ZGlmZiAtLWdpdCBhL0FuZHJvaWQubWsgYi9BbmRyb2lkLm1rCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI5NjkzMTcKLS0tIC9kZXYvbnVsbAorKysgYi9BbmRyb2lkLm1rCkBAIC0wLDAgKzEsNzAgQEAKKyMgLSotIG1vZGU6IG1ha2VmaWxlIC0qLQorIyBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworTE9DQUxfUEFUSCA6PSAkKGNhbGwgbXktZGlyKQorCisKKyMKKyMgSW5jbHVkZSB0aGUgZGVmaW5pdGlvbnMgdG8gYnVpbGQgdGhlIEphdmEgY29kZS4KKyMKKworaW5jbHVkZSAkKExPQ0FMX1BBVEgpL0phdmFMaWJyYXJ5Lm1rCisKKworIworIyBJbmNsdWRlIHRoZSBkZWZpbml0aW9ucyB0byBidWlsZCB0aGUgbmF0aXZlIGNvZGUuCisjCisKK2luY2x1ZGUgJChMT0NBTF9QQVRIKS9OYXRpdmVDb2RlLm1rCisKKyMKKyMgSW5jbHVkZSB0aGUgZGVmaW5pdGlvbnMgZm9yIHRoZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgKENBKSBjZXJ0aWZpY2F0ZXMKKyMKKworaW5jbHVkZSAkKExPQ0FMX1BBVEgpL0NhQ2VydHMubWsKKworIworIyBEaXNhYmxlIHRlc3QgbW9kdWxlcyBpZiBMSUJDT1JFX1NLSVBfVEVTVFMgZW52YXIgaXMgc2V0CisjCisKK2lmbmVxICgkKExJQkNPUkVfU0tJUF9URVNUUyksKQorJChpbmZvICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKQorJChpbmZvICogbGliY29yZSB0ZXN0cyBhcmUgc2tpcHBlZCBiZWNhdXNlIGVudmlyb25tZW50IHZhcmlhYmxlIExJQkNPUkVfU0tJUF9URVNUUz0kKExJQkNPUkVfU0tJUF9URVNUUykpCiskKGluZm8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiopCitBTExfTU9EVUxFX1RBR1MgOj0gJChmaWx0ZXItb3V0IHRlc3RzLCQoQUxMX01PRFVMRV9UQUdTKSkKK0FMTF9NT0RVTEVTIDo9ICQoZmlsdGVyLW91dCAkKEFMTF9NT0RVTEVfTkFNRV9UQUdTLnRlc3RzKSwkKEFMTF9NT0RVTEVTKSkKK2VuZGlmCisKKworIworIyAibSBkYWx2aWstaG9zdCIgZm9yIHF1aWNrIG1pbmltYWwgaG9zdCBidWlsZAorIworCitpZmVxICgkKFdJVEhfSE9TVF9EQUxWSUspLHRydWUpCisgICAgLlBIT05ZOiBkYWx2aWstaG9zdAorICAgIGRhbHZpay1ob3N0OiBcCisgICAgICAgIGRhbHZpayBcCisgICAgICAgICQoSE9TVF9PVVQpL2Jpbi9kYWx2aWt2bSBcCisgICAgICAgICQoSE9TVF9PVVQpL2Jpbi9kZXhvcHQgXAorICAgICAgICBjYWNlcnRzLWhvc3QgXAorICAgICAgICAkKEhPU1RfT1VUKS91c3Ivc2hhcmUvem9uZWluZm8vem9uZWluZm8uZGF0IFwKKyAgICAgICAgJChIT1NUX09VVCkvdXNyL3NoYXJlL3pvbmVpbmZvL3pvbmVpbmZvLmlkeCBcCisgICAgICAgICQoSE9TVF9PVVQpL3Vzci9zaGFyZS96b25laW5mby96b25laW5mby52ZXJzaW9uIFwKKyAgICAgICAgY29yZS1ob3N0ZGV4IFwKKyAgICAgICAgYm91bmN5Y2FzdGxlLWhvc3RkZXggXAorICAgICAgICBhcGFjaGUteG1sLWhvc3RkZXggXAorICAgICAgICBhcGFjaGUtaGFybW9ueS10ZXN0cy1ob3N0ZGV4IFwKKyAgICAgICAgJChjYWxsIGludGVybWVkaWF0ZXMtZGlyLWZvcixKQVZBX0xJQlJBUklFUyxjb3JlLXRlc3RzLCxDT01NT04pL2NsYXNzZXMuamFyCitlbmRpZgpkaWZmIC0tZ2l0IGEvQ2FDZXJ0cy5tayBiL0NhQ2VydHMubWsKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2RjZWQ4ZgotLS0gL2Rldi9udWxsCisrKyBiL0NhQ2VydHMubWsKQEAgLTAsMCArMSw1OCBAQAorIyAtKi0gbW9kZTogbWFrZWZpbGUgLSotCisjIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCisjCisjIERlZmluaXRpb25zIGZvciBpbnN0YWxsaW5nIENlcnRpZmljYXRlIEF1dGhvcml0eSAoQ0EpIGNlcnRpZmljYXRlcworIworCitkZWZpbmUgYWxsLWZpbGVzLXVuZGVyCiskKHBhdHN1YnN0IC4vJSwlLCBcCisgICQoc2hlbGwgY2QgJChMT0NBTF9QQVRIKSA7IFwKKyAgICAgICAgICBmaW5kICQoMSkgLXR5cGUgZikgXAorICkKK2VuZGVmCisKKyMgJCgxKTogbW9kdWxlIG5hbWUKKyMgJCgyKTogc291cmNlIGZpbGUKKyMgJCgzKTogZGVzdGluYXRpb24gZGlyZWN0b3J5CitkZWZpbmUgaW5jbHVkZS1wcmVidWlsdC13aXRoLWRlc3RpbmF0aW9uLWRpcmVjdG9yeQoraW5jbHVkZSAkJChDTEVBUl9WQVJTKQorTE9DQUxfTU9EVUxFIDo9ICQoMSkKK0xPQ0FMX01PRFVMRV9TVEVNIDo9ICQobm90ZGlyICQoMikpCitMT0NBTF9NT0RVTEVfVEFHUyA6PSBvcHRpb25hbAorTE9DQUxfTU9EVUxFX0NMQVNTIDo9IEVUQworTE9DQUxfTU9EVUxFX1BBVEggOj0gJCgzKQorTE9DQUxfU1JDX0ZJTEVTIDo9ICQoMikKK2luY2x1ZGUgJCQoQlVJTERfUFJFQlVJTFQpCitlbmRlZgorCitjYWNlcnRzIDo9ICQoY2FsbCBhbGwtZmlsZXMtdW5kZXIsbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzKQorCitjYWNlcnRzX3RhcmdldF9kaXJlY3RvcnkgOj0gJChUQVJHRVRfT1VUKS9ldGMvc2VjdXJpdHkvY2FjZXJ0cworJChmb3JlYWNoIGNhY2VydCwgJChjYWNlcnRzKSwgJChldmFsICQoY2FsbCBpbmNsdWRlLXByZWJ1aWx0LXdpdGgtZGVzdGluYXRpb24tZGlyZWN0b3J5LHRhcmdldC1jYWNlcnQtJChub3RkaXIgJChjYWNlcnQpKSwkKGNhY2VydCksJChjYWNlcnRzX3RhcmdldF9kaXJlY3RvcnkpKSkpCitjYWNlcnRzX3RhcmdldCA6PSAkKGFkZHByZWZpeCAkKGNhY2VydHNfdGFyZ2V0X2RpcmVjdG9yeSkvLCQoZm9yZWFjaCBjYWNlcnQsJChjYWNlcnRzKSwkKG5vdGRpciAkKGNhY2VydCkpKSkKKy5QSE9OWTogY2FjZXJ0c190YXJnZXQKK2NhY2VydHM6ICQoY2FjZXJ0c190YXJnZXQpCisKKyMgVGhpcyBpcyBzbyB0aGF0IGJ1aWxkL3RhcmdldC9wcm9kdWN0L2NvcmUubWsgY2FuIHVzZSBjYWNlcnRzIGluIFBST0RVQ1RfUEFDS0FHRVMKK0FMTF9NT0RVTEVTLmNhY2VydHMuSU5TVEFMTEVEIDo9ICQoY2FjZXJ0c190YXJnZXQpCisKK2lmZXEgKCQoV0lUSF9IT1NUX0RBTFZJSyksdHJ1ZSkKK2NhY2VydHNfaG9zdF9kaXJlY3RvcnkgOj0gJChIT1NUX09VVCkvZXRjL3NlY3VyaXR5L2NhY2VydHMKKyQoZm9yZWFjaCBjYWNlcnQsICQoY2FjZXJ0cyksICQoZXZhbCAkKGNhbGwgaW5jbHVkZS1wcmVidWlsdC13aXRoLWRlc3RpbmF0aW9uLWRpcmVjdG9yeSxob3N0LWNhY2VydC0kKG5vdGRpciAkKGNhY2VydCkpLCQoY2FjZXJ0KSwkKGNhY2VydHNfaG9zdF9kaXJlY3RvcnkpKSkpCitlbmRpZgorY2FjZXJ0c19ob3N0IDo9ICQoYWRkcHJlZml4ICQoY2FjZXJ0c19ob3N0X2RpcmVjdG9yeSkvLCQoZm9yZWFjaCBjYWNlcnQsJChjYWNlcnRzKSwkKG5vdGRpciAkKGNhY2VydCkpKSkKKy5QSE9OWTogY2FjZXJ0cy1ob3N0CitjYWNlcnRzLWhvc3Q6ICQoY2FjZXJ0c19ob3N0KQpkaWZmIC0tZ2l0IGEvQ2xlYW5TcGVjLm1rIGIvQ2xlYW5TcGVjLm1rCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE2MThmMWIKLS0tIC9kZXYvbnVsbAorKysgYi9DbGVhblNwZWMubWsKQEAgLTAsMCArMSw1MCBAQAorIyAtKi0gbW9kZTogbWFrZWZpbGUgLSotCisjIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorIworCisjIElmIHlvdSBkb24ndCBuZWVkIHRvIGRvIGEgZnVsbCBjbGVhbiBidWlsZCBidXQgd291bGQgbGlrZSB0byB0b3VjaAorIyBhIGZpbGUgb3IgZGVsZXRlIHNvbWUgaW50ZXJtZWRpYXRlIGZpbGVzLCBhZGQgYSBjbGVhbiBzdGVwIHRvIHRoZSBlbmQKKyMgb2YgdGhlIGxpc3QuICBUaGVzZSBzdGVwcyB3aWxsIG9ubHkgYmUgcnVuIG9uY2UsIGlmIHRoZXkgaGF2ZW4ndCBiZWVuCisjIHJ1biBiZWZvcmUuCisjCisjIEUuZy46CisjICAgICAkKGNhbGwgYWRkLWNsZWFuLXN0ZXAsIHRvdWNoIC1jIGV4dGVybmFsL3NxbGl0ZS9zcWxpdGUzLmgpCisjICAgICAkKGNhbGwgYWRkLWNsZWFuLXN0ZXAsIHJtIC1yZiAkKE9VVCkvb2JqL1NUQVRJQ19MSUJSQVJJRVMvbGliel9pbnRlcm1lZGlhdGVzKQorIworIyBBbHdheXMgdXNlICJ0b3VjaCAtYyIgYW5kICJybSAtZiIgb3IgInJtIC1yZiIgdG8gZ3JhY2VmdWxseSBkZWFsIHdpdGgKKyMgZmlsZXMgdGhhdCBhcmUgbWlzc2luZyBvciBoYXZlIGJlZW4gbW92ZWQuCisjCisjIFVzZSAkKFBST0RVQ1RfT1VUKSB0byBnZXQgdG8gdGhlICJvdXQvdGFyZ2V0L3Byb2R1Y3QvYmxhaC8iIGRpcmVjdG9yeS4KKyMgVXNlICQoT1VUKSB0byByZWZlciB0byB0aGUgIm91dCIgZGlyZWN0b3J5LgorIworIyBJZiB5b3UgbmVlZCB0byByZS1kbyBzb21ldGhpbmcgdGhhdCdzIGFscmVhZHkgbWVudGlvbmVkLCBqdXN0IGNvcHkKKyMgdGhlIGNvbW1hbmQgYW5kIGFkZCBpdCB0byB0aGUgYm90dG9tIG9mIHRoZSBsaXN0LiAgRS5nLiwgaWYgYSBjaGFuZ2UKKyMgdGhhdCB5b3UgbWFkZSBsYXN0IHdlZWsgcmVxdWlyZWQgdG91Y2hpbmcgYSBmaWxlIGFuZCBhIGNoYW5nZSB5b3UKKyMgbWFkZSB0b2RheSByZXF1aXJlcyB0b3VjaGluZyB0aGUgc2FtZSBmaWxlLCBqdXN0IGNvcHkgdGhlIG9sZAorIyB0b3VjaCBzdGVwIGFuZCBhZGQgaXQgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdC4KKyMKKyMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisjIE5FV0VSIENMRUFOIFNURVBTIE1VU1QgQkUgQVQgVEhFIEVORCBPRiBUSEUgTElTVAorIyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKworIyBGb3IgZXhhbXBsZToKKyMkKGNhbGwgYWRkLWNsZWFuLXN0ZXAsIHJtIC1yZiAkKE9VVCkvdGFyZ2V0L2NvbW1vbi9vYmovQVBQUy9BbmRyb2lkVGVzdHNfaW50ZXJtZWRpYXRlcykKKyMkKGNhbGwgYWRkLWNsZWFuLXN0ZXAsIHJtIC1yZiAkKE9VVCkvdGFyZ2V0L2NvbW1vbi9vYmovSkFWQV9MSUJSQVJJRVMvY29yZV9pbnRlcm1lZGlhdGVzKQorIyQoY2FsbCBhZGQtY2xlYW4tc3RlcCwgZmluZCAkKE9VVCkgLXR5cGUgZiAtbmFtZSAiSUdUYWxrU2Vzc2lvbioiIC1wcmludDAgfCB4YXJncyAtMCBybSAtZikKKyMkKGNhbGwgYWRkLWNsZWFuLXN0ZXAsIHJtIC1yZiAkKFBST0RVQ1RfT1VUKS9kYXRhLyopCisjJChjYWxsIGFkZC1jbGVhbi1zdGVwLCBybSAtcmYgJChPVVQpL29iai9TSEFSRURfTElCUkFSSUVTL2xpYmR2bSopCisjICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorIyBORVdFUiBDTEVBTiBTVEVQUyBNVVNUIEJFIEFUIFRIRSBFTkQgT0YgVEhFIExJU1QKKyMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCmRpZmYgLS1naXQgYS9Eb2NzLm1rIGIvRG9jcy5tawpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YjVlNDY5Ci0tLSAvZGV2L251bGwKKysrIGIvRG9jcy5tawpAQCAtMCwwICsxLDMwIEBACisjIC0qLSBtb2RlOiBtYWtlZmlsZSAtKi0KKyMgTGlzdCBvZiBsaWJjb3JlIGRpcmVjdG9yaWVzIHRvIGluY2x1ZGUgaW4gZG9jdW1lbnRhdGlvbi4KKyMgU2hhcmVkIGJldHdlZW4gbGliY29yZSBhbmQgZnJhbWV3b3Jrcy9iYXNlLgorCitkZWZpbmUgbGliY29yZWRvYy1hbGwtamF2YS1maWxlcy11bmRlcgorJChwYXRzdWJzdCAuLyUsJSwgXAorICAkKHNoZWxsIGNkICQoMSkgOyBcCisgICAgICAgICAgZmluZCAkKDIpIC1uYW1lICIqLmphdmEiIC1hbmQgLW5vdCAtbmFtZSAiLioiKSBcCisgKQorZW5kZWYKKworIyBMaXN0IG9mIGxpYmNvcmUgamF2YWRvYyBzb3VyY2UgZmlsZXMKKyMgCisjIE5vdGUgZGFsdmlrL3N5c3RlbSBpcyBub24tcmVjdXJzaXZlIHRvIGV4Y2x1ZGUgZGFsdmlrLnN5c3RlbS5wcm9maWxlcgorIworIyAkKDEpOiBkaXJlY3RvcnkgZm9yIHNlYXJjaCAodG8gc3VwcG9ydCB1c2UgZnJvbSBmcmFtZXdvcmtzL2Jhc2UpCitkZWZpbmUgbGliY29yZV90b19kb2N1bWVudAorICQoY2FsbCBsaWJjb3JlZG9jLWFsbC1qYXZhLWZpbGVzLXVuZGVyLCQoMSksIFwKKyAgIGRhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vIC1tYXhkZXB0aCAxKSBcCisgJChjYWxsIGxpYmNvcmVkb2MtYWxsLWphdmEtZmlsZXMtdW5kZXIsJCgxKSwgXAorICAgZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24gXAorICAgZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2J5dGVjb2RlIFwKKyAgIGpzb24vc3JjL21haW4vamF2YSBcCisgICBqdW5pdC9zcmMvbWFpbi9qYXZhIFwKKyAgIGx1bmkvc3JjL21haW4vamF2YS9qYXZhIFwKKyAgIGx1bmkvc3JjL21haW4vamF2YS9qYXZheCBcCisgICBsdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXggXAorICAgbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MgXAorICAgeG1sL3NyYy9tYWluL2phdmEvb3JnL3htbHB1bGwvdjEpCitlbmRlZgpkaWZmIC0tZ2l0IGEvSmF2YUxpYnJhcnkubWsgYi9KYXZhTGlicmFyeS5tawpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MTc5ZmRhCi0tLSAvZGV2L251bGwKKysrIGIvSmF2YUxpYnJhcnkubWsKQEAgLTAsMCArMSwyMjQgQEAKKyMgLSotIG1vZGU6IG1ha2VmaWxlIC0qLQorIyBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworIworIyBEZWZpbml0aW9ucyBmb3IgYnVpbGRpbmcgdGhlIEphdmEgbGlicmFyeSBhbmQgYXNzb2NpYXRlZCB0ZXN0cy4KKyMKKworIworIyBDb21tb24gZGVmaW5pdGlvbnMgZm9yIGhvc3QgYW5kIHRhcmdldC4KKyMKKworIyBsaWJjb3JlIGlzIGRpdmlkZWQgaW50byBtb2R1bGVzLgorIworIyBUaGUgc3RydWN0dXJlIG9mIGVhY2ggbW9kdWxlIGlzOgorIworIyAgIHNyYy8KKyMgICAgICAgbWFpbi8gICAgICAgICAgICAgICAjIFRvIGJlIHNoaXBwZWQgb24gZXZlcnkgZGV2aWNlLgorIyAgICAgICAgICAgIGphdmEvICAgICAgICAgICMgSmF2YSBzb3VyY2UgZm9yIGxpYnJhcnkgY29kZS4KKyMgICAgICAgICAgICBuYXRpdmUvICAgICAgICAjIEMrKyBzb3VyY2UgZm9yIGxpYnJhcnkgY29kZS4KKyMgICAgICAgICAgICByZXNvdXJjZXMvICAgICAjIFN1cHBvcnQgZmlsZXMuCisjICAgICAgIHRlc3QvICAgICAgICAgICAgICAgIyBCdWlsdCBvbmx5IG9uIGRlbWFuZCwgZm9yIHRlc3RpbmcuCisjICAgICAgICAgICAgamF2YS8gICAgICAgICAgIyBKYXZhIHNvdXJjZSBmb3IgdGVzdHMuCisjICAgICAgICAgICAgbmF0aXZlLyAgICAgICAgIyBDKysgc291cmNlIGZvciB0ZXN0cyAocmFyZSkuCisjICAgICAgICAgICAgcmVzb3VyY2VzLyAgICAgIyBTdXBwb3J0IGZpbGVzLgorIworIyBBbGwgc3ViZGlyZWN0b3JpZXMgYXJlIG9wdGlvbmFsIChoZW5jZSB0aGUgIjI+IC9kZXYvbnVsbCJzIGJlbG93KS4KKworZGVmaW5lIGFsbC1tYWluLWphdmEtZmlsZXMtdW5kZXIKKyQoZm9yZWFjaCBkaXIsJCgxKSwkKHBhdHN1YnN0IC4vJSwlLCQoc2hlbGwgY2QgJChMT0NBTF9QQVRIKSAmJiBmaW5kICQoZGlyKS9zcmMvbWFpbi9qYXZhIC1uYW1lICIqLmphdmEiIDI+IC9kZXYvbnVsbCkpKQorZW5kZWYKKworZGVmaW5lIGFsbC10ZXN0LWphdmEtZmlsZXMtdW5kZXIKKyQoZm9yZWFjaCBkaXIsJCgxKSwkKHBhdHN1YnN0IC4vJSwlLCQoc2hlbGwgY2QgJChMT0NBTF9QQVRIKSAmJiBmaW5kICQoZGlyKS9zcmMvdGVzdC9qYXZhIC1uYW1lICIqLmphdmEiIDI+IC9kZXYvbnVsbCkpKQorZW5kZWYKKworZGVmaW5lIGFsbC1jb3JlLXJlc291cmNlLWRpcnMKKyQoc2hlbGwgY2QgJChMT0NBTF9QQVRIKSAmJiBscyAtZCAqL3NyYy8kKDEpL3tqYXZhLHJlc291cmNlc30gMj4gL2Rldi9udWxsKQorZW5kZWYKKworIyBUaGUgSmF2YSBmaWxlcyBhbmQgdGhlaXIgYXNzb2NpYXRlZCByZXNvdXJjZXMuCitjb3JlX3NyY19maWxlcyA6PSAkKGNhbGwgYWxsLW1haW4tamF2YS1maWxlcy11bmRlcixkYWx2aWsgZG9tIGpzb24gbHVuaSBzdXBwb3J0IHhtbCkKK2NvcmVfcmVzb3VyY2VfZGlycyA6PSAkKGNhbGwgYWxsLWNvcmUtcmVzb3VyY2UtZGlycyxtYWluKQordGVzdF9yZXNvdXJjZV9kaXJzIDo9ICQoY2FsbCBhbGwtY29yZS1yZXNvdXJjZS1kaXJzLHRlc3QpCisKK2lmZXEgKCQoRU1NQV9JTlNUUlVNRU5UKSx0cnVlKQorICAgIGNvcmVfc3JjX2ZpbGVzICs9ICQoY2FsbCBhbGwtamF2YS1maWxlcy11bmRlciwgLi4vZXh0ZXJuYWwvZW1tYS9jb3JlIC4uL2V4dGVybmFsL2VtbWEvcHJlZ2VuZXJhdGVkKQorICAgIGNvcmVfcmVzb3VyY2VfZGlycyArPSAuLi9leHRlcm5hbC9lbW1hL2NvcmUvcmVzIC4uL2V4dGVybmFsL2VtbWEvcHJlZ2VuZXJhdGVkL3JlcworZW5kaWYKKworbG9jYWxfamF2YWNfZmxhZ3M9LWVuY29kaW5nIFVURi04CisjbG9jYWxfamF2YWNfZmxhZ3MrPS1YbGludDphbGwgLVhsaW50Oi1zZXJpYWwsLWRlcHJlY2F0aW9uLC11bmNoZWNrZWQKK2xvY2FsX2phdmFjX2ZsYWdzKz0tWG1heHdhcm5zIDk5OTk5OTkKKworIworIyBCdWlsZCBmb3IgdGhlIHRhcmdldCAoZGV2aWNlKS4KKyMKKworIyBEZWZpbml0aW9ucyB0byBtYWtlIHRoZSBjb3JlIGxpYnJhcnkuCisKK2luY2x1ZGUgJChDTEVBUl9WQVJTKQorCitMT0NBTF9TUkNfRklMRVMgOj0gJChjb3JlX3NyY19maWxlcykKK0xPQ0FMX0pBVkFfUkVTT1VSQ0VfRElSUyA6PSAkKGNvcmVfcmVzb3VyY2VfZGlycykKKworTE9DQUxfTk9fU1RBTkRBUkRfTElCUkFSSUVTIDo9IHRydWUKK0xPQ0FMX0pBVkFDRkxBR1MgOj0gJChsb2NhbF9qYXZhY19mbGFncykKK0xPQ0FMX0RYX0ZMQUdTIDo9IC0tY29yZS1saWJyYXJ5CisKK0xPQ0FMX05PX0VNTUFfSU5TVFJVTUVOVCA6PSB0cnVlCitMT0NBTF9OT19FTU1BX0NPTVBJTEUgOj0gdHJ1ZQorTE9DQUxfTU9EVUxFX1RBR1MgOj0gb3B0aW9uYWwKK0xPQ0FMX01PRFVMRSA6PSBjb3JlCisKK2luY2x1ZGUgJChCVUlMRF9KQVZBX0xJQlJBUlkpCisKK2NvcmUtaW50ZXJtZWRpYXRlcyA6PSAke2ludGVybWVkaWF0ZXN9CisKKworIyBNYWtlIGNvcmUtanVuaXQKK2luY2x1ZGUgJChDTEVBUl9WQVJTKQorTE9DQUxfU1JDX0ZJTEVTIDo9ICQoY2FsbCBhbGwtbWFpbi1qYXZhLWZpbGVzLXVuZGVyLGp1bml0KQorTE9DQUxfTk9fU1RBTkRBUkRfTElCUkFSSUVTIDo9IHRydWUKK0xPQ0FMX0pBVkFfTElCUkFSSUVTIDo9IGNvcmUKK0xPQ0FMX0pBVkFDRkxBR1MgOj0gJChsb2NhbF9qYXZhY19mbGFncykKK0xPQ0FMX01PRFVMRV9UQUdTIDo9IG9wdGlvbmFsCitMT0NBTF9NT0RVTEUgOj0gY29yZS1qdW5pdAoraW5jbHVkZSAkKEJVSUxEX0pBVkFfTElCUkFSWSkKKworIyBNYWtlIHRoZSBjb3JlLXRlc3RzIGxpYnJhcnkuCitpbmNsdWRlICQoQ0xFQVJfVkFSUykKK0xPQ0FMX1NSQ19GSUxFUyA6PSAkKGNhbGwgYWxsLXRlc3QtamF2YS1maWxlcy11bmRlcixkYWx2aWsgZG9tIGpzb24gbHVuaSBzdXBwb3J0IHhtbCkKK0xPQ0FMX0pBVkFfUkVTT1VSQ0VfRElSUyA6PSAkKHRlc3RfcmVzb3VyY2VfZGlycykKK0xPQ0FMX05PX1NUQU5EQVJEX0xJQlJBUklFUyA6PSB0cnVlCitMT0NBTF9KQVZBX0xJQlJBUklFUyA6PSBib3VuY3ljYXN0bGUgY29yZSBjb3JlLWp1bml0CitMT0NBTF9TVEFUSUNfSkFWQV9MSUJSQVJJRVMgOj0gc3FsaXRlLWpkYmMgbW9ja3dlYnNlcnZlcgorTE9DQUxfSkFWQUNGTEFHUyA6PSAkKGxvY2FsX2phdmFjX2ZsYWdzKQorTE9DQUxfTU9EVUxFX1RBR1MgOj0gdGVzdHMKK0xPQ0FMX01PRFVMRSA6PSBjb3JlLXRlc3RzCitMT0NBTF9OT19FTU1BX0lOU1RSVU1FTlQgOj0gdHJ1ZQorTE9DQUxfTk9fRU1NQV9DT01QSUxFIDo9IHRydWUKK2luY2x1ZGUgJChCVUlMRF9TVEFUSUNfSkFWQV9MSUJSQVJZKQorCisjIFRoaXMgb25lJ3MgdHJpY2t5LiBPbmUgb2Ygb3VyIHRlc3RzIG5lZWRzIHRvIGhhdmUgYQorIyByZXNvdXJjZSB3aXRoIGEgIiMiIGluIGl0cyBuYW1lLCBidXQgUGVyZm9yY2UgZG9lc24ndAorIyBhbGxvdyB1cyB0byBzdWJtaXQgc3VjaCBhIGZpbGUuIFNvIHdlIGNyZWF0ZSBpdCBoZXJlCisjIG9uLXRoZS1mbHkuCitUTVBfUkVTT1VSQ0VfRElSIDo9ICQoaW50ZXJtZWRpYXRlcy5DT01NT04pL3RtcC8KK1RNUF9SRVNPVVJDRV9GSUxFIDo9IG9yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy90ZXN0XCMucHJvcGVydGllcworCiskKFRNUF9SRVNPVVJDRV9ESVIpJChUTVBfUkVTT1VSQ0VfRklMRSk6CisJQG1rZGlyIC1wICQoZGlyICRAKQorCUBlY2hvICJIZWxsbywgd29ybGQhIiA+ICRACisKKyQoTE9DQUxfSU5URVJNRURJQVRFX1RBUkdFVFMpOiBQUklWQVRFX0VYVFJBX0pBUl9BUkdTIDo9ICQoZXh0cmFfamFyX2FyZ3MpIC1DICIkKFRNUF9SRVNPVVJDRV9ESVIpIiAiJChUTVBfUkVTT1VSQ0VfRklMRSkiCiskKExPQ0FMX0lOVEVSTUVESUFURV9UQVJHRVRTKTogJChUTVBfUkVTT1VSQ0VfRElSKSQoVE1QX1JFU09VUkNFX0ZJTEUpCisKKworIworIyBCdWlsZCBmb3IgdGhlIGhvc3QuCisjCisKK2lmZXEgKCQoV0lUSF9IT1NUX0RBTFZJSyksdHJ1ZSkKKworICAgICMgRGVmaW5pdGlvbnMgdG8gbWFrZSB0aGUgY29yZSBsaWJyYXJ5LgorCisgICAgaW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKKyAgICBMT0NBTF9TUkNfRklMRVMgOj0gJChjb3JlX3NyY19maWxlcykKKyAgICBMT0NBTF9KQVZBX1JFU09VUkNFX0RJUlMgOj0gJChjb3JlX3Jlc291cmNlX2RpcnMpCisKKyAgICBMT0NBTF9OT19TVEFOREFSRF9MSUJSQVJJRVMgOj0gdHJ1ZQorICAgIExPQ0FMX0pBVkFDRkxBR1MgOj0gJChsb2NhbF9qYXZhY19mbGFncykKKyAgICBMT0NBTF9EWF9GTEFHUyA6PSAtLWNvcmUtbGlicmFyeQorCisgICAgTE9DQUxfTk9fRU1NQV9JTlNUUlVNRU5UIDo9IHRydWUKKyAgICBMT0NBTF9OT19FTU1BX0NPTVBJTEUgOj0gdHJ1ZQorICAgIExPQ0FMX0JVSUxEX0hPU1RfREVYIDo9IHRydWUKKworICAgIExPQ0FMX01PRFVMRV9UQUdTIDo9IG9wdGlvbmFsCisgICAgTE9DQUxfTU9EVUxFIDo9IGNvcmUtaG9zdGRleAorCisgICAgaW5jbHVkZSAkKEJVSUxEX0hPU1RfSkFWQV9MSUJSQVJZKQorCisgICAgIyBNYWtlIGNvcmUtanVuaXQKKyAgICBpbmNsdWRlICQoQ0xFQVJfVkFSUykKKyAgICBMT0NBTF9TUkNfRklMRVMgOj0gJChjYWxsIGFsbC1tYWluLWphdmEtZmlsZXMtdW5kZXIsanVuaXQpCisgICAgTE9DQUxfTk9fU1RBTkRBUkRfTElCUkFSSUVTIDo9IHRydWUKKyAgICBMT0NBTF9KQVZBX0xJQlJBUklFUyA6PSBjb3JlLWhvc3RkZXgKKyAgICBMT0NBTF9KQVZBQ0ZMQUdTIDo9ICQobG9jYWxfamF2YWNfZmxhZ3MpCisgICAgTE9DQUxfTU9EVUxFX1RBR1MgOj0gb3B0aW9uYWwKKyAgICBMT0NBTF9NT0RVTEUgOj0gY29yZS1qdW5pdC1ob3N0ZGV4CisgICAgTE9DQUxfQlVJTERfSE9TVF9ERVggOj0gdHJ1ZQorICAgIGluY2x1ZGUgJChCVUlMRF9IT1NUX0pBVkFfTElCUkFSWSkKKworICAgICMgTWFrZSB0aGUgY29yZS10ZXN0cyBsaWJyYXJ5LgorICAgIGluY2x1ZGUgJChDTEVBUl9WQVJTKQorICAgIExPQ0FMX1NSQ19GSUxFUyA6PSAkKGNhbGwgYWxsLXRlc3QtamF2YS1maWxlcy11bmRlcixkYWx2aWsgZG9tIGpzb24gbHVuaSBzdXBwb3J0IHhtbCkKKyAgICBMT0NBTF9KQVZBX1JFU09VUkNFX0RJUlMgOj0gJCh0ZXN0X3Jlc291cmNlX2RpcnMpCisgICAgTE9DQUxfTk9fU1RBTkRBUkRfTElCUkFSSUVTIDo9IHRydWUKKyAgICBMT0NBTF9KQVZBX0xJQlJBUklFUyA6PSBib3VuY3ljYXN0bGUtaG9zdGRleCBjb3JlLWhvc3RkZXggY29yZS1qdW5pdC1ob3N0ZGV4CisgICAgTE9DQUxfU1RBVElDX0pBVkFfTElCUkFSSUVTIDo9IHNxbGl0ZS1qZGJjLWhvc3QgbW9ja3dlYnNlcnZlci1ob3N0ZGV4CisgICAgTE9DQUxfSkFWQUNGTEFHUyA6PSAkKGxvY2FsX2phdmFjX2ZsYWdzKQorICAgIExPQ0FMX01PRFVMRV9UQUdTIDo9IHRlc3RzCisgICAgTE9DQUxfTU9EVUxFIDo9IGNvcmUtdGVzdHMtaG9zdGRleAorICAgIExPQ0FMX05PX0VNTUFfSU5TVFJVTUVOVCA6PSB0cnVlCisgICAgTE9DQUxfTk9fRU1NQV9DT01QSUxFIDo9IHRydWUKKyAgICBMT0NBTF9CVUlMRF9IT1NUX0RFWCA6PSB0cnVlCisgICAgaW5jbHVkZSAkKEJVSUxEX0hPU1RfSkFWQV9MSUJSQVJZKQorZW5kaWYKKworIworIyBMb2NhbCBkcm9pZGRvYyBmb3IgZmFzdGVyIGxpYmNvcmUgdGVzdGluZworIworIworIyBSdW4gd2l0aDoKKyMgICAgIG0gbGliY29yZS1kb2NzCisjCisjIE1haW4gb3V0cHV0OgorIyAgICAgb3V0L3RhcmdldC9jb21tb24vZG9jcy9saWJjb3JlL3JlZmVyZW5jZS9wYWNrYWdlcy5odG1sCisjCisjIEFsbCB0ZXh0IGZvciBwcm9vZnJlYWRpbmcgKG9yIHJ1bm5pbmcgdG9vbHMgb3Zlcik6CisjICAgICBvdXQvdGFyZ2V0L2NvbW1vbi9kb2NzL2xpYmNvcmUtcHJvb2ZyZWFkLnR4dAorIworIyBUT0RPIGxpc3Qgb2YgbWlzc2luZyBqYXZhZG9jLCBldGM6CisjICAgICBvdXQvdGFyZ2V0L2NvbW1vbi9kb2NzL2xpYmNvcmUtZG9jcy10b2RvLmh0bWwKKyMKKyMgUmVydW46CisjICAgICBybSAtcmYgb3V0L3RhcmdldC9jb21tb24vZG9jcy9saWJjb3JlLXRpbWVzdGFtcCAmJiBtIGxpYmNvcmUtZG9jcworIworaW5jbHVkZSAkKENMRUFSX1ZBUlMpCisKKyMgZm9yIHNoYXJlZCBkZWZpbnRpb24gb2YgbGliY29yZV90b19kb2N1bWVudAoraW5jbHVkZSAkKExPQ0FMX1BBVEgpL0RvY3MubWsKKworTE9DQUxfU1JDX0ZJTEVTOj0kKGNhbGwgbGliY29yZV90b19kb2N1bWVudCwkKExPQ0FMX1BBVEgpKQorIyByZXJ1biBkb2MgZ2VuZXJhdGlvbiB3aXRob3V0IHJlY29tcGlsaW5nIHRoZSBqYXZhCitMT0NBTF9KQVZBX0xJQlJBUklFUzo9CitMT0NBTF9KQVZBQ0ZMQUdTIDo9ICQobG9jYWxfamF2YWNfZmxhZ3MpCitMT0NBTF9NT0RVTEVfQ0xBU1M6PUpBVkFfTElCUkFSSUVTCisKK0xPQ0FMX01PRFVMRSA6PSBsaWJjb3JlCisKK0xPQ0FMX0RST0lERE9DX09QVElPTlM6PSBcCisgLW9mZmxpbmVtb2RlIFwKKyAtdGl0bGUgImxpYmNvcmUiIFwKKyAtcHJvb2ZyZWFkICQoT1VUX0RPQ1MpLyQoTE9DQUxfTU9EVUxFKS1wcm9vZnJlYWQudHh0IFwKKyAtdG9kbyAuLi8kKExPQ0FMX01PRFVMRSktZG9jcy10b2RvLmh0bWwgXAorIC1oZGYgYW5kcm9pZC53aGljaGRvYyBvZmZsaW5lCisKK0xPQ0FMX0RST0lERE9DX0NVU1RPTV9URU1QTEFURV9ESVI6PWJ1aWxkL3Rvb2xzL2Ryb2lkZG9jL3RlbXBsYXRlcy1zZGsKKworaW5jbHVkZSAkKEJVSUxEX0RST0lERE9DKQpkaWZmIC0tZ2l0IGEvTk9USUNFIGIvTk9USUNFCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgxOGY2YzUKLS0tIC9kZXYvbnVsbAorKysgYi9OT1RJQ0UKQEAgLTAsMCArMSwzODIgQEAKKyAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgID09ICBOT1RJQ0UgZmlsZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBzZWN0aW9uIDQgZCBvZiAgICAgICAgICAgICAgICAgICAgPT0KKyAgID09ICB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT0KKyAgID09ICBpbiB0aGlzIGNhc2UgZm9yIHRoZSBBbmRyb2lkLXNwZWNpZmljIGNvZGUuICAgICAgICAgICAgICAgICAgICAgICAgPT0KKyAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworQW5kcm9pZCBDb2RlCitDb3B5cmlnaHQgMjAwNS0yMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKworVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBhcyBwYXJ0IG9mCitUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0IChodHRwOi8vc291cmNlLmFuZHJvaWQuY29tKS4KKworICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAgPT0gIE5PVElDRSBmaWxlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHNlY3Rpb24gNCBkIG9mICAgICAgICAgICAgICAgICAgICA9PQorICAgPT0gIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PQorICAgPT0gIGluIHRoaXMgY2FzZSBmb3IgdGhlIEFwYWNoZSBIYXJtb255IGRpc3RyaWJ1dGlvbi4gICAgICAgICAgICAgICAgICA9PQorICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitBcGFjaGUgSGFybW9ueQorQ29weXJpZ2h0IDIwMDYgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisKK1RoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYXQKK1RoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuCisKK1BvcnRpb25zIG9mIEhhcm1vbnkgd2VyZSBvcmlnaW5hbGx5IGRldmVsb3BlZCBieQorSW50ZWwgQ29ycG9yYXRpb24gYW5kIGFyZSBsaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlCitGb3VuZGF0aW9uIHVuZGVyIHRoZSAiU29mdHdhcmUgR3JhbnQgYW5kIENvcnBvcmF0ZSBDb250cmlidXRpb24KK0xpY2Vuc2UgQWdyZWVtZW50IiwgaW5mb3JtYWxseSBrbm93biBhcyB0aGUgIkludGVsIEhhcm1vbnkgQ0xBIi4KKworCisgICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgICA9PSAgTk9USUNFIGZpbGUgZm9yIHRoZSBJQ1UgTGljZW5zZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID09CisgICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0NvcHlyaWdodCAoYykgMTk5NS0yMDA5IEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIG90aGVycworCitBbGwgcmlnaHRzIHJlc2VydmVkLgorCitQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcKK2EgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZQorIlNvZnR3YXJlIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZword2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLAorZGlzdHJpYnV0ZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zCit0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlCitjb3B5cmlnaHQgbm90aWNlKHMpIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIG9mCit0aGUgU29mdHdhcmUgYW5kIHRoYXQgYm90aCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZShzKSBhbmQgdGhpcworcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcgZG9jdW1lbnRhdGlvbi4KKworVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCitFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YKK01FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVAorT0YgVEhJUkQgUEFSVFkgUklHSFRTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgorSE9MREVSUyBJTkNMVURFRCBJTiBUSElTIE5PVElDRSBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgT1IgQU5ZCitTUEVDSUFMIElORElSRUNUIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUywgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUgorUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YKK0NPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4KK0NPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCisKK0V4Y2VwdCBhcyBjb250YWluZWQgaW4gdGhpcyBub3RpY2UsIHRoZSBuYW1lIG9mIGEgY29weXJpZ2h0IGhvbGRlcgorc2hhbGwgbm90IGJlIHVzZWQgaW4gYWR2ZXJ0aXNpbmcgb3Igb3RoZXJ3aXNlIHRvIHByb21vdGUgdGhlIHNhbGUsIHVzZQorb3Igb3RoZXIgZGVhbGluZ3MgaW4gdGhpcyBTb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gYXV0aG9yaXphdGlvbgorb2YgdGhlIGNvcHlyaWdodCBob2xkZXIuCisKK0FsbCB0cmFkZW1hcmtzIGFuZCByZWdpc3RlcmVkIHRyYWRlbWFya3MgbWVudGlvbmVkIGhlcmVpbiBhcmUgdGhlCitwcm9wZXJ0eSBvZiB0aGVpciByZXNwZWN0aXZlIG93bmVycy4KKworCisgICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgICA9PSAgTk9USUNFIGZpbGUgZm9yIHRoZSBKVW5pdCBMaWNlbnNlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID09CisgICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0NvbW1vbiBQdWJsaWMgTGljZW5zZSAtIHYgMS4wCisKK1RIRSBBQ0NPTVBBTllJTkcgUFJPR1JBTSBJUyBQUk9WSURFRCBVTkRFUiBUSEUgVEVSTVMgT0YgVEhJUyBDT01NT04KK1BVQkxJQyBMSUNFTlNFICgiQUdSRUVNRU5UIikuIEFOWSBVU0UsIFJFUFJPRFVDVElPTiBPUiBESVNUUklCVVRJT04gT0YKK1RIRSBQUk9HUkFNIENPTlNUSVRVVEVTIFJFQ0lQSUVOVCdTIEFDQ0VQVEFOQ0UgT0YgVEhJUyBBR1JFRU1FTlQuCisKKzEuIERFRklOSVRJT05TCisKKyJDb250cmlidXRpb24iIG1lYW5zOgorCisgICAgICBhKSBpbiB0aGUgY2FzZSBvZiB0aGUgaW5pdGlhbCBDb250cmlidXRvciwgdGhlIGluaXRpYWwgY29kZSBhbmQKKyAgICAgICAgIGRvY3VtZW50YXRpb24gZGlzdHJpYnV0ZWQgdW5kZXIgdGhpcyBBZ3JlZW1lbnQsIGFuZAorICAgICAgYikgaW4gdGhlIGNhc2Ugb2YgZWFjaCBzdWJzZXF1ZW50IENvbnRyaWJ1dG9yOgorCisgICAgICBpKSBjaGFuZ2VzIHRvIHRoZSBQcm9ncmFtLCBhbmQKKworICAgICAgaWkpIGFkZGl0aW9ucyB0byB0aGUgUHJvZ3JhbTsKKworICAgICAgd2hlcmUgc3VjaCBjaGFuZ2VzIGFuZC9vciBhZGRpdGlvbnMgdG8gdGhlIFByb2dyYW0gb3JpZ2luYXRlCisgICAgICBmcm9tIGFuZCBhcmUgZGlzdHJpYnV0ZWQgYnkgdGhhdCBwYXJ0aWN1bGFyIENvbnRyaWJ1dG9yLiBBCisgICAgICBDb250cmlidXRpb24gJ29yaWdpbmF0ZXMnIGZyb20gYSBDb250cmlidXRvciBpZiBpdCB3YXMgYWRkZWQgdG8KKyAgICAgIHRoZSBQcm9ncmFtIGJ5IHN1Y2ggQ29udHJpYnV0b3IgaXRzZWxmIG9yIGFueW9uZSBhY3Rpbmcgb24gc3VjaAorICAgICAgQ29udHJpYnV0b3IncyBiZWhhbGYuIENvbnRyaWJ1dGlvbnMgZG8gbm90IGluY2x1ZGUgYWRkaXRpb25zIHRvCisgICAgICB0aGUgUHJvZ3JhbSB3aGljaDogKGkpIGFyZSBzZXBhcmF0ZSBtb2R1bGVzIG9mIHNvZnR3YXJlCisgICAgICBkaXN0cmlidXRlZCBpbiBjb25qdW5jdGlvbiB3aXRoIHRoZSBQcm9ncmFtIHVuZGVyIHRoZWlyIG93bgorICAgICAgbGljZW5zZSBhZ3JlZW1lbnQsIGFuZCAoaWkpIGFyZSBub3QgZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUKKyAgICAgIFByb2dyYW0uCisKKyJDb250cmlidXRvciIgbWVhbnMgYW55IHBlcnNvbiBvciBlbnRpdHkgdGhhdCBkaXN0cmlidXRlcyB0aGUgUHJvZ3JhbS4KKworIkxpY2Vuc2VkIFBhdGVudHMgIiBtZWFuIHBhdGVudCBjbGFpbXMgbGljZW5zYWJsZSBieSBhIENvbnRyaWJ1dG9yCit3aGljaCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZSB1c2Ugb3Igc2FsZSBvZiBpdHMgQ29udHJpYnV0aW9uCithbG9uZSBvciB3aGVuIGNvbWJpbmVkIHdpdGggdGhlIFByb2dyYW0uCisKKyJQcm9ncmFtIiBtZWFucyB0aGUgQ29udHJpYnV0aW9ucyBkaXN0cmlidXRlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhpcworQWdyZWVtZW50LgorCisiUmVjaXBpZW50IiBtZWFucyBhbnlvbmUgd2hvIHJlY2VpdmVzIHRoZSBQcm9ncmFtIHVuZGVyIHRoaXMKK0FncmVlbWVudCwgaW5jbHVkaW5nIGFsbCBDb250cmlidXRvcnMuCisKKzIuIEdSQU5UIE9GIFJJR0hUUworCisgICAgICBhKSBTdWJqZWN0IHRvIHRoZSB0ZXJtcyBvZiB0aGlzIEFncmVlbWVudCwgZWFjaCBDb250cmlidXRvcgorICAgICAgaGVyZWJ5IGdyYW50cyBSZWNpcGllbnQgYSBub24tZXhjbHVzaXZlLCB3b3JsZHdpZGUsIHJveWFsdHktZnJlZQorICAgICAgY29weXJpZ2h0IGxpY2Vuc2UgdG8gcmVwcm9kdWNlLCBwcmVwYXJlIGRlcml2YXRpdmUgd29ya3Mgb2YsCisgICAgICBwdWJsaWNseSBkaXNwbGF5LCBwdWJsaWNseSBwZXJmb3JtLCBkaXN0cmlidXRlIGFuZCBzdWJsaWNlbnNlCisgICAgICB0aGUgQ29udHJpYnV0aW9uIG9mIHN1Y2ggQ29udHJpYnV0b3IsIGlmIGFueSwgYW5kIHN1Y2gKKyAgICAgIGRlcml2YXRpdmUgd29ya3MsIGluIHNvdXJjZSBjb2RlIGFuZCBvYmplY3QgY29kZSBmb3JtLgorCisgICAgICBiKSBTdWJqZWN0IHRvIHRoZSB0ZXJtcyBvZiB0aGlzIEFncmVlbWVudCwgZWFjaCBDb250cmlidXRvcgorICAgICAgaGVyZWJ5IGdyYW50cyBSZWNpcGllbnQgYSBub24tZXhjbHVzaXZlLCB3b3JsZHdpZGUsIHJveWFsdHktZnJlZQorICAgICAgcGF0ZW50IGxpY2Vuc2UgdW5kZXIgTGljZW5zZWQgUGF0ZW50cyB0byBtYWtlLCB1c2UsIHNlbGwsIG9mZmVyCisgICAgICB0byBzZWxsLCBpbXBvcnQgYW5kIG90aGVyd2lzZSB0cmFuc2ZlciB0aGUgQ29udHJpYnV0aW9uIG9mIHN1Y2gKKyAgICAgIENvbnRyaWJ1dG9yLCBpZiBhbnksIGluIHNvdXJjZSBjb2RlIGFuZCBvYmplY3QgY29kZSBmb3JtLiBUaGlzCisgICAgICBwYXRlbnQgbGljZW5zZSBzaGFsbCBhcHBseSB0byB0aGUgY29tYmluYXRpb24gb2YgdGhlCisgICAgICBDb250cmlidXRpb24gYW5kIHRoZSBQcm9ncmFtIGlmLCBhdCB0aGUgdGltZSB0aGUgQ29udHJpYnV0aW9uIGlzCisgICAgICBhZGRlZCBieSB0aGUgQ29udHJpYnV0b3IsIHN1Y2ggYWRkaXRpb24gb2YgdGhlIENvbnRyaWJ1dGlvbgorICAgICAgY2F1c2VzIHN1Y2ggY29tYmluYXRpb24gdG8gYmUgY292ZXJlZCBieSB0aGUgTGljZW5zZWQgUGF0ZW50cy4KKyAgICAgIFRoZSBwYXRlbnQgbGljZW5zZSBzaGFsbCBub3QgYXBwbHkgdG8gYW55IG90aGVyIGNvbWJpbmF0aW9ucworICAgICAgd2hpY2ggaW5jbHVkZSB0aGUgQ29udHJpYnV0aW9uLiBObyBoYXJkd2FyZSBwZXIgc2UgaXMgbGljZW5zZWQKKyAgICAgIGhlcmV1bmRlci4KKworICAgICAgYykgUmVjaXBpZW50IHVuZGVyc3RhbmRzIHRoYXQgYWx0aG91Z2ggZWFjaCBDb250cmlidXRvciBncmFudHMKKyAgICAgIHRoZSBsaWNlbnNlcyB0byBpdHMgQ29udHJpYnV0aW9ucyBzZXQgZm9ydGggaGVyZWluLCBubworICAgICAgYXNzdXJhbmNlcyBhcmUgcHJvdmlkZWQgYnkgYW55IENvbnRyaWJ1dG9yIHRoYXQgdGhlIFByb2dyYW0gZG9lcworICAgICAgbm90IGluZnJpbmdlIHRoZSBwYXRlbnQgb3Igb3RoZXIgaW50ZWxsZWN0dWFsIHByb3BlcnR5IHJpZ2h0cyBvZgorICAgICAgYW55IG90aGVyIGVudGl0eS4gRWFjaCBDb250cmlidXRvciBkaXNjbGFpbXMgYW55IGxpYWJpbGl0eSB0bworICAgICAgUmVjaXBpZW50IGZvciBjbGFpbXMgYnJvdWdodCBieSBhbnkgb3RoZXIgZW50aXR5IGJhc2VkIG9uCisgICAgICBpbmZyaW5nZW1lbnQgb2YgaW50ZWxsZWN0dWFsIHByb3BlcnR5IHJpZ2h0cyBvciBvdGhlcndpc2UuIEFzIGEKKyAgICAgIGNvbmRpdGlvbiB0byBleGVyY2lzaW5nIHRoZSByaWdodHMgYW5kIGxpY2Vuc2VzIGdyYW50ZWQKKyAgICAgIGhlcmV1bmRlciwgZWFjaCBSZWNpcGllbnQgaGVyZWJ5IGFzc3VtZXMgc29sZSByZXNwb25zaWJpbGl0eSB0bworICAgICAgc2VjdXJlIGFueSBvdGhlciBpbnRlbGxlY3R1YWwgcHJvcGVydHkgcmlnaHRzIG5lZWRlZCwgaWYgYW55LgorICAgICAgRm9yIGV4YW1wbGUsIGlmIGEgdGhpcmQgcGFydHkgcGF0ZW50IGxpY2Vuc2UgaXMgcmVxdWlyZWQgdG8KKyAgICAgIGFsbG93IFJlY2lwaWVudCB0byBkaXN0cmlidXRlIHRoZSBQcm9ncmFtLCBpdCBpcyBSZWNpcGllbnQncworICAgICAgcmVzcG9uc2liaWxpdHkgdG8gYWNxdWlyZSB0aGF0IGxpY2Vuc2UgYmVmb3JlIGRpc3RyaWJ1dGluZyB0aGUKKyAgICAgIFByb2dyYW0uCisKKyAgICAgIGQpIEVhY2ggQ29udHJpYnV0b3IgcmVwcmVzZW50cyB0aGF0IHRvIGl0cyBrbm93bGVkZ2UgaXQgaGFzCisgICAgICBzdWZmaWNpZW50IGNvcHlyaWdodCByaWdodHMgaW4gaXRzIENvbnRyaWJ1dGlvbiwgaWYgYW55LCB0bworICAgICAgZ3JhbnQgdGhlIGNvcHlyaWdodCBsaWNlbnNlIHNldCBmb3J0aCBpbiB0aGlzIEFncmVlbWVudC4KKworMy4gUkVRVUlSRU1FTlRTCisKK0EgQ29udHJpYnV0b3IgbWF5IGNob29zZSB0byBkaXN0cmlidXRlIHRoZSBQcm9ncmFtIGluIG9iamVjdCBjb2RlIGZvcm0KK3VuZGVyIGl0cyBvd24gbGljZW5zZSBhZ3JlZW1lbnQsIHByb3ZpZGVkIHRoYXQ6CisKKyAgICAgIGEpIGl0IGNvbXBsaWVzIHdpdGggdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHRoaXMgQWdyZWVtZW50OyBhbmQKKworICAgICAgYikgaXRzIGxpY2Vuc2UgYWdyZWVtZW50OgorCisgICAgICBpKSBlZmZlY3RpdmVseSBkaXNjbGFpbXMgb24gYmVoYWxmIG9mIGFsbCBDb250cmlidXRvcnMgYWxsCisgICAgICB3YXJyYW50aWVzIGFuZCBjb25kaXRpb25zLCBleHByZXNzIGFuZCBpbXBsaWVkLCBpbmNsdWRpbmcKKyAgICAgIHdhcnJhbnRpZXMgb3IgY29uZGl0aW9ucyBvZiB0aXRsZSBhbmQgbm9uLWluZnJpbmdlbWVudCwgYW5kCisgICAgICBpbXBsaWVkIHdhcnJhbnRpZXMgb3IgY29uZGl0aW9ucyBvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MKKyAgICAgIGZvciBhIHBhcnRpY3VsYXIgcHVycG9zZTsKKworICAgICAgaWkpIGVmZmVjdGl2ZWx5IGV4Y2x1ZGVzIG9uIGJlaGFsZiBvZiBhbGwgQ29udHJpYnV0b3JzIGFsbAorICAgICAgbGlhYmlsaXR5IGZvciBkYW1hZ2VzLCBpbmNsdWRpbmcgZGlyZWN0LCBpbmRpcmVjdCwgc3BlY2lhbCwKKyAgICAgIGluY2lkZW50YWwgYW5kIGNvbnNlcXVlbnRpYWwgZGFtYWdlcywgc3VjaCBhcyBsb3N0IHByb2ZpdHM7CisKKyAgICAgIGlpaSkgc3RhdGVzIHRoYXQgYW55IHByb3Zpc2lvbnMgd2hpY2ggZGlmZmVyIGZyb20gdGhpcyBBZ3JlZW1lbnQKKyAgICAgIGFyZSBvZmZlcmVkIGJ5IHRoYXQgQ29udHJpYnV0b3IgYWxvbmUgYW5kIG5vdCBieSBhbnkgb3RoZXIKKyAgICAgIHBhcnR5OyBhbmQKKworICAgICAgaXYpIHN0YXRlcyB0aGF0IHNvdXJjZSBjb2RlIGZvciB0aGUgUHJvZ3JhbSBpcyBhdmFpbGFibGUgZnJvbQorICAgICAgc3VjaCBDb250cmlidXRvciwgYW5kIGluZm9ybXMgbGljZW5zZWVzIGhvdyB0byBvYnRhaW4gaXQgaW4gYQorICAgICAgcmVhc29uYWJsZSBtYW5uZXIgb24gb3IgdGhyb3VnaCBhIG1lZGl1bSBjdXN0b21hcmlseSB1c2VkIGZvcgorICAgICAgc29mdHdhcmUgZXhjaGFuZ2UuCisKK1doZW4gdGhlIFByb2dyYW0gaXMgbWFkZSBhdmFpbGFibGUgaW4gc291cmNlIGNvZGUgZm9ybToKKworICAgICAgYSkgaXQgbXVzdCBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGlzIEFncmVlbWVudDsgYW5kIAorCisgICAgICBiKSBhIGNvcHkgb2YgdGhpcyBBZ3JlZW1lbnQgbXVzdCBiZSBpbmNsdWRlZCB3aXRoIGVhY2ggY29weSBvZgorICAgICAgdGhlIFByb2dyYW0uCisKK0NvbnRyaWJ1dG9ycyBtYXkgbm90IHJlbW92ZSBvciBhbHRlciBhbnkgY29weXJpZ2h0IG5vdGljZXMgY29udGFpbmVkCit3aXRoaW4gdGhlIFByb2dyYW0uCisKK0VhY2ggQ29udHJpYnV0b3IgbXVzdCBpZGVudGlmeSBpdHNlbGYgYXMgdGhlIG9yaWdpbmF0b3Igb2YgaXRzCitDb250cmlidXRpb24sIGlmIGFueSwgaW4gYSBtYW5uZXIgdGhhdCByZWFzb25hYmx5IGFsbG93cyBzdWJzZXF1ZW50CitSZWNpcGllbnRzIHRvIGlkZW50aWZ5IHRoZSBvcmlnaW5hdG9yIG9mIHRoZSBDb250cmlidXRpb24uCisKKzQuIENPTU1FUkNJQUwgRElTVFJJQlVUSU9OCisKK0NvbW1lcmNpYWwgZGlzdHJpYnV0b3JzIG9mIHNvZnR3YXJlIG1heSBhY2NlcHQgY2VydGFpbgorcmVzcG9uc2liaWxpdGllcyB3aXRoIHJlc3BlY3QgdG8gZW5kIHVzZXJzLCBidXNpbmVzcyBwYXJ0bmVycyBhbmQgdGhlCitsaWtlLiBXaGlsZSB0aGlzIGxpY2Vuc2UgaXMgaW50ZW5kZWQgdG8gZmFjaWxpdGF0ZSB0aGUgY29tbWVyY2lhbCB1c2UKK29mIHRoZSBQcm9ncmFtLCB0aGUgQ29udHJpYnV0b3Igd2hvIGluY2x1ZGVzIHRoZSBQcm9ncmFtIGluIGEKK2NvbW1lcmNpYWwgcHJvZHVjdCBvZmZlcmluZyBzaG91bGQgZG8gc28gaW4gYSBtYW5uZXIgd2hpY2ggZG9lcyBub3QKK2NyZWF0ZSBwb3RlbnRpYWwgbGlhYmlsaXR5IGZvciBvdGhlciBDb250cmlidXRvcnMuIFRoZXJlZm9yZSwgaWYgYQorQ29udHJpYnV0b3IgaW5jbHVkZXMgdGhlIFByb2dyYW0gaW4gYSBjb21tZXJjaWFsIHByb2R1Y3Qgb2ZmZXJpbmcsCitzdWNoIENvbnRyaWJ1dG9yICgiQ29tbWVyY2lhbCBDb250cmlidXRvciIpIGhlcmVieSBhZ3JlZXMgdG8gZGVmZW5kCithbmQgaW5kZW1uaWZ5IGV2ZXJ5IG90aGVyIENvbnRyaWJ1dG9yICgiSW5kZW1uaWZpZWQgQ29udHJpYnV0b3IiKQorYWdhaW5zdCBhbnkgbG9zc2VzLCBkYW1hZ2VzIGFuZCBjb3N0cyAoY29sbGVjdGl2ZWx5ICJMb3NzZXMiKSBhcmlzaW5nCitmcm9tIGNsYWltcywgbGF3c3VpdHMgYW5kIG90aGVyIGxlZ2FsIGFjdGlvbnMgYnJvdWdodCBieSBhIHRoaXJkIHBhcnR5CithZ2FpbnN0IHRoZSBJbmRlbW5pZmllZCBDb250cmlidXRvciB0byB0aGUgZXh0ZW50IGNhdXNlZCBieSB0aGUgYWN0cworb3Igb21pc3Npb25zIG9mIHN1Y2ggQ29tbWVyY2lhbCBDb250cmlidXRvciBpbiBjb25uZWN0aW9uIHdpdGggaXRzCitkaXN0cmlidXRpb24gb2YgdGhlIFByb2dyYW0gaW4gYSBjb21tZXJjaWFsIHByb2R1Y3Qgb2ZmZXJpbmcuIFRoZQorb2JsaWdhdGlvbnMgaW4gdGhpcyBzZWN0aW9uIGRvIG5vdCBhcHBseSB0byBhbnkgY2xhaW1zIG9yIExvc3NlcworcmVsYXRpbmcgdG8gYW55IGFjdHVhbCBvciBhbGxlZ2VkIGludGVsbGVjdHVhbCBwcm9wZXJ0eSBpbmZyaW5nZW1lbnQuCitJbiBvcmRlciB0byBxdWFsaWZ5LCBhbiBJbmRlbW5pZmllZCBDb250cmlidXRvciBtdXN0OiBhKSBwcm9tcHRseQorbm90aWZ5IHRoZSBDb21tZXJjaWFsIENvbnRyaWJ1dG9yIGluIHdyaXRpbmcgb2Ygc3VjaCBjbGFpbSwgYW5kIGIpCithbGxvdyB0aGUgQ29tbWVyY2lhbCBDb250cmlidXRvciB0byBjb250cm9sLCBhbmQgY29vcGVyYXRlIHdpdGggdGhlCitDb21tZXJjaWFsIENvbnRyaWJ1dG9yIGluLCB0aGUgZGVmZW5zZSBhbmQgYW55IHJlbGF0ZWQgc2V0dGxlbWVudAorbmVnb3RpYXRpb25zLiBUaGUgSW5kZW1uaWZpZWQgQ29udHJpYnV0b3IgbWF5IHBhcnRpY2lwYXRlIGluIGFueSBzdWNoCitjbGFpbSBhdCBpdHMgb3duIGV4cGVuc2UuCisKK0ZvciBleGFtcGxlLCBhIENvbnRyaWJ1dG9yIG1pZ2h0IGluY2x1ZGUgdGhlIFByb2dyYW0gaW4gYSBjb21tZXJjaWFsCitwcm9kdWN0IG9mZmVyaW5nLCBQcm9kdWN0IFguIFRoYXQgQ29udHJpYnV0b3IgaXMgdGhlbiBhIENvbW1lcmNpYWwKK0NvbnRyaWJ1dG9yLiBJZiB0aGF0IENvbW1lcmNpYWwgQ29udHJpYnV0b3IgdGhlbiBtYWtlcyBwZXJmb3JtYW5jZQorY2xhaW1zLCBvciBvZmZlcnMgd2FycmFudGllcyByZWxhdGVkIHRvIFByb2R1Y3QgWCwgdGhvc2UgcGVyZm9ybWFuY2UKK2NsYWltcyBhbmQgd2FycmFudGllcyBhcmUgc3VjaCBDb21tZXJjaWFsIENvbnRyaWJ1dG9yJ3MgcmVzcG9uc2liaWxpdHkKK2Fsb25lLiBVbmRlciB0aGlzIHNlY3Rpb24sIHRoZSBDb21tZXJjaWFsIENvbnRyaWJ1dG9yIHdvdWxkIGhhdmUgdG8KK2RlZmVuZCBjbGFpbXMgYWdhaW5zdCB0aGUgb3RoZXIgQ29udHJpYnV0b3JzIHJlbGF0ZWQgdG8gdGhvc2UKK3BlcmZvcm1hbmNlIGNsYWltcyBhbmQgd2FycmFudGllcywgYW5kIGlmIGEgY291cnQgcmVxdWlyZXMgYW55IG90aGVyCitDb250cmlidXRvciB0byBwYXkgYW55IGRhbWFnZXMgYXMgYSByZXN1bHQsIHRoZSBDb21tZXJjaWFsIENvbnRyaWJ1dG9yCittdXN0IHBheSB0aG9zZSBkYW1hZ2VzLgorCis1LiBOTyBXQVJSQU5UWQorCitFWENFUFQgQVMgRVhQUkVTU0xZIFNFVCBGT1JUSCBJTiBUSElTIEFHUkVFTUVOVCwgVEhFIFBST0dSQU0gSVMKK1BST1ZJREVEIE9OIEFOICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorS0lORCwgRUlUSEVSIEVYUFJFU1MgT1IgSU1QTElFRCBJTkNMVURJTkcsIFdJVEhPVVQgTElNSVRBVElPTiwgQU5ZCitXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWQorT1IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIEVhY2ggUmVjaXBpZW50IGlzIHNvbGVseQorcmVzcG9uc2libGUgZm9yIGRldGVybWluaW5nIHRoZSBhcHByb3ByaWF0ZW5lc3Mgb2YgdXNpbmcgYW5kCitkaXN0cmlidXRpbmcgdGhlIFByb2dyYW0gYW5kIGFzc3VtZXMgYWxsIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBpdHMKK2V4ZXJjaXNlIG9mIHJpZ2h0cyB1bmRlciB0aGlzIEFncmVlbWVudCwgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwordGhlIHJpc2tzIGFuZCBjb3N0cyBvZiBwcm9ncmFtIGVycm9ycywgY29tcGxpYW5jZSB3aXRoIGFwcGxpY2FibGUKK2xhd3MsIGRhbWFnZSB0byBvciBsb3NzIG9mIGRhdGEsIHByb2dyYW1zIG9yIGVxdWlwbWVudCwgYW5kCit1bmF2YWlsYWJpbGl0eSBvciBpbnRlcnJ1cHRpb24gb2Ygb3BlcmF0aW9ucy4KKworNi4gRElTQ0xBSU1FUiBPRiBMSUFCSUxJVFkKKworRVhDRVBUIEFTIEVYUFJFU1NMWSBTRVQgRk9SVEggSU4gVEhJUyBBR1JFRU1FTlQsIE5FSVRIRVIgUkVDSVBJRU5UIE5PUgorQU5ZIENPTlRSSUJVVE9SUyBTSEFMTCBIQVZFIEFOWSBMSUFCSUxJVFkgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULAorSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORworV0lUSE9VVCBMSU1JVEFUSU9OIExPU1QgUFJPRklUUyksIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GCitMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORworTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPUgorRElTVFJJQlVUSU9OIE9GIFRIRSBQUk9HUkFNIE9SIFRIRSBFWEVSQ0lTRSBPRiBBTlkgUklHSFRTIEdSQU5URUQKK0hFUkVVTkRFUiwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRVMuCisKKzcuIEdFTkVSQUwKKworSWYgYW55IHByb3Zpc2lvbiBvZiB0aGlzIEFncmVlbWVudCBpcyBpbnZhbGlkIG9yIHVuZW5mb3JjZWFibGUgdW5kZXIKK2FwcGxpY2FibGUgbGF3LCBpdCBzaGFsbCBub3QgYWZmZWN0IHRoZSB2YWxpZGl0eSBvciBlbmZvcmNlYWJpbGl0eSBvZgordGhlIHJlbWFpbmRlciBvZiB0aGUgdGVybXMgb2YgdGhpcyBBZ3JlZW1lbnQsIGFuZCB3aXRob3V0IGZ1cnRoZXIKK2FjdGlvbiBieSB0aGUgcGFydGllcyBoZXJldG8sIHN1Y2ggcHJvdmlzaW9uIHNoYWxsIGJlIHJlZm9ybWVkIHRvIHRoZQorbWluaW11bSBleHRlbnQgbmVjZXNzYXJ5IHRvIG1ha2Ugc3VjaCBwcm92aXNpb24gdmFsaWQgYW5kIGVuZm9yY2VhYmxlLgorCitJZiBSZWNpcGllbnQgaW5zdGl0dXRlcyBwYXRlbnQgbGl0aWdhdGlvbiBhZ2FpbnN0IGEgQ29udHJpYnV0b3Igd2l0aAorcmVzcGVjdCB0byBhIHBhdGVudCBhcHBsaWNhYmxlIHRvIHNvZnR3YXJlIChpbmNsdWRpbmcgYSBjcm9zcy1jbGFpbSBvcgorY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCksIHRoZW4gYW55IHBhdGVudCBsaWNlbnNlcyBncmFudGVkIGJ5IHRoYXQKK0NvbnRyaWJ1dG9yIHRvIHN1Y2ggUmVjaXBpZW50IHVuZGVyIHRoaXMgQWdyZWVtZW50IHNoYWxsIHRlcm1pbmF0ZSBhcworb2YgdGhlIGRhdGUgc3VjaCBsaXRpZ2F0aW9uIGlzIGZpbGVkLiBJbiBhZGRpdGlvbiwgaWYgUmVjaXBpZW50CitpbnN0aXR1dGVzIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKK2Nyb3NzLWNsYWltIG9yIGNvdW50ZXJjbGFpbSBpbiBhIGxhd3N1aXQpIGFsbGVnaW5nIHRoYXQgdGhlIFByb2dyYW0KK2l0c2VsZiAoZXhjbHVkaW5nIGNvbWJpbmF0aW9ucyBvZiB0aGUgUHJvZ3JhbSB3aXRoIG90aGVyIHNvZnR3YXJlIG9yCitoYXJkd2FyZSkgaW5mcmluZ2VzIHN1Y2ggUmVjaXBpZW50J3MgcGF0ZW50KHMpLCB0aGVuIHN1Y2ggUmVjaXBpZW50J3MKK3JpZ2h0cyBncmFudGVkIHVuZGVyIFNlY3Rpb24gMihiKSBzaGFsbCB0ZXJtaW5hdGUgYXMgb2YgdGhlIGRhdGUgc3VjaAorbGl0aWdhdGlvbiBpcyBmaWxlZC4KKworQWxsIFJlY2lwaWVudCdzIHJpZ2h0cyB1bmRlciB0aGlzIEFncmVlbWVudCBzaGFsbCB0ZXJtaW5hdGUgaWYgaXQKK2ZhaWxzIHRvIGNvbXBseSB3aXRoIGFueSBvZiB0aGUgbWF0ZXJpYWwgdGVybXMgb3IgY29uZGl0aW9ucyBvZiB0aGlzCitBZ3JlZW1lbnQgYW5kIGRvZXMgbm90IGN1cmUgc3VjaCBmYWlsdXJlIGluIGEgcmVhc29uYWJsZSBwZXJpb2Qgb2YKK3RpbWUgYWZ0ZXIgYmVjb21pbmcgYXdhcmUgb2Ygc3VjaCBub25jb21wbGlhbmNlLiBJZiBhbGwgUmVjaXBpZW50J3MKK3JpZ2h0cyB1bmRlciB0aGlzIEFncmVlbWVudCB0ZXJtaW5hdGUsIFJlY2lwaWVudCBhZ3JlZXMgdG8gY2Vhc2UgdXNlCithbmQgZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9ncmFtIGFzIHNvb24gYXMgcmVhc29uYWJseSBwcmFjdGljYWJsZS4KK0hvd2V2ZXIsIFJlY2lwaWVudCdzIG9ibGlnYXRpb25zIHVuZGVyIHRoaXMgQWdyZWVtZW50IGFuZCBhbnkgbGljZW5zZXMKK2dyYW50ZWQgYnkgUmVjaXBpZW50IHJlbGF0aW5nIHRvIHRoZSBQcm9ncmFtIHNoYWxsIGNvbnRpbnVlIGFuZAorc3Vydml2ZS4KKworRXZlcnlvbmUgaXMgcGVybWl0dGVkIHRvIGNvcHkgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoaXMgQWdyZWVtZW50LAorYnV0IGluIG9yZGVyIHRvIGF2b2lkIGluY29uc2lzdGVuY3kgdGhlIEFncmVlbWVudCBpcyBjb3B5cmlnaHRlZCBhbmQKK21heSBvbmx5IGJlIG1vZGlmaWVkIGluIHRoZSBmb2xsb3dpbmcgbWFubmVyLiBUaGUgQWdyZWVtZW50IFN0ZXdhcmQKK3Jlc2VydmVzIHRoZSByaWdodCB0byBwdWJsaXNoIG5ldyB2ZXJzaW9ucyAoaW5jbHVkaW5nIHJldmlzaW9ucykgb2YKK3RoaXMgQWdyZWVtZW50IGZyb20gdGltZSB0byB0aW1lLiBObyBvbmUgb3RoZXIgdGhhbiB0aGUgQWdyZWVtZW50CitTdGV3YXJkIGhhcyB0aGUgcmlnaHQgdG8gbW9kaWZ5IHRoaXMgQWdyZWVtZW50LiBJQk0gaXMgdGhlIGluaXRpYWwKK0FncmVlbWVudCBTdGV3YXJkLiBJQk0gbWF5IGFzc2lnbiB0aGUgcmVzcG9uc2liaWxpdHkgdG8gc2VydmUgYXMgdGhlCitBZ3JlZW1lbnQgU3Rld2FyZCB0byBhIHN1aXRhYmxlIHNlcGFyYXRlIGVudGl0eS4gRWFjaCBuZXcgdmVyc2lvbiBvZgordGhlIEFncmVlbWVudCB3aWxsIGJlIGdpdmVuIGEgZGlzdGluZ3Vpc2hpbmcgdmVyc2lvbiBudW1iZXIuIFRoZQorUHJvZ3JhbSAoaW5jbHVkaW5nIENvbnRyaWJ1dGlvbnMpIG1heSBhbHdheXMgYmUgZGlzdHJpYnV0ZWQgc3ViamVjdCB0bwordGhlIHZlcnNpb24gb2YgdGhlIEFncmVlbWVudCB1bmRlciB3aGljaCBpdCB3YXMgcmVjZWl2ZWQuIEluIGFkZGl0aW9uLAorYWZ0ZXIgYSBuZXcgdmVyc2lvbiBvZiB0aGUgQWdyZWVtZW50IGlzIHB1Ymxpc2hlZCwgQ29udHJpYnV0b3IgbWF5CitlbGVjdCB0byBkaXN0cmlidXRlIHRoZSBQcm9ncmFtIChpbmNsdWRpbmcgaXRzIENvbnRyaWJ1dGlvbnMpIHVuZGVyCit0aGUgbmV3IHZlcnNpb24uIEV4Y2VwdCBhcyBleHByZXNzbHkgc3RhdGVkIGluIFNlY3Rpb25zIDIoYSkgYW5kIDIoYikKK2Fib3ZlLCBSZWNpcGllbnQgcmVjZWl2ZXMgbm8gcmlnaHRzIG9yIGxpY2Vuc2VzIHRvIHRoZSBpbnRlbGxlY3R1YWwKK3Byb3BlcnR5IG9mIGFueSBDb250cmlidXRvciB1bmRlciB0aGlzIEFncmVlbWVudCwgd2hldGhlciBleHByZXNzbHksCitieSBpbXBsaWNhdGlvbiwgZXN0b3BwZWwgb3Igb3RoZXJ3aXNlLiBBbGwgcmlnaHRzIGluIHRoZSBQcm9ncmFtIG5vdAorZXhwcmVzc2x5IGdyYW50ZWQgdW5kZXIgdGhpcyBBZ3JlZW1lbnQgYXJlIHJlc2VydmVkLgorCitUaGlzIEFncmVlbWVudCBpcyBnb3Zlcm5lZCBieSB0aGUgbGF3cyBvZiB0aGUgU3RhdGUgb2YgTmV3IFlvcmsgYW5kCit0aGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5IGxhd3Mgb2YgdGhlIFVuaXRlZCBTdGF0ZXMgb2YgQW1lcmljYS4gTm8KK3BhcnR5IHRvIHRoaXMgQWdyZWVtZW50IHdpbGwgYnJpbmcgYSBsZWdhbCBhY3Rpb24gdW5kZXIgdGhpcyBBZ3JlZW1lbnQKK21vcmUgdGhhbiBvbmUgeWVhciBhZnRlciB0aGUgY2F1c2Ugb2YgYWN0aW9uIGFyb3NlLiBFYWNoIHBhcnR5IHdhaXZlcworaXRzIHJpZ2h0cyB0byBhIGp1cnkgdHJpYWwgaW4gYW55IHJlc3VsdGluZyBsaXRpZ2F0aW9uLgorCisKKyAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgID09ICBOT1RJQ0UgZmlsZSBmb3IgdGhlIEtYTUwgTGljZW5zZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT0KKyAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworQ29weXJpZ2h0IChjKSAyMDAyLDIwMDMsIFN0ZWZhbiBIYXVzdGVpbiwgT2JlcmhhdXNlbiwgUmhsZC4sIEdlcm1hbnkKKworUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nCithIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUKKyJTb2Z0d2FyZSIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcKK3dpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwKK2Rpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0bworcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvCit0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CisKK1RoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlCitpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KKworVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCitFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YKK01FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4KK0lOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZCitDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULAorVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUKK1NPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgorCisKKyAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgID09ICBOT1RJQ0UgZmlsZSBmb3IgdGhlIFNRTGl0ZSBKYXZhIFdyYXBwZXIgTGljZW5zZS4gICAgICAgICAgICAgICAgICAgPT0KKyAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworVGhpcyBzb2Z0d2FyZSBpcyBjb3B5cmlnaHRlZCBieSBDaHJpc3RpYW4gV2VybmVyIDxjaHdAY2gtd2VybmVyLmRlPgorYW5kIG90aGVycy4gVGhlIGZvbGxvd2luZyB0ZXJtcyBhcHBseSB0byBhbGwgZmlsZXMgYXNzb2NpYXRlZCB3aXRoIHRoZQorc29mdHdhcmUgdW5sZXNzIGV4cGxpY2l0bHkgZGlzY2xhaW1lZCBpbiBpbmRpdmlkdWFsIGZpbGVzLgorCitUaGUgYXV0aG9ycyBoZXJlYnkgZ3JhbnQgcGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwKK2FuZCBsaWNlbnNlIHRoaXMgc29mdHdhcmUgYW5kIGl0cyBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSwgcHJvdmlkZWQKK3RoYXQgZXhpc3RpbmcgY29weXJpZ2h0IG5vdGljZXMgYXJlIHJldGFpbmVkIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgdGhpcworbm90aWNlIGlzIGluY2x1ZGVkIHZlcmJhdGltIGluIGFueSBkaXN0cmlidXRpb25zLiBObyB3cml0dGVuIGFncmVlbWVudCwKK2xpY2Vuc2UsIG9yIHJveWFsdHkgZmVlIGlzIHJlcXVpcmVkIGZvciBhbnkgb2YgdGhlIGF1dGhvcml6ZWQgdXNlcy4KK01vZGlmaWNhdGlvbnMgdG8gdGhpcyBzb2Z0d2FyZSBtYXkgYmUgY29weXJpZ2h0ZWQgYnkgdGhlaXIgYXV0aG9ycworYW5kIG5lZWQgbm90IGZvbGxvdyB0aGUgbGljZW5zaW5nIHRlcm1zIGRlc2NyaWJlZCBoZXJlLCBwcm92aWRlZCB0aGF0Cit0aGUgbmV3IHRlcm1zIGFyZSBjbGVhcmx5IGluZGljYXRlZCBvbiB0aGUgZmlyc3QgcGFnZSBvZiBlYWNoIGZpbGUgd2hlcmUKK3RoZXkgYXBwbHkuCisKK0lOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIERJU1RSSUJVVE9SUyBCRSBMSUFCTEUgVE8gQU5ZIFBBUlRZCitGT1IgRElSRUNULCBJTkRJUkVDVCwgU1BFQ0lBTCwgSU5DSURFTlRBTCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTCitBUklTSU5HIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIElUUyBET0NVTUVOVEFUSU9OLCBPUiBBTlkKK0RFUklWQVRJVkVTIFRIRVJFT0YsIEVWRU4gSUYgVEhFIEFVVEhPUlMgSEFWRSBCRUVOIEFEVklTRUQgT0YgVEhFCitQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworVEhFIEFVVEhPUlMgQU5EIERJU1RSSUJVVE9SUyBTUEVDSUZJQ0FMTFkgRElTQ0xBSU0gQU5ZIFdBUlJBTlRJRVMsCitJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCitGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSwgQU5EIE5PTi1JTkZSSU5HRU1FTlQuICBUSElTIFNPRlRXQVJFCitJUyBQUk9WSURFRCBPTiBBTiAiQVMgSVMiIEJBU0lTLCBBTkQgVEhFIEFVVEhPUlMgQU5EIERJU1RSSUJVVE9SUyBIQVZFCitOTyBPQkxJR0FUSU9OIFRPIFBST1ZJREUgTUFJTlRFTkFOQ0UsIFNVUFBPUlQsIFVQREFURVMsIEVOSEFOQ0VNRU5UUywgT1IKK01PRElGSUNBVElPTlMuCisKKworICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICAgPT0gIE5PVElDRSBmaWxlIGZvciB0aGUgVzNDIExpY2Vuc2UuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PQorICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlCitvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuCitBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzCitkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuCitUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0CitXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCitNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgpkaWZmIC0tZ2l0IGEvTmF0aXZlQ29kZS5tayBiL05hdGl2ZUNvZGUubWsKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWU3YzRmNAotLS0gL2Rldi9udWxsCisrKyBiL05hdGl2ZUNvZGUubWsKQEAgLTAsMCArMSwxMjYgQEAKKyMgLSotIG1vZGU6IG1ha2VmaWxlIC0qLQorIyBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworIworIyBEZWZpbml0aW9ucyBmb3IgYnVpbGRpbmcgdGhlIG5hdGl2ZSBjb2RlIG5lZWRlZCBmb3IgdGhlIGNvcmUgbGlicmFyeS4KKyMKKworIworIyBDb21tb24gZGVmaW5pdGlvbnMgZm9yIGhvc3QgYW5kIHRhcmdldC4KKyMKKworIyBHZXQgdGhlIGxpc3Qgb2YgYWxsIG5hdGl2ZSBkaXJlY3RvcmllcyB0aGF0IGNvbnRhaW4gc3ViLm1rIGZpbGVzLgorIyBXZSdyZSB1c2luZyAic3ViLm1rIiB0byBtYWtlIGl0IGNsZWFyIHRoYXQgdGhlc2UgYXJlIG5vdCB0eXBpY2FsCisjIGFuZHJvaWQgbWFrZWZpbGVzLgorZGVmaW5lIGFsbC1jb3JlLW5hdGl2ZS1kaXJzCiskKHBhdHN1YnN0ICUvc3ViLm1rLCUsJChzaGVsbCBjZCAkKExPQ0FMX1BBVEgpICYmIGxzIC1kICovc3JjLyQoMSkvbmF0aXZlL3N1Yi5tayAyPiAvZGV2L251bGwpKQorZW5kZWYKKworIyBUaGVzZSB0d28gZGVmaW5pdGlvbnMgYXJlIHVzZWQgdG8gaGVscCBzYW5pdHkgY2hlY2sgd2hhdCdzIHB1dCBpbgorIyBzdWIubWsuIFNlZSwgdGhlICJlcnJvciIgZGlyZWN0aXZlcyBpbW1lZGlhdGVseSBiZWxvdy4KK2NvcmVfbWFnaWNfbG9jYWxfdGFyZ2V0IDo9IC4uLi8vOjpkZWZhdWx0OjovLy4uLgorY29yZV9sb2NhbF9wYXRoIDo9ICQoTE9DQUxfUEFUSCkKKworIyBJbmNsdWRlIGEgc3VibWFrZWZpbGUsIHJlc29sdmUgaXRzIHNvdXJjZSBmaWxlIGxvY2F0aW9ucywKKyMgYW5kIHN0aWNrIHRoZW0gb24gY29yZV9zcmNfZmlsZXMuICBUaGUgc3VibWFrZWZpbGVzIGFyZQorIyBmcmVlIHRvIGFwcGVuZCB0byBMT0NBTF9TUkNfRklMRVMsIExPQ0FMX0NfSU5DTFVERVMsCisjIExPQ0FMX1NIQVJFRF9MSUJSQVJJRVMsIG9yIExPQ0FMX1NUQVRJQ19MSUJSQVJJRVMsIGJ1dCBub3RoaW5nCisjIGVsc2UuIEFsbCBvdGhlciBMT0NBTF8qIHZhcmlhYmxlcyB3aWxsIGJlIGlnbm9yZWQuCisjCisjICQoMSk6IGRpcmVjdG9yeSBjb250YWluaW5nIHRoZSBtYWtlZmlsZSB0byBpbmNsdWRlCitkZWZpbmUgaW5jbHVkZS1jb3JlLW5hdGl2ZS1kaXIKKyAgICBMT0NBTF9TUkNfRklMRVMgOj0KKyAgICBpbmNsdWRlICQoTE9DQUxfUEFUSCkvJCgxKS9zdWIubWsKKyAgICBpZm5lcSAoJCQoTE9DQUxfTU9EVUxFKSwkKGNvcmVfbWFnaWNfbG9jYWxfdGFyZ2V0KSkKKyAgICAgICAgJCQoZXJyb3IgJChMT0NBTF9QQVRIKS8kKDEpL3N1Yi5tayBzaG91bGQgbm90IGluY2x1ZGUgQ0xFQVJfVkFSUyBcCisgICAgICAgICAgICBvciBkZWZpbmUgTE9DQUxfTU9EVUxFKQorICAgIGVuZGlmCisgICAgaWZuZXEgKCQkKExPQ0FMX1BBVEgpLCQoY29yZV9sb2NhbF9wYXRoKSkKKyAgICAgICAgJCQoZXJyb3IgJChMT0NBTF9QQVRIKS8kKDEpL3N1Yi5tayBzaG91bGQgbm90IGRlZmluZSBMT0NBTF9QQVRIKQorICAgIGVuZGlmCisgICAgY29yZV9zcmNfZmlsZXMgKz0gJCQoYWRkcHJlZml4ICQoMSkvLCQkKExPQ0FMX1NSQ19GSUxFUykpCisgICAgTE9DQUxfU1JDX0ZJTEVTIDo9CitlbmRlZgorCisjIEZpbmQgYW55IG5hdGl2ZSBkaXJlY3RvcmllcyBjb250YWluaW5nIHN1Yi5tayBmaWxlcy4KK2NvcmVfbmF0aXZlX2RpcnMgOj0gJChzdHJpcCAkKGNhbGwgYWxsLWNvcmUtbmF0aXZlLWRpcnMsbWFpbikpCitpZmVxICgkKGNvcmVfbmF0aXZlX2RpcnMpLCkKKyAgICAkKGVycm9yIE5vIG5hdGl2ZSBjb2RlIGRlZmluZWQgZm9yIGxpYmNvcmUpCitlbmRpZgorCisjIFNldCB1cCB0aGUgZGVmYXVsdCBzdGF0ZS4gTm90ZTogV2UgdXNlIENMRUFSX1ZBUlMgaGVyZSwgZXZlbiB0aG91Z2gKKyMgd2UgYXJlbid0IHF1aXRlIGRlZmluaW5nIGEgbmV3IHJ1bGUgeWV0LCB0byBtYWtlIHN1cmUgdGhhdCB0aGUKKyMgc3ViLm1rIGZpbGVzIGRvbid0IHNlZSBhbnl0aGluZyBzdHJheSBmcm9tIHRoZSBsYXN0IHJ1bGUgdGhhdCB3YXMKKyMgc2V0IHVwLgoraW5jbHVkZSAkKENMRUFSX1ZBUlMpCitMT0NBTF9NT0RVTEUgOj0gJChjb3JlX21hZ2ljX2xvY2FsX3RhcmdldCkKK2NvcmVfc3JjX2ZpbGVzIDo9CisKKyMgSW5jbHVkZSB0aGUgc3ViLm1rIGZpbGVzLgorJChmb3JlYWNoIGRpciwgXAorICAgICQoY29yZV9uYXRpdmVfZGlycyksIFwKKyAgICAkKGV2YWwgJChjYWxsIGluY2x1ZGUtY29yZS1uYXRpdmUtZGlyLCQoZGlyKSkpKQorCisjIEV4dHJhY3Qgb3V0IHRoZSBhbGxvd2VkIExPQ0FMXyogdmFyaWFibGVzLiBOb3RlOiAkKHNvcnQpIGFsc28KKyMgcmVtb3ZlcyBkdXBsaWNhdGVzLgorY29yZV9jX2luY2x1ZGVzIDo9ICQoc29ydCBsaWJjb3JlL2luY2x1ZGUgJChMT0NBTF9DX0lOQ0xVREVTKSAkKEpOSV9IX0lOQ0xVREUpKQorY29yZV9zaGFyZWRfbGlicmFyaWVzIDo9ICQoc29ydCAkKExPQ0FMX1NIQVJFRF9MSUJSQVJJRVMpKQorY29yZV9zdGF0aWNfbGlicmFyaWVzIDo9ICQoc29ydCAkKExPQ0FMX1NUQVRJQ19MSUJSQVJJRVMpKQorY29yZV9jZmxhZ3MgOj0gLWZ2aXNpYmlsaXR5PWhpZGRlbiAtZnZpc2liaWxpdHktaW5saW5lcy1oaWRkZW4KK2NvcmVfY2ZsYWdzICs9ICctREdDQ19ISURERU49X19hdHRyaWJ1dGVfXygodmlzaWJpbGl0eSgiaGlkZGVuIikpKScKKworCisjCisjIEJ1aWxkIGZvciB0aGUgdGFyZ2V0IChkZXZpY2UpLgorIworCitpbmNsdWRlICQoQ0xFQVJfVkFSUykKKworTE9DQUxfQ0ZMQUdTICs9IC1XYWxsIC1XZXh0cmEgLVdlcnJvcgorTE9DQUxfQ0ZMQUdTICs9ICQoY29yZV9jZmxhZ3MpCitpZmVxICgkKFRBUkdFVF9BUkNIKSxhcm0pCisjIElnbm9yZSAibm90ZTogdGhlIG1hbmdsaW5nIG9mICd2YV9saXN0JyBoYXMgY2hhbmdlZCBpbiBHQ0MgNC40IgorTE9DQUxfQ0ZMQUdTICs9IC1Xbm8tcHNhYmkKK2VuZGlmCisKKyMgRGVmaW5lIHRoZSBydWxlcy4KK0xPQ0FMX1NSQ19GSUxFUyA6PSAkKGNvcmVfc3JjX2ZpbGVzKQorTE9DQUxfQ19JTkNMVURFUyA6PSAkKGNvcmVfY19pbmNsdWRlcykKK0xPQ0FMX1NIQVJFRF9MSUJSQVJJRVMgOj0gJChjb3JlX3NoYXJlZF9saWJyYXJpZXMpCitMT0NBTF9TVEFUSUNfTElCUkFSSUVTIDo9ICQoY29yZV9zdGF0aWNfbGlicmFyaWVzKQorTE9DQUxfTU9EVUxFX1RBR1MgOj0gb3B0aW9uYWwKK0xPQ0FMX01PRFVMRSA6PSBsaWJqYXZhY29yZQorCitMT0NBTF9DX0lOQ0xVREVTICs9IGV4dGVybmFsL3N0bHBvcnQvc3RscG9ydCBiaW9uaWMvIGJpb25pYy9saWJzdGRjKysvaW5jbHVkZQorTE9DQUxfU0hBUkVEX0xJQlJBUklFUyArPSBsaWJzdGxwb3J0CisKK2luY2x1ZGUgJChCVUlMRF9TVEFUSUNfTElCUkFSWSkKKworIworIyBCdWlsZCBmb3IgdGhlIGhvc3QuCisjCisKK2lmZXEgKCQoV0lUSF9IT1NUX0RBTFZJSyksdHJ1ZSkKKyAgICBpbmNsdWRlICQoQ0xFQVJfVkFSUykKKyAgICAjIERlZmluZSB0aGUgcnVsZXMuCisgICAgTE9DQUxfU1JDX0ZJTEVTIDo9ICQoY29yZV9zcmNfZmlsZXMpCisgICAgTE9DQUxfQ0ZMQUdTICs9ICQoY29yZV9jZmxhZ3MpCisgICAgTE9DQUxfQ19JTkNMVURFUyA6PSAkKGNvcmVfY19pbmNsdWRlcykKKyAgICBMT0NBTF9TSEFSRURfTElCUkFSSUVTIDo9ICQoY29yZV9zaGFyZWRfbGlicmFyaWVzKQorICAgIExPQ0FMX1NUQVRJQ19MSUJSQVJJRVMgOj0gJChjb3JlX3N0YXRpY19saWJyYXJpZXMpCisgICAgTE9DQUxfTU9EVUxFX1RBR1MgOj0gb3B0aW9uYWwKKyAgICBMT0NBTF9NT0RVTEUgOj0gbGliamF2YWNvcmUtaG9zdAorICAgIGluY2x1ZGUgJChCVUlMRF9IT1NUX1NUQVRJQ19MSUJSQVJZKQorZW5kaWYKZGlmZiAtLWdpdCBhL1RoaXJkUGFydHlQcm9qZWN0LnByb3AgYi9UaGlyZFBhcnR5UHJvamVjdC5wcm9wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmODI4ZmEKLS0tIC9kZXYvbnVsbAorKysgYi9UaGlyZFBhcnR5UHJvamVjdC5wcm9wCkBAIC0wLDAgKzEsOSBAQAorIyBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgorI0ZyaSBKdWwgMTYgMTA6MDM6MDggUERUIDIwMTAKK2N1cnJlbnRWZXJzaW9uPTUuME0xMAordmVyc2lvbj1Vbmtub3duCitpc05hdGl2ZT1mYWxzZQorbmFtZT1hcGFjaGVfaGFybW9ueQora2V5d29yZHM9YXBhY2hlIGhhcm1vbnkKK29uRGV2aWNlPXRydWUKK2hvbWVwYWdlPWh0dHBcOi8vaGFybW9ueS5hcGFjaGUub3JnLwpkaWZmIC0tZ2l0IGEvZGFsdmlrL01PRFVMRV9MSUNFTlNFX0FQQUNIRTIgYi9kYWx2aWsvTU9EVUxFX0xJQ0VOU0VfQVBBQ0hFMgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjlkZTI5Ci0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL01PRFVMRV9MSUNFTlNFX0FQQUNIRTIKZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL0FuZHJvaWRPbmx5LmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9BbmRyb2lkT25seS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhM2MxYzUKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9BbmRyb2lkT25seS5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5hbm5vdGF0aW9uOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CisKKy8qKgorICogTWFya3MgYSB0ZXN0LWNhc2UgYXMgQW5kcm9pZC1vbmx5LCB0aGF0IGlzLCBpdCBzaG91bGQgbm90IGJlIGV4ZWN1dGVkIG9uCisgKiBvdGhlciBzeXN0ZW1zLgorICoKKyAqIEBoaWRlCisgKi8KK0BSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCitAVGFyZ2V0KHsgRWxlbWVudFR5cGUuTUVUSE9ELCBFbGVtZW50VHlwZS5UWVBFIH0pCitwdWJsaWMgQGludGVyZmFjZSBBbmRyb2lkT25seSB7CisKKyAgICAvKioKKyAgICAgKiBQbGFpbiB0ZXh0IHJlYXNvbiBmb3IgYWRkaW5nIHRoaXMgYW5ub3RhdGlvbi4KKyAgICAgKi8KKyAgICBTdHJpbmcgdmFsdWUoKTsKKworfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vQW5ub3RhdGlvbkRlZmF1bHQuamF2YSBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL0Fubm90YXRpb25EZWZhdWx0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTgwNjJmYgotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL0Fubm90YXRpb25EZWZhdWx0LmphdmEKQEAgLTAsMCArMSwzMCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLmFubm90YXRpb247CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5OworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldDsKKworLyoqCisgKiBBICJzeXN0ZW0gYW5ub3RhdGlvbiIgdXNlZCB0byBwcm92aWRlIHRoZSBBbm5vdGF0aW9uRGVmYXVsdCBhdHRyaWJ1dGUuCisgKi8KK0BSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCitAVGFyZ2V0KEVsZW1lbnRUeXBlLkFOTk9UQVRJT05fVFlQRSkKK0BpbnRlcmZhY2UgQW5ub3RhdGlvbkRlZmF1bHQge30KKwpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vQnJva2VuVGVzdC5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vQnJva2VuVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQwMWQ2NTIKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9Ccm9rZW5UZXN0LmphdmEKQEAgLTAsMCArMSwzOCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLmFubm90YXRpb247CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5OworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldDsKKworLyoqCisgKiBNYXJrcyBhIHRlc3QgY2FzZSBhcyBicm9rZW4uIFRoaXMgbWVhbnMgdGhlIHRlc3QgY2FzZSBzaG91bGQgYmUgZml4ZWQuCisgKgorICogQGhpZGUKKyAqLworQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKK0BUYXJnZXQoeyBFbGVtZW50VHlwZS5NRVRIT0QgfSkKK3B1YmxpYyBAaW50ZXJmYWNlIEJyb2tlblRlc3QgeworCisgICAgLyoqCisgICAgICogUGxhaW4gdGV4dCByZWFzb24gZm9yIGFkZGluZyB0aGlzIGFubm90YXRpb24uCisgICAgICovCisgICAgU3RyaW5nIHZhbHVlKCk7CisKK30KZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL0VuY2xvc2luZ0NsYXNzLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI1NDZjNGMKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzcy5qYXZhCkBAIC0wLDAgKzEsMzAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5hbm5vdGF0aW9uOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CisKKy8qKgorICogQSAic3lzdGVtIGFubm90YXRpb24iIHVzZWQgdG8gcHJvdmlkZSBwYXJ0IG9mIHRoZSBJbm5lckNsYXNzZXMgYXR0cmlidXRlLgorICovCitAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorQFRhcmdldChFbGVtZW50VHlwZS5BTk5PVEFUSU9OX1RZUEUpCitAaW50ZXJmYWNlIEVuY2xvc2luZ0NsYXNzIHt9CisKZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL0VuY2xvc2luZ01ldGhvZC5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vRW5jbG9zaW5nTWV0aG9kLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWE5NzE1NQotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL0VuY2xvc2luZ01ldGhvZC5qYXZhCkBAIC0wLDAgKzEsMzAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5hbm5vdGF0aW9uOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CisKKy8qKgorICogQSAic3lzdGVtIGFubm90YXRpb24iIHVzZWQgdG8gcHJvdmlkZSB0aGUgRW5jbG9zaW5nTWV0aG9kIGF0dHJpYnV0ZS4KKyAqLworQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKK0BUYXJnZXQoRWxlbWVudFR5cGUuQU5OT1RBVElPTl9UWVBFKQorQGludGVyZmFjZSBFbmNsb3NpbmdNZXRob2Qge30KKwpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vSW5uZXJDbGFzcy5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vSW5uZXJDbGFzcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA1NDg0MmYKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzLmphdmEKQEAgLTAsMCArMSwzMCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLmFubm90YXRpb247CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5OworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldDsKKworLyoqCisgKiBBICJzeXN0ZW0gYW5ub3RhdGlvbiIgdXNlZCB0byBwcm92aWRlIHBhcnQgb2YgdGhlIElubmVyQ2xhc3NlcyBhdHRyaWJ1dGUuCisgKi8KK0BSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCitAVGFyZ2V0KEVsZW1lbnRUeXBlLkFOTk9UQVRJT05fVFlQRSkKK0BpbnRlcmZhY2UgSW5uZXJDbGFzcyB7fQorCmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9Lbm93bkZhaWx1cmUuamF2YSBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL0tub3duRmFpbHVyZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExZTgxM2QKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9Lbm93bkZhaWx1cmUuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBkYWx2aWsuYW5ub3RhdGlvbjsKKworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3k7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OworCisvKioKKyAqIE1hcmtzIGEgdGVzdCBjYXNlIGFzIGEga25vd24gZmFpbHVyZS4gVGhpcyBtZWFucyB0aGUgdW5kZXJseWluZworICogaW1wbGVtZW50YXRpb24gc2hvdWxkIGJlIGZpeGVkLiBTZWVtcyB0byBiZSBzaW1pbGFyIHRvIEBjb2Rle0BUb0JlRml4ZWR9LCBzbworICogbWF5YmUgdGhlIHR3byBjYW4gYmUgbWVyZ2VkIGF0IHNvbWUgcG9pbnQuCisgKgorICogQGhpZGUKKyAqLworQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKK0BUYXJnZXQoeyBFbGVtZW50VHlwZS5NRVRIT0QgfSkKK3B1YmxpYyBAaW50ZXJmYWNlIEtub3duRmFpbHVyZSB7CisKKyAgICAvKioKKyAgICAgKiBQbGFpbiB0ZXh0IHJlYXNvbiBmb3IgYWRkaW5nIHRoaXMgYW5ub3RhdGlvbi4KKyAgICAgKi8KKyAgICBTdHJpbmcgdmFsdWUoKTsKKworfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vTWVtYmVyQ2xhc3Nlcy5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vTWVtYmVyQ2xhc3Nlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIyMTNiZTcKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9NZW1iZXJDbGFzc2VzLmphdmEKQEAgLTAsMCArMSwzMCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLmFubm90YXRpb247CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5OworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldDsKKworLyoqCisgKiBBICJzeXN0ZW0gYW5ub3RhdGlvbiIgdXNlZCB0byBwcm92aWRlIHRoZSBNZW1iZXJDbGFzc2VzIGxpc3QuCisgKi8KK0BSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCitAVGFyZ2V0KEVsZW1lbnRUeXBlLkFOTk9UQVRJT05fVFlQRSkKK0BpbnRlcmZhY2UgTWVtYmVyQ2xhc3NlcyB7fQorCmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9TaWRlRWZmZWN0LmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9TaWRlRWZmZWN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjkyZTliYwotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL1NpZGVFZmZlY3QuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBkYWx2aWsuYW5ub3RhdGlvbjsKKworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3k7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OworCisvKioKKyAqIE1hcmtzIGEgdGVzdC1jYXNlIGFzIGVpdGhlciBoYXZpbmcgYSBzaWRlLWVmZmVjdCB0aGF0IG90aGVyIHRlc3RzIG1pZ2h0CisgKiBub3RpY2Ugb3Igc3VmZmVyaW5nIGZyb20gc3VjaCBhIHNpZGUgZWZmZWN0LiBTdWNoIHRlc3RzIHNob3VsZCBiZSBydW4gaW4gYW4KKyAqIGlzb2xhdGVkIG1hbm5lci4KKyAqCisgKiBAaGlkZQorICovCitAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorQFRhcmdldCh7IEVsZW1lbnRUeXBlLk1FVEhPRCwgRWxlbWVudFR5cGUuVFlQRSB9KQorcHVibGljIEBpbnRlcmZhY2UgU2lkZUVmZmVjdCB7CisKKyAgICAvKioKKyAgICAgKiBQbGFpbiB0ZXh0IHJlYXNvbiBmb3IgYWRkaW5nIHRoaXMgYW5ub3RhdGlvbi4KKyAgICAgKi8KKyAgICBTdHJpbmcgdmFsdWUoKTsKKworfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vU2lnbmF0dXJlLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9TaWduYXR1cmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTZkN2RkCi0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vU2lnbmF0dXJlLmphdmEKQEAgLTAsMCArMSwzMCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLmFubm90YXRpb247CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5OworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldDsKKworLyoqCisgKiBBICJzeXN0ZW0gYW5ub3RhdGlvbiIgdXNlZCB0byBwcm92aWRlIHRoZSBTaWduYXR1cmUgYXR0cmlidXRlLgorICovCitAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorQFRhcmdldChFbGVtZW50VHlwZS5BTk5PVEFUSU9OX1RZUEUpCitAaW50ZXJmYWNlIFNpZ25hdHVyZSB7fQorCmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9UZXN0TGV2ZWwuamF2YSBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL1Rlc3RMZXZlbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY2MmVhMmYKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9UZXN0TGV2ZWwuamF2YQpAQCAtMCwwICsxLDg1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBkYWx2aWsuYW5ub3RhdGlvbjsKKworLyoqCisgKiBEZWZpbmVzIGFuIGVudW1lcmF0aW9uIG9mIHBvc3NpYmxlIHN0YXRlcyBhIHRlc3QgY2FzZSBjYW4gYmUgaW4uCisgKgorICogQGhpZGUKKyAqLworcHVibGljIGVudW0gVGVzdExldmVsIHsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB0aGF0IGEgdGVzdCBtZXRob2QgY29tcGxldGVseSB0ZXN0cyBpdHMgdGFyZ2V0IEFQSSBtZXRob2QuCisgICAgICovCisgICAgQ09NUExFVEUsCisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhhdCBhIHRlc3QgbWV0aG9kIHBhcnRpYWxseSB0ZXN0cyBpdHMgdGFyZ2V0IEFQSSBtZXRob2QgYW5kCisgICAgICogdGhhdCB0b2dldGhlciB3aXRoIGFsbCBvdGhlciB7QGNvZGUgUEFSVElBTF9DT01QTEVURX0gdGVzdHMgZm9yIHRoZSBzYW1lCisgICAgICogbWV0aG9kIGl0IGlzIHN1ZmZpY2llbnQuCisgICAgICovCisgICAgUEFSVElBTF9DT01QTEVURSwKKworICAgIC8qKgorICAgICAqIEp1c3QgZm9yIGNvbXBhdGliaWxpdHkgcHVycG9zZXMsIHdpbGwgYmUgcmVtb3ZlZCBsYXRlci4KKyAgICAgKi8KKyAgICBQQVJUSUFMX09LLAorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoYXQgYSB0ZXN0IG1ldGhvZCBwYXJ0aWFsbHkgdGVzdHMgaXRzIHRhcmdldCBBUEkgbWV0aG9kLiBJdAorICAgICAqIG5lZWRzIGEgc2Vjb25kIHJldmlldyBwaGFzZSB0byBmaW5kIG91dCBpZiB0aGUgc3VtIG9mIGFsbCBwYXJ0aWFsIHRlc3RzCisgICAgICogaXMgc3VmZmljaWVudCBmb3IgY29tcGxldGVseSB0ZXN0aW5nIHRoZSB0YXJnZXQgQVBJIG1ldGhvZC4gSWYgeWVzLCB0aGUKKyAgICAgKiBsZXZlbCBoYXMgdG8gYmUgY2hhbmdlZCB0byB7QGNvZGUgUEFSVElBTF9DT01QTEVURX0uCisgICAgICovCisgICAgUEFSVElBTCwKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB0aGF0IGEgdGVzdCBtZXRob2QgaXMga25vd24gdG8gbm90IGNvbXBsZXRlbHkgdGVzdCBhbiBBUEkKKyAgICAgKiBtZXRob2QgYnV0IHRoZSBtaXNzaW5nIHRlc3Qgc3RlcHMgYXJlIHRvbyBjb21wbGV4IGFuZCBjb3N0bHkgdG8KKyAgICAgKiBpbXBsZW1lbnQuIFRoaXMgbGV2ZWwgaXMgcG9zaXRpb25lZCBzb21ld2hlcmUgYmV0d2VlbiB7QGNvZGUgUEFSVElBTH0KKyAgICAgKiBhbmQge0Bjb2RlIENPTVBMRVRFfS4KKyAgICAgKi8KKyAgICBTVUZGSUNJRU5ULAorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoYXQgYSB0ZXN0IG1ldGhvZCBwcm92aWRlcyBhZGRpdGlvbmFsIHRlc3RpbmcgZm9yIGFuIEFQSQorICAgICAqIG1ldGhvZCBmb3Igd2hpY2ggdGhlcmUgYWxyZWFkeSBleGlzdHMgb25lIHtAY29kZSBDT01QTEVURX0gb3IgYSBzZXQgb2YKKyAgICAgKiB7QGNvZGUgUEFSVElBTF9DT01QTEVURX0gdGVzdHMuIFRoaXMgbGV2ZWwgbWF5IGFsc28gYmUgdXNlZCBmb3IgdGVzdAorICAgICAqIG1ldGhvZHMgdGhhdCB0ZXN0IGEgY29uY2VwdCB3aGljaCBjYW4gbm90IGJlIGRpcmVjdGx5IGF0dHJpYnV0ZWQgdG8KKyAgICAgKiB0aGUgc3BlY2lmaWNhdGlvbiBvZiBhbiBBUEkgbWV0aG9kIG9yIGNsYXNzLgorICAgICAqLworICAgIEFERElUSU9OQUwsCisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGVyZSBpcyBub3RoaW5nIHRvIHRlc3QgaW4gYW4gQVBJIG1ldGhvZCwgZm9yIGV4YW1wbGUgaWYKKyAgICAgKiB0aGUgc3BlY2lmaWNhdGlvbiBzdGF0ZXMgdGhhdCBhIG1ldGhvZCBkb2VzIG5vdGhpbmcuCisgICAgICovCisgICAgTk9UX05FQ0VTU0FSWSwKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB0aGF0IGl0IGlzIHZlcnkgaGFyZCBvciBpbXBvc3NpYmxlIHRvIHRlc3QgYW4gQVBJIG1ldGhvZC4KKyAgICAgKi8KKyAgICBOT1RfRkVBU0lCTEUsCisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgdGVzdHMgaXMgZWl0aGVyIGluc3VmZmljaWVudCBvciB3cm9uZy4gU29tZXRoaW5nIG5lZWRzCisgICAgICogdG8gYmUgZG9uZSBhYm91dCBpdC4KKyAgICAgKi8KKyAgICBUT0RPLAorCit9CmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9UZXN0VGFyZ2V0LmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9UZXN0VGFyZ2V0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGNmZDIwYwotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL1Rlc3RUYXJnZXQuamF2YQpAQCAtMCwwICsxLDU5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBkYWx2aWsuYW5ub3RhdGlvbjsKKworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3k7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OworCisvKioKKyAqIERlZmluZXMgYW4gYW5ub3RhdGlvbiB1c2VkIGJlIHVzZWQgd2l0aGluIHRoZSBUZXN0SW5mbyBhbm5vdGF0aW9uLiBJdAorICogc3BlY2lmaWVzIGEgc2luZ2xlIG1ldGhvZCB0YXJnZXQgZm9yIHRoZSB0ZXN0IChidXQgY2FuIGJlIHVzZWQgbXVsdGlwbGUKKyAqIHRpbWVzKS4KKyAqCisgKiBAZGVwcmVjYXRlZCBPYnNvbGV0ZQorICovCitAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorQFRhcmdldCh7IEVsZW1lbnRUeXBlLkFOTk9UQVRJT05fVFlQRSB9KQorQERlcHJlY2F0ZWQKK3B1YmxpYyBAaW50ZXJmYWNlIFRlc3RUYXJnZXQgeworCisgICAgLyoqCisgICAgICogU3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBtZXRob2QgdGhhdCBpcyBiZWluZyB0ZXN0ZWQuCisgICAgICovCisgICAgU3RyaW5nIG1ldGhvZE5hbWUoKSBkZWZhdWx0ICIiOworCisgICAgLyoqCisgICAgICogU3BlY2lmaWVzIHRoZSBuYW1lIG9mIGEgY29uY2VwdCBiZWluZyB0ZXN0ZWQuIFVzZSB0aGlzIGlmCisgICAgICoge0Bjb2RlIG1ldGhvZE5hbWV9IGlzIG5vdCBhY2N1cmF0ZSBlbm91Z2guIEUuZy4gZm9yCisgICAgICoge0BsaW5rIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuI2NvbXBpbGUoU3RyaW5nKX0ge0Bjb2RlIG1ldGhvZE5hbWV9IGlzIG5vdAorICAgICAqIHN1ZmZpY2llbnQgc2luY2UgdGhlIFN0cmluZyBjb250YWlucyBhIHBhdHRlcm4gd2l0aCBpdHMgb3duIHN5bnRheCB3aGljaAorICAgICAqIGhhcyB0byBiZSB0ZXN0ZWQgd2l0aCBkaWZmZXJlbnQgYXNwZWN0cy4gQXJlYXMgY29uY2VybmVkIGFyZSBlLmcuIEpEQkMKKyAgICAgKiAoU0VMRUNULCBJTlNFUlQsIFVQREFURSwgREVMRVRFLCAuLi4pLCByZWdleCAoY2hhcmFjdGVyIHNldHMsCisgICAgICogb3BlcmF0b3JzLC4uLiksIGZvcm1hdHRlcnMgKERlY2ltYWxGb3JtYXQsIERhdGVGb3JtYXQsIENob2ljZUZvcm1hdCwKKyAgICAgKiAuLi4pLCAuLi4KKyAgICAgKi8KKyAgICBTdHJpbmcgY29uY2VwdE5hbWUoKSBkZWZhdWx0ICIiOworCisgICAgLyoqCisgICAgICogU3BlY2lmaWVzIHRoZSBzaWduYXR1cmUgb2YgdGhlIG1ldGhvZCB0aGF0IGlzIGJlaW5nIHRlc3RlZCwgaW4gdGVybXMgb2YKKyAgICAgKiBKYXZhIGNsYXNzZXMuCisgICAgICovCisgICAgQ2xhc3M8Pz5bXSBtZXRob2RBcmdzKCkgZGVmYXVsdCB7fTsKKworfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vVGVzdFRhcmdldENsYXNzLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9UZXN0VGFyZ2V0Q2xhc3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lODgwNDBlCi0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vVGVzdFRhcmdldENsYXNzLmphdmEKQEAgLTAsMCArMSw0NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLmFubm90YXRpb247CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5OworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldDsKKworLyoqCisgKiBEZWZpbmVzIGFuIGFubm90YXRpb24gZm9yIHRlc3QgY2xhc3NlcyB0aGF0IGFsbG93cyB0byBsaW5rIHRoZW0gdG8gdGhlIGNsYXNzCisgKiB0aGF0IGlzIGJlaW5nIHRlc3RlZC4gVGhlIGN1cnJlbnQgYXNzdW1wdGlvbiBpcyB0aGF0IHRoZSB0ZXN0IGFyZSBzb21ld2hhdAorICogb3JnYW5pemVkIGFjY29yZGluZyB0byB0aGUgQVBJIGNsYXNzZXMgdGhleSB0ZXN0LiBNaWdodCBiZSB0b28gc3RyaWN0IGZvcgorICogc29tZSBjYXNlcy4KKyAqCisgKiBAZGVwcmVjYXRlZCBPYnNvbGV0ZQorICovCitAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorQFRhcmdldCh7IEVsZW1lbnRUeXBlLlRZUEUgfSkKK0BEZXByZWNhdGVkCitwdWJsaWMgQGludGVyZmFjZSBUZXN0VGFyZ2V0Q2xhc3MgeworCisgICAgLyoqCisgICAgICogU3BlY2lmaWVzIHRoZSBjbGFzcyBiZWluZyB0ZXN0ZWQuCisgICAgICovCisgICAgQ2xhc3M8Pz4gdmFsdWUoKTsKKworICAgIC8qKgorICAgICAqIE9wdGlvbiB0byBzcGVjaWZ5IHVudGVzdGVkIG1ldGhvZHMgZm9yIHRoZSBjbGFzcy4KKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIFRlc3RUYXJnZXROZXdbXSB1bnRlc3RlZE1ldGhvZHMoKSBkZWZhdWx0IHt9OworfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vVGVzdFRhcmdldE5ldy5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vVGVzdFRhcmdldE5ldy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgwYWViZWUKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9UZXN0VGFyZ2V0TmV3LmphdmEKQEAgLTAsMCArMSw2NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLmFubm90YXRpb247CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5OworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldDsKKworLyoqCisgKiBEZWZpbmVzIGFuIGFubm90YXRpb24gdXNlZCBiZSB1c2VkIHdpdGhpbiB0aGUgVGVzdEluZm8gYW5ub3RhdGlvbi4gSXQKKyAqIHNwZWNpZmllcyBhIHNpbmdsZSBtZXRob2QgdGFyZ2V0IGZvciB0aGUgdGVzdCAoYnV0IGNhbiBiZSB1c2VkIG11bHRpcGxlCisgKiB0aW1lcykuCisgKiBAaGlkZQorICovCitAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorQFRhcmdldCh7IEVsZW1lbnRUeXBlLkFOTk9UQVRJT05fVFlQRSwgRWxlbWVudFR5cGUuTUVUSE9EIH0pCitwdWJsaWMgQGludGVyZmFjZSBUZXN0VGFyZ2V0TmV3IHsKKworICAgIC8qKgorICAgICAqIFNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgQVBJIG1ldGhvZCB0aGF0IGlzIGJlaW5nIHRlc3RlZC4gVGhpcyBmaWVsZAorICAgICAqIG1heSBiZSBsZWZ0IGVtcHR5IGlmIHRoZSB0ZXN0IHRhcmdldCBpcyBhIGNvbmNlcHQgaW1wbGVtZW50ZWQgaW4gYQorICAgICAqIGNsYXNzIHJhdGhlciB0aGFuIGEgY29uY3JldGUgQVBJIG1ldGhvZC4KKyAgICAgKi8KKyAgICBTdHJpbmcgbWV0aG9kKCkgZGVmYXVsdCAiIjsKKworICAgIC8qKgorICAgICAqIFNwZWNpZmllcyB0aGUgc2lnbmF0dXJlIG9mIHRoZSBBUEkgbWV0aG9kIHRoYXQgaXMgYmVpbmcgdGVzdGVkLCBpbiB0ZXJtcworICAgICAqIG9mIEphdmEgY2xhc3Nlcy4KKyAgICAgKi8KKyAgICBDbGFzczw/PltdIGFyZ3MoKSBkZWZhdWx0IHt9OworCisgICAgLyoqCisgICAgICogU3BlY2lmaWVzIHRoZSBjbGFzcyB0byB3aGljaCB0aGUgdGVzdGVkIG1ldGhvZCBiZWxvbmdzLiBJZiB0aGlzIHZhbHVlIGlzCisgICAgICogbm90IHByb3ZpZGVkLCB0aGUgY2xhc3MgaWRlbnRpZmllZCBpbiBAVGVzdFRhcmdldENsYXNzIGlzIHVzZWQgYnkgdGhlCisgICAgICogdGVzdCBwcm9ncmVzcyBkb2NsZXQuCisgICAgICovCisgICAgQ2xhc3M8Pz4gY2xhenooKSBkZWZhdWx0IHZvaWQuY2xhc3M7CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWZpZXMgdGhlIGxldmVsIG9mIGNvdmVyYWdlIHRoZSB0ZXN0ZWQgQVBJIG1ldGhvZCBoYXMuCisgICAgICovCisgICAgVGVzdExldmVsIGxldmVsKCk7CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWZpZXMgbm90ZXdvcnRoeSBwbGFpbi10ZXh0IGluZm9ybWF0aW9uIGFib3V0IHRoZSB0ZXN0LCBmb3IgZXhhbXBsZQorICAgICAqIGlmIHNvbWV0aGluZyBpcyBOT1QgY292ZXJlZCBieSB0aGUgdGVzdCBtZXRob2QuCisgICAgICovCisgICAgU3RyaW5nIG5vdGVzKCkgZGVmYXVsdCAiIjsKK30KZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL1Rlc3RUYXJnZXRzLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9UZXN0VGFyZ2V0cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIwNzU3MmMKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9UZXN0VGFyZ2V0cy5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5hbm5vdGF0aW9uOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CisKKy8qKgorICogRGVmaW5lcyBhbiBhbm5vdGF0aW9uIGZvciB0ZXN0IGNsYXNzZXMgdGhhdCBhbGxvd3MgdG8gbGluayB0aGVtIHRvIHRoZSBjbGFzcworICogdGhhdCBpcyBiZWluZyB0ZXN0ZWQuIFRoZSBjdXJyZW50IGFzc3VtcHRpb24gaXMgdGhhdCB0aGUgdGVzdCBhcmUgc29tZXdoYXQKKyAqIG9yZ2FuaXplZCBhY2NvcmRpbmcgdG8gdGhlIEFQSSBjbGFzc2VzIHRoZXkgdGVzdC4gTWlnaHQgYmUgdG9vIHN0cmljdCBmb3IKKyAqIHNvbWUgY2FzZXMuCisgKiBAaGlkZQorICovCitAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorQFRhcmdldCh7IEVsZW1lbnRUeXBlLk1FVEhPRCB9KQorcHVibGljIEBpbnRlcmZhY2UgVGVzdFRhcmdldHMgeworCisgICAgLyoqCisgICAgICogU3BlY2lmaWVzIHRoZSBBUEkgbWV0aG9kcyB0aGF0IGFyZSB0ZXN0ZWQgYnkgdGhlIGFubm90YXRlZCB0ZXN0IG1ldGhvZC4KKyAgICAgKi8KKyAgICBUZXN0VGFyZ2V0TmV3W10gdmFsdWUoKTsKK30KZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL1Rocm93cy5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vVGhyb3dzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTYxMTE2YQotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL1Rocm93cy5qYXZhCkBAIC0wLDAgKzEsMzAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5hbm5vdGF0aW9uOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CisKKy8qKgorICogQSAic3lzdGVtIGFubm90YXRpb24iIHVzZWQgdG8gcHJvdmlkZSB0aGUgRXhjZXB0aW9ucyBhdHRyaWJ1dGUuCisgKi8KK0BSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCitAVGFyZ2V0KEVsZW1lbnRUeXBlLkFOTk9UQVRJT05fVFlQRSkKK0BpbnRlcmZhY2UgVGhyb3dzIHt9CisKZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL1RvQmVGaXhlZC5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2Fubm90YXRpb24vVG9CZUZpeGVkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzUxYTAzOAotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL1RvQmVGaXhlZC5qYXZhCkBAIC0wLDAgKzEsNDMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5hbm5vdGF0aW9uOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CisKKy8qKgorICogRGVmaW5lcyBhbiBhbm5vdGF0aW9uIGZvciB0ZXN0IG1ldGhvZHMgdGhhdCBpbmRpY2F0ZSB0aGUgdGVzdCBtZXRob2QKKyAqIG5lZWQgdG8gYmUgZml4ZWQgaW4gZnV0dXJlLgorICoge0BoaWRlIHBlbmRpbmcgQVBJIENvdW5jaWwgYXBwcm92YWx9CisgKi8KK0BSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCitAVGFyZ2V0KHsgRWxlbWVudFR5cGUuTUVUSE9EIH0pCitwdWJsaWMgQGludGVyZmFjZSBUb0JlRml4ZWQgeworCisgICAgLyoqCisgICAgICogU3BlY2lmaWVzIHRoZSByZWxhdGVkIGJ1ZyBudW1iZXIgb24gQ1RTIGJ1ZyB0cmFja2luZyBzeXN0ZW0uCisgICAgICovCisgICAgU3RyaW5nIGJ1ZygpIGRlZmF1bHQgIiI7CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWZpZXMgd2h5IHRoaXMgbWV0aG9kIG5lZWQgdG8gYmUgZml4ZWQuIElmIHdlIHRoaW5rIGl0J3MgYSBidWcsIGV4cGxhaW4KKyAgICAgKiB0aGUgZXhwZWN0YXRpb24gYW5kIHRoZSBhY3R1YWwgcmVzdWx0LgorICAgICAqLworICAgIFN0cmluZyBleHBsYW5hdGlvbigpIGRlZmF1bHQgIiI7Cit9CmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9wYWNrYWdlLmh0bWwgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYW5ub3RhdGlvbi9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmE2N2RjMAotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9hbm5vdGF0aW9uL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDggQEAKKzxodG1sPgorICA8Ym9keT4KKyAgICA8cD4KKyAgICAgIERlZmluZXMgc29tZSBhbm5vdGF0aW9ucyB0aGF0IGFyZSB1c2VkIHdpdGhpbiB0aGUgQW5kcm9pZCBzeXN0ZW0sIGVpdGhlcgorICAgICAgZm9yIHRoZSBjb3JlIGxpYnJhcmllcyBvciBmb3IgdGVzdGluZyBwdXJwb3Nlcy4KKyAgICA8L3A+CisgIDwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9ieXRlY29kZS9PcGNvZGVJbmZvLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYnl0ZWNvZGUvT3Bjb2RlSW5mby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYyNTNlZTcKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYnl0ZWNvZGUvT3Bjb2RlSW5mby5qYXZhCkBAIC0wLDAgKzEsODEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5ieXRlY29kZTsKKworLyoqCisgKiBJbmZvcm1hdGlvbiBhYm91dCBEYWx2aWsgb3Bjb2Rlcy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE9wY29kZUluZm8geworICAgIC8qKgorICAgICAqIFRoZSBtYXhpbXVtIHBvc3NpYmxlIHZhbHVlIG9mIGEgRGFsdmlrIG9wY29kZS4KKyAgICAgKgorICAgICAqIDxwPjxiPk5vdGU6PC9iPjogVGhpcyBpcyBjb25zdGFudCBpbiBhbnkgZ2l2ZW4gVk0gaW5jYXJuYXRpb24sCisgICAgICogYnV0IGl0IGlzIHN1YmplY3QgdG8gY2hhbmdlIG92ZXIgdGltZSwgc28gaXQgaXMgbm90IGFwcHJvcHJpYXRlCisgICAgICogdG8gcmVwcmVzZW50IGFzIGEgY29tcGlsZS10aW1lIGNvbnN0YW50IHZhbHVlLjwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhJTVVNX1ZBTFVFOworCisgICAgLyoqCisgICAgICogVGhlIG1heGltdW0gcG9zc2libGUgInBhY2tlZCB2YWx1ZSIgb2YgYSBEYWx2aWsgb3Bjb2RlLiBUaGUKKyAgICAgKiBwYWNrZWQgdmFsdWUgb2YgYW4gb3Bjb2RlIGlzIGEgZGVuc2VyIHJlcHJlc2VudGF0aW9uIHRoYXQgaXMKKyAgICAgKiBvbmx5IHVzZWQgd2hlbiByZXBvcnRpbmcgdXNhZ2Ugc3RhdGlzdGljcy4gVGhlIG1hcHBpbmcgYmV0d2VlbgorICAgICAqIHBhY2tlZCBvcGNvZGUgdmFsdWVzIGFuZCByZWd1bGFyIG9wY29kZSB2YWx1ZXMgaXMKKyAgICAgKiBpbXBsZW1lbnRhdGlvbi1zcGVjaWZpYyBhbmQgbWF5IHZhcnkgb3ZlciB0aW1lLgorICAgICAqCisgICAgICogPHA+PGI+Tm90ZTo8L2I+OiBUaGlzIGlzIGNvbnN0YW50IGluIGFueSBnaXZlbiBWTSBpbmNhcm5hdGlvbiwKKyAgICAgKiBidXQgaXQgaXMgc3ViamVjdCB0byBjaGFuZ2Ugb3ZlciB0aW1lLCBzbyBpdCBpcyBub3QgYXBwcm9wcmlhdGUKKyAgICAgKiB0byByZXByZXNlbnQgYXMgYSBjb21waWxlLXRpbWUgY29uc3RhbnQgdmFsdWUuPC9wPgorICAgICAqCisgICAgICogQHNlZSBkYWx2aWsuc3lzdGVtLlZNRGVidWcuZ2V0SW5zdHJ1Y3Rpb25Db3VudCgpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYSU1VTV9QQUNLRURfVkFMVUU7CisKKyAgICBzdGF0aWMgeworICAgICAgICAvKgorICAgICAgICAgKiBTZWUgbm90ZSBvbiB0aGUgZGVmaW5pdGlvbiBvZiBNQVhJTVVNX1ZBTFVFLCBhYm92ZSwgZm9yCisgICAgICAgICAqIHdoeSBpdCdzIG5vdCBhc3NpZ25lZCBkaXJlY3RseSBvbiB0aGUgZGVjbGFyYXRpb24gbGluZS4KKyAgICAgICAgICoKKyAgICAgICAgICogSU1QT1JUQU5UIE5PVEU6IFRoaXMgYXNzaWdubWVudCBpcyBnZW5lcmF0ZWQgYXV0b21hdGljYWxseQorICAgICAgICAgKiBieSB0aGUgb3Bjb2RlLWdlbiB0b29sLiBBbnkgZWRpdHMgd2lsbCBnZXQgd2lwZWQgb3V0IHRoZQorICAgICAgICAgKiBuZXh0IHRpbWUgdGhlIHRvb2wgaXMgcnVuLgorICAgICAgICAgKi8KKyAgICAgICAgLy8gQkVHSU4obGliY29yZS1tYXhpbXVtLXZhbHVlcyk7IEdFTkVSQVRFRCBBVVRPTUFUSUNBTExZIEJZIG9wY29kZS1nZW4KKyAgICAgICAgTUFYSU1VTV9WQUxVRSA9IDY1NTM1OworICAgICAgICBNQVhJTVVNX1BBQ0tFRF9WQUxVRSA9IDUxMTsKKyAgICAgICAgLy8gRU5EKGxpYmNvcmUtbWF4aW11bS12YWx1ZXMpCisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBjbGFzcyBpcyBub3QgaW5zdGFudGlhYmxlLgorICAgICAqLworICAgIHByaXZhdGUgT3Bjb2RlSW5mbygpIHsKKyAgICAgICAgLy8gVGhpcyBzcGFjZSBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsuCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBwYWNrZWQgb3Bjb2RlIHZhbHVlIHJlcHJlc2VudHMgYQorICAgICAqIG1ldGhvZCBpbnZvY2F0aW9uIG9wZXJhdGlvbi4gVGhpcyBpbmNsdWRlcyBtb3N0IHRoaW5ncyB0aGF0CisgICAgICogbG9vayBsaWtlIG1ldGhvZCBpbnZvY2F0aW9uIGF0IHRoZSBzb3VyY2UgbGV2ZWwsIGJ1dCBpdCBub3RhYmx5CisgICAgICogZXhjbHVkZXMgbWV0aG9kcyB0aGF0IGFyZSBpbXBsZW1lbnRlZCBkaXJlY3RseSBpbiB0aGUgVk0gYXMKKyAgICAgKiB3ZWxsIGFzIG9uZXMgdGhlIFZNIGtub3dzIHRvIGhhdmUgZW1wdHkgaW1wbGVtZW50YXRpb25zLgorICAgICAqCisgICAgICogQGhpZGUgVW5jbGVhciBpZiB0aGlzIGlzIHVzZWZ1bCBlbm91Z2ggdG8gcHVibGlzaCBhcyBzdXBwb3J0ZWQgQVBJLgorICAgICAqCisgICAgICogQHBhcmFtIG9wY29kZSBvbmUgb2YgdGhlIHZhbHVlcyBkZWZpbmVkIGluIHtAbGluayBPcGNvZGVzfQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gaXNJbnZva2UoaW50IHBhY2tlZE9wY29kZSk7Cit9CmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYnl0ZWNvZGUvT3Bjb2Rlcy5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2J5dGVjb2RlL09wY29kZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OGYwZjdkCi0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2J5dGVjb2RlL09wY29kZXMuamF2YQpAQCAtMCwwICsxLDQxMiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLmJ5dGVjb2RlOworCisvKioKKyAqIEEgbGlzdCBvZiBhbGwgbm9ybWFsIChub3QgaW1wbGVtZW50YXRpb24tc3BlY2lmaWMpIERhbHZpayBvcGNvZGVzLgorICovCitwdWJsaWMgaW50ZXJmYWNlIE9wY29kZXMgeworICAgIC8qCisgICAgICogSU1QT1JUQU5UIE5PVEU6IFRoZSBjb250ZW50cyBvZiB0aGlzIGZpbGUgYXJlIG1vc3RseSBnZW5lcmF0ZWQKKyAgICAgKiBhdXRvbWF0aWNhbGx5IGJ5IHRoZSBvcGNvZGUtZ2VuIHRvb2wuIEFueSBlZGl0cyB0byB0aGUgZ2VuZXJhdGVkCisgICAgICogc2VjdGlvbnMgd2lsbCBnZXQgd2lwZWQgb3V0IHRoZSBuZXh0IHRpbWUgdGhlIHRvb2wgaXMgcnVuLgorICAgICAqLworCisgICAgLy8gQkVHSU4obGliY29yZS1vcGNvZGVzKTsgR0VORVJBVEVEIEFVVE9NQVRJQ0FMTFkgQlkgb3Bjb2RlLWdlbgorICAgIGludCBPUF9OT1AgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDAwOworICAgIGludCBPUF9NT1ZFICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDAxOworICAgIGludCBPUF9NT1ZFX0ZST00xNiAgICAgICAgICAgICAgICAgID0gMHgwMDAyOworICAgIGludCBPUF9NT1ZFXzE2ICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDAzOworICAgIGludCBPUF9NT1ZFX1dJREUgICAgICAgICAgICAgICAgICAgID0gMHgwMDA0OworICAgIGludCBPUF9NT1ZFX1dJREVfRlJPTTE2ICAgICAgICAgICAgID0gMHgwMDA1OworICAgIGludCBPUF9NT1ZFX1dJREVfMTYgICAgICAgICAgICAgICAgID0gMHgwMDA2OworICAgIGludCBPUF9NT1ZFX09CSkVDVCAgICAgICAgICAgICAgICAgID0gMHgwMDA3OworICAgIGludCBPUF9NT1ZFX09CSkVDVF9GUk9NMTYgICAgICAgICAgID0gMHgwMDA4OworICAgIGludCBPUF9NT1ZFX09CSkVDVF8xNiAgICAgICAgICAgICAgID0gMHgwMDA5OworICAgIGludCBPUF9NT1ZFX1JFU1VMVCAgICAgICAgICAgICAgICAgID0gMHgwMDBhOworICAgIGludCBPUF9NT1ZFX1JFU1VMVF9XSURFICAgICAgICAgICAgID0gMHgwMDBiOworICAgIGludCBPUF9NT1ZFX1JFU1VMVF9PQkpFQ1QgICAgICAgICAgID0gMHgwMDBjOworICAgIGludCBPUF9NT1ZFX0VYQ0VQVElPTiAgICAgICAgICAgICAgID0gMHgwMDBkOworICAgIGludCBPUF9SRVRVUk5fVk9JRCAgICAgICAgICAgICAgICAgID0gMHgwMDBlOworICAgIGludCBPUF9SRVRVUk4gICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDBmOworICAgIGludCBPUF9SRVRVUk5fV0lERSAgICAgICAgICAgICAgICAgID0gMHgwMDEwOworICAgIGludCBPUF9SRVRVUk5fT0JKRUNUICAgICAgICAgICAgICAgID0gMHgwMDExOworICAgIGludCBPUF9DT05TVF80ICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDEyOworICAgIGludCBPUF9DT05TVF8xNiAgICAgICAgICAgICAgICAgICAgID0gMHgwMDEzOworICAgIGludCBPUF9DT05TVCAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDE0OworICAgIGludCBPUF9DT05TVF9ISUdIMTYgICAgICAgICAgICAgICAgID0gMHgwMDE1OworICAgIGludCBPUF9DT05TVF9XSURFXzE2ICAgICAgICAgICAgICAgID0gMHgwMDE2OworICAgIGludCBPUF9DT05TVF9XSURFXzMyICAgICAgICAgICAgICAgID0gMHgwMDE3OworICAgIGludCBPUF9DT05TVF9XSURFICAgICAgICAgICAgICAgICAgID0gMHgwMDE4OworICAgIGludCBPUF9DT05TVF9XSURFX0hJR0gxNiAgICAgICAgICAgID0gMHgwMDE5OworICAgIGludCBPUF9DT05TVF9TVFJJTkcgICAgICAgICAgICAgICAgID0gMHgwMDFhOworICAgIGludCBPUF9DT05TVF9TVFJJTkdfSlVNQk8gICAgICAgICAgID0gMHgwMDFiOworICAgIGludCBPUF9DT05TVF9DTEFTUyAgICAgICAgICAgICAgICAgID0gMHgwMDFjOworICAgIGludCBPUF9NT05JVE9SX0VOVEVSICAgICAgICAgICAgICAgID0gMHgwMDFkOworICAgIGludCBPUF9NT05JVE9SX0VYSVQgICAgICAgICAgICAgICAgID0gMHgwMDFlOworICAgIGludCBPUF9DSEVDS19DQVNUICAgICAgICAgICAgICAgICAgID0gMHgwMDFmOworICAgIGludCBPUF9JTlNUQU5DRV9PRiAgICAgICAgICAgICAgICAgID0gMHgwMDIwOworICAgIGludCBPUF9BUlJBWV9MRU5HVEggICAgICAgICAgICAgICAgID0gMHgwMDIxOworICAgIGludCBPUF9ORVdfSU5TVEFOQ0UgICAgICAgICAgICAgICAgID0gMHgwMDIyOworICAgIGludCBPUF9ORVdfQVJSQVkgICAgICAgICAgICAgICAgICAgID0gMHgwMDIzOworICAgIGludCBPUF9GSUxMRURfTkVXX0FSUkFZICAgICAgICAgICAgID0gMHgwMDI0OworICAgIGludCBPUF9GSUxMRURfTkVXX0FSUkFZX1JBTkdFICAgICAgID0gMHgwMDI1OworICAgIGludCBPUF9GSUxMX0FSUkFZX0RBVEEgICAgICAgICAgICAgID0gMHgwMDI2OworICAgIGludCBPUF9USFJPVyAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDI3OworICAgIGludCBPUF9HT1RPICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDI4OworICAgIGludCBPUF9HT1RPXzE2ICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDI5OworICAgIGludCBPUF9HT1RPXzMyICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDJhOworICAgIGludCBPUF9QQUNLRURfU1dJVENIICAgICAgICAgICAgICAgID0gMHgwMDJiOworICAgIGludCBPUF9TUEFSU0VfU1dJVENIICAgICAgICAgICAgICAgID0gMHgwMDJjOworICAgIGludCBPUF9DTVBMX0ZMT0FUICAgICAgICAgICAgICAgICAgID0gMHgwMDJkOworICAgIGludCBPUF9DTVBHX0ZMT0FUICAgICAgICAgICAgICAgICAgID0gMHgwMDJlOworICAgIGludCBPUF9DTVBMX0RPVUJMRSAgICAgICAgICAgICAgICAgID0gMHgwMDJmOworICAgIGludCBPUF9DTVBHX0RPVUJMRSAgICAgICAgICAgICAgICAgID0gMHgwMDMwOworICAgIGludCBPUF9DTVBfTE9ORyAgICAgICAgICAgICAgICAgICAgID0gMHgwMDMxOworICAgIGludCBPUF9JRl9FUSAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDMyOworICAgIGludCBPUF9JRl9ORSAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDMzOworICAgIGludCBPUF9JRl9MVCAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDM0OworICAgIGludCBPUF9JRl9HRSAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDM1OworICAgIGludCBPUF9JRl9HVCAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDM2OworICAgIGludCBPUF9JRl9MRSAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDM3OworICAgIGludCBPUF9JRl9FUVogICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDM4OworICAgIGludCBPUF9JRl9ORVogICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDM5OworICAgIGludCBPUF9JRl9MVFogICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDNhOworICAgIGludCBPUF9JRl9HRVogICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDNiOworICAgIGludCBPUF9JRl9HVFogICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDNjOworICAgIGludCBPUF9JRl9MRVogICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDNkOworICAgIGludCBPUF9BR0VUICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDQ0OworICAgIGludCBPUF9BR0VUX1dJREUgICAgICAgICAgICAgICAgICAgID0gMHgwMDQ1OworICAgIGludCBPUF9BR0VUX09CSkVDVCAgICAgICAgICAgICAgICAgID0gMHgwMDQ2OworICAgIGludCBPUF9BR0VUX0JPT0xFQU4gICAgICAgICAgICAgICAgID0gMHgwMDQ3OworICAgIGludCBPUF9BR0VUX0JZVEUgICAgICAgICAgICAgICAgICAgID0gMHgwMDQ4OworICAgIGludCBPUF9BR0VUX0NIQVIgICAgICAgICAgICAgICAgICAgID0gMHgwMDQ5OworICAgIGludCBPUF9BR0VUX1NIT1JUICAgICAgICAgICAgICAgICAgID0gMHgwMDRhOworICAgIGludCBPUF9BUFVUICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDRiOworICAgIGludCBPUF9BUFVUX1dJREUgICAgICAgICAgICAgICAgICAgID0gMHgwMDRjOworICAgIGludCBPUF9BUFVUX09CSkVDVCAgICAgICAgICAgICAgICAgID0gMHgwMDRkOworICAgIGludCBPUF9BUFVUX0JPT0xFQU4gICAgICAgICAgICAgICAgID0gMHgwMDRlOworICAgIGludCBPUF9BUFVUX0JZVEUgICAgICAgICAgICAgICAgICAgID0gMHgwMDRmOworICAgIGludCBPUF9BUFVUX0NIQVIgICAgICAgICAgICAgICAgICAgID0gMHgwMDUwOworICAgIGludCBPUF9BUFVUX1NIT1JUICAgICAgICAgICAgICAgICAgID0gMHgwMDUxOworICAgIGludCBPUF9JR0VUICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDUyOworICAgIGludCBPUF9JR0VUX1dJREUgICAgICAgICAgICAgICAgICAgID0gMHgwMDUzOworICAgIGludCBPUF9JR0VUX09CSkVDVCAgICAgICAgICAgICAgICAgID0gMHgwMDU0OworICAgIGludCBPUF9JR0VUX0JPT0xFQU4gICAgICAgICAgICAgICAgID0gMHgwMDU1OworICAgIGludCBPUF9JR0VUX0JZVEUgICAgICAgICAgICAgICAgICAgID0gMHgwMDU2OworICAgIGludCBPUF9JR0VUX0NIQVIgICAgICAgICAgICAgICAgICAgID0gMHgwMDU3OworICAgIGludCBPUF9JR0VUX1NIT1JUICAgICAgICAgICAgICAgICAgID0gMHgwMDU4OworICAgIGludCBPUF9JUFVUICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDU5OworICAgIGludCBPUF9JUFVUX1dJREUgICAgICAgICAgICAgICAgICAgID0gMHgwMDVhOworICAgIGludCBPUF9JUFVUX09CSkVDVCAgICAgICAgICAgICAgICAgID0gMHgwMDViOworICAgIGludCBPUF9JUFVUX0JPT0xFQU4gICAgICAgICAgICAgICAgID0gMHgwMDVjOworICAgIGludCBPUF9JUFVUX0JZVEUgICAgICAgICAgICAgICAgICAgID0gMHgwMDVkOworICAgIGludCBPUF9JUFVUX0NIQVIgICAgICAgICAgICAgICAgICAgID0gMHgwMDVlOworICAgIGludCBPUF9JUFVUX1NIT1JUICAgICAgICAgICAgICAgICAgID0gMHgwMDVmOworICAgIGludCBPUF9TR0VUICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDYwOworICAgIGludCBPUF9TR0VUX1dJREUgICAgICAgICAgICAgICAgICAgID0gMHgwMDYxOworICAgIGludCBPUF9TR0VUX09CSkVDVCAgICAgICAgICAgICAgICAgID0gMHgwMDYyOworICAgIGludCBPUF9TR0VUX0JPT0xFQU4gICAgICAgICAgICAgICAgID0gMHgwMDYzOworICAgIGludCBPUF9TR0VUX0JZVEUgICAgICAgICAgICAgICAgICAgID0gMHgwMDY0OworICAgIGludCBPUF9TR0VUX0NIQVIgICAgICAgICAgICAgICAgICAgID0gMHgwMDY1OworICAgIGludCBPUF9TR0VUX1NIT1JUICAgICAgICAgICAgICAgICAgID0gMHgwMDY2OworICAgIGludCBPUF9TUFVUICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDY3OworICAgIGludCBPUF9TUFVUX1dJREUgICAgICAgICAgICAgICAgICAgID0gMHgwMDY4OworICAgIGludCBPUF9TUFVUX09CSkVDVCAgICAgICAgICAgICAgICAgID0gMHgwMDY5OworICAgIGludCBPUF9TUFVUX0JPT0xFQU4gICAgICAgICAgICAgICAgID0gMHgwMDZhOworICAgIGludCBPUF9TUFVUX0JZVEUgICAgICAgICAgICAgICAgICAgID0gMHgwMDZiOworICAgIGludCBPUF9TUFVUX0NIQVIgICAgICAgICAgICAgICAgICAgID0gMHgwMDZjOworICAgIGludCBPUF9TUFVUX1NIT1JUICAgICAgICAgICAgICAgICAgID0gMHgwMDZkOworICAgIGludCBPUF9JTlZPS0VfVklSVFVBTCAgICAgICAgICAgICAgID0gMHgwMDZlOworICAgIGludCBPUF9JTlZPS0VfU1VQRVIgICAgICAgICAgICAgICAgID0gMHgwMDZmOworICAgIGludCBPUF9JTlZPS0VfRElSRUNUICAgICAgICAgICAgICAgID0gMHgwMDcwOworICAgIGludCBPUF9JTlZPS0VfU1RBVElDICAgICAgICAgICAgICAgID0gMHgwMDcxOworICAgIGludCBPUF9JTlZPS0VfSU5URVJGQUNFICAgICAgICAgICAgID0gMHgwMDcyOworICAgIGludCBPUF9JTlZPS0VfVklSVFVBTF9SQU5HRSAgICAgICAgID0gMHgwMDc0OworICAgIGludCBPUF9JTlZPS0VfU1VQRVJfUkFOR0UgICAgICAgICAgID0gMHgwMDc1OworICAgIGludCBPUF9JTlZPS0VfRElSRUNUX1JBTkdFICAgICAgICAgID0gMHgwMDc2OworICAgIGludCBPUF9JTlZPS0VfU1RBVElDX1JBTkdFICAgICAgICAgID0gMHgwMDc3OworICAgIGludCBPUF9JTlZPS0VfSU5URVJGQUNFX1JBTkdFICAgICAgID0gMHgwMDc4OworICAgIGludCBPUF9ORUdfSU5UICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDdiOworICAgIGludCBPUF9OT1RfSU5UICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDdjOworICAgIGludCBPUF9ORUdfTE9ORyAgICAgICAgICAgICAgICAgICAgID0gMHgwMDdkOworICAgIGludCBPUF9OT1RfTE9ORyAgICAgICAgICAgICAgICAgICAgID0gMHgwMDdlOworICAgIGludCBPUF9ORUdfRkxPQVQgICAgICAgICAgICAgICAgICAgID0gMHgwMDdmOworICAgIGludCBPUF9ORUdfRE9VQkxFICAgICAgICAgICAgICAgICAgID0gMHgwMDgwOworICAgIGludCBPUF9JTlRfVE9fTE9ORyAgICAgICAgICAgICAgICAgID0gMHgwMDgxOworICAgIGludCBPUF9JTlRfVE9fRkxPQVQgICAgICAgICAgICAgICAgID0gMHgwMDgyOworICAgIGludCBPUF9JTlRfVE9fRE9VQkxFICAgICAgICAgICAgICAgID0gMHgwMDgzOworICAgIGludCBPUF9MT05HX1RPX0lOVCAgICAgICAgICAgICAgICAgID0gMHgwMDg0OworICAgIGludCBPUF9MT05HX1RPX0ZMT0FUICAgICAgICAgICAgICAgID0gMHgwMDg1OworICAgIGludCBPUF9MT05HX1RPX0RPVUJMRSAgICAgICAgICAgICAgID0gMHgwMDg2OworICAgIGludCBPUF9GTE9BVF9UT19JTlQgICAgICAgICAgICAgICAgID0gMHgwMDg3OworICAgIGludCBPUF9GTE9BVF9UT19MT05HICAgICAgICAgICAgICAgID0gMHgwMDg4OworICAgIGludCBPUF9GTE9BVF9UT19ET1VCTEUgICAgICAgICAgICAgID0gMHgwMDg5OworICAgIGludCBPUF9ET1VCTEVfVE9fSU5UICAgICAgICAgICAgICAgID0gMHgwMDhhOworICAgIGludCBPUF9ET1VCTEVfVE9fTE9ORyAgICAgICAgICAgICAgID0gMHgwMDhiOworICAgIGludCBPUF9ET1VCTEVfVE9fRkxPQVQgICAgICAgICAgICAgID0gMHgwMDhjOworICAgIGludCBPUF9JTlRfVE9fQllURSAgICAgICAgICAgICAgICAgID0gMHgwMDhkOworICAgIGludCBPUF9JTlRfVE9fQ0hBUiAgICAgICAgICAgICAgICAgID0gMHgwMDhlOworICAgIGludCBPUF9JTlRfVE9fU0hPUlQgICAgICAgICAgICAgICAgID0gMHgwMDhmOworICAgIGludCBPUF9BRERfSU5UICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDkwOworICAgIGludCBPUF9TVUJfSU5UICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDkxOworICAgIGludCBPUF9NVUxfSU5UICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDkyOworICAgIGludCBPUF9ESVZfSU5UICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDkzOworICAgIGludCBPUF9SRU1fSU5UICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDk0OworICAgIGludCBPUF9BTkRfSU5UICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDk1OworICAgIGludCBPUF9PUl9JTlQgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDk2OworICAgIGludCBPUF9YT1JfSU5UICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDk3OworICAgIGludCBPUF9TSExfSU5UICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDk4OworICAgIGludCBPUF9TSFJfSU5UICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDk5OworICAgIGludCBPUF9VU0hSX0lOVCAgICAgICAgICAgICAgICAgICAgID0gMHgwMDlhOworICAgIGludCBPUF9BRERfTE9ORyAgICAgICAgICAgICAgICAgICAgID0gMHgwMDliOworICAgIGludCBPUF9TVUJfTE9ORyAgICAgICAgICAgICAgICAgICAgID0gMHgwMDljOworICAgIGludCBPUF9NVUxfTE9ORyAgICAgICAgICAgICAgICAgICAgID0gMHgwMDlkOworICAgIGludCBPUF9ESVZfTE9ORyAgICAgICAgICAgICAgICAgICAgID0gMHgwMDllOworICAgIGludCBPUF9SRU1fTE9ORyAgICAgICAgICAgICAgICAgICAgID0gMHgwMDlmOworICAgIGludCBPUF9BTkRfTE9ORyAgICAgICAgICAgICAgICAgICAgID0gMHgwMGEwOworICAgIGludCBPUF9PUl9MT05HICAgICAgICAgICAgICAgICAgICAgID0gMHgwMGExOworICAgIGludCBPUF9YT1JfTE9ORyAgICAgICAgICAgICAgICAgICAgID0gMHgwMGEyOworICAgIGludCBPUF9TSExfTE9ORyAgICAgICAgICAgICAgICAgICAgID0gMHgwMGEzOworICAgIGludCBPUF9TSFJfTE9ORyAgICAgICAgICAgICAgICAgICAgID0gMHgwMGE0OworICAgIGludCBPUF9VU0hSX0xPTkcgICAgICAgICAgICAgICAgICAgID0gMHgwMGE1OworICAgIGludCBPUF9BRERfRkxPQVQgICAgICAgICAgICAgICAgICAgID0gMHgwMGE2OworICAgIGludCBPUF9TVUJfRkxPQVQgICAgICAgICAgICAgICAgICAgID0gMHgwMGE3OworICAgIGludCBPUF9NVUxfRkxPQVQgICAgICAgICAgICAgICAgICAgID0gMHgwMGE4OworICAgIGludCBPUF9ESVZfRkxPQVQgICAgICAgICAgICAgICAgICAgID0gMHgwMGE5OworICAgIGludCBPUF9SRU1fRkxPQVQgICAgICAgICAgICAgICAgICAgID0gMHgwMGFhOworICAgIGludCBPUF9BRERfRE9VQkxFICAgICAgICAgICAgICAgICAgID0gMHgwMGFiOworICAgIGludCBPUF9TVUJfRE9VQkxFICAgICAgICAgICAgICAgICAgID0gMHgwMGFjOworICAgIGludCBPUF9NVUxfRE9VQkxFICAgICAgICAgICAgICAgICAgID0gMHgwMGFkOworICAgIGludCBPUF9ESVZfRE9VQkxFICAgICAgICAgICAgICAgICAgID0gMHgwMGFlOworICAgIGludCBPUF9SRU1fRE9VQkxFICAgICAgICAgICAgICAgICAgID0gMHgwMGFmOworICAgIGludCBPUF9BRERfSU5UXzJBRERSICAgICAgICAgICAgICAgID0gMHgwMGIwOworICAgIGludCBPUF9TVUJfSU5UXzJBRERSICAgICAgICAgICAgICAgID0gMHgwMGIxOworICAgIGludCBPUF9NVUxfSU5UXzJBRERSICAgICAgICAgICAgICAgID0gMHgwMGIyOworICAgIGludCBPUF9ESVZfSU5UXzJBRERSICAgICAgICAgICAgICAgID0gMHgwMGIzOworICAgIGludCBPUF9SRU1fSU5UXzJBRERSICAgICAgICAgICAgICAgID0gMHgwMGI0OworICAgIGludCBPUF9BTkRfSU5UXzJBRERSICAgICAgICAgICAgICAgID0gMHgwMGI1OworICAgIGludCBPUF9PUl9JTlRfMkFERFIgICAgICAgICAgICAgICAgID0gMHgwMGI2OworICAgIGludCBPUF9YT1JfSU5UXzJBRERSICAgICAgICAgICAgICAgID0gMHgwMGI3OworICAgIGludCBPUF9TSExfSU5UXzJBRERSICAgICAgICAgICAgICAgID0gMHgwMGI4OworICAgIGludCBPUF9TSFJfSU5UXzJBRERSICAgICAgICAgICAgICAgID0gMHgwMGI5OworICAgIGludCBPUF9VU0hSX0lOVF8yQUREUiAgICAgICAgICAgICAgID0gMHgwMGJhOworICAgIGludCBPUF9BRERfTE9OR18yQUREUiAgICAgICAgICAgICAgID0gMHgwMGJiOworICAgIGludCBPUF9TVUJfTE9OR18yQUREUiAgICAgICAgICAgICAgID0gMHgwMGJjOworICAgIGludCBPUF9NVUxfTE9OR18yQUREUiAgICAgICAgICAgICAgID0gMHgwMGJkOworICAgIGludCBPUF9ESVZfTE9OR18yQUREUiAgICAgICAgICAgICAgID0gMHgwMGJlOworICAgIGludCBPUF9SRU1fTE9OR18yQUREUiAgICAgICAgICAgICAgID0gMHgwMGJmOworICAgIGludCBPUF9BTkRfTE9OR18yQUREUiAgICAgICAgICAgICAgID0gMHgwMGMwOworICAgIGludCBPUF9PUl9MT05HXzJBRERSICAgICAgICAgICAgICAgID0gMHgwMGMxOworICAgIGludCBPUF9YT1JfTE9OR18yQUREUiAgICAgICAgICAgICAgID0gMHgwMGMyOworICAgIGludCBPUF9TSExfTE9OR18yQUREUiAgICAgICAgICAgICAgID0gMHgwMGMzOworICAgIGludCBPUF9TSFJfTE9OR18yQUREUiAgICAgICAgICAgICAgID0gMHgwMGM0OworICAgIGludCBPUF9VU0hSX0xPTkdfMkFERFIgICAgICAgICAgICAgID0gMHgwMGM1OworICAgIGludCBPUF9BRERfRkxPQVRfMkFERFIgICAgICAgICAgICAgID0gMHgwMGM2OworICAgIGludCBPUF9TVUJfRkxPQVRfMkFERFIgICAgICAgICAgICAgID0gMHgwMGM3OworICAgIGludCBPUF9NVUxfRkxPQVRfMkFERFIgICAgICAgICAgICAgID0gMHgwMGM4OworICAgIGludCBPUF9ESVZfRkxPQVRfMkFERFIgICAgICAgICAgICAgID0gMHgwMGM5OworICAgIGludCBPUF9SRU1fRkxPQVRfMkFERFIgICAgICAgICAgICAgID0gMHgwMGNhOworICAgIGludCBPUF9BRERfRE9VQkxFXzJBRERSICAgICAgICAgICAgID0gMHgwMGNiOworICAgIGludCBPUF9TVUJfRE9VQkxFXzJBRERSICAgICAgICAgICAgID0gMHgwMGNjOworICAgIGludCBPUF9NVUxfRE9VQkxFXzJBRERSICAgICAgICAgICAgID0gMHgwMGNkOworICAgIGludCBPUF9ESVZfRE9VQkxFXzJBRERSICAgICAgICAgICAgID0gMHgwMGNlOworICAgIGludCBPUF9SRU1fRE9VQkxFXzJBRERSICAgICAgICAgICAgID0gMHgwMGNmOworICAgIGludCBPUF9BRERfSU5UX0xJVDE2ICAgICAgICAgICAgICAgID0gMHgwMGQwOworICAgIGludCBPUF9SU1VCX0lOVCAgICAgICAgICAgICAgICAgICAgID0gMHgwMGQxOworICAgIGludCBPUF9NVUxfSU5UX0xJVDE2ICAgICAgICAgICAgICAgID0gMHgwMGQyOworICAgIGludCBPUF9ESVZfSU5UX0xJVDE2ICAgICAgICAgICAgICAgID0gMHgwMGQzOworICAgIGludCBPUF9SRU1fSU5UX0xJVDE2ICAgICAgICAgICAgICAgID0gMHgwMGQ0OworICAgIGludCBPUF9BTkRfSU5UX0xJVDE2ICAgICAgICAgICAgICAgID0gMHgwMGQ1OworICAgIGludCBPUF9PUl9JTlRfTElUMTYgICAgICAgICAgICAgICAgID0gMHgwMGQ2OworICAgIGludCBPUF9YT1JfSU5UX0xJVDE2ICAgICAgICAgICAgICAgID0gMHgwMGQ3OworICAgIGludCBPUF9BRERfSU5UX0xJVDggICAgICAgICAgICAgICAgID0gMHgwMGQ4OworICAgIGludCBPUF9SU1VCX0lOVF9MSVQ4ICAgICAgICAgICAgICAgID0gMHgwMGQ5OworICAgIGludCBPUF9NVUxfSU5UX0xJVDggICAgICAgICAgICAgICAgID0gMHgwMGRhOworICAgIGludCBPUF9ESVZfSU5UX0xJVDggICAgICAgICAgICAgICAgID0gMHgwMGRiOworICAgIGludCBPUF9SRU1fSU5UX0xJVDggICAgICAgICAgICAgICAgID0gMHgwMGRjOworICAgIGludCBPUF9BTkRfSU5UX0xJVDggICAgICAgICAgICAgICAgID0gMHgwMGRkOworICAgIGludCBPUF9PUl9JTlRfTElUOCAgICAgICAgICAgICAgICAgID0gMHgwMGRlOworICAgIGludCBPUF9YT1JfSU5UX0xJVDggICAgICAgICAgICAgICAgID0gMHgwMGRmOworICAgIGludCBPUF9TSExfSU5UX0xJVDggICAgICAgICAgICAgICAgID0gMHgwMGUwOworICAgIGludCBPUF9TSFJfSU5UX0xJVDggICAgICAgICAgICAgICAgID0gMHgwMGUxOworICAgIGludCBPUF9VU0hSX0lOVF9MSVQ4ICAgICAgICAgICAgICAgID0gMHgwMGUyOworICAgIGludCBPUF9DT05TVF9DTEFTU19KVU1CTyAgICAgICAgICAgID0gMHgwMGZmOworICAgIGludCBPUF9DSEVDS19DQVNUX0pVTUJPICAgICAgICAgICAgID0gMHgwMWZmOworICAgIGludCBPUF9JTlNUQU5DRV9PRl9KVU1CTyAgICAgICAgICAgID0gMHgwMmZmOworICAgIGludCBPUF9ORVdfSU5TVEFOQ0VfSlVNQk8gICAgICAgICAgID0gMHgwM2ZmOworICAgIGludCBPUF9ORVdfQVJSQVlfSlVNQk8gICAgICAgICAgICAgID0gMHgwNGZmOworICAgIGludCBPUF9GSUxMRURfTkVXX0FSUkFZX0pVTUJPICAgICAgID0gMHgwNWZmOworICAgIGludCBPUF9JR0VUX0pVTUJPICAgICAgICAgICAgICAgICAgID0gMHgwNmZmOworICAgIGludCBPUF9JR0VUX1dJREVfSlVNQk8gICAgICAgICAgICAgID0gMHgwN2ZmOworICAgIGludCBPUF9JR0VUX09CSkVDVF9KVU1CTyAgICAgICAgICAgID0gMHgwOGZmOworICAgIGludCBPUF9JR0VUX0JPT0xFQU5fSlVNQk8gICAgICAgICAgID0gMHgwOWZmOworICAgIGludCBPUF9JR0VUX0JZVEVfSlVNQk8gICAgICAgICAgICAgID0gMHgwYWZmOworICAgIGludCBPUF9JR0VUX0NIQVJfSlVNQk8gICAgICAgICAgICAgID0gMHgwYmZmOworICAgIGludCBPUF9JR0VUX1NIT1JUX0pVTUJPICAgICAgICAgICAgID0gMHgwY2ZmOworICAgIGludCBPUF9JUFVUX0pVTUJPICAgICAgICAgICAgICAgICAgID0gMHgwZGZmOworICAgIGludCBPUF9JUFVUX1dJREVfSlVNQk8gICAgICAgICAgICAgID0gMHgwZWZmOworICAgIGludCBPUF9JUFVUX09CSkVDVF9KVU1CTyAgICAgICAgICAgID0gMHgwZmZmOworICAgIGludCBPUF9JUFVUX0JPT0xFQU5fSlVNQk8gICAgICAgICAgID0gMHgxMGZmOworICAgIGludCBPUF9JUFVUX0JZVEVfSlVNQk8gICAgICAgICAgICAgID0gMHgxMWZmOworICAgIGludCBPUF9JUFVUX0NIQVJfSlVNQk8gICAgICAgICAgICAgID0gMHgxMmZmOworICAgIGludCBPUF9JUFVUX1NIT1JUX0pVTUJPICAgICAgICAgICAgID0gMHgxM2ZmOworICAgIGludCBPUF9TR0VUX0pVTUJPICAgICAgICAgICAgICAgICAgID0gMHgxNGZmOworICAgIGludCBPUF9TR0VUX1dJREVfSlVNQk8gICAgICAgICAgICAgID0gMHgxNWZmOworICAgIGludCBPUF9TR0VUX09CSkVDVF9KVU1CTyAgICAgICAgICAgID0gMHgxNmZmOworICAgIGludCBPUF9TR0VUX0JPT0xFQU5fSlVNQk8gICAgICAgICAgID0gMHgxN2ZmOworICAgIGludCBPUF9TR0VUX0JZVEVfSlVNQk8gICAgICAgICAgICAgID0gMHgxOGZmOworICAgIGludCBPUF9TR0VUX0NIQVJfSlVNQk8gICAgICAgICAgICAgID0gMHgxOWZmOworICAgIGludCBPUF9TR0VUX1NIT1JUX0pVTUJPICAgICAgICAgICAgID0gMHgxYWZmOworICAgIGludCBPUF9TUFVUX0pVTUJPICAgICAgICAgICAgICAgICAgID0gMHgxYmZmOworICAgIGludCBPUF9TUFVUX1dJREVfSlVNQk8gICAgICAgICAgICAgID0gMHgxY2ZmOworICAgIGludCBPUF9TUFVUX09CSkVDVF9KVU1CTyAgICAgICAgICAgID0gMHgxZGZmOworICAgIGludCBPUF9TUFVUX0JPT0xFQU5fSlVNQk8gICAgICAgICAgID0gMHgxZWZmOworICAgIGludCBPUF9TUFVUX0JZVEVfSlVNQk8gICAgICAgICAgICAgID0gMHgxZmZmOworICAgIGludCBPUF9TUFVUX0NIQVJfSlVNQk8gICAgICAgICAgICAgID0gMHgyMGZmOworICAgIGludCBPUF9TUFVUX1NIT1JUX0pVTUJPICAgICAgICAgICAgID0gMHgyMWZmOworICAgIGludCBPUF9JTlZPS0VfVklSVFVBTF9KVU1CTyAgICAgICAgID0gMHgyMmZmOworICAgIGludCBPUF9JTlZPS0VfU1VQRVJfSlVNQk8gICAgICAgICAgID0gMHgyM2ZmOworICAgIGludCBPUF9JTlZPS0VfRElSRUNUX0pVTUJPICAgICAgICAgID0gMHgyNGZmOworICAgIGludCBPUF9JTlZPS0VfU1RBVElDX0pVTUJPICAgICAgICAgID0gMHgyNWZmOworICAgIGludCBPUF9JTlZPS0VfSU5URVJGQUNFX0pVTUJPICAgICAgID0gMHgyNmZmOworICAgIC8vIEVORChsaWJjb3JlLW9wY29kZXMpCisKKyAgICAvKgorICAgICAqIFRoZSByZXN0IG9mIHRoZXNlIGFyZSBlaXRoZXIgZ2VuZXJhdGVkIGJ5IGRleG9wdCBmb3Igb3B0aW1pemVkCisgICAgICogY29kZSwgb3IgaW5zZXJ0ZWQgYnkgdGhlIFZNIGF0IHJ1bnRpbWUuICBUaGV5IGFyZSBuZXZlciBnZW5lcmF0ZWQKKyAgICAgKiBieSAiZHgiLgorICAgICAqCisgICAgICogVGhleSBhcmUgYWxsIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZQorICAgICAqIHJlbGVhc2UsIHNpbmNlIHRoZXNlIGRlY2xhcmF0aW9ucyBhcmUgcmVhbGx5IG9mIHByaXZhdGUgaW1wbGVtZW50YXRpb24KKyAgICAgKiBkZXRhaWxzIHRoYXQgYXJlIHN1YmplY3QgdG8gY2hhbmdlLgorICAgICAqLworCisgICAgLyoqCisgICAgICogSW1wbGVtZW50YXRpb24gZGV0YWlsLgorICAgICAqIEBkZXByZWNhdGVkIEltcGxlbWVudGF0aW9uIGRldGFpbC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZCBpbnQgT1BfSUdFVF9XSURFX1ZPTEFUSUxFICAgICAgICAgICA9IDB4ZTg7CisKKyAgICAvKioKKyAgICAgKiBJbXBsZW1lbnRhdGlvbiBkZXRhaWwuCisgICAgICogQGRlcHJlY2F0ZWQgSW1wbGVtZW50YXRpb24gZGV0YWlsLgorICAgICAqLworICAgIEBEZXByZWNhdGVkIGludCBPUF9JUFVUX1dJREVfVk9MQVRJTEUgICAgICAgICAgID0gMHhlOTsKKworICAgIC8qKgorICAgICAqIEltcGxlbWVudGF0aW9uIGRldGFpbC4KKyAgICAgKiBAZGVwcmVjYXRlZCBJbXBsZW1lbnRhdGlvbiBkZXRhaWwuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQgaW50IE9QX1NHRVRfV0lERV9WT0xBVElMRSAgICAgICAgICAgPSAweGVhOworCisgICAgLyoqCisgICAgICogSW1wbGVtZW50YXRpb24gZGV0YWlsLgorICAgICAqIEBkZXByZWNhdGVkIEltcGxlbWVudGF0aW9uIGRldGFpbC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZCBpbnQgT1BfU1BVVF9XSURFX1ZPTEFUSUxFICAgICAgICAgICA9IDB4ZWI7CisKKyAgICAvKioKKyAgICAgKiBJbXBsZW1lbnRhdGlvbiBkZXRhaWwuCisgICAgICogQGRlcHJlY2F0ZWQgSW1wbGVtZW50YXRpb24gZGV0YWlsLgorICAgICAqLworICAgIEBEZXByZWNhdGVkIGludCBPUF9CUkVBS1BPSU5UICAgICAgICAgICAgICAgICAgID0gMHhlYzsKKworICAgIC8qKgorICAgICAqIEltcGxlbWVudGF0aW9uIGRldGFpbC4KKyAgICAgKiBAZGVwcmVjYXRlZCBJbXBsZW1lbnRhdGlvbiBkZXRhaWwuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQgaW50IE9QX1RIUk9XX1ZFUklGSUNBVElPTl9FUlJPUiAgICAgPSAweGVkOworCisgICAgLyoqCisgICAgICogSW1wbGVtZW50YXRpb24gZGV0YWlsLgorICAgICAqIEBkZXByZWNhdGVkIEltcGxlbWVudGF0aW9uIGRldGFpbC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZCBpbnQgT1BfRVhFQ1VURV9JTkxJTkUgICAgICAgICAgICAgICA9IDB4ZWU7CisKKyAgICAvKioKKyAgICAgKiBJbXBsZW1lbnRhdGlvbiBkZXRhaWwuCisgICAgICogQGRlcHJlY2F0ZWQgSW1wbGVtZW50YXRpb24gZGV0YWlsLgorICAgICAqLworICAgIEBEZXByZWNhdGVkIGludCBPUF9FWEVDVVRFX0lOTElORV9SQU5HRSAgICAgICAgID0gMHhlZjsKKworICAgIC8qKgorICAgICAqIEltcGxlbWVudGF0aW9uIGRldGFpbC4KKyAgICAgKiBAZGVwcmVjYXRlZCBJbXBsZW1lbnRhdGlvbiBkZXRhaWwuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQgaW50IE9QX0lOVk9LRV9ESVJFQ1RfRU1QVFkgICAgICAgICAgPSAweGYwOworCisgICAgLyoqCisgICAgICogSW1wbGVtZW50YXRpb24gZGV0YWlsLgorICAgICAqIEBkZXByZWNhdGVkIEltcGxlbWVudGF0aW9uIGRldGFpbC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZCBpbnQgT1BfSUdFVF9RVUlDSyAgICAgICAgICAgICAgICAgICA9IDB4ZjI7CisKKyAgICAvKioKKyAgICAgKiBJbXBsZW1lbnRhdGlvbiBkZXRhaWwuCisgICAgICogQGRlcHJlY2F0ZWQgSW1wbGVtZW50YXRpb24gZGV0YWlsLgorICAgICAqLworICAgIEBEZXByZWNhdGVkIGludCBPUF9JR0VUX1dJREVfUVVJQ0sgICAgICAgICAgICAgID0gMHhmMzsKKworICAgIC8qKgorICAgICAqIEltcGxlbWVudGF0aW9uIGRldGFpbC4KKyAgICAgKiBAZGVwcmVjYXRlZCBJbXBsZW1lbnRhdGlvbiBkZXRhaWwuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQgaW50IE9QX0lHRVRfT0JKRUNUX1FVSUNLICAgICAgICAgICAgPSAweGY0OworCisgICAgLyoqCisgICAgICogSW1wbGVtZW50YXRpb24gZGV0YWlsLgorICAgICAqIEBkZXByZWNhdGVkIEltcGxlbWVudGF0aW9uIGRldGFpbC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZCBpbnQgT1BfSVBVVF9RVUlDSyAgICAgICAgICAgICAgICAgICA9IDB4ZjU7CisKKyAgICAvKioKKyAgICAgKiBJbXBsZW1lbnRhdGlvbiBkZXRhaWwuCisgICAgICogQGRlcHJlY2F0ZWQgSW1wbGVtZW50YXRpb24gZGV0YWlsLgorICAgICAqLworICAgIEBEZXByZWNhdGVkIGludCBPUF9JUFVUX1dJREVfUVVJQ0sgICAgICAgICAgICAgID0gMHhmNjsKKworICAgIC8qKgorICAgICAqIEltcGxlbWVudGF0aW9uIGRldGFpbC4KKyAgICAgKiBAZGVwcmVjYXRlZCBJbXBsZW1lbnRhdGlvbiBkZXRhaWwuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQgaW50IE9QX0lQVVRfT0JKRUNUX1FVSUNLICAgICAgICAgICAgPSAweGY3OworCisgICAgLyoqCisgICAgICogSW1wbGVtZW50YXRpb24gZGV0YWlsLgorICAgICAqIEBkZXByZWNhdGVkIEltcGxlbWVudGF0aW9uIGRldGFpbC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZCBpbnQgT1BfSU5WT0tFX1ZJUlRVQUxfUVVJQ0sgICAgICAgICA9IDB4Zjg7CisKKyAgICAvKioKKyAgICAgKiBJbXBsZW1lbnRhdGlvbiBkZXRhaWwuCisgICAgICogQGRlcHJlY2F0ZWQgSW1wbGVtZW50YXRpb24gZGV0YWlsLgorICAgICAqLworICAgIEBEZXByZWNhdGVkIGludCBPUF9JTlZPS0VfVklSVFVBTF9RVUlDS19SQU5HRSAgID0gMHhmOTsKKworICAgIC8qKgorICAgICAqIEltcGxlbWVudGF0aW9uIGRldGFpbC4KKyAgICAgKiBAZGVwcmVjYXRlZCBJbXBsZW1lbnRhdGlvbiBkZXRhaWwuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQgaW50IE9QX0lOVk9LRV9TVVBFUl9RVUlDSyAgICAgICAgICAgPSAweGZhOworCisgICAgLyoqCisgICAgICogSW1wbGVtZW50YXRpb24gZGV0YWlsLgorICAgICAqIEBkZXByZWNhdGVkIEltcGxlbWVudGF0aW9uIGRldGFpbC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZCBpbnQgT1BfSU5WT0tFX1NVUEVSX1FVSUNLX1JBTkdFICAgICA9IDB4ZmI7Cit9CmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvYnl0ZWNvZGUvcGFja2FnZS5odG1sIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2J5dGVjb2RlL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MmIwZTkyCi0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL2J5dGVjb2RlL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDcgQEAKKzxodG1sPgorICA8Ym9keT4KKyAgICA8cD4KKyAgICAgIFByb3ZpZGVzIGNsYXNzZXMgcmVsYXRlZCB0byBEYWx2aWsgYnl0ZWNvZGUuIAorICAgIDwvcD4KKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9BbGxvY2F0aW9uTGltaXRFcnJvci5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9BbGxvY2F0aW9uTGltaXRFcnJvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIzZjg5NDcKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL0FsbG9jYXRpb25MaW1pdEVycm9yLmphdmEKQEAgLTAsMCArMSw0MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLnN5c3RlbTsKKworLyoqCisgKiBJcyB0aHJvd24gd2hlbiBhbiBhbGxvY2F0aW9uIGxpbWl0IGlzIGV4Y2VlZGVkLgorICoKKyAqIEBoaWRlCisgKi8KK3B1YmxpYyBjbGFzcyBBbGxvY2F0aW9uTGltaXRFcnJvciBleHRlbmRzIFZpcnR1YWxNYWNoaW5lRXJyb3IgeworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgZXhjZXB0aW9uIGluc3RhbmNlIGFuZCBpbml0aWFsaXplcyBpdCB3aXRoIGRlZmF1bHQgdmFsdWVzLgorICAgICAqLworICAgIHB1YmxpYyBBbGxvY2F0aW9uTGltaXRFcnJvcigpIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGV4Y2VwdGlvbiBpbnN0YW5jZSBhbmQgaW5pdGlhbGl6ZXMgaXQgd2l0aCBhIGdpdmVuIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZSB0aGUgZXJyb3IgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBBbGxvY2F0aW9uTGltaXRFcnJvcihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vQmFzZURleENsYXNzTG9hZGVyLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL0Jhc2VEZXhDbGFzc0xvYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiMjRmMGIKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL0Jhc2VEZXhDbGFzc0xvYWRlci5qYXZhCkBAIC0wLDAgKzEsMTI4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBkYWx2aWsuc3lzdGVtOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CisKKy8qKgorICogQmFzZSBjbGFzcyBmb3IgY29tbW9uIGZ1bmN0aW9uYWxpdHkgYmV0d2VlbiB2YXJpb3VzIGRleC1iYXNlZAorICoge0BsaW5rIENsYXNzTG9hZGVyfSBpbXBsZW1lbnRhdGlvbnMuCisgKi8KK3B1YmxpYyBjbGFzcyBCYXNlRGV4Q2xhc3NMb2FkZXIgZXh0ZW5kcyBDbGFzc0xvYWRlciB7CisgICAgLyoqIG9yaWdpbmFsbHkgc3BlY2lmaWVkIHBhdGggKGp1c3QgdXNlZCBmb3Ige0Bjb2RlIHRvU3RyaW5nKCl9KSAqLworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG9yaWdpbmFsUGF0aDsKKworICAgIC8qKiBzdHJ1Y3R1cmVkIGxpc3RzIG9mIHBhdGggZWxlbWVudHMgKi8KKyAgICBwcml2YXRlIGZpbmFsIERleFBhdGhMaXN0IHBhdGhMaXN0OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXhQYXRoIHRoZSBsaXN0IG9mIGphci9hcGsgZmlsZXMgY29udGFpbmluZyBjbGFzc2VzIGFuZAorICAgICAqIHJlc291cmNlcywgZGVsaW1pdGVkIGJ5IHtAY29kZSBGaWxlLnBhdGhTZXBhcmF0b3J9LCB3aGljaAorICAgICAqIGRlZmF1bHRzIHRvIHtAY29kZSAiOiJ9IG9uIEFuZHJvaWQKKyAgICAgKiBAcGFyYW0gb3B0aW1pemVkRGlyZWN0b3J5IGRpcmVjdG9yeSB3aGVyZSBvcHRpbWl6ZWQgZGV4IGZpbGVzCisgICAgICogc2hvdWxkIGJlIHdyaXR0ZW47IG1heSBiZSB7QGNvZGUgbnVsbH0KKyAgICAgKiBAcGFyYW0gbGlicmFyeVBhdGggdGhlIGxpc3Qgb2YgZGlyZWN0b3JpZXMgY29udGFpbmluZyBuYXRpdmUKKyAgICAgKiBsaWJyYXJpZXMsIGRlbGltaXRlZCBieSB7QGNvZGUgRmlsZS5wYXRoU2VwYXJhdG9yfTsgbWF5IGJlCisgICAgICoge0Bjb2RlIG51bGx9CisgICAgICogQHBhcmFtIHBhcmVudCB0aGUgcGFyZW50IGNsYXNzIGxvYWRlcgorICAgICAqLworICAgIHB1YmxpYyBCYXNlRGV4Q2xhc3NMb2FkZXIoU3RyaW5nIGRleFBhdGgsIEZpbGUgb3B0aW1pemVkRGlyZWN0b3J5LAorICAgICAgICAgICAgU3RyaW5nIGxpYnJhcnlQYXRoLCBDbGFzc0xvYWRlciBwYXJlbnQpIHsKKyAgICAgICAgc3VwZXIocGFyZW50KTsKKworICAgICAgICB0aGlzLm9yaWdpbmFsUGF0aCA9IGRleFBhdGg7CisgICAgICAgIHRoaXMucGF0aExpc3QgPQorICAgICAgICAgICAgbmV3IERleFBhdGhMaXN0KHRoaXMsIGRleFBhdGgsIGxpYnJhcnlQYXRoLCBvcHRpbWl6ZWREaXJlY3RvcnkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBDbGFzczw/PiBmaW5kQ2xhc3MoU3RyaW5nIG5hbWUpIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgQ2xhc3MgY2xhenogPSBwYXRoTGlzdC5maW5kQ2xhc3MobmFtZSk7CisKKyAgICAgICAgaWYgKGNsYXp6ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uKG5hbWUpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGNsYXp6OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBVUkwgZmluZFJlc291cmNlKFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiBwYXRoTGlzdC5maW5kUmVzb3VyY2UobmFtZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIEVudW1lcmF0aW9uPFVSTD4gZmluZFJlc291cmNlcyhTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gcGF0aExpc3QuZmluZFJlc291cmNlcyhuYW1lKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGZpbmRMaWJyYXJ5KFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiBwYXRoTGlzdC5maW5kTGlicmFyeShuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHBhY2thZ2UgaW5mb3JtYXRpb24gZm9yIHRoZSBnaXZlbiBwYWNrYWdlLgorICAgICAqIFVuZm9ydHVuYXRlbHksIGluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIGRvbid0IHJlYWxseSBoYXZlIHRoaXMKKyAgICAgKiBpbmZvcm1hdGlvbiwgYW5kIGFzIGEgbm9uLXNlY3VyZSB7QGNvZGUgQ2xhc3NMb2FkZXJ9LCBpdCBpc24ndAorICAgICAqIGV2ZW4gcmVxdWlyZWQgdG8sIGFjY29yZGluZyB0byB0aGUgc3BlYy4gWWV0LCB3ZSB3YW50IHRvCisgICAgICogcHJvdmlkZSBpdCwgaW4gb3JkZXIgdG8gbWFrZSBhbGwgdGhvc2UgaG9wZWZ1bCBjYWxsZXJzIG9mCisgICAgICoge0Bjb2RlIG15Q2xhc3MuZ2V0UGFja2FnZSgpLmdldE5hbWUoKX0gaGFwcHkuIFRodXMgd2UgY29uc3RydWN0CisgICAgICogYSB7QGNvZGUgUGFja2FnZX0gb2JqZWN0IHRoZSBmaXJzdCB0aW1lIGl0IGlzIGJlaW5nIHJlcXVlc3RlZAorICAgICAqIGFuZCBmaWxsIG1vc3Qgb2YgdGhlIGZpZWxkcyB3aXRoIGR1bW15IHZhbHVlcy4gVGhlIHtAY29kZQorICAgICAqIFBhY2thZ2V9IG9iamVjdCBpcyB0aGVuIHB1dCBpbnRvIHRoZSB7QGNvZGUgQ2xhc3NMb2FkZXJ9J3MKKyAgICAgKiBwYWNrYWdlIGNhY2hlLCBzbyB3ZSBzZWUgdGhlIHNhbWUgb25lIG5leHQgdGltZS4gV2UgZG9uJ3QKKyAgICAgKiBjcmVhdGUge0Bjb2RlIFBhY2thZ2V9IG9iamVjdHMgZm9yIHtAY29kZSBudWxsfSBhcmd1bWVudHMgb3IKKyAgICAgKiBmb3IgdGhlIGRlZmF1bHQgcGFja2FnZS4KKyAgICAgKgorICAgICAqIDxwPlRoZXJlIGlzIGEgbGltaXRlZCBjaGFuY2UgdGhhdCB3ZSBlbmQgdXAgd2l0aCBtdWx0aXBsZQorICAgICAqIHtAY29kZSBQYWNrYWdlfSBvYmplY3RzIHJlcHJlc2VudGluZyB0aGUgc2FtZSBwYWNrYWdlOiBJdCBjYW4KKyAgICAgKiBoYXBwZW4gd2hlbiB3aGVuIGEgcGFja2FnZSBpcyBzY2F0dGVyZWQgYWNyb3NzIGRpZmZlcmVudCBKQVIKKyAgICAgKiBmaWxlcyB3aGljaCB3ZXJlIGxvYWRlZCBieSBkaWZmZXJlbnQge0Bjb2RlIENsYXNzTG9hZGVyfQorICAgICAqIGluc3RhbmNlcy4gVGhpcyBpcyByYXRoZXIgdW5saWtlbHksIGFuZCBnaXZlbiB0aGF0IHRoaXMgd2hvbGUKKyAgICAgKiB0aGluZyBpcyBtb3JlIG9yIGxlc3MgYSB3b3JrYXJvdW5kLCBwcm9iYWJseSBub3Qgd29ydGggdGhlCisgICAgICogZWZmb3J0IHRvIGFkZHJlc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgY2xhc3MKKyAgICAgKiBAcmV0dXJuIHRoZSBwYWNrYWdlIGluZm9ybWF0aW9uIGZvciB0aGUgY2xhc3MsIG9yIHtAY29kZSBudWxsfQorICAgICAqIGlmIHRoZXJlIGlzIG5vIHBhY2thZ2UgaW5mb3JtYXRpb24gYXZhaWxhYmxlIGZvciBpdAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBzeW5jaHJvbml6ZWQgUGFja2FnZSBnZXRQYWNrYWdlKFN0cmluZyBuYW1lKSB7CisgICAgICAgIGlmIChuYW1lICE9IG51bGwgJiYgIW5hbWUuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBQYWNrYWdlIHBhY2sgPSBzdXBlci5nZXRQYWNrYWdlKG5hbWUpOworCisgICAgICAgICAgICBpZiAocGFjayA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcGFjayA9IGRlZmluZVBhY2thZ2UobmFtZSwgIlVua25vd24iLCAiMC4wIiwgIlVua25vd24iLAorICAgICAgICAgICAgICAgICAgICAgICAgIlVua25vd24iLCAiMC4wIiwgIlVua25vd24iLCBudWxsKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIHBhY2s7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiWyIgKyBvcmlnaW5hbFBhdGggKyAiXSI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9CbG9ja0d1YXJkLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL0Jsb2NrR3VhcmQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNjFmMGUxCi0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9CbG9ja0d1YXJkLmphdmEKQEAgLTAsMCArMSwxNTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5zeXN0ZW07CisKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEubmV0LlNvY2tldEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRzOworCisvKioKKyAqIE1lY2hhbmlzbSB0byBsZXQgdGhyZWFkcyBzZXQgcmVzdHJpY3Rpb25zIG9uIHdoYXQgY29kZSBpcyBhbGxvd2VkCisgKiB0byBkbyBpbiB0aGVpciB0aHJlYWQuCisgKgorICogPHA+VGhpcyBpcyBtZWFudCBmb3IgYXBwbGljYXRpb25zIHRvIHByZXZlbnQgY2VydGFpbiBibG9ja2luZworICogb3BlcmF0aW9ucyBmcm9tIHJ1bm5pbmcgb24gdGhlaXIgbWFpbiBldmVudCBsb29wIChvciAiVUkiKSB0aHJlYWRzLgorICoKKyAqIDxwPk5vdGUgdGhhdCB0aGlzIGlzIGFsbCBiZXN0LWVmZm9ydCB0byBjYXRjaCBtb3N0IGFjY2lkZW50YWwgbWlzdGFrZXMKKyAqIGFuZCBpc24ndCBpbnRlbmRlZCB0byBiZSBhIHBlcmZlY3QgbWVjaGFuaXNtLCBub3IgcHJvdmlkZSBhbnkgc29ydCBvZgorICogc2VjdXJpdHkuCisgKgorICogQGhpZGUKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEJsb2NrR3VhcmQgeworCisgICAgLy8gVE9ETzogcmVmYWN0b3IgY2xhc3MgbmFtZSB0byBzb21ldGhpbmcgbW9yZSBnZW5lcmljLCBzaW5jZSBpdHMgc2NvcGUgaXMKKyAgICAvLyBncm93aW5nIGJleW9uZCBqdXN0IGJsb2NraW5nL2xvZ2dpbmcuCisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBESVNBTExPV19ESVNLX1dSSVRFID0gMHgwMTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBESVNBTExPV19ESVNLX1JFQUQgPSAweDAyOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERJU0FMTE9XX05FVFdPUksgPSAweDA0OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBU1NfUkVTVFJJQ1RJT05TX1ZJQV9SUEMgPSAweDA4OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBFTkFMVFlfTE9HID0gMHgxMDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQRU5BTFRZX0RJQUxPRyA9IDB4MjA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEVOQUxUWV9ERUFUSCA9IDB4NDA7CisKKyAgICBwdWJsaWMgaW50ZXJmYWNlIFBvbGljeSB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBDYWxsZWQgb24gZGlzayB3cml0ZXMuCisgICAgICAgICAqLworICAgICAgICB2b2lkIG9uV3JpdGVUb0Rpc2soKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ2FsbGVkIG9uIGRpc2sgcmVhZHMuCisgICAgICAgICAqLworICAgICAgICB2b2lkIG9uUmVhZEZyb21EaXNrKCk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENhbGxlZCBvbiBuZXR3b3JrIG9wZXJhdGlvbnMuCisgICAgICAgICAqLworICAgICAgICB2b2lkIG9uTmV0d29yaygpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRoZSBwb2xpY3kgYml0bWFzaywgZm9yIHNoaXBwaW5nIG92ZXIgQmluZGVyIGNhbGxzCisgICAgICAgICAqIHRvIHJlbW90ZSB0aHJlYWRzL3Byb2Nlc3NlcyBhbmQgcmVpbnN0YW50aWF0aW5nIHRoZSBwb2xpY3kKKyAgICAgICAgICogdGhlcmUuICBUaGUgYml0cyBpbiB0aGUgbWFzayBhcmUgZnJvbSB0aGUgRElTQUxMT1dfKiBhbmQKKyAgICAgICAgICogUEVOQUxUWV8qIGNvbnN0YW50cy4KKyAgICAgICAgICovCisgICAgICAgIGludCBnZXRQb2xpY3lNYXNrKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBCbG9ja0d1YXJkUG9saWN5RXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CisgICAgICAgIC8vIGJpdG1hc2sgb2YgRElTQUxMT1dfKiwgUEVOQUxUWV8qLCBldGMgZmxhZ3MKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbVBvbGljeVN0YXRlOworICAgICAgICBwcml2YXRlIGZpbmFsIGludCBtUG9saWN5VmlvbGF0ZWQ7CisgICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG1NZXNzYWdlOyAgIC8vIG1heSBiZSBudWxsCisKKyAgICAgICAgcHVibGljIEJsb2NrR3VhcmRQb2xpY3lFeGNlcHRpb24oaW50IHBvbGljeVN0YXRlLCBpbnQgcG9saWN5VmlvbGF0ZWQpIHsKKyAgICAgICAgICAgIHRoaXMocG9saWN5U3RhdGUsIHBvbGljeVZpb2xhdGVkLCBudWxsKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBCbG9ja0d1YXJkUG9saWN5RXhjZXB0aW9uKGludCBwb2xpY3lTdGF0ZSwgaW50IHBvbGljeVZpb2xhdGVkLCBTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICAgICAgbVBvbGljeVN0YXRlID0gcG9saWN5U3RhdGU7CisgICAgICAgICAgICBtUG9saWN5VmlvbGF0ZWQgPSBwb2xpY3lWaW9sYXRlZDsKKyAgICAgICAgICAgIG1NZXNzYWdlID0gbWVzc2FnZTsKKyAgICAgICAgICAgIGZpbGxJblN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0UG9saWN5KCkgeworICAgICAgICAgICAgcmV0dXJuIG1Qb2xpY3lTdGF0ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0UG9saWN5VmlvbGF0aW9uKCkgeworICAgICAgICAgICAgcmV0dXJuIG1Qb2xpY3lWaW9sYXRlZDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKyAgICAgICAgICAgIC8vIE5vdGU6IGRvIG5vdCBjaGFuZ2UgdGhpcyBmb3JtYXQgY2FzdWFsbHkuICBJdCdzCisgICAgICAgICAgICAvLyBzb21ld2hhdCB1bmZvcnR1bmF0ZWx5IFBhcmNlbGVkIGFuZCBwYXNzZWQgYXJvdW5kCisgICAgICAgICAgICAvLyBCaW5kZXIgY2FsbHMgYW5kIHBhcnNlZCBiYWNrIGludG8gYW4gRXhjZXB0aW9uIGJ5CisgICAgICAgICAgICAvLyBBbmRyb2lkJ3MgU3RyaWN0TW9kZS4gIFRoaXMgd2FzIHRoZSBsZWFzdCBpbnZhc2l2ZQorICAgICAgICAgICAgLy8gb3B0aW9uIGFuZCBhdm9pZGVkIGEgZ3Jvc3MgbWl4IG9mIEphdmEgU2VyaWFsaXphdGlvbgorICAgICAgICAgICAgLy8gY29tYmluZWQgd2l0aCBQYXJjZWxzLgorICAgICAgICAgICAgcmV0dXJuICJwb2xpY3k9IiArIG1Qb2xpY3lTdGF0ZSArICIgdmlvbGF0aW9uPSIgKyBtUG9saWN5VmlvbGF0ZWQgKworICAgICAgICAgICAgICAgICAgICAobU1lc3NhZ2UgPT0gbnVsbCA/ICIiIDogKCIgbXNnPSIgKyBtTWVzc2FnZSkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGRlZmF1bHQsIHBlcm1pc3NpdmUgcG9saWN5IHRoYXQgZG9lc24ndCBwcmV2ZW50IGFueSBvcGVyYXRpb25zLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUG9saWN5IExBWF9QT0xJQ1kgPSBuZXcgUG9saWN5KCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgb25Xcml0ZVRvRGlzaygpIHt9CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBvblJlYWRGcm9tRGlzaygpIHt9CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBvbk5ldHdvcmsoKSB7fQorICAgICAgICAgICAgcHVibGljIGludCBnZXRQb2xpY3lNYXNrKCkgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgVGhyZWFkTG9jYWw8UG9saWN5PiB0aHJlYWRQb2xpY3kgPSBuZXcgVGhyZWFkTG9jYWw8UG9saWN5PigpIHsKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBQb2xpY3kgaW5pdGlhbFZhbHVlKCkgeworICAgICAgICAgICAgcmV0dXJuIExBWF9QT0xJQ1k7CisgICAgICAgIH0KKyAgICB9OworCisgICAgLyoqCisgICAgICogR2V0IHRoZSBjdXJyZW50IHRocmVhZCdzIHBvbGljeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgdGhyZWFkJ3MgcG9saWN5LiAgTmV2ZXIgcmV0dXJucyBudWxsLgorICAgICAqICAgICBXaWxsIHJldHVybiB0aGUgTEFYX1BPTElDWSBpbnN0YW5jZSBpZiBub3RoaW5nIGVsc2UgaXMgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUG9saWN5IGdldFRocmVhZFBvbGljeSgpIHsKKyAgICAgICAgcmV0dXJuIHRocmVhZFBvbGljeS5nZXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjdXJyZW50IHRocmVhZCdzIGJsb2NrIGd1YXJkIHBvbGljeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwb2xpY3kgcG9saWN5IHRvIHNldC4gIE1heSBub3QgYmUgbnVsbC4gIFVzZSB0aGUgcHVibGljIExBWF9QT0xJQ1kKKyAgICAgKiAgIGlmIHlvdSB3YW50IHRvIHVuc2V0IHRoZSBhY3RpdmUgcG9saWN5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRUaHJlYWRQb2xpY3koUG9saWN5IHBvbGljeSkgeworICAgICAgICBpZiAocG9saWN5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicG9saWN5ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aHJlYWRQb2xpY3kuc2V0KHBvbGljeSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBCbG9ja0d1YXJkKCkge30KK30KZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vQ2xvc2VHdWFyZC5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9DbG9zZUd1YXJkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTM2YmUyZgotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vQ2xvc2VHdWFyZC5qYXZhCkBAIC0wLDAgKzEsMjMwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBkYWx2aWsuc3lzdGVtOworCisvKioKKyAqIENsb3NlR3VhcmQgaXMgYSBtZWNoYW5pc20gZm9yIGZsYWdnaW5nIGltcGxpY2l0IGZpbmFsaXplciBjbGVhbnVwIG9mCisgKiByZXNvdXJjZXMgdGhhdCBzaG91bGQgaGF2ZSBiZWVuIGNsZWFuZWQgdXAgYnkgZXhwbGljaXQgY2xvc2UKKyAqIG1ldGhvZHMgKGFrYSAiZXhwbGljaXQgdGVybWluYXRpb24gbWV0aG9kcyIgaW4gRWZmZWN0aXZlIEphdmEpLgorICogPHA+CisgKiBBIHNpbXBsZSBleGFtcGxlOiA8cHJlPiAgIHtAY29kZQorICogICBjbGFzcyBGb28geworICoKKyAqICAgICAgIHByaXZhdGUgZmluYWwgQ2xvc2VHdWFyZCBndWFyZCA9IENsb3NlR3VhcmQuZ2V0KCk7CisgKgorICogICAgICAgLi4uCisgKgorICogICAgICAgcHVibGljIEZvbygpIHsKKyAqICAgICAgICAgICAuLi47CisgKiAgICAgICAgICAgZ3VhcmQub3BlbigiY2xlYW51cCIpOworICogICAgICAgfQorICoKKyAqICAgICAgIHB1YmxpYyB2b2lkIGNsZWFudXAoKSB7CisgKiAgICAgICAgICBndWFyZC5jbG9zZSgpOworICogICAgICAgICAgLi4uOworICogICAgICAgfQorICoKKyAqICAgICAgIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisgKiAgICAgICAgICAgdHJ5IHsKKyAqICAgICAgICAgICAgICAgaWYgKGd1YXJkICE9IG51bGwpIHsKKyAqICAgICAgICAgICAgICAgICAgIGd1YXJkLndhcm5JZk9wZW4oKTsKKyAqICAgICAgICAgICAgICAgfQorICogICAgICAgICAgICAgICBjbGVhbnVwKCk7CisgKiAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAqICAgICAgICAgICAgICAgc3VwZXIuZmluYWxpemUoKTsKKyAqICAgICAgICAgICB9CisgKiAgICAgICB9CisgKiAgIH0KKyAqIH08L3ByZT4KKyAqCisgKiBJbiB1c2FnZSB3aGVyZSB0aGUgcmVzb3VyY2UgdG8gYmUgZXhwbGljaXRseSBjbGVhbmVkIHVwIGFyZQorICogYWxsb2NhdGVkIGFmdGVyIG9iamVjdCBjb25zdHJ1Y3Rpb24sIENsb3NlR3VhcmQgcHJvdGVjdGlvbiBjYW4KKyAqIGJlIGRlZmVycmVkLiBGb3IgZXhhbXBsZTogPHByZT4gICB7QGNvZGUKKyAqICAgY2xhc3MgQmFyIHsKKyAqCisgKiAgICAgICBwcml2YXRlIGZpbmFsIENsb3NlR3VhcmQgZ3VhcmQgPSBDbG9zZUd1YXJkLmdldCgpOworICoKKyAqICAgICAgIC4uLgorICoKKyAqICAgICAgIHB1YmxpYyBCYXIoKSB7CisgKiAgICAgICAgICAgLi4uOworICogICAgICAgfQorICoKKyAqICAgICAgIHB1YmxpYyB2b2lkIGNvbm5lY3QoKSB7CisgKiAgICAgICAgICAuLi47CisgKiAgICAgICAgICBndWFyZC5vcGVuKCJjbGVhbnVwIik7CisgKiAgICAgICB9CisgKgorICogICAgICAgcHVibGljIHZvaWQgY2xlYW51cCgpIHsKKyAqICAgICAgICAgIGd1YXJkLmNsb3NlKCk7CisgKiAgICAgICAgICAuLi47CisgKiAgICAgICB9CisgKgorICogICAgICAgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAqICAgICAgICAgICB0cnkgeworICogICAgICAgICAgICAgICBpZiAoZ3VhcmQgIT0gbnVsbCkgeworICogICAgICAgICAgICAgICAgICAgZ3VhcmQud2FybklmT3BlbigpOworICogICAgICAgICAgICAgICB9CisgKiAgICAgICAgICAgICAgIGNsZWFudXAoKTsKKyAqICAgICAgICAgICB9IGZpbmFsbHkgeworICogICAgICAgICAgICAgICBzdXBlci5maW5hbGl6ZSgpOworICogICAgICAgICAgIH0KKyAqICAgICAgIH0KKyAqICAgfQorICogfTwvcHJlPgorICoKKyAqIFdoZW4gdXNlZCBpbiBhIGNvbnN0cnVjdG9yIGNhbGxzIHRvIHtAY29kZSBvcGVufSBzaG91bGQgb2NjdXIgYXQKKyAqIHRoZSBlbmQgb2YgdGhlIGNvbnN0cnVjdG9yIHNpbmNlIGFuIGV4Y2VwdGlvbiB0aGF0IHdvdWxkIGNhdXNlCisgKiBhYnJ1cHQgdGVybWluYXRpb24gb2YgdGhlIGNvbnN0cnVjdG9yIHdpbGwgbWVhbiB0aGF0IHRoZSB1c2VyIHdpbGwKKyAqIG5vdCBoYXZlIGEgcmVmZXJlbmNlIHRvIHRoZSBvYmplY3QgdG8gY2xlYW51cCBleHBsaWNpdGx5LiBXaGVuIHVzZWQKKyAqIGluIGEgbWV0aG9kLCB0aGUgY2FsbCB0byB7QGNvZGUgb3Blbn0gc2hvdWxkIG9jY3VyIGp1c3QgYWZ0ZXIKKyAqIHJlc291cmNlIGFjcXVpc2l0aW9uLgorICoKKyAqIDxwPgorICoKKyAqIE5vdGUgdGhhdCB0aGUgbnVsbCBjaGVjayBvbiB7QGNvZGUgZ3VhcmR9IGluIHRoZSBmaW5hbGl6ZXIgaXMgdG8KKyAqIGNvdmVyIGNhc2VzIHdoZXJlIGEgY29uc3RydWN0b3IgdGhyb3dzIGFuIGV4Y2VwdGlvbiBjYXVzaW5nIHRoZQorICoge0Bjb2RlIGd1YXJkfSB0byBiZSB1bmluaXRpYWxpemVkLgorICoKKyAqIEBoaWRlCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBDbG9zZUd1YXJkIHsKKworICAgIC8qKgorICAgICAqIEluc3RhbmNlIHVzZWQgd2hlbiBDbG9zZUd1YXJkIGlzIGRpc2FibGVkIHRvIGF2b2lkIGFsbG9jYXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ2xvc2VHdWFyZCBOT09QID0gbmV3IENsb3NlR3VhcmQoKTsKKworICAgIC8qKgorICAgICAqIEVuYWJsZWQgYnkgZGVmYXVsdCBzbyB3ZSBjYW4gY2F0Y2ggaXNzdWVzIGVhcmx5IGluIFZNIHN0YXJ0dXAuCisgICAgICogTm90ZSwgaG93ZXZlciwgdGhhdCBBbmRyb2lkIGRpc2FibGVzIHRoaXMgZWFybHkgaW4gaXRzIHN0YXJ0dXAsCisgICAgICogYnV0IGVuYWJsZXMgaXQgd2l0aCBEcm9wQm94aW5nIGZvciBzeXN0ZW0gYXBwcyBvbiBkZWJ1ZyBidWlsZHMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9sYXRpbGUgYm9vbGVhbiBFTkFCTEVEID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIEhvb2sgZm9yIGN1c3RvbWl6aW5nIGhvdyBDbG9zZUd1YXJkIGlzc3VlcyBhcmUgcmVwb3J0ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9sYXRpbGUgUmVwb3J0ZXIgUkVQT1JURVIgPSBuZXcgRGVmYXVsdFJlcG9ydGVyKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgQ2xvc2VHdWFyZCBpbnN0YW5jZS4gSWYgQ2xvc2VHdWFyZCBpcyBlbmFibGVkLCB7QGNvZGUKKyAgICAgKiAjb3BlbihTdHJpbmcpfSBjYW4gYmUgdXNlZCB0byBzZXQgdXAgdGhlIGluc3RhbmNlIHRvIHdhcm4gb24KKyAgICAgKiBmYWlsdXJlIHRvIGNsb3NlLiBJZiBDbG9zZUd1YXJkIGlzIGRpc2FibGVkLCBhIG5vbi1udWxsIG5vLW9wCisgICAgICogaW5zdGFuY2UgaXMgcmV0dXJuZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDbG9zZUd1YXJkIGdldCgpIHsKKyAgICAgICAgaWYgKCFFTkFCTEVEKSB7CisgICAgICAgICAgICByZXR1cm4gTk9PUDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IENsb3NlR3VhcmQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2VkIHRvIGVuYWJsZSBvciBkaXNhYmxlIENsb3NlR3VhcmQuIE5vdGUgdGhhdCBDbG9zZUd1YXJkIG9ubHkKKyAgICAgKiB3YXJucyBpZiBpdCBpcyBlbmFibGVkIGZvciBib3RoIGFsbG9jYXRpb24gYW5kIGZpbmFsaXphdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0RW5hYmxlZChib29sZWFuIGVuYWJsZWQpIHsKKyAgICAgICAgRU5BQkxFRCA9IGVuYWJsZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlZCB0byByZXBsYWNlIGRlZmF1bHQgUmVwb3J0ZXIgdXNlZCB0byB3YXJuIG9mIENsb3NlR3VhcmQKKyAgICAgKiB2aW9sYXRpb25zLiBNdXN0IGJlIG5vbi1udWxsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRSZXBvcnRlcihSZXBvcnRlciByZXBvcnRlcikgeworICAgICAgICBpZiAocmVwb3J0ZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJyZXBvcnRlciA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgUkVQT1JURVIgPSByZXBvcnRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIG5vbi1udWxsIENsb3NlR3VhcmQuUmVwb3J0ZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBSZXBvcnRlciBnZXRSZXBvcnRlcigpIHsKKyAgICAgICAgcmV0dXJuIFJFUE9SVEVSOworICAgIH0KKworICAgIHByaXZhdGUgQ2xvc2VHdWFyZCgpIHt9CisKKyAgICAvKioKKyAgICAgKiBJZiBDbG9zZUd1YXJkIGlzIGVuYWJsZWQsIHtAY29kZSBvcGVufSBpbml0aWFsaXplcyB0aGUgaW5zdGFuY2UKKyAgICAgKiB3aXRoIGEgd2FybmluZyB0aGF0IHRoZSBjYWxsZXIgc2hvdWxkIGhhdmUgZXhwbGljaXRseSBjYWxsZWQgdGhlCisgICAgICoge0Bjb2RlIGNsb3Nlcn0gbWV0aG9kIGluc3RlYWQgb2YgcmVseWluZyBvbiBmaW5hbGl6YXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2xvc2VyIG5vbi1udWxsIG5hbWUgb2YgZXhwbGljaXQgdGVybWluYXRpb24gbWV0aG9kCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBjbG9zZXIgaXMgbnVsbCwgcmVnYXJkbGVzcyBvZgorICAgICAqIHdoZXRoZXIgb3Igbm90IENsb3NlR3VhcmQgaXMgZW5hYmxlZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG9wZW4oU3RyaW5nIGNsb3NlcikgeworICAgICAgICAvLyBhbHdheXMgcGVyZm9ybSB0aGUgY2hlY2sgZm9yIHZhbGlkIEFQSSB1c2FnZS4uLgorICAgICAgICBpZiAoY2xvc2VyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiY2xvc2VyID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICAvLyAuLi5idXQgYXZvaWQgYWxsb2NhdGluZyBhbiBhbGxvY2F0aW9uU2l0ZSBpZiBkaXNhYmxlZAorICAgICAgICBpZiAodGhpcyA9PSBOT09QIHx8ICFFTkFCTEVEKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIG1lc3NhZ2UgPSAiRXhwbGljaXQgdGVybWluYXRpb24gbWV0aG9kICciICsgY2xvc2VyICsgIicgbm90IGNhbGxlZCI7CisgICAgICAgIGFsbG9jYXRpb25TaXRlID0gbmV3IFRocm93YWJsZShtZXNzYWdlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFRocm93YWJsZSBhbGxvY2F0aW9uU2l0ZTsKKworICAgIC8qKgorICAgICAqIE1hcmtzIHRoaXMgQ2xvc2VHdWFyZCBpbnN0YW5jZSBhcyBjbG9zZWQgdG8gYXZvaWQgd2FybmluZ3Mgb24KKyAgICAgKiBmaW5hbGl6YXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgIGFsbG9jYXRpb25TaXRlID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiBDbG9zZUd1YXJkIGlzIGVuYWJsZWQsIGxvZ3MgYSB3YXJuaW5nIGlmIHRoZSBjYWxsZXIgZGlkIG5vdAorICAgICAqIHByb3Blcmx5IGNsZWFudXAgYnkgY2FsbGluZyBhbiBleHBsaWNpdCBjbG9zZSBtZXRob2QKKyAgICAgKiBiZWZvcmUgZmluYWxpemF0aW9uLiBJZiBDbG9zZUd1YXJkIGlzIGRpc2FibGUsIG5vIGFjdGlvbiBpcworICAgICAqIHBlcmZvcm1lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3YXJuSWZPcGVuKCkgeworICAgICAgICBpZiAoYWxsb2NhdGlvblNpdGUgPT0gbnVsbCB8fCAhRU5BQkxFRCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIG1lc3NhZ2UgPQorICAgICAgICAgICAgICAgICgiQSByZXNvdXJjZSB3YXMgYWNxdWlyZWQgYXQgYXR0YWNoZWQgc3RhY2sgdHJhY2UgYnV0IG5ldmVyIHJlbGVhc2VkLiAiCisgICAgICAgICAgICAgICAgICsgIlNlZSBqYXZhLmlvLkNsb3NlYWJsZSBmb3IgaW5mb3JtYXRpb24gb24gYXZvaWRpbmcgcmVzb3VyY2UgbGVha3MuIik7CisKKyAgICAgICAgUkVQT1JURVIucmVwb3J0KG1lc3NhZ2UsIGFsbG9jYXRpb25TaXRlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnRlcmZhY2UgdG8gYWxsb3cgY3VzdG9taXphdGlvbiBvZiByZXBvcnRpbmcgYmVoYXZpb3IuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnRlcmZhY2UgUmVwb3J0ZXIgeworICAgICAgICBwdWJsaWMgdm9pZCByZXBvcnQgKFN0cmluZyBtZXNzYWdlLCBUaHJvd2FibGUgYWxsb2NhdGlvblNpdGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlZmF1bHQgUmVwb3J0ZXIgd2hpY2ggcmVwb3J0cyBDbG9zZUd1YXJkIHZpb2xhdGlvbnMgdG8gdGhlIGxvZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBEZWZhdWx0UmVwb3J0ZXIgaW1wbGVtZW50cyBSZXBvcnRlciB7CisgICAgICAgIHB1YmxpYyB2b2lkIHJlcG9ydCAoU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBhbGxvY2F0aW9uU2l0ZSkgeworICAgICAgICAgICAgU3lzdGVtLmxvZ1cobWVzc2FnZSwgYWxsb2NhdGlvblNpdGUpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9EYWx2aWtMb2dIYW5kbGVyLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL0RhbHZpa0xvZ0hhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNjJjYTNiCi0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9EYWx2aWtMb2dIYW5kbGVyLmphdmEKQEAgLTAsMCArMSw0NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLnN5c3RlbTsKKworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxldmVsOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ2dlcjsKKworLyoqCisgKiBBbiBvcHRpbWl6ZWQgaGFuZGxlciBmb3IgZWZmaWNpZW50IHB1Ymxpc2hpbmcgb2YgYmFzaWMgbG9nIG1lc3NhZ2VzLgorICogSW1wbGVtZW50ZXJzIHNob3VsZCBhbHNvIGJlIHN1YmNsYXNzZXMgb2Yge0BsaW5rIGphdmEudXRpbC5sb2dnaW5nLkhhbmRsZXJ9LgorICoKKyAqIDxwPlVubGlrZSB0aGUgZGVmYXVsdCBsb2cgaGFuZGxlciwgdGhpcyBBUEkgZG9lc24ndCByZXF1aXJlIGludGVybWVkaWF0ZQorICogb2JqZWN0cyB0byBiZSBhbGxvY2F0ZWQgZm9yIGxvZyBoYW5kbGluZy4gSXQgYWxzbyBpbmNsdWRlcyBhIHNob3J0IHRhZywgd2hpY2gKKyAqIG1heSBvdGhlcndpc2UgbmVlZCB0byBiZSBjYWxjdWxhdGVkIGZvciBlYWNoIHB1Ymxpc2hlZCBtZXNzYWdlLgorICoKKyAqIEBoaWRlCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRGFsdmlrTG9nSGFuZGxlciB7CisKKyAgICAvKioKKyAgICAgKiBQdWJsaXNoZXMgYSBsb2cgbWVzc2FnZS4gVW5saWtlIHtAbGluaworICAgICAqIGphdmEudXRpbC5sb2dnaW5nLkhhbmRsZXIjcHVibGlzaChqYXZhLnV0aWwubG9nZ2luZy5Mb2dSZWNvcmQpfSwgdGhpcworICAgICAqIG1ldGhvZCBpbmNsdWRlcyBvbmx5IHRoZSByYXcgbG9nIG1lc3NhZ2UuIExvZyBtZXNzYWdlcyB0aGF0IHdlcmUgY3JlYXRlZAorICAgICAqIHdpdGggYWRkaXRpb25hbCBmaWVsZHMgKHBhcmFtZXRlcnMsIHNvdXJjZSBtZXRob2RzLCBldGMuKSB3aWxsIGZsb3cKKyAgICAgKiB0aHJvdWdoIHRoZSBjb252ZW50aW9uYWwgY2hhbm5lbHMgaW5zdGVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YWcgdGhlIHNob3J0ICgyMyBjaGFyYWN0ZXJzIG9yIGZld2VyKSBsb2dnZXIgdGFnIGlkZW50aWZ5aW5nCisgICAgICogICAgICB7QGNvZGUgbG9nZ2VyfS4KKyAgICAgKi8KKyAgICB2b2lkIHB1Ymxpc2goTG9nZ2VyIHNvdXJjZSwgU3RyaW5nIHRhZywgTGV2ZWwgbGV2ZWwsIFN0cmluZyBtZXNzYWdlKTsKKworICAgIC8vIFRPRE86IHN1cHBvcnQgbWVzc2FnZXMgd2l0aCB0aHJvd2FibGVzPworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vRGFsdmlrTG9nZ2luZy5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9EYWx2aWtMb2dnaW5nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjVjN2FkNQotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vRGFsdmlrTG9nZ2luZy5qYXZhCkBAIC0wLDAgKzEsNDggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5zeXN0ZW07CisKKy8qKgorICogVXRpbGl0eSBtZXRob2RzIGZvciBsb2dnaW5nIHRvIHtAY29kZSBEYWx2aWtIYW5kbGVyc30uCisgKgorICogQGhpZGUKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIERhbHZpa0xvZ2dpbmcgeworICAgIHByaXZhdGUgRGFsdmlrTG9nZ2luZygpIHt9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzaG9ydCBsb2dnZXIgdGFnICh1cCB0byAyMyBjaGFycykgZm9yIHRoZSBnaXZlbiBsb2dnZXIgbmFtZS4KKyAgICAgKiBUcmFkaXRpb25hbGx5IGxvZ2dlcnMgYXJlIG5hbWVkIGJ5IGZ1bGx5LXF1YWxpZmllZCBKYXZhIGNsYXNzZXM7IHRoaXMKKyAgICAgKiBtZXRob2QgYXR0ZW1wdHMgdG8gcmV0dXJuIGEgY29uY2lzZSBpZGVudGlmeWluZyBwYXJ0IG9mIHN1Y2ggbmFtZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgbG9nZ2VyTmFtZVRvVGFnKFN0cmluZyBsb2dnZXJOYW1lKSB7CisgICAgICAgIC8vIEFub255bW91cyBsb2dnZXIuCisgICAgICAgIGlmIChsb2dnZXJOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAibnVsbCI7CisgICAgICAgIH0KKworICAgICAgICBpbnQgbGVuZ3RoID0gbG9nZ2VyTmFtZS5sZW5ndGgoKTsKKyAgICAgICAgaWYgKGxlbmd0aCA8PSAyMykgeworICAgICAgICAgICAgcmV0dXJuIGxvZ2dlck5hbWU7CisgICAgICAgIH0KKworICAgICAgICBpbnQgbGFzdFBlcmlvZCA9IGxvZ2dlck5hbWUubGFzdEluZGV4T2YoIi4iKTsKKyAgICAgICAgcmV0dXJuIGxlbmd0aCAtIChsYXN0UGVyaW9kICsgMSkgPD0gMjMKKyAgICAgICAgICAgICAgICA/IGxvZ2dlck5hbWUuc3Vic3RyaW5nKGxhc3RQZXJpb2QgKyAxKQorICAgICAgICAgICAgICAgIDogbG9nZ2VyTmFtZS5zdWJzdHJpbmcobG9nZ2VyTmFtZS5sZW5ndGgoKSAtIDIzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL0RleENsYXNzTG9hZGVyLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL0RleENsYXNzTG9hZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWMyYTcwYQotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vRGV4Q2xhc3NMb2FkZXIuamF2YQpAQCAtMCwwICsxLDU5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBkYWx2aWsuc3lzdGVtOworCitpbXBvcnQgamF2YS5pby5GaWxlOworCisvKioKKyAqIEEgY2xhc3MgbG9hZGVyIHRoYXQgbG9hZHMgY2xhc3NlcyBmcm9tIHtAY29kZSAuamFyfSBhbmQge0Bjb2RlIC5hcGt9IGZpbGVzCisgKiBjb250YWluaW5nIGEge0Bjb2RlIGNsYXNzZXMuZGV4fSBlbnRyeS4gVGhpcyBjYW4gYmUgdXNlZCB0byBleGVjdXRlIGNvZGUgbm90CisgKiBpbnN0YWxsZWQgYXMgcGFydCBvZiBhbiBhcHBsaWNhdGlvbi4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGxvYWRlciByZXF1aXJlcyBhbiBhcHBsaWNhdGlvbi1wcml2YXRlLCB3cml0YWJsZSBkaXJlY3RvcnkgdG8KKyAqIGNhY2hlIG9wdGltaXplZCBjbGFzc2VzLiBVc2Uge0Bjb2RlIENvbnRleHQuZ2V0RGlyKFN0cmluZywgaW50KX0gdG8gY3JlYXRlCisgKiBzdWNoIGEgZGlyZWN0b3J5OiA8cHJlPiAgIHtAY29kZQorICogICBGaWxlIGRleE91dHB1dERpciA9IGNvbnRleHQuZ2V0RGlyKCJkZXgiLCAwKTsKKyAqIH08L3ByZT4KKyAqCisgKiA8cD48c3Ryb25nPkRvIG5vdCBjYWNoZSBvcHRpbWl6ZWQgY2xhc3NlcyBvbiBleHRlcm5hbCBzdG9yYWdlLjwvc3Ryb25nPgorICogRXh0ZXJuYWwgc3RvcmFnZSBkb2VzIG5vdCBwcm92aWRlIGFjY2VzcyBjb250cm9scyBuZWNlc3NhcnkgdG8gcHJvdGVjdCB5b3VyCisgKiBhcHBsaWNhdGlvbiBmcm9tIGNvZGUgaW5qZWN0aW9uIGF0dGFja3MuCisgKi8KK3B1YmxpYyBjbGFzcyBEZXhDbGFzc0xvYWRlciBleHRlbmRzIEJhc2VEZXhDbGFzc0xvYWRlciB7CisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHtAY29kZSBEZXhDbGFzc0xvYWRlcn0gdGhhdCBmaW5kcyBpbnRlcnByZXRlZCBhbmQgbmF0aXZlCisgICAgICogY29kZS4gIEludGVycHJldGVkIGNsYXNzZXMgYXJlIGZvdW5kIGluIGEgc2V0IG9mIERFWCBmaWxlcyBjb250YWluZWQKKyAgICAgKiBpbiBKYXIgb3IgQVBLIGZpbGVzLgorICAgICAqCisgICAgICogPHA+VGhlIHBhdGggbGlzdHMgYXJlIHNlcGFyYXRlZCB1c2luZyB0aGUgY2hhcmFjdGVyIHNwZWNpZmllZCBieSB0aGUKKyAgICAgKiB7QGNvZGUgcGF0aC5zZXBhcmF0b3J9IHN5c3RlbSBwcm9wZXJ0eSwgd2hpY2ggZGVmYXVsdHMgdG8ge0Bjb2RlIDp9LgorICAgICAqCisgICAgICogQHBhcmFtIGRleFBhdGggdGhlIGxpc3Qgb2YgamFyL2FwayBmaWxlcyBjb250YWluaW5nIGNsYXNzZXMgYW5kCisgICAgICogICAgIHJlc291cmNlcywgZGVsaW1pdGVkIGJ5IHtAY29kZSBGaWxlLnBhdGhTZXBhcmF0b3J9LCB3aGljaAorICAgICAqICAgICBkZWZhdWx0cyB0byB7QGNvZGUgIjoifSBvbiBBbmRyb2lkCisgICAgICogQHBhcmFtIG9wdGltaXplZERpcmVjdG9yeSBkaXJlY3Rvcnkgd2hlcmUgb3B0aW1pemVkIGRleCBmaWxlcworICAgICAqICAgICBzaG91bGQgYmUgd3JpdHRlbjsgbXVzdCBub3QgYmUge0Bjb2RlIG51bGx9CisgICAgICogQHBhcmFtIGxpYnJhcnlQYXRoIHRoZSBsaXN0IG9mIGRpcmVjdG9yaWVzIGNvbnRhaW5pbmcgbmF0aXZlCisgICAgICogICAgIGxpYnJhcmllcywgZGVsaW1pdGVkIGJ5IHtAY29kZSBGaWxlLnBhdGhTZXBhcmF0b3J9OyBtYXkgYmUKKyAgICAgKiAgICAge0Bjb2RlIG51bGx9CisgICAgICogQHBhcmFtIHBhcmVudCB0aGUgcGFyZW50IGNsYXNzIGxvYWRlcgorICAgICAqLworICAgIHB1YmxpYyBEZXhDbGFzc0xvYWRlcihTdHJpbmcgZGV4UGF0aCwgU3RyaW5nIG9wdGltaXplZERpcmVjdG9yeSwKKyAgICAgICAgICAgIFN0cmluZyBsaWJyYXJ5UGF0aCwgQ2xhc3NMb2FkZXIgcGFyZW50KSB7CisgICAgICAgIHN1cGVyKGRleFBhdGgsIG5ldyBGaWxlKG9wdGltaXplZERpcmVjdG9yeSksIGxpYnJhcnlQYXRoLCBwYXJlbnQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vRGV4RmlsZS5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9EZXhGaWxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGMzZTA2MwotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vRGV4RmlsZS5qYXZhCkBAIC0wLDAgKzEsMjg2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBkYWx2aWsuc3lzdGVtOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworCisvKioKKyAqIE1hbmlwdWxhdGVzIERFWCBmaWxlcy4gVGhlIGNsYXNzIGlzIHNpbWlsYXIgaW4gcHJpbmNpcGxlIHRvCisgKiB7QGxpbmsgamF2YS51dGlsLnppcC5aaXBGaWxlfS4gSXQgaXMgdXNlZCBwcmltYXJpbHkgYnkgY2xhc3MgbG9hZGVycy4KKyAqIDxwPgorICogTm90ZSB3ZSBkb24ndCBkaXJlY3RseSBvcGVuIGFuZCByZWFkIHRoZSBERVggZmlsZSBoZXJlLiBUaGV5J3JlIG1lbW9yeS1tYXBwZWQKKyAqIHJlYWQtb25seSBieSB0aGUgVk0uCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBEZXhGaWxlIHsKKyAgICBwcml2YXRlIGludCBtQ29va2llOworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG1GaWxlTmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIENsb3NlR3VhcmQgZ3VhcmQgPSBDbG9zZUd1YXJkLmdldCgpOworCisgICAgLyoqCisgICAgICogT3BlbnMgYSBERVggZmlsZSBmcm9tIGEgZ2l2ZW4gRmlsZSBvYmplY3QuIFRoaXMgd2lsbCB1c3VhbGx5IGJlIGEgWklQL0pBUgorICAgICAqIGZpbGUgd2l0aCBhICJjbGFzc2VzLmRleCIgaW5zaWRlLgorICAgICAqCisgICAgICogVGhlIFZNIHdpbGwgZ2VuZXJhdGUgdGhlIG5hbWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZmlsZSBpbgorICAgICAqIC9kYXRhL2RhbHZpay1jYWNoZSBhbmQgb3BlbiBpdCwgcG9zc2libHkgY3JlYXRpbmcgb3IgdXBkYXRpbmcKKyAgICAgKiBpdCBmaXJzdCBpZiBzeXN0ZW0gcGVybWlzc2lvbnMgYWxsb3cuICBEb24ndCBwYXNzIGluIHRoZSBuYW1lIG9mCisgICAgICogYSBmaWxlIGluIC9kYXRhL2RhbHZpay1jYWNoZSwgYXMgdGhlIG5hbWVkIGZpbGUgaXMgZXhwZWN0ZWQgdG8gYmUKKyAgICAgKiBpbiBpdHMgb3JpZ2luYWwgKHByZS1kZXhvcHQpIHN0YXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBGaWxlIG9iamVjdCByZWZlcmVuY2luZyB0aGUgYWN0dWFsIERFWCBmaWxlCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycywgc3VjaCBhcyB0aGUgZmlsZSBub3QgYmVpbmcgZm91bmQgb3IKKyAgICAgKiAgICAgICAgICAgICBhY2Nlc3MgcmlnaHRzIG1pc3NpbmcgZm9yIG9wZW5pbmcgaXQKKyAgICAgKi8KKyAgICBwdWJsaWMgRGV4RmlsZShGaWxlIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoZmlsZS5nZXRQYXRoKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE9wZW5zIGEgREVYIGZpbGUgZnJvbSBhIGdpdmVuIGZpbGVuYW1lLiBUaGlzIHdpbGwgdXN1YWxseSBiZSBhIFpJUC9KQVIKKyAgICAgKiBmaWxlIHdpdGggYSAiY2xhc3Nlcy5kZXgiIGluc2lkZS4KKyAgICAgKgorICAgICAqIFRoZSBWTSB3aWxsIGdlbmVyYXRlIHRoZSBuYW1lIG9mIHRoZSBjb3JyZXNwb25kaW5nIGZpbGUgaW4KKyAgICAgKiAvZGF0YS9kYWx2aWstY2FjaGUgYW5kIG9wZW4gaXQsIHBvc3NpYmx5IGNyZWF0aW5nIG9yIHVwZGF0aW5nCisgICAgICogaXQgZmlyc3QgaWYgc3lzdGVtIHBlcm1pc3Npb25zIGFsbG93LiAgRG9uJ3QgcGFzcyBpbiB0aGUgbmFtZSBvZgorICAgICAqIGEgZmlsZSBpbiAvZGF0YS9kYWx2aWstY2FjaGUsIGFzIHRoZSBuYW1lZCBmaWxlIGlzIGV4cGVjdGVkIHRvIGJlCisgICAgICogaW4gaXRzIG9yaWdpbmFsIChwcmUtZGV4b3B0KSBzdGF0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGZpbGVuYW1lIG9mIHRoZSBERVggZmlsZQorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMsIHN1Y2ggYXMgdGhlIGZpbGUgbm90IGJlaW5nIGZvdW5kIG9yCisgICAgICogICAgICAgICAgICAgYWNjZXNzIHJpZ2h0cyBtaXNzaW5nIGZvciBvcGVuaW5nIGl0CisgICAgICovCisgICAgcHVibGljIERleEZpbGUoU3RyaW5nIGZpbGVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBtQ29va2llID0gb3BlbkRleEZpbGUoZmlsZU5hbWUsIG51bGwsIDApOworICAgICAgICBtRmlsZU5hbWUgPSBmaWxlTmFtZTsKKyAgICAgICAgZ3VhcmQub3BlbigiY2xvc2UiKTsKKyAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oIkRFWCBGSUxFIGNvb2tpZSBpcyAiICsgbUNvb2tpZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3BlbnMgYSBERVggZmlsZSBmcm9tIGEgZ2l2ZW4gZmlsZW5hbWUsIHVzaW5nIGEgc3BlY2lmaWVkIGZpbGUKKyAgICAgKiB0byBob2xkIHRoZSBvcHRpbWl6ZWQgZGF0YS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzb3VyY2VOYW1lCisgICAgICogIEphciBvciBBUEsgZmlsZSB3aXRoICJjbGFzc2VzLmRleCIuCisgICAgICogQHBhcmFtIG91dHB1dE5hbWUKKyAgICAgKiAgRmlsZSB0aGF0IHdpbGwgaG9sZCB0aGUgb3B0aW1pemVkIGZvcm0gb2YgdGhlIERFWCBkYXRhLgorICAgICAqIEBwYXJhbSBmbGFncworICAgICAqICBFbmFibGUgb3B0aW9uYWwgZmVhdHVyZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBEZXhGaWxlKFN0cmluZyBzb3VyY2VOYW1lLCBTdHJpbmcgb3V0cHV0TmFtZSwgaW50IGZsYWdzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBtQ29va2llID0gb3BlbkRleEZpbGUoc291cmNlTmFtZSwgb3V0cHV0TmFtZSwgZmxhZ3MpOworICAgICAgICBtRmlsZU5hbWUgPSBzb3VyY2VOYW1lOworICAgICAgICBndWFyZC5vcGVuKCJjbG9zZSIpOworICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigiREVYIEZJTEUgY29va2llIGlzICIgKyBtQ29va2llKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPcGVuIGEgREVYIGZpbGUsIHNwZWNpZnlpbmcgdGhlIGZpbGUgaW4gd2hpY2ggdGhlIG9wdGltaXplZCBERVgKKyAgICAgKiBkYXRhIHNob3VsZCBiZSB3cml0dGVuLiAgSWYgdGhlIG9wdGltaXplZCBmb3JtIGV4aXN0cyBhbmQgYXBwZWFycworICAgICAqIHRvIGJlIGN1cnJlbnQsIGl0IHdpbGwgYmUgdXNlZDsgaWYgbm90LCB0aGUgVk0gd2lsbCBhdHRlbXB0IHRvCisgICAgICogcmVnZW5lcmF0ZSBpdC4KKyAgICAgKgorICAgICAqIFRoaXMgaXMgaW50ZW5kZWQgZm9yIHVzZSBieSBhcHBsaWNhdGlvbnMgdGhhdCB3aXNoIHRvIGRvd25sb2FkCisgICAgICogYW5kIGV4ZWN1dGUgREVYIGZpbGVzIG91dHNpZGUgdGhlIHVzdWFsIGFwcGxpY2F0aW9uIGluc3RhbGxhdGlvbgorICAgICAqIG1lY2hhbmlzbS4gIFRoaXMgZnVuY3Rpb24gc2hvdWxkIG5vdCBiZSBjYWxsZWQgZGlyZWN0bHkgYnkgYW4KKyAgICAgKiBhcHBsaWNhdGlvbjsgaW5zdGVhZCwgdXNlIGEgY2xhc3MgbG9hZGVyIHN1Y2ggYXMKKyAgICAgKiBkYWx2aWsuc3lzdGVtLkRleENsYXNzTG9hZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZVBhdGhOYW1lCisgICAgICogIEphciBvciBBUEsgZmlsZSB3aXRoICJjbGFzc2VzLmRleCIuICAoTWF5IGV4cGFuZCB0aGlzIHRvIGluY2x1ZGUKKyAgICAgKiAgInJhdyBERVgiIGluIHRoZSBmdXR1cmUuKQorICAgICAqIEBwYXJhbSBvdXRwdXRQYXRoTmFtZQorICAgICAqICBGaWxlIHRoYXQgd2lsbCBob2xkIHRoZSBvcHRpbWl6ZWQgZm9ybSBvZiB0aGUgREVYIGRhdGEuCisgICAgICogQHBhcmFtIGZsYWdzCisgICAgICogIEVuYWJsZSBvcHRpb25hbCBmZWF0dXJlcy4gIChDdXJyZW50bHkgbm9uZSBkZWZpbmVkLikKKyAgICAgKiBAcmV0dXJuCisgICAgICogIEEgbmV3IG9yIHByZXZpb3VzbHktb3BlbmVkIERleEZpbGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICBJZiB1bmFibGUgdG8gb3BlbiB0aGUgc291cmNlIG9yIG91dHB1dCBmaWxlLgorICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgRGV4RmlsZSBsb2FkRGV4KFN0cmluZyBzb3VyY2VQYXRoTmFtZSwgU3RyaW5nIG91dHB1dFBhdGhOYW1lLAorICAgICAgICBpbnQgZmxhZ3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVE9ETzogd2UgbWF5IHdhbnQgdG8gY2FjaGUgcHJldmlvdXNseS1vcGVuZWQgRGV4RmlsZSBvYmplY3RzLgorICAgICAgICAgKiBUaGUgY2FjaGUgd291bGQgYmUgc3luY2hyb25pemVkIHdpdGggY2xvc2UoKS4gIFRoaXMgd291bGQgaGVscAorICAgICAgICAgKiB1cyBhdm9pZCBtYXBwaW5nIHRoZSBzYW1lIERFWCBtb3JlIHRoYW4gb25jZSB3aGVuIGFuIGFwcAorICAgICAgICAgKiBkZWNpZGVkIHRvIG9wZW4gaXQgbXVsdGlwbGUgdGltZXMuICBJbiBwcmFjdGljZSB0aGlzIG1heSBub3QKKyAgICAgICAgICogYmUgYSByZWFsIGlzc3VlLgorICAgICAgICAgKi8KKyAgICAgICAgcmV0dXJuIG5ldyBEZXhGaWxlKHNvdXJjZVBhdGhOYW1lLCBvdXRwdXRQYXRoTmFtZSwgZmxhZ3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWUgb2YgdGhlIChhbHJlYWR5IG9wZW5lZCkgREVYIGZpbGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBmaWxlIG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBtRmlsZU5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoZSBERVggZmlsZS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1heSBub3QgYmUgYWJsZSB0byByZWxlYXNlIGFueSByZXNvdXJjZXMuIElmIGNsYXNzZXMgZnJvbSB0aGlzCisgICAgICogREVYIGZpbGUgYXJlIHN0aWxsIHJlc2lkZW50LCB0aGUgREVYIGZpbGUgY2FuJ3QgYmUgdW5tYXBwZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyBkdXJpbmcgY2xvc2luZyB0aGUgZmlsZSwgd2hpY2gKKyAgICAgKiAgICAgICAgICAgICBub3JtYWxseSBzaG91bGQgbm90IGhhcHBlbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZ3VhcmQuY2xvc2UoKTsKKyAgICAgICAgY2xvc2VEZXhGaWxlKG1Db29raWUpOworICAgICAgICBtQ29va2llID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2FkcyBhIGNsYXNzLiBSZXR1cm5zIHRoZSBjbGFzcyBvbiBzdWNjZXNzLCBvciBhIHtAY29kZSBudWxsfSByZWZlcmVuY2UKKyAgICAgKiBvbiBmYWlsdXJlLgorICAgICAqIDxwPgorICAgICAqIElmIHlvdSBhcmUgbm90IGNhbGxpbmcgdGhpcyBmcm9tIGEgY2xhc3MgbG9hZGVyLCB0aGlzIGlzIG1vc3QgbGlrZWx5IG5vdAorICAgICAqIGdvaW5nIHRvIGRvIHdoYXQgeW91IHdhbnQuIFVzZSB7QGxpbmsgQ2xhc3MjZm9yTmFtZShTdHJpbmcpfSBpbnN0ZWFkLgorICAgICAqIDxwPgorICAgICAqIFRoZSBtZXRob2QgZG9lcyBub3QgdGhyb3cge0BsaW5rIENsYXNzTm90Rm91bmRFeGNlcHRpb259IGlmIHRoZSBjbGFzcworICAgICAqIGlzbid0IGZvdW5kIGJlY2F1c2UgaXQgaXNuJ3QgcmVhc29uYWJsZSB0byB0aHJvdyBleGNlcHRpb25zIHdpbGRseSBldmVyeQorICAgICAqIHRpbWUgYSBjbGFzcyBpcyBub3QgZm91bmQgaW4gdGhlIGZpcnN0IERFWCBmaWxlIHdlIGxvb2sgYXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGNsYXNzIG5hbWUsIHdoaWNoIHNob3VsZCBsb29rIGxpa2UgImphdmEvbGFuZy9TdHJpbmciCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9hZGVyCisgICAgICogICAgICAgICAgICB0aGUgY2xhc3MgbG9hZGVyIHRoYXQgdHJpZXMgdG8gbG9hZCB0aGUgY2xhc3MgKGluIG1vc3QgY2FzZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYWxsZXIgb2YgdGhlIG1ldGhvZAorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0BsaW5rIENsYXNzfSBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBjbGFzcywgb3Ige0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpZiB0aGUgY2xhc3MgY2Fubm90IGJlIGxvYWRlZAorICAgICAqLworICAgIHB1YmxpYyBDbGFzcyBsb2FkQ2xhc3MoU3RyaW5nIG5hbWUsIENsYXNzTG9hZGVyIGxvYWRlcikgeworICAgICAgICBTdHJpbmcgc2xhc2hOYW1lID0gbmFtZS5yZXBsYWNlKCcuJywgJy8nKTsKKyAgICAgICAgcmV0dXJuIGxvYWRDbGFzc0JpbmFyeU5hbWUoc2xhc2hOYW1lLCBsb2FkZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlZSB7QGxpbmsgI2xvYWRDbGFzcyhTdHJpbmcsIENsYXNzTG9hZGVyKX0uCisgICAgICoKKyAgICAgKiBUaGlzIHRha2VzIGEgImJpbmFyeSIgY2xhc3MgbmFtZSB0byBiZXR0ZXIgbWF0Y2ggQ2xhc3NMb2FkZXIgc2VtYW50aWNzLgorICAgICAqCisgICAgICogQGhpZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xhc3MgbG9hZENsYXNzQmluYXJ5TmFtZShTdHJpbmcgbmFtZSwgQ2xhc3NMb2FkZXIgbG9hZGVyKSB7CisgICAgICAgIHJldHVybiBkZWZpbmVDbGFzcyhuYW1lLCBsb2FkZXIsIG1Db29raWUpOworICAgIH0KKworICAgIHByaXZhdGUgbmF0aXZlIHN0YXRpYyBDbGFzcyBkZWZpbmVDbGFzcyhTdHJpbmcgbmFtZSwgQ2xhc3NMb2FkZXIgbG9hZGVyLCBpbnQgY29va2llKTsKKworICAgIC8qKgorICAgICAqIEVudW1lcmF0ZSB0aGUgbmFtZXMgb2YgdGhlIGNsYXNzZXMgaW4gdGhpcyBERVggZmlsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gZW51bWVyYXRpb24gb2YgbmFtZXMgb2YgY2xhc3NlcyBjb250YWluZWQgaW4gdGhlIERFWCBmaWxlLCBpbgorICAgICAqICAgICAgICAgdGhlIHVzdWFsIGludGVybmFsIGZvcm0gKGxpa2UgImphdmEvbGFuZy9TdHJpbmciKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBlbnRyaWVzKCkgeworICAgICAgICByZXR1cm4gbmV3IERGRW51bSh0aGlzKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEhlbHBlciBjbGFzcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGNsYXNzIERGRW51bSBpbXBsZW1lbnRzIEVudW1lcmF0aW9uPFN0cmluZz4geworICAgICAgICBwcml2YXRlIGludCBtSW5kZXg7CisgICAgICAgIHByaXZhdGUgU3RyaW5nW10gbU5hbWVMaXN0OworCisgICAgICAgIERGRW51bShEZXhGaWxlIGRmKSB7CisgICAgICAgICAgICBtSW5kZXggPSAwOworICAgICAgICAgICAgbU5hbWVMaXN0ID0gZ2V0Q2xhc3NOYW1lTGlzdChtQ29va2llKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc01vcmVFbGVtZW50cygpIHsKKyAgICAgICAgICAgIHJldHVybiAobUluZGV4IDwgbU5hbWVMaXN0Lmxlbmd0aCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIG5leHRFbGVtZW50KCkgeworICAgICAgICAgICAgcmV0dXJuIG1OYW1lTGlzdFttSW5kZXgrK107CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKiByZXR1cm4gYSBTdHJpbmcgYXJyYXkgd2l0aCBjbGFzcyBuYW1lcyAqLworICAgIG5hdGl2ZSBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBnZXRDbGFzc05hbWVMaXN0KGludCBjb29raWUpOworCisgICAgLyoqCisgICAgICogQ2FsbGVkIHdoZW4gdGhlIGNsYXNzIGlzIGZpbmFsaXplZC4gTWFrZXMgc3VyZSB0aGUgREVYIGZpbGUgaXMgY2xvc2VkLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgZHVyaW5nIGNsb3NpbmcgdGhlIGZpbGUsIHdoaWNoCisgICAgICogICAgICAgICAgICAgbm9ybWFsbHkgc2hvdWxkIG5vdCBoYXBwZW4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChndWFyZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZ3VhcmQud2FybklmT3BlbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2xvc2UoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHN1cGVyLmZpbmFsaXplKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIE9wZW4gYSBERVggZmlsZS4gIFRoZSB2YWx1ZSByZXR1cm5lZCBpcyBhIG1hZ2ljIFZNIGNvb2tpZS4gIE9uCisgICAgICogZmFpbHVyZSwgYW4gSU9FeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqLworICAgIG5hdGl2ZSBwcml2YXRlIHN0YXRpYyBpbnQgb3BlbkRleEZpbGUoU3RyaW5nIHNvdXJjZU5hbWUsIFN0cmluZyBvdXRwdXROYW1lLAorICAgICAgICBpbnQgZmxhZ3MpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qCisgICAgICogT3BlbiBhIERFWCBmaWxlIGJhc2VkIG9uIGEge0Bjb2RlIGJ5dGVbXX0uIFRoZSB2YWx1ZSByZXR1cm5lZAorICAgICAqIGlzIGEgbWFnaWMgVk0gY29va2llLiBPbiBmYWlsdXJlLCBhIFJ1bnRpbWVFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqLworICAgIG5hdGl2ZSBwcml2YXRlIHN0YXRpYyBpbnQgb3BlbkRleEZpbGUoYnl0ZVtdIGZpbGVDb250ZW50cyk7CisKKyAgICAvKgorICAgICAqIENsb3NlIERFWCBmaWxlLgorICAgICAqLworICAgIG5hdGl2ZSBwcml2YXRlIHN0YXRpYyB2b2lkIGNsb3NlRGV4RmlsZShpbnQgY29va2llKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgVk0gYmVsaWV2ZXMgdGhhdCB0aGUgYXBrL2phciBmaWxlIGlzIG91dCBvZiBkYXRlCisgICAgICogYW5kIHNob3VsZCBiZSBwYXNzZWQgdGhyb3VnaCAiZGV4b3B0IiBhZ2Fpbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlTmFtZSB0aGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgYXBrL2phciBmaWxlIHRvIGV4YW1pbmUuCisgICAgICogQHJldHVybiB0cnVlIGlmIGRleG9wdCBzaG91bGQgYmUgY2FsbGVkIG9uIHRoZSBmaWxlLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBpZiBmaWxlTmFtZSBpcyBub3QgcmVhZGFibGUsCisgICAgICogICAgICAgICBub3QgYSBmaWxlLCBvciBub3QgcHJlc2VudC4KKyAgICAgKiBAdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gaWYgZmlsZU5hbWUgaXMgbm90IGEgdmFsaWQgYXBrL2phciBmaWxlIG9yCisgICAgICogICAgICAgICBpZiBwcm9ibGVtcyBvY2N1ciB3aGlsZSBwYXJzaW5nIGl0LgorICAgICAqIEB0aHJvd3MgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGZpbGVOYW1lIGlzIG51bGwuCisgICAgICogQHRocm93cyBkYWx2aWsuc3lzdGVtLlN0YWxlRGV4Q2FjaGVFcnJvciBpZiB0aGUgb3B0aW1pemVkIGRleCBmaWxlCisgICAgICogICAgICAgICBpcyBzdGFsZSBidXQgZXhpc3RzIG9uIGEgcmVhZC1vbmx5IHBhcnRpdGlvbi4KKyAgICAgKi8KKyAgICBuYXRpdmUgcHVibGljIHN0YXRpYyBib29sZWFuIGlzRGV4T3B0TmVlZGVkKFN0cmluZyBmaWxlTmFtZSkKKyAgICAgICAgICAgIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24sIElPRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9EZXhQYXRoTGlzdC5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9EZXhQYXRoTGlzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEyNTMyMjMKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL0RleFBhdGhMaXN0LmphdmEKQEAgLTAsMCArMSw0MjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5zeXN0ZW07CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEZpbGU7CisKKy8qKgorICogQSBwYWlyIG9mIGxpc3RzIG9mIGVudHJpZXMsIGFzc29jaWF0ZWQgd2l0aCBhIHtAY29kZSBDbGFzc0xvYWRlcn0uCisgKiBPbmUgb2YgdGhlIGxpc3RzIGlzIGEgZGV4L3Jlc291cmNlIHBhdGggJm1kYXNoOyB0eXBpY2FsbHkgcmVmZXJyZWQKKyAqIHRvIGFzIGEgImNsYXNzIHBhdGgiICZtZGFzaDsgbGlzdCwgYW5kIHRoZSBvdGhlciBuYW1lcyBkaXJlY3RvcmllcworICogY29udGFpbmluZyBuYXRpdmUgY29kZSBsaWJyYXJpZXMuIENsYXNzIHBhdGggZW50cmllcyBtYXkgYmUgYW55IG9mOgorICogYSB7QGNvZGUgLmphcn0gb3Ige0Bjb2RlIC56aXB9IGZpbGUgY29udGFpbmluZyBhbiBvcHRpb25hbAorICogdG9wLWxldmVsIHtAY29kZSBjbGFzc2VzLmRleH0gZmlsZSBhcyB3ZWxsIGFzIGFyYml0cmFyeSByZXNvdXJjZXMsCisgKiBvciBhIHBsYWluIHtAY29kZSAuZGV4fSBmaWxlICh3aXRoIG5vIHBvc3NpYmlsaXR5IG9mIGFzc29jaWF0ZWQKKyAqIHJlc291cmNlcykuCisgKgorICogPHA+VGhpcyBjbGFzcyBhbHNvIGNvbnRhaW5zIG1ldGhvZHMgdG8gdXNlIHRoZXNlIGxpc3RzIHRvIGxvb2sgdXAKKyAqIGNsYXNzZXMgYW5kIHJlc291cmNlcy48L3A+CisgKi8KKy8qcGFja2FnZSovIGZpbmFsIGNsYXNzIERleFBhdGhMaXN0IHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVYX1NVRkZJWCA9ICIuZGV4IjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFSX1NVRkZJWCA9ICIuamFyIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWklQX1NVRkZJWCA9ICIuemlwIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVBLX1NVRkZJWCA9ICIuYXBrIjsKKworICAgIC8qKiBjbGFzcyBkZWZpbml0aW9uIGNvbnRleHQgKi8KKyAgICBwcml2YXRlIGZpbmFsIENsYXNzTG9hZGVyIGRlZmluaW5nQ29udGV4dDsKKworICAgIC8qKiBsaXN0IG9mIGRleC9yZXNvdXJjZSAoY2xhc3MgcGF0aCkgZWxlbWVudHMgKi8KKyAgICBwcml2YXRlIGZpbmFsIEVsZW1lbnRbXSBkZXhFbGVtZW50czsKKworICAgIC8qKiBsaXN0IG9mIG5hdGl2ZSBsaWJyYXJ5IGRpcmVjdG9yeSBlbGVtZW50cyAqLworICAgIHByaXZhdGUgZmluYWwgRmlsZVtdIG5hdGl2ZUxpYnJhcnlEaXJlY3RvcmllczsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGVmaW5pbmdDb250ZXh0IHRoZSBjb250ZXh0IGluIHdoaWNoIGFueSBhcy15ZXQgdW5yZXNvbHZlZAorICAgICAqIGNsYXNzZXMgc2hvdWxkIGJlIGRlZmluZWQKKyAgICAgKiBAcGFyYW0gZGV4UGF0aCBsaXN0IG9mIGRleC9yZXNvdXJjZSBwYXRoIGVsZW1lbnRzLCBzZXBhcmF0ZWQgYnkKKyAgICAgKiB7QGNvZGUgRmlsZS5wYXRoU2VwYXJhdG9yfQorICAgICAqIEBwYXJhbSBsaWJyYXJ5UGF0aCBsaXN0IG9mIG5hdGl2ZSBsaWJyYXJ5IGRpcmVjdG9yeSBwYXRoIGVsZW1lbnRzLAorICAgICAqIHNlcGFyYXRlZCBieSB7QGNvZGUgRmlsZS5wYXRoU2VwYXJhdG9yfQorICAgICAqIEBwYXJhbSBvcHRpbWl6ZWREaXJlY3RvcnkgZGlyZWN0b3J5IHdoZXJlIG9wdGltaXplZCB7QGNvZGUgLmRleH0gZmlsZXMKKyAgICAgKiBzaG91bGQgYmUgZm91bmQgYW5kIHdyaXR0ZW4gdG8sIG9yIHtAY29kZSBudWxsfSB0byB1c2UgdGhlIGRlZmF1bHQKKyAgICAgKiBzeXN0ZW0gZGlyZWN0b3J5IGZvciBzYW1lCisgICAgICovCisgICAgcHVibGljIERleFBhdGhMaXN0KENsYXNzTG9hZGVyIGRlZmluaW5nQ29udGV4dCwgU3RyaW5nIGRleFBhdGgsCisgICAgICAgICAgICBTdHJpbmcgbGlicmFyeVBhdGgsIEZpbGUgb3B0aW1pemVkRGlyZWN0b3J5KSB7CisgICAgICAgIGlmIChkZWZpbmluZ0NvbnRleHQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJkZWZpbmluZ0NvbnRleHQgPT0gbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGRleFBhdGggPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJkZXhQYXRoID09IG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChvcHRpbWl6ZWREaXJlY3RvcnkgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKCFvcHRpbWl6ZWREaXJlY3RvcnkuZXhpc3RzKCkpICB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICJvcHRpbWl6ZWREaXJlY3RvcnkgZG9lc24ndCBleGlzdDogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBvcHRpbWl6ZWREaXJlY3RvcnkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoIShvcHRpbWl6ZWREaXJlY3RvcnkuY2FuUmVhZCgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgb3B0aW1pemVkRGlyZWN0b3J5LmNhbldyaXRlKCkpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICJvcHRpbWl6ZWREaXJlY3Rvcnkgbm90IHJlYWRhYmxlL3dyaXRhYmxlOiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIG9wdGltaXplZERpcmVjdG9yeSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0aGlzLmRlZmluaW5nQ29udGV4dCA9IGRlZmluaW5nQ29udGV4dDsKKyAgICAgICAgdGhpcy5kZXhFbGVtZW50cyA9CisgICAgICAgICAgICBtYWtlRGV4RWxlbWVudHMoc3BsaXREZXhQYXRoKGRleFBhdGgpLCBvcHRpbWl6ZWREaXJlY3RvcnkpOworICAgICAgICB0aGlzLm5hdGl2ZUxpYnJhcnlEaXJlY3RvcmllcyA9IHNwbGl0TGlicmFyeVBhdGgobGlicmFyeVBhdGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNwbGl0cyB0aGUgZ2l2ZW4gZGV4IHBhdGggc3RyaW5nIGludG8gZWxlbWVudHMgdXNpbmcgdGhlIHBhdGgKKyAgICAgKiBzZXBhcmF0b3IsIHBydW5pbmcgb3V0IGFueSBlbGVtZW50cyB0aGF0IGRvIG5vdCByZWZlciB0byBleGlzdGluZworICAgICAqIGFuZCByZWFkYWJsZSBmaWxlcy4gKFRoYXQgaXMsIGRpcmVjdG9yaWVzIGFyZSBub3QgaW5jbHVkZWQgaW4gdGhlCisgICAgICogcmVzdWx0LikKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBBcnJheUxpc3Q8RmlsZT4gc3BsaXREZXhQYXRoKFN0cmluZyBwYXRoKSB7CisgICAgICAgIHJldHVybiBzcGxpdFBhdGhzKHBhdGgsIG51bGwsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGxpdHMgdGhlIGdpdmVuIGxpYnJhcnkgZGlyZWN0b3J5IHBhdGggc3RyaW5nIGludG8gZWxlbWVudHMKKyAgICAgKiB1c2luZyB0aGUgcGF0aCBzZXBhcmF0b3IgKHtAY29kZSBGaWxlLnBhdGhTZXBhcmF0b3J9LCB3aGljaAorICAgICAqIGRlZmF1bHRzIHRvIHtAY29kZSAiOiJ9IG9uIEFuZHJvaWQsIGFwcGVuZGluZyBvbiB0aGUgZWxlbWVudHMKKyAgICAgKiBmcm9tIHRoZSBzeXN0ZW0gbGlicmFyeSBwYXRoLCBhbmQgcHJ1bmluZyBvdXQgYW55IGVsZW1lbnRzIHRoYXQKKyAgICAgKiBkbyBub3QgcmVmZXIgdG8gZXhpc3RpbmcgYW5kIHJlYWRhYmxlIGRpcmVjdG9yaWVzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIEZpbGVbXSBzcGxpdExpYnJhcnlQYXRoKFN0cmluZyBwYXRoKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIE5hdGl2ZSBsaWJyYXJpZXMgbWF5IGV4aXN0IGluIGJvdGggdGhlIHN5c3RlbSBhbmQKKyAgICAgICAgICogYXBwbGljYXRpb24gbGlicmFyeSBwYXRocywgYW5kIHdlIHVzZSB0aGlzIHNlYXJjaCBvcmRlcjoKKyAgICAgICAgICoKKyAgICAgICAgICogICAxLiB0aGlzIGNsYXNzIGxvYWRlcidzIGxpYnJhcnkgcGF0aCBmb3IgYXBwbGljYXRpb24KKyAgICAgICAgICogICAgICBsaWJyYXJpZXMKKyAgICAgICAgICogICAyLiB0aGUgVk0ncyBsaWJyYXJ5IHBhdGggZnJvbSB0aGUgc3lzdGVtCisgICAgICAgICAqICAgICAgcHJvcGVydHkgZm9yIHN5c3RlbSBsaWJyYXJpZXMKKyAgICAgICAgICoKKyAgICAgICAgICogVGhpcyBvcmRlciB3YXMgcmV2ZXJzZWQgcHJpb3IgdG8gR2luZ2VyYnJlYWQ7IHNlZSBodHRwOi8vYi8yOTMzNDU2LgorICAgICAgICAgKi8KKyAgICAgICAgQXJyYXlMaXN0PEZpbGU+IHJlc3VsdCA9IHNwbGl0UGF0aHMoCisgICAgICAgICAgICAgICAgcGF0aCwgU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmxpYnJhcnkucGF0aCIsICIuIiksIHRydWUpOworICAgICAgICByZXR1cm4gcmVzdWx0LnRvQXJyYXkobmV3IEZpbGVbcmVzdWx0LnNpemUoKV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNwbGl0cyB0aGUgZ2l2ZW4gcGF0aCBzdHJpbmdzIGludG8gZmlsZSBlbGVtZW50cyB1c2luZyB0aGUgcGF0aAorICAgICAqIHNlcGFyYXRvciwgY29tYmluaW5nIHRoZSByZXN1bHRzIGFuZCBmaWx0ZXJpbmcgb3V0IGVsZW1lbnRzCisgICAgICogdGhhdCBkb24ndCBleGlzdCwgYXJlbid0IHJlYWRhYmxlLCBvciBhcmVuJ3QgZWl0aGVyIGEgcmVndWxhcgorICAgICAqIGZpbGUgb3IgYSBkaXJlY3RvcnkgKGFzIHNwZWNpZmllZCkuIEVpdGhlciBzdHJpbmcgbWF5IGJlIGVtcHR5CisgICAgICogb3Ige0Bjb2RlIG51bGx9LCBpbiB3aGljaCBjYXNlIGl0IGlzIGlnbm9yZWQuIElmIGJvdGggc3RyaW5ncworICAgICAqIGFyZSBlbXB0eSBvciB7QGNvZGUgbnVsbH0sIG9yIGFsbCBlbGVtZW50cyBnZXQgcHJ1bmVkIG91dCwgdGhlbgorICAgICAqIHRoaXMgcmV0dXJucyBhIHplcm8tZWxlbWVudCBsaXN0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIEFycmF5TGlzdDxGaWxlPiBzcGxpdFBhdGhzKFN0cmluZyBwYXRoMSwgU3RyaW5nIHBhdGgyLAorICAgICAgICAgICAgYm9vbGVhbiB3YW50RGlyZWN0b3JpZXMpIHsKKyAgICAgICAgQXJyYXlMaXN0PEZpbGU+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8RmlsZT4oKTsKKworICAgICAgICBzcGxpdEFuZEFkZChwYXRoMSwgd2FudERpcmVjdG9yaWVzLCByZXN1bHQpOworICAgICAgICBzcGxpdEFuZEFkZChwYXRoMiwgd2FudERpcmVjdG9yaWVzLCByZXN1bHQpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEhlbHBlciBmb3Ige0BsaW5rICNzcGxpdFBhdGhzfSwgd2hpY2ggZG9lcyB0aGUgYWN0dWFsIHNwbGl0dGluZworICAgICAqIGFuZCBmaWx0ZXJpbmcgYW5kIGFkZGluZyB0byBhIHJlc3VsdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHNwbGl0QW5kQWRkKFN0cmluZyBwYXRoLCBib29sZWFuIHdhbnREaXJlY3RvcmllcywKKyAgICAgICAgICAgIEFycmF5TGlzdDxGaWxlPiByZXN1bHRMaXN0KSB7CisgICAgICAgIGlmIChwYXRoID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ1tdIHN0cmluZ3MgPSBwYXRoLnNwbGl0KFBhdHRlcm4ucXVvdGUoRmlsZS5wYXRoU2VwYXJhdG9yKSk7CisKKyAgICAgICAgZm9yIChTdHJpbmcgcyA6IHN0cmluZ3MpIHsKKyAgICAgICAgICAgIEZpbGUgZmlsZSA9IG5ldyBGaWxlKHMpOworCisgICAgICAgICAgICBpZiAoISAoZmlsZS5leGlzdHMoKSAmJiBmaWxlLmNhblJlYWQoKSkpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIE5vdGU6IFRoZXJlIGFyZSBvdGhlciBlbnRpdGllcyBpbiBmaWxlc3lzdGVtcyB0aGFuCisgICAgICAgICAgICAgKiByZWd1bGFyIGZpbGVzIGFuZCBkaXJlY3Rvcmllcy4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaWYgKHdhbnREaXJlY3RvcmllcykgeworICAgICAgICAgICAgICAgIGlmICghZmlsZS5pc0RpcmVjdG9yeSgpKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKCFmaWxlLmlzRmlsZSgpKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmVzdWx0TGlzdC5hZGQoZmlsZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYWtlcyBhbiBhcnJheSBvZiBkZXgvcmVzb3VyY2UgcGF0aCBlbGVtZW50cywgb25lIHBlciBlbGVtZW50IG9mCisgICAgICogdGhlIGdpdmVuIGFycmF5LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIEVsZW1lbnRbXSBtYWtlRGV4RWxlbWVudHMoQXJyYXlMaXN0PEZpbGU+IGZpbGVzLAorICAgICAgICAgICAgRmlsZSBvcHRpbWl6ZWREaXJlY3RvcnkpIHsKKyAgICAgICAgQXJyYXlMaXN0PEVsZW1lbnQ+IGVsZW1lbnRzID0gbmV3IEFycmF5TGlzdDxFbGVtZW50PigpOworCisgICAgICAgIC8qCisgICAgICAgICAqIE9wZW4gYWxsIGZpbGVzIGFuZCBsb2FkIHRoZSAoZGlyZWN0IG9yIGNvbnRhaW5lZCkgZGV4IGZpbGVzCisgICAgICAgICAqIHVwIGZyb250LgorICAgICAgICAgKi8KKyAgICAgICAgZm9yIChGaWxlIGZpbGUgOiBmaWxlcykgeworICAgICAgICAgICAgWmlwRmlsZSB6aXAgPSBudWxsOworICAgICAgICAgICAgRGV4RmlsZSBkZXggPSBudWxsOworICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBmaWxlLmdldE5hbWUoKTsKKworICAgICAgICAgICAgaWYgKG5hbWUuZW5kc1dpdGgoREVYX1NVRkZJWCkpIHsKKyAgICAgICAgICAgICAgICAvLyBSYXcgZGV4IGZpbGUgKG5vdCBpbnNpZGUgYSB6aXAvamFyKS4KKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBkZXggPSBsb2FkRGV4RmlsZShmaWxlLCBvcHRpbWl6ZWREaXJlY3RvcnkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5sb2dFKCJVbmFibGUgdG8gbG9hZCBkZXggZmlsZTogIiArIGZpbGUsIGV4KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWUuZW5kc1dpdGgoQVBLX1NVRkZJWCkgfHwgbmFtZS5lbmRzV2l0aChKQVJfU1VGRklYKQorICAgICAgICAgICAgICAgICAgICB8fCBuYW1lLmVuZHNXaXRoKFpJUF9TVUZGSVgpKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgemlwID0gbmV3IFppcEZpbGUoZmlsZSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgICAgICogTm90ZTogWmlwRXhjZXB0aW9uIChhIHN1YmNsYXNzIG9mIElPRXhjZXB0aW9uKQorICAgICAgICAgICAgICAgICAgICAgKiBtaWdodCBnZXQgdGhyb3duIGJ5IHRoZSBaaXBGaWxlIGNvbnN0cnVjdG9yCisgICAgICAgICAgICAgICAgICAgICAqIChlLmcuIGlmIHRoZSBmaWxlIGlzbid0IGFjdHVhbGx5IGEgemlwL2phcgorICAgICAgICAgICAgICAgICAgICAgKiBmaWxlKS4KKyAgICAgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5sb2dFKCJVbmFibGUgdG8gb3BlbiB6aXAgZmlsZTogIiArIGZpbGUsIGV4KTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBkZXggPSBsb2FkRGV4RmlsZShmaWxlLCBvcHRpbWl6ZWREaXJlY3RvcnkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgICAgICogSU9FeGNlcHRpb24gbWlnaHQgZ2V0IHRocm93biAibGVnaXRpbWF0ZWx5IiBieQorICAgICAgICAgICAgICAgICAgICAgKiB0aGUgRGV4RmlsZSBjb25zdHJ1Y3RvciBpZiB0aGUgemlwIGZpbGUgdHVybnMKKyAgICAgICAgICAgICAgICAgICAgICogb3V0IHRvIGJlIHJlc291cmNlLW9ubHkgKHRoYXQgaXMsIG5vCisgICAgICAgICAgICAgICAgICAgICAqIGNsYXNzZXMuZGV4IGZpbGUgaW4gaXQpLiBTYWZlIHRvIGp1c3QgaWdub3JlCisgICAgICAgICAgICAgICAgICAgICAqIHRoZSBleGNlcHRpb24gaGVyZSwgYW5kIGxldCBkZXggPT0gbnVsbC4KKyAgICAgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ubG9nVygiVW5rbm93biBmaWxlIHR5cGUgZm9yOiAiICsgZmlsZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICgoemlwICE9IG51bGwpIHx8IChkZXggIT0gbnVsbCkpIHsKKyAgICAgICAgICAgICAgICBlbGVtZW50cy5hZGQobmV3IEVsZW1lbnQoZmlsZSwgemlwLCBkZXgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBlbGVtZW50cy50b0FycmF5KG5ldyBFbGVtZW50W2VsZW1lbnRzLnNpemUoKV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgRGV4RmlsZX0gaW5zdGFuY2UsIGFzIGFwcHJvcHJpYXRlIGRlcGVuZGluZworICAgICAqIG9uIHdoZXRoZXIge0Bjb2RlIG9wdGltaXplZERpcmVjdG9yeX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIERleEZpbGUgbG9hZERleEZpbGUoRmlsZSBmaWxlLCBGaWxlIG9wdGltaXplZERpcmVjdG9yeSkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChvcHRpbWl6ZWREaXJlY3RvcnkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBEZXhGaWxlKGZpbGUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgU3RyaW5nIG9wdGltaXplZFBhdGggPSBvcHRpbWl6ZWRQYXRoRm9yKGZpbGUsIG9wdGltaXplZERpcmVjdG9yeSk7CisgICAgICAgICAgICByZXR1cm4gRGV4RmlsZS5sb2FkRGV4KGZpbGUuZ2V0UGF0aCgpLCBvcHRpbWl6ZWRQYXRoLCAwKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIGEgZGV4L2phciBmaWxlIHBhdGggYW5kIGFuIG91dHB1dCBkaXJlY3RvcnkgdG8gYW4KKyAgICAgKiBvdXRwdXQgZmlsZSBwYXRoIGZvciBhbiBhc3NvY2lhdGVkIG9wdGltaXplZCBkZXggZmlsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgb3B0aW1pemVkUGF0aEZvcihGaWxlIHBhdGgsCisgICAgICAgICAgICBGaWxlIG9wdGltaXplZERpcmVjdG9yeSkgeworICAgICAgICAvKgorICAgICAgICAgKiBHZXQgdGhlIGZpbGVuYW1lIGNvbXBvbmVudCBvZiB0aGUgcGF0aCwgYW5kIHJlcGxhY2UgdGhlCisgICAgICAgICAqIHN1ZmZpeCB3aXRoICIuZGV4IiBpZiB0aGF0J3Mgbm90IGFscmVhZHkgdGhlIHN1ZmZpeC4KKyAgICAgICAgICoKKyAgICAgICAgICogV2UgZG9uJ3Qgd2FudCB0byB1c2UgIi5vZGV4IiwgYmVjYXVzZSB0aGUgYnVpbGQgc3lzdGVtIHVzZXMKKyAgICAgICAgICogdGhhdCBmb3IgZmlsZXMgdGhhdCBhcmUgcGFpcmVkIHdpdGggcmVzb3VyY2Utb25seSBqYXIKKyAgICAgICAgICogZmlsZXMuIElmIHRoZSBWTSBjYW4gYXNzdW1lIHRoYXQgdGhlcmUncyBubyBjbGFzc2VzLmRleCBpbgorICAgICAgICAgKiB0aGUgbWF0Y2hpbmcgamFyLCBpdCBkb2Vzbid0IG5lZWQgdG8gb3BlbiB0aGUgamFyIHRvIGNoZWNrCisgICAgICAgICAqIGZvciB1cGRhdGVkIGRlcGVuZGVuY2llcywgcHJvdmlkaW5nIGEgc2xpZ2h0IHBlcmZvcm1hbmNlCisgICAgICAgICAqIGJvb3N0IGF0IHN0YXJ0dXAuIFRoZSB1c2Ugb2YgIi5kZXgiIGhlcmUgbWF0Y2hlcyB0aGUgdXNlIG9uCisgICAgICAgICAqIGZpbGVzIGluIC9kYXRhL2RhbHZpay1jYWNoZS4KKyAgICAgICAgICovCisgICAgICAgIFN0cmluZyBmaWxlTmFtZSA9IHBhdGguZ2V0TmFtZSgpOworICAgICAgICBpZiAoIWZpbGVOYW1lLmVuZHNXaXRoKERFWF9TVUZGSVgpKSB7CisgICAgICAgICAgICBpbnQgbGFzdERvdCA9IGZpbGVOYW1lLmxhc3RJbmRleE9mKCIuIik7CisgICAgICAgICAgICBpZiAobGFzdERvdCA8IDApIHsKKyAgICAgICAgICAgICAgICBmaWxlTmFtZSArPSBERVhfU1VGRklYOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIobGFzdERvdCArIDQpOworICAgICAgICAgICAgICAgIHNiLmFwcGVuZChmaWxlTmFtZSwgMCwgbGFzdERvdCk7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKERFWF9TVUZGSVgpOworICAgICAgICAgICAgICAgIGZpbGVOYW1lID0gc2IudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEZpbGUgcmVzdWx0ID0gbmV3IEZpbGUob3B0aW1pemVkRGlyZWN0b3J5LCBmaWxlTmFtZSk7CisgICAgICAgIHJldHVybiByZXN1bHQuZ2V0UGF0aCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIHRoZSBuYW1lZCBjbGFzcyBpbiBvbmUgb2YgdGhlIGRleCBmaWxlcyBwb2ludGVkIGF0IGJ5CisgICAgICogdGhpcyBpbnN0YW5jZS4gVGhpcyB3aWxsIGZpbmQgdGhlIG9uZSBpbiB0aGUgZWFybGllc3QgbGlzdGVkCisgICAgICogcGF0aCBlbGVtZW50LiBJZiB0aGUgY2xhc3MgaXMgZm91bmQgYnV0IGhhcyBub3QgeWV0IGJlZW4KKyAgICAgKiBkZWZpbmVkLCB0aGVuIHRoaXMgbWV0aG9kIHdpbGwgZGVmaW5lIGl0IGluIHRoZSBkZWZpbmluZworICAgICAqIGNvbnRleHQgdGhhdCB0aGlzIGluc3RhbmNlIHdhcyBjb25zdHJ1Y3RlZCB3aXRoLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZWQgY2xhc3Mgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZSBjbGFzcyBpcyBub3QKKyAgICAgKiBmb3VuZCBpbiBhbnkgb2YgdGhlIGRleCBmaWxlcworICAgICAqLworICAgIHB1YmxpYyBDbGFzcyBmaW5kQ2xhc3MoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgZm9yIChFbGVtZW50IGVsZW1lbnQgOiBkZXhFbGVtZW50cykgeworICAgICAgICAgICAgRGV4RmlsZSBkZXggPSBlbGVtZW50LmRleEZpbGU7CisKKyAgICAgICAgICAgIGlmIChkZXggIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIENsYXNzIGNsYXp6ID0gZGV4LmxvYWRDbGFzc0JpbmFyeU5hbWUobmFtZSwgZGVmaW5pbmdDb250ZXh0KTsKKyAgICAgICAgICAgICAgICBpZiAoY2xhenogIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2xheno7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgdGhlIG5hbWVkIHJlc291cmNlIGluIG9uZSBvZiB0aGUgemlwL2phciBmaWxlcyBwb2ludGVkIGF0CisgICAgICogYnkgdGhpcyBpbnN0YW5jZS4gVGhpcyB3aWxsIGZpbmQgdGhlIG9uZSBpbiB0aGUgZWFybGllc3QgbGlzdGVkCisgICAgICogcGF0aCBlbGVtZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIFVSTCB0byB0aGUgbmFtZWQgcmVzb3VyY2Ugb3Ige0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqIHJlc291cmNlIGlzIG5vdCBmb3VuZCBpbiBhbnkgb2YgdGhlIHppcC9qYXIgZmlsZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMIGZpbmRSZXNvdXJjZShTdHJpbmcgbmFtZSkgeworICAgICAgICBmb3IgKEVsZW1lbnQgZWxlbWVudCA6IGRleEVsZW1lbnRzKSB7CisgICAgICAgICAgICBVUkwgdXJsID0gZWxlbWVudC5maW5kUmVzb3VyY2UobmFtZSk7CisgICAgICAgICAgICBpZiAodXJsICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdXJsOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgYWxsIHRoZSByZXNvdXJjZXMgd2l0aCB0aGUgZ2l2ZW4gbmFtZSwgcmV0dXJuaW5nIGFuCisgICAgICogZW51bWVyYXRpb24gb2YgdGhlbS4gSWYgdGhlcmUgYXJlIG5vIHJlc291cmNlcyB3aXRoIHRoZSBnaXZlbgorICAgICAqIG5hbWUsIHRoZW4gdGhpcyBtZXRob2QgcmV0dXJucyBhbiBlbXB0eSBlbnVtZXJhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bWVyYXRpb248VVJMPiBmaW5kUmVzb3VyY2VzKFN0cmluZyBuYW1lKSB7CisgICAgICAgIEFycmF5TGlzdDxVUkw+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8VVJMPigpOworCisgICAgICAgIGZvciAoRWxlbWVudCBlbGVtZW50IDogZGV4RWxlbWVudHMpIHsKKyAgICAgICAgICAgIFVSTCB1cmwgPSBlbGVtZW50LmZpbmRSZXNvdXJjZShuYW1lKTsKKyAgICAgICAgICAgIGlmICh1cmwgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQodXJsKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbnVtZXJhdGlvbihyZXN1bHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIHRoZSBuYW1lZCBuYXRpdmUgY29kZSBsaWJyYXJ5IG9uIGFueSBvZiB0aGUgbGlicmFyeQorICAgICAqIGRpcmVjdG9yaWVzIHBvaW50ZWQgYXQgYnkgdGhpcyBpbnN0YW5jZS4gVGhpcyB3aWxsIGZpbmQgdGhlCisgICAgICogb25lIGluIHRoZSBlYXJsaWVzdCBsaXN0ZWQgZGlyZWN0b3J5LCBpZ25vcmluZyBhbnkgdGhhdCBhcmUgbm90CisgICAgICogcmVhZGFibGUgcmVndWxhciBmaWxlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNvbXBsZXRlIHBhdGggdG8gdGhlIGxpYnJhcnkgb3Ige0Bjb2RlIG51bGx9IGlmIG5vCisgICAgICogbGlicmFyeSB3YXMgZm91bmQKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGZpbmRMaWJyYXJ5KFN0cmluZyBsaWJyYXJ5TmFtZSkgeworICAgICAgICBTdHJpbmcgZmlsZU5hbWUgPSBTeXN0ZW0ubWFwTGlicmFyeU5hbWUobGlicmFyeU5hbWUpOworCisgICAgICAgIGZvciAoRmlsZSBkaXJlY3RvcnkgOiBuYXRpdmVMaWJyYXJ5RGlyZWN0b3JpZXMpIHsKKyAgICAgICAgICAgIEZpbGUgZmlsZSA9IG5ldyBGaWxlKGRpcmVjdG9yeSwgZmlsZU5hbWUpOworICAgICAgICAgICAgaWYgKGZpbGUuZXhpc3RzKCkgJiYgZmlsZS5pc0ZpbGUoKSAmJiBmaWxlLmNhblJlYWQoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmaWxlLmdldFBhdGgoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVsZW1lbnQgb2YgdGhlIGRleC9yZXNvdXJjZSBmaWxlIHBhdGgKKyAgICAgKi8KKyAgICAvKnBhY2thZ2UqLyBzdGF0aWMgY2xhc3MgRWxlbWVudCB7CisgICAgICAgIHB1YmxpYyBmaW5hbCBGaWxlIGZpbGU7CisgICAgICAgIHB1YmxpYyBmaW5hbCBaaXBGaWxlIHppcEZpbGU7CisgICAgICAgIHB1YmxpYyBmaW5hbCBEZXhGaWxlIGRleEZpbGU7CisKKyAgICAgICAgcHVibGljIEVsZW1lbnQoRmlsZSBmaWxlLCBaaXBGaWxlIHppcEZpbGUsIERleEZpbGUgZGV4RmlsZSkgeworICAgICAgICAgICAgdGhpcy5maWxlID0gZmlsZTsKKyAgICAgICAgICAgIHRoaXMuemlwRmlsZSA9IHppcEZpbGU7CisgICAgICAgICAgICB0aGlzLmRleEZpbGUgPSBkZXhGaWxlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFVSTCBmaW5kUmVzb3VyY2UoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgIGlmICgoemlwRmlsZSA9PSBudWxsKSB8fCAoemlwRmlsZS5nZXRFbnRyeShuYW1lKSA9PSBudWxsKSkgeworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogRWl0aGVyIHRoaXMgZWxlbWVudCBoYXMgbm8gemlwL2phciBmaWxlIChmaXJzdAorICAgICAgICAgICAgICAgICAqIGNsYXVzZSksIG9yIHRoZSB6aXAvamFyIGZpbGUgZG9lc24ndCBoYXZlIGFuIGVudHJ5CisgICAgICAgICAgICAgICAgICogZm9yIHRoZSBnaXZlbiBuYW1lIChzZWNvbmQgY2xhdXNlKS4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAqIEZpbGUudG9VUkwoKSBpcyBjb21wbGlhbnQgd2l0aCBSRkMgMTczOCBpbgorICAgICAgICAgICAgICAgICAqIGFsd2F5cyBjcmVhdGluZyBhYnNvbHV0ZSBwYXRoIG5hbWVzLiBJZiB3ZQorICAgICAgICAgICAgICAgICAqIGNvbnN0cnVjdCB0aGUgVVJMIGJ5IGNvbmNhdGVuYXRpbmcgc3RyaW5ncywgd2UKKyAgICAgICAgICAgICAgICAgKiBtaWdodCBlbmQgdXAgd2l0aCBpbGxlZ2FsIFVSTHMgZm9yIHJlbGF0aXZlCisgICAgICAgICAgICAgICAgICogbmFtZXMuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVUkwoImphcjoiICsgZmlsZS50b1VSTCgpICsgIiEvIiArIG5hbWUpOworICAgICAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZXgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9OYXRpdmVTdGFydC5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9OYXRpdmVTdGFydC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEzODI4MjMKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL05hdGl2ZVN0YXJ0LmphdmEKQEAgLTAsMCArMSwzOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLnN5c3RlbTsKKworLyoqCisgKiBEdW1teSBjbGFzcyB1c2VkIGR1cmluZyBKTkkgaW5pdGlhbGl6YXRpb24uICBUaGUgSk5JIGZ1bmN0aW9ucyB3YW50CisgKiB0byBiZSBhYmxlIHRvIGNyZWF0ZSBvYmplY3RzLCBhbmQgdGhlIFZNIG5lZWRzIHRvIGRpc2NhcmQgdGhlIHJlZmVyZW5jZXMKKyAqIHdoZW4gdGhlIGZ1bmN0aW9uIHJldHVybnMuICBUaGF0IGdldHMgYSBsaXR0bGUgd2VpcmQgd2hlbiB3ZSdyZQorICogY2FsbGluZyBKTkkgZnVuY3Rpb25zIGZyb20gdGhlIEMgbWFpbigpLCBhbmQgdGhlcmUncyBubyBKYXZhIHN0YWNrIGZyYW1lCisgKiB0byBoaXRjaCB0aGUgcmVmZXJlbmNlcyBvbnRvLgorICoKKyAqIFJhdGhlciB0aGFuIGhhdmluZyBzb21lIHNwZWNpYWwtY2FzZSBjb2RlLCB3ZSBjcmVhdGUgdGhpcyBzaW1wbGUgbGl0dGxlCisgKiBjbGFzcyBhbmQgcHJldGVuZCB0aGF0IGl0IGNhbGxlZCB0aGUgQyBtYWluKCkuCisgKgorICogVGhpcyBhbHNvIGNvbWVzIGluIGhhbmR5IHdoZW4gYSBuYXRpdmUgdGhyZWFkIGF0dGFjaGVzIGl0c2VsZiB3aXRoIHRoZQorICogSk5JIEF0dGFjaEN1cnJlbnRUaHJlYWQgY2FsbC4gIElmIHRoZXkgYXR0YWNoIHRoZSB0aHJlYWQgYW5kIHN0YXJ0CisgKiBjcmVhdGluZyBvYmplY3RzLCB3ZSBuZWVkIGEgZmFrZSBmcmFtZSB0byBzdG9yZSBzdHVmZiBpbi4KKyAqLworY2xhc3MgTmF0aXZlU3RhcnQgeworICAgIHByaXZhdGUgTmF0aXZlU3RhcnQoKSB7fQorCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIHZvaWQgbWFpbihTdHJpbmdbXSBkdW1teSk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgdm9pZCBydW4oKTsKK30KZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vUGF0aENsYXNzTG9hZGVyLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL1BhdGhDbGFzc0xvYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyYzU1ODYKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL1BhdGhDbGFzc0xvYWRlci5qYXZhCkBAIC0wLDAgKzEsNjcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5zeXN0ZW07CisKKy8qKgorICogUHJvdmlkZXMgYSBzaW1wbGUge0BsaW5rIENsYXNzTG9hZGVyfSBpbXBsZW1lbnRhdGlvbiB0aGF0IG9wZXJhdGVzIG9uIGEgbGlzdAorICogb2YgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIGluIHRoZSBsb2NhbCBmaWxlIHN5c3RlbSwgYnV0IGRvZXMgbm90IGF0dGVtcHQgdG8KKyAqIGxvYWQgY2xhc3NlcyBmcm9tIHRoZSBuZXR3b3JrLiBBbmRyb2lkIHVzZXMgdGhpcyBjbGFzcyBmb3IgaXRzIHN5c3RlbSBjbGFzcworICogbG9hZGVyIGFuZCBmb3IgaXRzIGFwcGxpY2F0aW9uIGNsYXNzIGxvYWRlcihzKS4KKyAqLworcHVibGljIGNsYXNzIFBhdGhDbGFzc0xvYWRlciBleHRlbmRzIEJhc2VEZXhDbGFzc0xvYWRlciB7CisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHtAY29kZSBQYXRoQ2xhc3NMb2FkZXJ9IHRoYXQgb3BlcmF0ZXMgb24gYSBnaXZlbiBsaXN0IG9mIGZpbGVzCisgICAgICogYW5kIGRpcmVjdG9yaWVzLiBUaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIGNhbGxpbmcKKyAgICAgKiB7QGxpbmsgI1BhdGhDbGFzc0xvYWRlcihTdHJpbmcsIFN0cmluZywgQ2xhc3NMb2FkZXIpfSB3aXRoIGEKKyAgICAgKiB7QGNvZGUgbnVsbH0gdmFsdWUgZm9yIHRoZSBzZWNvbmQgYXJndW1lbnQgKHNlZSBkZXNjcmlwdGlvbiB0aGVyZSkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV4UGF0aCB0aGUgbGlzdCBvZiBqYXIvYXBrIGZpbGVzIGNvbnRhaW5pbmcgY2xhc3NlcyBhbmQKKyAgICAgKiByZXNvdXJjZXMsIGRlbGltaXRlZCBieSB7QGNvZGUgRmlsZS5wYXRoU2VwYXJhdG9yfSwgd2hpY2gKKyAgICAgKiBkZWZhdWx0cyB0byB7QGNvZGUgIjoifSBvbiBBbmRyb2lkCisgICAgICogQHBhcmFtIHBhcmVudCB0aGUgcGFyZW50IGNsYXNzIGxvYWRlcgorICAgICAqLworICAgIHB1YmxpYyBQYXRoQ2xhc3NMb2FkZXIoU3RyaW5nIGRleFBhdGgsIENsYXNzTG9hZGVyIHBhcmVudCkgeworICAgICAgICBzdXBlcihkZXhQYXRoLCBudWxsLCBudWxsLCBwYXJlbnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgUGF0aENsYXNzTG9hZGVyfSB0aGF0IG9wZXJhdGVzIG9uIHR3byBnaXZlbgorICAgICAqIGxpc3RzIG9mIGZpbGVzIGFuZCBkaXJlY3Rvcmllcy4gVGhlIGVudHJpZXMgb2YgdGhlIGZpcnN0IGxpc3QKKyAgICAgKiBzaG91bGQgYmUgb25lIG9mIHRoZSBmb2xsb3dpbmc6CisgICAgICoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPkpBUi9aSVAvQVBLIGZpbGVzLCBwb3NzaWJseSBjb250YWluaW5nIGEgImNsYXNzZXMuZGV4IiBmaWxlIGFzCisgICAgICogd2VsbCBhcyBhcmJpdHJhcnkgcmVzb3VyY2VzLgorICAgICAqIDxsaT5SYXcgIi5kZXgiIGZpbGVzIChub3QgaW5zaWRlIGEgemlwIGZpbGUpLgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBUaGUgZW50cmllcyBvZiB0aGUgc2Vjb25kIGxpc3Qgc2hvdWxkIGJlIGRpcmVjdG9yaWVzIGNvbnRhaW5pbmcKKyAgICAgKiBuYXRpdmUgbGlicmFyeSBmaWxlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXhQYXRoIHRoZSBsaXN0IG9mIGphci9hcGsgZmlsZXMgY29udGFpbmluZyBjbGFzc2VzIGFuZAorICAgICAqIHJlc291cmNlcywgZGVsaW1pdGVkIGJ5IHtAY29kZSBGaWxlLnBhdGhTZXBhcmF0b3J9LCB3aGljaAorICAgICAqIGRlZmF1bHRzIHRvIHtAY29kZSAiOiJ9IG9uIEFuZHJvaWQKKyAgICAgKiBAcGFyYW0gbGlicmFyeVBhdGggdGhlIGxpc3Qgb2YgZGlyZWN0b3JpZXMgY29udGFpbmluZyBuYXRpdmUKKyAgICAgKiBsaWJyYXJpZXMsIGRlbGltaXRlZCBieSB7QGNvZGUgRmlsZS5wYXRoU2VwYXJhdG9yfTsgbWF5IGJlCisgICAgICoge0Bjb2RlIG51bGx9CisgICAgICogQHBhcmFtIHBhcmVudCB0aGUgcGFyZW50IGNsYXNzIGxvYWRlcgorICAgICAqLworICAgIHB1YmxpYyBQYXRoQ2xhc3NMb2FkZXIoU3RyaW5nIGRleFBhdGgsIFN0cmluZyBsaWJyYXJ5UGF0aCwKKyAgICAgICAgICAgIENsYXNzTG9hZGVyIHBhcmVudCkgeworICAgICAgICBzdXBlcihkZXhQYXRoLCBudWxsLCBsaWJyYXJ5UGF0aCwgcGFyZW50KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL1BvdGVudGlhbERlYWRsb2NrRXJyb3IuamF2YSBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vUG90ZW50aWFsRGVhZGxvY2tFcnJvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdhMThiYjUKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL1BvdGVudGlhbERlYWRsb2NrRXJyb3IuamF2YQpAQCAtMCwwICsxLDQxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBkYWx2aWsuc3lzdGVtOworCisvKioKKyAqIElzIHRocm93biB3aGVuIHRoZSBWTSBpZGVudGlmaWVzIGEgcG90ZW50aWFsIGRlYWRsb2NrLgorICoKKyAqIEBoaWRlCisgKi8KK3B1YmxpYyBjbGFzcyBQb3RlbnRpYWxEZWFkbG9ja0Vycm9yIGV4dGVuZHMgVmlydHVhbE1hY2hpbmVFcnJvciB7CisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBleGNlcHRpb24gaW5zdGFuY2UgYW5kIGluaXRpYWxpemVzIGl0IHdpdGggZGVmYXVsdCB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIFBvdGVudGlhbERlYWRsb2NrRXJyb3IoKSB7CisgICAgICAgIHN1cGVyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBleGNlcHRpb24gaW5zdGFuY2UgYW5kIGluaXRpYWxpemVzIGl0IHdpdGggYSBnaXZlbiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UgdGhlIGVycm9yIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgUG90ZW50aWFsRGVhZGxvY2tFcnJvcihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vU29ja2V0VGFnZ2VyLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL1NvY2tldFRhZ2dlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc1MjQyY2UKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL1NvY2tldFRhZ2dlci5qYXZhCkBAIC0wLDAgKzEsODAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5zeXN0ZW07CisKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRFeGNlcHRpb247CisKKy8qKgorICogQ2FsbGJhY2tzIGZvciBzb2NrZXQgYXNzaWdubWVudCBhbmQgcmVhc3NpZ25tZW50LgorICoKKyAqIEBoaWRlCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTb2NrZXRUYWdnZXIgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgU29ja2V0VGFnZ2VyIHRhZ2dlciA9IG5ldyBTb2NrZXRUYWdnZXIoKSB7CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCB0YWcoRmlsZURlc2NyaXB0b3Igc29ja2V0RGVzY3JpcHRvcikgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7fQorICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgdW50YWcoRmlsZURlc2NyaXB0b3Igc29ja2V0RGVzY3JpcHRvcikgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7fQorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllZCB3aGVuIHtAY29kZSBzb2NrZXREZXNjcmlwdG9yfSBpcyBlaXRoZXIgYXNzaWduZWQgdG8gdGhlIGN1cnJlbnQKKyAgICAgKiB0aHJlYWQuIFRoZSBzb2NrZXQgaXMgZWl0aGVyIG5ld2x5IGNvbm5lY3RlZCBvciByZXVzZWQgZnJvbSBhIGNvbm5lY3Rpb24KKyAgICAgKiBwb29sLiBJbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBtZXRob2Qgc2hvdWxkIGJlIHRocmVhZC1zYWZlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHRhZyhGaWxlRGVzY3JpcHRvciBzb2NrZXREZXNjcmlwdG9yKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogTm90aWZpZWQgd2hlbiB7QGNvZGUgc29ja2V0RGVzY3JpcHRvcn0gaXMgcmVsZWFzZWQgZnJvbSB0aGUgY3VycmVudAorICAgICAqIHRocmVhZCB0byBhIGNvbm5lY3Rpb24gcG9vbC4gSW1wbGVtZW50YXRpb25zIG9mIHRoaXMgbWV0aG9kIHNob3VsZCBiZQorICAgICAqIHRocmVhZC1zYWZlLgorICAgICAqCisgICAgICogPHA+PHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiB0aGlzIG1ldGhvZCB3aWxsIG5vdCBiZSBpbnZva2VkIHdoZW4gdGhlIHNvY2tldAorICAgICAqIGlzIGNsb3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB1bnRhZyhGaWxlRGVzY3JpcHRvciBzb2NrZXREZXNjcmlwdG9yKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uOworCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGFnKFNvY2tldCBzb2NrZXQpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBpZiAoIXNvY2tldC5pc0Nsb3NlZCgpKSB7CisgICAgICAgICAgICB0YWcoc29ja2V0LmdldEZpbGVEZXNjcmlwdG9yJCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHVudGFnKFNvY2tldCBzb2NrZXQpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBpZiAoIXNvY2tldC5pc0Nsb3NlZCgpKSB7CisgICAgICAgICAgICB1bnRhZyhzb2NrZXQuZ2V0RmlsZURlc2NyaXB0b3IkKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGlzIHByb2Nlc3MnIHNvY2tldCB0YWdnZXIgdG8ge0Bjb2RlIHRhZ2dlcn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXQoU29ja2V0VGFnZ2VyIHRhZ2dlcikgeworICAgICAgICBpZiAodGFnZ2VyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidGFnZ2VyID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBTb2NrZXRUYWdnZXIudGFnZ2VyID0gdGFnZ2VyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBwcm9jZXNzIHNvY2tldCB0YWdnZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgU29ja2V0VGFnZ2VyIGdldCgpIHsKKyAgICAgICAgcmV0dXJuIHRhZ2dlcjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL1N0YWxlRGV4Q2FjaGVFcnJvci5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9TdGFsZURleENhY2hlRXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YmRkODZhCi0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9TdGFsZURleENhY2hlRXJyb3IuamF2YQpAQCAtMCwwICsxLDQxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBkYWx2aWsuc3lzdGVtOworCisvKioKKyAqIElzIHRocm93biB3aGVuIHRoZSBWTSBkZXRlcm1pbmVzIHRoYXQgYSBERVggZmlsZSdzIGNhY2hlIGlzIG91dCBvZiBkYXRlLCBhbmQKKyAqIHRoYXQgdGhlcmUgaXMgbm8gd2F5IHRvIHJlY3JlYXRlIGl0LgorICoKKyAqIEBoaWRlCisgKi8KK3B1YmxpYyBjbGFzcyBTdGFsZURleENhY2hlRXJyb3IgZXh0ZW5kcyBWaXJ0dWFsTWFjaGluZUVycm9yIHsKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGV4Y2VwdGlvbiBpbnN0YW5jZSBhbmQgaW5pdGlhbGl6ZXMgaXQgd2l0aCBkZWZhdWx0IHZhbHVlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RhbGVEZXhDYWNoZUVycm9yKCkgeworICAgICAgICBzdXBlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgZXhjZXB0aW9uIGluc3RhbmNlIGFuZCBpbml0aWFsaXplcyBpdCB3aXRoIGEgZ2l2ZW4gbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlIHRoZSBlcnJvciBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIFN0YWxlRGV4Q2FjaGVFcnJvcihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL1RlbXBvcmFyeURpcmVjdG9yeS5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9UZW1wb3JhcnlEaXJlY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZjBmNzU5Ci0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9UZW1wb3JhcnlEaXJlY3RvcnkuamF2YQpAQCAtMCwwICsxLDk3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBkYWx2aWsuc3lzdGVtOworCitpbXBvcnQgamF2YS5pby5GaWxlOworCisvKioKKyAqIFV0aWxpdHkgY2xhc3MgdG8gaGFuZGxlIHRoZSBzZXR1cCBvZiB0aGUgY29yZSBsaWJyYXJ5J3MgY29uY2VwdCBvZgorICogd2hhdCB0aGUgImRlZmF1bHQgdGVtcG9yYXJ5IGRpcmVjdG9yeSIgaXMuIEFwcGxpY2F0aW9uIGNvZGUgbWF5CisgKiBjYWxsIGludG8gdGhpcyBjbGFzcyB3aXRoIGFuIGFwcHJvcHJpYXRlIGJhc2UgZGlyZWN0b3J5IGR1cmluZyBpdHMKKyAqIHN0YXJ0dXAsIGFzIGEgcmVhc29uYWJseSBlYXN5IHdheSB0byBnZXQgdGhlIHN0YW5kYXJkIHByb3BlcnR5CisgKiA8Y29kZT5qYXZhLmlvLnRtcGRpcjwvY29kZT4gdG8gcG9pbnQgYXQgc29tZXRoaW5nIHVzZWZ1bC4KKyAqCisgKiBAaGlkZQorICovCitwdWJsaWMgY2xhc3MgVGVtcG9yYXJ5RGlyZWN0b3J5IHsKKyAgICAvKiogc3lzdGVtIHByb3BlcnR5IG5hbWUgZm9yIHRoZSB0ZW1wb3JhcnkgZGlyZWN0b3J5ICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZID0gImphdmEuaW8udG1wZGlyIjsKKworICAgIC8qKiBmaW5hbCBwYXRoIGNvbXBvbmVudCBuYW1lIGZvciB0aGUgdGVtcG9yYXJ5IGRpcmVjdG9yeSAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQQVRIX05BTUUgPSAidG1wIjsKKworICAgIC8qKiB3aGV0aGVyIGEgdGVtcG9yYXJ5IGRpcmVjdG9yeSBoYXMgYmVlbiBjb25maWd1cmVkIHlldCAqLworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gY29uZmlndXJlZCA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogQ29udmVuaWVuY2UgbWV0aG9kIHdoaWNoIGlzIGVxdWl2YWxlbnQgdG8KKyAgICAgKiA8Y29kZT5zZXR1cERpcmVjdG9yeShuZXcgRmlsZShiYXNlRGlyKSk8L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtIGJhc2VEaXIgdGhlIGJhc2UgZGlyZWN0b3J5IG9mIHRoZSB0ZW1wb3JhcnkgZGlyZWN0b3J5CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldFVwRGlyZWN0b3J5KFN0cmluZyBiYXNlRGlyKSB7CisgICAgICAgIHNldFVwRGlyZWN0b3J5KG5ldyBGaWxlKGJhc2VEaXIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSB0ZW1wb3JhcnkgZGlyZWN0b3J5LCBidXQgb25seSBpZiBvbmUgaXNuJ3QgYWxyZWFkeQorICAgICAqIGRlZmluZWQgZm9yIHRoaXMgcHJvY2VzcywgYW5kIG9ubHkgaWYgaXQgaXMgcG9zc2libGUgKGUuZy4sIHRoZQorICAgICAqIGRpcmVjdG9yeSBhbHJlYWR5IGV4aXN0cyBhbmQgaXMgcmVhZC13cml0ZSwgb3IgdGhlIGRpcmVjdG9yeQorICAgICAqIGNhbiBiZSBjcmVhdGVkKS4gVGhpcyBjYWxsIHdpbGwgZG8gb25lIG9mIHRocmVlIHRoaW5nczoKKyAgICAgKgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+cmV0dXJuIHdpdGhvdXQgZXJyb3IgYW5kIHdpdGhvdXQgZG9pbmcgYW55dGhpbmcsIGlmIGEKKyAgICAgKiBwcmV2aW91cyBjYWxsIHRvIHRoaXMgbWV0aG9kIHN1Y2NlZWRlZDwvbGk+CisgICAgICogPGxpPnJldHVybiB3aXRob3V0IGVycm9yLCBoYXZpbmcgZWl0aGVyIGNyZWF0ZWQgYSB0ZW1wb3JhcnkKKyAgICAgKiBkaXJlY3RvcnkgdW5kZXIgdGhlIGdpdmVuIGJhc2Ugb3IgdmVyaWZpZWQgdGhhdCBzdWNoIGEgZGlyZWN0b3J5CisgICAgICogYWxyZWFkeSBleGlzdHM8L2xpPgorICAgICAqIDxsaT50aHJvdyA8Y29kZT5VbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbjwvY29kZT4gaWYgdGhlCisgICAgICogZGlyZWN0b3J5IGNvdWxkIG5vdCBiZSBjcmVhdGVkIG9yIGFjY2Vzc2VkPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGJhc2VEaXIgdGhlIGJhc2UgZGlyZWN0b3J5IG9mIHRoZSB0ZW1wb3JhcnkgZGlyZWN0b3J5CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRVcERpcmVjdG9yeShGaWxlIGJhc2VEaXIpIHsKKyAgICAgICAgaWYgKGNvbmZpZ3VyZWQpIHsKKyAgICAgICAgICAgIFN5c3RlbS5sb2dFKCJBbHJlYWR5IHNldCB0bzogIiArIFN5c3RlbS5nZXRQcm9wZXJ0eShQUk9QRVJUWSkpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgRmlsZSBkaXIgPSBuZXcgRmlsZShiYXNlRGlyLCBQQVRIX05BTUUpOworICAgICAgICBTdHJpbmcgYWJzb2x1dGUgPSBkaXIuZ2V0QWJzb2x1dGVQYXRoKCk7CisKKyAgICAgICAgaWYgKGRpci5leGlzdHMoKSkgeworICAgICAgICAgICAgaWYgKCFkaXIuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICJOYW1lIGlzIHVzZWQgYnkgYSBub24tZGlyZWN0b3J5IGZpbGU6ICIgKworICAgICAgICAgICAgICAgICAgICAgICAgYWJzb2x1dGUpOworICAgICAgICAgICAgfSBlbHNlIGlmICghKGRpci5jYW5SZWFkKCkgJiYgZGlyLmNhbldyaXRlKCkpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgIkV4aXN0aW5nIGRpcmVjdG9yeSBpcyBub3QgcmVhZGFibGUgYW5kIHdyaXRhYmxlOiAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFic29sdXRlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmICghZGlyLm1rZGlycygpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgIkZhaWxlZCB0byBjcmVhdGUgZGlyZWN0b3J5OiAiICsgYWJzb2x1dGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KFBST1BFUlRZLCBhYnNvbHV0ZSk7CisgICAgICAgIGNvbmZpZ3VyZWQgPSB0cnVlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vVk1EZWJ1Zy5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9WTURlYnVnLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWNlMTQ5YwotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vVk1EZWJ1Zy5qYXZhCkBAIC0wLDAgKzEsMzczIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBkYWx2aWsuc3lzdGVtOworCitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFByb3ZpZGVzIGFjY2VzcyB0byBzb21lIFZNLXNwZWNpZmljIGRlYnVnIGZlYXR1cmVzLiBUaG91Z2ggdGhpcyBjbGFzcyBhbmQKKyAqIG1hbnkgb2YgaXRzIG1lbWJlcnMgYXJlIHB1YmxpYywgdGhpcyBjbGFzcyBpcyBtZWFudCB0byBiZSB3cmFwcGVkIGluIGEgbW9yZQorICogZnJpZW5kbHkgd2F5IGZvciB1c2UgYnkgYXBwbGljYXRpb24gZGV2ZWxvcGVycy4gT24gdGhlIEFuZHJvaWQgcGxhdGZvcm0sIHRoZQorICogcmVjb21tZW5kZWQgd2F5IHRvIGFjY2VzcyB0aGlzIGZ1bmN0aW9uYWxpdHkgaXMgdGhyb3VnaCB0aGUgY2xhc3MKKyAqIDxjb2RlPmFuZHJvaWQub3MuRGVidWc8L2NvZGU+LgorICoKKyAqIEBoaWRlCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBWTURlYnVnIHsKKyAgICAvKioKKyAgICAgKiBTcGVjaWZpZXMgdGhlIGRlZmF1bHQgbWV0aG9kIHRyYWNlIGRhdGEgZmlsZSBuYW1lLgorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgb25seSB1c2VkIGluIG9uZSBwbGFjZSwgd2hpY2ggaXMgdW51c2VkIGFuZCBkZXByZWNhdGVkCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBzdGF0aWMgcHVibGljIGZpbmFsIFN0cmluZyBERUZBVUxUX01FVEhPRF9UUkFDRV9GSUxFX05BTUUgPSAiL3NkY2FyZC9kbXRyYWNlLnRyYWNlIjsKKworICAgIC8qKgorICAgICAqIGZsYWcgZm9yIHN0YXJ0TWV0aG9kVHJhY2luZygpLCB3aGljaCBhZGRzIHRoZSByZXN1bHRzIGZyb20KKyAgICAgKiBzdGFydEFsbG9jQ291bnRpbmcgdG8gdGhlIHRyYWNlIGtleSBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRSQUNFX0NPVU5UX0FMTE9DUyA9IDE7CisKKyAgICAvKiBjb25zdGFudHMgZm9yIGdldEFsbG9jQ291bnQgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgS0lORF9BTExPQ0FURURfT0JKRUNUUyAgICAgPSAxPDwwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBLSU5EX0FMTE9DQVRFRF9CWVRFUyAgICAgICA9IDE8PDE7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEtJTkRfRlJFRURfT0JKRUNUUyAgICAgICAgID0gMTw8MjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgS0lORF9GUkVFRF9CWVRFUyAgICAgICAgICAgPSAxPDwzOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBLSU5EX0dDX0lOVk9DQVRJT05TICAgICAgICA9IDE8PDQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEtJTkRfQ0xBU1NfSU5JVF9DT1VOVCAgICAgID0gMTw8NTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgS0lORF9DTEFTU19JTklUX1RJTUUgICAgICAgPSAxPDw2OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBLSU5EX0VYVF9BTExPQ0FURURfT0JKRUNUUyA9IDE8PDEyOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBLSU5EX0VYVF9BTExPQ0FURURfQllURVMgICA9IDE8PDEzOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBLSU5EX0VYVF9GUkVFRF9PQkpFQ1RTICAgICA9IDE8PDE0OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBLSU5EX0VYVF9GUkVFRF9CWVRFUyAgICAgICA9IDE8PDE1OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgS0lORF9HTE9CQUxfQUxMT0NBVEVEX09CSkVDVFMgPQorICAgICAgICBLSU5EX0FMTE9DQVRFRF9PQkpFQ1RTOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtJTkRfR0xPQkFMX0FMTE9DQVRFRF9CWVRFUyA9CisgICAgICAgIEtJTkRfQUxMT0NBVEVEX0JZVEVTOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtJTkRfR0xPQkFMX0ZSRUVEX09CSkVDVFMgPQorICAgICAgICBLSU5EX0ZSRUVEX09CSkVDVFM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgS0lORF9HTE9CQUxfRlJFRURfQllURVMgPQorICAgICAgICBLSU5EX0ZSRUVEX0JZVEVTOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtJTkRfR0xPQkFMX0dDX0lOVk9DQVRJT05TID0KKyAgICAgICAgS0lORF9HQ19JTlZPQ0FUSU9OUzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBLSU5EX0dMT0JBTF9DTEFTU19JTklUX0NPVU5UID0KKyAgICAgICAgS0lORF9DTEFTU19JTklUX0NPVU5UOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtJTkRfR0xPQkFMX0NMQVNTX0lOSVRfVElNRSA9CisgICAgICAgIEtJTkRfQ0xBU1NfSU5JVF9USU1FOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtJTkRfR0xPQkFMX0VYVF9BTExPQ0FURURfT0JKRUNUUyA9CisgICAgICAgIEtJTkRfRVhUX0FMTE9DQVRFRF9PQkpFQ1RTOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtJTkRfR0xPQkFMX0VYVF9BTExPQ0FURURfQllURVMgPQorICAgICAgICBLSU5EX0VYVF9BTExPQ0FURURfQllURVM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgS0lORF9HTE9CQUxfRVhUX0ZSRUVEX09CSkVDVFMgPQorICAgICAgICBLSU5EX0VYVF9GUkVFRF9PQkpFQ1RTOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtJTkRfR0xPQkFMX0VYVF9GUkVFRF9CWVRFUyA9CisgICAgICAgIEtJTkRfRVhUX0ZSRUVEX0JZVEVTOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgS0lORF9USFJFQURfQUxMT0NBVEVEX09CSkVDVFMgPQorICAgICAgICBLSU5EX0FMTE9DQVRFRF9PQkpFQ1RTIDw8IDE2OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtJTkRfVEhSRUFEX0FMTE9DQVRFRF9CWVRFUyA9CisgICAgICAgIEtJTkRfQUxMT0NBVEVEX0JZVEVTIDw8IDE2OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtJTkRfVEhSRUFEX0ZSRUVEX09CSkVDVFMgPQorICAgICAgICBLSU5EX0ZSRUVEX09CSkVDVFMgPDwgMTY7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgS0lORF9USFJFQURfRlJFRURfQllURVMgPQorICAgICAgICBLSU5EX0ZSRUVEX0JZVEVTIDw8IDE2OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtJTkRfVEhSRUFEX0dDX0lOVk9DQVRJT05TID0KKyAgICAgICAgS0lORF9HQ19JTlZPQ0FUSU9OUyA8PCAxNjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBLSU5EX1RIUkVBRF9DTEFTU19JTklUX0NPVU5UID0KKyAgICAgICAgS0lORF9DTEFTU19JTklUX0NPVU5UIDw8IDE2OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtJTkRfVEhSRUFEX0NMQVNTX0lOSVRfVElNRSA9CisgICAgICAgIEtJTkRfQ0xBU1NfSU5JVF9USU1FIDw8IDE2OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtJTkRfVEhSRUFEX0VYVF9BTExPQ0FURURfT0JKRUNUUyA9CisgICAgICAgIEtJTkRfRVhUX0FMTE9DQVRFRF9PQkpFQ1RTIDw8IDE2OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtJTkRfVEhSRUFEX0VYVF9BTExPQ0FURURfQllURVMgPQorICAgICAgICBLSU5EX0VYVF9BTExPQ0FURURfQllURVMgPDwgMTY7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgS0lORF9USFJFQURfRVhUX0ZSRUVEX09CSkVDVFMgPQorICAgICAgICBLSU5EX0VYVF9GUkVFRF9PQkpFQ1RTIDw8IDE2OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtJTkRfVEhSRUFEX0VYVF9GUkVFRF9CWVRFUyA9CisgICAgICAgIEtJTkRfRVhUX0ZSRUVEX0JZVEVTIDw8IDE2OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgS0lORF9BTExfQ09VTlRTID0gMHhmZmZmZmZmZjsKKworICAgIC8qIGFsbCBtZXRob2RzIGFyZSBzdGF0aWMgKi8KKyAgICBwcml2YXRlIFZNRGVidWcoKSB7fQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGltZSBzaW5jZSB0aGUgbGFzdCBrbm93biBkZWJ1Z2dlciBhY3Rpdml0eS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHRpbWUgaW4gbWlsbGlzZWNvbmRzLCBvciAtMSBpZiB0aGUgZGVidWdnZXIgaXMgbm90IGNvbm5lY3RlZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGxvbmcgbGFzdERlYnVnZ2VyQWN0aXZpdHkoKTsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgaWYgZGVidWdnaW5nIGlzIGVuYWJsZWQgaW4gdGhpcyBWTS4gIElmIGRlYnVnZ2luZyBpcyBub3QKKyAgICAgKiBlbmFibGVkLCBhIGRlYnVnZ2VyIGNhbm5vdCBiZSBhdHRhY2hlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBkZWJ1Z2dpbmcgaXMgZW5hYmxlZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gaXNEZWJ1Z2dpbmdFbmFibGVkKCk7CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIGlmIGEgZGVidWdnZXIgaXMgY3VycmVudGx5IGF0dGFjaGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0cnVlIGlmIChhbmQgb25seSBpZikgYSBkZWJ1Z2dlciBpcyBjb25uZWN0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIGlzRGVidWdnZXJDb25uZWN0ZWQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2Ygc3RyaW5ncyB0aGF0IGlkZW50aWZ5IFZNIGZlYXR1cmVzLiAgVGhpcyBpcworICAgICAqIHVzZWQgYnkgRERNUyB0byBkZXRlcm1pbmUgd2hhdCBzb3J0cyBvZiBvcGVyYXRpb25zIHRoZSBWTSBjYW4KKyAgICAgKiBwZXJmb3JtLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIFN0cmluZ1tdIGdldFZtRmVhdHVyZUxpc3QoKTsKKworICAgIC8qKgorICAgICAqIFN0YXJ0IG1ldGhvZCB0cmFjaW5nIHdpdGggZGVmYXVsdCBuYW1lLCBzaXplLCBhbmQgd2l0aCA8Y29kZT4wPC9jb2RlPgorICAgICAqIGZsYWdzLgorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgbm90IHVzZWQsIG5vdCBuZWVkZWQKKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzdGFydE1ldGhvZFRyYWNpbmcoKSB7CisgICAgICAgIHN0YXJ0TWV0aG9kVHJhY2luZyhERUZBVUxUX01FVEhPRF9UUkFDRV9GSUxFX05BTUUsIDAsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0YXJ0IG1ldGhvZCB0cmFjaW5nLCBzcGVjaWZ5aW5nIGEgZmlsZSBuYW1lIGFzIHdlbGwgYXMgYSBkZWZhdWx0CisgICAgICogYnVmZmVyIHNpemUuIFNlZSA8YQorICAgICAqIGhyZWY9IntAZG9jUm9vdH1ndWlkZS9kZXZlbG9waW5nL3Rvb2xzL3RyYWNldmlldy5odG1sIj4gUnVubmluZyB0aGUKKyAgICAgKiBUcmFjZXZpZXcgRGVidWdnaW5nIFByb2dyYW08L2E+IGZvciBpbmZvcm1hdGlvbiBhYm91dCByZWFkaW5nCisgICAgICogdHJhY2UgZmlsZXMuCisgICAgICoKKyAgICAgKiA8cD5Zb3UgY2FuIHVzZSBlaXRoZXIgYSBmdWxseSBxdWFsaWZpZWQgcGF0aCBhbmQKKyAgICAgKiBuYW1lLCBvciBqdXN0IGEgbmFtZS4gSWYgb25seSBhIG5hbWUgaXMgc3BlY2lmaWVkLCB0aGUgZmlsZSB3aWxsCisgICAgICogYmUgY3JlYXRlZCB1bmRlciB0aGUgL3NkY2FyZC8gZGlyZWN0b3J5LiBJZiBhIG5hbWUgaXMgbm90IGdpdmVuLAorICAgICAqIHRoZSBkZWZhdWx0IGlzIC9zZGNhcmQvZG10cmFjZS50cmFjZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gdHJhY2VGaWxlTmFtZSBuYW1lIHRvIGdpdmUgdGhlIHRyYWNlIGZpbGUKKyAgICAgKiBAcGFyYW0gYnVmZmVyU2l6ZSB0aGUgbWF4aW11bSBzaXplIG9mIGJvdGggZmlsZXMgY29tYmluZWQuIElmIHBhc3NlZAorICAgICAqIGFzIDxjb2RlPjA8L2NvZGU+LCBpdCBkZWZhdWx0cyB0byA4TUIuCisgICAgICogQHBhcmFtIGZsYWdzIGZsYWdzIHRvIGNvbnRyb2wgbWV0aG9kIHRyYWNpbmcuIFRoZSBvbmx5IG9uZSB0aGF0CisgICAgICogaXMgY3VycmVudGx5IGRlZmluZWQgaXMge0BsaW5rICNUUkFDRV9DT1VOVF9BTExPQ1N9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzdGFydE1ldGhvZFRyYWNpbmcoU3RyaW5nIHRyYWNlRmlsZU5hbWUsCisgICAgICAgIGludCBidWZmZXJTaXplLCBpbnQgZmxhZ3MpIHsKKworICAgICAgICBpZiAodHJhY2VGaWxlTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHN0YXJ0TWV0aG9kVHJhY2luZ05hdGl2ZSh0cmFjZUZpbGVOYW1lLCBudWxsLCBidWZmZXJTaXplLCBmbGFncyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTGlrZSBzdGFydE1ldGhvZFRyYWNpbmcoU3RyaW5nLCBpbnQsIGludCksIGJ1dCB0YWtpbmcgYW4gYWxyZWFkeS1vcGVuZWQKKyAgICAgKiBGaWxlRGVzY3JpcHRvciBpbiB3aGljaCB0aGUgdHJhY2UgaXMgd3JpdHRlbi4gIFRoZSBmaWxlIG5hbWUgaXMgYWxzbworICAgICAqIHN1cHBsaWVkIHNpbXBseSBmb3IgbG9nZ2luZy4gIE1ha2VzIGEgZHVwIG9mIHRoZSBmaWxlIGRlc2NyaXB0b3IuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHN0YXJ0TWV0aG9kVHJhY2luZyhTdHJpbmcgdHJhY2VGaWxlTmFtZSwKKyAgICAgICAgRmlsZURlc2NyaXB0b3IgZmQsIGludCBidWZmZXJTaXplLCBpbnQgZmxhZ3MpCisgICAgeworICAgICAgICBpZiAodHJhY2VGaWxlTmFtZSA9PSBudWxsIHx8IGZkID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgc3RhcnRNZXRob2RUcmFjaW5nTmF0aXZlKHRyYWNlRmlsZU5hbWUsIGZkLCBidWZmZXJTaXplLCBmbGFncyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3RhcnRzIG1ldGhvZCB0cmFjaW5nIHdpdGhvdXQgYSBiYWNraW5nIGZpbGUuICBXaGVuIHN0b3BNZXRob2RUcmFjaW5nCisgICAgICogaXMgY2FsbGVkLCB0aGUgcmVzdWx0IGlzIHNlbnQgZGlyZWN0bHkgdG8gRERNUy4gIChJZiBERE1TIGlzIG5vdAorICAgICAqIGF0dGFjaGVkIHdoZW4gdHJhY2luZyBlbmRzLCB0aGUgcHJvZmlsaW5nIGRhdGEgd2lsbCBiZSBkaXNjYXJkZWQuKQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzdGFydE1ldGhvZFRyYWNpbmdEZG1zKGludCBidWZmZXJTaXplLCBpbnQgZmxhZ3MpIHsKKyAgICAgICAgc3RhcnRNZXRob2RUcmFjaW5nTmF0aXZlKG51bGwsIG51bGwsIGJ1ZmZlclNpemUsIGZsYWdzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbXBsZW1lbnRzIGFsbCBzdGFydE1ldGhvZFRyYWNpbmcgdmFyaWFudHMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIHZvaWQgc3RhcnRNZXRob2RUcmFjaW5nTmF0aXZlKFN0cmluZyB0cmFjZUZpbGVOYW1lLAorICAgICAgICBGaWxlRGVzY3JpcHRvciBmZCwgaW50IGJ1ZmZlclNpemUsIGludCBmbGFncyk7CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmUgd2hldGhlciBtZXRob2QgdHJhY2luZyBpcyBjdXJyZW50bHkgYWN0aXZlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gaXNNZXRob2RUcmFjaW5nQWN0aXZlKCk7CisKKyAgICAvKioKKyAgICAgKiBTdG9wcyBtZXRob2QgdHJhY2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHN0b3BNZXRob2RUcmFjaW5nKCk7CisKKyAgICAvKioKKyAgICAgKiBTdGFydHMgc2VuZGluZyBEYWx2aWsgbWV0aG9kIHRyYWNlIGluZm8gdG8gdGhlIGVtdWxhdG9yLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgc3RhcnRFbXVsYXRvclRyYWNpbmcoKTsKKworICAgIC8qKgorICAgICAqIFN0b3BzIHNlbmRpbmcgRGFsdmlrIG1ldGhvZCB0cmFjZSBpbmZvIHRvIHRoZSBlbXVsYXRvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHN0b3BFbXVsYXRvclRyYWNpbmcoKTsKKworICAgIC8qKgorICAgICAqIEdldCBhbiBpbmRpY2F0aW9uIG9mIHRocmVhZCBDUFUgdXNhZ2UuIFRoZSB2YWx1ZSByZXR1cm5lZCBpbmRpY2F0ZXMgdGhlCisgICAgICogYW1vdW50IG9mIHRpbWUgdGhhdCB0aGUgY3VycmVudCB0aHJlYWQgaGFzIHNwZW50IGV4ZWN1dGluZyBjb2RlIG9yCisgICAgICogd2FpdGluZyBmb3IgY2VydGFpbiB0eXBlcyBvZiBJL08uCisgICAgICogPHA+CisgICAgICogVGhlIHRpbWUgaXMgZXhwcmVzc2VkIGluIG5hbm9zZWNvbmRzLCBhbmQgaXMgb25seSBtZWFuaW5nZnVsIHdoZW4KKyAgICAgKiBjb21wYXJlZCB0byB0aGUgcmVzdWx0IGZyb20gYW4gZWFybGllciBjYWxsLiBOb3RlIHRoYXQgbmFub3NlY29uZAorICAgICAqIHJlc29sdXRpb24gZG9lcyBub3QgaW1wbHkgbmFub3NlY29uZCBhY2N1cmFjeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIENQVSB1c2FnZS4gQSB2YWx1ZSBvZiAtMSBtZWFucyB0aGUgc3lzdGVtIGRvZXMgbm90IHN1cHBvcnQKKyAgICAgKiAgICAgICAgIHRoaXMgZmVhdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBsb25nIHRocmVhZENwdVRpbWVOYW5vcygpOworCisgICAgLyoqCisgICAgICogQ291bnQgdGhlIG51bWJlciBhbmQgYWdncmVnYXRlIHNpemUgb2YgbWVtb3J5IGFsbG9jYXRpb25zIGJldHdlZW4KKyAgICAgKiB0d28gcG9pbnRzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgc3RhcnRBbGxvY0NvdW50aW5nKCk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBzdG9wQWxsb2NDb3VudGluZygpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBnZXRBbGxvY0NvdW50KGludCBraW5kKTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHJlc2V0QWxsb2NDb3VudChpbnQga2luZHMpOworCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgZXhpc3RzIGZvciBiaW5hcnkgY29tcGF0aWJpbGl0eS4gIEl0IHdhcyBwYXJ0IG9mCisgICAgICogdGhlIGFsbG9jYXRpb24gbGltaXRzIEFQSSB3aGljaCB3YXMgcmVtb3ZlZCBpbiBIb25leWNvbWIuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgc3RhdGljIGludCBzZXRBbGxvY2F0aW9uTGltaXQoaW50IGxpbWl0KSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBleGlzdHMgZm9yIGJpbmFyeSBjb21wYXRpYmlsaXR5LiAgSXQgd2FzIHBhcnQgb2YKKyAgICAgKiB0aGUgYWxsb2NhdGlvbiBsaW1pdHMgQVBJIHdoaWNoIHdhcyByZW1vdmVkIGluIEhvbmV5Y29tYi4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBzdGF0aWMgaW50IHNldEdsb2JhbEFsbG9jYXRpb25MaW1pdChpbnQgbGltaXQpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvdW50IHRoZSBudW1iZXIgb2YgaW5zdHJ1Y3Rpb25zIGV4ZWN1dGVkIGJldHdlZW4gdHdvIHBvaW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHN0YXJ0SW5zdHJ1Y3Rpb25Db3VudGluZygpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgc3RvcEluc3RydWN0aW9uQ291bnRpbmcoKTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIGdldEluc3RydWN0aW9uQ291bnQoaW50W10gY291bnRzKTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHJlc2V0SW5zdHJ1Y3Rpb25Db3VudCgpOworCisgICAgLyoqCisgICAgICogRHVtcHMgYSBsaXN0IG9mIGxvYWRlZCBjbGFzcyB0byB0aGUgbG9nIGZpbGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBwcmludExvYWRlZENsYXNzZXMoaW50IGZsYWdzKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBsb2FkZWQgY2xhc3Nlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBsb2FkZWQgY2xhc3NlcworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBnZXRMb2FkZWRDbGFzc0NvdW50KCk7CisKKyAgICAvKioKKyAgICAgKiBEdW1wcyAiaHByb2YiIGRhdGEgdG8gdGhlIHNwZWNpZmllZCBmaWxlLiAgVGhpcyBtYXkgY2F1c2UgYSBHQy4KKyAgICAgKgorICAgICAqIFRoZSBWTSBtYXkgY3JlYXRlIGEgdGVtcG9yYXJ5IGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGVOYW1lIEZ1bGwgcGF0aG5hbWUgb2Ygb3V0cHV0IGZpbGUgKGUuZy4gIi9zZGNhcmQvZHVtcC5ocHJvZiIpLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhlIFZNIHdhcyBidWlsdCB3aXRob3V0CisgICAgICogICAgICAgICBIUFJPRiBzdXBwb3J0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIG9wZW5pbmcgb3Igd3JpdGluZyBmaWxlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZHVtcEhwcm9mRGF0YShTdHJpbmcgZmlsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChmaWxlTmFtZSA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGR1bXBIcHJvZkRhdGEoZmlsZU5hbWUsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbGxlY3RzICJocHJvZiIgaGVhcCBkYXRhIGFuZCBzZW5kcyBpdCB0byBERE1TLiAgVGhpcyBtYXkgY2F1c2UgYSBHQy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhlIFZNIHdhcyBidWlsdCB3aXRob3V0CisgICAgICogICAgICAgICBIUFJPRiBzdXBwb3J0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgZHVtcEhwcm9mRGF0YURkbXMoKTsKKworICAgIC8qKgorICAgICAqIER1bXBzICJocHJvZiIgaGVhcCBkYXRhIHRvIGEgZmlsZSwgYnkgbmFtZSBvciBkZXNjcmlwdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGVOYW1lIE5hbWUgb2Ygb3V0cHV0IGZpbGUuICBJZiBmZCBpcyBub24tbnVsbCwgdGhlCisgICAgICogICAgICAgIGZpbGUgbmFtZSBpcyBvbmx5IHVzZWQgaW4gbG9nIG1lc3NhZ2VzIChhbmQgbWF5IGJlIG51bGwpLgorICAgICAqIEBwYXJhbSBmZCBEZXNjcmlwdG9yIG9mIG9wZW4gZmlsZSB0aGF0IHdpbGwgcmVjZWl2ZSB0aGUgb3V0cHV0LgorICAgICAqICAgICAgICBJZiB0aGlzIGlzIG51bGwsIHRoZSBmaWxlTmFtZSBpcyB1c2VkIGluc3RlYWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBkdW1wSHByb2ZEYXRhKFN0cmluZyBmaWxlTmFtZSwgRmlsZURlc2NyaXB0b3IgZmQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBQcmltZXMgdGhlIHJlZ2lzdGVyIG1hcCBjYWNoZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIGNhY2hlUmVnaXN0ZXJNYXAoU3RyaW5nIGNsYXNzQW5kTWV0aG9kRGVzYyk7CisKKyAgICAvKioKKyAgICAgKiBEdW1wcyB0aGUgY29udGVudHMgb2YgdGhlIFZNIHJlZmVyZW5jZSB0YWJsZXMgKGUuZy4gSk5JIGxvY2FscyBhbmQKKyAgICAgKiBnbG9iYWxzKSB0byB0aGUgbG9nIGZpbGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBkdW1wUmVmZXJlbmNlVGFibGVzKCk7CisKKyAgICAvKioKKyAgICAgKiBDcmFzaGVzIHRoZSBWTS4gIFNlcmlvdXNseS4gIER1bXBzIHRoZSBpbnRlcnByZXRlciBzdGFjayB0cmFjZSBmb3IKKyAgICAgKiB0aGUgY3VycmVudCB0aHJlYWQgYW5kIHRoZW4gYWJvcnRzIHRoZSBWTSBzbyB5b3UgY2FuIHNlZSB0aGUgbmF0aXZlCisgICAgICogc3RhY2sgdHJhY2UuICBVc2VmdWwgZm9yIGZpZ3VyaW5nIG91dCBob3cgeW91IGdvdCBzb21ld2hlcmUgd2hlbgorICAgICAqIGxvdHMgb2YgbmF0aXZlIGNvZGUgaXMgaW52b2x2ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBjcmFzaCgpOworCisgICAgLyoqCisgICAgICogVG9nZXRoZXIgd2l0aCBnZGIsIHByb3ZpZGUgYSBoYW5keSB3YXkgdG8gc3RvcCB0aGUgVk0gYXQgdXNlci10YWdnZWQKKyAgICAgKiBsb2NhdGlvbnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBpbmZvcG9pbnQoaW50IGlkKTsKKworICAgIC8qCisgICAgICogRmFrZSBtZXRob2QsIGluc2VydGVkIGludG8gZG10cmFjZSBvdXRwdXQgd2hlbiB0aGUgZ2FyYmFnZSBjb2xsZWN0b3IKKyAgICAgKiBydW5zLiAgTm90IGFjdHVhbGx5IGNhbGxlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHN0YXJ0R0MoKSB7fQorCisgICAgLyoKKyAgICAgKiBGYWtlIG1ldGhvZCwgaW5zZXJ0ZWQgaW50byBkbXRyYWNlIG91dHB1dCBkdXJpbmcgY2xhc3MgcHJlcGFyYXRpb24KKyAgICAgKiAobG9hZGluZyBhbmQgbGlua2luZywgYnV0IG5vdCB2ZXJpZmljYXRpb24gb3IgaW5pdGlhbGl6YXRpb24pLiAgTm90CisgICAgICogYWN0dWFsbHkgY2FsbGVkLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgc3RhcnRDbGFzc1ByZXAoKSB7fQorCisgICAgLyoqCisgICAgICogQ291bnRzIHRoZSBpbnN0YW5jZXMgb2YgYSBjbGFzcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrbGFzcyB0aGUgY2xhc3MgdG8gYmUgY291bnRlZC4KKyAgICAgKiBAcGFyYW0gYXNzaWduYWJsZSBpZiBmYWxzZSwgZGlyZWN0IGluc3RhbmNlcyBvZiBrbGFzcyBhcmUKKyAgICAgKiAgICAgICAgICAgICAgICAgICBjb3VudGVkLiAgSWYgdHJ1ZSwgaW5zdGFuY2VzIHRoYXQgYXJlCisgICAgICogICAgICAgICAgICAgICAgICAgYXNzaWduYWJsZSB0byBrbGFzcywgYXMgZGVmaW5lZCBieQorICAgICAqICAgICAgICAgICAgICAgICAgIHtAbGluayBDbGFzcyNpc0Fzc2lnbmFibGVGcm9tfSBhcmUgY291bnRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgbWF0Y2hpbmcgaW5zdGFuY2VzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGxvbmcgY291bnRJbnN0YW5jZXNPZkNsYXNzKENsYXNzIGtsYXNzLCBib29sZWFuIGFzc2lnbmFibGUpOworfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9WTVJ1bnRpbWUuamF2YSBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vVk1SdW50aW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzM3MjkwZAotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vVk1SdW50aW1lLmphdmEKQEAgLTAsMCArMSwyMjAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5zeXN0ZW07CisKKy8qKgorICogUHJvdmlkZXMgYW4gaW50ZXJmYWNlIHRvIFZNLWdsb2JhbCwgRGFsdmlrLXNwZWNpZmljIGZlYXR1cmVzLgorICogQW4gYXBwbGljYXRpb24gY2Fubm90IGNyZWF0ZSBpdHMgb3duIFJ1bnRpbWUgaW5zdGFuY2UsIGFuZCBtdXN0IG9idGFpbgorICogb25lIGZyb20gdGhlIGdldFJ1bnRpbWUgbWV0aG9kLgorICoKKyAqIEBoaWRlCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBWTVJ1bnRpbWUgeworCisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIFZNUnVudGltZSBzaW5nbGV0b24uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVk1SdW50aW1lIFRIRV9PTkUgPSBuZXcgVk1SdW50aW1lKCk7CisKKyAgICAvKioKKyAgICAgKiBQcmV2ZW50cyB0aGlzIGNsYXNzIGZyb20gYmVpbmcgaW5zdGFudGlhdGVkLgorICAgICAqLworICAgIHByaXZhdGUgVk1SdW50aW1lKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIFZNIGluc3RhbmNlJ3MgRGFsdmlrLXNwZWNpZmljCisgICAgICogcnVudGltZSBlbnZpcm9ubWVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJ1bnRpbWUgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBWTVJ1bnRpbWUgZ2V0UnVudGltZSgpIHsKKyAgICAgICAgcmV0dXJuIFRIRV9PTkU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhlIFZNJ3MgY29tbWFuZC1saW5lIHByb3BlcnR5IHNldHRpbmdzLgorICAgICAqIFRoZXNlIGFyZSBpbiB0aGUgZm9ybSAibmFtZT12YWx1ZSIgcmF0aGVyIHRoYW4gIi1EbmFtZT12YWx1ZSIuCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSBTdHJpbmdbXSBwcm9wZXJ0aWVzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBWTSdzIGJvb3QgY2xhc3MgcGF0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgbmF0aXZlIFN0cmluZyBib290Q2xhc3NQYXRoKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBWTSdzIGNsYXNzIHBhdGguCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSBTdHJpbmcgY2xhc3NQYXRoKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBWTSdzIHZlcnNpb24uCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSBTdHJpbmcgdm1WZXJzaW9uKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IGlkZWFsIGhlYXAgdXRpbGl6YXRpb24sIHJlcHJlc2VudGVkIGFzIGEgbnVtYmVyCisgICAgICogYmV0d2VlbiB6ZXJvIGFuZCBvbmUuICBBZnRlciBhIEdDIGhhcHBlbnMsIHRoZSBEYWx2aWsgaGVhcCBtYXkKKyAgICAgKiBiZSByZXNpemVkIHNvIHRoYXQgKHNpemUgb2YgbGl2ZSBvYmplY3RzKSAvIChzaXplIG9mIGhlYXApIGlzCisgICAgICogZXF1YWwgdG8gdGhpcyBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IGlkZWFsIGhlYXAgdXRpbGl6YXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgbmF0aXZlIGZsb2F0IGdldFRhcmdldEhlYXBVdGlsaXphdGlvbigpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY3VycmVudCBpZGVhbCBoZWFwIHV0aWxpemF0aW9uLCByZXByZXNlbnRlZCBhcyBhIG51bWJlcgorICAgICAqIGJldHdlZW4gemVybyBhbmQgb25lLiAgQWZ0ZXIgYSBHQyBoYXBwZW5zLCB0aGUgRGFsdmlrIGhlYXAgbWF5CisgICAgICogYmUgcmVzaXplZCBzbyB0aGF0IChzaXplIG9mIGxpdmUgb2JqZWN0cykgLyAoc2l6ZSBvZiBoZWFwKSBpcworICAgICAqIGVxdWFsIHRvIHRoaXMgbnVtYmVyLgorICAgICAqCisgICAgICogPHA+VGhpcyBpcyBvbmx5IGEgaGludCB0byB0aGUgZ2FyYmFnZSBjb2xsZWN0b3IgYW5kIG1heSBiZSBpZ25vcmVkLgorICAgICAqCisgICAgICogQHBhcmFtIG5ld1RhcmdldCB0aGUgbmV3IHN1Z2dlc3RlZCBpZGVhbCBoZWFwIHV0aWxpemF0aW9uLgorICAgICAqICAgICAgICAgICAgICAgICAgVGhpcyB2YWx1ZSBtYXkgYmUgYWRqdXN0ZWQgaW50ZXJuYWxseS4KKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyBpZGVhbCBoZWFwIHV0aWxpemF0aW9uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgbmV3VGFyZ2V0IGlzICZsdDs9IDAuMCBvciAmZ3Q7PSAxLjAKKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgc2V0VGFyZ2V0SGVhcFV0aWxpemF0aW9uKGZsb2F0IG5ld1RhcmdldCkgeworICAgICAgICBpZiAobmV3VGFyZ2V0IDw9IDAuMCB8fCBuZXdUYXJnZXQgPj0gMS4wKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKG5ld1RhcmdldCArCisgICAgICAgICAgICAgICAgICAgICIgb3V0IG9mIHJhbmdlICgwLDEpIik7CisgICAgICAgIH0KKyAgICAgICAgLyogU3luY2hyb25pemUgdG8gbWFrZSBzdXJlIHRoYXQgb25seSBvbmUgdGhyZWFkIGdldHMKKyAgICAgICAgICogYSBnaXZlbiAib2xkIiB2YWx1ZSBpZiBib3RoIHVwZGF0ZSBhdCB0aGUgc2FtZSB0aW1lLgorICAgICAgICAgKiBBbGxvd3MgZm9yIHJlbGlhYmxlIHNhdmUtYW5kLXJlc3RvcmUgc2VtYW50aWNzLgorICAgICAgICAgKi8KKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICBmbG9hdCBvbGRUYXJnZXQgPSBnZXRUYXJnZXRIZWFwVXRpbGl6YXRpb24oKTsKKyAgICAgICAgICAgIG5hdGl2ZVNldFRhcmdldEhlYXBVdGlsaXphdGlvbihuZXdUYXJnZXQpOworICAgICAgICAgICAgcmV0dXJuIG9sZFRhcmdldDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHRhcmdldCBTREsgdmVyc2lvbi4gU2hvdWxkIG9ubHkgYmUgY2FsbGVkIGJlZm9yZSB0aGUKKyAgICAgKiBhcHAgc3RhcnRzIHRvIHJ1biwgYmVjYXVzZSBpdCBtYXkgY2hhbmdlIHRoZSBWTSdzIGJlaGF2aW9yIGluCisgICAgICogZGFuZ2Vyb3VzIHdheXMuIFVzZSAwIHRvIG1lYW4gImN1cnJlbnQiIChzaW5jZSBjYWxsZXJzIHdvbid0CisgICAgICogbmVjZXNzYXJpbHkga25vdyB0aGUgYWN0dWFsIGN1cnJlbnQgU0RLIHZlcnNpb24sIGFuZCB0aGUKKyAgICAgKiBhbGxvY2F0ZWQgdmVyc2lvbiBudW1iZXJzIHN0YXJ0IGF0IDEpLgorICAgICAqLworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCBzZXRUYXJnZXRTZGtWZXJzaW9uKGludCB0YXJnZXRTZGtWZXJzaW9uKTsKKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGV4aXN0cyBmb3IgYmluYXJ5IGNvbXBhdGliaWxpdHkuICBJdCB3YXMgcGFydCBvZiBhCisgICAgICogaGVhcCBzaXppbmcgQVBJIHdoaWNoIHdhcyByZW1vdmVkIGluIEhvbmV5Y29tYi4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBsb25nIGdldE1pbmltdW1IZWFwU2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgZXhpc3RzIGZvciBiaW5hcnkgY29tcGF0aWJpbGl0eS4gIEl0IHdhcyBwYXJ0IG9mIGEKKyAgICAgKiBoZWFwIHNpemluZyBBUEkgd2hpY2ggd2FzIHJlbW92ZWQgaW4gSG9uZXljb21iLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGxvbmcgc2V0TWluaW11bUhlYXBTaXplKGxvbmcgc2l6ZSkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBleGlzdHMgZm9yIGJpbmFyeSBjb21wYXRpYmlsaXR5LiAgSXQgdXNlZCB0bworICAgICAqIHBlcmZvcm0gYSBnYXJiYWdlIGNvbGxlY3Rpb24gdGhhdCBjbGVhcmVkIFNvZnRSZWZlcmVuY2VzLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHZvaWQgZ2NTb2Z0UmVmZXJlbmNlcygpIHt9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBleGlzdHMgZm9yIGJpbmFyeSBjb21wYXRpYmlsaXR5LiAgSXQgaXMgZXF1aXZhbGVudAorICAgICAqIHRvIHtAbGluayBTeXN0ZW0jcnVuRmluYWxpemF0aW9ufS4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyB2b2lkIHJ1bkZpbmFsaXphdGlvblN5bmMoKSB7CisgICAgICAgIFN5c3RlbS5ydW5GaW5hbGl6YXRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbXBsZW1lbnRzIHNldFRhcmdldEhlYXBVdGlsaXphdGlvbigpLgorICAgICAqCisgICAgICogQHBhcmFtIG5ld1RhcmdldCB0aGUgbmV3IHN1Z2dlc3RlZCBpZGVhbCBoZWFwIHV0aWxpemF0aW9uLgorICAgICAqICAgICAgICAgICAgICAgICAgVGhpcyB2YWx1ZSBtYXkgYmUgYWRqdXN0ZWQgaW50ZXJuYWxseS4KKyAgICAgKi8KKyAgICBwcml2YXRlIG5hdGl2ZSB2b2lkIG5hdGl2ZVNldFRhcmdldEhlYXBVdGlsaXphdGlvbihmbG9hdCBuZXdUYXJnZXQpOworCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgZXhpc3RzIGZvciBiaW5hcnkgY29tcGF0aWJpbGl0eS4gIEl0IHdhcyBwYXJ0IG9mCisgICAgICogdGhlIGV4dGVybmFsIGFsbG9jYXRpb24gQVBJIHdoaWNoIHdhcyByZW1vdmVkIGluIEhvbmV5Y29tYi4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBib29sZWFuIHRyYWNrRXh0ZXJuYWxBbGxvY2F0aW9uKGxvbmcgc2l6ZSkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBleGlzdHMgZm9yIGJpbmFyeSBjb21wYXRpYmlsaXR5LiAgSXQgd2FzIHBhcnQgb2YKKyAgICAgKiB0aGUgZXh0ZXJuYWwgYWxsb2NhdGlvbiBBUEkgd2hpY2ggd2FzIHJlbW92ZWQgaW4gSG9uZXljb21iLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHZvaWQgdHJhY2tFeHRlcm5hbEZyZWUobG9uZyBzaXplKSB7fQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgZXhpc3RzIGZvciBiaW5hcnkgY29tcGF0aWJpbGl0eS4gIEl0IHdhcyBwYXJ0IG9mCisgICAgICogdGhlIGV4dGVybmFsIGFsbG9jYXRpb24gQVBJIHdoaWNoIHdhcyByZW1vdmVkIGluIEhvbmV5Y29tYi4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBsb25nIGdldEV4dGVybmFsQnl0ZXNBbGxvY2F0ZWQoKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlbGxzIHRoZSBWTSB0byBlbmFibGUgdGhlIEpJVCBjb21waWxlci4gSWYgdGhlIFZNIGRvZXMgbm90IGhhdmUgYSBKSVQKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiwgY2FsbGluZyB0aGlzIG1ldGhvZCBzaG91bGQgaGF2ZSBubyBlZmZlY3QuCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSB2b2lkIHN0YXJ0Sml0Q29tcGlsYXRpb24oKTsKKworICAgIC8qKgorICAgICAqIFRlbGxzIHRoZSBWTSB0byBkaXNhYmxlIHRoZSBKSVQgY29tcGlsZXIuIElmIHRoZSBWTSBkb2VzIG5vdCBoYXZlIGEgSklUCisgICAgICogaW1wbGVtZW50YXRpb24sIGNhbGxpbmcgdGhpcyBtZXRob2Qgc2hvdWxkIGhhdmUgbm8gZWZmZWN0LgorICAgICAqLworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCBkaXNhYmxlSml0Q29tcGlsYXRpb24oKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgYWxsb2NhdGVkIGluIGFuIGFyZWEgb2YgdGhlIEphdmEgaGVhcCB3aGVyZSBpdCB3aWxsIG5ldmVyIGJlIG1vdmVkLgorICAgICAqIFRoaXMgaXMgdXNlZCB0byBpbXBsZW1lbnQgbmF0aXZlIGFsbG9jYXRpb25zIG9uIHRoZSBKYXZhIGhlYXAsIHN1Y2ggYXMgRGlyZWN0Qnl0ZUJ1ZmZlcnMKKyAgICAgKiBhbmQgQml0bWFwcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgbmF0aXZlIE9iamVjdCBuZXdOb25Nb3ZhYmxlQXJyYXkoQ2xhc3M8Pz4gY29tcG9uZW50VHlwZSwgaW50IGxlbmd0aCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhZGRyZXNzIG9mIGFycmF5WzBdLiBUaGlzIGRpZmZlcnMgZnJvbSB1c2luZyBKTkkgaW4gdGhhdCBKTkkgbWlnaHQgbGllIGFuZAorICAgICAqIGdpdmUgeW91IHRoZSBhZGRyZXNzIG9mIGEgY29weSBvZiB0aGUgYXJyYXkgd2hlbiBpbiBmb3JjZWNvcHkgbW9kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbmF0aXZlIGxvbmcgYWRkcmVzc09mKE9iamVjdCBhcnJheSk7CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGFueSBncm93dGggbGltaXRzLCBhbGxvd2luZyB0aGUgYXBwbGljYXRpb24gdG8gYWxsb2NhdGUKKyAgICAgKiB1cCB0byB0aGUgbWF4aW11bSBoZWFwIHNpemUuCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSB2b2lkIGNsZWFyR3Jvd3RoTGltaXQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiBlaXRoZXIgYSBKYXZhIGRlYnVnZ2VyIG9yIG5hdGl2ZSBkZWJ1Z2dlciBpcyBhY3RpdmUuCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSBib29sZWFuIGlzRGVidWdnZXJBY3RpdmUoKTsKK30KZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vVk1TdGFjay5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9WTVN0YWNrLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWEyYmUyMwotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vVk1TdGFjay5qYXZhCkBAIC0wLDAgKzEsODQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5zeXN0ZW07CisKKy8qKgorICogUHJvdmlkZXMgYSBsaW1pdGVkIGludGVyZmFjZSB0byB0aGUgRGFsdmlrIFZNIHN0YWNrLiBUaGlzIGNsYXNzIGlzIG1vc3RseQorICogdXNlZCBmb3IgaW1wbGVtZW50aW5nIHNlY3VyaXR5IGNoZWNrcy4KKyAqCisgKiBAaGlkZQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgVk1TdGFjayB7CisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGVmaW5pbmcgY2xhc3MgbG9hZGVyIG9mIHRoZSBjYWxsZXIncyBjYWxsZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0ZWQgY2xhc3MgbG9hZGVyLCBvciB7QGNvZGUgbnVsbH0gaWYgdGhpcyBpcyB0aGUKKyAgICAgKiAgICAgICAgIGJvb3RzdHJhcCBjbGFzcyBsb2FkZXIuCisgICAgICovCisgICAgbmF0aXZlIHB1YmxpYyBzdGF0aWMgQ2xhc3NMb2FkZXIgZ2V0Q2FsbGluZ0NsYXNzTG9hZGVyKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbGFzcyBvZiB0aGUgY2FsbGVyJ3MgY2FsbGVyJ3MgY2FsbGVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVxdWVzdGVkIGNsYXNzLCBvciB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgbmF0aXZlIHB1YmxpYyBzdGF0aWMgQ2xhc3M8Pz4gZ2V0U3RhY2tDbGFzczIoKTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgY2xhc3NlcyBmcm9tIHRoZSBtZXRob2RzIGF0IHRoZSB0b3Agb2YgdGhlIHN0YWNrLgorICAgICAqIFdlIGNvbnRpbnVlIHVudGlsIHdlIHJlYWNoIHRoZSBib3R0b20gb2YgdGhlIHN0YWNrIG9yIGV4Y2VlZCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgbWF4aW11bSBkZXB0aC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgdG9wbW9zdCBzdGFjayBmcmFtZSAodGhpcyBtZXRob2QpIGFuZCB0aGUgb25lIGFib3ZlIHRoYXQgKHRoZQorICAgICAqIGNhbGxlcikgYXJlIGV4Y2x1ZGVkIGZyb20gdGhlIGFycmF5LiAgRnJhbWVzIHdpdGggamF2YS5sYW5nLnJlZmxlY3QKKyAgICAgKiBjbGFzc2VzIGFyZSBza2lwcGVkIG92ZXIuCisgICAgICogPHA+CisgICAgICogVGhlIGNsYXNzZXMgaW4gdGhlIGFycmF5IGFyZSB0aGUgZGVmaW5pbmcgY2xhc3NlcyBvZiB0aGUgbWV0aG9kcy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIGlzIHNpbWlsYXIgdG8gSGFybW9ueSdzIFZNU3RhY2suZ2V0Q2xhc3NlcywgZXhjZXB0IHRoYXQgdGhpcworICAgICAqIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgaGF2ZSBhIGNvbmNlcHQgb2YgInByaXZpbGVnZWQiIGZyYW1lcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtYXhEZXB0aAorICAgICAqICAgICAgbWF4aW11bSBudW1iZXIgb2YgY2xhc3NlcyB0byByZXR1cm4sIG9yIC0xIGZvciBhbGwKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IHdpdGggY2xhc3NlcyBmb3IgdGhlIG1vc3QtcmVjZW50IG1ldGhvZHMgb24gdGhlIHN0YWNrCisgICAgICovCisgICAgbmF0aXZlIHB1YmxpYyBzdGF0aWMgQ2xhc3M8Pz5bXSBnZXRDbGFzc2VzKGludCBtYXhEZXB0aCk7CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgdGhlIHN0YWNrIHRyYWNlIGZyb20gdGhlIHNwZWNpZmllZCB0aHJlYWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdAorICAgICAqICAgICAgdGhyZWFkIG9mIGludGVyZXN0CisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBzdGFjayB0cmFjZSBlbGVtZW50cywgb3IgbnVsbCBpZiB0aGUgdGhyZWFkCisgICAgICogICAgICBkb2Vzbid0IGhhdmUgYSBzdGFjayB0cmFjZSAoZS5nLiBiZWNhdXNlIGl0IGV4aXRlZCkKKyAgICAgKi8KKyAgICBuYXRpdmUgcHVibGljIHN0YXRpYyBTdGFja1RyYWNlRWxlbWVudFtdIGdldFRocmVhZFN0YWNrVHJhY2UoVGhyZWFkIHQpOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGEgcGFydGlhbCBzdGFjayB0cmFjZSBmcm9tIHRoZSBzcGVjaWZpZWQgdGhyZWFkIGludG8KKyAgICAgKiB0aGUgcHJvdmlkZWQgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdAorICAgICAqICAgICAgdGhyZWFkIG9mIGludGVyZXN0CisgICAgICogQHBhcmFtIHN0YWNrVHJhY2VFbGVtZW50cworICAgICAqICAgICAgcHJlYWxsb2NhdGVkIGFycmF5IGZvciB1c2Ugd2hlbiBvbmx5IHRoZSB0b3Agb2Ygc3RhY2sgaXMKKyAgICAgKiAgICAgIGRlc2lyZWQuIFVudXNlZCBlbGVtZW50cyB3aWxsIGJlIGZpbGxlZCB3aXRoIG51bGwgdmFsdWVzLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBmaWxsZWQKKyAgICAgKi8KKyAgICBuYXRpdmUgcHVibGljIHN0YXRpYyBpbnQgZmlsbFN0YWNrVHJhY2VFbGVtZW50cyhUaHJlYWQgdCwKKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnRbXSBzdGFja1RyYWNlRWxlbWVudHMpOworfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9aeWdvdGUuamF2YSBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vWnlnb3RlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjhjOTkxMgotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vWnlnb3RlLmphdmEKQEAgLTAsMCArMSwyMTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDYgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5zeXN0ZW07CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CisKKy8qKgorICogUHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBEYWx2aWsgInp5Z290ZSIgZmVhdHVyZSwgd2hpY2ggYWxsb3dzIGEgVk0gaW5zdGFuY2UgdG8KKyAqIGJlIHBhcnRpYWxseSBpbml0aWFsaXplZCBhbmQgdGhlbiBmb3JrKCknZCBmcm9tIHRoZSBwYXJ0aWFsbHkgaW5pdGlhbGl6ZWQKKyAqIHN0YXRlLgorICoKKyAqIEBoaWRlCisgKi8KK3B1YmxpYyBjbGFzcyBaeWdvdGUgeworICAgIC8qCisgICAgICogQml0IHZhbHVlcyBmb3IgImRlYnVnRmxhZ3MiIGFyZ3VtZW50LiAgVGhlIGRlZmluaXRpb25zIGFyZSBkdXBsaWNhdGVkCisgICAgICogaW4gdGhlIG5hdGl2ZSBjb2RlLgorICAgICAqLworICAgIC8qKiBlbmFibGUgZGVidWdnaW5nIG92ZXIgSkRXUCAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFQlVHX0VOQUJMRV9ERUJVR0dFUiAgID0gMTsKKyAgICAvKiogZW5hYmxlIEpOSSBjaGVja3MgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUJVR19FTkFCTEVfQ0hFQ0tKTkkgICA9IDEgPDwgMTsKKyAgICAvKiogZW5hYmxlIEphdmEgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgImFzc2VydCIgc3RhdGVtZW50cyAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFQlVHX0VOQUJMRV9BU1NFUlQgICAgID0gMSA8PCAyOworICAgIC8qKiBkaXNhYmxlIHRoZSBKSVQgY29tcGlsZXIgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUJVR19FTkFCTEVfU0FGRU1PREUgICA9IDEgPDwgMzsKKyAgICAvKiogRW5hYmxlIGxvZ2dpbmcgb2YgdGhpcmQtcGFydHkgSk5JIGFjdGl2aXR5LiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFQlVHX0VOQUJMRV9KTklfTE9HR0lORyA9IDEgPDwgNDsKKworICAgIC8qKgorICAgICAqIFdoZW4gc2V0IGJ5IHRoZSBzeXN0ZW0gc2VydmVyLCBhbGwgc3Vic2VxdWVudCBhcHBzIHdpbGwgYmUgbGF1bmNoZWQgaW4KKyAgICAgKiBWTSBzYWZlIG1vZGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIHN5c3RlbUluU2FmZU1vZGUgPSBmYWxzZTsKKworICAgIHByaXZhdGUgWnlnb3RlKCkge30KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcHJlRm9yaygpIHsKKyAgICAgICAgRGFlbW9ucy5zdG9wKCk7CisgICAgICAgIHdhaXRVbnRpbEFsbFRocmVhZHNTdG9wcGVkKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2UgbXVzdCBub3QgZm9yayB1bnRpbCB3ZSdyZSBzaW5nbGUtdGhyZWFkZWQgYWdhaW4uIFdhaXQgdW50aWwgL3Byb2Mgc2hvd3Mgd2UncmUKKyAgICAgKiBkb3duIHRvIGp1c3Qgb25lIHRocmVhZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHdhaXRVbnRpbEFsbFRocmVhZHNTdG9wcGVkKCkgeworICAgICAgICBGaWxlIHRhc2tzID0gbmV3IEZpbGUoIi9wcm9jL3NlbGYvdGFzayIpOworICAgICAgICB3aGlsZSAodGFza3MubGlzdCgpLmxlbmd0aCA+IDEpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgLy8gRXhwZXJpbWVudGFsbHksIGJvb3RpbmcgYW5kIHBsYXlpbmcgYWJvdXQgd2l0aCBhIHN0aW5ncmF5LCBJIG5ldmVyIHNhdyB1cworICAgICAgICAgICAgICAgIC8vIGdvIHJvdW5kIHRoaXMgbG9vcCBtb3JlIHRoYW4gb25jZSB3aXRoIGEgMTBtcyBzbGVlcC4KKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTApOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwb3N0Rm9yaygpIHsKKyAgICAgICAgRGFlbW9ucy5zdGFydCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZvcmtzIGEgbmV3IFp5Z290ZSBpbnN0YW5jZSwgYnV0IGRvZXMgbm90IGxlYXZlIHRoZSB6eWdvdGUgbW9kZS4KKyAgICAgKiBUaGUgY3VycmVudCBWTSBtdXN0IGhhdmUgYmVlbiBzdGFydGVkIHdpdGggdGhlIC1Yenlnb3RlIGZsYWcuIFRoZQorICAgICAqIG5ldyBjaGlsZCBpcyBleHBlY3RlZCB0byBldmVudHVhbGx5IGNhbGwgZm9ya0FuZFNwZWNpYWxpemUoKQorICAgICAqCisgICAgICogQHJldHVybiAwIGlmIHRoaXMgaXMgdGhlIGNoaWxkLCBwaWQgb2YgdGhlIGNoaWxkCisgICAgICogaWYgdGhpcyBpcyB0aGUgcGFyZW50LCBvciAtMSBvbiBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGZvcmsoKSB7CisgICAgICAgIHByZUZvcmsoKTsKKyAgICAgICAgaW50IHBpZCA9IG5hdGl2ZUZvcmsoKTsKKyAgICAgICAgcG9zdEZvcmsoKTsKKyAgICAgICAgcmV0dXJuIHBpZDsKKyAgICB9CisKKyAgICBuYXRpdmUgcHVibGljIHN0YXRpYyBpbnQgbmF0aXZlRm9yaygpOworCisgICAgLyoqCisgICAgICogRm9ya3MgYSBuZXcgVk0gaW5zdGFuY2UuICBUaGUgY3VycmVudCBWTSBtdXN0IGhhdmUgYmVlbiBzdGFydGVkCisgICAgICogd2l0aCB0aGUgLVh6eWdvdGUgZmxhZy4gPGI+Tk9URTogbmV3IGluc3RhbmNlIGtlZXBzIGFsbAorICAgICAqIHJvb3QgY2FwYWJpbGl0aWVzLiBUaGUgbmV3IHByb2Nlc3MgaXMgZXhwZWN0ZWQgdG8gY2FsbCBjYXBzZXQoKTwvYj4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdWlkIHRoZSBVTklYIHVpZCB0aGF0IHRoZSBuZXcgcHJvY2VzcyBzaG91bGQgc2V0dWlkKCkgdG8gYWZ0ZXIKKyAgICAgKiBmb3JrKClpbmcgYW5kIGFuZCBiZWZvcmUgc3Bhd25pbmcgYW55IHRocmVhZHMuCisgICAgICogQHBhcmFtIGdpZCB0aGUgVU5JWCBnaWQgdGhhdCB0aGUgbmV3IHByb2Nlc3Mgc2hvdWxkIHNldGdpZCgpIHRvIGFmdGVyCisgICAgICogZm9yaygpaW5nIGFuZCBhbmQgYmVmb3JlIHNwYXduaW5nIGFueSB0aHJlYWRzLgorICAgICAqIEBwYXJhbSBnaWRzIG51bGwtb2s7IGEgbGlzdCBvZiBVTklYIGdpZHMgdGhhdCB0aGUgbmV3IHByb2Nlc3Mgc2hvdWxkCisgICAgICogc2V0Z3JvdXBzKCkgdG8gYWZ0ZXIgZm9yayBhbmQgYmVmb3JlIHNwYXduaW5nIGFueSB0aHJlYWRzLgorICAgICAqIEBwYXJhbSBkZWJ1Z0ZsYWdzIGJpdCBmbGFncyB0aGF0IGVuYWJsZSBkZWJ1Z2dpbmcgZmVhdHVyZXMuCisgICAgICogQHBhcmFtIHJsaW1pdHMgbnVsbC1vayBhbiBhcnJheSBvZiBybGltaXQgdHVwbGVzLCB3aXRoIHRoZSBzZWNvbmQKKyAgICAgKiBkaW1lbnNpb24gaGF2aW5nIGEgbGVuZ3RoIG9mIDMgYW5kIHJlcHJlc2VudGluZworICAgICAqIChyZXNvdXJjZSwgcmxpbV9jdXIsIHJsaW1fbWF4KS4gVGhlc2UgYXJlIHNldCB2aWEgdGhlIHBvc2l4CisgICAgICogc2V0cmxpbWl0KDIpIGNhbGwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIDAgaWYgdGhpcyBpcyB0aGUgY2hpbGQsIHBpZCBvZiB0aGUgY2hpbGQKKyAgICAgKiBpZiB0aGlzIGlzIHRoZSBwYXJlbnQsIG9yIC0xIG9uIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGZvcmtBbmRTcGVjaWFsaXplKGludCB1aWQsIGludCBnaWQsIGludFtdIGdpZHMsCisgICAgICAgICAgICBpbnQgZGVidWdGbGFncywgaW50W11bXSBybGltaXRzKSB7CisgICAgICAgIHByZUZvcmsoKTsKKyAgICAgICAgaW50IHBpZCA9IG5hdGl2ZUZvcmtBbmRTcGVjaWFsaXplKHVpZCwgZ2lkLCBnaWRzLCBkZWJ1Z0ZsYWdzLCBybGltaXRzKTsKKyAgICAgICAgcG9zdEZvcmsoKTsKKyAgICAgICAgcmV0dXJuIHBpZDsKKyAgICB9CisKKyAgICBuYXRpdmUgcHVibGljIHN0YXRpYyBpbnQgbmF0aXZlRm9ya0FuZFNwZWNpYWxpemUoaW50IHVpZCwgaW50IGdpZCwKKyAgICAgICAgICAgIGludFtdIGdpZHMsIGludCBkZWJ1Z0ZsYWdzLCBpbnRbXVtdIHJsaW1pdHMpOworCisgICAgLyoqCisgICAgICogRm9ya3MgYSBuZXcgVk0gaW5zdGFuY2UuCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIHtAbGluayBaeWdvdGUjZm9ya0FuZFNwZWNpYWxpemUoaW50LCBpbnQsIGludFtdLCBpbnQsIGludFtdW10pfQorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHN0YXRpYyBpbnQgZm9ya0FuZFNwZWNpYWxpemUoaW50IHVpZCwgaW50IGdpZCwgaW50W10gZ2lkcywKKyAgICAgICAgICAgIGJvb2xlYW4gZW5hYmxlRGVidWdnZXIsIGludFtdW10gcmxpbWl0cykgeworICAgICAgICBpbnQgZGVidWdGbGFncyA9IGVuYWJsZURlYnVnZ2VyID8gREVCVUdfRU5BQkxFX0RFQlVHR0VSIDogMDsKKyAgICAgICAgcmV0dXJuIGZvcmtBbmRTcGVjaWFsaXplKHVpZCwgZ2lkLCBnaWRzLCBkZWJ1Z0ZsYWdzLCBybGltaXRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWFsIG1ldGhvZCB0byBzdGFydCB0aGUgc3lzdGVtIHNlcnZlciBwcm9jZXNzLiBJbiBhZGRpdGlvbiB0byB0aGUKKyAgICAgKiBjb21tb24gYWN0aW9ucyBwZXJmb3JtZWQgaW4gZm9ya0FuZFNwZWNpYWxpemUsIHRoZSBwaWQgb2YgdGhlIGNoaWxkCisgICAgICogcHJvY2VzcyBpcyByZWNvcmRlZCBzdWNoIHRoYXQgdGhlIGRlYXRoIG9mIHRoZSBjaGlsZCBwcm9jZXNzIHdpbGwgY2F1c2UKKyAgICAgKiB6eWdvdGUgdG8gZXhpdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1aWQgdGhlIFVOSVggdWlkIHRoYXQgdGhlIG5ldyBwcm9jZXNzIHNob3VsZCBzZXR1aWQoKSB0byBhZnRlcgorICAgICAqIGZvcmsoKWluZyBhbmQgYW5kIGJlZm9yZSBzcGF3bmluZyBhbnkgdGhyZWFkcy4KKyAgICAgKiBAcGFyYW0gZ2lkIHRoZSBVTklYIGdpZCB0aGF0IHRoZSBuZXcgcHJvY2VzcyBzaG91bGQgc2V0Z2lkKCkgdG8gYWZ0ZXIKKyAgICAgKiBmb3JrKClpbmcgYW5kIGFuZCBiZWZvcmUgc3Bhd25pbmcgYW55IHRocmVhZHMuCisgICAgICogQHBhcmFtIGdpZHMgbnVsbC1vazsgYSBsaXN0IG9mIFVOSVggZ2lkcyB0aGF0IHRoZSBuZXcgcHJvY2VzcyBzaG91bGQKKyAgICAgKiBzZXRncm91cHMoKSB0byBhZnRlciBmb3JrIGFuZCBiZWZvcmUgc3Bhd25pbmcgYW55IHRocmVhZHMuCisgICAgICogQHBhcmFtIGRlYnVnRmxhZ3MgYml0IGZsYWdzIHRoYXQgZW5hYmxlIGRlYnVnZ2luZyBmZWF0dXJlcy4KKyAgICAgKiBAcGFyYW0gcmxpbWl0cyBudWxsLW9rIGFuIGFycmF5IG9mIHJsaW1pdCB0dXBsZXMsIHdpdGggdGhlIHNlY29uZAorICAgICAqIGRpbWVuc2lvbiBoYXZpbmcgYSBsZW5ndGggb2YgMyBhbmQgcmVwcmVzZW50aW5nCisgICAgICogKHJlc291cmNlLCBybGltX2N1ciwgcmxpbV9tYXgpLiBUaGVzZSBhcmUgc2V0IHZpYSB0aGUgcG9zaXgKKyAgICAgKiBzZXRybGltaXQoMikgY2FsbC4KKyAgICAgKiBAcGFyYW0gcGVybWl0dGVkQ2FwYWJpbGl0aWVzIGFyZ3VtZW50IGZvciBzZXRjYXAoKQorICAgICAqIEBwYXJhbSBlZmZlY3RpdmVDYXBhYmlsaXRpZXMgYXJndW1lbnQgZm9yIHNldGNhcCgpCisgICAgICoKKyAgICAgKiBAcmV0dXJuIDAgaWYgdGhpcyBpcyB0aGUgY2hpbGQsIHBpZCBvZiB0aGUgY2hpbGQKKyAgICAgKiBpZiB0aGlzIGlzIHRoZSBwYXJlbnQsIG9yIC0xIG9uIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGZvcmtTeXN0ZW1TZXJ2ZXIoaW50IHVpZCwgaW50IGdpZCwgaW50W10gZ2lkcywKKyAgICAgICAgICAgIGludCBkZWJ1Z0ZsYWdzLCBpbnRbXVtdIHJsaW1pdHMsCisgICAgICAgICAgICBsb25nIHBlcm1pdHRlZENhcGFiaWxpdGllcywgbG9uZyBlZmZlY3RpdmVDYXBhYmlsaXRpZXMpIHsKKyAgICAgICAgcHJlRm9yaygpOworICAgICAgICBpbnQgcGlkID0gbmF0aXZlRm9ya1N5c3RlbVNlcnZlcih1aWQsIGdpZCwgZ2lkcywgZGVidWdGbGFncywgcmxpbWl0cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVybWl0dGVkQ2FwYWJpbGl0aWVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RpdmVDYXBhYmlsaXRpZXMpOworICAgICAgICBwb3N0Rm9yaygpOworICAgICAgICByZXR1cm4gcGlkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNwZWNpYWwgbWV0aG9kIHRvIHN0YXJ0IHRoZSBzeXN0ZW0gc2VydmVyIHByb2Nlc3MuCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIHtAbGluayBaeWdvdGUjZm9ya1N5c3RlbVNlcnZlcihpbnQsIGludCwgaW50W10sIGludCwgaW50W11bXSl9CisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgc3RhdGljIGludCBmb3JrU3lzdGVtU2VydmVyKGludCB1aWQsIGludCBnaWQsIGludFtdIGdpZHMsCisgICAgICAgICAgICBib29sZWFuIGVuYWJsZURlYnVnZ2VyLCBpbnRbXVtdIHJsaW1pdHMpIHsKKyAgICAgICAgaW50IGRlYnVnRmxhZ3MgPSBlbmFibGVEZWJ1Z2dlciA/IERFQlVHX0VOQUJMRV9ERUJVR0dFUiA6IDA7CisgICAgICAgIHJldHVybiBmb3JrQW5kU3BlY2lhbGl6ZSh1aWQsIGdpZCwgZ2lkcywgZGVidWdGbGFncywgcmxpbWl0cyk7CisgICAgfQorCisgICAgbmF0aXZlIHB1YmxpYyBzdGF0aWMgaW50IG5hdGl2ZUZvcmtTeXN0ZW1TZXJ2ZXIoaW50IHVpZCwgaW50IGdpZCwKKyAgICAgICAgICAgIGludFtdIGdpZHMsIGludCBkZWJ1Z0ZsYWdzLCBpbnRbXVtdIHJsaW1pdHMsCisgICAgICAgICAgICBsb25nIHBlcm1pdHRlZENhcGFiaWxpdGllcywgbG9uZyBlZmZlY3RpdmVDYXBhYmlsaXRpZXMpOworCisgICAgLyoqCisgICAgICogRXhlY3V0ZXMgIi9zeXN0ZW0vYmluL3NoIC1jICZsdDtjb21tYW5kJmd0OyIgdXNpbmcgdGhlIGV4ZWMoKSBzeXN0ZW0gY2FsbC4KKyAgICAgKiBUaGlzIG1ldGhvZCBuZXZlciByZXR1cm5zLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbW1hbmQgVGhlIHNoZWxsIGNvbW1hbmQgdG8gZXhlY3V0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZXhlY1NoZWxsKFN0cmluZyBjb21tYW5kKSB7CisgICAgICAgIG5hdGl2ZUV4ZWNTaGVsbChjb21tYW5kKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHF1b3RlcyBzaGVsbCBhcmd1bWVudHMgdG8gdGhlIHNwZWNpZmllZCBzdHJpbmcgYnVpbGRlci4KKyAgICAgKiBUaGUgYXJndW1lbnRzIGFyZSBxdW90ZWQgdXNpbmcgc2luZ2xlLXF1b3RlcywgZXNjYXBlZCBpZiBuZWNlc3NhcnksCisgICAgICogcHJlZml4ZWQgd2l0aCBhIHNwYWNlLCBhbmQgYXBwZW5kZWQgdG8gdGhlIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29tbWFuZCBBIHN0cmluZyBidWlsZGVyIGZvciB0aGUgc2hlbGwgY29tbWFuZCBiZWluZyBjb25zdHJ1Y3RlZC4KKyAgICAgKiBAcGFyYW0gYXJncyBBbiBhcnJheSBvZiBhcmd1bWVudCBzdHJpbmdzIHRvIGJlIHF1b3RlZCBhbmQgYXBwZW5kZWQgdG8gdGhlIGNvbW1hbmQuCisgICAgICogQHNlZSAjZXhlY1NoZWxsKFN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYXBwZW5kUXVvdGVkU2hlbGxBcmdzKFN0cmluZ0J1aWxkZXIgY29tbWFuZCwgU3RyaW5nW10gYXJncykgeworICAgICAgICBmb3IgKFN0cmluZyBhcmcgOiBhcmdzKSB7CisgICAgICAgICAgICBjb21tYW5kLmFwcGVuZCgiICciKS5hcHBlbmQoYXJnLnJlcGxhY2UoIiciLCAiJ1xcJyciKSkuYXBwZW5kKCInIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBuYXRpdmUgcHJpdmF0ZSBzdGF0aWMgdm9pZCBuYXRpdmVFeGVjU2hlbGwoU3RyaW5nIGNvbW1hbmQpOworfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9wYWNrYWdlLmh0bWwgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMWQwZDMwCi0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSw3IEBACis8aHRtbD4KKyAgPGJvZHk+CisgICAgPHA+CisgICAgICBQcm92aWRlcyB1dGlsaXR5IGFuZCBzeXN0ZW0gaW5mb3JtYXRpb24gY2xhc3NlcyBzcGVjaWZpYyB0byB0aGUgRGFsdmlrIFZNLgorICAgIDwvcD4KKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9wcm9maWxlci9Bc2NpaUhwcm9mV3JpdGVyLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL3Byb2ZpbGVyL0FzY2lpSHByb2ZXcml0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYmRkY2M2Ci0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9wcm9maWxlci9Bc2NpaUhwcm9mV3JpdGVyLmphdmEKQEAgLTAsMCArMSw5OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLnN5c3RlbS5wcm9maWxlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuQ29tcGFyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBBc2NpaUhwcm9mV3JpdGVyIHByb2R1Y2VzIGhwcm9mIGNvbXBhdGlibGUgdGV4dCBvdXRwdXQgZm9yIHVzZSB3aXRoCisgKiB0aGlyZCBwYXJ0eSB0b29scyBzdWNoIGFzIFBlcmZBbmFsLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQXNjaWlIcHJvZldyaXRlciB7CisKKyAgICBwcml2YXRlIGZpbmFsIEhwcm9mRGF0YSBkYXRhOworICAgIHByaXZhdGUgZmluYWwgUHJpbnRXcml0ZXIgb3V0OworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBwcm92aWRlZCBkYXRhIHRvIHRoZSBzcGVjaWZpZWQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB3cml0ZShIcHJvZkRhdGEgZGF0YSwgT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgbmV3IEFzY2lpSHByb2ZXcml0ZXIoZGF0YSwgb3V0cHV0U3RyZWFtKS53cml0ZSgpOworICAgIH0KKworICAgIHByaXZhdGUgQXNjaWlIcHJvZldyaXRlcihIcHJvZkRhdGEgZGF0YSwgT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSkgeworICAgICAgICB0aGlzLmRhdGEgPSBkYXRhOworICAgICAgICB0aGlzLm91dCA9IG5ldyBQcmludFdyaXRlcihvdXRwdXRTdHJlYW0pOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoSHByb2ZEYXRhLlRocmVhZEV2ZW50IGUgOiBkYXRhLmdldFRocmVhZEhpc3RvcnkoKSkgeworICAgICAgICAgICAgb3V0LnByaW50bG4oZSk7CisgICAgICAgIH0KKworICAgICAgICBMaXN0PEhwcm9mRGF0YS5TYW1wbGU+IHNhbXBsZXMKKyAgICAgICAgICAgICAgICA9IG5ldyBBcnJheUxpc3Q8SHByb2ZEYXRhLlNhbXBsZT4oZGF0YS5nZXRTYW1wbGVzKCkpOworICAgICAgICBDb2xsZWN0aW9ucy5zb3J0KHNhbXBsZXMsIFNBTVBMRV9DT01QQVJBVE9SKTsKKyAgICAgICAgaW50IHRvdGFsID0gMDsKKyAgICAgICAgZm9yIChIcHJvZkRhdGEuU2FtcGxlIHNhbXBsZSA6IHNhbXBsZXMpIHsKKyAgICAgICAgICAgIEhwcm9mRGF0YS5TdGFja1RyYWNlIHN0YWNrVHJhY2UgPSBzYW1wbGUuc3RhY2tUcmFjZTsKKyAgICAgICAgICAgIGludCBjb3VudCA9IHNhbXBsZS5jb3VudDsKKyAgICAgICAgICAgIHRvdGFsICs9IGNvdW50OworICAgICAgICAgICAgb3V0LnByaW50ZigiVFJBQ0UgJWQ6ICh0aHJlYWQ9JWQpXG4iLAorICAgICAgICAgICAgICAgICAgICAgICBzdGFja1RyYWNlLnN0YWNrVHJhY2VJZCwKKyAgICAgICAgICAgICAgICAgICAgICAgc3RhY2tUcmFjZS50aHJlYWRJZCk7CisgICAgICAgICAgICBmb3IgKFN0YWNrVHJhY2VFbGVtZW50IGUgOiBzdGFja1RyYWNlLnN0YWNrRnJhbWVzKSB7CisgICAgICAgICAgICAgICAgb3V0LnByaW50ZigiXHQlc1xuIiwgZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgRGF0ZSBub3cgPSBuZXcgRGF0ZShkYXRhLmdldFN0YXJ0TWlsbGlzKCkpOworICAgICAgICAvLyAiQ1BVIFNBTVBMRVMgQkVHSU4gKHRvdGFsID0gODI2KSBXZWQgSnVsIDIxIDEyOjAzOjQ2IDIwMTAiCisgICAgICAgIG91dC5wcmludGYoIkNQVSBTQU1QTEVTIEJFR0lOICh0b3RhbCA9ICVkKSAldGEgJXRiICV0ZCAldFQgJXRZXG4iLAorICAgICAgICAgICAgICAgICAgIHRvdGFsLCBub3csIG5vdywgbm93LCBub3csIG5vdyk7CisgICAgICAgIG91dC5wcmludGYoInJhbmsgICBzZWxmICBhY2N1bSAgIGNvdW50IHRyYWNlIG1ldGhvZFxuIik7CisgICAgICAgIGludCByYW5rID0gMDsKKyAgICAgICAgZG91YmxlIGFjY3VtID0gMDsKKyAgICAgICAgZm9yIChIcHJvZkRhdGEuU2FtcGxlIHNhbXBsZSA6IHNhbXBsZXMpIHsKKyAgICAgICAgICAgIHJhbmsrKzsKKyAgICAgICAgICAgIEhwcm9mRGF0YS5TdGFja1RyYWNlIHN0YWNrVHJhY2UgPSBzYW1wbGUuc3RhY2tUcmFjZTsKKyAgICAgICAgICAgIGludCBjb3VudCA9IHNhbXBsZS5jb3VudDsKKyAgICAgICAgICAgIGRvdWJsZSBzZWxmID0gKGRvdWJsZSljb3VudC8oZG91YmxlKXRvdGFsOworICAgICAgICAgICAgYWNjdW0gKz0gc2VsZjsKKworICAgICAgICAgICAgLy8gIiAgIDEgNjUuNjIlIDY1LjYyJSAgICAgNTQyIDMwMDMwMiBqYXZhLmxhbmcuTG9uZy5wYXJzZUxvbmciCisgICAgICAgICAgICBvdXQucHJpbnRmKCIlIDRkJSA2LjJmJSUlIDYuMmYlJSAlIDdkICUgNWQgJXMuJXNcbiIsCisgICAgICAgICAgICAgICAgICAgICAgIHJhbmssIHNlbGYqMTAwLCBhY2N1bSoxMDAsIGNvdW50LCBzdGFja1RyYWNlLnN0YWNrVHJhY2VJZCwKKyAgICAgICAgICAgICAgICAgICAgICAgc3RhY2tUcmFjZS5zdGFja0ZyYW1lc1swXS5nZXRDbGFzc05hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgc3RhY2tUcmFjZS5zdGFja0ZyYW1lc1swXS5nZXRNZXRob2ROYW1lKCkpOworICAgICAgICB9CisgICAgICAgIG91dC5wcmludGYoIkNQVSBTQU1QTEVTIEVORFxuIik7CisgICAgICAgIG91dC5mbHVzaCgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbXBhcmF0b3I8SHByb2ZEYXRhLlNhbXBsZT4gU0FNUExFX0NPTVBBUkFUT1IKKyAgICAgICAgICAgID0gbmV3IENvbXBhcmF0b3I8SHByb2ZEYXRhLlNhbXBsZT4oKSB7CisgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShIcHJvZkRhdGEuU2FtcGxlIHMxLCBIcHJvZkRhdGEuU2FtcGxlIHMyKSB7CisgICAgICAgICAgICByZXR1cm4gczIuY291bnQgLSBzMS5jb3VudDsKKyAgICAgICAgfQorICAgIH07Cit9CmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL3Byb2ZpbGVyL0JpbmFyeUhwcm9mLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL3Byb2ZpbGVyL0JpbmFyeUhwcm9mLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTcyMDQ0NgotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vcHJvZmlsZXIvQmluYXJ5SHByb2YuamF2YQpAQCAtMCwwICsxLDE0OCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLnN5c3RlbS5wcm9maWxlcjsKKworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBIcHJvZiBiaW5hcnkgZm9ybWF0IHJlbGF0ZWQgY29uc3RhbnRzIHNoYXJlZCBiZXR3ZWVuIHRoZQorICogQmluYXJ5SHByb2ZSZWFkZXIgYW5kIEJpbmFyeUhwcm9mV3JpdGVyLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQmluYXJ5SHByb2YgeworICAgIC8qKgorICAgICAqIEN1cnJlbnRseSBjb2RlIG9ubHkgc3VwcG9ydHMgNCBieXRlIGlkIHNpemUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSURfU0laRSA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBQcmVmaXggb2YgdmFsaWQgbWFnaWMgdmFsdWVzIGZyb20gdGhlIHN0YXJ0IG9mIGEgYmluYXJ5IGhwcm9mIGZpbGUuCisgICAgICovCisgICAgc3RhdGljIFN0cmluZyBNQUdJQyA9ICJKQVZBIFBST0ZJTEUgIjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZpbGUncyBtYWdpYyB2YWx1ZSBhcyBhIFN0cmluZyBpZiBmb3VuZCwgb3RoZXJ3aXNlIG51bGwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgcmVhZE1hZ2ljKERhdGFJbnB1dFN0cmVhbSBpbikgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbNTEyXTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBieXRlIGIgPSBpbi5yZWFkQnl0ZSgpOworICAgICAgICAgICAgICAgIGlmIChiID09ICdcMCcpIHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN0cmluZyA9IG5ldyBTdHJpbmcoYnl0ZXMsIDAsIGksICJVVEYtOCIpOworICAgICAgICAgICAgICAgICAgICBpZiAoc3RyaW5nLnN0YXJ0c1dpdGgoTUFHSUMpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyaW5nOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBieXRlc1tpXSA9IGI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGVudW0gVGFnIHsKKworICAgICAgICBTVFJJTkdfSU5fVVRGOCgweDAxLCAtSURfU0laRSksCisgICAgICAgIExPQURfQ0xBU1MoMHgwMiwgNCArIElEX1NJWkUgKyA0ICsgSURfU0laRSksCisgICAgICAgIFVOTE9BRF9DTEFTUygweDAzLCA0KSwKKyAgICAgICAgU1RBQ0tfRlJBTUUoMHgwNCwgSURfU0laRSArIElEX1NJWkUgKyBJRF9TSVpFICsgSURfU0laRSArIDQgKyA0KSwKKyAgICAgICAgU1RBQ0tfVFJBQ0UoMHgwNSwgLSg0ICsgNCArIDQpKSwKKyAgICAgICAgQUxMT0NfU0lURVMoMHgwNiwgLSgyICsgNCArIDQgKyA0ICsgOCArIDggKyA0KSksCisgICAgICAgIEhFQVBfU1VNTUFSWSgweDA3LCA0ICsgNCArIDggKyA4KSwKKyAgICAgICAgU1RBUlRfVEhSRUFEKDB4MGEsIDQgKyBJRF9TSVpFICsgNCArIElEX1NJWkUgKyBJRF9TSVpFICsgSURfU0laRSksCisgICAgICAgIEVORF9USFJFQUQoMHgwYiwgNCksCisgICAgICAgIEhFQVBfRFVNUCgweDBjLCAtMCksCisgICAgICAgIEhFQVBfRFVNUF9TRUdNRU5UKDB4MWMsIC0wKSwKKyAgICAgICAgSEVBUF9EVU1QX0VORCgweDJjLCAwKSwKKyAgICAgICAgQ1BVX1NBTVBMRVMoMHgwZCwgLSg0ICsgNCkpLAorICAgICAgICBDT05UUk9MX1NFVFRJTkdTKDB4MGUsIDQgKyAyKTsKKworICAgICAgICBwdWJsaWMgZmluYWwgYnl0ZSB0YWc7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE1pbmltdW0gc2l6ZSBpbiBieXRlcy4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmaW5hbCBpbnQgbWluaW11bVNpemU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE1heGltdW0gc2l6ZSBpbiBieXRlcy4gMCBtZWFuIG5vIHNwZWNpZmljIGxpbWl0LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZpbmFsIGludCBtYXhpbXVtU2l6ZTsKKworICAgICAgICBwcml2YXRlIFRhZyhpbnQgdGFnLCBpbnQgc2l6ZSkgeworICAgICAgICAgICAgdGhpcy50YWcgPSAoYnl0ZSkgdGFnOworICAgICAgICAgICAgaWYgKHNpemUgPiAwKSB7CisgICAgICAgICAgICAgICAgLy8gZml4ZWQgc2l6ZSwgbWF4IGFuZCBtaW4gdGhlIHNhbWUKKyAgICAgICAgICAgICAgICB0aGlzLm1pbmltdW1TaXplID0gc2l6ZTsKKyAgICAgICAgICAgICAgICB0aGlzLm1heGltdW1TaXplID0gc2l6ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gb25seSBtaW5pbXVtIGJvdW5kCisgICAgICAgICAgICAgICAgdGhpcy5taW5pbXVtU2l6ZSA9IC1zaXplOworICAgICAgICAgICAgICAgIHRoaXMubWF4aW11bVNpemUgPSAwOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPEJ5dGUsIFRhZz4gQllURV9UT19UQUcKKyAgICAgICAgICAgICAgICA9IG5ldyBIYXNoTWFwPEJ5dGUsIFRhZz4oKTsKKworICAgICAgICBzdGF0aWMgeworICAgICAgICAgICAgZm9yIChUYWcgdiA6IFRhZy52YWx1ZXMoKSkgeworICAgICAgICAgICAgICAgIEJZVEVfVE9fVEFHLnB1dCh2LnRhZywgdik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3RhdGljIFRhZyBnZXQoYnl0ZSB0YWcpIHsKKyAgICAgICAgICAgIHJldHVybiBCWVRFX1RPX1RBRy5nZXQodGFnKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIG51bGwgaWYgdGhlIGFjdHVhbCBzaXplIG1lZXRzIGV4cGVjdGF0aW9ucywgb3IgYQorICAgICAgICAgKiBTdHJpbmcgZXJyb3IgbWVzc2FnZSBpZiBub3QuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgU3RyaW5nIGNoZWNrU2l6ZShpbnQgYWN0dWFsKSB7CisgICAgICAgICAgICBpZiAoYWN0dWFsIDwgbWluaW11bVNpemUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gImV4cGVjdGVkIGEgbWluaW1pYWwgcmVjb3JkIHNpemUgb2YgIiArIG1pbmltdW1TaXplICsgIiBmb3IgIiArIHRoaXMKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiBidXQgcmVjZWl2ZWQgIiArIGFjdHVhbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChtYXhpbXVtU2l6ZSA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYWN0dWFsID4gbWF4aW11bVNpemUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gImV4cGVjdGVkIGEgbWF4aW11bSByZWNvcmQgc2l6ZSBvZiAiICsgbWF4aW11bVNpemUgKyAiIGZvciAiICsgdGhpcworICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGJ1dCByZWNlaXZlZCAiICsgYWN0dWFsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGVudW0gQ29udHJvbFNldHRpbmdzIHsKKyAgICAgICAgQUxMT0NfVFJBQ0VTKDB4MDEpLAorICAgICAgICBDUFVfU0FNUExJTkcoMHgwMik7CisKKyAgICAgICAgcHVibGljIGZpbmFsIGludCBiaXRtYXNrOworCisgICAgICAgIHByaXZhdGUgQ29udHJvbFNldHRpbmdzKGludCBiaXRtYXNrKSB7CisgICAgICAgICAgICB0aGlzLmJpdG1hc2sgPSBiaXRtYXNrOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL3Byb2ZpbGVyL0JpbmFyeUhwcm9mUmVhZGVyLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL3Byb2ZpbGVyL0JpbmFyeUhwcm9mUmVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzVhMTdmMwotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vcHJvZmlsZXIvQmluYXJ5SHByb2ZSZWFkZXIuamF2YQpAQCAtMCwwICsxLDQ4MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLnN5c3RlbS5wcm9maWxlcjsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkVPRkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiA8cHJlPiAgIHtAY29kZQorICogQmluYXJ5SHByb2ZSZWFkZXIgcmVhZGVyID0gbmV3IEJpbmFyeUhwcm9mUmVhZGVyKG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGlucHV0U3RyZWFtKSk7CisgKiByZWFkZXIuc2V0U3RyaWN0KGZhbHNlKTsgLy8gZm9yIFJJIGNvbXBhdGFiaWxpdHkKKyAqIHJlYWRlci5yZWFkKCk7CisgKiBpbnB1dFN0cmVhbS5jbG9zZSgpOworICogcmVhZGVyLmdldFZlcnNpb24oKTsKKyAqIHJlYWRlci5nZXRIcHJvZkRhdGEoKTsKKyAqIH08L3ByZT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEJpbmFyeUhwcm9mUmVhZGVyIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gVFJBQ0UgPSBmYWxzZTsKKworICAgIHByaXZhdGUgZmluYWwgRGF0YUlucHV0U3RyZWFtIGluOworCisgICAgLyoqCisgICAgICogQnkgZGVmYXVsdCB3ZSB0cnkgdG8gc3RyaWN0bHkgdmFsaWRhdGUgcnVsZXMgZm9sbG93ZWQgYnkKKyAgICAgKiBvdXIgSHByb2ZXcml0ZXIuIEZvciBleGFtcGxlLCBldmVyeSBlbmQgdGhyZWFkIGlzIHByZWNlZGVkCisgICAgICogYnkgYSBtYXRjaGluZyBzdGFydCB0aHJlYWQuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIHN0cmljdCA9IHRydWU7CisKKyAgICAvKioKKyAgICAgKiB2ZXJzaW9uIHN0cmluZyBmcm9tIGhlYWRlciBhZnRlciByZWFkIGhhcyBiZWVuIHBlcmZvcm1lZCwKKyAgICAgKiBvdGhlcndpc2UgbnVsbC4gbnVsbG5lc3MgdXNlZCB0byBkZXRlY3QgaWYgY2FsbGVycyB0cnkgdG8KKyAgICAgKiBhY2Nlc3MgZGF0YSBiZWZvcmUgcmVhZCBpcyBjYWxsZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgdmVyc2lvbjsKKworICAgIHByaXZhdGUgZmluYWwgTWFwPEhwcm9mRGF0YS5TdGFja1RyYWNlLCBpbnRbXT4gc3RhY2tUcmFjZXMKKyAgICAgICAgICAgID0gbmV3IEhhc2hNYXA8SHByb2ZEYXRhLlN0YWNrVHJhY2UsIGludFtdPigpOworCisgICAgcHJpdmF0ZSBmaW5hbCBIcHJvZkRhdGEgaHByb2ZEYXRhID0gbmV3IEhwcm9mRGF0YShzdGFja1RyYWNlcyk7CisKKyAgICBwcml2YXRlIGZpbmFsIE1hcDxJbnRlZ2VyLCBTdHJpbmc+IGlkVG9TdHJpbmcgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBTdHJpbmc+KCk7CisgICAgcHJpdmF0ZSBmaW5hbCBNYXA8SW50ZWdlciwgU3RyaW5nPiBpZFRvQ2xhc3NOYW1lID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgU3RyaW5nPigpOworICAgIHByaXZhdGUgZmluYWwgTWFwPEludGVnZXIsIFN0YWNrVHJhY2VFbGVtZW50PiBpZFRvU3RhY2tGcmFtZQorICAgICAgICAgICAgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBTdGFja1RyYWNlRWxlbWVudD4oKTsKKyAgICBwcml2YXRlIGZpbmFsIE1hcDxJbnRlZ2VyLCBIcHJvZkRhdGEuU3RhY2tUcmFjZT4gaWRUb1N0YWNrVHJhY2UKKyAgICAgICAgICAgID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgSHByb2ZEYXRhLlN0YWNrVHJhY2U+KCk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgQmluYXJ5SHByb2ZSZWFkZXIgYXJvdW5kIHRoZSBzcGVjaWZpZWQge0Bjb2RlCisgICAgICogaW5wdXRTdHJlYW19CisgICAgICovCisgICAgcHVibGljIEJpbmFyeUhwcm9mUmVhZGVyKElucHV0U3RyZWFtIGlucHV0U3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLmluID0gbmV3IERhdGFJbnB1dFN0cmVhbShpbnB1dFN0cmVhbSk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZ2V0U3RyaWN0ICgpIHsKKyAgICAgICAgcmV0dXJuIHN0cmljdDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTdHJpY3QgKGJvb2xlYW4gc3RyaWN0KSB7CisgICAgICAgIGlmICh2ZXJzaW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oImNhbm5vdCBzZXQgc3RyaWN0IGFmdGVyIHJlYWQoKSIpOworICAgICAgICB9CisgICAgICAgIHRoaXMuc3RyaWN0ID0gc3RyaWN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgcmVhZCgpIGhhcyBub3QgYmVlbiBjYWxsZWQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrUmVhZCgpIHsKKyAgICAgICAgaWYgKHZlcnNpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiZGF0YSBhY2Nlc3MgYmVmb3JlIHJlYWQoKSIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRWZXJzaW9uKCkgeworICAgICAgICBjaGVja1JlYWQoKTsKKyAgICAgICAgcmV0dXJuIHZlcnNpb247CisgICAgfQorCisgICAgcHVibGljIEhwcm9mRGF0YSBnZXRIcHJvZkRhdGEoKSB7CisgICAgICAgIGNoZWNrUmVhZCgpOworICAgICAgICByZXR1cm4gaHByb2ZEYXRhOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgdGhlIGhwcm9mIGhlYWRlciBhbmQgcmVjb3JkcyBmcm9tIHRoZSBpbnB1dAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBwYXJzZUhlYWRlcigpOworICAgICAgICBwYXJzZVJlY29yZHMoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcGFyc2VIZWFkZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoVFJBQ0UpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiaHByb2ZUYWc9SEVBREVSIik7CisgICAgICAgIH0KKyAgICAgICAgcGFyc2VWZXJzaW9uKCk7CisgICAgICAgIHBhcnNlSWRTaXplKCk7CisgICAgICAgIHBhcnNlVGltZSgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwYXJzZVZlcnNpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgdmVyc2lvbiA9IEJpbmFyeUhwcm9mLnJlYWRNYWdpYyhpbik7CisgICAgICAgIGlmICh2ZXJzaW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRIcHJvZkV4Y2VwdGlvbigiQ291bGQgbm90IGZpbmQgSFBST0YgdmVyc2lvbiIpOworICAgICAgICB9CisgICAgICAgIGlmIChUUkFDRSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcdHZlcnNpb249IiArIHZlcnNpb24pOworICAgICAgICB9CisgICAgICAgIHRoaXMudmVyc2lvbiA9IHZlcnNpb247CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHBhcnNlSWRTaXplKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGlkU2l6ZSA9IGluLnJlYWRJbnQoKTsKKyAgICAgICAgaWYgKFRSQUNFKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0aWRTaXplPSIgKyBpZFNpemUpOworICAgICAgICB9CisgICAgICAgIGlmIChpZFNpemUgIT0gQmluYXJ5SHByb2YuSURfU0laRSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZEhwcm9mRXhjZXB0aW9uKCJVbnN1cHBvcnRlZCBpZGVudGlmaWVyIHNpemU6ICIgKyBpZFNpemUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHBhcnNlVGltZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgdGltZSA9IGluLnJlYWRMb25nKCk7CisgICAgICAgIGlmIChUUkFDRSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcdHRpbWU9IiArIExvbmcudG9IZXhTdHJpbmcodGltZSkgKyAiICIgKyBuZXcgRGF0ZSh0aW1lKSk7CisgICAgICAgIH0KKyAgICAgICAgaHByb2ZEYXRhLnNldFN0YXJ0TWlsbGlzKHRpbWUpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwYXJzZVJlY29yZHMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3aGlsZSAocGFyc2VSZWNvcmQoKSkgeworICAgICAgICAgICAgOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCBhbmQgcHJvY2VzcyB0aGUgbmV4dCByZWNvcmQuIFJldHVybnMgdHJ1ZSBpZiBhCisgICAgICogcmVjb3JkIHdhcyBoYW5kbGVkLCBmYWxzZSBvbiBFT0YuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIHBhcnNlUmVjb3JkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHRhZ09yRU9GID0gaW4ucmVhZCgpOworICAgICAgICBpZiAodGFnT3JFT0YgPT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBieXRlIHRhZyA9IChieXRlKSB0YWdPckVPRjsKKyAgICAgICAgaW50IHRpbWVEZWx0YUluTWljcm9zZWNvbmRzID0gaW4ucmVhZEludCgpOworICAgICAgICBpbnQgcmVjb3JkTGVuZ3RoID0gaW4ucmVhZEludCgpOworICAgICAgICBCaW5hcnlIcHJvZi5UYWcgaHByb2ZUYWcgPSBCaW5hcnlIcHJvZi5UYWcuZ2V0KHRhZyk7CisgICAgICAgIGlmIChUUkFDRSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJocHJvZlRhZz0iICsgaHByb2ZUYWcpOworICAgICAgICB9CisgICAgICAgIGlmIChocHJvZlRhZyA9PSBudWxsKSB7CisgICAgICAgICAgICBza2lwUmVjb3JkKGhwcm9mVGFnLCByZWNvcmRMZW5ndGgpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIGVycm9yID0gaHByb2ZUYWcuY2hlY2tTaXplKHJlY29yZExlbmd0aCk7CisgICAgICAgIGlmIChlcnJvciAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkSHByb2ZFeGNlcHRpb24oZXJyb3IpOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoaHByb2ZUYWcpIHsKKyAgICAgICAgICAgIGNhc2UgQ09OVFJPTF9TRVRUSU5HUzoKKyAgICAgICAgICAgICAgICBwYXJzZUNvbnRyb2xTZXR0aW5ncygpOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworCisgICAgICAgICAgICBjYXNlIFNUUklOR19JTl9VVEY4OgorICAgICAgICAgICAgICAgIHBhcnNlU3RyaW5nSW5VdGY4KHJlY29yZExlbmd0aCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisKKyAgICAgICAgICAgIGNhc2UgU1RBUlRfVEhSRUFEOgorICAgICAgICAgICAgICAgIHBhcnNlU3RhcnRUaHJlYWQoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIGNhc2UgRU5EX1RIUkVBRDoKKyAgICAgICAgICAgICAgICBwYXJzZUVuZFRocmVhZCgpOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworCisgICAgICAgICAgICBjYXNlIExPQURfQ0xBU1M6CisgICAgICAgICAgICAgICAgcGFyc2VMb2FkQ2xhc3MoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIGNhc2UgU1RBQ0tfRlJBTUU6CisgICAgICAgICAgICAgICAgcGFyc2VTdGFja0ZyYW1lKCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICBjYXNlIFNUQUNLX1RSQUNFOgorICAgICAgICAgICAgICAgIHBhcnNlU3RhY2tUcmFjZShyZWNvcmRMZW5ndGgpOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworCisgICAgICAgICAgICBjYXNlIENQVV9TQU1QTEVTOgorICAgICAgICAgICAgICAgIHBhcnNlQ3B1U2FtcGxlcyhyZWNvcmRMZW5ndGgpOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworCisgICAgICAgICAgICBjYXNlIFVOTE9BRF9DTEFTUzoKKyAgICAgICAgICAgIGNhc2UgQUxMT0NfU0lURVM6CisgICAgICAgICAgICBjYXNlIEhFQVBfU1VNTUFSWToKKyAgICAgICAgICAgIGNhc2UgSEVBUF9EVU1QOgorICAgICAgICAgICAgY2FzZSBIRUFQX0RVTVBfU0VHTUVOVDoKKyAgICAgICAgICAgIGNhc2UgSEVBUF9EVU1QX0VORDoKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgc2tpcFJlY29yZChocHJvZlRhZywgcmVjb3JkTGVuZ3RoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBza2lwUmVjb3JkKEJpbmFyeUhwcm9mLlRhZyBocHJvZlRhZywgbG9uZyByZWNvcmRMZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChUUkFDRSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcdHNraXBwaW5nIHJlY29yZExlbmd0aD0iICsgcmVjb3JkTGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICBsb25nIHNraXBwZWQgPSBpbi5za2lwKHJlY29yZExlbmd0aCk7CisgICAgICAgIGlmIChza2lwcGVkICE9IHJlY29yZExlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbigiRXhwZWN0ZWQgdG8gc2tpcCAiICsgcmVjb3JkTGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBieXRlcyBidXQgb25seSBza2lwcGVkICIgKyBza2lwcGVkICsgIiBieXRlcyIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHBhcnNlQ29udHJvbFNldHRpbmdzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGZsYWdzID0gaW4ucmVhZEludCgpOworICAgICAgICBzaG9ydCBkZXB0aCA9IGluLnJlYWRTaG9ydCgpOworICAgICAgICBpZiAoVFJBQ0UpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRmbGFncz0iICsgSW50ZWdlci50b0hleFN0cmluZyhmbGFncykpOworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcdGRlcHRoPSIgKyBkZXB0aCk7CisgICAgICAgIH0KKyAgICAgICAgaHByb2ZEYXRhLnNldEZsYWdzKGZsYWdzKTsKKyAgICAgICAgaHByb2ZEYXRhLnNldERlcHRoKGRlcHRoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcGFyc2VTdHJpbmdJblV0ZjgoaW50IHJlY29yZExlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHN0cmluZ0lkID0gaW4ucmVhZEludCgpOworICAgICAgICBieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVtyZWNvcmRMZW5ndGggLSBCaW5hcnlIcHJvZi5JRF9TSVpFXTsKKyAgICAgICAgcmVhZEZ1bGx5KGluLCBieXRlcyk7CisgICAgICAgIFN0cmluZyBzdHJpbmcgPSBuZXcgU3RyaW5nKGJ5dGVzLCAiVVRGLTgiKTsKKyAgICAgICAgaWYgKFRSQUNFKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0c3RyaW5nPSIgKyBzdHJpbmcpOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBvbGQgPSBpZFRvU3RyaW5nLnB1dChzdHJpbmdJZCwgc3RyaW5nKTsKKyAgICAgICAgaWYgKG9sZCAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkSHByb2ZFeGNlcHRpb24oIkR1cGxpY2F0ZSBzdHJpbmcgaWQ6ICIgKyBzdHJpbmdJZCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHJlYWRGdWxseShJbnB1dFN0cmVhbSBpbiwgYnl0ZVtdIGRzdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IG9mZnNldCA9IDA7CisgICAgICAgIGludCBieXRlQ291bnQgPSBkc3QubGVuZ3RoOworICAgICAgICB3aGlsZSAoYnl0ZUNvdW50ID4gMCkgeworICAgICAgICAgICAgaW50IGJ5dGVzUmVhZCA9IGluLnJlYWQoZHN0LCBvZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgICAgICBpZiAoYnl0ZXNSZWFkIDwgMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG9mZnNldCArPSBieXRlc1JlYWQ7CisgICAgICAgICAgICBieXRlQ291bnQgLT0gYnl0ZXNSZWFkOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHBhcnNlTG9hZENsYXNzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGNsYXNzSWQgPSBpbi5yZWFkSW50KCk7CisgICAgICAgIGludCBjbGFzc09iamVjdElkID0gcmVhZElkKCk7CisgICAgICAgIC8vIHNlcmlhbCBudW1iZXIgYXBwYXJlbnRseSBub3QgYSBzdGFjayB0cmFjZSBpZC4gKGludCB2cyBJRCkKKyAgICAgICAgLy8gd2UgZG9uJ3QgdXNlIHRoaXMgZmllbGQuCisgICAgICAgIGludCBzdGFja1RyYWNlU2VyaWFsTnVtYmVyID0gaW4ucmVhZEludCgpOworICAgICAgICBTdHJpbmcgY2xhc3NOYW1lID0gcmVhZFN0cmluZygpOworICAgICAgICBpZiAoVFJBQ0UpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRjbGFzc0lkPSIgKyBjbGFzc0lkKTsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRjbGFzc09iamVjdElkPSIgKyBjbGFzc09iamVjdElkKTsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRzdGFja1RyYWNlU2VyaWFsTnVtYmVyPSIgKyBzdGFja1RyYWNlU2VyaWFsTnVtYmVyKTsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRjbGFzc05hbWU9IiArIGNsYXNzTmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIG9sZCA9IGlkVG9DbGFzc05hbWUucHV0KGNsYXNzSWQsIGNsYXNzTmFtZSk7CisgICAgICAgIGlmIChvbGQgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZEhwcm9mRXhjZXB0aW9uKCJEdXBsaWNhdGUgY2xhc3MgaWQ6ICIgKyBjbGFzc0lkKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgaW50IHJlYWRJZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBpbi5yZWFkSW50KCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgcmVhZFN0cmluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBpZCA9IHJlYWRJZCgpOworICAgICAgICBpZiAoaWQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHN0cmluZyA9IGlkVG9TdHJpbmcuZ2V0KGlkKTsKKyAgICAgICAgaWYgKHN0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkSHByb2ZFeGNlcHRpb24oIlVua25vd24gc3RyaW5nIGlkICIgKyBpZCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN0cmluZzsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyByZWFkQ2xhc3MoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgaWQgPSByZWFkSWQoKTsKKyAgICAgICAgU3RyaW5nIHN0cmluZyA9IGlkVG9DbGFzc05hbWUuZ2V0KGlkKTsKKyAgICAgICAgaWYgKHN0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkSHByb2ZFeGNlcHRpb24oIlVua25vd24gY2xhc3MgaWQgIiArIGlkKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3RyaW5nOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwYXJzZVN0YXJ0VGhyZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHRocmVhZElkID0gaW4ucmVhZEludCgpOworICAgICAgICBpbnQgb2JqZWN0SWQgPSByZWFkSWQoKTsKKyAgICAgICAgLy8gc3RhY2sgdHJhY2Ugd2hlcmUgdGhyZWFkIHdhcyBjcmVhdGVkLgorICAgICAgICAvLyBzZXJpYWwgbnVtYmVyIGFwcGFyZW50bHkgbm90IGEgc3RhY2sgdHJhY2UgaWQuIChpbnQgdnMgSUQpCisgICAgICAgIC8vIHdlIGRvbid0IHVzZSB0aGlzIGZpZWxkLgorICAgICAgICBpbnQgc3RhY2tUcmFjZVNlcmlhbE51bWJlciA9IGluLnJlYWRJbnQoKTsKKyAgICAgICAgU3RyaW5nIHRocmVhZE5hbWUgPSByZWFkU3RyaW5nKCk7CisgICAgICAgIFN0cmluZyBncm91cE5hbWUgPSByZWFkU3RyaW5nKCk7CisgICAgICAgIFN0cmluZyBwYXJlbnRHcm91cE5hbWUgPSByZWFkU3RyaW5nKCk7CisgICAgICAgIGlmIChUUkFDRSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcdHRocmVhZElkPSIgKyB0aHJlYWRJZCk7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0b2JqZWN0SWQ9IiArIG9iamVjdElkKTsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRzdGFja1RyYWNlU2VyaWFsTnVtYmVyPSIgKyBzdGFja1RyYWNlU2VyaWFsTnVtYmVyKTsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHR0aHJlYWROYW1lPSIgKyB0aHJlYWROYW1lKTsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRncm91cE5hbWU9IiArIGdyb3VwTmFtZSk7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0cGFyZW50R3JvdXBOYW1lPSIgKyBwYXJlbnRHcm91cE5hbWUpOworICAgICAgICB9CisgICAgICAgIEhwcm9mRGF0YS5UaHJlYWRFdmVudCBldmVudAorICAgICAgICAgICAgICAgID0gSHByb2ZEYXRhLlRocmVhZEV2ZW50LnN0YXJ0KG9iamVjdElkLCB0aHJlYWRJZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJlYWROYW1lLCBncm91cE5hbWUsIHBhcmVudEdyb3VwTmFtZSk7CisgICAgICAgIGhwcm9mRGF0YS5hZGRUaHJlYWRFdmVudChldmVudCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHBhcnNlRW5kVGhyZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHRocmVhZElkID0gaW4ucmVhZEludCgpOworICAgICAgICBpZiAoVFJBQ0UpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHR0aHJlYWRJZD0iICsgdGhyZWFkSWQpOworICAgICAgICB9CisgICAgICAgIEhwcm9mRGF0YS5UaHJlYWRFdmVudCBldmVudCA9IEhwcm9mRGF0YS5UaHJlYWRFdmVudC5lbmQodGhyZWFkSWQpOworICAgICAgICBocHJvZkRhdGEuYWRkVGhyZWFkRXZlbnQoZXZlbnQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwYXJzZVN0YWNrRnJhbWUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgc3RhY2tGcmFtZUlkID0gcmVhZElkKCk7CisgICAgICAgIFN0cmluZyBtZXRob2ROYW1lID0gcmVhZFN0cmluZygpOworICAgICAgICBTdHJpbmcgbWV0aG9kU2lnbmF0dXJlID0gcmVhZFN0cmluZygpOworICAgICAgICBTdHJpbmcgZmlsZSA9IHJlYWRTdHJpbmcoKTsKKyAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9IHJlYWRDbGFzcygpOworICAgICAgICBpbnQgbGluZSA9IGluLnJlYWRJbnQoKTsKKyAgICAgICAgaWYgKFRSQUNFKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0c3RhY2tGcmFtZUlkPSIgKyBzdGFja0ZyYW1lSWQpOworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcdGNsYXNzTmFtZT0iICsgY2xhc3NOYW1lKTsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRtZXRob2ROYW1lPSIgKyBtZXRob2ROYW1lKTsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRtZXRob2RTaWduYXR1cmU9IiArIG1ldGhvZFNpZ25hdHVyZSk7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0ZmlsZT0iICsgZmlsZSk7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0bGluZT0iICsgbGluZSk7CisgICAgICAgIH0KKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnQgc3RhY2tGcmFtZSA9IG5ldyBTdGFja1RyYWNlRWxlbWVudChjbGFzc05hbWUsIG1ldGhvZE5hbWUsIGZpbGUsIGxpbmUpOworICAgICAgICBTdGFja1RyYWNlRWxlbWVudCBvbGQgPSBpZFRvU3RhY2tGcmFtZS5wdXQoc3RhY2tGcmFtZUlkLCBzdGFja0ZyYW1lKTsKKyAgICAgICAgaWYgKG9sZCAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkSHByb2ZFeGNlcHRpb24oIkR1cGxpY2F0ZSBzdGFjayBmcmFtZSBpZDogIiArIHN0YWNrRnJhbWVJZCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcGFyc2VTdGFja1RyYWNlKGludCByZWNvcmRMZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBzdGFja1RyYWNlSWQgPSBpbi5yZWFkSW50KCk7CisgICAgICAgIGludCB0aHJlYWRJZCA9IGluLnJlYWRJbnQoKTsKKyAgICAgICAgaW50IGZyYW1lcyA9IGluLnJlYWRJbnQoKTsKKyAgICAgICAgaWYgKFRSQUNFKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0c3RhY2tUcmFjZUlkPSIgKyBzdGFja1RyYWNlSWQpOworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcdHRocmVhZElkPSIgKyB0aHJlYWRJZCk7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0ZnJhbWVzPSIgKyBmcmFtZXMpOworICAgICAgICB9CisgICAgICAgIGludCBleHBlY3RlZExlbmd0aCA9IDQgKyA0ICsgNCArIChmcmFtZXMgKiBCaW5hcnlIcHJvZi5JRF9TSVpFKTsKKyAgICAgICAgaWYgKHJlY29yZExlbmd0aCAhPSBleHBlY3RlZExlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZEhwcm9mRXhjZXB0aW9uKCJFeHBlY3RlZCBzdGFjayB0cmFjZSByZWNvcmQgb2Ygc2l6ZSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBleHBlY3RlZExlbmd0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBiYXNlZCBvbiBudW1iZXIgb2YgZnJhbWVzIGJ1dCBoZWFkZXIgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgInNwZWNpZmllZCBhIGxlbmd0aCBvZiAgIiArIHJlY29yZExlbmd0aCk7CisgICAgICAgIH0KKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnRbXSBzdGFja0ZyYW1lcyA9IG5ldyBTdGFja1RyYWNlRWxlbWVudFtmcmFtZXNdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZyYW1lczsgaSsrKSB7CisgICAgICAgICAgICBpbnQgc3RhY2tGcmFtZUlkID0gcmVhZElkKCk7CisgICAgICAgICAgICBTdGFja1RyYWNlRWxlbWVudCBzdGFja0ZyYW1lID0gaWRUb1N0YWNrRnJhbWUuZ2V0KHN0YWNrRnJhbWVJZCk7CisgICAgICAgICAgICBpZiAoVFJBQ0UpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0c3RhY2tGcmFtZUlkPSIgKyBzdGFja0ZyYW1lSWQpOworICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRzdGFja0ZyYW1lPSIgKyBzdGFja0ZyYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzdGFja0ZyYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkSHByb2ZFeGNlcHRpb24oIlVua25vd24gc3RhY2sgZnJhbWUgaWQgIiArIHN0YWNrRnJhbWVJZCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzdGFja0ZyYW1lc1tpXSA9IHN0YWNrRnJhbWU7CisgICAgICAgIH0KKworICAgICAgICBIcHJvZkRhdGEuU3RhY2tUcmFjZSBzdGFja1RyYWNlCisgICAgICAgICAgICAgICAgPSBuZXcgSHByb2ZEYXRhLlN0YWNrVHJhY2Uoc3RhY2tUcmFjZUlkLCB0aHJlYWRJZCwgc3RhY2tGcmFtZXMpOworICAgICAgICBpZiAoc3RyaWN0KSB7CisgICAgICAgICAgICBocHJvZkRhdGEuYWRkU3RhY2tUcmFjZShzdGFja1RyYWNlLCBuZXcgaW50WzFdKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIFRoZSBSSSBjYW4gaGF2ZSBkdXBsaWNhdGUgc3RhY2tzLCBwcmVzdW1hYmx5IHRoZXkKKyAgICAgICAgICAgIC8vIGhhdmUgYSBtaW5vciByYWNlIGlmIHR3byBzYW1wbGVzIHdpdGggdGhlIHNhbWUKKyAgICAgICAgICAgIC8vIHN0YWNrIGFyZSB0YWtlbiBhcm91bmQgdGhlIHNhbWUgdGltZS4gaWYgd2UgaGF2ZSBhCisgICAgICAgICAgICAvLyBkdXBsaWNhdGUsIGp1c3Qgc2tpcCBhZGRpbmcgaXQgdG8gaHByb2ZEYXRhLCBidXQKKyAgICAgICAgICAgIC8vIHJlZ2lzdGVyIGl0IGxvY2FsbHkgaW4gaWRUb1N0YWNrRnJhbWUuIGlmIGl0IHNlZW4KKyAgICAgICAgICAgIC8vIGluIENQVV9TQU1QTEVTLCB3ZSB3aWxsIGZpbmQgYSBTdGFja1RyYWNlIGlzIGVxdWFsCisgICAgICAgICAgICAvLyB0byB0aGUgZmlyc3QsIHNvIHRoZXkgd2lsbCBzaGFyZSBhIGNvdW50Q2VsbC4KKyAgICAgICAgICAgIGludFtdIGNvdW50Q2VsbCA9IHN0YWNrVHJhY2VzLmdldChzdGFja1RyYWNlKTsKKyAgICAgICAgICAgIGlmIChjb3VudENlbGwgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGhwcm9mRGF0YS5hZGRTdGFja1RyYWNlKHN0YWNrVHJhY2UsIG5ldyBpbnRbMV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgSHByb2ZEYXRhLlN0YWNrVHJhY2Ugb2xkID0gaWRUb1N0YWNrVHJhY2UucHV0KHN0YWNrVHJhY2VJZCwgc3RhY2tUcmFjZSk7CisgICAgICAgIGlmIChvbGQgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZEhwcm9mRXhjZXB0aW9uKCJEdXBsaWNhdGUgc3RhY2sgdHJhY2UgaWQ6ICIgKyBzdGFja1RyYWNlSWQpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcGFyc2VDcHVTYW1wbGVzKGludCByZWNvcmRMZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCB0b3RhbFNhbXBsZXMgPSBpbi5yZWFkSW50KCk7CisgICAgICAgIGludCBzYW1wbGVzQ291bnQgPSBpbi5yZWFkSW50KCk7CisgICAgICAgIGlmIChUUkFDRSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcdHRvdGFsU2FtcGxlcz0iICsgdG90YWxTYW1wbGVzKTsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRzYW1wbGVzQ291bnQ9IiArIHNhbXBsZXNDb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGV4cGVjdGVkTGVuZ3RoID0gNCArIDQgKyAoc2FtcGxlc0NvdW50ICogKDQgKyA0KSk7CisgICAgICAgIGlmIChyZWNvcmRMZW5ndGggIT0gZXhwZWN0ZWRMZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRIcHJvZkV4Y2VwdGlvbigiRXhwZWN0ZWQgQ1BVIHNhbXBsZXMgcmVjb3JkIG9mIHNpemUgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZXhwZWN0ZWRMZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgYmFzZWQgb24gbnVtYmVyIG9mIHNhbXBsZXMgYnV0IGhlYWRlciAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAic3BlY2lmaWVkIGEgbGVuZ3RoIG9mICAiICsgcmVjb3JkTGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgdG90YWwgPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNhbXBsZXNDb3VudDsgaSsrKSB7CisgICAgICAgICAgICBpbnQgY291bnQgPSBpbi5yZWFkSW50KCk7CisgICAgICAgICAgICBpbnQgc3RhY2tUcmFjZUlkID0gaW4ucmVhZEludCgpOworICAgICAgICAgICAgaWYgKFRSQUNFKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcdGNvdW50PSIgKyBjb3VudCk7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcdHN0YWNrVHJhY2VJZD0iICsgc3RhY2tUcmFjZUlkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEhwcm9mRGF0YS5TdGFja1RyYWNlIHN0YWNrVHJhY2UgPSBpZFRvU3RhY2tUcmFjZS5nZXQoc3RhY2tUcmFjZUlkKTsKKyAgICAgICAgICAgIGlmIChzdGFja1RyYWNlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkSHByb2ZFeGNlcHRpb24oIlVua25vd24gc3RhY2sgdHJhY2UgaWQgIiArIHN0YWNrVHJhY2VJZCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY291bnQgPT0gMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRIcHJvZkV4Y2VwdGlvbigiWmVybyBzYW1wbGUgY291bnQgZm9yIHN0YWNrIHRyYWNlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzdGFja1RyYWNlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludFtdIGNvdW50Q2VsbCA9IHN0YWNrVHJhY2VzLmdldChzdGFja1RyYWNlKTsKKyAgICAgICAgICAgIGlmIChzdHJpY3QpIHsKKyAgICAgICAgICAgICAgICBpZiAoY291bnRDZWxsWzBdICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZEhwcm9mRXhjZXB0aW9uKCJTZXR0aW5nIHNhbXBsZSBjb3VudCBvZiBzdGFjayB0cmFjZSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHN0YWNrVHJhY2UgKyAiIHRvICIgKyBjb3VudAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGZvdW5kIGl0IHdhcyBhbHJlYWR5IGluaXRpYWxpemVkIHRvICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgY291bnRDZWxsWzBdKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIENvYWxlc2NlIGNvdW50cyBmcm9tIGR1cGxpY2F0ZSBzdGFjayB0cmFjZXMuCisgICAgICAgICAgICAgICAgLy8gRm9yIG1vcmUgb24gdGhpcywgc2VlIGNvbW1lbnRzIGluIHBhcnNlU3RhY2tUcmFjZS4KKyAgICAgICAgICAgICAgICBjb3VudCArPSBjb3VudENlbGxbMF07CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb3VudENlbGxbMF0gPSBjb3VudDsKKyAgICAgICAgICAgIHRvdGFsICs9IGNvdW50OworICAgICAgICB9CisgICAgICAgIGlmIChzdHJpY3QgJiYgdG90YWxTYW1wbGVzICE9IHRvdGFsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkSHByb2ZFeGNlcHRpb24oIkV4cGVjdGVkIGEgdG90YWwgb2YgIiArIHRvdGFsU2FtcGxlcworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBzYW1wbGVzIGJ1dCBzYXcgIiArIHRvdGFsKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vcHJvZmlsZXIvQmluYXJ5SHByb2ZXcml0ZXIuamF2YSBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vcHJvZmlsZXIvQmluYXJ5SHByb2ZXcml0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YzI5ODM4Ci0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9wcm9maWxlci9CaW5hcnlIcHJvZldyaXRlci5qYXZhCkBAIC0wLDAgKzEsMjUzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBkYWx2aWsuc3lzdGVtLnByb2ZpbGVyOworCitpbXBvcnQgamF2YS5pby5EYXRhT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCisvKioKKyAqIEJpbmFyeUhwcm9mV3JpdGVyIHByb2R1Y2VzIGhwcm9mIGNvbXBhdGlibGUgYmluYXJ5IG91dHB1dCBmb3IgdXNlCisgKiB3aXRoIHRoaXJkIHBhcnR5IHRvb2xzLiBTdWNoIGZpbGVzIGNhbiBiZSBjb252ZXJ0ZWQgdG8gdGV4dCB3aXRoCisgKiB3aXRoIHtAbGluayBIcHJvZkJpbmFyeVRvQXNjaWl9IG9yIHJlYWQgYmFjayBpbiB3aXRoIHtAbGluayBCaW5hcnlIcHJvZlJlYWRlcn0uCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBCaW5hcnlIcHJvZldyaXRlciB7CisKKyAgICBwcml2YXRlIGludCBuZXh0U3RyaW5nSWQgPSAxOyAvLyBpZCAwID0+IG51bGwKKyAgICBwcml2YXRlIGludCBuZXh0Q2xhc3NJZCA9IDE7CisgICAgcHJpdmF0ZSBpbnQgbmV4dFN0YWNrRnJhbWVJZCA9IDE7CisgICAgcHJpdmF0ZSBmaW5hbCBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBzdHJpbmdUb0lkID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBJbnRlZ2VyPigpOworICAgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgSW50ZWdlcj4gY2xhc3NOYW1lVG9JZCA9IG5ldyBIYXNoTWFwPFN0cmluZywgSW50ZWdlcj4oKTsKKyAgICBwcml2YXRlIGZpbmFsIE1hcDxTdGFja1RyYWNlRWxlbWVudCwgSW50ZWdlcj4gc3RhY2tGcmFtZVRvSWQKKyAgICAgICAgICAgID0gbmV3IEhhc2hNYXA8U3RhY2tUcmFjZUVsZW1lbnQsIEludGVnZXI+KCk7CisKKyAgICBwcml2YXRlIGZpbmFsIEhwcm9mRGF0YSBkYXRhOworICAgIHByaXZhdGUgZmluYWwgRGF0YU91dHB1dFN0cmVhbSBvdXQ7CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIHByb3ZpZGVkIGRhdGEgdG8gdGhlIHNwZWNpZmllZCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlKEhwcm9mRGF0YSBkYXRhLCBPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBuZXcgQmluYXJ5SHByb2ZXcml0ZXIoZGF0YSwgb3V0cHV0U3RyZWFtKS53cml0ZSgpOworICAgIH0KKworICAgIHByaXZhdGUgQmluYXJ5SHByb2ZXcml0ZXIoSHByb2ZEYXRhIGRhdGEsIE91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0pIHsKKyAgICAgICAgdGhpcy5kYXRhID0gZGF0YTsKKyAgICAgICAgdGhpcy5vdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShvdXRwdXRTdHJlYW0pOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZUhlYWRlcihkYXRhLmdldFN0YXJ0TWlsbGlzKCkpOworCisgICAgICAgICAgICB3cml0ZUNvbnRyb2xTZXR0aW5ncyhkYXRhLmdldEZsYWdzKCksIGRhdGEuZ2V0RGVwdGgoKSk7CisKKyAgICAgICAgICAgIGZvciAoSHByb2ZEYXRhLlRocmVhZEV2ZW50IGV2ZW50IDogZGF0YS5nZXRUaHJlYWRIaXN0b3J5KCkpIHsKKyAgICAgICAgICAgICAgICB3cml0ZVRocmVhZEV2ZW50KGV2ZW50KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU2V0PEhwcm9mRGF0YS5TYW1wbGU+IHNhbXBsZXMgPSBkYXRhLmdldFNhbXBsZXMoKTsKKyAgICAgICAgICAgIGludCB0b3RhbCA9IDA7CisgICAgICAgICAgICBmb3IgKEhwcm9mRGF0YS5TYW1wbGUgc2FtcGxlIDogc2FtcGxlcykgeworICAgICAgICAgICAgICAgIHRvdGFsICs9IHNhbXBsZS5jb3VudDsKKyAgICAgICAgICAgICAgICB3cml0ZVN0YWNrVHJhY2Uoc2FtcGxlLnN0YWNrVHJhY2UpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgd3JpdGVDcHVTYW1wbGVzKHRvdGFsLCBzYW1wbGVzKTsKKworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgb3V0LmZsdXNoKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVIZWFkZXIobG9uZyBkdW1wVGltZUluTWlsbGlzZWNvbmRzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXQud3JpdGVCeXRlcyhCaW5hcnlIcHJvZi5NQUdJQyArICIxLjAuMiIpOworICAgICAgICBvdXQud3JpdGVCeXRlKDApOyAvLyBudWxsIHRlcm1pbmF0ZWQgc3RyaW5nCisgICAgICAgIG91dC53cml0ZUludChCaW5hcnlIcHJvZi5JRF9TSVpFKTsKKyAgICAgICAgb3V0LndyaXRlTG9uZyhkdW1wVGltZUluTWlsbGlzZWNvbmRzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVDb250cm9sU2V0dGluZ3MoaW50IGZsYWdzLCBpbnQgZGVwdGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChkZXB0aCA+IFNob3J0Lk1BWF9WQUxVRSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiZGVwdGggdG9vIGxhcmdlIGZvciBiaW5hcnkgaHByb2Y6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBkZXB0aCArICIgPiAiICsgU2hvcnQuTUFYX1ZBTFVFKTsKKyAgICAgICAgfQorICAgICAgICB3cml0ZVJlY29yZEhlYWRlcihCaW5hcnlIcHJvZi5UYWcuQ09OVFJPTF9TRVRUSU5HUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQmluYXJ5SHByb2YuVGFnLkNPTlRST0xfU0VUVElOR1MubWF4aW11bVNpemUpOworICAgICAgICBvdXQud3JpdGVJbnQoZmxhZ3MpOworICAgICAgICBvdXQud3JpdGVTaG9ydCgoc2hvcnQpIGRlcHRoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVUaHJlYWRFdmVudChIcHJvZkRhdGEuVGhyZWFkRXZlbnQgZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3dpdGNoIChlLnR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgU1RBUlQ6CisgICAgICAgICAgICAgICAgd3JpdGVTdGFydFRocmVhZChlKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICBjYXNlIEVORDoKKyAgICAgICAgICAgICAgICB3cml0ZVN0b3BUaHJlYWQoZSk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oZS50eXBlLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZVN0YXJ0VGhyZWFkKEhwcm9mRGF0YS5UaHJlYWRFdmVudCBlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgdGhyZWFkTmFtZUlkID0gd3JpdGVTdHJpbmcoZS50aHJlYWROYW1lKTsKKyAgICAgICAgaW50IGdyb3VwTmFtZUlkID0gd3JpdGVTdHJpbmcoZS5ncm91cE5hbWUpOworICAgICAgICBpbnQgcGFyZW50R3JvdXBOYW1lSWQgPSB3cml0ZVN0cmluZyhlLnBhcmVudEdyb3VwTmFtZSk7CisgICAgICAgIHdyaXRlUmVjb3JkSGVhZGVyKEJpbmFyeUhwcm9mLlRhZy5TVEFSVF9USFJFQUQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgIEJpbmFyeUhwcm9mLlRhZy5TVEFSVF9USFJFQUQubWF4aW11bVNpemUpOworICAgICAgICBvdXQud3JpdGVJbnQoZS50aHJlYWRJZCk7CisgICAgICAgIHdyaXRlSWQoZS5vYmplY3RJZCk7CisgICAgICAgIG91dC53cml0ZUludCgwKTsgLy8gc3RhY2sgdHJhY2Ugd2hlcmUgdGhyZWFkIHdhcyBzdGFydGVkIHVuYXZhaWxhYmxlCisgICAgICAgIHdyaXRlSWQodGhyZWFkTmFtZUlkKTsKKyAgICAgICAgd3JpdGVJZChncm91cE5hbWVJZCk7CisgICAgICAgIHdyaXRlSWQocGFyZW50R3JvdXBOYW1lSWQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZVN0b3BUaHJlYWQoSHByb2ZEYXRhLlRocmVhZEV2ZW50IGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlUmVjb3JkSGVhZGVyKEJpbmFyeUhwcm9mLlRhZy5FTkRfVEhSRUFELAorICAgICAgICAgICAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICBCaW5hcnlIcHJvZi5UYWcuRU5EX1RIUkVBRC5tYXhpbXVtU2l6ZSk7CisgICAgICAgIG91dC53cml0ZUludChlLnRocmVhZElkKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVSZWNvcmRIZWFkZXIoQmluYXJ5SHByb2YuVGFnIGhwcm9mVGFnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdGltZURlbHRhSW5NaWNyb3NlY29uZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCByZWNvcmRMZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBlcnJvciA9IGhwcm9mVGFnLmNoZWNrU2l6ZShyZWNvcmRMZW5ndGgpOworICAgICAgICBpZiAoZXJyb3IgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGVycm9yKTsKKyAgICAgICAgfQorICAgICAgICBvdXQud3JpdGVCeXRlKGhwcm9mVGFnLnRhZyk7CisgICAgICAgIG91dC53cml0ZUludCh0aW1lRGVsdGFJbk1pY3Jvc2Vjb25kcyk7CisgICAgICAgIG91dC53cml0ZUludChyZWNvcmRMZW5ndGgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUlkKGludCBpZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LndyaXRlSW50KGlkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbnN1cmVzIHRoYXQgYSBzdHJpbmcgaGFzIGJlZW4gd3JpdGVuIHRvIHRoZSBvdXQgYW5kCisgICAgICogcmV0dXJucyBpdHMgSUQuIFRoZSBJRCBvZiBhIG51bGwgc3RyaW5nIGlzIHplcm8sIGFuZAorICAgICAqIGRvZXNuJ3QgYWN0dWFsbHkgcmVzdWx0IGluIGFueSBvdXRwdXQuIEluIGEgc3RyaW5nIGhhcworICAgICAqIGFscmVhZHkgYmVlbiB3cml0dGVuIHByZXZpb3VzbHksIHRoZSBlYXJsaWVyIElEIHdpbGwgYmUKKyAgICAgKiByZXR1cm5lZCBhbmQgbm8gb3V0cHV0IHdpbGwgYmUgd3JpdHRlbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCB3cml0ZVN0cmluZyhTdHJpbmcgc3RyaW5nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoc3RyaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIEludGVnZXIgaWRlbnRpZmllciA9IHN0cmluZ1RvSWQuZ2V0KHN0cmluZyk7CisgICAgICAgIGlmIChpZGVudGlmaWVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBpZGVudGlmaWVyOworICAgICAgICB9CisKKyAgICAgICAgaW50IGlkID0gbmV4dFN0cmluZ0lkKys7CisgICAgICAgIHN0cmluZ1RvSWQucHV0KHN0cmluZywgaWQpOworCisgICAgICAgIGJ5dGVbXSBieXRlcyA9IHN0cmluZy5nZXRCeXRlcygiVVRGLTgiKTsKKyAgICAgICAgd3JpdGVSZWNvcmRIZWFkZXIoQmluYXJ5SHByb2YuVGFnLlNUUklOR19JTl9VVEY4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICBCaW5hcnlIcHJvZi5JRF9TSVpFICsgYnl0ZXMubGVuZ3RoKTsKKyAgICAgICAgb3V0LndyaXRlSW50KGlkKTsKKyAgICAgICAgb3V0LndyaXRlKGJ5dGVzLCAwLCBieXRlcy5sZW5ndGgpOworCisgICAgICAgIHJldHVybiBpZDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVDcHVTYW1wbGVzKGludCB0b3RhbFNhbXBsZXMsIFNldDxIcHJvZkRhdGEuU2FtcGxlPiBzYW1wbGVzKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHNhbXBsZXNDb3VudCA9IHNhbXBsZXMuc2l6ZSgpOworICAgICAgICBpZiAoc2FtcGxlc0NvdW50ID09IDApIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB3cml0ZVJlY29yZEhlYWRlcihCaW5hcnlIcHJvZi5UYWcuQ1BVX1NBTVBMRVMsIDAsIDQgKyA0ICsgKHNhbXBsZXNDb3VudCAqICg0ICsgNCkpKTsKKyAgICAgICAgb3V0LndyaXRlSW50KHRvdGFsU2FtcGxlcyk7CisgICAgICAgIG91dC53cml0ZUludChzYW1wbGVzQ291bnQpOworICAgICAgICBmb3IgKEhwcm9mRGF0YS5TYW1wbGUgc2FtcGxlIDogc2FtcGxlcykgeworICAgICAgICAgICAgb3V0LndyaXRlSW50KHNhbXBsZS5jb3VudCk7CisgICAgICAgICAgICBvdXQud3JpdGVJbnQoc2FtcGxlLnN0YWNrVHJhY2Uuc3RhY2tUcmFjZUlkKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZVN0YWNrVHJhY2UoSHByb2ZEYXRhLlN0YWNrVHJhY2Ugc3RhY2tUcmFjZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGZyYW1lcyA9IHN0YWNrVHJhY2Uuc3RhY2tGcmFtZXMubGVuZ3RoOworICAgICAgICBpbnRbXSBzdGFja0ZyYW1lSWRzID0gbmV3IGludFtmcmFtZXNdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZyYW1lczsgaSsrKSB7CisgICAgICAgICAgICBzdGFja0ZyYW1lSWRzW2ldID0gd3JpdGVTdGFja0ZyYW1lKHN0YWNrVHJhY2Uuc3RhY2tGcmFtZXNbaV0pOworICAgICAgICB9CisgICAgICAgIHdyaXRlUmVjb3JkSGVhZGVyKEJpbmFyeUhwcm9mLlRhZy5TVEFDS19UUkFDRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgNCArIDQgKyA0ICsgKGZyYW1lcyAqIEJpbmFyeUhwcm9mLklEX1NJWkUpKTsKKyAgICAgICAgb3V0LndyaXRlSW50KHN0YWNrVHJhY2Uuc3RhY2tUcmFjZUlkKTsKKyAgICAgICAgb3V0LndyaXRlSW50KHN0YWNrVHJhY2UudGhyZWFkSWQpOworICAgICAgICBvdXQud3JpdGVJbnQoZnJhbWVzKTsKKyAgICAgICAgZm9yIChpbnQgc3RhY2tGcmFtZUlkIDogc3RhY2tGcmFtZUlkcykgeworICAgICAgICAgICAgd3JpdGVJZChzdGFja0ZyYW1lSWQpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgd3JpdGVMb2FkQ2xhc3MoU3RyaW5nIGNsYXNzTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSW50ZWdlciBpZGVudGlmaWVyID0gY2xhc3NOYW1lVG9JZC5nZXQoY2xhc3NOYW1lKTsKKyAgICAgICAgaWYgKGlkZW50aWZpZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGlkZW50aWZpZXI7CisgICAgICAgIH0KKyAgICAgICAgaW50IGlkID0gbmV4dENsYXNzSWQrKzsKKyAgICAgICAgY2xhc3NOYW1lVG9JZC5wdXQoY2xhc3NOYW1lLCBpZCk7CisKKyAgICAgICAgaW50IGNsYXNzTmFtZUlkID0gd3JpdGVTdHJpbmcoY2xhc3NOYW1lKTsKKyAgICAgICAgd3JpdGVSZWNvcmRIZWFkZXIoQmluYXJ5SHByb2YuVGFnLkxPQURfQ0xBU1MsCisgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgIEJpbmFyeUhwcm9mLlRhZy5MT0FEX0NMQVNTLm1heGltdW1TaXplKTsKKyAgICAgICAgb3V0LndyaXRlSW50KGlkKTsKKyAgICAgICAgd3JpdGVJZCgwKTsgLy8gY2xhc3Mgb2JqZWN0IElECisgICAgICAgIG91dC53cml0ZUludCgwKTsgLy8gc3RhY2sgdHJhY2Ugd2hlcmUgY2xhc3Mgd2FzIGxvYWRlZCBpcyB1bmF2YWlsYWJsZQorICAgICAgICB3cml0ZUlkKGNsYXNzTmFtZUlkKTsKKworICAgICAgICByZXR1cm4gaWQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgd3JpdGVTdGFja0ZyYW1lKFN0YWNrVHJhY2VFbGVtZW50IHN0YWNrRnJhbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEludGVnZXIgaWRlbnRpZmllciA9IHN0YWNrRnJhbWVUb0lkLmdldChzdGFja0ZyYW1lKTsKKyAgICAgICAgaWYgKGlkZW50aWZpZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGlkZW50aWZpZXI7CisgICAgICAgIH0KKworICAgICAgICBpbnQgaWQgPSBuZXh0U3RhY2tGcmFtZUlkKys7CisgICAgICAgIHN0YWNrRnJhbWVUb0lkLnB1dChzdGFja0ZyYW1lLCBpZCk7CisKKyAgICAgICAgaW50IGNsYXNzSWQgPSB3cml0ZUxvYWRDbGFzcyhzdGFja0ZyYW1lLmdldENsYXNzTmFtZSgpKTsKKyAgICAgICAgaW50IG1ldGhvZE5hbWVJZCA9IHdyaXRlU3RyaW5nKHN0YWNrRnJhbWUuZ2V0TWV0aG9kTmFtZSgpKTsKKyAgICAgICAgaW50IHNvdXJjZUlkID0gd3JpdGVTdHJpbmcoc3RhY2tGcmFtZS5nZXRGaWxlTmFtZSgpKTsKKyAgICAgICAgd3JpdGVSZWNvcmRIZWFkZXIoQmluYXJ5SHByb2YuVGFnLlNUQUNLX0ZSQU1FLAorICAgICAgICAgICAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICBCaW5hcnlIcHJvZi5UYWcuU1RBQ0tfRlJBTUUubWF4aW11bVNpemUpOworICAgICAgICB3cml0ZUlkKGlkKTsKKyAgICAgICAgd3JpdGVJZChtZXRob2ROYW1lSWQpOworICAgICAgICB3cml0ZUlkKDApOyAvLyBtZXRob2Qgc2lnbmF0dXJlIGlzIHVuYXZhaWxhYmxlIGZyb20gU3RhY2tUcmFjZUVsZW1lbnQKKyAgICAgICAgd3JpdGVJZChzb3VyY2VJZCk7CisgICAgICAgIG91dC53cml0ZUludChjbGFzc0lkKTsKKyAgICAgICAgb3V0LndyaXRlSW50KHN0YWNrRnJhbWUuZ2V0TGluZU51bWJlcigpKTsKKworICAgICAgICByZXR1cm4gaWQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9wcm9maWxlci9EYWx2aWtUaHJlYWRTYW1wbGVyLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL3Byb2ZpbGVyL0RhbHZpa1RocmVhZFNhbXBsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMjBjYzMyCi0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9wcm9maWxlci9EYWx2aWtUaHJlYWRTYW1wbGVyLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLnN5c3RlbS5wcm9maWxlcjsKKworaW1wb3J0IGRhbHZpay5zeXN0ZW0uVk1TdGFjazsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitjbGFzcyBEYWx2aWtUaHJlYWRTYW1wbGVyIGltcGxlbWVudHMgVGhyZWFkU2FtcGxlciB7CisKKyAgICBwcml2YXRlIGludCBkZXB0aDsKKworICAgIC8qKgorICAgICAqIFJldXNhYmxlIHN0b3JhZ2UgZm9yIHNhbXBsaW5nIHNpemVkIGZvciB0aGUgc3BlY2lmaWVkIGRlcHRoLgorICAgICAqLworICAgIHByaXZhdGUgU3RhY2tUcmFjZUVsZW1lbnRbXVtdIG11dGFibGVTdGFja1RyYWNlRWxlbWVudHM7CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2V0RGVwdGgoaW50IGRlcHRoKSB7CisgICAgICAgIHRoaXMuZGVwdGggPSBkZXB0aDsKKyAgICAgICAgdGhpcy5tdXRhYmxlU3RhY2tUcmFjZUVsZW1lbnRzID0gbmV3IFN0YWNrVHJhY2VFbGVtZW50W2RlcHRoKzFdW107CisgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgbXV0YWJsZVN0YWNrVHJhY2VFbGVtZW50cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdGhpcy5tdXRhYmxlU3RhY2tUcmFjZUVsZW1lbnRzW2ldID0gbmV3IFN0YWNrVHJhY2VFbGVtZW50W2ldOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdGFja1RyYWNlRWxlbWVudFtdIGdldFN0YWNrVHJhY2UoVGhyZWFkIHRocmVhZCkgeworICAgICAgICBpbnQgY291bnQgPSBWTVN0YWNrLmZpbGxTdGFja1RyYWNlRWxlbWVudHModGhyZWFkLCBtdXRhYmxlU3RhY2tUcmFjZUVsZW1lbnRzW2RlcHRoXSk7CisgICAgICAgIGlmIChjb3VudCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoY291bnQgPCBkZXB0aCkgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShtdXRhYmxlU3RhY2tUcmFjZUVsZW1lbnRzW2RlcHRoXSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YWJsZVN0YWNrVHJhY2VFbGVtZW50c1tjb3VudF0sIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbXV0YWJsZVN0YWNrVHJhY2VFbGVtZW50c1tjb3VudF07CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9wcm9maWxlci9IcHJvZkJpbmFyeVRvQXNjaWkuamF2YSBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vcHJvZmlsZXIvSHByb2ZCaW5hcnlUb0FzY2lpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDZjNDQzZAotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vcHJvZmlsZXIvSHByb2ZCaW5hcnlUb0FzY2lpLmphdmEKQEAgLTAsMCArMSwxODIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5zeXN0ZW0ucHJvZmlsZXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5FT0ZFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworLyoqCisgKiBSdW4gb24gZGV2aWNlIHdpdGg6CisgKiBhZGIgc2hlbGwgZGFsdmlrdm0gJ2RhbHZpay5zeXN0ZW0ucHJvZmlsZXIuSHByb2ZCaW5hcnlUb0FzY2lpJworICoKKyAqIFJ1biBvbiBob3N0IHdpdGg6CisgKiBqYXZhIC1jbGFzc3BhdGggb3V0L3RhcmdldC9jb21tb24vb2JqL0pBVkFfTElCUkFSSUVTL2NvcmVfaW50ZXJtZWRpYXRlcy9jbGFzc2VzLmphcgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSHByb2ZCaW5hcnlUb0FzY2lpIHsKKworICAgIC8qKgorICAgICAqIE1haW4gZW50cnkgcG9pbnQgZm9yIEhwcm9mQmluYXJ5VG9Bc2NpaSBjb21tYW5kIGxpbmUgdG9vbAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgU3lzdGVtLmV4aXQoY29udmVydChhcmdzKSA/IDAgOiAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBzaW5nbGUgZmlsZSBmcm9tIGFyZ3VtZW50cyBhbmQgYXR0ZW1wdHMgdG8gcmVhZCBpdCBhcworICAgICAqIGVpdGhlciBhIGJpbmFyeSBocHJvZiBmaWxlIG9yIGEgdmVyc2lvbiB3aXRoIGEgdGV4dCBoZWFkZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBjb252ZXJ0KFN0cmluZ1tdIGFyZ3MpIHsKKworICAgICAgICBpZiAoYXJncy5sZW5ndGggIT0gMSkgeworICAgICAgICAgICAgdXNhZ2UoImJpbmFyeSBocHJvZiBmaWxlIGFyZ3VtZW50IGV4cGVjdGVkIik7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgRmlsZSBmaWxlID0gbmV3IEZpbGUoYXJnc1swXSk7CisgICAgICAgIGlmICghZmlsZS5leGlzdHMoKSkgeworICAgICAgICAgICAgdXNhZ2UoImZpbGUgIiArIGZpbGUgKyAiIGRvZXMgbm90IGV4aXN0Iik7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc3RhcnRzV2l0aE1hZ2ljKGZpbGUpKSB7CisgICAgICAgICAgICBIcHJvZkRhdGEgaHByb2ZEYXRhOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBocHJvZkRhdGEgPSByZWFkSHByb2YoZmlsZSk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJQcm9ibGVtIHJlYWRpbmcgYmluYXJ5IGhwcm9mIGRhdGEgZnJvbSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZmlsZSArICI6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHdyaXRlKGhwcm9mRGF0YSk7CisgICAgICAgIH0KKworICAgICAgICBIcHJvZkRhdGEgaHByb2ZEYXRhOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaHByb2ZEYXRhID0gcmVhZFNuYXBzaG90KGZpbGUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlByb2JsZW0gcmVhZGluZyBzbmFwc2hvdCBjb250YWluaW5nIGJpbmFyeSBocHJvZiBkYXRhIGZyb20gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZmlsZSArICI6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHdyaXRlKGhwcm9mRGF0YSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvYmUgdGhlIHN0YXJ0IG9mIGZpbGUgdG8gc2VlIGlmIGl0IHN0YXJ0cyB3aXRoIGEgcGxhdXNpYmxlCisgICAgICogYmluYXJ5IGhwcm9mIG1hZ2ljIHZhbHVlLiBJZiBzbywgaXQgaXMgcmV0dXJuZWQuIE9uIGFueSBvdGhlcgorICAgICAqIGNhc2UgaW5jbHVkaW5nIHVuZXhwZWN0ZWQgZXJyb3JzLCBmYWxzZSBpcyByZXR1cm5lZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHN0YXJ0c1dpdGhNYWdpYyhGaWxlIGZpbGUpIHsKKyAgICAgICAgRGF0YUlucHV0U3RyZWFtIGlucHV0U3RyZWFtID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlucHV0U3RyZWFtID0gbmV3IERhdGFJbnB1dFN0cmVhbShuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpKSk7CisgICAgICAgICAgICByZXR1cm4gQmluYXJ5SHByb2YucmVhZE1hZ2ljKGlucHV0U3RyZWFtKSAhPSBudWxsOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBjbG9zZVF1aWV0bHkoaW5wdXRTdHJlYW0pOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCBhbmQgcmV0dXJuIGFuIEhwcm9mRGF0YSBmcm9tIGEgdmFuaWxsYSBiaW5hcnkgaHByb2YgZmlsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBIcHJvZkRhdGEgcmVhZEhwcm9mKEZpbGUgZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0gPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5wdXRTdHJlYW0gPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpKTsKKyAgICAgICAgICAgIHJldHVybiByZWFkKGlucHV0U3RyZWFtKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGNsb3NlUXVpZXRseShpbnB1dFN0cmVhbSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGEgZmlsZSBsb29raW5nIGZvciB0ZXh0IGhlYWRlciB0ZXJtaW5hdGVkIGJ5IHR3byBuZXdsaW5lcywKKyAgICAgKiB0aGVuIHByb2NlZWQgdG8gcmVhZCBiaW5hcnkgaHByb2YgZGF0YS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBIcHJvZkRhdGEgcmVhZFNuYXBzaG90KEZpbGUgZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0gPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5wdXRTdHJlYW0gPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpKTsKKyAgICAgICAgICAgIGludCBjaDsKKyAgICAgICAgICAgIHdoaWxlICgoY2ggPSBpbnB1dFN0cmVhbS5yZWFkKCkpICE9IC0xKSB7CisgICAgICAgICAgICAgICAgaWYgKGNoID09ICdcbicgJiYgaW5wdXRTdHJlYW0ucmVhZCgpID09ICdcbicpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWQoaW5wdXRTdHJlYW0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oIkNvdWxkIG5vdCBmaW5kIGV4cGVjdGVkIGhlYWRlciIpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgY2xvc2VRdWlldGx5KGlucHV0U3RyZWFtKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgYmluYXJ5IGhwcm9mIGRhdGEgZnJvbSB0aGUgcHJvdmlkZWQgaW5wdXQgc3RyZWFtIGFuZAorICAgICAqIHJldHVybiB0aGUgSHByb2ZEYXRhIG9iamVjdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBIcHJvZkRhdGEgcmVhZChJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQmluYXJ5SHByb2ZSZWFkZXIgcmVhZGVyID0gbmV3IEJpbmFyeUhwcm9mUmVhZGVyKGlucHV0U3RyZWFtKTsKKyAgICAgICAgcmVhZGVyLnNldFN0cmljdChmYWxzZSk7CisgICAgICAgIHJlYWRlci5yZWFkKCk7CisgICAgICAgIHJldHVybiByZWFkZXIuZ2V0SHByb2ZEYXRhKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRnJvbSBJb1V0aWxzLmNsb3NlUXVpZXRseSBidXQgcmVwbGljYXRlZCBmb3Igb3BlbiBzb3VyY2UKKyAgICAgKiB2ZXJzaW9uLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY2xvc2VRdWlldGx5KENsb3NlYWJsZSBjKSB7CisgICAgICAgIGlmIChjICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGUgdGV4dCB2ZXJpb24gb2YgaHByb2YgZGF0YSB0byBzdGFuZGFyZCBvdXRwdXQuIFJldHVybnMKKyAgICAgKiBmYWxzZSBvbiBlcnJvci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHdyaXRlKEhwcm9mRGF0YSBocHJvZkRhdGEpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFzY2lpSHByb2ZXcml0ZXIud3JpdGUoaHByb2ZEYXRhLCBTeXN0ZW0ub3V0KTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJQcm9ibGVtIHdyaXRpbmcgQVNDSUkgaHByb2YgZGF0YTogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdXNhZ2UgZXJyb3IgYnV0IGRvZXMgbm90IGV4aXQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB1c2FnZShTdHJpbmcgZXJyb3IpIHsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludCgiRVJST1I6ICIpOworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oZXJyb3IpOworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJ1c2FnZTogSHByb2ZCaW5hcnlUb0FzY2lpIDxiaW5hcnktaHByb2YtZmlsZT4iKTsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUmVhZHMgYSBiaW5hcnkgaHByb2YgZmlsZSBhbmQgcHJpbnQgaXQgaW4gQVNDSUkgZm9ybWF0Iik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9wcm9maWxlci9IcHJvZkRhdGEuamF2YSBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vcHJvZmlsZXIvSHByb2ZEYXRhLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2I0NGJiOQotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vcHJvZmlsZXIvSHByb2ZEYXRhLmphdmEKQEAgLTAsMCArMSwzOTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5zeXN0ZW0ucHJvZmlsZXI7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXAuRW50cnk7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCisvKioKKyAqIFJlcHJlc2VudHMgc2FtcGxpbmcgcHJvZmlsZXIgZGF0YS4gQ2FuIGJlIGNvbnZlcnRlZCB0byBBU0NJSSBvcgorICogYmluYXJ5IGhwcm9mLXN0eWxlIG91dHB1dCB1c2luZyB7QGxpbmsgQXNjaWlIcHJvZldyaXRlcn0gb3IKKyAqIHtAbGluayBCaW5hcnlIcHJvZldyaXRlcn0uCisgKiA8cD4KKyAqIFRoZSBkYXRhIGluY2x1ZGVzOgorICogPHVsPgorICogPGxpPnRoZSBzdGFydCB0aW1lIG9mIHRoZSBsYXN0IHNhbXBsaW5nIHBlcmlvZAorICogPGxpPnRoZSBoaXN0b3J5IG9mIHRocmVhZCBzdGFydCBhbmQgZW5kIGV2ZW50cworICogPGxpPnN0YWNrIHRyYWNlcyB3aXRoIGZyZXF1ZW5jeSBjb3VudHMKKyAqIDx1bD4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEhwcm9mRGF0YSB7CisKKyAgICBwdWJsaWMgc3RhdGljIGVudW0gVGhyZWFkRXZlbnRUeXBlIHsgU1RBUlQsIEVORCB9OworCisgICAgLyoqCisgICAgICogVGhyZWFkRXZlbnQgcmVwcmVzZW50cyB0aHJlYWQgY3JlYXRpb24gYW5kIGRlYXRoIGV2ZW50cyBmb3IKKyAgICAgKiByZXBvcnRpbmcuIEl0IHByb3ZpZGVzIGEgcmVjb3JkIG9mIHRoZSB0aHJlYWQgYW5kIHRocmVhZCBncm91cAorICAgICAqIG5hbWVzIGZvciB0eWluZyBzYW1wbGVzIGJhY2sgdG8gdGhlaXIgc291cmNlIHRocmVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRocmVhZEV2ZW50IHsKKworICAgICAgICBwdWJsaWMgZmluYWwgVGhyZWFkRXZlbnRUeXBlIHR5cGU7CisgICAgICAgIHB1YmxpYyBmaW5hbCBpbnQgb2JqZWN0SWQ7CisgICAgICAgIHB1YmxpYyBmaW5hbCBpbnQgdGhyZWFkSWQ7CisgICAgICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgdGhyZWFkTmFtZTsKKyAgICAgICAgcHVibGljIGZpbmFsIFN0cmluZyBncm91cE5hbWU7CisgICAgICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgcGFyZW50R3JvdXBOYW1lOworCisgICAgICAgIHB1YmxpYyBzdGF0aWMgVGhyZWFkRXZlbnQgc3RhcnQoaW50IG9iamVjdElkLCBpbnQgdGhyZWFkSWQsIFN0cmluZyB0aHJlYWROYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBncm91cE5hbWUsIFN0cmluZyBwYXJlbnRHcm91cE5hbWUpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVGhyZWFkRXZlbnQoVGhyZWFkRXZlbnRUeXBlLlNUQVJULCBvYmplY3RJZCwgdGhyZWFkSWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocmVhZE5hbWUsIGdyb3VwTmFtZSwgcGFyZW50R3JvdXBOYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBzdGF0aWMgVGhyZWFkRXZlbnQgZW5kKGludCB0aHJlYWRJZCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBUaHJlYWRFdmVudChUaHJlYWRFdmVudFR5cGUuRU5ELCB0aHJlYWRJZCk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIFRocmVhZEV2ZW50KFRocmVhZEV2ZW50VHlwZSB0eXBlLCBpbnQgb2JqZWN0SWQsIGludCB0aHJlYWRJZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdGhyZWFkTmFtZSwgU3RyaW5nIGdyb3VwTmFtZSwgU3RyaW5nIHBhcmVudEdyb3VwTmFtZSkgeworICAgICAgICAgICAgaWYgKHRocmVhZE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidGhyZWFkTmFtZSA9PSBudWxsIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aGlzLnR5cGUgPSBUaHJlYWRFdmVudFR5cGUuU1RBUlQ7CisgICAgICAgICAgICB0aGlzLm9iamVjdElkID0gb2JqZWN0SWQ7CisgICAgICAgICAgICB0aGlzLnRocmVhZElkID0gdGhyZWFkSWQ7CisgICAgICAgICAgICB0aGlzLnRocmVhZE5hbWUgPSB0aHJlYWROYW1lOworICAgICAgICAgICAgdGhpcy5ncm91cE5hbWUgPSBncm91cE5hbWU7CisgICAgICAgICAgICB0aGlzLnBhcmVudEdyb3VwTmFtZSA9IHBhcmVudEdyb3VwTmFtZTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgVGhyZWFkRXZlbnQoVGhyZWFkRXZlbnRUeXBlIHR5cGUsIGludCB0aHJlYWRJZCkgeworICAgICAgICAgICAgdGhpcy50eXBlID0gVGhyZWFkRXZlbnRUeXBlLkVORDsKKyAgICAgICAgICAgIHRoaXMub2JqZWN0SWQgPSAtMTsKKyAgICAgICAgICAgIHRoaXMudGhyZWFkSWQgPSB0aHJlYWRJZDsKKyAgICAgICAgICAgIHRoaXMudGhyZWFkTmFtZSA9IG51bGw7CisgICAgICAgICAgICB0aGlzLmdyb3VwTmFtZSA9IG51bGw7CisgICAgICAgICAgICB0aGlzLnBhcmVudEdyb3VwTmFtZSA9IG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgICAgIGludCByZXN1bHQgPSAxNzsKKyAgICAgICAgICAgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgb2JqZWN0SWQ7CisgICAgICAgICAgICByZXN1bHQgPSAzMSAqIHJlc3VsdCArIHRocmVhZElkOworICAgICAgICAgICAgcmVzdWx0ID0gMzEgKiByZXN1bHQgKyBoYXNoQ29kZSh0aHJlYWROYW1lKTsKKyAgICAgICAgICAgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgaGFzaENvZGUoZ3JvdXBOYW1lKTsKKyAgICAgICAgICAgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgaGFzaENvZGUocGFyZW50R3JvdXBOYW1lKTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHN0YXRpYyBpbnQgaGFzaENvZGUoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIHJldHVybiAobyA9PSBudWxsKSA/IDAgOiBvLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgICAgICBpZiAoIShvIGluc3RhbmNlb2YgVGhyZWFkRXZlbnQpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgVGhyZWFkRXZlbnQgZXZlbnQgPSAoVGhyZWFkRXZlbnQpIG87CisgICAgICAgICAgICByZXR1cm4gKHRoaXMudHlwZSA9PSBldmVudC50eXBlCisgICAgICAgICAgICAgICAgICAgICYmIHRoaXMub2JqZWN0SWQgPT0gZXZlbnQub2JqZWN0SWQKKyAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy50aHJlYWRJZCA9PSBldmVudC50aHJlYWRJZAorICAgICAgICAgICAgICAgICAgICAmJiBlcXVhbCh0aGlzLnRocmVhZE5hbWUsIGV2ZW50LnRocmVhZE5hbWUpCisgICAgICAgICAgICAgICAgICAgICYmIGVxdWFsKHRoaXMuZ3JvdXBOYW1lLCBldmVudC5ncm91cE5hbWUpCisgICAgICAgICAgICAgICAgICAgICYmIGVxdWFsKHRoaXMucGFyZW50R3JvdXBOYW1lLCBldmVudC5wYXJlbnRHcm91cE5hbWUpKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gZXF1YWwoT2JqZWN0IGEsIE9iamVjdCBiKSB7CisgICAgICAgICAgICByZXR1cm4gYSA9PSBiIHx8IChhICE9IG51bGwgJiYgYS5lcXVhbHMoYikpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgICAgICAgICAgICBjYXNlIFNUQVJUOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVEhSRUFEIFNUQVJUIChvYmo9JWQsIGlkID0gJWQsIG5hbWU9XCIlc1wiLCBncm91cD1cIiVzXCIpIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3RJZCwgdGhyZWFkSWQsIHRocmVhZE5hbWUsIGdyb3VwTmFtZSk7CisgICAgICAgICAgICAgICAgY2FzZSBFTkQ6CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCJUSFJFQUQgRU5EIChpZCA9ICVkKSIsIHRocmVhZElkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24odHlwZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEEgdW5pcXVlIHN0YWNrIHRyYWNlIGZvciBhIHNwZWNpZmljIHRocmVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFN0YWNrVHJhY2UgeworCisgICAgICAgIHB1YmxpYyBmaW5hbCBpbnQgc3RhY2tUcmFjZUlkOworICAgICAgICBpbnQgdGhyZWFkSWQ7CisgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50W10gc3RhY2tGcmFtZXM7CisKKyAgICAgICAgU3RhY2tUcmFjZSgpIHsKKyAgICAgICAgICAgIHRoaXMuc3RhY2tUcmFjZUlkID0gLTE7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RhY2tUcmFjZShpbnQgc3RhY2tUcmFjZUlkLCBpbnQgdGhyZWFkSWQsIFN0YWNrVHJhY2VFbGVtZW50W10gc3RhY2tGcmFtZXMpIHsKKyAgICAgICAgICAgIGlmIChzdGFja0ZyYW1lcyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJzdGFja0ZyYW1lcyA9PSBudWxsIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aGlzLnN0YWNrVHJhY2VJZCA9IHN0YWNrVHJhY2VJZDsKKyAgICAgICAgICAgIHRoaXMudGhyZWFkSWQgPSB0aHJlYWRJZDsKKyAgICAgICAgICAgIHRoaXMuc3RhY2tGcmFtZXMgPSBzdGFja0ZyYW1lczsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0VGhyZWFkSWQoKSB7CisgICAgICAgICAgICByZXR1cm4gdGhyZWFkSWQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RhY2tUcmFjZUVsZW1lbnRbXSBnZXRTdGFja0ZyYW1lcygpIHsKKyAgICAgICAgICAgIHJldHVybiBzdGFja0ZyYW1lczsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgaW50IHJlc3VsdCA9IDE3OworICAgICAgICAgICAgcmVzdWx0ID0gMzEgKiByZXN1bHQgKyB0aHJlYWRJZDsKKyAgICAgICAgICAgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgQXJyYXlzLmhhc2hDb2RlKHN0YWNrRnJhbWVzKTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgICAgICBpZiAoIShvIGluc3RhbmNlb2YgU3RhY2tUcmFjZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTdGFja1RyYWNlIHMgPSAoU3RhY2tUcmFjZSkgbzsKKyAgICAgICAgICAgIHJldHVybiB0aHJlYWRJZCA9PSBzLnRocmVhZElkICYmIEFycmF5cy5lcXVhbHMoc3RhY2tGcmFtZXMsIHMuc3RhY2tGcmFtZXMpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIGZyYW1lcyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgICAgICBpZiAoc3RhY2tGcmFtZXMubGVuZ3RoID4gMCkgeworICAgICAgICAgICAgICAgIGZyYW1lcy5hcHBlbmQoJ1xuJyk7CisgICAgICAgICAgICAgICAgZm9yIChTdGFja1RyYWNlRWxlbWVudCBzdGFja0ZyYW1lIDogc3RhY2tGcmFtZXMpIHsKKyAgICAgICAgICAgICAgICAgICAgZnJhbWVzLmFwcGVuZCgiXHQgYXQgIik7CisgICAgICAgICAgICAgICAgICAgIGZyYW1lcy5hcHBlbmQoc3RhY2tGcmFtZSk7CisgICAgICAgICAgICAgICAgICAgIGZyYW1lcy5hcHBlbmQoJ1xuJyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmcmFtZXMuYXBwZW5kKCI8ZW1wdHk+Iik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gIlN0YWNrVHJhY2Vbc3RhY2tUcmFjZUlkPSIgKyBzdGFja1RyYWNlSWQKKyAgICAgICAgICAgICAgICAgICAgKyAiLCB0aHJlYWRJZD0iICsgdGhyZWFkSWQKKyAgICAgICAgICAgICAgICAgICAgKyAiLCBmcmFtZXM9IiArIGZyYW1lcyArICJdIjsKKworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQSByZWFkIG9ubHkgY29udGFpbmVyIGNvbWJpbmluZyBhIHN0YWNrIHRyYWNlIHdpdGggaXRzIGZyZXF1ZW5jeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFNhbXBsZSB7CisKKyAgICAgICAgcHVibGljIGZpbmFsIFN0YWNrVHJhY2Ugc3RhY2tUcmFjZTsKKyAgICAgICAgcHVibGljIGZpbmFsIGludCBjb3VudDsKKworICAgICAgICBwcml2YXRlIFNhbXBsZShTdGFja1RyYWNlIHN0YWNrVHJhY2UsIGludCBjb3VudCkgeworICAgICAgICAgICAgaWYgKHN0YWNrVHJhY2UgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigic3RhY2tUcmFjZSA9PSBudWxsIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY291bnQgPCAwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiY291bnQgPCAwOiIgKyBjb3VudCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aGlzLnN0YWNrVHJhY2UgPSBzdGFja1RyYWNlOworICAgICAgICAgICAgdGhpcy5jb3VudCA9IGNvdW50OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICBpbnQgcmVzdWx0ID0gMTc7CisgICAgICAgICAgICByZXN1bHQgPSAzMSAqIHJlc3VsdCArIHN0YWNrVHJhY2UuaGFzaENvZGUoKTsKKyAgICAgICAgICAgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgY291bnQ7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICAgICAgaWYgKCEobyBpbnN0YW5jZW9mIFNhbXBsZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTYW1wbGUgcyA9IChTYW1wbGUpIG87CisgICAgICAgICAgICByZXR1cm4gY291bnQgPT0gcy5jb3VudCAmJiBzdGFja1RyYWNlLmVxdWFscyhzLnN0YWNrVHJhY2UpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICByZXR1cm4gIlNhbXBsZVtjb3VudD0iICsgY291bnQgKyAiICIgKyBzdGFja1RyYWNlICsgIl0iOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdGFydCBvZiBsYXN0IHNhbXBsaW5nIHBlcmlvZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGxvbmcgc3RhcnRNaWxsaXM7CisKKyAgICAvKioKKyAgICAgKiBDT05UUk9MX1NFVFRJTkdTIGZsYWdzCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgZmxhZ3M7CisKKyAgICAvKioKKyAgICAgKiBzdGFjayBzYW1wbGluZyBkZXB0aAorICAgICAqLworICAgIHByaXZhdGUgaW50IGRlcHRoOworCisgICAgLyoqCisgICAgICogTGlzdCBvZiB0aHJlYWQgY3JlYXRpb24gYW5kIGRlYXRoIGV2ZW50cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8VGhyZWFkRXZlbnQ+IHRocmVhZEhpc3RvcnkgPSBuZXcgQXJyYXlMaXN0PFRocmVhZEV2ZW50PigpOworCisgICAgLyoqCisgICAgICogTWFwIG9mIHRocmVhZCBpZCB0byBhIHN0YXJ0IFRocmVhZEV2ZW50CisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBNYXA8SW50ZWdlciwgVGhyZWFkRXZlbnQ+IHRocmVhZElkVG9UaHJlYWRFdmVudAorICAgICAgICAgICAgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBUaHJlYWRFdmVudD4oKTsKKworICAgIC8qKgorICAgICAqIE1hcCBvZiBzdGFjayB0cmFjZXMgdG8gYSBtdXRhYmxlIHNhbXBsZSBjb3VudC4gVGhlIG1hcCBpcworICAgICAqIHByb3ZpZGVkIGJ5IHRoZSBjcmVhdG9yIG9mIHRoZSBIcHJvZkRhdGEgc28gb25seSBoYXZlCisgICAgICogbXV0YWJsZSBhY2Nlc3MgdG8gdGhlIGludFtdIGNlbGxzIHRoYXQgY29udGFpbiB0aGUgc2FtcGxlCisgICAgICogY291bnQuIE9ubHkgYW4gdW5tb2RpZmlhYmxlIGl0ZXJhdG9yIHZpZXcgaXMgYXZhaWxhYmxlIHRvCisgICAgICogdXNlcnMgb2YgdGhlIEhwcm9mRGF0YS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIE1hcDxIcHJvZkRhdGEuU3RhY2tUcmFjZSwgaW50W10+IHN0YWNrVHJhY2VzOworCisgICAgcHVibGljIEhwcm9mRGF0YShNYXA8U3RhY2tUcmFjZSwgaW50W10+IHN0YWNrVHJhY2VzKSB7CisgICAgICAgIGlmIChzdGFja1RyYWNlcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInN0YWNrVHJhY2VzID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnN0YWNrVHJhY2VzID0gc3RhY2tUcmFjZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIHN0YXJ0IHRpbWUgaW4gbWlsbGlzZWNvbmRzIG9mIHRoZSBsYXN0IHByb2ZpbGluZyBwZXJpb2QuCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0U3RhcnRNaWxsaXMoKSB7CisgICAgICAgIHJldHVybiBzdGFydE1pbGxpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHRpbWUgZm9yIHRoZSBzdGFydCBvZiB0aGUgY3VycmVudCBzYW1wbGluZyBwZXJpb2QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3RhcnRNaWxsaXMobG9uZyBzdGFydE1pbGxpcykgeworICAgICAgICB0aGlzLnN0YXJ0TWlsbGlzID0gc3RhcnRNaWxsaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSB7QGxpbmsgQmluYXJ5SHByb2YuQ29udHJvbFNldHRpbmdzfSBmbGFncworICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RmxhZ3MoKSB7CisgICAgICAgIHJldHVybiBmbGFnczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHtAbGluayBCaW5hcnlIcHJvZi5Db250cm9sU2V0dGluZ3N9IGZsYWdzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RmxhZ3MoaW50IGZsYWdzKSB7CisgICAgICAgIHRoaXMuZmxhZ3MgPSBmbGFnczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHN0YWNrIHNhbXBsaW5nIGRlcHRoCisgICAgICovCisgICAgcHVibGljIGludCBnZXREZXB0aCgpIHsKKyAgICAgICAgcmV0dXJuIGRlcHRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgc3RhY2sgc2FtcGxpbmcgZGVwdGgKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREZXB0aChpbnQgZGVwdGgpIHsKKyAgICAgICAgdGhpcy5kZXB0aCA9IGRlcHRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhbiB1bm1vZGlmaWFibGUgaGlzdG9yeSBvZiBzdGFydCBhbmQgZW5kIHRocmVhZCBldmVudHMuCisgICAgICovCisgICAgcHVibGljIExpc3Q8VGhyZWFkRXZlbnQ+IGdldFRocmVhZEhpc3RvcnkoKSB7CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHRocmVhZEhpc3RvcnkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIG5ldyBzZXQgY29udGFpbmluZyB0aGUgY3VycmVudCBzYW1wbGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2V0PFNhbXBsZT4gZ2V0U2FtcGxlcygpIHsKKyAgICAgICAgU2V0PFNhbXBsZT4gc2FtcGxlcyA9IG5ldyBIYXNoU2V0PFNhbXBsZT4oc3RhY2tUcmFjZXMuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChFbnRyeTxTdGFja1RyYWNlLCBpbnRbXT4gZSA6IHN0YWNrVHJhY2VzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIFN0YWNrVHJhY2Ugc3RhY2tUcmFjZSA9IGUuZ2V0S2V5KCk7CisgICAgICAgICAgICBpbnQgY291bnRDZWxsW10gPSBlLmdldFZhbHVlKCk7CisgICAgICAgICAgICBpbnQgY291bnQgPSBjb3VudENlbGxbMF07CisgICAgICAgICAgICBTYW1wbGUgc2FtcGxlID0gbmV3IFNhbXBsZShzdGFja1RyYWNlLCBjb3VudCk7CisgICAgICAgICAgICBzYW1wbGVzLmFkZChzYW1wbGUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzYW1wbGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlY29yZCBhbiBldmVudCBpbiB0aGUgdGhyZWFkIGhpc3RvcnkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkVGhyZWFkRXZlbnQoVGhyZWFkRXZlbnQgZXZlbnQpIHsKKyAgICAgICAgaWYgKGV2ZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiZXZlbnQgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIFRocmVhZEV2ZW50IG9sZCA9IHRocmVhZElkVG9UaHJlYWRFdmVudC5wdXQoZXZlbnQudGhyZWFkSWQsIGV2ZW50KTsKKyAgICAgICAgc3dpdGNoIChldmVudC50eXBlKSB7CisgICAgICAgICAgICBjYXNlIFNUQVJUOgorICAgICAgICAgICAgICAgIGlmIChvbGQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJUaHJlYWRFdmVudCBhbHJlYWR5IHJlZ2lzdGVyZWQgZm9yIGlkICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGV2ZW50LnRocmVhZElkKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIEVORDoKKyAgICAgICAgICAgICAgICAvLyBEbyBub3QgYXNzZXJ0IHRoYXQgdGhlIEVORF9USFJFQUQgbWF0Y2hlcyBhCisgICAgICAgICAgICAgICAgLy8gU1RBUlRfVEhSRUFEIHVubGVzcyBpbiBzdHJpY3QgbW9kZS4gV2hpbGUgdGhoaXMKKyAgICAgICAgICAgICAgICAvLyBob2xkIHRydWUgaW4gdGhlIGJpbmFyeSBocHJvZiBCaW5hcnlIcHJvZldyaXRlcgorICAgICAgICAgICAgICAgIC8vIHByb2R1Y2VzLCBpdCBpcyBub3QgdHJ1ZSBvZiBocHJvZiBmaWxlcyBjcmVhdGVkCisgICAgICAgICAgICAgICAgLy8gYnkgdGhlIFJJLiBIb3dldmVyLCBpZiB0aGVyZSBpcyBhbiBldmVudAorICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgcmVnaXN0ZWQgZm9yIGEgdGhyZWFkIGlkLCBpdCBzaG91bGQgYmUKKyAgICAgICAgICAgICAgICAvLyB0aGUgbWF0Y2hpbmcgc3RhcnQsIG5vdCBhIGR1cGxpY2F0ZSBlbmQuCisgICAgICAgICAgICAgICAgaWYgKG9sZCAhPSBudWxsICYmIG9sZC50eXBlID09IFRocmVhZEV2ZW50VHlwZS5FTkQpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRHVwbGljYXRlIFRocmVhZEV2ZW50LmVuZCBmb3IgaWQgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZXZlbnQudGhyZWFkSWQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICB0aHJlYWRIaXN0b3J5LmFkZChldmVudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVjb3JkIGFuIHN0YWNrIHRyYWNlIGFuZCBhbiBhc3NvY2lhdGVkIGludFtdIGNlbGwgb2YKKyAgICAgKiBzYW1wbGUgY291bmQgZm9yIHRoZSBzdGFjayB0cmFjZS4gVGhlIGNhbGxlciBpcyBhbGxvd2VkCisgICAgICogcmV0YWluIGEgcG9pbnRlciB0byB0aGUgY2VsbCB0byB1cGRhdGUgdGhlIGNvdW50LiBUaGUKKyAgICAgKiBTYW1wbGluZ1Byb2ZpbGVyIGludGVudGlvbmFsbHkgZG9lcyBub3QgcHJlc2VudCBhIG11dGFibGUKKyAgICAgKiB2aWV3IG9mIHRoZSBjb3VudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRTdGFja1RyYWNlKFN0YWNrVHJhY2Ugc3RhY2tUcmFjZSwgaW50W10gY291bnRDZWxsKSB7CisgICAgICAgIGlmICghdGhyZWFkSWRUb1RocmVhZEV2ZW50LmNvbnRhaW5zS2V5KHN0YWNrVHJhY2UudGhyZWFkSWQpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbmtub3duIHRocmVhZCBpZCAiICsgc3RhY2tUcmFjZS50aHJlYWRJZCk7CisgICAgICAgIH0KKyAgICAgICAgaW50W10gb2xkID0gc3RhY2tUcmFjZXMucHV0KHN0YWNrVHJhY2UsIGNvdW50Q2VsbCk7CisgICAgICAgIGlmIChvbGQgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiU3RhY2tUcmFjZSBhbHJlYWR5IHJlZ2lzdGVyZWQgZm9yIGlkICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzdGFja1RyYWNlLnN0YWNrVHJhY2VJZCArICI6XG4iICsgc3RhY2tUcmFjZSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL3Byb2ZpbGVyL01hbGZvcm1lZEhwcm9mRXhjZXB0aW9uLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL3Byb2ZpbGVyL01hbGZvcm1lZEhwcm9mRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjQwOTdiMgotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vcHJvZmlsZXIvTWFsZm9ybWVkSHByb2ZFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDM1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBkYWx2aWsuc3lzdGVtLnByb2ZpbGVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworcHVibGljIGZpbmFsIGNsYXNzIE1hbGZvcm1lZEhwcm9mRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODU1ODk5MDIzNzA0Nzg5NDIxM0w7CisKKyAgICBNYWxmb3JtZWRIcHJvZkV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICB9CisgICAgTWFsZm9ybWVkSHByb2ZFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlLCBjYXVzZSk7CisgICAgfQorICAgIE1hbGZvcm1lZEhwcm9mRXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL3Byb2ZpbGVyL1BvcnRhYmxlVGhyZWFkU2FtcGxlci5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9wcm9maWxlci9Qb3J0YWJsZVRocmVhZFNhbXBsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NmUwYjI3Ci0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9wcm9maWxlci9Qb3J0YWJsZVRocmVhZFNhbXBsZXIuamF2YQpAQCAtMCwwICsxLDQzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBkYWx2aWsuc3lzdGVtLnByb2ZpbGVyOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBUaHJlYWRTYW1wbGVyIGltcGxlbWVudGF0aW9uIHRoYXQgb25seSB1c2VzIFRocmVhZC5nZXRTdGFja1RyYWNlKCkKKyAqIGFuZCB0aGVyZWZvcmUgaXMgcG9ydGFibGUuCisgKi8KK2NsYXNzIFBvcnRhYmxlVGhyZWFkU2FtcGxlciBpbXBsZW1lbnRzIFRocmVhZFNhbXBsZXIgeworCisgICAgcHJpdmF0ZSBpbnQgZGVwdGg7CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2V0RGVwdGgoaW50IGRlcHRoKSB7CisgICAgICAgIHRoaXMuZGVwdGggPSBkZXB0aDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0YWNrVHJhY2VFbGVtZW50W10gZ2V0U3RhY2tUcmFjZShUaHJlYWQgdGhyZWFkKSB7CisgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50W10gc3RhY2tGcmFtZXMgPSB0aHJlYWQuZ2V0U3RhY2tUcmFjZSgpOworICAgICAgICBpZiAoc3RhY2tGcmFtZXMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGlmIChzdGFja0ZyYW1lcy5sZW5ndGggPiBkZXB0aCkgeworICAgICAgICAgICAgc3RhY2tGcmFtZXMgPSBBcnJheXMuY29weU9mUmFuZ2Uoc3RhY2tGcmFtZXMsIDAsIGRlcHRoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3RhY2tGcmFtZXM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9wcm9maWxlci9TYW1wbGluZ1Byb2ZpbGVyLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9kYWx2aWsvc3lzdGVtL3Byb2ZpbGVyL1NhbXBsaW5nUHJvZmlsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMjY2MTAzCi0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9wcm9maWxlci9TYW1wbGluZ1Byb2ZpbGVyLmphdmEKQEAgLTAsMCArMSw0OTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5zeXN0ZW0ucHJvZmlsZXI7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZXI7CitpbXBvcnQgamF2YS51dGlsLlRpbWVyVGFzazsKKworLyoqCisgKiBBIHNhbXBsaW5nIHByb2ZpbGVyLiBJdCBjdXJyZW50bHkgaXMgaW1wbGVtZW50ZWQgd2l0aG91dCBhbnkKKyAqIHZpcnR1YWwgbWFjaGluZSBzdXBwb3J0LCByZWx5aW5nIHNvbGVseSBvbiB7QGNvZGUKKyAqIFRocmVhZC5nZXRTdGFja1RyYWNlfSB0byBjb2xsZWN0IHNhbXBsZXMuIEFzIHN1Y2gsIHRoZSBvdmVyaGVhZCBpcworICogaGlnaGVyIHRoYW4gYSBuYXRpdmUgYXBwcm9hY2ggYW5kIGl0IGRvZXMgbm90IHByb3ZpZGUgaW5zaWdodCBpbnRvCisgKiB3aGVyZSB0aW1lIGlzIHNwZW50IHdpdGhpbiBuYXRpdmUgY29kZSwgYnV0IGl0IGNhbiBzdGlsbCBwcm92aWRlCisgKiB1c2VmdWwgaW5zaWdodCBpbnRvIHdoZXJlIGEgcHJvZ3JhbSBpcyBzcGVuZGluZyB0aW1lLgorICoKKyAqIDxoMz5Vc2FnZSBFeGFtcGxlPC9oMz4KKyAqCisgKiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgc2hvd3MgaG93IHRvIHVzZSB0aGUge0Bjb2RlCisgKiBTYW1wbGluZ1Byb2ZpbGVyfS4gSXQgc2FtcGxlcyB0aGUgY3VycmVudCB0aHJlYWQncyBzdGFjayB0byBhIGRlcHRoCisgKiBvZiAxMiBzdGFjayBmcmFtZSBlbGVtZW50cyBvdmVyIHR3byBkaWZmZXJlbnQgbWVhc3VyZW1lbnQgcGVyaW9kcworICogd2l0aCBzYW1wbGVzIHRha2VuIGV2ZXJ5IDEwMCBtaWxsaXNlY29uZHMuIEluIHRoZW4gcHJpbnRzIHRoZQorICogcmVzdWx0cyBpbiBocHJvZiBmb3JtYXQgdG8gdGhlIHN0YW5kYXJkIG91dHB1dC4KKyAqCisgKiA8cHJlPiB7QGNvZGUKKyAqIFRocmVhZFNldCB0aHJlYWRTZXQgPSBTYW1wbGluZ1Byb2ZpbGVyLm5ld0FycmF5VGhyZWFkU2V0KFRocmVhZC5jdXJyZW50VGhyZWFkKCkpOworICogU2FtcGxpbmdQcm9maWxlciBwcm9maWxlciA9IG5ldyBTYW1wbGluZ1Byb2ZpbGVyKDEyLCB0aHJlYWRTZXQpOworICogcHJvZmlsZXIuc3RhcnQoMTAwKTsKKyAqIC8vIHBlcmlvZCBvZiBtZWFzdXJlbWVudAorICogcHJvZmlsZXIuc3RvcCgpOworICogLy8gcGVyaW9kIG9mIG5vbi1tZWFzdXJlbWVudAorICogcHJvZmlsZXIuc3RhcnQoMTAwKTsKKyAqIC8vIGFub3RoZXIgcGVyaW9kIG9mIG1lYXN1cmVtZW50CisgKiBwcm9maWxlci5zdG9wKCk7CisgKiBwcm9maWxlci5zaHV0ZG93bigpOworICogQXNjaWlIcHJvZldyaXRlci53cml0ZShwcm9maWxlci5nZXRIcHJvZkRhdGEoKSwgU3lzdGVtLm91dCk7CisgKiB9PC9wcmU+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTYW1wbGluZ1Byb2ZpbGVyIHsKKworICAgIC8qKgorICAgICAqIE1hcCBvZiBzdGFjayB0cmFjZXMgdG8gYSBtdXRhYmxlIHNhbXBsZSBjb3VudC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIE1hcDxIcHJvZkRhdGEuU3RhY2tUcmFjZSwgaW50W10+IHN0YWNrVHJhY2VzCisgICAgICAgICAgICA9IG5ldyBIYXNoTWFwPEhwcm9mRGF0YS5TdGFja1RyYWNlLCBpbnRbXT4oKTsKKworICAgIC8qKgorICAgICAqIERhdGEgY29sbGVjdGVkIGJ5IHRoZSBzYW1wbGluZyBwcm9maWxlcgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgSHByb2ZEYXRhIGhwcm9mRGF0YSA9IG5ldyBIcHJvZkRhdGEoc3RhY2tUcmFjZXMpOworCisgICAgLyoqCisgICAgICogVGltZXIgdGhhdCBpcyB1c2VkIGZvciB0aGUgbGlmZXRpbWUgb2YgdGhlIHByb2ZpbGVyCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBUaW1lciB0aW1lciA9IG5ldyBUaW1lcigiU2FtcGxpbmdQcm9maWxlciIsIHRydWUpOworCisgICAgLyoqCisgICAgICogQSBzYW1wbGVyIGlzIGNyZWF0ZWQgZXZlcnkgdGltZSBwcm9maWxpbmcgc3RhcnRzIGFuZCBjbGVhcmVkCisgICAgICogZXZlcnl0aW1lIHByb2ZpbGluZyBzdG9wcyBiZWNhdXNlIG9uY2UgYSB7QGNvZGUgVGltZXJUYXNrfSBpcworICAgICAqIGNhbmNlbGVkIGl0IGNhbm5vdCBiZSByZXVzZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBTYW1wbGVyIHNhbXBsZXI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF4aW11bSBudW1iZXIgb2Yge0Bjb2RlIFN0YWNrVHJhY2VFbGVtZW50c30gdG8gcmV0YWluIGluCisgICAgICogZWFjaCBzdGFjay4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBkZXB0aDsKKworICAgIC8qKgorICAgICAqIFRoZSB7QGNvZGUgVGhyZWFkU2V0fSB0aGF0IGlkZW50aWZpZXMgd2hpY2ggdGhyZWFkcyB0byBzYW1wbGUuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBUaHJlYWRTZXQgdGhyZWFkU2V0OworCisgICAgLyoKKyAgICAgKiAgUmVhbCBocHJvZiBvdXRwdXQgZXhhbXBsZXMgZG9uJ3Qgc3RhcnQgdGhlIHRocmVhZCBhbmQgdHJhY2UKKyAgICAgKiAgaWRlbnRpZmllcnMgYXQgb25lIGJ1dCBzZWVtIHRvIHN0YXJ0IGF0IHRoZXNlIGFyYml0cmFyeQorICAgICAqICBjb25zdGFudHMuIEl0IGNlcnRhaW5seSBzZWVtcyB1c2VmdWwgdG8gaGF2ZSByZWxhdGl2ZWx5IHVuaXF1ZQorICAgICAqICBpZGVudGlmZXJzIHdoZW4gbWFudWFsIHNlYXJjaGluZyBocHJvZiBvdXRwdXQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbmV4dFRocmVhZElkID0gMjAwMDAxOworICAgIHByaXZhdGUgaW50IG5leHRTdGFja1RyYWNlSWQgPSAzMDAwMDE7CisgICAgcHJpdmF0ZSBpbnQgbmV4dE9iamVjdElkID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSB0aHJlYWRzIGN1cnJlbnRseSBrbm93biB0byB0aGUgcHJvZmlsZXIgZm9yIGRldGVjdGluZworICAgICAqIHRocmVhZCBzdGFydCBhbmQgZW5kIGV2ZW50cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIFRocmVhZFtdIGN1cnJlbnRUaHJlYWRzID0gbmV3IFRocmVhZFswXTsKKworICAgIC8qKgorICAgICAqIE1hcCBvZiBjdXJyZW50bHkgYWN0aXZlIHRocmVhZHMgdG8gdGhlaXIgaWRlbnRpZmllcnMuIFdoZW4KKyAgICAgKiB0aHJlYWRzIGRpc2FwcGVhciB0aGV5IGFyZSByZW1vdmVkIGFuZCBvbmx5IHJlZmVyZW5jZWQgYnkgdGhlaXIKKyAgICAgKiBpZGVudGlmaWVycyB0byBwcmV2ZW50IHJldGFpbmluZyBnYXJiYWdlIHRocmVhZHMuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBNYXA8VGhyZWFkLCBJbnRlZ2VyPiB0aHJlYWRJZHMgPSBuZXcgSGFzaE1hcDxUaHJlYWQsIEludGVnZXI+KCk7CisKKyAgICAvKioKKyAgICAgKiBNdXRhYmxlIHtAY29kZSBTdGFja1RyYWNlfSB0aGF0IGlzIHVzZWQgZm9yIHByb2JpbmcgdGhlIHtAbGluaworICAgICAqICNzdGFja1RyYWNlcyBzdGFja1RyYWNlc30gbWFwIHdpdGhvdXQgYWxsb2NhdGluZyBhIHtAY29kZQorICAgICAqIFN0YWNrVHJhY2V9LiBJZiB7QGxpbmsgI2FkZFN0YWNrVHJhY2UgYWRkU3RhY2tUcmFjZX0gbmVlZHMgdG8KKyAgICAgKiBiZSB0aHJlYWQgc2FmZSwgaGF2ZSBhIHNpbmdsZSBtdXRhYmxlIGluc3RhbmNlIHdvdWxkIG5lZWQgdG8gYmUKKyAgICAgKiByZWNvbnNpZGVyZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBIcHJvZkRhdGEuU3RhY2tUcmFjZSBtdXRhYmxlU3RhY2tUcmFjZSA9IG5ldyBIcHJvZkRhdGEuU3RhY2tUcmFjZSgpOworCisgICAgLyoqCisgICAgICogVGhlIHtAY29kZSBUaHJlYWRTYW1wbGVyfSBpcyB1c2VkIHRvIHByb2R1Y2UgYSB7QGNvZGUKKyAgICAgKiBTdGFja1RyYWNlRWxlbWVudH0gYXJyYXkgZm9yIGEgZ2l2ZW4gdGhyZWFkLiBUaGUgYXJyYXkgaXMKKyAgICAgKiBleHBlY3RlZCB0byBiZSB7QGxpbmsgI2RlcHRoIGRlcHRofSBvciBsZXNzIGluIGxlbmd0aC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFRocmVhZFNhbXBsZXIgdGhyZWFkU2FtcGxlcjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIHNhbXBsaW5nIHByb2ZpbGVyIHRoYXQgY29sbGVjdHMgc3RhY2tzIHdpdGggdGhlCisgICAgICogc3BlY2lmaWVkIGRlcHRoIGZyb20gdGhlIHRocmVhZHMgc3BlY2lmaWVkIGJ5IHRoZSBzcGVjaWZpZWQKKyAgICAgKiB0aHJlYWQgY29sbGVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGRlcHRoIFRoZSBtYXhpbXVtIHN0YWNrIGRlcHRoIHRvIHJldGFpbiBmb3IgZWFjaCBzYW1wbGUKKyAgICAgKiBzaW1pbGFyIHRvIHRoZSBocHJvZiBvcHRpb24gb2YgdGhlIHNhbWUgbmFtZS4gQW55IHN0YWNrIGRlZXBlcgorICAgICAqIHRoYW4gdGhpcyB3aWxsIGJlIHRydW5jYXRlZCB0byB0aGlzIGRlcHRoLiBBIGdvb2Qgc3RhcnRpbmcKKyAgICAgKiB2YWx1ZSBpcyA0IGFsdGhvdWdoIGl0IGlzIG5vdCB1bmNvbW1vbiB0byBuZWVkIHRvIHJhaXNlIHRoaXMgdG8KKyAgICAgKiBnZXQgZW5vdWdoIGNvbnRleHQgdG8gdW5kZXJzdGFuZCBwcm9ncmFtIGJlaGF2aW9yLiBXaGlsZQorICAgICAqIHByb2dyYW1zIHdpdGggZXh0ZW5zaXZlIHJlY3Vyc2lvbiBtYXkgcmVxdWlyZSBhIGhpZ2ggdmFsdWUgZm9yCisgICAgICogZGVwdGgsIHNpbXBseSBwYXNzaW5nIGluIGEgdmFsdWUgZm9yIEludGVnZXIuTUFYX1ZBTFVFIGlzIG5vdAorICAgICAqIGFkdmlzZWQgYmVjYXVzZSBvZiB0aGUgc2lnbmlmaWNhbnQgbWVtb3J5IG5lZWQgdG8gcmV0YWluIHN1Y2gKKyAgICAgKiBzdGFja3MgYW5kIHJ1bnRpbWUgb3ZlcmhlYWQgdG8gY29tcGFyZSBzdGFja3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhyZWFkU2V0IFRoZSB0aHJlYWQgc2V0IHNwZWNpZmllcyB3aGljaCB0aHJlYWRzIHRvCisgICAgICogc2FtcGxlLiBJbiBhIGdlbmVyYWwgcHVycG9zZSBwcm9ncmFtLCBhbGwgdGhyZWFkcyB0eXBpY2FsbHkKKyAgICAgKiBzaG91bGQgYmUgc2FtcGxlIHdpdGggYSBUaHJlYWRTZXQgc3VjaCBhcyBwcm92aWVkIGJ5IHtAbGluaworICAgICAqICNuZXdUaHJlYWRHcm91cFRoZWFkU2V0IG5ld1RocmVhZEdyb3VwVGhlYWRTZXR9LiBGb3IgYQorICAgICAqIGJlbmNobWFyayBhIGZpeGVkIHNldCBzdWNoIGFzIHByb3ZpZWQgYnkge0BsaW5rCisgICAgICogI25ld0FycmF5VGhyZWFkU2V0IG5ld0FycmF5VGhyZWFkU2V0fSBjYW4gcmVkdWNlIHRoZSBvdmVyaGVhZAorICAgICAqIG9mIHByb2ZpbGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2FtcGxpbmdQcm9maWxlcihpbnQgZGVwdGgsIFRocmVhZFNldCB0aHJlYWRTZXQpIHsKKyAgICAgICAgdGhpcy5kZXB0aCA9IGRlcHRoOworICAgICAgICB0aGlzLnRocmVhZFNldCA9IHRocmVhZFNldDsKKyAgICAgICAgdGhpcy50aHJlYWRTYW1wbGVyID0gZmluZERlZmF1bHRUaHJlYWRTYW1wbGVyKCk7CisgICAgICAgIHRocmVhZFNhbXBsZXIuc2V0RGVwdGgoZGVwdGgpOworICAgICAgICBocHJvZkRhdGEuc2V0RmxhZ3MoQmluYXJ5SHByb2YuQ29udHJvbFNldHRpbmdzLkNQVV9TQU1QTElORy5iaXRtYXNrKTsKKyAgICAgICAgaHByb2ZEYXRhLnNldERlcHRoKGRlcHRoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBUaHJlYWRTYW1wbGVyIGZpbmREZWZhdWx0VGhyZWFkU2FtcGxlcigpIHsKKyAgICAgICAgaWYgKCJEYWx2aWsgQ29yZSBMaWJyYXJ5Ii5lcXVhbHMoU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLnNwZWNpZmljYXRpb24ubmFtZSIpKSkgeworICAgICAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9ICJkYWx2aWsuc3lzdGVtLnByb2ZpbGVyLkRhbHZpa1RocmVhZFNhbXBsZXIiOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gKFRocmVhZFNhbXBsZXIpIENsYXNzLmZvck5hbWUoY2xhc3NOYW1lKS5uZXdJbnN0YW5jZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlByb2JsZW0gY3JlYXRpbmcgIiArIGNsYXNzTmFtZSArICI6ICIgKyBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFBvcnRhYmxlVGhyZWFkU2FtcGxlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgVGhyZWFkU2V0IHNwZWNpZmllcyB0aGUgc2V0IG9mIHRocmVhZHMgdG8gc2FtcGxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50ZXJmYWNlIFRocmVhZFNldCB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIHRocmVhZHMgdG8gYmUgc2FtcGxlZC4gVGhlCisgICAgICAgICAqIGFycmF5IG1heSBiZSBsb25nZXIgdGhhbiB0aGUgbnVtYmVyIG9mIHRocmVhZHMgdG8gYmUKKyAgICAgICAgICogc2FtcGxlZCwgaW4gd2hpY2ggY2FzZSB0aGUgZXh0cmEgZWxlbWVudHMgbXVzdCBiZSBudWxsLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFRocmVhZFtdIHRocmVhZHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgVGhyZWFkU2V0IGZvciBhIGZpeGVkIHNldCBvZiB0aHJlYWRzIHRoYXQgd2lsbCBub3QKKyAgICAgKiB2YXJ5IGF0IHJ1bnRpbWUuIFRoaXMgaGFzIGxlc3Mgb3ZlcmhlYWQgdGhhbiBhIGR5bmFtaWNhbGx5CisgICAgICogY2FsY3VsYXRlZCBzZXQsIHN1Y2ggYXMge0BsaW5rICNuZXdUaHJlYWRHcm91cFRoZWFkU2V0fSwgd2hpY2ggaGFzCisgICAgICogdG8gZW51bWVyYXRlIHRoZSB0aHJlYWRzIGVhY2ggdGltZSBwcm9maWxlciB3YW50cyB0byBjb2xsZWN0CisgICAgICogc2FtcGxlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFRocmVhZFNldCBuZXdBcnJheVRocmVhZFNldChUaHJlYWQuLi4gdGhyZWFkcykgeworICAgICAgICByZXR1cm4gbmV3IEFycmF5VGhyZWFkU2V0KHRocmVhZHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFuIEFycmF5VGhyZWFkU2V0IHNhbXBsZXMgYSBmaXhlZCBzZXQgb2YgdGhyZWFkcyB0aGF0IGRvZXMgbm90CisgICAgICogdmFyeSBvdmVyIHRoZSBsaWZlIG9mIHRoZSBwcm9maWxlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBBcnJheVRocmVhZFNldCBpbXBsZW1lbnRzIFRocmVhZFNldCB7CisgICAgICAgIHByaXZhdGUgZmluYWwgVGhyZWFkW10gdGhyZWFkczsKKyAgICAgICAgcHVibGljIEFycmF5VGhyZWFkU2V0KFRocmVhZC4uLiB0aHJlYWRzKSB7CisgICAgICAgICAgICBpZiAodGhyZWFkcyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ0aHJlYWRzID09IG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMudGhyZWFkcyA9IHRocmVhZHM7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIFRocmVhZFtdIHRocmVhZHMoKSB7CisgICAgICAgICAgICByZXR1cm4gdGhyZWFkczsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBUaHJlYWRTZXQgdGhhdCBpcyBkeW5hbWljYWxseSBjb21wdXRlZCBiYXNlZCBvbiB0aGUKKyAgICAgKiB0aHJlYWRzIGZvdW5kIGluIHRoZSBzcGVjaWZpZWQgVGhyZWFkR3JvdXAgYW5kIHRoYXQKKyAgICAgKiBUaHJlYWRHcm91cCdzIGNoaWxkcmVuLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVGhyZWFkU2V0IG5ld1RocmVhZEdyb3VwVGhlYWRTZXQoVGhyZWFkR3JvdXAgdGhyZWFkR3JvdXApIHsKKyAgICAgICAgcmV0dXJuIG5ldyBUaHJlYWRHcm91cFRocmVhZFNldCh0aHJlYWRHcm91cCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQW4gVGhyZWFkR3JvdXBUaHJlYWRTZXQgc2FtcGxlIHRoZSB0aHJlYWRzIGZyb20gdGhlIHNwZWNpZmllZAorICAgICAqIFRocmVhZEdyb3VwIGFuZCB0aGUgVGhyZWFkR3JvdXAncyBjaGlsZHJlbgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFRocmVhZEdyb3VwVGhyZWFkU2V0IGltcGxlbWVudHMgVGhyZWFkU2V0IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBUaHJlYWRHcm91cCB0aHJlYWRHcm91cDsKKyAgICAgICAgcHJpdmF0ZSBUaHJlYWRbXSB0aHJlYWRzOworICAgICAgICBwcml2YXRlIGludCBsYXN0VGhyZWFkOworCisgICAgICAgIHB1YmxpYyBUaHJlYWRHcm91cFRocmVhZFNldChUaHJlYWRHcm91cCB0aHJlYWRHcm91cCkgeworICAgICAgICAgICAgaWYgKHRocmVhZEdyb3VwID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInRocmVhZEdyb3VwID09IG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMudGhyZWFkR3JvdXAgPSB0aHJlYWRHcm91cDsKKyAgICAgICAgICAgIHJlc2l6ZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSB2b2lkIHJlc2l6ZSgpIHsKKyAgICAgICAgICAgIGludCBjb3VudCA9IHRocmVhZEdyb3VwLmFjdGl2ZUNvdW50KCk7CisgICAgICAgICAgICAvLyB3ZSBjYW4gb25seSB0ZWxsIGlmIHdlIGhhZCBlbm91Z2ggcm9vbSBmb3IgYWxsIGFjdGl2ZQorICAgICAgICAgICAgLy8gdGhyZWFkcyBpZiB3ZSBhY3R1YWxseSBhcmUgbGFyZ2VyIHRoYW4gdGhlIHRoZSBudW1iZXIgb2YKKyAgICAgICAgICAgIC8vIGFjdGl2ZSB0aHJlYWRzLiBtYWtpbmcgaXQgbGFyZ2VyIGFsc28gbGVhdmVzIHVzIHJvb20gdG8KKyAgICAgICAgICAgIC8vIHRvbGVyYXRlIGFkZGl0aW9uYWwgdGhyZWFkcyB3aXRob3V0IHJlc2l6aW5nLgorICAgICAgICAgICAgdGhyZWFkcyA9IG5ldyBUaHJlYWRbY291bnQqMl07CisgICAgICAgICAgICBsYXN0VGhyZWFkID0gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBUaHJlYWRbXSB0aHJlYWRzKCkgeworICAgICAgICAgICAgaW50IHRocmVhZENvdW50OworICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICB0aHJlYWRDb3VudCA9IHRocmVhZEdyb3VwLmVudW1lcmF0ZSh0aHJlYWRzKTsKKyAgICAgICAgICAgICAgICBpZiAodGhyZWFkQ291bnQgPT0gdGhyZWFkcy5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzaXplKCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHRocmVhZENvdW50IDwgbGFzdFRocmVhZCkgeworICAgICAgICAgICAgICAgIC8vIGF2b2lkIHJldGFpbmluZyBwb2ludGVycyB0byB0aHJlYWRzIHRoYXQgaGF2ZSBlbmRlZAorICAgICAgICAgICAgICAgIEFycmF5cy5maWxsKHRocmVhZHMsIHRocmVhZENvdW50LCBsYXN0VGhyZWFkLCBudWxsKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGxhc3RUaHJlYWQgPSB0aHJlYWRDb3VudDsKKyAgICAgICAgICAgIHJldHVybiB0aHJlYWRzOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU3RhcnRzIHByb2ZpbGVyIHNhbXBsaW5nIGF0IHRoZSBzcGVjaWZpZWQgcmF0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnRlcnZhbCBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBiZXR3ZWVuIHNhbXBsZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdGFydChpbnQgaW50ZXJ2YWwpIHsKKyAgICAgICAgaWYgKGludGVydmFsIDwgMSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaW50ZXJ2YWwgPCAxIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNhbXBsZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigicHJvZmlsaW5nIGFscmVhZHkgc3RhcnRlZCIpOworICAgICAgICB9CisgICAgICAgIHNhbXBsZXIgPSBuZXcgU2FtcGxlcigpOworICAgICAgICBocHJvZkRhdGEuc2V0U3RhcnRNaWxsaXMoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworICAgICAgICB0aW1lci5zY2hlZHVsZUF0Rml4ZWRSYXRlKHNhbXBsZXIsIDAsIGludGVydmFsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdG9wcyBwcm9maWxlciBzYW1wbGluZy4gSXQgY2FuIGJlIHJlc3RhcnRlZCB3aXRoIHtAbGluaworICAgICAqICNzdGFydChpbnQpfSB0byBjb250aW51ZSBzYW1wbGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdG9wKCkgeworICAgICAgICBpZiAoc2FtcGxlciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgc3luY2hyb25pemVkKHNhbXBsZXIpIHsKKyAgICAgICAgICAgIHNhbXBsZXIuc3RvcCA9IHRydWU7CisgICAgICAgICAgICB3aGlsZSAoIXNhbXBsZXIuc3RvcHBlZCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHNhbXBsZXIud2FpdCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgc2FtcGxlciA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2h1dHMgZG93biBwcm9maWxpbmcgYWZ0ZXIgd2hpY2ggaXQgY2FuIG5vdCBiZSByZXN0YXJ0ZWQuIEl0IGlzCisgICAgICogaW1wb3J0YW50IHRvIHNodXQgZG93biBwcm9maWxpbmcgd2hlbiBkb25lIHRvIGZyZWUgcmVzb3VyY2VzCisgICAgICogdXNlZCBieSB0aGUgcHJvZmlsZXIuIFNodXR0aW5nIGRvd24gdGhlIHByb2ZpbGVyIGFsc28gc3RvcHMgdGhlCisgICAgICogcHJvZmlsaW5nIGlmIHRoYXQgaGFzIG5vdCBhbHJlYWR5IGJlZW4gZG9uZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzaHV0ZG93bigpIHsKKyAgICAgICAgc3RvcCgpOworICAgICAgICB0aW1lci5jYW5jZWwoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBocHJvZiBkYXRhIGFjY3VtdWxhdGVkIGJ5IHRoZSBwcm9maWxlciBzaW5jZSBpdCB3YXMKKyAgICAgKiBjcmVhdGVkLiBUaGUgcHJvZmlsZXIgbmVlZHMgdG8gYmUgc3RvcHBlZCwgYnV0IG5vdCBuZWNlc3NhcmlseQorICAgICAqIHNodXQgZG93biwgaW4gb3JkZXIgdG8gYWNjZXNzIHRoZSBkYXRhLiBJZiB0aGUgcHJvZmlsZXIgaXMKKyAgICAgKiByZXN0YXJ0ZWQsIHRoZXJlIGlzIG5vIHRocmVhZCBzYWZlIHdheSB0byBhY2Nlc3MgdGhlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIEhwcm9mRGF0YSBnZXRIcHJvZkRhdGEoKSB7CisgICAgICAgIGlmIChzYW1wbGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oImNhbm5vdCBhY2Nlc3MgaHByb2YgZGF0YSB3aGlsZSBzYW1wbGluZyIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBocHJvZkRhdGE7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIFNhbXBsZXIgZG9lcyB0aGUgcmVhbCB3b3JrIG9mIHRoZSBwcm9maWxlci4KKyAgICAgKgorICAgICAqIEF0IGV2ZXJ5IHNhbXBsZSB0aW1lLCBpdCBhc2tzIHRoZSB0aHJlYWQgc2V0IGZvciB0aGUgc2V0CisgICAgICogb2YgdGhyZWFkcyB0byBzYW1wbGUuIEl0IG1haW50YWlucyBhIGhpc3Rvcnkgb2YgdGhyZWFkIGNyZWF0aW9uCisgICAgICogYW5kIGRlYXRoIGV2ZW50cyBiYXNlZCBvbiBjaGFuZ2VzIG9ic2VydmVkIHRvIHRoZSB0aHJlYWRzCisgICAgICogcmV0dXJuZWQgYnkgdGhlIHtAY29kZSBUaHJlYWRTZXR9LgorICAgICAqCisgICAgICogRm9yIGVhY2ggdGhyZWFkIHRvIGJlIHNhbXBsZWQsIGEgc3RhY2sgaXMgY29sbGVjdGVkIGFuZCB1c2VkIHRvCisgICAgICogdXBkYXRlIHRoZSBzZXQgb2YgY29sbGVjdGVkIHNhbXBsZXMuIFN0YWNrcyBhcmUgdHJ1bmNhdGVkIHRvIGEKKyAgICAgKiBtYXhpbXVtIGRlcHRoLiBUaGVyZSBpcyBubyB3YXkgdG8gdGVsbCBpZiBhIHN0YWNrIGhhcyBiZWVuIHRydW5jYXRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGNsYXNzIFNhbXBsZXIgZXh0ZW5kcyBUaW1lclRhc2sgeworCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBzdG9wOworICAgICAgICBwcml2YXRlIGJvb2xlYW4gc3RvcHBlZDsKKworICAgICAgICBwcml2YXRlIFRocmVhZCB0aW1lclRocmVhZDsKKworICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQodGhpcykgeworICAgICAgICAgICAgICAgIGlmIChzdG9wKSB7CisgICAgICAgICAgICAgICAgICAgIGNhbmNlbCgpOworICAgICAgICAgICAgICAgICAgICBzdG9wcGVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgbm90aWZ5QWxsKCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICh0aW1lclRocmVhZCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGltZXJUaHJlYWQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBwcm9jZXNzIHRocmVhZCBjcmVhdGlvbiBhbmQgZGVhdGggZmlyc3Qgc28gdGhhdCB3ZQorICAgICAgICAgICAgLy8gYXNzaWduIHRocmVhZCBpZHMgdG8gYW55IG5ldyB0aHJlYWRzIGJlZm9yZSBhbGxvY2F0aW5nCisgICAgICAgICAgICAvLyBuZXcgc3RhY2tzIGZvciB0aGVtCisgICAgICAgICAgICBUaHJlYWRbXSBuZXdUaHJlYWRzID0gdGhyZWFkU2V0LnRocmVhZHMoKTsKKyAgICAgICAgICAgIGlmICghQXJyYXlzLmVxdWFscyhjdXJyZW50VGhyZWFkcywgbmV3VGhyZWFkcykpIHsKKyAgICAgICAgICAgICAgICB1cGRhdGVUaHJlYWRIaXN0b3J5KGN1cnJlbnRUaHJlYWRzLCBuZXdUaHJlYWRzKTsKKyAgICAgICAgICAgICAgICBjdXJyZW50VGhyZWFkcyA9IG5ld1RocmVhZHMuY2xvbmUoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZm9yIChUaHJlYWQgdGhyZWFkIDogY3VycmVudFRocmVhZHMpIHsKKyAgICAgICAgICAgICAgICBpZiAodGhyZWFkID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICh0aHJlYWQgPT0gdGltZXJUaHJlYWQpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnRbXSBzdGFja0ZyYW1lcyA9IHRocmVhZFNhbXBsZXIuZ2V0U3RhY2tUcmFjZSh0aHJlYWQpOworICAgICAgICAgICAgICAgIGlmIChzdGFja0ZyYW1lcyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZWNvcmRTdGFja1RyYWNlKHRocmVhZCwgc3RhY2tGcmFtZXMpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJlY29yZCBhIG5ldyBzdGFjayB0cmFjZS4gVGhlIHRocmVhZCBzaG91bGQgaGF2ZSBiZWVuCisgICAgICAgICAqIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCB3aXRoIGFkZFN0YXJ0VGhyZWFkLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSB2b2lkIHJlY29yZFN0YWNrVHJhY2UoVGhyZWFkIHRocmVhZCwgU3RhY2tUcmFjZUVsZW1lbnRbXSBzdGFja0ZyYW1lcykgeworICAgICAgICAgICAgSW50ZWdlciB0aHJlYWRJZCA9IHRocmVhZElkcy5nZXQodGhyZWFkKTsKKyAgICAgICAgICAgIGlmICh0aHJlYWRJZCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVW5rbm93biB0aHJlYWQgIiArIHRocmVhZCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtdXRhYmxlU3RhY2tUcmFjZS50aHJlYWRJZCA9IHRocmVhZElkOworICAgICAgICAgICAgbXV0YWJsZVN0YWNrVHJhY2Uuc3RhY2tGcmFtZXMgPSBzdGFja0ZyYW1lczsKKworICAgICAgICAgICAgaW50W10gY291bnRDZWxsID0gc3RhY2tUcmFjZXMuZ2V0KG11dGFibGVTdGFja1RyYWNlKTsKKyAgICAgICAgICAgIGlmIChjb3VudENlbGwgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGNvdW50Q2VsbCA9IG5ldyBpbnRbMV07CisgICAgICAgICAgICAgICAgLy8gY2xvbmVkIGJlY2F1c2UgdGhlIFRocmVhZFNhbXBsZXIgbWF5IHJldXNlIHRoZSBhcnJheQorICAgICAgICAgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50W10gc3RhY2tGcmFtZXNDb3B5ID0gc3RhY2tGcmFtZXMuY2xvbmUoKTsKKyAgICAgICAgICAgICAgICBIcHJvZkRhdGEuU3RhY2tUcmFjZSBzdGFja1RyYWNlCisgICAgICAgICAgICAgICAgICAgICAgICA9IG5ldyBIcHJvZkRhdGEuU3RhY2tUcmFjZShuZXh0U3RhY2tUcmFjZUlkKyssIHRocmVhZElkLCBzdGFja0ZyYW1lc0NvcHkpOworICAgICAgICAgICAgICAgIGhwcm9mRGF0YS5hZGRTdGFja1RyYWNlKHN0YWNrVHJhY2UsIGNvdW50Q2VsbCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb3VudENlbGxbMF0rKzsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCB1cGRhdGVUaHJlYWRIaXN0b3J5KFRocmVhZFtdIG9sZFRocmVhZHMsIFRocmVhZFtdIG5ld1RocmVhZHMpIHsKKyAgICAgICAgICAgIC8vIHRocmVhZCBzdGFydC9zdG9wIHNob3VsZG4ndCBoYXBwZW4gdG9vIG9mdGVuIGFuZAorICAgICAgICAgICAgLy8gdGhlc2UgYXJlbid0IHRvbyBiaWcsIHNvIGhvcGVmdWxseSB0aGlzIGFwcHJvYWNoCisgICAgICAgICAgICAvLyB3b24ndCBiZSB0b28gc2xvdy4uLgorICAgICAgICAgICAgU2V0PFRocmVhZD4gbiA9IG5ldyBIYXNoU2V0PFRocmVhZD4oQXJyYXlzLmFzTGlzdChuZXdUaHJlYWRzKSk7CisgICAgICAgICAgICBTZXQ8VGhyZWFkPiBvID0gbmV3IEhhc2hTZXQ8VGhyZWFkPihBcnJheXMuYXNMaXN0KG9sZFRocmVhZHMpKTsKKworICAgICAgICAgICAgLy8gYWRkZWQgPSBuZXctb2xkCisgICAgICAgICAgICBTZXQ8VGhyZWFkPiBhZGRlZCA9IG5ldyBIYXNoU2V0PFRocmVhZD4obik7CisgICAgICAgICAgICBhZGRlZC5yZW1vdmVBbGwobyk7CisKKyAgICAgICAgICAgIC8vIHJlbW92ZWQgPSBvbGQtbmV3CisgICAgICAgICAgICBTZXQ8VGhyZWFkPiByZW1vdmVkID0gbmV3IEhhc2hTZXQ8VGhyZWFkPihvKTsKKyAgICAgICAgICAgIHJlbW92ZWQucmVtb3ZlQWxsKG4pOworCisgICAgICAgICAgICBmb3IgKFRocmVhZCB0aHJlYWQgOiBhZGRlZCkgeworICAgICAgICAgICAgICAgIGlmICh0aHJlYWQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHRocmVhZCA9PSB0aW1lclRocmVhZCkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYWRkU3RhcnRUaHJlYWQodGhyZWFkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZvciAoVGhyZWFkIHRocmVhZCA6IHJlbW92ZWQpIHsKKyAgICAgICAgICAgICAgICBpZiAodGhyZWFkID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICh0aHJlYWQgPT0gdGltZXJUaHJlYWQpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFkZEVuZFRocmVhZCh0aHJlYWQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJlY29yZCB0aGF0IGEgbmV3bHkgbm90aWNlZCB0aHJlYWQuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIHZvaWQgYWRkU3RhcnRUaHJlYWQoVGhyZWFkIHRocmVhZCkgeworICAgICAgICAgICAgaWYgKHRocmVhZCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ0aHJlYWQgPT0gbnVsbCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHRocmVhZElkID0gbmV4dFRocmVhZElkKys7CisgICAgICAgICAgICBJbnRlZ2VyIG9sZCA9IHRocmVhZElkcy5wdXQodGhyZWFkLCB0aHJlYWRJZCk7CisgICAgICAgICAgICBpZiAob2xkICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJUaHJlYWQgYWxyZWFkeSByZWdpc3RlcmVkIGFzICIgKyBvbGQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBTdHJpbmcgdGhyZWFkTmFtZSA9IHRocmVhZC5nZXROYW1lKCk7CisgICAgICAgICAgICAvLyBncm91cCB3aWxsIGJlY29tZSBudWxsIHdoZW4gdGhyZWFkIGlzIHRlcm1pbmF0ZWQKKyAgICAgICAgICAgIFRocmVhZEdyb3VwIGdyb3VwID0gdGhyZWFkLmdldFRocmVhZEdyb3VwKCk7CisgICAgICAgICAgICBTdHJpbmcgZ3JvdXBOYW1lID0gZ3JvdXAgPT0gbnVsbCA/IG51bGwgOiBncm91cC5nZXROYW1lKCk7CisgICAgICAgICAgICBUaHJlYWRHcm91cCBwYXJlbnRHcm91cCA9IGdyb3VwID09IG51bGwgPyBudWxsIDogZ3JvdXAuZ2V0UGFyZW50KCk7CisgICAgICAgICAgICBTdHJpbmcgcGFyZW50R3JvdXBOYW1lID0gcGFyZW50R3JvdXAgPT0gbnVsbCA/IG51bGwgOiBwYXJlbnRHcm91cC5nZXROYW1lKCk7CisKKyAgICAgICAgICAgIEhwcm9mRGF0YS5UaHJlYWRFdmVudCBldmVudAorICAgICAgICAgICAgICAgICAgICA9IEhwcm9mRGF0YS5UaHJlYWRFdmVudC5zdGFydChuZXh0T2JqZWN0SWQrKywgdGhyZWFkSWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocmVhZE5hbWUsIGdyb3VwTmFtZSwgcGFyZW50R3JvdXBOYW1lKTsKKyAgICAgICAgICAgIGhwcm9mRGF0YS5hZGRUaHJlYWRFdmVudChldmVudCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmVjb3JkIHRoYXQgYSB0aHJlYWQgaGFzIGRpc2FwcGVhcmVkLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSB2b2lkIGFkZEVuZFRocmVhZChUaHJlYWQgdGhyZWFkKSB7CisgICAgICAgICAgICBpZiAodGhyZWFkID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInRocmVhZCA9PSBudWxsIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBJbnRlZ2VyIHRocmVhZElkID0gdGhyZWFkSWRzLnJlbW92ZSh0aHJlYWQpOworICAgICAgICAgICAgaWYgKHRocmVhZElkID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbmtub3duIHRocmVhZCAiICsgdGhyZWFkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEhwcm9mRGF0YS5UaHJlYWRFdmVudCBldmVudCA9IEhwcm9mRGF0YS5UaHJlYWRFdmVudC5lbmQodGhyZWFkSWQpOworICAgICAgICAgICAgaHByb2ZEYXRhLmFkZFRocmVhZEV2ZW50KGV2ZW50KTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vcHJvZmlsZXIvVGhyZWFkU2FtcGxlci5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvZGFsdmlrL3N5c3RlbS9wcm9maWxlci9UaHJlYWRTYW1wbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTA0YjE2ZAotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL2RhbHZpay9zeXN0ZW0vcHJvZmlsZXIvVGhyZWFkU2FtcGxlci5qYXZhCkBAIC0wLDAgKzEsNDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5zeXN0ZW0ucHJvZmlsZXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFRoZSB7QGNvZGUgVGhyZWFkU2FtcGxlcn0gaW50ZXJmYWNlcyBhbGxvd3MgYSBwcm9maWxlciB0byBjaG9vc2UKKyAqIGJldHdlZW4gcG9ydGFibGUgYW5kIFZNIHNwZWNpZmljIGltcGxlbWVudGF0aW9ucyBvZiB0aHJlYWQKKyAqIHNhbXBsaW5nLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFRocmVhZFNhbXBsZXIgeworCisgICAgLyoqCisgICAgICogVXNlZCB0byBzcGVjaWZ5IHRoZSBtYXhpbXVtIHN0YWNrIGRlcHRoIHRvIGNvbGxlY3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGVwdGgoaW50IGRlcHRoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybiBhIHN0YWNrIHRyYWNlIGZvciB0aGUgY3VycmVudCB0aHJlYWQgbGltaXRlZCBieSB0aGUKKyAgICAgKiBtYXhpbXVtIGRlcHRoIHNwZWNpZmllZCBieSB7QGxpbmsgI3NldERlcHRoIHNldERlcHRofS4gTWF5CisgICAgICogcmV0dXJuIG51bGwgaWYgbm8gc2FtcGxlIGlzIGF2YWlsYmxlIGZvciB0aGUgdGhyZWFkLCB3aGljaCBtYXkKKyAgICAgKiBoYXBwZW4gaW4gY2FzZXMgc3VjaCBhcyB0aHJlYWQgdGVybWluYXRpb24uIFRoZSByZXN1bHRpbmcgYXJyYXkKKyAgICAgKiBzaG91bGQgYmUgY29waWVkIGJlZm9yZSB0aGUgbmV4dCBjYWxsIHRvIHtAY29kZSBnZXRTdGFja1RyYWNlfQorICAgICAqIGlmIHRoZSBjYWxsZXIgd2FudHMgdG8gdXNlIHRoZSByZXN1bHRzLCBzaW5jZSB0aGUge0Bjb2RlCisgICAgICogVGhyZWFkU2FtcGxlcn0gbWF5IHJldXNlIHRoZSBhcnJheS4gTm90ZSB0aGF0IHRoZSBlbGVtZW50cworICAgICAqIHRoZW1zZWx2ZXMgYXJlIGltbXV0YWJsZSBhbmQgZG8gbm90IG5lZWQgdG8gYmUgY29waWVkLgorICAgICAqLworICAgIHB1YmxpYyBTdGFja1RyYWNlRWxlbWVudFtdIGdldFN0YWNrVHJhY2UoVGhyZWFkIHRocmVhZCk7Cit9CmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvZGFsdmlrL05hdGl2ZVRlc3RUYXJnZXQuamF2YSBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9kYWx2aWsvTmF0aXZlVGVzdFRhcmdldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdiNDZkMmUKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvZGFsdmlrL05hdGl2ZVRlc3RUYXJnZXQuamF2YQpAQCAtMCwwICsxLDY4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuZGFsdmlrOworCisvKioKKyAqIE1ldGhvZHMgdXNlZCB0byB0ZXN0IGNhbGxpbmcgaW50byBuYXRpdmUgY29kZS4gVGhlIG1ldGhvZHMgaW4gdGhpcworICogY2xhc3MgYXJlIGFsbCBlZmZlY3RpdmVseSBuby1vcHMgYW5kIG1heSBiZSB1c2VkIHRvIHRlc3QgdGhlIG1lY2hhbmlzbXMKKyAqIGFuZCBwZXJmb3JtYW5jZSBvZiBjYWxsaW5nIG5hdGl2ZSBtZXRob2RzLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTmF0aXZlVGVzdFRhcmdldCB7CisgICAgLyoqCisgICAgICogVGhpcyBjbGFzcyBpcyB1bmluc3RhbnRpYWJsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIE5hdGl2ZVRlc3RUYXJnZXQoKSB7CisgICAgICAgIC8vIFRoaXMgc3BhY2UgaW50ZW50aW9uYWxseSBsZWZ0IGJsYW5rLgorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgaXMgYW4gZW1wdHkgbmF0aXZlIHN0YXRpYyBtZXRob2Qgd2l0aCBubyBhcmdzLCBob29rZWQgdXAgdXNpbmcKKyAgICAgKiBKTkkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBlbXB0eUpuaVN0YXRpY01ldGhvZDAoKTsKKworICAgIC8qKgorICAgICAqIFRoaXMgaXMgYW4gZW1wdHkgbmF0aXZlIHN0YXRpYyBtZXRob2Qgd2l0aCBzaXggYXJncywgaG9va2VkIHVwIHVzaW5nCisgICAgICogSk5JLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgZW1wdHlKbmlTdGF0aWNNZXRob2Q2KGludCBhLCBpbnQgYiwgaW50IGMsCisgICAgICAgIGludCBkLCBpbnQgZSwgaW50IGYpOworCisgICAgLyoqCisgICAgICogVGhpcyBpcyBhbiBlbXB0eSBuYXRpdmUgc3RhdGljIG1ldGhvZCB3aXRoIHNpeCBhcmdzLCBob29rZWQgdXAKKyAgICAgKiB1c2luZyBKTkkuIFRoZXNlIGhhdmUgbW9yZSBjb21wbGV4IGFyZ3MgdG8gc2hvdyB0aGUgY29zdCBvZgorICAgICAqIHBhcnNpbmcgdGhlIHNpZ25hdHVyZS4gQWxsIHNpeCB2YWx1ZXMgc2hvdWxkIGJlIG51bGwKKyAgICAgKiByZWZlcmVuY2VzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgZW1wdHlKbmlTdGF0aWNNZXRob2Q2TChTdHJpbmcgYSwgU3RyaW5nW10gYiwKKyAgICAgICAgaW50W11bXSBjLCBPYmplY3QgZCwgT2JqZWN0W10gZSwgT2JqZWN0W11bXVtdW10gZik7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBpbnRlbmRlZCB0byBiZSAiaW5saW5lZCIgYnkgdGhlIHZpcnR1YWwgbWFjaGluZQorICAgICAqIChlLmcuLCBnaXZlbiBzcGVjaWFsIHRyZWF0bWVudCBhcyBhbiBpbnRyaW5zaWMpLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBlbXB0eUlubGluZU1ldGhvZCgpIHsKKyAgICAgICAgLy8gVGhpcyBzcGFjZSBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsuCisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgaXMgaW50ZW5kZWQgdG8gYmUgZGVmaW5lZCBpbiBuYXRpdmUgY29kZSBhbmQgaG9va2VkCisgICAgICogdXAgdXNpbmcgdGhlIHZpcnR1YWwgbWFjaGluZSdzIHNwZWNpYWwgZmFzdC1wYXRoIG5hdGl2ZSBsaW5rYWdlCisgICAgICogKGFzIG9wcG9zZWQgdG8gYmVpbmcgaG9va2VkIHVwIHVzaW5nIEpOSSkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBlbXB0eUludGVybmFsU3RhdGljTWV0aG9kKCk7Cit9CmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvZGFsdmlrL2RkbWMvQ2h1bmsuamF2YSBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9kYWx2aWsvZGRtYy9DaHVuay5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjliOTg4OTMKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvZGFsdmlrL2RkbWMvQ2h1bmsuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuZGFsdmlrLmRkbWM7CisKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworCisvKioKKyAqIEEgY2h1bmsgb2YgRERNIGRhdGEuICBUaGlzIGlzIHJlYWxseSBqdXN0IG1lYW50IHRvIGhvbGQgYSBmZXcgcGllY2VzCisgKiBvZiBkYXRhIHRvZ2V0aGVyLgorICoKKyAqIFRoZSAib2Zmc2V0IiBhbmQgImxlbmd0aCIgZmllbGRzIGFyZSBwcmVzZW50IHNvIGhhbmRsZXJzIGNhbiBvdmVyLWFsbG9jYXRlCisgKiBvciBzaGFyZSBieXRlIGJ1ZmZlcnMuCisgKi8KK3B1YmxpYyBjbGFzcyBDaHVuayB7CisKKyAgICAvKgorICAgICAqIFB1YmxpYyBtZW1iZXJzLiAgRG8gbm90IHJlbmFtZSB3aXRob3V0IHVwZGF0aW5nIHRoZSBWTS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHR5cGU7ICAgICAgICAgICAgICAgIC8vIGNodW5rIHR5cGUKKyAgICBwdWJsaWMgYnl0ZVtdIGRhdGE7ICAgICAgICAgICAgIC8vIGNodW5rIGRhdGEKKyAgICBwdWJsaWMgaW50IG9mZnNldCwgbGVuZ3RoOyAgICAgIC8vIHBvc2l0aW9uIHdpdGhpbiAiZGF0YSIKKworICAgIC8qKgorICAgICAqIEJsYW5rIGNvbnN0cnVjdG9yLiAgRmlsbCBpbiB5b3VyIG93biBmaWVsZHMuCisgICAgICovCisgICAgcHVibGljIENodW5rKCkge30KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIHdpdGggYWxsIGZpZWxkcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2h1bmsoaW50IHR5cGUsIGJ5dGVbXSBkYXRhLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7CisgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0OworICAgICAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgZnJvbSBhIEJ5dGVCdWZmZXIuICBUaGUgY2h1bmsgaXMgYXNzdW1lZCB0byBzdGFydCBhdAorICAgICAqIG9mZnNldCAwIGFuZCBjb250aW51ZSB0byB0aGUgY3VycmVudCBwb3NpdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2h1bmsoaW50IHR5cGUsIEJ5dGVCdWZmZXIgYnVmKSB7CisgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisKKyAgICAgICAgdGhpcy5kYXRhID0gYnVmLmFycmF5KCk7CisgICAgICAgIHRoaXMub2Zmc2V0ID0gYnVmLmFycmF5T2Zmc2V0KCk7CisgICAgICAgIHRoaXMubGVuZ3RoID0gYnVmLnBvc2l0aW9uKCk7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvZGFsdmlrL2RkbWMvQ2h1bmtIYW5kbGVyLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvZGFsdmlrL2RkbWMvQ2h1bmtIYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWQwMDczYgotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9kYWx2aWsvZGRtYy9DaHVua0hhbmRsZXIuamF2YQpAQCAtMCwwICsxLDEzNyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmRhbHZpay5kZG1jOworCitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlT3JkZXI7CisKKy8qKgorICogSGFuZGxlIGEgY2h1bmsgb2YgZGF0YSBzZW50IGZyb20gYSBERE0gc2VydmVyLgorICoKKyAqIFRvIGhhbmRsZSBhIGNodW5rIHR5cGUsIHN1Yi1jbGFzcyBDaHVua0hhbmRsZXIgYW5kIHJlZ2lzdGVyIHlvdXIgY2xhc3MKKyAqIHdpdGggRGRtU2VydmVyLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ2h1bmtIYW5kbGVyIHsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQnl0ZU9yZGVyIENIVU5LX09SREVSID0gQnl0ZU9yZGVyLkJJR19FTkRJQU47CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDSFVOS19GQUlMID0gdHlwZSgiRkFJTCIpOworCisKKyAgICBwdWJsaWMgQ2h1bmtIYW5kbGVyKCkge30KKworICAgIC8qKgorICAgICAqIENhbGxlZCB3aGVuIHRoZSBERE0gc2VydmVyIGNvbm5lY3RzLiAgVGhlIGhhbmRsZXIgaXMgYWxsb3dlZCB0bworICAgICAqIHNlbmQgbWVzc2FnZXMgdG8gdGhlIHNlcnZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBjb25uZWN0ZWQoKTsKKworICAgIC8qKgorICAgICAqIENhbGxlZCB3aGVuIHRoZSBERE0gc2VydmVyIGRpc2Nvbm5lY3RzLiAgQ2FuIGJlIHVzZWQgdG8gZGlzYWJsZQorICAgICAqIHBlcmlvZGljIHRyYW5zbWlzc2lvbnMgb3IgY2xlYW4gdXAgc2F2ZWQgc3RhdGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZGlzY29ubmVjdGVkKCk7CisKKyAgICAvKioKKyAgICAgKiBIYW5kbGUgYSBzaW5nbGUgY2h1bmsgb2YgZGF0YS4gICJyZXF1ZXN0IiBpbmNsdWRlcyB0aGUgdHlwZSBhbmQKKyAgICAgKiB0aGUgY2h1bmsgcGF5bG9hZC4KKyAgICAgKgorICAgICAqIFJldHVybnMgYSByZXNwb25zZSBpbiBhIENodW5rLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBDaHVuayBoYW5kbGVDaHVuayhDaHVuayByZXF1ZXN0KTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIEZBSUwgY2h1bmsuICBUaGUgImhhbmRsZUNodW5rIiBtZXRob2RzIGNhbiB1c2UgdGhpcyB0bworICAgICAqIHJldHVybiBhbiBlcnJvciBtZXNzYWdlIHdoZW4gdGhleSBhcmUgbm90IGFibGUgdG8gcHJvY2VzcyBhIGNodW5rLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ2h1bmsgY3JlYXRlRmFpbENodW5rKGludCBlcnJvckNvZGUsIFN0cmluZyBtc2cpIHsKKyAgICAgICAgaWYgKG1zZyA9PSBudWxsKQorICAgICAgICAgICAgbXNnID0gIiI7CisKKyAgICAgICAgQnl0ZUJ1ZmZlciBvdXQgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDggKyBtc2cubGVuZ3RoKCkgKiAyKTsKKyAgICAgICAgb3V0Lm9yZGVyKENodW5rSGFuZGxlci5DSFVOS19PUkRFUik7CisgICAgICAgIG91dC5wdXRJbnQoZXJyb3JDb2RlKTsKKyAgICAgICAgb3V0LnB1dEludChtc2cubGVuZ3RoKCkpOworICAgICAgICBwdXRTdHJpbmcob3V0LCBtc2cpOworCisgICAgICAgIHJldHVybiBuZXcgQ2h1bmsoQ0hVTktfRkFJTCwgb3V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uIHRvIHdyYXAgYSBCeXRlQnVmZmVyIGFyb3VuZCBhIENodW5rLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQnl0ZUJ1ZmZlciB3cmFwQ2h1bmsoQ2h1bmsgcmVxdWVzdCkgeworICAgICAgICBCeXRlQnVmZmVyIGluOworCisgICAgICAgIGluID0gQnl0ZUJ1ZmZlci53cmFwKHJlcXVlc3QuZGF0YSwgcmVxdWVzdC5vZmZzZXQsIHJlcXVlc3QubGVuZ3RoKTsKKyAgICAgICAgaW4ub3JkZXIoQ0hVTktfT1JERVIpOworICAgICAgICByZXR1cm4gaW47CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uIHRvIGNvcHkgYSBTdHJpbmcgb3V0IG9mIGEgQnl0ZUJ1ZmZlci4KKyAgICAgKgorICAgICAqIFRoaXMgaXMgaGVyZSBiZWNhdXNlIG11bHRpcGxlIGNodW5rIGhhbmRsZXJzIGNhbiBtYWtlIHVzZSBvZiBpdCwKKyAgICAgKiBhbmQgdGhlcmUncyBub3doZXJlIGJldHRlciB0byBwdXQgaXQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0U3RyaW5nKEJ5dGVCdWZmZXIgYnVmLCBpbnQgbGVuKSB7CisgICAgICAgIGNoYXJbXSBkYXRhID0gbmV3IGNoYXJbbGVuXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykKKyAgICAgICAgICAgIGRhdGFbaV0gPSBidWYuZ2V0Q2hhcigpOworICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhkYXRhKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uIHRvIGNvcHkgYSBTdHJpbmcgaW50byBhIEJ5dGVCdWZmZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHB1dFN0cmluZyhCeXRlQnVmZmVyIGJ1ZiwgU3RyaW5nIHN0cikgeworICAgICAgICBpbnQgbGVuID0gc3RyLmxlbmd0aCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKQorICAgICAgICAgICAgYnVmLnB1dENoYXIoc3RyLmNoYXJBdChpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCBhIDQtY2hhcmFjdGVyIHN0cmluZyB0byBhIDMyLWJpdCB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHR5cGUoU3RyaW5nIHR5cGVOYW1lKSB7CisgICAgICAgIGlmICh0eXBlTmFtZS5sZW5ndGgoKSAhPSA0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJCYWQgdHlwZSBuYW1lOiAiICsgdHlwZU5hbWUpOworICAgICAgICB9CisgICAgICAgIGludCByZXN1bHQgPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDQ7ICsraSkgeworICAgICAgICAgICAgcmVzdWx0ID0gKChyZXN1bHQgPDwgOCkgfCAodHlwZU5hbWUuY2hhckF0KGkpICYgMHhmZikpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCBhbiBpbnRlZ2VyIHR5cGUgdG8gYSA0LWNoYXJhY3RlciBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgbmFtZShpbnQgdHlwZSkKKyAgICB7CisgICAgICAgIGNoYXJbXSBhc2NpaSA9IG5ldyBjaGFyWzRdOworCisgICAgICAgIGFzY2lpWzBdID0gKGNoYXIpICgodHlwZSA+PiAyNCkgJiAweGZmKTsKKyAgICAgICAgYXNjaWlbMV0gPSAoY2hhcikgKCh0eXBlID4+IDE2KSAmIDB4ZmYpOworICAgICAgICBhc2NpaVsyXSA9IChjaGFyKSAoKHR5cGUgPj4gOCkgJiAweGZmKTsKKyAgICAgICAgYXNjaWlbM10gPSAoY2hhcikgKHR5cGUgJiAweGZmKTsKKworICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhhc2NpaSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvZGFsdmlrL2RkbWMvRGRtU2VydmVyLmphdmEgYi9kYWx2aWsvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvZGFsdmlrL2RkbWMvRGRtU2VydmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjFiZWUzNAotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9kYWx2aWsvZGRtYy9EZG1TZXJ2ZXIuamF2YQpAQCAtMCwwICsxLDE3NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmRhbHZpay5kZG1jOworCitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworCisKKy8qKgorICogVGhpcyByZXByZXNlbnRzIG91ciBjb25uZWN0aW9uIHRvIHRoZSBERE0gU2VydmVyLgorICovCitwdWJsaWMgY2xhc3MgRGRtU2VydmVyIHsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMSUVOVF9QUk9UT0NPTF9WRVJTSU9OID0gMTsKKworICAgIHByaXZhdGUgc3RhdGljIEhhc2hNYXA8SW50ZWdlcixDaHVua0hhbmRsZXI+IG1IYW5kbGVyTWFwID0KKyAgICAgICAgbmV3IEhhc2hNYXA8SW50ZWdlcixDaHVua0hhbmRsZXI+KCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09OTkVDVEVEID0gMTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRElTQ09OTkVDVEVEID0gMjsKKworICAgIHByaXZhdGUgc3RhdGljIHZvbGF0aWxlIGJvb2xlYW4gbVJlZ2lzdHJhdGlvbkNvbXBsZXRlID0gZmFsc2U7CisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBtUmVnaXN0cmF0aW9uVGltZWRPdXQgPSBmYWxzZTsKKworCisgICAgLyoqCisgICAgICogRG9uJ3QgaW5zdGFudGlhdGU7IGFsbCBtZW1iZXJzIGFuZCBtZXRob2RzIGFyZSBzdGF0aWMuCisgICAgICovCisgICAgcHJpdmF0ZSBEZG1TZXJ2ZXIoKSB7fQorCisgICAgLyoqCisgICAgICogUmVnaXN0ZXIgYW4gaW5zdGFuY2Ugb2YgdGhlIENodW5rSGFuZGxlciBjbGFzcyB0byBoYW5kbGUgYSBzcGVjaWZpYworICAgICAqIGNodW5rIHR5cGUuCisgICAgICoKKyAgICAgKiBUaHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoZSB0eXBlIGFscmVhZHkgaGFzIGEgaGFuZGxlciByZWdpc3RlcmVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckhhbmRsZXIoaW50IHR5cGUsIENodW5rSGFuZGxlciBoYW5kbGVyKSB7CisgICAgICAgIGlmIChoYW5kbGVyID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKworICAgICAgICBzeW5jaHJvbml6ZWQgKG1IYW5kbGVyTWFwKSB7CisgICAgICAgICAgICBpZiAobUhhbmRsZXJNYXAuZ2V0KHR5cGUpICE9IG51bGwpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oInR5cGUgIiArIEludGVnZXIudG9IZXhTdHJpbmcodHlwZSkKKyAgICAgICAgICAgICAgICAgICAgKyAiIGFscmVhZHkgcmVnaXN0ZXJlZCIpOworCisgICAgICAgICAgICBtSGFuZGxlck1hcC5wdXQodHlwZSwgaGFuZGxlcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVbnJlZ2lzdGVyIHRoZSBleGlzdGluZyBoYW5kbGVyIGZvciB0aGUgc3BlY2lmaWVkIHR5cGUuCisgICAgICoKKyAgICAgKiBSZXR1cm5zIHRoZSBvbGQgaGFuZGxlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIENodW5rSGFuZGxlciB1bnJlZ2lzdGVySGFuZGxlcihpbnQgdHlwZSkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKG1IYW5kbGVyTWFwKSB7CisgICAgICAgICAgICByZXR1cm4gbUhhbmRsZXJNYXAucmVtb3ZlKHR5cGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGFwcGxpY2F0aW9uIG11c3QgY2FsbCBoZXJlIGFmdGVyIGl0IGZpbmlzaGVzIHJlZ2lzdGVyaW5nCisgICAgICogaGFuZGxlcnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdHJhdGlvbkNvbXBsZXRlKCkgeworICAgICAgICAvLyBzeW5jIG9uIG1IYW5kbGVyTWFwIGJlY2F1c2UgaXQncyBjb252ZW5pZW50IGFuZCBtYWtlcyBhIGtpbmQgb2YKKyAgICAgICAgLy8gc2Vuc2UKKyAgICAgICAgc3luY2hyb25pemVkIChtSGFuZGxlck1hcCkgeworICAgICAgICAgICAgbVJlZ2lzdHJhdGlvbkNvbXBsZXRlID0gdHJ1ZTsKKyAgICAgICAgICAgIG1IYW5kbGVyTWFwLm5vdGlmeUFsbCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZCBhIGNodW5rIG9mIGRhdGEgdG8gdGhlIERETSBzZXJ2ZXIuICBUaGlzIHRha2VzIHRoZSBmb3JtIG9mIGEKKyAgICAgKiBKRFdQICJldmVudCIsIHdoaWNoIGRvZXMgbm90IGVsaWNpdCBhIHJlc3BvbnNlIGZyb20gdGhlIHNlcnZlci4KKyAgICAgKgorICAgICAqIFVzZSB0aGlzIGZvciAidW5zb2xpY2l0ZWQiIGNodW5rcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2VuZENodW5rKENodW5rIGNodW5rKSB7CisgICAgICAgIG5hdGl2ZVNlbmRDaHVuayhjaHVuay50eXBlLCBjaHVuay5kYXRhLCBjaHVuay5vZmZzZXQsIGNodW5rLmxlbmd0aCk7CisgICAgfQorCisgICAgLyogc2VuZCBhIGNodW5rIHRvIHRoZSBERE0gc2VydmVyICovCisgICAgbmF0aXZlIHByaXZhdGUgc3RhdGljIHZvaWQgbmF0aXZlU2VuZENodW5rKGludCB0eXBlLCBieXRlW10gZGF0YSwKKyAgICAgICAgaW50IG9mZnNldCwgaW50IGxlbmd0aCk7CisKKyAgICAvKgorICAgICAqIENhbGxlZCBieSB0aGUgVk0gd2hlbiB0aGUgRERNIHNlcnZlciBjb25uZWN0cyBvciBkaXNjb25uZWN0cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGJyb2FkY2FzdChpbnQgZXZlbnQpCisgICAgeworICAgICAgICBzeW5jaHJvbml6ZWQgKG1IYW5kbGVyTWFwKSB7CisgICAgICAgICAgICBDb2xsZWN0aW9uIHZhbHVlcyA9IG1IYW5kbGVyTWFwLnZhbHVlcygpOworICAgICAgICAgICAgSXRlcmF0b3IgaXRlciA9IHZhbHVlcy5pdGVyYXRvcigpOworCisgICAgICAgICAgICB3aGlsZSAoaXRlci5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBDaHVua0hhbmRsZXIgaGFuZGxlciA9IChDaHVua0hhbmRsZXIpIGl0ZXIubmV4dCgpOworICAgICAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQpIHsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBDT05ORUNURUQ6CisgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLmNvbm5lY3RlZCgpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgRElTQ09OTkVDVEVEOgorICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5kaXNjb25uZWN0ZWQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUaGlzIGlzIGNhbGxlZCBieSB0aGUgVk0gd2hlbiBhIGNodW5rIGFycml2ZXMuCisgICAgICoKKyAgICAgKiBGb3IgYSBERE0tYXdhcmUgYXBwbGljYXRpb24sIHdlIHdhbnQgdG8gd2FpdCB1bnRpbCB0aGUgYXBwIGhhcyBoYWQKKyAgICAgKiBhIGNoYW5jZSB0byByZWdpc3RlciBhbGwgb2YgaXRzIGNodW5rIGhhbmRsZXJzLiAgT3RoZXJ3aXNlLCB3ZSdsbAorICAgICAqIGVuZCB1cCBkcm9wcGluZyBlYXJseS1hcnJpdmluZyBwYWNrZXRzIG9uIHRoZSBmbG9vci4KKyAgICAgKgorICAgICAqIEZvciBhIG5vbi1ERE0tYXdhcmUgYXBwbGljYXRpb24sIHdlJ2xsIGVuZCB1cCB3YWl0aW5nIGhlcmUgZm9yZXZlcgorICAgICAqIGlmIERETVMgaGFwcGVucyB0byBjb25uZWN0LiAgSXQncyBoYXJkIHRvIGtub3cgZm9yIHN1cmUgdGhhdAorICAgICAqIHJlZ2lzdHJhdGlvbiBpc24ndCBnb2luZyB0byBoYXBwZW4sIHNvIHdlIHNldHRsZSBmb3IgYSB0aW1lb3V0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIENodW5rIGRpc3BhdGNoKGludCB0eXBlLCBieXRlW10gZGF0YSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKKyAgICB7CisgICAgICAgIENodW5rSGFuZGxlciBoYW5kbGVyOworCisgICAgICAgIHN5bmNocm9uaXplZCAobUhhbmRsZXJNYXApIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBJZiByZWdpc3RyYXRpb24gaGFzbid0IGNvbXBsZXRlZCwgYW5kIHdlIGhhdmVuJ3QgdGltZWQgb3V0CisgICAgICAgICAgICAgKiB3YWl0aW5nIGZvciBpdCwgd2FpdCBhIGJpdC4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgd2hpbGUgKCFtUmVnaXN0cmF0aW9uQ29tcGxldGUgJiYgIW1SZWdpc3RyYXRpb25UaW1lZE91dCkgeworICAgICAgICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJkaXNwYXRjaCgpIHdhaXRpbmcgZm9yIHJlZyIpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIG1IYW5kbGVyTWFwLndhaXQoMTAwMCk7ICAgICAvLyAxLjAgc2VjCisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaWUpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKCFtUmVnaXN0cmF0aW9uQ29tcGxldGUpIHsKKyAgICAgICAgICAgICAgICAgICAgLyogdGltZWQgb3V0LCBkb24ndCB3YWl0IGFnYWluICovCisgICAgICAgICAgICAgICAgICAgIG1SZWdpc3RyYXRpb25UaW1lZE91dCA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBoYW5kbGVyID0gbUhhbmRsZXJNYXAuZ2V0KHR5cGUpOworICAgICAgICB9CisgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCIgZGlzcGF0Y2ggY29udCIpOworCisgICAgICAgIGlmIChoYW5kbGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQ2h1bmsgY2h1bmsgPSBuZXcgQ2h1bmsodHlwZSwgZGF0YSwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICByZXR1cm4gaGFuZGxlci5oYW5kbGVDaHVuayhjaHVuayk7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvZGFsdmlrL2RkbWMvRGRtVm1JbnRlcm5hbC5qYXZhIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2RhbHZpay9kZG1jL0RkbVZtSW50ZXJuYWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMTI5M2IwCi0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2RhbHZpay9kZG1jL0RkbVZtSW50ZXJuYWwuamF2YQpAQCAtMCwwICsxLDg0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuZGFsdmlrLmRkbWM7CisKKy8qKgorICogRGVjbGFyYXRpb25zIGZvciBzb21lIFZNLWludGVybmFsIERETSBzdHVmZi4KKyAqLworcHVibGljIGNsYXNzIERkbVZtSW50ZXJuYWwgeworCisgICAgLyogZG8gbm90IGluc3RhbnRpYXRlICovCisgICAgcHJpdmF0ZSBEZG1WbUludGVybmFsKCkge30KKworICAgIC8qKgorICAgICAqIEVuYWJsZSB0aHJlYWQgbm90aWZpY2F0aW9uLgorICAgICAqCisgICAgICogVGhpcyBpcyBidWlsdCBpbnRvIHRoZSBWTSwgc2luY2UgdGhhdCdzIHdoZXJlIHRocmVhZHMgZ2V0IG1hbmFnZWQuCisgICAgICovCisgICAgbmF0aXZlIHB1YmxpYyBzdGF0aWMgdm9pZCB0aHJlYWROb3RpZnkoYm9vbGVhbiBlbmFibGUpOworCisgICAgLyoqCisgICAgICogRW5hYmxlIGhlYXAgaW5mbyB1cGRhdGVzLgorICAgICAqCisgICAgICogVGhpcyBpcyBidWlsdCBpbnRvIHRoZSBWTSwgc2luY2UgdGhhdCdzIHdoZXJlIHRoZSBoZWFwIGlzIG1hbmFnZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gd2hlbiB3aGVuIHRvIHNlbmQgdGhlIG5leHQgSFBJRiBjaHVuaworICAgICAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLiAgZmFsc2UgaWYgJ3doZW4nIGlzIGJhZCBvciBpZiB0aGVyZSB3YXMKKyAgICAgKiAgICAgICAgIGFuIGludGVybmFsIGVycm9yLgorICAgICAqLworICAgIG5hdGl2ZSBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaGVhcEluZm9Ob3RpZnkoaW50IHdoZW4pOworCisgICAgLyoqCisgICAgICogRW5hYmxlIGhlYXAgc2VnbWVudCB1cGRhdGVzIGZvciB0aGUgamF2YSAoaXNOYXRpdmUgPT0gZmFsc2UpIG9yCisgICAgICogbmF0aXZlIChpc05hdGl2ZSA9PSB0cnVlKSBoZWFwLgorICAgICAqCisgICAgICogVGhpcyBpcyBidWlsdCBpbnRvIHRoZSBWTSwgc2luY2UgdGhhdCdzIHdoZXJlIHRoZSBoZWFwIGlzIG1hbmFnZWQuCisgICAgICovCisgICAgbmF0aXZlIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBoZWFwU2VnbWVudE5vdGlmeShpbnQgd2hlbiwgaW50IHdoYXQsCisgICAgICAgIGJvb2xlYW4gaXNOYXRpdmUpOworCisgICAgLyoqCisgICAgICogR2V0IHN0YXR1cyBpbmZvIGZvciBhbGwgdGhyZWFkcy4gIFRoaXMgaXMgZm9yIHRoZSBUSFNUIGNodW5rLgorICAgICAqCisgICAgICogUmV0dXJucyBhIGJ5dGUgYXJyYXkgd2l0aCB0aGUgVEhTVCBkYXRhLCBvciBudWxsIGlmIHNvbWV0aGluZworICAgICAqIHdlbnQgd3JvbmcuCisgICAgICovCisgICAgbmF0aXZlIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIGdldFRocmVhZFN0YXRzKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXQgYSBzdGFjayB0cmFjZSBmb3IgdGhlIHNwZWNpZmllZCB0aHJlYWQgSUQuICBUaGUgSUQgY2FuIGJlIGZvdW5kCisgICAgICogaW4gdGhlIGRhdGEgZnJvbSBnZXRUaHJlYWRTdGF0cy4KKyAgICAgKi8KKyAgICBuYXRpdmUgcHVibGljIHN0YXRpYyBTdGFja1RyYWNlRWxlbWVudFtdIGdldFN0YWNrVHJhY2VCeUlkKGludCB0aHJlYWRJZCk7CisKKyAgICAvKioKKyAgICAgKiBFbmFibGUgb3IgZGlzYWJsZSAicmVjZW50IGFsbG9jYXRpb24iIHRyYWNraW5nLgorICAgICAqLworICAgIG5hdGl2ZSBwdWJsaWMgc3RhdGljIHZvaWQgZW5hYmxlUmVjZW50QWxsb2NhdGlvbnMoYm9vbGVhbiBlbmFibGUpOworCisgICAgLyoKKyAgICAgKiBSZXR1cm4gYSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciBvciBub3QgdGhlICJyZWNlbnQgYWxsb2NhdGlvbiIKKyAgICAgKiBmZWF0dXJlIGlzIGN1cnJlbnRseSBlbmFibGVkLgorICAgICAqLworICAgIG5hdGl2ZSBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZ2V0UmVjZW50QWxsb2NhdGlvblN0YXR1cygpOworCisgICAgLyoqCisgICAgICogRmlsbCBhIGJ1ZmZlciB3aXRoIGRhdGEgb24gcmVjZW50IGhlYXAgYWxsb2NhdGlvbnMuCisgICAgICovCisgICAgbmF0aXZlIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIGdldFJlY2VudEFsbG9jYXRpb25zKCk7Cit9CisKZGlmZiAtLWdpdCBhL2RhbHZpay9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9kYWx2aWsvZGRtYy9SRUFETUUudHh0IGIvZGFsdmlrL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2RhbHZpay9kZG1jL1JFQURNRS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTlkZWY4MAotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9kYWx2aWsvZGRtYy9SRUFETUUudHh0CkBAIC0wLDAgKzEgQEAKK1RoZXNlIGNsYXNzZXMgYXJlIHRpZWQgdG8gdGhlIFZNLCBlLmcuIHRoZSBWTSBtYXkgaW52b2tlIHNvbWUgb2YgdGhlIG1ldGhvZHMuCmRpZmYgLS1naXQgYS9kYWx2aWsvc3JjL21haW4vbmF0aXZlL29yZ19hcGFjaGVfaGFybW9ueV9kYWx2aWtfTmF0aXZlVGVzdFRhcmdldC5jcHAgYi9kYWx2aWsvc3JjL21haW4vbmF0aXZlL29yZ19hcGFjaGVfaGFybW9ueV9kYWx2aWtfTmF0aXZlVGVzdFRhcmdldC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDZlMThhZQotLS0gL2Rldi9udWxsCisrKyBiL2RhbHZpay9zcmMvbWFpbi9uYXRpdmUvb3JnX2FwYWNoZV9oYXJtb255X2RhbHZpa19OYXRpdmVUZXN0VGFyZ2V0LmNwcApAQCAtMCwwICsxLDY4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2luY2x1ZGUgIkpOSUhlbHAuaCIKKworLyoKKyAqIHB1YmxpYyBzdGF0aWMgdm9pZCBlbXB0eUpuaVN0YXRpY01ldGhvZDAoKQorICoKKyAqIEZvciBiZW5jaG1hcmtzLCBhIGRvLW5vdGhpbmcgSk5JIG1ldGhvZCB3aXRoIG5vIGFyZ3VtZW50cy4KKyAqLworc3RhdGljIHZvaWQgZW1wdHlKbmlTdGF0aWNNZXRob2QwKEpOSUVudiosIGpjbGFzcykKK3sKKyAgICAvLyBUaGlzIHNwYWNlIGludGVudGlvbmFsbHkgbGVmdCBibGFuay4KK30KKworLyoKKyAqIHB1YmxpYyBzdGF0aWMgdm9pZCBlbXB0eUpuaVN0YXRpY01ldGhvZDYoaW50IGEsIGludCBiLCBpbnQgYywKKyAqICAgaW50IGQsIGludCBlLCBpbnQgZikKKyAqCisgKiBGb3IgYmVuY2htYXJrcywgYSBkby1ub3RoaW5nIEpOSSBtZXRob2Qgd2l0aCBzaXggYXJndW1lbnRzLgorICovCitzdGF0aWMgdm9pZCBlbXB0eUpuaVN0YXRpY01ldGhvZDYoSk5JRW52KiwgamNsYXNzLAorICAgIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQpCit7CisgICAgLy8gVGhpcyBzcGFjZSBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsuCit9CisKKy8qCisgKiBwdWJsaWMgc3RhdGljIHZvaWQgZW1wdHlKbmlTdGF0aWNNZXRob2Q2TChTdHJpbmcgYSwgU3RyaW5nW10gYiwKKyAqICAgaW50W11bXSBjLCBPYmplY3QgZCwgT2JqZWN0W10gZSwgT2JqZWN0W11bXVtdW10gZikKKyAqCisgKiBGb3IgYmVuY2htYXJrcywgYSBkby1ub3RoaW5nIEpOSSBtZXRob2Qgd2l0aCBzaXggYXJndW1lbnRzLgorICovCitzdGF0aWMgdm9pZCBlbXB0eUpuaVN0YXRpY01ldGhvZDZMKEpOSUVudiosIGpjbGFzcywKKyAgICBqb2JqZWN0LCBqYXJyYXksIGphcnJheSwgam9iamVjdCwgamFycmF5LCBqYXJyYXkpCit7CisgICAgLy8gVGhpcyBzcGFjZSBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsuCit9CisKK3N0YXRpYyBKTklOYXRpdmVNZXRob2QgZ01ldGhvZHNbXSA9IHsKKyAgeyAiZW1wdHlKbmlTdGF0aWNNZXRob2QwIiwgICIoKVYiLCAgICAgICAodm9pZCopZW1wdHlKbmlTdGF0aWNNZXRob2QwIH0sCisgIHsgImVtcHR5Sm5pU3RhdGljTWV0aG9kNiIsICAiKElJSUlJSSlWIiwgKHZvaWQqKWVtcHR5Sm5pU3RhdGljTWV0aG9kNiB9LAorICB7ICJlbXB0eUpuaVN0YXRpY01ldGhvZDZMIiwgIihMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9TdHJpbmc7W1tJTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0O1tbW1tMamF2YS9sYW5nL09iamVjdDspViIsICh2b2lkKillbXB0eUpuaVN0YXRpY01ldGhvZDZMIH0sCit9OworaW50IHJlZ2lzdGVyX29yZ19hcGFjaGVfaGFybW9ueV9kYWx2aWtfTmF0aXZlVGVzdFRhcmdldChKTklFbnYqIGVudikgeworICAgIGludCByZXN1bHQgPSBqbmlSZWdpc3Rlck5hdGl2ZU1ldGhvZHMoZW52LAorICAgICAgICAgICAgIm9yZy9hcGFjaGUvaGFybW9ueS9kYWx2aWsvTmF0aXZlVGVzdFRhcmdldCIsCisgICAgICAgICAgICBnTWV0aG9kcywgTkVMRU0oZ01ldGhvZHMpKTsKKyAgICBpZiAocmVzdWx0ICE9IDApIHsKKyAgICAgICAgLyogcHJpbnQgd2FybmluZywgYnV0IGFsbG93IHRvIGNvbnRpbnVlICovCisgICAgICAgIExPR1coIldBUk5JTkc6IE5hdGl2ZVRlc3RUYXJnZXQgbm90IHJlZ2lzdGVyZWRcbiIpOworICAgICAgICBlbnYtPkV4Y2VwdGlvbkNsZWFyKCk7CisgICAgfQorICAgIHJldHVybiAwOworfQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy9tYWluL25hdGl2ZS9zdWIubWsgYi9kYWx2aWsvc3JjL21haW4vbmF0aXZlL3N1Yi5tawpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YWRjOGExCi0tLSAvZGV2L251bGwKKysrIGIvZGFsdmlrL3NyYy9tYWluL25hdGl2ZS9zdWIubWsKQEAgLTAsMCArMSwxNyBAQAorIyAtKi0gbW9kZTogbWFrZWZpbGUgLSotCisjIFRoaXMgZmlsZSBpcyBpbmNsdWRlZCBieSB0aGUgdG9wLWxldmVsIGxpYmNvcmUgQW5kcm9pZC5tay4KKyMgSXQncyBub3QgYSBub3JtYWwgbWFrZWZpbGUsIHNvIHdlIGRvbid0IGluY2x1ZGUgQ0xFQVJfVkFSUworIyBvciBCVUlMRF8qX0xJQlJBUlkuCisKK0xPQ0FMX1NSQ19GSUxFUyA6PSBcCisJb3JnX2FwYWNoZV9oYXJtb255X2RhbHZpa19OYXRpdmVUZXN0VGFyZ2V0LmNwcAorCisjTE9DQUxfQ19JTkNMVURFUyArPQorCisjIEFueSBzaGFyZWQvc3RhdGljIGxpYnMgdGhhdCBhcmUgbGlzdGVkIGhlcmUgbXVzdCBhbHNvCisjIGJlIGxpc3RlZCBpbiBsaWJzL25hdGl2ZWhlbHBlci9BbmRyb2lkLm1rLgorIyBUT0RPOiBmaXggdGhpcyByZXF1aXJlbWVudAorCisjTE9DQUxfU0hBUkVEX0xJQlJBUklFUyArPQorCisjTE9DQUxfU1RBVElDX0xJQlJBUklFUyArPQpkaWZmIC0tZ2l0IGEvZGFsdmlrL3NyYy90ZXN0L2phdmEvZGFsdmlrL3N5c3RlbS9wcm9maWxlci9TYW1wbGluZ1Byb2ZpbGVyVGVzdC5qYXZhIGIvZGFsdmlrL3NyYy90ZXN0L2phdmEvZGFsdmlrL3N5c3RlbS9wcm9maWxlci9TYW1wbGluZ1Byb2ZpbGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQwMjJjZDAKLS0tIC9kZXYvbnVsbAorKysgYi9kYWx2aWsvc3JjL3Rlc3QvamF2YS9kYWx2aWsvc3lzdGVtL3Byb2ZpbGVyL1NhbXBsaW5nUHJvZmlsZXJUZXN0LmphdmEKQEAgLTAsMCArMSwzMDkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGRhbHZpay5zeXN0ZW0ucHJvZmlsZXI7CisKK2ltcG9ydCBkYWx2aWsuc3lzdGVtLnByb2ZpbGVyLkFzY2lpSHByb2ZXcml0ZXI7CitpbXBvcnQgZGFsdmlrLnN5c3RlbS5wcm9maWxlci5CaW5hcnlIcHJvZlJlYWRlcjsKK2ltcG9ydCBkYWx2aWsuc3lzdGVtLnByb2ZpbGVyLkJpbmFyeUhwcm9mV3JpdGVyOworaW1wb3J0IGRhbHZpay5zeXN0ZW0ucHJvZmlsZXIuSHByb2ZEYXRhLlNhbXBsZTsKK2ltcG9ydCBkYWx2aWsuc3lzdGVtLnByb2ZpbGVyLkhwcm9mRGF0YS5TdGFja1RyYWNlOworaW1wb3J0IGRhbHZpay5zeXN0ZW0ucHJvZmlsZXIuSHByb2ZEYXRhLlRocmVhZEV2ZW50OworaW1wb3J0IGRhbHZpay5zeXN0ZW0ucHJvZmlsZXIuSHByb2ZEYXRhOworaW1wb3J0IGRhbHZpay5zeXN0ZW0ucHJvZmlsZXIuU2FtcGxpbmdQcm9maWxlci5UaHJlYWRTZXQ7CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLkRIUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBTYW1wbGluZ1Byb2ZpbGVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFJ1biB0aGUgU2FtcGxpbmdQcm9maWxlciB0byBnYXRoZXIgc29tZSBkYXRhIG9uIGFuIGFjdHVhbAorICAgICAqIGNvbXB1dGF0aW9uLCB0aGVuIGFzc2VydCB0aGF0IGl0IGxvb2tzIGNvcnJlY3Qgd2l0aCB0ZXN0X0hwcm9mRGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NhbXBsaW5nUHJvZmlsZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGhyZWFkU2V0IHRocmVhZFNldCA9IFNhbXBsaW5nUHJvZmlsZXIubmV3QXJyYXlUaHJlYWRTZXQoVGhyZWFkLmN1cnJlbnRUaHJlYWQoKSk7CisgICAgICAgIFNhbXBsaW5nUHJvZmlsZXIgcHJvZmlsZXIgPSBuZXcgU2FtcGxpbmdQcm9maWxlcigxMiwgdGhyZWFkU2V0KTsKKyAgICAgICAgcHJvZmlsZXIuc3RhcnQoMTAwKTsKKyAgICAgICAgdG9CZU1lYXN1cmVkKCk7CisgICAgICAgIHByb2ZpbGVyLnN0b3AoKTsKKyAgICAgICAgcHJvZmlsZXIuc2h1dGRvd24oKTsKKyAgICAgICAgdGVzdF9IcHJvZkRhdGEocHJvZmlsZXIuZ2V0SHByb2ZEYXRhKCksIHRydWUpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQX1NUUiA9CisgICAgICAgICAgICAiOTQ5NGZlYzA5NWYzYjg1ZWUyODY1NDJiMzgzNmZjODFhNWRkMGEwMzQ5YjRjMjM5ZGQzODc0NGQ0ODhjZjhlMyIKKyAgICAgICAgICAgICsgIjFkYjhiY2I3ZDMzYjQxYWJiOWU1YTMzY2NhOTE0NGIxY2VmMzMyYzk0YmYwNTczYmYwNDdhM2FjYTk4Y2RmM2IiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBHX1NUUiA9CisgICAgICAgICAgICAiOThhYjdjNWM0MzE0NzlkODY0NWUzM2FhMDk3NThlMDkwN2M3ODc0Nzc5OGQwOTY4NTc2Zjk4Nzc0MjFhOTA4OSIKKyAgICAgICAgICAgICsgIjc1NmY3ODc2ZTc2NTkwYjc2NzY1NjQ1Yzk4Nzk3NmQ3NjRkZDQ1NjQ2OThhODc1ODVlNjQ1NTQ5ODRiYjQ0NDUiCisgICAgICAgICAgICArICI3NmU1NzY0Nzg2Zjg3NWI0NDU2YyI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gUCA9IG5ldyBCaWdJbnRlZ2VyKFBfU1RSLDE2KS50b0J5dGVBcnJheSgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBHID0gbmV3IEJpZ0ludGVnZXIoR19TVFIsMTYpLnRvQnl0ZUFycmF5KCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHRvQmVNZWFzdXJlZCAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbG9uZyBzdGFydCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDAwOyBpKyspIHsKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgcCA9IG5ldyBCaWdJbnRlZ2VyKFApOworICAgICAgICAgICAgQmlnSW50ZWdlciBnID0gbmV3IEJpZ0ludGVnZXIoRyk7CisgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGdlbiA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRIIik7CisgICAgICAgICAgICBnZW4uaW5pdGlhbGl6ZShuZXcgREhQYXJhbWV0ZXJTcGVjKHAsIGcpLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICB9CisgICAgICAgIGxvbmcgZW5kID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9IcHJvZkRhdGFfbnVsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEhwcm9mRGF0YShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfSHByb2ZEYXRhX2VtcHR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1hcDxTdGFja1RyYWNlLCBpbnRbXT4gc3RhY2tUcmFjZXMgPSBuZXcgSGFzaE1hcDxTdGFja1RyYWNlLCBpbnRbXT4oKTsKKyAgICAgICAgSHByb2ZEYXRhIGhwcm9mRGF0YSA9IG5ldyBIcHJvZkRhdGEoc3RhY2tUcmFjZXMpOworICAgICAgICB0ZXN0X0hwcm9mRGF0YShocHJvZkRhdGEsIHRydWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfSHByb2ZEYXRhX3RpbWVNaWxsaXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWFwPFN0YWNrVHJhY2UsIGludFtdPiBzdGFja1RyYWNlcyA9IG5ldyBIYXNoTWFwPFN0YWNrVHJhY2UsIGludFtdPigpOworICAgICAgICBIcHJvZkRhdGEgaHByb2ZEYXRhID0gbmV3IEhwcm9mRGF0YShzdGFja1RyYWNlcyk7CisgICAgICAgIGxvbmcgbm93ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgIGhwcm9mRGF0YS5zZXRTdGFydE1pbGxpcyhub3cpOworICAgICAgICBhc3NlcnRFcXVhbHMobm93LCBocHJvZkRhdGEuZ2V0U3RhcnRNaWxsaXMoKSk7CisgICAgICAgIHRlc3RfSHByb2ZEYXRhKGhwcm9mRGF0YSwgdHJ1ZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9IcHJvZkRhdGFfYWRkVGhyZWFkRXZlbnRfbnVsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNYXA8U3RhY2tUcmFjZSwgaW50W10+IHN0YWNrVHJhY2VzID0gbmV3IEhhc2hNYXA8U3RhY2tUcmFjZSwgaW50W10+KCk7CisgICAgICAgIEhwcm9mRGF0YSBocHJvZkRhdGEgPSBuZXcgSHByb2ZEYXRhKHN0YWNrVHJhY2VzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGhwcm9mRGF0YS5hZGRUaHJlYWRFdmVudChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0ZXN0X0hwcm9mRGF0YShocHJvZkRhdGEsIHRydWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfSHByb2ZEYXRhX2FkZFRocmVhZEV2ZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1hcDxTdGFja1RyYWNlLCBpbnRbXT4gc3RhY2tUcmFjZXMgPSBuZXcgSGFzaE1hcDxTdGFja1RyYWNlLCBpbnRbXT4oKTsKKyAgICAgICAgSHByb2ZEYXRhIGhwcm9mRGF0YSA9IG5ldyBIcHJvZkRhdGEoc3RhY2tUcmFjZXMpOworCisgICAgICAgIC8vIHNob3VsZCBoYXZlIG5vdGhpbmcgaW4gdGhlIHRocmVhZCBoaXN0b3J5IHRvIHN0YXJ0CisgICAgICAgIGFzc2VydEVxdWFscygwLCBocHJvZkRhdGEuZ2V0VGhyZWFkSGlzdG9yeSgpLnNpemUoKSk7CisKKyAgICAgICAgLy8gYWRkIHRocmVhZCAxCisgICAgICAgIGZpbmFsIGludCB0aHJlYWRJZCA9IDE7CisgICAgICAgIGZpbmFsIGludCBvYmplY3RJZCA9IDI7CisgICAgICAgIFRocmVhZEV2ZW50IHN0YXJ0MSA9IFRocmVhZEV2ZW50LnN0YXJ0KG9iamVjdElkLCB0aHJlYWRJZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRocmVhZC1uYW1lIiwgInRocmVhZC1ncm91cCIsICJwYXJlbnQtZ3JvdXAiKTsKKyAgICAgICAgaHByb2ZEYXRhLmFkZFRocmVhZEV2ZW50KHN0YXJ0MSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KHN0YXJ0MSksIGhwcm9mRGF0YS5nZXRUaHJlYWRIaXN0b3J5KCkpOworICAgICAgICB0ZXN0X0hwcm9mRGF0YShocHJvZkRhdGEsIHRydWUpOworCisgICAgICAgIC8vIHJlbW92ZSB0aHJlYWQgMiwgd2hpY2ggc2hvdWxkIG5vdCBleGlzdCAoYnV0IHRoYXQncyBva2F5IG9uIHRoZSBSSSkKKyAgICAgICAgVGhyZWFkRXZlbnQgZW5kMiA9IFRocmVhZEV2ZW50LmVuZCh0aHJlYWRJZCsxKTsKKyAgICAgICAgaHByb2ZEYXRhLmFkZFRocmVhZEV2ZW50KGVuZDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChzdGFydDEsIGVuZDIpLCBocHJvZkRhdGEuZ2V0VGhyZWFkSGlzdG9yeSgpKTsKKyAgICAgICAgdGVzdF9IcHJvZkRhdGEoaHByb2ZEYXRhLCBmYWxzZSk7IC8vIG5vbi1zdHJpY3QgZnJvbSBoZXJlIGRvd24gYmVjYXVzZSBvZiB0aGlzIFJJIGRhdGEKKworICAgICAgICAvLyByZW1vdmUgdGhyZWFkIDEsIHdoaWNoIHNob3VsZCBleGlzdAorICAgICAgICBUaHJlYWRFdmVudCBlbmQxID0gVGhyZWFkRXZlbnQuZW5kKHRocmVhZElkKTsKKyAgICAgICAgaHByb2ZEYXRhLmFkZFRocmVhZEV2ZW50KGVuZDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChzdGFydDEsIGVuZDIsIGVuZDEpLCBocHJvZkRhdGEuZ2V0VGhyZWFkSGlzdG9yeSgpKTsKKyAgICAgICAgdGVzdF9IcHJvZkRhdGEoaHByb2ZEYXRhLCBmYWxzZSk7CisKKyAgICAgICAgLy8gcmVtb3ZlIHRocmVhZCAxIGFnYWluLCB3aGljaCBzaG91bGQgbm90IGV4aXN0IChpdHMgbm90IG9rYXkgdG8gaGF2ZSBlbmQgZm9sbG93ZWQgYnkgZW5kKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaHByb2ZEYXRhLmFkZFRocmVhZEV2ZW50KFRocmVhZEV2ZW50LmVuZCh0aHJlYWRJZCkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChzdGFydDEsIGVuZDIsIGVuZDEpLCBocHJvZkRhdGEuZ2V0VGhyZWFkSGlzdG9yeSgpKTsKKyAgICAgICAgdGVzdF9IcHJvZkRhdGEoaHByb2ZEYXRhLCBmYWxzZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9IcHJvZkRhdGFfYWRkU3RhY2tUcmFjZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNYXA8U3RhY2tUcmFjZSwgaW50W10+IHN0YWNrVHJhY2VzID0gbmV3IEhhc2hNYXA8U3RhY2tUcmFjZSwgaW50W10+KCk7CisgICAgICAgIEhwcm9mRGF0YSBocHJvZkRhdGEgPSBuZXcgSHByb2ZEYXRhKHN0YWNrVHJhY2VzKTsKKworICAgICAgICAvLyBzaG91bGQgaGF2ZSBubyBzYW1wbGVzIHRvIHN0YXJ0CisgICAgICAgIGFzc2VydEVxdWFscygwLCBocHJvZkRhdGEuZ2V0U2FtcGxlcygpLnNpemUoKSk7CisKKyAgICAgICAgLy8gYXR0ZW1wdCB0byBhZGQgYSBzdGFjayBmb3IgYSBub24tZXhpc3RlbnQgdGhyZWFkLCBzaG91bGQgZmFpbAorICAgICAgICBmaW5hbCBpbnQgc3RhY2tUcmFjZUlkID0gMTsKKyAgICAgICAgZmluYWwgaW50IHRocmVhZElkID0gMjsKKyAgICAgICAgZmluYWwgaW50IG9iamVjdElkID0gMzsKKyAgICAgICAgZmluYWwgaW50IHNhbXBsZUNvdW50ID0gNDsKKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnRbXSBzdGFja0ZyYW1lcyA9IG5ldyBUaHJvd2FibGUoKS5nZXRTdGFja1RyYWNlKCk7CisgICAgICAgIGZpbmFsIGludFtdIGNvdW50Q2VsbCA9IG5ldyBpbnRbXSB7IDQgfTsKKyAgICAgICAgU3RhY2tUcmFjZSBzdGFja1RyYWNlID0gbmV3IFN0YWNrVHJhY2Uoc3RhY2tUcmFjZUlkLCB0aHJlYWRJZCwgc3RhY2tGcmFtZXMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaHByb2ZEYXRhLmFkZFN0YWNrVHJhY2Uoc3RhY2tUcmFjZSwgY291bnRDZWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICAvLyBhZGQgdGhlIHRocmVhZCBhbmQgYWRkIHRoZSBldmVudAorICAgICAgICBUaHJlYWRFdmVudCBzdGFydCA9IFRocmVhZEV2ZW50LnN0YXJ0KG9iamVjdElkLCB0aHJlYWRJZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGhyZWFkLW5hbWUiLCAidGhyZWFkLWdyb3VwIiwgInBhcmVudC1ncm91cCIpOworICAgICAgICBocHJvZkRhdGEuYWRkVGhyZWFkRXZlbnQoc3RhcnQpOworICAgICAgICBocHJvZkRhdGEuYWRkU3RhY2tUcmFjZShzdGFja1RyYWNlLCBjb3VudENlbGwpOworICAgICAgICBTZXQ8U2FtcGxlPiBzYW1wbGVzID0gaHByb2ZEYXRhLmdldFNhbXBsZXMoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzYW1wbGVzKTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShzYW1wbGVzLCBocHJvZkRhdGEuZ2V0U2FtcGxlcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHNhbXBsZXMuc2l6ZSgpKTsKKyAgICAgICAgU2FtcGxlIHNhbXBsZSA9IHNhbXBsZXMuaXRlcmF0b3IoKS5uZXh0KCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoc2FtcGxlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHN0YWNrVHJhY2UsIHNhbXBsZS5zdGFja1RyYWNlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNhbXBsZUNvdW50LCBzYW1wbGUuY291bnQpOworICAgICAgICB0ZXN0X0hwcm9mRGF0YShocHJvZkRhdGEsIHRydWUpOworCisgICAgICAgIC8vIGNvbmZpcm0gd2UgY2FuIG11dGF0ZSB0aGUgc2FtcGxlIGNvdW50LCBidXQgdGhhdCBpdHMgbm90CisgICAgICAgIC8vIHZpc2libGUgaW4gdGhlIGN1cnJlbnQgc2FtcGxlLCBidXQgaXQgd2lsbCBiZSB2aXNpYmxlIGluIGEKKyAgICAgICAgLy8gbmV3IG9uZS4KKyAgICAgICAgY291bnRDZWxsWzBdICs9IDQyOworICAgICAgICBhc3NlcnRFcXVhbHMoc2FtcGxlQ291bnQsIHNhbXBsZS5jb3VudCk7CisgICAgICAgIFNhbXBsZSBzYW1wbGUyID0gaHByb2ZEYXRhLmdldFNhbXBsZXMoKS5pdGVyYXRvcigpLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNhbXBsZUNvdW50ICsgNDIsIHNhbXBsZTIuY291bnQpOworICAgICAgICB0ZXN0X0hwcm9mRGF0YShocHJvZkRhdGEsIHRydWUpOworCisgICAgICAgIC8vIHRyeSB0byByZXVzZSB0aGUgc3RhY2tUcmFjZUlkLCBzaG91bGQgZmFpbAorICAgICAgICB0cnkgeworICAgICAgICAgICAgaHByb2ZEYXRhLmFkZFN0YWNrVHJhY2Uoc3RhY2tUcmFjZSwgY291bnRDZWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGhwcm9mRGF0YS5nZXRTYW1wbGVzKCkuc2l6ZSgpKTsKKyAgICAgICAgdGVzdF9IcHJvZkRhdGEoaHByb2ZEYXRhLCB0cnVlKTsKKworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0X0hwcm9mRGF0YShIcHJvZkRhdGEgaHByb2ZEYXRhLCBib29sZWFuIHN0cmljdCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEhwcm9mRGF0YShocHJvZkRhdGEsIHN0cmljdCk7CisgICAgICAgIHRlc3RfSHByb2ZEYXRhX2FzY2lpKGhwcm9mRGF0YSk7CisgICAgICAgIHRlc3RfSHByb2ZEYXRhX2JpbmFyeShocHJvZkRhdGEsIHN0cmljdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzZXJ0IGdlbmVyYWwgcHJvcGVyaXRpZXMgb2YgSHByb2ZEYXRhIGhvbGQgdHJ1ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0SHByb2ZEYXRhKEhwcm9mRGF0YSBocHJvZkRhdGEsIGJvb2xlYW4gc3RyaWN0KSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTGlzdDxUaHJlYWRFdmVudD4gdGhyZWFkSGlzdG9yeSA9IGhwcm9mRGF0YS5nZXRUaHJlYWRIaXN0b3J5KCk7CisgICAgICAgIGFzc2VydE5vdE51bGwodGhyZWFkSGlzdG9yeSk7CisgICAgICAgIFNldDxJbnRlZ2VyPiB0aHJlYWRzU2VlbiA9IG5ldyBIYXNoU2V0PEludGVnZXI+KCk7CisgICAgICAgIFNldDxJbnRlZ2VyPiB0aHJlYWRzQWN0aXZlID0gbmV3IEhhc2hTZXQ8SW50ZWdlcj4oKTsKKyAgICAgICAgZm9yIChUaHJlYWRFdmVudCBldmVudCA6IHRocmVhZEhpc3RvcnkpIHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZXZlbnQpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChldmVudC50eXBlKTsKKyAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQudHlwZSkgeworICAgICAgICAgICAgICAgIGNhc2UgU1RBUlQ6CisgICAgICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZXZlbnQudGhyZWFkTmFtZSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUodGhyZWFkc0FjdGl2ZS5hZGQoZXZlbnQudGhyZWFkSWQpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSh0aHJlYWRzU2Vlbi5hZGQoZXZlbnQudGhyZWFkSWQpKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBFTkQ6CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgZXZlbnQub2JqZWN0SWQpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGV2ZW50LnRocmVhZE5hbWUpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGV2ZW50Lmdyb3VwTmFtZSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydE51bGwoZXZlbnQucGFyZW50R3JvdXBOYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmljdCkgeworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSh0aHJlYWRzQWN0aXZlLnJlbW92ZShldmVudC50aHJlYWRJZCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgU2V0PFNhbXBsZT4gc2FtcGxlcyA9IGhwcm9mRGF0YS5nZXRTYW1wbGVzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoc2FtcGxlcyk7CisgICAgICAgIGZvciAoU2FtcGxlIHNhbXBsZSA6IHNhbXBsZXMpIHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc2FtcGxlKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoc2FtcGxlLmNvdW50ID4gMCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHNhbXBsZS5zdGFja1RyYWNlKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoc2FtcGxlLnN0YWNrVHJhY2Uuc3RhY2tUcmFjZUlkICE9IC0xKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUodGhyZWFkc1NlZW4uY29udGFpbnMoc2FtcGxlLnN0YWNrVHJhY2UuZ2V0VGhyZWFkSWQoKSkpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChzYW1wbGUuc3RhY2tUcmFjZS5nZXRTdGFja0ZyYW1lcygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnQgdG8gSHByb2ZEYXRhIHRvIEFTQ0lJIHRvIHNlZSBpZiBpdCB0cmlnZ2VycyBhbnkgZXhjZXB0aW9ucworICAgICAqLworICAgIHByaXZhdGUgdm9pZCB0ZXN0X0hwcm9mRGF0YV9hc2NpaShIcHJvZkRhdGEgaHByb2ZEYXRhKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgQXNjaWlIcHJvZldyaXRlci53cml0ZShocHJvZkRhdGEsIG91dCk7CisgICAgICAgIGFzc2VydEZhbHNlKG91dC50b0J5dGVBcnJheSgpLmxlbmd0aCA9PSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0IHRvIEhwcm9mRGF0YSB0byBiaW5hcnkgYW5kIHRoZW4gcmVwYXJzZSBhcyB0bworICAgICAqIEhwcm9mRGF0YS4gTWFrZSBzdXJlIHRoZSBhY2Nlc3NpYmxlIGRhdGEgaXMgZXF1aXZhbGVudC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgdGVzdF9IcHJvZkRhdGFfYmluYXJ5KEhwcm9mRGF0YSBocHJvZkRhdGEsIGJvb2xlYW4gc3RyaWN0KSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBCaW5hcnlIcHJvZldyaXRlci53cml0ZShocHJvZkRhdGEsIG91dCk7CisgICAgICAgIG91dC5jbG9zZSgpOworCisgICAgICAgIGJ5dGVbXSBieXRlcyA9IG91dC50b0J5dGVBcnJheSgpOworICAgICAgICBhc3NlcnRGYWxzZShieXRlcy5sZW5ndGggPT0gMCk7CisgICAgICAgIGlmIChmYWxzZSkgeworICAgICAgICAgICAgRmlsZSBmaWxlID0gbmV3IEZpbGUoIi9zZGNhcmQvamF2YS5ocHJvZiIpOworICAgICAgICAgICAgT3V0cHV0U3RyZWFtIGRlYnVnID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZSk7CisgICAgICAgICAgICBkZWJ1Zy53cml0ZShieXRlcyk7CisgICAgICAgICAgICBkZWJ1Zy5jbG9zZSgpOworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJXcm90ZSBiaW5hcnkgaHByb2YgZGF0YSB0byAiICsgZmlsZSk7CisgICAgICAgIH0KKworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcyk7CisgICAgICAgIEJpbmFyeUhwcm9mUmVhZGVyIHJlYWRlciA9IG5ldyBCaW5hcnlIcHJvZlJlYWRlcihpbik7CisgICAgICAgIGFzc2VydFRydWUocmVhZGVyLmdldFN0cmljdCgpKTsKKyAgICAgICAgcmVhZGVyLnJlYWQoKTsKKyAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJKQVZBIFBST0ZJTEUgMS4wLjIiLCByZWFkZXIuZ2V0VmVyc2lvbigpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChyZWFkZXIuZ2V0SHByb2ZEYXRhKCkpOworCisgICAgICAgIEhwcm9mRGF0YSBwYXJzZWQgPSByZWFkZXIuZ2V0SHByb2ZEYXRhKCk7CisgICAgICAgIGFzc2VydEhwcm9mRGF0YShocHJvZkRhdGEsIHN0cmljdCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExvbmcudG9IZXhTdHJpbmcoaHByb2ZEYXRhLmdldFN0YXJ0TWlsbGlzKCkpLAorICAgICAgICAgICAgICAgICAgICAgTG9uZy50b0hleFN0cmluZyhwYXJzZWQuZ2V0U3RhcnRNaWxsaXMoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoTG9uZy50b0hleFN0cmluZyhocHJvZkRhdGEuZ2V0RmxhZ3MoKSksCisgICAgICAgICAgICAgICAgICAgICBMb25nLnRvSGV4U3RyaW5nKHBhcnNlZC5nZXRGbGFncygpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhMb25nLnRvSGV4U3RyaW5nKGhwcm9mRGF0YS5nZXREZXB0aCgpKSwKKyAgICAgICAgICAgICAgICAgICAgIExvbmcudG9IZXhTdHJpbmcocGFyc2VkLmdldERlcHRoKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGhwcm9mRGF0YS5nZXRUaHJlYWRIaXN0b3J5KCksCisgICAgICAgICAgICAgICAgICAgICBwYXJzZWQuZ2V0VGhyZWFkSGlzdG9yeSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGhwcm9mRGF0YS5nZXRTYW1wbGVzKCksCisgICAgICAgICAgICAgICAgICAgICBwYXJzZWQuZ2V0U2FtcGxlcygpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9SRUFETUUgYi9kb20vc3JjL3Rlc3QvamF2YS9SRUFETUUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGI5ZDlkNAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL1JFQURNRQpAQCAtMCwwICsxLDEwIEBACithbGwgY2xhc3NlcyB1bmRlciBvcmcudzNjLmRvbXRzIGFyZSBmcm9tIHRoZSBvZmZpY2lhbCB3M2MgdGVzdCBzdWl0ZS4KK0xldmVsIDEgQ29yZSB0ZXN0cyBhbmQgTGV2ZWwgMiBDb3JlIHRlc3RzIGZyb20KK2h0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0LworCithZGRpdGlvbnMgbWFkZToKK2FsbCBhZGRpdGlvbnMgdW5kZXIgb3JnLnczYy5kb20uKiBhbmQgb3JnLnczYy5kb20uZXZlbnRzLioKKworCityZW1vdmFsczoKK29yZy93M2MvZG9tdHMvSlVuaXRSdW5uZXIuamF2YQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9CYXRpa1Rlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0JhdGlrVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZTVjNjgyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9CYXRpa1Rlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmphdmEKQEAgLTAsMCArMSwyMzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHM7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlcjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5OworCitpbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CisKKy8qKgorICogICBUaGlzIGNsYXNzIGltcGxlbWVudHMgdGhlIGdlbmVyaWMgcGFyc2VyIGFuZCBjb25maWd1YXRpb24KKyAqICAgYWJzdHJhY3QgY2xhc3MgZm9yIHRoZSBET00gaW1wbGVtZW50YXRpb24gb2YgQmF0aWsuCisgKgorICogICBAYXV0aG9yIEN1cnQgQXJub2xkCisgKi8KK3B1YmxpYyBjbGFzcyBCYXRpa1Rlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgZXh0ZW5kcyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB7CisKKyAgLyoqICBkb20gZmFjdG9yeS4gICovCisgIHByaXZhdGUgT2JqZWN0IGRvbUZhY3Rvcnk7CisKKyAgLyoqICB4bWwgcmVhZGVyLiAgICAqLworICBwcml2YXRlIG9yZy54bWwuc2F4LlhNTFJlYWRlciB4bWxSZWFkZXI7CisKKyAgLyoqICByZWZsZWN0aXZlIG1ldGhvZCB0byBjcmVhdGUgZG9jdW1lbnQgaW4gQmF0aWsuICAgKiovCisgIHByaXZhdGUgTWV0aG9kIGNyZWF0ZURvY3VtZW50OworCisgIC8qKiAgZG9tIGltcGxlbWVudGF0aW9uIGZyb20gQmF0aWsuICAgKiovCisgIHByaXZhdGUgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKworICAvKioKKyAgICogQ3JlYXRlcyBhIEJhdGlrIGltcGxlbWVudGF0aW9uIG9mIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LgorICAgKiBAcGFyYW0gc2V0dGluZ3MgYXJyYXkgb2Ygc2V0dGluZ3MsIG1heSBiZSBudWxsLgorICAgKiBAdGhyb3dzIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24KKyAgICogICAgIElmIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgdGhlIHNwZWNpZmllZCBzZXR0aW5ncworICAgKi8KKyAgcHVibGljIEJhdGlrVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkoCisgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MpIHRocm93cyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICBzdXBlcihzZXR0aW5ncyk7CisgICAgZG9tSW1wbCA9IG51bGw7CisKKyAgICAvLworICAgIC8vICAgZ2V0IHRoZSBKQVhQIHNwZWNpZmllZCBTQVggcGFyc2VyJ3MgY2xhc3MgbmFtZQorICAgIC8vCisgICAgU0FYUGFyc2VyRmFjdG9yeSBzYXhGYWN0b3J5ID0gU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICAgIHRyeSB7CisgICAgICBTQVhQYXJzZXIgc2F4UGFyc2VyID0gc2F4RmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKKyAgICAgIHhtbFJlYWRlciA9IHNheFBhcnNlci5nZXRYTUxSZWFkZXIoKTsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgIHRocm93IG5ldyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uKGV4LCBudWxsKTsKKyAgICB9CisgICAgU3RyaW5nIHhtbFJlYWRlckNsYXNzTmFtZSA9IHhtbFJlYWRlci5nZXRDbGFzcygpLmdldE5hbWUoKTsKKworICAgIC8vCisgICAgLy8gICBjYW4ndCBjaGFuZ2Ugc2V0dGluZ3MsIHNvIGlmIG5vdCB0aGUgc2FtZSBhcworICAgIC8vICAgICAgdGhlIGRlZmF1bHQgU0FYIHBhcnNlciB0aGVuIHRocm93IGFuIGV4Y2VwdGlvbgorICAgIC8vCisgICAgLy8gICAgZm9yKGludCBpID0gMDsgaSA8IHNldHRpbmdzLmxlbmd0aDsgaSsrKSB7CisgICAgLy8gICAgICBpZighc2V0dGluZ3NbaV0uaGFzU2V0dGluZyh0aGlzKSkgeworICAgIC8vICAgICAgICBUT0RPCisgICAgLy8gICAgICAgIHRocm93IG5ldyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uKG51bGwsc2V0dGluZ3NbaV0pOworICAgIC8vICAgICAgfQorICAgIC8vICAgIH0KKyAgICAvLworICAgIC8vICAgdHJ5IGxvYWRpbmcgQmF0aWsgcmVmbGVjdGl2ZWx5CisgICAgLy8KKyAgICB0cnkgeworICAgICAgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpOworICAgICAgQ2xhc3MgZG9tRmFjdG9yeUNsYXNzID0KKyAgICAgICAgICBjbGFzc0xvYWRlci5sb2FkQ2xhc3MoCisgICAgICAgICAgIm9yZy5hcGFjaGUuYmF0aWsuZG9tLnN2Zy5TQVhTVkdEb2N1bWVudEZhY3RvcnkiKTsKKworICAgICAgQ29uc3RydWN0b3IgZG9tRmFjdG9yeUNvbnN0cnVjdG9yID0KKyAgICAgICAgICBkb21GYWN0b3J5Q2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzW10ge1N0cmluZy5jbGFzc30pOworICAgICAgZG9tRmFjdG9yeSA9CisgICAgICAgICAgZG9tRmFjdG9yeUNvbnN0cnVjdG9yLm5ld0luc3RhbmNlKAorICAgICAgICAgIG5ldyBPYmplY3RbXSB7eG1sUmVhZGVyQ2xhc3NOYW1lfSk7CisgICAgICBjcmVhdGVEb2N1bWVudCA9CisgICAgICAgICAgZG9tRmFjdG9yeUNsYXNzLmdldE1ldGhvZCgKKyAgICAgICAgICAiY3JlYXRlRG9jdW1lbnQiLAorICAgICAgICAgIG5ldyBDbGFzc1tdIHtTdHJpbmcuY2xhc3MsIGphdmEuaW8uSW5wdXRTdHJlYW0uY2xhc3N9KTsKKyAgICB9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGV4KSB7CisgICAgICB0aHJvdyBuZXcgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbigKKyAgICAgICAgICBleC5nZXRUYXJnZXRFeGNlcHRpb24oKSwKKyAgICAgICAgICBudWxsKTsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgIHRocm93IG5ldyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uKGV4LCBudWxsKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogICAgQ3JlYXRlIG5ldyBpbnN0YW5jZSBvZiBkb2N1bWVudCBidWlsZGVyIGZhY3RvcnkKKyAgICogICAgcmVmbGVjdGluZyBzcGVjaWZpZWQgc2V0dGluZ3MuCisgICAqICAgIEBwYXJhbSBuZXdTZXR0aW5ncyBuZXcgc2V0dGluZ3MKKyAgICogICAgQHJldHVybiBOZXcgaW5zdGFuY2UKKyAgICogICAgQHRocm93cyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uCisgICAqICAgICAgICAgaWYgc2V0dGluZ3MgYXJlIG5vdCBzdXBwb3J0ZWQgYnkgaW1wbGVtZW50YXRpb24KKyAgICovCisgIHB1YmxpYyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBuZXdJbnN0YW5jZSgKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdbXSBuZXdTZXR0aW5ncykKKyAgICAgICAgdGhyb3dzIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgIGlmIChuZXdTZXR0aW5ncyA9PSBudWxsKSB7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIG1lcmdlZFNldHRpbmdzID0gbWVyZ2VTZXR0aW5ncyhuZXdTZXR0aW5ncyk7CisgICAgcmV0dXJuIG5ldyBCYXRpa1Rlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5KG1lcmdlZFNldHRpbmdzKTsKKyAgfQorCisgIC8qKgorICAgKiAgICBMb2FkcyBzcGVjaWZpZWQgVVJMLgorICAgKiAgICBAcGFyYW0gdXJsIHVybCB0byBsb2FkCisgICAqICAgIEByZXR1cm4gRE9NIGRvY3VtZW50CisgICAqICAgIEB0aHJvd3MgRE9NVGVzdExvYWRFeGNlcHRpb24gaWYgdW5hYmxlIHRvIGxvYWQgZG9jdW1lbnQKKyAgICovCisgIHB1YmxpYyBEb2N1bWVudCBsb2FkKGphdmEubmV0LlVSTCB1cmwpIHRocm93cyBET01UZXN0TG9hZEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gc3RyZWFtID0gdXJsLm9wZW5TdHJlYW0oKTsKKyAgICAgIHJldHVybiAob3JnLnczYy5kb20uRG9jdW1lbnQpIGNyZWF0ZURvY3VtZW50Lmludm9rZSgKKyAgICAgICAgICBkb21GYWN0b3J5LAorICAgICAgICAgIG5ldyBPYmplY3RbXSB7dXJsLnRvU3RyaW5nKCksIHN0cmVhbX0pOworICAgIH0gY2F0Y2ggKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZXgpIHsKKyAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworICAgICAgdGhyb3cgbmV3IERPTVRlc3RMb2FkRXhjZXB0aW9uKGV4LmdldFRhcmdldEV4Y2VwdGlvbigpKTsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworICAgICAgdGhyb3cgbmV3IERPTVRlc3RMb2FkRXhjZXB0aW9uKGV4KTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogICAgIEdldHMgRE9NSW1wbGVtZW50YXRpb24uCisgICAqICAgICBAcmV0dXJuIERPTSBpbXBsZW1lbnRhdGlvbiwgbWF5IGJlIG51bGwKKyAgICovCisgIHB1YmxpYyBET01JbXBsZW1lbnRhdGlvbiBnZXRET01JbXBsZW1lbnRhdGlvbigpIHsKKyAgICAvLworICAgIC8vICAgZ2V0IERPTSBpbXBsZW1lbnRhdGlvbgorICAgIC8vCisgICAgaWYgKGRvbUltcGwgPT0gbnVsbCkgeworICAgICAgdHJ5IHsKKyAgICAgICAgQ2xhc3Mgc3ZnRG9tSW1wbENsYXNzID0KKyAgICAgICAgICAgIENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKAorICAgICAgICAgICAgIm9yZy5hcGFjaGUuYmF0aWsuZG9tLnN2Zy5TVkdET01JbXBsZW1lbnRhdGlvbiIpOworICAgICAgICBNZXRob2QgZ2V0SW1wbCA9CisgICAgICAgICAgICBzdmdEb21JbXBsQ2xhc3MuZ2V0TWV0aG9kKAorICAgICAgICAgICAgImdldERPTUltcGxlbWVudGF0aW9uIiwKKyAgICAgICAgICAgIG5ldyBDbGFzc1swXSk7CisgICAgICAgIGRvbUltcGwgPQorICAgICAgICAgICAgKERPTUltcGxlbWVudGF0aW9uKSBnZXRJbXBsLmludm9rZShudWxsLCBuZXcgT2JqZWN0WzBdKTsKKyAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGRvbUltcGw7CisgIH0KKworICAvKioKKyAgICogICBEZXRlcm1pbmVzIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBzdXBwb3J0cyB0aGUgc3BlY2lmaWVkIGZlYXR1cmUuCisgICAqICAgQHBhcmFtIGZlYXR1cmUgRmVhdHVyZQorICAgKiAgIEBwYXJhbSB2ZXJzaW9uIFZlcnNpb24KKyAgICogICBAcmV0dXJuIHRydWUgaWYgaW1wbGVtZW50YXRpb24gc3VwcG9ydHMgdGhlIGZlYXR1cmUKKyAgICovCisgIHB1YmxpYyBib29sZWFuIGhhc0ZlYXR1cmUoU3RyaW5nIGZlYXR1cmUsIFN0cmluZyB2ZXJzaW9uKSB7CisgICAgcmV0dXJuIGdldERPTUltcGxlbWVudGF0aW9uKCkuaGFzRmVhdHVyZShmZWF0dXJlLCB2ZXJzaW9uKTsKKyAgfQorCisgIC8qKgorICAgKiAgIEFkZHMgYW55IHNwZWNpYWxpemVkIGV4dGVuc2lvbiByZXF1aXJlZCBieSB0aGUgaW1wbGVtZW50YXRpb24uCisgICAqICAgQHBhcmFtIHRlc3RGaWxlTmFtZSBmaWxlIG5hbWUgZnJvbSB0ZXN0CisgICAqICAgQHJldHVybiBwb3NzaWJseSBtb2RpZmllZCBmaWxlIG5hbWUKKyAgICovCisgIHB1YmxpYyBTdHJpbmcgYWRkRXh0ZW5zaW9uKFN0cmluZyB0ZXN0RmlsZU5hbWUpIHsKKyAgICByZXR1cm4gdGVzdEZpbGVOYW1lICsgIi5zdmciOworICB9CisKKyAgLyoqCisgICAqICAgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGltcGxlbWVudGF0aW9uIGNvbWJpbmVzIHRleHQgYW5kIGNkYXRhIG5vZGVzLgorICAgKiAgIEByZXR1cm4gdHJ1ZSBpZiBjb2FsZXNjaW5nCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc0NvYWxlc2NpbmcoKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLyoqCisgICAqICAgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGltcGxlbWVudGF0aW9uIGV4cGFuZHMgZW50aXR5IHJlZmVyZW5jZXMuCisgICAqICAgQHJldHVybiB0cnVlIGlmIGV4cGFuZGluZyBlbnRpdHkgcmVmZXJlbmNlcworICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8qKgorICAgKiAgIEluZGljYXRlcyB3aGV0aGVyIHRoZSBpbXBsZW1lbnRhdGlvbiBpZ25vcmVzCisgICAqICAgICAgIGVsZW1lbnQgY29udGVudCB3aGl0ZXNwYWNlLgorICAgKiAgIEByZXR1cm4gdHJ1ZSBpZiBpZ25vcmluZyBlbGVtZW50IGNvbnRlbnQgd2hpdGVzcGFjZQorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNJZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSgpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvKioKKyAgICogICBJbmRpY2F0ZXMgd2hldGhlciB0aGUgaW1wbGVtZW50YXRpb24gaXMgbmFtZXNwYWNlIGF3YXJlLgorICAgKiAgIEByZXR1cm4gdHJ1ZSBpZiBuYW1lc3BhY2UgYXdhcmUKKyAgICovCisgIHB1YmxpYyBib29sZWFuIGlzTmFtZXNwYWNlQXdhcmUoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvKioKKyAgICogICBJbmRpY2F0ZXMgd2hldGhlciB0aGUgaW1wbGVtZW50YXRpb24gaXMgdmFsaWRhdGluZy4KKyAgICogICBAcmV0dXJuIHRydWUgaWYgdmFsaWRhdGluZworICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNWYWxpZGF0aW5nKCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIGNvbnRlbnQgdHlwZS4KKyAgICogQHJldHVybiBjb250ZW50IHR5cGUsICJpbWFnZS9zdmcreG1sIgorICAgKi8KKyAgcHVibGljIFN0cmluZyBnZXRDb250ZW50VHlwZSgpIHsKKyAgICByZXR1cm4gImltYWdlL3N2Zyt4bWwiOworICB9CisKK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvRE9NNEpUZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9ET000SlRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGQ2YWNkZAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvRE9NNEpUZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMTU0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworLyoKKyAgJExvZzogRE9NNEpUZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5qYXZhLHYgJAorICBSZXZpc2lvbiAxLjIgIDIwMDQvMDMvMTEgMDE6NDQ6MjEgIGRvbS10cy00CisgIENoZWNrc3R5bGUgZml4ZXMgKGJ1ZyA1OTIpCisKKyAgUmV2aXNpb24gMS4xICAyMDAyLzAyLzAzIDA3OjQ3OjUxICBkb20tdHMtNAorICBNb3JlIG1pc3NpbmcgZmlsZXMKKworICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210czsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworCitpbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOworCisvKioKKyAqICAgVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBnZW5lcmljIHBhcnNlciBhbmQgY29uZmlndWF0aW9uCisgKiAgIGFic3RyYWN0IGNsYXNzIGZvciBKQVhQIHN1cHBvcnRpbmcgcGFyc2Vycy4KKyAqLworcHVibGljIGNsYXNzIERPTTRKVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICBleHRlbmRzIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHsKKworICBwcml2YXRlIGZpbmFsIE9iamVjdCBkb21GYWN0b3J5OworICBwcml2YXRlIGZpbmFsIE9iamVjdCBzYXhSZWFkZXI7CisgIHByaXZhdGUgZmluYWwgb3JnLnhtbC5zYXguWE1MUmVhZGVyIHhtbFJlYWRlcjsKKyAgcHJpdmF0ZSBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICBwcml2YXRlIGZpbmFsIE1ldGhvZCByZWFkTWV0aG9kOworCisgIC8qKgorICAgKiBDcmVhdGVzIGEgSkFYUCBpbXBsZW1lbnRhdGlvbiBvZiBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS4KKyAgICogQHBhcmFtIGZhY3RvcnkgbnVsbCBmb3IgZGVmYXVsdCBKQVhQIHByb3ZpZGVyLiAgSWYgbm90IG51bGwsCisgICAqIGZhY3Rvcnkgd2lsbCBiZSBtdXRhdGVkIGluIGNvbnN0cnVjdG9yIGFuZCBzaG91bGQgYmUgcmVsZWFzZWQKKyAgICogYnkgY2FsbGluZyBjb2RlIHVwb24gcmV0dXJuLgorICAgKiBAcGFyYW0gWE1MUmVhZGVyIGlmIG51bGwgdXNlIGRlZmF1bHQgWE1MUmVhZGVyLiAgSWYgcHJvdmlkZWQsCisgICAqIGl0IG1heSBiZSBtdXRhdGVkIGFuZCBzaG91bGQgYmUgcmVsZWFzZWQgYnkgdGhlIGNhbGxlciBpbW1lZGlhdGVseQorICAgKiBhZnRlciB0aGUgY29uc3RydWN0b3IuCisgICAqIEBwYXJhbSBzZXR0aW5ncyBhcnJheSBvZiBzZXR0aW5ncywgbWF5IGJlIG51bGwuCisgICAqLworICBwdWJsaWMgRE9NNEpUZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeShEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MpIHRocm93cworICAgICAgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgc3VwZXIoc2V0dGluZ3MpOworICAgIHRyeSB7CisgICAgICAvLworICAgICAgLy8gICBUaGUgZm9sbG93aW5nIHJlZmxlY3Rpb24gY29kZSBpcyB0cnlpbmcgdG8gYWNjb21wbGlzaAorICAgICAgLy8KKyAgICAgIC8vZG9tRmFjdG9yeSA9IG9yZy5kb200ai5kb20uRE9NRG9jdW1lbnRGYWN0b3J5LmdldEluc3RhbmNlKCk7CisgICAgICAvL2RvbUltcGwgPSAoRE9NSW1wbGVtZW50YXRpb24pIGRvbUZhY3Rvcnk7CisgICAgICAvL3NheFJlYWRlciA9IG5ldyBvcmcuZG9tNGouaW8uU0FYUmVhZGVyKGRvbUZhY3RvcnkpOworICAgICAgLy94bWxSZWFkZXIgPSBzYXhSZWFkZXIuZ2V0WE1MUmVhZGVyKCk7CisKKyAgICAgIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKTsKKyAgICAgIENsYXNzIGRvbUZhY3RvcnlDbGFzcyA9IGNsYXNzTG9hZGVyLmxvYWRDbGFzcygKKyAgICAgICAgICAib3JnLmRvbTRqLmRvbS5ET01Eb2N1bWVudEZhY3RvcnkiKTsKKyAgICAgIE1ldGhvZCBnZXRJbnN0YW5jZSA9IGRvbUZhY3RvcnlDbGFzcy5nZXRNZXRob2QoImdldEluc3RhbmNlIiwgbmV3IENsYXNzW10ge30pOworICAgICAgZG9tRmFjdG9yeSA9IGdldEluc3RhbmNlLmludm9rZShudWxsLCBuZXcgT2JqZWN0W10ge30pOworICAgICAgZG9tSW1wbCA9IChET01JbXBsZW1lbnRhdGlvbikgZG9tRmFjdG9yeTsKKyAgICAgIENsYXNzIHNheFJlYWRlckNsYXNzID0gY2xhc3NMb2FkZXIubG9hZENsYXNzKCJvcmcuZG9tNGouaW8uU0FYUmVhZGVyIik7CisgICAgICBDb25zdHJ1Y3RvciBzYXhSZWFkZXJDb25zdHJ1Y3RvciA9IHNheFJlYWRlckNsYXNzLmdldENvbnN0cnVjdG9yKAorICAgICAgICAgIG5ldyBDbGFzc1tdIHtjbGFzc0xvYWRlci5sb2FkQ2xhc3MoIm9yZy5kb200ai5Eb2N1bWVudEZhY3RvcnkiKX0pOworICAgICAgc2F4UmVhZGVyID0gc2F4UmVhZGVyQ29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHtkb21GYWN0b3J5fSk7CisKKyAgICAgIE1ldGhvZCBnZXRSZWFkZXJNZXRob2QgPSBzYXhSZWFkZXJDbGFzcy5nZXRNZXRob2QoImdldFhNTFJlYWRlciIsCisgICAgICAgICAgbmV3IENsYXNzW10ge30pOworICAgICAgeG1sUmVhZGVyID0gKFhNTFJlYWRlcikgZ2V0UmVhZGVyTWV0aG9kLmludm9rZShzYXhSZWFkZXIsIG5ldyBPYmplY3RbMF0pOworCisgICAgICByZWFkTWV0aG9kID0gc2F4UmVhZGVyQ2xhc3MuZ2V0TWV0aG9kKCJyZWFkIiwgbmV3IENsYXNzW10ge2phdmEubmV0LlVSTC5jbGFzc30pOworICAgIH0KKyAgICBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBleCkgeworICAgICAgdGhyb3cgbmV3IERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24oZXguZ2V0VGFyZ2V0RXhjZXB0aW9uKCksIG51bGwpOworICAgIH0KKyAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICB0aHJvdyBuZXcgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbihleCwgbnVsbCk7CisgICAgfQorICAgIC8vCisgICAgLy8gICBUT0RPOiBQcm9jZXNzIHNldHRpbmdzCisgICAgLy8KKyAgfQorCisgIHB1YmxpYyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBuZXdJbnN0YW5jZShEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10KKyAgICAgIG5ld1NldHRpbmdzKSB0aHJvd3MgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgaWYgKG5ld1NldHRpbmdzID09IG51bGwpIHsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKyAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gbWVyZ2VkU2V0dGluZ3MgPSBtZXJnZVNldHRpbmdzKG5ld1NldHRpbmdzKTsKKyAgICByZXR1cm4gbmV3IERPTTRKVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkobWVyZ2VkU2V0dGluZ3MpOworICB9CisKKyAgcHVibGljIERvY3VtZW50IGxvYWQoamF2YS5uZXQuVVJMIHVybCkgdGhyb3dzIERPTVRlc3RMb2FkRXhjZXB0aW9uIHsKKyAgICBpZiAodXJsID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidXJsIik7CisgICAgfQorICAgIGlmIChzYXhSZWFkZXIgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJzYXhSZWFkZXIiKTsKKyAgICB9CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiAob3JnLnczYy5kb20uRG9jdW1lbnQpIHJlYWRNZXRob2QuaW52b2tlKHNheFJlYWRlciwKKyAgICAgICAgICBuZXcgT2JqZWN0W10ge3VybH0pOworICAgIH0KKyAgICBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBleCkgeworICAgICAgZXguZ2V0VGFyZ2V0RXhjZXB0aW9uKCkucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICB0aHJvdyBuZXcgRE9NVGVzdExvYWRFeGNlcHRpb24oZXguZ2V0VGFyZ2V0RXhjZXB0aW9uKCkpOworICAgIH0KKyAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgIHRocm93IG5ldyBET01UZXN0TG9hZEV4Y2VwdGlvbihleCk7CisgICAgfQorICB9CisKKyAgcHVibGljIERPTUltcGxlbWVudGF0aW9uIGdldERPTUltcGxlbWVudGF0aW9uKCkgeworICAgIHJldHVybiBkb21JbXBsOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gaGFzRmVhdHVyZShTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pIHsKKyAgICByZXR1cm4gZG9tSW1wbC5oYXNGZWF0dXJlKGZlYXR1cmUsIHZlcnNpb24pOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gaXNDb2FsZXNjaW5nKCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGlzRXhwYW5kRW50aXR5UmVmZXJlbmNlcygpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBpc0lnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGlzTmFtZXNwYWNlQXdhcmUoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBpc1ZhbGlkYXRpbmcoKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvRE9NRXJyb3JJbXBsLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0RPTUVycm9ySW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjYzIxMTUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0RPTUVycm9ySW1wbC5qYXZhCkBAIC0wLDAgKzEsNjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzOworCitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXJyb3I7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NTG9jYXRvcjsKKworLyoqCisgKiAgIFRoaXMgaXMgYSB1dGlsaXR5IGltcGxlbWVudGF0aW9uIG9mIEV2ZW50TGlzdGVuZXIKKyAqICAgICAgdGhhdCBjYXB0dXJlcyBhbGwgZXZlbnRzIGFuZCBwcm92aWRlcyBhY2Nlc3MKKyAqICAgICAgdG8gbGlzdHMgb2YgYWxsIGV2ZW50cyBieSBtb2RlCisgKi8KK3B1YmxpYyBjbGFzcyBET01FcnJvckltcGwKKyAgICBpbXBsZW1lbnRzIERPTUVycm9yIHsKKyAgcHJpdmF0ZSBmaW5hbCBzaG9ydCBzZXZlcml0eTsKKyAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbWVzc2FnZTsKKyAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgdHlwZTsKKyAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgcmVsYXRlZEV4Y2VwdGlvbjsKKyAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgcmVsYXRlZERhdGE7CisgIHByaXZhdGUgZmluYWwgRE9NTG9jYXRvciBsb2NhdGlvbjsKKworICAvKioKKyAgICogUHVibGljIGNvbnN0cnVjdG9yCisgICAqCisgICAqLworICBwdWJsaWMgRE9NRXJyb3JJbXBsKERPTUVycm9yIHNyYykgeworICAgIHRoaXMuc2V2ZXJpdHkgPSBzcmMuZ2V0U2V2ZXJpdHkoKTsKKyAgICB0aGlzLm1lc3NhZ2UgPSBzcmMuZ2V0TWVzc2FnZSgpOworICAgIHRoaXMudHlwZSA9IHNyYy5nZXRUeXBlKCk7CisgICAgdGhpcy5yZWxhdGVkRXhjZXB0aW9uID0gc3JjLmdldFJlbGF0ZWRFeGNlcHRpb24oKTsKKyAgICB0aGlzLnJlbGF0ZWREYXRhID0gc3JjLmdldFJlbGF0ZWREYXRhKCk7CisgICAgdGhpcy5sb2NhdGlvbiA9IG5ldyBET01Mb2NhdG9ySW1wbChzcmMuZ2V0TG9jYXRpb24oKSk7CisgIH0KKworICBwdWJsaWMgZmluYWwgc2hvcnQgZ2V0U2V2ZXJpdHkoKSB7CisgICAgcmV0dXJuIHNldmVyaXR5OworICB9CisKKyAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRNZXNzYWdlKCkgeworICAgIHJldHVybiBtZXNzYWdlOworICB9CisKKyAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRUeXBlKCkgeworICAgIHJldHVybiB0eXBlOworICB9CisKKyAgcHVibGljIGZpbmFsIE9iamVjdCBnZXRSZWxhdGVkRXhjZXB0aW9uKCkgeworICAgIHJldHVybiByZWxhdGVkRXhjZXB0aW9uOworICB9CisKKyAgcHVibGljIGZpbmFsIE9iamVjdCBnZXRSZWxhdGVkRGF0YSgpIHsKKyAgICByZXR1cm4gcmVsYXRlZERhdGE7CisgIH0KKworICBwdWJsaWMgZmluYWwgRE9NTG9jYXRvciBnZXRMb2NhdGlvbigpIHsKKyAgICByZXR1cm4gbG9jYXRpb247CisgIH0KK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvRE9NRXJyb3JNb25pdG9yLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0RPTUVycm9yTW9uaXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEzNGRkMDMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0RPTUVycm9yTW9uaXRvci5qYXZhCkBAIC0wLDAgKzEsNjYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01FcnJvcjsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01FcnJvckhhbmRsZXI7CisKKy8qKgorICogICBUaGlzIGlzIGEgdXRpbGl0eSBpbXBsZW1lbnRhdGlvbiBvZiBFdmVudExpc3RlbmVyCisgKiAgICAgIHRoYXQgY2FwdHVyZXMgYWxsIGV2ZW50cyBhbmQgcHJvdmlkZXMgYWNjZXNzCisgKiAgICAgIHRvIGxpc3RzIG9mIGFsbCBldmVudHMgYnkgbW9kZQorICovCitwdWJsaWMgY2xhc3MgRE9NRXJyb3JNb25pdG9yCisgICAgaW1wbGVtZW50cyBET01FcnJvckhhbmRsZXIgeworICBwcml2YXRlIGZpbmFsIExpc3QgZXJyb3JzID0gbmV3IEFycmF5TGlzdCgpOworCisgIC8qKgorICAgKiBQdWJsaWMgY29uc3RydWN0b3IKKyAgICoKKyAgICovCisgIHB1YmxpYyBET01FcnJvck1vbml0b3IoKSB7CisgIH0KKworICAvKioKKyAgICogSW1wbGVtZW50YXRpb24gb2YgRE9NRXJyb3JIYW5kbGVyLmhhbmRsZUVycm9yIHRoYXQKKyAgICogYWRkcyBjb3B5IG9mIGVycm9yIHRvIGxpc3QgZm9yIGxhdGVyIHJldHJpZXZhbC4KKyAgICoKKyAgICovCisgIHB1YmxpYyBib29sZWFuIGhhbmRsZUVycm9yKERPTUVycm9yIGVycm9yKSB7CisgICAgZXJyb3JzLmFkZChuZXcgRE9NRXJyb3JJbXBsKGVycm9yKSk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvKioKKyAgICogR2V0cyBsaXN0IG9mIGVycm9ycworICAgKgorICAgKiBAcmV0dXJuIHJldHVybiBlcnJvcnMKKyAgICovCisgIHB1YmxpYyBMaXN0IGdldEFsbEVycm9ycygpIHsKKyAgICByZXR1cm4gbmV3IEFycmF5TGlzdChlcnJvcnMpOworICB9CisKKyAgcHVibGljIHZvaWQgYXNzZXJ0TG93ZXJTZXZlcml0eShET01UZXN0Q2FzZSB0ZXN0Q2FzZSwgU3RyaW5nIGlkLCBpbnQgc2V2ZXJpdHkpIHsKKyAgICBJdGVyYXRvciBpdGVyID0gZXJyb3JzLml0ZXJhdG9yKCk7CisgICAgd2hpbGUgKGl0ZXIuaGFzTmV4dCgpKSB7CisgICAgICBET01FcnJvciBlcnJvciA9IChET01FcnJvcikgaXRlci5uZXh0KCk7CisgICAgICBpZiAoZXJyb3IuZ2V0U2V2ZXJpdHkoKSA+PSBzZXZlcml0eSkgeworICAgICAgICB0ZXN0Q2FzZS5mYWlsKGlkICsgZXJyb3IuZ2V0TWVzc2FnZSgpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvRE9NTG9jYXRvckltcGwuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvRE9NTG9jYXRvckltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OWEwYzU4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9ET01Mb2NhdG9ySW1wbC5qYXZhCkBAIC0wLDAgKzEsODQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KK3BhY2thZ2Ugb3JnLnczYy5kb210czsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUxvY2F0b3I7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKKworLyoqCisgKiBJbXBsZW1lbnRhdGlvbiBvZiBET01Mb2NhdG9yCisgKgorICovCitwdWJsaWMgY2xhc3MgRE9NTG9jYXRvckltcGwKKyAgICBpbXBsZW1lbnRzIERPTUxvY2F0b3IgeworICBwcml2YXRlIGZpbmFsIGludCBsaW5lTnVtYmVyOworICBwcml2YXRlIGZpbmFsIGludCBjb2x1bW5OdW1iZXI7CisgIHByaXZhdGUgZmluYWwgaW50IGJ5dGVPZmZzZXQ7CisgIHByaXZhdGUgZmluYWwgaW50IHV0ZjE2T2Zmc2V0OworICBwcml2YXRlIGZpbmFsIE5vZGUgcmVsYXRlZE5vZGU7CisgIHByaXZhdGUgZmluYWwgU3RyaW5nIHVyaTsKKworICBwdWJsaWMgRE9NTG9jYXRvckltcGwoRE9NTG9jYXRvciBzcmMpIHsKKyAgICB0aGlzLmxpbmVOdW1iZXIgPSBzcmMuZ2V0TGluZU51bWJlcigpOworICAgIHRoaXMuY29sdW1uTnVtYmVyID0gc3JjLmdldENvbHVtbk51bWJlcigpOworICAgIHRoaXMuYnl0ZU9mZnNldCA9IHNyYy5nZXRCeXRlT2Zmc2V0KCk7CisgICAgdGhpcy51dGYxNk9mZnNldCA9IHNyYy5nZXRVdGYxNk9mZnNldCgpOworICAgIHRoaXMucmVsYXRlZE5vZGUgPSBzcmMuZ2V0UmVsYXRlZE5vZGUoKTsKKyAgICB0aGlzLnVyaSA9IHNyYy5nZXRVcmkoKTsKKyAgfQorCisgIC8qCisgICAqIExpbmUgbnVtYmVyCisgICAqIEBzZWUgb3JnLnczYy5kb20uRE9NTG9jYXRvciNnZXRMaW5lTnVtYmVyKCkKKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpIHsKKyAgICByZXR1cm4gbGluZU51bWJlcjsKKyAgfQorCisgIC8qCisgICAqIENvbHVtbiBudW1iZXIKKyAgICogQHNlZSBvcmcudzNjLmRvbS5ET01Mb2NhdG9yI2dldENvbHVtbk51bWJlcigpCisgICAqLworICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpIHsKKyAgICByZXR1cm4gY29sdW1uTnVtYmVyOworICB9CisKKyAgLyoKKyAgICogQnl0ZSBvZmZzZXQKKyAgICogQHNlZSBvcmcudzNjLmRvbS5ET01Mb2NhdG9yI2dldEJ5dGVPZmZzZXQoKQorICAgKi8KKyAgcHVibGljIGludCBnZXRCeXRlT2Zmc2V0KCkgeworICAgIHJldHVybiBieXRlT2Zmc2V0OworICB9CisKKyAgLyogVVRGLTE2IG9mZnNldAorICAgKiBAc2VlIG9yZy53M2MuZG9tLkRPTUxvY2F0b3IjZ2V0VXRmMTZPZmZzZXQoKQorICAgKi8KKyAgcHVibGljIGludCBnZXRVdGYxNk9mZnNldCgpIHsKKyAgICByZXR1cm4gdXRmMTZPZmZzZXQ7CisgIH0KKworICAvKiBSZWxhdGVkIG5vZGUKKyAgICogQHNlZSBvcmcudzNjLmRvbS5ET01Mb2NhdG9yI2dldFJlbGF0ZWROb2RlKCkKKyAgICovCisgIHB1YmxpYyBOb2RlIGdldFJlbGF0ZWROb2RlKCkgeworICAgIHJldHVybiByZWxhdGVkTm9kZTsKKyAgfQorCisgIC8qIFVSSQorICAgKiBAc2VlIG9yZy53M2MuZG9tLkRPTUxvY2F0b3IjZ2V0VXJpKCkKKyAgICovCisgIHB1YmxpYyBTdHJpbmcgZ2V0VXJpKCkgeworICAgIHJldHVybiB1cmk7CisgIH0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9ET01UZXN0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0RPTVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZGQ4ZjI2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9ET01UZXN0LmphdmEKQEAgLTAsMCArMSwyODkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUKKyAqIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4KKyAqIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZSBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcworICogcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKKyAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKKyAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlCisgKiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTDsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworCisvKioKKyAqIFRoaXMgaXMgYW4gYWJzdHJhY3QgYmFzZSBjbGFzcyBmb3IgZ2VuZXJhdGVkIERPTSB0ZXN0cworICoKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIERPTVRlc3QgLyogd0JNOiBpbXBsZW1lbnRzIEV2ZW50TGlzdGVuZXIgKi8geworICBwcml2YXRlIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisgIHByaXZhdGUgaW50IG11dGF0aW9uQ291bnQgPSAwOworCisgIC8qKgorICAgKiBUaGlzIGlzIHRoZSBhcHByb3ByaWF0ZSBjb25zdHJ1Y3RvciBmb3IgdGVzdHMgdGhhdCBtYWtlIG5vIHJlcXVpcmVtZW50cworICAgKiBvbiB0aGUgcGFyc2VyIGNvbmZpZ3VyYXRpb24uCisgICAqCisgICAqIEBwYXJhbSBmYWN0b3J5CisgICAqICAgICAgICAgICAgbXVzdCBub3QgYmUgbnVsbAorICAgKi8KKyAgcHVibGljIERPTVRlc3QoRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgeworICAgIGlmIChmYWN0b3J5ID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiZmFjdG9yeSIpOworICAgIH0KKyAgICB0aGlzLmZhY3RvcnkgPSBmYWN0b3J5OworICB9CisKKyAgLyoqCisgICAqIFRoaXMgY29uc3RydWN0b3IgaXMgdXNlZCBieSB0ZXN0cyB0aGF0IG11c3QgY3JlYXRlIGEgbW9kaWZpZWQgZG9jdW1lbnQKKyAgICogZmFjdG9yeSB0byBtZWV0IHJlcXVpcmVtZW50cyBvbiB0aGUgcGFyc2VyIGNvbmZpZ3VyYXRpb24uIHNldEZhY3RvcnkKKyAgICogc2hvdWxkIGJlIGNhbGxlZCB3aXRoaW4gdGhlIHRlc3QncyBjb25zdHJ1Y3Rvci4KKyAgICovCisgIHB1YmxpYyBET01UZXN0KCkgeworICAgIGZhY3RvcnkgPSBudWxsOworICB9CisKKyAgLyoqCisgICAqIFNob3VsZCBvbmx5IGJlIGNhbGxlZCBpbiB0aGUgY29uc3RydWN0b3Igb2YgYSBkZXJpdmVkIHR5cGUuCisgICAqLworICBwcm90ZWN0ZWQgdm9pZCBzZXRGYWN0b3J5KERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpIHsKKyAgICB0aGlzLmZhY3RvcnkgPSBmYWN0b3J5OworICB9CisKKyAgcHVibGljIGJvb2xlYW4gaGFzRmVhdHVyZShTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pIHsKKyAgICByZXR1cm4gZmFjdG9yeS5oYXNGZWF0dXJlKGZlYXR1cmUsIHZlcnNpb24pOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gaGFzU2V0dGluZyhEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIHNldHRpbmcpIHsKKyAgICByZXR1cm4gc2V0dGluZy5oYXNTZXR0aW5nKGZhY3RvcnkpOworICB9CisKKyAgcHJvdGVjdGVkIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGdldEZhY3RvcnkoKSB7CisgICAgcmV0dXJuIGZhY3Rvcnk7CisgIH0KKworICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb24gZ2V0SW1wbGVtZW50YXRpb24oKSB7CisgICAgcmV0dXJuIGZhY3RvcnkuZ2V0RE9NSW1wbGVtZW50YXRpb24oKTsKKyAgfQorCisgIHByaXZhdGUgVVJMIHJlc29sdmVVUkkoU3RyaW5nIGJhc2VVUkkpIHRocm93cyBET01UZXN0TG9hZEV4Y2VwdGlvbiB7CisgICAgU3RyaW5nIGRvY1VSSSA9IGZhY3RvcnkuYWRkRXh0ZW5zaW9uKGJhc2VVUkkpOworCisgICAgVVJMIHJlc29sdmVkVVJJID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgcmVzb2x2ZWRVUkkgPSBuZXcgVVJMKGRvY1VSSSk7CisgICAgICBpZiAocmVzb2x2ZWRVUkkuZ2V0UHJvdG9jb2woKSAhPSBudWxsKSB7CisgICAgICAgIHJldHVybiByZXNvbHZlZFVSSTsKKyAgICAgIH0KKyAgICB9CisgICAgY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBleCkgeworICAgICAgLy8gICAgICAgIHRocm93IG5ldyBET01UZXN0TG9hZEV4Y2VwdGlvbihleCk7CisgICAgfQorICAgIC8vCisgICAgLy8gICBidWlsZCBhIFVSTCBmb3IgYSB0ZXN0IGZpbGUgaW4gdGhlIEpBUgorICAgIC8vCisgICAgcmVzb2x2ZWRVUkkgPSBnZXRDbGFzcygpLmdldFJlc291cmNlKCIvIiArIGRvY1VSSSk7CisgICAgaWYgKHJlc29sdmVkVVJJID09IG51bGwpIHsKKyAgICAgIC8vCisgICAgICAvLyAgIHNlZSBpZiBpdCBpcyBhbiBhYnNvbHV0ZSBVUkkKKyAgICAgIC8vCisgICAgICBpbnQgZmlyc3RTbGFzaCA9IGRvY1VSSS5pbmRleE9mKCcvJyk7CisgICAgICB0cnkgeworICAgICAgICBpZiAoZmlyc3RTbGFzaCA9PSAwCisgICAgICAgICAgICB8fCAoZmlyc3RTbGFzaCA+PSAxCisgICAgICAgICAgICAgICAgJiYgZG9jVVJJLmNoYXJBdChmaXJzdFNsYXNoIC0gMSkgPT0gJzonKSkgeworICAgICAgICAgIHJlc29sdmVkVVJJID0gbmV3IFVSTChkb2NVUkkpOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgIC8vCisgICAgICAgICAgLy8gIHRyeSB0aGUgZmlsZXMvbGV2ZWw/L3NwZWMgZGlyZWN0b3J5CisgICAgICAgICAgLy8KKyAgICAgICAgICBTdHJpbmcgZmlsZW5hbWUgPSBnZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXROYW1lKCk7CisgICAgICAgICAgZmlsZW5hbWUgPQorICAgICAgICAgICAgICAidGVzdHMvIgorICAgICAgICAgICAgICArIGZpbGVuYW1lLnN1YnN0cmluZygxNCkucmVwbGFjZSgnLicsICcvJykKKyAgICAgICAgICAgICAgKyAiL2ZpbGVzLyIKKyAgICAgICAgICAgICAgKyBkb2NVUkk7CisgICAgICAgICAgcmVzb2x2ZWRVUkkgPSBuZXcgamF2YS5pby5GaWxlKGZpbGVuYW1lKS50b1VSTCgpOworICAgICAgICB9CisgICAgICB9CisgICAgICBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGV4KSB7CisgICAgICAgIHRocm93IG5ldyBET01UZXN0TG9hZEV4Y2VwdGlvbihleCk7CisgICAgICB9CisgICAgfQorCisgICAgaWYgKHJlc29sdmVkVVJJID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBET01UZXN0TG9hZEV4Y2VwdGlvbigKKyAgICAgICAgICBuZXcgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb24oZG9jVVJJKSk7CisgICAgfQorICAgIHJldHVybiByZXNvbHZlZFVSSTsKKyAgfQorCisgIHB1YmxpYyBTdHJpbmcgZ2V0UmVzb3VyY2VVUkkoU3RyaW5nIGhyZWYsIFN0cmluZyBzY2hlbWUsIFN0cmluZyBjb250ZW50VHlwZSkgdGhyb3dzCisgICAgICBET01UZXN0TG9hZEV4Y2VwdGlvbiB7CisgICAgaWYgKHNjaGVtZSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInNjaGVtZSIpOworICAgIH0KKyAgICBpZiAoImZpbGUiLmVxdWFscyhzY2hlbWUpKSB7CisgICAgICByZXR1cm4gcmVzb2x2ZVVSSShocmVmKS50b1N0cmluZygpOworICAgIH0KKyAgICBpZiAoImh0dHAiLmVxdWFscyhzY2hlbWUpKSB7CisgICAgICBTdHJpbmdCdWZmZXIgaHR0cFVSTCA9IG5ldyBTdHJpbmdCdWZmZXIoCisgICAgICAgICAgU3lzdGVtLmdldFByb3BlcnR5KCJvcmcudzNjLmRvbXRzLmh0dHBiYXNlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC93ZWJkYXYvIikpOworICAgICAgaHR0cFVSTC5hcHBlbmQoaHJlZik7CisgICAgICBpZiAoImFwcGxpY2F0aW9uL3BkZiIuZXF1YWxzKGNvbnRlbnRUeXBlKSkgeworICAgICAgICBodHRwVVJMLmFwcGVuZCgiLnBkZiIpOworICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIGh0dHBVUkwuYXBwZW5kKCIueG1sIik7CisgICAgICB9CisgICAgICByZXR1cm4gaHR0cFVSTC50b1N0cmluZygpOworICAgIH0KKyAgICB0aHJvdyBuZXcgRE9NVGVzdExvYWRFeGNlcHRpb24obmV3IEV4Y2VwdGlvbigiVW5yZWNvZ25pemVkIFVSSSBzY2hlbWUgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NoZW1lKSk7CisgIH0KKworICBwdWJsaWMgU3RyaW5nIGNyZWF0ZVRlbXBVUkkoU3RyaW5nIHNjaGVtZSkgdGhyb3dzIERPTVRlc3RMb2FkRXhjZXB0aW9uIHsKKyAgICBpZiAoc2NoZW1lID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigic2NoZW1lIik7CisgICAgfQorICAgIGlmICgiZmlsZSIuZXF1YWxzKHNjaGVtZSkpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIEZpbGUgdGVtcEZpbGUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJkb210cyIsICIueG1sIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgLy8KKyAgICAgICAgICAvLyAgIGlmIGF2YWlsYWJsZSB1c2UgSkRLIDEuNCdzIEZpbGUudG9VUkkoKS50b1N0cmluZygpCisgICAgICAgICAgLy8KKyAgICAgICAgICBNZXRob2QgbWV0aG9kID0gRmlsZS5jbGFzcy5nZXRNZXRob2QoInRvVVJJIiwgKENsYXNzPD8+KSBudWxsKTsKKyAgICAgICAgICBPYmplY3QgdXJpID0gbWV0aG9kLmludm9rZSh0ZW1wRmlsZSwgKENsYXNzPD8+KSBudWxsKTsKKyAgICAgICAgICByZXR1cm4gdXJpLnRvU3RyaW5nKCk7CisgICAgICAgIH0KKyAgICAgICAgY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgIC8vCisgICAgICAgICAgLy8gICBGaWxlLnRvVVJMIGlzIG5vdCBhcyByb2J1c3QKKyAgICAgICAgICAvLworICAgICAgICAgIFVSTCB1cmwgPSB0ZW1wRmlsZS50b1VSTCgpOworICAgICAgICAgIHJldHVybiB1cmwudG9TdHJpbmcoKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICB0aHJvdyBuZXcgRE9NVGVzdExvYWRFeGNlcHRpb24oZXgpOworICAgICAgfQorICAgIH0KKyAgICBpZiAoImh0dHAiLmVxdWFscyhzY2hlbWUpKSB7CisgICAgICBTdHJpbmcgaHR0cEJhc2UgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoIm9yZy53M2MuZG9tdHMuaHR0cGJhc2UiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJodHRwOi8vbG9jYWxob3N0OjgwODAvd2ViZGF2LyIpOworICAgICAgamF2YS5sYW5nLlN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKGh0dHBCYXNlKTsKKyAgICAgIGlmICghaHR0cEJhc2UuZW5kc1dpdGgoIi8iKSkgeworICAgICAgICAgIGJ1Zi5hcHBlbmQoIi8iKTsKKyAgICAgIH0KKyAgICAgIGJ1Zi5hcHBlbmQoInRtcCIpOworICAgICAgYnVmLmFwcGVuZCggKG5ldyBqYXZhLnV0aWwuUmFuZG9tKCkpLm5leHRJbnQoSW50ZWdlci5NQVhfVkFMVUUpKTsKKyAgICAgIGJ1Zi5hcHBlbmQoIi54bWwiKTsKKyAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKKyAgICB9CisgICAgdGhyb3cgbmV3IERPTVRlc3RMb2FkRXhjZXB0aW9uKG5ldyBFeGNlcHRpb24oIlVucmVjb2duaXplZCBVUkkgc2NoZW1lICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtZSkpOworICB9CisKKyAgcHVibGljIERvY3VtZW50IGxvYWQoU3RyaW5nIGRvY1VSSSwgYm9vbGVhbiB3aWxsQmVNb2RpZmllZCkgdGhyb3dzCisgICAgICBET01UZXN0TG9hZEV4Y2VwdGlvbiB7CisgICAgRG9jdW1lbnQgZG9jID0gZmFjdG9yeS5sb2FkKHJlc29sdmVVUkkoZG9jVVJJKSk7CisgICAgLy8KKyAgICAvLyAgIGlmIHdpbGwgYmUgbW9kaWZpZWQgaXMgZmFsc2UgYW5kIGRvYyBpcyBhbiBFdmVudFRhcmdldAorICAgIC8vCisgICAgLyoKKyAgICAgKiB3Qk06IGlmICghd2lsbEJlTW9kaWZpZWQgJiYgZG9jIGluc3RhbmNlb2YgRXZlbnRUYXJnZXQpIHsKKyAgICAgKiAoKEV2ZW50VGFyZ2V0KSBkb2MpLmFkZEV2ZW50TGlzdGVuZXIoIkRPTVN1YnRyZWVNb2RpZmllZCIsIHRoaXMsCisgICAgICogZmFsc2UpOyB9CisgICAgICovCisgICAgcmV0dXJuIGRvYzsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHByZWxvYWQoU3RyaW5nIGNvbnRlbnRUeXBlLCBTdHJpbmcgZG9jVVJJLCBib29sZWFuIHdpbGxCZU1vZGlmaWVkKSB0aHJvd3MKKyAgICAgIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgIGlmICgidGV4dC9odG1sIi5lcXVhbHMoY29udGVudFR5cGUpIHx8CisgICAgICAgICJhcHBsaWNhdGlvbi94aHRtbCt4bWwiLmVxdWFscyhjb250ZW50VHlwZSkpIHsKKyAgICAgIGlmIChkb2NVUkkuc3RhcnRzV2l0aCgic3RhZmYiKSB8fCBkb2NVUkkuZXF1YWxzKCJkYXRhdHlwZV9ub3JtYWxpemF0aW9uIikpIHsKKyAgICAgICAgdGhyb3cgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbi5pbmNvbXBhdGlibGVMb2FkKGRvY1VSSSwgY29udGVudFR5cGUpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHB1YmxpYyBPYmplY3QgY3JlYXRlWFBhdGhFdmFsdWF0b3IoRG9jdW1lbnQgZG9jKSB7CisgICAgcmV0dXJuIGZhY3RvcnkuY3JlYXRlWFBhdGhFdmFsdWF0b3IoZG9jKTsKKyAgfQorCisgIHB1YmxpYyBJbnB1dFN0cmVhbSBjcmVhdGVTdHJlYW0oU3RyaW5nIGJ5dGVzKSB0aHJvd3MgRE9NVGVzdExvYWRFeGNlcHRpb24sCisgICAgICBJT0V4Y2VwdGlvbiB7CisgICAgaW50IGJ5dGVDb3VudCA9IGJ5dGVzLmxlbmd0aCgpIC8gMjsKKyAgICBieXRlW10gYXJyYXkgPSBuZXcgYnl0ZVtieXRlQ291bnRdOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYnl0ZUNvdW50OyBpKyspIHsKKyAgICAgIGFycmF5W2ldID0gQnl0ZS5wYXJzZUJ5dGUoYnl0ZXMuc3Vic3RyaW5nKGkgKiAyLCBpICogMiArIDIpLCAxNik7CisgICAgfQorICAgIHJldHVybiBuZXcgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbShhcnJheSk7CisgIH0KKworICBhYnN0cmFjdCBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpOworCisgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzQ29hbGVzY2luZygpIHsKKyAgICByZXR1cm4gZmFjdG9yeS5pc0NvYWxlc2NpbmcoKTsKKyAgfQorCisgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzRXhwYW5kRW50aXR5UmVmZXJlbmNlcygpIHsKKyAgICByZXR1cm4gZmFjdG9yeS5pc0V4cGFuZEVudGl0eVJlZmVyZW5jZXMoKTsKKyAgfQorCisgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoKSB7CisgICAgcmV0dXJuIGZhY3RvcnkuaXNJZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSgpOworICB9CisKKyAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNOYW1lc3BhY2VBd2FyZSgpIHsKKyAgICByZXR1cm4gZmFjdG9yeS5pc05hbWVzcGFjZUF3YXJlKCk7CisgIH0KKworICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc1ZhbGlkYXRpbmcoKSB7CisgICAgcmV0dXJuIGZhY3RvcnkuaXNWYWxpZGF0aW5nKCk7CisgIH0KKworICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc1NpZ25lZCgpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSGFzTnVsbFN0cmluZygpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0Q29udGVudFR5cGUoKSB7CisgICAgcmV0dXJuIGZhY3RvcnkuZ2V0Q29udGVudFR5cGUoKTsKKyAgfQorCisgIC8qKgorICAgKiBJbXBsZW1lbnRhdGlvbiBvZiBFdmVudExpc3RlbmVyLmhhbmRsZUV2ZW50CisgICAqCisgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCB3aGVuIGEgbXV0YXRpb24gaXMgcmVwb3J0ZWQgZm9yIGEgZG9jdW1lbnQgdGhhdAorICAgKiB3YXMgZGVjbGFyZWQgdG8gbm90IGJlIG1vZGlmaWVkIGR1cmluZyB0ZXN0aW5nCisgICAqCisgICAqIEBwYXJhbSBldnQKKyAgICogICAgICAgICAgICBtdXRhdGlvbiBldmVudAorICAgKi8KKyAgLyoKKyAgICogd0JNOiBwdWJsaWMgZmluYWwgdm9pZCBoYW5kbGVFdmVudChFdmVudCBldnQpIHsgbXV0YXRpb25Db3VudCsrOyB9CisgICAqLworCisgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TXV0YXRpb25Db3VudCgpIHsKKyAgICByZXR1cm4gbXV0YXRpb25Db3VudDsKKyAgfQorCit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0RPTVRlc3RDYXNlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0RPTVRlc3RDYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTUwODc3MgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvRE9NVGVzdENhc2UuamF2YQpAQCAtMCwwICsxLDk4MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZQorICogb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgorICogQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcworICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzCisgKiBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQorICogV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUworICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UKKyAqIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CisKKy8qKgorICogVGhpcyBpcyBhbiBhYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBnZW5lcmF0ZWQgRE9NIHRlc3RzCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBET01UZXN0Q2FzZQorICAgIGV4dGVuZHMgRE9NVGVzdCB7CisgIHByaXZhdGUgRE9NVGVzdEZyYW1ld29yayBmcmFtZXdvcms7CisKKyAgLyoqCisgICAqIFRoaXMgY29uc3RydWN0b3IgaXMgZm9yIERPTVRlc3RDYXNlJ3MgdGhhdCBtYWtlIHNwZWNpZmljIGRlbWFuZHMgZm9yCisgICAqIHBhcnNlciBjb25maWd1cmF0aW9uLiBzZXRGYWN0b3J5IHNob3VsZCBiZSBjYWxsZWQgYmVmb3JlIHRoZSBlbmQgb2YgdGhlCisgICAqIHRlc3RzIGNvbnN0cnVjdG9yIHRvIHNldCB0aGUgZmFjdG9yeS4KKyAgICovCisgIHB1YmxpYyBET01UZXN0Q2FzZSgpIHsKKyAgICBmcmFtZXdvcmsgPSBudWxsOworICB9CisKKyAgLyoqCisgICAqIFRoaXMgY29uc3RydWN0b3IgaXMgZm9yIERPTVRlc3RDYXNlJ3MgdGhhdCBkbyBub3QgYWRkIGFueSByZXF1aXJlbWVudHMKKyAgICogZm9yIHBhcnNlciBjb25maWd1cmF0aW9uLgorICAgKgorICAgKiBAcGFyYW0gZmFjdG9yeQorICAgKiAgICAgICAgICAgIGRvY3VtZW50IGZhY3RvcnkgdG8gYmUgdXNlZCBieSB0ZXN0LCBtYXkgbm90IGJlIG51bGwuCisgICAqLworICBwdWJsaWMgRE9NVGVzdENhc2UoRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgeworICAgIHN1cGVyKGZhY3RvcnkpOworICAgIGZyYW1ld29yayA9IG51bGw7CisgIH0KKworICAvKioKKyAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBtYWluKCkgZm9yIGVhY2ggdGVzdCBhbmQgbG9jYXRlcyB0aGUKKyAgICogYXBwcm9wcmlhdGUgdGVzdCBmcmFtZXdvcmsgYW5kIHJ1bnMgdGhlIHNwZWNpZmllZCB0ZXN0CisgICAqCisgICAqIEBwYXJhbSB0ZXN0Q2xhc3MKKyAgICogICAgICAgICAgICB0ZXN0IGNsYXNzCisgICAqIEBwYXJhbSBhcmdzCisgICAqICAgICAgICAgICAgYXJndW1lbnRzIHRvIHRlc3QgY2xhc3MKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBkb01haW4oQ2xhc3MgdGVzdENsYXNzLCBTdHJpbmdbXSBhcmdzKSB7CisgICAgLy8KKyAgICAvLyAgIEF0dGVtcHQgdG8gbG9hZCBKVW5pdFJ1bm5lcgorICAgIC8vCisgICAgQ2xhc3NMb2FkZXIgbG9hZGVyID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKTsKKyAgICB0cnkgeworICAgICAgQ2xhc3MgcnVubmVyQ2xhc3MgPSBsb2FkZXIubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLkpVbml0UnVubmVyIik7CisgICAgICBDb25zdHJ1Y3RvciBydW5uZXJGYWN0b3J5ID0KKyAgICAgICAgICBydW5uZXJDbGFzcy5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbXSB7Q2xhc3MuY2xhc3N9KTsKKyAgICAgIC8vCisgICAgICAvLyAgIGNyZWF0ZSB0aGUgSlVuaXRSdW5uZXIKKyAgICAgIC8vCisgICAgICBPYmplY3QganVuaXRSdW4gPQorICAgICAgICAgIHJ1bm5lckZhY3RvcnkubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHt0ZXN0Q2xhc3N9KTsKKyAgICAgIC8vCisgICAgICAvLyAgIGZpbmQgYW5kIGNhbGwgaXRzIGV4ZWN1dGUgbWV0aG9kIG1ldGhvZAorICAgICAgLy8KKyAgICAgIENsYXNzIGFyZ3NDbGFzcyA9IGxvYWRlci5sb2FkQ2xhc3MoIltMamF2YS5sYW5nLlN0cmluZzsiKTsKKyAgICAgIE1ldGhvZCBleGVjTWV0aG9kID0KKyAgICAgICAgICBydW5uZXJDbGFzcy5nZXRNZXRob2QoImV4ZWN1dGUiLCBuZXcgQ2xhc3NbXSB7YXJnc0NsYXNzfSk7CisgICAgICBleGVjTWV0aG9kLmludm9rZShqdW5pdFJ1biwgbmV3IE9iamVjdFtdIHthcmdzfSk7CisgICAgfQorICAgIGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGV4KSB7CisgICAgICBleC5nZXRUYXJnZXRFeGNlcHRpb24oKS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICB9CisgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgU3lzdGVtLm91dC5wcmludGxuKAorICAgICAgICAgICJqdW5pdC1ydW4uamFyIGFuZCBqdW5pdC5qYXIgXG4gbXVzdCBiZSBpbiBzYW1lIGRpcmVjdG9yeSBvciBvbiBjbGFzc3BhdGguIik7CisgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQm9keSBvZiB0ZXN0CisgICAqCisgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAqLworICBhYnN0cmFjdCBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZTsKKworICAvKioKKyAgICogU2V0cyB0ZXN0IGZyYW1ld29yayB0byBiZSB1c2VkIGJ5IHRlc3QuCisgICAqCisgICAqIEBwYXJhbSBmcmFtZXdvcmsKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldEZyYW1ld29yayhET01UZXN0RnJhbWV3b3JrIGZyYW1ld29yaykgeworICAgIHRoaXMuZnJhbWV3b3JrID0gZnJhbWV3b3JrOworICB9CisKKyAgLyoqCisgICAqIFdhaXQKKyAgICoKKyAgICogQHBhcmFtIG1pbGxpc2Vjb25kCisgICAqICAgICAgICAgICAgbWlsbGlzZWNvbmRzIHRvIHdhaXQKKyAgICovCisgIHB1YmxpYyB2b2lkIHdhaXQoaW50IG1pbGxpc2Vjb25kKSB7CisgICAgZnJhbWV3b3JrLndhaXQobWlsbGlzZWNvbmQpOworICB9CisKKyAgLyoqCisgICAqIEZhaWwgdGVzdAorICAgKgorICAgKiBAcGFyYW0gYXNzZXJ0SUQKKyAgICogICAgICAgICAgICBpZGVudGlmaWVyIG9mIGFzc2VydGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZmFpbChTdHJpbmcgYXNzZXJ0SUQpIHsKKyAgICBmcmFtZXdvcmsuZmFpbCh0aGlzLCBhc3NlcnRJRCk7CisgIH0KKworICAvKioKKyAgICogQXNzZXJ0cyB0aGF0IGFjdHVhbD09dHJ1ZQorICAgKgorICAgKiBAcGFyYW0gYXNzZXJ0SUQKKyAgICogICAgICAgICAgICBpZGVudGlmaWVyIG9mIGFzc2VydGlvbgorICAgKiBAcGFyYW0gYWN0dWFsCisgICAqICAgICAgICAgICAgYWN0dWFsIHZhbHVlCisgICAqLworICBwdWJsaWMgdm9pZCBhc3NlcnRUcnVlKFN0cmluZyBhc3NlcnRJRCwgYm9vbGVhbiBhY3R1YWwpIHsKKyAgICBmcmFtZXdvcmsuYXNzZXJ0VHJ1ZSh0aGlzLCBhc3NlcnRJRCwgYWN0dWFsKTsKKyAgfQorCisgIC8qKgorICAgKiBBc3NlcnRzIHRoYXQgYWN0dWFsPT10cnVlCisgICAqCisgICAqIEBwYXJhbSBhc3NlcnRJRAorICAgKiAgICAgICAgICAgIGlkZW50aWZpZXIgb2YgYXNzZXJ0aW9uCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBhY3R1YWwgdmFsdWUKKyAgICovCisgIHB1YmxpYyB2b2lkIGFzc2VydFRydWUoU3RyaW5nIGFzc2VydElELCBPYmplY3QgYWN0dWFsKSB7CisgICAgZnJhbWV3b3JrLmFzc2VydFRydWUodGhpcywgYXNzZXJ0SUQsICggKEJvb2xlYW4pIGFjdHVhbCkuYm9vbGVhblZhbHVlKCkpOworICB9CisKKyAgLyoqCisgICAqIEFzc2VydHMgdGhhdCBhY3R1YWw9PWZhbHNlCisgICAqCisgICAqIEBwYXJhbSBhc3NlcnRJRAorICAgKiAgICAgICAgICAgIGlkZW50aWZpZXIgb2YgYXNzZXJ0aW9uCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBhY3R1YWwgdmFsdWUKKyAgICovCisgIHB1YmxpYyB2b2lkIGFzc2VydEZhbHNlKFN0cmluZyBhc3NlcnRJRCwgYm9vbGVhbiBhY3R1YWwpIHsKKyAgICBmcmFtZXdvcmsuYXNzZXJ0RmFsc2UodGhpcywgYXNzZXJ0SUQsIGFjdHVhbCk7CisgIH0KKworICAvKioKKyAgICogQXNzZXJ0cyB0aGF0IGFjdHVhbD09ZmFsc2UKKyAgICoKKyAgICogQHBhcmFtIGFzc2VydElECisgICAqICAgICAgICAgICAgaWRlbnRpZmllciBvZiBhc3NlcnRpb24KKyAgICogQHBhcmFtIGFjdHVhbAorICAgKiAgICAgICAgICAgIGFjdHVhbCB2YWx1ZQorICAgKi8KKyAgcHVibGljIHZvaWQgYXNzZXJ0RmFsc2UoU3RyaW5nIGFzc2VydElELCBPYmplY3QgYWN0dWFsKSB7CisgICAgZnJhbWV3b3JrLmFzc2VydEZhbHNlKAorICAgICAgICB0aGlzLAorICAgICAgICBhc3NlcnRJRCwKKyAgICAgICAgKCAoQm9vbGVhbikgYWN0dWFsKS5ib29sZWFuVmFsdWUoKSk7CisgIH0KKworICAvKioKKyAgICogQXNzZXJ0cyB0aGF0IGFjdHVhbCA9PSBudWxsCisgICAqCisgICAqIEBwYXJhbSBhc3NlcnRJRAorICAgKiAgICAgICAgICAgIGlkZW50aWZpZXIgb2YgYXNzZXJ0aW9uCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBhY3R1YWwgdmFsdWUKKyAgICovCisgIHB1YmxpYyB2b2lkIGFzc2VydE51bGwoU3RyaW5nIGFzc2VydElELCBPYmplY3QgYWN0dWFsKSB7CisgICAgZnJhbWV3b3JrLmFzc2VydE51bGwodGhpcywgYXNzZXJ0SUQsIGFjdHVhbCk7CisgIH0KKworICAvKioKKyAgICogQXNzZXJ0cyB0aGF0IGFjdHVhbCAhPSBudWxsCisgICAqCisgICAqIEBwYXJhbSBhc3NlcnRJRAorICAgKiAgICAgICAgICAgIGlkZW50aWZpZXIgb2YgYXNzZXJ0aW9uCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBhY3R1YWwgdmFsdWUKKyAgICovCisgIHB1YmxpYyB2b2lkIGFzc2VydE5vdE51bGwoU3RyaW5nIGFzc2VydElELCBPYmplY3QgYWN0dWFsKSB7CisgICAgZnJhbWV3b3JrLmFzc2VydE5vdE51bGwodGhpcywgYXNzZXJ0SUQsIGFjdHVhbCk7CisgIH0KKworICAvKioKKyAgICogQXNzZXJ0cyB0aGF0IGFjdHVhbCBhbmQgZXhwZWN0ZWQgYXJlIHRoZSBzYW1lIG9iamVjdAorICAgKgorICAgKiBAcGFyYW0gYXNzZXJ0SUQKKyAgICogICAgICAgICAgICBpZGVudGlmaWVyIG9mIGFzc2VydGlvbgorICAgKiBAcGFyYW0gYWN0dWFsCisgICAqICAgICAgICAgICAgYWN0dWFsIHZhbHVlCisgICAqLworICBwdWJsaWMgdm9pZCBhc3NlcnRTYW1lKFN0cmluZyBhc3NlcnRJRCwgT2JqZWN0IGV4cGVjdGVkLCBPYmplY3QgYWN0dWFsKSB7CisgICAgZnJhbWV3b3JrLmFzc2VydFNhbWUodGhpcywgYXNzZXJ0SUQsIGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgLyoqCisgICAqIEFzc2VydHMgdGhhdCBvYmogaXMgYW4gaW5zdGFuY2Ugb2YgY2xzCisgICAqCisgICAqIEBwYXJhbSBhc3NlcnRJRAorICAgKiAgICAgICAgICAgIGlkZW50aWZpZXIgb2YgYXNzZXJ0aW9uCisgICAqIEBwYXJhbSBvYmoKKyAgICogICAgICAgICAgICBvYmplY3QKKyAgICogQHBhcmFtIGNscworICAgKiAgICAgICAgICAgIGNsYXNzLCBtYXkgbm90IGJlIG51bGwuCisgICAqLworICBwdWJsaWMgdm9pZCBhc3NlcnRJbnN0YW5jZU9mKFN0cmluZyBhc3NlcnRJRCwgQ2xhc3MgY2xzLCBPYmplY3Qgb2JqKSB7CisgICAgZnJhbWV3b3JrLmFzc2VydEluc3RhbmNlT2YodGhpcywgYXNzZXJ0SUQsIG9iaiwgY2xzKTsKKyAgfQorCisgIC8qKgorICAgKiBBc3NlcnRzIHRoYXQgdGhlIGxlbmd0aCBvZiB0aGUgY29sbGVjdGlvbiBpcyB0aGUgZXhwZWN0ZWQgc2l6ZS4KKyAgICoKKyAgICogQHBhcmFtIGFzc2VydElECisgICAqICAgICAgICAgICAgaWRlbnRpZmllciBvZiBhc3NlcnRpb24KKyAgICogQHBhcmFtIGV4cGVjdGVkU2l6ZQorICAgKiAgICAgICAgICAgIGV4cGVjdGVkIHNpemUKKyAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICogICAgICAgICAgICBjb2xsZWN0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBhc3NlcnRTaXplKAorICAgICAgU3RyaW5nIGFzc2VydElELAorICAgICAgaW50IGV4cGVjdGVkU2l6ZSwKKyAgICAgIE5vZGVMaXN0IGNvbGxlY3Rpb24pIHsKKyAgICBmcmFtZXdvcmsuYXNzZXJ0U2l6ZSh0aGlzLCBhc3NlcnRJRCwgZXhwZWN0ZWRTaXplLCBjb2xsZWN0aW9uKTsKKyAgfQorCisgIC8qKgorICAgKiBBc3NlcnRzIHRoYXQgdGhlIGxlbmd0aCBvZiB0aGUgY29sbGVjdGlvbiBpcyB0aGUgZXhwZWN0ZWQgc2l6ZS4KKyAgICoKKyAgICogQHBhcmFtIGFzc2VydElECisgICAqICAgICAgICAgICAgaWRlbnRpZmllciBvZiBhc3NlcnRpb24KKyAgICogQHBhcmFtIGV4cGVjdGVkU2l6ZQorICAgKiAgICAgICAgICAgIGV4cGVjdGVkIHNpemUKKyAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICogICAgICAgICAgICBjb2xsZWN0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBhc3NlcnRTaXplKAorICAgICAgU3RyaW5nIGFzc2VydElELAorICAgICAgaW50IGV4cGVjdGVkU2l6ZSwKKyAgICAgIE5hbWVkTm9kZU1hcCBjb2xsZWN0aW9uKSB7CisgICAgZnJhbWV3b3JrLmFzc2VydFNpemUodGhpcywgYXNzZXJ0SUQsIGV4cGVjdGVkU2l6ZSwgY29sbGVjdGlvbik7CisgIH0KKworICAvKioKKyAgICogQXNzZXJ0cyB0aGF0IHRoZSBsZW5ndGggb2YgdGhlIGNvbGxlY3Rpb24gaXMgdGhlIGV4cGVjdGVkIHNpemUuCisgICAqCisgICAqIEBwYXJhbSBhc3NlcnRJRAorICAgKiAgICAgICAgICAgIGlkZW50aWZpZXIgb2YgYXNzZXJ0aW9uCisgICAqIEBwYXJhbSBleHBlY3RlZFNpemUKKyAgICogICAgICAgICAgICBleHBlY3RlZCBzaXplCisgICAqIEBwYXJhbSBjb2xsZWN0aW9uCisgICAqICAgICAgICAgICAgY29sbGVjdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgYXNzZXJ0U2l6ZSgKKyAgICAgIFN0cmluZyBhc3NlcnRJRCwKKyAgICAgIGludCBleHBlY3RlZFNpemUsCisgICAgICBDb2xsZWN0aW9uIGNvbGxlY3Rpb24pIHsKKyAgICBmcmFtZXdvcmsuYXNzZXJ0U2l6ZSh0aGlzLCBhc3NlcnRJRCwgZXhwZWN0ZWRTaXplLCBjb2xsZWN0aW9uKTsKKyAgfQorCisgIC8qKgorICAgKiBBc3NlcnRzIHRoYXQgZXhwZWN0ZWQuZXF1YWxzSWdub3JlQ2FzZShhY3R1YWwpIGlzIHRydWUKKyAgICoKKyAgICogQHBhcmFtIGFzc2VydElECisgICAqICAgICAgICAgICAgaWRlbnRpZmllciBvZiBhc3NlcnRpb24KKyAgICogQHBhcmFtIGFjdHVhbAorICAgKiAgICAgICAgICAgIGFjdHVhbCB2YWx1ZQorICAgKiBAcGFyYW0gZXhwZWN0ZWQKKyAgICogICAgICAgICAgICBFeHBlY3RlZCB2YWx1ZSwgbWF5IG5vdCBiZSBudWxsLgorICAgKi8KKyAgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzSWdub3JlQ2FzZSgKKyAgICAgIFN0cmluZyBhc3NlcnRJRCwKKyAgICAgIFN0cmluZyBleHBlY3RlZCwKKyAgICAgIFN0cmluZyBhY3R1YWwpIHsKKyAgICBmcmFtZXdvcmsuYXNzZXJ0RXF1YWxzSWdub3JlQ2FzZSh0aGlzLCBhc3NlcnRJRCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICAvKioKKyAgICogQXNzZXJ0cyB0aGF0IGVhY2ggZW50cnkgaW4gYWN0dWFsIGlzIG1hdGNoZWQgd2l0aCBhbiBlbnRyeSBpbiBleHBlY3RlZAorICAgKiB0aGF0IG9ubHkgZGlmZmVycyBieSBjYXNlLiBPcmRlciBpcyBub3Qgc2lnbmlmaWNhbnQuCisgICAqCisgICAqIEBwYXJhbSBhc3NlcnRJRAorICAgKiAgICAgICAgICAgIGlkZW50aWZpZXIgb2YgYXNzZXJ0aW9uCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBhY3R1YWwgdmFsdWUKKyAgICogQHBhcmFtIGV4cGVjdGVkCisgICAqICAgICAgICAgICAgRXhwZWN0ZWQgdmFsdWUsIG1heSBub3QgYmUgbnVsbC4KKyAgICovCisgIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFsc0lnbm9yZUNhc2UoCisgICAgICBTdHJpbmcgYXNzZXJ0SUQsCisgICAgICBDb2xsZWN0aW9uIGV4cGVjdGVkLAorICAgICAgQ29sbGVjdGlvbiBhY3R1YWwpIHsKKyAgICBmcmFtZXdvcmsuYXNzZXJ0RXF1YWxzSWdub3JlQ2FzZSh0aGlzLCBhc3NlcnRJRCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICAvKioKKyAgICogQXNzZXJ0cyB0aGF0IGVhY2ggZW50cnkgaW4gYWN0dWFsIGlzIG1hdGNoZWQgd2l0aCBhbiBlbnRyeSBpbiBleHBlY3RlZAorICAgKiB0aGF0IG9ubHkgZGlmZmVycyBieSBjYXNlLiBPcmRlciBpcyBzaWduaWZpY2FudC4KKyAgICoKKyAgICogQHBhcmFtIGFzc2VydElECisgICAqICAgICAgICAgICAgaWRlbnRpZmllciBvZiBhc3NlcnRpb24KKyAgICogQHBhcmFtIGFjdHVhbAorICAgKiAgICAgICAgICAgIGFjdHVhbCB2YWx1ZQorICAgKiBAcGFyYW0gZXhwZWN0ZWQKKyAgICogICAgICAgICAgICBFeHBlY3RlZCB2YWx1ZSwgbWF5IG5vdCBiZSBudWxsLgorICAgKi8KKyAgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzSWdub3JlQ2FzZSgKKyAgICAgIFN0cmluZyBhc3NlcnRJRCwKKyAgICAgIExpc3QgZXhwZWN0ZWQsCisgICAgICBMaXN0IGFjdHVhbCkgeworICAgIGZyYW1ld29yay5hc3NlcnRFcXVhbHNJZ25vcmVDYXNlKHRoaXMsIGFzc2VydElELCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgfQorCisgIC8qKgorICAgKiBBc3NlcnRzIHRoYXQgZXhwZWN0ZWQuZXF1YWxzSWdub3JlQ2FzZShhY3R1YWwpIGlzIHRydWUKKyAgICoKKyAgICogQHBhcmFtIGFzc2VydElECisgICAqICAgICAgICAgICAgaWRlbnRpZmllciBvZiBhc3NlcnRpb24KKyAgICogQHBhcmFtIGFjdHVhbAorICAgKiAgICAgICAgICAgIGFjdHVhbCB2YWx1ZQorICAgKiBAcGFyYW0gZXhwZWN0ZWQKKyAgICogICAgICAgICAgICBFeHBlY3RlZCB2YWx1ZSwgbWF5IG5vdCBiZSBudWxsLgorICAgKi8KKyAgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoCisgICAgICBTdHJpbmcgY29udGV4dCwKKyAgICAgIFN0cmluZyBhc3NlcnRJRCwKKyAgICAgIFN0cmluZyBleHBlY3RlZCwKKyAgICAgIFN0cmluZyBhY3R1YWwpIHsKKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIC8vCisgICAgLy8gICBpZiB0aGUgY29udGVudCB0eXBlIGlzIEhUTUwgKG5vdCBYSFRNTCkKKyAgICAvLworICAgIGlmICgidGV4dC9odG1sIi5lcXVhbHMoY29udGVudFR5cGUpKSB7CisgICAgICAvLworICAgICAgLy8gIGlmIHRoZSBjb250ZXh0IGlzIGF0dHJpYnV0ZSwgdGhlbiB1c2UgY2FzZS1pbnNlbnRpdmUgY29tcGFyaXNvbgorICAgICAgLy8KKyAgICAgIGlmICgiYXR0cmlidXRlIi5lcXVhbHMoY29udGV4dCkpIHsKKyAgICAgICAgZnJhbWV3b3JrLmFzc2VydEVxdWFsc0lnbm9yZUNhc2UodGhpcywgYXNzZXJ0SUQsIGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIC8vCisgICAgICAgIC8vICBvdGhlcndpc2Ugc2hvdWxkIGJlIGNvbXBhcmVkIGFnYWluc3QgdXBwZXJjYXNlZCBleHBlY3RhdGlvbgorICAgICAgICBmcmFtZXdvcmsuYXNzZXJ0RXF1YWxzKHRoaXMsIGFzc2VydElELCBleHBlY3RlZC50b1VwcGVyQ2FzZSgpLCBhY3R1YWwpOworICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgIGZyYW1ld29yay5hc3NlcnRFcXVhbHModGhpcywgYXNzZXJ0SUQsIGV4cGVjdGVkLCBhY3R1YWwpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGVzIGFuIGVxdWl2YWxlbnQgbGlzdCB3aGVyZSBldmVyeSBtZW1iZXIgaGFzCisgICAqICAgICBiZWVuIHVwcGVyY2FzZWQKKyAgICoKKyAgICovCisgIHByaXZhdGUgTGlzdCB0b1VwcGVyQ2FzZShDb2xsZWN0aW9uIGV4cGVjdGVkKSB7CisgICAgTGlzdCB1cHBlcmQgPSBuZXcgQXJyYXlMaXN0KGV4cGVjdGVkLnNpemUoKSk7CisgICAgSXRlcmF0b3IgaXRlciA9IGV4cGVjdGVkLml0ZXJhdG9yKCk7CisgICAgd2hpbGUgKGl0ZXIuaGFzTmV4dCgpKSB7CisgICAgICB1cHBlcmQuYWRkKGl0ZXIubmV4dCgpLnRvU3RyaW5nKCkudG9VcHBlckNhc2UoKSk7CisgICAgfQorICAgIHJldHVybiB1cHBlcmQ7CisgIH0KKworICAvKioKKyAgICogQXNzZXJ0cyB0aGF0IGVhY2ggZW50cnkgaW4gYWN0dWFsIGlzIG1hdGNoZWQgd2l0aCBhbiBlbnRyeSBpbiBleHBlY3RlZAorICAgKiB0aGF0IG9ubHkgZGlmZmVycyBieSBjYXNlLiBPcmRlciBpcyBub3Qgc2lnbmlmaWNhbnQuCisgICAqCisgICAqIEBwYXJhbSBhc3NlcnRJRAorICAgKiAgICAgICAgICAgIGlkZW50aWZpZXIgb2YgYXNzZXJ0aW9uCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBhY3R1YWwgdmFsdWUKKyAgICogQHBhcmFtIGV4cGVjdGVkCisgICAqICAgICAgICAgICAgRXhwZWN0ZWQgdmFsdWUsIG1heSBub3QgYmUgbnVsbC4KKyAgICovCisgIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFsQXV0b0Nhc2UoCisgICAgICBTdHJpbmcgY29udGV4dCwKKyAgICAgIFN0cmluZyBhc3NlcnRJRCwKKyAgICAgIENvbGxlY3Rpb24gZXhwZWN0ZWQsCisgICAgICBDb2xsZWN0aW9uIGFjdHVhbCkgeworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgaWYgKCJ0ZXh0L2h0bWwiLmVxdWFscyhjb250ZW50VHlwZSkpIHsKKyAgICAgIGlmICgiYXR0cmlidXRlIi5lcXVhbHMoY29udGV4dCkpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzSWdub3JlQ2FzZShhc3NlcnRJRCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgICB9CisgICAgICBlbHNlIHsKKyAgICAgICAgZnJhbWV3b3JrLmFzc2VydEVxdWFscyh0aGlzLCBhc3NlcnRJRCwgdG9VcHBlckNhc2UoZXhwZWN0ZWQpLCBhY3R1YWwpOworICAgICAgfQorCisgICAgfQorICAgIGVsc2UgeworICAgICAgZnJhbWV3b3JrLmFzc2VydEVxdWFscyh0aGlzLCBhc3NlcnRJRCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEFzc2VydHMgdGhhdCBlYWNoIGVudHJ5IGluIGFjdHVhbCBpcyBtYXRjaGVkIHdpdGggYW4gZW50cnkgaW4gZXhwZWN0ZWQKKyAgICogdGhhdCBvbmx5IGRpZmZlcnMgYnkgY2FzZS4gT3JkZXIgaXMgc2lnbmlmaWNhbnQuCisgICAqCisgICAqIEBwYXJhbSBhc3NlcnRJRAorICAgKiAgICAgICAgICAgIGlkZW50aWZpZXIgb2YgYXNzZXJ0aW9uCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBhY3R1YWwgdmFsdWUKKyAgICogQHBhcmFtIGV4cGVjdGVkCisgICAqICAgICAgICAgICAgRXhwZWN0ZWQgdmFsdWUsIG1heSBub3QgYmUgbnVsbC4KKyAgICovCisgIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFsc0F1dG9DYXNlKAorICAgICAgU3RyaW5nIGNvbnRleHQsCisgICAgICBTdHJpbmcgYXNzZXJ0SUQsCisgICAgICBMaXN0IGV4cGVjdGVkLAorICAgICAgTGlzdCBhY3R1YWwpIHsKKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIGlmICgidGV4dC9odG1sIi5lcXVhbHMoY29udGVudFR5cGUpKSB7CisgICAgICBpZiAoImF0dHJpYnV0ZSIuZXF1YWxzKGNvbnRleHQpKSB7CisgICAgICAgIGFzc2VydEVxdWFsc0lnbm9yZUNhc2UoYXNzZXJ0SUQsIGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIGZyYW1ld29yay5hc3NlcnRFcXVhbHModGhpcywgYXNzZXJ0SUQsIHRvVXBwZXJDYXNlKGV4cGVjdGVkKSwgYWN0dWFsKTsKKyAgICAgIH0KKworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgIGZyYW1ld29yay5hc3NlcnRFcXVhbHModGhpcywgYXNzZXJ0SUQsIGV4cGVjdGVkLCBhY3R1YWwpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBBc3NlcnRzIHRoYXQgZXhwZWN0ZWQuZXF1YWxzKGFjdHVhbCkgaXMgdHJ1ZQorICAgKgorICAgKiBAcGFyYW0gYXNzZXJ0SUQKKyAgICogICAgICAgICAgICBpZGVudGlmaWVyIG9mIGFzc2VydGlvbgorICAgKiBAcGFyYW0gYWN0dWFsCisgICAqICAgICAgICAgICAgYWN0dWFsIHZhbHVlCisgICAqIEBwYXJhbSBleHBlY3RlZAorICAgKiAgICAgICAgICAgIEV4cGVjdGVkIHZhbHVlLCBtYXkgbm90IGJlIG51bGwuCisgICAqLworICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIGFzc2VydElELCBTdHJpbmcgZXhwZWN0ZWQsIFN0cmluZyBhY3R1YWwpIHsKKyAgICBmcmFtZXdvcmsuYXNzZXJ0RXF1YWxzKHRoaXMsIGFzc2VydElELCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgfQorCisgIC8qKgorICAgKiBBc3NlcnRzIHRoYXQgdmFsdWVzIG9mIGV4cGVjdGVkIGFuZCBhY3R1YWwgYXJlIGVxdWFsLgorICAgKgorICAgKiBAcGFyYW0gYXNzZXJ0SUQKKyAgICogICAgICAgICAgICBpZGVudGlmaWVyIG9mIGFzc2VydGlvbgorICAgKiBAcGFyYW0gYWN0dWFsCisgICAqICAgICAgICAgICAgYWN0dWFsIHZhbHVlCisgICAqIEBwYXJhbSBleHBlY3RlZAorICAgKiAgICAgICAgICAgIEV4cGVjdGVkIHZhbHVlLCBtYXkgbm90IGJlIG51bGwuCisgICAqLworICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIGFzc2VydElELCBpbnQgZXhwZWN0ZWQsIGludCBhY3R1YWwpIHsKKyAgICBmcmFtZXdvcmsuYXNzZXJ0RXF1YWxzKHRoaXMsIGFzc2VydElELCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgfQorCisgIC8qKgorICAgKiBBc3NlcnRzIHRoYXQgdmFsdWVzIG9mIGV4cGVjdGVkIGFuZCBhY3R1YWwgYXJlIGVxdWFsLgorICAgKgorICAgKiBAcGFyYW0gYXNzZXJ0SUQKKyAgICogICAgICAgICAgICBpZGVudGlmaWVyIG9mIGFzc2VydGlvbgorICAgKiBAcGFyYW0gYWN0dWFsCisgICAqICAgICAgICAgICAgYWN0dWFsIHZhbHVlCisgICAqIEBwYXJhbSBleHBlY3RlZAorICAgKiAgICAgICAgICAgIEV4cGVjdGVkIHZhbHVlLCBtYXkgbm90IGJlIG51bGwuCisgICAqLworICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIGFzc2VydElELCBkb3VibGUgZXhwZWN0ZWQsIGRvdWJsZSBhY3R1YWwpIHsKKyAgICBmcmFtZXdvcmsuYXNzZXJ0RXF1YWxzKHRoaXMsIGFzc2VydElELCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgfQorCisgIC8qKgorICAgKiBBc3NlcnRzIHRoYXQgdmFsdWVzIG9mIGV4cGVjdGVkIGFuZCBhY3R1YWwgYXJlIGVxdWFsLgorICAgKgorICAgKiBAcGFyYW0gYXNzZXJ0SUQKKyAgICogICAgICAgICAgICBpZGVudGlmaWVyIG9mIGFzc2VydGlvbgorICAgKiBAcGFyYW0gYWN0dWFsCisgICAqICAgICAgICAgICAgYWN0dWFsIHZhbHVlCisgICAqIEBwYXJhbSBleHBlY3RlZAorICAgKiAgICAgICAgICAgIEV4cGVjdGVkIHZhbHVlLCBtYXkgbm90IGJlIG51bGwuCisgICAqLworICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoCisgICAgICBTdHJpbmcgYXNzZXJ0SUQsCisgICAgICBib29sZWFuIGV4cGVjdGVkLAorICAgICAgYm9vbGVhbiBhY3R1YWwpIHsKKyAgICBmcmFtZXdvcmsuYXNzZXJ0RXF1YWxzKHRoaXMsIGFzc2VydElELCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgfQorCisgIC8qKgorICAgKiBBc3NlcnRzIHRoYXQgZWFjaCBlbnRyeSBpbiBhY3R1YWwgZXhhY3RseSBtYXRjaGVzIHdpdGggYW4gZW50cnkgaW4KKyAgICogZXhwZWN0ZWQuIE9yZGVyIGlzIG5vdCBzaWduaWZpY2FudC4KKyAgICoKKyAgICogQHBhcmFtIGFzc2VydElECisgICAqICAgICAgICAgICAgaWRlbnRpZmllciBvZiBhc3NlcnRpb24KKyAgICogQHBhcmFtIGFjdHVhbAorICAgKiAgICAgICAgICAgIGFjdHVhbCB2YWx1ZQorICAgKiBAcGFyYW0gZXhwZWN0ZWQKKyAgICogICAgICAgICAgICBFeHBlY3RlZCB2YWx1ZSwgbWF5IG5vdCBiZSBudWxsLgorICAgKi8KKyAgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKAorICAgICAgU3RyaW5nIGFzc2VydElELAorICAgICAgQ29sbGVjdGlvbiBleHBlY3RlZCwKKyAgICAgIE5vZGVMaXN0IGFjdHVhbCkgeworICAgIENvbGxlY3Rpb24gYWN0dWFsTGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICBpbnQgYWN0dWFsTGVuID0gYWN0dWFsLmdldExlbmd0aCgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWN0dWFsTGVuOyBpKyspIHsKKyAgICAgIGFjdHVhbExpc3QuYWRkKGFjdHVhbC5pdGVtKGkpKTsKKyAgICB9CisgICAgZnJhbWV3b3JrLmFzc2VydEVxdWFscyh0aGlzLCBhc3NlcnRJRCwgZXhwZWN0ZWQsIGFjdHVhbExpc3QpOworICB9CisKKyAgLyoqCisgICAqIEFzc2VydHMgdGhhdCBlYWNoIGVudHJ5IGluIGFjdHVhbCBleGFjdGx5IG1hdGNoZXMgd2l0aCBhbiBlbnRyeSBpbgorICAgKiBleHBlY3RlZC4gT3JkZXIgaXMgbm90IHNpZ25pZmljYW50LgorICAgKgorICAgKiBAcGFyYW0gYXNzZXJ0SUQKKyAgICogICAgICAgICAgICBpZGVudGlmaWVyIG9mIGFzc2VydGlvbgorICAgKiBAcGFyYW0gYWN0dWFsCisgICAqICAgICAgICAgICAgYWN0dWFsIHZhbHVlCisgICAqIEBwYXJhbSBleHBlY3RlZAorICAgKiAgICAgICAgICAgIEV4cGVjdGVkIHZhbHVlLCBtYXkgbm90IGJlIG51bGwuCisgICAqLworICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoCisgICAgICBTdHJpbmcgYXNzZXJ0SUQsCisgICAgICBDb2xsZWN0aW9uIGV4cGVjdGVkLAorICAgICAgQ29sbGVjdGlvbiBhY3R1YWwpIHsKKyAgICBmcmFtZXdvcmsuYXNzZXJ0RXF1YWxzKHRoaXMsIGFzc2VydElELCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgfQorCisgIC8qKgorICAgKiBBc3NlcnRzIHRoYXQgZXhwZWN0ZWQuZXF1YWxzSWdub3JlQ2FzZShhY3R1YWwpIGlzIGZhbHNlCisgICAqCisgICAqIEBwYXJhbSBhc3NlcnRJRAorICAgKiAgICAgICAgICAgIGlkZW50aWZpZXIgb2YgYXNzZXJ0aW9uCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBhY3R1YWwgdmFsdWUKKyAgICogQHBhcmFtIGV4cGVjdGVkCisgICAqICAgICAgICAgICAgRXhwZWN0ZWQgdmFsdWUsIG1heSBub3QgYmUgbnVsbC4KKyAgICovCisgIHB1YmxpYyB2b2lkIGFzc2VydE5vdEVxdWFsc0lnbm9yZUNhc2UoCisgICAgICBTdHJpbmcgYXNzZXJ0SUQsCisgICAgICBTdHJpbmcgZXhwZWN0ZWQsCisgICAgICBTdHJpbmcgYWN0dWFsKSB7CisgICAgZnJhbWV3b3JrLmFzc2VydE5vdEVxdWFsc0lnbm9yZUNhc2UodGhpcywgYXNzZXJ0SUQsIGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgLyoqCisgICAqIEFzc2VydHMgdGhhdCBleHBlY3RlZC5lcXVhbHNJZ25vcmVDYXNlKGFjdHVhbCkgaXMgZmFsc2UKKyAgICoKKyAgICogQHBhcmFtIGFzc2VydElECisgICAqICAgICAgICAgICAgaWRlbnRpZmllciBvZiBhc3NlcnRpb24KKyAgICogQHBhcmFtIGFjdHVhbAorICAgKiAgICAgICAgICAgIGFjdHVhbCB2YWx1ZQorICAgKiBAcGFyYW0gZXhwZWN0ZWQKKyAgICogICAgICAgICAgICBFeHBlY3RlZCB2YWx1ZSwgbWF5IG5vdCBiZSBudWxsLgorICAgKi8KKyAgcHVibGljIHZvaWQgYXNzZXJ0Tm90RXF1YWxzQXV0b0Nhc2UoCisgICAgICBTdHJpbmcgY29udGV4dCwKKyAgICAgIFN0cmluZyBhc3NlcnRJRCwKKyAgICAgIFN0cmluZyBleHBlY3RlZCwKKyAgICAgIFN0cmluZyBhY3R1YWwpIHsKKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIGlmICgidGV4dC9odG1sIi5lcXVhbHMoY29udGVudFR5cGUpKSB7CisgICAgICBpZiAoImF0dHJpYnV0ZSIuZXF1YWxzKGNvbnRleHQpKSB7CisgICAgICAgIGZyYW1ld29yay5hc3NlcnROb3RFcXVhbHNJZ25vcmVDYXNlKHRoaXMsIGFzc2VydElELCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgIH0KKyAgICAgIGVsc2UgeworICAgICAgICBmcmFtZXdvcmsuYXNzZXJ0Tm90RXF1YWxzKHRoaXMsIGFzc2VydElELCBleHBlY3RlZC50b1VwcGVyQ2FzZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdHVhbCk7CisgICAgICB9CisgICAgfQorICAgIGZyYW1ld29yay5hc3NlcnROb3RFcXVhbHModGhpcywgYXNzZXJ0SUQsIGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgLyoqCisgICAqIEFzc2VydHMgdGhhdCB2YWx1ZXMgb2YgZXhwZWN0ZWQgYW5kIGFjdHVhbCBhcmUgbm90IGVxdWFsLgorICAgKgorICAgKiBAcGFyYW0gYXNzZXJ0SUQKKyAgICogICAgICAgICAgICBpZGVudGlmaWVyIG9mIGFzc2VydGlvbgorICAgKiBAcGFyYW0gYWN0dWFsCisgICAqICAgICAgICAgICAgYWN0dWFsIHZhbHVlCisgICAqIEBwYXJhbSBleHBlY3RlZAorICAgKiAgICAgICAgICAgIEV4cGVjdGVkIHZhbHVlLCBtYXkgbm90IGJlIG51bGwuCisgICAqLworICBwdWJsaWMgdm9pZCBhc3NlcnROb3RFcXVhbHMoCisgICAgICBTdHJpbmcgYXNzZXJ0SUQsCisgICAgICBTdHJpbmcgZXhwZWN0ZWQsCisgICAgICBTdHJpbmcgYWN0dWFsKSB7CisgICAgZnJhbWV3b3JrLmFzc2VydE5vdEVxdWFscyh0aGlzLCBhc3NlcnRJRCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICAvKioKKyAgICogQXNzZXJ0cyB0aGF0IHZhbHVlcyBvZiBleHBlY3RlZCBhbmQgYWN0dWFsIGFyZSBub3QgZXF1YWwuCisgICAqCisgICAqIEBwYXJhbSBhc3NlcnRJRAorICAgKiAgICAgICAgICAgIGlkZW50aWZpZXIgb2YgYXNzZXJ0aW9uCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBhY3R1YWwgdmFsdWUKKyAgICogQHBhcmFtIGV4cGVjdGVkCisgICAqICAgICAgICAgICAgRXhwZWN0ZWQgdmFsdWUsIG1heSBub3QgYmUgbnVsbC4KKyAgICovCisgIHB1YmxpYyB2b2lkIGFzc2VydE5vdEVxdWFscyhTdHJpbmcgYXNzZXJ0SUQsIGludCBleHBlY3RlZCwgaW50IGFjdHVhbCkgeworICAgIGZyYW1ld29yay5hc3NlcnROb3RFcXVhbHModGhpcywgYXNzZXJ0SUQsIGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgLyoqCisgICAqIEFzc2VydHMgdGhhdCB2YWx1ZXMgb2YgZXhwZWN0ZWQgYW5kIGFjdHVhbCBhcmUgbm90IGVxdWFsLgorICAgKgorICAgKiBAcGFyYW0gYXNzZXJ0SUQKKyAgICogICAgICAgICAgICBpZGVudGlmaWVyIG9mIGFzc2VydGlvbgorICAgKiBAcGFyYW0gYWN0dWFsCisgICAqICAgICAgICAgICAgYWN0dWFsIHZhbHVlCisgICAqIEBwYXJhbSBleHBlY3RlZAorICAgKiAgICAgICAgICAgIEV4cGVjdGVkIHZhbHVlLCBtYXkgbm90IGJlIG51bGwuCisgICAqLworICBwdWJsaWMgdm9pZCBhc3NlcnROb3RFcXVhbHMoCisgICAgICBTdHJpbmcgYXNzZXJ0SUQsCisgICAgICBkb3VibGUgZXhwZWN0ZWQsCisgICAgICBkb3VibGUgYWN0dWFsKSB7CisgICAgZnJhbWV3b3JrLmFzc2VydE5vdEVxdWFscyh0aGlzLCBhc3NlcnRJRCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICAvKioKKyAgICogQXNzZXJ0cyBhc3BlY3RzIG9mIGEgVVJJCisgICAqCisgICAqIEBwYXJhbSBhc3NlcnRJRAorICAgKiAgICAgICAgICAgIGlkZW50aWZpZXIgb2YgYXNzZXJ0aW9uCisgICAqIEBwYXJhbSBzY2hlbWUKKyAgICogICAgICAgICAgICBFeHBlY3RlZCBzY2hlbWUsIGZvciBleGFtcGxlLCAiZmlsZSIuIElmIG51bGwsIHNjaGVtZSBpcworICAgKiAgICAgICAgICAgIGlnbm9yZWQuCisgICAqIEBwYXJhbSBwYXRoCisgICAqICAgICAgICAgICAgRXhwZWN0ZWQgcGF0aCwgZm9yIGV4YW1wbGUsICIvRE9NL1Rlc3QiLiBJZiBudWxsLCBwYXRoIGlzCisgICAqICAgICAgICAgICAgaWdub3JlZC4KKyAgICogQHBhcmFtIGhvc3QKKyAgICogICAgICAgICAgICBFeHBlY3RlZCBob3N0LCBmb3IgZXhhbXBsZSwgInd3dy53My5vcmciLiBJZiBudWxsLCBob3N0IGlzCisgICAqICAgICAgICAgICAgaWdub3JlZC4KKyAgICogQHBhcmFtIGZpbGUKKyAgICogICAgICAgICAgICBFeHBlY3RlZCBmaWxlLCBmb3IgZXhhbXBsZSwgInN0YWZmLnhtbCIuIElmIG51bGwsIGZpbGUgaXMKKyAgICogICAgICAgICAgICBpZ25vcmVkLgorICAgKiBAcGFyYW0gbmFtZQorICAgKiAgICAgICAgICAgIEV4cGVjdGVkIG5hbWUsIGZvciBleGFtcGxlLCAic3RhZmYiLiBJZiBudWxsLCBuYW1lIGlzCisgICAqICAgICAgICAgICAgaWdub3JlZC4KKyAgICogQHBhcmFtIG5hbWUKKyAgICogICAgICAgICAgICBFeHBlY3RlZCBuYW1lLCBmb3IgZXhhbXBsZSwgInN0YWZmIi4gSWYgbnVsbCwgbmFtZSBpcworICAgKiAgICAgICAgICAgIGlnbm9yZWQuCisgICAqIEBwYXJhbSBpc0Fic29sdXRlCisgICAqICAgICAgICAgICAgaWYgQm9vbGVhbi5UUlVFLCBVUkkgbXVzdCBiZSBhYnNvbHV0ZS4gTnVsbCBpbmRpY2F0ZXMgbm8KKyAgICogICAgICAgICAgICBhc3NlcnRpb24uCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBVUkkgdG8gYmUgdGVzdGVkLgorICAgKi8KKyAgcHVibGljIHZvaWQgYXNzZXJ0VVJJRXF1YWxzKAorICAgICAgU3RyaW5nIGFzc2VydElELAorICAgICAgU3RyaW5nIHNjaGVtZSwKKyAgICAgIFN0cmluZyBwYXRoLAorICAgICAgU3RyaW5nIGhvc3QsCisgICAgICBTdHJpbmcgZmlsZSwKKyAgICAgIFN0cmluZyBuYW1lLAorICAgICAgU3RyaW5nIHF1ZXJ5LAorICAgICAgU3RyaW5nIGZyYWdtZW50LAorICAgICAgQm9vbGVhbiBpc0Fic29sdXRlLAorICAgICAgU3RyaW5nIGFjdHVhbCkgeworICAgIC8vCisgICAgLy8gIFVSSSBtdXN0IGJlIG5vbi1udWxsCisgICAgYXNzZXJ0Tm90TnVsbChhc3NlcnRJRCwgYWN0dWFsKTsKKworICAgIFN0cmluZyB1cmkgPSBhY3R1YWw7CisKKyAgICBpbnQgbGFzdFBvdW5kID0gYWN0dWFsLmxhc3RJbmRleE9mKCIjIik7CisgICAgU3RyaW5nIGFjdHVhbEZyYWdtZW50ID0gIiI7CisgICAgaWYgKGxhc3RQb3VuZCAhPSAtMSkgeworICAgICAgLy8KKyAgICAgIC8vICAgc3Vic3RyaW5nIGJlZm9yZSBwb3VuZAorICAgICAgLy8KKyAgICAgIHVyaSA9IGFjdHVhbC5zdWJzdHJpbmcoMCwgbGFzdFBvdW5kKTsKKyAgICAgIGFjdHVhbEZyYWdtZW50ID0gYWN0dWFsLnN1YnN0cmluZyhsYXN0UG91bmQgKyAxKTsKKyAgICB9CisgICAgaWYgKGZyYWdtZW50ICE9IG51bGwpIHsKKyAgICAgIGFzc2VydEVxdWFscyhhc3NlcnRJRCwgZnJhZ21lbnQsIGFjdHVhbEZyYWdtZW50KTsKKworICAgIH0KKyAgICBpbnQgbGFzdFF1ZXN0aW9uID0gdXJpLmxhc3RJbmRleE9mKCI/Iik7CisgICAgU3RyaW5nIGFjdHVhbFF1ZXJ5ID0gIiI7CisgICAgaWYgKGxhc3RRdWVzdGlvbiAhPSAtMSkgeworICAgICAgLy8KKyAgICAgIC8vICAgc3Vic3RyaW5nIGJlZm9yZSBwb3VuZAorICAgICAgLy8KKyAgICAgIHVyaSA9IGFjdHVhbC5zdWJzdHJpbmcoMCwgbGFzdFF1ZXN0aW9uKTsKKyAgICAgIGFjdHVhbFF1ZXJ5ID0gYWN0dWFsLnN1YnN0cmluZyhsYXN0UXVlc3Rpb24gKyAxKTsKKyAgICB9CisgICAgaWYgKHF1ZXJ5ICE9IG51bGwpIHsKKyAgICAgIGFzc2VydEVxdWFscyhhc3NlcnRJRCwgcXVlcnksIGFjdHVhbFF1ZXJ5KTsKKworICAgIH0KKyAgICBpbnQgZmlyc3RDb2xvbiA9IHVyaS5pbmRleE9mKCI6Iik7CisgICAgaW50IGZpcnN0U2xhc2ggPSB1cmkuaW5kZXhPZigiLyIpOworICAgIFN0cmluZyBhY3R1YWxQYXRoID0gdXJpOworICAgIFN0cmluZyBhY3R1YWxTY2hlbWUgPSAiIjsKKyAgICBpZiAoZmlyc3RDb2xvbiAhPSAtMSAmJiBmaXJzdENvbG9uIDwgZmlyc3RTbGFzaCkgeworICAgICAgYWN0dWFsU2NoZW1lID0gdXJpLnN1YnN0cmluZygwLCBmaXJzdENvbG9uKTsKKyAgICAgIGFjdHVhbFBhdGggPSB1cmkuc3Vic3RyaW5nKGZpcnN0Q29sb24gKyAxKTsKKyAgICB9CisKKyAgICBpZiAoc2NoZW1lICE9IG51bGwpIHsKKyAgICAgIGFzc2VydEVxdWFscyhhc3NlcnRJRCwgc2NoZW1lLCBhY3R1YWxTY2hlbWUpOworICAgIH0KKworICAgIGlmIChwYXRoICE9IG51bGwpIHsKKyAgICAgIGFzc2VydEVxdWFscyhhc3NlcnRJRCwgcGF0aCwgYWN0dWFsUGF0aCk7CisgICAgfQorCisgICAgaWYgKGhvc3QgIT0gbnVsbCkgeworICAgICAgU3RyaW5nIGFjdHVhbEhvc3QgPSAiIjsKKyAgICAgIGlmIChhY3R1YWxQYXRoLnN0YXJ0c1dpdGgoIi8vIikpIHsKKyAgICAgICAgaW50IHRlcm1TbGFzaCA9IGFjdHVhbFBhdGguaW5kZXhPZigiLyIsIDIpOworICAgICAgICBhY3R1YWxIb3N0ID0gYWN0dWFsUGF0aC5zdWJzdHJpbmcoMCwgdGVybVNsYXNoKTsKKyAgICAgIH0KKyAgICAgIGFzc2VydEVxdWFscyhhc3NlcnRJRCwgaG9zdCwgYWN0dWFsSG9zdCk7CisgICAgfQorCisgICAgU3RyaW5nIGFjdHVhbEZpbGUgPSBhY3R1YWxQYXRoOworICAgIGlmIChmaWxlICE9IG51bGwgfHwgbmFtZSAhPSBudWxsKSB7CisgICAgICBpbnQgZmluYWxTbGFzaCA9IGFjdHVhbFBhdGgubGFzdEluZGV4T2YoIi8iKTsKKyAgICAgIGlmIChmaW5hbFNsYXNoICE9IC0xKSB7CisgICAgICAgIGFjdHVhbEZpbGUgPSBhY3R1YWxQYXRoLnN1YnN0cmluZyhmaW5hbFNsYXNoICsgMSk7CisgICAgICB9CisgICAgICBpZiAoZmlsZSAhPSBudWxsKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhhc3NlcnRJRCwgZmlsZSwgYWN0dWFsRmlsZSk7CisgICAgICB9CisgICAgfQorCisgICAgaWYgKG5hbWUgIT0gbnVsbCkgeworICAgICAgU3RyaW5nIGFjdHVhbE5hbWUgPSBhY3R1YWxGaWxlOworICAgICAgaW50IGZpbmFsUGVyaW9kID0gYWN0dWFsRmlsZS5sYXN0SW5kZXhPZigiLiIpOworICAgICAgaWYgKGZpbmFsUGVyaW9kICE9IC0xKSB7CisgICAgICAgIGFjdHVhbE5hbWUgPSBhY3R1YWxGaWxlLnN1YnN0cmluZygwLCBmaW5hbFBlcmlvZCk7CisgICAgICB9CisgICAgICBhc3NlcnRFcXVhbHMoYXNzZXJ0SUQsIG5hbWUsIGFjdHVhbE5hbWUpOworICAgIH0KKworICAgIGlmIChpc0Fic29sdXRlICE9IG51bGwpIHsKKyAgICAgIC8vCisgICAgICAvLyAgIEphciBVUkwncyB3aWxsIGhhdmUgYW55IGFjdHVhbCBwYXRoIGxpa2UgZmlsZTovYzovc29tZWRyaXZlLi4uCisgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgYXNzZXJ0SUQsCisgICAgICAgICAgaXNBYnNvbHV0ZS5ib29sZWFuVmFsdWUoKSwKKyAgICAgICAgICBhY3R1YWxQYXRoLnN0YXJ0c1dpdGgoIi8iKSB8fCBhY3R1YWxQYXRoLnN0YXJ0c1dpdGgoImZpbGU6LyIpKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ29tcGFyZXMgdGhlIGlkZW50aXR5IG9mIGFjdHVhbCBhbmQgZXhwZWN0ZWQuCisgICAqCisgICAqIEBwYXJhbSBleHBlY3RlZAorICAgKiAgICAgICAgICAgIGV4cGVjdGVkCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBhY3R1YWwKKyAgICogQHJldHVybiB0cnVlIGlmIGFjdHVhbCBhbmQgZXhwZWN0ZWQgYXJlIHRoZSBzYW1lIG9iamVjdC4KKyAgICovCisgIHB1YmxpYyBib29sZWFuIHNhbWUoT2JqZWN0IGV4cGVjdGVkLCBPYmplY3QgYWN0dWFsKSB7CisgICAgcmV0dXJuIGZyYW1ld29yay5zYW1lKGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgLyoqCisgICAqIENvbXBhcmVzIHRoZSB2YWx1ZSBvZiBhY3R1YWwgYW5kIGV4cGVjdGVkIGlnbm9yaW5nIGNhc2UuCisgICAqCisgICAqIEBwYXJhbSBleHBlY3RlZAorICAgKiAgICAgICAgICAgIGV4cGVjdGVkCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBhY3R1YWwKKyAgICogQHJldHVybiB0cnVlIGlmIGFjdHVhbCBhbmQgZXhwZWN0ZWQgYXJlIGVxdWFsIGlnbm9yaW5nIGNhc2UuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBlcXVhbHNJZ25vcmVDYXNlKFN0cmluZyBleHBlY3RlZCwgU3RyaW5nIGFjdHVhbCkgeworICAgIHJldHVybiBmcmFtZXdvcmsuZXF1YWxzSWdub3JlQ2FzZShleHBlY3RlZCwgYWN0dWFsKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wYXJlcyB0aGUgdmFsdWVzIGluIGFjdHVhbCBhbmQgZXhwZWN0ZWQgaWdub3JpbmcgY2FzZSBhbmQgb3JkZXIuCisgICAqCisgICAqIEBwYXJhbSBleHBlY3RlZAorICAgKiAgICAgICAgICAgIGV4cGVjdGVkCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBhY3R1YWwKKyAgICogQHJldHVybiB0cnVlIGlmIGFjdHVhbCBhbmQgZXhwZWN0ZWQgYXJlIGVxdWFsIGlnbm9yaW5nIGNhc2UuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBlcXVhbHNJZ25vcmVDYXNlKENvbGxlY3Rpb24gZXhwZWN0ZWQsIENvbGxlY3Rpb24gYWN0dWFsKSB7CisgICAgcmV0dXJuIGZyYW1ld29yay5lcXVhbHNJZ25vcmVDYXNlKGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgLyoqCisgICAqIENvbXBhcmVzIHRoZSB2YWx1ZXMgaW4gYWN0dWFsIGFuZCBleHBlY3RlZCBpZ25vcmluZyBjYXNlLgorICAgKgorICAgKiBAcGFyYW0gZXhwZWN0ZWQKKyAgICogICAgICAgICAgICBleHBlY3RlZAorICAgKiBAcGFyYW0gYWN0dWFsCisgICAqICAgICAgICAgICAgYWN0dWFsCisgICAqIEByZXR1cm4gdHJ1ZSBpZiBhY3R1YWwgYW5kIGV4cGVjdGVkIGFyZSBlcXVhbCBpZ25vcmluZyBjYXNlLgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzSWdub3JlQ2FzZShMaXN0IGV4cGVjdGVkLCBMaXN0IGFjdHVhbCkgeworICAgIHJldHVybiBmcmFtZXdvcmsuZXF1YWxzSWdub3JlQ2FzZShleHBlY3RlZCwgYWN0dWFsKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wYXJlcyB0aGUgdmFsdWUgb2YgYWN0dWFsIGFuZCBleHBlY3RlZCBpZ25vcmluZyBjYXNlLgorICAgKgorICAgKiBAcGFyYW0gZXhwZWN0ZWQKKyAgICogICAgICAgICAgICBleHBlY3RlZAorICAgKiBAcGFyYW0gYWN0dWFsCisgICAqICAgICAgICAgICAgYWN0dWFsCisgICAqIEByZXR1cm4gdHJ1ZSBpZiBhY3R1YWwgYW5kIGV4cGVjdGVkIGFyZSBlcXVhbCBpZ25vcmluZyBjYXNlLgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzQXV0b0Nhc2UoU3RyaW5nIGNvbnRleHQsIFN0cmluZyBleHBlY3RlZCwgU3RyaW5nIGFjdHVhbCkgeworICAgIGlmICgidGV4dC9odG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpIHsKKyAgICAgIGlmICgiYXR0cmlidXRlIi5lcXVhbHMoY29udGV4dCkpIHsKKyAgICAgICAgcmV0dXJuIGZyYW1ld29yay5lcXVhbHNJZ25vcmVDYXNlKGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIHJldHVybiBmcmFtZXdvcmsuZXF1YWxzKGV4cGVjdGVkLnRvVXBwZXJDYXNlKCksIGFjdHVhbCk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmcmFtZXdvcmsuZXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgLyoqCisgICAqIENvbXBhcmVzIHRoZSB2YWx1ZXMgaW4gYWN0dWFsIGFuZCBleHBlY3RlZCBpZ25vcmluZyBjYXNlIGFuZCBvcmRlci4KKyAgICoKKyAgICogQHBhcmFtIGV4cGVjdGVkCisgICAqICAgICAgICAgICAgZXhwZWN0ZWQKKyAgICogQHBhcmFtIGFjdHVhbAorICAgKiAgICAgICAgICAgIGFjdHVhbAorICAgKiBAcmV0dXJuIHRydWUgaWYgYWN0dWFsIGFuZCBleHBlY3RlZCBhcmUgZXF1YWwgaWdub3JpbmcgY2FzZS4KKyAgICovCisgIHB1YmxpYyBib29sZWFuIGVxdWFsc0F1dG9DYXNlKFN0cmluZyBjb250ZXh0LCBDb2xsZWN0aW9uIGV4cGVjdGVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsZWN0aW9uIGFjdHVhbCkgeworICAgIGlmICgidGV4dC9odG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpIHsKKyAgICAgIGlmICgiYXR0cmlidXRlIi5lcXVhbHMoY29udGV4dCkpIHsKKyAgICAgICAgcmV0dXJuIGZyYW1ld29yay5lcXVhbHNJZ25vcmVDYXNlKGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIHJldHVybiBmcmFtZXdvcmsuZXF1YWxzKHRvVXBwZXJDYXNlKGV4cGVjdGVkKSwgYWN0dWFsKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGZyYW1ld29yay5lcXVhbHMoZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICAvKioKKyAgICogQ29tcGFyZXMgdGhlIHZhbHVlcyBpbiBhY3R1YWwgYW5kIGV4cGVjdGVkIGlnbm9yaW5nIGNhc2UuCisgICAqCisgICAqIEBwYXJhbSBleHBlY3RlZAorICAgKiAgICAgICAgICAgIGV4cGVjdGVkCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBhY3R1YWwKKyAgICogQHJldHVybiB0cnVlIGlmIGFjdHVhbCBhbmQgZXhwZWN0ZWQgYXJlIGVxdWFsIGlnbm9yaW5nIGNhc2UuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBlcXVhbHNBdXRvQ2FzZShTdHJpbmcgY29udGV4dCwgTGlzdCBleHBlY3RlZCwgTGlzdCBhY3R1YWwpIHsKKyAgICBpZiAoInRleHQvaHRtbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSB7CisgICAgICBpZiAoImF0dHJpYnV0ZSIuZXF1YWxzKGNvbnRleHQpKSB7CisgICAgICAgIHJldHVybiBmcmFtZXdvcmsuZXF1YWxzSWdub3JlQ2FzZShleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgIH0KKyAgICAgIGVsc2UgeworICAgICAgICByZXR1cm4gZnJhbWV3b3JrLmVxdWFscyh0b1VwcGVyQ2FzZShleHBlY3RlZCksIGFjdHVhbCk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmcmFtZXdvcmsuZXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgLyoqCisgICAqIENvbXBhcmVzIHRoZSB2YWx1ZXMgb2YgYWN0dWFsIGFuZCBleHBlY3RlZC4KKyAgICoKKyAgICogQHBhcmFtIGV4cGVjdGVkCisgICAqICAgICAgICAgICAgZXhwZWN0ZWQKKyAgICogQHBhcmFtIGFjdHVhbAorICAgKiAgICAgICAgICAgIGFjdHVhbAorICAgKiBAcmV0dXJuIHRydWUgaWYgYWN0dWFsIGFuZCBleHBlY3RlZCBhcmUgZXF1YWwuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoU3RyaW5nIGV4cGVjdGVkLCBTdHJpbmcgYWN0dWFsKSB7CisgICAgcmV0dXJuIGZyYW1ld29yay5lcXVhbHMoZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICAvKioKKyAgICogQ29tcGFyZXMgdGhlIHZhbHVlcyBvZiBhY3R1YWwgYW5kIGV4cGVjdGVkLgorICAgKgorICAgKiBAcGFyYW0gZXhwZWN0ZWQKKyAgICogICAgICAgICAgICBleHBlY3RlZAorICAgKiBAcGFyYW0gYWN0dWFsCisgICAqICAgICAgICAgICAgYWN0dWFsCisgICAqIEByZXR1cm4gdHJ1ZSBpZiBhY3R1YWwgYW5kIGV4cGVjdGVkIGFyZSBlcXVhbC4KKyAgICovCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhpbnQgZXhwZWN0ZWQsIGludCBhY3R1YWwpIHsKKyAgICByZXR1cm4gZnJhbWV3b3JrLmVxdWFscyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wYXJlcyB0aGUgdmFsdWVzIG9mIGFjdHVhbCBhbmQgZXhwZWN0ZWQuCisgICAqCisgICAqIEBwYXJhbSBleHBlY3RlZAorICAgKiAgICAgICAgICAgIGV4cGVjdGVkCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBhY3R1YWwKKyAgICogQHJldHVybiB0cnVlIGlmIGFjdHVhbCBhbmQgZXhwZWN0ZWQgYXJlIGVxdWFsLgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGRvdWJsZSBleHBlY3RlZCwgZG91YmxlIGFjdHVhbCkgeworICAgIHJldHVybiBmcmFtZXdvcmsuZXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgLyoqCisgICAqIENvbXBhcmVzIHRoZSB2YWx1ZXMgaW4gYWN0dWFsIGFuZCBleHBlY3RlZCBpZ25vcmluZyBvcmRlci4KKyAgICoKKyAgICogQHBhcmFtIGV4cGVjdGVkCisgICAqICAgICAgICAgICAgZXhwZWN0ZWQKKyAgICogQHBhcmFtIGFjdHVhbAorICAgKiAgICAgICAgICAgIGFjdHVhbAorICAgKiBAcmV0dXJuIHRydWUgaWYgYWN0dWFsIGFuZCBleHBlY3RlZCBhcmUgZXF1YWwuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoQ29sbGVjdGlvbiBleHBlY3RlZCwgQ29sbGVjdGlvbiBhY3R1YWwpIHsKKyAgICByZXR1cm4gZnJhbWV3b3JrLmVxdWFscyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wYXJlcyB0aGUgdmFsdWVzIGluIGFjdHVhbCBhbmQgZXhwZWN0ZWQuCisgICAqCisgICAqIEBwYXJhbSBleHBlY3RlZAorICAgKiAgICAgICAgICAgIGV4cGVjdGVkCisgICAqIEBwYXJhbSBhY3R1YWwKKyAgICogICAgICAgICAgICBhY3R1YWwKKyAgICogQHJldHVybiB0cnVlIGlmIGFjdHVhbCBhbmQgZXhwZWN0ZWQgYXJlIGVxdWFsLgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKExpc3QgZXhwZWN0ZWQsIExpc3QgYWN0dWFsKSB7CisgICAgcmV0dXJuIGZyYW1ld29yay5lcXVhbHMoZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICAvKioKKyAgICogR2V0cyB0aGUgc2l6ZSBvZiB0aGUgY29sbGVjdGlvbgorICAgKgorICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgKiAgICAgICAgICAgIGNvbGxlY3Rpb24sIG1heSBub3QgYmUgbnVsbC4KKyAgICogQHJldHVybiBzaXplIG9mIGNvbGxlY3Rpb24KKyAgICovCisgIHB1YmxpYyBpbnQgc2l6ZShDb2xsZWN0aW9uIGNvbGxlY3Rpb24pIHsKKyAgICByZXR1cm4gZnJhbWV3b3JrLnNpemUoY29sbGVjdGlvbik7CisgIH0KKworICAvKioKKyAgICogR2V0cyB0aGUgc2l6ZSBvZiB0aGUgY29sbGVjdGlvbgorICAgKgorICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgKiAgICAgICAgICAgIGNvbGxlY3Rpb24sIG1heSBub3QgYmUgbnVsbC4KKyAgICogQHJldHVybiBzaXplIG9mIGNvbGxlY3Rpb24KKyAgICovCisgIHB1YmxpYyBpbnQgc2l6ZShOYW1lZE5vZGVNYXAgY29sbGVjdGlvbikgeworICAgIHJldHVybiBmcmFtZXdvcmsuc2l6ZShjb2xsZWN0aW9uKTsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIHRoZSBzaXplIG9mIHRoZSBjb2xsZWN0aW9uCisgICAqCisgICAqIEBwYXJhbSBjb2xsZWN0aW9uCisgICAqICAgICAgICAgICAgY29sbGVjdGlvbiwgbWF5IG5vdCBiZSBudWxsLgorICAgKiBAcmV0dXJuIHNpemUgb2YgY29sbGVjdGlvbgorICAgKi8KKyAgcHVibGljIGludCBzaXplKE5vZGVMaXN0IGNvbGxlY3Rpb24pIHsKKyAgICByZXR1cm4gZnJhbWV3b3JrLnNpemUoY29sbGVjdGlvbik7CisgIH0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIyNGU3MGUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0RPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmphdmEKQEAgLTAsMCArMSwxOTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHM7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIHBhcnRpY3VsYXIgcGFyc2VyIGFuZCBjb25maWd1cmF0aW9uCisgKiAoc3VjaCBhcyBlbnRpdHktZXhwYW5kaW5nLCBub24tdmFsaWRhdGluZywgd2hpdGVzcGFjZSBpZ25vcmluZykKKyAqIGZvciBhIHRlc3Qgc2Vzc2lvbi4gIEluZGl2aWR1YWwgdGVzdHMgb3Igc3VpdGVzIHdpdGhpbiBhCisgKiBzZXNzaW9uIGNhbiBvdmVycmlkZSB0aGUgc2Vzc2lvbiBwcm9wZXJ0aWVzIG9uIGEgY2FsbCB0bworICogY3JlYXRlQnVpbGRlckZhY3RvcnkuCisgKgorICogQGF1dGhvciBDdXJ0IEFybm9sZAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgeworICAvKioKKyAgICogICBQYXJzZXIgY29uZmlndXJhdGlvbgorICAgKi8KKyAgcHJpdmF0ZSBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3M7CisKKyAgLyoqCisgICAqICAgQ29uc3RydWN0b3IKKyAgICogICBAcGFyYW0gcHJvcGVydGllcyBBcnJheSBvZiBwYXJzZXIgc2V0dGluZ3MsIG1heSBiZSBudWxsLgorICAgKi8KKyAgcHVibGljIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncykgdGhyb3dzCisgICAgICBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICBpZiAoc2V0dGluZ3MgPT0gbnVsbCkgeworICAgICAgdGhpcy5zZXR0aW5ncyA9IG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nWzBdOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgIHRoaXMuc2V0dGluZ3MgPSAoRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdKSBzZXR0aW5ncy5jbG9uZSgpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiAgIFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICogICB3aXRoIHRoZSBzZXR0aW5ncyBmcm9tIHRoZSBhcmd1bWVudCBsaXN0CisgICAqICAgYW5kIGFueSBub24tcmV2b2tlZCBzZXR0aW5ncyBmcm9tIHRoZSBjdXJyZW50IG9iamVjdC4KKyAgICogICBAcGFyYW0gc2V0dGluZ3MgYXJyYXkgb2Ygc2V0dGluZ3MsIG1heSBiZSBudWxsLgorICAgKi8KKyAgcHVibGljIGFic3RyYWN0IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IG5ld0luc3RhbmNlKAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzKSB0aHJvd3MgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbjsKKworICBwdWJsaWMgYWJzdHJhY3QgRE9NSW1wbGVtZW50YXRpb24gZ2V0RE9NSW1wbGVtZW50YXRpb24oKTsKKworICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBoYXNGZWF0dXJlKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbik7CisKKyAgcHVibGljIGFic3RyYWN0IERvY3VtZW50IGxvYWQoamF2YS5uZXQuVVJMIHVybCkgdGhyb3dzIERPTVRlc3RMb2FkRXhjZXB0aW9uOworCisgIC8qKgorICAgKiAgQ3JlYXRlcyBYUGF0aCBldmFsdWF0b3IKKyAgICogIEBwYXJhbSBkb2MgRE9NIGRvY3VtZW50LCBtYXkgbm90IGJlIG51bGwKKyAgICovCisgIHB1YmxpYyBPYmplY3QgY3JlYXRlWFBhdGhFdmFsdWF0b3IoRG9jdW1lbnQgZG9jKSB7CisgICAgdHJ5IHsKKyAgICAgIE1ldGhvZCBnZXRGZWF0dXJlTWV0aG9kID0gZG9jLmdldENsYXNzKCkuZ2V0TWV0aG9kKCJnZXRGZWF0dXJlIiwKKyAgICAgICAgICBuZXcgQ2xhc3NbXSB7U3RyaW5nLmNsYXNzLCBTdHJpbmcuY2xhc3N9KTsKKyAgICAgIGlmIChnZXRGZWF0dXJlTWV0aG9kICE9IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIGdldEZlYXR1cmVNZXRob2QuaW52b2tlKGRvYywgbmV3IE9iamVjdFtdIHsiWFBhdGgiLCBudWxsfSk7CisgICAgICB9CisgICAgfQorICAgIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICB9CisgICAgcmV0dXJuIGRvYzsKKyAgfQorCisgIC8qKgorICAgKiAgIE1lcmdlcyB0aGUgc2V0dGluZ3MgZnJvbSB0aGUgc3BlY2lmaWMgdGVzdCBjYXNlIG9yIHN1aXRlCisgICAqICAgd2l0aCB0aGUgZXhpc3RpbmcgKHR5cGljYWxseSBzZXNzaW9uKSBzZXR0aW5ncy4KKyAgICogICBAcGFyYW0gc2V0dGluZ3MgbmV3IHNldHRpbmdzLCBtYXkgYmUgbnVsbCB3aGljaCB3aWxsCisgICAqICAgcmV0dXJuIGNsb25lIG9mIGV4aXN0aW5nIHNldHRpbmdzLgorICAgKi8KKyAgcHJvdGVjdGVkIERvY3VtZW50QnVpbGRlclNldHRpbmdbXSBtZXJnZVNldHRpbmdzKERvY3VtZW50QnVpbGRlclNldHRpbmdbXQorICAgICAgbmV3U2V0dGluZ3MpIHsKKyAgICBpZiAobmV3U2V0dGluZ3MgPT0gbnVsbCkgeworICAgICAgcmV0dXJuIChEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10pIHNldHRpbmdzLmNsb25lKCk7CisgICAgfQorICAgIExpc3QgbWVyZ2VkU2V0dGluZ3MgPSBuZXcgQXJyYXlMaXN0KHNldHRpbmdzLmxlbmd0aCArIG5ld1NldHRpbmdzLmxlbmd0aCk7CisgICAgLy8KKyAgICAvLyAgICBhbGwgbmV3IHNldHRpbmdzIGFyZSByZXNwZWN0ZWQKKyAgICAvLworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmV3U2V0dGluZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgIG1lcmdlZFNldHRpbmdzLmFkZChuZXdTZXR0aW5nc1tpXSk7CisgICAgfQorICAgIC8vCisgICAgLy8gICAgZm9yIGFsbCBwcmV2aW91cyBzZXR0aW5ncywgdGFrZSBvbmx5IHRob3NlIHRoYXQKKyAgICAvLyAgICAgICBkbyBub3QgY29uZmxpY3Qgd2l0aCBleGlzdGluZyBzZXR0aW5ncworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2V0dGluZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcgc2V0dGluZyA9IHNldHRpbmdzW2ldOworICAgICAgYm9vbGVhbiBoYXNDb25mbGljdCA9IGZhbHNlOworICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBuZXdTZXR0aW5ncy5sZW5ndGg7IGorKykgeworICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIG5ld1NldHRpbmcgPSBuZXdTZXR0aW5nc1tqXTsKKyAgICAgICAgaWYgKG5ld1NldHRpbmcuaGFzQ29uZmxpY3Qoc2V0dGluZykgfHwgc2V0dGluZy5oYXNDb25mbGljdChuZXdTZXR0aW5nKSkgeworICAgICAgICAgIGhhc0NvbmZsaWN0ID0gdHJ1ZTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgaWYgKCFoYXNDb25mbGljdCkgeworICAgICAgICBtZXJnZWRTZXR0aW5ncy5hZGQoc2V0dGluZyk7CisgICAgICB9CisgICAgfQorCisgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIG1lcmdlZEFycmF5ID0KKyAgICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmdbbWVyZ2VkU2V0dGluZ3Muc2l6ZSgpXTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG1lcmdlZFNldHRpbmdzLnNpemUoKTsgaSsrKSB7CisgICAgICBtZXJnZWRBcnJheVtpXSA9IChEb2N1bWVudEJ1aWxkZXJTZXR0aW5nKSBtZXJnZWRTZXR0aW5ncy5nZXQoaSk7CisgICAgfQorICAgIHJldHVybiBtZXJnZWRBcnJheTsKKyAgfQorCisgIHB1YmxpYyBTdHJpbmcgYWRkRXh0ZW5zaW9uKFN0cmluZyB0ZXN0RmlsZU5hbWUpIHsKKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIGlmICgidGV4dC9odG1sIi5lcXVhbHMoY29udGVudFR5cGUpKSB7CisgICAgICByZXR1cm4gdGVzdEZpbGVOYW1lICsgIi5odG1sIjsKKyAgICB9CisgICAgaWYgKCJpbWFnZS9zdmcreG1sIi5lcXVhbHMoY29udGVudFR5cGUpKSB7CisgICAgICByZXR1cm4gdGVzdEZpbGVOYW1lICsgIi5zdmciOworICAgIH0KKyAgICBpZiAoImFwcGxpY2F0aW9uL3hodG1sK3htbCIuZXF1YWxzKGNvbnRlbnRUeXBlKSkgeworICAgICAgcmV0dXJuIHRlc3RGaWxlTmFtZSArICIueGh0bWwiOworICAgIH0KKyAgICByZXR1cm4gdGVzdEZpbGVOYW1lICsgIi54bWwiOworICB9CisKKyAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNDb2FsZXNjaW5nKCk7CisKKyAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKCk7CisKKyAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNJZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSgpOworCisgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzTmFtZXNwYWNlQXdhcmUoKTsKKworICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc1ZhbGlkYXRpbmcoKTsKKworICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgeworICAgIHJldHVybiBTeXN0ZW0uZ2V0UHJvcGVydHkoIm9yZy53M2MuZG9tdHMuY29udGVudFR5cGUiLCAidGV4dC94bWwiKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIGFsbCBkZXRlcm1pbmFibGUgc2V0dGluZ3MgZm9yIHRoZSBEb2N1bWVudEJ1aWxkZXIKKyAgICogaW5jbHVkaW5nIHRob3NlIGF0IGltcGxlbWVudGF0aW9uIGRlZmF1bHRzLgorICAgKiBAcGFyYW0gYnVpbGRlciBtdXN0IG5vdCBiZSBudWxsCisgICAqLworICBwdWJsaWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIGdldEFjdHVhbFNldHRpbmdzKCkgeworCisgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIGFsbFNldHRpbmdzID0gbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcuY29hbGVzY2luZywKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5leHBhbmRFbnRpdHlSZWZlcmVuY2VzLAorICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLmhhc051bGxTdHJpbmcsCisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcuaWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UsCisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUsCisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcuc2lnbmVkLAorICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLnZhbGlkYXRpbmcsCisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcubm90Q29hbGVzY2luZywKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RFeHBhbmRFbnRpdHlSZWZlcmVuY2VzLAorICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5vdEhhc051bGxTdHJpbmcsCisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcubm90SWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UsCisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcubm90TmFtZXNwYWNlQXdhcmUsCisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcubm90U2lnbmVkLAorICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5vdFZhbGlkYXRpbmcKKyAgICB9OworCisgICAgTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdChhbGxTZXR0aW5ncy5sZW5ndGggLyAyKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsbFNldHRpbmdzLmxlbmd0aDsgaSsrKSB7CisgICAgICBpZiAoYWxsU2V0dGluZ3NbaV0uaGFzU2V0dGluZyh0aGlzKSkgeworICAgICAgICBsaXN0LmFkZChhbGxTZXR0aW5nc1tpXSk7CisgICAgICB9CisgICAgfQorICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW2xpc3Quc2l6ZSgpXTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHNldHRpbmdzLmxlbmd0aDsgaSsrKSB7CisgICAgICBzZXR0aW5nc1tpXSA9IChEb2N1bWVudEJ1aWxkZXJTZXR0aW5nKSBsaXN0LmdldChpKTsKKyAgICB9CisgICAgcmV0dXJuIHNldHRpbmdzOworICB9CisKK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvRE9NVGVzdEZyYW1ld29yay5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9ET01UZXN0RnJhbWV3b3JrLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzgzNmY0YgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvRE9NVGVzdEZyYW1ld29yay5qYXZhCkBAIC0wLDAgKzEsMTc3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzOworCitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CisKKy8qKgorICogICAgVGhpcyBpbnRlcmZhY2UgcHJvdmlkZXMgc2VydmljZXMgdHlwaWNhbGx5IHByb3ZpZGVkIGJ5IGEgdGVzdCBmcmFtZXdvcmsKKyAqLworcHVibGljIGludGVyZmFjZSBET01UZXN0RnJhbWV3b3JrIHsKKyAgYm9vbGVhbiBoYXNGZWF0dXJlKAorICAgICAgRG9jdW1lbnRCdWlsZGVyIGRvY0J1aWxkZXIsCisgICAgICBTdHJpbmcgZmVhdHVyZSwKKyAgICAgIFN0cmluZyB2ZXJzaW9uKTsKKworICB2b2lkIHdhaXQoaW50IG1pbGxpc2Vjb25kKTsKKworICB2b2lkIGZhaWwoRE9NVGVzdENhc2UgdGVzdCwgU3RyaW5nIGFzc2VydElEKTsKKworICB2b2lkIGFzc2VydFRydWUoRE9NVGVzdENhc2UgdGVzdCwgU3RyaW5nIGFzc2VydElELCBib29sZWFuIGFjdHVhbCk7CisKKyAgdm9pZCBhc3NlcnRGYWxzZShET01UZXN0Q2FzZSB0ZXN0LCBTdHJpbmcgYXNzZXJ0SUQsIGJvb2xlYW4gYWN0dWFsKTsKKworICB2b2lkIGFzc2VydE51bGwoRE9NVGVzdENhc2UgdGVzdCwgU3RyaW5nIGFzc2VydElELCBPYmplY3QgYWN0dWFsKTsKKworICB2b2lkIGFzc2VydE5vdE51bGwoRE9NVGVzdENhc2UgdGVzdCwgU3RyaW5nIGFzc2VydElELCBPYmplY3QgYWN0dWFsKTsKKworICB2b2lkIGFzc2VydFNhbWUoCisgICAgICBET01UZXN0Q2FzZSB0ZXN0LAorICAgICAgU3RyaW5nIGFzc2VydElELAorICAgICAgT2JqZWN0IGV4cGVjdGVkLAorICAgICAgT2JqZWN0IGFjdHVhbCk7CisKKyAgdm9pZCBhc3NlcnRJbnN0YW5jZU9mKAorICAgICAgRE9NVGVzdENhc2UgdGVzdCwKKyAgICAgIFN0cmluZyBhc3NlcnRJRCwKKyAgICAgIE9iamVjdCBvYmosCisgICAgICBDbGFzcyBjbHMpOworCisgIHZvaWQgYXNzZXJ0U2l6ZSgKKyAgICAgIERPTVRlc3RDYXNlIHRlc3QsCisgICAgICBTdHJpbmcgYXNzZXJ0SUQsCisgICAgICBpbnQgZXhwZWN0ZWRTaXplLAorICAgICAgTm9kZUxpc3QgY29sbGVjdGlvbik7CisKKyAgdm9pZCBhc3NlcnRTaXplKAorICAgICAgRE9NVGVzdENhc2UgdGVzdCwKKyAgICAgIFN0cmluZyBhc3NlcnRJRCwKKyAgICAgIGludCBleHBlY3RlZFNpemUsCisgICAgICBOYW1lZE5vZGVNYXAgY29sbGVjdGlvbik7CisKKyAgdm9pZCBhc3NlcnRTaXplKAorICAgICAgRE9NVGVzdENhc2UgdGVzdCwKKyAgICAgIFN0cmluZyBhc3NlcnRJRCwKKyAgICAgIGludCBleHBlY3RlZFNpemUsCisgICAgICBDb2xsZWN0aW9uIGNvbGxlY3Rpb24pOworCisgIHZvaWQgYXNzZXJ0RXF1YWxzSWdub3JlQ2FzZSgKKyAgICAgIERPTVRlc3RDYXNlIHRlc3QsCisgICAgICBTdHJpbmcgYXNzZXJ0SUQsCisgICAgICBTdHJpbmcgZXhwZWN0ZWQsCisgICAgICBTdHJpbmcgYWN0dWFsKTsKKworICB2b2lkIGFzc2VydEVxdWFsc0lnbm9yZUNhc2UoCisgICAgICBET01UZXN0Q2FzZSB0ZXN0LAorICAgICAgU3RyaW5nIGFzc2VydElELAorICAgICAgQ29sbGVjdGlvbiBleHBlY3RlZCwKKyAgICAgIENvbGxlY3Rpb24gYWN0dWFsKTsKKworICB2b2lkIGFzc2VydEVxdWFsc0lnbm9yZUNhc2UoCisgICAgICBET01UZXN0Q2FzZSB0ZXN0LAorICAgICAgU3RyaW5nIGFzc2VydElELAorICAgICAgTGlzdCBleHBlY3RlZCwKKyAgICAgIExpc3QgYWN0dWFsKTsKKworICB2b2lkIGFzc2VydEVxdWFscygKKyAgICAgIERPTVRlc3RDYXNlIHRlc3QsCisgICAgICBTdHJpbmcgYXNzZXJ0SUQsCisgICAgICBTdHJpbmcgZXhwZWN0ZWQsCisgICAgICBTdHJpbmcgYWN0dWFsKTsKKworICB2b2lkIGFzc2VydEVxdWFscygKKyAgICAgIERPTVRlc3RDYXNlIHRlc3QsCisgICAgICBTdHJpbmcgYXNzZXJ0SUQsCisgICAgICBpbnQgZXhwZWN0ZWQsCisgICAgICBpbnQgYWN0dWFsKTsKKworICB2b2lkIGFzc2VydEVxdWFscygKKyAgICAgIERPTVRlc3RDYXNlIHRlc3QsCisgICAgICBTdHJpbmcgYXNzZXJ0SUQsCisgICAgICBib29sZWFuIGV4cGVjdGVkLAorICAgICAgYm9vbGVhbiBhY3R1YWwpOworCisgIHZvaWQgYXNzZXJ0RXF1YWxzKAorICAgICAgRE9NVGVzdENhc2UgdGVzdCwKKyAgICAgIFN0cmluZyBhc3NlcnRJRCwKKyAgICAgIGRvdWJsZSBleHBlY3RlZCwKKyAgICAgIGRvdWJsZSBhY3R1YWwpOworCisgIHZvaWQgYXNzZXJ0RXF1YWxzKAorICAgICAgRE9NVGVzdENhc2UgdGVzdCwKKyAgICAgIFN0cmluZyBhc3NlcnRJRCwKKyAgICAgIENvbGxlY3Rpb24gZXhwZWN0ZWQsCisgICAgICBDb2xsZWN0aW9uIGFjdHVhbCk7CisKKyAgdm9pZCBhc3NlcnROb3RFcXVhbHNJZ25vcmVDYXNlKAorICAgICAgRE9NVGVzdENhc2UgdGVzdCwKKyAgICAgIFN0cmluZyBhc3NlcnRJRCwKKyAgICAgIFN0cmluZyBleHBlY3RlZCwKKyAgICAgIFN0cmluZyBhY3R1YWwpOworCisgIHZvaWQgYXNzZXJ0Tm90RXF1YWxzKAorICAgICAgRE9NVGVzdENhc2UgdGVzdCwKKyAgICAgIFN0cmluZyBhc3NlcnRJRCwKKyAgICAgIFN0cmluZyBleHBlY3RlZCwKKyAgICAgIFN0cmluZyBhY3R1YWwpOworCisgIHZvaWQgYXNzZXJ0Tm90RXF1YWxzKAorICAgICAgRE9NVGVzdENhc2UgdGVzdCwKKyAgICAgIFN0cmluZyBhc3NlcnRJRCwKKyAgICAgIGludCBleHBlY3RlZCwKKyAgICAgIGludCBhY3R1YWwpOworCisgIHZvaWQgYXNzZXJ0Tm90RXF1YWxzKAorICAgICAgRE9NVGVzdENhc2UgdGVzdCwKKyAgICAgIFN0cmluZyBhc3NlcnRJRCwKKyAgICAgIGJvb2xlYW4gZXhwZWN0ZWQsCisgICAgICBib29sZWFuIGFjdHVhbCk7CisKKyAgdm9pZCBhc3NlcnROb3RFcXVhbHMoCisgICAgICBET01UZXN0Q2FzZSB0ZXN0LAorICAgICAgU3RyaW5nIGFzc2VydElELAorICAgICAgZG91YmxlIGV4cGVjdGVkLAorICAgICAgZG91YmxlIGFjdHVhbCk7CisKKyAgYm9vbGVhbiBzYW1lKE9iamVjdCBleHBlY3RlZCwgT2JqZWN0IGFjdHVhbCk7CisKKyAgYm9vbGVhbiBlcXVhbHNJZ25vcmVDYXNlKFN0cmluZyBleHBlY3RlZCwgU3RyaW5nIGFjdHVhbCk7CisKKyAgYm9vbGVhbiBlcXVhbHNJZ25vcmVDYXNlKENvbGxlY3Rpb24gZXhwZWN0ZWQsIENvbGxlY3Rpb24gYWN0dWFsKTsKKworICBib29sZWFuIGVxdWFsc0lnbm9yZUNhc2UoTGlzdCBleHBlY3RlZCwgTGlzdCBhY3R1YWwpOworCisgIGJvb2xlYW4gZXF1YWxzKFN0cmluZyBleHBlY3RlZCwgU3RyaW5nIGFjdHVhbCk7CisKKyAgYm9vbGVhbiBlcXVhbHMoaW50IGV4cGVjdGVkLCBpbnQgYWN0dWFsKTsKKworICBib29sZWFuIGVxdWFscyhib29sZWFuIGV4cGVjdGVkLCBib29sZWFuIGFjdHVhbCk7CisKKyAgYm9vbGVhbiBlcXVhbHMoZG91YmxlIGV4cGVjdGVkLCBkb3VibGUgYWN0dWFsKTsKKworICBib29sZWFuIGVxdWFscyhDb2xsZWN0aW9uIGV4cGVjdGVkLCBDb2xsZWN0aW9uIGFjdHVhbCk7CisKKyAgYm9vbGVhbiBlcXVhbHMoTGlzdCBleHBlY3RlZCwgTGlzdCBhY3R1YWwpOworCisgIGludCBzaXplKENvbGxlY3Rpb24gY29sbGVjdGlvbik7CisKKyAgaW50IHNpemUoTmFtZWROb2RlTWFwIGNvbGxlY3Rpb24pOworCisgIGludCBzaXplKE5vZGVMaXN0IGNvbGxlY3Rpb24pOworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0RPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYTFjMGUwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw3NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzOworCisKKy8qKgorICogVGhpcyBleGNlcHRpb24gcmVwcmVzZW50cyBhIG1pc21hdGNoIGJldHdlZW4gdGhlCisgKiByZXF1aXJlbWVudHMgb2YgdGhlIHRlc3QgKGZvciBleGFtcGxlLCBlbnRpdHkgcHJlc2VydmluZykKKyAqIGFuZCB0aGUgY2FwYWJpbGl0aWVzIG9mIHRoZSBwYXJzZXIgdW5kZXIgdGVzdC4KKyAqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyAqLworcHVibGljIGNsYXNzIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24KKyAgICBleHRlbmRzIEV4Y2VwdGlvbiB7CisgIHByaXZhdGUgZmluYWwgU3RyaW5nIG1zZzsKKworICBwcml2YXRlIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24oU3RyaW5nIG1zZykgeworICAgIHRoaXMubXNnID0gbXNnOworICB9CisKKyAgLyoqCisgICAqICBDb25zdHJ1Y3RvciBmcm9tIGEgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgorICAgKiAgb3IgcmVmbGVjdGlvbiBleGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uKFRocm93YWJsZSBleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZyBzZXR0aW5nKSB7CisgICAgaWYgKGV4ICE9IG51bGwpIHsKKyAgICAgIG1zZyA9IGV4LnRvU3RyaW5nKCk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgaWYgKHNldHRpbmcgIT0gbnVsbCkgeworICAgICAgICBtc2cgPSBzZXR0aW5nLnRvU3RyaW5nKCk7CisgICAgICB9CisgICAgICBlbHNlIHsKKyAgICAgICAgbXNnID0gc3VwZXIudG9TdHJpbmcoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBwdWJsaWMgc3RhdGljIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gaW5jb21wYXRpYmxlRmVhdHVyZShTdHJpbmcgZmVhdHVyZSwKKyAgICAgIFN0cmluZyB2ZXJzaW9uKSB7CisgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoCisgICAgICAgICJJbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IGZlYXR1cmUgXCIiKTsKKyAgICBidWYuYXBwZW5kKGZlYXR1cmUpOworICAgIGJ1Zi5hcHBlbmQoIlwiIHZlcnNpb249XCIiKTsKKyAgICBidWYuYXBwZW5kKHZlcnNpb24pOworICAgIGJ1Zi5hcHBlbmQoIlwiLiIpOworICAgIHJldHVybiBuZXcgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbihidWYudG9TdHJpbmcoKSk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gaW5jb21wYXRpYmxlTG9hZChTdHJpbmcgaHJlZiwKKyAgICAgIFN0cmluZyBjb250ZW50VHlwZSkgeworICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKAorICAgICAgICAiRG9jdW1lbnQgaXMgaW5jb21wYXRpYmxlIHdpdGggY29udGVudCB0eXBlLCBcIiIpOworICAgIGJ1Zi5hcHBlbmQoaHJlZik7CisgICAgYnVmLmFwcGVuZCgiXCIgbm90IGF2YWlsYWJsZSBmb3IgPVwiIik7CisgICAgYnVmLmFwcGVuZChjb250ZW50VHlwZSk7CisgICAgYnVmLmFwcGVuZCgiXCIuIik7CisgICAgcmV0dXJuIG5ldyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uKGJ1Zi50b1N0cmluZygpKTsKKyAgfQorCisgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgcmV0dXJuIG1zZzsKKyAgfQorCit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0RPTVRlc3RJbm5lckNsYXNzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0RPTVRlc3RJbm5lckNsYXNzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmM5ZDliYQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvRE9NVGVzdElubmVyQ2xhc3MuamF2YQpAQCAtMCwwICsxLDE5MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210czsKKworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCitpbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247CitpbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworCisvKioKKyAqICAgIFRoaXMgY2xhc3MgcHJvdmlkZXMgYWNjZXNzIHRvIERPTVRlc3RDYXNlIG1ldGhvZHMgKGxpa2UKKyAqICAgICAgIGFzc2VydEVxdWFscykgZm9yIGlubmVyIGNsYXNzZXMKKyAqLworcHVibGljIGNsYXNzIERPTVRlc3RJbm5lckNsYXNzIHsKKyAgcHJpdmF0ZSBmaW5hbCBET01UZXN0Q2FzZSB0ZXN0OworCisgIHB1YmxpYyBET01UZXN0SW5uZXJDbGFzcyhET01UZXN0Q2FzZSB0ZXN0KSB7CisgICAgdGhpcy50ZXN0ID0gdGVzdDsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHdhaXQoaW50IG1pbGxpc2Vjb25kKSB7CisgICAgdGVzdC53YWl0KG1pbGxpc2Vjb25kKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGFzc2VydFRydWUoU3RyaW5nIGFzc2VydElELCBib29sZWFuIGFjdHVhbCkgeworICAgIHRlc3QuYXNzZXJ0VHJ1ZShhc3NlcnRJRCwgYWN0dWFsKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGFzc2VydEZhbHNlKFN0cmluZyBhc3NlcnRJRCwgYm9vbGVhbiBhY3R1YWwpIHsKKyAgICB0ZXN0LmFzc2VydEZhbHNlKGFzc2VydElELCBhY3R1YWwpOworICB9CisKKyAgcHVibGljIHZvaWQgYXNzZXJ0TnVsbChTdHJpbmcgYXNzZXJ0SUQsIE9iamVjdCBhY3R1YWwpIHsKKyAgICB0ZXN0LmFzc2VydE51bGwoYXNzZXJ0SUQsIGFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnROb3ROdWxsKFN0cmluZyBhc3NlcnRJRCwgT2JqZWN0IGFjdHVhbCkgeworICAgIHRlc3QuYXNzZXJ0Tm90TnVsbChhc3NlcnRJRCwgYWN0dWFsKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGFzc2VydFNhbWUoU3RyaW5nIGFzc2VydElELCBPYmplY3QgZXhwZWN0ZWQsIE9iamVjdCBhY3R1YWwpIHsKKyAgICB0ZXN0LmFzc2VydFNhbWUoYXNzZXJ0SUQsIGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgcHVibGljIHZvaWQgYXNzZXJ0SW5zdGFuY2VPZihTdHJpbmcgYXNzZXJ0SUQsIENsYXNzIGNscywgT2JqZWN0IG9iaikgeworICAgIHRlc3QuYXNzZXJ0SW5zdGFuY2VPZihhc3NlcnRJRCwgY2xzLCBvYmopOworICB9CisKKyAgcHVibGljIHZvaWQgYXNzZXJ0U2l6ZShTdHJpbmcgYXNzZXJ0SUQsIGludCBleHBlY3RlZFNpemUsIE5vZGVMaXN0IGNvbGxlY3Rpb24pIHsKKyAgICB0ZXN0LmFzc2VydFNpemUoYXNzZXJ0SUQsIGV4cGVjdGVkU2l6ZSwgY29sbGVjdGlvbik7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnRTaXplKFN0cmluZyBhc3NlcnRJRCwgaW50IGV4cGVjdGVkU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lZE5vZGVNYXAgY29sbGVjdGlvbikgeworICAgIHRlc3QuYXNzZXJ0U2l6ZShhc3NlcnRJRCwgZXhwZWN0ZWRTaXplLCBjb2xsZWN0aW9uKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGFzc2VydFNpemUoU3RyaW5nIGFzc2VydElELCBpbnQgZXhwZWN0ZWRTaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb24gY29sbGVjdGlvbikgeworICAgIHRlc3QuYXNzZXJ0U2l6ZShhc3NlcnRJRCwgZXhwZWN0ZWRTaXplLCBjb2xsZWN0aW9uKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFsc0lnbm9yZUNhc2UoU3RyaW5nIGFzc2VydElELCBTdHJpbmcgZXhwZWN0ZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGFjdHVhbCkgeworICAgIHRlc3QuYXNzZXJ0RXF1YWxzSWdub3JlQ2FzZShhc3NlcnRJRCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHNJZ25vcmVDYXNlKFN0cmluZyBhc3NlcnRJRCwgQ29sbGVjdGlvbiBleHBlY3RlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsZWN0aW9uIGFjdHVhbCkgeworICAgIHRlc3QuYXNzZXJ0RXF1YWxzSWdub3JlQ2FzZShhc3NlcnRJRCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHNJZ25vcmVDYXNlKFN0cmluZyBhc3NlcnRJRCwgTGlzdCBleHBlY3RlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0IGFjdHVhbCkgeworICAgIHRlc3QuYXNzZXJ0RXF1YWxzSWdub3JlQ2FzZShhc3NlcnRJRCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIGFzc2VydElELCBTdHJpbmcgZXhwZWN0ZWQsIFN0cmluZyBhY3R1YWwpIHsKKyAgICB0ZXN0LmFzc2VydEVxdWFscyhhc3NlcnRJRCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIGFzc2VydElELCBpbnQgZXhwZWN0ZWQsIGludCBhY3R1YWwpIHsKKyAgICB0ZXN0LmFzc2VydEVxdWFscyhhc3NlcnRJRCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIGFzc2VydElELCBkb3VibGUgZXhwZWN0ZWQsIGRvdWJsZSBhY3R1YWwpIHsKKyAgICB0ZXN0LmFzc2VydEVxdWFscyhhc3NlcnRJRCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIGFzc2VydElELCBib29sZWFuIGV4cGVjdGVkLCBib29sZWFuIGFjdHVhbCkgeworICAgIHRlc3QuYXNzZXJ0RXF1YWxzKGFzc2VydElELCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFscyhTdHJpbmcgYXNzZXJ0SUQsIENvbGxlY3Rpb24gZXhwZWN0ZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlTGlzdCBhY3R1YWwpIHsKKyAgICB0ZXN0LmFzc2VydEVxdWFscyhhc3NlcnRJRCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIGFzc2VydElELCBDb2xsZWN0aW9uIGV4cGVjdGVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGVjdGlvbiBhY3R1YWwpIHsKKyAgICB0ZXN0LmFzc2VydEVxdWFscyhhc3NlcnRJRCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnROb3RFcXVhbHNJZ25vcmVDYXNlKFN0cmluZyBhc3NlcnRJRCwgU3RyaW5nIGV4cGVjdGVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhY3R1YWwpIHsKKyAgICB0ZXN0LmFzc2VydE5vdEVxdWFsc0lnbm9yZUNhc2UoYXNzZXJ0SUQsIGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgcHVibGljIHZvaWQgYXNzZXJ0Tm90RXF1YWxzKFN0cmluZyBhc3NlcnRJRCwgU3RyaW5nIGV4cGVjdGVkLCBTdHJpbmcgYWN0dWFsKSB7CisgICAgdGVzdC5hc3NlcnROb3RFcXVhbHMoYXNzZXJ0SUQsIGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgcHVibGljIHZvaWQgYXNzZXJ0Tm90RXF1YWxzKFN0cmluZyBhc3NlcnRJRCwgaW50IGV4cGVjdGVkLCBpbnQgYWN0dWFsKSB7CisgICAgdGVzdC5hc3NlcnROb3RFcXVhbHMoYXNzZXJ0SUQsIGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgcHVibGljIHZvaWQgYXNzZXJ0Tm90RXF1YWxzKFN0cmluZyBhc3NlcnRJRCwgZG91YmxlIGV4cGVjdGVkLCBkb3VibGUgYWN0dWFsKSB7CisgICAgdGVzdC5hc3NlcnROb3RFcXVhbHMoYXNzZXJ0SUQsIGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgcHVibGljIHZvaWQgYXNzZXJ0VVJJRXF1YWxzKFN0cmluZyBhc3NlcnRJRCwgU3RyaW5nIHNjaGVtZSwgU3RyaW5nIHBhdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgaG9zdCwgU3RyaW5nIGZpbGUsIFN0cmluZyBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5LCBTdHJpbmcgZnJhZ21lbnQsIEJvb2xlYW4gaXNBYnNvbHV0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhY3R1YWwpIHsKKyAgICB0ZXN0LmFzc2VydFVSSUVxdWFscyhhc3NlcnRJRCwgc2NoZW1lLCBwYXRoLCBob3N0LCBmaWxlLCBuYW1lLCBxdWVyeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBmcmFnbWVudCwgaXNBYnNvbHV0ZSwgYWN0dWFsKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIHNhbWUoT2JqZWN0IGV4cGVjdGVkLCBPYmplY3QgYWN0dWFsKSB7CisgICAgcmV0dXJuIHRlc3Quc2FtZShleHBlY3RlZCwgYWN0dWFsKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGVxdWFsc0lnbm9yZUNhc2UoU3RyaW5nIGV4cGVjdGVkLCBTdHJpbmcgYWN0dWFsKSB7CisgICAgcmV0dXJuIHRlc3QuZXF1YWxzSWdub3JlQ2FzZShleHBlY3RlZCwgYWN0dWFsKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGVxdWFsc0lnbm9yZUNhc2UoQ29sbGVjdGlvbiBleHBlY3RlZCwgQ29sbGVjdGlvbiBhY3R1YWwpIHsKKyAgICByZXR1cm4gdGVzdC5lcXVhbHNJZ25vcmVDYXNlKGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzSWdub3JlQ2FzZShMaXN0IGV4cGVjdGVkLCBMaXN0IGFjdHVhbCkgeworICAgIHJldHVybiB0ZXN0LmVxdWFsc0lnbm9yZUNhc2UoZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoU3RyaW5nIGV4cGVjdGVkLCBTdHJpbmcgYWN0dWFsKSB7CisgICAgcmV0dXJuIHRlc3QuZXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGludCBleHBlY3RlZCwgaW50IGFjdHVhbCkgeworICAgIHJldHVybiB0ZXN0LmVxdWFscyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhkb3VibGUgZXhwZWN0ZWQsIGRvdWJsZSBhY3R1YWwpIHsKKyAgICByZXR1cm4gdGVzdC5lcXVhbHMoZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoQ29sbGVjdGlvbiBleHBlY3RlZCwgQ29sbGVjdGlvbiBhY3R1YWwpIHsKKyAgICByZXR1cm4gdGVzdC5lcXVhbHMoZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoTGlzdCBleHBlY3RlZCwgTGlzdCBhY3R1YWwpIHsKKyAgICByZXR1cm4gdGVzdC5lcXVhbHMoZXhwZWN0ZWQsIGFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgaW50IHNpemUoQ29sbGVjdGlvbiBjb2xsZWN0aW9uKSB7CisgICAgcmV0dXJuIHRlc3Quc2l6ZShjb2xsZWN0aW9uKTsKKyAgfQorCisgIHB1YmxpYyBpbnQgc2l6ZShOYW1lZE5vZGVNYXAgY29sbGVjdGlvbikgeworICAgIHJldHVybiB0ZXN0LnNpemUoY29sbGVjdGlvbik7CisgIH0KKworICBwdWJsaWMgaW50IHNpemUoTm9kZUxpc3QgY29sbGVjdGlvbikgeworICAgIHJldHVybiB0ZXN0LnNpemUoY29sbGVjdGlvbik7CisgIH0KKworICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb24gZ2V0SW1wbGVtZW50YXRpb24oKSB7CisgICAgcmV0dXJuIHRlc3QuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgfQorCit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0RPTVRlc3RMb2FkRXhjZXB0aW9uLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0RPTVRlc3RMb2FkRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2QzMjBiYQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvRE9NVGVzdExvYWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzOworCisKKy8qKgorICogRW5jYXBzdWxhdGVzIGEgY29uY3JldGUgbG9hZCBleGNlcHRpb24gc3VjaCBhcworICogYSBTQVggZXhjZXB0aW9uCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKiBAZGF0ZSAyIEZlYiAyMDAyCisgKi8KK3B1YmxpYyBjbGFzcyBET01UZXN0TG9hZEV4Y2VwdGlvbgorICAgIGV4dGVuZHMgRXhjZXB0aW9uIHsKKyAgcHJpdmF0ZSBmaW5hbCBUaHJvd2FibGUgaW5uZXJFeGNlcHRpb247CisKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yCisgICAqIEBwYXJhbSBpbm5lckV4Y2VwdGlvbiBzaG91bGQgbm90IGJlIG51bGwKKyAgICovCisgIHB1YmxpYyBET01UZXN0TG9hZEV4Y2VwdGlvbihUaHJvd2FibGUgaW5uZXJFeGNlcHRpb24pIHsKKyAgICB0aGlzLmlubmVyRXhjZXB0aW9uID0gaW5uZXJFeGNlcHRpb247CisgIH0KKworICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIGlmIChpbm5lckV4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICByZXR1cm4gaW5uZXJFeGNlcHRpb24udG9TdHJpbmcoKTsKKyAgICB9CisgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvRE9NVGVzdFNpbmsuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvRE9NVGVzdFNpbmsuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YzY0MWE3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9ET01UZXN0U2luay5qYXZhCkBAIC0wLDAgKzEsMjcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCisvKgorICAkTG9nOiBET01UZXN0U2luay5qYXZhLHYgJAorICBSZXZpc2lvbiAxLjIgIDIwMDQvMDMvMTEgMDE6NDQ6MjEgIGRvbS10cy00CisgIENoZWNrc3R5bGUgZml4ZXMgKGJ1ZyA1OTIpCisKKyAgUmV2aXNpb24gMS4xICAyMDAxLzA3LzIzIDA0OjUyOjIwICBkb20tdHMtNAorICBJbml0aWFsIHRlc3QgcnVubmluZyB1c2luZyBKVW5pdC4KKworICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210czsKKworcHVibGljIGludGVyZmFjZSBET01UZXN0U2luayB7CisgIHB1YmxpYyB2b2lkIGFkZFRlc3QoQ2xhc3MgdGVzdCk7Cit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0RPTVRlc3RTdWl0ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9ET01UZXN0U3VpdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NGE3NmI4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9ET01UZXN0U3VpdGUuamF2YQpAQCAtMCwwICsxLDYyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworLyoKKyAgJExvZzogRE9NVGVzdFN1aXRlLmphdmEsdiAkCisgIFJldmlzaW9uIDEuNCAgMjAwNC8wMy8xMSAwMTo0NDoyMSAgZG9tLXRzLTQKKyAgQ2hlY2tzdHlsZSBmaXhlcyAoYnVnIDU5MikKKworICBSZXZpc2lvbiAxLjMgIDIwMDIvMDIvMDMgMDQ6MjI6MzUgIGRvbS10cy00CisgIERPTTRKIGFuZCBCYXRpayBzdXBwb3J0IGFkZGVkLgorICBSZXdvcmsgb2YgcGFyc2VyIHNldHRpbmdzCisKKyAgUmV2aXNpb24gMS4yICAyMDAxLzA3LzIzIDA0OjUyOjIwICBkb20tdHMtNAorICBJbml0aWFsIHRlc3QgcnVubmluZyB1c2luZyBKVW5pdC4KKworICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210czsKKworLyoqCisgKiBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBhbGwgdGVzdCBzdWl0ZXMKKyAqICh0aGF0IGlzIGFueSBjb2xsZWN0aW9uIG9mIERPTVRlc3QncykKKyAqCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBET01UZXN0U3VpdGUKKyAgICBleHRlbmRzIERPTVRlc3QgeworICAvKioKKyAgICogVGhpcyBjb25zdHJ1Y3RvciBpcyB1c2VkIGZvciBzdWl0ZXMgdGhhdAorICAgKiBhc3NlcnQgb25lIG9yIG1vcmUgaW1wbGVtZW50YXRpb24gYXR0cmlidXRlcyBvcgorICAgKiBmZWF0dXJlcy4gIHNldExpYnJhcnkgc2hvdWxkIGJlIGNhbGxlZCBiZWZvcmUKKyAgICogdGhlIGNvbXBsZXRpb24gb2YgdGhlIGNvbnN0cnVjdG9yIGluIHRoZSBkZXJpdmVkIGNsYXNzLgorICAgKi8KKyAgcHJvdGVjdGVkIERPTVRlc3RTdWl0ZSgpIHsKKyAgfQorCisgIC8qKgorICAgKiBUaGlzIGNvbnN0cnVjdG9yIGlzIHVzZWQgZm9yIHN1aXRlcyB0aGF0IG1ha2Ugbm8KKyAgICogYWRkaXRpb25hbCByZXF1aXJlbWVudHMgb24gdGhlIHBhcnNlciBjb25maWd1cmF0aW9uLgorICAgKiBAcGFyYW0gZmFjdG9yeSBtYXkgbm90IGJlIG51bGwKKyAgICovCisgIHByb3RlY3RlZCBET01UZXN0U3VpdGUoRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgeworICAgIHN1cGVyKGZhY3RvcnkpOworICB9CisKKyAgLyoqCisgICAqIEFkZHMgYSB0ZXN0IHRvIHRoZSB0ZXN0IHN1aXRlLiAgVGhpcyBtZXRob2QgY2FuCisgICAqIG9ubHkgYmUgcnVuIGFmdGVyIHRoZSB0ZXN0IHN1aXRlIGhhcyBiZWVuIGF0dGFjaGVkCisgICAqIHRvIGEgdGVzdCBmcmFtZXdvcmsgc2luY2UgZWFjaCBmcmFtZXdvcmsgaW1wbGVtZW50cworICAgKiB0ZXN0IHN1aXRlcyBpbiBkaWZmZXJlbnQgbWFubmVycy4KKyAgICovCisgIGFic3RyYWN0IHB1YmxpYyB2b2lkIGJ1aWxkKERPTVRlc3RTaW5rIHNpbmspOworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0RvY3VtZW50QnVpbGRlclNldHRpbmcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YWFmNjUyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLmphdmEKQEAgLTAsMCArMSwyODIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUKKyAqIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4KKyAqIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZSBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcworICogcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKKyAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKKyAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlCisgKiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210czsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBhbiBwYXJzZXIgc2V0dGluZywgc3VjaCBhcyBub24tdmFsaWRhdGluZyBvciBlbnRpdHktZXhwYW5kaW5nLgorICoKKyAqIEBhdXRob3IgQ3VydCBBcm5vbGQgQGRhdGUgMiBGZWIgMjAwMgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRG9jdW1lbnRCdWlsZGVyU2V0dGluZyB7CisgIC8qKgorICAgKiBwcm9wZXJ0eSBuYW1lLgorICAgKi8KKyAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcHJvcGVydHk7CisKKyAgLyoqCisgICAqICAgcHJvcGVydHkgdmFsdWUuCisgICAqLworICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gdmFsdWU7CisKKyAgLyoqCisgICAqIHN0cmF0ZWd5IHVzZWQgdG8gc2V0IG9yIGdldCBwcm9wZXJ0eSB2YWx1ZS4KKyAgICovCisgIHByaXZhdGUgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5IHN0cmF0ZWd5OworCisgIC8qKgorICAgKiBjb2FsZXNjaW5nID0gdHJ1ZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZyBjb2FsZXNjaW5nID0KKyAgICAgIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nKAorICAgICAgImNvYWxlc2NpbmciLAorICAgICAgdHJ1ZSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneS5jb2FsZXNjaW5nKTsKKworICAvKioKKyAgICogY29hbGVzY2luZyA9IGZhbHNlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIG5vdENvYWxlc2NpbmcgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICAiY29hbGVzY2luZyIsCisgICAgICBmYWxzZSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneS5jb2FsZXNjaW5nKTsKKworICAvKioKKyAgICogZXhwYW5kRW50aXR5UmVmZXJlbmNlcyA9IGZhbHNlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIGV4cGFuZEVudGl0eVJlZmVyZW5jZXMgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICAiZXhwYW5kRW50aXR5UmVmZXJlbmNlcyIsCisgICAgICB0cnVlLAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5LmV4cGFuZEVudGl0eVJlZmVyZW5jZXMpOworCisgIC8qKgorICAgKiBleHBhbmRFbnRpdHlSZWZlcmVuY2VzID0gdHJ1ZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZyBub3RFeHBhbmRFbnRpdHlSZWZlcmVuY2VzID0KKyAgICAgIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nKAorICAgICAgImV4cGFuZEVudGl0eVJlZmVyZW5jZXMiLAorICAgICAgZmFsc2UsCisgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kuZXhwYW5kRW50aXR5UmVmZXJlbmNlcyk7CisKKyAgLyoqCisgICAqIGlnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlID0gdHJ1ZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZyBpZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSA9CisgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZygKKyAgICAgICJpZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSIsCisgICAgICB0cnVlLAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5Lmlnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKTsKKworICAvKioKKyAgICogaWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UgPSBmYWxzZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZworICAgICAgbm90SWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICAiaWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UiLAorICAgICAgZmFsc2UsCisgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kuaWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UpOworCisgIC8qKgorICAgKiBuYW1lc3BhY2VBd2FyZSA9IHRydWUuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmcgbmFtZXNwYWNlQXdhcmUgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICAibmFtZXNwYWNlQXdhcmUiLAorICAgICAgdHJ1ZSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneS5uYW1lc3BhY2VBd2FyZSk7CisKKyAgLyoqCisgICAqIG5hbWVzcGFjZUF3YXJlID0gZmFsc2UuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmcgbm90TmFtZXNwYWNlQXdhcmUgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICAibmFtZXNwYWNlQXdhcmUiLAorICAgICAgZmFsc2UsCisgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kubmFtZXNwYWNlQXdhcmUpOworCisgIC8qKgorICAgKiB2YWxpZGF0aW5nID0gdHJ1ZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZyB2YWxpZGF0aW5nID0KKyAgICAgIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nKAorICAgICAgInZhbGlkYXRpbmciLAorICAgICAgdHJ1ZSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneS52YWxpZGF0aW5nKTsKKworICAvKioKKyAgICogdmFsaWRhdGluZyA9IGZhbHNlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIG5vdFZhbGlkYXRpbmcgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICAidmFsaWRhdGluZyIsCisgICAgICBmYWxzZSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneS52YWxpZGF0aW5nKTsKKworICAvKioKKyAgICogc2lnbmVkID0gdHJ1ZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZyBzaWduZWQgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICAic2lnbmVkIiwKKyAgICAgIHRydWUsCisgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kuc2lnbmVkKTsKKworICAvKioKKyAgICogc2lnbmVkID0gZmFsc2UuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmcgbm90U2lnbmVkID0KKyAgICAgIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nKAorICAgICAgInNpZ25lZCIsCisgICAgICBmYWxzZSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneS5zaWduZWQpOworCisgIC8qKgorICAgKiBoYXNOdWxsU3RyaW5nID0gdHJ1ZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZyBoYXNOdWxsU3RyaW5nID0KKyAgICAgIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nKAorICAgICAgImhhc051bGxTdHJpbmciLAorICAgICAgdHJ1ZSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneS5oYXNOdWxsU3RyaW5nKTsKKworICAvKioKKyAgICogaGFzTnVsbFN0cmluZyA9IGZhbHNlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIG5vdEhhc051bGxTdHJpbmcgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICAiaGFzTnVsbFN0cmluZyIsCisgICAgICBmYWxzZSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneS5oYXNOdWxsU3RyaW5nKTsKKworICAvKioKKyAgICogU2NoZW1hIHZhbGlkYXRpbmcgZW5hYmxlZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZyBzY2hlbWFWYWxpZGF0aW5nID0KKyAgICAgIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nKAorICAgICAgInNjaGVtYVZhbGlkYXRpbmciLAorICAgICAgdHJ1ZSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneS5zY2hlbWFWYWxpZGF0aW5nKTsKKworICAvKioKKyAgICogU2NoZW1hIHZhbGlkYXRpbmcgZGlzYWJsZWQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmcgbm90U2NoZW1hVmFsaWRhdGluZyA9CisgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZygKKyAgICAgICJzY2hlbWFWYWxpZGF0aW5nIiwKKyAgICAgIGZhbHNlLAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5LnNjaGVtYVZhbGlkYXRpbmcpOworCisgIC8qKgorICAgKiBDb21tZW50cyBpZ25vcmVkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIGlnbm9yaW5nQ29tbWVudHMgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICAiaWdub3JpbmdDb21tZW50cyIsCisgICAgICB0cnVlLAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5Lmlnbm9yaW5nQ29tbWVudHMpOworCisgIC8qKgorICAgKiBDb21tZW50cyBwcmVzZXJ2ZWQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmcgbm90SWdub3JpbmdDb21tZW50cyA9CisgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZygKKyAgICAgICJpZ25vcmluZ0NvbW1lbnRzIiwKKyAgICAgIGZhbHNlLAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5Lmlnbm9yaW5nQ29tbWVudHMpOworCisgIC8qKgorICAgKiBQcm90ZWN0ZWQgY29uc3RydWN0b3IsIHVzZSBzdGF0aWMgbWVtYmVycyBmb3Igc3VwcG9ydGVkIHNldHRpbmdzLgorICAgKiBAcGFyYW0gcHJvcGVydHkgcHJvcGVydHkgbmFtZSwgZm9sbG93cyBKQVhQLgorICAgKiBAcGFyYW0gdmFsdWUgcHJvcGVydHkgdmFsdWUKKyAgICogQHBhcmFtIHN0cmF0ZWd5IHN0cmF0ZWd5LCBtYXkgbm90IGJlIG51bGwKKyAgICovCisgIHByb3RlY3RlZCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nKAorICAgICAgU3RyaW5nIHByb3BlcnR5LAorICAgICAgYm9vbGVhbiB2YWx1ZSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneSBzdHJhdGVneSkgeworICAgIGlmIChwcm9wZXJ0eSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInByb3BlcnR5Iik7CisgICAgfQorICAgIHRoaXMucHJvcGVydHkgPSBwcm9wZXJ0eTsKKyAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgdGhpcy5zdHJhdGVneSA9IHN0cmF0ZWd5OworICB9CisKKyAgLyoqCisgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc2V0dGluZ3MgaGF2ZSBhIGNvbmZsaWN0IG9yIGFyZSBpZGVudGljYWwuCisgICAqCisgICAqIEBwYXJhbSBvdGhlcgorICAgKiAgICAgICAgICAgIG90aGVyIHNldHRpbmcsIG1heSBub3QgYmUgbnVsbC4KKyAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgc2V0dGluZyBhbmQgdGhlIHNwZWNpZmllZCBzZXR0aW5nIGNvbmZsaWN0CisgICAqLworICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNDb25mbGljdChEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIG90aGVyKSB7CisgICAgaWYgKG90aGVyID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigib3RoZXIiKTsKKyAgICB9CisgICAgaWYgKG90aGVyID09IHRoaXMpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICByZXR1cm4gc3RyYXRlZ3kuaGFzQ29uZmxpY3Qob3RoZXIuc3RyYXRlZ3kpOworICB9CisKKyAgLyoqCisgICAqIERldGVybWluZXMgY3VycmVudCB2YWx1ZSBvZiBzZXR0aW5nLgorICAgKiBAcGFyYW0gZmFjdG9yeSBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5CisgICAqIEByZXR1cm4gYm9vbGVhbiB0cnVlIGlmIHByb3BlcnR5IGVuYWJsZWQuCisgICAqLworICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNTZXR0aW5nKERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpIHsKKyAgICByZXR1cm4gc3RyYXRlZ3kuaGFzU2V0dGluZyhmYWN0b3J5KSA9PSB2YWx1ZTsKKyAgfQorCisgIC8qKgorICAgKiBBdHRlbXB0cyB0byBjaGFuZ2UgYnVpbGRlciB0byBoYXZlIHRoaXMgc2V0dGluZy4KKyAgICogQHBhcmFtIGZhY3RvcnkgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBGYWN0b3J5IGZvciBET00gYnVpbGRlcnMKKyAgICogQHRocm93cyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uCisgICAqICAgICAgaWYgZmFjdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHRoZSBzZXR0aW5nCisgICAqLworICBwdWJsaWMgZmluYWwgdm9pZCBhcHBseVNldHRpbmcoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSB0aHJvd3MKKyAgICAgIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgIHN0cmF0ZWd5LmFwcGx5U2V0dGluZyhmYWN0b3J5LCB2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogR2V0cyB0aGUgcHJvcGVydHkgbmFtZS4KKyAgICogQHJldHVybiBwcm9wZXJ0eSBuYW1lCisgICAqLworICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldFByb3BlcnR5KCkgeworICAgIHJldHVybiBwcm9wZXJ0eTsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIHRoZSBwcm9wZXJ0eSB2YWx1ZS4KKyAgICogQHJldHVybiBwcm9wZXJ0eSB2YWx1ZQorICAgKi8KKyAgcHVibGljIGZpbmFsIGJvb2xlYW4gZ2V0VmFsdWUoKSB7CisgICAgcmV0dXJuIHZhbHVlOworICB9CisKKyAgLyoqCisgICAqIEdldHMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNldHRpbmcuCisgICAqIEByZXR1cm4gc3RyaW5nIHJlcHJlc2VudGF0aW9uCisgICAqLworICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIFN0cmluZ0J1ZmZlciBidWlsZGVyID0gbmV3IFN0cmluZ0J1ZmZlcihwcm9wZXJ0eSk7CisgICAgYnVpbGRlci5hcHBlbmQoJz0nKTsKKyAgICBidWlsZGVyLmFwcGVuZChTdHJpbmcudmFsdWVPZih2YWx1ZSkpOworICAgIHJldHVybiBidWlsZGVyLnRvU3RyaW5nKCk7CisgIH0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmRmMWE5MgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5LmphdmEKQEAgLTAsMCArMSwxOTkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YKKyAqIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4KKyAqIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZSBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcworICogcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKKyAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKKyAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlCisgKiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210czsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBhIHN0cmF0ZWd5IHRoYXQgcHJvdmlkZXMgdGhlIG1hcHBpbmcgZnJvbSBhbiBhYnN0cmFjdCBzZXR0aW5nCisgKiAoc3VjaCBhcyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLnZhbGlkYXRpbmcpIHRvIGEgc3BlY2lmaWMgRE9NIGltcGxlbWVudGF0aW9uCisgKgorICogQGF1dGhvciBDdXJ0IEFybm9sZCBAZGF0ZSAyIEZlYiAyMDAyCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kgeworICBwcm90ZWN0ZWQgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5KCkgeworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEpBWFBfU0NIRU1BX0xBTkdVQUdFID0KKyAgICAgICJodHRwOi8vamF2YS5zdW4uY29tL3htbC9qYXhwL3Byb3BlcnRpZXMvc2NoZW1hTGFuZ3VhZ2UiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVzNDX1hNTF9TQ0hFTUEgPQorICAgICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIjsKKworICBwdWJsaWMgYm9vbGVhbiBoYXNDb25mbGljdChEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kgb3RoZXIpIHsKKyAgICByZXR1cm4gKG90aGVyID09IHRoaXMpOworICB9CisKKyAgcHVibGljIGFic3RyYWN0IHZvaWQgYXBwbHlTZXR0aW5nKAorICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5LAorICAgICAgYm9vbGVhbiB2YWx1ZSkgdGhyb3dzIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb247CisKKyAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaGFzU2V0dGluZyhET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KTsKKworICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneSBjb2FsZXNjaW5nID0KKyAgICAgIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3koKSB7CisgICAgcHVibGljIHZvaWQgYXBwbHlTZXR0aW5nKERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSwgYm9vbGVhbiB2YWx1ZSkKKyAgICAgICAgdGhyb3dzIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgZmFjdG9yeS5zZXRDb2FsZXNjaW5nKHZhbHVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNTZXR0aW5nKERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpIHsKKyAgICAgIHJldHVybiBmYWN0b3J5LmlzQ29hbGVzY2luZygpOworICAgIH0KKworICB9OworCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5CisgICAgICBleHBhbmRFbnRpdHlSZWZlcmVuY2VzID0KKyAgICAgIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3koKSB7CisgICAgcHVibGljIHZvaWQgYXBwbHlTZXR0aW5nKERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSwgYm9vbGVhbiB2YWx1ZSkKKyAgICAgICAgdGhyb3dzIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgZmFjdG9yeS5zZXRFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKHZhbHVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNTZXR0aW5nKERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpIHsKKyAgICAgIHJldHVybiBmYWN0b3J5LmlzRXhwYW5kRW50aXR5UmVmZXJlbmNlcygpOworICAgIH0KKyAgfTsKKworICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneQorICAgICAgaWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneSgpIHsKKyAgICBwdWJsaWMgdm9pZCBhcHBseVNldHRpbmcoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5LCBib29sZWFuIHZhbHVlKQorICAgICAgICB0aHJvd3MgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBmYWN0b3J5LnNldElnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKHZhbHVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNTZXR0aW5nKERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpIHsKKyAgICAgIHJldHVybiBmYWN0b3J5LmlzSWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoKTsKKyAgICB9CisgIH07CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kgaWdub3JpbmdDb21tZW50cyA9CisgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5KCkgeworICAgIHB1YmxpYyB2b2lkIGFwcGx5U2V0dGluZyhEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnksIGJvb2xlYW4gdmFsdWUpCisgICAgICAgIHRocm93cyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIGlmICh2YWx1ZSkgeworICAgICAgICB0aHJvdyBuZXcgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbigKKyAgICAgICAgICAgIG5ldyBFeGNlcHRpb24oImlnbm9yZUNvbW1lbnRzPXRydWUgbm90IHN1cHBvcnRlZCIpLAorICAgICAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5pZ25vcmluZ0NvbW1lbnRzKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNTZXR0aW5nKERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH07CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kgbmFtZXNwYWNlQXdhcmUgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneSgpIHsKKyAgICBwdWJsaWMgdm9pZCBhcHBseVNldHRpbmcoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5LCBib29sZWFuIHZhbHVlKSB0aHJvd3MKKyAgICAgICAgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHZhbHVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNTZXR0aW5nKERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpIHsKKyAgICAgIHJldHVybiBmYWN0b3J5LmlzTmFtZXNwYWNlQXdhcmUoKTsKKyAgICB9CisgIH07CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kgdmFsaWRhdGluZyA9CisgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5KCkgeworICAgIHB1YmxpYyB2b2lkIGFwcGx5U2V0dGluZyhEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnksIGJvb2xlYW4gdmFsdWUpIHRocm93cworICAgICAgICBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIGZhY3Rvcnkuc2V0VmFsaWRhdGluZyh2YWx1ZSk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaGFzU2V0dGluZyhET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSB7CisgICAgICByZXR1cm4gZmFjdG9yeS5pc1ZhbGlkYXRpbmcoKTsKKyAgICB9CisgIH07CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kgc2lnbmVkID0KKyAgICAgIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3koKSB7CisgICAgcHVibGljIHZvaWQgYXBwbHlTZXR0aW5nKERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSwgYm9vbGVhbiB2YWx1ZSkgdGhyb3dzCisgICAgICAgIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aHJvdyBuZXcgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbigKKyAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5vdFNpZ25lZCk7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaGFzU2V0dGluZyhET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH07CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kgaGFzTnVsbFN0cmluZyA9CisgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5KCkgeworICAgIHB1YmxpYyB2b2lkIGFwcGx5U2V0dGluZyhEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnksIGJvb2xlYW4gdmFsdWUpIHRocm93cworICAgICAgICBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhyb3cgbmV3IERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24oCisgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RIYXNOdWxsU3RyaW5nKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNTZXR0aW5nKERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfTsKKworICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneSBzY2hlbWFWYWxpZGF0aW5nID0KKyAgICAgIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3koKSB7CisgICAgcHVibGljIHZvaWQgYXBwbHlTZXR0aW5nKERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSwgYm9vbGVhbiB2YWx1ZSkgdGhyb3dzCisgICAgICAgIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgaWYgKHZhbHVlKSB7CisgICAgICAgIGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7CisgICAgICAgIGZhY3Rvcnkuc2V0VmFsaWRhdGluZyh0cnVlKTsKKyAgICAgICAgZmFjdG9yeS5zZXRBdHRyaWJ1dGUoSkFYUF9TQ0hFTUFfTEFOR1VBR0UsIFczQ19YTUxfU0NIRU1BKTsKKyAgICAgIH0KKyAgICAgIGVsc2UgeworICAgICAgICBmYWN0b3J5LnNldEF0dHJpYnV0ZShKQVhQX1NDSEVNQV9MQU5HVUFHRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNTZXR0aW5nKERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIGlmIChmYWN0b3J5LmlzVmFsaWRhdGluZygpKSB7CisgICAgICAgICAgTWV0aG9kIGdldEF0dHJNZXRob2QgPSBmYWN0b3J5LmdldENsYXNzKCkuZ2V0TWV0aG9kKCJnZXRBdHRyaWJ1dGUiLAorICAgICAgICAgICAgICBuZXcgQ2xhc3NbXSB7U3RyaW5nLmNsYXNzfSk7CisgICAgICAgICAgU3RyaW5nIHZhbCA9IChTdHJpbmcpIGdldEF0dHJNZXRob2QuaW52b2tlKGZhY3RvcnksCisgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7SkFYUF9TQ0hFTUFfTEFOR1VBR0V9KTsKKyAgICAgICAgICByZXR1cm4gVzNDX1hNTF9TQ0hFTUEuZXF1YWxzKHZhbCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgIH0KKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvLworICAgIC8vICAgc2NoZW1hIHZhbGlkYXRpbmcgY29uZmxpY3RzIHdpdGggbmFtZXNwYWNlQXdhcmUKKyAgICAvLyAgICAgICAgYW5kIHZhbGlkYXRpbmcKKyAgICAvLworICAgIHB1YmxpYyBib29sZWFuIGhhc0NvbmZsaWN0KERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneSBvdGhlcikgeworICAgICAgaWYgKG90aGVyID09IHRoaXMgfHwKKyAgICAgICAgICBvdGhlciA9PSBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kubmFtZXNwYWNlQXdhcmUgfHwKKyAgICAgICAgICBvdGhlciA9PSBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kudmFsaWRhdGluZykgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgfTsKKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGNhOGYxZgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmphdmEKQEAgLTAsMCArMSwxODYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHM7CisKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247CisKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247CisKKy8qKgorICogICBUaGlzIGNsYXNzIGltcGxlbWVudHMgdGhlIGdlbmVyaWMgcGFyc2VyIGFuZCBjb25maWd1YXRpb24KKyAqICAgYWJzdHJhY3QgY2xhc3MgZm9yIEpBWFAgc3VwcG9ydGluZyBwYXJzZXJzLgorICovCitwdWJsaWMgY2xhc3MgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgZXh0ZW5kcyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB7CisKKyAgcHJpdmF0ZSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisgIHByaXZhdGUgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBKQVhQIGltcGxlbWVudGF0aW9uIG9mIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LgorICAgKiBAcGFyYW0gZmFjdG9yeSBudWxsIGZvciBkZWZhdWx0IEpBWFAgcHJvdmlkZXIuICBJZiBub3QgbnVsbCwKKyAgICogZmFjdG9yeSB3aWxsIGJlIG11dGF0ZWQgaW4gY29uc3RydWN0b3IgYW5kIHNob3VsZCBiZSByZWxlYXNlZAorICAgKiBieSBjYWxsaW5nIGNvZGUgdXBvbiByZXR1cm4uCisgICAqIEBwYXJhbSBzZXR0aW5ncyBhcnJheSBvZiBzZXR0aW5ncywgbWF5IGJlIG51bGwuCisgICAqLworICBwdWJsaWMgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5KAorICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBiYXNlRmFjdG9yeSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncykgdGhyb3dzIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgIHN1cGVyKHNldHRpbmdzKTsKKyAgICBpZiAoYmFzZUZhY3RvcnkgPT0gbnVsbCkgeworICAgICAgZmFjdG9yeSA9IERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICBmYWN0b3J5ID0gYmFzZUZhY3Rvcnk7CisgICAgfQorICAgIC8vCisgICAgLy8gICAgYXBwbHkgc2V0dGluZ3MgdG8gc2VsZWN0ZWQgZG9jdW1lbnQgYnVpbGRlcgorICAgIC8vICAgICAgICAgbWF5IHRocm93IGV4Y2VwdGlvbiBpZiBpbmNvbXBhdGlibGUKKyAgICBpZiAoc2V0dGluZ3MgIT0gbnVsbCkgeworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZXR0aW5ncy5sZW5ndGg7IGkrKykgeworICAgICAgICBzZXR0aW5nc1tpXS5hcHBseVNldHRpbmcoZmFjdG9yeSk7CisgICAgICB9CisgICAgfQorICAgIHRyeSB7CisgICAgICB0aGlzLmJ1aWxkZXIgPSBmYWN0b3J5Lm5ld0RvY3VtZW50QnVpbGRlcigpOworICAgIH0KKyAgICBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleCkgeworICAgICAgdGhyb3cgbmV3IERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24oZXgsIG51bGwpOworICAgIH0KKyAgfQorCisgIHByb3RlY3RlZCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBjcmVhdGVJbnN0YW5jZShEb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICBuZXdGYWN0b3J5LAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIG1lcmdlZFNldHRpbmdzKSB0aHJvd3MKKyAgICAgIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgIHJldHVybiBuZXcgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5KG5ld0ZhY3RvcnksIG1lcmdlZFNldHRpbmdzKTsKKyAgfQorCisgIHB1YmxpYyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBuZXdJbnN0YW5jZShEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10KKyAgICAgIG5ld1NldHRpbmdzKSB0aHJvd3MgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgaWYgKG5ld1NldHRpbmdzID09IG51bGwpIHsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKyAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gbWVyZ2VkU2V0dGluZ3MgPSBtZXJnZVNldHRpbmdzKG5ld1NldHRpbmdzKTsKKyAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IG5ld0ZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisgICAgcmV0dXJuIGNyZWF0ZUluc3RhbmNlKG5ld0ZhY3RvcnksIG1lcmdlZFNldHRpbmdzKTsKKyAgfQorCisgIHByaXZhdGUgY2xhc3MgTG9hZEVycm9ySGFuZGxlcgorICAgICAgaW1wbGVtZW50cyBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIgeworICAgIHByaXZhdGUgU0FYRXhjZXB0aW9uIHBhcnNlRXhjZXB0aW9uOworICAgIHByaXZhdGUgaW50IGVycm9yQ291bnQ7CisgICAgcHJpdmF0ZSBpbnQgd2FybmluZ0NvdW50OworICAgIHB1YmxpYyBMb2FkRXJyb3JIYW5kbGVyKCkgeworICAgICAgcGFyc2VFeGNlcHRpb24gPSBudWxsOworICAgICAgZXJyb3JDb3VudCA9IDA7CisgICAgICB3YXJuaW5nQ291bnQgPSAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGV4KSB7CisgICAgICBlcnJvckNvdW50Kys7CisgICAgICBpZiAocGFyc2VFeGNlcHRpb24gPT0gbnVsbCkgeworICAgICAgICBwYXJzZUV4Y2VwdGlvbiA9IGV4OworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoU0FYUGFyc2VFeGNlcHRpb24gZXgpIHsKKyAgICAgIHdhcm5pbmdDb3VudCsrOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZXgpIHsKKyAgICAgIGlmIChwYXJzZUV4Y2VwdGlvbiA9PSBudWxsKSB7CisgICAgICAgIHBhcnNlRXhjZXB0aW9uID0gZXg7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFNBWEV4Y2VwdGlvbiBnZXRGaXJzdEV4Y2VwdGlvbigpIHsKKyAgICAgIHJldHVybiBwYXJzZUV4Y2VwdGlvbjsKKyAgICB9CisgIH0KKworICBwdWJsaWMgRG9jdW1lbnQgbG9hZChqYXZhLm5ldC5VUkwgdXJsKSB0aHJvd3MgRE9NVGVzdExvYWRFeGNlcHRpb24geworICAgIERvY3VtZW50IGRvYyA9IG51bGw7CisgICAgRXhjZXB0aW9uIHBhcnNlRXhjZXB0aW9uID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgTG9hZEVycm9ySGFuZGxlciBlcnJvckhhbmRsZXIgPSBuZXcgTG9hZEVycm9ySGFuZGxlcigpOworICAgICAgYnVpbGRlci5zZXRFcnJvckhhbmRsZXIoZXJyb3JIYW5kbGVyKTsKKyAgICAgIElucHV0U3RyZWFtIHN0cmVhbSA9IHVybC5vcGVuU3RyZWFtKCk7CisgICAgICBkb2MgPSBidWlsZGVyLnBhcnNlKHN0cmVhbSwgdXJsLnRvU3RyaW5nKCkpOworICAgICAgc3RyZWFtLmNsb3NlKCk7CisgICAgICBwYXJzZUV4Y2VwdGlvbiA9IGVycm9ySGFuZGxlci5nZXRGaXJzdEV4Y2VwdGlvbigpOworICAgIH0KKyAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICBwYXJzZUV4Y2VwdGlvbiA9IGV4OworICAgIH0KKyAgICBidWlsZGVyLnNldEVycm9ySGFuZGxlcihudWxsKTsKKyAgICBpZiAocGFyc2VFeGNlcHRpb24gIT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IERPTVRlc3RMb2FkRXhjZXB0aW9uKHBhcnNlRXhjZXB0aW9uKTsKKyAgICB9CisgICAgcmV0dXJuIGRvYzsKKyAgfQorCisgIHB1YmxpYyBET01JbXBsZW1lbnRhdGlvbiBnZXRET01JbXBsZW1lbnRhdGlvbigpIHsKKyAgICByZXR1cm4gYnVpbGRlci5nZXRET01JbXBsZW1lbnRhdGlvbigpOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gaGFzRmVhdHVyZShTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pIHsKKyAgICByZXR1cm4gYnVpbGRlci5nZXRET01JbXBsZW1lbnRhdGlvbigpLmhhc0ZlYXR1cmUoZmVhdHVyZSwgdmVyc2lvbik7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBpc0NvYWxlc2NpbmcoKSB7CisgICAgcmV0dXJuIGZhY3RvcnkuaXNDb2FsZXNjaW5nKCk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBpc0V4cGFuZEVudGl0eVJlZmVyZW5jZXMoKSB7CisgICAgcmV0dXJuIGZhY3RvcnkuaXNFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKCk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBpc0lnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKCkgeworICAgIHJldHVybiBmYWN0b3J5LmlzSWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGlzTmFtZXNwYWNlQXdhcmUoKSB7CisgICAgcmV0dXJuIGZhY3RvcnkuaXNOYW1lc3BhY2VBd2FyZSgpOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gaXNWYWxpZGF0aW5nKCkgeworICAgIHJldHVybiBmYWN0b3J5LmlzVmFsaWRhdGluZygpOworICB9CisKKyAgcHVibGljIHN0YXRpYyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gZ2V0Q29uZmlndXJhdGlvbjEoKSB7CisgICAgcmV0dXJuIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5vdENvYWxlc2NpbmcsCisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcubm90RXhwYW5kRW50aXR5UmVmZXJlbmNlcywKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RJZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSwKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3ROYW1lc3BhY2VBd2FyZSwKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RWYWxpZGF0aW5nfTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIGdldENvbmZpZ3VyYXRpb24yKCkgeworICAgIHJldHVybiBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RDb2FsZXNjaW5nLAorICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLmV4cGFuZEVudGl0eVJlZmVyZW5jZXMsCisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcuaWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UsCisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUsCisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcudmFsaWRhdGluZ307CisKKyAgfQorCit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0pUaWR5RE9NSW1wbGVtZW50YXRpb24uamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvSlRpZHlET01JbXBsZW1lbnRhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYwYTZjOGEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0pUaWR5RE9NSW1wbGVtZW50YXRpb24uamF2YQpAQCAtMCwwICsxLDEzMSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMiBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHM7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRUeXBlOworCisvKioKKyAqICAgSlRpZHkgZG9lcyBub3QgaW1wbGVtZW50IERPTUltcGxlbWVudGF0aW9uCisgKiAgICB3ZSBkbyBpdCBoZXJlIHRvIGtlZXAgdGhlIHRlc3QgZXhjbHVzaW9uIGxvZ2ljCisgKiAgICBmcm9tIGZhbGxpbmcgYXBhcnQuCisgKi8KK3B1YmxpYyBjbGFzcyBKVGlkeURPTUltcGxlbWVudGF0aW9uCisgICAgaW1wbGVtZW50cyBET01JbXBsZW1lbnRhdGlvbiB7CisKKyAgLyoqCisgICAqIFRlc3QgaWYgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBpbXBsZW1lbnRzIGEgc3BlY2lmaWMgZmVhdHVyZS4KKyAgICogQHBhcmFtIGZlYXR1cmUgVGhlIG5hbWUgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdCAoY2FzZS1pbnNlbnNpdGl2ZSkuIFRoZQorICAgKiAgIHZhbHVlcyB1c2VkIGJ5IERPTSBmZWF0dXJlcyBhcmUgZGVmaW5lZCB0aHJvdWdob3V0IHRoZSBET00gTGV2ZWwgMgorICAgKiAgIHNwZWNpZmljYXRpb25zIGFuZCBsaXN0ZWQgaW4gdGhlICBzZWN0aW9uLiBUaGUgbmFtZSBtdXN0IGJlIGFuIFhNTAorICAgKiAgIG5hbWUuIFRvIGF2b2lkIHBvc3NpYmxlIGNvbmZsaWN0cywgYXMgYSBjb252ZW50aW9uLCBuYW1lcyByZWZlcnJpbmcKKyAgICogICB0byBmZWF0dXJlcyBkZWZpbmVkIG91dHNpZGUgdGhlIERPTSBzcGVjaWZpY2F0aW9uIHNob3VsZCBiZSBtYWRlCisgICAqICAgdW5pcXVlLgorICAgKiBAcGFyYW0gdmVyc2lvbiBUaGlzIGlzIHRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGUgZmVhdHVyZSB0byB0ZXN0LiBJbgorICAgKiAgIExldmVsIDIsIHRoZSBzdHJpbmcgY2FuIGJlIGVpdGhlciAiMi4wIiBvciAiMS4wIi4gSWYgdGhlIHZlcnNpb24gaXMKKyAgICogICBub3Qgc3BlY2lmaWVkLCBzdXBwb3J0aW5nIGFueSB2ZXJzaW9uIG9mIHRoZSBmZWF0dXJlIGNhdXNlcyB0aGUKKyAgICogICBtZXRob2QgdG8gcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+LgorICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBmZWF0dXJlIGlzIGltcGxlbWVudGVkIGluIHRoZQorICAgKiAgIHNwZWNpZmllZCB2ZXJzaW9uLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaGFzRmVhdHVyZShTdHJpbmcgZmVhdHVyZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmVyc2lvbikgeworICAgIGlmIChmZWF0dXJlLmVxdWFscygiQ29yZSIpKSB7CisgICAgICByZXR1cm4gdmVyc2lvbiA9PSBudWxsIHx8IHZlcnNpb24uZXF1YWxzKCIxLjAiKSB8fCB2ZXJzaW9uLmVxdWFscygiMi4wIik7CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGVzIGFuIGVtcHR5IDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gbm9kZS4gRW50aXR5IGRlY2xhcmF0aW9ucworICAgKiBhbmQgbm90YXRpb25zIGFyZSBub3QgbWFkZSBhdmFpbGFibGUuIEVudGl0eSByZWZlcmVuY2UgZXhwYW5zaW9ucyBhbmQKKyAgICogZGVmYXVsdCBhdHRyaWJ1dGUgYWRkaXRpb25zIGRvIG5vdCBvY2N1ci4gSXQgaXMgZXhwZWN0ZWQgdGhhdCBhCisgICAqIGZ1dHVyZSB2ZXJzaW9uIG9mIHRoZSBET00gd2lsbCBwcm92aWRlIGEgd2F5IGZvciBwb3B1bGF0aW5nIGEKKyAgICogPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPi4KKyAgICogQHBhcmFtIHF1YWxpZmllZE5hbWUgVGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBkb2N1bWVudCB0eXBlIHRvIGJlCisgICAqICAgY3JlYXRlZC4KKyAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBleHRlcm5hbCBzdWJzZXQgcHVibGljIGlkZW50aWZpZXIuCisgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgZXh0ZXJuYWwgc3Vic2V0IHN5c3RlbSBpZGVudGlmaWVyLgorICAgKiBAcmV0dXJuIEEgbmV3IDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gbm9kZSB3aXRoCisgICAqICAgPGNvZGU+Tm9kZS5vd25lckRvY3VtZW50PC9jb2RlPiBzZXQgdG8gPGNvZGU+bnVsbDwvY29kZT4uCisgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAqICAgSU5WQUxJRF9DSEFSQUNURVJfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBxdWFsaWZpZWQgbmFtZQorICAgKiAgIGNvbnRhaW5zIGFuIGlsbGVnYWwgY2hhcmFjdGVyLgorICAgKiAgIDxicj5OQU1FU1BBQ0VfRVJSOiBSYWlzZWQgaWYgdGhlIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IGlzCisgICAqICAgbWFsZm9ybWVkLgorICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogTWF5IGJlIHJhaXNlZCBieSBET00gaW1wbGVtZW50YXRpb25zIHdoaWNoIGRvCisgICAqICAgbm90IHN1cHBvcnQgdGhlIDxjb2RlPiJYTUwiPC9jb2RlPiBmZWF0dXJlLCBpZiB0aGV5IGNob29zZSBub3QgdG8KKyAgICogICBzdXBwb3J0IHRoaXMgbWV0aG9kLiBPdGhlciBmZWF0dXJlcyBpbnRyb2R1Y2VkIGluIHRoZSBmdXR1cmUsIGJ5CisgICAqICAgdGhlIERPTSBXRyBvciBpbiBleHRlbnNpb25zIGRlZmluZWQgYnkgb3RoZXIgZ3JvdXBzLCBtYXkgYWxzbworICAgKiAgIGRlbWFuZCBzdXBwb3J0IGZvciB0aGlzIG1ldGhvZDsgcGxlYXNlIGNvbnN1bHQgdGhlIGRlZmluaXRpb24gb2YKKyAgICogICB0aGUgZmVhdHVyZSB0byBzZWUgaWYgaXQgcmVxdWlyZXMgdGhpcyBtZXRob2QuCisgICAqIEBzaW5jZSBET00gTGV2ZWwgMgorICAgKi8KKyAgcHVibGljIERvY3VtZW50VHlwZSBjcmVhdGVEb2N1bWVudFR5cGUoU3RyaW5nIHF1YWxpZmllZE5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwdWJsaWNJZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk5vdCBJbXBsZW1lbnRlZCIpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBET00gRG9jdW1lbnQgb2JqZWN0IG9mIHRoZSBzcGVjaWZpZWQgdHlwZSB3aXRoIGl0cyBkb2N1bWVudAorICAgKiBlbGVtZW50LgorICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBkb2N1bWVudCBlbGVtZW50IHRvCisgICAqICAgY3JlYXRlLgorICAgKiBAcGFyYW0gcXVhbGlmaWVkTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGRvY3VtZW50IGVsZW1lbnQgdG8gYmUKKyAgICogICBjcmVhdGVkLgorICAgKiBAcGFyYW0gZG9jdHlwZSBUaGUgdHlwZSBvZiBkb2N1bWVudCB0byBiZSBjcmVhdGVkIG9yIDxjb2RlPm51bGw8L2NvZGU+LgorICAgKiAgIFdoZW4gPGNvZGU+ZG9jdHlwZTwvY29kZT4gaXMgbm90IDxjb2RlPm51bGw8L2NvZGU+LCBpdHMKKyAgICogICA8Y29kZT5Ob2RlLm93bmVyRG9jdW1lbnQ8L2NvZGU+IGF0dHJpYnV0ZSBpcyBzZXQgdG8gdGhlIGRvY3VtZW50CisgICAqICAgYmVpbmcgY3JlYXRlZC4KKyAgICogQHJldHVybiBBIG5ldyA8Y29kZT5Eb2N1bWVudDwvY29kZT4gb2JqZWN0LgorICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgKiAgIElOVkFMSURfQ0hBUkFDVEVSX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgcXVhbGlmaWVkIG5hbWUKKyAgICogICBjb250YWlucyBhbiBpbGxlZ2FsIGNoYXJhY3Rlci4KKyAgICogICA8YnI+TkFNRVNQQUNFX0VSUjogUmFpc2VkIGlmIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBpcworICAgKiAgIG1hbGZvcm1lZCwgaWYgdGhlIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IGhhcyBhIHByZWZpeCBhbmQgdGhlCisgICAqICAgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwgb3IgaWYgdGhlCisgICAqICAgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gaGFzIGEgcHJlZml4IHRoYXQgaXMgInhtbCIgYW5kIHRoZQorICAgKiAgIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgZGlmZmVyZW50IGZyb20gIgorICAgKiAgIGh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIgLCBvciBpZiB0aGUgRE9NCisgICAqICAgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCB0aGUgPGNvZGU+IlhNTCI8L2NvZGU+IGZlYXR1cmUgYnV0CisgICAqICAgYSBub24tbnVsbCBuYW1lc3BhY2UgVVJJIHdhcyBwcm92aWRlZCwgc2luY2UgbmFtZXNwYWNlcyB3ZXJlCisgICAqICAgZGVmaW5lZCBieSBYTUwuCisgICAqICAgPGJyPldST05HX0RPQ1VNRU5UX0VSUjogUmFpc2VkIGlmIDxjb2RlPmRvY3R5cGU8L2NvZGU+IGhhcyBhbHJlYWR5CisgICAqICAgYmVlbiB1c2VkIHdpdGggYSBkaWZmZXJlbnQgZG9jdW1lbnQgb3Igd2FzIGNyZWF0ZWQgZnJvbSBhIGRpZmZlcmVudAorICAgKiAgIGltcGxlbWVudGF0aW9uLgorICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogTWF5IGJlIHJhaXNlZCBieSBET00gaW1wbGVtZW50YXRpb25zIHdoaWNoIGRvCisgICAqICAgbm90IHN1cHBvcnQgdGhlICJYTUwiIGZlYXR1cmUsIGlmIHRoZXkgY2hvb3NlIG5vdCB0byBzdXBwb3J0IHRoaXMKKyAgICogICBtZXRob2QuIE90aGVyIGZlYXR1cmVzIGludHJvZHVjZWQgaW4gdGhlIGZ1dHVyZSwgYnkgdGhlIERPTSBXRyBvcgorICAgKiAgIGluIGV4dGVuc2lvbnMgZGVmaW5lZCBieSBvdGhlciBncm91cHMsIG1heSBhbHNvIGRlbWFuZCBzdXBwb3J0IGZvcgorICAgKiAgIHRoaXMgbWV0aG9kOyBwbGVhc2UgY29uc3VsdCB0aGUgZGVmaW5pdGlvbiBvZiB0aGUgZmVhdHVyZSB0byBzZWUgaWYKKyAgICogICBpdCByZXF1aXJlcyB0aGlzIG1ldGhvZC4KKyAgICogQHNpbmNlIERPTSBMZXZlbCAyCisgICAqLworICBwdWJsaWMgRG9jdW1lbnQgY3JlYXRlRG9jdW1lbnQoU3RyaW5nIG5hbWVzcGFjZVVSSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRG9jdW1lbnRUeXBlIGRvY3R5cGUpIHRocm93cyBET01FeGNlcHRpb24geworICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTm90IEltcGxlbWVudGVkIik7CisgIH0KKworICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb24gZ2V0SW50ZXJmYWNlKFN0cmluZyBmZWF0dXJlKSB7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICBwdWJsaWMgT2JqZWN0IGdldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmUsIFN0cmluZyB2ZXJzaW9uKSB7CisgICAgcmV0dXJuIG51bGw7CisgIH0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9KVGlkeURvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvSlRpZHlEb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2I4ZjQ1NAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvSlRpZHlEb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmphdmEKQEAgLTAsMCArMSwxMzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDItMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHM7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworCisvKioKKyAqICAgVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBnZW5lcmljIHBhcnNlciBidWlsZGVyCisgKiAgIGZvciBKVGlkeSAoaHR0cDovL3NmLm5ldC9wcm9qZWN0cy9KVGlkeSkgd2hpY2ggcmVhZHMgSFRNTAorICogICBhbmQgc3VwcG9ydHMgdGhlIGZ1bmRhbWVudGFsIERPTSBpbnRlcmZhY2VzIGJ1dCBub3QgZWl0aGVyIEhUTUwgTDEgRE9NCisgKiAgIG9yIEhUTUwgTDIgRE9NCisgKi8KK3B1YmxpYyBjbGFzcyBKVGlkeURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICBleHRlbmRzIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHsKKworICBwcml2YXRlIGZpbmFsIENvbnN0cnVjdG9yIHRpZHlDb25zdHJ1Y3RvcjsKKyAgcHJpdmF0ZSBmaW5hbCBNZXRob2QgcGFyc2VET01NZXRob2Q7CisgIHByaXZhdGUgZmluYWwgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ2xhc3NbXSBOT19DTEFTU0VTID0gbmV3IENsYXNzWzBdOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXSBOT19PQkpFQ1RTID0gbmV3IE9iamVjdFswXTsKKworICAvKioKKyAgICogQ3JlYXRlcyBhIGltcGxlbWVudGF0aW9uIG9mIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAqIHVzaW5nIEpUaWR5J3MgSFRNTCBwYXJzZXIgYW5kIERPTSBpbXBsZW1lbnRhdGlvbgorICAgKiBAcGFyYW0gc2V0dGluZ3MgYXJyYXkgb2Ygc2V0dGluZ3MsIG1heSBiZSBudWxsLgorICAgKi8KKyAgcHVibGljIEpUaWR5RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncykgdGhyb3dzIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgIHN1cGVyKHNldHRpbmdzKTsKKworICAgIHRyeSB7CisgICAgICBDbGFzc0xvYWRlciBjbGFzc0xvYWRlciA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCk7CisgICAgICBDbGFzcyB0aWR5Q2xhc3MgPSBjbGFzc0xvYWRlci5sb2FkQ2xhc3MoIm9yZy53M2MudGlkeS5UaWR5Iik7CisKKyAgICAgIHRpZHlDb25zdHJ1Y3RvciA9CisgICAgICAgICAgdGlkeUNsYXNzLmdldENvbnN0cnVjdG9yKE5PX0NMQVNTRVMpOworCisgICAgICBwYXJzZURPTU1ldGhvZCA9CisgICAgICAgICAgdGlkeUNsYXNzLmdldE1ldGhvZCgicGFyc2VET00iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IENsYXNzW10ge2phdmEuaW8uSW5wdXRTdHJlYW0uY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqYXZhLmlvLk91dHB1dFN0cmVhbS5jbGFzc30pOworCisgICAgICAvLworICAgICAgLy8gIEpUaWR5IGRvZXNuJ3QgaW1wbGVtZW50IERPTUltcGxlbWVudGF0aW9uIHNvCisgICAgICAvLyAgICB3ZSB3aWxsIGRvIGl0IGhlcmUKKyAgICAgIGRvbUltcGwgPSBuZXcgSlRpZHlET01JbXBsZW1lbnRhdGlvbigpOworCisgICAgfQorICAgIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgIHRocm93IG5ldyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uKGV4LCBudWxsKTsKKyAgICB9CisKKyAgICAvLworICAgIC8vICAgIGFwcGx5IHNldHRpbmdzIHRvIHNlbGVjdGVkIGRvY3VtZW50IGJ1aWxkZXIKKyAgICAvLyAgICAgICAgIG1heSB0aHJvdyBleGNlcHRpb24gaWYgaW5jb21wYXRpYmxlCisgICAgaWYgKHNldHRpbmdzICE9IG51bGwpIHsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2V0dGluZ3MubGVuZ3RoOyBpKyspIHsKKy8vICAgICAgICBzZXR0aW5nc1tpXS5hcHBseVNldHRpbmcoZmFjdG9yeSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcHVibGljIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IG5ld0luc3RhbmNlKERvY3VtZW50QnVpbGRlclNldHRpbmdbXQorICAgICAgbmV3U2V0dGluZ3MpIHRocm93cyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICBpZiAobmV3U2V0dGluZ3MgPT0gbnVsbCkgeworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdbXSBtZXJnZWRTZXR0aW5ncyA9IG1lcmdlU2V0dGluZ3MobmV3U2V0dGluZ3MpOworICAgIHJldHVybiBuZXcgSlRpZHlEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KG1lcmdlZFNldHRpbmdzKTsKKyAgfQorCisgIHB1YmxpYyBEb2N1bWVudCBsb2FkKGphdmEubmV0LlVSTCB1cmwpIHRocm93cyBET01UZXN0TG9hZEV4Y2VwdGlvbiB7CisgICAgRG9jdW1lbnQgZG9jID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBzdHJlYW0gPSB1cmwub3BlblN0cmVhbSgpOworICAgICAgT2JqZWN0IHRpZHlPYmogPSB0aWR5Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFswXSk7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIHBhcnNlRE9NTWV0aG9kLmludm9rZSh0aWR5T2JqLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtzdHJlYW0sIG51bGx9KTsKKyAgICB9CisgICAgY2F0Y2ggKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZXgpIHsKKyAgICAgIHRocm93IG5ldyBET01UZXN0TG9hZEV4Y2VwdGlvbihleC5nZXRUYXJnZXRFeGNlcHRpb24oKSk7CisgICAgfQorICAgIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgIHRocm93IG5ldyBET01UZXN0TG9hZEV4Y2VwdGlvbihleCk7CisgICAgfQorICAgIHJldHVybiBkb2M7CisgIH0KKworICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb24gZ2V0RE9NSW1wbGVtZW50YXRpb24oKSB7CisgICAgcmV0dXJuIGRvbUltcGw7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBoYXNGZWF0dXJlKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikgeworICAgIHJldHVybiBkb21JbXBsLmhhc0ZlYXR1cmUoZmVhdHVyZSwgdmVyc2lvbik7CisgIH0KKworICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgeworICAgIHJldHVybiAidGV4dC9odG1sIjsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGlzQ29hbGVzY2luZygpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBpc0V4cGFuZEVudGl0eVJlZmVyZW5jZXMoKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gaXNJZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSgpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBpc05hbWVzcGFjZUF3YXJlKCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGlzVmFsaWRhdGluZygpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvSlVuaXRUZXN0Q2FzZUFkYXB0ZXIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvSlVuaXRUZXN0Q2FzZUFkYXB0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MTEwNzkyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9KVW5pdFRlc3RDYXNlQWRhcHRlci5qYXZhCkBAIC0wLDAgKzEsNDkxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworIAorcGFja2FnZSBvcmcudzNjLmRvbXRzOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkk7CitpbXBvcnQgamF2YS5uZXQuVVJJU3ludGF4RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ2dlcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworCisKK3B1YmxpYyBjbGFzcyBKVW5pdFRlc3RDYXNlQWRhcHRlciBleHRlbmRzIFRlc3RDYXNlIGltcGxlbWVudHMgRE9NVGVzdEZyYW1ld29yayB7CisKKyAgcHJpdmF0ZSBET01UZXN0Q2FzZSB0ZXN0OworICAKKyAgCisgIHByaXZhdGUgc3RhdGljIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGRlZmF1bHRGYWN0b3J5ID0gbnVsbDsgCisKKyAgcHVibGljIEpVbml0VGVzdENhc2VBZGFwdGVyKERPTVRlc3RDYXNlIHRlc3QpIHsKKyAgICBzdXBlcih0ZXN0LmdldFRhcmdldFVSSSgpKTsKKyAgICB0ZXN0LnNldEZyYW1ld29yayh0aGlzKTsKKyAgICB0aGlzLnRlc3QgPSB0ZXN0OworICB9CisvL0JFR0lOIGFuZHJvaWQtYWRkZWQKKyAgcHVibGljIEpVbml0VGVzdENhc2VBZGFwdGVyKCkgeworICAgICAgCisgIH0KKyAgCisgIHByaXZhdGUgU3RyaW5nIGVycm9yTWVzc2FnZSA9IG51bGw7CisgIHByaXZhdGUgYm9vbGVhbiBmYWlsZWQgPSBmYWxzZTsKKyAgCisgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgc3VwZXIuc2V0TmFtZShuYW1lKTsKKyAgICAgICAgaWYgKHRlc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBVUkkgdXJpID0gbmV3IFVSSShuYW1lKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcgcGF0aCA9IHVyaS5nZXRQYXRoKCk7CisgICAgICAgICAgICAgICAgcGF0aCA9IHBhdGgucmVwbGFjZUFsbCgiLyIsICIuIik7CisgICAgICAgICAgICAgICAgQ2xhc3M8Pz4gY2xhenogPSBudWxsOworICAgICAgICAgICAgICAgIGludCBwb3MgPSBwYXRoLmluZGV4T2YoJy4nKTsKKyAgICAgICAgICAgICAgICB3aGlsZSAocG9zICE9IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjbGF6eiA9IENsYXNzLmZvck5hbWUoIm9yZy53M2MuZG9tdHMuIiArIHBhdGgpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG8gbm90aGluZworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXRoLnN1YnN0cmluZyhwb3MgKyAxKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGNsYXp6ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gImNsYXNzIG5vdCBmb3VuZCBmb3IgdGVzdDogIiArIG5hbWU7CisgICAgICAgICAgICAgICAgICAgIGZhaWxlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoZGVmYXVsdEZhY3RvcnkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBkZWZhdWx0RmFjdG9yeSA9IG5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkobnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQ29uc3RydWN0b3I8Pz4gY29uc3RydWN0b3IgPSBjbGF6ei5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3M8Pz5bXSB7CisgICAgICAgICAgICAgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzCisgICAgICAgICAgICAgICAgfSk7CisKKyAgICAgICAgICAgICAgICB0ZXN0ID0gKERPTVRlc3RDYXNlKWNvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7CisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRGYWN0b3J5CisgICAgICAgICAgICAgICAgfSk7CisgICAgICAgICAgICAgICAgdGVzdC5zZXRGcmFtZXdvcmsodGhpcyk7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICB9IGNhdGNoIChVUklTeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWxlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICAgICAgaWYgKGVycm9yTWVzc2FnZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9ICIiICsgZS50b1N0cmluZygpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWxlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICAgICAgaWYgKGVycm9yTWVzc2FnZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9ICIiICsgZS50b1N0cmluZygpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWxlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICAgICAgaWYgKGVycm9yTWVzc2FnZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9ICIiICsgZS50b1N0cmluZygpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWxlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICAgICAgaWYgKGVycm9yTWVzc2FnZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9ICIiICsgZS50b1N0cmluZygpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgICAgIGlmIChlcnJvck1lc3NhZ2UgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSAiIiArIGUudG9TdHJpbmcoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWxlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICAgICAgaWYgKGVycm9yTWVzc2FnZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9ICIiICsgZS50b1N0cmluZygpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbGVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgICAgICBpZiAoZXJyb3JNZXNzYWdlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gIiIgKyBlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbGVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBUaHJvd2FibGUgdCA9IGUuZ2V0Q2F1c2UoKTsKKyAgICAgICAgICAgICAgICBpZiAodCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IHQuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3JNZXNzYWdlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9ICIiICsgdC50b1N0cmluZygpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvck1lc3NhZ2UgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gIiIgKyBlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisvL0VORCBhbmRyb2lkLWFkZGVkCisgIHByb3RlY3RlZCB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIC8vQkVHSU4gYW5kcm9pZC1hZGRlZAorICAgICAgaWYgKGZhaWxlZCkgeworICAgICAgICAgIGlmIChlcnJvck1lc3NhZ2UgIT0gbnVsbCkgeworICAgICAgICAgICAgICBmYWlsKGVycm9yTWVzc2FnZSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgZmFpbCgiaW5pdCBmYWlsZWQiKTsKKyAgICAgICAgICB9CisgICAgICB9CisgICAgICAvL0VORCBhbmRyb2lkLWFkZGVkCisgICAgdGVzdC5ydW5UZXN0KCk7CisgICAgaW50IG11dGF0aW9uQ291bnQgPSB0ZXN0LmdldE11dGF0aW9uQ291bnQoKTsKKyAgICBpZiAobXV0YXRpb25Db3VudCAhPSAwKSB7CisgICAgCWZhaWwoIkRvY3VtZW50IGxvYWRlZCB3aXRoIHdpbGxCZU1vZGlmaWVkPSdmYWxzZScgd2FzIG1vZGlmaWVkIGluIGNvdXJzZSBvZiB0ZXN0LiIpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGhhc0ZlYXR1cmUoRG9jdW1lbnRCdWlsZGVyIGRvY0J1aWxkZXIsCisgICAgICAgIFN0cmluZyBmZWF0dXJlLAorICAgICAgICBTdHJpbmcgdmVyc2lvbikgIHsKKyAgICAgcmV0dXJuIGRvY0J1aWxkZXIuZ2V0RE9NSW1wbGVtZW50YXRpb24oKS5oYXNGZWF0dXJlKGZlYXR1cmUsdmVyc2lvbik7CisgIH0KKworICBwdWJsaWMgdm9pZCB3YWl0KGludCBtaWxsaXNlY29uZCkgeworICB9CisKKyAgcHVibGljIHZvaWQgZmFpbChET01UZXN0Q2FzZSB0ZXN0LCBTdHJpbmcgYXNzZXJ0SUQpIHsKKyAgCWZhaWwoYXNzZXJ0SUQpOworICB9CisgIAorICBwdWJsaWMgdm9pZCBhc3NlcnRUcnVlKERPTVRlc3RDYXNlIHRlc3QsIFN0cmluZyBhc3NlcnRJRCwgYm9vbGVhbiBhY3R1YWwpIHsKKyAgICBhc3NlcnRUcnVlKGFzc2VydElELGFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnRGYWxzZShET01UZXN0Q2FzZSB0ZXN0LCBTdHJpbmcgYXNzZXJ0SUQsIGJvb2xlYW4gYWN0dWFsKSB7CisgICAgaWYoYWN0dWFsKSB7CisgICAgICBhc3NlcnRFcXVhbHMoYXNzZXJ0SUQsU3RyaW5nLnZhbHVlT2YoZmFsc2UpLCBTdHJpbmcudmFsdWVPZihhY3R1YWwpKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnROdWxsKERPTVRlc3RDYXNlIHRlc3QsIFN0cmluZyBhc3NlcnRJRCwgT2JqZWN0IGFjdHVhbCkgeworICAgIGFzc2VydE51bGwoYXNzZXJ0SUQsYWN0dWFsKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGFzc2VydE5vdE51bGwoRE9NVGVzdENhc2UgdGVzdCwgU3RyaW5nIGFzc2VydElELCBPYmplY3QgYWN0dWFsKSB7CisgICAgYXNzZXJ0Tm90TnVsbChhc3NlcnRJRCxhY3R1YWwpOworICB9CisKKyAgcHVibGljIHZvaWQgYXNzZXJ0U2FtZShET01UZXN0Q2FzZSB0ZXN0LCBTdHJpbmcgYXNzZXJ0SUQsIE9iamVjdCBleHBlY3RlZCwgT2JqZWN0IGFjdHVhbCkgeworICAgIGJvb2xlYW4gc2FtZSA9IChleHBlY3RlZCA9PSBhY3R1YWwpOworICAgIC8vCisgICAgLy8gICBpZiB0aGUgbm90IHRoZSBzYW1lIGJ1dCBib3RoIGFyZSBub3QgbnVsbAorICAgIC8vICAgICAgbWlnaHQgc3RpbGwgcmVhbGx5IGJlIHRoZSBzYW1lCisgICAgLy8KKyAgICBpZighc2FtZSkgeworICAgICAgaWYoZXhwZWN0ZWQgPT0gbnVsbCB8fCBhY3R1YWwgPT0gbnVsbCB8fAorICAgICAgICAgIShleHBlY3RlZCBpbnN0YW5jZW9mIE5vZGUpIHx8ICEoYWN0dWFsIGluc3RhbmNlb2YgTm9kZSkpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGFzc2VydElELGV4cGVjdGVkLGFjdHVhbCk7CisgICAgICB9CisgICAgICBlbHNlIHsKKyAgICAgICAgLy8KKyAgICAgICAgLy8gIGNvdWxkIGRvIHNvbWV0aGluZyB3aXRoIGlzU2FtZQorICAgICAgICAvLworICAgICAgICBhc3NlcnRFcXVhbHMoYXNzZXJ0SUQsZXhwZWN0ZWQsYWN0dWFsKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnRJbnN0YW5jZU9mKERPTVRlc3RDYXNlIHRlc3QsIFN0cmluZyBhc3NlcnRJRCwgT2JqZWN0IG9iaiwgQ2xhc3MgY2xzKSB7CisgICAgYXNzZXJ0VHJ1ZShhc3NlcnRJRCxjbHMuaXNJbnN0YW5jZShvYmopKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGFzc2VydFNpemUoRE9NVGVzdENhc2UgdGVzdCwgU3RyaW5nIGFzc2VydElELCBpbnQgZXhwZWN0ZWRTaXplLCBOb2RlTGlzdCBjb2xsZWN0aW9uKSB7CisgICAgYXNzZXJ0RXF1YWxzKGFzc2VydElELGV4cGVjdGVkU2l6ZSwgY29sbGVjdGlvbi5nZXRMZW5ndGgoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnRTaXplKERPTVRlc3RDYXNlIHRlc3QsIFN0cmluZyBhc3NlcnRJRCwgaW50IGV4cGVjdGVkU2l6ZSwgTmFtZWROb2RlTWFwIGNvbGxlY3Rpb24pIHsKKyAgICBhc3NlcnRFcXVhbHMoYXNzZXJ0SUQsIGV4cGVjdGVkU2l6ZSwgY29sbGVjdGlvbi5nZXRMZW5ndGgoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnRTaXplKERPTVRlc3RDYXNlIHRlc3QsIFN0cmluZyBhc3NlcnRJRCwgaW50IGV4cGVjdGVkU2l6ZSwgQ29sbGVjdGlvbiBjb2xsZWN0aW9uKSB7CisgICAgYXNzZXJ0RXF1YWxzKGFzc2VydElELCBleHBlY3RlZFNpemUsIGNvbGxlY3Rpb24uc2l6ZSgpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFsc0lnbm9yZUNhc2UoRE9NVGVzdENhc2UgdGVzdCwgU3RyaW5nIGFzc2VydElELCBTdHJpbmcgZXhwZWN0ZWQsIFN0cmluZyBhY3R1YWwpIHsKKyAgCWlmICghZXhwZWN0ZWQuZXF1YWxzSWdub3JlQ2FzZShhY3R1YWwpKSB7CisgIAkJYXNzZXJ0RXF1YWxzKGFzc2VydElELGV4cGVjdGVkLCBhY3R1YWwpOworICAJfQorICB9CisKKyAgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzSWdub3JlQ2FzZShET01UZXN0Q2FzZSB0ZXN0LCBTdHJpbmcgYXNzZXJ0SUQsIENvbGxlY3Rpb24gZXhwZWN0ZWQsIENvbGxlY3Rpb24gYWN0dWFsKSB7CisgICAgaW50IHNpemUgPSBleHBlY3RlZC5zaXplKCk7CisgICAgYXNzZXJ0Tm90TnVsbChhc3NlcnRJRCxleHBlY3RlZCk7CisgICAgYXNzZXJ0Tm90TnVsbChhc3NlcnRJRCxhY3R1YWwpOworICAgIGFzc2VydEVxdWFscyhhc3NlcnRJRCxzaXplLCBhY3R1YWwuc2l6ZSgpKTsKKyAgICBib29sZWFuIGVxdWFscyA9IChleHBlY3RlZCAhPSBudWxsICYmIGFjdHVhbCAhPSBudWxsICYmIHNpemUgPT0gYWN0dWFsLnNpemUoKSk7CisgICAgaWYoZXF1YWxzKSB7CisgICAgICBMaXN0IGV4cGVjdGVkQXJyYXkgPSBuZXcgQXJyYXlMaXN0KGV4cGVjdGVkKTsKKyAgICAgIFN0cmluZyBleHBlY3RlZFN0cmluZzsKKyAgICAgIFN0cmluZyBhY3R1YWxTdHJpbmc7CisgICAgICBJdGVyYXRvciBhY3R1YWxJdGVyID0gYWN0dWFsLml0ZXJhdG9yKCk7CisgICAgICBJdGVyYXRvciBleHBlY3RlZEl0ZXI7CisgICAgICB3aGlsZShhY3R1YWxJdGVyLmhhc05leHQoKSAmJiBlcXVhbHMpIHsKKyAgICAgICAgYWN0dWFsU3RyaW5nID0gKFN0cmluZykgYWN0dWFsSXRlci5uZXh0KCk7CisgICAgICAgIGV4cGVjdGVkSXRlciA9IGV4cGVjdGVkQXJyYXkuaXRlcmF0b3IoKTsKKyAgICAgICAgZXF1YWxzID0gZmFsc2U7CisgICAgICAgIHdoaWxlKGV4cGVjdGVkSXRlci5oYXNOZXh0KCkgJiYgIWVxdWFscykgeworICAgICAgICAgIGV4cGVjdGVkU3RyaW5nID0gKFN0cmluZykgZXhwZWN0ZWRJdGVyLm5leHQoKTsKKyAgICAgICAgICBpZihhY3R1YWxTdHJpbmcuZXF1YWxzSWdub3JlQ2FzZShleHBlY3RlZFN0cmluZykpIHsKKyAgICAgICAgICAgIGVxdWFscyA9IHRydWU7CisgICAgICAgICAgICBleHBlY3RlZEFycmF5LnJlbW92ZShleHBlY3RlZFN0cmluZyk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIGFzc2VydFRydWUoYXNzZXJ0SUQsZXF1YWxzKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFsc0lnbm9yZUNhc2UoRE9NVGVzdENhc2UgdGVzdCwgU3RyaW5nIGFzc2VydElELCBMaXN0IGV4cGVjdGVkLCBMaXN0IGFjdHVhbCkgeworICAgIGludCBzaXplID0gZXhwZWN0ZWQuc2l6ZSgpOworICAgIGFzc2VydE5vdE51bGwoYXNzZXJ0SUQsZXhwZWN0ZWQpOworICAgIGFzc2VydE5vdE51bGwoYXNzZXJ0SUQsYWN0dWFsKTsKKyAgICBhc3NlcnRFcXVhbHMoYXNzZXJ0SUQsc2l6ZSwgYWN0dWFsLnNpemUoKSk7CisgICAgYm9vbGVhbiBlcXVhbHMgPSAoZXhwZWN0ZWQgIT0gbnVsbCAmJiBhY3R1YWwgIT0gbnVsbCAmJiBzaXplID09IGFjdHVhbC5zaXplKCkpOworICAgIGlmKGVxdWFscykgeworICAgICAgU3RyaW5nIGV4cGVjdGVkU3RyaW5nOworICAgICAgU3RyaW5nIGFjdHVhbFN0cmluZzsKKyAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgZXhwZWN0ZWRTdHJpbmcgPSAoU3RyaW5nKSBleHBlY3RlZC5nZXQoaSk7CisgICAgICAgIGFjdHVhbFN0cmluZyA9IChTdHJpbmcpIGFjdHVhbC5nZXQoaSk7CisgICAgICAgIGlmKCFleHBlY3RlZFN0cmluZy5lcXVhbHNJZ25vcmVDYXNlKGFjdHVhbFN0cmluZykpIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoYXNzZXJ0SUQsZXhwZWN0ZWRTdHJpbmcsYWN0dWFsU3RyaW5nKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFscyhET01UZXN0Q2FzZSB0ZXN0LCBTdHJpbmcgYXNzZXJ0SUQsIFN0cmluZyBleHBlY3RlZCwgU3RyaW5nIGFjdHVhbCkgeworICAgIGFzc2VydEVxdWFscyhhc3NlcnRJRCxleHBlY3RlZCxhY3R1YWwpOworICB9CisKKyAgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKERPTVRlc3RDYXNlIHRlc3QsIFN0cmluZyBhc3NlcnRJRCwgaW50IGV4cGVjdGVkLCBpbnQgYWN0dWFsKSB7CisgICAgYXNzZXJ0RXF1YWxzKGFzc2VydElELGV4cGVjdGVkLGFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoRE9NVGVzdENhc2UgdGVzdCwgU3RyaW5nIGFzc2VydElELCBib29sZWFuIGV4cGVjdGVkLCBib29sZWFuIGFjdHVhbCkgeworICAgIGFzc2VydEVxdWFscyhhc3NlcnRJRCxleHBlY3RlZCxhY3R1YWwpOworICB9CisKKyAgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKERPTVRlc3RDYXNlIHRlc3QsIFN0cmluZyBhc3NlcnRJRCwgZG91YmxlIGV4cGVjdGVkLCBkb3VibGUgYWN0dWFsKSB7CisgICAgICBhc3NlcnRFcXVhbHMoYXNzZXJ0SUQsIGV4cGVjdGVkLCBhY3R1YWwsIDAuMCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoRE9NVGVzdENhc2UgdGVzdCwgU3RyaW5nIGFzc2VydElELCBDb2xsZWN0aW9uIGV4cGVjdGVkLCBDb2xsZWN0aW9uIGFjdHVhbCkgeworICAgIGludCBzaXplID0gZXhwZWN0ZWQuc2l6ZSgpOworICAgIGFzc2VydE5vdE51bGwoYXNzZXJ0SUQsZXhwZWN0ZWQpOworICAgIGFzc2VydE5vdE51bGwoYXNzZXJ0SUQsYWN0dWFsKTsKKyAgICBhc3NlcnRFcXVhbHMoYXNzZXJ0SUQsc2l6ZSwgYWN0dWFsLnNpemUoKSk7CisgICAgYm9vbGVhbiBlcXVhbHMgPSAoZXhwZWN0ZWQgIT0gbnVsbCAmJiBhY3R1YWwgIT0gbnVsbCAmJiBzaXplID09IGFjdHVhbC5zaXplKCkpOworICAgIGlmKGVxdWFscykgeworICAgICAgTGlzdCBleHBlY3RlZEFycmF5ID0gbmV3IEFycmF5TGlzdChleHBlY3RlZCk7CisgICAgICBPYmplY3QgZXhwZWN0ZWRPYmo7CisgICAgICBPYmplY3QgYWN0dWFsT2JqOworICAgICAgSXRlcmF0b3IgYWN0dWFsSXRlciA9IGFjdHVhbC5pdGVyYXRvcigpOworICAgICAgSXRlcmF0b3IgZXhwZWN0ZWRJdGVyOworICAgICAgd2hpbGUoYWN0dWFsSXRlci5oYXNOZXh0KCkgJiYgZXF1YWxzKSB7CisgICAgICAgIGFjdHVhbE9iaiA9IGFjdHVhbEl0ZXIubmV4dCgpOworICAgICAgICBleHBlY3RlZEl0ZXIgPSBleHBlY3RlZEFycmF5Lml0ZXJhdG9yKCk7CisgICAgICAgIGVxdWFscyA9IGZhbHNlOworICAgICAgICB3aGlsZShleHBlY3RlZEl0ZXIuaGFzTmV4dCgpICYmICFlcXVhbHMpIHsKKyAgICAgICAgICBleHBlY3RlZE9iaiA9IGV4cGVjdGVkSXRlci5uZXh0KCk7CisgICAgICAgICAgaWYoZXhwZWN0ZWRPYmogPT0gYWN0dWFsT2JqIHx8IGV4cGVjdGVkT2JqLmVxdWFscyhhY3R1YWxPYmopKSB7CisgICAgICAgICAgICBlcXVhbHMgPSB0cnVlOworICAgICAgICAgICAgZXhwZWN0ZWRBcnJheS5yZW1vdmUoZXhwZWN0ZWRPYmopOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICBhc3NlcnRUcnVlKGFzc2VydElELGVxdWFscyk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnROb3RFcXVhbHNJZ25vcmVDYXNlKERPTVRlc3RDYXNlIHRlc3QsIFN0cmluZyBhc3NlcnRJRCwgU3RyaW5nIGV4cGVjdGVkLCBTdHJpbmcgYWN0dWFsKSB7CisgICAgaWYoZXhwZWN0ZWQuZXF1YWxzSWdub3JlQ2FzZShhY3R1YWwpKSB7CisgICAgICBhc3NlcnRUcnVlKGFzc2VydElELCAhZXhwZWN0ZWQuZXF1YWxzSWdub3JlQ2FzZShhY3R1YWwpKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnROb3RFcXVhbHMoRE9NVGVzdENhc2UgdGVzdCwgU3RyaW5nIGFzc2VydElELCBTdHJpbmcgZXhwZWN0ZWQsIFN0cmluZyBhY3R1YWwpIHsKKyAgICBhc3NlcnRUcnVlKGFzc2VydElELCAhZXhwZWN0ZWQuZXF1YWxzKGFjdHVhbCkpOworICB9CisKKyAgcHVibGljIHZvaWQgYXNzZXJ0Tm90RXF1YWxzKERPTVRlc3RDYXNlIHRlc3QsIFN0cmluZyBhc3NlcnRJRCwgaW50IGV4cGVjdGVkLCBpbnQgYWN0dWFsKSB7CisgICAgYXNzZXJ0VHJ1ZShhc3NlcnRJRCxleHBlY3RlZCAhPWFjdHVhbCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhc3NlcnROb3RFcXVhbHMoRE9NVGVzdENhc2UgdGVzdCwgU3RyaW5nIGFzc2VydElELCBib29sZWFuIGV4cGVjdGVkLCBib29sZWFuIGFjdHVhbCkgeworICAgIGFzc2VydFRydWUoYXNzZXJ0SUQsZXhwZWN0ZWQgIT1hY3R1YWwpOworICB9CisKKworICBwdWJsaWMgdm9pZCBhc3NlcnROb3RFcXVhbHMoRE9NVGVzdENhc2UgdGVzdCwgU3RyaW5nIGFzc2VydElELCBkb3VibGUgZXhwZWN0ZWQsIGRvdWJsZSBhY3R1YWwpIHsKKyAgICBpZihleHBlY3RlZCA9PSBhY3R1YWwpIHsKKyAgICAgIGFzc2VydFRydWUoYXNzZXJ0SUQsZXhwZWN0ZWQgIT0gYWN0dWFsKTsKKyAgICB9CisgIH0KKworCisgIHB1YmxpYyBib29sZWFuIHNhbWUoT2JqZWN0IGV4cGVjdGVkLCBPYmplY3QgYWN0dWFsKSB7CisgICAgYm9vbGVhbiBlcXVhbHMgPSAoZXhwZWN0ZWQgPT0gYWN0dWFsKTsKKyAgICBpZighZXF1YWxzICYmIGV4cGVjdGVkICE9IG51bGwgJiYgZXhwZWN0ZWQgaW5zdGFuY2VvZiBOb2RlICYmCisgICAgICBhY3R1YWwgIT0gbnVsbCAmJiBhY3R1YWwgaW5zdGFuY2VvZiBOb2RlKSB7CisgICAgICAvLworICAgICAgLy8gIGNhbiB1c2UgTm9kZS5pc1NhbWUgZXZlbnR1YWxseQorICAgIH0KKyAgICByZXR1cm4gZXF1YWxzOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzSWdub3JlQ2FzZShTdHJpbmcgZXhwZWN0ZWQsIFN0cmluZyBhY3R1YWwpIHsKKyAgICByZXR1cm4gZXhwZWN0ZWQuZXF1YWxzSWdub3JlQ2FzZShhY3R1YWwpOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzSWdub3JlQ2FzZShDb2xsZWN0aW9uIGV4cGVjdGVkLCBDb2xsZWN0aW9uIGFjdHVhbCkgeworICAgIGludCBzaXplID0gZXhwZWN0ZWQuc2l6ZSgpOworICAgIGJvb2xlYW4gZXF1YWxzID0gKGV4cGVjdGVkICE9IG51bGwgJiYgYWN0dWFsICE9IG51bGwgJiYgc2l6ZSA9PSBhY3R1YWwuc2l6ZSgpKTsKKyAgICBpZihlcXVhbHMpIHsKKyAgICAgIExpc3QgZXhwZWN0ZWRBcnJheSA9IG5ldyBBcnJheUxpc3QoZXhwZWN0ZWQpOworICAgICAgU3RyaW5nIGV4cGVjdGVkU3RyaW5nOworICAgICAgU3RyaW5nIGFjdHVhbFN0cmluZzsKKyAgICAgIEl0ZXJhdG9yIGFjdHVhbEl0ZXIgPSBhY3R1YWwuaXRlcmF0b3IoKTsKKyAgICAgIEl0ZXJhdG9yIGV4cGVjdGVkSXRlcjsKKyAgICAgIHdoaWxlKGFjdHVhbEl0ZXIuaGFzTmV4dCgpICYmIGVxdWFscykgeworICAgICAgICBhY3R1YWxTdHJpbmcgPSAoU3RyaW5nKSBhY3R1YWxJdGVyLm5leHQoKTsKKyAgICAgICAgZXhwZWN0ZWRJdGVyID0gZXhwZWN0ZWRBcnJheS5pdGVyYXRvcigpOworICAgICAgICBlcXVhbHMgPSBmYWxzZTsKKyAgICAgICAgd2hpbGUoZXhwZWN0ZWRJdGVyLmhhc05leHQoKSAmJiAhZXF1YWxzKSB7CisgICAgICAgICAgZXhwZWN0ZWRTdHJpbmcgPSAoU3RyaW5nKSBleHBlY3RlZEl0ZXIubmV4dCgpOworICAgICAgICAgIGlmKGFjdHVhbFN0cmluZy5lcXVhbHNJZ25vcmVDYXNlKGV4cGVjdGVkU3RyaW5nKSkgeworICAgICAgICAgICAgZXF1YWxzID0gdHJ1ZTsKKyAgICAgICAgICAgIGV4cGVjdGVkQXJyYXkucmVtb3ZlKGV4cGVjdGVkU3RyaW5nKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGVxdWFsczsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGVxdWFsc0lnbm9yZUNhc2UoTGlzdCBleHBlY3RlZCwgTGlzdCBhY3R1YWwpIHsKKyAgICBpbnQgc2l6ZSA9IGV4cGVjdGVkLnNpemUoKTsKKyAgICBib29sZWFuIGVxdWFscyA9IChleHBlY3RlZCAhPSBudWxsICYmIGFjdHVhbCAhPSBudWxsICYmIHNpemUgPT0gYWN0dWFsLnNpemUoKSk7CisgICAgaWYoZXF1YWxzKSB7CisgICAgICBTdHJpbmcgZXhwZWN0ZWRTdHJpbmc7CisgICAgICBTdHJpbmcgYWN0dWFsU3RyaW5nOworICAgICAgZm9yKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICBleHBlY3RlZFN0cmluZyA9IChTdHJpbmcpIGV4cGVjdGVkLmdldChpKTsKKyAgICAgICAgYWN0dWFsU3RyaW5nID0gKFN0cmluZykgYWN0dWFsLmdldChpKTsKKyAgICAgICAgaWYoIWV4cGVjdGVkU3RyaW5nLmVxdWFsc0lnbm9yZUNhc2UoYWN0dWFsU3RyaW5nKSkgeworICAgICAgICAgIGVxdWFscyA9IGZhbHNlOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBlcXVhbHM7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoU3RyaW5nIGV4cGVjdGVkLCBTdHJpbmcgYWN0dWFsKSB7CisgICAgcmV0dXJuIGV4cGVjdGVkLmVxdWFscyhhY3R1YWwpOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGludCBleHBlY3RlZCwgaW50IGFjdHVhbCkgeworICAgIHJldHVybiBleHBlY3RlZCA9PSBhY3R1YWw7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoYm9vbGVhbiBleHBlY3RlZCwgYm9vbGVhbiBhY3R1YWwpIHsKKyAgICByZXR1cm4gZXhwZWN0ZWQgPT0gYWN0dWFsOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGRvdWJsZSBleHBlY3RlZCwgZG91YmxlIGFjdHVhbCkgeworICAgIHJldHVybiBleHBlY3RlZCA9PSBhY3R1YWw7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoQ29sbGVjdGlvbiBleHBlY3RlZCwgQ29sbGVjdGlvbiBhY3R1YWwpIHsKKyAgICBpbnQgc2l6ZSA9IGV4cGVjdGVkLnNpemUoKTsKKyAgICBib29sZWFuIGVxdWFscyA9IChleHBlY3RlZCAhPSBudWxsICYmIGFjdHVhbCAhPSBudWxsICYmIHNpemUgPT0gYWN0dWFsLnNpemUoKSk7CisgICAgaWYoZXF1YWxzKSB7CisgICAgICBMaXN0IGV4cGVjdGVkQXJyYXkgPSBuZXcgQXJyYXlMaXN0KGV4cGVjdGVkKTsKKyAgICAgIE9iamVjdCBleHBlY3RlZE9iajsKKyAgICAgIE9iamVjdCBhY3R1YWxPYmo7CisgICAgICBJdGVyYXRvciBhY3R1YWxJdGVyID0gYWN0dWFsLml0ZXJhdG9yKCk7CisgICAgICBJdGVyYXRvciBleHBlY3RlZEl0ZXI7CisgICAgICB3aGlsZShhY3R1YWxJdGVyLmhhc05leHQoKSAmJiBlcXVhbHMpIHsKKyAgICAgICAgYWN0dWFsT2JqID0gYWN0dWFsSXRlci5uZXh0KCk7CisgICAgICAgIGV4cGVjdGVkSXRlciA9IGV4cGVjdGVkQXJyYXkuaXRlcmF0b3IoKTsKKyAgICAgICAgZXF1YWxzID0gZmFsc2U7CisgICAgICAgIHdoaWxlKGV4cGVjdGVkSXRlci5oYXNOZXh0KCkgJiYgIWVxdWFscykgeworICAgICAgICAgIGV4cGVjdGVkT2JqID0gZXhwZWN0ZWRJdGVyLm5leHQoKTsKKyAgICAgICAgICBpZihleHBlY3RlZE9iaiAhPSBhY3R1YWxPYmogJiYgZXhwZWN0ZWRPYmouZXF1YWxzKGFjdHVhbE9iaikpIHsKKyAgICAgICAgICAgIGVxdWFscyA9IHRydWU7CisgICAgICAgICAgICBleHBlY3RlZEFycmF5LnJlbW92ZShleHBlY3RlZE9iaik7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBlcXVhbHM7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoTGlzdCBleHBlY3RlZCwgTGlzdCBhY3R1YWwpIHsKKyAgICBpbnQgc2l6ZSA9IGV4cGVjdGVkLnNpemUoKTsKKyAgICBib29sZWFuIGVxdWFscyA9IChleHBlY3RlZCAhPSBudWxsICYmIGFjdHVhbCAhPSBudWxsICYmIHNpemUgPT0gYWN0dWFsLnNpemUoKSk7CisgICAgaWYoZXF1YWxzKSB7CisgICAgICBPYmplY3QgZXhwZWN0ZWRPYmo7CisgICAgICBPYmplY3QgYWN0dWFsT2JqOworICAgICAgZm9yKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICBleHBlY3RlZE9iaiA9IGV4cGVjdGVkLmdldChpKTsKKyAgICAgICAgYWN0dWFsT2JqID0gYWN0dWFsLmdldChpKTsKKyAgICAgICAgaWYoIWV4cGVjdGVkT2JqLmVxdWFscyhhY3R1YWxPYmopKSB7CisgICAgICAgICAgZXF1YWxzID0gZmFsc2U7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGVxdWFsczsKKyAgfQorCisgIHB1YmxpYyBpbnQgc2l6ZShDb2xsZWN0aW9uIGNvbGxlY3Rpb24pIHsKKyAgICByZXR1cm4gY29sbGVjdGlvbi5zaXplKCk7CisgIH0KKworICBwdWJsaWMgaW50IHNpemUoTmFtZWROb2RlTWFwIGNvbGxlY3Rpb24pIHsKKyAgICByZXR1cm4gY29sbGVjdGlvbi5nZXRMZW5ndGgoKTsKKyAgfQorCisgIHB1YmxpYyBpbnQgc2l6ZShOb2RlTGlzdCBjb2xsZWN0aW9uKSB7CisgICAgcmV0dXJuIGNvbGxlY3Rpb24uZ2V0TGVuZ3RoKCk7CisgIH0KKworCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9KVW5pdFRlc3RTdWl0ZUFkYXB0ZXIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvSlVuaXRUZXN0U3VpdGVBZGFwdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjJmY2FkMwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvSlVuaXRUZXN0U3VpdGVBZGFwdGVyLmphdmEKQEAgLTAsMCArMSw2NCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210czsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworcHVibGljIGNsYXNzIEpVbml0VGVzdFN1aXRlQWRhcHRlciBleHRlbmRzIFRlc3RTdWl0ZSBpbXBsZW1lbnRzIERPTVRlc3RTaW5rICB7CisKKyAgcHJpdmF0ZSBET01UZXN0U3VpdGUgdGVzdDsKKworICBwdWJsaWMgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKERPTVRlc3RTdWl0ZSB0ZXN0KSB7CisgICAgc3VwZXIodGVzdC5nZXRUYXJnZXRVUkkoKSk7CisgICAgdGhpcy50ZXN0ID0gdGVzdDsKKyAgICB0ZXN0LmJ1aWxkKHRoaXMpOworICB9CisKKyAgcHVibGljIHZvaWQgYWRkVGVzdChDbGFzcyB0ZXN0Y2xhc3MpIHsKKyAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0gdGVzdC5nZXRGYWN0b3J5KCk7CisgICAgdHJ5IHsKKyAgICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9IHRlc3RjbGFzcy5nZXRDb25zdHJ1Y3RvcigKKyAgICAgICAgICBuZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0gKTsKKyAgICAgICAgLy8KKyAgICAgICAgLy8gICBzaW5jZSB0aGlzIGlzIGRvbmUgd2l0aCByZWZsZWN0aW9uCisgICAgICAgIC8vICAgICBhbnkgZXhjZXB0aW9uIG9uIGNvbnN0cnVjdGlvbiBpcyB3cmFwcGVkIHdpdGgKKyAgICAgICAgLy8gICAgIGFuIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gYW5kIG11c3QgYmUgdW53cmFwcGVkCisgICAgICBPYmplY3QgZG9tdGVzdDsKKyAgICAgIHRyeSB7CisgICAgICAgIGRvbXRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKyAgICAgIH0gY2F0Y2goSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBleCkgeworICAgICAgICB0aHJvdyBleC5nZXRUYXJnZXRFeGNlcHRpb24oKTsKKyAgICAgIH0KKworICAgICAgaWYoZG9tdGVzdCBpbnN0YW5jZW9mIERPTVRlc3RDYXNlKSB7CisgICAgICAgIFRlc3RDYXNlIHRlc3QgPSBuZXcgSlVuaXRUZXN0Q2FzZUFkYXB0ZXIoKERPTVRlc3RDYXNlKSBkb210ZXN0KTsKKyAgICAgICAgYWRkVGVzdCh0ZXN0KTsKKyAgICAgIH0KKyAgICAgIGVsc2UgeworICAgICAgICBpZihkb210ZXN0IGluc3RhbmNlb2YgRE9NVGVzdFN1aXRlKSB7CisgICAgICAgICAgVGVzdFN1aXRlIHRlc3QgPSBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIGRvbXRlc3QpOworICAgICAgICAgIGFkZFRlc3QodGVzdCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgY2F0Y2goVGhyb3dhYmxlIGV4KSB7CisgICAgICBpZighKGV4IGluc3RhbmNlb2YgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbikpIHsKKyAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICB9CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0p1bml0VGVzdENhc2VzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0p1bml0VGVzdENhc2VzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGExYjZhYgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvSnVuaXRUZXN0Q2FzZXMuamF2YQpAQCAtMCwwICsxLDIxODkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcudzNjLmRvbXRzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFdyYXBwZXIgY2xhc3MgdG8gbWFrZSB0aGUgVzNDIERPTSB0ZXN0IHdvcmsgYXMgSlVuaXQgdGVzdCBjYXNlcy4gTm90ZSB0aGlzCisgKiBmaWxlIGhhcyBiZWVuIGdlbmVyYXRlZCwgc28gdGhlIG1ldGhvZCBuYW1lcyBtYXkgYmUgY3J5cHRpYyBhbmQgYWxzbyBiZQorICogbG9uZ2VyIHRoYW4gODAgY2hhcmFjdGVycyBwZXIgbGluZS4KKyAqLworcHVibGljIGNsYXNzIEp1bml0VGVzdENhc2VzIGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSB2b2lkIHJ1bkRvbVRlc3QoU3RyaW5nIG5hbWUpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBKVW5pdFRlc3RDYXNlQWRhcHRlciBhZGFwdGVyID0gbmV3IEpVbml0VGVzdENhc2VBZGFwdGVyKCk7CisgICAgICAgIGFkYXB0ZXIuc2V0TmFtZShuYW1lKTsKKyAgICAgICAgYWRhcHRlci5ydW5UZXN0KCk7CisgICAgfQorICAgIAorICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfYXR0cmNyZWF0ZWRvY3VtZW50ZnJhZ21lbnQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvYXR0cmNyZWF0ZWRvY3VtZW50ZnJhZ21lbnQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2F0dHJjcmVhdGV0ZXh0bm9kZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9hdHRyY3JlYXRldGV4dG5vZGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2F0dHJjcmVhdGV0ZXh0bm9kZTIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvYXR0cmNyZWF0ZXRleHRub2RlMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfYXR0cmVmZmVjdGl2ZXZhbHVlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2F0dHJlZmZlY3RpdmV2YWx1ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfYXR0cm5hbWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvYXR0cm5hbWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2F0dHJuZXh0c2libGluZ251bGwoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvYXR0cm5leHRzaWJsaW5nbnVsbCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfYXR0cnBhcmVudG5vZGVudWxsKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2F0dHJwYXJlbnRub2RlbnVsbCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfYXR0cnByZXZpb3Vzc2libGluZ251bGwoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvYXR0cnByZXZpb3Vzc2libGluZ251bGwiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2F0dHJzcGVjaWZpZWR2YWx1ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9hdHRyc3BlY2lmaWVkdmFsdWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2F0dHJzcGVjaWZpZWR2YWx1ZWNoYW5nZWQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvYXR0cnNwZWNpZmllZHZhbHVlY2hhbmdlZCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfY2RhdGFzZWN0aW9uZ2V0ZGF0YSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jZGF0YXNlY3Rpb25nZXRkYXRhIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9jaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGFnZXRkYXRhKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhZ2V0ZGF0YSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFiZWdpbmluZygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWJlZ2luaW5nIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWVuZCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWVuZCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFleGNlZWRzbGVuZ3RoKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZXhjZWVkc2xlbmd0aCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFnZXRsZW5ndGhhbmRkYXRhKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZ2V0bGVuZ3RoYW5kZGF0YSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFtaWRkbGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFtaWRkbGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2NoYXJhY3RlcmRhdGFnZXRkYXRhKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFnZXRkYXRhIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9jaGFyYWN0ZXJkYXRhZ2V0bGVuZ3RoKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFnZXRsZW5ndGgiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhYmVnaW5uaW5nKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhYmVnaW5uaW5nIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YWVuZCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YWVuZCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfY2hhcmFjdGVyZGF0YWluc2VydGRhdGFtaWRkbGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluc2VydGRhdGFtaWRkbGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWJlZ2luaW5nKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWJlZ2luaW5nIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFlbmQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZW5kIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFleGNlZWRzbGVuZ3Rob2ZhcmcoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZXhjZWVkc2xlbmd0aG9mYXJnIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFleGNlZWRzbGVuZ3Rob2ZkYXRhKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWV4Y2VlZHNsZW5ndGhvZmRhdGEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YW1pZGRsZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFtaWRkbGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2NoYXJhY3RlcmRhdGFzdWJzdHJpbmd2YWx1ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhc3Vic3RyaW5ndmFsdWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2NvbW1lbnRnZXRjb21tZW50KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NvbW1lbnRnZXRjb21tZW50Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9kb2N1bWVudGNyZWF0ZWNkYXRhc2VjdGlvbigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZWNkYXRhc2VjdGlvbiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZG9jdW1lbnRjcmVhdGVjb21tZW50KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlY29tbWVudCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZG9jdW1lbnRjcmVhdGVkb2N1bWVudGZyYWdtZW50KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlZG9jdW1lbnRmcmFnbWVudCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZG9jdW1lbnRjcmVhdGVlbGVtZW50KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZG9jdW1lbnRjcmVhdGVlbGVtZW50Y2FzZXNlbnNpdGl2ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZWVsZW1lbnRjYXNlc2Vuc2l0aXZlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9kb2N1bWVudGNyZWF0ZWVudGl0eXJlZmVyZW5jZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZWVudGl0eXJlZmVyZW5jZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZG9jdW1lbnRjcmVhdGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb24oKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb24iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2RvY3VtZW50Y3JlYXRldGV4dG5vZGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGV0ZXh0bm9kZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZG9jdW1lbnRnZXRkb2N0eXBlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0ZG9jdHlwZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZG9jdW1lbnRnZXRkb2N0eXBlbm9kdGQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9jdW1lbnRnZXRkb2N0eXBlbm9kdGQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVsZW5ndGgoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZWxlbmd0aCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZXZhbHVlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV2YWx1ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZG9jdW1lbnRnZXRpbXBsZW1lbnRhdGlvbigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGdldGltcGxlbWVudGF0aW9uIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9kb2N1bWVudGdldHJvb3Rub2RlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0cm9vdG5vZGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWF0dHJpYnV0ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVhdHRyaWJ1dGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWVsZW1lbnQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlZWxlbWVudCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZG9jdW1lbnR0eXBlZ2V0ZG9jdHlwZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudHR5cGVnZXRkb2N0eXBlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVub3ZlcnNpb24oKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9taW1wbGVtZW50YXRpb25mZWF0dXJlbm92ZXJzaW9uIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVudWxsKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZW51bGwiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZXhtbCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmV4bWwiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2VsZW1lbnRhZGRuZXdhdHRyaWJ1dGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudGFkZG5ld2F0dHJpYnV0ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZWxlbWVudGFzc29jaWF0ZWRhdHRyaWJ1dGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudGFzc29jaWF0ZWRhdHRyaWJ1dGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2VsZW1lbnRjaGFuZ2VhdHRyaWJ1dGV2YWx1ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50Y2hhbmdlYXR0cmlidXRldmFsdWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9lbGVtZW50Z2V0YXR0cmlidXRlbm9kZW51bGwoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVudWxsIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVhY2Nlc3Nub2RlbGlzdCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVhY2Nlc3Nub2RlbGlzdCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbm9tYXRjaCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVub21hdGNoIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9lbGVtZW50Z2V0dGFnbmFtZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50Z2V0dGFnbmFtZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZWxlbWVudGludXNlYXR0cmlidXRlZXJyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnRpbnVzZWF0dHJpYnV0ZWVyciIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZWxlbWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb24oKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb24iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2VsZW1lbnRub3JtYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudG5vcm1hbGl6ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZWxlbWVudG5vdGZvdW5kZXJyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnRub3Rmb3VuZGVyciIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZWxlbWVudHJlbW92ZWF0dHJpYnV0ZWFmdGVyY3JlYXRlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVhZnRlcmNyZWF0ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vZGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vZGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2VsZW1lbnRyZXBsYWNlZXhpc3RpbmdhdHRyaWJ1dGVnZXZhbHVlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnRyZXBsYWNlZXhpc3RpbmdhdHRyaWJ1dGVnZXZhbHVlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9lbGVtZW50cmV0cmlldmVhdHRydmFsdWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudHJldHJpZXZlYXR0cnZhbHVlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9lbGVtZW50cmV0cmlldmV0YWduYW1lKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnRyZXRyaWV2ZXRhZ25hbWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnVsbCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9kZW51bGwiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2VsZW1lbnR3cm9uZ2RvY3VtZW50ZXJyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnR3cm9uZ2RvY3VtZW50ZXJyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9uYW1lZG5vZGVtYXBjaGlsZG5vZGVyYW5nZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXBjaGlsZG5vZGVyYW5nZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbmFtZWRub2RlbWFwaW51c2VhdHRyaWJ1dGVlcnIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwaW51c2VhdHRyaWJ1dGVlcnIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25hbWVkbm9kZW1hcG5vdGZvdW5kZXJyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcG5vdGZvdW5kZXJyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9uYW1lZG5vZGVtYXBudW1iZXJvZm5vZGVzKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcG51bWJlcm9mbm9kZXMiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbXJldHVybm5vZGV2YWx1ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1yZXR1cm5ub2RldmFsdWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25hbWVkbm9kZW1hcHJldHVybmF0dHJub2RlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHJldHVybmF0dHJub2RlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9uYW1lZG5vZGVtYXByZXR1cm5maXJzdGl0ZW0oKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwcmV0dXJuZmlyc3RpdGVtIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9uYW1lZG5vZGVtYXByZXR1cm5sYXN0aXRlbSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXByZXR1cm5sYXN0aXRlbSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbmFtZWRub2RlbWFwcmV0dXJubnVsbCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXByZXR1cm5udWxsIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW0oKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1yZXR1cm52YWx1ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1yZXR1cm52YWx1ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtd2l0aG5ld3ZhbHVlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXdpdGhuZXd2YWx1ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbmFtZWRub2RlbWFwd3Jvbmdkb2N1bWVudGVycigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXB3cm9uZ2RvY3VtZW50ZXJyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlYXBwZW5kY2hpbGQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlYXBwZW5kY2hpbGRnZXRub2RlbmFtZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlYXBwZW5kY2hpbGRnZXRub2RlbmFtZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbm9kZWFwcGVuZGNoaWxkbmV3Y2hpbGRkaWZmZG9jdW1lbnQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkbmV3Y2hpbGRkaWZmZG9jdW1lbnQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVhcHBlbmRjaGlsZG5vZGVhbmNlc3RvcigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlYXBwZW5kY2hpbGRub2RlYW5jZXN0b3IiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVhdHRyaWJ1dGVub2RlYXR0cmlidXRlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVhdHRyaWJ1dGVub2RlYXR0cmlidXRlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlYXR0cmlidXRlbm9kZW5hbWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWF0dHJpYnV0ZW5vZGVuYW1lIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlYXR0cmlidXRlbm9kZXR5cGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWF0dHJpYnV0ZW5vZGV0eXBlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlYXR0cmlidXRlbm9kZXZhbHVlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVhdHRyaWJ1dGVub2RldmFsdWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVjZGF0YXNlY3Rpb25ub2RlYXR0cmlidXRlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVjZGF0YXNlY3Rpb25ub2RlYXR0cmlidXRlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlY2RhdGFzZWN0aW9ubm9kZW5hbWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWNkYXRhc2VjdGlvbm5vZGVuYW1lIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlY2RhdGFzZWN0aW9ubm9kZXR5cGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWNkYXRhc2VjdGlvbm5vZGV0eXBlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlY2RhdGFzZWN0aW9ubm9kZXZhbHVlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVjZGF0YXNlY3Rpb25ub2RldmFsdWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVjaGlsZG5vZGVzKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVjaGlsZG5vZGVzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlY2hpbGRub2Rlc2VtcHR5KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVjaGlsZG5vZGVzZW1wdHkiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVjb21tZW50bm9kZWF0dHJpYnV0ZXMoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWNvbW1lbnRub2RlYXR0cmlidXRlcyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbm9kZWNvbW1lbnRub2RlbmFtZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlY29tbWVudG5vZGVuYW1lIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlY29tbWVudG5vZGV0eXBlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVjb21tZW50bm9kZXR5cGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVjb21tZW50bm9kZXZhbHVlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVjb21tZW50bm9kZXZhbHVlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGVuYW1lKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVkb2N1bWVudGZyYWdtZW50bm9kZW5hbWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVkb2N1bWVudGZyYWdtZW50bm9kZXR5cGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldHlwZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldmFsdWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldmFsdWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVkb2N1bWVudG5vZGVhdHRyaWJ1dGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50bm9kZWF0dHJpYnV0ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbm9kZWRvY3VtZW50bm9kZW5hbWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50bm9kZW5hbWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVkb2N1bWVudG5vZGV0eXBlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVkb2N1bWVudG5vZGV0eXBlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZG9jdW1lbnRub2RldmFsdWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50bm9kZXZhbHVlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZG9jdW1lbnR0eXBlbm9kZW5hbWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50dHlwZW5vZGVuYW1lIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZG9jdW1lbnR0eXBlbm9kZXR5cGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50dHlwZW5vZGV0eXBlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZG9jdW1lbnR0eXBlbm9kZXZhbHVlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVkb2N1bWVudHR5cGVub2RldmFsdWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVlbGVtZW50bm9kZWF0dHJpYnV0ZXMoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWVsZW1lbnRub2RlYXR0cmlidXRlcyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbm9kZWVsZW1lbnRub2RlbmFtZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZWxlbWVudG5vZGVuYW1lIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZWxlbWVudG5vZGV0eXBlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVlbGVtZW50bm9kZXR5cGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVlbGVtZW50bm9kZXZhbHVlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVlbGVtZW50bm9kZXZhbHVlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZW50aXR5cmVmZXJlbmNlbm9kZWF0dHJpYnV0ZXMoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWVudGl0eXJlZmVyZW5jZW5vZGVhdHRyaWJ1dGVzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZW50aXR5cmVmZXJlbmNlbm9kZW5hbWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWVudGl0eXJlZmVyZW5jZW5vZGVuYW1lIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZW50aXR5cmVmZXJlbmNlbm9kZXR5cGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWVudGl0eXJlZmVyZW5jZW5vZGV0eXBlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZW50aXR5cmVmZXJlbmNlbm9kZXZhbHVlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVlbnRpdHlyZWZlcmVuY2Vub2RldmFsdWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVnZXRmaXJzdGNoaWxkKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVnZXRmaXJzdGNoaWxkIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZ2V0Zmlyc3RjaGlsZG51bGwoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWdldGZpcnN0Y2hpbGRudWxsIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZ2V0bGFzdGNoaWxkKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVnZXRsYXN0Y2hpbGQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVnZXRsYXN0Y2hpbGRudWxsKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVnZXRsYXN0Y2hpbGRudWxsIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZ2V0bmV4dHNpYmxpbmcoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWdldG5leHRzaWJsaW5nIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZ2V0bmV4dHNpYmxpbmdudWxsKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVnZXRuZXh0c2libGluZ251bGwiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVnZXRvd25lcmRvY3VtZW50KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVnZXRvd25lcmRvY3VtZW50Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZ2V0b3duZXJkb2N1bWVudG51bGwoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWdldG93bmVyZG9jdW1lbnRudWxsIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlZ2V0cHJldmlvdXNzaWJsaW5nKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVnZXRwcmV2aW91c3NpYmxpbmciKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVnZXRwcmV2aW91c3NpYmxpbmdudWxsKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVnZXRwcmV2aW91c3NpYmxpbmdudWxsIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlaGFzY2hpbGRub2RlcygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlaGFzY2hpbGRub2RlcyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbm9kZWhhc2NoaWxkbm9kZXNmYWxzZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlaGFzY2hpbGRub2Rlc2ZhbHNlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlaW5zZXJ0YmVmb3JlbmV3Y2hpbGRkaWZmZG9jdW1lbnQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZW5ld2NoaWxkZGlmZmRvY3VtZW50Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlaW5zZXJ0YmVmb3JlbmV3Y2hpbGRleGlzdHMoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZW5ld2NoaWxkZXhpc3RzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlaW5zZXJ0YmVmb3Jlbm9kZWFuY2VzdG9yKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmVub2RlYW5jZXN0b3IiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVpbnNlcnRiZWZvcmVub2RlbmFtZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3Jlbm9kZW5hbWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVsaXN0aW5kZXhlcXVhbHplcm8oKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWxpc3RpbmRleGVxdWFsemVybyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbm9kZWxpc3RpbmRleGdldGxlbmd0aCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlbGlzdGluZGV4Z2V0bGVuZ3RoIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlbGlzdGluZGV4Z2V0bGVuZ3Rob2ZlbXB0eWxpc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWxpc3RpbmRleGdldGxlbmd0aG9mZW1wdHlsaXN0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlbGlzdGluZGV4bm90emVybygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlbGlzdGluZGV4bm90emVybyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbm9kZWxpc3RyZXR1cm5maXJzdGl0ZW0oKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWxpc3RyZXR1cm5maXJzdGl0ZW0iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVsaXN0cmV0dXJubGFzdGl0ZW0oKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWxpc3RyZXR1cm5sYXN0aXRlbSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbm9kZWxpc3R0cmF2ZXJzZWxpc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWxpc3R0cmF2ZXJzZWxpc3QiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVwYXJlbnRub2RlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVwYXJlbnRub2RlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlcGFyZW50bm9kZW51bGwoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXBhcmVudG5vZGVudWxsIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZWF0dHJpYnV0ZXMoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXByb2Nlc3NpbmdpbnN0cnVjdGlvbm5vZGVhdHRyaWJ1dGVzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZW5hbWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXByb2Nlc3NpbmdpbnN0cnVjdGlvbm5vZGVuYW1lIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZXR5cGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXByb2Nlc3NpbmdpbnN0cnVjdGlvbm5vZGV0eXBlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZXZhbHVlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25ub2RldmFsdWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVyZW1vdmVjaGlsZCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlcmVtb3ZlY2hpbGQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVyZW1vdmVjaGlsZGdldG5vZGVuYW1lKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVyZW1vdmVjaGlsZGdldG5vZGVuYW1lIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlcmVwbGFjZWNoaWxkbmV3Y2hpbGRkaWZmZG9jdW1lbnQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG5ld2NoaWxkZGlmZmRvY3VtZW50Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RlcmVwbGFjZWNoaWxkbm9kZWFuY2VzdG9yKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVyZXBsYWNlY2hpbGRub2RlYW5jZXN0b3IiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGVyZXBsYWNlY2hpbGRub2RlbmFtZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlcmVwbGFjZWNoaWxkbm9kZW5hbWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGV0ZXh0bm9kZWF0dHJpYnV0ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RldGV4dG5vZGVhdHRyaWJ1dGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGV0ZXh0bm9kZW5hbWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXRleHRub2RlbmFtZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbm9kZXRleHRub2RldHlwZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RldGV4dG5vZGV0eXBlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RldGV4dG5vZGV2YWx1ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RldGV4dG5vZGV2YWx1ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfcHJvY2Vzc2luZ2luc3RydWN0aW9uZ2V0ZGF0YSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9wcm9jZXNzaW5naW5zdHJ1Y3Rpb25nZXRkYXRhIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9wcm9jZXNzaW5naW5zdHJ1Y3Rpb25nZXR0YXJnZXQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvcHJvY2Vzc2luZ2luc3RydWN0aW9uZ2V0dGFyZ2V0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV90ZXh0c3BsaXR0ZXh0Zm91cigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0Zm91ciIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfdGV4dHNwbGl0dGV4dG9uZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0b25lIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV90ZXh0c3BsaXR0ZXh0dGhyZWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvdGV4dHNwbGl0dGV4dHRocmVlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV90ZXh0d2l0aG5vbWFya3VwKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL3RleHR3aXRobm9tYXJrdXAiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGV2YWx1ZTAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGV2YWx1ZTAxIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RldmFsdWUwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RldmFsdWUwMyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfbm9kZXZhbHVlMDQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXZhbHVlMDQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX25vZGV2YWx1ZTA1KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGV2YWx1ZTA1Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9ub2RldmFsdWUwNigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RldmFsdWUwNiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfYXR0cmNyZWF0ZWRvY3VtZW50ZnJhZ21lbnQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cmNyZWF0ZWRvY3VtZW50ZnJhZ21lbnQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2F0dHJjcmVhdGV0ZXh0bm9kZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRyY3JlYXRldGV4dG5vZGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2F0dHJjcmVhdGV0ZXh0bm9kZTIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cmNyZWF0ZXRleHRub2RlMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfYXR0cmVmZmVjdGl2ZXZhbHVlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJlZmZlY3RpdmV2YWx1ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfYXR0cm5hbWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cm5hbWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2F0dHJuZXh0c2libGluZ251bGwoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cm5leHRzaWJsaW5nbnVsbCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfYXR0cnBhcmVudG5vZGVudWxsKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJwYXJlbnRub2RlbnVsbCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfYXR0cnByZXZpb3Vzc2libGluZ251bGwoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cnByZXZpb3Vzc2libGluZ251bGwiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2F0dHJzcGVjaWZpZWR2YWx1ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRyc3BlY2lmaWVkdmFsdWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2F0dHJzcGVjaWZpZWR2YWx1ZWNoYW5nZWQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cnNwZWNpZmllZHZhbHVlY2hhbmdlZCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhZ2V0ZGF0YSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YWdldGRhdGEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhYmVnaW5pbmcoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFiZWdpbmluZyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFlbmQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFlbmQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZXhjZWVkc2xlbmd0aCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWV4Y2VlZHNsZW5ndGgiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZ2V0bGVuZ3RoYW5kZGF0YSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWdldGxlbmd0aGFuZGRhdGEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhbWlkZGxlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhbWlkZGxlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19jaGFyYWN0ZXJkYXRhZ2V0ZGF0YSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhZ2V0ZGF0YSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfY2hhcmFjdGVyZGF0YWdldGxlbmd0aCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhZ2V0bGVuZ3RoIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YWJlZ2lubmluZygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YWJlZ2lubmluZyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfY2hhcmFjdGVyZGF0YWluc2VydGRhdGFlbmQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluc2VydGRhdGFlbmQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhbWlkZGxlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhbWlkZGxlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFiZWdpbmluZygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFiZWdpbmluZyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZW5kKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWVuZCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZXhjZWVkc2xlbmd0aG9mYXJnKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWV4Y2VlZHNsZW5ndGhvZmFyZyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZXhjZWVkc2xlbmd0aG9mZGF0YSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFleGNlZWRzbGVuZ3Rob2ZkYXRhIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFtaWRkbGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhbWlkZGxlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19jaGFyYWN0ZXJkYXRhc3Vic3RyaW5ndmFsdWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YXN1YnN0cmluZ3ZhbHVlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19jb21tZW50Z2V0Y29tbWVudCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jb21tZW50Z2V0Y29tbWVudCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZG9jdW1lbnRjcmVhdGVjb21tZW50KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Y3JlYXRlY29tbWVudCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZG9jdW1lbnRjcmVhdGVkb2N1bWVudGZyYWdtZW50KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Y3JlYXRlZG9jdW1lbnRmcmFnbWVudCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZG9jdW1lbnRjcmVhdGVlbGVtZW50KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Y3JlYXRlZWxlbWVudCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZG9jdW1lbnRjcmVhdGVlbGVtZW50Y2FzZXNlbnNpdGl2ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19kb2N1bWVudGNyZWF0ZWVsZW1lbnRjYXNlc2Vuc2l0aXZlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19kb2N1bWVudGNyZWF0ZXRleHRub2RlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Y3JlYXRldGV4dG5vZGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2RvY3VtZW50Z2V0ZG9jdHlwZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19kb2N1bWVudGdldGRvY3R5cGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVsZW5ndGgoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZWxlbmd0aCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZXRvdGFsbGVuZ3RoKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV0b3RhbGxlbmd0aCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZXZhbHVlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV2YWx1ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZG9jdW1lbnRnZXRpbXBsZW1lbnRhdGlvbigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19kb2N1bWVudGdldGltcGxlbWVudGF0aW9uIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19kb2N1bWVudGdldHJvb3Rub2RlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Z2V0cm9vdG5vZGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWF0dHJpYnV0ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVhdHRyaWJ1dGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWF0dHJpYnV0ZTEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlYXR0cmlidXRlMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlZWxlbWVudCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbGVtZW50Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbGVtZW50MSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbGVtZW50MSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZG9taW1wbGVtZW50YXRpb25mZWF0dXJlbm92ZXJzaW9uKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZW5vdmVyc2lvbiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZG9taW1wbGVtZW50YXRpb25mZWF0dXJlbnVsbCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVudWxsIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmV4bWwoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZG9taW1wbGVtZW50YXRpb25mZWF0dXJleG1sIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19lbGVtZW50YWRkbmV3YXR0cmlidXRlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRhZGRuZXdhdHRyaWJ1dGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2VsZW1lbnRhc3NvY2lhdGVkYXR0cmlidXRlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRhc3NvY2lhdGVkYXR0cmlidXRlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19lbGVtZW50Y2hhbmdlYXR0cmlidXRldmFsdWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGNoYW5nZWF0dHJpYnV0ZXZhbHVlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19lbGVtZW50Z2V0YXR0cmlidXRlbm9kZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50Z2V0YXR0cmlidXRlbm9kZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVudWxsKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnVsbCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lYWNjZXNzbm9kZWxpc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lYWNjZXNzbm9kZWxpc3QiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5vbWF0Y2goKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbm9tYXRjaCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZWxlbWVudGdldHRhZ25hbWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGdldHRhZ25hbWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2VsZW1lbnRpbnVzZWF0dHJpYnV0ZWVycigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50aW51c2VhdHRyaWJ1dGVlcnIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2VsZW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19lbGVtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbjEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb24xIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19lbGVtZW50bm9ybWFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRub3JtYWxpemUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2VsZW1lbnRub3Rmb3VuZGVycigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50bm90Zm91bmRlcnIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJlbW92ZWF0dHJpYnV0ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZWxlbWVudHJlbW92ZWF0dHJpYnV0ZWFmdGVyY3JlYXRlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVhZnRlcmNyZWF0ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vZGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vZGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2VsZW1lbnRyZXBsYWNlZXhpc3RpbmdhdHRyaWJ1dGVnZXZhbHVlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRyZXBsYWNlZXhpc3RpbmdhdHRyaWJ1dGVnZXZhbHVlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19lbGVtZW50cmV0cmlldmVhdHRydmFsdWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJldHJpZXZlYXR0cnZhbHVlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19lbGVtZW50cmV0cmlldmV0YWduYW1lKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRyZXRyaWV2ZXRhZ25hbWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnVsbCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50c2V0YXR0cmlidXRlbm9kZW51bGwiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2VsZW1lbnR3cm9uZ2RvY3VtZW50ZXJyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnR3cm9uZ2RvY3VtZW50ZXJyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW0oKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19uYW1lZG5vZGVtYXBpbnVzZWF0dHJpYnV0ZWVycigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXBpbnVzZWF0dHJpYnV0ZWVyciIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbmFtZWRub2RlbWFwbm90Zm91bmRlcnIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwbm90Zm91bmRlcnIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW0iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25hbWVkbm9kZW1hcHJldHVybmF0dHJub2RlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHJldHVybmF0dHJub2RlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19uYW1lZG5vZGVtYXByZXR1cm5udWxsKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHJldHVybm51bGwiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW0iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXJldHVybnZhbHVlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXJldHVybnZhbHVlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW13aXRobmV3dmFsdWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtd2l0aG5ld3ZhbHVlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19uYW1lZG5vZGVtYXB3cm9uZ2RvY3VtZW50ZXJyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHdyb25nZG9jdW1lbnRlcnIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVhcHBlbmRjaGlsZCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVhcHBlbmRjaGlsZGdldG5vZGVuYW1lKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVhcHBlbmRjaGlsZGdldG5vZGVuYW1lIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19ub2RlYXBwZW5kY2hpbGRuZXdjaGlsZGRpZmZkb2N1bWVudCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGRuZXdjaGlsZGRpZmZkb2N1bWVudCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWFwcGVuZGNoaWxkbm9kZWFuY2VzdG9yKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVhcHBlbmRjaGlsZG5vZGVhbmNlc3RvciIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWF0dHJpYnV0ZW5vZGVhdHRyaWJ1dGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWF0dHJpYnV0ZW5vZGVhdHRyaWJ1dGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVhdHRyaWJ1dGVub2RlbmFtZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlYXR0cmlidXRlbm9kZW5hbWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVhdHRyaWJ1dGVub2RldHlwZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlYXR0cmlidXRlbm9kZXR5cGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVhdHRyaWJ1dGVub2RldmFsdWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWF0dHJpYnV0ZW5vZGV2YWx1ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWNoaWxkbm9kZXMoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWNoaWxkbm9kZXMiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVjaGlsZG5vZGVzZW1wdHkoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWNoaWxkbm9kZXNlbXB0eSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWNvbW1lbnRub2RlYXR0cmlidXRlcygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlY29tbWVudG5vZGVhdHRyaWJ1dGVzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19ub2RlY29tbWVudG5vZGVuYW1lKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVjb21tZW50bm9kZW5hbWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVjb21tZW50bm9kZXR5cGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWNvbW1lbnRub2RldHlwZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWNvbW1lbnRub2RldmFsdWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWNvbW1lbnRub2RldmFsdWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVkb2N1bWVudGZyYWdtZW50bm9kZW5hbWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RlbmFtZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldHlwZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGV0eXBlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGV2YWx1ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGV2YWx1ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWRvY3VtZW50bm9kZWF0dHJpYnV0ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZG9jdW1lbnRub2RlYXR0cmlidXRlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19ub2RlZG9jdW1lbnRub2RlbmFtZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZG9jdW1lbnRub2RlbmFtZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWRvY3VtZW50bm9kZXR5cGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWRvY3VtZW50bm9kZXR5cGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVkb2N1bWVudG5vZGV2YWx1ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZG9jdW1lbnRub2RldmFsdWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVlbGVtZW50bm9kZW5hbWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWVsZW1lbnRub2RlbmFtZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWVsZW1lbnRub2RldHlwZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZWxlbWVudG5vZGV0eXBlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19ub2RlZWxlbWVudG5vZGV2YWx1ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZWxlbWVudG5vZGV2YWx1ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWdldGZpcnN0Y2hpbGQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWdldGZpcnN0Y2hpbGQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVnZXRmaXJzdGNoaWxkbnVsbCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZ2V0Zmlyc3RjaGlsZG51bGwiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVnZXRsYXN0Y2hpbGQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWdldGxhc3RjaGlsZCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWdldGxhc3RjaGlsZG51bGwoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWdldGxhc3RjaGlsZG51bGwiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVnZXRuZXh0c2libGluZygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZ2V0bmV4dHNpYmxpbmciKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVnZXRuZXh0c2libGluZ251bGwoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWdldG5leHRzaWJsaW5nbnVsbCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWdldG93bmVyZG9jdW1lbnQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWdldG93bmVyZG9jdW1lbnQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVnZXRvd25lcmRvY3VtZW50bnVsbCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZ2V0b3duZXJkb2N1bWVudG51bGwiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVnZXRwcmV2aW91c3NpYmxpbmcoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWdldHByZXZpb3Vzc2libGluZyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWdldHByZXZpb3Vzc2libGluZ251bGwoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWdldHByZXZpb3Vzc2libGluZ251bGwiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVoYXNjaGlsZG5vZGVzKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVoYXNjaGlsZG5vZGVzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19ub2RlaGFzY2hpbGRub2Rlc2ZhbHNlKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVoYXNjaGlsZG5vZGVzZmFsc2UiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVpbnNlcnRiZWZvcmVuZXdjaGlsZGRpZmZkb2N1bWVudCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlaW5zZXJ0YmVmb3JlbmV3Y2hpbGRkaWZmZG9jdW1lbnQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVpbnNlcnRiZWZvcmVub2RlYW5jZXN0b3IoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZW5vZGVhbmNlc3RvciIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWluc2VydGJlZm9yZW5vZGVuYW1lKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVpbnNlcnRiZWZvcmVub2RlbmFtZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWxpc3RpbmRleGVxdWFsemVybygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlbGlzdGluZGV4ZXF1YWx6ZXJvIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19ub2RlbGlzdGluZGV4Z2V0bGVuZ3RoKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVsaXN0aW5kZXhnZXRsZW5ndGgiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVsaXN0aW5kZXhnZXRsZW5ndGhvZmVtcHR5bGlzdCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlbGlzdGluZGV4Z2V0bGVuZ3Rob2ZlbXB0eWxpc3QiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVsaXN0aW5kZXhub3R6ZXJvKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVsaXN0aW5kZXhub3R6ZXJvIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19ub2RlbGlzdHJldHVybmZpcnN0aXRlbSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlbGlzdHJldHVybmZpcnN0aXRlbSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZWxpc3RyZXR1cm5sYXN0aXRlbSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlbGlzdHJldHVybmxhc3RpdGVtIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19ub2RlbGlzdHRyYXZlcnNlbGlzdCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlbGlzdHRyYXZlcnNlbGlzdCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZXBhcmVudG5vZGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZXBhcmVudG5vZGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVwYXJlbnRub2RlbnVsbCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlcGFyZW50bm9kZW51bGwiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVyZW1vdmVjaGlsZCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlcmVtb3ZlY2hpbGQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVyZW1vdmVjaGlsZGdldG5vZGVuYW1lKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVyZW1vdmVjaGlsZGdldG5vZGVuYW1lIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19ub2RlcmVwbGFjZWNoaWxkbmV3Y2hpbGRkaWZmZG9jdW1lbnQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZXJlcGxhY2VjaGlsZG5ld2NoaWxkZGlmZmRvY3VtZW50Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19ub2RlcmVwbGFjZWNoaWxkbm9kZWFuY2VzdG9yKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVyZXBsYWNlY2hpbGRub2RlYW5jZXN0b3IiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGVyZXBsYWNlY2hpbGRub2RlbmFtZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlcmVwbGFjZWNoaWxkbm9kZW5hbWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGV0ZXh0bm9kZWF0dHJpYnV0ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RldGV4dG5vZGVhdHRyaWJ1dGUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGV0ZXh0bm9kZW5hbWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZXRleHRub2RlbmFtZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZXRleHRub2RldHlwZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RldGV4dG5vZGV0eXBlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19ub2RldGV4dG5vZGV2YWx1ZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RldGV4dG5vZGV2YWx1ZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZXZhbHVlMDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZXZhbHVlMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGV2YWx1ZTAzKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGV2YWx1ZTAzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19ub2RldmFsdWUwNCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RldmFsdWUwNCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfbm9kZXZhbHVlMDUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZXZhbHVlMDUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX25vZGV2YWx1ZTA2KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGV2YWx1ZTA2Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY190ZXh0c3BsaXR0ZXh0Zm91cigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY190ZXh0c3BsaXR0ZXh0Zm91ciIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfdGV4dHNwbGl0dGV4dG9uZSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY190ZXh0c3BsaXR0ZXh0b25lIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY190ZXh0c3BsaXR0ZXh0dGhyZWUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfdGV4dHNwbGl0dGV4dHRocmVlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY190ZXh0d2l0aG5vbWFya3VwKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX3RleHR3aXRobm9tYXJrdXAiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMV9jb3JlX2hjX2F0dHJhcHBlbmRjaGlsZDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cmFwcGVuZGNoaWxkMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfYXR0cmFwcGVuZGNoaWxkNCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRyYXBwZW5kY2hpbGQ0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDFfY29yZV9oY19hdHRyaW5zZXJ0YmVmb3JlNSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRyaW5zZXJ0YmVmb3JlNSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwxX2NvcmVfaGNfYXR0cmluc2VydGJlZm9yZTcoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cmluc2VydGJlZm9yZTciKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2F0dHJnZXRvd25lcmVsZW1lbnQwMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9hdHRyZ2V0b3duZXJlbGVtZW50MDIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2F0dHJnZXRvd25lcmVsZW1lbnQwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9hdHRyZ2V0b3duZXJlbGVtZW50MDMiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2F0dHJnZXRvd25lcmVsZW1lbnQwNCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9hdHRyZ2V0b3duZXJlbGVtZW50MDQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2F0dHJnZXRvd25lcmVsZW1lbnQwNSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9hdHRyZ2V0b3duZXJlbGVtZW50MDUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2NyZWF0ZUF0dHJpYnV0ZU5TMDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlQXR0cmlidXRlTlMwMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfY3JlYXRlQXR0cmlidXRlTlMwMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9jcmVhdGVBdHRyaWJ1dGVOUzAyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9jcmVhdGVBdHRyaWJ1dGVOUzAzKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2NyZWF0ZUF0dHJpYnV0ZU5TMDMiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2NyZWF0ZUF0dHJpYnV0ZU5TMDQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlQXR0cmlidXRlTlMwNCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfY3JlYXRlQXR0cmlidXRlTlMwNSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9jcmVhdGVBdHRyaWJ1dGVOUzA1Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9jcmVhdGVEb2N1bWVudDAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50MDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2NyZWF0ZURvY3VtZW50MDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnQwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfY3JlYXRlRG9jdW1lbnQwNSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudDA1Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9jcmVhdGVEb2N1bWVudDA2KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50MDYiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2NyZWF0ZURvY3VtZW50MDcoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnQwNyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfY3JlYXRlRG9jdW1lbnRUeXBlMDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnRUeXBlMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2NyZWF0ZURvY3VtZW50VHlwZTAyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50VHlwZTAyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9jcmVhdGVEb2N1bWVudFR5cGUwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudFR5cGUwMyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfY3JlYXRlRWxlbWVudE5TMDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlRWxlbWVudE5TMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2NyZWF0ZUVsZW1lbnROUzAyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2NyZWF0ZUVsZW1lbnROUzAyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9jcmVhdGVFbGVtZW50TlMwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9jcmVhdGVFbGVtZW50TlMwMyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfY3JlYXRlRWxlbWVudE5TMDQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlRWxlbWVudE5TMDQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2NyZWF0ZUVsZW1lbnROUzA1KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2NyZWF0ZUVsZW1lbnROUzA1Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzAxIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzAyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDMoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzAzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA1Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDYoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA2Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDcoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA3Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudGNyZWF0ZWVsZW1lbnROUzAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwNSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGNyZWF0ZWVsZW1lbnROUzA1Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudGNyZWF0ZWVsZW1lbnROUzA2KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDYiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvY3VtZW50Z2V0ZWxlbWVudGJ5aWQwMSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGdldGVsZW1lbnRieWlkMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzAxIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDMoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDMiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzA0KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzA0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwNSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwNSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZG9jdW1lbnRpbXBvcnRub2RlMDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMDIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvY3VtZW50aW1wb3J0bm9kZTA1KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTA1Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudGltcG9ydG5vZGUwNigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwNiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZG9jdW1lbnRpbXBvcnRub2RlMDcoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMDciKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvY3VtZW50aW1wb3J0bm9kZTA4KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTA4Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudGltcG9ydG5vZGUwOSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwOSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZG9jdW1lbnRpbXBvcnRub2RlMTAoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTAiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvY3VtZW50aW1wb3J0bm9kZTExKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTExIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudGltcG9ydG5vZGUxMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUxMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZG9jdW1lbnRpbXBvcnRub2RlMTMoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTMiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvY3VtZW50aW1wb3J0bm9kZTE1KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTE1Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudGltcG9ydG5vZGUxNygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUxNyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZG9jdW1lbnRpbXBvcnRub2RlMTgoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTgiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvY3VtZW50dHlwZWludGVybmFsU3Vic2V0MDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnR0eXBlaW50ZXJuYWxTdWJzZXQwMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZG9jdW1lbnR0eXBlcHVibGljaWQwMSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudHR5cGVwdWJsaWNpZDAxIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb2N1bWVudHR5cGVzeXN0ZW1pZDAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50dHlwZXN5c3RlbWlkMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDMiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwNCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwNSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwNygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDciKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnR0eXBlMDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50dHlwZTAyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50dHlwZTA0KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnR0eXBlMDQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZWNvcmUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9taW1wbGVtZW50YXRpb25mZWF0dXJlY29yZSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZG9taW1wbGVtZW50YXRpb25mZWF0dXJleG1sdmVyc2lvbjIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9taW1wbGVtZW50YXRpb25mZWF0dXJleG1sdmVyc2lvbjIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2RvbWltcGxlbWVudGF0aW9uaGFzZmVhdHVyZTAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uaGFzZmVhdHVyZTAxIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9kb21pbXBsZW1lbnRhdGlvbmhhc2ZlYXR1cmUwMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmhhc2ZlYXR1cmUwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnMwMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnMwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVuczAyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVuczA0KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5zMDQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5zMDUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwNSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZWxlbWVudGhhc2F0dHJpYnV0ZTAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRoYXNhdHRyaWJ1dGUwMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZWxlbWVudGhhc2F0dHJpYnV0ZTAzKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRoYXNhdHRyaWJ1dGUwMyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZWxlbWVudGhhc2F0dHJpYnV0ZTA0KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRoYXNhdHRyaWJ1dGUwNCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZWxlbWVudGhhc2F0dHJpYnV0ZW5zMDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZWxlbWVudGhhc2F0dHJpYnV0ZW5zMDIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2VsZW1lbnRoYXNhdHRyaWJ1dGVuczAzKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRoYXNhdHRyaWJ1dGVuczAzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9lbGVtZW50cmVtb3ZlYXR0cmlidXRlbnMwMSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50cmVtb3ZlYXR0cmlidXRlbnMwMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczAyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczAzKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczA0KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwNCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczA1KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwNSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZWxlbWVudHNldGF0dHJpYnV0ZW5zMDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5zMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2VsZW1lbnRzZXRhdHRyaWJ1dGVuczAyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVuczAyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9lbGVtZW50c2V0YXR0cmlidXRlbnMwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbnMwMyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZWxlbWVudHNldGF0dHJpYnV0ZW5zMDQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5zMDQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2VsZW1lbnRzZXRhdHRyaWJ1dGVuczA1KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVuczA1Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9lbGVtZW50c2V0YXR0cmlidXRlbnMwOCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbnMwOCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZWxlbWVudHNldGF0dHJpYnV0ZW5zdXJpbnVsbCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbnN1cmludWxsIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRBdHRyaWJ1dGVOUzAyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2dldEF0dHJpYnV0ZU5TMDIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2dldEF0dHJpYnV0ZU5TMDMoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0QXR0cmlidXRlTlMwMyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZ2V0QXR0cmlidXRlTlMwNCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9nZXRBdHRyaWJ1dGVOUzA0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRBdHRyaWJ1dGVOUzA1KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2dldEF0dHJpYnV0ZU5TMDUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2dldEF0dHJpYnV0ZU5vZGVOUzAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2dldEF0dHJpYnV0ZU5vZGVOUzAxIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRBdHRyaWJ1dGVOb2RlTlMwMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9nZXRBdHRyaWJ1dGVOb2RlTlMwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfZ2V0RWxlbWVudEJ5SWQwMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9nZXRFbGVtZW50QnlJZDAyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzAyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDMoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzAzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA1Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDYoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA2Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDcoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA3Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDgoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA4Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDkoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA5Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMTAoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzEwIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMTEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzExIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMTIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzEyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMTMoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzEzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMTQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzE0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9nZXROYW1lZEl0ZW1OUzAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2dldE5hbWVkSXRlbU5TMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2dldE5hbWVkSXRlbU5TMDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0TmFtZWRJdGVtTlMwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfaGFzQXR0cmlidXRlMDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2hhc0F0dHJpYnV0ZTAzKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2hhc0F0dHJpYnV0ZTAzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9oYXNBdHRyaWJ1dGVOUzAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2hhc0F0dHJpYnV0ZU5TMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2hhc0F0dHJpYnV0ZU5TMDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlTlMwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfaGFzQXR0cmlidXRlTlMwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGVOUzAzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9oYXNBdHRyaWJ1dGVOUzA1KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2hhc0F0dHJpYnV0ZU5TMDUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2hhc0F0dHJpYnV0ZXMwMSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGVzMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2hhc0F0dHJpYnV0ZXMwMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGVzMDIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2hjX25hbWVkbm9kZW1hcGludmFsaWR0eXBlMSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9oY19uYW1lZG5vZGVtYXBpbnZhbGlkdHlwZTEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2hjX25vZGVkb2N1bWVudGZyYWdtZW50bm9ybWFsaXplMSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9oY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vcm1hbGl6ZTEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2hjX25vZGVkb2N1bWVudGZyYWdtZW50bm9ybWFsaXplMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9oY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vcm1hbGl6ZTIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2ltcG9ydE5vZGUwMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pbXBvcnROb2RlMDIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2ltcG9ydE5vZGUwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pbXBvcnROb2RlMDMiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2ltcG9ydE5vZGUwNCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pbXBvcnROb2RlMDQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2ltcG9ydE5vZGUwOCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pbXBvcnROb2RlMDgiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2ltcG9ydE5vZGUxMCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pbXBvcnROb2RlMTAiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2ltcG9ydE5vZGUxNCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pbXBvcnROb2RlMTQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2ltcG9ydE5vZGUxNSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pbXBvcnROb2RlMTUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2ltcG9ydE5vZGUxNigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pbXBvcnROb2RlMTYiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2ltcG9ydE5vZGUxNygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pbXBvcnROb2RlMTciKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2ludGVybmFsU3Vic2V0MDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaW50ZXJuYWxTdWJzZXQwMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfaXNTdXBwb3J0ZWQwMSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDAxIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9pc1N1cHBvcnRlZDAyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2lzU3VwcG9ydGVkMDQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaXNTdXBwb3J0ZWQwNCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfaXNTdXBwb3J0ZWQwNSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDA1Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9pc1N1cHBvcnRlZDA2KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDYiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2lzU3VwcG9ydGVkMDcoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaXNTdXBwb3J0ZWQwNyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfaXNTdXBwb3J0ZWQwOSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDA5Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9pc1N1cHBvcnRlZDEwKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMTAiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2lzU3VwcG9ydGVkMTEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaXNTdXBwb3J0ZWQxMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfaXNTdXBwb3J0ZWQxMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDEyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9pc1N1cHBvcnRlZDEzKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMTMiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2lzU3VwcG9ydGVkMTQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaXNTdXBwb3J0ZWQxNCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbG9jYWxOYW1lMDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbG9jYWxOYW1lMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX2xvY2FsTmFtZTAyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2xvY2FsTmFtZTAyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9sb2NhbE5hbWUwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9sb2NhbE5hbWUwMyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbG9jYWxOYW1lMDQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbG9jYWxOYW1lMDQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczAzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczA0KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDUoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwNSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwNigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczA2Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDMoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA2Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA3KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDciKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDgoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwOCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwOSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA5Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczAzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA0KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDYoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA3Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA4KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDgiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX25hbWVzcGFjZVVSSTAyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVzcGFjZVVSSTAyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9uYW1lc3BhY2VVUkkwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lc3BhY2VVUkkwMyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbmFtZXNwYWNlVVJJMDQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbmFtZXNwYWNlVVJJMDQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX25vZGVnZXRsb2NhbG5hbWUwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub2RlZ2V0bG9jYWxuYW1lMDMiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX25vZGVnZXRuYW1lc3BhY2V1cmkwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub2RlZ2V0bmFtZXNwYWNldXJpMDMiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX25vZGVnZXRvd25lcmRvY3VtZW50MDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbm9kZWdldG93bmVyZG9jdW1lbnQwMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbm9kZWdldG93bmVyZG9jdW1lbnQwMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub2RlZ2V0b3duZXJkb2N1bWVudDAyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9ub2RlZ2V0cHJlZml4MDMoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbm9kZWdldHByZWZpeDAzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9ub2RlaGFzYXR0cmlidXRlczAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVoYXNhdHRyaWJ1dGVzMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX25vZGVoYXNhdHRyaWJ1dGVzMDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbm9kZWhhc2F0dHJpYnV0ZXMwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbm9kZWhhc2F0dHJpYnV0ZXMwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub2RlaGFzYXR0cmlidXRlczAzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9ub2RlaGFzYXR0cmlidXRlczA0KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVoYXNhdHRyaWJ1dGVzMDQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX25vZGVpc3N1cHBvcnRlZDAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVpc3N1cHBvcnRlZDAxIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9ub2RlaXNzdXBwb3J0ZWQwMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub2RlaXNzdXBwb3J0ZWQwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbm9kZWlzc3VwcG9ydGVkMDMoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbm9kZWlzc3VwcG9ydGVkMDMiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX25vZGVpc3N1cHBvcnRlZDA0KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVpc3N1cHBvcnRlZDA0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9ub2RlaXNzdXBwb3J0ZWQwNSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub2RlaXNzdXBwb3J0ZWQwNSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbm9kZW5vcm1hbGl6ZTAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVub3JtYWxpemUwMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbm9kZXNldHByZWZpeDAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbm9kZXNldHByZWZpeDAyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbm9kZXNldHByZWZpeDAzKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwMyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbm9kZXNldHByZWZpeDA1KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwNSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbm9kZXNldHByZWZpeDA2KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwNiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbm9kZXNldHByZWZpeDA3KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwNyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbm9kZXNldHByZWZpeDA4KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwOCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfbm9ybWFsaXplMDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbm9ybWFsaXplMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX293bmVyRG9jdW1lbnQwMSgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9vd25lckRvY3VtZW50MDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX293bmVyRWxlbWVudDAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL293bmVyRWxlbWVudDAxIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9vd25lckVsZW1lbnQwMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9vd25lckVsZW1lbnQwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfcHJlZml4MDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvcHJlZml4MDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX3ByZWZpeDAyKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3ByZWZpeDAyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9wcmVmaXgwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9wcmVmaXgwMyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfcHJlZml4MDQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvcHJlZml4MDQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX3ByZWZpeDA1KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3ByZWZpeDA1Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9wcmVmaXgwNygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9wcmVmaXgwNyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfcHJlZml4MTAoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvcHJlZml4MTAiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX3ByZWZpeDExKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3ByZWZpeDExIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9wdWJsaWNJZDAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3B1YmxpY0lkMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX3JlbW92ZU5hbWVkSXRlbU5TMDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvcmVtb3ZlTmFtZWRJdGVtTlMwMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfcmVtb3ZlTmFtZWRJdGVtTlMwMigpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9yZW1vdmVOYW1lZEl0ZW1OUzAyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9zZXRBdHRyaWJ1dGVOUzAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX3NldEF0dHJpYnV0ZU5TMDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfc2V0QXR0cmlidXRlTlMwNCgpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOUzA0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9zZXRBdHRyaWJ1dGVOUzA1KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX3NldEF0dHJpYnV0ZU5TMDYoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMwNiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfc2V0QXR0cmlidXRlTlMwNygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOUzA3Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9zZXRBdHRyaWJ1dGVOUzA5KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDkiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX3NldEF0dHJpYnV0ZU5vZGVOUzAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5vZGVOUzAxIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9zZXRBdHRyaWJ1dGVOb2RlTlMwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOb2RlTlMwMyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfc2V0QXR0cmlidXRlTm9kZU5TMDQoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTm9kZU5TMDQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX3NldEF0dHJpYnV0ZU5vZGVOUzA1KCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5vZGVOUzA1Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9zZXROYW1lZEl0ZW1OUzAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3NldE5hbWVkSXRlbU5TMDEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xldmVsMl9jb3JlX3NldE5hbWVkSXRlbU5TMDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsgCisgICAgICAgIHJ1bkRvbVRlc3QoImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvc2V0TmFtZWRJdGVtTlMwMiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGV2ZWwyX2NvcmVfc2V0TmFtZWRJdGVtTlMwMygpIHRocm93cyBUaHJvd2FibGUgeyAKKyAgICAgICAgcnVuRG9tVGVzdCgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9zZXROYW1lZEl0ZW1OUzAzIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sZXZlbDJfY29yZV9zeXN0ZW1JZDAxKCkgdGhyb3dzIFRocm93YWJsZSB7IAorICAgICAgICBydW5Eb21UZXN0KCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3N5c3RlbUlkMDEiKTsKKyAgICB9CisKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL0xTRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9MU0RvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNzY5NjAyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9MU0RvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDQxNCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210czsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKKworLyoqCisgKiAgIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgZ2VuZXJpYyBwYXJzZXIgYW5kIGNvbmZpZ3VhdGlvbgorICogICBhYnN0cmFjdCBjbGFzcyBmb3IgdGhlIERPTSBMMyBpbXBsZW1lbnRhdGlvbnMKKyAqCisgKiAgIEBhdXRob3IgQ3VydCBBcm5vbGQKKyAqLworcHVibGljIGNsYXNzIExTRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgIGV4dGVuZHMgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgeworCisgIHByaXZhdGUgZmluYWwgT2JqZWN0IHBhcnNlcjsKKyAgcHJpdmF0ZSBmaW5hbCBNZXRob2QgcGFyc2VVUklNZXRob2Q7CisgIHByaXZhdGUgZmluYWwgRE9NSW1wbGVtZW50YXRpb24gaW1wbDsKKworICAvKioKKyAgICoKKyAgICogQWJzdHJhY3QgY2xhc3MgZm9yIGEgc3RyYXRlZ3kgdG8gbWFwIGEgRG9jdW1lbnRCdWlsZGVyU2V0dGluZworICAgKiB0byBhbiBhY3Rpb24gb24gTFNQYXJzZXIuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBMU1N0cmF0ZWd5IHsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqLworICAgIHByb3RlY3RlZCBMU1N0cmF0ZWd5KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGxpZXMgc2V0dGluZyB0byBMU1BhcnNlcgorICAgICAqCisgICAgICogQHBhcmFtIHNldHRpbmcgc2V0dGluZworICAgICAqIEBwYXJhbSBwYXJzZXIgcGFyc2VyCisgICAgICogQHRocm93cyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIGlmIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHNldHRpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBhcHBseVNldHRpbmcoRG9jdW1lbnRCdWlsZGVyU2V0dGluZyBzZXR0aW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgcGFyc2VyKSB0aHJvd3MKKyAgICAgICAgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgc3RhdGUgb2Ygc2V0dGluZyBmb3IgcGFyc2VyCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyc2VyIHBhcnNlcgorICAgICAqIEByZXR1cm4gc3RhdGUgb2Ygc2V0dGluZworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGhhc1NldHRpbmcoT2JqZWN0IHBhcnNlcik7CisKKyAgfQorCisgIC8qKgorICAgKiBSZXByZXNlbnRzIGEgZml4ZWQgc2V0dGluZywgZm9yIGV4YW1wbGUsIGFsbCBKYXZhIGltcGxlbWVudGF0aW9ucworICAgKiBzdXBwb3J0ZWQgc2lnbmVkIHZhbHVlcy4KKyAgICoKKyAgICovCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIExTRml4ZWRTdHJhdGVneQorICAgICAgZXh0ZW5kcyBMU1N0cmF0ZWd5IHsKKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gZml4ZWRWYWx1ZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2V0dGluZ05hbWUgc2V0dGluZyBuYW1lCisgICAgICogQHBhcmFtIGZpeGVkVmFsdWUgZml4ZWQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgTFNGaXhlZFN0cmF0ZWd5KGJvb2xlYW4gZml4ZWRWYWx1ZSkgeworICAgICAgdGhpcy5maXhlZFZhbHVlID0gZml4ZWRWYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBseSBzZXR0aW5nLiAgVGhyb3dzIGV4Y2VwdGlvbiBpZiByZXF1ZXN0ZWQgc2V0dGluZworICAgICAqIGRvZXMgbm90IG1hdGNoIGZpeGVkIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFwcGx5U2V0dGluZyhEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIHNldHRpbmcsIE9iamVjdCBwYXJzZXIpIHRocm93cworICAgICAgICBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIGlmIChzZXR0aW5nLmdldFZhbHVlKCkgIT0gZml4ZWRWYWx1ZSkgeworICAgICAgICB0aHJvdyBuZXcgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbihudWxsLCBzZXR0aW5nKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGZpeGVkIHZhbHVlIGZvciBzZXR0aW5nCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzU2V0dGluZyhPYmplY3QgcGFyc2VyKSB7CisgICAgICByZXR1cm4gZml4ZWRWYWx1ZTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQSBzdHJhdGVneSBmb3IgYSBzZXR0aW5nIHRoYXQgY2FuIGJlIGFwcGxpZWQgYnkgc2V0dGluZyBhIERPTUNvbmZpZ3VyYXRpb24KKyAgICogcGFyYW1ldGVyLgorICAgKgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTFNQYXJhbWV0ZXJTdHJhdGVneQorICAgICAgZXh0ZW5kcyBMU1N0cmF0ZWd5IHsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBsc1BhcmFtZXRlcjsKKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gaW52ZXJzZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yCisgICAgICoKKyAgICAgKiBAcGFyYW0gbHNQYXJhbWV0ZXIgY29ycmVzcG9uZGluZyBET01Db25maWd1cmF0aW9uIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSBpbnZlcnNlIGlmIHRydWUsIERPTUNvbmZpZ3VyYXRpb24gdmFsdWUgaXMgdGhlIGludmVyc2UKKyAgICAgKiBvZiB0aGUgc2V0dGluZyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBMU1BhcmFtZXRlclN0cmF0ZWd5KFN0cmluZyBsc1BhcmFtZXRlciwgYm9vbGVhbiBpbnZlcnNlKSB7CisgICAgICB0aGlzLmxzUGFyYW1ldGVyID0gbHNQYXJhbWV0ZXI7CisgICAgICB0aGlzLmludmVyc2UgPSBpbnZlcnNlOworICAgIH0KKworICAgIHByb3RlY3RlZCBzdGF0aWMgdm9pZCBzZXRQYXJhbWV0ZXIoRG9jdW1lbnRCdWlsZGVyU2V0dGluZyBzZXR0aW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHBhcnNlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwYXJhbWV0ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgdmFsdWUpIHRocm93cworICAgICAgICBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHRyeSB7CisgICAgICAgIE1ldGhvZCBkb21Db25maWdNZXRob2QgPSBwYXJzZXIuZ2V0Q2xhc3MoKS5nZXRNZXRob2QoImdldERvbUNvbmZpZyIsCisgICAgICAgICAgICBuZXcgQ2xhc3NbMF0pOworICAgICAgICBPYmplY3QgZG9tQ29uZmlnID0gZG9tQ29uZmlnTWV0aG9kLmludm9rZShwYXJzZXIsIG5ldyBPYmplY3RbMF0pOworICAgICAgICBNZXRob2Qgc2V0UGFyYW1ldGVyTWV0aG9kID0gZG9tQ29uZmlnLmdldENsYXNzKCkuZ2V0TWV0aG9kKAorICAgICAgICAgICAgInNldFBhcmFtZXRlciIsIG5ldyBDbGFzc1tdIHtTdHJpbmcuY2xhc3MsIE9iamVjdC5jbGFzc30pOworICAgICAgICBzZXRQYXJhbWV0ZXJNZXRob2QuaW52b2tlKGRvbUNvbmZpZywgbmV3IE9iamVjdFtdIHtwYXJhbWV0ZXIsIHZhbHVlfSk7CisKKyAgICAgIH0KKyAgICAgIGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGV4KSB7CisgICAgICAgIHRocm93IG5ldyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uKGV4LmdldFRhcmdldEV4Y2VwdGlvbigpLCBzZXR0aW5nKTsKKyAgICAgIH0KKyAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgdGhyb3cgbmV3IERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24oZXgsIHNldHRpbmcpOworICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCBzdGF0aWMgT2JqZWN0IGdldFBhcmFtZXRlcihPYmplY3QgcGFyc2VyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcGFyYW1ldGVyKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgIE1ldGhvZCBkb21Db25maWdNZXRob2QgPSBwYXJzZXIuZ2V0Q2xhc3MoKS5nZXRNZXRob2QoImdldERvbUNvbmZpZyIsCisgICAgICAgICAgbmV3IENsYXNzWzBdKTsKKyAgICAgIE9iamVjdCBkb21Db25maWcgPSBkb21Db25maWdNZXRob2QuaW52b2tlKHBhcnNlciwgbmV3IE9iamVjdFswXSk7CisgICAgICBNZXRob2QgZ2V0UGFyYW1ldGVyTWV0aG9kID0gZG9tQ29uZmlnLmdldENsYXNzKCkuZ2V0TWV0aG9kKCJnZXRQYXJhbWV0ZXIiLAorICAgICAgICAgIG5ldyBDbGFzc1tdIHtTdHJpbmcuY2xhc3N9KTsKKyAgICAgIHJldHVybiBnZXRQYXJhbWV0ZXJNZXRob2QuaW52b2tlKGRvbUNvbmZpZywgbmV3IE9iamVjdFtdIHtwYXJhbWV0ZXJ9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBseSBzZXR0aW5nCisgICAgICovCisgICAgcHVibGljIHZvaWQgYXBwbHlTZXR0aW5nKERvY3VtZW50QnVpbGRlclNldHRpbmcgc2V0dGluZywgT2JqZWN0IHBhcnNlcikgdGhyb3dzCisgICAgICAgIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgaWYgKGludmVyc2UpIHsKKyAgICAgICAgc2V0UGFyYW1ldGVyKHNldHRpbmcsIHBhcnNlciwgbHNQYXJhbWV0ZXIsCisgICAgICAgICAgICAgICAgICAgICBuZXcgQm9vbGVhbighc2V0dGluZy5nZXRWYWx1ZSgpKSk7CisgICAgICB9CisgICAgICBlbHNlIHsKKyAgICAgICAgc2V0UGFyYW1ldGVyKHNldHRpbmcsIHBhcnNlciwgbHNQYXJhbWV0ZXIsIG5ldyBCb29sZWFuKHNldHRpbmcuZ2V0VmFsdWUoKSkpOworICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB2YWx1ZSBvZiBzZXR0aW5nCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzU2V0dGluZyhPYmplY3QgcGFyc2VyKSB7CisgICAgICB0cnkgeworICAgICAgICBpZiAoaW52ZXJzZSkgeworICAgICAgICAgIHJldHVybiEgKCAoQm9vbGVhbikgZ2V0UGFyYW1ldGVyKHBhcnNlciwgbHNQYXJhbWV0ZXIpKS5ib29sZWFuVmFsdWUoKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gKCAoQm9vbGVhbikgZ2V0UGFyYW1ldGVyKHBhcnNlciwgbHNQYXJhbWV0ZXIpKS5ib29sZWFuVmFsdWUoKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEEgc3RyYXRlZ3kgZm9yIHRoZSB2YWxpZGF0aW9uIHNldHRpbmdzIHdoaWNoIHJlcXVpcmUKKyAgICogdHdvIERPTUNvbmZpZ3VydXJlIHBhcmFtZXRlcnMgYmVpbmcgc2V0LCAndmFsaWRhdGUnIGFuZCAnc2NoZW1hLXR5cGUnCisgICAqCisgICAqLworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBMU1ZhbGlkYXRlU3RyYXRlZ3kKKyAgICAgIGV4dGVuZHMgTFNQYXJhbWV0ZXJTdHJhdGVneSB7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgc2NoZW1hVHlwZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yCisgICAgICogQHBhcmFtIHNjaGVtYVR5cGUgc2NoZW1hIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgTFNWYWxpZGF0ZVN0cmF0ZWd5KFN0cmluZyBzY2hlbWFUeXBlKSB7CisgICAgICBzdXBlcigidmFsaWRhdGUiLCBmYWxzZSk7CisgICAgICB0aGlzLnNjaGVtYVR5cGUgPSBzY2hlbWFUeXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGx5IHNldHRpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhcHBseVNldHRpbmcoRG9jdW1lbnRCdWlsZGVyU2V0dGluZyBzZXR0aW5nLCBPYmplY3QgcGFyc2VyKSB0aHJvd3MKKyAgICAgICAgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlci5hcHBseVNldHRpbmcoc2V0dGluZywgcGFyc2VyKTsKKyAgICAgIHNldFBhcmFtZXRlcihudWxsLCBwYXJzZXIsICJzY2hlbWEtdHlwZSIsIHNjaGVtYVR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBzZXR0aW5nIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzU2V0dGluZyhPYmplY3QgcGFyc2VyKSB7CisgICAgICBpZiAoc3VwZXIuaGFzU2V0dGluZyhwYXJzZXIpKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgU3RyaW5nIHBhcnNlclNjaGVtYVR5cGUgPSAoU3RyaW5nKSBnZXRQYXJhbWV0ZXIocGFyc2VyLCAic2NoZW1hLXR5cGUiKTsKKyAgICAgICAgICBpZiAoc2NoZW1hVHlwZSA9PSBudWxsIHx8IHNjaGVtYVR5cGUuZXF1YWxzKHBhcnNlclNjaGVtYVR5cGUpKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgIH0KKworICAvKioKKyAgICogU3RyYXRlZ2llcyBmb3IgbWFwcGluZyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5ncyB0bworICAgKiBhY3Rpb25zIG9uIExTUGFyc2VyCisgICAqLworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXAgc3RyYXRlZ2llczsKKworICBzdGF0aWMgeworICAgIHN0cmF0ZWdpZXMgPSBuZXcgSGFzaE1hcCgpOworICAgIHN0cmF0ZWdpZXMucHV0KCJjb2FsZXNjaW5nIiwgbmV3IExTUGFyYW1ldGVyU3RyYXRlZ3koImNkYXRhLXNlY3Rpb25zIiwgdHJ1ZSkpOworICAgIHN0cmF0ZWdpZXMucHV0KCJleHBhbmRFbnRpdHlSZWZlcmVuY2VzIiwgbmV3IExTUGFyYW1ldGVyU3RyYXRlZ3koImVudGl0aWVzIiwgdHJ1ZSkpOworICAgIHN0cmF0ZWdpZXMucHV0KCJpZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSIsCisgICAgICAgICAgICAgICAgICAgbmV3IExTUGFyYW1ldGVyU3RyYXRlZ3koImVsZW1lbnQtY29udGVudC13aGl0ZXNwYWNlIiwgdHJ1ZSkpOworICAgIHN0cmF0ZWdpZXMucHV0KCJuYW1lc3BhY2VBd2FyZSIsIG5ldyBMU1BhcmFtZXRlclN0cmF0ZWd5KCJuYW1lc3BhY2VzIiwgZmFsc2UpKTsKKyAgICBzdHJhdGVnaWVzLnB1dCgidmFsaWRhdGluZyIsCisgICAgICAgICAgICAgICAgICAgbmV3IExTVmFsaWRhdGVTdHJhdGVneSgiaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCIpKTsKKyAgICBzdHJhdGVnaWVzLnB1dCgic2NoZW1hVmFsaWRhdGluZyIsCisgICAgICAgICAgICAgICAgICAgbmV3IExTVmFsaWRhdGVTdHJhdGVneSgiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiKSk7CisgICAgc3RyYXRlZ2llcy5wdXQoImlnbm9yaW5nQ29tbWVudHMiLCBuZXcgTFNQYXJhbWV0ZXJTdHJhdGVneSgiY29tbWVudHMiLCB0cnVlKSk7CisgICAgc3RyYXRlZ2llcy5wdXQoInNpZ25lZCIsIG5ldyBMU0ZpeGVkU3RyYXRlZ3kodHJ1ZSkpOworICAgIHN0cmF0ZWdpZXMucHV0KCJoYXNOdWxsU3RyaW5nIiwgbmV3IExTRml4ZWRTdHJhdGVneSh0cnVlKSk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlcyBhIExTIGltcGxlbWVudGF0aW9uIG9mIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LgorICAgKiBAcGFyYW0gc2V0dGluZ3MgYXJyYXkgb2Ygc2V0dGluZ3MsIG1heSBiZSBudWxsLgorICAgKiBAdGhyb3dzIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24KKyAgICogICAgIFRocm93biBpZiBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IHRoZSBzcGVjaWZpZWQgc2V0dGluZ3MKKyAgICovCisgIHB1YmxpYyBMU0RvY3VtZW50QnVpbGRlckZhY3RvcnkoRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzKSB0aHJvd3MKKyAgICAgIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgIHN1cGVyKHNldHRpbmdzKTsKKworICAgIHRyeSB7CisgICAgICBDbGFzcyBkb21JbXBsUmVnaXN0cnlDbGFzcyA9IENsYXNzLmZvck5hbWUoCisgICAgICAgICAgIm9yZy53M2MuZG9tLmJvb3RzdHJhcC5ET01JbXBsZW1lbnRhdGlvblJlZ2lzdHJ5Iik7CisgICAgICBNZXRob2QgbmV3SW5zdGFuY2VNZXRob2QgPSBkb21JbXBsUmVnaXN0cnlDbGFzcy5nZXRNZXRob2QoIm5ld0luc3RhbmNlIiwgKENsYXNzPD8+KSBudWxsKTsKKyAgICAgIE9iamVjdCBkb21SZWdpc3RyeSA9IG5ld0luc3RhbmNlTWV0aG9kLmludm9rZShudWxsLCAoQ2xhc3M8Pz4pIG51bGwpOworICAgICAgTWV0aG9kIGdldERPTUltcGxlbWVudGF0aW9uTWV0aG9kID0gZG9tSW1wbFJlZ2lzdHJ5Q2xhc3MuZ2V0TWV0aG9kKAorICAgICAgICAgICJnZXRET01JbXBsZW1lbnRhdGlvbiIsIG5ldyBDbGFzc1tdIHtTdHJpbmcuY2xhc3N9KTsKKyAgICAgIGltcGwgPSAoRE9NSW1wbGVtZW50YXRpb24pIGdldERPTUltcGxlbWVudGF0aW9uTWV0aG9kLmludm9rZShkb21SZWdpc3RyeSwKKyAgICAgICAgICBuZXcgT2JqZWN0W10geyJMUyJ9KTsKKyAgICAgIE1ldGhvZCBjcmVhdGVMU1BhcnNlck1ldGhvZCA9IGltcGwuZ2V0Q2xhc3MoKS5nZXRNZXRob2QoImNyZWF0ZUxTUGFyc2VyIiwKKyAgICAgICAgICBuZXcgQ2xhc3NbXSB7c2hvcnQuY2xhc3MsIFN0cmluZy5jbGFzc30pOworICAgICAgcGFyc2VyID0gY3JlYXRlTFNQYXJzZXJNZXRob2QuaW52b2tlKGltcGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtuZXcgU2hvcnQoIChzaG9ydCkgMSksIG51bGx9KTsKKyAgICAgIHBhcnNlVVJJTWV0aG9kID0gcGFyc2VyLmdldENsYXNzKCkuZ2V0TWV0aG9kKCJwYXJzZVVSSSIsCisgICAgICAgICAgbmV3IENsYXNzW10ge1N0cmluZy5jbGFzc30pOworICAgIH0KKyAgICBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBleCkgeworICAgICAgdGhyb3cgbmV3IERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24oZXguZ2V0VGFyZ2V0RXhjZXB0aW9uKCksIG51bGwpOworICAgIH0KKyAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICB0aHJvdyBuZXcgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbihleCwgbnVsbCk7CisgICAgfQorCisgICAgaWYgKHNldHRpbmdzICE9IG51bGwpIHsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2V0dGluZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgT2JqZWN0IHN0cmF0ZWd5ID0gc3RyYXRlZ2llcy5nZXQoc2V0dGluZ3NbaV0uZ2V0UHJvcGVydHkoKSk7CisgICAgICAgIGlmIChzdHJhdGVneSA9PSBudWxsKSB7CisgICAgICAgICAgdGhyb3cgbmV3IERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24obnVsbCwgc2V0dGluZ3NbaV0pOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICggKExTU3RyYXRlZ3kpIHN0cmF0ZWd5KS5hcHBseVNldHRpbmcoc2V0dGluZ3NbaV0sIHBhcnNlcik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKioKKyAgICogICAgQ3JlYXRlIG5ldyBpbnN0YW5jZSBvZiBkb2N1bWVudCBidWlsZGVyIGZhY3RvcnkKKyAgICogICAgcmVmbGVjdGluZyBzcGVjaWZpZWQgc2V0dGluZ3MKKyAgICogICAgQHBhcmFtIG5ld1NldHRpbmdzIG5ldyBzZXR0aW5ncworICAgKiAgICBAcmV0dXJuIE5ldyBpbnN0YW5jZQorICAgKiAgICBAdGhyb3dzIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24KKyAgICogICAgICAgICBpZiBzZXR0aW5ncyBhcmUgbm90IHN1cHBvcnRlZCBieSBpbXBsZW1lbnRhdGlvbgorICAgKi8KKyAgcHVibGljIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IG5ld0luc3RhbmNlKAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIG5ld1NldHRpbmdzKSB0aHJvd3MgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgaWYgKG5ld1NldHRpbmdzID09IG51bGwpIHsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKyAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gbWVyZ2VkU2V0dGluZ3MgPSBtZXJnZVNldHRpbmdzKG5ld1NldHRpbmdzKTsKKyAgICByZXR1cm4gbmV3IExTRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShtZXJnZWRTZXR0aW5ncyk7CisgIH0KKworICAvKioKKyAgICogICAgTG9hZHMgc3BlY2lmaWVkIFVSTAorICAgKiAgICBAcGFyYW0gdXJsIHVybCB0byBsb2FkCisgICAqICAgIEByZXR1cm4gRE9NIGRvY3VtZW50CisgICAqICAgIEB0aHJvd3MgRE9NVGVzdExvYWRFeGNlcHRpb24gaWYgdW5hYmxlIHRvIGxvYWQgZG9jdW1lbnQKKyAgICovCisgIHB1YmxpYyBEb2N1bWVudCBsb2FkKGphdmEubmV0LlVSTCB1cmwpIHRocm93cyBET01UZXN0TG9hZEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiAoRG9jdW1lbnQpIHBhcnNlVVJJTWV0aG9kLmludm9rZShwYXJzZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHt1cmwudG9TdHJpbmcoKX0pOworICAgIH0KKyAgICBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBleCkgeworICAgICAgdGhyb3cgbmV3IERPTVRlc3RMb2FkRXhjZXB0aW9uKGV4LmdldFRhcmdldEV4Y2VwdGlvbigpKTsKKyAgICB9CisgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgdGhyb3cgbmV3IERPTVRlc3RMb2FkRXhjZXB0aW9uKGV4KTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogICAgIEdldHMgRE9NSW1wbGVtZW50YXRpb24KKyAgICogICAgIEByZXR1cm4gRE9NIGltcGxlbWVudGF0aW9uLCBtYXkgYmUgbnVsbAorICAgKi8KKyAgcHVibGljIERPTUltcGxlbWVudGF0aW9uIGdldERPTUltcGxlbWVudGF0aW9uKCkgeworICAgIHJldHVybiBpbXBsOworICB9CisKKyAgLyoqCisgICAqICAgRGV0ZXJtaW5lcyBpZiB0aGUgaW1wbGVtZW50YXRpb24gc3VwcG9ydHMgdGhlIHNwZWNpZmllZCBmZWF0dXJlCisgICAqICAgQHBhcmFtIGZlYXR1cmUgRmVhdHVyZQorICAgKiAgIEBwYXJhbSB2ZXJzaW9uIFZlcnNpb24KKyAgICogICBAcmV0dXJuIHRydWUgaWYgaW1wbGVtZW50YXRpb24gc3VwcG9ydHMgdGhlIGZlYXR1cmUKKyAgICovCisgIHB1YmxpYyBib29sZWFuIGhhc0ZlYXR1cmUoU3RyaW5nIGZlYXR1cmUsIFN0cmluZyB2ZXJzaW9uKSB7CisgICAgcmV0dXJuIGdldERPTUltcGxlbWVudGF0aW9uKCkuaGFzRmVhdHVyZShmZWF0dXJlLCB2ZXJzaW9uKTsKKyAgfQorCisgIHByaXZhdGUgYm9vbGVhbiBoYXNQcm9wZXJ0eShTdHJpbmcgcGFyYW1ldGVyKSB7CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiAoIChCb29sZWFuKSBMU1BhcmFtZXRlclN0cmF0ZWd5LmdldFBhcmFtZXRlcihwYXJzZXIsIHBhcmFtZXRlcikpLgorICAgICAgICAgIGJvb2xlYW5WYWx1ZSgpOworICAgIH0KKyAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgfQorCisgIC8qKgorICAgKiAgIEluZGljYXRlcyB3aGV0aGVyIHRoZSBpbXBsZW1lbnRhdGlvbiBjb21iaW5lcyB0ZXh0IGFuZCBjZGF0YSBub2Rlcy4KKyAgICogICBAcmV0dXJuIHRydWUgaWYgY29hbGVzY2luZworICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNDb2FsZXNjaW5nKCkgeworICAgIHJldHVybiFoYXNQcm9wZXJ0eSgiY2RhdGEtc2VjdGlvbnMiKTsKKyAgfQorCisgIC8qKgorICAgKiAgIEluZGljYXRlcyB3aGV0aGVyIHRoZSBpbXBsZW1lbnRhdGlvbiBleHBhbmRzIGVudGl0eSByZWZlcmVuY2VzLgorICAgKiAgIEByZXR1cm4gdHJ1ZSBpZiBleHBhbmRpbmcgZW50aXR5IHJlZmVyZW5jZXMKKyAgICovCisgIHB1YmxpYyBib29sZWFuIGlzRXhwYW5kRW50aXR5UmVmZXJlbmNlcygpIHsKKyAgICByZXR1cm4haGFzUHJvcGVydHkoImVudGl0aWVzIik7CisgIH0KKworICAvKioKKyAgICogICBJbmRpY2F0ZXMgd2hldGhlciB0aGUgaW1wbGVtZW50YXRpb24gaWdub3JlcworICAgKiAgICAgICBlbGVtZW50IGNvbnRlbnQgd2hpdGVzcGFjZS4KKyAgICogICBAcmV0dXJuIHRydWUgaWYgaWdub3JpbmcgZWxlbWVudCBjb250ZW50IHdoaXRlc3BhY2UKKyAgICovCisgIHB1YmxpYyBib29sZWFuIGlzSWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoKSB7CisgICAgcmV0dXJuIWhhc1Byb3BlcnR5KCJlbGVtZW50LWNvbnRlbnQtd2hpdGVzcGFjZSIpOworICB9CisKKyAgLyoqCisgICAqICAgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGltcGxlbWVudGF0aW9uIGlzIG5hbWVzcGFjZSBhd2FyZS4KKyAgICogICBAcmV0dXJuIHRydWUgaWYgbmFtZXNwYWNlIGF3YXJlCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc05hbWVzcGFjZUF3YXJlKCkgeworICAgIHJldHVybiBoYXNQcm9wZXJ0eSgibmFtZXNwYWNlcyIpOworICB9CisKKyAgLyoqCisgICAqICAgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGltcGxlbWVudGF0aW9uIGlzIHZhbGlkYXRpbmcuCisgICAqICAgQHJldHVybiB0cnVlIGlmIHZhbGlkYXRpbmcKKyAgICovCisgIHB1YmxpYyBib29sZWFuIGlzVmFsaWRhdGluZygpIHsKKyAgICByZXR1cm4gaGFzUHJvcGVydHkoInZhbGlkYXRlIik7CisgIH0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9Vc2VyRGF0YU1vbml0b3IuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvVXNlckRhdGFNb25pdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDdlMzViYgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvVXNlckRhdGFNb25pdG9yLmphdmEKQEAgLTAsMCArMSw2OSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YKKyAqIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4KKyAqIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZSBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcworICogcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKKyAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKKyAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlCisgKiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210czsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLlVzZXJEYXRhSGFuZGxlcjsKKworLyoqCisgKiBUaGlzIGlzIGEgdXRpbGl0eSBpbXBsZW1lbnRhdGlvbiBvZiBVc2VyRGF0YUhhbmRsZXIgdGhhdCBjYXB0dXJlcyBhbGwKKyAqIG5vdGlmaWNhdGlvbnMKKyAqLworcHVibGljIGNsYXNzIFVzZXJEYXRhTW9uaXRvcgorICAgIGltcGxlbWVudHMgVXNlckRhdGFIYW5kbGVyIHsKKyAgcHJpdmF0ZSBmaW5hbCBMaXN0IG5vdGlmaWNhdGlvbnMgPSBuZXcgQXJyYXlMaXN0KCk7CisKKyAgLyoqCisgICAqIFB1YmxpYyBjb25zdHJ1Y3RvcgorICAgKgorICAgKi8KKyAgcHVibGljIFVzZXJEYXRhTW9uaXRvcigpIHsKKyAgfQorCisgIC8qKgorICAgKiBJbXBsZW1lbnRhdGlvbiBvZiBVc2VyRGF0YUhhbmRsZXIuaGFuZGxlLiBDcmVhdGVzIGEgVXNlckRhdGFOb3RpZmljYXRpb24KKyAgICogZm9yIGxhdGVyIHRlc3RpbmcKKyAgICoKKyAgICogQHBhcmFtIG9wZXJhdGlvbgorICAgKiAgICAgICAgICAgIFNlZSBvcmcudzNjLmRvbS5Vc2VyRGF0YUhhbmRsZXIKKyAgICogQHBhcmFtIGtleQorICAgKiAgICAgICAgICAgIFNlZSBvcmcudzNjLmRvbS5Vc2VyRGF0YUhhbmRsZXIKKyAgICogQHBhcmFtIGRhdGEKKyAgICogICAgICAgICAgICBTZWUgb3JnLnczYy5kb20uVXNlckRhdGFIYW5kbGVyCisgICAqIEBwYXJhbSBzcmMKKyAgICogICAgICAgICAgICBTZWUgb3JnLnczYy5kb20uVXNlckRhdGFIYW5kbGVyCisgICAqIEBwYXJhbSBkc3QKKyAgICogICAgICAgICAgICBTZWUgb3JnLnczYy5kb20uVXNlckRhdGFIYW5kbGVyCisgICAqLworICBwdWJsaWMgdm9pZCBoYW5kbGUoCisgICAgICBzaG9ydCBvcGVyYXRpb24sCisgICAgICBTdHJpbmcga2V5LAorICAgICAgT2JqZWN0IGRhdGEsCisgICAgICBOb2RlIHNyYywKKyAgICAgIE5vZGUgZHN0KSB7CisgICAgbm90aWZpY2F0aW9ucy5hZGQoCisgICAgICAgIG5ldyBVc2VyRGF0YU5vdGlmaWNhdGlvbihvcGVyYXRpb24sIGtleSwgZGF0YSwgc3JjLCBkc3QpKTsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIGxpc3Qgb2Ygbm90aWZpY2F0aW9ucworICAgKgorICAgKiBAcmV0dXJuIExpc3Qgb2Ygbm90aWZpY2F0aW9ucywgbWF5IG5vdCBiZSBudWxsLgorICAgKi8KKyAgcHVibGljIGZpbmFsIExpc3QgZ2V0QWxsTm90aWZpY2F0aW9ucygpIHsKKyAgICByZXR1cm4gbmV3IEFycmF5TGlzdChub3RpZmljYXRpb25zKTsKKyAgfQorCit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL1VzZXJEYXRhTm90aWZpY2F0aW9uLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL1VzZXJEYXRhTm90aWZpY2F0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDQyMjkwMQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvVXNlckRhdGFOb3RpZmljYXRpb24uamF2YQpAQCAtMCwwICsxLDg4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZgorICogVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgorICogQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcworICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzCisgKiBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQorICogV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUworICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UKKyAqIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzOworCitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKKworLyoqCisgKiBUaGlzIGNsYXNzIGNhcHR1cmVzIHRoZSBwYXJhbWV0ZXJzIHRvIG9uZSBpbnZvY2F0aW9uIG9mCisgKiBVc2VyRGF0YUhhbmRsZXIuaGFuZGxlLgorICoKKyAqLworcHVibGljIGNsYXNzIFVzZXJEYXRhTm90aWZpY2F0aW9uIHsKKyAgcHJpdmF0ZSBmaW5hbCBzaG9ydCBvcGVyYXRpb247CisgIHByaXZhdGUgZmluYWwgU3RyaW5nIGtleTsKKyAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgZGF0YTsKKyAgcHJpdmF0ZSBmaW5hbCBOb2RlIHNyYzsKKyAgcHJpdmF0ZSBmaW5hbCBOb2RlIGRzdDsKKworICAvKioKKyAgICogUHVibGljIGNvbnN0cnVjdG9yCisgICAqCisgICAqLworICBwdWJsaWMgVXNlckRhdGFOb3RpZmljYXRpb24oc2hvcnQgb3BlcmF0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdCBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSBzcmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlIGRzdCkgeworICAgIHRoaXMub3BlcmF0aW9uID0gb3BlcmF0aW9uOworICAgIHRoaXMua2V5ID0ga2V5OworICAgIHRoaXMuZGF0YSA9IGRhdGE7CisgICAgdGhpcy5zcmMgPSBzcmM7CisgICAgdGhpcy5kc3QgPSBkc3Q7CisgIH0KKworICAvKioKKyAgICogR2V0IHZhbHVlIG9mIG9wZXJhdGlvbiBwYXJhbWV0ZXIKKyAgICoKKyAgICogQHJldHVybiB2YWx1ZSBvZiBvcGVyYXRpb24gcGFyYW1ldGVyCisgICAqLworICBwdWJsaWMgZmluYWwgc2hvcnQgZ2V0T3BlcmF0aW9uKCkgeworICAgIHJldHVybiBvcGVyYXRpb247CisgIH0KKworICAvKioKKyAgICogR2V0cyB2YWx1ZSBvZiBrZXkgcGFyYW1ldGVyCisgICAqCisgICAqIEByZXR1cm4gdmFsdWUgb2Yga2V5IHBhcmFtZXRlcgorICAgKi8KKyAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRLZXkoKSB7CisgICAgcmV0dXJuIGtleTsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIHZhbHVlIG9mIGRhdGEgcGFyYW1ldGVyCisgICAqCisgICAqIEByZXR1cm4gdmFsdWUgb2YgZGF0YSBwYXJhbWV0ZXIKKyAgICovCisgIHB1YmxpYyBmaW5hbCBPYmplY3QgZ2V0RGF0YSgpIHsKKyAgICByZXR1cm4gZGF0YTsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIHZhbHVlIG9mIHNyYyBwYXJhbWV0ZXIKKyAgICoKKyAgICogQHJldHVybiB2YWx1ZSBvZiBzcmMgcGFyYW1ldGVyCisgICAqLworICBwdWJsaWMgZmluYWwgTm9kZSBnZXRTcmMoKSB7CisgICAgcmV0dXJuIHNyYzsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIHZhbHVlIG9mIGRzdCBwYXJhbWV0ZXIKKyAgICoKKyAgICogQHJldHVybiB2YWx1ZSBvZiBkc3QgcGFyYW1ldGVyCisgICAqLworICBwdWJsaWMgZmluYWwgTm9kZSBnZXREc3QoKSB7CisgICAgcmV0dXJuIGRzdDsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9YYWxhbkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL1hhbGFuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYjYwNjU4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9YYWxhbkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmphdmEKQEAgLTAsMCArMSw3OSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKy8qCisgICRMb2c6IFhhbGFuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YSx2ICQKKyAgUmV2aXNpb24gMS4yICAyMDA0LzAzLzExIDAxOjQ0OjIxICBkb20tdHMtNAorICBDaGVja3N0eWxlIGZpeGVzIChidWcgNTkyKQorCisgIFJldmlzaW9uIDEuMSAgMjAwMy8wNC8yNCAwNTowMjowNSAgZG9tLXRzLTQKKyAgWGFsYW4tSiBzdXBwb3J0IGZvciBMMyBYUGF0aAorICBodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MTkxCisKKyAgUmV2aXNpb24gMS4xICAyMDAyLzAyLzAzIDA3OjQ3OjUxICBkb20tdHMtNAorICBNb3JlIG1pc3NpbmcgZmlsZXMKKworICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210czsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworCisvKioKKyAqCisgKiAgIFRoaXMgY2xhc3MgdXNlcyBYYWxhbi1KIHRvIGFkZCBYUGF0aCBzdXBwb3J0CisgKiAgICAgICB0byB0aGUgY3VycmVudCBKQVhQIERPTSBpbXBsZW1lbnRhdGlvbgorICovCitwdWJsaWMgY2xhc3MgWGFsYW5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgIGV4dGVuZHMgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHsKKworICAvKioKKyAgICogQ3JlYXRlcyBhIEpBWFAgaW1wbGVtZW50YXRpb24gb2YgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuCisgICAqIEBwYXJhbSBmYWN0b3J5IG51bGwgZm9yIGRlZmF1bHQgSkFYUCBwcm92aWRlci4gIElmIG5vdCBudWxsLAorICAgKiBmYWN0b3J5IHdpbGwgYmUgbXV0YXRlZCBpbiBjb25zdHJ1Y3RvciBhbmQgc2hvdWxkIGJlIHJlbGVhc2VkCisgICAqIGJ5IGNhbGxpbmcgY29kZSB1cG9uIHJldHVybi4KKyAgICogQHBhcmFtIHNldHRpbmdzIGFycmF5IG9mIHNldHRpbmdzLCBtYXkgYmUgbnVsbC4KKyAgICovCisgIHB1YmxpYyBYYWxhbkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5KAorICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBiYXNlRmFjdG9yeSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncykgdGhyb3dzIERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgIHN1cGVyKGJhc2VGYWN0b3J5LCBzZXR0aW5ncyk7CisgIH0KKworICBwcm90ZWN0ZWQgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgY3JlYXRlSW5zdGFuY2UoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgbmV3RmFjdG9yeSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdbXSBtZXJnZWRTZXR0aW5ncykgdGhyb3dzCisgICAgICBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gbmV3IFhhbGFuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkobmV3RmFjdG9yeSwgbWVyZ2VkU2V0dGluZ3MpOworICB9CisKKyAgLyoqCisgICAqICBDcmVhdGVzIFhQYXRoIGV2YWx1YXRvcgorICAgKiAgQHBhcmFtIGRvYyBET00gZG9jdW1lbnQsIG1heSBub3QgYmUgbnVsbAorICAgKi8KKyAgcHVibGljIE9iamVjdCBjcmVhdGVYUGF0aEV2YWx1YXRvcihEb2N1bWVudCBkb2MpIHsKKyAgICB0cnkgeworICAgICAgQ2xhc3MgeHBhdGhDbGFzcyA9IENsYXNzLmZvck5hbWUoCisgICAgICAgICAgIm9yZy5hcGFjaGUueHBhdGguZG9tYXBpLlhQYXRoRXZhbHVhdG9ySW1wbCIpOworICAgICAgQ29uc3RydWN0b3IgY29uc3RydWN0b3IgPSB4cGF0aENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHtEb2N1bWVudC5jbGFzc30pOworICAgICAgcmV0dXJuIGNvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7ZG9jfSk7CisgICAgfQorICAgIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICB9CisgICAgcmV0dXJuIGRvYzsKKyAgfQorCit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL1hlcmNlc0hUTUwyRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9YZXJjZXNIVE1MMkRvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZjY1NzIzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9YZXJjZXNIVE1MMkRvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDI2MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMiBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHM7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyOworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3Rvcnk7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0OworaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7CitpbXBvcnQgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyOworCisvKioKKyAqICAgVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBnZW5lcmljIHBhcnNlciBhbmQgY29uZmlndWF0aW9uCisgKiAgIGNsYXNzIGZvciB0aGUgSFRNTCBET00gTDIgaW1wbGVtZW50YXRpb24gaW4gWGVyY2VzLUoKKyAqLworcHVibGljIGNsYXNzIFhlcmNlc0hUTUwyRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgIGV4dGVuZHMgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgeworCisgIHByaXZhdGUgU0FYUGFyc2VyRmFjdG9yeSBmYWN0b3J5OworICBwcml2YXRlIENvbnN0cnVjdG9yIGh0bWxCdWlsZGVyQ29uc3RydWN0b3I7CisgIHByaXZhdGUgTWV0aG9kIGdldEhUTUxEb2N1bWVudE1ldGhvZDsKKyAgcHJpdmF0ZSBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDbGFzc1tdIE5PX0NMQVNTRVMgPSBuZXcgQ2xhc3NbMF07CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdIE5PX09CSkVDVFMgPSBuZXcgT2JqZWN0WzBdOworCisgIC8qKgorICAgKiBDcmVhdGVzIGEgaW1wbGVtZW50YXRpb24gb2YgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICogdXNpbmcgb3JnLmFwYWNoZS5odG1sLmRvbS5IVE1MQnVpbGRlcgorICAgKiBAcGFyYW0gc2V0dGluZ3MgYXJyYXkgb2Ygc2V0dGluZ3MsIG1heSBiZSBudWxsLgorICAgKi8KKyAgcHVibGljIFhlcmNlc0hUTUwyRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MpIHRocm93cworICAgICAgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgc3VwZXIoc2V0dGluZ3MpOworCisgICAgdHJ5IHsKKyAgICAgIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKTsKKyAgICAgIENsYXNzIGh0bWxCdWlsZGVyQ2xhc3MgPQorICAgICAgICAgIGNsYXNzTG9hZGVyLmxvYWRDbGFzcygib3JnLmFwYWNoZS5odG1sMi5kb20uSFRNTEJ1aWxkZXIiKTsKKworICAgICAgaHRtbEJ1aWxkZXJDb25zdHJ1Y3RvciA9CisgICAgICAgICAgaHRtbEJ1aWxkZXJDbGFzcy5nZXRDb25zdHJ1Y3RvcihOT19DTEFTU0VTKTsKKworICAgICAgZ2V0SFRNTERvY3VtZW50TWV0aG9kID0KKyAgICAgICAgICBodG1sQnVpbGRlckNsYXNzLmdldE1ldGhvZCgiZ2V0SFRNTERvY3VtZW50IiwgTk9fQ0xBU1NFUyk7CisKKyAgICAgIENsYXNzIGh0bWxET01JbXBsID0KKyAgICAgICAgICBjbGFzc0xvYWRlci5sb2FkQ2xhc3MoCisgICAgICAgICAgIm9yZy5hcGFjaGUuaHRtbDIuZG9tLkhUTUxET01JbXBsZW1lbnRhdGlvbkltcGwiKTsKKyAgICAgIE1ldGhvZCBtZXRob2QgPQorICAgICAgICAgIGh0bWxET01JbXBsLmdldE1ldGhvZCgiZ2V0SFRNTERPTUltcGxlbWVudGF0aW9uIiwgTk9fQ0xBU1NFUyk7CisgICAgICBkb21JbXBsID0gKERPTUltcGxlbWVudGF0aW9uKSBtZXRob2QuaW52b2tlKG51bGwsIE5PX09CSkVDVFMpOworCisgICAgICBDbGFzcyBzYXhGYWN0b3J5Q2xhc3MgPQorICAgICAgICAgIGNsYXNzTG9hZGVyLmxvYWRDbGFzcygKKyAgICAgICAgICAib3JnLmFwYWNoZS54ZXJjZXMuamF4cC5TQVhQYXJzZXJGYWN0b3J5SW1wbCIpOworICAgICAgZmFjdG9yeSA9IChTQVhQYXJzZXJGYWN0b3J5KSBzYXhGYWN0b3J5Q2xhc3MubmV3SW5zdGFuY2UoKTsKKyAgICB9CisgICAgY2F0Y2ggKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZXgpIHsKKyAgICAgIHRocm93IG5ldyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uKAorICAgICAgICAgIGV4LmdldFRhcmdldEV4Y2VwdGlvbigpLAorICAgICAgICAgIG51bGwpOworICAgIH0KKyAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICB0aHJvdyBuZXcgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbihleCwgbnVsbCk7CisgICAgfQorCisgICAgLy8KKyAgICAvLyAgICBhcHBseSBzZXR0aW5ncyB0byBzZWxlY3RlZCBkb2N1bWVudCBidWlsZGVyCisgICAgLy8gICAgICAgICBtYXkgdGhyb3cgZXhjZXB0aW9uIGlmIGluY29tcGF0aWJsZQorICAgIGlmIChzZXR0aW5ncyAhPSBudWxsKSB7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNldHRpbmdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIC8vICAgICAgICBzZXR0aW5nc1tpXS5hcHBseVNldHRpbmcoZmFjdG9yeSk7CisgICAgICB9CisgICAgfQorICAgIHRyeSB7CisgICAgICBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOworICAgIH0KKyAgICBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleCkgeworICAgICAgdGhyb3cgbmV3IERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24oZXgsIG51bGwpOworICAgIH0KKyAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGV4KSB7CisgICAgICB0aHJvdyBuZXcgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbihleCwgbnVsbCk7CisgICAgfQorICB9CisKKyAgcHVibGljIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IG5ld0luc3RhbmNlKERvY3VtZW50QnVpbGRlclNldHRpbmdbXQorICAgICAgbmV3U2V0dGluZ3MpIHRocm93cyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICBpZiAobmV3U2V0dGluZ3MgPT0gbnVsbCkgeworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdbXSBtZXJnZWRTZXR0aW5ncyA9IG1lcmdlU2V0dGluZ3MobmV3U2V0dGluZ3MpOworICAgIHJldHVybiBuZXcgWGVyY2VzSFRNTDJEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KG1lcmdlZFNldHRpbmdzKTsKKyAgfQorCisgIHByaXZhdGUgY2xhc3MgSFRNTEhhbmRsZXIKKyAgICAgIGV4dGVuZHMgRGVmYXVsdEhhbmRsZXIKKyAgICAgIGltcGxlbWVudHMgQXR0cmlidXRlTGlzdCB7CisgICAgcHJpdmF0ZSBmaW5hbCBEb2N1bWVudEhhbmRsZXIgaHRtbEJ1aWxkZXI7CisgICAgcHJpdmF0ZSBmaW5hbCBNZXRob2QgZ2V0SFRNTERvY3VtZW50TWV0aG9kOworICAgIHByaXZhdGUgQXR0cmlidXRlcyBjdXJyZW50QXR0cmlidXRlczsKKworICAgIHB1YmxpYyBIVE1MSGFuZGxlcigKKyAgICAgICAgQ29uc3RydWN0b3IgaHRtbEJ1aWxkZXJDb25zdHJ1Y3RvciwKKyAgICAgICAgTWV0aG9kIGdldEhUTUxEb2N1bWVudE1ldGhvZCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICBodG1sQnVpbGRlciA9CisgICAgICAgICAgKERvY3VtZW50SGFuZGxlcikgaHRtbEJ1aWxkZXJDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZSgKKyAgICAgICAgICBuZXcgT2JqZWN0WzBdKTsKKyAgICAgIHRoaXMuZ2V0SFRNTERvY3VtZW50TWV0aG9kID0gZ2V0SFRNTERvY3VtZW50TWV0aG9kOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgIGh0bWxCdWlsZGVyLnN0YXJ0RG9jdW1lbnQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgaHRtbEJ1aWxkZXIuZW5kRG9jdW1lbnQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCisgICAgICAgIFN0cmluZyB1cmksCisgICAgICAgIFN0cmluZyBsb2NhbE5hbWUsCisgICAgICAgIFN0cmluZyBxTmFtZSwKKyAgICAgICAgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgIGN1cnJlbnRBdHRyaWJ1dGVzID0gYXR0cmlidXRlczsKKyAgICAgIGh0bWxCdWlsZGVyLnN0YXJ0RWxlbWVudChxTmFtZSwgdGhpcyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUpIHRocm93cworICAgICAgICBTQVhFeGNlcHRpb24geworICAgICAgaHRtbEJ1aWxkZXIuZW5kRWxlbWVudChxTmFtZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkgdGhyb3dzCisgICAgICAgIFNBWEV4Y2VwdGlvbiB7CisgICAgICBodG1sQnVpbGRlci5jaGFyYWN0ZXJzKGNoLCBzdGFydCwgbGVuZ3RoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB0aHJvd3MKKyAgICAgICAgU0FYRXhjZXB0aW9uIHsKKyAgICAgIGh0bWxCdWlsZGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UoY2gsIHN0YXJ0LCBsZW5ndGgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkgdGhyb3dzCisgICAgICAgIFNBWEV4Y2VwdGlvbiB7CisgICAgICBodG1sQnVpbGRlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRG9jdW1lbnQgZ2V0SFRNTERvY3VtZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gKERvY3VtZW50KSBnZXRIVE1MRG9jdW1lbnRNZXRob2QuaW52b2tlKAorICAgICAgICAgIGh0bWxCdWlsZGVyLAorICAgICAgICAgIE5PX09CSkVDVFMpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgeworICAgICAgcmV0dXJuIGN1cnJlbnRBdHRyaWJ1dGVzLmdldExlbmd0aCgpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZShpbnQgaSkgeworICAgICAgcmV0dXJuIGN1cnJlbnRBdHRyaWJ1dGVzLmdldFFOYW1lKGkpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZShpbnQgaSkgeworICAgICAgcmV0dXJuIGN1cnJlbnRBdHRyaWJ1dGVzLmdldFR5cGUoaSk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZShpbnQgaSkgeworICAgICAgcmV0dXJuIGN1cnJlbnRBdHRyaWJ1dGVzLmdldFZhbHVlKGkpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZShTdHJpbmcgbmFtZSkgeworICAgICAgcmV0dXJuIGN1cnJlbnRBdHRyaWJ1dGVzLmdldFR5cGUobmFtZSk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZShTdHJpbmcgbmFtZSkgeworICAgICAgcmV0dXJuIGN1cnJlbnRBdHRyaWJ1dGVzLmdldFZhbHVlKG5hbWUpOworICAgIH0KKworICB9CisKKyAgcHVibGljIERvY3VtZW50IGxvYWQoamF2YS5uZXQuVVJMIHVybCkgdGhyb3dzIERPTVRlc3RMb2FkRXhjZXB0aW9uIHsKKyAgICBEb2N1bWVudCBkb2MgPSBudWxsOworICAgIHRyeSB7CisgICAgICBTQVhQYXJzZXIgcGFyc2VyID0gZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKKyAgICAgIEhUTUxIYW5kbGVyIGhhbmRsZXIgPQorICAgICAgICAgIG5ldyBIVE1MSGFuZGxlcihodG1sQnVpbGRlckNvbnN0cnVjdG9yLCBnZXRIVE1MRG9jdW1lbnRNZXRob2QpOworICAgICAgcGFyc2VyLnBhcnNlKHVybC50b1N0cmluZygpLCBoYW5kbGVyKTsKKyAgICAgIGRvYyA9IGhhbmRsZXIuZ2V0SFRNTERvY3VtZW50KCk7CisgICAgfQorICAgIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgIHRocm93IG5ldyBET01UZXN0TG9hZEV4Y2VwdGlvbihleCk7CisgICAgfQorICAgIHJldHVybiBkb2M7CisgIH0KKworICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb24gZ2V0RE9NSW1wbGVtZW50YXRpb24oKSB7CisgICAgcmV0dXJuIGRvbUltcGw7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBoYXNGZWF0dXJlKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikgeworICAgIHJldHVybiBkb21JbXBsLmhhc0ZlYXR1cmUoZmVhdHVyZSwgdmVyc2lvbik7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBpc0NvYWxlc2NpbmcoKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gaXNFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGlzSWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gaXNOYW1lc3BhY2VBd2FyZSgpIHsKKyAgICByZXR1cm4gZmFjdG9yeS5pc05hbWVzcGFjZUF3YXJlKCk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBpc1ZhbGlkYXRpbmcoKSB7CisgICAgcmV0dXJuIGZhY3RvcnkuaXNWYWxpZGF0aW5nKCk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIERvY3VtZW50QnVpbGRlclNldHRpbmdbXSBnZXRDb25maWd1cmF0aW9uMSgpIHsKKyAgICByZXR1cm4gbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcubm90Q29hbGVzY2luZywKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RFeHBhbmRFbnRpdHlSZWZlcmVuY2VzLAorICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5vdElnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlLAorICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5vdE5hbWVzcGFjZUF3YXJlLAorICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5vdFZhbGlkYXRpbmd9OworICB9CisKKyAgcHVibGljIHN0YXRpYyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gZ2V0Q29uZmlndXJhdGlvbjIoKSB7CisgICAgcmV0dXJuIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5vdENvYWxlc2NpbmcsCisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcuZXhwYW5kRW50aXR5UmVmZXJlbmNlcywKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5pZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSwKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZSwKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy52YWxpZGF0aW5nfTsKKworICB9CisKK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvWGVyY2VzSFRNTERvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvWGVyY2VzSFRNTERvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNmI1MzdiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9YZXJjZXNIVE1MRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMjYxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAyIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210czsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXI7CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeTsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3Q7CitpbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKK2ltcG9ydCBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuRGVmYXVsdEhhbmRsZXI7CisKKy8qKgorICogICBUaGlzIGNsYXNzIGltcGxlbWVudHMgdGhlIGdlbmVyaWMgcGFyc2VyIGFuZCBjb25maWd1YXRpb24KKyAqICAgYWJzdHJhY3QgY2xhc3MgdGhlIEhUTUwgRE9NIGltcGxlbWVudGF0aW9uIGluIFhlcmNlcy1KCisgKi8KK3B1YmxpYyBjbGFzcyBYZXJjZXNIVE1MRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgIGV4dGVuZHMgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgeworCisgIHByaXZhdGUgU0FYUGFyc2VyRmFjdG9yeSBmYWN0b3J5OworICBwcml2YXRlIENvbnN0cnVjdG9yIGh0bWxCdWlsZGVyQ29uc3RydWN0b3I7CisgIHByaXZhdGUgTWV0aG9kIGdldEhUTUxEb2N1bWVudE1ldGhvZDsKKyAgcHJpdmF0ZSBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDbGFzc1tdIE5PX0NMQVNTRVMgPSBuZXcgQ2xhc3NbMF07CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdIE5PX09CSkVDVFMgPSBuZXcgT2JqZWN0WzBdOworCisgIC8qKgorICAgKiBDcmVhdGVzIGEgaW1wbGVtZW50YXRpb24gb2YgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICogdXNpbmcgb3JnLmFwYWNoZS5odG1sLmRvbS5IVE1MQnVpbGRlcgorICAgKiBAcGFyYW0gc2V0dGluZ3MgYXJyYXkgb2Ygc2V0dGluZ3MsIG1heSBiZSBudWxsLgorICAgKi8KKyAgcHVibGljIFhlcmNlc0hUTUxEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncykgdGhyb3dzCisgICAgICBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICBzdXBlcihzZXR0aW5ncyk7CisKKyAgICB0cnkgeworICAgICAgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpOworICAgICAgQ2xhc3MgaHRtbEJ1aWxkZXJDbGFzcyA9CisgICAgICAgICAgY2xhc3NMb2FkZXIubG9hZENsYXNzKCJvcmcuYXBhY2hlLmh0bWwuZG9tLkhUTUxCdWlsZGVyIik7CisKKyAgICAgIGh0bWxCdWlsZGVyQ29uc3RydWN0b3IgPQorICAgICAgICAgIGh0bWxCdWlsZGVyQ2xhc3MuZ2V0Q29uc3RydWN0b3IoTk9fQ0xBU1NFUyk7CisKKyAgICAgIGdldEhUTUxEb2N1bWVudE1ldGhvZCA9CisgICAgICAgICAgaHRtbEJ1aWxkZXJDbGFzcy5nZXRNZXRob2QoImdldEhUTUxEb2N1bWVudCIsIE5PX0NMQVNTRVMpOworCisgICAgICBDbGFzcyBodG1sRE9NSW1wbCA9CisgICAgICAgICAgY2xhc3NMb2FkZXIubG9hZENsYXNzKAorICAgICAgICAgICJvcmcuYXBhY2hlLmh0bWwuZG9tLkhUTUxET01JbXBsZW1lbnRhdGlvbkltcGwiKTsKKyAgICAgIE1ldGhvZCBtZXRob2QgPQorICAgICAgICAgIGh0bWxET01JbXBsLmdldE1ldGhvZCgiZ2V0SFRNTERPTUltcGxlbWVudGF0aW9uIiwgTk9fQ0xBU1NFUyk7CisgICAgICBkb21JbXBsID0gKERPTUltcGxlbWVudGF0aW9uKSBtZXRob2QuaW52b2tlKG51bGwsIE5PX09CSkVDVFMpOworCisgICAgICBDbGFzcyBzYXhGYWN0b3J5Q2xhc3MgPQorICAgICAgICAgIGNsYXNzTG9hZGVyLmxvYWRDbGFzcygKKyAgICAgICAgICAib3JnLmFwYWNoZS54ZXJjZXMuamF4cC5TQVhQYXJzZXJGYWN0b3J5SW1wbCIpOworICAgICAgZmFjdG9yeSA9IChTQVhQYXJzZXJGYWN0b3J5KSBzYXhGYWN0b3J5Q2xhc3MubmV3SW5zdGFuY2UoKTsKKyAgICB9CisgICAgY2F0Y2ggKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZXgpIHsKKyAgICAgIHRocm93IG5ldyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uKAorICAgICAgICAgIGV4LmdldFRhcmdldEV4Y2VwdGlvbigpLAorICAgICAgICAgIG51bGwpOworICAgIH0KKyAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICB0aHJvdyBuZXcgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbihleCwgbnVsbCk7CisgICAgfQorCisgICAgLy8KKyAgICAvLyAgICBhcHBseSBzZXR0aW5ncyB0byBzZWxlY3RlZCBkb2N1bWVudCBidWlsZGVyCisgICAgLy8gICAgICAgICBtYXkgdGhyb3cgZXhjZXB0aW9uIGlmIGluY29tcGF0aWJsZQorICAgIGlmIChzZXR0aW5ncyAhPSBudWxsKSB7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNldHRpbmdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIC8vICAgICAgICBzZXR0aW5nc1tpXS5hcHBseVNldHRpbmcoZmFjdG9yeSk7CisgICAgICB9CisgICAgfQorICAgIHRyeSB7CisgICAgICBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOworICAgIH0KKyAgICBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleCkgeworICAgICAgdGhyb3cgbmV3IERPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24oZXgsIG51bGwpOworICAgIH0KKyAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGV4KSB7CisgICAgICB0aHJvdyBuZXcgRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbihleCwgbnVsbCk7CisgICAgfQorICB9CisKKyAgcHVibGljIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IG5ld0luc3RhbmNlKERvY3VtZW50QnVpbGRlclNldHRpbmdbXQorICAgICAgbmV3U2V0dGluZ3MpIHRocm93cyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICBpZiAobmV3U2V0dGluZ3MgPT0gbnVsbCkgeworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdbXSBtZXJnZWRTZXR0aW5ncyA9IG1lcmdlU2V0dGluZ3MobmV3U2V0dGluZ3MpOworICAgIHJldHVybiBuZXcgWGVyY2VzSFRNTERvY3VtZW50QnVpbGRlckZhY3RvcnkobWVyZ2VkU2V0dGluZ3MpOworICB9CisKKyAgcHJpdmF0ZSBjbGFzcyBIVE1MSGFuZGxlcgorICAgICAgZXh0ZW5kcyBEZWZhdWx0SGFuZGxlcgorICAgICAgaW1wbGVtZW50cyBBdHRyaWJ1dGVMaXN0IHsKKyAgICBwcml2YXRlIGZpbmFsIERvY3VtZW50SGFuZGxlciBodG1sQnVpbGRlcjsKKyAgICBwcml2YXRlIGZpbmFsIE1ldGhvZCBnZXRIVE1MRG9jdW1lbnRNZXRob2Q7CisgICAgcHJpdmF0ZSBBdHRyaWJ1dGVzIGN1cnJlbnRBdHRyaWJ1dGVzOworCisgICAgcHVibGljIEhUTUxIYW5kbGVyKAorICAgICAgICBDb25zdHJ1Y3RvciBodG1sQnVpbGRlckNvbnN0cnVjdG9yLAorICAgICAgICBNZXRob2QgZ2V0SFRNTERvY3VtZW50TWV0aG9kKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgIGh0bWxCdWlsZGVyID0KKyAgICAgICAgICAoRG9jdW1lbnRIYW5kbGVyKSBodG1sQnVpbGRlckNvbnN0cnVjdG9yLm5ld0luc3RhbmNlKAorICAgICAgICAgIG5ldyBPYmplY3RbMF0pOworICAgICAgdGhpcy5nZXRIVE1MRG9jdW1lbnRNZXRob2QgPSBnZXRIVE1MRG9jdW1lbnRNZXRob2Q7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgaHRtbEJ1aWxkZXIuc3RhcnREb2N1bWVudCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICBodG1sQnVpbGRlci5lbmREb2N1bWVudCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKKyAgICAgICAgU3RyaW5nIHVyaSwKKyAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSwKKyAgICAgICAgU3RyaW5nIHFOYW1lLAorICAgICAgICBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgY3VycmVudEF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzOworICAgICAgaHRtbEJ1aWxkZXIuc3RhcnRFbGVtZW50KHFOYW1lLCB0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkgdGhyb3dzCisgICAgICAgIFNBWEV4Y2VwdGlvbiB7CisgICAgICBodG1sQnVpbGRlci5lbmRFbGVtZW50KHFOYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB0aHJvd3MKKyAgICAgICAgU0FYRXhjZXB0aW9uIHsKKyAgICAgIGh0bWxCdWlsZGVyLmNoYXJhY3RlcnMoY2gsIHN0YXJ0LCBsZW5ndGgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHRocm93cworICAgICAgICBTQVhFeGNlcHRpb24geworICAgICAgaHRtbEJ1aWxkZXIuaWdub3JhYmxlV2hpdGVzcGFjZShjaCwgc3RhcnQsIGxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKSB0aHJvd3MKKyAgICAgICAgU0FYRXhjZXB0aW9uIHsKKyAgICAgIGh0bWxCdWlsZGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEpOworICAgIH0KKworICAgIHB1YmxpYyBEb2N1bWVudCBnZXRIVE1MRG9jdW1lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiAoRG9jdW1lbnQpIGdldEhUTUxEb2N1bWVudE1ldGhvZC5pbnZva2UoCisgICAgICAgICAgaHRtbEJ1aWxkZXIsCisgICAgICAgICAgTk9fT0JKRUNUUyk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7CisgICAgICByZXR1cm4gY3VycmVudEF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKGludCBpKSB7CisgICAgICByZXR1cm4gY3VycmVudEF0dHJpYnV0ZXMuZ2V0UU5hbWUoaSk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRUeXBlKGludCBpKSB7CisgICAgICByZXR1cm4gY3VycmVudEF0dHJpYnV0ZXMuZ2V0VHlwZShpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKGludCBpKSB7CisgICAgICByZXR1cm4gY3VycmVudEF0dHJpYnV0ZXMuZ2V0VmFsdWUoaSk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRUeXBlKFN0cmluZyBuYW1lKSB7CisgICAgICByZXR1cm4gY3VycmVudEF0dHJpYnV0ZXMuZ2V0VHlwZShuYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKFN0cmluZyBuYW1lKSB7CisgICAgICByZXR1cm4gY3VycmVudEF0dHJpYnV0ZXMuZ2V0VmFsdWUobmFtZSk7CisgICAgfQorCisgIH0KKworICBwdWJsaWMgRG9jdW1lbnQgbG9hZChqYXZhLm5ldC5VUkwgdXJsKSB0aHJvd3MgRE9NVGVzdExvYWRFeGNlcHRpb24geworICAgIERvY3VtZW50IGRvYyA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIFNBWFBhcnNlciBwYXJzZXIgPSBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOworICAgICAgSFRNTEhhbmRsZXIgaGFuZGxlciA9CisgICAgICAgICAgbmV3IEhUTUxIYW5kbGVyKGh0bWxCdWlsZGVyQ29uc3RydWN0b3IsIGdldEhUTUxEb2N1bWVudE1ldGhvZCk7CisgICAgICBwYXJzZXIucGFyc2UodXJsLnRvU3RyaW5nKCksIGhhbmRsZXIpOworICAgICAgZG9jID0gaGFuZGxlci5nZXRIVE1MRG9jdW1lbnQoKTsKKyAgICB9CisgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgdGhyb3cgbmV3IERPTVRlc3RMb2FkRXhjZXB0aW9uKGV4KTsKKyAgICB9CisgICAgcmV0dXJuIGRvYzsKKyAgfQorCisgIHB1YmxpYyBET01JbXBsZW1lbnRhdGlvbiBnZXRET01JbXBsZW1lbnRhdGlvbigpIHsKKyAgICByZXR1cm4gZG9tSW1wbDsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGhhc0ZlYXR1cmUoU3RyaW5nIGZlYXR1cmUsIFN0cmluZyB2ZXJzaW9uKSB7CisgICAgcmV0dXJuIGRvbUltcGwuaGFzRmVhdHVyZShmZWF0dXJlLCB2ZXJzaW9uKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGlzQ29hbGVzY2luZygpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBpc0V4cGFuZEVudGl0eVJlZmVyZW5jZXMoKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gaXNJZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSgpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBpc05hbWVzcGFjZUF3YXJlKCkgeworICAgIHJldHVybiBmYWN0b3J5LmlzTmFtZXNwYWNlQXdhcmUoKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGlzVmFsaWRhdGluZygpIHsKKyAgICByZXR1cm4gZmFjdG9yeS5pc1ZhbGlkYXRpbmcoKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIGdldENvbmZpZ3VyYXRpb24xKCkgeworICAgIHJldHVybiBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RDb2FsZXNjaW5nLAorICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5vdEV4cGFuZEVudGl0eVJlZmVyZW5jZXMsCisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcubm90SWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UsCisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcubm90TmFtZXNwYWNlQXdhcmUsCisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcubm90VmFsaWRhdGluZ307CisgIH0KKworICBwdWJsaWMgc3RhdGljIERvY3VtZW50QnVpbGRlclNldHRpbmdbXSBnZXRDb25maWd1cmF0aW9uMigpIHsKKyAgICByZXR1cm4gbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CisgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcubm90Q29hbGVzY2luZywKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5leHBhbmRFbnRpdHlSZWZlcmVuY2VzLAorICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLmlnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlLAorICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlLAorICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLnZhbGlkYXRpbmd9OworCisgIH0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9UZXN0QmF0aWsuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdEJhdGlrLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTgxYjM0NAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdEJhdGlrLmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5CYXRpa1Rlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nOworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworCitwdWJsaWMgY2xhc3MgVGVzdEJhdGlrIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKyAgICAgICAgbmV3IEJhdGlrVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkobmV3IERvY3VtZW50QnVpbGRlclNldHRpbmdbMF0pOworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL1Rlc3RDcmltc29uLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL1Rlc3RDcmltc29uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDk2M2I2NAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdENyaW1zb24uamF2YQpAQCAtMCwwICsxLDQ4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworcHVibGljIGNsYXNzIFRlc3RDcmltc29uIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGNyaW1zb25GYWN0b3J5ID0gKERvY3VtZW50QnVpbGRlckZhY3RvcnkpCisgICAgICBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLmFwYWNoZS5jcmltc29uLmpheHAuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeUltcGwiKS5uZXdJbnN0YW5jZSgpOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkoY3JpbXNvbkZhY3RvcnksCisgICAgICAgICAgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24xKCkpOworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL1Rlc3RDcmltc29uQWx0Q29uZmlnLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL1Rlc3RDcmltc29uQWx0Q29uZmlnLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTI0ZDhjZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdENyaW1zb25BbHRDb25maWcuamF2YQpAQCAtMCwwICsxLDQ4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworcHVibGljIGNsYXNzIFRlc3RDcmltc29uQWx0Q29uZmlnIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGNyaW1zb25GYWN0b3J5ID0gKERvY3VtZW50QnVpbGRlckZhY3RvcnkpCisgICAgICBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLmFwYWNoZS5jcmltc29uLmpheHAuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeUltcGwiKS5uZXdJbnN0YW5jZSgpOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkoY3JpbXNvbkZhY3RvcnksCisgICAgICAgICAgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24yKCkpOworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL1Rlc3RET000Si5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9UZXN0RE9NNEouamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMzY4ZDQ0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9UZXN0RE9NNEouamF2YQpAQCAtMCwwICsxLDQzIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTTRKVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmc7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKK3B1YmxpYyBjbGFzcyBUZXN0RE9NNEogZXh0ZW5kcyBUZXN0U3VpdGUgeworCisgIHB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbgorICB7CisgICAgQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmUuYWxsdGVzdHMiKTsKKyAgICBDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPSB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorICAgICAgICBuZXcgRE9NNEpUZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeShuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1swXSk7CisKKyAgICBPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisgICAgcmV0dXJuIG5ldyBKVW5pdFRlc3RTdWl0ZUFkYXB0ZXIoKERPTVRlc3RTdWl0ZSkgdGVzdCk7CisgIH0KKworCit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdERlZmF1bHRMUy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9UZXN0RGVmYXVsdExTLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjg5MGE3MgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdERlZmF1bHRMUy5qYXZhCkBAIC0wLDAgKzEsNTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUKKyAqIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4KKyAqIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZSBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcworICogcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKKyAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKKyAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlCisgKiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkxTRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiBUZXN0IHN1aXRlIHRoYXQgcnVucyBhbGwgRE9NIEwxIENvcmUgdGVzdHMgdXNpbmcgdGhlCisgKiBEZWZhdWx0IExTIHBhcnNlciBpbiBkZWZhdWx0IGNvbmZpZ3VyYXRpb24uCisgKiAKKyAqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyAqIAorICovCitwdWJsaWMgY2xhc3MgVGVzdERlZmF1bHRMUyBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKwlwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworCQlDbGFzcyB0ZXN0Q2xhc3MgPQorCQkJQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoCisJCQkJIm9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmUuYWxsdGVzdHMiKTsKKwkJQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0KKwkJCXRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcigKKwkJCQluZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisJCURPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorCQkJbmV3IExTRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKwkJCQlKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisKKwkJT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworCQlyZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKwl9CisKK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdERlZmF1bHRMU0FsdENvbmZpZy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9UZXN0RGVmYXVsdExTQWx0Q29uZmlnLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWU4ZTI2NAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdERlZmF1bHRMU0FsdENvbmZpZy5qYXZhCkBAIC0wLDAgKzEsNTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUKKyAqIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4KKyAqIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZSBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcworICogcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKKyAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKKyAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlCisgKiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkxTRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiBUZXN0IHN1aXRlIHRoYXQgcnVucyBhbGwgRE9NIEwxIENvcmUgdGVzdHMgdXNpbmcgdGhlCisgKiBEZWZhdWx0IExTIHBhcnNlciBpbiBhbiBhbHRlcm5hdGUgY29uZmlndXJhdGlvbi4KKyAqIAorICogQGF1dGhvciBDdXJ0IEFybm9sZAorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0RGVmYXVsdExTQWx0Q29uZmlnIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworCXB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJCUNsYXNzIHRlc3RDbGFzcyA9CisJCQlDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygKKwkJCQkib3JnLnczYy5kb210cy5sZXZlbDEuY29yZS5hbGx0ZXN0cyIpOworCQlDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPQorCQkJdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKAorCQkJCW5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKwkJRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisJCQluZXcgTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KAorCQkJCUpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMigpKTsKKworCQlPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9UZXN0RGVmYXVsdFBhcnNlci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9UZXN0RGVmYXVsdFBhcnNlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZiNDNkZmIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL1Rlc3REZWZhdWx0UGFyc2VyLmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworcHVibGljIGNsYXNzIFRlc3REZWZhdWx0UGFyc2VyIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKyAgICAgICAgbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeShudWxsLAorICAgICAgICAgIEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgfQorCisKK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9UZXN0RGVmYXVsdFBhcnNlckFsdENvbmZpZy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9UZXN0RGVmYXVsdFBhcnNlckFsdENvbmZpZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNjMTliMTAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL1Rlc3REZWZhdWx0UGFyc2VyQWx0Q29uZmlnLmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworcHVibGljIGNsYXNzIFRlc3REZWZhdWx0UGFyc2VyQWx0Q29uZmlnIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKyAgICAgICAgbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeShudWxsLAorICAgICAgICAgIEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMigpKTsKKworICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgfQorCisKK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9UZXN0R05VSkFYUC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9UZXN0R05VSkFYUC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjZWJlODgKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL1Rlc3RHTlVKQVhQLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKK3B1YmxpYyBjbGFzcyBUZXN0R05VSkFYUCBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKyAgcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uCisgIHsKKyAgICBDbGFzcyB0ZXN0Q2xhc3MgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLnczYy5kb210cy5sZXZlbDEuY29yZS5hbGx0ZXN0cyIpOworICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9IHRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisKKyAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGdudWpheHBGYWN0b3J5ID0gKERvY3VtZW50QnVpbGRlckZhY3RvcnkpCisgICAgICBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLgorICAgICAgICBsb2FkQ2xhc3MoImdudS54bWwuZG9tLkpBWFBGYWN0b3J5IikubmV3SW5zdGFuY2UoKTsKKworICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorICAgICAgICBuZXcgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5KGdudWpheHBGYWN0b3J5LAorICAgICAgICAgIEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL1Rlc3RHTlVKQVhQQWx0Q29uZmlnLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL1Rlc3RHTlVKQVhQQWx0Q29uZmlnLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTkwMGRiMQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdEdOVUpBWFBBbHRDb25maWcuamF2YQpAQCAtMCwwICsxLDQ5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworcHVibGljIGNsYXNzIFRlc3RHTlVKQVhQQWx0Q29uZmlnIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGdudWpheHBGYWN0b3J5ID0gKERvY3VtZW50QnVpbGRlckZhY3RvcnkpCisgICAgICBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLgorICAgICAgICBsb2FkQ2xhc3MoImdudS54bWwuZG9tLkpBWFBGYWN0b3J5IikubmV3SW5zdGFuY2UoKTsKKworICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorICAgICAgICBuZXcgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5KGdudWpheHBGYWN0b3J5LAorICAgICAgICAgIEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMigpKTsKKworICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgfQorCisKK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9UZXN0SlRpZHkuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdEpUaWR5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTJlY2YzZgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdEpUaWR5LmphdmEKQEAgLTAsMCArMSw0MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmc7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVGlkeURvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKK3B1YmxpYyBjbGFzcyBUZXN0SlRpZHkgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisgIHB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbgorICB7CisgICAgQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmUuYWxsdGVzdHMiKTsKKyAgICBDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPSB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorICAgICAgICBuZXcgSlRpZHlEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nWzBdKTsKKworICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL1Rlc3RPcmFjbGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdE9yYWNsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk2YzlmMzYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL1Rlc3RPcmFjbGUuamF2YQpAQCAtMCwwICsxLDUwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworcHVibGljIGNsYXNzIFRlc3RPcmFjbGUgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisgIHB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbgorICB7CisgICAgQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmUuYWxsdGVzdHMiKTsKKyAgICBDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPSB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworICAgIERvY3VtZW50QnVpbGRlckZhY3Rvcnkgb3JhY2xlRmFjdG9yeSA9IChEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KQorICAgICAgQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS4KKyAgICAgICAgbG9hZENsYXNzKCJvcmFjbGUueG1sLmpheHAuSlhEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IikubmV3SW5zdGFuY2UoKTsKKworICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorICAgICAgICBuZXcgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5KG9yYWNsZUZhY3RvcnksCisgICAgICAgICAgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24xKCkpOworCisKKyAgICBPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisgICAgcmV0dXJuIG5ldyBKVW5pdFRlc3RTdWl0ZUFkYXB0ZXIoKERPTVRlc3RTdWl0ZSkgdGVzdCk7CisgIH0KKworCit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdE9yYWNsZUFsdENvbmZpZy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9UZXN0T3JhY2xlQWx0Q29uZmlnLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTY4YWJkMAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdE9yYWNsZUFsdENvbmZpZy5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworCitwdWJsaWMgY2xhc3MgVGVzdE9yYWNsZUFsdENvbmZpZyBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKyAgcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uCisgIHsKKyAgICBDbGFzcyB0ZXN0Q2xhc3MgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLnczYy5kb210cy5sZXZlbDEuY29yZS5hbGx0ZXN0cyIpOworICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9IHRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBvcmFjbGVGYWN0b3J5ID0gKERvY3VtZW50QnVpbGRlckZhY3RvcnkpCisgICAgICBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLgorICAgICAgICBsb2FkQ2xhc3MoIm9yYWNsZS54bWwuamF4cC5KWERvY3VtZW50QnVpbGRlckZhY3RvcnkiKS5uZXdJbnN0YW5jZSgpOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnkob3JhY2xlRmFjdG9yeSwKKyAgICAgICAgICBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisKKyAgICBPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisgICAgcmV0dXJuIG5ldyBKVW5pdFRlc3RTdWl0ZUFkYXB0ZXIoKERPTVRlc3RTdWl0ZSkgdGVzdCk7CisgIH0KKworCit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdFhlcmNlcy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9UZXN0WGVyY2VzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjY4YmFkMAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdFhlcmNlcy5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworCitwdWJsaWMgY2xhc3MgVGVzdFhlcmNlcyBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKyAgcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uCisgIHsKKyAgICBDbGFzcyB0ZXN0Q2xhc3MgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLnczYy5kb210cy5sZXZlbDEuY29yZS5hbGx0ZXN0cyIpOworICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9IHRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB4ZXJjZXNGYWN0b3J5ID0gKERvY3VtZW50QnVpbGRlckZhY3RvcnkpCisgICAgICBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLmFwYWNoZS54ZXJjZXMuamF4cC5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbCIpLm5ld0luc3RhbmNlKCk7CisKKyAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKyAgICAgICAgbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSh4ZXJjZXNGYWN0b3J5LAorICAgICAgICAgIEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL1Rlc3RYZXJjZXNBbHRDb25maWcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvVGVzdFhlcmNlc0FsdENvbmZpZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc0YjNjNGMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL1Rlc3RYZXJjZXNBbHRDb25maWcuamF2YQpAQCAtMCwwICsxLDQ4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworcHVibGljIGNsYXNzIFRlc3RYZXJjZXNBbHRDb25maWcgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisgIHB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbgorICB7CisgICAgQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmUuYWxsdGVzdHMiKTsKKyAgICBDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPSB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgeGVyY2VzRmFjdG9yeSA9IChEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KQorICAgICAgQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy5hcGFjaGUueGVyY2VzLmpheHAuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeUltcGwiKS5uZXdJbnN0YW5jZSgpOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkoeGVyY2VzRmFjdG9yeSwKKyAgICAgICAgICBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisKKyAgICBPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisgICAgcmV0dXJuIG5ldyBKVW5pdFRlc3RTdWl0ZUFkYXB0ZXIoKERPTVRlc3RTdWl0ZSkgdGVzdCk7CisgIH0KKworCit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYWxsdGVzdHMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYWxsdGVzdHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYzkwN2YyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hbGx0ZXN0cy5qYXZhCkBAIC0wLDAgKzEsNTk1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U2luazsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKy8qKgorICogCisqIEBhdXRob3IgRE9NIFRlc3QgU3VpdGUgUHJvamVjdAorKi8KK3B1YmxpYyBjbGFzcyBhbGx0ZXN0cyBleHRlbmRzIERPTVRlc3RTdWl0ZSB7CisKKyAgICAvKioKKyAgICAqIENvbnN0cnVjdG9yCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3MgRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggc2V0dGluZ3MKKyAgICAqLworICAgcHVibGljIGFsbHRlc3RzKERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpIHRocm93cyBFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAgIHNldEZhY3RvcnkoZmFjdG9yeSk7CisgICB9CisKKyAgIC8qKgorICAgICogICBCdWlsZCB0ZXN0IHN1aXRlIGJ5IGFkZGluZyBlYWNoIHRlc3QgdG8gdGhlIHRlc3Qgc2luaworICAgICogICBAcGFyYW0gc2luayB0ZXN0IHNpbmsKKyAgICAqLworICAgcHVibGljIHZvaWQgYnVpbGQoRE9NVGVzdFNpbmsgc2luaykgeworICAgICAgc2luay5hZGRUZXN0KGF0dHJjcmVhdGVkb2N1bWVudGZyYWdtZW50LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChhdHRyY3JlYXRldGV4dG5vZGUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGF0dHJjcmVhdGV0ZXh0bm9kZTIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoYXR0cmRlZmF1bHR2YWx1ZS5jbGFzcyk7IC8vamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjogTm8gdmFsaWRhdGluZyBEb2N1bWVudEJ1aWxkZXIgaW1wbGVtZW50YXRpb24gYXZhaWxhYmxlCisgICAgICBzaW5rLmFkZFRlc3QoYXR0cmVmZmVjdGl2ZXZhbHVlLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGF0dHJlbnRpdHlyZXBsYWNlbWVudC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoYXR0cm5hbWUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGF0dHJuZXh0c2libGluZ251bGwuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoYXR0cm5vdHNwZWNpZmllZHZhbHVlLmNsYXNzKTsgLy8gamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjogTm8gdmFsaWRhdGluZyBEb2N1bWVudEJ1aWxkZXIgaW1wbGVtZW50YXRpb24gYXZhaWxhYmxlCisgICAgICBzaW5rLmFkZFRlc3QoYXR0cnBhcmVudG5vZGVudWxsLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChhdHRycHJldmlvdXNzaWJsaW5nbnVsbC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChhdHRyc2V0dmFsdWVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoYXR0cnNldHZhbHVlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGF0dHJzcGVjaWZpZWR2YWx1ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoYXR0cnNwZWNpZmllZHZhbHVlY2hhbmdlZC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChhdHRyc3BlY2lmaWVkdmFsdWVyZW1vdmUuY2xhc3MpOyAvLyBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOiBObyB2YWxpZGF0aW5nIERvY3VtZW50QnVpbGRlciBpbXBsZW1lbnRhdGlvbiBhdmFpbGFibGUKKyAgICAgIHNpbmsuYWRkVGVzdChjZGF0YXNlY3Rpb25nZXRkYXRhLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGNkYXRhc2VjdGlvbm5vcm1hbGl6ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGNoYXJhY3RlcmRhdGFhcHBlbmRkYXRhZ2V0ZGF0YS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChjaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChjaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChjaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWJlZ2luaW5nLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChjaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWVuZC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFleGNlZWRzbGVuZ3RoLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChjaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWdldGxlbmd0aGFuZGRhdGEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGNoYXJhY3RlcmRhdGFkZWxldGVkYXRhbWlkZGxlLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGNoYXJhY3RlcmRhdGFkZWxldGVkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGNoYXJhY3RlcmRhdGFkZWxldGVkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGNoYXJhY3RlcmRhdGFnZXRkYXRhLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChjaGFyYWN0ZXJkYXRhZ2V0bGVuZ3RoLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGNoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhY291bnRuZWdhdGl2ZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChjaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyZGVsZXRlZGF0YW9mZnNldGdyZWF0ZXIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFvZmZzZXRuZWdhdGl2ZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChjaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyaW5zZXJ0ZGF0YW9mZnNldGdyZWF0ZXIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmluc2VydGRhdGFvZmZzZXRuZWdhdGl2ZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChjaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJycmVwbGFjZWRhdGFjb3VudG5lZ2F0aXZlLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGNoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJyZXBsYWNlZGF0YW9mZnNldGdyZWF0ZXIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhb2Zmc2V0bmVnYXRpdmUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ2NvdW50bmVnYXRpdmUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ25lZ2F0aXZlb2Zmc2V0LmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGNoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJzdWJzdHJpbmdvZmZzZXRncmVhdGVyLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChjaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YWJlZ2lubmluZy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY2hhcmFjdGVyZGF0YWluc2VydGRhdGFlbmQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGNoYXJhY3RlcmRhdGFpbnNlcnRkYXRhbWlkZGxlLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGNoYXJhY3RlcmRhdGFpbnNlcnRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGNoYXJhY3RlcmRhdGFpbnNlcnRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGNoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWJlZ2luaW5nLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChjaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFlbmQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGNoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWV4Y2VlZHNsZW5ndGhvZmFyZy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZXhjZWVkc2xlbmd0aG9mZGF0YS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhbWlkZGxlLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGNoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChjaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChjaGFyYWN0ZXJkYXRhc2V0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChjaGFyYWN0ZXJkYXRhc2V0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGNoYXJhY3RlcmRhdGFzZXRub2RldmFsdWUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoY2hhcmFjdGVyZGF0YXN1YnN0cmluZ2V4Y2VlZHN2YWx1ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY2hhcmFjdGVyZGF0YXN1YnN0cmluZ3ZhbHVlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChjb21tZW50Z2V0Y29tbWVudC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRjcmVhdGVjZGF0YXNlY3Rpb24uY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50Y3JlYXRlY29tbWVudC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRjcmVhdGVkb2N1bWVudGZyYWdtZW50LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGNyZWF0ZWVsZW1lbnQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50Y3JlYXRlZWxlbWVudGNhc2VzZW5zaXRpdmUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRjcmVhdGVlbGVtZW50ZGVmYXVsdGF0dHIuY2xhc3MpOyAvLyBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOiBObyB2YWxpZGF0aW5nIERvY3VtZW50QnVpbGRlciBpbXBsZW1lbnRhdGlvbiBhdmFpbGFibGUKKyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGNyZWF0ZWVudGl0eXJlZmVyZW5jZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGNyZWF0ZWVudGl0eXJlZmVyZW5jZWtub3duLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGNyZWF0ZXByb2Nlc3NpbmdpbnN0cnVjdGlvbi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRjcmVhdGV0ZXh0bm9kZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRnZXRkb2N0eXBlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGdldGRvY3R5cGVub2R0ZC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZWxlbmd0aC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1ldG90YWxsZW5ndGguY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV2YWx1ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRnZXRpbXBsZW1lbnRhdGlvbi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRnZXRyb290bm9kZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlYXR0cmlidXRlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbGVtZW50LmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWVudHJlZi5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbnRyZWYxLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZXBpLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZXBpMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnR0eXBlZ2V0ZG9jdHlwZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudHR5cGVnZXRlbnRpdGllcy5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudHR5cGVnZXRlbnRpdGllc2xlbmd0aC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudHR5cGVnZXRlbnRpdGllc3R5cGUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnR0eXBlZ2V0bm90YXRpb25zLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50dHlwZWdldG5vdGF0aW9uc3R5cGUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvbWltcGxlbWVudGF0aW9uZmVhdHVyZW5vdmVyc2lvbi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9taW1wbGVtZW50YXRpb25mZWF0dXJlbnVsbC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9taW1wbGVtZW50YXRpb25mZWF0dXJleG1sLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50YWRkbmV3YXR0cmlidXRlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50YXNzb2NpYXRlZGF0dHJpYnV0ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudGNoYW5nZWF0dHJpYnV0ZXZhbHVlLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRjcmVhdGVuZXdhdHRyaWJ1dGUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRnZXRhdHRyaWJ1dGVub2RlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50Z2V0YXR0cmlidXRlbm9kZW51bGwuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudGdldGVsZW1lbnRlbXB0eS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVhY2Nlc3Nub2RlbGlzdC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbm9tYXRjaC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVzcGVjaWFsdmFsdWUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRnZXR0YWduYW1lLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50aW51c2VhdHRyaWJ1dGVlcnIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50bm9ybWFsaXplLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50bm90Zm91bmRlcnIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudHJlbW92ZWF0dHJpYnV0ZS5jbGFzcyk7IC8vIGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb246IE5vIHZhbGlkYXRpbmcgRG9jdW1lbnRCdWlsZGVyIGltcGxlbWVudGF0aW9uIGF2YWlsYWJsZQorICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRyZW1vdmVhdHRyaWJ1dGVhZnRlcmNyZWF0ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vZGUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vZGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vZGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRyZW1vdmVhdHRyaWJ1dGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50cmVtb3ZlYXR0cmlidXRlcmVzdG9yZWRlZmF1bHR2YWx1ZS5jbGFzcyk7IC8vIGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb246IE5vIHZhbGlkYXRpbmcgRG9jdW1lbnRCdWlsZGVyIGltcGxlbWVudGF0aW9uIGF2YWlsYWJsZQorLy8gICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudHJlcGxhY2VhdHRyaWJ1dGV3aXRoc2VsZi5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50cmVwbGFjZWV4aXN0aW5nYXR0cmlidXRlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50cmVwbGFjZWV4aXN0aW5nYXR0cmlidXRlZ2V2YWx1ZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50cmV0cmlldmVhbGxhdHRyaWJ1dGVzLmNsYXNzKTsgLy8gamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjogTm8gdmFsaWRhdGluZyBEb2N1bWVudEJ1aWxkZXIgaW1wbGVtZW50YXRpb24gYXZhaWxhYmxlCisgICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudHJldHJpZXZlYXR0cnZhbHVlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50cmV0cmlldmV0YWduYW1lLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRzZXRhdHRyaWJ1dGVub2Rlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRzZXRhdHRyaWJ1dGVub2Rlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnVsbC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50c2V0YXR0cmlidXRlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRzZXRhdHRyaWJ1dGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudHdyb25nZG9jdW1lbnRlcnIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZW50aXR5Z2V0ZW50aXR5bmFtZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChlbnRpdHlnZXRwdWJsaWNpZC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChlbnRpdHlnZXRwdWJsaWNpZG51bGwuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5hbWVkbm9kZW1hcGNoaWxkbm9kZXJhbmdlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChuYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW0uY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5hbWVkbm9kZW1hcGludXNlYXR0cmlidXRlZXJyLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChuYW1lZG5vZGVtYXBub3Rmb3VuZGVyci5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwbnVtYmVyb2Zub2Rlcy5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW0uY2xhc3MpOyAvLyBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOiBObyB2YWxpZGF0aW5nIERvY3VtZW50QnVpbGRlciBpbXBsZW1lbnRhdGlvbiBhdmFpbGFibGUKKy8vICAgICAgc2luay5hZGRUZXN0KG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbWdldHZhbHVlLmNsYXNzKTsgLy8gamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjogTm8gdmFsaWRhdGluZyBEb2N1bWVudEJ1aWxkZXIgaW1wbGVtZW50YXRpb24gYXZhaWxhYmxlCisgICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtcmV0dXJubm9kZXZhbHVlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChuYW1lZG5vZGVtYXByZXR1cm5hdHRybm9kZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwcmV0dXJuZmlyc3RpdGVtLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChuYW1lZG5vZGVtYXByZXR1cm5sYXN0aXRlbS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwcmV0dXJubnVsbC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1yZXR1cm52YWx1ZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW10aGF0ZXhpc3RzLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW13aXRobmV3dmFsdWUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5hbWVkbm9kZW1hcHdyb25nZG9jdW1lbnRlcnIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVhcHBlbmRjaGlsZC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlYXBwZW5kY2hpbGRjaGlsZGV4aXN0cy5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlYXBwZW5kY2hpbGRkb2NmcmFnbWVudC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWFwcGVuZGNoaWxkZ2V0bm9kZW5hbWUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZWFwcGVuZGNoaWxkaW52YWxpZG5vZGV0eXBlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlYXBwZW5kY2hpbGRuZXdjaGlsZGRpZmZkb2N1bWVudC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWFwcGVuZGNoaWxkbm9kZWFuY2VzdG9yLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KG5vZGVhcHBlbmRjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlYXBwZW5kY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWF0dHJpYnV0ZW5vZGVhdHRyaWJ1dGUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVhdHRyaWJ1dGVub2RlbmFtZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWF0dHJpYnV0ZW5vZGV0eXBlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlYXR0cmlidXRlbm9kZXZhbHVlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlY2RhdGFzZWN0aW9ubm9kZWF0dHJpYnV0ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWNkYXRhc2VjdGlvbm5vZGVuYW1lLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlY2RhdGFzZWN0aW9ubm9kZXR5cGUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVjZGF0YXNlY3Rpb25ub2RldmFsdWUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVjaGlsZG5vZGVzLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KG5vZGVjaGlsZG5vZGVzYXBwZW5kY2hpbGQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVjaGlsZG5vZGVzZW1wdHkuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZWNsb25lYXR0cmlidXRlc2NvcGllZC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlY2xvbmVmYWxzZW5vY29weXRleHQuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZWNsb25lZ2V0cGFyZW50bnVsbC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlY2xvbmVub2RlZmFsc2UuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZWNsb25lbm9kZXRydWUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZWNsb25ldHJ1ZWNvcHl0ZXh0LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlY29tbWVudG5vZGVhdHRyaWJ1dGVzLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlY29tbWVudG5vZGVuYW1lLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlY29tbWVudG5vZGV0eXBlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlY29tbWVudG5vZGV2YWx1ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWRvY3VtZW50ZnJhZ21lbnRub2RlbmFtZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldHlwZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldmFsdWUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVkb2N1bWVudG5vZGVhdHRyaWJ1dGUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVkb2N1bWVudG5vZGVuYW1lLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlZG9jdW1lbnRub2RldHlwZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWRvY3VtZW50bm9kZXZhbHVlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlZG9jdW1lbnR0eXBlbm9kZW5hbWUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVkb2N1bWVudHR5cGVub2RldHlwZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWRvY3VtZW50dHlwZW5vZGV2YWx1ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWVsZW1lbnRub2RlYXR0cmlidXRlcy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWVsZW1lbnRub2RlbmFtZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWVsZW1lbnRub2RldHlwZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWVsZW1lbnRub2RldmFsdWUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZWVudGl0eW5vZGVhdHRyaWJ1dGVzLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KG5vZGVlbnRpdHlub2RlbmFtZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlZW50aXR5bm9kZXR5cGUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZWVudGl0eW5vZGV2YWx1ZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlZW50aXR5c2V0bm9kZXZhbHVlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlZW50aXR5cmVmZXJlbmNlbm9kZWF0dHJpYnV0ZXMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVlbnRpdHlyZWZlcmVuY2Vub2RlbmFtZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWVudGl0eXJlZmVyZW5jZW5vZGV0eXBlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlZW50aXR5cmVmZXJlbmNlbm9kZXZhbHVlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlZ2V0Zmlyc3RjaGlsZC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWdldGZpcnN0Y2hpbGRudWxsLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlZ2V0bGFzdGNoaWxkLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlZ2V0bGFzdGNoaWxkbnVsbC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWdldG5leHRzaWJsaW5nLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlZ2V0bmV4dHNpYmxpbmdudWxsLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlZ2V0b3duZXJkb2N1bWVudC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWdldG93bmVyZG9jdW1lbnRudWxsLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlZ2V0cHJldmlvdXNzaWJsaW5nLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlZ2V0cHJldmlvdXNzaWJsaW5nbnVsbC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWhhc2NoaWxkbm9kZXMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVoYXNjaGlsZG5vZGVzZmFsc2UuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZWluc2VydGJlZm9yZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlaW5zZXJ0YmVmb3JlZG9jZnJhZ21lbnQuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZWluc2VydGJlZm9yZWludmFsaWRub2RldHlwZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWluc2VydGJlZm9yZW5ld2NoaWxkZGlmZmRvY3VtZW50LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlaW5zZXJ0YmVmb3JlbmV3Y2hpbGRleGlzdHMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVpbnNlcnRiZWZvcmVub2RlYW5jZXN0b3IuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVpbnNlcnRiZWZvcmVub2RlbmFtZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlaW5zZXJ0YmVmb3Jlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KG5vZGVpbnNlcnRiZWZvcmVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlaW5zZXJ0YmVmb3JlcmVmY2hpbGRub25leGlzdGVudC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlaW5zZXJ0YmVmb3JlcmVmY2hpbGRudWxsLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlbGlzdGluZGV4ZXF1YWx6ZXJvLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlbGlzdGluZGV4Z2V0bGVuZ3RoLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlbGlzdGluZGV4Z2V0bGVuZ3Rob2ZlbXB0eWxpc3QuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVsaXN0aW5kZXhub3R6ZXJvLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlbGlzdHJldHVybmZpcnN0aXRlbS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWxpc3RyZXR1cm5sYXN0aXRlbS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWxpc3R0cmF2ZXJzZWxpc3QuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZW5vdGF0aW9ubm9kZWF0dHJpYnV0ZXMuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZW5vdGF0aW9ubm9kZW5hbWUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZW5vdGF0aW9ubm9kZXR5cGUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZW5vdGF0aW9ubm9kZXZhbHVlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlcGFyZW50bm9kZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZXBhcmVudG5vZGVudWxsLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZWF0dHJpYnV0ZXMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25ub2RlbmFtZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZXByb2Nlc3NpbmdpbnN0cnVjdGlvbm5vZGV0eXBlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZXZhbHVlLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KG5vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25zZXRub2RldmFsdWUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVyZW1vdmVjaGlsZC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZXJlbW92ZWNoaWxkZ2V0bm9kZW5hbWUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZXJlbW92ZWNoaWxkbm9kZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlcmVtb3ZlY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZXJlbW92ZWNoaWxkbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZXJlbW92ZWNoaWxkb2xkY2hpbGRub25leGlzdGVudC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlcmVwbGFjZWNoaWxkLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KG5vZGVyZXBsYWNlY2hpbGRpbnZhbGlkbm9kZXR5cGUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVyZXBsYWNlY2hpbGRuZXdjaGlsZGRpZmZkb2N1bWVudC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlcmVwbGFjZWNoaWxkbmV3Y2hpbGRleGlzdHMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVyZXBsYWNlY2hpbGRub2RlYW5jZXN0b3IuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVyZXBsYWNlY2hpbGRub2RlbmFtZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlcmVwbGFjZWNoaWxkbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KG5vZGVyZXBsYWNlY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RlcmVwbGFjZWNoaWxkb2xkY2hpbGRub25leGlzdGVudC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2Rlc2V0bm9kZXZhbHVlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KG5vZGVzZXRub2RldmFsdWVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZXRleHRub2RlYXR0cmlidXRlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RldGV4dG5vZGVuYW1lLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RldGV4dG5vZGV0eXBlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RldGV4dG5vZGV2YWx1ZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub3RhdGlvbmdldG5vdGF0aW9ubmFtZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub3RhdGlvbmdldHB1YmxpY2lkLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KG5vdGF0aW9uZ2V0cHVibGljaWRudWxsLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KG5vdGF0aW9uZ2V0c3lzdGVtaWQuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm90YXRpb25nZXRzeXN0ZW1pZG51bGwuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KHByb2Nlc3NpbmdpbnN0cnVjdGlvbmdldGRhdGEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KHByb2Nlc3NpbmdpbnN0cnVjdGlvbmdldHRhcmdldC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChwcm9jZXNzaW5naW5zdHJ1Y3Rpb25zZXRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KHByb2Nlc3NpbmdpbnN0cnVjdGlvbnNldGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdCh0ZXh0aW5kZXhzaXplZXJybmVnYXRpdmVvZmZzZXQuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QodGV4dGluZGV4c2l6ZWVycm9mZnNldG91dG9mYm91bmRzLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KHRleHRwYXJzZWludG9saXN0b2ZlbGVtZW50cy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QodGV4dHNwbGl0dGV4dGZvdXIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QodGV4dHNwbGl0dGV4dG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdCh0ZXh0c3BsaXR0ZXh0bm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KHRleHRzcGxpdHRleHRvbmUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KHRleHRzcGxpdHRleHR0aHJlZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdCh0ZXh0c3BsaXR0ZXh0dHdvLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdCh0ZXh0d2l0aG5vbWFya3VwLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RldmFsdWUwMS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2RldmFsdWUwMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZXZhbHVlMDMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGV2YWx1ZTA0LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RldmFsdWUwNS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZXZhbHVlMDYuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZXZhbHVlMDcuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZXZhbHVlMDguY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qobm9kZXZhbHVlMDkuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJjcmVhdGVkb2N1bWVudGZyYWdtZW50LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19hdHRyY3JlYXRldGV4dG5vZGUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJjcmVhdGV0ZXh0bm9kZTIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJlZmZlY3RpdmV2YWx1ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfYXR0cm5hbWUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJuZXh0c2libGluZ251bGwuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJwYXJlbnRub2RlbnVsbC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfYXR0cnByZXZpb3Vzc2libGluZ251bGwuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJzcGVjaWZpZWR2YWx1ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfYXR0cnNwZWNpZmllZHZhbHVlY2hhbmdlZC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhZ2V0ZGF0YS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFiZWdpbmluZy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFlbmQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZXhjZWVkc2xlbmd0aC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFnZXRsZW5ndGhhbmRkYXRhLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YW1pZGRsZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfY2hhcmFjdGVyZGF0YWdldGRhdGEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2NoYXJhY3RlcmRhdGFnZXRsZW5ndGguY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFjb3VudG5lZ2F0aXZlLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhb2Zmc2V0Z3JlYXRlci5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyZGVsZXRlZGF0YW9mZnNldG5lZ2F0aXZlLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJpbnNlcnRkYXRhb2Zmc2V0Z3JlYXRlci5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyaW5zZXJ0ZGF0YW9mZnNldG5lZ2F0aXZlLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJyZXBsYWNlZGF0YWNvdW50bmVnYXRpdmUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhb2Zmc2V0Z3JlYXRlci5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJycmVwbGFjZWRhdGFvZmZzZXRuZWdhdGl2ZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nY291bnRuZWdhdGl2ZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nbmVnYXRpdmVvZmZzZXQuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ29mZnNldGdyZWF0ZXIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhYmVnaW5uaW5nLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YWVuZC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfY2hhcmFjdGVyZGF0YWluc2VydGRhdGFtaWRkbGUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWJlZ2luaW5nLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFlbmQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWV4Y2VlZHNsZW5ndGhvZmFyZy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZXhjZWVkc2xlbmd0aG9mZGF0YS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhbWlkZGxlLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2NoYXJhY3RlcmRhdGFzZXRub2RldmFsdWUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfY2hhcmFjdGVyZGF0YXN1YnN0cmluZ2V4Y2VlZHN2YWx1ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfY2hhcmFjdGVyZGF0YXN1YnN0cmluZ3ZhbHVlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19jb21tZW50Z2V0Y29tbWVudC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfZG9jdW1lbnRjcmVhdGVjb21tZW50LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19kb2N1bWVudGNyZWF0ZWRvY3VtZW50ZnJhZ21lbnQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2RvY3VtZW50Y3JlYXRlZWxlbWVudC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfZG9jdW1lbnRjcmVhdGVlbGVtZW50Y2FzZXNlbnNpdGl2ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfZG9jdW1lbnRjcmVhdGV0ZXh0bm9kZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfZG9jdW1lbnRnZXRkb2N0eXBlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lbGVuZ3RoLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1ldG90YWxsZW5ndGguY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV2YWx1ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfZG9jdW1lbnRnZXRpbXBsZW1lbnRhdGlvbi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfZG9jdW1lbnRnZXRyb290bm9kZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlYXR0cmlidXRlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVhdHRyaWJ1dGUxLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbGVtZW50LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbGVtZW50MS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfZG9taW1wbGVtZW50YXRpb25mZWF0dXJlbm92ZXJzaW9uLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVudWxsLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmV4bWwuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2VsZW1lbnRhZGRuZXdhdHRyaWJ1dGUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2VsZW1lbnRhc3NvY2lhdGVkYXR0cmlidXRlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19lbGVtZW50Y2hhbmdlYXR0cmlidXRldmFsdWUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfZWxlbWVudGNyZWF0ZW5ld2F0dHJpYnV0ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfZWxlbWVudGdldGF0dHJpYnV0ZW5vZGUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnVsbC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19lbGVtZW50Z2V0ZWxlbWVudGVtcHR5LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZWFjY2Vzc25vZGVsaXN0LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVub21hdGNoLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZXNwZWNpYWx2YWx1ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfZWxlbWVudGdldHRhZ25hbWUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2VsZW1lbnRpbnVzZWF0dHJpYnV0ZWVyci5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfZWxlbWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb24uY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2VsZW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfZWxlbWVudG5vcm1hbGl6ZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19lbGVtZW50bm9ybWFsaXplMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfZWxlbWVudG5vdGZvdW5kZXJyLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19lbGVtZW50cmVtb3ZlYXR0cmlidXRlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19lbGVtZW50cmVtb3ZlYXR0cmlidXRlYWZ0ZXJjcmVhdGUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVub2RlLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2VsZW1lbnRyZXBsYWNlYXR0cmlidXRld2l0aHNlbGYuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfZWxlbWVudHJlcGxhY2VleGlzdGluZ2F0dHJpYnV0ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfZWxlbWVudHJlcGxhY2VleGlzdGluZ2F0dHJpYnV0ZWdldmFsdWUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfZWxlbWVudHJldHJpZXZlYWxsYXR0cmlidXRlcy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfZWxlbWVudHJldHJpZXZlYXR0cnZhbHVlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19lbGVtZW50cmV0cmlldmV0YWduYW1lLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19lbGVtZW50c2V0YXR0cmlidXRlbm9kZW51bGwuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2VsZW1lbnR3cm9uZ2RvY3VtZW50ZXJyLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2VudGl0aWVzcmVtb3ZlbmFtZWRpdGVtMS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19lbnRpdGllc3NldG5hbWVkaXRlbTEuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfbmFtZWRub2RlbWFwY2hpbGRub2RlcmFuZ2UuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbmFtZWRub2RlbWFwaW51c2VhdHRyaWJ1dGVlcnIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25hbWVkbm9kZW1hcG5vdGZvdW5kZXJyLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX25hbWVkbm9kZW1hcG51bWJlcm9mbm9kZXMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbmFtZWRub2RlbWFwcmV0dXJuYXR0cm5vZGUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfbmFtZWRub2RlbWFwcmV0dXJuZmlyc3RpdGVtLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX25hbWVkbm9kZW1hcHJldHVybmxhc3RpdGVtLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19uYW1lZG5vZGVtYXByZXR1cm5udWxsLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW0uY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXJldHVybnZhbHVlLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXRoYXRleGlzdHMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXdpdGhuZXd2YWx1ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbmFtZWRub2RlbWFwd3Jvbmdkb2N1bWVudGVyci5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWFwcGVuZGNoaWxkLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVhcHBlbmRjaGlsZGNoaWxkZXhpc3RzLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVhcHBlbmRjaGlsZGRvY2ZyYWdtZW50LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlYXBwZW5kY2hpbGRnZXRub2RlbmFtZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlYXBwZW5kY2hpbGRpbnZhbGlkbm9kZXR5cGUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVhcHBlbmRjaGlsZG5ld2NoaWxkZGlmZmRvY3VtZW50LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlYXBwZW5kY2hpbGRub2RlYW5jZXN0b3IuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVhdHRyaWJ1dGVub2RlYXR0cmlidXRlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlYXR0cmlidXRlbm9kZW5hbWUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVhdHRyaWJ1dGVub2RldHlwZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWF0dHJpYnV0ZW5vZGV2YWx1ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWNoaWxkbm9kZXMuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWNoaWxkbm9kZXNhcHBlbmRjaGlsZC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWNoaWxkbm9kZXNlbXB0eS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlY2xvbmVhdHRyaWJ1dGVzY29waWVkLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVjbG9uZWZhbHNlbm9jb3B5dGV4dC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlY2xvbmVnZXRwYXJlbnRudWxsLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVjbG9uZW5vZGVmYWxzZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlY2xvbmVub2RldHJ1ZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlY2xvbmV0cnVlY29weXRleHQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVjb21tZW50bm9kZWF0dHJpYnV0ZXMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVjb21tZW50bm9kZW5hbWUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVjb21tZW50bm9kZXR5cGUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVjb21tZW50bm9kZXZhbHVlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGVuYW1lLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGV0eXBlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGV2YWx1ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWRvY3VtZW50bm9kZWF0dHJpYnV0ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWRvY3VtZW50bm9kZW5hbWUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVkb2N1bWVudG5vZGV0eXBlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlZG9jdW1lbnRub2RldmFsdWUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWVsZW1lbnRub2RlYXR0cmlidXRlcy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWVsZW1lbnRub2RlbmFtZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWVsZW1lbnRub2RldHlwZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWVsZW1lbnRub2RldmFsdWUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVnZXRmaXJzdGNoaWxkLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlZ2V0Zmlyc3RjaGlsZG51bGwuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVnZXRsYXN0Y2hpbGQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVnZXRsYXN0Y2hpbGRudWxsLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlZ2V0bmV4dHNpYmxpbmcuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVnZXRuZXh0c2libGluZ251bGwuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVnZXRvd25lcmRvY3VtZW50LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlZ2V0b3duZXJkb2N1bWVudG51bGwuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVnZXRwcmV2aW91c3NpYmxpbmcuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVnZXRwcmV2aW91c3NpYmxpbmdudWxsLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlaGFzY2hpbGRub2Rlcy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWhhc2NoaWxkbm9kZXNmYWxzZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlaW5zZXJ0YmVmb3JlLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVpbnNlcnRiZWZvcmVkb2NmcmFnbWVudC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlaW5zZXJ0YmVmb3JlaW52YWxpZG5vZGV0eXBlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlaW5zZXJ0YmVmb3JlbmV3Y2hpbGRkaWZmZG9jdW1lbnQuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWluc2VydGJlZm9yZW5ld2NoaWxkZXhpc3RzLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlaW5zZXJ0YmVmb3Jlbm9kZWFuY2VzdG9yLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlaW5zZXJ0YmVmb3Jlbm9kZW5hbWUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWluc2VydGJlZm9yZXJlZmNoaWxkbm9uZXhpc3RlbnQuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWluc2VydGJlZm9yZXJlZmNoaWxkbnVsbC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWxpc3RpbmRleGVxdWFsemVyby5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWxpc3RpbmRleGdldGxlbmd0aC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWxpc3RpbmRleGdldGxlbmd0aG9mZW1wdHlsaXN0LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlbGlzdGluZGV4bm90emVyby5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWxpc3RyZXR1cm5maXJzdGl0ZW0uY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVsaXN0cmV0dXJubGFzdGl0ZW0uY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVsaXN0dHJhdmVyc2VsaXN0LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlcGFyZW50bm9kZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZXBhcmVudG5vZGVudWxsLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlcmVtb3ZlY2hpbGQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVyZW1vdmVjaGlsZGdldG5vZGVuYW1lLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVyZW1vdmVjaGlsZG5vZGUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZXJlbW92ZWNoaWxkb2xkY2hpbGRub25leGlzdGVudC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlcmVwbGFjZWNoaWxkLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVyZXBsYWNlY2hpbGRpbnZhbGlkbm9kZXR5cGUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVyZXBsYWNlY2hpbGRuZXdjaGlsZGRpZmZkb2N1bWVudC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlcmVwbGFjZWNoaWxkbmV3Y2hpbGRleGlzdHMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVyZXBsYWNlY2hpbGRub2RlYW5jZXN0b3IuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGVyZXBsYWNlY2hpbGRub2RlbmFtZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlcmVwbGFjZWNoaWxkb2xkY2hpbGRub25leGlzdGVudC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZXRleHRub2RlYXR0cmlidXRlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RldGV4dG5vZGVuYW1lLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RldGV4dG5vZGV0eXBlLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RldGV4dG5vZGV2YWx1ZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZXZhbHVlMDEuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZXZhbHVlMDIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGV2YWx1ZTAzLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RldmFsdWUwNC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZXZhbHVlMDUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25vZGV2YWx1ZTA2LmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX25vZGV2YWx1ZTA3LmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX25vZGV2YWx1ZTA4LmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX25vdGF0aW9uc3JlbW92ZW5hbWVkaXRlbTEuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfbm90YXRpb25zc2V0bmFtZWRpdGVtMS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY190ZXh0aW5kZXhzaXplZXJybmVnYXRpdmVvZmZzZXQuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfdGV4dGluZGV4c2l6ZWVycm9mZnNldG91dG9mYm91bmRzLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX3RleHRwYXJzZWludG9saXN0b2ZlbGVtZW50cy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfdGV4dHNwbGl0dGV4dGZvdXIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX3RleHRzcGxpdHRleHRvbmUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX3RleHRzcGxpdHRleHR0aHJlZS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY190ZXh0c3BsaXR0ZXh0dHdvLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY190ZXh0d2l0aG5vbWFya3VwLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJhcHBlbmRjaGlsZDEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJhcHBlbmRjaGlsZDIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfYXR0cmFwcGVuZGNoaWxkMy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfYXR0cmFwcGVuZGNoaWxkNC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19hdHRyYXBwZW5kY2hpbGQ1LmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJhcHBlbmRjaGlsZDYuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfYXR0cmNoaWxkbm9kZXMxLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJjaGlsZG5vZGVzMi5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19hdHRyY2xvbmVub2RlMS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19hdHRyZmlyc3RjaGlsZC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19hdHRyZ2V0dmFsdWUxLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJnZXR2YWx1ZTIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfYXR0cmhhc2NoaWxkbm9kZXMuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfYXR0cmluc2VydGJlZm9yZTEuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfYXR0cmluc2VydGJlZm9yZTIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfYXR0cmluc2VydGJlZm9yZTMuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfYXR0cmluc2VydGJlZm9yZTQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJpbnNlcnRiZWZvcmU1LmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJpbnNlcnRiZWZvcmU2LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19hdHRyaW5zZXJ0YmVmb3JlNy5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19hdHRybGFzdGNoaWxkLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJub3JtYWxpemUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfYXR0cnJlbW92ZWNoaWxkMS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoY19hdHRycmVtb3ZlY2hpbGQyLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJyZXBsYWNlY2hpbGQxLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJyZXBsYWNlY2hpbGQyLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX2F0dHJzZXR2YWx1ZTEuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfYXR0cnNldHZhbHVlMi5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChhdHRycmVtb3ZlY2hpbGQxLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGF0dHJyZXBsYWNlY2hpbGQxLmNsYXNzKTsKKworICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0IHN1aXRlCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0IHN1aXRlCisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2FsbHRlc3RzIjsKKyAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIGluZGl2aWR1YWwgdGVzdAorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihhbGx0ZXN0cy5jbGFzcywgYXJncyk7CisgICB9CisKK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cmNyZWF0ZWRvY3VtZW50ZnJhZ21lbnQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cmNyZWF0ZWRvY3VtZW50ZnJhZ21lbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMWM2YjFlCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRyY3JlYXRlZG9jdW1lbnRmcmFnbWVudC5qYXZhCkBAIC0wLDAgKzEsOTcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIEF0dHIgbm9kZXMgbWF5IGJlIGFzc29jaWF0ZWQgd2l0aCBFbGVtZW50IG5vZGVzIGNvbnRhaW5lZCB3aXRoaW4gYSBEb2N1bWVudEZyYWdtZW50LgorICogICBDcmVhdGUgYSBuZXcgRG9jdW1lbnRGcmFnbWVudCBhbmQgYWRkIGEgbmV3bHkgY3JlYXRlZCBFbGVtZW50IG5vZGUod2l0aCBvbmUgYXR0cmlidXRlKS4gIAorICogICBPbmNlIHRoZSBlbGVtZW50IGlzIGFkZGVkLCBpdHMgYXR0cmlidXRlIHNob3VsZCBiZSBhdmFpbGFibGUgYXMgYW4gYXR0cmlidXRlIGFzc29jaWF0ZWQgCisgKiAgIHdpdGggYW4gRWxlbWVudCB3aXRoaW4gYSBEb2N1bWVudEZyYWdtZW50LgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzVDQjA0QjUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM1Q0IwNEI1PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEYwODIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEYwODI8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtQjYzRUQxQTMiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUI2M0VEMUEzPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBhdHRyY3JlYXRlZG9jdW1lbnRmcmFnbWVudCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgYXR0cmNyZWF0ZWRvY3VtZW50ZnJhZ21lbnQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudEZyYWdtZW50IGRvY0ZyYWdtZW50OworICAgICAgRWxlbWVudCBuZXdPbmU7CisgICAgICBOb2RlIGRvbWVzdGljTm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBkb21lc3RpY0F0dHI7CisgICAgICBBdHRyIGF0dHJzOworICAgICAgU3RyaW5nIGF0dHJOYW1lOworICAgICAgTm9kZSBhcHBlbmRlZENoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZG9jRnJhZ21lbnQgPSBkb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOworICAgICAgbmV3T25lID0gZG9jLmNyZWF0ZUVsZW1lbnQoIm5ld0VsZW1lbnQiKTsKKyAgICAgIG5ld09uZS5zZXRBdHRyaWJ1dGUoIm5ld2RvbWVzdGljIiwgIlllcyIpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGRvY0ZyYWdtZW50LmFwcGVuZENoaWxkKG5ld09uZSk7CisgICAgICBkb21lc3RpY05vZGUgPSBkb2NGcmFnbWVudC5nZXRGaXJzdENoaWxkKCk7CisgICAgICBkb21lc3RpY0F0dHIgPSBkb21lc3RpY05vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXR0cnMgPSAoQXR0cikgZG9tZXN0aWNBdHRyLml0ZW0oMCk7CisgICAgICBhdHRyTmFtZSA9IGF0dHJzLmdldE5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0ckNyZWF0ZURvY3VtZW50RnJhZ21lbnRBc3NlcnQiLCAibmV3ZG9tZXN0aWMiLCBhdHRyTmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2F0dHJjcmVhdGVkb2N1bWVudGZyYWdtZW50IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihhdHRyY3JlYXRlZG9jdW1lbnRmcmFnbWVudC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cmNyZWF0ZXRleHRub2RlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2F0dHJjcmVhdGV0ZXh0bm9kZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFmZjgwZmYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2F0dHJjcmVhdGV0ZXh0bm9kZS5qYXZhCkBAIC0wLDAgKzEsOTggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0VmFsdWUoKSIgbWV0aG9kIGZvciBhbiBhdHRyaWJ1dGUgY3JlYXRlcyBhIAorICogICBUZXh0IG5vZGUgd2l0aCB0aGUgdW5wYXJzZWQgY29udGVudCBvZiB0aGUgc3RyaW5nLgorICogICBSZXRyaWV2ZSB0aGUgYXR0cmlidXRlIG5hbWVkICJzdHJlZXQiIGZyb20gdGhlIGxhc3QgCisgKiAgIGNoaWxkIG9mIG9mIHRoZSBmb3VydGggZW1wbG95ZWUgYW5kIGFzc2lnbiB0aGUgIlkmZW50MTsiIAorICogICBzdHJpbmcgdG8gaXRzIHZhbHVlIGF0dHJpYnV0ZS4gIFRoaXMgdmFsdWUgaXMgbm90IHlldAorICogICBwYXJzZWQgYW5kIHRoZXJlZm9yZSBzaG91bGQgc3RpbGwgYmUgdGhlIHNhbWUgdXBvbgorICogICByZXRyaWV2YWwuIFRoaXMgdGVzdCB1c2VzIHRoZSAiZ2V0TmFtZWRJdGVtKG5hbWUpIiBtZXRob2QKKyAqICAgZnJvbSB0aGUgTmFtZWROb2RlTWFwIGludGVyZmFjZS4gIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjIxNjYyNDc0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMjE2NjI0NzQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyQXByLzAwNTcuaHRtbCI+aHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyQXByLzAwNTcuaHRtbDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgYXR0cmNyZWF0ZXRleHRub2RlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBhdHRyY3JlYXRldGV4dG5vZGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhZGRyZXNzTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgc3RyZWV0QXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGFkZHJlc3NMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0Tm9kZSA9IGFkZHJlc3NMaXN0Lml0ZW0oMyk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgc3RyZWV0QXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgic3RyZWV0Iik7CisgICAgICBzdHJlZXRBdHRyLnNldFZhbHVlKCJZJmVudDE7Iik7CisgICAgICB2YWx1ZSA9IHN0cmVldEF0dHIuZ2V0VmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygidmFsdWUiLCAiWSZlbnQxOyIsIHZhbHVlKTsKKyAgICAgIHZhbHVlID0gc3RyZWV0QXR0ci5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZVZhbHVlIiwgIlkmZW50MTsiLCB2YWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2F0dHJjcmVhdGV0ZXh0bm9kZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oYXR0cmNyZWF0ZXRleHRub2RlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRyY3JlYXRldGV4dG5vZGUyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2F0dHJjcmVhdGV0ZXh0bm9kZTIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNzMzYzQzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRyY3JlYXRldGV4dG5vZGUyLmphdmEKQEAgLTAsMCArMSw5NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXROb2RlVmFsdWUoKSIgbWV0aG9kIGZvciBhbiBhdHRyaWJ1dGUgY3JlYXRlcyBhIAorICogICBUZXh0IG5vZGUgd2l0aCB0aGUgdW5wYXJzZWQgY29udGVudCBvZiB0aGUgc3RyaW5nLgorICogICBSZXRyaWV2ZSB0aGUgYXR0cmlidXRlIG5hbWVkICJzdHJlZXQiIGZyb20gdGhlIGxhc3QgCisgKiAgIGNoaWxkIG9mIG9mIHRoZSBmb3VydGggZW1wbG95ZWUgYW5kIGFzc2lnbiB0aGUgIlkmZW50MTsiIAorICogICBzdHJpbmcgdG8gaXRzIHZhbHVlIGF0dHJpYnV0ZS4gIFRoaXMgdmFsdWUgaXMgbm90IHlldAorICogICBwYXJzZWQgYW5kIHRoZXJlZm9yZSBzaG91bGQgc3RpbGwgYmUgdGhlIHNhbWUgdXBvbgorICogICByZXRyaWV2YWwuIFRoaXMgdGVzdCB1c2VzIHRoZSAiZ2V0TmFtZWRJdGVtKG5hbWUpIiBtZXRob2QKKyAqICAgZnJvbSB0aGUgTmFtZWROb2RlTWFwIGludGVyZmFjZS4gCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9saXN0cy53My5vcmcvQXJjaGl2ZXMvUHVibGljL3d3dy1kb20tdHMvMjAwMkFwci8wMDU3Lmh0bWwiPmh0dHA6Ly9saXN0cy53My5vcmcvQXJjaGl2ZXMvUHVibGljL3d3dy1kb20tdHMvMjAwMkFwci8wMDU3Lmh0bWw8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGF0dHJjcmVhdGV0ZXh0bm9kZTIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGF0dHJjcmVhdGV0ZXh0bm9kZTIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhZGRyZXNzTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgc3RyZWV0QXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGFkZHJlc3NMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0Tm9kZSA9IGFkZHJlc3NMaXN0Lml0ZW0oMyk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgc3RyZWV0QXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgic3RyZWV0Iik7CisgICAgICBzdHJlZXRBdHRyLnNldE5vZGVWYWx1ZSgiWSZlbnQxOyIpOworICAgICAgdmFsdWUgPSBzdHJlZXRBdHRyLmdldFZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlIiwgIlkmZW50MTsiLCB2YWx1ZSk7CisgICAgICB2YWx1ZSA9IHN0cmVldEF0dHIuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVWYWx1ZSIsICJZJmVudDE7IiwgdmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9hdHRyY3JlYXRldGV4dG5vZGUyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihhdHRyY3JlYXRldGV4dG5vZGUyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRyZGVmYXVsdHZhbHVlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2F0dHJkZWZhdWx0dmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNTFjNTg0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRyZGVmYXVsdHZhbHVlLmphdmEKQEAgLTAsMCArMSwxMDQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZXJlIGlzIG5vdCBhbiBleHBsaWNpdCB2YWx1ZSBhc3NpZ25lZCB0byBhbiBhdHRyaWJ1dGUKKyAqICAgYW5kIHRoZXJlIGlzIGEgZGVjbGFyYXRpb24gZm9yIHRoaXMgYXR0cmlidXRlIGFuZCB0aGF0CisgKiAgIGRlY2xhcmF0aW9uIGluY2x1ZGVzIGEgZGVmYXVsdCB2YWx1ZSwgdGhlbiB0aGF0IGRlZmF1bHQKKyAqICAgdmFsdWUgaXMgdGhlIGF0dHJpYnV0ZXMgZGVmYXVsdCB2YWx1ZS4KKyAqICAgUmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBuYW1lZCAic3RyZWV0IiBmcm9tIHRoZSBsYXN0IAorICogICBjaGlsZCBvZiBvZiB0aGUgZmlyc3QgZW1wbG95ZWUgYW5kIGV4YW1pbmUgaXRzIAorICogICB2YWx1ZS4gIFRoYXQgdmFsdWUgc2hvdWxkIGJlIHRoZSB2YWx1ZSBnaXZlbiB0aGUKKyAqICAgYXR0cmlidXRlIGluIHRoZSBEVEQgZmlsZS4gIFRoZSB0ZXN0IHVzZXMgdGhlIAorICogICAiZ2V0TmFtZWRJdGVtKG5hbWUpIiBtZXRob2QgZnJvbSB0aGUgTmFtZWROb2RlTWFwIAorICogICBpbnRlcmZhY2UuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwNzQ1Nzc1NDkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwNzQ1Nzc1NDk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyTWFyLzAwMDIuaHRtbCI+aHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyTWFyLzAwMDIuaHRtbDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgYXR0cmRlZmF1bHR2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgYXR0cmRlZmF1bHR2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy52YWxpZGF0aW5nCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NMaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBzdHJlZXRBdHRyOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGFkZHJlc3NMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0Tm9kZSA9IGFkZHJlc3NMaXN0Lml0ZW0oMCk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgc3RyZWV0QXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgic3RyZWV0Iik7CisgICAgICB2YWx1ZSA9IHN0cmVldEF0dHIuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJEZWZhdWx0VmFsdWVBc3NlcnQiLCAiWWVzIiwgdmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9hdHRyZGVmYXVsdHZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihhdHRyZGVmYXVsdHZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRyZWZmZWN0aXZldmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cmVmZmVjdGl2ZXZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGVmZTRmMAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cmVmZmVjdGl2ZXZhbHVlLmphdmEKQEAgLTAsMCArMSw5MSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgSWYgYW4gQXR0ciBpcyBleHBsaWNpdGx5IGFzc2lnbmVkIGFueSB2YWx1ZSwgdGhlbiB0aGF0IHZhbHVlIGlzIHRoZSBhdHRyaWJ1dGVzIGVmZmVjdGl2ZSB2YWx1ZS4KKyAqICAgUmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBuYW1lZCAiZG9tZXN0aWMiIGZyb20gdGhlIGxhc3QgY2hpbGQgb2Ygb2YgdGhlIGZpcnN0IGVtcGxveWVlIAorICogICBhbmQgZXhhbWluZSBpdHMgbm9kZVZhbHVlIGF0dHJpYnV0ZS4gIFRoaXMgdGVzdCB1c2VzIHRoZSAiZ2V0TmFtZWRJdGVtKG5hbWUpIiBtZXRob2QgCisgKiAgIGZyb20gdGhlIE5hbWVkTm9kZU1hcCBpbnRlcmZhY2UuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwNzQ1Nzc1NDkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwNzQ1Nzc1NDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGF0dHJlZmZlY3RpdmV2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgYXR0cmVmZmVjdGl2ZXZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NMaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBkb21lc3RpY0F0dHI7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgYWRkcmVzc0xpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3ROb2RlID0gYWRkcmVzc0xpc3QuaXRlbSgwKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBkb21lc3RpY0F0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oImRvbWVzdGljIik7CisgICAgICB2YWx1ZSA9IGRvbWVzdGljQXR0ci5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0ckVmZmVjdGl2ZVZhbHVlQXNzZXJ0IiwgIlllcyIsIHZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvYXR0cmVmZmVjdGl2ZXZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihhdHRyZWZmZWN0aXZldmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2F0dHJlbnRpdHlyZXBsYWNlbWVudC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRyZW50aXR5cmVwbGFjZW1lbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMjU4ODExCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRyZW50aXR5cmVwbGFjZW1lbnQuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0VmFsdWUoKSIgbWV0aG9kIHdpbGwgcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUKKyAqICAgYXR0cmlidXRlIGFzIGEgc3RyaW5nLiAgVGhlIGdlbmVyYWwgZW50aXR5IHJlZmVyZW5jZXMKKyAqICAgYXJlIHJlcGxhY2VkIHdpdGggdGhlaXIgdmFsdWVzLgorICogICBSZXRyaWV2ZSB0aGUgYXR0cmlidXRlIG5hbWVkICJzdHJlZXQiIGZyb20gdGhlIGxhc3QgCisgKiAgIGNoaWxkIG9mIG9mIHRoZSBmb3VydGggZW1wbG95ZWUgYW5kIGV4YW1pbmUgdGhlIHN0cmluZyAKKyAqICAgcmV0dXJuZWQgYnkgdGhlICJnZXRWYWx1ZSgpIiBtZXRob2QuICBUaGUgdmFsdWUgc2hvdWxkCisgKiAgIGJlIHNldCB0byAiWWVzIiBhZnRlciB0aGUgRW50aXR5UmVmZXJlbmNlIGlzCisgKiAgIHJlcGxhY2VkIHdpdGggaXRzIHZhbHVlLiAgVGhpcyB0ZXN0IHVzZXMgdGhlICAKKyAqICAgImdldE5hbWVkSXRlbShuYW1lKSIgbWV0aG9kIGZyb20gdGhlIE5hbWVkTm9kZU1hcCAKKyAqICAgaW50ZXJmYWNlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjIxNjYyNDc0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMjE2NjI0NzQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGF0dHJlbnRpdHlyZXBsYWNlbWVudCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgYXR0cmVudGl0eXJlcGxhY2VtZW50KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWRkcmVzc0xpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIHN0cmVldEF0dHI7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBhZGRyZXNzTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdE5vZGUgPSBhZGRyZXNzTGlzdC5pdGVtKDMpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3ROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHN0cmVldEF0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oInN0cmVldCIpOworICAgICAgdmFsdWUgPSBzdHJlZXRBdHRyLmdldFZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInN0cmVldFllcyIsICJZZXMiLCB2YWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2F0dHJlbnRpdHlyZXBsYWNlbWVudCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oYXR0cmVudGl0eXJlcGxhY2VtZW50LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRybmFtZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRybmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA2YTc4Y2MKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2F0dHJuYW1lLmphdmEKQEAgLTAsMCArMSw5NCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIGdldE5vZGVOYW1lKCkgbWV0aG9kIG9mIGFuIEF0dHJpYnV0ZSBub2RlLiAKKyAqICAgUmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBuYW1lZCBzdHJlZXQgZnJvbSB0aGUgbGFzdCAKKyAqICAgY2hpbGQgb2Ygb2YgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgZXhhbWluZSBpdHMgCisgKiAgIE5vZGVOYW1lLiAgVGhpcyB0ZXN0IHVzZXMgdGhlIGdldE5hbWVkSXRlbShuYW1lKSBtZXRob2QgZnJvbSB0aGUgTmFtZWROb2RlTWFwIAorICogICBpbnRlcmZhY2UuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIxMTk0MDMiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIxMTk0MDM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGF0dHJuYW1lIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBhdHRybmFtZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhZGRyZXNzTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgc3RyZWV0QXR0cjsKKyAgICAgIFN0cmluZyBuYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGFkZHJlc3NMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0Tm9kZSA9IGFkZHJlc3NMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgc3RyZWV0QXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgic3RyZWV0Iik7CisgICAgICBuYW1lID0gc3RyZWV0QXR0ci5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTmFtZSIsICJzdHJlZXQiLCBuYW1lKTsKKyAgICAgIG5hbWUgPSBzdHJlZXRBdHRyLmdldE5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibmFtZSIsICJzdHJlZXQiLCBuYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvYXR0cm5hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGF0dHJuYW1lLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRybmV4dHNpYmxpbmdudWxsLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2F0dHJuZXh0c2libGluZ251bGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NTNhOTEyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRybmV4dHNpYmxpbmdudWxsLmphdmEKQEAgLTAsMCArMSw5MSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBUaGUgImdldE5leHRTaWJsaW5nKCkiIG1ldGhvZCBmb3IgYW4gQXR0ciBub2RlIHNob3VsZCByZXR1cm4gbnVsbC4KKyAqIFJldHJpZXZlIHRoZSBhdHRyaWJ1dGUgbmFtZWQgImRvbWVzdGljIiBmcm9tIHRoZSBsYXN0IGNoaWxkIG9mIG9mIHRoZQorICogZmlyc3QgZW1wbG95ZWUgYW5kIGV4YW1pbmUgaXRzIE5leHRTaWJsaW5nIG5vZGUuICBUaGlzIHRlc3QgdXNlcyB0aGUKKyAqICJnZXROYW1lZEl0ZW0obmFtZSkiIG1ldGhvZCBmcm9tIHRoZSBOYW1lZE5vZGVNYXAgaW50ZXJmYWNlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNkFDNTRDMkYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTZBQzU0QzJGPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBhdHRybmV4dHNpYmxpbmdudWxsIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBhdHRybmV4dHNpYmxpbmdudWxsKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NMaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBkb21lc3RpY0F0dHI7CisgICAgICBOb2RlIHM7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgYWRkcmVzc0xpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3ROb2RlID0gYWRkcmVzc0xpc3QuaXRlbSgwKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBkb21lc3RpY0F0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oImRvbWVzdGljIik7CisgICAgICBzID0gZG9tZXN0aWNBdHRyLmdldE5leHRTaWJsaW5nKCk7CisgICAgICBhc3NlcnROdWxsKCJhdHRyTmV4dFNpYmxpbmdOdWxsQXNzZXJ0Iiwgcyk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2F0dHJuZXh0c2libGluZ251bGwiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGF0dHJuZXh0c2libGluZ251bGwuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2F0dHJub3RzcGVjaWZpZWR2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRybm90c3BlY2lmaWVkdmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YWRmZjUwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRybm90c3BlY2lmaWVkdmFsdWUuamF2YQpAQCAtMCwwICsxLDEwMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldFNwZWNpZmllZCgpIiBtZXRob2QgZm9yIGFuIEF0dHIgbm9kZSBzaG91bGQgCisgKiAgIGJlIHNldCB0byBmYWxzZSBpZiB0aGUgYXR0cmlidXRlIHdhcyBub3QgZXhwbGljaXRseSBnaXZlbgorICogICBhIHZhbHVlLgorICogICBSZXRyaWV2ZSB0aGUgYXR0cmlidXRlIG5hbWVkICJzdHJlZXQiIGZyb20gdGhlIGxhc3QgCisgKiAgIGNoaWxkIG9mIG9mIHRoZSBmaXJzdCBlbXBsb3llZSBhbmQgZXhhbWluZSB0aGUgdmFsdWUgCisgKiAgIHJldHVybmVkIGJ5IHRoZSAiZ2V0U3BlY2lmaWVkKCkiIG1ldGhvZC4gIFRoaXMgdGVzdCB1c2VzIAorICogICB0aGUgImdldE5hbWVkSXRlbShuYW1lKSIgbWV0aG9kIGZyb20gdGhlIE5hbWVkTm9kZU1hcCAKKyAqICAgaW50ZXJmYWNlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODYyNTI5MjczIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NjI1MjkyNzM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyTWFyLzAwMDIuaHRtbCI+aHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyTWFyLzAwMDIuaHRtbDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgYXR0cm5vdHNwZWNpZmllZHZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBhdHRybm90c3BlY2lmaWVkdmFsdWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcudmFsaWRhdGluZworICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhZGRyZXNzTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgc3RyZWV0QXR0cjsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgYWRkcmVzc0xpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3ROb2RlID0gYWRkcmVzc0xpc3QuaXRlbSgwKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBzdHJlZXRBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJzdHJlZXQiKTsKKyAgICAgIHN0YXRlID0gc3RyZWV0QXR0ci5nZXRTcGVjaWZpZWQoKTsKKyAgICAgIGFzc2VydEZhbHNlKCJzdHJlZXROb3RTcGVjaWZpZWQiLCBzdGF0ZSk7Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2F0dHJub3RzcGVjaWZpZWR2YWx1ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oYXR0cm5vdHNwZWNpZmllZHZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRycGFyZW50bm9kZW51bGwuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cnBhcmVudG5vZGVudWxsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODc1N2E3MgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cnBhcmVudG5vZGVudWxsLmphdmEKQEAgLTAsMCArMSw5MSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBUaGUgImdldFBhcmVudE5vZGUoKSIgbWV0aG9kIGZvciBhbiBBdHRyIG5vZGUgc2hvdWxkIHJldHVybiBudWxsLiAgUmV0cmlldmUKKyAqIHRoZSBhdHRyaWJ1dGUgbmFtZWQgImRvbWVzdGljIiBmcm9tIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSBmaXJzdCBlbXBsb3llZQorICogYW5kIGV4YW1pbmUgaXRzIHBhcmVudE5vZGUgYXR0cmlidXRlLiAgVGhpcyB0ZXN0IGFsc28gdXNlcyB0aGUgImdldE5hbWVkSXRlbShuYW1lKSIKKyAqIG1ldGhvZCBmcm9tIHRoZSBOYW1lZE5vZGVNYXAgaW50ZXJmYWNlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA2MDE4NDMxNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA2MDE4NDMxNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgYXR0cnBhcmVudG5vZGVudWxsIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBhdHRycGFyZW50bm9kZW51bGwoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWRkcmVzc0xpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIGRvbWVzdGljQXR0cjsKKyAgICAgIE5vZGUgczsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBhZGRyZXNzTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdE5vZGUgPSBhZGRyZXNzTGlzdC5pdGVtKDApOworICAgICAgYXR0cmlidXRlcyA9IHRlc3ROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGRvbWVzdGljQXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgiZG9tZXN0aWMiKTsKKyAgICAgIHMgPSBkb21lc3RpY0F0dHIuZ2V0UGFyZW50Tm9kZSgpOworICAgICAgYXNzZXJ0TnVsbCgiYXR0clBhcmVudE5vZGVOdWxsQXNzZXJ0Iiwgcyk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2F0dHJwYXJlbnRub2RlbnVsbCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oYXR0cnBhcmVudG5vZGVudWxsLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRycHJldmlvdXNzaWJsaW5nbnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRycHJldmlvdXNzaWJsaW5nbnVsbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJkY2U1NjkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2F0dHJwcmV2aW91c3NpYmxpbmdudWxsLmphdmEKQEAgLTAsMCArMSw5MSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBUaGUgImdldFByZXZpb3VzU2libGluZygpIiBtZXRob2QgZm9yIGFuIEF0dHIgbm9kZSBzaG91bGQgcmV0dXJuIG51bGwuCisgKiBSZXRyaWV2ZSB0aGUgYXR0cmlidXRlIG5hbWVkICJkb21lc3RpYyIgZnJvbSB0aGUgbGFzdCBjaGlsZCBvZiBvZiB0aGUKKyAqIGZpcnN0IGVtcGxveWVlIGFuZCBleGFtaW5lIGl0cyBQcmV2aW91c1NpYmxpbmcgbm9kZS4gIFRoaXMgdGVzdCB1c2VzIHRoZQorICogImdldE5hbWVkSXRlbShuYW1lKSIgbWV0aG9kIGZyb20gdGhlIE5hbWVkTm9kZU1hcCBpbnRlcmZhY2UuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NDBGQjNDOCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjQwRkIzQzg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGF0dHJwcmV2aW91c3NpYmxpbmdudWxsIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBhdHRycHJldmlvdXNzaWJsaW5nbnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhZGRyZXNzTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgZG9tZXN0aWNBdHRyOworICAgICAgTm9kZSBzOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGFkZHJlc3NMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0Tm9kZSA9IGFkZHJlc3NMaXN0Lml0ZW0oMCk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgZG9tZXN0aWNBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJkb21lc3RpYyIpOworICAgICAgcyA9IGRvbWVzdGljQXR0ci5nZXRQcmV2aW91c1NpYmxpbmcoKTsKKyAgICAgIGFzc2VydE51bGwoImF0dHJQcmV2aW91c1NpYmxpbmdOdWxsQXNzZXJ0Iiwgcyk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2F0dHJwcmV2aW91c3NpYmxpbmdudWxsIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihhdHRycHJldmlvdXNzaWJsaW5nbnVsbC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cnJlbW92ZWNoaWxkMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRycmVtb3ZlY2hpbGQxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGRlMTVjYgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cnJlbW92ZWNoaWxkMS5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBSZW1vdmluZyBhIGNoaWxkIG5vZGUgZnJvbSBhbiBhdHRyaWJ1dGUgaW4gYW4gZW50aXR5IHJlZmVyZW5jZQorICogc2hvdWxkIHJlc3VsdCBpbiBhbiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgRE9NRXhjZXB0aW9uLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTczNDgzNDA2NiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTczNDgzNDA2NjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMTczNDgzNDA2NicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTE3MzQ4MzQwNjYnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGF0dHJyZW1vdmVjaGlsZDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGF0dHJyZW1vdmVjaGlsZDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbnRpdHlSZWZlcmVuY2UgZW50UmVmOworICAgICAgRWxlbWVudCBlbnRFbGVtZW50OworICAgICAgTm9kZSBhdHRyTm9kZTsKKyAgICAgIFRleHQgdGV4dE5vZGU7CisgICAgICBOb2RlIHJlbW92ZWROb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZW50UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworICAgICAgZW50RWxlbWVudCA9IChFbGVtZW50KSBlbnRSZWYuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50RWxlbWVudE5vdE51bGwiLCBlbnRFbGVtZW50KTsKKyAgICAgIGF0dHJOb2RlID0gZW50RWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlKCJkb21lc3RpYyIpOworICAgICAgdGV4dE5vZGUgPSAoVGV4dCkgYXR0ck5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiYXR0ckNoaWxkTm90TnVsbCIsIHRleHROb2RlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVtb3ZlZE5vZGUgPSBhdHRyTm9kZS5yZW1vdmVDaGlsZCh0ZXh0Tm9kZSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJzZXRWYWx1ZV90aHJvd3NfTk9fTU9ESUZJQ0FUSU9OX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9hdHRycmVtb3ZlY2hpbGQxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihhdHRycmVtb3ZlY2hpbGQxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRycmVwbGFjZWNoaWxkMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRycmVwbGFjZWNoaWxkMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4NDU4NmMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2F0dHJyZXBsYWNlY2hpbGQxLmphdmEKQEAgLTAsMCArMSwxMDEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBSZXBsYWNpbmcgYSBjaGlsZCBub2RlIGZyb20gYW4gYXR0cmlidXRlIGluIGFuIGVudGl0eSByZWZlcmVuY2UKKyAqIHNob3VsZCByZXN1bHQgaW4gYW4gTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIERPTUV4Y2VwdGlvbi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC03ODU4ODczMDcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC03ODU4ODczMDcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGF0dHJyZXBsYWNlY2hpbGQxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBhdHRycmVwbGFjZWNoaWxkMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWY7CisgICAgICBFbGVtZW50IGVudEVsZW1lbnQ7CisgICAgICBOb2RlIGF0dHJOb2RlOworICAgICAgVGV4dCB0ZXh0Tm9kZTsKKyAgICAgIE5vZGUgcmVtb3ZlZE5vZGU7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZW50UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworICAgICAgZW50RWxlbWVudCA9IChFbGVtZW50KSBlbnRSZWYuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50RWxlbWVudE5vdE51bGwiLCBlbnRFbGVtZW50KTsKKyAgICAgIGF0dHJOb2RlID0gZW50RWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlKCJkb21lc3RpYyIpOworICAgICAgdGV4dE5vZGUgPSAoVGV4dCkgYXR0ck5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiYXR0ckNoaWxkTm90TnVsbCIsIHRleHROb2RlKTsKKyAgICAgIG5ld0NoaWxkID0gZG9jLmNyZWF0ZVRleHROb2RlKCJZZXN0ZXJkYXkiKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVtb3ZlZE5vZGUgPSBhdHRyTm9kZS5yZXBsYWNlQ2hpbGQobmV3Q2hpbGQsIHRleHROb2RlKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInNldFZhbHVlX3Rocm93c19OT19NT0RJRklDQVRJT05fRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2F0dHJyZXBsYWNlY2hpbGQxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihhdHRycmVwbGFjZWNoaWxkMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cnNldHZhbHVlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2F0dHJzZXR2YWx1ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk4YzVlMjgKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2F0dHJzZXR2YWx1ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCkBAIC0wLDAgKzEsMTMzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0VmFsdWUoKSIgbWV0aG9kIGZvciBhbiBhdHRyaWJ1dGUgY2F1c2VzIHRoZSAKKyAqICAgRE9NRXhjZXB0aW9uIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiB0byBiZSByYWlzZWQKKyAqICAgaWYgdGhlIG5vZGUgaXMgcmVhZG9ubHkuCisgKiAgIE9idGFpbiB0aGUgY2hpbGRyZW4gb2YgdGhlIFRISVJEICJnZW5kZXIiIGVsZW1lbnQuICBUaGUgZWxlbWVudHMKKyAqICAgY29udGVudCBpcyBhbiBlbnRpdHkgcmVmZXJlbmNlLiAgR2V0IHRoZSAiZG9tZXN0aWMiIGF0dHJpYnV0ZQorICogICBmcm9tIHRoZSBlbnRpdHkgcmVmZXJlbmNlIGFuZCBleGVjdXRlIHRoZSAic2V0VmFsdWUoKSIgbWV0aG9kLgorICogICBUaGlzIGNhdXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gdG8gYmUgdGhyb3duLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9XRC1ET00tTGV2ZWwtMS0yMDAwMDkyOS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1dELURPTS1MZXZlbC0xLTIwMDAwOTI5L2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9XRC1ET00tTGV2ZWwtMS0yMDAwMDkyOS9sZXZlbC1vbmUtY29yZSNJRC0yMjE2NjI0NzQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvV0QtRE9NLUxldmVsLTEtMjAwMDA5MjkvbGV2ZWwtb25lLWNvcmUjSUQtMjIxNjYyNDc0PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvV0QtRE9NLUxldmVsLTEtMjAwMDA5MjkvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTIyMTY2MjQ3NCcpL3NldHJhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9XRC1ET00tTGV2ZWwtMS0yMDAwMDkyOS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjIxNjYyNDc0Jykvc2V0cmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0RPTS91cGRhdGVzL1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS1lcnJhdGEuaHRtbCI+aHR0cDovL3d3dy53My5vcmcvRE9NL3VwZGF0ZXMvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxLWVycmF0YS5odG1sPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIyMTY2MjQ3NCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjIxNjYyNDc0PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBhdHRyc2V0dmFsdWVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGF0dHJzZXR2YWx1ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVycihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RFeHBhbmRFbnRpdHlSZWZlcmVuY2VzCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyOworICAgICAgTm9kZUxpc3QgZ2VuTGlzdDsKKyAgICAgIE5vZGUgZ2VuOworICAgICAgTm9kZUxpc3QgZ0xpc3Q7CisgICAgICBOb2RlIGc7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0ckxpc3Q7CisgICAgICBBdHRyIGF0dHJOb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZ2VuZGVyTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZ2VuZGVyIik7CisgICAgICBnZW5kZXIgPSBnZW5kZXJMaXN0Lml0ZW0oMik7CisgICAgICBhc3NlcnROb3ROdWxsKCJnZW5kZXJOb3ROdWxsIiwgZ2VuZGVyKTsKKyAgICAgIGdlbkxpc3QgPSBnZW5kZXIuZ2V0Q2hpbGROb2RlcygpOworICAgICAgZ2VuID0gZ2VuTGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2VuZGVyRmlyc3RDaGlsZE5vdE51bGwiLCBnZW4pOworICAgICAgZ0xpc3QgPSBnZW4uZ2V0Q2hpbGROb2RlcygpOworICAgICAgZyA9IGdMaXN0Lml0ZW0oMCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJnZW5kZXJGaXJzdEdyYW5kY2hpbGROb3ROdWxsIiwgZyk7CisgICAgICBhdHRyTGlzdCA9IGcuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiYXR0cmlidXRlc05vdE51bGwiLCBhdHRyTGlzdCk7CisgICAgICBhdHRyTm9kZSA9IChBdHRyKSBhdHRyTGlzdC5nZXROYW1lZEl0ZW0oImRvbWVzdGljIik7CisgICAgICBhc3NlcnROb3ROdWxsKCJhdHRyTm90TnVsbCIsIGF0dHJOb2RlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgYXR0ck5vZGUuc2V0VmFsdWUoIm5ld3ZhbHVlIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJzZXRWYWx1ZV90aHJvd3NfTk9fTU9ESUZJQ0FUSU9OIiwgc3VjY2Vzcyk7CisgICAgICB9CisKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGF0dHJOb2RlLnNldE5vZGVWYWx1ZSgibmV3dmFsdWUyIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJzZXROb2RlVmFsdWVfdGhyb3dzX05PX01PRElGSUNBVElPTiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9hdHRyc2V0dmFsdWVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGF0dHJzZXR2YWx1ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cnNldHZhbHVlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cnNldHZhbHVlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NDU1ZmVlCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRyc2V0dmFsdWVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhCkBAIC0wLDAgKzEsMTIzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldFZhbHVlKCkiIG1ldGhvZCBmb3IgYW4gYXR0cmlidXRlIGNhdXNlcyB0aGUgCisgKiAgIERPTUV4Y2VwdGlvbiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgdG8gYmUgcmFpc2VkCisgKiAgIGlmIHRoZSBub2RlIGlzIHJlYWRvbmx5LgorICogICBDcmVhdGUgYW4gZW50aXR5IHJlZmVyZW5jZSB1c2luZyBkb2N1bWVudC5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoKQorICogICBHZXQgdGhlICJkb21lc3RpYyIgYXR0cmlidXRlIGZyb20gdGhlIGVudGl0eSAKKyAqICAgcmVmZXJlbmNlIGFuZCBleGVjdXRlIHRoZSAic2V0VmFsdWUoKSIgbWV0aG9kLgorICogICBUaGlzIGNhdXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gdG8gYmUgdGhyb3duLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9XRC1ET00tTGV2ZWwtMS0yMDAwMDkyOS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1dELURPTS1MZXZlbC0xLTIwMDAwOTI5L2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9XRC1ET00tTGV2ZWwtMS0yMDAwMDkyOS9sZXZlbC1vbmUtY29yZSNJRC0yMjE2NjI0NzQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvV0QtRE9NLUxldmVsLTEtMjAwMDA5MjkvbGV2ZWwtb25lLWNvcmUjSUQtMjIxNjYyNDc0PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvV0QtRE9NLUxldmVsLTEtMjAwMDA5MjkvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTIyMTY2MjQ3NCcpL3NldHJhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9XRC1ET00tTGV2ZWwtMS0yMDAwMDkyOS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjIxNjYyNDc0Jykvc2V0cmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0RPTS91cGRhdGVzL1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS1lcnJhdGEuaHRtbCI+aHR0cDovL3d3dy53My5vcmcvRE9NL3VwZGF0ZXMvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxLWVycmF0YS5odG1sPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIyMTY2MjQ3NCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjIxNjYyNDc0PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvYXR0cnNldHZhbHVlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLnhtbCI+aHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9hdHRyc2V0dmFsdWVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIueG1sPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBhdHRyc2V0dmFsdWVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgYXR0cnNldHZhbHVlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbnRpdHlSZWZlcmVuY2UgZW50UmVmOworICAgICAgRWxlbWVudCBlbnRFbGVtZW50OworICAgICAgTmFtZWROb2RlTWFwIGF0dHJMaXN0OworICAgICAgTm9kZSBhdHRyTm9kZTsKKyAgICAgIE5vZGUgZ2VuZGVyOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgYXBwZW5kZWRDaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGdlbmRlckxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImdlbmRlciIpOworICAgICAgZ2VuZGVyID0gZ2VuZGVyTGlzdC5pdGVtKDIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2VuZGVyTm90TnVsbCIsIGdlbmRlcik7CisgICAgICBlbnRSZWYgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQ0Iik7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRSZWZOb3ROdWxsIiwgZW50UmVmKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBnZW5kZXIuYXBwZW5kQ2hpbGQoZW50UmVmKTsKKyAgICAgIGVudEVsZW1lbnQgPSAoRWxlbWVudCkgZW50UmVmLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudEVsZW1lbnROb3ROdWxsIiwgZW50RWxlbWVudCk7CisgICAgICBhdHRyTGlzdCA9IGVudEVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXR0ck5vZGUgPSBhdHRyTGlzdC5nZXROYW1lZEl0ZW0oImRvbWVzdGljIik7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICgoQXR0cikgLypOb2RlICovYXR0ck5vZGUpLnNldFZhbHVlKCJuZXd2YWx1ZSIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgic2V0VmFsdWVfdGhyb3dzX05PX01PRElGSUNBVElPTiIsIHN1Y2Nlc3MpOworICAgICAgfQorCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhdHRyTm9kZS5zZXROb2RlVmFsdWUoIm5ld3ZhbHVlMiIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgic2V0Tm9kZVZhbHVlX3Rocm93c19OT19NT0RJRklDQVRJT04iLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvYXR0cnNldHZhbHVlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGF0dHJzZXR2YWx1ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRyc3BlY2lmaWVkdmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cnNwZWNpZmllZHZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTAwODdmZgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cnNwZWNpZmllZHZhbHVlLmphdmEKQEAgLTAsMCArMSw5NCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldFNwZWNpZmllZCgpIiBtZXRob2QgZm9yIGFuIEF0dHIgbm9kZSBzaG91bGQgCisgKiAgIGJlIHNldCB0byB0cnVlIGlmIHRoZSBhdHRyaWJ1dGUgd2FzIGV4cGxpY2l0bHkgZ2l2ZW4KKyAqICAgYSB2YWx1ZS4KKyAqICAgUmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBuYW1lZCAiZG9tZXN0aWMiIGZyb20gdGhlIGxhc3QgCisgKiAgIGNoaWxkIG9mIG9mIHRoZSBmaXJzdCBlbXBsb3llZSBhbmQgZXhhbWluZSB0aGUgdmFsdWUgCisgKiAgIHJldHVybmVkIGJ5IHRoZSAiZ2V0U3BlY2lmaWVkKCkiIG1ldGhvZC4gIFRoaXMgdGVzdCB1c2VzIAorICogICB0aGUgImdldE5hbWVkSXRlbShuYW1lKSIgbWV0aG9kIGZyb20gdGhlIE5hbWVkTm9kZU1hcCAKKyAqICAgaW50ZXJmYWNlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODYyNTI5MjczIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NjI1MjkyNzM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGF0dHJzcGVjaWZpZWR2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgYXR0cnNwZWNpZmllZHZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NMaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBkb21lc3RpY0F0dHI7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGFkZHJlc3NMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0Tm9kZSA9IGFkZHJlc3NMaXN0Lml0ZW0oMCk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgZG9tZXN0aWNBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJkb21lc3RpYyIpOworICAgICAgc3RhdGUgPSBkb21lc3RpY0F0dHIuZ2V0U3BlY2lmaWVkKCk7CisgICAgICBhc3NlcnRUcnVlKCJkb21lc3RpY1NwZWNpZmllZCIsIHN0YXRlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvYXR0cnNwZWNpZmllZHZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihhdHRyc3BlY2lmaWVkdmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2F0dHJzcGVjaWZpZWR2YWx1ZWNoYW5nZWQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cnNwZWNpZmllZHZhbHVlY2hhbmdlZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhY2M4YWUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2F0dHJzcGVjaWZpZWR2YWx1ZWNoYW5nZWQuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0U3BlY2lmaWVkKCkiIG1ldGhvZCBmb3IgYW4gQXR0ciBub2RlIHNob3VsZCByZXR1cm4gdHJ1ZSBpZiB0aGUgCisgKiAgIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgaXMgY2hhbmdlZC4gCisgKiAgIFJldHJpZXZlIHRoZSBhdHRyaWJ1dGUgbmFtZWQgInN0cmVldCIgZnJvbSB0aGUgbGFzdCAKKyAqICAgY2hpbGQgb2Ygb2YgdGhlIFRISVJEIGVtcGxveWVlIGFuZCBjaGFuZ2UgaXRzIAorICogICB2YWx1ZSB0byAiWWVzIih3aGljaCBpcyB0aGUgZGVmYXVsdCBEVEQgdmFsdWUpLiAgVGhpcworICogICBzaG91bGQgY2F1c2UgdGhlICJnZXRTcGVjaWZpZWQoKSIgbWV0aG9kIHRvIGJlIHRydWUuCisgKiAgIFRoaXMgdGVzdCB1c2VzIHRoZSAic2V0QXR0cmlidXRlKG5hbWUsdmFsdWUpIiBtZXRob2QKKyAqICAgZnJvbSB0aGUgRWxlbWVudCBpbnRlcmZhY2UgYW5kIHRoZSAiZ2V0TmFtZWRJdGVtKG5hbWUpIgorICogICBtZXRob2QgZnJvbSB0aGUgTmFtZWROb2RlTWFwIGludGVyZmFjZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg2MjUyOTI3MyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODYyNTI5MjczPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBhdHRyc3BlY2lmaWVkdmFsdWVjaGFuZ2VkIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBhdHRyc3BlY2lmaWVkdmFsdWVjaGFuZ2VkKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWRkcmVzc0xpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIHN0cmVldEF0dHI7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgYWRkcmVzc0xpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3ROb2RlID0gYWRkcmVzc0xpc3QuaXRlbSgyKTsKKyAgICAgICgoRWxlbWVudCkgLypOb2RlICovdGVzdE5vZGUpLnNldEF0dHJpYnV0ZSgic3RyZWV0IiwgIlllcyIpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3ROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHN0cmVldEF0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oInN0cmVldCIpOworICAgICAgc3RhdGUgPSBzdHJlZXRBdHRyLmdldFNwZWNpZmllZCgpOworICAgICAgYXNzZXJ0VHJ1ZSgic3RyZWV0U3BlY2lmaWVkIiwgc3RhdGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9hdHRyc3BlY2lmaWVkdmFsdWVjaGFuZ2VkIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihhdHRyc3BlY2lmaWVkdmFsdWVjaGFuZ2VkLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9hdHRyc3BlY2lmaWVkdmFsdWVyZW1vdmUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cnNwZWNpZmllZHZhbHVlcmVtb3ZlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmQ3MjgyNwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvYXR0cnNwZWNpZmllZHZhbHVlcmVtb3ZlLmphdmEKQEAgLTAsMCArMSwxMDcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBUbyByZXNwZWNpZnkgdGhlIGF0dHJpYnV0ZSB0byBpdHMgZGVmYXVsdCB2YWx1ZSBmcm9tCisgKiB0aGUgRFRELCB0aGUgYXR0cmlidXRlIG11c3QgYmUgZGVsZXRlZC4gIFRoaXMgd2lsbCB0aGVuCisgKiBtYWtlIGEgbmV3IGF0dHJpYnV0ZSBhdmFpbGFibGUgd2l0aCB0aGUgImdldFNwZWNpZmllZCgpIgorICogbWV0aG9kIHZhbHVlIHNldCB0byBmYWxzZS4KKyAqIFJldHJpZXZlIHRoZSBhdHRyaWJ1dGUgbmFtZWQgInN0cmVldCIgZnJvbSB0aGUgbGFzdAorICogY2hpbGQgb2Ygb2YgdGhlIFRISVJEIGVtcGxveWVlIGFuZCBkZWxldGUgaXQuICBUaGlzCisgKiBzaG91bGQgdGhlbiBjcmVhdGUgYSBuZXcgYXR0cmlidXRlIHdpdGggaXRzIGRlZmF1bHQKKyAqIHZhbHVlIGFuZCBhbHNvIGNhdXNlIHRoZSAiZ2V0U3BlY2lmaWVkKCkiIG1ldGhvZCB0bworICogcmV0dXJuIGZhbHNlLgorICogVGhpcyB0ZXN0IHVzZXMgdGhlICJyZW1vdmVBdHRyaWJ1dGUobmFtZSkiIG1ldGhvZAorICogZnJvbSB0aGUgRWxlbWVudCBpbnRlcmZhY2UgYW5kIHRoZSAiZ2V0TmFtZWRJdGVtKG5hbWUpIgorICogbWV0aG9kIGZyb20gdGhlIE5hbWVkTm9kZU1hcCBpbnRlcmZhY2UuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02RDZBQzBGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNkQ2QUMwRjk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyTWFyLzAwMDIuaHRtbCI+aHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyTWFyLzAwMDIuaHRtbDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgYXR0cnNwZWNpZmllZHZhbHVlcmVtb3ZlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBhdHRyc3BlY2lmaWVkdmFsdWVyZW1vdmUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcudmFsaWRhdGluZworICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NMaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBzdHJlZXRBdHRyOworICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGFkZHJlc3NMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0Tm9kZSA9IGFkZHJlc3NMaXN0Lml0ZW0oMik7CisgICAgICAoKEVsZW1lbnQpIC8qTm9kZSAqL3Rlc3ROb2RlKS5yZW1vdmVBdHRyaWJ1dGUoInN0cmVldCIpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3ROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHN0cmVldEF0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oInN0cmVldCIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgic3RyZWV0QXR0ck5vdE51bGwiLCBzdHJlZXRBdHRyKTsKKyAgICAgIHN0YXRlID0gc3RyZWV0QXR0ci5nZXRTcGVjaWZpZWQoKTsKKyAgICAgIGFzc2VydEZhbHNlKCJhdHRyU3BlY2lmaWVkVmFsdWVSZW1vdmVBc3NlcnQiLCBzdGF0ZSk7Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2F0dHJzcGVjaWZpZWR2YWx1ZXJlbW92ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oYXR0cnNwZWNpZmllZHZhbHVlcmVtb3ZlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jZGF0YXNlY3Rpb25nZXRkYXRhLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NkYXRhc2VjdGlvbmdldGRhdGEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mM2VmN2E4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jZGF0YXNlY3Rpb25nZXRkYXRhLmphdmEKQEAgLTAsMCArMSw5OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIFJldHJpZXZlIHRoZSBsYXN0IENEQVRBU2VjdGlvbiBub2RlIGxvY2F0ZWQgaW5zaWRlIHRoZQorICogc2Vjb25kIGNoaWxkIG9mIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGV4YW1pbmUgaXRzCisgKiBjb250ZW50LiAgU2luY2UgdGhlIENEQVRBU2VjdGlvbiBpbnRlcmZhY2UgaW5oZXJpdHMKKyAqIGZyb20gdGhlIENoYXJhY3RlckRhdGEgaW50ZXJmYWNlKHZpYSB0aGUgVGV4dCBub2RlKSwKKyAqIHRoZSAiZ2V0RGF0YSgpIiBtZXRob2QgY2FuIGJlIHVzZWQgdG8gYWNjZXNzIHRoZQorICogQ0RBVEEgY29udGVudC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY2RhdGFzZWN0aW9uZ2V0ZGF0YSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY2RhdGFzZWN0aW9uZ2V0ZGF0YShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RDb2FsZXNjaW5nCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IG5hbWVMaXN0OworICAgICAgTm9kZSBjaGlsZDsKKyAgICAgIE5vZGUgbGFzdENoaWxkOworICAgICAgU3RyaW5nIGRhdGE7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgbmFtZUxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIm5hbWUiKTsKKyAgICAgIGNoaWxkID0gbmFtZUxpc3QuaXRlbSgxKTsKKyAgICAgIGxhc3RDaGlsZCA9IGNoaWxkLmdldExhc3RDaGlsZCgpOworICAgICAgbm9kZVR5cGUgPSAoaW50KSBsYXN0Q2hpbGQuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiaXNDREFUQSIsIDQsIG5vZGVUeXBlKTsKKyAgICAgIGRhdGEgPSAoKENoYXJhY3RlckRhdGEpIC8qTm9kZSAqL2xhc3RDaGlsZCkuZ2V0RGF0YSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkYXRhIiwgIlRoaXMgaXMgYW4gYWRqYWNlbnQgQ0RBVEFTZWN0aW9uIHdpdGggYSByZWZlcmVuY2UgdG8gYSB0YWIgJnRhYjsiLCBkYXRhKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2RhdGFzZWN0aW9uZ2V0ZGF0YSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2RhdGFzZWN0aW9uZ2V0ZGF0YS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2RhdGFzZWN0aW9ubm9ybWFsaXplLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NkYXRhc2VjdGlvbm5vcm1hbGl6ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcyMzViMzEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NkYXRhc2VjdGlvbm5vcm1hbGl6ZS5qYXZhCkBAIC0wLDAgKzEsOTggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQWRqYWNlbnQgQ0RBVEFTZWN0aW9uIG5vZGVzIGNhbm5vdCBiZSBtZXJnZWQgdG9nZXRoZXIgYnkKKyAqIHVzZSBvZiB0aGUgIm5vcm1hbGl6ZSgpIiBtZXRob2QgZnJvbSB0aGUgRWxlbWVudCBpbnRlcmZhY2UuCisgKiBSZXRyaWV2ZSBzZWNvbmQgY2hpbGQgb2YgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgaW52b2tlCisgKiB0aGUgIm5vcm1hbGl6ZSgpIiBtZXRob2QuICBUaGUgRWxlbWVudCB1bmRlciBjb250YWlucworICogdHdvIENEQVRBU2VjdGlvbiBub2RlcyB0aGF0IHNob3VsZCBub3QgYmUgbWVyZ2VkIHRvZ2V0aGVyCisgKiBieSB0aGUgIm5vcm1hbGl6ZSgpIiBtZXRob2QuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNjJDRjA4MyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTYyQ0YwODM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNkYXRhc2VjdGlvbm5vcm1hbGl6ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY2RhdGFzZWN0aW9ubm9ybWFsaXplKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgbmFtZUxpc3Q7CisgICAgICBFbGVtZW50IGxDaGlsZDsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTm9kZXM7CisgICAgICBDREFUQVNlY3Rpb24gY2RhdGFOOworICAgICAgU3RyaW5nIGRhdGE7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBuYW1lTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgibmFtZSIpOworICAgICAgbENoaWxkID0gKEVsZW1lbnQpIG5hbWVMaXN0Lml0ZW0oMSk7CisgICAgICBsQ2hpbGQubm9ybWFsaXplKCk7CisgICAgICBjaGlsZE5vZGVzID0gbENoaWxkLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGNkYXRhTiA9IChDREFUQVNlY3Rpb24pIGNoaWxkTm9kZXMuaXRlbSgxKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImZpcnN0Q0RBVEFTZWN0aW9uIiwgY2RhdGFOKTsKKyAgICAgIGRhdGEgPSBjZGF0YU4uZ2V0RGF0YSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkYXRhMSIsICJUaGlzIGlzIGEgQ0RBVEFTZWN0aW9uIHdpdGggRW50aXR5UmVmZXJlbmNlIG51bWJlciAyICZlbnQyOyIsIGRhdGEpOworICAgICAgY2RhdGFOID0gKENEQVRBU2VjdGlvbikgY2hpbGROb2Rlcy5pdGVtKDMpOworICAgICAgYXNzZXJ0Tm90TnVsbCgic2Vjb25kQ0RBVEFTZWN0aW9uIiwgY2RhdGFOKTsKKyAgICAgIGRhdGEgPSBjZGF0YU4uZ2V0RGF0YSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkYXRhMyIsICJUaGlzIGlzIGFuIGFkamFjZW50IENEQVRBU2VjdGlvbiB3aXRoIGEgcmVmZXJlbmNlIHRvIGEgdGFiICZ0YWI7IiwgZGF0YSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NkYXRhc2VjdGlvbm5vcm1hbGl6ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2RhdGFzZWN0aW9ubm9ybWFsaXplLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjYTdiMGMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhLmphdmEKQEAgLTAsMCArMSw5NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJhcHBlbmREYXRhKGFyZykiIG1ldGhvZCBhcHBlbmRzIGEgc3RyaW5nIHRvIHRoZSBlbmQgCisgKiAgICBvZiB0aGUgY2hhcmFjdGVyIGRhdGEgb2YgdGhlIG5vZGUuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBmcm9tIHRoZSBzZWNvbmQgY2hpbGQgCisgKiAgICBvZiB0aGUgZmlyc3QgZW1wbG95ZWUuICBUaGUgYXBwZW5kRGF0YShhcmcpIG1ldGhvZCBpcworICogICAgY2FsbGVkIHdpdGggYXJnPSIsIEVzcXVpcmUiLiAgVGhlIG1ldGhvZCBzaG91bGQgYXBwZW5kIAorICogICAgdGhlIHNwZWNpZmllZCBkYXRhIHRvIHRoZSBhbHJlYWR5IGV4aXN0aW5nIGNoYXJhY3RlciAgCisgKiAgICBkYXRhLiAgVGhlIG5ldyB2YWx1ZSByZXR1cm4gYnkgdGhlICJnZXRMZW5ndGgoKSIgbWV0aG9kCisgKiAgICBzaG91bGQgYmUgMjQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzI3OTFBMkYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTMyNzkxQTJGPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkVmFsdWU7CisgICAgICBpbnQgY2hpbGRMZW5ndGg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgibmFtZSIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgY2hpbGQuYXBwZW5kRGF0YSgiLCBFc3F1aXJlIik7CisgICAgICBjaGlsZFZhbHVlID0gY2hpbGQuZ2V0RGF0YSgpOworICAgICAgY2hpbGRMZW5ndGggPSBjaGlsZFZhbHVlLmxlbmd0aCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyYWN0ZXJkYXRhQXBwZW5kRGF0YUFzc2VydCIsIDI0LCBjaGlsZExlbmd0aCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGFnZXRkYXRhLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhZ2V0ZGF0YS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUzYzM1MmUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhZ2V0ZGF0YS5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIE9uIHN1Y2Nlc3NmdWwgaW52b2NhdGlvbiBvZiB0aGUgImFwcGVuZERhdGEoYXJnKSIgCisgKiAgICBtZXRob2QgdGhlICJnZXREYXRhKCkiIG1ldGhvZCBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlCisgKiAgICBjb25jYXRlbnRhdGlvbiBvZiBkYXRhIGFuZCB0aGUgc3BlY2lmaWVkIHN0cmluZy4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIHNlY29uZCBjaGlsZCAKKyAqICAgIG9mIHRoZSBmaXJzdCBlbXBsb3llZS4gIFRoZSBhcHBlbmREYXRhKGFyZykgbWV0aG9kIGlzCisgKiAgICBjYWxsZWQgd2l0aCBhcmc9IiwgRXNxdWlyZSIuICBUaGUgbWV0aG9kIHNob3VsZCBhcHBlbmQgCisgKiAgICB0aGUgc3BlY2lmaWVkIGRhdGEgdG8gdGhlIGFscmVhZHkgZXhpc3RpbmcgY2hhcmFjdGVyICAKKyAqICAgIGRhdGEuICBUaGUgbmV3IHZhbHVlIHJldHVybiBieSB0aGUgImdldERhdGEoKSIgbWV0aG9kCisgKiAgICBzaG91bGQgYmUgIk1hcmdhcmV0IE1hcnRpbiwgRXNxdWlyZSIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzI3OTFBMkYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTMyNzkxQTJGPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YWdldGRhdGEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFhcHBlbmRkYXRhZ2V0ZGF0YShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGREYXRhOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIm5hbWUiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkLmFwcGVuZERhdGEoIiwgRXNxdWlyZSIpOworICAgICAgY2hpbGREYXRhID0gY2hpbGQuZ2V0RGF0YSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyYWN0ZXJkYXRhQXBwZW5kRGF0YUdldERhdGFBc3NlcnQiLCAiTWFyZ2FyZXQgTWFydGluLCBFc3F1aXJlIiwgY2hpbGREYXRhKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGFnZXRkYXRhIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YWdldGRhdGEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWMxZmQ5YQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuamF2YQpAQCAtMCwwICsxLDExNCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImFwcGVuZERhdGEoYXJnKSIgbWV0aG9kIHJhaXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiAKKyAqICAgIERPTUV4Y2VwdGlvbiBpZiB0aGUgbm9kZSBpcyByZWFkb25seS4gIAorICogICAgT2J0YWluIHRoZSBjaGlsZHJlbiBvZiB0aGUgVEhJUkQgImdlbmRlciIgZWxlbWVudC4gIFRoZSBlbGVtZW50cworICogICAgY29udGVudCBpcyBhbiBlbnRpdHkgcmVmZXJlbmNlLiAgR2V0IHRoZSBGSVJTVCBpdGVtIAorICogICAgZnJvbSB0aGUgZW50aXR5IHJlZmVyZW5jZSBhbmQgZXhlY3V0ZSB0aGUgImFwcGVuZERhdGEoYXJnKSIgbWV0aG9kLgorICogICAgVGhpcyBjYXVzZXMgYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgRE9NRXhjZXB0aW9uIHRvIGJlIHRocm93bi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzI3OTFBMkYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTMyNzkxQTJGPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0zMjc5MUEyRicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTMyNzkxQTJGJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTMyNzkxQTJGIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zMjc5MUEyRjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFhcHBlbmRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyTm9kZTsKKyAgICAgIE5vZGUgZW50RWxlbWVudDsKKyAgICAgIE5vZGUgZW50RWxlbWVudENvbnRlbnQ7CisgICAgICBOb2RlIGVudFJlZmVyZW5jZTsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGdlbmRlckxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImdlbmRlciIpOworICAgICAgZ2VuZGVyTm9kZSA9IGdlbmRlckxpc3QuaXRlbSgyKTsKKyAgICAgIGVudFJlZmVyZW5jZSA9IGdlbmRlck5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50UmVmZXJlbmNlTm90TnVsbCIsIGVudFJlZmVyZW5jZSk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGVudFJlZmVyZW5jZS5nZXROb2RlVHlwZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDEsIG5vZGVUeXBlKSkgeworICAgICAgICAgIGVudFJlZmVyZW5jZSA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDQiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZW50UmVmZXJlbmNlKTsKKyAgICAgIH0KKyAgICBlbnRFbGVtZW50ID0gZW50UmVmZXJlbmNlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudEVsZW1lbnROb3ROdWxsIiwgZW50RWxlbWVudCk7CisgICAgICBlbnRFbGVtZW50Q29udGVudCA9IGVudEVsZW1lbnQuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50RWxlbWVudENvbnRlbnROb3ROdWxsIiwgZW50RWxlbWVudENvbnRlbnQpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAoKENoYXJhY3RlckRhdGEpIC8qTm9kZSAqL2VudEVsZW1lbnRDb250ZW50KS5hcHBlbmREYXRhKCJuZXdTdHJpbmciKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcyNWEzNWYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YQpAQCAtMCwwICsxLDEwMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIENyZWF0ZSBhbiBlbnQzIGVudGl0eSByZWZlcmVuY2UgYW5kIGNhbGwgYXBwZW5kRGF0YSBvbiBhIHRleHQgY2hpbGQsIHNob3VsZCB0aHJvd24gYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIuIAorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zMjc5MUEyRiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzI3OTFBMkY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTMyNzkxQTJGJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMzI3OTFBMkYnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzI3OTFBMkYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTMyNzkxQTJGPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIueG1sIj5odHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLnhtbDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGdlbmRlckxpc3Q7CisgICAgICBOb2RlIGdlbmRlck5vZGU7CisgICAgICBOb2RlIGVudFRleHQ7CisgICAgICBFbnRpdHlSZWZlcmVuY2UgZW50UmVmZXJlbmNlOworICAgICAgTm9kZSBhcHBlbmRlZENoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZ2VuZGVyTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZ2VuZGVyIik7CisgICAgICBnZW5kZXJOb2RlID0gZ2VuZGVyTGlzdC5pdGVtKDIpOworICAgICAgZW50UmVmZXJlbmNlID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50MyIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWZlcmVuY2UpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGdlbmRlck5vZGUuYXBwZW5kQ2hpbGQoZW50UmVmZXJlbmNlKTsKKyAgICAgIGVudFRleHQgPSBlbnRSZWZlcmVuY2UuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50VGV4dE5vdE51bGwiLCBlbnRUZXh0KTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgKChDaGFyYWN0ZXJEYXRhKSAvKk5vZGUgKi9lbnRUZXh0KS5hcHBlbmREYXRhKCJuZXdTdHJpbmciKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWJlZ2luaW5nLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhYmVnaW5pbmcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYTBhNGJjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWJlZ2luaW5nLmphdmEKQEAgLTAsMCArMSw5NCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBUaGUgImRlbGV0ZURhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kIHJlbW92ZXMgYSByYW5nZSBvZgorICogY2hhcmFjdGVycyBmcm9tIHRoZSBub2RlLiAgRGVsZXRlIGRhdGEgYXQgdGhlIGJlZ2lubmluZworICogb2YgdGhlIGNoYXJhY3RlciBkYXRhLgorICogUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiBmaXJzdCBlbXBsb3llZS4gIFRoZSAiZGVsZXRlRGF0YShvZmZzZXQsY291bnQpIgorICogbWV0aG9kIGlzIHRoZW4gY2FsbGVkIHdpdGggb2Zmc2V0PTAgYW5kIGNvdW50PTE2LgorICogVGhlIG1ldGhvZCBzaG91bGQgZGVsZXRlIHRoZSBjaGFyYWN0ZXJzIGZyb20gcG9zaXRpb24KKyAqIDAgdGhydSBwb3NpdGlvbiAxNi4gIFRoZSBuZXcgdmFsdWUgb2YgdGhlIGNoYXJhY3RlciBkYXRhCisgKiBzaG91bGQgYmUgIkRhbGxhcywgVGV4YXMgOTg1NTEiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0M2MDM3ODEiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWJlZ2luaW5nIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWJlZ2luaW5nKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZERhdGE7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgY2hpbGQuZGVsZXRlRGF0YSgwLCAxNik7CisgICAgICBjaGlsZERhdGEgPSBjaGlsZC5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlcmRhdGFEZWxldGVEYXRhQmVnaW5pbmdBc3NlcnQiLCAiRGFsbGFzLCBUZXhhcyA5ODU1MSIsIGNoaWxkRGF0YSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhYmVnaW5pbmciOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNoYXJhY3RlcmRhdGFkZWxldGVkYXRhYmVnaW5pbmcuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZW5kLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZW5kLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmJlMTk1YQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFlbmQuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImRlbGV0ZURhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kIHJlbW92ZXMgYSByYW5nZSBvZiAKKyAqICAgIGNoYXJhY3RlcnMgZnJvbSB0aGUgbm9kZS4gIERlbGV0ZSBkYXRhIGF0IHRoZSBlbmQgCisgKiAgICBvZiB0aGUgY2hhcmFjdGVyIGRhdGEuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBmcm9tIHRoZSBsYXN0IGNoaWxkIG9mIHRoZQorICogICAgZmlyc3QgZW1wbG95ZWUuICBUaGUgImRlbGV0ZURhdGEob2Zmc2V0LGNvdW50KSIKKyAqICAgIG1ldGhvZCBpcyB0aGVuIGNhbGxlZCB3aXRoIG9mZnNldD0zMCBhbmQgY291bnQ9NS4KKyAqICAgIFRoZSBtZXRob2Qgc2hvdWxkIGRlbGV0ZSB0aGUgY2hhcmFjdGVycyBmcm9tIHBvc2l0aW9uCisgKiAgICAzMCB0aHJ1IHBvc2l0aW9uIDM1LiAgVGhlIG5ldyB2YWx1ZSBvZiB0aGUgY2hhcmFjdGVyIGRhdGEKKyAqICAgIHNob3VsZCBiZSAiMTIzMCBOb3J0aCBBdmUuIERhbGxhcywgVGV4YXMiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03QzYwMzc4MTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFlbmQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFkZWxldGVkYXRhZW5kKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZERhdGE7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgY2hpbGQuZGVsZXRlRGF0YSgzMCwgNSk7CisgICAgICBjaGlsZERhdGEgPSBjaGlsZC5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlcmRhdGFEZWxldGVEYXRhRW5kQXNzZXJ0IiwgIjEyMzAgTm9ydGggQXZlLiBEYWxsYXMsIFRleGFzICIsIGNoaWxkRGF0YSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZW5kIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWVuZC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFleGNlZWRzbGVuZ3RoLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZXhjZWVkc2xlbmd0aC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxZTI1NGUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZXhjZWVkc2xlbmd0aC5qYXZhCkBAIC0wLDAgKzEsOTggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZSBzdW0gb2YgdGhlIG9mZnNldCBhbmQgY291bnQgdXNlZCBpbiB0aGUgICAgICAgIAorICogICAgImRlbGV0ZURhdGEob2Zmc2V0LGNvdW50KSBtZXRob2QgaXMgZ3JlYXRlciB0aGFuIHRoZQorICogICAgbGVuZ3RoIG9mIHRoZSBjaGFyYWN0ZXIgZGF0YSB0aGVuIGFsbCB0aGUgY2hhcmFjdGVycworICogICAgZnJvbSB0aGUgb2Zmc2V0IHRvIHRoZSBlbmQgb2YgdGhlIGRhdGEgYXJlIGRlbGV0ZWQuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgZnJvbSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqICAgIGZpcnN0IGVtcGxveWVlLiAgVGhlICJkZWxldGVEYXRhKG9mZnNldCxjb3VudCkiCisgKiAgICBtZXRob2QgaXMgdGhlbiBjYWxsZWQgd2l0aCBvZmZzZXQ9NCBhbmQgY291bnQ9NTAuCisgKiAgICBUaGUgbWV0aG9kIHNob3VsZCBkZWxldGUgdGhlIGNoYXJhY3RlcnMgZnJvbSBwb3NpdGlvbiA0CisgKiAgICB0byB0aGUgZW5kIG9mIHRoZSBkYXRhIHNpbmNlIHRoZSBvZmZzZXQrY291bnQoNTArNCkKKyAqICAgIGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoZSBjaGFyYWN0ZXIgZGF0YSgzNSkuCisgKiAgICBUaGUgbmV3IHZhbHVlIG9mIHRoZSBjaGFyYWN0ZXIgZGF0YSBzaG91bGQgYmUgIjEyMzAiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03QzYwMzc4MTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFleGNlZWRzbGVuZ3RoIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWV4Y2VlZHNsZW5ndGgoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkRGF0YTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZC5kZWxldGVEYXRhKDQsIDUwKTsKKyAgICAgIGNoaWxkRGF0YSA9IGNoaWxkLmdldERhdGEoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2hhcmFjdGVyZGF0YURlbGV0ZURhdGFFeGNlZWRzTGVuZ3RoQXNzZXJ0IiwgIjEyMzAiLCBjaGlsZERhdGEpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWV4Y2VlZHNsZW5ndGgiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNoYXJhY3RlcmRhdGFkZWxldGVkYXRhZXhjZWVkc2xlbmd0aC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFnZXRsZW5ndGhhbmRkYXRhLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZ2V0bGVuZ3RoYW5kZGF0YS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdlM2NmMTMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZ2V0bGVuZ3RoYW5kZGF0YS5qYXZhCkBAIC0wLDAgKzEsMTA0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBPbiBzdWNjZXNzZnVsIGludm9jYXRpb24gb2YgdGhlICJkZWxldGVEYXRhKG9mZnNldCxjb3VudCkiCisgKiAgICBtZXRob2QsIHRoZSAiZ2V0RGF0YSgpIiBhbmQgImdldExlbmd0aCgpIiBtZXRob2RzIHJlZmxlY3QKKyAqICAgIHRoZSBjaGFuZ2VzLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiAgICBmaXJzdCBlbXBsb3llZS4gIFRoZSAiZGVsZXRlRGF0YShvZmZzZXQsY291bnQpIgorICogICAgbWV0aG9kIGlzIHRoZW4gY2FsbGVkIHdpdGggb2Zmc2V0PTMwIGFuZCBjb3VudD01LgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgZGVsZXRlIHRoZSBjaGFyYWN0ZXJzIGZyb20gcG9zaXRpb24KKyAqICAgIDMwIHRocnUgcG9zaXRpb24gMzUuICBUaGUgbmV3IHZhbHVlIG9mIHRoZSBjaGFyYWN0ZXIgZGF0YQorICogICAgc2hvdWxkIGJlICIxMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyIgd2hpY2ggaXMKKyAqICAgIHJldHVybmVkIGJ5IHRoZSAiZ2V0RGF0YSgpIiBtZXRob2QgYW5kICJnZXRMZW5ndGgoKSIKKyAqICAgIG1ldGhvZCBzaG91bGQgcmV0dXJuIDMwIi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03RDYxMTc4QyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0Q2MTE3OEM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0M2MDM3ODEiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWdldGxlbmd0aGFuZGRhdGEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFkZWxldGVkYXRhZ2V0bGVuZ3RoYW5kZGF0YShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGREYXRhOworICAgICAgaW50IGNoaWxkTGVuZ3RoOworICAgICAgamF2YS51dGlsLkxpc3QgcmVzdWx0ID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIAorICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkLmRlbGV0ZURhdGEoMzAsIDUpOworICAgICAgY2hpbGREYXRhID0gY2hpbGQuZ2V0RGF0YSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkYXRhIiwgIjEyMzAgTm9ydGggQXZlLiBEYWxsYXMsIFRleGFzICIsIGNoaWxkRGF0YSk7CisgICAgICBjaGlsZExlbmd0aCA9IChpbnQpIGNoaWxkLmdldExlbmd0aCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJsZW5ndGgiLCAzMCwgY2hpbGRMZW5ndGgpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWdldGxlbmd0aGFuZGRhdGEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNoYXJhY3RlcmRhdGFkZWxldGVkYXRhZ2V0bGVuZ3RoYW5kZGF0YS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFtaWRkbGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFtaWRkbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNWYyZmYzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YW1pZGRsZS5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZGVsZXRlRGF0YShvZmZzZXQsY291bnQpIiBtZXRob2QgcmVtb3ZlcyBhIHJhbmdlIG9mIAorICogICAgY2hhcmFjdGVycyBmcm9tIHRoZSBub2RlLiAgRGVsZXRlIGRhdGEgaW4gdGhlIG1pZGRsZSAKKyAqICAgIG9mIHRoZSBjaGFyYWN0ZXIgZGF0YS4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiAgICBmaXJzdCBlbXBsb3llZS4gIFRoZSAiZGVsZXRlRGF0YShvZmZzZXQsY291bnQpIgorICogICAgbWV0aG9kIGlzIHRoZW4gY2FsbGVkIHdpdGggb2Zmc2V0PTE2IGFuZCBjb3VudD04LgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgZGVsZXRlIHRoZSBjaGFyYWN0ZXJzIGZyb20gcG9zaXRpb24KKyAqICAgIDE2IHRocnUgcG9zaXRpb24gMjQuICBUaGUgbmV3IHZhbHVlIG9mIHRoZSBjaGFyYWN0ZXIgZGF0YQorICogICAgc2hvdWxkIGJlICIxMjMwIE5vcnRoIEF2ZS4gVGV4YXMgOTg1NTEiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03QzYwMzc4MTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFtaWRkbGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFkZWxldGVkYXRhbWlkZGxlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZERhdGE7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgY2hpbGQuZGVsZXRlRGF0YSgxNiwgOCk7CisgICAgICBjaGlsZERhdGEgPSBjaGlsZC5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlcmRhdGFEZWxldGVEYXRhTWlkZGxlQXNzZXJ0IiwgIjEyMzAgTm9ydGggQXZlLiBUZXhhcyA5ODU1MSIsIGNoaWxkRGF0YSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhbWlkZGxlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YW1pZGRsZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOTAyYjc3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCkBAIC0wLDAgKzEsMTE0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZGVsZXRlRGF0YShvZmZzZXQsY291bnQpIiBtZXRob2QgcmFpc2VzIGEgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIAorICogICAgRE9NRXhjZXB0aW9uIGlmIHRoZSBub2RlIGlzIHJlYWRvbmx5LiAgIAorICogICAgT2J0YWluIHRoZSBjaGlsZHJlbiBvZiB0aGUgVEhJUkQgImdlbmRlciIgZWxlbWVudC4gIFRoZSBlbGVtZW50cworICogICAgY29udGVudCBpcyBhbiBlbnRpdHkgcmVmZXJlbmNlLiAgR2V0IHRoZSBGSVJTVCBpdGVtIAorICogICAgZnJvbSB0aGUgZW50aXR5IHJlZmVyZW5jZSBhbmQgZXhlY3V0ZSB0aGUgImRlbGV0ZURhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kLgorICogICAgVGhpcyBjYXVzZXMgYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgRE9NRXhjZXB0aW9uIHRvIGJlIHRocm93bi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0M2MDM3ODEiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC03QzYwMzc4MScpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTdDNjAzNzgxJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03QzYwMzc4MTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFkZWxldGVkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyTm9kZTsKKyAgICAgIE5vZGUgZW50RWxlbWVudDsKKyAgICAgIE5vZGUgZW50RWxlbWVudENvbnRlbnQ7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBOb2RlIGVudFJlZmVyZW5jZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGdlbmRlckxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImdlbmRlciIpOworICAgICAgZ2VuZGVyTm9kZSA9IGdlbmRlckxpc3QuaXRlbSgyKTsKKyAgICAgIGVudFJlZmVyZW5jZSA9IGdlbmRlck5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50UmVmZXJlbmNlTm90TnVsbCIsIGVudFJlZmVyZW5jZSk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGVudFJlZmVyZW5jZS5nZXROb2RlVHlwZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDMsIG5vZGVUeXBlKSkgeworICAgICAgICAgIGVudFJlZmVyZW5jZSA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDQiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZW50UmVmZXJlbmNlKTsKKyAgICAgIH0KKyAgICBlbnRFbGVtZW50ID0gZW50UmVmZXJlbmNlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudEVsZW1lbnROb3ROdWxsIiwgZW50RWxlbWVudCk7CisgICAgICBlbnRFbGVtZW50Q29udGVudCA9IGVudEVsZW1lbnQuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50RWxlbWVudENvbnRlbnROb3ROdWxsIiwgZW50RWxlbWVudENvbnRlbnQpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAoKENoYXJhY3RlckRhdGEpIC8qTm9kZSAqL2VudEVsZW1lbnRDb250ZW50KS5kZWxldGVEYXRhKDEsIDMpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjEyMmMzZAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQ3JlYXRlIGFuIGVudDMgZW50aXR5IHJlZmVyZW5jZSBhbmQgY2FsbCBkZWxldGVEYXRhIG9uIGEgdGV4dCBjaGlsZCwgc2hvdWxkIHRocm93biBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUi4gCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03QzYwMzc4MTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtN0M2MDM3ODEnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC03QzYwMzc4MScpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03QzYwMzc4MSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0M2MDM3ODE8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWwiPmh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIueG1sPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyTm9kZTsKKyAgICAgIE5vZGUgZW50VGV4dDsKKyAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWZlcmVuY2U7CisgICAgICBOb2RlIGFwcGVuZGVkQ2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBnZW5kZXJMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJnZW5kZXIiKTsKKyAgICAgIGdlbmRlck5vZGUgPSBnZW5kZXJMaXN0Lml0ZW0oMik7CisgICAgICBlbnRSZWZlcmVuY2UgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQzIik7CisgICAgICBhc3NlcnROb3ROdWxsKCJjcmVhdGVkRW50UmVmTm90TnVsbCIsIGVudFJlZmVyZW5jZSk7CisgICAgICBhcHBlbmRlZENoaWxkID0gZ2VuZGVyTm9kZS5hcHBlbmRDaGlsZChlbnRSZWZlcmVuY2UpOworICAgICAgZW50VGV4dCA9IGVudFJlZmVyZW5jZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRUZXh0Tm90TnVsbCIsIGVudFRleHQpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAoKENoYXJhY3RlckRhdGEpIC8qTm9kZSAqL2VudFRleHQpLmRlbGV0ZURhdGEoMSwgMyk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWdldGRhdGEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWdldGRhdGEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OTVmOWQ1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhZ2V0ZGF0YS5qYXZhCkBAIC0wLDAgKzEsOTAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0RGF0YSgpIiBtZXRob2QgcmV0cmlldmVzIHRoZSBjaGFyYWN0ZXIgZGF0YSAKKyAqICAgY3VycmVudGx5IHN0b3JlZCBpbiB0aGUgbm9kZS4KKyAqICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIHNlY29uZCBjaGlsZCAKKyAqICAgb2YgdGhlIGZpcnN0IGVtcGxveWVlIGFuZCBpbnZva2UgdGhlICJnZXREYXRhKCkiIAorICogICBtZXRob2QuICBUaGUgbWV0aG9kIHJldHVybnMgdGhlIGNoYXJhY3RlciBkYXRhIAorICogICBzdHJpbmcuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNoYXJhY3RlcmRhdGFnZXRkYXRhIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjaGFyYWN0ZXJkYXRhZ2V0ZGF0YShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkRGF0YTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgibmFtZSIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgY2hpbGREYXRhID0gY2hpbGQuZ2V0RGF0YSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyYWN0ZXJkYXRhR2V0RGF0YUFzc2VydCIsICJNYXJnYXJldCBNYXJ0aW4iLCBjaGlsZERhdGEpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhZ2V0ZGF0YSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2hhcmFjdGVyZGF0YWdldGRhdGEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFnZXRsZW5ndGguamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWdldGxlbmd0aC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc0NThkN2EKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFnZXRsZW5ndGguamF2YQpAQCAtMCwwICsxLDkyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldExlbmd0aCgpIiBtZXRob2QgcmV0dXJucyB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgCisgKiAgIHN0b3JlZCBpbiB0aGlzIG5vZGVzIGRhdGEuCisgKiAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBmcm9tIHRoZSBzZWNvbmQgCisgKiAgIGNoaWxkIG9mIHRoZSBmaXJzdCBlbXBsb3llZSBhbmQgZXhhbWluZSB0aGUgCisgKiAgIHZhbHVlIHJldHVybmVkIGJ5IHRoZSBnZXRMZW5ndGgoKSBtZXRob2QuICAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03RDYxMTc4QyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0Q2MTE3OEM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNoYXJhY3RlcmRhdGFnZXRsZW5ndGggZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFnZXRsZW5ndGgoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZFZhbHVlOworICAgICAgaW50IGNoaWxkTGVuZ3RoOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJuYW1lIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZFZhbHVlID0gY2hpbGQuZ2V0RGF0YSgpOworICAgICAgY2hpbGRMZW5ndGggPSBjaGlsZFZhbHVlLmxlbmd0aCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyYWN0ZXJkYXRhR2V0TGVuZ3RoQXNzZXJ0IiwgMTUsIGNoaWxkTGVuZ3RoKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWdldGxlbmd0aCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2hhcmFjdGVyZGF0YWdldGxlbmd0aC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFjb3VudG5lZ2F0aXZlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhY291bnRuZWdhdGl2ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ5MDJkNzMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhY291bnRuZWdhdGl2ZS5qYXZhCkBAIC0wLDAgKzEsMTA3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImRlbGV0ZURhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kIHJhaXNlcyBhbgorICogICAgSU5ERVhfU0laRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgY291bnQgCisgKiAgICBpcyBuZWdhdGl2ZS4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBvZiB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqICAgIGZpcnN0IGVtcGxveWVlIGFuZCBpbnZva2UgaXRzICJkZWxldGVEYXRhKG9mZnNldCxjb3VudCkiCisgKiAgICBtZXRob2Qgd2l0aCBvZmZzZXQ9MTAgYW5kIGNvdW50PS0zLiAgSXQgc2hvdWxkIHJhaXNlIHRoZQorICogICAgZGVzaXJlZCBleGNlcHRpb24gc2luY2UgdGhlIGNvdW50IGlzIG5lZ2F0aXZlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjUzMUJDQ0YiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTY1MzFCQ0NGPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC02NTMxQkNDRicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNjUzMUJDQ0YnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFjb3VudG5lZ2F0aXZlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyZGVsZXRlZGF0YWNvdW50bmVnYXRpdmUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcuc2lnbmVkCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNoaWxkLmRlbGV0ZURhdGEoMTAsIC0zKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dzX0lOREVYX1NJWkVfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhY291bnRuZWdhdGl2ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFjb3VudG5lZ2F0aXZlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyZGVsZXRlZGF0YW9mZnNldGdyZWF0ZXIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFvZmZzZXRncmVhdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGQ4YzdlOAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFvZmZzZXRncmVhdGVyLmphdmEKQEAgLTAsMCArMSwxMDQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJkZWxldGVEYXRhKG9mZnNldCxjb3VudCkiIG1ldGhvZCByYWlzZXMgYW4KKyAqICAgIElOREVYX1NJWkVfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIG9mZnNldAorICogICAgaXMgZ3JlYXRlciB0aGF0IHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgc3RyaW5nLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIG9mIHRoZSBsYXN0IGNoaWxkIG9mIHRoZQorICogICAgZmlyc3QgZW1wbG95ZWUgYW5kIGludm9rZSBpdHMgImRlbGV0ZURhdGEob2Zmc2V0LGNvdW50KSIKKyAqICAgIG1ldGhvZCB3aXRoIG9mZnNldD00MCBhbmQgY291bnQ9My4gIEl0IHNob3VsZCByYWlzZSB0aGUKKyAqICAgIGRlc2lyZWQgZXhjZXB0aW9uIHNpbmNlIHRoZSBvZmZzZXQgaXMgZ3JlYXRlciB0aGFuIHRoZQorICogICAgbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gdGhlIHN0cmluZy4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03QzYwMzc4MTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtN0M2MDM3ODEnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTdDNjAzNzgxJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0M2MDM3ODEiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhb2Zmc2V0Z3JlYXRlciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFvZmZzZXRncmVhdGVyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNoaWxkLmRlbGV0ZURhdGEoNDAsIDMpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTkRFWF9TSVpFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTkRFWF9TSVpFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyZGVsZXRlZGF0YW9mZnNldGdyZWF0ZXIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhb2Zmc2V0Z3JlYXRlci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFvZmZzZXRuZWdhdGl2ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyZGVsZXRlZGF0YW9mZnNldG5lZ2F0aXZlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTZkZDM2OAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFvZmZzZXRuZWdhdGl2ZS5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImRlbGV0ZURhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kIHJhaXNlcyBhbgorICogICAgSU5ERVhfU0laRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgb2Zmc2V0CisgKiAgICBpcyBuZWdhdGl2ZS4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBvZiB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqICAgIGZpcnN0IGVtcGxveWVlIGFuZCBpbnZva2UgaXRzICJkZWxldGVEYXRhKG9mZnNldCxjb3VudCkiCisgKiAgICBtZXRob2Qgd2l0aCBvZmZzZXQ9LTUgYW5kIGNvdW50PTMuICBJdCBzaG91bGQgcmFpc2UgdGhlCisgKiAgICBkZXNpcmVkIGV4Y2VwdGlvbiBzaW5jZSB0aGUgb2Zmc2V0IGlzIG5lZ2F0aXZlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0M2MDM3ODEiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC03QzYwMzc4MScpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtN0M2MDM3ODEnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03QzYwMzc4MSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0M2MDM3ODE8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhb2Zmc2V0bmVnYXRpdmUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhb2Zmc2V0bmVnYXRpdmUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcuc2lnbmVkCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNoaWxkLmRlbGV0ZURhdGEoLTUsIDMpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTkRFWF9TSVpFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd3NfSU5ERVhfU0laRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFvZmZzZXRuZWdhdGl2ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFvZmZzZXRuZWdhdGl2ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmluc2VydGRhdGFvZmZzZXRncmVhdGVyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJpbnNlcnRkYXRhb2Zmc2V0Z3JlYXRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMxNjMxNjIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJpbnNlcnRkYXRhb2Zmc2V0Z3JlYXRlci5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW5zZXJ0RGF0YShvZmZzZXQsYXJnKSIgbWV0aG9kIHJhaXNlcyBhbgorICogICAgSU5ERVhfU0laRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgb2Zmc2V0CisgKiAgICBpcyBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIHRoZSBzdHJpbmcuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgb2YgdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiAgICBmaXJzdCBlbXBsb3llZSBhbmQgaW52b2tlIGl0cyBpbnNlcnREYXRhIihvZmZzZXQsYXJnKSIKKyAqICAgIG1ldGhvZCB3aXRoIG9mZnNldD00MCBhbmQgYXJnPSJBQkMiLiAgSXQgc2hvdWxkIHJhaXNlCisgKiAgICB0aGUgZGVzaXJlZCBleGNlcHRpb24gc2luY2UgdGhlIG9mZnNldCBpcyBncmVhdGVyIHRoYW4KKyAqICAgIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgc3RyaW5nLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0M2MDM3ODEiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC03QzYwMzc4MScpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtN0M2MDM3ODEnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyaW5zZXJ0ZGF0YW9mZnNldGdyZWF0ZXIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJpbnNlcnRkYXRhb2Zmc2V0Z3JlYXRlcihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGlsZC5pbnNlcnREYXRhKDQwLCAiQUJDIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOREVYX1NJWkVfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOREVYX1NJWkVfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJpbnNlcnRkYXRhb2Zmc2V0Z3JlYXRlciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmluc2VydGRhdGFvZmZzZXRncmVhdGVyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyaW5zZXJ0ZGF0YW9mZnNldG5lZ2F0aXZlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJpbnNlcnRkYXRhb2Zmc2V0bmVnYXRpdmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNTc4ZDljCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyaW5zZXJ0ZGF0YW9mZnNldG5lZ2F0aXZlLmphdmEKQEAgLTAsMCArMSwxMDcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW5zZXJ0RGF0YShvZmZzZXQsYXJnKSIgbWV0aG9kIHJhaXNlcyBhbgorICogICAgSU5ERVhfU0laRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgb2Zmc2V0CisgKiAgICBpcyBuZWdhdGl2ZS4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBvZiB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqICAgIGZpcnN0IGVtcGxveWVlIGFuZCBpbnZva2UgaXRzIGluc2VydERhdGEiKG9mZnNldCxhcmcpIgorICogICAgbWV0aG9kIHdpdGggb2Zmc2V0PS01IGFuZCBhcmc9IkFCQyIuICBJdCBzaG91bGQgcmFpc2UKKyAqICAgIHRoZSBkZXNpcmVkIGV4Y2VwdGlvbiBzaW5jZSB0aGUgb2Zmc2V0IGlzIG5lZ2F0aXZlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRTVDQkE3RkIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU1Q0JBN0ZCPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC1FNUNCQTdGQicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtRTVDQkE3RkInKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmluc2VydGRhdGFvZmZzZXRuZWdhdGl2ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmluc2VydGRhdGFvZmZzZXRuZWdhdGl2ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5zaWduZWQKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgY2hpbGQuaW5zZXJ0RGF0YSgtNSwgIkFCQyIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTkRFWF9TSVpFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd3NfSU5ERVhfU0laRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmluc2VydGRhdGFvZmZzZXRuZWdhdGl2ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmluc2VydGRhdGFvZmZzZXRuZWdhdGl2ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhY291bnRuZWdhdGl2ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJycmVwbGFjZWRhdGFjb3VudG5lZ2F0aXZlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDFiNWJjYwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhY291bnRuZWdhdGl2ZS5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIiBtZXRob2QgcmFpc2VzIGFuCisgKiAgICBJTkRFWF9TSVpFX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBjb3VudAorICogICAgaXMgbmVnYXRpdmUuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgb2YgdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiAgICBmaXJzdCBlbXBsb3llZSBhbmQgaW52b2tlIGl0cworICogICAgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIG1ldGhvZCB3aXRoIG9mZnNldD0xMAorICogICAgYW5kIGNvdW50PS0zIGFuZCBhcmc9IkFCQyIuICBJdCBzaG91bGQgcmFpc2UgdGhlCisgKiAgICBkZXNpcmVkIGV4Y2VwdGlvbiBzaW5jZSB0aGUgY291bnQgaXMgbmVnYXRpdmUuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NTMxQkNDRiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjUzMUJDQ0Y8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTY1MzFCQ0NGJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC02NTMxQkNDRicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJycmVwbGFjZWRhdGFjb3VudG5lZ2F0aXZlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJycmVwbGFjZWRhdGFjb3VudG5lZ2F0aXZlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLnNpZ25lZAorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGlsZC5yZXBsYWNlRGF0YSgxMCwgLTMsICJBQkMiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dzX0lOREVYX1NJWkVfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJyZXBsYWNlZGF0YWNvdW50bmVnYXRpdmUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJyZXBsYWNlZGF0YWNvdW50bmVnYXRpdmUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJyZXBsYWNlZGF0YW9mZnNldGdyZWF0ZXIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhb2Zmc2V0Z3JlYXRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZlZGExNmYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJyZXBsYWNlZGF0YW9mZnNldGdyZWF0ZXIuamF2YQpAQCAtMCwwICsxLDEwNCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIiBtZXRob2QgcmFpc2VzIGFuCisgKiAgICBJTkRFWF9TSVpFX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBvZmZzZXQKKyAqICAgIGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgb2YgdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiAgICBmaXJzdCBlbXBsb3llZSBhbmQgaW52b2tlIGl0cworICogICAgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIG1ldGhvZCB3aXRoIG9mZnNldD00MAorICogICAgYW5kIGNvdW50PTMgYW5kIGFyZz0iQUJDIi4gIEl0IHNob3VsZCByYWlzZSB0aGUKKyAqICAgIGRlc2lyZWQgZXhjZXB0aW9uIHNpbmNlIHRoZSBvZmZzZXQgaXMgZ3JlYXRlciB0aGFuIHRoZQorICogICAgbGVuZ3RoIG9mIHRoZSBzdHJpbmcuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03QzYwMzc4MSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0M2MDM3ODE8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTdDNjAzNzgxJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC03QzYwMzc4MScpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJyZXBsYWNlZGF0YW9mZnNldGdyZWF0ZXIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJyZXBsYWNlZGF0YW9mZnNldGdyZWF0ZXIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgY2hpbGQucmVwbGFjZURhdGEoNDAsIDMsICJBQkMiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSU5ERVhfU0laRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhb2Zmc2V0Z3JlYXRlciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhb2Zmc2V0Z3JlYXRlci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhb2Zmc2V0bmVnYXRpdmUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhb2Zmc2V0bmVnYXRpdmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOGFhZTVjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJycmVwbGFjZWRhdGFvZmZzZXRuZWdhdGl2ZS5qYXZhCkBAIC0wLDAgKzEsMTA5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIiBtZXRob2QgcmFpc2VzIGFuCisgKiAgICBJTkRFWF9TSVpFX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBvZmZzZXQKKyAqICAgIGlzIG5lZ2F0aXZlLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIG9mIHRoZSBsYXN0IGNoaWxkIG9mIHRoZQorICogICAgZmlyc3QgZW1wbG95ZWUgYW5kIGludm9rZSBpdHMKKyAqICAgICJyZXBsYWNlRGF0YShvZmZzZXQsY291bnQsYXJnKSBtZXRob2Qgd2l0aCBvZmZzZXQ9LTUKKyAqICAgIGFuZCBjb3VudD0zIGFuZCBhcmc9IkFCQyIuICBJdCBzaG91bGQgcmFpc2UgdGhlCisgKiAgICBkZXNpcmVkIGV4Y2VwdGlvbiBzaW5jZSB0aGUgb2Zmc2V0IGlzIG5lZ2F0aXZlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRTVDQkE3RkIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU1Q0JBN0ZCPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC1FNUNCQTdGQicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtRTVDQkE3RkInKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1FNUNCQTdGQiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRTVDQkE3RkI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJyZXBsYWNlZGF0YW9mZnNldG5lZ2F0aXZlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJycmVwbGFjZWRhdGFvZmZzZXRuZWdhdGl2ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5zaWduZWQKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgY2hpbGQucmVwbGFjZURhdGEoLTUsIDMsICJBQkMiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dzX0lOREVYX1NJWkVfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJyZXBsYWNlZGF0YW9mZnNldG5lZ2F0aXZlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJycmVwbGFjZWRhdGFvZmZzZXRuZWdhdGl2ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ2NvdW50bmVnYXRpdmUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ2NvdW50bmVnYXRpdmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMTRkNDRhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nY291bnRuZWdhdGl2ZS5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInN1YnN0cmluZ0RhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kIHJhaXNlcyBhbgorICogICAgSU5ERVhfU0laRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgY291bnQgCisgKiAgICBpcyBuZWdhdGl2ZS4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBvZiB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqICAgIGZpcnN0IGVtcGxveWVlIGFuZCBpbnZva2UgaXRzICJzdWJzdHJpbmdEYXRhKG9mZnNldCxjb3VudCkKKyAqICAgIG1ldGhvZCB3aXRoIG9mZnNldD0xMCBhbmQgY291bnQ9LTMuICBJdCBzaG91bGQgcmFpc2UgdGhlCisgKiAgICBkZXNpcmVkIGV4Y2VwdGlvbiBzaW5jZSB0aGUgY291bnQgaXMgbmVnYXRpdmUuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NTMxQkNDRiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjUzMUJDQ0Y8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTY1MzFCQ0NGJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC02NTMxQkNDRicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nY291bnRuZWdhdGl2ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ2NvdW50bmVnYXRpdmUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcuc2lnbmVkCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgYmFkU3Vic3RyaW5nOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJhZFN1YnN0cmluZyA9IGNoaWxkLnN1YnN0cmluZ0RhdGEoMTAsIC0zKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dzX0lOREVYX1NJWkVfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJzdWJzdHJpbmdjb3VudG5lZ2F0aXZlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nY291bnRuZWdhdGl2ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ25lZ2F0aXZlb2Zmc2V0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJzdWJzdHJpbmduZWdhdGl2ZW9mZnNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM3ZmNlYTQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJzdWJzdHJpbmduZWdhdGl2ZW9mZnNldC5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInN1YnN0cmluZ0RhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kIHJhaXNlcyBhbgorICogICAgSU5ERVhfU0laRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgb2Zmc2V0CisgKiAgICBpcyBuZWdhdGl2ZS4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBvZiB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqICAgIGZpcnN0IGVtcGxveWVlIGFuZCBpbnZva2UgaXRzICJzdWJzdHJpbmdEYXRhKG9mZnNldCxjb3VudCkKKyAqICAgIG1ldGhvZCB3aXRoIG9mZnNldD0tNSBhbmQgY291bnQ9My4gIEl0IHNob3VsZCByYWlzZSB0aGUKKyAqICAgIGRlc2lyZWQgZXhjZXB0aW9uIHNpbmNlIHRoZSBvZmZzZXQgaXMgbmVnYXRpdmUuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NTMxQkNDRiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjUzMUJDQ0Y8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTY1MzFCQ0NGJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC02NTMxQkNDRicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nbmVnYXRpdmVvZmZzZXQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJzdWJzdHJpbmduZWdhdGl2ZW9mZnNldChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5zaWduZWQKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBiYWRTdHJpbmc7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgYmFkU3RyaW5nID0gY2hpbGQuc3Vic3RyaW5nRGF0YSgtNSwgMyk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOREVYX1NJWkVfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93c19JTkRFWF9TSVpFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nbmVnYXRpdmVvZmZzZXQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJzdWJzdHJpbmduZWdhdGl2ZW9mZnNldC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ29mZnNldGdyZWF0ZXIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ29mZnNldGdyZWF0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MDBjNWViCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nb2Zmc2V0Z3JlYXRlci5qYXZhCkBAIC0wLDAgKzEsMTA0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic3Vic3RyaW5nRGF0YShvZmZzZXQsY291bnQpIiBtZXRob2QgcmFpc2VzIGFuCisgKiAgICBJTkRFWF9TSVpFX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBvZmZzZXQKKyAqICAgIGlzIGdyZWF0ZXIgdGhhbiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gdGhlIHN0cmluZy4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIG9mIHRoZSBsYXN0IGNoaWxkIG9mIHRoZQorICogICAgZmlyc3QgZW1wbG95ZWUgYW5kIGludm9rZSBpdHMgInN1YnN0cmluZ0RhdGEob2Zmc2V0LGNvdW50KQorICogICAgbWV0aG9kIHdpdGggb2Zmc2V0PTQwIGFuZCBjb3VudD0zLiAgSXQgc2hvdWxkIHJhaXNlIHRoZQorICogICAgZGVzaXJlZCBleGNlcHRpb24gc2luY2UgdGhlIG9mZnNldHMgdmFsdWUgaXMgZ3JlYXRlcgorICogICAgdGhhbiB0aGUgbGVuZ3RoLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjUzMUJDQ0YiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTY1MzFCQ0NGPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC02NTMxQkNDRicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNjUzMUJDQ0YnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nb2Zmc2V0Z3JlYXRlciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ29mZnNldGdyZWF0ZXIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBiYWRTdHJpbmc7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgYmFkU3RyaW5nID0gY2hpbGQuc3Vic3RyaW5nRGF0YSg0MCwgMyk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOREVYX1NJWkVfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOREVYX1NJWkVfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJzdWJzdHJpbmdvZmZzZXRncmVhdGVyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nb2Zmc2V0Z3JlYXRlci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluc2VydGRhdGFiZWdpbm5pbmcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluc2VydGRhdGFiZWdpbm5pbmcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YWRiNzIyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YWJlZ2lubmluZy5qYXZhCkBAIC0wLDAgKzEsOTQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogVGhlICJpbnNlcnREYXRhKG9mZnNldCxhcmcpIiBtZXRob2Qgd2lsbCBpbnNlcnQgYSBzdHJpbmcKKyAqIGF0IHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIG9mZnNldC4gIEluc2VydCB0aGUgZGF0YSBhdAorICogdGhlIGJlZ2lubmluZyBvZiB0aGUgY2hhcmFjdGVyIGRhdGEuCisgKiBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgZnJvbSB0aGUgc2Vjb25kIGNoaWxkIG9mCisgKiB0aGUgZmlyc3QgZW1wbG95ZWUuICBUaGUgImluc2VydERhdGEob2Zmc2V0LGFyZykiCisgKiBtZXRob2QgaXMgdGhlbiBjYWxsZWQgd2l0aCBvZmZzZXQ9MCBhbmQgYXJnPSJNc3MuIi4KKyAqIFRoZSBtZXRob2Qgc2hvdWxkIGluc2VydCB0aGUgc3RyaW5nICJNc3MuIiBhdCBwb3NpdGlvbiAwLgorICogVGhlIG5ldyB2YWx1ZSBvZiB0aGUgY2hhcmFjdGVyIGRhdGEgc2hvdWxkIGJlCisgKiAiTXNzLiBNYXJnYXJldCBNYXJ0aW4iLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtM0VEQjY5NUYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTNFREI2OTVGPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YWJlZ2lubmluZyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY2hhcmFjdGVyZGF0YWluc2VydGRhdGFiZWdpbm5pbmcoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkRGF0YTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJuYW1lIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZC5pbnNlcnREYXRhKDAsICJNc3MuICIpOworICAgICAgY2hpbGREYXRhID0gY2hpbGQuZ2V0RGF0YSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyYWN0ZXJkYXRhSW5zZXJ0RGF0YUJlZ2lubmluZ0Fzc2VydCIsICJNc3MuIE1hcmdhcmV0IE1hcnRpbiIsIGNoaWxkRGF0YSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhYmVnaW5uaW5nIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YWJlZ2lubmluZy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluc2VydGRhdGFlbmQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluc2VydGRhdGFlbmQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMzA1MmM2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YWVuZC5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW5zZXJ0RGF0YShvZmZzZXQsYXJnKSIgbWV0aG9kIHdpbGwgaW5zZXJ0IGEgc3RyaW5nIAorICogICAgYXQgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgb2Zmc2V0LiAgSW5zZXJ0IHRoZSBkYXRhIGF0IAorICogICAgdGhlIGVuZCBvZiB0aGUgY2hhcmFjdGVyIGRhdGEuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgZnJvbSB0aGUgc2Vjb25kIGNoaWxkIG9mICAKKyAqICAgIHRoZSBmaXJzdCBlbXBsb3llZS4gIFRoZSAiaW5zZXJ0RGF0YShvZmZzZXQsYXJnKSIKKyAqICAgIG1ldGhvZCBpcyB0aGVuIGNhbGxlZCB3aXRoIG9mZnNldD0xNSBhbmQgYXJnPSIsIEVzcXVpcmUiLgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgaW5zZXJ0IHRoZSBzdHJpbmcgIiwgRXNxdWlyZSIgYXQgCisgKiAgICBwb3NpdGlvbiAxNS4gIFRoZSBuZXcgdmFsdWUgb2YgdGhlIGNoYXJhY3RlciBkYXRhIHNob3VsZAorICogICAgYmUgIk1hcmdhcmV0IE1hcnRpbiwgRXNxdWlyZSIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtM0VEQjY5NUYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTNFREI2OTVGPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YWVuZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY2hhcmFjdGVyZGF0YWluc2VydGRhdGFlbmQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkRGF0YTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJuYW1lIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZC5pbnNlcnREYXRhKDE1LCAiLCBFc3F1aXJlIik7CisgICAgICBjaGlsZERhdGEgPSBjaGlsZC5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlcmRhdGFJbnNlcnREYXRhRW5kQXNzZXJ0IiwgIk1hcmdhcmV0IE1hcnRpbiwgRXNxdWlyZSIsIGNoaWxkRGF0YSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhZW5kIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YWVuZC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluc2VydGRhdGFtaWRkbGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluc2VydGRhdGFtaWRkbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZjY1MTY4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YW1pZGRsZS5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW5zZXJ0RGF0YShvZmZzZXQsYXJnKSIgbWV0aG9kIHdpbGwgaW5zZXJ0IGEgc3RyaW5nIAorICogICAgYXQgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgb2Zmc2V0LiAgSW5zZXJ0IHRoZSBkYXRhIGluIAorICogICAgdGhlIG1pZGRsZSBvZiB0aGUgY2hhcmFjdGVyIGRhdGEuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgZnJvbSB0aGUgc2Vjb25kIGNoaWxkIG9mICAKKyAqICAgIHRoZSBmaXJzdCBlbXBsb3llZS4gIFRoZSAiaW5zZXJ0RGF0YShvZmZzZXQsYXJnKSIKKyAqICAgIG1ldGhvZCBpcyB0aGVuIGNhbGxlZCB3aXRoIG9mZnNldD05IGFuZCBhcmc9IkFubiIuCisgKiAgICBUaGUgbWV0aG9kIHNob3VsZCBpbnNlcnQgdGhlIHN0cmluZyAiQW5uIiBhdCBwb3NpdGlvbiA5LgorICogICAgVGhlIG5ldyB2YWx1ZSBvZiB0aGUgY2hhcmFjdGVyIGRhdGEgc2hvdWxkIGJlCisgKiAgICAiTWFyZ2FyZXQgQW5uIE1hcnRpbiIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtM0VEQjY5NUYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTNFREI2OTVGPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YW1pZGRsZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY2hhcmFjdGVyZGF0YWluc2VydGRhdGFtaWRkbGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkRGF0YTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJuYW1lIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZC5pbnNlcnREYXRhKDksICJBbm4gIik7CisgICAgICBjaGlsZERhdGEgPSBjaGlsZC5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlcmRhdGFJbnNlcnREYXRhTWlkZGxlQXNzZXJ0IiwgIk1hcmdhcmV0IEFubiBNYXJ0aW4iLCBjaGlsZERhdGEpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YW1pZGRsZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2hhcmFjdGVyZGF0YWluc2VydGRhdGFtaWRkbGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjJmMjNhNgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluc2VydGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuamF2YQpAQCAtMCwwICsxLDExNCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImluc2VydERhdGEob2Zmc2V0LGFyZykiIG1ldGhvZCByYWlzZXMgYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgCisgKiAgICBET01FeGNlcHRpb24gaWYgdGhlIG5vZGUgaXMgcmVhZG9ubHkuICAgCisgKiAgICBPYnRhaW4gdGhlIGNoaWxkcmVuIG9mIHRoZSBUSElSRCAiZ2VuZGVyIiBlbGVtZW50LiAgVGhlIGVsZW1lbnRzCisgKiAgICBjb250ZW50IGlzIGFuIGVudGl0eSByZWZlcmVuY2UuICBHZXQgdGhlIEZJUlNUIGl0ZW0gCisgKiAgICBmcm9tIHRoZSBlbnRpdHkgcmVmZXJlbmNlIGFuZCBleGVjdXRlIHRoZSAiaW5zZXJ0RGF0YShvZmZzZXQsYXJnKSIgbWV0aG9kLgorICogICAgVGhpcyBjYXVzZXMgYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgRE9NRXhjZXB0aW9uIHRvIGJlIHRocm93bi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtM0VEQjY5NUYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTNFREI2OTVGPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0zRURCNjk1RicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTNFREI2OTVGJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTNFREI2OTVGIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zRURCNjk1RjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY2hhcmFjdGVyZGF0YWluc2VydGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFpbnNlcnRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyTm9kZTsKKyAgICAgIE5vZGUgZW50RWxlbWVudDsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIE5vZGUgZW50RWxlbWVudENvbnRlbnQ7CisgICAgICBOb2RlIGVudFJlZmVyZW5jZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGdlbmRlckxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImdlbmRlciIpOworICAgICAgZ2VuZGVyTm9kZSA9IGdlbmRlckxpc3QuaXRlbSgyKTsKKyAgICAgIGVudFJlZmVyZW5jZSA9IGdlbmRlck5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50UmVmZXJlbmNlTm90TnVsbCIsIGVudFJlZmVyZW5jZSk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGVudFJlZmVyZW5jZS5nZXROb2RlVHlwZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDEsIG5vZGVUeXBlKSkgeworICAgICAgICAgIGVudFJlZmVyZW5jZSA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDQiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZW50UmVmZXJlbmNlKTsKKyAgICAgIH0KKyAgICBlbnRFbGVtZW50ID0gZW50UmVmZXJlbmNlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudEVsZW1lbnROb3ROdWxsIiwgZW50RWxlbWVudCk7CisgICAgICBlbnRFbGVtZW50Q29udGVudCA9IGVudEVsZW1lbnQuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50RWxlbWVudENvbnRlbnROb3ROdWxsIiwgZW50RWxlbWVudENvbnRlbnQpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAoKENoYXJhY3RlckRhdGEpIC8qTm9kZSAqL2VudEVsZW1lbnRDb250ZW50KS5pbnNlcnREYXRhKDEsICJuZXdBcmciKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2hhcmFjdGVyZGF0YWluc2VydGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluc2VydGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyY2E3ZWUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YQpAQCAtMCwwICsxLDk5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQ3JlYXRlIGFuIGVudDMgZW50aXR5IHJlZmVyZW5jZSBhbmQgY2FsbCBpbnNlcnREYXRhIG9uIGEgdGV4dCBjaGlsZCwgc2hvdWxkIHRocm93biBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUi4gCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTNFREI2OTVGIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zRURCNjk1RjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtM0VEQjY5NUYnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0zRURCNjk1RicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zRURCNjk1RiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtM0VEQjY5NUY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWwiPmh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YWluc2VydGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIueG1sPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgZW50VGV4dDsKKyAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWZlcmVuY2U7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBnZW5kZXJMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJnZW5kZXIiKTsKKyAgICAgIGdlbmRlck5vZGUgPSBnZW5kZXJMaXN0Lml0ZW0oMik7CisgICAgICBlbnRSZWZlcmVuY2UgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQzIik7CisgICAgICBhc3NlcnROb3ROdWxsKCJjcmVhdGVkRW50UmVmTm90TnVsbCIsIGVudFJlZmVyZW5jZSk7CisgICAgICBlbnRUZXh0ID0gKENoYXJhY3RlckRhdGEpIGVudFJlZmVyZW5jZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRUZXh0Tm90TnVsbCIsIGVudFRleHQpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbnRUZXh0Lmluc2VydERhdGEoMSwgIm5ld0FyZyIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNoYXJhY3RlcmRhdGFpbnNlcnRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWJlZ2luaW5nLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWJlZ2luaW5nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzNmYTk4OAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhYmVnaW5pbmcuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIFRoZSAicmVwbGFjZURhdGEob2Zmc2V0LGNvdW50LGFyZykiIG1ldGhvZCByZXBsYWNlcyB0aGUKKyAqIGNoYXJhY3RlcnMgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCBvZmZzZXQgd2l0aCB0aGUKKyAqIHNwZWNpZmllZCBzdHJpbmcuICBUZXN0IGZvciByZXBsYWNlbWVudCBpbiB0aGUKKyAqIG1pZGRsZSBvZiB0aGUgZGF0YS4KKyAqIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBmcm9tIHRoZSBsYXN0IGNoaWxkIG9mIHRoZQorICogZmlyc3QgZW1wbG95ZWUuICBUaGUgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIgorICogbWV0aG9kIGlzIHRoZW4gY2FsbGVkIHdpdGggb2Zmc2V0PTUgYW5kIGNvdW50PTUgYW5kCisgKiBhcmc9IlNvdXRoIi4gIFRoZSBtZXRob2Qgc2hvdWxkIHJlcGxhY2UgY2hhcmFjdGVycyBmaXZlCisgKiB0aHJ1IDkgb2YgdGhlIGNoYXJhY3RlciBkYXRhIHdpdGggIlNvdXRoIi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU1Q0JBN0ZCIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1FNUNCQTdGQjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhYmVnaW5pbmcgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWJlZ2luaW5nKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZERhdGE7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgY2hpbGQucmVwbGFjZURhdGEoMCwgNCwgIjI1MDAiKTsKKyAgICAgIGNoaWxkRGF0YSA9IGNoaWxkLmdldERhdGEoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2hhcmFjdGVyZGF0YVJlcGxhY2VEYXRhQmVnaW5pbmdBc3NlcnQiLCAiMjUwMCBOb3J0aCBBdmUuIERhbGxhcywgVGV4YXMgOTg1NTEiLCBjaGlsZERhdGEpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFiZWdpbmluZyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhYmVnaW5pbmcuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWVuZC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFlbmQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OWUyZjg3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFlbmQuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIiBtZXRob2QgcmVwbGFjZXMgdGhlIAorICogICAgY2hhcmFjdGVycyBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIG9mZnNldCB3aXRoIHRoZQorICogICAgc3BlY2lmaWVkIHN0cmluZy4gIFRlc3QgZm9yIHJlcGxhY2VtZW50IGF0IHRoZSAKKyAqICAgIGVuZCBvZiB0aGUgZGF0YS4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiAgICBmaXJzdCBlbXBsb3llZS4gIFRoZSAicmVwbGFjZURhdGEob2Zmc2V0LGNvdW50LGFyZykiCisgKiAgICBtZXRob2QgaXMgdGhlbiBjYWxsZWQgd2l0aCBvZmZzZXQ9MzAgYW5kIGNvdW50PTUgYW5kCisgKiAgICBhcmc9Ijk4NjY1Ii4gIFRoZSBtZXRob2Qgc2hvdWxkIHJlcGxhY2UgY2hhcmFjdGVycyAzMCAgCisgKiAgICB0aHJ1IDM0IG9mIHRoZSBjaGFyYWN0ZXIgZGF0YSB3aXRoICI5ODY2NSIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRTVDQkE3RkIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU1Q0JBN0ZCPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFlbmQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWVuZChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGREYXRhOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkLnJlcGxhY2VEYXRhKDMwLCA1LCAiOTg2NjUiKTsKKyAgICAgIGNoaWxkRGF0YSA9IGNoaWxkLmdldERhdGEoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2hhcmFjdGVyZGF0YVJlcGxhY2VEYXRhRW5kQXNzZXJ0IiwgIjEyMzAgTm9ydGggQXZlLiBEYWxsYXMsIFRleGFzIDk4NjY1IiwgY2hpbGREYXRhKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZW5kIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFlbmQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWV4Y2VlZHNsZW5ndGhvZmFyZy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFleGNlZWRzbGVuZ3Rob2ZhcmcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMDI1YmU0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFleGNlZWRzbGVuZ3Rob2ZhcmcuamF2YQpAQCAtMCwwICsxLDk3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIiBtZXRob2QgcmVwbGFjZXMgdGhlIAorICogICAgY2hhcmFjdGVycyBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIG9mZnNldCB3aXRoIHRoZQorICogICAgc3BlY2lmaWVkIHN0cmluZy4gIFRlc3QgdGhlIHNpdHVhdGlvbiB3aGVyZSB0aGUgbGVuZ3RoIAorICogICAgb2YgdGhlIGFyZyBzdHJpbmcgaXMgZ3JlYXRlciB0aGFuIHRoZSBzcGVjaWZpZWQgb2Zmc2V0LgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgZnJvbSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqICAgIGZpcnN0IGVtcGxveWVlLiAgVGhlICJyZXBsYWNlRGF0YShvZmZzZXQsY291bnQsYXJnKSIKKyAqICAgIG1ldGhvZCBpcyB0aGVuIGNhbGxlZCB3aXRoIG9mZnNldD0wIGFuZCBjb3VudD00IGFuZAorICogICAgYXJnPSIyNjAwMzAiLiAgVGhlIG1ldGhvZCBzaG91bGQgcmVwbGFjZSBjaGFyYWN0ZXJzIG9uZSAgCisgKiAgICB0aHJ1IGZvdXIgd2l0aCAiMjYwMDMwIi4gIE5vdGUgdGhhdCB0aGUgbGVuZ3RoIG9mIHRoZQorICogICAgc3BlY2lmaWVkIHN0cmluZyBpcyBncmVhdGVyIHRoYXQgdGhlIHNwZWNpZmllZCBvZmZzZXQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRTVDQkE3RkIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU1Q0JBN0ZCPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFleGNlZWRzbGVuZ3Rob2ZhcmcgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWV4Y2VlZHNsZW5ndGhvZmFyZyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGREYXRhOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkLnJlcGxhY2VEYXRhKDAsIDQsICIyNjAwMzAiKTsKKyAgICAgIGNoaWxkRGF0YSA9IGNoaWxkLmdldERhdGEoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2hhcmFjdGVyZGF0YVJlcGxhY2VEYXRhRXhjZWVkc0xlbmd0aE9mQXJnQXNzZXJ0IiwgIjI2MDAzMCBOb3J0aCBBdmUuIERhbGxhcywgVGV4YXMgOTg1NTEiLCBjaGlsZERhdGEpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFleGNlZWRzbGVuZ3Rob2ZhcmciOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWV4Y2VlZHNsZW5ndGhvZmFyZy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZXhjZWVkc2xlbmd0aG9mZGF0YS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFleGNlZWRzbGVuZ3Rob2ZkYXRhLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTc5NGYxMQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZXhjZWVkc2xlbmd0aG9mZGF0YS5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZSBzdW0gb2YgdGhlIG9mZnNldCBhbmQgY291bnQgZXhjZWVkcyB0aGUgbGVuZ3RoIHRoZW4gCisgKiAgICBhbGwgdGhlIGNoYXJhY3RlcnMgdG8gdGhlIGVuZCBvZiB0aGUgZGF0YSBhcmUgcmVwbGFjZWQuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBmcm9tIHRoZSBsYXN0IGNoaWxkIG9mIHRoZQorICogICAgZmlyc3QgZW1wbG95ZWUuICBUaGUgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIgorICogICAgbWV0aG9kIGlzIHRoZW4gY2FsbGVkIHdpdGggb2Zmc2V0PTAgYW5kIGNvdW50PTUwIGFuZAorICogICAgYXJnPSIyNjAwIi4gIFRoZSBtZXRob2Qgc2hvdWxkIHJlcGxhY2UgYWxsIHRoZSBjaGFyYWN0ZXJzCisgKiAgICB3aXRoICIyNjAwIi4gVGhpcyBpcyBiZWNhdXNlIHRoZSBzdW0gb2YgdGhlIG9mZnNldCBhbmQKKyAqICAgIGNvdW50IGV4Y2VlZHMgdGhlIGxlbmd0aCBvZiB0aGUgY2hhcmFjdGVyIGRhdGEuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRTVDQkE3RkIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU1Q0JBN0ZCPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFleGNlZWRzbGVuZ3Rob2ZkYXRhIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFleGNlZWRzbGVuZ3Rob2ZkYXRhKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZERhdGE7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgY2hpbGQucmVwbGFjZURhdGEoMCwgNTAsICIyNjAwIik7CisgICAgICBjaGlsZERhdGEgPSBjaGlsZC5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlcmRhdGFSZXBsYWNlRGF0YUV4Y2VlZHNMZW5ndGhPZkRhdGFBc3NlcnQiLCAiMjYwMCIsIGNoaWxkRGF0YSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWV4Y2VlZHNsZW5ndGhvZmRhdGEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWV4Y2VlZHNsZW5ndGhvZmRhdGEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YW1pZGRsZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFtaWRkbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYTE2OGU2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFtaWRkbGUuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIiBtZXRob2QgcmVwbGFjZXMgdGhlIAorICogICAgY2hhcmFjdGVycyBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIG9mZnNldCB3aXRoIHRoZQorICogICAgc3BlY2lmaWVkIHN0cmluZy4gIFRlc3QgZm9yIHJlcGxhY2VtZW50IGluIHRoZSAKKyAqICAgIG1pZGRsZSBvZiB0aGUgZGF0YS4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiAgICBmaXJzdCBlbXBsb3llZS4gIFRoZSAicmVwbGFjZURhdGEob2Zmc2V0LGNvdW50LGFyZykiCisgKiAgICBtZXRob2QgaXMgdGhlbiBjYWxsZWQgd2l0aCBvZmZzZXQ9NSBhbmQgY291bnQ9NSBhbmQKKyAqICAgIGFyZz0iU291dGgiLiAgVGhlIG1ldGhvZCBzaG91bGQgcmVwbGFjZSBjaGFyYWN0ZXJzIGZpdmUgIAorICogICAgdGhydSA5IG9mIHRoZSBjaGFyYWN0ZXIgZGF0YSB3aXRoICJTb3V0aCIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRTVDQkE3RkIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU1Q0JBN0ZCPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFtaWRkbGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YW1pZGRsZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGREYXRhOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkLnJlcGxhY2VEYXRhKDUsIDUsICJTb3V0aCIpOworICAgICAgY2hpbGREYXRhID0gY2hpbGQuZ2V0RGF0YSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyYWN0ZXJkYXRhUmVwbGFjZURhdGFNaWRkbGVBc3NlcnQiLCAiMTIzMCBTb3V0aCBBdmUuIERhbGxhcywgVGV4YXMgOTg1NTEiLCBjaGlsZERhdGEpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFtaWRkbGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YW1pZGRsZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYxNzZkM2IKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCkBAIC0wLDAgKzEsMTE1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAicmVwbGFjZURhdGEob2Zmc2V0LGNvdW50LGFyZykiIG1ldGhvZCByYWlzZXMgYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgCisgKiAgICBET01FeGNlcHRpb24gaWYgdGhlIG5vZGUgaXMgcmVhZG9ubHkuCisgKiAgICAKKyAqICAgIE9idGFpbiB0aGUgY2hpbGRyZW4gb2YgdGhlIFRISVJEICJnZW5kZXIiIGVsZW1lbnQuICBUaGUgZWxlbWVudHMKKyAqICAgIGNvbnRlbnQgaXMgYW4gZW50aXR5IHJlZmVyZW5jZS4gIEdldCB0aGUgRklSU1QgaXRlbSAKKyAqICAgIGZyb20gdGhlIGVudGl0eSByZWZlcmVuY2UgYW5kIGV4ZWN1dGUgdGhlICJyZXBsYWNlRGF0YShvZmZzZXQsY291bnQsYXJnKSIgbWV0aG9kLgorICogICAgVGhpcyBjYXVzZXMgYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgRE9NRXhjZXB0aW9uIHRvIGJlIHRocm93bi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRTVDQkE3RkIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU1Q0JBN0ZCPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC1FNUNCQTdGQicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELUU1Q0JBN0ZCJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU1Q0JBN0ZCIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1FNUNCQTdGQjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBnZW5kZXJMaXN0OworICAgICAgTm9kZSBnZW5kZXJOb2RlOworICAgICAgTm9kZSBlbnRFbGVtZW50OworICAgICAgTm9kZSBlbnRFbGVtZW50Q29udGVudDsKKyAgICAgIE5vZGUgZW50UmVmZXJlbmNlOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZ2VuZGVyTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZ2VuZGVyIik7CisgICAgICBnZW5kZXJOb2RlID0gZ2VuZGVyTGlzdC5pdGVtKDIpOworICAgICAgZW50UmVmZXJlbmNlID0gZ2VuZGVyTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRSZWZlcmVuY2VOb3ROdWxsIiwgZW50UmVmZXJlbmNlKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgZW50UmVmZXJlbmNlLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoMSwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgZW50UmVmZXJlbmNlID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWZlcmVuY2UpOworICAgICAgfQorICAgIGVudEVsZW1lbnQgPSBlbnRSZWZlcmVuY2UuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50RWxlbWVudE5vdE51bGwiLCBlbnRFbGVtZW50KTsKKyAgICAgIGVudEVsZW1lbnRDb250ZW50ID0gZW50RWxlbWVudC5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRFbGVtZW50Q29udGVudE5vdE51bGwiLCBlbnRFbGVtZW50Q29udGVudCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICgoQ2hhcmFjdGVyRGF0YSkgLypOb2RlICovZW50RWxlbWVudENvbnRlbnQpLnJlcGxhY2VEYXRhKDEsIDMsICJuZXdBcmciKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMGQ3ZWZkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQ3JlYXRlIGFuIGVudDMgZW50aXR5IHJlZmVyZW5jZSBhbmQgY2FsbCByZXBsYWNlRGF0YSBvbiBhIHRleHQgY2hpbGQsIHNob3VsZCB0aHJvd24gYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIuIAorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1FNUNCQTdGQiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRTVDQkE3RkI8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELUU1Q0JBN0ZCJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtRTVDQkE3RkInKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRTVDQkE3RkIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU1Q0JBN0ZCPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLnhtbCI+aHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIueG1sPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBnZW5kZXJMaXN0OworICAgICAgTm9kZSBnZW5kZXJOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBlbnRUZXh0OworICAgICAgRW50aXR5UmVmZXJlbmNlIGVudFJlZmVyZW5jZTsKKyAgICAgIE5vZGUgYXBwZW5kZWROb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZ2VuZGVyTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZ2VuZGVyIik7CisgICAgICBnZW5kZXJOb2RlID0gZ2VuZGVyTGlzdC5pdGVtKDIpOworICAgICAgZW50UmVmZXJlbmNlID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50MyIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWZlcmVuY2UpOworICAgICAgYXBwZW5kZWROb2RlID0gZ2VuZGVyTm9kZS5hcHBlbmRDaGlsZChlbnRSZWZlcmVuY2UpOworICAgICAgZW50VGV4dCA9IChDaGFyYWN0ZXJEYXRhKSBlbnRSZWZlcmVuY2UuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50VGV4dE5vdE51bGwiLCBlbnRUZXh0KTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgZW50VGV4dC5yZXBsYWNlRGF0YSgxLCAzLCAibmV3QXJnIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhc2V0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhc2V0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNlNzg5OGMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFzZXRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmphdmEKQEAgLTAsMCArMSwxMTQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXREYXRhKGRhdGEpIiBtZXRob2QgcmFpc2VzIGEgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIAorICogICAgRE9NRXhjZXB0aW9uIGlmIHRoZSBub2RlIGlzIHJlYWRvbmx5LgorICogICAgT2J0YWluIHRoZSBjaGlsZHJlbiBvZiB0aGUgVEhJUkQgImdlbmRlciIgZWxlbWVudC4gIFRoZSBlbGVtZW50cworICogICAgY29udGVudCBpcyBhbiBlbnRpdHkgcmVmZXJlbmNlLiAgR2V0IHRoZSBGSVJTVCBpdGVtIAorICogICAgZnJvbSB0aGUgZW50aXR5IHJlZmVyZW5jZSBhbmQgZXhlY3V0ZSB0aGUgInNldERhdGEoZGF0YSkiIG1ldGhvZC4KKyAqICAgIFRoaXMgY2F1c2VzIGEgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIERPTUV4Y2VwdGlvbiB0byBiZSB0aHJvd24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNzJBQjgzNTknKS9zZXRyYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC03MkFCODM1OScpL3NldHJhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNoYXJhY3RlcmRhdGFzZXRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjaGFyYWN0ZXJkYXRhc2V0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVycihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGdlbmRlckxpc3Q7CisgICAgICBOb2RlIGdlbmRlck5vZGU7CisgICAgICBOb2RlIGVudEVsZW1lbnQ7CisgICAgICBOb2RlIGVudEVsZW1lbnRDb250ZW50OworICAgICAgTm9kZSBlbnRSZWZlcmVuY2U7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBnZW5kZXJMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJnZW5kZXIiKTsKKyAgICAgIGdlbmRlck5vZGUgPSBnZW5kZXJMaXN0Lml0ZW0oMik7CisgICAgICBlbnRSZWZlcmVuY2UgPSBnZW5kZXJOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudFJlZmVyZW5jZU5vdE51bGwiLCBlbnRSZWZlcmVuY2UpOworICAgICAgbm9kZVR5cGUgPSAoaW50KSBlbnRSZWZlcmVuY2UuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygxLCBub2RlVHlwZSkpIHsKKyAgICAgICAgICBlbnRSZWZlcmVuY2UgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQ0Iik7CisgICAgICBhc3NlcnROb3ROdWxsKCJjcmVhdGVkRW50UmVmTm90TnVsbCIsIGVudFJlZmVyZW5jZSk7CisgICAgICB9CisgICAgZW50RWxlbWVudCA9IGVudFJlZmVyZW5jZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRFbGVtZW50Tm90TnVsbCIsIGVudEVsZW1lbnQpOworICAgICAgZW50RWxlbWVudENvbnRlbnQgPSBlbnRFbGVtZW50LmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudEVsZW1lbnRDb250ZW50Tm90TnVsbCIsIGVudEVsZW1lbnRDb250ZW50KTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgKChDaGFyYWN0ZXJEYXRhKSAvKk5vZGUgKi9lbnRFbGVtZW50Q29udGVudCkuc2V0RGF0YSgibmV3RGF0YSIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFzZXRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjaGFyYWN0ZXJkYXRhc2V0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXNldGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhc2V0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmRiNjNhOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXNldGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBDcmVhdGUgYW4gZW50MyBlbnRpdHkgcmVmZXJlbmNlIGFuZCBjYWxsIHNldERhdGEgb24gYSB0ZXh0IGNoaWxkLCBzaG91bGQgdGhyb3duIGEgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLiAKKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC03MkFCODM1OScpL3NldHJhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTcyQUI4MzU5Jykvc2V0cmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFzZXRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLnhtbCI+aHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhc2V0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWw8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNoYXJhY3RlcmRhdGFzZXRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFzZXRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBnZW5kZXJMaXN0OworICAgICAgTm9kZSBnZW5kZXJOb2RlOworICAgICAgTm9kZSBlbnRUZXh0OworICAgICAgRW50aXR5UmVmZXJlbmNlIGVudFJlZmVyZW5jZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGdlbmRlckxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImdlbmRlciIpOworICAgICAgZ2VuZGVyTm9kZSA9IGdlbmRlckxpc3QuaXRlbSg0KTsKKyAgICAgIGVudFJlZmVyZW5jZSA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDMiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZW50UmVmZXJlbmNlKTsKKyAgICAgIGVudFRleHQgPSBlbnRSZWZlcmVuY2UuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50VGV4dE5vdE51bGwiLCBlbnRUZXh0KTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgKChDaGFyYWN0ZXJEYXRhKSAvKk5vZGUgKi9lbnRUZXh0KS5zZXREYXRhKCJuZXdEYXRhIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXNldGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2hhcmFjdGVyZGF0YXNldGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXNldG5vZGV2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhc2V0bm9kZXZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmI1ZGZlYgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXNldG5vZGV2YWx1ZS5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICBUaGUgInNldE5vZGVWYWx1ZSgpIiBtZXRob2QgY2hhbmdlcyB0aGUgY2hhcmFjdGVyIGRhdGEgCisgKiAgIGN1cnJlbnRseSBzdG9yZWQgaW4gdGhlIG5vZGUuCisgKiAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBmcm9tIHRoZSBzZWNvbmQgY2hpbGQgCisgKiAgIG9mIHRoZSBmaXJzdCBlbXBsb3llZSBhbmQgaW52b2tlIHRoZSAic2V0Tm9kZVZhbHVlKCkiIAorICogICBtZXRob2QsIGNhbGwgImdldERhdGEoKSIgYW5kIGNvbXBhcmUuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNoYXJhY3RlcmRhdGFzZXRub2RldmFsdWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNoYXJhY3RlcmRhdGFzZXRub2RldmFsdWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkRGF0YTsKKyAgICAgIFN0cmluZyBjaGlsZFZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIm5hbWUiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkLnNldE5vZGVWYWx1ZSgiTWFyaWx5biBNYXJ0aW4iKTsKKyAgICAgIGNoaWxkRGF0YSA9IGNoaWxkLmdldERhdGEoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZGF0YSIsICJNYXJpbHluIE1hcnRpbiIsIGNoaWxkRGF0YSk7CisgICAgICBjaGlsZFZhbHVlID0gY2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlIiwgIk1hcmlseW4gTWFydGluIiwgY2hpbGRWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFzZXRub2RldmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNoYXJhY3RlcmRhdGFzZXRub2RldmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFzdWJzdHJpbmdleGNlZWRzdmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXN1YnN0cmluZ2V4Y2VlZHN2YWx1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdlZTBiOGYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFzdWJzdHJpbmdleGNlZWRzdmFsdWUuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBJZiB0aGUgc3VtIG9mIHRoZSAib2Zmc2V0IiBhbmQgImNvdW50IiBleGNlZWRzIHRoZQorICogICAgImxlbmd0aCIgdGhlbiB0aGUgInN1YnN0cmluZ0RhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kCisgKiAgICByZXR1cm5zIGFsbCB0aGUgY2hhcmFjdGVycyB0byB0aGUgZW5kIG9mIHRoZSBkYXRhLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIHNlY29uZCBjaGlsZCAKKyAqICAgIG9mIHRoZSBmaXJzdCBlbXBsb3llZSBhbmQgYWNjZXNzIHBhcnQgb2YgdGhlIGRhdGEgCisgKiAgICBieSB1c2luZyB0aGUgc3Vic3RyaW5nRGF0YShvZmZzZXQsY291bnQpIG1ldGhvZAorICogICAgd2l0aCBvZmZzZXQ9OSBhbmQgY291bnQ9MTAuICBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gCisgKiAgICB0aGUgc3Vic3RyaW5nICJNYXJ0aW4iIHNpbmNlIG9mZnNldCtjb3VudCA+IGxlbmd0aAorICogICAgKDE5ID4gMTUpLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjUzMUJDQ0YiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTY1MzFCQ0NGPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjaGFyYWN0ZXJkYXRhc3Vic3RyaW5nZXhjZWVkc3ZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjaGFyYWN0ZXJkYXRhc3Vic3RyaW5nZXhjZWVkc3ZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgc3Vic3RyaW5nOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJuYW1lIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBzdWJzdHJpbmcgPSBjaGlsZC5zdWJzdHJpbmdEYXRhKDksIDEwKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2hhcmFjdGVyZGF0YVN1YlN0cmluZ0V4Y2VlZHNWYWx1ZUFzc2VydCIsICJNYXJ0aW4iLCBzdWJzdHJpbmcpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhc3Vic3RyaW5nZXhjZWVkc3ZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjaGFyYWN0ZXJkYXRhc3Vic3RyaW5nZXhjZWVkc3ZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jaGFyYWN0ZXJkYXRhc3Vic3RyaW5ndmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXN1YnN0cmluZ3ZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDZlNzEyYwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvY2hhcmFjdGVyZGF0YXN1YnN0cmluZ3ZhbHVlLmphdmEKQEAgLTAsMCArMSw5MyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzdWJzdHJpbmdEYXRhKG9mZnNldCxjb3VudCkiIG1ldGhvZCByZXR1cm5zIHRoZSAKKyAqICAgIHNwZWNpZmllZCBzdHJpbmcuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBmcm9tIHRoZSBzZWNvbmQgY2hpbGQgCisgKiAgICBvZiB0aGUgZmlyc3QgZW1wbG95ZWUgYW5kIGFjY2VzcyBwYXJ0IG9mIHRoZSBkYXRhIAorICogICAgYnkgdXNpbmcgdGhlIHN1YnN0cmluZ0RhdGEob2Zmc2V0LGNvdW50KSBtZXRob2QuICBUaGUKKyAqICAgIG1ldGhvZCBzaG91bGQgcmV0dXJuIHRoZSBzcGVjaWZpZWQgc3Vic3RyaW5nIHN0YXJ0aW5nIAorICogICAgYXQgcG9zaXRpb24gIm9mZnNldCIgYW5kIGV4dHJhY3QgImNvdW50IiBjaGFyYWN0ZXJzLgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIHRoZSBzdHJpbmcgIk1hcmdhcmV0Ii4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTY1MzFCQ0NGIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NTMxQkNDRjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY2hhcmFjdGVyZGF0YXN1YnN0cmluZ3ZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjaGFyYWN0ZXJkYXRhc3Vic3RyaW5ndmFsdWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBzdWJzdHJpbmc7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIm5hbWUiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIHN1YnN0cmluZyA9IGNoaWxkLnN1YnN0cmluZ0RhdGEoMCwgOCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlcmRhdGFTdWJTdHJpbmdWYWx1ZUFzc2VydCIsICJNYXJnYXJldCIsIHN1YnN0cmluZyk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2NoYXJhY3RlcmRhdGFzdWJzdHJpbmd2YWx1ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY2hhcmFjdGVyZGF0YXN1YnN0cmluZ3ZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jb21tZW50Z2V0Y29tbWVudC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9jb21tZW50Z2V0Y29tbWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY2ZWIyMTIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2NvbW1lbnRnZXRjb21tZW50LmphdmEKQEAgLTAsMCArMSwxMDIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIEEgY29tbWVudCBpcyBhbGwgdGhlIGNoYXJhY3RlcnMgYmV0d2VlbiB0aGUgc3RhcnRpbmcKKyAqICAgJzwhLS0nIGFuZCBlbmRpbmcgJy0tPicgCisgKiAgIFJldHJpZXZlIHRoZSBub2RlcyBvZiB0aGUgRE9NIGRvY3VtZW50LiAgU2VhcmNoIGZvciBhIAorICogICBjb21tZW50IG5vZGUgYW5kIHRoZSBjb250ZW50IGlzIGl0cyB2YWx1ZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEzMzQ0ODEzMjgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEzMzQ0ODEzMjg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIzNzU1OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjb21tZW50Z2V0Y29tbWVudCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY29tbWVudGdldGNvbW1lbnQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIFN0cmluZyBjaGlsZFZhbHVlOworICAgICAgaW50IGNvbW1lbnRDb3VudCA9IDA7CisgICAgICBpbnQgY2hpbGRUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDU3ID0gMDsgaW5kZXhOMTAwNTcgPCBlbGVtZW50TGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwNTcrKykgeworICAgICAgICAgIGNoaWxkID0gKE5vZGUpIGVsZW1lbnRMaXN0Lml0ZW0oaW5kZXhOMTAwNTcpOworICAgIGNoaWxkVHlwZSA9IChpbnQpIGNoaWxkLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoOCwgY2hpbGRUeXBlKSkgeworICAgICAgICAgIGNoaWxkTmFtZSA9IGNoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lIiwgIiNjb21tZW50IiwgY2hpbGROYW1lKTsKKyAgICAgIGNoaWxkVmFsdWUgPSBjaGlsZC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZVZhbHVlIiwgIiBUaGlzIGlzIGNvbW1lbnQgbnVtYmVyIDEuIiwgY2hpbGRWYWx1ZSk7CisgICAgICBjb21tZW50Q291bnQgPSBjb21tZW50Q291bnQgKyAxOworICAgICAgfQorICAgICAgfQorICAgICAgYXNzZXJ0RXF1YWxzKCJjb21tZW50Q291bnQiLCAxLCBjb21tZW50Q291bnQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9jb21tZW50Z2V0Y29tbWVudCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY29tbWVudGdldGNvbW1lbnQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlYXR0cmlidXRlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlYXR0cmlidXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWI3ZjUyOAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGUuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNyZWF0ZUF0dHJpYnV0ZShuYW1lKSIgbWV0aG9kIGNyZWF0ZXMgYW4gQXR0cmlidXRlIAorICogICAgbm9kZSBvZiB0aGUgZ2l2ZW4gbmFtZS4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGVudGlyZSBET00gZG9jdW1lbnQgYW5kIGludm9rZSBpdHMgCisgKiAgICAiY3JlYXRlQXR0cmlidXRlKG5hbWUpIiBtZXRob2QuICBJdCBzaG91bGQgY3JlYXRlIGEgIAorICogICAgbmV3IEF0dHJpYnV0ZSBub2RlIHdpdGggdGhlIGdpdmVuIG5hbWUuIFRoZSBuYW1lLCB2YWx1ZQorICogICAgYW5kIHR5cGUgb2YgdGhlIG5ld2x5IGNyZWF0ZWQgb2JqZWN0IGFyZSByZXRyaWV2ZWQgYW5kCisgKiAgICBvdXRwdXQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDg0ODkxMTk4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDg0ODkxMTk4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBBdHRyIG5ld0F0dHJOb2RlOworICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKyAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgIGludCBhdHRyVHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld0F0dHJOb2RlID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZSgiZGlzdHJpY3QiKTsKKyAgICAgIGF0dHJWYWx1ZSA9IG5ld0F0dHJOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZSIsICIiLCBhdHRyVmFsdWUpOworICAgICAgYXR0ck5hbWUgPSBuZXdBdHRyTm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lIiwgImRpc3RyaWN0IiwgYXR0ck5hbWUpOworICAgICAgYXR0clR5cGUgPSAoaW50KSBuZXdBdHRyTm9kZS5nZXROb2RlVHlwZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0eXBlIiwgMiwgYXR0clR5cGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlY2RhdGFzZWN0aW9uLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlY2RhdGFzZWN0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDEyMzQxZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGVjZGF0YXNlY3Rpb24uamF2YQpAQCAtMCwwICsxLDkzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY3JlYXRlQ0RBVEFTZWN0aW9uKGRhdGEpIiBtZXRob2QgY3JlYXRlcyBhIG5ldyAKKyAqICAgIENEQVRBU2VjdGlvbiBub2RlIHdob3NlIHZhbHVlIGlzIHRoZSBzcGVjaWZpZWQgc3RyaW5nLgorICogICAgUmV0cmlldmUgdGhlIGVudGlyZSBET00gZG9jdW1lbnQgYW5kIGludm9rZSBpdHMgCisgKiAgICAiY3JlYXRlQ0RBVEFTZWN0aW9uKGRhdGEpIiBtZXRob2QuICBJdCBzaG91bGQgY3JlYXRlIGEKKyAqICAgIG5ldyBDREFUQVNlY3Rpb24gbm9kZSB3aG9zZSAiZGF0YSIgaXMgdGhlIHNwZWNpZmllZCAKKyAqICAgIHN0cmluZy4gIFRoZSBjb250ZW50LCBuYW1lIGFuZCB0eXBlIGFyZSByZXRyaWV2ZWQgYW5kCisgKiAgICBvdXRwdXQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1EMjZDMEFGOCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRDI2QzBBRjg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50Y3JlYXRlY2RhdGFzZWN0aW9uIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGNyZWF0ZWNkYXRhc2VjdGlvbihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIENEQVRBU2VjdGlvbiBuZXdDREFUQVNlY3Rpb25Ob2RlOworICAgICAgU3RyaW5nIG5ld0NEQVRBU2VjdGlvblZhbHVlOworICAgICAgU3RyaW5nIG5ld0NEQVRBU2VjdGlvbk5hbWU7CisgICAgICBpbnQgbmV3Q0RBVEFTZWN0aW9uVHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld0NEQVRBU2VjdGlvbk5vZGUgPSBkb2MuY3JlYXRlQ0RBVEFTZWN0aW9uKCJUaGlzIGlzIGEgbmV3IENEQVRBU2VjdGlvbiBub2RlIik7CisgICAgICBuZXdDREFUQVNlY3Rpb25WYWx1ZSA9IG5ld0NEQVRBU2VjdGlvbk5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVWYWx1ZSIsICJUaGlzIGlzIGEgbmV3IENEQVRBU2VjdGlvbiBub2RlIiwgbmV3Q0RBVEFTZWN0aW9uVmFsdWUpOworICAgICAgbmV3Q0RBVEFTZWN0aW9uTmFtZSA9IG5ld0NEQVRBU2VjdGlvbk5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZU5hbWUiLCAiI2NkYXRhLXNlY3Rpb24iLCBuZXdDREFUQVNlY3Rpb25OYW1lKTsKKyAgICAgIG5ld0NEQVRBU2VjdGlvblR5cGUgPSAoaW50KSBuZXdDREFUQVNlY3Rpb25Ob2RlLmdldE5vZGVUeXBlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVUeXBlIiwgNCwgbmV3Q0RBVEFTZWN0aW9uVHlwZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlY2RhdGFzZWN0aW9uIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGNyZWF0ZWNkYXRhc2VjdGlvbi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGVjb21tZW50LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlY29tbWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkxNTgzOTAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlY29tbWVudC5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY3JlYXRlQ29tbWVudChkYXRhKSIgbWV0aG9kIGNyZWF0ZXMgYSBuZXcgQ29tbWVudAorICogICAgbm9kZSBnaXZlbiB0aGUgc3BlY2lmaWVkIHN0cmluZy4gCisgKiAgICBSZXRyaWV2ZSB0aGUgZW50aXJlIERPTSBkb2N1bWVudCBhbmQgaW52b2tlIGl0cyAKKyAqICAgICJjcmVhdGVDb21tZW50KGRhdGEpIiBtZXRob2QuICBJdCBzaG91bGQgY3JlYXRlIGEgbmV3CisgKiAgICBDb21tZW50IG5vZGUgd2hvc2UgImRhdGEiIGlzIHRoZSBzcGVjaWZpZWQgc3RyaW5nLgorICogICAgVGhlIGNvbnRlbnQsIG5hbWUgYW5kIHR5cGUgYXJlIHJldHJpZXZlZCBhbmQgb3V0cHV0LgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTMzNDQ4MTMyOCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTMzNDQ4MTMyODwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRjcmVhdGVjb21tZW50IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGNyZWF0ZWNvbW1lbnQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBDb21tZW50IG5ld0NvbW1lbnROb2RlOworICAgICAgU3RyaW5nIG5ld0NvbW1lbnRWYWx1ZTsKKyAgICAgIFN0cmluZyBuZXdDb21tZW50TmFtZTsKKyAgICAgIGludCBuZXdDb21tZW50VHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld0NvbW1lbnROb2RlID0gZG9jLmNyZWF0ZUNvbW1lbnQoIlRoaXMgaXMgYSBuZXcgQ29tbWVudCBub2RlIik7CisgICAgICBuZXdDb21tZW50VmFsdWUgPSBuZXdDb21tZW50Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygidmFsdWUiLCAiVGhpcyBpcyBhIG5ldyBDb21tZW50IG5vZGUiLCBuZXdDb21tZW50VmFsdWUpOworICAgICAgbmV3Q29tbWVudE5hbWUgPSBuZXdDb21tZW50Tm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lIiwgIiNjb21tZW50IiwgbmV3Q29tbWVudE5hbWUpOworICAgICAgbmV3Q29tbWVudFR5cGUgPSAoaW50KSBuZXdDb21tZW50Tm9kZS5nZXROb2RlVHlwZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0eXBlIiwgOCwgbmV3Q29tbWVudFR5cGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZWNvbW1lbnQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Y3JlYXRlY29tbWVudC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGVkb2N1bWVudGZyYWdtZW50LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlZG9jdW1lbnRmcmFnbWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI5NDJhYmIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlZG9jdW1lbnRmcmFnbWVudC5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpIiBtZXRob2QgY3JlYXRlcyBhbiBlbXB0eSAKKyAqICAgIERvY3VtZW50RnJhZ21lbnQgb2JqZWN0LgorICogICAgUmV0cmlldmUgdGhlIGVudGlyZSBET00gZG9jdW1lbnQgYW5kIGludm9rZSBpdHMgCisgKiAgICAiY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpIiBtZXRob2QuICBUaGUgY29udGVudCwgbmFtZSwgCisgKiAgICB0eXBlIGFuZCB2YWx1ZSBvZiB0aGUgbmV3bHkgY3JlYXRlZCBvYmplY3QgYXJlIG91dHB1dC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM1Q0IwNEI1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zNUNCMDRCNTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRjcmVhdGVkb2N1bWVudGZyYWdtZW50IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGNyZWF0ZWRvY3VtZW50ZnJhZ21lbnQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudEZyYWdtZW50IG5ld0RvY0ZyYWdtZW50OworICAgICAgTm9kZUxpc3QgY2hpbGRyZW47CisgICAgICBpbnQgbGVuZ3RoOworICAgICAgU3RyaW5nIG5ld0RvY0ZyYWdtZW50TmFtZTsKKyAgICAgIGludCBuZXdEb2NGcmFnbWVudFR5cGU7CisgICAgICBTdHJpbmcgbmV3RG9jRnJhZ21lbnRWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld0RvY0ZyYWdtZW50ID0gZG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKKyAgICAgIGNoaWxkcmVuID0gbmV3RG9jRnJhZ21lbnQuZ2V0Q2hpbGROb2RlcygpOworICAgICAgbGVuZ3RoID0gKGludCkgY2hpbGRyZW4uZ2V0TGVuZ3RoKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImxlbmd0aCIsIDAsIGxlbmd0aCk7CisgICAgICBuZXdEb2NGcmFnbWVudE5hbWUgPSBuZXdEb2NGcmFnbWVudC5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lIiwgIiNkb2N1bWVudC1mcmFnbWVudCIsIG5ld0RvY0ZyYWdtZW50TmFtZSk7CisgICAgICBuZXdEb2NGcmFnbWVudFR5cGUgPSAoaW50KSBuZXdEb2NGcmFnbWVudC5nZXROb2RlVHlwZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0eXBlIiwgMTEsIG5ld0RvY0ZyYWdtZW50VHlwZSk7CisgICAgICBuZXdEb2NGcmFnbWVudFZhbHVlID0gbmV3RG9jRnJhZ21lbnQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJ2YWx1ZSIsIG5ld0RvY0ZyYWdtZW50VmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZWRvY3VtZW50ZnJhZ21lbnQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Y3JlYXRlZG9jdW1lbnRmcmFnbWVudC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGVlbGVtZW50LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5YTMzOWIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudC5qYXZhCkBAIC0wLDAgKzEsOTMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY3JlYXRlRWxlbWVudCh0YWdOYW1lKSIgbWV0aG9kIGNyZWF0ZXMgYW4gRWxlbWVudCAKKyAqICAgIG9mIHRoZSB0eXBlIHNwZWNpZmllZC4KKyAqICAgIFJldHJpZXZlIHRoZSBlbnRpcmUgRE9NIGRvY3VtZW50IGFuZCBpbnZva2UgaXRzIAorICogICAgImNyZWF0ZUVsZW1lbnQodGFnTmFtZSkiIG1ldGhvZCB3aXRoIHRhZ05hbWU9ImFkZHJlc3MiLgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgY3JlYXRlIGFuIGluc3RhbmNlIG9mIGFuIEVsZW1lbnQgbm9kZQorICogICAgd2hvc2UgdGFnTmFtZSBpcyAiYWRkcmVzcyIuICBUaGUgTm9kZU5hbWUsIE5vZGVUeXBlIAorICogICAgYW5kIE5vZGVWYWx1ZSBhcmUgcmV0dXJuZWQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMTQxNzQxNTQ3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMTQxNzQxNTQ3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGNyZWF0ZWVsZW1lbnQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50Y3JlYXRlZWxlbWVudChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgbmV3RWxlbWVudDsKKyAgICAgIFN0cmluZyBuZXdFbGVtZW50TmFtZTsKKyAgICAgIGludCBuZXdFbGVtZW50VHlwZTsKKyAgICAgIFN0cmluZyBuZXdFbGVtZW50VmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdFbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnQoImFkZHJlc3MiKTsKKyAgICAgIG5ld0VsZW1lbnROYW1lID0gbmV3RWxlbWVudC5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lIiwgImFkZHJlc3MiLCBuZXdFbGVtZW50TmFtZSk7CisgICAgICBuZXdFbGVtZW50VHlwZSA9IChpbnQpIG5ld0VsZW1lbnQuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIGFzc2VydEVxdWFscygidHlwZSIsIDEsIG5ld0VsZW1lbnRUeXBlKTsKKyAgICAgIG5ld0VsZW1lbnRWYWx1ZSA9IG5ld0VsZW1lbnQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJ2YWx1ZUluaXRpYWxseU51bGwiLCBuZXdFbGVtZW50VmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZWVsZW1lbnQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Y3JlYXRlZWxlbWVudC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGVlbGVtZW50Y2FzZXNlbnNpdGl2ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZWVsZW1lbnRjYXNlc2Vuc2l0aXZlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTA4ZTQ1OAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGVlbGVtZW50Y2FzZXNlbnNpdGl2ZS5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSB0YWdOYW1lIHBhcmFtZXRlciBpbiB0aGUgImNyZWF0ZUVsZW1lbnQodGFnTmFtZSkiCisgKiAgICBtZXRob2QgaXMgY2FzZS1zZW5zaXRpdmUgZm9yIFhNTCBkb2N1bWVudHMuCisgKiAgICBSZXRyaWV2ZSB0aGUgZW50aXJlIERPTSBkb2N1bWVudCBhbmQgaW52b2tlIGl0cyAKKyAqICAgICJjcmVhdGVFbGVtZW50KHRhZ05hbWUpIiBtZXRob2QgdHdpY2UuICBPbmNlIGZvciB0YWdOYW1lCisgKiAgICBlcXVhbCB0byAiYWRkcmVzcyIgYW5kIG9uY2UgZm9yIHRhZ05hbWUgZXF1YWwgdG8gIkFERFJFU1MiCisgKiAgICBFYWNoIGNhbGwgc2hvdWxkIGNyZWF0ZSBhIGRpc3RpbmN0IEVsZW1lbnQgbm9kZS4gIFRoZQorICogICAgbmV3bHkgY3JlYXRlZCBFbGVtZW50cyBhcmUgdGhlbiBhc3NpZ25lZCBhdHRyaWJ1dGVzIAorICogICAgdGhhdCBhcmUgcmV0cmlldmVkLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjE0MTc0MTU0NyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjE0MTc0MTU0NzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRjcmVhdGVlbGVtZW50Y2FzZXNlbnNpdGl2ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRjcmVhdGVlbGVtZW50Y2FzZXNlbnNpdGl2ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgbmV3RWxlbWVudDE7CisgICAgICBFbGVtZW50IG5ld0VsZW1lbnQyOworICAgICAgU3RyaW5nIGF0dHJpYnV0ZTE7CisgICAgICBTdHJpbmcgYXR0cmlidXRlMjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld0VsZW1lbnQxID0gZG9jLmNyZWF0ZUVsZW1lbnQoIkFERFJFU1MiKTsKKyAgICAgIG5ld0VsZW1lbnQyID0gZG9jLmNyZWF0ZUVsZW1lbnQoImFkZHJlc3MiKTsKKyAgICAgIG5ld0VsZW1lbnQxLnNldEF0dHJpYnV0ZSgiZGlzdHJpY3QiLCAiRm9ydCBXb3J0aCIpOworICAgICAgbmV3RWxlbWVudDIuc2V0QXR0cmlidXRlKCJjb3VudHkiLCAiRGFsbGFzIik7CisgICAgICBhdHRyaWJ1dGUxID0gbmV3RWxlbWVudDEuZ2V0QXR0cmlidXRlKCJkaXN0cmljdCIpOworICAgICAgYXR0cmlidXRlMiA9IG5ld0VsZW1lbnQyLmdldEF0dHJpYnV0ZSgiY291bnR5Iik7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJpYjEiLCAiRm9ydCBXb3J0aCIsIGF0dHJpYnV0ZTEpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyaWIyIiwgIkRhbGxhcyIsIGF0dHJpYnV0ZTIpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZWVsZW1lbnRjYXNlc2Vuc2l0aXZlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGNyZWF0ZWVsZW1lbnRjYXNlc2Vuc2l0aXZlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZWVsZW1lbnRkZWZhdWx0YXR0ci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZWVsZW1lbnRkZWZhdWx0YXR0ci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdkN2E5N2EKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudGRlZmF1bHRhdHRyLmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJjcmVhdGVFbGVtZW50KHRhZ05hbWUpIiBtZXRob2QgY3JlYXRlcyBhbiBFbGVtZW50IAorICogICAgb2YgdGhlIHR5cGUgc3BlY2lmaWVkLiAgSW4gYWRkaXRpb24sIGlmIHRoZXJlIGFyZSBrbm93biBhdHRyaWJ1dGVzCisgKiAgICB3aXRoIGRlZmF1bHQgdmFsdWVzLCBBdHRyIG5vZGVzIHJlcHJlc2VudGluZyB0aGVtIGFyZSBhdXRvbWF0aWNhbGx5CisgKiAgICBjcmVhdGVkIGFuZCBhdHRhY2hlZCB0byB0aGUgZWxlbWVudC4KKyAqICAgIFJldHJpZXZlIHRoZSBlbnRpcmUgRE9NIGRvY3VtZW50IGFuZCBpbnZva2UgaXRzIAorICogICAgImNyZWF0ZUVsZW1lbnQodGFnTmFtZSkiIG1ldGhvZCB3aXRoIHRhZ05hbWU9ImFkZHJlc3MiLgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgY3JlYXRlIGFuIGluc3RhbmNlIG9mIGFuIEVsZW1lbnQgbm9kZQorICogICAgd2hvc2UgdGFnTmFtZSBpcyAiYWRkcmVzcyIuICBUaGUgdGFnTmFtZSAiYWRkcmVzcyIgaGFzIGFuIAorICogICAgYXR0cmlidXRlIHdpdGggZGVmYXVsdCB2YWx1ZXMsIHRoZXJlZm9yZSB0aGUgbmV3bHkgY3JlYXRlZCBlbGVtZW50CisgKiAgICB3aWxsIGhhdmUgdGhlbS4gIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjE0MTc0MTU0NyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjE0MTc0MTU0NzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDJNYXIvMDAwMi5odG1sIj5odHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDJNYXIvMDAwMi5odG1sPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGNyZWF0ZWVsZW1lbnRkZWZhdWx0YXR0ciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRjcmVhdGVlbGVtZW50ZGVmYXVsdGF0dHIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcudmFsaWRhdGluZworICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgbmV3RWxlbWVudDsKKyAgICAgIE5hbWVkTm9kZU1hcCBkZWZhdWx0QXR0cjsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgbmFtZTsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld0VsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudCgiYWRkcmVzcyIpOworICAgICAgZGVmYXVsdEF0dHIgPSBuZXdFbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGNoaWxkID0gZGVmYXVsdEF0dHIuaXRlbSgwKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImRlZmF1bHRBdHRyTm90TnVsbCIsIGNoaWxkKTsKKyAgICAgIG5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyTmFtZSIsICJzdHJlZXQiLCBuYW1lKTsKKyAgICAgIHZhbHVlID0gY2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJWYWx1ZSIsICJZZXMiLCB2YWx1ZSk7CisgICAgICBhc3NlcnRTaXplKCJhdHRyQ291bnQiLCAxLCBkZWZhdWx0QXR0cik7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudGRlZmF1bHRhdHRyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGNyZWF0ZWVsZW1lbnRkZWZhdWx0YXR0ci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGVlbnRpdHlyZWZlcmVuY2UuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGVlbnRpdHlyZWZlcmVuY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjcyNmFmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZWVudGl0eXJlZmVyZW5jZS5qYXZhCkBAIC0wLDAgKzEsOTcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJjcmVhdGVFbnRpdHlSZWZlcmVuY2UobmFtZSkiIG1ldGhvZCBjcmVhdGVzIGFuIAorICogICAgRW50aXR5UmVmZXJyZW5jZSBub2RlLgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgZW50aXJlIERPTSBkb2N1bWVudCBhbmQgaW52b2tlIGl0cyAKKyAqICAgICJjcmVhdGVFbnRpdHlSZWZlcmVuY2UobmFtZSkiIG1ldGhvZC4gIEl0IHNob3VsZCBjcmVhdGUgCisgKiAgICBhIG5ldyBFbnRpdHlSZWZlcmVuY2Ugbm9kZSBmb3IgdGhlIEVudGl0eSB3aXRoIHRoZSAKKyAqICAgIGdpdmVuIG5hbWUuICBUaGUgbmFtZSwgdmFsdWUgYW5kIHR5cGUgYXJlIHJldHJpZXZlZCBhbmQKKyAqICAgIG91dHB1dC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzkyQjc1QUUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM5MkI3NUFFPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODA8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50Y3JlYXRlZW50aXR5cmVmZXJlbmNlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGNyZWF0ZWVudGl0eXJlZmVyZW5jZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVudGl0eVJlZmVyZW5jZSBuZXdFbnRSZWZOb2RlOworICAgICAgU3RyaW5nIGVudFJlZlZhbHVlOworICAgICAgU3RyaW5nIGVudFJlZk5hbWU7CisgICAgICBpbnQgZW50UmVmVHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld0VudFJlZk5vZGUgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQxIik7CisgICAgICBhc3NlcnROb3ROdWxsKCJjcmVhdGVkRW50UmVmTm90TnVsbCIsIG5ld0VudFJlZk5vZGUpOworICAgICAgZW50UmVmVmFsdWUgPSBuZXdFbnRSZWZOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgidmFsdWUiLCBlbnRSZWZWYWx1ZSk7CisgICAgICBlbnRSZWZOYW1lID0gbmV3RW50UmVmTm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lIiwgImVudDEiLCBlbnRSZWZOYW1lKTsKKyAgICAgIGVudFJlZlR5cGUgPSAoaW50KSBuZXdFbnRSZWZOb2RlLmdldE5vZGVUeXBlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInR5cGUiLCA1LCBlbnRSZWZUeXBlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGVlbnRpdHlyZWZlcmVuY2UiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Y3JlYXRlZW50aXR5cmVmZXJlbmNlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZWVudGl0eXJlZmVyZW5jZWtub3duLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRlZW50aXR5cmVmZXJlbmNla25vd24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMmYxNjdlCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZWVudGl0eXJlZmVyZW5jZWtub3duLmphdmEKQEAgLTAsMCArMSwxMDAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJjcmVhdGVFbnRpdHlSZWZlcmVuY2UobmFtZSkiIG1ldGhvZCBjcmVhdGVzIGFuIAorICogICAgRW50aXR5UmVmZXJlbmNlIG5vZGUuICBJbiBhZGRpdGlvbiwgaWYgdGhlIHJlZmVyZW5jZWQgZW50aXR5CisgKiAgICBpcyBrbm93biwgdGhlIGNoaWxkIGxpc3Qgb2YgdGhlICJFbnRpdHlSZWZlcmVuY2UiIG5vZGUKKyAqICAgIGlzIHRoZSBzYW1lIGFzIHRoZSBjb3JyZXNwb25kaW5nICJFbnRpdHkiIG5vZGUuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBlbnRpcmUgRE9NIGRvY3VtZW50IGFuZCBpbnZva2UgaXRzIAorICogICAgImNyZWF0ZUVudGl0eVJlZmVyZW5jZShuYW1lKSIgbWV0aG9kLiAgSXQgc2hvdWxkIGNyZWF0ZSAKKyAqICAgIGEgbmV3IEVudGl0eVJlZmVyZW5jZSBub2RlIGZvciB0aGUgRW50aXR5IHdpdGggdGhlIAorICogICAgZ2l2ZW4gbmFtZS4gIFRoZSByZWZlcmVuY2VkIGVudGl0eSBpcyBrbm93biwgdGhlcmVmb3JlIHRoZSBjaGlsZAorICogICAgbGlzdCBvZiB0aGUgIkVudGl0eVJlZmVyZW5jZSIgbm9kZSBpcyB0aGUgc2FtZSBhcyB0aGUgY29ycmVzcG9uZGluZworICogICAgIkVudGl0eSIgbm9kZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM5MkI3NUFFIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zOTJCNzVBRTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRjcmVhdGVlbnRpdHlyZWZlcmVuY2Vrbm93biBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRjcmVhdGVlbnRpdHlyZWZlcmVuY2Vrbm93bihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVudGl0eVJlZmVyZW5jZSBuZXdFbnRSZWZOb2RlOworICAgICAgTm9kZUxpc3QgbmV3RW50UmVmTGlzdDsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgbmFtZTsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld0VudFJlZk5vZGUgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQzIik7CisgICAgICBhc3NlcnROb3ROdWxsKCJjcmVhdGVkRW50UmVmTm90TnVsbCIsIG5ld0VudFJlZk5vZGUpOworICAgICAgbmV3RW50UmVmTGlzdCA9IG5ld0VudFJlZk5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgYXNzZXJ0U2l6ZSgic2l6ZSIsIDEsIG5ld0VudFJlZkxpc3QpOworICAgICAgY2hpbGQgPSBuZXdFbnRSZWZOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIG5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lIiwgIiN0ZXh0IiwgbmFtZSk7CisgICAgICB2YWx1ZSA9IGNoaWxkLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZSIsICJUZXhhcyIsIHZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGVlbnRpdHlyZWZlcmVuY2Vrbm93biI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRjcmVhdGVlbnRpdHlyZWZlcmVuY2Vrbm93bi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb24uamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZDFkN2I5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZXByb2Nlc3NpbmdpbnN0cnVjdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCxkYXRhKSIgbWV0aG9kIAorICogICAgY3JlYXRlcyBhIG5ldyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gbm9kZSB3aXRoIHRoZQorICogICAgc3BlY2lmaWVkIG5hbWUgYW5kIGRhdGEgc3RyaW5nLgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgZW50aXJlIERPTSBkb2N1bWVudCBhbmQgaW52b2tlIGl0cyAKKyAqICAgICJjcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LGRhdGEpIiBtZXRob2QuICAKKyAqICAgIEl0IHNob3VsZCBjcmVhdGUgYSBuZXcgUEkgbm9kZSB3aXRoIHRoZSBzcGVjaWZpZWQgdGFyZ2V0IAorICogICAgYW5kIGRhdGEuICBUaGUgdGFyZ2V0LCBkYXRhIGFuZCB0eXBlIGFyZSByZXRyaWV2ZWQgYW5kCisgKiAgICBvdXRwdXQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlIyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9saXN0cy53My5vcmcvQXJjaGl2ZXMvUHVibGljL3d3dy1kb20tdHMvMjAwMUFwci8wMDIwLmh0bWwiPmh0dHA6Ly9saXN0cy53My5vcmcvQXJjaGl2ZXMvUHVibGljL3d3dy1kb20tdHMvMjAwMUFwci8wMDIwLmh0bWw8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTM1OTQ0NDM5Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMzU5NDQ0Mzk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRjcmVhdGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb24gZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50Y3JlYXRlcHJvY2Vzc2luZ2luc3RydWN0aW9uKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uIG5ld1BJTm9kZTsKKyAgICAgIFN0cmluZyBwaVZhbHVlOworICAgICAgU3RyaW5nIHBpTmFtZTsKKyAgICAgIGludCBwaVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdQSU5vZGUgPSBkb2MuY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKCJURVNUUEkiLCAiVGhpcyBpcyBhIG5ldyBQSSBub2RlIik7CisgICAgICBhc3NlcnROb3ROdWxsKCJjcmVhdGVkUElOb3ROdWxsIiwgbmV3UElOb2RlKTsKKyAgICAgIHBpTmFtZSA9IG5ld1BJTm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lIiwgIlRFU1RQSSIsIHBpTmFtZSk7CisgICAgICBwaVZhbHVlID0gbmV3UElOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZSIsICJUaGlzIGlzIGEgbmV3IFBJIG5vZGUiLCBwaVZhbHVlKTsKKyAgICAgIHBpVHlwZSA9IChpbnQpIG5ld1BJTm9kZS5nZXROb2RlVHlwZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0eXBlIiwgNywgcGlUeXBlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9jdW1lbnRjcmVhdGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb24iOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Y3JlYXRlcHJvY2Vzc2luZ2luc3RydWN0aW9uLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZXRleHRub2RlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Y3JlYXRldGV4dG5vZGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNWQ5YTZiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZXRleHRub2RlLmphdmEKQEAgLTAsMCArMSw5MiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJjcmVhdGVUZXh0Tm9kZShkYXRhKSIgbWV0aG9kIGNyZWF0ZXMgYSBUZXh0IG5vZGUgCisgKiAgICBnaXZlbiB0aGUgc3BlY2ZpZWQgc3RyaW5nLgorICogICAgUmV0cmlldmUgdGhlIGVudGlyZSBET00gZG9jdW1lbnQgYW5kIGludm9rZSBpdHMgCisgKiAgICAiY3JlYXRlVGV4dE5vZGUoZGF0YSkiIG1ldGhvZC4gIEl0IHNob3VsZCBjcmVhdGUgYSAKKyAqICAgIG5ldyBUZXh0IG5vZGUgd2hvc2UgImRhdGEiIGlzIHRoZSBzcGVjaWZpZWQgc3RyaW5nLgorICogICAgVGhlIE5vZGVOYW1lIGFuZCBOb2RlVHlwZSBhcmUgYWxzbyBjaGVja2VkLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTk3NTM0ODEyNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTk3NTM0ODEyNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRjcmVhdGV0ZXh0bm9kZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRjcmVhdGV0ZXh0bm9kZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIFRleHQgbmV3VGV4dE5vZGU7CisgICAgICBTdHJpbmcgbmV3VGV4dE5hbWU7CisgICAgICBTdHJpbmcgbmV3VGV4dFZhbHVlOworICAgICAgaW50IG5ld1RleHRUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgbmV3VGV4dE5vZGUgPSBkb2MuY3JlYXRlVGV4dE5vZGUoIlRoaXMgaXMgYSBuZXcgVGV4dCBub2RlIik7CisgICAgICBuZXdUZXh0VmFsdWUgPSBuZXdUZXh0Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygidmFsdWUiLCAiVGhpcyBpcyBhIG5ldyBUZXh0IG5vZGUiLCBuZXdUZXh0VmFsdWUpOworICAgICAgbmV3VGV4dE5hbWUgPSBuZXdUZXh0Tm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lIiwgIiN0ZXh0IiwgbmV3VGV4dE5hbWUpOworICAgICAgbmV3VGV4dFR5cGUgPSAoaW50KSBuZXdUZXh0Tm9kZS5nZXROb2RlVHlwZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0eXBlIiwgMywgbmV3VGV4dFR5cGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGNyZWF0ZXRleHRub2RlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGNyZWF0ZXRleHRub2RlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGdldGRvY3R5cGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRnZXRkb2N0eXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDBlMjM3NgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRnZXRkb2N0eXBlLmphdmEKQEAgLTAsMCArMSw5OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldERvY3R5cGUoKSIgbWV0aG9kIHJldHVybnMgdGhlIERvY3VtZW50IAorICogICAgVHlwZSBEZWNsYXJhdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhpcyBkb2N1bWVudC4KKyAqICAgIFJldHJpZXZlIHRoZSBlbnRpcmUgRE9NIGRvY3VtZW50IGFuZCBpbnZva2UgaXRzIAorICogICAgImdldERvY3R5cGUoKSIgbWV0aG9kLiAgVGhlIG5hbWUgb2YgdGhlIGRvY3VtZW50CisgKiAgICB0eXBlIHNob3VsZCBiZSByZXR1cm5lZC4gIFRoZSAiZ2V0TmFtZSgpIiBtZXRob2QKKyAqICAgIHNob3VsZCBiZSBlcXVhbCB0byAic3RhZmYiIG9yICJzdmciLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtQjYzRUQxQTMxIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1CNjNFRDFBMzE8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGdldGRvY3R5cGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50Z2V0ZG9jdHlwZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIFN0cmluZyBkb2NUeXBlTmFtZTsKKyAgICAgIFN0cmluZyBub2RlVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgZG9jVHlwZU5hbWUgPSBkb2NUeXBlLmdldE5hbWUoKTsKKyAgICAgIAorICAgICAgaWYgKCgiaW1hZ2Uvc3ZnK3htbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkgeworICAgICAgICAgIGFzc2VydEVxdWFscygiZG9jdHlwZU5hbWVTVkciLCAic3ZnIiwgZG9jVHlwZU5hbWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3R5cGVOYW1lIiwgInN0YWZmIiwgZG9jVHlwZU5hbWUpOworICAgICAgfQorICAgICAgICAKKyAgICBub2RlVmFsdWUgPSBkb2NUeXBlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgiaW5pdGlhbGx5TnVsbCIsIG5vZGVWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0ZG9jdHlwZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRnZXRkb2N0eXBlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGdldGRvY3R5cGVub2R0ZC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGdldGRvY3R5cGVub2R0ZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU1NGE3OGUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0ZG9jdHlwZW5vZHRkLmphdmEKQEAgLTAsMCArMSw4OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXREb2N0eXBlKCkiIG1ldGhvZCByZXR1cm5zIG51bGwgZm9yIFhNTCBkb2N1bWVudHMKKyAqICAgIHdpdGhvdXQgYSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uLgorICogICAgUmV0cmlldmUgdGhlIFhNTCBkb2N1bWVudCB3aXRob3V0IGEgRFREIGFuZCBpbnZva2UgdGhlIAorICogICAgImdldERvY3R5cGUoKSIgbWV0aG9kLiAgSXQgc2hvdWxkIHJldHVybiBudWxsLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUI2M0VEMUEzMSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtQjYzRUQxQTMxPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGdldGRvY3R5cGVub2R0ZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRnZXRkb2N0eXBlbm9kdGQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubm90VmFsaWRhdGluZworICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfbm9kdGRzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19ub2R0ZHN0YWZmIiwgZmFsc2UpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBhc3NlcnROdWxsKCJkb2N1bWVudEdldERvY1R5cGVOb0RUREFzc2VydCIsIGRvY1R5cGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGdldGRvY3R5cGVub2R0ZCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRnZXRkb2N0eXBlbm9kdGQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVsZW5ndGguamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZWxlbmd0aC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwNmEyZmYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVsZW5ndGguamF2YQpAQCAtMCwwICsxLDg1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEVsZW1lbnRzQnlUYWdOYW1lKHRhZ05hbWUpIiBtZXRob2QgcmV0dXJucyBhIAorICogICAgTm9kZUxpc3Qgb2YgYWxsIHRoZSBFbGVtZW50cyB3aXRoIGEgZ2l2ZW4gdGFnTmFtZS4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGVudGlyZSBET00gZG9jdW1lbnQgYW5kIGludm9rZSBpdHMgCisgKiAgICAiZ2V0RWxlbWVudHNCeVRhZ05hbWUodGFnTmFtZSkiIG1ldGhvZCB3aXRoIHRhZ05hbWUKKyAqICAgIGVxdWFsIHRvICJuYW1lIi4gIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiBhIE5vZGVMaXN0IAorICogICAgdGhhdCBjb250YWlucyA1IGVsZW1lbnRzLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtQTZDOTA5NCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtQTZDOTA5NDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZWxlbmd0aCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZWxlbmd0aChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBuYW1lTGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBuYW1lTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgibmFtZSIpOworICAgICAgYXNzZXJ0U2l6ZSgiZG9jdW1lbnRHZXRFbGVtZW50c0J5VGFnTmFtZUxlbmd0aEFzc2VydCIsIDUsIG5hbWVMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZWxlbmd0aCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZWxlbmd0aC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZXRvdGFsbGVuZ3RoLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV0b3RhbGxlbmd0aC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVjYjAyOWQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV0b3RhbGxlbmd0aC5qYXZhCkBAIC0wLDAgKzEsODYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICBSZXRyaWV2ZSB0aGUgZW50aXJlIERPTSBkb2N1bWVudCwgaW52b2tlCisgKiAgICBnZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpIGFuZCBjaGVjayB0aGUgbGVuZ3RoIG9mIHRoZSBOb2RlTGlzdC4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1BNkM5MDk0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1BNkM5MDk0PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1ldG90YWxsZW5ndGggZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV0b3RhbGxlbmd0aChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBuYW1lTGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBuYW1lTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpOworICAgICAgCisgICAgICBpZiAoKCJpbWFnZS9zdmcreG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKSB7CisgICAgICAgICAgYXNzZXJ0U2l6ZSgiZWxlbWVudENvdW50U1ZHIiwgMzksIG5hbWVMaXN0KTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0U2l6ZSgiZG9jdW1lbnRHZXRFbGVtZW50c0J5VGFnTmFtZVRvdGFsTGVuZ3RoQXNzZXJ0IiwgMzcsIG5hbWVMaXN0KTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1ldG90YWxsZW5ndGgiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV0b3RhbGxlbmd0aC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZXZhbHVlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV2YWx1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA1ZDE1NGYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV2YWx1ZS5qYXZhCkBAIC0wLDAgKzEsOTMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0RWxlbWVudHNCeVRhZ05hbWUodGFnTmFtZSkiIG1ldGhvZCByZXR1cm5zIGEgCisgKiAgICBOb2RlTGlzdCBvZiBhbGwgdGhlIEVsZW1lbnRzIHdpdGggYSBnaXZlbiB0YWdOYW1lCisgKiAgICBpbiBhIHByZS1vcmRlciB0cmF2ZXJzYWwgb2YgdGhlIHRyZWUuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBlbnRpcmUgRE9NIGRvY3VtZW50IGFuZCBpbnZva2UgaXRzIAorICogICAgImdldEVsZW1lbnRzQnlUYWdOYW1lKHRhZ05hbWUpIiBtZXRob2Qgd2l0aCB0YWdOYW1lCisgKiAgICBlcXVhbCB0byAibmFtZSIuICBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gYSBOb2RlTGlzdCAKKyAqICAgIHRoYXQgY29udGFpbnMgNSBlbGVtZW50cy4gIFRoZSBGT1VSVEggaXRlbSBpbiB0aGUKKyAqICAgIGxpc3QgaXMgcmV0cmlldmVkIGFuZCBvdXRwdXQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1BNkM5MDk0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1BNkM5MDk0PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1ldmFsdWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBuYW1lTGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBOb2RlIGZpcnN0Q2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGRWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBuYW1lTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgibmFtZSIpOworICAgICAgbmFtZU5vZGUgPSBuYW1lTGlzdC5pdGVtKDMpOworICAgICAgZmlyc3RDaGlsZCA9IG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkVmFsdWUgPSBmaXJzdENoaWxkLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudEdldEVsZW1lbnRzQnlUYWdOYW1lVmFsdWVBc3NlcnQiLCAiSmVueSBPY29ubm9yIiwgY2hpbGRWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV2YWx1ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZXZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGdldGltcGxlbWVudGF0aW9uLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0aW1wbGVtZW50YXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZGE3YzMwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGdldGltcGxlbWVudGF0aW9uLmphdmEKQEAgLTAsMCArMSw4NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRJbXBsZW1lbnRhdGlvbigpIiBtZXRob2QgcmV0dXJucyB0aGUgCisgKiAgICBET01JbXBsZW1lbnRhdGlvbiBvYmplY3QgdGhhdCBoYW5kbGVzIHRoaXMgZG9jdW1lbnQuIAorICogICAgUmV0cmlldmUgdGhlIGVudGlyZSBET00gZG9jdW1lbnQgYW5kIGludm9rZSBpdHMgCisgKiAgICAiZ2V0SW1wbGVtZW50YXRpb24oKSIgbWV0aG9kLiAgSXQgc2hvdWxkIHJldHVybiBhIAorICogICAgRE9NSW1wbGVtZW50YXRpb24gd2hvc2UgImhhc0ZlYXR1cmUoIlhNTCIsIjEuMCIpCisgKiAgICBtZXRob2QgcmV0dXJucyB0aGUgYm9vbGVhbiB2YWx1ZSAidHJ1ZSIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xQjc5M0VCQSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMUI3OTNFQkE8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50Z2V0aW1wbGVtZW50YXRpb24gZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50Z2V0aW1wbGVtZW50YXRpb24oZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9jSW1wbDsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZG9jSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgc3RhdGUgPSBkb2NJbXBsLmhhc0ZlYXR1cmUoIlhNTCIsICIxLjAiKTsKK2Fzc2VydFRydWUoImRvY3VtZW50R2V0SW1wbGVtZW50YXRpb25Bc3NlcnQiLCBzdGF0ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0aW1wbGVtZW50YXRpb24iOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Z2V0aW1wbGVtZW50YXRpb24uY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0cm9vdG5vZGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRnZXRyb290bm9kZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwNzExZWQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50Z2V0cm9vdG5vZGUuamF2YQpAQCAtMCwwICsxLDkyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldERvY3VtZW50RWxlbWVudCgpIiBtZXRob2QgcHJvdmlkZXMgZGlyZWN0IGFjY2VzcyAKKyAqICAgIHRvIHRoZSBjaGlsZCBub2RlIHRoYXQgaXMgdGhlIHJvb3QgZWxlbWVudCBvZiB0aGUgZG9jdW1lbnQuCisgKiAgICBSZXRyaWV2ZSB0aGUgZW50aXJlIERPTSBkb2N1bWVudCBhbmQgaW52b2tlIGl0cyAKKyAqICAgICJnZXREb2N1bWVudEVsZW1lbnQoKSIgbWV0aG9kLiAgSXQgc2hvdWxkIHJldHVybiBhbgorICogICAgRWxlbWVudCBub2RlIHdob3NlIE5vZGVOYW1lIGlzICJzdGFmZiIgKG9yICJzdmciKS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg3Q0QwOTIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg3Q0QwOTI8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1MSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1MTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRnZXRyb290bm9kZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRnZXRyb290bm9kZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IHJvb3Q7CisgICAgICBTdHJpbmcgcm9vdE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgcm9vdCA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIHJvb3ROYW1lID0gcm9vdC5nZXROb2RlTmFtZSgpOworICAgICAgCisgICAgICBpZiAoKCJpbWFnZS9zdmcreG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdmdSb290Tm9kZSIsICJzdmciLCByb290TmFtZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRHZXRSb290Tm9kZUFzc2VydCIsICJzdGFmZiIsIHJvb3ROYW1lKTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGdldHJvb3Rub2RlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGdldHJvb3Rub2RlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVhdHRyaWJ1dGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlYXR0cmlidXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzhkOWYwYQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlYXR0cmlidXRlLmphdmEKQEAgLTAsMCArMSw5OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNyZWF0ZUF0dHJpYnV0ZSh0YWdOYW1lKSIgbWV0aG9kIHJhaXNlcyBhbgorICogICAgSU5WQUxJRF9DSEFSQUNURVJfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkCisgKiAgICB0YWdOYW1lIGNvbnRhaW5zIGFuIGludmFsaWQgY2hhcmFjdGVyLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGVudGlyZSBET00gZG9jdW1lbnQgYW5kIGludm9rZSBpdHMgCisgKiAgICAiY3JlYXRlQXR0cmlidXRlKHRhZ05hbWUpIiBtZXRob2Qgd2l0aCB0aGUgdGFnTmFtZSBlcXVhbAorICogICAgdG8gdGhlIHN0cmluZyAiaW52YWxpZF5OYW1lIi4gIER1ZSB0byB0aGUgaW52YWxpZCAKKyAqICAgIGNoYXJhY3RlciB0aGUgZGVzaXJlZCBFWENFUFRJT04gc2hvdWxkIGJlIHJhaXNlZC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA4NDg5MTE5OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA4NDg5MTE5ODwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMTA4NDg5MTE5OCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTEwODQ4OTExOTgnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA4NDg5MTE5OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA4NDg5MTE5ODwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVhdHRyaWJ1dGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWF0dHJpYnV0ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEF0dHIgY3JlYXRlZEF0dHI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNyZWF0ZWRBdHRyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZSgiaW52YWxpZF5OYW1lIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTlZBTElEX0NIQVJBQ1RFUl9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlYXR0cmlidXRlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVhdHRyaWJ1dGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWVsZW1lbnQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlZWxlbWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2NDU5ZWEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWVsZW1lbnQuamF2YQpAQCAtMCwwICsxLDk4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY3JlYXRlRWxlbWVudCh0YWdOYW1lKSIgbWV0aG9kIHJhaXNlcyBhbgorICogICAgSU5WQUxJRF9DSEFSQUNURVJfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkCisgKiAgICB0YWdOYW1lIGNvbnRhaW5zIGFuIGludmFsaWQgY2hhcmFjdGVyLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGVudGlyZSBET00gZG9jdW1lbnQgYW5kIGludm9rZSBpdHMgCisgKiAgICAiY3JlYXRlRWxlbWVudCh0YWdOYW1lKSIgbWV0aG9kIHdpdGggdGhlIHRhZ05hbWUgZXF1YWwKKyAqICAgIHRvIHRoZSBzdHJpbmcgImludmFsaWReTmFtZSIuICBEdWUgdG8gdGhlIGludmFsaWQgCisgKiAgICBjaGFyYWN0ZXIgdGhlIGRlc2lyZWQgRVhDRVBUSU9OIHNob3VsZCBiZSByYWlzZWQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIxNDE3NDE1NDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIxNDE3NDE1NDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTIxNDE3NDE1NDcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yMTQxNzQxNTQ3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIxNDE3NDE1NDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIxNDE3NDE1NDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlZWxlbWVudCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlZWxlbWVudChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgYmFkRWxlbWVudDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgYmFkRWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCJpbnZhbGlkXk5hbWUiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOVkFMSURfQ0hBUkFDVEVSX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbGVtZW50IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbGVtZW50LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbnRyZWYuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlZW50cmVmLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWViZmIzNQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlZW50cmVmLmphdmEKQEAgLTAsMCArMSwxMTAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJjcmVhdGVFbnRpdHlSZWZlcmVuY2UodGFnTmFtZSkiIG1ldGhvZCByYWlzZXMgYW4KKyAqICAgIElOVkFMSURfQ0hBUkFDVEVSX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZAorICogICAgdGFnTmFtZSBjb250YWlucyBhbiBpbnZhbGlkIGNoYXJhY3Rlci4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM5MkI3NUFFIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zOTJCNzVBRTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMzkyQjc1QUUnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0zOTJCNzVBRScpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbnRyZWYgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWVudHJlZihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKyAgICAgIGlmIChmYWN0b3J5Lmhhc0ZlYXR1cmUoIlhNTCIsIG51bGwpICE9IHRydWUpIHsKKyAgICAgICAgIHRocm93IG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbi5pbmNvbXBhdGlibGVGZWF0dXJlKCJYTUwiLCBudWxsKTsKKyAgICAgIH0KKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVudGl0eVJlZmVyZW5jZSBiYWRFbnRpdHlSZWY7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICAKKyAgICAgIGlmICgoInRleHQvaHRtbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkgeworICAgICAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgYmFkRW50aXR5UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZm9vIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9TVVBQT1JURURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9IGVsc2UgeworICAgICAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgYmFkRW50aXR5UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiaW52YWxpZF5OYW1lIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTlZBTElEX0NIQVJBQ1RFUl9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbnRyZWYiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWVudHJlZi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlZW50cmVmMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbnRyZWYxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzE4NTY4MAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlZW50cmVmMS5qYXZhCkBAIC0wLDAgKzEsMTA3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIENyZWF0aW5nIGFuIGVudGl0eSByZWZlcmVuY2Ugd2l0aCBhbiBlbXB0eSBuYW1lIHNob3VsZCBjYXVzZSBhbiBJTlZBTElEX0NIQVJBQ1RFUl9FUlIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM5MkI3NUFFIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zOTJCNzVBRTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMzkyQjc1QUUnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0zOTJCNzVBRScpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9NTI1Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9NTI1PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbnRyZWYxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbnRyZWYxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworICAgICAgaWYgKGZhY3RvcnkuaGFzRmVhdHVyZSgiWE1MIiwgbnVsbCkgIT0gdHJ1ZSkgeworICAgICAgICAgdGhyb3cgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uLmluY29tcGF0aWJsZUZlYXR1cmUoIlhNTCIsIG51bGwpOworICAgICAgfQorCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRW50aXR5UmVmZXJlbmNlIGJhZEVudGl0eVJlZjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIAorICAgICAgaWYgKCgidGV4dC9odG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKSB7CisgICAgICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiYWRFbnRpdHlSZWYgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJmb28iKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9UX1NVUFBPUlRFRF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30gZWxzZSB7CisgICAgICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiYWRFbnRpdHlSZWYgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCIiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOVkFMSURfQ0hBUkFDVEVSX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgICAgICAKKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWVudHJlZjEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWVudHJlZjEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZXBpLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZXBpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2E0ODk5NgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlcGkuamF2YQpAQCAtMCwwICsxLDExMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsZGF0YSkgbWV0aG9kIAorICogICAgcmFpc2VzIGFuIElOVkFMSURfQ0hBUkFDVEVSX0VSUiBET01FeGNlcHRpb24gaWYgdGhlCisgKiAgICBzcGVjaWZpZWQgdGFnTmFtZSBjb250YWlucyBhbiBpbnZhbGlkIGNoYXJhY3Rlci4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEzNTk0NDQzOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTM1OTQ0NDM5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0xMzU5NDQ0MzknKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0xMzU5NDQ0MzknKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlcGkgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZXBpKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworICAgICAgaWYgKGZhY3RvcnkuaGFzRmVhdHVyZSgiWE1MIiwgbnVsbCkgIT0gdHJ1ZSkgeworICAgICAgICAgdGhyb3cgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uLmluY29tcGF0aWJsZUZlYXR1cmUoIlhNTCIsIG51bGwpOworICAgICAgfQorCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uIGJhZFBJOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgCisgICAgICBpZiAoKCJ0ZXh0L2h0bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpIHsKKyAgICAgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJhZFBJID0gZG9jLmNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbigiZm9vIiwgImRhdGEiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9UX1NVUFBPUlRFRF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30gZWxzZSB7CisgICAgICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiYWRQSSA9IGRvYy5jcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oImludmFsaWReTmFtZSIsICJkYXRhIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTlZBTElEX0NIQVJBQ1RFUl9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVwaSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlcGkuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZXBpMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVwaTEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43Yjk3ODA3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVwaTEuamF2YQpAQCAtMCwwICsxLDEwNyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBDcmVhdGluZyBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gd2l0aCBhbiBlbXB0eSB0YXJnZXQgc2hvdWxkIGNhdXNlIGFuIElOVkFMSURfQ0hBUkFDVEVSX0VSUi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTM1OTQ0NDM5Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMzU5NDQ0Mzk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTEzNTk0NDQzOScpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTEzNTk0NDQzOScpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9NTI1Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9NTI1PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVwaTEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZXBpMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKyAgICAgIGlmIChmYWN0b3J5Lmhhc0ZlYXR1cmUoIlhNTCIsIG51bGwpICE9IHRydWUpIHsKKyAgICAgICAgIHRocm93IG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbi5pbmNvbXBhdGlibGVGZWF0dXJlKCJYTUwiLCBudWxsKTsKKyAgICAgIH0KKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBiYWRQSTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIAorICAgICAgaWYgKCgidGV4dC9odG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKSB7CisgICAgICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiYWRQSSA9IGRvYy5jcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oImZvbyIsICJkYXRhIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9TVVBQT1JURURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9IGVsc2UgeworICAgICAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgYmFkUEkgPSBkb2MuY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKCIiLCAiZGF0YSIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTlZBTElEX0NIQVJBQ1RFUl9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSU5WQUxJRF9DSEFSQUNURVJfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAgICAgIAorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlcGkxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVwaTEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50dHlwZWdldGRvY3R5cGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnR0eXBlZ2V0ZG9jdHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg4MWQyN2IKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50dHlwZWdldGRvY3R5cGUuamF2YQpAQCAtMCwwICsxLDkzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0TmFtZSgpIiBtZXRob2QgY29udGFpbnMgdGhlIG5hbWUgb2YgdGhlIERURC4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBEb2N1bWVudCBUeXBlIGZvciB0aGlzIGRvY3VtZW50IGFuZCBleGFtaW5lCisgKiAgICB0aGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAiZ2V0TmFtZSgpIiBtZXRob2QuCisgKiAgICBJdCBzaG91bGQgYmUgc2V0IHRvICJzdGFmZiIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1CNjNFRDFBMzEiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUI2M0VEMUEzMTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODQ0NzYzMTM0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODQ0NzYzMTM0PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudHR5cGVnZXRkb2N0eXBlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudHR5cGVnZXRkb2N0eXBlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgU3RyaW5nIG5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgbmFtZSA9IGRvY1R5cGUuZ2V0TmFtZSgpOworICAgICAgCisgICAgICBpZiAoKCJpbWFnZS9zdmcreG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N0eXBlTmFtZSIsICJzdmciLCBuYW1lKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudHR5cGVHZXREb2NUeXBlQXNzZXJ0IiwgInN0YWZmIiwgbmFtZSk7CisgICAgICB9CisgICAgICAgIAorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9jdW1lbnR0eXBlZ2V0ZG9jdHlwZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnR0eXBlZ2V0ZG9jdHlwZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnR0eXBlZ2V0ZW50aXRpZXMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnR0eXBlZ2V0ZW50aXRpZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMzRjNjZlCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudHR5cGVnZXRlbnRpdGllcy5qYXZhCkBAIC0wLDAgKzEsMTIwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0RW50aXRpZXMoKSIgbWV0aG9kIGlzIGEgTmFtZWROb2RlTWFwIHRoYXQgY29udGFpbnMKKyAqICAgIHRoZSBnZW5lcmFsIGVudGl0aWVzIGZvciB0aGlzIGRvY3VtZW50LiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIERvY3VtZW50IFR5cGUgZm9yIHRoaXMgZG9jdW1lbnQgYW5kIGNyZWF0ZSAKKyAqICAgIGEgTmFtZWROb2RlTWFwIG9mIGFsbCBpdHMgZW50aXRpZXMuICBUaGUgZW50aXJlIG1hcCBpcworICogICAgdHJhdmVyc2VkIGFuZCB0aGUgbmFtZXMgb2YgdGhlIGVudGl0aWVzIGFyZSByZXRyaWV2ZWQuCisgKiAgICBUaGVyZSBzaG91bGQgYmUgNSBlbnRpdGllcy4gIER1cGxpY2F0ZXMgc2hvdWxkIGJlIGlnbm9yZWQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzg4Nzk0NjMwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzg4Nzk0NjMwPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudHR5cGVnZXRlbnRpdGllcyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnR0eXBlZ2V0ZW50aXRpZXMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBOYW1lZE5vZGVNYXAgZW50aXR5TGlzdDsKKyAgICAgIFN0cmluZyBuYW1lOworICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb24gZXhwZWN0ZWRSZXN1bHQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJlbnQxIik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVudDIiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZW50MyIpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJlbnQ0Iik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVudDUiKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb24gZXhwZWN0ZWRSZXN1bHRTVkcgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgZXhwZWN0ZWRSZXN1bHRTVkcuYWRkKCJlbnQxIik7CisgICAgICBleHBlY3RlZFJlc3VsdFNWRy5hZGQoImVudDIiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0U1ZHLmFkZCgiZW50MyIpOworICAgICAgZXhwZWN0ZWRSZXN1bHRTVkcuYWRkKCJlbnQ0Iik7CisgICAgICBleHBlY3RlZFJlc3VsdFNWRy5hZGQoImVudDUiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0U1ZHLmFkZCgic3ZndW5pdCIpOworICAgICAgZXhwZWN0ZWRSZXN1bHRTVkcuYWRkKCJzdmd0ZXN0Iik7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9uIG5hbWVMaXN0ID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIAorICAgICAgTm9kZSBlbnRpdHk7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgZW50aXR5TGlzdCA9IGRvY1R5cGUuZ2V0RW50aXRpZXMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudGl0aWVzTm90TnVsbCIsIGVudGl0eUxpc3QpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwN0IgPSAwOyBpbmRleE4xMDA3QiA8IGVudGl0eUxpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDdCKyspIHsKKyAgICAgICAgICBlbnRpdHkgPSAoTm9kZSkgZW50aXR5TGlzdC5pdGVtKGluZGV4TjEwMDdCKTsKKyAgICBuYW1lID0gZW50aXR5LmdldE5vZGVOYW1lKCk7CisgICAgICBuYW1lTGlzdC5hZGQobmFtZSk7CisgICAgICAgIH0KKyAgICAgIAorICAgICAgaWYgKCgiaW1hZ2Uvc3ZnK3htbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkgeworICAgICAgICAgIGFzc2VydEVxdWFscygiZW50aXR5TmFtZXNTVkciLCBleHBlY3RlZFJlc3VsdFNWRywgbmFtZUxpc3QpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoImVudGl0eU5hbWVzIiwgZXhwZWN0ZWRSZXN1bHQsIG5hbWVMaXN0KTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb2N1bWVudHR5cGVnZXRlbnRpdGllcyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnR0eXBlZ2V0ZW50aXRpZXMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50dHlwZWdldGVudGl0aWVzbGVuZ3RoLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50dHlwZWdldGVudGl0aWVzbGVuZ3RoLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2E0NjUzNAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnR0eXBlZ2V0ZW50aXRpZXNsZW5ndGguamF2YQpAQCAtMCwwICsxLDkzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIER1cGxpY2F0ZSBlbnRpdGllcyBhcmUgdG8gYmUgZGlzY2FyZGVkLiAKKyAqICAgIFJldHJpZXZlIHRoZSBEb2N1bWVudCBUeXBlIGZvciB0aGlzIGRvY3VtZW50IGFuZCBjcmVhdGUgCisgKiAgICBhIE5hbWVkTm9kZU1hcCBvZiBhbGwgaXRzIGVudGl0aWVzLiAgVGhlIGVudGl0eSBuYW1lZCAKKyAqICAgICJlbnQxIiBpcyBkZWZpbmVkIHR3aWNlIGFuZCB0aGVyZWZvcmUgdGhhdCBsYXN0IAorICogICAgb2NjdXJyYW5jZSBzaG91bGQgYmUgZGlzY2FyZGVkLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTc4ODc5NDYzMCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTc4ODc5NDYzMDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnR0eXBlZ2V0ZW50aXRpZXNsZW5ndGggZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50dHlwZWdldGVudGl0aWVzbGVuZ3RoKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTmFtZWROb2RlTWFwIGVudGl0eUxpc3Q7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgZW50aXR5TGlzdCA9IGRvY1R5cGUuZ2V0RW50aXRpZXMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudGl0aWVzTm90TnVsbCIsIGVudGl0eUxpc3QpOworICAgICAgCisgICAgICBpZiAoKCJpbWFnZS9zdmcreG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKSB7CisgICAgICAgICAgYXNzZXJ0U2l6ZSgiZW50aXR5U2l6ZVNWRyIsIDcsIGVudGl0eUxpc3QpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBhc3NlcnRTaXplKCJlbnRpdHlTaXplIiwgNSwgZW50aXR5TGlzdCk7CisgICAgICB9CisgICAgICAgIAorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9jdW1lbnR0eXBlZ2V0ZW50aXRpZXNsZW5ndGgiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50dHlwZWdldGVudGl0aWVzbGVuZ3RoLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudHR5cGVnZXRlbnRpdGllc3R5cGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnR0eXBlZ2V0ZW50aXRpZXN0eXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzQ3Yzk5NAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnR0eXBlZ2V0ZW50aXRpZXN0eXBlLmphdmEKQEAgLTAsMCArMSw5NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBFdmVyeSBub2RlIGluIHRoZSBtYXAgcmV0dXJuZWQgYnkgdGhlICJnZXRFbnRpdGllcygpIgorICogICAgbWV0aG9kIGltcGxlbWVudHMgdGhlIEVudGl0eSBpbnRlcmZhY2UuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBEb2N1bWVudCBUeXBlIGZvciB0aGlzIGRvY3VtZW50IGFuZCBjcmVhdGUgCisgKiAgICBhIE5hbWVkTm9kZU1hcCBvZiBhbGwgaXRzIGVudGl0aWVzLiAgVHJhdmVyc2UgdGhlIAorICogICAgZW50aXJlIGxpc3QgYW5kIGV4YW1pbmUgdGhlIE5vZGVUeXBlIG9mIGVhY2ggbm9kZQorICogICAgaW4gdGhlIGxpc3QuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzg4Nzk0NjMwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzg4Nzk0NjMwPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudHR5cGVnZXRlbnRpdGllc3R5cGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50dHlwZWdldGVudGl0aWVzdHlwZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdHlMaXN0OworICAgICAgTm9kZSBlbnRpdHk7CisgICAgICBpbnQgZW50aXR5VHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImRvY1R5cGVOb3ROdWxsIiwgZG9jVHlwZSk7CisgICAgICBlbnRpdHlMaXN0ID0gZG9jVHlwZS5nZXRFbnRpdGllcygpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50aXRpZXNOb3ROdWxsIiwgZW50aXR5TGlzdCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA0OSA9IDA7IGluZGV4TjEwMDQ5IDwgZW50aXR5TGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwNDkrKykgeworICAgICAgICAgIGVudGl0eSA9IChOb2RlKSBlbnRpdHlMaXN0Lml0ZW0oaW5kZXhOMTAwNDkpOworICAgIGVudGl0eVR5cGUgPSAoaW50KSBlbnRpdHkuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnR0eXBlR2V0RW50aXRpZXNUeXBlQXNzZXJ0IiwgNiwgZW50aXR5VHlwZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9jdW1lbnR0eXBlZ2V0ZW50aXRpZXN0eXBlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudHR5cGVnZXRlbnRpdGllc3R5cGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50dHlwZWdldG5vdGF0aW9ucy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudHR5cGVnZXRub3RhdGlvbnMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NzlkNjU2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb2N1bWVudHR5cGVnZXRub3RhdGlvbnMuamF2YQpAQCAtMCwwICsxLDEwMiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldE5vdGF0aW9ucygpIiBtZXRob2QgY3JlYXRlcyBhIE5hbWVkTm9kZU1hcCB0aGF0ICAgCisgKiAgICBjb250YWlucyBhbGwgdGhlIG5vdGF0aW9ucyBkZWNsYXJlZCBpbiB0aGUgRFRELgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgRG9jdW1lbnQgVHlwZSBmb3IgdGhpcyBkb2N1bWVudCBhbmQgY3JlYXRlCisgKiAgICBhIE5hbWVkTm9kZU1hcCBvYmplY3Qgb2YgYWxsIHRoZSBub3RhdGlvbnMuICBUaGVyZQorICogICAgc2hvdWxkIGJlIHR3byBpdGVtcyBpbiB0aGUgbGlzdCAobm90YXRpb24xIGFuZCBub3RhdGlvbjIpLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENDY4MjlFRiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRDQ2ODI5RUY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50dHlwZWdldG5vdGF0aW9ucyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnR0eXBlZ2V0bm90YXRpb25zKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTmFtZWROb2RlTWFwIG5vdGF0aW9uTGlzdDsKKyAgICAgIE5vZGUgbm90YXRpb247CisgICAgICBTdHJpbmcgbm90YXRpb25OYW1lOworICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb24gYWN0dWFsID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb24gZXhwZWN0ZWQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgZXhwZWN0ZWQuYWRkKCJub3RhdGlvbjEiKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgibm90YXRpb24yIik7CisgICAgICAKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImRvY1R5cGVOb3ROdWxsIiwgZG9jVHlwZSk7CisgICAgICBub3RhdGlvbkxpc3QgPSBkb2NUeXBlLmdldE5vdGF0aW9ucygpOworICAgICAgYXNzZXJ0Tm90TnVsbCgibm90YXRpb25zTm90TnVsbCIsIG5vdGF0aW9uTGlzdCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA1QiA9IDA7IGluZGV4TjEwMDVCIDwgbm90YXRpb25MaXN0LmdldExlbmd0aCgpOyBpbmRleE4xMDA1QisrKSB7CisgICAgICAgICAgbm90YXRpb24gPSAoTm9kZSkgbm90YXRpb25MaXN0Lml0ZW0oaW5kZXhOMTAwNUIpOworICAgIG5vdGF0aW9uTmFtZSA9IG5vdGF0aW9uLmdldE5vZGVOYW1lKCk7CisgICAgICBhY3R1YWwuYWRkKG5vdGF0aW9uTmFtZSk7CisgICAgICAgIH0KKyAgICAgIGFzc2VydEVxdWFscygibmFtZXMiLCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZG9jdW1lbnR0eXBlZ2V0bm90YXRpb25zIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudHR5cGVnZXRub3RhdGlvbnMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50dHlwZWdldG5vdGF0aW9uc3R5cGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9jdW1lbnR0eXBlZ2V0bm90YXRpb25zdHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI1MWM4NGYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvY3VtZW50dHlwZWdldG5vdGF0aW9uc3R5cGUuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIEV2ZXJ5IG5vZGUgaW4gdGhlIG1hcCByZXR1cm5lZCBieSB0aGUgImdldE5vdGF0aW9ucygpIgorICogICAgbWV0aG9kIGltcGxlbWVudHMgdGhlIE5vdGF0aW9uIGludGVyZmFjZS4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIERvY3VtZW50IFR5cGUgZm9yIHRoaXMgZG9jdW1lbnQgYW5kIGNyZWF0ZQorICogICAgYSBOYW1lZE5vZGVNYXAgb2JqZWN0IG9mIGFsbCB0aGUgbm90YXRpb25zLiAgVHJhdmVyc2UKKyAqICAgIHRoZSBlbnRpcmUgbGlzdCBhbmQgZXhhbWluZSB0aGUgTm9kZVR5cGUgb2YgZWFjaCBub2RlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRDQ2ODI5RUYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ0NjgyOUVGPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudHR5cGVnZXRub3RhdGlvbnN0eXBlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudHR5cGVnZXRub3RhdGlvbnN0eXBlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTmFtZWROb2RlTWFwIG5vdGF0aW9uTGlzdDsKKyAgICAgIE5vZGUgbm90YXRpb247CisgICAgICBpbnQgbm90YXRpb25UeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZG9jVHlwZU5vdE51bGwiLCBkb2NUeXBlKTsKKyAgICAgIG5vdGF0aW9uTGlzdCA9IGRvY1R5cGUuZ2V0Tm90YXRpb25zKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJub3RhdGlvbnNOb3ROdWxsIiwgbm90YXRpb25MaXN0KTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDQ5ID0gMDsgaW5kZXhOMTAwNDkgPCBub3RhdGlvbkxpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDQ5KyspIHsKKyAgICAgICAgICBub3RhdGlvbiA9IChOb2RlKSBub3RhdGlvbkxpc3QuaXRlbShpbmRleE4xMDA0OSk7CisgICAgbm90YXRpb25UeXBlID0gKGludCkgbm90YXRpb24uZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnR0eXBlR2V0Tm90YXRpb25zVHlwZUFzc2VydCIsIDEyLCBub3RhdGlvblR5cGUpOworICAgICAgICB9CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2RvY3VtZW50dHlwZWdldG5vdGF0aW9uc3R5cGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50dHlwZWdldG5vdGF0aW9uc3R5cGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZW5vdmVyc2lvbi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVub3ZlcnNpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMzJiODk0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVub3ZlcnNpb24uamF2YQpAQCAtMCwwICsxLDgyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogaGFzRmVhdHVyZSgiWE1MIiwgIiIpIHNob3VsZCByZXR1cm4gdHJ1ZSBmb3IgaW1wbGVtZW50YXRpb25zIHRoYXQgY2FuIHJlYWQgc3RhZmYgZmlsZXMuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC01Q0VEOTRENyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNUNFRDk0RDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8xMS9ET00tTGV2ZWwtMi1lcnJhdGEjY29yZS0xNCI+aHR0cDovL3d3dy53My5vcmcvMjAwMC8xMS9ET00tTGV2ZWwtMi1lcnJhdGEjY29yZS0xNDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9taW1wbGVtZW50YXRpb25mZWF0dXJlbm92ZXJzaW9uIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVub3ZlcnNpb24oZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgc3RhdGUgPSBkb21JbXBsLmhhc0ZlYXR1cmUoIlhNTCIsICIiKTsKK2Fzc2VydFRydWUoImhhc1hNTEVtcHR5Iiwgc3RhdGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVub3ZlcnNpb24iOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvbWltcGxlbWVudGF0aW9uZmVhdHVyZW5vdmVyc2lvbi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9taW1wbGVtZW50YXRpb25mZWF0dXJlbnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVudWxsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODhlZDEzNgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9taW1wbGVtZW50YXRpb25mZWF0dXJlbnVsbC5qYXZhCkBAIC0wLDAgKzEsOTAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBoYXNGZWF0dXJlKCJYTUwiLCBudWxsKSBzaG91bGQgcmV0dXJuIHRydWUgZm9yIGltcGxlbWVudGF0aW9ucyB0aGF0IGNhbiByZWFkIHN0YWZmIGRvY3VtZW50cy4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC01Q0VEOTRENyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNUNFRDk0RDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8xMS9ET00tTGV2ZWwtMi1lcnJhdGEjY29yZS0xNCI+aHR0cDovL3d3dy53My5vcmcvMjAwMC8xMS9ET00tTGV2ZWwtMi1lcnJhdGEjY29yZS0xNDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9taW1wbGVtZW50YXRpb25mZWF0dXJlbnVsbCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9taW1wbGVtZW50YXRpb25mZWF0dXJlbnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5oYXNOdWxsU3RyaW5nCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgU3RyaW5nIG51bGxWZXJzaW9uID0gbnVsbDsKKworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgIHN0YXRlID0gZG9tSW1wbC5oYXNGZWF0dXJlKCJYTUwiLCBudWxsVmVyc2lvbik7Cithc3NlcnRUcnVlKCJoYXNYTUxudWxsIiwgc3RhdGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVudWxsIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVudWxsLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmV4bWwuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9taW1wbGVtZW50YXRpb25mZWF0dXJleG1sLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzFjZjYzMwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZG9taW1wbGVtZW50YXRpb25mZWF0dXJleG1sLmphdmEKQEAgLTAsMCArMSw4MSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIGhhc0ZlYXR1cmUoInhtbCIsICIxLjAiKSBzaG91bGQgcmV0dXJuIHRydWUgZm9yIGltcGxlbWVudGF0aW9ucyB0aGF0IGNhbiByZWFkIHN0YWZmIGRvY3VtZW50cy4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTVDRUQ5NEQ3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC01Q0VEOTRENzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9taW1wbGVtZW50YXRpb25mZWF0dXJleG1sIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb21pbXBsZW1lbnRhdGlvbmZlYXR1cmV4bWwoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgc3RhdGUgPSBkb21JbXBsLmhhc0ZlYXR1cmUoInhtbCIsICIxLjAiKTsKK2Fzc2VydFRydWUoImhhc1hNTDEiLCBzdGF0ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZXhtbCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9taW1wbGVtZW50YXRpb25mZWF0dXJleG1sLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50YWRkbmV3YXR0cmlidXRlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRhZGRuZXdhdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YmU0ODJiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50YWRkbmV3YXR0cmlidXRlLmphdmEKQEAgLTAsMCArMSw5MSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXRBdHRyaWJ1dGUobmFtZSx2YWx1ZSkiIG1ldGhvZCBhZGRzIGEgbmV3IGF0dHJpYnV0ZQorICogICAgdG8gdGhlIEVsZW1lbnQgCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSBsYXN0IGVtcGxveWVlLCB0aGVuIAorICogICAgYWRkIGFuIGF0dHJpYnV0ZSB0byBpdCBieSBpbnZva2luZyB0aGUgICAgICAgICAgICAgCisgKiAgICAic2V0QXR0cmlidXRlKG5hbWUsdmFsdWUpIiBtZXRob2QuICBJdCBzaG91bGQgY3JlYXRlCisgKiAgICBhICJuYW1lIiBhdHRyaWJ1dGUgd2l0aCBhbiBhc3NpZ25lZCB2YWx1ZSBlcXVhbCB0byAKKyAqICAgICJ2YWx1ZSIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50YWRkbmV3YXR0cmlidXRlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50YWRkbmV3YXR0cmlidXRlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RFbXBsb3llZTsKKyAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEVtcGxveWVlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oNCk7CisgICAgICB0ZXN0RW1wbG95ZWUuc2V0QXR0cmlidXRlKCJkaXN0cmljdCIsICJkYWxsYXMiKTsKKyAgICAgIGF0dHJWYWx1ZSA9IHRlc3RFbXBsb3llZS5nZXRBdHRyaWJ1dGUoImRpc3RyaWN0Iik7CisgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRBZGROZXdBdHRyaWJ1dGVBc3NlcnQiLCAiZGFsbGFzIiwgYXR0clZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudGFkZG5ld2F0dHJpYnV0ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudGFkZG5ld2F0dHJpYnV0ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudGFzc29jaWF0ZWRhdHRyaWJ1dGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudGFzc29jaWF0ZWRhdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNzE3ZTJhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50YXNzb2NpYXRlZGF0dHJpYnV0ZS5qYXZhCkBAIC0wLDAgKzEsOTQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgRWxlbWVudHMgbWF5IGhhdmUgYXR0cmlidXRlcyBhc3NvY2lhdGVkIHdpdGggdGhlbS4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGZpcnN0IGF0dHJpYnV0ZSBmcm9tIHRoZSBsYXN0IGNoaWxkIG9mCisgKiAgICB0aGUgZmlyc3QgZW1wbG95ZWUgYW5kIGludm9rZSB0aGUgImdldFNwZWNpZmllZCgpIiAKKyAqICAgIG1ldGhvZC4gIFRoaXMgdGVzdCBpcyBvbmx5IGludGVuZGVkIHRvIHNob3cgdGhhdCAgIAorICogICAgRWxlbWVudHMgY2FuIGFjdHVhbGx5IGhhdmUgYXR0cmlidXRlcy4gIFRoaXMgdGVzdCB1c2VzICAKKyAqICAgIHRoZSAiZ2V0TmFtZWRJdGVtKG5hbWUpIiBtZXRob2QgZnJvbSB0aGUgTmFtZWROb2RlTWFwCisgKiAgICBpbnRlcmZhY2UuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50YXNzb2NpYXRlZGF0dHJpYnV0ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudGFzc29jaWF0ZWRhdHRyaWJ1dGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RFbXBsb3llZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBkb21lc3RpY0F0dHI7CisgICAgICBib29sZWFuIHNwZWNpZmllZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEVtcGxveWVlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0RW1wbG95ZWUuZ2V0QXR0cmlidXRlcygpOworICAgICAgZG9tZXN0aWNBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJkb21lc3RpYyIpOworICAgICAgc3BlY2lmaWVkID0gZG9tZXN0aWNBdHRyLmdldFNwZWNpZmllZCgpOworICAgICAgYXNzZXJ0VHJ1ZSgiZG9tZXN0aWNTcGVjaWZpZWQiLCBzcGVjaWZpZWQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50YXNzb2NpYXRlZGF0dHJpYnV0ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudGFzc29jaWF0ZWRhdHRyaWJ1dGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRjaGFuZ2VhdHRyaWJ1dGV2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50Y2hhbmdlYXR0cmlidXRldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZDQ4NzcwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50Y2hhbmdlYXR0cmlidXRldmFsdWUuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldEF0dHJpYnV0ZShuYW1lLHZhbHVlKSIgbWV0aG9kIGFkZHMgYSBuZXcgYXR0cmlidXRlCisgKiAgICB0byB0aGUgRWxlbWVudC4gIElmIHRoZSAibmFtZSIgaXMgYWxyZWFkeSBwcmVzZW50LCB0aGVuCisgKiAgICBpdHMgdmFsdWUgc2hvdWxkIGJlIGNoYW5nZWQgdG8gdGhlIG5ldyBvbmUgdGhhdCBpcyBpbgorICogICAgdGhlICJ2YWx1ZSIgcGFyYW1ldGVyLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGxhc3QgY2hpbGQgb2YgdGhlIGZvdXJ0aCBlbXBsb3llZSwgdGhlbiBhZGQgCisgKiAgICBhbiBhdHRyaWJ1dGUgdG8gaXQgYnkgaW52b2tpbmcgdGhlIAorICogICAgInNldEF0dHJpYnV0ZShuYW1lLHZhbHVlKSIgbWV0aG9kLiAgU2luY2UgdGhlIG5hbWUgb2YgdGhlCisgKiAgICB1c2VkIGF0dHJpYnV0ZSgic3RyZWV0IikgaXMgYWxyZWFkeSBwcmVzZW50IGluIHRoaXMgICAgIAorICogICAgZWxlbWVudCwgdGhlbiBpdHMgdmFsdWUgc2hvdWxkIGJlIGNoYW5nZWQgdG8gdGhlIG5ldyBvbmUKKyAqICAgIG9mIHRoZSAidmFsdWUiIHBhcmFtZXRlci4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEYwODIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEYwODI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRjaGFuZ2VhdHRyaWJ1dGV2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudGNoYW5nZWF0dHJpYnV0ZXZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RFbXBsb3llZTsKKyAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEVtcGxveWVlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMyk7CisgICAgICB0ZXN0RW1wbG95ZWUuc2V0QXR0cmlidXRlKCJzdHJlZXQiLCAiTmVpdGhlciIpOworICAgICAgYXR0clZhbHVlID0gdGVzdEVtcGxveWVlLmdldEF0dHJpYnV0ZSgic3RyZWV0Iik7CisgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRDaGFuZ2VBdHRyaWJ1dGVWYWx1ZUFzc2VydCIsICJOZWl0aGVyIiwgYXR0clZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudGNoYW5nZWF0dHJpYnV0ZXZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50Y2hhbmdlYXR0cmlidXRldmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRjcmVhdGVuZXdhdHRyaWJ1dGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudGNyZWF0ZW5ld2F0dHJpYnV0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJjYjgzNjQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRjcmVhdGVuZXdhdHRyaWJ1dGUuamF2YQpAQCAtMCwwICsxLDk4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldEF0dHJpYnV0ZU5vZGUobmV3QXR0cikiIG1ldGhvZCBhZGRzIGEgbmV3IAorICogICAgYXR0cmlidXRlIHRvIHRoZSBFbGVtZW50LiAgCisgKiAgICAKKyAqICAgIFJldHJpZXZlIGZpcnN0IGFkZHJlc3MgZWxlbWVudCBhbmQgYWRkCisgKiAgICBhIG5ldyBhdHRyaWJ1dGUgbm9kZSB0byBpdCBieSBpbnZva2luZyBpdHMgICAgICAgICAKKyAqICAgICJzZXRBdHRyaWJ1dGVOb2RlKG5ld0F0dHIpIiBtZXRob2QuICBUaGlzIHRlc3QgbWFrZXMgdXNlCisgKiAgICBvZiB0aGUgImNyZWF0ZUF0dHJpYnV0ZShuYW1lKSIgbWV0aG9kIGZyb20gdGhlIERvY3VtZW50CisgKiAgICBpbnRlcmZhY2UuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04ODcyMzYxNTQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg4NzIzNjE1NDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudGNyZWF0ZW5ld2F0dHJpYnV0ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudGNyZWF0ZW5ld2F0dHJpYnV0ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcmVzczsKKyAgICAgIEF0dHIgbmV3QXR0cmlidXRlOworICAgICAgQXR0ciBvbGRBdHRyOworICAgICAgQXR0ciBkaXN0cmljdEF0dHI7CisgICAgICBTdHJpbmcgYXR0clZhbDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0QWRkcmVzcyA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgbmV3QXR0cmlidXRlID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZSgiZGlzdHJpY3QiKTsKKyAgICAgIG9sZEF0dHIgPSB0ZXN0QWRkcmVzcy5zZXRBdHRyaWJ1dGVOb2RlKG5ld0F0dHJpYnV0ZSk7CisgICAgICBhc3NlcnROdWxsKCJvbGRfYXR0cl9kb2VzbnRfZXhpc3QiLCBvbGRBdHRyKTsKKyAgICAgIGRpc3RyaWN0QXR0ciA9IHRlc3RBZGRyZXNzLmdldEF0dHJpYnV0ZU5vZGUoImRpc3RyaWN0Iik7CisgICAgICBhc3NlcnROb3ROdWxsKCJuZXdfZGlzdHJpY3RfYWNjZXNzaWJsZSIsIGRpc3RyaWN0QXR0cik7CisgICAgICBhdHRyVmFsID0gdGVzdEFkZHJlc3MuZ2V0QXR0cmlidXRlKCJkaXN0cmljdCIpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyX3ZhbHVlIiwgIiIsIGF0dHJWYWwpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50Y3JlYXRlbmV3YXR0cmlidXRlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50Y3JlYXRlbmV3YXR0cmlidXRlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50Z2V0YXR0cmlidXRlbm9kZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50Z2V0YXR0cmlidXRlbm9kZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI4YzlmMzAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlLmphdmEKQEAgLTAsMCArMSw5MSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRBdHRyaWJ1dGVOb2RlKG5hbWUpIiBtZXRob2QgcmV0cmlldmVzIGFuCisgKiAgICBhdHRyaWJ1dGUgbm9kZSBieSBuYW1lLgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgYXR0cmlidXRlICJkb21lc3RpYyIgZnJvbSB0aGUgbGFzdCBjaGlsZAorICogICAgb2YgdGhlIGZpcnN0IGVtcGxveWVlLiAgU2luY2UgdGhlIG1ldGhvZCByZXR1cm5zIGFuCisgKiAgICBBdHRyIG9iamVjdCwgdGhlICJuYW1lIiBjYW4gYmUgZXhhbWluZWQgdG8gZW5zdXJlIHRoZQorICogICAgcHJvcGVyIGF0dHJpYnV0ZSB3YXMgcmV0cmlldmVkLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjE3QTkxQjgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIxN0E5MUI4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50Z2V0YXR0cmlidXRlbm9kZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudGdldGF0dHJpYnV0ZW5vZGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEVtcGxveWVlOworICAgICAgQXR0ciBkb21lc3RpY0F0dHI7CisgICAgICBTdHJpbmcgbmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGRvbWVzdGljQXR0ciA9IHRlc3RFbXBsb3llZS5nZXRBdHRyaWJ1dGVOb2RlKCJkb21lc3RpYyIpOworICAgICAgbmFtZSA9IGRvbWVzdGljQXR0ci5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50R2V0QXR0cmlidXRlTm9kZUFzc2VydCIsICJkb21lc3RpYyIsIG5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50Z2V0YXR0cmlidXRlbm9kZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudGdldGF0dHJpYnV0ZW5vZGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50Z2V0YXR0cmlidXRlbm9kZW51bGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNTQ0OWY2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50Z2V0YXR0cmlidXRlbm9kZW51bGwuamF2YQpAQCAtMCwwICsxLDkwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEF0dHJpYnV0ZU5vZGUobmFtZSkiIG1ldGhvZCByZXRyaWV2ZXMgYW4KKyAqICAgIGF0dHJpYnV0ZSBub2RlIGJ5IG5hbWUuICBJdCBzaG91bGQgcmV0dXJuIG51bGwgaWYgdGhlCisgKiAgICAibmFtZSIgYXR0cmlidXRlIGRvZXMgbm90IGV4aXN0LgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgZmlyc3QgZW1wbG95ZWUgYW5kIGF0dGVtcHQKKyAqICAgIHRvIHJldHJpZXZlIGEgbm9uLWV4aXN0aW5nIGF0dHJpYnV0ZS4gIFRoZSBtZXRob2Qgc2hvdWxkCisgKiAgICByZXR1cm4gIm51bGwiLiAgVGhlIG5vbi1leGlzdGluZyBhdHRyaWJ1dGUgdG8gYmUgdXNlZAorICogICAgaXMgImludmFsaWRBdHRyaWJ1dGUiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjE3QTkxQjgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIxN0E5MUI4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50Z2V0YXR0cmlidXRlbm9kZW51bGwgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0RW1wbG95ZWU7CisgICAgICBBdHRyIGRvbWVzdGljQXR0cjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGRvbWVzdGljQXR0ciA9IHRlc3RFbXBsb3llZS5nZXRBdHRyaWJ1dGVOb2RlKCJpbnZhbGlkQXR0cmlidXRlIik7CisgICAgICBhc3NlcnROdWxsKCJlbGVtZW50R2V0QXR0cmlidXRlTm9kZU51bGxBc3NlcnQiLCBkb21lc3RpY0F0dHIpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50Z2V0YXR0cmlidXRlbm9kZW51bGwiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnVsbC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudGdldGVsZW1lbnRlbXB0eS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50Z2V0ZWxlbWVudGVtcHR5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzliYjkyNAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudGdldGVsZW1lbnRlbXB0eS5qYXZhCkBAIC0wLDAgKzEsOTcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0QXR0cmlidXRlKG5hbWUpIiBtZXRob2QgcmV0dXJucyBhbiBlbXB0eSAKKyAqICAgIHN0cmluZyBpZiBubyB2YWx1ZSB3YXMgYXNzaWduZWQgdG8gYW4gYXR0cmlidXRlIGFuZCAKKyAqICAgIG5vIGRlZmF1bHQgdmFsdWUgd2FzIGdpdmVuIGluIHRoZSBEVEQgZmlsZS4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGxhc3QgY2hpbGQgb2YgdGhlIGxhc3QgZW1wbG95ZWUsIHRoZW4KKyAqICAgIGludm9rZSAiZ2V0QXR0cmlidXRlKG5hbWUpIiBtZXRob2QsIHdoZXJlICJuYW1lIiBpcyBhbgorICogICAgYXR0cmlidXRlIHdpdGhvdXQgYSBzcGVjaWZpZWQgb3IgRFREIGRlZmF1bHQgdmFsdWUuIAorICogICAgVGhlICJnZXRBdHRyaWJ1dGUobmFtZSkiIG1ldGhvZCBzaG91bGQgcmV0dXJuIHRoZSBlbXB0eQorICogICAgc3RyaW5nLiAgVGhpcyBtZXRob2QgbWFrZXMgdXNlIG9mIHRoZQorICogICAgImNyZWF0ZUF0dHJpYnV0ZShuZXdBdHRyKSIgbWV0aG9kIGZyb20gdGhlIERvY3VtZW50CisgKiAgICBpbnRlcmZhY2UuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NjZFRTBGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjY2RUUwRjk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRnZXRlbGVtZW50ZW1wdHkgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRnZXRlbGVtZW50ZW1wdHkoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0RW1wbG95ZWU7CisgICAgICBBdHRyIGRvbWVzdGljQXR0cjsKKyAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdBdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJkaXN0cmljdCIpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3RFbXBsb3llZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDMpOworICAgICAgZG9tZXN0aWNBdHRyID0gdGVzdEVtcGxveWVlLnNldEF0dHJpYnV0ZU5vZGUobmV3QXR0cmlidXRlKTsKKyAgICAgIGF0dHJWYWx1ZSA9IHRlc3RFbXBsb3llZS5nZXRBdHRyaWJ1dGUoImRpc3RyaWN0Iik7CisgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRHZXRFbGVtZW50RW1wdHlBc3NlcnQiLCAiIiwgYXR0clZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudGdldGVsZW1lbnRlbXB0eSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudGdldGVsZW1lbnRlbXB0eS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFmOGJhZGEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZS5qYXZhCkBAIC0wLDAgKzEsODYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogVGhlICJnZXRFbGVtZW50c0J5VGFnTmFtZShuYW1lKSIgbWV0aG9kIHJldHVybnMgYSBsaXN0CisgKiBvZiBhbGwgZGVzY2VuZGFudCBFbGVtZW50cyB3aXRoIHRoZSBnaXZlbiB0YWcgbmFtZS4KKyAqIFRlc3QgZm9yIGFuIGVtcHR5IGxpc3QuCisgKiBDcmVhdGUgYSBOb2RlTGlzdCBvZiBhbGwgdGhlIGRlc2NlbmRhbnQgZWxlbWVudHMKKyAqIHVzaW5nIHRoZSBzdHJpbmcgIm5vTWF0Y2giIGFzIHRoZSB0YWdOYW1lLgorICogVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgTm9kZUxpc3Qgd2hvc2UgbGVuZ3RoIGlzCisgKiAiMCIgc2luY2UgdGhlcmUgYXJlIG5vdCBhbnkgZGVzY2VuZGFudCBlbGVtZW50cworICogdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gdGFnIG5hbWUuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xOTM4OTE4RCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTkzODkxOEQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgYXNzZXJ0U2l6ZSgiZWxlbWVudEdldEVsZW1lbnRzQnlUYWdOYW1lQXNzZXJ0IiwgNSwgZWxlbWVudExpc3QpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lYWNjZXNzbm9kZWxpc3QuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lYWNjZXNzbm9kZWxpc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NjcyMWIwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVhY2Nlc3Nub2RlbGlzdC5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBFbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpIHNob3VsZCByZXR1cm4gYSBOb2RlTGlzdCB3aG9zZSBsZW5ndGggaXMKKyAqICI1IiBpbiB0aGUgb3JkZXIgdGhlIGNoaWxkcmVuIHdlcmUgZW5jb3VudGVyZWQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xOTM4OTE4RCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTkzODkxOEQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZWFjY2Vzc25vZGVsaXN0IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVhY2Nlc3Nub2RlbGlzdChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEVtcGxveWVlOworICAgICAgTm9kZSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBTdHJpbmcgY2hpbGRWYWx1ZTsKKyAgICAgIGludCBjaGlsZFR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgzKTsKKyAgICAgIGNoaWxkID0gdGVzdEVtcGxveWVlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkVHlwZSA9IChpbnQpIGNoaWxkLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoMywgY2hpbGRUeXBlKSkgeworICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKTsKKyAgICAgIH0KKyAgICBjaGlsZE5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlbmFtZSIsICJlbXBsb3llZUlkIiwgY2hpbGROYW1lKTsKKyAgICAgIGNoaWxkID0gY2hpbGQuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgY2hpbGRWYWx1ZSA9IGNoaWxkLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJlbXAwMDA0IiwgIkVNUDAwMDQiLCBjaGlsZFZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lYWNjZXNzbm9kZWxpc3QiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZWFjY2Vzc25vZGVsaXN0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVub21hdGNoLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5vbWF0Y2guamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hODlkNGRjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVub21hdGNoLmphdmEKQEAgLTAsMCArMSw4NCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBUaGUgImdldEVsZW1lbnRzQnlUYWdOYW1lKG5hbWUpIiBtZXRob2QgcmV0dXJucyBhIGxpc3QKKyAqIG9mIGFsbCBkZXNjZW5kYW50IEVsZW1lbnRzIHdpdGggdGhlIGdpdmVuIHRhZyBuYW1lLgorICogQ3JlYXRlIGEgTm9kZUxpc3Qgb2YgYWxsIHRoZSBkZXNjZW5kYW50IGVsZW1lbnRzCisgKiB1c2luZyB0aGUgc3RyaW5nICJlbXBsb3llZSIgYXMgdGhlIHRhZ05hbWUuCisgKiBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gYSBOb2RlTGlzdCB3aG9zZSBsZW5ndGggaXMKKyAqICI1Ii4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE5Mzg5MThEIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xOTM4OTE4RDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbm9tYXRjaCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbm9tYXRjaChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgibm9NYXRjaCIpOworICAgICAgYXNzZXJ0U2l6ZSgiZWxlbWVudEdldEVsZW1lbnRzQnlUYWdOYW1lTm9NYXRjaE5vTWF0Y2hBc3NlcnQiLCAwLCBlbGVtZW50TGlzdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5vbWF0Y2giOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5vbWF0Y2guY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZXNwZWNpYWx2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVzcGVjaWFsdmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYTFiOTI3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVzcGVjaWFsdmFsdWUuamF2YQpAQCAtMCwwICsxLDEwNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIFRoZSAiZ2V0RWxlbWVudHNCeVRhZ05hbWUobmFtZSkiIG1ldGhvZCBtYXkgdXNlIHRoZQorICogc3BlY2lhbCB2YWx1ZSAiKiIgdG8gbWF0Y2ggYWxsIHRhZ3MgaW4gdGhlIGVsZW1lbnQKKyAqIHRyZWUuCisgKiBDcmVhdGUgYSBOb2RlTGlzdCBvZiBhbGwgdGhlIGRlc2NlbmRhbnQgZWxlbWVudHMKKyAqIG9mIHRoZSBsYXN0IGVtcGxveWVlIGJ5IHVzaW5nIHRoZSBzcGVjaWFsIHZhbHVlICIqIi4KKyAqIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiBhbGwgdGhlIGRlc2NlbmRhbnQgY2hpbGRyZW4oNikKKyAqIGluIHRoZSBvcmRlciB0aGUgY2hpbGRyZW4gd2VyZSBlbmNvdW50ZXJlZC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE5Mzg5MThEIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xOTM4OTE4RDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lc3BlY2lhbHZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVzcGVjaWFsdmFsdWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IGxhc3RFbXBsb3llZTsKKyAgICAgIE5vZGVMaXN0IGxhc3RlbXBMaXN0OworICAgICAgTm9kZSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBqYXZhLnV0aWwuTGlzdCByZXN1bHQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuTGlzdCBleHBlY3RlZFJlc3VsdCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcGxveWVlSWQiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgibmFtZSIpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJwb3NpdGlvbiIpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJzYWxhcnkiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZ2VuZGVyIik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImFkZHJlc3MiKTsKKyAgICAgIAorICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgbGFzdEVtcGxveWVlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oNCk7CisgICAgICBsYXN0ZW1wTGlzdCA9IGxhc3RFbXBsb3llZS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwNkEgPSAwOyBpbmRleE4xMDA2QSA8IGxhc3RlbXBMaXN0LmdldExlbmd0aCgpOyBpbmRleE4xMDA2QSsrKSB7CisgICAgICAgICAgY2hpbGQgPSAoTm9kZSkgbGFzdGVtcExpc3QuaXRlbShpbmRleE4xMDA2QSk7CisgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIHJlc3VsdC5hZGQoY2hpbGROYW1lKTsKKyAgICAgICAgfQorICAgICAgYXNzZXJ0RXF1YWxzKCJ0YWdOYW1lcyIsIGV4cGVjdGVkUmVzdWx0LCByZXN1bHQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVzcGVjaWFsdmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZXNwZWNpYWx2YWx1ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudGdldHRhZ25hbWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudGdldHRhZ25hbWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZmVmODdmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50Z2V0dGFnbmFtZS5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0VGFnTmFtZSgpIiBtZXRob2QgcmV0dXJucyB0aGUgCisgKiAgICB0YWdOYW1lIG9mIGFuIGVsZW1lbnQuICAgIAorICogICAgCisgKiAgICBJbnZva2UgdGhlICJnZXRUYWdOYW1lKCkiIG1ldGhvZCBvbmUgdGhlIAorICogICAgcm9vdCBub2RlLiBUaGUgdmFsdWUgcmV0dXJuZWQgc2hvdWxkIGJlICJzdGFmZiIuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA0NjgyODE1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDQ2ODI4MTU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1MSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1MTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudGdldHRhZ25hbWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRnZXR0YWduYW1lKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgcm9vdDsKKyAgICAgIFN0cmluZyB0YWduYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIHJvb3QgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICB0YWduYW1lID0gcm9vdC5nZXRUYWdOYW1lKCk7CisgICAgICAKKyAgICAgIGlmICgoImltYWdlL3N2Zyt4bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoInN2Z1RhZ05hbWUiLCAic3ZnIiwgdGFnbmFtZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICAgIGFzc2VydEVxdWFscygiZWxlbWVudEdldFRhZ05hbWVBc3NlcnQiLCAic3RhZmYiLCB0YWduYW1lKTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50Z2V0dGFnbmFtZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudGdldHRhZ25hbWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRpbnVzZWF0dHJpYnV0ZWVyci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50aW51c2VhdHRyaWJ1dGVlcnIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYTYwYzcwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50aW51c2VhdHRyaWJ1dGVlcnIuamF2YQpAQCAtMCwwICsxLDExMiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXRBdHRyaWJ1dGVOb2RlKG5ld0F0dHIpIiBtZXRob2QgcmFpc2VzIGFuIAorICogICAgIklOVVNFX0FUVFJJQlVURV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSAibmV3QXR0ciIgCisgKiAgICBpcyBhbHJlYWR5IGFuIGF0dHJpYnV0ZSBvZiBhbm90aGVyIGVsZW1lbnQuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGFwcGVuZAorICogICAgYSBuZXdseSBjcmVhdGVkIGVsZW1lbnQuICBUaGUgImNyZWF0ZUF0dHJpYnV0ZShuYW1lKSIKKyAqICAgIGFuZCAic2V0QXR0cmlidXRlTm9kZShuZXdBdHRyKSIgbWV0aG9kcyBhcmUgaW52b2tlZAorICogICAgdG8gY3JlYXRlIGFuZCBhZGQgYSBuZXcgYXR0cmlidXRlIHRvIHRoZSBuZXdseSBjcmVhdGVkCisgKiAgICBFbGVtZW50LiAgVGhlICJzZXRBdHRyaWJ1dGVOb2RlKG5ld0F0dHIpIiBtZXRob2QgaXMKKyAqICAgIG9uY2UgYWdhaW4gY2FsbGVkIHRvIGFkZCB0aGUgbmV3IGF0dHJpYnV0ZSBjYXVzaW5nIGFuCisgKiAgICBleGNlcHRpb24gdG8gYmUgcmFpc2VkIHNpbmNlIHRoZSBhdHRyaWJ1dGUgaXMgYWxyZWFkeQorICogICAgYW4gYXR0cmlidXRlIG9mIGFub3RoZXIgZWxlbWVudC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlVTRV9BVFRSSUJVVEVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04ODcyMzYxNTQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg4NzIzNjE1NDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtODg3MjM2MTU0JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTg4NzIzNjE1NCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVVNFX0FUVFJJQlVURV9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRpbnVzZWF0dHJpYnV0ZWVyciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudGludXNlYXR0cmlidXRlZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBOb2RlTGlzdCBhZGRyZXNzRWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RBZGRyZXNzOworICAgICAgRWxlbWVudCBuZXdFbGVtZW50OworICAgICAgTm9kZSBhcHBlbmRlZENoaWxkOworICAgICAgQXR0ciBzZXRBdHRyMTsKKyAgICAgIEF0dHIgc2V0QXR0cjI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBhZGRyZXNzRWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gKEVsZW1lbnQpIGFkZHJlc3NFbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgbmV3RWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCJuZXdFbGVtZW50Iik7CisgICAgICBhcHBlbmRlZENoaWxkID0gdGVzdEFkZHJlc3MuYXBwZW5kQ2hpbGQobmV3RWxlbWVudCk7CisgICAgICBuZXdBdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJuZXdBdHRyaWJ1dGUiKTsKKyAgICAgIHNldEF0dHIxID0gbmV3RWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlKG5ld0F0dHJpYnV0ZSk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldEF0dHIyID0gdGVzdEFkZHJlc3Muc2V0QXR0cmlidXRlTm9kZShuZXdBdHRyaWJ1dGUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTlVTRV9BVFRSSUJVVEVfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOVVNFX0FUVFJJQlVURV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudGludXNlYXR0cmlidXRlZXJyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50aW51c2VhdHRyaWJ1dGVlcnIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjUxYjQ4NAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDk5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0QXR0cmlidXRlKG5hbWUsdmFsdWUpIiBtZXRob2QgcmFpc2VzIGFuIAorICogICAgIklOVkFMSURfQ0hBUkFDVEVSX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCAKKyAqICAgIG5hbWUgY29udGFpbnMgYW4gaW52YWxpZCBjaGFyYWN0ZXIuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSBmaXJzdCBlbXBsb3llZSBhbmQgCisgKiAgICBjYWxsIGl0cyAic2V0QXR0cmlidXRlKG5hbWUsdmFsdWUpIiBtZXRob2Qgd2l0aCAgICAKKyAqICAgICJuYW1lIiBjb250YWluaW5nIGFuIGludmFsaWQgY2hhcmFjdGVyLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RjA4MiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RjA4MjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtRjY4RjA4MicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELUY2OEYwODInKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb24gZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RBZGRyZXNzOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRlc3RBZGRyZXNzLnNldEF0dHJpYnV0ZSgiaW52YWxpZF5OYW1lIiwgInZhbHVlIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTlZBTElEX0NIQVJBQ1RFUl9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb24iOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50bm9ybWFsaXplLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRub3JtYWxpemUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNzNlN2NkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50bm9ybWFsaXplLmphdmEKQEAgLTAsMCArMSw5NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJub3JtYWxpemUoKSIgbWV0aG9kIHB1dHMgYWxsIHRoZSBub2RlcyBpbiB0aGUgZnVsbAorICogICAgZGVwdGggb2YgdGhlIHN1Yi10cmVlIHVuZGVybmVhdGggdGhpcyBlbGVtZW50IGludG8gYSAKKyAqICAgICJub3JtYWwiIGZvcm0uIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgdGhpcmQgZW1wbG95ZWUgYW5kIGFjY2VzcyBpdHMgc2Vjb25kIGNoaWxkLgorICogICAgVGhpcyBjaGlsZCBjb250YWlucyBhIGJsb2NrIG9mIHRleHQgdGhhdCBpcyBzcHJlYWQgCisgKiAgICBhY3Jvc3MgbXVsdGlwbGUgbGluZXMuICBUaGUgY29udGVudCBvZiB0aGUgIm5hbWUiIGNoaWxkCisgKiAgICBzaG91bGQgYmUgcGFyc2VkIGFuZCB0cmVhdGVkIGFzIGEgc2luZ2xlIFRleHQgbm9kZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE2MkNGMDgzIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNjJDRjA4MzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudG5vcm1hbGl6ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudG5vcm1hbGl6ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgcm9vdDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0TmFtZTsKKyAgICAgIE5vZGUgZmlyc3RDaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZFZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgcm9vdCA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIHJvb3Qubm9ybWFsaXplKCk7CisgICAgICBlbGVtZW50TGlzdCA9IHJvb3QuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIm5hbWUiKTsKKyAgICAgIHRlc3ROYW1lID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBmaXJzdENoaWxkID0gdGVzdE5hbWUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgY2hpbGRWYWx1ZSA9IGZpcnN0Q2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnROb3JtYWxpemVBc3NlcnQiLCAiUm9nZXJcbiBKb25lcyIsIGNoaWxkVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50bm9ybWFsaXplIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50bm9ybWFsaXplLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50bm90Zm91bmRlcnIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudG5vdGZvdW5kZXJyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODQxM2Y2YgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudG5vdGZvdW5kZXJyLmphdmEKQEAgLTAsMCArMSwxMDQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAicmVtb3ZlQXR0cmlidXRlTm9kZShvbGRBdHRyKSIgbWV0aG9kIHJhaXNlcyBhCisgKiAgICBOT1RfRk9VTkRfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgIm9sZEF0dHIiIGF0dHJpYnV0ZQorICogICAgaXMgbm90IGFuIGF0dHJpYnV0ZSBvZiB0aGUgZWxlbWVudC4KKyAqICAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBsYXN0IGVtcGxveWVlIGFuZCBhdHRlbXB0IHRvIHJlbW92ZQorICogICAgYSBub24gZXhpc3RpbmcgYXR0cmlidXRlIG5vZGUuICBUaGlzIHNob3VsZCBjYXVzZSB0aGUKKyAqICAgIGludGVuZGVkIGV4Y2VwdGlvbiB0byBiZSByYWlzZWQuICBUaGlzIHRlc3QgbWFrZXMgdXNlCisgKiAgICBvZiB0aGUgImNyZWF0ZUF0dHJpYnV0ZShuYW1lKSIgbWV0aG9kIGZyb20gdGhlIERvY3VtZW50IAorICogICAgaW50ZXJmYWNlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVVNFX0FUVFJJQlVURV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlVTRV9BVFRSSUJVVEVfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ1ODkxOTgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ1ODkxOTg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELUQ1ODkxOTgnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlVTRV9BVFRSSUJVVEVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtRDU4OTE5OCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVVNFX0FUVFJJQlVURV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudG5vdGZvdW5kZXJyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50bm90Zm91bmRlcnIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBBdHRyIG9sZEF0dHJpYnV0ZTsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NFbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEFkZHJlc3M7CisgICAgICBBdHRyIGF0dHJBZGRyZXNzOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgYWRkcmVzc0VsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0QWRkcmVzcyA9IChFbGVtZW50KSBhZGRyZXNzRWxlbWVudExpc3QuaXRlbSg0KTsKKyAgICAgIG9sZEF0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoIm9sZEF0dHJpYnV0ZSIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhdHRyQWRkcmVzcyA9IHRlc3RBZGRyZXNzLnJlbW92ZUF0dHJpYnV0ZU5vZGUob2xkQXR0cmlidXRlKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT1RfRk9VTkRfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnRub3Rmb3VuZGVyciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudG5vdGZvdW5kZXJyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50cmVtb3ZlYXR0cmlidXRlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYTU0MTFiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50cmVtb3ZlYXR0cmlidXRlLmphdmEKQEAgLTAsMCArMSwxMDAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZW1vdmVBdHRyaWJ1dGUobmFtZSkiIHJlbW92ZXMgYW4gYXR0cmlidXRlIGJ5IG5hbWUuCisgKiAgICBJZiB0aGUgYXR0cmlidXRlIGhhcyBhIGRlZmF1bHQgdmFsdWUsIGl0IGlzIGltbWVkaWF0ZWx5CisgKiAgICByZXBsYWNlZC4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBuYW1lZCAic3RyZWV0IiBmcm9tIHRoZSBsYXN0IGNoaWxkCisgKiAgICBvZiB0aGUgZm91cnRoIGVtcGxveWVlLCB0aGVuIHJlbW92ZSB0aGUgInN0cmVldCIgCisgKiAgICBhdHRyaWJ1dGUgYnkgaW52b2tpbmcgdGhlICJyZW1vdmVBdHRyaWJ1dGUobmFtZSkiIG1ldGhvZC4KKyAqICAgIFRoZSAic3RyZWV0IiBhdHRyaWJ1dGUgaGFzIGEgZGVmYXVsdCB2YWx1ZSBkZWZpbmVkIGluIHRoZQorICogICAgRFREIGZpbGUsIHRoYXQgdmFsdWUgc2hvdWxkIGltbWVkaWF0ZWx5IHJlcGxhY2UgdGhlIG9sZAorICogICAgdmFsdWUuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02RDZBQzBGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNkQ2QUMwRjk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyTWFyLzAwMDIuaHRtbCI+aHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyTWFyLzAwMDIuaHRtbDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudHJlbW92ZWF0dHJpYnV0ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudHJlbW92ZWF0dHJpYnV0ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy52YWxpZGF0aW5nCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RFbXBsb3llZTsKKyAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEVtcGxveWVlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMyk7CisgICAgICB0ZXN0RW1wbG95ZWUucmVtb3ZlQXR0cmlidXRlKCJzdHJlZXQiKTsKKyAgICAgIGF0dHJWYWx1ZSA9IHRlc3RFbXBsb3llZS5nZXRBdHRyaWJ1dGUoInN0cmVldCIpOworICAgICAgYXNzZXJ0RXF1YWxzKCJzdHJlZXRZZXMiLCAiWWVzIiwgYXR0clZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudHJlbW92ZWF0dHJpYnV0ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudHJlbW92ZWF0dHJpYnV0ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHJlbW92ZWF0dHJpYnV0ZWFmdGVyY3JlYXRlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVhZnRlcmNyZWF0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUxNTNmMTUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVhZnRlcmNyZWF0ZS5qYXZhCkBAIC0wLDAgKzEsOTcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAicmVtb3ZlQXR0cmlidXRlTm9kZShvbGRBdHRyKSIgbWV0aG9kIHJlbW92ZXMgdGhlIAorICogICAgc3BlY2lmaWVkIGF0dHJpYnV0ZS4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSB0aGlyZCBlbXBsb3llZSwgYWRkIGEKKyAqICAgIG5ldyAiZGlzdHJpY3QiIG5vZGUgdG8gaXQgYW5kIHRoZW4gdHJ5IHRvIHJlbW92ZSBpdC4gCisgKiAgICBUbyB2ZXJpZnkgdGhhdCB0aGUgbm9kZSB3YXMgcmVtb3ZlZCB1c2UgdGhlCisgKiAgICAiZ2V0TmFtZWRJdGVtKG5hbWUpIiBtZXRob2QgZnJvbSB0aGUgTmFtZWROb2RlTWFwCisgKiAgICBpbnRlcmZhY2UuICBJdCBhbHNvIHVzZXMgdGhlICJnZXRBdHRyaWJ1dGVzKCkiIG1ldGhvZAorICogICAgZnJvbSB0aGUgTm9kZSBpbnRlcmZhY2UuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENTg5MTk4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENTg5MTk4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50cmVtb3ZlYXR0cmlidXRlYWZ0ZXJjcmVhdGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRyZW1vdmVhdHRyaWJ1dGVhZnRlcmNyZWF0ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0RW1wbG95ZWU7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBkaXN0cmljdEF0dHI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEVtcGxveWVlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBuZXdBdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJkaXN0cmljdCIpOworICAgICAgZGlzdHJpY3RBdHRyID0gdGVzdEVtcGxveWVlLnNldEF0dHJpYnV0ZU5vZGUobmV3QXR0cmlidXRlKTsKKyAgICAgIGRpc3RyaWN0QXR0ciA9IHRlc3RFbXBsb3llZS5yZW1vdmVBdHRyaWJ1dGVOb2RlKG5ld0F0dHJpYnV0ZSk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdEVtcGxveWVlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGRpc3RyaWN0QXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgiZGlzdHJpY3QiKTsKKyAgICAgIGFzc2VydE51bGwoImVsZW1lbnRSZW1vdmVBdHRyaWJ1dGVBZnRlckNyZWF0ZUFzc2VydCIsIGRpc3RyaWN0QXR0cik7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVhZnRlcmNyZWF0ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudHJlbW92ZWF0dHJpYnV0ZWFmdGVyY3JlYXRlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9kZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9kZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjViMzc4YmYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVub2RlLmphdmEKQEAgLTAsMCArMSw5MiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZW1vdmVBdHRyaWJ1dGVOb2RlKG9sZEF0dHIpIiBtZXRob2QgcmV0dXJucyB0aGUKKyAqICAgIG5vZGUgdGhhdCB3YXMgcmVtb3ZlZC4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSB0aGlyZCBlbXBsb3llZSBhbmQKKyAqICAgIHJlbW92ZSBpdHMgInN0cmVldCIgQXR0ciBub2RlLiAgVGhlIG1ldGhvZCBzaG91bGQgIAorICogICAgcmV0dXJuIHRoZSBvbGQgYXR0cmlidXRlIG5vZGUuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENTg5MTk4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENTg5MTk4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9kZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vZGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEVtcGxveWVlOworICAgICAgQXR0ciBzdHJlZXRBdHRyOworICAgICAgQXR0ciByZW1vdmVkQXR0cjsKKyAgICAgIFN0cmluZyByZW1vdmVkVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEVtcGxveWVlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBzdHJlZXRBdHRyID0gdGVzdEVtcGxveWVlLmdldEF0dHJpYnV0ZU5vZGUoInN0cmVldCIpOworICAgICAgcmVtb3ZlZEF0dHIgPSB0ZXN0RW1wbG95ZWUucmVtb3ZlQXR0cmlidXRlTm9kZShzdHJlZXRBdHRyKTsKKyAgICAgIHJlbW92ZWRWYWx1ZSA9IHJlbW92ZWRBdHRyLmdldFZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRSZW1vdmVBdHRyaWJ1dGVOb2RlQXNzZXJ0IiwgIk5vIiwgcmVtb3ZlZFZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vZGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRyZW1vdmVhdHRyaWJ1dGVub2RlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9kZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9kZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJkNWI3NTUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVub2Rlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmphdmEKQEAgLTAsMCArMSwxMjIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZW1vdmVBdHRyaWJ1dGVOb2RlKG9sZEF0dHIpIiBtZXRob2QgZm9yIGFuIGF0dHJpYnV0ZSBjYXVzZXMgdGhlIAorICogICAgRE9NRXhjZXB0aW9uIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiB0byBiZSByYWlzZWQKKyAqICAgIGlmIHRoZSBub2RlIGlzIHJlYWRvbmx5LgorICogICAgCisgKiAgICBPYnRhaW4gdGhlIGNoaWxkcmVuIG9mIHRoZSBUSElSRCAiZ2VuZGVyIiBlbGVtZW50LiAgVGhlIGVsZW1lbnRzCisgKiAgICBjb250ZW50IGlzIGFuIGVudGl0eSByZWZlcmVuY2UuICBUcnkgdG8gcmVtb3ZlIHRoZSAiZG9tZXN0aWMiIGF0dHJpYnV0ZQorICogICAgZnJvbSB0aGUgZW50aXR5IHJlZmVyZW5jZSBieSBleGVjdXRpbmcgdGhlICJyZW1vdmVBdHRyaWJ1dGVOb2RlKG9sZEF0dHIpIiBtZXRob2QuCisgKiAgICBUaGlzIGNhdXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gdG8gYmUgdGhyb3duLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENTg5MTk4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENTg5MTk4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC1ENTg5MTk4JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtRDU4OTE5OCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENTg5MTk4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENTg5MTk4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9kZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vZGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBnZW5kZXJMaXN0OworICAgICAgTm9kZSBnZW5kZXI7CisgICAgICBOb2RlTGlzdCBnZW5MaXN0OworICAgICAgTm9kZSBnZW47CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBOb2RlTGlzdCBnTGlzdDsKKyAgICAgIEVsZW1lbnQgZ2VuRWxlbWVudDsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyTGlzdDsKKyAgICAgIEF0dHIgYXR0ck5vZGU7CisgICAgICBBdHRyIHJlbW92ZWRBdHRyOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZ2VuZGVyTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZ2VuZGVyIik7CisgICAgICBnZW5kZXIgPSBnZW5kZXJMaXN0Lml0ZW0oMik7CisgICAgICBnZW5MaXN0ID0gZ2VuZGVyLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGdlbiA9IGdlbkxpc3QuaXRlbSgwKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImdlbk5vdE51bGwiLCBnZW4pOworICAgICAgbm9kZVR5cGUgPSAoaW50KSBnZW4uZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygxLCBub2RlVHlwZSkpIHsKKyAgICAgICAgICBnZW4gPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQ0Iik7CisgICAgICBhc3NlcnROb3ROdWxsKCJjcmVhdGVkRW50UmVmTm90TnVsbCIsIGdlbik7CisgICAgICB9CisgICAgZ0xpc3QgPSBnZW4uZ2V0Q2hpbGROb2RlcygpOworICAgICAgZ2VuRWxlbWVudCA9IChFbGVtZW50KSBnTGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2VuRWxlbWVudE5vdE51bGwiLCBnZW5FbGVtZW50KTsKKyAgICAgIGF0dHJMaXN0ID0gZ2VuRWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBhdHRyTm9kZSA9IChBdHRyKSBhdHRyTGlzdC5nZXROYW1lZEl0ZW0oImRvbWVzdGljIik7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlbW92ZWRBdHRyID0gZ2VuRWxlbWVudC5yZW1vdmVBdHRyaWJ1dGVOb2RlKGF0dHJOb2RlKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9kZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vZGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVub2Rlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vZGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjN2Q1NjMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVub2Rlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YQpAQCAtMCwwICsxLDExNSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlbW92ZUF0dHJpYnV0ZU5vZGUob2xkQXR0cikiIG1ldGhvZCBmb3IgYW4gYXR0cmlidXRlIGNhdXNlcyB0aGUgCisgKiAgICBET01FeGNlcHRpb24gTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIHRvIGJlIHJhaXNlZAorICogICAgaWYgdGhlIG5vZGUgaXMgcmVhZG9ubHkuCisgKiAgICAKKyAqICAgIENyZWF0ZSBhbiBlbnRpdHkgcmVmZXJlbmNlIGFuZCBhZGQgaXQgdG8gdGhlIGNoaWxkcmVuIG9mIHRoZSBUSElSRCAiZ2VuZGVyIiBlbGVtZW50LgorICogICAgVHJ5IHRvIHJlbW92ZSB0aGUgImRvbWVzdGljIiBhdHRyaWJ1dGUgZnJvbSB0aGUgZW50aXR5IAorICogICAgcmVmZXJlbmNlIGJ5IGV4ZWN1dGluZyB0aGUgInJlbW92ZUF0dHJpYnV0ZU5vZGUob2xkQXR0cikiIG1ldGhvZC4KKyAqICAgIFRoaXMgY2F1c2VzIGEgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIERPTUV4Y2VwdGlvbiB0byBiZSB0aHJvd24uCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ1ODkxOTgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ1ODkxOTg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELUQ1ODkxOTgnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC1ENTg5MTk4JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ1ODkxOTgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ1ODkxOTg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9kZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWwiPmh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vZGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIueG1sPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9kZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9kZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyOworICAgICAgRW50aXR5UmVmZXJlbmNlIGVudFJlZjsKKyAgICAgIEVsZW1lbnQgZW50RWxlbWVudDsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyTGlzdDsKKyAgICAgIEF0dHIgYXR0ck5vZGU7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBBdHRyIHJlbW92ZWRBdHRyOworICAgICAgTm9kZSBhcHBlbmRlZENoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZ2VuZGVyTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZ2VuZGVyIik7CisgICAgICBnZW5kZXIgPSBnZW5kZXJMaXN0Lml0ZW0oMik7CisgICAgICBlbnRSZWYgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQ0Iik7CisgICAgICBhc3NlcnROb3ROdWxsKCJjcmVhdGVkRW50UmVmTm90TnVsbCIsIGVudFJlZik7CisgICAgICBhcHBlbmRlZENoaWxkID0gZ2VuZGVyLmFwcGVuZENoaWxkKGVudFJlZik7CisgICAgICBlbnRFbGVtZW50ID0gKEVsZW1lbnQpIGVudFJlZi5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRFbGVtZW50Tm90TnVsbCIsIGVudEVsZW1lbnQpOworICAgICAgYXR0ckxpc3QgPSBlbnRFbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGF0dHJOb2RlID0gKEF0dHIpIGF0dHJMaXN0LmdldE5hbWVkSXRlbSgiZG9tZXN0aWMiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImF0dHJOb2RlTm90TnVsbCIsIGF0dHJOb2RlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVtb3ZlZEF0dHIgPSBlbnRFbGVtZW50LnJlbW92ZUF0dHJpYnV0ZU5vZGUoYXR0ck5vZGUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVub2Rlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRyZW1vdmVhdHRyaWJ1dGVub2Rlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU0YjkzYzQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuamF2YQpAQCAtMCwwICsxLDExNyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlbW92ZUF0dHJpYnV0ZShuYW1lKSIgbWV0aG9kIGZvciBhbiBhdHRyaWJ1dGUgY2F1c2VzIHRoZSAKKyAqICAgIERPTUV4Y2VwdGlvbiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgdG8gYmUgcmFpc2VkCisgKiAgICBpZiB0aGUgbm9kZSBpcyByZWFkb25seS4KKyAqICAgIAorICogICAgT2J0YWluIHRoZSBjaGlsZHJlbiBvZiB0aGUgVEhJUkQgImdlbmRlciIgZWxlbWVudC4gIFRoZSBlbGVtZW50cworICogICAgY29udGVudCBpcyBhbiBlbnRpdHkgcmVmZXJlbmNlLiAgVHJ5IHRvIHJlbW92ZSB0aGUgImRvbWVzdGljIiBhdHRyaWJ1dGUKKyAqICAgIGZyb20gdGhlIGVudGl0eSByZWZlcmVuY2UgYnkgZXhlY3V0aW5nIHRoZSAicmVtb3ZlQXR0cmlidXRlKG5hbWUpIiBtZXRob2QuCisgKiAgICBUaGlzIGNhdXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gdG8gYmUgdGhyb3duLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02RDZBQzBGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNkQ2QUMwRjk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTZENkFDMEY5JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNkQ2QUMwRjknKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNkQ2QUMwRjkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTZENkFDMEY5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyOworICAgICAgTm9kZUxpc3QgZ2VuTGlzdDsKKyAgICAgIE5vZGUgZ2VuOworICAgICAgTm9kZUxpc3QgZ0xpc3Q7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBFbGVtZW50IGdlbkVsZW1lbnQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBnZW5kZXJMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJnZW5kZXIiKTsKKyAgICAgIGdlbmRlciA9IGdlbmRlckxpc3QuaXRlbSgyKTsKKyAgICAgIGdlbkxpc3QgPSBnZW5kZXIuZ2V0Q2hpbGROb2RlcygpOworICAgICAgZ2VuID0gZ2VuTGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2VuTm90TnVsbCIsIGdlbik7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGdlbi5nZXROb2RlVHlwZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDEsIG5vZGVUeXBlKSkgeworICAgICAgICAgIGdlbiA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDQiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZ2VuKTsKKyAgICAgIH0KKyAgICBnTGlzdCA9IGdlbi5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBnZW5FbGVtZW50ID0gKEVsZW1lbnQpIGdMaXN0Lml0ZW0oMCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJnZW5FbGVtZW50Tm90TnVsbCIsIGdlbkVsZW1lbnQpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBnZW5FbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgiZG9tZXN0aWMiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGJmYjFhOAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmphdmEKQEAgLTAsMCArMSwxMDcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZW1vdmVBdHRyaWJ1dGUobmFtZSkiIG1ldGhvZCBmb3IgYW4gYXR0cmlidXRlIGNhdXNlcyB0aGUgCisgKiAgICBET01FeGNlcHRpb24gTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIHRvIGJlIHJhaXNlZAorICogICAgaWYgdGhlIG5vZGUgaXMgcmVhZG9ubHkuCisgKiAgICAKKyAqICAgIENyZWF0ZSBhbiByZWZlcmVuY2UgdGhlIGVudGl0eSBlbnQ0IGFuZCBhZGQgaXQgdG8gdGhlIFRISVJEICJnZW5kZXIiIGVsZW1lbnQuICAKKyAqICAgIFRyeSB0byByZW1vdmUgdGhlICJkb21lc3RpYyIgYXR0cmlidXRlIGZyb20gdGhlIGVudGl0eSByZWZlcmVuY2UgYnkgZXhlY3V0aW5nIHRoZSAicmVtb3ZlQXR0cmlidXRlKG5hbWUpIiBtZXRob2QuCisgKiAgICBUaGlzIGNhdXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gdG8gYmUgdGhyb3duLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02RDZBQzBGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNkQ2QUMwRjk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTZENkFDMEY5JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNkQ2QUMwRjknKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNkQ2QUMwRjkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTZENkFDMEY5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWwiPmh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWw8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRyZW1vdmVhdHRyaWJ1dGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyOworICAgICAgRW50aXR5UmVmZXJlbmNlIGVudFJlZjsKKyAgICAgIEVsZW1lbnQgZW50RWxlbWVudDsKKyAgICAgIE5vZGUgYXBwZW5kZWRDaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGdlbmRlckxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImdlbmRlciIpOworICAgICAgZ2VuZGVyID0gZ2VuZGVyTGlzdC5pdGVtKDIpOworICAgICAgZW50UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGdlbmRlci5hcHBlbmRDaGlsZChlbnRSZWYpOworICAgICAgZW50RWxlbWVudCA9IChFbGVtZW50KSBlbnRSZWYuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50RWxlbWVudE5vdE51bGwiLCBlbnRFbGVtZW50KTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgZW50RWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoImRvbWVzdGljIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVyZXN0b3JlZGVmYXVsdHZhbHVlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVyZXN0b3JlZGVmYXVsdHZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmJlNTJiZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHJlbW92ZWF0dHJpYnV0ZXJlc3RvcmVkZWZhdWx0dmFsdWUuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlbW92ZUF0dHJpYnV0ZU5vZGUob2xkQXR0cikiIG1ldGhvZCByZW1vdmVzIHRoZQorICogICAgc3BlY2lmaWVkIGF0dHJpYnV0ZSBub2RlIGFuZCByZXN0b3JlcyBhbnkgZGVmYXVsdCB2YWx1ZXMuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgdGhpcmQgZW1wbG95ZWVkIGFuZCAKKyAqICAgIHJlbW92ZSBpdHMgInN0cmVldCIgQXR0ciBub2RlLiAgU2luY2UgdGhpcyBub2RlIGhhcyBhCisgKiAgICBkZWZhdWx0IHZhbHVlIGRlZmluZWQgaW4gdGhlIERURCBmaWxlLCB0aGF0IGRlZmF1bHQKKyAqICAgIHNob3VsZCBpbW1lZGlhdGVseSBiZSB0aGUgbmV3IHZhbHVlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRDU4OTE5OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRDU4OTE5ODwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDJNYXIvMDAwMi5odG1sIj5odHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDJNYXIvMDAwMi5odG1sPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50cmVtb3ZlYXR0cmlidXRlcmVzdG9yZWRlZmF1bHR2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudHJlbW92ZWF0dHJpYnV0ZXJlc3RvcmVkZWZhdWx0dmFsdWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcudmFsaWRhdGluZworICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0RW1wbG95ZWU7CisgICAgICBBdHRyIHN0cmVldEF0dHI7CisgICAgICBTdHJpbmcgYXR0cmlidXRlOworICAgICAgQXR0ciByZW1vdmVkQXR0cjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIHN0cmVldEF0dHIgPSB0ZXN0RW1wbG95ZWUuZ2V0QXR0cmlidXRlTm9kZSgic3RyZWV0Iik7CisgICAgICByZW1vdmVkQXR0ciA9IHRlc3RFbXBsb3llZS5yZW1vdmVBdHRyaWJ1dGVOb2RlKHN0cmVldEF0dHIpOworICAgICAgYXR0cmlidXRlID0gdGVzdEVtcGxveWVlLmdldEF0dHJpYnV0ZSgic3RyZWV0Iik7CisgICAgICBhc3NlcnRFcXVhbHMoInN0cmVldFllcyIsICJZZXMiLCBhdHRyaWJ1dGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50cmVtb3ZlYXR0cmlidXRlcmVzdG9yZWRlZmF1bHR2YWx1ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudHJlbW92ZWF0dHJpYnV0ZXJlc3RvcmVkZWZhdWx0dmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZXBsYWNlYXR0cmlidXRld2l0aHNlbGYuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHJlcGxhY2VhdHRyaWJ1dGV3aXRoc2VsZi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBkMDI5YjUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZXBsYWNlYXR0cmlidXRld2l0aHNlbGYuamF2YQpAQCAtMCwwICsxLDg5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIFRoaXMgdGVzdCBjYWxscyBzZXRBdHRyaWJ1dGVOb2RlIHRvIHJlcGxhY2UgYW4gYXR0cmlidXRlIHdpdGggaXRzZWxmLiAgCisgKiBTaW5jZSB0aGUgbm9kZSBpcyBub3QgYW4gYXR0cmlidXRlIG9mIGFub3RoZXIgRWxlbWVudCwgaXQgd291bGQKKyAqIGJlIGluYXBwcm9wcmlhdGUgdG8gdGhyb3cgYW4gSU5VU0VfQVRUUklCVVRFX0VSUi4KKyAqIFRoaXMgdGVzdCB3YXMgZGVyaXZlZCBmcm9tIGVsZW1lbnRpbnVzZXJhdHRyaWJ1dGVlcnIgd2hpY2gKKyAqIGluYWR2ZXJ0YW5seSBtYWRlIHRoaXMgdGVzdC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODg3MjM2MTU0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04ODcyMzYxNTQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRyZXBsYWNlYXR0cmlidXRld2l0aHNlbGYgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRyZXBsYWNlYXR0cmlidXRld2l0aHNlbGYoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEVtcGxveWVlOworICAgICAgQXR0ciBzdHJlZXRBdHRyOworICAgICAgQXR0ciByZXBsYWNlZEF0dHI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEVtcGxveWVlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBzdHJlZXRBdHRyID0gdGVzdEVtcGxveWVlLmdldEF0dHJpYnV0ZU5vZGUoInN0cmVldCIpOworICAgICAgcmVwbGFjZWRBdHRyID0gdGVzdEVtcGxveWVlLnNldEF0dHJpYnV0ZU5vZGUoc3RyZWV0QXR0cik7CisgICAgICBhc3NlcnRTYW1lKCJyZXBsYWNlZEF0dHIiLCBzdHJlZXRBdHRyLCByZXBsYWNlZEF0dHIpOworfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50cmVwbGFjZWF0dHJpYnV0ZXdpdGhzZWxmIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50cmVwbGFjZWF0dHJpYnV0ZXdpdGhzZWxmLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50cmVwbGFjZWV4aXN0aW5nYXR0cmlidXRlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZXBsYWNlZXhpc3RpbmdhdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45OWZiY2RmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50cmVwbGFjZWV4aXN0aW5nYXR0cmlidXRlLmphdmEKQEAgLTAsMCArMSw5NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXRBdHRyaWJ1dGVOb2RlKG5ld0F0dHIpIiBtZXRob2QgYWRkcyBhIG5ldworICogICAgYXR0cmlidXRlIHRvIHRoZSBFbGVtZW50LiAgSWYgdGhlICJuZXdBdHRyIiBBdHRyIG5vZGUgaXMKKyAqICAgIGFscmVhZHkgcHJlc2VudCBpbiB0aGlzIGVsZW1lbnQsIGl0IHNob3VsZCByZXBsYWNlIHRoZQorICogICAgZXhpc3Rpbmcgb25lLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGxhc3QgY2hpbGQgb2YgdGhlIHRoaXJkIGVtcGxveWVlIGFuZCBhZGQgYSAKKyAqICAgIG5ldyBhdHRyaWJ1dGUgbm9kZSBieSBpbnZva2luZyB0aGUgInNldEF0dHJpYnV0ZU5vZGUobmV3IAorICogICAgQXR0cikiIG1ldGhvZC4gIFRoZSBuZXcgYXR0cmlidXRlIG5vZGUgdG8gYmUgYWRkZWQgaXMgCisgKiAgICAic3RyZWV0Iiwgd2hpY2ggaXMgYWxyZWFkeSBwcmVzZW50IGluIHRoaXMgZWxlbWVudC4gIFRoZQorICogICAgbWV0aG9kIHNob3VsZCByZXBsYWNlIHRoZSBleGlzdGluZyBBdHRyIG5vZGUgd2l0aCB0aGUgCisgKiAgICBuZXcgb25lLiAgVGhpcyB0ZXN0IHVzZXMgdGhlICJjcmVhdGVBdHRyaWJ1dGUobmFtZSkiCisgKiAgICBtZXRob2QgZnJvbSB0aGUgRG9jdW1lbnQgaW50ZXJmYWNlLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50cmVwbGFjZWV4aXN0aW5nYXR0cmlidXRlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50cmVwbGFjZWV4aXN0aW5nYXR0cmlidXRlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RFbXBsb3llZTsKKyAgICAgIEF0dHIgbmV3QXR0cmlidXRlOworICAgICAgU3RyaW5nIG5hbWU7CisgICAgICBBdHRyIHNldEF0dHI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEVtcGxveWVlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBuZXdBdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJzdHJlZXQiKTsKKyAgICAgIHNldEF0dHIgPSB0ZXN0RW1wbG95ZWUuc2V0QXR0cmlidXRlTm9kZShuZXdBdHRyaWJ1dGUpOworICAgICAgbmFtZSA9IHRlc3RFbXBsb3llZS5nZXRBdHRyaWJ1dGUoInN0cmVldCIpOworICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50UmVwbGFjZUV4aXN0aW5nQXR0cmlidXRlQXNzZXJ0IiwgIiIsIG5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50cmVwbGFjZWV4aXN0aW5nYXR0cmlidXRlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50cmVwbGFjZWV4aXN0aW5nYXR0cmlidXRlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50cmVwbGFjZWV4aXN0aW5nYXR0cmlidXRlZ2V2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50cmVwbGFjZWV4aXN0aW5nYXR0cmlidXRlZ2V2YWx1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ3YjRmZjIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZXBsYWNlZXhpc3RpbmdhdHRyaWJ1dGVnZXZhbHVlLmphdmEKQEAgLTAsMCArMSw5NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBJZiB0aGUgInNldEF0dHJpYnV0ZU5vZGUobmV3QXR0cikiIG1ldGhvZCByZXBsYWNlcyBhbgorICogZXhpc3RpbmcgQXR0ciBub2RlIHdpdGggdGhlIHNhbWUgbmFtZSwgdGhlbiBpdCBzaG91bGQKKyAqIHJldHVybiB0aGUgcHJldmlvdXNseSBleGlzdGluZyBBdHRyIG5vZGUuCisgKiBSZXRyaWV2ZSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgdGhpcmQgZW1wbG95ZWUgYW5kIGFkZCBhCisgKiBuZXcgYXR0cmlidXRlIG5vZGUuICBUaGUgbmV3IGF0dHJpYnV0ZSBub2RlIGlzICJzdHJlZXQiLAorICogd2hpY2ggaXMgYWxyZWFkeSBwcmVzZW50IGluIHRoaXMgRWxlbWVudC4gIFRoZSBtZXRob2QKKyAqIHNob3VsZCByZXR1cm4gdGhlIGV4aXN0aW5nIEF0dHIgbm9kZShvbGQgInN0cmVldCIgQXR0cikuCisgKiBUaGlzIHRlc3QgdXNlcyB0aGUgImNyZWF0ZUF0dHJpYnV0ZShuYW1lKSIgbWV0aG9kCisgKiBmcm9tIHRoZSBEb2N1bWVudCBpbnRlcmZhY2UuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04ODcyMzYxNTQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg4NzIzNjE1NDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudHJlcGxhY2VleGlzdGluZ2F0dHJpYnV0ZWdldmFsdWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRyZXBsYWNlZXhpc3RpbmdhdHRyaWJ1dGVnZXZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RFbXBsb3llZTsKKyAgICAgIEF0dHIgbmV3QXR0cmlidXRlOworICAgICAgQXR0ciBzdHJlZXRBdHRyOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3RFbXBsb3llZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgbmV3QXR0cmlidXRlID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZSgic3RyZWV0Iik7CisgICAgICBzdHJlZXRBdHRyID0gdGVzdEVtcGxveWVlLnNldEF0dHJpYnV0ZU5vZGUobmV3QXR0cmlidXRlKTsKKyAgICAgIHZhbHVlID0gc3RyZWV0QXR0ci5nZXRWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJzdHJlZXRObyIsICJObyIsIHZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudHJlcGxhY2VleGlzdGluZ2F0dHJpYnV0ZWdldmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRyZXBsYWNlZXhpc3RpbmdhdHRyaWJ1dGVnZXZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50cmV0cmlldmVhbGxhdHRyaWJ1dGVzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRyZXRyaWV2ZWFsbGF0dHJpYnV0ZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNjU0YzAxCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50cmV0cmlldmVhbGxhdHRyaWJ1dGVzLmphdmEKQEAgLTAsMCArMSw5OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRBdHRyaWJ1dGVzKCkiIG1ldGhvZChOb2RlIEludGVyZmFjZSkgbWF5CisgKiAgICBiZSB1c2VkIHRvIHJldHJpZXZlIHRoZSBzZXQgb2YgYWxsIGF0dHJpYnV0ZXMgb2YgYW4KKyAqICAgIGVsZW1lbnQuIAorICogICAgCisgKiAgICBDcmVhdGUgYSBsaXN0IG9mIGFsbCB0aGUgYXR0cmlidXRlcyBvZiB0aGUgbGFzdCBjaGlsZAorICogICAgb2YgdGhlIGZpcnN0IGVtcGxveWVlIGJ5IHVzaW5nIHRoZSAiZ2V0QXR0cmlidXRlcygpIgorICogICAgbWV0aG9kLiAgRXhhbWluZSB0aGUgbGVuZ3RoIG9mIHRoZSBhdHRyaWJ1dGUgbGlzdC4gIAorICogICAgVGhpcyB0ZXN0IHVzZXMgdGhlICJnZXRMZW5ndGgoKSIgbWV0aG9kIGZyb20gdGhlICAgICAgICAKKyAqICAgIE5hbWVOb2RlTWFwIGludGVyZmFjZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyTWFyLzAwMDIuaHRtbCI+aHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyTWFyLzAwMDIuaHRtbDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudHJldHJpZXZlYWxsYXR0cmlidXRlcyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudHJldHJpZXZlYWxsYXR0cmlidXRlcyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy52YWxpZGF0aW5nCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NMaXN0OworICAgICAgTm9kZSB0ZXN0QWRkcmVzczsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGFkZHJlc3NMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0QWRkcmVzcyA9IGFkZHJlc3NMaXN0Lml0ZW0oMCk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdEFkZHJlc3MuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXNzZXJ0U2l6ZSgiZWxlbWVudFJldHJpZXZlQWxsQXR0cmlidXRlc0Fzc2VydCIsIDIsIGF0dHJpYnV0ZXMpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50cmV0cmlldmVhbGxhdHRyaWJ1dGVzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50cmV0cmlldmVhbGxhdHRyaWJ1dGVzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50cmV0cmlldmVhdHRydmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHJldHJpZXZlYXR0cnZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2E0NjVkZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHJldHJpZXZlYXR0cnZhbHVlLmphdmEKQEAgLTAsMCArMSw4OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRBdHRyaWJ1dGUobmFtZSkiIG1ldGhvZCByZXR1cm5zIGFuIGF0dHJpYnV0ZQorICogICAgdmFsdWUgYnkgbmFtZS4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIHNlY29uZCBhZGRyZXNzIGVsZW1lbnQsIHRoZW4KKyAqICAgIGludm9rZSB0aGUgJ2dldEF0dHJpYnV0ZSgic3RyZWV0IiknIG1ldGhvZC4gIFRoaXMgc2hvdWxkCisgKiAgICByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUoIk5vIikuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NjZFRTBGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjY2RUUwRjk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRyZXRyaWV2ZWF0dHJ2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudHJldHJpZXZlYXR0cnZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcmVzczsKKyAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBhdHRyVmFsdWUgPSB0ZXN0QWRkcmVzcy5nZXRBdHRyaWJ1dGUoInN0cmVldCIpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyVmFsdWUiLCAiTm8iLCBhdHRyVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50cmV0cmlldmVhdHRydmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRyZXRyaWV2ZWF0dHJ2YWx1ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHJldHJpZXZldGFnbmFtZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50cmV0cmlldmV0YWduYW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDU3MzkxOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHJldHJpZXZldGFnbmFtZS5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0RWxlbWVudHNCeVRhZ05hbWUoKSIgbWV0aG9kIHJldHVybnMgYSBOb2RlTGlzdCAKKyAqICAgIG9mIGFsbCBkZXNjZW5kYW50IGVsZW1lbnRzIHdpdGggYSBnaXZlbiB0YWdOYW1lLiAgICAKKyAqICAgIAorICogICAgSW52b2tlIHRoZSAiZ2V0RWxlbWVudHNCeVRhZ05hbWUoKSIgbWV0aG9kIGFuZCBjcmVhdGUKKyAqICAgIGEgTm9kZUxpc3Qgb2YgInBvc2l0aW9uIiBlbGVtZW50cy4gIFJldHJpZXZlIHRoZSBzZWNvbmQgCisgKiAgICAicG9zaXRpb24iIGVsZW1lbnQgaW4gdGhlIGxpc3QgYW5kIHJldHVybiB0aGUgTm9kZU5hbWUuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDQ2ODI4MTUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwNDY4MjgxNTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudHJldHJpZXZldGFnbmFtZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudHJldHJpZXZldGFnbmFtZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgU3RyaW5nIG5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInBvc2l0aW9uIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgbmFtZSA9IHRlc3RFbXBsb3llZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlbmFtZSIsICJwb3NpdGlvbiIsIG5hbWUpOworICAgICAgbmFtZSA9ICgoRWxlbWVudCkgLypOb2RlICovdGVzdEVtcGxveWVlKS5nZXRUYWdOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInRhZ25hbWUiLCAicG9zaXRpb24iLCBuYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudHJldHJpZXZldGFnbmFtZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudHJldHJpZXZldGFnbmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOWM5MzA0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9kZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCkBAIC0wLDAgKzEsMTE2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0QXR0cmlidXRlTm9kZShuZXdBdHRyKSIgbWV0aG9kIGZvciBhbiBhdHRyaWJ1dGUgY2F1c2VzIHRoZSAKKyAqICAgIERPTUV4Y2VwdGlvbiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgdG8gYmUgcmFpc2VkCisgKiAgICBpZiB0aGUgbm9kZSBpcyByZWFkb25seS4KKyAqICAgIAorICogICAgT2J0YWluIHRoZSBjaGlsZHJlbiBvZiB0aGUgVEhJUkQgImdlbmRlciIgZWxlbWVudC4gIFRoZSBlbGVtZW50cworICogICAgY29udGVudCBpcyBhbiBlbnRpdHkgcmVmZXJlbmNlLiAgVHJ5IHRvIHJlbW92ZSB0aGUgImRvbWVzdGljIiBhdHRyaWJ1dGUKKyAqICAgIGZyb20gdGhlIGVudGl0eSByZWZlcmVuY2UgYnkgZXhlY3V0aW5nIHRoZSAic2V0QXR0cmlidXRlTm9kZShuZXdBdHRyKSIgbWV0aG9kLgorICogICAgVGhpcyBjYXVzZXMgYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgRE9NRXhjZXB0aW9uIHRvIGJlIHRocm93bi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODg3MjM2MTU0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04ODcyMzYxNTQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTg4NzIzNjE1NCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTg4NzIzNjE1NCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04ODcyMzYxNTQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg4NzIzNjE1NDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRzZXRhdHRyaWJ1dGVub2Rlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyOworICAgICAgTm9kZSBlbnRSZWY7CisgICAgICBFbGVtZW50IGVudEVsZW1lbnQ7CisgICAgICBBdHRyIG5ld0F0dHI7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBBdHRyIGJhZEF0dHI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBnZW5kZXJMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJnZW5kZXIiKTsKKyAgICAgIGdlbmRlciA9IGdlbmRlckxpc3QuaXRlbSgyKTsKKyAgICAgIGVudFJlZiA9IGdlbmRlci5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRSZWZOb3ROdWxsIiwgZW50UmVmKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgZW50UmVmLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoMSwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgZW50UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworICAgICAgfQorICAgIGVudEVsZW1lbnQgPSAoRWxlbWVudCkgZW50UmVmLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudEVsZW1lbnROb3ROdWxsIiwgZW50RWxlbWVudCk7CisgICAgICBuZXdBdHRyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZSgibmV3QXR0ciIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiYWRBdHRyID0gZW50RWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlKG5ld0F0dHIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2Rlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50c2V0YXR0cmlidXRlbm9kZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9kZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTY5NzBmMgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhCkBAIC0wLDAgKzEsMTE3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0QXR0cmlidXRlTm9kZShuZXdBdHRyKSIgbWV0aG9kIGZvciBhbiBhdHRyaWJ1dGUgY2F1c2VzIHRoZSAKKyAqICAgIERPTUV4Y2VwdGlvbiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgdG8gYmUgcmFpc2VkCisgKiAgICBpZiB0aGUgbm9kZSBpcyByZWFkb25seS4KKyAqICAgIAorICogICAgQ3JlYXRlIGFuIGVudGl0eSByZWZlcmVuY2UgYW5kIGFkZCB0byB0aGUgVEhJUkQgImdlbmRlciIgZWxlbWVudC4gIFRoZSBlbGVtZW50cworICogICAgY29udGVudCBpcyBhbiBlbnRpdHkgcmVmZXJlbmNlLiAgVHJ5IHRvIHJlbW92ZSB0aGUgImRvbWVzdGljIiBhdHRyaWJ1dGUKKyAqICAgIGZyb20gdGhlIGVudGl0eSByZWZlcmVuY2UgYnkgZXhlY3V0aW5nIHRoZSAic2V0QXR0cmlidXRlTm9kZShuZXdBdHRyKSIgbWV0aG9kLgorICogICAgVGhpcyBjYXVzZXMgYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgRE9NRXhjZXB0aW9uIHRvIGJlIHRocm93bi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODg3MjM2MTU0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04ODcyMzYxNTQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTg4NzIzNjE1NCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTg4NzIzNjE1NCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04ODcyMzYxNTQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg4NzIzNjE1NDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2Rlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLnhtbCI+aHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9kZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWw8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRzZXRhdHRyaWJ1dGVub2Rlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRzZXRhdHRyaWJ1dGVub2Rlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubm90RXhwYW5kRW50aXR5UmVmZXJlbmNlcworICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGdlbmRlckxpc3Q7CisgICAgICBOb2RlIGdlbmRlcjsKKyAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWY7CisgICAgICBFbGVtZW50IGVudEVsZW1lbnQ7CisgICAgICBBdHRyIG5ld0F0dHI7CisgICAgICBBdHRyIGJhZEF0dHI7CisgICAgICBOb2RlIGFwcGVuZGVkQ2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBnZW5kZXJMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJnZW5kZXIiKTsKKyAgICAgIGdlbmRlciA9IGdlbmRlckxpc3QuaXRlbSgyKTsKKyAgICAgIGVudFJlZiA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDQiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZW50UmVmKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBnZW5kZXIuYXBwZW5kQ2hpbGQoZW50UmVmKTsKKyAgICAgIGVudEVsZW1lbnQgPSAoRWxlbWVudCkgZW50UmVmLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudEVsZW1lbnROb3ROdWxsIiwgZW50RWxlbWVudCk7CisgICAgICBuZXdBdHRyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZSgibmV3QXR0ciIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiYWRBdHRyID0gZW50RWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlKG5ld0F0dHIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2Rlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRzZXRhdHRyaWJ1dGVub2Rlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9kZW51bGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NWY1YmNkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9kZW51bGwuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldEF0dHJpYnV0ZU5vZGUobmV3QXR0cikiIG1ldGhvZCByZXR1cm5zIHRoZQorICogICAgbnVsbCB2YWx1ZSBpZiBubyBwcmV2aW91c2x5IGV4aXN0aW5nIEF0dHIgbm9kZSB3aXRoIHRoZQorICogICAgc2FtZSBuYW1lIHdhcyByZXBsYWNlZC4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGxhc3QgY2hpbGQgb2YgdGhlIHRoaXJkIGVtcGxveWVlIGFuZCBhZGQgYSAKKyAqICAgIG5ldyBhdHRyaWJ1dGUgdG8gaXQuICBUaGUgbmV3IGF0dHJpYnV0ZSBub2RlIGFkZGVkIGlzIAorICogICAgImRpc3RyaWN0Iiwgd2hpY2ggaXMgbm90IHBhcnQgb2YgdGhpcyBFbGVtZW50LiAgVGhlICAgCisgKiAgICBtZXRob2Qgc2hvdWxkIHJldHVybiB0aGUgbnVsbCB2YWx1ZS4gICAKKyAqICAgIFRoaXMgdGVzdCB1c2VzIHRoZSAiY3JlYXRlQXR0cmlidXRlKG5hbWUpIgorICogICAgbWV0aG9kIGZyb20gdGhlIERvY3VtZW50IGludGVyZmFjZS4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04ODcyMzYxNTQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg4NzIzNjE1NDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVudWxsIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50c2V0YXR0cmlidXRlbm9kZW51bGwoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEVtcGxveWVlOworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBBdHRyIGRpc3RyaWN0QXR0cjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoImRpc3RyaWN0Iik7CisgICAgICBkaXN0cmljdEF0dHIgPSB0ZXN0RW1wbG95ZWUuc2V0QXR0cmlidXRlTm9kZShuZXdBdHRyaWJ1dGUpOworICAgICAgYXNzZXJ0TnVsbCgiZWxlbWVudFNldEF0dHJpYnV0ZU5vZGVOdWxsQXNzZXJ0IiwgZGlzdHJpY3RBdHRyKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVudWxsIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50c2V0YXR0cmlidXRlbm9kZW51bGwuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNlMDFmZTIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuamF2YQpAQCAtMCwwICsxLDExMiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldEF0dHJpYnV0ZShuYW1lLHZhbHVlKSIgbWV0aG9kIGZvciBhbiBhdHRyaWJ1dGUgY2F1c2VzIHRoZSAKKyAqICAgIERPTUV4Y2VwdGlvbiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgdG8gYmUgcmFpc2VkCisgKiAgICBpZiB0aGUgbm9kZSBpcyByZWFkb25seS4KKyAqICAgIAorICogICAgT2J0YWluIHRoZSBjaGlsZHJlbiBvZiB0aGUgVEhJUkQgImdlbmRlciIgZWxlbWVudC4gIFRoZSBlbGVtZW50cworICogICAgY29udGVudCBpcyBhbiBlbnRpdHkgcmVmZXJlbmNlLiAgVHJ5IHRvIHJlbW92ZSB0aGUgImRvbWVzdGljIiBhdHRyaWJ1dGUKKyAqICAgIGZyb20gdGhlIGVudGl0eSByZWZlcmVuY2UgYnkgZXhlY3V0aW5nIHRoZSAic2V0QXR0cmlidXRlKG5hbWUsdmFsdWUpIiBtZXRob2QuCisgKiAgICBUaGlzIGNhdXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gdG8gYmUgdGhyb3duLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC1GNjhGMDgyJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtRjY4RjA4MicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50c2V0YXR0cmlidXRlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50c2V0YXR0cmlidXRlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5vdEV4cGFuZEVudGl0eVJlZmVyZW5jZXMKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBnZW5kZXJMaXN0OworICAgICAgTm9kZSBnZW5kZXI7CisgICAgICBFbnRpdHlSZWZlcmVuY2UgZW50UmVmOworICAgICAgRWxlbWVudCBlbnRFbGVtZW50OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZ2VuZGVyTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZ2VuZGVyIik7CisgICAgICBnZW5kZXIgPSBnZW5kZXJMaXN0Lml0ZW0oMik7CisgICAgICBlbnRSZWYgPSAoRW50aXR5UmVmZXJlbmNlKSBnZW5kZXIuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50UmVmTm90TnVsbCIsIGVudFJlZik7CisgICAgICBlbnRFbGVtZW50ID0gKEVsZW1lbnQpIGVudFJlZi5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRFbGVtZW50Tm90TnVsbCIsIGVudEVsZW1lbnQpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbnRFbGVtZW50LnNldEF0dHJpYnV0ZSgibmV3QXR0ciIsICJuZXdWYWx1ZSIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRzZXRhdHRyaWJ1dGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMmJjY2IxCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YQpAQCAtMCwwICsxLDEwNyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldEF0dHJpYnV0ZShuYW1lLHZhbHVlKSIgbWV0aG9kIGZvciBhbiBhdHRyaWJ1dGUgY2F1c2VzIHRoZSAKKyAqICAgIERPTUV4Y2VwdGlvbiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgdG8gYmUgcmFpc2VkCisgKiAgICBpZiB0aGUgbm9kZSBpcyByZWFkb25seS4KKyAqICAgIAorICogICAgQWRkIGFuIGVudDQgcmVmZXJlbmNlIHRvIHRoZSBjaGlsZHJlbiBvZiB0aGUgVEhJUkQgImdlbmRlciIgZWxlbWVudC4gIAorICogICAgVHJ5IHRvIHJlbW92ZSB0aGUgImRvbWVzdGljIiBhdHRyaWJ1dGUKKyAqICAgIGZyb20gdGhlIGVudGl0eSByZWZlcmVuY2UgYnkgZXhlY3V0aW5nIHRoZSAic2V0QXR0cmlidXRlKG5hbWUsdmFsdWUpIiBtZXRob2QuCisgKiAgICBUaGlzIGNhdXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gdG8gYmUgdGhyb3duLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC1GNjhGMDgyJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtRjY4RjA4MicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWwiPmh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWw8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRzZXRhdHRyaWJ1dGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudHNldGF0dHJpYnV0ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyOworICAgICAgRW50aXR5UmVmZXJlbmNlIGVudFJlZjsKKyAgICAgIEVsZW1lbnQgZW50RWxlbWVudDsKKyAgICAgIE5vZGUgYXBwZW5kZWRDaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGdlbmRlckxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImdlbmRlciIpOworICAgICAgZ2VuZGVyID0gZ2VuZGVyTGlzdC5pdGVtKDIpOworICAgICAgZW50UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGdlbmRlci5hcHBlbmRDaGlsZChlbnRSZWYpOworICAgICAgZW50RWxlbWVudCA9IChFbGVtZW50KSBlbnRSZWYuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50RWxlbWVudE5vdE51bGwiLCBlbnRFbGVtZW50KTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgZW50RWxlbWVudC5zZXRBdHRyaWJ1dGUoIm5ld0F0dHIiLCAibmV3VmFsdWUiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRzZXRhdHRyaWJ1dGVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHdyb25nZG9jdW1lbnRlcnIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZWxlbWVudHdyb25nZG9jdW1lbnRlcnIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYzFhNTBiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbGVtZW50d3Jvbmdkb2N1bWVudGVyci5qYXZhCkBAIC0wLDAgKzEsMTEwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0QXR0cmlidXRlTm9kZShuZXdBdHRyKSIgbWV0aG9kIHJhaXNlcyBhbiAKKyAqICAgICJXUk9OR19ET0NVTUVOVF9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSAibmV3QXR0ciIgCisgKiAgICB3YXMgY3JlYXRlZCBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0CisgKiAgICBjcmVhdGVkIHRoaXMgZG9jdW1lbnQuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBsYXN0IGVtcGxveWVlIGFuZCBhdHRlbXB0IHRvIHNldCBhIG5ldworICogICAgYXR0cmlidXRlIG5vZGUgZm9yIGl0cyAiZW1wbG95ZWUiIGVsZW1lbnQuICBUaGUgbmV3CisgKiAgICBhdHRyaWJ1dGUgd2FzIGNyZWF0ZWQgZnJvbSBhIGRvY3VtZW50IG90aGVyIHRoYW4gdGhlCisgKiAgICBvbmUgdGhhdCBjcmVhdGVkIHRoaXMgZWxlbWVudCwgdGhlcmVmb3JlIGEKKyAqICAgIFdST05HX0RPQ1VNRU5UX0VSUiBET01FeGNlcHRpb24gc2hvdWxkIGJlIHJhaXNlZC4KKyAqICAgIFRoaXMgdGVzdCB1c2VzIHRoZSAiY3JlYXRlQXR0cmlidXRlKG5ld0F0dHIpIiBtZXRob2QKKyAqICAgIGZyb20gdGhlIERvY3VtZW50IGludGVyZmFjZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdXUk9OR19ET0NVTUVOVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdXUk9OR19ET0NVTUVOVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODg3MjM2MTU0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04ODcyMzYxNTQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTg4NzIzNjE1NCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J1dST05HX0RPQ1VNRU5UX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTg4NzIzNjE1NCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J1dST05HX0RPQ1VNRU5UX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50d3Jvbmdkb2N1bWVudGVyciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudHdyb25nZG9jdW1lbnRlcnIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jMTsKKyAgICAgIERvY3VtZW50IGRvYzI7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NFbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEFkZHJlc3M7CisgICAgICBBdHRyIGF0dHJBZGRyZXNzOworICAgICAgZG9jMSA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGRvYzIgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgbmV3QXR0cmlidXRlID0gZG9jMi5jcmVhdGVBdHRyaWJ1dGUoIm5ld0F0dHJpYnV0ZSIpOworICAgICAgYWRkcmVzc0VsZW1lbnRMaXN0ID0gZG9jMS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEFkZHJlc3MgPSAoRWxlbWVudCkgYWRkcmVzc0VsZW1lbnRMaXN0Lml0ZW0oNCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGF0dHJBZGRyZXNzID0gdGVzdEFkZHJlc3Muc2V0QXR0cmlidXRlTm9kZShuZXdBdHRyaWJ1dGUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfV1JPTkdfRE9DVU1FTlRfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VsZW1lbnR3cm9uZ2RvY3VtZW50ZXJyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50d3Jvbmdkb2N1bWVudGVyci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZW50aXR5Z2V0ZW50aXR5bmFtZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbnRpdHlnZXRlbnRpdHluYW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmUwNmRjNAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZW50aXR5Z2V0ZW50aXR5bmFtZS5qYXZhCkBAIC0wLDAgKzEsOTMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIG5vZGVOYW1lIGF0dHJpYnV0ZSB0aGF0IGlzIGluaGVyaXRlZCBmcm9tIE5vZGUgIAorICogICAgY29udGFpbnMgdGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGVudGl0eSBuYW1lZCAiZW50MSIgYW5kIGFjY2VzcyBpdHMgbmFtZSBieSAKKyAqICAgIGludm9raW5nIHRoZSAiZ2V0Tm9kZU5hbWUoKSIgbWV0aG9kIGluaGVyaXRlZCBmcm9tCisgKiAgICB0aGUgTm9kZSBpbnRlcmZhY2UuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC01MjdEQ0ZGMiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNTI3RENGRjI8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZW50aXR5Z2V0ZW50aXR5bmFtZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZW50aXR5Z2V0ZW50aXR5bmFtZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdHlMaXN0OworICAgICAgRW50aXR5IGVudGl0eU5vZGU7CisgICAgICBTdHJpbmcgZW50aXR5TmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImRvY1R5cGVOb3ROdWxsIiwgZG9jVHlwZSk7CisgICAgICBlbnRpdHlMaXN0ID0gZG9jVHlwZS5nZXRFbnRpdGllcygpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50aXRpZXNOb3ROdWxsIiwgZW50aXR5TGlzdCk7CisgICAgICBlbnRpdHlOb2RlID0gKEVudGl0eSkgZW50aXR5TGlzdC5nZXROYW1lZEl0ZW0oImVudDEiKTsKKyAgICAgIGVudGl0eU5hbWUgPSBlbnRpdHlOb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImVudGl0eUdldEVudGl0eU5hbWVBc3NlcnQiLCAiZW50MSIsIGVudGl0eU5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbnRpdHlnZXRlbnRpdHluYW1lIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbnRpdHlnZXRlbnRpdHluYW1lLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbnRpdHlnZXRwdWJsaWNpZC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9lbnRpdHlnZXRwdWJsaWNpZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVlMWU4N2MKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VudGl0eWdldHB1YmxpY2lkLmphdmEKQEAgLTAsMCArMSwxMDEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRQdWJsaWNJZCgpIiBtZXRob2Qgb2YgYW4gRW50aXR5IG5vZGUgY29udGFpbnMKKyAqICAgIHRoZSBwdWJsaWMgaWRlbnRpZmllciBhc3NvY2lhdGVkIHdpdGggdGhlIGVudGl0eSwgaWYKKyAqICAgIG9uZSB3YXMgc3BlY2lmaWVkLgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgZW50aXR5IG5hbWVkICJlbnQ1IiBhbmQgYWNjZXNzIGl0cyAgCisgKiAgICBwdWJsaWMgaWRlbnRpZmllci4gIFRoZSBzdHJpbmcgImVudGl0eVVSSSIgc2hvdWxkIGJlCisgKiAgICByZXR1cm5lZC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ3MzAzMDI1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENzMwMzAyNTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02QUJBRUIzOCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNkFCQUVCMzg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRDdDMjlGM0UiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ3QzI5RjNFPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbnRpdHlnZXRwdWJsaWNpZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZW50aXR5Z2V0cHVibGljaWQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBOYW1lZE5vZGVNYXAgZW50aXR5TGlzdDsKKyAgICAgIEVudGl0eSBlbnRpdHlOb2RlOworICAgICAgU3RyaW5nIHB1YmxpY0lkOworICAgICAgU3RyaW5nIHN5c3RlbUlkOworICAgICAgU3RyaW5nIG5vdGF0aW9uOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZG9jVHlwZU5vdE51bGwiLCBkb2NUeXBlKTsKKyAgICAgIGVudGl0eUxpc3QgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdGllc05vdE51bGwiLCBlbnRpdHlMaXN0KTsKKyAgICAgIGVudGl0eU5vZGUgPSAoRW50aXR5KSBlbnRpdHlMaXN0LmdldE5hbWVkSXRlbSgiZW50NSIpOworICAgICAgcHVibGljSWQgPSBlbnRpdHlOb2RlLmdldFB1YmxpY0lkKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInB1YmxpY0lkIiwgImVudGl0eVVSSSIsIHB1YmxpY0lkKTsKKyAgICAgIHN5c3RlbUlkID0gZW50aXR5Tm9kZS5nZXRTeXN0ZW1JZCgpOworICAgICAgYXNzZXJ0VVJJRXF1YWxzKCJzeXN0ZW1JZCIsIG51bGwsIG51bGwsIG51bGwsICJlbnRpdHlGaWxlIiwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgc3lzdGVtSWQpOworbm90YXRpb24gPSBlbnRpdHlOb2RlLmdldE5vdGF0aW9uTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub3RhdGlvbiIsICJub3RhdGlvbjEiLCBub3RhdGlvbik7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2VudGl0eWdldHB1YmxpY2lkIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbnRpdHlnZXRwdWJsaWNpZC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvZW50aXR5Z2V0cHVibGljaWRudWxsLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VudGl0eWdldHB1YmxpY2lkbnVsbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1MGQ1NGYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2VudGl0eWdldHB1YmxpY2lkbnVsbC5qYXZhCkBAIC0wLDAgKzEsOTQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRQdWJsaWNJZCgpIiBtZXRob2Qgb2YgYW4gRW50aXR5IG5vZGUgY29udGFpbnMKKyAqICAgIHRoZSBwdWJsaWMgaWRlbnRpZmllciBhc3NvY2lhdGVkIHdpdGggdGhlIGVudGl0eSwgaWYKKyAqICAgIG9uZSB3YXMgbm90IHNwZWNpZmllZCBhIG51bGwgdmFsdWUgc2hvdWxkIGJlIHJldHVybmVkLgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgZW50aXR5IG5hbWVkICJlbnQxIiBhbmQgYWNjZXNzIGl0cyAgCisgKiAgICBwdWJsaWMgaWRlbnRpZmllci4gIFNpbmNlIGEgcHVibGljIGlkZW50aWZpZXIgd2FzIG5vdAorICogICAgc3BlY2lmaWVkIGZvciB0aGlzIGVudGl0eSwgdGhlICJnZXRQdWJsaWNJZCgpIiBtZXRob2QgCisgKiAgICBzaG91bGQgcmV0dXJuIG51bGwuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENzMwMzAyNSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRDczMDMwMjU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVudGl0eWdldHB1YmxpY2lkbnVsbCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZW50aXR5Z2V0cHVibGljaWRudWxsKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTmFtZWROb2RlTWFwIGVudGl0eUxpc3Q7CisgICAgICBFbnRpdHkgZW50aXR5Tm9kZTsKKyAgICAgIFN0cmluZyBwdWJsaWNJZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImRvY1R5cGVOb3ROdWxsIiwgZG9jVHlwZSk7CisgICAgICBlbnRpdHlMaXN0ID0gZG9jVHlwZS5nZXRFbnRpdGllcygpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50aXRpZXNOb3ROdWxsIiwgZW50aXR5TGlzdCk7CisgICAgICBlbnRpdHlOb2RlID0gKEVudGl0eSkgZW50aXR5TGlzdC5nZXROYW1lZEl0ZW0oImVudDEiKTsKKyAgICAgIHB1YmxpY0lkID0gZW50aXR5Tm9kZS5nZXRQdWJsaWNJZCgpOworICAgICAgYXNzZXJ0TnVsbCgiZW50aXR5R2V0UHVibGljSWROdWxsQXNzZXJ0IiwgcHVibGljSWQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9lbnRpdHlnZXRwdWJsaWNpZG51bGwiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVudGl0eWdldHB1YmxpY2lkbnVsbC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmFwcGVuZGNoaWxkMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyYXBwZW5kY2hpbGQxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2QzZTY5NgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmFwcGVuZGNoaWxkMS5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQXBwZW5kcyBhIHRleHQgbm9kZSB0byBhbiBhdHRyaWJ1dGUgYW5kIGNoZWNrcyBpZiB0aGUgdmFsdWUgb2YKKyAqIHRoZSBhdHRyaWJ1dGUgaXMgY2hhbmdlZC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfYXR0cmFwcGVuZGNoaWxkMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfYXR0cmFwcGVuZGNoaWxkMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFjcm9ueW1MaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciB0aXRsZUF0dHI7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBUZXh0IHRleHROb2RlOworICAgICAgTm9kZSByZXR2YWw7CisgICAgICBOb2RlIGxhc3RDaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGFjcm9ueW1MaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFjcm9ueW1MaXN0Lml0ZW0oMyk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgdGl0bGVBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJ0aXRsZSIpOworICAgICAgdGV4dE5vZGUgPSBkb2MuY3JlYXRlVGV4dE5vZGUoInRlcmRheSIpOworICAgICAgcmV0dmFsID0gdGl0bGVBdHRyLmFwcGVuZENoaWxkKHRleHROb2RlKTsKKyAgICAgIHZhbHVlID0gdGl0bGVBdHRyLmdldFZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJWYWx1ZSIsICJZZXN0ZXJkYXkiLCB2YWx1ZSk7CisgICAgICB2YWx1ZSA9IHRpdGxlQXR0ci5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0ck5vZGVWYWx1ZSIsICJZZXN0ZXJkYXkiLCB2YWx1ZSk7CisgICAgICB2YWx1ZSA9IHJldHZhbC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygicmV0dmFsVmFsdWUiLCAidGVyZGF5IiwgdmFsdWUpOworICAgICAgbGFzdENoaWxkID0gdGl0bGVBdHRyLmdldExhc3RDaGlsZCgpOworICAgICAgdmFsdWUgPSBsYXN0Q2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImxhc3RDaGlsZFZhbHVlIiwgInRlcmRheSIsIHZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cmFwcGVuZGNoaWxkMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfYXR0cmFwcGVuZGNoaWxkMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmFwcGVuZGNoaWxkMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyYXBwZW5kY2hpbGQyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzYxOWVkOAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmFwcGVuZGNoaWxkMi5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBdHRlbXB0cyB0byBhcHBlbmQgYW4gZWxlbWVudCB0byB0aGUgY2hpbGQgbm9kZXMgb2YgYW4gYXR0cmlidXRlLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19hdHRyYXBwZW5kY2hpbGQyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19hdHRyYXBwZW5kY2hpbGQyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWNyb255bUxpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIHRpdGxlQXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIE5vZGUgbmV3Q2hpbGQ7CisgICAgICBOb2RlIHJldHZhbDsKKyAgICAgIE5vZGUgbGFzdENoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgYWNyb255bUxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3ROb2RlID0gYWNyb255bUxpc3QuaXRlbSgzKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICB0aXRsZUF0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oInRpdGxlIik7CisgICAgICBuZXdDaGlsZCA9IGRvYy5jcmVhdGVFbGVtZW50KCJ0ZXJkYXkiKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dmFsID0gdGl0bGVBdHRyLmFwcGVuZENoaWxkKG5ld0NoaWxkKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0hJRVJBUkNIWV9SRVFVRVNUX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRyYXBwZW5kY2hpbGQyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRyYXBwZW5kY2hpbGQyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyYXBwZW5kY2hpbGQzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJhcHBlbmRjaGlsZDMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZmEwMWNhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyYXBwZW5kY2hpbGQzLmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBcHBlbmRzIGEgZG9jdW1lbnQgZnJhZ21lbnQgdG8gYW4gYXR0cmlidXRlIGFuZCBjaGVja3MgaWYgdGhlIHZhbHVlIG9mCisgKiB0aGUgYXR0cmlidXRlIGlzIGNoYW5nZWQuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2F0dHJhcHBlbmRjaGlsZDMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2F0dHJhcHBlbmRjaGlsZDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhY3JvbnltTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgdGl0bGVBdHRyOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgVGV4dCB0ZXJOb2RlOworICAgICAgVGV4dCBkYXlOb2RlOworICAgICAgTm9kZSByZXR2YWw7CisgICAgICBOb2RlIGxhc3RDaGlsZDsKKyAgICAgIERvY3VtZW50RnJhZ21lbnQgZG9jRnJhZzsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGFjcm9ueW1MaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFjcm9ueW1MaXN0Lml0ZW0oMyk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgdGl0bGVBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJ0aXRsZSIpOworICAgICAgdGVyTm9kZSA9IGRvYy5jcmVhdGVUZXh0Tm9kZSgidGVyIik7CisgICAgICBkYXlOb2RlID0gZG9jLmNyZWF0ZVRleHROb2RlKCJkYXkiKTsKKyAgICAgIGRvY0ZyYWcgPSBkb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOworICAgICAgcmV0dmFsID0gZG9jRnJhZy5hcHBlbmRDaGlsZCh0ZXJOb2RlKTsKKyAgICAgIHJldHZhbCA9IGRvY0ZyYWcuYXBwZW5kQ2hpbGQoZGF5Tm9kZSk7CisgICAgICByZXR2YWwgPSB0aXRsZUF0dHIuYXBwZW5kQ2hpbGQoZG9jRnJhZyk7CisgICAgICB2YWx1ZSA9IHRpdGxlQXR0ci5nZXRWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyVmFsdWUiLCAiWWVzdGVyZGF5IiwgdmFsdWUpOworICAgICAgdmFsdWUgPSB0aXRsZUF0dHIuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJOb2RlVmFsdWUiLCAiWWVzdGVyZGF5IiwgdmFsdWUpOworICAgICAgdmFsdWUgPSByZXR2YWwuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJyZXR2YWxWYWx1ZSIsIHZhbHVlKTsKKyAgICAgIGxhc3RDaGlsZCA9IHRpdGxlQXR0ci5nZXRMYXN0Q2hpbGQoKTsKKyAgICAgIHZhbHVlID0gbGFzdENoaWxkLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJsYXN0Q2hpbGRWYWx1ZSIsICJkYXkiLCB2YWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJhcHBlbmRjaGlsZDMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2F0dHJhcHBlbmRjaGlsZDMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJhcHBlbmRjaGlsZDQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmFwcGVuZGNoaWxkNC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZiNzRlYmYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJhcHBlbmRjaGlsZDQuamF2YQpAQCAtMCwwICsxLDExOCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEF0dGVtcHQgdG8gYXBwZW5kIGEgQ0RBVEFTZWN0aW9uIHRvIGFuIGF0dHJpYnV0ZSB3aGljaCBzaG91bGQgcmVzdWx0CisgKiBpbiBhIEhJRVJBUkNIWV9SRVFVRVNUX0VSUi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfYXR0cmFwcGVuZGNoaWxkNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfYXR0cmFwcGVuZGNoaWxkNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKyAgICAgIGlmIChmYWN0b3J5Lmhhc0ZlYXR1cmUoIlhNTCIsIG51bGwpICE9IHRydWUpIHsKKyAgICAgICAgIHRocm93IG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbi5pbmNvbXBhdGlibGVGZWF0dXJlKCJYTUwiLCBudWxsKTsKKyAgICAgIH0KKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFjcm9ueW1MaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciB0aXRsZUF0dHI7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBOb2RlIHRleHROb2RlOworICAgICAgTm9kZSByZXR2YWw7CisgICAgICBOb2RlIGxhc3RDaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGFjcm9ueW1MaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFjcm9ueW1MaXN0Lml0ZW0oMyk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgdGl0bGVBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJ0aXRsZSIpOworICAgICAgCisgICAgICBpZiAoKCJ0ZXh0L2h0bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpIHsKKyAgICAgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRleHROb2RlID0gZG9jLmNyZWF0ZUNEQVRBU2VjdGlvbigidGVyZGF5Iik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9TVVBQT1JURURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9IGVsc2UgeworICAgICAgICAgIHRleHROb2RlID0gZG9jLmNyZWF0ZUNEQVRBU2VjdGlvbigidGVyZGF5Iik7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHZhbCA9IHRpdGxlQXR0ci5hcHBlbmRDaGlsZCh0ZXh0Tm9kZSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19ISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRyYXBwZW5kY2hpbGQ0IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRyYXBwZW5kY2hpbGQ0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyYXBwZW5kY2hpbGQ1LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJhcHBlbmRjaGlsZDUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNjg0NmUxCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyYXBwZW5kY2hpbGQ1LmphdmEKQEAgLTAsMCArMSwxMDMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBdHRlbXB0IHRvIGFwcGVuZCBhIG5vZGUgZnJvbSBhbm90aGVyIGRvY3VtZW50IHRvIGFuIGF0dHJpYnV0ZSB3aGljaCBzaG91bGQgcmVzdWx0CisgKiBpbiBhIFdST05HX0RPQ1VNRU5UX0VSUi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfYXR0cmFwcGVuZGNoaWxkNSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfYXR0cmFwcGVuZGNoaWxkNShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFjcm9ueW1MaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciB0aXRsZUF0dHI7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBOb2RlIHRleHROb2RlOworICAgICAgTm9kZSByZXR2YWw7CisgICAgICBOb2RlIGxhc3RDaGlsZDsKKyAgICAgIERvY3VtZW50IG90aGVyRG9jOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgb3RoZXJEb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBhY3JvbnltTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdE5vZGUgPSBhY3JvbnltTGlzdC5pdGVtKDMpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3ROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHRpdGxlQXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgidGl0bGUiKTsKKyAgICAgIHRleHROb2RlID0gb3RoZXJEb2MuY3JlYXRlVGV4dE5vZGUoInRlcmRheSIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR2YWwgPSB0aXRsZUF0dHIuYXBwZW5kQ2hpbGQodGV4dE5vZGUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfV1JPTkdfRE9DVU1FTlRfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJhcHBlbmRjaGlsZDUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2F0dHJhcHBlbmRjaGlsZDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJhcHBlbmRjaGlsZDYuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmFwcGVuZGNoaWxkNi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc1NGJhMmIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJhcHBlbmRjaGlsZDYuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQ3JlYXRlcyBhbiBuZXcgYXR0cmlidXRlIG5vZGUgYW5kIGFwcGVuZHMgYSB0ZXh0IG5vZGUuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2F0dHJhcHBlbmRjaGlsZDYgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2F0dHJhcHBlbmRjaGlsZDYoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhY3JvbnltTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgdGl0bGVBdHRyOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgVGV4dCB0ZXh0Tm9kZTsKKyAgICAgIE5vZGUgcmV0dmFsOworICAgICAgTm9kZSBsYXN0Q2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICB0aXRsZUF0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJ0aXRsZSIpOworICAgICAgdGV4dE5vZGUgPSBkb2MuY3JlYXRlVGV4dE5vZGUoIlllc3RlcmRheSIpOworICAgICAgcmV0dmFsID0gdGl0bGVBdHRyLmFwcGVuZENoaWxkKHRleHROb2RlKTsKKyAgICAgIHZhbHVlID0gdGl0bGVBdHRyLmdldFZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJWYWx1ZSIsICJZZXN0ZXJkYXkiLCB2YWx1ZSk7CisgICAgICB2YWx1ZSA9IHRpdGxlQXR0ci5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0ck5vZGVWYWx1ZSIsICJZZXN0ZXJkYXkiLCB2YWx1ZSk7CisgICAgICB2YWx1ZSA9IHJldHZhbC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygicmV0dmFsVmFsdWUiLCAiWWVzdGVyZGF5IiwgdmFsdWUpOworICAgICAgbGFzdENoaWxkID0gdGl0bGVBdHRyLmdldExhc3RDaGlsZCgpOworICAgICAgdmFsdWUgPSBsYXN0Q2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImxhc3RDaGlsZFZhbHVlIiwgIlllc3RlcmRheSIsIHZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cmFwcGVuZGNoaWxkNiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfYXR0cmFwcGVuZGNoaWxkNi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmNoaWxkbm9kZXMxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJjaGlsZG5vZGVzMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiMzhmYmIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJjaGlsZG5vZGVzMS5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBDaGVja3MgdGhhdCBOb2RlLmNoaWxkTm9kZXMgZm9yIGFuIGF0dHJpYnV0ZSBub2RlIGNvbnRhaW5zCisgKiB0aGUgZXhwZWN0ZWQgdGV4dCBub2RlLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTQ1MTQ2MDk4NyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTQ1MTQ2MDk4NzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfYXR0cmNoaWxkbm9kZXMxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19hdHRyY2hpbGRub2RlczEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWNyb255bUxpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIHRpdGxlQXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIFRleHQgdGV4dE5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZE5vZGVzOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGFjcm9ueW1MaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFjcm9ueW1MaXN0Lml0ZW0oMyk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgdGl0bGVBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJ0aXRsZSIpOworICAgICAgY2hpbGROb2RlcyA9IHRpdGxlQXR0ci5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBhc3NlcnRTaXplKCJjaGlsZE5vZGVzU2l6ZSIsIDEsIGNoaWxkTm9kZXMpOworICAgICAgdGV4dE5vZGUgPSAoVGV4dCkgY2hpbGROb2Rlcy5pdGVtKDApOworICAgICAgdmFsdWUgPSB0ZXh0Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2hpbGQxSXNZZXMiLCAiWWVzIiwgdmFsdWUpOworICAgICAgdGV4dE5vZGUgPSAoVGV4dCkgY2hpbGROb2Rlcy5pdGVtKDEpOworICAgICAgYXNzZXJ0TnVsbCgic2Vjb25kSXRlbUlzTnVsbCIsIHRleHROb2RlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cmNoaWxkbm9kZXMxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRyY2hpbGRub2RlczEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJjaGlsZG5vZGVzMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyY2hpbGRub2RlczIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MjUxNzdhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyY2hpbGRub2RlczIuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIENoZWNrcyBOb2RlLmNoaWxkTm9kZXMgZm9yIGFuIGF0dHJpYnV0ZSB3aXRoIG11bHRpcGxlIGNoaWxkIG5vZGVzLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTQ1MTQ2MDk4NyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTQ1MTQ2MDk4NzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfYXR0cmNoaWxkbm9kZXMyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19hdHRyY2hpbGRub2RlczIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhY3JvbnltTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgdGl0bGVBdHRyOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgVGV4dCB0ZXh0Tm9kZTsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTm9kZXM7CisgICAgICBOb2RlIHJldHZhbDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGFjcm9ueW1MaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFjcm9ueW1MaXN0Lml0ZW0oMyk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgdGl0bGVBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJ0aXRsZSIpOworICAgICAgY2hpbGROb2RlcyA9IHRpdGxlQXR0ci5nZXRDaGlsZE5vZGVzKCk7CisgICAgICB0ZXh0Tm9kZSA9IGRvYy5jcmVhdGVUZXh0Tm9kZSgidGVyZGF5Iik7CisgICAgICByZXR2YWwgPSB0aXRsZUF0dHIuYXBwZW5kQ2hpbGQodGV4dE5vZGUpOworICAgICAgYXNzZXJ0U2l6ZSgiY2hpbGROb2Rlc1NpemUiLCAyLCBjaGlsZE5vZGVzKTsKKyAgICAgIHRleHROb2RlID0gKFRleHQpIGNoaWxkTm9kZXMuaXRlbSgwKTsKKyAgICAgIHZhbHVlID0gdGV4dE5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoaWxkMUlzWWVzIiwgIlllcyIsIHZhbHVlKTsKKyAgICAgIHRleHROb2RlID0gKFRleHQpIGNoaWxkTm9kZXMuaXRlbSgxKTsKKyAgICAgIHZhbHVlID0gdGV4dE5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoaWxkMklzVGVyZGF5IiwgInRlcmRheSIsIHZhbHVlKTsKKyAgICAgIHRleHROb2RlID0gKFRleHQpIGNoaWxkTm9kZXMuaXRlbSgyKTsKKyAgICAgIGFzc2VydE51bGwoInRoaXJkSXRlbUlzTnVsbCIsIHRleHROb2RlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cmNoaWxkbm9kZXMyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRyY2hpbGRub2RlczIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJjbG9uZW5vZGUxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJjbG9uZW5vZGUxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzM4YTY3MwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmNsb25lbm9kZTEuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEFwcGVuZHMgYSB0ZXh0IG5vZGUgdG8gYW4gYXR0cmlidXRlIGFuZCBjbG9uZXMgdGhlIG5vZGUuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zQTBFRDBBNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtM0EwRUQwQTQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2F0dHJjbG9uZW5vZGUxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19hdHRyY2xvbmVub2RlMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFjcm9ueW1MaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciB0aXRsZUF0dHI7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBUZXh0IHRleHROb2RlOworICAgICAgTm9kZSByZXR2YWw7CisgICAgICBOb2RlIGxhc3RDaGlsZDsKKyAgICAgIEF0dHIgY2xvbmVkVGl0bGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBhY3JvbnltTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdE5vZGUgPSBhY3JvbnltTGlzdC5pdGVtKDMpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3ROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHRpdGxlQXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgidGl0bGUiKTsKKyAgICAgIHRleHROb2RlID0gZG9jLmNyZWF0ZVRleHROb2RlKCJ0ZXJkYXkiKTsKKyAgICAgIHJldHZhbCA9IHRpdGxlQXR0ci5hcHBlbmRDaGlsZCh0ZXh0Tm9kZSk7CisgICAgICBjbG9uZWRUaXRsZSA9IChBdHRyKSB0aXRsZUF0dHIuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgIHRleHROb2RlLnNldE5vZGVWYWx1ZSgidGV4dF9ub2RlX25vdF9jbG9uZWQiKTsKKyAgICAgIHZhbHVlID0gY2xvbmVkVGl0bGUuZ2V0VmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0clZhbHVlIiwgIlllc3RlcmRheSIsIHZhbHVlKTsKKyAgICAgIHZhbHVlID0gY2xvbmVkVGl0bGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJOb2RlVmFsdWUiLCAiWWVzdGVyZGF5IiwgdmFsdWUpOworICAgICAgbGFzdENoaWxkID0gY2xvbmVkVGl0bGUuZ2V0TGFzdENoaWxkKCk7CisgICAgICB2YWx1ZSA9IGxhc3RDaGlsZC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibGFzdENoaWxkVmFsdWUiLCAidGVyZGF5IiwgdmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRyY2xvbmVub2RlMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfYXR0cmNsb25lbm9kZTEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJjcmVhdGVkb2N1bWVudGZyYWdtZW50LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJjcmVhdGVkb2N1bWVudGZyYWdtZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmU0NDQ2NQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmNyZWF0ZWRvY3VtZW50ZnJhZ21lbnQuamF2YQpAQCAtMCwwICsxLDEwNSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgQ3JlYXRlIGEgbmV3IERvY3VtZW50RnJhZ21lbnQgYW5kIGFkZCBhIG5ld2x5IGNyZWF0ZWQgRWxlbWVudCBub2RlKHdpdGggb25lIGF0dHJpYnV0ZSkuICAKKyAqICAgT25jZSB0aGUgZWxlbWVudCBpcyBhZGRlZCwgaXRzIGF0dHJpYnV0ZSBzaG91bGQgYmUgYXZhaWxhYmxlIGFzIGFuIGF0dHJpYnV0ZSBhc3NvY2lhdGVkIAorICogICB3aXRoIGFuIEVsZW1lbnQgd2l0aGluIGEgRG9jdW1lbnRGcmFnbWVudC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM1Q0IwNEI1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zNUNCMDRCNTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUI2M0VEMUEzIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1CNjNFRDFBMzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjM2Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjM2PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9saXN0cy53My5vcmcvQXJjaGl2ZXMvUHVibGljL3d3dy1kb20tdHMvMjAwM0p1bi8wMDExLmh0bWwiPmh0dHA6Ly9saXN0cy53My5vcmcvQXJjaGl2ZXMvUHVibGljL3d3dy1kb20tdHMvMjAwM0p1bi8wMDExLmh0bWw8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTE4NCI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTE4NDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfYXR0cmNyZWF0ZWRvY3VtZW50ZnJhZ21lbnQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2F0dHJjcmVhdGVkb2N1bWVudGZyYWdtZW50KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRGcmFnbWVudCBkb2NGcmFnbWVudDsKKyAgICAgIEVsZW1lbnQgbmV3T25lOworICAgICAgTm9kZSBkb21lc3RpY05vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgU3RyaW5nIGF0dHJOYW1lOworICAgICAgTm9kZSBhcHBlbmRlZENoaWxkOworICAgICAgaW50IGxhbmdBdHRyQ291bnQgPSAwOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZG9jRnJhZ21lbnQgPSBkb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOworICAgICAgbmV3T25lID0gZG9jLmNyZWF0ZUVsZW1lbnQoImh0bWwiKTsKKyAgICAgIG5ld09uZS5zZXRBdHRyaWJ1dGUoImxhbmciLCAiRU4iKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBkb2NGcmFnbWVudC5hcHBlbmRDaGlsZChuZXdPbmUpOworICAgICAgZG9tZXN0aWNOb2RlID0gZG9jRnJhZ21lbnQuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXR0cmlidXRlcyA9IGRvbWVzdGljTm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA3OCA9IDA7IGluZGV4TjEwMDc4IDwgYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwNzgrKykgeworICAgICAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLml0ZW0oaW5kZXhOMTAwNzgpOworICAgIGF0dHJOYW1lID0gYXR0cmlidXRlLmdldE5vZGVOYW1lKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHNBdXRvQ2FzZSgiYXR0cmlidXRlIiwgImxhbmciLCBhdHRyTmFtZSkpIHsKKyAgICAgICAgICBsYW5nQXR0ckNvdW50ICs9IDE7CisgICAgICB9CisgICAgICB9CisgICAgICBhc3NlcnRFcXVhbHMoImhhc0xhbmdBdHRyIiwgMSwgbGFuZ0F0dHJDb3VudCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJjcmVhdGVkb2N1bWVudGZyYWdtZW50IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRyY3JlYXRlZG9jdW1lbnRmcmFnbWVudC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmNyZWF0ZXRleHRub2RlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJjcmVhdGV0ZXh0bm9kZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIwZWI1ZGEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJjcmVhdGV0ZXh0bm9kZS5qYXZhCkBAIC0wLDAgKzEsOTcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0VmFsdWUoKSIgbWV0aG9kIGZvciBhbiBhdHRyaWJ1dGUgY3JlYXRlcyBhIAorICogICBUZXh0IG5vZGUgd2l0aCB0aGUgdW5wYXJzZWQgY29udGVudCBvZiB0aGUgc3RyaW5nLgorICogICBSZXRyaWV2ZSB0aGUgYXR0cmlidXRlIG5hbWVkICJjbGFzcyIgZnJvbSB0aGUgbGFzdCAKKyAqICAgY2hpbGQgb2Ygb2YgdGhlIGZvdXJ0aCBlbXBsb3llZSBhbmQgYXNzaWduIHRoZSAiWSZlbnQxOyIgCisgKiAgIHN0cmluZyB0byBpdHMgdmFsdWUgYXR0cmlidXRlLiAgVGhpcyB2YWx1ZSBpcyBub3QgeWV0CisgKiAgIHBhcnNlZCBhbmQgdGhlcmVmb3JlIHNob3VsZCBzdGlsbCBiZSB0aGUgc2FtZSB1cG9uCisgKiAgIHJldHJpZXZhbC4gVGhpcyB0ZXN0IHVzZXMgdGhlICJnZXROYW1lZEl0ZW0obmFtZSkiIG1ldGhvZAorICogICBmcm9tIHRoZSBOYW1lZE5vZGVNYXAgaW50ZXJmYWNlLiAgCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMjE2NjI0NzQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIyMTY2MjQ3NDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDJBcHIvMDA1Ny5odG1sIj5odHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDJBcHIvMDA1Ny5odG1sPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19hdHRyY3JlYXRldGV4dG5vZGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2F0dHJjcmVhdGV0ZXh0bm9kZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NMaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBzdHJlZXRBdHRyOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgYWRkcmVzc0xpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3ROb2RlID0gYWRkcmVzc0xpc3QuaXRlbSgzKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBzdHJlZXRBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJjbGFzcyIpOworICAgICAgc3RyZWV0QXR0ci5zZXRWYWx1ZSgiWSZlbnQxOyIpOworICAgICAgdmFsdWUgPSBzdHJlZXRBdHRyLmdldFZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlIiwgIlkmZW50MTsiLCB2YWx1ZSk7CisgICAgICB2YWx1ZSA9IHN0cmVldEF0dHIuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVWYWx1ZSIsICJZJmVudDE7IiwgdmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRyY3JlYXRldGV4dG5vZGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2F0dHJjcmVhdGV0ZXh0bm9kZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmNyZWF0ZXRleHRub2RlMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyY3JlYXRldGV4dG5vZGUyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjQ4N2Q2OQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmNyZWF0ZXRleHRub2RlMi5qYXZhCkBAIC0wLDAgKzEsOTcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0Tm9kZVZhbHVlKCkiIG1ldGhvZCBmb3IgYW4gYXR0cmlidXRlIGNyZWF0ZXMgYSAKKyAqICAgVGV4dCBub2RlIHdpdGggdGhlIHVucGFyc2VkIGNvbnRlbnQgb2YgdGhlIHN0cmluZy4KKyAqICAgUmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBuYW1lZCAiY2xhc3MiIGZyb20gdGhlIGxhc3QgCisgKiAgIGNoaWxkIG9mIG9mIHRoZSBmb3VydGggZW1wbG95ZWUgYW5kIGFzc2lnbiB0aGUgIlkmZW50MTsiIAorICogICBzdHJpbmcgdG8gaXRzIHZhbHVlIGF0dHJpYnV0ZS4gIFRoaXMgdmFsdWUgaXMgbm90IHlldAorICogICBwYXJzZWQgYW5kIHRoZXJlZm9yZSBzaG91bGQgc3RpbGwgYmUgdGhlIHNhbWUgdXBvbgorICogICByZXRyaWV2YWwuIFRoaXMgdGVzdCB1c2VzIHRoZSAiZ2V0TmFtZWRJdGVtKG5hbWUpIiBtZXRob2QKKyAqICAgZnJvbSB0aGUgTmFtZWROb2RlTWFwIGludGVyZmFjZS4gCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9saXN0cy53My5vcmcvQXJjaGl2ZXMvUHVibGljL3d3dy1kb20tdHMvMjAwMkFwci8wMDU3Lmh0bWwiPmh0dHA6Ly9saXN0cy53My5vcmcvQXJjaGl2ZXMvUHVibGljL3d3dy1kb20tdHMvMjAwMkFwci8wMDU3Lmh0bWw8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2F0dHJjcmVhdGV0ZXh0bm9kZTIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2F0dHJjcmVhdGV0ZXh0bm9kZTIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhZGRyZXNzTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgc3RyZWV0QXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGFkZHJlc3NMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFkZHJlc3NMaXN0Lml0ZW0oMyk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgc3RyZWV0QXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgiY2xhc3MiKTsKKyAgICAgIHN0cmVldEF0dHIuc2V0Tm9kZVZhbHVlKCJZJmVudDE7Iik7CisgICAgICB2YWx1ZSA9IHN0cmVldEF0dHIuZ2V0VmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygidmFsdWUiLCAiWSZlbnQxOyIsIHZhbHVlKTsKKyAgICAgIHZhbHVlID0gc3RyZWV0QXR0ci5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZVZhbHVlIiwgIlkmZW50MTsiLCB2YWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJjcmVhdGV0ZXh0bm9kZTIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2F0dHJjcmVhdGV0ZXh0bm9kZTIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJlZmZlY3RpdmV2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyZWZmZWN0aXZldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOTA5NDRiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyZWZmZWN0aXZldmFsdWUuamF2YQpAQCAtMCwwICsxLDkwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBJZiBhbiBBdHRyIGlzIGV4cGxpY2l0bHkgYXNzaWduZWQgYW55IHZhbHVlLCB0aGVuIHRoYXQgdmFsdWUgaXMgdGhlIGF0dHJpYnV0ZXMgZWZmZWN0aXZlIHZhbHVlLgorICogICBSZXRyaWV2ZSB0aGUgYXR0cmlidXRlIG5hbWVkICJkb21lc3RpYyIgZnJvbSB0aGUgbGFzdCBjaGlsZCBvZiBvZiB0aGUgZmlyc3QgZW1wbG95ZWUgCisgKiAgIGFuZCBleGFtaW5lIGl0cyBub2RlVmFsdWUgYXR0cmlidXRlLiAgVGhpcyB0ZXN0IHVzZXMgdGhlICJnZXROYW1lZEl0ZW0obmFtZSkiIG1ldGhvZCAKKyAqICAgZnJvbSB0aGUgTmFtZWROb2RlTWFwIGludGVyZmFjZS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA3NDU3NzU0OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA3NDU3NzU0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfYXR0cmVmZmVjdGl2ZXZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19hdHRyZWZmZWN0aXZldmFsdWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWRkcmVzc0xpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIGRvbWVzdGljQXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBhZGRyZXNzTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdE5vZGUgPSBhZGRyZXNzTGlzdC5pdGVtKDApOworICAgICAgYXR0cmlidXRlcyA9IHRlc3ROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGRvbWVzdGljQXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgidGl0bGUiKTsKKyAgICAgIHZhbHVlID0gZG9tZXN0aWNBdHRyLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyRWZmZWN0aXZlVmFsdWVBc3NlcnQiLCAiWWVzIiwgdmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRyZWZmZWN0aXZldmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2F0dHJlZmZlY3RpdmV2YWx1ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmZpcnN0Y2hpbGQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmZpcnN0Y2hpbGQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lN2RhM2I4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyZmlyc3RjaGlsZC5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBDaGVja3MgdGhhdCBOb2RlLmZpcnN0Q2hpbGQgZm9yIGFuIGF0dHJpYnV0ZSBub2RlIGNvbnRhaW5zCisgKiB0aGUgZXhwZWN0ZWQgdGV4dCBub2RlLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTY5NzI3Mzg4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNjk3MjczODg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2F0dHJmaXJzdGNoaWxkIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19hdHRyZmlyc3RjaGlsZChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFjcm9ueW1MaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciB0aXRsZUF0dHI7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBUZXh0IHRleHROb2RlOworICAgICAgTm9kZSBvdGhlckNoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgYWNyb255bUxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3ROb2RlID0gYWNyb255bUxpc3QuaXRlbSgzKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICB0aXRsZUF0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oInRpdGxlIik7CisgICAgICB0ZXh0Tm9kZSA9IChUZXh0KSB0aXRsZUF0dHIuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgidGV4dE5vZGVOb3ROdWxsIiwgdGV4dE5vZGUpOworICAgICAgdmFsdWUgPSB0ZXh0Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2hpbGQxSXNZZXMiLCAiWWVzIiwgdmFsdWUpOworICAgICAgb3RoZXJDaGlsZCA9IHRleHROb2RlLmdldE5leHRTaWJsaW5nKCk7CisgICAgICBhc3NlcnROdWxsKCJuZXh0U2libGluZ0lzTnVsbCIsIG90aGVyQ2hpbGQpOworICAgICAgb3RoZXJDaGlsZCA9IHRleHROb2RlLmdldFByZXZpb3VzU2libGluZygpOworICAgICAgYXNzZXJ0TnVsbCgicHJldmlvdXNTaWJsaW5nSXNOdWxsIiwgb3RoZXJDaGlsZCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJmaXJzdGNoaWxkIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRyZmlyc3RjaGlsZC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmdldHZhbHVlMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyZ2V0dmFsdWUxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjM0ODRkYQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmdldHZhbHVlMS5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBDaGVja3MgdGhlIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSB0aGF0IGNvbnRhaW5zIGVudGl0eSByZWZlcmVuY2VzLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjIxNjYyNDc0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMjE2NjI0NzQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2F0dHJnZXR2YWx1ZTEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2F0dHJnZXR2YWx1ZTEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhY3JvbnltTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgdGl0bGVBdHRyOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgVGV4dCB0ZXh0Tm9kZTsKKyAgICAgIE5vZGUgcmV0dmFsOworICAgICAgTm9kZSBsYXN0Q2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBhY3JvbnltTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdE5vZGUgPSBhY3JvbnltTGlzdC5pdGVtKDMpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3ROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHRpdGxlQXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgiY2xhc3MiKTsKKyAgICAgIHZhbHVlID0gdGl0bGVBdHRyLmdldFZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJWYWx1ZTEiLCAiWVx1MDNiMSIsIHZhbHVlKTsgLy8gYW5kcm9pZC1jaGFuZ2VkOiBHUkVFSyBMT1dFUiBDQVNFIEFMUEhBCisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJnZXR2YWx1ZTEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2F0dHJnZXR2YWx1ZTEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJnZXR2YWx1ZTIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmdldHZhbHVlMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgxNGI2OTMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJnZXR2YWx1ZTIuamF2YQpAQCAtMCwwICsxLDExMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIENoZWNrcyB0aGUgdmFsdWUgb2YgYW4gYXR0cmlidXRlIHRoYXQgY29udGFpbnMgZW50aXR5IHJlZmVyZW5jZXMuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMjE2NjI0NzQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIyMTY2MjQ3NDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfYXR0cmdldHZhbHVlMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfYXR0cmdldHZhbHVlMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKyAgICAgIGlmIChmYWN0b3J5Lmhhc0ZlYXR1cmUoIlhNTCIsIG51bGwpICE9IHRydWUpIHsKKyAgICAgICAgIHRocm93IG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbi5pbmNvbXBhdGlibGVGZWF0dXJlKCJYTUwiLCBudWxsKTsKKyAgICAgIH0KKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFjcm9ueW1MaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciB0aXRsZUF0dHI7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBUZXh0IHRleHROb2RlOworICAgICAgTm9kZSByZXR2YWw7CisgICAgICBOb2RlIGZpcnN0Q2hpbGQ7CisgICAgICBFbnRpdHlSZWZlcmVuY2UgYWxwaGFSZWY7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBhY3JvbnltTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdE5vZGUgPSBhY3JvbnltTGlzdC5pdGVtKDMpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3ROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHRpdGxlQXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgiY2xhc3MiKTsKKyAgICAgIAorICAgICAgaWYgKCgidGV4dC9odG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKSB7CisgICAgICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhbHBoYVJlZiA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImFscGhhIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9TVVBQT1JURURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9IGVsc2UgeworICAgICAgICAgIGFscGhhUmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiYWxwaGEiKTsKKyAgICAgIGZpcnN0Q2hpbGQgPSB0aXRsZUF0dHIuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgcmV0dmFsID0gdGl0bGVBdHRyLmluc2VydEJlZm9yZShhbHBoYVJlZiwgZmlyc3RDaGlsZCk7CisgICAgICB2YWx1ZSA9IHRpdGxlQXR0ci5nZXRWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyVmFsdWUxIiwgIlx1MDNiMVlcdTAzYjEiLCB2YWx1ZSk7IC8vIGFuZHJvaWQtY2hhbmdlZDogR1JFRUsgTE9XRVIgQ0FTRSBBTFBIQQorICAgICAgfQorICAgICAgICAKKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJnZXR2YWx1ZTIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2F0dHJnZXR2YWx1ZTIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJoYXNjaGlsZG5vZGVzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJoYXNjaGlsZG5vZGVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDRjNjVmNgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmhhc2NoaWxkbm9kZXMuamF2YQpAQCAtMCwwICsxLDg3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQ2hlY2tzIHRoYXQgTm9kZS5oYXNDaGlsZE5vZGVzKCkgaXMgdHJ1ZSBmb3IgYW4gYXR0cmlidXRlIHdpdGggY29udGVudC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTgxMDU5NDE4NyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODEwNTk0MTg3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19hdHRyaGFzY2hpbGRub2RlcyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfYXR0cmhhc2NoaWxkbm9kZXMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhY3JvbnltTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgdGl0bGVBdHRyOworICAgICAgYm9vbGVhbiBoYXNDaGlsZE5vZGVzOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgYWNyb255bUxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3ROb2RlID0gYWNyb255bUxpc3QuaXRlbSgzKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICB0aXRsZUF0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oInRpdGxlIik7CisgICAgICBoYXNDaGlsZE5vZGVzID0gdGl0bGVBdHRyLmhhc0NoaWxkTm9kZXMoKTsKKyAgICAgIGFzc2VydFRydWUoImhhc0NoaWxkcmVuSXNUcnVlIiwgaGFzQ2hpbGROb2Rlcyk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJoYXNjaGlsZG5vZGVzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRyaGFzY2hpbGRub2Rlcy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmluc2VydGJlZm9yZTEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmluc2VydGJlZm9yZTEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNjcxMTQ4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyaW5zZXJ0YmVmb3JlMS5qYXZhCkBAIC0wLDAgKzEsMTA2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQXBwZW5kcyBhIHRleHQgbm9kZSB0byBhbiBhdHRyaWJ1dGUgYW5kIGNoZWNrcyBpZiB0aGUgdmFsdWUgb2YKKyAqIHRoZSBhdHRyaWJ1dGUgaXMgY2hhbmdlZC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19hdHRyaW5zZXJ0YmVmb3JlMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfYXR0cmluc2VydGJlZm9yZTEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhY3JvbnltTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgdGl0bGVBdHRyOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgVGV4dCB0ZXh0Tm9kZTsKKyAgICAgIE5vZGUgcmV0dmFsOworICAgICAgTm9kZSBmaXJzdENoaWxkOworICAgICAgTm9kZSBsYXN0Q2hpbGQ7CisgICAgICBOb2RlIHJlZkNoaWxkID0gbnVsbDsKKworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgYWNyb255bUxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3ROb2RlID0gYWNyb255bUxpc3QuaXRlbSgzKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICB0aXRsZUF0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oInRpdGxlIik7CisgICAgICB0ZXh0Tm9kZSA9IGRvYy5jcmVhdGVUZXh0Tm9kZSgidGVyZGF5Iik7CisgICAgICByZXR2YWwgPSB0aXRsZUF0dHIuaW5zZXJ0QmVmb3JlKHRleHROb2RlLCByZWZDaGlsZCk7CisgICAgICB2YWx1ZSA9IHRpdGxlQXR0ci5nZXRWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyVmFsdWUiLCAiWWVzdGVyZGF5IiwgdmFsdWUpOworICAgICAgdmFsdWUgPSB0aXRsZUF0dHIuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJOb2RlVmFsdWUiLCAiWWVzdGVyZGF5IiwgdmFsdWUpOworICAgICAgdmFsdWUgPSByZXR2YWwuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInJldHZhbFZhbHVlIiwgInRlcmRheSIsIHZhbHVlKTsKKyAgICAgIGZpcnN0Q2hpbGQgPSB0aXRsZUF0dHIuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgdmFsdWUgPSBmaXJzdENoaWxkLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJmaXJzdENoaWxkVmFsdWUiLCAiWWVzIiwgdmFsdWUpOworICAgICAgbGFzdENoaWxkID0gdGl0bGVBdHRyLmdldExhc3RDaGlsZCgpOworICAgICAgdmFsdWUgPSBsYXN0Q2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImxhc3RDaGlsZFZhbHVlIiwgInRlcmRheSIsIHZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cmluc2VydGJlZm9yZTEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2F0dHJpbnNlcnRiZWZvcmUxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyaW5zZXJ0YmVmb3JlMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyaW5zZXJ0YmVmb3JlMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk1NDIzMzAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJpbnNlcnRiZWZvcmUyLmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBQcmVwZW5kcyBhIHRleHQgbm9kZSB0byBhbiBhdHRyaWJ1dGUgYW5kIGNoZWNrcyBpZiB0aGUgdmFsdWUgb2YKKyAqIHRoZSBhdHRyaWJ1dGUgaXMgY2hhbmdlZC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19hdHRyaW5zZXJ0YmVmb3JlMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfYXR0cmluc2VydGJlZm9yZTIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhY3JvbnltTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgdGl0bGVBdHRyOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgVGV4dCB0ZXh0Tm9kZTsKKyAgICAgIE5vZGUgcmV0dmFsOworICAgICAgTm9kZSBsYXN0Q2hpbGQ7CisgICAgICBOb2RlIGZpcnN0Q2hpbGQ7CisgICAgICBOb2RlIHJlZkNoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgYWNyb255bUxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3ROb2RlID0gYWNyb255bUxpc3QuaXRlbSgzKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICB0aXRsZUF0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oInRpdGxlIik7CisgICAgICB0ZXh0Tm9kZSA9IGRvYy5jcmVhdGVUZXh0Tm9kZSgidGVyZGF5Iik7CisgICAgICByZWZDaGlsZCA9IHRpdGxlQXR0ci5nZXRGaXJzdENoaWxkKCk7CisgICAgICByZXR2YWwgPSB0aXRsZUF0dHIuaW5zZXJ0QmVmb3JlKHRleHROb2RlLCByZWZDaGlsZCk7CisgICAgICB2YWx1ZSA9IHRpdGxlQXR0ci5nZXRWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyVmFsdWUiLCAidGVyZGF5WWVzIiwgdmFsdWUpOworICAgICAgdmFsdWUgPSB0aXRsZUF0dHIuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJOb2RlVmFsdWUiLCAidGVyZGF5WWVzIiwgdmFsdWUpOworICAgICAgdmFsdWUgPSByZXR2YWwuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInJldHZhbFZhbHVlIiwgInRlcmRheSIsIHZhbHVlKTsKKyAgICAgIGZpcnN0Q2hpbGQgPSB0aXRsZUF0dHIuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgdmFsdWUgPSBmaXJzdENoaWxkLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJmaXJzdENoaWxkVmFsdWUiLCAidGVyZGF5IiwgdmFsdWUpOworICAgICAgbGFzdENoaWxkID0gdGl0bGVBdHRyLmdldExhc3RDaGlsZCgpOworICAgICAgdmFsdWUgPSBsYXN0Q2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImxhc3RDaGlsZFZhbHVlIiwgIlllcyIsIHZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cmluc2VydGJlZm9yZTIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2F0dHJpbnNlcnRiZWZvcmUyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyaW5zZXJ0YmVmb3JlMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyaW5zZXJ0YmVmb3JlMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdhYzZlNmIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJpbnNlcnRiZWZvcmUzLmphdmEKQEAgLTAsMCArMSwxMTIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBcHBlbmRzIGEgZG9jdW1lbnQgZnJhZ21lbnQgdG8gYW4gYXR0cmlidXRlIGFuZCBjaGVja3MgaWYgdGhlIHZhbHVlIG9mCisgKiB0aGUgYXR0cmlidXRlIGlzIGNoYW5nZWQuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3MjciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfYXR0cmluc2VydGJlZm9yZTMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2F0dHJpbnNlcnRiZWZvcmUzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWNyb255bUxpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIHRpdGxlQXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIFRleHQgdGVyTm9kZTsKKyAgICAgIFRleHQgZGF5Tm9kZTsKKyAgICAgIERvY3VtZW50RnJhZ21lbnQgZG9jRnJhZzsKKyAgICAgIE5vZGUgcmV0dmFsOworICAgICAgTm9kZSBmaXJzdENoaWxkOworICAgICAgTm9kZSBsYXN0Q2hpbGQ7CisgICAgICBOb2RlIHJlZkNoaWxkID0gbnVsbDsKKworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgYWNyb255bUxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3ROb2RlID0gYWNyb255bUxpc3QuaXRlbSgzKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICB0aXRsZUF0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oInRpdGxlIik7CisgICAgICB0ZXJOb2RlID0gZG9jLmNyZWF0ZVRleHROb2RlKCJ0ZXIiKTsKKyAgICAgIGRheU5vZGUgPSBkb2MuY3JlYXRlVGV4dE5vZGUoImRheSIpOworICAgICAgZG9jRnJhZyA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CisgICAgICByZXR2YWwgPSBkb2NGcmFnLmFwcGVuZENoaWxkKHRlck5vZGUpOworICAgICAgcmV0dmFsID0gZG9jRnJhZy5hcHBlbmRDaGlsZChkYXlOb2RlKTsKKyAgICAgIHJldHZhbCA9IHRpdGxlQXR0ci5pbnNlcnRCZWZvcmUoZG9jRnJhZywgcmVmQ2hpbGQpOworICAgICAgdmFsdWUgPSB0aXRsZUF0dHIuZ2V0VmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0clZhbHVlIiwgIlllc3RlcmRheSIsIHZhbHVlKTsKKyAgICAgIHZhbHVlID0gdGl0bGVBdHRyLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyTm9kZVZhbHVlIiwgIlllc3RlcmRheSIsIHZhbHVlKTsKKyAgICAgIHZhbHVlID0gcmV0dmFsLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgicmV0dmFsVmFsdWUiLCB2YWx1ZSk7CisgICAgICBmaXJzdENoaWxkID0gdGl0bGVBdHRyLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIHZhbHVlID0gZmlyc3RDaGlsZC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZmlyc3RDaGlsZFZhbHVlIiwgIlllcyIsIHZhbHVlKTsKKyAgICAgIGxhc3RDaGlsZCA9IHRpdGxlQXR0ci5nZXRMYXN0Q2hpbGQoKTsKKyAgICAgIHZhbHVlID0gbGFzdENoaWxkLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJsYXN0Q2hpbGRWYWx1ZSIsICJkYXkiLCB2YWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJpbnNlcnRiZWZvcmUzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRyaW5zZXJ0YmVmb3JlMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmluc2VydGJlZm9yZTQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmluc2VydGJlZm9yZTQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOWNlYzViCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyaW5zZXJ0YmVmb3JlNC5qYXZhCkBAIC0wLDAgKzEsMTEyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogUHJlcGVuZHMgYSBkb2N1bWVudCBmcmFnbWVudCB0byBhbiBhdHRyaWJ1dGUgYW5kIGNoZWNrcyBpZiB0aGUgdmFsdWUgb2YKKyAqIHRoZSBhdHRyaWJ1dGUgaXMgY2hhbmdlZC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19hdHRyaW5zZXJ0YmVmb3JlNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfYXR0cmluc2VydGJlZm9yZTQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhY3JvbnltTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgdGl0bGVBdHRyOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgVGV4dCB0ZXJOb2RlOworICAgICAgVGV4dCBkYXlOb2RlOworICAgICAgRG9jdW1lbnRGcmFnbWVudCBkb2NGcmFnOworICAgICAgTm9kZSByZXR2YWw7CisgICAgICBOb2RlIGZpcnN0Q2hpbGQ7CisgICAgICBOb2RlIGxhc3RDaGlsZDsKKyAgICAgIE5vZGUgcmVmQ2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBhY3JvbnltTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdE5vZGUgPSBhY3JvbnltTGlzdC5pdGVtKDMpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3ROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHRpdGxlQXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgidGl0bGUiKTsKKyAgICAgIHRlck5vZGUgPSBkb2MuY3JlYXRlVGV4dE5vZGUoInRlciIpOworICAgICAgZGF5Tm9kZSA9IGRvYy5jcmVhdGVUZXh0Tm9kZSgiZGF5Iik7CisgICAgICBkb2NGcmFnID0gZG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKKyAgICAgIHJldHZhbCA9IGRvY0ZyYWcuYXBwZW5kQ2hpbGQodGVyTm9kZSk7CisgICAgICByZXR2YWwgPSBkb2NGcmFnLmFwcGVuZENoaWxkKGRheU5vZGUpOworICAgICAgcmVmQ2hpbGQgPSB0aXRsZUF0dHIuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgcmV0dmFsID0gdGl0bGVBdHRyLmluc2VydEJlZm9yZShkb2NGcmFnLCByZWZDaGlsZCk7CisgICAgICB2YWx1ZSA9IHRpdGxlQXR0ci5nZXRWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyVmFsdWUiLCAidGVyZGF5WWVzIiwgdmFsdWUpOworICAgICAgdmFsdWUgPSB0aXRsZUF0dHIuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJOb2RlVmFsdWUiLCAidGVyZGF5WWVzIiwgdmFsdWUpOworICAgICAgdmFsdWUgPSByZXR2YWwuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJyZXR2YWxWYWx1ZSIsIHZhbHVlKTsKKyAgICAgIGZpcnN0Q2hpbGQgPSB0aXRsZUF0dHIuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgdmFsdWUgPSBmaXJzdENoaWxkLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJmaXJzdENoaWxkVmFsdWUiLCAidGVyIiwgdmFsdWUpOworICAgICAgbGFzdENoaWxkID0gdGl0bGVBdHRyLmdldExhc3RDaGlsZCgpOworICAgICAgdmFsdWUgPSBsYXN0Q2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImxhc3RDaGlsZFZhbHVlIiwgIlllcyIsIHZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cmluc2VydGJlZm9yZTQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2F0dHJpbnNlcnRiZWZvcmU0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyaW5zZXJ0YmVmb3JlNS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyaW5zZXJ0YmVmb3JlNS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNhM2U0N2UKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJpbnNlcnRiZWZvcmU1LmphdmEKQEAgLTAsMCArMSwxMTkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBdHRlbXB0IHRvIGFwcGVuZCBhIENEQVRBU2VjdGlvbiB0byBhbiBhdHRyaWJ1dGUgd2hpY2ggc2hvdWxkIHJlc3VsdAorICogaW4gYSBISUVSQVJDSFlfUkVRVUVTVF9FUlIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3MjciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfYXR0cmluc2VydGJlZm9yZTUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2F0dHJpbnNlcnRiZWZvcmU1KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworICAgICAgaWYgKGZhY3RvcnkuaGFzRmVhdHVyZSgiWE1MIiwgbnVsbCkgIT0gdHJ1ZSkgeworICAgICAgICAgdGhyb3cgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uLmluY29tcGF0aWJsZUZlYXR1cmUoIlhNTCIsIG51bGwpOworICAgICAgfQorCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWNyb255bUxpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIHRpdGxlQXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIE5vZGUgdGV4dE5vZGU7CisgICAgICBOb2RlIHJldHZhbDsKKyAgICAgIE5vZGUgcmVmQ2hpbGQgPSBudWxsOworCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBhY3JvbnltTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdE5vZGUgPSBhY3JvbnltTGlzdC5pdGVtKDMpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3ROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHRpdGxlQXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgidGl0bGUiKTsKKyAgICAgIAorICAgICAgaWYgKCgidGV4dC9odG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKSB7CisgICAgICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXh0Tm9kZSA9IGRvYy5jcmVhdGVDREFUQVNlY3Rpb24oInRlcmRheSIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT1RfU1VQUE9SVEVEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfSBlbHNlIHsKKyAgICAgICAgICB0ZXh0Tm9kZSA9IGRvYy5jcmVhdGVDREFUQVNlY3Rpb24oInRlcmRheSIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR2YWwgPSB0aXRsZUF0dHIuaW5zZXJ0QmVmb3JlKHRleHROb2RlLCByZWZDaGlsZCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19ISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRyaW5zZXJ0YmVmb3JlNSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfYXR0cmluc2VydGJlZm9yZTUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJpbnNlcnRiZWZvcmU2LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJpbnNlcnRiZWZvcmU2LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmNiNjZiNQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmluc2VydGJlZm9yZTYuamF2YQpAQCAtMCwwICsxLDEwNCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEF0dGVtcHQgdG8gYXBwZW5kIGEgdGV4dCBub2RlIGZyb20gYW5vdGhlciBkb2N1bWVudCB0byBhbiBhdHRyaWJ1dGUgd2hpY2ggc2hvdWxkIHJlc3VsdAorICogaW4gYSBXUk9OR19ET0NVTUVOVF9FUlIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3MjciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfYXR0cmluc2VydGJlZm9yZTYgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2F0dHJpbnNlcnRiZWZvcmU2KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWNyb255bUxpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIHRpdGxlQXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIE5vZGUgdGV4dE5vZGU7CisgICAgICBOb2RlIHJldHZhbDsKKyAgICAgIE5vZGUgcmVmQ2hpbGQgPSBudWxsOworCisgICAgICBEb2N1bWVudCBvdGhlckRvYzsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIG90aGVyRG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgYWNyb255bUxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3ROb2RlID0gYWNyb255bUxpc3QuaXRlbSgzKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICB0aXRsZUF0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oInRpdGxlIik7CisgICAgICB0ZXh0Tm9kZSA9IG90aGVyRG9jLmNyZWF0ZVRleHROb2RlKCJ0ZXJkYXkiKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dmFsID0gdGl0bGVBdHRyLmluc2VydEJlZm9yZSh0ZXh0Tm9kZSwgcmVmQ2hpbGQpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfV1JPTkdfRE9DVU1FTlRfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJpbnNlcnRiZWZvcmU2IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRyaW5zZXJ0YmVmb3JlNi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmluc2VydGJlZm9yZTcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmluc2VydGJlZm9yZTcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMjJhMjdmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyaW5zZXJ0YmVmb3JlNy5qYXZhCkBAIC0wLDAgKzEsMTI2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQXBwZW5kcyBhIGRvY3VtZW50IGZyYWdtZW50IGNvbnRhaW5pbmcgYSBDREFUQVNlY3Rpb24gdG8gYW4gYXR0cmlidXRlLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3Mjc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2F0dHJpbnNlcnRiZWZvcmU3IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19hdHRyaW5zZXJ0YmVmb3JlNyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKyAgICAgIGlmIChmYWN0b3J5Lmhhc0ZlYXR1cmUoIlhNTCIsIG51bGwpICE9IHRydWUpIHsKKyAgICAgICAgIHRocm93IG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbi5pbmNvbXBhdGlibGVGZWF0dXJlKCJYTUwiLCBudWxsKTsKKyAgICAgIH0KKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFjcm9ueW1MaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciB0aXRsZUF0dHI7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBUZXh0IHRlck5vZGU7CisgICAgICBOb2RlIGRheU5vZGU7CisgICAgICBEb2N1bWVudEZyYWdtZW50IGRvY0ZyYWc7CisgICAgICBOb2RlIHJldHZhbDsKKyAgICAgIE5vZGUgZmlyc3RDaGlsZDsKKyAgICAgIE5vZGUgbGFzdENoaWxkOworICAgICAgTm9kZSByZWZDaGlsZCA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGFjcm9ueW1MaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFjcm9ueW1MaXN0Lml0ZW0oMyk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgdGl0bGVBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJ0aXRsZSIpOworICAgICAgdGVyTm9kZSA9IGRvYy5jcmVhdGVUZXh0Tm9kZSgidGVyIik7CisgICAgICAKKyAgICAgIGlmICgoInRleHQvaHRtbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkgeworICAgICAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgZGF5Tm9kZSA9IGRvYy5jcmVhdGVDREFUQVNlY3Rpb24oImRheSIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT1RfU1VQUE9SVEVEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfSBlbHNlIHsKKyAgICAgICAgICBkYXlOb2RlID0gZG9jLmNyZWF0ZUNEQVRBU2VjdGlvbigiZGF5Iik7CisgICAgICBkb2NGcmFnID0gZG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKKyAgICAgIHJldHZhbCA9IGRvY0ZyYWcuYXBwZW5kQ2hpbGQodGVyTm9kZSk7CisgICAgICByZXR2YWwgPSBkb2NGcmFnLmFwcGVuZENoaWxkKGRheU5vZGUpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR2YWwgPSB0aXRsZUF0dHIuaW5zZXJ0QmVmb3JlKGRvY0ZyYWcsIHJlZkNoaWxkKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0hJRVJBUkNIWV9SRVFVRVNUX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgICAgICAKKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJpbnNlcnRiZWZvcmU3IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRyaW5zZXJ0YmVmb3JlNy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmxhc3RjaGlsZC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRybGFzdGNoaWxkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDQ2N2I1YgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cmxhc3RjaGlsZC5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBDaGVja3MgdGhhdCBOb2RlLmxhc3RDaGlsZCBmb3IgYW4gYXR0cmlidXRlIG5vZGUgY29udGFpbnMKKyAqIHRoZSBleHBlY3RlZCB0ZXh0IG5vZGUuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02MUFEMDlGQiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjFBRDA5RkI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2F0dHJsYXN0Y2hpbGQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2F0dHJsYXN0Y2hpbGQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhY3JvbnltTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgdGl0bGVBdHRyOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgVGV4dCB0ZXh0Tm9kZTsKKyAgICAgIE5vZGUgb3RoZXJDaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGFjcm9ueW1MaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFjcm9ueW1MaXN0Lml0ZW0oMyk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgdGl0bGVBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJ0aXRsZSIpOworICAgICAgdGV4dE5vZGUgPSAoVGV4dCkgdGl0bGVBdHRyLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoInRleHROb2RlTm90TnVsbCIsIHRleHROb2RlKTsKKyAgICAgIHZhbHVlID0gdGV4dE5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoaWxkMUlzWWVzIiwgIlllcyIsIHZhbHVlKTsKKyAgICAgIG90aGVyQ2hpbGQgPSB0ZXh0Tm9kZS5nZXROZXh0U2libGluZygpOworICAgICAgYXNzZXJ0TnVsbCgibmV4dFNpYmxpbmdJc051bGwiLCBvdGhlckNoaWxkKTsKKyAgICAgIG90aGVyQ2hpbGQgPSB0ZXh0Tm9kZS5nZXRQcmV2aW91c1NpYmxpbmcoKTsKKyAgICAgIGFzc2VydE51bGwoInByZXZpb3VzU2libGluZ0lzTnVsbCIsIG90aGVyQ2hpbGQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRybGFzdGNoaWxkIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRybGFzdGNoaWxkLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRybmFtZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRybmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNmM2IyNzYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJuYW1lLmphdmEKQEAgLTAsMCArMSw5NCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgUmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBuYW1lZCBjbGFzcyBmcm9tIHRoZSBsYXN0IAorICogICBjaGlsZCBvZiBvZiB0aGUgc2Vjb25kICJwIiBlbGVtZW50IGFuZCBleGFtaW5lIGl0cyAKKyAqICAgTm9kZU5hbWUuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIxMTk0MDMiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIxMTk0MDM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzNiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzNjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDNKdW4vMDAxMS5odG1sIj5odHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDNKdW4vMDAxMS5odG1sPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19hdHRybmFtZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfYXR0cm5hbWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWRkcmVzc0xpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIHN0cmVldEF0dHI7CisgICAgICBTdHJpbmcgc3Ryb25nMTsKKyAgICAgIFN0cmluZyBzdHJvbmcyOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGFkZHJlc3NMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFkZHJlc3NMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgc3RyZWV0QXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgiY2xhc3MiKTsKKyAgICAgIHN0cm9uZzEgPSBzdHJlZXRBdHRyLmdldE5vZGVOYW1lKCk7CisgICAgICBzdHJvbmcyID0gc3RyZWV0QXR0ci5nZXROYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHNBdXRvQ2FzZSgiYXR0cmlidXRlIiwgIm5vZGVOYW1lIiwgImNsYXNzIiwgc3Ryb25nMSk7CisgICAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJhdHRyaWJ1dGUiLCAibmFtZSIsICJjbGFzcyIsIHN0cm9uZzIpOworICAgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJuYW1lIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRybmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cm5leHRzaWJsaW5nbnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRybmV4dHNpYmxpbmdudWxsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTdlZmIzOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cm5leHRzaWJsaW5nbnVsbC5qYXZhCkBAIC0wLDAgKzEsOTAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogVGhlICJnZXROZXh0U2libGluZygpIiBtZXRob2QgZm9yIGFuIEF0dHIgbm9kZSBzaG91bGQgcmV0dXJuIG51bGwuCisgKiBSZXRyaWV2ZSB0aGUgYXR0cmlidXRlIG5hbWVkICJkb21lc3RpYyIgZnJvbSB0aGUgbGFzdCBjaGlsZCBvZiBvZiB0aGUKKyAqIGZpcnN0IGVtcGxveWVlIGFuZCBleGFtaW5lIGl0cyBOZXh0U2libGluZyBub2RlLiAgVGhpcyB0ZXN0IHVzZXMgdGhlCisgKiAiZ2V0TmFtZWRJdGVtKG5hbWUpIiBtZXRob2QgZnJvbSB0aGUgTmFtZWROb2RlTWFwIGludGVyZmFjZS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTZBQzU0QzJGIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02QUM1NEMyRjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfYXR0cm5leHRzaWJsaW5nbnVsbCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfYXR0cm5leHRzaWJsaW5nbnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhZGRyZXNzTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgZG9tZXN0aWNBdHRyOworICAgICAgTm9kZSBzOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGFkZHJlc3NMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFkZHJlc3NMaXN0Lml0ZW0oMCk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgZG9tZXN0aWNBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJ0aXRsZSIpOworICAgICAgcyA9IGRvbWVzdGljQXR0ci5nZXROZXh0U2libGluZygpOworICAgICAgYXNzZXJ0TnVsbCgiYXR0ck5leHRTaWJsaW5nTnVsbEFzc2VydCIsIHMpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRybmV4dHNpYmxpbmdudWxsIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRybmV4dHNpYmxpbmdudWxsLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRybm9ybWFsaXplLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJub3JtYWxpemUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMTdlNzFhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRybm9ybWFsaXplLmphdmEKQEAgLTAsMCArMSwxMDIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBcHBlbmRzIGEgdGV4dCBub2RlIHRvIGFuIGF0dHJpYnV0ZSwgbm9ybWFsaXplcyB0aGUgYXR0cmlidXRlCisgKiBhbmQgY2hlY2tzIGZvciBhIHNpbmdsZSBjaGlsZCBub2RlLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTYyQ0YwODMiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE2MkNGMDgzPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19hdHRybm9ybWFsaXplIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19hdHRybm9ybWFsaXplKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWNyb255bUxpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIHRpdGxlQXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIFRleHQgdGV4dE5vZGU7CisgICAgICBOb2RlIHJldHZhbDsKKyAgICAgIE5vZGUgZmlyc3RDaGlsZDsKKyAgICAgIE5vZGUgc2Vjb25kQ2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBhY3JvbnltTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdE5vZGUgPSBhY3JvbnltTGlzdC5pdGVtKDMpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3ROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHRpdGxlQXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgidGl0bGUiKTsKKyAgICAgIHRleHROb2RlID0gZG9jLmNyZWF0ZVRleHROb2RlKCJ0ZXJkYXkiKTsKKyAgICAgIHJldHZhbCA9IHRpdGxlQXR0ci5hcHBlbmRDaGlsZCh0ZXh0Tm9kZSk7CisgICAgICB0ZXh0Tm9kZSA9IGRvYy5jcmVhdGVUZXh0Tm9kZSgiIik7CisgICAgICByZXR2YWwgPSB0aXRsZUF0dHIuYXBwZW5kQ2hpbGQodGV4dE5vZGUpOworICAgICAgKChFbGVtZW50KSAvKk5vZGUgKi90ZXN0Tm9kZSkubm9ybWFsaXplKCk7CisgICAgICB2YWx1ZSA9IHRpdGxlQXR0ci5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0ck5vZGVWYWx1ZSIsICJZZXN0ZXJkYXkiLCB2YWx1ZSk7CisgICAgICBmaXJzdENoaWxkID0gdGl0bGVBdHRyLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIHZhbHVlID0gZmlyc3RDaGlsZC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZmlyc3RDaGlsZFZhbHVlIiwgIlllc3RlcmRheSIsIHZhbHVlKTsKKyAgICAgIHNlY29uZENoaWxkID0gZmlyc3RDaGlsZC5nZXROZXh0U2libGluZygpOworICAgICAgYXNzZXJ0TnVsbCgic2Vjb25kQ2hpbGRJc051bGwiLCBzZWNvbmRDaGlsZCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJub3JtYWxpemUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2F0dHJub3JtYWxpemUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJwYXJlbnRub2RlbnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRycGFyZW50bm9kZW51bGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xN2Y0MjgzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRycGFyZW50bm9kZW51bGwuamF2YQpAQCAtMCwwICsxLDkwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIFRoZSAiZ2V0UGFyZW50Tm9kZSgpIiBtZXRob2QgZm9yIGFuIEF0dHIgbm9kZSBzaG91bGQgcmV0dXJuIG51bGwuICBSZXRyaWV2ZQorICogdGhlIGF0dHJpYnV0ZSBuYW1lZCAiZG9tZXN0aWMiIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlIGZpcnN0IGVtcGxveWVlCisgKiBhbmQgZXhhbWluZSBpdHMgcGFyZW50Tm9kZSBhdHRyaWJ1dGUuICBUaGlzIHRlc3QgYWxzbyB1c2VzIHRoZSAiZ2V0TmFtZWRJdGVtKG5hbWUpIgorICogbWV0aG9kIGZyb20gdGhlIE5hbWVkTm9kZU1hcCBpbnRlcmZhY2UuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDYwMTg0MzE3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDYwMTg0MzE3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19hdHRycGFyZW50bm9kZW51bGwgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2F0dHJwYXJlbnRub2RlbnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhZGRyZXNzTGlzdDsKKyAgICAgIE5vZGUgdGVzdE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgZG9tZXN0aWNBdHRyOworICAgICAgTm9kZSBzOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGFkZHJlc3NMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFkZHJlc3NMaXN0Lml0ZW0oMCk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgZG9tZXN0aWNBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJ0aXRsZSIpOworICAgICAgcyA9IGRvbWVzdGljQXR0ci5nZXRQYXJlbnROb2RlKCk7CisgICAgICBhc3NlcnROdWxsKCJhdHRyUGFyZW50Tm9kZU51bGxBc3NlcnQiLCBzKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cnBhcmVudG5vZGVudWxsIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRycGFyZW50bm9kZW51bGwuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJwcmV2aW91c3NpYmxpbmdudWxsLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJwcmV2aW91c3NpYmxpbmdudWxsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjYzYmY3NgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cnByZXZpb3Vzc2libGluZ251bGwuamF2YQpAQCAtMCwwICsxLDkwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIFRoZSAiZ2V0UHJldmlvdXNTaWJsaW5nKCkiIG1ldGhvZCBmb3IgYW4gQXR0ciBub2RlIHNob3VsZCByZXR1cm4gbnVsbC4KKyAqIFJldHJpZXZlIHRoZSBhdHRyaWJ1dGUgbmFtZWQgImRvbWVzdGljIiBmcm9tIHRoZSBsYXN0IGNoaWxkIG9mIG9mIHRoZQorICogZmlyc3QgZW1wbG95ZWUgYW5kIGV4YW1pbmUgaXRzIFByZXZpb3VzU2libGluZyBub2RlLiAgVGhpcyB0ZXN0IHVzZXMgdGhlCisgKiAiZ2V0TmFtZWRJdGVtKG5hbWUpIiBtZXRob2QgZnJvbSB0aGUgTmFtZWROb2RlTWFwIGludGVyZmFjZS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTY0MEZCM0M4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NDBGQjNDODwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfYXR0cnByZXZpb3Vzc2libGluZ251bGwgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2F0dHJwcmV2aW91c3NpYmxpbmdudWxsKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NMaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBkb21lc3RpY0F0dHI7CisgICAgICBOb2RlIHM7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgYWRkcmVzc0xpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3ROb2RlID0gYWRkcmVzc0xpc3QuaXRlbSgwKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBkb21lc3RpY0F0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oInRpdGxlIik7CisgICAgICBzID0gZG9tZXN0aWNBdHRyLmdldFByZXZpb3VzU2libGluZygpOworICAgICAgYXNzZXJ0TnVsbCgiYXR0clByZXZpb3VzU2libGluZ051bGxBc3NlcnQiLCBzKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cnByZXZpb3Vzc2libGluZ251bGwiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2F0dHJwcmV2aW91c3NpYmxpbmdudWxsLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRycmVtb3ZlY2hpbGQxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJyZW1vdmVjaGlsZDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZDg4MzM0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRycmVtb3ZlY2hpbGQxLmphdmEKQEAgLTAsMCArMSw5OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIFJlbW92ZXMgdGhlIGNoaWxkIG5vZGUgb2YgYW4gYXR0cmlidXRlIGFuZCBjaGVja3MgdGhhdCB0aGUgdmFsdWUgaXMgZW1wdHkuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19hdHRycmVtb3ZlY2hpbGQxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19hdHRycmVtb3ZlY2hpbGQxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWNyb255bUxpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIHRpdGxlQXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIFRleHQgdGV4dE5vZGU7CisgICAgICBOb2RlIHJldHZhbDsKKyAgICAgIE5vZGUgZmlyc3RDaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGFjcm9ueW1MaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFjcm9ueW1MaXN0Lml0ZW0oMyk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgdGl0bGVBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJ0aXRsZSIpOworICAgICAgdGV4dE5vZGUgPSAoVGV4dCkgdGl0bGVBdHRyLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImF0dHJDaGlsZE5vdE51bGwiLCB0ZXh0Tm9kZSk7CisgICAgICByZXR2YWwgPSB0aXRsZUF0dHIucmVtb3ZlQ2hpbGQodGV4dE5vZGUpOworICAgICAgdmFsdWUgPSB0aXRsZUF0dHIuZ2V0VmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0clZhbHVlIiwgIiIsIHZhbHVlKTsKKyAgICAgIHZhbHVlID0gdGl0bGVBdHRyLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyTm9kZVZhbHVlIiwgIiIsIHZhbHVlKTsKKyAgICAgIHZhbHVlID0gcmV0dmFsLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJyZXR2YWxWYWx1ZSIsICJZZXMiLCB2YWx1ZSk7CisgICAgICBmaXJzdENoaWxkID0gdGl0bGVBdHRyLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE51bGwoImZpcnN0Q2hpbGROdWxsIiwgZmlyc3RDaGlsZCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJyZW1vdmVjaGlsZDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2F0dHJyZW1vdmVjaGlsZDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJyZW1vdmVjaGlsZDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cnJlbW92ZWNoaWxkMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlY2U2YWYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJyZW1vdmVjaGlsZDIuamF2YQpAQCAtMCwwICsxLDk4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQXR0ZW1wdHMgdG8gcmVtb3ZlIGEgZnJlc2hseSBjcmVhdGVkIHRleHQgbm9kZSB3aGljaCBzaG91bGQgcmVzdWx0IGluIGEgTk9UX0ZPVU5EX0VSUiBleGNlcHRpb24uCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19hdHRycmVtb3ZlY2hpbGQyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19hdHRycmVtb3ZlY2hpbGQyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWNyb255bUxpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIHRpdGxlQXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIFRleHQgdGV4dE5vZGU7CisgICAgICBOb2RlIHJldHZhbDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGFjcm9ueW1MaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFjcm9ueW1MaXN0Lml0ZW0oMyk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgdGl0bGVBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJ0aXRsZSIpOworICAgICAgdGV4dE5vZGUgPSBkb2MuY3JlYXRlVGV4dE5vZGUoIlllc3RlcmRheSIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR2YWwgPSB0aXRsZUF0dHIucmVtb3ZlQ2hpbGQodGV4dE5vZGUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT1RfRk9VTkRfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9GT1VORF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfYXR0cnJlbW92ZWNoaWxkMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfYXR0cnJlbW92ZWNoaWxkMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cnJlcGxhY2VjaGlsZDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cnJlcGxhY2VjaGlsZDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OWU4MGY5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRycmVwbGFjZWNoaWxkMS5qYXZhCkBAIC0wLDAgKzEsMTAyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogUmVwbGFjZXMgYSB0ZXh0IG5vZGUgb2YgYW4gYXR0cmlidXRlIGFuZCBjaGVja3MgaWYgdGhlIHZhbHVlIG9mCisgKiB0aGUgYXR0cmlidXRlIGlzIGNoYW5nZWQuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfYXR0cnJlcGxhY2VjaGlsZDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2F0dHJyZXBsYWNlY2hpbGQxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWNyb255bUxpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIHRpdGxlQXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIFRleHQgdGV4dE5vZGU7CisgICAgICBOb2RlIHJldHZhbDsKKyAgICAgIE5vZGUgZmlyc3RDaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGFjcm9ueW1MaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFjcm9ueW1MaXN0Lml0ZW0oMyk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgdGl0bGVBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJ0aXRsZSIpOworICAgICAgdGV4dE5vZGUgPSBkb2MuY3JlYXRlVGV4dE5vZGUoInRlcmRheSIpOworICAgICAgZmlyc3RDaGlsZCA9IHRpdGxlQXR0ci5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJhdHRyQ2hpbGROb3ROdWxsIiwgZmlyc3RDaGlsZCk7CisgICAgICByZXR2YWwgPSB0aXRsZUF0dHIucmVwbGFjZUNoaWxkKHRleHROb2RlLCBmaXJzdENoaWxkKTsKKyAgICAgIHZhbHVlID0gdGl0bGVBdHRyLmdldFZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJWYWx1ZSIsICJ0ZXJkYXkiLCB2YWx1ZSk7CisgICAgICB2YWx1ZSA9IHRpdGxlQXR0ci5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0ck5vZGVWYWx1ZSIsICJ0ZXJkYXkiLCB2YWx1ZSk7CisgICAgICB2YWx1ZSA9IHJldHZhbC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygicmV0dmFsVmFsdWUiLCAiWWVzIiwgdmFsdWUpOworICAgICAgZmlyc3RDaGlsZCA9IHRpdGxlQXR0ci5nZXRGaXJzdENoaWxkKCk7CisgICAgICB2YWx1ZSA9IGZpcnN0Q2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImZpcnN0Q2hpbGRWYWx1ZSIsICJ0ZXJkYXkiLCB2YWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJyZXBsYWNlY2hpbGQxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRycmVwbGFjZWNoaWxkMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cnJlcGxhY2VjaGlsZDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cnJlcGxhY2VjaGlsZDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMjY4NDBkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRycmVwbGFjZWNoaWxkMi5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogUmVwbGFjZXMgYSB0ZXh0IG5vZGUgb2YgYW4gYXR0cmlidXRlIHdpdGggYSBkb2N1bWVudCBmcmFnbWVudCBhbmQgY2hlY2tzIGlmIHRoZSB2YWx1ZSBvZgorICogdGhlIGF0dHJpYnV0ZSBpcyBjaGFuZ2VkLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2F0dHJyZXBsYWNlY2hpbGQyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19hdHRycmVwbGFjZWNoaWxkMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFjcm9ueW1MaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciB0aXRsZUF0dHI7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBUZXh0IHRlck5vZGU7CisgICAgICBUZXh0IGRheU5vZGU7CisgICAgICBEb2N1bWVudEZyYWdtZW50IGRvY0ZyYWc7CisgICAgICBOb2RlIHJldHZhbDsKKyAgICAgIE5vZGUgZmlyc3RDaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGFjcm9ueW1MaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFjcm9ueW1MaXN0Lml0ZW0oMyk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgdGl0bGVBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJ0aXRsZSIpOworICAgICAgdGVyTm9kZSA9IGRvYy5jcmVhdGVUZXh0Tm9kZSgidGVyIik7CisgICAgICBkYXlOb2RlID0gZG9jLmNyZWF0ZVRleHROb2RlKCJkYXkiKTsKKyAgICAgIGRvY0ZyYWcgPSBkb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOworICAgICAgcmV0dmFsID0gZG9jRnJhZy5hcHBlbmRDaGlsZCh0ZXJOb2RlKTsKKyAgICAgIHJldHZhbCA9IGRvY0ZyYWcuYXBwZW5kQ2hpbGQoZGF5Tm9kZSk7CisgICAgICBmaXJzdENoaWxkID0gdGl0bGVBdHRyLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImF0dHJDaGlsZE5vdE51bGwiLCBmaXJzdENoaWxkKTsKKyAgICAgIHJldHZhbCA9IHRpdGxlQXR0ci5yZXBsYWNlQ2hpbGQoZG9jRnJhZywgZmlyc3RDaGlsZCk7CisgICAgICB2YWx1ZSA9IHRpdGxlQXR0ci5nZXRWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyVmFsdWUiLCAidGVyZGF5IiwgdmFsdWUpOworICAgICAgdmFsdWUgPSB0aXRsZUF0dHIuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJOb2RlVmFsdWUiLCAidGVyZGF5IiwgdmFsdWUpOworICAgICAgdmFsdWUgPSByZXR2YWwuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInJldHZhbFZhbHVlIiwgIlllcyIsIHZhbHVlKTsKKyAgICAgIGZpcnN0Q2hpbGQgPSB0aXRsZUF0dHIuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgdmFsdWUgPSBmaXJzdENoaWxkLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJmaXJzdENoaWxkVmFsdWUiLCAidGVyIiwgdmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRycmVwbGFjZWNoaWxkMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfYXR0cnJlcGxhY2VjaGlsZDIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJzZXR2YWx1ZTEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cnNldHZhbHVlMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhNDUzNWIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJzZXR2YWx1ZTEuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIFNldHMgQXR0ci52YWx1ZSBvbiBhbiBhdHRyaWJ1dGUgdGhhdCBvbmx5IGhhcyBhIHNpbXBsZSB2YWx1ZS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIyMTY2MjQ3NCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjIxNjYyNDc0PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19hdHRyc2V0dmFsdWUxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19hdHRyc2V0dmFsdWUxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWNyb255bUxpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIHRpdGxlQXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIE5vZGUgcmV0dmFsOworICAgICAgTm9kZSBmaXJzdENoaWxkOworICAgICAgTm9kZSBvdGhlckNoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgYWNyb255bUxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3ROb2RlID0gYWNyb255bUxpc3QuaXRlbSgzKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICB0aXRsZUF0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oInRpdGxlIik7CisgICAgICBmaXJzdENoaWxkID0gdGl0bGVBdHRyLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImF0dHJDaGlsZE5vdE51bGwiLCBmaXJzdENoaWxkKTsKKyAgICAgIHRpdGxlQXR0ci5zZXRWYWx1ZSgiVG9tb3Jyb3ciKTsKKyAgICAgIGZpcnN0Q2hpbGQuc2V0Tm9kZVZhbHVlKCJpbXBsIHJldXNlZCBub2RlIik7CisgICAgICB2YWx1ZSA9IHRpdGxlQXR0ci5nZXRWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyVmFsdWUiLCAiVG9tb3Jyb3ciLCB2YWx1ZSk7CisgICAgICB2YWx1ZSA9IHRpdGxlQXR0ci5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0ck5vZGVWYWx1ZSIsICJUb21vcnJvdyIsIHZhbHVlKTsKKyAgICAgIGZpcnN0Q2hpbGQgPSB0aXRsZUF0dHIuZ2V0TGFzdENoaWxkKCk7CisgICAgICB2YWx1ZSA9IGZpcnN0Q2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImZpcnN0Q2hpbGRWYWx1ZSIsICJUb21vcnJvdyIsIHZhbHVlKTsKKyAgICAgIG90aGVyQ2hpbGQgPSBmaXJzdENoaWxkLmdldE5leHRTaWJsaW5nKCk7CisgICAgICBhc3NlcnROdWxsKCJuZXh0U2libGluZ0lzTnVsbCIsIG90aGVyQ2hpbGQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRyc2V0dmFsdWUxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRyc2V0dmFsdWUxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyc2V0dmFsdWUyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJzZXR2YWx1ZTIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOTJlYWExCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyc2V0dmFsdWUyLmphdmEKQEAgLTAsMCArMSwxMDMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBTZXRzIEF0dHIudmFsdWUgb24gYW4gYXR0cmlidXRlIHRoYXQgc2hvdWxkIGNvbnRhaW4gbXVsdGlwbGUgY2hpbGQgbm9kZXMuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMjE2NjI0NzQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIyMTY2MjQ3NDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfYXR0cnNldHZhbHVlMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfYXR0cnNldHZhbHVlMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFjcm9ueW1MaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciB0aXRsZUF0dHI7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBUZXh0IHRleHROb2RlOworICAgICAgTm9kZSByZXR2YWw7CisgICAgICBOb2RlIGZpcnN0Q2hpbGQ7CisgICAgICBOb2RlIG90aGVyQ2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBhY3JvbnltTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdE5vZGUgPSBhY3JvbnltTGlzdC5pdGVtKDMpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3ROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHRpdGxlQXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgidGl0bGUiKTsKKyAgICAgIHRleHROb2RlID0gZG9jLmNyZWF0ZVRleHROb2RlKCJ0ZXJkYXkiKTsKKyAgICAgIHJldHZhbCA9IHRpdGxlQXR0ci5hcHBlbmRDaGlsZCh0ZXh0Tm9kZSk7CisgICAgICBmaXJzdENoaWxkID0gdGl0bGVBdHRyLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImF0dHJDaGlsZE5vdE51bGwiLCBmaXJzdENoaWxkKTsKKyAgICAgIHRpdGxlQXR0ci5zZXRWYWx1ZSgiVG9tb3Jyb3ciKTsKKyAgICAgIGZpcnN0Q2hpbGQuc2V0Tm9kZVZhbHVlKCJpbXBsIHJldXNlZCBub2RlIik7CisgICAgICB2YWx1ZSA9IHRpdGxlQXR0ci5nZXRWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyVmFsdWUiLCAiVG9tb3Jyb3ciLCB2YWx1ZSk7CisgICAgICB2YWx1ZSA9IHRpdGxlQXR0ci5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0ck5vZGVWYWx1ZSIsICJUb21vcnJvdyIsIHZhbHVlKTsKKyAgICAgIGZpcnN0Q2hpbGQgPSB0aXRsZUF0dHIuZ2V0TGFzdENoaWxkKCk7CisgICAgICB2YWx1ZSA9IGZpcnN0Q2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImZpcnN0Q2hpbGRWYWx1ZSIsICJUb21vcnJvdyIsIHZhbHVlKTsKKyAgICAgIG90aGVyQ2hpbGQgPSBmaXJzdENoaWxkLmdldE5leHRTaWJsaW5nKCk7CisgICAgICBhc3NlcnROdWxsKCJuZXh0U2libGluZ0lzTnVsbCIsIG90aGVyQ2hpbGQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRyc2V0dmFsdWUyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRyc2V0dmFsdWUyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyc3BlY2lmaWVkdmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cnNwZWNpZmllZHZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTQ5ODIzOAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfYXR0cnNwZWNpZmllZHZhbHVlLmphdmEKQEAgLTAsMCArMSw5MyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldFNwZWNpZmllZCgpIiBtZXRob2QgZm9yIGFuIEF0dHIgbm9kZSBzaG91bGQgCisgKiAgIGJlIHNldCB0byB0cnVlIGlmIHRoZSBhdHRyaWJ1dGUgd2FzIGV4cGxpY2l0bHkgZ2l2ZW4KKyAqICAgYSB2YWx1ZS4KKyAqICAgUmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBuYW1lZCAiZG9tZXN0aWMiIGZyb20gdGhlIGxhc3QgCisgKiAgIGNoaWxkIG9mIG9mIHRoZSBmaXJzdCBlbXBsb3llZSBhbmQgZXhhbWluZSB0aGUgdmFsdWUgCisgKiAgIHJldHVybmVkIGJ5IHRoZSAiZ2V0U3BlY2lmaWVkKCkiIG1ldGhvZC4gIFRoaXMgdGVzdCB1c2VzIAorICogICB0aGUgImdldE5hbWVkSXRlbShuYW1lKSIgbWV0aG9kIGZyb20gdGhlIE5hbWVkTm9kZU1hcCAKKyAqICAgaW50ZXJmYWNlLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODYyNTI5MjczIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NjI1MjkyNzM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2F0dHJzcGVjaWZpZWR2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfYXR0cnNwZWNpZmllZHZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NMaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBkb21lc3RpY0F0dHI7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGFkZHJlc3NMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGFkZHJlc3NMaXN0Lml0ZW0oMCk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgZG9tZXN0aWNBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJ0aXRsZSIpOworICAgICAgc3RhdGUgPSBkb21lc3RpY0F0dHIuZ2V0U3BlY2lmaWVkKCk7CisgICAgICBhc3NlcnRUcnVlKCJhY3JvbnltVGl0bGVTcGVjaWZpZWQiLCBzdGF0ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2F0dHJzcGVjaWZpZWR2YWx1ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfYXR0cnNwZWNpZmllZHZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyc3BlY2lmaWVkdmFsdWVjaGFuZ2VkLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2F0dHJzcGVjaWZpZWR2YWx1ZWNoYW5nZWQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YmE0YzU3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19hdHRyc3BlY2lmaWVkdmFsdWVjaGFuZ2VkLmphdmEKQEAgLTAsMCArMSw5NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldFNwZWNpZmllZCgpIiBtZXRob2QgZm9yIGFuIEF0dHIgbm9kZSBzaG91bGQgcmV0dXJuIHRydWUgaWYgdGhlIAorICogICB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlIGlzIGNoYW5nZWQuIAorICogICBSZXRyaWV2ZSB0aGUgYXR0cmlidXRlIG5hbWVkICJjbGFzcyIgZnJvbSB0aGUgbGFzdCAKKyAqICAgY2hpbGQgb2Ygb2YgdGhlIFRISVJEIGVtcGxveWVlIGFuZCBjaGFuZ2UgaXRzIAorICogICB2YWx1ZSB0byAiWWVzIih3aGljaCBpcyB0aGUgZGVmYXVsdCBEVEQgdmFsdWUpLiAgVGhpcworICogICBzaG91bGQgY2F1c2UgdGhlICJnZXRTcGVjaWZpZWQoKSIgbWV0aG9kIHRvIGJlIHRydWUuCisgKiAgIFRoaXMgdGVzdCB1c2VzIHRoZSAic2V0QXR0cmlidXRlKG5hbWUsdmFsdWUpIiBtZXRob2QKKyAqICAgZnJvbSB0aGUgRWxlbWVudCBpbnRlcmZhY2UgYW5kIHRoZSAiZ2V0TmFtZWRJdGVtKG5hbWUpIgorICogICBtZXRob2QgZnJvbSB0aGUgTmFtZWROb2RlTWFwIGludGVyZmFjZS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg2MjUyOTI3MyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODYyNTI5MjczPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19hdHRyc3BlY2lmaWVkdmFsdWVjaGFuZ2VkIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19hdHRyc3BlY2lmaWVkdmFsdWVjaGFuZ2VkKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWRkcmVzc0xpc3Q7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIHN0cmVldEF0dHI7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgYWRkcmVzc0xpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3ROb2RlID0gYWRkcmVzc0xpc3QuaXRlbSgyKTsKKyAgICAgICgoRWxlbWVudCkgLypOb2RlICovdGVzdE5vZGUpLnNldEF0dHJpYnV0ZSgiY2xhc3MiLCAiWVx1MDNiMSIpOyAvLyBhbmRyb2lkLWNoYW5nZWQ6IEdSRUVLIExPV0VSIENBU0UgQUxQSEEKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBzdHJlZXRBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJjbGFzcyIpOworICAgICAgc3RhdGUgPSBzdHJlZXRBdHRyLmdldFNwZWNpZmllZCgpOworICAgICAgYXNzZXJ0VHJ1ZSgiYWNyb255bUNsYXNzU3BlY2lmaWVkIiwgc3RhdGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19hdHRyc3BlY2lmaWVkdmFsdWVjaGFuZ2VkIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19hdHRyc3BlY2lmaWVkdmFsdWVjaGFuZ2VkLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMwN2U2OTYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhLmphdmEKQEAgLTAsMCArMSw5NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJhcHBlbmREYXRhKGFyZykiIG1ldGhvZCBhcHBlbmRzIGEgc3RyaW5nIHRvIHRoZSBlbmQgCisgKiAgICBvZiB0aGUgY2hhcmFjdGVyIGRhdGEgb2YgdGhlIG5vZGUuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBmcm9tIHRoZSBzZWNvbmQgY2hpbGQgCisgKiAgICBvZiB0aGUgZmlyc3QgZW1wbG95ZWUuICBUaGUgYXBwZW5kRGF0YShhcmcpIG1ldGhvZCBpcworICogICAgY2FsbGVkIHdpdGggYXJnPSIsIEVzcXVpcmUiLiAgVGhlIG1ldGhvZCBzaG91bGQgYXBwZW5kIAorICogICAgdGhlIHNwZWNpZmllZCBkYXRhIHRvIHRoZSBhbHJlYWR5IGV4aXN0aW5nIGNoYXJhY3RlciAgCisgKiAgICBkYXRhLiAgVGhlIG5ldyB2YWx1ZSByZXR1cm4gYnkgdGhlICJnZXRMZW5ndGgoKSIgbWV0aG9kCisgKiAgICBzaG91bGQgYmUgMjQuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzI3OTFBMkYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTMyNzkxQTJGPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19jaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkVmFsdWU7CisgICAgICBpbnQgY2hpbGRMZW5ndGg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgic3Ryb25nIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZC5hcHBlbmREYXRhKCIsIEVzcXVpcmUiKTsKKyAgICAgIGNoaWxkVmFsdWUgPSBjaGlsZC5nZXREYXRhKCk7CisgICAgICBjaGlsZExlbmd0aCA9IGNoaWxkVmFsdWUubGVuZ3RoKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlcmRhdGFBcHBlbmREYXRhQXNzZXJ0IiwgMjQsIGNoaWxkTGVuZ3RoKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhYXBwZW5kZGF0YWdldGRhdGEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGFnZXRkYXRhLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDJjYmYzMgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGFnZXRkYXRhLmphdmEKQEAgLTAsMCArMSw5NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgT24gc3VjY2Vzc2Z1bCBpbnZvY2F0aW9uIG9mIHRoZSAiYXBwZW5kRGF0YShhcmcpIiAKKyAqICAgIG1ldGhvZCB0aGUgImdldERhdGEoKSIgbWV0aG9kIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUKKyAqICAgIGNvbmNhdGVudGF0aW9uIG9mIGRhdGEgYW5kIHRoZSBzcGVjaWZpZWQgc3RyaW5nLgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgZnJvbSB0aGUgc2Vjb25kIGNoaWxkIAorICogICAgb2YgdGhlIGZpcnN0IGVtcGxveWVlLiAgVGhlIGFwcGVuZERhdGEoYXJnKSBtZXRob2QgaXMKKyAqICAgIGNhbGxlZCB3aXRoIGFyZz0iLCBFc3F1aXJlIi4gIFRoZSBtZXRob2Qgc2hvdWxkIGFwcGVuZCAKKyAqICAgIHRoZSBzcGVjaWZpZWQgZGF0YSB0byB0aGUgYWxyZWFkeSBleGlzdGluZyBjaGFyYWN0ZXIgIAorICogICAgZGF0YS4gIFRoZSBuZXcgdmFsdWUgcmV0dXJuIGJ5IHRoZSAiZ2V0RGF0YSgpIiBtZXRob2QKKyAqICAgIHNob3VsZCBiZSAiTWFyZ2FyZXQgTWFydGluLCBFc3F1aXJlIi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zMjc5MUEyRiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzI3OTFBMkY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhZ2V0ZGF0YSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGFnZXRkYXRhKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZERhdGE7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgic3Ryb25nIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZC5hcHBlbmREYXRhKCIsIEVzcXVpcmUiKTsKKyAgICAgIGNoaWxkRGF0YSA9IGNoaWxkLmdldERhdGEoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2hhcmFjdGVyZGF0YUFwcGVuZERhdGFHZXREYXRhQXNzZXJ0IiwgIk1hcmdhcmV0IE1hcnRpbiwgRXNxdWlyZSIsIGNoaWxkRGF0YSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFhcHBlbmRkYXRhZ2V0ZGF0YSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfY2hhcmFjdGVyZGF0YWFwcGVuZGRhdGFnZXRkYXRhLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWJlZ2luaW5nLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhYmVnaW5pbmcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNzlmZTZjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWJlZ2luaW5nLmphdmEKQEAgLTAsMCArMSw5MyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBUaGUgImRlbGV0ZURhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kIHJlbW92ZXMgYSByYW5nZSBvZgorICogY2hhcmFjdGVycyBmcm9tIHRoZSBub2RlLiAgRGVsZXRlIGRhdGEgYXQgdGhlIGJlZ2lubmluZworICogb2YgdGhlIGNoYXJhY3RlciBkYXRhLgorICogUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiBmaXJzdCBlbXBsb3llZS4gIFRoZSAiZGVsZXRlRGF0YShvZmZzZXQsY291bnQpIgorICogbWV0aG9kIGlzIHRoZW4gY2FsbGVkIHdpdGggb2Zmc2V0PTAgYW5kIGNvdW50PTE2LgorICogVGhlIG1ldGhvZCBzaG91bGQgZGVsZXRlIHRoZSBjaGFyYWN0ZXJzIGZyb20gcG9zaXRpb24KKyAqIDAgdGhydSBwb3NpdGlvbiAxNi4gIFRoZSBuZXcgdmFsdWUgb2YgdGhlIGNoYXJhY3RlciBkYXRhCisgKiBzaG91bGQgYmUgIkRhbGxhcywgVGV4YXMgOTg1NTEiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0M2MDM3ODEiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWJlZ2luaW5nIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWJlZ2luaW5nKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZERhdGE7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgY2hpbGQuZGVsZXRlRGF0YSgwLCAxNik7CisgICAgICBjaGlsZERhdGEgPSBjaGlsZC5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRhdGEiLCAiRGFsbGFzLCBUZXhhcyA5ODU1MSIsIGNoaWxkRGF0YSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhYmVnaW5pbmciOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhYmVnaW5pbmcuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZW5kLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZW5kLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjQwMWI4ZgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFlbmQuamF2YQpAQCAtMCwwICsxLDk1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImRlbGV0ZURhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kIHJlbW92ZXMgYSByYW5nZSBvZiAKKyAqICAgIGNoYXJhY3RlcnMgZnJvbSB0aGUgbm9kZS4gIERlbGV0ZSBkYXRhIGF0IHRoZSBlbmQgCisgKiAgICBvZiB0aGUgY2hhcmFjdGVyIGRhdGEuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBmcm9tIHRoZSBsYXN0IGNoaWxkIG9mIHRoZQorICogICAgZmlyc3QgZW1wbG95ZWUuICBUaGUgImRlbGV0ZURhdGEob2Zmc2V0LGNvdW50KSIKKyAqICAgIG1ldGhvZCBpcyB0aGVuIGNhbGxlZCB3aXRoIG9mZnNldD0zMCBhbmQgY291bnQ9NS4KKyAqICAgIFRoZSBtZXRob2Qgc2hvdWxkIGRlbGV0ZSB0aGUgY2hhcmFjdGVycyBmcm9tIHBvc2l0aW9uCisgKiAgICAzMCB0aHJ1IHBvc2l0aW9uIDM1LiAgVGhlIG5ldyB2YWx1ZSBvZiB0aGUgY2hhcmFjdGVyIGRhdGEKKyAqICAgIHNob3VsZCBiZSAiMTIzMCBOb3J0aCBBdmUuIERhbGxhcywgVGV4YXMiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03QzYwMzc4MTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFlbmQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZW5kKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZERhdGE7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgY2hpbGQuZGVsZXRlRGF0YSgzMCwgNSk7CisgICAgICBjaGlsZERhdGEgPSBjaGlsZC5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlcmRhdGFEZWxldGVEYXRhRW5kQXNzZXJ0IiwgIjEyMzAgTm9ydGggQXZlLiBEYWxsYXMsIFRleGFzICIsIGNoaWxkRGF0YSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZW5kIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWVuZC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFleGNlZWRzbGVuZ3RoLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZXhjZWVkc2xlbmd0aC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVjNjBiZmMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZXhjZWVkc2xlbmd0aC5qYXZhCkBAIC0wLDAgKzEsOTcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZSBzdW0gb2YgdGhlIG9mZnNldCBhbmQgY291bnQgdXNlZCBpbiB0aGUgICAgICAgIAorICogICAgImRlbGV0ZURhdGEob2Zmc2V0LGNvdW50KSBtZXRob2QgaXMgZ3JlYXRlciB0aGFuIHRoZQorICogICAgbGVuZ3RoIG9mIHRoZSBjaGFyYWN0ZXIgZGF0YSB0aGVuIGFsbCB0aGUgY2hhcmFjdGVycworICogICAgZnJvbSB0aGUgb2Zmc2V0IHRvIHRoZSBlbmQgb2YgdGhlIGRhdGEgYXJlIGRlbGV0ZWQuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgZnJvbSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqICAgIGZpcnN0IGVtcGxveWVlLiAgVGhlICJkZWxldGVEYXRhKG9mZnNldCxjb3VudCkiCisgKiAgICBtZXRob2QgaXMgdGhlbiBjYWxsZWQgd2l0aCBvZmZzZXQ9NCBhbmQgY291bnQ9NTAuCisgKiAgICBUaGUgbWV0aG9kIHNob3VsZCBkZWxldGUgdGhlIGNoYXJhY3RlcnMgZnJvbSBwb3NpdGlvbiA0CisgKiAgICB0byB0aGUgZW5kIG9mIHRoZSBkYXRhIHNpbmNlIHRoZSBvZmZzZXQrY291bnQoNTArNCkKKyAqICAgIGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoZSBjaGFyYWN0ZXIgZGF0YSgzNSkuCisgKiAgICBUaGUgbmV3IHZhbHVlIG9mIHRoZSBjaGFyYWN0ZXIgZGF0YSBzaG91bGQgYmUgIjEyMzAiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03QzYwMzc4MTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFleGNlZWRzbGVuZ3RoIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWV4Y2VlZHNsZW5ndGgoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkRGF0YTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZC5kZWxldGVEYXRhKDQsIDUwKTsKKyAgICAgIGNoaWxkRGF0YSA9IGNoaWxkLmdldERhdGEoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2hhcmFjdGVyZGF0YURlbGV0ZURhdGFFeGNlZWRzTGVuZ3RoQXNzZXJ0IiwgIjEyMzAiLCBjaGlsZERhdGEpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWV4Y2VlZHNsZW5ndGgiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZXhjZWVkc2xlbmd0aC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFnZXRsZW5ndGhhbmRkYXRhLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZ2V0bGVuZ3RoYW5kZGF0YS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFhN2ZlMzIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZ2V0bGVuZ3RoYW5kZGF0YS5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBPbiBzdWNjZXNzZnVsIGludm9jYXRpb24gb2YgdGhlICJkZWxldGVEYXRhKG9mZnNldCxjb3VudCkiCisgKiAgICBtZXRob2QsIHRoZSAiZ2V0RGF0YSgpIiBhbmQgImdldExlbmd0aCgpIiBtZXRob2RzIHJlZmxlY3QKKyAqICAgIHRoZSBjaGFuZ2VzLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiAgICBmaXJzdCBlbXBsb3llZS4gIFRoZSAiZGVsZXRlRGF0YShvZmZzZXQsY291bnQpIgorICogICAgbWV0aG9kIGlzIHRoZW4gY2FsbGVkIHdpdGggb2Zmc2V0PTMwIGFuZCBjb3VudD01LgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgZGVsZXRlIHRoZSBjaGFyYWN0ZXJzIGZyb20gcG9zaXRpb24KKyAqICAgIDMwIHRocnUgcG9zaXRpb24gMzUuICBUaGUgbmV3IHZhbHVlIG9mIHRoZSBjaGFyYWN0ZXIgZGF0YQorICogICAgc2hvdWxkIGJlICIxMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyIgd2hpY2ggaXMKKyAqICAgIHJldHVybmVkIGJ5IHRoZSAiZ2V0RGF0YSgpIiBtZXRob2QgYW5kICJnZXRMZW5ndGgoKSIKKyAqICAgIG1ldGhvZCBzaG91bGQgcmV0dXJuIDMwIi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03RDYxMTc4QyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0Q2MTE3OEM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0M2MDM3ODEiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWdldGxlbmd0aGFuZGRhdGEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZ2V0bGVuZ3RoYW5kZGF0YShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGREYXRhOworICAgICAgaW50IGNoaWxkTGVuZ3RoOworICAgICAgamF2YS51dGlsLkxpc3QgcmVzdWx0ID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIAorICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkLmRlbGV0ZURhdGEoMzAsIDUpOworICAgICAgY2hpbGREYXRhID0gY2hpbGQuZ2V0RGF0YSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkYXRhIiwgIjEyMzAgTm9ydGggQXZlLiBEYWxsYXMsIFRleGFzICIsIGNoaWxkRGF0YSk7CisgICAgICBjaGlsZExlbmd0aCA9IChpbnQpIGNoaWxkLmdldExlbmd0aCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJsZW5ndGgiLCAzMCwgY2hpbGRMZW5ndGgpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YWdldGxlbmd0aGFuZGRhdGEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhZ2V0bGVuZ3RoYW5kZGF0YS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFtaWRkbGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFtaWRkbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NzJlMTM2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YW1pZGRsZS5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZGVsZXRlRGF0YShvZmZzZXQsY291bnQpIiBtZXRob2QgcmVtb3ZlcyBhIHJhbmdlIG9mIAorICogICAgY2hhcmFjdGVycyBmcm9tIHRoZSBub2RlLiAgRGVsZXRlIGRhdGEgaW4gdGhlIG1pZGRsZSAKKyAqICAgIG9mIHRoZSBjaGFyYWN0ZXIgZGF0YS4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiAgICBmaXJzdCBlbXBsb3llZS4gIFRoZSAiZGVsZXRlRGF0YShvZmZzZXQsY291bnQpIgorICogICAgbWV0aG9kIGlzIHRoZW4gY2FsbGVkIHdpdGggb2Zmc2V0PTE2IGFuZCBjb3VudD04LgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgZGVsZXRlIHRoZSBjaGFyYWN0ZXJzIGZyb20gcG9zaXRpb24KKyAqICAgIDE2IHRocnUgcG9zaXRpb24gMjQuICBUaGUgbmV3IHZhbHVlIG9mIHRoZSBjaGFyYWN0ZXIgZGF0YQorICogICAgc2hvdWxkIGJlICIxMjMwIE5vcnRoIEF2ZS4gVGV4YXMgOTg1NTEiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03QzYwMzc4MTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfY2hhcmFjdGVyZGF0YWRlbGV0ZWRhdGFtaWRkbGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhbWlkZGxlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZERhdGE7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgY2hpbGQuZGVsZXRlRGF0YSgxNiwgOCk7CisgICAgICBjaGlsZERhdGEgPSBjaGlsZC5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlcmRhdGFEZWxldGVEYXRhTWlkZGxlQXNzZXJ0IiwgIjEyMzAgTm9ydGggQXZlLiBUZXhhcyA5ODU1MSIsIGNoaWxkRGF0YSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFkZWxldGVkYXRhbWlkZGxlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19jaGFyYWN0ZXJkYXRhZGVsZXRlZGF0YW1pZGRsZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWdldGRhdGEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWdldGRhdGEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MzU4MmE5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhZ2V0ZGF0YS5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0RGF0YSgpIiBtZXRob2QgcmV0cmlldmVzIHRoZSBjaGFyYWN0ZXIgZGF0YSAKKyAqICAgY3VycmVudGx5IHN0b3JlZCBpbiB0aGUgbm9kZS4KKyAqICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIHNlY29uZCBjaGlsZCAKKyAqICAgb2YgdGhlIGZpcnN0IGVtcGxveWVlIGFuZCBpbnZva2UgdGhlICJnZXREYXRhKCkiIAorICogICBtZXRob2QuICBUaGUgbWV0aG9kIHJldHVybnMgdGhlIGNoYXJhY3RlciBkYXRhIAorICogICBzdHJpbmcuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2NoYXJhY3RlcmRhdGFnZXRkYXRhIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19jaGFyYWN0ZXJkYXRhZ2V0ZGF0YShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkRGF0YTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgic3Ryb25nIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZERhdGEgPSBjaGlsZC5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlcmRhdGFHZXREYXRhQXNzZXJ0IiwgIk1hcmdhcmV0IE1hcnRpbiIsIGNoaWxkRGF0YSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFnZXRkYXRhIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19jaGFyYWN0ZXJkYXRhZ2V0ZGF0YS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWdldGxlbmd0aC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhZ2V0bGVuZ3RoLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTgxY2E0MgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWdldGxlbmd0aC5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0TGVuZ3RoKCkiIG1ldGhvZCByZXR1cm5zIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyAKKyAqICAgc3RvcmVkIGluIHRoaXMgbm9kZXMgZGF0YS4KKyAqICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIHNlY29uZCAKKyAqICAgY2hpbGQgb2YgdGhlIGZpcnN0IGVtcGxveWVlIGFuZCBleGFtaW5lIHRoZSAKKyAqICAgdmFsdWUgcmV0dXJuZWQgYnkgdGhlIGdldExlbmd0aCgpIG1ldGhvZC4gIAorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdENjExNzhDIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03RDYxMTc4QzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfY2hhcmFjdGVyZGF0YWdldGxlbmd0aCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfY2hhcmFjdGVyZGF0YWdldGxlbmd0aChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkVmFsdWU7CisgICAgICBpbnQgY2hpbGRMZW5ndGg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInN0cm9uZyIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgY2hpbGRWYWx1ZSA9IGNoaWxkLmdldERhdGEoKTsKKyAgICAgIGNoaWxkTGVuZ3RoID0gY2hpbGRWYWx1ZS5sZW5ndGgoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2hhcmFjdGVyZGF0YUdldExlbmd0aEFzc2VydCIsIDE1LCBjaGlsZExlbmd0aCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFnZXRsZW5ndGgiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2NoYXJhY3RlcmRhdGFnZXRsZW5ndGguY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhY291bnRuZWdhdGl2ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyZGVsZXRlZGF0YWNvdW50bmVnYXRpdmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNDFiNTE1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyZGVsZXRlZGF0YWNvdW50bmVnYXRpdmUuamF2YQpAQCAtMCwwICsxLDEwNyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJkZWxldGVEYXRhKG9mZnNldCxjb3VudCkiIG1ldGhvZCByYWlzZXMgYW4KKyAqICAgIElOREVYX1NJWkVfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGNvdW50IAorICogICAgaXMgbmVnYXRpdmUuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgb2YgdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiAgICBmaXJzdCBlbXBsb3llZSBhbmQgaW52b2tlIGl0cyAiZGVsZXRlRGF0YShvZmZzZXQsY291bnQpIgorICogICAgbWV0aG9kIHdpdGggb2Zmc2V0PTEwIGFuZCBjb3VudD0tMy4gIEl0IHNob3VsZCByYWlzZSB0aGUKKyAqICAgIGRlc2lyZWQgZXhjZXB0aW9uIHNpbmNlIHRoZSBjb3VudCBpcyBuZWdhdGl2ZS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTY1MzFCQ0NGIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NTMxQkNDRjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNjUzMUJDQ0YnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTY1MzFCQ0NGJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhY291bnRuZWdhdGl2ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFjb3VudG5lZ2F0aXZlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLnNpZ25lZAorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGRTdWJzdHJpbmc7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGlsZFN1YnN0cmluZyA9IGNoaWxkLnN1YnN0cmluZ0RhdGEoMTAsIC0zKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dzX0lOREVYX1NJWkVfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhY291bnRuZWdhdGl2ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFjb3VudG5lZ2F0aXZlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyZGVsZXRlZGF0YW9mZnNldGdyZWF0ZXIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFvZmZzZXRncmVhdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmYzZjhjYgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFvZmZzZXRncmVhdGVyLmphdmEKQEAgLTAsMCArMSwxMDMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJkZWxldGVEYXRhKG9mZnNldCxjb3VudCkiIG1ldGhvZCByYWlzZXMgYW4KKyAqICAgIElOREVYX1NJWkVfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIG9mZnNldAorICogICAgaXMgZ3JlYXRlciB0aGF0IHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgc3RyaW5nLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIG9mIHRoZSBsYXN0IGNoaWxkIG9mIHRoZQorICogICAgZmlyc3QgZW1wbG95ZWUgYW5kIGludm9rZSBpdHMgImRlbGV0ZURhdGEob2Zmc2V0LGNvdW50KSIKKyAqICAgIG1ldGhvZCB3aXRoIG9mZnNldD00MCBhbmQgY291bnQ9My4gIEl0IHNob3VsZCByYWlzZSB0aGUKKyAqICAgIGRlc2lyZWQgZXhjZXB0aW9uIHNpbmNlIHRoZSBvZmZzZXQgaXMgZ3JlYXRlciB0aGFuIHRoZQorICogICAgbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gdGhlIHN0cmluZy4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03QzYwMzc4MTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtN0M2MDM3ODEnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTdDNjAzNzgxJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0M2MDM3ODEiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhb2Zmc2V0Z3JlYXRlciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFvZmZzZXRncmVhdGVyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNoaWxkLmRlbGV0ZURhdGEoNDAsIDMpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTkRFWF9TSVpFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTkRFWF9TSVpFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyZGVsZXRlZGF0YW9mZnNldGdyZWF0ZXIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhb2Zmc2V0Z3JlYXRlci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFvZmZzZXRuZWdhdGl2ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyZGVsZXRlZGF0YW9mZnNldG5lZ2F0aXZlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzNmNzNhNwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFvZmZzZXRuZWdhdGl2ZS5qYXZhCkBAIC0wLDAgKzEsMTA3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImRlbGV0ZURhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kIHJhaXNlcyBhbgorICogICAgSU5ERVhfU0laRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgb2Zmc2V0CisgKiAgICBpcyBuZWdhdGl2ZS4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBvZiB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqICAgIGZpcnN0IGVtcGxveWVlIGFuZCBpbnZva2UgaXRzICJkZWxldGVEYXRhKG9mZnNldCxjb3VudCkiCisgKiAgICBtZXRob2Qgd2l0aCBvZmZzZXQ9LTUgYW5kIGNvdW50PTMuICBJdCBzaG91bGQgcmFpc2UgdGhlCisgKiAgICBkZXNpcmVkIGV4Y2VwdGlvbiBzaW5jZSB0aGUgb2Zmc2V0IGlzIG5lZ2F0aXZlLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0M2MDM3ODEiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC03QzYwMzc4MScpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtN0M2MDM3ODEnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03QzYwMzc4MSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0M2MDM3ODE8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhb2Zmc2V0bmVnYXRpdmUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJkZWxldGVkYXRhb2Zmc2V0bmVnYXRpdmUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcuc2lnbmVkCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNoaWxkLmRlbGV0ZURhdGEoLTUsIDMpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTkRFWF9TSVpFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd3NfSU5ERVhfU0laRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFvZmZzZXRuZWdhdGl2ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmRlbGV0ZWRhdGFvZmZzZXRuZWdhdGl2ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmluc2VydGRhdGFvZmZzZXRncmVhdGVyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJpbnNlcnRkYXRhb2Zmc2V0Z3JlYXRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRkMTc0NjMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJpbnNlcnRkYXRhb2Zmc2V0Z3JlYXRlci5qYXZhCkBAIC0wLDAgKzEsMTAyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW5zZXJ0RGF0YShvZmZzZXQsYXJnKSIgbWV0aG9kIHJhaXNlcyBhbgorICogICAgSU5ERVhfU0laRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgb2Zmc2V0CisgKiAgICBpcyBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIHRoZSBzdHJpbmcuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgb2YgdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiAgICBmaXJzdCBlbXBsb3llZSBhbmQgaW52b2tlIGl0cyBpbnNlcnREYXRhIihvZmZzZXQsYXJnKSIKKyAqICAgIG1ldGhvZCB3aXRoIG9mZnNldD00MCBhbmQgYXJnPSJBQkMiLiAgSXQgc2hvdWxkIHJhaXNlCisgKiAgICB0aGUgZGVzaXJlZCBleGNlcHRpb24gc2luY2UgdGhlIG9mZnNldCBpcyBncmVhdGVyIHRoYW4KKyAqICAgIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgc3RyaW5nLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtN0M2MDM3ODEiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC03QzYwMzc4MScpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtN0M2MDM3ODEnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyaW5zZXJ0ZGF0YW9mZnNldGdyZWF0ZXIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJpbnNlcnRkYXRhb2Zmc2V0Z3JlYXRlcihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGlsZC5kZWxldGVEYXRhKDQwLCAzKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSU5ERVhfU0laRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmluc2VydGRhdGFvZmZzZXRncmVhdGVyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyaW5zZXJ0ZGF0YW9mZnNldGdyZWF0ZXIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJpbnNlcnRkYXRhb2Zmc2V0bmVnYXRpdmUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmluc2VydGRhdGFvZmZzZXRuZWdhdGl2ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdhZWExMDYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJpbnNlcnRkYXRhb2Zmc2V0bmVnYXRpdmUuamF2YQpAQCAtMCwwICsxLDEwNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJpbnNlcnREYXRhKG9mZnNldCxhcmcpIiBtZXRob2QgcmFpc2VzIGFuCisgKiAgICBJTkRFWF9TSVpFX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBvZmZzZXQKKyAqICAgIGlzIG5lZ2F0aXZlLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIG9mIHRoZSBsYXN0IGNoaWxkIG9mIHRoZQorICogICAgZmlyc3QgZW1wbG95ZWUgYW5kIGludm9rZSBpdHMgaW5zZXJ0RGF0YSIob2Zmc2V0LGFyZykiCisgKiAgICBtZXRob2Qgd2l0aCBvZmZzZXQ9LTUgYW5kIGFyZz0iQUJDIi4gIEl0IHNob3VsZCByYWlzZQorICogICAgdGhlIGRlc2lyZWQgZXhjZXB0aW9uIHNpbmNlIHRoZSBvZmZzZXQgaXMgbmVnYXRpdmUuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1FNUNCQTdGQiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRTVDQkE3RkI8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELUU1Q0JBN0ZCJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC1FNUNCQTdGQicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyaW5zZXJ0ZGF0YW9mZnNldG5lZ2F0aXZlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyaW5zZXJ0ZGF0YW9mZnNldG5lZ2F0aXZlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLnNpZ25lZAorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGlsZC5yZXBsYWNlRGF0YSgtNSwgMywgIkFCQyIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTkRFWF9TSVpFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd3NfSU5ERVhfU0laRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmluc2VydGRhdGFvZmZzZXRuZWdhdGl2ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycmluc2VydGRhdGFvZmZzZXRuZWdhdGl2ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhY291bnRuZWdhdGl2ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJycmVwbGFjZWRhdGFjb3VudG5lZ2F0aXZlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDVlYWJjNwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhY291bnRuZWdhdGl2ZS5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIiBtZXRob2QgcmFpc2VzIGFuCisgKiAgICBJTkRFWF9TSVpFX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBjb3VudAorICogICAgaXMgbmVnYXRpdmUuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgb2YgdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiAgICBmaXJzdCBlbXBsb3llZSBhbmQgaW52b2tlIGl0cworICogICAgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIG1ldGhvZCB3aXRoIG9mZnNldD0xMAorICogICAgYW5kIGNvdW50PS0zIGFuZCBhcmc9IkFCQyIuICBJdCBzaG91bGQgcmFpc2UgdGhlCisgKiAgICBkZXNpcmVkIGV4Y2VwdGlvbiBzaW5jZSB0aGUgY291bnQgaXMgbmVnYXRpdmUuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NTMxQkNDRiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjUzMUJDQ0Y8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTY1MzFCQ0NGJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC02NTMxQkNDRicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJycmVwbGFjZWRhdGFjb3VudG5lZ2F0aXZlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJycmVwbGFjZWRhdGFjb3VudG5lZ2F0aXZlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLnNpZ25lZAorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgYmFkU3RyaW5nOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgYmFkU3RyaW5nID0gY2hpbGQuc3Vic3RyaW5nRGF0YSgxMCwgLTMpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTkRFWF9TSVpFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd3NfSU5ERVhfU0laRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhY291bnRuZWdhdGl2ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhY291bnRuZWdhdGl2ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhb2Zmc2V0Z3JlYXRlci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJycmVwbGFjZWRhdGFvZmZzZXRncmVhdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2FmNTA3ZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhb2Zmc2V0Z3JlYXRlci5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAicmVwbGFjZURhdGEob2Zmc2V0LGNvdW50LGFyZykiIG1ldGhvZCByYWlzZXMgYW4KKyAqICAgIElOREVYX1NJWkVfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIG9mZnNldAorICogICAgaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YgdGhlIHN0cmluZy4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBvZiB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqICAgIGZpcnN0IGVtcGxveWVlIGFuZCBpbnZva2UgaXRzCisgKiAgICAicmVwbGFjZURhdGEob2Zmc2V0LGNvdW50LGFyZykgbWV0aG9kIHdpdGggb2Zmc2V0PTQwCisgKiAgICBhbmQgY291bnQ9MyBhbmQgYXJnPSJBQkMiLiAgSXQgc2hvdWxkIHJhaXNlIHRoZQorICogICAgZGVzaXJlZCBleGNlcHRpb24gc2luY2UgdGhlIG9mZnNldCBpcyBncmVhdGVyIHRoYW4gdGhlCisgKiAgICBsZW5ndGggb2YgdGhlIHN0cmluZy4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTdDNjAzNzgxIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03QzYwMzc4MTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtN0M2MDM3ODEnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTdDNjAzNzgxJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0MiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0MjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhb2Zmc2V0Z3JlYXRlciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhb2Zmc2V0Z3JlYXRlcihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGlsZC5kZWxldGVEYXRhKDQwLCAzKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSU5ERVhfU0laRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhb2Zmc2V0Z3JlYXRlciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhb2Zmc2V0Z3JlYXRlci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhb2Zmc2V0bmVnYXRpdmUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnJlcGxhY2VkYXRhb2Zmc2V0bmVnYXRpdmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYjkzZWU5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJycmVwbGFjZWRhdGFvZmZzZXRuZWdhdGl2ZS5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIiBtZXRob2QgcmFpc2VzIGFuCisgKiAgICBJTkRFWF9TSVpFX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBvZmZzZXQKKyAqICAgIGlzIG5lZ2F0aXZlLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIG9mIHRoZSBsYXN0IGNoaWxkIG9mIHRoZQorICogICAgZmlyc3QgZW1wbG95ZWUgYW5kIGludm9rZSBpdHMKKyAqICAgICJyZXBsYWNlRGF0YShvZmZzZXQsY291bnQsYXJnKSBtZXRob2Qgd2l0aCBvZmZzZXQ9LTUKKyAqICAgIGFuZCBjb3VudD0zIGFuZCBhcmc9IkFCQyIuICBJdCBzaG91bGQgcmFpc2UgdGhlCisgKiAgICBkZXNpcmVkIGV4Y2VwdGlvbiBzaW5jZSB0aGUgb2Zmc2V0IGlzIG5lZ2F0aXZlLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRTVDQkE3RkIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU1Q0JBN0ZCPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC1FNUNCQTdGQicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtRTVDQkE3RkInKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1FNUNCQTdGQiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRTVDQkE3RkI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJyZXBsYWNlZGF0YW9mZnNldG5lZ2F0aXZlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJycmVwbGFjZWRhdGFvZmZzZXRuZWdhdGl2ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5zaWduZWQKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgY2hpbGQucmVwbGFjZURhdGEoLTUsIDMsICJBQkMiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dzX0lOREVYX1NJWkVfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJyZXBsYWNlZGF0YW9mZnNldG5lZ2F0aXZlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJycmVwbGFjZWRhdGFvZmZzZXRuZWdhdGl2ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ2NvdW50bmVnYXRpdmUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ2NvdW50bmVnYXRpdmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZDNiYzUzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nY291bnRuZWdhdGl2ZS5qYXZhCkBAIC0wLDAgKzEsMTA3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInN1YnN0cmluZ0RhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kIHJhaXNlcyBhbgorICogICAgSU5ERVhfU0laRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgY291bnQgCisgKiAgICBpcyBuZWdhdGl2ZS4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBvZiB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqICAgIGZpcnN0IGVtcGxveWVlIGFuZCBpbnZva2UgaXRzICJzdWJzdHJpbmdEYXRhKG9mZnNldCxjb3VudCkKKyAqICAgIG1ldGhvZCB3aXRoIG9mZnNldD0xMCBhbmQgY291bnQ9LTMuICBJdCBzaG91bGQgcmFpc2UgdGhlCisgKiAgICBkZXNpcmVkIGV4Y2VwdGlvbiBzaW5jZSB0aGUgY291bnQgaXMgbmVnYXRpdmUuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NTMxQkNDRiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjUzMUJDQ0Y8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTY1MzFCQ0NGJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC02NTMxQkNDRicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nY291bnRuZWdhdGl2ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ2NvdW50bmVnYXRpdmUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcuc2lnbmVkCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgYmFkU3Vic3RyaW5nOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJhZFN1YnN0cmluZyA9IGNoaWxkLnN1YnN0cmluZ0RhdGEoMTAsIC0zKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dzX0lOREVYX1NJWkVfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJzdWJzdHJpbmdjb3VudG5lZ2F0aXZlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nY291bnRuZWdhdGl2ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ25lZ2F0aXZlb2Zmc2V0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJzdWJzdHJpbmduZWdhdGl2ZW9mZnNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE3Y2NkMmQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJzdWJzdHJpbmduZWdhdGl2ZW9mZnNldC5qYXZhCkBAIC0wLDAgKzEsMTA3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInN1YnN0cmluZ0RhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kIHJhaXNlcyBhbgorICogICAgSU5ERVhfU0laRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgb2Zmc2V0CisgKiAgICBpcyBuZWdhdGl2ZS4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBvZiB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqICAgIGZpcnN0IGVtcGxveWVlIGFuZCBpbnZva2UgaXRzICJzdWJzdHJpbmdEYXRhKG9mZnNldCxjb3VudCkKKyAqICAgIG1ldGhvZCB3aXRoIG9mZnNldD0tNSBhbmQgY291bnQ9My4gIEl0IHNob3VsZCByYWlzZSB0aGUKKyAqICAgIGRlc2lyZWQgZXhjZXB0aW9uIHNpbmNlIHRoZSBvZmZzZXQgaXMgbmVnYXRpdmUuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NTMxQkNDRiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjUzMUJDQ0Y8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTY1MzFCQ0NGJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC02NTMxQkNDRicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nbmVnYXRpdmVvZmZzZXQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJzdWJzdHJpbmduZWdhdGl2ZW9mZnNldChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5zaWduZWQKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBiYWRTdHJpbmc7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgYmFkU3RyaW5nID0gY2hpbGQuc3Vic3RyaW5nRGF0YSgtNSwgMyk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOREVYX1NJWkVfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93c19JTkRFWF9TSVpFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nbmVnYXRpdmVvZmZzZXQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJzdWJzdHJpbmduZWdhdGl2ZW9mZnNldC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ29mZnNldGdyZWF0ZXIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ29mZnNldGdyZWF0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kM2QyYjJmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nb2Zmc2V0Z3JlYXRlci5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInN1YnN0cmluZ0RhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kIHJhaXNlcyBhbgorICogICAgSU5ERVhfU0laRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgb2Zmc2V0CisgKiAgICBpcyBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIHRoZSBzdHJpbmcuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBvZiB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqICAgIGZpcnN0IGVtcGxveWVlIGFuZCBpbnZva2UgaXRzICJzdWJzdHJpbmdEYXRhKG9mZnNldCxjb3VudCkKKyAqICAgIG1ldGhvZCB3aXRoIG9mZnNldD00MCBhbmQgY291bnQ9My4gIEl0IHNob3VsZCByYWlzZSB0aGUKKyAqICAgIGRlc2lyZWQgZXhjZXB0aW9uIHNpbmNlIHRoZSBvZmZzZXRzIHZhbHVlIGlzIGdyZWF0ZXIKKyAqICAgIHRoYW4gdGhlIGxlbmd0aC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTY1MzFCQ0NGIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NTMxQkNDRjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNjUzMUJDQ0YnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTY1MzFCQ0NGJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ29mZnNldGdyZWF0ZXIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2NoYXJhY3RlcmRhdGFpbmRleHNpemVlcnJzdWJzdHJpbmdvZmZzZXRncmVhdGVyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgYmFkU3RyaW5nOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJhZFN0cmluZyA9IGNoaWxkLnN1YnN0cmluZ0RhdGEoNDAsIDMpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTkRFWF9TSVpFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTkRFWF9TSVpFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5kZXhzaXplZXJyc3Vic3RyaW5nb2Zmc2V0Z3JlYXRlciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfY2hhcmFjdGVyZGF0YWluZGV4c2l6ZWVycnN1YnN0cmluZ29mZnNldGdyZWF0ZXIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhYmVnaW5uaW5nLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhYmVnaW5uaW5nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzE0MmU5ZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluc2VydGRhdGFiZWdpbm5pbmcuamF2YQpAQCAtMCwwICsxLDkzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIFRoZSAiaW5zZXJ0RGF0YShvZmZzZXQsYXJnKSIgbWV0aG9kIHdpbGwgaW5zZXJ0IGEgc3RyaW5nCisgKiBhdCB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBvZmZzZXQuICBJbnNlcnQgdGhlIGRhdGEgYXQKKyAqIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGNoYXJhY3RlciBkYXRhLgorICogUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIHNlY29uZCBjaGlsZCBvZgorICogdGhlIGZpcnN0IGVtcGxveWVlLiAgVGhlICJpbnNlcnREYXRhKG9mZnNldCxhcmcpIgorICogbWV0aG9kIGlzIHRoZW4gY2FsbGVkIHdpdGggb2Zmc2V0PTAgYW5kIGFyZz0iTXNzLiIuCisgKiBUaGUgbWV0aG9kIHNob3VsZCBpbnNlcnQgdGhlIHN0cmluZyAiTXNzLiIgYXQgcG9zaXRpb24gMC4KKyAqIFRoZSBuZXcgdmFsdWUgb2YgdGhlIGNoYXJhY3RlciBkYXRhIHNob3VsZCBiZQorICogIk1zcy4gTWFyZ2FyZXQgTWFydGluIi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTNFREI2OTVGIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zRURCNjk1RjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfY2hhcmFjdGVyZGF0YWluc2VydGRhdGFiZWdpbm5pbmcgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhYmVnaW5uaW5nKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZERhdGE7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgic3Ryb25nIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZC5pbnNlcnREYXRhKDAsICJNc3MuICIpOworICAgICAgY2hpbGREYXRhID0gY2hpbGQuZ2V0RGF0YSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyYWN0ZXJkYXRhSW5zZXJ0RGF0YUJlZ2lubmluZ0Fzc2VydCIsICJNc3MuIE1hcmdhcmV0IE1hcnRpbiIsIGNoaWxkRGF0YSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhYmVnaW5uaW5nIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YWJlZ2lubmluZy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluc2VydGRhdGFlbmQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluc2VydGRhdGFlbmQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYzcyMThmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YWVuZC5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW5zZXJ0RGF0YShvZmZzZXQsYXJnKSIgbWV0aG9kIHdpbGwgaW5zZXJ0IGEgc3RyaW5nIAorICogICAgYXQgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgb2Zmc2V0LiAgSW5zZXJ0IHRoZSBkYXRhIGF0IAorICogICAgdGhlIGVuZCBvZiB0aGUgY2hhcmFjdGVyIGRhdGEuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgZnJvbSB0aGUgc2Vjb25kIGNoaWxkIG9mICAKKyAqICAgIHRoZSBmaXJzdCBlbXBsb3llZS4gIFRoZSAiaW5zZXJ0RGF0YShvZmZzZXQsYXJnKSIKKyAqICAgIG1ldGhvZCBpcyB0aGVuIGNhbGxlZCB3aXRoIG9mZnNldD0xNSBhbmQgYXJnPSIsIEVzcXVpcmUiLgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgaW5zZXJ0IHRoZSBzdHJpbmcgIiwgRXNxdWlyZSIgYXQgCisgKiAgICBwb3NpdGlvbiAxNS4gIFRoZSBuZXcgdmFsdWUgb2YgdGhlIGNoYXJhY3RlciBkYXRhIHNob3VsZAorICogICAgYmUgIk1hcmdhcmV0IE1hcnRpbiwgRXNxdWlyZSIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtM0VEQjY5NUYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTNFREI2OTVGPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YWVuZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfY2hhcmFjdGVyZGF0YWluc2VydGRhdGFlbmQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkRGF0YTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJzdHJvbmciKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkLmluc2VydERhdGEoMTUsICIsIEVzcXVpcmUiKTsKKyAgICAgIGNoaWxkRGF0YSA9IGNoaWxkLmdldERhdGEoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2hhcmFjdGVyZGF0YUluc2VydERhdGFFbmRBc3NlcnQiLCAiTWFyZ2FyZXQgTWFydGluLCBFc3F1aXJlIiwgY2hpbGREYXRhKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluc2VydGRhdGFlbmQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhZW5kLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YW1pZGRsZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YW1pZGRsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE2MGZlNGQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhbWlkZGxlLmphdmEKQEAgLTAsMCArMSw5NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJpbnNlcnREYXRhKG9mZnNldCxhcmcpIiBtZXRob2Qgd2lsbCBpbnNlcnQgYSBzdHJpbmcgCisgKiAgICBhdCB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBvZmZzZXQuICBJbnNlcnQgdGhlIGRhdGEgaW4gCisgKiAgICB0aGUgbWlkZGxlIG9mIHRoZSBjaGFyYWN0ZXIgZGF0YS4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBmcm9tIHRoZSBzZWNvbmQgY2hpbGQgb2YgIAorICogICAgdGhlIGZpcnN0IGVtcGxveWVlLiAgVGhlICJpbnNlcnREYXRhKG9mZnNldCxhcmcpIgorICogICAgbWV0aG9kIGlzIHRoZW4gY2FsbGVkIHdpdGggb2Zmc2V0PTkgYW5kIGFyZz0iQW5uIi4KKyAqICAgIFRoZSBtZXRob2Qgc2hvdWxkIGluc2VydCB0aGUgc3RyaW5nICJBbm4iIGF0IHBvc2l0aW9uIDkuCisgKiAgICBUaGUgbmV3IHZhbHVlIG9mIHRoZSBjaGFyYWN0ZXIgZGF0YSBzaG91bGQgYmUKKyAqICAgICJNYXJnYXJldCBBbm4gTWFydGluIi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03MkFCODM1OTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zRURCNjk1RiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtM0VEQjY5NUY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhbWlkZGxlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19jaGFyYWN0ZXJkYXRhaW5zZXJ0ZGF0YW1pZGRsZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGREYXRhOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInN0cm9uZyIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgY2hpbGQgPSAoQ2hhcmFjdGVyRGF0YSkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgY2hpbGQuaW5zZXJ0RGF0YSg5LCAiQW5uICIpOworICAgICAgY2hpbGREYXRhID0gY2hpbGQuZ2V0RGF0YSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyYWN0ZXJkYXRhSW5zZXJ0RGF0YU1pZGRsZUFzc2VydCIsICJNYXJnYXJldCBBbm4gTWFydGluIiwgY2hpbGREYXRhKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YWluc2VydGRhdGFtaWRkbGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2NoYXJhY3RlcmRhdGFpbnNlcnRkYXRhbWlkZGxlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFiZWdpbmluZy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFiZWdpbmluZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2MmMxZGQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWJlZ2luaW5nLmphdmEKQEAgLTAsMCArMSw5MyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBUaGUgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIiBtZXRob2QgcmVwbGFjZXMgdGhlCisgKiBjaGFyYWN0ZXJzIHN0YXJ0aW5nIGF0IHRoZSBzcGVjaWZpZWQgb2Zmc2V0IHdpdGggdGhlCisgKiBzcGVjaWZpZWQgc3RyaW5nLiAgVGVzdCBmb3IgcmVwbGFjZW1lbnQgaW4gdGhlCisgKiBtaWRkbGUgb2YgdGhlIGRhdGEuCisgKiBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgZnJvbSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqIGZpcnN0IGVtcGxveWVlLiAgVGhlICJyZXBsYWNlRGF0YShvZmZzZXQsY291bnQsYXJnKSIKKyAqIG1ldGhvZCBpcyB0aGVuIGNhbGxlZCB3aXRoIG9mZnNldD01IGFuZCBjb3VudD01IGFuZAorICogYXJnPSJTb3V0aCIuICBUaGUgbWV0aG9kIHNob3VsZCByZXBsYWNlIGNoYXJhY3RlcnMgZml2ZQorICogdGhydSA5IG9mIHRoZSBjaGFyYWN0ZXIgZGF0YSB3aXRoICJTb3V0aCIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1FNUNCQTdGQiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRTVDQkE3RkI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWJlZ2luaW5nIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFiZWdpbmluZyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGREYXRhOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkLnJlcGxhY2VEYXRhKDAsIDQsICIyNTAwIik7CisgICAgICBjaGlsZERhdGEgPSBjaGlsZC5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlcmRhdGFSZXBsYWNlRGF0YUJlZ2luaW5nQXNzZXJ0IiwgIjI1MDAgTm9ydGggQXZlLiBEYWxsYXMsIFRleGFzIDk4NTUxIiwgY2hpbGREYXRhKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhYmVnaW5pbmciOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWJlZ2luaW5nLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFlbmQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZW5kLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2M4Njc5NAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZW5kLmphdmEKQEAgLTAsMCArMSw5NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZXBsYWNlRGF0YShvZmZzZXQsY291bnQsYXJnKSIgbWV0aG9kIHJlcGxhY2VzIHRoZSAKKyAqICAgIGNoYXJhY3RlcnMgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCBvZmZzZXQgd2l0aCB0aGUKKyAqICAgIHNwZWNpZmllZCBzdHJpbmcuICBUZXN0IGZvciByZXBsYWNlbWVudCBhdCB0aGUgCisgKiAgICBlbmQgb2YgdGhlIGRhdGEuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBmcm9tIHRoZSBsYXN0IGNoaWxkIG9mIHRoZQorICogICAgZmlyc3QgZW1wbG95ZWUuICBUaGUgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIgorICogICAgbWV0aG9kIGlzIHRoZW4gY2FsbGVkIHdpdGggb2Zmc2V0PTMwIGFuZCBjb3VudD01IGFuZAorICogICAgYXJnPSI5ODY2NSIuICBUaGUgbWV0aG9kIHNob3VsZCByZXBsYWNlIGNoYXJhY3RlcnMgMzAgIAorICogICAgdGhydSAzNCBvZiB0aGUgY2hhcmFjdGVyIGRhdGEgd2l0aCAiOTg2NjUiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU1Q0JBN0ZCIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1FNUNCQTdGQjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZW5kIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFlbmQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkRGF0YTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZC5yZXBsYWNlRGF0YSgzMCwgNSwgIjk4NjY1Iik7CisgICAgICBjaGlsZERhdGEgPSBjaGlsZC5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlcmRhdGFSZXBsYWNlRGF0YUVuZEFzc2VydCIsICIxMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyA5ODY2NSIsIGNoaWxkRGF0YSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWVuZCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZW5kLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFleGNlZWRzbGVuZ3Rob2ZhcmcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZXhjZWVkc2xlbmd0aG9mYXJnLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjQ1YzQ5YQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZXhjZWVkc2xlbmd0aG9mYXJnLmphdmEKQEAgLTAsMCArMSw5NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZXBsYWNlRGF0YShvZmZzZXQsY291bnQsYXJnKSIgbWV0aG9kIHJlcGxhY2VzIHRoZSAKKyAqICAgIGNoYXJhY3RlcnMgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCBvZmZzZXQgd2l0aCB0aGUKKyAqICAgIHNwZWNpZmllZCBzdHJpbmcuICBUZXN0IHRoZSBzaXR1YXRpb24gd2hlcmUgdGhlIGxlbmd0aCAKKyAqICAgIG9mIHRoZSBhcmcgc3RyaW5nIGlzIGdyZWF0ZXIgdGhhbiB0aGUgc3BlY2lmaWVkIG9mZnNldC4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiAgICBmaXJzdCBlbXBsb3llZS4gIFRoZSAicmVwbGFjZURhdGEob2Zmc2V0LGNvdW50LGFyZykiCisgKiAgICBtZXRob2QgaXMgdGhlbiBjYWxsZWQgd2l0aCBvZmZzZXQ9MCBhbmQgY291bnQ9NCBhbmQKKyAqICAgIGFyZz0iMjYwMDMwIi4gIFRoZSBtZXRob2Qgc2hvdWxkIHJlcGxhY2UgY2hhcmFjdGVycyBvbmUgIAorICogICAgdGhydSBmb3VyIHdpdGggIjI2MDAzMCIuICBOb3RlIHRoYXQgdGhlIGxlbmd0aCBvZiB0aGUKKyAqICAgIHNwZWNpZmllZCBzdHJpbmcgaXMgZ3JlYXRlciB0aGF0IHRoZSBzcGVjaWZpZWQgb2Zmc2V0LgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU1Q0JBN0ZCIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1FNUNCQTdGQjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZXhjZWVkc2xlbmd0aG9mYXJnIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFleGNlZWRzbGVuZ3Rob2ZhcmcoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkRGF0YTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZC5yZXBsYWNlRGF0YSgwLCA0LCAiMjYwMDMwIik7CisgICAgICBjaGlsZERhdGEgPSBjaGlsZC5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlcmRhdGFSZXBsYWNlRGF0YUV4Y2VlZHNMZW5ndGhPZkFyZ0Fzc2VydCIsICIyNjAwMzAgTm9ydGggQXZlLiBEYWxsYXMsIFRleGFzIDk4NTUxIiwgY2hpbGREYXRhKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZXhjZWVkc2xlbmd0aG9mYXJnIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFleGNlZWRzbGVuZ3Rob2ZhcmcuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWV4Y2VlZHNsZW5ndGhvZmRhdGEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZXhjZWVkc2xlbmd0aG9mZGF0YS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVmZTg4Y2MKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFyZXBsYWNlZGF0YWV4Y2VlZHNsZW5ndGhvZmRhdGEuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBJZiB0aGUgc3VtIG9mIHRoZSBvZmZzZXQgYW5kIGNvdW50IGV4Y2VlZHMgdGhlIGxlbmd0aCB0aGVuIAorICogICAgYWxsIHRoZSBjaGFyYWN0ZXJzIHRvIHRoZSBlbmQgb2YgdGhlIGRhdGEgYXJlIHJlcGxhY2VkLgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgZnJvbSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqICAgIGZpcnN0IGVtcGxveWVlLiAgVGhlICJyZXBsYWNlRGF0YShvZmZzZXQsY291bnQsYXJnKSIKKyAqICAgIG1ldGhvZCBpcyB0aGVuIGNhbGxlZCB3aXRoIG9mZnNldD0wIGFuZCBjb3VudD01MCBhbmQKKyAqICAgIGFyZz0iMjYwMCIuICBUaGUgbWV0aG9kIHNob3VsZCByZXBsYWNlIGFsbCB0aGUgY2hhcmFjdGVycworICogICAgd2l0aCAiMjYwMCIuIFRoaXMgaXMgYmVjYXVzZSB0aGUgc3VtIG9mIHRoZSBvZmZzZXQgYW5kCisgKiAgICBjb3VudCBleGNlZWRzIHRoZSBsZW5ndGggb2YgdGhlIGNoYXJhY3RlciBkYXRhLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU1Q0JBN0ZCIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1FNUNCQTdGQjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZXhjZWVkc2xlbmd0aG9mZGF0YSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhZXhjZWVkc2xlbmd0aG9mZGF0YShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGREYXRhOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkLnJlcGxhY2VEYXRhKDAsIDUwLCAiMjYwMCIpOworICAgICAgY2hpbGREYXRhID0gY2hpbGQuZ2V0RGF0YSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyYWN0ZXJkYXRhUmVwbGFjZURhdGFFeGNlZWRzTGVuZ3RoT2ZEYXRhQXNzZXJ0IiwgIjI2MDAiLCBjaGlsZERhdGEpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFleGNlZWRzbGVuZ3Rob2ZkYXRhIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFleGNlZWRzbGVuZ3Rob2ZkYXRhLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFtaWRkbGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhbWlkZGxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODdiMTA4MQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhbWlkZGxlLmphdmEKQEAgLTAsMCArMSw5NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZXBsYWNlRGF0YShvZmZzZXQsY291bnQsYXJnKSIgbWV0aG9kIHJlcGxhY2VzIHRoZSAKKyAqICAgIGNoYXJhY3RlcnMgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCBvZmZzZXQgd2l0aCB0aGUKKyAqICAgIHNwZWNpZmllZCBzdHJpbmcuICBUZXN0IGZvciByZXBsYWNlbWVudCBpbiB0aGUgCisgKiAgICBtaWRkbGUgb2YgdGhlIGRhdGEuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBjaGFyYWN0ZXIgZGF0YSBmcm9tIHRoZSBsYXN0IGNoaWxkIG9mIHRoZQorICogICAgZmlyc3QgZW1wbG95ZWUuICBUaGUgInJlcGxhY2VEYXRhKG9mZnNldCxjb3VudCxhcmcpIgorICogICAgbWV0aG9kIGlzIHRoZW4gY2FsbGVkIHdpdGggb2Zmc2V0PTUgYW5kIGNvdW50PTUgYW5kCisgKiAgICBhcmc9IlNvdXRoIi4gIFRoZSBtZXRob2Qgc2hvdWxkIHJlcGxhY2UgY2hhcmFjdGVycyBmaXZlICAKKyAqICAgIHRocnUgOSBvZiB0aGUgY2hhcmFjdGVyIGRhdGEgd2l0aCAiU291dGgiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU1Q0JBN0ZCIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1FNUNCQTdGQjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhbWlkZGxlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFtaWRkbGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkRGF0YTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZC5yZXBsYWNlRGF0YSg1LCA1LCAiU291dGgiKTsKKyAgICAgIGNoaWxkRGF0YSA9IGNoaWxkLmdldERhdGEoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2hhcmFjdGVyZGF0YVJlcGxhY2VEYXRhTWlkZGxlQXNzZXJ0IiwgIjEyMzAgU291dGggQXZlLiBEYWxsYXMsIFRleGFzIDk4NTUxIiwgY2hpbGREYXRhKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YXJlcGxhY2VkYXRhbWlkZGxlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19jaGFyYWN0ZXJkYXRhcmVwbGFjZWRhdGFtaWRkbGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFzZXRub2RldmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YXNldG5vZGV2YWx1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcxZDkzZmMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFzZXRub2RldmFsdWUuamF2YQpAQCAtMCwwICsxLDkyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgVGhlICJzZXROb2RlVmFsdWUoKSIgbWV0aG9kIGNoYW5nZXMgdGhlIGNoYXJhY3RlciBkYXRhIAorICogICBjdXJyZW50bHkgc3RvcmVkIGluIHRoZSBub2RlLgorICogICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgZnJvbSB0aGUgc2Vjb25kIGNoaWxkIAorICogICBvZiB0aGUgZmlyc3QgZW1wbG95ZWUgYW5kIGludm9rZSB0aGUgInNldE5vZGVWYWx1ZSgpIiAKKyAqICAgbWV0aG9kLCBjYWxsICJnZXREYXRhKCkiIGFuZCBjb21wYXJlLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzJBQjgzNTkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTcyQUI4MzU5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19jaGFyYWN0ZXJkYXRhc2V0bm9kZXZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19jaGFyYWN0ZXJkYXRhc2V0bm9kZXZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZERhdGE7CisgICAgICBTdHJpbmcgY2hpbGRWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJzdHJvbmciKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkLnNldE5vZGVWYWx1ZSgiTWFyaWx5biBNYXJ0aW4iKTsKKyAgICAgIGNoaWxkRGF0YSA9IGNoaWxkLmdldERhdGEoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZGF0YSIsICJNYXJpbHluIE1hcnRpbiIsIGNoaWxkRGF0YSk7CisgICAgICBjaGlsZFZhbHVlID0gY2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlIiwgIk1hcmlseW4gTWFydGluIiwgY2hpbGRWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFzZXRub2RldmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2NoYXJhY3RlcmRhdGFzZXRub2RldmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFzdWJzdHJpbmdleGNlZWRzdmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY2hhcmFjdGVyZGF0YXN1YnN0cmluZ2V4Y2VlZHN2YWx1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZjNjQ2ODgKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFzdWJzdHJpbmdleGNlZWRzdmFsdWUuamF2YQpAQCAtMCwwICsxLDkzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBJZiB0aGUgc3VtIG9mIHRoZSAib2Zmc2V0IiBhbmQgImNvdW50IiBleGNlZWRzIHRoZQorICogICAgImxlbmd0aCIgdGhlbiB0aGUgInN1YnN0cmluZ0RhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kCisgKiAgICByZXR1cm5zIGFsbCB0aGUgY2hhcmFjdGVycyB0byB0aGUgZW5kIG9mIHRoZSBkYXRhLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIHNlY29uZCBjaGlsZCAKKyAqICAgIG9mIHRoZSBmaXJzdCBlbXBsb3llZSBhbmQgYWNjZXNzIHBhcnQgb2YgdGhlIGRhdGEgCisgKiAgICBieSB1c2luZyB0aGUgc3Vic3RyaW5nRGF0YShvZmZzZXQsY291bnQpIG1ldGhvZAorICogICAgd2l0aCBvZmZzZXQ9OSBhbmQgY291bnQ9MTAuICBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gCisgKiAgICB0aGUgc3Vic3RyaW5nICJNYXJ0aW4iIHNpbmNlIG9mZnNldCtjb3VudCA+IGxlbmd0aAorICogICAgKDE5ID4gMTUpLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjUzMUJDQ0YiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTY1MzFCQ0NGPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19jaGFyYWN0ZXJkYXRhc3Vic3RyaW5nZXhjZWVkc3ZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19jaGFyYWN0ZXJkYXRhc3Vic3RyaW5nZXhjZWVkc3ZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIENoYXJhY3RlckRhdGEgY2hpbGQ7CisgICAgICBTdHJpbmcgc3Vic3RyaW5nOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJzdHJvbmciKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkID0gKENoYXJhY3RlckRhdGEpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIHN1YnN0cmluZyA9IGNoaWxkLnN1YnN0cmluZ0RhdGEoOSwgMTApOworICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyYWN0ZXJkYXRhU3ViU3RyaW5nRXhjZWVkc1ZhbHVlQXNzZXJ0IiwgIk1hcnRpbiIsIHN1YnN0cmluZyk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFzdWJzdHJpbmdleGNlZWRzdmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2NoYXJhY3RlcmRhdGFzdWJzdHJpbmdleGNlZWRzdmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2NoYXJhY3RlcmRhdGFzdWJzdHJpbmd2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhc3Vic3RyaW5ndmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MDUwZmJhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhc3Vic3RyaW5ndmFsdWUuamF2YQpAQCAtMCwwICsxLDkyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInN1YnN0cmluZ0RhdGEob2Zmc2V0LGNvdW50KSIgbWV0aG9kIHJldHVybnMgdGhlIAorICogICAgc3BlY2lmaWVkIHN0cmluZy4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlIHNlY29uZCBjaGlsZCAKKyAqICAgIG9mIHRoZSBmaXJzdCBlbXBsb3llZSBhbmQgYWNjZXNzIHBhcnQgb2YgdGhlIGRhdGEgCisgKiAgICBieSB1c2luZyB0aGUgc3Vic3RyaW5nRGF0YShvZmZzZXQsY291bnQpIG1ldGhvZC4gIFRoZQorICogICAgbWV0aG9kIHNob3VsZCByZXR1cm4gdGhlIHNwZWNpZmllZCBzdWJzdHJpbmcgc3RhcnRpbmcgCisgKiAgICBhdCBwb3NpdGlvbiAib2Zmc2V0IiBhbmQgZXh0cmFjdCAiY291bnQiIGNoYXJhY3RlcnMuCisgKiAgICBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gdGhlIHN0cmluZyAiTWFyZ2FyZXQiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjUzMUJDQ0YiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTY1MzFCQ0NGPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19jaGFyYWN0ZXJkYXRhc3Vic3RyaW5ndmFsdWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2NoYXJhY3RlcmRhdGFzdWJzdHJpbmd2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNoaWxkOworICAgICAgU3RyaW5nIHN1YnN0cmluZzsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgic3Ryb25nIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZCA9IChDaGFyYWN0ZXJEYXRhKSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBzdWJzdHJpbmcgPSBjaGlsZC5zdWJzdHJpbmdEYXRhKDAsIDgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyYWN0ZXJkYXRhU3ViU3RyaW5nVmFsdWVBc3NlcnQiLCAiTWFyZ2FyZXQiLCBzdWJzdHJpbmcpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19jaGFyYWN0ZXJkYXRhc3Vic3RyaW5ndmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2NoYXJhY3RlcmRhdGFzdWJzdHJpbmd2YWx1ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY29tbWVudGdldGNvbW1lbnQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfY29tbWVudGdldGNvbW1lbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NDZmOTc1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19jb21tZW50Z2V0Y29tbWVudC5qYXZhCkBAIC0wLDAgKzEsMTA2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIEEgY29tbWVudCBpcyBhbGwgdGhlIGNoYXJhY3RlcnMgYmV0d2VlbiB0aGUgc3RhcnRpbmcKKyAqICAgJzwhLS0nIGFuZCBlbmRpbmcgJy0tPicgCisgKiAgIFJldHJpZXZlIHRoZSBub2RlcyBvZiB0aGUgRE9NIGRvY3VtZW50LiAgU2VhcmNoIGZvciBhIAorICogICBjb21tZW50IG5vZGUgYW5kIHRoZSBjb250ZW50IGlzIGl0cyB2YWx1ZS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEzMzQ0ODEzMjgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEzMzQ0ODEzMjg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIzNzU1OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIzNzU1OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD01MDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD01MDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2NvbW1lbnRnZXRjb21tZW50IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19jb21tZW50Z2V0Y29tbWVudChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgU3RyaW5nIGNoaWxkVmFsdWU7CisgICAgICBpbnQgY29tbWVudENvdW50ID0gMDsKKyAgICAgIGludCBjaGlsZFR5cGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA1RSA9IDA7IGluZGV4TjEwMDVFIDwgZWxlbWVudExpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDVFKyspIHsKKyAgICAgICAgICBjaGlsZCA9IChOb2RlKSBlbGVtZW50TGlzdC5pdGVtKGluZGV4TjEwMDVFKTsKKyAgICBjaGlsZFR5cGUgPSAoaW50KSBjaGlsZC5nZXROb2RlVHlwZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDgsIGNoaWxkVHlwZSkpIHsKKyAgICAgICAgICBjaGlsZE5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTmFtZSIsICIjY29tbWVudCIsIGNoaWxkTmFtZSk7CisgICAgICBjaGlsZFZhbHVlID0gY2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVWYWx1ZSIsICIgVGhpcyBpcyBjb21tZW50IG51bWJlciAxLiIsIGNoaWxkVmFsdWUpOworICAgICAgYXR0cmlidXRlcyA9IGNoaWxkLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGFzc2VydE51bGwoImF0dHJpYnV0ZXMiLCBhdHRyaWJ1dGVzKTsKKyAgICAgIGNvbW1lbnRDb3VudCArPSAxOworICAgICAgfQorICAgICAgfQorICAgICAgYXNzZXJ0VHJ1ZSgiYXRNb3N0T25lQ29tbWVudCIsIChjb21tZW50Q291bnQgPCAyKSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2NvbW1lbnRnZXRjb21tZW50IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19jb21tZW50Z2V0Y29tbWVudC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ODNkYWJkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZS5qYXZhCkBAIC0wLDAgKzEsOTMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICBSZXRyaWV2ZSB0aGUgZW50aXJlIERPTSBkb2N1bWVudCBhbmQgaW52b2tlIGl0cyAKKyAqICAgICJjcmVhdGVBdHRyaWJ1dGUobmFtZSkiIG1ldGhvZC4gIEl0IHNob3VsZCBjcmVhdGUgYSAgCisgKiAgICBuZXcgQXR0cmlidXRlIG5vZGUgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4gVGhlIG5hbWUsIHZhbHVlCisgKiAgICBhbmQgdHlwZSBvZiB0aGUgbmV3bHkgY3JlYXRlZCBvYmplY3QgYXJlIHJldHJpZXZlZCBhbmQKKyAqICAgIG91dHB1dC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwODQ4OTExOTgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwODQ4OTExOTg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzNiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzNjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDNKdW4vMDAxMS5odG1sIj5odHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDNKdW4vMDAxMS5odG1sPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDMiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2RvY3VtZW50Y3JlYXRlYXR0cmlidXRlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEF0dHIgbmV3QXR0ck5vZGU7CisgICAgICBTdHJpbmcgYXR0clZhbHVlOworICAgICAgU3RyaW5nIGF0dHJOYW1lOworICAgICAgaW50IGF0dHJUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgbmV3QXR0ck5vZGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJ0aXRsZSIpOworICAgICAgYXR0clZhbHVlID0gbmV3QXR0ck5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlIiwgIiIsIGF0dHJWYWx1ZSk7CisgICAgICBhdHRyTmFtZSA9IG5ld0F0dHJOb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHNBdXRvQ2FzZSgiYXR0cmlidXRlIiwgIm5hbWUiLCAidGl0bGUiLCBhdHRyTmFtZSk7CisgICAgICAgIGF0dHJUeXBlID0gKGludCkgbmV3QXR0ck5vZGUuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIGFzc2VydEVxdWFscygidHlwZSIsIDIsIGF0dHJUeXBlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2RvY3VtZW50Y3JlYXRlYXR0cmlidXRlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGNyZWF0ZWNvbW1lbnQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRjcmVhdGVjb21tZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjVjMDIyNgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRjcmVhdGVjb21tZW50LmphdmEKQEAgLTAsMCArMSw5MSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJjcmVhdGVDb21tZW50KGRhdGEpIiBtZXRob2QgY3JlYXRlcyBhIG5ldyBDb21tZW50CisgKiAgICBub2RlIGdpdmVuIHRoZSBzcGVjaWZpZWQgc3RyaW5nLiAKKyAqICAgIFJldHJpZXZlIHRoZSBlbnRpcmUgRE9NIGRvY3VtZW50IGFuZCBpbnZva2UgaXRzIAorICogICAgImNyZWF0ZUNvbW1lbnQoZGF0YSkiIG1ldGhvZC4gIEl0IHNob3VsZCBjcmVhdGUgYSBuZXcKKyAqICAgIENvbW1lbnQgbm9kZSB3aG9zZSAiZGF0YSIgaXMgdGhlIHNwZWNpZmllZCBzdHJpbmcuCisgKiAgICBUaGUgY29udGVudCwgbmFtZSBhbmQgdHlwZSBhcmUgcmV0cmlldmVkIGFuZCBvdXRwdXQuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMzM0NDgxMzI4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMzM0NDgxMzI4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19kb2N1bWVudGNyZWF0ZWNvbW1lbnQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2RvY3VtZW50Y3JlYXRlY29tbWVudChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIENvbW1lbnQgbmV3Q29tbWVudE5vZGU7CisgICAgICBTdHJpbmcgbmV3Q29tbWVudFZhbHVlOworICAgICAgU3RyaW5nIG5ld0NvbW1lbnROYW1lOworICAgICAgaW50IG5ld0NvbW1lbnRUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgbmV3Q29tbWVudE5vZGUgPSBkb2MuY3JlYXRlQ29tbWVudCgiVGhpcyBpcyBhIG5ldyBDb21tZW50IG5vZGUiKTsKKyAgICAgIG5ld0NvbW1lbnRWYWx1ZSA9IG5ld0NvbW1lbnROb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZSIsICJUaGlzIGlzIGEgbmV3IENvbW1lbnQgbm9kZSIsIG5ld0NvbW1lbnRWYWx1ZSk7CisgICAgICBuZXdDb21tZW50TmFtZSA9IG5ld0NvbW1lbnROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInN0cm9uZyIsICIjY29tbWVudCIsIG5ld0NvbW1lbnROYW1lKTsKKyAgICAgIG5ld0NvbW1lbnRUeXBlID0gKGludCkgbmV3Q29tbWVudE5vZGUuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIGFzc2VydEVxdWFscygidHlwZSIsIDgsIG5ld0NvbW1lbnRUeXBlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRjcmVhdGVjb21tZW50IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19kb2N1bWVudGNyZWF0ZWNvbW1lbnQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Y3JlYXRlZG9jdW1lbnRmcmFnbWVudC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGNyZWF0ZWRvY3VtZW50ZnJhZ21lbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43Yzk2ZjQ4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGNyZWF0ZWRvY3VtZW50ZnJhZ21lbnQuamF2YQpAQCAtMCwwICsxLDk1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSIgbWV0aG9kIGNyZWF0ZXMgYW4gZW1wdHkgCisgKiAgICBEb2N1bWVudEZyYWdtZW50IG9iamVjdC4KKyAqICAgIFJldHJpZXZlIHRoZSBlbnRpcmUgRE9NIGRvY3VtZW50IGFuZCBpbnZva2UgaXRzIAorICogICAgImNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSIgbWV0aG9kLiAgVGhlIGNvbnRlbnQsIG5hbWUsIAorICogICAgdHlwZSBhbmQgdmFsdWUgb2YgdGhlIG5ld2x5IGNyZWF0ZWQgb2JqZWN0IGFyZSBvdXRwdXQuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zNUNCMDRCNSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzVDQjA0QjU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2RvY3VtZW50Y3JlYXRlZG9jdW1lbnRmcmFnbWVudCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfZG9jdW1lbnRjcmVhdGVkb2N1bWVudGZyYWdtZW50KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRGcmFnbWVudCBuZXdEb2NGcmFnbWVudDsKKyAgICAgIE5vZGVMaXN0IGNoaWxkcmVuOworICAgICAgaW50IGxlbmd0aDsKKyAgICAgIFN0cmluZyBuZXdEb2NGcmFnbWVudE5hbWU7CisgICAgICBpbnQgbmV3RG9jRnJhZ21lbnRUeXBlOworICAgICAgU3RyaW5nIG5ld0RvY0ZyYWdtZW50VmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdEb2NGcmFnbWVudCA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CisgICAgICBjaGlsZHJlbiA9IG5ld0RvY0ZyYWdtZW50LmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGxlbmd0aCA9IChpbnQpIGNoaWxkcmVuLmdldExlbmd0aCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJsZW5ndGgiLCAwLCBsZW5ndGgpOworICAgICAgbmV3RG9jRnJhZ21lbnROYW1lID0gbmV3RG9jRnJhZ21lbnQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygic3Ryb25nIiwgIiNkb2N1bWVudC1mcmFnbWVudCIsIG5ld0RvY0ZyYWdtZW50TmFtZSk7CisgICAgICBuZXdEb2NGcmFnbWVudFR5cGUgPSAoaW50KSBuZXdEb2NGcmFnbWVudC5nZXROb2RlVHlwZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0eXBlIiwgMTEsIG5ld0RvY0ZyYWdtZW50VHlwZSk7CisgICAgICBuZXdEb2NGcmFnbWVudFZhbHVlID0gbmV3RG9jRnJhZ21lbnQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJ2YWx1ZSIsIG5ld0RvY0ZyYWdtZW50VmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19kb2N1bWVudGNyZWF0ZWRvY3VtZW50ZnJhZ21lbnQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2RvY3VtZW50Y3JlYXRlZG9jdW1lbnRmcmFnbWVudC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRjcmVhdGVlbGVtZW50LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Y3JlYXRlZWxlbWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyNjZlZjUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Y3JlYXRlZWxlbWVudC5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY3JlYXRlRWxlbWVudCh0YWdOYW1lKSIgbWV0aG9kIGNyZWF0ZXMgYW4gRWxlbWVudCAKKyAqICAgIG9mIHRoZSB0eXBlIHNwZWNpZmllZC4KKyAqICAgIFJldHJpZXZlIHRoZSBlbnRpcmUgRE9NIGRvY3VtZW50IGFuZCBpbnZva2UgaXRzIAorICogICAgImNyZWF0ZUVsZW1lbnQodGFnTmFtZSkiIG1ldGhvZCB3aXRoIHRhZ05hbWU9ImFjcm9ueW0iLgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgY3JlYXRlIGFuIGluc3RhbmNlIG9mIGFuIEVsZW1lbnQgbm9kZQorICogICAgd2hvc2UgdGFnTmFtZSBpcyAiYWNyb255bSIuICBUaGUgTm9kZU5hbWUsIE5vZGVUeXBlIAorICogICAgYW5kIE5vZGVWYWx1ZSBhcmUgcmV0dXJuZWQuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMTQxNzQxNTQ3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMTQxNzQxNTQ3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19kb2N1bWVudGNyZWF0ZWVsZW1lbnQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2RvY3VtZW50Y3JlYXRlZWxlbWVudChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgbmV3RWxlbWVudDsKKyAgICAgIFN0cmluZyBuZXdFbGVtZW50TmFtZTsKKyAgICAgIGludCBuZXdFbGVtZW50VHlwZTsKKyAgICAgIFN0cmluZyBuZXdFbGVtZW50VmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdFbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnQoImFjcm9ueW0iKTsKKyAgICAgIG5ld0VsZW1lbnROYW1lID0gbmV3RWxlbWVudC5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImVsZW1lbnQiLCAic3Ryb25nIiwgImFjcm9ueW0iLCBuZXdFbGVtZW50TmFtZSk7CisgICAgICAgIG5ld0VsZW1lbnRUeXBlID0gKGludCkgbmV3RWxlbWVudC5nZXROb2RlVHlwZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0eXBlIiwgMSwgbmV3RWxlbWVudFR5cGUpOworICAgICAgbmV3RWxlbWVudFZhbHVlID0gbmV3RWxlbWVudC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydE51bGwoInZhbHVlSW5pdGlhbGx5TnVsbCIsIG5ld0VsZW1lbnRWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Y3JlYXRlZWxlbWVudCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZG9jdW1lbnRjcmVhdGVlbGVtZW50LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGNyZWF0ZWVsZW1lbnRjYXNlc2Vuc2l0aXZlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Y3JlYXRlZWxlbWVudGNhc2VzZW5zaXRpdmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMjRkNjc1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGNyZWF0ZWVsZW1lbnRjYXNlc2Vuc2l0aXZlLmphdmEKQEAgLTAsMCArMSwxMDMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIHRhZ05hbWUgcGFyYW1ldGVyIGluIHRoZSAiY3JlYXRlRWxlbWVudCh0YWdOYW1lKSIKKyAqICAgIG1ldGhvZCBpcyBjYXNlLXNlbnNpdGl2ZSBmb3IgWE1MIGRvY3VtZW50cy4KKyAqICAgIFJldHJpZXZlIHRoZSBlbnRpcmUgRE9NIGRvY3VtZW50IGFuZCBpbnZva2UgaXRzIAorICogICAgImNyZWF0ZUVsZW1lbnQodGFnTmFtZSkiIG1ldGhvZCB0d2ljZS4gIE9uY2UgZm9yIHRhZ05hbWUKKyAqICAgIGVxdWFsIHRvICJhY3JvbnltIiBhbmQgb25jZSBmb3IgdGFnTmFtZSBlcXVhbCB0byAiQUNST05ZTSIKKyAqICAgIEVhY2ggY2FsbCBzaG91bGQgY3JlYXRlIGEgZGlzdGluY3QgRWxlbWVudCBub2RlLiAgVGhlCisgKiAgICBuZXdseSBjcmVhdGVkIEVsZW1lbnRzIGFyZSB0aGVuIGFzc2lnbmVkIGF0dHJpYnV0ZXMgCisgKiAgICB0aGF0IGFyZSByZXRyaWV2ZWQuCisgKiAgICBNb2RpZmllZCBvbiAyNyBKdW5lIDIwMDMgdG8gYXZvaWQgc2V0dGluZyBhbiBpbnZhbGlkIHN0eWxlCisgKiAgICB2YWx1ZXMgYW5kIGNoZWNrZWQgdGhlIG5vZGUgbmFtZXMgdG8gc2VlIGlmIHRoZXkgbWF0Y2hlZCBleHBlY3RhdGlvbnMuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMTQxNzQxNTQ3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMTQxNzQxNTQ3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDMiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2RvY3VtZW50Y3JlYXRlZWxlbWVudGNhc2VzZW5zaXRpdmUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2RvY3VtZW50Y3JlYXRlZWxlbWVudGNhc2VzZW5zaXRpdmUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IG5ld0VsZW1lbnQxOworICAgICAgRWxlbWVudCBuZXdFbGVtZW50MjsKKyAgICAgIFN0cmluZyBhdHRyaWJ1dGUxOworICAgICAgU3RyaW5nIGF0dHJpYnV0ZTI7CisgICAgICBTdHJpbmcgbm9kZU5hbWUxOworICAgICAgU3RyaW5nIG5vZGVOYW1lMjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld0VsZW1lbnQxID0gZG9jLmNyZWF0ZUVsZW1lbnQoIkFDUk9OWU0iKTsKKyAgICAgIG5ld0VsZW1lbnQyID0gZG9jLmNyZWF0ZUVsZW1lbnQoImFjcm9ueW0iKTsKKyAgICAgIG5ld0VsZW1lbnQxLnNldEF0dHJpYnV0ZSgibGFuZyIsICJFTiIpOworICAgICAgbmV3RWxlbWVudDIuc2V0QXR0cmlidXRlKCJ0aXRsZSIsICJEYWxsYXMiKTsKKyAgICAgIGF0dHJpYnV0ZTEgPSBuZXdFbGVtZW50MS5nZXRBdHRyaWJ1dGUoImxhbmciKTsKKyAgICAgIGF0dHJpYnV0ZTIgPSBuZXdFbGVtZW50Mi5nZXRBdHRyaWJ1dGUoInRpdGxlIik7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJpYjEiLCAiRU4iLCBhdHRyaWJ1dGUxKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0cmliMiIsICJEYWxsYXMiLCBhdHRyaWJ1dGUyKTsKKyAgICAgIG5vZGVOYW1lMSA9IG5ld0VsZW1lbnQxLmdldE5vZGVOYW1lKCk7CisgICAgICBub2RlTmFtZTIgPSBuZXdFbGVtZW50Mi5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImVsZW1lbnQiLCAibm9kZU5hbWUxIiwgIkFDUk9OWU0iLCBub2RlTmFtZTEpOworICAgICAgICBhc3NlcnRFcXVhbHNBdXRvQ2FzZSgiZWxlbWVudCIsICJub2RlTmFtZTIiLCAiYWNyb255bSIsIG5vZGVOYW1lMik7CisgICAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRjcmVhdGVlbGVtZW50Y2FzZXNlbnNpdGl2ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZG9jdW1lbnRjcmVhdGVlbGVtZW50Y2FzZXNlbnNpdGl2ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRjcmVhdGV0ZXh0bm9kZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGNyZWF0ZXRleHRub2RlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDdmYWFiMQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRjcmVhdGV0ZXh0bm9kZS5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY3JlYXRlVGV4dE5vZGUoZGF0YSkiIG1ldGhvZCBjcmVhdGVzIGEgVGV4dCBub2RlIAorICogICAgZ2l2ZW4gdGhlIHNwZWNmaWVkIHN0cmluZy4KKyAqICAgIFJldHJpZXZlIHRoZSBlbnRpcmUgRE9NIGRvY3VtZW50IGFuZCBpbnZva2UgaXRzIAorICogICAgImNyZWF0ZVRleHROb2RlKGRhdGEpIiBtZXRob2QuICBJdCBzaG91bGQgY3JlYXRlIGEgCisgKiAgICBuZXcgVGV4dCBub2RlIHdob3NlICJkYXRhIiBpcyB0aGUgc3BlY2lmaWVkIHN0cmluZy4KKyAqICAgIFRoZSBOb2RlTmFtZSBhbmQgTm9kZVR5cGUgYXJlIGFsc28gY2hlY2tlZC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE5NzUzNDgxMjciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE5NzUzNDgxMjc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2RvY3VtZW50Y3JlYXRldGV4dG5vZGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2RvY3VtZW50Y3JlYXRldGV4dG5vZGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBUZXh0IG5ld1RleHROb2RlOworICAgICAgU3RyaW5nIG5ld1RleHROYW1lOworICAgICAgU3RyaW5nIG5ld1RleHRWYWx1ZTsKKyAgICAgIGludCBuZXdUZXh0VHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld1RleHROb2RlID0gZG9jLmNyZWF0ZVRleHROb2RlKCJUaGlzIGlzIGEgbmV3IFRleHQgbm9kZSIpOworICAgICAgbmV3VGV4dFZhbHVlID0gbmV3VGV4dE5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlIiwgIlRoaXMgaXMgYSBuZXcgVGV4dCBub2RlIiwgbmV3VGV4dFZhbHVlKTsKKyAgICAgIG5ld1RleHROYW1lID0gbmV3VGV4dE5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygic3Ryb25nIiwgIiN0ZXh0IiwgbmV3VGV4dE5hbWUpOworICAgICAgbmV3VGV4dFR5cGUgPSAoaW50KSBuZXdUZXh0Tm9kZS5nZXROb2RlVHlwZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0eXBlIiwgMywgbmV3VGV4dFR5cGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19kb2N1bWVudGNyZWF0ZXRleHRub2RlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19kb2N1bWVudGNyZWF0ZXRleHRub2RlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGdldGRvY3R5cGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRnZXRkb2N0eXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjlhY2NjYwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRnZXRkb2N0eXBlLmphdmEKQEAgLTAsMCArMSwxMDIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBY2Nlc3MgRG9jdW1lbnQuZG9jdHlwZSBmb3IgaGNfc3RhZmYsIGlmIG5vdCB0ZXh0L2h0bWwgc2hvdWxkIHJldHVybiBEb2N1bWVudFR5cGUgbm9kZS4KKyAqIEhUTUwgaW1wbGVtZW50YXRpb25zIG1heSByZXR1cm4gbnVsbC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUI2M0VEMUEzMSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtQjYzRUQxQTMxPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19kb2N1bWVudGdldGRvY3R5cGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2RvY3VtZW50Z2V0ZG9jdHlwZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIFN0cmluZyBkb2NUeXBlTmFtZTsKKyAgICAgIFN0cmluZyBub2RlVmFsdWU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKAorICAgICEoKCJ0ZXh0L2h0bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpCispIHsKKyAgICAgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgfQorICAgIAorICAgICAgaWYgKChkb2NUeXBlICE9IG51bGwpKSB7CisgICAgICAgICAgZG9jVHlwZU5hbWUgPSBkb2NUeXBlLmdldE5hbWUoKTsKKyAgICAgIAorICAgICAgaWYgKCgiaW1hZ2Uvc3ZnK3htbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkgeworICAgICAgICAgIGFzc2VydEVxdWFscygibm9kZU5hbWVTVkciLCAic3ZnIiwgZG9jVHlwZU5hbWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lIiwgImh0bWwiLCBkb2NUeXBlTmFtZSk7CisgICAgICB9CisgICAgICAgIAorICAgIG5vZGVWYWx1ZSA9IGRvY1R5cGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJub2RlVmFsdWUiLCBub2RlVmFsdWUpOworICAgICAgYXR0cmlidXRlcyA9IGRvY1R5cGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXNzZXJ0TnVsbCgiYXR0cmlidXRlcyIsIGF0dHJpYnV0ZXMpOworICAgICAgfQorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRnZXRkb2N0eXBlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19kb2N1bWVudGdldGRvY3R5cGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVsZW5ndGguamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZWxlbmd0aC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4MjQ3NTEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVsZW5ndGguamF2YQpAQCAtMCwwICsxLDg0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEVsZW1lbnRzQnlUYWdOYW1lKHRhZ05hbWUpIiBtZXRob2QgcmV0dXJucyBhIAorICogICAgTm9kZUxpc3Qgb2YgYWxsIHRoZSBFbGVtZW50cyB3aXRoIGEgZ2l2ZW4gdGFnTmFtZS4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGVudGlyZSBET00gZG9jdW1lbnQgYW5kIGludm9rZSBpdHMgCisgKiAgICAiZ2V0RWxlbWVudHNCeVRhZ05hbWUodGFnTmFtZSkiIG1ldGhvZCB3aXRoIHRhZ05hbWUKKyAqICAgIGVxdWFsIHRvICJzdHJvbmciLiAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgTm9kZUxpc3QgCisgKiAgICB0aGF0IGNvbnRhaW5zIDUgZWxlbWVudHMuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1BNkM5MDk0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1BNkM5MDk0PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lbGVuZ3RoIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lbGVuZ3RoKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IG5hbWVMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIG5hbWVMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJzdHJvbmciKTsKKyAgICAgIGFzc2VydFNpemUoImRvY3VtZW50R2V0RWxlbWVudHNCeVRhZ05hbWVMZW5ndGhBc3NlcnQiLCA1LCBuYW1lTGlzdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVsZW5ndGgiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVsZW5ndGguY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV0b3RhbGxlbmd0aC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1ldG90YWxsZW5ndGguamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNDY2MGRkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1ldG90YWxsZW5ndGguamF2YQpAQCAtMCwwICsxLDE4NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgIFJldHJpZXZlIHRoZSBlbnRpcmUgRE9NIGRvY3VtZW50IGFuZCBpbnZva2UgaXRzIAorICogICAgImdldEVsZW1lbnRzQnlUYWdOYW1lKHRhZ05hbWUpIiBtZXRob2Qgd2l0aCB0YWdOYW1lCisgKiAgICBlcXVhbCB0byAiKiIuICBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gYSBOb2RlTGlzdCAKKyAqICAgIHRoYXQgY29udGFpbnMgYWxsIHRoZSBlbGVtZW50cyBvZiB0aGUgZG9jdW1lbnQuIAorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtQTZDOTA5NCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtQTZDOTA5NDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjUxIj5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjUxPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1ldG90YWxsZW5ndGggZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV0b3RhbGxlbmd0aChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBuYW1lTGlzdDsKKyAgICAgIGphdmEudXRpbC5MaXN0IGV4cGVjdGVkTmFtZXMgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoImh0bWwiKTsKKyAgICAgIGV4cGVjdGVkTmFtZXMuYWRkKCJoZWFkIik7CisgICAgICBleHBlY3RlZE5hbWVzLmFkZCgibWV0YSIpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoInRpdGxlIik7CisgICAgICBleHBlY3RlZE5hbWVzLmFkZCgic2NyaXB0Iik7CisgICAgICBleHBlY3RlZE5hbWVzLmFkZCgic2NyaXB0Iik7CisgICAgICBleHBlY3RlZE5hbWVzLmFkZCgic2NyaXB0Iik7CisgICAgICBleHBlY3RlZE5hbWVzLmFkZCgiYm9keSIpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoInAiKTsKKyAgICAgIGV4cGVjdGVkTmFtZXMuYWRkKCJlbSIpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoInN0cm9uZyIpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoImNvZGUiKTsKKyAgICAgIGV4cGVjdGVkTmFtZXMuYWRkKCJzdXAiKTsKKyAgICAgIGV4cGVjdGVkTmFtZXMuYWRkKCJ2YXIiKTsKKyAgICAgIGV4cGVjdGVkTmFtZXMuYWRkKCJhY3JvbnltIik7CisgICAgICBleHBlY3RlZE5hbWVzLmFkZCgicCIpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoImVtIik7CisgICAgICBleHBlY3RlZE5hbWVzLmFkZCgic3Ryb25nIik7CisgICAgICBleHBlY3RlZE5hbWVzLmFkZCgiY29kZSIpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoInN1cCIpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoInZhciIpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoImFjcm9ueW0iKTsKKyAgICAgIGV4cGVjdGVkTmFtZXMuYWRkKCJwIik7CisgICAgICBleHBlY3RlZE5hbWVzLmFkZCgiZW0iKTsKKyAgICAgIGV4cGVjdGVkTmFtZXMuYWRkKCJzdHJvbmciKTsKKyAgICAgIGV4cGVjdGVkTmFtZXMuYWRkKCJjb2RlIik7CisgICAgICBleHBlY3RlZE5hbWVzLmFkZCgic3VwIik7CisgICAgICBleHBlY3RlZE5hbWVzLmFkZCgidmFyIik7CisgICAgICBleHBlY3RlZE5hbWVzLmFkZCgiYWNyb255bSIpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoInAiKTsKKyAgICAgIGV4cGVjdGVkTmFtZXMuYWRkKCJlbSIpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoInN0cm9uZyIpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoImNvZGUiKTsKKyAgICAgIGV4cGVjdGVkTmFtZXMuYWRkKCJzdXAiKTsKKyAgICAgIGV4cGVjdGVkTmFtZXMuYWRkKCJ2YXIiKTsKKyAgICAgIGV4cGVjdGVkTmFtZXMuYWRkKCJhY3JvbnltIik7CisgICAgICBleHBlY3RlZE5hbWVzLmFkZCgicCIpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoImVtIik7CisgICAgICBleHBlY3RlZE5hbWVzLmFkZCgic3Ryb25nIik7CisgICAgICBleHBlY3RlZE5hbWVzLmFkZCgiY29kZSIpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoInN1cCIpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoInZhciIpOworICAgICAgZXhwZWN0ZWROYW1lcy5hZGQoImFjcm9ueW0iKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkxpc3Qgc3ZnRXhwZWN0ZWROYW1lcyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgic3ZnIik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgicmVjdCIpOworICAgICAgc3ZnRXhwZWN0ZWROYW1lcy5hZGQoInNjcmlwdCIpOworICAgICAgc3ZnRXhwZWN0ZWROYW1lcy5hZGQoImhlYWQiKTsKKyAgICAgIHN2Z0V4cGVjdGVkTmFtZXMuYWRkKCJtZXRhIik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgidGl0bGUiKTsKKyAgICAgIHN2Z0V4cGVjdGVkTmFtZXMuYWRkKCJib2R5Iik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgicCIpOworICAgICAgc3ZnRXhwZWN0ZWROYW1lcy5hZGQoImVtIik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgic3Ryb25nIik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgiY29kZSIpOworICAgICAgc3ZnRXhwZWN0ZWROYW1lcy5hZGQoInN1cCIpOworICAgICAgc3ZnRXhwZWN0ZWROYW1lcy5hZGQoInZhciIpOworICAgICAgc3ZnRXhwZWN0ZWROYW1lcy5hZGQoImFjcm9ueW0iKTsKKyAgICAgIHN2Z0V4cGVjdGVkTmFtZXMuYWRkKCJwIik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgiZW0iKTsKKyAgICAgIHN2Z0V4cGVjdGVkTmFtZXMuYWRkKCJzdHJvbmciKTsKKyAgICAgIHN2Z0V4cGVjdGVkTmFtZXMuYWRkKCJjb2RlIik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgic3VwIik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgidmFyIik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgiYWNyb255bSIpOworICAgICAgc3ZnRXhwZWN0ZWROYW1lcy5hZGQoInAiKTsKKyAgICAgIHN2Z0V4cGVjdGVkTmFtZXMuYWRkKCJlbSIpOworICAgICAgc3ZnRXhwZWN0ZWROYW1lcy5hZGQoInN0cm9uZyIpOworICAgICAgc3ZnRXhwZWN0ZWROYW1lcy5hZGQoImNvZGUiKTsKKyAgICAgIHN2Z0V4cGVjdGVkTmFtZXMuYWRkKCJzdXAiKTsKKyAgICAgIHN2Z0V4cGVjdGVkTmFtZXMuYWRkKCJ2YXIiKTsKKyAgICAgIHN2Z0V4cGVjdGVkTmFtZXMuYWRkKCJhY3JvbnltIik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgicCIpOworICAgICAgc3ZnRXhwZWN0ZWROYW1lcy5hZGQoImVtIik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgic3Ryb25nIik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgiY29kZSIpOworICAgICAgc3ZnRXhwZWN0ZWROYW1lcy5hZGQoInN1cCIpOworICAgICAgc3ZnRXhwZWN0ZWROYW1lcy5hZGQoInZhciIpOworICAgICAgc3ZnRXhwZWN0ZWROYW1lcy5hZGQoImFjcm9ueW0iKTsKKyAgICAgIHN2Z0V4cGVjdGVkTmFtZXMuYWRkKCJwIik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgiZW0iKTsKKyAgICAgIHN2Z0V4cGVjdGVkTmFtZXMuYWRkKCJzdHJvbmciKTsKKyAgICAgIHN2Z0V4cGVjdGVkTmFtZXMuYWRkKCJjb2RlIik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgic3VwIik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgidmFyIik7CisgICAgICBzdmdFeHBlY3RlZE5hbWVzLmFkZCgiYWNyb255bSIpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuTGlzdCBhY3R1YWxOYW1lcyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICAKKyAgICAgIEVsZW1lbnQgdGhpc0VsZW1lbnQ7CisgICAgICBTdHJpbmcgdGhpc1RhZzsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBuYW1lTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAxNDggPSAwOyBpbmRleE4xMDE0OCA8IG5hbWVMaXN0LmdldExlbmd0aCgpOyBpbmRleE4xMDE0OCsrKSB7CisgICAgICAgICAgdGhpc0VsZW1lbnQgPSAoRWxlbWVudCkgbmFtZUxpc3QuaXRlbShpbmRleE4xMDE0OCk7CisgICAgdGhpc1RhZyA9IHRoaXNFbGVtZW50LmdldFRhZ05hbWUoKTsKKyAgICAgIGFjdHVhbE5hbWVzLmFkZCh0aGlzVGFnKTsKKyAgICAgICAgfQorICAgICAgCisgICAgICBpZiAoKCJpbWFnZS9zdmcreG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImVsZW1lbnQiLCAic3ZnVGFnTmFtZXMiLCBzdmdFeHBlY3RlZE5hbWVzLCBhY3R1YWxOYW1lcyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImVsZW1lbnQiLCAidGFnTmFtZXMiLCBleHBlY3RlZE5hbWVzLCBhY3R1YWxOYW1lcyk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1ldG90YWxsZW5ndGgiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV0b3RhbGxlbmd0aC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZXZhbHVlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV2YWx1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdiZjY3MDMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV2YWx1ZS5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0RWxlbWVudHNCeVRhZ05hbWUodGFnTmFtZSkiIG1ldGhvZCByZXR1cm5zIGEgCisgKiAgICBOb2RlTGlzdCBvZiBhbGwgdGhlIEVsZW1lbnRzIHdpdGggYSBnaXZlbiB0YWdOYW1lCisgKiAgICBpbiBhIHByZS1vcmRlciB0cmF2ZXJzYWwgb2YgdGhlIHRyZWUuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBlbnRpcmUgRE9NIGRvY3VtZW50IGFuZCBpbnZva2UgaXRzIAorICogICAgImdldEVsZW1lbnRzQnlUYWdOYW1lKHRhZ05hbWUpIiBtZXRob2Qgd2l0aCB0YWdOYW1lCisgKiAgICBlcXVhbCB0byAic3Ryb25nIi4gIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiBhIE5vZGVMaXN0IAorICogICAgdGhhdCBjb250YWlucyA1IGVsZW1lbnRzLiAgVGhlIEZPVVJUSCBpdGVtIGluIHRoZQorICogICAgbGlzdCBpcyByZXRyaWV2ZWQgYW5kIG91dHB1dC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUE2QzkwOTQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUE2QzkwOTQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZXZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IG5hbWVMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIE5vZGUgZmlyc3RDaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZFZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIG5hbWVMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJzdHJvbmciKTsKKyAgICAgIG5hbWVOb2RlID0gbmFtZUxpc3QuaXRlbSgzKTsKKyAgICAgIGZpcnN0Q2hpbGQgPSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZFZhbHVlID0gZmlyc3RDaGlsZC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRHZXRFbGVtZW50c0J5VGFnTmFtZVZhbHVlQXNzZXJ0IiwgIkplbnkgT2Nvbm5vciIsIGNoaWxkVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1ldmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWV2YWx1ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRnZXRpbXBsZW1lbnRhdGlvbi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGdldGltcGxlbWVudGF0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDYzNjI3NQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRnZXRpbXBsZW1lbnRhdGlvbi5qYXZhCkBAIC0wLDAgKzEsOTMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICBSZXRyaWV2ZSB0aGUgZW50aXJlIERPTSBkb2N1bWVudCBhbmQgaW52b2tlIGl0cyAKKyAqICAgICJnZXRJbXBsZW1lbnRhdGlvbigpIiBtZXRob2QuICBJZiBjb250ZW50VHlwZT0idGV4dC9odG1sIiwgCisgKiAgICBET01JbXBsZW1lbnRhdGlvbi5oYXNGZWF0dXJlKCJIVE1MIiwiMS4wIikgc2hvdWxkIGJlIHRydWUuICAKKyAqICAgIE90aGVyd2lzZSwgRE9NSW1wbGVtZW50YXRpb24uaGFzRmVhdHVyZSgiWE1MIiwgIjEuMCIpCisgKiAgICBzaG91bGQgYmUgdHJ1ZS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTFCNzkzRUJBIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xQjc5M0VCQTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ1Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ1PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19kb2N1bWVudGdldGltcGxlbWVudGF0aW9uIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19kb2N1bWVudGdldGltcGxlbWVudGF0aW9uKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvY0ltcGw7CisgICAgICBib29sZWFuIHhtbHN0YXRlOworICAgICAgYm9vbGVhbiBodG1sc3RhdGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZG9jSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgeG1sc3RhdGUgPSBkb2NJbXBsLmhhc0ZlYXR1cmUoIlhNTCIsICIxLjAiKTsKK2h0bWxzdGF0ZSA9IGRvY0ltcGwuaGFzRmVhdHVyZSgiSFRNTCIsICIxLjAiKTsKKworICAgICAgaWYgKCgidGV4dC9odG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKSB7CisgICAgICAgICAgYXNzZXJ0VHJ1ZSgic3VwcG9ydHNfSFRNTF8xLjAiLCBodG1sc3RhdGUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBhc3NlcnRUcnVlKCJzdXBwb3J0c19YTUxfMS4wIiwgeG1sc3RhdGUpOworICAgICAgfQorICAgICAgICAKKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Z2V0aW1wbGVtZW50YXRpb24iOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2RvY3VtZW50Z2V0aW1wbGVtZW50YXRpb24uY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Z2V0cm9vdG5vZGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRnZXRyb290bm9kZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE3YjU0ZmIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Z2V0cm9vdG5vZGUuamF2YQpAQCAtMCwwICsxLDg4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICBMb2FkIGEgZG9jdW1lbnQgYW5kIGludm9rZSBpdHMgCisgKiAgICAiZ2V0RG9jdW1lbnRFbGVtZW50KCkiIG1ldGhvZC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg3Q0QwOTIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg3Q0QwOTI8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1MSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1MTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfZG9jdW1lbnRnZXRyb290bm9kZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfZG9jdW1lbnRnZXRyb290bm9kZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IHJvb3Q7CisgICAgICBTdHJpbmcgcm9vdE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgcm9vdCA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIHJvb3ROYW1lID0gcm9vdC5nZXROb2RlTmFtZSgpOworICAgICAgCisgICAgICBpZiAoKCJpbWFnZS9zdmcreG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdmdUYWdOYW1lIiwgInN2ZyIsIHJvb3ROYW1lKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImVsZW1lbnQiLCAiZG9jRWxlbU5hbWUiLCAiaHRtbCIsIHJvb3ROYW1lKTsKKyAgICAgICAgfQorICAgICAgICAKKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50Z2V0cm9vdG5vZGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2RvY3VtZW50Z2V0cm9vdG5vZGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWF0dHJpYnV0ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVhdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZjQ3NDY5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVhdHRyaWJ1dGUuamF2YQpAQCAtMCwwICsxLDk3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY3JlYXRlQXR0cmlidXRlKHRhZ05hbWUpIiBtZXRob2QgcmFpc2VzIGFuCisgKiAgICBJTlZBTElEX0NIQVJBQ1RFUl9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQKKyAqICAgIHRhZ05hbWUgY29udGFpbnMgYW4gaW52YWxpZCBjaGFyYWN0ZXIuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgZW50aXJlIERPTSBkb2N1bWVudCBhbmQgaW52b2tlIGl0cyAKKyAqICAgICJjcmVhdGVBdHRyaWJ1dGUodGFnTmFtZSkiIG1ldGhvZCB3aXRoIHRoZSB0YWdOYW1lIGVxdWFsCisgKiAgICB0byB0aGUgc3RyaW5nICJpbnZhbGlkXk5hbWUiLiAgRHVlIHRvIHRoZSBpbnZhbGlkIAorICogICAgY2hhcmFjdGVyIHRoZSBkZXNpcmVkIEVYQ0VQVElPTiBzaG91bGQgYmUgcmFpc2VkLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDg0ODkxMTk4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDg0ODkxMTk4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0xMDg0ODkxMTk4JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMTA4NDg5MTE5OCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDg0ODkxMTk4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDg0ODkxMTk4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWF0dHJpYnV0ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlYXR0cmlidXRlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgQXR0ciBjcmVhdGVkQXR0cjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgY3JlYXRlZEF0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJpbnZhbGlkXk5hbWUiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOVkFMSURfQ0hBUkFDVEVSX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVhdHRyaWJ1dGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWF0dHJpYnV0ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlYXR0cmlidXRlMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVhdHRyaWJ1dGUxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2IyOTk1MwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlYXR0cmlidXRlMS5qYXZhCkBAIC0wLDAgKzEsOTAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQ3JlYXRpbmcgYW4gYXR0cmlidXRlIHdpdGggYW4gZW1wdHkgbmFtZSBzaG91bGQgY2F1c2UgYW4gSU5WQUxJRF9DSEFSQUNURVJfRVJSLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDg0ODkxMTk4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDg0ODkxMTk4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0xMDg0ODkxMTk4JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMTA4NDg5MTE5OCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDg0ODkxMTk4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDg0ODkxMTk4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD01MjUiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD01MjU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWF0dHJpYnV0ZTEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWF0dHJpYnV0ZTEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBBdHRyIGNyZWF0ZWRBdHRyOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjcmVhdGVkQXR0ciA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoIiIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTlZBTElEX0NIQVJBQ1RFUl9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSU5WQUxJRF9DSEFSQUNURVJfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWF0dHJpYnV0ZTEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWF0dHJpYnV0ZTEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWVsZW1lbnQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlZWxlbWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhlOTAyOWEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWVsZW1lbnQuamF2YQpAQCAtMCwwICsxLDk3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY3JlYXRlRWxlbWVudCh0YWdOYW1lKSIgbWV0aG9kIHJhaXNlcyBhbgorICogICAgSU5WQUxJRF9DSEFSQUNURVJfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkCisgKiAgICB0YWdOYW1lIGNvbnRhaW5zIGFuIGludmFsaWQgY2hhcmFjdGVyLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGVudGlyZSBET00gZG9jdW1lbnQgYW5kIGludm9rZSBpdHMgCisgKiAgICAiY3JlYXRlRWxlbWVudCh0YWdOYW1lKSIgbWV0aG9kIHdpdGggdGhlIHRhZ05hbWUgZXF1YWwKKyAqICAgIHRvIHRoZSBzdHJpbmcgImludmFsaWReTmFtZSIuICBEdWUgdG8gdGhlIGludmFsaWQgCisgKiAgICBjaGFyYWN0ZXIgdGhlIGRlc2lyZWQgRVhDRVBUSU9OIHNob3VsZCBiZSByYWlzZWQuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIxNDE3NDE1NDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIxNDE3NDE1NDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTIxNDE3NDE1NDcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yMTQxNzQxNTQ3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIxNDE3NDE1NDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIxNDE3NDE1NDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlZWxlbWVudCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlZWxlbWVudChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgYmFkRWxlbWVudDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgYmFkRWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCJpbnZhbGlkXk5hbWUiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOVkFMSURfQ0hBUkFDVEVSX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbGVtZW50IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbGVtZW50LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbGVtZW50MS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbGVtZW50MS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJmNTllMjIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWVsZW1lbnQxLmphdmEKQEAgLTAsMCArMSw5MCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBDcmVhdGluZyBhbiBlbGVtZW50IHdpdGggYW4gZW1wdHkgbmFtZSBzaG91bGQgY2F1c2UgYW4gSU5WQUxJRF9DSEFSQUNURVJfRVJSLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMTQxNzQxNTQ3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMTQxNzQxNTQ3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yMTQxNzQxNTQ3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjE0MTc0MTU0NycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMTQxNzQxNTQ3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMTQxNzQxNTQ3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD01MjUiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD01MjU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2RvY3VtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbmNyZWF0ZWVsZW1lbnQxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbGVtZW50MShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgYmFkRWxlbWVudDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgYmFkRWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCIiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOVkFMSURfQ0hBUkFDVEVSX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19kb2N1bWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb25jcmVhdGVlbGVtZW50MSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZG9jdW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uY3JlYXRlZWxlbWVudDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZW5vdmVyc2lvbi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVub3ZlcnNpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNGFkMjdjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVub3ZlcnNpb24uamF2YQpAQCAtMCwwICsxLDkzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgTG9hZCBhIGRvY3VtZW50IGFuZCBpbnZva2UgaXRzIAorICogICAgImdldEltcGxlbWVudGF0aW9uKCkiIG1ldGhvZC4gIFRoaXMgc2hvdWxkIGNyZWF0ZSBhCisgKiAgICBET01JbXBsZW1lbnRhdGlvbiBvYmplY3Qgd2hvc2UgImhhc0ZlYXR1cmUoZmVhdHVyZSwKKyAqICAgIHZlcnNpb24pIiBtZXRob2QgaXMgaW52b2tlZCB3aXRoIHZlcnNpb24gZXF1YWwgdG8gIiIuCisgKiAgICBJZiB0aGUgdmVyc2lvbiBpcyBub3Qgc3BlY2lmaWVkLCBzdXBwb3J0aW5nIGFueSB2ZXJzaW9uCisgKiAgICBmZWF0dXJlIHdpbGwgY2F1c2UgdGhlIG1ldGhvZCB0byByZXR1cm4gInRydWUiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNUNFRDk0RDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTVDRUQ5NEQ3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMTEvRE9NLUxldmVsLTItZXJyYXRhI2NvcmUtMTQiPmh0dHA6Ly93d3cudzMub3JnLzIwMDAvMTEvRE9NLUxldmVsLTItZXJyYXRhI2NvcmUtMTQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfZG9taW1wbGVtZW50YXRpb25mZWF0dXJlbm92ZXJzaW9uIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVub3ZlcnNpb24oZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgCisgICAgICBpZiAoKCJ0ZXh0L2h0bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpIHsKKyAgICAgICAgICBzdGF0ZSA9IGRvbUltcGwuaGFzRmVhdHVyZSgiSFRNTCIsICIiKTsKK30gZWxzZSB7CisgICAgICAgICAgc3RhdGUgPSBkb21JbXBsLmhhc0ZlYXR1cmUoIlhNTCIsICIiKTsKK30KKyAgICAgICAgCisgICAgYXNzZXJ0VHJ1ZSgiaGFzRmVhdHVyZUJsYW5rIiwgc3RhdGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVub3ZlcnNpb24iOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZW5vdmVyc2lvbi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9taW1wbGVtZW50YXRpb25mZWF0dXJlbnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVudWxsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWViNzkxMAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZG9taW1wbGVtZW50YXRpb25mZWF0dXJlbnVsbC5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgTG9hZCBhIGRvY3VtZW50IGFuZCBpbnZva2UgaXRzIAorICogICAgImdldEltcGxlbWVudGF0aW9uKCkiIG1ldGhvZC4gIFRoaXMgc2hvdWxkIGNyZWF0ZSBhCisgKiAgICBET01JbXBsZW1lbnRhdGlvbiBvYmplY3Qgd2hvc2UgImhhc0ZlYXR1cmUoZmVhdHVyZSwKKyAqICAgIHZlcnNpb24pIiBtZXRob2QgaXMgaW52b2tlZCB3aXRoIHZlcnNpb24gZXF1YWwgdG8gbnVsbC4KKyAqICAgIElmIHRoZSB2ZXJzaW9uIGlzIG5vdCBzcGVjaWZpZWQsIHN1cHBvcnRpbmcgYW55IHZlcnNpb24KKyAqICAgIGZlYXR1cmUgd2lsbCBjYXVzZSB0aGUgbWV0aG9kIHRvIHJldHVybiAidHJ1ZSIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTVDRUQ5NEQ3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC01Q0VEOTRENzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzExL0RPTS1MZXZlbC0yLWVycmF0YSNjb3JlLTE0Ij5odHRwOi8vd3d3LnczLm9yZy8yMDAwLzExL0RPTS1MZXZlbC0yLWVycmF0YSNjb3JlLTE0PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDUiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZW51bGwgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZW51bGwoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcuaGFzTnVsbFN0cmluZworICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICAKKyAgICAgIGlmICgoInRleHQvaHRtbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkgeworICAgICAgICAgIHN0YXRlID0gZG9tSW1wbC5oYXNGZWF0dXJlKCJIVE1MIiwgbnVsbCk7Cithc3NlcnRUcnVlKCJzdXBwb3J0c19IVE1MX251bGwiLCBzdGF0ZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICAgIHN0YXRlID0gZG9tSW1wbC5oYXNGZWF0dXJlKCJYTUwiLCBudWxsKTsKK2Fzc2VydFRydWUoInN1cHBvcnRzX1hNTF9udWxsIiwgc3RhdGUpOworICAgICAgfQorICAgICAgICAKKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZW51bGwiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZW51bGwuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZXhtbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmV4bWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNjY2MjJkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmV4bWwuamF2YQpAQCAtMCwwICsxLDkyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgUmV0cmlldmUgdGhlIGVudGlyZSBET00gZG9jdW1lbnQgYW5kIGludm9rZSBpdHMgCisgKiAgICAiZ2V0SW1wbGVtZW50YXRpb24oKSIgbWV0aG9kLiAgVGhpcyBzaG91bGQgY3JlYXRlIGEKKyAqICAgIERPTUltcGxlbWVudGF0aW9uIG9iamVjdCB3aG9zZSAiaGFzRmVhdHVyZShmZWF0dXJlLAorICogICAgdmVyc2lvbikiIG1ldGhvZCBpcyBpbnZva2VkIHdpdGggImZlYXR1cmUiIGVxdWFsIHRvICJodG1sIiBvciAieG1sIi4KKyAqICAgIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiBhIGJvb2xlYW4gInRydWUiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNUNFRDk0RDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTVDRUQ5NEQ3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDUiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZXhtbCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfZG9taW1wbGVtZW50YXRpb25mZWF0dXJleG1sKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgIAorICAgICAgaWYgKCgidGV4dC9odG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKSB7CisgICAgICAgICAgc3RhdGUgPSBkb21JbXBsLmhhc0ZlYXR1cmUoImh0bWwiLCAiMS4wIik7Cithc3NlcnRUcnVlKCJzdXBwb3J0c19odG1sXzEuMCIsIHN0YXRlKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc3RhdGUgPSBkb21JbXBsLmhhc0ZlYXR1cmUoInhtbCIsICIxLjAiKTsKK2Fzc2VydFRydWUoInN1cHBvcnRzX3htbF8xLjAiLCBzdGF0ZSk7CisgICAgICB9CisgICAgICAgIAorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZG9taW1wbGVtZW50YXRpb25mZWF0dXJleG1sIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmV4bWwuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRhZGRuZXdhdHRyaWJ1dGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGFkZG5ld2F0dHJpYnV0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc1OWI1NzkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRhZGRuZXdhdHRyaWJ1dGUuamF2YQpAQCAtMCwwICsxLDkxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0QXR0cmlidXRlKG5hbWUsdmFsdWUpIiBtZXRob2QgYWRkcyBhIG5ldyBhdHRyaWJ1dGUKKyAqICAgIHRvIHRoZSBFbGVtZW50IAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgbGFzdCBlbXBsb3llZSwgdGhlbiAKKyAqICAgIGFkZCBhbiBhdHRyaWJ1dGUgdG8gaXQgYnkgaW52b2tpbmcgdGhlICAgICAgICAgICAgIAorICogICAgInNldEF0dHJpYnV0ZShuYW1lLHZhbHVlKSIgbWV0aG9kLiAgSXQgc2hvdWxkIGNyZWF0ZQorICogICAgYSAic3Ryb25nIiBhdHRyaWJ1dGUgd2l0aCBhbiBhc3NpZ25lZCB2YWx1ZSBlcXVhbCB0byAKKyAqICAgICJ2YWx1ZSIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDMiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2VsZW1lbnRhZGRuZXdhdHRyaWJ1dGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2VsZW1lbnRhZGRuZXdhdHRyaWJ1dGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEVtcGxveWVlOworICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSg0KTsKKyAgICAgIHRlc3RFbXBsb3llZS5zZXRBdHRyaWJ1dGUoImxhbmciLCAiRU4tdXMiKTsKKyAgICAgIGF0dHJWYWx1ZSA9IHRlc3RFbXBsb3llZS5nZXRBdHRyaWJ1dGUoImxhbmciKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0clZhbHVlIiwgIkVOLXVzIiwgYXR0clZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGFkZG5ld2F0dHJpYnV0ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZWxlbWVudGFkZG5ld2F0dHJpYnV0ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGFzc29jaWF0ZWRhdHRyaWJ1dGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGFzc29jaWF0ZWRhdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MDZiZmNiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50YXNzb2NpYXRlZGF0dHJpYnV0ZS5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgYXR0cmlidXRlIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YKKyAqICAgIHRoZSBmaXJzdCBlbXBsb3llZSBhbmQgaW52b2tlIHRoZSAiZ2V0U3BlY2lmaWVkKCkiIAorICogICAgbWV0aG9kLiAgVGhpcyB0ZXN0IGlzIG9ubHkgaW50ZW5kZWQgdG8gc2hvdyB0aGF0ICAgCisgKiAgICBFbGVtZW50cyBjYW4gYWN0dWFsbHkgaGF2ZSBhdHRyaWJ1dGVzLiAgVGhpcyB0ZXN0IHVzZXMgIAorICogICAgdGhlICJnZXROYW1lZEl0ZW0obmFtZSkiIG1ldGhvZCBmcm9tIHRoZSBOYW1lZE5vZGVNYXAKKyAqICAgIGludGVyZmFjZS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2VsZW1lbnRhc3NvY2lhdGVkYXR0cmlidXRlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19lbGVtZW50YXNzb2NpYXRlZGF0dHJpYnV0ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIGRvbWVzdGljQXR0cjsKKyAgICAgIGJvb2xlYW4gc3BlY2lmaWVkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXR0cmlidXRlcyA9IHRlc3RFbXBsb3llZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBkb21lc3RpY0F0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oInRpdGxlIik7CisgICAgICBzcGVjaWZpZWQgPSBkb21lc3RpY0F0dHIuZ2V0U3BlY2lmaWVkKCk7CisgICAgICBhc3NlcnRUcnVlKCJhY3JvbnltVGl0bGVTcGVjaWZpZWQiLCBzcGVjaWZpZWQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50YXNzb2NpYXRlZGF0dHJpYnV0ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZWxlbWVudGFzc29jaWF0ZWRhdHRyaWJ1dGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRjaGFuZ2VhdHRyaWJ1dGV2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50Y2hhbmdlYXR0cmlidXRldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNWIyZTUxCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50Y2hhbmdlYXR0cmlidXRldmFsdWUuamF2YQpAQCAtMCwwICsxLDkzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldEF0dHJpYnV0ZShuYW1lLHZhbHVlKSIgbWV0aG9kIGFkZHMgYSBuZXcgYXR0cmlidXRlCisgKiAgICB0byB0aGUgRWxlbWVudC4gIElmIHRoZSAic3Ryb25nIiBpcyBhbHJlYWR5IHByZXNlbnQsIHRoZW4KKyAqICAgIGl0cyB2YWx1ZSBzaG91bGQgYmUgY2hhbmdlZCB0byB0aGUgbmV3IG9uZSB0aGF0IGlzIGluCisgKiAgICB0aGUgInZhbHVlIiBwYXJhbWV0ZXIuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgZm91cnRoIGVtcGxveWVlLCB0aGVuIGFkZCAKKyAqICAgIGFuIGF0dHJpYnV0ZSB0byBpdCBieSBpbnZva2luZyB0aGUgCisgKiAgICAic2V0QXR0cmlidXRlKG5hbWUsdmFsdWUpIiBtZXRob2QuICBTaW5jZSB0aGUgbmFtZSBvZiB0aGUKKyAqICAgIHVzZWQgYXR0cmlidXRlKCJjbGFzcyIpIGlzIGFscmVhZHkgcHJlc2VudCBpbiB0aGlzICAgICAKKyAqICAgIGVsZW1lbnQsIHRoZW4gaXRzIHZhbHVlIHNob3VsZCBiZSBjaGFuZ2VkIHRvIHRoZSBuZXcgb25lCisgKiAgICBvZiB0aGUgInZhbHVlIiBwYXJhbWV0ZXIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19lbGVtZW50Y2hhbmdlYXR0cmlidXRldmFsdWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2VsZW1lbnRjaGFuZ2VhdHRyaWJ1dGV2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0RW1wbG95ZWU7CisgICAgICBTdHJpbmcgYXR0clZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RFbXBsb3llZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDMpOworICAgICAgdGVzdEVtcGxveWVlLnNldEF0dHJpYnV0ZSgiY2xhc3MiLCAiTmVpdGhlciIpOworICAgICAgYXR0clZhbHVlID0gdGVzdEVtcGxveWVlLmdldEF0dHJpYnV0ZSgiY2xhc3MiKTsKKyAgICAgIGFzc2VydEVxdWFscygiZWxlbWVudENoYW5nZUF0dHJpYnV0ZVZhbHVlQXNzZXJ0IiwgIk5laXRoZXIiLCBhdHRyVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50Y2hhbmdlYXR0cmlidXRldmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2VsZW1lbnRjaGFuZ2VhdHRyaWJ1dGV2YWx1ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGNyZWF0ZW5ld2F0dHJpYnV0ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50Y3JlYXRlbmV3YXR0cmlidXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGRkNWI2YQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGNyZWF0ZW5ld2F0dHJpYnV0ZS5qYXZhCkBAIC0wLDAgKzEsOTggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXRBdHRyaWJ1dGVOb2RlKG5ld0F0dHIpIiBtZXRob2QgYWRkcyBhIG5ldyAKKyAqICAgIGF0dHJpYnV0ZSB0byB0aGUgRWxlbWVudC4gIAorICogICAgCisgKiAgICBSZXRyaWV2ZSBmaXJzdCBhZGRyZXNzIGVsZW1lbnQgYW5kIGFkZAorICogICAgYSBuZXcgYXR0cmlidXRlIG5vZGUgdG8gaXQgYnkgaW52b2tpbmcgaXRzICAgICAgICAgCisgKiAgICAic2V0QXR0cmlidXRlTm9kZShuZXdBdHRyKSIgbWV0aG9kLiAgVGhpcyB0ZXN0IG1ha2VzIHVzZQorICogICAgb2YgdGhlICJjcmVhdGVBdHRyaWJ1dGUobmFtZSkiIG1ldGhvZCBmcm9tIHRoZSBEb2N1bWVudAorICogICAgaW50ZXJmYWNlLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODg3MjM2MTU0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04ODcyMzYxNTQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0MyI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0MzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfZWxlbWVudGNyZWF0ZW5ld2F0dHJpYnV0ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfZWxlbWVudGNyZWF0ZW5ld2F0dHJpYnV0ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcmVzczsKKyAgICAgIEF0dHIgbmV3QXR0cmlidXRlOworICAgICAgQXR0ciBvbGRBdHRyOworICAgICAgQXR0ciBkaXN0cmljdEF0dHI7CisgICAgICBTdHJpbmcgYXR0clZhbDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0QWRkcmVzcyA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgbmV3QXR0cmlidXRlID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZSgibGFuZyIpOworICAgICAgb2xkQXR0ciA9IHRlc3RBZGRyZXNzLnNldEF0dHJpYnV0ZU5vZGUobmV3QXR0cmlidXRlKTsKKyAgICAgIGFzc2VydE51bGwoIm9sZF9hdHRyX2RvZXNudF9leGlzdCIsIG9sZEF0dHIpOworICAgICAgZGlzdHJpY3RBdHRyID0gdGVzdEFkZHJlc3MuZ2V0QXR0cmlidXRlTm9kZSgibGFuZyIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgibmV3X2Rpc3RyaWN0X2FjY2Vzc2libGUiLCBkaXN0cmljdEF0dHIpOworICAgICAgYXR0clZhbCA9IHRlc3RBZGRyZXNzLmdldEF0dHJpYnV0ZSgibGFuZyIpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyX3ZhbHVlIiwgIiIsIGF0dHJWYWwpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50Y3JlYXRlbmV3YXR0cmlidXRlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19lbGVtZW50Y3JlYXRlbmV3YXR0cmlidXRlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50Z2V0YXR0cmlidXRlbm9kZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50Z2V0YXR0cmlidXRlbm9kZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkwYmM3ZjQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlLmphdmEKQEAgLTAsMCArMSw4NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgIFJldHJpZXZlIHRoZSBhdHRyaWJ1dGUgInRpdGxlIiBmcm9tIHRoZSBsYXN0IGNoaWxkCisgKiAgICBvZiB0aGUgZmlyc3QgInAiIGVsZW1lbnQgYW5kIGNoZWNrIGl0cyBub2RlIG5hbWUuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMTdBOTFCOCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjE3QTkxQjg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzNiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzNjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDNKdW4vMDAxMS5odG1sIj5odHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDNKdW4vMDAxMS5odG1sPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19lbGVtZW50Z2V0YXR0cmlidXRlbm9kZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfZWxlbWVudGdldGF0dHJpYnV0ZW5vZGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RFbXBsb3llZTsKKyAgICAgIEF0dHIgZG9tZXN0aWNBdHRyOworICAgICAgU3RyaW5nIG5vZGVOYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGRvbWVzdGljQXR0ciA9IHRlc3RFbXBsb3llZS5nZXRBdHRyaWJ1dGVOb2RlKCJ0aXRsZSIpOworICAgICAgbm9kZU5hbWUgPSBkb21lc3RpY0F0dHIuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJhdHRyaWJ1dGUiLCAibm9kZU5hbWUiLCAidGl0bGUiLCBub2RlTmFtZSk7CisgICAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGdldGF0dHJpYnV0ZW5vZGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50Z2V0YXR0cmlidXRlbm9kZW51bGwuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVudWxsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjk0MTY5MwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVudWxsLmphdmEKQEAgLTAsMCArMSw4OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRBdHRyaWJ1dGVOb2RlKG5hbWUpIiBtZXRob2QgcmV0cmlldmVzIGFuCisgKiAgICBhdHRyaWJ1dGUgbm9kZSBieSBuYW1lLiAgSXQgc2hvdWxkIHJldHVybiBudWxsIGlmIHRoZQorICogICAgInN0cm9uZyIgYXR0cmlidXRlIGRvZXMgbm90IGV4aXN0LgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgZmlyc3QgZW1wbG95ZWUgYW5kIGF0dGVtcHQKKyAqICAgIHRvIHJldHJpZXZlIGEgbm9uLWV4aXN0aW5nIGF0dHJpYnV0ZS4gIFRoZSBtZXRob2Qgc2hvdWxkCisgKiAgICByZXR1cm4gIm51bGwiLiAgVGhlIG5vbi1leGlzdGluZyBhdHRyaWJ1dGUgdG8gYmUgdXNlZAorICogICAgaXMgImludmFsaWRBdHRyaWJ1dGUiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjE3QTkxQjgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIxN0E5MUI4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19lbGVtZW50Z2V0YXR0cmlidXRlbm9kZW51bGwgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0RW1wbG95ZWU7CisgICAgICBBdHRyIGRvbWVzdGljQXR0cjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGRvbWVzdGljQXR0ciA9IHRlc3RFbXBsb3llZS5nZXRBdHRyaWJ1dGVOb2RlKCJpbnZhbGlkQXR0cmlidXRlIik7CisgICAgICBhc3NlcnROdWxsKCJlbGVtZW50R2V0QXR0cmlidXRlTm9kZU51bGxBc3NlcnQiLCBkb21lc3RpY0F0dHIpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50Z2V0YXR0cmlidXRlbm9kZW51bGwiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnVsbC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGdldGVsZW1lbnRlbXB0eS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50Z2V0ZWxlbWVudGVtcHR5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjkyNDE4NwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGdldGVsZW1lbnRlbXB0eS5qYXZhCkBAIC0wLDAgKzEsOTcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRBdHRyaWJ1dGUobmFtZSkiIG1ldGhvZCByZXR1cm5zIGFuIGVtcHR5IAorICogICAgc3RyaW5nIGlmIG5vIHZhbHVlIHdhcyBhc3NpZ25lZCB0byBhbiBhdHRyaWJ1dGUgYW5kIAorICogICAgbm8gZGVmYXVsdCB2YWx1ZSB3YXMgZ2l2ZW4gaW4gdGhlIERURCBmaWxlLgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgbGFzdCBlbXBsb3llZSwgdGhlbgorICogICAgaW52b2tlICJnZXRBdHRyaWJ1dGUobmFtZSkiIG1ldGhvZCwgd2hlcmUgInN0cm9uZyIgaXMgYW4KKyAqICAgIGF0dHJpYnV0ZSB3aXRob3V0IGEgc3BlY2lmaWVkIG9yIERURCBkZWZhdWx0IHZhbHVlLiAKKyAqICAgIFRoZSAiZ2V0QXR0cmlidXRlKG5hbWUpIiBtZXRob2Qgc2hvdWxkIHJldHVybiB0aGUgZW1wdHkKKyAqICAgIHN0cmluZy4gIFRoaXMgbWV0aG9kIG1ha2VzIHVzZSBvZiB0aGUKKyAqICAgICJjcmVhdGVBdHRyaWJ1dGUobmV3QXR0cikiIG1ldGhvZCBmcm9tIHRoZSBEb2N1bWVudAorICogICAgaW50ZXJmYWNlLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjY2RUUwRjkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTY2NkVFMEY5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDMiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2VsZW1lbnRnZXRlbGVtZW50ZW1wdHkgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2VsZW1lbnRnZXRlbGVtZW50ZW1wdHkoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0RW1wbG95ZWU7CisgICAgICBBdHRyIGRvbWVzdGljQXR0cjsKKyAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdBdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJsYW5nIik7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdEVtcGxveWVlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMyk7CisgICAgICBkb21lc3RpY0F0dHIgPSB0ZXN0RW1wbG95ZWUuc2V0QXR0cmlidXRlTm9kZShuZXdBdHRyaWJ1dGUpOworICAgICAgYXR0clZhbHVlID0gdGVzdEVtcGxveWVlLmdldEF0dHJpYnV0ZSgibGFuZyIpOworICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50R2V0RWxlbWVudEVtcHR5QXNzZXJ0IiwgIiIsIGF0dHJWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRnZXRlbGVtZW50ZW1wdHkiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2VsZW1lbnRnZXRlbGVtZW50ZW1wdHkuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zN2QxZTIyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWUuamF2YQpAQCAtMCwwICsxLDg1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIFRoZSAiZ2V0RWxlbWVudHNCeVRhZ05hbWUobmFtZSkiIG1ldGhvZCByZXR1cm5zIGEgbGlzdAorICogb2YgYWxsIGRlc2NlbmRhbnQgRWxlbWVudHMgd2l0aCB0aGUgZ2l2ZW4gdGFnIG5hbWUuCisgKiBUZXN0IGZvciBhbiBlbXB0eSBsaXN0LgorICogQ3JlYXRlIGEgTm9kZUxpc3Qgb2YgYWxsIHRoZSBkZXNjZW5kYW50IGVsZW1lbnRzCisgKiB1c2luZyB0aGUgc3RyaW5nICJub01hdGNoIiBhcyB0aGUgdGFnTmFtZS4KKyAqIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiBhIE5vZGVMaXN0IHdob3NlIGxlbmd0aCBpcworICogIjAiIHNpbmNlIHRoZXJlIGFyZSBub3QgYW55IGRlc2NlbmRhbnQgZWxlbWVudHMKKyAqIHRoYXQgbWF0Y2ggdGhlIGdpdmVuIHRhZyBuYW1lLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTkzODkxOEQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE5Mzg5MThEPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgYXNzZXJ0U2l6ZSgiZWxlbWVudEdldEVsZW1lbnRzQnlUYWdOYW1lQXNzZXJ0IiwgNSwgZWxlbWVudExpc3QpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lYWNjZXNzbm9kZWxpc3QuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lYWNjZXNzbm9kZWxpc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NTcwNzFiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVhY2Nlc3Nub2RlbGlzdC5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIFRoZSAiZ2V0RWxlbWVudHNCeVRhZ05hbWUobmFtZSkiIG1ldGhvZCByZXR1cm5zIGEgbGlzdAorICogb2YgYWxsIGRlc2NlbmRhbnQgRWxlbWVudHMgaW4gdGhlIG9yZGVyIHRoZSBjaGlsZHJlbgorICogd2VyZSBlbmNvdW50ZXJlZCBpbiBhIHByZSBvcmRlciB0cmF2ZXJzYWwgb2YgdGhlIGVsZW1lbnQKKyAqIHRyZWUuCisgKiBDcmVhdGUgYSBOb2RlTGlzdCBvZiBhbGwgdGhlIGRlc2NlbmRhbnQgZWxlbWVudHMKKyAqIHVzaW5nIHRoZSBzdHJpbmcgInAiIGFzIHRoZSB0YWdOYW1lLgorICogVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgTm9kZUxpc3Qgd2hvc2UgbGVuZ3RoIGlzCisgKiAiNSIgaW4gdGhlIG9yZGVyIHRoZSBjaGlsZHJlbiB3ZXJlIGVuY291bnRlcmVkLgorICogQWNjZXNzIHRoZSBGT1VSVEggZWxlbWVudCBpbiB0aGUgTm9kZUxpc3QuICBUaGUgRk9VUlRICisgKiBlbGVtZW50LCB0aGUgZmlyc3Qgb3Igc2Vjb25kIHNob3VsZCBiZSBhbiAiZW0iIG5vZGUgd2l0aAorICogdGhlIGNvbnRlbnQgIkVNUDAwMDQiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTkzODkxOEQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE5Mzg5MThEPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDYiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZWFjY2Vzc25vZGVsaXN0IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVhY2Nlc3Nub2RlbGlzdChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEVtcGxveWVlOworICAgICAgTm9kZSBmaXJzdEM7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgQ2hhcmFjdGVyRGF0YSBlbXBsb3llZUlETm9kZTsKKyAgICAgIFN0cmluZyBlbXBsb3llZUlEOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgzKTsKKyAgICAgIGZpcnN0QyA9IHRlc3RFbXBsb3llZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGZpcnN0Qy5nZXROb2RlVHlwZSgpOworICAgICAgCisgICAgd2hpbGUgKGVxdWFscygzLCBub2RlVHlwZSkpIHsKKyAgICBmaXJzdEMgPSBmaXJzdEMuZ2V0TmV4dFNpYmxpbmcoKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgZmlyc3RDLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICB9CitjaGlsZE5hbWUgPSBmaXJzdEMuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJlbGVtZW50IiwgImNoaWxkTmFtZSIsICJlbSIsIGNoaWxkTmFtZSk7CisgICAgICAgIGVtcGxveWVlSUROb2RlID0gKENoYXJhY3RlckRhdGEpIGZpcnN0Qy5nZXRGaXJzdENoaWxkKCk7CisgICAgICBlbXBsb3llZUlEID0gZW1wbG95ZWVJRE5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImVtcGxveWVlSUQiLCAiRU1QMDAwNCIsIGVtcGxveWVlSUQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVhY2Nlc3Nub2RlbGlzdCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lYWNjZXNzbm9kZWxpc3QuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5vbWF0Y2guamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbm9tYXRjaC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1ZGM3OWUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5vbWF0Y2guamF2YQpAQCAtMCwwICsxLDgzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIFRoZSAiZ2V0RWxlbWVudHNCeVRhZ05hbWUobmFtZSkiIG1ldGhvZCByZXR1cm5zIGEgbGlzdAorICogb2YgYWxsIGRlc2NlbmRhbnQgRWxlbWVudHMgd2l0aCB0aGUgZ2l2ZW4gdGFnIG5hbWUuCisgKiBDcmVhdGUgYSBOb2RlTGlzdCBvZiBhbGwgdGhlIGRlc2NlbmRhbnQgZWxlbWVudHMKKyAqIHVzaW5nIHRoZSBzdHJpbmcgImVtcGxveWVlIiBhcyB0aGUgdGFnTmFtZS4KKyAqIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiBhIE5vZGVMaXN0IHdob3NlIGxlbmd0aCBpcworICogIjUiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTkzODkxOEQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE5Mzg5MThEPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVub21hdGNoIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVub21hdGNoKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJub01hdGNoIik7CisgICAgICBhc3NlcnRTaXplKCJlbGVtZW50R2V0RWxlbWVudHNCeVRhZ05hbWVOb01hdGNoTm9NYXRjaEFzc2VydCIsIDAsIGVsZW1lbnRMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbm9tYXRjaCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbm9tYXRjaC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lc3BlY2lhbHZhbHVlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZXNwZWNpYWx2YWx1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMwYWJlYmIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZXNwZWNpYWx2YWx1ZS5qYXZhCkBAIC0wLDAgKzEsMTA1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogVGhlICJnZXRFbGVtZW50c0J5VGFnTmFtZShuYW1lKSIgbWV0aG9kIG1heSB1c2UgdGhlCisgKiBzcGVjaWFsIHZhbHVlICIqIiB0byBtYXRjaCBhbGwgdGFncyBpbiB0aGUgZWxlbWVudAorICogdHJlZS4KKyAqIENyZWF0ZSBhIE5vZGVMaXN0IG9mIGFsbCB0aGUgZGVzY2VuZGFudCBlbGVtZW50cworICogb2YgdGhlIGxhc3QgZW1wbG95ZWUgYnkgdXNpbmcgdGhlIHNwZWNpYWwgdmFsdWUgIioiLgorICogVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGFsbCB0aGUgZGVzY2VuZGFudCBjaGlsZHJlbig2KQorICogaW4gdGhlIG9yZGVyIHRoZSBjaGlsZHJlbiB3ZXJlIGVuY291bnRlcmVkLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTkzODkxOEQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE5Mzg5MThEPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVzcGVjaWFsdmFsdWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZXNwZWNpYWx2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgbGFzdEVtcGxveWVlOworICAgICAgTm9kZUxpc3QgbGFzdGVtcExpc3Q7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIGphdmEudXRpbC5MaXN0IHJlc3VsdCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5MaXN0IGV4cGVjdGVkUmVzdWx0ID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZW0iKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgic3Ryb25nIik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImNvZGUiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgic3VwIik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoInZhciIpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJhY3JvbnltIik7CisgICAgICAKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgbGFzdEVtcGxveWVlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oNCk7CisgICAgICBsYXN0ZW1wTGlzdCA9IGxhc3RFbXBsb3llZS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwNjcgPSAwOyBpbmRleE4xMDA2NyA8IGxhc3RlbXBMaXN0LmdldExlbmd0aCgpOyBpbmRleE4xMDA2NysrKSB7CisgICAgICAgICAgY2hpbGQgPSAoTm9kZSkgbGFzdGVtcExpc3QuaXRlbShpbmRleE4xMDA2Nyk7CisgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIHJlc3VsdC5hZGQoY2hpbGROYW1lKTsKKyAgICAgICAgfQorICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImVsZW1lbnQiLCAidGFnTmFtZXMiLCBleHBlY3RlZFJlc3VsdCwgcmVzdWx0KTsKKyAgICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVzcGVjaWFsdmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZXNwZWNpYWx2YWx1ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGdldHRhZ25hbWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGdldHRhZ25hbWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMzgyZTBlCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50Z2V0dGFnbmFtZS5qYXZhCkBAIC0wLDAgKzEsODggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICBJbnZva2UgdGhlICJnZXRUYWdOYW1lKCkiIG1ldGhvZCBvbmUgdGhlIAorICogICAgcm9vdCBub2RlLiBUaGUgdmFsdWUgcmV0dXJuZWQgc2hvdWxkIGJlICJodG1sIiBvciAic3ZnIi4gCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDQ2ODI4MTUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwNDY4MjgxNTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjUxIj5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjUxPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19lbGVtZW50Z2V0dGFnbmFtZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfZWxlbWVudGdldHRhZ25hbWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCByb290OworICAgICAgU3RyaW5nIHRhZ25hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgcm9vdCA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIHRhZ25hbWUgPSByb290LmdldFRhZ05hbWUoKTsKKyAgICAgIAorICAgICAgaWYgKCgiaW1hZ2Uvc3ZnK3htbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkgeworICAgICAgICAgIGFzc2VydEVxdWFscygic3ZnVGFnbmFtZSIsICJzdmciLCB0YWduYW1lKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImVsZW1lbnQiLCAidGFnbmFtZSIsICJodG1sIiwgdGFnbmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50Z2V0dGFnbmFtZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZWxlbWVudGdldHRhZ25hbWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRpbnVzZWF0dHJpYnV0ZWVyci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50aW51c2VhdHRyaWJ1dGVlcnIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNjhhMDBlCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50aW51c2VhdHRyaWJ1dGVlcnIuamF2YQpAQCAtMCwwICsxLDEwNCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldEF0dHJpYnV0ZU5vZGUobmV3QXR0cikiIG1ldGhvZCByYWlzZXMgYW4gCisgKiAgICAiSU5VU0VfQVRUUklCVVRFX0VSUiBET01FeGNlcHRpb24gaWYgdGhlICJuZXdBdHRyIiAKKyAqICAgIGlzIGFscmVhZHkgYW4gYXR0cmlidXRlIG9mIGFub3RoZXIgZWxlbWVudC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlVTRV9BVFRSSUJVVEVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04ODcyMzYxNTQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg4NzIzNjE1NDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtODg3MjM2MTU0JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTg4NzIzNjE1NCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVVNFX0FUVFJJQlVURV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NCI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfZWxlbWVudGludXNlYXR0cmlidXRlZXJyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19lbGVtZW50aW51c2VhdHRyaWJ1dGVlcnIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NFbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEFkZHJlc3M7CisgICAgICBFbGVtZW50IG5ld0VsZW1lbnQ7CisgICAgICBBdHRyIGF0dHJBZGRyZXNzOworICAgICAgTm9kZSBhcHBlbmRlZENoaWxkOworICAgICAgQXR0ciBzZXRBdHRyMTsKKyAgICAgIEF0dHIgc2V0QXR0cjI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBhZGRyZXNzRWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImJvZHkiKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gKEVsZW1lbnQpIGFkZHJlc3NFbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgbmV3RWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCJwIik7CisgICAgICBhcHBlbmRlZENoaWxkID0gdGVzdEFkZHJlc3MuYXBwZW5kQ2hpbGQobmV3RWxlbWVudCk7CisgICAgICBuZXdBdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJ0aXRsZSIpOworICAgICAgc2V0QXR0cjEgPSBuZXdFbGVtZW50LnNldEF0dHJpYnV0ZU5vZGUobmV3QXR0cmlidXRlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgc2V0QXR0cjIgPSB0ZXN0QWRkcmVzcy5zZXRBdHRyaWJ1dGVOb2RlKG5ld0F0dHJpYnV0ZSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVVNFX0FUVFJJQlVURV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSU5VU0VfQVRUUklCVVRFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50aW51c2VhdHRyaWJ1dGVlcnIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2VsZW1lbnRpbnVzZWF0dHJpYnV0ZWVyci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb24uamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kN2JmZmY1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsOTcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXRBdHRyaWJ1dGUobmFtZSx2YWx1ZSkiIG1ldGhvZCByYWlzZXMgYW4gCisgKiAgICAiSU5WQUxJRF9DSEFSQUNURVJfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIAorICogICAgbmFtZSBjb250YWlucyBhbiBpbnZhbGlkIGNoYXJhY3Rlci4gICAKKyAqICAgIFJldHJpZXZlIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSBmaXJzdCBlbXBsb3llZSBhbmQgCisgKiAgICBjYWxsIGl0cyAic2V0QXR0cmlidXRlKG5hbWUsdmFsdWUpIiBtZXRob2Qgd2l0aCAgICAKKyAqICAgICJzdHJvbmciIGNvbnRhaW5pbmcgYW4gaW52YWxpZCBjaGFyYWN0ZXIuIAorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC1GNjhGMDgyJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtRjY4RjA4MicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19lbGVtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfZWxlbWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb24oZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEFkZHJlc3M7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdEFkZHJlc3MgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdEFkZHJlc3Muc2V0QXR0cmlidXRlKCJpbnZhbGlkXk5hbWUiLCAidmFsdWUiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOVkFMSURfQ0hBUkFDVEVSX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZWxlbWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb24uY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbjEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMjg4NmFlCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbjEuamF2YQpAQCAtMCwwICsxLDkyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIENhbGxpbmcgRWxlbWVudC5zZXRBdHRyaWJ1dGUgd2l0aCBhbiBlbXB0eSBuYW1lIHdpbGwgY2F1c2UgYW4gSU5WQUxJRF9DSEFSQUNURVJfRVJSLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhGMDgyPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC1GNjhGMDgyJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtRjY4RjA4MicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9NTI1Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9NTI1PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19lbGVtZW50aW52YWxpZGNoYXJhY3RlcmV4Y2VwdGlvbjEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2VsZW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcmVzczsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0QWRkcmVzcyA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0QWRkcmVzcy5zZXRBdHRyaWJ1dGUoIiIsICJ2YWx1ZSIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTlZBTElEX0NIQVJBQ1RFUl9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSU5WQUxJRF9DSEFSQUNURVJfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRpbnZhbGlkY2hhcmFjdGVyZXhjZXB0aW9uMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZWxlbWVudGludmFsaWRjaGFyYWN0ZXJleGNlcHRpb24xLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50bm9ybWFsaXplLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRub3JtYWxpemUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYjE3MTRkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50bm9ybWFsaXplLmphdmEKQEAgLTAsMCArMSw5NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEFwcGVuZCBhIGNvdXBsZSBvZiB0ZXh0IG5vZGVzIHRvIHRoZSBmaXJzdCBzdXAgZWxlbWVudCwgbm9ybWFsaXplIHRoZQorICogZG9jdW1lbnQgZWxlbWVudCBhbmQgY2hlY2sgdGhhdCB0aGUgZWxlbWVudCBoYXMgYmVlbiBub3JtYWxpemVkLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTYyQ0YwODMiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE2MkNGMDgzPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD01NDYiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD01NDY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2VsZW1lbnRub3JtYWxpemUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2VsZW1lbnRub3JtYWxpemUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IHJvb3Q7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdE5hbWU7CisgICAgICBOb2RlIGZpcnN0Q2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGRWYWx1ZTsKKyAgICAgIFRleHQgdGV4dE5vZGU7CisgICAgICBOb2RlIHJldE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgic3VwIik7CisgICAgICB0ZXN0TmFtZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgdGV4dE5vZGUgPSBkb2MuY3JlYXRlVGV4dE5vZGUoIiIpOworICAgICAgcmV0Tm9kZSA9IHRlc3ROYW1lLmFwcGVuZENoaWxkKHRleHROb2RlKTsKKyAgICAgIHRleHROb2RlID0gZG9jLmNyZWF0ZVRleHROb2RlKCIsMDAwIik7CisgICAgICByZXROb2RlID0gdGVzdE5hbWUuYXBwZW5kQ2hpbGQodGV4dE5vZGUpOworICAgICAgcm9vdCA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIHJvb3Qubm9ybWFsaXplKCk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgic3VwIik7CisgICAgICB0ZXN0TmFtZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgZmlyc3RDaGlsZCA9IHRlc3ROYW1lLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkVmFsdWUgPSBmaXJzdENoaWxkLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50Tm9ybWFsaXplQXNzZXJ0IiwgIjU2LDAwMCwwMDAiLCBjaGlsZFZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudG5vcm1hbGl6ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZWxlbWVudG5vcm1hbGl6ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudG5vcm1hbGl6ZTIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudG5vcm1hbGl6ZTIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZjY0ZmE1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50bm9ybWFsaXplMi5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBZGQgYW4gZW1wdHkgdGV4dCBub2RlIHRvIGFuIGV4aXN0aW5nIGF0dHJpYnV0ZSBub2RlLCBub3JtYWxpemUgdGhlIGNvbnRhaW5pbmcgZWxlbWVudAorICogYW5kIGNoZWNrIHRoYXQgdGhlIGF0dHJpYnV0ZSBub2RlIGhhcyBlbGltaW5hdGVkIHRoZSBlbXB0eSB0ZXh0LgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTYyQ0YwODMiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE2MkNGMDgzPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD00ODIiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD00ODI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2VsZW1lbnRub3JtYWxpemUyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19lbGVtZW50bm9ybWFsaXplMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgcm9vdDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgTm9kZSBmaXJzdENoaWxkOworICAgICAgTm9kZSBzZWNvbmRDaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZFZhbHVlOworICAgICAgVGV4dCBlbXB0eVRleHQ7CisgICAgICBBdHRyIGF0dHJOb2RlOworICAgICAgTm9kZSByZXR2YWw7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICByb290ID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgZW1wdHlUZXh0ID0gZG9jLmNyZWF0ZVRleHROb2RlKCIiKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gcm9vdC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXR0ck5vZGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5vZGUoInRpdGxlIik7CisgICAgICByZXR2YWwgPSBhdHRyTm9kZS5hcHBlbmRDaGlsZChlbXB0eVRleHQpOworICAgICAgZWxlbWVudC5ub3JtYWxpemUoKTsKKyAgICAgIGF0dHJOb2RlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlKCJ0aXRsZSIpOworICAgICAgZmlyc3RDaGlsZCA9IGF0dHJOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkVmFsdWUgPSBmaXJzdENoaWxkLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJmaXJzdENoaWxkIiwgIlllcyIsIGNoaWxkVmFsdWUpOworICAgICAgc2Vjb25kQ2hpbGQgPSBmaXJzdENoaWxkLmdldE5leHRTaWJsaW5nKCk7CisgICAgICBhc3NlcnROdWxsKCJzZWNvbmRDaGlsZE51bGwiLCBzZWNvbmRDaGlsZCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRub3JtYWxpemUyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19lbGVtZW50bm9ybWFsaXplMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudG5vdGZvdW5kZXJyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRub3Rmb3VuZGVyci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU4ODU0NWEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRub3Rmb3VuZGVyci5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlbW92ZUF0dHJpYnV0ZU5vZGUob2xkQXR0cikiIG1ldGhvZCByYWlzZXMgYQorICogICAgTk9UX0ZPVU5EX0VSUiBET01FeGNlcHRpb24gaWYgdGhlICJvbGRBdHRyIiBhdHRyaWJ1dGUKKyAqICAgIGlzIG5vdCBhbiBhdHRyaWJ1dGUgb2YgdGhlIGVsZW1lbnQuCisgKiAgICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgbGFzdCBlbXBsb3llZSBhbmQgYXR0ZW1wdCB0byByZW1vdmUKKyAqICAgIGEgbm9uIGV4aXN0aW5nIGF0dHJpYnV0ZSBub2RlLiAgVGhpcyBzaG91bGQgY2F1c2UgdGhlCisgKiAgICBpbnRlbmRlZCBleGNlcHRpb24gdG8gYmUgcmFpc2VkLiAgVGhpcyB0ZXN0IG1ha2VzIHVzZQorICogICAgb2YgdGhlICJjcmVhdGVBdHRyaWJ1dGUobmFtZSkiIG1ldGhvZCBmcm9tIHRoZSBEb2N1bWVudCAKKyAqICAgIGludGVyZmFjZS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlVTRV9BVFRSSUJVVEVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENTg5MTk4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENTg5MTk4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC1ENTg5MTk4JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELUQ1ODkxOTgnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlVTRV9BVFRSSUJVVEVfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2VsZW1lbnRub3Rmb3VuZGVyciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfZWxlbWVudG5vdGZvdW5kZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgQXR0ciBvbGRBdHRyaWJ1dGU7CisgICAgICBOb2RlTGlzdCBhZGRyZXNzRWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RBZGRyZXNzOworICAgICAgQXR0ciBhdHRyQWRkcmVzczsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGFkZHJlc3NFbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdEFkZHJlc3MgPSAoRWxlbWVudCkgYWRkcmVzc0VsZW1lbnRMaXN0Lml0ZW0oNCk7CisgICAgICBvbGRBdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJ0aXRsZSIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhdHRyQWRkcmVzcyA9IHRlc3RBZGRyZXNzLnJlbW92ZUF0dHJpYnV0ZU5vZGUob2xkQXR0cmlidXRlKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT1RfRk9VTkRfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRub3Rmb3VuZGVyciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZWxlbWVudG5vdGZvdW5kZXJyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50cmVtb3ZlYXR0cmlidXRlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hY2Y2ZGMzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50cmVtb3ZlYXR0cmlidXRlLmphdmEKQEAgLTAsMCArMSw4NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZW1vdmVBdHRyaWJ1dGUobmFtZSkiIHJlbW92ZXMgYW4gYXR0cmlidXRlIGJ5IG5hbWUuCisgKiAgICBJZiB0aGUgYXR0cmlidXRlIGhhcyBhIGRlZmF1bHQgdmFsdWUsIGl0IGlzIGltbWVkaWF0ZWx5CisgKiAgICByZXBsYWNlZC4gIEhvd2V2ZXIsIHRoZXJlIGlzIG5vIGRlZmF1bHQgdmFsdWVzIGluIHRoZSBIVE1MCisgKiAgICBjb21wYXRpYmxlIHRlc3RzLCBzbyBpdHMgdmFsdWUgaXMgIiIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02RDZBQzBGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNkQ2QUMwRjk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyTWFyLzAwMDIuaHRtbCI+aHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyTWFyLzAwMDIuaHRtbDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfZWxlbWVudHJlbW92ZWF0dHJpYnV0ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfZWxlbWVudHJlbW92ZWF0dHJpYnV0ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0RW1wbG95ZWU7CisgICAgICBTdHJpbmcgYXR0clZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RFbXBsb3llZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDMpOworICAgICAgdGVzdEVtcGxveWVlLnJlbW92ZUF0dHJpYnV0ZSgiY2xhc3MiKTsKKyAgICAgIGF0dHJWYWx1ZSA9IHRlc3RFbXBsb3llZS5nZXRBdHRyaWJ1dGUoImNsYXNzIik7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJWYWx1ZSIsICIiLCBhdHRyVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50cmVtb3ZlYXR0cmlidXRlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19lbGVtZW50cmVtb3ZlYXR0cmlidXRlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50cmVtb3ZlYXR0cmlidXRlYWZ0ZXJjcmVhdGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJlbW92ZWF0dHJpYnV0ZWFmdGVyY3JlYXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGVjNzNhOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJlbW92ZWF0dHJpYnV0ZWFmdGVyY3JlYXRlLmphdmEKQEAgLTAsMCArMSw5NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlbW92ZUF0dHJpYnV0ZU5vZGUob2xkQXR0cikiIG1ldGhvZCByZW1vdmVzIHRoZSAKKyAqICAgIHNwZWNpZmllZCBhdHRyaWJ1dGUuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgdGhpcmQgZW1wbG95ZWUsIGFkZCBhCisgKiAgICBuZXcgImxhbmciIGF0dHJpYnV0ZSB0byBpdCBhbmQgdGhlbiB0cnkgdG8gcmVtb3ZlIGl0LiAKKyAqICAgIFRvIHZlcmlmeSB0aGF0IHRoZSBub2RlIHdhcyByZW1vdmVkIHVzZSB0aGUKKyAqICAgICJnZXROYW1lZEl0ZW0obmFtZSkiIG1ldGhvZCBmcm9tIHRoZSBOYW1lZE5vZGVNYXAKKyAqICAgIGludGVyZmFjZS4gIEl0IGFsc28gdXNlcyB0aGUgImdldEF0dHJpYnV0ZXMoKSIgbWV0aG9kCisgKiAgICBmcm9tIHRoZSBOb2RlIGludGVyZmFjZS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ1ODkxOTgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ1ODkxOTg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0MyI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0MzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfZWxlbWVudHJlbW92ZWF0dHJpYnV0ZWFmdGVyY3JlYXRlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19lbGVtZW50cmVtb3ZlYXR0cmlidXRlYWZ0ZXJjcmVhdGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEVtcGxveWVlOworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgZGlzdHJpY3RBdHRyOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RFbXBsb3llZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgbmV3QXR0cmlidXRlID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZSgibGFuZyIpOworICAgICAgZGlzdHJpY3RBdHRyID0gdGVzdEVtcGxveWVlLnNldEF0dHJpYnV0ZU5vZGUobmV3QXR0cmlidXRlKTsKKyAgICAgIGRpc3RyaWN0QXR0ciA9IHRlc3RFbXBsb3llZS5yZW1vdmVBdHRyaWJ1dGVOb2RlKG5ld0F0dHJpYnV0ZSk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdEVtcGxveWVlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGRpc3RyaWN0QXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgibGFuZyIpOworICAgICAgYXNzZXJ0TnVsbCgicmVtb3ZlZF9pdGVtX251bGwiLCBkaXN0cmljdEF0dHIpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50cmVtb3ZlYXR0cmlidXRlYWZ0ZXJjcmVhdGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVhZnRlcmNyZWF0ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vZGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5vZGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MDk2MTE0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9kZS5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZW1vdmVBdHRyaWJ1dGVOb2RlKG9sZEF0dHIpIiBtZXRob2QgcmV0dXJucyB0aGUKKyAqICAgIG5vZGUgdGhhdCB3YXMgcmVtb3ZlZC4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSB0aGlyZCBlbXBsb3llZSBhbmQKKyAqICAgIHJlbW92ZSBpdHMgImNsYXNzIiBBdHRyIG5vZGUuICBUaGUgbWV0aG9kIHNob3VsZCAgCisgKiAgICByZXR1cm4gdGhlIG9sZCBhdHRyaWJ1dGUgbm9kZS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ1ODkxOTgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ1ODkxOTg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVub2RlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19lbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9kZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0RW1wbG95ZWU7CisgICAgICBBdHRyIHN0cmVldEF0dHI7CisgICAgICBBdHRyIHJlbW92ZWRBdHRyOworICAgICAgU3RyaW5nIHJlbW92ZWRWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIHN0cmVldEF0dHIgPSB0ZXN0RW1wbG95ZWUuZ2V0QXR0cmlidXRlTm9kZSgiY2xhc3MiKTsKKyAgICAgIHJlbW92ZWRBdHRyID0gdGVzdEVtcGxveWVlLnJlbW92ZUF0dHJpYnV0ZU5vZGUoc3RyZWV0QXR0cik7CisgICAgICBhc3NlcnROb3ROdWxsKCJyZW1vdmVkQXR0ck5vdE51bGwiLCByZW1vdmVkQXR0cik7CisgICAgICByZW1vdmVkVmFsdWUgPSByZW1vdmVkQXR0ci5nZXRWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50UmVtb3ZlQXR0cmlidXRlTm9kZUFzc2VydCIsICJObyIsIHJlbW92ZWRWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVub2RlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19lbGVtZW50cmVtb3ZlYXR0cmlidXRlbm9kZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJlcGxhY2VhdHRyaWJ1dGV3aXRoc2VsZi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50cmVwbGFjZWF0dHJpYnV0ZXdpdGhzZWxmLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmI4NjYxYwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJlcGxhY2VhdHRyaWJ1dGV3aXRoc2VsZi5qYXZhCkBAIC0wLDAgKzEsOTAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogVGhpcyB0ZXN0IGNhbGxzIHNldEF0dHJpYnV0ZU5vZGUgdG8gcmVwbGFjZSBhbiBhdHRyaWJ1dGUgd2l0aCBpdHNlbGYuICAKKyAqIFNpbmNlIHRoZSBub2RlIGlzIG5vdCBhbiBhdHRyaWJ1dGUgb2YgYW5vdGhlciBFbGVtZW50LCBpdCB3b3VsZAorICogYmUgaW5hcHByb3ByaWF0ZSB0byB0aHJvdyBhbiBJTlVTRV9BVFRSSUJVVEVfRVJSLgorICogVGhpcyB0ZXN0IHdhcyBkZXJpdmVkIGZyb20gZWxlbWVudGludXNlcmF0dHJpYnV0ZWVyciB3aGljaAorICogaW5hZHZlcnRhbmx5IG1hZGUgdGhpcyB0ZXN0LgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04ODcyMzYxNTQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg4NzIzNjE1NDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfZWxlbWVudHJlcGxhY2VhdHRyaWJ1dGV3aXRoc2VsZiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfZWxlbWVudHJlcGxhY2VhdHRyaWJ1dGV3aXRoc2VsZihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0RW1wbG95ZWU7CisgICAgICBBdHRyIHN0cmVldEF0dHI7CisgICAgICBBdHRyIHJlcGxhY2VkQXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIHN0cmVldEF0dHIgPSB0ZXN0RW1wbG95ZWUuZ2V0QXR0cmlidXRlTm9kZSgiY2xhc3MiKTsKKyAgICAgIHJlcGxhY2VkQXR0ciA9IHRlc3RFbXBsb3llZS5zZXRBdHRyaWJ1dGVOb2RlKHN0cmVldEF0dHIpOworICAgICAgYXNzZXJ0U2FtZSgicmVwbGFjZWRBdHRyIiwgc3RyZWV0QXR0ciwgcmVwbGFjZWRBdHRyKTsKK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJlcGxhY2VhdHRyaWJ1dGV3aXRoc2VsZiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZWxlbWVudHJlcGxhY2VhdHRyaWJ1dGV3aXRoc2VsZi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJlcGxhY2VleGlzdGluZ2F0dHJpYnV0ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50cmVwbGFjZWV4aXN0aW5nYXR0cmlidXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjIxZTI2NQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJlcGxhY2VleGlzdGluZ2F0dHJpYnV0ZS5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0QXR0cmlidXRlTm9kZShuZXdBdHRyKSIgbWV0aG9kIGFkZHMgYSBuZXcKKyAqICAgIGF0dHJpYnV0ZSB0byB0aGUgRWxlbWVudC4gIElmIHRoZSAibmV3QXR0ciIgQXR0ciBub2RlIGlzCisgKiAgICBhbHJlYWR5IHByZXNlbnQgaW4gdGhpcyBlbGVtZW50LCBpdCBzaG91bGQgcmVwbGFjZSB0aGUKKyAqICAgIGV4aXN0aW5nIG9uZS4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSB0aGlyZCBlbXBsb3llZSBhbmQgYWRkIGEgCisgKiAgICBuZXcgYXR0cmlidXRlIG5vZGUgYnkgaW52b2tpbmcgdGhlICJzZXRBdHRyaWJ1dGVOb2RlKG5ldyAKKyAqICAgIEF0dHIpIiBtZXRob2QuICBUaGUgbmV3IGF0dHJpYnV0ZSBub2RlIHRvIGJlIGFkZGVkIGlzIAorICogICAgImNsYXNzIiwgd2hpY2ggaXMgYWxyZWFkeSBwcmVzZW50IGluIHRoaXMgZWxlbWVudC4gIFRoZQorICogICAgbWV0aG9kIHNob3VsZCByZXBsYWNlIHRoZSBleGlzdGluZyBBdHRyIG5vZGUgd2l0aCB0aGUgCisgKiAgICBuZXcgb25lLiAgVGhpcyB0ZXN0IHVzZXMgdGhlICJjcmVhdGVBdHRyaWJ1dGUobmFtZSkiCisgKiAgICBtZXRob2QgZnJvbSB0aGUgRG9jdW1lbnQgaW50ZXJmYWNlLiAKKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19lbGVtZW50cmVwbGFjZWV4aXN0aW5nYXR0cmlidXRlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19lbGVtZW50cmVwbGFjZWV4aXN0aW5nYXR0cmlidXRlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RFbXBsb3llZTsKKyAgICAgIEF0dHIgbmV3QXR0cmlidXRlOworICAgICAgU3RyaW5nIHN0cm9uZzsKKyAgICAgIEF0dHIgc2V0QXR0cjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoImNsYXNzIik7CisgICAgICBzZXRBdHRyID0gdGVzdEVtcGxveWVlLnNldEF0dHJpYnV0ZU5vZGUobmV3QXR0cmlidXRlKTsKKyAgICAgIHN0cm9uZyA9IHRlc3RFbXBsb3llZS5nZXRBdHRyaWJ1dGUoImNsYXNzIik7CisgICAgICBhc3NlcnRFcXVhbHMoInJlcGxhY2VkVmFsdWUiLCAiIiwgc3Ryb25nKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJlcGxhY2VleGlzdGluZ2F0dHJpYnV0ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZWxlbWVudHJlcGxhY2VleGlzdGluZ2F0dHJpYnV0ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJlcGxhY2VleGlzdGluZ2F0dHJpYnV0ZWdldmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJlcGxhY2VleGlzdGluZ2F0dHJpYnV0ZWdldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42OWMzN2I5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50cmVwbGFjZWV4aXN0aW5nYXR0cmlidXRlZ2V2YWx1ZS5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBJZiB0aGUgInNldEF0dHJpYnV0ZU5vZGUobmV3QXR0cikiIG1ldGhvZCByZXBsYWNlcyBhbgorICogZXhpc3RpbmcgQXR0ciBub2RlIHdpdGggdGhlIHNhbWUgbmFtZSwgdGhlbiBpdCBzaG91bGQKKyAqIHJldHVybiB0aGUgcHJldmlvdXNseSBleGlzdGluZyBBdHRyIG5vZGUuCisgKiBSZXRyaWV2ZSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgdGhpcmQgZW1wbG95ZWUgYW5kIGFkZCBhCisgKiBuZXcgYXR0cmlidXRlIG5vZGUuICBUaGUgbmV3IGF0dHJpYnV0ZSBub2RlIGlzICJjbGFzcyIsCisgKiB3aGljaCBpcyBhbHJlYWR5IHByZXNlbnQgaW4gdGhpcyBFbGVtZW50LiAgVGhlIG1ldGhvZAorICogc2hvdWxkIHJldHVybiB0aGUgZXhpc3RpbmcgQXR0ciBub2RlKG9sZCAiY2xhc3MiIEF0dHIpLgorICogVGhpcyB0ZXN0IHVzZXMgdGhlICJjcmVhdGVBdHRyaWJ1dGUobmFtZSkiIG1ldGhvZAorICogZnJvbSB0aGUgRG9jdW1lbnQgaW50ZXJmYWNlLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODg3MjM2MTU0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04ODcyMzYxNTQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2VsZW1lbnRyZXBsYWNlZXhpc3RpbmdhdHRyaWJ1dGVnZXZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19lbGVtZW50cmVwbGFjZWV4aXN0aW5nYXR0cmlidXRlZ2V2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0RW1wbG95ZWU7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIEF0dHIgc3RyZWV0QXR0cjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoImNsYXNzIik7CisgICAgICBzdHJlZXRBdHRyID0gdGVzdEVtcGxveWVlLnNldEF0dHJpYnV0ZU5vZGUobmV3QXR0cmlidXRlKTsKKyAgICAgIGFzc2VydE5vdE51bGwoInByZXZpb3VzQXR0ck5vdE51bGwiLCBzdHJlZXRBdHRyKTsKKyAgICAgIHZhbHVlID0gc3RyZWV0QXR0ci5nZXRWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJwcmV2aW91c0F0dHJWYWx1ZSIsICJObyIsIHZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJlcGxhY2VleGlzdGluZ2F0dHJpYnV0ZWdldmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2VsZW1lbnRyZXBsYWNlZXhpc3RpbmdhdHRyaWJ1dGVnZXZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50cmV0cmlldmVhbGxhdHRyaWJ1dGVzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRyZXRyaWV2ZWFsbGF0dHJpYnV0ZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMTJmYjgyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50cmV0cmlldmVhbGxhdHRyaWJ1dGVzLmphdmEKQEAgLTAsMCArMSwxMDggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICBDcmVhdGUgYSBsaXN0IG9mIGFsbCB0aGUgYXR0cmlidXRlcyBvZiB0aGUgbGFzdCBjaGlsZAorICogICAgb2YgdGhlIGZpcnN0ICJwIiBlbGVtZW50IGJ5IHVzaW5nIHRoZSAiZ2V0QXR0cmlidXRlcygpIgorICogICAgbWV0aG9kLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDJNYXIvMDAwMi5odG1sIj5odHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDJNYXIvMDAwMi5odG1sPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0xODQiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0xODQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2VsZW1lbnRyZXRyaWV2ZWFsbGF0dHJpYnV0ZXMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2VsZW1lbnRyZXRyaWV2ZWFsbGF0dHJpYnV0ZXMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWRkcmVzc0xpc3Q7CisgICAgICBOb2RlIHRlc3RBZGRyZXNzOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIFN0cmluZyBhdHRyaWJ1dGVOYW1lOworICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb24gYWN0dWFsID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb24gaHRtbEV4cGVjdGVkID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGh0bWxFeHBlY3RlZC5hZGQoInRpdGxlIik7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9uIGV4cGVjdGVkID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgidGl0bGUiKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgiZGlyIik7CisgICAgICAKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBhZGRyZXNzTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdEFkZHJlc3MgPSBhZGRyZXNzTGlzdC5pdGVtKDApOworICAgICAgYXR0cmlidXRlcyA9IHRlc3RBZGRyZXNzLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDZCID0gMDsgaW5kZXhOMTAwNkIgPCBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOyBpbmRleE4xMDA2QisrKSB7CisgICAgICAgICAgYXR0cmlidXRlID0gKEF0dHIpIGF0dHJpYnV0ZXMuaXRlbShpbmRleE4xMDA2Qik7CisgICAgYXR0cmlidXRlTmFtZSA9IGF0dHJpYnV0ZS5nZXROb2RlTmFtZSgpOworICAgICAgYWN0dWFsLmFkZChhdHRyaWJ1dGVOYW1lKTsKKyAgICAgICAgfQorICAgICAgCisgICAgICBpZiAoKCJ0ZXh0L2h0bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHNJZ25vcmVDYXNlKCJodG1sQXR0cmlidXRlTmFtZXMiLCBodG1sRXhwZWN0ZWQsIGFjdHVhbCk7Cit9IGVsc2UgeworICAgICAgICAgIGFzc2VydEVxdWFsc0lnbm9yZUNhc2UoImF0dHJpYnV0ZU5hbWVzIiwgZXhwZWN0ZWQsIGFjdHVhbCk7Cit9CisgICAgICAgIAorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJldHJpZXZlYWxsYXR0cmlidXRlcyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZWxlbWVudHJldHJpZXZlYWxsYXR0cmlidXRlcy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHJldHJpZXZlYXR0cnZhbHVlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRyZXRyaWV2ZWF0dHJ2YWx1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhYzNkMmEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRyZXRyaWV2ZWF0dHJ2YWx1ZS5qYXZhCkBAIC0wLDAgKzEsODcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0QXR0cmlidXRlKG5hbWUpIiBtZXRob2QgcmV0dXJucyBhbiBhdHRyaWJ1dGUKKyAqICAgIHZhbHVlIGJ5IG5hbWUuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgYWRkcmVzcyBlbGVtZW50LCB0aGVuCisgKiAgICBpbnZva2UgdGhlICdnZXRBdHRyaWJ1dGUoImNsYXNzIiknIG1ldGhvZC4gIFRoaXMgc2hvdWxkCisgKiAgICByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUoIk5vIikuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NjZFRTBGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjY2RUUwRjk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2VsZW1lbnRyZXRyaWV2ZWF0dHJ2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfZWxlbWVudHJldHJpZXZlYXR0cnZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcmVzczsKKyAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBhdHRyVmFsdWUgPSB0ZXN0QWRkcmVzcy5nZXRBdHRyaWJ1dGUoImNsYXNzIik7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJWYWx1ZSIsICJObyIsIGF0dHJWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRyZXRyaWV2ZWF0dHJ2YWx1ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZWxlbWVudHJldHJpZXZlYXR0cnZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50cmV0cmlldmV0YWduYW1lLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRyZXRyaWV2ZXRhZ25hbWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYWE0ZDdhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50cmV0cmlldmV0YWduYW1lLmphdmEKQEAgLTAsMCArMSw5MCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRFbGVtZW50c0J5VGFnTmFtZSgpIiBtZXRob2QgcmV0dXJucyBhIE5vZGVMaXN0IAorICogICAgb2YgYWxsIGRlc2NlbmRhbnQgZWxlbWVudHMgd2l0aCBhIGdpdmVuIHRhZ05hbWUuICAgIAorICogICAgCisgKiAgICBJbnZva2UgdGhlICJnZXRFbGVtZW50c0J5VGFnTmFtZSgpIiBtZXRob2QgYW5kIGNyZWF0ZQorICogICAgYSBOb2RlTGlzdCBvZiAiY29kZSIgZWxlbWVudHMuICBSZXRyaWV2ZSB0aGUgc2Vjb25kIAorICogICAgImNvZGUiIGVsZW1lbnQgaW4gdGhlIGxpc3QgYW5kIHJldHVybiB0aGUgTm9kZU5hbWUuIAorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDQ2ODI4MTUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwNDY4MjgxNTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfZWxlbWVudHJldHJpZXZldGFnbmFtZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfZWxlbWVudHJldHJpZXZldGFnbmFtZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgU3RyaW5nIHN0cm9uZzsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiY29kZSIpOworICAgICAgdGVzdEVtcGxveWVlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIHN0cm9uZyA9IHRlc3RFbXBsb3llZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImVsZW1lbnQiLCAibm9kZW5hbWUiLCAiY29kZSIsIHN0cm9uZyk7CisgICAgICAgIHN0cm9uZyA9ICgoRWxlbWVudCkgLypOb2RlICovdGVzdEVtcGxveWVlKS5nZXRUYWdOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHNBdXRvQ2FzZSgiZWxlbWVudCIsICJ0YWduYW1lIiwgImNvZGUiLCBzdHJvbmcpOworICAgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRyZXRyaWV2ZXRhZ25hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2VsZW1lbnRyZXRyaWV2ZXRhZ25hbWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50c2V0YXR0cmlidXRlbm9kZW51bGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MDkxNDJmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50c2V0YXR0cmlidXRlbm9kZW51bGwuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0QXR0cmlidXRlTm9kZShuZXdBdHRyKSIgbWV0aG9kIHJldHVybnMgdGhlCisgKiAgICBudWxsIHZhbHVlIGlmIG5vIHByZXZpb3VzbHkgZXhpc3RpbmcgQXR0ciBub2RlIHdpdGggdGhlCisgKiAgICBzYW1lIG5hbWUgd2FzIHJlcGxhY2VkLgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgdGhpcmQgZW1wbG95ZWUgYW5kIGFkZCBhIAorICogICAgbmV3IGF0dHJpYnV0ZSB0byBpdC4gIFRoZSBuZXcgYXR0cmlidXRlIG5vZGUgYWRkZWQgaXMgCisgKiAgICAibGFuZyIsIHdoaWNoIGlzIG5vdCBwYXJ0IG9mIHRoaXMgRWxlbWVudC4gIFRoZSAgIAorICogICAgbWV0aG9kIHNob3VsZCByZXR1cm4gdGhlIG51bGwgdmFsdWUuICAgCisgKiAgICBUaGlzIHRlc3QgdXNlcyB0aGUgImNyZWF0ZUF0dHJpYnV0ZShuYW1lKSIKKyAqICAgIG1ldGhvZCBmcm9tIHRoZSBEb2N1bWVudCBpbnRlcmZhY2UuIAorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODg3MjM2MTU0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04ODcyMzYxNTQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0MyI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0MzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVudWxsIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19lbGVtZW50c2V0YXR0cmlidXRlbm9kZW51bGwoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEVtcGxveWVlOworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBBdHRyIGRpc3RyaWN0QXR0cjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoImxhbmciKTsKKyAgICAgIGRpc3RyaWN0QXR0ciA9IHRlc3RFbXBsb3llZS5zZXRBdHRyaWJ1dGVOb2RlKG5ld0F0dHJpYnV0ZSk7CisgICAgICBhc3NlcnROdWxsKCJlbGVtZW50U2V0QXR0cmlidXRlTm9kZU51bGxBc3NlcnQiLCBkaXN0cmljdEF0dHIpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50c2V0YXR0cmlidXRlbm9kZW51bGwiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnVsbC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHdyb25nZG9jdW1lbnRlcnIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfZWxlbWVudHdyb25nZG9jdW1lbnRlcnIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOGUxNzZhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbGVtZW50d3Jvbmdkb2N1bWVudGVyci5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0QXR0cmlidXRlTm9kZShuZXdBdHRyKSIgbWV0aG9kIHJhaXNlcyBhbiAKKyAqICAgICJXUk9OR19ET0NVTUVOVF9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSAibmV3QXR0ciIgCisgKiAgICB3YXMgY3JlYXRlZCBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0CisgKiAgICBjcmVhdGVkIHRoaXMgZG9jdW1lbnQuCisgKiAgICBSZXRyaWV2ZSB0aGUgbGFzdCBlbXBsb3llZSBhbmQgYXR0ZW1wdCB0byBzZXQgYSBuZXcKKyAqICAgIGF0dHJpYnV0ZSBub2RlIGZvciBpdHMgImVtcGxveWVlIiBlbGVtZW50LiAgVGhlIG5ldworICogICAgYXR0cmlidXRlIHdhcyBjcmVhdGVkIGZyb20gYSBkb2N1bWVudCBvdGhlciB0aGFuIHRoZQorICogICAgb25lIHRoYXQgY3JlYXRlZCB0aGlzIGVsZW1lbnQsIHRoZXJlZm9yZSBhCisgKiAgICBXUk9OR19ET0NVTUVOVF9FUlIgRE9NRXhjZXB0aW9uIHNob3VsZCBiZSByYWlzZWQuCisgKiAgICBUaGlzIHRlc3QgdXNlcyB0aGUgImNyZWF0ZUF0dHJpYnV0ZShuZXdBdHRyKSIgbWV0aG9kCisgKiAgICBmcm9tIHRoZSBEb2N1bWVudCBpbnRlcmZhY2UuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nV1JPTkdfRE9DVU1FTlRfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nV1JPTkdfRE9DVU1FTlRfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg4NzIzNjE1NCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODg3MjM2MTU0PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC04ODcyMzYxNTQnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdXUk9OR19ET0NVTUVOVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC04ODcyMzYxNTQnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdXUk9OR19ET0NVTUVOVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfZWxlbWVudHdyb25nZG9jdW1lbnRlcnIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2VsZW1lbnR3cm9uZ2RvY3VtZW50ZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzE7CisgICAgICBEb2N1bWVudCBkb2MyOworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBOb2RlTGlzdCBhZGRyZXNzRWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RBZGRyZXNzOworICAgICAgQXR0ciBhdHRyQWRkcmVzczsKKyAgICAgIGRvYzEgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBkb2MyID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9IGRvYzIuY3JlYXRlQXR0cmlidXRlKCJuZXdBdHRyaWJ1dGUiKTsKKyAgICAgIGFkZHJlc3NFbGVtZW50TGlzdCA9IGRvYzEuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gKEVsZW1lbnQpIGFkZHJlc3NFbGVtZW50TGlzdC5pdGVtKDQpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhdHRyQWRkcmVzcyA9IHRlc3RBZGRyZXNzLnNldEF0dHJpYnV0ZU5vZGUobmV3QXR0cmlidXRlKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X1dST05HX0RPQ1VNRU5UX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbGVtZW50d3Jvbmdkb2N1bWVudGVyciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfZWxlbWVudHdyb25nZG9jdW1lbnRlcnIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VudGl0aWVzcmVtb3ZlbmFtZWRpdGVtMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbnRpdGllc3JlbW92ZW5hbWVkaXRlbTEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZTZiNWVhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbnRpdGllc3JlbW92ZW5hbWVkaXRlbTEuamF2YQpAQCAtMCwwICsxLDEwMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBbiBhdHRlbXB0IHRvIGFkZCByZW1vdmUgYW4gZW50aXR5IHNob3VsZCByZXN1bHQgaW4gYSBOT19NT0RJRklDQVRJT05fRVJSLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTc4ODc5NDYzMCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTc4ODc5NDYzMDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENThCMTkzIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENThCMTkzPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19lbnRpdGllc3JlbW92ZW5hbWVkaXRlbTEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2VudGl0aWVzcmVtb3ZlbmFtZWRpdGVtMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKyAgICAgIGlmIChmYWN0b3J5Lmhhc0ZlYXR1cmUoIlhNTCIsIG51bGwpICE9IHRydWUpIHsKKyAgICAgICAgIHRocm93IG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbi5pbmNvbXBhdGlibGVGZWF0dXJlKCJYTUwiLCBudWxsKTsKKyAgICAgIH0KKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdGllczsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTm9kZSByZXR2YWw7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKAorICAgICEoKCJ0ZXh0L2h0bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpCispIHsKKyAgICAgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgZW50aXRpZXMgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdGllc05vdE51bGwiLCBlbnRpdGllcyk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHZhbCA9IGVudGl0aWVzLnJlbW92ZU5hbWVkSXRlbSgiYWxwaGEiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfZW50aXRpZXNyZW1vdmVuYW1lZGl0ZW0xIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19lbnRpdGllc3JlbW92ZW5hbWVkaXRlbTEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX2VudGl0aWVzc2V0bmFtZWRpdGVtMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbnRpdGllc3NldG5hbWVkaXRlbTEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OTBmMzVhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19lbnRpdGllc3NldG5hbWVkaXRlbTEuamF2YQpAQCAtMCwwICsxLDEwOSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBbiBhdHRlbXB0IHRvIGFkZCBhbiBlbGVtZW50IHRvIHRoZSBuYW1lZCBub2RlIG1hcCByZXR1cm5lZCBieSBlbnRpdGllcyBzaG91bGQgCisgKiByZXN1bHQgaW4gYSBOT19NT0RJRklDQVRJT05fRVJSIG9yIEhJRVJBUkNIWV9SRVFVRVNUX0VSUi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3ODg3OTQ2MzAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3ODg3OTQ2MzA8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTAyNTE2Mzc4OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTAyNTE2Mzc4ODwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfZW50aXRpZXNzZXRuYW1lZGl0ZW0xIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19lbnRpdGllc3NldG5hbWVkaXRlbTEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisgICAgICBpZiAoZmFjdG9yeS5oYXNGZWF0dXJlKCJYTUwiLCBudWxsKSAhPSB0cnVlKSB7CisgICAgICAgICB0aHJvdyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24uaW5jb21wYXRpYmxlRmVhdHVyZSgiWE1MIiwgbnVsbCk7CisgICAgICB9CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOYW1lZE5vZGVNYXAgZW50aXRpZXM7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIE5vZGUgcmV0dmFsOworICAgICAgRWxlbWVudCBlbGVtOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICAKKyAgICAgIGlmICgKKyAgICAhKCgidGV4dC9odG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKQorKSB7CisgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZG9jVHlwZU5vdE51bGwiLCBkb2NUeXBlKTsKKyAgICAgIGVudGl0aWVzID0gZG9jVHlwZS5nZXRFbnRpdGllcygpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50aXRpZXNOb3ROdWxsIiwgZW50aXRpZXMpOworICAgICAgZWxlbSA9IGRvYy5jcmVhdGVFbGVtZW50KCJiciIpOworICAgICAgCisgICAgICB0cnkgeworICAgICAgcmV0dmFsID0gZW50aXRpZXMuc2V0TmFtZWRJdGVtKGVsZW0pOworICAgICAgZmFpbCgidGhyb3dfSElFUl9PUl9OT19NT0RfRVJSIik7CisgICAgIAorICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgIHN3aXRjaCAoZXguY29kZSkgeworICAgICAgY2FzZSAzIDogCisgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDcgOiAKKyAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIHRocm93IGV4OworICAgICAgICAgIH0KKyAgICAgIH0gCit9CisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19lbnRpdGllc3NldG5hbWVkaXRlbTEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2VudGl0aWVzc2V0bmFtZWRpdGVtMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwY2hpbGRub2RlcmFuZ2UuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwY2hpbGRub2RlcmFuZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMjgzYTYxCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXBjaGlsZG5vZGVyYW5nZS5qYXZhCkBAIC0wLDAgKzEsMTA2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgQ3JlYXRlIGEgTmFtZWROb2RlTWFwIG9iamVjdCBmcm9tIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZQorICogICAgbGFzdCBjaGlsZCBvZiB0aGUgdGhpcmQgInAiIGVsZW1lbnQgYW5kIHRyYXZlcnNlIHRoZQorICogICAgbGlzdCBmcm9tIGluZGV4IDAgdGhydSBsZW5ndGggLTEuICBBbGwgaW5kaWNlcyBzaG91bGQKKyAqICAgIGJlIHZhbGlkLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zNDk0NjdGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3Rjk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNkQwRkIxOUUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTZEMEZCMTlFPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTAiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTA8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25hbWVkbm9kZW1hcGNoaWxkbm9kZXJhbmdlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19uYW1lZG5vZGVtYXBjaGlsZG5vZGVyYW5nZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIHN0cm9uZzsKKyAgICAgIGludCBsZW5ndGg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RFbXBsb3llZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdEVtcGxveWVlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGxlbmd0aCA9IChpbnQpIGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7CisgICAgICAKKyAgICAgIGlmICgoInRleHQvaHRtbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkgeworICAgICAgICAgIGFzc2VydEVxdWFscygiaHRtbExlbmd0aCIsIDIsIGxlbmd0aCk7CisgICAgICB9IGVsc2UgeworICAgICAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoIiwgMywgbGVuZ3RoKTsKKyAgICAgIGNoaWxkID0gYXR0cmlidXRlcy5pdGVtKDIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiYXR0cjIiLCBjaGlsZCk7CisgICAgICB9CisgICAgICAgIAorICAgIGNoaWxkID0gYXR0cmlidXRlcy5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiYXR0cjAiLCBjaGlsZCk7CisgICAgICBjaGlsZCA9IGF0dHJpYnV0ZXMuaXRlbSgxKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImF0dHIxIiwgY2hpbGQpOworICAgICAgY2hpbGQgPSBhdHRyaWJ1dGVzLml0ZW0oMyk7CisgICAgICBhc3NlcnROdWxsKCJhdHRyMyIsIGNoaWxkKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwY2hpbGRub2RlcmFuZ2UiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25hbWVkbm9kZW1hcGNoaWxkbm9kZXJhbmdlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW0uamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmU5ZTc5MwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtLmphdmEKQEAgLTAsMCArMSw5MyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgInAiIGVsZW1lbnQgYW5kIGNyZWF0ZSBhIE5hbWVkTm9kZU1hcCAKKyAqICAgIGxpc3Rpbmcgb2YgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGxhc3QgY2hpbGQuICBPbmNlIHRoZQorICogICAgbGlzdCBpcyBjcmVhdGVkIGFuIGludm9jYXRpb24gb2YgdGhlICJnZXROYW1lZEl0ZW0obmFtZSkiCisgKiAgICBtZXRob2QgaXMgZG9uZSB3aXRoIG5hbWU9InRpdGxlIi4gIFRoaXMgc2hvdWxkIHJlc3VsdAorICogICAgaW4gdGhlIHRpdGxlIEF0dHIgbm9kZSBiZWluZyByZXR1cm5lZC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwNzQ1Nzc1NDkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwNzQ1Nzc1NDk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3RjkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM0OTQ2N0Y5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yMzYiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yMzY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAzSnVuLzAwMTEuaHRtbCI+aHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAzSnVuLzAwMTEuaHRtbDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW0oZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RFbXBsb3llZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBkb21lc3RpY0F0dHI7CisgICAgICBTdHJpbmcgYXR0ck5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RFbXBsb3llZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdEVtcGxveWVlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGRvbWVzdGljQXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgidGl0bGUiKTsKKyAgICAgIGF0dHJOYW1lID0gZG9tZXN0aWNBdHRyLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHNBdXRvQ2FzZSgiYXR0cmlidXRlIiwgIm5vZGVOYW1lIiwgInRpdGxlIiwgYXR0ck5hbWUpOworICAgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXBpbnVzZWF0dHJpYnV0ZWVyci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXBpbnVzZWF0dHJpYnV0ZWVyci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2ZGMzZjgKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcGludXNlYXR0cmlidXRlZXJyLmphdmEKQEAgLTAsMCArMSwxMDkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBUaGUgInNldE5hbWVkSXRlbShhcmcpIiBtZXRob2QgcmFpc2VzIGEKKyAqIElOVVNFX0FUVFJJQlVURV9FUlIgRE9NRXhjZXB0aW9uIGlmICJhcmciIGlzIGFuCisgKiBBdHRyIHRoYXQgaXMgYWxyZWFkeSBpbiBhbiBhdHRyaWJ1dGUgb2YgYW5vdGhlciBFbGVtZW50LgorICogQ3JlYXRlIGEgTmFtZWROb2RlTWFwIG9iamVjdCBmcm9tIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZQorICogbGFzdCBjaGlsZCBvZiB0aGUgdGhpcmQgZW1wbG95ZWUgYW5kIGF0dGVtcHQgdG8gYWRkCisgKiBhbiBhdHRyaWJ1dGUgdGhhdCBpcyBhbHJlYWR5IGJlaW5nIHVzZWQgYnkgdGhlIGZpcnN0CisgKiBlbXBsb3llZS4gIFRoaXMgc2hvdWxkIHJhaXNlIHRoZSBkZXNpcmVkIGV4Y2VwdGlvbi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlVTRV9BVFRSSUJVVEVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDI1MTYzNzg4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDI1MTYzNzg4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0xMDI1MTYzNzg4JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTEwMjUxNjM3ODgnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlVTRV9BVFRSSUJVVEVfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25hbWVkbm9kZW1hcGludXNlYXR0cmlidXRlZXJyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19uYW1lZG5vZGVtYXBpbnVzZWF0dHJpYnV0ZWVycihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCBmaXJzdE5vZGU7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIGRvbWVzdGljQXR0cjsKKyAgICAgIEF0dHIgc2V0QXR0cjsKKyAgICAgIE5vZGUgc2V0Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICBmaXJzdE5vZGUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGRvbWVzdGljQXR0ciA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoInRpdGxlIik7CisgICAgICBkb21lc3RpY0F0dHIuc2V0VmFsdWUoIllcdTAzYjEiKTsgLy8gYW5kcm9pZC1jaGFuZ2VkOiBHUkVFSyBMT1dFUiBDQVNFIEFMUEhBCisgICAgICBzZXRBdHRyID0gZmlyc3ROb2RlLnNldEF0dHJpYnV0ZU5vZGUoZG9tZXN0aWNBdHRyKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0Tm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXROb2RlID0gYXR0cmlidXRlcy5zZXROYW1lZEl0ZW0oZG9tZXN0aWNBdHRyKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5VU0VfQVRUUklCVVRFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTlVTRV9BVFRSSUJVVEVfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcGludXNlYXR0cmlidXRlZXJyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19uYW1lZG5vZGVtYXBpbnVzZWF0dHJpYnV0ZWVyci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwbm90Zm91bmRlcnIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwbm90Zm91bmRlcnIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZDZiODZmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXBub3Rmb3VuZGVyci5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAicmVtb3ZlTmFtZWRJdGVtKG5hbWUpIiBtZXRob2QgcmFpc2VzIGEgCisgKiAgICBOT1RfRk9VTkRfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBub3QgYSBub2RlCisgKiAgICBuYW1lZCAic3Ryb25nIiBpbiB0aGUgbWFwLgorICogICAgCisgKiAgICBDcmVhdGUgYSBOYW1lZE5vZGVNYXAgb2JqZWN0IGZyb20gdGhlIGF0dHJpYnV0ZXMgb2YgdGhlCisgKiAgICBsYXN0IGNoaWxkIG9mIHRoZSB0aGlyZCBlbXBsb3llZSBhbmQgYXR0ZW1wdCB0byByZW1vdmUKKyAqICAgIHRoZSAibGFuZyIgYXR0cmlidXRlLiAgVGhlcmUgaXMgbm90IGEgbm9kZSBuYW1lZAorICogICAgImxhbmciIGluIHRoZSBsaXN0IGFuZCB0aGVyZWZvcmUgdGhlIGRlc2lyZWQgICAKKyAqICAgIGV4Y2VwdGlvbiBzaG91bGQgYmUgcmFpc2VkLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVVNFX0FUVFJJQlVURV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlVTRV9BVFRSSUJVVEVfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ1OEIxOTMiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ1OEIxOTM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELUQ1OEIxOTMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlVTRV9BVFRSSUJVVEVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtRDU4QjE5MycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVVNFX0FUVFJJQlVURV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0MyI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0MzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbmFtZWRub2RlbWFwbm90Zm91bmRlcnIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25hbWVkbm9kZW1hcG5vdGZvdW5kZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RFbXBsb3llZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgTm9kZSByZW1vdmVkTm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0RW1wbG95ZWUuZ2V0QXR0cmlidXRlcygpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZW1vdmVkTm9kZSA9IGF0dHJpYnV0ZXMucmVtb3ZlTmFtZWRJdGVtKCJsYW5nIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9UX0ZPVU5EX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXBub3Rmb3VuZGVyciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbmFtZWRub2RlbWFwbm90Zm91bmRlcnIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcG51bWJlcm9mbm9kZXMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwbnVtYmVyb2Zub2Rlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU0YTQ5NjUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcG51bWJlcm9mbm9kZXMuamF2YQpAQCAtMCwwICsxLDkyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgUmV0cmlldmUgdGhlIHNlY29uZCAicCIgZWxlbWVudCBhbmQgZXZhbHVhdGUgTm9kZS5hdHRyaWJ1dGVzLmxlbmd0aC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNkQwRkIxOUUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTZEMEZCMTlFPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTAiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTA8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25hbWVkbm9kZW1hcG51bWJlcm9mbm9kZXMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25hbWVkbm9kZW1hcG51bWJlcm9mbm9kZXMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBpbnQgbGVuZ3RoOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RFbXBsb3llZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdEVtcGxveWVlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGxlbmd0aCA9IChpbnQpIGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7CisgICAgICAKKyAgICAgIGlmICgoInRleHQvaHRtbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkgeworICAgICAgICAgIGFzc2VydEVxdWFscygiaHRtbExlbmd0aCIsIDIsIGxlbmd0aCk7CisgICAgICB9IGVsc2UgeworICAgICAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoIiwgMywgbGVuZ3RoKTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXBudW1iZXJvZm5vZGVzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19uYW1lZG5vZGVtYXBudW1iZXJvZm5vZGVzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW0uamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDJiN2E2MAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtLmphdmEKQEAgLTAsMCArMSw5NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZW1vdmVOYW1lZEl0ZW0obmFtZSkiIG1ldGhvZCByZW1vdmVzIGEgbm9kZSAKKyAqICAgIHNwZWNpZmllZCBieSBuYW1lLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIHRoaXJkIGVtcGxveWVlIGFuZCBjcmVhdGUgYSBOYW1lZE5vZGVNYXAgCisgKiAgICBvYmplY3Qgb2YgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGxhc3QgY2hpbGQuICBPbmNlIHRoZQorICogICAgbGlzdCBpcyBjcmVhdGVkIGludm9rZSB0aGUgInJlbW92ZU5hbWVkSXRlbShuYW1lKSIKKyAqICAgIG1ldGhvZCB3aXRoIG5hbWU9ImNsYXNzIi4gIFRoaXMgc2hvdWxkIHJlc3VsdAorICogICAgaW4gdGhlIHJlbW92YWwgb2YgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENThCMTkzIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENThCMTkzPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM0OTQ2N0Y5Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zNDk0NjdGOTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDJNYXIvMDAwMi5odG1sIj5odHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDJNYXIvMDAwMi5odG1sPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW0gZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBOb2RlIHRlc3RBZGRyZXNzOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIHN0cmVldEF0dHI7CisgICAgICBib29sZWFuIHNwZWNpZmllZDsKKyAgICAgIE5vZGUgcmVtb3ZlZE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdEFkZHJlc3MgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3RBZGRyZXNzLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHJlbW92ZWROb2RlID0gYXR0cmlidXRlcy5yZW1vdmVOYW1lZEl0ZW0oImNsYXNzIik7CisgICAgICBzdHJlZXRBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJjbGFzcyIpOworICAgICAgYXNzZXJ0TnVsbCgiaXNudWxsIiwgc3RyZWV0QXR0cik7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXByZXR1cm5hdHRybm9kZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXByZXR1cm5hdHRybm9kZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZkNDc5M2EKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHJldHVybmF0dHJub2RlLmphdmEKQEAgLTAsMCArMSw5NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgcCBlbGVtZW50IGFuZCBjcmVhdGUgYSBOYW1lZE5vZGVNYXAgCisgKiAgICBsaXN0aW5nIG9mIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBsYXN0IGNoaWxkLiAgT25jZSB0aGUKKyAqICAgIGxpc3QgaXMgY3JlYXRlZCBhbiBpbnZvY2F0aW9uIG9mIHRoZSAiZ2V0TmFtZWRJdGVtKG5hbWUpIgorICogICAgbWV0aG9kIGlzIGRvbmUgd2l0aCBuYW1lPSJjbGFzcyIuICBUaGlzIHNob3VsZCByZXN1bHQKKyAqICAgIGluIHRoZSBtZXRob2QgcmV0dXJuaW5nIGFuIEF0dHIgbm9kZS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwNzQ1Nzc1NDkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwNzQ1Nzc1NDk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMTEyMTE5NDAzIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMTEyMTE5NDAzPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yMzYiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yMzY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25hbWVkbm9kZW1hcHJldHVybmF0dHJub2RlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19uYW1lZG5vZGVtYXByZXR1cm5hdHRybm9kZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIHN0cmVldEF0dHI7CisgICAgICBTdHJpbmcgYXR0ck5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RFbXBsb3llZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdEVtcGxveWVlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHN0cmVldEF0dHIgPSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgiY2xhc3MiKTsKKyAgICAgIGFzc2VydEluc3RhbmNlT2YoInR5cGVBc3NlcnQiLCBBdHRyLmNsYXNzLCBzdHJlZXRBdHRyKTsKK2F0dHJOYW1lID0gc3RyZWV0QXR0ci5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImF0dHJpYnV0ZSIsICJub2RlTmFtZSIsICJjbGFzcyIsIGF0dHJOYW1lKTsKKyAgICAgICAgYXR0ck5hbWUgPSAoKEF0dHIpIC8qTm9kZSAqL3N0cmVldEF0dHIpLmdldE5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJhdHRyaWJ1dGUiLCAibmFtZSIsICJjbGFzcyIsIGF0dHJOYW1lKTsKKyAgICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXByZXR1cm5hdHRybm9kZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbmFtZWRub2RlbWFwcmV0dXJuYXR0cm5vZGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHJldHVybmZpcnN0aXRlbS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXByZXR1cm5maXJzdGl0ZW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMGZkNTVkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXByZXR1cm5maXJzdGl0ZW0uamF2YQpAQCAtMCwwICsxLDExNCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgIml0ZW0oaW5kZXgpIiBtZXRob2QgcmV0dXJucyB0aGUgaW5kZXh0aCBpdGVtIGluIAorICogICAgdGhlIG1hcCh0ZXN0IGZvciBmaXJzdCBpdGVtKS4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgImFjcm9ueW0iIGdldCB0aGUgTmFtZWROb2RlTWFwIG9mIHRoZSBhdHRyaWJ1dGVzLiBTaW5jZSB0aGUKKyAqICAgIERPTSBkb2VzIG5vdCBzcGVjaWZ5IGFuIG9yZGVyIG9mIHRoZXNlIG5vZGVzIHRoZSBjb250ZW50cworICogICAgb2YgdGhlIEZJUlNUIG5vZGUgY2FuIGNvbnRhaW4gZWl0aGVyICJ0aXRsZSIsICJjbGFzcyIgb3IgImRpciIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zNDk0NjdGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3Rjk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzNiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzNjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDNKdW4vMDAxMS5odG1sIj5odHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDNKdW4vMDAxMS5odG1sPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0xODQiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0xODQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25hbWVkbm9kZW1hcHJldHVybmZpcnN0aXRlbSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbmFtZWRub2RlbWFwcmV0dXJuZmlyc3RpdGVtKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RBZGRyZXNzOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIG5vZGVOYW1lOworICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb24gaHRtbEV4cGVjdGVkID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGh0bWxFeHBlY3RlZC5hZGQoInRpdGxlIik7CisgICAgICBodG1sRXhwZWN0ZWQuYWRkKCJjbGFzcyIpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbiBleHBlY3RlZCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZC5hZGQoInRpdGxlIik7CisgICAgICBleHBlY3RlZC5hZGQoImNsYXNzIik7CisgICAgICBleHBlY3RlZC5hZGQoImRpciIpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbiBhY3R1YWwgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdEFkZHJlc3MgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3RBZGRyZXNzLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDcwID0gMDsgaW5kZXhOMTAwNzAgPCBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOyBpbmRleE4xMDA3MCsrKSB7CisgICAgICAgICAgY2hpbGQgPSAoTm9kZSkgYXR0cmlidXRlcy5pdGVtKGluZGV4TjEwMDcwKTsKKyAgICBub2RlTmFtZSA9IGNoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICBhY3R1YWwuYWRkKG5vZGVOYW1lKTsKKyAgICAgICAgfQorICAgICAgCisgICAgICBpZiAoKCJ0ZXh0L2h0bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHNJZ25vcmVDYXNlKCJhdHRyTmFtZV9odG1sIiwgaHRtbEV4cGVjdGVkLCBhY3R1YWwpOworfSBlbHNlIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoImF0dHJOYW1lIiwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgICB9CisgICAgICAgIAorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwcmV0dXJuZmlyc3RpdGVtIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19uYW1lZG5vZGVtYXByZXR1cm5maXJzdGl0ZW0uY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHJldHVybmxhc3RpdGVtLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHJldHVybmxhc3RpdGVtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzJiNzgzYgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwcmV0dXJubGFzdGl0ZW0uamF2YQpAQCAtMCwwICsxLDExNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgIml0ZW0oaW5kZXgpIiBtZXRob2QgcmV0dXJucyB0aGUgaW5kZXh0aCBpdGVtIGluIAorICogICAgdGhlIG1hcCh0ZXN0IGZvciBsYXN0IGl0ZW0pLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIHNlY29uZCAiYWNyb255bSIgYW5kIGdldCB0aGUgYXR0cmlidXRlIG5hbWUuIFNpbmNlIHRoZQorICogICAgRE9NIGRvZXMgbm90IHNwZWNpZnkgYW4gb3JkZXIgb2YgdGhlc2Ugbm9kZXMgdGhlIGNvbnRlbnRzCisgKiAgICBvZiB0aGUgTEFTVCBub2RlIGNhbiBjb250YWluIGVpdGhlciAidGl0bGUiIG9yICJjbGFzcyIuCisgKiAgICBUaGUgdGVzdCBzaG91bGQgcmV0dXJuICJ0cnVlIiBpZiB0aGUgTEFTVCBub2RlIGlzIGVpdGhlcgorICogICAgb2YgdGhlc2UgdmFsdWVzLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3RjkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM0OTQ2N0Y5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yMzYiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yMzY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAzSnVuLzAwMTEuaHRtbCI+aHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAzSnVuLzAwMTEuaHRtbDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MTg0Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MTg0PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19uYW1lZG5vZGVtYXByZXR1cm5sYXN0aXRlbSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbmFtZWRub2RlbWFwcmV0dXJubGFzdGl0ZW0oZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIG5vZGVOYW1lOworICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb24gaHRtbEV4cGVjdGVkID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGh0bWxFeHBlY3RlZC5hZGQoInRpdGxlIik7CisgICAgICBodG1sRXhwZWN0ZWQuYWRkKCJjbGFzcyIpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbiBleHBlY3RlZCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZC5hZGQoInRpdGxlIik7CisgICAgICBleHBlY3RlZC5hZGQoImNsYXNzIik7CisgICAgICBleHBlY3RlZC5hZGQoImRpciIpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbiBhY3R1YWwgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdEVtcGxveWVlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0RW1wbG95ZWUuZ2V0QXR0cmlidXRlcygpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwNzAgPSAwOyBpbmRleE4xMDA3MCA8IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDcwKyspIHsKKyAgICAgICAgICBjaGlsZCA9IChOb2RlKSBhdHRyaWJ1dGVzLml0ZW0oaW5kZXhOMTAwNzApOworICAgIG5vZGVOYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFjdHVhbC5hZGQobm9kZU5hbWUpOworICAgICAgICB9CisgICAgICAKKyAgICAgIGlmICgoInRleHQvaHRtbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkgeworICAgICAgICAgIGFzc2VydEVxdWFsc0lnbm9yZUNhc2UoImF0dHJOYW1lX2h0bWwiLCBodG1sRXhwZWN0ZWQsIGFjdHVhbCk7Cit9IGVsc2UgeworICAgICAgICAgIGFzc2VydEVxdWFscygiYXR0ck5hbWUiLCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXByZXR1cm5sYXN0aXRlbSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbmFtZWRub2RlbWFwcmV0dXJubGFzdGl0ZW0uY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHJldHVybm51bGwuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwcmV0dXJubnVsbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBkNWFiM2IKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHJldHVybm51bGwuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0TmFtZWRJdGVtKG5hbWUpIiBtZXRob2QgcmV0dXJucyBudWxsIG9mIHRoZSAKKyAqICAgIHNwZWNpZmllZCBuYW1lIGRpZCBub3QgaWRlbnRpZnkgYW55IG5vZGUgaW4gdGhlIG1hcC4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGNyZWF0ZSBhIE5hbWVkTm9kZU1hcCAKKyAqICAgIGxpc3Rpbmcgb2YgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGxhc3QgY2hpbGQuICBPbmNlIHRoZQorICogICAgbGlzdCBpcyBjcmVhdGVkIGFuIGludm9jYXRpb24gb2YgdGhlICJnZXROYW1lZEl0ZW0obmFtZSkiCisgKiAgICBtZXRob2QgaXMgZG9uZSB3aXRoIG5hbWU9ImxhbmciLiAgVGhpcyBuYW1lIGRvZXMgbm90IAorICogICAgbWF0Y2ggYW55IG5hbWVzIGluIHRoZSBsaXN0IHRoZXJlZm9yZSB0aGUgbWV0aG9kIHNob3VsZAorICogICAgcmV0dXJuIG51bGwuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDc0NTc3NTQ5Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDc0NTc3NTQ5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDMiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbmFtZWRub2RlbWFwcmV0dXJubnVsbCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbmFtZWRub2RlbWFwcmV0dXJubnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIGRpc3RyaWN0Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdEVtcGxveWVlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0RW1wbG95ZWUuZ2V0QXR0cmlidXRlcygpOworICAgICAgZGlzdHJpY3ROb2RlID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJsYW5nIik7CisgICAgICBhc3NlcnROdWxsKCJsYW5nQXR0ck51bGwiLCBkaXN0cmljdE5vZGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXByZXR1cm5udWxsIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19uYW1lZG5vZGVtYXByZXR1cm5udWxsLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW0uamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjA5MDA5YQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtLmphdmEKQEAgLTAsMCArMSwxMDMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kICJwIiBlbGVtZW50IGFuZCBjcmVhdGUgYSBOYW1lZE5vZGVNYXAgCisgKiAgICBvYmplY3QgZnJvbSB0aGUgYXR0cmlidXRlcyBvZiB0aGUgbGFzdCBjaGlsZCBieQorICogICAgaW52b2tpbmcgdGhlICJnZXRBdHRyaWJ1dGVzKCkiIG1ldGhvZC4gIE9uY2UgdGhlCisgKiAgICBsaXN0IGlzIGNyZWF0ZWQgYW4gaW52b2NhdGlvbiBvZiB0aGUgInNldE5hbWVkSXRlbShhcmcpIgorICogICAgbWV0aG9kIGlzIGRvbmUgd2l0aCBhcmc9bmV3QXR0ciwgd2hlcmUgbmV3QXR0ciBpcyBhCisgKiAgICBuZXcgQXR0ciBOb2RlIHByZXZpb3VzbHkgY3JlYXRlZC4gIFRoZSAic2V0TmFtZWRJdGVtKGFyZykiCisgKiAgICBtZXRob2Qgc2hvdWxkIGFkZCB0aGVuIG5ldyBub2RlIHRvIHRoZSBOYW1lZE5vZGVJdGVtIAorICogICAgb2JqZWN0IGJ5IHVzaW5nIGl0cyAibm9kZU5hbWUiIGF0dHJpYnV0ZSgibGFuZycpLgorICogICAgVGhpcyBub2RlIGlzIHRoZW4gcmV0cmlldmVkIHVzaW5nIHRoZSAiZ2V0TmFtZWRJdGVtKG5hbWUpIgorICogICAgbWV0aG9kLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTAyNTE2Mzc4OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTAyNTE2Mzc4ODwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zNDk0NjdGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3Rjk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzNiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzNjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDNKdW4vMDAxMS5odG1sIj5odHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDNKdW4vMDAxMS5odG1sPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDMiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIE5vZGUgdGVzdEFkZHJlc3M7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgZGlzdHJpY3ROb2RlOworICAgICAgU3RyaW5nIGF0dHJOYW1lOworICAgICAgTm9kZSBzZXROb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoImxhbmciKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0QWRkcmVzcy5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBzZXROb2RlID0gYXR0cmlidXRlcy5zZXROYW1lZEl0ZW0obmV3QXR0cmlidXRlKTsKKyAgICAgIGRpc3RyaWN0Tm9kZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgibGFuZyIpOworICAgICAgYXR0ck5hbWUgPSBkaXN0cmljdE5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJhdHRyaWJ1dGUiLCAibm9kZU5hbWUiLCAibGFuZyIsIGF0dHJOYW1lKTsKKyAgICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW0iOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtcmV0dXJudmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtcmV0dXJudmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOWQ3OTZmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1yZXR1cm52YWx1ZS5qYXZhCkBAIC0wLDAgKzEsMTA0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZSAic2V0TmFtZWRJdGVtKGFyZykiIG1ldGhvZCByZXBsYWNlcyBhbiBhbHJlYWR5IAorICogICAgZXhpc3Rpbmcgbm9kZSB3aXRoIHRoZSBzYW1lIG5hbWUgdGhlbiB0aGUgYWxyZWFkeSAKKyAqICAgIGV4aXN0aW5nIG5vZGUgaXMgcmV0dXJuZWQuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSB0aGlyZCBlbXBsb3llZSBhbmQgY3JlYXRlIGEgTmFtZWROb2RlTWFwIAorICogICAgb2JqZWN0IGZyb20gdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGxhc3QgY2hpbGQgYnkKKyAqICAgIGludm9raW5nIHRoZSAiZ2V0QXR0cmlidXRlcygpIiBtZXRob2QuICBPbmNlIHRoZQorICogICAgbGlzdCBpcyBjcmVhdGVkIGFuIGludm9jYXRpb24gb2YgdGhlICJzZXROYW1lZEl0ZW0oYXJnKSIKKyAqICAgIG1ldGhvZCBpcyBkb25lIHdpdGggYXJnPW5ld0F0dHIsIHdoZXJlIG5ld0F0dHIgaXMgYQorICogICAgbmV3IEF0dHIgTm9kZSBwcmV2aW91c2x5IGNyZWF0ZWQgYW5kIHdob3NlIG5vZGUgbmFtZQorICogICAgYWxyZWFkeSBleGlzdHMgaW4gdGhlIG1hcC4gIFRoZSAic2V0TmFtZWRJdGVtKGFyZykiCisgKiAgICBtZXRob2Qgc2hvdWxkIHJlcGxhY2UgdGhlIGFscmVhZHkgZXhpc3Rpbmcgbm9kZSB3aXRoCisgKiAgICB0aGUgbmV3IG9uZSBhbmQgcmV0dXJuIHRoZSBleGlzdGluZyBub2RlLiAgIAorICogICAgVGhpcyB0ZXN0IHVzZXMgdGhlICJjcmVhdGVBdHRyaWJ1dGUobmFtZSkiIG1ldGhvZCBmcm9tCisgKiAgICB0aGUgZG9jdW1lbnQgaW50ZXJmYWNlLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTAyNTE2Mzc4OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTAyNTE2Mzc4ODwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zNDk0NjdGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3Rjk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXJldHVybnZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1yZXR1cm52YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBOb2RlIHRlc3RBZGRyZXNzOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIG5ld05vZGU7CisgICAgICBTdHJpbmcgYXR0clZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoImNsYXNzIik7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdEFkZHJlc3MuZ2V0QXR0cmlidXRlcygpOworICAgICAgbmV3Tm9kZSA9IGF0dHJpYnV0ZXMuc2V0TmFtZWRJdGVtKG5ld0F0dHJpYnV0ZSk7CisgICAgICBhc3NlcnROb3ROdWxsKCJwcmV2aW91c0F0dHJOb3ROdWxsIiwgbmV3Tm9kZSk7CisgICAgICBhdHRyVmFsdWUgPSBuZXdOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJwcmV2aW91c0F0dHJWYWx1ZSIsICJObyIsIGF0dHJWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXJldHVybnZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1yZXR1cm52YWx1ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtdGhhdGV4aXN0cy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW10aGF0ZXhpc3RzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTBmODhlNAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtdGhhdGV4aXN0cy5qYXZhCkBAIC0wLDAgKzEsMTA2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBJZiB0aGUgbm9kZSB0byBiZSBhZGRlZCBieSB0aGUgInNldE5hbWVkSXRlbShhcmcpIiBtZXRob2QgCisgKiAgICBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgTmFtZWROb2RlTWFwLCBpdCBpcyByZXBsYWNlZCBieQorICogICAgdGhlIG5ldyBvbmUuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGNyZWF0ZSBhIE5hbWVkTm9kZU1hcCAKKyAqICAgIG9iamVjdCBmcm9tIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBsYXN0IGNoaWxkIGJ5CisgKiAgICBpbnZva2luZyB0aGUgImdldEF0dHJpYnV0ZXMoKSIgbWV0aG9kLiAgT25jZSB0aGUKKyAqICAgIGxpc3QgaXMgY3JlYXRlZCBhbiBpbnZvY2F0aW9uIG9mIHRoZSAic2V0TmFtZWRJdGVtKGFyZykiCisgKiAgICBtZXRob2QgaXMgZG9uZSB3aXRoIGFyZz1uZXdBdHRyLCB3aGVyZSBuZXdBdHRyIGlzIGEKKyAqICAgIG5ldyBBdHRyIE5vZGUgcHJldmlvdXNseSBjcmVhdGVkIGFuZCB3aG9zZSBub2RlIG5hbWUKKyAqICAgIGFscmVhZHkgZXhpc3RzIGluIHRoZSBtYXAuICBUaGUgInNldE5hbWVkSXRlbShhcmcpIgorICogICAgbWV0aG9kIHNob3VsZCByZXBsYWNlIHRoZSBhbHJlYWR5IGV4aXN0aW5nIG5vZGUgd2l0aAorICogICAgdGhlIG5ldyBvbmUuICAgCisgKiAgICBUaGlzIG5vZGUgaXMgdGhlbiByZXRyaWV2ZWQgdXNpbmcgdGhlICJnZXROYW1lZEl0ZW0obmFtZSkiCisgKiAgICBtZXRob2QuICBUaGlzIHRlc3QgdXNlcyB0aGUgImNyZWF0ZUF0dHJpYnV0ZShuYW1lKSIKKyAqICAgIG1ldGhvZCBmcm9tIHRoZSBkb2N1bWVudCBpbnRlcmZhY2UKKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwMjUxNjM3ODgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwMjUxNjM3ODg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3RjkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM0OTQ2N0Y5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW10aGF0ZXhpc3RzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW10aGF0ZXhpc3RzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIE5vZGUgdGVzdEFkZHJlc3M7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgZGlzdHJpY3ROb2RlOworICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKyAgICAgIE5vZGUgc2V0Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0QWRkcmVzcyA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBuZXdBdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJjbGFzcyIpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3RBZGRyZXNzLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHNldE5vZGUgPSBhdHRyaWJ1dGVzLnNldE5hbWVkSXRlbShuZXdBdHRyaWJ1dGUpOworICAgICAgZGlzdHJpY3ROb2RlID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJjbGFzcyIpOworICAgICAgYXR0clZhbHVlID0gZGlzdHJpY3ROb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lZG5vZGVtYXBTZXROYW1lZEl0ZW1UaGF0RXhpc3RzQXNzZXJ0IiwgIiIsIGF0dHJWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXRoYXRleGlzdHMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXRoYXRleGlzdHMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXdpdGhuZXd2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW13aXRobmV3dmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOGYyNWZkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW13aXRobmV3dmFsdWUuamF2YQpAQCAtMCwwICsxLDk5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZSAic2V0TmFtZWRJdGVtKGFyZykiIG1ldGhvZCBkb2VzIG5vdCByZXBsYWNlIGFuIAorICogICAgZXhpc3Rpbmcgbm9kZSB3aXRoIHRoZSBzYW1lIG5hbWUgdGhlbiBpdCByZXR1cm5zIG51bGwuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgdGhpcmQgZW1wbG95ZWUgYW5kIGNyZWF0ZSBhIE5hbWVkTm9kZU1hcCAKKyAqICAgIG9iamVjdCBmcm9tIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBsYXN0IGNoaWxkLgorICogICAgT25jZSB0aGUgbGlzdCBpcyBjcmVhdGVkIHRoZSAic2V0TmFtZWRJdGVtKGFyZykiIG1ldGhvZAorICogICAgaXMgaW52b2tlZCB3aXRoIGFyZz1uZXdBdHRyLCB3aGVyZSBuZXdBdHRyIGlzIGEKKyAqICAgIG5ld2x5IGNyZWF0ZWQgQXR0ciBOb2RlIGFuZCB3aG9zZSBub2RlIG5hbWUKKyAqICAgIGFscmVhZHkgZXhpc3RzIGluIHRoZSBtYXAuICBUaGUgInNldE5hbWVkSXRlbShhcmcpIgorICogICAgbWV0aG9kIHNob3VsZCBhZGQgdGhlIG5ldyBub2RlIGFuZCByZXR1cm4gbnVsbC4KKyAqICAgIFRoaXMgdGVzdCB1c2VzIHRoZSAiY3JlYXRlQXR0cmlidXRlKG5hbWUpIiBtZXRob2QgZnJvbQorICogICAgdGhlIGRvY3VtZW50IGludGVyZmFjZS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwMjUxNjM3ODgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwMjUxNjM3ODg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3RjkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM0OTQ2N0Y5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDMiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXdpdGhuZXd2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtd2l0aG5ld3ZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIE5vZGUgdGVzdEFkZHJlc3M7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIE5vZGUgbmV3Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0QWRkcmVzcyA9IGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBuZXdBdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJsYW5nIik7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdEFkZHJlc3MuZ2V0QXR0cmlidXRlcygpOworICAgICAgbmV3Tm9kZSA9IGF0dHJpYnV0ZXMuc2V0TmFtZWRJdGVtKG5ld0F0dHJpYnV0ZSk7CisgICAgICBhc3NlcnROdWxsKCJwcmV2VmFsdWVOdWxsIiwgbmV3Tm9kZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXdpdGhuZXd2YWx1ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtd2l0aG5ld3ZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXB3cm9uZ2RvY3VtZW50ZXJyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHdyb25nZG9jdW1lbnRlcnIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYzQ2NDlkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19uYW1lZG5vZGVtYXB3cm9uZ2RvY3VtZW50ZXJyLmphdmEKQEAgLTAsMCArMSwxMTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXROYW1lZEl0ZW0oYXJnKSIgbWV0aG9kIHJhaXNlcyBhIAorICogICAgV1JPTkdfRE9DVU1FTlRfRVJSIERPTUV4Y2VwdGlvbiBpZiAiYXJnIiB3YXMgY3JlYXRlZAorICogICAgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudCB0aGFuIHRoZSBvbmUgdGhhdCBjcmVhdGVkCisgKiAgICB0aGUgTmFtZWROb2RlTWFwLiAKKyAqICAgIAorICogICAgQ3JlYXRlIGEgTmFtZWROb2RlTWFwIG9iamVjdCBmcm9tIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZQorICogICAgbGFzdCBjaGlsZCBvZiB0aGUgdGhpcmQgZW1wbG95ZWUgYW5kIGF0dGVtcHQgdG8gYWRkCisgKiAgICBhbm90aGVyIEF0dHIgbm9kZSB0byBpdCB0aGF0IHdhcyBjcmVhdGVkIGZyb20gYSAKKyAqICAgIGRpZmZlcmVudCBET00gZG9jdW1lbnQuICBUaGlzIHNob3VsZCByYWlzZSB0aGUgZGVzaXJlZAorICogICAgZXhjZXB0aW9uLiAgVGhpcyBtZXRob2QgdXNlcyB0aGUgImNyZWF0ZUF0dHJpYnV0ZShuYW1lKSIKKyAqICAgIG1ldGhvZCBmcm9tIHRoZSBEb2N1bWVudCBpbnRlcmZhY2UuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nV1JPTkdfRE9DVU1FTlRfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nV1JPTkdfRE9DVU1FTlRfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwMjUxNjM3ODgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwMjUxNjM3ODg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTEwMjUxNjM3ODgnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdXUk9OR19ET0NVTUVOVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0xMDI1MTYzNzg4JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nV1JPTkdfRE9DVU1FTlRfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25hbWVkbm9kZW1hcHdyb25nZG9jdW1lbnRlcnIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25hbWVkbm9kZW1hcHdyb25nZG9jdW1lbnRlcnIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2MxOworICAgICAgRG9jdW1lbnQgZG9jMjsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0QWRkcmVzczsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgTm9kZSBuZXdBdHRyaWJ1dGU7CisgICAgICBTdHJpbmcgc3Ryb25nOworICAgICAgTm9kZSBzZXROb2RlOworICAgICAgZG9jMSA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGRvYzIgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYzEuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9IGRvYzIuY3JlYXRlQXR0cmlidXRlKCJuZXdBdHRyaWJ1dGUiKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0QWRkcmVzcy5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldE5vZGUgPSBhdHRyaWJ1dGVzLnNldE5hbWVkSXRlbShuZXdBdHRyaWJ1dGUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfV1JPTkdfRE9DVU1FTlRfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25hbWVkbm9kZW1hcHdyb25nZG9jdW1lbnRlcnIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25hbWVkbm9kZW1hcHdyb25nZG9jdW1lbnRlcnIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVhcHBlbmRjaGlsZC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MjFmODcxCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGQuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgInAiIGFuZCBhcHBlbmQgYSAiYnIiIEVsZW1lbnQKKyAqICAgICBub2RlIHRvIHRoZSBsaXN0IG9mIGNoaWxkcmVuLiAgIFRoZSBsYXN0IG5vZGUgaW4gdGhlIGxpc3QKKyAqICAgICBpcyB0aGVuIHJldHJpZXZlZCBhbmQgaXRzIE5vZGVOYW1lIGV4YW1pbmVkLiAgIFRoZQorICogICAgICJnZXROb2RlTmFtZSgpIiBtZXRob2Qgc2hvdWxkIHJldHVybiAiYnIiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDciPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVhcHBlbmRjaGlsZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWFwcGVuZGNoaWxkKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgY3JlYXRlZE5vZGU7CisgICAgICBOb2RlIGxjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBOb2RlIGFwcGVuZGVkQ2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTGlzdCA9IGVtcGxveWVlTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBjcmVhdGVkTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50KCJiciIpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGVtcGxveWVlTm9kZS5hcHBlbmRDaGlsZChjcmVhdGVkTm9kZSk7CisgICAgICBsY2hpbGQgPSBlbXBsb3llZU5vZGUuZ2V0TGFzdENoaWxkKCk7CisgICAgICBjaGlsZE5hbWUgPSBsY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJlbGVtZW50IiwgIm5vZGVOYW1lIiwgImJyIiwgY2hpbGROYW1lKTsKKyAgICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVhcHBlbmRjaGlsZC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWFwcGVuZGNoaWxkY2hpbGRleGlzdHMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWFwcGVuZGNoaWxkY2hpbGRleGlzdHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mODM3OTcxCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGRjaGlsZGV4aXN0cy5qYXZhCkBAIC0wLDAgKzEsMTI1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZSAibmV3Q2hpbGQiIGlzIGFscmVhZHkgaW4gdGhlIHRyZWUsIGl0IGlzIGZpcnN0CisgKiAgICAgcmVtb3ZlZCBiZWZvcmUgdGhlIG5ldyBvbmUgaXMgYXBwZW5kZWQuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlICJlbSIgc2Vjb25kIGVtcGxveWVlIGFuZCAgIAorICogICAgIGFwcGVuZCB0aGUgZmlyc3QgY2hpbGQgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdC4gICBBZnRlcgorICogICAgIHRoZSAiYXBwZW5kQ2hpbGQobmV3Q2hpbGQpIiBtZXRob2QgaXMgaW52b2tlZCB0aGUgZmlyc3QgCisgKiAgICAgY2hpbGQgc2hvdWxkIGJlIHRoZSBvbmUgdGhhdCB3YXMgc2Vjb25kIGFuZCB0aGUgbGFzdAorICogICAgIGNoaWxkIHNob3VsZCBiZSB0aGUgb25lIHRoYXQgd2FzIGZpcnN0LgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDYiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVhcHBlbmRjaGlsZGNoaWxkZXhpc3RzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlYXBwZW5kY2hpbGRjaGlsZGV4aXN0cyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgTm9kZSBjaGlsZE5vZGU7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZSBtZW1iZXJOb2RlOworICAgICAgU3RyaW5nIG1lbWJlck5hbWU7CisgICAgICBqYXZhLnV0aWwuTGlzdCByZWZyZXNoZWRBY3R1YWwgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuTGlzdCBhY3R1YWwgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBqYXZhLnV0aWwuTGlzdCBleHBlY3RlZCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZC5hZGQoInN0cm9uZyIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJjb2RlIik7CisgICAgICBleHBlY3RlZC5hZGQoInN1cCIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJ2YXIiKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgiYWNyb255bSIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJlbSIpOworICAgICAgCisgICAgICBOb2RlIGFwcGVuZGVkQ2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgY2hpbGROb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTGlzdCA9ICgoRWxlbWVudCkgLypOb2RlICovY2hpbGROb2RlKS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpOworICAgICAgbmV3Q2hpbGQgPSBjaGlsZExpc3QuaXRlbSgwKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBjaGlsZE5vZGUuYXBwZW5kQ2hpbGQobmV3Q2hpbGQpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwODUgPSAwOyBpbmRleE4xMDA4NSA8IGNoaWxkTGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwODUrKykgeworICAgICAgICAgIG1lbWJlck5vZGUgPSAoTm9kZSkgY2hpbGRMaXN0Lml0ZW0oaW5kZXhOMTAwODUpOworICAgIG1lbWJlck5hbWUgPSBtZW1iZXJOb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBhY3R1YWwuYWRkKG1lbWJlck5hbWUpOworICAgICAgICB9CisgICAgICBhc3NlcnRFcXVhbHNBdXRvQ2FzZSgiZWxlbWVudCIsICJsaXZlQnlUYWdOYW1lIiwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgICAgIGNoaWxkTGlzdCA9IGNoaWxkTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA5QyA9IDA7IGluZGV4TjEwMDlDIDwgY2hpbGRMaXN0LmdldExlbmd0aCgpOyBpbmRleE4xMDA5QysrKSB7CisgICAgICAgICAgbWVtYmVyTm9kZSA9IChOb2RlKSBjaGlsZExpc3QuaXRlbShpbmRleE4xMDA5Qyk7CisgICAgbm9kZVR5cGUgPSAoaW50KSBtZW1iZXJOb2RlLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoMSwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgbWVtYmVyTmFtZSA9IG1lbWJlck5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIHJlZnJlc2hlZEFjdHVhbC5hZGQobWVtYmVyTmFtZSk7CisgICAgICB9CisgICAgICB9CisgICAgICBhc3NlcnRFcXVhbHNBdXRvQ2FzZSgiZWxlbWVudCIsICJyZWZyZXNoZWRDaGlsZE5vZGVzIiwgZXhwZWN0ZWQsIHJlZnJlc2hlZEFjdHVhbCk7CisgICAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWFwcGVuZGNoaWxkY2hpbGRleGlzdHMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVhcHBlbmRjaGlsZGNoaWxkZXhpc3RzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGRkb2NmcmFnbWVudC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGRkb2NmcmFnbWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5MGMxZjAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVhcHBlbmRjaGlsZGRvY2ZyYWdtZW50LmphdmEKQEAgLTAsMCArMSwxMjUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZSAibmV3Q2hpbGQiIGlzIGEgRG9jdW1lbnRGcmFnbWVudCBvYmplY3QgdGhlbgorICogICAgIGFsbCBpdHMgY29udGVudCBpcyBhZGRlZCB0byB0aGUgY2hpbGQgbGlzdCBvZiB0aGlzIG5vZGUuCisgKiAgICAgCisgKiAgICAgQ3JlYXRlIGFuZCBwb3B1bGF0ZSBhIG5ldyBEb2N1bWVudEZyYWdtZW50IG9iamVjdCBhbmQKKyAqICAgICBhcHBlbmQgaXQgdG8gdGhlIHNlY29uZCBlbXBsb3llZS4gICBBZnRlciB0aGUgCisgKiAgICAgImFwcGVuZENoaWxkKG5ld0NoaWxkKSIgbWV0aG9kIGlzIGludm9rZWQgcmV0cmlldmUgdGhlCisgKiAgICAgbmV3IG5vZGVzIGF0IHRoZSBlbmQgb2YgdGhlIGxpc3QsIHRoZXkgc2hvdWxkIGJlIHRoZQorICogICAgIHR3byBFbGVtZW50IG5vZGVzIGZyb20gdGhlIERvY3VtZW50RnJhZ21lbnQuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlYXBwZW5kY2hpbGRkb2NmcmFnbWVudCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWFwcGVuZGNoaWxkZG9jZnJhZ21lbnQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgRG9jdW1lbnRGcmFnbWVudCBuZXdkb2NGcmFnbWVudDsKKyAgICAgIE5vZGUgbmV3Q2hpbGQxOworICAgICAgTm9kZSBuZXdDaGlsZDI7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIGphdmEudXRpbC5MaXN0IHJlc3VsdCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICAKKyAgICAgIE5vZGUgYXBwZW5kZWRDaGlsZDsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIGphdmEudXRpbC5MaXN0IGV4cGVjdGVkID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgiZW0iKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgic3Ryb25nIik7CisgICAgICBleHBlY3RlZC5hZGQoImNvZGUiKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgic3VwIik7CisgICAgICBleHBlY3RlZC5hZGQoInZhciIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJhY3JvbnltIik7CisgICAgICBleHBlY3RlZC5hZGQoImJyIik7CisgICAgICBleHBlY3RlZC5hZGQoImIiKTsKKyAgICAgIAorICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjaGlsZExpc3QgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgbmV3ZG9jRnJhZ21lbnQgPSBkb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOworICAgICAgbmV3Q2hpbGQxID0gZG9jLmNyZWF0ZUVsZW1lbnQoImJyIik7CisgICAgICBuZXdDaGlsZDIgPSBkb2MuY3JlYXRlRWxlbWVudCgiYiIpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IG5ld2RvY0ZyYWdtZW50LmFwcGVuZENoaWxkKG5ld0NoaWxkMSk7CisgICAgICBhcHBlbmRlZENoaWxkID0gbmV3ZG9jRnJhZ21lbnQuYXBwZW5kQ2hpbGQobmV3Q2hpbGQyKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBlbXBsb3llZU5vZGUuYXBwZW5kQ2hpbGQobmV3ZG9jRnJhZ21lbnQpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwQTIgPSAwOyBpbmRleE4xMDBBMiA8IGNoaWxkTGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwQTIrKykgeworICAgICAgICAgIGNoaWxkID0gKE5vZGUpIGNoaWxkTGlzdC5pdGVtKGluZGV4TjEwMEEyKTsKKyAgICBub2RlVHlwZSA9IChpbnQpIGNoaWxkLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoMSwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIHJlc3VsdC5hZGQoY2hpbGROYW1lKTsKKyAgICAgIH0KKyAgICAgIH0KKyAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJlbGVtZW50IiwgIm5vZGVOYW1lcyIsIGV4cGVjdGVkLCByZXN1bHQpOworICAgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVhcHBlbmRjaGlsZGRvY2ZyYWdtZW50IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlYXBwZW5kY2hpbGRkb2NmcmFnbWVudC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWFwcGVuZGNoaWxkZ2V0bm9kZW5hbWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWFwcGVuZGNoaWxkZ2V0bm9kZW5hbWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NmNkM2EzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGRnZXRub2RlbmFtZS5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJhcHBlbmRDaGlsZChuZXdDaGlsZCkiIG1ldGhvZCByZXR1cm5zIHRoZSBub2RlCisgKiAgICAgYWRkZWQuCisgKiAgICAgCisgKiAgICAgQXBwZW5kIGEgbmV3bHkgY3JlYXRlZCBub2RlIHRvIHRoZSBjaGlsZCBsaXN0IG9mIHRoZSAKKyAqICAgICBzZWNvbmQgZW1wbG95ZWUgYW5kIGNoZWNrIHRoZSBOb2RlTmFtZSByZXR1cm5lZC4gICBUaGUKKyAqICAgICAiZ2V0Tm9kZU5hbWUoKSIgbWV0aG9kIHNob3VsZCByZXR1cm4gImJyIi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDciPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVhcHBlbmRjaGlsZGdldG5vZGVuYW1lIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlYXBwZW5kY2hpbGRnZXRub2RlbmFtZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZSBhcHBlbmROb2RlOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgY2hpbGRMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIG5ld0NoaWxkID0gZG9jLmNyZWF0ZUVsZW1lbnQoImJyIik7CisgICAgICBhcHBlbmROb2RlID0gZW1wbG95ZWVOb2RlLmFwcGVuZENoaWxkKG5ld0NoaWxkKTsKKyAgICAgIGNoaWxkTmFtZSA9IGFwcGVuZE5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJlbGVtZW50IiwgIm5vZGVOYW1lIiwgImJyIiwgY2hpbGROYW1lKTsKKyAgICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGRnZXRub2RlbmFtZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWFwcGVuZGNoaWxkZ2V0bm9kZW5hbWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVhcHBlbmRjaGlsZGludmFsaWRub2RldHlwZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGRpbnZhbGlkbm9kZXR5cGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMmM4MDRmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGRpbnZhbGlkbm9kZXR5cGUuamF2YQpAQCAtMCwwICsxLDEwMiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJhcHBlbmRDaGlsZChuZXdDaGlsZCkiIG1ldGhvZCByYWlzZXMgYSAKKyAqICAgICBISUVSQVJDSFlfUkVRVUVTVF9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoaXMgbm9kZSBpcyBvZgorICogICAgIGEgdHlwZSB0aGF0IGRvZXMgbm90IGFsbG93IGNoaWxkcmVuIG9mIHRoZSB0eXBlICJuZXdDaGlsZCIKKyAqICAgICB0byBiZSBpbnNlcnRlZC4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgcm9vdCBub2RlIGFuZCBhdHRlbXB0IHRvIGFwcGVuZCBhIG5ld2x5CisgKiAgICAgY3JlYXRlZCBBdHRyIG5vZGUuICAgQW4gRWxlbWVudCBub2RlIGNhbm5vdCBoYXZlIGNoaWxkcmVuCisgKiAgICAgb2YgdGhlICJBdHRyIiB0eXBlLCB0aGVyZWZvcmUgdGhlIGRlc2lyZWQgZXhjZXB0aW9uCisgKiAgICAgc2hvdWxkIGJlIHJhaXNlZC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0xODRFNzEwNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTE4NEU3MTA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSElFUkFSQ0hZX1JFUVVFU1RfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlYXBwZW5kY2hpbGRpbnZhbGlkbm9kZXR5cGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVhcHBlbmRjaGlsZGludmFsaWRub2RldHlwZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgcm9vdE5vZGU7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZSBhcHBlbmRlZENoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgcm9vdE5vZGUgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBuZXdDaGlsZCA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoIm5ld0F0dHJpYnV0ZSIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcHBlbmRlZENoaWxkID0gcm9vdE5vZGUuYXBwZW5kQ2hpbGQobmV3Q2hpbGQpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5ISUVSQVJDSFlfUkVRVUVTVF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSElFUkFSQ0hZX1JFUVVFU1RfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVhcHBlbmRjaGlsZGludmFsaWRub2RldHlwZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWFwcGVuZGNoaWxkaW52YWxpZG5vZGV0eXBlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGRuZXdjaGlsZGRpZmZkb2N1bWVudC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGRuZXdjaGlsZGRpZmZkb2N1bWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNiOWMzNjMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVhcHBlbmRjaGlsZG5ld2NoaWxkZGlmZmRvY3VtZW50LmphdmEKQEAgLTAsMCArMSwxMDcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJhcHBlbmRDaGlsZChuZXdDaGlsZCkiIG1ldGhvZCByYWlzZXMgYSAKKyAqICAgICBXUk9OR19ET0NVTUVOVF9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSAibmV3Q2hpbGQiIHdhcworICogICAgIGNyZWF0ZWQgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudCB0aGFuIHRoZSBvbmUgdGhhdCAKKyAqICAgICBjcmVhdGVkIHRoaXMgbm9kZS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBhdHRlbXB0IHRvIGFwcGVuZCAgICAKKyAqICAgICBhIG5vZGUgY3JlYXRlZCBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50LiAgIEFuIGF0dGVtcHQgCisgKiAgICAgdG8gbWFrZSBzdWNoIGEgcmVwbGFjZW1lbnQgc2hvdWxkIHJhaXNlIHRoZSBkZXNpcmVkIAorICogICAgIGV4Y2VwdGlvbi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT1RfRk9VTkRfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9UX0ZPVU5EX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTE4NEU3MTA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9UX0ZPVU5EX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTE4NEU3MTA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9UX0ZPVU5EX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NyI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWFwcGVuZGNoaWxkbmV3Y2hpbGRkaWZmZG9jdW1lbnQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVhcHBlbmRjaGlsZG5ld2NoaWxkZGlmZmRvY3VtZW50KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzE7CisgICAgICBEb2N1bWVudCBkb2MyOworICAgICAgTm9kZSBuZXdDaGlsZDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbGVtZW50Tm9kZTsKKyAgICAgIE5vZGUgYXBwZW5kZWRDaGlsZDsKKyAgICAgIGRvYzEgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZG9jMiA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld0NoaWxkID0gZG9jMS5jcmVhdGVFbGVtZW50KCJiciIpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MyLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwIik7CisgICAgICBlbGVtZW50Tm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFwcGVuZGVkQ2hpbGQgPSBlbGVtZW50Tm9kZS5hcHBlbmRDaGlsZChuZXdDaGlsZCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19XUk9OR19ET0NVTUVOVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWFwcGVuZGNoaWxkbmV3Y2hpbGRkaWZmZG9jdW1lbnQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVhcHBlbmRjaGlsZG5ld2NoaWxkZGlmZmRvY3VtZW50LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGRub2RlYW5jZXN0b3IuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWFwcGVuZGNoaWxkbm9kZWFuY2VzdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjg4NGJmOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWFwcGVuZGNoaWxkbm9kZWFuY2VzdG9yLmphdmEKQEAgLTAsMCArMSwxMDQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiYXBwZW5kQ2hpbGQobmV3Q2hpbGQpIiBtZXRob2QgcmFpc2VzIGEgCisgKiAgICAgSElFUkFSQ0hZX1JFUVVFU1RfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgbm9kZSB0byAKKyAqICAgICBhcHBlbmQgaXMgb25lIG9mIHRoaXMgbm9kZSdzIGFuY2VzdG9ycy4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBhdHRlbXB0IHRvIGFwcGVuZCAKKyAqICAgICBhbiBhbmNlc3RvciBub2RlKHJvb3Qgbm9kZSkgdG8gaXQuCisgKiAgICAgQW4gYXR0ZW1wdCB0byBtYWtlIHN1Y2ggYW4gYWRkaXRpb24gc2hvdWxkIHJhaXNlIHRoZSAKKyAqICAgICBkZXNpcmVkIGV4Y2VwdGlvbi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0xODRFNzEwNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTE4NEU3MTA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSElFUkFSQ0hZX1JFUVVFU1RfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWFwcGVuZGNoaWxkbm9kZWFuY2VzdG9yIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlYXBwZW5kY2hpbGRub2RlYW5jZXN0b3IoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgb2xkQ2hpbGQ7CisgICAgICBOb2RlIGFwcGVuZGVkQ2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdDaGlsZCA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcHBlbmRlZENoaWxkID0gZW1wbG95ZWVOb2RlLmFwcGVuZENoaWxkKG5ld0NoaWxkKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0hJRVJBUkNIWV9SRVFVRVNUX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlYXBwZW5kY2hpbGRub2RlYW5jZXN0b3IiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVhcHBlbmRjaGlsZG5vZGVhbmNlc3Rvci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWF0dHJpYnV0ZW5vZGVhdHRyaWJ1dGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWF0dHJpYnV0ZW5vZGVhdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMjQzMGI3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXR0cmlidXRlbm9kZWF0dHJpYnV0ZS5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogVGhlICJnZXRBdHRyaWJ1dGVzKCkiIG1ldGhvZCBpbnZva2VkIG9uIGFuIEF0dHJpYnV0ZQorICogTm9kZSByZXR1cm5zIG51bGwuCisgKiBSZXRyaWV2ZSB0aGUgZmlyc3QgYXR0cmlidXRlIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiBmaXJzdCBlbXBsb3llZSBhbmQgaW52b2tlIHRoZSAiZ2V0QXR0cmlidXRlcygpIiBtZXRob2QKKyAqIG9uIHRoZSBBdHRyaWJ1dGUgTm9kZS4gIEl0IHNob3VsZCByZXR1cm4gbnVsbC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVhdHRyaWJ1dGVub2RlYXR0cmlidXRlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlYXR0cmlidXRlbm9kZWF0dHJpYnV0ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEFkZHI7CisgICAgICBOYW1lZE5vZGVNYXAgYWRkckF0dHI7CisgICAgICBOb2RlIGF0dHJOb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0QWRkciA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYWRkckF0dHIgPSB0ZXN0QWRkci5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBhdHRyTm9kZSA9IGFkZHJBdHRyLml0ZW0oMCk7CisgICAgICBhdHRyTGlzdCA9IGF0dHJOb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGFzc2VydE51bGwoIm5vZGVBdHRyaWJ1dGVOb2RlQXR0cmlidXRlQXNzZXJ0MSIsIGF0dHJMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWF0dHJpYnV0ZW5vZGVhdHRyaWJ1dGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVhdHRyaWJ1dGVub2RlYXR0cmlidXRlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXR0cmlidXRlbm9kZW5hbWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWF0dHJpYnV0ZW5vZGVuYW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjNlYTNmZAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWF0dHJpYnV0ZW5vZGVuYW1lLmphdmEKQEAgLTAsMCArMSw4OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBSZXRyaWV2ZSB0aGUgQXR0cmlidXRlIG5hbWVkICJ0aXRsZSIgZnJvbSB0aGUgbGFzdCAKKyAqICAgICBjaGlsZCBvZiB0aGUgZmlyc3QgcCBlbGVtZW50IGFuZCBjaGVjayB0aGUgc3RyaW5nIHJldHVybmVkIAorICogICAgIGJ5IHRoZSAiZ2V0Tm9kZU5hbWUoKSIgbWV0aG9kLiAgIEl0IHNob3VsZCBiZSBlcXVhbCB0byAKKyAqICAgICAidGl0bGUiLiAKKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzNiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzNjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWF0dHJpYnV0ZW5vZGVuYW1lIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlYXR0cmlidXRlbm9kZW5hbWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RBZGRyOworICAgICAgQXR0ciBhZGRyQXR0cjsKKyAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdEFkZHIgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGFkZHJBdHRyID0gdGVzdEFkZHIuZ2V0QXR0cmlidXRlTm9kZSgidGl0bGUiKTsKKyAgICAgIGF0dHJOYW1lID0gYWRkckF0dHIuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJhdHRyaWJ1dGUiLCAibm9kZU5hbWUiLCAidGl0bGUiLCBhdHRyTmFtZSk7CisgICAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWF0dHJpYnV0ZW5vZGVuYW1lIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlYXR0cmlidXRlbm9kZW5hbWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVhdHRyaWJ1dGVub2RldHlwZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXR0cmlidXRlbm9kZXR5cGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jM2U1M2E3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXR0cmlidXRlbm9kZXR5cGUuamF2YQpAQCAtMCwwICsxLDg5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldE5vZGVUeXBlKCkiIG1ldGhvZCBmb3IgYW4gQXR0cmlidXRlIE5vZGUKKyAqICAgICByZXR1cm5zIHRoZSBjb25zdGFudCB2YWx1ZSAyLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBmaXJzdCBhdHRyaWJ1dGUgZnJvbSB0aGUgbGFzdCBjaGlsZCBvZgorICogICAgIHRoZSBmaXJzdCBlbXBsb3llZSBhbmQgaW52b2tlIHRoZSAiZ2V0Tm9kZVR5cGUoKSIgICAKKyAqICAgICBtZXRob2QuICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIDIuIAorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMTEyMzc1NTg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVhdHRyaWJ1dGVub2RldHlwZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWF0dHJpYnV0ZW5vZGV0eXBlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcjsKKyAgICAgIEF0dHIgYWRkckF0dHI7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhZGRyQXR0ciA9IHRlc3RBZGRyLmdldEF0dHJpYnV0ZU5vZGUoInRpdGxlIik7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGFkZHJBdHRyLmdldE5vZGVUeXBlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVBdHRyTm9kZVR5cGVBc3NlcnQxIiwgMiwgbm9kZVR5cGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlYXR0cmlidXRlbm9kZXR5cGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVhdHRyaWJ1dGVub2RldHlwZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWF0dHJpYnV0ZW5vZGV2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlYXR0cmlidXRlbm9kZXZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGY3ODc2MgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWF0dHJpYnV0ZW5vZGV2YWx1ZS5qYXZhCkBAIC0wLDAgKzEsOTAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlVmFsdWUoKSIgbWV0aG9kIGZvciBhbiAKKyAqICAgICBBdHRyaWJ1dGUgTm9kZSBpcyB0aGUgdmFsdWUgb2YgdGhlIEF0dHJpYnV0ZS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgQXR0cmlidXRlIG5hbWVkICJ0aXRsZSIgZnJvbSB0aGUgbGFzdCAKKyAqICAgICBjaGlsZCBvZiB0aGUgZmlyc3QgInAiIGFuZCBjaGVjayB0aGUgc3RyaW5nIHJldHVybmVkIAorICogICAgIGJ5IHRoZSAiZ2V0Tm9kZVZhbHVlKCkiIG1ldGhvZC4gICBJdCBzaG91bGQgYmUgZXF1YWwgdG8gCisgKiAgICAgIlllcyIuIAorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWF0dHJpYnV0ZW5vZGV2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWF0dHJpYnV0ZW5vZGV2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEFkZHI7CisgICAgICBBdHRyIGFkZHJBdHRyOworICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWNyb255bSIpOworICAgICAgdGVzdEFkZHIgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGFkZHJBdHRyID0gdGVzdEFkZHIuZ2V0QXR0cmlidXRlTm9kZSgidGl0bGUiKTsKKyAgICAgIGF0dHJWYWx1ZSA9IGFkZHJBdHRyLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlVmFsdWUiLCAiWWVzIiwgYXR0clZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWF0dHJpYnV0ZW5vZGV2YWx1ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWF0dHJpYnV0ZW5vZGV2YWx1ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNoaWxkbm9kZXMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNoaWxkbm9kZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YjM1YmM5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlY2hpbGRub2Rlcy5qYXZhCkBAIC0wLDAgKzEsMTE0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIAorICogICAgIFRoZSAiZ2V0Q2hpbGROb2RlcygpIiBtZXRob2QgcmV0dXJucyBhIE5vZGVMaXN0CisgKiAgICAgdGhhdCBjb250YWlucyBhbGwgY2hpbGRyZW4gb2YgdGhpcyBub2RlLiAKKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBjaGVjayB0aGUgTm9kZUxpc3QKKyAqICAgICByZXR1cm5lZCBieSB0aGUgImdldENoaWxkTm9kZXMoKSIgbWV0aG9kLiAgIFRoZQorICogICAgIGxlbmd0aCBvZiB0aGUgbGlzdCBzaG91bGQgYmUgMTMuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNDUxNDYwOTg3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNDUxNDYwOTg3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDYiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVjaGlsZG5vZGVzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlY2hpbGRub2RlcyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZSBjaGlsZE5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZE5vZGVzOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIGphdmEudXRpbC5MaXN0IGFjdHVhbCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5MaXN0IGV4cGVjdGVkID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgiZW0iKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgic3Ryb25nIik7CisgICAgICBleHBlY3RlZC5hZGQoImNvZGUiKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgic3VwIik7CisgICAgICBleHBlY3RlZC5hZGQoInZhciIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJhY3JvbnltIik7CisgICAgICAKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTm9kZXMgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwNkMgPSAwOyBpbmRleE4xMDA2QyA8IGNoaWxkTm9kZXMuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDZDKyspIHsKKyAgICAgICAgICBjaGlsZE5vZGUgPSAoTm9kZSkgY2hpbGROb2Rlcy5pdGVtKGluZGV4TjEwMDZDKTsKKyAgICBub2RlVHlwZSA9IChpbnQpIGNoaWxkTm9kZS5nZXROb2RlVHlwZSgpOworICAgICAgY2hpbGROYW1lID0gY2hpbGROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoMSwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgYWN0dWFsLmFkZChjaGlsZE5hbWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoInRleHROb2RlVHlwZSIsIDMsIG5vZGVUeXBlKTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgICB9CisgICAgICBhc3NlcnRFcXVhbHNBdXRvQ2FzZSgiZWxlbWVudCIsICJlbGVtZW50TmFtZXMiLCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlY2hpbGRub2RlcyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWNoaWxkbm9kZXMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVjaGlsZG5vZGVzYXBwZW5kY2hpbGQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNoaWxkbm9kZXNhcHBlbmRjaGlsZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQwZjExMzkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVjaGlsZG5vZGVzYXBwZW5kY2hpbGQuamF2YQpAQCAtMCwwICsxLDEyNCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIE5vZGVMaXN0IHJldHVybmVkIGJ5IHRoZSAiZ2V0Q2hpbGROb2RlcygpIiBtZXRob2QKKyAqICAgICBpcyBsaXZlLiAgIENoYW5nZXMgb24gdGhlIG5vZGUncyBjaGlsZHJlbiBhcmUgaW1tZWRpYXRlbHkKKyAqICAgICByZWZsZWN0ZWQgb24gdGhlIG5vZGVzIHJldHVybmVkIGluIHRoZSBOb2RlTGlzdC4KKyAqICAgICAKKyAqICAgICBDcmVhdGUgYSBOb2RlTGlzdCBvZiB0aGUgY2hpbGRyZW4gb2YgdGhlIHNlY29uZCBlbXBsb3llZQorICogICAgIGFuZCB0aGVuIGFkZCBhIG5ld2x5IGNyZWF0ZWQgZWxlbWVudCB0aGF0IHdhcyBjcmVhdGVkCisgKiAgICAgYnkgdGhlICJjcmVhdGVFbGVtZW50KCkiIG1ldGhvZChEb2N1bWVudCBJbnRlcmZhY2UpIHRvCisgKiAgICAgdGhlIHNlY29uZCBlbXBsb3llZSBieSB1c2luZyB0aGUgImFwcGVuZENoaWxkKCkiIG1ldGhvZC4KKyAqICAgICBUaGUgbGVuZ3RoIG9mIHRoZSBOb2RlTGlzdCBzaG91bGQgcmVmbGVjdCB0aGlzIG5ldworICogICAgIGFkZGl0aW9uIHRvIHRoZSBjaGlsZCBsaXN0LiAgIEl0IHNob3VsZCByZXR1cm4gdGhlIHZhbHVlIDE0LgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTQ1MTQ2MDk4NyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTQ1MTQ2MDk4NzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlY2hpbGRub2Rlc2FwcGVuZGNoaWxkIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlY2hpbGRub2Rlc2FwcGVuZGNoaWxkKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgY3JlYXRlZE5vZGU7CisgICAgICBOb2RlIGNoaWxkTm9kZTsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBpbnQgY2hpbGRUeXBlOworICAgICAgTm9kZSB0ZXh0Tm9kZTsKKyAgICAgIGphdmEudXRpbC5MaXN0IGFjdHVhbCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5MaXN0IGV4cGVjdGVkID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgiZW0iKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgic3Ryb25nIik7CisgICAgICBleHBlY3RlZC5hZGQoImNvZGUiKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgic3VwIik7CisgICAgICBleHBlY3RlZC5hZGQoInZhciIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJhY3JvbnltIik7CisgICAgICBleHBlY3RlZC5hZGQoImJyIik7CisgICAgICAKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgY2hpbGRMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGNyZWF0ZWROb2RlID0gZG9jLmNyZWF0ZUVsZW1lbnQoImJyIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbXBsb3llZU5vZGUuYXBwZW5kQ2hpbGQoY3JlYXRlZE5vZGUpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwODcgPSAwOyBpbmRleE4xMDA4NyA8IGNoaWxkTGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwODcrKykgeworICAgICAgICAgIGNoaWxkTm9kZSA9IChOb2RlKSBjaGlsZExpc3QuaXRlbShpbmRleE4xMDA4Nyk7CisgICAgY2hpbGROYW1lID0gY2hpbGROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBjaGlsZFR5cGUgPSAoaW50KSBjaGlsZE5vZGUuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygxLCBjaGlsZFR5cGUpKSB7CisgICAgICAgICAgYWN0dWFsLmFkZChjaGlsZE5hbWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoInRleHROb2RlVHlwZSIsIDMsIGNoaWxkVHlwZSk7CisgICAgICB9CisgICAgICAgIAorICAgICAgfQorICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImVsZW1lbnQiLCAiY2hpbGRFbGVtZW50cyIsIGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVjaGlsZG5vZGVzYXBwZW5kY2hpbGQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVjaGlsZG5vZGVzYXBwZW5kY2hpbGQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVjaGlsZG5vZGVzZW1wdHkuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNoaWxkbm9kZXNlbXB0eS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI1MzNlMjUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVjaGlsZG5vZGVzZW1wdHkuamF2YQpAQCAtMCwwICsxLDkzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0Q2hpbGROb2RlcygpIiBtZXRob2QgcmV0dXJucyBhIE5vZGVMaXN0CisgKiAgICAgdGhhdCBjb250YWlucyBhbGwgY2hpbGRyZW4gb2YgdGhpcyBub2RlLiAgIElmIHRoZXJlCisgKiAgICAgYXJlIG5vdCBhbnkgY2hpbGRyZW4sIHRoaXMgaXMgYSBOb2RlTGlzdCB0aGF0IGRvZXMgbm90IAorICogICAgIGNvbnRhaW4gYW55IG5vZGVzLiAKKyAqICAgICBSZXRyaWV2ZSB0aGUgY2hhcmFjdGVyIGRhdGEgb2YgdGhlIHNlY29uZCAiZW0iIG5vZGUgYW5kCisgKiAgICAgaW52b2tlIHRoZSAiZ2V0Q2hpbGROb2RlcygpIiBtZXRob2QuICAgVGhlCisgKiAgICAgTm9kZUxpc3QgcmV0dXJuZWQgc2hvdWxkIG5vdCBoYXZlIGFueSBub2Rlcy4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE0NTE0NjA5ODciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE0NTE0NjA5ODc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWNoaWxkbm9kZXNlbXB0eSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWNoaWxkbm9kZXNlbXB0eShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZSB0ZXh0Tm9kZTsKKyAgICAgIGludCBsZW5ndGg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgdGV4dE5vZGUgPSBlbXBsb3llZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgY2hpbGRMaXN0ID0gdGV4dE5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgbGVuZ3RoID0gKGludCkgY2hpbGRMaXN0LmdldExlbmd0aCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJsZW5ndGhfemVybyIsIDAsIGxlbmd0aCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVjaGlsZG5vZGVzZW1wdHkiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVjaGlsZG5vZGVzZW1wdHkuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVjbG9uZWF0dHJpYnV0ZXNjb3BpZWQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNsb25lYXR0cmlidXRlc2NvcGllZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmExMDFkMmQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVjbG9uZWF0dHJpYnV0ZXNjb3BpZWQuamF2YQpAQCAtMCwwICsxLDExMyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGFjcm9ueW0gZWxlbWVudCBhbmQgaW52b2tlCisgKiAgICAgdGhlIGNsb25lTm9kZSBtZXRob2QuICAgVGhlCisgKiAgICAgZHVwbGljYXRlIG5vZGUgcmV0dXJuZWQgYnkgdGhlIG1ldGhvZCBzaG91bGQgY29weSB0aGUKKyAqICAgICBhdHRyaWJ1dGVzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG5vZGUuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yMzYiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yMzY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTE4NCI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTE4NDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWNsb25lYXR0cmlidXRlc2NvcGllZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWNsb25lYXR0cmlidXRlc2NvcGllZChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBhZGRyZXNzTm9kZTsKKyAgICAgIE5vZGUgY2xvbmVkTm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgTm9kZSBhdHRyaWJ1dGVOb2RlOworICAgICAgU3RyaW5nIGF0dHJpYnV0ZU5hbWU7CisgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbiByZXN1bHQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbiBodG1sRXhwZWN0ZWQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgaHRtbEV4cGVjdGVkLmFkZCgiY2xhc3MiKTsKKyAgICAgIGh0bWxFeHBlY3RlZC5hZGQoInRpdGxlIik7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9uIGV4cGVjdGVkID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgiY2xhc3MiKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgidGl0bGUiKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgiZGlyIik7CisgICAgICAKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICBhZGRyZXNzTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjbG9uZWROb2RlID0gYWRkcmVzc05vZGUuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSBjbG9uZWROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDc2ID0gMDsgaW5kZXhOMTAwNzYgPCBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOyBpbmRleE4xMDA3NisrKSB7CisgICAgICAgICAgYXR0cmlidXRlTm9kZSA9IChOb2RlKSBhdHRyaWJ1dGVzLml0ZW0oaW5kZXhOMTAwNzYpOworICAgIGF0dHJpYnV0ZU5hbWUgPSBhdHRyaWJ1dGVOb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICByZXN1bHQuYWRkKGF0dHJpYnV0ZU5hbWUpOworICAgICAgICB9CisgICAgICAKKyAgICAgIGlmICgoInRleHQvaHRtbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkgeworICAgICAgICAgIGFzc2VydEVxdWFsc0lnbm9yZUNhc2UoIm5vZGVOYW1lc19odG1sIiwgaHRtbEV4cGVjdGVkLCByZXN1bHQpOworfSBlbHNlIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lcyIsIGV4cGVjdGVkLCByZXN1bHQpOworICAgICAgfQorICAgICAgICAKKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVjbG9uZWF0dHJpYnV0ZXNjb3BpZWQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVjbG9uZWF0dHJpYnV0ZXNjb3BpZWQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVjbG9uZWZhbHNlbm9jb3B5dGV4dC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlY2xvbmVmYWxzZW5vY29weXRleHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNWRhNmFhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlY2xvbmVmYWxzZW5vY29weXRleHQuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNsb25lTm9kZShkZWVwKSIgbWV0aG9kIGRvZXMgbm90IGNvcHkgdGV4dCB1bmxlc3MgaXQKKyAqICAgICBpcyBkZWVwIGNsb25lZC4oVGVzdCBmb3IgZGVlcD1mYWxzZSkKKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgZm91cnRoIGNoaWxkIG9mIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kCisgKiAgICAgdGhlICJjbG9uZU5vZGUoZGVlcCkiIG1ldGhvZCB3aXRoIGRlZXA9ZmFsc2UuICAgVGhlCisgKiAgICAgZHVwbGljYXRlIG5vZGUgcmV0dXJuZWQgYnkgdGhlIG1ldGhvZCBzaG91bGQgbm90IGNvcHkKKyAqICAgICBhbnkgdGV4dCBkYXRhIGNvbnRhaW5lZCBpbiB0aGlzIG5vZGUuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zQTBFRDBBNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtM0EwRUQwQTQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVjbG9uZWZhbHNlbm9jb3B5dGV4dCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWNsb25lZmFsc2Vub2NvcHl0ZXh0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgY2hpbGROb2RlOworICAgICAgTm9kZSBjbG9uZWROb2RlOworICAgICAgTm9kZSBsYXN0Q2hpbGROb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjaGlsZExpc3QgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgY2hpbGROb2RlID0gY2hpbGRMaXN0Lml0ZW0oMyk7CisgICAgICBjbG9uZWROb2RlID0gY2hpbGROb2RlLmNsb25lTm9kZShmYWxzZSk7CisgICAgICBsYXN0Q2hpbGROb2RlID0gY2xvbmVkTm9kZS5nZXRMYXN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE51bGwoIm5vZGVDbG9uZUZhbHNlTm9Db3B5VGV4dEFzc2VydDEiLCBsYXN0Q2hpbGROb2RlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWNsb25lZmFsc2Vub2NvcHl0ZXh0IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlY2xvbmVmYWxzZW5vY29weXRleHQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVjbG9uZWdldHBhcmVudG51bGwuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNsb25lZ2V0cGFyZW50bnVsbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVlMWIyOTgKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVjbG9uZWdldHBhcmVudG51bGwuamF2YQpAQCAtMCwwICsxLDkwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgZHVwbGljYXRlIG5vZGUgcmV0dXJuZWQgYnkgdGhlICJjbG9uZU5vZGUoZGVlcCkiCisgKiAgICAgbWV0aG9kIGRvZXMgbm90IGhhdmUgYSBQYXJlbnROb2RlLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGludm9rZSB0aGUKKyAqICAgICAiY2xvbmVOb2RlKGRlZXApIiBtZXRob2Qgd2l0aCBkZWVwPWZhbHNlLiAgIFRoZQorICogICAgIGR1cGxpY2F0ZSBub2RlIHJldHVybmVkIHNob3VsZCByZXR1cm4gbnVsbCB3aGVuIHRoZQorICogICAgICJnZXRQYXJlbnROb2RlKCkiIGlzIGludm9rZWQuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zQTBFRDBBNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtM0EwRUQwQTQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVjbG9uZWdldHBhcmVudG51bGwgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVjbG9uZWdldHBhcmVudG51bGwoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZSBjbG9uZWROb2RlOworICAgICAgTm9kZSBwYXJlbnROb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjbG9uZWROb2RlID0gZW1wbG95ZWVOb2RlLmNsb25lTm9kZShmYWxzZSk7CisgICAgICBwYXJlbnROb2RlID0gY2xvbmVkTm9kZS5nZXRQYXJlbnROb2RlKCk7CisgICAgICBhc3NlcnROdWxsKCJub2RlQ2xvbmVHZXRQYXJlbnROdWxsQXNzZXJ0MSIsIHBhcmVudE5vZGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlY2xvbmVnZXRwYXJlbnRudWxsIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlY2xvbmVnZXRwYXJlbnRudWxsLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlY2xvbmVub2RlZmFsc2UuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNsb25lbm9kZWZhbHNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTFlMjBiMgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNsb25lbm9kZWZhbHNlLmphdmEKQEAgLTAsMCArMSw5NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJjbG9uZU5vZGUoZGVlcCkiIG1ldGhvZCByZXR1cm5zIGEgY29weSBvZiB0aGUgbm9kZQorICogICAgIG9ubHkgaWYgZGVlcD1mYWxzZS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBpbnZva2UgdGhlCisgKiAgICAgImNsb25lTm9kZShkZWVwKSIgbWV0aG9kIHdpdGggZGVlcD1mYWxzZS4gICBUaGUKKyAqICAgICBtZXRob2Qgc2hvdWxkIG9ubHkgY2xvbmUgdGhpcyBub2RlLiAgIFRoZSBOb2RlTmFtZSBhbmQKKyAqICAgICBsZW5ndGggb2YgdGhlIE5vZGVMaXN0IGFyZSBjaGVja2VkLiAgIFRoZSAiZ2V0Tm9kZU5hbWUoKSIKKyAqICAgICBtZXRob2Qgc2hvdWxkIHJldHVybiAiZW1wbG95ZWUiIGFuZCB0aGUgImdldExlbmd0aCgpIgorICogICAgIG1ldGhvZCBzaG91bGQgcmV0dXJuIDAuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zQTBFRDBBNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtM0EwRUQwQTQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVjbG9uZW5vZGVmYWxzZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWNsb25lbm9kZWZhbHNlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGUgY2xvbmVkTm9kZTsKKyAgICAgIFN0cmluZyBjbG9uZU5hbWU7CisgICAgICBOb2RlTGlzdCBjbG9uZUNoaWxkcmVuOworICAgICAgaW50IGxlbmd0aDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgY2xvbmVkTm9kZSA9IGVtcGxveWVlTm9kZS5jbG9uZU5vZGUoZmFsc2UpOworICAgICAgY2xvbmVOYW1lID0gY2xvbmVkTm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImVsZW1lbnQiLCAic3Ryb25nIiwgInAiLCBjbG9uZU5hbWUpOworICAgICAgICBjbG9uZUNoaWxkcmVuID0gY2xvbmVkTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBsZW5ndGggPSAoaW50KSBjbG9uZUNoaWxkcmVuLmdldExlbmd0aCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJsZW5ndGgiLCAwLCBsZW5ndGgpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlY2xvbmVub2RlZmFsc2UiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVjbG9uZW5vZGVmYWxzZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNsb25lbm9kZXRydWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNsb25lbm9kZXRydWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42OWMwNDU1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlY2xvbmVub2RldHJ1ZS5qYXZhCkBAIC0wLDAgKzEsMTEzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY2xvbmVOb2RlKGRlZXApIiBtZXRob2QgcmV0dXJucyBhIGNvcHkgb2YgdGhlIG5vZGUKKyAqICAgICBhbmQgdGhlIHN1YnRyZWUgdW5kZXIgaXQgaWYgZGVlcD10cnVlLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGludm9rZSB0aGUKKyAqICAgICAiY2xvbmVOb2RlKGRlZXApIiBtZXRob2Qgd2l0aCBkZWVwPXRydWUuICAgVGhlCisgKiAgICAgbWV0aG9kIHNob3VsZCBjbG9uZSB0aGlzIG5vZGUgYW5kIHRoZSBzdWJ0cmVlIHVuZGVyIGl0LgorICogICAgIFRoZSBOb2RlTmFtZSBvZiBlYWNoIGNoaWxkIGluIHRoZSByZXR1cm5lZCBub2RlIGlzIAorICogICAgIGNoZWNrZWQgdG8gaW5zdXJlIHRoZSBlbnRpcmUgc3VidHJlZSB1bmRlciB0aGUgc2Vjb25kCisgKiAgICAgZW1wbG95ZWUgd2FzIGNsb25lZC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTNBMEVEMEE0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zQTBFRDBBNDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlY2xvbmVub2RldHJ1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWNsb25lbm9kZXRydWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZSBjbG9uZWROb2RlOworICAgICAgTm9kZUxpc3QgY2xvbmVkTGlzdDsKKyAgICAgIE5vZGUgY2xvbmVkQ2hpbGQ7CisgICAgICBTdHJpbmcgY2xvbmVkQ2hpbGROYW1lOworICAgICAgTm9kZUxpc3Qgb3JpZ0xpc3Q7CisgICAgICBOb2RlIG9yaWdDaGlsZDsKKyAgICAgIFN0cmluZyBvcmlnQ2hpbGROYW1lOworICAgICAgamF2YS51dGlsLkxpc3QgcmVzdWx0ID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkxpc3QgZXhwZWN0ZWQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIG9yaWdMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDY1ID0gMDsgaW5kZXhOMTAwNjUgPCBvcmlnTGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwNjUrKykgeworICAgICAgICAgIG9yaWdDaGlsZCA9IChOb2RlKSBvcmlnTGlzdC5pdGVtKGluZGV4TjEwMDY1KTsKKyAgICBvcmlnQ2hpbGROYW1lID0gb3JpZ0NoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICBleHBlY3RlZC5hZGQob3JpZ0NoaWxkTmFtZSk7CisgICAgICAgIH0KKyAgICAgIGNsb25lZE5vZGUgPSBlbXBsb3llZU5vZGUuY2xvbmVOb2RlKHRydWUpOworICAgICAgY2xvbmVkTGlzdCA9IGNsb25lZE5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwN0IgPSAwOyBpbmRleE4xMDA3QiA8IGNsb25lZExpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDdCKyspIHsKKyAgICAgICAgICBjbG9uZWRDaGlsZCA9IChOb2RlKSBjbG9uZWRMaXN0Lml0ZW0oaW5kZXhOMTAwN0IpOworICAgIGNsb25lZENoaWxkTmFtZSA9IGNsb25lZENoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICByZXN1bHQuYWRkKGNsb25lZENoaWxkTmFtZSk7CisgICAgICAgIH0KKyAgICAgIGFzc2VydEVxdWFscygiY2xvbmUiLCBleHBlY3RlZCwgcmVzdWx0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWNsb25lbm9kZXRydWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVjbG9uZW5vZGV0cnVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlY2xvbmV0cnVlY29weXRleHQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNsb25ldHJ1ZWNvcHl0ZXh0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTc5ZjgyYwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNsb25ldHJ1ZWNvcHl0ZXh0LmphdmEKQEAgLTAsMCArMSw5MyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNsb25lTm9kZShkZWVwKSIgbWV0aG9kIGRvZXMgbm90IGNvcHkgdGV4dCB1bmxlc3MgaXQKKyAqICAgICBpcyBkZWVwIGNsb25lZC4oVGVzdCBmb3IgZGVlcD10cnVlKQorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBlaWdodGggY2hpbGQgb2YgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQKKyAqICAgICB0aGUgImNsb25lTm9kZShkZWVwKSIgbWV0aG9kIHdpdGggZGVlcD10cnVlLiAgIFRoZQorICogICAgIGR1cGxpY2F0ZSBub2RlIHJldHVybmVkIGJ5IHRoZSBtZXRob2Qgc2hvdWxkIGNvcHkKKyAqICAgICBhbnkgdGV4dCBkYXRhIGNvbnRhaW5lZCBpbiB0aGlzIG5vZGUuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zQTBFRDBBNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtM0EwRUQwQTQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWNsb25ldHJ1ZWNvcHl0ZXh0IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlY2xvbmV0cnVlY29weXRleHQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgY2hpbGROb2RlOworICAgICAgTm9kZSBjbG9uZWROb2RlOworICAgICAgTm9kZSBsYXN0Q2hpbGROb2RlOworICAgICAgU3RyaW5nIGNoaWxkVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgic3VwIik7CisgICAgICBjaGlsZE5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgY2xvbmVkTm9kZSA9IGNoaWxkTm9kZS5jbG9uZU5vZGUodHJ1ZSk7CisgICAgICBsYXN0Q2hpbGROb2RlID0gY2xvbmVkTm9kZS5nZXRMYXN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkVmFsdWUgPSBsYXN0Q2hpbGROb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJjbG9uZUNvbnRhaW5zVGV4dCIsICIzNSwwMDAiLCBjaGlsZFZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWNsb25ldHJ1ZWNvcHl0ZXh0IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlY2xvbmV0cnVlY29weXRleHQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVjb21tZW50bm9kZWF0dHJpYnV0ZXMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNvbW1lbnRub2RlYXR0cmlidXRlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBkYjNiODMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVjb21tZW50bm9kZWF0dHJpYnV0ZXMuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEF0dHJpYnV0ZXMoKSIgbWV0aG9kIGludm9rZWQgb24gYSBDb21tZW50IAorICogICAgIE5vZGUgcmV0dXJucyBudWxsLgorICogICAgIEZpbmQgYW55IGNvbW1lbnQgdGhhdCBpcyBhbiBpbW1lZGlhdGUgY2hpbGQgb2YgdGhlIHJvb3QKKyAqICAgICBhbmQgYXNzZXJ0IHRoYXQgTm9kZS5hdHRyaWJ1dGVzIGlzIG51bGwuICBUaGVuIGNyZWF0ZQorICogICAgIGEgbmV3IGNvbW1lbnQgbm9kZSAoaW4gY2FzZSB0aGV5IGhhZCBiZWVuIG9taXR0ZWQpIGFuZAorICogICAgIG1ha2UgdGhlIGFzc2VydGlvbi4gICAgCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MjgyNzkzMjIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MjgyNzkzMjI8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OCI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0ODwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjYzIj5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjYzPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlY29tbWVudG5vZGVhdHRyaWJ1dGVzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlY29tbWVudG5vZGVhdHRyaWJ1dGVzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGUgY29tbWVudE5vZGU7CisgICAgICBOb2RlTGlzdCBub2RlTGlzdDsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyTGlzdDsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBub2RlTGlzdCA9IGRvYy5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA0MyA9IDA7IGluZGV4TjEwMDQzIDwgbm9kZUxpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDQzKyspIHsKKyAgICAgICAgICBjb21tZW50Tm9kZSA9IChOb2RlKSBub2RlTGlzdC5pdGVtKGluZGV4TjEwMDQzKTsKKyAgICBub2RlVHlwZSA9IChpbnQpIGNvbW1lbnROb2RlLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoOCwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgYXR0ckxpc3QgPSBjb21tZW50Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBhc3NlcnROdWxsKCJleGlzdGluZ0NvbW1lbnRBdHRyaWJ1dGVzTnVsbCIsIGF0dHJMaXN0KTsKKyAgICAgIH0KKyAgICAgIH0KKyAgICAgIGNvbW1lbnROb2RlID0gZG9jLmNyZWF0ZUNvbW1lbnQoIlRoaXMgaXMgYSBjb21tZW50Iik7CisgICAgICBhdHRyTGlzdCA9IGNvbW1lbnROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGFzc2VydE51bGwoImNyZWF0ZWRDb21tZW50QXR0cmlidXRlc051bGwiLCBhdHRyTGlzdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVjb21tZW50bm9kZWF0dHJpYnV0ZXMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVjb21tZW50bm9kZWF0dHJpYnV0ZXMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVjb21tZW50bm9kZW5hbWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNvbW1lbnRub2RlbmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIyYTdkZTEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVjb21tZW50bm9kZW5hbWUuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAiZ2V0Tm9kZU5hbWUoKSIgbWV0aG9kIGZvciBhIAorICogICAgIENvbW1lbnQgTm9kZSBpcyAiI2NvbW1lbnQiLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBDb21tZW50IG5vZGUgaW4gdGhlIFhNTCBmaWxlIAorICogICAgIGFuZCBjaGVjayB0aGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAiZ2V0Tm9kZU5hbWUoKSIgCisgKiAgICAgbWV0aG9kLiAgIEl0IHNob3VsZCBiZSBlcXVhbCB0byAiI2NvbW1lbnQiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzI4Mjc5MzIyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzI4Mjc5MzIyPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDgiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVjb21tZW50bm9kZW5hbWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVjb21tZW50bm9kZW5hbWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGNvbW1lbnROb2RlOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgU3RyaW5nIGNvbW1lbnROYW1lOworICAgICAgU3RyaW5nIGNvbW1lbnROb2RlTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA0NCA9IDA7IGluZGV4TjEwMDQ0IDwgZWxlbWVudExpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDQ0KyspIHsKKyAgICAgICAgICBjb21tZW50Tm9kZSA9IChOb2RlKSBlbGVtZW50TGlzdC5pdGVtKGluZGV4TjEwMDQ0KTsKKyAgICBub2RlVHlwZSA9IChpbnQpIGNvbW1lbnROb2RlLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoOCwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgY29tbWVudE5vZGVOYW1lID0gY29tbWVudE5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZXhpc3RpbmdOb2RlTmFtZSIsICIjY29tbWVudCIsIGNvbW1lbnROb2RlTmFtZSk7CisgICAgICB9CisgICAgICB9CisgICAgICBjb21tZW50Tm9kZSA9IGRvYy5jcmVhdGVDb21tZW50KCJUaGlzIGlzIGEgY29tbWVudCIpOworICAgICAgY29tbWVudE5vZGVOYW1lID0gY29tbWVudE5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY3JlYXRlZE5vZGVOYW1lIiwgIiNjb21tZW50IiwgY29tbWVudE5vZGVOYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWNvbW1lbnRub2RlbmFtZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWNvbW1lbnRub2RlbmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNvbW1lbnRub2RldHlwZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlY29tbWVudG5vZGV0eXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmZhZTNlMgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNvbW1lbnRub2RldHlwZS5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXROb2RlVHlwZSgpIiBtZXRob2QgZm9yIGEgQ29tbWVudCBOb2RlCisgKiAgICAgcmV0dXJucyB0aGUgY29uc3RhbnQgdmFsdWUgOC4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgbm9kZXMgZnJvbSB0aGUgZG9jdW1lbnQgYW5kIGNoZWNrIGZvcgorICogICAgIGEgY29tbWVudCBub2RlIGFuZCBpbnZva2UgdGhlICJnZXROb2RlVHlwZSgpIiBtZXRob2QuICAgVGhpcyBzaG91bGQgICAKKyAqICAgICByZXR1cm4gOC4gCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMTEyMzc1NTgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIzNzU1ODwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzI4Mjc5MzIyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzI4Mjc5MzIyPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDgiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVjb21tZW50bm9kZXR5cGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVjb21tZW50bm9kZXR5cGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgdGVzdExpc3Q7CisgICAgICBOb2RlIGNvbW1lbnROb2RlOworICAgICAgU3RyaW5nIGNvbW1lbnROb2RlTmFtZTsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICB0ZXN0TGlzdCA9IGRvYy5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA0MCA9IDA7IGluZGV4TjEwMDQwIDwgdGVzdExpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDQwKyspIHsKKyAgICAgICAgICBjb21tZW50Tm9kZSA9IChOb2RlKSB0ZXN0TGlzdC5pdGVtKGluZGV4TjEwMDQwKTsKKyAgICBjb21tZW50Tm9kZU5hbWUgPSBjb21tZW50Tm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKCIjY29tbWVudCIsIGNvbW1lbnROb2RlTmFtZSkpIHsKKyAgICAgICAgICBub2RlVHlwZSA9IChpbnQpIGNvbW1lbnROb2RlLmdldE5vZGVUeXBlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImV4aXN0aW5nQ29tbWVudE5vZGVUeXBlIiwgOCwgbm9kZVR5cGUpOworICAgICAgfQorICAgICAgfQorICAgICAgY29tbWVudE5vZGUgPSBkb2MuY3JlYXRlQ29tbWVudCgiVGhpcyBpcyBhIGNvbW1lbnQiKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgY29tbWVudE5vZGUuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY3JlYXRlZENvbW1lbnROb2RlVHlwZSIsIDgsIG5vZGVUeXBlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWNvbW1lbnRub2RldHlwZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWNvbW1lbnRub2RldHlwZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNvbW1lbnRub2RldmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWNvbW1lbnRub2RldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNDJmYWU4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlY29tbWVudG5vZGV2YWx1ZS5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIHN0cmluZyByZXR1cm5lZCBieSB0aGUgImdldE5vZGVWYWx1ZSgpIiBtZXRob2QgZm9yIGEgCisgKiAgICAgQ29tbWVudCBOb2RlIGlzIHRoZSBjb250ZW50IG9mIHRoZSBjb21tZW50LgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBjb21tZW50IGluIHRoZSBYTUwgZmlsZSBhbmQgICAKKyAqICAgICBjaGVjayB0aGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAiZ2V0Tm9kZVZhbHVlKCkiIG1ldGhvZC4gCisgKiAgICAgSXQgc2hvdWxkIGJlIGVxdWFsIHRvICJUaGlzIGlzIGNvbW1lbnQgbnVtYmVyIDEiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzI4Mjc5MzIyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzI4Mjc5MzIyPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDgiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVjb21tZW50bm9kZXZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlY29tbWVudG5vZGV2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgY29tbWVudE5vZGU7CisgICAgICBTdHJpbmcgY29tbWVudE5hbWU7CisgICAgICBTdHJpbmcgY29tbWVudFZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDQwID0gMDsgaW5kZXhOMTAwNDAgPCBlbGVtZW50TGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwNDArKykgeworICAgICAgICAgIGNvbW1lbnROb2RlID0gKE5vZGUpIGVsZW1lbnRMaXN0Lml0ZW0oaW5kZXhOMTAwNDApOworICAgIGNvbW1lbnROYW1lID0gY29tbWVudE5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygiI2NvbW1lbnQiLCBjb21tZW50TmFtZSkpIHsKKyAgICAgICAgICBjb21tZW50VmFsdWUgPSBjb21tZW50Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygidmFsdWUiLCAiIFRoaXMgaXMgY29tbWVudCBudW1iZXIgMS4iLCBjb21tZW50VmFsdWUpOworICAgICAgfQorICAgICAgfQorICAgICAgY29tbWVudE5vZGUgPSBkb2MuY3JlYXRlQ29tbWVudCgiIFRoaXMgaXMgYSBjb21tZW50Iik7CisgICAgICBjb21tZW50VmFsdWUgPSBjb21tZW50Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY3JlYXRlZENvbW1lbnROb2RlVmFsdWUiLCAiIFRoaXMgaXMgYSBjb21tZW50IiwgY29tbWVudFZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWNvbW1lbnRub2RldmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVjb21tZW50bm9kZXZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGVuYW1lLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVkb2N1bWVudGZyYWdtZW50bm9kZW5hbWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYmJjODNlCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGVuYW1lLmphdmEKQEAgLTAsMCArMSw4NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIHN0cmluZyByZXR1cm5lZCBieSB0aGUgImdldE5vZGVOYW1lKCkiIG1ldGhvZCBmb3IgYSAKKyAqICAgICBEb2N1bWVudEZyYWdtZW50IE5vZGUgaXMgIiNkb2N1bWVudC1mcmFtZW50Ii4KKyAqICAgICBSZXRyaWV2ZSB0aGUgRE9NIGRvY3VtZW50IGFuZCBpbnZva2UgdGhlCisgKiAgICAgImNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSIgbWV0aG9kIGFuZCBjaGVjayB0aGUgc3RyaW5nICAgICAgCisgKiAgICAgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlTmFtZSgpIiBtZXRob2QuICAgSXQgc2hvdWxkIGJlIAorICogICAgIGVxdWFsIHRvICIjZG9jdW1lbnQtZnJhZ21lbnQiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1CNjNFRDFBMyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtQjYzRUQxQTM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVkb2N1bWVudGZyYWdtZW50bm9kZW5hbWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVkb2N1bWVudGZyYWdtZW50bm9kZW5hbWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudEZyYWdtZW50IGRvY0ZyYWdtZW50OworICAgICAgU3RyaW5nIGRvY3VtZW50RnJhZ21lbnROYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZG9jRnJhZ21lbnQgPSBkb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOworICAgICAgZG9jdW1lbnRGcmFnbWVudE5hbWUgPSBkb2NGcmFnbWVudC5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlRG9jdW1lbnRGcmFnbWVudE5vZGVOYW1lQXNzZXJ0MSIsICIjZG9jdW1lbnQtZnJhZ21lbnQiLCBkb2N1bWVudEZyYWdtZW50TmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVkb2N1bWVudGZyYWdtZW50bm9kZW5hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVkb2N1bWVudGZyYWdtZW50bm9kZW5hbWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVkb2N1bWVudGZyYWdtZW50bm9kZXR5cGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUyYWZkNjUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVkb2N1bWVudGZyYWdtZW50bm9kZXR5cGUuamF2YQpAQCAtMCwwICsxLDg2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldE5vZGVUeXBlKCkiIG1ldGhvZCBmb3IgYSBEb2N1bWVudEZyYWdtZW50IE5vZGUKKyAqICAgICByZXR1cm5zIHRoZSBjb25zdGFudCB2YWx1ZSAxMS4KKyAqICAgICBJbnZva2UgdGhlICJjcmVhdGVEb2N1bWVudEZyYWdtZW50KCkiIG1ldGhvZCBhbmQgICAgCisgKiAgICAgZXhhbWluZSB0aGUgTm9kZVR5cGUgb2YgdGhlIGRvY3VtZW50IGZyYWdtZW50CisgKiAgICAgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlVHlwZSgpIiBtZXRob2QuICAgVGhlIG1ldGhvZCAKKyAqICAgICBzaG91bGQgcmV0dXJuIDExLiAKKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIzNzU1OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUI2M0VEMUEzIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1CNjNFRDFBMzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldHlwZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldHlwZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50RnJhZ21lbnQgZG9jdW1lbnRGcmFnbWVudE5vZGU7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBkb2N1bWVudEZyYWdtZW50Tm9kZSA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGRvY3VtZW50RnJhZ21lbnROb2RlLmdldE5vZGVUeXBlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVEb2N1bWVudEZyYWdtZW50Tm9kZVR5cGVBc3NlcnQxIiwgMTEsIG5vZGVUeXBlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldHlwZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldHlwZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZWI0MmJjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGV2YWx1ZS5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlVmFsdWUoKSIgbWV0aG9kIGZvciBhIAorICogICAgIERvY3VtZW50RnJhZ21lbnQgTm9kZSBpcyBudWxsLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBET00gZG9jdW1lbnQgYW5kIGludm9rZSB0aGUKKyAqICAgICAiY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpIiBtZXRob2QgYW5kIGNoZWNrIHRoZSBzdHJpbmcgICAgICAKKyAqICAgICByZXR1cm5lZCBieSB0aGUgImdldE5vZGVWYWx1ZSgpIiBtZXRob2QuICAgSXQgc2hvdWxkIGJlIAorICogICAgIGVxdWFsIHRvIG51bGwuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUI2M0VEMUEzIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1CNjNFRDFBMzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVkb2N1bWVudGZyYWdtZW50bm9kZXZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGV2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50RnJhZ21lbnQgZG9jRnJhZ21lbnQ7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0ckxpc3Q7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBkb2NGcmFnbWVudCA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CisgICAgICBhdHRyTGlzdCA9IGRvY0ZyYWdtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGFzc2VydE51bGwoImF0dHJpYnV0ZXNOdWxsIiwgYXR0ckxpc3QpOworICAgICAgdmFsdWUgPSBkb2NGcmFnbWVudC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydE51bGwoImluaXRpYWxseU51bGwiLCB2YWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVkb2N1bWVudGZyYWdtZW50bm9kZXZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGV2YWx1ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWRvY3VtZW50bm9kZWF0dHJpYnV0ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZG9jdW1lbnRub2RlYXR0cmlidXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWMwOWRjYgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWRvY3VtZW50bm9kZWF0dHJpYnV0ZS5qYXZhCkBAIC0wLDAgKzEsODMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogVGhlICJnZXRBdHRyaWJ1dGVzKCkiIG1ldGhvZCBpbnZva2VkIG9uIGEgRG9jdW1lbnQKKyAqIE5vZGUgcmV0dXJucyBudWxsLgorICogUmV0cmlldmUgdGhlIERPTSBEb2N1bWVudCBhbmQgaW52b2tlIHRoZQorICogImdldEF0dHJpYnV0ZXMoKSIgbWV0aG9kIG9uIHRoZSBEb2N1bWVudCBOb2RlLgorICogSXQgc2hvdWxkIHJldHVybiBudWxsLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNpLURvY3VtZW50Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNpLURvY3VtZW50PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlZG9jdW1lbnRub2RlYXR0cmlidXRlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlZG9jdW1lbnRub2RlYXR0cmlidXRlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyTGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBhdHRyTGlzdCA9IGRvYy5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBhc3NlcnROdWxsKCJkb2NfYXR0cmlidXRlc19pc19udWxsIiwgYXR0ckxpc3QpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZG9jdW1lbnRub2RlYXR0cmlidXRlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlZG9jdW1lbnRub2RlYXR0cmlidXRlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZG9jdW1lbnRub2RlbmFtZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZG9jdW1lbnRub2RlbmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZmYjE4YzYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVkb2N1bWVudG5vZGVuYW1lLmphdmEKQEAgLTAsMCArMSw4MyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAiZ2V0Tm9kZU5hbWUoKSIgbWV0aG9kIGZvciBhIAorICogICAgIERvY3VtZW50IE5vZGUgaXMgIiNkb2N1bWVudCIuCisgKiAgICAgUmV0cmlldmUgdGhlIERPTSBkb2N1bWVudCBhbmQgY2hlY2sgdGhlIHN0cmluZyByZXR1cm5lZAorICogICAgIGJ5IHRoZSAiZ2V0Tm9kZU5hbWUoKSIgbWV0aG9kLiAgIEl0IHNob3VsZCBiZSBlcXVhbCB0byAKKyAqICAgICAiI2RvY3VtZW50Ii4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI2ktRG9jdW1lbnQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI2ktRG9jdW1lbnQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWRvY3VtZW50bm9kZW5hbWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVkb2N1bWVudG5vZGVuYW1lKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIFN0cmluZyBkb2N1bWVudE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZG9jdW1lbnROYW1lID0gZG9jLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Tm9kZU5hbWUiLCAiI2RvY3VtZW50IiwgZG9jdW1lbnROYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWRvY3VtZW50bm9kZW5hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVkb2N1bWVudG5vZGVuYW1lLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZG9jdW1lbnRub2RldHlwZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZG9jdW1lbnRub2RldHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZiYzRkNDIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVkb2N1bWVudG5vZGV0eXBlLmphdmEKQEAgLTAsMCArMSw4MiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBUaGUgImdldE5vZGVUeXBlKCkiIG1ldGhvZCBmb3IgYSBEb2N1bWVudCBOb2RlCisgKiByZXR1cm5zIHRoZSBjb25zdGFudCB2YWx1ZSA5LgorICogUmV0cmlldmUgdGhlIGRvY3VtZW50IGFuZCBpbnZva2UgdGhlICJnZXROb2RlVHlwZSgpIiAKKyAqIG1ldGhvZC4gICBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gOS4gCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNpLURvY3VtZW50Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNpLURvY3VtZW50PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIzNzU1OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlZG9jdW1lbnRub2RldHlwZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWRvY3VtZW50bm9kZXR5cGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgZG9jLmdldE5vZGVUeXBlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVEb2N1bWVudE5vZGVUeXBlQXNzZXJ0MSIsIDksIG5vZGVUeXBlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWRvY3VtZW50bm9kZXR5cGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVkb2N1bWVudG5vZGV0eXBlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZG9jdW1lbnRub2RldmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWRvY3VtZW50bm9kZXZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGY3MGRkMgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWRvY3VtZW50bm9kZXZhbHVlLmphdmEKQEAgLTAsMCArMSw4MyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIHN0cmluZyByZXR1cm5lZCBieSB0aGUgImdldE5vZGVWYWx1ZSgpIiBtZXRob2QgZm9yIGEgCisgKiAgICAgRG9jdW1lbnQgTm9kZSBpcyBudWxsLgorICogICAgIFJldHJpZXZlIHRoZSBET00gRG9jdW1lbnQgYW5kIGNoZWNrIHRoZSBzdHJpbmcgcmV0dXJuZWQKKyAqICAgICBieSB0aGUgImdldE5vZGVWYWx1ZSgpIiBtZXRob2QuICAgSXQgc2hvdWxkIGJlIGVxdWFsIHRvIAorICogICAgIG51bGwuIAorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjaS1Eb2N1bWVudCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjaS1Eb2N1bWVudDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlZG9jdW1lbnRub2RldmFsdWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVkb2N1bWVudG5vZGV2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBTdHJpbmcgZG9jdW1lbnRWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2N1bWVudFZhbHVlID0gZG9jLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgiZG9jdW1lbnROb2RlVmFsdWUiLCBkb2N1bWVudFZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWRvY3VtZW50bm9kZXZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlZG9jdW1lbnRub2RldmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVlbGVtZW50bm9kZWF0dHJpYnV0ZXMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWVsZW1lbnRub2RlYXR0cmlidXRlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYzNGE3ODAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVlbGVtZW50bm9kZWF0dHJpYnV0ZXMuamF2YQpAQCAtMCwwICsxLDEwOSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBSZXRyaWV2ZSB0aGUgdGhpcmQgImFjcm9ueW0iIGVsZW1lbnQgYW5kIGV2YWx1YXRlIE5vZGUuYXR0cmlidXRlcy4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzNiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzNjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDNKdW4vMDAxMS5odG1sIj5odHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLXRzLzIwMDNKdW4vMDAxMS5odG1sPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0xODQiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0xODQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVlbGVtZW50bm9kZWF0dHJpYnV0ZXMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVlbGVtZW50bm9kZWF0dHJpYnV0ZXMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RBZGRyOworICAgICAgTmFtZWROb2RlTWFwIGFkZHJBdHRyOworICAgICAgTm9kZSBhdHRyTm9kZTsKKyAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9uIGF0dHJMaXN0ID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb24gaHRtbEV4cGVjdGVkID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGh0bWxFeHBlY3RlZC5hZGQoInRpdGxlIik7CisgICAgICBodG1sRXhwZWN0ZWQuYWRkKCJjbGFzcyIpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbiBleHBlY3RlZCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZC5hZGQoInRpdGxlIik7CisgICAgICBleHBlY3RlZC5hZGQoImNsYXNzIik7CisgICAgICBleHBlY3RlZC5hZGQoImRpciIpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBhZGRyQXR0ciA9IHRlc3RBZGRyLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDcwID0gMDsgaW5kZXhOMTAwNzAgPCBhZGRyQXR0ci5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwNzArKykgeworICAgICAgICAgIGF0dHJOb2RlID0gKE5vZGUpIGFkZHJBdHRyLml0ZW0oaW5kZXhOMTAwNzApOworICAgIGF0dHJOYW1lID0gYXR0ck5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGF0dHJMaXN0LmFkZChhdHRyTmFtZSk7CisgICAgICAgIH0KKyAgICAgIAorICAgICAgaWYgKCgidGV4dC9odG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzSWdub3JlQ2FzZSgiYXR0ck5hbWVzX2h0bWwiLCBodG1sRXhwZWN0ZWQsIGF0dHJMaXN0KTsKK30gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyTmFtZXMiLCBleHBlY3RlZCwgYXR0ckxpc3QpOworICAgICAgfQorICAgICAgICAKKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVlbGVtZW50bm9kZWF0dHJpYnV0ZXMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVlbGVtZW50bm9kZWF0dHJpYnV0ZXMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVlbGVtZW50bm9kZW5hbWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWVsZW1lbnRub2RlbmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY2NjgwOGEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVlbGVtZW50bm9kZW5hbWUuamF2YQpAQCAtMCwwICsxLDkwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFJldHJpZXZlIHRoZSBmaXJzdCBFbGVtZW50IE5vZGUoUm9vdCBOb2RlKSBvZiB0aGUgICAKKyAqICAgICBET00gb2JqZWN0IGFuZCBjaGVjayB0aGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAgICAgICAgICAgIAorICogICAgICJnZXROb2RlTmFtZSgpIiBtZXRob2QuICAgSXQgc2hvdWxkIGJlIGVxdWFsIHRvIGl0cworICogICAgIHRhZ05hbWUuIAorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjUxIj5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjUxPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlZWxlbWVudG5vZGVuYW1lIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlZWxlbWVudG5vZGVuYW1lKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudE5vZGU7CisgICAgICBTdHJpbmcgZWxlbWVudE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudE5vZGUgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBlbGVtZW50TmFtZSA9IGVsZW1lbnROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICAKKyAgICAgIGlmICgoImltYWdlL3N2Zyt4bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoInN2Z05vZGVOYW1lIiwgInN2ZyIsIGVsZW1lbnROYW1lKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImVsZW1lbnQiLCAibm9kZU5hbWUiLCAiaHRtbCIsIGVsZW1lbnROYW1lKTsKKyAgICAgICAgfQorICAgICAgICAKKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVlbGVtZW50bm9kZW5hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVlbGVtZW50bm9kZW5hbWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVlbGVtZW50bm9kZXR5cGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWVsZW1lbnRub2RldHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNiZWZkY2EKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVlbGVtZW50bm9kZXR5cGUuamF2YQpAQCAtMCwwICsxLDg0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldE5vZGVUeXBlKCkiIG1ldGhvZCBmb3IgYW4gRWxlbWVudCBOb2RlCisgKiAgICAgcmV0dXJucyB0aGUgY29uc3RhbnQgdmFsdWUgMS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgcm9vdCBub2RlIGFuZCBpbnZva2UgdGhlICJnZXROb2RlVHlwZSgpIiAgIAorICogICAgIG1ldGhvZC4gICBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gMS4gCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMTEyMzc1NTgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIzNzU1ODwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWVsZW1lbnRub2RldHlwZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWVsZW1lbnRub2RldHlwZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IHJvb3ROb2RlOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIHJvb3ROb2RlID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgbm9kZVR5cGUgPSAoaW50KSByb290Tm9kZS5nZXROb2RlVHlwZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlRWxlbWVudE5vZGVUeXBlQXNzZXJ0MSIsIDEsIG5vZGVUeXBlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWVsZW1lbnRub2RldHlwZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWVsZW1lbnRub2RldHlwZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWVsZW1lbnRub2RldmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWVsZW1lbnRub2RldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNGNkNTE1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZWxlbWVudG5vZGV2YWx1ZS5qYXZhCkBAIC0wLDAgKzEsODEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIHN0cmluZyByZXR1cm5lZCBieSB0aGUgImdldE5vZGVWYWx1ZSgpIiBtZXRob2QgZm9yIGFuIAorICogICAgIEVsZW1lbnQgTm9kZSBpcyBudWxsLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWVsZW1lbnRub2RldmFsdWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVlbGVtZW50bm9kZXZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudE5vZGU7CisgICAgICBTdHJpbmcgZWxlbWVudFZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnROb2RlID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgZWxlbWVudFZhbHVlID0gZWxlbWVudE5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJlbGVtZW50Tm9kZVZhbHVlIiwgZWxlbWVudFZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWVsZW1lbnRub2RldmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVlbGVtZW50bm9kZXZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0Zmlyc3RjaGlsZC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0Zmlyc3RjaGlsZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI5ZTY0MTkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVnZXRmaXJzdGNoaWxkLmphdmEKQEAgLTAsMCArMSw5NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEZpcnN0Q2hpbGQoKSIgbWV0aG9kIHJldHVybnMgdGhlIGZpcnN0IGNoaWxkCisgKiAgICAgb2YgdGhpcyBub2RlLiAKKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBpbnZva2UgdGhlCisgKiAgICAgImdldEZpcnN0Q2hpbGQoKSIgbWV0aG9kLiAgIFRoZSBOb2RlTmFtZSByZXR1cm5lZAorICogICAgIHNob3VsZCBiZSAiI3RleHQiIG9yICJFTSIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNjk3MjczODgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE2OTcyNzM4ODwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlZ2V0Zmlyc3RjaGlsZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWdldGZpcnN0Y2hpbGQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGUgZmNoaWxkTm9kZTsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBmY2hpbGROb2RlID0gZW1wbG95ZWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkTmFtZSA9IGZjaGlsZE5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygiI3RleHQiLCBjaGlsZE5hbWUpKSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmaXJzdENoaWxkX3dfd2hpdGVzcGFjZSIsICIjdGV4dCIsIGNoaWxkTmFtZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJlbGVtZW50IiwgImZpcnN0Q2hpbGRfd29fd2hpdGVzcGFjZSIsICJlbSIsIGNoaWxkTmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZ2V0Zmlyc3RjaGlsZCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWdldGZpcnN0Y2hpbGQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVnZXRmaXJzdGNoaWxkbnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0Zmlyc3RjaGlsZG51bGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYjZiNWIxCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0Zmlyc3RjaGlsZG51bGwuamF2YQpAQCAtMCwwICsxLDg4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZXJlIGlzIG5vdCBhIGZpcnN0IGNoaWxkIHRoZW4gdGhlICJnZXRGaXJzdENoaWxkKCkiCisgKiAgICAgbWV0aG9kIHJldHVybnMgbnVsbC4KKyAqICAgICBSZXRyaWV2ZSB0aGUgdGV4dCBvZiB0aGUgZmlyc3QgImVtIiBlbGVtZW50IGFuZCBpbnZva2UgdGhlICJnZXRGaXJzdENoaWxkKCkiIG1ldGhvZC4gICBJdAorICogICAgIHNob3VsZCByZXR1cm4gbnVsbC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE2OTcyNzM4OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTY5NzI3Mzg4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDYiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVnZXRmaXJzdGNoaWxkbnVsbCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWdldGZpcnN0Y2hpbGRudWxsKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVtTGlzdDsKKyAgICAgIE5vZGUgZW1Ob2RlOworICAgICAgQ2hhcmFjdGVyRGF0YSBlbVRleHQ7CisgICAgICBOb2RlIG51bGxDaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbUxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtIik7CisgICAgICBlbU5vZGUgPSBlbUxpc3QuaXRlbSgwKTsKKyAgICAgIGVtVGV4dCA9IChDaGFyYWN0ZXJEYXRhKSBlbU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgbnVsbENoaWxkID0gZW1UZXh0LmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE51bGwoIm51bGxDaGlsZCIsIG51bGxDaGlsZCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVnZXRmaXJzdGNoaWxkbnVsbCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWdldGZpcnN0Y2hpbGRudWxsLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0bGFzdGNoaWxkLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVnZXRsYXN0Y2hpbGQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYTVkY2QzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0bGFzdGNoaWxkLmphdmEKQEAgLTAsMCArMSw4OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRMYXN0Q2hpbGQoKSIgbWV0aG9kIHJldHVybnMgdGhlIGxhc3QgY2hpbGQKKyAqICAgICBvZiB0aGlzIG5vZGUuIAorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGludm9rZSB0aGUKKyAqICAgICAiZ2V0TGFzdENoaWxkKCkiIG1ldGhvZC4gICBUaGUgTm9kZU5hbWUgcmV0dXJuZWQKKyAqICAgICBzaG91bGQgYmUgIiN0ZXh0Ii4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYxQUQwOUZCIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02MUFEMDlGQjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWdldGxhc3RjaGlsZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWdldGxhc3RjaGlsZChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZSBsY2hpbGROb2RlOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGxjaGlsZE5vZGUgPSBlbXBsb3llZU5vZGUuZ2V0TGFzdENoaWxkKCk7CisgICAgICBjaGlsZE5hbWUgPSBsY2hpbGROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIndoaXRlc3BhY2UiLCAiI3RleHQiLCBjaGlsZE5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZ2V0bGFzdGNoaWxkIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlZ2V0bGFzdGNoaWxkLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0bGFzdGNoaWxkbnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0bGFzdGNoaWxkbnVsbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAyYTZiMGEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVnZXRsYXN0Y2hpbGRudWxsLmphdmEKQEAgLTAsMCArMSw4OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBJZiB0aGVyZSBpcyBub3QgYSBsYXN0IGNoaWxkIHRoZW4gdGhlICJnZXRMYXN0Q2hpbGQoKSIKKyAqICAgICBtZXRob2QgcmV0dXJucyBudWxsLgorICogICBSZXRyaWV2ZSB0aGUgdGV4dCBvZiB0aGUgZmlyc3QgImVtIiBlbGVtZW50IGFuZCBpbnZva2UgdGhlICJnZXRGaXJzdENoaWxkKCkiIG1ldGhvZC4gICBJdAorICogICAgIHNob3VsZCByZXR1cm4gbnVsbC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYxQUQwOUZCIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02MUFEMDlGQjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlZ2V0bGFzdGNoaWxkbnVsbCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWdldGxhc3RjaGlsZG51bGwoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZW1MaXN0OworICAgICAgTm9kZSBlbU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGVtVGV4dDsKKyAgICAgIE5vZGUgbnVsbENoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVtTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW0iKTsKKyAgICAgIGVtTm9kZSA9IGVtTGlzdC5pdGVtKDApOworICAgICAgZW1UZXh0ID0gKENoYXJhY3RlckRhdGEpIGVtTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBudWxsQ2hpbGQgPSBlbVRleHQuZ2V0TGFzdENoaWxkKCk7CisgICAgICBhc3NlcnROdWxsKCJudWxsQ2hpbGQiLCBudWxsQ2hpbGQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZ2V0bGFzdGNoaWxkbnVsbCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWdldGxhc3RjaGlsZG51bGwuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVnZXRuZXh0c2libGluZy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0bmV4dHNpYmxpbmcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NWI4N2YyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0bmV4dHNpYmxpbmcuamF2YQpAQCAtMCwwICsxLDg5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldE5leHRTaWJsaW5nKCkiIG1ldGhvZCByZXR1cm5zIHRoZSBub2RlIGltbWVkaWF0ZWx5CisgKiAgICAgZm9sbG93aW5nIHRoaXMgbm9kZS4gCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIGZpcnN0IGNoaWxkIG9mIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kCisgKiAgICAgaW52b2tlIHRoZSAiZ2V0TmV4dFNpYmxpbmcoKSIgbWV0aG9kLiAgIEl0IHNob3VsZCByZXR1cm4KKyAqICAgICBhIG5vZGUgd2l0aCB0aGUgTm9kZU5hbWUgb2YgIiN0ZXh0Ii4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTZBQzU0QzJGIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02QUM1NEMyRjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWdldG5leHRzaWJsaW5nIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlZ2V0bmV4dHNpYmxpbmcoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtTm9kZTsKKyAgICAgIE5vZGUgbnNOb2RlOworICAgICAgU3RyaW5nIG5zTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW0iKTsKKyAgICAgIGVtTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBuc05vZGUgPSBlbU5vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKKyAgICAgIG5zTmFtZSA9IG5zTm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ3aGl0ZXNwYWNlIiwgIiN0ZXh0IiwgbnNOYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWdldG5leHRzaWJsaW5nIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlZ2V0bmV4dHNpYmxpbmcuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVnZXRuZXh0c2libGluZ251bGwuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWdldG5leHRzaWJsaW5nbnVsbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk0NzAxZjIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVnZXRuZXh0c2libGluZ251bGwuamF2YQpAQCAtMCwwICsxLDg5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBJZiB0aGVyZSBpcyBub3QgYSBub2RlIGltbWVkaWF0ZWx5IGZvbGxvd2luZyB0aGlzIG5vZGUgdGhlCisgKiAgICAgImdldE5leHRTaWJsaW5nKCkiIG1ldGhvZCByZXR1cm5zIG51bGwuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIGZpcnN0IGNoaWxkIG9mIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kCisgKiAgICAgaW52b2tlIHRoZSAiZ2V0TmV4dFNpYmxpbmcoKSIgbWV0aG9kLiAgIEl0IHNob3VsZAorICogICAgIGJlIHNldCB0byBudWxsLiAKKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTZBQzU0QzJGIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02QUM1NEMyRjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWdldG5leHRzaWJsaW5nbnVsbCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWdldG5leHRzaWJsaW5nbnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZSBsY05vZGU7CisgICAgICBOb2RlIG5zTm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGxjTm9kZSA9IGVtcGxveWVlTm9kZS5nZXRMYXN0Q2hpbGQoKTsKKyAgICAgIG5zTm9kZSA9IGxjTm9kZS5nZXROZXh0U2libGluZygpOworICAgICAgYXNzZXJ0TnVsbCgibm9kZUdldE5leHRTaWJsaW5nTnVsbEFzc2VydDEiLCBuc05vZGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZ2V0bmV4dHNpYmxpbmdudWxsIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlZ2V0bmV4dHNpYmxpbmdudWxsLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0b3duZXJkb2N1bWVudC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0b3duZXJkb2N1bWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMwOWNmZDkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVnZXRvd25lcmRvY3VtZW50LmphdmEKQEAgLTAsMCArMSw5MyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEV2YWx1YXRlIE5vZGUub3duZXJEb2N1bWVudCBvbiB0aGUgc2Vjb25kICJwIiBlbGVtZW50LgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjbm9kZS1vd25lckRvYyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjbm9kZS1vd25lckRvYzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjUxIj5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjUxPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlZ2V0b3duZXJkb2N1bWVudCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWdldG93bmVyZG9jdW1lbnQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGRvY05vZGU7CisgICAgICBEb2N1bWVudCBvd25lckRvY3VtZW50OworICAgICAgRWxlbWVudCBkb2NFbGVtZW50OworICAgICAgU3RyaW5nIGVsZW1lbnROYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwIik7CisgICAgICBkb2NOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIG93bmVyRG9jdW1lbnQgPSBkb2NOb2RlLmdldE93bmVyRG9jdW1lbnQoKTsKKyAgICAgIGRvY0VsZW1lbnQgPSBvd25lckRvY3VtZW50LmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgZWxlbWVudE5hbWUgPSBkb2NFbGVtZW50LmdldE5vZGVOYW1lKCk7CisgICAgICAKKyAgICAgIGlmICgoImltYWdlL3N2Zyt4bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoInN2Z05vZGVOYW1lIiwgInN2ZyIsIGVsZW1lbnROYW1lKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImVsZW1lbnQiLCAib3duZXJEb2NFbGVtVGFnTmFtZSIsICJodG1sIiwgZWxlbWVudE5hbWUpOworICAgICAgICB9CisgICAgICAgIAorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWdldG93bmVyZG9jdW1lbnQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVnZXRvd25lcmRvY3VtZW50LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0b3duZXJkb2N1bWVudG51bGwuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWdldG93bmVyZG9jdW1lbnRudWxsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGYxZjUwOAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWdldG93bmVyZG9jdW1lbnRudWxsLmphdmEKQEAgLTAsMCArMSw4MiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRPd25lckRvY3VtZW50KCkiIG1ldGhvZCByZXR1cm5zIG51bGwgaWYgdGhlIHRhcmdldAorICogICAgIG5vZGUgaXRzZWxmIGlzIGEgZG9jdW1lbnQuCisgKiAgICAgCisgKiAgICAgSW52b2tlIHRoZSAiZ2V0T3duZXJEb2N1bWVudCgpIiBtZXRob2Qgb24gdGhlIG1hc3RlciAKKyAqICAgICBkb2N1bWVudC4gICBUaGUgRG9jdW1lbnQgcmV0dXJuZWQgc2hvdWxkIGJlIG51bGwuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNub2RlLW93bmVyRG9jIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNub2RlLW93bmVyRG9jPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlZ2V0b3duZXJkb2N1bWVudG51bGwgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVnZXRvd25lcmRvY3VtZW50bnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBvd25lckRvY3VtZW50OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIG93bmVyRG9jdW1lbnQgPSBkb2MuZ2V0T3duZXJEb2N1bWVudCgpOworICAgICAgYXNzZXJ0TnVsbCgibm9kZUdldE93bmVyRG9jdW1lbnROdWxsQXNzZXJ0MSIsIG93bmVyRG9jdW1lbnQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZ2V0b3duZXJkb2N1bWVudG51bGwiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVnZXRvd25lcmRvY3VtZW50bnVsbC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWdldHByZXZpb3Vzc2libGluZy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0cHJldmlvdXNzaWJsaW5nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTBhZGM1ZgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWdldHByZXZpb3Vzc2libGluZy5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0UHJldmlvdXNTaWJsaW5nKCkiIG1ldGhvZCByZXR1cm5zIHRoZSBub2RlCisgKiAgICAgaW1tZWRpYXRlbHkgcHJlY2VkaW5nIHRoaXMgbm9kZS4gCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHNlY29uZCBjaGlsZCBvZiB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCAgICAKKyAqICAgICBpbnZva2UgdGhlICJnZXRQcmV2aW91c1NpYmxpbmcoKSIgbWV0aG9kLiAgIEl0IHNob3VsZAorICogICAgIHJldHVybiBhIG5vZGUgd2l0aCBhIE5vZGVOYW1lIG9mICIjdGV4dCIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NDBGQjNDOCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjQwRkIzQzg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVnZXRwcmV2aW91c3NpYmxpbmcgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVnZXRwcmV2aW91c3NpYmxpbmcoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgTm9kZSBwc05vZGU7CisgICAgICBTdHJpbmcgcHNOYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJzdHJvbmciKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIHBzTm9kZSA9IG5hbWVOb2RlLmdldFByZXZpb3VzU2libGluZygpOworICAgICAgcHNOYW1lID0gcHNOb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIndoaXRlc3BhY2UiLCAiI3RleHQiLCBwc05hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlZ2V0cHJldmlvdXNzaWJsaW5nIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlZ2V0cHJldmlvdXNzaWJsaW5nLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0cHJldmlvdXNzaWJsaW5nbnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlZ2V0cHJldmlvdXNzaWJsaW5nbnVsbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2NWQ0MWUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVnZXRwcmV2aW91c3NpYmxpbmdudWxsLmphdmEKQEAgLTAsMCArMSw4OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgSWYgdGhlcmUgaXMgbm90IGEgbm9kZSBpbW1lZGlhdGVseSBwcmVjZWRpbmcgdGhpcyBub2RlIHRoZQorICogICAgICJnZXRQcmV2aW91c1NpYmxpbmcoKSIgbWV0aG9kIHJldHVybnMgbnVsbC4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgY2hpbGQgb2YgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQKKyAqICAgICBpbnZva2UgdGhlICJnZXRQcmV2aW91c1NpYmxpbmcoKSIgbWV0aG9kLiAgIEl0IHNob3VsZAorICogICAgIGJlIHNldCB0byBudWxsLiAKKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTY0MEZCM0M4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NDBGQjNDODwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWdldHByZXZpb3Vzc2libGluZ251bGwgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVnZXRwcmV2aW91c3NpYmxpbmdudWxsKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlIGZjTm9kZTsKKyAgICAgIE5vZGUgcHNOb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgZmNOb2RlID0gZW1wbG95ZWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIHBzTm9kZSA9IGZjTm9kZS5nZXRQcmV2aW91c1NpYmxpbmcoKTsKKyAgICAgIGFzc2VydE51bGwoIm5vZGVHZXRQcmV2aW91c1NpYmxpbmdOdWxsQXNzZXJ0MSIsIHBzTm9kZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVnZXRwcmV2aW91c3NpYmxpbmdudWxsIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlZ2V0cHJldmlvdXNzaWJsaW5nbnVsbC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWhhc2NoaWxkbm9kZXMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWhhc2NoaWxkbm9kZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZDhiY2Y4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlaGFzY2hpbGRub2Rlcy5qYXZhCkBAIC0wLDAgKzEsODcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaGFzQ2hpbGROb2RlcygpIiBtZXRob2QgcmV0dXJucyB0cnVlIGlmIHRoZSBub2RlCisgKiAgICAgaGFzIGNoaWxkcmVuLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSByb290IG5vZGUoInN0YWZmIikgYW5kIGludm9rZSB0aGUgCisgKiAgICAgImhhc0NoaWxkTm9kZXMoKSIgbWV0aG9kLiAgIEl0IHNob3VsZCByZXR1cm4gdGhlIGJvb2xlYW4KKyAqICAgICB2YWx1ZSAidHJ1ZSIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04MTA1OTQxODciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTgxMDU5NDE4NzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWhhc2NoaWxkbm9kZXMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVoYXNjaGlsZG5vZGVzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgc3RhdGUgPSBlbXBsb3llZU5vZGUuaGFzQ2hpbGROb2RlcygpOworICAgICAgYXNzZXJ0VHJ1ZSgibm9kZUhhc0NoaWxkQXNzZXJ0MSIsIHN0YXRlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWhhc2NoaWxkbm9kZXMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVoYXNjaGlsZG5vZGVzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlaGFzY2hpbGRub2Rlc2ZhbHNlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVoYXNjaGlsZG5vZGVzZmFsc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYzE5ZjZiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlaGFzY2hpbGRub2Rlc2ZhbHNlLmphdmEKQEAgLTAsMCArMSw5MCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImhhc0NoaWxkTm9kZXMoKSIgbWV0aG9kIHJldHVybnMgZmFsc2UgaWYgdGhlIG5vZGUKKyAqICAgICBkb2VzIG5vdCBoYXZlIGFueSBjaGlsZHJlbi4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgdGV4dCBvZiB0aGUgZmlyc3QgImVtIiBlbGVtZW50IGFuZCBpbnZva2UgdGhlICJoYXNDaGlsZE5vZGVzKCkiIG1ldGhvZC4gICBJdAorICogICAgIHNob3VsZCByZXR1cm4gZmFsc2UuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNDUxNDYwOTg3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNDUxNDYwOTg3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTgxMDU5NDE4NyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODEwNTk0MTg3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDYiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVoYXNjaGlsZG5vZGVzZmFsc2UgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVoYXNjaGlsZG5vZGVzZmFsc2UoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZW1MaXN0OworICAgICAgTm9kZSBlbU5vZGU7CisgICAgICBDaGFyYWN0ZXJEYXRhIGVtVGV4dDsKKyAgICAgIGJvb2xlYW4gaGFzQ2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZW1MaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbSIpOworICAgICAgZW1Ob2RlID0gZW1MaXN0Lml0ZW0oMCk7CisgICAgICBlbVRleHQgPSAoQ2hhcmFjdGVyRGF0YSkgZW1Ob2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGhhc0NoaWxkID0gZW1UZXh0Lmhhc0NoaWxkTm9kZXMoKTsKKyAgICAgIGFzc2VydEZhbHNlKCJoYXNDaGlsZCIsIGhhc0NoaWxkKTsKK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWhhc2NoaWxkbm9kZXNmYWxzZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWhhc2NoaWxkbm9kZXNmYWxzZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlaW5zZXJ0YmVmb3JlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTk2MmY3YgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZS5qYXZhCkBAIC0wLDAgKzEsMTE5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLHJlZkNoaWxkKSIgbWV0aG9kIGluc2VydHMgdGhlCisgKiAgICAgbm9kZSAibmV3Q2hpbGQiIGJlZm9yZSB0aGUgbm9kZSAicmVmQ2hpbGQiLiAKKyAqICAgICAKKyAqICAgICBJbnNlcnQgYSBuZXdseSBjcmVhdGVkIEVsZW1lbnQgbm9kZSBiZWZvcmUgdGhlIHNlY29uZAorICogICAgIHN1cCBlbGVtZW50IGluIHRoZSBkb2N1bWVudCBhbmQgY2hlY2sgdGhlICJuZXdDaGlsZCIKKyAqICAgICBhbmQgInJlZkNoaWxkIiBhZnRlciBpbnNlcnRpb24gZm9yIGNvcnJlY3QgcGxhY2VtZW50LgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3Mjc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNjEiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNjE8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVpbnNlcnRiZWZvcmUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVpbnNlcnRiZWZvcmUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgTm9kZSByZWZDaGlsZDsKKyAgICAgIE5vZGUgbmV3Q2hpbGQ7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIE5vZGUgaW5zZXJ0ZWROb2RlOworICAgICAgamF2YS51dGlsLkxpc3QgYWN0dWFsID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkxpc3QgZXhwZWN0ZWQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgZXhwZWN0ZWQuYWRkKCJlbSIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJzdHJvbmciKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgiY29kZSIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJiciIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJzdXAiKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgidmFyIik7CisgICAgICBleHBlY3RlZC5hZGQoImFjcm9ueW0iKTsKKyAgICAgIAorICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInN1cCIpOworICAgICAgcmVmQ2hpbGQgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgZW1wbG95ZWVOb2RlID0gcmVmQ2hpbGQuZ2V0UGFyZW50Tm9kZSgpOworICAgICAgY2hpbGRMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIG5ld0NoaWxkID0gZG9jLmNyZWF0ZUVsZW1lbnQoImJyIik7CisgICAgICBpbnNlcnRlZE5vZGUgPSBlbXBsb3llZU5vZGUuaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLCByZWZDaGlsZCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA5MSA9IDA7IGluZGV4TjEwMDkxIDwgY2hpbGRMaXN0LmdldExlbmd0aCgpOyBpbmRleE4xMDA5MSsrKSB7CisgICAgICAgICAgY2hpbGQgPSAoTm9kZSkgY2hpbGRMaXN0Lml0ZW0oaW5kZXhOMTAwOTEpOworICAgIG5vZGVUeXBlID0gKGludCkgY2hpbGQuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygxLCBub2RlVHlwZSkpIHsKKyAgICAgICAgICBjaGlsZE5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgYWN0dWFsLmFkZChjaGlsZE5hbWUpOworICAgICAgfQorICAgICAgfQorICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImVsZW1lbnQiLCAibm9kZU5hbWVzIiwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWluc2VydGJlZm9yZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZWRvY2ZyYWdtZW50LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVpbnNlcnRiZWZvcmVkb2NmcmFnbWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1ZmIxMDIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVpbnNlcnRiZWZvcmVkb2NmcmFnbWVudC5qYXZhCkBAIC0wLDAgKzEsMTEyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZSAibmV3Q2hpbGQiIGlzIGEgRG9jdW1lbnRGcmFnbWVudCBvYmplY3QgdGhlbiBhbGwKKyAqICAgICBpdHMgY2hpbGRyZW4gYXJlIGluc2VydGVkIGluIHRoZSBzYW1lIG9yZGVyIGJlZm9yZSB0aGUKKyAqICAgICB0aGUgInJlZkNoaWxkIi4gCisgKiAgICAgCisgKiAgICAgQ3JlYXRlIGEgRG9jdW1lbnRGcmFnbWVudCBvYmplY3QgYW5kIHBvcHVsYXRlIGl0IHdpdGgKKyAqICAgICB0d28gRWxlbWVudCBub2Rlcy4gICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZAorICogICAgIGluc2VydCB0aGUgbmV3bHkgY3JlYXRlZCBEb2N1bWVudEZyYWdtZW50IGJlZm9yZSBpdHMKKyAqICAgICBmb3VydGggY2hpbGQuICAgVGhlIHNlY29uZCBlbXBsb3llZSBzaG91bGQgbm93IGhhdmUgdHdvCisgKiAgICAgZXh0cmEgY2hpbGRyZW4oIm5ld0NoaWxkMSIgYW5kICJuZXdDaGlsZDIiKSBhdCAKKyAqICAgICBwb3NpdGlvbnMgZm91cnRoIGFuZCBmaWZ0aCByZXNwZWN0aXZlbHkuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3MjciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlaW5zZXJ0YmVmb3JlZG9jZnJhZ21lbnQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVpbnNlcnRiZWZvcmVkb2NmcmFnbWVudChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIHJlZkNoaWxkOworICAgICAgRG9jdW1lbnRGcmFnbWVudCBuZXdkb2NGcmFnbWVudDsKKyAgICAgIE5vZGUgbmV3Q2hpbGQxOworICAgICAgTm9kZSBuZXdDaGlsZDI7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIE5vZGUgYXBwZW5kZWRDaGlsZDsKKyAgICAgIE5vZGUgaW5zZXJ0ZWROb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjaGlsZExpc3QgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgcmVmQ2hpbGQgPSBjaGlsZExpc3QuaXRlbSgzKTsKKyAgICAgIG5ld2RvY0ZyYWdtZW50ID0gZG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKKyAgICAgIG5ld0NoaWxkMSA9IGRvYy5jcmVhdGVFbGVtZW50KCJiciIpOworICAgICAgbmV3Q2hpbGQyID0gZG9jLmNyZWF0ZUVsZW1lbnQoImIiKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBuZXdkb2NGcmFnbWVudC5hcHBlbmRDaGlsZChuZXdDaGlsZDEpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IG5ld2RvY0ZyYWdtZW50LmFwcGVuZENoaWxkKG5ld0NoaWxkMik7CisgICAgICBpbnNlcnRlZE5vZGUgPSBlbXBsb3llZU5vZGUuaW5zZXJ0QmVmb3JlKG5ld2RvY0ZyYWdtZW50LCByZWZDaGlsZCk7CisgICAgICBjaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDMpOworICAgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJlbGVtZW50IiwgImNoaWxkTmFtZTMiLCAiYnIiLCBjaGlsZE5hbWUpOworICAgICAgICBjaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDQpOworICAgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJlbGVtZW50IiwgImNoaWxkTmFtZTQiLCAiYiIsIGNoaWxkTmFtZSk7CisgICAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZWRvY2ZyYWdtZW50IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlaW5zZXJ0YmVmb3JlZG9jZnJhZ21lbnQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVpbnNlcnRiZWZvcmVpbnZhbGlkbm9kZXR5cGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZWludmFsaWRub2RldHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRiOTU0YTQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVpbnNlcnRiZWZvcmVpbnZhbGlkbm9kZXR5cGUuamF2YQpAQCAtMCwwICsxLDEwOCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImluc2VydEJlZm9yZShuZXdDaGlsZCxyZWZDaGlsZCkiIG1ldGhvZCByYWlzZXMgYSAKKyAqICAgICBISUVSQVJDSFlfUkVRVUVTVF9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoaXMgbm9kZSBpcyBvZgorICogICAgIGEgdHlwZSB0aGF0IGRvZXMgbm90IGFsbG93IGNoaWxkcmVuIG9mIHRoZSB0eXBlICJuZXdDaGlsZCIKKyAqICAgICB0byBiZSBpbnNlcnRlZC4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgcm9vdCBub2RlIGFuZCBhdHRlbXB0IHRvIGluc2VydCBhIG5ld2x5CisgKiAgICAgY3JlYXRlZCBBdHRyIG5vZGUuICAgQW4gRWxlbWVudCBub2RlIGNhbm5vdCBoYXZlIGNoaWxkcmVuCisgKiAgICAgb2YgdGhlICJBdHRyIiB0eXBlLCB0aGVyZWZvcmUgdGhlIGRlc2lyZWQgZXhjZXB0aW9uCisgKiAgICAgc2hvdWxkIGJlIHJhaXNlZC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3Mjc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTk1MjI4MDcyNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTk1MjI4MDcyNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3MjciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTQwNiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTQwNjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWluc2VydGJlZm9yZWludmFsaWRub2RldHlwZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWluc2VydGJlZm9yZWludmFsaWRub2RldHlwZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgcm9vdE5vZGU7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHJlZkNoaWxkOworICAgICAgTm9kZSBpbnNlcnRlZE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdDaGlsZCA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoInRpdGxlIik7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgcmVmQ2hpbGQgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgcm9vdE5vZGUgPSAoRWxlbWVudCkgcmVmQ2hpbGQuZ2V0UGFyZW50Tm9kZSgpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnNlcnRlZE5vZGUgPSByb290Tm9kZS5pbnNlcnRCZWZvcmUobmV3Q2hpbGQsIHJlZkNoaWxkKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0hJRVJBUkNIWV9SRVFVRVNUX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlaW5zZXJ0YmVmb3JlaW52YWxpZG5vZGV0eXBlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlaW5zZXJ0YmVmb3JlaW52YWxpZG5vZGV0eXBlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlaW5zZXJ0YmVmb3JlbmV3Y2hpbGRkaWZmZG9jdW1lbnQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZW5ld2NoaWxkZGlmZmRvY3VtZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTk3MTNhMwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZW5ld2NoaWxkZGlmZmRvY3VtZW50LmphdmEKQEAgLTAsMCArMSwxMDkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJpbnNlcnRCZWZvcmUobmV3Q2hpbGQscmVmQ2hpbGQpIiBtZXRob2QgcmFpc2VzIGEgCisgKiAgICAgV1JPTkdfRE9DVU1FTlRfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgIm5ld0NoaWxkIiB3YXMKKyAqICAgICBjcmVhdGVkIGZyb20gYSBkaWZmZXJlbnQgZG9jdW1lbnQgdGhhbiB0aGUgb25lIHRoYXQgCisgKiAgICAgY3JlYXRlZCB0aGlzIG5vZGUuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgYXR0ZW1wdCB0byBpbnNlcnQgYSBuZXcgCisgKiAgICAgY2hpbGQgdGhhdCB3YXMgY3JlYXRlZCBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlCisgKiAgICAgb25lIHRoYXQgY3JlYXRlZCB0aGUgc2Vjb25kIGVtcGxveWVlLiAgIEFuIGF0dGVtcHQgdG8KKyAqICAgICBpbnNlcnQgc3VjaCBhIGNoaWxkIHNob3VsZCByYWlzZSB0aGUgZGVzaXJlZCBleGNlcHRpb24uCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nV1JPTkdfRE9DVU1FTlRfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nV1JPTkdfRE9DVU1FTlRfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC05NTIyODA3MjcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdXUk9OR19ET0NVTUVOVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC05NTIyODA3MjcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdXUk9OR19ET0NVTUVOVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3Mjc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NyI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWluc2VydGJlZm9yZW5ld2NoaWxkZGlmZmRvY3VtZW50IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlaW5zZXJ0YmVmb3JlbmV3Y2hpbGRkaWZmZG9jdW1lbnQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jMTsKKyAgICAgIERvY3VtZW50IGRvYzI7CisgICAgICBOb2RlIHJlZkNoaWxkOworICAgICAgTm9kZSBuZXdDaGlsZDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbGVtZW50Tm9kZTsKKyAgICAgIE5vZGUgaW5zZXJ0ZWROb2RlOworICAgICAgZG9jMSA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2MyID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgbmV3Q2hpbGQgPSBkb2MxLmNyZWF0ZUVsZW1lbnQoImJyIik7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYzIuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKKyAgICAgIGVsZW1lbnROb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIHJlZkNoaWxkID0gZWxlbWVudE5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnNlcnRlZE5vZGUgPSBlbGVtZW50Tm9kZS5pbnNlcnRCZWZvcmUobmV3Q2hpbGQsIHJlZkNoaWxkKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X1dST05HX0RPQ1VNRU5UX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlaW5zZXJ0YmVmb3JlbmV3Y2hpbGRkaWZmZG9jdW1lbnQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVpbnNlcnRiZWZvcmVuZXdjaGlsZGRpZmZkb2N1bWVudC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZW5ld2NoaWxkZXhpc3RzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVpbnNlcnRiZWZvcmVuZXdjaGlsZGV4aXN0cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhZDcxZDAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVpbnNlcnRiZWZvcmVuZXdjaGlsZGV4aXN0cy5qYXZhCkBAIC0wLDAgKzEsMTE5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZSAibmV3Q2hpbGQiIGlzIGFscmVhZHkgaW4gdGhlIHRyZWUsIHRoZQorICogICAgICJpbnNlcnRCZWZvcmUobmV3Q2hpbGQscmVmQ2hpbGQpIiBtZXRob2QgbXVzdCBmaXJzdAorICogICAgIHJlbW92ZSBpdCBiZWZvcmUgdGhlIGluc2VydGlvbiB0YWtlcyBwbGFjZS4KKyAqICAgICAKKyAqICAgICBJbnNlcnQgYSBub2RlIEVsZW1lbnQgKCJlbSIpIHRoYXQgaXMgYWxyZWFkeQorICogICAgIHByZXNlbnQgaW4gdGhlIHRyZWUuICAgVGhlIGV4aXN0aW5nIG5vZGUgc2hvdWxkIGJlIAorICogICAgIHJlbW92ZWQgZmlyc3QgYW5kIHRoZSBuZXcgb25lIGluc2VydGVkLiAgIFRoZSBub2RlIGlzCisgKiAgICAgaW5zZXJ0ZWQgYXQgYSBkaWZmZXJlbnQgcG9zaXRpb24gaW4gdGhlIHRyZWUgdG8gYXNzdXJlCisgKiAgICAgdGhhdCBpdCB3YXMgaW5kZWVkIGluc2VydGVkLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3Mjc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWluc2VydGJlZm9yZW5ld2NoaWxkZXhpc3RzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlaW5zZXJ0YmVmb3JlbmV3Y2hpbGRleGlzdHMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgTm9kZSByZWZDaGlsZDsKKyAgICAgIE5vZGUgbmV3Q2hpbGQ7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIE5vZGUgaW5zZXJ0ZWROb2RlOworICAgICAgamF2YS51dGlsLkxpc3QgZXhwZWN0ZWQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgZXhwZWN0ZWQuYWRkKCJzdHJvbmciKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgiY29kZSIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJzdXAiKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgidmFyIik7CisgICAgICBleHBlY3RlZC5hZGQoImVtIik7CisgICAgICBleHBlY3RlZC5hZGQoImFjcm9ueW0iKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkxpc3QgcmVzdWx0ID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIAorICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjaGlsZExpc3QgPSAoKEVsZW1lbnQpIC8qTm9kZSAqL2VtcGxveWVlTm9kZSkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIioiKTsKKyAgICAgIHJlZkNoaWxkID0gY2hpbGRMaXN0Lml0ZW0oNSk7CisgICAgICBuZXdDaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDApOworICAgICAgaW5zZXJ0ZWROb2RlID0gZW1wbG95ZWVOb2RlLmluc2VydEJlZm9yZShuZXdDaGlsZCwgcmVmQ2hpbGQpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwOEMgPSAwOyBpbmRleE4xMDA4QyA8IGNoaWxkTGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwOEMrKykgeworICAgICAgICAgIGNoaWxkID0gKE5vZGUpIGNoaWxkTGlzdC5pdGVtKGluZGV4TjEwMDhDKTsKKyAgICBub2RlVHlwZSA9IChpbnQpIGNoaWxkLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoMSwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIHJlc3VsdC5hZGQoY2hpbGROYW1lKTsKKyAgICAgIH0KKyAgICAgIH0KKyAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJlbGVtZW50IiwgImNoaWxkTmFtZXMiLCBleHBlY3RlZCwgcmVzdWx0KTsKKyAgICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlaW5zZXJ0YmVmb3JlbmV3Y2hpbGRleGlzdHMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVpbnNlcnRiZWZvcmVuZXdjaGlsZGV4aXN0cy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZW5vZGVhbmNlc3Rvci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlaW5zZXJ0YmVmb3Jlbm9kZWFuY2VzdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGQ2OWJkOAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZW5vZGVhbmNlc3Rvci5qYXZhCkBAIC0wLDAgKzEsMTA2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImluc2VydEJlZm9yZShuZXdDaGlsZCxyZWZDaGlsZCkiIG1ldGhvZCByYWlzZXMgYSAKKyAqICAgICBISUVSQVJDSFlfUkVRVUVTVF9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBub2RlIHRvIGJlCisgKiAgICAgaW5zZXJ0ZWQgaXMgb25lIG9mIHRoaXMgbm9kZXMgYW5jZXN0b3JzLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGF0dGVtcHQgdG8gaW5zZXJ0IGEKKyAqICAgICBub2RlIHRoYXQgaXMgb25lIG9mIGl0cyBhbmNlc3RvcnMocm9vdCBub2RlKS4gICBBbiAKKyAqICAgICBhdHRlbXB0IHRvIGluc2VydCBzdWNoIGEgbm9kZSBzaG91bGQgcmFpc2UgdGhlIAorICogICAgIGRlc2lyZWQgZXhjZXB0aW9uLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3MjciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtOTUyMjgwNzI3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSElFUkFSQ0hZX1JFUVVFU1RfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtOTUyMjgwNzI3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSElFUkFSQ0hZX1JFUVVFU1RfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlaW5zZXJ0YmVmb3Jlbm9kZWFuY2VzdG9yIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlaW5zZXJ0YmVmb3Jlbm9kZWFuY2VzdG9yKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBuZXdDaGlsZDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIHJlZkNoaWxkOworICAgICAgTm9kZSBpbnNlcnRlZE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdDaGlsZCA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgY2hpbGRMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIHJlZkNoaWxkID0gY2hpbGRMaXN0Lml0ZW0oMCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluc2VydGVkTm9kZSA9IGVtcGxveWVlTm9kZS5pbnNlcnRCZWZvcmUobmV3Q2hpbGQsIHJlZkNoaWxkKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0hJRVJBUkNIWV9SRVFVRVNUX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlaW5zZXJ0YmVmb3Jlbm9kZWFuY2VzdG9yIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlaW5zZXJ0YmVmb3Jlbm9kZWFuY2VzdG9yLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlaW5zZXJ0YmVmb3Jlbm9kZW5hbWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZW5vZGVuYW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWFkYTk1MAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZW5vZGVuYW1lLmphdmEKQEAgLTAsMCArMSw5OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImluc2VydEJlZm9yZShuZXdDaGlsZCxyZWZjaGlsZCkiIG1ldGhvZCByZXR1cm5zIAorICogICAgIHRoZSBub2RlIGJlaW5nIGluc2VydGVkLgorICogICAgIAorICogICAgIEluc2VydCBhbiBFbGVtZW50IG5vZGUgYmVmb3JlIHRoZSBmb3VydGgKKyAqICAgICBjaGlsZCBvZiB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBjaGVjayB0aGUgbm9kZQorICogICAgIHJldHVybmVkIGZyb20gdGhlICJpbnNlcnRCZWZvcmUobmV3Q2hpbGQscmVmQ2hpbGQpIiAKKyAqICAgICBtZXRob2QuICAgVGhlIG5vZGUgcmV0dXJuZWQgc2hvdWxkIGJlICJuZXdDaGlsZCIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDciPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVpbnNlcnRiZWZvcmVub2RlbmFtZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWluc2VydGJlZm9yZW5vZGVuYW1lKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgcmVmQ2hpbGQ7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZSBpbnNlcnRlZE5vZGU7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjaGlsZExpc3QgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgcmVmQ2hpbGQgPSBjaGlsZExpc3QuaXRlbSgzKTsKKyAgICAgIG5ld0NoaWxkID0gZG9jLmNyZWF0ZUVsZW1lbnQoImJyIik7CisgICAgICBpbnNlcnRlZE5vZGUgPSBlbXBsb3llZU5vZGUuaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLCByZWZDaGlsZCk7CisgICAgICBjaGlsZE5hbWUgPSBpbnNlcnRlZE5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJlbGVtZW50IiwgIm5vZGVOYW1lIiwgImJyIiwgY2hpbGROYW1lKTsKKyAgICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlaW5zZXJ0YmVmb3Jlbm9kZW5hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVpbnNlcnRiZWZvcmVub2RlbmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZXJlZmNoaWxkbm9uZXhpc3RlbnQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZXJlZmNoaWxkbm9uZXhpc3RlbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOTIyNTk1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlaW5zZXJ0YmVmb3JlcmVmY2hpbGRub25leGlzdGVudC5qYXZhCkBAIC0wLDAgKzEsMTA2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLHJlZkNoaWxkKSIgbWV0aG9kIHJhaXNlcyBhIAorICogICAgIE5PVF9GT1VORF9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSByZWZlcmVuY2UgY2hpbGQgaXMKKyAqICAgICBub3QgYSBjaGlsZCBvZiB0aGlzIG5vZGUuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgYXR0ZW1wdCB0byBpbnNlcnQgYQorICogICAgIG5ldyBub2RlIGJlZm9yZSBhIHJlZmVyZW5jZSBub2RlIHRoYXQgaXMgbm90IGEgY2hpbGQKKyAqICAgICBvZiB0aGlzIG5vZGUuICAgQW4gYXR0ZW1wdCB0byBpbnNlcnQgYmVmb3JlIGEgbm9uIGNoaWxkCisgKiAgICAgbm9kZSBzaG91bGQgcmFpc2UgdGhlIGRlc2lyZWQgZXhjZXB0aW9uLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PVF9GT1VORF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT1RfRk9VTkRfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC05NTIyODA3MjcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT1RfRk9VTkRfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtOTUyMjgwNzI3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9UX0ZPVU5EX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3MjciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVpbnNlcnRiZWZvcmVyZWZjaGlsZG5vbmV4aXN0ZW50IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlaW5zZXJ0YmVmb3JlcmVmY2hpbGRub25leGlzdGVudChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGUgcmVmQ2hpbGQ7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVsZW1lbnROb2RlOworICAgICAgTm9kZSBpbnNlcnRlZE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdDaGlsZCA9IGRvYy5jcmVhdGVFbGVtZW50KCJiciIpOworICAgICAgcmVmQ2hpbGQgPSBkb2MuY3JlYXRlRWxlbWVudCgiYiIpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKKyAgICAgIGVsZW1lbnROb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zZXJ0ZWROb2RlID0gZWxlbWVudE5vZGUuaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLCByZWZDaGlsZCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9UX0ZPVU5EX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlaW5zZXJ0YmVmb3JlcmVmY2hpbGRub25leGlzdGVudCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWluc2VydGJlZm9yZXJlZmNoaWxkbm9uZXhpc3RlbnQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVpbnNlcnRiZWZvcmVyZWZjaGlsZG51bGwuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZXJlZmNoaWxkbnVsbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQzOTY4NGIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVpbnNlcnRiZWZvcmVyZWZjaGlsZG51bGwuamF2YQpAQCAtMCwwICsxLDEwMiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBJZiB0aGUgInJlZkNoaWxkIiBpcyBudWxsIHRoZW4gdGhlCisgKiAgICAgImluc2VydEJlZm9yZShuZXdDaGlsZCxyZWZDaGlsZCkiIG1ldGhvZCBpbnNlcnRzIHRoZQorICogICAgIG5vZGUgIm5ld0NoaWxkIiBhdCB0aGUgZW5kIG9mIHRoZSBsaXN0IG9mIGNoaWxkcmVuLiAKKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBpbnZva2UgdGhlCisgKiAgICAgImluc2VydEJlZm9yZShuZXdDaGlsZCxyZWZDaGlsZCkiIG1ldGhvZCB3aXRoCisgKiAgICAgcmVmQ2hpbGQ9bnVsbC4gICBTaW5jZSAicmVmQ2hpbGQiIGlzIG51bGwgdGhlICJuZXdDaGlsZCIKKyAqICAgICBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdC4gICBUaGUgbGFzdCBpdGVtCisgKiAgICAgaW4gdGhlIGxpc3QgaXMgY2hlY2tlZCBhZnRlciBpbnNlcnRpb24uICAgVGhlIGxhc3QgRWxlbWVudAorICogICAgIG5vZGUgb2YgdGhlIGxpc3Qgc2hvdWxkIGJlICJuZXdDaGlsZCIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3MjciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlaW5zZXJ0YmVmb3JlcmVmY2hpbGRudWxsIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlaW5zZXJ0YmVmb3JlcmVmY2hpbGRudWxsKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgcmVmQ2hpbGQgPSBudWxsOworCisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBOb2RlIGluc2VydGVkTm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgY2hpbGRMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIG5ld0NoaWxkID0gZG9jLmNyZWF0ZUVsZW1lbnQoImJyIik7CisgICAgICBpbnNlcnRlZE5vZGUgPSBlbXBsb3llZU5vZGUuaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLCByZWZDaGlsZCk7CisgICAgICBjaGlsZCA9IGVtcGxveWVlTm9kZS5nZXRMYXN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkTmFtZSA9IGNoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHNBdXRvQ2FzZSgiZWxlbWVudCIsICJub2RlTmFtZSIsICJiciIsIGNoaWxkTmFtZSk7CisgICAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZWluc2VydGJlZm9yZXJlZmNoaWxkbnVsbCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWluc2VydGJlZm9yZXJlZmNoaWxkbnVsbC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWxpc3RpbmRleGVxdWFsemVyby5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlbGlzdGluZGV4ZXF1YWx6ZXJvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTU1NmQ0NgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWxpc3RpbmRleGVxdWFsemVyby5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgQ3JlYXRlIGEgbGlzdCBvZiBhbGwgdGhlIGNoaWxkcmVuIGVsZW1lbnRzIG9mIHRoZSB0aGlyZAorICogICAgZW1wbG95ZWUgYW5kIGFjY2VzcyBpdHMgZmlyc3QgY2hpbGQgYnkgdXNpbmcgYW4gaW5kZXgKKyAqICAgIG9mIDAuICBUaGlzIHNob3VsZCByZXN1bHQgaW4gdGhlIHdoaXRzcGFjZSBiZWZvcmUgImVtIiBiZWluZworICogICAgc2VsZWN0ZWQgKGVtIHdoZW4gaWdub3Jpbmcgd2hpdGVzcGFjZSkuICAKKyAqICAgIEZ1cnRoZXIgd2UgZXZhbHVhdGUgaXRzIGNvbnRlbnQoYnkgdXNpbmcKKyAqICAgIHRoZSAiZ2V0Tm9kZU5hbWUoKSIgbWV0aG9kKSB0byBlbnN1cmUgdGhlIHByb3BlcgorICogICAgZWxlbWVudCB3YXMgYWNjZXNzZWQuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NDQzNzcxMzYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0NDM3NzEzNjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlbGlzdGluZGV4ZXF1YWx6ZXJvIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlbGlzdGluZGV4ZXF1YWx6ZXJvKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBlbXBsb3llZUxpc3Q7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIGludCBsZW5ndGg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBlbXBsb3llZUxpc3QgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgbGVuZ3RoID0gKGludCkgZW1wbG95ZWVMaXN0LmdldExlbmd0aCgpOworICAgICAgY2hpbGQgPSBlbXBsb3llZUxpc3QuaXRlbSgwKTsKKyAgICAgIGNoaWxkTmFtZSA9IGNoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoMTMsIGxlbmd0aCkpIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoImNoaWxkTmFtZV93X3doaXRlc3BhY2UiLCAiI3RleHQiLCBjaGlsZE5hbWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHNBdXRvQ2FzZSgiZWxlbWVudCIsICJjaGlsZE5hbWVfd29fd2hpdGVzcGFjZSIsICJlbSIsIGNoaWxkTmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlbGlzdGluZGV4ZXF1YWx6ZXJvIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlbGlzdGluZGV4ZXF1YWx6ZXJvLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlbGlzdGluZGV4Z2V0bGVuZ3RoLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVsaXN0aW5kZXhnZXRsZW5ndGguamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOTY1ZDllCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlbGlzdGluZGV4Z2V0bGVuZ3RoLmphdmEKQEAgLTAsMCArMSw5NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldExlbmd0aCgpIiBtZXRob2QgcmV0dXJucyB0aGUgbnVtYmVyIG9mIG5vZGVzCisgKiAgICBpbiB0aGUgbGlzdC4KKyAqICAgIAorICogICAgQ3JlYXRlIGEgbGlzdCBvZiBhbGwgdGhlIGNoaWxkcmVuIGVsZW1lbnRzIG9mIHRoZSB0aGlyZAorICogICAgZW1wbG95ZWUgYW5kIGludm9rZSB0aGUgImdldExlbmd0aCgpIiBtZXRob2QuIAorICogICAgSXQgc2hvdWxkIGNvbnRhaW4gdGhlIHZhbHVlIDEzLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjAzNTEwMzM3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMDM1MTAzMzc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWxpc3RpbmRleGdldGxlbmd0aCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWxpc3RpbmRleGdldGxlbmd0aChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZUxpc3QgZW1wbG95ZWVMaXN0OworICAgICAgaW50IGxlbmd0aDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIGVtcGxveWVlTGlzdCA9IGVtcGxveWVlTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBsZW5ndGggPSAoaW50KSBlbXBsb3llZUxpc3QuZ2V0TGVuZ3RoKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoNiwgbGVuZ3RoKSkgeworICAgICAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoX3dvX3NwYWNlIiwgNiwgbGVuZ3RoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJsZW5ndGhfd19zcGFjZSIsIDEzLCBsZW5ndGgpOworICAgICAgfQorICAgICAgICAKKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVsaXN0aW5kZXhnZXRsZW5ndGgiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVsaXN0aW5kZXhnZXRsZW5ndGguY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVsaXN0aW5kZXhnZXRsZW5ndGhvZmVtcHR5bGlzdC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlbGlzdGluZGV4Z2V0bGVuZ3Rob2ZlbXB0eWxpc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NWI5MDg4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlbGlzdGluZGV4Z2V0bGVuZ3Rob2ZlbXB0eWxpc3QuamF2YQpAQCAtMCwwICsxLDkzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0TGVuZ3RoKCkiIG1ldGhvZCByZXR1cm5zIHRoZSBudW1iZXIgb2Ygbm9kZXMKKyAqICAgIGluIHRoZSBsaXN0LihUZXN0IGZvciBFTVBUWSBsaXN0KQorICogICAgCisgKiAgICBDcmVhdGUgYSBsaXN0IG9mIGFsbCB0aGUgY2hpbGRyZW4gb2YgdGhlIFRleHQgbm9kZSAKKyAqICAgIGluc2lkZSB0aGUgZmlyc3QgY2hpbGQgb2YgdGhlIHRoaXJkIGVtcGxveWVlIGFuZAorICogICAgaW52b2tlIHRoZSAiZ2V0TGVuZ3RoKCkiIG1ldGhvZC4gICBJdCBzaG91bGQgY29udGFpbgorICogICAgdGhlIHZhbHVlIDAuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMDM1MTAzMzciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIwMzUxMDMzNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlbGlzdGluZGV4Z2V0bGVuZ3Rob2ZlbXB0eWxpc3QgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVsaXN0aW5kZXhnZXRsZW5ndGhvZmVtcHR5bGlzdChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbUxpc3Q7CisgICAgICBOb2RlIGVtTm9kZTsKKyAgICAgIE5vZGUgdGV4dE5vZGU7CisgICAgICBOb2RlTGlzdCB0ZXh0TGlzdDsKKyAgICAgIGludCBsZW5ndGg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZW1MaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbSIpOworICAgICAgZW1Ob2RlID0gZW1MaXN0Lml0ZW0oMik7CisgICAgICB0ZXh0Tm9kZSA9IGVtTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICB0ZXh0TGlzdCA9IHRleHROb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGxlbmd0aCA9IChpbnQpIHRleHRMaXN0LmdldExlbmd0aCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJsZW5ndGgiLCAwLCBsZW5ndGgpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlbGlzdGluZGV4Z2V0bGVuZ3Rob2ZlbXB0eWxpc3QiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVsaXN0aW5kZXhnZXRsZW5ndGhvZmVtcHR5bGlzdC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWxpc3RpbmRleG5vdHplcm8uamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWxpc3RpbmRleG5vdHplcm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NGM5YzgyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlbGlzdGluZGV4bm90emVyby5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBpdGVtcyBpbiB0aGUgbGlzdCBhcmUgYWNjZXNzaWJsZSB2aWEgYW4gaW50ZWdyYWwKKyAqICAgIGluZGV4IHN0YXJ0aW5nIGZyb20gemVyby4KKyAqICAgIChJbmRleCBub3QgZXF1YWwgMCkKKyAqICAgIAorICogICAgQ3JlYXRlIGEgbGlzdCBvZiBhbGwgdGhlIGNoaWxkcmVuIGVsZW1lbnRzIG9mIHRoZSB0aGlyZAorICogICAgZW1wbG95ZWUgYW5kIGFjY2VzcyBpdHMgZm91cnRoIGNoaWxkIGJ5IHVzaW5nIGFuIGluZGV4CisgKiAgICBvZiAzIGFuZCBjYWxsaW5nIGdldE5vZGVOYW1lKCkgd2hpY2ggc2hvdWxkIHJldHVybgorICogICAgInN0cm9uZyIgKG5vIHdoaXRlc3BhY2UpICBvciAiI3RleHQiICh3aXRoIHdoaXRlc3BhY2UpLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODQ0Mzc3MTM2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NDQzNzcxMzY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZWxpc3RpbmRleG5vdHplcm8gZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVsaXN0aW5kZXhub3R6ZXJvKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBlbXBsb3llZUxpc3Q7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIGVtcGxveWVlTGlzdCA9IGVtcGxveWVlTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBjaGlsZCA9IGVtcGxveWVlTGlzdC5pdGVtKDMpOworICAgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygiI3RleHQiLCBjaGlsZE5hbWUpKSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJjaGlsZE5hbWVfc3BhY2UiLCAiI3RleHQiLCBjaGlsZE5hbWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHNBdXRvQ2FzZSgiZWxlbWVudCIsICJjaGlsZE5hbWVfc3Ryb25nIiwgInN0cm9uZyIsIGNoaWxkTmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlbGlzdGluZGV4bm90emVybyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWxpc3RpbmRleG5vdHplcm8uY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVsaXN0cmV0dXJuZmlyc3RpdGVtLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVsaXN0cmV0dXJuZmlyc3RpdGVtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzYzMzIwNAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWxpc3RyZXR1cm5maXJzdGl0ZW0uamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgQ3JlYXRlIGEgbGlzdCBvZiBhbGwgdGhlIGNoaWxkcmVuIGVsZW1lbnRzIG9mIHRoZSB0aGlyZAorICogICAgZW1wbG95ZWUgYW5kIGFjY2VzcyBpdHMgZmlyc3QgY2hpbGQgYnkgaW52b2tpbmcgdGhlIAorICogICAgIml0ZW0oaW5kZXgpIiBtZXRob2Qgd2l0aCBhbiBpbmRleD0wLiAgVGhpcyBzaG91bGQKKyAqICAgIHJlc3VsdCBpbiBub2RlIHdpdGggYSBub2RlTmFtZSBvZiAiI3RleHQiIG9yICJlbSIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NDQzNzcxMzYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0NDM3NzEzNjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlbGlzdHJldHVybmZpcnN0aXRlbSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWxpc3RyZXR1cm5maXJzdGl0ZW0oZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGVtcGxveWVlTGlzdDsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgZW1wbG95ZWVMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGNoaWxkID0gZW1wbG95ZWVMaXN0Lml0ZW0oMCk7CisgICAgICBjaGlsZE5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKCIjdGV4dCIsIGNoaWxkTmFtZSkpIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lX3dfc3BhY2UiLCAiI3RleHQiLCBjaGlsZE5hbWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHNBdXRvQ2FzZSgiZWxlbWVudCIsICJub2RlTmFtZV93b19zcGFjZSIsICJlbSIsIGNoaWxkTmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlbGlzdHJldHVybmZpcnN0aXRlbSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWxpc3RyZXR1cm5maXJzdGl0ZW0uY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVsaXN0cmV0dXJubGFzdGl0ZW0uamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZWxpc3RyZXR1cm5sYXN0aXRlbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVlYjAzZGMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVsaXN0cmV0dXJubGFzdGl0ZW0uamF2YQpAQCAtMCwwICsxLDEwMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgIENyZWF0ZSBhIGxpc3Qgb2YgYWxsIHRoZSBjaGlsZHJlbiBlbGVtZW50cyBvZiB0aGUgdGhpcmQKKyAqICAgIGVtcGxveWVlIGFuZCBhY2Nlc3MgaXRzIGxhc3QgY2hpbGQgYnkgaW52b2tpbmcgdGhlIAorICogICAgIml0ZW0oaW5kZXgpIiBtZXRob2Qgd2l0aCBhbiBpbmRleD1sZW5ndGgtMS4gIFRoaXMgc2hvdWxkCisgKiAgICByZXN1bHQgaW4gbm9kZSB3aXRoIG5vZGVOYW1lPSIjdGV4dCIgb3IgYWNyb255bS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0NDM3NzEzNiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODQ0Mzc3MTM2PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDYiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVsaXN0cmV0dXJubGFzdGl0ZW0gZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVsaXN0cmV0dXJubGFzdGl0ZW0oZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGVtcGxveWVlTGlzdDsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgaW50IGluZGV4OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgZW1wbG95ZWVMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGluZGV4ID0gKGludCkgZW1wbG95ZWVMaXN0LmdldExlbmd0aCgpOworICAgICAgaW5kZXggLT0gMTsKKyAgICAgIGNoaWxkID0gZW1wbG95ZWVMaXN0Lml0ZW0oKChpbnQpIC8qaW50ICovaW5kZXgpKTsKKyAgICAgIGNoaWxkTmFtZSA9IGNoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoMTIsIGluZGV4KSkgeworICAgICAgICAgIGFzc2VydEVxdWFscygibGFzdE5vZGVOYW1lX3dfd2hpdGVzcGFjZSIsICIjdGV4dCIsIGNoaWxkTmFtZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJlbGVtZW50IiwgImxhc3ROb2RlTmFtZSIsICJhY3JvbnltIiwgY2hpbGROYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmRleCIsIDUsIGluZGV4KTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlbGlzdHJldHVybmxhc3RpdGVtIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlbGlzdHJldHVybmxhc3RpdGVtLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlbGlzdHRyYXZlcnNlbGlzdC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlbGlzdHRyYXZlcnNlbGlzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI5YjE3NjIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVsaXN0dHJhdmVyc2VsaXN0LmphdmEKQEAgLTAsMCArMSwxMTQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIHJhbmdlIG9mIHZhbGlkIGNoaWxkIG5vZGUgaW5kaWNlcyBpcyAwIHRocnUgbGVuZ3RoIC0xCisgKiAgICAKKyAqICAgIENyZWF0ZSBhIGxpc3Qgb2YgYWxsIHRoZSBjaGlsZHJlbiBlbGVtZW50cyBvZiB0aGUgdGhpcmQKKyAqICAgIGVtcGxveWVlIGFuZCB0cmF2ZXJzZSB0aGUgbGlzdCBmcm9tIGluZGV4PTAgdGhydQorICogICAgbGVuZ3RoIC0xLiAgICAgCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMDM1MTAzMzciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIwMzUxMDMzNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NDQzNzcxMzYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0NDM3NzEzNjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlbGlzdHRyYXZlcnNlbGlzdCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZWxpc3R0cmF2ZXJzZWxpc3QoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGVtcGxveWVlTGlzdDsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgamF2YS51dGlsLkxpc3QgcmVzdWx0ID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkxpc3QgZXhwZWN0ZWQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgZXhwZWN0ZWQuYWRkKCJlbSIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJzdHJvbmciKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgiY29kZSIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJzdXAiKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgidmFyIik7CisgICAgICBleHBlY3RlZC5hZGQoImFjcm9ueW0iKTsKKyAgICAgIAorICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgZW1wbG95ZWVMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDczID0gMDsgaW5kZXhOMTAwNzMgPCBlbXBsb3llZUxpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDczKyspIHsKKyAgICAgICAgICBjaGlsZCA9IChOb2RlKSBlbXBsb3llZUxpc3QuaXRlbShpbmRleE4xMDA3Myk7CisgICAgbm9kZVR5cGUgPSAoaW50KSBjaGlsZC5nZXROb2RlVHlwZSgpOworICAgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygxLCBub2RlVHlwZSkpIHsKKyAgICAgICAgICByZXN1bHQuYWRkKGNoaWxkTmFtZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICAgIGFzc2VydEVxdWFscygidGV4dE5vZGVUeXBlIiwgMywgbm9kZVR5cGUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0Tm9kZU5hbWUiLCAiI3RleHQiLCBjaGlsZE5hbWUpOworICAgICAgfQorICAgICAgICAKKyAgICAgIH0KKyAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJlbGVtZW50IiwgIm5vZGVOYW1lcyIsIGV4cGVjdGVkLCByZXN1bHQpOworICAgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVsaXN0dHJhdmVyc2VsaXN0IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlbGlzdHRyYXZlcnNlbGlzdC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXBhcmVudG5vZGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXBhcmVudG5vZGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NzA3MGY1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlcGFyZW50bm9kZS5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0UGFyZW50Tm9kZSgpIiBtZXRob2QgcmV0dXJucyB0aGUgcGFyZW50CisgKiAgICAgb2YgdGhpcyBub2RlLiAKKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBpbnZva2UgdGhlIAorICogICAgICJnZXRQYXJlbnROb2RlKCkiIG1ldGhvZCBvbiB0aGlzIG5vZGUuICAgSXQgc2hvdWxkCisgKiAgICAgYmUgc2V0IHRvICJib2R5Ii4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwNjAxODQzMTciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwNjAxODQzMTc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVwYXJlbnRub2RlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlcGFyZW50bm9kZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZSBwYXJlbnROb2RlOworICAgICAgU3RyaW5nIHBhcmVudE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBwYXJlbnROb2RlID0gZW1wbG95ZWVOb2RlLmdldFBhcmVudE5vZGUoKTsKKyAgICAgIHBhcmVudE5hbWUgPSBwYXJlbnROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHNBdXRvQ2FzZSgiZWxlbWVudCIsICJwYXJlbnROb2RlTmFtZSIsICJib2R5IiwgcGFyZW50TmFtZSk7CisgICAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZXBhcmVudG5vZGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVwYXJlbnRub2RlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlcGFyZW50bm9kZW51bGwuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXBhcmVudG5vZGVudWxsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDg5NmI4MQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXBhcmVudG5vZGVudWxsLmphdmEKQEAgLTAsMCArMSw4NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRQYXJlbnROb2RlKCkiIG1ldGhvZCBpbnZva2VkIG9uIGEgbm9kZSB0aGF0IGhhcworICogICAgIGp1c3QgYmVlbiBjcmVhdGVkIGFuZCBub3QgeWV0IGFkZGVkIHRvIHRoZSB0cmVlIGlzIG51bGwuIAorICogICAgIENyZWF0ZSBhIG5ldyAiZW1wbG95ZWUiIEVsZW1lbnQgbm9kZSB1c2luZyB0aGUgICAgICAgICAgICAgCisgKiAgICAgImNyZWF0ZUVsZW1lbnQobmFtZSkiIG1ldGhvZCBmcm9tIHRoZSBEb2N1bWVudCBpbnRlcmZhY2UuCisgKiAgICAgU2luY2UgdGhpcyBuZXcgbm9kZSBoYXMgbm90IHlldCBiZWVuIGFkZGVkIHRvIHRoZSB0cmVlLAorICogICAgIHRoZSAiZ2V0UGFyZW50Tm9kZSgpIiBtZXRob2Qgd2lsbCByZXR1cm4gbnVsbC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwNjAxODQzMTciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwNjAxODQzMTc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NyI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZXBhcmVudG5vZGVudWxsIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlcGFyZW50bm9kZW51bGwoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBjcmVhdGVkTm9kZTsKKyAgICAgIE5vZGUgcGFyZW50Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBjcmVhdGVkTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50KCJiciIpOworICAgICAgcGFyZW50Tm9kZSA9IGNyZWF0ZWROb2RlLmdldFBhcmVudE5vZGUoKTsKKyAgICAgIGFzc2VydE51bGwoInBhcmVudE5vZGUiLCBwYXJlbnROb2RlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZXBhcmVudG5vZGVudWxsIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlcGFyZW50bm9kZW51bGwuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVyZW1vdmVjaGlsZC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlcmVtb3ZlY2hpbGQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOTA1ZjQ2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlcmVtb3ZlY2hpbGQuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAicmVtb3ZlQ2hpbGQob2xkQ2hpbGQpIiBtZXRob2QgcmVtb3ZlcyB0aGUgY2hpbGQgbm9kZQorICogICAgIGluZGljYXRlZCBieSAib2xkQ2hpbGQiIGZyb20gdGhlIGxpc3Qgb2YgY2hpbGRyZW4gYW5kCisgKiAgICAgcmV0dXJucyBpdC4gCisgKiAgICAgCisgKiAgICAgUmVtb3ZlIHRoZSBmaXJzdCBlbXBsb3llZSBieSBpbnZva2luZyB0aGUKKyAqICAgICAicmVtb3ZlQ2hpbGQob2xkQ2hpbGQpIiBtZXRob2QgYW4gY2hlY2tpbmcgdGhlCisgKiAgICAgbm9kZSByZXR1cm5lZCBieSB0aGUgImdldFBhcmVudE5vZGUoKSIgbWV0aG9kLiAgIEl0CisgKiAgICAgc2hvdWxkIGJlIHNldCB0byBudWxsLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTczNDgzNDA2NiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTczNDgzNDA2NjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlcmVtb3ZlY2hpbGQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVyZW1vdmVjaGlsZChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgcm9vdE5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIGNoaWxkVG9SZW1vdmU7CisgICAgICBOb2RlIHJlbW92ZWRDaGlsZDsKKyAgICAgIE5vZGUgcGFyZW50Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIHJvb3ROb2RlID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgY2hpbGRMaXN0ID0gcm9vdE5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgY2hpbGRUb1JlbW92ZSA9IGNoaWxkTGlzdC5pdGVtKDEpOworICAgICAgcmVtb3ZlZENoaWxkID0gcm9vdE5vZGUucmVtb3ZlQ2hpbGQoY2hpbGRUb1JlbW92ZSk7CisgICAgICBwYXJlbnROb2RlID0gcmVtb3ZlZENoaWxkLmdldFBhcmVudE5vZGUoKTsKKyAgICAgIGFzc2VydE51bGwoInBhcmVudE5vZGVOdWxsIiwgcGFyZW50Tm9kZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVyZW1vdmVjaGlsZCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZXJlbW92ZWNoaWxkLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlcmVtb3ZlY2hpbGRnZXRub2RlbmFtZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlcmVtb3ZlY2hpbGRnZXRub2RlbmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI4ZTkwNDEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVyZW1vdmVjaGlsZGdldG5vZGVuYW1lLmphdmEKQEAgLTAsMCArMSw5OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlbW92ZUNoaWxkKG9sZENoaWxkKSIgbWV0aG9kIHJldHVybnMgCisgKiAgICAgdGhlIG5vZGUgYmVpbmcgcmVtb3ZlZC4KKyAqICAgICAKKyAqICAgICBSZW1vdmUgdGhlIGZpcnN0IGNoaWxkIG9mIHRoZSBzZWNvbmQgZW1wbG95ZWUgCisgKiAgICAgYW5kIGNoZWNrIHRoZSBOb2RlTmFtZSByZXR1cm5lZCBieSB0aGUgCisgKiAgICAgInJlbW92ZUNoaWxkKG9sZENoaWxkKSIgbWV0aG9kLiAgIFRoZSByZXR1cm5lZCBub2RlCisgKiAgICAgc2hvdWxkIGhhdmUgYSBOb2RlTmFtZSBlcXVhbCB0byAiI3RleHQiLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDYiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVyZW1vdmVjaGlsZGdldG5vZGVuYW1lIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlcmVtb3ZlY2hpbGRnZXRub2RlbmFtZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIG9sZENoaWxkOworICAgICAgTm9kZSByZW1vdmVkQ2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgU3RyaW5nIG9sZE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTGlzdCA9IGVtcGxveWVlTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBvbGRDaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDApOworICAgICAgb2xkTmFtZSA9IG9sZENoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICByZW1vdmVkQ2hpbGQgPSBlbXBsb3llZU5vZGUucmVtb3ZlQ2hpbGQob2xkQ2hpbGQpOworICAgICAgYXNzZXJ0Tm90TnVsbCgibm90bnVsbCIsIHJlbW92ZWRDaGlsZCk7CisgICAgICBjaGlsZE5hbWUgPSByZW1vdmVkQ2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZU5hbWUiLCBvbGROYW1lLCBjaGlsZE5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlcmVtb3ZlY2hpbGRnZXRub2RlbmFtZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZXJlbW92ZWNoaWxkZ2V0bm9kZW5hbWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVyZW1vdmVjaGlsZG5vZGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXJlbW92ZWNoaWxkbm9kZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEzMjg4NmMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVyZW1vdmVjaGlsZG5vZGUuamF2YQpAQCAtMCwwICsxLDEyNCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlbW92ZUNoaWxkKG9sZENoaWxkKSIgbWV0aG9kIHJlbW92ZXMgdGhlIG5vZGUKKyAqICAgICBpbmRpY2F0ZWQgYnkgIm9sZENoaWxkIi4gCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHNlY29uZCBwIGVsZW1lbnQgYW5kIHJlbW92ZSBpdHMgZmlyc3QgY2hpbGQuCisgKiAgICAgQWZ0ZXIgdGhlIHJlbW92YWwsIHRoZSBzZWNvbmQgcCBlbGVtZW50IHNob3VsZCBoYXZlIDUgZWxlbWVudAorICogICAgIGNoaWxkcmVuIGFuZCB0aGUgZmlyc3QgY2hpbGQgc2hvdWxkIG5vdyBiZSB0aGUgY2hpbGQKKyAqICAgICB0aGF0IHVzZWQgdG8gYmUgYXQgdGhlIHNlY29uZCBwb3NpdGlvbiBpbiB0aGUgbGlzdC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MzQ4MzQwNjYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MzQ4MzQwNjY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NiI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZXJlbW92ZWNoaWxkbm9kZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZXJlbW92ZWNoaWxkbm9kZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZUxpc3QgZW1MaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIG9sZENoaWxkOworICAgICAgTm9kZSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBpbnQgbGVuZ3RoOworICAgICAgTm9kZSByZW1vdmVkQ2hpbGQ7CisgICAgICBTdHJpbmcgcmVtb3ZlZE5hbWU7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBqYXZhLnV0aWwuTGlzdCBleHBlY3RlZCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZC5hZGQoInN0cm9uZyIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJjb2RlIik7CisgICAgICBleHBlY3RlZC5hZGQoInN1cCIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJ2YXIiKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgiYWNyb255bSIpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuTGlzdCBhY3R1YWwgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTGlzdCA9IGVtcGxveWVlTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBlbUxpc3QgPSAoKEVsZW1lbnQpIC8qTm9kZSAqL2VtcGxveWVlTm9kZSkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtIik7CisgICAgICBvbGRDaGlsZCA9IGVtTGlzdC5pdGVtKDApOworICAgICAgcmVtb3ZlZENoaWxkID0gZW1wbG95ZWVOb2RlLnJlbW92ZUNoaWxkKG9sZENoaWxkKTsKKyAgICAgIHJlbW92ZWROYW1lID0gcmVtb3ZlZENoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHNBdXRvQ2FzZSgiZWxlbWVudCIsICJyZW1vdmVkTmFtZSIsICJlbSIsIHJlbW92ZWROYW1lKTsKKyAgICAgICAgZm9yIChpbnQgaW5kZXhOMTAwOTggPSAwOyBpbmRleE4xMDA5OCA8IGNoaWxkTGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwOTgrKykgeworICAgICAgICAgIGNoaWxkID0gKE5vZGUpIGNoaWxkTGlzdC5pdGVtKGluZGV4TjEwMDk4KTsKKyAgICBub2RlVHlwZSA9IChpbnQpIGNoaWxkLmdldE5vZGVUeXBlKCk7CisgICAgICBjaGlsZE5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDEsIG5vZGVUeXBlKSkgeworICAgICAgICAgIGFjdHVhbC5hZGQoY2hpbGROYW1lKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0Tm9kZVR5cGUiLCAzLCBub2RlVHlwZSk7CisgICAgICBhc3NlcnRFcXVhbHMoInRleHROb2RlTmFtZSIsICIjdGV4dCIsIGNoaWxkTmFtZSk7CisgICAgICB9CisgICAgICAgIAorICAgICAgfQorICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImVsZW1lbnQiLCAiY2hpbGROYW1lcyIsIGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVyZW1vdmVjaGlsZG5vZGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVyZW1vdmVjaGlsZG5vZGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVyZW1vdmVjaGlsZG9sZGNoaWxkbm9uZXhpc3RlbnQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXJlbW92ZWNoaWxkb2xkY2hpbGRub25leGlzdGVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIyNDIyYjIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVyZW1vdmVjaGlsZG9sZGNoaWxkbm9uZXhpc3RlbnQuamF2YQpAQCAtMCwwICsxLDEwMiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlbW92ZUNoaWxkKG9sZENoaWxkKSIgbWV0aG9kIHJhaXNlcyBhIAorICogICAgIE5PVF9GT1VORF9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBvbGQgY2hpbGQgaXMKKyAqICAgICBub3QgYSBjaGlsZCBvZiB0aGlzIG5vZGUuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgYXR0ZW1wdCB0byByZW1vdmUgYQorICogICAgIG5vZGUgdGhhdCBpcyBub3Qgb25lIG9mIGl0cyBjaGlsZHJlbi4gICBBbiBhdHRlbXB0IHRvCisgKiAgICAgcmVtb3ZlIHN1Y2ggYSBub2RlIHNob3VsZCByYWlzZSB0aGUgZGVzaXJlZCBleGNlcHRpb24uCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9UX0ZPVU5EX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PVF9GT1VORF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTczNDgzNDA2NiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTczNDgzNDA2NjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMTczNDgzNDA2NicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PVF9GT1VORF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0xNzM0ODM0MDY2JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9UX0ZPVU5EX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDciPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVyZW1vdmVjaGlsZG9sZGNoaWxkbm9uZXhpc3RlbnQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVyZW1vdmVjaGlsZG9sZGNoaWxkbm9uZXhpc3RlbnQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIG9sZENoaWxkOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVsZW1lbnROb2RlOworICAgICAgTm9kZSByZW1vdmVkQ2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBvbGRDaGlsZCA9IGRvYy5jcmVhdGVFbGVtZW50KCJiciIpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKKyAgICAgIGVsZW1lbnROb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVtb3ZlZENoaWxkID0gZWxlbWVudE5vZGUucmVtb3ZlQ2hpbGQob2xkQ2hpbGQpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT1RfRk9VTkRfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9GT1VORF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZXJlbW92ZWNoaWxkb2xkY2hpbGRub25leGlzdGVudCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZXJlbW92ZWNoaWxkb2xkY2hpbGRub25leGlzdGVudC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXJlcGxhY2VjaGlsZC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlcmVwbGFjZWNoaWxkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDkxNTZjNQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXJlcGxhY2VjaGlsZC5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZXBsYWNlQ2hpbGQobmV3Q2hpbGQsb2xkQ2hpbGQpIiBtZXRob2QgcmVwbGFjZXMgCisgKiAgICAgdGhlIG5vZGUgIm9sZENoaWxkIiB3aXRoIHRoZSBub2RlICJuZXdDaGlsZCIuIAorICogICAgIAorICogICAgIFJlcGxhY2UgdGhlIGZpcnN0IGVsZW1lbnQgb2YgdGhlIHNlY29uZCBlbXBsb3llZSB3aXRoCisgKiAgICAgYSBuZXdseSBjcmVhdGVkIEVsZW1lbnQgbm9kZS4gICBDaGVjayB0aGUgZmlyc3QgcG9zaXRpb24KKyAqICAgICBhZnRlciB0aGUgcmVwbGFjZW1lbnQgb3BlcmF0aW9uIGlzIGNvbXBsZXRlZC4gICBUaGUgbmV3CisgKiAgICAgRWxlbWVudCBzaG91bGQgYmUgIm5ld0NoaWxkIi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDciPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGVyZXBsYWNlY2hpbGQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVyZXBsYWNlY2hpbGQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgTm9kZSBvbGRDaGlsZDsKKyAgICAgIE5vZGUgbmV3Q2hpbGQ7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIE5vZGUgcmVwbGFjZWROb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjaGlsZExpc3QgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgb2xkQ2hpbGQgPSBjaGlsZExpc3QuaXRlbSgwKTsKKyAgICAgIG5ld0NoaWxkID0gZG9jLmNyZWF0ZUVsZW1lbnQoImJyIik7CisgICAgICByZXBsYWNlZE5vZGUgPSBlbXBsb3llZU5vZGUucmVwbGFjZUNoaWxkKG5ld0NoaWxkLCBvbGRDaGlsZCk7CisgICAgICBjaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDApOworICAgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFsc0F1dG9DYXNlKCJlbGVtZW50IiwgIm5vZGVOYW1lIiwgImJyIiwgY2hpbGROYW1lKTsKKyAgICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlcmVwbGFjZWNoaWxkIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlcmVwbGFjZWNoaWxkLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlcmVwbGFjZWNoaWxkaW52YWxpZG5vZGV0eXBlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVyZXBsYWNlY2hpbGRpbnZhbGlkbm9kZXR5cGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NWM2MzcxCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlcmVwbGFjZWNoaWxkaW52YWxpZG5vZGV0eXBlLmphdmEKQEAgLTAsMCArMSwxMDggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZXBsYWNlQ2hpbGQobmV3Q2hpbGQsb2xkQ2hpbGQpIiBtZXRob2QgcmFpc2VzIGEgCisgKiAgICAgSElFUkFSQ0hZX1JFUVVFU1RfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGlzIG5vZGUgaXMgb2YKKyAqICAgICBhIHR5cGUgdGhhdCBkb2VzIG5vdCBhbGxvdyBjaGlsZHJlbiBvZiB0aGUgdHlwZSAibmV3Q2hpbGQiCisgKiAgICAgdG8gYmUgaW5zZXJ0ZWQuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHJvb3Qgbm9kZSBhbmQgYXR0ZW1wdCB0byByZXBsYWNlIAorICogICAgIG9uZSBvZiBpdHMgY2hpbGRyZW4gd2l0aCBhIG5ld2x5IGNyZWF0ZWQgQXR0ciBub2RlLgorICogICAgIEFuIEVsZW1lbnQgbm9kZSBjYW5ub3QgaGF2ZSBjaGlsZHJlbiBvZiB0aGUgIkF0dHIiCisgKiAgICAgdHlwZSwgdGhlcmVmb3JlIHRoZSBkZXNpcmVkIGV4Y2VwdGlvbiBzaG91bGQgYmUgcmFpc2VkLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNzg1ODg3MzA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSElFUkFSQ0hZX1JFUVVFU1RfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNzg1ODg3MzA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSElFUkFSQ0hZX1JFUVVFU1RfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDciPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9NDA2Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9NDA2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlcmVwbGFjZWNoaWxkaW52YWxpZG5vZGV0eXBlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlcmVwbGFjZWNoaWxkaW52YWxpZG5vZGV0eXBlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCByb290Tm9kZTsKKyAgICAgIE5vZGUgbmV3Q2hpbGQ7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgb2xkQ2hpbGQ7CisgICAgICBOb2RlIHJlcGxhY2VkQ2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdDaGlsZCA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoImxhbmciKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwIik7CisgICAgICBvbGRDaGlsZCA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICByb290Tm9kZSA9IChFbGVtZW50KSBvbGRDaGlsZC5nZXRQYXJlbnROb2RlKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcGxhY2VkQ2hpbGQgPSByb290Tm9kZS5yZXBsYWNlQ2hpbGQobmV3Q2hpbGQsIG9sZENoaWxkKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0hJRVJBUkNIWV9SRVFVRVNUX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlcmVwbGFjZWNoaWxkaW52YWxpZG5vZGV0eXBlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlcmVwbGFjZWNoaWxkaW52YWxpZG5vZGV0eXBlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlcmVwbGFjZWNoaWxkbmV3Y2hpbGRkaWZmZG9jdW1lbnQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXJlcGxhY2VjaGlsZG5ld2NoaWxkZGlmZmRvY3VtZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGRjZGVlZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXJlcGxhY2VjaGlsZG5ld2NoaWxkZGlmZmRvY3VtZW50LmphdmEKQEAgLTAsMCArMSwxMDkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZXBsYWNlQ2hpbGQobmV3Q2hpbGQsb2xkQ2hpbGQpIiBtZXRob2QgcmFpc2VzIGEgCisgKiAgICAgV1JPTkdfRE9DVU1FTlRfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgIm5ld0NoaWxkIiB3YXMKKyAqICAgICBjcmVhdGVkIGZyb20gYSBkaWZmZXJlbnQgZG9jdW1lbnQgdGhhbiB0aGUgb25lIHRoYXQgCisgKiAgICAgY3JlYXRlZCB0aGlzIG5vZGUuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgYXR0ZW1wdCB0byByZXBsYWNlIG9uZSAgIAorICogICAgIG9mIGl0cyBjaGlsZHJlbiB3aXRoIGEgbm9kZSBjcmVhdGVkIGZyb20gYSBkaWZmZXJlbnQgCisgKiAgICAgZG9jdW1lbnQuICAgQW4gYXR0ZW1wdCB0byBtYWtlIHN1Y2ggYSByZXBsYWNlbWVudCAKKyAqICAgICBzaG91bGQgcmFpc2UgdGhlIGRlc2lyZWQgZXhjZXB0aW9uLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PVF9GT1VORF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT1RfRk9VTkRfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC03ODU4ODczMDcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT1RfRk9VTkRfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNzg1ODg3MzA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9UX0ZPVU5EX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlcmVwbGFjZWNoaWxkbmV3Y2hpbGRkaWZmZG9jdW1lbnQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVyZXBsYWNlY2hpbGRuZXdjaGlsZGRpZmZkb2N1bWVudChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2MxOworICAgICAgRG9jdW1lbnQgZG9jMjsKKyAgICAgIE5vZGUgb2xkQ2hpbGQ7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVsZW1lbnROb2RlOworICAgICAgTm9kZSByZXBsYWNlZENoaWxkOworICAgICAgZG9jMSA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2MyID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgbmV3Q2hpbGQgPSBkb2MxLmNyZWF0ZUVsZW1lbnQoImJyIik7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYzIuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKKyAgICAgIGVsZW1lbnROb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIG9sZENoaWxkID0gZWxlbWVudE5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXBsYWNlZENoaWxkID0gZWxlbWVudE5vZGUucmVwbGFjZUNoaWxkKG5ld0NoaWxkLCBvbGRDaGlsZCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19XUk9OR19ET0NVTUVOVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZXJlcGxhY2VjaGlsZG5ld2NoaWxkZGlmZmRvY3VtZW50IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlcmVwbGFjZWNoaWxkbmV3Y2hpbGRkaWZmZG9jdW1lbnQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVyZXBsYWNlY2hpbGRuZXdjaGlsZGV4aXN0cy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlcmVwbGFjZWNoaWxkbmV3Y2hpbGRleGlzdHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OWJkM2ViCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlcmVwbGFjZWNoaWxkbmV3Y2hpbGRleGlzdHMuamF2YQpAQCAtMCwwICsxLDEyMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBJZiB0aGUgIm5ld0NoaWxkIiBpcyBhbHJlYWR5IGluIHRoZSB0cmVlLCBpdCBpcyBmaXJzdAorICogICAgIHJlbW92ZWQgYmVmb3JlIHRoZSBuZXcgb25lIGlzIGFkZGVkLgorICogICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHNlY29uZCAicCIgYW5kIHJlcGxhY2UgImFjcm9ueW0iIHdpdGggaXRzICJlbSIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlcmVwbGFjZWNoaWxkbmV3Y2hpbGRleGlzdHMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVyZXBsYWNlY2hpbGRuZXdjaGlsZGV4aXN0cyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIG9sZENoaWxkID0gbnVsbDsKKworICAgICAgTm9kZSBuZXdDaGlsZCA9IG51bGw7CisKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgTm9kZSBjaGlsZE5vZGU7CisgICAgICBqYXZhLnV0aWwuTGlzdCBhY3R1YWwgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuTGlzdCBleHBlY3RlZCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZC5hZGQoInN0cm9uZyIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJjb2RlIik7CisgICAgICBleHBlY3RlZC5hZGQoInN1cCIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJ2YXIiKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgiZW0iKTsKKyAgICAgIAorICAgICAgTm9kZSByZXBsYWNlZENoaWxkOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInAiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjaGlsZExpc3QgPSAoKEVsZW1lbnQpIC8qTm9kZSAqL2VtcGxveWVlTm9kZSkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIioiKTsKKyAgICAgIG5ld0NoaWxkID0gY2hpbGRMaXN0Lml0ZW0oMCk7CisgICAgICBvbGRDaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDUpOworICAgICAgcmVwbGFjZWRDaGlsZCA9IGVtcGxveWVlTm9kZS5yZXBsYWNlQ2hpbGQobmV3Q2hpbGQsIG9sZENoaWxkKTsKKyAgICAgIGFzc2VydFNhbWUoInJldHVybl92YWx1ZV9zYW1lIiwgb2xkQ2hpbGQsIHJlcGxhY2VkQ2hpbGQpOworZm9yIChpbnQgaW5kZXhOMTAwOTQgPSAwOyBpbmRleE4xMDA5NCA8IGNoaWxkTGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwOTQrKykgeworICAgICAgICAgIGNoaWxkTm9kZSA9IChOb2RlKSBjaGlsZExpc3QuaXRlbShpbmRleE4xMDA5NCk7CisgICAgY2hpbGROYW1lID0gY2hpbGROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGNoaWxkTm9kZS5nZXROb2RlVHlwZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDEsIG5vZGVUeXBlKSkgeworICAgICAgICAgIGFjdHVhbC5hZGQoY2hpbGROYW1lKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0Tm9kZVR5cGUiLCAzLCBub2RlVHlwZSk7CisgICAgICBhc3NlcnRFcXVhbHMoInRleHROb2RlTmFtZSIsICIjdGV4dCIsIGNoaWxkTmFtZSk7CisgICAgICB9CisgICAgICAgIAorICAgICAgfQorICAgICAgYXNzZXJ0RXF1YWxzQXV0b0Nhc2UoImVsZW1lbnQiLCAiY2hpbGROYW1lcyIsIGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVyZXBsYWNlY2hpbGRuZXdjaGlsZGV4aXN0cyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZXJlcGxhY2VjaGlsZG5ld2NoaWxkZXhpc3RzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlcmVwbGFjZWNoaWxkbm9kZWFuY2VzdG9yLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVyZXBsYWNlY2hpbGRub2RlYW5jZXN0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZGE3NjA2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlcmVwbGFjZWNoaWxkbm9kZWFuY2VzdG9yLmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAicmVwbGFjZUNoaWxkKG5ld0NoaWxkLG9sZENoaWxkKSIgbWV0aG9kIHJhaXNlcyBhIAorICogICAgIEhJRVJBUkNIWV9SRVFVRVNUX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIG5vZGUgdG8gcHV0CisgKiAgICAgaW4gaXMgb25lIG9mIHRoaXMgbm9kZSdzIGFuY2VzdG9ycy4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBhdHRlbXB0IHRvIHJlcGxhY2UKKyAqICAgICBvbmUgb2YgaXRzIGNoaWxkcmVuIHdpdGggYW4gYW5jZXN0b3Igbm9kZShyb290IG5vZGUpLgorICogICAgIEFuIGF0dGVtcHQgdG8gbWFrZSBzdWNoIGEgcmVwbGFjZW1lbnQgc2hvdWxkIHJhaXNlIHRoZSAKKyAqICAgICBkZXNpcmVkIGV4Y2VwdGlvbi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTc4NTg4NzMwNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTc4NTg4NzMwNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZXJlcGxhY2VjaGlsZG5vZGVhbmNlc3RvciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZXJlcGxhY2VjaGlsZG5vZGVhbmNlc3RvcihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGUgbmV3Q2hpbGQ7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgTm9kZSBvbGRDaGlsZDsKKyAgICAgIE5vZGUgcmVwbGFjZWROb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgbmV3Q2hpbGQgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTGlzdCA9IGVtcGxveWVlTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBvbGRDaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDApOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXBsYWNlZE5vZGUgPSBlbXBsb3llZU5vZGUucmVwbGFjZUNoaWxkKG5ld0NoaWxkLCBvbGRDaGlsZCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19ISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZXJlcGxhY2VjaGlsZG5vZGVhbmNlc3RvciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZXJlcGxhY2VjaGlsZG5vZGVhbmNlc3Rvci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXJlcGxhY2VjaGlsZG5vZGVuYW1lLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVyZXBsYWNlY2hpbGRub2RlbmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5NDdkMzkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGVyZXBsYWNlY2hpbGRub2RlbmFtZS5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZXBsYWNlQ2hpbGQobmV3Q2hpbGQsb2xkQ2hpbGQpIiBtZXRob2QgcmV0dXJucyAKKyAqICAgICB0aGUgbm9kZSBiZWluZyByZXBsYWNlZC4KKyAqICAgICAKKyAqICAgICBSZXBsYWNlIHRoZSBzZWNvbmQgRWxlbWVudCBvZiB0aGUgc2Vjb25kIGVtcGxveWVlIHdpdGgKKyAqICAgICBhIG5ld2x5IGNyZWF0ZWQgbm9kZSBFbGVtZW50IGFuZCBjaGVjayB0aGUgTm9kZU5hbWUgCisgKiAgICAgcmV0dXJuZWQgYnkgdGhlICJyZXBsYWNlQ2hpbGQobmV3Q2hpbGQsb2xkQ2hpbGQpIgorICogICAgIG1ldGhvZC4gICBUaGUgcmV0dXJuZWQgbm9kZSBzaG91bGQgaGF2ZSBhIE5vZGVOYW1lIGVxdWFsCisgKiAgICAgdG8gImVtIi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NyI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZXJlcGxhY2VjaGlsZG5vZGVuYW1lIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RlcmVwbGFjZWNoaWxkbm9kZW5hbWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgTm9kZSBvbGRDaGlsZDsKKyAgICAgIE5vZGUgbmV3Q2hpbGQ7CisgICAgICBOb2RlIHJlcGxhY2VkTm9kZTsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTGlzdCA9ICgoRWxlbWVudCkgLypOb2RlICovZW1wbG95ZWVOb2RlKS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW0iKTsKKyAgICAgIG9sZENoaWxkID0gY2hpbGRMaXN0Lml0ZW0oMCk7CisgICAgICBuZXdDaGlsZCA9IGRvYy5jcmVhdGVFbGVtZW50KCJiciIpOworICAgICAgcmVwbGFjZWROb2RlID0gZW1wbG95ZWVOb2RlLnJlcGxhY2VDaGlsZChuZXdDaGlsZCwgb2xkQ2hpbGQpOworICAgICAgY2hpbGROYW1lID0gcmVwbGFjZWROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHNBdXRvQ2FzZSgiZWxlbWVudCIsICJyZXBsYWNlZE5vZGVOYW1lIiwgImVtIiwgY2hpbGROYW1lKTsKKyAgICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RlcmVwbGFjZWNoaWxkbm9kZW5hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGVyZXBsYWNlY2hpbGRub2RlbmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXJlcGxhY2VjaGlsZG9sZGNoaWxkbm9uZXhpc3RlbnQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXJlcGxhY2VjaGlsZG9sZGNoaWxkbm9uZXhpc3RlbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYmJkYTI3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RlcmVwbGFjZWNoaWxkb2xkY2hpbGRub25leGlzdGVudC5qYXZhCkBAIC0wLDAgKzEsMTA0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAicmVwbGFjZUNoaWxkKG5ld0NoaWxkLG9sZENoaWxkKSIgbWV0aG9kIHJhaXNlcyBhIAorICogICAgIE5PVF9GT1VORF9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBvbGQgY2hpbGQgaXMKKyAqICAgICBub3QgYSBjaGlsZCBvZiB0aGlzIG5vZGUuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgYXR0ZW1wdCB0byByZXBsYWNlIGEKKyAqICAgICBub2RlIHRoYXQgaXMgbm90IG9uZSBvZiBpdHMgY2hpbGRyZW4uICAgQW4gYXR0ZW1wdCB0bworICogICAgIHJlcGxhY2Ugc3VjaCBhIG5vZGUgc2hvdWxkIHJhaXNlIHRoZSBkZXNpcmVkIGV4Y2VwdGlvbi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT1RfRk9VTkRfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9UX0ZPVU5EX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNzg1ODg3MzA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9UX0ZPVU5EX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTc4NTg4NzMwNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PVF9GT1VORF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NyI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0NzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZXJlcGxhY2VjaGlsZG9sZGNoaWxkbm9uZXhpc3RlbnQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVyZXBsYWNlY2hpbGRvbGRjaGlsZG5vbmV4aXN0ZW50KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBvbGRDaGlsZDsKKyAgICAgIE5vZGUgbmV3Q2hpbGQ7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZWxlbWVudE5vZGU7CisgICAgICBOb2RlIHJlcGxhY2VkTm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld0NoaWxkID0gZG9jLmNyZWF0ZUVsZW1lbnQoImJyIik7CisgICAgICBvbGRDaGlsZCA9IGRvYy5jcmVhdGVFbGVtZW50KCJiIik7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgicCIpOworICAgICAgZWxlbWVudE5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXBsYWNlZE5vZGUgPSBlbGVtZW50Tm9kZS5yZXBsYWNlQ2hpbGQobmV3Q2hpbGQsIG9sZENoaWxkKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT1RfRk9VTkRfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGVyZXBsYWNlY2hpbGRvbGRjaGlsZG5vbmV4aXN0ZW50IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlcmVwbGFjZWNoaWxkb2xkY2hpbGRub25leGlzdGVudC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXRleHRub2RlYXR0cmlidXRlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGV0ZXh0bm9kZWF0dHJpYnV0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA3NDQyMDQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGV0ZXh0bm9kZWF0dHJpYnV0ZS5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogVGhlICJnZXRBdHRyaWJ1dGVzKCkiIG1ldGhvZCBpbnZva2VkIG9uIGEgVGV4dAorICogTm9kZSByZXR1cm5zIG51bGwuCisgKiBSZXRyaWV2ZSB0aGUgVGV4dCBub2RlIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiBmaXJzdCBlbXBsb3llZSBhbmQgaW52b2tlIHRoZSAiZ2V0QXR0cmlidXRlcygpIiBtZXRob2QKKyAqIG9uIHRoZSBUZXh0IE5vZGUuICBJdCBzaG91bGQgcmV0dXJuIG51bGwuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEzMTIyOTU3NzIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEzMTIyOTU3NzI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGV0ZXh0bm9kZWF0dHJpYnV0ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZXRleHRub2RlYXR0cmlidXRlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0QWRkcjsKKyAgICAgIE5vZGUgdGV4dE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0ckxpc3Q7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RBZGRyID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIHRleHROb2RlID0gdGVzdEFkZHIuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXR0ckxpc3QgPSB0ZXh0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBhc3NlcnROdWxsKCJ0ZXh0X2F0dHJpYnV0ZXNfaXNfbnVsbCIsIGF0dHJMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZXRleHRub2RlYXR0cmlidXRlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RldGV4dG5vZGVhdHRyaWJ1dGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGV0ZXh0bm9kZW5hbWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXRleHRub2RlbmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgzMGQwODYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGV0ZXh0bm9kZW5hbWUuamF2YQpAQCAtMCwwICsxLDg1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlTmFtZSgpIiBtZXRob2QgZm9yIGEgCisgKiAgICAgVGV4dCBOb2RlIGlzICIjdGV4dCIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RldGV4dG5vZGVuYW1lIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RldGV4dG5vZGVuYW1lKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcjsKKyAgICAgIE5vZGUgdGV4dE5vZGU7CisgICAgICBTdHJpbmcgdGV4dE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICB0ZXh0Tm9kZSA9IHRlc3RBZGRyLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIHRleHROYW1lID0gdGV4dE5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygidGV4dE5vZGVOYW1lIiwgIiN0ZXh0IiwgdGV4dE5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RldGV4dG5vZGVuYW1lIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RldGV4dG5vZGVuYW1lLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RldGV4dG5vZGV0eXBlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGV0ZXh0bm9kZXR5cGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOWMwODYyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RldGV4dG5vZGV0eXBlLmphdmEKQEAgLTAsMCArMSw4OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXROb2RlVHlwZSgpIiBtZXRob2QgZm9yIGEgVGV4dCBOb2RlCisgKiAgICAgcmV0dXJucyB0aGUgY29uc3RhbnQgdmFsdWUgMy4KKyAqICAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIFRleHQgbm9kZSBmcm9tIHRoZSBsYXN0IGNoaWxkIG9mCisgKiAgICAgdGhlIGZpcnN0IGVtcGxveWVlIGFuZCBpbnZva2UgdGhlICJnZXROb2RlVHlwZSgpIiAgIAorICogICAgIG1ldGhvZC4gICBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gMy4gCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMTEyMzc1NTgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIzNzU1ODwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZXRleHRub2RldHlwZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZXRleHRub2RldHlwZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEFkZHI7CisgICAgICBOb2RlIHRleHROb2RlOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICB0ZXN0QWRkciA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgdGV4dE5vZGUgPSB0ZXN0QWRkci5nZXRGaXJzdENoaWxkKCk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIHRleHROb2RlLmdldE5vZGVUeXBlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVUZXh0Tm9kZVR5cGVBc3NlcnQxIiwgMywgbm9kZVR5cGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RldGV4dG5vZGV0eXBlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RldGV4dG5vZGV0eXBlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RldGV4dG5vZGV2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RldGV4dG5vZGV2YWx1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2NDdlYmIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGV0ZXh0bm9kZXZhbHVlLmphdmEKQEAgLTAsMCArMSw5MCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAiZ2V0Tm9kZVZhbHVlKCkiIG1ldGhvZCBmb3IgYSAKKyAqICAgICBUZXh0IE5vZGUgaXMgdGhlIGNvbnRlbnQgb2YgdGhlIFRleHQgbm9kZS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgVGV4dCBub2RlIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlIGZpcnN0IAorICogICAgIGVtcGxveWVlIGFuZCBjaGVjayB0aGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAKKyAqICAgICAiZ2V0Tm9kZVZhbHVlKCkiIG1ldGhvZC4gICBJdCBzaG91bGQgYmUgZXF1YWwgdG8gCisgKiAgICAgIjEyMzAgTm9ydGggQXZlLiBEYWxsYXMsIFRleGFzIDk4NTUxIi4gCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RldGV4dG5vZGV2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZXRleHRub2RldmFsdWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RBZGRyOworICAgICAgTm9kZSB0ZXh0Tm9kZTsKKyAgICAgIFN0cmluZyB0ZXh0VmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIHRlc3RBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICB0ZXh0Tm9kZSA9IHRlc3RBZGRyLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIHRleHRWYWx1ZSA9IHRleHROb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0Tm9kZVZhbHVlIiwgIjEyMzAgTm9ydGggQXZlLiBEYWxsYXMsIFRleGFzIDk4NTUxIiwgdGV4dFZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZXRleHRub2RldmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGV0ZXh0bm9kZXZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RldmFsdWUwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RldmFsdWUwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFlZjk3ZjUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGV2YWx1ZTAxLmphdmEKQEAgLTAsMCArMSw4NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBbiBlbGVtZW50IGlzIGNyZWF0ZWQsIHNldE5vZGVWYWx1ZSBpcyBjYWxsZWQgd2l0aCBhIG5vbi1udWxsIGFyZ3VtZW50LCBidXQgZ2V0Tm9kZVZhbHVlCisgKiBzaG91bGQgc3RpbGwgcmV0dXJuIG51bGwuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI2ktRG9jdW1lbnQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI2ktRG9jdW1lbnQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGV2YWx1ZTAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RldmFsdWUwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgbmV3Tm9kZTsKKyAgICAgIFN0cmluZyBuZXdWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld05vZGUgPSBkb2MuY3JlYXRlRWxlbWVudCgiYWNyb255bSIpOworICAgICAgbmV3VmFsdWUgPSBuZXdOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgiaW5pdGlhbGx5TnVsbCIsIG5ld1ZhbHVlKTsKKyAgICAgIG5ld05vZGUuc2V0Tm9kZVZhbHVlKCJUaGlzIHNob3VsZCBoYXZlIG5vIGVmZmVjdCIpOworICAgICAgbmV3VmFsdWUgPSBuZXdOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgibnVsbEFmdGVyQXR0ZW1wdGVkQ2hhbmdlIiwgbmV3VmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RldmFsdWUwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZXZhbHVlMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGV2YWx1ZTAyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGV2YWx1ZTAyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODlmYjg1ZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXZhbHVlMDIuamF2YQpAQCAtMCwwICsxLDg1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEFuIGNvbW1lbnQgaXMgY3JlYXRlZCwgc2V0Tm9kZVZhbHVlIGlzIGNhbGxlZCB3aXRoIGEgbm9uLW51bGwgYXJndW1lbnQsIGJ1dCBnZXROb2RlVmFsdWUKKyAqIHNob3VsZCBzdGlsbCByZXR1cm4gbnVsbC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODA8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTcyODI3OTMyMiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTcyODI3OTMyMjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZXZhbHVlMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGV2YWx1ZTAyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBuZXdOb2RlOworICAgICAgU3RyaW5nIG5ld1ZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgbmV3Tm9kZSA9IGRvYy5jcmVhdGVDb21tZW50KCJUaGlzIGlzIGEgbmV3IENvbW1lbnQgbm9kZSIpOworICAgICAgbmV3VmFsdWUgPSBuZXdOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJpbml0aWFsIiwgIlRoaXMgaXMgYSBuZXcgQ29tbWVudCBub2RlIiwgbmV3VmFsdWUpOworICAgICAgbmV3Tm9kZS5zZXROb2RlVmFsdWUoIlRoaXMgc2hvdWxkIGhhdmUgYW4gZWZmZWN0Iik7CisgICAgICBuZXdWYWx1ZSA9IG5ld05vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImFmdGVyQ2hhbmdlIiwgIlRoaXMgc2hvdWxkIGhhdmUgYW4gZWZmZWN0IiwgbmV3VmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RldmFsdWUwMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZXZhbHVlMDIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGV2YWx1ZTAzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGV2YWx1ZTAzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzM2YjhlNwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXZhbHVlMDMuamF2YQpAQCAtMCwwICsxLDEwMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBbiBlbnRpdHkgcmVmZXJlbmNlIGlzIGNyZWF0ZWQsIHNldE5vZGVWYWx1ZSBpcyBjYWxsZWQgd2l0aCBhIG5vbi1udWxsIGFyZ3VtZW50LCBidXQgZ2V0Tm9kZVZhbHVlCisgKiBzaG91bGQgc3RpbGwgcmV0dXJuIG51bGwuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExQzk4NDkwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMUM5ODQ5MDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZXZhbHVlMDMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGV2YWx1ZTAzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBuZXdOb2RlOworICAgICAgU3RyaW5nIG5ld1ZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgCisgICAgICBpZiAoKCJ0ZXh0L2h0bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpIHsKKyAgICAgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ld05vZGUgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQxIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9TVVBQT1JURURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9IGVsc2UgeworICAgICAgICAgIG5ld05vZGUgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQxIik7CisgICAgICBhc3NlcnROb3ROdWxsKCJjcmVhdGVkRW50UmVmTm90TnVsbCIsIG5ld05vZGUpOworICAgICAgbmV3VmFsdWUgPSBuZXdOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgiaW5pdGlhbGx5TnVsbCIsIG5ld1ZhbHVlKTsKKyAgICAgIG5ld05vZGUuc2V0Tm9kZVZhbHVlKCJUaGlzIHNob3VsZCBoYXZlIG5vIGVmZmVjdCIpOworICAgICAgbmV3VmFsdWUgPSBuZXdOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgibnVsbEFmdGVyQXR0ZW1wdGVkQ2hhbmdlIiwgbmV3VmFsdWUpOworICAgICAgfQorICAgICAgICAKKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGV2YWx1ZTAzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RldmFsdWUwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXZhbHVlMDQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXZhbHVlMDQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jODZmZDQ3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RldmFsdWUwNC5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBbiBkb2N1bWVudCB0eXBlIGFjY2Vzc2VkLCBzZXROb2RlVmFsdWUgaXMgY2FsbGVkIHdpdGggYSBub24tbnVsbCBhcmd1bWVudCwgYnV0IGdldE5vZGVWYWx1ZQorICogc2hvdWxkIHN0aWxsIHJldHVybiBudWxsLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1CNjNFRDFBMzEiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUI2M0VEMUEzMTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZXZhbHVlMDQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGV2YWx1ZTA0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBuZXdOb2RlOworICAgICAgU3RyaW5nIG5ld1ZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgbmV3Tm9kZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBhc3NlcnRUcnVlKCJkb2NUeXBlTm90TnVsbE9yRG9jSXNIVE1MIiwgCisgICAgKChuZXdOb2RlICE9IG51bGwpIHwgKCJ0ZXh0L2h0bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpCispOworICAgICAgCisgICAgICBpZiAoKG5ld05vZGUgIT0gbnVsbCkpIHsKKyAgICAgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIG5ld05vZGUpOworICAgICAgbmV3VmFsdWUgPSBuZXdOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgiaW5pdGlhbGx5TnVsbCIsIG5ld1ZhbHVlKTsKKyAgICAgIG5ld05vZGUuc2V0Tm9kZVZhbHVlKCJUaGlzIHNob3VsZCBoYXZlIG5vIGVmZmVjdCIpOworICAgICAgbmV3VmFsdWUgPSBuZXdOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgibnVsbEFmdGVyQXR0ZW1wdGVkQ2hhbmdlIiwgbmV3VmFsdWUpOworICAgICAgfQorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm9kZXZhbHVlMDQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vZGV2YWx1ZTA0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RldmFsdWUwNS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RldmFsdWUwNS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJiNzFiYzQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGV2YWx1ZTA1LmphdmEKQEAgLTAsMCArMSw4NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBIGRvY3VtZW50IGZyYWdtZW50IGlzIGNyZWF0ZWQsIHNldE5vZGVWYWx1ZSBpcyBjYWxsZWQgd2l0aCBhIG5vbi1udWxsIGFyZ3VtZW50LCBidXQgZ2V0Tm9kZVZhbHVlCisgKiBzaG91bGQgc3RpbGwgcmV0dXJuIG51bGwuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUI2M0VEMUEzIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1CNjNFRDFBMzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZXZhbHVlMDUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGV2YWx1ZTA1KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBuZXdOb2RlOworICAgICAgU3RyaW5nIG5ld1ZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgbmV3Tm9kZSA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CisgICAgICBuZXdWYWx1ZSA9IG5ld05vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJpbml0aWFsbHlOdWxsIiwgbmV3VmFsdWUpOworICAgICAgbmV3Tm9kZS5zZXROb2RlVmFsdWUoIlRoaXMgc2hvdWxkIGhhdmUgbm8gZWZmZWN0Iik7CisgICAgICBuZXdWYWx1ZSA9IG5ld05vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJudWxsQWZ0ZXJBdHRlbXB0ZWRDaGFuZ2UiLCBuZXdWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGV2YWx1ZTA1IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RldmFsdWUwNS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXZhbHVlMDYuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXZhbHVlMDYuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OWJhZmIzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RldmFsdWUwNi5qYXZhCkBAIC0wLDAgKzEsODMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQW4gZG9jdW1lbnQgaXMgYWNjZXNzZWQsIHNldE5vZGVWYWx1ZSBpcyBjYWxsZWQgd2l0aCBhIG5vbi1udWxsIGFyZ3VtZW50LCBidXQgZ2V0Tm9kZVZhbHVlCisgKiBzaG91bGQgc3RpbGwgcmV0dXJuIG51bGwuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI2ktRG9jdW1lbnQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI2ktRG9jdW1lbnQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25vZGV2YWx1ZTA2IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub2RldmFsdWUwNihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IG5ld05vZGU7CisgICAgICBTdHJpbmcgbmV3VmFsdWU7CisgICAgICBuZXdOb2RlID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgbmV3VmFsdWUgPSBuZXdOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgiaW5pdGlhbGx5TnVsbCIsIG5ld1ZhbHVlKTsKKyAgICAgIG5ld05vZGUuc2V0Tm9kZVZhbHVlKCJUaGlzIHNob3VsZCBoYXZlIG5vIGVmZmVjdCIpOworICAgICAgbmV3VmFsdWUgPSBuZXdOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgibnVsbEFmdGVyQXR0ZW1wdGVkQ2hhbmdlIiwgbmV3VmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY19ub2RldmFsdWUwNiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZXZhbHVlMDYuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGV2YWx1ZTA3LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX25vZGV2YWx1ZTA3LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjBhODIxNwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXZhbHVlMDcuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEFuIEVudGl0eSBpcyBhY2Nlc3NlZCwgc2V0Tm9kZVZhbHVlIGlzIGNhbGxlZCB3aXRoIGEgbm9uLW51bGwgYXJndW1lbnQsIGJ1dCBnZXROb2RlVmFsdWUKKyAqIHNob3VsZCBzdGlsbCByZXR1cm4gbnVsbC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODA8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNTI3RENGRjIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTUyN0RDRkYyPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RldmFsdWUwNyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbm9kZXZhbHVlMDcoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisgICAgICBpZiAoZmFjdG9yeS5oYXNGZWF0dXJlKCJYTUwiLCBudWxsKSAhPSB0cnVlKSB7CisgICAgICAgICB0aHJvdyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24uaW5jb21wYXRpYmxlRmVhdHVyZSgiWE1MIiwgbnVsbCk7CisgICAgICB9CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIG5ld05vZGU7CisgICAgICBTdHJpbmcgbmV3VmFsdWU7CisgICAgICBOYW1lZE5vZGVNYXAgbm9kZU1hcDsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICAKKyAgICAgIGlmICgKKyAgICAhKCgidGV4dC9odG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKQorKSB7CisgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZG9jVHlwZU5vdE51bGwiLCBkb2NUeXBlKTsKKyAgICAgIG5vZGVNYXAgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdGllc05vdE51bGwiLCBub2RlTWFwKTsKKyAgICAgIG5ld05vZGUgPSBub2RlTWFwLmdldE5hbWVkSXRlbSgiYWxwaGEiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudGl0eU5vdE51bGwiLCBuZXdOb2RlKTsKKyAgICAgIG5ld1ZhbHVlID0gbmV3Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydE51bGwoImluaXRpYWxseU51bGwiLCBuZXdWYWx1ZSk7CisgICAgICBuZXdOb2RlLnNldE5vZGVWYWx1ZSgiVGhpcyBzaG91bGQgaGF2ZSBubyBlZmZlY3QiKTsKKyAgICAgIG5ld1ZhbHVlID0gbmV3Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydE51bGwoIm51bGxBZnRlckF0dGVtcHRlZENoYW5nZSIsIG5ld1ZhbHVlKTsKKyAgICAgIH0KKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGV2YWx1ZTA3IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RldmFsdWUwNy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXZhbHVlMDguamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm9kZXZhbHVlMDguamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNWJkZjViCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub2RldmFsdWUwOC5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQW4gbm90YXRpb24gaXMgYWNjZXNzZWQsIHNldE5vZGVWYWx1ZSBpcyBjYWxsZWQgd2l0aCBhIG5vbi1udWxsIGFyZ3VtZW50LCBidXQgZ2V0Tm9kZVZhbHVlCisgKiBzaG91bGQgc3RpbGwgcmV0dXJuIG51bGwuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTU0MzFEMUI5Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC01NDMxRDFCOTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm9kZXZhbHVlMDggZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGV2YWx1ZTA4KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworICAgICAgaWYgKGZhY3RvcnkuaGFzRmVhdHVyZSgiWE1MIiwgbnVsbCkgIT0gdHJ1ZSkgeworICAgICAgICAgdGhyb3cgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uLmluY29tcGF0aWJsZUZlYXR1cmUoIlhNTCIsIG51bGwpOworICAgICAgfQorCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBOb2RlIG5ld05vZGU7CisgICAgICBTdHJpbmcgbmV3VmFsdWU7CisgICAgICBOYW1lZE5vZGVNYXAgbm9kZU1hcDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgCisgICAgICBpZiAoCisgICAgISgoInRleHQvaHRtbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkKKykgeworICAgICAgICAgIGFzc2VydE5vdE51bGwoImRvY1R5cGVOb3ROdWxsIiwgZG9jVHlwZSk7CisgICAgICBub2RlTWFwID0gZG9jVHlwZS5nZXROb3RhdGlvbnMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoIm5vdGF0aW9uc05vdE51bGwiLCBub2RlTWFwKTsKKyAgICAgIG5ld05vZGUgPSBub2RlTWFwLmdldE5hbWVkSXRlbSgibm90YXRpb24xIik7CisgICAgICBhc3NlcnROb3ROdWxsKCJub3RhdGlvbk5vdE51bGwiLCBuZXdOb2RlKTsKKyAgICAgIG5ld1ZhbHVlID0gbmV3Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydE51bGwoImluaXRpYWxseU51bGwiLCBuZXdWYWx1ZSk7CisgICAgICBuZXdOb2RlLnNldE5vZGVWYWx1ZSgiVGhpcyBzaG91bGQgaGF2ZSBubyBlZmZlY3QiKTsKKyAgICAgIG5ld1ZhbHVlID0gbmV3Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydE51bGwoIm51bGxBZnRlckF0dGVtcHRlZENoYW5nZSIsIG5ld1ZhbHVlKTsKKyAgICAgIH0KKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX25vZGV2YWx1ZTA4IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RldmFsdWUwOC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm90YXRpb25zcmVtb3ZlbmFtZWRpdGVtMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub3RhdGlvbnNyZW1vdmVuYW1lZGl0ZW0xLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDA4OGQzZgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm90YXRpb25zcmVtb3ZlbmFtZWRpdGVtMS5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEFuIGF0dGVtcHQgdG8gYWRkIHJlbW92ZSBhbiBub3RhdGlvbiBzaG91bGQgcmVzdWx0IGluIGEgTk9fTU9ESUZJQ0FUSU9OX0VSUi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ0NjgyOUVGIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENDY4MjlFRjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENThCMTkzIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENThCMTkzPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub3RhdGlvbnNyZW1vdmVuYW1lZGl0ZW0xIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub3RhdGlvbnNyZW1vdmVuYW1lZGl0ZW0xKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworICAgICAgaWYgKGZhY3RvcnkuaGFzRmVhdHVyZSgiWE1MIiwgbnVsbCkgIT0gdHJ1ZSkgeworICAgICAgICAgdGhyb3cgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uLmluY29tcGF0aWJsZUZlYXR1cmUoIlhNTCIsIG51bGwpOworICAgICAgfQorCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTmFtZWROb2RlTWFwIG5vdGF0aW9uczsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTm9kZSByZXR2YWw7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKAorICAgICEoKCJ0ZXh0L2h0bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpCispIHsKKyAgICAgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgbm90YXRpb25zID0gZG9jVHlwZS5nZXROb3RhdGlvbnMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoIm5vdGF0aW9uc05vdE51bGwiLCBub3RhdGlvbnMpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR2YWwgPSBub3RhdGlvbnMucmVtb3ZlTmFtZWRJdGVtKCJub3RhdGlvbjEiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm90YXRpb25zcmVtb3ZlbmFtZWRpdGVtMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm90YXRpb25zcmVtb3ZlbmFtZWRpdGVtMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm90YXRpb25zc2V0bmFtZWRpdGVtMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY19ub3RhdGlvbnNzZXRuYW1lZGl0ZW0xLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWUyMjBiYwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfbm90YXRpb25zc2V0bmFtZWRpdGVtMS5qYXZhCkBAIC0wLDAgKzEsMTA5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEFuIGF0dGVtcHQgdG8gYWRkIGFuIGVsZW1lbnQgdG8gdGhlIG5hbWVkIG5vZGUgbWFwIHJldHVybmVkIGJ5IG5vdGF0aW9ucyBzaG91bGQgCisgKiByZXN1bHQgaW4gYSBOT19NT0RJRklDQVRJT05fRVJSIG9yIEhJRVJBUkNIWV9SRVFVRVNUX0VSUi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ0NjgyOUVGIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1ENDY4MjlFRjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDI1MTYzNzg4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDI1MTYzNzg4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub3RhdGlvbnNzZXRuYW1lZGl0ZW0xIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub3RhdGlvbnNzZXRuYW1lZGl0ZW0xKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworICAgICAgaWYgKGZhY3RvcnkuaGFzRmVhdHVyZSgiWE1MIiwgbnVsbCkgIT0gdHJ1ZSkgeworICAgICAgICAgdGhyb3cgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uLmluY29tcGF0aWJsZUZlYXR1cmUoIlhNTCIsIG51bGwpOworICAgICAgfQorCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTmFtZWROb2RlTWFwIG5vdGF0aW9uczsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTm9kZSByZXR2YWw7CisgICAgICBFbGVtZW50IGVsZW07CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKAorICAgICEoKCJ0ZXh0L2h0bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpCispIHsKKyAgICAgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgbm90YXRpb25zID0gZG9jVHlwZS5nZXROb3RhdGlvbnMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoIm5vdGF0aW9uc05vdE51bGwiLCBub3RhdGlvbnMpOworICAgICAgZWxlbSA9IGRvYy5jcmVhdGVFbGVtZW50KCJiciIpOworICAgICAgCisgICAgICB0cnkgeworICAgICAgcmV0dmFsID0gbm90YXRpb25zLnNldE5hbWVkSXRlbShlbGVtKTsKKyAgICAgIGZhaWwoInRocm93X0hJRVJfT1JfTk9fTU9EX0VSUiIpOworICAgICAKKyAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICBzd2l0Y2ggKGV4LmNvZGUpIHsKKyAgICAgIGNhc2UgMyA6IAorICAgICAgIGJyZWFrOworICAgICAgY2FzZSA3IDogCisgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICB0aHJvdyBleDsKKyAgICAgICAgICB9CisgICAgICB9IAorfQorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfbm90YXRpb25zc2V0bmFtZWRpdGVtMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm90YXRpb25zc2V0bmFtZWRpdGVtMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfdGV4dGluZGV4c2l6ZWVycm5lZ2F0aXZlb2Zmc2V0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX3RleHRpbmRleHNpemVlcnJuZWdhdGl2ZW9mZnNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVkZTdmMzQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX3RleHRpbmRleHNpemVlcnJuZWdhdGl2ZW9mZnNldC5qYXZhCkBAIC0wLDAgKzEsMTA3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNwbGl0VGV4dChvZmZzZXQpIiBtZXRob2QgcmFpc2VzIGFuCisgKiAgICAgSU5ERVhfU0laRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgb2Zmc2V0IGlzCisgKiAgICAgbmVnYXRpdmUuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHRleHR1YWwgZGF0YSBmcm9tIHRoZSBzZWNvbmQgY2hpbGQgb2YgdGhlIAorICogICAgIHRoaXJkIGVtcGxveWVlIGFuZCBpbnZva2UgdGhlICJzcGxpdFRleHQob2Zmc2V0KSIgbWV0aG9kLgorICogICAgIFRoZSBkZXNpcmVkIGV4Y2VwdGlvbiBzaG91bGQgYmUgcmFpc2VkIHNpbmNlIHRoZSBvZmZzZXQKKyAqICAgICBpcyBhIG5lZ2F0aXZlIG51bWJlci4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM4ODUzQzFEIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zODg1M0MxRDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMzg4NTNDMUQnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTM4ODUzQzFEJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX3RleHRpbmRleHNpemVlcnJuZWdhdGl2ZW9mZnNldCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfdGV4dGluZGV4c2l6ZWVycm5lZ2F0aXZlb2Zmc2V0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLnNpZ25lZAorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIFRleHQgdGV4dE5vZGU7CisgICAgICBUZXh0IHNwbGl0Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJzdHJvbmciKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIHRleHROb2RlID0gKFRleHQpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgc3BsaXROb2RlID0gdGV4dE5vZGUuc3BsaXRUZXh0KC02OSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOREVYX1NJWkVfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93c19JTkRFWF9TSVpFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY190ZXh0aW5kZXhzaXplZXJybmVnYXRpdmVvZmZzZXQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX3RleHRpbmRleHNpemVlcnJuZWdhdGl2ZW9mZnNldC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfdGV4dGluZGV4c2l6ZWVycm9mZnNldG91dG9mYm91bmRzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX3RleHRpbmRleHNpemVlcnJvZmZzZXRvdXRvZmJvdW5kcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFmNTgzMjIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX3RleHRpbmRleHNpemVlcnJvZmZzZXRvdXRvZmJvdW5kcy5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic3BsaXRUZXh0KG9mZnNldCkiIG1ldGhvZCByYWlzZXMgYW4KKyAqICAgICBJTkRFWF9TSVpFX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBvZmZzZXQgaXMKKyAqICAgICBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIHRoZSBUZXh0IG5vZGUuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHRleHR1YWwgZGF0YSBmcm9tIHRoZSBzZWNvbmQgY2hpbGQgb2YgdGhlIAorICogICAgIHRoaXJkIGVtcGxveWVlIGFuZCBpbnZva2UgdGhlICJzcGxpdFRleHQob2Zmc2V0KSIgbWV0aG9kLgorICogICAgIFRoZSBkZXNpcmVkIGV4Y2VwdGlvbiBzaG91bGQgYmUgcmFpc2VkIHNpbmNlIHRoZSBvZmZzZXQKKyAqICAgICBpcyBhIGdyZWF0ZXIgdGhhbiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gdGhlIFRleHQKKyAqICAgICBub2RlLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzg4NTNDMUQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM4ODUzQzFEPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0zODg1M0MxRCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOREVYX1NJWkVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMzg4NTNDMUQnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY190ZXh0aW5kZXhzaXplZXJyb2Zmc2V0b3V0b2Zib3VuZHMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX3RleHRpbmRleHNpemVlcnJvZmZzZXRvdXRvZmJvdW5kcyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIFRleHQgdGV4dE5vZGU7CisgICAgICBUZXh0IHNwbGl0Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJzdHJvbmciKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIHRleHROb2RlID0gKFRleHQpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgc3BsaXROb2RlID0gdGV4dE5vZGUuc3BsaXRUZXh0KDMwMCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOREVYX1NJWkVfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOREVYX1NJWkVfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX3RleHRpbmRleHNpemVlcnJvZmZzZXRvdXRvZmJvdW5kcyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfdGV4dGluZGV4c2l6ZWVycm9mZnNldG91dG9mYm91bmRzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY190ZXh0cGFyc2VpbnRvbGlzdG9mZWxlbWVudHMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfdGV4dHBhcnNlaW50b2xpc3RvZmVsZW1lbnRzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmExMDUwMQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfdGV4dHBhcnNlaW50b2xpc3RvZmVsZW1lbnRzLmphdmEKQEAgLTAsMCArMSwxMjUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgUmV0cmlldmUgdGhlIHRleHR1YWwgZGF0YSBmcm9tIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSAKKyAqICAgICBzZWNvbmQgZW1wbG95ZWUuICAgVGhhdCBub2RlIGlzIGNvbXBvc2VkIG9mIHR3byAgIAorICogICAgIEVudGl0eVJlZmVyZW5jZSBub2RlcyBhbmQgdHdvIFRleHQgbm9kZXMuICAgQWZ0ZXIKKyAqICAgICB0aGUgY29udGVudCBub2RlIGlzIHBhcnNlZCwgdGhlICJhY3JvbnltIiBFbGVtZW50CisgKiAgICAgc2hvdWxkIGNvbnRhaW4gZm91ciBjaGlsZHJlbiB3aXRoIGVhY2ggb25lIG9mIHRoZQorICogICAgIEVudGl0eVJlZmVyZW5jZXMgY29udGFpbmluZyBvbmUgY2hpbGQuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNDUxNDYwOTg3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNDUxNDYwOTg3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExQzk4NDkwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMUM5ODQ5MDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03NDU1NDk2MTQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc0NTU0OTYxNDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfdGV4dHBhcnNlaW50b2xpc3RvZmVsZW1lbnRzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY190ZXh0cGFyc2VpbnRvbGlzdG9mZWxlbWVudHMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGFkZHJlc3NOb2RlOworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgTm9kZSBjaGlsZDsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIE5vZGUgZ3JhbmRDaGlsZDsKKyAgICAgIGludCBsZW5ndGg7CisgICAgICBqYXZhLnV0aWwuTGlzdCByZXN1bHQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuTGlzdCBleHBlY3RlZE5vcm1hbCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZE5vcm1hbC5hZGQoIlx1MDNiMiIpOyAvLyBhbmRyb2lkLWNoYW5nZWQ6IEdSRUVLIExPV0VSIENBU0UgQkVUQQorICAgICAgZXhwZWN0ZWROb3JtYWwuYWRkKCIgRGFsbGFzLCAiKTsKKyAgICAgIGV4cGVjdGVkTm9ybWFsLmFkZCgiXHUwM2IzIik7IC8vIGFuZHJvaWQtY2hhbmdlZDogR1JFRUsgTE9XRVIgQ0FTRSBHQU1NQQorICAgICAgZXhwZWN0ZWROb3JtYWwuYWRkKCJcbiA5ODU1NCIpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuTGlzdCBleHBlY3RlZEV4cGFuZGVkID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGV4cGVjdGVkRXhwYW5kZWQuYWRkKCJcdTAzYjIgRGFsbGFzLCBcdTAzYjNcbiA5ODU1NCIpOyAvLyBhbmRyb2lkLWNoYW5nZWQ6IEdSRUVLIExPV0VSIENBU0UgQkVUQSwgR1JFRUsgTE9XRVIgQ0FTRSBHQU1NQQorICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFjcm9ueW0iKTsKKyAgICAgIGFkZHJlc3NOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTGlzdCA9IGFkZHJlc3NOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGxlbmd0aCA9IChpbnQpIGNoaWxkTGlzdC5nZXRMZW5ndGgoKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDdDID0gMDsgaW5kZXhOMTAwN0MgPCBjaGlsZExpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDdDKyspIHsKKyAgICAgICAgICBjaGlsZCA9IChOb2RlKSBjaGlsZExpc3QuaXRlbShpbmRleE4xMDA3Qyk7CisgICAgdmFsdWUgPSBjaGlsZC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIAorICAgICAgaWYgKCh2YWx1ZSA9PSBudWxsKSkgeworICAgICAgICAgIGdyYW5kQ2hpbGQgPSBjaGlsZC5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJncmFuZENoaWxkTm90TnVsbCIsIGdyYW5kQ2hpbGQpOworICAgICAgdmFsdWUgPSBncmFuZENoaWxkLmdldE5vZGVWYWx1ZSgpOworICAgICAgcmVzdWx0LmFkZCh2YWx1ZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICAgIHJlc3VsdC5hZGQodmFsdWUpOworICAgICAgfQorICAgICAgICAKKyAgICAgIH0KKyAgICAgIAorICAgICAgaWYgKGVxdWFscygxLCBsZW5ndGgpKSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJhc3NlcnRFcUNvYWxlc2NpbmciLCBleHBlY3RlZEV4cGFuZGVkLCByZXN1bHQpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoImFzc2VydEVxTm9ybWFsIiwgZXhwZWN0ZWROb3JtYWwsIHJlc3VsdCk7CisgICAgICB9CisgICAgICAgIAorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfdGV4dHBhcnNlaW50b2xpc3RvZmVsZW1lbnRzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY190ZXh0cGFyc2VpbnRvbGlzdG9mZWxlbWVudHMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX3RleHRzcGxpdHRleHRmb3VyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX3RleHRzcGxpdHRleHRmb3VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmVhZmE0MgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfdGV4dHNwbGl0dGV4dGZvdXIuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNwbGl0VGV4dChvZmZzZXQpIiBtZXRob2QgcmV0dXJucyB0aGUgbmV3IFRleHQgbm9kZS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgdGV4dHVhbCBkYXRhIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlIAorICogICAgIGZpcnN0IGVtcGxveWVlIGFuZCBpbnZva2UgdGhlICJzcGxpdFRleHQob2Zmc2V0KSIgbWV0aG9kLgorICogICAgIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiB0aGUgbmV3IFRleHQgbm9kZS4gICBUaGUgb2Zmc2V0CisgKiAgICAgdmFsdWUgdXNlZCBmb3IgdGhpcyB0ZXN0IGlzIDMwLiAgIFRoZSAiZ2V0Tm9kZVZhbHVlKCkiCisgKiAgICAgbWV0aG9kIGlzIGNhbGxlZCB0byBjaGVjayB0aGF0IHRoZSBuZXcgbm9kZSBub3cgY29udGFpbnMKKyAqICAgICB0aGUgY2hhcmFjdGVycyBhdCBhbmQgYWZ0ZXIgcG9zaXRpb24gMzAuCisgKiAgICAgKFN0YXJ0aW5nIGNvdW50IGF0IDApCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zODg1M0MxRCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzg4NTNDMUQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX3RleHRzcGxpdHRleHRmb3VyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY190ZXh0c3BsaXR0ZXh0Zm91cihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBhZGRyZXNzTm9kZTsKKyAgICAgIFRleHQgdGV4dE5vZGU7CisgICAgICBUZXh0IHNwbGl0Tm9kZTsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhY3JvbnltIik7CisgICAgICBhZGRyZXNzTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICB0ZXh0Tm9kZSA9IChUZXh0KSBhZGRyZXNzTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBzcGxpdE5vZGUgPSB0ZXh0Tm9kZS5zcGxpdFRleHQoMzApOworICAgICAgdmFsdWUgPSBzcGxpdE5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInRleHRTcGxpdFRleHRGb3VyQXNzZXJ0IiwgIjk4NTUxIiwgdmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY190ZXh0c3BsaXR0ZXh0Zm91ciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfdGV4dHNwbGl0dGV4dGZvdXIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX3RleHRzcGxpdHRleHRvbmUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfdGV4dHNwbGl0dGV4dG9uZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI0ZjhiZDMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX3RleHRzcGxpdHRleHRvbmUuamF2YQpAQCAtMCwwICsxLDk3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNwbGl0VGV4dChvZmZzZXQpIiBtZXRob2QgYnJlYWtzIHRoZSBUZXh0IG5vZGUgaW50bworICogICAgIHR3byBUZXh0IG5vZGVzIGF0IHRoZSBzcGVjaWZpZWQgb2Zmc2V0IGtlZXBpbmcgZWFjaCBub2RlCisgKiAgICAgYXMgc2libGluZ3MgaW4gdGhlIHRyZWUuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHRleHR1YWwgZGF0YSBmcm9tIHRoZSBzZWNvbmQgY2hpbGQgb2YgdGhlIAorICogICAgIHRoaXJkIGVtcGxveWVlIGFuZCBpbnZva2UgdGhlICJzcGxpdFRleHQob2Zmc2V0KSIgbWV0aG9kLgorICogICAgIFRoZSBtZXRob2Qgc3BsaXRzIHRoZSBUZXh0IG5vZGUgaW50byB0d28gbmV3IHNpYmxpbmcKKyAqICAgICBUZXh0IG5vZGVzIGtlZXBpbmcgYm90aCBvZiB0aGVtIGluIHRoZSB0cmVlLiAgIFRoaXMgdGVzdAorICogICAgIGNoZWNrcyB0aGUgIm5leHRTaWJsaW5nKCkiIG1ldGhvZCBvZiB0aGUgb3JpZ2luYWwgbm9kZQorICogICAgIHRvIGVuc3VyZSB0aGF0IHRoZSB0d28gbm9kZXMgYXJlIGluZGVlZCBzaWJsaW5ncy4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM4ODUzQzFEIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zODg1M0MxRDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfdGV4dHNwbGl0dGV4dG9uZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfdGV4dHNwbGl0dGV4dG9uZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIFRleHQgdGV4dE5vZGU7CisgICAgICBUZXh0IHNwbGl0Tm9kZTsKKyAgICAgIE5vZGUgc2Vjb25kUGFydDsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJzdHJvbmciKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIHRleHROb2RlID0gKFRleHQpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIHNwbGl0Tm9kZSA9IHRleHROb2RlLnNwbGl0VGV4dCg3KTsKKyAgICAgIHNlY29uZFBhcnQgPSB0ZXh0Tm9kZS5nZXROZXh0U2libGluZygpOworICAgICAgdmFsdWUgPSBzZWNvbmRQYXJ0LmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0U3BsaXRUZXh0T25lQXNzZXJ0IiwgIkpvbmVzIiwgdmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY190ZXh0c3BsaXR0ZXh0b25lIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY190ZXh0c3BsaXR0ZXh0b25lLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY190ZXh0c3BsaXR0ZXh0dGhyZWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfdGV4dHNwbGl0dGV4dHRocmVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTYwN2M3YQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvaGNfdGV4dHNwbGl0dGV4dHRocmVlLmphdmEKQEAgLTAsMCArMSw5NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgQWZ0ZXIgdGhlICJzcGxpdFRleHQob2Zmc2V0KSIgbWV0aG9kIGJyZWFrcyB0aGUgVGV4dCBub2RlCisgKiAgICAgaW50byB0d28gVGV4dCBub2RlcywgdGhlIG5ldyBUZXh0IG5vZGUgY29udGFpbnMgYWxsIHRoZQorICogICAgIGNvbnRlbnQgYXQgYW5kIGFmdGVyIHRoZSBvZmZzZXQgcG9pbnQuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHRleHR1YWwgZGF0YSBmcm9tIHRoZSBzZWNvbmQgY2hpbGQgb2YgdGhlIAorICogICAgIHRoaXJkIGVtcGxveWVlIGFuZCBpbnZva2UgdGhlICJzcGxpdFRleHQob2Zmc2V0KSIgbWV0aG9kLgorICogICAgIFRoZSBuZXcgVGV4dCBub2RlIHNob3VsZCBjb250YWluIGFsbCB0aGUgY29udGVudAorICogICAgIGF0IGFuZCBhZnRlciB0aGUgb2Zmc2V0IHBvaW50LiAgIFRoZSAiZ2V0Tm9kZVZhbHVlKCkiCisgKiAgICAgbWV0aG9kIGlzIGNhbGxlZCB0byBjaGVjayB0aGF0IHRoZSBuZXcgbm9kZSBub3cgY29udGFpbnMKKyAqICAgICB0aGUgY2hhcmFjdGVycyBhdCBhbmQgYWZ0ZXIgcG9zaXRpb24gc2V2ZW4uCisgKiAgICAgKFN0YXJ0aW5nIGNvdW50IGF0IDApCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zODg1M0MxRCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzg4NTNDMUQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX3RleHRzcGxpdHRleHR0aHJlZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfdGV4dHNwbGl0dGV4dHRocmVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgVGV4dCB0ZXh0Tm9kZTsKKyAgICAgIFRleHQgc3BsaXROb2RlOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInN0cm9uZyIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgdGV4dE5vZGUgPSAoVGV4dCkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgc3BsaXROb2RlID0gdGV4dE5vZGUuc3BsaXRUZXh0KDYpOworICAgICAgdmFsdWUgPSBzcGxpdE5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInRleHRTcGxpdFRleHRUaHJlZUFzc2VydCIsICIgSm9uZXMiLCB2YWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL2hjX3RleHRzcGxpdHRleHR0aHJlZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfdGV4dHNwbGl0dGV4dHRocmVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY190ZXh0c3BsaXR0ZXh0dHdvLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX3RleHRzcGxpdHRleHR0d28uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYTkyNWM3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY190ZXh0c3BsaXR0ZXh0dHdvLmphdmEKQEAgLTAsMCArMSw5NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgQWZ0ZXIgdGhlICJzcGxpdFRleHQob2Zmc2V0KSIgbWV0aG9kIGJyZWFrcyB0aGUgVGV4dCBub2RlCisgKiAgICAgaW50byB0d28gVGV4dCBub2RlcywgdGhlIG9yaWdpbmFsIG5vZGUgY29udGFpbnMgYWxsIHRoZQorICogICAgIGNvbnRlbnQgdXAgdG8gdGhlIG9mZnNldCBwb2ludC4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgdGV4dHVhbCBkYXRhIGZyb20gdGhlIHNlY29uZCBjaGlsZCBvZiB0aGUgCisgKiAgICAgdGhpcmQgZW1wbG95ZWUgYW5kIGludm9rZSB0aGUgInNwbGl0VGV4dChvZmZzZXQpIiBtZXRob2QuCisgKiAgICAgVGhlIG9yaWdpbmFsIFRleHQgbm9kZSBzaG91bGQgY29udGFpbiBhbGwgdGhlIGNvbnRlbnQKKyAqICAgICB1cCB0byB0aGUgb2Zmc2V0IHBvaW50LiAgIFRoZSAiZ2V0Tm9kZVZhbHVlKCkiIG1ldGhvZAorICogICAgIGlzIGNhbGxlZCB0byBjaGVjayB0aGF0IHRoZSBvcmlnaW5hbCBub2RlIG5vdyBjb250YWlucworICogICAgIHRoZSBmaXJzdCBmaXZlIGNoYXJhY3RlcnMuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zODg1M0MxRCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzg4NTNDMUQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX3RleHRzcGxpdHRleHR0d28gZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX3RleHRzcGxpdHRleHR0d28oZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBUZXh0IHRleHROb2RlOworICAgICAgVGV4dCBzcGxpdE5vZGU7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgic3Ryb25nIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICB0ZXh0Tm9kZSA9IChUZXh0KSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBzcGxpdE5vZGUgPSB0ZXh0Tm9kZS5zcGxpdFRleHQoNSk7CisgICAgICB2YWx1ZSA9IHRleHROb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0U3BsaXRUZXh0VHdvQXNzZXJ0IiwgIlJvZ2VyIiwgdmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9oY190ZXh0c3BsaXR0ZXh0dHdvIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY190ZXh0c3BsaXR0ZXh0dHdvLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY190ZXh0d2l0aG5vbWFya3VwLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL2hjX3RleHR3aXRobm9tYXJrdXAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZmY5NmMyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9oY190ZXh0d2l0aG5vbWFya3VwLmphdmEKQEAgLTAsMCArMSw5NCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgSWYgdGhlcmUgaXMgbm90IGFueSBtYXJrdXAgaW5zaWRlIGFuIEVsZW1lbnQgb3IgQXR0ciBub2RlCisgKiAgICAgY29udGVudCwgdGhlbiB0aGUgdGV4dCBpcyBjb250YWluZWQgaW4gYSBzaW5nbGUgb2JqZWN0ICAgCisgKiAgICAgaW1wbGVtZW50aW5nIHRoZSBUZXh0IGludGVyZmFjZSB0aGF0IGlzIHRoZSBvbmx5IGNoaWxkCisgKiAgICAgb2YgdGhlIGVsZW1lbnQuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHRleHR1YWwgZGF0YSBmcm9tIHRoZSBzZWNvbmQgY2hpbGQgb2YgdGhlIAorICogICAgIHRoaXJkIGVtcGxveWVlLiAgIFRoYXQgVGV4dCBub2RlIGNvbnRhaW5zIGEgYmxvY2sgb2YgCisgKiAgICAgbXVsdGlwbGUgdGV4dCBsaW5lcyB3aXRob3V0IG1hcmt1cCwgc28gdGhleSBzaG91bGQgYmUKKyAqICAgICB0cmVhdGVkIGFzIGEgc2luZ2xlIFRleHQgbm9kZS4gICBUaGUgImdldE5vZGVWYWx1ZSgpIiAgICAKKyAqICAgICBtZXRob2Qgc2hvdWxkIGNvbnRhaW4gdGhlIGNvbWJpbmF0aW9uIG9mIHRoZSB0d28gbGluZXMuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMzEyMjk1NzcyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMzEyMjk1NzcyPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODA8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX3RleHR3aXRobm9tYXJrdXAgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX3RleHR3aXRobm9tYXJrdXAoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgTm9kZSBub2RlVjsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgic3Ryb25nIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBub2RlViA9IG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIHZhbHVlID0gbm9kZVYuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInRleHRXaXRoTm9NYXJrdXBBc3NlcnQiLCAiUm9nZXJcbiBKb25lcyIsIHZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvaGNfdGV4dHdpdGhub21hcmt1cCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfdGV4dHdpdGhub21hcmt1cC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwY2hpbGRub2RlcmFuZ2UuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwY2hpbGRub2RlcmFuZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMDdlZTBhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXBjaGlsZG5vZGVyYW5nZS5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSByYW5nZSBvZiB2YWxpZCBjaGlsZCBub2RlIGluZGljZXMgaXMgMCB0byBMZW5ndGggLTEuCisgKiAgICAKKyAqICAgIENyZWF0ZSBhIE5hbWVkTm9kZU1hcCBvYmplY3QgZnJvbSB0aGUgYXR0cmlidXRlcyBvZiB0aGUKKyAqICAgIGxhc3QgY2hpbGQgb2YgdGhlIHRoaXJkIGVtcGxveWVlIGFuZCB0cmF2ZXJzZSB0aGUKKyAqICAgIGxpc3QgZnJvbSBpbmRleCAwIHRocnUgbGVuZ3RoIC0xLiAgQWxsIGluZGljZXMgc2hvdWxkCisgKiAgICBiZSB2YWxpZC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3RjkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM0OTQ2N0Y5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTZEMEZCMTlFIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02RDBGQjE5RTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgbmFtZWRub2RlbWFwY2hpbGRub2RlcmFuZ2UgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5hbWVkbm9kZW1hcGNoaWxkbm9kZXJhbmdlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RFbXBsb3llZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgTm9kZSBjaGlsZDsKKyAgICAgIGludCBsZW5ndGg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEVtcGxveWVlID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0RW1wbG95ZWUuZ2V0QXR0cmlidXRlcygpOworICAgICAgbGVuZ3RoID0gKGludCkgYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKKyAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoIiwgMiwgbGVuZ3RoKTsKKyAgICAgIGNoaWxkID0gYXR0cmlidXRlcy5pdGVtKDApOworICAgICAgY2hpbGQgPSBhdHRyaWJ1dGVzLml0ZW0oMSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcGNoaWxkbm9kZXJhbmdlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihuYW1lZG5vZGVtYXBjaGlsZG5vZGVyYW5nZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZlYTA2OTEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbS5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0TmFtZWRJdGVtKG5hbWUpIiBtZXRob2QgcmV0cmlldmVzIGEgbm9kZSAKKyAqICAgIHNwZWNpZmllZCBieSBuYW1lLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgY3JlYXRlIGEgTmFtZWROb2RlTWFwIAorICogICAgbGlzdGluZyBvZiB0aGUgYXR0cmlidXRlcyBvZiB0aGUgbGFzdCBjaGlsZC4gIE9uY2UgdGhlCisgKiAgICBsaXN0IGlzIGNyZWF0ZWQgYW4gaW52b2NhdGlvbiBvZiB0aGUgImdldE5hbWVkSXRlbShuYW1lKSIKKyAqICAgIG1ldGhvZCBpcyBkb25lIHdpdGggbmFtZT0iZG9tZXN0aWMiLiAgVGhpcyBzaG91bGQgcmVzdWx0CisgKiAgICBpbiB0aGUgZG9tZXN0aWMgQXR0ciBub2RlIGJlaW5nIHJldHVybmVkLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA3NDU3NzU0OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA3NDU3NzU0OTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zNDk0NjdGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3Rjk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcGdldG5hbWVkaXRlbSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0RW1wbG95ZWU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgZG9tZXN0aWNBdHRyOworICAgICAgU3RyaW5nIGF0dHJOYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3RFbXBsb3llZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBkb21lc3RpY0F0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oImRvbWVzdGljIik7CisgICAgICBhdHRyTmFtZSA9IGRvbWVzdGljQXR0ci5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lZG5vZGVtYXBHZXROYW1lZEl0ZW1Bc3NlcnQiLCAiZG9tZXN0aWMiLCBhdHRyTmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXBpbnVzZWF0dHJpYnV0ZWVyci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXBpbnVzZWF0dHJpYnV0ZWVyci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmViZTdhMmUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcGludXNlYXR0cmlidXRlZXJyLmphdmEKQEAgLTAsMCArMSwxMTAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBUaGUgInNldE5hbWVkSXRlbShhcmcpIiBtZXRob2QgcmFpc2VzIGEKKyAqIElOVVNFX0FUVFJJQlVURV9FUlIgRE9NRXhjZXB0aW9uIGlmICJhcmciIGlzIGFuCisgKiBBdHRyIHRoYXQgaXMgYWxyZWFkeSBpbiBhbiBhdHRyaWJ1dGUgb2YgYW5vdGhlciBFbGVtZW50LgorICogQ3JlYXRlIGEgTmFtZWROb2RlTWFwIG9iamVjdCBmcm9tIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZQorICogbGFzdCBjaGlsZCBvZiB0aGUgdGhpcmQgZW1wbG95ZWUgYW5kIGF0dGVtcHQgdG8gYWRkCisgKiBhbiBhdHRyaWJ1dGUgdGhhdCBpcyBhbHJlYWR5IGJlaW5nIHVzZWQgYnkgdGhlIGZpcnN0CisgKiBlbXBsb3llZS4gIFRoaXMgc2hvdWxkIHJhaXNlIHRoZSBkZXNpcmVkIGV4Y2VwdGlvbi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlVTRV9BVFRSSUJVVEVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDI1MTYzNzg4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDI1MTYzNzg4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0xMDI1MTYzNzg4JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTEwMjUxNjM3ODgnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlVTRV9BVFRSSUJVVEVfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcGludXNlYXR0cmlidXRlZXJyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lZG5vZGVtYXBpbnVzZWF0dHJpYnV0ZWVycihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCBmaXJzdE5vZGU7CisgICAgICBOb2RlIHRlc3ROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIGRvbWVzdGljQXR0cjsKKyAgICAgIEF0dHIgc2V0QXR0cjsKKyAgICAgIE5vZGUgc2V0Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICBmaXJzdE5vZGUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGRvbWVzdGljQXR0ciA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoImRvbWVzdGljIik7CisgICAgICBkb21lc3RpY0F0dHIuc2V0VmFsdWUoIlllcyIpOworICAgICAgc2V0QXR0ciA9IGZpcnN0Tm9kZS5zZXRBdHRyaWJ1dGVOb2RlKGRvbWVzdGljQXR0cik7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdE5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3ROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgc2V0Tm9kZSA9IGF0dHJpYnV0ZXMuc2V0TmFtZWRJdGVtKGRvbWVzdGljQXR0cik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVVNFX0FUVFJJQlVURV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSU5VU0VfQVRUUklCVVRFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXBpbnVzZWF0dHJpYnV0ZWVyciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZWRub2RlbWFwaW51c2VhdHRyaWJ1dGVlcnIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcG5vdGZvdW5kZXJyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcG5vdGZvdW5kZXJyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmZkOTNmNAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwbm90Zm91bmRlcnIuamF2YQpAQCAtMCwwICsxLDEwMyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZW1vdmVOYW1lZEl0ZW0obmFtZSkiIG1ldGhvZCByYWlzZXMgYSAKKyAqICAgIE5PVF9GT1VORF9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZXJlIGlzIG5vdCBhIG5vZGUKKyAqICAgIG5hbWVkICJuYW1lIiBpbiB0aGUgbWFwLgorICogICAgCisgKiAgICBDcmVhdGUgYSBOYW1lZE5vZGVNYXAgb2JqZWN0IGZyb20gdGhlIGF0dHJpYnV0ZXMgb2YgdGhlCisgKiAgICBsYXN0IGNoaWxkIG9mIHRoZSB0aGlyZCBlbXBsb3llZSBhbmQgYXR0ZW1wdCB0byByZW1vdmUKKyAqICAgIHRoZSAiZGlzdHJpY3QiIGF0dHJpYnV0ZS4gIFRoZXJlIGlzIG5vdCBhIG5vZGUgbmFtZWQKKyAqICAgICJkaXN0cmljdCIgaW4gdGhlIGxpc3QgYW5kIHRoZXJlZm9yZSB0aGUgZGVzaXJlZCAgIAorICogICAgZXhjZXB0aW9uIHNob3VsZCBiZSByYWlzZWQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVVNFX0FUVFJJQlVURV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRDU4QjE5MyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRDU4QjE5MzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtRDU4QjE5MycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVVNFX0FUVFJJQlVURV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC1ENThCMTkzJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgbmFtZWRub2RlbWFwbm90Zm91bmRlcnIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5hbWVkbm9kZW1hcG5vdGZvdW5kZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RFbXBsb3llZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgTm9kZSByZW1vdmVkTm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0RW1wbG95ZWUuZ2V0QXR0cmlidXRlcygpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZW1vdmVkTm9kZSA9IGF0dHJpYnV0ZXMucmVtb3ZlTmFtZWRJdGVtKCJkaXN0cmljdCIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT1RfRk9VTkRfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9GT1VORF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwbm90Zm91bmRlcnIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcG5vdGZvdW5kZXJyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXBudW1iZXJvZm5vZGVzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcG51bWJlcm9mbm9kZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMjA5NzM1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXBudW1iZXJvZm5vZGVzLmphdmEKQEAgLTAsMCArMSw5MiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRMZW5ndGgoKSIgbWV0aG9kIHJldHVybnMgdGhlIG51bWJlciBvZiBub2RlcworICogICAgaW4gdGhlIG1hcC4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGNyZWF0ZSBhIE5hbWVkTm9kZU1hcCAKKyAqICAgIGxpc3Rpbmcgb2YgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGxhc3QgY2hpbGQuICBPbmNlIHRoZQorICogICAgbGlzdCBpcyBjcmVhdGVkIGFuIGludm9jYXRpb24gb2YgdGhlICJnZXRMZW5ndGgoKSIKKyAqICAgIG1ldGhvZCBpcyBleGVjdXRlZC4gIFRoZSBudW1iZXIgb2Ygbm9kZXMgc2hvdWxkIGJlIDIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTZEMEZCMTlFIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02RDBGQjE5RTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgbmFtZWRub2RlbWFwbnVtYmVyb2Zub2RlcyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbmFtZWRub2RlbWFwbnVtYmVyb2Zub2RlcyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0RW1wbG95ZWU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIGludCBsZW5ndGg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEVtcGxveWVlID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0RW1wbG95ZWUuZ2V0QXR0cmlidXRlcygpOworICAgICAgbGVuZ3RoID0gKGludCkgYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKKyAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoIiwgMiwgbGVuZ3RoKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwbnVtYmVyb2Zub2RlcyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZWRub2RlbWFwbnVtYmVyb2Zub2Rlcy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY2N2M3ZjgKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbS5qYXZhCkBAIC0wLDAgKzEsMTA3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAicmVtb3ZlTmFtZWRJdGVtKG5hbWUpIiBtZXRob2QgcmVtb3ZlcyBhIG5vZGUgCisgKiAgICBzcGVjaWZpZWQgYnkgbmFtZS4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSB0aGlyZCBlbXBsb3llZSBhbmQgY3JlYXRlIGEgTmFtZWROb2RlTWFwIAorICogICAgb2JqZWN0IG9mIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBsYXN0IGNoaWxkLiAgT25jZSB0aGUKKyAqICAgIGxpc3QgaXMgY3JlYXRlZCBpbnZva2UgdGhlICJyZW1vdmVOYW1lZEl0ZW0obmFtZSkiCisgKiAgICBtZXRob2Qgd2l0aCBuYW1lPSJzdHJlZXQiLiAgVGhpcyBzaG91bGQgcmVzdWx0CisgKiAgICBpbiB0aGUgcmVtb3ZhbCBvZiB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZSBhbmQKKyAqICAgIHRoZSAiZ2V0U3BlY2lmaWVkKCkiIG1ldGhvZCBzaG91bGQgcmV0dXJuIGZhbHNlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRDU4QjE5MyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRDU4QjE5MzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zNDk0NjdGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3Rjk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyTWFyLzAwMDIuaHRtbCI+aHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyTWFyLzAwMDIuaHRtbDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW0oZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcudmFsaWRhdGluZworICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0QWRkcmVzczsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBzdHJlZXRBdHRyOworICAgICAgYm9vbGVhbiBzcGVjaWZpZWQ7CisgICAgICBOb2RlIHJlbW92ZWROb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0QWRkcmVzcy5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJhdHRyaWJ1dGVzTm90TnVsbCIsIGF0dHJpYnV0ZXMpOworICAgICAgcmVtb3ZlZE5vZGUgPSBhdHRyaWJ1dGVzLnJlbW92ZU5hbWVkSXRlbSgic3RyZWV0Iik7CisgICAgICBzdHJlZXRBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJzdHJlZXQiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoInN0cmVldEF0dHJOb3ROdWxsIiwgc3RyZWV0QXR0cik7CisgICAgICBzcGVjaWZpZWQgPSBzdHJlZXRBdHRyLmdldFNwZWNpZmllZCgpOworICAgICAgYXNzZXJ0RmFsc2UoImF0dHJOb3RTcGVjaWZpZWQiLCBzcGVjaWZpZWQpOworfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW0iOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtZ2V0dmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtZ2V0dmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZDQzMWJiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1nZXR2YWx1ZS5qYXZhCkBAIC0wLDAgKzEsMTA5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZSBub2RlIHJlbW92ZWQgYnkgdGhlICJyZW1vdmVOYW1lZEl0ZW0obmFtZSkiIG1ldGhvZCAKKyAqICAgIGlzIGFuIEF0dHIgbm9kZSB3aXRoIGEgZGVmYXVsdCB2YWx1ZSBpdCBpcyBpbW1lZGlhdGVseQorICogICAgcmVwbGFjZWQuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgdGhpcmQgZW1wbG95ZWUgYW5kIGNyZWF0ZSBhIE5hbWVkTm9kZU1hcCAKKyAqICAgIG9iamVjdCBvZiB0aGUgYXR0cmlidXRlcyBvZiB0aGUgbGFzdCBjaGlsZC4gIE9uY2UgdGhlCisgKiAgICBsaXN0IGlzIGNyZWF0ZWQgaW52b2tlIHRoZSAicmVtb3ZlTmFtZWRJdGVtKG5hbWUpIgorICogICAgbWV0aG9kIHdpdGggbmFtZT0ic3RyZWV0Ii4gIFRoZSAicmVtb3ZlTmFtZWRJdGVtKG5hbWUpIgorICogICAgbWV0aG9kIHNob3VsZCByZW1vdmUgdGhlICJzdHJlZXQiIGF0dHJpYnV0ZSBhbmQgc2luY2UKKyAqICAgIGl0IGhhcyBhIGRlZmF1bHQgdmFsdWUgb2YgIlllcyIsIHRoYXQgdmFsdWUgc2hvdWxkCisgKiAgICBpbW1lZGlhdGVseSBiZSB0aGUgYXR0cmlidXRlcyB2YWx1ZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ1OEIxOTMiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUQ1OEIxOTM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3RjkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM0OTQ2N0Y5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9saXN0cy53My5vcmcvQXJjaGl2ZXMvUHVibGljL3d3dy1kb20tdHMvMjAwMk1hci8wMDAyLmh0bWwiPmh0dHA6Ly9saXN0cy53My5vcmcvQXJjaGl2ZXMvUHVibGljL3d3dy1kb20tdHMvMjAwMk1hci8wMDAyLmh0bWw8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbWdldHZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1nZXR2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy52YWxpZGF0aW5nCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RFbXBsb3llZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBzdHJlZXRBdHRyOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgTm9kZSByZW1vdmVkTm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3RFbXBsb3llZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJhdHRyaWJ1dGVzTm90TnVsbCIsIGF0dHJpYnV0ZXMpOworICAgICAgcmVtb3ZlZE5vZGUgPSBhdHRyaWJ1dGVzLnJlbW92ZU5hbWVkSXRlbSgic3RyZWV0Iik7CisgICAgICBzdHJlZXRBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJzdHJlZXQiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoInN0cmVldEF0dHJOb3ROdWxsIiwgc3RyZWV0QXR0cik7CisgICAgICB2YWx1ZSA9IHN0cmVldEF0dHIuZ2V0VmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibmFtZWRub2RlbWFwUmVtb3ZlTmFtZWRJdGVtR2V0VmFsdWVBc3NlcnQiLCAiWWVzIiwgdmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1nZXR2YWx1ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtZ2V0dmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbXJldHVybm5vZGV2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1yZXR1cm5ub2RldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMDU3MTMyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1yZXR1cm5ub2RldmFsdWUuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlbW92ZU5hbWVkSXRlbShuYW1lKSIgbWV0aG9kIHJldHVybnMgdGhlIG5vZGUKKyAqICAgIHJlbW92ZWQgZnJvbSB0aGUgbWFwLiAgCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSB0aGlyZCBlbXBsb3llZSBhbmQgY3JlYXRlIGEgTmFtZWROb2RlTWFwIAorICogICAgb2JqZWN0IG9mIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBsYXN0IGNoaWxkLiAgT25jZSB0aGUKKyAqICAgIGxpc3QgaXMgY3JlYXRlZCBpbnZva2UgdGhlICJyZW1vdmVOYW1lZEl0ZW0obmFtZSkiCisgKiAgICBtZXRob2Qgd2l0aCBuYW1lPSJzdHJlZXQiLiAgVGhlICJyZW1vdmVOYW1lZEl0ZW0obmFtZSkiCisgKiAgICBtZXRob2Qgc2hvdWxkIHJlbW92ZSB0aGUgZXhpc3RpbmcgInN0cmVldCIgYXR0cmlidXRlCisgKiAgICBhbmQgcmV0dXJuIGl0LgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRDU4QjE5MyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRDU4QjE5MzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zNDk0NjdGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3Rjk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbXJldHVybm5vZGV2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtcmV0dXJubm9kZXZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RBZGRyZXNzOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIHJlbW92ZWROb2RlOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0QWRkcmVzcy5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICByZW1vdmVkTm9kZSA9IGF0dHJpYnV0ZXMucmVtb3ZlTmFtZWRJdGVtKCJzdHJlZXQiKTsKKyAgICAgIHZhbHVlID0gcmVtb3ZlZE5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5hbWVkbm9kZW1hcFJlbW92ZU5hbWVkSXRlbVJldHVybk5vZGVWYWx1ZUFzc2VydCIsICJObyIsIHZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtcmV0dXJubm9kZXZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1yZXR1cm5ub2RldmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHJldHVybmF0dHJub2RlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHJldHVybmF0dHJub2RlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTJkN2E0MAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwcmV0dXJuYXR0cm5vZGUuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXROYW1lZEl0ZW0obmFtZSkiIG1ldGhvZCByZXR1cm5zIGEgbm9kZSBvZiBhbnkgCisgKiAgICB0eXBlIHNwZWNpZmllZCBieSBuYW1lLiAKKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgY3JlYXRlIGEgTmFtZWROb2RlTWFwIAorICogICAgbGlzdGluZyBvZiB0aGUgYXR0cmlidXRlcyBvZiB0aGUgbGFzdCBjaGlsZC4gIE9uY2UgdGhlCisgKiAgICBsaXN0IGlzIGNyZWF0ZWQgYW4gaW52b2NhdGlvbiBvZiB0aGUgImdldE5hbWVkSXRlbShuYW1lKSIKKyAqICAgIG1ldGhvZCBpcyBkb25lIHdpdGggbmFtZT0ic3RyZWV0Ii4gIFRoaXMgc2hvdWxkIHJlc3VsdAorICogICAgaW4gdGhlIG1ldGhvZCByZXR1cm5pbmcgYW4gQXR0ciBub2RlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA3NDU3NzU0OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA3NDU3NzU0OTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTYzNzY0NjAyNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIxMTk0MDMiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIxMTk0MDM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcHJldHVybmF0dHJub2RlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lZG5vZGVtYXByZXR1cm5hdHRybm9kZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIHN0cmVldEF0dHI7CisgICAgICBTdHJpbmcgYXR0ck5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3RFbXBsb3llZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdEVtcGxveWVlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHN0cmVldEF0dHIgPSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgic3RyZWV0Iik7CisgICAgICBhc3NlcnRJbnN0YW5jZU9mKCJ0eXBlQXNzZXJ0IiwgQXR0ci5jbGFzcywgc3RyZWV0QXR0cik7CithdHRyTmFtZSA9IHN0cmVldEF0dHIuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZU5hbWUiLCAic3RyZWV0IiwgYXR0ck5hbWUpOworICAgICAgYXR0ck5hbWUgPSAoKEF0dHIpIC8qTm9kZSAqL3N0cmVldEF0dHIpLmdldE5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0ck5hbWUiLCAic3RyZWV0IiwgYXR0ck5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXByZXR1cm5hdHRybm9kZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZWRub2RlbWFwcmV0dXJuYXR0cm5vZGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHJldHVybmZpcnN0aXRlbS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXByZXR1cm5maXJzdGl0ZW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MDcxMTYwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXByZXR1cm5maXJzdGl0ZW0uamF2YQpAQCAtMCwwICsxLDk3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgIml0ZW0oaW5kZXgpIiBtZXRob2QgcmV0dXJucyB0aGUgaW5kZXh0aCBpdGVtIGluIAorICogICAgdGhlIG1hcCh0ZXN0IGZvciBmaXJzdCBpdGVtKS4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGNyZWF0ZSBhIE5hbWVkTm9kZU1hcCAKKyAqICAgIGxpc3Rpbmcgb2YgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGxhc3QgY2hpbGQuIFNpbmNlIHRoZQorICogICAgRE9NIGRvZXMgbm90IHNwZWNpZnkgYW4gb3JkZXIgb2YgdGhlc2Ugbm9kZXMgdGhlIGNvbnRlbnRzCisgKiAgICBvZiB0aGUgRklSU1Qgbm9kZSBjYW4gY29udGFpbiBlaXRoZXIgImRvbWVzdGljIiBvciAic3RyZWV0Ii4KKyAqICAgIFRoZSB0ZXN0IHNob3VsZCByZXR1cm4gInRydWUiIGlmIHRoZSBGSVJTVCBub2RlIGlzIGVpdGhlcgorICogICAgb2YgdGhlc2UgdmFsdWVzLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3RjkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM0OTQ2N0Y5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBuYW1lZG5vZGVtYXByZXR1cm5maXJzdGl0ZW0gZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5hbWVkbm9kZW1hcHJldHVybmZpcnN0aXRlbShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0QWRkcmVzczsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgTm9kZSBjaGlsZDsKKyAgICAgIFN0cmluZyBuYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0QWRkcmVzcy5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBjaGlsZCA9IGF0dHJpYnV0ZXMuaXRlbSgwKTsKKyAgICAgIG5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0VHJ1ZSgibmFtZWRub2RlbWFwUmV0dXJuRmlyc3RJdGVtQXNzZXJ0IiwgCisgICAgKGVxdWFscygiZG9tZXN0aWMiLCBuYW1lKSB8IGVxdWFscygic3RyZWV0IiwgbmFtZSkpCispOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXByZXR1cm5maXJzdGl0ZW0iOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcHJldHVybmZpcnN0aXRlbS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwcmV0dXJubGFzdGl0ZW0uamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwcmV0dXJubGFzdGl0ZW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMDQ3MzYzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXByZXR1cm5sYXN0aXRlbS5qYXZhCkBAIC0wLDAgKzEsOTcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaXRlbShpbmRleCkiIG1ldGhvZCByZXR1cm5zIHRoZSBpbmRleHRoIGl0ZW0gaW4gCisgKiAgICB0aGUgbWFwKHRlc3QgZm9yIGxhc3QgaXRlbSkuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBjcmVhdGUgYSBOYW1lZE5vZGVNYXAgCisgKiAgICBsaXN0aW5nIG9mIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBsYXN0IGNoaWxkLiBTaW5jZSB0aGUKKyAqICAgIERPTSBkb2VzIG5vdCBzcGVjaWZ5IGFuIG9yZGVyIG9mIHRoZXNlIG5vZGVzIHRoZSBjb250ZW50cworICogICAgb2YgdGhlIExBU1Qgbm9kZSBjYW4gY29udGFpbiBlaXRoZXIgImRvbWVzdGljIiBvciAic3RyZWV0Ii4KKyAqICAgIFRoZSB0ZXN0IHNob3VsZCByZXR1cm4gInRydWUiIGlmIHRoZSBMQVNUIG5vZGUgaXMgZWl0aGVyCisgKiAgICBvZiB0aGVzZSB2YWx1ZXMuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zNDk0NjdGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3Rjk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcHJldHVybmxhc3RpdGVtIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lZG5vZGVtYXByZXR1cm5sYXN0aXRlbShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0RW1wbG95ZWU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgbmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3RFbXBsb3llZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBjaGlsZCA9IGF0dHJpYnV0ZXMuaXRlbSgxKTsKKyAgICAgIG5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0VHJ1ZSgibmFtZWRub2RlbWFwUmV0dXJuTGFzdEl0ZW1Bc3NlcnQiLCAKKyAgICAoZXF1YWxzKCJkb21lc3RpYyIsIG5hbWUpIHwgZXF1YWxzKCJzdHJlZXQiLCBuYW1lKSkKKyk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHJldHVybmxhc3RpdGVtIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihuYW1lZG5vZGVtYXByZXR1cm5sYXN0aXRlbS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwcmV0dXJubnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXByZXR1cm5udWxsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDUzN2Y1MgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwcmV0dXJubnVsbC5qYXZhCkBAIC0wLDAgKzEsOTMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0TmFtZWRJdGVtKG5hbWUpIiBtZXRob2QgcmV0dXJucyBudWxsIG9mIHRoZSAKKyAqICAgIHNwZWNpZmllZCBuYW1lIGRpZCBub3QgaWRlbnRpZnkgYW55IG5vZGUgaW4gdGhlIG1hcC4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGNyZWF0ZSBhIE5hbWVkTm9kZU1hcCAKKyAqICAgIGxpc3Rpbmcgb2YgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGxhc3QgY2hpbGQuICBPbmNlIHRoZQorICogICAgbGlzdCBpcyBjcmVhdGVkIGFuIGludm9jYXRpb24gb2YgdGhlICJnZXROYW1lZEl0ZW0obmFtZSkiCisgKiAgICBtZXRob2QgaXMgZG9uZSB3aXRoIG5hbWU9ImRpc3RyaWN0Ii4gIFRoaXMgbmFtZSBkb2VzIG5vdCAKKyAqICAgIG1hdGNoIGFueSBuYW1lcyBpbiB0aGUgbGlzdCB0aGVyZWZvcmUgdGhlIG1ldGhvZCBzaG91bGQKKyAqICAgIHJldHVybiBudWxsLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA3NDU3NzU0OSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA3NDU3NzU0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgbmFtZWRub2RlbWFwcmV0dXJubnVsbCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbmFtZWRub2RlbWFwcmV0dXJubnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIGRpc3RyaWN0Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEVtcGxveWVlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0RW1wbG95ZWUuZ2V0QXR0cmlidXRlcygpOworICAgICAgZGlzdHJpY3ROb2RlID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJkaXN0cmljdCIpOworICAgICAgYXNzZXJ0TnVsbCgibmFtZWRub2RlbWFwUmV0dXJuTnVsbEFzc2VydCIsIGRpc3RyaWN0Tm9kZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHJldHVybm51bGwiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcHJldHVybm51bGwuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZmZhZjI5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW0uamF2YQpAQCAtMCwwICsxLDEwNSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXROYW1lZEl0ZW0oYXJnKSIgbWV0aG9kIGFkZHMgYSBub2RlIHVzaW5nIGl0cyAKKyAqICAgIG5vZGVOYW1lIGF0dHJpYnV0ZS4gCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGNyZWF0ZSBhIE5hbWVkTm9kZU1hcCAKKyAqICAgIG9iamVjdCBmcm9tIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBsYXN0IGNoaWxkIGJ5CisgKiAgICBpbnZva2luZyB0aGUgImdldEF0dHJpYnV0ZXMoKSIgbWV0aG9kLiAgT25jZSB0aGUKKyAqICAgIGxpc3QgaXMgY3JlYXRlZCBhbiBpbnZvY2F0aW9uIG9mIHRoZSAic2V0TmFtZWRJdGVtKGFyZykiCisgKiAgICBtZXRob2QgaXMgZG9uZSB3aXRoIGFyZz1uZXdBdHRyLCB3aGVyZSBuZXdBdHRyIGlzIGEKKyAqICAgIG5ldyBBdHRyIE5vZGUgcHJldmlvdXNseSBjcmVhdGVkLiAgVGhlICJzZXROYW1lZEl0ZW0oYXJnKSIKKyAqICAgIG1ldGhvZCBzaG91bGQgYWRkIHRoZW4gbmV3IG5vZGUgdG8gdGhlIE5hbWVkTm9kZUl0ZW0gCisgKiAgICBvYmplY3QgYnkgdXNpbmcgaXRzICJub2RlTmFtZSIgYXR0cmlidXRlKCJkaXN0cmljdCcpLgorICogICAgVGhpcyBub2RlIGlzIHRoZW4gcmV0cmlldmVkIHVzaW5nIHRoZSAiZ2V0TmFtZWRJdGVtKG5hbWUpIgorICogICAgbWV0aG9kLiAgVGhpcyB0ZXN0IHVzZXMgdGhlICJjcmVhdGVBdHRyaWJ1dGUobmFtZSkiCisgKiAgICBtZXRob2QgZnJvbSB0aGUgZG9jdW1lbnQgaW50ZXJmYWNlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTAyNTE2Mzc4OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTAyNTE2Mzc4ODwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zNDk0NjdGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3Rjk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIE5vZGUgdGVzdEFkZHJlc3M7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgZGlzdHJpY3ROb2RlOworICAgICAgU3RyaW5nIGF0dHJOYW1lOworICAgICAgTm9kZSBzZXROb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoImRpc3RyaWN0Iik7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdEFkZHJlc3MuZ2V0QXR0cmlidXRlcygpOworICAgICAgc2V0Tm9kZSA9IGF0dHJpYnV0ZXMuc2V0TmFtZWRJdGVtKG5ld0F0dHJpYnV0ZSk7CisgICAgICBkaXN0cmljdE5vZGUgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oImRpc3RyaWN0Iik7CisgICAgICBhdHRyTmFtZSA9IGRpc3RyaWN0Tm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lZG5vZGVtYXBTZXROYW1lZEl0ZW1Bc3NlcnQiLCAiZGlzdHJpY3QiLCBhdHRyTmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1yZXR1cm52YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1yZXR1cm52YWx1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJhYTgwZDMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXJldHVybnZhbHVlLmphdmEKQEAgLTAsMCArMSwxMDQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZSAic2V0TmFtZWRJdGVtKGFyZykiIG1ldGhvZCByZXBsYWNlcyBhbiBhbHJlYWR5IAorICogICAgZXhpc3Rpbmcgbm9kZSB3aXRoIHRoZSBzYW1lIG5hbWUgdGhlbiB0aGUgYWxyZWFkeSAKKyAqICAgIGV4aXN0aW5nIG5vZGUgaXMgcmV0dXJuZWQuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSB0aGlyZCBlbXBsb3llZSBhbmQgY3JlYXRlIGEgTmFtZWROb2RlTWFwIAorICogICAgb2JqZWN0IGZyb20gdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGxhc3QgY2hpbGQgYnkKKyAqICAgIGludm9raW5nIHRoZSAiZ2V0QXR0cmlidXRlcygpIiBtZXRob2QuICBPbmNlIHRoZQorICogICAgbGlzdCBpcyBjcmVhdGVkIGFuIGludm9jYXRpb24gb2YgdGhlICJzZXROYW1lZEl0ZW0oYXJnKSIKKyAqICAgIG1ldGhvZCBpcyBkb25lIHdpdGggYXJnPW5ld0F0dHIsIHdoZXJlIG5ld0F0dHIgaXMgYQorICogICAgbmV3IEF0dHIgTm9kZSBwcmV2aW91c2x5IGNyZWF0ZWQgYW5kIHdob3NlIG5vZGUgbmFtZQorICogICAgYWxyZWFkeSBleGlzdHMgaW4gdGhlIG1hcC4gIFRoZSAic2V0TmFtZWRJdGVtKGFyZykiCisgKiAgICBtZXRob2Qgc2hvdWxkIHJlcGxhY2UgdGhlIGFscmVhZHkgZXhpc3Rpbmcgbm9kZSB3aXRoCisgKiAgICB0aGUgbmV3IG9uZSBhbmQgcmV0dXJuIHRoZSBleGlzdGluZyBub2RlLiAgIAorICogICAgVGhpcyB0ZXN0IHVzZXMgdGhlICJjcmVhdGVBdHRyaWJ1dGUobmFtZSkiIG1ldGhvZCBmcm9tCisgKiAgICB0aGUgZG9jdW1lbnQgaW50ZXJmYWNlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTAyNTE2Mzc4OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTAyNTE2Mzc4ODwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zNDk0NjdGOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3Rjk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXJldHVybnZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1yZXR1cm52YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBOb2RlIHRlc3RBZGRyZXNzOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIG5ld05vZGU7CisgICAgICBTdHJpbmcgYXR0clZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoInN0cmVldCIpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3RBZGRyZXNzLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIG5ld05vZGUgPSBhdHRyaWJ1dGVzLnNldE5hbWVkSXRlbShuZXdBdHRyaWJ1dGUpOworICAgICAgYXR0clZhbHVlID0gbmV3Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygicmV0dXJuZWROb2RlVmFsdWUiLCAiTm8iLCBhdHRyVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1yZXR1cm52YWx1ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtcmV0dXJudmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXRoYXRleGlzdHMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtdGhhdGV4aXN0cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNkODhkOTIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXRoYXRleGlzdHMuamF2YQpAQCAtMCwwICsxLDEwNyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBJZiB0aGUgbm9kZSB0byBiZSBhZGRlZCBieSB0aGUgInNldE5hbWVkSXRlbShhcmcpIiBtZXRob2QgCisgKiAgICBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgTmFtZWROb2RlTWFwLCBpdCBpcyByZXBsYWNlZCBieQorICogICAgdGhlIG5ldyBvbmUuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGNyZWF0ZSBhIE5hbWVkTm9kZU1hcCAKKyAqICAgIG9iamVjdCBmcm9tIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBsYXN0IGNoaWxkIGJ5CisgKiAgICBpbnZva2luZyB0aGUgImdldEF0dHJpYnV0ZXMoKSIgbWV0aG9kLiAgT25jZSB0aGUKKyAqICAgIGxpc3QgaXMgY3JlYXRlZCBhbiBpbnZvY2F0aW9uIG9mIHRoZSAic2V0TmFtZWRJdGVtKGFyZykiCisgKiAgICBtZXRob2QgaXMgZG9uZSB3aXRoIGFyZz1uZXdBdHRyLCB3aGVyZSBuZXdBdHRyIGlzIGEKKyAqICAgIG5ldyBBdHRyIE5vZGUgcHJldmlvdXNseSBjcmVhdGVkIGFuZCB3aG9zZSBub2RlIG5hbWUKKyAqICAgIGFscmVhZHkgZXhpc3RzIGluIHRoZSBtYXAuICBUaGUgInNldE5hbWVkSXRlbShhcmcpIgorICogICAgbWV0aG9kIHNob3VsZCByZXBsYWNlIHRoZSBhbHJlYWR5IGV4aXN0aW5nIG5vZGUgd2l0aAorICogICAgdGhlIG5ldyBvbmUuICAgCisgKiAgICBUaGlzIG5vZGUgaXMgdGhlbiByZXRyaWV2ZWQgdXNpbmcgdGhlICJnZXROYW1lZEl0ZW0obmFtZSkiCisgKiAgICBtZXRob2QuICBUaGlzIHRlc3QgdXNlcyB0aGUgImNyZWF0ZUF0dHJpYnV0ZShuYW1lKSIKKyAqICAgIG1ldGhvZCBmcm9tIHRoZSBkb2N1bWVudCBpbnRlcmZhY2UKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwMjUxNjM3ODgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwMjUxNjM3ODg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3RjkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM0OTQ2N0Y5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW10aGF0ZXhpc3RzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW10aGF0ZXhpc3RzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIE5vZGUgdGVzdEFkZHJlc3M7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEF0dHIgZGlzdHJpY3ROb2RlOworICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKyAgICAgIE5vZGUgc2V0Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0QWRkcmVzcyA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBuZXdBdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJzdHJlZXQiKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0QWRkcmVzcy5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBzZXROb2RlID0gYXR0cmlidXRlcy5zZXROYW1lZEl0ZW0obmV3QXR0cmlidXRlKTsKKyAgICAgIGRpc3RyaWN0Tm9kZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgic3RyZWV0Iik7CisgICAgICBhdHRyVmFsdWUgPSBkaXN0cmljdE5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInN0cmVldFZhbHVlIiwgIiIsIGF0dHJWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXRoYXRleGlzdHMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXRoYXRleGlzdHMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXdpdGhuZXd2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW13aXRobmV3dmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MWQ3YjI1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW13aXRobmV3dmFsdWUuamF2YQpAQCAtMCwwICsxLDk5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZSAic2V0TmFtZWRJdGVtKGFyZykiIG1ldGhvZCBkb2VzIG5vdCByZXBsYWNlIGFuIAorICogICAgZXhpc3Rpbmcgbm9kZSB3aXRoIHRoZSBzYW1lIG5hbWUgdGhlbiBpdCByZXR1cm5zIG51bGwuIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgdGhpcmQgZW1wbG95ZWUgYW5kIGNyZWF0ZSBhIE5hbWVkTm9kZU1hcCAKKyAqICAgIG9iamVjdCBmcm9tIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBsYXN0IGNoaWxkLgorICogICAgT25jZSB0aGUgbGlzdCBpcyBjcmVhdGVkIHRoZSAic2V0TmFtZWRJdGVtKGFyZykiIG1ldGhvZAorICogICAgaXMgaW52b2tlZCB3aXRoIGFyZz1uZXdBdHRyLCB3aGVyZSBuZXdBdHRyIGlzIGEKKyAqICAgIG5ld2x5IGNyZWF0ZWQgQXR0ciBOb2RlIGFuZCB3aG9zZSBub2RlIG5hbWUKKyAqICAgIGFscmVhZHkgZXhpc3RzIGluIHRoZSBtYXAuICBUaGUgInNldE5hbWVkSXRlbShhcmcpIgorICogICAgbWV0aG9kIHNob3VsZCBhZGQgdGhlIG5ldyBub2RlIGFuZCByZXR1cm4gbnVsbC4KKyAqICAgIFRoaXMgdGVzdCB1c2VzIHRoZSAiY3JlYXRlQXR0cmlidXRlKG5hbWUpIiBtZXRob2QgZnJvbQorICogICAgdGhlIGRvY3VtZW50IGludGVyZmFjZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwMjUxNjM3ODgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwMjUxNjM3ODg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzQ5NDY3RjkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM0OTQ2N0Y5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW13aXRobmV3dmFsdWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbXdpdGhuZXd2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBOb2RlIHRlc3RBZGRyZXNzOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIG5ld05vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEFkZHJlc3MgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgbmV3QXR0cmlidXRlID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZSgiZGlzdHJpY3QiKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0QWRkcmVzcy5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBuZXdOb2RlID0gYXR0cmlidXRlcy5zZXROYW1lZEl0ZW0obmV3QXR0cmlidXRlKTsKKyAgICAgIGFzc2VydE51bGwoInJldHVybmVkTm9kZU51bGwiLCBuZXdOb2RlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtd2l0aG5ld3ZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW13aXRobmV3dmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHdyb25nZG9jdW1lbnRlcnIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbmFtZWRub2RlbWFwd3Jvbmdkb2N1bWVudGVyci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgxMzkzZDQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25hbWVkbm9kZW1hcHdyb25nZG9jdW1lbnRlcnIuamF2YQpAQCAtMCwwICsxLDExMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldE5hbWVkSXRlbShhcmcpIiBtZXRob2QgcmFpc2VzIGEgCisgKiAgICBXUk9OR19ET0NVTUVOVF9FUlIgRE9NRXhjZXB0aW9uIGlmICJhcmciIHdhcyBjcmVhdGVkCisgKiAgICBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQKKyAqICAgIHRoZSBOYW1lZE5vZGVNYXAuIAorICogICAgCisgKiAgICBDcmVhdGUgYSBOYW1lZE5vZGVNYXAgb2JqZWN0IGZyb20gdGhlIGF0dHJpYnV0ZXMgb2YgdGhlCisgKiAgICBsYXN0IGNoaWxkIG9mIHRoZSB0aGlyZCBlbXBsb3llZSBhbmQgYXR0ZW1wdCB0byBhZGQKKyAqICAgIGFub3RoZXIgQXR0ciBub2RlIHRvIGl0IHRoYXQgd2FzIGNyZWF0ZWQgZnJvbSBhIAorICogICAgZGlmZmVyZW50IERPTSBkb2N1bWVudC4gIFRoaXMgc2hvdWxkIHJhaXNlIHRoZSBkZXNpcmVkCisgKiAgICBleGNlcHRpb24uICBUaGlzIG1ldGhvZCB1c2VzIHRoZSAiY3JlYXRlQXR0cmlidXRlKG5hbWUpIgorICogICAgbWV0aG9kIGZyb20gdGhlIERvY3VtZW50IGludGVyZmFjZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdXUk9OR19ET0NVTUVOVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdXUk9OR19ET0NVTUVOVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTAyNTE2Mzc4OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTAyNTE2Mzc4ODwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMTAyNTE2Mzc4OCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J1dST05HX0RPQ1VNRU5UX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTEwMjUxNjM3ODgnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdXUk9OR19ET0NVTUVOVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgbmFtZWRub2RlbWFwd3Jvbmdkb2N1bWVudGVyciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbmFtZWRub2RlbWFwd3Jvbmdkb2N1bWVudGVycihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzE7CisgICAgICBEb2N1bWVudCBkb2MyOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RBZGRyZXNzOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIG5ld0F0dHJpYnV0ZTsKKyAgICAgIE5vZGUgc2V0Tm9kZTsKKyAgICAgIGRvYzEgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBkb2MyID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MxLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0QWRkcmVzcyA9IGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBuZXdBdHRyaWJ1dGUgPSBkb2MyLmNyZWF0ZUF0dHJpYnV0ZSgibmV3QXR0cmlidXRlIik7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdEFkZHJlc3MuZ2V0QXR0cmlidXRlcygpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXROb2RlID0gYXR0cmlidXRlcy5zZXROYW1lZEl0ZW0obmV3QXR0cmlidXRlKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X1dST05HX0RPQ1VNRU5UX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9uYW1lZG5vZGVtYXB3cm9uZ2RvY3VtZW50ZXJyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihuYW1lZG5vZGVtYXB3cm9uZ2RvY3VtZW50ZXJyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXBwZW5kY2hpbGQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjBmZTRmOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkLmphdmEKQEAgLTAsMCArMSw5OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJhcHBlbmRDaGlsZChuZXdDaGlsZCkiIG1ldGhvZCBhZGRzIHRoZSBub2RlCisgKiAgICAgIm5ld0NoaWxkIiB0byB0aGUgZW5kIG9mIHRoZSBsaXN0IG9mIGNoaWxkcmVuIG9mIHRoZQorICogICAgIG5vZGUuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgYXBwZW5kIGEgbmV3IEVsZW1lbnQKKyAqICAgICBub2RlIHRvIHRoZSBsaXN0IG9mIGNoaWxkcmVuLiAgIFRoZSBsYXN0IG5vZGUgaW4gdGhlIGxpc3QKKyAqICAgICBpcyB0aGVuIHJldHJpZXZlZCBhbmQgaXRzIE5vZGVOYW1lIGV4YW1pbmVkLiAgIFRoZQorICogICAgICJnZXROb2RlTmFtZSgpIiBtZXRob2Qgc2hvdWxkIHJldHVybiAibmV3Q2hpbGQiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlYXBwZW5kY2hpbGQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVhcHBlbmRjaGlsZChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIGNyZWF0ZWROb2RlOworICAgICAgTm9kZSBsY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgTm9kZSBhcHBlbmRlZENoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgY2hpbGRMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGNyZWF0ZWROb2RlID0gZG9jLmNyZWF0ZUVsZW1lbnQoIm5ld0NoaWxkIik7CisgICAgICBhcHBlbmRlZENoaWxkID0gZW1wbG95ZWVOb2RlLmFwcGVuZENoaWxkKGNyZWF0ZWROb2RlKTsKKyAgICAgIGxjaGlsZCA9IGVtcGxveWVlTm9kZS5nZXRMYXN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkTmFtZSA9IGxjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlQXBwZW5kQ2hpbGRBc3NlcnQxIiwgIm5ld0NoaWxkIiwgY2hpbGROYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlYXBwZW5kY2hpbGQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVhcHBlbmRjaGlsZGNoaWxkZXhpc3RzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVhcHBlbmRjaGlsZGNoaWxkZXhpc3RzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjc0ZGRhYwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkY2hpbGRleGlzdHMuamF2YQpAQCAtMCwwICsxLDExMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBJZiB0aGUgIm5ld0NoaWxkIiBpcyBhbHJlYWR5IGluIHRoZSB0cmVlLCBpdCBpcyBmaXJzdAorICogICAgIHJlbW92ZWQgYmVmb3JlIHRoZSBuZXcgb25lIGlzIGFwcGVuZGVkLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBmaXJzdCBjaGlsZCBvZiB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCAgIAorICogICAgIGFwcGVuZCB0aGUgZmlyc3QgY2hpbGQgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdC4gICBBZnRlcgorICogICAgIHRoZSAiYXBwZW5kQ2hpbGQobmV3Q2hpbGQpIiBtZXRob2QgaXMgaW52b2tlZCB0aGUgZmlyc3QgCisgKiAgICAgY2hpbGQgc2hvdWxkIGJlIHRoZSBvbmUgdGhhdCB3YXMgc2Vjb25kIGFuZCB0aGUgbGFzdAorICogICAgIGNoaWxkIHNob3VsZCBiZSB0aGUgb25lIHRoYXQgd2FzIGZpcnN0LgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlYXBwZW5kY2hpbGRjaGlsZGV4aXN0cyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWFwcGVuZGNoaWxkY2hpbGRleGlzdHMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgY2hpbGROb2RlOworICAgICAgTm9kZSBuZXdDaGlsZDsKKyAgICAgIE5vZGUgbGNoaWxkOworICAgICAgTm9kZSBmY2hpbGQ7CisgICAgICBTdHJpbmcgbGNoaWxkTmFtZTsKKyAgICAgIFN0cmluZyBmY2hpbGROYW1lOworICAgICAgTm9kZSBhcHBlbmRlZENoaWxkOworICAgICAgU3RyaW5nIGluaXRpYWxOYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBjaGlsZE5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgbmV3Q2hpbGQgPSBjaGlsZE5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgaW5pdGlhbE5hbWUgPSBuZXdDaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGNoaWxkTm9kZS5hcHBlbmRDaGlsZChuZXdDaGlsZCk7CisgICAgICBmY2hpbGQgPSBjaGlsZE5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgZmNoaWxkTmFtZSA9IGZjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgbGNoaWxkID0gY2hpbGROb2RlLmdldExhc3RDaGlsZCgpOworICAgICAgbGNoaWxkTmFtZSA9IGxjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKCJlbXBsb3llZUlkIiwgaW5pdGlhbE5hbWUpKSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJhc3NlcnQxX25vd2hpdGVzcGFjZSIsICJuYW1lIiwgZmNoaWxkTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoImFzc2VydDJfbm93aGl0ZXNwYWNlIiwgImVtcGxveWVlSWQiLCBsY2hpbGROYW1lKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJhc3NlcnQxIiwgImVtcGxveWVlSWQiLCBmY2hpbGROYW1lKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXNzZXJ0MiIsICIjdGV4dCIsIGxjaGlsZE5hbWUpOworICAgICAgfQorICAgICAgICAKKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVhcHBlbmRjaGlsZGNoaWxkZXhpc3RzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlYXBwZW5kY2hpbGRjaGlsZGV4aXN0cy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkZG9jZnJhZ21lbnQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkZG9jZnJhZ21lbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMDU5ZWY4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXBwZW5kY2hpbGRkb2NmcmFnbWVudC5qYXZhCkBAIC0wLDAgKzEsMTIxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIENyZWF0ZSBhbmQgcG9wdWxhdGUgYSBuZXcgRG9jdW1lbnRGcmFnbWVudCBvYmplY3QgYW5kCisgKiAgICAgYXBwZW5kIGl0IHRvIHRoZSBzZWNvbmQgZW1wbG95ZWUuICAgQWZ0ZXIgdGhlIAorICogICAgICJhcHBlbmRDaGlsZChuZXdDaGlsZCkiIG1ldGhvZCBpcyBpbnZva2VkIHJldHJpZXZlIHRoZQorICogICAgIG5ldyBub2RlcyBhdCB0aGUgZW5kIG9mIHRoZSBsaXN0LCB0aGV5IHNob3VsZCBiZSB0aGUKKyAqICAgICB0d28gRWxlbWVudCBub2RlcyBmcm9tIHRoZSBEb2N1bWVudEZyYWdtZW50LgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlYXBwZW5kY2hpbGRkb2NmcmFnbWVudCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWFwcGVuZGNoaWxkZG9jZnJhZ21lbnQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgRG9jdW1lbnRGcmFnbWVudCBuZXdkb2NGcmFnbWVudDsKKyAgICAgIE5vZGUgbmV3Q2hpbGQxOworICAgICAgTm9kZSBuZXdDaGlsZDI7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIGphdmEudXRpbC5MaXN0IHJlc3VsdCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICAKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIE5vZGUgYXBwZW5kZWRDaGlsZDsKKyAgICAgIGphdmEudXRpbC5MaXN0IGV4cGVjdGVkID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgiZW1wbG95ZWVJZCIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJuYW1lIik7CisgICAgICBleHBlY3RlZC5hZGQoInBvc2l0aW9uIik7CisgICAgICBleHBlY3RlZC5hZGQoInNhbGFyeSIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJnZW5kZXIiKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgiYWRkcmVzcyIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJuZXdDaGlsZDEiKTsKKyAgICAgIGV4cGVjdGVkLmFkZCgibmV3Q2hpbGQyIik7CisgICAgICAKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTGlzdCA9IGVtcGxveWVlTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBuZXdkb2NGcmFnbWVudCA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CisgICAgICBuZXdDaGlsZDEgPSBkb2MuY3JlYXRlRWxlbWVudCgibmV3Q2hpbGQxIik7CisgICAgICBuZXdDaGlsZDIgPSBkb2MuY3JlYXRlRWxlbWVudCgibmV3Q2hpbGQyIik7CisgICAgICBhcHBlbmRlZENoaWxkID0gbmV3ZG9jRnJhZ21lbnQuYXBwZW5kQ2hpbGQobmV3Q2hpbGQxKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBuZXdkb2NGcmFnbWVudC5hcHBlbmRDaGlsZChuZXdDaGlsZDIpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGVtcGxveWVlTm9kZS5hcHBlbmRDaGlsZChuZXdkb2NGcmFnbWVudCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA5RiA9IDA7IGluZGV4TjEwMDlGIDwgY2hpbGRMaXN0LmdldExlbmd0aCgpOyBpbmRleE4xMDA5RisrKSB7CisgICAgICAgICAgY2hpbGQgPSAoTm9kZSkgY2hpbGRMaXN0Lml0ZW0oaW5kZXhOMTAwOUYpOworICAgIG5vZGVUeXBlID0gKGludCkgY2hpbGQuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygxLCBub2RlVHlwZSkpIHsKKyAgICAgICAgICBjaGlsZE5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgcmVzdWx0LmFkZChjaGlsZE5hbWUpOworICAgICAgfQorICAgICAgfQorICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50TmFtZXMiLCBleHBlY3RlZCwgcmVzdWx0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkZG9jZnJhZ21lbnQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVhcHBlbmRjaGlsZGRvY2ZyYWdtZW50LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXBwZW5kY2hpbGRnZXRub2RlbmFtZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXBwZW5kY2hpbGRnZXRub2RlbmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMzYzE2YjkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVhcHBlbmRjaGlsZGdldG5vZGVuYW1lLmphdmEKQEAgLTAsMCArMSw5NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJhcHBlbmRDaGlsZChuZXdDaGlsZCkiIG1ldGhvZCByZXR1cm5zIHRoZSBub2RlCisgKiAgICAgYWRkZWQuCisgKiAgICAgCisgKiAgICAgQXBwZW5kIGEgbmV3bHkgY3JlYXRlZCBub2RlIHRvIHRoZSBjaGlsZCBsaXN0IG9mIHRoZSAKKyAqICAgICBzZWNvbmQgZW1wbG95ZWUgYW5kIGNoZWNrIHRoZSBOb2RlTmFtZSByZXR1cm5lZC4gICBUaGUKKyAqICAgICAiZ2V0Tm9kZU5hbWUoKSIgbWV0aG9kIHNob3VsZCByZXR1cm4gIm5ld0NoaWxkIi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlYXBwZW5kY2hpbGRnZXRub2RlbmFtZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWFwcGVuZGNoaWxkZ2V0bm9kZW5hbWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgTm9kZSBuZXdDaGlsZDsKKyAgICAgIE5vZGUgYXBwZW5kTm9kZTsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjaGlsZExpc3QgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgbmV3Q2hpbGQgPSBkb2MuY3JlYXRlRWxlbWVudCgibmV3Q2hpbGQiKTsKKyAgICAgIGFwcGVuZE5vZGUgPSBlbXBsb3llZU5vZGUuYXBwZW5kQ2hpbGQobmV3Q2hpbGQpOworICAgICAgY2hpbGROYW1lID0gYXBwZW5kTm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlQXBwZW5kQ2hpbGRHZXROb2RlTmFtZUFzc2VydDEiLCAibmV3Q2hpbGQiLCBjaGlsZE5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlYXBwZW5kY2hpbGRnZXRub2RlbmFtZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWFwcGVuZGNoaWxkZ2V0bm9kZW5hbWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVhcHBlbmRjaGlsZGludmFsaWRub2RldHlwZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXBwZW5kY2hpbGRpbnZhbGlkbm9kZXR5cGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NWExMzdmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXBwZW5kY2hpbGRpbnZhbGlkbm9kZXR5cGUuamF2YQpAQCAtMCwwICsxLDEwMyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImFwcGVuZENoaWxkKG5ld0NoaWxkKSIgbWV0aG9kIHJhaXNlcyBhIAorICogICAgIEhJRVJBUkNIWV9SRVFVRVNUX0VSUiBET01FeGNlcHRpb24gaWYgdGhpcyBub2RlIGlzIG9mCisgKiAgICAgYSB0eXBlIHRoYXQgZG9lcyBub3QgYWxsb3cgY2hpbGRyZW4gb2YgdGhlIHR5cGUgIm5ld0NoaWxkIgorICogICAgIHRvIGJlIGluc2VydGVkLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSByb290IG5vZGUgYW5kIGF0dGVtcHQgdG8gYXBwZW5kIGEgbmV3bHkKKyAqICAgICBjcmVhdGVkIEF0dHIgbm9kZS4gICBBbiBFbGVtZW50IG5vZGUgY2Fubm90IGhhdmUgY2hpbGRyZW4KKyAqICAgICBvZiB0aGUgIkF0dHIiIHR5cGUsIHRoZXJlZm9yZSB0aGUgZGVzaXJlZCBleGNlcHRpb24KKyAqICAgICBzaG91bGQgYmUgcmFpc2VkLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTE4NEU3MTA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSElFUkFSQ0hZX1JFUVVFU1RfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMTg0RTcxMDcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVhcHBlbmRjaGlsZGludmFsaWRub2RldHlwZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWFwcGVuZGNoaWxkaW52YWxpZG5vZGV0eXBlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCByb290Tm9kZTsKKyAgICAgIE5vZGUgbmV3Q2hpbGQ7CisgICAgICBOb2RlIGFwcGVuZGVkQ2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICByb290Tm9kZSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIG5ld0NoaWxkID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZSgibmV3QXR0cmlidXRlIik7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFwcGVuZGVkQ2hpbGQgPSByb290Tm9kZS5hcHBlbmRDaGlsZChuZXdDaGlsZCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19ISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkaW52YWxpZG5vZGV0eXBlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlYXBwZW5kY2hpbGRpbnZhbGlkbm9kZXR5cGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVhcHBlbmRjaGlsZG5ld2NoaWxkZGlmZmRvY3VtZW50LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVhcHBlbmRjaGlsZG5ld2NoaWxkZGlmZmRvY3VtZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTNhNjFhNQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkbmV3Y2hpbGRkaWZmZG9jdW1lbnQuamF2YQpAQCAtMCwwICsxLDEwOCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImFwcGVuZENoaWxkKG5ld0NoaWxkKSIgbWV0aG9kIHJhaXNlcyBhIAorICogICAgIFdST05HX0RPQ1VNRU5UX0VSUiBET01FeGNlcHRpb24gaWYgdGhlICJuZXdDaGlsZCIgd2FzCisgKiAgICAgY3JlYXRlZCBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IAorICogICAgIGNyZWF0ZWQgdGhpcyBub2RlLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGF0dGVtcHQgdG8gYXBwZW5kICAgIAorICogICAgIGEgbm9kZSBjcmVhdGVkIGZyb20gYSBkaWZmZXJlbnQgZG9jdW1lbnQuICAgQW4gYXR0ZW1wdCAKKyAqICAgICB0byBtYWtlIHN1Y2ggYSByZXBsYWNlbWVudCBzaG91bGQgcmFpc2UgdGhlIGRlc2lyZWQgCisgKiAgICAgZXhjZXB0aW9uLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PVF9GT1VORF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT1RfRk9VTkRfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMTg0RTcxMDcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT1RfRk9VTkRfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMTg0RTcxMDcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT1RfRk9VTkRfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlYXBwZW5kY2hpbGRuZXdjaGlsZGRpZmZkb2N1bWVudCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWFwcGVuZGNoaWxkbmV3Y2hpbGRkaWZmZG9jdW1lbnQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jMTsKKyAgICAgIERvY3VtZW50IGRvYzI7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVsZW1lbnROb2RlOworICAgICAgTm9kZSBhcHBlbmRlZENoaWxkOworICAgICAgZG9jMSA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2MyID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgbmV3Q2hpbGQgPSBkb2MxLmNyZWF0ZUVsZW1lbnQoIm5ld0NoaWxkIik7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYzIuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbGVtZW50Tm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFwcGVuZGVkQ2hpbGQgPSBlbGVtZW50Tm9kZS5hcHBlbmRDaGlsZChuZXdDaGlsZCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19XUk9OR19ET0NVTUVOVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkbmV3Y2hpbGRkaWZmZG9jdW1lbnQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVhcHBlbmRjaGlsZG5ld2NoaWxkZGlmZmRvY3VtZW50LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXBwZW5kY2hpbGRub2RlYW5jZXN0b3IuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkbm9kZWFuY2VzdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDBiNDBlNQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkbm9kZWFuY2VzdG9yLmphdmEKQEAgLTAsMCArMSwxMDQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJhcHBlbmRDaGlsZChuZXdDaGlsZCkiIG1ldGhvZCByYWlzZXMgYSAKKyAqICAgICBISUVSQVJDSFlfUkVRVUVTVF9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBub2RlIHRvIAorICogICAgIGFwcGVuZCBpcyBvbmUgb2YgdGhpcyBub2RlJ3MgYW5jZXN0b3JzLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGF0dGVtcHQgdG8gYXBwZW5kIAorICogICAgIGFuIGFuY2VzdG9yIG5vZGUocm9vdCBub2RlKSB0byBpdC4KKyAqICAgICBBbiBhdHRlbXB0IHRvIG1ha2Ugc3VjaCBhbiBhZGRpdGlvbiBzaG91bGQgcmFpc2UgdGhlIAorICogICAgIGRlc2lyZWQgZXhjZXB0aW9uLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTE4NEU3MTA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSElFUkFSQ0hZX1JFUVVFU1RfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMTg0RTcxMDcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVhcHBlbmRjaGlsZG5vZGVhbmNlc3RvciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWFwcGVuZGNoaWxkbm9kZWFuY2VzdG9yKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBuZXdDaGlsZDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlIGFwcGVuZGVkQ2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdDaGlsZCA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgYXBwZW5kZWRDaGlsZCA9IGVtcGxveWVlTm9kZS5hcHBlbmRDaGlsZChuZXdDaGlsZCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19ISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkbm9kZWFuY2VzdG9yIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlYXBwZW5kY2hpbGRub2RlYW5jZXN0b3IuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVhcHBlbmRjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXBwZW5kY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41M2JlZjg1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXBwZW5kY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuamF2YQpAQCAtMCwwICsxLDExNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImFwcGVuZENoaWxkKG5ld0NoaWxkKSIgbWV0aG9kIGNhdXNlcyB0aGUgCisgKiAgICAgRE9NRXhjZXB0aW9uIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiB0byBiZSByYWlzZWQKKyAqICAgICBpZiB0aGUgbm9kZSBpcyByZWFkb25seS4KKyAqICAgICAKKyAqICAgICBPYnRhaW4gdGhlIGNoaWxkcmVuIG9mIHRoZSBUSElSRCAiZ2VuZGVyIiBlbGVtZW50LiAgIFRoZSBlbGVtZW50cworICogICAgIGNvbnRlbnQgaXMgYW4gZW50aXR5IHJlZmVyZW5jZS4gICBHZXQgdGhlIEZJUlNUIGl0ZW0gCisgKiAgICAgZnJvbSB0aGUgZW50aXR5IHJlZmVyZW5jZSBhbmQgZXhlY3V0ZSB0aGUgImFwcGVuZENoaWxkKG5ld0NoaWxkKSIgbWV0aG9kLgorICogICAgIFRoaXMgY2F1c2VzIGEgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIERPTUV4Y2VwdGlvbiB0byBiZSB0aHJvd24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMTg0RTcxMDcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0xODRFNzEwNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVhcHBlbmRjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWFwcGVuZGNoaWxkbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyTm9kZTsKKyAgICAgIE5vZGUgZW50UmVmOworICAgICAgTm9kZSBlbnRFbGVtZW50OworICAgICAgTm9kZSBjcmVhdGVkTm9kZTsKKyAgICAgIE5vZGUgYXBwZW5kZWROb2RlOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZ2VuZGVyTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZ2VuZGVyIik7CisgICAgICBnZW5kZXJOb2RlID0gZ2VuZGVyTGlzdC5pdGVtKDIpOworICAgICAgZW50UmVmID0gZ2VuZGVyTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRSZWZOb3ROdWxsIiwgZW50UmVmKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgZW50UmVmLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoMSwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgZW50UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworICAgICAgfQorICAgIGVudEVsZW1lbnQgPSBlbnRSZWYuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50RWxlbWVudE5vdE51bGwiLCBlbnRFbGVtZW50KTsKKyAgICAgIGNyZWF0ZWROb2RlID0gZG9jLmNyZWF0ZUVsZW1lbnQoInRleHQzIik7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFwcGVuZGVkTm9kZSA9IGVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoY3JlYXRlZE5vZGUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVhcHBlbmRjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWFwcGVuZGNoaWxkbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXBwZW5kY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXBwZW5kY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUyYTBiNmQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVhcHBlbmRjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmphdmEKQEAgLTAsMCArMSwxMDAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJhcHBlbmRDaGlsZChuZXdDaGlsZCkiIG1ldGhvZCBjYXVzZXMgdGhlIAorICogICAgIERPTUV4Y2VwdGlvbiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgdG8gYmUgcmFpc2VkCisgKiAgICAgaWYgdGhlIG5vZGUgaXMgcmVhZG9ubHkuCisgKiAgICAgCisgKiAgICAgQ3JlYXRlIGFuIGVudDQgZW50aXR5IHJlZmVyZW5jZSBhbmQgIHRoZSAiYXBwZW5kQ2hpbGQobmV3Q2hpbGQpIiBtZXRob2QuCisgKiAgICAgVGhpcyBjYXVzZXMgYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgRE9NRXhjZXB0aW9uIHRvIGJlIHRocm93bi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTg0RTcxMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0xODRFNzEwNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTE4NEU3MTA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVhcHBlbmRjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWwiPmh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWFwcGVuZGNoaWxkbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLnhtbDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWFwcGVuZGNoaWxkbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVhcHBlbmRjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBlbnRSZWY7CisgICAgICBOb2RlIGNyZWF0ZWROb2RlOworICAgICAgTm9kZSBhcHBlbmRlZE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbnRSZWYgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQ0Iik7CisgICAgICBhc3NlcnROb3ROdWxsKCJjcmVhdGVkRW50UmVmTm90TnVsbCIsIGVudFJlZik7CisgICAgICBjcmVhdGVkTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50KCJ0ZXh0MyIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcHBlbmRlZE5vZGUgPSBlbnRSZWYuYXBwZW5kQ2hpbGQoY3JlYXRlZE5vZGUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVhcHBlbmRjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlYXBwZW5kY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWF0dHJpYnV0ZW5vZGVhdHRyaWJ1dGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWF0dHJpYnV0ZW5vZGVhdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YjMyNzU1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXR0cmlidXRlbm9kZWF0dHJpYnV0ZS5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogVGhlICJnZXRBdHRyaWJ1dGVzKCkiIG1ldGhvZCBpbnZva2VkIG9uIGFuIEF0dHJpYnV0ZQorICogTm9kZSByZXR1cm5zIG51bGwuCisgKiBSZXRyaWV2ZSB0aGUgZmlyc3QgYXR0cmlidXRlIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlCisgKiBmaXJzdCBlbXBsb3llZSBhbmQgaW52b2tlIHRoZSAiZ2V0QXR0cmlidXRlcygpIiBtZXRob2QKKyAqIG9uIHRoZSBBdHRyaWJ1dGUgTm9kZS4gIEl0IHNob3VsZCByZXR1cm4gbnVsbC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjM3NjQ2MDI0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Mzc2NDYwMjQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVhdHRyaWJ1dGVub2RlYXR0cmlidXRlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlYXR0cmlidXRlbm9kZWF0dHJpYnV0ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEFkZHI7CisgICAgICBOYW1lZE5vZGVNYXAgYWRkckF0dHI7CisgICAgICBOb2RlIGF0dHJOb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0QWRkciA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYWRkckF0dHIgPSB0ZXN0QWRkci5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBhdHRyTm9kZSA9IGFkZHJBdHRyLml0ZW0oMCk7CisgICAgICBhdHRyTGlzdCA9IGF0dHJOb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGFzc2VydE51bGwoIm5vZGVBdHRyaWJ1dGVOb2RlQXR0cmlidXRlQXNzZXJ0MSIsIGF0dHJMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWF0dHJpYnV0ZW5vZGVhdHRyaWJ1dGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVhdHRyaWJ1dGVub2RlYXR0cmlidXRlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXR0cmlidXRlbm9kZW5hbWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWF0dHJpYnV0ZW5vZGVuYW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjQxYzE2MAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWF0dHJpYnV0ZW5vZGVuYW1lLmphdmEKQEAgLTAsMCArMSw5MSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIHN0cmluZyByZXR1cm5lZCBieSB0aGUgImdldE5vZGVOYW1lKCkiIG1ldGhvZCBmb3IgYW4gCisgKiAgICAgQXR0cmlidXRlIE5vZGUgaXMgdGhlIG5hbWUgb2YgdGhlIEF0dHJpYnV0ZS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgQXR0cmlidXRlIG5hbWVkICJkb21lc3RpYyIgZnJvbSB0aGUgbGFzdCAKKyAqICAgICBjaGlsZCBvZiB0aGUgZmlyc3QgZW1wbG95ZWUgYW5kIGNoZWNrIHRoZSBzdHJpbmcgcmV0dXJuZWQgCisgKiAgICAgYnkgdGhlICJnZXROb2RlTmFtZSgpIiBtZXRob2QuICAgSXQgc2hvdWxkIGJlIGVxdWFsIHRvIAorICogICAgICJkb21lc3RpYyIuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWF0dHJpYnV0ZW5vZGVuYW1lIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlYXR0cmlidXRlbm9kZW5hbWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RBZGRyOworICAgICAgQXR0ciBhZGRyQXR0cjsKKyAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEFkZHIgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGFkZHJBdHRyID0gdGVzdEFkZHIuZ2V0QXR0cmlidXRlTm9kZSgiZG9tZXN0aWMiKTsKKyAgICAgIGF0dHJOYW1lID0gYWRkckF0dHIuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZUF0dHJpYnV0ZU5vZGVOYW1lQXNzZXJ0MSIsICJkb21lc3RpYyIsIGF0dHJOYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWF0dHJpYnV0ZW5vZGVuYW1lIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlYXR0cmlidXRlbm9kZW5hbWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVhdHRyaWJ1dGVub2RldHlwZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXR0cmlidXRlbm9kZXR5cGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40Nzc3NjE3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXR0cmlidXRlbm9kZXR5cGUuamF2YQpAQCAtMCwwICsxLDkwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldE5vZGVUeXBlKCkiIG1ldGhvZCBmb3IgYW4gQXR0cmlidXRlIE5vZGUKKyAqICAgICByZXR1cm5zIHRoZSBjb25zdGFudCB2YWx1ZSAyLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBmaXJzdCBhdHRyaWJ1dGUgZnJvbSB0aGUgbGFzdCBjaGlsZCBvZgorICogICAgIHRoZSBmaXJzdCBlbXBsb3llZSBhbmQgaW52b2tlIHRoZSAiZ2V0Tm9kZVR5cGUoKSIgICAKKyAqICAgICBtZXRob2QuICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIDIuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMTEyMzc1NTg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVhdHRyaWJ1dGVub2RldHlwZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWF0dHJpYnV0ZW5vZGV0eXBlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcjsKKyAgICAgIEF0dHIgYWRkckF0dHI7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhZGRyQXR0ciA9IHRlc3RBZGRyLmdldEF0dHJpYnV0ZU5vZGUoImRvbWVzdGljIik7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGFkZHJBdHRyLmdldE5vZGVUeXBlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVBdHRyTm9kZVR5cGVBc3NlcnQxIiwgMiwgbm9kZVR5cGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlYXR0cmlidXRlbm9kZXR5cGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVhdHRyaWJ1dGVub2RldHlwZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWF0dHJpYnV0ZW5vZGV2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlYXR0cmlidXRlbm9kZXZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjVhZmVhYgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWF0dHJpYnV0ZW5vZGV2YWx1ZS5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlVmFsdWUoKSIgbWV0aG9kIGZvciBhbiAKKyAqICAgICBBdHRyaWJ1dGUgTm9kZSBpcyB0aGUgdmFsdWUgb2YgdGhlIEF0dHJpYnV0ZS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgQXR0cmlidXRlIG5hbWVkICJkb21lc3RpYyIgZnJvbSB0aGUgbGFzdCAKKyAqICAgICBjaGlsZCBvZiB0aGUgZmlyc3QgZW1wbG95ZWUgYW5kIGNoZWNrIHRoZSBzdHJpbmcgcmV0dXJuZWQgCisgKiAgICAgYnkgdGhlICJnZXROb2RlVmFsdWUoKSIgbWV0aG9kLiAgIEl0IHNob3VsZCBiZSBlcXVhbCB0byAKKyAqICAgICAiWWVzIi4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlYXR0cmlidXRlbm9kZXZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlYXR0cmlidXRlbm9kZXZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcjsKKyAgICAgIEF0dHIgYWRkckF0dHI7CisgICAgICBTdHJpbmcgYXR0clZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0QWRkciA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYWRkckF0dHIgPSB0ZXN0QWRkci5nZXRBdHRyaWJ1dGVOb2RlKCJkb21lc3RpYyIpOworICAgICAgYXR0clZhbHVlID0gYWRkckF0dHIuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVBdHRyaWJ1dGVOb2RlVmFsdWVBc3NlcnQxIiwgIlllcyIsIGF0dHJWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVhdHRyaWJ1dGVub2RldmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVhdHRyaWJ1dGVub2RldmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjZGF0YXNlY3Rpb25ub2RlYXR0cmlidXRlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjZGF0YXNlY3Rpb25ub2RlYXR0cmlidXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWU0NzAwNAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNkYXRhc2VjdGlvbm5vZGVhdHRyaWJ1dGUuamF2YQpAQCAtMCwwICsxLDk3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogVGhlICJnZXRBdHRyaWJ1dGVzKCkiIG1ldGhvZCBpbnZva2VkIG9uIGEgQ0RBVEFTZWN0aW9uCisgKiBOb2RlIHJldHVybnMgbnVsbC4KKyAqIFJldHJpZXZlIHRoZSBDREFUQVNlY3Rpb24gbm9kZSBjb250YWluZWQgaW5zaWRlIHRoZQorICogc2Vjb25kIGNoaWxkIG9mIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGludm9rZSB0aGUKKyAqICJnZXRBdHRyaWJ1dGVzKCkiIG1ldGhvZCBvbiB0aGUgQ0RBVEFTZWN0aW9uIG5vZGUuCisgKiBJdCBzaG91bGQgcmV0dXJuIG51bGwuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTY2NzQ2OTIxMiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjY3NDY5MjEyPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlY2RhdGFzZWN0aW9ubm9kZWF0dHJpYnV0ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWNkYXRhc2VjdGlvbm5vZGVhdHRyaWJ1dGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IGNkYXRhTmFtZTsKKyAgICAgIE5vZGUgY2RhdGFOb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJMaXN0OworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJuYW1lIik7CisgICAgICBjZGF0YU5hbWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNkYXRhTm9kZSA9IGNkYXRhTmFtZS5nZXRMYXN0Q2hpbGQoKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgY2RhdGFOb2RlLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmICghZXF1YWxzKDQsIG5vZGVUeXBlKSkgeworICAgICAgICAgIGNkYXRhTm9kZSA9IGRvYy5jcmVhdGVDREFUQVNlY3Rpb24oIiIpOworICAgICAgfQorICAgIGF0dHJMaXN0ID0gY2RhdGFOb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGFzc2VydE51bGwoImNkYXRhU2VjdGlvbiIsIGF0dHJMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWNkYXRhc2VjdGlvbm5vZGVhdHRyaWJ1dGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVjZGF0YXNlY3Rpb25ub2RlYXR0cmlidXRlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY2RhdGFzZWN0aW9ubm9kZW5hbWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNkYXRhc2VjdGlvbm5vZGVuYW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2VkYTkwYQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNkYXRhc2VjdGlvbm5vZGVuYW1lLmphdmEKQEAgLTAsMCArMSw5OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAiZ2V0Tm9kZU5hbWUoKSIgbWV0aG9kIGZvciBhIAorICogICAgIENEQVRBU2VjdGlvbiBOb2RlIGlzICNjZGF0YS1zZWN0aW9uIi4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgQ0RBVEFTZWN0aW9uIG5vZGUgaW5zaWRlIHRoZSBzZWNvbmQgY2hpbGQKKyAqICAgICBvZiB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBjaGVjayB0aGUgc3RyaW5nIHJldHVybmVkIAorICogICAgIGJ5IHRoZSAiZ2V0Tm9kZU5hbWUoKSIgbWV0aG9kLiAgIEl0IHNob3VsZCBiZSBlcXVhbCB0byAKKyAqICAgICAiI2NkYXRhLXNlY3Rpb24iLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjY3NDY5MjEyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Njc0NjkyMTI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVjZGF0YXNlY3Rpb25ub2RlbmFtZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWNkYXRhc2VjdGlvbm5vZGVuYW1lKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCBjZGF0YU5hbWU7CisgICAgICBOb2RlIGNkYXRhTm9kZTsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIFN0cmluZyBjZGF0YU5vZGVOYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJuYW1lIik7CisgICAgICBjZGF0YU5hbWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNkYXRhTm9kZSA9IGNkYXRhTmFtZS5nZXRMYXN0Q2hpbGQoKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgY2RhdGFOb2RlLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmICghZXF1YWxzKDQsIG5vZGVUeXBlKSkgeworICAgICAgICAgIGNkYXRhTm9kZSA9IGRvYy5jcmVhdGVDREFUQVNlY3Rpb24oIiIpOworICAgICAgfQorICAgIGNkYXRhTm9kZU5hbWUgPSBjZGF0YU5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2RhdGFOb2RlTmFtZSIsICIjY2RhdGEtc2VjdGlvbiIsIGNkYXRhTm9kZU5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlY2RhdGFzZWN0aW9ubm9kZW5hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVjZGF0YXNlY3Rpb25ub2RlbmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNkYXRhc2VjdGlvbm5vZGV0eXBlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjZGF0YXNlY3Rpb25ub2RldHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkwZjk1MDYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjZGF0YXNlY3Rpb25ub2RldHlwZS5qYXZhCkBAIC0wLDAgKzEsMTAyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0Tm9kZVR5cGUoKSIgbWV0aG9kIGZvciBhIENEQVRBU2VjdGlvbiBOb2RlCisgKiAgICAgcmV0dXJucyB0aGUgY29uc3RhbnQgdmFsdWUgNC4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgQ0RBVEFTZWN0aW9uIG5vZGUgY29udGFpbmVkIGluc2lkZSB0aGUKKyAqICAgICBzZWNvbmQgY2hpbGQgb2YgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgaW52b2tlIHRoZSAKKyAqICAgICAiZ2V0Tm9kZVR5cGUoKSIgbWV0aG9kLiAgIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiA0LiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIzNzU1OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTY2NzQ2OTIxMiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjY3NDY5MjEyPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlY2RhdGFzZWN0aW9ubm9kZXR5cGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVjZGF0YXNlY3Rpb25ub2RldHlwZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RDb2FsZXNjaW5nCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0TmFtZTsKKyAgICAgIE5vZGUgY2RhdGFOb2RlOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJuYW1lIik7CisgICAgICB0ZXN0TmFtZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgY2RhdGFOb2RlID0gdGVzdE5hbWUuZ2V0TGFzdENoaWxkKCk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGNkYXRhTm9kZS5nZXROb2RlVHlwZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDMsIG5vZGVUeXBlKSkgeworICAgICAgICAgIGNkYXRhTm9kZSA9IGRvYy5jcmVhdGVDREFUQVNlY3Rpb24oIiIpOworICAgICAgbm9kZVR5cGUgPSAoaW50KSBjZGF0YU5vZGUuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIH0KKyAgICBhc3NlcnRFcXVhbHMoIm5vZGVUeXBlQ0RBVEEiLCA0LCBub2RlVHlwZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVjZGF0YXNlY3Rpb25ub2RldHlwZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWNkYXRhc2VjdGlvbm5vZGV0eXBlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY2RhdGFzZWN0aW9ubm9kZXZhbHVlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjZGF0YXNlY3Rpb25ub2RldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ODgzYjI3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY2RhdGFzZWN0aW9ubm9kZXZhbHVlLmphdmEKQEAgLTAsMCArMSwxMDUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIHN0cmluZyByZXR1cm5lZCBieSB0aGUgImdldE5vZGVWYWx1ZSgpIiBtZXRob2QgZm9yIGEgCisgKiAgICAgQ0RBVEFTZWN0aW9uIE5vZGUgaXMgdGhlIGNvbnRlbnQgb2YgdGhlIENEQVRBU2VjdGlvbi4gCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIENEQVRBU2VjdGlvbiBub2RlIGluc2lkZSB0aGUgc2Vjb25kIGNoaWxkCisgKiAgICAgb2YgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgY2hlY2sgdGhlIHN0cmluZyByZXR1cm5lZCAKKyAqICAgICBieSB0aGUgImdldE5vZGVWYWx1ZSgpIiBtZXRob2QuICAgSXQgc2hvdWxkIGJlIGVxdWFsIHRvIAorICogICAgICJUaGlzIGlzIGEgQ0RBVEEgU2VjdGlvbiB3aXRoIEVudGl0eVJlZmVyZW5jZSBudW1iZXIgMiAKKyAqICAgICAmZW50MjsiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02Njc0NjkyMTIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTY2NzQ2OTIxMjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWNkYXRhc2VjdGlvbm5vZGV2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWNkYXRhc2VjdGlvbm5vZGV2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RDb2FsZXNjaW5nCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCBjZGF0YU5hbWU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNkYXRhTm9kZVZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJuYW1lIik7CisgICAgICBjZGF0YU5hbWUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTGlzdCA9IGNkYXRhTmFtZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBjaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDEpOworICAgICAgCisgICAgICBpZiAoKGNoaWxkID09IG51bGwpKSB7CisgICAgICAgICAgY2hpbGQgPSBkb2MuY3JlYXRlQ0RBVEFTZWN0aW9uKCJUaGlzIGlzIGEgQ0RBVEFTZWN0aW9uIHdpdGggRW50aXR5UmVmZXJlbmNlIG51bWJlciAyICZlbnQyOyIpOworICAgICAgfQorICAgIGNkYXRhTm9kZVZhbHVlID0gY2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlIiwgIlRoaXMgaXMgYSBDREFUQVNlY3Rpb24gd2l0aCBFbnRpdHlSZWZlcmVuY2UgbnVtYmVyIDIgJmVudDI7IiwgY2RhdGFOb2RlVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlY2RhdGFzZWN0aW9ubm9kZXZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlY2RhdGFzZWN0aW9ubm9kZXZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY2hpbGRub2Rlcy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY2hpbGRub2Rlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg1OWQ4ZTYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjaGlsZG5vZGVzLmphdmEKQEAgLTAsMCArMSwxMDUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBDb2xsZWN0IHRoZSBlbGVtZW50IG5hbWVzIGZyb20gTm9kZS5jaGlsZE5vZGVzIGFuZCBjaGVjayBhZ2FpbnN0IGV4cGVjdGF0aW9ucy4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE0NTE0NjA5ODciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE0NTE0NjA5ODc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVjaGlsZG5vZGVzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlY2hpbGRub2RlcyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZUxpc3QgY2hpbGROb2RlczsKKyAgICAgIE5vZGUgY2hpbGROb2RlOworICAgICAgaW50IGNoaWxkVHlwZTsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBqYXZhLnV0aWwuTGlzdCBlbGVtZW50TmFtZXMgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuTGlzdCBleHBlY3RlZEVsZW1lbnROYW1lcyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZEVsZW1lbnROYW1lcy5hZGQoImVtcGxveWVlSWQiKTsKKyAgICAgIGV4cGVjdGVkRWxlbWVudE5hbWVzLmFkZCgibmFtZSIpOworICAgICAgZXhwZWN0ZWRFbGVtZW50TmFtZXMuYWRkKCJwb3NpdGlvbiIpOworICAgICAgZXhwZWN0ZWRFbGVtZW50TmFtZXMuYWRkKCJzYWxhcnkiKTsKKyAgICAgIGV4cGVjdGVkRWxlbWVudE5hbWVzLmFkZCgiZ2VuZGVyIik7CisgICAgICBleHBlY3RlZEVsZW1lbnROYW1lcy5hZGQoImFkZHJlc3MiKTsKKyAgICAgIAorICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTm9kZXMgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwNkMgPSAwOyBpbmRleE4xMDA2QyA8IGNoaWxkTm9kZXMuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDZDKyspIHsKKyAgICAgICAgICBjaGlsZE5vZGUgPSAoTm9kZSkgY2hpbGROb2Rlcy5pdGVtKGluZGV4TjEwMDZDKTsKKyAgICBjaGlsZFR5cGUgPSAoaW50KSBjaGlsZE5vZGUuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygxLCBjaGlsZFR5cGUpKSB7CisgICAgICAgICAgY2hpbGROYW1lID0gY2hpbGROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBlbGVtZW50TmFtZXMuYWRkKGNoaWxkTmFtZSk7CisgICAgICB9CisgICAgICB9CisgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnROYW1lcyIsIGV4cGVjdGVkRWxlbWVudE5hbWVzLCBlbGVtZW50TmFtZXMpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlY2hpbGRub2RlcyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWNoaWxkbm9kZXMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjaGlsZG5vZGVzYXBwZW5kY2hpbGQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNoaWxkbm9kZXNhcHBlbmRjaGlsZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRmYjg2YzgKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjaGlsZG5vZGVzYXBwZW5kY2hpbGQuamF2YQpAQCAtMCwwICsxLDkzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQWRkIGFuIGVsZW1lbnQgYW5kIGNoZWNrIHRoYXQgdGhlIHByZXZpb3VzbHkgcmV0cmlldmVkIGNoaWxkTm9kZXMgTm9kZUxpc3QKKyAqIGlzIGxpdmUuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNDUxNDYwOTg3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNDUxNDYwOTg3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE4NEU3MTA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xODRFNzEwNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWNoaWxkbm9kZXNhcHBlbmRjaGlsZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWNoaWxkbm9kZXNhcHBlbmRjaGlsZChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIGNyZWF0ZWROb2RlOworICAgICAgaW50IGV4cGVjdGVkTGVuZ3RoOworICAgICAgaW50IGxlbmd0aDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTGlzdCA9IGVtcGxveWVlTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBleHBlY3RlZExlbmd0aCA9IChpbnQpIGNoaWxkTGlzdC5nZXRMZW5ndGgoKTsKKyAgICAgIGV4cGVjdGVkTGVuZ3RoICs9IDE7CisgICAgICBjcmVhdGVkTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50KCJ0ZXh0MyIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZW1wbG95ZWVOb2RlLmFwcGVuZENoaWxkKGNyZWF0ZWROb2RlKTsKKyAgICAgIGxlbmd0aCA9IChpbnQpIGNoaWxkTGlzdC5nZXRMZW5ndGgoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2hpbGROb2RlTGVuZ3RoIiwgZXhwZWN0ZWRMZW5ndGgsIGxlbmd0aCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVjaGlsZG5vZGVzYXBwZW5kY2hpbGQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVjaGlsZG5vZGVzYXBwZW5kY2hpbGQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjaGlsZG5vZGVzZW1wdHkuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNoaWxkbm9kZXNlbXB0eS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhMjZhYmYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjaGlsZG5vZGVzZW1wdHkuamF2YQpAQCAtMCwwICsxLDk1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0Q2hpbGROb2RlcygpIiBtZXRob2QgcmV0dXJucyBhIE5vZGVMaXN0CisgKiAgICAgdGhhdCBjb250YWlucyBhbGwgY2hpbGRyZW4gb2YgdGhpcyBub2RlLiAgIElmIHRoZXJlCisgKiAgICAgYXJlIG5vdCBhbnkgY2hpbGRyZW4sIHRoaXMgaXMgYSBOb2RlTGlzdCB0aGF0IGRvZXMgbm90IAorICogICAgIGNvbnRhaW4gYW55IG5vZGVzLiAKKyAqICAgICBSZXRyaWV2ZSB0aGUgVGV4dCBub2RlIGZyb20gdGhlIHNlY29uZCBjaGlsZCBvZiB0aGUgc2Vjb25kCisgKiAgICAgZW1wbG95ZWUgYW5kIGludm9rZSB0aGUgImdldENoaWxkTm9kZXMoKSIgbWV0aG9kLiAgIFRoZQorICogICAgIE5vZGVMaXN0IHJldHVybmVkIHNob3VsZCBub3QgaGF2ZSBhbnkgbm9kZXMuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNDUxNDYwOTg3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNDUxNDYwOTg3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlY2hpbGRub2Rlc2VtcHR5IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlY2hpbGRub2Rlc2VtcHR5KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIHNlY29uZENOb2RlOworICAgICAgTm9kZSB0ZXh0Tm9kZTsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTm9kZXNMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTGlzdCA9IGVtcGxveWVlTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBzZWNvbmRDTm9kZSA9IGNoaWxkTGlzdC5pdGVtKDEpOworICAgICAgdGV4dE5vZGUgPSBzZWNvbmRDTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZE5vZGVzTGlzdCA9IHRleHROb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGFzc2VydFNpemUoIm5vZGVDaGlsZE5vZGVzRW1wdHlBc3NlcnQxIiwgMCwgY2hpbGROb2Rlc0xpc3QpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlY2hpbGRub2Rlc2VtcHR5IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlY2hpbGRub2Rlc2VtcHR5LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY2xvbmVhdHRyaWJ1dGVzY29waWVkLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjbG9uZWF0dHJpYnV0ZXNjb3BpZWQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ODE0MDNiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY2xvbmVhdHRyaWJ1dGVzY29waWVkLmphdmEKQEAgLTAsMCArMSwxMDUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZSBjbG9uZU5vZGUgbWV0aG9kIGlzIHVzZWQgdG8gY2xvbmUgYW4KKyAqICAgICBFbGVtZW50IG5vZGUsIGFsbCB0aGUgYXR0cmlidXRlcyBvZiB0aGUgRWxlbWVudCBhcmUKKyAqICAgICBjb3BpZWQgYWxvbmcgd2l0aCB0aGVpciB2YWx1ZXMuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIGxhc3QgY2hpbGQgb2YgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgaW52b2tlCisgKiAgICAgdGhlIGNsb25lTm9kZSBtZXRob2QuICAgVGhlCisgKiAgICAgZHVwbGljYXRlIG5vZGUgcmV0dXJuZWQgYnkgdGhlIG1ldGhvZCBzaG91bGQgY29weSB0aGUKKyAqICAgICBhdHRyaWJ1dGVzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG5vZGUuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlY2xvbmVhdHRyaWJ1dGVzY29waWVkIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlY2xvbmVhdHRyaWJ1dGVzY29waWVkKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGFkZHJlc3NOb2RlOworICAgICAgTm9kZSBjbG9uZWROb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIGF0dHJpYnV0ZU5vZGU7CisgICAgICBTdHJpbmcgYXR0cmlidXRlTmFtZTsKKyAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9uIHJlc3VsdCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9uIGV4cGVjdGVkUmVzdWx0ID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZG9tZXN0aWMiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgic3RyZWV0Iik7CisgICAgICAKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICBhZGRyZXNzTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjbG9uZWROb2RlID0gYWRkcmVzc05vZGUuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSBjbG9uZWROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDY1ID0gMDsgaW5kZXhOMTAwNjUgPCBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOyBpbmRleE4xMDA2NSsrKSB7CisgICAgICAgICAgYXR0cmlidXRlTm9kZSA9IChOb2RlKSBhdHRyaWJ1dGVzLml0ZW0oaW5kZXhOMTAwNjUpOworICAgIGF0dHJpYnV0ZU5hbWUgPSBhdHRyaWJ1dGVOb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICByZXN1bHQuYWRkKGF0dHJpYnV0ZU5hbWUpOworICAgICAgICB9CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVDbG9uZUF0dHJpYnV0ZXNDb3BpZWRBc3NlcnQxIiwgZXhwZWN0ZWRSZXN1bHQsIHJlc3VsdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVjbG9uZWF0dHJpYnV0ZXNjb3BpZWQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVjbG9uZWF0dHJpYnV0ZXNjb3BpZWQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjbG9uZWZhbHNlbm9jb3B5dGV4dC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY2xvbmVmYWxzZW5vY29weXRleHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NThhYmFiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY2xvbmVmYWxzZW5vY29weXRleHQuamF2YQpAQCAtMCwwICsxLDk1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNsb25lTm9kZShkZWVwKSIgbWV0aG9kIGRvZXMgbm90IGNvcHkgdGV4dCB1bmxlc3MgaXQKKyAqICAgICBpcyBkZWVwIGNsb25lZC4oVGVzdCBmb3IgZGVlcD1mYWxzZSkKKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgZm91cnRoIGNoaWxkIG9mIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kCisgKiAgICAgdGhlICJjbG9uZU5vZGUoZGVlcCkiIG1ldGhvZCB3aXRoIGRlZXA9ZmFsc2UuICAgVGhlCisgKiAgICAgZHVwbGljYXRlIG5vZGUgcmV0dXJuZWQgYnkgdGhlIG1ldGhvZCBzaG91bGQgbm90IGNvcHkKKyAqICAgICBhbnkgdGV4dCBkYXRhIGNvbnRhaW5lZCBpbiB0aGlzIG5vZGUuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zQTBFRDBBNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtM0EwRUQwQTQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVjbG9uZWZhbHNlbm9jb3B5dGV4dCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWNsb25lZmFsc2Vub2NvcHl0ZXh0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgY2hpbGROb2RlOworICAgICAgTm9kZSBjbG9uZWROb2RlOworICAgICAgTm9kZSBsYXN0Q2hpbGROb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgY2hpbGRMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGNoaWxkTm9kZSA9IGNoaWxkTGlzdC5pdGVtKDMpOworICAgICAgY2xvbmVkTm9kZSA9IGNoaWxkTm9kZS5jbG9uZU5vZGUoZmFsc2UpOworICAgICAgbGFzdENoaWxkTm9kZSA9IGNsb25lZE5vZGUuZ2V0TGFzdENoaWxkKCk7CisgICAgICBhc3NlcnROdWxsKCJub1RleHROb2RlcyIsIGxhc3RDaGlsZE5vZGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlY2xvbmVmYWxzZW5vY29weXRleHQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVjbG9uZWZhbHNlbm9jb3B5dGV4dC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNsb25lZ2V0cGFyZW50bnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY2xvbmVnZXRwYXJlbnRudWxsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmFkMWY4YQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNsb25lZ2V0cGFyZW50bnVsbC5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBkdXBsaWNhdGUgbm9kZSByZXR1cm5lZCBieSB0aGUgImNsb25lTm9kZShkZWVwKSIKKyAqICAgICBtZXRob2QgZG9lcyBub3QgaGF2ZSBhIFBhcmVudE5vZGUuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgaW52b2tlIHRoZQorICogICAgICJjbG9uZU5vZGUoZGVlcCkiIG1ldGhvZCB3aXRoIGRlZXA9ZmFsc2UuICAgVGhlCisgKiAgICAgZHVwbGljYXRlIG5vZGUgcmV0dXJuZWQgc2hvdWxkIHJldHVybiBudWxsIHdoZW4gdGhlCisgKiAgICAgImdldFBhcmVudE5vZGUoKSIgaXMgaW52b2tlZC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTNBMEVEMEE0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zQTBFRDBBNDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWNsb25lZ2V0cGFyZW50bnVsbCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWNsb25lZ2V0cGFyZW50bnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlIGNsb25lZE5vZGU7CisgICAgICBOb2RlIHBhcmVudE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjbG9uZWROb2RlID0gZW1wbG95ZWVOb2RlLmNsb25lTm9kZShmYWxzZSk7CisgICAgICBwYXJlbnROb2RlID0gY2xvbmVkTm9kZS5nZXRQYXJlbnROb2RlKCk7CisgICAgICBhc3NlcnROdWxsKCJub2RlQ2xvbmVHZXRQYXJlbnROdWxsQXNzZXJ0MSIsIHBhcmVudE5vZGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlY2xvbmVnZXRwYXJlbnRudWxsIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlY2xvbmVnZXRwYXJlbnRudWxsLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY2xvbmVub2RlZmFsc2UuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNsb25lbm9kZWZhbHNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2JlMjUzZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNsb25lbm9kZWZhbHNlLmphdmEKQEAgLTAsMCArMSw5OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJjbG9uZU5vZGUoZGVlcCkiIG1ldGhvZCByZXR1cm5zIGEgY29weSBvZiB0aGUgbm9kZQorICogICAgIG9ubHkgaWYgZGVlcD1mYWxzZS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBpbnZva2UgdGhlCisgKiAgICAgImNsb25lTm9kZShkZWVwKSIgbWV0aG9kIHdpdGggZGVlcD1mYWxzZS4gICBUaGUKKyAqICAgICBtZXRob2Qgc2hvdWxkIG9ubHkgY2xvbmUgdGhpcyBub2RlLiAgIFRoZSBOb2RlTmFtZSBhbmQKKyAqICAgICBsZW5ndGggb2YgdGhlIE5vZGVMaXN0IGFyZSBjaGVja2VkLiAgIFRoZSAiZ2V0Tm9kZU5hbWUoKSIKKyAqICAgICBtZXRob2Qgc2hvdWxkIHJldHVybiAiZW1wbG95ZWUiIGFuZCB0aGUgImdldExlbmd0aCgpIgorICogICAgIG1ldGhvZCBzaG91bGQgcmV0dXJuIDAuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zQTBFRDBBNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtM0EwRUQwQTQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVjbG9uZW5vZGVmYWxzZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWNsb25lbm9kZWZhbHNlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGUgY2xvbmVkTm9kZTsKKyAgICAgIFN0cmluZyBjbG9uZU5hbWU7CisgICAgICBOb2RlTGlzdCBjbG9uZUNoaWxkcmVuOworICAgICAgaW50IGxlbmd0aDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNsb25lZE5vZGUgPSBlbXBsb3llZU5vZGUuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgIGNsb25lTmFtZSA9IGNsb25lZE5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibmFtZSIsICJlbXBsb3llZSIsIGNsb25lTmFtZSk7CisgICAgICBjbG9uZUNoaWxkcmVuID0gY2xvbmVkTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBsZW5ndGggPSAoaW50KSBjbG9uZUNoaWxkcmVuLmdldExlbmd0aCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJsZW5ndGgiLCAwLCBsZW5ndGgpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlY2xvbmVub2RlZmFsc2UiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVjbG9uZW5vZGVmYWxzZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNsb25lbm9kZXRydWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNsb25lbm9kZXRydWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOTUyZDI5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY2xvbmVub2RldHJ1ZS5qYXZhCkBAIC0wLDAgKzEsMTM1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY2xvbmVOb2RlKGRlZXApIiBtZXRob2QgcmV0dXJucyBhIGNvcHkgb2YgdGhlIG5vZGUKKyAqICAgICBhbmQgdGhlIHN1YnRyZWUgdW5kZXIgaXQgaWYgZGVlcD10cnVlLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGludm9rZSB0aGUKKyAqICAgICAiY2xvbmVOb2RlKGRlZXApIiBtZXRob2Qgd2l0aCBkZWVwPXRydWUuICAgVGhlCisgKiAgICAgbWV0aG9kIHNob3VsZCBjbG9uZSB0aGlzIG5vZGUgYW5kIHRoZSBzdWJ0cmVlIHVuZGVyIGl0LgorICogICAgIFRoZSBOb2RlTmFtZSBvZiBlYWNoIGNoaWxkIGluIHRoZSByZXR1cm5lZCBub2RlIGlzIAorICogICAgIGNoZWNrZWQgdG8gaW5zdXJlIHRoZSBlbnRpcmUgc3VidHJlZSB1bmRlciB0aGUgc2Vjb25kCisgKiAgICAgZW1wbG95ZWUgd2FzIGNsb25lZC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTNBMEVEMEE0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zQTBFRDBBNDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWNsb25lbm9kZXRydWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVjbG9uZW5vZGV0cnVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgY2xvbmVkTm9kZTsKKyAgICAgIE5vZGVMaXN0IGNsb25lZExpc3Q7CisgICAgICBOb2RlIGNsb25lZENoaWxkOworICAgICAgU3RyaW5nIGNsb25lZENoaWxkTmFtZTsKKyAgICAgIGludCBsZW5ndGg7CisgICAgICBqYXZhLnV0aWwuTGlzdCByZXN1bHQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuTGlzdCBleHBlY3RlZFdoaXRlc3BhY2UgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgZXhwZWN0ZWRXaGl0ZXNwYWNlLmFkZCgiI3RleHQiKTsKKyAgICAgIGV4cGVjdGVkV2hpdGVzcGFjZS5hZGQoImVtcGxveWVlSWQiKTsKKyAgICAgIGV4cGVjdGVkV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICBleHBlY3RlZFdoaXRlc3BhY2UuYWRkKCJuYW1lIik7CisgICAgICBleHBlY3RlZFdoaXRlc3BhY2UuYWRkKCIjdGV4dCIpOworICAgICAgZXhwZWN0ZWRXaGl0ZXNwYWNlLmFkZCgicG9zaXRpb24iKTsKKyAgICAgIGV4cGVjdGVkV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICBleHBlY3RlZFdoaXRlc3BhY2UuYWRkKCJzYWxhcnkiKTsKKyAgICAgIGV4cGVjdGVkV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICBleHBlY3RlZFdoaXRlc3BhY2UuYWRkKCJnZW5kZXIiKTsKKyAgICAgIGV4cGVjdGVkV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICBleHBlY3RlZFdoaXRlc3BhY2UuYWRkKCJhZGRyZXNzIik7CisgICAgICBleHBlY3RlZFdoaXRlc3BhY2UuYWRkKCIjdGV4dCIpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuTGlzdCBleHBlY3RlZE5vV2hpdGVzcGFjZSA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZE5vV2hpdGVzcGFjZS5hZGQoImVtcGxveWVlSWQiKTsKKyAgICAgIGV4cGVjdGVkTm9XaGl0ZXNwYWNlLmFkZCgibmFtZSIpOworICAgICAgZXhwZWN0ZWROb1doaXRlc3BhY2UuYWRkKCJwb3NpdGlvbiIpOworICAgICAgZXhwZWN0ZWROb1doaXRlc3BhY2UuYWRkKCJzYWxhcnkiKTsKKyAgICAgIGV4cGVjdGVkTm9XaGl0ZXNwYWNlLmFkZCgiZ2VuZGVyIik7CisgICAgICBleHBlY3RlZE5vV2hpdGVzcGFjZS5hZGQoImFkZHJlc3MiKTsKKyAgICAgIAorICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgY2hpbGRMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGxlbmd0aCA9IChpbnQpIGNoaWxkTGlzdC5nZXRMZW5ndGgoKTsKKyAgICAgIGNsb25lZE5vZGUgPSBlbXBsb3llZU5vZGUuY2xvbmVOb2RlKHRydWUpOworICAgICAgY2xvbmVkTGlzdCA9IGNsb25lZE5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwQUUgPSAwOyBpbmRleE4xMDBBRSA8IGNsb25lZExpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMEFFKyspIHsKKyAgICAgICAgICBjbG9uZWRDaGlsZCA9IChOb2RlKSBjbG9uZWRMaXN0Lml0ZW0oaW5kZXhOMTAwQUUpOworICAgIGNsb25lZENoaWxkTmFtZSA9IGNsb25lZENoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICByZXN1bHQuYWRkKGNsb25lZENoaWxkTmFtZSk7CisgICAgICAgIH0KKyAgICAgIAorICAgICAgaWYgKGVxdWFscyg2LCBsZW5ndGgpKSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJub3doaXRlc3BhY2UiLCBleHBlY3RlZE5vV2hpdGVzcGFjZSwgcmVzdWx0KTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ3aGl0ZXNwYWNlIiwgZXhwZWN0ZWRXaGl0ZXNwYWNlLCByZXN1bHQpOworICAgICAgfQorICAgICAgICAKKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVjbG9uZW5vZGV0cnVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlY2xvbmVub2RldHJ1ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNsb25ldHJ1ZWNvcHl0ZXh0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjbG9uZXRydWVjb3B5dGV4dC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA2NzZlMzkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjbG9uZXRydWVjb3B5dGV4dC5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgUmV0cmlldmUgdGhlIHNlY29uZCBzYWxhcnkgYW5kCisgKiAgICAgdGhlICJjbG9uZU5vZGUoZGVlcCkiIG1ldGhvZCB3aXRoIGRlZXA9dHJ1ZS4gICBUaGUKKyAqICAgICBkdXBsaWNhdGUgbm9kZSByZXR1cm5lZCBieSB0aGUgbWV0aG9kIHNob3VsZCBjb3B5CisgKiAgICAgYW55IHRleHQgZGF0YSBjb250YWluZWQgaW4gdGhpcyBub2RlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtM0EwRUQwQTQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTNBMEVEMEE0PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlY2xvbmV0cnVlY29weXRleHQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVjbG9uZXRydWVjb3B5dGV4dChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgTm9kZSBjaGlsZE5vZGU7CisgICAgICBOb2RlIGNsb25lZE5vZGU7CisgICAgICBOb2RlIGxhc3RDaGlsZE5vZGU7CisgICAgICBTdHJpbmcgY2hpbGRWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJzYWxhcnkiKTsKKyAgICAgIGNoaWxkTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjbG9uZWROb2RlID0gY2hpbGROb2RlLmNsb25lTm9kZSh0cnVlKTsKKyAgICAgIGxhc3RDaGlsZE5vZGUgPSBjbG9uZWROb2RlLmdldExhc3RDaGlsZCgpOworICAgICAgY2hpbGRWYWx1ZSA9IGxhc3RDaGlsZE5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVDbG9uZVRydWVDb3B5VGV4dEFzc2VydDEiLCAiMzUsMDAwIiwgY2hpbGRWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVjbG9uZXRydWVjb3B5dGV4dCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWNsb25ldHJ1ZWNvcHl0ZXh0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY29tbWVudG5vZGVhdHRyaWJ1dGVzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjb21tZW50bm9kZWF0dHJpYnV0ZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZmUzM2I4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY29tbWVudG5vZGVhdHRyaWJ1dGVzLmphdmEKQEAgLTAsMCArMSwxMDAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRBdHRyaWJ1dGVzKCkiIG1ldGhvZCBpbnZva2VkIG9uIGEgQ29tbWVudCAKKyAqICAgICBOb2RlIHJldHVybnMgbnVsbC4KKyAqICAgICBGaW5kIGFueSBjb21tZW50IHRoYXQgaXMgYW4gaW1tZWRpYXRlIGNoaWxkIG9mIHRoZSByb290CisgKiAgICAgYW5kIGFzc2VydCB0aGF0IE5vZGUuYXR0cmlidXRlcyBpcyBudWxsLiAgVGhlbiBjcmVhdGUKKyAqICAgICBhIG5ldyBjb21tZW50IG5vZGUgKGluIGNhc2UgdGhleSBoYWQgYmVlbiBvbWl0dGVkKSBhbmQKKyAqICAgICBtYWtlIHRoZSBhc3NlcnRpb24uICAgIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzI4Mjc5MzIyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzI4Mjc5MzIyPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDgiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVjb21tZW50bm9kZWF0dHJpYnV0ZXMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVjb21tZW50bm9kZWF0dHJpYnV0ZXMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgTm9kZSBjaGlsZE5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0ckxpc3Q7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgY2hpbGRMaXN0ID0gZG9jLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDQzID0gMDsgaW5kZXhOMTAwNDMgPCBjaGlsZExpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDQzKyspIHsKKyAgICAgICAgICBjaGlsZE5vZGUgPSAoTm9kZSkgY2hpbGRMaXN0Lml0ZW0oaW5kZXhOMTAwNDMpOworICAgIG5vZGVUeXBlID0gKGludCkgY2hpbGROb2RlLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoOCwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgYXR0ckxpc3QgPSBjaGlsZE5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXNzZXJ0TnVsbCgiYXR0cmlidXRlc051bGwiLCBhdHRyTGlzdCk7CisgICAgICB9CisgICAgICB9CisgICAgICBjaGlsZE5vZGUgPSBkb2MuY3JlYXRlQ29tbWVudCgiVGhpcyBpcyBhIGNvbW1lbnQiKTsKKyAgICAgIGF0dHJMaXN0ID0gY2hpbGROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGFzc2VydE51bGwoImNyZWF0ZWRBdHRyaWJ1dGVzTnVsbCIsIGF0dHJMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWNvbW1lbnRub2RlYXR0cmlidXRlcyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWNvbW1lbnRub2RlYXR0cmlidXRlcy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNvbW1lbnRub2RlbmFtZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY29tbWVudG5vZGVuYW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmQ0OWFjMwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNvbW1lbnRub2RlbmFtZS5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlTmFtZSgpIiBtZXRob2QgZm9yIGEgCisgKiAgICAgQ29tbWVudCBOb2RlIGlzICIjY29tbWVudCIuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIENvbW1lbnQgbm9kZSBpbiB0aGUgWE1MIGZpbGUgCisgKiAgICAgYW5kIGNoZWNrIHRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlTmFtZSgpIiAKKyAqICAgICBtZXRob2QuICAgSXQgc2hvdWxkIGJlIGVxdWFsIHRvICIjY29tbWVudCIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MjgyNzkzMjIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MjgyNzkzMjI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVjb21tZW50bm9kZW5hbWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVjb21tZW50bm9kZW5hbWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGNvbW1lbnROb2RlOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgU3RyaW5nIGNvbW1lbnROb2RlTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA0MCA9IDA7IGluZGV4TjEwMDQwIDwgZWxlbWVudExpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDQwKyspIHsKKyAgICAgICAgICBjb21tZW50Tm9kZSA9IChOb2RlKSBlbGVtZW50TGlzdC5pdGVtKGluZGV4TjEwMDQwKTsKKyAgICBub2RlVHlwZSA9IChpbnQpIGNvbW1lbnROb2RlLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoOCwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgY29tbWVudE5vZGVOYW1lID0gY29tbWVudE5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY29tbWVudE5vZGVOYW1lIiwgIiNjb21tZW50IiwgY29tbWVudE5vZGVOYW1lKTsKKyAgICAgIH0KKyAgICAgIH0KKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWNvbW1lbnRub2RlbmFtZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWNvbW1lbnRub2RlbmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNvbW1lbnRub2RldHlwZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlY29tbWVudG5vZGV0eXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzNkMjA2MAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNvbW1lbnRub2RldHlwZS5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0Tm9kZVR5cGUoKSIgbWV0aG9kIGZvciBhIENvbW1lbnQgTm9kZQorICogICAgIHJldHVybnMgdGhlIGNvbnN0YW50IHZhbHVlIDguCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIG5vZGVzIGZyb20gdGhlIGRvY3VtZW50IGFuZCBjaGVjayBmb3IKKyAqICAgICBhIGNvbW1lbnQgbm9kZSBhbmQgaW52b2tlIHRoZSAiZ2V0Tm9kZVR5cGUoKSIgbWV0aG9kLiAgIFRoaXMgc2hvdWxkICAgCisgKiAgICAgcmV0dXJuIDguIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMTEyMzc1NTg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTcyODI3OTMyMiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTcyODI3OTMyMjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWNvbW1lbnRub2RldHlwZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWNvbW1lbnRub2RldHlwZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCB0ZXN0TGlzdDsKKyAgICAgIE5vZGUgY29tbWVudE5vZGU7CisgICAgICBTdHJpbmcgY29tbWVudE5vZGVOYW1lOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIHRlc3RMaXN0ID0gZG9jLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDQwID0gMDsgaW5kZXhOMTAwNDAgPCB0ZXN0TGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwNDArKykgeworICAgICAgICAgIGNvbW1lbnROb2RlID0gKE5vZGUpIHRlc3RMaXN0Lml0ZW0oaW5kZXhOMTAwNDApOworICAgIGNvbW1lbnROb2RlTmFtZSA9IGNvbW1lbnROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoIiNjb21tZW50IiwgY29tbWVudE5vZGVOYW1lKSkgeworICAgICAgICAgIG5vZGVUeXBlID0gKGludCkgY29tbWVudE5vZGUuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZUNvbW1lbnROb2RlVHlwZUFzc2VydDEiLCA4LCBub2RlVHlwZSk7CisgICAgICB9CisgICAgICB9CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVjb21tZW50bm9kZXR5cGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVjb21tZW50bm9kZXR5cGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjb21tZW50bm9kZXZhbHVlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVjb21tZW50bm9kZXZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjEwZGY1ZgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWNvbW1lbnRub2RldmFsdWUuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAiZ2V0Tm9kZVZhbHVlKCkiIG1ldGhvZCBmb3IgYSAKKyAqICAgICBDb21tZW50IE5vZGUgaXMgdGhlIGNvbnRlbnQgb2YgdGhlIGNvbW1lbnQuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIGNvbW1lbnQgaW4gdGhlIFhNTCBmaWxlIGFuZCAgIAorICogICAgIGNoZWNrIHRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlVmFsdWUoKSIgbWV0aG9kLiAKKyAqICAgICBJdCBzaG91bGQgYmUgZXF1YWwgdG8gIlRoaXMgaXMgY29tbWVudCBudW1iZXIgMSIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MjgyNzkzMjIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MjgyNzkzMjI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVjb21tZW50bm9kZXZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlY29tbWVudG5vZGV2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgY29tbWVudE5vZGU7CisgICAgICBTdHJpbmcgY29tbWVudE5hbWU7CisgICAgICBTdHJpbmcgY29tbWVudFZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDQwID0gMDsgaW5kZXhOMTAwNDAgPCBlbGVtZW50TGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwNDArKykgeworICAgICAgICAgIGNvbW1lbnROb2RlID0gKE5vZGUpIGVsZW1lbnRMaXN0Lml0ZW0oaW5kZXhOMTAwNDApOworICAgIGNvbW1lbnROYW1lID0gY29tbWVudE5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygiI2NvbW1lbnQiLCBjb21tZW50TmFtZSkpIHsKKyAgICAgICAgICBjb21tZW50VmFsdWUgPSBjb21tZW50Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygidmFsdWUiLCAiIFRoaXMgaXMgY29tbWVudCBudW1iZXIgMS4iLCBjb21tZW50VmFsdWUpOworICAgICAgfQorICAgICAgfQorICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlY29tbWVudG5vZGV2YWx1ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWNvbW1lbnRub2RldmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVkb2N1bWVudGZyYWdtZW50bm9kZW5hbWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RlbmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE0OWNlYmQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVkb2N1bWVudGZyYWdtZW50bm9kZW5hbWUuamF2YQpAQCAtMCwwICsxLDg3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAiZ2V0Tm9kZU5hbWUoKSIgbWV0aG9kIGZvciBhIAorICogICAgIERvY3VtZW50RnJhZ21lbnQgTm9kZSBpcyAiI2RvY3VtZW50LWZyYW1lbnQiLgorICogICAgIFJldHJpZXZlIHRoZSBET00gZG9jdW1lbnQgYW5kIGludm9rZSB0aGUKKyAqICAgICAiY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpIiBtZXRob2QgYW5kIGNoZWNrIHRoZSBzdHJpbmcgICAgICAKKyAqICAgICByZXR1cm5lZCBieSB0aGUgImdldE5vZGVOYW1lKCkiIG1ldGhvZC4gICBJdCBzaG91bGQgYmUgCisgKiAgICAgZXF1YWwgdG8gIiNkb2N1bWVudC1mcmFnbWVudCIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUI2M0VEMUEzIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1CNjNFRDFBMzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RlbmFtZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RlbmFtZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50RnJhZ21lbnQgZG9jRnJhZ21lbnQ7CisgICAgICBTdHJpbmcgZG9jdW1lbnRGcmFnbWVudE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBkb2NGcmFnbWVudCA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CisgICAgICBkb2N1bWVudEZyYWdtZW50TmFtZSA9IGRvY0ZyYWdtZW50LmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVEb2N1bWVudEZyYWdtZW50Tm9kZU5hbWVBc3NlcnQxIiwgIiNkb2N1bWVudC1mcmFnbWVudCIsIGRvY3VtZW50RnJhZ21lbnROYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RlbmFtZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWRvY3VtZW50ZnJhZ21lbnRub2RlbmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldHlwZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGV0eXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTM3NzhhNwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldHlwZS5qYXZhCkBAIC0wLDAgKzEsODcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0Tm9kZVR5cGUoKSIgbWV0aG9kIGZvciBhIERvY3VtZW50RnJhZ21lbnQgTm9kZQorICogICAgIHJldHVybnMgdGhlIGNvbnN0YW50IHZhbHVlIDExLgorICogICAgIEludm9rZSB0aGUgImNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSIgbWV0aG9kIGFuZCAgICAKKyAqICAgICBleGFtaW5lIHRoZSBOb2RlVHlwZSBvZiB0aGUgZG9jdW1lbnQgZnJhZ21lbnQKKyAqICAgICByZXR1cm5lZCBieSB0aGUgImdldE5vZGVUeXBlKCkiIG1ldGhvZC4gICBUaGUgbWV0aG9kIAorICogICAgIHNob3VsZCByZXR1cm4gMTEuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMTEyMzc1NTg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtQjYzRUQxQTMiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUI2M0VEMUEzPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlZG9jdW1lbnRmcmFnbWVudG5vZGV0eXBlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlZG9jdW1lbnRmcmFnbWVudG5vZGV0eXBlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRGcmFnbWVudCBkb2N1bWVudEZyYWdtZW50Tm9kZTsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGRvY3VtZW50RnJhZ21lbnROb2RlID0gZG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgZG9jdW1lbnRGcmFnbWVudE5vZGUuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZURvY3VtZW50RnJhZ21lbnROb2RlVHlwZUFzc2VydDEiLCAxMSwgbm9kZVR5cGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGV0eXBlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlZG9jdW1lbnRmcmFnbWVudG5vZGV0eXBlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGV2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnRmcmFnbWVudG5vZGV2YWx1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZhM2JkM2MKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVkb2N1bWVudGZyYWdtZW50bm9kZXZhbHVlLmphdmEKQEAgLTAsMCArMSw5MyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIHN0cmluZyByZXR1cm5lZCBieSB0aGUgImdldE5vZGVWYWx1ZSgpIiBtZXRob2QgZm9yIGEgCisgKiAgICAgRG9jdW1lbnRGcmFnbWVudCBOb2RlIGlzIG51bGwuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIERPTSBkb2N1bWVudCBhbmQgaW52b2tlIHRoZQorICogICAgICJjcmVhdGVEb2N1bWVudEZyYWdtZW50KCkiIG1ldGhvZCBhbmQgY2hlY2sgdGhlIHN0cmluZyAgICAgIAorICogICAgIHJldHVybmVkIGJ5IHRoZSAiZ2V0Tm9kZVZhbHVlKCkiIG1ldGhvZC4gICBJdCBzaG91bGQgYmUgCisgKiAgICAgZXF1YWwgdG8gbnVsbC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtQjYzRUQxQTMiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUI2M0VEMUEzPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODA8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldmFsdWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVkb2N1bWVudGZyYWdtZW50bm9kZXZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRGcmFnbWVudCBkb2NGcmFnbWVudDsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyTGlzdDsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGRvY0ZyYWdtZW50ID0gZG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKKyAgICAgIGF0dHJMaXN0ID0gZG9jRnJhZ21lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXNzZXJ0TnVsbCgiYXR0cmlidXRlc051bGwiLCBhdHRyTGlzdCk7CisgICAgICB2YWx1ZSA9IGRvY0ZyYWdtZW50LmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgiaW5pdGlhbGx5TnVsbCIsIHZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50ZnJhZ21lbnRub2RldmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVkb2N1bWVudGZyYWdtZW50bm9kZXZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnRub2RlYXR0cmlidXRlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVkb2N1bWVudG5vZGVhdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NzBkMmZiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnRub2RlYXR0cmlidXRlLmphdmEKQEAgLTAsMCArMSw4MSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIFRoZSAiZ2V0QXR0cmlidXRlcygpIiBtZXRob2QgaW52b2tlZCBvbiBhIERvY3VtZW50CisgKiBOb2RlIHJldHVybnMgbnVsbC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjaS1Eb2N1bWVudCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjaS1Eb2N1bWVudDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWRvY3VtZW50bm9kZWF0dHJpYnV0ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWRvY3VtZW50bm9kZWF0dHJpYnV0ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0ckxpc3Q7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgYXR0ckxpc3QgPSBkb2MuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXNzZXJ0TnVsbCgiZG9jdW1lbnRBdHRyaWJ1dGVzTnVsbCIsIGF0dHJMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50bm9kZWF0dHJpYnV0ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWRvY3VtZW50bm9kZWF0dHJpYnV0ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50bm9kZW5hbWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50bm9kZW5hbWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMGRhOGNkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnRub2RlbmFtZS5qYXZhCkBAIC0wLDAgKzEsODQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlTmFtZSgpIiBtZXRob2QgZm9yIGEgCisgKiAgICAgRG9jdW1lbnQgTm9kZSBpcyAiI2RvY3VtZW50Ii4KKyAqICAgICBSZXRyaWV2ZSB0aGUgRE9NIGRvY3VtZW50IGFuZCBjaGVjayB0aGUgc3RyaW5nIHJldHVybmVkCisgKiAgICAgYnkgdGhlICJnZXROb2RlTmFtZSgpIiBtZXRob2QuICAgSXQgc2hvdWxkIGJlIGVxdWFsIHRvIAorICogICAgICIjZG9jdW1lbnQiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjaS1Eb2N1bWVudCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjaS1Eb2N1bWVudDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlZG9jdW1lbnRub2RlbmFtZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWRvY3VtZW50bm9kZW5hbWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgU3RyaW5nIGRvY3VtZW50TmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2N1bWVudE5hbWUgPSBkb2MuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnROb2RlTmFtZSIsICIjZG9jdW1lbnQiLCBkb2N1bWVudE5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnRub2RlbmFtZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWRvY3VtZW50bm9kZW5hbWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVkb2N1bWVudG5vZGV0eXBlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVkb2N1bWVudG5vZGV0eXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmIzZDMyYgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50bm9kZXR5cGUuamF2YQpAQCAtMCwwICsxLDgzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIFRoZSAiZ2V0Tm9kZVR5cGUoKSIgbWV0aG9kIGZvciBhIERvY3VtZW50IE5vZGUKKyAqIHJldHVybnMgdGhlIGNvbnN0YW50IHZhbHVlIDkuCisgKiBSZXRyaWV2ZSB0aGUgZG9jdW1lbnQgYW5kIGludm9rZSB0aGUgImdldE5vZGVUeXBlKCkiIAorICogbWV0aG9kLiAgIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiA5LiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI2ktRG9jdW1lbnQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI2ktRG9jdW1lbnQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMTEyMzc1NTg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVkb2N1bWVudG5vZGV0eXBlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlZG9jdW1lbnRub2RldHlwZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgbm9kZVR5cGUgPSAoaW50KSBkb2MuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZURvY3VtZW50Tm9kZVR5cGVBc3NlcnQxIiwgOSwgbm9kZVR5cGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnRub2RldHlwZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWRvY3VtZW50bm9kZXR5cGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVkb2N1bWVudG5vZGV2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnRub2RldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zY2FhMWNiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnRub2RldmFsdWUuamF2YQpAQCAtMCwwICsxLDg0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAiZ2V0Tm9kZVZhbHVlKCkiIG1ldGhvZCBmb3IgYSAKKyAqICAgICBEb2N1bWVudCBOb2RlIGlzIG51bGwuCisgKiAgICAgUmV0cmlldmUgdGhlIERPTSBEb2N1bWVudCBhbmQgY2hlY2sgdGhlIHN0cmluZyByZXR1cm5lZAorICogICAgIGJ5IHRoZSAiZ2V0Tm9kZVZhbHVlKCkiIG1ldGhvZC4gICBJdCBzaG91bGQgYmUgZXF1YWwgdG8gCisgKiAgICAgbnVsbC4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNpLURvY3VtZW50Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNpLURvY3VtZW50PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODA8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVkb2N1bWVudG5vZGV2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWRvY3VtZW50bm9kZXZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIFN0cmluZyBkb2N1bWVudFZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGRvY3VtZW50VmFsdWUgPSBkb2MuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJkb2N1bWVudE5vZGVWYWx1ZU51bGwiLCBkb2N1bWVudFZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50bm9kZXZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlZG9jdW1lbnRub2RldmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVkb2N1bWVudHR5cGVub2RlbmFtZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnR0eXBlbm9kZW5hbWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ODUzYTVhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnR0eXBlbm9kZW5hbWUuamF2YQpAQCAtMCwwICsxLDkwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFJldHJpZXZlIHRoZSBET0NUWVBFIGRlY2xhcmF0aW9uIGZyb20gdGhlIFhNTCBmaWxlIGFuZAorICogICAgIGNoZWNrIHRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlTmFtZSgpIiAKKyAqICAgICBtZXRob2QuICAgSXQgc2hvdWxkIGJlIGVxdWFsIHRvICJzdGFmZiIgb3IgInN2ZyIuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWRvY3VtZW50dHlwZW5vZGVuYW1lIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlZG9jdW1lbnR0eXBlbm9kZW5hbWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBTdHJpbmcgZG9jdW1lbnRUeXBlTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImRvY1R5cGVOb3ROdWxsIiwgZG9jVHlwZSk7CisgICAgICBkb2N1bWVudFR5cGVOYW1lID0gZG9jVHlwZS5nZXROb2RlTmFtZSgpOworICAgICAgCisgICAgICBpZiAoKCJpbWFnZS9zdmcreG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N0eXBlTmFtZVNWRyIsICJzdmciLCBkb2N1bWVudFR5cGVOYW1lKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudE5hbWUiLCAic3RhZmYiLCBkb2N1bWVudFR5cGVOYW1lKTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnR0eXBlbm9kZW5hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVkb2N1bWVudHR5cGVub2RlbmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50dHlwZW5vZGV0eXBlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVkb2N1bWVudHR5cGVub2RldHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ2ZDkwZjAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVkb2N1bWVudHR5cGVub2RldHlwZS5qYXZhCkBAIC0wLDAgKzEsODMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXROb2RlVHlwZSgpIiBtZXRob2QgZm9yIGEgRG9jdW1lbnRUeXBlIE5vZGUKKyAqICAgICByZXR1cm5zIHRoZSBjb25zdGFudCB2YWx1ZSAxMC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIzNzU1OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlZG9jdW1lbnR0eXBlbm9kZXR5cGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVkb2N1bWVudHR5cGVub2RldHlwZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jdW1lbnRUeXBlTm9kZTsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2N1bWVudFR5cGVOb2RlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImRvY3R5cGVOb3ROdWxsIiwgZG9jdW1lbnRUeXBlTm9kZSk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGRvY3VtZW50VHlwZU5vZGUuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZVR5cGUiLCAxMCwgbm9kZVR5cGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnR0eXBlbm9kZXR5cGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVkb2N1bWVudHR5cGVub2RldHlwZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50dHlwZW5vZGV2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZG9jdW1lbnR0eXBlbm9kZXZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWIwMTNkOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWRvY3VtZW50dHlwZW5vZGV2YWx1ZS5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIHN0cmluZyByZXR1cm5lZCBieSB0aGUgImdldE5vZGVWYWx1ZSgpIiBtZXRob2QgZm9yIGEgCisgKiAgICAgRG9jdW1lbnRUeXBlIE5vZGUgaXMgbnVsbC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlZG9jdW1lbnR0eXBlbm9kZXZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlZG9jdW1lbnR0eXBlbm9kZXZhbHVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZG9jVHlwZU5vdE51bGwiLCBkb2NUeXBlKTsKKyAgICAgIGF0dHJMaXN0ID0gZG9jVHlwZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBhc3NlcnROdWxsKCJkb2N0eXBlQXR0cmlidXRlc051bGwiLCBhdHRyTGlzdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVkb2N1bWVudHR5cGVub2RldmFsdWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVkb2N1bWVudHR5cGVub2RldmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVlbGVtZW50bm9kZWF0dHJpYnV0ZXMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWVsZW1lbnRub2RlYXR0cmlidXRlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMzMThjOWQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVlbGVtZW50bm9kZWF0dHJpYnV0ZXMuamF2YQpAQCAtMCwwICsxLDEwMyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRBdHRyaWJ1dGVzKCkiIG1ldGhvZCBpbnZva2VkIG9uIGFuIEVsZW1lbnQKKyAqICAgICBOb2RlIHJldHVybnMgYSBOYW1lZE5vZGVNYXAgY29udGFpbmluZyB0aGUgYXR0cmlidXRlcworICogICAgIG9mIHRoaXMgbm9kZS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgdGhpcmQgZW1wbG95ZWUgYW5kCisgKiAgICAgaW52b2tlIHRoZSAiZ2V0QXR0cmlidXRlcygpIiBtZXRob2QuICAgSXQgc2hvdWxkIHJldHVybgorICogICAgIGEgTmFtZWROb2RlTWFwIGNvbnRhaW5pbmcgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIEVsZW1lbnQKKyAqICAgICBub2RlLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVlbGVtZW50bm9kZWF0dHJpYnV0ZXMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVlbGVtZW50bm9kZWF0dHJpYnV0ZXMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RBZGRyOworICAgICAgTmFtZWROb2RlTWFwIGFkZHJBdHRyOworICAgICAgTm9kZSBhdHRyTm9kZTsKKyAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9uIGF0dHJMaXN0ID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb24gZXhwZWN0ZWQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgZXhwZWN0ZWQuYWRkKCJkb21lc3RpYyIpOworICAgICAgZXhwZWN0ZWQuYWRkKCJzdHJlZXQiKTsKKyAgICAgIAorICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0QWRkciA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgYWRkckF0dHIgPSB0ZXN0QWRkci5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA1QyA9IDA7IGluZGV4TjEwMDVDIDwgYWRkckF0dHIuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDVDKyspIHsKKyAgICAgICAgICBhdHRyTm9kZSA9IChOb2RlKSBhZGRyQXR0ci5pdGVtKGluZGV4TjEwMDVDKTsKKyAgICBhdHRyTmFtZSA9IGF0dHJOb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBhdHRyTGlzdC5hZGQoYXR0ck5hbWUpOworICAgICAgICB9CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVFbGVtZW50Tm9kZVZhbHVlQXNzZXJ0MSIsIGV4cGVjdGVkLCBhdHRyTGlzdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVlbGVtZW50bm9kZWF0dHJpYnV0ZXMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVlbGVtZW50bm9kZWF0dHJpYnV0ZXMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVlbGVtZW50bm9kZW5hbWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWVsZW1lbnRub2RlbmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg5MmYxYWEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVlbGVtZW50bm9kZW5hbWUuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAiZ2V0Tm9kZU5hbWUoKSIgbWV0aG9kIGZvciBhbiAKKyAqICAgICBFbGVtZW50IE5vZGUgaXMgaXRzIHRhZ05hbWUuIAorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBmaXJzdCBFbGVtZW50IE5vZGUoUm9vdCBOb2RlKSBvZiB0aGUgICAKKyAqICAgICBET00gb2JqZWN0IGFuZCBjaGVjayB0aGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAgICAgICAgICAgIAorICogICAgICJnZXROb2RlTmFtZSgpIiBtZXRob2QuICAgSXQgc2hvdWxkIGJlIGVxdWFsIHRvIGl0cworICogICAgIHRhZ05hbWUuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjUxIj5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjUxPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlZWxlbWVudG5vZGVuYW1lIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlZWxlbWVudG5vZGVuYW1lKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudE5vZGU7CisgICAgICBTdHJpbmcgZWxlbWVudE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudE5vZGUgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBlbGVtZW50TmFtZSA9IGVsZW1lbnROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICAKKyAgICAgIGlmICgoImltYWdlL3N2Zyt4bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoInN2Z05vZGVOYW1lIiwgInN2ZyIsIGVsZW1lbnROYW1lKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlRWxlbWVudE5vZGVOYW1lQXNzZXJ0MSIsICJzdGFmZiIsIGVsZW1lbnROYW1lKTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZWxlbWVudG5vZGVuYW1lIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlZWxlbWVudG5vZGVuYW1lLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZWxlbWVudG5vZGV0eXBlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVlbGVtZW50bm9kZXR5cGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NzY2ODU5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZWxlbWVudG5vZGV0eXBlLmphdmEKQEAgLTAsMCArMSw4NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXROb2RlVHlwZSgpIiBtZXRob2QgZm9yIGFuIEVsZW1lbnQgTm9kZQorICogICAgIHJldHVybnMgdGhlIGNvbnN0YW50IHZhbHVlIDEuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHJvb3Qgbm9kZSBhbmQgaW52b2tlIHRoZSAiZ2V0Tm9kZVR5cGUoKSIgICAKKyAqICAgICBtZXRob2QuICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIDEuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMTEyMzc1NTg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVlbGVtZW50bm9kZXR5cGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVlbGVtZW50bm9kZXR5cGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCByb290Tm9kZTsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICByb290Tm9kZSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgcm9vdE5vZGUuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZUVsZW1lbnROb2RlVHlwZUFzc2VydDEiLCAxLCBub2RlVHlwZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVlbGVtZW50bm9kZXR5cGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVlbGVtZW50bm9kZXR5cGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVlbGVtZW50bm9kZXZhbHVlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVlbGVtZW50bm9kZXZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmZlM2E5ZAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWVsZW1lbnRub2RldmFsdWUuamF2YQpAQCAtMCwwICsxLDgyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlVmFsdWUoKSIgbWV0aG9kIGZvciBhbiAKKyAqICAgICBFbGVtZW50IE5vZGUgaXMgbnVsbC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODA8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVlbGVtZW50bm9kZXZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlZWxlbWVudG5vZGV2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnROb2RlOworICAgICAgU3RyaW5nIGVsZW1lbnRWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50Tm9kZSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIGVsZW1lbnRWYWx1ZSA9IGVsZW1lbnROb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgiZWxlbWVudE5vZGVWYWx1ZU51bGwiLCBlbGVtZW50VmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZWxlbWVudG5vZGV2YWx1ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWVsZW1lbnRub2RldmFsdWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVlbnRpdHlub2RlYXR0cmlidXRlcy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZW50aXR5bm9kZWF0dHJpYnV0ZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZDgzZmUxCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZW50aXR5bm9kZWF0dHJpYnV0ZXMuamF2YQpAQCAtMCwwICsxLDg5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0QXR0cmlidXRlcygpIiBtZXRob2QgaW52b2tlZCBvbiBhbiBFbnRpdHkgCisgKiAgICAgTm9kZSByZXR1cm5zIG51bGwuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlZW50aXR5bm9kZWF0dHJpYnV0ZXMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVlbnRpdHlub2RlYXR0cmlidXRlcyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdGllczsKKyAgICAgIE5vZGUgZW50aXR5Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyTGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImRvY1R5cGVOb3ROdWxsIiwgZG9jVHlwZSk7CisgICAgICBlbnRpdGllcyA9IGRvY1R5cGUuZ2V0RW50aXRpZXMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudGl0aWVzTm90TnVsbCIsIGVudGl0aWVzKTsKKyAgICAgIGVudGl0eU5vZGUgPSBlbnRpdGllcy5nZXROYW1lZEl0ZW0oImVudDEiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudDFOb3ROdWxsIiwgZW50aXR5Tm9kZSk7CisgICAgICBhdHRyTGlzdCA9IGVudGl0eU5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXNzZXJ0TnVsbCgiZW50aXR5QXR0cmlidXRlc051bGwiLCBhdHRyTGlzdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVlbnRpdHlub2RlYXR0cmlidXRlcyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWVudGl0eW5vZGVhdHRyaWJ1dGVzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZW50aXR5bm9kZW5hbWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWVudGl0eW5vZGVuYW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjc5YjViZAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWVudGl0eW5vZGVuYW1lLmphdmEKQEAgLTAsMCArMSw4OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIENoZWNrIHRoZSBub2RlTmFtZSBvZiB0aGUgZW50aXR5IHJldHVybmVkIGJ5IERvY3VtZW50VHlwZS5lbnRpdGllcy5nZXROYW1lZEl0ZW0oImVudDEiKS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVlbnRpdHlub2RlbmFtZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWVudGl0eW5vZGVuYW1lKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTmFtZWROb2RlTWFwIGVudGl0aWVzOworICAgICAgTm9kZSBlbnRpdHlOb2RlOworICAgICAgU3RyaW5nIGVudGl0eU5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgZW50aXRpZXMgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdGllc05vdE51bGwiLCBlbnRpdGllcyk7CisgICAgICBlbnRpdHlOb2RlID0gZW50aXRpZXMuZ2V0TmFtZWRJdGVtKCJlbnQxIik7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdHlOb2RlTm90TnVsbCIsIGVudGl0eU5vZGUpOworICAgICAgZW50aXR5TmFtZSA9IGVudGl0eU5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZW50aXR5Tm9kZU5hbWUiLCAiZW50MSIsIGVudGl0eU5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZW50aXR5bm9kZW5hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVlbnRpdHlub2RlbmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWVudGl0eW5vZGV0eXBlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVlbnRpdHlub2RldHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFkNmRjNjkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVlbnRpdHlub2RldHlwZS5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXROb2RlVHlwZSgpIiBtZXRob2QgZm9yIGFuIEVudGl0eSBOb2RlCisgKiAgICAgcmV0dXJucyB0aGUgY29uc3RhbnQgdmFsdWUgNi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExMTIzNzU1OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlZW50aXR5bm9kZXR5cGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVlbnRpdHlub2RldHlwZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdGllczsKKyAgICAgIE5vZGUgZW50aXR5Tm9kZTsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImRvY1R5cGVOb3ROdWxsIiwgZG9jVHlwZSk7CisgICAgICBlbnRpdGllcyA9IGRvY1R5cGUuZ2V0RW50aXRpZXMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudGl0aWVzTm90TnVsbCIsIGVudGl0aWVzKTsKKyAgICAgIGVudGl0eU5vZGUgPSBlbnRpdGllcy5nZXROYW1lZEl0ZW0oImVudDEiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudDFOb3ROdWxsIiwgZW50aXR5Tm9kZSk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGVudGl0eU5vZGUuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZW50aXR5Tm9kZVR5cGUiLCA2LCBub2RlVHlwZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVlbnRpdHlub2RldHlwZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWVudGl0eW5vZGV0eXBlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZW50aXR5bm9kZXZhbHVlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVlbnRpdHlub2RldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NDMyZDQ5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZW50aXR5bm9kZXZhbHVlLmphdmEKQEAgLTAsMCArMSw4OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAiZ2V0Tm9kZVZhbHVlKCkiIG1ldGhvZCBmb3IgYW4gCisgKiAgICAgRW50aXR5IE5vZGUgaXMgbnVsbC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODA8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVlbnRpdHlub2RldmFsdWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVlbnRpdHlub2RldmFsdWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBOYW1lZE5vZGVNYXAgZW50aXRpZXM7CisgICAgICBOb2RlIGVudGl0eU5vZGU7CisgICAgICBTdHJpbmcgZW50aXR5VmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgZW50aXRpZXMgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdGllc05vdE51bGwiLCBlbnRpdGllcyk7CisgICAgICBlbnRpdHlOb2RlID0gZW50aXRpZXMuZ2V0TmFtZWRJdGVtKCJlbnQxIik7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnQxTm90TnVsbCIsIGVudGl0eU5vZGUpOworICAgICAgZW50aXR5VmFsdWUgPSBlbnRpdHlOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgiZW50aXR5Tm9kZVZhbHVlIiwgZW50aXR5VmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZW50aXR5bm9kZXZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlZW50aXR5bm9kZXZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZW50aXR5cmVmZXJlbmNlbm9kZWF0dHJpYnV0ZXMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWVudGl0eXJlZmVyZW5jZW5vZGVhdHRyaWJ1dGVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzZkOGVhMwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWVudGl0eXJlZmVyZW5jZW5vZGVhdHRyaWJ1dGVzLmphdmEKQEAgLTAsMCArMSw5MyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEF0dHJpYnV0ZXMoKSIgbWV0aG9kIGludm9rZWQgb24gYW4gRW50aXR5UmVmZXJlbmNlIAorICogICAgIE5vZGUgcmV0dXJucyBudWxsLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWVudGl0eXJlZmVyZW5jZW5vZGVhdHRyaWJ1dGVzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlZW50aXR5cmVmZXJlbmNlbm9kZWF0dHJpYnV0ZXMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgZW50UmVmQWRkcjsKKyAgICAgIE5vZGUgZW50UmVmTm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyTGlzdDsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICBlbnRSZWZBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBlbnRSZWZOb2RlID0gZW50UmVmQWRkci5nZXRGaXJzdENoaWxkKCk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGVudFJlZk5vZGUuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKCFlcXVhbHMoNSwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgZW50UmVmTm9kZSA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDIiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZW50UmVmTm9kZSk7CisgICAgICB9CisgICAgYXR0ckxpc3QgPSBlbnRSZWZOb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGFzc2VydE51bGwoImF0dHJMaXN0IiwgYXR0ckxpc3QpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZW50aXR5cmVmZXJlbmNlbm9kZWF0dHJpYnV0ZXMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVlbnRpdHlyZWZlcmVuY2Vub2RlYXR0cmlidXRlcy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWVudGl0eXJlZmVyZW5jZW5vZGVuYW1lLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVlbnRpdHlyZWZlcmVuY2Vub2RlbmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVlZjJiMTYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVlbnRpdHlyZWZlcmVuY2Vub2RlbmFtZS5qYXZhCkBAIC0wLDAgKzEsOTggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIHN0cmluZyByZXR1cm5lZCBieSB0aGUgImdldE5vZGVOYW1lKCkiIG1ldGhvZCBmb3IgYW4gCisgKiAgICAgRW50aXR5UmVmZXJlbmNlIE5vZGUgaXMgdGhlIG5hbWUgb2YgdGhlIGVudGl0eSByZWZlcmVuY2VkLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBmaXJzdCBFbnRpdHkgUmVmZXJlbmNlIG5vZGUgZnJvbSB0aGUgbGFzdAorICogICAgIGNoaWxkIG9mIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGNoZWNrIHRoZSBzdHJpbmcgCisgKiAgICAgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlTmFtZSgpIiBtZXRob2QuICAgSXQgc2hvdWxkIGJlIAorICogICAgIGVxdWFsIHRvICJlbnQyIi4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlZW50aXR5cmVmZXJlbmNlbm9kZW5hbWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVlbnRpdHlyZWZlcmVuY2Vub2RlbmFtZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgZW50UmVmQWRkcjsKKyAgICAgIE5vZGUgZW50UmVmTm9kZTsKKyAgICAgIFN0cmluZyBlbnRSZWZOYW1lOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICBlbnRSZWZBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBlbnRSZWZOb2RlID0gZW50UmVmQWRkci5nZXRGaXJzdENoaWxkKCk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGVudFJlZk5vZGUuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKCFlcXVhbHMoNSwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgZW50UmVmTm9kZSA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDIiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZW50UmVmTm9kZSk7CisgICAgICB9CisgICAgZW50UmVmTmFtZSA9IGVudFJlZk5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZUVudGl0eVJlZmVyZW5jZU5vZGVOYW1lQXNzZXJ0MSIsICJlbnQyIiwgZW50UmVmTmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVlbnRpdHlyZWZlcmVuY2Vub2RlbmFtZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWVudGl0eXJlZmVyZW5jZW5vZGVuYW1lLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZW50aXR5cmVmZXJlbmNlbm9kZXR5cGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWVudGl0eXJlZmVyZW5jZW5vZGV0eXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzQyNmNhZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWVudGl0eXJlZmVyZW5jZW5vZGV0eXBlLmphdmEKQEAgLTAsMCArMSw5NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldE5vZGVUeXBlKCkiIG1ldGhvZCBmb3IgYW4gRW50aXR5UmVmZXJlbmNlIE5vZGUKKyAqICAgICByZXR1cm5zIHRoZSBjb25zdGFudCB2YWx1ZSA1LgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBFbnRpdHlSZWZlcmVuY2Ugbm9kZSBmcm9tIHRoZSBsYXN0IGNoaWxkCisgKiAgICAgb2YgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgaW52b2tlIHRoZSAiZ2V0Tm9kZVR5cGUoKSIgICAKKyAqICAgICBtZXRob2QuICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIDUuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMTEyMzc1NTg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVlbnRpdHlyZWZlcmVuY2Vub2RldHlwZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWVudGl0eXJlZmVyZW5jZW5vZGV0eXBlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCBlbnRSZWZBZGRyOworICAgICAgTm9kZSBlbnRSZWZOb2RlOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICBlbnRSZWZBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBlbnRSZWZOb2RlID0gZW50UmVmQWRkci5nZXRGaXJzdENoaWxkKCk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGVudFJlZk5vZGUuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygzLCBub2RlVHlwZSkpIHsKKyAgICAgICAgICBlbnRSZWZOb2RlID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50MiIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWZOb2RlKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgZW50UmVmTm9kZS5nZXROb2RlVHlwZSgpOworICAgICAgfQorICAgIGFzc2VydEVxdWFscygiZW50aXR5Tm9kZVR5cGUiLCA1LCBub2RlVHlwZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVlbnRpdHlyZWZlcmVuY2Vub2RldHlwZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWVudGl0eXJlZmVyZW5jZW5vZGV0eXBlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZW50aXR5cmVmZXJlbmNlbm9kZXZhbHVlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVlbnRpdHlyZWZlcmVuY2Vub2RldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MzFiMjQ3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZW50aXR5cmVmZXJlbmNlbm9kZXZhbHVlLmphdmEKQEAgLTAsMCArMSw5OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAiZ2V0Tm9kZVZhbHVlKCkiIG1ldGhvZCBmb3IgYW4gCisgKiAgICAgRW50aXR5UmVmZXJlbmNlIE5vZGUgaXMgbnVsbC4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgRW50aXR5IFJlZmVyZW5jZSBub2RlIGZyb20gdGhlIGxhc3QKKyAqICAgICBjaGlsZCBvZiB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBjaGVjayB0aGUgc3RyaW5nIAorICogICAgIHJldHVybmVkIGJ5IHRoZSAiZ2V0Tm9kZVZhbHVlKCkiIG1ldGhvZC4gICBJdCBzaG91bGQgYmUgCisgKiAgICAgZXF1YWwgdG8gbnVsbC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODA8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVlbnRpdHlyZWZlcmVuY2Vub2RldmFsdWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVlbnRpdHlyZWZlcmVuY2Vub2RldmFsdWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IGVudFJlZkFkZHI7CisgICAgICBOb2RlIGVudFJlZk5vZGU7CisgICAgICBTdHJpbmcgZW50UmVmVmFsdWU7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIGVudFJlZkFkZHIgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGVudFJlZk5vZGUgPSBlbnRSZWZBZGRyLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgZW50UmVmTm9kZS5nZXROb2RlVHlwZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDMsIG5vZGVUeXBlKSkgeworICAgICAgICAgIGVudFJlZk5vZGUgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQyIik7CisgICAgICBhc3NlcnROb3ROdWxsKCJjcmVhdGVkRW50UmVmTm90TnVsbCIsIGVudFJlZk5vZGUpOworICAgICAgfQorICAgIGVudFJlZlZhbHVlID0gZW50UmVmTm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydE51bGwoImVudFJlZk5vZGVWYWx1ZSIsIGVudFJlZlZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWVudGl0eXJlZmVyZW5jZW5vZGV2YWx1ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWVudGl0eXJlZmVyZW5jZW5vZGV2YWx1ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWVudGl0eXNldG5vZGV2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZW50aXR5c2V0bm9kZXZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjU2MTc5MAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWVudGl0eXNldG5vZGV2YWx1ZS5qYXZhCkBAIC0wLDAgKzEsOTAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIHN0cmluZyByZXR1cm5lZCBieSB0aGUgImdldE5vZGVWYWx1ZSgpIiBtZXRob2QgZm9yIGFuIAorICogICAgIEVudGl0eSBOb2RlIGlzIGFsd2F5cyBudWxsIGFuZCAic2V0Tm9kZVZhbHVlIiBzaG91bGQgaGF2ZSBubyBlZmZlY3QuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTUyN0RDRkYyIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC01MjdEQ0ZGMjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWVudGl0eXNldG5vZGV2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWVudGl0eXNldG5vZGV2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTmFtZWROb2RlTWFwIGVudGl0aWVzOworICAgICAgTm9kZSBlbnRpdHlOb2RlOworICAgICAgU3RyaW5nIGVudGl0eVZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgZW50aXRpZXMgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdGllc05vdE51bGwiLCBlbnRpdGllcyk7CisgICAgICBlbnRpdHlOb2RlID0gZW50aXRpZXMuZ2V0TmFtZWRJdGVtKCJlbnQxIik7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnQxTm90TnVsbCIsIGVudGl0eU5vZGUpOworICAgICAgZW50aXR5Tm9kZS5zZXROb2RlVmFsdWUoIlRoaXMgc2hvdWxkIGhhdmUgbm8gZWZmZWN0Iik7CisgICAgICBlbnRpdHlWYWx1ZSA9IGVudGl0eU5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJub2RlVmFsdWVOdWxsIiwgZW50aXR5VmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZW50aXR5c2V0bm9kZXZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlZW50aXR5c2V0bm9kZXZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZ2V0Zmlyc3RjaGlsZC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZ2V0Zmlyc3RjaGlsZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFmNWMyNzMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVnZXRmaXJzdGNoaWxkLmphdmEKQEAgLTAsMCArMSw5MSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEZpcnN0Q2hpbGQoKSIgbWV0aG9kIHJldHVybnMgdGhlIGZpcnN0IGNoaWxkCisgKiAgICAgb2YgdGhpcyBub2RlLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE2OTcyNzM4OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTY5NzI3Mzg4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlZ2V0Zmlyc3RjaGlsZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWdldGZpcnN0Y2hpbGQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGUgZmNoaWxkTm9kZTsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgZmNoaWxkTm9kZSA9IGVtcGxveWVlTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjaGlsZE5hbWUgPSBmY2hpbGROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoIiN0ZXh0IiwgY2hpbGROYW1lKSkgeworICAgICAgICAgIGZjaGlsZE5vZGUgPSBmY2hpbGROb2RlLmdldE5leHRTaWJsaW5nKCk7CisgICAgICBjaGlsZE5hbWUgPSBmY2hpbGROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICB9CisgICAgYXNzZXJ0RXF1YWxzKCJub2RlTmFtZSIsICJlbXBsb3llZUlkIiwgY2hpbGROYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWdldGZpcnN0Y2hpbGQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVnZXRmaXJzdGNoaWxkLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZ2V0Zmlyc3RjaGlsZG51bGwuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWdldGZpcnN0Y2hpbGRudWxsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzA0MTczNQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWdldGZpcnN0Y2hpbGRudWxsLmphdmEKQEAgLTAsMCArMSw5NCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgSWYgdGhlcmUgaXMgbm90IGEgZmlyc3QgY2hpbGQgdGhlbiB0aGUgImdldEZpcnN0Q2hpbGQoKSIKKyAqICAgICBtZXRob2QgcmV0dXJucyBudWxsLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBUZXh0IG5vZGUgZm9ybSB0aGUgc2Vjb25kIGNoaWxkIG9mIHRoZSBmaXJzdAorICogICAgIGVtcGxveWVlIGFuZCBpbnZva2UgdGhlICJnZXRGaXJzdENoaWxkKCkiIG1ldGhvZC4gICBJdAorICogICAgIHNob3VsZCByZXR1cm4gbnVsbC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE2OTcyNzM4OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTY5NzI3Mzg4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlZ2V0Zmlyc3RjaGlsZG51bGwgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVnZXRmaXJzdGNoaWxkbnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZUxpc3QgZW1wbG95ZWVMaXN0OworICAgICAgTm9kZSBzZWNvbmRDaGlsZE5vZGU7CisgICAgICBOb2RlIHRleHROb2RlOworICAgICAgTm9kZSBub0NoaWxkTm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBlbXBsb3llZUxpc3QgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgc2Vjb25kQ2hpbGROb2RlID0gZW1wbG95ZWVMaXN0Lml0ZW0oMSk7CisgICAgICB0ZXh0Tm9kZSA9IHNlY29uZENoaWxkTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBub0NoaWxkTm9kZSA9IHRleHROb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE51bGwoIm5vZGVHZXRGaXJzdENoaWxkTnVsbEFzc2VydDEiLCBub0NoaWxkTm9kZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVnZXRmaXJzdGNoaWxkbnVsbCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWdldGZpcnN0Y2hpbGRudWxsLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZ2V0bGFzdGNoaWxkLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVnZXRsYXN0Y2hpbGQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZTMzNWZjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZ2V0bGFzdGNoaWxkLmphdmEKQEAgLTAsMCArMSw5MSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldExhc3RDaGlsZCgpIiBtZXRob2QgcmV0dXJucyB0aGUgbGFzdCBjaGlsZAorICogICAgIG9mIHRoaXMgbm9kZS4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02MUFEMDlGQiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjFBRDA5RkI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVnZXRsYXN0Y2hpbGQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVnZXRsYXN0Y2hpbGQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGUgbGNoaWxkTm9kZTsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgbGNoaWxkTm9kZSA9IGVtcGxveWVlTm9kZS5nZXRMYXN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkTmFtZSA9IGxjaGlsZE5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygiI3RleHQiLCBjaGlsZE5hbWUpKSB7CisgICAgICAgICAgbGNoaWxkTm9kZSA9IGxjaGlsZE5vZGUuZ2V0UHJldmlvdXNTaWJsaW5nKCk7CisgICAgICBjaGlsZE5hbWUgPSBsY2hpbGROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICB9CisgICAgYXNzZXJ0RXF1YWxzKCJub2RlTmFtZSIsICJhZGRyZXNzIiwgY2hpbGROYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWdldGxhc3RjaGlsZCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWdldGxhc3RjaGlsZC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWdldGxhc3RjaGlsZG51bGwuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWdldGxhc3RjaGlsZG51bGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNjRjN2M3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZ2V0bGFzdGNoaWxkbnVsbC5qYXZhCkBAIC0wLDAgKzEsOTQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZXJlIGlzIG5vdCBhIGxhc3QgY2hpbGQgdGhlbiB0aGUgImdldExhc3RDaGlsZCgpIgorICogICAgIG1ldGhvZCByZXR1cm5zIG51bGwuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIFRleHQgbm9kZSBmcm9tIHRoZSBzZWNvbmQgY2hpbGQgb2YgdGhlIGZpcnN0CisgKiAgICAgZW1wbG95ZWUgYW5kIGludm9rZSB0aGUgImdldExhc3RDaGlsZCgpIiBtZXRob2QuICAgSXQKKyAqICAgICBzaG91bGQgcmV0dXJuIG51bGwuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02MUFEMDlGQiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjFBRDA5RkI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVnZXRsYXN0Y2hpbGRudWxsIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlZ2V0bGFzdGNoaWxkbnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZUxpc3QgZW1wbG95ZWVMaXN0OworICAgICAgTm9kZSBzZWNvbmRDaGlsZE5vZGU7CisgICAgICBOb2RlIHRleHROb2RlOworICAgICAgTm9kZSBub0NoaWxkTm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBlbXBsb3llZUxpc3QgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgc2Vjb25kQ2hpbGROb2RlID0gZW1wbG95ZWVMaXN0Lml0ZW0oMSk7CisgICAgICB0ZXh0Tm9kZSA9IHNlY29uZENoaWxkTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBub0NoaWxkTm9kZSA9IHRleHROb2RlLmdldExhc3RDaGlsZCgpOworICAgICAgYXNzZXJ0TnVsbCgibm9kZUdldExhc3RDaGlsZE51bGxBc3NlcnQxIiwgbm9DaGlsZE5vZGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZ2V0bGFzdGNoaWxkbnVsbCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWdldGxhc3RjaGlsZG51bGwuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVnZXRuZXh0c2libGluZy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZ2V0bmV4dHNpYmxpbmcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OTE3MjEyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZ2V0bmV4dHNpYmxpbmcuamF2YQpAQCAtMCwwICsxLDkxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0TmV4dFNpYmxpbmcoKSIgbWV0aG9kIHJldHVybnMgdGhlIG5vZGUgaW1tZWRpYXRlbHkKKyAqICAgICBmb2xsb3dpbmcgdGhpcyBub2RlLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTZBQzU0QzJGIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02QUM1NEMyRjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWdldG5leHRzaWJsaW5nIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlZ2V0bmV4dHNpYmxpbmcoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlSWROb2RlOworICAgICAgTm9kZSBuc05vZGU7CisgICAgICBTdHJpbmcgbnNOYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZUlkIik7CisgICAgICBlbXBsb3llZUlkTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBuc05vZGUgPSBlbXBsb3llZUlkTm9kZS5nZXROZXh0U2libGluZygpOworICAgICAgbnNOYW1lID0gbnNOb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoIiN0ZXh0IiwgbnNOYW1lKSkgeworICAgICAgICAgIG5zTm9kZSA9IG5zTm9kZS5nZXROZXh0U2libGluZygpOworICAgICAgbnNOYW1lID0gbnNOb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICB9CisgICAgYXNzZXJ0RXF1YWxzKCJub2RlTmFtZSIsICJuYW1lIiwgbnNOYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWdldG5leHRzaWJsaW5nIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlZ2V0bmV4dHNpYmxpbmcuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVnZXRuZXh0c2libGluZ251bGwuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWdldG5leHRzaWJsaW5nbnVsbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVlMWJmYmQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVnZXRuZXh0c2libGluZ251bGwuamF2YQpAQCAtMCwwICsxLDkwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBJZiB0aGVyZSBpcyBub3QgYSBub2RlIGltbWVkaWF0ZWx5IGZvbGxvd2luZyB0aGlzIG5vZGUgdGhlCisgKiAgICAgImdldE5leHRTaWJsaW5nKCkiIG1ldGhvZCByZXR1cm5zIG51bGwuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIGZpcnN0IGNoaWxkIG9mIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kCisgKiAgICAgaW52b2tlIHRoZSAiZ2V0TmV4dFNpYmxpbmcoKSIgbWV0aG9kLiAgIEl0IHNob3VsZAorICogICAgIGJlIHNldCB0byBudWxsLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTZBQzU0QzJGIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02QUM1NEMyRjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWdldG5leHRzaWJsaW5nbnVsbCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWdldG5leHRzaWJsaW5nbnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZSBsY05vZGU7CisgICAgICBOb2RlIG5zTm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBsY05vZGUgPSBlbXBsb3llZU5vZGUuZ2V0TGFzdENoaWxkKCk7CisgICAgICBuc05vZGUgPSBsY05vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKKyAgICAgIGFzc2VydE51bGwoIm5vZGVHZXROZXh0U2libGluZ051bGxBc3NlcnQxIiwgbnNOb2RlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWdldG5leHRzaWJsaW5nbnVsbCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWdldG5leHRzaWJsaW5nbnVsbC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWdldG93bmVyZG9jdW1lbnQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWdldG93bmVyZG9jdW1lbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NTdlZGQyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZ2V0b3duZXJkb2N1bWVudC5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0T3duZXJEb2N1bWVudCgpIiBtZXRob2QgcmV0dXJucyB0aGUgRG9jdW1lbnQKKyAqICAgICBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoaXMgbm9kZS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBleGFtaW5lIERvY3VtZW50IAorICogICAgIHJldHVybmVkIGJ5IHRoZSAiZ2V0T3duZXJEb2N1bWVudCgpIiBtZXRob2QuICAgSW52b2tlCisgKiAgICAgdGhlICJnZXREb2N1bWVudEVsZW1lbnQoKSIgb24gdGhlIERvY3VtZW50IHdoaWNoIHdpbGwKKyAqICAgICByZXR1cm4gYW4gRWxlbWVudCB0aGF0IGlzIGVxdWFsIHRvICJzdGFmZiIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNub2RlLW93bmVyRG9jIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNub2RlLW93bmVyRG9jPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTEiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTE8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVnZXRvd25lcmRvY3VtZW50IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlZ2V0b3duZXJkb2N1bWVudChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZG9jTm9kZTsKKyAgICAgIERvY3VtZW50IG93bmVyRG9jdW1lbnQ7CisgICAgICBFbGVtZW50IGRvY0VsZW1lbnQ7CisgICAgICBTdHJpbmcgZWxlbWVudE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBkb2NOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIG93bmVyRG9jdW1lbnQgPSBkb2NOb2RlLmdldE93bmVyRG9jdW1lbnQoKTsKKyAgICAgIGRvY0VsZW1lbnQgPSBvd25lckRvY3VtZW50LmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgZWxlbWVudE5hbWUgPSBkb2NFbGVtZW50LmdldE5vZGVOYW1lKCk7CisgICAgICAKKyAgICAgIGlmICgoImltYWdlL3N2Zyt4bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoInN2Z1RhZ05hbWUiLCAic3ZnIiwgZWxlbWVudE5hbWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVHZXRPd25lckRvY3VtZW50QXNzZXJ0MSIsICJzdGFmZiIsIGVsZW1lbnROYW1lKTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZ2V0b3duZXJkb2N1bWVudCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWdldG93bmVyZG9jdW1lbnQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVnZXRvd25lcmRvY3VtZW50bnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZ2V0b3duZXJkb2N1bWVudG51bGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iODUzNTIzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZ2V0b3duZXJkb2N1bWVudG51bGwuamF2YQpAQCAtMCwwICsxLDgwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0T3duZXJEb2N1bWVudCgpIiBtZXRob2QgcmV0dXJucyBudWxsIGlmIHRoZSB0YXJnZXQKKyAqICAgICBub2RlIGl0c2VsZiBpcyBhIGRvY3VtZW50LgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjbm9kZS1vd25lckRvYyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjbm9kZS1vd25lckRvYzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWdldG93bmVyZG9jdW1lbnRudWxsIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlZ2V0b3duZXJkb2N1bWVudG51bGwoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnQgb3duZXJEb2N1bWVudDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBvd25lckRvY3VtZW50ID0gZG9jLmdldE93bmVyRG9jdW1lbnQoKTsKKyAgICAgIGFzc2VydE51bGwoImRvY3VtZW50T3duZXJEb2N1bWVudE51bGwiLCBvd25lckRvY3VtZW50KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWdldG93bmVyZG9jdW1lbnRudWxsIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlZ2V0b3duZXJkb2N1bWVudG51bGwuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVnZXRwcmV2aW91c3NpYmxpbmcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWdldHByZXZpb3Vzc2libGluZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE4OTYzOTQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVnZXRwcmV2aW91c3NpYmxpbmcuamF2YQpAQCAtMCwwICsxLDkxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0UHJldmlvdXNTaWJsaW5nKCkiIG1ldGhvZCByZXR1cm5zIHRoZSBub2RlCisgKiAgICAgaW1tZWRpYXRlbHkgcHJlY2VkaW5nIHRoaXMgbm9kZS4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NDBGQjNDOCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNjQwRkIzQzg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVnZXRwcmV2aW91c3NpYmxpbmcgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVnZXRwcmV2aW91c3NpYmxpbmcoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgTm9kZSBwc05vZGU7CisgICAgICBTdHJpbmcgcHNOYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJuYW1lIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBwc05vZGUgPSBuYW1lTm9kZS5nZXRQcmV2aW91c1NpYmxpbmcoKTsKKyAgICAgIHBzTmFtZSA9IHBzTm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKCIjdGV4dCIsIHBzTmFtZSkpIHsKKyAgICAgICAgICBwc05vZGUgPSBwc05vZGUuZ2V0UHJldmlvdXNTaWJsaW5nKCk7CisgICAgICBwc05hbWUgPSBwc05vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIH0KKyAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lIiwgImVtcGxveWVlSWQiLCBwc05hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZ2V0cHJldmlvdXNzaWJsaW5nIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlZ2V0cHJldmlvdXNzaWJsaW5nLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZ2V0cHJldmlvdXNzaWJsaW5nbnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlZ2V0cHJldmlvdXNzaWJsaW5nbnVsbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdlYmE0NzUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVnZXRwcmV2aW91c3NpYmxpbmdudWxsLmphdmEKQEAgLTAsMCArMSw5MCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgSWYgdGhlcmUgaXMgbm90IGEgbm9kZSBpbW1lZGlhdGVseSBwcmVjZWRpbmcgdGhpcyBub2RlIHRoZQorICogICAgICJnZXRQcmV2aW91c1NpYmxpbmcoKSIgbWV0aG9kIHJldHVybnMgbnVsbC4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgY2hpbGQgb2YgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQKKyAqICAgICBpbnZva2UgdGhlICJnZXRQcmV2aW91c1NpYmxpbmcoKSIgbWV0aG9kLiAgIEl0IHNob3VsZAorICogICAgIGJlIHNldCB0byBudWxsLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTY0MEZCM0M4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC02NDBGQjNDODwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWdldHByZXZpb3Vzc2libGluZ251bGwgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVnZXRwcmV2aW91c3NpYmxpbmdudWxsKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlIGZjTm9kZTsKKyAgICAgIE5vZGUgcHNOb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIGZjTm9kZSA9IGVtcGxveWVlTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBwc05vZGUgPSBmY05vZGUuZ2V0UHJldmlvdXNTaWJsaW5nKCk7CisgICAgICBhc3NlcnROdWxsKCJub2RlR2V0UHJldmlvdXNTaWJsaW5nTnVsbEFzc2VydDEiLCBwc05vZGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlZ2V0cHJldmlvdXNzaWJsaW5nbnVsbCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWdldHByZXZpb3Vzc2libGluZ251bGwuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVoYXNjaGlsZG5vZGVzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVoYXNjaGlsZG5vZGVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTRiMWJkYgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWhhc2NoaWxkbm9kZXMuamF2YQpAQCAtMCwwICsxLDg4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImhhc0NoaWxkTm9kZXMoKSIgbWV0aG9kIHJldHVybnMgdHJ1ZSBpZiB0aGUgbm9kZQorICogICAgIGhhcyBjaGlsZHJlbi4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgcm9vdCBub2RlKCJzdGFmZiIpIGFuZCBpbnZva2UgdGhlIAorICogICAgICJoYXNDaGlsZE5vZGVzKCkiIG1ldGhvZC4gICBJdCBzaG91bGQgcmV0dXJuIHRoZSBib29sZWFuCisgKiAgICAgdmFsdWUgInRydWUiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODEwNTk0MTg3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04MTA1OTQxODc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVoYXNjaGlsZG5vZGVzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlaGFzY2hpbGRub2RlcyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBzdGF0ZSA9IGVtcGxveWVlTm9kZS5oYXNDaGlsZE5vZGVzKCk7CisgICAgICBhc3NlcnRUcnVlKCJub2RlSGFzQ2hpbGRBc3NlcnQxIiwgc3RhdGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlaGFzY2hpbGRub2RlcyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWhhc2NoaWxkbm9kZXMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVoYXNjaGlsZG5vZGVzZmFsc2UuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWhhc2NoaWxkbm9kZXNmYWxzZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFmYWM1MWUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVoYXNjaGlsZG5vZGVzZmFsc2UuamF2YQpAQCAtMCwwICsxLDk1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImhhc0NoaWxkTm9kZXMoKSIgbWV0aG9kIHJldHVybnMgZmFsc2UgaWYgdGhlIG5vZGUKKyAqICAgICBkb2VzIG5vdCBoYXZlIGFueSBjaGlsZHJlbi4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgVGV4dCBub2RlIGluc2lkZSB0aGUgZmlyc3QgY2hpbGQgb2YgdGhlIAorICogICAgIHNlY29uZCBlbXBsb3llZSBhbmQgaW52b2tlIHRoZSAiaGFzQ2hpbGROb2RlcygpIiBtZXRob2QuCisgKiAgICAgSXQgc2hvdWxkIHJldHVybiB0aGUgYm9vbGVhbiB2YWx1ZSAiZmFsc2UiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTQ1MTQ2MDk4NyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTQ1MTQ2MDk4NzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04MTA1OTQxODciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTgxMDU5NDE4NzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWhhc2NoaWxkbm9kZXNmYWxzZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWhhc2NoaWxkbm9kZXNmYWxzZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBOb2RlTGlzdCBlbXBsb3llZUlkTGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZSB0ZXh0Tm9kZTsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBjaGlsZCA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBlbXBsb3llZUlkTGlzdCA9IGNoaWxkLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVtcGxveWVlSWRMaXN0Lml0ZW0oMSk7CisgICAgICB0ZXh0Tm9kZSA9IGVtcGxveWVlTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBzdGF0ZSA9IHRleHROb2RlLmhhc0NoaWxkTm9kZXMoKTsKKyAgICAgIGFzc2VydEZhbHNlKCJub2RlSGFzQ2hpbGRGYWxzZUFzc2VydDEiLCBzdGF0ZSk7Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVoYXNjaGlsZG5vZGVzZmFsc2UiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVoYXNjaGlsZG5vZGVzZmFsc2UuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk4NWQxMTMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmUuamF2YQpAQCAtMCwwICsxLDE0MCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJpbnNlcnRCZWZvcmUobmV3Q2hpbGQscmVmQ2hpbGQpIiBtZXRob2QgaW5zZXJ0cyB0aGUKKyAqICAgICBub2RlICJuZXdDaGlsZCIgYmVmb3JlIHRoZSBub2RlICJyZWZDaGlsZCIuIAorICogICAgIAorICogICAgIEluc2VydCBhIG5ld2x5IGNyZWF0ZWQgRWxlbWVudCBub2RlIGJlZm9yZSB0aGUgZWlndGgKKyAqICAgICBjaGlsZCBvZiB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBjaGVjayB0aGUgIm5ld0NoaWxkIgorICogICAgIGFuZCAicmVmQ2hpbGQiIGFmdGVyIGluc2VydGlvbiBmb3IgY29ycmVjdCBwbGFjZW1lbnQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3MjciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWluc2VydGJlZm9yZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWluc2VydGJlZm9yZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIHJlZkNoaWxkOworICAgICAgTm9kZSBuZXdDaGlsZDsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgaW50IGxlbmd0aDsKKyAgICAgIE5vZGUgaW5zZXJ0ZWROb2RlOworICAgICAgamF2YS51dGlsLkxpc3QgYWN0dWFsID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkxpc3QgZXhwZWN0ZWRXaXRoV2hpdGVzcGFjZSA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZFdpdGhXaGl0ZXNwYWNlLmFkZCgiI3RleHQiKTsKKyAgICAgIGV4cGVjdGVkV2l0aFdoaXRlc3BhY2UuYWRkKCJlbXBsb3llZUlkIik7CisgICAgICBleHBlY3RlZFdpdGhXaGl0ZXNwYWNlLmFkZCgiI3RleHQiKTsKKyAgICAgIGV4cGVjdGVkV2l0aFdoaXRlc3BhY2UuYWRkKCJuYW1lIik7CisgICAgICBleHBlY3RlZFdpdGhXaGl0ZXNwYWNlLmFkZCgiI3RleHQiKTsKKyAgICAgIGV4cGVjdGVkV2l0aFdoaXRlc3BhY2UuYWRkKCJwb3NpdGlvbiIpOworICAgICAgZXhwZWN0ZWRXaXRoV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICBleHBlY3RlZFdpdGhXaGl0ZXNwYWNlLmFkZCgibmV3Q2hpbGQiKTsKKyAgICAgIGV4cGVjdGVkV2l0aFdoaXRlc3BhY2UuYWRkKCJzYWxhcnkiKTsKKyAgICAgIGV4cGVjdGVkV2l0aFdoaXRlc3BhY2UuYWRkKCIjdGV4dCIpOworICAgICAgZXhwZWN0ZWRXaXRoV2hpdGVzcGFjZS5hZGQoImdlbmRlciIpOworICAgICAgZXhwZWN0ZWRXaXRoV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICBleHBlY3RlZFdpdGhXaGl0ZXNwYWNlLmFkZCgiYWRkcmVzcyIpOworICAgICAgZXhwZWN0ZWRXaXRoV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5MaXN0IGV4cGVjdGVkV2l0aG91dFdoaXRlc3BhY2UgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgZXhwZWN0ZWRXaXRob3V0V2hpdGVzcGFjZS5hZGQoImVtcGxveWVlSWQiKTsKKyAgICAgIGV4cGVjdGVkV2l0aG91dFdoaXRlc3BhY2UuYWRkKCJuYW1lIik7CisgICAgICBleHBlY3RlZFdpdGhvdXRXaGl0ZXNwYWNlLmFkZCgicG9zaXRpb24iKTsKKyAgICAgIGV4cGVjdGVkV2l0aG91dFdoaXRlc3BhY2UuYWRkKCJuZXdDaGlsZCIpOworICAgICAgZXhwZWN0ZWRXaXRob3V0V2hpdGVzcGFjZS5hZGQoInNhbGFyeSIpOworICAgICAgZXhwZWN0ZWRXaXRob3V0V2hpdGVzcGFjZS5hZGQoImdlbmRlciIpOworICAgICAgZXhwZWN0ZWRXaXRob3V0V2hpdGVzcGFjZS5hZGQoImFkZHJlc3MiKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkxpc3QgZXhwZWN0ZWQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjaGlsZExpc3QgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgbGVuZ3RoID0gKGludCkgY2hpbGRMaXN0LmdldExlbmd0aCgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDYsIGxlbmd0aCkpIHsKKyAgICAgICAgICByZWZDaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDMpOworICAgICAgZXhwZWN0ZWQgPSAgZXhwZWN0ZWRXaXRob3V0V2hpdGVzcGFjZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmVmQ2hpbGQgPSBjaGlsZExpc3QuaXRlbSg3KTsKKyAgICAgIGV4cGVjdGVkID0gIGV4cGVjdGVkV2l0aFdoaXRlc3BhY2U7CisgICAgICB9CisgICAgICAgIAorICAgIG5ld0NoaWxkID0gZG9jLmNyZWF0ZUVsZW1lbnQoIm5ld0NoaWxkIik7CisgICAgICBpbnNlcnRlZE5vZGUgPSBlbXBsb3llZU5vZGUuaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLCByZWZDaGlsZCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDBEQyA9IDA7IGluZGV4TjEwMERDIDwgY2hpbGRMaXN0LmdldExlbmd0aCgpOyBpbmRleE4xMDBEQysrKSB7CisgICAgICAgICAgY2hpbGQgPSAoTm9kZSkgY2hpbGRMaXN0Lml0ZW0oaW5kZXhOMTAwREMpOworICAgIGNoaWxkTmFtZSA9IGNoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICBhY3R1YWwuYWRkKGNoaWxkTmFtZSk7CisgICAgICAgIH0KKyAgICAgIGFzc2VydEVxdWFscygibm9kZU5hbWVzIiwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVpbnNlcnRiZWZvcmUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmVkb2NmcmFnbWVudC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3JlZG9jZnJhZ21lbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZjJlZTE0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3JlZG9jZnJhZ21lbnQuamF2YQpAQCAtMCwwICsxLDExMiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgSWYgdGhlICJuZXdDaGlsZCIgaXMgYSBEb2N1bWVudEZyYWdtZW50IG9iamVjdCB0aGVuIGFsbAorICogICAgIGl0cyBjaGlsZHJlbiBhcmUgaW5zZXJ0ZWQgaW4gdGhlIHNhbWUgb3JkZXIgYmVmb3JlIHRoZQorICogICAgIHRoZSAicmVmQ2hpbGQiLiAKKyAqICAgICAKKyAqICAgICBDcmVhdGUgYSBEb2N1bWVudEZyYWdtZW50IG9iamVjdCBhbmQgcG9wdWxhdGUgaXQgd2l0aAorICogICAgIHR3byBFbGVtZW50IG5vZGVzLiAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kCisgKiAgICAgaW5zZXJ0IHRoZSBuZXdseSBjcmVhdGVkIERvY3VtZW50RnJhZ21lbnQgYmVmb3JlIGl0cworICogICAgIGZvdXJ0aCBjaGlsZC4gICBUaGUgc2Vjb25kIGVtcGxveWVlIHNob3VsZCBub3cgaGF2ZSB0d28KKyAqICAgICBleHRyYSBjaGlsZHJlbigibmV3Q2hpbGQxIiBhbmQgIm5ld0NoaWxkMiIpIGF0IAorICogICAgIHBvc2l0aW9ucyBmb3VydGggYW5kIGZpZnRoIHJlc3BlY3RpdmVseS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlaW5zZXJ0YmVmb3JlZG9jZnJhZ21lbnQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVpbnNlcnRiZWZvcmVkb2NmcmFnbWVudChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIHJlZkNoaWxkOworICAgICAgRG9jdW1lbnRGcmFnbWVudCBuZXdkb2NGcmFnbWVudDsKKyAgICAgIE5vZGUgbmV3Q2hpbGQxOworICAgICAgTm9kZSBuZXdDaGlsZDI7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIE5vZGUgYXBwZW5kZWRDaGlsZDsKKyAgICAgIE5vZGUgaW5zZXJ0ZWROb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgY2hpbGRMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIHJlZkNoaWxkID0gY2hpbGRMaXN0Lml0ZW0oMyk7CisgICAgICBuZXdkb2NGcmFnbWVudCA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CisgICAgICBuZXdDaGlsZDEgPSBkb2MuY3JlYXRlRWxlbWVudCgibmV3Q2hpbGQxIik7CisgICAgICBuZXdDaGlsZDIgPSBkb2MuY3JlYXRlRWxlbWVudCgibmV3Q2hpbGQyIik7CisgICAgICBhcHBlbmRlZENoaWxkID0gbmV3ZG9jRnJhZ21lbnQuYXBwZW5kQ2hpbGQobmV3Q2hpbGQxKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBuZXdkb2NGcmFnbWVudC5hcHBlbmRDaGlsZChuZXdDaGlsZDIpOworICAgICAgaW5zZXJ0ZWROb2RlID0gZW1wbG95ZWVOb2RlLmluc2VydEJlZm9yZShuZXdkb2NGcmFnbWVudCwgcmVmQ2hpbGQpOworICAgICAgY2hpbGQgPSBjaGlsZExpc3QuaXRlbSgzKTsKKyAgICAgIGNoaWxkTmFtZSA9IGNoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoaWxkTmFtZTMiLCAibmV3Q2hpbGQxIiwgY2hpbGROYW1lKTsKKyAgICAgIGNoaWxkID0gY2hpbGRMaXN0Lml0ZW0oNCk7CisgICAgICBjaGlsZE5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJjaGlsZE5hbWU0IiwgIm5ld0NoaWxkMiIsIGNoaWxkTmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmVkb2NmcmFnbWVudCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWluc2VydGJlZm9yZWRvY2ZyYWdtZW50LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3JlaW52YWxpZG5vZGV0eXBlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmVpbnZhbGlkbm9kZXR5cGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMTM2ZDdkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3JlaW52YWxpZG5vZGV0eXBlLmphdmEKQEAgLTAsMCArMSwxMDcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJpbnNlcnRCZWZvcmUobmV3Q2hpbGQscmVmQ2hpbGQpIiBtZXRob2QgcmFpc2VzIGEgCisgKiAgICAgSElFUkFSQ0hZX1JFUVVFU1RfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGlzIG5vZGUgaXMgb2YKKyAqICAgICBhIHR5cGUgdGhhdCBkb2VzIG5vdCBhbGxvdyBjaGlsZHJlbiBvZiB0aGUgdHlwZSAibmV3Q2hpbGQiCisgKiAgICAgdG8gYmUgaW5zZXJ0ZWQuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHJvb3Qgbm9kZSBhbmQgYXR0ZW1wdCB0byBpbnNlcnQgYSBuZXdseQorICogICAgIGNyZWF0ZWQgQXR0ciBub2RlLiAgIEFuIEVsZW1lbnQgbm9kZSBjYW5ub3QgaGF2ZSBjaGlsZHJlbgorICogICAgIG9mIHRoZSAiQXR0ciIgdHlwZSwgdGhlcmVmb3JlIHRoZSBkZXNpcmVkIGV4Y2VwdGlvbgorICogICAgIHNob3VsZCBiZSByYWlzZWQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSElFUkFSQ0hZX1JFUVVFU1RfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSElFUkFSQ0hZX1JFUVVFU1RfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC05NTIyODA3MjcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC05NTIyODA3MjcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3Mjc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWluc2VydGJlZm9yZWludmFsaWRub2RldHlwZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWluc2VydGJlZm9yZWludmFsaWRub2RldHlwZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgcm9vdE5vZGU7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHJlZkNoaWxkOworICAgICAgTm9kZSBpbnNlcnRlZE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICByb290Tm9kZSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIG5ld0NoaWxkID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZSgibmV3QXR0cmlidXRlIik7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIHJlZkNoaWxkID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zZXJ0ZWROb2RlID0gcm9vdE5vZGUuaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLCByZWZDaGlsZCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19ISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZWludmFsaWRub2RldHlwZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWluc2VydGJlZm9yZWludmFsaWRub2RldHlwZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZW5ld2NoaWxkZGlmZmRvY3VtZW50LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmVuZXdjaGlsZGRpZmZkb2N1bWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRhOGJlMWYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmVuZXdjaGlsZGRpZmZkb2N1bWVudC5qYXZhCkBAIC0wLDAgKzEsMTA5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImluc2VydEJlZm9yZShuZXdDaGlsZCxyZWZDaGlsZCkiIG1ldGhvZCByYWlzZXMgYSAKKyAqICAgICBXUk9OR19ET0NVTUVOVF9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSAibmV3Q2hpbGQiIHdhcworICogICAgIGNyZWF0ZWQgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudCB0aGFuIHRoZSBvbmUgdGhhdCAKKyAqICAgICBjcmVhdGVkIHRoaXMgbm9kZS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBhdHRlbXB0IHRvIGluc2VydCBhIG5ldyAKKyAqICAgICBjaGlsZCB0aGF0IHdhcyBjcmVhdGVkIGZyb20gYSBkaWZmZXJlbnQgZG9jdW1lbnQgdGhhbiB0aGUKKyAqICAgICBvbmUgdGhhdCBjcmVhdGVkIHRoZSBzZWNvbmQgZW1wbG95ZWUuICAgQW4gYXR0ZW1wdCB0bworICogICAgIGluc2VydCBzdWNoIGEgY2hpbGQgc2hvdWxkIHJhaXNlIHRoZSBkZXNpcmVkIGV4Y2VwdGlvbi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdXUk9OR19ET0NVTUVOVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdXUk9OR19ET0NVTUVOVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3Mjc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTk1MjI4MDcyNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J1dST05HX0RPQ1VNRU5UX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTk1MjI4MDcyNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J1dST05HX0RPQ1VNRU5UX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3MjciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWluc2VydGJlZm9yZW5ld2NoaWxkZGlmZmRvY3VtZW50IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlaW5zZXJ0YmVmb3JlbmV3Y2hpbGRkaWZmZG9jdW1lbnQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jMTsKKyAgICAgIERvY3VtZW50IGRvYzI7CisgICAgICBOb2RlIHJlZkNoaWxkOworICAgICAgTm9kZSBuZXdDaGlsZDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbGVtZW50Tm9kZTsKKyAgICAgIE5vZGUgaW5zZXJ0ZWROb2RlOworICAgICAgZG9jMSA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2MyID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgbmV3Q2hpbGQgPSBkb2MxLmNyZWF0ZUVsZW1lbnQoIm5ld0NoaWxkIik7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYzIuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbGVtZW50Tm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICByZWZDaGlsZCA9IGVsZW1lbnROb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zZXJ0ZWROb2RlID0gZWxlbWVudE5vZGUuaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLCByZWZDaGlsZCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19XUk9OR19ET0NVTUVOVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZW5ld2NoaWxkZGlmZmRvY3VtZW50IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlaW5zZXJ0YmVmb3JlbmV3Y2hpbGRkaWZmZG9jdW1lbnQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmVuZXdjaGlsZGV4aXN0cy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3JlbmV3Y2hpbGRleGlzdHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZGQxYzczCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3JlbmV3Y2hpbGRleGlzdHMuamF2YQpAQCAtMCwwICsxLDE0MiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBJZiB0aGUgIm5ld0NoaWxkIiBpcyBhbHJlYWR5IGluIHRoZSB0cmVlLCB0aGUKKyAqICAgICAiaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLHJlZkNoaWxkKSIgbWV0aG9kIG11c3QgZmlyc3QKKyAqICAgICByZW1vdmUgaXQgYmVmb3JlIHRoZSBpbnNlcnRpb24gdGFrZXMgcGxhY2UuCisgKiAgICAgCisgKiAgICAgSW5zZXJ0IGEgbm9kZSBFbGVtZW50ICgiZW1wbG95ZWVJZCIpIHRoYXQgaXMgYWxyZWFkeQorICogICAgIHByZXNlbnQgaW4gdGhlIHRyZWUuICAgVGhlIGV4aXN0aW5nIG5vZGUgc2hvdWxkIGJlIAorICogICAgIHJlbW92ZWQgZmlyc3QgYW5kIHRoZSBuZXcgb25lIGluc2VydGVkLiAgIFRoZSBub2RlIGlzCisgKiAgICAgaW5zZXJ0ZWQgYXQgYSBkaWZmZXJlbnQgcG9zaXRpb24gaW4gdGhlIHRyZWUgdG8gYXNzdXJlCisgKiAgICAgdGhhdCBpdCB3YXMgaW5kZWVkIGluc2VydGVkLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3Mjc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVpbnNlcnRiZWZvcmVuZXdjaGlsZGV4aXN0cyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWluc2VydGJlZm9yZW5ld2NoaWxkZXhpc3RzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgcmVmQ2hpbGQ7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZSBjaGlsZDsKKyAgICAgIGludCBsZW5ndGg7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgTm9kZSBpbnNlcnRlZE5vZGU7CisgICAgICBqYXZhLnV0aWwuTGlzdCBleHBlY3RlZFdoaXRlc3BhY2UgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgZXhwZWN0ZWRXaGl0ZXNwYWNlLmFkZCgiI3RleHQiKTsKKyAgICAgIGV4cGVjdGVkV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICBleHBlY3RlZFdoaXRlc3BhY2UuYWRkKCJuYW1lIik7CisgICAgICBleHBlY3RlZFdoaXRlc3BhY2UuYWRkKCIjdGV4dCIpOworICAgICAgZXhwZWN0ZWRXaGl0ZXNwYWNlLmFkZCgicG9zaXRpb24iKTsKKyAgICAgIGV4cGVjdGVkV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICBleHBlY3RlZFdoaXRlc3BhY2UuYWRkKCJzYWxhcnkiKTsKKyAgICAgIGV4cGVjdGVkV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICBleHBlY3RlZFdoaXRlc3BhY2UuYWRkKCJnZW5kZXIiKTsKKyAgICAgIGV4cGVjdGVkV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICBleHBlY3RlZFdoaXRlc3BhY2UuYWRkKCJlbXBsb3llZUlkIik7CisgICAgICBleHBlY3RlZFdoaXRlc3BhY2UuYWRkKCJhZGRyZXNzIik7CisgICAgICBleHBlY3RlZFdoaXRlc3BhY2UuYWRkKCIjdGV4dCIpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuTGlzdCBleHBlY3RlZE5vV2hpdGVzcGFjZSA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZE5vV2hpdGVzcGFjZS5hZGQoIm5hbWUiKTsKKyAgICAgIGV4cGVjdGVkTm9XaGl0ZXNwYWNlLmFkZCgicG9zaXRpb24iKTsKKyAgICAgIGV4cGVjdGVkTm9XaGl0ZXNwYWNlLmFkZCgic2FsYXJ5Iik7CisgICAgICBleHBlY3RlZE5vV2hpdGVzcGFjZS5hZGQoImdlbmRlciIpOworICAgICAgZXhwZWN0ZWROb1doaXRlc3BhY2UuYWRkKCJlbXBsb3llZUlkIik7CisgICAgICBleHBlY3RlZE5vV2hpdGVzcGFjZS5hZGQoImFkZHJlc3MiKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkxpc3QgZXhwZWN0ZWQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuTGlzdCByZXN1bHQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjaGlsZExpc3QgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgbGVuZ3RoID0gKGludCkgY2hpbGRMaXN0LmdldExlbmd0aCgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDYsIGxlbmd0aCkpIHsKKyAgICAgICAgICBleHBlY3RlZCA9ICBleHBlY3RlZE5vV2hpdGVzcGFjZTsKKyAgICAgIHJlZkNoaWxkID0gY2hpbGRMaXN0Lml0ZW0oNSk7CisgICAgICBuZXdDaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDApOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBleHBlY3RlZCA9ICBleHBlY3RlZFdoaXRlc3BhY2U7CisgICAgICByZWZDaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDExKTsKKyAgICAgIG5ld0NoaWxkID0gY2hpbGRMaXN0Lml0ZW0oMSk7CisgICAgICB9CisgICAgICAgIAorICAgIGluc2VydGVkTm9kZSA9IGVtcGxveWVlTm9kZS5pbnNlcnRCZWZvcmUobmV3Q2hpbGQsIHJlZkNoaWxkKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMEREID0gMDsgaW5kZXhOMTAwREQgPCBjaGlsZExpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMEREKyspIHsKKyAgICAgICAgICBjaGlsZCA9IChOb2RlKSBjaGlsZExpc3QuaXRlbShpbmRleE4xMDBERCk7CisgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIHJlc3VsdC5hZGQoY2hpbGROYW1lKTsKKyAgICAgICAgfQorICAgICAgYXNzZXJ0RXF1YWxzKCJjaGlsZE5hbWVzIiwgZXhwZWN0ZWQsIHJlc3VsdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmVuZXdjaGlsZGV4aXN0cyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWluc2VydGJlZm9yZW5ld2NoaWxkZXhpc3RzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3Jlbm9kZWFuY2VzdG9yLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmVub2RlYW5jZXN0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMDJmN2ZjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3Jlbm9kZWFuY2VzdG9yLmphdmEKQEAgLTAsMCArMSwxMDggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJpbnNlcnRCZWZvcmUobmV3Q2hpbGQscmVmQ2hpbGQpIiBtZXRob2QgcmFpc2VzIGEgCisgKiAgICAgSElFUkFSQ0hZX1JFUVVFU1RfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgbm9kZSB0byBiZQorICogICAgIGluc2VydGVkIGlzIG9uZSBvZiB0aGlzIG5vZGVzIGFuY2VzdG9ycy4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBhdHRlbXB0IHRvIGluc2VydCBhCisgKiAgICAgbm9kZSB0aGF0IGlzIG9uZSBvZiBpdHMgYW5jZXN0b3JzKHJvb3Qgbm9kZSkuICAgQW4gCisgKiAgICAgYXR0ZW1wdCB0byBpbnNlcnQgc3VjaCBhIG5vZGUgc2hvdWxkIHJhaXNlIHRoZSAKKyAqICAgICBkZXNpcmVkIGV4Y2VwdGlvbi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3Mjc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTk1MjI4MDcyNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTk1MjI4MDcyNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3MjciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlaW5zZXJ0YmVmb3Jlbm9kZWFuY2VzdG9yIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlaW5zZXJ0YmVmb3Jlbm9kZWFuY2VzdG9yKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBuZXdDaGlsZDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIHJlZkNoaWxkOworICAgICAgTm9kZSBpbnNlcnRlZE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdDaGlsZCA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTGlzdCA9IGVtcGxveWVlTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICByZWZDaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDApOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnNlcnRlZE5vZGUgPSBlbXBsb3llZU5vZGUuaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLCByZWZDaGlsZCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19ISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZW5vZGVhbmNlc3RvciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWluc2VydGJlZm9yZW5vZGVhbmNlc3Rvci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZW5vZGVuYW1lLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmVub2RlbmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ0OTQwNTMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmVub2RlbmFtZS5qYXZhCkBAIC0wLDAgKzEsOTggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLHJlZmNoaWxkKSIgbWV0aG9kIHJldHVybnMgCisgKiAgICAgdGhlIG5vZGUgYmVpbmcgaW5zZXJ0ZWQuCisgKiAgICAgCisgKiAgICAgSW5zZXJ0IGFuIEVsZW1lbnQgbm9kZSBiZWZvcmUgdGhlIGZvdXJ0aAorICogICAgIGNoaWxkIG9mIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGNoZWNrIHRoZSBub2RlCisgKiAgICAgcmV0dXJuZWQgZnJvbSB0aGUgImluc2VydEJlZm9yZShuZXdDaGlsZCxyZWZDaGlsZCkiIAorICogICAgIG1ldGhvZC4gICBUaGUgbm9kZSByZXR1cm5lZCBzaG91bGQgYmUgIm5ld0NoaWxkIi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3Mjc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVpbnNlcnRiZWZvcmVub2RlbmFtZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWluc2VydGJlZm9yZW5vZGVuYW1lKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgcmVmQ2hpbGQ7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZSBpbnNlcnRlZE5vZGU7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgY2hpbGRMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIHJlZkNoaWxkID0gY2hpbGRMaXN0Lml0ZW0oMyk7CisgICAgICBuZXdDaGlsZCA9IGRvYy5jcmVhdGVFbGVtZW50KCJuZXdDaGlsZCIpOworICAgICAgaW5zZXJ0ZWROb2RlID0gZW1wbG95ZWVOb2RlLmluc2VydEJlZm9yZShuZXdDaGlsZCwgcmVmQ2hpbGQpOworICAgICAgY2hpbGROYW1lID0gaW5zZXJ0ZWROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVJbnNlcnRCZWZvcmVOb2RlTmFtZUFzc2VydDEiLCAibmV3Q2hpbGQiLCBjaGlsZE5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3Jlbm9kZW5hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVpbnNlcnRiZWZvcmVub2RlbmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3Jlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmNjYjJhMAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCkBAIC0wLDAgKzEsMTE4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLHJlZkNoaWxkKSIgbWV0aG9kIGNhdXNlcyB0aGUgCisgKiAgICAgRE9NRXhjZXB0aW9uIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiB0byBiZSByYWlzZWQKKyAqICAgICBpZiB0aGUgbm9kZSBpcyByZWFkb25seS4KKyAqICAgICAKKyAqICAgICBPYnRhaW4gdGhlIGNoaWxkcmVuIG9mIHRoZSBUSElSRCAiZ2VuZGVyIiBlbGVtZW50LiAgIFRoZSBlbGVtZW50cworICogICAgIGNvbnRlbnQgaXMgYW4gZW50aXR5IHJlZmVyZW5jZS4gICBHZXQgdGhlIEZJUlNUIGl0ZW0gCisgKiAgICAgZnJvbSB0aGUgZW50aXR5IHJlZmVyZW5jZSBhbmQgZXhlY3V0ZSB0aGUgImluc2VydEJlZm9yZShuZXdDaGlsZCxyZWZDaGlsZCkiIG1ldGhvZC4KKyAqICAgICBUaGlzIGNhdXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gdG8gYmUgdGhyb3duLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3MjciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtOTUyMjgwNzI3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtOTUyMjgwNzI3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlaW5zZXJ0YmVmb3Jlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlaW5zZXJ0YmVmb3Jlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyTm9kZTsKKyAgICAgIE5vZGUgZW50UmVmOworICAgICAgTm9kZSBlbnRFbGVtZW50OworICAgICAgTm9kZSBjcmVhdGVkTm9kZTsKKyAgICAgIE5vZGUgaW5zZXJ0ZWROb2RlOworICAgICAgTm9kZSByZWZDaGlsZCA9IG51bGw7CisKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGdlbmRlckxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImdlbmRlciIpOworICAgICAgZ2VuZGVyTm9kZSA9IGdlbmRlckxpc3QuaXRlbSgyKTsKKyAgICAgIGVudFJlZiA9IGdlbmRlck5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50UmVmTm90TnVsbCIsIGVudFJlZik7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGVudFJlZi5nZXROb2RlVHlwZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDEsIG5vZGVUeXBlKSkgeworICAgICAgICAgIGVudFJlZiA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDQiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZW50UmVmKTsKKyAgICAgIH0KKyAgICBlbnRFbGVtZW50ID0gZW50UmVmLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudEVsZW1lbnROb3ROdWxsIiwgZW50RWxlbWVudCk7CisgICAgICBjcmVhdGVkTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50KCJ0ZXh0MyIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnNlcnRlZE5vZGUgPSBlbnRFbGVtZW50Lmluc2VydEJlZm9yZShjcmVhdGVkTm9kZSwgcmVmQ2hpbGQpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9UX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3Jlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlaW5zZXJ0YmVmb3Jlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3Jlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGU0MmZiNAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmphdmEKQEAgLTAsMCArMSwxMDIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLHJlZkNoaWxkKSIgbWV0aG9kIGNhdXNlcyB0aGUgCisgKiAgICAgRE9NRXhjZXB0aW9uIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiB0byBiZSByYWlzZWQKKyAqICAgICBpZiB0aGUgbm9kZSBpcyByZWFkb25seS4KKyAqICAgICAKKyAqICAgICBDcmVhdGUgYW4gZW50NCBlbnRpdHkgcmVmZXJlbmNlIGFuZCBhbmQgZXhlY3V0ZSB0aGUgImluc2VydEJlZm9yZShuZXdDaGlsZCxyZWZDaGlsZCkiIG1ldGhvZC4KKyAqICAgICBUaGlzIGNhdXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gdG8gYmUgdGhyb3duLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3MjciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtOTUyMjgwNzI3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtOTUyMjgwNzI3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWwiPmh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWw8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVpbnNlcnRiZWZvcmVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWluc2VydGJlZm9yZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBlbnRSZWY7CisgICAgICBOb2RlIGNyZWF0ZWROb2RlOworICAgICAgTm9kZSBpbnNlcnRlZE5vZGU7CisgICAgICBOb2RlIHJlZkNoaWxkID0gbnVsbDsKKworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZW50UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworICAgICAgY3JlYXRlZE5vZGUgPSBkb2MuY3JlYXRlRWxlbWVudCgidGV4dDMiKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zZXJ0ZWROb2RlID0gZW50UmVmLmluc2VydEJlZm9yZShjcmVhdGVkTm9kZSwgcmVmQ2hpbGQpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWluc2VydGJlZm9yZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3JlcmVmY2hpbGRub25leGlzdGVudC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3JlcmVmY2hpbGRub25leGlzdGVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1OGM2ZmQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmVyZWZjaGlsZG5vbmV4aXN0ZW50LmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJpbnNlcnRCZWZvcmUobmV3Q2hpbGQscmVmQ2hpbGQpIiBtZXRob2QgcmFpc2VzIGEgCisgKiAgICAgTk9UX0ZPVU5EX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHJlZmVyZW5jZSBjaGlsZCBpcworICogICAgIG5vdCBhIGNoaWxkIG9mIHRoaXMgbm9kZS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBhdHRlbXB0IHRvIGluc2VydCBhCisgKiAgICAgbmV3IG5vZGUgYmVmb3JlIGEgcmVmZXJlbmNlIG5vZGUgdGhhdCBpcyBub3QgYSBjaGlsZAorICogICAgIG9mIHRoaXMgbm9kZS4gICBBbiBhdHRlbXB0IHRvIGluc2VydCBiZWZvcmUgYSBub24gY2hpbGQKKyAqICAgICBub2RlIHNob3VsZCByYWlzZSB0aGUgZGVzaXJlZCBleGNlcHRpb24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9UX0ZPVU5EX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PVF9GT1VORF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3Mjc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTk1MjI4MDcyNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PVF9GT1VORF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC05NTIyODA3MjcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT1RfRk9VTkRfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtOTUyMjgwNzI3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVpbnNlcnRiZWZvcmVyZWZjaGlsZG5vbmV4aXN0ZW50IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlaW5zZXJ0YmVmb3JlcmVmY2hpbGRub25leGlzdGVudChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGUgcmVmQ2hpbGQ7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVsZW1lbnROb2RlOworICAgICAgTm9kZSBpbnNlcnRlZE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdDaGlsZCA9IGRvYy5jcmVhdGVFbGVtZW50KCJuZXdDaGlsZCIpOworICAgICAgcmVmQ2hpbGQgPSBkb2MuY3JlYXRlRWxlbWVudCgicmVmQ2hpbGQiKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZWxlbWVudE5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnNlcnRlZE5vZGUgPSBlbGVtZW50Tm9kZS5pbnNlcnRCZWZvcmUobmV3Q2hpbGQsIHJlZkNoaWxkKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT1RfRk9VTkRfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVpbnNlcnRiZWZvcmVyZWZjaGlsZG5vbmV4aXN0ZW50IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlaW5zZXJ0YmVmb3JlcmVmY2hpbGRub25leGlzdGVudC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZXJlZmNoaWxkbnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3JlcmVmY2hpbGRudWxsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzFiZDlmYgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWluc2VydGJlZm9yZXJlZmNoaWxkbnVsbC5qYXZhCkBAIC0wLDAgKzEsMTAyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBJZiB0aGUgInJlZkNoaWxkIiBpcyBudWxsIHRoZW4gdGhlCisgKiAgICAgImluc2VydEJlZm9yZShuZXdDaGlsZCxyZWZDaGlsZCkiIG1ldGhvZCBpbnNlcnRzIHRoZQorICogICAgIG5vZGUgIm5ld0NoaWxkIiBhdCB0aGUgZW5kIG9mIHRoZSBsaXN0IG9mIGNoaWxkcmVuLiAKKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBpbnZva2UgdGhlCisgKiAgICAgImluc2VydEJlZm9yZShuZXdDaGlsZCxyZWZDaGlsZCkiIG1ldGhvZCB3aXRoCisgKiAgICAgcmVmQ2hpbGQ9bnVsbC4gICBTaW5jZSAicmVmQ2hpbGQiIGlzIG51bGwgdGhlICJuZXdDaGlsZCIKKyAqICAgICBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdC4gICBUaGUgbGFzdCBpdGVtCisgKiAgICAgaW4gdGhlIGxpc3QgaXMgY2hlY2tlZCBhZnRlciBpbnNlcnRpb24uICAgVGhlIGxhc3QgRWxlbWVudAorICogICAgIG5vZGUgb2YgdGhlIGxpc3Qgc2hvdWxkIGJlICJuZXdDaGlsZCIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC05NTIyODA3MjciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTk1MjI4MDcyNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWluc2VydGJlZm9yZXJlZmNoaWxkbnVsbCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWluc2VydGJlZm9yZXJlZmNoaWxkbnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIHJlZkNoaWxkID0gbnVsbDsKKworICAgICAgTm9kZSBuZXdDaGlsZDsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgTm9kZSBpbnNlcnRlZE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjaGlsZExpc3QgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgbmV3Q2hpbGQgPSBkb2MuY3JlYXRlRWxlbWVudCgibmV3Q2hpbGQiKTsKKyAgICAgIGluc2VydGVkTm9kZSA9IGVtcGxveWVlTm9kZS5pbnNlcnRCZWZvcmUobmV3Q2hpbGQsIHJlZkNoaWxkKTsKKyAgICAgIGNoaWxkID0gZW1wbG95ZWVOb2RlLmdldExhc3RDaGlsZCgpOworICAgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZUluc2VydEJlZm9yZVJlZkNoaWxkTnVsbEFzc2VydDEiLCAibmV3Q2hpbGQiLCBjaGlsZE5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlaW5zZXJ0YmVmb3JlcmVmY2hpbGRudWxsIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlaW5zZXJ0YmVmb3JlcmVmY2hpbGRudWxsLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlbGlzdGluZGV4ZXF1YWx6ZXJvLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVsaXN0aW5kZXhlcXVhbHplcm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NzYyOWI3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlbGlzdGluZGV4ZXF1YWx6ZXJvLmphdmEKQEAgLTAsMCArMSw5MiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgIENyZWF0ZSBhIGxpc3Qgb2YgYWxsIHRoZSBjaGlsZHJlbiBlbGVtZW50cyBvZiB0aGUgdGhpcmQKKyAqICAgIGVtcGxveWVlIGFuZCBhY2Nlc3MgaXRzIGZpcnN0IGNoaWxkIGJ5IHVzaW5nIGFuIGluZGV4CisgKiAgICBvZiAwLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODQ0Mzc3MTM2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NDQzNzcxMzY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVsaXN0aW5kZXhlcXVhbHplcm8gZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVsaXN0aW5kZXhlcXVhbHplcm8oZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGVtcGxveWVlTGlzdDsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIGVtcGxveWVlTGlzdCA9IGVtcGxveWVlTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBjaGlsZCA9IGVtcGxveWVlTGlzdC5pdGVtKDApOworICAgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIAorICAgICAgaWYgKCFlcXVhbHMoIiN0ZXh0IiwgY2hpbGROYW1lKSkgeworICAgICAgICAgIGFzc2VydEVxdWFscygiY2hpbGROYW1lIiwgImVtcGxveWVlSWQiLCBjaGlsZE5hbWUpOworICAgICAgfQorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWxpc3RpbmRleGVxdWFsemVybyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWxpc3RpbmRleGVxdWFsemVyby5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWxpc3RpbmRleGdldGxlbmd0aC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlbGlzdGluZGV4Z2V0bGVuZ3RoLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzFkMTQwOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWxpc3RpbmRleGdldGxlbmd0aC5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRMZW5ndGgoKSIgbWV0aG9kIHJldHVybnMgdGhlIG51bWJlciBvZiBub2RlcworICogICAgaW4gdGhlIGxpc3Qgc2hvdWxkIGJlIDYgKG5vIHdoaXRlc3BhY2UpIG9yIDEzLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjAzNTEwMzM3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0yMDM1MTAzMzc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVsaXN0aW5kZXhnZXRsZW5ndGggZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVsaXN0aW5kZXhnZXRsZW5ndGgoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGVtcGxveWVlTGlzdDsKKyAgICAgIGludCBsZW5ndGg7CisgICAgICBpbnQgZXhwZWN0ZWRDb3VudCA9IDA7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgZW1wbG95ZWVMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGxlbmd0aCA9IChpbnQpIGVtcGxveWVlTGlzdC5nZXRMZW5ndGgoKTsKKyAgICAgIGFzc2VydFRydWUoImxlbmd0aElzNm9yMTMiLCAKKyAgICAoZXF1YWxzKDYsIGxlbmd0aCkgfCBlcXVhbHMoMTMsIGxlbmd0aCkpCispOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlbGlzdGluZGV4Z2V0bGVuZ3RoIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlbGlzdGluZGV4Z2V0bGVuZ3RoLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlbGlzdGluZGV4Z2V0bGVuZ3Rob2ZlbXB0eWxpc3QuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWxpc3RpbmRleGdldGxlbmd0aG9mZW1wdHlsaXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDMzNzcxZgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWxpc3RpbmRleGdldGxlbmd0aG9mZW1wdHlsaXN0LmphdmEKQEAgLTAsMCArMSw5NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRMZW5ndGgoKSIgbWV0aG9kIHJldHVybnMgdGhlIG51bWJlciBvZiBub2RlcworICogICAgaW4gdGhlIGxpc3QuKFRlc3QgZm9yIEVNUFRZIGxpc3QpCisgKiAgICAKKyAqICAgIENyZWF0ZSBhIGxpc3Qgb2YgYWxsIHRoZSBjaGlsZHJlbiBvZiB0aGUgVGV4dCBub2RlIAorICogICAgaW5zaWRlIHRoZSBmaXJzdCBjaGlsZCBvZiB0aGUgdGhpcmQgZW1wbG95ZWUgYW5kCisgKiAgICBpbnZva2UgdGhlICJnZXRMZW5ndGgoKSIgbWV0aG9kLiAgIEl0IHNob3VsZCBjb250YWluCisgKiAgICB0aGUgdmFsdWUgMC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIwMzUxMDMzNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjAzNTEwMzM3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlbGlzdGluZGV4Z2V0bGVuZ3Rob2ZlbXB0eWxpc3QgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVsaXN0aW5kZXhnZXRsZW5ndGhvZmVtcHR5bGlzdChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZUxpc3QgZW1wbG95ZWVMaXN0OworICAgICAgTm9kZSBjaGlsZE5vZGU7CisgICAgICBOb2RlIHRleHROb2RlOworICAgICAgTm9kZUxpc3QgdGV4dExpc3Q7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgZW1wbG95ZWVMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGNoaWxkTm9kZSA9IGVtcGxveWVlTGlzdC5pdGVtKDEpOworICAgICAgdGV4dE5vZGUgPSBjaGlsZE5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgdGV4dExpc3QgPSB0ZXh0Tm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBhc3NlcnRTaXplKCJub2RlbGlzdEluZGV4R2V0TGVuZ3RoT2ZFbXB0eUxpc3RBc3NlcnQiLCAwLCB0ZXh0TGlzdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVsaXN0aW5kZXhnZXRsZW5ndGhvZmVtcHR5bGlzdCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWxpc3RpbmRleGdldGxlbmd0aG9mZW1wdHlsaXN0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlbGlzdGluZGV4bm90emVyby5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlbGlzdGluZGV4bm90emVyby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYzZGU4ZDgKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVsaXN0aW5kZXhub3R6ZXJvLmphdmEKQEAgLTAsMCArMSwxMDAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICBDcmVhdGUgYSBsaXN0IG9mIGFsbCB0aGUgY2hpbGRyZW4gZWxlbWVudHMgb2YgdGhlIHRoaXJkCisgKiAgICBlbXBsb3llZSBhbmQgYWNjZXNzIGl0cyBmb3VydGggY2hpbGQgYnkgdXNpbmcgYW4gaW5kZXgKKyAqICAgIG9mIDMuICBUaGlzIHNob3VsZCByZXN1bHQgaW4gIm5hbWUiIGJlaW5nCisgKiAgICBzZWxlY3RlZC4gIEZ1cnRoZXIgd2UgZXZhbHVhdGUgaXRzIGNvbnRlbnQoYnkgdXNpbmcKKyAqICAgIHRoZSAiZ2V0Tm9kZU5hbWUoKSIgbWV0aG9kKSB0byBlbnN1cmUgdGhlIHByb3BlcgorICogICAgZWxlbWVudCB3YXMgYWNjZXNzZWQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NDQzNzcxMzYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0NDM3NzEzNjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWxpc3RpbmRleG5vdHplcm8gZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVsaXN0aW5kZXhub3R6ZXJvKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBlbXBsb3llZUxpc3Q7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgaW50IGxlbmd0aDsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgZW1wbG95ZWVMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGxlbmd0aCA9IChpbnQpIGVtcGxveWVlTGlzdC5nZXRMZW5ndGgoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscyg2LCBsZW5ndGgpKSB7CisgICAgICAgICAgY2hpbGQgPSBlbXBsb3llZUxpc3QuaXRlbSgxKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgY2hpbGQgPSBlbXBsb3llZUxpc3QuaXRlbSgzKTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZU5hbWUiLCAibmFtZSIsIGNoaWxkTmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVsaXN0aW5kZXhub3R6ZXJvIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlbGlzdGluZGV4bm90emVyby5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWxpc3RyZXR1cm5maXJzdGl0ZW0uamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWxpc3RyZXR1cm5maXJzdGl0ZW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMzIxNTg4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlbGlzdHJldHVybmZpcnN0aXRlbS5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBHZXQgdGhlIGZpcnN0IGNoaWxkIG9mIHRoZSB0aGlyZCBlbXBsb3llZSB1c2luZyBOb2RlTGlzdC5pdGVtKDApCisgKiB3aGljaCB3aWxsIGVpdGhlciBiZSBhIFRleHQgbm9kZSAod2hpdGVzcGFjZSkgb3IgZW1wbG95ZWVJZCBlbGVtZW50LgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODQ0Mzc3MTM2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NDQzNzcxMzY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVsaXN0cmV0dXJuZmlyc3RpdGVtIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlbGlzdHJldHVybmZpcnN0aXRlbShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZUxpc3QgZW1wbG95ZWVMaXN0OworICAgICAgTm9kZSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBpbnQgbGVuZ3RoOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIGVtcGxveWVlTGlzdCA9IGVtcGxveWVlTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBjaGlsZCA9IGVtcGxveWVlTGlzdC5pdGVtKDApOworICAgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGxlbmd0aCA9IChpbnQpIGVtcGxveWVlTGlzdC5nZXRMZW5ndGgoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscyg2LCBsZW5ndGgpKSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzSWdub3JlQ2FzZSgiZmlyc3RDaGlsZE5vV2hpdGVzcGFjZSIsICJlbXBsb3llZUlkIiwgY2hpbGROYW1lKTsKK30gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzSWdub3JlQ2FzZSgiZmlyc3RDaGlsZFdpdGhXaGl0ZXNwYWNlIiwgIiN0ZXh0IiwgY2hpbGROYW1lKTsKK30KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlbGlzdHJldHVybmZpcnN0aXRlbSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWxpc3RyZXR1cm5maXJzdGl0ZW0uY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVsaXN0cmV0dXJubGFzdGl0ZW0uamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWxpc3RyZXR1cm5sYXN0aXRlbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlOTdhYjAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVsaXN0cmV0dXJubGFzdGl0ZW0uamF2YQpAQCAtMCwwICsxLDk4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogR2V0IHRoaXMgbGFzdCBjaGlsZCBvZiB0aGUgdGhpcmQgZW1wbG95ZWUgdXNpbmcgTm9kZUxpc3QuaXRlbShOb2RlTGlzdC5sZW5ndGggLSAxKQorICogYW5kIGNoZWNrIHRoYXQgaXQgaXMgZWl0aGVyIGEgVGV4dCBlbGVtZW50ICh3aXRoIHdoaXRlc3BhY2UpIG9yIGFuIGFkZHJlc3MgZWxlbWVudC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0NDM3NzEzNiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODQ0Mzc3MTM2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlbGlzdHJldHVybmxhc3RpdGVtIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlbGlzdHJldHVybmxhc3RpdGVtKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBlbXBsb3llZUxpc3Q7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIGludCBsZW5ndGg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgZW1wbG95ZWVMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGxlbmd0aCA9IChpbnQpIGVtcGxveWVlTGlzdC5nZXRMZW5ndGgoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscyg2LCBsZW5ndGgpKSB7CisgICAgICAgICAgY2hpbGQgPSBlbXBsb3llZUxpc3QuaXRlbSg1KTsKKyAgICAgIGNoaWxkTmFtZSA9IGNoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lMSIsICJhZGRyZXNzIiwgY2hpbGROYW1lKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgY2hpbGQgPSBlbXBsb3llZUxpc3QuaXRlbSgxMik7CisgICAgICBjaGlsZE5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTmFtZTIiLCAiI3RleHQiLCBjaGlsZE5hbWUpOworICAgICAgfQorICAgICAgICAKKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVsaXN0cmV0dXJubGFzdGl0ZW0iOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVsaXN0cmV0dXJubGFzdGl0ZW0uY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVsaXN0dHJhdmVyc2VsaXN0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVsaXN0dHJhdmVyc2VsaXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODVjYmM0OAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZWxpc3R0cmF2ZXJzZWxpc3QuamF2YQpAQCAtMCwwICsxLDEyOCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgcmFuZ2Ugb2YgdmFsaWQgY2hpbGQgbm9kZSBpbmRpY2VzIGlzIDAgdGhydSBsZW5ndGggLTEKKyAqICAgIAorICogICAgQ3JlYXRlIGEgbGlzdCBvZiBhbGwgdGhlIGNoaWxkcmVuIGVsZW1lbnRzIG9mIHRoZSB0aGlyZAorICogICAgZW1wbG95ZWUgYW5kIHRyYXZlcnNlIHRoZSBsaXN0IGZyb20gaW5kZXg9MCB0aHJ1CisgKiAgICBsZW5ndGggLTEuICAgICAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTIwMzUxMDMzNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMjAzNTEwMzM3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0NDM3NzEzNiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODQ0Mzc3MTM2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlbGlzdHRyYXZlcnNlbGlzdCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWxpc3R0cmF2ZXJzZWxpc3QoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGVtcGxveWVlTGlzdDsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgamF2YS51dGlsLkxpc3QgcmVzdWx0ID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIAorICAgICAgaW50IGxlbmd0aDsKKyAgICAgIGphdmEudXRpbC5MaXN0IGV4cGVjdGVkV2hpdGVzcGFjZSA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZFdoaXRlc3BhY2UuYWRkKCIjdGV4dCIpOworICAgICAgZXhwZWN0ZWRXaGl0ZXNwYWNlLmFkZCgiZW1wbG95ZWVJZCIpOworICAgICAgZXhwZWN0ZWRXaGl0ZXNwYWNlLmFkZCgiI3RleHQiKTsKKyAgICAgIGV4cGVjdGVkV2hpdGVzcGFjZS5hZGQoIm5hbWUiKTsKKyAgICAgIGV4cGVjdGVkV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICBleHBlY3RlZFdoaXRlc3BhY2UuYWRkKCJwb3NpdGlvbiIpOworICAgICAgZXhwZWN0ZWRXaGl0ZXNwYWNlLmFkZCgiI3RleHQiKTsKKyAgICAgIGV4cGVjdGVkV2hpdGVzcGFjZS5hZGQoInNhbGFyeSIpOworICAgICAgZXhwZWN0ZWRXaGl0ZXNwYWNlLmFkZCgiI3RleHQiKTsKKyAgICAgIGV4cGVjdGVkV2hpdGVzcGFjZS5hZGQoImdlbmRlciIpOworICAgICAgZXhwZWN0ZWRXaGl0ZXNwYWNlLmFkZCgiI3RleHQiKTsKKyAgICAgIGV4cGVjdGVkV2hpdGVzcGFjZS5hZGQoImFkZHJlc3MiKTsKKyAgICAgIGV4cGVjdGVkV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5MaXN0IGV4cGVjdGVkTm9XaGl0ZXNwYWNlID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGV4cGVjdGVkTm9XaGl0ZXNwYWNlLmFkZCgiZW1wbG95ZWVJZCIpOworICAgICAgZXhwZWN0ZWROb1doaXRlc3BhY2UuYWRkKCJuYW1lIik7CisgICAgICBleHBlY3RlZE5vV2hpdGVzcGFjZS5hZGQoInBvc2l0aW9uIik7CisgICAgICBleHBlY3RlZE5vV2hpdGVzcGFjZS5hZGQoInNhbGFyeSIpOworICAgICAgZXhwZWN0ZWROb1doaXRlc3BhY2UuYWRkKCJnZW5kZXIiKTsKKyAgICAgIGV4cGVjdGVkTm9XaGl0ZXNwYWNlLmFkZCgiYWRkcmVzcyIpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgZW1wbG95ZWVMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGxlbmd0aCA9IChpbnQpIGVtcGxveWVlTGlzdC5nZXRMZW5ndGgoKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMEE0ID0gMDsgaW5kZXhOMTAwQTQgPCBlbXBsb3llZUxpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMEE0KyspIHsKKyAgICAgICAgICBjaGlsZCA9IChOb2RlKSBlbXBsb3llZUxpc3QuaXRlbShpbmRleE4xMDBBNCk7CisgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIHJlc3VsdC5hZGQoY2hpbGROYW1lKTsKKyAgICAgICAgfQorICAgICAgCisgICAgICBpZiAoZXF1YWxzKDYsIGxlbmd0aCkpIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoIm5vd2hpdGVzcGFjZSIsIGV4cGVjdGVkTm9XaGl0ZXNwYWNlLCByZXN1bHQpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoIndoaXRlc3BhY2UiLCBleHBlY3RlZFdoaXRlc3BhY2UsIHJlc3VsdCk7CisgICAgICB9CisgICAgICAgIAorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZWxpc3R0cmF2ZXJzZWxpc3QiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVsaXN0dHJhdmVyc2VsaXN0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2Rlbm90YXRpb25ub2RlYXR0cmlidXRlcy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2Rlbm90YXRpb25ub2RlYXR0cmlidXRlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVlYWY0MmMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVub3RhdGlvbm5vZGVhdHRyaWJ1dGVzLmphdmEKQEAgLTAsMCArMSw5MiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEF0dHJpYnV0ZXMoKSIgbWV0aG9kIGludm9rZWQgb24gYSBOb3RhdGlvbiAKKyAqICAgICBOb2RlIHJldHVybnMgbnVsbC4KKyAqICAgICBSZXRyaWV2ZSB0aGUgTm90YXRpb24gZGVjbGFyYXRpb24gaW5zaWRlIHRoZSBEb2N1bWVudFR5cGUKKyAqICAgICBub2RlIGFuZCBpbnZva2UgdGhlICJnZXRBdHRyaWJ1dGVzKCkiIG1ldGhvZCBvbiB0aGUgCisgKiAgICAgTm90YXRpb24gTm9kZS4gICBJdCBzaG91bGQgcmV0dXJuIG51bGwuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODRDRjA5NjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZW5vdGF0aW9ubm9kZWF0dHJpYnV0ZXMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVub3RhdGlvbm5vZGVhdHRyaWJ1dGVzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTmFtZWROb2RlTWFwIG5vdGF0aW9uczsKKyAgICAgIE5vZGUgbm90YXRpb25Ob2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZG9jVHlwZU5vdE51bGwiLCBkb2NUeXBlKTsKKyAgICAgIG5vdGF0aW9ucyA9IGRvY1R5cGUuZ2V0Tm90YXRpb25zKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJub3RhdGlvbnNOb3ROdWxsIiwgbm90YXRpb25zKTsKKyAgICAgIG5vdGF0aW9uTm9kZSA9IG5vdGF0aW9ucy5nZXROYW1lZEl0ZW0oIm5vdGF0aW9uMSIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgibm90YXRpb25Ob3ROdWxsIiwgbm90YXRpb25Ob2RlKTsKKyAgICAgIGF0dHJMaXN0ID0gbm90YXRpb25Ob2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGFzc2VydE51bGwoIm5vZGVOb3RhdGlvbk5vZGVBdHRyaWJ1dGVzQXNzZXJ0MSIsIGF0dHJMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZW5vdGF0aW9ubm9kZWF0dHJpYnV0ZXMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVub3RhdGlvbm5vZGVhdHRyaWJ1dGVzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2Rlbm90YXRpb25ub2RlbmFtZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2Rlbm90YXRpb25ub2RlbmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhiMjVlMzEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVub3RhdGlvbm5vZGVuYW1lLmphdmEKQEAgLTAsMCArMSw5MyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgc3RyaW5nIHJldHVybmVkIGJ5IHRoZSAiZ2V0Tm9kZU5hbWUoKSIgbWV0aG9kIGZvciBhIAorICogICAgIE5vdGF0aW9uIE5vZGUgaXMgdGhlIG5hbWUgb2YgdGhlIG5vdGF0aW9uLgorICogICAgIFJldHJpZXZlIHRoZSBOb3RhdGlvbiBkZWNsYXJhdGlvbiBpbnNpZGUgdGhlICAgCisgKiAgICAgRG9jdW1lbnRUeXBlIG5vZGUgYW5kIGNoZWNrIHRoZSBzdHJpbmcgcmV0dXJuZWQgCisgKiAgICAgYnkgdGhlICJnZXROb2RlTmFtZSgpIiBtZXRob2QuICAgSXQgc2hvdWxkIGJlIGVxdWFsIHRvIAorICogICAgICJub3RhdGlvbjEiLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVub3RhdGlvbm5vZGVuYW1lIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2Rlbm90YXRpb25ub2RlbmFtZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBub3RhdGlvbnM7CisgICAgICBOb2RlIG5vdGF0aW9uTm9kZTsKKyAgICAgIFN0cmluZyBub3RhdGlvbk5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgbm90YXRpb25zID0gZG9jVHlwZS5nZXROb3RhdGlvbnMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoIm5vdGF0aW9uc05vdE51bGwiLCBub3RhdGlvbnMpOworICAgICAgbm90YXRpb25Ob2RlID0gbm90YXRpb25zLmdldE5hbWVkSXRlbSgibm90YXRpb24xIik7CisgICAgICBhc3NlcnROb3ROdWxsKCJub3RhdGlvbk5vdE51bGwiLCBub3RhdGlvbk5vZGUpOworICAgICAgbm90YXRpb25OYW1lID0gbm90YXRpb25Ob2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lIiwgIm5vdGF0aW9uMSIsIG5vdGF0aW9uTmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVub3RhdGlvbm5vZGVuYW1lIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2Rlbm90YXRpb25ub2RlbmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZW5vdGF0aW9ubm9kZXR5cGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZW5vdGF0aW9ubm9kZXR5cGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45M2NiZTIzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2Rlbm90YXRpb25ub2RldHlwZS5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXROb2RlVHlwZSgpIiBtZXRob2QgZm9yIGFuIE5vdGF0aW9uIE5vZGUKKyAqICAgICByZXR1cm5zIHRoZSBjb25zdGFudCB2YWx1ZSAxMi4KKyAqICAgICBSZXRyaWV2ZSB0aGUgTm90YXRpb24gZGVjbGFyYXRpb24gaW4gdGhlIERvY3VtZW50VHlwZSAKKyAqICAgICBub2RlIGFuZCBpbnZva2UgdGhlICJnZXROb2RlVHlwZSgpIiBtZXRob2QuICAgVGhlIG1ldGhvZAorICogICAgIHNob3VsZCByZXR1cm4gMTIuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMTEyMzc1NTg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVub3RhdGlvbm5vZGV0eXBlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2Rlbm90YXRpb25ub2RldHlwZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBub3RhdGlvbnM7CisgICAgICBOb3RhdGlvbiBub3RhdGlvbk5vZGU7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgbm90YXRpb25zID0gZG9jVHlwZS5nZXROb3RhdGlvbnMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoIm5vdGF0aW9uc05vdE51bGwiLCBub3RhdGlvbnMpOworICAgICAgbm90YXRpb25Ob2RlID0gKE5vdGF0aW9uKSBub3RhdGlvbnMuZ2V0TmFtZWRJdGVtKCJub3RhdGlvbjEiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoIm5vdGF0aW9uTm90TnVsbCIsIG5vdGF0aW9uTm9kZSk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIG5vdGF0aW9uTm9kZS5nZXROb2RlVHlwZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTm90YXRpb25Ob2RlVHlwZUFzc2VydDEiLCAxMiwgbm9kZVR5cGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2Rlbm90YXRpb25ub2RldHlwZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZW5vdGF0aW9ubm9kZXR5cGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVub3RhdGlvbm5vZGV2YWx1ZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2Rlbm90YXRpb25ub2RldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMjkxMjczCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2Rlbm90YXRpb25ub2RldmFsdWUuamF2YQpAQCAtMCwwICsxLDkzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlVmFsdWUoKSIgbWV0aG9kIGZvciBhIAorICogICAgIE5vdGF0aW9uIE5vZGUgaXMgbnVsbC4KKyAqICAgICBSZXRyaWV2ZSB0aGUgTm90YXRpb24gZGVjbGFyYXRpb24gaW5zaWRlIHRoZSAKKyAqICAgICBEb2N1bWVudFR5cGUgbm9kZSBhbmQgY2hlY2sgdGhlIHN0cmluZyByZXR1cm5lZCAKKyAqICAgICBieSB0aGUgImdldE5vZGVWYWx1ZSgpIiBtZXRob2QuICAgSXQgc2hvdWxkIGJlIGVxdWFsIHRvIAorICogICAgIG51bGwuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZW5vdGF0aW9ubm9kZXZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2Rlbm90YXRpb25ub2RldmFsdWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBOYW1lZE5vZGVNYXAgbm90YXRpb25zOworICAgICAgTm9kZSBub3RhdGlvbk5vZGU7CisgICAgICBTdHJpbmcgbm90YXRpb25WYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImRvY1R5cGVOb3ROdWxsIiwgZG9jVHlwZSk7CisgICAgICBub3RhdGlvbnMgPSBkb2NUeXBlLmdldE5vdGF0aW9ucygpOworICAgICAgYXNzZXJ0Tm90TnVsbCgibm90YXRpb25zTm90TnVsbCIsIG5vdGF0aW9ucyk7CisgICAgICBub3RhdGlvbk5vZGUgPSBub3RhdGlvbnMuZ2V0TmFtZWRJdGVtKCJub3RhdGlvbjEiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoIm5vdGF0aW9uTm90TnVsbCIsIG5vdGF0aW9uTm9kZSk7CisgICAgICBub3RhdGlvblZhbHVlID0gbm90YXRpb25Ob2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgibm9kZVZhbHVlIiwgbm90YXRpb25WYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVub3RhdGlvbm5vZGV2YWx1ZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZW5vdGF0aW9ubm9kZXZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcGFyZW50bm9kZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcGFyZW50bm9kZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUyN2M1M2MKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVwYXJlbnRub2RlLmphdmEKQEAgLTAsMCArMSw5NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldFBhcmVudE5vZGUoKSIgbWV0aG9kIHJldHVybnMgdGhlIHBhcmVudAorICogICAgIG9mIHRoaXMgbm9kZS4gCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgaW52b2tlIHRoZSAKKyAqICAgICAiZ2V0UGFyZW50Tm9kZSgpIiBtZXRob2Qgb24gdGhpcyBub2RlLiAgIEl0IHNob3VsZAorICogICAgIGJlIHNldCB0byAic3RhZmYiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA2MDE4NDMxNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA2MDE4NDMxNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjUxIj5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjUxPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlcGFyZW50bm9kZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXBhcmVudG5vZGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGUgcGFyZW50Tm9kZTsKKyAgICAgIFN0cmluZyBwYXJlbnROYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIHBhcmVudE5vZGUgPSBlbXBsb3llZU5vZGUuZ2V0UGFyZW50Tm9kZSgpOworICAgICAgcGFyZW50TmFtZSA9IHBhcmVudE5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIAorICAgICAgaWYgKCgiaW1hZ2Uvc3ZnK3htbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkgeworICAgICAgICAgIGFzc2VydEVxdWFscygic3ZnVGFnTmFtZSIsICJzdmciLCBwYXJlbnROYW1lKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlUGFyZW50Tm9kZUFzc2VydDEiLCAic3RhZmYiLCBwYXJlbnROYW1lKTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlcGFyZW50bm9kZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXBhcmVudG5vZGUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVwYXJlbnRub2RlbnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcGFyZW50bm9kZW51bGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YzFhOWRjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcGFyZW50bm9kZW51bGwuamF2YQpAQCAtMCwwICsxLDg2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldFBhcmVudE5vZGUoKSIgbWV0aG9kIGludm9rZWQgb24gYSBub2RlIHRoYXQgaGFzCisgKiAgICAganVzdCBiZWVuIGNyZWF0ZWQgYW5kIG5vdCB5ZXQgYWRkZWQgdG8gdGhlIHRyZWUgaXMgbnVsbC4gCisgKiAgICAgQ3JlYXRlIGEgbmV3ICJlbXBsb3llZSIgRWxlbWVudCBub2RlIHVzaW5nIHRoZSAgICAgICAgICAgICAKKyAqICAgICAiY3JlYXRlRWxlbWVudChuYW1lKSIgbWV0aG9kIGZyb20gdGhlIERvY3VtZW50IGludGVyZmFjZS4KKyAqICAgICBTaW5jZSB0aGlzIG5ldyBub2RlIGhhcyBub3QgeWV0IGJlZW4gYWRkZWQgdG8gdGhlIHRyZWUsCisgKiAgICAgdGhlICJnZXRQYXJlbnROb2RlKCkiIG1ldGhvZCB3aWxsIHJldHVybiBudWxsLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA2MDE4NDMxNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTA2MDE4NDMxNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZXBhcmVudG5vZGVudWxsIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlcGFyZW50bm9kZW51bGwoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBjcmVhdGVkTm9kZTsKKyAgICAgIE5vZGUgcGFyZW50Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBjcmVhdGVkTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50KCJlbXBsb3llZSIpOworICAgICAgcGFyZW50Tm9kZSA9IGNyZWF0ZWROb2RlLmdldFBhcmVudE5vZGUoKTsKKyAgICAgIGFzc2VydE51bGwoInBhcmVudE5vZGUiLCBwYXJlbnROb2RlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXBhcmVudG5vZGVudWxsIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlcGFyZW50bm9kZW51bGwuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25ub2RlYXR0cmlidXRlcy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZWF0dHJpYnV0ZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZTI0NTQ3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZWF0dHJpYnV0ZXMuamF2YQpAQCAtMCwwICsxLDg3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEF0dHJpYnV0ZXMoKSIgbWV0aG9kIGludm9rZWQgb24gYSBQcm9jZXNzaW5nIAorICogICAgIEluc3RydWN0aW9uIE5vZGUgcmV0dXJucyBudWxsLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBQcm9jZXNzaW5nIEluc3RydWN0aW9uIG5vZGUgYW5kIGludm9rZSAKKyAqICAgICB0aGUgImdldEF0dHJpYnV0ZXMoKSIgbWV0aG9kLiAgIEl0IHNob3VsZCByZXR1cm4gbnVsbC4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04NENGMDk2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZWF0dHJpYnV0ZXMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25ub2RlYXR0cmlidXRlcyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCB0ZXN0TGlzdDsKKyAgICAgIE5vZGUgcGlOb2RlOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIHRlc3RMaXN0ID0gZG9jLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIHBpTm9kZSA9IHRlc3RMaXN0Lml0ZW0oMCk7CisgICAgICBhdHRyTGlzdCA9IHBpTm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBhc3NlcnROdWxsKCJub2RlUHJvY2Vzc2luZ0luc3RydWN0aW9uTm9kZUF0dHJBc3NlcnQxIiwgYXR0ckxpc3QpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZWF0dHJpYnV0ZXMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25ub2RlYXR0cmlidXRlcy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXByb2Nlc3NpbmdpbnN0cnVjdGlvbm5vZGVuYW1lLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25ub2RlbmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMwMmYwMzEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25ub2RlbmFtZS5qYXZhCkBAIC0wLDAgKzEsODggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlTmFtZSgpIiBtZXRob2QgZm9yIGEgCisgKiAgICAgUHJvY2Vzc2luZyBJbnN0cnVjdGlvbiBOb2RlIGlzIHRoZSB0YXJnZXQuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIFByb2Nlc3NpbmcgSW5zdHJ1Y3Rpb24gTm9kZSBpbiB0aGUgWE1MIGZpbGUgCisgKiAgICAgYW5kIGNoZWNrIHRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlTmFtZSgpIiAKKyAqICAgICBtZXRob2QuICAgSXQgc2hvdWxkIGJlIGVxdWFsIHRvICJYTUwtU1RZTEUiLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25ub2RlbmFtZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXByb2Nlc3NpbmdpbnN0cnVjdGlvbm5vZGVuYW1lKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IHRlc3RMaXN0OworICAgICAgTm9kZSBwaU5vZGU7CisgICAgICBTdHJpbmcgcGlOYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIHRlc3RMaXN0ID0gZG9jLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIHBpTm9kZSA9IHRlc3RMaXN0Lml0ZW0oMCk7CisgICAgICBwaU5hbWUgPSBwaU5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZVByb2Nlc3NpbmdJbnN0cnVjdGlvbk5vZGVOYW1lQXNzZXJ0MSIsICJURVNULVNUWUxFIiwgcGlOYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXByb2Nlc3NpbmdpbnN0cnVjdGlvbm5vZGVuYW1lIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZW5hbWUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25ub2RldHlwZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZXR5cGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MzU2YmRjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZXR5cGUuamF2YQpAQCAtMCwwICsxLDg4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldE5vZGVUeXBlKCkiIG1ldGhvZCBmb3IgYSBQcm9jZXNzaW5nIEluc3RydWN0aW9uIAorICogICAgIG5vZGUgcmV0dXJucyB0aGUgY29uc3RhbnQgdmFsdWUgNy4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSBhIE5vZGVMaXN0IG9mIGNoaWxkIGVsZW1lbnRzIGZyb20gdGhlIGRvY3VtZW50LgorICogICAgIFJldHJpZXZlIHRoZSBmaXJzdCBjaGlsZCBhbmQgaW52b2tlIHRoZSAiZ2V0Tm9kZVR5cGUoKSIgICAKKyAqICAgICBtZXRob2QuICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIDcuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMTEyMzc1NTg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25ub2RldHlwZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXByb2Nlc3NpbmdpbnN0cnVjdGlvbm5vZGV0eXBlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IHRlc3RMaXN0OworICAgICAgTm9kZSBwaU5vZGU7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgdGVzdExpc3QgPSBkb2MuZ2V0Q2hpbGROb2RlcygpOworICAgICAgcGlOb2RlID0gdGVzdExpc3QuaXRlbSgwKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgcGlOb2RlLmdldE5vZGVUeXBlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25Ob2RlVHlwZUFzc2VydDEiLCA3LCBub2RlVHlwZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25ub2RldHlwZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXByb2Nlc3NpbmdpbnN0cnVjdGlvbm5vZGV0eXBlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZXZhbHVlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25ub2RldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNDg0Y2FhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZXZhbHVlLmphdmEKQEAgLTAsMCArMSw4OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIHN0cmluZyByZXR1cm5lZCBieSB0aGUgImdldE5vZGVWYWx1ZSgpIiBtZXRob2QgZm9yIGEgCisgKiAgICAgUHJvY2Vzc2luZyBJbnN0cnVjdGlvbiBOb2RlIGlzIHRoZSBjb250ZW50IG9mIHRoZQorICogICAgIFByb2Nlc3NpbmcgSW5zdHJ1Y3Rpb24oZXhjbHVkZSB0aGUgdGFyZ2V0KS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgUHJvY2Vzc2luZyBJbnN0cnVjdGlvbiBub2RlIGluIHRoZSBYTUwgZmlsZSAKKyAqICAgICBhbmQgY2hlY2sgdGhlIHN0cmluZyByZXR1cm5lZCBieSB0aGUgImdldE5vZGVWYWx1ZSgpIiAKKyAqICAgICBtZXRob2QuICAgSXQgc2hvdWxkIGJlIGVxdWFsIHRvICJQSURBVEEiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZXByb2Nlc3NpbmdpbnN0cnVjdGlvbm5vZGV2YWx1ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXByb2Nlc3NpbmdpbnN0cnVjdGlvbm5vZGV2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCB0ZXN0TGlzdDsKKyAgICAgIE5vZGUgcGlOb2RlOworICAgICAgU3RyaW5nIHBpVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgdGVzdExpc3QgPSBkb2MuZ2V0Q2hpbGROb2RlcygpOworICAgICAgcGlOb2RlID0gdGVzdExpc3QuaXRlbSgwKTsKKyAgICAgIHBpVmFsdWUgPSBwaU5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlIiwgIlBJREFUQSIsIHBpVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZXZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9ubm9kZXZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9uc2V0bm9kZXZhbHVlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25zZXRub2RldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNGU4ZmRkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9uc2V0bm9kZXZhbHVlLmphdmEKQEAgLTAsMCArMSw4OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBTZXR0aW5nIHRoZSBub2RlVmFsdWUgc2hvdWxkIGNoYW5nZSB0aGUgdmFsdWUgcmV0dXJuZWQgYnkKKyAqICAgICBub2RlVmFsdWUgYW5kIFByb2Nlc3NpbmdJbnN0cnVjdGlvbi5nZXREYXRhLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDA0MjE1ODEzIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDA0MjE1ODEzPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTgzNzgyMjM5MyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODM3ODIyMzkzPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0xODEiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0xODE8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25zZXRub2RldmFsdWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVwcm9jZXNzaW5naW5zdHJ1Y3Rpb25zZXRub2RldmFsdWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCB0ZXN0TGlzdDsKKyAgICAgIE5vZGUgcGlOb2RlOworICAgICAgU3RyaW5nIHBpVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICB0ZXN0TGlzdCA9IGRvYy5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBwaU5vZGUgPSB0ZXN0TGlzdC5pdGVtKDApOworICAgICAgcGlOb2RlLnNldE5vZGVWYWx1ZSgiU29tZXRoaW5nIGRpZmZlcmVudCIpOworICAgICAgcGlWYWx1ZSA9IHBpTm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZVZhbHVlIiwgIlNvbWV0aGluZyBkaWZmZXJlbnQiLCBwaVZhbHVlKTsKKyAgICAgIHBpVmFsdWUgPSAoKFByb2Nlc3NpbmdJbnN0cnVjdGlvbikgLypOb2RlICovcGlOb2RlKS5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRhdGEiLCAiU29tZXRoaW5nIGRpZmZlcmVudCIsIHBpVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9uc2V0bm9kZXZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlcHJvY2Vzc2luZ2luc3RydWN0aW9uc2V0bm9kZXZhbHVlLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcmVtb3ZlY2hpbGQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlbW92ZWNoaWxkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTE3ZWQ3YQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlbW92ZWNoaWxkLmphdmEKQEAgLTAsMCArMSw5NCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZW1vdmVDaGlsZChvbGRDaGlsZCkiIG1ldGhvZCByZW1vdmVzIHRoZSBjaGlsZCBub2RlCisgKiAgICAgaW5kaWNhdGVkIGJ5ICJvbGRDaGlsZCIgZnJvbSB0aGUgbGlzdCBvZiBjaGlsZHJlbiBhbmQKKyAqICAgICByZXR1cm5zIGl0LiAKKyAqICAgICAKKyAqICAgICBSZW1vdmUgdGhlIGZpcnN0IGVtcGxveWVlIGJ5IGludm9raW5nIHRoZQorICogICAgICJyZW1vdmVDaGlsZChvbGRDaGlsZCkiIG1ldGhvZCBhbiBjaGVja2luZyB0aGUKKyAqICAgICBub2RlIHJldHVybmVkIGJ5IHRoZSAiZ2V0UGFyZW50Tm9kZSgpIiBtZXRob2QuICAgSXQKKyAqICAgICBzaG91bGQgYmUgc2V0IHRvIG51bGwuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlcmVtb3ZlY2hpbGQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVyZW1vdmVjaGlsZChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgcm9vdE5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIGNoaWxkVG9SZW1vdmU7CisgICAgICBOb2RlIHJlbW92ZWRDaGlsZDsKKyAgICAgIE5vZGUgcGFyZW50Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIHJvb3ROb2RlID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgY2hpbGRMaXN0ID0gcm9vdE5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgY2hpbGRUb1JlbW92ZSA9IGNoaWxkTGlzdC5pdGVtKDEpOworICAgICAgcmVtb3ZlZENoaWxkID0gcm9vdE5vZGUucmVtb3ZlQ2hpbGQoY2hpbGRUb1JlbW92ZSk7CisgICAgICBwYXJlbnROb2RlID0gcmVtb3ZlZENoaWxkLmdldFBhcmVudE5vZGUoKTsKKyAgICAgIGFzc2VydE51bGwoIm5vZGVSZW1vdmVDaGlsZEFzc2VydDEiLCBwYXJlbnROb2RlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXJlbW92ZWNoaWxkIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlcmVtb3ZlY2hpbGQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVyZW1vdmVjaGlsZGdldG5vZGVuYW1lLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVyZW1vdmVjaGlsZGdldG5vZGVuYW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2MyZTYxYwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlbW92ZWNoaWxkZ2V0bm9kZW5hbWUuamF2YQpAQCAtMCwwICsxLDEwMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgUmVtb3ZlIHRoZSBmaXJzdCBjaGlsZCBvZiB0aGUgc2Vjb25kIGVtcGxveWVlIAorICogICAgIGFuZCBjaGVjayB0aGUgTm9kZU5hbWUgcmV0dXJuZWQgYnkgdGhlIAorICogICAgICJyZW1vdmVDaGlsZChvbGRDaGlsZCkiIG1ldGhvZC4gICBUaGUgcmV0dXJuZWQgbm9kZQorICogICAgIHNob3VsZCBoYXZlIGEgTm9kZU5hbWUgZXF1YWwgdG8gIiN0ZXh0IiBvciBlbXBsb3llZUlkIGRlcGVuZGluZyBvbiB3aGl0ZXNwYWNlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlcmVtb3ZlY2hpbGRnZXRub2RlbmFtZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXJlbW92ZWNoaWxkZ2V0bm9kZW5hbWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgTm9kZSBvbGRDaGlsZDsKKyAgICAgIE5vZGUgcmVtb3ZlZENoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIGludCBsZW5ndGg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjaGlsZExpc3QgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgbGVuZ3RoID0gKGludCkgY2hpbGRMaXN0LmdldExlbmd0aCgpOworICAgICAgb2xkQ2hpbGQgPSBjaGlsZExpc3QuaXRlbSgwKTsKKyAgICAgIHJlbW92ZWRDaGlsZCA9IGVtcGxveWVlTm9kZS5yZW1vdmVDaGlsZChvbGRDaGlsZCk7CisgICAgICBjaGlsZE5hbWUgPSByZW1vdmVkQ2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscyg2LCBsZW5ndGgpKSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJub3doaXRlc3BhY2UiLCAiZW1wbG95ZWVJZCIsIGNoaWxkTmFtZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICAgIGFzc2VydEVxdWFscygid2hpdGVzcGFjZSIsICIjdGV4dCIsIGNoaWxkTmFtZSk7CisgICAgICB9CisgICAgICAgIAorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXJlbW92ZWNoaWxkZ2V0bm9kZW5hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVyZW1vdmVjaGlsZGdldG5vZGVuYW1lLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcmVtb3ZlY2hpbGRub2RlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVyZW1vdmVjaGlsZG5vZGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZDIxYWRlCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcmVtb3ZlY2hpbGRub2RlLmphdmEKQEAgLTAsMCArMSwxMDcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgUmV0cmlldmUgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgcmVtb3ZlIGl0cyBmaXJzdCBjaGlsZC4KKyAqICAgICBBZnRlciB0aGUgcmVtb3ZhbCwgdGhlIHNlY29uZCBlbXBsb3llZSBzaG91bGQgaGF2ZSBmaXZlIG9yIHR3ZWx2ZSAKKyAqICAgICBjaGlsZHJlbiBhbmQgdGhlIGZpcnN0IGNoaWxkIHNob3VsZCBub3cgYmUgdGhlIGNoaWxkCisgKiAgICAgdGhhdCB1c2VkIHRvIGJlIGF0IHRoZSBzZWNvbmQgcG9zaXRpb24gaW4gdGhlIGxpc3QuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlcmVtb3ZlY2hpbGRub2RlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlcmVtb3ZlY2hpbGRub2RlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgb2xkQ2hpbGQ7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIGludCBsZW5ndGg7CisgICAgICBOb2RlIHJlbW92ZWRDaGlsZDsKKyAgICAgIFN0cmluZyByZW1vdmVkTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTGlzdCA9IGVtcGxveWVlTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBvbGRDaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDApOworICAgICAgcmVtb3ZlZENoaWxkID0gZW1wbG95ZWVOb2RlLnJlbW92ZUNoaWxkKG9sZENoaWxkKTsKKyAgICAgIHJlbW92ZWROYW1lID0gcmVtb3ZlZENoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICBjaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDApOworICAgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGxlbmd0aCA9IChpbnQpIGNoaWxkTGlzdC5nZXRMZW5ndGgoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscyg1LCBsZW5ndGgpKSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJyZW1vdmVkTmFtZU5vV2hpdGVzcGFjZSIsICJlbXBsb3llZUlkIiwgcmVtb3ZlZE5hbWUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJjaGlsZE5hbWVOb1doaXRlc3BhY2UiLCAibmFtZSIsIGNoaWxkTmFtZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICAgIGFzc2VydEVxdWFscygicmVtb3ZlZE5hbWUiLCAiI3RleHQiLCByZW1vdmVkTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoaWxkTmFtZSIsICJlbXBsb3llZUlkIiwgY2hpbGROYW1lKTsKKyAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoIiwgMTIsIGxlbmd0aCk7CisgICAgICB9CisgICAgICAgIAorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXJlbW92ZWNoaWxkbm9kZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXJlbW92ZWNoaWxkbm9kZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlbW92ZWNoaWxkbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVyZW1vdmVjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY3NjBjNjgKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVyZW1vdmVjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCkBAIC0wLDAgKzEsMTE0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlbW92ZUNoaWxkKG9sZENoaWxkKSIgbWV0aG9kIGNhdXNlcyB0aGUgCisgKiAgICAgRE9NRXhjZXB0aW9uIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiB0byBiZSByYWlzZWQKKyAqICAgICBpZiB0aGUgbm9kZSBpcyByZWFkb25seS4KKyAqICAgICAKKyAqICAgICBPYnRhaW4gdGhlIGNoaWxkcmVuIG9mIHRoZSBUSElSRCAiZ2VuZGVyIiBlbGVtZW50LiAgIFRoZSBlbGVtZW50cworICogICAgIGNvbnRlbnQgaXMgYW4gZW50aXR5IHJlZmVyZW5jZS4gICBHZXQgdGhlIEZJUlNUIGl0ZW0gCisgKiAgICAgZnJvbSB0aGUgZW50aXR5IHJlZmVyZW5jZSBhbmQgZXhlY3V0ZSB0aGUgInJlbW92ZUNoaWxkKG9sZENoaWxkKSIgbWV0aG9kLgorICogICAgIFRoaXMgY2F1c2VzIGEgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIERPTUV4Y2VwdGlvbiB0byBiZSB0aHJvd24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MzQ4MzQwNjYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MzQ4MzQwNjY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTE3MzQ4MzQwNjYnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0xNzM0ODM0MDY2JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MzQ4MzQwNjYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MzQ4MzQwNjY8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVyZW1vdmVjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXJlbW92ZWNoaWxkbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyTm9kZTsKKyAgICAgIE5vZGUgZW50UmVmOworICAgICAgTm9kZSBlbnRFbGVtZW50OworICAgICAgTm9kZSByZW1vdmVkTm9kZTsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGdlbmRlckxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImdlbmRlciIpOworICAgICAgZ2VuZGVyTm9kZSA9IGdlbmRlckxpc3QuaXRlbSgyKTsKKyAgICAgIGVudFJlZiA9IGdlbmRlck5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50UmVmTm90TnVsbCIsIGVudFJlZik7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGVudFJlZi5nZXROb2RlVHlwZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDEsIG5vZGVUeXBlKSkgeworICAgICAgICAgIGVudFJlZiA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDQiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZW50UmVmKTsKKyAgICAgIH0KKyAgICBlbnRFbGVtZW50ID0gZW50UmVmLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudEVsZW1lbnROb3ROdWxsIiwgZW50RWxlbWVudCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlbW92ZWROb2RlID0gZW50UmVmLnJlbW92ZUNoaWxkKGVudEVsZW1lbnQpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVyZW1vdmVjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXJlbW92ZWNoaWxkbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcmVtb3ZlY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcmVtb3ZlY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJkYmZmMjIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVyZW1vdmVjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmphdmEKQEAgLTAsMCArMSwxMDEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZW1vdmVDaGlsZChvbGRDaGlsZCkiIG1ldGhvZCBjYXVzZXMgdGhlIAorICogICAgIERPTUV4Y2VwdGlvbiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgdG8gYmUgcmFpc2VkCisgKiAgICAgaWYgdGhlIG5vZGUgaXMgcmVhZG9ubHkuCisgKiAgICAgCisgKiAgICAgQ3JlYXRlIGFuIGVudGl0eSByZWZlcmVuY2UgYW5kIGV4ZWN1dGUgdGhlICJyZW1vdmVDaGlsZChvbGRDaGlsZCkiIG1ldGhvZC4KKyAqICAgICBUaGlzIGNhdXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gdG8gYmUgdGhyb3duLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0xNzM0ODM0MDY2JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMTczNDgzNDA2NicpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXJlbW92ZWNoaWxkbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLnhtbCI+aHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlcmVtb3ZlY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIueG1sPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlcmVtb3ZlY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXJlbW92ZWNoaWxkbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIGVudFJlZjsKKyAgICAgIE5vZGUgZW50VGV4dDsKKyAgICAgIE5vZGUgcmVtb3ZlZE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbnRSZWYgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQ0Iik7CisgICAgICBhc3NlcnROb3ROdWxsKCJjcmVhdGVkRW50UmVmTm90TnVsbCIsIGVudFJlZik7CisgICAgICBlbnRUZXh0ID0gZW50UmVmLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudFRleHROb3ROdWxsIiwgZW50VGV4dCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlbW92ZWROb2RlID0gZW50UmVmLnJlbW92ZUNoaWxkKGVudFRleHQpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVyZW1vdmVjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlcmVtb3ZlY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlbW92ZWNoaWxkb2xkY2hpbGRub25leGlzdGVudC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcmVtb3ZlY2hpbGRvbGRjaGlsZG5vbmV4aXN0ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWM2MzQwOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlbW92ZWNoaWxkb2xkY2hpbGRub25leGlzdGVudC5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAicmVtb3ZlQ2hpbGQob2xkQ2hpbGQpIiBtZXRob2QgcmFpc2VzIGEgCisgKiAgICAgTk9UX0ZPVU5EX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIG9sZCBjaGlsZCBpcworICogICAgIG5vdCBhIGNoaWxkIG9mIHRoaXMgbm9kZS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBhdHRlbXB0IHRvIHJlbW92ZSBhCisgKiAgICAgbm9kZSB0aGF0IGlzIG5vdCBvbmUgb2YgaXRzIGNoaWxkcmVuLiAgIEFuIGF0dGVtcHQgdG8KKyAqICAgICByZW1vdmUgc3VjaCBhIG5vZGUgc2hvdWxkIHJhaXNlIHRoZSBkZXNpcmVkIGV4Y2VwdGlvbi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT1RfRk9VTkRfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9UX0ZPVU5EX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xNzM0ODM0MDY2PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0xNzM0ODM0MDY2JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9UX0ZPVU5EX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTE3MzQ4MzQwNjYnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT1RfRk9VTkRfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MzQ4MzQwNjYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MzQ4MzQwNjY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZXJlbW92ZWNoaWxkb2xkY2hpbGRub25leGlzdGVudCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXJlbW92ZWNoaWxkb2xkY2hpbGRub25leGlzdGVudChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGUgb2xkQ2hpbGQ7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZWxlbWVudE5vZGU7CisgICAgICBOb2RlIHJlbW92ZWRDaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIG9sZENoaWxkID0gZG9jLmNyZWF0ZUVsZW1lbnQoIm9sZENoaWxkIik7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIGVsZW1lbnROb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVtb3ZlZENoaWxkID0gZWxlbWVudE5vZGUucmVtb3ZlQ2hpbGQob2xkQ2hpbGQpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT1RfRk9VTkRfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9GT1VORF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXJlbW92ZWNoaWxkb2xkY2hpbGRub25leGlzdGVudCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXJlbW92ZWNoaWxkb2xkY2hpbGRub25leGlzdGVudC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcmVwbGFjZWNoaWxkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWJlMDczNgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZC5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAicmVwbGFjZUNoaWxkKG5ld0NoaWxkLG9sZENoaWxkKSIgbWV0aG9kIHJlcGxhY2VzIAorICogICAgIHRoZSBub2RlICJvbGRDaGlsZCIgd2l0aCB0aGUgbm9kZSAibmV3Q2hpbGQiLiAKKyAqICAgICAKKyAqICAgICBSZXBsYWNlIHRoZSBmaXJzdCBlbGVtZW50IG9mIHRoZSBzZWNvbmQgZW1wbG95ZWUgd2l0aAorICogICAgIGEgbmV3bHkgY3JlYXRlZCBFbGVtZW50IG5vZGUuICAgQ2hlY2sgdGhlIGZpcnN0IHBvc2l0aW9uCisgKiAgICAgYWZ0ZXIgdGhlIHJlcGxhY2VtZW50IG9wZXJhdGlvbiBpcyBjb21wbGV0ZWQuICAgVGhlIG5ldworICogICAgIEVsZW1lbnQgc2hvdWxkIGJlICJuZXdDaGlsZCIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZXJlcGxhY2VjaGlsZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXJlcGxhY2VjaGlsZChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIG9sZENoaWxkOworICAgICAgTm9kZSBuZXdDaGlsZDsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgTm9kZSByZXBsYWNlZE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjaGlsZExpc3QgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgb2xkQ2hpbGQgPSBjaGlsZExpc3QuaXRlbSgwKTsKKyAgICAgIG5ld0NoaWxkID0gZG9jLmNyZWF0ZUVsZW1lbnQoIm5ld0NoaWxkIik7CisgICAgICByZXBsYWNlZE5vZGUgPSBlbXBsb3llZU5vZGUucmVwbGFjZUNoaWxkKG5ld0NoaWxkLCBvbGRDaGlsZCk7CisgICAgICBjaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDApOworICAgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZVJlcGxhY2VDaGlsZEFzc2VydDEiLCAibmV3Q2hpbGQiLCBjaGlsZE5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlcmVwbGFjZWNoaWxkIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlcmVwbGFjZWNoaWxkLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcmVwbGFjZWNoaWxkaW52YWxpZG5vZGV0eXBlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVyZXBsYWNlY2hpbGRpbnZhbGlkbm9kZXR5cGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mN2JjNWE5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcmVwbGFjZWNoaWxkaW52YWxpZG5vZGV0eXBlLmphdmEKQEAgLTAsMCArMSwxMDcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZXBsYWNlQ2hpbGQobmV3Q2hpbGQsb2xkQ2hpbGQpIiBtZXRob2QgcmFpc2VzIGEgCisgKiAgICAgSElFUkFSQ0hZX1JFUVVFU1RfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGlzIG5vZGUgaXMgb2YKKyAqICAgICBhIHR5cGUgdGhhdCBkb2VzIG5vdCBhbGxvdyBjaGlsZHJlbiBvZiB0aGUgdHlwZSAibmV3Q2hpbGQiCisgKiAgICAgdG8gYmUgaW5zZXJ0ZWQuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHJvb3Qgbm9kZSBhbmQgYXR0ZW1wdCB0byByZXBsYWNlIAorICogICAgIG9uZSBvZiBpdHMgY2hpbGRyZW4gd2l0aCBhIG5ld2x5IGNyZWF0ZWQgQXR0ciBub2RlLgorICogICAgIEFuIEVsZW1lbnQgbm9kZSBjYW5ub3QgaGF2ZSBjaGlsZHJlbiBvZiB0aGUgIkF0dHIiCisgKiAgICAgdHlwZSwgdGhlcmVmb3JlIHRoZSBkZXNpcmVkIGV4Y2VwdGlvbiBzaG91bGQgYmUgcmFpc2VkLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNzg1ODg3MzA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSElFUkFSQ0hZX1JFUVVFU1RfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNzg1ODg3MzA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSElFUkFSQ0hZX1JFUVVFU1RfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVyZXBsYWNlY2hpbGRpbnZhbGlkbm9kZXR5cGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVyZXBsYWNlY2hpbGRpbnZhbGlkbm9kZXR5cGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IHJvb3ROb2RlOworICAgICAgTm9kZSBuZXdDaGlsZDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBvbGRDaGlsZDsKKyAgICAgIE5vZGUgcmVwbGFjZWRDaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIHJvb3ROb2RlID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgbmV3Q2hpbGQgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJuZXdBdHRyaWJ1dGUiKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgb2xkQ2hpbGQgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXBsYWNlZENoaWxkID0gcm9vdE5vZGUucmVwbGFjZUNoaWxkKG5ld0NoaWxkLCBvbGRDaGlsZCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19ISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZGludmFsaWRub2RldHlwZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXJlcGxhY2VjaGlsZGludmFsaWRub2RldHlwZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG5ld2NoaWxkZGlmZmRvY3VtZW50LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVyZXBsYWNlY2hpbGRuZXdjaGlsZGRpZmZkb2N1bWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk3YTg2MmEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVyZXBsYWNlY2hpbGRuZXdjaGlsZGRpZmZkb2N1bWVudC5qYXZhCkBAIC0wLDAgKzEsMTA5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlcGxhY2VDaGlsZChuZXdDaGlsZCxvbGRDaGlsZCkiIG1ldGhvZCByYWlzZXMgYSAKKyAqICAgICBXUk9OR19ET0NVTUVOVF9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSAibmV3Q2hpbGQiIHdhcworICogICAgIGNyZWF0ZWQgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudCB0aGFuIHRoZSBvbmUgdGhhdCAKKyAqICAgICBjcmVhdGVkIHRoaXMgbm9kZS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBhdHRlbXB0IHRvIHJlcGxhY2Ugb25lICAgCisgKiAgICAgb2YgaXRzIGNoaWxkcmVuIHdpdGggYSBub2RlIGNyZWF0ZWQgZnJvbSBhIGRpZmZlcmVudCAKKyAqICAgICBkb2N1bWVudC4gICBBbiBhdHRlbXB0IHRvIG1ha2Ugc3VjaCBhIHJlcGxhY2VtZW50IAorICogICAgIHNob3VsZCByYWlzZSB0aGUgZGVzaXJlZCBleGNlcHRpb24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9UX0ZPVU5EX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PVF9GT1VORF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTc4NTg4NzMwNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PVF9GT1VORF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC03ODU4ODczMDcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT1RfRk9VTkRfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlcmVwbGFjZWNoaWxkbmV3Y2hpbGRkaWZmZG9jdW1lbnQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVyZXBsYWNlY2hpbGRuZXdjaGlsZGRpZmZkb2N1bWVudChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2MxOworICAgICAgRG9jdW1lbnQgZG9jMjsKKyAgICAgIE5vZGUgb2xkQ2hpbGQ7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVsZW1lbnROb2RlOworICAgICAgTm9kZSByZXBsYWNlZENoaWxkOworICAgICAgZG9jMSA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2MyID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgbmV3Q2hpbGQgPSBkb2MxLmNyZWF0ZUVsZW1lbnQoIm5ld0NoaWxkIik7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYzIuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbGVtZW50Tm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBvbGRDaGlsZCA9IGVsZW1lbnROb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVwbGFjZWRDaGlsZCA9IGVsZW1lbnROb2RlLnJlcGxhY2VDaGlsZChuZXdDaGlsZCwgb2xkQ2hpbGQpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfV1JPTkdfRE9DVU1FTlRfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVyZXBsYWNlY2hpbGRuZXdjaGlsZGRpZmZkb2N1bWVudCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXJlcGxhY2VjaGlsZG5ld2NoaWxkZGlmZmRvY3VtZW50LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcmVwbGFjZWNoaWxkbmV3Y2hpbGRleGlzdHMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG5ld2NoaWxkZXhpc3RzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWFiNDViNQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG5ld2NoaWxkZXhpc3RzLmphdmEKQEAgLTAsMCArMSwxMzkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgUmV0cmlldmUgdGhlIHNlY29uZCBlbXBsb3llZSBhbmQgcmVwbGFjZSBpdHMgVFdFTEZUSCAKKyAqICAgICBjaGlsZChhZGRyZXNzKSB3aXRoIGl0cyBTRUNPTkQgY2hpbGQoZW1wbG95ZWVJZCkuICAgQWZ0ZXIgdGhlCisgKiAgICAgcmVwbGFjZW1lbnQgdGhlIHNlY29uZCBjaGlsZCBzaG91bGQgbm93IGJlIHRoZSBvbmUgdGhhdCB1c2VkICAgCisgKiAgICAgdG8gYmUgYXQgdGhlIHRoaXJkIHBvc2l0aW9uIGFuZCB0aGUgVFdFTEZUSCBjaGlsZCBzaG91bGQgYmUgdGhlCisgKiAgICAgb25lIHRoYXQgdXNlZCB0byBiZSBhdCB0aGUgU0VDT05EIHBvc2l0aW9uLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVyZXBsYWNlY2hpbGRuZXdjaGlsZGV4aXN0cyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXJlcGxhY2VjaGlsZG5ld2NoaWxkZXhpc3RzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgb2xkQ2hpbGQgPSBudWxsOworCisgICAgICBOb2RlIG5ld0NoaWxkID0gbnVsbDsKKworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIE5vZGUgY2hpbGROb2RlOworICAgICAgaW50IGxlbmd0aDsKKyAgICAgIGphdmEudXRpbC5MaXN0IGFjdHVhbCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5MaXN0IGV4cGVjdGVkID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkxpc3QgZXhwZWN0ZWRXaXRob3V0V2hpdGVzcGFjZSA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZFdpdGhvdXRXaGl0ZXNwYWNlLmFkZCgibmFtZSIpOworICAgICAgZXhwZWN0ZWRXaXRob3V0V2hpdGVzcGFjZS5hZGQoInBvc2l0aW9uIik7CisgICAgICBleHBlY3RlZFdpdGhvdXRXaGl0ZXNwYWNlLmFkZCgic2FsYXJ5Iik7CisgICAgICBleHBlY3RlZFdpdGhvdXRXaGl0ZXNwYWNlLmFkZCgiZ2VuZGVyIik7CisgICAgICBleHBlY3RlZFdpdGhvdXRXaGl0ZXNwYWNlLmFkZCgiZW1wbG95ZWVJZCIpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuTGlzdCBleHBlY3RlZFdpdGhXaGl0ZXNwYWNlID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGV4cGVjdGVkV2l0aFdoaXRlc3BhY2UuYWRkKCIjdGV4dCIpOworICAgICAgZXhwZWN0ZWRXaXRoV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICBleHBlY3RlZFdpdGhXaGl0ZXNwYWNlLmFkZCgibmFtZSIpOworICAgICAgZXhwZWN0ZWRXaXRoV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICBleHBlY3RlZFdpdGhXaGl0ZXNwYWNlLmFkZCgicG9zaXRpb24iKTsKKyAgICAgIGV4cGVjdGVkV2l0aFdoaXRlc3BhY2UuYWRkKCIjdGV4dCIpOworICAgICAgZXhwZWN0ZWRXaXRoV2hpdGVzcGFjZS5hZGQoInNhbGFyeSIpOworICAgICAgZXhwZWN0ZWRXaXRoV2hpdGVzcGFjZS5hZGQoIiN0ZXh0Iik7CisgICAgICBleHBlY3RlZFdpdGhXaGl0ZXNwYWNlLmFkZCgiZ2VuZGVyIik7CisgICAgICBleHBlY3RlZFdpdGhXaGl0ZXNwYWNlLmFkZCgiI3RleHQiKTsKKyAgICAgIGV4cGVjdGVkV2l0aFdoaXRlc3BhY2UuYWRkKCJlbXBsb3llZUlkIik7CisgICAgICBleHBlY3RlZFdpdGhXaGl0ZXNwYWNlLmFkZCgiI3RleHQiKTsKKyAgICAgIAorICAgICAgTm9kZSByZXBsYWNlZENoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgY2hpbGRMaXN0ID0gZW1wbG95ZWVOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGxlbmd0aCA9IChpbnQpIGNoaWxkTGlzdC5nZXRMZW5ndGgoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygxMywgbGVuZ3RoKSkgeworICAgICAgICAgIG5ld0NoaWxkID0gY2hpbGRMaXN0Lml0ZW0oMSk7CisgICAgICBvbGRDaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDExKTsKKyAgICAgIGV4cGVjdGVkID0gIGV4cGVjdGVkV2l0aFdoaXRlc3BhY2U7CisgICAgICB9IGVsc2UgeworICAgICAgICAgIG5ld0NoaWxkID0gY2hpbGRMaXN0Lml0ZW0oMCk7CisgICAgICBvbGRDaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDUpOworICAgICAgZXhwZWN0ZWQgPSAgZXhwZWN0ZWRXaXRob3V0V2hpdGVzcGFjZTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgcmVwbGFjZWRDaGlsZCA9IGVtcGxveWVlTm9kZS5yZXBsYWNlQ2hpbGQobmV3Q2hpbGQsIG9sZENoaWxkKTsKKyAgICAgIGFzc2VydFNhbWUoInJldHVybl92YWx1ZV9zYW1lIiwgb2xkQ2hpbGQsIHJlcGxhY2VkQ2hpbGQpOworZm9yIChpbnQgaW5kZXhOMTAwREUgPSAwOyBpbmRleE4xMDBERSA8IGNoaWxkTGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwREUrKykgeworICAgICAgICAgIGNoaWxkTm9kZSA9IChOb2RlKSBjaGlsZExpc3QuaXRlbShpbmRleE4xMDBERSk7CisgICAgY2hpbGROYW1lID0gY2hpbGROb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBhY3R1YWwuYWRkKGNoaWxkTmFtZSk7CisgICAgICAgIH0KKyAgICAgIGFzc2VydEVxdWFscygiY2hpbGROYW1lcyIsIGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlcmVwbGFjZWNoaWxkbmV3Y2hpbGRleGlzdHMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVyZXBsYWNlY2hpbGRuZXdjaGlsZGV4aXN0cy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG5vZGVhbmNlc3Rvci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcmVwbGFjZWNoaWxkbm9kZWFuY2VzdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDNiNjIwZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG5vZGVhbmNlc3Rvci5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAicmVwbGFjZUNoaWxkKG5ld0NoaWxkLG9sZENoaWxkKSIgbWV0aG9kIHJhaXNlcyBhIAorICogICAgIEhJRVJBUkNIWV9SRVFVRVNUX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIG5vZGUgdG8gcHV0CisgKiAgICAgaW4gaXMgb25lIG9mIHRoaXMgbm9kZSdzIGFuY2VzdG9ycy4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgc2Vjb25kIGVtcGxveWVlIGFuZCBhdHRlbXB0IHRvIHJlcGxhY2UKKyAqICAgICBvbmUgb2YgaXRzIGNoaWxkcmVuIHdpdGggYW4gYW5jZXN0b3Igbm9kZShyb290IG5vZGUpLgorICogICAgIEFuIGF0dGVtcHQgdG8gbWFrZSBzdWNoIGEgcmVwbGFjZW1lbnQgc2hvdWxkIHJhaXNlIHRoZSAKKyAqICAgICBkZXNpcmVkIGV4Y2VwdGlvbi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdISUVSQVJDSFlfUkVRVUVTVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTc4NTg4NzMwNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTc4NTg4NzMwNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjQ5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlcmVwbGFjZWNoaWxkbm9kZWFuY2VzdG9yIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlcmVwbGFjZWNoaWxkbm9kZWFuY2VzdG9yKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBuZXdDaGlsZDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIG9sZENoaWxkOworICAgICAgTm9kZSByZXBsYWNlZE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdDaGlsZCA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGNoaWxkTGlzdCA9IGVtcGxveWVlTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBvbGRDaGlsZCA9IGNoaWxkTGlzdC5pdGVtKDApOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXBsYWNlZE5vZGUgPSBlbXBsb3llZU5vZGUucmVwbGFjZUNoaWxkKG5ld0NoaWxkLCBvbGRDaGlsZCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19ISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG5vZGVhbmNlc3RvciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXJlcGxhY2VjaGlsZG5vZGVhbmNlc3Rvci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG5vZGVuYW1lLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVyZXBsYWNlY2hpbGRub2RlbmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdmMjk5MDcKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVyZXBsYWNlY2hpbGRub2RlbmFtZS5qYXZhCkBAIC0wLDAgKzEsMTA0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFJlcGxhY2UgdGhlIHNlY29uZCBFbGVtZW50IG9mIHRoZSBzZWNvbmQgZW1wbG95ZWUgd2l0aAorICogICAgIGEgbmV3bHkgY3JlYXRlZCBub2RlIEVsZW1lbnQgYW5kIGNoZWNrIHRoZSBOb2RlTmFtZSAKKyAqICAgICByZXR1cm5lZCBieSB0aGUgInJlcGxhY2VDaGlsZChuZXdDaGlsZCxvbGRDaGlsZCkiCisgKiAgICAgbWV0aG9kLiAgIFRoZSByZXR1cm5lZCBub2RlIHNob3VsZCBoYXZlIGEgTm9kZU5hbWUgZXF1YWwKKyAqICAgICB0byAiZW1wbG95ZWVJZCIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDk1PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlcmVwbGFjZWNoaWxkbm9kZW5hbWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVyZXBsYWNlY2hpbGRub2RlbmFtZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIG9sZENoaWxkOworICAgICAgTm9kZSBuZXdDaGlsZDsKKyAgICAgIE5vZGUgcmVwbGFjZWROb2RlOworICAgICAgaW50IGxlbmd0aDsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjaGlsZExpc3QgPSBlbXBsb3llZU5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgbGVuZ3RoID0gKGludCkgY2hpbGRMaXN0LmdldExlbmd0aCgpOworICAgICAgb2xkQ2hpbGQgPSBjaGlsZExpc3QuaXRlbSgxKTsKKyAgICAgIG5ld0NoaWxkID0gZG9jLmNyZWF0ZUVsZW1lbnQoIm5ld0NoaWxkIik7CisgICAgICByZXBsYWNlZE5vZGUgPSBlbXBsb3llZU5vZGUucmVwbGFjZUNoaWxkKG5ld0NoaWxkLCBvbGRDaGlsZCk7CisgICAgICBjaGlsZE5hbWUgPSByZXBsYWNlZE5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscyg2LCBsZW5ndGgpKSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJub3doaXRlc3BhY2UiLCAibmFtZSIsIGNoaWxkTmFtZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICAgIGFzc2VydEVxdWFscygid2hpdGVzcGFjZSIsICJlbXBsb3llZUlkIiwgY2hpbGROYW1lKTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RlcmVwbGFjZWNoaWxkbm9kZW5hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVyZXBsYWNlY2hpbGRub2RlbmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RlcmVwbGFjZWNoaWxkbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2IyOWUxOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCkBAIC0wLDAgKzEsMTE1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlcGxhY2VDaGlsZChuZXdDaGlsZCxvbGRDaGlsZCkiIG1ldGhvZCBjYXVzZXMgdGhlIAorICogICAgIERPTUV4Y2VwdGlvbiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgdG8gYmUgcmFpc2VkCisgKiAgICAgaWYgdGhlIG5vZGUgaXMgcmVhZG9ubHkuCisgKiAgICAgCisgKiAgICAgT2J0YWluIHRoZSBjaGlsZHJlbiBvZiB0aGUgVEhJUkQgImdlbmRlciIgZWxlbWVudC4gICBUaGUgZWxlbWVudHMKKyAqICAgICBjb250ZW50IGlzIGFuIGVudGl0eSByZWZlcmVuY2UuICAgR2V0IHRoZSBGSVJTVCBpdGVtIAorICogICAgIGZyb20gdGhlIGVudGl0eSByZWZlcmVuY2UgYW5kIGV4ZWN1dGUgdGhlICJyZXBsYWNlQ2hpbGQobmV3Q2hpbGQsb2xkQ2hpbGQpIiBtZXRob2QuCisgKiAgICAgVGhpcyBjYXVzZXMgYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgRE9NRXhjZXB0aW9uIHRvIGJlIHRocm93bi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNzg1ODg3MzA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNzg1ODg3MzA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlcmVwbGFjZWNoaWxkbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlcmVwbGFjZWNoaWxkbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyTm9kZTsKKyAgICAgIE5vZGUgZW50UmVmOworICAgICAgTm9kZSBlbnRFbGVtZW50OworICAgICAgTm9kZSBjcmVhdGVkTm9kZTsKKyAgICAgIE5vZGUgcmVwbGFjZWRDaGlsZDsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGdlbmRlckxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImdlbmRlciIpOworICAgICAgZ2VuZGVyTm9kZSA9IGdlbmRlckxpc3QuaXRlbSgyKTsKKyAgICAgIGVudFJlZiA9IGdlbmRlck5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgbm9kZVR5cGUgPSAoaW50KSBlbnRSZWYuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygxLCBub2RlVHlwZSkpIHsKKyAgICAgICAgICBlbnRSZWYgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQ0Iik7CisgICAgICBhc3NlcnROb3ROdWxsKCJjcmVhdGVkRW50UmVmTm90TnVsbCIsIGVudFJlZik7CisgICAgICB9CisgICAgZW50RWxlbWVudCA9IGVudFJlZi5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjcmVhdGVkTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50KCJuZXdDaGlsZCIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXBsYWNlZENoaWxkID0gZW50UmVmLnJlcGxhY2VDaGlsZChjcmVhdGVkTm9kZSwgZW50RWxlbWVudCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyciI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXJlcGxhY2VjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVyZXBsYWNlY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE2OGZkNzgKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVyZXBsYWNlY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhCkBAIC0wLDAgKzEsMTAyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlcGxhY2VDaGlsZChuZXdDaGlsZCxvbGRDaGlsZCkiIG1ldGhvZCBjYXVzZXMgdGhlIAorICogICAgIERPTUV4Y2VwdGlvbiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgdG8gYmUgcmFpc2VkCisgKiAgICAgaWYgdGhlIG5vZGUgaXMgcmVhZG9ubHkuCisgKiAgICAgCisgKiAgICAgQ3JlYXRlIGFuIGVudGl0eSByZWZlcmVuY2UgZXhlY3V0ZSB0aGUgInJlcGxhY2VDaGlsZChuZXdDaGlsZCxvbGRDaGlsZCkiIG1ldGhvZC4KKyAqICAgICBUaGlzIGNhdXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gdG8gYmUgdGhyb3duLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNzg1ODg3MzA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtNzg1ODg3MzA3JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWwiPmh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWw8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVyZXBsYWNlY2hpbGRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXJlcGxhY2VjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBlbnRSZWY7CisgICAgICBOb2RlIGVudFRleHQ7CisgICAgICBOb2RlIGNyZWF0ZWROb2RlOworICAgICAgTm9kZSByZXBsYWNlZENoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZW50UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworICAgICAgZW50VGV4dCA9IGVudFJlZi5nZXRGaXJzdENoaWxkKCk7CisgICAgICBjcmVhdGVkTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50KCJuZXdDaGlsZCIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXBsYWNlZENoaWxkID0gZW50UmVmLnJlcGxhY2VDaGlsZChjcmVhdGVkTm9kZSwgZW50VGV4dCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlcmVwbGFjZWNoaWxkbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVyZXBsYWNlY2hpbGRvbGRjaGlsZG5vbmV4aXN0ZW50LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVyZXBsYWNlY2hpbGRvbGRjaGlsZG5vbmV4aXN0ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmUxOWVhOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXJlcGxhY2VjaGlsZG9sZGNoaWxkbm9uZXhpc3RlbnQuamF2YQpAQCAtMCwwICsxLDEwNSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlcGxhY2VDaGlsZChuZXdDaGlsZCxvbGRDaGlsZCkiIG1ldGhvZCByYWlzZXMgYSAKKyAqICAgICBOT1RfRk9VTkRfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgb2xkIGNoaWxkIGlzCisgKiAgICAgbm90IGEgY2hpbGQgb2YgdGhpcyBub2RlLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgYW5kIGF0dGVtcHQgdG8gcmVwbGFjZSBhCisgKiAgICAgbm9kZSB0aGF0IGlzIG5vdCBvbmUgb2YgaXRzIGNoaWxkcmVuLiAgIEFuIGF0dGVtcHQgdG8KKyAqICAgICByZXBsYWNlIHN1Y2ggYSBub2RlIHNob3VsZCByYWlzZSB0aGUgZGVzaXJlZCBleGNlcHRpb24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9UX0ZPVU5EX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PVF9GT1VORF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC03ODU4ODczMDc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTc4NTg4NzMwNycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PVF9GT1VORF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC03ODU4ODczMDcnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT1RfRk9VTkRfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc4NTg4NzMwNyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzg1ODg3MzA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNDk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVyZXBsYWNlY2hpbGRvbGRjaGlsZG5vbmV4aXN0ZW50IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlcmVwbGFjZWNoaWxkb2xkY2hpbGRub25leGlzdGVudChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGUgb2xkQ2hpbGQ7CisgICAgICBOb2RlIG5ld0NoaWxkOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGVsZW1lbnROb2RlOworICAgICAgTm9kZSByZXBsYWNlZE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdDaGlsZCA9IGRvYy5jcmVhdGVFbGVtZW50KCJuZXdDaGlsZCIpOworICAgICAgb2xkQ2hpbGQgPSBkb2MuY3JlYXRlRWxlbWVudCgib2xkQ2hpbGQiKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZWxlbWVudE5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXBsYWNlZE5vZGUgPSBlbGVtZW50Tm9kZS5yZXBsYWNlQ2hpbGQobmV3Q2hpbGQsIG9sZENoaWxkKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT1RfRk9VTkRfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVyZXBsYWNlY2hpbGRvbGRjaGlsZG5vbmV4aXN0ZW50IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlcmVwbGFjZWNoaWxkb2xkY2hpbGRub25leGlzdGVudC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXNldG5vZGV2YWx1ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2Rlc2V0bm9kZXZhbHVlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWEwODg1MwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXNldG5vZGV2YWx1ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCkBAIC0wLDAgKzEsMTE3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldE5vZGVWYWx1ZShub2RlVmFsdWUpIiBtZXRob2QgY2F1c2VzIHRoZSAKKyAqICAgICBET01FeGNlcHRpb24gTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIHRvIGJlIHJhaXNlZAorICogICAgIGlmIHRoZSBub2RlIGlzIHJlYWRvbmx5LgorICogICAgIAorICogICAgIE9idGFpbiB0aGUgY2hpbGRyZW4gb2YgdGhlIFRISVJEICJnZW5kZXIiIGVsZW1lbnQuICAgVGhlIGVsZW1lbnRzCisgKiAgICAgY29udGVudCBpcyBhbiBlbnRpdHkgcmVmZXJlbmNlLiAgIEdldCB0aGUgU0VDT05EIGl0ZW0gCisgKiAgICAgZnJvbSB0aGUgZW50aXR5IHJlZmVyZW5jZSBhbmQgZXhlY3V0ZSB0aGUgInNldE5vZGVWYWx1ZShub2RlVmFsdWUpIiBtZXRob2QuCisgKiAgICAgVGhpcyBjYXVzZXMgYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgRE9NRXhjZXB0aW9uIHRvIGJlIHRocm93bi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC1GNjhEMDgwJykvc2V0cmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtRjY4RDA4MCcpL3NldHJhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2Rlc2V0bm9kZXZhbHVlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2Rlc2V0bm9kZXZhbHVlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyTm9kZTsKKyAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWY7CisgICAgICBFbGVtZW50IGVudEVsZW1lbnQ7CisgICAgICBDaGFyYWN0ZXJEYXRhIGVudEVsZW1lbnRUZXh0OworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZ2VuZGVyTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZ2VuZGVyIik7CisgICAgICBnZW5kZXJOb2RlID0gZ2VuZGVyTGlzdC5pdGVtKDIpOworICAgICAgZW50UmVmID0gKEVudGl0eVJlZmVyZW5jZSkgZ2VuZGVyTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRSZWZOb3ROdWxsIiwgZW50UmVmKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgZW50UmVmLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoMSwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgZW50UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworICAgICAgfQorICAgIGVudEVsZW1lbnQgPSAoRWxlbWVudCkgZW50UmVmLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudEVsZW1lbnROb3ROdWxsIiwgZW50RWxlbWVudCk7CisgICAgICBlbnRFbGVtZW50VGV4dCA9IChDaGFyYWN0ZXJEYXRhKSBlbnRFbGVtZW50LmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudEVsZW1lbnRUZXh0Tm90TnVsbCIsIGVudEVsZW1lbnRUZXh0KTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgZW50RWxlbWVudFRleHQuc2V0Tm9kZVZhbHVlKCJuZXdWYWx1ZSIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVzZXRub2RldmFsdWVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVzZXRub2RldmFsdWVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGVzZXRub2RldmFsdWVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2Rlc2V0bm9kZXZhbHVlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNzJkYTQ5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2Rlc2V0bm9kZXZhbHVlbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIENyZWF0ZSBhbiBlbnRpdHkgcmVmZXJlbmNlIGFuZCBleGVjdXRlIHRoZSAic2V0Tm9kZVZhbHVlKG5vZGVWYWx1ZSkiIG1ldGhvZC4KKyAqICAgICBUaGlzIGNhdXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gdG8gYmUgdGhyb3duLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC1GNjhEMDgwJykvc2V0cmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtRjY4RDA4MCcpL3NldHJhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXNldG5vZGV2YWx1ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWwiPmh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXNldG5vZGV2YWx1ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci54bWw8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVzZXRub2RldmFsdWVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXNldG5vZGV2YWx1ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRW50aXR5UmVmZXJlbmNlIGVudFJlZjsKKyAgICAgIENoYXJhY3RlckRhdGEgZW50VGV4dDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVudFJlZiA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDMiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZW50UmVmKTsKKyAgICAgIGVudFRleHQgPSAoQ2hhcmFjdGVyRGF0YSkgZW50UmVmLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudFRleHROb3ROdWxsIiwgZW50VGV4dCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVudFRleHQuc2V0Tm9kZVZhbHVlKCJuZXdWYWx1ZSIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGVzZXRub2RldmFsdWVub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXNldG5vZGV2YWx1ZW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldGV4dG5vZGVhdHRyaWJ1dGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXRleHRub2RlYXR0cmlidXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWE0YzVkZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXRleHRub2RlYXR0cmlidXRlLmphdmEKQEAgLTAsMCArMSw5MCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBUaGUgImdldEF0dHJpYnV0ZXMoKSIgbWV0aG9kIGludm9rZWQgb24gYSBUZXh0CisgKiBOb2RlIHJldHVybnMgbnVsbC4KKyAqIFJldHJpZXZlIHRoZSBUZXh0IG5vZGUgZnJvbSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUKKyAqIGZpcnN0IGVtcGxveWVlIGFuZCBpbnZva2UgdGhlICJnZXRBdHRyaWJ1dGVzKCkiIG1ldGhvZAorICogb24gdGhlIFRleHQgTm9kZS4gIEl0IHNob3VsZCByZXR1cm4gbnVsbC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTYiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTg0Q0YwOTY8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTMxMjI5NTc3MiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTMxMjI5NTc3MjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZXRleHRub2RlYXR0cmlidXRlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RldGV4dG5vZGVhdHRyaWJ1dGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RBZGRyOworICAgICAgTm9kZSB0ZXh0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyTGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEFkZHIgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgdGV4dE5vZGUgPSB0ZXN0QWRkci5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhdHRyTGlzdCA9IHRleHROb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGFzc2VydE51bGwoIm5vZGVUZXh0Tm9kZUF0dHJpYnV0ZXNBc3NlcnQxIiwgYXR0ckxpc3QpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RldGV4dG5vZGVhdHRyaWJ1dGUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGV0ZXh0bm9kZWF0dHJpYnV0ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXRleHRub2RlbmFtZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldGV4dG5vZGVuYW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTg4ZjAzZAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXRleHRub2RlbmFtZS5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlTmFtZSgpIiBtZXRob2QgZm9yIGEgCisgKiAgICAgVGV4dCBOb2RlIGlzICIjdGV4dCIuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIFRleHQgTm9kZSBmcm9tIHRoZSBsYXN0IGNoaWxkIG9mIHRoZQorICogICAgIGZpcnN0IGVtcGxveWVlIGFuZCBjaGVjayB0aGUgc3RyaW5nIHJldHVybmVkIAorICogICAgIGJ5IHRoZSAiZ2V0Tm9kZU5hbWUoKSIgbWV0aG9kLiAgIEl0IHNob3VsZCBiZSBlcXVhbCB0byAKKyAqICAgICAiI3RleHQiLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwOTU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGV0ZXh0bm9kZW5hbWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGV0ZXh0bm9kZW5hbWUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RBZGRyOworICAgICAgTm9kZSB0ZXh0Tm9kZTsKKyAgICAgIFN0cmluZyB0ZXh0TmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEFkZHIgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIHRleHROb2RlID0gdGVzdEFkZHIuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgdGV4dE5hbWUgPSB0ZXh0Tm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlVGV4dE5vZGVOYW1lQXNzZXJ0MSIsICIjdGV4dCIsIHRleHROYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXRleHRub2RlbmFtZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXRleHRub2RlbmFtZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXRleHRub2RldHlwZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldGV4dG5vZGV0eXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTc4ZDlhZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXRleHRub2RldHlwZS5qYXZhCkBAIC0wLDAgKzEsOTAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0Tm9kZVR5cGUoKSIgbWV0aG9kIGZvciBhIFRleHQgTm9kZQorICogICAgIHJldHVybnMgdGhlIGNvbnN0YW50IHZhbHVlIDMuCisgKiAgICAgIAorICogICAgIFJldHJpZXZlIHRoZSBUZXh0IG5vZGUgZnJvbSB0aGUgbGFzdCBjaGlsZCBvZgorICogICAgIHRoZSBmaXJzdCBlbXBsb3llZSBhbmQgaW52b2tlIHRoZSAiZ2V0Tm9kZVR5cGUoKSIgICAKKyAqICAgICBtZXRob2QuICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIDMuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTExMjM3NTU4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMTEyMzc1NTg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGV0ZXh0bm9kZXR5cGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGV0ZXh0bm9kZXR5cGUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RBZGRyOworICAgICAgTm9kZSB0ZXh0Tm9kZTsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEFkZHIgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIHRleHROb2RlID0gdGVzdEFkZHIuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgbm9kZVR5cGUgPSAoaW50KSB0ZXh0Tm9kZS5nZXROb2RlVHlwZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlVGV4dE5vZGVUeXBlQXNzZXJ0MSIsIDMsIG5vZGVUeXBlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXRleHRub2RldHlwZSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXRleHRub2RldHlwZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXRleHRub2RldmFsdWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXRleHRub2RldmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MWJjZGQ4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldGV4dG5vZGV2YWx1ZS5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlICJnZXROb2RlVmFsdWUoKSIgbWV0aG9kIGZvciBhIAorICogICAgIFRleHQgTm9kZSBpcyB0aGUgY29udGVudCBvZiB0aGUgVGV4dCBub2RlLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBUZXh0IG5vZGUgZnJvbSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgZmlyc3QgCisgKiAgICAgZW1wbG95ZWUgYW5kIGNoZWNrIHRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlIAorICogICAgICJnZXROb2RlVmFsdWUoKSIgbWV0aG9kLiAgIEl0IHNob3VsZCBiZSBlcXVhbCB0byAKKyAqICAgICAiMTIzMCBOb3J0aCBBdmUuIERhbGxhcywgVGV4YXMgOTg1NTEiLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODA8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGV0ZXh0bm9kZXZhbHVlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RldGV4dG5vZGV2YWx1ZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdEFkZHI7CisgICAgICBOb2RlIHRleHROb2RlOworICAgICAgU3RyaW5nIHRleHRWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEFkZHIgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIHRleHROb2RlID0gdGVzdEFkZHIuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgdGV4dFZhbHVlID0gdGV4dE5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVUZXh0Tm9kZVZhbHVlQXNzZXJ0MSIsICIxMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyA5ODU1MSIsIHRleHRWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGV0ZXh0bm9kZXZhbHVlIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RldGV4dG5vZGV2YWx1ZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXZhbHVlMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXZhbHVlMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZTRkOGIyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldmFsdWUwMS5qYXZhCkBAIC0wLDAgKzEsODUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQW4gZWxlbWVudCBpcyBjcmVhdGVkLCBzZXROb2RlVmFsdWUgaXMgY2FsbGVkIHdpdGggYSBub24tbnVsbCBhcmd1bWVudCwgYnV0IGdldE5vZGVWYWx1ZQorICogc2hvdWxkIHN0aWxsIHJldHVybiBudWxsLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNpLURvY3VtZW50Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNpLURvY3VtZW50PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RldmFsdWUwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXZhbHVlMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IG5ld05vZGU7CisgICAgICBTdHJpbmcgbmV3VmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdOb2RlID0gZG9jLmNyZWF0ZUVsZW1lbnQoImFkZHJlc3MiKTsKKyAgICAgIG5ld1ZhbHVlID0gbmV3Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydE51bGwoImluaXRpYWxseU51bGwiLCBuZXdWYWx1ZSk7CisgICAgICBuZXdOb2RlLnNldE5vZGVWYWx1ZSgiVGhpcyBzaG91bGQgaGF2ZSBubyBlZmZlY3QiKTsKKyAgICAgIG5ld1ZhbHVlID0gbmV3Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydE51bGwoIm51bGxBZnRlckF0dGVtcHRlZENoYW5nZSIsIG5ld1ZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXZhbHVlMDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGV2YWx1ZTAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldmFsdWUwMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldmFsdWUwMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM1NDFmNmUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGV2YWx1ZTAyLmphdmEKQEAgLTAsMCArMSw4NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBbiBjb21tZW50IGlzIGNyZWF0ZWQsIHNldE5vZGVWYWx1ZSBpcyBjYWxsZWQgd2l0aCBhIG5vbi1udWxsIGFyZ3VtZW50LCBidXQgZ2V0Tm9kZVZhbHVlCisgKiBzaG91bGQgc3RpbGwgcmV0dXJuIG51bGwuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MjgyNzkzMjIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE3MjgyNzkzMjI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGV2YWx1ZTAyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RldmFsdWUwMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGUgbmV3Tm9kZTsKKyAgICAgIFN0cmluZyBuZXdWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld05vZGUgPSBkb2MuY3JlYXRlQ29tbWVudCgiVGhpcyBpcyBhIG5ldyBDb21tZW50IG5vZGUiKTsKKyAgICAgIG5ld1ZhbHVlID0gbmV3Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiaW5pdGlhbCIsICJUaGlzIGlzIGEgbmV3IENvbW1lbnQgbm9kZSIsIG5ld1ZhbHVlKTsKKyAgICAgIG5ld05vZGUuc2V0Tm9kZVZhbHVlKCJUaGlzIHNob3VsZCBoYXZlIGFuIGVmZmVjdCIpOworICAgICAgbmV3VmFsdWUgPSBuZXdOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhZnRlckNoYW5nZSIsICJUaGlzIHNob3VsZCBoYXZlIGFuIGVmZmVjdCIsIG5ld1ZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXZhbHVlMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGV2YWx1ZTAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldmFsdWUwMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldmFsdWUwMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI4MWQwZWYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGV2YWx1ZTAzLmphdmEKQEAgLTAsMCArMSw4NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEFuIGVudGl0eSByZWZlcmVuY2UgaXMgY3JlYXRlZCwgc2V0Tm9kZVZhbHVlIGlzIGNhbGxlZCB3aXRoIGEgbm9uLW51bGwgYXJndW1lbnQsIGJ1dCBnZXROb2RlVmFsdWUKKyAqIHNob3VsZCBzdGlsbCByZXR1cm4gbnVsbC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODA8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTFDOTg0OTAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExQzk4NDkwPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RldmFsdWUwMyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXZhbHVlMDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIG5ld05vZGU7CisgICAgICBTdHJpbmcgbmV3VmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdOb2RlID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50MSIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBuZXdOb2RlKTsKKyAgICAgIG5ld1ZhbHVlID0gbmV3Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydE51bGwoImluaXRpYWxseU51bGwiLCBuZXdWYWx1ZSk7CisgICAgICBuZXdOb2RlLnNldE5vZGVWYWx1ZSgiVGhpcyBzaG91bGQgaGF2ZSBubyBlZmZlY3QiKTsKKyAgICAgIG5ld1ZhbHVlID0gbmV3Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydE51bGwoIm51bGxBZnRlckF0dGVtcHRlZENoYW5nZSIsIG5ld1ZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXZhbHVlMDMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGV2YWx1ZTAzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldmFsdWUwNC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldmFsdWUwNC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjMmNhY2YKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGV2YWx1ZTA0LmphdmEKQEAgLTAsMCArMSw4NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEFuIGRvY3VtZW50IHR5cGUgYWNjZXNzZWQsIHNldE5vZGVWYWx1ZSBpcyBjYWxsZWQgd2l0aCBhIG5vbi1udWxsIGFyZ3VtZW50LCBidXQgZ2V0Tm9kZVZhbHVlCisgKiBzaG91bGQgc3RpbGwgcmV0dXJuIG51bGwuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUI2M0VEMUEzMSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtQjYzRUQxQTMxPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RldmFsdWUwNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXZhbHVlMDQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIG5ld05vZGU7CisgICAgICBTdHJpbmcgbmV3VmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdOb2RlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImRvY1R5cGVOb3ROdWxsIiwgbmV3Tm9kZSk7CisgICAgICBuZXdWYWx1ZSA9IG5ld05vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJpbml0aWFsbHlOdWxsIiwgbmV3VmFsdWUpOworICAgICAgbmV3Tm9kZS5zZXROb2RlVmFsdWUoIlRoaXMgc2hvdWxkIGhhdmUgbm8gZWZmZWN0Iik7CisgICAgICBuZXdWYWx1ZSA9IG5ld05vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJudWxsQWZ0ZXJBdHRlbXB0ZWRDaGFuZ2UiLCBuZXdWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGV2YWx1ZTA0IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RldmFsdWUwNC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXZhbHVlMDUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXZhbHVlMDUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NTk0YjRjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldmFsdWUwNS5qYXZhCkBAIC0wLDAgKzEsODUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQSBkb2N1bWVudCBmcmFnbWVudCBpcyBjcmVhdGVkLCBzZXROb2RlVmFsdWUgaXMgY2FsbGVkIHdpdGggYSBub24tbnVsbCBhcmd1bWVudCwgYnV0IGdldE5vZGVWYWx1ZQorICogc2hvdWxkIHN0aWxsIHJldHVybiBudWxsLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1CNjNFRDFBMyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtQjYzRUQxQTM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGV2YWx1ZTA1IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RldmFsdWUwNShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGUgbmV3Tm9kZTsKKyAgICAgIFN0cmluZyBuZXdWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld05vZGUgPSBkb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOworICAgICAgbmV3VmFsdWUgPSBuZXdOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgiaW5pdGlhbGx5TnVsbCIsIG5ld1ZhbHVlKTsKKyAgICAgIG5ld05vZGUuc2V0Tm9kZVZhbHVlKCJUaGlzIHNob3VsZCBoYXZlIG5vIGVmZmVjdCIpOworICAgICAgbmV3VmFsdWUgPSBuZXdOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgibnVsbEFmdGVyQXR0ZW1wdGVkQ2hhbmdlIiwgbmV3VmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RldmFsdWUwNSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXZhbHVlMDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGV2YWx1ZTA2LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGV2YWx1ZTA2LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODI0ZjhmNAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXZhbHVlMDYuamF2YQpAQCAtMCwwICsxLDgzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEFuIGRvY3VtZW50IGlzIGFjY2Vzc2VkLCBzZXROb2RlVmFsdWUgaXMgY2FsbGVkIHdpdGggYSBub24tbnVsbCBhcmd1bWVudCwgYnV0IGdldE5vZGVWYWx1ZQorICogc2hvdWxkIHN0aWxsIHJldHVybiBudWxsLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNpLURvY3VtZW50Ij5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNpLURvY3VtZW50PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RldmFsdWUwNiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXZhbHVlMDYoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBuZXdOb2RlOworICAgICAgU3RyaW5nIG5ld1ZhbHVlOworICAgICAgbmV3Tm9kZSA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIG5ld1ZhbHVlID0gbmV3Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydE51bGwoImluaXRpYWxseU51bGwiLCBuZXdWYWx1ZSk7CisgICAgICBuZXdOb2RlLnNldE5vZGVWYWx1ZSgiVGhpcyBzaG91bGQgaGF2ZSBubyBlZmZlY3QiKTsKKyAgICAgIG5ld1ZhbHVlID0gbmV3Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydE51bGwoIm51bGxBZnRlckF0dGVtcHRlZENoYW5nZSIsIG5ld1ZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm9kZXZhbHVlMDYiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGV2YWx1ZTA2LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldmFsdWUwNy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldmFsdWUwNy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYwN2JkMzUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vZGV2YWx1ZTA3LmphdmEKQEAgLTAsMCArMSw5MiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEFuIEVudGl0eSBpcyBhY2Nlc3NlZCwgc2V0Tm9kZVZhbHVlIGlzIGNhbGxlZCB3aXRoIGEgbm9uLW51bGwgYXJndW1lbnQsIGJ1dCBnZXROb2RlVmFsdWUKKyAqIHNob3VsZCBzdGlsbCByZXR1cm4gbnVsbC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODA8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNTI3RENGRjIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTUyN0RDRkYyPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RldmFsdWUwNyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXZhbHVlMDcoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIG5ld05vZGU7CisgICAgICBTdHJpbmcgbmV3VmFsdWU7CisgICAgICBOYW1lZE5vZGVNYXAgbm9kZU1hcDsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgbm9kZU1hcCA9IGRvY1R5cGUuZ2V0RW50aXRpZXMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudGl0aWVzTm90TnVsbCIsIG5vZGVNYXApOworICAgICAgbmV3Tm9kZSA9IG5vZGVNYXAuZ2V0TmFtZWRJdGVtKCJlbnQxIik7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdHlOb3ROdWxsIiwgbmV3Tm9kZSk7CisgICAgICBuZXdWYWx1ZSA9IG5ld05vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJpbml0aWFsbHlOdWxsIiwgbmV3VmFsdWUpOworICAgICAgbmV3Tm9kZS5zZXROb2RlVmFsdWUoIlRoaXMgc2hvdWxkIGhhdmUgbm8gZWZmZWN0Iik7CisgICAgICBuZXdWYWx1ZSA9IG5ld05vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJudWxsQWZ0ZXJBdHRlbXB0ZWRDaGFuZ2UiLCBuZXdWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGV2YWx1ZTA3IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RldmFsdWUwNy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXZhbHVlMDguamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXZhbHVlMDguamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZGVhOWVlCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldmFsdWUwOC5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBbiBub3RhdGlvbiBpcyBhY2Nlc3NlZCwgc2V0Tm9kZVZhbHVlIGlzIGNhbGxlZCB3aXRoIGEgbm9uLW51bGwgYXJndW1lbnQsIGJ1dCBnZXROb2RlVmFsdWUKKyAqIHNob3VsZCBzdGlsbCByZXR1cm4gbnVsbC4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUY2OEQwODA8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNTQzMUQxQjkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTU0MzFEMUI5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RldmFsdWUwOCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXZhbHVlMDgoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIE5vZGUgbmV3Tm9kZTsKKyAgICAgIFN0cmluZyBuZXdWYWx1ZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBub2RlTWFwOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgbm9kZU1hcCA9IGRvY1R5cGUuZ2V0Tm90YXRpb25zKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJub3RhdGlvbnNOb3ROdWxsIiwgbm9kZU1hcCk7CisgICAgICBuZXdOb2RlID0gbm9kZU1hcC5nZXROYW1lZEl0ZW0oIm5vdGF0aW9uMSIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgibm90YXRpb25Ob3ROdWxsIiwgbmV3Tm9kZSk7CisgICAgICBuZXdWYWx1ZSA9IG5ld05vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJpbml0aWFsbHlOdWxsIiwgbmV3VmFsdWUpOworICAgICAgbmV3Tm9kZS5zZXROb2RlVmFsdWUoIlRoaXMgc2hvdWxkIGhhdmUgbm8gZWZmZWN0Iik7CisgICAgICBuZXdWYWx1ZSA9IG5ld05vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROdWxsKCJudWxsQWZ0ZXJBdHRlbXB0ZWRDaGFuZ2UiLCBuZXdWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vZGV2YWx1ZTA4IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RldmFsdWUwOC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXZhbHVlMDkuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm9kZXZhbHVlMDkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MzJlN2YwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub2RldmFsdWUwOS5qYXZhCkBAIC0wLDAgKzEsODUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQW4gcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBpcyBjcmVhdGVkLCBzZXROb2RlVmFsdWUgaXMgY2FsbGVkIHdpdGggYSBub24tbnVsbCBhcmd1bWVudCwgYnV0IGdldE5vZGVWYWx1ZQorICogc2hvdWxkIHN0aWxsIHJldHVybiBudWxsLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA4MDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDA0MjE1ODEzIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0xMDA0MjE1ODEzPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RldmFsdWUwOSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXZhbHVlMDkoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIG5ld05vZGU7CisgICAgICBTdHJpbmcgbmV3VmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBuZXdOb2RlID0gZG9jLmNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbigiVEFSR0VUIiwgIkRBVEEiKTsKKyAgICAgIG5ld1ZhbHVlID0gbmV3Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiaW5pdGlhbCIsICJEQVRBIiwgbmV3VmFsdWUpOworICAgICAgbmV3Tm9kZS5zZXROb2RlVmFsdWUoIlRoaXMgc2hvdWxkIGhhdmUgYW4gZWZmZWN0Iik7CisgICAgICBuZXdWYWx1ZSA9IG5ld05vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImFmdGVyIiwgIlRoaXMgc2hvdWxkIGhhdmUgYW4gZWZmZWN0IiwgbmV3VmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub2RldmFsdWUwOSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXZhbHVlMDkuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vdGF0aW9uZ2V0bm90YXRpb25uYW1lLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vdGF0aW9uZ2V0bm90YXRpb25uYW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGJjMTEyOAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm90YXRpb25nZXRub3RhdGlvbm5hbWUuamF2YQpAQCAtMCwwICsxLDkwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgUmV0cmlldmUgdGhlIG5vdGF0aW9uIG5hbWVkICJub3RhdGlvbjEiIGFuZCBhY2Nlc3MgaXRzIAorICogICAgbmFtZSBieSBpbnZva2luZyB0aGUgImdldE5vZGVOYW1lKCkiIG1ldGhvZCBpbmhlcml0ZWQKKyAqICAgIGZyb20gdGhlIE5vZGUgaW50ZXJmYWNlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRjY4RDA5NTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC01NDMxRDFCOSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNTQzMUQxQjk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vdGF0aW9uZ2V0bm90YXRpb25uYW1lIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub3RhdGlvbmdldG5vdGF0aW9ubmFtZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBub3RhdGlvbnM7CisgICAgICBOb3RhdGlvbiBub3RhdGlvbk5vZGU7CisgICAgICBTdHJpbmcgbm90YXRpb25OYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZG9jVHlwZU5vdE51bGwiLCBkb2NUeXBlKTsKKyAgICAgIG5vdGF0aW9ucyA9IGRvY1R5cGUuZ2V0Tm90YXRpb25zKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJub3RhdGlvbnNOb3ROdWxsIiwgbm90YXRpb25zKTsKKyAgICAgIG5vdGF0aW9uTm9kZSA9IChOb3RhdGlvbikgbm90YXRpb25zLmdldE5hbWVkSXRlbSgibm90YXRpb24xIik7CisgICAgICBub3RhdGlvbk5hbWUgPSBub3RhdGlvbk5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm90YXRpb25HZXROb3RhdGlvbk5hbWVBc3NlcnQiLCAibm90YXRpb24xIiwgbm90YXRpb25OYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm90YXRpb25nZXRub3RhdGlvbm5hbWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vdGF0aW9uZ2V0bm90YXRpb25uYW1lLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub3RhdGlvbmdldHB1YmxpY2lkLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vdGF0aW9uZ2V0cHVibGljaWQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZTE1OThkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub3RhdGlvbmdldHB1YmxpY2lkLmphdmEKQEAgLTAsMCArMSw4OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgIFJldHJpZXZlIHRoZSBub3RhdGlvbiBuYW1lZCAibm90YXRpb24xIiBhbmQgYWNjZXNzIGl0cyAgCisgKiAgICBwdWJsaWMgaWRlbnRpZmllci4gIFRoZSBzdHJpbmcgIm5vdGF0aW9uMUZpbGUiIHNob3VsZCBiZQorICogICAgcmV0dXJuZWQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC01NEYyQjREMCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNTRGMkI0RDA8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vdGF0aW9uZ2V0cHVibGljaWQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vdGF0aW9uZ2V0cHVibGljaWQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBOYW1lZE5vZGVNYXAgbm90YXRpb25zOworICAgICAgTm90YXRpb24gbm90YXRpb25Ob2RlOworICAgICAgU3RyaW5nIHB1YmxpY0lkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZG9jVHlwZU5vdE51bGwiLCBkb2NUeXBlKTsKKyAgICAgIG5vdGF0aW9ucyA9IGRvY1R5cGUuZ2V0Tm90YXRpb25zKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJub3RhdGlvbnNOb3ROdWxsIiwgbm90YXRpb25zKTsKKyAgICAgIG5vdGF0aW9uTm9kZSA9IChOb3RhdGlvbikgbm90YXRpb25zLmdldE5hbWVkSXRlbSgibm90YXRpb24xIik7CisgICAgICBwdWJsaWNJZCA9IG5vdGF0aW9uTm9kZS5nZXRQdWJsaWNJZCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJwdWJsaWNJZCIsICJub3RhdGlvbjFGaWxlIiwgcHVibGljSWQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9ub3RhdGlvbmdldHB1YmxpY2lkIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub3RhdGlvbmdldHB1YmxpY2lkLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub3RhdGlvbmdldHB1YmxpY2lkbnVsbC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub3RhdGlvbmdldHB1YmxpY2lkbnVsbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI4YmNlNDUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vdGF0aW9uZ2V0cHVibGljaWRudWxsLmphdmEKQEAgLTAsMCArMSw5NCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldFB1YmxpY0lkKCkiIG1ldGhvZCBvZiBhIE5vdGF0aW9uIG5vZGUgY29udGFpbnMKKyAqICAgIHRoZSBwdWJsaWMgaWRlbnRpZmllciBhc3NvY2lhdGVkIHdpdGggdGhlIG5vdGF0aW9uLCBpZgorICogICAgb25lIHdhcyBub3Qgc3BlY2lmaWVkIGEgbnVsbCB2YWx1ZSBzaG91bGQgYmUgcmV0dXJuZWQuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBub3RhdGlvbiBuYW1lZCAibm90YXRpb24yIiBhbmQgYWNjZXNzIGl0cyAgCisgKiAgICBwdWJsaWMgaWRlbnRpZmllci4gIFNpbmNlIGEgcHVibGljIGlkZW50aWZpZXIgd2FzIG5vdAorICogICAgc3BlY2lmaWVkIGZvciB0aGlzIG5vdGF0aW9uLCB0aGUgImdldFB1YmxpY0lkKCkiIG1ldGhvZAorICogICAgc2hvdWxkIHJldHVybiBudWxsLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNTRGMkI0RDAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTU0RjJCNEQwPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub3RhdGlvbmdldHB1YmxpY2lkbnVsbCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm90YXRpb25nZXRwdWJsaWNpZG51bGwoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBOYW1lZE5vZGVNYXAgbm90YXRpb25zOworICAgICAgTm90YXRpb24gbm90YXRpb25Ob2RlOworICAgICAgU3RyaW5nIHB1YmxpY0lkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZG9jVHlwZU5vdE51bGwiLCBkb2NUeXBlKTsKKyAgICAgIG5vdGF0aW9ucyA9IGRvY1R5cGUuZ2V0Tm90YXRpb25zKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJub3RhdGlvbnNOb3ROdWxsIiwgbm90YXRpb25zKTsKKyAgICAgIG5vdGF0aW9uTm9kZSA9IChOb3RhdGlvbikgbm90YXRpb25zLmdldE5hbWVkSXRlbSgibm90YXRpb24yIik7CisgICAgICBwdWJsaWNJZCA9IG5vdGF0aW9uTm9kZS5nZXRQdWJsaWNJZCgpOworICAgICAgYXNzZXJ0TnVsbCgicHVibGljSWQiLCBwdWJsaWNJZCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vdGF0aW9uZ2V0cHVibGljaWRudWxsIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub3RhdGlvbmdldHB1YmxpY2lkbnVsbC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm90YXRpb25nZXRzeXN0ZW1pZC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9ub3RhdGlvbmdldHN5c3RlbWlkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGNlN2ZjYQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm90YXRpb25nZXRzeXN0ZW1pZC5qYXZhCkBAIC0wLDAgKzEsOTQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRTeXN0ZW1JZCgpIiBtZXRob2Qgb2YgYSBOb3RhdGlvbiBub2RlIGNvbnRhaW5zCisgKiAgICB0aGUgc3lzdGVtIGlkZW50aWZpZXIgYXNzb2NpYXRlZCB3aXRoIHRoZSBub3RhdGlvbiwgaWYKKyAqICAgIG9uZSB3YXMgc3BlY2lmaWVkLgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgbm90YXRpb24gbmFtZWQgIm5vdGF0aW9uMiIgYW5kIGFjY2VzcyBpdHMgIAorICogICAgc3lzdGVtIGlkZW50aWZpZXIuICBUaGUgc3RyaW5nICJub3RhdGlvbjJGaWxlIiBzaG91bGQgYmUKKyAqICAgIHJldHVybmVkLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRThBQUIxRDAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELUU4QUFCMUQwPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub3RhdGlvbmdldHN5c3RlbWlkIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub3RhdGlvbmdldHN5c3RlbWlkKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTmFtZWROb2RlTWFwIG5vdGF0aW9uczsKKyAgICAgIE5vdGF0aW9uIG5vdGF0aW9uTm9kZTsKKyAgICAgIFN0cmluZyBzeXN0ZW1JZDsKKyAgICAgIGludCBpbmRleDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImRvY1R5cGVOb3ROdWxsIiwgZG9jVHlwZSk7CisgICAgICBub3RhdGlvbnMgPSBkb2NUeXBlLmdldE5vdGF0aW9ucygpOworICAgICAgYXNzZXJ0Tm90TnVsbCgibm90YXRpb25zTm90TnVsbCIsIG5vdGF0aW9ucyk7CisgICAgICBub3RhdGlvbk5vZGUgPSAoTm90YXRpb24pIG5vdGF0aW9ucy5nZXROYW1lZEl0ZW0oIm5vdGF0aW9uMiIpOworICAgICAgc3lzdGVtSWQgPSBub3RhdGlvbk5vZGUuZ2V0U3lzdGVtSWQoKTsKKyAgICAgIGFzc2VydFVSSUVxdWFscygidXJpRXF1YWxzIiwgbnVsbCwgbnVsbCwgbnVsbCwgIm5vdGF0aW9uMkZpbGUiLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBzeXN0ZW1JZCk7Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL25vdGF0aW9uZ2V0c3lzdGVtaWQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vdGF0aW9uZ2V0c3lzdGVtaWQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vdGF0aW9uZ2V0c3lzdGVtaWRudWxsLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL25vdGF0aW9uZ2V0c3lzdGVtaWRudWxsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjg2NjMzNgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvbm90YXRpb25nZXRzeXN0ZW1pZG51bGwuamF2YQpAQCAtMCwwICsxLDkwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgUmV0cmlldmUgdGhlIG5vdGF0aW9uIG5hbWVkICJub3RhdGlvbjEiIGFuZCBhY2Nlc3MgaXRzICAKKyAqICAgIHN5c3RlbSBpZGVudGlmaWVyLiAgU2luY2UgYSBzeXN0ZW0gaWRlbnRpZmllciB3YXMgbm90CisgKiAgICBzcGVjaWZpZWQgZm9yIHRoaXMgbm90YXRpb24sIHRoZSAiZ2V0U3lzdGVtSWQoKSIgbWV0aG9kCisgKiAgICBzaG91bGQgcmV0dXJuIG51bGwuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1FOEFBQjFEMCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtRThBQUIxRDA8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vdGF0aW9uZ2V0c3lzdGVtaWRudWxsIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub3RhdGlvbmdldHN5c3RlbWlkbnVsbChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBub3RhdGlvbnM7CisgICAgICBOb3RhdGlvbiBub3RhdGlvbk5vZGU7CisgICAgICBTdHJpbmcgc3lzdGVtSWQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgbm90YXRpb25zID0gZG9jVHlwZS5nZXROb3RhdGlvbnMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoIm5vdGF0aW9uc05vdE51bGwiLCBub3RhdGlvbnMpOworICAgICAgbm90YXRpb25Ob2RlID0gKE5vdGF0aW9uKSBub3RhdGlvbnMuZ2V0TmFtZWRJdGVtKCJub3RhdGlvbjEiKTsKKyAgICAgIHN5c3RlbUlkID0gbm90YXRpb25Ob2RlLmdldFN5c3RlbUlkKCk7CisgICAgICBhc3NlcnROdWxsKCJzeXN0ZW1JZCIsIHN5c3RlbUlkKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvbm90YXRpb25nZXRzeXN0ZW1pZG51bGwiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vdGF0aW9uZ2V0c3lzdGVtaWRudWxsLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9wcm9jZXNzaW5naW5zdHJ1Y3Rpb25nZXRkYXRhLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL3Byb2Nlc3NpbmdpbnN0cnVjdGlvbmdldGRhdGEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MDAwMmU3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9wcm9jZXNzaW5naW5zdHJ1Y3Rpb25nZXRkYXRhLmphdmEKQEAgLTAsMCArMSw5MiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldERhdGEoKSIgbWV0aG9kIHJldHVybnMgdGhlIGNvbnRlbnQgb2YgdGhlICAKKyAqICAgIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uICBJdCBzdGFydHMgYXQgdGhlIGZpcnN0IG5vbgorICogICAgd2hpdGUgY2hhcmFjdGVyIGZvbGxvd2luZyB0aGUgdGFyZ2V0IGFuZCBlbmRzIGF0IHRoZQorICogICAgY2hhcmFjdGVyIGltbWVkaWF0ZWx5IHByZWNlZGluZyB0aGUgIj8+Ii4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBub2RlIGxvY2F0ZWQgIAorICogICAgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIHByb2xvZy4gIENyZWF0ZSBhIG5vZGVsaXN0IG9mIHRoZSAKKyAqICAgIGNoaWxkIG5vZGVzIG9mIHRoaXMgZG9jdW1lbnQuICBJbnZva2UgdGhlICJnZXREYXRhKCkiCisgKiAgICBtZXRob2Qgb24gdGhlIGZpcnN0IGNoaWxkIGluIHRoZSBsaXN0LiBUaGlzIHNob3VsZAorICogICAgcmV0dXJuIHRoZSBjb250ZW50IG9mIHRoZSBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04Mzc4MjIzOTMiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTgzNzgyMjM5MzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgcHJvY2Vzc2luZ2luc3RydWN0aW9uZ2V0ZGF0YSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgcHJvY2Vzc2luZ2luc3RydWN0aW9uZ2V0ZGF0YShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBjaGlsZE5vZGVzOworICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uIHBpTm9kZTsKKyAgICAgIFN0cmluZyBkYXRhOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGNoaWxkTm9kZXMgPSBkb2MuZ2V0Q2hpbGROb2RlcygpOworICAgICAgcGlOb2RlID0gKFByb2Nlc3NpbmdJbnN0cnVjdGlvbikgY2hpbGROb2Rlcy5pdGVtKDApOworICAgICAgZGF0YSA9IHBpTm9kZS5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInByb2Nlc3NpbmdpbnN0cnVjdGlvbkdldFRhcmdldEFzc2VydCIsICJQSURBVEEiLCBkYXRhKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvcHJvY2Vzc2luZ2luc3RydWN0aW9uZ2V0ZGF0YSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4ocHJvY2Vzc2luZ2luc3RydWN0aW9uZ2V0ZGF0YS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvcHJvY2Vzc2luZ2luc3RydWN0aW9uZ2V0dGFyZ2V0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL3Byb2Nlc3NpbmdpbnN0cnVjdGlvbmdldHRhcmdldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNiYjAxYTkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL3Byb2Nlc3NpbmdpbnN0cnVjdGlvbmdldHRhcmdldC5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRUYXJnZXQoKSIgbWV0aG9kIHJldHVybnMgdGhlIHRhcmdldCBvZiB0aGUgIAorICogICAgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4gIEl0IGlzIHRoZSBmaXJzdCB0b2tlbiBmb2xsb3dpbmcKKyAqICAgIHRoZSBtYXJrdXAgdGhhdCBiZWdpbnMgdGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gbm9kZSBsb2NhdGVkICAKKyAqICAgIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSBwcm9sb2cuICBDcmVhdGUgYSBub2RlbGlzdCBvZiB0aGUgCisgKiAgICBjaGlsZCBub2RlcyBvZiB0aGlzIGRvY3VtZW50LiAgSW52b2tlIHRoZSAiZ2V0VGFyZ2V0KCkiCisgKiAgICBtZXRob2Qgb24gdGhlIGZpcnN0IGNoaWxkIGluIHRoZSBsaXN0LiBUaGlzIHNob3VsZAorICogICAgcmV0dXJuIHRoZSB0YXJnZXQgb2YgdGhlIFByb2Nlc3NpbmdJbnN0cnVjdGlvbi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE0Nzg2ODkxOTIiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE0Nzg2ODkxOTI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIHByb2Nlc3NpbmdpbnN0cnVjdGlvbmdldHRhcmdldCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgcHJvY2Vzc2luZ2luc3RydWN0aW9uZ2V0dGFyZ2V0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTm9kZXM7CisgICAgICBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gcGlOb2RlOworICAgICAgU3RyaW5nIHRhcmdldDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBjaGlsZE5vZGVzID0gZG9jLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIHBpTm9kZSA9IChQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24pIGNoaWxkTm9kZXMuaXRlbSgwKTsKKyAgICAgIHRhcmdldCA9IHBpTm9kZS5nZXRUYXJnZXQoKTsKKyAgICAgIGFzc2VydEVxdWFscygicHJvY2Vzc2luZ2luc3RydWN0aW9uR2V0VGFyZ2V0QXNzZXJ0IiwgIlRFU1QtU1RZTEUiLCB0YXJnZXQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9wcm9jZXNzaW5naW5zdHJ1Y3Rpb25nZXR0YXJnZXQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHByb2Nlc3NpbmdpbnN0cnVjdGlvbmdldHRhcmdldC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvcHJvY2Vzc2luZ2luc3RydWN0aW9uc2V0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9wcm9jZXNzaW5naW5zdHJ1Y3Rpb25zZXRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWRiZTlkNQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvcHJvY2Vzc2luZ2luc3RydWN0aW9uc2V0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyci5qYXZhCkBAIC0wLDAgKzEsMTEyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0RGF0YShkYXRhKSIgbWV0aG9kIGZvciBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gY2F1c2VzIHRoZSAKKyAqICAgIERPTUV4Y2VwdGlvbiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgdG8gYmUgcmFpc2VkCisgKiAgICBpZiB0aGUgbm9kZSBpcyByZWFkb25seS4KKyAqICAgIAorICogICAgT2J0YWluIHRoZSBjaGlsZHJlbiBvZiB0aGUgVEhJUkQgImdlbmRlciIgZWxlbWVudC4gIFRoZSBlbGVtZW50cworICogICAgY29udGVudCBpcyBhbiBlbnRpdHkgcmVmZXJlbmNlLiAgVHJ5IHRvIHJlbW92ZSB0aGUgImRvbWVzdGljIiBhdHRyaWJ1dGUKKyAqICAgIGZyb20gdGhlIGVudGl0eSByZWZlcmVuY2UgYnkgZXhlY3V0aW5nIHRoZSAic2V0RGF0YShkYXRhKSIgbWV0aG9kLgorICogICAgVGhpcyBjYXVzZXMgYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgRE9NRXhjZXB0aW9uIHRvIGJlIHRocm93bi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODM3ODIyMzkzIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04Mzc4MjIzOTM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTgzNzgyMjM5MycpL3NldHJhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTgzNzgyMjM5MycpL3NldHJhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04Mzc4MjIzOTMiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTgzNzgyMjM5MzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgcHJvY2Vzc2luZ2luc3RydWN0aW9uc2V0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgcHJvY2Vzc2luZ2luc3RydWN0aW9uc2V0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVycihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RFeHBhbmRFbnRpdHlSZWZlcmVuY2VzCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyOworICAgICAgTm9kZSBlbnRSZWY7CisgICAgICBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gcGlOb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZ2VuZGVyTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZ2VuZGVyIik7CisgICAgICBnZW5kZXIgPSBnZW5kZXJMaXN0Lml0ZW0oMik7CisgICAgICBlbnRSZWYgPSBnZW5kZXIuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50UmVmTm90TnVsbCIsIGVudFJlZik7CisgICAgICBwaU5vZGUgPSAoUHJvY2Vzc2luZ0luc3RydWN0aW9uKSBlbnRSZWYuZ2V0TGFzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJwaU5vZGVOb3ROdWxsIiwgcGlOb2RlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgcGlOb2RlLnNldERhdGEoIm5ld0RhdGEiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9wcm9jZXNzaW5naW5zdHJ1Y3Rpb25zZXRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihwcm9jZXNzaW5naW5zdHJ1Y3Rpb25zZXRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS9wcm9jZXNzaW5naW5zdHJ1Y3Rpb25zZXRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvcHJvY2Vzc2luZ2luc3RydWN0aW9uc2V0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTg1NjE4MQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvcHJvY2Vzc2luZ2luc3RydWN0aW9uc2V0ZGF0YW5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmphdmEKQEAgLTAsMCArMSwxMTAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXREYXRhKGRhdGEpIiBtZXRob2QgZm9yIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBjYXVzZXMgdGhlIAorICogICAgRE9NRXhjZXB0aW9uIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiB0byBiZSByYWlzZWQKKyAqICAgIGlmIHRoZSBub2RlIGlzIHJlYWRvbmx5LgorICogICAgCisgKiAgICBDcmVhdGUgYW4gZW50NCBlbnRpdHkgcmVmZXJlbmNlIGFuZCBhZGQgdG8gZG9jdW1lbnQgb2YgdGhlIFRISVJEICJnZW5kZXIiIGVsZW1lbnQuICBUaGUgZWxlbWVudHMKKyAqICAgIGNvbnRlbnQgaXMgYW4gZW50aXR5IHJlZmVyZW5jZS4gIFRyeSB0byByZW1vdmUgdGhlICJkb21lc3RpYyIgYXR0cmlidXRlCisgKiAgICBmcm9tIHRoZSBlbnRpdHkgcmVmZXJlbmNlIGJ5IGV4ZWN1dGluZyB0aGUgInNldERhdGEoZGF0YSkiIG1ldGhvZC4KKyAqICAgIFRoaXMgY2F1c2VzIGEgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIERPTUV4Y2VwdGlvbiB0byBiZSB0aHJvd24uCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTgzNzgyMjM5MyI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODM3ODIyMzkzPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC04Mzc4MjIzOTMnKS9zZXRyYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC04Mzc4MjIzOTMnKS9zZXRyYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtODM3ODIyMzkzIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC04Mzc4MjIzOTM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyQXByLzAwNTMuaHRtbCI+aHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LWRvbS10cy8yMDAyQXByLzAwNTMuaHRtbDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL3Byb2Nlc3NpbmdpbnN0cnVjdGlvbnNldGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIueG1sIj5odHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL3Byb2Nlc3NpbmdpbnN0cnVjdGlvbnNldGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIueG1sPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBwcm9jZXNzaW5naW5zdHJ1Y3Rpb25zZXRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHByb2Nlc3NpbmdpbnN0cnVjdGlvbnNldGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGdlbmRlckxpc3Q7CisgICAgICBOb2RlIGdlbmRlcjsKKyAgICAgIE5vZGUgZW50UmVmOworICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uIHBpTm9kZTsKKyAgICAgIE5vZGUgYXBwZW5kZWRDaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGdlbmRlckxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImdlbmRlciIpOworICAgICAgZ2VuZGVyID0gZ2VuZGVyTGlzdC5pdGVtKDIpOworICAgICAgZW50UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGdlbmRlci5hcHBlbmRDaGlsZChlbnRSZWYpOworICAgICAgZW50UmVmID0gZ2VuZGVyLmdldExhc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50UmVmTm90TnVsbCIsIGVudFJlZik7CisgICAgICBwaU5vZGUgPSAoUHJvY2Vzc2luZ0luc3RydWN0aW9uKSBlbnRSZWYuZ2V0TGFzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJwaU5vZGVOb3ROdWxsIiwgcGlOb2RlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgcGlOb2RlLnNldERhdGEoIm5ld0RhdGEiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS9wcm9jZXNzaW5naW5zdHJ1Y3Rpb25zZXRkYXRhbm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHByb2Nlc3NpbmdpbnN0cnVjdGlvbnNldGRhdGFub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvdGV4dGluZGV4c2l6ZWVycm5lZ2F0aXZlb2Zmc2V0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL3RleHRpbmRleHNpemVlcnJuZWdhdGl2ZW9mZnNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRhODcwYTgKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL3RleHRpbmRleHNpemVlcnJuZWdhdGl2ZW9mZnNldC5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNwbGl0VGV4dChvZmZzZXQpIiBtZXRob2QgcmFpc2VzIGFuCisgKiAgICAgSU5ERVhfU0laRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgb2Zmc2V0IGlzCisgKiAgICAgbmVnYXRpdmUuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHRleHR1YWwgZGF0YSBmcm9tIHRoZSBzZWNvbmQgY2hpbGQgb2YgdGhlIAorICogICAgIHRoaXJkIGVtcGxveWVlIGFuZCBpbnZva2UgdGhlICJzcGxpdFRleHQob2Zmc2V0KSIgbWV0aG9kLgorICogICAgIFRoZSBkZXNpcmVkIGV4Y2VwdGlvbiBzaG91bGQgYmUgcmFpc2VkIHNpbmNlIHRoZSBvZmZzZXQKKyAqICAgICBpcyBhIG5lZ2F0aXZlIG51bWJlci4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM4ODUzQzFEIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zODg1M0MxRDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMzg4NTNDMUQnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTM4ODUzQzFEJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIHRleHRpbmRleHNpemVlcnJuZWdhdGl2ZW9mZnNldCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgdGV4dGluZGV4c2l6ZWVycm5lZ2F0aXZlb2Zmc2V0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLnNpZ25lZAorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIFRleHQgdGV4dE5vZGU7CisgICAgICBUZXh0IHNwbGl0Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJuYW1lIik7CisgICAgICBuYW1lTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICB0ZXh0Tm9kZSA9IChUZXh0KSBuYW1lTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNwbGl0Tm9kZSA9IHRleHROb2RlLnNwbGl0VGV4dCgtNjkpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTkRFWF9TSVpFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd3NfSU5ERVhfU0laRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvdGV4dGluZGV4c2l6ZWVycm5lZ2F0aXZlb2Zmc2V0IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbih0ZXh0aW5kZXhzaXplZXJybmVnYXRpdmVvZmZzZXQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL3RleHRpbmRleHNpemVlcnJvZmZzZXRvdXRvZmJvdW5kcy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS90ZXh0aW5kZXhzaXplZXJyb2Zmc2V0b3V0b2Zib3VuZHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTFhNTM3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS90ZXh0aW5kZXhzaXplZXJyb2Zmc2V0b3V0b2Zib3VuZHMuamF2YQpAQCAtMCwwICsxLDEwNCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNwbGl0VGV4dChvZmZzZXQpIiBtZXRob2QgcmFpc2VzIGFuCisgKiAgICAgSU5ERVhfU0laRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgb2Zmc2V0IGlzCisgKiAgICAgZ3JlYXRlciB0aGFuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgVGV4dCBub2RlLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSB0ZXh0dWFsIGRhdGEgZnJvbSB0aGUgc2Vjb25kIGNoaWxkIG9mIHRoZSAKKyAqICAgICB0aGlyZCBlbXBsb3llZSBhbmQgaW52b2tlIHRoZSAic3BsaXRUZXh0KG9mZnNldCkiIG1ldGhvZC4KKyAqICAgICBUaGUgZGVzaXJlZCBleGNlcHRpb24gc2hvdWxkIGJlIHJhaXNlZCBzaW5jZSB0aGUgb2Zmc2V0CisgKiAgICAgaXMgYSBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIHRoZSBUZXh0CisgKiAgICAgbm9kZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOREVYX1NJWkVfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM4ODUzQzFEIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zODg1M0MxRDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMzg4NTNDMUQnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTkRFWF9TSVpFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTM4ODUzQzFEJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5ERVhfU0laRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgdGV4dGluZGV4c2l6ZWVycm9mZnNldG91dG9mYm91bmRzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyB0ZXh0aW5kZXhzaXplZXJyb2Zmc2V0b3V0b2Zib3VuZHMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmFtZU5vZGU7CisgICAgICBUZXh0IHRleHROb2RlOworICAgICAgVGV4dCBzcGxpdE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgibmFtZSIpOworICAgICAgbmFtZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgdGV4dE5vZGUgPSAoVGV4dCkgbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzcGxpdE5vZGUgPSB0ZXh0Tm9kZS5zcGxpdFRleHQoMzAwKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSU5ERVhfU0laRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvdGV4dGluZGV4c2l6ZWVycm9mZnNldG91dG9mYm91bmRzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbih0ZXh0aW5kZXhzaXplZXJyb2Zmc2V0b3V0b2Zib3VuZHMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL3RleHRwYXJzZWludG9saXN0b2ZlbGVtZW50cy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS90ZXh0cGFyc2VpbnRvbGlzdG9mZWxlbWVudHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wN2I3ODM4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS90ZXh0cGFyc2VpbnRvbGlzdG9mZWxlbWVudHMuamF2YQpAQCAtMCwwICsxLDEyNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBSZXRyaWV2ZSB0aGUgdGV4dHVhbCBkYXRhIGZyb20gdGhlIGxhc3QgY2hpbGQgb2YgdGhlIAorICogICAgIHNlY29uZCBlbXBsb3llZS4gICBUaGF0IG5vZGUgaXMgY29tcG9zZWQgb2YgdHdvICAgCisgKiAgICAgRW50aXR5UmVmZXJlbmNlIG5vZGVzIGFuZCB0d28gVGV4dCBub2Rlcy4gICBBZnRlcgorICogICAgIHRoZSBjb250ZW50IG5vZGUgaXMgcGFyc2VkLCB0aGUgImFkZHJlc3MiIEVsZW1lbnQKKyAqICAgICBzaG91bGQgY29udGFpbiBmb3VyIGNoaWxkcmVuIHdpdGggZWFjaCBvbmUgb2YgdGhlCisgKiAgICAgRW50aXR5UmVmZXJlbmNlcyBjb250YWluaW5nIG9uZSBjaGlsZC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE0NTE0NjA5ODciPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTE0NTE0NjA5ODc8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTFDOTg0OTAiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTExQzk4NDkwPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTc0NTU0OTYxNCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtNzQ1NTQ5NjE0PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyB0ZXh0cGFyc2VpbnRvbGlzdG9mZWxlbWVudHMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHRleHRwYXJzZWludG9saXN0b2ZlbGVtZW50cyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgYWRkcmVzc05vZGU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgaW50IGxlbmd0aDsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIE5vZGUgZ3JhbmRDaGlsZDsKKyAgICAgIGphdmEudXRpbC5MaXN0IHJlc3VsdCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5MaXN0IGV4cGVjdGVkTm9ybWFsID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGV4cGVjdGVkTm9ybWFsLmFkZCgiMTkwMCBEYWxsYXMgUm9hZCIpOworICAgICAgZXhwZWN0ZWROb3JtYWwuYWRkKCIgRGFsbGFzLCAiKTsKKyAgICAgIGV4cGVjdGVkTm9ybWFsLmFkZCgiVGV4YXMiKTsKKyAgICAgIGV4cGVjdGVkTm9ybWFsLmFkZCgiXG4gOTg1NTQiKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkxpc3QgZXhwZWN0ZWRFeHBhbmRlZCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZEV4cGFuZGVkLmFkZCgiMTkwMCBEYWxsYXMgUm9hZCBEYWxsYXMsIFRleGFzXG4gOTg1NTQiKTsKKyAgICAgIAorICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICBhZGRyZXNzTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBjaGlsZExpc3QgPSBhZGRyZXNzTm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBsZW5ndGggPSAoaW50KSBjaGlsZExpc3QuZ2V0TGVuZ3RoKCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA3RiA9IDA7IGluZGV4TjEwMDdGIDwgY2hpbGRMaXN0LmdldExlbmd0aCgpOyBpbmRleE4xMDA3RisrKSB7CisgICAgICAgICAgY2hpbGQgPSAoTm9kZSkgY2hpbGRMaXN0Lml0ZW0oaW5kZXhOMTAwN0YpOworICAgIHZhbHVlID0gY2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICAKKyAgICAgIGlmICgodmFsdWUgPT0gbnVsbCkpIHsKKyAgICAgICAgICBncmFuZENoaWxkID0gY2hpbGQuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZ3JhbmRDaGlsZE5vdE51bGwiLCBncmFuZENoaWxkKTsKKyAgICAgIHZhbHVlID0gZ3JhbmRDaGlsZC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIHJlc3VsdC5hZGQodmFsdWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXN1bHQuYWRkKHZhbHVlKTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgICB9CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoNCwgbGVuZ3RoKSkgeworICAgICAgICAgIGFzc2VydEVxdWFscygiYXNzZXJ0RXFOb3JtYWwiLCBleHBlY3RlZE5vcm1hbCwgcmVzdWx0KTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJhc3NlcnRFcUNvYWxlc2NpbmciLCBleHBlY3RlZEV4cGFuZGVkLCByZXN1bHQpOworICAgICAgfQorICAgICAgICAKKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL3RleHRwYXJzZWludG9saXN0b2ZlbGVtZW50cyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4odGV4dHBhcnNlaW50b2xpc3RvZmVsZW1lbnRzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0Zm91ci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0Zm91ci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlNTRkMzIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL3RleHRzcGxpdHRleHRmb3VyLmphdmEKQEAgLTAsMCArMSw5NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzcGxpdFRleHQob2Zmc2V0KSIgbWV0aG9kIHJldHVybnMgdGhlIG5ldyBUZXh0IG5vZGUuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHRleHR1YWwgZGF0YSBmcm9tIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSAKKyAqICAgICBmaXJzdCBlbXBsb3llZSBhbmQgaW52b2tlIHRoZSAic3BsaXRUZXh0KG9mZnNldCkiIG1ldGhvZC4KKyAqICAgICBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gdGhlIG5ldyBUZXh0IG5vZGUuICAgVGhlIG9mZnNldAorICogICAgIHZhbHVlIHVzZWQgZm9yIHRoaXMgdGVzdCBpcyAzMC4gICBUaGUgImdldE5vZGVWYWx1ZSgpIgorICogICAgIG1ldGhvZCBpcyBjYWxsZWQgdG8gY2hlY2sgdGhhdCB0aGUgbmV3IG5vZGUgbm93IGNvbnRhaW5zCisgKiAgICAgdGhlIGNoYXJhY3RlcnMgYXQgYW5kIGFmdGVyIHBvc2l0aW9uIDMwLgorICogICAgIChTdGFydGluZyBjb3VudCBhdCAwKQorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzg4NTNDMUQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM4ODUzQzFEPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyB0ZXh0c3BsaXR0ZXh0Zm91ciBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgdGV4dHNwbGl0dGV4dGZvdXIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgYWRkcmVzc05vZGU7CisgICAgICBUZXh0IHRleHROb2RlOworICAgICAgVGV4dCBzcGxpdE5vZGU7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgYWRkcmVzc05vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgdGV4dE5vZGUgPSAoVGV4dCkgYWRkcmVzc05vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgc3BsaXROb2RlID0gdGV4dE5vZGUuc3BsaXRUZXh0KDMwKTsKKyAgICAgIHZhbHVlID0gc3BsaXROb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0U3BsaXRUZXh0Rm91ckFzc2VydCIsICI5ODU1MSIsIHZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwxL2NvcmUvdGV4dHNwbGl0dGV4dGZvdXIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHRleHRzcGxpdHRleHRmb3VyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0bm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL3RleHRzcGxpdHRleHRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZTMzZmRlCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0bm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmphdmEKQEAgLTAsMCArMSwxMTcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzcGxpdFRleHQob2Zmc2V0KSIgbWV0aG9kIHJhaXNlcyBhIAorICogICAgIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gaWYgdGhlCisgKiAgICAgbm9kZSBpcyByZWFkb25seS4KKyAqICAgICAgCisgKiAgICAgT2J0YWluIHRoZSBjaGlsZHJlbiBvZiB0aGUgVEhJUkQgImdlbmRlciIgZWxlbWVudC4gICBUaGUgZWxlbWVudHMKKyAqICAgICBjb250ZW50IGlzIGFuIGVudGl0eSByZWZlcmVuY2UuICAgR2V0IHRoZSBlbGVtZW50IGNvbnRlbnQgb2YgdGhlIEZJUlNUCisgKiAgICAgVGV4dCBOb2RlIG9mIHRoZSBlbnRpdHkgcmVmZXJlbmNlIGFuZCBleGVjdXRlIHRoZSAic3BsaXRUZXh0KG9mZnNldCkiIG1ldGhvZC4KKyAqICAgICBUaGlzIGNhdXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gdG8gYmUgdGhyb3duLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zODg1M0MxRCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzg4NTNDMUQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTM4ODUzQzFEJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMzg4NTNDMUQnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzg4NTNDMUQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM4ODUzQzFEPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyB0ZXh0c3BsaXR0ZXh0bm9tb2RpZmljYXRpb25hbGxvd2VkZXJyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyB0ZXh0c3BsaXR0ZXh0bm9tb2RpZmljYXRpb25hbGxvd2VkZXJyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZ2VuZGVyTGlzdDsKKyAgICAgIE5vZGUgZ2VuZGVyOworICAgICAgTm9kZSBlbnRSZWY7CisgICAgICBOb2RlIGVudEVsZW1lbnQ7CisgICAgICBOb2RlIGVudEVsZW1lbnRUZXh0OworICAgICAgVGV4dCBzcGxpdE5vZGU7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBnZW5kZXJMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJnZW5kZXIiKTsKKyAgICAgIGdlbmRlciA9IGdlbmRlckxpc3QuaXRlbSgyKTsKKyAgICAgIGVudFJlZiA9IGdlbmRlci5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRSZWZOb3ROdWxsIiwgZW50UmVmKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgZW50UmVmLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoMSwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgZW50UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworICAgICAgfQorICAgIGVudEVsZW1lbnQgPSBlbnRSZWYuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50RWxlbWVudE5vdE51bGwiLCBlbnRFbGVtZW50KTsKKyAgICAgIGVudEVsZW1lbnRUZXh0ID0gZW50RWxlbWVudC5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRFbGVtZW50VGV4dE5vdE51bGwiLCBlbnRFbGVtZW50VGV4dCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNwbGl0Tm9kZSA9ICgoVGV4dCkgLypOb2RlICovZW50RWxlbWVudFRleHQpLnNwbGl0VGV4dCgyKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0bm9tb2RpZmljYXRpb25hbGxvd2VkZXJyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbih0ZXh0c3BsaXR0ZXh0bm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0bm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvdGV4dHNwbGl0dGV4dG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTE0M2Y3MwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvdGV4dHNwbGl0dGV4dG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFLmphdmEKQEAgLTAsMCArMSw5NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBDcmVhdGUgYW4gZW50MyByZWZlcmVuY2UgYW5kIGV4ZWN1dGUgdGhlICJzcGxpdFRleHQob2Zmc2V0KSIgbWV0aG9kLgorICogICAgIFRoaXMgY2F1c2VzIGEgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIERPTUV4Y2VwdGlvbiB0byBiZSB0aHJvd24uCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM4ODUzQzFEIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zODg1M0MxRDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMzg4NTNDMUQnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI3hwb2ludGVyKGlkKCdJRC0zODg1M0MxRCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zODg1M0MxRCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzg4NTNDMUQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0bm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLnhtbCI+aHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0bm9tb2RpZmljYXRpb25hbGxvd2VkZXJyLnhtbDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgdGV4dHNwbGl0dGV4dG5vbW9kaWZpY2F0aW9uYWxsb3dlZGVyckVFIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyB0ZXh0c3BsaXR0ZXh0bm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIGVudFJlZjsKKyAgICAgIE5vZGUgZW50VGV4dDsKKyAgICAgIFRleHQgc3BsaXROb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZW50UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50MyIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworICAgICAgZW50VGV4dCA9IGVudFJlZi5nZXRGaXJzdENoaWxkKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRUZXh0Tm90TnVsbCIsIGVudFRleHQpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzcGxpdE5vZGUgPSAoKFRleHQpIC8qTm9kZSAqL2VudFRleHQpLnNwbGl0VGV4dCgyKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0bm9tb2RpZmljYXRpb25hbGxvd2VkZXJyRUUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHRleHRzcGxpdHRleHRub21vZGlmaWNhdGlvbmFsbG93ZWRlcnJFRS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvdGV4dHNwbGl0dGV4dG9uZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0b25lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzBiYmJmNAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvdGV4dHNwbGl0dGV4dG9uZS5qYXZhCkBAIC0wLDAgKzEsOTggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic3BsaXRUZXh0KG9mZnNldCkiIG1ldGhvZCBicmVha3MgdGhlIFRleHQgbm9kZSBpbnRvCisgKiAgICAgdHdvIFRleHQgbm9kZXMgYXQgdGhlIHNwZWNpZmllZCBvZmZzZXQga2VlcGluZyBlYWNoIG5vZGUKKyAqICAgICBhcyBzaWJsaW5ncyBpbiB0aGUgdHJlZS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgdGV4dHVhbCBkYXRhIGZyb20gdGhlIHNlY29uZCBjaGlsZCBvZiB0aGUgCisgKiAgICAgdGhpcmQgZW1wbG95ZWUgYW5kIGludm9rZSB0aGUgInNwbGl0VGV4dChvZmZzZXQpIiBtZXRob2QuCisgKiAgICAgVGhlIG1ldGhvZCBzcGxpdHMgdGhlIFRleHQgbm9kZSBpbnRvIHR3byBuZXcgc2libGluZworICogICAgIFRleHQgbm9kZXMga2VlcGluZyBib3RoIG9mIHRoZW0gaW4gdGhlIHRyZWUuICAgVGhpcyB0ZXN0CisgKiAgICAgY2hlY2tzIHRoZSAibmV4dFNpYmxpbmcoKSIgbWV0aG9kIG9mIHRoZSBvcmlnaW5hbCBub2RlCisgKiAgICAgdG8gZW5zdXJlIHRoYXQgdGhlIHR3byBub2RlcyBhcmUgaW5kZWVkIHNpYmxpbmdzLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzg4NTNDMUQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM4ODUzQzFEPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyB0ZXh0c3BsaXR0ZXh0b25lIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyB0ZXh0c3BsaXR0ZXh0b25lKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgVGV4dCB0ZXh0Tm9kZTsKKyAgICAgIFRleHQgc3BsaXROb2RlOworICAgICAgTm9kZSBzZWNvbmRQYXJ0OworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIm5hbWUiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIHRleHROb2RlID0gKFRleHQpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIHNwbGl0Tm9kZSA9IHRleHROb2RlLnNwbGl0VGV4dCg3KTsKKyAgICAgIHNlY29uZFBhcnQgPSB0ZXh0Tm9kZS5nZXROZXh0U2libGluZygpOworICAgICAgdmFsdWUgPSBzZWNvbmRQYXJ0LmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0U3BsaXRUZXh0T25lQXNzZXJ0IiwgIkpvbmVzIiwgdmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0b25lIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbih0ZXh0c3BsaXR0ZXh0b25lLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0dGhyZWUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvdGV4dHNwbGl0dGV4dHRocmVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTJkM2UxMwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvdGV4dHNwbGl0dGV4dHRocmVlLmphdmEKQEAgLTAsMCArMSw5NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgQWZ0ZXIgdGhlICJzcGxpdFRleHQob2Zmc2V0KSIgbWV0aG9kIGJyZWFrcyB0aGUgVGV4dCBub2RlCisgKiAgICAgaW50byB0d28gVGV4dCBub2RlcywgdGhlIG5ldyBUZXh0IG5vZGUgY29udGFpbnMgYWxsIHRoZQorICogICAgIGNvbnRlbnQgYXQgYW5kIGFmdGVyIHRoZSBvZmZzZXQgcG9pbnQuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHRleHR1YWwgZGF0YSBmcm9tIHRoZSBzZWNvbmQgY2hpbGQgb2YgdGhlIAorICogICAgIHRoaXJkIGVtcGxveWVlIGFuZCBpbnZva2UgdGhlICJzcGxpdFRleHQob2Zmc2V0KSIgbWV0aG9kLgorICogICAgIFRoZSBuZXcgVGV4dCBub2RlIHNob3VsZCBjb250YWluIGFsbCB0aGUgY29udGVudAorICogICAgIGF0IGFuZCBhZnRlciB0aGUgb2Zmc2V0IHBvaW50LiAgIFRoZSAiZ2V0Tm9kZVZhbHVlKCkiCisgKiAgICAgbWV0aG9kIGlzIGNhbGxlZCB0byBjaGVjayB0aGF0IHRoZSBuZXcgbm9kZSBub3cgY29udGFpbnMKKyAqICAgICB0aGUgY2hhcmFjdGVycyBhdCBhbmQgYWZ0ZXIgcG9zaXRpb24gc2V2ZW4uCisgKiAgICAgKFN0YXJ0aW5nIGNvdW50IGF0IDApCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC0zODg1M0MxRCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzg4NTNDMUQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIHRleHRzcGxpdHRleHR0aHJlZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgdGV4dHNwbGl0dGV4dHRocmVlKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgVGV4dCB0ZXh0Tm9kZTsKKyAgICAgIFRleHQgc3BsaXROb2RlOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIm5hbWUiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIHRleHROb2RlID0gKFRleHQpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIHNwbGl0Tm9kZSA9IHRleHROb2RlLnNwbGl0VGV4dCg2KTsKKyAgICAgIHZhbHVlID0gc3BsaXROb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0U3BsaXRUZXh0VGhyZWVBc3NlcnQiLCAiIEpvbmVzIiwgdmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0dGhyZWUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHRleHRzcGxpdHRleHR0aHJlZS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvdGV4dHNwbGl0dGV4dHR3by5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvY29yZS90ZXh0c3BsaXR0ZXh0dHdvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWM2ODZmMAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvdGV4dHNwbGl0dGV4dHR3by5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIEFmdGVyIHRoZSAic3BsaXRUZXh0KG9mZnNldCkiIG1ldGhvZCBicmVha3MgdGhlIFRleHQgbm9kZQorICogICAgIGludG8gdHdvIFRleHQgbm9kZXMsIHRoZSBvcmlnaW5hbCBub2RlIGNvbnRhaW5zIGFsbCB0aGUKKyAqICAgICBjb250ZW50IHVwIHRvIHRoZSBvZmZzZXQgcG9pbnQuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHRleHR1YWwgZGF0YSBmcm9tIHRoZSBzZWNvbmQgY2hpbGQgb2YgdGhlIAorICogICAgIHRoaXJkIGVtcGxveWVlIGFuZCBpbnZva2UgdGhlICJzcGxpdFRleHQob2Zmc2V0KSIgbWV0aG9kLgorICogICAgIFRoZSBvcmlnaW5hbCBUZXh0IG5vZGUgc2hvdWxkIGNvbnRhaW4gYWxsIHRoZSBjb250ZW50CisgKiAgICAgdXAgdG8gdGhlIG9mZnNldCBwb2ludC4gICBUaGUgImdldE5vZGVWYWx1ZSgpIiBtZXRob2QKKyAqICAgICBpcyBjYWxsZWQgdG8gY2hlY2sgdGhhdCB0aGUgb3JpZ2luYWwgbm9kZSBub3cgY29udGFpbnMKKyAqICAgICB0aGUgZmlyc3QgZml2ZSBjaGFyYWN0ZXJzLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMzg4NTNDMUQiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTM4ODUzQzFEPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyB0ZXh0c3BsaXR0ZXh0dHdvIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyB0ZXh0c3BsaXR0ZXh0dHdvKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIG5hbWVOb2RlOworICAgICAgVGV4dCB0ZXh0Tm9kZTsKKyAgICAgIFRleHQgc3BsaXROb2RlOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIm5hbWUiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIHRleHROb2RlID0gKFRleHQpIG5hbWVOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIHNwbGl0Tm9kZSA9IHRleHROb2RlLnNwbGl0VGV4dCg1KTsKKyAgICAgIHZhbHVlID0gdGV4dE5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInRleHRTcGxpdFRleHRUd29Bc3NlcnQiLCAiUm9nZXIiLCB2YWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMS9jb3JlL3RleHRzcGxpdHRleHR0d28iOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHRleHRzcGxpdHRleHR0d28uY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL3RleHR3aXRobm9tYXJrdXAuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2NvcmUvdGV4dHdpdGhub21hcmt1cC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiMDc0NjAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9jb3JlL3RleHR3aXRobm9tYXJrdXAuamF2YQpAQCAtMCwwICsxLDk1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDEuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIElmIHRoZXJlIGlzIG5vdCBhbnkgbWFya3VwIGluc2lkZSBhbiBFbGVtZW50IG9yIEF0dHIgbm9kZQorICogICAgIGNvbnRlbnQsIHRoZW4gdGhlIHRleHQgaXMgY29udGFpbmVkIGluIGEgc2luZ2xlIG9iamVjdCAgIAorICogICAgIGltcGxlbWVudGluZyB0aGUgVGV4dCBpbnRlcmZhY2UgdGhhdCBpcyB0aGUgb25seSBjaGlsZAorICogICAgIG9mIHRoZSBlbGVtZW50LgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSB0ZXh0dWFsIGRhdGEgZnJvbSB0aGUgc2Vjb25kIGNoaWxkIG9mIHRoZSAKKyAqICAgICB0aGlyZCBlbXBsb3llZS4gICBUaGF0IFRleHQgbm9kZSBjb250YWlucyBhIGJsb2NrIG9mIAorICogICAgIG11bHRpcGxlIHRleHQgbGluZXMgd2l0aG91dCBtYXJrdXAsIHNvIHRoZXkgc2hvdWxkIGJlCisgKiAgICAgdHJlYXRlZCBhcyBhIHNpbmdsZSBUZXh0IG5vZGUuICAgVGhlICJnZXROb2RlVmFsdWUoKSIgICAgCisgKiAgICAgbWV0aG9kIHNob3VsZCBjb250YWluIHRoZSBjb21iaW5hdGlvbiBvZiB0aGUgdHdvIGxpbmVzLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTMxMjI5NTc3MiI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTMxMjI5NTc3MjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSNJRC1GNjhEMDgwPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyB0ZXh0d2l0aG5vbWFya3VwIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyB0ZXh0d2l0aG5vbWFya3VwKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBuYW1lTm9kZTsKKyAgICAgIE5vZGUgbm9kZVY7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIm5hbWUiKTsKKyAgICAgIG5hbWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIG5vZGVWID0gbmFtZU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgdmFsdWUgPSBub2RlVi5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygidGV4dE5vZGVWYWx1ZSIsICJSb2dlclxuIEpvbmVzIiwgdmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDEvY29yZS90ZXh0d2l0aG5vbWFya3VwIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbih0ZXh0d2l0aG5vbWFya3VwLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvaHRtbC9UZXN0RGVmYXVsdExTLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9odG1sL1Rlc3REZWZhdWx0TFMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYzdhYWVhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvaHRtbC9UZXN0RGVmYXVsdExTLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZQorICogb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgorICogQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcworICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzCisgKiBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQorICogV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUworICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UKKyAqIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5odG1sOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworCisvKioKKyAqIFRlc3Qgc3VpdGUgdGhhdCBydW5zIGFsbCBET00gTDEgSFRNTCB0ZXN0cyB1c2luZyB0aGUKKyAqIERlZmF1bHQgTFMgcGFyc2VyIGluIGRlZmF1bHQgY29uZmlndXJhdGlvbi4KKyAqIAorICogQGF1dGhvciBDdXJ0IEFybm9sZAorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0RGVmYXVsdExTIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworCXB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJCUNsYXNzIHRlc3RDbGFzcyA9CisJCQlDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygKKwkJCQkib3JnLnczYy5kb210cy5sZXZlbDEuaHRtbC5hbGx0ZXN0cyIpOworCQlDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPQorCQkJdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKAorCQkJCW5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKwkJRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisJCQluZXcgTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KAorCQkJCUpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworCQlPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvaHRtbC9UZXN0RGVmYXVsdExTQWx0Q29uZmlnLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9odG1sL1Rlc3REZWZhdWx0TFNBbHRDb25maWcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZmIxYzc1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDEvaHRtbC9UZXN0RGVmYXVsdExTQWx0Q29uZmlnLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZQorICogb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgorICogQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcworICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzCisgKiBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQorICogV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUworICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UKKyAqIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMS5odG1sOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworCisvKioKKyAqIFRlc3Qgc3VpdGUgdGhhdCBydW5zIGFsbCBET00gTDEgSFRNTCB0ZXN0cyB1c2luZyB0aGUKKyAqIERlZmF1bHQgTFMgcGFyc2VyIGluIGFuIGFsdGVybmF0ZSBjb25maWd1cmF0aW9uLgorICogCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3REZWZhdWx0TFNBbHRDb25maWcgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisJcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwkJQ2xhc3MgdGVzdENsYXNzID0KKwkJCUNsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKAorCQkJCSJvcmcudzNjLmRvbXRzLmxldmVsMS5odG1sLmFsbHRlc3RzIik7CisJCUNvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9CisJCQl0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IoCisJCQkJbmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworCQlET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKwkJCW5ldyBMU0RvY3VtZW50QnVpbGRlckZhY3RvcnkoCisJCQkJSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24yKCkpOworCisJCU9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKwkJcmV0dXJuIG5ldyBKVW5pdFRlc3RTdWl0ZUFkYXB0ZXIoKERPTVRlc3RTdWl0ZSkgdGVzdCk7CisJfQorCit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9odG1sL1Rlc3RYZXJjZXNIVE1MLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMS9odG1sL1Rlc3RYZXJjZXNIVE1MLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWU5YzZkZAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwxL2h0bWwvVGVzdFhlcmNlc0hUTUwuamF2YQpAQCAtMCwwICsxLDQzIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwxLmh0bWw7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworaW1wb3J0IG9yZy53M2MuZG9tdHMuWGVyY2VzSFRNTERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK3B1YmxpYyBjbGFzcyBUZXN0WGVyY2VzSFRNTCBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKyAgcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uCisgIHsKKyAgICBDbGFzcyB0ZXN0Q2xhc3MgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLnczYy5kb210cy5sZXZlbDEuaHRtbC5hbGx0ZXN0cyIpOworICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9IHRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBYZXJjZXNIVE1MRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKyAgICAgICAgICBYZXJjZXNIVE1MRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgfQorCisKK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9UZXN0QmF0aWsuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdEJhdGlrLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDFkYzE3ZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdEJhdGlrLmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5CYXRpa1Rlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nOworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworCitwdWJsaWMgY2xhc3MgVGVzdEJhdGlrIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKyAgICAgICAgbmV3IEJhdGlrVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkobmV3IERvY3VtZW50QnVpbGRlclNldHRpbmdbMF0pOworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3RDcmltc29uLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3RDcmltc29uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWU4ZmQzOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdENyaW1zb24uamF2YQpAQCAtMCwwICsxLDQ4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworcHVibGljIGNsYXNzIFRlc3RDcmltc29uIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGNyaW1zb25GYWN0b3J5ID0gKERvY3VtZW50QnVpbGRlckZhY3RvcnkpCisgICAgICBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLmFwYWNoZS5jcmltc29uLmpheHAuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeUltcGwiKS5uZXdJbnN0YW5jZSgpOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkoY3JpbXNvbkZhY3RvcnksCisgICAgICAgICAgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24xKCkpOworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3RDcmltc29uQWx0Q29uZmlnLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3RDcmltc29uQWx0Q29uZmlnLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWFjNGZjMAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdENyaW1zb25BbHRDb25maWcuamF2YQpAQCAtMCwwICsxLDQ4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworcHVibGljIGNsYXNzIFRlc3RDcmltc29uQWx0Q29uZmlnIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGNyaW1zb25GYWN0b3J5ID0gKERvY3VtZW50QnVpbGRlckZhY3RvcnkpCisgICAgICBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLmFwYWNoZS5jcmltc29uLmpheHAuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeUltcGwiKS5uZXdJbnN0YW5jZSgpOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkoY3JpbXNvbkZhY3RvcnksCisgICAgICAgICAgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24yKCkpOworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3RET000Si5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9UZXN0RE9NNEouamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NzY4NDJmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9UZXN0RE9NNEouamF2YQpAQCAtMCwwICsxLDQzIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTTRKVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmc7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKK3B1YmxpYyBjbGFzcyBUZXN0RE9NNEogZXh0ZW5kcyBUZXN0U3VpdGUgeworCisgIHB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbgorICB7CisgICAgQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmUuYWxsdGVzdHMiKTsKKyAgICBDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPSB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorICAgICAgICBuZXcgRE9NNEpUZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeShuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1swXSk7CisKKyAgICBPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisgICAgcmV0dXJuIG5ldyBKVW5pdFRlc3RTdWl0ZUFkYXB0ZXIoKERPTVRlc3RTdWl0ZSkgdGVzdCk7CisgIH0KKworCit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdERlZmF1bHRMUy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9UZXN0RGVmYXVsdExTLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWQ4NmNkNQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdERlZmF1bHRMUy5qYXZhCkBAIC0wLDAgKzEsNTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUKKyAqIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4KKyAqIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZSBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcworICogcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKKyAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKKyAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlCisgKiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CitpbXBvcnQgb3JnLnczYy5kb210cy5MU0RvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKy8qKgorICogVGVzdCBzdWl0ZSB0aGF0IHJ1bnMgYWxsIERPTSBMMiBDb3JlIHRlc3RzIHVzaW5nIHRoZQorICogRGVmYXVsdCBMUyBwYXJzZXIgaW4gZGVmYXVsdCBjb25maWd1cmF0aW9uLgorICogCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3REZWZhdWx0TFMgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisJcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwkJQ2xhc3MgdGVzdENsYXNzID0KKwkJCUNsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKAorCQkJCSJvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlLmFsbHRlc3RzIik7CisJCUNvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9CisJCQl0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IoCisJCQkJbmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworCQlET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKwkJCW5ldyBMU0RvY3VtZW50QnVpbGRlckZhY3RvcnkoCisJCQkJSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24xKCkpOworCisJCU9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKwkJcmV0dXJuIG5ldyBKVW5pdFRlc3RTdWl0ZUFkYXB0ZXIoKERPTVRlc3RTdWl0ZSkgdGVzdCk7CisJfQorCit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3REZWZhdWx0TFNBbHRDb25maWcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdERlZmF1bHRMU0FsdENvbmZpZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIyNTMzMDIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3REZWZhdWx0TFNBbHRDb25maWcuamF2YQpAQCAtMCwwICsxLDUxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlCisgKiBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuCisgKiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMKKyAqIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZCisgKiBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTCisgKiBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZQorICogaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5MU0RvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKKy8qKgorICogVGVzdCBzdWl0ZSB0aGF0IHJ1bnMgYWxsIERPTSBMMiBDb3JlIHRlc3RzIHVzaW5nIHRoZQorICogRGVmYXVsdCBMUyBwYXJzZXIgaW4gYW4gYWx0ZXJuYXRlIGNvbmZpZ3VyYXRpb24KKyAqIAorICogQGF1dGhvciBDdXJ0IEFybm9sZAorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0RGVmYXVsdExTQWx0Q29uZmlnIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworCXB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJCUNsYXNzIHRlc3RDbGFzcyA9CisJCQlDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygKKwkJCQkib3JnLnczYy5kb210cy5sZXZlbDIuY29yZS5hbGx0ZXN0cyIpOworCQlDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPQorCQkJdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKAorCQkJCW5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKwkJRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisJCQluZXcgTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KAorCQkJCUpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMigpKTsKKworCQlPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9UZXN0RGVmYXVsdFBhcnNlci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9UZXN0RGVmYXVsdFBhcnNlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJhOGIwOTMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3REZWZhdWx0UGFyc2VyLmphdmEKQEAgLTAsMCArMSw1MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiBUZXN0IHN1aXRlIHVzaW5nIHRoZSBkZWZhdWx0IEpBWFAgcGFyc2VyIGluIHRoZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24KKyAqIAorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0RGVmYXVsdFBhcnNlciBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKyAgLyoqCisgICAgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIHRlc3Qgc3VpdGUKKyAgICAqIEByZXR1cm4gbmV3IHRlc3Qgc3VpdGUKKyAgICAqIEBleGNlcHRpb24gRXhjZXB0aW9uIGlmIHRlc3RzIG9yIGltcGxlbWVudGF0aW9uIGNhbiBiZSBjcmVhdGVkLiAKKyAgICAqLworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKyAgICAgICAgbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeShudWxsLAorICAgICAgICAgIEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgfQorCisKK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9UZXN0RGVmYXVsdFBhcnNlckFsdENvbmZpZy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9UZXN0RGVmYXVsdFBhcnNlckFsdENvbmZpZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5YWMzYzYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3REZWZhdWx0UGFyc2VyQWx0Q29uZmlnLmphdmEKQEAgLTAsMCArMSw1NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworCisKKy8qKgorICogVGVzdCBzdWl0ZSB1c2luZyB0aGUgZGVmYXVsdCBKQVhQIHBhcnNlciBpbiB0aGUgYWx0ZXJuYXRpdmUgY29uZmlndXJhdGlvbgorICogCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3REZWZhdWx0UGFyc2VyQWx0Q29uZmlnIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgdGVzdCBzdWl0ZQorICAgICAqIEByZXR1cm4gbmV3IHRlc3Qgc3VpdGUKKyAgICAgKiBAZXhjZXB0aW9uIEV4Y2VwdGlvbiBpZiB0ZXN0cyBvciBpbXBsZW1lbnRhdGlvbiBjYW4gYmUgY3JlYXRlZC4gCisgICAgICovCisgICAgCisgIHB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbgorICB7CisgICAgQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmUuYWxsdGVzdHMiKTsKKyAgICBDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPSB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorICAgICAgICBuZXcgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5KG51bGwsCisgICAgICAgICAgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24yKCkpOworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3RHTlVKQVhQLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3RHTlVKQVhQLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzcwM2IzYwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdEdOVUpBWFAuamF2YQpAQCAtMCwwICsxLDUxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworcHVibGljIGNsYXNzIFRlc3RHTlVKQVhQIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKworICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZ251amF4cEZhY3RvcnkgPSAoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSkKKyAgICAgIENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkuCisgICAgICAgIGxvYWRDbGFzcygiZ251LnhtbC5kb20uSkFYUEZhY3RvcnkiKS5uZXdJbnN0YW5jZSgpOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkoZ251amF4cEZhY3RvcnksCisgICAgICAgICAgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24xKCkpOworCisKKyAgICBPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisgICAgcmV0dXJuIG5ldyBKVW5pdFRlc3RTdWl0ZUFkYXB0ZXIoKERPTVRlc3RTdWl0ZSkgdGVzdCk7CisgIH0KKworCit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdEdOVUpBWFBBbHRDb25maWcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdEdOVUpBWFBBbHRDb25maWcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNmE1YjU5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9UZXN0R05VSkFYUEFsdENvbmZpZy5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworCitwdWJsaWMgY2xhc3MgVGVzdEdOVUpBWFBBbHRDb25maWcgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisgIHB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbgorICB7CisgICAgQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmUuYWxsdGVzdHMiKTsKKyAgICBDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPSB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZ251amF4cEZhY3RvcnkgPSAoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSkKKyAgICAgIENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkuCisgICAgICAgIGxvYWRDbGFzcygiZ251LnhtbC5kb20uSkFYUEZhY3RvcnkiKS5uZXdJbnN0YW5jZSgpOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkoZ251amF4cEZhY3RvcnksCisgICAgICAgICAgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24yKCkpOworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3RKVGlkeS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9UZXN0SlRpZHkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43N2UyNDBkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9UZXN0SlRpZHkuamF2YQpAQCAtMCwwICsxLDQxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZzsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpUaWR5RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworcHVibGljIGNsYXNzIFRlc3RKVGlkeSBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKyAgcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uCisgIHsKKyAgICBDbGFzcyB0ZXN0Q2xhc3MgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLnczYy5kb210cy5sZXZlbDIuY29yZS5hbGx0ZXN0cyIpOworICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9IHRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBKVGlkeURvY3VtZW50QnVpbGRlckZhY3RvcnkobmV3IERvY3VtZW50QnVpbGRlclNldHRpbmdbMF0pOworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdE9yYWNsZS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9UZXN0T3JhY2xlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2YxYzllOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdE9yYWNsZS5qYXZhCkBAIC0wLDAgKzEsNjMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YKKyAqIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4KKyAqIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZSBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcworICogcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKKyAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKKyAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlCisgKiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworCisvKioKKyAqIFRlc3Qgc3VpdGUgdGhhdCBydW5zIGFsbCBET00gTDIgQ29yZSB0ZXN0cyB1c2luZyB0aGUKKyAqIE9yYWNsZSBQYXJzZXIgZm9yIEphdmEgaW4gZGVmYXVsdCBjb25maWd1cmF0aW9uLgorICoKKyAqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0T3JhY2xlIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0b3IKKyAgICAgICAgICogQHJldHVybiB0ZXN0IHN1aXRlCisgICAgICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgIENsYXNzIHRlc3RDbGFzcyA9CisgICAgICAgICAgICAgICAgICAgICAgICBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmUuYWxsdGVzdHMiKTsKKyAgICAgICAgICAgICAgICBDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPQorICAgICAgICAgICAgICAgICAgICAgICAgdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisgICAgICAgICAgICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBvcmFjbGVGYWN0b3J5ID0KKyAgICAgICAgICAgICAgICAgICAgICAgIChEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KSBDbGFzc0xvYWRlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubG9hZENsYXNzKCJvcmFjbGUueG1sLmpheHAuSlhEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm5ld0luc3RhbmNlKCk7CisKKyAgICAgICAgICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yYWNsZUZhY3RvcnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworICAgICAgICAgICAgICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgICAgICAgfQorCit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3RPcmFjbGVBbHRDb25maWcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdE9yYWNsZUFsdENvbmZpZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgwZDk1MWUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3RPcmFjbGVBbHRDb25maWcuamF2YQpAQCAtMCwwICsxLDYyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mCisgKiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuCisgKiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMKKyAqIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZCisgKiBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTCisgKiBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZQorICogaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiBUZXN0IHN1aXRlIHRoYXQgcnVucyBhbGwgRE9NIEwyIENvcmUgdGVzdHMgdXNpbmcgdGhlCisgKiBPcmFjbGUgUGFyc2VyIGZvciBKYXZhIGluIGRlZmF1bHQgY29uZmlndXJhdGlvbi4KKyAqCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKgorICovCitwdWJsaWMgY2xhc3MgVGVzdE9yYWNsZUFsdENvbmZpZyBleHRlbmRzIFRlc3RTdWl0ZSB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBDb25zdHJ1Y3RvcgorICAgICAgICAgKiBAcmV0dXJuIHRlc3Qgc3VpdGUKKyAgICAgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgQ2xhc3MgdGVzdENsYXNzID0KKyAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3JnLnczYy5kb210cy5sZXZlbDIuY29yZS5hbGx0ZXN0cyIpOworICAgICAgICAgICAgICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9CisgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IG9yYWNsZUZhY3RvcnkgPQorICAgICAgICAgICAgICAgICAgICAgICAgKERvY3VtZW50QnVpbGRlckZhY3RvcnkpIENsYXNzTG9hZGVyCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5sb2FkQ2xhc3MoIm9yYWNsZS54bWwuamF4cC5KWERvY3VtZW50QnVpbGRlckZhY3RvcnkiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubmV3SW5zdGFuY2UoKTsKKworICAgICAgICAgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JhY2xlRmFjdG9yeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24yKCkpOworCisgICAgICAgICAgICAgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICAgICAgICB9CisKK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdFhlcmNlcy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9UZXN0WGVyY2VzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDRjODY3OAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdFhlcmNlcy5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworCitwdWJsaWMgY2xhc3MgVGVzdFhlcmNlcyBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKyAgcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uCisgIHsKKyAgICBDbGFzcyB0ZXN0Q2xhc3MgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLnczYy5kb210cy5sZXZlbDIuY29yZS5hbGx0ZXN0cyIpOworICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9IHRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB4ZXJjZXNGYWN0b3J5ID0gKERvY3VtZW50QnVpbGRlckZhY3RvcnkpCisgICAgICBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLmFwYWNoZS54ZXJjZXMuamF4cC5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbCIpLm5ld0luc3RhbmNlKCk7CisKKyAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKyAgICAgICAgbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSh4ZXJjZXNGYWN0b3J5LAorICAgICAgICAgIEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3RYZXJjZXNBbHRDb25maWcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvVGVzdFhlcmNlc0FsdENvbmZpZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE3MDY3YmIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL1Rlc3RYZXJjZXNBbHRDb25maWcuamF2YQpAQCAtMCwwICsxLDQ4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworcHVibGljIGNsYXNzIFRlc3RYZXJjZXNBbHRDb25maWcgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisgIHB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbgorICB7CisgICAgQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmUuYWxsdGVzdHMiKTsKKyAgICBDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPSB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgeGVyY2VzRmFjdG9yeSA9IChEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KQorICAgICAgQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy5hcGFjaGUueGVyY2VzLmpheHAuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeUltcGwiKS5uZXdJbnN0YW5jZSgpOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkoeGVyY2VzRmFjdG9yeSwKKyAgICAgICAgICBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisKKyAgICBPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisgICAgcmV0dXJuIG5ldyBKVW5pdFRlc3RTdWl0ZUFkYXB0ZXIoKERPTVRlc3RTdWl0ZSkgdGVzdCk7CisgIH0KKworCit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvYWxsdGVzdHMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvYWxsdGVzdHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YWFmMTNiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9hbGx0ZXN0cy5qYXZhCkBAIC0wLDAgKzEsMzUwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U2luazsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKy8qKgorICogCisqIEBhdXRob3IgRE9NIFRlc3QgU3VpdGUgUHJvamVjdAorKi8KK3B1YmxpYyBjbGFzcyBhbGx0ZXN0cyBleHRlbmRzIERPTVRlc3RTdWl0ZSB7CisKKyAgICAvKioKKyAgICAqIENvbnN0cnVjdG9yCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3MgRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggc2V0dGluZ3MKKyAgICAqLworICAgcHVibGljIGFsbHRlc3RzKERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpIHRocm93cyBFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAgIHNldEZhY3RvcnkoZmFjdG9yeSk7CisgICB9CisKKyAgIC8qKgorICAgICogICBCdWlsZCB0ZXN0IHN1aXRlIGJ5IGFkZGluZyBlYWNoIHRlc3QgdG8gdGhlIHRlc3Qgc2luaworICAgICogICBAcGFyYW0gc2luayB0ZXN0IHNpbmsKKyAgICAqLworICAgcHVibGljIHZvaWQgYnVpbGQoRE9NVGVzdFNpbmsgc2luaykgeworLy8gICAgICBzaW5rLmFkZFRlc3QoYXR0cmdldG93bmVyZWxlbWVudDAxLmNsYXNzKTsgLy8gIGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb246IE5vIHZhbGlkYXRpbmcgRG9jdW1lbnRCdWlsZGVyIGltcGxlbWVudGF0aW9uIGF2YWlsYWJsZQorICAgICAgc2luay5hZGRUZXN0KGF0dHJnZXRvd25lcmVsZW1lbnQwMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoYXR0cmdldG93bmVyZWxlbWVudDAzLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChhdHRyZ2V0b3duZXJlbGVtZW50MDQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGF0dHJnZXRvd25lcmVsZW1lbnQwNS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY3JlYXRlQXR0cmlidXRlTlMwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY3JlYXRlQXR0cmlidXRlTlMwMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY3JlYXRlQXR0cmlidXRlTlMwMy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY3JlYXRlQXR0cmlidXRlTlMwNC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY3JlYXRlQXR0cmlidXRlTlMwNS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChjcmVhdGVBdHRyaWJ1dGVOUzA2LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChjcmVhdGVEb2N1bWVudDAxLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChjcmVhdGVEb2N1bWVudDAyLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGNyZWF0ZURvY3VtZW50MDMuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoY3JlYXRlRG9jdW1lbnQwNC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY3JlYXRlRG9jdW1lbnQwNS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY3JlYXRlRG9jdW1lbnQwNi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY3JlYXRlRG9jdW1lbnQwNy5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChjcmVhdGVEb2N1bWVudDA4LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChjcmVhdGVEb2N1bWVudFR5cGUwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY3JlYXRlRG9jdW1lbnRUeXBlMDIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGNyZWF0ZURvY3VtZW50VHlwZTAzLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGNyZWF0ZURvY3VtZW50VHlwZTA0LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChjcmVhdGVFbGVtZW50TlMwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY3JlYXRlRWxlbWVudE5TMDIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGNyZWF0ZUVsZW1lbnROUzAzLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChjcmVhdGVFbGVtZW50TlMwNC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoY3JlYXRlRWxlbWVudE5TMDUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzAyLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA1LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDYuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwNS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwNi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRnZXRlbGVtZW50YnlpZDAxLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzAzLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwNC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRpbXBvcnRub2RlMDEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50aW1wb3J0bm9kZTAyLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50aW1wb3J0bm9kZTAzLmNsYXNzKTsgLy8gamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjogTm8gdmFsaWRhdGluZyBEb2N1bWVudEJ1aWxkZXIgaW1wbGVtZW50YXRpb24gYXZhaWxhYmxlCisvLyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGltcG9ydG5vZGUwNC5jbGFzcyk7IC8vIGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb246IE5vIHZhbGlkYXRpbmcgRG9jdW1lbnRCdWlsZGVyIGltcGxlbWVudGF0aW9uIGF2YWlsYWJsZQorICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50aW1wb3J0bm9kZTA1LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGltcG9ydG5vZGUwNi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRpbXBvcnRub2RlMDcuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50aW1wb3J0bm9kZTA4LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGltcG9ydG5vZGUwOS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRpbXBvcnRub2RlMTAuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50aW1wb3J0bm9kZTExLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGltcG9ydG5vZGUxMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRpbXBvcnRub2RlMTMuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRpbXBvcnRub2RlMTQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50aW1wb3J0bm9kZTE1LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChkb2N1bWVudGltcG9ydG5vZGUxNy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRpbXBvcnRub2RlMTguY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRpbXBvcnRub2RlMTkuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRpbXBvcnRub2RlMjAuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRpbXBvcnRub2RlMjEuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZG9jdW1lbnRpbXBvcnRub2RlMjIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50dHlwZWludGVybmFsU3Vic2V0MDEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50dHlwZXB1YmxpY2lkMDEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvY3VtZW50dHlwZXN5c3RlbWlkMDEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwMy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudDA0LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwNy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwNC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9taW1wbGVtZW50YXRpb25mZWF0dXJlY29yZS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZG9taW1wbGVtZW50YXRpb25mZWF0dXJleG1sdmVyc2lvbjIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGRvbWltcGxlbWVudGF0aW9uaGFzZmVhdHVyZTAxLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChkb21pbXBsZW1lbnRhdGlvbmhhc2ZlYXR1cmUwMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAxLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50Z2V0YXR0cmlidXRlbm9kZW5zMDIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAzLmNsYXNzKTsgLy8gamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjogTm8gdmFsaWRhdGluZyBEb2N1bWVudEJ1aWxkZXIgaW1wbGVtZW50YXRpb24gYXZhaWxhYmxlCisvLyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50Z2V0YXR0cmlidXRlbnMwMi5jbGFzcyk7IC8vIGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb246IE5vIHZhbGlkYXRpbmcgRG9jdW1lbnRCdWlsZGVyIGltcGxlbWVudGF0aW9uIGF2YWlsYWJsZQorICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5zMDIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5zMDQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5zMDUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRoYXNhdHRyaWJ1dGUwMS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50aGFzYXR0cmlidXRlMDIuY2xhc3MpOyAvLyBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOiBObyB2YWxpZGF0aW5nIERvY3VtZW50QnVpbGRlciBpbXBsZW1lbnRhdGlvbiBhdmFpbGFibGUKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50aGFzYXR0cmlidXRlMDMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRoYXNhdHRyaWJ1dGUwNC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50aGFzYXR0cmlidXRlbnMwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudGhhc2F0dHJpYnV0ZW5zMDIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRoYXNhdHRyaWJ1dGVuczAzLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50cmVtb3ZlYXR0cmlidXRlbnMwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczAxLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczA0LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDUuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczA2LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50c2V0YXR0cmlidXRlbnMwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudHNldGF0dHJpYnV0ZW5zMDIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRzZXRhdHRyaWJ1dGVuczAzLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50c2V0YXR0cmlidXRlbnMwNC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZWxlbWVudHNldGF0dHJpYnV0ZW5zMDUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGVsZW1lbnRzZXRhdHRyaWJ1dGVuczA4LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChlbGVtZW50c2V0YXR0cmlidXRlbnN1cmludWxsLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGdldEF0dHJpYnV0ZU5TMDEuY2xhc3MpOyAvLyBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOiBObyB2YWxpZGF0aW5nIERvY3VtZW50QnVpbGRlciBpbXBsZW1lbnRhdGlvbiBhdmFpbGFibGUKKyAgICAgIHNpbmsuYWRkVGVzdChnZXRBdHRyaWJ1dGVOUzAyLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChnZXRBdHRyaWJ1dGVOUzAzLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChnZXRBdHRyaWJ1dGVOUzA0LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChnZXRBdHRyaWJ1dGVOUzA1LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChnZXRBdHRyaWJ1dGVOb2RlTlMwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZ2V0QXR0cmlidXRlTm9kZU5TMDIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZ2V0RWxlbWVudEJ5SWQwMS5jbGFzcyk7IC8vIGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb246IE5vIHZhbGlkYXRpbmcgRG9jdW1lbnRCdWlsZGVyIGltcGxlbWVudGF0aW9uIGF2YWlsYWJsZQorICAgICAgc2luay5hZGRUZXN0KGdldEVsZW1lbnRCeUlkMDIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzAxLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChnZXRFbGVtZW50c0J5VGFnTmFtZU5TMDIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGdldEVsZW1lbnRzQnlUYWdOYW1lTlMwMy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA0LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChnZXRFbGVtZW50c0J5VGFnTmFtZU5TMDUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGdldEVsZW1lbnRzQnlUYWdOYW1lTlMwNi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA3LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChnZXRFbGVtZW50c0J5VGFnTmFtZU5TMDguY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGdldEVsZW1lbnRzQnlUYWdOYW1lTlMwOS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzEwLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChnZXRFbGVtZW50c0J5VGFnTmFtZU5TMTEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGdldEVsZW1lbnRzQnlUYWdOYW1lTlMxMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzEzLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChnZXRFbGVtZW50c0J5VGFnTmFtZU5TMTQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGdldE5hbWVkSXRlbU5TMDEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGdldE5hbWVkSXRlbU5TMDIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoZ2V0TmFtZWRJdGVtTlMwMy5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChnZXROYW1lZEl0ZW1OUzA0LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoYXNBdHRyaWJ1dGUwMS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoYXNBdHRyaWJ1dGUwMi5jbGFzcyk7IC8vIGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb246IE5vIHZhbGlkYXRpbmcgRG9jdW1lbnRCdWlsZGVyIGltcGxlbWVudGF0aW9uIGF2YWlsYWJsZQorICAgICAgc2luay5hZGRUZXN0KGhhc0F0dHJpYnV0ZTAzLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhhc0F0dHJpYnV0ZTA0LmNsYXNzKTsgLy8gamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjogTm8gdmFsaWRhdGluZyBEb2N1bWVudEJ1aWxkZXIgaW1wbGVtZW50YXRpb24gYXZhaWxhYmxlCisgICAgICBzaW5rLmFkZFRlc3QoaGFzQXR0cmlidXRlTlMwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGFzQXR0cmlidXRlTlMwMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGFzQXR0cmlidXRlTlMwMy5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChoYXNBdHRyaWJ1dGVOUzA0LmNsYXNzKTsgLy8gamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjogTm8gdmFsaWRhdGluZyBEb2N1bWVudEJ1aWxkZXIgaW1wbGVtZW50YXRpb24gYXZhaWxhYmxlCisgICAgICBzaW5rLmFkZFRlc3QoaGFzQXR0cmlidXRlTlMwNS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGFzQXR0cmlidXRlczAxLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoYXNBdHRyaWJ1dGVzMDIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfZW50aXRpZXNyZW1vdmVuYW1lZGl0ZW1uczEuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfZW50aXRpZXNzZXRuYW1lZGl0ZW1uczEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGhjX25hbWVkbm9kZW1hcGludmFsaWR0eXBlMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaGNfbm9kZWRvY3VtZW50ZnJhZ21lbnRub3JtYWxpemUxLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChoY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vcm1hbGl6ZTIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaGNfbm90YXRpb25zcmVtb3ZlbmFtZWRpdGVtbnMxLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGhjX25vdGF0aW9uc3NldG5hbWVkaXRlbW5zMS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChpbXBvcnROb2RlMDEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGltcG9ydE5vZGUwMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaW1wb3J0Tm9kZTAzLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChpbXBvcnROb2RlMDQuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaW1wb3J0Tm9kZTA1LmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGltcG9ydE5vZGUwNi5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChpbXBvcnROb2RlMDcuY2xhc3MpOyAvLyBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOiBObyB2YWxpZGF0aW5nIERvY3VtZW50QnVpbGRlciBpbXBsZW1lbnRhdGlvbiBhdmFpbGFibGUKKyAgICAgIHNpbmsuYWRkVGVzdChpbXBvcnROb2RlMDguY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaW1wb3J0Tm9kZTA5LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChpbXBvcnROb2RlMTAuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QoaW1wb3J0Tm9kZTExLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KGltcG9ydE5vZGUxMi5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChpbXBvcnROb2RlMTMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGltcG9ydE5vZGUxNC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaW1wb3J0Tm9kZTE1LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChpbXBvcnROb2RlMTYuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGltcG9ydE5vZGUxNy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaW50ZXJuYWxTdWJzZXQwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaXNTdXBwb3J0ZWQwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaXNTdXBwb3J0ZWQwMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaXNTdXBwb3J0ZWQwNC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaXNTdXBwb3J0ZWQwNS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaXNTdXBwb3J0ZWQwNi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaXNTdXBwb3J0ZWQwNy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaXNTdXBwb3J0ZWQwOS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaXNTdXBwb3J0ZWQxMC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaXNTdXBwb3J0ZWQxMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaXNTdXBwb3J0ZWQxMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaXNTdXBwb3J0ZWQxMy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QoaXNTdXBwb3J0ZWQxNC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobG9jYWxOYW1lMDEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KGxvY2FsTmFtZTAyLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChsb2NhbE5hbWUwMy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobG9jYWxOYW1lMDQuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwMy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwNC5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwNS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwNi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczAyLmNsYXNzKTsgLy8gamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjogTm8gdmFsaWRhdGluZyBEb2N1bWVudEJ1aWxkZXIgaW1wbGVtZW50YXRpb24gYXZhaWxhYmxlCisgICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMy5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA0LmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDUuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDYuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDcuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDguY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDkuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDQuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwOC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA5LmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMTAuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QobmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMxMS5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChuYW1lc3BhY2VVUkkwMS5jbGFzcyk7IC8vIGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb246IE5vIHZhbGlkYXRpbmcgRG9jdW1lbnRCdWlsZGVyIGltcGxlbWVudGF0aW9uIGF2YWlsYWJsZQorICAgICAgc2luay5hZGRUZXN0KG5hbWVzcGFjZVVSSTAyLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChuYW1lc3BhY2VVUkkwMy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QobmFtZXNwYWNlVVJJMDQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVnZXRsb2NhbG5hbWUwMy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWdldG5hbWVzcGFjZXVyaTAzLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlZ2V0b3duZXJkb2N1bWVudDAxLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlZ2V0b3duZXJkb2N1bWVudDAyLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlZ2V0cHJlZml4MDMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVoYXNhdHRyaWJ1dGVzMDEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVoYXNhdHRyaWJ1dGVzMDIuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVoYXNhdHRyaWJ1dGVzMDMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVoYXNhdHRyaWJ1dGVzMDQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVpc3N1cHBvcnRlZDAxLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlaXNzdXBwb3J0ZWQwMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZWlzc3VwcG9ydGVkMDMuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVpc3N1cHBvcnRlZDA0LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2RlaXNzdXBwb3J0ZWQwNS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZW5vcm1hbGl6ZTAxLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2Rlc2V0cHJlZml4MDEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVzZXRwcmVmaXgwMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZXNldHByZWZpeDAzLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KG5vZGVzZXRwcmVmaXgwNC5jbGFzcyk7IC8vIGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb246IE5vIHZhbGlkYXRpbmcgRG9jdW1lbnRCdWlsZGVyIGltcGxlbWVudGF0aW9uIGF2YWlsYWJsZQorICAgICAgc2luay5hZGRUZXN0KG5vZGVzZXRwcmVmaXgwNS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qobm9kZXNldHByZWZpeDA2LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChub2Rlc2V0cHJlZml4MDcuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vZGVzZXRwcmVmaXgwOC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChub2Rlc2V0cHJlZml4MDkuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG5vcm1hbGl6ZTAxLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChvd25lckRvY3VtZW50MDEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KG93bmVyRWxlbWVudDAxLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChvd25lckVsZW1lbnQwMi5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QocHJlZml4MDEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KHByZWZpeDAyLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChwcmVmaXgwMy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QocHJlZml4MDQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KHByZWZpeDA1LmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KHByZWZpeDA2LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChwcmVmaXgwNy5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChwcmVmaXgwOC5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChwcmVmaXgwOS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3QocHJlZml4MTAuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KHByZWZpeDExLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChwdWJsaWNJZDAxLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KHJlbW92ZUF0dHJpYnV0ZU5TMDEuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QocmVtb3ZlQXR0cmlidXRlTlMwMi5jbGFzcyk7IC8vIGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb246IE5vIHZhbGlkYXRpbmcgRG9jdW1lbnRCdWlsZGVyIGltcGxlbWVudGF0aW9uIGF2YWlsYWJsZQorICAgICAgc2luay5hZGRUZXN0KHJlbW92ZU5hbWVkSXRlbU5TMDEuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KHJlbW92ZU5hbWVkSXRlbU5TMDIuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3QocmVtb3ZlTmFtZWRJdGVtTlMwMy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qoc2V0QXR0cmlidXRlTlMwMS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qoc2V0QXR0cmlidXRlTlMwMi5jbGFzcyk7CisvLyAgICAgIHNpbmsuYWRkVGVzdChzZXRBdHRyaWJ1dGVOUzAzLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChzZXRBdHRyaWJ1dGVOUzA0LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChzZXRBdHRyaWJ1dGVOUzA1LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChzZXRBdHRyaWJ1dGVOUzA2LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChzZXRBdHRyaWJ1dGVOUzA3LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChzZXRBdHRyaWJ1dGVOUzA5LmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KHNldEF0dHJpYnV0ZU5TMTAuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KHNldEF0dHJpYnV0ZU5vZGVOUzAxLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KHNldEF0dHJpYnV0ZU5vZGVOUzAyLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChzZXRBdHRyaWJ1dGVOb2RlTlMwMy5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qoc2V0QXR0cmlidXRlTm9kZU5TMDQuY2xhc3MpOworICAgICAgc2luay5hZGRUZXN0KHNldEF0dHJpYnV0ZU5vZGVOUzA1LmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChzZXROYW1lZEl0ZW1OUzAxLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChzZXROYW1lZEl0ZW1OUzAyLmNsYXNzKTsKKyAgICAgIHNpbmsuYWRkVGVzdChzZXROYW1lZEl0ZW1OUzAzLmNsYXNzKTsKKy8vICAgICAgc2luay5hZGRUZXN0KHNldE5hbWVkSXRlbU5TMDQuY2xhc3MpOworLy8gICAgICBzaW5rLmFkZFRlc3Qoc2V0TmFtZWRJdGVtTlMwNS5jbGFzcyk7CisgICAgICBzaW5rLmFkZFRlc3Qoc3lzdGVtSWQwMS5jbGFzcyk7CisKKyAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdCBzdWl0ZQorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdCBzdWl0ZQorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9hbGx0ZXN0cyI7CisgICB9CisKKyAgIC8qKgorICAgICogUnVucyBpbmRpdmlkdWFsIHRlc3QKKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oYWxsdGVzdHMuY2xhc3MsIGFyZ3MpOworICAgfQorCit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2F0dHJnZXRvd25lcmVsZW1lbnQwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9hdHRyZ2V0b3duZXJlbGVtZW50MDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZjIyNDIwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9hdHRyZ2V0b3duZXJlbGVtZW50MDEuamF2YQpAQCAtMCwwICsxLDEwNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgImdldE93bmVyRWxlbWVudCgpIiB3aWxsIHJldHVybiB0aGUgRWxlbWVudCBub2RlIHRoaXMgYXR0cmlidXRlIGlzIGF0dGFjaGVkIHRvIG9yIAorICogIG51bGwgaWYgdGhpcyBhdHRyaWJ1dGUgaXMgbm90IGluIHVzZS4gIAorICogICAKKyAqICAgIFJldHJlaXZlIHRoZSBkZWZhdWx0IGF0dHJpYnV0ZSBkZWZhdWx0QXR0ciBhbmQgY2hlY2sgaXRzIG93bmVyIGVsZW1lbnQuICBWZXJpZnkgaWYgdGhlIG5hbWUKKyAqICAgIHRoZSBub2RlTmFtZSBvZiB0aGUgcmV0dXJuZWQgb3duZXJFbGVtZW50IGlzIGVtcDplbXBsb3llZS4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNBdHRyLW93bmVyRWxlbWVudCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0F0dHItb3duZXJFbGVtZW50PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGF0dHJnZXRvd25lcmVsZW1lbnQwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgYXR0cmdldG93bmVyZWxlbWVudDAxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlLAorb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLnZhbGlkYXRpbmcKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBBdHRyIGF0dHI7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBFbGVtZW50IG93bmVyRWxlbWVudDsKKyAgICAgIFN0cmluZyBvd25lckVsZW1lbnROYW1lOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImVtcGxveWVlIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBhdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtTlMobnVsbE5TLCAiZGVmYXVsdEF0dHIiKTsKKyAgICAgIG93bmVyRWxlbWVudCA9IGF0dHIuZ2V0T3duZXJFbGVtZW50KCk7CisgICAgICBvd25lckVsZW1lbnROYW1lID0gb3duZXJFbGVtZW50LmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJnZXRvd25lcmVsZW1lbnQwMSIsICJlbXA6ZW1wbG95ZWUiLCBvd25lckVsZW1lbnROYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvYXR0cmdldG93bmVyZWxlbWVudDAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihhdHRyZ2V0b3duZXJlbGVtZW50MDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2F0dHJnZXRvd25lcmVsZW1lbnQwMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9hdHRyZ2V0b3duZXJlbGVtZW50MDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYzRmOTM5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9hdHRyZ2V0b3duZXJlbGVtZW50MDIuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgIFRoZSAiZ2V0T3duZXJFbGVtZW50KCkiIHdpbGwgcmV0dXJuIHRoZSBFbGVtZW50IG5vZGUgdGhpcyBhdHRyaWJ1dGUKKyAqICAgaXMgYXR0YWNoZWQgdG8gb3IgbnVsbCBpZiB0aGlzIGF0dHJpYnV0ZSBpcyBub3QgaW4gdXNlLiAgCisgKiAgIAorICogICBDcmVhdGUgYSBuZXcgZWxlbWVudCBhbmQgYXR0cmlidXRlIG5vZGUsIGF0dGFjaCB0aGUgYXR0cmlidXRlIHRvIHRoZSBlbGVtZW50LgorICogICBDaGVjayB0aGUgdmFsdWUgb2Ygb3duZXIgZWxlbWVudCBvZiB0aGUgbmV3IGF0dHJpYnV0ZSBub2RlCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQXR0ci1vd25lckVsZW1lbnQiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNBdHRyLW93bmVyRWxlbWVudDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgYXR0cmdldG93bmVyZWxlbWVudDAyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBhdHRyZ2V0b3duZXJlbGVtZW50MDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBFbGVtZW50IG93bmVyRWxlbWVudDsKKyAgICAgIFN0cmluZyBvd25lckVsZW1lbnROYW1lOworICAgICAgQXR0ciBhdHRyOworICAgICAgQXR0ciBuZXdBdHRyOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCJyb290Iik7CisgICAgICBhdHRyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vTDEiLCAiTDE6YXR0Iik7CisgICAgICBuZXdBdHRyID0gZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMoYXR0cik7CisgICAgICBvd25lckVsZW1lbnQgPSBhdHRyLmdldE93bmVyRWxlbWVudCgpOworICAgICAgb3duZXJFbGVtZW50TmFtZSA9IG93bmVyRWxlbWVudC5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzSWdub3JlQ2FzZSgiYXR0cmdldG93bmVyZWxlbWVudDAyIiwgInJvb3QiLCBvd25lckVsZW1lbnROYW1lKTsKK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvYXR0cmdldG93bmVyZWxlbWVudDAyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihhdHRyZ2V0b3duZXJlbGVtZW50MDIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2F0dHJnZXRvd25lcmVsZW1lbnQwMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9hdHRyZ2V0b3duZXJlbGVtZW50MDMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMDM3OGQ4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9hdHRyZ2V0b3duZXJlbGVtZW50MDMuamF2YQpAQCAtMCwwICsxLDEwMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKworKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCisKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKworSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAorCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisKK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCisKK1BVUlBPU0UuICAKKworCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgVGhlICJnZXRPd25lckVsZW1lbnQoKSIgd2lsbCByZXR1cm4gdGhlIEVsZW1lbnQgbm9kZSB0aGlzIGF0dHJpYnV0ZQorICogICBpcyBhdHRhY2hlZCB0byBvciBudWxsIGlmIHRoaXMgYXR0cmlidXRlIGlzIG5vdCBpbiB1c2UuICAKKyAqICAgCisgKiAgIENyZWF0ZSBhIG5ldyBhdHRyaWJ1dGUgbm9kZSBmb3IgdGhpcyBkb2N1bWVudCBub2RlLiAgU2luY2UgdGhlIG5ld2x5IGF0dHJpYnV0ZSBpcworICogICBub3QgaXQgdXNlIGl0cyBvd25lciBlbGVtZW50IHNob3VsZCBiZSBudWxsLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0F0dHItb3duZXJFbGVtZW50Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQXR0ci1vd25lckVsZW1lbnQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGF0dHJnZXRvd25lcmVsZW1lbnQwMyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgYXR0cmdldG93bmVyZWxlbWVudDAzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBvd25lckVsZW1lbnQ7CisgICAgICBBdHRyIGF0dHI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBhdHRyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00iLCAiZG9tOmF0dHIiKTsKKyAgICAgIG93bmVyRWxlbWVudCA9IGF0dHIuZ2V0T3duZXJFbGVtZW50KCk7CisgICAgICBhc3NlcnROdWxsKCJhdHRyZ2V0b3duZXJlbGVtZW50MDMiLCBvd25lckVsZW1lbnQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9hdHRyZ2V0b3duZXJlbGVtZW50MDMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGF0dHJnZXRvd25lcmVsZW1lbnQwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvYXR0cmdldG93bmVyZWxlbWVudDA0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2F0dHJnZXRvd25lcmVsZW1lbnQwNC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkxN2EwNWEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2F0dHJnZXRvd25lcmVsZW1lbnQwNC5qYXZhCkBAIC0wLDAgKzEsMTAyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgIFRoZSAiZ2V0T3duZXJFbGVtZW50KCkiIHdpbGwgcmV0dXJuIHRoZSBFbGVtZW50IG5vZGUgdGhpcyBhdHRyaWJ1dGUgaXMgYXR0YWNoZWQgdG8gb3IgCisgKiAgIG51bGwgaWYgdGhpcyBhdHRyaWJ1dGUgaXMgbm90IGluIHVzZS4gIAorICogICBJbXBvcnQgYW4gYXR0cmlidXRlIG5vZGUgdG8gYW5vdGhlciBkb2N1bWVudC4gIElmIGFuIEF0dHIgbm9kZSBpcyBpbXBvcnRlZCwgaXRzIAorICogICBvd25lckVsZW1lbnQgYXR0cmlidXRlIHNob3VsZCBiZSBzZXQgdG8gbnVsbC4gIFZlcmlmeSBpZiB0aGUgb3duZXJFbGVtZW50IGhhcyBiZWVuIHNldCAKKyAqICAgdG8gbnVsbC4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNBdHRyLW93bmVyRWxlbWVudCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0F0dHItb3duZXJFbGVtZW50PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBhdHRyZ2V0b3duZXJlbGVtZW50MDQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGF0dHJnZXRvd25lcmVsZW1lbnQwNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBkb2NJbXA7CisgICAgICBOb2RlIG93bmVyRWxlbWVudDsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cjsKKyAgICAgIEF0dHIgYXR0ckltcDsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NlczsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGRvY0ltcCA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBhZGRyZXNzZXMgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJhZGRyZXNzIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGFkZHJlc3Nlcy5pdGVtKDEpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkcmVzc05vdE51bGwiLCBlbGVtZW50KTsKKyAgICAgIGF0dHIgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5vZGVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJ6b25lIik7CisgICAgICBhdHRySW1wID0gKEF0dHIpIGRvY0ltcC5pbXBvcnROb2RlKGF0dHIsIHRydWUpOworICAgICAgb3duZXJFbGVtZW50ID0gYXR0ckltcC5nZXRPd25lckVsZW1lbnQoKTsKKyAgICAgIGFzc2VydE51bGwoImF0dHJnZXRvd25lcmVsZW1lbnQwNCIsIG93bmVyRWxlbWVudCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2F0dHJnZXRvd25lcmVsZW1lbnQwNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oYXR0cmdldG93bmVyZWxlbWVudDA0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9hdHRyZ2V0b3duZXJlbGVtZW50MDUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvYXR0cmdldG93bmVyZWxlbWVudDA1LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWUwMjc4NgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvYXR0cmdldG93bmVyZWxlbWVudDA1LmphdmEKQEAgLTAsMCArMSwxMDkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgIFRoZSAiZ2V0T3duZXJFbGVtZW50KCkiIHdpbGwgcmV0dXJuIHRoZSBFbGVtZW50IG5vZGUgdGhpcyBhdHRyaWJ1dGUgaXMgYXR0YWNoZWQgdG8gCisgKiAgIG9yIG51bGwgaWYgdGhpcyBhdHRyaWJ1dGUgaXMgbm90IGluIHVzZS4gIAorICogICAKKyAqICAgUmV0cmVpdmUgYW4gZWxlbWVudCBhbmQgaXRzIGF0dHJpYnV0ZXMuICBUaGVuIHJlbW92ZSB0aGUgZWxlbWVudCBhbmQgY2hlY2sgdGhlIG5hbWUgb2YgCisgKiAgIHRoZSBvd25lckVsZW1lbnQgb2YgYXR0cmlidXRlIG9mIHRoZSBhdHRyaWJ1dGUgInN0cmVldCIuICAKKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNBdHRyLW93bmVyRWxlbWVudCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0F0dHItb3duZXJFbGVtZW50PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGF0dHJnZXRvd25lcmVsZW1lbnQwNSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgYXR0cmdldG93bmVyZWxlbWVudDA1KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIGVsZW1lbnQ7CisgICAgICBFbGVtZW50IG93bmVyRWxlbWVudDsKKyAgICAgIEVsZW1lbnQgcGFyZW50RWxlbWVudDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgU3RyaW5nIG93bmVyRWxlbWVudE5hbWU7CisgICAgICBBdHRyIGF0dHI7CisgICAgICBOb2RlIHJlbW92ZWRDaGlsZDsKKyAgICAgIE5hbWVkTm9kZU1hcCBub2RlTWFwOworICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJhZGRyZXNzIik7CisgICAgICBlbGVtZW50ID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIHBhcmVudEVsZW1lbnQgPSAoRWxlbWVudCkgZWxlbWVudC5nZXRQYXJlbnROb2RlKCk7CisgICAgICBub2RlTWFwID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICByZW1vdmVkQ2hpbGQgPSBwYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKGVsZW1lbnQpOworICAgICAgYXR0ciA9IChBdHRyKSBub2RlTWFwLmdldE5hbWVkSXRlbU5TKG51bGxOUywgInN0cmVldCIpOworICAgICAgb3duZXJFbGVtZW50ID0gYXR0ci5nZXRPd25lckVsZW1lbnQoKTsKKyAgICAgIG93bmVyRWxlbWVudE5hbWUgPSBvd25lckVsZW1lbnQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0cmdldG93bmVyZWxlbWVudDA1IiwgImFkZHJlc3MiLCBvd25lckVsZW1lbnROYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvYXR0cmdldG93bmVyZWxlbWVudDA1IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihhdHRyZ2V0b3duZXJlbGVtZW50MDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZUF0dHJpYnV0ZU5TMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlQXR0cmlidXRlTlMwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhMmYzZDUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZUF0dHJpYnV0ZU5TMDEuamF2YQpAQCAtMCwwICsxLDEwMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJjcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkkscXVhbGlmaWVkTmFtZSkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIERvY3VtZW50IHNob3VsZCByYWlzZSBOQU1FU1BBQ0VfRVJSIERPTUV4Y2VwdGlvbgorICogICAgaWYgcXVhbGlmaWVkTmFtZSBpcyBtYWxmb3JtZWQuCisgKiAgICAKKyAqICAgIEludm9rZSBtZXRob2QgY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUpIG9uCisgKiAgICB0aGUgWE1MTlMgRG9jdW1lbnQgd2l0aCBuYW1lc3BhY2VVUkkgYmVpbmcgImh0dHA6Ly93d3cuZWNvbW1lcmNlLm9yZy8iLAorICogICAgcXVhbGlmaWVkTmFtZSBhcyAicHJlZml4Ojpsb2NhbCIuICBNZXRob2Qgc2hvdWxkIHJhaXNlCisgKiAgICBOQU1FU1BBQ0VfRVJSIERPTUV4Y2VwdGlvbi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOQU1FU1BBQ0VfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckF0dHJOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyQXR0ck5TPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRG9jQ3JBdHRyTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOQU1FU1BBQ0VfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELURvY0NyQXR0ck5TJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY3JlYXRlQXR0cmlidXRlTlMwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY3JlYXRlQXR0cmlidXRlTlMwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5lY29tbWVyY2Uub3JnLyI7CisgICAgICBTdHJpbmcgbWFsZm9ybWVkTmFtZSA9ICJwcmVmaXg6OmxvY2FsIjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEF0dHIgbmV3QXR0cjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3QXR0ciA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIG1hbGZvcm1lZE5hbWUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05BTUVTUEFDRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlQXR0cmlidXRlTlMwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY3JlYXRlQXR0cmlidXRlTlMwMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlQXR0cmlidXRlTlMwMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVBdHRyaWJ1dGVOUzAyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDQ0YTQwMQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlQXR0cmlidXRlTlMwMi5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lKSIgbWV0aG9kIGZvciBhIAorICogICAgRG9jdW1lbnQgc2hvdWxkIHJhaXNlIE5BTUVTUEFDRV9FUlIgRE9NRXhjZXB0aW9uCisgKiAgICBpZiBxdWFsaWZpZWROYW1lIGhhcyBhIHByZWZpeCBhbmQgbmFtZXNwYWNlVVJJIGlzIG51bGwuCisgKiAgICAKKyAqICAgIEludm9rZSBtZXRob2QgY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUpIG9uIHRoaXMgZG9jdW1lbnQKKyAqICAgIHdpdGggbmFtZXNwYWNlVVJJIGJlaW5nIG51bGwgYW5kIHF1YWxpZmllZE5hbWUgY29udGFpbnMgdGhlIHByZWZpeCAicGVyc29uIi4KKyAqICAgIE1ldGhvZCBzaG91bGQgcmFpc2UgTkFNRVNQQUNFX0VSUiBET01FeGNlcHRpb24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05BTUVTUEFDRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRG9jQ3JBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckF0dHJOUzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELURvY0NyQXR0ck5TJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1Eb2NDckF0dHJOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05BTUVTUEFDRV9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNyZWF0ZUF0dHJpYnV0ZU5TMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNyZWF0ZUF0dHJpYnV0ZU5TMDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gbnVsbDsKKworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAicHJlZml4OmxvY2FsIjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEF0dHIgbmV3QXR0cjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3QXR0ciA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05BTUVTUEFDRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlQXR0cmlidXRlTlMwMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY3JlYXRlQXR0cmlidXRlTlMwMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlQXR0cmlidXRlTlMwMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVBdHRyaWJ1dGVOUzAzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWJjZTYwMQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlQXR0cmlidXRlTlMwMy5qYXZhCkBAIC0wLDAgKzEsMTMyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lKSIgbWV0aG9kIGZvciBhIAorICogICAgRG9jdW1lbnQgc2hvdWxkIHJhaXNlIElOVkFMSURfQ0hBUkFDVEVSX0VSUiBET01FeGNlcHRpb24KKyAqICAgIGlmIHF1YWxpZmllZE5hbWUgY29udGFpbnMgYW4gaWxsZWdhbCBjaGFyYWN0ZXIuCisgKiAgICAKKyAqICAgIEludm9rZSBtZXRob2QgY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUpIG9uIHRoaXMgZG9jdW1lbnQKKyAqICAgIHdpdGggcXVhbGlmaWVkTmFtZSBjb250YWluaW5nIGFuIGlsbGVnYWwgY2hhcmFjdGVyIGZyb20gaWxsZWdhbENoYXJzW10uCisgKiAgICBNZXRob2Qgc2hvdWxkIHJhaXNlIElOVkFMSURfQ0hBUkFDVEVSX0VSUiBET01FeGNlcHRpb24gZm9yIGFsbAorICogICAgY2hhcmFjdGVycyBpbiBpbGxlZ2FsQ2hhcnNbXS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckF0dHJOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyQXR0ck5TPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRG9jQ3JBdHRyTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRG9jQ3JBdHRyTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNyZWF0ZUF0dHJpYnV0ZU5TMDMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNyZWF0ZUF0dHJpYnV0ZU5TMDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cud2VkZGluZy5jb20vIjsKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lOworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgQXR0ciBuZXdBdHRyOworICAgICAgamF2YS51dGlsLkxpc3QgaWxsZWdhbFFOYW1lcyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOnsiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246fSIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjp+Iik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOiciKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246ISIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjpAIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOiMiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246JCIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjolIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOl4iKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246JiIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjoqIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOigiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246KSIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjorIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOj0iKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246WyIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjpdIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOlxcIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOi8iKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246OyIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjpgIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOjwiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246PiIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjosIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOmEgIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOlwiIik7CisgICAgICAKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDkwID0gMDsgaW5kZXhOMTAwOTAgPCBpbGxlZ2FsUU5hbWVzLnNpemUoKTsgaW5kZXhOMTAwOTArKykgeworICAgICAgICAgIHF1YWxpZmllZE5hbWUgPSAoU3RyaW5nKSBpbGxlZ2FsUU5hbWVzLmdldChpbmRleE4xMDA5MCk7CisgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXdBdHRyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTlZBTElEX0NIQVJBQ1RFUl9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KKyAgfQorICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9jcmVhdGVBdHRyaWJ1dGVOUzAzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjcmVhdGVBdHRyaWJ1dGVOUzAzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVBdHRyaWJ1dGVOUzA0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZUF0dHJpYnV0ZU5TMDQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMzAxOTg5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVBdHRyaWJ1dGVOUzA0LmphdmEKQEAgLTAsMCArMSwxMDMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUpIiBtZXRob2QgZm9yIGEgCisgKiAgICBEb2N1bWVudCBzaG91bGQgcmFpc2UgTkFNRVNQQUNFX0VSUiBET01FeGNlcHRpb24KKyAqICAgIGlmIHF1YWxpZmllZE5hbWUgaGFzIHRoZSAieG1sIiBwcmVmaXggYW5kIG5hbWVzcGFjZVVSSSBpcyBkaWZmZXJlbnQKKyAqICAgIGZyb20gImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIuCisgKiAgICAKKyAqICAgIEludm9rZSBtZXRob2QgY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUpIG9uIHRoaXMgZG9jdW1lbnQKKyAqICAgIHdpdGggcXVhbGlmaWVkTmFtZSBiZWluZyAieG1sOmF0dHIxIGFuZCBuYW1lc3BhY2VVUkkgZXF1YWxzCisgKiAgICB0aGUgc3RyaW5nICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2VzIiAod2hpY2ggZGlmZmVycyBmcm9tIHRoZSByZXF1aXJlZAorICogICAgICAgIHN0cmluZyAiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIikuCisgKiAgICBNZXRob2Qgc2hvdWxkIHJhaXNlIE5BTUVTUEFDRV9FUlIgRE9NRXhjZXB0aW9uLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOQU1FU1BBQ0VfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05BTUVTUEFDRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyQXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRG9jQ3JBdHRyTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1Eb2NDckF0dHJOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05BTUVTUEFDRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRG9jQ3JBdHRyTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOQU1FU1BBQ0VfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjcmVhdGVBdHRyaWJ1dGVOUzA0IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjcmVhdGVBdHRyaWJ1dGVOUzA0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2VzIjsKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gInhtbDphdHRyMSI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBBdHRyIG5ld0F0dHI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ld0F0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2NyZWF0ZUF0dHJpYnV0ZU5TMDQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNyZWF0ZUF0dHJpYnV0ZU5TMDQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZUF0dHJpYnV0ZU5TMDUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlQXR0cmlidXRlTlMwNS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwYmQ1ZGQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZUF0dHJpYnV0ZU5TMDUuamF2YQpAQCAtMCwwICsxLDkyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lKSIgbWV0aG9kIGZvciBhIAorICogICAgRG9jdW1lbnQgc2hvdWxkIHJldHVybiBhIG5ldyBBdHRyIG9iamVjdCBnaXZlbiB0aGF0IGFsbCBwYXJhbWV0ZXJzIGFyZQorICogICAgdmFsaWQgYW5kIGNvcnJlY3RseSBmb3JtZWQuCisgKiAgICAKKyAqICAgIEludm9rZSBtZXRob2QgY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUpIG9uIHRoaXMgZG9jdW1lbnQgd2l0aAorICogICAgcGFyYW1ldGVycyBlcXVhbCAiaHR0cDovL3d3dy5lY29tbWVyY2Uub3JnLyIgYW5kICJlY29tOmxvY2FsIgorICogICAgcmVzcGVjdGl2ZWx5LiBNZXRob2Qgc2hvdWxkIHJldHVybiBhIG5ldyBBdHRyIG9iamVjdCB3aG9zZSBuYW1lIGlzICJlY29tOmxvY2FsIi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC0xMTEyMTE5NDAzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtMTExMjExOTQwMzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY3JlYXRlQXR0cmlidXRlTlMwNSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY3JlYXRlQXR0cmlidXRlTlMwNShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5lY29tbWVyY2Uub3JnLyI7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJlY29ubTpsb2NhbCI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBBdHRyIG5ld0F0dHI7CisgICAgICBTdHJpbmcgYXR0ck5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBuZXdBdHRyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICBhdHRyTmFtZSA9IG5ld0F0dHIuZ2V0TmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0aHJvd19FcXVhbHMiLCBxdWFsaWZpZWROYW1lLCBhdHRyTmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2NyZWF0ZUF0dHJpYnV0ZU5TMDUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNyZWF0ZUF0dHJpYnV0ZU5TMDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZUF0dHJpYnV0ZU5TMDYuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlQXR0cmlidXRlTlMwNi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYxNjEzNzAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZUF0dHJpYnV0ZU5TMDYuamF2YQpAQCAtMCwwICsxLDkzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIERvY3VtZW50LmNyZWF0ZUF0dHJpYnV0ZU5TIHdpdGggYW4gZW1wdHkgcXVhbGlmaWVkIG5hbWUgc2hvdWxkIGNhdXNlIGFuIElOVkFMSURfQ0hBUkFDVEVSX0VSUi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckF0dHJOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyQXR0ck5TPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRG9jQ3JBdHRyTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRG9jQ3JBdHRyTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTUyNSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTUyNTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY3JlYXRlQXR0cmlidXRlTlMwNiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY3JlYXRlQXR0cmlidXRlTlMwNihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5leGFtcGxlLmNvbS8iOworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWU7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBBdHRyIG5ld0F0dHI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ld0F0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCAiIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTlZBTElEX0NIQVJBQ1RFUl9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlQXR0cmlidXRlTlMwNiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY3JlYXRlQXR0cmlidXRlTlMwNi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnQwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudDAxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmY2OTU0MQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnQwMS5qYXZhCkBAIC0wLDAgKzEsMTA3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgVGhlICJjcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkkscXVhbGlmaWVkTmFtZSxkb2N0eXBlKSIgbWV0aG9kIGZvciBhIAorICogICBET01JbXBsZW1lbnRhdGlvbiBzaG91bGQgcmFpc2UgTkFNRVNQQUNFX0VSUiBET01FeGNlcHRpb24KKyAqICAgaWYgcGFyYW1ldGVyIHF1YWxpZmllZE5hbWUgaXMgbWFsZm9ybWVkLgorICogICAKKyAqICAgUmV0cmlldmUgdGhlIERPTUltcGxlbWVudGF0aW9uIG9uIHRoZSBYTUxOUyBEb2N1bWVudC4KKyAqICAgSW52b2tlIG1ldGhvZCBjcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkkscXVhbGlmaWVkTmFtZSxkb2N0eXBlKSAKKyAqICAgb24gdGhlIHJldHJpZXZlZCBET01JbXBsZW1lbnRhdGlvbiB3aXRoIG5hbWVzcGFjZVVSSSBiZWluZworICogICB0aGUgbGl0ZXJhbCBzdHJpbmcgImh0dHA6Ly93d3cuZWNvbW1lcmNlLm9yZy8iLCBxdWFsaWZpZWROYW1lIGFzCisgKiAgICJwcmVmaXg6OmxvY2FsIiwgYW5kIGRvY3R5cGUgYXMgbnVsbC4gIE1ldGhvZCBzaG91bGQgcmFpc2UKKyAqICAgTkFNRVNQQUNFX0VSUiBET01FeGNlcHRpb24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05BTUVTUEFDRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2N1bWVudCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1ET00tY3JlYXRlRG9jdW1lbnQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY3JlYXRlRG9jdW1lbnQwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY3JlYXRlRG9jdW1lbnQwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5lY29tbWVyY2Uub3JnLyI7CisgICAgICBTdHJpbmcgbWFsZm9ybWVkTmFtZSA9ICJwcmVmaXg6OmxvY2FsIjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlID0gbnVsbDsKKworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIERvY3VtZW50IGFOZXdEb2M7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFOZXdEb2MgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KG5hbWVzcGFjZVVSSSwgbWFsZm9ybWVkTmFtZSwgZG9jVHlwZSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudDAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjcmVhdGVEb2N1bWVudDAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudDAyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50MDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ODc3NzNmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudDAyLmphdmEKQEAgLTAsMCArMSwxMDUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY3JlYXRlRG9jdW1lbnQobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUsZG9jdHlwZSkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIERPTUltcGxlbWVudGF0aW9uIHNob3VsZCByYWlzZSBOQU1FU1BBQ0VfRVJSIERPTUV4Y2VwdGlvbgorICogICAgaWYgcXVhbGlmaWVkTmFtZSBoYXMgYSBwcmVmaXggYW5kIG5hbWVzcGFjZVVSSSBpcyBudWxsLgorICogICAgCisgKiAgICBJbnZva2UgbWV0aG9kIGNyZWF0ZURvY3VtZW50KG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lLGRvY3R5cGUpIG9uCisgKiAgICB0aGlzIGRvbWltcGxlbWVudGF0aW9uIHdpdGggbmFtZXNwYWNlVVJJIGJlaW5nIG51bGwgYW5kIHF1YWxpZmllZE5hbWUKKyAqICAgIGVxdWFscyAiazpsb2NhbCIuIE1ldGhvZCBzaG91bGQgcmFpc2UgTkFNRVNQQUNFX0VSUiBET01FeGNlcHRpb24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05BTUVTUEFDRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2N1bWVudCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1ET00tY3JlYXRlRG9jdW1lbnQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY3JlYXRlRG9jdW1lbnQwMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY3JlYXRlRG9jdW1lbnQwMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSBudWxsOworCisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJrOmxvY2FsIjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlID0gbnVsbDsKKworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIERvY3VtZW50IGFOZXdEb2M7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFOZXdEb2MgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSwgZG9jVHlwZSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudDAyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjcmVhdGVEb2N1bWVudDAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudDAzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50MDMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jN2ZhZWY5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudDAzLmphdmEKQEAgLTAsMCArMSwxMDQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY3JlYXRlRG9jdW1lbnQobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUsZG9jdHlwZSkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIERPTUltcGxlbWVudGF0aW9uIHNob3VsZCByYWlzZSBXUk9OR19ET0NVTUVOVF9FUlIgRE9NRXhjZXB0aW9uCisgKiAgICBpZiBwYXJhbWV0ZXIgZG9jdHlwZSBoYXMgYmVlbiB1c2VkIHdpdGggYSBkaWZmZXJlbnQgZG9jdW1lbnQuCisgKiAgICAKKyAqICAgIEludm9rZSBtZXRob2QgY3JlYXRlRG9jdW1lbnQobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUsZG9jdHlwZSkgb24KKyAqICAgIHRoaXMgZG9taW1wbGVtZW50YXRpb24gd2hlcmUgZG9jdHlwZSBpcyB0aGUgdHlwZSBvZiB0aGlzIGRvY3VtZW50LgorICogICAgTWV0aG9kIHNob3VsZCByYWlzZSBXUk9OR19ET0NVTUVOVF9FUlIgRE9NRXhjZXB0aW9uLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdXUk9OR19ET0NVTUVOVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nV1JPTkdfRE9DVU1FTlRfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2N1bWVudDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0xldmVsLTItQ29yZS1ET00tY3JlYXRlRG9jdW1lbnQnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdXUk9OR19ET0NVTUVOVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2N1bWVudCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J1dST05HX0RPQ1VNRU5UX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY3JlYXRlRG9jdW1lbnQwMyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY3JlYXRlRG9jdW1lbnQwMyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5lY29tbWVyY2Uub3JnL3NjaGVtYSI7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJuYW1lc3BhY2VVUkk6eCI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBEb2N1bWVudCBhTmV3RG9jOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFOZXdEb2MgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSwgZG9jVHlwZSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19XUk9OR19ET0NVTUVOVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnQwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY3JlYXRlRG9jdW1lbnQwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnQwNC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudDA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjUyZWNlOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnQwNC5qYXZhCkBAIC0wLDAgKzEsMTA3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNyZWF0ZURvY3VtZW50KG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lLGRvY3R5cGUpIiBtZXRob2QgZm9yIGEgCisgKiAgICBET01JbXBsZW1lbnRhdGlvbiBzaG91bGQgcmFpc2UgV1JPTkdfRE9DVU1FTlRfRVJSIERPTUV4Y2VwdGlvbgorICogICAgaWYgcGFyYW1ldGVyIGRvY3R5cGUgd2FzIGNyZWF0ZWQgZnJvbSBhIGRpZmZlcmVudCBpbXBsZW1lbnRhdGlvbi4KKyAqICAgIAorICogICAgSW52b2tlIG1ldGhvZCBjcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkkscXVhbGlmaWVkTmFtZSxkb2N0eXBlKSBvbgorICogICAgYSBkb21pbXBsZW1lbnRhdGlvbiB0aGF0IGlzIGRpZmZlcmVudCBmcm9tIHRoaXMgZG9taW1wbGVtZW50YXRpb24uCisgKiAgICBEb2N0eXBlIGlzIHRoZSB0eXBlIG9mIHRoaXMgZG9jdW1lbnQuCisgKiAgICBNZXRob2Qgc2hvdWxkIHJhaXNlIFdST05HX0RPQ1VNRU5UX0VSUiBET01FeGNlcHRpb24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J1dST05HX0RPQ1VNRU5UX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdXUk9OR19ET0NVTUVOVF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1ET00tY3JlYXRlRG9jdW1lbnQiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2N1bWVudCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J1dST05HX0RPQ1VNRU5UX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nV1JPTkdfRE9DVU1FTlRfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjcmVhdGVEb2N1bWVudDA0IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjcmVhdGVEb2N1bWVudDA0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LmVjb21tZXJjZS5vcmcvc2NoZW1hIjsKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gIm5hbWVzcGFjZVVSSTp4IjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIERvY3VtZW50IGFOZXdEb2M7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBhTmV3RG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBkb21JbXBsID0gYU5ld0RvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhTmV3RG9jID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsIGRvY1R5cGUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfV1JPTkdfRE9DVU1FTlRfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50MDQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNyZWF0ZURvY3VtZW50MDQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50MDUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnQwNS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE2Y2Y4NmQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50MDUuamF2YQpAQCAtMCwwICsxLDEzNyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJjcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkkscXVhbGlmaWVkTmFtZSxkb2N0eXBlKSIgbWV0aG9kIGZvciBhIAorICogICAgRE9NSW1wbGVtZW50YXRpb24gc2hvdWxkIHJhaXNlIElOVkFMSURfQ0hBUkFDVEVSX0VSUiBET01FeGNlcHRpb24KKyAqICAgIGlmIHBhcmFtZXRlciBxdWFsaWZpZWROYW1lIGNvbnRhaW5zIGFuIGlsbGVnYWwgY2hhcmFjdGVyLgorICogICAgCisgKiAgICBJbnZva2UgbWV0aG9kIGNyZWF0ZURvY3VtZW50KG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lLGRvY3R5cGUpIG9uCisgKiAgICB0aGlzIGRvbWltcGxlbWVudGF0aW9uIHdpdGggbmFtZXNwYWNlVVJJIGVxdWFscyAiaHR0cDovL3d3dy5lY29tbWVyY2Uub3JnL3NjaGVtYSIsCisgKiAgICBkb2N0eXBlIGlzIG51bGwgYW5kIHF1YWxpZmllZE5hbWUgY29udGFpbnMgYW4gaWxsZWdhbCBjaGFyYWN0ZXIgZnJvbQorICogICAgaWxsZWdhbENoYXJzW10uICBNZXRob2Qgc2hvdWxkIHJhaXNlIElOVkFMSURfQ0hBUkFDVEVSX0VSUiBET01FeGNlcHRpb24KKyAqICAgIGZvciBhbGwgY2hhcmFjdGVycyBpbiBpbGxlZ2FsQ2hhcnNbXS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNyZWF0ZURvY3VtZW50MDUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNyZWF0ZURvY3VtZW50MDUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cuZWNvbW1lcmNlLm9yZy9zY2hlbWEiOworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWU7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZSA9IG51bGw7CisKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBEb2N1bWVudCBhTmV3RG9jOworICAgICAgU3RyaW5nIGNoYXJhY3Q7CisgICAgICBqYXZhLnV0aWwuTGlzdCBpbGxlZ2FsUU5hbWVzID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6eyIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTp9Iik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOn4iKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6JyIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTohIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOkAiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6IyIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTokIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOiUiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6XiIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTomIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOioiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6KCIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTopIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOisiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6PSIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTpbIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOl0iKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6XFwiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6LyIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTo7Iik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOmAiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6PCIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTo+Iik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOiwiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6YSAiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6XCIiKTsKKyAgICAgIAorICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwOUEgPSAwOyBpbmRleE4xMDA5QSA8IGlsbGVnYWxRTmFtZXMuc2l6ZSgpOyBpbmRleE4xMDA5QSsrKSB7CisgICAgICAgICAgcXVhbGlmaWVkTmFtZSA9IChTdHJpbmcpIGlsbGVnYWxRTmFtZXMuZ2V0KGluZGV4TjEwMDlBKTsKKyAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFOZXdEb2MgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSwgZG9jVHlwZSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTlZBTElEX0NIQVJBQ1RFUl9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KKyAgfQorICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudDA1IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjcmVhdGVEb2N1bWVudDA1LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudDA2LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50MDYuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NjUzZDI2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudDA2LmphdmEKQEAgLTAsMCArMSwxMDggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICBUaGUgImNyZWF0ZURvY3VtZW50KG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lLGRvY3R5cGUpIiBtZXRob2QgZm9yIGEgCisgKiAgIERPTUltcGxlbWVudGF0aW9uIHNob3VsZCByYWlzZSBOQU1FU1BBQ0VfRVJSIERPTUV4Y2VwdGlvbgorICogICBpZiBxdWFsaWZpZWROYW1lIGhhcyB0aGUgInhtbCIgcHJlZml4IGFuZCBuYW1lc3BhY2VVUkkgZGlmZmVyZW50IGZyb20KKyAqICAgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIKKyAqICAgCisgKiAgIEludm9rZSBtZXRob2QgY3JlYXRlRG9jdW1lbnQobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUsZG9jdHlwZSkgb24KKyAqICAgdGhpcyBkb21pbXBsZW1lbnRhdGlvbiB3aXRoIHF1YWxpZmllZE5hbWUgInhtbDpsb2NhbCIgCisgKiAgIGFuZCBuYW1lc3BhY2VVUkkgYXMgdGhlIHN0cmluZworICogICAiaHR0cDovL3d3dy5lY29tbWVyY2Uub3JnL3NjaGVtYSIgKHdoaWNoIGlzIGRpZmZlcmVudCBmcm9tIHRoZSByZXF1aXJlZAorICogICAiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIikuIE1ldGhvZCBzaG91bGQgcmFpc2UKKyAqICAgTkFNRVNQQUNFX0VSUiBET01FeGNlcHRpb24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05BTUVTUEFDRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2N1bWVudCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1ET00tY3JlYXRlRG9jdW1lbnQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY3JlYXRlRG9jdW1lbnQwNiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY3JlYXRlRG9jdW1lbnQwNihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL2Vjb21tZXJjZS5vcmcvc2NoZW1hIjsKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gInhtbDpsb2NhbCI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZSA9IG51bGw7CisKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBEb2N1bWVudCBhTmV3RG9jOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhTmV3RG9jID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsIGRvY1R5cGUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05BTUVTUEFDRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnQwNiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY3JlYXRlRG9jdW1lbnQwNi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnQwNy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudDA3LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTk3NmFkMwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnQwNy5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNyZWF0ZURvY3VtZW50KG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lLGRvY3R5cGUpIiBtZXRob2QgZm9yIGEgCisgKiAgICBET01JbXBsZW1lbnRhdGlvbiBzaG91bGQgcmV0dXJuIGEgbmV3IHhtbCBEb2N1bWVudCBvYmplY3Qgb2YgdGhlIAorICogICAgc3BlY2lmaWVkIHR5cGUgd2l0aCBpdHMgZG9jdW1lbnQgZWxlbWVudCBnaXZlbiB0aGF0IGFsbCBwYXJhbWV0ZXJzIGFyZQorICogICAgdmFsaWQgYW5kIGNvcnJlY3RseSBmb3JtZWQuCisgKiAgICAKKyAqICAgIEludm9rZSBtZXRob2QgY3JlYXRlRG9jdW1lbnQobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUsZG9jdHlwZSkgb24KKyAqICAgIHRoaXMgZG9taW1wbGVtZW50YXRpb24uIG5hbWVzcGFjZVVSSSBpcyAiaHR0cDovL3d3dy5lY29tbWVyY2Uub3JnL3NjaGVtYSIKKyAqICAgIHF1YWxpZmllZE5hbWUgaXMgInk6eCIgYW5kIGRvY3R5cGUgaXMgbnVsbC4KKyAqICAgIE1ldGhvZCBzaG91bGQgcmV0dXJuIGEgbmV3IHhtbCBEb2N1bWVudCBhcyBzcGVjaWZpZWQgYnkgdGhlIGxpc3RlZCBwYXJhbWV0ZXJzLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1ET00tY3JlYXRlRG9jdW1lbnQiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjcmVhdGVEb2N1bWVudDA3IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjcmVhdGVEb2N1bWVudDA3KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LmVjb21tZXJjZS5vcmcvc2NoZW1hIjsKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gInk6eCI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZSA9IG51bGw7CisKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBEb2N1bWVudCBhTmV3RG9jOworICAgICAgU3RyaW5nIG5vZGVOYW1lOworICAgICAgU3RyaW5nIG5vZGVWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgIGFOZXdEb2MgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSwgZG9jVHlwZSk7CisgICAgICBub2RlTmFtZSA9IGFOZXdEb2MuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIG5vZGVWYWx1ZSA9IGFOZXdEb2MuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lIiwgIiNkb2N1bWVudCIsIG5vZGVOYW1lKTsKKyAgICAgIGFzc2VydE51bGwoIm5vZGVWYWx1ZSIsIG5vZGVWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50MDciOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNyZWF0ZURvY3VtZW50MDcuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50MDguamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnQwOC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVjYjUyYmQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50MDguamF2YQpAQCAtMCwwICsxLDkyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIERPTUltcGxlbWVudGF0aW9uLmNyZWF0ZURvY3VtZW50IHdpdGggYW4gZW1wdHkgcXVhbGlmaWVkIG5hbWUgc2hvdWxkIGNhdXNlIGFuIElOVkFMSURfQ0hBUkFDVEVSX0VSUi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTUyNSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTUyNTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY3JlYXRlRG9jdW1lbnQwOCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICovCisgICBwdWJsaWMgY3JlYXRlRG9jdW1lbnQwOChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgeworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cuZXhhbXBsZS5vcmcvc2NoZW1hIjsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlID0gbnVsbDsKKworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIERvY3VtZW50IGFOZXdEb2M7CisgICAgICBTdHJpbmcgY2hhcmFjdDsKKyAgICAgIGRvbUltcGwgPSBnZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhTmV3RG9jID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkksICIiLCBkb2NUeXBlKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOVkFMSURfQ0hBUkFDVEVSX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudDA4IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjcmVhdGVEb2N1bWVudDA4LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudFR5cGUwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudFR5cGUwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjNGI0YTMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50VHlwZTAxLmphdmEKQEAgLTAsMCArMSwxMDUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICBUaGUgImNyZWF0ZURvY3VtZW50VHlwZShxdWFsaWZpZWROYW1lLHB1YmxpY0lkLHN5c3RlbUlkKSIgbWV0aG9kIGZvciBhIAorICogICBET01JbXBsZW1lbnRhdGlvbiBzaG91bGQgcmFpc2UgTkFNRVNQQUNFX0VSUiBET01FeGNlcHRpb24gaWYKKyAqICAgcXVhbGlmaWVkTmFtZSBpcyBtYWxmb3JtZWQuCisgKiAgIAorICogICBSZXRyaWV2ZSB0aGUgRE9NSW1wbGVtZW50YXRpb24gb24gdGhlIFhNTE5TIERvY3VtZW50LgorICogICBJbnZva2UgbWV0aG9kIGNyZWF0ZURvY3VtZW50VHlwZShxdWFsaWZpZWROYW1lLHB1YmxpY0lkLHN5c3RlbUlkKQorICogICBvbiB0aGUgcmV0cmlldmVkIERPTUltcGxlbWVudGF0aW9uIHdpdGggcXVhbGlmaWVkTmFtZSBiZWluZyB0aGUgbGl0ZXJhbAorICogICBzdHJpbmcgInByZWZpeDo6bG9jYWwiLCBwdWJsaWNJZCBhcyAiU1RBRkYiLCBhbmQgc3lzdGVtSWQgYXMgInN0YWZmIi4KKyAqICAgTWV0aG9kIHNob3VsZCByYWlzZSBOQU1FU1BBQ0VfRVJSIERPTUV4Y2VwdGlvbi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOQU1FU1BBQ0VfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY1R5cGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY1R5cGU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY1R5cGUnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOQU1FU1BBQ0VfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0xldmVsLTItQ29yZS1ET00tY3JlYXRlRG9jVHlwZScpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05BTUVTUEFDRV9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNyZWF0ZURvY3VtZW50VHlwZTAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjcmVhdGVEb2N1bWVudFR5cGUwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBwdWJsaWNJZCA9ICJTVEFGRiI7CisgICAgICBTdHJpbmcgc3lzdGVtSWQgPSAic3RhZmYueG1sIjsKKyAgICAgIFN0cmluZyBtYWxmb3JtZWROYW1lID0gInByZWZpeDo6bG9jYWwiOworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIERvY3VtZW50VHlwZSBuZXdUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXdUeXBlID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudFR5cGUobWFsZm9ybWVkTmFtZSwgcHVibGljSWQsIHN5c3RlbUlkKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50VHlwZTAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjcmVhdGVEb2N1bWVudFR5cGUwMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnRUeXBlMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnRUeXBlMDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOTMxN2FlCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudFR5cGUwMi5qYXZhCkBAIC0wLDAgKzEsMTM2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNyZWF0ZURvY3VtZW50VHlwZShxdWFsaWZpZWROYW1lLHB1YmxpY0lkLHN5c3RlbUlkKSIgbWV0aG9kIGZvciBhIAorICogICAgRE9NSW1wbGVtZW50YXRpb24gc2hvdWxkIHJhaXNlIElOVkFMSURfQ0hBUkFDVEVSX0VSUiBET01FeGNlcHRpb24gaWYKKyAqICAgIHF1YWxpZmllZE5hbWUgY29udGFpbnMgYW4gaWxsZWdhbCBjaGFyYWN0ZXIuCisgKiAgICAKKyAqICAgIEludm9rZSBtZXRob2QgY3JlYXRlRG9jdW1lbnRUeXBlKHF1YWxpZmllZE5hbWUscHVibGljSWQsc3lzdGVtSWQpIG9uCisgKiAgICB0aGlzIGRvbWltcGxlbWVudGF0aW9uIHdpdGggcXVhbGlmaWVkTmFtZSBjb250YWluaW5nIGFuIGlsbGVnYWwgY2hhcmFjdGVyCisgKiAgICBmcm9tIGlsbGVnYWxDaGFyc1tdLiBNZXRob2Qgc2hvdWxkIHJhaXNlIElOVkFMSURfQ0hBUkFDVEVSX0VSUgorICogICAgRE9NRXhjZXB0aW9uIGZvciBhbGwgY2hhcmFjdGVycyBpbiBpbGxlZ2FsQ2hhcnNbXS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY1R5cGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY1R5cGU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY1R5cGUnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2NUeXBlJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjcmVhdGVEb2N1bWVudFR5cGUwMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY3JlYXRlRG9jdW1lbnRUeXBlMDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBTdHJpbmcgcHVibGljSWQgPSAiaHR0cDovL3d3dy5sb2NhbGhvc3QuY29tLyI7CisgICAgICBTdHJpbmcgc3lzdGVtSWQgPSAibXlEb2MuZHRkIjsKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lOworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGUgPSBudWxsOworCisgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgamF2YS51dGlsLkxpc3QgaWxsZWdhbFFOYW1lcyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOnsiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6fSIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTp+Iik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOiciKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6ISIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTpAIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOiMiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6JCIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTolIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOl4iKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6JiIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaToqIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOigiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6KSIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTorIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOj0iKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6WyIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTpdIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOlxcIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOi8iKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6OyIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTpgIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOjwiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6PiIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTosIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOmEgIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOlwiIik7CisgICAgICAKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDlBID0gMDsgaW5kZXhOMTAwOUEgPCBpbGxlZ2FsUU5hbWVzLnNpemUoKTsgaW5kZXhOMTAwOUErKykgeworICAgICAgICAgIHF1YWxpZmllZE5hbWUgPSAoU3RyaW5nKSBpbGxlZ2FsUU5hbWVzLmdldChpbmRleE4xMDA5QSk7CisgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkb2NUeXBlID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudFR5cGUocXVhbGlmaWVkTmFtZSwgcHVibGljSWQsIHN5c3RlbUlkKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOVkFMSURfQ0hBUkFDVEVSX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorICB9CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50VHlwZTAyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjcmVhdGVEb2N1bWVudFR5cGUwMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnRUeXBlMDMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnRUeXBlMDMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNzc3MzMxCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudFR5cGUwMy5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNyZWF0ZURvY3VtZW50VHlwZShxdWFsaWZpZWROYW1lLHB1YmxpY0lkLHN5c3RlbUlkKSIgbWV0aG9kIGZvciBhIAorICogICAgRE9NSW1wbGVtZW50YXRpb24gc2hvdWxkIHJldHVybiBhIG5ldyBEb2N1bWVudFR5cGUgbm9kZSAKKyAqICAgIGdpdmVuIHRoYXQgcXVhbGlmaWVkTmFtZSBpcyB2YWxpZCBhbmQgY29ycmVjdGx5IGZvcm1lZC4KKyAqICAgIAorICogICAgSW52b2tlIG1ldGhvZCBjcmVhdGVEb2N1bWVudFR5cGUocXVhbGlmaWVkTmFtZSxwdWJsaWNJZCxzeXN0ZW1JZCkgb24KKyAqICAgIHRoaXMgZG9taW1wbGVtZW50YXRpb24gd2l0aCBxdWFsaWZpZWROYW1lICJwcmVmaXg6bXlEb2MiLgorICogICAgTWV0aG9kIHNob3VsZCByZXR1cm4gYSBuZXcgRG9jdW1lbnRUeXBlIG5vZGUuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2NUeXBlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2NUeXBlPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjcmVhdGVEb2N1bWVudFR5cGUwMyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY3JlYXRlRG9jdW1lbnRUeXBlMDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly9lY29tbWVyY2Uub3JnL3NjaGVtYSI7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJwcmVmaXg6bXlEb2MiOworICAgICAgU3RyaW5nIHB1YmxpY0lkID0gImh0dHA6Ly93d3cubG9jYWxob3N0LmNvbSI7CisgICAgICBTdHJpbmcgc3lzdGVtSWQgPSAibXlEb2MuZHRkIjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBEb2N1bWVudFR5cGUgbmV3VHlwZSA9IG51bGw7CisKKyAgICAgIFN0cmluZyBub2RlTmFtZTsKKyAgICAgIFN0cmluZyBub2RlVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICBuZXdUeXBlID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudFR5cGUocXVhbGlmaWVkTmFtZSwgcHVibGljSWQsIHN5c3RlbUlkKTsKKyAgICAgIG5vZGVOYW1lID0gbmV3VHlwZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTmFtZSIsICJwcmVmaXg6bXlEb2MiLCBub2RlTmFtZSk7CisgICAgICBub2RlVmFsdWUgPSBuZXdUeXBlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0TnVsbCgibm9kZVZhbHVlIiwgbm9kZVZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlRG9jdW1lbnRUeXBlMDMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNyZWF0ZURvY3VtZW50VHlwZTAzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudFR5cGUwNC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVEb2N1bWVudFR5cGUwNC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM2OWEwOGIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50VHlwZTA0LmphdmEKQEAgLTAsMCArMSw5MyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBET01JbXBsZW1lbnRhdGlvbi5jcmVhdGVEb2N1bWVudFR5cGUgd2l0aCBhbiBlbXB0eSBuYW1lIHNob3VsZCBjYXVzZSBhbiBJTlZBTElEX0NIQVJBQ1RFUl9FUlIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2NUeXBlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2NUeXBlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2NUeXBlJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0xldmVsLTItQ29yZS1ET00tY3JlYXRlRG9jVHlwZScpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9NTI1Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9NTI1PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjcmVhdGVEb2N1bWVudFR5cGUwNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICovCisgICBwdWJsaWMgY3JlYXRlRG9jdW1lbnRUeXBlMDQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIHB1YmxpY0lkID0gImh0dHA6Ly93d3cuZXhhbXBsZS5jb20vIjsKKyAgICAgIFN0cmluZyBzeXN0ZW1JZCA9ICJteURvYy5kdGQiOworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWU7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZSA9IG51bGw7CisKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBkb21JbXBsID0gZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgZG9jVHlwZSA9IGRvbUltcGwuY3JlYXRlRG9jdW1lbnRUeXBlKCIiLCBwdWJsaWNJZCwgc3lzdGVtSWQpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTlZBTElEX0NIQVJBQ1RFUl9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSU5WQUxJRF9DSEFSQUNURVJfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2NyZWF0ZURvY3VtZW50VHlwZTA0IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjcmVhdGVEb2N1bWVudFR5cGUwNC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRWxlbWVudE5TMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRWxlbWVudE5TMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YjU5YjQ0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVFbGVtZW50TlMwMS5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkkscXVhbGlmaWVkTmFtZSkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIERvY3VtZW50IHNob3VsZCByYWlzZSBOQU1FU1BBQ0VfRVJSIERPTUV4Y2VwdGlvbiBpZiAKKyAqICAgIHF1YWxpZmllZE5hbWUgaXMgbWFsZm9ybWVkLgorICogICAgCisgKiAgICBJbnZva2UgbWV0aG9kIGNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkkscXVhbGlmaWVkTmFtZSkgb24KKyAqICAgIHRoZSBYTUxOUyBEb2N1bWVudCB3aXRoIG5hbWVzcGFjZVVSSSBiZWluZyB0aGUgbGl0ZXJhbCBzdHJpbmcKKyAqICAgICJodHRwOi8vd3d3LmVjb21tZXJjZS5vcmcvIiwgYW5kIHF1YWxpZmllZE5hbWUgYXMgInByZWZpeDo6bG9jYWwiLgorICogICAgTWV0aG9kIHNob3VsZCByYWlzZSBOQU1FU1BBQ0VfRVJSIERPTUV4Y2VwdGlvbi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOQU1FU1BBQ0VfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckVsTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckVsTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1Eb2NDckVsTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOQU1FU1BBQ0VfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELURvY0NyRWxOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05BTUVTUEFDRV9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNyZWF0ZUVsZW1lbnROUzAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjcmVhdGVFbGVtZW50TlMwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5lY29tbWVyY2Uub3JnLyI7CisgICAgICBTdHJpbmcgbWFsZm9ybWVkTmFtZSA9ICJwcmVmaXg6OmxvY2FsIjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgbmV3RWxlbWVudDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3RWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCBtYWxmb3JtZWROYW1lKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2NyZWF0ZUVsZW1lbnROUzAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjcmVhdGVFbGVtZW50TlMwMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRWxlbWVudE5TMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRWxlbWVudE5TMDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMmMyNmE3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVFbGVtZW50TlMwMi5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkkscXVhbGlmaWVkTmFtZSkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIERvY3VtZW50IHNob3VsZCByYWlzZSBOQU1FU1BBQ0VfRVJSIERPTUV4Y2VwdGlvbiBpZiAKKyAqICAgIHF1YWxpZmllZE5hbWUgaGFzIGEgcHJlZml4IGFuZCBuYW1lc3BhY2VVUkkgaXMgbnVsbC4KKyAqICAgIAorICogICAgSW52b2tlIG1ldGhvZCBjcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUpIG9uIHRoaXMgZG9jdW1lbnQKKyAqICAgIHdpdGggbmFtZXNwYWNlVVJJIGJlaW5nIG51bGwgYW5kIHF1YWxpZmllZE5hbWUgYmVpbmcgImVsZW06YXR0cjEiLgorICogICAgTWV0aG9kIHNob3VsZCByYWlzZSBOQU1FU1BBQ0VfRVJSIERPTUV4Y2VwdGlvbi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOQU1FU1BBQ0VfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckVsTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckVsTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1Eb2NDckVsTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOQU1FU1BBQ0VfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELURvY0NyRWxOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05BTUVTUEFDRV9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNyZWF0ZUVsZW1lbnROUzAyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjcmVhdGVFbGVtZW50TlMwMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSBudWxsOworCisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJwcmVmaXg6bG9jYWwiOworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBuZXdFbGVtZW50OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXdFbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05BTUVTUEFDRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlRWxlbWVudE5TMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNyZWF0ZUVsZW1lbnROUzAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVFbGVtZW50TlMwMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVFbGVtZW50TlMwMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZlNTAzYjMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZUVsZW1lbnROUzAzLmphdmEKQEAgLTAsMCArMSwxMzQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lKSIgbWV0aG9kIGZvciBhIAorICogICAgRG9jdW1lbnQgc2hvdWxkIHJhaXNlIElOVkFMSURfQ0hBUkFDVEVSX0VSUiBET01FeGNlcHRpb24gaWYgCisgKiAgICBxdWFsaWZpZWROYW1lIGNvbnRhaW5zIGFuIGlsbGVnYWwgY2hhcmFjdGVyLgorICogICAgCisgKiAgICBJbnZva2UgbWV0aG9kIGNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkkscXVhbGlmaWVkTmFtZSkgb24gdGhpcyBkb2N1bWVudAorICogICAgd2l0aCBxdWFsaWZpZWROYW1lIGNvbnRhaW5pbmcgYW4gaWxsZWdhbCBjaGFyYWN0ZXIgZnJvbSBpbGxlZ2FsQ2hhcnNbXS4KKyAqICAgIE1ldGhvZCBzaG91bGQgcmFpc2UgSU5WQUxJRF9DSEFSQUNURVJfRVJSIERPTUV4Y2VwdGlvbiBmb3IgYWxsIGNoYXJhY3RlcnMKKyAqICAgIGluIGlsbGVnYWxDaGFyc1tdLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyRWxOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyRWxOUzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELURvY0NyRWxOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1Eb2NDckVsTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNyZWF0ZUVsZW1lbnROUzAzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjcmVhdGVFbGVtZW50TlMwMyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy53ZWRkaW5nLmNvbS8iOworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWU7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBib29sZWFuIGRvbmU7CisgICAgICBFbGVtZW50IG5ld0VsZW1lbnQ7CisgICAgICBTdHJpbmcgY2hhcmFjdDsKKyAgICAgIGphdmEudXRpbC5MaXN0IGlsbGVnYWxRTmFtZXMgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjp7Iik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOn0iKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246fiIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjonIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOiEiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246QCIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjojIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOiQiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246JSIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjpeIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOiYiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246KiIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjooIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOikiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246KyIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjo9Iik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOlsiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246XSIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjpcXCIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjovIik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOjsiKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246YCIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjo8Iik7CisgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOj4iKTsKKyAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246LCIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjphICIpOworICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjpcIiIpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA5OCA9IDA7IGluZGV4TjEwMDk4IDwgaWxsZWdhbFFOYW1lcy5zaXplKCk7IGluZGV4TjEwMDk4KyspIHsKKyAgICAgICAgICBxdWFsaWZpZWROYW1lID0gKFN0cmluZykgaWxsZWdhbFFOYW1lcy5nZXQoaW5kZXhOMTAwOTgpOworICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3RWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOVkFMSURfQ0hBUkFDVEVSX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorICB9CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2NyZWF0ZUVsZW1lbnROUzAzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihjcmVhdGVFbGVtZW50TlMwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRWxlbWVudE5TMDQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvY3JlYXRlRWxlbWVudE5TMDQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNTRkMTgyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVFbGVtZW50TlMwNC5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgIFRoZSAiY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lIikgbWV0aG9kIGZvcgorICogICAgYSBEb2N1bWVudCBzaG91bGQgcmFpc2UgTkFNRVNQQUNFX0VSUiBET01FeGNlcHRpb24gaWYgdGhlCisgKiAgICBxdWFsaWZpZWROYW1lIGhhcyBhbiAieG1sIiBwcmVmaXggYW5kIHRoZSBuYW1lc3BhY2VVUkkgaXMgZGlmZmVyZW50CisgKiAgICBmcm9tIGh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIuCisgKiAgICAKKyAqICAgIEludm9rZSBtZXRob2QgY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lKSBvbiB0aGlzIGRvY3VtZW50CisgKiAgICB3aXRoIHF1YWxpZmllZE5hbWUgYmVpbmcgInhtbDplbGVtZW50MSIgYW5kIG5hbWVzcGFjZVVSSSBlcXVhbHMgdGhlIHN0cmluZworICogICAgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk3L25hbWVzcGFjZSIgKHdoaWNoIGRpZmZlcnMgZnJvbSB0aGUgcmVxdWlyZWQgCisgKiAgICBzdHJpbmcgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIpLgorICogICAgTWV0aG9kIHNob3VsZCByYWlzZSBOQU1FU1BBQ0VfRVJSIERPTUV4Y2VwdGlvbi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOQU1FU1BBQ0VfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckVsTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckVsTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1Eb2NDckVsTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOQU1FU1BBQ0VfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELURvY0NyRWxOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05BTUVTUEFDRV9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGNyZWF0ZUVsZW1lbnROUzA0IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBjcmVhdGVFbGVtZW50TlMwNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlcyI7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJ4bWw6ZWxlbWVudDEiOworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBuZXdFbGVtZW50OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXdFbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05BTUVTUEFDRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlRWxlbWVudE5TMDQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNyZWF0ZUVsZW1lbnROUzA0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVFbGVtZW50TlMwNS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVFbGVtZW50TlMwNS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMzZmYwMGMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZUVsZW1lbnROUzA1LmphdmEKQEAgLTAsMCArMSw5MiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJjcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUpIiBtZXRob2QgZm9yIGEgCisgKiAgICBEb2N1bWVudCBzaG91bGQgcmV0dXJuIGEgbmV3IEVsZW1lbnQgb2JqZWN0IGdpdmVuIHRoYXQgYWxsIHBhcmFtZXRlcnMKKyAqICAgIGFyZSB2YWxpZCBhbmQgY29ycmVjdGx5IGZvcm1lZC4KKyAqICAgIAorICogICAgSW52b2tlIG1ldGhvZCBjcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUgb24gdGhpcyBkb2N1bWVudAorICogICAgd2l0aCBuYW1lc3BhY2VVUkkgYXMgImh0dHA6Ly93d3cubmlzdC5nb3YiIGFuZCBxdWFsaWZpZWROYW1lIGFzICJnb3Y6ZmFjdWx0eSIuCisgKiAgICBNZXRob2Qgc2hvdWxkIHJldHVybiBhIG5ldyBFbGVtZW50IG9iamVjdCB3aG9zZSBuYW1lIGlzICJnb3Y6ZmFjdWx0eSIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtMTA0NjgyODE1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtMTA0NjgyODE1PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBjcmVhdGVFbGVtZW50TlMwNSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgY3JlYXRlRWxlbWVudE5TMDUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cubmlzdC5nb3YiOworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiZ292OmZhY3VsdHkiOworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBuZXdFbGVtZW50OworICAgICAgU3RyaW5nIGVsZW1lbnROYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgbmV3RWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgIGVsZW1lbnROYW1lID0gbmV3RWxlbWVudC5nZXRUYWdOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInRocm93X0VxdWFscyIsIHF1YWxpZmllZE5hbWUsIGVsZW1lbnROYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvY3JlYXRlRWxlbWVudE5TMDUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGNyZWF0ZUVsZW1lbnROUzA1LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVFbGVtZW50TlMwNi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9jcmVhdGVFbGVtZW50TlMwNi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU0NzQ0ZjMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2NyZWF0ZUVsZW1lbnROUzA2LmphdmEKQEAgLTAsMCArMSw5NSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBEb2N1bWVudC5jcmVhdGVFbGVtZW50TlMgd2l0aCBhbiBlbXB0eSBxdWFsaWZpZWQgbmFtZSBzaG91bGQgY2F1c2UgYW4gSU5WQUxJRF9DSEFSQUNURVJfRVJSLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyRWxOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyRWxOUzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELURvY0NyRWxOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1Eb2NDckVsTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTUyNSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTUyNTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgY3JlYXRlRWxlbWVudE5TMDYgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGNyZWF0ZUVsZW1lbnROUzA2KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LmV4YW1wbGUuY29tLyI7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZTsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIGJvb2xlYW4gZG9uZTsKKyAgICAgIEVsZW1lbnQgbmV3RWxlbWVudDsKKyAgICAgIFN0cmluZyBjaGFyYWN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXdFbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkksICIiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOVkFMSURfQ0hBUkFDVEVSX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9jcmVhdGVFbGVtZW50TlMwNiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oY3JlYXRlRWxlbWVudE5TMDYuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYmI2ZGExCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDEuamF2YQpAQCAtMCwwICsxLDk1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIGNyZWF0ZUF0dHJpYnV0ZU5TIGNyZWF0ZXMgYW4gYXR0cmlidXRlIG9mIHRoZSBnaXZlbiBxdWFsaWZpZWQgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSQorICogIAorICogIEludm9rZSB0aGUgY3JlYXRlQXR0cmlidXRlTlMgbWV0aG9kIG9uIHRoaXMgRG9jdW1lbnQgb2JqZWN0IHdpdGggYSBudWxsIAorICogIG5hbWVzcGFjZVVSSSwgYW5kIGEgcXVhbGlmaWVkTmFtZSB3aXRob3V0IGEgcHJlZml4LiAgVGhpcyBzaG91bGQgcmV0dXJuIGEgdmFsaWQgQXR0ciAKKyAqICBub2RlIG9iamVjdC4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckF0dHJOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyQXR0ck5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9IG51bGw7CisKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gInRlc3QiOworICAgICAgU3RyaW5nIG5hbWU7CisgICAgICBTdHJpbmcgbm9kZU5hbWU7CisgICAgICBTdHJpbmcgbm9kZVZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgYXR0cmlidXRlID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICBub2RlTmFtZSA9IGF0dHJpYnV0ZS5nZXROb2RlTmFtZSgpOworICAgICAgbm9kZVZhbHVlID0gYXR0cmlidXRlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDEiLCAidGVzdCIsIG5vZGVOYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NTgyZmYzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDIuamF2YQpAQCAtMCwwICsxLDExMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCBjcmVhdGVBdHRyaWJ1dGVOUyBjcmVhdGVzIGFuIGF0dHJpYnV0ZSBvZiB0aGUgZ2l2ZW4gcXVhbGlmaWVkIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkKKyAqICAKKyAqICBJbnZva2UgdGhlIGNyZWF0ZUF0dHJpYnV0ZU5TIG1ldGhvZCBvbiB0aGlzIERvY3VtZW50IG9iamVjdCB3aXRoIGEgdmFsaWQgdmFsdWVzIGZvciAKKyAqICBuYW1lc3BhY2VVUkksIGFuZCBhIHF1YWxpZmllZE5hbWUgYXMgYmVsb3cuICBUaGlzIHNob3VsZCByZXR1cm4gYSB2YWxpZCBBdHRyIG5vZGUuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRG9jQ3JBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckF0dHJOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzAyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBBdHRyIGF0dHJpYnV0ZTE7CisgICAgICBBdHRyIGF0dHJpYnV0ZTI7CisgICAgICBTdHJpbmcgbmFtZTsKKyAgICAgIFN0cmluZyBub2RlTmFtZTsKKyAgICAgIFN0cmluZyBub2RlVmFsdWU7CisgICAgICBTdHJpbmcgcHJlZml4OworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGF0dHJpYnV0ZTEgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIsICJ4bWw6eG1sIik7CisgICAgICBuYW1lID0gYXR0cmlidXRlMS5nZXROYW1lKCk7CisgICAgICBub2RlTmFtZSA9IGF0dHJpYnV0ZTEuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIG5vZGVWYWx1ZSA9IGF0dHJpYnV0ZTEuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBwcmVmaXggPSBhdHRyaWJ1dGUxLmdldFByZWZpeCgpOworICAgICAgbmFtZXNwYWNlVVJJID0gYXR0cmlidXRlMS5nZXROYW1lc3BhY2VVUkkoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzAyX2F0dDFfbmFtZSIsICJ4bWw6eG1sIiwgbmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMl9hdHQxX25vZGVOYW1lIiwgInhtbDp4bWwiLCBub2RlTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMl9hdHQxX25vZGVWYWx1ZSIsICIiLCBub2RlVmFsdWUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDJfYXR0MV9wcmVmaXgiLCAieG1sIiwgcHJlZml4KTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzAyX2F0dDFfbmFtZXNwYWNlVVJJIiwgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIsIG5hbWVzcGFjZVVSSSk7CisgICAgICBhdHRyaWJ1dGUyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIsICJ4bWxucyIpOworICAgICAgbmFtZSA9IGF0dHJpYnV0ZTIuZ2V0TmFtZSgpOworICAgICAgbm9kZU5hbWUgPSBhdHRyaWJ1dGUyLmdldE5vZGVOYW1lKCk7CisgICAgICBub2RlVmFsdWUgPSBhdHRyaWJ1dGUyLmdldE5vZGVWYWx1ZSgpOworICAgICAgcHJlZml4ID0gYXR0cmlidXRlMi5nZXRQcmVmaXgoKTsKKyAgICAgIG5hbWVzcGFjZVVSSSA9IGF0dHJpYnV0ZTIuZ2V0TmFtZXNwYWNlVVJJKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMl9hdHQyX25hbWUiLCAieG1sbnMiLCBuYW1lKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzAyX2F0dDJfbm9kZU5hbWUiLCAieG1sbnMiLCBub2RlTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMl9hdHQyX25vZGVWYWx1ZSIsICIiLCBub2RlVmFsdWUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDJfYXR0Ml9uYW1lc3BhY2VVUkkiLCAiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iLCBuYW1lc3BhY2VVUkkpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzAzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhmNDU3YjAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMy5qYXZhCkBAIC0wLDAgKzEsMTI1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKworUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKKworUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCisKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKwordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKKworUFVSUE9TRS4gIAorCisKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2QgY3JlYXRlQXR0cmlidXRlTlMgcmFpc2VzIGFuIElOVkFMSURfQ0hBUkFDVEVSX0VSUiBpZiB0aGUgc3BlY2lmaWVkIAorICogIHF1YWxpZmllZCBuYW1lIGNvbnRhaW5zIGFuIGlsbGVnYWwgY2hhcmFjdGVyCisgKiAgCisgKiAgSW52b2tlIHRoZSBjcmVhdGVBdHRyaWJ1dGVOUyBtZXRob2Qgb24gdGhpcyBEb2N1bWVudCBvYmplY3Qgd2l0aCBhIHZhbGlkIHZhbHVlIGZvciAKKyAqICBuYW1lc3BhY2VVUkksIGFuZCBxdWFsaWZpZWROYW1lcyB0aGF0IGNvbnRhaW4gaWxsZWdhbCBjaGFyYWN0ZXJzLiAgQ2hlY2sgaWYgdGhlIGFuCisgKiAgSU5WQUxJRF9DSEFSQUNURVJfRVJSIHdhcyB0aHJvd24uCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRG9jQ3JBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckF0dHJOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzAzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvTGV2ZWwyIjsKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lOworICAgICAgamF2YS51dGlsLkxpc3QgcXVhbGlmaWVkTmFtZXMgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCIvIik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIi8vIik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIlxcIik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIjsiKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiJiIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCIqIik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIl1dIik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIj4iKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiPCIpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA1QSA9IDA7IGluZGV4TjEwMDVBIDwgcXVhbGlmaWVkTmFtZXMuc2l6ZSgpOyBpbmRleE4xMDA1QSsrKSB7CisgICAgICAgICAgcXVhbGlmaWVkTmFtZSA9IChTdHJpbmcpIHF1YWxpZmllZE5hbWVzLmdldChpbmRleE4xMDA1QSk7CisgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoImRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMyIsIHN1Y2Nlc3MpOworICAgICAgfQorICB9CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzAzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmFlOTgwMAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA0LmphdmEKQEAgLTAsMCArMSwxMjEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKKworaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorCitQVVJQT1NFLiAgCisKKworCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCBjcmVhdGVBdHRyaWJ1dGVOUyByYWlzZXMgYSBOQU1FU1BBQ0VfRVJSIGlmIHRoZSBzcGVjaWZpZWQgcXVhbGlmaWVkIG5hbWUgCisgKiAgaXMgbWFsZm9ybWVkLgorICogIAorICogIEludm9rZSB0aGUgY3JlYXRlQXR0cmlidXRlTlMgbWV0aG9kIG9uIHRoaXMgRG9jdW1lbnQgb2JqZWN0IHdpdGggYSB2YWxpZCB2YWx1ZSBmb3IgCisgKiAgbmFtZXNwYWNlVVJJLCBhbmQgbWFsZm9ybWVkIHF1YWxpZmllZE5hbWVzLiAgQ2hlY2sgaWYgdGhlIGEgTkFNRVNQQUNFX0VSUiB3YXMgdGhyb3duLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyQXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRG9jQ3JBdHRyTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L0xldmVsMiI7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZTsKKyAgICAgIGphdmEudXRpbC5MaXN0IHF1YWxpZmllZE5hbWVzID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiXzoiKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiOjBhIik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIjoiKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiYTpiOmMiKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiXzo6YSIpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA0RSA9IDA7IGluZGV4TjEwMDRFIDwgcXVhbGlmaWVkTmFtZXMuc2l6ZSgpOyBpbmRleE4xMDA0RSsrKSB7CisgICAgICAgICAgcXVhbGlmaWVkTmFtZSA9IChTdHJpbmcpIHF1YWxpZmllZE5hbWVzLmdldChpbmRleE4xMDA0RSk7CisgICAgCisgICAgICB7CisgICAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgICAgLy8gICAgIE91ciBleGNlcHRpb24gcHJpb3JpdGllcyBkaWZmZXIgZnJvbSB0aGUgc3BlYworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGF0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgICAgICAgIGZhaWwoImRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNCIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgfQorICAgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICAgIH0KKyAgfQorICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA1LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdlZWNlYTMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNS5qYXZhCkBAIC0wLDAgKzEsMTA0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIGNyZWF0ZUF0dHJpYnV0ZU5TIHJhaXNlcyBhIE5BTUVTUEFDRV9FUlIgaWYgdGhlIHF1YWxpZmllZE5hbWUgaGFzIGEgcHJlZml4IGFuZCAKKyAqICB0aGUgbmFtZXNwYWNlVVJJIGlzIG51bGwuCisgKiAgCisgKiAgSW52b2tlIHRoZSBjcmVhdGVBdHRyaWJ1dGVOUyBtZXRob2Qgb24gYSBuZXcgRG9jdW1lbnQgb2JqZWN0IHdpdGggYSBudWxsIHZhbHVlIGZvciAKKyAqICBuYW1lc3BhY2VVUkksIGFuZCBhIHZhbGlkIHF1YWxpZmllZE5hbWUuICBDaGVjayBpZiBhIE5BTUVTUEFDRV9FUlIgaXMgdGhyb3duLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyQXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRG9jQ3JBdHRyTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA1KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnQgbmV3RG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGUgPSBudWxsOworCisgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gbnVsbDsKKworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiYWJjOmRlZiI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICBuZXdEb2MgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJkb206ZG9jIiwgZG9jVHlwZSk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGF0dHJpYnV0ZSA9IG5ld0RvYy5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoImRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNSIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA2LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhmNDc4MDEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNi5qYXZhCkBAIC0wLDAgKzEsMTA0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIGNyZWF0ZUF0dHJpYnV0ZU5TIHJhaXNlcyBhIE5BTUVTUEFDRV9FUlIgaWYgdGhlIHF1YWxpZmllZE5hbWUgaGFzIGEgcHJlZml4IHRoYXQgCisgKiAgaXMgInhtbCIgYW5kIHRoZSBuYW1lc3BhY2VVUkkgaXMgZGlmZmVyZW50IGZyb20gImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIuCisgKiAgCisgKiAgSW52b2tlIHRoZSBjcmVhdGVBdHRyaWJ1dGVOUyBtZXRob2Qgb24gYSBuZXcgRE9NSW1wbGVtZW50YXRpb24gb2JqZWN0IHdpdGggIHRoZSBxdWFsaWZpZWROYW1lIAorICogIGFzIHhtbDpyb290IGFuZCBuYW1lc3BhY2VVUkkgYXMgaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTggL25hbWVzcGFjZS4KKyAqICBDaGVjayBpZiB0aGUgTkFNRVNQQUNFX0VSUiBleGNlcHRpb24gaXMgdGhyb3duLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyQXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRG9jQ3JBdHRyTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA2KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnQgbmV3RG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGUgPSBudWxsOworCisgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4IC9uYW1lc3BhY2UiOworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAieG1sOnJvb3QiOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgbmV3RG9jID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudCgiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLCAiZG9tOmRvYyIsIGRvY1R5cGUpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhdHRyaWJ1dGUgPSBuZXdEb2MuY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDYiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA2IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDYuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOTk0Nzk3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDcuamF2YQpAQCAtMCwwICsxLDExMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKworKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCisKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKworSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAorCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisKK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCisKK1BVUlBPU0UuICAKKworCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIGNyZWF0ZUF0dHJpYnV0ZU5TIHJhaXNlcyBhIE5BTUVTUEFDRV9FUlIgaWYgdGhlIHF1YWxpZmllZE5hbWUgaXMgeG1sbnMgYW5kIAorICogIHRoZSBuYW1lc3BhY2VVUkkgaXMgZGlmZmVyZW50IGZyb20gaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucworICogIAorICogIEludm9rZSB0aGUgY3JlYXRlQXR0cmlidXRlTlMgbWV0aG9kIG9uIHRoaXMgRE9NSW1wbGVtZW50YXRpb24gb2JqZWN0IHdpdGggIAorICogIHRoZSBxdWFsaWZpZWROYW1lIGFzIHhtbG5zIGFuZCBuYW1lc3BhY2VVUkkgYXMgaHR0cDovL3d3dy5XMy5vcmcvMjAwMC94bWxucy4gIAorICogIENoZWNrIGlmIHRoZSBOQU1FU1BBQ0VfRVJSIGV4Y2VwdGlvbiBpcyB0aHJvd24uCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRG9jQ3JBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckF0dHJOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA3IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDcoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5XMy5vcmcvMjAwMC94bWxucyI7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJ4bWxucyI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGF0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoImRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNyIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDciOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwNy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGNyZWF0ZWVsZW1lbnROUzAxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTAzMTk0MQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwMS5qYXZhCkBAIC0wLDAgKzEsMTE1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKworUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKKworUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCisKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKwordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKKworUFVSUE9TRS4gIAorCisKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2QgY3JlYXRlRWxlbWVudE5TIGNyZWF0ZXMgYW4gZWxlbWVudCBvZiB0aGUgZ2l2ZW4gdmFsaWQgcXVhbGlmaWVkTmFtZSBhbmQgTmFtZXNwYWNlVVJJLiAKKyAqICAKKyAqICBJbnZva2UgdGhlIGNyZWF0ZUVsZW1lbnROUyBtZXRob2Qgb24gdGhpcyBEb2N1bWVudCBvYmplY3Qgd2l0aCBhIHZhbGlkIG5hbWVzcGFjZVVSSQorICogIGFuZCBxdWFsaWZpZWROYW1lLiAgQ2hlY2sgaWYgYSB2YWxpZCBFbGVtZW50IG9iamVjdCBpcyByZXR1cm5lZCB3aXRoIHRoZSBzYW1lIG5vZGUgYXR0cmlidXRlcy4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckVsTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Eb2NDckVsTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L2xldmVsMiI7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJYTUw6WE1MIjsKKyAgICAgIFN0cmluZyBub2RlTmFtZTsKKyAgICAgIFN0cmluZyBuc1VSSTsKKyAgICAgIFN0cmluZyBsb2NhbE5hbWU7CisgICAgICBTdHJpbmcgcHJlZml4OworICAgICAgU3RyaW5nIHRhZ05hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgbm9kZU5hbWUgPSBlbGVtZW50LmdldE5vZGVOYW1lKCk7CisgICAgICBuc1VSSSA9IGVsZW1lbnQuZ2V0TmFtZXNwYWNlVVJJKCk7CisgICAgICBsb2NhbE5hbWUgPSBlbGVtZW50LmdldExvY2FsTmFtZSgpOworICAgICAgcHJlZml4ID0gZWxlbWVudC5nZXRQcmVmaXgoKTsKKyAgICAgIHRhZ05hbWUgPSBlbGVtZW50LmdldFRhZ05hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwMV9ub2RlTmFtZSIsICJYTUw6WE1MIiwgbm9kZU5hbWUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGNyZWF0ZWVsZW1lbnROUzAxX25hbWVzcGFjZVVSSSIsICJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9sZXZlbDIiLCBuc1VSSSk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDFfbG9jYWxOYW1lIiwgIlhNTCIsIGxvY2FsTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDFfcHJlZml4IiwgIlhNTCIsIHByZWZpeCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDFfdGFnTmFtZSIsICJYTUw6WE1MIiwgdGFnTmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2Y2VkYjIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDIuamF2YQpAQCAtMCwwICsxLDExMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKworKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCisKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKworSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAorCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisKK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCisKK1BVUlBPU0UuICAKKworCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIGNyZWF0ZUVsZW1lbnROUyBjcmVhdGVzIGFuIGVsZW1lbnQgb2YgdGhlIGdpdmVuIHZhbGlkIHF1YWxpZmllZE5hbWUgYW5kIE5hbWVzcGFjZVVSSS4gCisgKiAgCisgKiAgSW52b2tlIHRoZSBjcmVhdGVFbGVtZW50TlMgbWV0aG9kIG9uIHRoaXMgRG9jdW1lbnQgb2JqZWN0IHdpdGggbnVsbCB2YWx1ZXMgZm9yIG5hbWVzcGFjZVVSSSwgCisgKiAgYW5kIGEgcXVhbGlmaWVkTmFtZSB3aXRoIGFuIGludmFsaWQgY2hhcmFjdGVyIGFuZCBjaGVjayBpZiBhbiBJTlZBTElEX0NIQVJBQ1RFUl9FUlIgaXMgdGhyb3duLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyRWxOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyRWxOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSBudWxsOworCisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJeXiI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJkb2N1bWVudGNyZWF0ZWVsZW1lbnROUzAyIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwNS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYwMTE1MGYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDUuamF2YQpAQCAtMCwwICsxLDExMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKworKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCisKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKworSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAorCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisKK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCisKK1BVUlBPU0UuICAKKworCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIGNyZWF0ZUVsZW1lbnROUyByYWlzZXMgYSBOQU1FU1BBQ0VfRVJSIGlmIHRoZSBxdWFsaWZpZWROYW1lIGhhcyBhIHByZWZpeCBhbmQgCisgKiAgdGhlIG5hbWVzcGFjZVVSSSBpcyBudWxsLgorICogIAorICogIEludm9rZSB0aGUgY3JlYXRlRWxlbWVudE5TIG1ldGhvZCBvbiBhIG5ldyBEb2N1bWVudCBvYmplY3Qgd2l0aCBhIG51bGwgdmFsdWUgZm9yIAorICogIG5hbWVzcGFjZVVSSSwgYW5kIGEgdmFsaWQgcXVhbGlmaWVkTmFtZS4gIENoZWNrIGlmIGEgTkFNRVNQQUNFX0VSUiBpcyB0aHJvd24uCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRG9jQ3JFbE5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRG9jQ3JFbE5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGNyZWF0ZWVsZW1lbnROUzA1IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGNyZWF0ZWVsZW1lbnROUzA1KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9IG51bGw7CisKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gIm51bGw6eG1sIjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJkb2N1bWVudGNyZWF0ZWVsZW1lbnROUzA1Iiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDYuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwNi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQyZTM5MzUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDYuamF2YQpAQCAtMCwwICsxLDEwNSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIG1ldGhvZCBjcmVhdGVFbGVtZW50TlMgcmFpc2VzIGEgTkFNRVNQQUNFX0VSUiBpZiB0aGUgcXVhbGlmaWVkTmFtZSAKKyAqICAgICBoYXMgYSBwcmVmaXggdGhhdCBpcyAieG1sIiBhbmQgdGhlIG5hbWVzcGFjZVVSSSBpcyBkaWZmZXJlbnQKKyAqICAgICBmcm9tIGh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZQorICogIAorICogIEludm9rZSB0aGUgY3JlYXRlRWxlbWVudE5TIG1ldGhvZCBvbiB0aGlzIERPTUltcGxlbWVudGF0aW9uIG9iamVjdCB3aXRoICAKKyAqICB0aGUgcXVhbGlmaWVkTmFtZSBhcyB4bWw6cm9vdCBhbmQgbmFtZXNwYWNlVVJJIGFzIGh0dHA6Ly93d3cudzMub3JnL3htbC8xOTk4L25hbWVzcGFjZQorICogIENoZWNrIGlmIHRoZSBOQU1FU1BBQ0VfRVJSIGV4Y2VwdGlvbiBpcyB0aHJvd24uCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRG9jQ3JFbE5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRG9jQ3JFbE5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGNyZWF0ZWVsZW1lbnROUzA2IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGNyZWF0ZWVsZW1lbnROUzA2KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnQgbmV3RG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGUgPSBudWxsOworCisgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LnczLm9yZy94bWwvMTk5OC9uYW1lc3BhY2UgIjsKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gInhtbDpyb290IjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgIG5ld0RvYyA9IGRvbUltcGwuY3JlYXRlRG9jdW1lbnQoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgImRvbTpkb2MiLCBkb2NUeXBlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgZWxlbWVudCA9IG5ld0RvYy5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJkb2N1bWVudGNyZWF0ZWVsZW1lbnROUzA2Iiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDYiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDYuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudGJ5aWQwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGdldGVsZW1lbnRieWlkMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NzJmYTQ3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGdldGVsZW1lbnRieWlkMDEuamF2YQpAQCAtMCwwICsxLDEwMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKworKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCisKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKworSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAorCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisKK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCisKK1BVUlBPU0UuICAKKworCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIGdldEVsZW1lbnRCeUlkIHJldHVybnMgdGhlIGVsZW1lbnQgd2hvc2UgSUQgaXMgZ2l2ZW4gYnkgZWxlbWVudElkLgorICogIElmIG5vdCBzdWNoIGVsZW1lbnQgZXhpc3RzLCByZXR1cm5zIG51bGwuCisgKiAgCisgKiAgSW52b2tlIHRoZSBnZXRFbGVtZW50QnlJZCBtZXRob2Qgb24gdGhpcyBEb2N1bWVudCBvYmplY3Qgd2l0aCBhbiBpbnZhbGlkIGVsZW1lbnRJZC4gCisgKiAgVGhpcyBzaG91bGQgcmV0dXJuIGEgbnVsbCBlbGVtZW50LgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQklkIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0RWxCSWQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50Z2V0ZWxlbWVudGJ5aWQwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRnZXRlbGVtZW50YnlpZDAxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgU3RyaW5nIGVsZW1lbnRJZCA9ICItLS0iOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudCA9IGRvYy5nZXRFbGVtZW50QnlJZChlbGVtZW50SWQpOworICAgICAgYXNzZXJ0TnVsbCgiZG9jdW1lbnRnZXRlbGVtZW50YnlpZDAxIiwgZWxlbWVudCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudGJ5aWQwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRnZXRlbGVtZW50YnlpZDAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg4MzIwZGMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzAxLmphdmEKQEAgLTAsMCArMSw5NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMgcmV0dXJucyBhIE5vZGVMaXN0IG9mIGFsbCB0aGUgRWxlbWVudHMgd2l0aCAKKyAqICBhIGdpdmVuIGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkgaW4gdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlIGVuY291bnRlcmVkIAorICogIGluIGEgcHJlb3JkZXIgdHJhdmVyc2FsIG9mIHRoZSBEb2N1bWVudCB0cmVlLgorICogIAorICogIEludm9rZSB0aGUgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyBtZXRob2Qgb24gYSBuZXcgRG9jdW1lbnQgb2JqZWN0IHdpdGggdGhlIHZhbHVlcyBvZgorICogIG5hbWVzcGFjZVVSST0qIGFuZCBsb2NhbE5hbWU9Ki4gIFRoaXMgc2hvdWxkIHJldHVybiBhIG5vZGVMaXN0IG9mIDEgaXRlbS4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXRFbEJUTk5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0RWxCVE5OUzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBuZXdEb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZSA9IG51bGw7CisKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBTdHJpbmcgbnVsbE5TID0gbnVsbDsKKworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgbmV3RG9jID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudChudWxsTlMsICJyb290IiwgZG9jVHlwZSk7CisgICAgICBjaGlsZExpc3QgPSBuZXdEb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICIqIik7CisgICAgICBhc3NlcnRTaXplKCJkb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwMSIsIDEsIGNoaWxkTGlzdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMGI3Mjg4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwMi5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMgcmV0dXJucyBhIE5vZGVMaXN0IG9mIGFsbCB0aGUgRWxlbWVudHMgd2l0aCAKKyAqICBhIGdpdmVuIGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkgaW4gdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlIGVuY291bnRlcmVkIAorICogIGluIGEgcHJlb3JkZXIgdHJhdmVyc2FsIG9mIHRoZSBEb2N1bWVudCB0cmVlLgorICogIAorICogIAorICogIENyZWF0ZSBhIG5ldyBlbGVtZW50IGhhdmluZyBhIGxvY2FsIG5hbWU9ImVtcGxveWVlSWQiIGJlbG9uZ2luZyB0byB0aGUgbmFtZXNwYWNlICJ0ZXN0IgorICogIGFuZCBhcHBlbmQgaXQgdG8gdGhpcyBkb2N1bWVudC4gIEludm9rZSB0aGUgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyBtZXRob2Qgb24gYSB0aGlzCisgKiAgRG9jdW1lbnQgb2JqZWN0IHdpdGggdGhlIHZhbHVlcyBvZiBuYW1lc3BhY2VVUkk9KiBhbmQgbG9jYWxOYW1lPSJlbGVtZW50SWQiLiAgVGhpcyAKKyAqICBzaG91bGQgcmV0dXJuIGEgbm9kZUxpc3Qgb2YgNiBpdGVtLiAgQ2hlY2sgdGhlIGxlbmd0aCBvZiB0aGUgbm9kZUxpc3QgcmV0dXJuZWQuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0RWxCVE5OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQlROTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzAyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBkb2NFbGVtOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgTm9kZSBhcHBlbmRlZENoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBkb2NFbGVtID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoInRlc3QiLCAiZW1wbG95ZWVJZCIpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGRvY0VsZW0uYXBwZW5kQ2hpbGQoZWxlbWVudCk7CisgICAgICBjaGlsZExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJlbXBsb3llZUlkIik7CisgICAgICBhc3NlcnRTaXplKCJkb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwMiIsIDYsIGNoaWxkTGlzdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzAyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yN2ZjN2Y0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwMy5qYXZhCkBAIC0wLDAgKzEsODggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2QgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyByZXR1cm5zIGEgTm9kZUxpc3Qgb2YgYWxsIHRoZSBFbGVtZW50cyB3aXRoIAorICogIGEgZ2l2ZW4gbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmUgZW5jb3VudGVyZWQgCisgKiAgaW4gYSBwcmVvcmRlciB0cmF2ZXJzYWwgb2YgdGhlIERvY3VtZW50IHRyZWUuCisgKiAgCisgKiAgSW52b2tlIHRoZSBnZXRFbGVtZW50c0J5VGFnTmFtZU5TIG1ldGhvZCBvbiBhIG5ldyBEb2N1bWVudCBvYmplY3Qgd2l0aCB0aGUgdmFsdWVzIG9mCisgKiAgbmFtZXNwYWNlVVJJPSoqIGFuZCBsb2NhbE5hbWU9KiouICBUaGlzIHNob3VsZCByZXR1cm4gYSBub2RlTGlzdCBvZiAwIGl0ZW1zLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQlROTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXRFbEJUTk5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwMyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBjaGlsZExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKioiLCAiKiIpOworICAgICAgYXNzZXJ0U2l6ZSgiZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDMiLCAwLCBjaGlsZExpc3QpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzA0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTM0OTAzNwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDQuamF2YQpAQCAtMCwwICsxLDk3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2QgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyByZXR1cm5zIGEgTm9kZUxpc3Qgb2YgYWxsIHRoZSBFbGVtZW50cyB3aXRoIAorICogIGEgZ2l2ZW4gbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmUgZW5jb3VudGVyZWQgCisgKiAgaW4gYSBwcmVvcmRlciB0cmF2ZXJzYWwgb2YgdGhlIERvY3VtZW50IHRyZWUuCisgKiAgCisgKiAgSW52b2tlIHRoZSBnZXRFbGVtZW50c0J5VGFnTmFtZU5TIG1ldGhvZCBvbiBhIG5ldyBEb2N1bWVudCBvYmplY3Qgd2l0aCB0aGUgdmFsdWVzIG9mCisgKiAgbmFtZXNwYWNlVVJJPSJudWxsIiBhbmQgbG9jYWxOYW1lPSIwIi4gIFRoaXMgc2hvdWxkIHJldHVybiBhIG5vZGVMaXN0IG9mIDAgaXRlbXMuICAKKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXRFbEJUTk5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0RWxCVE5OUzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBTdHJpbmcgbnVsbE5TID0gbnVsbDsKKworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgY2hpbGRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMobnVsbE5TLCAiMCIpOworICAgICAgYXNzZXJ0U2l6ZSgiZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDQiLCAwLCBjaGlsZExpc3QpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzA1LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzA1LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWFkYWRkNAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDUuamF2YQpAQCAtMCwwICsxLDkwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMgcmV0dXJucyBhIE5vZGVMaXN0IG9mIGFsbCB0aGUgRWxlbWVudHMgd2l0aCAKKyAqICBhIGdpdmVuIGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkgaW4gdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlIGVuY291bnRlcmVkIAorICogIGluIGEgcHJlb3JkZXIgdHJhdmVyc2FsIG9mIHRoZSBEb2N1bWVudCB0cmVlLgorICogIAorICogIAorICogIEludm9rZSB0aGUgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyBtZXRob2Qgb24gYSB0aGlzIERvY3VtZW50IG9iamVjdCB3aXRoIHRoZSAKKyAqICB2YWx1ZXMgb2YgbmFtZXNwYWNlVVJJPW51bGwgYW5kIGxvY2FsTmFtZT0iZWxlbWVudElkIi4gIFRoaXMgCisgKiAgc2hvdWxkIHJldHVybiBhIG5vZGVMaXN0IG9mIDAgaXRlbS4gIENoZWNrIHRoZSBsZW5ndGggb2YgdGhlIG5vZGVMaXN0IHJldHVybmVkLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQlROTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXRFbEJUTk5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGdldGVsZW1lbnRzYnl0YWduYW1lTlMwNSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBjaGlsZExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygibnVsbCIsICJlbGVtZW50SWQiKTsKKyAgICAgIGFzc2VydFNpemUoImRvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzA1IiwgMCwgY2hpbGRMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzA1LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYzZTQ5MjkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTAxLmphdmEKQEAgLTAsMCArMSwxMTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBpbXBvcnROb2RlIG1ldGhvZCBpbXBvcnRzIGEgbm9kZSBmcm9tIGFub3RoZXIgZG9jdW1lbnQgdG8gdGhpcyBkb2N1bWVudC4gCisgKiAgVGhlIHJldHVybmVkIG5vZGUgaGFzIG5vIHBhcmVudDsgKHBhcmVudE5vZGUgaXMgbnVsbCkuIFRoZSBzb3VyY2Ugbm9kZSBpcyBub3QgCisgKiAgYWx0ZXJlZCBvciByZW1vdmVkIGZyb20gdGhlIG9yaWdpbmFsIGRvY3VtZW50IGJ1dCBhIG5ldyBjb3B5IG9mIHRoZSBzb3VyY2Ugbm9kZQorICogIGlzIGNyZWF0ZWQuCisgKiAgCisgKiAgVXNpbmcgdGhlIG1ldGhvZCBpbXBvcnROb2RlIHdpdGggZGVlcD10cnVlLCBpbXBvcnQgdGhlIGF0dHJpYnV0ZSwgInN0cmVldCIgb2YgdGhlIHNlY29uZCAKKyAqICBlbGVtZW50IG5vZGUsIGZyb20gYSBsaXN0IG9mIG5vZGVzIHdob3NlIGxvY2FsIG5hbWVzIGFyZSAiYWRkcmVzcyIgYW5kIG5hbWVzcGFjZVVSSSAKKyAqICAiaHR0cDovL3d3dy5uaXN0LmdvdiIgaW50byB0aGUgc2FtZSBkb2N1bWVudC4gIENoZWNrIHRoZSBwYXJlbnROb2RlLCBub2RlTmFtZSwgCisgKiAgbm9kZVR5cGUgYW5kIG5vZGVWYWx1ZSBvZiB0aGUgaW1wb3J0ZWQgbm9kZSB0byB2ZXJpZnkgaWYgaXQgaGFzIGJlZW4gaW1wb3J0ZWQgY29ycmVjdGx5LgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRpbXBvcnRub2RlMDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50aW1wb3J0bm9kZTAxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBBdHRyIGF0dHI7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIGltcG9ydGVkQXR0cjsKKyAgICAgIFN0cmluZyBub2RlTmFtZTsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIFN0cmluZyBub2RlVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGNoaWxkTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImFkZHJlc3MiKTsKKyAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgY2hpbGRMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlKCJzdHJlZXQiKTsKKyAgICAgIGltcG9ydGVkQXR0ciA9IGRvYy5pbXBvcnROb2RlKGF0dHIsIGZhbHNlKTsKKyAgICAgIG5vZGVOYW1lID0gaW1wb3J0ZWRBdHRyLmdldE5vZGVOYW1lKCk7CisgICAgICBub2RlVmFsdWUgPSBpbXBvcnRlZEF0dHIuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGltcG9ydGVkQXR0ci5nZXROb2RlVHlwZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUwMV9ub2RlTmFtZSIsICJzdHJlZXQiLCBub2RlTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTAxX25vZGVUeXBlIiwgMiwgbm9kZVR5cGUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUwMV9ub2RlVmFsdWUiLCAiWWVzIiwgbm9kZVZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50aW1wb3J0bm9kZTAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5M2Q3MjUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTAyLmphdmEKQEAgLTAsMCArMSwxMTcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIGltcG9ydE5vZGUgbWV0aG9kIGltcG9ydHMgYSBub2RlIGZyb20gYW5vdGhlciBkb2N1bWVudCB0byB0aGlzIGRvY3VtZW50LiAKKyAqICBUaGUgcmV0dXJuZWQgbm9kZSBoYXMgbm8gcGFyZW50OyAocGFyZW50Tm9kZSBpcyBudWxsKS4gVGhlIHNvdXJjZSBub2RlIGlzIG5vdCAKKyAqICBhbHRlcmVkIG9yIHJlbW92ZWQgZnJvbSB0aGUgb3JpZ2luYWwgZG9jdW1lbnQgYnV0IGEgbmV3IGNvcHkgb2YgdGhlIHNvdXJjZSBub2RlCisgKiAgaXMgY3JlYXRlZC4KKyAqICAKKyAqICBVc2luZyB0aGUgbWV0aG9kIGltcG9ydE5vZGUgd2l0aCBkZWVwPWZhbHNlLCBpbXBvcnQgdGhlIGF0dHJpYnV0ZSwgImVtcDp6b25lIiBvZiB0aGUgCisgKiAgZWxlbWVudCBub2RlIHdoaWNoIGlzIHJldHJlaXZlZCBieSBpdHMgZWxlbWVudElkPSJDQU5BREEiLCBpbnRvIHRoZSBhbm90aGVyIGRvY3VtZW50LgorICogIENoZWNrIHRoZSBwYXJlbnROb2RlLCBub2RlTmFtZSwgbm9kZVR5cGUgYW5kIG5vZGVWYWx1ZSBvZiB0aGUgaW1wb3J0ZWQgbm9kZSB0byAKKyAqICB2ZXJpZnkgaWYgaXQgaGFzIGJlZW4gaW1wb3J0ZWQgY29ycmVjdGx5LgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRpbXBvcnRub2RlMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50aW1wb3J0bm9kZTAyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBkb2NJbXBvcnRlZDsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cjsKKyAgICAgIE5vZGUgaW1wb3J0ZWRBdHRyOworICAgICAgU3RyaW5nIG5vZGVOYW1lOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgU3RyaW5nIG5vZGVWYWx1ZTsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NlczsKKyAgICAgIE5vZGUgYXR0cnNQYXJlbnQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGRvY0ltcG9ydGVkID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgYWRkcmVzc2VzID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAiYWRkcmVzcyIpOworICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBhZGRyZXNzZXMuaXRlbSgxKTsKKyAgICAgIGF0dHIgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5vZGVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJ6b25lIik7CisgICAgICBpbXBvcnRlZEF0dHIgPSBkb2NJbXBvcnRlZC5pbXBvcnROb2RlKGF0dHIsIGZhbHNlKTsKKyAgICAgIG5vZGVOYW1lID0gaW1wb3J0ZWRBdHRyLmdldE5vZGVOYW1lKCk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGltcG9ydGVkQXR0ci5nZXROb2RlVHlwZSgpOworICAgICAgbm9kZVZhbHVlID0gaW1wb3J0ZWRBdHRyLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXR0cnNQYXJlbnQgPSBpbXBvcnRlZEF0dHIuZ2V0UGFyZW50Tm9kZSgpOworICAgICAgYXNzZXJ0TnVsbCgiZG9jdW1lbnRpbXBvcnRub2RlMDJfcGFyZW50TnVsbCIsIGF0dHJzUGFyZW50KTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMDJfbm9kZU5hbWUiLCAiZW1wOnpvbmUiLCBub2RlTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTAyX25vZGVUeXBlIiwgMiwgbm9kZVR5cGUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUwMl9ub2RlVmFsdWUiLCAiQ0FOQURBIiwgbm9kZVZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50aW1wb3J0bm9kZTAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZjZGI5OGQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTAzLmphdmEKQEAgLTAsMCArMSwxMTMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIGltcG9ydE5vZGUgbWV0aG9kIGltcG9ydHMgYSBub2RlIGZyb20gYW5vdGhlciBkb2N1bWVudCB0byB0aGlzIGRvY3VtZW50LiAKKyAqICBUaGUgcmV0dXJuZWQgbm9kZSBoYXMgbm8gcGFyZW50OyAocGFyZW50Tm9kZSBpcyBudWxsKS4gVGhlIHNvdXJjZSBub2RlIGlzIG5vdCAKKyAqICBhbHRlcmVkIG9yIHJlbW92ZWQgZnJvbSB0aGUgb3JpZ2luYWwgZG9jdW1lbnQgYnV0IGEgbmV3IGNvcHkgb2YgdGhlIHNvdXJjZSBub2RlCisgKiAgaXMgY3JlYXRlZC4KKyAqICAKKyAqICBVc2luZyB0aGUgbWV0aG9kIGltcG9ydE5vZGUgd2l0aCBkZWVwPWZhbHNlLCBpbXBvcnQgdGhlIGRlZmF1bHQgQXR0cmlidXRlIGF0dHJpYnV0ZSwgCisgKiAgImRlZmF1bHRBdHRyIiBvZiB0aGUgc2Vjb25kIGVsZW1lbnQgbm9kZSB3aG9zZSBuYW1lc3BhY2VVUkk9Imh0dHA6Ly93d3cubmlzdC5nb3YiIGFuZCAKKyAqICBsb2NhbE5hbWU9ImRlZmF1bHRBdHRyIiwgaW50byB0aGUgc2FtZSBkb2N1bWVudC4KKyAqICBDaGVjayB0aGUgcGFyZW50Tm9kZSwgbm9kZU5hbWUsIG5vZGVUeXBlIGFuZCBub2RlVmFsdWUgb2YgdGhlIGltcG9ydGVkIG5vZGUgdG8gCisgKiAgdmVyaWZ5IGlmIGl0IGhhcyBiZWVuIGltcG9ydGVkIGNvcnJlY3RseS4gIAorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRpbXBvcnRub2RlMDMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50aW1wb3J0bm9kZTAzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlLAorb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLnZhbGlkYXRpbmcKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cjsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgaW1wb3J0ZWRBdHRyOworICAgICAgU3RyaW5nIG5vZGVOYW1lOworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgU3RyaW5nIG5vZGVWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgY2hpbGRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAiZW1wbG95ZWUiKTsKKyAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgY2hpbGRMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlKCJkZWZhdWx0QXR0ciIpOworICAgICAgaW1wb3J0ZWRBdHRyID0gZG9jLmltcG9ydE5vZGUoYXR0ciwgZmFsc2UpOworICAgICAgbm9kZU5hbWUgPSBpbXBvcnRlZEF0dHIuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIG5vZGVWYWx1ZSA9IGltcG9ydGVkQXR0ci5nZXROb2RlVmFsdWUoKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgaW1wb3J0ZWRBdHRyLmdldE5vZGVUeXBlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTAzX25vZGVOYW1lIiwgImRlZmF1bHRBdHRyIiwgbm9kZU5hbWUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUwM19ub2RlVHlwZSIsIDIsIG5vZGVUeXBlKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMDNfbm9kZVZhbHVlIiwgImRlZmF1bHRWYWwiLCBub2RlVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRpbXBvcnRub2RlMDMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTA0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTc0Y2ZjMQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMDQuamF2YQpAQCAtMCwwICsxLDExOSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgaW1wb3J0Tm9kZSBtZXRob2QgaW1wb3J0cyBhIG5vZGUgZnJvbSBhbm90aGVyIGRvY3VtZW50IHRvIHRoaXMgZG9jdW1lbnQuIAorICogIFRoZSByZXR1cm5lZCBub2RlIGhhcyBubyBwYXJlbnQ7IChwYXJlbnROb2RlIGlzIG51bGwpLiBUaGUgc291cmNlIG5vZGUgaXMgbm90IAorICogIGFsdGVyZWQgb3IgcmVtb3ZlZCBmcm9tIHRoZSBvcmlnaW5hbCBkb2N1bWVudCBidXQgYSBuZXcgY29weSBvZiB0aGUgc291cmNlIG5vZGUKKyAqICBpcyBjcmVhdGVkLgorICogIAorICogIFVzaW5nIHRoZSBtZXRob2QgaW1wb3J0Tm9kZSB3aXRoIGRlZXA9dHJ1ZSwgaW1wb3J0IHRoZSBkZWZhdWx0IEF0dHJpYnV0ZSBhdHRyaWJ1dGUsIAorICogICJkZWZhdWx0QXR0ciIgb2YgdGhlIHNlY29uZCBlbGVtZW50IG5vZGUgd2hvc2UgbmFtZXNwYWNlVVJJPSJodHRwOi8vd3d3Lm5pc3QuZ292IiBhbmQgCisgKiAgbG9jYWxOYW1lPSJkZWZhdWx0QXR0ciIsIGludG8gYSBuZXcgZG9jdW1lbnQuCisgKiAgQ2hlY2sgdGhlIHBhcmVudE5vZGUsIG5vZGVOYW1lLCBub2RlVHlwZSBhbmQgbm9kZVZhbHVlIG9mIHRoZSBpbXBvcnRlZCBub2RlIHRvIAorICogIHZlcmlmeSBpZiBpdCBoYXMgYmVlbiBpbXBvcnRlZCBjb3JyZWN0bHkuICAKKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50aW1wb3J0bm9kZTA0IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGltcG9ydG5vZGUwNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZSwKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy52YWxpZGF0aW5nCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBuZXdEb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZSA9IG51bGw7CisKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBBdHRyIGF0dHI7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBOb2RlIGltcG9ydGVkQXR0cjsKKyAgICAgIFN0cmluZyBub2RlTmFtZTsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIFN0cmluZyBub2RlVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgIG5ld0RvYyA9IGRvbUltcGwuY3JlYXRlRG9jdW1lbnQoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgImwyOnJvb3QiLCBkb2NUeXBlKTsKKyAgICAgIGNoaWxkTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImVtcGxveWVlIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGNoaWxkTGlzdC5pdGVtKDEpOworICAgICAgYXR0ciA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlTm9kZSgiZGVmYXVsdEF0dHIiKTsKKyAgICAgIGltcG9ydGVkQXR0ciA9IG5ld0RvYy5pbXBvcnROb2RlKGF0dHIsIHRydWUpOworICAgICAgbm9kZU5hbWUgPSBpbXBvcnRlZEF0dHIuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIG5vZGVWYWx1ZSA9IGltcG9ydGVkQXR0ci5nZXROb2RlVmFsdWUoKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgaW1wb3J0ZWRBdHRyLmdldE5vZGVUeXBlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTA0X25vZGVOYW1lIiwgImRlZmF1bHRBdHRyIiwgbm9kZU5hbWUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUwNF9ub2RlVHlwZSIsIDIsIG5vZGVUeXBlKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMDRfbm9kZVZhbHVlIiwgImRlZmF1bHRWYWwiLCBub2RlVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRpbXBvcnRub2RlMDQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTA1LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTA1LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmEyZTllMQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMDUuamF2YQpAQCAtMCwwICsxLDExMyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIGltcG9ydE5vZGUgbWV0aG9kIGltcG9ydHMgYSBub2RlIGZyb20gYW5vdGhlciBkb2N1bWVudCB0byB0aGlzIGRvY3VtZW50LiAKKyAqICBUaGUgcmV0dXJuZWQgbm9kZSBoYXMgbm8gcGFyZW50OyAocGFyZW50Tm9kZSBpcyBudWxsKS4gVGhlIHNvdXJjZSBub2RlIGlzIG5vdCAKKyAqICBhbHRlcmVkIG9yIHJlbW92ZWQgZnJvbSB0aGUgb3JpZ2luYWwgZG9jdW1lbnQgYnV0IGEgbmV3IGNvcHkgb2YgdGhlIHNvdXJjZSBub2RlCisgKiAgaXMgY3JlYXRlZC4KKyAqICAKKyAqICBVc2luZyB0aGUgbWV0aG9kIGltcG9ydE5vZGUgd2l0aCBkZWVwPWZhbHNlLCBpbXBvcnQgYSBuZXdseSBjcmVhdGVkIGF0dHJpYnV0ZSBub2RlLCAKKyAqICBpbnRvIHRoZSBhbm90aGVyIGRvY3VtZW50LgorICogIENoZWNrIHRoZSBub2RlTmFtZSwgbm9kZVR5cGUgYW5kIG5vZGVWYWx1ZSBuYW1lc3BhY2VVUkkgb2YgdGhlIGltcG9ydGVkIG5vZGUgdG8gCisgKiAgdmVyaWZ5IGlmIGl0IGhhcyBiZWVuIGltcG9ydGVkIGNvcnJlY3RseS4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50aW1wb3J0bm9kZTA1IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGltcG9ydG5vZGUwNShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnQgZG9jSW1wb3J0ZWQ7CisgICAgICBBdHRyIGF0dHI7CisgICAgICBOb2RlIGltcG9ydGVkQXR0cjsKKyAgICAgIFN0cmluZyBub2RlTmFtZTsKKyAgICAgIGludCBub2RlVHlwZTsKKyAgICAgIFN0cmluZyBub2RlVmFsdWU7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBkb2NJbXBvcnRlZCA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGF0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgImFfOmIwIik7CisgICAgICBpbXBvcnRlZEF0dHIgPSBkb2NJbXBvcnRlZC5pbXBvcnROb2RlKGF0dHIsIGZhbHNlKTsKKyAgICAgIG5vZGVOYW1lID0gaW1wb3J0ZWRBdHRyLmdldE5vZGVOYW1lKCk7CisgICAgICBub2RlVmFsdWUgPSBpbXBvcnRlZEF0dHIuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGltcG9ydGVkQXR0ci5nZXROb2RlVHlwZSgpOworICAgICAgbmFtZXNwYWNlVVJJID0gaW1wb3J0ZWRBdHRyLmdldE5hbWVzcGFjZVVSSSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUwNV9ub2RlTmFtZSIsICJhXzpiMCIsIG5vZGVOYW1lKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMDVfbm9kZVR5cGUiLCAyLCBub2RlVHlwZSk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTA1X25vZGVWYWx1ZSIsICIiLCBub2RlVmFsdWUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUwNV9uYW1lc3BhY2VVUkkiLCAiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLCBuYW1lc3BhY2VVUkkpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwNSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRpbXBvcnRub2RlMDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTA2LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTA2LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2U3ZTIyOAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMDYuamF2YQpAQCAtMCwwICsxLDEwMiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgaW1wb3J0Tm9kZSBtZXRob2QgaW1wb3J0cyBhIG5vZGUgZnJvbSBhbm90aGVyIGRvY3VtZW50IHRvIHRoaXMgZG9jdW1lbnQuIAorICogIEEgTk9UX1NVUFBPUlRFRF9FUlIgaXMgcmFpc2VkIGlmIHRoZSB0eXBlIG9mIG5vZGUgYmVpbmcgaW1wb3J0ZWQgaXMKKyAqICBub3Qgc3VwcG9ydGVkCisgKiAgCisgKiAgVXNpbmcgdGhlIG1ldGhvZCBpbXBvcnROb2RlIHdpdGggZGVlcD1mYWxzZSwgdHJ5IHRvIGltcG9ydCB0aGlzIGRvY3VtZW50IG9iamVjdCB0byBpdHNlbGYuIAorICogIFNpbmNlIERvY3VtZW50IG5vZGVzIGNhbm5vdCBiZSBpbXBvcnRlZCwgYSBOT1RfU1VQUE9SVEVEX0VSUiBzaG91bGQgYmUgcmFpc2VkLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRpbXBvcnRub2RlMDYgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50aW1wb3J0bm9kZTA2KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBkb2NJbXBvcnRlZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkb2NJbXBvcnRlZCA9IChEb2N1bWVudCkgZG9jLmltcG9ydE5vZGUoZG9jLCBmYWxzZSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9TVVBQT1JURURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTA2IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGltcG9ydG5vZGUwNi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMDcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMDcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMWZmZDYwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwNy5qYXZhCkBAIC0wLDAgKzEsMTA1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBpbXBvcnROb2RlIG1ldGhvZCBpbXBvcnRzIGEgbm9kZSBmcm9tIGFub3RoZXIgZG9jdW1lbnQgdG8gdGhpcyBkb2N1bWVudC4gCisgKiAgQSBOT1RfU1VQUE9SVEVEX0VSUiBpcyByYWlzZWQgaWYgdGhlIHR5cGUgb2Ygbm9kZSBiZWluZyBpbXBvcnRlZCBpcworICogIG5vdCBzdXBwb3J0ZWQKKyAqICAKKyAqICBVc2luZyB0aGUgbWV0aG9kIGltcG9ydE5vZGUgd2l0aCBkZWVwPXRydWUsIHRyeSB0byBpbXBvcnQgdGhpcyBEb2N1bWVudCdzIAorICogIERvY3VtZW50VHlwZSBvYmplY3QuIFNpbmNlIERvY3VtZW50VHlwZSBub2RlcyBjYW5ub3QgYmUgaW1wb3J0ZWQsIGEgCisgKiAgTk9UX1NVUFBPUlRFRF9FUlIgc2hvdWxkIGJlIHJhaXNlZC4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50aW1wb3J0bm9kZTA3IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGltcG9ydG5vZGUwNyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBpbXBvcnRlZDsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgaW1wb3J0ZWQgPSBkb2MuaW1wb3J0Tm9kZShkb2NUeXBlLCB0cnVlKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9UX1NVUFBPUlRFRF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMDciOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50aW1wb3J0bm9kZTA3LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwOC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwOC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE1YzdkMWYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTA4LmphdmEKQEAgLTAsMCArMSwxMDkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIGltcG9ydE5vZGUgbWV0aG9kIGltcG9ydHMgYSBub2RlIGZyb20gYW5vdGhlciBkb2N1bWVudCB0byB0aGlzIGRvY3VtZW50LiAKKyAqICBBIE5PVF9TVVBQT1JURURfRVJSIGlzIHJhaXNlZCBpZiB0aGUgdHlwZSBvZiBub2RlIGJlaW5nIGltcG9ydGVkIGlzCisgKiAgbm90IHN1cHBvcnRlZAorICogIAorICogIFVzaW5nIHRoZSBtZXRob2QgaW1wb3J0Tm9kZSB3aXRoIGRlZXA9dHJ1ZSwgdHJ5IHRvIGltcG9ydCBhIG5ld2x5IGNyZWF0ZWQgRE9jdW1lbnRUeXBlCisgKiAgbm9kZS4gU2luY2UgRG9jdW1lbnRUeXBlIG5vZGVzIGNhbm5vdCBiZSBpbXBvcnRlZCwgYSBOT1RfU1VQUE9SVEVEX0VSUiBzaG91bGQgYmUgcmFpc2VkLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGltcG9ydG5vZGUwOCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRpbXBvcnRub2RlMDgoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGUgaW1wb3J0ZWQ7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBTdHJpbmcgbnVsbE5TID0gbnVsbDsKKworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICBkb2NUeXBlID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudFR5cGUoInRlc3Q6cm9vdCIsIG51bGxOUywgbnVsbE5TKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgaW1wb3J0ZWQgPSBkb2MuaW1wb3J0Tm9kZShkb2NUeXBlLCB0cnVlKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9UX1NVUFBPUlRFRF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMDgiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50aW1wb3J0bm9kZTA4LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwOS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUwOS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZlZmU4YWQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTA5LmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBpbXBvcnROb2RlIG1ldGhvZCBpbXBvcnRzIGEgbm9kZSBmcm9tIGFub3RoZXIgZG9jdW1lbnQgdG8gdGhpcyBkb2N1bWVudC4gCisgKiAgVGhlIHJldHVybmVkIG5vZGUgaGFzIG5vIHBhcmVudDsgKHBhcmVudE5vZGUgaXMgbnVsbCkuIFRoZSBzb3VyY2Ugbm9kZSBpcyBub3QgCisgKiAgYWx0ZXJlZCBvciByZW1vdmVkIGZyb20gdGhlIG9yaWdpbmFsIGRvY3VtZW50IGJ1dCBhIG5ldyBjb3B5IG9mIHRoZSBzb3VyY2Ugbm9kZQorICogIGlzIGNyZWF0ZWQuCisgKiAgCisgKiAgVXNpbmcgdGhlIG1ldGhvZCBpbXBvcnROb2RlIHdpdGggZGVlcD1mYWxzZSwgaW1wb3J0IGEgbmV3bHkgY3JlYXRlZCBEb2N1bWVudEZyYWdtZW50IG5vZGUKKyAqICB3aXRoIHRoZSBmaXJzdCBhZGRyZXNzIGVsZW1lbnQgZnJvbSB0aGlzIERvY3VtZW50IGFwcGVuZGVkIHRvIGl0IGludG8gdGhpcyBkb2N1bWVudC4gCisgKiAgU2luY2UgZGVlcD1mYWxzZSwgYW4gZW1wdHkgRG9jdW1lbnRGcmFnbWVudCBzaG91bGQgYmUgcmV0dXJuZWQgCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGltcG9ydG5vZGUwOSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRpbXBvcnRub2RlMDkoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50RnJhZ21lbnQgZG9jRnJhZ21lbnQ7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBib29sZWFuIHN1Y2Nlc3M7CisgICAgICBOb2RlIGFkZHJlc3NOb2RlOworICAgICAgTm9kZSBhcHBlbmRlZENoaWxkOworICAgICAgTm9kZSBpbXBvcnRlZERvY0ZyYWc7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGRvY0ZyYWdtZW50ID0gZG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKKyAgICAgIGNoaWxkTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCIqIiwgImFkZHJlc3MiKTsKKyAgICAgIGFkZHJlc3NOb2RlID0gY2hpbGRMaXN0Lml0ZW0oMCk7CisgICAgICBhcHBlbmRlZENoaWxkID0gZG9jRnJhZ21lbnQuYXBwZW5kQ2hpbGQoYWRkcmVzc05vZGUpOworICAgICAgaW1wb3J0ZWREb2NGcmFnID0gZG9jLmltcG9ydE5vZGUoZG9jRnJhZ21lbnQsIGZhbHNlKTsKKyAgICAgIHN1Y2Nlc3MgPSBpbXBvcnRlZERvY0ZyYWcuaGFzQ2hpbGROb2RlcygpOworICAgICAgYXNzZXJ0RmFsc2UoImRvY3VtZW50aW1wb3J0bm9kZTA5Iiwgc3VjY2Vzcyk7Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTA5IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGltcG9ydG5vZGUwOS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTAuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOWM1MjAyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUxMC5qYXZhCkBAIC0wLDAgKzEsMTA2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgaW1wb3J0Tm9kZSBtZXRob2QgaW1wb3J0cyBhIG5vZGUgZnJvbSBhbm90aGVyIGRvY3VtZW50IHRvIHRoaXMgZG9jdW1lbnQuIAorICogIFRoZSByZXR1cm5lZCBub2RlIGhhcyBubyBwYXJlbnQ7IChwYXJlbnROb2RlIGlzIG51bGwpLiBUaGUgc291cmNlIG5vZGUgaXMgbm90IAorICogIGFsdGVyZWQgb3IgcmVtb3ZlZCBmcm9tIHRoZSBvcmlnaW5hbCBkb2N1bWVudCBidXQgYSBuZXcgY29weSBvZiB0aGUgc291cmNlIG5vZGUKKyAqICBpcyBjcmVhdGVkLgorICogIAorICogIFVzaW5nIHRoZSBtZXRob2QgaW1wb3J0Tm9kZSB3aXRoIGRlZXA9ZmFsc2UsIGltcG9ydCBhIG5ld2x5IGNyZWF0ZWQgRG9jdW1lbnRGcmFnbWVudCBub2RlCisgKiAgd2l0aCB0aGUgZmlyc3QgYWRkcmVzcyBlbGVtZW50IGZyb20gdGhpcyBEb2N1bWVudCBhcHBlbmRlZCB0byBpdCBpbnRvIHRoaXMgZG9jdW1lbnQuIAorICogIFNpbmNlIGRlZXA9dHJ1ZSwgYSBEb2N1bWVudEZyYWdtZW50IHdpdGggaXRzIGNoaWxkIHNob3VsZCBiZSByZXR1cm5lZCAKKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50aW1wb3J0bm9kZTEwIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGltcG9ydG5vZGUxMChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRGcmFnbWVudCBkb2NGcmFnbWVudDsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIGJvb2xlYW4gc3VjY2VzczsKKyAgICAgIE5vZGUgYWRkcmVzc05vZGU7CisgICAgICBOb2RlIGFwcGVuZGVkQ2hpbGQ7CisgICAgICBOb2RlIGltcG9ydGVkRG9jRnJhZzsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZG9jRnJhZ21lbnQgPSBkb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOworICAgICAgY2hpbGRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiYWRkcmVzcyIpOworICAgICAgYWRkcmVzc05vZGUgPSBjaGlsZExpc3QuaXRlbSgwKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBkb2NGcmFnbWVudC5hcHBlbmRDaGlsZChhZGRyZXNzTm9kZSk7CisgICAgICBpbXBvcnRlZERvY0ZyYWcgPSBkb2MuaW1wb3J0Tm9kZShkb2NGcmFnbWVudCwgdHJ1ZSk7CisgICAgICBzdWNjZXNzID0gaW1wb3J0ZWREb2NGcmFnLmhhc0NoaWxkTm9kZXMoKTsKKyAgICAgIGFzc2VydFRydWUoImRvY3VtZW50aW1wb3J0bm9kZTEwIiwgc3VjY2Vzcyk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTEwIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGltcG9ydG5vZGUxMC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kM2M5MTQ2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUxMS5qYXZhCkBAIC0wLDAgKzEsMTA1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgaW1wb3J0Tm9kZSBtZXRob2QgaW1wb3J0cyBhIG5vZGUgZnJvbSBhbm90aGVyIGRvY3VtZW50IHRvIHRoaXMgZG9jdW1lbnQuIAorICogIFRoZSByZXR1cm5lZCBub2RlIGhhcyBubyBwYXJlbnQ7IChwYXJlbnROb2RlIGlzIG51bGwpLiBUaGUgc291cmNlIG5vZGUgaXMgbm90IAorICogIGFsdGVyZWQgb3IgcmVtb3ZlZCBmcm9tIHRoZSBvcmlnaW5hbCBkb2N1bWVudCBidXQgYSBuZXcgY29weSBvZiB0aGUgc291cmNlIG5vZGUKKyAqICBpcyBjcmVhdGVkLgorICogIAorICogIFVzaW5nIHRoZSBtZXRob2QgaW1wb3J0Tm9kZSB3aXRoIGRlZXA9ZmFsc2UsIGltcG9ydCB0aGlzIERvY3VtZW50J3MgZG9jdW1lbnRFbGVtZW50CisgKiAgbm9kZS4gIFZlcmlmeSBpZiB0aGUgbm9kZSBoYXMgYmVlbiBpbXBvcnRlZCBjb3JyZWN0bHkgYnkgaXRzIG5vZGVOYW1lIGF0dHRyaWJ1dGUgYW5kCisgKiAgaWYgdGhlIG9yaWdpbmFsIGRvY3VtZW50IGlzIG5vdCBhbHRlcmVkIGJ5IGNoZWNraW5nIGlmIGhhc0NoaWxkTm9kZXMgcmV0dXJucyBmYWxzZS4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50aW1wb3J0bm9kZTExIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGltcG9ydG5vZGUxMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBkb2NFbGVtZW50OworICAgICAgTm9kZSBpbXBvcnRlZDsKKyAgICAgIGJvb2xlYW4gc3VjY2VzczsKKyAgICAgIFN0cmluZyBub2RlTmFtZU9yaWc7CisgICAgICBTdHJpbmcgbm9kZU5hbWVJbXBvcnRlZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZG9jRWxlbWVudCA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIGltcG9ydGVkID0gZG9jLmltcG9ydE5vZGUoZG9jRWxlbWVudCwgZmFsc2UpOworICAgICAgc3VjY2VzcyA9IGltcG9ydGVkLmhhc0NoaWxkTm9kZXMoKTsKKyAgICAgIGFzc2VydEZhbHNlKCJkb2N1bWVudGltcG9ydG5vZGUxMSIsIHN1Y2Nlc3MpOworbm9kZU5hbWVJbXBvcnRlZCA9IGltcG9ydGVkLmdldE5vZGVOYW1lKCk7CisgICAgICBub2RlTmFtZU9yaWcgPSBkb2NFbGVtZW50LmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTExX05vZGVOYW1lIiwgbm9kZU5hbWVJbXBvcnRlZCwgbm9kZU5hbWVPcmlnKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50aW1wb3J0bm9kZTExLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUxMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUxMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY2OThiMGQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTEyLmphdmEKQEAgLTAsMCArMSwxMDggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBpbXBvcnROb2RlIG1ldGhvZCBpbXBvcnRzIGEgbm9kZSBmcm9tIGFub3RoZXIgZG9jdW1lbnQgdG8gdGhpcyBkb2N1bWVudC4gCisgKiAgVGhlIHJldHVybmVkIG5vZGUgaGFzIG5vIHBhcmVudDsgKHBhcmVudE5vZGUgaXMgbnVsbCkuIFRoZSBzb3VyY2Ugbm9kZSBpcyBub3QgCisgKiAgYWx0ZXJlZCBvciByZW1vdmVkIGZyb20gdGhlIG9yaWdpbmFsIGRvY3VtZW50IGJ1dCBhIG5ldyBjb3B5IG9mIHRoZSBzb3VyY2Ugbm9kZQorICogIGlzIGNyZWF0ZWQuCisgKiAgCisgKiAgVXNpbmcgdGhlIG1ldGhvZCBpbXBvcnROb2RlIHdpdGggZGVlcD10cnVlLCBpbXBvcnQgdGhlIGZpcnN0IGFkZHJlc3MgZWxlbWVudCBub2RlIG9mIHRoaXMKKyAqICBEb2N1bWVudC4gIFZlcmlmeSBpZiB0aGUgbm9kZSBoYXMgYmVlbiBpbXBvcnRlZCBjb3JyZWN0bHkgYnkgY2hlY2tpbmcgdGhlIGxlbmd0aCBvZiB0aGUKKyAqICB0aGlzIGVsZW1lbnRzIGNoaWxkTm9kZSBsaXN0IGJlZm9yZSBhbmQgYWZ0ZXIgdGhlIGltcG9ydC4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50aW1wb3J0bm9kZTEyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGltcG9ydG5vZGUxMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgTm9kZSBpbXBvcnRlZDsKKyAgICAgIE5vZGUgYWRkcmVzc0VsZW07CisgICAgICBOb2RlTGlzdCBhZGRyZXNzRWxlbUNoaWxkcmVuOworICAgICAgTm9kZUxpc3QgaW1wb3J0ZWRDaGlsZHJlbjsKKyAgICAgIGludCBhZGRyZXNzRWxlbUxlbjsKKyAgICAgIGludCBpbXBvcnRlZExlbjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgY2hpbGRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiYWRkcmVzcyIpOworICAgICAgYWRkcmVzc0VsZW0gPSBjaGlsZExpc3QuaXRlbSgwKTsKKyAgICAgIGltcG9ydGVkID0gZG9jLmltcG9ydE5vZGUoYWRkcmVzc0VsZW0sIHRydWUpOworICAgICAgYWRkcmVzc0VsZW1DaGlsZHJlbiA9IGFkZHJlc3NFbGVtLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGltcG9ydGVkQ2hpbGRyZW4gPSBpbXBvcnRlZC5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBhZGRyZXNzRWxlbUxlbiA9IChpbnQpIGFkZHJlc3NFbGVtQ2hpbGRyZW4uZ2V0TGVuZ3RoKCk7CisgICAgICBpbXBvcnRlZExlbiA9IChpbnQpIGltcG9ydGVkQ2hpbGRyZW4uZ2V0TGVuZ3RoKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTEyIiwgaW1wb3J0ZWRMZW4sIGFkZHJlc3NFbGVtTGVuKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50aW1wb3J0bm9kZTEyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUxMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUxMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFlNTM0ZGYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTEzLmphdmEKQEAgLTAsMCArMSwxMDQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBpbXBvcnROb2RlIG1ldGhvZCBpbXBvcnRzIGEgbm9kZSBmcm9tIGFub3RoZXIgZG9jdW1lbnQgdG8gdGhpcyBkb2N1bWVudC4gCisgKiAgVGhlIHJldHVybmVkIG5vZGUgaGFzIG5vIHBhcmVudDsgKHBhcmVudE5vZGUgaXMgbnVsbCkuIFRoZSBzb3VyY2Ugbm9kZSBpcyBub3QgCisgKiAgYWx0ZXJlZCBvciByZW1vdmVkIGZyb20gdGhlIG9yaWdpbmFsIGRvY3VtZW50IGJ1dCBhIG5ldyBjb3B5IG9mIHRoZSBzb3VyY2Ugbm9kZQorICogIGlzIGNyZWF0ZWQuCisgKiAgCisgKiAgVXNpbmcgdGhlIG1ldGhvZCBpbXBvcnROb2RlIHdpdGggZGVlcD1mYWxzZSwgaW1wb3J0IHRoZSBmaXJzdCBlbXBsb3llZSBlbGVtZW50IG5vZGUgb2YgdGhpcworICogIERvY3VtZW50LiAgVmVyaWZ5IGlmIHRoZSBub2RlIGhhcyBiZWVuIGltcG9ydGVkIGNvcnJlY3RseSBieSBjaGVja2luZyB0aGUgbGVuZ3RoIG9mIHRoZQorICogIHRoaXMgZWxlbWVudHMgY2hpbGROb2RlIGxpc3QgYmVmb3JlIGFuZCBhZnRlciB0aGUgaW1wb3J0LiAgCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGltcG9ydG5vZGUxMyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRpbXBvcnRub2RlMTMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgaW1wb3J0ZWQ7CisgICAgICBOb2RlTGlzdCBpbXBvcnRlZExpc3Q7CisgICAgICBOb2RlIGVtcGxveWVlRWxlbTsKKyAgICAgIGludCBpbXBvcnRlZExlbjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgY2hpbGRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiZW1wbG95ZWUiKTsKKyAgICAgIGVtcGxveWVlRWxlbSA9IGNoaWxkTGlzdC5pdGVtKDApOworICAgICAgaW1wb3J0ZWQgPSBkb2MuaW1wb3J0Tm9kZShlbXBsb3llZUVsZW0sIGZhbHNlKTsKKyAgICAgIGltcG9ydGVkTGlzdCA9IGltcG9ydGVkLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGltcG9ydGVkTGVuID0gKGludCkgaW1wb3J0ZWRMaXN0LmdldExlbmd0aCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUxMyIsIDAsIGltcG9ydGVkTGVuKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50aW1wb3J0bm9kZTEzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUxNC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUxNC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBhYjBhNDQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTE0LmphdmEKQEAgLTAsMCArMSwxMTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVXNpbmcgdGhlIG1ldGhvZCBpbXBvcnROb2RlIHdpdGggZGVlcD10cnVlLCBpbXBvcnQgdGhlIGZvdXJ0aCBlbXBsb3llZSBlbGVtZW50IG5vZGUgb2YgdGhpcworICogIERvY3VtZW50LiAgVmVyaWZ5IGlmIHRoZSBub2RlIGhhcyBiZWVuIGltcG9ydGVkIGNvcnJlY3RseSBieSBjaGVja2luZyAKKyAqICBpZiB0aGUgZGVmYXVsdCBhdHRyaWJ1dGUgcHJlc2VudCBvbiB0aGlzIG5vZGUgaGFzIG5vdCBiZWVuIGltcG9ydGVkCisgKiAgYW5kIGFuIGV4cGxpY2l0IGF0dHJpYnV0ZSBoYXMgYmVlbiBpbXBvcnRlZC4gIAorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD00MDIiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD00MDI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50aW1wb3J0bm9kZTE0IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGltcG9ydG5vZGUxNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnQgbmV3RG9jOworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIERvY3VtZW50VHlwZSBudWxsRG9jVHlwZSA9IG51bGw7CisKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIE5vZGUgaW1wb3J0ZWQ7CisgICAgICBOb2RlIGVtcGxveWVlRWxlbTsKKyAgICAgIEF0dHIgYXR0ck5vZGU7CisgICAgICBTdHJpbmcgYXR0clZhbHVlOworICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgY2hpbGRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiZW1wbG95ZWUiKTsKKyAgICAgIGVtcGxveWVlRWxlbSA9IGNoaWxkTGlzdC5pdGVtKDMpOworICAgICAgZG9tSW1wbCA9IGdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICBuZXdEb2MgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KG51bGxOUywgInN0YWZmIiwgbnVsbERvY1R5cGUpOworICAgICAgaW1wb3J0ZWQgPSBuZXdEb2MuaW1wb3J0Tm9kZShlbXBsb3llZUVsZW0sIHRydWUpOworICAgICAgYXR0ck5vZGUgPSAoKEVsZW1lbnQpIC8qTm9kZSAqL2ltcG9ydGVkKS5nZXRBdHRyaWJ1dGVOb2RlTlMobnVsbE5TLCAiZGVmYXVsdEF0dHIiKTsKKyAgICAgIGFzc2VydE51bGwoImRlZmF1bHRBdHRyTm90SW1wb3J0ZWQiLCBhdHRyTm9kZSk7CisgICAgICBhdHRyVmFsdWUgPSAoKEVsZW1lbnQpIC8qTm9kZSAqL2ltcG9ydGVkKS5nZXRBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iLCAiZW1wIik7CisgICAgICBhc3NlcnRFcXVhbHMoImV4cGxpY2l0QXR0ckltcG9ydGVkIiwgImh0dHA6Ly93d3cubmlzdC5nb3YiLCBhdHRyVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUxNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRpbXBvcnRub2RlMTQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTE1LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTE1LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWQyNjgwNAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTUuamF2YQpAQCAtMCwwICsxLDEwMyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIGltcG9ydE5vZGUgbWV0aG9kIGltcG9ydHMgYSBub2RlIGZyb20gYW5vdGhlciBkb2N1bWVudCB0byB0aGlzIGRvY3VtZW50LiAKKyAqICBUaGUgcmV0dXJuZWQgbm9kZSBoYXMgbm8gcGFyZW50OyAocGFyZW50Tm9kZSBpcyBudWxsKS4gVGhlIHNvdXJjZSBub2RlIGlzIG5vdCAKKyAqICBhbHRlcmVkIG9yIHJlbW92ZWQgZnJvbSB0aGUgb3JpZ2luYWwgZG9jdW1lbnQgYnV0IGEgbmV3IGNvcHkgb2YgdGhlIHNvdXJjZSBub2RlCisgKiAgaXMgY3JlYXRlZC4KKyAqICAKKyAqICBVc2luZyB0aGUgbWV0aG9kIGltcG9ydE5vZGUgd2l0aCBkZWVwPXRydWUsIGltcG9ydCBhIG5ld2x5IGNyZWF0ZWQgVGV4dCBub2RlIGZvciB0aGlzCisgKiAgRG9jdW1lbnQuICBWZXJpZnkgaWYgdGhlIG5vZGUgaGFzIGJlZW4gaW1wb3J0ZWQgY29ycmVjdGx5IGJ5IGNoZWNraW5nIHRoZSB2YWx1ZSBvZiB0aGUgCisgKiAgaW1wb3J0ZWQgdGV4dCBub2RlLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9jdW1lbnRpbXBvcnRub2RlMTUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50aW1wb3J0bm9kZTE1KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50IGRvY0ltcDsKKyAgICAgIE5vZGUgdGV4dEltcG9ydDsKKyAgICAgIE5vZGUgdGV4dFRvSW1wb3J0OworICAgICAgU3RyaW5nIG5vZGVWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZG9jSW1wID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICB0ZXh0VG9JbXBvcnQgPSBkb2MuY3JlYXRlVGV4dE5vZGUoIkRvY3VtZW50LmltcG9ydE5vZGUgdGVzdCBmb3IgYSBURVhUX05PREUiKTsKKyAgICAgIHRleHRJbXBvcnQgPSBkb2MuaW1wb3J0Tm9kZSh0ZXh0VG9JbXBvcnQsIHRydWUpOworICAgICAgbm9kZVZhbHVlID0gdGV4dEltcG9ydC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMTUiLCAiRG9jdW1lbnQuaW1wb3J0Tm9kZSB0ZXN0IGZvciBhIFRFWFRfTk9ERSIsIG5vZGVWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTE1IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGltcG9ydG5vZGUxNS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZTU3NDExCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUxNy5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgaW1wb3J0Tm9kZSBtZXRob2QgaW1wb3J0cyBhIG5vZGUgZnJvbSBhbm90aGVyIGRvY3VtZW50IHRvIHRoaXMgZG9jdW1lbnQuIAorICogIFRoZSByZXR1cm5lZCBub2RlIGhhcyBubyBwYXJlbnQ7IChwYXJlbnROb2RlIGlzIG51bGwpLiBUaGUgc291cmNlIG5vZGUgaXMgbm90IAorICogIGFsdGVyZWQgb3IgcmVtb3ZlZCBmcm9tIHRoZSBvcmlnaW5hbCBkb2N1bWVudCBidXQgYSBuZXcgY29weSBvZiB0aGUgc291cmNlIG5vZGUKKyAqICBpcyBjcmVhdGVkLgorICogIAorICogIFVzaW5nIHRoZSBtZXRob2QgaW1wb3J0Tm9kZSB3aXRoIGRlZXA9dHJ1ZSwgaW1wb3J0IGEgbmV3bHkgY3JlYXRlZCBDb21tZW50IG5vZGUgZm9yIHRoaXMKKyAqICBEb2N1bWVudC4gIFZlcmlmeSBpZiB0aGUgbm9kZSBoYXMgYmVlbiBpbXBvcnRlZCBjb3JyZWN0bHkgYnkgY2hlY2tpbmcgdGhlIHZhbHVlIG9mIHRoZSAKKyAqICBpbXBvcnRlZCBDb21tZW50IG5vZGUuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGltcG9ydG5vZGUxNyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRpbXBvcnRub2RlMTcoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnQgZG9jSW1wOworICAgICAgTm9kZSBjb21tZW50SW1wb3J0OworICAgICAgTm9kZSBjb21tZW50VG9JbXBvcnQ7CisgICAgICBTdHJpbmcgbm9kZVZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBkb2NJbXAgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGNvbW1lbnRUb0ltcG9ydCA9IGRvYy5jcmVhdGVDb21tZW50KCJEb2N1bWVudC5pbXBvcnROb2RlIHRlc3QgZm9yIGEgQ09NTUVOVF9OT0RFIik7CisgICAgICBjb21tZW50SW1wb3J0ID0gZG9jLmltcG9ydE5vZGUoY29tbWVudFRvSW1wb3J0LCB0cnVlKTsKKyAgICAgIG5vZGVWYWx1ZSA9IGNvbW1lbnRJbXBvcnQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTE3IiwgIkRvY3VtZW50LmltcG9ydE5vZGUgdGVzdCBmb3IgYSBDT01NRU5UX05PREUiLCBub2RlVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUxNyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRpbXBvcnRub2RlMTcuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTE4LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTE4LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGNiOWMwOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTguamF2YQpAQCAtMCwwICsxLDEwNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgaW1wb3J0Tm9kZSBtZXRob2QgaW1wb3J0cyBhIG5vZGUgZnJvbSBhbm90aGVyIGRvY3VtZW50IHRvIHRoaXMgZG9jdW1lbnQuIAorICogIFRoZSByZXR1cm5lZCBub2RlIGhhcyBubyBwYXJlbnQ7IChwYXJlbnROb2RlIGlzIG51bGwpLiBUaGUgc291cmNlIG5vZGUgaXMgbm90IAorICogIGFsdGVyZWQgb3IgcmVtb3ZlZCBmcm9tIHRoZSBvcmlnaW5hbCBkb2N1bWVudCBidXQgYSBuZXcgY29weSBvZiB0aGUgc291cmNlIG5vZGUKKyAqICBpcyBjcmVhdGVkLgorICogIAorICogIFVzaW5nIHRoZSBtZXRob2QgaW1wb3J0Tm9kZSB3aXRoIGRlZXA9dHJ1ZSwgaW1wb3J0IGEgbmV3bHkgY3JlYXRlZCBQSSBub2RlIGZvciB0aGlzCisgKiAgRG9jdW1lbnQuICBWZXJpZnkgaWYgdGhlIG5vZGUgaGFzIGJlZW4gaW1wb3J0ZWQgY29ycmVjdGx5IGJ5IGNoZWNraW5nIHRoZSBQSVRhcmdldCBhbmQgCisgKiAgUElEYXRhIHZhbHVlcyBvZiB0aGUgaW1wb3J0ZWQgUEkgbm9kZS4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50aW1wb3J0bm9kZTE4IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGltcG9ydG5vZGUxOChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBkb2NJbXA7CisgICAgICBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gcGlJbXBvcnQ7CisgICAgICBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gcGlUb0ltcG9ydDsKKyAgICAgIFN0cmluZyBwaURhdGE7CisgICAgICBTdHJpbmcgcGlUYXJnZXQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGRvY0ltcCA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgcGlUb0ltcG9ydCA9IGRvYy5jcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oIlRhcmdldCIsICJEYXRhIik7CisgICAgICBwaUltcG9ydCA9IChQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24pIGRvYy5pbXBvcnROb2RlKHBpVG9JbXBvcnQsIGZhbHNlKTsKKyAgICAgIHBpVGFyZ2V0ID0gcGlJbXBvcnQuZ2V0VGFyZ2V0KCk7CisgICAgICBwaURhdGEgPSBwaUltcG9ydC5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTE4X1RhcmdldCIsICJUYXJnZXQiLCBwaVRhcmdldCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTE4X0RhdGEiLCAiRGF0YSIsIHBpRGF0YSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTE4IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGltcG9ydG5vZGUxOC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTkuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMTkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYmUzNTViCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUxOS5qYXZhCkBAIC0wLDAgKzEsMTM2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBpbXBvcnROb2RlIG1ldGhvZCBpbXBvcnRzIGEgbm9kZSBmcm9tIGFub3RoZXIgZG9jdW1lbnQgdG8gdGhpcyBkb2N1bWVudC4gCisgKiAgVGhlIHJldHVybmVkIG5vZGUgaGFzIG5vIHBhcmVudDsgKHBhcmVudE5vZGUgaXMgbnVsbCkuIFRoZSBzb3VyY2Ugbm9kZSBpcyBub3QgCisgKiAgYWx0ZXJlZCBvciByZW1vdmVkIGZyb20gdGhlIG9yaWdpbmFsIGRvY3VtZW50IGJ1dCBhIG5ldyBjb3B5IG9mIHRoZSBzb3VyY2Ugbm9kZQorICogIGlzIGNyZWF0ZWQuCisgKiAgCisgKiAgVXNpbmcgdGhlIG1ldGhvZCBpbXBvcnROb2RlIHdpdGggZGVlcD10cnVlL2ZhbHNlLCBpbXBvcnQgYSBlbnRpdHkgbm9kZXMgZW50MiBhbmQgZW50NgorICogIGZyb20gdGhpcyBkb2N1bWVudCB0byBhIG5ldyBkb2N1bWVudCBvYmplY3QuICBWZXJpZnkgaWYgdGhlIG5vZGVzIGhhdmUgYmVlbiAKKyAqICBpbXBvcnRlZCBjb3JyZWN0bHkgYnkgY2hlY2tpbmcgdGhlIG5vZGVOYW1lcyBvZiB0aGUgaW1wb3J0ZWQgbm9kZXMgYW5kIHB1YmxpYyBhbmQgc3lzdGVtIGlkcy4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50aW1wb3J0bm9kZTE5IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGltcG9ydG5vZGUxOShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGVOdWxsID0gbnVsbDsKKworICAgICAgRG9jdW1lbnQgZG9jSW1wOworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTmFtZWROb2RlTWFwIG5vZGVNYXA7CisgICAgICBFbnRpdHkgZW50aXR5MjsKKyAgICAgIEVudGl0eSBlbnRpdHk2OworICAgICAgRW50aXR5IGVudGl0eUltcDI7CisgICAgICBFbnRpdHkgZW50aXR5SW1wNjsKKyAgICAgIFN0cmluZyBub2RlTmFtZTsKKyAgICAgIFN0cmluZyBzeXN0ZW1JZDsKKyAgICAgIFN0cmluZyBub3RhdGlvbk5hbWU7CisgICAgICBTdHJpbmcgbm9kZU5hbWVJbXA7CisgICAgICBTdHJpbmcgc3lzdGVtSWRJbXA7CisgICAgICBTdHJpbmcgbm90YXRpb25OYW1lSW1wOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGRvY0ltcCA9IGRvbUltcGwuY3JlYXRlRG9jdW1lbnQoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgImE6YiIsIGRvY1R5cGVOdWxsKTsKKyAgICAgIG5vZGVNYXAgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdGllc05vdE51bGwiLCBub2RlTWFwKTsKKyAgICAgIGVudGl0eTIgPSAoRW50aXR5KSBub2RlTWFwLmdldE5hbWVkSXRlbSgiZW50MiIpOworICAgICAgZW50aXR5NiA9IChFbnRpdHkpIG5vZGVNYXAuZ2V0TmFtZWRJdGVtKCJlbnQ2Iik7CisgICAgICBlbnRpdHlJbXAyID0gKEVudGl0eSkgZG9jSW1wLmltcG9ydE5vZGUoZW50aXR5MiwgZmFsc2UpOworICAgICAgZW50aXR5SW1wNiA9IChFbnRpdHkpIGRvY0ltcC5pbXBvcnROb2RlKGVudGl0eTYsIHRydWUpOworICAgICAgbm9kZU5hbWUgPSBlbnRpdHkyLmdldE5vZGVOYW1lKCk7CisgICAgICBub2RlTmFtZUltcCA9IGVudGl0eUltcDIuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMTlfRW50Mk5vZGVOYW1lIiwgbm9kZU5hbWUsIG5vZGVOYW1lSW1wKTsKKyAgICAgIG5vZGVOYW1lID0gZW50aXR5Ni5nZXROb2RlTmFtZSgpOworICAgICAgbm9kZU5hbWVJbXAgPSBlbnRpdHlJbXA2LmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTE5X0VudDZOb2RlTmFtZSIsIG5vZGVOYW1lLCBub2RlTmFtZUltcCk7CisgICAgICBzeXN0ZW1JZCA9IGVudGl0eTIuZ2V0U3lzdGVtSWQoKTsKKyAgICAgIHN5c3RlbUlkSW1wID0gZW50aXR5SW1wMi5nZXRTeXN0ZW1JZCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUxOV9FbnQyU3lzdGVtSWQiLCBzeXN0ZW1JZCwgc3lzdGVtSWRJbXApOworICAgICAgc3lzdGVtSWQgPSBlbnRpdHk2LmdldFN5c3RlbUlkKCk7CisgICAgICBzeXN0ZW1JZEltcCA9IGVudGl0eUltcDYuZ2V0U3lzdGVtSWQoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMTlfRW50NlN5c3RlbUlkIiwgc3lzdGVtSWQsIHN5c3RlbUlkSW1wKTsKKyAgICAgIG5vdGF0aW9uTmFtZSA9IGVudGl0eTIuZ2V0Tm90YXRpb25OYW1lKCk7CisgICAgICBub3RhdGlvbk5hbWVJbXAgPSBlbnRpdHlJbXAyLmdldE5vdGF0aW9uTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUxOV9FbnQyTm90YXRpb25OYW1lIiwgbm90YXRpb25OYW1lLCBub3RhdGlvbk5hbWVJbXApOworICAgICAgbm90YXRpb25OYW1lID0gZW50aXR5Ni5nZXROb3RhdGlvbk5hbWUoKTsKKyAgICAgIG5vdGF0aW9uTmFtZUltcCA9IGVudGl0eUltcDYuZ2V0Tm90YXRpb25OYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTE5X0VudDZOb3RhdGlvbk5hbWUiLCBub3RhdGlvbk5hbWUsIG5vdGF0aW9uTmFtZUltcCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTE5IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudGltcG9ydG5vZGUxOS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMjAuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMjAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYjc3NzEzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUyMC5qYXZhCkBAIC0wLDAgKzEsMTM0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgaW1wb3J0Tm9kZSBtZXRob2QgaW1wb3J0cyBhIG5vZGUgZnJvbSBhbm90aGVyIGRvY3VtZW50IHRvIHRoaXMgZG9jdW1lbnQuIAorICogIFRoZSByZXR1cm5lZCBub2RlIGhhcyBubyBwYXJlbnQ7IChwYXJlbnROb2RlIGlzIG51bGwpLiBUaGUgc291cmNlIG5vZGUgaXMgbm90IAorICogIGFsdGVyZWQgb3IgcmVtb3ZlZCBmcm9tIHRoZSBvcmlnaW5hbCBkb2N1bWVudCBidXQgYSBuZXcgY29weSBvZiB0aGUgc291cmNlIG5vZGUKKyAqICBpcyBjcmVhdGVkLgorICogIAorICogIFVzaW5nIHRoZSBtZXRob2QgaW1wb3J0Tm9kZSB3aXRoIGRlZXA9dHJ1ZSwgaW1wb3J0IGEgZW50aXR5IG5vZGUgZW50NCAKKyAqICBmcm9tIHRoaXMgZG9jdW1lbnQgdG8gYSBuZXcgZG9jdW1lbnQgb2JqZWN0LiAgVGhlIHJlcGxhY2VtZW50IHRleHQgb2YgdGhpcyBlbnRpdHkgaXMgYW4gZWxlbWVudAorICogIG5vZGUsIGEgY2RhdGEgbm9kZSBhbmQgYSBwaS4gIFZlcmlmeSBpZiB0aGUgbm9kZXMgaGF2ZSBiZWVuIAorICogIGltcG9ydGVkIGNvcnJlY3RseSBieSBjaGVja2luZyB0aGUgbm9kZU5hbWVzIG9mIHRoZSBpbXBvcnRlZCBlbGVtZW50IG5vZGUsIHRoZSBkYXRhIGZvciB0aGUKKyAqICBjZGF0YSBub2RlcyBhbmQgdGhlIFBJdGFyZ2V0IGFuZCBQSURhdGEgZm9yIHRoZSBwaSBub2Rlcy4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50aW1wb3J0bm9kZTIwIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGltcG9ydG5vZGUyMChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZSwKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RFeHBhbmRFbnRpdHlSZWZlcmVuY2VzCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBkb2NJbXA7CisgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZU51bGwgPSBudWxsOworCisgICAgICBOYW1lZE5vZGVNYXAgbm9kZU1hcDsKKyAgICAgIEVudGl0eSBlbnRpdHk0OworICAgICAgRW50aXR5IGVudGl0eUltcDQ7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBDaGFyYWN0ZXJEYXRhIGNkYXRhOworICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uIHBpOworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgTm9kZUxpc3QgZWxlbWNoaWxkTGlzdDsKKyAgICAgIFN0cmluZyBlbnQ0TmFtZTsKKyAgICAgIFN0cmluZyBlbnQ0SW1wTmFtZTsKKyAgICAgIFN0cmluZyBjZGF0YVZhbDsKKyAgICAgIFN0cmluZyBwaVRhcmdldFZhbDsKKyAgICAgIFN0cmluZyBwaURhdGFWYWw7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgZG9jSW1wID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudCgiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLCAiYTpiIiwgZG9jVHlwZU51bGwpOworICAgICAgbm9kZU1hcCA9IGRvY1R5cGUuZ2V0RW50aXRpZXMoKTsKKyAgICAgIGVudGl0eTQgPSAoRW50aXR5KSBub2RlTWFwLmdldE5hbWVkSXRlbSgiZW50NCIpOworICAgICAgZW50aXR5SW1wNCA9IChFbnRpdHkpIGRvY0ltcC5pbXBvcnROb2RlKGVudGl0eTQsIHRydWUpOworICAgICAgY2hpbGRMaXN0ID0gZW50aXR5SW1wNC5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGNoaWxkTGlzdC5pdGVtKDApOworICAgICAgZWxlbWNoaWxkTGlzdCA9IGVsZW1lbnQuZ2V0Q2hpbGROb2RlcygpOworICAgICAgY2RhdGEgPSAoQ2hhcmFjdGVyRGF0YSkgZWxlbWNoaWxkTGlzdC5pdGVtKDApOworICAgICAgcGkgPSAoUHJvY2Vzc2luZ0luc3RydWN0aW9uKSBjaGlsZExpc3QuaXRlbSgxKTsKKyAgICAgIGVudDROYW1lID0gZW50aXR5NC5nZXROb2RlTmFtZSgpOworICAgICAgZW50NEltcE5hbWUgPSBlbnRpdHlJbXA0LmdldE5vZGVOYW1lKCk7CisgICAgICBjZGF0YVZhbCA9IGNkYXRhLmdldERhdGEoKTsKKyAgICAgIHBpVGFyZ2V0VmFsID0gcGkuZ2V0VGFyZ2V0KCk7CisgICAgICBwaURhdGFWYWwgPSBwaS5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTIwX0VudDROb2RlTmFtZSIsIGVudDROYW1lLCBlbnQ0SW1wTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTIwX0NkYXRhIiwgIkVsZW1lbnQgZGF0YSIsIGNkYXRhVmFsKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMjBfUElUYXJnZXQiLCAiUEl0YXJnZXQiLCBwaVRhcmdldFZhbCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTIwX1BJRGF0YSIsICJQSWRhdGEiLCBwaURhdGFWYWwpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUyMCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9jdW1lbnRpbXBvcnRub2RlMjAuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTIxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTIxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWFlY2NmMwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMjEuamF2YQpAQCAtMCwwICsxLDE0NCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIGltcG9ydE5vZGUgbWV0aG9kIGltcG9ydHMgYSBub2RlIGZyb20gYW5vdGhlciBkb2N1bWVudCB0byB0aGlzIGRvY3VtZW50LiAKKyAqICBUaGUgcmV0dXJuZWQgbm9kZSBoYXMgbm8gcGFyZW50OyAocGFyZW50Tm9kZSBpcyBudWxsKS4gVGhlIHNvdXJjZSBub2RlIGlzIG5vdCAKKyAqICBhbHRlcmVkIG9yIHJlbW92ZWQgZnJvbSB0aGUgb3JpZ2luYWwgZG9jdW1lbnQgYnV0IGEgbmV3IGNvcHkgb2YgdGhlIHNvdXJjZSBub2RlCisgKiAgaXMgY3JlYXRlZC4KKyAqICAKKyAqICBVc2luZyB0aGUgbWV0aG9kIGltcG9ydE5vZGUgd2l0aCBkZWVwPXRydWUsIHJldHJlaXZlIHRoZSBlbnRpdHkgcmVmcyBwcmVzZW50IGluIHRoZSAKKyAqICBzZWNvbmQgZWxlbWVudCBub2RlIHdob3NlIHRhZ05hbWUgaXMgYWRkcmVzcyBhbmQgaW1wb3J0IHRoZXNlIG5vZGVzIGludG8gYW5vdGhlciBkb2N1bWVudC4gCisgKiAgVmVyaWZ5IGlmIHRoZSBub2RlcyBoYXZlIGJlZW4gaW1wb3J0ZWQgY29ycmVjdGx5IGJ5IGNoZWNraW5nIHRoZSBub2RlTmFtZXMgb2YgdGhlIAorICogIGltcG9ydGVkIG5vZGVzLCBzaW5jZSB0aGV5IGFyZSBpbXBvcnRlZCBpbnRvIGEgbmV3IGRvY3VtZW50IHdoaWNoIGRvZXNub3QgaGF2ZSB0aGVzIGRlZmluZWQsCisgKiAgdGhlIGltcG9ydGVkIG5vZGVzIHNob3VsZCBub3QgaGF2ZSBhbnkgY2hpbGRyZW4uCisgKiAgTm93IGltcG9ydCB0aGUgZW50aXR5UmVmIG5vZGVzIGludG8gdGhlIHNhbWUgZG9jdW1lbnQgYW5kIHZlcmlmeSBpZiB0aGUgbm9kZXMgaGF2ZSBiZWVuIAorICogIGltcG9ydGVkIGNvcnJlY3RseSBieSBjaGVja2luZyB0aGUgbm9kZU5hbWVzIG9mIHRoZSBpbXBvcnRlZCBub2RlcywgYW5kIGJ5IGNoZWNraW5nIHRoZSAKKyAqICB2YWx1ZSBvZiB0aGUgcmVwbGFjZW1lbnQgdGV4dCBvZiB0aGUgaW1wb3J0ZWQgbm9kZXMuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudGltcG9ydG5vZGUyMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9jdW1lbnRpbXBvcnRub2RlMjEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUsCitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubm90RXhwYW5kRW50aXR5UmVmZXJlbmNlcworICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGVOdWxsID0gbnVsbDsKKworICAgICAgRG9jdW1lbnQgZG9jSW1wOworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NMaXN0OworICAgICAgTm9kZUxpc3QgYWRkcmVzc0NoaWxkTGlzdDsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWYyOworICAgICAgRW50aXR5UmVmZXJlbmNlIGVudFJlZkltcDI7CisgICAgICBFbnRpdHlSZWZlcmVuY2UgZW50UmVmMzsKKyAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWZJbXAzOworICAgICAgU3RyaW5nIG5vZGVOYW1lMjsKKyAgICAgIFN0cmluZyBub2RlTmFtZTM7CisgICAgICBTdHJpbmcgbm9kZU5hbWVJbXAyOworICAgICAgU3RyaW5nIG5vZGVOYW1lSW1wMzsKKyAgICAgIE5vZGVMaXN0IG5vZGVzOworICAgICAgTm9kZSBub2RlSW1wMzsKKyAgICAgIE5vZGUgbm9kZUltcDI7CisgICAgICBTdHJpbmcgbm9kZVZhbHVlSW1wMjsKKyAgICAgIFN0cmluZyBub2RlVmFsdWVJbXAzOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICBkb2NJbXAgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJhOmIiLCBkb2NUeXBlTnVsbCk7CisgICAgICBhZGRyZXNzTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBhZGRyZXNzTGlzdC5pdGVtKDEpOworICAgICAgYWRkcmVzc0NoaWxkTGlzdCA9IGVsZW1lbnQuZ2V0Q2hpbGROb2RlcygpOworICAgICAgZW50UmVmMiA9IChFbnRpdHlSZWZlcmVuY2UpIGFkZHJlc3NDaGlsZExpc3QuaXRlbSgwKTsKKyAgICAgIGVudFJlZjMgPSAoRW50aXR5UmVmZXJlbmNlKSBhZGRyZXNzQ2hpbGRMaXN0Lml0ZW0oMik7CisgICAgICBlbnRSZWZJbXAyID0gKEVudGl0eVJlZmVyZW5jZSkgZG9jSW1wLmltcG9ydE5vZGUoZW50UmVmMiwgdHJ1ZSk7CisgICAgICBlbnRSZWZJbXAzID0gKEVudGl0eVJlZmVyZW5jZSkgZG9jSW1wLmltcG9ydE5vZGUoZW50UmVmMywgZmFsc2UpOworICAgICAgbm9kZU5hbWUyID0gZW50UmVmMi5nZXROb2RlTmFtZSgpOworICAgICAgbm9kZU5hbWUzID0gZW50UmVmMy5nZXROb2RlTmFtZSgpOworICAgICAgbm9kZU5hbWVJbXAyID0gZW50UmVmSW1wMi5nZXROb2RlTmFtZSgpOworICAgICAgbm9kZU5hbWVJbXAzID0gZW50UmVmSW1wMy5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUyMV9FbnQyTm9kZU5hbWUiLCBub2RlTmFtZTIsIG5vZGVOYW1lSW1wMik7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTIxX0VudDNOb2RlTmFtZSIsIG5vZGVOYW1lMywgbm9kZU5hbWVJbXAzKTsKKyAgICAgIGVudFJlZkltcDIgPSAoRW50aXR5UmVmZXJlbmNlKSBkb2MuaW1wb3J0Tm9kZShlbnRSZWYyLCB0cnVlKTsKKyAgICAgIGVudFJlZkltcDMgPSAoRW50aXR5UmVmZXJlbmNlKSBkb2MuaW1wb3J0Tm9kZShlbnRSZWYzLCBmYWxzZSk7CisgICAgICBub2RlcyA9IGVudFJlZkltcDIuZ2V0Q2hpbGROb2RlcygpOworICAgICAgbm9kZUltcDIgPSBub2Rlcy5pdGVtKDApOworICAgICAgbm9kZVZhbHVlSW1wMiA9IG5vZGVJbXAyLmdldE5vZGVWYWx1ZSgpOworICAgICAgbm9kZXMgPSBlbnRSZWZJbXAzLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIG5vZGVJbXAzID0gbm9kZXMuaXRlbSgwKTsKKyAgICAgIG5vZGVWYWx1ZUltcDMgPSBub2RlSW1wMy5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMjFfRW50Mk5vZGVWYWx1ZSIsICIxOTAwIERhbGxhcyBSb2FkIiwgbm9kZVZhbHVlSW1wMik7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTIxX0VudDNOb2RldmFsdWUiLCAiVGV4YXMiLCBub2RlVmFsdWVJbXAzKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMjEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50aW1wb3J0bm9kZTIxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUyMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudGltcG9ydG5vZGUyMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjZTg5NzcKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50aW1wb3J0bm9kZTIyLmphdmEKQEAgLTAsMCArMSwxNDQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIGltcG9ydE5vZGUgbWV0aG9kIGltcG9ydHMgYSBub2RlIGZyb20gYW5vdGhlciBkb2N1bWVudCB0byB0aGlzIGRvY3VtZW50LiAKKyAqICBUaGUgcmV0dXJuZWQgbm9kZSBoYXMgbm8gcGFyZW50OyAocGFyZW50Tm9kZSBpcyBudWxsKS4gVGhlIHNvdXJjZSBub2RlIGlzIG5vdCAKKyAqICBhbHRlcmVkIG9yIHJlbW92ZWQgZnJvbSB0aGUgb3JpZ2luYWwgZG9jdW1lbnQgYnV0IGEgbmV3IGNvcHkgb2YgdGhlIHNvdXJjZSBub2RlCisgKiAgaXMgY3JlYXRlZC4KKyAqICAKKyAqICBVc2luZyB0aGUgbWV0aG9kIGltcG9ydE5vZGUgd2l0aCBkZWVwPXRydWUvZmFsc2UsIGltcG9ydCB0d28gbm90YWl0b24gbm9kZXMgaW50byB0aGUgCisgKiAgc2FtZSBhbmQgZGlmZmVyZW50IGRvY3VtbmV0IG9iamVjdHMuICBJbiBlYWNoIGNhc2UgY2hlY2sgaWYgdmFsaWQgcHVibGljIGFuZCBzeXN0ZW1pZHMgCisgKiAgYXJlIHJldHVybmVkIGlmIGFueSBhbmQgaWYgbm9uZSwgY2hlY2sgaWYgYSBudWxsIHZhbHVlIHdhcyByZXR1cm5lZC4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50aW1wb3J0bm9kZTIyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudGltcG9ydG5vZGUyMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGVOdWxsID0gbnVsbDsKKworICAgICAgRG9jdW1lbnQgZG9jSW1wOworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTmFtZWROb2RlTWFwIG5vZGVNYXA7CisgICAgICBOb3RhdGlvbiBub3RhdGlvbjE7CisgICAgICBOb3RhdGlvbiBub3RhdGlvbjI7CisgICAgICBOb3RhdGlvbiBub3RhdGlvbkltcDE7CisgICAgICBOb3RhdGlvbiBub3RhdGlvbkltcDI7CisgICAgICBOb3RhdGlvbiBub3RhdGlvbkltcE5ldzE7CisgICAgICBOb3RhdGlvbiBub3RhdGlvbkltcE5ldzI7CisgICAgICBTdHJpbmcgcHVibGljSWQxOworICAgICAgU3RyaW5nIHB1YmxpY0lkMUltcDsKKyAgICAgIFN0cmluZyBwdWJsaWNJZDFOZXdJbXA7CisgICAgICBTdHJpbmcgcHVibGljSWQySW1wOworICAgICAgU3RyaW5nIHB1YmxpY0lkMk5ld0ltcDsKKyAgICAgIFN0cmluZyBzeXN0ZW1JZDFJbXA7CisgICAgICBTdHJpbmcgc3lzdGVtSWQxTmV3SW1wOworICAgICAgU3RyaW5nIHN5c3RlbUlkMjsKKyAgICAgIFN0cmluZyBzeXN0ZW1JZDJJbXA7CisgICAgICBTdHJpbmcgc3lzdGVtSWQyTmV3SW1wOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGRvY0ltcCA9IGRvbUltcGwuY3JlYXRlRG9jdW1lbnQoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgImE6YiIsIGRvY1R5cGVOdWxsKTsKKyAgICAgIG5vZGVNYXAgPSBkb2NUeXBlLmdldE5vdGF0aW9ucygpOworICAgICAgYXNzZXJ0Tm90TnVsbCgibm90YXRpb25zTm90TnVsbCIsIG5vZGVNYXApOworICAgICAgbm90YXRpb24xID0gKE5vdGF0aW9uKSBub2RlTWFwLmdldE5hbWVkSXRlbSgibm90YXRpb24xIik7CisgICAgICBub3RhdGlvbjIgPSAoTm90YXRpb24pIG5vZGVNYXAuZ2V0TmFtZWRJdGVtKCJub3RhdGlvbjIiKTsKKyAgICAgIG5vdGF0aW9uSW1wMSA9IChOb3RhdGlvbikgZG9jLmltcG9ydE5vZGUobm90YXRpb24xLCB0cnVlKTsKKyAgICAgIG5vdGF0aW9uSW1wMiA9IChOb3RhdGlvbikgZG9jLmltcG9ydE5vZGUobm90YXRpb24yLCBmYWxzZSk7CisgICAgICBub3RhdGlvbkltcE5ldzEgPSAoTm90YXRpb24pIGRvY0ltcC5pbXBvcnROb2RlKG5vdGF0aW9uMSwgZmFsc2UpOworICAgICAgbm90YXRpb25JbXBOZXcyID0gKE5vdGF0aW9uKSBkb2NJbXAuaW1wb3J0Tm9kZShub3RhdGlvbjIsIHRydWUpOworICAgICAgcHVibGljSWQxID0gbm90YXRpb24xLmdldFB1YmxpY0lkKCk7CisgICAgICBwdWJsaWNJZDFJbXAgPSBub3RhdGlvbjEuZ2V0UHVibGljSWQoKTsKKyAgICAgIHB1YmxpY0lkMU5ld0ltcCA9IG5vdGF0aW9uMS5nZXRQdWJsaWNJZCgpOworICAgICAgc3lzdGVtSWQxSW1wID0gbm90YXRpb24xLmdldFN5c3RlbUlkKCk7CisgICAgICBzeXN0ZW1JZDFOZXdJbXAgPSBub3RhdGlvbjEuZ2V0U3lzdGVtSWQoKTsKKyAgICAgIHB1YmxpY0lkMkltcCA9IG5vdGF0aW9uMi5nZXRQdWJsaWNJZCgpOworICAgICAgcHVibGljSWQyTmV3SW1wID0gbm90YXRpb24yLmdldFB1YmxpY0lkKCk7CisgICAgICBzeXN0ZW1JZDIgPSBub3RhdGlvbjIuZ2V0U3lzdGVtSWQoKTsKKyAgICAgIHN5c3RlbUlkMkltcCA9IG5vdGF0aW9uMi5nZXRTeXN0ZW1JZCgpOworICAgICAgc3lzdGVtSWQyTmV3SW1wID0gbm90YXRpb24yLmdldFN5c3RlbUlkKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTIyX04xUElEIiwgcHVibGljSWQxLCBwdWJsaWNJZDFJbXApOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUyMl9OMU5QSUQiLCBwdWJsaWNJZDEsIHB1YmxpY0lkMU5ld0ltcCk7CisgICAgICBhc3NlcnROdWxsKCJkb2N1bWVudGltcG9ydG5vZGUyMl9OMVNJRCIsIHN5c3RlbUlkMUltcCk7CisgICAgICBhc3NlcnROdWxsKCJkb2N1bWVudGltcG9ydG5vZGUyMl9OMU5TSUQiLCBzeXN0ZW1JZDFOZXdJbXApOworICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUyMl9OMlNJRCIsIHN5c3RlbUlkMiwgc3lzdGVtSWQySW1wKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMjJfTjJOU0lEIiwgc3lzdGVtSWQyLCBzeXN0ZW1JZDJOZXdJbXApOworICAgICAgYXNzZXJ0TnVsbCgiZG9jdW1lbnRpbXBvcnRub2RlMjJfTjJQSUQiLCBwdWJsaWNJZDJJbXApOworICAgICAgYXNzZXJ0TnVsbCgiZG9jdW1lbnRpbXBvcnRub2RlMjJfTjJOUElEIiwgcHVibGljSWQySW1wKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9jdW1lbnRpbXBvcnRub2RlMjIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50aW1wb3J0bm9kZTIyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudHR5cGVpbnRlcm5hbFN1YnNldDAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50dHlwZWludGVybmFsU3Vic2V0MDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNDMyNDExCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudHR5cGVpbnRlcm5hbFN1YnNldDAxLmphdmEKQEAgLTAsMCArMSw5MiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgbWV0aG9kIGdldEludGVybmFsU3Vic2V0KCkgcmV0dXJucyB0aGUgaW50ZXJuYWwgc3Vic2V0IGFzIGEgc3RyaW5nLiAKKyAqICAgCisgKiAgICAgQ3JlYXRlIGEgbmV3IERvY3VtZW50VHlwZSBub2RlIHdpdGggbnVsbCB2YWx1ZXMgZm9yIHB1YmxpY0lkIGFuZCBzeXN0ZW1JZC4KKyAqICAgICBWZXJpZnkgdGhhdCBpdHMgaW50ZXJuYWwgc3Vic2V0IGlzIG51bGwuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtQ29yZS1Eb2NUeXBlLWludGVybmFsU3Vic2V0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtQ29yZS1Eb2NUeXBlLWludGVybmFsU3Vic2V0PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50dHlwZWludGVybmFsU3Vic2V0MDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50dHlwZWludGVybmFsU3Vic2V0MDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBTdHJpbmcgaW50ZXJuYWw7CisgICAgICBTdHJpbmcgbnVsbE5TID0gbnVsbDsKKworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgZG9jVHlwZSA9IGRvbUltcGwuY3JlYXRlRG9jdW1lbnRUeXBlKCJsMjpyb290IiwgbnVsbE5TLCBudWxsTlMpOworICAgICAgaW50ZXJuYWwgPSBkb2NUeXBlLmdldEludGVybmFsU3Vic2V0KCk7CisgICAgICBhc3NlcnROdWxsKCJpbnRlcm5hbFN1YnNldE51bGwiLCBpbnRlcm5hbCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvY3VtZW50dHlwZWludGVybmFsU3Vic2V0MDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvY3VtZW50dHlwZWludGVybmFsU3Vic2V0MDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50dHlwZXB1YmxpY2lkMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9jdW1lbnR0eXBlcHVibGljaWQwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ3ODM0Y2QKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50dHlwZXB1YmxpY2lkMDEuamF2YQpAQCAtMCwwICsxLDkyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBtZXRob2QgZ2V0SW50ZXJuYWxTdWJzZXQoKSByZXR1cm5zIHRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgc3Vic2V0LgorICogICAKKyAqICAgICBDcmVhdGUgYSBuZXcgRG9jdW1lbnRUeXBlIG5vZGUgd2l0aCB0aGUgdmFsdWUgIlBVQiIgZm9yIGl0cyBwdWJsaWNJZC4KKyAqICAgICBDaGVjayB0aGUgdmFsdWUgb2YgdGhlIHB1YmxpY0lkIGF0dHJpYnV0ZSB1c2luZyBnZXRQdWJsaWNJZCgpLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUNvcmUtRG9jVHlwZS1wdWJsaWNJZCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUNvcmUtRG9jVHlwZS1wdWJsaWNJZDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb2N1bWVudHR5cGVwdWJsaWNpZDAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb2N1bWVudHR5cGVwdWJsaWNpZDAxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgU3RyaW5nIHB1YmxpY0lkOworICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgIGRvY1R5cGUgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50VHlwZSgibDI6cm9vdCIsICJQVUIiLCBudWxsTlMpOworICAgICAgcHVibGljSWQgPSBkb2NUeXBlLmdldFB1YmxpY0lkKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50dHlwZXB1YmxpY2lkMDEiLCAiUFVCIiwgcHVibGljSWQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudHR5cGVwdWJsaWNpZDAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudHR5cGVwdWJsaWNpZDAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudHR5cGVzeXN0ZW1pZDAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvY3VtZW50dHlwZXN5c3RlbWlkMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMjY2YmY1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb2N1bWVudHR5cGVzeXN0ZW1pZDAxLmphdmEKQEAgLTAsMCArMSw5MiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIG1ldGhvZCBnZXRJbnRlcm5hbFN1YnNldCgpIHJldHVybnMgdGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBleHRlcm5hbCBzdWJzZXQuCisgKiAgIAorICogICAgIENyZWF0ZSBhIG5ldyBEb2N1bWVudFR5cGUgbm9kZSB3aXRoIHRoZSB2YWx1ZSAiU1lTIiBmb3IgaXRzIHN5c3RlbUlkIGFuZCBQVUIgZm9yCisgKiAgICAgaXRzIHB1YmxpY0lkLiAgQ2hlY2sgdGhlIHZhbHVlIG9mIHRoZSBzeXN0ZW1JZCBhbmQgcGJ1bGljSWQgYXR0cmlidXRlcy4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Db3JlLURvY1R5cGUtc3lzdGVtSWQiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Db3JlLURvY1R5cGUtc3lzdGVtSWQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvY3VtZW50dHlwZXN5c3RlbWlkMDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvY3VtZW50dHlwZXN5c3RlbWlkMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBTdHJpbmcgcHVibGljSWQ7CisgICAgICBTdHJpbmcgc3lzdGVtSWQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICBkb2NUeXBlID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudFR5cGUoImwyOnJvb3QiLCAiUFVCIiwgIlNZUyIpOworICAgICAgcHVibGljSWQgPSBkb2NUeXBlLmdldFB1YmxpY0lkKCk7CisgICAgICBzeXN0ZW1JZCA9IGRvY1R5cGUuZ2V0U3lzdGVtSWQoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnR0eXBlcHVibGljaWQwMSIsICJQVUIiLCBwdWJsaWNJZCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50dHlwZXN5c3RlbWlkMDEiLCAiU1lTIiwgc3lzdGVtSWQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb2N1bWVudHR5cGVzeXN0ZW1pZDAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb2N1bWVudHR5cGVzeXN0ZW1pZDAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudDAzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzQwZTlhOAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudDAzLmphdmEKQEAgLTAsMCArMSwxMjcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKKworaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorCitQVVJQT1NFLiAgCisKKworCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIGNyZWF0ZURvY3VtZW50IG1ldGhvZCB3aXRoIHZhbGlkIGFyZ3VtZW50cywgc2hvdWxkIGNyZWF0ZSBhIERPTSBEb2N1bWVudCBvZiAKKyAqICAgICB0aGUgc3BlY2lmaWVkIHR5cGUuICAKKyAqICAgICAKKyAqICAgICBDYWxsIHRoZSBjcmVhdGVEb2N1bWVudCBvbiB0aGlzIERPTUltcGxlbWVudGF0aW9uIHdpdGggCisgKiAgICAgY3JlYXRlRG9jdW1lbnQgKCJodHRwOi8vd3d3LnczLm9yZy9ET01UZXN0L0wyIixzZWUgdGhlIGFycmF5IGJlbG93IGZvciB2YWxpZCBRTmFtZXMsbnVsbCkuICAKKyAqICAgICBDaGVjayBpZiB0aGUgcmV0dXJuZWQgRG9jdW1lbnQgb2JqZWN0IGlzIGlzIGVtcHR5IHdpdGggbm8gRG9jdW1lbnQgRWxlbWVudC4gCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2N1bWVudCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1ET00tY3JlYXRlRG9jdW1lbnQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwMyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudDAzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIERvY3VtZW50IG5ld0RvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlID0gbnVsbDsKKworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LnczLm9yZy9ET01UZXN0L0wyIjsKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lOworICAgICAgamF2YS51dGlsLkxpc3QgcXVhbGlmaWVkTmFtZXMgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJfOl8iKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiXzpoMCIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJfOnRlc3QiKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgibF86XyIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJuczpfMCIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJuczphMCIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJuczA6dGVzdCIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJhLmI6YyIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJhLWI6YyIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJhLWI6YyIpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA2QiA9IDA7IGluZGV4TjEwMDZCIDwgcXVhbGlmaWVkTmFtZXMuc2l6ZSgpOyBpbmRleE4xMDA2QisrKSB7CisgICAgICAgICAgcXVhbGlmaWVkTmFtZSA9IChTdHJpbmcpIHF1YWxpZmllZE5hbWVzLmdldChpbmRleE4xMDA2Qik7CisgICAgbmV3RG9jID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsIGRvY1R5cGUpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudDAzIiwgbmV3RG9jKTsKKyAgICAgICAgfQorICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudDA0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwNC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlMjRhZWYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwNC5qYXZhCkBAIC0wLDAgKzEsMTE2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKworUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKKworUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCisKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKwordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKKworUFVSUE9TRS4gIAorCisKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBjcmVhdGVEb2N1bWVudCBtZXRob2Qgc2hvdWxkIHRocm93IGEgTkFNRVNQQUNFX0VSUiBpZiB0aGUgcXVhbGlmaWVkTmFtZSBoYXMgCisgKiAgYSBwcmVmaXggYW5kIHRoZSBuYW1lc3BhY2VVUkkgaXMgbnVsbC4KKyAqICAgICAKKyAqICAgICBDYWxsIHRoZSBjcmVhdGVEb2N1bWVudCBvbiB0aGlzIERPTUltcGxlbWVudGF0aW9uIHdpdGggbnVsbCBuYW1lc3BhY2VVUkkgYW5kIGEgCisgKiAgICAgcXVhbGlmaWVkTmFtZSB0aGF0IGhhcyBhIG5hbWVzcGFjZSBwcmVmaXggdXNpbmcgdGhpcyBET01JbXBsZW1lbnRhdGlvbi4gIAorICogICAgIENoZWNrIGlmIHRoZSBOQU1FU1BBQ0VfRVJSIGlzIHRocm93bi4gIAorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1ET00tY3JlYXRlRG9jdW1lbnQiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2N1bWVudDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudDA0IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgRG9jdW1lbnQgbmV3RG9jOworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9IG51bGw7CisKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gImRvbTpyb290IjsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlID0gbnVsbDsKKworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXdEb2MgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSwgZG9jVHlwZSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgiZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudDA0Iiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudDA0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudDA1LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGVmZWU0OAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudDA1LmphdmEKQEAgLTAsMCArMSwxMTUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKKworaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorCitQVVJQT1NFLiAgCisKKworCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIGNyZWF0ZURvY3VtZW50IG1ldGhvZCBzaG91bGQgdGhyb3cgYSBOQU1FU1BBQ0VfRVJSIGlmIHRoZSBxdWFsaWZpZWROYW1lIGhhcyAKKyAqICBhIHByZWZpeCB0aGF0IGlzIHhtbCBhbmQgdGhlIG5hbWVzcGFjZVVSSSBpcyBkaWZmZXJlbnQgZnJvbSAKKyAqICBodHRwOi8vd3d3Li53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlLgorICogIAorICogIENhbGwgdGhlIGNyZWF0ZURvY3VtZW50IG9uIHRoaXMgRE9NSW1wbGVtZW50YXRpb24gd2l0aCBuYW1lc3BhY2VVUkkgdGhhdCBpcyAKKyAqICBodHRwOi8vd3d3LnczLm9yZy94bWwvMTk5OC9uYW1lc3BhY2UgYW5kIGEgcXVhbGlmaWVkTmFtZSB0aGF0IGhhcyB0aGUgcHJlZml4IHhtbAorICogIENoZWNrIGlmIHRoZSBOQU1FU1BBQ0VfRVJSIGlzIHRocm93bi4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2N1bWVudDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudDA1IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgRG9jdW1lbnQgbmV3RG9jOworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LnczLm9yZy94bWwvMTk5OC9uYW1lc3BhY2UiOworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAieG1sOnJvb3QiOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGUgPSBudWxsOworCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ld0RvYyA9IGRvbUltcGwuY3JlYXRlRG9jdW1lbnQobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lLCBkb2NUeXBlKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDUiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudDA1IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwNy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NmE0N2NkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDcuamF2YQpAQCAtMCwwICsxLDExMiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKworKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCisKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKworSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAorCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisKK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCisKK1BVUlBPU0UuICAKKworCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgY3JlYXRlRG9jdW1lbnQgbWV0aG9kIHNob3VsZCByYWlzZSBhIE5BTUVTUEFDRV9FUlIgaWYgdGhlIHF1YWxpZmllZE5hbWUgaXMgbWFsZm9ybWVkIAorICogICAgICAKKyAqICBJbnZva2UgdGhlIGNyZWF0ZURvY3VtZW50IG1ldGhvZCBvbiB0aGlzIERPTUltcGxlbWVudGF0aW9uIG9iamVjdCB3aXRoIG51bGwgdmFsdWVzCisgKiAgZm9yIG5hbWVzcGFjZVVSSSBhbmQgZG9jVHlwZSBhbmQgYSBtYWxmb3JtZWQgcXVhbGlmaWVkTmFtZS4gIAorICogIFRoZSBOQU1FU1BBQ0VfRVJSIHNob3VsZCBiZSByYWlzZWQuIAorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1ET00tY3JlYXRlRG9jdW1lbnQiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDcgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGRvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwNyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBEb2N1bWVudCBuZXdEb2M7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cudzMub3JnL0RPTVRlc3QvbGV2ZWwyIjsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlID0gbnVsbDsKKworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXdEb2MgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KG5hbWVzcGFjZVVSSSwgIjoiLCBkb2NUeXBlKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDciLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudDA3IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50MDcuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnR0eXBlMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk5ZjFhNjMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnR0eXBlMDEuamF2YQpAQCAtMCwwICsxLDEwOSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCBjcmVhdGVEb2N1bWVudFR5cGUgd2l0aCB2YWxpZCB2YWx1ZXMgZm9yIHF1YWxpZmllZE5hbWUsIHB1YmxpY0lkIGFuZAorICogIHN5c3RlbUlkIHNob3VsZCBjcmVhdGUgYW4gZW1wdHkgRG9jdW1lbnRUeXBlIG5vZGUuCisgKiAgCisgKiAgSW52b2tlIGNyZWF0ZURvY3VtZW50IG9uIHRoaXMgRE9NSW1wbGVtZW50YXRpb24gd2l0aCBhIHZhbGlkIHF1YWxpZmllZE5hbWUgYW5kIGRpZmZlcmVudAorICogIHB1YmxpY0lkcyBhbmQgc3lzdGVtSWRzLiAgQ2hlY2sgaWYgdGhlIHRoZSBEb2N1bWVudFR5cGUgbm9kZSB3YXMgY3JlYXRlZCB3aXRoIGl0cyAKKyAqICBvd25lckRvY3VtZW50IGF0dHJpYnV0ZSBzZXQgdG8gbnVsbC4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2N1bWVudDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBEb2N1bWVudFR5cGUgbmV3RG9jVHlwZTsKKyAgICAgIERvY3VtZW50IG93bmVyRG9jdW1lbnQ7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJ0ZXN0OnJvb3QiOworICAgICAgU3RyaW5nIHB1YmxpY0lkOworICAgICAgU3RyaW5nIHN5c3RlbUlkOworICAgICAgamF2YS51dGlsLkxpc3QgcHVibGljSWRzID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIHB1YmxpY0lkcy5hZGQoIjEyMzQiKTsKKyAgICAgIHB1YmxpY0lkcy5hZGQoInRlc3QiKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkxpc3Qgc3lzdGVtSWRzID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIHN5c3RlbUlkcy5hZGQoIiIpOworICAgICAgc3lzdGVtSWRzLmFkZCgidGVzdCIpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA1RCA9IDA7IGluZGV4TjEwMDVEIDwgcHVibGljSWRzLnNpemUoKTsgaW5kZXhOMTAwNUQrKykgeworICAgICAgICAgIHB1YmxpY0lkID0gKFN0cmluZykgcHVibGljSWRzLmdldChpbmRleE4xMDA1RCk7CisgICAgZm9yIChpbnQgaW5kZXhOMTAwNjEgPSAwOyBpbmRleE4xMDA2MSA8IHN5c3RlbUlkcy5zaXplKCk7IGluZGV4TjEwMDYxKyspIHsKKyAgICAgICAgICBzeXN0ZW1JZCA9IChTdHJpbmcpIHN5c3RlbUlkcy5nZXQoaW5kZXhOMTAwNjEpOworICAgIG5ld0RvY1R5cGUgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50VHlwZShxdWFsaWZpZWROYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwMV9uZXdEb2NUeXBlIiwgbmV3RG9jVHlwZSk7CisgICAgICBvd25lckRvY3VtZW50ID0gbmV3RG9jVHlwZS5nZXRPd25lckRvY3VtZW50KCk7CisgICAgICBhc3NlcnROdWxsKCJkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50dHlwZTAxX293bmVyRG9jdW1lbnQiLCBvd25lckRvY3VtZW50KTsKKyAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnR0eXBlMDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnR0eXBlMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnR0eXBlMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5NjJiZmEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnR0eXBlMDIuamF2YQpAQCAtMCwwICsxLDEyNyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKworKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCisKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKworSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAorCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisKK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCisKK1BVUlBPU0UuICAKKworCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIGNyZWF0ZURvY3VtZW50VHlwZSB3aXRoIHZhbGlkIHZhbHVlcyBmb3IgcXVhbGlmaWVkTmFtZSwgcHVibGljSWQgYW5kCisgKiAgc3lzdGVtSWQgc2hvdWxkIGNyZWF0ZSBhbiBlbXB0eSBEb2N1bWVudFR5cGUgbm9kZS4KKyAqICAKKyAqICBJbnZva2UgY3JlYXRlRG9jdW1lbnQgb24gdGhpcyBET01JbXBsZW1lbnRhdGlvbiB3aXRoIGEgZGlmZmVyZW50IHZhbGlkIHF1YWxpZmllZE5hbWVzIAorICogIGFuZCBhIHZhbGlkIHB1YmxpY0lkIGFuZCBzeXN0ZW1JZC4gIENoZWNrIGlmIHRoZSB0aGUgRG9jdW1lbnRUeXBlIG5vZGUgd2FzIGNyZWF0ZWQgCisgKiAgd2l0aCBpdHMgb3duZXJEb2N1bWVudCBhdHRyaWJ1dGUgc2V0IHRvIG51bGwuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2NUeXBlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2NUeXBlPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50dHlwZTAyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50dHlwZTAyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIERvY3VtZW50VHlwZSBuZXdEb2NUeXBlOworICAgICAgRG9jdW1lbnQgb3duZXJEb2N1bWVudDsKKyAgICAgIFN0cmluZyBwdWJsaWNJZCA9ICJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9kb20yLmR0ZCI7CisgICAgICBTdHJpbmcgc3lzdGVtSWQgPSAiZG9tMi5kdGQiOworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWU7CisgICAgICBqYXZhLnV0aWwuTGlzdCBxdWFsaWZpZWROYW1lcyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIl86XyIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJfOmgwIik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIl86dGVzdCIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJfOl8uIik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIl86YS0iKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgibF86XyIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJuczpfMCIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJuczphMCIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJuczA6dGVzdCIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJuczpFRUUuIik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIm5zOl8tIik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoImEuYjpjIik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoImEtYjpjLmoiKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiYS1iOmMiKTsKKyAgICAgIAorICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwNzcgPSAwOyBpbmRleE4xMDA3NyA8IHF1YWxpZmllZE5hbWVzLnNpemUoKTsgaW5kZXhOMTAwNzcrKykgeworICAgICAgICAgIHF1YWxpZmllZE5hbWUgPSAoU3RyaW5nKSBxdWFsaWZpZWROYW1lcy5nZXQoaW5kZXhOMTAwNzcpOworICAgIG5ld0RvY1R5cGUgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50VHlwZShxdWFsaWZpZWROYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwMl9uZXdEb2NUeXBlIiwgbmV3RG9jVHlwZSk7CisgICAgICBvd25lckRvY3VtZW50ID0gbmV3RG9jVHlwZS5nZXRPd25lckRvY3VtZW50KCk7CisgICAgICBhc3NlcnROdWxsKCJkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50dHlwZTAyX293bmVyRG9jdW1lbnQiLCBvd25lckRvY3VtZW50KTsKKyAgICAgICAgfQorICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50dHlwZTAyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50dHlwZTAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50dHlwZTA0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnR0eXBlMDQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZTAwODRjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50dHlwZTA0LmphdmEKQEAgLTAsMCArMSwxMzEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKKworaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorCitQVVJQT1NFLiAgCisKKworCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCBjcmVhdGVEb2N1bWVudFR5cGUgc2hvdWxkIHJhaXNlIGEgSU5WQUxJRF9DSEFSQUNURVJfRVJSIGlmIHRoZSBxdWFsaWZpZWROYW1lIAorICogIGNvbnRhaW5zIGFuIGlsbGVnYWwgY2hhcmFjdGVycy4KKyAqICAKKyAqICBJbnZva2UgY3JlYXRlRG9jdW1lbnQgb24gdGhpcyBET01JbXBsZW1lbnRhdGlvbiB3aXRoIHF1YWxpZmllZE5hbWVzIGhhdmluZyBpbGxlZ2FsIGNoYXJhY3RlcnMuIAorICogIENoZWNrIGlmIGFuIElOVkFMSURfQ0hBUkFDVEVSX0VSUiBpcyByYWlzZWQgaW4gZWFjaCBjYXNlLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1ET00tY3JlYXRlRG9jVHlwZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1ET00tY3JlYXRlRG9jVHlwZTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBEb2N1bWVudFR5cGUgbmV3RG9jVHlwZTsKKyAgICAgIFN0cmluZyBwdWJsaWNJZCA9ICJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9kb20yLmR0ZCI7CisgICAgICBTdHJpbmcgc3lzdGVtSWQgPSAiZG9tMi5kdGQiOworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWU7CisgICAgICBqYXZhLnV0aWwuTGlzdCBxdWFsaWZpZWROYW1lcyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoInsiKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgifSIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCInIik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIn4iKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiYCIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJAIik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIiMiKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiJCIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCIlIik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIl4iKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiJiIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCIqIik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIigiKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiKSIpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA3MyA9IDA7IGluZGV4TjEwMDczIDwgcXVhbGlmaWVkTmFtZXMuc2l6ZSgpOyBpbmRleE4xMDA3MysrKSB7CisgICAgICAgICAgcXVhbGlmaWVkTmFtZSA9IChTdHJpbmcpIHF1YWxpZmllZE5hbWVzLmdldChpbmRleE4xMDA3Myk7CisgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXdEb2NUeXBlID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudFR5cGUocXVhbGlmaWVkTmFtZSwgcHVibGljSWQsIHN5c3RlbUlkKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoImRvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnR0eXBlMDQiLCBzdWNjZXNzKTsKKyAgICAgIH0KKyAgfQorICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50dHlwZTA0IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50dHlwZTA0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVjb3JlLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZWNvcmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YTI5OWYwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmVjb3JlLmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKKworaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorCitQVVJQT1NFLiAgCisKKworCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJmZWF0dXJlIiBwYXJhbWV0ZXIgaW4gdGhlCisgKiAgICAiaGFzRmVhdHVyZShmZWF0dXJlLHZlcnNpb24pIiBtZXRob2QgaXMgdGhlIHBhY2thZ2UgbmFtZQorICogICAgb2YgdGhlIGZlYXR1cmUuICBMZWdhbCB2YWx1ZXMgYXJlIFhNTCBhbmQgSFRNTCBhbmQgQ09SRS4KKyAqICAgIChUZXN0IGZvciBmZWF0dXJlIGNvcmUsIGxvd2VyIGNhc2UpCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBlbnRpcmUgRE9NIGRvY3VtZW50IGFuZCBpbnZva2UgaXRzIAorICogICAgImdldEltcGxlbWVudGF0aW9uKCkiIG1ldGhvZC4gIFRoaXMgc2hvdWxkIGNyZWF0ZSBhCisgKiAgICBET01JbXBsZW1lbnRhdGlvbiBvYmplY3Qgd2hvc2UgImhhc0ZlYXR1cmUoZmVhdHVyZSwKKyAqICAgIHZlcnNpb24pIiBtZXRob2QgaXMgaW52b2tlZCB3aXRoIGZlYXR1cmUgZXF1YWwgdG8gImNvcmUiLgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgYm9vbGVhbiAidHJ1ZSIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtNUNFRDk0RDciPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC01Q0VEOTRENzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZG9taW1wbGVtZW50YXRpb25mZWF0dXJlY29yZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9taW1wbGVtZW50YXRpb25mZWF0dXJlY29yZShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICBzdGF0ZSA9IGRvbUltcGwuaGFzRmVhdHVyZSgiY29yZSIsICIyLjAiKTsKK2Fzc2VydFRydWUoImRvbWltcGxlbWVudGF0aW9uRmVhdHVyZWNvcmVBc3NlcnQiLCBzdGF0ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZWNvcmUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGRvbWltcGxlbWVudGF0aW9uZmVhdHVyZWNvcmUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZXhtbHZlcnNpb24yLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uZmVhdHVyZXhtbHZlcnNpb24yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDczMDJjZgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9taW1wbGVtZW50YXRpb25mZWF0dXJleG1sdmVyc2lvbjIuamF2YQpAQCAtMCwwICsxLDEwNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKworKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCisKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKworSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAorCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisKK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCisKK1BVUlBPU0UuICAKKworCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImZlYXR1cmUiIHBhcmFtZXRlciBpbiB0aGUKKyAqICAgICJoYXNGZWF0dXJlKGZlYXR1cmUsdmVyc2lvbikiIG1ldGhvZCBpcyB0aGUgcGFja2FnZSBuYW1lCisgKiAgICBvZiB0aGUgZmVhdHVyZS4gIExlZ2FsIHZhbHVlcyBhcmUgWE1MIGFuZCBIVE1MLgorICogICAgKFRlc3QgZm9yIGZlYXR1cmUgInhtbCIgYW5kIHZlcnNpb24gIjIuMCIpIAorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgZW50aXJlIERPTSBkb2N1bWVudCBhbmQgaW52b2tlIGl0cyAKKyAqICAgICJnZXRJbXBsZW1lbnRhdGlvbigpIiBtZXRob2QuICBUaGlzIHNob3VsZCBjcmVhdGUgYQorICogICAgRE9NSW1wbGVtZW50YXRpb24gb2JqZWN0IHdob3NlICJoYXNGZWF0dXJlKGZlYXR1cmUsCisgKiAgICB2ZXJzaW9uKSIgbWV0aG9kIGlzIGludm9rZWQgd2l0aCAiZmVhdHVyZSIgZXF1YWwgdG8gInhtbCIuCisgKiAgICBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gYSBib29sZWFuICJ0cnVlIi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC01Q0VEOTRENyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELTVDRUQ5NEQ3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb21pbXBsZW1lbnRhdGlvbmZlYXR1cmV4bWx2ZXJzaW9uMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9taW1wbGVtZW50YXRpb25mZWF0dXJleG1sdmVyc2lvbjIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgc3RhdGUgPSBkb21JbXBsLmhhc0ZlYXR1cmUoInhtbCIsICIyLjAiKTsKK2Fzc2VydFRydWUoImRvbWltcGxlbWVudGF0aW9uRmVhdHVyZXhtbFZlcnNpb24yQXNzZXJ0Iiwgc3RhdGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmZlYXR1cmV4bWx2ZXJzaW9uMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9taW1wbGVtZW50YXRpb25mZWF0dXJleG1sdmVyc2lvbjIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uaGFzZmVhdHVyZTAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uaGFzZmVhdHVyZTAxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjE3NGYxYgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9taW1wbGVtZW50YXRpb25oYXNmZWF0dXJlMDEuamF2YQpAQCAtMCwwICsxLDExNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCAiaGFzRmVhdHVyZShmZWF0dXJlLHZlcnNpb24pIiB0ZXN0cyBpZiB0aGUgRE9NSW1wbGVtZW50YXRpb24gaW1wbGVtZW50cworICogIGEgc3BlY2lmaWMgZmVhdHVyZSBhbmQgaWYgc28gcmV0dXJucyB0cnVlLgorICogIAorICogIENhbGwgdGhlIGhhc0ZlYXR1cmUgbWV0aG9kIG9uIHRoaXMgRE9NSW1wbGVtZW50YXRpb24gd2l0aCBhIGNvbWJpbmF0aW9uIG9mIGZlYXR1cmVzIAorICogIHZlcnNpb25zIGFzIGJlbG93LiAgVmFsaWQgZmVhdHVyZSBuYW1lcyBhcmUgY2FzZSBpbnNlbnNpdGl2ZSBhbmQgdmVyc2lvbnMgIjIuMCIsIAorICogICIxLjAiIGFuZCBpZiB0aGUgdmVyc2lvbiBpcyBub3Qgc3BlY2lmaWVkLCBzdXBwb3J0aW5nIGFueSB2ZXJzaW9uIG9mIHRoZSBmZWF0dXJlCisgKiAgc2hvdWxkIHJldHVybiB0cnVlLiAgQ2hlY2sgaWYgdGhlIHZhbHVlIHJldHVybmVkIHZhbHVlIHdhcyB0cnVlLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELTVDRUQ5NEQ3Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtNUNFRDk0RDc8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGRvbWltcGxlbWVudGF0aW9uaGFzZmVhdHVyZTAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBkb21pbXBsZW1lbnRhdGlvbmhhc2ZlYXR1cmUwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBTdHJpbmcgdmVyc2lvbiA9ICIiOworICAgICAgU3RyaW5nIHZlcnNpb24xID0gIjEuMCI7CisgICAgICBTdHJpbmcgdmVyc2lvbjIgPSAiMi4wIjsKKyAgICAgIFN0cmluZyBmZWF0dXJlQ29yZTsKKyAgICAgIFN0cmluZyBmZWF0dXJlWE1MOworICAgICAgYm9vbGVhbiBzdWNjZXNzOworICAgICAgamF2YS51dGlsLkxpc3QgZmVhdHVyZXNYTUwgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgZmVhdHVyZXNYTUwuYWRkKCJYTUwiKTsKKyAgICAgIGZlYXR1cmVzWE1MLmFkZCgieG1MIik7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5MaXN0IGZlYXR1cmVzQ29yZSA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBmZWF0dXJlc0NvcmUuYWRkKCJDb3JlIik7CisgICAgICBmZWF0dXJlc0NvcmUuYWRkKCJDT1JFIik7CisgICAgICAKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDYzID0gMDsgaW5kZXhOMTAwNjMgPCBmZWF0dXJlc1hNTC5zaXplKCk7IGluZGV4TjEwMDYzKyspIHsKKyAgICAgICAgICBmZWF0dXJlWE1MID0gKFN0cmluZykgZmVhdHVyZXNYTUwuZ2V0KGluZGV4TjEwMDYzKTsKKyAgICBzdWNjZXNzID0gZG9tSW1wbC5oYXNGZWF0dXJlKGZlYXR1cmVYTUwsIHZlcnNpb24pOworYXNzZXJ0VHJ1ZSgiZG9taW1wbGVtZW50YXRpb25oYXNmZWF0dXJlMDFfWE1MXzEiLCBzdWNjZXNzKTsKKyAgICAgIHN1Y2Nlc3MgPSBkb21JbXBsLmhhc0ZlYXR1cmUoZmVhdHVyZVhNTCwgdmVyc2lvbjEpOworYXNzZXJ0VHJ1ZSgiZG9taW1wbGVtZW50YXRpb25oYXNmZWF0dXJlMDFfWE1MXzIiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgICAgZm9yIChpbnQgaW5kZXhOMTAwN0MgPSAwOyBpbmRleE4xMDA3QyA8IGZlYXR1cmVzQ29yZS5zaXplKCk7IGluZGV4TjEwMDdDKyspIHsKKyAgICAgICAgICBmZWF0dXJlQ29yZSA9IChTdHJpbmcpIGZlYXR1cmVzQ29yZS5nZXQoaW5kZXhOMTAwN0MpOworICAgIHN1Y2Nlc3MgPSBkb21JbXBsLmhhc0ZlYXR1cmUoZmVhdHVyZUNvcmUsIHZlcnNpb24pOworYXNzZXJ0VHJ1ZSgiZG9taW1wbGVtZW50YXRpb25oYXNmZWF0dXJlMDFfQ29yZV8xIiwgc3VjY2Vzcyk7CisgICAgICBzdWNjZXNzID0gZG9tSW1wbC5oYXNGZWF0dXJlKGZlYXR1cmVDb3JlLCB2ZXJzaW9uMSk7CitzdWNjZXNzID0gZG9tSW1wbC5oYXNGZWF0dXJlKGZlYXR1cmVDb3JlLCB2ZXJzaW9uMik7Cithc3NlcnRUcnVlKCJkb21pbXBsZW1lbnRhdGlvbmhhc2ZlYXR1cmUwMV9Db3JlXzMiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9kb21pbXBsZW1lbnRhdGlvbmhhc2ZlYXR1cmUwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZG9taW1wbGVtZW50YXRpb25oYXNmZWF0dXJlMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uaGFzZmVhdHVyZTAyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uaGFzZmVhdHVyZTAyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDc1MzI5OQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZG9taW1wbGVtZW50YXRpb25oYXNmZWF0dXJlMDIuamF2YQpAQCAtMCwwICsxLDg4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2QgImhhc0ZlYXR1cmUoZmVhdHVyZSx2ZXJzaW9uKSIgdGVzdHMgaWYgdGhlIERPTUltcGxlbWVudGF0aW9uIGltcGxlbWVudHMKKyAqICBhIHNwZWNpZmljIGZlYXR1cmUgYW5kIGlmIG5vdCByZXR1cm5zIGZhbHNlLgorICogIAorICogIENhbGwgdGhlIGhhc0ZlYXR1cmUgbWV0aG9kIG9uIHRoaXMgRE9NSW1wbGVtZW50YXRpb24gd2l0aCBhIHVuZmltaWxpYXIgdmFsdWVzIGZvciAKKyAqICBmZWF0dXJlIGFuZCB2ZXJzaW9uLiAgQ2hlY2sgaWYgdGhlIHZhbHVlIHJldHVybmVkIHdhcyBmYWxzZS4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC01Q0VEOTRENyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELTVDRUQ5NEQ3PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBkb21pbXBsZW1lbnRhdGlvbmhhc2ZlYXR1cmUwMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZG9taW1wbGVtZW50YXRpb25oYXNmZWF0dXJlMDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgYm9vbGVhbiBzdWNjZXNzOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgc3VjY2VzcyA9IGRvbUltcGwuaGFzRmVhdHVyZSgiQmxhaCBCbGFoIiwgIiIpOworYXNzZXJ0RmFsc2UoImRvbWltcGxlbWVudGF0aW9uaGFzZmVhdHVyZTAyIiwgc3VjY2Vzcyk7Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2RvbWltcGxlbWVudGF0aW9uaGFzZmVhdHVyZTAyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihkb21pbXBsZW1lbnRhdGlvbmhhc2ZlYXR1cmUwMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnMwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI4NmUwN2QKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnMwMS5qYXZhCkBAIC0wLDAgKzEsMTE1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgICAgVGhlIG1ldGhvZCBnZXRBdHRyaWJ1dGVOb2RlTlMgcmV0cmlldmVzIGFuIEF0dHIgbm9kZSBieSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLgorICogICAgICAgQ3JlYXRlIGEgbmV3IGVsZW1lbnQgbm9kZSBhbmQgYWRkIDIgbmV3IGF0dHJpYnV0ZSBub2RlcyB0byBpdCB0aGF0IGhhdmUgdGhlIHNhbWUgCisgKiAgICAgICBsb2NhbCBuYW1lIGJ1dCBkaWZmZXJlbnQgbmFtZXNwYWNlVVJJcyBhbmQgcHJlZml4ZXMuICAKKyAqICAgICAgIFJldHJpZXZlIGFuIGF0dHJpYnV0ZSB1c2luZyBuYW1lc3BhY2UgYW5kIGxvY2FsbmFtZSBhbmQgY2hlY2sgaXRzIHZhbHVlLCBuYW1lIGFuZCAKKyAqICAgICAgIG5hbWVzcGFjZVVSSS4KKyAqICAgICAKKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEdldEF0Tm9kZU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxHZXRBdE5vZGVOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50Z2V0YXR0cmlidXRlbm9kZW5zMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBBdHRyIGF0dHJpYnV0ZTE7CisgICAgICBBdHRyIGF0dHJpYnV0ZTI7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTE7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTI7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICBTdHJpbmcgYXR0ck5hbWU7CisgICAgICBTdHJpbmcgYXR0Tm9kZU5hbWU7CisgICAgICBTdHJpbmcgYXR0ckxvY2FsTmFtZTsKKyAgICAgIFN0cmluZyBhdHRyTlM7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUygibmFtZXNwYWNlVVJJIiwgInJvb3QiKTsKKyAgICAgIGF0dHJpYnV0ZTEgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9MZXZlbDIiLCAibDI6YXR0Iik7CisgICAgICBuZXdBdHRyaWJ1dGUxID0gZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMoYXR0cmlidXRlMSk7CisgICAgICBhdHRyaWJ1dGUyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vTGV2ZWwxIiwgImF0dCIpOworICAgICAgbmV3QXR0cmlidXRlMiA9IGVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZU5TKGF0dHJpYnV0ZTIpOworICAgICAgYXR0cmlidXRlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9MZXZlbDIiLCAiYXR0Iik7CisgICAgICBhdHRyVmFsdWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhdHRyTmFtZSA9IGF0dHJpYnV0ZS5nZXROYW1lKCk7CisgICAgICBhdHROb2RlTmFtZSA9IGF0dHJpYnV0ZS5nZXROb2RlTmFtZSgpOworICAgICAgYXR0ckxvY2FsTmFtZSA9IGF0dHJpYnV0ZS5nZXRMb2NhbE5hbWUoKTsKKyAgICAgIGF0dHJOUyA9IGF0dHJpYnV0ZS5nZXROYW1lc3BhY2VVUkkoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAxX2F0dHJWYWx1ZSIsICIiLCBhdHRyVmFsdWUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50Z2V0YXR0cmlidXRlbm9kZW5zMDFfYXR0ck5hbWUiLCAibDI6YXR0IiwgYXR0ck5hbWUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50Z2V0YXR0cmlidXRlbm9kZW5zMDFfYXR0ck5vZGVOYW1lIiwgImwyOmF0dCIsIGF0dE5vZGVOYW1lKTsKKyAgICAgIGFzc2VydEVxdWFscygiZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAxX2F0dHJMb2NhbE5hbWUiLCAiYXR0IiwgYXR0ckxvY2FsTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnMwMV9hdHRyTnMiLCAiaHR0cDovL3d3dy53My5vcmcvRE9NL0xldmVsMiIsIGF0dHJOUyk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnMwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50Z2V0YXR0cmlidXRlbm9kZW5zMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGVhNmI1OAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAyLmphdmEKQEAgLTAsMCArMSw5OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgICBUaGUgbWV0aG9kIGdldEF0dHJpYnV0ZU5vZGVOUyByZXRyaWV2ZXMgYW4gQXR0ciBub2RlIGJ5IGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkuICAKKyAqICAgICAgIENyZWF0ZSBhIG5ldyBlbGVtZW50IG5vZGUgYW5kIGFkZCBhIG5ldyBhdHRyaWJ1dGUgbm9kZSB0byBpdC4gIFVzaW5nIHRoZSBnZXRBdHRyaWJ1dGVOb2RlTlMsCisgKiAgICAgICByZXRyaWV2ZSB0aGUgbmV3bHkgYWRkZWQgYXR0cmlidXRlIG5vZGUgYW5kIGNoZWNrIGl0cyB2YWx1ZS4KKyAqICAgICAKKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEdldEF0Tm9kZU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxHZXRBdE5vZGVOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50Z2V0YXR0cmlidXRlbm9kZW5zMDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIEF0dHIgbmV3QXR0cmlidXRlMTsKKyAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUygibmFtZXNwYWNlVVJJIiwgInJvb3QiKTsKKyAgICAgIGF0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL0xldmVsMiIsICJsMjphdHQiKTsKKyAgICAgIG5ld0F0dHJpYnV0ZTEgPSBlbGVtZW50LnNldEF0dHJpYnV0ZU5vZGVOUyhhdHRyaWJ1dGUpOworICAgICAgYXR0cmlidXRlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9MZXZlbDIiLCAiYXR0Iik7CisgICAgICBhdHRyVmFsdWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnMwMiIsICIiLCBhdHRyVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50Z2V0YXR0cmlidXRlbm9kZW5zMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnMwMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnMwMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAwYTUwOTMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnMwMy5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgICAgVGhlIG1ldGhvZCBnZXRBdHRyaWJ1dGVOb2RlTlMgcmV0cmlldmVzIGFuIEF0dHIgbm9kZSBieSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLgorICogICAgICAgVXNpbmcgdGhlIGdldEF0dHJpYnV0ZU5vZGVOUywgcmV0cmlldmUgYW5kIHZlcmlmeSB0aGUgdmFsdWUgb2YgdGhlIGRlZmF1bHQKKyAqICAgICAgIGF0dHJpYnV0ZSBub2RlLgorICogICAgIAorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsR2V0QXROb2RlTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEdldEF0Tm9kZU5TPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnMwMyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlLAorb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLnZhbGlkYXRpbmcKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICBTdHJpbmcgbnVsbE5TID0gbnVsbDsKKworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgY2hpbGRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAiZW1wbG95ZWUiKTsKKyAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgY2hpbGRMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyaWJ1dGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5vZGVOUyhudWxsTlMsICJkZWZhdWx0QXR0ciIpOworICAgICAgYXR0clZhbHVlID0gYXR0cmlidXRlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50Z2V0YXR0cmlidXRlbm9kZW5zMDMiLCAiZGVmYXVsdFZhbCIsIGF0dHJWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnMwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50Z2V0YXR0cmlidXRlbnMwMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50Z2V0YXR0cmlidXRlbnMwMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVkYTMzNjcKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRnZXRhdHRyaWJ1dGVuczAyLmphdmEKQEAgLTAsMCArMSw5OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICAgIFRoZSBtZXRob2QgZ2V0QXR0cmlidXRlTlMgcmV0cmlldmVzIGFuIGF0dHJpYnV0ZSB2YWx1ZSBieSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLiAgCisgKiAgICAgICBVc2luZyB0aGUgZ2V0QXR0cmlidXRlTm9kZU5TLCByZXRyZWl2ZSBhbmQgdmVyaWZ5IHRoZSB2YWx1ZSBvZiB0aGUgZGVmYXVsdCAKKyAqICAgICAgIGF0dHJpYnV0ZSBub2RlLgorICogICAgIAorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsR2V0QXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxHZXRBdHRyTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudGdldGF0dHJpYnV0ZW5zMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRnZXRhdHRyaWJ1dGVuczAyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlLAorb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLnZhbGlkYXRpbmcKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBTdHJpbmcgYXR0clZhbHVlOworICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGNoaWxkTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImVtcGxveWVlIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGNoaWxkTGlzdC5pdGVtKDEpOworICAgICAgYXR0clZhbHVlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOUyhudWxsTlMsICJkZWZhdWx0QXR0ciIpOworICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50Z2V0YXR0cmlidXRlbnMwMiIsICJkZWZhdWx0VmFsIiwgYXR0clZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZWxlbWVudGdldGF0dHJpYnV0ZW5zMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRnZXRhdHRyaWJ1dGVuczAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVuczAyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5zMDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wN2UxNmQ4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVuczAyLmphdmEKQEAgLTAsMCArMSwxMDggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKKworaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorCitQVVJQT1NFLiAgCisKKworCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgICBUaGUgbWV0aG9kIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMgcmV0dXJucyBhIE5vZGVMaXN0IG9mIGFsbCB0aGUgRWxlbWVudHMgd2l0aCBhIGdpdmVuIGxvY2FsIAorICogICAgICAgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmUgZW5jb3VudGVyZWQgaW4gYSBwcmVvcmRlciB0cmF2ZXJzYWwgCisgKiAgICAgICBvZiB0aGUgRG9jdW1lbnQgdHJlZS4gCisgKiAgICAgICBJbnZva2UgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyBvbiB0aGUgZG9jdW1lbnRFbGVtZW50IHdpdGggdmFsdWVzIGZvciBuYW1lc3BhY2VVUkkgJyonIGFuZCAKKyAqICAgICAgIGxvY2FsTmFtZSAnKicuICBWZXJpZnkgaWYgdGhpcyByZXR1cm5zIGEgbm9kZUxpc3Qgb2YgMCBlbGVtZW50cy4gCisgKiAgICAgCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0RWxCVE5OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQlROTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5zMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5zMDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnQgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBlbGVtZW50TGlzdCA9IGVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKioiLCAiKiIpOworICAgICAgYXNzZXJ0U2l6ZSgiZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwMiIsIDAsIGVsZW1lbnRMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwNC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVuczA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDFhNjllMQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwNC5qYXZhCkBAIC0wLDAgKzEsMTEyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgICAgUmV0dXJucyBhIE5vZGVMaXN0IG9mIGFsbCB0aGUgRWxlbWVudHMgd2l0aCBhIGdpdmVuIGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkgaW4gdGhlIAorICogICAgICAgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmUgZW5jb3VudGVyZWQgaW4gYSBwcmVvcmRlciB0cmF2ZXJzYWwgb2YgdGhlIERvY3VtZW50IHRyZWUuIAorICogICAgICAgQ3JlYXRlIGEgbmV3IGVsZW1lbnQgbm9kZSAoJ3Jvb3QnKSBhbmQgYXBwZW5kIHRocmVlIG5ld2x5IGNyZWF0ZWQgY2hpbGQgbm9kZXMgKGFsbCBoYXZlIAorICogICAgICAgbG9jYWwgbmFtZSAnY2hpbGQnIGFuZCBkZWZpbmVkIGluIGRpZmZlcmVudCBuYW1lc3BhY2VzKS4gCisgKiAgICAgICBUZXN0IDE6IGludm9rZSBnZXRFbGVtZW50c0J5VGFnTmFtZU5TIHRvIHJldHJpZXZlIG9uZSBvZiB0aGUgY2hpbGRyZW4uCisgKiAgICAgICBUZXN0IDI6IGludm9rZSBnZXRFbGVtZW50c0J5VGFnTmFtZU5TIHdpdGggdGhlIHZhbHVlIG9mIG5hbWVzcGFjZSBlcXVhbHMgdG8gJyonLCBhbmQgCisgKiAgICAgICB2ZXJpZnkgdGhhdCB0aGUgbm9kZSBsaXN0IGhhcyBsZW5ndGggb2YgMy4gCisgKiAgICAgCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0RWxCVE5OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQlROTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIEVsZW1lbnQgY2hpbGQxOworICAgICAgRWxlbWVudCBjaGlsZDI7CisgICAgICBFbGVtZW50IGNoaWxkMzsKKyAgICAgIE5vZGUgYXBwZW5kZWRDaGlsZDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00iLCAicm9vdCIpOworICAgICAgY2hpbGQxID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NL0xldmVsMSIsICJkb206Y2hpbGQiKTsKKyAgICAgIGNoaWxkMiA9IGRvYy5jcmVhdGVFbGVtZW50TlMobnVsbE5TLCAiY2hpbGQiKTsKKyAgICAgIGNoaWxkMyA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9MZXZlbDIiLCAiZG9tOmNoaWxkIik7CisgICAgICBhcHBlbmRlZENoaWxkID0gZWxlbWVudC5hcHBlbmRDaGlsZChjaGlsZDEpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGVsZW1lbnQuYXBwZW5kQ2hpbGQoY2hpbGQyKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBlbGVtZW50LmFwcGVuZENoaWxkKGNoaWxkMyk7CisgICAgICBlbGVtZW50TGlzdCA9IGVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyhudWxsTlMsICJjaGlsZCIpOworICAgICAgYXNzZXJ0U2l6ZSgiZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwNF8xIiwgMSwgZWxlbWVudExpc3QpOworICAgICAgZWxlbWVudExpc3QgPSBlbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiY2hpbGQiKTsKKyAgICAgIGFzc2VydFNpemUoImVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5zMDRfMiIsIDMsIGVsZW1lbnRMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwNC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwNS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVuczA1LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDIwNWY1YQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwNS5qYXZhCkBAIC0wLDAgKzEsMTA5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKworUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKKworUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCisKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKwordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKKworUFVSUE9TRS4gIAorCisKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgICAgUmV0dXJucyBhIE5vZGVMaXN0IG9mIGFsbCB0aGUgRWxlbWVudHMgd2l0aCBhIGdpdmVuIGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkgaW4gdGhlIAorICogICAgICAgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmUgZW5jb3VudGVyZWQgaW4gYSBwcmVvcmRlciB0cmF2ZXJzYWwgb2YgdGhlIERvY3VtZW50IHRyZWUuIAorICogICAgICAgSW52b2tlIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMgb24gdGhlIGRvY3VtZW50RWxlbWVudCB3aXRoIHRoZSBmb2xsb3dpbmcgdmFsdWVzOgorICogICAgICAgbmFtZXNwYWNlVVJJOiAnaHR0cDovL3d3dy5hbHRhdmlzdGEuY29tJyAKKyAqICAgICAgIGxvY2FsTmFtZTogJyonLiAgCisgKiAgICAgICBWZXJpZnkgaWYgdGhpcyByZXR1cm5zIGEgbm9kZUxpc3Qgb2YgMSBlbGVtZW50cy4gCisgKiAgICAgCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0RWxCVE5OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQlROTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5zMDUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5zMDUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnQgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBlbGVtZW50TGlzdCA9IGVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5hbHRhdmlzdGEuY29tIiwgIioiKTsKKyAgICAgIGFzc2VydFNpemUoImVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5zMDUiLCAxLCBlbGVtZW50TGlzdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5zMDUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZW5zMDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRoYXNhdHRyaWJ1dGUwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50aGFzYXR0cmlidXRlMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNjdmYjNhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50aGFzYXR0cmlidXRlMDEuamF2YQpAQCAtMCwwICsxLDEwNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKworKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCisKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKworSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAorCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisKK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCisKK1BVUlBPU0UuICAKKworCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICAgIFRoZSBtZXRob2QgaGFzQXR0cmlidXRlIHJldHVybnMgdHJ1ZSB3aGVuIGFuIGF0dHJpYnV0ZSB3aXRoIGEgZ2l2ZW4gbmFtZSBpcyBzcGVjaWZpZWQgCisgKiAgICAgICBvbiB0aGlzIGVsZW1lbnQgb3IgaGFzIGEgZGVmYXVsdCB2YWx1ZSwgZmFsc2Ugb3RoZXJ3aXNlCisgKiAgICAgICBJbnZva2UgdGhlIGhhc0F0dHJpYnV0ZSBtZXRob2QgdG8gY2hlY2sgaWYgdGhlIGRvY3VtZW50RWxlbWVudCBoYXMgYXR0cmlidXRyZXMuCisgKiAgICAgCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZUhhc0F0dHJzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZUhhc0F0dHJzPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50aGFzYXR0cmlidXRlMDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRoYXNhdHRyaWJ1dGUwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3ROYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnQgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBzdGF0ZSA9IGVsZW1lbnQuaGFzQXR0cmlidXRlKCIiKTsKKyAgICAgIGFzc2VydEZhbHNlKCJlbGVtZW50aGFzYXR0cmlidXRlMDEiLCBzdGF0ZSk7Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRoYXNhdHRyaWJ1dGUwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudGhhc2F0dHJpYnV0ZTAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50aGFzYXR0cmlidXRlMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudGhhc2F0dHJpYnV0ZTAyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzYyZTRkZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudGhhc2F0dHJpYnV0ZTAyLmphdmEKQEAgLTAsMCArMSw5NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICAgIFRoZSBtZXRob2QgaGFzQXR0cmlidXRlIHJldHVybnMgdHJ1ZSB3aGVuIGFuIGF0dHJpYnV0ZSB3aXRoIGEgZ2l2ZW4gbmFtZSBpcyBzcGVjaWZpZWQgCisgKiAgICAgICBvbiB0aGlzIGVsZW1lbnQgb3IgaGFzIGEgZGVmYXVsdCB2YWx1ZSwgZmFsc2Ugb3RoZXJ3aXNlCisgKiAgICAgICBJbnZva2UgdGhlIGhhc0F0dHJpYnV0ZSBtZXRob2QgdG8gb24gYW4gZWxlbWVudCB3aXRoIGRlZmF1bHQgYXR0cmlidXRlcyBhbmQgdmVyaWZ5IGlmIGl0CisgKiAgICAgICByZXR1cm5zIHRydWUuCisgKiAgICAgCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZUhhc0F0dHJzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZUhhc0F0dHJzPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50aGFzYXR0cmlidXRlMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRoYXNhdHRyaWJ1dGUwMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy52YWxpZGF0aW5nCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDplbXBsb3llZSIpOworICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wRW1wbG95ZWVOb3ROdWxsIiwgZWxlbWVudCk7CisgICAgICBzdGF0ZSA9IGVsZW1lbnQuaGFzQXR0cmlidXRlKCJkZWZhdWx0QXR0ciIpOworICAgICAgYXNzZXJ0VHJ1ZSgiZWxlbWVudGhhc2F0dHJpYnV0ZTAyIiwgc3RhdGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50aGFzYXR0cmlidXRlMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRoYXNhdHRyaWJ1dGUwMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudGhhc2F0dHJpYnV0ZTAzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRoYXNhdHRyaWJ1dGUwMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg4NzcwMDcKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRoYXNhdHRyaWJ1dGUwMy5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgICBUaGUgbWV0aG9kIGhhc0F0dHJpYnV0ZSByZXR1cm5zIHRydWUgd2hlbiBhbiBhdHRyaWJ1dGUgd2l0aCBhIGdpdmVuIG5hbWUgaXMgc3BlY2lmaWVkIAorICogICAgICAgb24gdGhpcyBlbGVtZW50IG9yIGhhcyBhIGRlZmF1bHQgdmFsdWUsIGZhbHNlIG90aGVyd2lzZS4KKyAqICAgICAgIENyZWF0ZSBhbiBlbGVtZW50IE5vZGUgYW5kIGFuIGF0dHJpYnV0ZSBOb2RlLiAgSW52b2tlIGhhc0F0dHJpYnV0ZSBtZXRob2QKKyAqICAgICAgIHRvIHZlcmlmeSB0aGF0IHRoZXJlIGlzIG5vIGF0dHJpYnV0ZS4gQXBwZW5kIHRoZSBhdHRyaWJ1dGUgbm9kZSB0byB0aGUgZWxlbWVudCBub2RlLgorICogICAgICAgSW52b2tlIHRoZSBoYXNBdHRyaWJ1dGUgbWV0aG9kIG9uIHRoZSBlbGVtZW50IGFuZCB2ZXJpZnkgaWYgaXQgcmV0dXJucyB0cnVlLgorICogICAgIAorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVIYXNBdHRycyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVIYXNBdHRyczwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudGhhc2F0dHJpYnV0ZTAzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50aGFzYXR0cmlidXRlMDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCJhZGRyZXNzIik7CisgICAgICBhdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJkb21lc3RpYyIpOworICAgICAgc3RhdGUgPSBlbGVtZW50Lmhhc0F0dHJpYnV0ZSgiZG9tZXN0aWMiKTsKKyAgICAgIGFzc2VydEZhbHNlKCJlbGVtZW50aGFzYXR0cmlidXRlMDNfRmFsc2UiLCBzdGF0ZSk7CituZXdBdHRyaWJ1dGUgPSBlbGVtZW50LnNldEF0dHJpYnV0ZU5vZGUoYXR0cmlidXRlKTsKKyAgICAgIHN0YXRlID0gZWxlbWVudC5oYXNBdHRyaWJ1dGUoImRvbWVzdGljIik7CisgICAgICBhc3NlcnRUcnVlKCJlbGVtZW50aGFzYXR0cmlidXRlMDNfVHJ1ZSIsIHN0YXRlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZWxlbWVudGhhc2F0dHJpYnV0ZTAzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50aGFzYXR0cmlidXRlMDMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRoYXNhdHRyaWJ1dGUwNC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50aGFzYXR0cmlidXRlMDQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZDY3NTkwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50aGFzYXR0cmlidXRlMDQuamF2YQpAQCAtMCwwICsxLDkyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICAgIFRoZSBtZXRob2QgaGFzQXR0cmlidXRlIHJldHVybnMgdHJ1ZSB3aGVuIGFuIGF0dHJpYnV0ZSB3aXRoIGEgZ2l2ZW4gbmFtZSBpcyBzcGVjaWZpZWQgCisgKiAgICAgICBvbiB0aGlzIGVsZW1lbnQgb3IgaGFzIGEgZGVmYXVsdCB2YWx1ZSwgZmFsc2Ugb3RoZXJ3aXNlLgorICogICAgICAgQ3JlYXRlIGFuIGVsZW1lbnQgTm9kZSBhbmQgYW4gYXR0cmlidXRlIE5vZGUgYW5kIGFkZCB0aGUgYXR0cmlidXRlIG5vZGUgdG8gdGhlIGVsZW1lbnQuCisgKiAgICAgICBJbnZva2UgdGhlIGhhc0F0dHJpYnV0ZSBtZXRob2Qgb24gdGhlIGVsZW1lbnQgYW5kIHZlcmlmeSBpZiB0aGUgbWV0aG9kIHJldHVybnMgdHJ1ZS4KKyAqICAgICAKKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlSGFzQXR0cnMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlSGFzQXR0cnM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRoYXNhdHRyaWJ1dGUwNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudGhhc2F0dHJpYnV0ZTA0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIEF0dHIgbmV3QXR0cmlidXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudCgiYWRkcmVzcyIpOworICAgICAgYXR0cmlidXRlID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZSgiZG9tZXN0aWMiKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9IGVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZShhdHRyaWJ1dGUpOworICAgICAgc3RhdGUgPSBlbGVtZW50Lmhhc0F0dHJpYnV0ZSgiZG9tZXN0aWMiKTsKKyAgICAgIGFzc2VydFRydWUoImVsZW1lbnRoYXNhdHRyaWJ1dGUwNCIsIHN0YXRlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZWxlbWVudGhhc2F0dHJpYnV0ZTA0IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50aGFzYXR0cmlidXRlMDQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRoYXNhdHRyaWJ1dGVuczAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRoYXNhdHRyaWJ1dGVuczAxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWJmYmM1MAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudGhhc2F0dHJpYnV0ZW5zMDEuamF2YQpAQCAtMCwwICsxLDk4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICAgIFRoZSBtZXRob2QgaGFzQXR0cmlidXRlTlMgcmV0dXJucyB0cnVlIHdoZW4gYW4gYXR0cmlidXRlIHdpdGggYSBnaXZlbiBsb2NhbCBuYW1lIAorICogICAgICAgYW5kIG5hbWVzcGFjZSAKKyAqICAgICAgIFVSSSBpcyBzcGVjaWZpZWQgb24gdGhpcyBlbGVtZW50IG9yIGhhcyBhIGRlZmF1bHQgdmFsdWUsIGZhbHNlIG90aGVyd2lzZS4gCisgKiAgICAgICAKKyAqICAgICAgIFJldHJlaXZlIHRoZSBmaXJzdCBlbXBsb3llZSBlbGVtZW50IG5vZGUuICBJbnZva2UgdGhlIGhhc0F0dHJpYnV0ZU5TIG1ldGhvZCB0byBjaGVjayBpZiBpdCAKKyAqICAgICAgIGhhcyB0aGUgeG1sbnMgYXR0cmlidXRlIHRoYXQgYmVsb25ncyB0byB0aGUgbmFtZXNwYWNlIGh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvLgorICogICAgIAorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsSGFzQXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxIYXNBdHRyTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRoYXNhdHRyaWJ1dGVuczAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50aGFzYXR0cmlidXRlbnMwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiZW1wbG95ZWUiKTsKKyAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIHN0YXRlID0gZWxlbWVudC5oYXNBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iLCAieG1sbnMiKTsKKyAgICAgIGFzc2VydFRydWUoImVsZW1lbnRoYXNhdHRyaWJ1dGVuczAxIiwgc3RhdGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50aGFzYXR0cmlidXRlbnMwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudGhhc2F0dHJpYnV0ZW5zMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRoYXNhdHRyaWJ1dGVuczAyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRoYXNhdHRyaWJ1dGVuczAyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTFhMDZjMgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudGhhc2F0dHJpYnV0ZW5zMDIuamF2YQpAQCAtMCwwICsxLDEwMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICAgIFRoZSBtZXRob2QgaGFzQXR0cmlidXRlTlMgcmV0dXJucyB0cnVlIHdoZW4gYW4gYXR0cmlidXRlIHdpdGggYSBnaXZlbiBsb2NhbCAKKyAqICAgICAgIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkgaXMgc3BlY2lmaWVkIG9uIHRoaXMgZWxlbWVudCBvciBoYXMgYSBkZWZhdWx0IHZhbHVlLCAKKyAqICAgICAgIGZhbHNlIG90aGVyd2lzZS4gCisgKiAgICAgICBDcmVhdGUgYSBuZXcgZWxlbWVudCBhbmQgYXR0cmlidXRlIG5vZGUgdGhhdCBiZWxvbmcgdG8gdGhlIHNhbWUgbmFtZXNwYWNlLiAgCisgKiAgICAgICBBZGQgdGhlIGF0dHJpYnV0ZSBub2RlIHRvIHRoZSBlbGVtZW50IG5vZGUuICBDaGVjayBpZiB0aGUgbmV3bHkgY3JlYXRlZCBlbGVtZW50IAorICogICAgICAgbm9kZSBoYXMgYW4gYXR0cmlidXRlIGJ5IGludm9raW5nIHRoZSBoYXNBdHRyaWJ1dGVOUyBtZXRob2Qgd2l0aCBhcHByb3ByaWF0ZSAKKyAqICAgICAgIHZhbHVlcyBmb3IgdGhlIG5hbWVzcGFjZVVSSSBhbmQgbG9jYWxOYW1lIHBhcmFtZXRlcnMuCisgKiAgICAgCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxIYXNBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEhhc0F0dHJOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudGhhc2F0dHJpYnV0ZW5zMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRoYXNhdHRyaWJ1dGVuczAyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIEF0dHIgbmV3QXR0cmlidXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00iLCAiYWRkcmVzcyIpOworICAgICAgYXR0cmlidXRlID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00iLCAiZG9tZXN0aWMiKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9IGVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZShhdHRyaWJ1dGUpOworICAgICAgc3RhdGUgPSBlbGVtZW50Lmhhc0F0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00iLCAiZG9tZXN0aWMiKTsKKyAgICAgIGFzc2VydFRydWUoImhhc0RvbWVzdGljQXR0ciIsIHN0YXRlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZWxlbWVudGhhc2F0dHJpYnV0ZW5zMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRoYXNhdHRyaWJ1dGVuczAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50aGFzYXR0cmlidXRlbnMwMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50aGFzYXR0cmlidXRlbnMwMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxNWJkOTYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRoYXNhdHRyaWJ1dGVuczAzLmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgICBUaGUgbWV0aG9kIGhhc0F0dHJpYnV0ZU5TIHJldHVybnMgdHJ1ZSB3aGVuIGFuIGF0dHJpYnV0ZSB3aXRoIGEgZ2l2ZW4gbG9jYWwgbmFtZSAKKyAqICAgICAgIGFuZCBuYW1lc3BhY2UgVVJJIGlzIHNwZWNpZmllZCBvbiB0aGlzIGVsZW1lbnQgb3IgaGFzIGEgZGVmYXVsdCB2YWx1ZSwgCisgKiAgICAgICBmYWxzZSBvdGhlcndpc2UuIAorICogICAgICAgCisgKiAgICAgICBDcmVhdGUgYSBuZXcgZWxlbWVudCBhbmQgYW4gYXR0cmlidXRlIG5vZGUgdGhhdCBoYXMgYW4gZW1wdHkgbmFtZXNwYWNlLiAgCisgKiAgICAgICBBZGQgdGhlIGF0dHJpYnV0ZSBub2RlIHRvIHRoZSBlbGVtZW50IG5vZGUuICBDaGVjayBpZiB0aGUgbmV3bHkgY3JlYXRlZCBlbGVtZW50IAorICogICAgICAgbm9kZSBoYXMgYW4gYXR0cmlidXRlIGJ5IGludm9raW5nIHRoZSBoYXNBdHRyaWJ1dGVOUyBtZXRob2Qgd2l0aCBhcHByb3ByaWF0ZSAKKyAqICAgICAgIHZhbHVlcyBmb3IgdGhlIG5hbWVzcGFjZVVSSSBhbmQgbG9jYWxOYW1lIHBhcmFtZXRlcnMuCisgKiAgICAgCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxIYXNBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEhhc0F0dHJOUzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50aGFzYXR0cmlidXRlbnMwMyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudGhhc2F0dHJpYnV0ZW5zMDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBTdHJpbmcgbnVsbE5TID0gbnVsbDsKKworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00iLCAiYWRkcmVzcyIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlRWxlbWVudE5vdE51bGwiLCBlbGVtZW50KTsKKyAgICAgIGF0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUyhudWxsTlMsICJkb21lc3RpYyIpOworICAgICAgbmV3QXR0cmlidXRlID0gZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlKGF0dHJpYnV0ZSk7CisgICAgICBzdGF0ZSA9IGVsZW1lbnQuaGFzQXR0cmlidXRlTlMobnVsbE5TLCAiZG9tZXN0aWMiKTsKKyAgICAgIGFzc2VydFRydWUoImVsZW1lbnRoYXNhdHRyaWJ1dGVuczAzIiwgc3RhdGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50aGFzYXR0cmlidXRlbnMwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudGhhc2F0dHJpYnV0ZW5zMDMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVuczAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRyZW1vdmVhdHRyaWJ1dGVuczAxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjZlYzI3YQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5zMDEuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgICBUaGUgbWV0aG9kIHJlbW92ZUF0dHJpYnV0ZU5TIHJlbW92ZXMgYW4gYXR0cmlidXRlIGJ5IGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkuCisgKiAgICAgICBDcmVhdGUgYSBuZXcgZWxlbWVudCBhbmQgYWRkIGEgbmV3IGF0dHJpYnV0ZSBub2RlIHRvIGl0LiAKKyAqICAgICAgIFJlbW92ZSB0aGUgYXR0cmlidXRlIG5vZGUgdXNpbmcgdGhlIHJlbW92ZUF0dHJpYnV0ZU5vZGVOUyBtZXRob2QuICAKKyAqICAgICAgIENoZWNrIGlmIHRoZSBhdHRyaWJ1dGUgd2FzIHJlbW92ZSBieSBpbnZva2luZyB0aGUgaGFzQXR0cmlidXRlTlMKKyAqICAgICAgIG1ldGhvZCBvbiB0aGUgZWxlbWVudCBhbmQgY2hlY2sgaWYgaXQgcmV0dXJucyBmYWxzZS4KKyAqICAgICAKKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFJlbUF0TlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFJlbUF0TlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRyZW1vdmVhdHRyaWJ1dGVuczAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50cmVtb3ZlYXR0cmlidXRlbnMwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NIiwgImVsZW0iKTsKKyAgICAgIGF0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvY3JlYXRlQXR0cmlidXRlTlMiLCAiYXR0ciIpOworICAgICAgbmV3QXR0cmlidXRlID0gZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMoYXR0cmlidXRlKTsKKyAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L2NyZWF0ZUF0dHJpYnV0ZU5TIiwgImF0dHIiKTsKKyAgICAgIHN0YXRlID0gZWxlbWVudC5oYXNBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvY3JlYXRlQXR0cmlidXRlTlMiLCAiYXR0ciIpOworICAgICAgYXNzZXJ0RmFsc2UoImVsZW1lbnRyZW1vdmVhdHRyaWJ1dGVuczAxIiwgc3RhdGUpOworfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50cmVtb3ZlYXR0cmlidXRlbnMwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5zMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZmMyZWU3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDEuamF2YQpAQCAtMCwwICsxLDExNyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgICBUZXN0aW5nIEVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZU5TOiBJZiBhbiBhdHRyaWJ1dGUgd2l0aCB0aGF0IGxvY2FsIG5hbWUgCisgKiAgICAgICBhbmQgdGhhdCBuYW1lc3BhY2UgVVJJIGlzIGFscmVhZHkgcHJlc2VudCBpbiB0aGUgZWxlbWVudCwgaXQgaXMgcmVwbGFjZWQKKyAqICAgICAgIGJ5IHRoZSBuZXcgb25lLgorICogICAgICAgQ3JlYXRlIGEgbmV3IGVsZW1lbnQgYW5kIHR3byBuZXcgYXR0cmlidXRlIG5vZGVzIChpbiB0aGUgc2FtZSBuYW1lc3BhY2UKKyAqICAgICAgIGFuZCBzYW1lIGxvY2FsTmFtZXMpLiAgCisgKiAgICAgICBBZGQgdGhlIHR3byBuZXcgYXR0cmlidXRlIG5vZGVzIHRvIHRoZSBlbGVtZW50IG5vZGUgdXNpbmcgdGhlIAorICogICAgICAgc2V0QXR0cmlidXRlTm9kZU5TIG1ldGhvZC4gIENoZWNrIHRoYXQgb25seSBvbmUgYXR0cmlidXRlIGlzIGFkZGVkLCBjaGVjaworICogICAgICAgdGhlIHZhbHVlIG9mIHRoaXMgYXR0cmlidXRlLgorICogICAgIAorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXROb2RlTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0Tm9kZU5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cmlidXRlMTsKKyAgICAgIEF0dHIgYXR0cmlidXRlMjsKKyAgICAgIEF0dHIgYXR0ck5vZGU7CisgICAgICBTdHJpbmcgYXR0ck5hbWU7CisgICAgICBTdHJpbmcgYXR0ck5TOworICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBpbnQgbGVuZ3RoOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L0xldmVsMiIsICJuZXc6ZWxlbWVudCIpOworICAgICAgYXR0cmlidXRlMSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvYXR0MSIsICJwMTphdHQiKTsKKyAgICAgIGF0dHJpYnV0ZTIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L2F0dDEiLCAicDI6YXR0Iik7CisgICAgICBhdHRyaWJ1dGUyLnNldFZhbHVlKCJ2YWx1ZTIiKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9IGVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZU5TKGF0dHJpYnV0ZTEpOworICAgICAgbmV3QXR0cmlidXRlID0gZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMoYXR0cmlidXRlMik7CisgICAgICBhdHRyTm9kZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlTm9kZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9hdHQxIiwgImF0dCIpOworICAgICAgYXR0ck5hbWUgPSBhdHRyTm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgYXR0ck5TID0gYXR0ck5vZGUuZ2V0TmFtZXNwYWNlVVJJKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMV9hdHRyTmFtZSIsICJwMjphdHQiLCBhdHRyTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMV9hdHRyTlMiLCAiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvYXR0MSIsIGF0dHJOUyk7CisgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBsZW5ndGggPSAoaW50KSBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJsZW5ndGgiLCAxLCBsZW5ndGgpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczAyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1ZWVkNGIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMi5qYXZhCkBAIC0wLDAgKzEsMTEwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgICAgVGVzdCB0aGUgc2V0QXR0cmlidXRlTm9kZU5TIG1ldGhvZC4KKyAqICAgICAgIFJldHJlaXZlIHRoZSBzdHJlZXQgYXR0cmlidXRlIGZyb20gdGhlIHNlY29uZCBhZGRyZXNzIGVsZW1lbnQgbm9kZS4gIAorICogICAgICAgQ2xvbmUgaXQgYW5kIGFkZCBpdCB0byB0aGUgZmlyc3QgYWRkcmVzcyBub2RlLiAgVGhlIElOVVNFX0FUVFJJQlVURV9FUlIgZXhjZXB0aW9uCisgKiAgICAgICBzaG91bGQgbm90IGJlIHRocm93bi4gQ2hlY2sgdGhlIG5hbWUgYW5kIHZhbHVlIG9mIHRoZSBuZXdseSBhZGRlZCBub2RlLgorICogICAgIAorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXROb2RlTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0Tm9kZU5TPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczAyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBFbGVtZW50IGVsZW1lbnQyOworICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICBBdHRyIGF0dHJpYnV0ZUNsb25lZDsKKyAgICAgIEF0dHIgbmV3QXR0cjsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgU3RyaW5nIGF0dHJOYW1lOworICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKyAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAiYWRkcmVzcyIpOworICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgYXR0cmlidXRlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlTlMobnVsbE5TLCAic3RyZWV0Iik7CisgICAgICBhdHRyaWJ1dGVDbG9uZWQgPSAoQXR0cikgYXR0cmlidXRlLmNsb25lTm9kZSh0cnVlKTsKKyAgICAgIGVsZW1lbnQyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICBuZXdBdHRyID0gZWxlbWVudDIuc2V0QXR0cmlidXRlTm9kZU5TKGF0dHJpYnV0ZUNsb25lZCk7CisgICAgICBhdHRyTmFtZSA9IG5ld0F0dHIuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGF0dHJWYWx1ZSA9IG5ld0F0dHIuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMl9hdHRyTmFtZSIsICJzdHJlZXQiLCBhdHRyTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMl9hdHRyVmFsdWUiLCAiWWVzIiwgYXR0clZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczAyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNTFlYzJlCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDMuamF2YQpAQCAtMCwwICsxLDExMyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICAgIFRoZSBtZXRob2Qgc2V0QXR0cmlidXRlTm9kZU5TIGFkZHMgYSBuZXcgYXR0cmlidXRlIGFuZCByYWlzZXMgdGhlIAorICogICAgICAgSU5VU0VfQVRUUklCVVRFX0VSUiBleGNlcHRpb24gaWYgdGhlIG5ld0F0dHIgaXMgYWxyZWFkeSBhbiBhdHRyaWJ1dGUgb2YgCisgKiAgICAgICBhbm90aGVyIEVsZW1lbnQgb2JqZWN0LiAKKyAqICAgICAgIAorICogICAgICAgUmV0cmVpdmUgYW4gYXR0cmlidXRlIG5vZGUgb2YgYW4gZXhpc3RpbmcgZWxlbWVudCBub2RlLiAgQXR0ZW1wdCB0byBhZGQgaXQgdG8gYW4gYW5vdGhlcgorICogICAgICAgZWxlbWVudCBub2RlLiAgQ2hlY2sgaWYgdGhlIElOVVNFX0FUVFJJQlVURV9FUlIgZXhjZXB0aW9uIGlzIHRocm93bi4KKyAqICAgICAKKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0Tm9kZU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdE5vZGVOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczAzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUsCitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDE7CisgICAgICBFbGVtZW50IGVsZW1lbnQyOworICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJhZGRyZXNzIik7CisgICAgICBlbGVtZW50MSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgYXR0cmlidXRlID0gZWxlbWVudDEuZ2V0QXR0cmlidXRlTm9kZU5TKG51bGxOUywgInN0cmVldCIpOworICAgICAgZWxlbWVudDIgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3QXR0cmlidXRlID0gZWxlbWVudDIuc2V0QXR0cmlidXRlTm9kZU5TKGF0dHJpYnV0ZSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVVNFX0FUVFJJQlVURV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgiZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczAzIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczAzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjhiMTQyYgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczA0LmphdmEKQEAgLTAsMCArMSwxMDkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgICAgVGhlIG1ldGhvZCBzZXRBdHRyaWJ1dGVOb2RlTlMgQWRkcyBhIG5ldyBhdHRyaWJ1dGUgYW5kIHJhaXNlcyBhbiBJTlVTRV9BVFRSSUJVVEVfRVJSIAorICogICAgICAgaWYgbmV3QXR0ciBpcyBhbHJlYWR5IGFuIGF0dHJpYnV0ZSBvZiBhbm90aGVyIEVsZW1lbnQgb2JqZWN0LiAKKyAqICAgICAgIAorICogICAgICAgQ3JlYXRlIHR3byBuZXcgZWxlbWVudCBub2RlcyBhbmQgYSBuZXcgYXR0cmlidXRlIG5vZGUuICBBdHRlbXB0IHRvIGFkZCB0aGUgc2FtZSBhdHRyaWJ1dGUKKyAqICAgICAgIG5vZGUgdG8gdGhlIHNhbWUgdHdvIGVsZW1lbnQgbm9kZXMuCisgKiAgICAgICBDaGVjayBpZiBhbiBJTlVTRV9BVFRSSUJVVEVfRVJSIGlzIHRocm93bi4KKyAqICAgICAKKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0Tm9kZU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdE5vZGVOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczA0IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDE7CisgICAgICBFbGVtZW50IGVsZW1lbnQyOworICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudDEgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJlbGVtMSIpOworICAgICAgZWxlbWVudDIgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJlbGVtMiIpOworICAgICAgYXR0cmlidXRlID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJhdHRyIik7CisgICAgICBuZXdBdHRyaWJ1dGUgPSBlbGVtZW50MS5zZXRBdHRyaWJ1dGVOb2RlTlMoYXR0cmlidXRlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3QXR0cmlidXRlID0gZWxlbWVudDIuc2V0QXR0cmlidXRlTm9kZU5TKGF0dHJpYnV0ZSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVVNFX0FUVFJJQlVURV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgiZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczA0Iiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczA0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczA1LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmUxZWJiYQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczA1LmphdmEKQEAgLTAsMCArMSwxMDkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgICBUaGUgbWV0aG9kIHNldEF0dHJpYnV0ZU5vZGVOUyBBZGRzIGEgbmV3IGF0dHJpYnV0ZSBhbmQgcmFpc2VzIAorICogICAgICAgYW4gV1JPTkdfRE9DVU1FTlRfRVJSIGlmIG5ld0F0dHIgd2FzIGNyZWF0ZWQgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudCAKKyAqICAgICAgIHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhlIGVsZW1lbnQuCisgKiAgICAgICBDcmVhdGUgbmV3IGVsZW1lbnQgYW5kIGF0dHJpYnV0ZSBub2RlcyBpbiBkaWZmZXJlbnQgZG9jdW1lbnRzLiAgCisgKiAgICAgICBBdHRlbXB0IHRvIGFkZCB0aGUgYXR0cmlidXRlIG5vZGUgdG8gdGhlIGVsZW1lbnQgbm9kZS4KKyAqICAgICAgIENoZWNrIGlmIGFuIFdST05HX0RPQ1VNRU5UX0VSUiBpcyB0aHJvd24uCisgKiAgICAgCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdE5vZGVOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXROb2RlTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwNSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczA1KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50IGRvY0FsdDsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGRvY0FsdCA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgImVsZW0xIik7CisgICAgICBhdHRyaWJ1dGUgPSBkb2NBbHQuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgImF0dHIiKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3QXR0cmlidXRlID0gZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMoYXR0cmlidXRlKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X1dST05HX0RPQ1VNRU5UX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwNS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczA2LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwNi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU1ZDM2OTEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwNi5qYXZhCkBAIC0wLDAgKzEsMTE0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIHNldEF0dHJpYnV0ZU5vZGVOUyBBZGRzIGEgbmV3IGF0dHJpYnV0ZSBhbmQgcmFpc2VzIGFuIFdST05HX0RPQ1VNRU5UX0VSUiBpZiB0aGlzIG5vZGUgCisgKiAgaXMgcmVhZG9ubHkuCisgKiAgQXR0ZW1wdCB0byBhZGQgYW4gYXR0cmlidXRlIG5vZGUgdG8gYW4gZWxlbWVudCBub2RlIHdoaWNoIGlzIHBhcnQgb2YgdGhlIHJlcGxhY2VtZW50IHRleHQgb2YgCisgKiAgYSByZWFkLW9ubHkgRW50aXR5UmVmZXJlbmNlIG5vZGUuCisgKiAgQ2hlY2sgaWYgYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgaXMgdGhyb3duLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXROb2RlTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0Tm9kZU5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDYgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwNihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RFeHBhbmRFbnRpdHlSZWZlcmVuY2VzCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIEF0dHIgYXR0cmlidXRlMjsKKyAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWY7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmV3QXR0cmlidXRlOworICAgICAgTm9kZSBuZXdDaGlsZDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgImVsZW0xIik7CisgICAgICBhdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgImF0dHIiKTsKKyAgICAgIGVudFJlZiA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDQiKTsKKyAgICAgIG5ld0NoaWxkID0gYXR0cmlidXRlLmFwcGVuZENoaWxkKGVudFJlZik7CisgICAgICBuZXdBdHRyaWJ1dGUgPSBlbGVtZW50LnNldEF0dHJpYnV0ZU5vZGVOUyhhdHRyaWJ1dGUpOworICAgICAgZWxlbWVudExpc3QgPSBlbnRSZWYuZ2V0Q2hpbGROb2RlcygpOworICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXR0cmlidXRlMiA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLCAiYXR0cjIiKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3QXR0cmlidXRlID0gZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMoYXR0cmlidXRlMik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJlbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDYiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczA2IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihlbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDYuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVuczAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVuczAxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjM5NDU0ZAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5zMDEuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgICBUaGUgbWV0aG9kIHNldEF0dHJpYnV0ZU5TIGFkZHMgYSBuZXcgYXR0cmlidXRlLgorICogICAgICAgQ3JlYXRlIGEgbmV3IGVsZW1lbnQgYW5kIGFkZCBhIG5ldyBhdHRyaWJ1dGUgbm9kZSB0byBpdCB1c2luZyB0aGUgc2V0QXR0cmlidXRlTlMgbWV0aG9kLiAKKyAqICAgICAgIENoZWNrIGlmIHRoZSBhdHRyaWJ1dGUgd2FzIGNvcnJlY3RseSBzZXQgYnkgaW52b2tpbmcgdGhlIGdldEF0dHJpYnV0ZU5vZGVOUyBtZXRob2QgCisgKiAgICAgICBhbmQgY2hlY2tpbmcgdGhlIG5vZGVOYW1lIGFuZCBub2RlVmFsdWUgb2YgdGhlIHJldHVybmVkIG5vZGVzLgorICogICAgIAorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdHRyTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRzZXRhdHRyaWJ1dGVuczAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50c2V0YXR0cmlidXRlbnMwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgU3RyaW5nIGF0dHJOYW1lOworICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00iLCAiZG9tOmVsZW0iKTsKKyAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L3NldEF0dHJpYnV0ZU5TIiwgImF0dHIiLCAidmFsdWUiKTsKKyAgICAgIGF0dHJpYnV0ZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlTm9kZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9zZXRBdHRyaWJ1dGVOUyIsICJhdHRyIik7CisgICAgICBhdHRyTmFtZSA9IGF0dHJpYnV0ZS5nZXROb2RlTmFtZSgpOworICAgICAgYXR0clZhbHVlID0gYXR0cmlidXRlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50c2V0YXR0cmlidXRlbnMwMV9hdHRyTmFtZSIsICJhdHRyIiwgYXR0ck5hbWUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50c2V0YXR0cmlidXRlbnMwMV9hdHRyVmFsdWUiLCAidmFsdWUiLCBhdHRyVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbnMwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudHNldGF0dHJpYnV0ZW5zMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVuczAyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVuczAyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDMwZjgxYgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5zMDIuamF2YQpAQCAtMCwwICsxLDEwMyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgICBUaGUgbWV0aG9kIHNldEF0dHJpYnV0ZU5TIGFkZHMgYSBuZXcgYXR0cmlidXRlLgorICogICAgICAgCisgKiAgICAgICBSZXRyaWV2ZSBhbiBleGlzdGluZyBlbGVtZW50IG5vZGUgd2l0aCBhdHRyaWJ1dGVzIGFuZCBhZGQgYSBuZXcgYXR0cmlidXRlIG5vZGUgdG8gaXQgdXNpbmcgCisgKiAgICAgICB0aGUgc2V0QXR0cmlidXRlTlMgbWV0aG9kLiAgIENoZWNrIGlmIHRoZSBhdHRyaWJ1dGUgd2FzIGNvcnJlY3RseSBzZXQgYnkgaW52b2tpbmcgdGhlIAorICogICAgICAgZ2V0QXR0cmlidXRlTm9kZU5TIG1ldGhvZCBhbmQgY2hlY2tpbmcgdGhlIG5vZGVOYW1lIGFuZCBub2RlVmFsdWUgb2YgdGhlIHJldHVybmVkIG5vZGVzLgorICogICAgIAorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdHRyTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRzZXRhdHRyaWJ1dGVuczAyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50c2V0YXR0cmlidXRlbnMwMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBTdHJpbmcgYXR0ck5hbWU7CisgICAgICBTdHJpbmcgYXR0clZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJhZGRyZXNzIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9zZXRBdHRyaWJ1dGVOUyIsICJ0aGlzOnN0cmVldCIsICJTaWx2ZXIgU3RyZWV0Iik7CisgICAgICBhdHRyaWJ1dGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5vZGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3Qvc2V0QXR0cmlidXRlTlMiLCAic3RyZWV0Iik7CisgICAgICBhdHRyTmFtZSA9IGF0dHJpYnV0ZS5nZXROb2RlTmFtZSgpOworICAgICAgYXR0clZhbHVlID0gYXR0cmlidXRlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50c2V0YXR0cmlidXRlbnMwMl9hdHRyTmFtZSIsICJ0aGlzOnN0cmVldCIsIGF0dHJOYW1lKTsKKyAgICAgIGFzc2VydEVxdWFscygiZWxlbWVudHNldGF0dHJpYnV0ZW5zMDJfYXR0clZhbHVlIiwgIlNpbHZlciBTdHJlZXQiLCBhdHRyVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbnMwMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudHNldGF0dHJpYnV0ZW5zMDIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVuczAzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVuczAzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDUxYWMzZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5zMDMuamF2YQpAQCAtMCwwICsxLDEwNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICAgIFRoZSBtZXRob2Qgc2V0QXR0cmlidXRlTlMgYWRkcyBhIG5ldyBhdHRyaWJ1dGUuCisgKiAgICAgICBSZXRyZWl2ZSBhbiBleGlzdGluZyBlbGVtZW50IG5vZGUgd2l0aCBhIGRlZmF1bHQgYXR0cmlidXRlIG5vZGUgYW5kIAorICogICAgICAgYWRkIHR3byBuZXcgYXR0cmlidXRlIG5vZGVzIHRoYXQgaGF2ZSB0aGUgc2FtZSBsb2NhbCBuYW1lIGFzIHRoZSAKKyAqICAgICAgIGRlZmF1bHQgYXR0cmlidXRlIGJ1dCBkaWZmZXJlbnQgbmFtZXNwYWNlVVJJIHRvIGl0IHVzaW5nIHRoZSBzZXRBdHRyaWJ1dGVOUyBtZXRob2QuICAgCisgKiAgICAgICBDaGVjayBpZiB0aGUgYXR0cmlidXRlIHdhcyBjb3JyZWN0bHkgc2V0IGJ5IGludm9raW5nIHRoZSBnZXRBdHRyaWJ1dGVOb2RlTlMgbWV0aG9kCisgKiAgICAgICBhbmQgY2hlY2tpbmcgdGhlIG5vZGVOYW1lIGFuZCBub2RlVmFsdWUgb2YgdGhlIHJldHVybmVkIG5vZGVzLgorICogICAgIAorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdHRyTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRzZXRhdHRyaWJ1dGVuczAzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50c2V0YXR0cmlidXRlbnMwMyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6ZW1wbG95ZWUiKTsKKyAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVtcEVtcGxveWVlTm90TnVsbCIsIGVsZW1lbnQpOworICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvMSIsICJkZWZhdWx0QXR0ciIsICJkZWZhdWx0MSIpOworICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvMiIsICJkZWZhdWx0QXR0ciIsICJkZWZhdWx0MiIpOworICAgICAgYXR0cmlidXRlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0LzEiLCAiZGVmYXVsdEF0dHIiKTsKKyAgICAgIGF0dHJOYW1lID0gYXR0cmlidXRlLmdldE5vZGVOYW1lKCk7CisgICAgICBhdHRyVmFsdWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRzZXRhdHRyaWJ1dGVuczAzX2F0dHJOYW1lIiwgImRlZmF1bHRBdHRyIiwgYXR0ck5hbWUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50c2V0YXR0cmlidXRlbnMwM19hdHRyVmFsdWUiLCAiZGVmYXVsdDEiLCBhdHRyVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbnMwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudHNldGF0dHJpYnV0ZW5zMDMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVuczA0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVuczA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzdiYmRhMAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5zMDQuamF2YQpAQCAtMCwwICsxLDExMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgICBUaGUgbWV0aG9kIHNldEF0dHJpYnV0ZU5TIGFkZHMgYSBuZXcgYXR0cmlidXRlIGFuZCByYWlzZXMgYSBJTlZBTElEX0NIQVJBQ1RFUl9FUlIgaWYgCisgKiAgICAgICB0aGUgc3BlY2lmaWVkIHF1YWxpZmllZCBuYW1lIGNvbnRhaW5zIGFuIGlsbGVnYWwgY2hhcmFjdGVyLgorICogICAgICAgSW52b2tlIHRoZSBzZXRBdHRyaWJ1dGVOUyBtZXRob2Qgb24gdGhpcyBFbGVtZW50IG9iamVjdCB3aXRoIGEgdmFsaWQgdmFsdWUgZm9yIAorICogICAgICAgbmFtZXNwYWNlVVJJLCBhbmQgcXVhbGlmaWVkTmFtZXMgdGhhdCBjb250YWluIGlsbGVnYWwgY2hhcmFjdGVycy4gIENoZWNrIGlmIHRoZSBhbgorICogICAgICAgSU5WQUxJRF9DSEFSQUNURVJfRVJSIHdhcyB0aHJvd24uCisgKiAgICAgCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0dHJOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZWxlbWVudHNldGF0dHJpYnV0ZW5zMDQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGVsZW1lbnRzZXRhdHRyaWJ1dGVuczA0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZTsKKyAgICAgIGphdmEudXRpbC5MaXN0IHF1YWxpZmllZE5hbWVzID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiLyIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCIvLyIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJcXCIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCI7Iik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIiYiKTsKKyAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiKiIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJdXSIpOworICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCI+Iik7CisgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIjwiKTsKKyAgICAgIAorICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvTDIiLCAiZG9tOmVsZW0iKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDU4ID0gMDsgaW5kZXhOMTAwNTggPCBxdWFsaWZpZWROYW1lcy5zaXplKCk7IGluZGV4TjEwMDU4KyspIHsKKyAgICAgICAgICBxdWFsaWZpZWROYW1lID0gKFN0cmluZykgcXVhbGlmaWVkTmFtZXMuZ2V0KGluZGV4TjEwMDU4KTsKKyAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L0wyIiwgcXVhbGlmaWVkTmFtZSwgInRlc3QiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoImVsZW1lbnRzZXRhdHRyaWJ1dGVuczA0Iiwgc3VjY2Vzcyk7CisgICAgICB9CisgIH0KKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5zMDQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGVsZW1lbnRzZXRhdHRyaWJ1dGVuczA0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbnMwNS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbnMwNS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc3ODUyOWIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVuczA1LmphdmEKQEAgLTAsMCArMSw5OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICAgIFRoZSBtZXRob2Qgc2V0QXR0cmlidXRlTlMgYWRkcyBhIG5ldyBhdHRyaWJ1dGUgYW5kIHJhaXNlcyBhIE5BTUVTUEFDRV9FUlIgaWYgdGhlIAorICogICAgICAgcXVhbGlmaWVkTmFtZSBoYXMgYSBwcmVmaXggYW5kIHRoZSBuYW1lc3BhY2VVUkkgaXMgbnVsbC4KKyAqICAgICAgIEludm9rZSB0aGUgc2V0QXR0cmlidXRlTlMgbWV0aG9kIG9uIGEgbmV3IEVsZW1lbnQgb2JqZWN0IHdpdGggbnVsbCBuYW1lc3BhY2VVUkkgYW5kIGEgCisgKiAgICAgICBxdWFsaWZpZWROYW1lIHRoYXQgaGFzIGEgbmFtZXNwYWNlIHByZWZpeC4gIENoZWNrIGlmIHRoZSBOQU1FU1BBQ0VfRVJSIHdhcyB0aHJvd24uCisgKiAgICAgCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0dHJOUzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50c2V0YXR0cmlidXRlbnMwNSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZWxlbWVudHNldGF0dHJpYnV0ZW5zMDUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9MMiIsICJkb206ZWxlbSIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGxOUywgImRvbTpyb290IiwgInRlc3QiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJlbGVtZW50c2V0YXR0cmlidXRlbnMwNSIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbnMwNSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudHNldGF0dHJpYnV0ZW5zMDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVuczA4LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVuczA4LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTNhNGI3NgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5zMDguamF2YQpAQCAtMCwwICsxLDEwOSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgICBUaGUgbWV0aG9kIHNldEF0dHJpYnV0ZU5TIGFkZHMgYSBuZXcgYXR0cmlidXRlIGFuZCByYWlzZXMgYSBOQU1FU1BBQ0VfRVJSIAorICogICAgICAgaWYgdGhlIHF1YWxpZmllZE5hbWUsIG9yIGl0cyBwcmVmaXgsIGlzICJ4bWxucyIgYW5kIHRoZSBuYW1lc3BhY2VVUkkgaXMgCisgKiAgICAgICBkaWZmZXJlbnQgZnJvbSAiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iLgorICogICAgICAgCisgKiAgICAgICBJbnZva2UgdGhlIHNldEF0dHJpYnV0ZU5TIG1ldGhvZCBvbiBhIG5ldyBFbGVtZW50IG9iamVjdCB3aXRoIG5hbWVzcGFjZVVSSSB0aGF0IGlzIAorICogICAgICAgaHR0cDovL3d3dy53My5vcmcvRE9NVGVzdC9sZXZlbDIgYW5kIGEgcXVhbGlmaWVkTmFtZSB0aGF0IGhhcyB0aGUgcHJlZml4IHhtbG5zIGFuZCBvbmNlCisgKiAgICAgICBhZ2FpbiB3aXRoIGEgcXVhbGlmaWVkTmFtZSB0aGF0IGlzIHhtbG5zLiAgCisgKiAgICAgICBDaGVjayBpZiB0aGUgTkFNRVNQQUNFX0VSUiB3YXMgdGhyb3duLgorICogICAgIAorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdHRyTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGVsZW1lbnRzZXRhdHRyaWJ1dGVuczA4IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50c2V0YXR0cmlidXRlbnMwOChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NVGVzdC9sZXZlbDIiLCAiZG9tOmVsZW0iKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NVGVzdC9sZXZlbDIiLCAieG1sbnMiLCAidGVzdCIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoImVsZW1lbnRzZXRhdHRyaWJ1dGVuczA4X0VycjEiLCBzdWNjZXNzKTsKKyAgICAgIH0KKworICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NVGVzdC9sZXZlbDIiLCAieG1sbnM6cm9vdCIsICJ0ZXN0Iik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgiZWxlbWVudHNldGF0dHJpYnV0ZW5zMDhfRXJyMiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9lbGVtZW50c2V0YXR0cmlidXRlbnMwOCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudHNldGF0dHJpYnV0ZW5zMDguY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVuc3VyaW51bGwuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5zdXJpbnVsbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyOWQ5ZjcKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2VsZW1lbnRzZXRhdHRyaWJ1dGVuc3VyaW51bGwuamF2YQpAQCAtMCwwICsxLDExNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKworKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCisKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKworSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAorCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisKK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCisKK1BVUlBPU0UuICAKKworCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lLHZhbHVlKSIgbWV0aG9kIHJhaXNlcyBhIAorICogICAgTkFNRVNQQUNFX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZAorICogICAgcXVhbGlmaWVkTmFtZSBoYXMgYSBwcmVmaXggYW5kIHRoZSBuYW1lc3BhY2VVUkkgaXMgbnVsbC4KKyAqICAgIAorICogICAgQXR0ZW1wdCB0byBhZGQgYSBuZXcgYXR0cmlidXRlIG9uIHRoZSBmaXJzdCBlbXBsb3llZSBub2RlLgorICogICAgQW4gZXhjZXB0aW9uIHNob3VsZCBiZSByYWlzZWQgc2luY2UgdGhlICJxdWFsaWZpZWROYW1lIiBoYXMgYQorICogICAgcHJlZml4IGFuZCB0aGUgbmFtZXNwYWNlVVJJIGlzIG51bGwuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdHRyTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1FbFNldEF0dHJOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05BTUVTUEFDRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRWxTZXRBdHRyTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOQU1FU1BBQ0VfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBlbGVtZW50c2V0YXR0cmlidXRlbnN1cmludWxsIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBlbGVtZW50c2V0YXR0cmlidXRlbnN1cmludWxsKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9IG51bGw7CisKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gImVtcDpxdWFsaWZpZWROYW1lIjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0QWRkcjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgdGVzdEFkZHIgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAoKEVsZW1lbnQpIC8qTm9kZSAqL3Rlc3RBZGRyKS5zZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsICJuZXdWYWx1ZSIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05BTUVTUEFDRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZWxlbWVudHNldGF0dHJpYnV0ZW5zdXJpbnVsbCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZWxlbWVudHNldGF0dHJpYnV0ZW5zdXJpbnVsbC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0QXR0cmlidXRlTlMwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRBdHRyaWJ1dGVOUzAxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmE0YzBlNQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0QXR0cmlidXRlTlMwMS5qYXZhCkBAIC0wLDAgKzEsMTAyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSkiIG1ldGhvZCByZXRyaWV2ZXMgYW4KKyAqICAgIGF0dHJpYnV0ZSB2YWx1ZSBieSBsb2NhbCBuYW1lIGFuZCBOYW1lc3BhY2VVUkkuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBmaXJzdCAiZW1wOmFkZHJlc3MiIGVsZW1lbnQuCisgKiAgICBUaGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhlICJnZXRBdHRyaWJ1dGVOUygpIiBtZXRob2Qgc2hvdWxkIGJlIHRoZSAKKyAqICAgIHZhbHVlICJESVNUUklDVCIgc2luY2UgdGhlIGF0dHJpYnV0ZSBoYXMgYSBkZWZhdWx0IHZhbHVlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsR2V0QXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxHZXRBdHRyTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzOCI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzODwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZ2V0QXR0cmlidXRlTlMwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZ2V0QXR0cmlidXRlTlMwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZSwKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy52YWxpZGF0aW5nCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5pc3QuZ292IjsKKyAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSAiZGlzdHJpY3QiOworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiZW1wOmRpc3RyaWN0IjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcjsKKyAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhdHRyVmFsdWUgPSB0ZXN0QWRkci5nZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJWYWx1ZSIsICJESVNUUklDVCIsIGF0dHJWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2dldEF0dHJpYnV0ZU5TMDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGdldEF0dHJpYnV0ZU5TMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEF0dHJpYnV0ZU5TMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0QXR0cmlidXRlTlMwMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjOGQ3MTgKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEF0dHJpYnV0ZU5TMDIuamF2YQpAQCAtMCwwICsxLDEwMyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpIiBtZXRob2QgcmV0cmlldmVzIGFuCisgKiAgICBhdHRyaWJ1dGUgdmFsdWUgYnkgbG9jYWwgbmFtZSBhbmQgTmFtZXNwYWNlVVJJLgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgImVtcDphZGRyZXNzIiBlbGVtZW50LgorICogICAgQ3JlYXRlIGEgbmV3IGF0dHJpYnV0ZSB3aXRoIHRoZSAiY3JlYXRlQXR0cmlidXRlTlMoKSIgbWV0aG9kLgorICogICAgQWRkIHRoZSBuZXcgYXR0cmlidXRlIHdpdGggdGhlICJzZXRBdHRyaWJ1dGVOUygpIiBtZXRob2QuCisgKiAgICBUaGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhlICJnZXRBdHRyaWJ1dGVOUygpIiBtZXRob2Qgc2hvdWxkIGJlIHRoZSAKKyAqICAgIGVtcHR5IHN0cmluZyBzaW5jZSB0aGUgYXR0cmlidXRlIGRvZXMgbm90IGhhdmUgYSBkZWZhdWx0IHZhbHVlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsR2V0QXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxHZXRBdHRyTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGdldEF0dHJpYnV0ZU5TMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGdldEF0dHJpYnV0ZU5TMDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5uaXN0LmdvdiI7CisgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gImRpc3RyaWN0IjsKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gImVtcDpkaXN0cmljdCI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcjsKKyAgICAgIEF0dHIgZGlzdHJpY3RBdHRyOworICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgbmV3QXR0cmlidXRlID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbXBBZGRyTm90TnVsbCIsIHRlc3RBZGRyKTsKKyAgICAgIGRpc3RyaWN0QXR0ciA9IHRlc3RBZGRyLnNldEF0dHJpYnV0ZU5vZGVOUyhuZXdBdHRyaWJ1dGUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICB0ZXN0QWRkciA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXR0clZhbHVlID0gdGVzdEFkZHIuZ2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0aHJvd19FcXVhbHMiLCAiIiwgYXR0clZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0QXR0cmlidXRlTlMwMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZ2V0QXR0cmlidXRlTlMwMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0QXR0cmlidXRlTlMwMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRBdHRyaWJ1dGVOUzAzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGJiYWViNQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0QXR0cmlidXRlTlMwMy5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKSIgbWV0aG9kIHJldHJpZXZlcyBhbgorICogICAgYXR0cmlidXRlIHZhbHVlIGJ5IGxvY2FsIG5hbWUgYW5kIE5hbWVzcGFjZVVSSS4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGZpcnN0ICJlbXA6YWRkcmVzcyIgZWxlbWVudC4KKyAqICAgIFRoZSB2YWx1ZSByZXR1cm5lZCBieSB0aGUgImdldEF0dHJpYnV0ZU5TKCkiIG1ldGhvZCBmb3IgdGhlIGVtcDpkb21lc3RpYyBhdHRyaWJ1dGUgCisgKiAgICBzaG91bGQgYmUgdGhlIGVtcHR5IHN0cmluZyBzaW5jZSB0aGUgYXR0cmlidXRlIGRvZXMgbm90IGhhdmUgYSBzcGVjaWZpZWQgdmFsdWUKKyAqICAgIGJlY2F1c2UgaXQgd2FzIHJlbW92ZWQgYnkgdGhlICJyZW1vdmVBdHRyaWJ1dGVOUygpIiBtZXRob2QuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxHZXRBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEdldEF0dHJOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZ2V0QXR0cmlidXRlTlMwMyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZ2V0QXR0cmlidXRlTlMwMyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5pc3QuZ292IjsKKyAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSAiZG9tZXN0aWMiOworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IHRlc3RBZGRyOworICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICB0ZXN0QWRkciA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkck5vdE51bGwiLCB0ZXN0QWRkcik7CisgICAgICB0ZXN0QWRkci5yZW1vdmVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7CisgICAgICBhdHRyVmFsdWUgPSB0ZXN0QWRkci5nZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoInRocm93X0VxdWFscyIsICIiLCBhdHRyVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9nZXRBdHRyaWJ1dGVOUzAzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihnZXRBdHRyaWJ1dGVOUzAzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRBdHRyaWJ1dGVOUzA0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEF0dHJpYnV0ZU5TMDQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YzlmYTA2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRBdHRyaWJ1dGVOUzA0LmphdmEKQEAgLTAsMCArMSwxMDEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKSIgbWV0aG9kIHJldHJpZXZlcyBhbgorICogICAgYXR0cmlidXRlIHZhbHVlIGJ5IGxvY2FsIG5hbWUgYW5kIE5hbWVzcGFjZVVSSS4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGZpcnN0ICJlbXA6YWRkcmVzcyIgZWxlbWVudC4KKyAqICAgIENyZWF0ZSBhIG5ldyBhdHRyaWJ1dGUgd2l0aCB0aGUgImNyZWF0ZUF0dHJpYnV0ZU5TKCkiIG1ldGhvZC4KKyAqICAgIEFkZCB0aGUgbmV3IGF0dHJpYnV0ZSBhbmQgdmFsdWUgd2l0aCB0aGUgInNldEF0dHJpYnV0ZU5TKCkiIG1ldGhvZC4KKyAqICAgIFRoZSB2YWx1ZSByZXR1cm5lZCBieSB0aGUgImdldEF0dHJpYnV0ZU5TKCkiIG1ldGhvZCBzaG91bGQgYmUgIAorICogICAgdGhlIHN0cmluZyAiTmV3VmFsdWUiIHNpbmNlIHRoZSBhdHRyaWJ1dGUgaGFkIGEgc3BlY2lmaWVkIHZhbHVlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsR2V0QXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxHZXRBdHRyTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGdldEF0dHJpYnV0ZU5TMDQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGdldEF0dHJpYnV0ZU5TMDQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5uaXN0LmdvdiI7CisgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gImJsYW5rIjsKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gImVtcDpibGFuayI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcjsKKyAgICAgIEF0dHIgZGlzdHJpY3RBdHRyOworICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgbmV3QXR0cmlidXRlID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbXBBZGRyTm90TnVsbCIsIHRlc3RBZGRyKTsKKyAgICAgIHRlc3RBZGRyLnNldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSwgIk5ld1ZhbHVlIik7CisgICAgICBhdHRyVmFsdWUgPSB0ZXN0QWRkci5nZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoInRocm93X0VxdWFscyIsICJOZXdWYWx1ZSIsIGF0dHJWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2dldEF0dHJpYnV0ZU5TMDQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGdldEF0dHJpYnV0ZU5TMDQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEF0dHJpYnV0ZU5TMDUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0QXR0cmlidXRlTlMwNS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU0MjRkNmIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEF0dHJpYnV0ZU5TMDUuamF2YQpAQCAtMCwwICsxLDk5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSkiIG1ldGhvZCByZXRyaWV2ZXMgYW4KKyAqICAgIGF0dHJpYnV0ZSB2YWx1ZSBieSBsb2NhbCBuYW1lIGFuZCBOYW1lc3BhY2VVUkkuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBmaXJzdCBlbXA6YWRkcmVzcyBlbGVtZW50IG5vZGUgCisgKiAgICBhbmQgcmV0cmlldmUgdGhlIGVtcDpkb21lc3RpYyBhdHRyaWJ1dGUuICBUaGUgbWV0aG9kIHJldHVybnMgYW4KKyAqICAgIEF0dHIgdmFsdWUgYXMgYSBzdHJpbmcsIHRoZSAidmFsdWUiIGNhbiBiZSBleGFtaW5lZCB0byBlbnN1cmUgdGhlCisgKiAgICBwcm9wZXIgYXR0cmlidXRlIHZhbHVlIHdhcyByZXRyaWV2ZWQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxHZXRBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEdldEF0dHJOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZ2V0QXR0cmlidXRlTlMwNSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZ2V0QXR0cmlidXRlTlMwNShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcjsKKyAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbXBBZGRyTm90TnVsbCIsIHRlc3RBZGRyKTsKKyAgICAgIGF0dHJWYWx1ZSA9IHRlc3RBZGRyLmdldEF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImRvbWVzdGljIik7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJWYWx1ZSIsICJZZXMiLCBhdHRyVmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9nZXRBdHRyaWJ1dGVOUzA1IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihnZXRBdHRyaWJ1dGVOUzA1LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRBdHRyaWJ1dGVOb2RlTlMwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRBdHRyaWJ1dGVOb2RlTlMwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5YmIwNmMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEF0dHJpYnV0ZU5vZGVOUzAxLmphdmEKQEAgLTAsMCArMSw5NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEF0dHJpYnV0ZU5vZGVOUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKSIgbWV0aG9kIHJldHJpZXZlcyBhbgorICogICAgYXR0cmlidXRlIG5vZGUgYnkgbG9jYWwgbmFtZSBhbmQgTmFtZXNwYWNlVVJJLgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgZW1wOmFkZHJlc3MgZWxlbWVudCBub2RlLiAKKyAqICAgIFRoZSBnZXRBdHRyaWJ1dGVOb2RlTlMgbWV0aG9kIHJldHVybnMgYW4KKyAqICAgIEF0dHIgbm9kZSwgdGhlICJ2YWx1ZSIgY2FuIGJlIGV4YW1pbmVkIHRvIGVuc3VyZSB0aGUKKyAqICAgIHByb3BlciBhdHRyaWJ1dGUgbm9kZSB3YXMgcmV0cmlldmVkLiAgVGhpcyBhdHRyaWJ1dGUKKyAqICAgIHZhbHVlIHNob3VsZCBiZSBudWxsIHNpbmNlIHRoZXJlIGlzIG5vIHN1Y2ggYXR0cmlidXRlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsR2V0QXROb2RlTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEdldEF0Tm9kZU5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBnZXRBdHRyaWJ1dGVOb2RlTlMwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZ2V0QXR0cmlidXRlTm9kZU5TMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cubmlzdC5nb3YiOworICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9ICJpbnZhbGlkbG9jYWxuYW1lIjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcjsKKyAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICB0ZXN0QWRkciA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkck5vdE51bGwiLCB0ZXN0QWRkcik7CisgICAgICBhdHRyaWJ1dGUgPSB0ZXN0QWRkci5nZXRBdHRyaWJ1dGVOb2RlTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgYXNzZXJ0TnVsbCgidGhyb3dfTnVsbCIsIGF0dHJpYnV0ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2dldEF0dHJpYnV0ZU5vZGVOUzAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihnZXRBdHRyaWJ1dGVOb2RlTlMwMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0QXR0cmlidXRlTm9kZU5TMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0QXR0cmlidXRlTm9kZU5TMDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YjIzMjVlCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRBdHRyaWJ1dGVOb2RlTlMwMi5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0QXR0cmlidXRlTm9kZU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpIiBtZXRob2QgcmV0cmlldmVzIGFuCisgKiAgICBhdHRyaWJ1dGUgbm9kZSBieSBsb2NhbCBuYW1lIGFuZCBOYW1lc3BhY2VVUkkuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBmaXJzdCBlbXA6YWRkcmVzcyBlbGVtZW50IG5vZGUuIAorICogICAgVGhlIGdldEF0dHJpYnV0ZU5vZGVOUyBtZXRob2QgcmV0dXJucyBhbgorICogICAgQXR0ciBub2RlLCB0aGUgInZhbHVlIiBjYW4gYmUgZXhhbWluZWQgdG8gZW5zdXJlIHRoZQorICogICAgcHJvcGVyIGF0dHJpYnV0ZSBub2RlIHdhcyByZXRyaWV2ZWQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRjY4RDA5NSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUY2OEQwOTU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGdldEF0dHJpYnV0ZU5vZGVOUzAyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBnZXRBdHRyaWJ1dGVOb2RlTlMwMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcjsKKyAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgU3RyaW5nIGF0dHJOYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICB0ZXN0QWRkciA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkck5vdE51bGwiLCB0ZXN0QWRkcik7CisgICAgICBhdHRyaWJ1dGUgPSB0ZXN0QWRkci5nZXRBdHRyaWJ1dGVOb2RlTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAiZG9tZXN0aWMiKTsKKyAgICAgIGF0dHJOYW1lID0gYXR0cmlidXRlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImF0dHJOYW1lIiwgImVtcDpkb21lc3RpYyIsIGF0dHJOYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0QXR0cmlidXRlTm9kZU5TMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGdldEF0dHJpYnV0ZU5vZGVOUzAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50QnlJZDAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRCeUlkMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZWMxNDBjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50QnlJZDAxLmphdmEKQEAgLTAsMCArMSw5NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEVsZW1lbnRCeUlkKGVsZW1lbnRJZCkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIERvY3VtZW50IHNob3VsZCByZXR1cm4gYW4gZWxlbWVudCB3aG9zZSBJRCBtYXRjaGVzIGVsZW1lbnRJZC4KKyAqICAgIAorICogICAgSW52b2tlIG1ldGhvZCBnZXRFbGVtZW50QnlJZChlbGVtZW50SWQpIG9uIHRoaXMgZG9jdW1lbnQKKyAqICAgIHdpdGggZWxlbWVudElkIGVxdWFscyAiQ0FOQURBIi4gIE1ldGhvZCBzaG91bGQgcmV0dXJuIGFuIGVsZW1lbnQKKyAqICAgIHdob3NlIHRhZyBuYW1lIGlzICJlbXA6YWRkcmVzcyIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtMTA0NjgyODE1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtMTA0NjgyODE1PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0zODMiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0zODM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGdldEVsZW1lbnRCeUlkMDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGdldEVsZW1lbnRCeUlkMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcudmFsaWRhdGluZworICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIFN0cmluZyB0YWduYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudCA9IGRvYy5nZXRFbGVtZW50QnlJZCgiQ0FOQURBIik7CisgICAgICB0YWduYW1lID0gZWxlbWVudC5nZXRUYWdOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInRocm93X0VxdWFscyIsICJlbXA6YWRkcmVzcyIsIHRhZ25hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9nZXRFbGVtZW50QnlJZDAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihnZXRFbGVtZW50QnlJZDAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50QnlJZDAyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRCeUlkMDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNjgzZmFjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50QnlJZDAyLmphdmEKQEAgLTAsMCArMSw4OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgCisgKiAgICBUaGUgImdldEVsZW1lbnRCeUlkKGVsZW1lbnRJZCkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIERvY3VtZW50IHNob3VsZCByZXR1cm4gbnVsbCBpZiBlbGVtZW50SWQgZG9lcyBub3QgaWRlbnRpZnkgYW55CisgKiAgICBlbGVtZW50cyBpbiB0aGlzIGRvY3VtZW50LgorICogICAgCisgKiAgICBJbnZva2UgbWV0aG9kIGdldEVsZW1lbnRCeUlkKGVsZW1lbnRJZCkgb24gdGhpcyBkb2N1bWVudAorICogICAgd2l0aCBlbGVtZW50SWQgZXF1YWxzICJDYW5jdW4iLiBNZXRob2Qgc2hvdWxkIHJldHVybiBudWxsLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQklkIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0RWxCSWQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGdldEVsZW1lbnRCeUlkMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGdldEVsZW1lbnRCeUlkMDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50ID0gZG9jLmdldEVsZW1lbnRCeUlkKCJDYW5jdW4iKTsKKyAgICAgIGFzc2VydE51bGwoInRocm93X051bGwiLCBlbGVtZW50KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudEJ5SWQwMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZ2V0RWxlbWVudEJ5SWQwMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVjNzUxZmMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMwMS5qYXZhCkBAIC0wLDAgKzEsOTAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKSIgbWV0aG9kIGZvciBhIAorICogICAgRG9jdW1lbnQgc2hvdWxkIHJldHVybiBhIG5ldyBOb2RlTGlzdCBvZiBhbGwgRWxlbWVudHMgdGhhdCBoYXZlIGEgbmFtZXNwYWNlCisgKiAgICB3aGVuIGxvY2FsIG5hbWUgaXMgc3BlY2lmaWVkIGFzICcgJy4KKyAqICAgIAorICogICAgSW52b2tlIG1ldGhvZCBnZXRFbGVtZW50c0J5VGFnTmFtZU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpIG9uIHRoaXMgZG9jdW1lbnQKKyAqICAgIHdpdGggbmFtZXNwYWNlVVJJIGFuZCBsb2NhbE5hbWUgYXMgIiAiLgorICogICAgTWV0aG9kIHNob3VsZCByZXR1cm4gYSBuZXcgTm9kZUxpc3Qgb2YgMzcgZWxlbWVudHMuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0RWxCVE5OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQlROTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzAxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICIqIjsKKyAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSAiKiI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBuZXdMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgbmV3TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKKyAgICAgIGFzc2VydFNpemUoInRocm93X1NpemUiLCAzNywgbmV3TGlzdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzAyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzA2ZGUzOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzAyLmphdmEKQEAgLTAsMCArMSwxMDQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKSIgbWV0aG9kIGZvciBhIAorICogICAgRG9jdW1lbnQgc2hvdWxkIHJldHVybiBhIG5ldyBOb2RlTGlzdCBvZiBhbGwgRWxlbWVudHMgd2l0aCBhIGdpdmVuCisgKiAgICBsb2NhbE5hbWUgYW5kIG5hbWVzcGFjZVVSSSBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIGVuY291bnRlcmVkIGluIGEgcHJlb3JkZXIKKyAqICAgIHRyYXZlcnNhbCBvZiB0aGUgZG9jdW1lbnQgdHJlZS4KKyAqICAgIAorICogICAgSW52b2tlIG1ldGhvZCBnZXRFbGVtZW50c0J5VGFnTmFtZU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpIG9uIHRoaXMgZG9jdW1lbnQKKyAqICAgIHdpdGggbmFtZXNwYWNlVVJJIGJlaW5nICIgIiBhbmQgbG9jYWxOYW1lIGlzICJlbXBsb3llZSIuCisgKiAgICBNZXRob2Qgc2hvdWxkIHJldHVybiBhIG5ldyBOb2RlTGlzdCBjb250YWluaW5nIGZpdmUgRWxlbWVudHMuIAorICogICAgUmV0cmlldmUgdGhlIEZPVVJUSCBlbGVtZW50IHdob3NlIG5hbWUgc2hvdWxkIGJlICJlbXA6ZW1wbG95ZWUiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQlROTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXRFbEJUTk5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBnZXRFbGVtZW50c0J5VGFnTmFtZU5TMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMwMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IG5ld0xpc3Q7CisgICAgICBFbGVtZW50IG5ld0VsZW1lbnQ7CisgICAgICBTdHJpbmcgcHJlZml4OworICAgICAgU3RyaW5nIGxuYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgbmV3TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCIqIiwgImVtcGxveWVlIik7CisgICAgICBhc3NlcnRTaXplKCJlbXBsb3llZUNvdW50IiwgNSwgbmV3TGlzdCk7CisgICAgICBuZXdFbGVtZW50ID0gKEVsZW1lbnQpIG5ld0xpc3QuaXRlbSgzKTsKKyAgICAgIHByZWZpeCA9IG5ld0VsZW1lbnQuZ2V0UHJlZml4KCk7CisgICAgICBhc3NlcnRFcXVhbHMoInByZWZpeCIsICJlbXAiLCBwcmVmaXgpOworICAgICAgbG5hbWUgPSBuZXdFbGVtZW50LmdldExvY2FsTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJsbmFtZSIsICJlbXBsb3llZSIsIGxuYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzAyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihnZXRFbGVtZW50c0J5VGFnTmFtZU5TMDIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMwMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZWMwOWU0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDMuamF2YQpAQCAtMCwwICsxLDEyMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRFbGVtZW50c0J5VGFnTmFtZU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpIiBtZXRob2QgcmV0dXJucyBhIE5vZGVMaXN0CisgKiAgICBvZiBhbGwgZGVzY2VuZGFudCBFbGVtZW50cyB3aXRoIGEgZ2l2ZW4gbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSBpbiB0aGUKKyAqICAgIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlIGVuY291bnRlcmVkIGluIGEgcHJlb3JkZXIgdHJhdmVyc2FsIG9mIHRoaXMgRWxlbWVudCB0cmVlLgorICogICAgCisgKiAgICBDcmVhdGUgYSBOb2RlTGlzdCBvZiBhbGwgdGhlIGRlc2NlbmRhbnQgZWxlbWVudHMKKyAqICAgIHVzaW5nIHRoZSAiaHR0cDovL3d3dy5uaXN0LmdvdiIgYXMgdGhlIG5hbWVzcGFjZVVSSSBhbmQgdGhlIHNwZWNpYWwgdmFsdWUgIiAiIGFzIHRoZSAKKyAqICAgIGxvY2FsTmFtZS4KKyAqICAgIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiBhIE5vZGVMaXN0IG9mIGVsZW1lbnRzIHRoYXQgaGF2ZSAiaHR0cDovL3d3dy5uaXN0LmdvdgorICogICAgYXMgYSBuYW1lc3BhY2UgVVJJLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQlROTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXRFbEJUTk5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBnZXRFbGVtZW50c0J5VGFnTmFtZU5TMDMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMwMyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBqYXZhLnV0aWwuTGlzdCByZXN1bHQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuTGlzdCBleHBlY3RlZFJlc3VsdCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcGxveWVlIik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcGxveWVlSWQiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgibmFtZSIpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJwb3NpdGlvbiIpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJzYWxhcnkiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZ2VuZGVyIik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImFkZHJlc3MiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZW1wOmVtcGxveWVlIik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcDplbXBsb3llZUlkIik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcDpwb3NpdGlvbiIpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJlbXA6c2FsYXJ5Iik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcDpnZW5kZXIiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZW1wOmFkZHJlc3MiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiYWRkcmVzcyIpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgIioiKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDc2ID0gMDsgaW5kZXhOMTAwNzYgPCBlbGVtZW50TGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwNzYrKykgeworICAgICAgICAgIGNoaWxkID0gKE5vZGUpIGVsZW1lbnRMaXN0Lml0ZW0oaW5kZXhOMTAwNzYpOworICAgIGNoaWxkTmFtZSA9IGNoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICByZXN1bHQuYWRkKGNoaWxkTmFtZSk7CisgICAgICAgIH0KKyAgICAgIGFzc2VydEVxdWFscygibm9kZU5hbWVzIiwgZXhwZWN0ZWRSZXN1bHQsIHJlc3VsdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzAzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTYwMDQwOAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA0LmphdmEKQEAgLTAsMCArMSwxMTIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKSIgbWV0aG9kIHJldHVybnMgYSBOb2RlTGlzdAorICogICAgb2YgYWxsIGRlc2NlbmRhbnQgRWxlbWVudHMgd2l0aCBhIGdpdmVuIGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkgaW4gdGhlCisgKiAgICBvcmRlciBpbiB3aGljaCB0aGV5IGFyZSBlbmNvdW50ZXJlZCBpbiBhIHByZW9yZGVyIHRyYXZlcnNhbCBvZiB0aGlzIEVsZW1lbnQgdHJlZS4KKyAqICAgIAorICogICAgQ3JlYXRlIGEgTm9kZUxpc3Qgb2YgYWxsIHRoZSBkZXNjZW5kYW50IGVsZW1lbnRzCisgKiAgICB1c2luZyB0aGUgc3BlY2lhbCB2YWx1ZSAiICIgYXMgdGhlIG5hbWVzcGFjZVVSSSBhbmQgImFkZHJlc3MiIGFzIHRoZSAKKyAqICAgIGxvY2FsTmFtZS4KKyAqICAgIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiBhIE5vZGVMaXN0IG9mIEVsZW1lbnRzIHRoYXQgaGF2ZQorICogICAgImFkZHJlc3MiIGFzIHRoZSBsb2NhbCBuYW1lLiAgCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0RWxCVE5OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQlROTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMwNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIGphdmEudXRpbC5MaXN0IHJlc3VsdCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5MaXN0IGV4cGVjdGVkUmVzdWx0ID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiYWRkcmVzcyIpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJhZGRyZXNzIik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImFkZHJlc3MiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZW1wOmFkZHJlc3MiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiYWRkcmVzcyIpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCIqIiwgImFkZHJlc3MiKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDU5ID0gMDsgaW5kZXhOMTAwNTkgPCBlbGVtZW50TGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwNTkrKykgeworICAgICAgICAgIGNoaWxkID0gKE5vZGUpIGVsZW1lbnRMaXN0Lml0ZW0oaW5kZXhOMTAwNTkpOworICAgIGNoaWxkTmFtZSA9IGNoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICByZXN1bHQuYWRkKGNoaWxkTmFtZSk7CisgICAgICAgIH0KKyAgICAgIGFzc2VydEVxdWFscygibm9kZU5hbWVzIiwgZXhwZWN0ZWRSZXN1bHQsIHJlc3VsdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMwNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA1LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTQzZmI3MAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA1LmphdmEKQEAgLTAsMCArMSw5MiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRFbGVtZW50c0J5VGFnTmFtZU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpIiBtZXRob2QgcmV0dXJucyBhIE5vZGVMaXN0CisgKiAgICBvZiBhbGwgZGVzY2VuZGFudCBFbGVtZW50cyB3aXRoIGEgZ2l2ZW4gbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSBpbiB0aGUKKyAqICAgIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlIGVuY291bnRlcmVkIGluIGEgcHJlb3JkZXIgdHJhdmVyc2FsIG9mIHRoaXMgRWxlbWVudCB0cmVlLgorICogICAgCisgKiAgICBDcmVhdGUgYSBOb2RlTGlzdCBvZiBhbGwgdGhlIGRlc2NlbmRhbnQgZWxlbWVudHMKKyAqICAgIHVzaW5nIHRoZSAiaHR0cDovL3d3dy5uaXN0LmdvdiIgYXMgdGhlIG5hbWVzcGFjZVVSSSBhbmQgIm5vbWF0Y2giIGFzIHRoZSAKKyAqICAgIGxvY2FsTmFtZS4KKyAqICAgIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiBhIE5vZGVMaXN0IHdob3NlIGxlbmd0aCBpcworICogICAgIjAiLiAgCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0RWxCVE5OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQlROTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMwNSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA1KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5pc3QuZ292IjsKKyAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSAibm9tYXRjaCI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgYXNzZXJ0U2l6ZSgidGhyb3dfU2l6ZSIsIDAsIGVsZW1lbnRMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA1IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihnZXRFbGVtZW50c0J5VGFnTmFtZU5TMDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMwNi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDYuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMzU1ZjcxCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDYuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEVsZW1lbnRzQnlUYWdOYW1lTlMobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSkiIG1ldGhvZCByZXR1cm5zIGEgTm9kZUxpc3QKKyAqICAgIG9mIGFsbCBkZXNjZW5kYW50IEVsZW1lbnRzIHdpdGggYSBnaXZlbiBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJIGluIHRoZQorICogICAgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmUgZW5jb3VudGVyZWQgaW4gYSBwcmVvcmRlciB0cmF2ZXJzYWwgb2YgdGhpcyBFbGVtZW50IHRyZWUuCisgKiAgICAKKyAqICAgIENyZWF0ZSBhIE5vZGVMaXN0IG9mIGFsbCB0aGUgZGVzY2VuZGFudCBlbGVtZW50cworICogICAgdXNpbmcgdGhlICJodHRwOi8vd3d3Lm5vbWF0Y2guY29tIiBhcyB0aGUgbmFtZXNwYWNlVVJJIGFuZCAiYWRkcmVzcyIgYXMgdGhlIAorICogICAgbG9jYWxOYW1lLgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgTm9kZUxpc3Qgd2hvc2UgbGVuZ3RoIGlzCisgKiAgICAiMCIuICAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXRFbEJUTk5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0RWxCVE5OUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA2IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBnZXRFbGVtZW50c0J5VGFnTmFtZU5TMDYoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubm9tYXRjaC5jb20iLCAiYWRkcmVzcyIpOworICAgICAgYXNzZXJ0U2l6ZSgibWF0Y2hTaXplIiwgMCwgZWxlbWVudExpc3QpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDYiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGdldEVsZW1lbnRzQnlUYWdOYW1lTlMwNi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA3LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMwNy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA2NjNkYTEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMwNy5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKSIgbWV0aG9kIHJldHVybnMgYSBOb2RlTGlzdAorICogICAgb2YgYWxsIGRlc2NlbmRhbnQgRWxlbWVudHMgd2l0aCBhIGdpdmVuIGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkgaW4gdGhlCisgKiAgICBvcmRlciBpbiB3aGljaCB0aGV5IGFyZSBlbmNvdW50ZXJlZCBpbiBhIHByZW9yZGVyIHRyYXZlcnNhbCBvZiB0aGlzIEVsZW1lbnQgdHJlZS4KKyAqICAgIAorICogICAgQ3JlYXRlIGEgTm9kZUxpc3Qgb2YgYWxsIHRoZSBkZXNjZW5kYW50IGVsZW1lbnRzCisgKiAgICB1c2luZyB0aGUgc3RyaW5nICJodHRwOi8vd3d3Lm5pc3QuZ292IiBhcyB0aGUgbmFtZXNwYWNlVVJJIGFuZCAiYWRkcmVzcyIgYXMgdGhlIAorICogICAgbG9jYWxOYW1lLgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgTm9kZUxpc3Qgd2hvc2UgbGVuZ3RoIGlzCisgKiAgICAiMyIuICAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXRFbEJUTk5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0RWxCVE5OUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA3IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBnZXRFbGVtZW50c0J5VGFnTmFtZU5TMDcoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAiYWRkcmVzcyIpOworICAgICAgYXNzZXJ0U2l6ZSgiYWRkcmVzc2VzIiwgMywgZWxlbWVudExpc3QpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDciOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGdldEVsZW1lbnRzQnlUYWdOYW1lTlMwNy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA4LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMwOC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhMzU2YWIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMwOC5qYXZhCkBAIC0wLDAgKzEsODcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIEVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygnKicsJyonKSBzaG91bGQgcmV0dXJuIGFsbCBjaGlsZAorICogICAgIGVsZW1lbnRzLiAgVGhlcmUgaXMgc29tZSBjb250ZW50aW9uIG9uIHdoZXRoZXIgdGhpcyBzaG91bGQgbWF0Y2gKKyAqICAgICB1bnF1YWxpZmllZCBlbGVtZW50cywgdGhpcyB0ZXN0IHJlZmxlY3RzIHRoZSBpbnRlcnByZXRhdGlvbiB0aGF0CisgKiAgICAgJyonIHNob3VsZCBtYXRjaCBlbGVtZW50cyBpbiBhbGwgbmFtZXNwYWNlcyBhbmQgdW5xdWFsaWZpZWQgZWxlbWVudHMuCisgKiAgICAgRGVyaXZlZCBmcm9tIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMwMSB3aGljaCB0ZXN0cyBzaW1pbGFyIGZ1bmN0aW9uYWxpdHkKKyAqICAgICBvbiB0aGUgRG9jdW1lbnQgaW50ZXJmYWNlLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELTE5Mzg5MThEIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtMTkzODkxOEQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMwOCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA4KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBkb2NFbGVtOworICAgICAgTm9kZUxpc3QgbmV3TGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGRvY0VsZW0gPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBuZXdMaXN0ID0gZG9jRWxlbS5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCIqIiwgIioiKTsKKyAgICAgIGFzc2VydFNpemUoImxpc3RTaXplIiwgMzUsIG5ld0xpc3QpOyAvLyAzNiBvbiB0aGUgUkksIHdoaWNoIHN1cHBvcnRzIGVudGl0eSByZWZlcmVuY2VzCisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMwOCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA4LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA5LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMwOS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiNjUyOWMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMwOS5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEVsZW1lbnRzQnlUYWdOYW1lTlMobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIEVsZW1lbnQgc2hvdWxkIHJldHVybiBhIG5ldyBOb2RlTGlzdCBvZiBhbGwgZGVzY2VuZGFudCBFbGVtZW50cyB3aXRoIGEgZ2l2ZW4KKyAqICAgIGxvY2FsTmFtZSBhbmQgbmFtZXNwYWNlVVJJIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgZW5jb3VudGVyZWQgaW4gYSBwcmVvcmRlcgorICogICAgdHJhdmVyc2FsIG9mIHRoZSBkb2N1bWVudCB0cmVlLgorICogICAgCisgKiAgICBJbnZva2UgbWV0aG9kIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSkgb24gdGhlIGRvY3VtZW50CisgKiAgICBlbGVtZW50IHdpdGggbmFtZXNwYWNlVVJJIGJlaW5nICIqIiBhbmQgbG9jYWxOYW1lIGlzICJlbXBsb3llZSIuCisgKiAgICBNZXRob2Qgc2hvdWxkIHJldHVybiBhIG5ldyBOb2RlTGlzdCBjb250YWluaW5nIGZpdmUgRWxlbWVudHMuIAorICogICAgUmV0cmlldmUgdGhlIEZPVVJUSCBlbGVtZW50IHdob3NlIG5hbWUgc2hvdWxkIGJlICJlbXA6ZW1wbG95ZWUiLgorICogICAgRGVyaXZlZCBmcm9tIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMwMiBhbmQgcmVmbGVjdHMgaXRzIGludGVycHJldGF0aW9uCisgKiAgICB0aGF0IG5hbWVzcGFjZT0iKiIgbWF0Y2hlcyBuYW1lc3BhY2UgdW5xdWFsaWZpZWQgdGFnbmFtZXMuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC0xOTM4OTE4RCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELTE5Mzg5MThEPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBnZXRFbGVtZW50c0J5VGFnTmFtZU5TMDkgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMwOShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IG5ld0xpc3Q7CisgICAgICBFbGVtZW50IG5ld0VsZW1lbnQ7CisgICAgICBTdHJpbmcgcHJlZml4OworICAgICAgU3RyaW5nIGxuYW1lOworICAgICAgRWxlbWVudCBkb2NFbGVtOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9jRWxlbSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIG5ld0xpc3QgPSBkb2NFbGVtLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiZW1wbG95ZWUiKTsKKyAgICAgIGFzc2VydFNpemUoImVtcGxveWVlQ291bnQiLCA1LCBuZXdMaXN0KTsKKyAgICAgIG5ld0VsZW1lbnQgPSAoRWxlbWVudCkgbmV3TGlzdC5pdGVtKDMpOworICAgICAgcHJlZml4ID0gbmV3RWxlbWVudC5nZXRQcmVmaXgoKTsKKyAgICAgIGFzc2VydEVxdWFscygicHJlZml4IiwgImVtcCIsIHByZWZpeCk7CisgICAgICBsbmFtZSA9IG5ld0VsZW1lbnQuZ2V0TG9jYWxOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImxuYW1lIiwgImVtcGxveWVlIiwgbG5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMDkiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGdldEVsZW1lbnRzQnlUYWdOYW1lTlMwOS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzEwLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMxMC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ5MWM1MWMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMxMC5qYXZhCkBAIC0wLDAgKzEsMTI0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEVsZW1lbnRzQnlUYWdOYW1lTlMobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSkiIG1ldGhvZCByZXR1cm5zIGEgTm9kZUxpc3QKKyAqICAgIG9mIGFsbCBkZXNjZW5kYW50IEVsZW1lbnRzIHdpdGggYSBnaXZlbiBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJIGluIHRoZQorICogICAgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmUgZW5jb3VudGVyZWQgaW4gYSBwcmVvcmRlciB0cmF2ZXJzYWwgb2YgdGhpcyBFbGVtZW50IHRyZWUuCisgKiAgICAKKyAqICAgIENyZWF0ZSBhIE5vZGVMaXN0IG9mIGFsbCB0aGUgZGVzY2VuZGFudCBlbGVtZW50cyBvZiB0aGUgZG9jdW1lbnQgZWxlbWVudAorICogICAgdXNpbmcgdGhlICJodHRwOi8vd3d3Lm5pc3QuZ292IiBhcyB0aGUgbmFtZXNwYWNlVVJJIGFuZCB0aGUgc3BlY2lhbCB2YWx1ZSAiKiIgYXMgdGhlIAorICogICAgbG9jYWxOYW1lLgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgTm9kZUxpc3Qgb2YgZWxlbWVudHMgdGhhdCBoYXZlICJodHRwOi8vd3d3Lm5pc3QuZ292CisgKiAgICBhcyBhIG5hbWVzcGFjZSBVUkkuCisgKiAgICBEZXJpdmVkIGZyb20gZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzAzCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC0xOTM4OTE4RCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELTE5Mzg5MThEPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBnZXRFbGVtZW50c0J5VGFnTmFtZU5TMTAgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMxMChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZG9jRWxlbTsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBjaGlsZDsKKyAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICBqYXZhLnV0aWwuTGlzdCByZXN1bHQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgCisgICAgICBqYXZhLnV0aWwuTGlzdCBleHBlY3RlZFJlc3VsdCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcGxveWVlIik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcGxveWVlSWQiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgibmFtZSIpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJwb3NpdGlvbiIpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJzYWxhcnkiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZ2VuZGVyIik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImFkZHJlc3MiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZW1wOmVtcGxveWVlIik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcDplbXBsb3llZUlkIik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcDpwb3NpdGlvbiIpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJlbXA6c2FsYXJ5Iik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcDpnZW5kZXIiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZW1wOmFkZHJlc3MiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiYWRkcmVzcyIpOworICAgICAgCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBkb2NFbGVtID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgZWxlbWVudExpc3QgPSBkb2NFbGVtLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAiKiIpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwN0UgPSAwOyBpbmRleE4xMDA3RSA8IGVsZW1lbnRMaXN0LmdldExlbmd0aCgpOyBpbmRleE4xMDA3RSsrKSB7CisgICAgICAgICAgY2hpbGQgPSAoTm9kZSkgZWxlbWVudExpc3QuaXRlbShpbmRleE4xMDA3RSk7CisgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIHJlc3VsdC5hZGQoY2hpbGROYW1lKTsKKyAgICAgICAgfQorICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTmFtZXMiLCBleHBlY3RlZFJlc3VsdCwgcmVzdWx0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzEwIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihnZXRFbGVtZW50c0J5VGFnTmFtZU5TMTAuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMxMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMTEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOTdhY2JjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMTEuamF2YQpAQCAtMCwwICsxLDExNCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRFbGVtZW50c0J5VGFnTmFtZU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpIiBtZXRob2QgcmV0dXJucyBhIE5vZGVMaXN0CisgKiAgICBvZiBhbGwgZGVzY2VuZGFudCBFbGVtZW50cyB3aXRoIGEgZ2l2ZW4gbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSBpbiB0aGUKKyAqICAgIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlIGVuY291bnRlcmVkIGluIGEgcHJlb3JkZXIgdHJhdmVyc2FsIG9mIHRoaXMgRWxlbWVudCB0cmVlLgorICogICAgCisgKiAgICBDcmVhdGUgYSBOb2RlTGlzdCBvZiBhbGwgdGhlIGRlc2NlbmRhbnQgZWxlbWVudHMKKyAqICAgIHVzaW5nIHRoZSBzcGVjaWFsIHZhbHVlICIqIiBhcyB0aGUgbmFtZXNwYWNlVVJJIGFuZCAiYWRkcmVzcyIgYXMgdGhlIAorICogICAgbG9jYWxOYW1lLgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgTm9kZUxpc3Qgb2YgRWxlbWVudHMgdGhhdCBoYXZlCisgKiAgICAiYWRkcmVzcyIgYXMgdGhlIGxvY2FsIG5hbWUuICAKKyAqICAgIFRoaXMgdGVzdCBpcyBkZXJpdmVkIGZyb20gZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzA0CisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtMTkzODkxOEQiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC0xOTM4OTE4RDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzExIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBnZXRFbGVtZW50c0J5VGFnTmFtZU5TMTEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGRvY0VsZW07CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgamF2YS51dGlsLkxpc3QgcmVzdWx0ID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIAorICAgICAgamF2YS51dGlsLkxpc3QgZXhwZWN0ZWRSZXN1bHQgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJhZGRyZXNzIik7CisgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImFkZHJlc3MiKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiYWRkcmVzcyIpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJlbXA6YWRkcmVzcyIpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJhZGRyZXNzIik7CisgICAgICAKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGRvY0VsZW0gPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvY0VsZW0uZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJhZGRyZXNzIik7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA1RSA9IDA7IGluZGV4TjEwMDVFIDwgZWxlbWVudExpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDVFKyspIHsKKyAgICAgICAgICBjaGlsZCA9IChOb2RlKSBlbGVtZW50TGlzdC5pdGVtKGluZGV4TjEwMDVFKTsKKyAgICBjaGlsZE5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgcmVzdWx0LmFkZChjaGlsZE5hbWUpOworICAgICAgICB9CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lcyIsIGV4cGVjdGVkUmVzdWx0LCByZXN1bHQpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMTEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGdldEVsZW1lbnRzQnlUYWdOYW1lTlMxMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzEyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMxMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQxY2I0MzcKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMxMi5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKSIgbWV0aG9kIHJldHVybnMgYSBOb2RlTGlzdAorICogICAgb2YgYWxsIGRlc2NlbmRhbnQgRWxlbWVudHMgd2l0aCBhIGdpdmVuIGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkgaW4gdGhlCisgKiAgICBvcmRlciBpbiB3aGljaCB0aGV5IGFyZSBlbmNvdW50ZXJlZCBpbiBhIHByZW9yZGVyIHRyYXZlcnNhbCBvZiB0aGlzIEVsZW1lbnQgdHJlZS4KKyAqICAgIAorICogICAgQ3JlYXRlIGEgTm9kZUxpc3Qgb2YgYWxsIHRoZSBkZXNjZW5kYW50IGVsZW1lbnRzCisgKiAgICB1c2luZyB0aGUgImh0dHA6Ly93d3cubmlzdC5nb3YiIGFzIHRoZSBuYW1lc3BhY2VVUkkgYW5kICJub21hdGNoIiBhcyB0aGUgCisgKiAgICBsb2NhbE5hbWUuCisgKiAgICBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gYSBOb2RlTGlzdCB3aG9zZSBsZW5ndGggaXMgIjAiLiAgCisgKiAgICBUaGlzIHRlc3QgaXMgYSBtb2RpZmljYXRpb24gb2YgZ2V0RWxlbWVudHNCeVRhZ05hbWUwNQorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELTE5Mzg5MThEIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtMTkzODkxOEQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMxMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzEyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBkb2NFbGVtOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBkb2NFbGVtID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgZWxlbWVudExpc3QgPSBkb2NFbGVtLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAibm9tYXRjaCIpOworICAgICAgYXNzZXJ0U2l6ZSgic2l6ZSIsIDAsIGVsZW1lbnRMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzEyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihnZXRFbGVtZW50c0J5VGFnTmFtZU5TMTIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMxMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMTMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZTJkN2E2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMTMuamF2YQpAQCAtMCwwICsxLDk3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEVsZW1lbnRzQnlUYWdOYW1lTlMobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSkiIG1ldGhvZCByZXR1cm5zIGEgTm9kZUxpc3QKKyAqICAgIG9mIGFsbCBkZXNjZW5kYW50IEVsZW1lbnRzIHdpdGggYSBnaXZlbiBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJIGluIHRoZQorICogICAgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmUgZW5jb3VudGVyZWQgaW4gYSBwcmVvcmRlciB0cmF2ZXJzYWwgb2YgdGhpcyBFbGVtZW50IHRyZWUuCisgKiAgICAKKyAqICAgIENyZWF0ZSBhIE5vZGVMaXN0IG9mIGFsbCB0aGUgZGVzY2VuZGFudCBlbGVtZW50cworICogICAgdXNpbmcgdGhlICJodHRwOi8vd3d3Lm5vbWF0Y2guY29tIiBhcyB0aGUgbmFtZXNwYWNlVVJJIGFuZCAiYWRkcmVzcyIgYXMgdGhlIAorICogICAgbG9jYWxOYW1lLgorICogICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgTm9kZUxpc3Qgd2hvc2UgbGVuZ3RoIGlzCisgKiAgICAiMCIuICAKKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC0xOTM4OTE4RCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELTE5Mzg5MThEPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBnZXRFbGVtZW50c0J5VGFnTmFtZU5TMTMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMxMyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZG9jRWxlbTsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9jRWxlbSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jRWxlbS5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5vbWF0Y2guY29tIiwgImFkZHJlc3MiKTsKKyAgICAgIGFzc2VydFNpemUoIm1hdGNoU2l6ZSIsIDAsIGVsZW1lbnRMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzEzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihnZXRFbGVtZW50c0J5VGFnTmFtZU5TMTMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMxNC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMTQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMzM0ZjI3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXRFbGVtZW50c0J5VGFnTmFtZU5TMTQuamF2YQpAQCAtMCwwICsxLDk3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldEVsZW1lbnRzQnlUYWdOYW1lTlMobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSkiIG1ldGhvZCByZXR1cm5zIGEgTm9kZUxpc3QKKyAqICAgIG9mIGFsbCBkZXNjZW5kYW50IEVsZW1lbnRzIHdpdGggYSBnaXZlbiBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJIGluIHRoZQorICogICAgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmUgZW5jb3VudGVyZWQgaW4gYSBwcmVvcmRlciB0cmF2ZXJzYWwgb2YgdGhpcyBFbGVtZW50IHRyZWUuCisgKiAgICAKKyAqICAgIENyZWF0ZSBhIE5vZGVMaXN0IG9mIGFsbCB0aGUgZGVzY2VuZGFudCBlbGVtZW50cworICogICAgdXNpbmcgdGhlIHN0cmluZyAiaHR0cDovL3d3dy5uaXN0LmdvdiIgYXMgdGhlIG5hbWVzcGFjZVVSSSBhbmQgImFkZHJlc3MiIGFzIHRoZSAKKyAqICAgIGxvY2FsTmFtZS4KKyAqICAgIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiBhIE5vZGVMaXN0IHdob3NlIGxlbmd0aCBpcworICogICAgIjMiLiAgCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtMTkzODkxOEQiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC0xOTM4OTE4RDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzE0IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBnZXRFbGVtZW50c0J5VGFnTmFtZU5TMTQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGRvY0VsZW07CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGRvY0VsZW0gPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvY0VsZW0uZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJhZGRyZXNzIik7CisgICAgICBhc3NlcnRTaXplKCJhZGRyZXNzZXMiLCAzLCBlbGVtZW50TGlzdCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2dldEVsZW1lbnRzQnlUYWdOYW1lTlMxNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZ2V0RWxlbWVudHNCeVRhZ05hbWVOUzE0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXROYW1lZEl0ZW1OUzAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldE5hbWVkSXRlbU5TMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NTlhNTgyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXROYW1lZEl0ZW1OUzAxLmphdmEKQEAgLTAsMCArMSwxMDMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0TmFtZWRJdGVtTlMobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIE5hbWVkTm9kZU1hcCBzaG91bGQgcmV0dXJuIGEgbm9kZSBzcGVjaWZpZWQgYnkgbG9jYWxOYW1lIGFuZCBuYW1lc3BhY2VVUkkgCisgKiAgICAKKyAqICAgIFJldHJpZXZlIGEgbGlzdCBvZiBlbGVtZW50cyB3aXRoIHRhZyBuYW1lICJhZGRyZXNzIi4KKyAqICAgIEFjY2VzcyB0aGUgc2Vjb25kIGVsZW1lbnQgZnJvbSB0aGUgbGlzdCBhbmQgZ2V0IGl0cyBhdHRyaWJ1dGVzLgorICogICAgVHJ5IHRvIHJldHJpZXZlIHRoZSBhdHRyaWJ1dGUgbm9kZSB3aXRoIGxvY2FsIG5hbWUgImRvbWVzdGljIgorICogICAgYW5kIG5hbWVzcGFjZSB1cmkgImh0dHA6Ly93d3cudXNhLmNvbSIgd2l0aAorICogICAgbWV0aG9kIGdldE5hbWVkSXRlbU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1GNjhEMDk1PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBnZXROYW1lZEl0ZW1OUzAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBnZXROYW1lZEl0ZW1OUzAxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RFbXBsb3llZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBkb21lc3RpY0F0dHI7CisgICAgICBTdHJpbmcgYXR0ck5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEVtcGxveWVlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0RW1wbG95ZWUuZ2V0QXR0cmlidXRlcygpOworICAgICAgZG9tZXN0aWNBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtTlMoImh0dHA6Ly93d3cudXNhLmNvbSIsICJkb21lc3RpYyIpOworICAgICAgYXR0ck5hbWUgPSBkb21lc3RpY0F0dHIuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0ck5hbWUiLCAiZG1zdGM6ZG9tZXN0aWMiLCBhdHRyTmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2dldE5hbWVkSXRlbU5TMDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGdldE5hbWVkSXRlbU5TMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldE5hbWVkSXRlbU5TMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0TmFtZWRJdGVtTlMwMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA4N2I5ZTAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldE5hbWVkSXRlbU5TMDIuamF2YQpAQCAtMCwwICsxLDk5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldE5hbWVkSXRlbU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpIiBtZXRob2QgZm9yIGEgCisgKiAgICBOYW1lZE5vZGVNYXAgc2hvdWxkIHJldHVybiBudWxsCisgKiAgICBpZiBwYXJhbWV0ZXJzIGRvIG5vdCBpZGVudGlmeSBhbnkgbm9kZSBpbiB0aGlzIG1hcC4KKyAqICAgIAorICogICAgUmV0cmlldmUgYSBsaXN0IG9mIGVsZW1lbnRzIHdpdGggdGFnIG5hbWUgImFkZHJlc3MiLgorICogICAgQWNjZXNzIHRoZSBzZWNvbmQgZWxlbWVudCBmcm9tIHRoZSBsaXN0IGFuZCBnZXQgaXRzIGF0dHJpYnV0ZXMuCisgKiAgICBUcnkgdG8gcmV0cmlldmUgYW4gYXR0cmlidXRlIG5vZGUgd2l0aCBsb2NhbCBuYW1lICJkb21lc3QiCisgKiAgICBhbmQgbmFtZXNwYWNlIHVyaSAiaHR0cDovL3d3dy51c2EuY29tIiB3aXRoCisgKiAgICBtZXRob2QgZ2V0TmFtZWRJdGVtTlMobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSkuCisgKiAgICBUaGlzIHNob3VsZCByZXR1cm4gbnVsbCBiZWNhdXNlICJkb21lc3QiIGRvZXMgbm90IG1hdGNoIGFueSBsb2NhbCBuYW1lcyBpbiB0aGlzIG1hcC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXROYW1lZEl0ZW1OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldE5hbWVkSXRlbU5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBnZXROYW1lZEl0ZW1OUzAyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBnZXROYW1lZEl0ZW1OUzAyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LnVzYS5jb20iOworICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9ICJkb21lc3QiOworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RFbXBsb3llZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBuZXdBdHRyOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3RFbXBsb3llZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdEVtcGxveWVlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIG5ld0F0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW1OUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7CisgICAgICBhc3NlcnROdWxsKCJ0aHJvd19OdWxsIiwgbmV3QXR0cik7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2dldE5hbWVkSXRlbU5TMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGdldE5hbWVkSXRlbU5TMDIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldE5hbWVkSXRlbU5TMDMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0TmFtZWRJdGVtTlMwMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzNTM1MmYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2dldE5hbWVkSXRlbU5TMDMuamF2YQpAQCAtMCwwICsxLDkxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEVudGl0eSBub2RlcyBhcmUgbm90IG5hbWVzcGFjZWQgYW5kIHNob3VsZCBub3QgYmUgcmV0cmlldmFibGUgdXNpbmcKKyAqIGdldE5hbWVkSXRlbU5TLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0TmFtZWRJdGVtTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXROYW1lZEl0ZW1OUzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBnZXROYW1lZEl0ZW1OUzAzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBnZXROYW1lZEl0ZW1OUzAzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBOYW1lZE5vZGVNYXAgZW50aXRpZXM7CisgICAgICBFbnRpdHkgZW50aXR5OworICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgZW50aXRpZXMgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdGllc05vdE51bGwiLCBlbnRpdGllcyk7CisgICAgICBlbnRpdHkgPSAoRW50aXR5KSBlbnRpdGllcy5nZXROYW1lZEl0ZW1OUyhudWxsTlMsICJlbnQxIik7CisgICAgICBhc3NlcnROdWxsKCJlbnRpdHlOdWxsIiwgZW50aXR5KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0TmFtZWRJdGVtTlMwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZ2V0TmFtZWRJdGVtTlMwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0TmFtZWRJdGVtTlMwNC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9nZXROYW1lZEl0ZW1OUzA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjIyZjk2MwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvZ2V0TmFtZWRJdGVtTlMwNC5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogTm90YXRpb24gbm9kZXMgYXJlIG5vdCBuYW1lc3BhY2VkIGFuZCBzaG91bGQgbm90IGJlIHJldHJpZXZhYmxlIHVzaW5nCisgKiBnZXROYW1lZEl0ZW1OUy4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldE5hbWVkSXRlbU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0TmFtZWRJdGVtTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgZ2V0TmFtZWRJdGVtTlMwNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgZ2V0TmFtZWRJdGVtTlMwNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTmFtZWROb2RlTWFwIG5vdGF0aW9uczsKKyAgICAgIE5vdGF0aW9uIG5vdGF0aW9uOworICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgbm90YXRpb25zID0gZG9jVHlwZS5nZXROb3RhdGlvbnMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoIm5vdGF0aW9uc05vdE51bGwiLCBub3RhdGlvbnMpOworICAgICAgbm90YXRpb24gPSAoTm90YXRpb24pIG5vdGF0aW9ucy5nZXROYW1lZEl0ZW1OUyhudWxsTlMsICJub3RhdGlvbjEiKTsKKyAgICAgIGFzc2VydE51bGwoIm5vdGF0aW9uTnVsbCIsIG5vdGF0aW9uKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvZ2V0TmFtZWRJdGVtTlMwNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oZ2V0TmFtZWRJdGVtTlMwNC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOWUyZDdhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGUwMS5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaGFzQXR0cmlidXRlKCkiIG1ldGhvZCBmb3IgYW4gRWxlbWVudCBzaG91bGQgCisgKiAgICByZXR1cm4gdHJ1ZSBpZiB0aGUgZWxlbWVudCBoYXMgYW4gYXR0cmlidXRlIHdpdGggdGhlIGdpdmVuIG5hbWUuCisgKiAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgImFkZHJlc3MiIGVsZW1lbnQgYW5kIHRoZSAiaGFzQXR0cmlidXRlKCkiIG1ldGhvZAorICogICAgc2hvdWxkIHJldHVybiBmYWxzZSBzaW5jZSB0aGUgZWxlbWVudCBkb2VzIG5vdCBoYXZlIGEgZGVmYXVsdCB2YWx1ZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEhhc0F0dHIiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEhhc0F0dHI8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhhc0F0dHJpYnV0ZTAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoYXNBdHRyaWJ1dGUwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdE5vZGU7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0Tm9kZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDQpOworICAgICAgc3RhdGUgPSB0ZXN0Tm9kZS5oYXNBdHRyaWJ1dGUoImRvbWVzdGljIik7CisgICAgICBhc3NlcnRGYWxzZSgidGhyb3dfRmFsc2UiLCBzdGF0ZSk7Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2hhc0F0dHJpYnV0ZTAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoYXNBdHRyaWJ1dGUwMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlMDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yM2VmODRjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGUwMi5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJoYXNBdHRyaWJ1dGUoKSIgbWV0aG9kIGZvciBhbiBFbGVtZW50IHNob3VsZCAKKyAqICAgIHJldHVybiB0cnVlIGlmIHRoZSBlbGVtZW50IGhhcyBhbiBhdHRyaWJ1dGUgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4KKyAqICAgIFJldHJpZXZlIHRoZSBmaXJzdCAiYWRkcmVzcyIgZWxlbWVudCBhbmQgdGhlICJoYXNBdHRyaWJ1dGUoKSIgbWV0aG9kCisgKiAgICBzaG91bGQgcmV0dXJuIHRydWUgc2luY2UgdGhlIGF0dHJpYnV0ZSAic3RyZWV0IiBoYXMgYSBkZWZhdWx0IHZhbHVlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsSGFzQXR0ciI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsSGFzQXR0cjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjM4Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjM4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoYXNBdHRyaWJ1dGUwMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGFzQXR0cmlidXRlMDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcudmFsaWRhdGluZworICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdE5vZGU7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0Tm9kZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgc3RhdGUgPSB0ZXN0Tm9kZS5oYXNBdHRyaWJ1dGUoInN0cmVldCIpOworICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfVHJ1ZSIsIHN0YXRlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhhc0F0dHJpYnV0ZTAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGUwMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGUwMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFkYzIzZTQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2hhc0F0dHJpYnV0ZTAzLmphdmEKQEAgLTAsMCArMSw4OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJoYXNBdHRyaWJ1dGUoKSIgbWV0aG9kIGZvciBhbiBFbGVtZW50IHNob3VsZCAKKyAqICAgIHJldHVybiBmYWxzZSBpZiB0aGUgZWxlbWVudCBkb2VzIG5vdCBoYXZlIGFuIGF0dHJpYnV0ZSB3aXRoIHRoZSBnaXZlbiBuYW1lLgorICogICAgUmV0cmlldmUgdGhlIGZpcnN0ICJhZGRyZXNzIiBlbGVtZW50IGFuZCB0aGUgImhhc0F0dHJpYnV0ZSgpIiBtZXRob2QKKyAqICAgIHNob3VsZCByZXR1cm4gZmFsc2Ugc2luY2UgdGhlIGVsZW1lbnQgZG9lcyBub3QgaGF2ZSAibm9tYXRjaCIgYXMgYW4gYXR0cmlidXRlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsSGFzQXR0ciI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsSGFzQXR0cjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGFzQXR0cmlidXRlMDMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhhc0F0dHJpYnV0ZTAzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0Tm9kZTsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3ROb2RlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBzdGF0ZSA9IHRlc3ROb2RlLmhhc0F0dHJpYnV0ZSgibm9tYXRjaCIpOworICAgICAgYXNzZXJ0RmFsc2UoInRocm93X0ZhbHNlIiwgc3RhdGUpOworfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGUwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGFzQXR0cmlidXRlMDMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2hhc0F0dHJpYnV0ZTA0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2hhc0F0dHJpYnV0ZTA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOThhOWYyNAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlMDQuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaGFzQXR0cmlidXRlKCkiIG1ldGhvZCBmb3IgYW4gRWxlbWVudCBzaG91bGQgCisgKiAgICByZXR1cm4gdHJ1ZSBpZiB0aGUgZWxlbWVudCBoYXMgYW4gYXR0cmlidXRlIHdpdGggdGhlIGdpdmVuIG5hbWUuCisgKiAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgImFkZHJlc3MiIGVsZW1lbnQgYW5kIHRoZSAiaGFzQXR0cmlidXRlKCkiIG1ldGhvZAorICogICAgc2hvdWxkIHJldHVybiB0cnVlIHNpbmNlIHRoZSBlbGVtZW50IGhhcyAiZG9tZXN0aWMiIGFzIGFuIGF0dHJpYnV0ZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEhhc0F0dHIiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEhhc0F0dHI8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzOCI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzODwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGFzQXR0cmlidXRlMDQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhhc0F0dHJpYnV0ZTA0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLnZhbGlkYXRpbmcKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdE5vZGU7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3ROb2RlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBzdGF0ZSA9IHRlc3ROb2RlLmhhc0F0dHJpYnV0ZSgiZG1zdGM6ZG9tZXN0aWMiKTsKKyAgICAgIGFzc2VydFRydWUoImhhc0RvbWVzdGljQXR0ciIsIHN0YXRlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlMDQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhhc0F0dHJpYnV0ZTA0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGVOUzAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2hhc0F0dHJpYnV0ZU5TMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYTZjNTMyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGVOUzAxLmphdmEKQEAgLTAsMCArMSw5NCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgCisgKiAgICBUaGUgImhhc0F0dHJpYnV0ZU5TKCkiIG1ldGhvZCBmb3IgYW4gRWxlbWVudCBzaG91bGQgCisgKiAgICByZXR1cm4gZmFsc2UgaWYgdGhlIGVsZW1lbnQgZG9lcyBub3QgaGF2ZSBhbiBhdHRyaWJ1dGUgd2l0aCB0aGUgZ2l2ZW4gbG9jYWwgbmFtZQorICogICAgYW5kL29yIGEgbmFtZXNwYWNlIFVSSSBzcGVjaWZpZWQgb24gdGhpcyBlbGVtZW50IG9yIGRvZXMgbm90IGhhdmUgYSBkZWZhdWx0IHZhbHVlLgorICogICAgUmV0cmlldmUgdGhlIGZpcnN0ICJhZGRyZXNzIiBlbGVtZW50IGFuZCB0aGUgImhhc0F0dHJpYnV0ZU5TKCkiIG1ldGhvZAorICogICAgc2hvdWxkIHJldHVybiBmYWxzZSBzaW5jZSB0aGUgZWxlbWVudCBoYXMgIm5vbWF0Y2giIGFzIHRoZSBsb2NhbCBuYW1lCisgKiAgICBhbmQgImh0dHA6Ly93d3cudXNhLmNvbSIgYXMgdGhlIG5hbWVzcGFjZSBVUkkuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxIYXNBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEhhc0F0dHJOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGFzQXR0cmlidXRlTlMwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGFzQXR0cmlidXRlTlMwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSAibm9tYXRjaCI7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cudXNhLmNvbSI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdE5vZGU7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3ROb2RlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBzdGF0ZSA9IHRlc3ROb2RlLmhhc0F0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKKyAgICAgIGFzc2VydEZhbHNlKCJ0aHJvd19GYWxzZSIsIHN0YXRlKTsKK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlTlMwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGFzQXR0cmlidXRlTlMwMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlTlMwMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGVOUzAyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGY3MWU5OQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlTlMwMi5qYXZhCkBAIC0wLDAgKzEsOTMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaGFzQXR0cmlidXRlTlMoKSIgbWV0aG9kIGZvciBhbiBFbGVtZW50IHNob3VsZCAKKyAqICAgIHJldHVybiBmYWxzZSBpZiB0aGUgZWxlbWVudCBkb2VzIG5vdCBoYXZlIGFuIGF0dHJpYnV0ZSB3aXRoIHRoZSBnaXZlbiBsb2NhbCBuYW1lIAorICogICAgYW5kL29yIG5hbWVzcGFjZSBVUkkgc3BlY2lmaWVkIG9uIHRoaXMgZWxlbWVudCBvciBkb2VzIG5vdCBoYXZlIGEgZGVmYXVsdCB2YWx1ZS4KKyAqICAgIFJldHJpZXZlIHRoZSBmaXJzdCAiYWRkcmVzcyIgZWxlbWVudCBhbmQgdGhlICJoYXNBdHRyaWJ1dGVOUygpIiBtZXRob2QKKyAqICAgIHNob3VsZCByZXR1cm4gZmFsc2Ugc2luY2UgdGhlIGVsZW1lbnQgaGFzICJkb21lc3RpYyIgYXMgdGhlIGxvY2FsIG5hbWUKKyAqICAgIGFuZCAiaHR0cDovL3d3dy5ub21hdGNoLmNvbSIgYXMgdGhlIG5hbWVzcGFjZSBVUkkuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxIYXNBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEhhc0F0dHJOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGFzQXR0cmlidXRlTlMwMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGFzQXR0cmlidXRlTlMwMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSAiZG9tZXN0aWMiOworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5vbWF0Y2guY29tIjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0Tm9kZTsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdE5vZGUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIHN0YXRlID0gdGVzdE5vZGUuaGFzQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgYXNzZXJ0RmFsc2UoInRocm93X0ZhbHNlIiwgc3RhdGUpOworfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGVOUzAyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoYXNBdHRyaWJ1dGVOUzAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGVOUzAzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2hhc0F0dHJpYnV0ZU5TMDMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMmY2NzkyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGVOUzAzLmphdmEKQEAgLTAsMCArMSw5NCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImhhc0F0dHJpYnV0ZU5TKCkiIG1ldGhvZCBmb3IgYW4gRWxlbWVudCBzaG91bGQgCisgKiAgICByZXR1cm4gZmFsc2UgaWYgdGhlIGVsZW1lbnQgZG9lcyBub3QgaGF2ZSBhbiBhdHRyaWJ1dGUgd2l0aCB0aGUgZ2l2ZW4gbG9jYWwgbmFtZSAKKyAqICAgIGFuZC9vciBuYW1lc3BhY2UgVVJJIHNwZWNpZmllZCBvbiB0aGlzIGVsZW1lbnQgb3IgZG9lcyBub3QgaGF2ZSBhIGRlZmF1bHQgdmFsdWUuCisgKiAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgImVtcDphZGRyZXNzIiBlbGVtZW50LgorICogICAgVGhlIGJvb2xlYW4gdmFsdWUgcmV0dXJuZWQgYnkgdGhlICJoYXNBdHRyaWJ1dGVOUygpIiBzaG91bGQgYmUgZmFsc2UgCisgKiAgICBzaW5jZSB0aGUgYXR0cmlidXRlIGRvZXMgbm90IGhhdmUgYSBkZWZhdWx0IHZhbHVlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsSGFzQXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxIYXNBdHRyTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhhc0F0dHJpYnV0ZU5TMDMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhhc0F0dHJpYnV0ZU5TMDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gImJsYW5rIjsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5uaXN0LmdvdiI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdE5vZGU7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICB0ZXN0Tm9kZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkck5vdE51bGwiLCB0ZXN0Tm9kZSk7CisgICAgICBzdGF0ZSA9IHRlc3ROb2RlLmhhc0F0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKKyAgICAgIGFzc2VydEZhbHNlKCJ0aHJvd19GYWxzZSIsIHN0YXRlKTsKK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlTlMwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGFzQXR0cmlidXRlTlMwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlTlMwNC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGVOUzA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDhlMjA1MAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlTlMwNC5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaGFzQXR0cmlidXRlTlMoKSIgbWV0aG9kIGZvciBhbiBFbGVtZW50IHNob3VsZCAKKyAqICAgIHJldHVybiB0cnVlIGlmIHRoZSBhdHRyaWJ1dGUgd2l0aCB0aGUgZ2l2ZW4gbG9jYWwgbmFtZSAKKyAqICAgIGFuZCBuYW1lc3BhY2UgVVJJIGhhcyBhIGRlZmF1bHQgdmFsdWUuCisgKiAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgImVtcDphZGRyZXNzIiBlbGVtZW50LgorICogICAgVGhlIGJvb2xlYW4gdmFsdWUgcmV0dXJuZWQgYnkgdGhlICJoYXNBdHRyaWJ1dGVOUygpIiBzaG91bGQgYmUgdHJ1ZSAKKyAqICAgIHNpbmNlIHRoZSBhdHRyaWJ1dGUgaGFzIGEgZGVmYXVsdCB2YWx1ZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEhhc0F0dHJOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsSGFzQXR0ck5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoYXNBdHRyaWJ1dGVOUzA0IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoYXNBdHRyaWJ1dGVOUzA0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlLAorb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLnZhbGlkYXRpbmcKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gImRpc3RyaWN0IjsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5uaXN0LmdvdiI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgdGVzdE5vZGU7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICB0ZXN0Tm9kZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkcmVzc05vdE51bGwiLCB0ZXN0Tm9kZSk7CisgICAgICBzdGF0ZSA9IHRlc3ROb2RlLmhhc0F0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKKyAgICAgIGFzc2VydFRydWUoImhhc0F0dHJpYnV0ZSIsIHN0YXRlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlTlMwNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGFzQXR0cmlidXRlTlMwNC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlTlMwNS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGVOUzA1LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTRkOTllZAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlTlMwNS5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaGFzQXR0cmlidXRlTlMoKSIgbWV0aG9kIGZvciBhbiBFbGVtZW50IHNob3VsZCAKKyAqICAgIHJldHVybiB0cnVlIGlmIHRoZSBlbGVtZW50IGhhcyBhbiBhdHRyaWJ1dGUgd2l0aCB0aGUgZ2l2ZW4gbG9jYWwgbmFtZQorICogICAgYW5kIHRoZSBuYW1lc3BhY2UgVVJJIGlzIHNwZWNpZmllZCBvbiB0aGlzIGVsZW1lbnQgb3IgaGFzIGEgZGVmYXVsdCB2YWx1ZS4KKyAqICAgIFJldHJpZXZlIHRoZSBmaXJzdCAiYWRkcmVzcyIgZWxlbWVudCBhbmQgdGhlICJoYXNBdHRyaWJ1dGVOUygpIiBtZXRob2QKKyAqICAgIHNob3VsZCByZXR1cm4gdHJ1ZSBzaW5jZSB0aGUgZWxlbWVudCBoYXMgImRvbWVzdGljIiBhcyB0aGUgbG9jYWwgbmFtZQorICogICAgYW5kICJodHRwOi8vd3d3LnVzYS5jb20iIGFzIHRoZSBuYW1lc3BhY2UgVVJJLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsSGFzQXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxIYXNBdHRyTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhhc0F0dHJpYnV0ZU5TMDUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhhc0F0dHJpYnV0ZU5TMDUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gImRvbWVzdGljIjsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy51c2EuY29tIjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0Tm9kZTsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdE5vZGUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIHN0YXRlID0gdGVzdE5vZGUuaGFzQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgYXNzZXJ0VHJ1ZSgiaGFzQXR0cmlidXRlIiwgc3RhdGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGVOUzA1IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoYXNBdHRyaWJ1dGVOUzA1LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGVzMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlczAxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDEyZTEzMgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlczAxLmphdmEKQEAgLTAsMCArMSw4OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJoYXNBdHRyaWJ1dGVzKCkiIG1ldGhvZCBmb3IgYSBub2RlIHNob3VsZCAKKyAqICAgICByZXR1cm4gZmFsc2UgaWYgdGhlIG5vZGUgZG9lcyBub3QgaGF2ZSBhbiBhdHRyaWJ1dGUuIAorICogICAgIFJldHJpZXZlIHRoZSBmaXJzdCAibmFtZSIgbm9kZSBhbmQgaW52b2tlIHRoZSAiaGFzQXR0cmlidXRlcygpIiBtZXRob2QuCisgKiAgICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGZhbHNlIHNpbmNlIHRoZSBub2RlIGRvZXMgbm90IGhhdmUgYW4gYXR0cmlidXRlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVIYXNBdHRycyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVIYXNBdHRyczwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGFzQXR0cmlidXRlczAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoYXNBdHRyaWJ1dGVzMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgYWRkckxpc3Q7CisgICAgICBOb2RlIGFkZHJOb2RlOworICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBhZGRyTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgibmFtZSIpOworICAgICAgYWRkck5vZGUgPSBhZGRyTGlzdC5pdGVtKDApOworICAgICAgc3RhdGUgPSBhZGRyTm9kZS5oYXNBdHRyaWJ1dGVzKCk7CisgICAgICBhc3NlcnRGYWxzZSgidGhyb3dfRmFsc2UiLCBzdGF0ZSk7Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2hhc0F0dHJpYnV0ZXMwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGFzQXR0cmlidXRlczAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oYXNBdHRyaWJ1dGVzMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlczAyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODg1NWU1OAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGFzQXR0cmlidXRlczAyLmphdmEKQEAgLTAsMCArMSw4OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJoYXNBdHRyaWJ1dGVzKCkiIG1ldGhvZCBmb3IgYSBub2RlIHNob3VsZCAKKyAqICAgICByZXR1cm4gdHJ1ZSBpZiB0aGUgbm9kZSBoYXMgYXR0cmlidXRlcy4gCisgKiAgICAgUmV0cmlldmUgdGhlIGZpcnN0IGFkZHJlc3Mgbm9kZSBhbmQgdGhlICJoYXNBdHRyaWJ1dGVzKCkiIG1ldGhvZAorICogICAgIHNob3VsZCByZXR1cm4gdHJ1ZSBzaW5jZSB0aGUgbm9kZSBoYXMgImRvbWVzdGljIiBhcyBhbiBhdHRyaWJ1dGUuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZUhhc0F0dHJzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZUhhc0F0dHJzPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoYXNBdHRyaWJ1dGVzMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhhc0F0dHJpYnV0ZXMwMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBhZGRyTGlzdDsKKyAgICAgIE5vZGUgYWRkck5vZGU7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGFkZHJMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICBhZGRyTm9kZSA9IGFkZHJMaXN0Lml0ZW0oMCk7CisgICAgICBzdGF0ZSA9IGFkZHJOb2RlLmhhc0F0dHJpYnV0ZXMoKTsKKyAgICAgIGFzc2VydFRydWUoInRocm93X1RydWUiLCBzdGF0ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2hhc0F0dHJpYnV0ZXMwMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGFzQXR0cmlidXRlczAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oY19lbnRpdGllc3JlbW92ZW5hbWVkaXRlbW5zMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oY19lbnRpdGllc3JlbW92ZW5hbWVkaXRlbW5zMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM1NzY5OGYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2hjX2VudGl0aWVzcmVtb3ZlbmFtZWRpdGVtbnMxLmphdmEKQEAgLTAsMCArMSwxMDQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQW4gYXR0ZW1wdCB0byBhZGQgcmVtb3ZlIGFuIGVudGl0eSB1c2luZyByZW1vdmVOYW1lZEl0ZW1OUyBzaG91bGQgcmVzdWx0IGluIAorICogYSBOT19NT0RJRklDQVRJT05fRVJSIG9yIGEgTk9UX0ZPVU5EX0VSUi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC0xNzg4Nzk0NjMwIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtMTc4ODc5NDYzMDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtcmVtb3ZlTmFtZWRJdGVtTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1yZW1vdmVOYW1lZEl0ZW1OUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfZW50aXRpZXNyZW1vdmVuYW1lZGl0ZW1uczEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX2VudGl0aWVzcmVtb3ZlbmFtZWRpdGVtbnMxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTmFtZWROb2RlTWFwIGVudGl0aWVzOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBOb2RlIHJldHZhbDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgCisgICAgICBpZiAoCisgICAgISgoInRleHQvaHRtbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkKKykgeworICAgICAgICAgIGFzc2VydE5vdE51bGwoImRvY1R5cGVOb3ROdWxsIiwgZG9jVHlwZSk7CisgICAgICBlbnRpdGllcyA9IGRvY1R5cGUuZ2V0RW50aXRpZXMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudGl0aWVzTm90TnVsbCIsIGVudGl0aWVzKTsKKyAgICAgIAorICAgICAgdHJ5IHsKKyAgICAgIHJldHZhbCA9IGVudGl0aWVzLnJlbW92ZU5hbWVkSXRlbU5TKCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiwgImFscGhhIik7CisgICAgICBmYWlsKCJ0aHJvd19OT19NT0RfT1JfTk9UX0ZPVU5EX0VSUiIpOworICAgICAKKyAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICBzd2l0Y2ggKGV4LmNvZGUpIHsKKyAgICAgIGNhc2UgNyA6IAorICAgICAgIGJyZWFrOworICAgICAgY2FzZSA4IDogCisgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICB0aHJvdyBleDsKKyAgICAgICAgICB9CisgICAgICB9IAorfQorICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaGNfZW50aXRpZXNyZW1vdmVuYW1lZGl0ZW1uczEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX2VudGl0aWVzcmVtb3ZlbmFtZWRpdGVtbnMxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oY19lbnRpdGllc3NldG5hbWVkaXRlbW5zMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oY19lbnRpdGllc3NldG5hbWVkaXRlbW5zMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ3ZjZmZDUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2hjX2VudGl0aWVzc2V0bmFtZWRpdGVtbnMxLmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCitSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogQW4gYXR0ZW1wdCB0byBhZGQgYW4gZWxlbWVudCB0byB0aGUgbmFtZWQgbm9kZSBtYXAgcmV0dXJuZWQgYnkgZW50aXRpZXMgc2hvdWxkIAorICogcmVzdWx0IGluIGEgTk9fTU9ESUZJQ0FUSU9OX0VSUiBvciBISUVSQVJDSFlfUkVRVUVTVF9FUlIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtMTc4ODc5NDYzMCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELTE3ODg3OTQ2MzA8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXNldE5hbWVkSXRlbU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtc2V0TmFtZWRJdGVtTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX2VudGl0aWVzc2V0bmFtZWRpdGVtbnMxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19lbnRpdGllc3NldG5hbWVkaXRlbW5zMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdGllczsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTm9kZSByZXR2YWw7CisgICAgICBFbGVtZW50IGVsZW07CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKAorICAgICEoKCJ0ZXh0L2h0bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpCispIHsKKyAgICAgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgZW50aXRpZXMgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdGllc05vdE51bGwiLCBlbnRpdGllcyk7CisgICAgICBlbGVtID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIsICJiciIpOworICAgICAgCisgICAgICB0cnkgeworICAgICAgcmV0dmFsID0gZW50aXRpZXMuc2V0TmFtZWRJdGVtTlMoZWxlbSk7CisgICAgICBmYWlsKCJ0aHJvd19ISUVSX09SX05PX01PRF9FUlIiKTsKKyAgICAgCisgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgc3dpdGNoIChleC5jb2RlKSB7CisgICAgICBjYXNlIDMgOiAKKyAgICAgICBicmVhazsKKyAgICAgIGNhc2UgNyA6IAorICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgdGhyb3cgZXg7CisgICAgICAgICAgfQorICAgICAgfSAKK30KKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2hjX2VudGl0aWVzc2V0bmFtZWRpdGVtbnMxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19lbnRpdGllc3NldG5hbWVkaXRlbW5zMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGNfbmFtZWRub2RlbWFwaW52YWxpZHR5cGUxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2hjX25hbWVkbm9kZW1hcGludmFsaWR0eXBlMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY5ZWUxYzUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2hjX25hbWVkbm9kZW1hcGludmFsaWR0eXBlMS5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBdHRlbXB0IHRvIGluc2VydCBhbiBlbGVtZW50IGludG8gYW4gYXR0cmlidXRlIGxpc3QsCisgKiBzaG91bGQgcmFpc2UgYSBISUVSQVJDSFlfUkVRVUVTVF9FUlIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSElFUkFSQ0hZX1JFUVVFU1RfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMS9sZXZlbC1vbmUtY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSElFUkFSQ0hZX1JFUVVFU1RfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwMjUxNjM3ODgiPmh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxL2xldmVsLW9uZS1jb3JlI0lELTEwMjUxNjM3ODg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8xMS9ET00tTGV2ZWwtMi1lcnJhdGEjY29yZS00Ij5odHRwOi8vd3d3LnczLm9yZy8yMDAwLzExL0RPTS1MZXZlbC0yLWVycmF0YSNjb3JlLTQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGhjX25hbWVkbm9kZW1hcGludmFsaWR0eXBlMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaGNfbmFtZWRub2RlbWFwaW52YWxpZHR5cGUxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJoY19zdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBFbGVtZW50IGRvY0VsZW07CisgICAgICBFbGVtZW50IG5ld0VsZW07CisgICAgICBOb2RlIHJldHZhbDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGRvY0VsZW0gPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBhdHRyaWJ1dGVzID0gZG9jRWxlbS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBuZXdFbGVtID0gZG9jLmNyZWF0ZUVsZW1lbnQoImh0bWwiKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dmFsID0gYXR0cmlidXRlcy5zZXROYW1lZEl0ZW0obmV3RWxlbSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19ISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaGNfbmFtZWRub2RlbWFwaW52YWxpZHR5cGUxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19uYW1lZG5vZGVtYXBpbnZhbGlkdHlwZTEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2hjX25vZGVkb2N1bWVudGZyYWdtZW50bm9ybWFsaXplMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vcm1hbGl6ZTEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMDY1YTY2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vcm1hbGl6ZTEuamF2YQpAQCAtMCwwICsxLDkyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIENyZWF0ZSBhIGRvY3VtZW50IGZyYWdtZW50IHdpdGggdHdvIGFkamFjZW50IHRleHQgbm9kZXMsIG5vcm1hbGl6ZSBhbmQgc2VlIGlmIHRoZSB0ZXh0IG5vZGVzCisgKiB3ZXJlIGNvbWJpbmVkLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1GNjhEMDk1PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1CNjNFRDFBMyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUI2M0VEMUEzPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vcm1hbGl6ZTEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVkb2N1bWVudGZyYWdtZW50bm9ybWFsaXplMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50RnJhZ21lbnQgZG9jRnJhZ21lbnQ7CisgICAgICBTdHJpbmcgbm9kZVZhbHVlOworICAgICAgVGV4dCB0eHROb2RlOworICAgICAgTm9kZSByZXR2YWw7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBkb2NGcmFnbWVudCA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CisgICAgICB0eHROb2RlID0gZG9jLmNyZWF0ZVRleHROb2RlKCJmb28iKTsKKyAgICAgIHJldHZhbCA9IGRvY0ZyYWdtZW50LmFwcGVuZENoaWxkKHR4dE5vZGUpOworICAgICAgdHh0Tm9kZSA9IGRvYy5jcmVhdGVUZXh0Tm9kZSgiYmFyIik7CisgICAgICByZXR2YWwgPSBkb2NGcmFnbWVudC5hcHBlbmRDaGlsZCh0eHROb2RlKTsKKyAgICAgIGRvY0ZyYWdtZW50Lm5vcm1hbGl6ZSgpOworICAgICAgdHh0Tm9kZSA9IChUZXh0KSBkb2NGcmFnbWVudC5nZXRGaXJzdENoaWxkKCk7CisgICAgICBub2RlVmFsdWUgPSB0eHROb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub3JtYWxpemVkTm9kZVZhbHVlIiwgImZvb2JhciIsIG5vZGVWYWx1ZSk7CisgICAgICByZXR2YWwgPSB0eHROb2RlLmdldE5leHRTaWJsaW5nKCk7CisgICAgICBhc3NlcnROdWxsKCJzaW5nbGVDaGlsZCIsIHJldHZhbCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2hjX25vZGVkb2N1bWVudGZyYWdtZW50bm9ybWFsaXplMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm9kZWRvY3VtZW50ZnJhZ21lbnRub3JtYWxpemUxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vcm1hbGl6ZTIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGNfbm9kZWRvY3VtZW50ZnJhZ21lbnRub3JtYWxpemUyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmQ4ZTk3NgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGNfbm9kZWRvY3VtZW50ZnJhZ21lbnRub3JtYWxpemUyLmphdmEKQEAgLTAsMCArMSw4NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBDcmVhdGUgYSBkb2N1bWVudCBmcmFnbWVudCB3aXRoIGFuIGVtcHR5IHRleHQgbm9kZSwgYWZ0ZXIgbm9ybWFsaXphdGlvbiB0aGVyZSBzaG91bGQgYmUgbm8gY2hpbGQgbm9kZXMuCisgKiB3ZXJlIGNvbWJpbmVkLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1GNjhEMDk1PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1CNjNFRDFBMyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUI2M0VEMUEzPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vcm1hbGl6ZTIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vZGVkb2N1bWVudGZyYWdtZW50bm9ybWFsaXplMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50RnJhZ21lbnQgZG9jRnJhZ21lbnQ7CisgICAgICBTdHJpbmcgbm9kZVZhbHVlOworICAgICAgVGV4dCB0eHROb2RlOworICAgICAgTm9kZSByZXR2YWw7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBkb2NGcmFnbWVudCA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CisgICAgICB0eHROb2RlID0gZG9jLmNyZWF0ZVRleHROb2RlKCIiKTsKKyAgICAgIHJldHZhbCA9IGRvY0ZyYWdtZW50LmFwcGVuZENoaWxkKHR4dE5vZGUpOworICAgICAgZG9jRnJhZ21lbnQubm9ybWFsaXplKCk7CisgICAgICB0eHROb2RlID0gKFRleHQpIGRvY0ZyYWdtZW50LmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGFzc2VydE51bGwoIm5vQ2hpbGQiLCB0eHROb2RlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaGNfbm9kZWRvY3VtZW50ZnJhZ21lbnRub3JtYWxpemUyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihoY19ub2RlZG9jdW1lbnRmcmFnbWVudG5vcm1hbGl6ZTIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2hjX25vdGF0aW9uc3JlbW92ZW5hbWVkaXRlbW5zMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oY19ub3RhdGlvbnNyZW1vdmVuYW1lZGl0ZW1uczEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MjRkY2M1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9oY19ub3RhdGlvbnNyZW1vdmVuYW1lZGl0ZW1uczEuamF2YQpAQCAtMCwwICsxLDEwNCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKK0NvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiBBbiBhdHRlbXB0IHRvIGFkZCByZW1vdmUgYW4gbm90YXRpb24gdXNpbmcgcmVtb3ZlTmFtZWRJdGVtTlMgc2hvdWxkIHJlc3VsdCBpbiAKKyAqIGEgTk9fTU9ESUZJQ0FUSU9OX0VSUiBvciBhIE5PVF9GT1VORF9FUlIuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRDQ2ODI5RUYiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1ENDY4MjlFRjwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtcmVtb3ZlTmFtZWRJdGVtTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1yZW1vdmVOYW1lZEl0ZW1OUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaGNfbm90YXRpb25zcmVtb3ZlbmFtZWRpdGVtbnMxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBoY19ub3RhdGlvbnNyZW1vdmVuYW1lZGl0ZW1uczEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOYW1lZE5vZGVNYXAgbm90YXRpb25zOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBOb2RlIHJldHZhbDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgCisgICAgICBpZiAoCisgICAgISgoInRleHQvaHRtbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkKKykgeworICAgICAgICAgIGFzc2VydE5vdE51bGwoImRvY1R5cGVOb3ROdWxsIiwgZG9jVHlwZSk7CisgICAgICBub3RhdGlvbnMgPSBkb2NUeXBlLmdldE5vdGF0aW9ucygpOworICAgICAgYXNzZXJ0Tm90TnVsbCgibm90YXRpb25zTm90TnVsbCIsIG5vdGF0aW9ucyk7CisgICAgICAKKyAgICAgIHRyeSB7CisgICAgICByZXR2YWwgPSBub3RhdGlvbnMucmVtb3ZlTmFtZWRJdGVtTlMoImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiLCAiYWxwaGEiKTsKKyAgICAgIGZhaWwoInRocm93X05PX01PRF9PUl9OT1RfRk9VTkRfRVJSIik7CisgICAgIAorICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgIHN3aXRjaCAoZXguY29kZSkgeworICAgICAgY2FzZSA3IDogCisgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDggOiAKKyAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIHRocm93IGV4OworICAgICAgICAgIH0KKyAgICAgIH0gCit9CisgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9oY19ub3RhdGlvbnNyZW1vdmVuYW1lZGl0ZW1uczEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGhjX25vdGF0aW9uc3JlbW92ZW5hbWVkaXRlbW5zMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaGNfbm90YXRpb25zc2V0bmFtZWRpdGVtbnMxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2hjX25vdGF0aW9uc3NldG5hbWVkaXRlbW5zMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY1YTEzZjYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2hjX25vdGF0aW9uc3NldG5hbWVkaXRlbW5zMS5qYXZhCkBAIC0wLDAgKzEsMTA2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEFuIGF0dGVtcHQgdG8gYWRkIGFuIGVsZW1lbnQgdG8gdGhlIG5hbWVkIG5vZGUgbWFwIHJldHVybmVkIGJ5IG5vdGF0aW9ucyBzaG91bGQgCisgKiByZXN1bHQgaW4gYSBOT19NT0RJRklDQVRJT05fRVJSIG9yIEhJRVJBUkNIWV9SRVFVRVNUX0VSUi4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1ENDY4MjlFRiI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUQ0NjgyOUVGPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1zZXROYW1lZEl0ZW1OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXNldE5hbWVkSXRlbU5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBoY19ub3RhdGlvbnNzZXRuYW1lZGl0ZW1uczEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGhjX25vdGF0aW9uc3NldG5hbWVkaXRlbW5zMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5hbWVkTm9kZU1hcCBub3RhdGlvbnM7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIE5vZGUgcmV0dmFsOworICAgICAgRWxlbWVudCBlbGVtOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIHRydWUpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICAKKyAgICAgIGlmICgKKyAgICAhKCgidGV4dC9odG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKQorKSB7CisgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZG9jVHlwZU5vdE51bGwiLCBkb2NUeXBlKTsKKyAgICAgIG5vdGF0aW9ucyA9IGRvY1R5cGUuZ2V0Tm90YXRpb25zKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJub3RhdGlvbnNOb3ROdWxsIiwgbm90YXRpb25zKTsKKyAgICAgIGVsZW0gPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiwgImJyIik7CisgICAgICAKKyAgICAgIHRyeSB7CisgICAgICByZXR2YWwgPSBub3RhdGlvbnMuc2V0TmFtZWRJdGVtTlMoZWxlbSk7CisgICAgICBmYWlsKCJ0aHJvd19ISUVSX09SX05PX01PRF9FUlIiKTsKKyAgICAgCisgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgc3dpdGNoIChleC5jb2RlKSB7CisgICAgICBjYXNlIDMgOiAKKyAgICAgICBicmVhazsKKyAgICAgIGNhc2UgNyA6IAorICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgdGhyb3cgZXg7CisgICAgICAgICAgfQorICAgICAgfSAKK30KKyAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2hjX25vdGF0aW9uc3NldG5hbWVkaXRlbW5zMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaGNfbm90YXRpb25zc2V0bmFtZWRpdGVtbnMxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTAxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOThmODNmNwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTAxLmphdmEKQEAgLTAsMCArMSwxMzIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIERvY3VtZW50IHNob3VsZCBpbXBvcnQgdGhlIGdpdmVuIGltcG9ydGVkTm9kZSBpbnRvIHRoYXQgRG9jdW1lbnQuCisgKiAgICBUaGUgaW1wb3J0ZWROb2RlIGlzIG9mIHR5cGUgQXR0ci4gCisgKiAgICBUaGUgb3duZXJFbGVtZW50IGlzIHNldCB0byBudWxsLiBTcGVjaWZpZWQgZmxhZyBpcyBzZXQgdG8gdHJ1ZS4KKyAqICAgIENoaWxkcmVuIGlzIGltcG9ydGVkLgorICogICAgCisgKiAgICBDcmVhdGUgYSBuZXcgYXR0cmlidXRlIHdob3NlIG5hbWUgaXMgImVsZW06YXR0cjEiIGluIGEgZGlmZmVyZW50IGRvY3VtZW50LgorICogICAgQ3JlYXRlIGEgY2hpbGQgVGV4dCBub2RlIHdpdGggdmFsdWUgImltcG9ydGVkVGV4dCIgZm9yIHRoZSBhdHRyaWJ1dGUgbm9kZSBhYm92ZS4KKyAqICAgIEludm9rZSBtZXRob2QgaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkgb24gdGhpcyBkb2N1bWVudCB3aXRoCisgKiAgICBpbXBvcnRlZE5vZGUgYmVpbmcgdGhlIG5ld2x5IGNyZWF0ZWQgYXR0cmlidXRlLgorICogICAgTWV0aG9kIHNob3VsZCByZXR1cm4gYSBub2RlIHdob3NlIG5hbWUgbWF0Y2hlcyAiZWxlbTphdHRyMSIgYW5kIGEgY2hpbGQgbm9kZQorICogICAgd2hvc2UgdmFsdWUgZXF1YWxzICJpbXBvcnRlZFRleHQiLgorICogICAgVGhlIHJldHVybmVkIG5vZGUgc2hvdWxkIGJlbG9uZyB0byB0aGlzIGRvY3VtZW50IHdob3NlIHN5c3RlbUlkIGlzICJzdGFmZi5kdGQiCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBpbXBvcnROb2RlMDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGltcG9ydE5vZGUwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBhTmV3RG9jOworICAgICAgQXR0ciBuZXdBdHRyOworICAgICAgVGV4dCBpbXBvcnRlZENoaWxkOworICAgICAgTm9kZSBhTm9kZTsKKyAgICAgIERvY3VtZW50IG93bmVyRG9jdW1lbnQ7CisgICAgICBFbGVtZW50IGF0dHJPd25lckVsZW1lbnQ7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIFN0cmluZyBzeXN0ZW07CisgICAgICBib29sZWFuIHNwZWNpZmllZDsKKyAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKyAgICAgIFN0cmluZyBub2RlTmFtZTsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgY2hpbGRWYWx1ZTsKKyAgICAgIGphdmEudXRpbC5MaXN0IHJlc3VsdCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5MaXN0IGV4cGVjdGVkUmVzdWx0ID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKKyAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZWxlbTphdHRyMSIpOworICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJpbXBvcnRlZFRleHQiKTsKKyAgICAgIAorICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBhTmV3RG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBuZXdBdHRyID0gYU5ld0RvYy5jcmVhdGVBdHRyaWJ1dGUoImVsZW06YXR0cjEiKTsKKyAgICAgIGltcG9ydGVkQ2hpbGQgPSBhTmV3RG9jLmNyZWF0ZVRleHROb2RlKCJpbXBvcnRlZFRleHQiKTsKKyAgICAgIGFOb2RlID0gbmV3QXR0ci5hcHBlbmRDaGlsZChpbXBvcnRlZENoaWxkKTsKKyAgICAgIGFOb2RlID0gZG9jLmltcG9ydE5vZGUobmV3QXR0ciwgZmFsc2UpOworICAgICAgb3duZXJEb2N1bWVudCA9IGFOb2RlLmdldE93bmVyRG9jdW1lbnQoKTsKKyAgICAgIGRvY1R5cGUgPSBvd25lckRvY3VtZW50LmdldERvY3R5cGUoKTsKKyAgICAgIHN5c3RlbSA9IGRvY1R5cGUuZ2V0U3lzdGVtSWQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImFOb2RlIiwgYU5vZGUpOworICAgICAgYXNzZXJ0VVJJRXF1YWxzKCJzeXN0ZW1JZCIsIG51bGwsIG51bGwsIG51bGwsICJzdGFmZk5TLmR0ZCIsIG51bGwsIG51bGwsIG51bGwsIG51bGwsIHN5c3RlbSk7CithdHRyT3duZXJFbGVtZW50ID0gKChBdHRyKSAvKk5vZGUgKi9hTm9kZSkuZ2V0T3duZXJFbGVtZW50KCk7CisgICAgICBhc3NlcnROdWxsKCJvd25lckVsZW1lbnQiLCBhdHRyT3duZXJFbGVtZW50KTsKKyAgICAgIHNwZWNpZmllZCA9ICgoQXR0cikgLypOb2RlICovYU5vZGUpLmdldFNwZWNpZmllZCgpOworICAgICAgYXNzZXJ0VHJ1ZSgic3BlY2lmaWVkIiwgc3BlY2lmaWVkKTsKKyAgICAgIGNoaWxkTGlzdCA9IGFOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGFzc2VydFNpemUoImNoaWxkTGlzdCIsIDEsIGNoaWxkTGlzdCk7CisgICAgICBub2RlTmFtZSA9IGFOb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lIiwgImVsZW06YXR0cjEiLCBub2RlTmFtZSk7CisgICAgICBjaGlsZCA9IGFOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkVmFsdWUgPSBjaGlsZC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2hpbGRWYWx1ZSIsICJpbXBvcnRlZFRleHQiLCBjaGlsZFZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihpbXBvcnROb2RlMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUwMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYzAxODA1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMDIuamF2YQpAQCAtMCwwICsxLDEwNCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImltcG9ydE5vZGUoaW1wb3J0ZWROb2RlLGRlZXApIiBtZXRob2QgZm9yIGEgCisgKiAgICBEb2N1bWVudCBzaG91bGQgaW1wb3J0IHRoZSBnaXZlbiBpbXBvcnRlZE5vZGUgaW50byB0aGF0IERvY3VtZW50LgorICogICAgVGhlIGltcG9ydGVkTm9kZSBpcyBvZiB0eXBlIENEYXRhX1NlY3Rpb24uCisgKiAgICAKKyAqICAgIENyZWF0ZSBhIENEQVRBU2VjdGlvbiBub2RlIHdpdGggdmFsdWUgYmVpbmcgdGhlIHN0cmluZyAidGhpcyBpcyBDREFUQVNlY3Rpb24gZGF0YSIgaW4gCisgKiAgICBhIGRpZmZlcmVudCBkb2N1bWVudC4gIEludm9rZSBtZXRob2QgaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkgb24KKyAqICAgIHRoaXMgZG9jdW1lbnQuICBNZXRob2Qgc2hvdWxkIHJldHVybiBhIENEQVRBU2VjdGlvbiBub2RlIHdob3NlIHZhbHVlIG1hdGNoZXMKKyAqICAgIHRoZSBhYm92ZSBzdHJpbmcuIFRoZSByZXR1cm5lZCBub2RlIHNob3VsZCBiZWxvbmcgdG8gdGhpcyBkb2N1bWVudCB3aG9zZSBzeXN0ZW1JZCBpcyAic3RhZmYuZHRkIgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaW1wb3J0Tm9kZTAyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBpbXBvcnROb2RlMDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnQgYU5ld0RvYzsKKyAgICAgIENEQVRBU2VjdGlvbiBjRGF0YVNlYzsKKyAgICAgIE5vZGUgYU5vZGU7CisgICAgICBEb2N1bWVudCBvd25lckRvY3VtZW50OworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBTdHJpbmcgc3lzdGVtOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBhTmV3RG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBjRGF0YVNlYyA9IGFOZXdEb2MuY3JlYXRlQ0RBVEFTZWN0aW9uKCJ0aGlzIGlzIENEQVRBU2VjdGlvbiBkYXRhIik7CisgICAgICBhTm9kZSA9IGRvYy5pbXBvcnROb2RlKGNEYXRhU2VjLCBmYWxzZSk7CisgICAgICBvd25lckRvY3VtZW50ID0gYU5vZGUuZ2V0T3duZXJEb2N1bWVudCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgib3duZXJEb2N1bWVudE5vdE51bGwiLCBvd25lckRvY3VtZW50KTsKKyAgICAgIGRvY1R5cGUgPSBvd25lckRvY3VtZW50LmdldERvY3R5cGUoKTsKKyAgICAgIHN5c3RlbSA9IGRvY1R5cGUuZ2V0U3lzdGVtSWQoKTsKKyAgICAgIGFzc2VydFVSSUVxdWFscygiZHRkU3lzdGVtSWQiLCBudWxsLCBudWxsLCBudWxsLCAic3RhZmZOUy5kdGQiLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBzeXN0ZW0pOwordmFsdWUgPSBhTm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZVZhbHVlIiwgInRoaXMgaXMgQ0RBVEFTZWN0aW9uIGRhdGEiLCB2YWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUwMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaW1wb3J0Tm9kZTAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMDMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTAzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGE0ZWViZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTAzLmphdmEKQEAgLTAsMCArMSwxMDUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJpbXBvcnROb2RlKGltcG9ydGVkTm9kZSxkZWVwKSIgbWV0aG9kIGZvciBhIAorICogICAgRG9jdW1lbnQgc2hvdWxkIGltcG9ydCB0aGUgZ2l2ZW4gaW1wb3J0ZWROb2RlIGludG8gdGhhdCBEb2N1bWVudC4KKyAqICAgIFRoZSBpbXBvcnRlZE5vZGUgaXMgb2YgdHlwZSBDb21tZW50LgorICogICAgCisgKiAgICBDcmVhdGUgYSBjb21tZW50IG5vZGUgd2l0aCB2YWx1ZSBiZWluZyB0aGUgc3RyaW5nICJ0aGlzIGlzIGEgY29tbWVudCIgaW4gCisgKiAgICBhIGRpZmZlcmVudCBkb2N1bWVudC4gIEludm9rZSBtZXRob2QgaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkgb24KKyAqICAgIHRoaXMgZG9jdW1lbnQuICBNZXRob2Qgc2hvdWxkIHJldHVybiBhIGNvbW1lbnQgbm9kZSB3aG9zZSB2YWx1ZSBtYXRjaGVzCisgKiAgICB0aGUgYWJvdmUgc3RyaW5nLiBUaGUgcmV0dXJuZWQgbm9kZSBzaG91bGQgYmVsb25nIHRvIHRoaXMgZG9jdW1lbnQgd2hvc2UKKyAqICAgIHN5c3RlbUlkIGlzICJzdGFmZi5kdGQiCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBpbXBvcnROb2RlMDMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGltcG9ydE5vZGUwMyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBhTmV3RG9jOworICAgICAgQ29tbWVudCBjb21tZW50OworICAgICAgTm9kZSBhTm9kZTsKKyAgICAgIERvY3VtZW50IG93bmVyRG9jdW1lbnQ7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIFN0cmluZyBzeXN0ZW07CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGFOZXdEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGNvbW1lbnQgPSBhTmV3RG9jLmNyZWF0ZUNvbW1lbnQoInRoaXMgaXMgYSBjb21tZW50Iik7CisgICAgICBhTm9kZSA9IGRvYy5pbXBvcnROb2RlKGNvbW1lbnQsIGZhbHNlKTsKKyAgICAgIG93bmVyRG9jdW1lbnQgPSBhTm9kZS5nZXRPd25lckRvY3VtZW50KCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJvd25lckRvY3VtZW50Tm90TnVsbCIsIG93bmVyRG9jdW1lbnQpOworICAgICAgZG9jVHlwZSA9IG93bmVyRG9jdW1lbnQuZ2V0RG9jdHlwZSgpOworICAgICAgc3lzdGVtID0gZG9jVHlwZS5nZXRTeXN0ZW1JZCgpOworICAgICAgYXNzZXJ0VVJJRXF1YWxzKCJzeXN0ZW1JZCIsIG51bGwsIG51bGwsIG51bGwsICJzdGFmZk5TLmR0ZCIsIG51bGwsIG51bGwsIG51bGwsIG51bGwsIHN5c3RlbSk7Cit2YWx1ZSA9IGFOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlVmFsdWUiLCAidGhpcyBpcyBhIGNvbW1lbnQiLCB2YWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaW1wb3J0Tm9kZTAzLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMDQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzcyM2U0MwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTA0LmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIERvY3VtZW50IHNob3VsZCBpbXBvcnQgdGhlIGdpdmVuIGltcG9ydGVkTm9kZSBpbnRvIHRoYXQgRG9jdW1lbnQuCisgKiAgICBUaGUgaW1wb3J0ZWROb2RlIGlzIG9mIHR5cGUgRG9jdW1lbnRfRnJhZ21lbnQuCisgKiAgICAKKyAqICAgIENyZWF0ZSBhIERvY3VtZW50RnJhZ21lbnQgaW4gYSBkaWZmZXJlbnQgZG9jdW1lbnQuCisgKiAgICBDcmVhdGUgYSBDb21tZW50IGNoaWxkIG5vZGUgZm9yIHRoZSBEb2N1bWVudCBGcmFnbWVudC4KKyAqICAgIEludm9rZSBtZXRob2QgaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkgb24gdGhpcyBkb2N1bWVudAorICogICAgd2l0aCBpbXBvcnRlZE5vZGUgYmVpbmcgdGhlIG5ld2x5IGNyZWF0ZWQgRG9jdW1lbnRGcmFnbWVudC4KKyAqICAgIE1ldGhvZCBzaG91bGQgcmV0dXJuIGEgbm9kZSBvZiB0eXBlIERvY3VtZW50RnJhZ21lbnQgd2hvc2UgY2hpbGQgaGFzCisgKiAgICBjb21tZW50IHZhbHVlICJkZXNjZW5kYW50MSIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBpbXBvcnROb2RlMDQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGltcG9ydE5vZGUwNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50IGFOZXdEb2M7CisgICAgICBEb2N1bWVudEZyYWdtZW50IGRvY0ZyYWc7CisgICAgICBDb21tZW50IGNvbW1lbnQ7CisgICAgICBOb2RlIGFOb2RlOworICAgICAgTm9kZUxpc3QgY2hpbGRyZW47CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBhTmV3RG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZG9jRnJhZyA9IGFOZXdEb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOworICAgICAgY29tbWVudCA9IGFOZXdEb2MuY3JlYXRlQ29tbWVudCgiZGVzY2VuZGFudDEiKTsKKyAgICAgIGFOb2RlID0gZG9jRnJhZy5hcHBlbmRDaGlsZChjb21tZW50KTsKKyAgICAgIGFOb2RlID0gZG9jLmltcG9ydE5vZGUoZG9jRnJhZywgdHJ1ZSk7CisgICAgICBjaGlsZHJlbiA9IGFOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGFzc2VydFNpemUoInRocm93X1NpemUiLCAxLCBjaGlsZHJlbik7CisgICAgICBjaGlsZCA9IGFOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIGNoaWxkVmFsdWUgPSBjaGlsZC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZGVzY2VuZGFudDEiLCAiZGVzY2VuZGFudDEiLCBjaGlsZFZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTA0IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihpbXBvcnROb2RlMDQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUwNS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMDUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZWNhZjIyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMDUuamF2YQpAQCAtMCwwICsxLDExMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJpbXBvcnROb2RlKGltcG9ydGVkTm9kZSxkZWVwKSIgbWV0aG9kIGZvciBhIAorICogICAgRG9jdW1lbnQgc2hvdWxkIGltcG9ydCB0aGUgZ2l2ZW4gaW1wb3J0ZWROb2RlIGludG8gdGhhdCBEb2N1bWVudC4KKyAqICAgIFRoZSBpbXBvcnRlZE5vZGUgaXMgb2YgdHlwZSBFbGVtZW50LgorICogICAgCisgKiAgICBSZXRyaWV2ZSBlbGVtZW50ICJlbXA6YWRkcmVzcyIgZnJvbSBzdGFmZk5TLnhtbCBkb2N1bWVudC4KKyAqICAgIEludm9rZSBtZXRob2QgaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkgb24gdGhpcyBkb2N1bWVudAorICogICAgd2l0aCBpbXBvcnRlZE5vZGUgYmVpbmcgdGhlIGVsZW1lbnQgZnJvbSBhYm92ZSBhbmQgZGVlcCBpcyBmYWxzZS4KKyAqICAgIE1ldGhvZCBzaG91bGQgcmV0dXJuIGFuIGVsZW1lbnQgbm9kZSB3aG9zZSBuYW1lIG1hdGNoZXMgImVtcDphZGRyZXNzIiAKKyAqICAgIGFuZCB3aG9zZSBjaGlsZHJlbiBhcmUgbm90IGltcG9ydGVkLiBUaGUgcmV0dXJuZWQgbm9kZSBzaG91bGQgCisgKiAgICBiZWxvbmcgdG8gdGhpcyBkb2N1bWVudCB3aG9zZSBzeXN0ZW1JZCBpcyAic3RhZmYuZHRkIgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaW1wb3J0Tm9kZTA1IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBpbXBvcnROb2RlMDUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnQgYU5ld0RvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIE5vZGUgYU5vZGU7CisgICAgICBib29sZWFuIGhhc0NoaWxkOworICAgICAgRG9jdW1lbnQgb3duZXJEb2N1bWVudDsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgU3RyaW5nIHN5c3RlbTsKKyAgICAgIFN0cmluZyBuYW1lOworICAgICAgTm9kZUxpc3QgYWRkcmVzc2VzOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBhTmV3RG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBhZGRyZXNzZXMgPSBhTmV3RG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6YWRkcmVzcyIpOworICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBhZGRyZXNzZXMuaXRlbSgwKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVtcEFkZHJlc3NOb3ROdWxsIiwgZWxlbWVudCk7CisgICAgICBhTm9kZSA9IGRvYy5pbXBvcnROb2RlKGVsZW1lbnQsIGZhbHNlKTsKKyAgICAgIGhhc0NoaWxkID0gYU5vZGUuaGFzQ2hpbGROb2RlcygpOworICAgICAgYXNzZXJ0RmFsc2UoImhhc0NoaWxkIiwgaGFzQ2hpbGQpOworb3duZXJEb2N1bWVudCA9IGFOb2RlLmdldE93bmVyRG9jdW1lbnQoKTsKKyAgICAgIGRvY1R5cGUgPSBvd25lckRvY3VtZW50LmdldERvY3R5cGUoKTsKKyAgICAgIHN5c3RlbSA9IGRvY1R5cGUuZ2V0U3lzdGVtSWQoKTsKKyAgICAgIGFzc2VydFVSSUVxdWFscygiZHRkU3lzdGVtSWQiLCBudWxsLCBudWxsLCBudWxsLCAic3RhZmZOUy5kdGQiLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBzeXN0ZW0pOworbmFtZSA9IGFOb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lIiwgImVtcDphZGRyZXNzIiwgbmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUwNSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaW1wb3J0Tm9kZTA1LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMDYuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTA2LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGU5MWViNQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTA2LmphdmEKQEAgLTAsMCArMSwxMDggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIERvY3VtZW50IHNob3VsZCBpbXBvcnQgdGhlIGdpdmVuIGltcG9ydGVkTm9kZSBpbnRvIHRoYXQgRG9jdW1lbnQuCisgKiAgICBUaGUgaW1wb3J0ZWROb2RlIGlzIG9mIHR5cGUgRWxlbWVudC4KKyAqICAgIAorICogICAgUmV0cmlldmUgZWxlbWVudCAiZW1wOmFkZHJlc3MiIGZyb20gc3RhZmZOUy54bWwgZG9jdW1lbnQuCisgKiAgICBJbnZva2UgbWV0aG9kIGltcG9ydE5vZGUoaW1wb3J0ZWROb2RlLGRlZXApIG9uIHRoaXMgZG9jdW1lbnQKKyAqICAgIHdpdGggaW1wb3J0ZWROb2RlIGJlaW5nIHRoZSBlbGVtZW50IGZyb20gYWJvdmUgYW5kIGRlZXAgaXMgdHJ1ZS4KKyAqICAgIE1ldGhvZCBzaG91bGQgcmV0dXJuIGFuIGVsZW1lbnQgbm9kZSB3aG9zZSBuYW1lIG1hdGNoZXMgImVtcDphZGRyZXNzIiBhbmQKKyAqICAgIHdob3NlIGRlc2NlbmRhbnQgaXMgaW1wb3J0ZWQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBpbXBvcnROb2RlMDYgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGltcG9ydE5vZGUwNihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBhTmV3RG9jOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgTm9kZSBhTm9kZTsKKyAgICAgIGJvb2xlYW4gaGFzQ2hpbGQ7CisgICAgICBTdHJpbmcgbmFtZTsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICBOb2RlTGlzdCBhZGRyZXNzZXM7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGFOZXdEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGFkZHJlc3NlcyA9IGFOZXdEb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGFkZHJlc3Nlcy5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkcmVzc05vdE51bGwiLCBlbGVtZW50KTsKKyAgICAgIGFOb2RlID0gZG9jLmltcG9ydE5vZGUoZWxlbWVudCwgdHJ1ZSk7CisgICAgICBoYXNDaGlsZCA9IGFOb2RlLmhhc0NoaWxkTm9kZXMoKTsKKyAgICAgIGFzc2VydFRydWUoInRocm93X1RydWUiLCBoYXNDaGlsZCk7CisgICAgICBuYW1lID0gYU5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZU5hbWUiLCAiZW1wOmFkZHJlc3MiLCBuYW1lKTsKKyAgICAgIGNoaWxkID0gYU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgdmFsdWUgPSBjaGlsZC5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZVZhbHVlIiwgIjI3IFNvdXRoIFJvYWQuIERhbGxhcywgdGV4YXMgOTg1NTYiLCB2YWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUwNiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaW1wb3J0Tm9kZTA2LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMDcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTA3LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTk5ZDFhOAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTA3LmphdmEKQEAgLTAsMCArMSwxMTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJpbXBvcnROb2RlKGltcG9ydGVkTm9kZSxkZWVwKSIgbWV0aG9kIGZvciBhIAorICogICAgRG9jdW1lbnQgc2hvdWxkIGltcG9ydCB0aGUgZ2l2ZW4gaW1wb3J0ZWROb2RlIGludG8gdGhhdCBEb2N1bWVudC4KKyAqICAgIFRoZSBpbXBvcnRlZE5vZGUgaXMgb2YgdHlwZSBFbGVtZW50LgorICogICAgSWYgdGhpcyBkb2N1bWVudCBkZWZpbmVzIGRlZmF1bHQgYXR0cmlidXRlcyBmb3IgdGhpcyBlbGVtZW50IG5hbWUgKGltcG9ydGVkTm9kZSksCisgKiAgICB0aG9zZSBkZWZhdWx0IGF0dHJpYnV0ZXMgYXJlIGFzc2lnbmVkLgorICogICAgCisgKiAgICBDcmVhdGUgYW4gZWxlbWVudCB3aG9zZSBuYW1lIGlzICJlbXA6ZW1wbG95ZWUiIGluIGEgZGlmZmVyZW50IGRvY3VtZW50LgorICogICAgSW52b2tlIG1ldGhvZCBpbXBvcnROb2RlKGltcG9ydGVkTm9kZSxkZWVwKSBvbiB0aGlzIGRvY3VtZW50IHdoaWNoCisgKiAgICBkZWZpbmVzIGRlZmF1bHQgYXR0cmlidXRlIGZvciB0aGUgZWxlbWVudCBuYW1lICJlbXA6ZW1wbG95ZWUiLgorICogICAgTWV0aG9kIHNob3VsZCByZXR1cm4gYW4gdGhlIGltcG9ydGVkIGVsZW1lbnQgd2l0aCBhbiBhc3NpZ25lZCBkZWZhdWx0IGF0dHJpYnV0ZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzOCI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzODwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaW1wb3J0Tm9kZTA3IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBpbXBvcnROb2RlMDcoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUsCitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcudmFsaWRhdGluZworICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnQgYU5ld0RvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIE5vZGUgYU5vZGU7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIFN0cmluZyBuYW1lOworICAgICAgTm9kZSBhdHRyOworICAgICAgU3RyaW5nIGxuYW1lOworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5pc3QuZ292IjsKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gImVtcDplbXBsb3llZSI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGFOZXdEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50ID0gYU5ld0RvYy5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgIGFOb2RlID0gZG9jLmltcG9ydE5vZGUoZWxlbWVudCwgZmFsc2UpOworICAgICAgYXR0cmlidXRlcyA9IGFOb2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGFzc2VydFNpemUoInRocm93X1NpemUiLCAxLCBhdHRyaWJ1dGVzKTsKKyAgICAgIG5hbWUgPSBhTm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTmFtZSIsICJlbXA6ZW1wbG95ZWUiLCBuYW1lKTsKKyAgICAgIGF0dHIgPSBhdHRyaWJ1dGVzLml0ZW0oMCk7CisgICAgICBsbmFtZSA9IGF0dHIuZ2V0TG9jYWxOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImxuYW1lIiwgImRlZmF1bHRBdHRyIiwgbG5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pbXBvcnROb2RlMDciOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGltcG9ydE5vZGUwNy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTA4LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUwOC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmOGYwY2UKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUwOC5qYXZhCkBAIC0wLDAgKzEsMTA1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImltcG9ydE5vZGUoaW1wb3J0ZWROb2RlLGRlZXApIiBtZXRob2QgZm9yIGEgCisgKiAgICBEb2N1bWVudCBzaG91bGQgaW1wb3J0IHRoZSBnaXZlbiBpbXBvcnRlZE5vZGUgaW50byB0aGF0IERvY3VtZW50LgorICogICAgVGhlIGltcG9ydGVkTm9kZSBpcyBvZiB0eXBlIERvY3VtZW50X0ZyYWdtZW50LgorICogICAgCisgKiAgICBDcmVhdGUgYSBEb2N1bWVudEZyYWdtZW50IGluIGEgZGlmZmVyZW50IGRvY3VtZW50LgorICogICAgSW52b2tlIG1ldGhvZCBpbXBvcnROb2RlKGltcG9ydGVkTm9kZSxkZWVwKSBvbiB0aGlzIGRvY3VtZW50CisgKiAgICB3aXRoIGltcG9ydGVkTm9kZSBiZWluZyB0aGUgbmV3bHkgY3JlYXRlZCBEb2N1bWVudEZyYWdtZW50LgorICogICAgTWV0aG9kIHNob3VsZCByZXR1cm4gYW4gZW1wdHkgRG9jdW1lbnRGcmFnbWVudCB0aGF0IGJlbG9uZ3MKKyAqICAgIHRvIHRoaXMgZG9jdW1lbnQgd2hvc2Ugc3lzdGVtSWQgaXMgInN0YWZmLmR0ZCIgCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Db3JlLURvY1R5cGUtc3lzdGVtSWQiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Db3JlLURvY1R5cGUtc3lzdGVtSWQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGltcG9ydE5vZGUwOCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaW1wb3J0Tm9kZTA4KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50IGFOZXdEb2M7CisgICAgICBEb2N1bWVudEZyYWdtZW50IGRvY0ZyYWc7CisgICAgICBOb2RlIGFOb2RlOworICAgICAgYm9vbGVhbiBoYXNDaGlsZDsKKyAgICAgIERvY3VtZW50IG93bmVyRG9jdW1lbnQ7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIFN0cmluZyBzeXN0ZW07CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGFOZXdEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGRvY0ZyYWcgPSBhTmV3RG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKKyAgICAgIGFOb2RlID0gZG9jLmltcG9ydE5vZGUoZG9jRnJhZywgZmFsc2UpOworICAgICAgaGFzQ2hpbGQgPSBhTm9kZS5oYXNDaGlsZE5vZGVzKCk7CisgICAgICBhc3NlcnRGYWxzZSgiaGFzQ2hpbGQiLCBoYXNDaGlsZCk7Citvd25lckRvY3VtZW50ID0gYU5vZGUuZ2V0T3duZXJEb2N1bWVudCgpOworICAgICAgZG9jVHlwZSA9IG93bmVyRG9jdW1lbnQuZ2V0RG9jdHlwZSgpOworICAgICAgc3lzdGVtID0gZG9jVHlwZS5nZXRTeXN0ZW1JZCgpOworICAgICAgYXNzZXJ0VVJJRXF1YWxzKCJzeXN0ZW0iLCBudWxsLCBudWxsLCBudWxsLCAic3RhZmZOUy5kdGQiLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBzeXN0ZW0pOworfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pbXBvcnROb2RlMDgiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGltcG9ydE5vZGUwOC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTA5LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUwOS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAxODZjZWUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUwOS5qYXZhCkBAIC0wLDAgKzEsMTE3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIERvY3VtZW50IHNob3VsZCBpbXBvcnQgdGhlIGdpdmVuIGltcG9ydGVkTm9kZSBpbnRvIHRoYXQgRG9jdW1lbnQuCisgKiAgICBUaGUgaW1wb3J0ZWROb2RlIGlzIG9mIHR5cGUgRW50aXR5LgorICogICAgCisgKiAgICBSZXRyaWV2ZSBlbnRpdHkgImVudDYiIGZyb20gc3RhZmZOUy54bWwgZG9jdW1lbnQuICAKKyAqICAgIEludm9rZSBtZXRob2QgaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkgb24gdGhpcyBkb2N1bWVudC4KKyAqICAgIE1ldGhvZCBzaG91bGQgcmV0dXJuIGEgbm9kZSBvZiB0eXBlIEVudGl0eSB3aG9zZSBwdWJsaWNJZCwgc3lzdGVtSWQgYW5kCisgKiAgICBub3RhdGlvbk5hbWUgYXR0cmlidXRlcyBhcmUgY29waWVkLgorICogICAgVGhlIHJldHVybmVkIG5vZGUgc2hvdWxkIGJlbG9uZyB0byB0aGlzIGRvY3VtZW50IHdob3NlIHN5c3RlbUlkIGlzICJzdGFmZi5kdGQiCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBpbXBvcnROb2RlMDkgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGltcG9ydE5vZGUwOShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBhTmV3RG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvYzFUeXBlOworICAgICAgTmFtZWROb2RlTWFwIGVudGl0eUxpc3Q7CisgICAgICBFbnRpdHkgZW50aXR5MjsKKyAgICAgIEVudGl0eSBlbnRpdHkxOworICAgICAgRG9jdW1lbnQgb3duZXJEb2N1bWVudDsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgU3RyaW5nIHN5c3RlbTsKKyAgICAgIFN0cmluZyBlbnRpdHlOYW1lOworICAgICAgU3RyaW5nIHB1YmxpY1ZhbDsKKyAgICAgIFN0cmluZyBub3RhdGlvbk5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGFOZXdEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGRvY1R5cGUgPSBhTmV3RG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGVudGl0eUxpc3QgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdGllc05vdE51bGwiLCBlbnRpdHlMaXN0KTsKKyAgICAgIGVudGl0eTIgPSAoRW50aXR5KSBlbnRpdHlMaXN0LmdldE5hbWVkSXRlbSgiZW50NiIpOworICAgICAgZW50aXR5MSA9IChFbnRpdHkpIGRvYy5pbXBvcnROb2RlKGVudGl0eTIsIGZhbHNlKTsKKyAgICAgIG93bmVyRG9jdW1lbnQgPSBlbnRpdHkxLmdldE93bmVyRG9jdW1lbnQoKTsKKyAgICAgIGRvY1R5cGUgPSBvd25lckRvY3VtZW50LmdldERvY3R5cGUoKTsKKyAgICAgIHN5c3RlbSA9IGRvY1R5cGUuZ2V0U3lzdGVtSWQoKTsKKyAgICAgIGFzc2VydFVSSUVxdWFscygiZHRkU3lzdGVtSWQiLCBudWxsLCBudWxsLCBudWxsLCAic3RhZmZOUy5kdGQiLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBzeXN0ZW0pOworZW50aXR5TmFtZSA9IGVudGl0eTEuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZW50aXR5TmFtZSIsICJlbnQ2IiwgZW50aXR5TmFtZSk7CisgICAgICBwdWJsaWNWYWwgPSBlbnRpdHkxLmdldFB1YmxpY0lkKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImVudGl0eVB1YmxpY0lkIiwgInVyaSIsIHB1YmxpY1ZhbCk7CisgICAgICBzeXN0ZW0gPSBlbnRpdHkxLmdldFN5c3RlbUlkKCk7CisgICAgICBhc3NlcnRVUklFcXVhbHMoImVudGl0eVN5c3RlbUlkIiwgbnVsbCwgbnVsbCwgbnVsbCwgImZpbGUiLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBzeXN0ZW0pOworbm90YXRpb25OYW1lID0gZW50aXR5MS5nZXROb3RhdGlvbk5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm90YXRpb25OYW1lIiwgIm5vdGF0aW9uMiIsIG5vdGF0aW9uTmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUwOSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaW1wb3J0Tm9kZTA5LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMTAuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTEwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzM5NTUwNgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTEwLmphdmEKQEAgLTAsMCArMSwxMDggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJpbXBvcnROb2RlKGltcG9ydGVkTm9kZSxkZWVwKSIgbWV0aG9kIGZvciBhIAorICogICAgRG9jdW1lbnQgc2hvdWxkIGltcG9ydCB0aGUgZ2l2ZW4gaW1wb3J0ZWROb2RlIGludG8gdGhhdCBEb2N1bWVudC4KKyAqICAgIFRoZSBpbXBvcnRlZE5vZGUgaXMgb2YgdHlwZSBFbnRpdHlfUmVmZXJlbmNlLgorICogICAgT25seSB0aGUgRW50aXR5UmVmZXJlbmNlIGlzIGNvcGllZCwgcmVnYXJkbGVzcyBvZiBkZWVwJ3MgdmFsdWUuCisgKiAgICAKKyAqICAgIENyZWF0ZSBhbiBlbnRpdHkgcmVmZXJlbmNlIHdob3NlIG5hbWUgaXMgImVudFJlZjEiIGluIGEgZGlmZmVyZW50IGRvY3VtZW50LgorICogICAgR2l2ZSBpdCB2YWx1ZSAiZW50UmVmMVZhbHVlIi4KKyAqICAgIEludm9rZSBtZXRob2QgaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkgb24gdGhpcyBkb2N1bWVudCB3aXRoIGltcG9ydGVkTm9kZQorICogICAgYmVpbmcgImVudFJlZjEiLgorICogICAgTWV0aG9kIHNob3VsZCByZXR1cm4gYSBub2RlIG9mIHR5cGUgRW50aXR5X1JlZmVyZW5jZSAod2hvc2UgdmFsdWUgaXMgbnVsbCkgdGhhdAorICogICAgYmVsb25ncyB0byB0aGlzIGRvY3VtZW50IHdob3NlIHN5c3RlbUlkIGlzICJzdGFmZi5kdGQiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaW1wb3J0Tm9kZTEwIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBpbXBvcnROb2RlMTAoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnQgYU5ld0RvYzsKKyAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWY7CisgICAgICBOb2RlIGFOb2RlOworICAgICAgRG9jdW1lbnQgb3duZXJEb2N1bWVudDsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgU3RyaW5nIHN5c3RlbTsKKyAgICAgIFN0cmluZyBuYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBhTmV3RG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBlbnRSZWYgPSBhTmV3RG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50UmVmMSIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworICAgICAgZW50UmVmLnNldE5vZGVWYWx1ZSgiZW50UmVmMVZhbHVlIik7CisgICAgICBhTm9kZSA9IGRvYy5pbXBvcnROb2RlKGVudFJlZiwgZmFsc2UpOworICAgICAgb3duZXJEb2N1bWVudCA9IGFOb2RlLmdldE93bmVyRG9jdW1lbnQoKTsKKyAgICAgIGRvY1R5cGUgPSBvd25lckRvY3VtZW50LmdldERvY3R5cGUoKTsKKyAgICAgIHN5c3RlbSA9IGRvY1R5cGUuZ2V0U3lzdGVtSWQoKTsKKyAgICAgIGFzc2VydFVSSUVxdWFscygic3lzdGVtSWQiLCBudWxsLCBudWxsLCBudWxsLCAic3RhZmZOUy5kdGQiLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBzeXN0ZW0pOworbmFtZSA9IGFOb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lIiwgImVudFJlZjEiLCBuYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTEwIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihpbXBvcnROb2RlMTAuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUxMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMTEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZTAxNmM2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMTEuamF2YQpAQCAtMCwwICsxLDEwNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImltcG9ydE5vZGUoaW1wb3J0ZWROb2RlLGRlZXApIiBtZXRob2QgZm9yIGEgCisgKiAgICBEb2N1bWVudCBzaG91bGQgaW1wb3J0IHRoZSBnaXZlbiBpbXBvcnRlZE5vZGUgaW50byB0aGF0IERvY3VtZW50LgorICogICAgVGhlIGltcG9ydGVkTm9kZSBpcyBvZiB0eXBlIEVudGl0eV9SZWZlcmVuY2UuCisgKiAgICBPbmx5IHRoZSBFbnRpdHlSZWZlcmVuY2UgaXMgY29waWVkLCByZWdhcmRsZXNzIG9mIGRlZXAncyB2YWx1ZS4KKyAqICAgIElmIHRoZSBEb2N1bWVudCBwcm92aWRlcyBhIGRlZmluaXRpb24gZm9yIHRoZSBlbnRpdHkgbmFtZSwgaXRzIHZhbHVlIGlzIGFzc2lnbmVkLgorICogICAgCisgKiAgICBDcmVhdGUgYW4gZW50aXR5IHJlZmVyZW5jZSB3aG9zZSBuYW1lIGlzICJlbnQzIiBpbiBhIGRpZmZlcmVudCBkb2N1bWVudC4KKyAqICAgIEludm9rZSBtZXRob2QgaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkgb24gdGhpcyBkb2N1bWVudCB3aXRoIGltcG9ydGVkTm9kZQorICogICAgYmVpbmcgImVudDMiLgorICogICAgTWV0aG9kIHNob3VsZCByZXR1cm4gYSBub2RlIG9mIHR5cGUgRW50aXR5X1JlZmVyZW5jZSB3aG9zZSBmaXJzdCBjaGlsZCdzIHZhbHVlIGlzICJUZXhhcyIgYXMgZGVmaW5lZAorICogICAgaW4gdGhpcyBkb2N1bWVudC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGltcG9ydE5vZGUxMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaW1wb3J0Tm9kZTExKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnQgYU5ld0RvYzsKKyAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWY7CisgICAgICBOb2RlIGFOb2RlOworICAgICAgU3RyaW5nIG5hbWU7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkVmFsdWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBhTmV3RG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZW50UmVmID0gYU5ld0RvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDMiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZW50UmVmKTsKKyAgICAgIGFOb2RlID0gZG9jLmltcG9ydE5vZGUoZW50UmVmLCB0cnVlKTsKKyAgICAgIG5hbWUgPSBhTm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJlbnRpdHlOYW1lIiwgImVudDMiLCBuYW1lKTsKKyAgICAgIGNoaWxkID0gYU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY2hpbGQiLCBjaGlsZCk7CisgICAgICBjaGlsZFZhbHVlID0gY2hpbGQuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoaWxkVmFsdWUiLCAiVGV4YXMiLCBjaGlsZFZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTExIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihpbXBvcnROb2RlMTEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUxMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMTIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NzFjNTg2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMTIuamF2YQpAQCAtMCwwICsxLDExNCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImltcG9ydE5vZGUoaW1wb3J0ZWROb2RlLGRlZXApIiBtZXRob2QgZm9yIGEgCisgKiAgICBEb2N1bWVudCBzaG91bGQgaW1wb3J0IHRoZSBnaXZlbiBpbXBvcnRlZE5vZGUgaW50byB0aGF0IERvY3VtZW50LgorICogICAgVGhlIGltcG9ydGVkTm9kZSBpcyBvZiB0eXBlIEVudGl0eS4KKyAqICAgIAorICogICAgUmV0cmlldmUgZW50aXR5ICJlbnQ0IiBmcm9tIHN0YWZmTlMueG1sIGRvY3VtZW50LiAgCisgKiAgICBJbnZva2UgbWV0aG9kIGltcG9ydE5vZGUoaW1wb3J0ZWROb2RlLGRlZXApIG9uIHRoaXMgZG9jdW1lbnQgd2l0aCBkZWVwIGFzIGZhbHNlLgorICogICAgTWV0aG9kIHNob3VsZCByZXR1cm4gYSBub2RlIG9mIHR5cGUgRW50aXR5IHdob3NlIGRlc2NlbmRhbnQgaXMgY29waWVkLgorICogICAgVGhlIHJldHVybmVkIG5vZGUgc2hvdWxkIGJlbG9uZyB0byB0aGlzIGRvY3VtZW50IHdob3NlIHN5c3RlbUlkIGlzICJzdGFmZk5TLmR0ZCIKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGltcG9ydE5vZGUxMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaW1wb3J0Tm9kZTEyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50IGFOZXdEb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jMVR5cGU7CisgICAgICBOYW1lZE5vZGVNYXAgZW50aXR5TGlzdDsKKyAgICAgIEVudGl0eSBlbnRpdHkyOworICAgICAgRW50aXR5IGVudGl0eTE7CisgICAgICBEb2N1bWVudCBvd25lckRvY3VtZW50OworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBTdHJpbmcgc3lzdGVtOworICAgICAgU3RyaW5nIGVudGl0eU5hbWU7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgU3RyaW5nIGNoaWxkTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgYU5ld0RvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZG9jMVR5cGUgPSBhTmV3RG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGVudGl0eUxpc3QgPSBkb2MxVHlwZS5nZXRFbnRpdGllcygpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50aXRpZXNOb3ROdWxsIiwgZW50aXR5TGlzdCk7CisgICAgICBlbnRpdHkyID0gKEVudGl0eSkgZW50aXR5TGlzdC5nZXROYW1lZEl0ZW0oImVudDQiKTsKKyAgICAgIGVudGl0eTEgPSAoRW50aXR5KSBkb2MuaW1wb3J0Tm9kZShlbnRpdHkyLCB0cnVlKTsKKyAgICAgIG93bmVyRG9jdW1lbnQgPSBlbnRpdHkxLmdldE93bmVyRG9jdW1lbnQoKTsKKyAgICAgIGRvY1R5cGUgPSBvd25lckRvY3VtZW50LmdldERvY3R5cGUoKTsKKyAgICAgIHN5c3RlbSA9IGRvY1R5cGUuZ2V0U3lzdGVtSWQoKTsKKyAgICAgIGFzc2VydFVSSUVxdWFscygic3lzdGVtSWQiLCBudWxsLCBudWxsLCBudWxsLCAic3RhZmZOUy5kdGQiLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBzeXN0ZW0pOworZW50aXR5TmFtZSA9IGVudGl0eTEuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZW50aXR5TmFtZSIsICJlbnQ0IiwgZW50aXR5TmFtZSk7CisgICAgICBjaGlsZCA9IGVudGl0eTEuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgibm90bnVsbCIsIGNoaWxkKTsKKyAgICAgIGNoaWxkTmFtZSA9IGNoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImNoaWxkTmFtZSIsICJlbnRFbGVtZW50MSIsIGNoaWxkTmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUxMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaW1wb3J0Tm9kZTEyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMTMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTEzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjY1ZTZiMAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTEzLmphdmEKQEAgLTAsMCArMSwxMTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJpbXBvcnROb2RlKGltcG9ydGVkTm9kZSxkZWVwKSIgbWV0aG9kIGZvciBhIAorICogICAgRG9jdW1lbnQgc2hvdWxkIGltcG9ydCB0aGUgZ2l2ZW4gaW1wb3J0ZWROb2RlIGludG8gdGhhdCBEb2N1bWVudC4KKyAqICAgIFRoZSBpbXBvcnRlZE5vZGUgaXMgb2YgdHlwZSBOb3RhdGlvbi4KKyAqICAgIAorICogICAgUmV0cmlldmUgbm90YXRpb24gbmFtZWQgIm5vdGF0aW9uMSIgZnJvbSBkb2N1bWVudCBzdGFmZk5TLnhtbC4KKyAqICAgIEludm9rZSBtZXRob2QgaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkgd2hlcmUgaW1wb3J0ZWROb2RlCisgKiAgICBjb250YWlucyB0aGUgcmV0cmlldmVkIG5vdGF0aW9uIGFuZCBkZWVwIGlzIGZhbHNlLiAgTWV0aG9kIHNob3VsZAorICogICAgcmV0dXJuIGEgbm9kZSBvZiB0eXBlIG5vdGF0aW9uIHdob3NlIG5hbWUgaXMgIm5vdGF0aW9uMSIuIAorICogICAgVGhlIHJldHVybmVkIG5vZGUgc2hvdWxkIGJlbG9uZyB0byB0aGlzIGRvY3VtZW50IHdob3NlIHN5c3RlbUlkIGlzICJzdGFmZi5kdGQiCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBpbXBvcnROb2RlMTMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGltcG9ydE5vZGUxMyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBhTmV3RG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvYzFUeXBlOworICAgICAgTmFtZWROb2RlTWFwIG5vdGF0aW9uTGlzdDsKKyAgICAgIE5vdGF0aW9uIG5vdGF0aW9uOworICAgICAgTm90YXRpb24gYU5vZGU7CisgICAgICBEb2N1bWVudCBvd25lckRvY3VtZW50OworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBTdHJpbmcgc3lzdGVtOworICAgICAgU3RyaW5nIHB1YmxpY1ZhbDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgYU5ld0RvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZG9jMVR5cGUgPSBhTmV3RG9jLmdldERvY3R5cGUoKTsKKyAgICAgIG5vdGF0aW9uTGlzdCA9IGRvYzFUeXBlLmdldE5vdGF0aW9ucygpOworICAgICAgYXNzZXJ0Tm90TnVsbCgibm90YXRpb25zTm90TnVsbCIsIG5vdGF0aW9uTGlzdCk7CisgICAgICBub3RhdGlvbiA9IChOb3RhdGlvbikgbm90YXRpb25MaXN0LmdldE5hbWVkSXRlbSgibm90YXRpb24xIik7CisgICAgICBhTm9kZSA9IChOb3RhdGlvbikgZG9jLmltcG9ydE5vZGUobm90YXRpb24sIGZhbHNlKTsKKyAgICAgIG93bmVyRG9jdW1lbnQgPSBhTm9kZS5nZXRPd25lckRvY3VtZW50KCk7CisgICAgICBkb2NUeXBlID0gb3duZXJEb2N1bWVudC5nZXREb2N0eXBlKCk7CisgICAgICBzeXN0ZW0gPSBkb2NUeXBlLmdldFN5c3RlbUlkKCk7CisgICAgICBhc3NlcnRVUklFcXVhbHMoInN5c3RlbUlkIiwgbnVsbCwgbnVsbCwgbnVsbCwgInN0YWZmTlMuZHRkIiwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgc3lzdGVtKTsKK3B1YmxpY1ZhbCA9IGFOb2RlLmdldFB1YmxpY0lkKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInB1YmxpY0lkIiwgIm5vdGF0aW9uMUZpbGUiLCBwdWJsaWNWYWwpOworICAgICAgc3lzdGVtID0gYU5vZGUuZ2V0U3lzdGVtSWQoKTsKKyAgICAgIGFzc2VydE51bGwoIm5vdGF0aW9uU3lzdGVtSWQiLCBzeXN0ZW0pOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pbXBvcnROb2RlMTMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGltcG9ydE5vZGUxMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTE0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUxNC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmNzc4ODYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUxNC5qYXZhCkBAIC0wLDAgKzEsMTA5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIERvY3VtZW50IHNob3VsZCBpbXBvcnQgdGhlIGdpdmVuIGltcG9ydGVkTm9kZSBpbnRvIHRoYXQgRG9jdW1lbnQuCisgKiAgICBUaGUgaW1wb3J0ZWROb2RlIGlzIG9mIHR5cGUgUHJvY2Vzc2luZyBJbnN0cnVjdGlvbi4KKyAqICAgIAorICogICAgQ3JlYXRlIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB3aXRoIHRhcmdldCBhcyAidGFyZ2V0MSIgYW5kIGRhdGEgYXMgImRhdGExIiAKKyAqICAgIGluIGEgZGlmZmVyZW50IGRvY3VtZW50LiBJbnZva2UgbWV0aG9kIGltcG9ydE5vZGUoaW1wb3J0ZWROb2RlLGRlZXApIG9uIHRoaXMgZG9jdW1lbnQuCisgKiAgICBNZXRob2Qgc2hvdWxkIHJldHVybiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gd2hvc2UgdGFyZ2V0IGFuZCBkYXRhIG1hdGNoIHRoZSBnaXZlbiAKKyAqICAgIHBhcmFtZXRlcnMuIFRoZSByZXR1cm5lZCBQSSBzaG91bGQgYmVsb25nIHRvIHRoaXMgZG9jdW1lbnQgd2hvc2Ugc3lzdGVtSWQgaXMgInN0YWZmLmR0ZCIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBpbXBvcnROb2RlMTQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGltcG9ydE5vZGUxNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBhTmV3RG9jOworICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uIHBpOworICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uIGFOb2RlOworICAgICAgRG9jdW1lbnQgb3duZXJEb2N1bWVudDsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgU3RyaW5nIHN5c3RlbTsKKyAgICAgIFN0cmluZyB0YXJnZXQ7CisgICAgICBTdHJpbmcgZGF0YTsKKyAgICAgIGphdmEudXRpbC5MaXN0IHJlc3VsdCA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICAKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgYU5ld0RvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgcGkgPSBhTmV3RG9jLmNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbigidGFyZ2V0MSIsICJkYXRhMSIpOworICAgICAgYU5vZGUgPSAoUHJvY2Vzc2luZ0luc3RydWN0aW9uKSBkb2MuaW1wb3J0Tm9kZShwaSwgZmFsc2UpOworICAgICAgb3duZXJEb2N1bWVudCA9IGFOb2RlLmdldE93bmVyRG9jdW1lbnQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoIm93bmVyRG9jdW1lbnROb3ROdWxsIiwgb3duZXJEb2N1bWVudCk7CisgICAgICBkb2NUeXBlID0gb3duZXJEb2N1bWVudC5nZXREb2N0eXBlKCk7CisgICAgICBzeXN0ZW0gPSBkb2NUeXBlLmdldFN5c3RlbUlkKCk7CisgICAgICBhc3NlcnRVUklFcXVhbHMoInN5c3RlbUlkIiwgbnVsbCwgbnVsbCwgbnVsbCwgInN0YWZmTlMuZHRkIiwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgc3lzdGVtKTsKK3RhcmdldCA9IGFOb2RlLmdldFRhcmdldCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJwaVRhcmdldCIsICJ0YXJnZXQxIiwgdGFyZ2V0KTsKKyAgICAgIGRhdGEgPSBhTm9kZS5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInBpRGF0YSIsICJkYXRhMSIsIGRhdGEpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pbXBvcnROb2RlMTQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGltcG9ydE5vZGUxNC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTE1LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUxNS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwZDJiODYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUxNS5qYXZhCkBAIC0wLDAgKzEsMTA1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIERvY3VtZW50IHNob3VsZCBpbXBvcnQgdGhlIGdpdmVuIGltcG9ydGVkTm9kZSBpbnRvIHRoYXQgRG9jdW1lbnQuCisgKiAgICBUaGUgaW1wb3J0ZWROb2RlIGlzIG9mIHR5cGUgVGV4dC4KKyAqICAgIAorICogICAgQ3JlYXRlIGEgdGV4dCBub2RlIHdpdGggdmFsdWUgYmVpbmcgdGhlIHN0cmluZyAidGhpcyBpcyB0ZXh0IGRhdGEiIGluIAorICogICAgYSBkaWZmZXJlbnQgZG9jdW1lbnQuICBJbnZva2UgbWV0aG9kIGltcG9ydE5vZGUoaW1wb3J0ZWROb2RlLGRlZXApIG9uCisgKiAgICB0aGlzIGRvY3VtZW50LiAgTWV0aG9kIHNob3VsZCByZXR1cm4gYSB0ZXh0IG5vZGUgd2hvc2UgdmFsdWUgbWF0Y2hlcworICogICAgdGhlIGFib3ZlIHN0cmluZy4gVGhlIHJldHVybmVkIG5vZGUgc2hvdWxkIGJlbG9uZyB0byB0aGlzIGRvY3VtZW50IAorICogICAgd2hvc2Ugc3lzdGVtSWQgaXMgInN0YWZmLmR0ZCIKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGltcG9ydE5vZGUxNSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaW1wb3J0Tm9kZTE1KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50IGFOZXdEb2M7CisgICAgICBUZXh0IHRleHQ7CisgICAgICBOb2RlIGFOb2RlOworICAgICAgRG9jdW1lbnQgb3duZXJEb2N1bWVudDsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgU3RyaW5nIHN5c3RlbTsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgYU5ld0RvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgdGV4dCA9IGFOZXdEb2MuY3JlYXRlVGV4dE5vZGUoInRoaXMgaXMgdGV4dCBkYXRhIik7CisgICAgICBhTm9kZSA9IGRvYy5pbXBvcnROb2RlKHRleHQsIGZhbHNlKTsKKyAgICAgIG93bmVyRG9jdW1lbnQgPSBhTm9kZS5nZXRPd25lckRvY3VtZW50KCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJvd25lckRvY3VtZW50Tm90TnVsbCIsIG93bmVyRG9jdW1lbnQpOworICAgICAgZG9jVHlwZSA9IG93bmVyRG9jdW1lbnQuZ2V0RG9jdHlwZSgpOworICAgICAgc3lzdGVtID0gZG9jVHlwZS5nZXRTeXN0ZW1JZCgpOworICAgICAgYXNzZXJ0VVJJRXF1YWxzKCJzeXN0ZW1JZCIsIG51bGwsIG51bGwsIG51bGwsICJzdGFmZk5TLmR0ZCIsIG51bGwsIG51bGwsIG51bGwsIG51bGwsIHN5c3RlbSk7Cit2YWx1ZSA9IGFOb2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlVmFsdWUiLCAidGhpcyBpcyB0ZXh0IGRhdGEiLCB2YWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUxNSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaW1wb3J0Tm9kZTE1LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMTYuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTE2LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDkwMWQ5NQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTE2LmphdmEKQEAgLTAsMCArMSwxMDQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIERvY3VtZW50IHNob3VsZCByYWlzZSBOT1RfU1VQUE9SVEVEX0VSUiBET01FeGNlcHRpb24gaWYKKyAqICAgIHRoZSB0eXBlIG9mIG5vZGUgYmVpbmcgaW1wb3J0ZWQgaXMgRG9jdW1lbnRUeXBlLgorICogICAgCisgKiAgICBSZXRyaWV2ZSBkb2N1bWVudCBzdGFmZi54bWwgYW5kIGdldCBpdHMgdHlwZS4KKyAqICAgIEludm9rZSBtZXRob2QgaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkgd2hlcmUgaW1wb3J0ZWROb2RlCisgKiAgICBjb250YWlucyB0aGUgZG9jdW1lbnQgdHlwZSBvZiB0aGUgc3RhZmYueG1sLiAgCisgKiAgICBNZXRob2Qgc2hvdWxkIHJhaXNlIE5PVF9TVVBQT1JUX0VSUiBET01FeGNlcHRpb24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PVF9TVVBQT1JURURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PVF9TVVBQT1JURURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdDb3JlLURvY3VtZW50LWltcG9ydE5vZGUnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT1RfU1VQUE9SVEVEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdDb3JlLURvY3VtZW50LWltcG9ydE5vZGUnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT1RfU1VQUE9SVEVEX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaW1wb3J0Tm9kZTE2IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBpbXBvcnROb2RlMTYoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnQgYW5vdGhlckRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTm9kZSBub2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBhbm90aGVyRG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBkb2NUeXBlID0gYW5vdGhlckRvYy5nZXREb2N0eXBlKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5vZGUgPSBkb2MuaW1wb3J0Tm9kZShkb2NUeXBlLCBmYWxzZSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9TVVBQT1JURURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2ltcG9ydE5vZGUxNiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaW1wb3J0Tm9kZTE2LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pbXBvcnROb2RlMTcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTE3LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTJlYmU1MwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTE3LmphdmEKQEAgLTAsMCArMSwxMDIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkiIG1ldGhvZCBmb3IgYSAKKyAqICAgIERvY3VtZW50IHNob3VsZCByYWlzZSBOT1RfU1VQUE9SVEVEX0VSUiBET01FeGNlcHRpb24gaWYKKyAqICAgIHRoZSB0eXBlIG9mIG5vZGUgYmVpbmcgaW1wb3J0ZWQgaXMgRG9jdW1lbnQuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHN0YWZmLnhtbCBkb2N1bWVudC4KKyAqICAgIEludm9rZSBtZXRob2QgaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkgd2hlcmUgaW1wb3J0ZWROb2RlCisgKiAgICBjb250YWlucyBzdGFmZi54bWwgYW5kIGRlZXAgaXMgdHJ1ZS4KKyAqICAgIE1ldGhvZCBzaG91bGQgcmFpc2UgTk9UX1NVUFBPUlRFRF9FUlIgRE9NRXhjZXB0aW9uLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT1RfU1VQUE9SVEVEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT1RfU1VQUE9SVEVEX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9UX1NVUFBPUlRFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnQ29yZS1Eb2N1bWVudC1pbXBvcnROb2RlJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9UX1NVUFBPUlRFRF9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGltcG9ydE5vZGUxNyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaW1wb3J0Tm9kZTE3KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50IGFub3RoZXJEb2M7CisgICAgICBOb2RlIG5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGFub3RoZXJEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgbm9kZSA9IGRvYy5pbXBvcnROb2RlKGFub3RoZXJEb2MsIGZhbHNlKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9UX1NVUFBPUlRFRF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaW1wb3J0Tm9kZTE3IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihpbXBvcnROb2RlMTcuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2ludGVybmFsU3Vic2V0MDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaW50ZXJuYWxTdWJzZXQwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY0YzRhN2UKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2ludGVybmFsU3Vic2V0MDEuamF2YQpAQCAtMCwwICsxLDkwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0SW50ZXJuYWxTdWJzZXQoKSIgbWV0aG9kIHJldHVybnMgCisgKiAgICB0aGUgaW50ZXJuYWwgc3Vic2V0IGFzIGEgc3RyaW5nIG9yIG51bGwgaWYgdGhlcmUgaXMgbm9uZS4KKyAqICAgIFRoaXMgZG9lcyBub3QgY29udGFpbiB0aGUgZGVsaW1pdGluZyBicmFja2V0cy4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGRvY3VtZW50dHlwZS4KKyAqICAgIEFwcGx5IHRoZSAiZ2V0SW50ZXJuYWxTdWJzZXQoKSIgbWV0aG9kLiAgTnVsbCBpcyByZXR1cm5lZCBzaW5jZSB0aGVyZSAKKyAqICAgIGlzIG5vdCBhbiBpbnRlcm5hbCBzdWJzZXQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtQ29yZS1Eb2NUeXBlLWludGVybmFsU3Vic2V0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtQ29yZS1Eb2NUeXBlLWludGVybmFsU3Vic2V0PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBpbnRlcm5hbFN1YnNldDAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBpbnRlcm5hbFN1YnNldDAxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZjIiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIFN0cmluZyBpbnRlcm5hbDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYyIiwgZmFsc2UpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBpbnRlcm5hbCA9IGRvY1R5cGUuZ2V0SW50ZXJuYWxTdWJzZXQoKTsKKyAgICAgIGFzc2VydE51bGwoImludGVybmFsU3Vic2V0TnVsbCIsIGludGVybmFsKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvaW50ZXJuYWxTdWJzZXQwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oaW50ZXJuYWxTdWJzZXQwMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaXNTdXBwb3J0ZWQwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDAxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTEzYWZmMwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaXNTdXBwb3J0ZWQwMS5qYXZhCkBAIC0wLDAgKzEsOTQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZmVhdHVyZSIgcGFyYW1ldGVyIGluIHRoZQorICogICAgIGlzU3VwcG9ydGVkKGZlYXR1cmUsdmVyc2lvbikiIG1ldGhvZCBpcyB0aGUgbmFtZQorICogICAgIG9mIHRoZSBmZWF0dXJlIGFuZCB0aGUgdmVyc2lvbiBpcyB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlCisgKiAgICAgZmVhdHVyZSB0byB0ZXN0LiAgIFhYWCBpcyBOT1QgYSBsZWdhbCB2YWx1ZSBmb3IgdGhlIGZlYXR1cmUgcGFyYW1ldGVyLgorICogICAgIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiAiZmFsc2UiIHNpbmNlIFhYWCBpcyBub3QgYSB2YWxpZCBmZWF0dXJlLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSByb290IG5vZGUgb2YgdGhlIERPTSBkb2N1bWVudCBieSBpbnZva2luZyAKKyAqICAgICB0aGUgImdldERvY3VtZW50RWxlbWVudCgpIiBtZXRob2QuICAgVGhpcyBzaG91bGQgY3JlYXRlIGEKKyAqICAgICBub2RlIG9iamVjdCBvbiB3aGljaCB0aGUgImlzU3VwcG9ydGVkKGZlYXR1cmUsdmVyc2lvbikiCisgKiAgICAgbWV0aG9kIGlzIGludm9rZWQgd2l0aCAiZmVhdHVyZSIgZXF1YWwgdG8gIlhYWCIgYW5kIHZlcnNpb24gdG8gIjEuMCIuCisgKiAgICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgYm9vbGVhbiAiZmFsc2UiIHNpbmNlIFhYWCBpcyBub3QgYSB2YWxpZCBmZWF0dXJlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1Ob2RlLXN1cHBvcnRzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGlzU3VwcG9ydGVkMDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGlzU3VwcG9ydGVkMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSByb290Tm9kZTsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgcm9vdE5vZGUgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBzdGF0ZSA9IHJvb3ROb2RlLmlzU3VwcG9ydGVkKCJYWFgiLCAiMS4wIik7CisgICAgICBhc3NlcnRGYWxzZSgidGhyb3dfRmFsc2UiLCBzdGF0ZSk7Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGlzU3VwcG9ydGVkMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaXNTdXBwb3J0ZWQwMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjODQyZDcKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDIuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImZlYXR1cmUiIHBhcmFtZXRlciBpbiB0aGUKKyAqICAgICBpc1N1cHBvcnRlZChmZWF0dXJlLHZlcnNpb24pIiBtZXRob2QgaXMgdGhlIG5hbWUKKyAqICAgICBvZiB0aGUgZmVhdHVyZSBhbmQgdGhlIHZlcnNpb24gaXMgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZQorICogICAgIGZlYXR1cmUgdG8gdGVzdC4gICBYTUwgaXMgYSBsZWdhbCB2YWx1ZSBmb3IgdGhlIGZlYXR1cmUgcGFyYW1ldGVyLgorICogICAgIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiAiZmFsc2UiIHNpbmNlIDkuMCBpcyBub3QgYSB2YWxpZCB2ZXJzaW9uLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSByb290IG5vZGUgb2YgdGhlIERPTSBkb2N1bWVudCBieSBpbnZva2luZyAKKyAqICAgICB0aGUgImdldERvY3VtZW50RWxlbWVudCgpIiBtZXRob2QuICAgVGhpcyBzaG91bGQgY3JlYXRlIGEKKyAqICAgICBub2RlIG9iamVjdCBvbiB3aGljaCB0aGUgImlzU3VwcG9ydGVkKGZlYXR1cmUsdmVyc2lvbikiCisgKiAgICAgbWV0aG9kIGlzIGludm9rZWQgd2l0aCAiZmVhdHVyZSIgZXF1YWwgdG8gIlhNTCIgYW5kIHZlcnNpb24gdG8gIjkuMCIuCisgKiAgICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgYm9vbGVhbiAiZmFsc2UiIHNpbmNlIDkuMCBpcyBub3QgYSB2YWxpZCB2ZXJzaW9uLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1Ob2RlLXN1cHBvcnRzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGlzU3VwcG9ydGVkMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGlzU3VwcG9ydGVkMDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSByb290Tm9kZTsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgcm9vdE5vZGUgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBzdGF0ZSA9IHJvb3ROb2RlLmlzU3VwcG9ydGVkKCJYTUwiLCAiOS4wIik7CisgICAgICBhc3NlcnRGYWxzZSgidGhyb3dfRmFsc2UiLCBzdGF0ZSk7Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGlzU3VwcG9ydGVkMDIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaXNTdXBwb3J0ZWQwNC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZjNDk5ZmMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDQuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImZlYXR1cmUiIHBhcmFtZXRlciBpbiB0aGUKKyAqICAgICBpc1N1cHBvcnRlZChmZWF0dXJlLHZlcnNpb24pIiBtZXRob2QgaXMgdGhlIG5hbWUKKyAqICAgICBvZiB0aGUgZmVhdHVyZSBhbmQgdGhlIHZlcnNpb24gaXMgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZQorICogICAgIGZlYXR1cmUgdG8gdGVzdC4gICBYTUwgaXMgYSBsZWdhbCB2YWx1ZSBmb3IgdGhlIGZlYXR1cmUgcGFyYW1ldGVyIAorICogICAgIChUZXN0IGZvciB4bWwsIGxvd2VyIGNhc2UpLiAKKyAqICAgICBMZWdhbCB2YWx1ZXMgZm9yIHRoZSB2ZXJzaW9uIHBhcmFtZXRlciBhcmUgMS4wIGFuZCAyLjAKKyAqICAgICAoVGVzdCBmb3IgMS4wKS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgcm9vdCBub2RlIG9mIHRoZSBET00gZG9jdW1lbnQgYnkgaW52b2tpbmcgCisgKiAgICAgdGhlICJnZXREb2N1bWVudEVsZW1lbnQoKSIgbWV0aG9kLiAgIFRoaXMgc2hvdWxkIGNyZWF0ZSBhCisgKiAgICAgbm9kZSBvYmplY3Qgb24gd2hpY2ggdGhlICJpc1N1cHBvcnRlZChmZWF0dXJlLHZlcnNpb24pIgorICogICAgIG1ldGhvZCBpcyBpbnZva2VkIHdpdGggImZlYXR1cmUiIGVxdWFsIHRvICJ4bWwiIGFuZCB0aGUgdmVyc2lvbiBlcXVhbCB0byAxLjAuCisgKiAgICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgYm9vbGVhbiAidHJ1ZSIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtTm9kZS1zdXBwb3J0czwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaXNTdXBwb3J0ZWQwNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaXNTdXBwb3J0ZWQwNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIHJvb3ROb2RlOworICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICByb290Tm9kZSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIHN0YXRlID0gcm9vdE5vZGUuaXNTdXBwb3J0ZWQoInhtbCIsICIxLjAiKTsKKyAgICAgIGFzc2VydFRydWUoInRocm93X1RydWUiLCBzdGF0ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGlzU3VwcG9ydGVkMDQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaXNTdXBwb3J0ZWQwNS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyM2RkZWMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDUuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImZlYXR1cmUiIHBhcmFtZXRlciBpbiB0aGUKKyAqICAgICBpc1N1cHBvcnRlZChmZWF0dXJlLHZlcnNpb24pIiBtZXRob2QgaXMgdGhlIG5hbWUKKyAqICAgICBvZiB0aGUgZmVhdHVyZSBhbmQgdGhlIHZlcnNpb24gaXMgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZQorICogICAgIGZlYXR1cmUgdG8gdGVzdC4gICBDb3JlIGlzIGEgbGVnYWwgdmFsdWUgZm9yIHRoZSBmZWF0dXJlIHBhcmFtZXRlciAKKyAqICAgICAoVGVzdCBmb3IgY29yZSwgbG93ZXIgY2FzZSkuIAorICogICAgIExlZ2FsIHZhbHVlcyBmb3IgdGhlIHZlcnNpb24gcGFyYW1ldGVyIGFyZSAxLjAgYW5kIDIuMAorICogICAgIChUZXN0IGZvciAyLjApLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSByb290IG5vZGUgb2YgdGhlIERPTSBkb2N1bWVudCBieSBpbnZva2luZyAKKyAqICAgICB0aGUgImdldERvY3VtZW50RWxlbWVudCgpIiBtZXRob2QuICAgVGhpcyBzaG91bGQgY3JlYXRlIGEKKyAqICAgICBub2RlIG9iamVjdCBvbiB3aGljaCB0aGUgImlzU3VwcG9ydGVkKGZlYXR1cmUsdmVyc2lvbikiCisgKiAgICAgbWV0aG9kIGlzIGludm9rZWQgd2l0aCAiZmVhdHVyZSIgZXF1YWwgdG8gImNvcmUiIGFuZCB0aGUgdmVyc2lvbiBlcXVhbCB0byAyLjAuCisgKiAgICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgYm9vbGVhbiAidHJ1ZSIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtTm9kZS1zdXBwb3J0czwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaXNTdXBwb3J0ZWQwNSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaXNTdXBwb3J0ZWQwNShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIHJvb3ROb2RlOworICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICByb290Tm9kZSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIHN0YXRlID0gcm9vdE5vZGUuaXNTdXBwb3J0ZWQoImNvcmUiLCAiMi4wIik7CisgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19UcnVlIiwgc3RhdGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDA1IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihpc1N1cHBvcnRlZDA1LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDA2LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDYuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YTQ5YzczCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDA2LmphdmEKQEAgLTAsMCArMSw5NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJmZWF0dXJlIiBwYXJhbWV0ZXIgaW4gdGhlCisgKiAgICAgaXNTdXBwb3J0ZWQoZmVhdHVyZSx2ZXJzaW9uKSIgbWV0aG9kIGlzIHRoZSBuYW1lCisgKiAgICAgb2YgdGhlIGZlYXR1cmUgYW5kIHRoZSB2ZXJzaW9uIGlzIHRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGUKKyAqICAgICBmZWF0dXJlIHRvIHRlc3QuICAgWE1MIGlzIGEgbGVnYWwgdmFsdWUgZm9yIHRoZSBmZWF0dXJlIHBhcmFtZXRlcgorICogICAgIChUZXN0IGZvciB4bWwsIGxvd2VyIGNhc2UpLiAKKyAqICAgICBMZWdhbCB2YWx1ZXMgZm9yIHRoZSB2ZXJzaW9uIHBhcmFtZXRlciBhcmUgMS4wIGFuZCAyLjAKKyAqICAgICAoVGVzdCBmb3IgMi4wKS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgcm9vdCBub2RlIG9mIHRoZSBET00gZG9jdW1lbnQgYnkgaW52b2tpbmcgCisgKiAgICAgdGhlICJnZXREb2N1bWVudEVsZW1lbnQoKSIgbWV0aG9kLiAgIFRoaXMgc2hvdWxkIGNyZWF0ZSBhCisgKiAgICAgbm9kZSBvYmplY3Qgb24gd2hpY2ggdGhlICJpc1N1cHBvcnRlZChmZWF0dXJlLHZlcnNpb24pIgorICogICAgIG1ldGhvZCBpcyBpbnZva2VkIHdpdGggImZlYXR1cmUiIGVxdWFsIHRvICJ4bWwiIGFuZCB0aGUgdmVyc2lvbiBlcXVhbCB0byAyLjAuCisgKiAgICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgYm9vbGVhbiAidHJ1ZSIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtTm9kZS1zdXBwb3J0czwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaXNTdXBwb3J0ZWQwNiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaXNTdXBwb3J0ZWQwNihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIHJvb3ROb2RlOworICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICByb290Tm9kZSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIHN0YXRlID0gcm9vdE5vZGUuaXNTdXBwb3J0ZWQoInhtbCIsICIyLjAiKTsKKyAgICAgIGFzc2VydFRydWUoInRocm93X1RydWUiLCBzdGF0ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDYiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGlzU3VwcG9ydGVkMDYuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaXNTdXBwb3J0ZWQwNy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQwMWY3MWQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDcuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImZlYXR1cmUiIHBhcmFtZXRlciBpbiB0aGUKKyAqICAgICBpc1N1cHBvcnRlZChmZWF0dXJlLHZlcnNpb24pIiBtZXRob2QgaXMgdGhlIG5hbWUKKyAqICAgICBvZiB0aGUgZmVhdHVyZSBhbmQgdGhlIHZlcnNpb24gaXMgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZQorICogICAgIGZlYXR1cmUgdG8gdGVzdC4gICBYTUwgaXMgYSBsZWdhbCB2YWx1ZSBmb3IgdGhlIGZlYXR1cmUgcGFyYW1ldGVyCisgKiAgICAgKFRlc3QgZm9yIFhNTCkuIAorICogICAgIElmIHRoZSB2ZXJzaW9uIGlzIG5vdCBzcGVjaWZpZWQsIHN1cHBvcnRpbmcgYW55IHZlcnNpb24gb2YgdGhlCisgKiAgICAgbWV0aG9kIHRvIHJldHVybiB0cnVlLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSByb290IG5vZGUgb2YgdGhlIERPTSBkb2N1bWVudCBieSBpbnZva2luZyAKKyAqICAgICB0aGUgImdldERvY3VtZW50RWxlbWVudCgpIiBtZXRob2QuICAgVGhpcyBzaG91bGQgY3JlYXRlIGEKKyAqICAgICBub2RlIG9iamVjdCBvbiB3aGljaCB0aGUgImlzU3VwcG9ydGVkKGZlYXR1cmUsdmVyc2lvbikiCisgKiAgICAgbWV0aG9kIGlzIGludm9rZWQgd2l0aCAiZmVhdHVyZSIgZXF1YWwgdG8gIlhNTCIgYW5kIHRoZSB2ZXJzaW9uIGVxdWFsIGJsYW5rLgorICogICAgIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiBhIGJvb2xlYW4gInRydWUiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1Ob2RlLXN1cHBvcnRzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGlzU3VwcG9ydGVkMDcgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGlzU3VwcG9ydGVkMDcoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSByb290Tm9kZTsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgcm9vdE5vZGUgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBzdGF0ZSA9IHJvb3ROb2RlLmlzU3VwcG9ydGVkKCJYTUwiLCAiIik7CisgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19UcnVlIiwgc3RhdGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDA3IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihpc1N1cHBvcnRlZDA3LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDA5LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMDkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YjRhZTE0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDA5LmphdmEKQEAgLTAsMCArMSw5NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJmZWF0dXJlIiBwYXJhbWV0ZXIgaW4gdGhlCisgKiAgICAgaXNTdXBwb3J0ZWQoZmVhdHVyZSx2ZXJzaW9uKSIgbWV0aG9kIGlzIHRoZSBuYW1lCisgKiAgICAgb2YgdGhlIGZlYXR1cmUgYW5kIHRoZSB2ZXJzaW9uIGlzIHRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGUKKyAqICAgICBmZWF0dXJlIHRvIHRlc3QuICAgWE1MIGlzIGEgbGVnYWwgdmFsdWUgZm9yIHRoZSBmZWF0dXJlIHBhcmFtZXRlciAKKyAqICAgICAoVGVzdCBmb3IgWE1MLCB1cHBlciBjYXNlKS4gCisgKiAgICAgTGVnYWwgdmFsdWVzIGZvciB0aGUgdmVyc2lvbiBwYXJhbWV0ZXIgYXJlIDEuMCBhbmQgMi4wCisgKiAgICAgKFRlc3QgZm9yIDEuMCkuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgRE9NIGRvY3VtZW50IGJ5IGludm9raW5nIAorICogICAgIHRoZSAiZ2V0RG9jdW1lbnRFbGVtZW50KCkiIG1ldGhvZC4gICBUaGlzIHNob3VsZCBjcmVhdGUgYQorICogICAgIG5vZGUgb2JqZWN0IG9uIHdoaWNoIHRoZSAiaXNTdXBwb3J0ZWQoZmVhdHVyZSx2ZXJzaW9uKSIKKyAqICAgICBtZXRob2QgaXMgaW52b2tlZCB3aXRoICJmZWF0dXJlIiBlcXVhbCB0byAiWE1MIiBhbmQgdGhlIHZlcnNpb24gZXF1YWwgdG8gMS4wLgorICogICAgIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiBhIGJvb2xlYW4gInRydWUiLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1Ob2RlLXN1cHBvcnRzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGlzU3VwcG9ydGVkMDkgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGlzU3VwcG9ydGVkMDkoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSByb290Tm9kZTsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgcm9vdE5vZGUgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBzdGF0ZSA9IHJvb3ROb2RlLmlzU3VwcG9ydGVkKCJYTUwiLCAiMS4wIik7CisgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19UcnVlIiwgc3RhdGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDA5IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihpc1N1cHBvcnRlZDA5LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDEwLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMTAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NDE0ZGI0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDEwLmphdmEKQEAgLTAsMCArMSw5NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJmZWF0dXJlIiBwYXJhbWV0ZXIgaW4gdGhlCisgKiAgICAgaXNTdXBwb3J0ZWQoZmVhdHVyZSx2ZXJzaW9uKSIgbWV0aG9kIGlzIHRoZSBuYW1lCisgKiAgICAgb2YgdGhlIGZlYXR1cmUgYW5kIHRoZSB2ZXJzaW9uIGlzIHRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGUKKyAqICAgICBmZWF0dXJlIHRvIHRlc3QuICAgQ09SRSBpcyBhIGxlZ2FsIHZhbHVlIGZvciB0aGUgZmVhdHVyZSBwYXJhbWV0ZXIKKyAqICAgICAoVGVzdCBmb3IgQ09SRSwgdXBwZXIgY2FzZSkuIAorICogICAgIExlZ2FsIHZhbHVlcyBmb3IgdGhlIHZlcnNpb24gcGFyYW1ldGVyIGFyZSAxLjAgYW5kIDIuMAorICogICAgIChUZXN0IGZvciAyLjApLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSByb290IG5vZGUgb2YgdGhlIERPTSBkb2N1bWVudCBieSBpbnZva2luZyAKKyAqICAgICB0aGUgImdldERvY3VtZW50RWxlbWVudCgpIiBtZXRob2QuICAgVGhpcyBzaG91bGQgY3JlYXRlIGEKKyAqICAgICBub2RlIG9iamVjdCBvbiB3aGljaCB0aGUgImlzU3VwcG9ydGVkKGZlYXR1cmUsdmVyc2lvbikiCisgKiAgICAgbWV0aG9kIGlzIGludm9rZWQgd2l0aCAiZmVhdHVyZSIgZXF1YWwgdG8gIkNPUkUiIGFuZCB0aGUgdmVyc2lvbiBlcXVhbCB0byAyLjAuCisgKiAgICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgYm9vbGVhbiAidHJ1ZSIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtTm9kZS1zdXBwb3J0czwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaXNTdXBwb3J0ZWQxMCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaXNTdXBwb3J0ZWQxMChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIHJvb3ROb2RlOworICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICByb290Tm9kZSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIHN0YXRlID0gcm9vdE5vZGUuaXNTdXBwb3J0ZWQoIkNPUkUiLCAiMi4wIik7CisgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19UcnVlIiwgc3RhdGUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDEwIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihpc1N1cHBvcnRlZDEwLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDExLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMTEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43N2UyOGRlCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9pc1N1cHBvcnRlZDExLmphdmEKQEAgLTAsMCArMSw5NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJmZWF0dXJlIiBwYXJhbWV0ZXIgaW4gdGhlCisgKiAgICAgaXNTdXBwb3J0ZWQoZmVhdHVyZSx2ZXJzaW9uKSIgbWV0aG9kIGlzIHRoZSBuYW1lCisgKiAgICAgb2YgdGhlIGZlYXR1cmUgYW5kIHRoZSB2ZXJzaW9uIGlzIHRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGUKKyAqICAgICBmZWF0dXJlIHRvIHRlc3QuICAgWE1MIGlzIGEgbGVnYWwgdmFsdWUgZm9yIHRoZSBmZWF0dXJlIHBhcmFtZXRlcgorICogICAgIChUZXN0IGZvciBYTUwsIHVwcGVyIGNhc2UpLiAKKyAqICAgICBMZWdhbCB2YWx1ZXMgZm9yIHRoZSB2ZXJzaW9uIHBhcmFtZXRlciBhcmUgMS4wIGFuZCAyLjAKKyAqICAgICAoVGVzdCBmb3IgMi4wKS4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgcm9vdCBub2RlIG9mIHRoZSBET00gZG9jdW1lbnQgYnkgaW52b2tpbmcgCisgKiAgICAgdGhlICJnZXREb2N1bWVudEVsZW1lbnQoKSIgbWV0aG9kLiAgIFRoaXMgc2hvdWxkIGNyZWF0ZSBhCisgKiAgICAgbm9kZSBvYmplY3Qgb24gd2hpY2ggdGhlICJpc1N1cHBvcnRlZChmZWF0dXJlLHZlcnNpb24pIgorICogICAgIG1ldGhvZCBpcyBpbnZva2VkIHdpdGggImZlYXR1cmUiIGVxdWFsIHRvICJYTUwiIGFuZCB0aGUgdmVyc2lvbiBlcXVhbCB0byAyLjAuCisgKiAgICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgYm9vbGVhbiAidHJ1ZSIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtTm9kZS1zdXBwb3J0czwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaXNTdXBwb3J0ZWQxMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaXNTdXBwb3J0ZWQxMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIHJvb3ROb2RlOworICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICByb290Tm9kZSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIHN0YXRlID0gcm9vdE5vZGUuaXNTdXBwb3J0ZWQoIlhNTCIsICIyLjAiKTsKKyAgICAgIGFzc2VydFRydWUoInRocm93X1RydWUiLCBzdGF0ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMTEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGlzU3VwcG9ydGVkMTEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMTIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaXNTdXBwb3J0ZWQxMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZlYzQ5ODgKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMTIuamF2YQpAQCAtMCwwICsxLDEyMiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImZlYXR1cmUiIHBhcmFtZXRlciBpbiB0aGUKKyAqICAgICBpc1N1cHBvcnRlZChmZWF0dXJlLHZlcnNpb24pIiBtZXRob2QgaXMgdGhlIG5hbWUKKyAqICAgICBvZiB0aGUgZmVhdHVyZSBhbmQgdGhlIHZlcnNpb24gaXMgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZQorICogICAgIGZlYXR1cmUgdG8gdGVzdC4gICBDT1JFIGlzIGEgbGVnYWwgdmFsdWUgZm9yIHRoZSBmZWF0dXJlIHBhcmFtZXRlciAKKyAqICAgICAoVGVzdCBmb3IgQ09SRSwgdXBwZXIgY2FzZSkuIAorICogICAgIExlZ2FsIHZhbHVlcyBmb3IgdGhlIHZlcnNpb24gcGFyYW1ldGVyIGFyZSAxLjAgYW5kIDIuMAorICogICAgIChUZXN0IGZvciAxLjApLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSByb290IG5vZGUgb2YgdGhlIERPTSBkb2N1bWVudCBieSBpbnZva2luZyAKKyAqICAgICB0aGUgImdldERvY3VtZW50RWxlbWVudCgpIiBtZXRob2QuICAgVGhpcyBzaG91bGQgY3JlYXRlIGEKKyAqICAgICBub2RlIG9iamVjdCBvbiB3aGljaCB0aGUgImlzU3VwcG9ydGVkKGZlYXR1cmUsdmVyc2lvbikiCisgKiAgICAgbWV0aG9kIGlzIGludm9rZWQgd2l0aCAiZmVhdHVyZSIgZXF1YWwgdG8gIkNPUkUiIGFuZCB0aGUgdmVyc2lvbiBlcXVhbCB0byAxLjAuCisgKiAgICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgYm9vbGVhbiAidHJ1ZSIuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtTm9kZS1zdXBwb3J0czwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgaXNTdXBwb3J0ZWQxMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgaXNTdXBwb3J0ZWQxMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBqYXZhLnV0aWwuTGlzdCBmZWF0dXJlcyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBmZWF0dXJlcy5hZGQoIkNvcmUiKTsKKyAgICAgIGZlYXR1cmVzLmFkZCgiWE1MIik7CisgICAgICBmZWF0dXJlcy5hZGQoIkhUTUwiKTsKKyAgICAgIGZlYXR1cmVzLmFkZCgiVmlld3MiKTsKKyAgICAgIGZlYXR1cmVzLmFkZCgiU3R5bGVTaGVldHMiKTsKKyAgICAgIGZlYXR1cmVzLmFkZCgiQ1NTIik7CisgICAgICBmZWF0dXJlcy5hZGQoIkNTUzIiKTsKKyAgICAgIGZlYXR1cmVzLmFkZCgiRXZlbnRzIik7CisgICAgICBmZWF0dXJlcy5hZGQoIlVJRXZlbnRzIik7CisgICAgICBmZWF0dXJlcy5hZGQoIk1vdXNlRXZlbnRzIik7CisgICAgICBmZWF0dXJlcy5hZGQoIk11dGF0aW9uRXZlbnRzIik7CisgICAgICBmZWF0dXJlcy5hZGQoIkhUTUxFdmVudHMiKTsKKyAgICAgIGZlYXR1cmVzLmFkZCgiUmFuZ2UiKTsKKyAgICAgIGZlYXR1cmVzLmFkZCgiVHJhdmVyc2FsIik7CisgICAgICBmZWF0dXJlcy5hZGQoImJvZ3VzLmJvZ3VzLmJvZ3VzIik7CisgICAgICAKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGUgcm9vdE5vZGU7CisgICAgICBTdHJpbmcgZmVhdHVyZUVsZW1lbnQ7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIHJvb3ROb2RlID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgc3RhdGUgPSByb290Tm9kZS5pc1N1cHBvcnRlZCgiQ29yZSIsICIyLjAiKTsKKyAgICAgIGFzc2VydFRydWUoIkNvcmUyIiwgc3RhdGUpOworICAgICAgZm9yIChpbnQgaW5kZXhOMTAwNzggPSAwOyBpbmRleE4xMDA3OCA8IGZlYXR1cmVzLnNpemUoKTsgaW5kZXhOMTAwNzgrKykgeworICAgICAgICAgIGZlYXR1cmVFbGVtZW50ID0gKFN0cmluZykgZmVhdHVyZXMuZ2V0KGluZGV4TjEwMDc4KTsKKyAgICBzdGF0ZSA9IHJvb3ROb2RlLmlzU3VwcG9ydGVkKGZlYXR1cmVFbGVtZW50LCAiMS4wIik7CisgICAgICAgIH0KKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDgzID0gMDsgaW5kZXhOMTAwODMgPCBmZWF0dXJlcy5zaXplKCk7IGluZGV4TjEwMDgzKyspIHsKKyAgICAgICAgICBmZWF0dXJlRWxlbWVudCA9IChTdHJpbmcpIGZlYXR1cmVzLmdldChpbmRleE4xMDA4Myk7CisgICAgc3RhdGUgPSByb290Tm9kZS5pc1N1cHBvcnRlZChmZWF0dXJlRWxlbWVudCwgIjIuMCIpOworICAgICAgICB9CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMTIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGlzU3VwcG9ydGVkMTIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMTMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaXNTdXBwb3J0ZWQxMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVjNTg2NzQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMTMuamF2YQpAQCAtMCwwICsxLDg0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIENhbGxzIGlzU3VwcG9ydGVkKCJDb3JlIiwiIikgc2hvdWxkIHJldHVybiB0cnVlIGZvciBhbGwgaW1wbGVtZW50YXRpb25zIChieSBleHRlbnNpb24gb2YgY29yZS0xNCkuCisqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtTm9kZS1zdXBwb3J0czwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzExL0RPTS1MZXZlbC0yLWVycmF0YSNjb3JlLTE0Ij5odHRwOi8vd3d3LnczLm9yZy8yMDAwLzExL0RPTS1MZXZlbC0yLWVycmF0YSNjb3JlLTE0PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBpc1N1cHBvcnRlZDEzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBpc1N1cHBvcnRlZDEzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGUgcm9vdE5vZGU7CisgICAgICBib29sZWFuIHN0YXRlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIHJvb3ROb2RlID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgc3RhdGUgPSByb290Tm9kZS5pc1N1cHBvcnRlZCgiQ29yZSIsICIiKTsKKyAgICAgIGFzc2VydFRydWUoIkNvcmUiLCBzdGF0ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMTMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGlzU3VwcG9ydGVkMTMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMTQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvaXNTdXBwb3J0ZWQxNC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJjMGNjNmIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMTQuamF2YQpAQCAtMCwwICsxLDg2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIENhbGxzIGlzU3VwcG9ydGVkKCJDb3JlIixudWxsKSBzaG91bGQgcmV0dXJuIHRydWUgZm9yIGFsbCBpbXBsZW1lbnRhdGlvbnMgKGJ5IGV4dGVuc2lvbiBvZiBjb3JlLTE0KS4KKyogQGF1dGhvciBDdXJ0IEFybm9sZAorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtTm9kZS1zdXBwb3J0cyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1Ob2RlLXN1cHBvcnRzPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMTEvRE9NLUxldmVsLTItZXJyYXRhI2NvcmUtMTQiPmh0dHA6Ly93d3cudzMub3JnLzIwMDAvMTEvRE9NLUxldmVsLTItZXJyYXRhI2NvcmUtMTQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGlzU3VwcG9ydGVkMTQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGlzU3VwcG9ydGVkMTQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSByb290Tm9kZTsKKyAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICBTdHJpbmcgbnVsbFN0cmluZyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICByb290Tm9kZSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgIHN0YXRlID0gcm9vdE5vZGUuaXNTdXBwb3J0ZWQoIkNvcmUiLCBudWxsU3RyaW5nKTsKKyAgICAgIGFzc2VydFRydWUoIkNvcmUiLCBzdGF0ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2lzU3VwcG9ydGVkMTQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGlzU3VwcG9ydGVkMTQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2xvY2FsTmFtZTAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2xvY2FsTmFtZTAxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmI3MzE5MwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbG9jYWxOYW1lMDEuamF2YQpAQCAtMCwwICsxLDEwMiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldExvY2FsTmFtZSgpIiBtZXRob2QgZm9yIGEgTm9kZQorICogICAgIHJldHVybnMgdGhlIGxvY2FsIHBhcnQgb2YgdGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoaXMgbm9kZSwKKyAqICAgICBhbmQgZm9yIG5vZGVzIG9mIGFueSB0eXBlIG90aGVyIHRoYW4gRUxFTUVOVF9OT0RFIGFuZCBBVFRSSUJVVEVfTk9ERQorICogICAgIGFuZCBub2RlcyBjcmVhdGVkIHdpdGggYSBET00gTGV2ZWwgMSBtZXRob2QsIHRoaXMgaXMgbnVsbC4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgZW1wOmFkZHJlc3Mgbm9kZSBhbmQgZ2V0IHRoZSBhdHRyaWJ1dGVzIG9mIHRoaXMgbm9kZS4iICAgCisgKiAgICAgVGhlbiBhcHBseSB0aGUgZ2V0TG9jYWxOYW1lKCkgbWV0aG9kIHRvIHRoZSBlbXA6ZG9tZXN0aWMgYXR0cmlidXRlLgorICogICAgIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiAiZG9tZXN0aWMiLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNMb2NhbE4iPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNMb2NhbE48L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGxvY2FsTmFtZTAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBsb2NhbE5hbWUwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcjsKKyAgICAgIEF0dHIgYWRkckF0dHI7CisgICAgICBTdHJpbmcgbG9jYWxOYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICB0ZXN0QWRkciA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkck5vdE51bGwiLCB0ZXN0QWRkcik7CisgICAgICBhZGRyQXR0ciA9IHRlc3RBZGRyLmdldEF0dHJpYnV0ZU5vZGUoImVtcDpkb21lc3RpYyIpOworICAgICAgbG9jYWxOYW1lID0gYWRkckF0dHIuZ2V0TG9jYWxOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImxvY2FsTmFtZSIsICJkb21lc3RpYyIsIGxvY2FsTmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2xvY2FsTmFtZTAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihsb2NhbE5hbWUwMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbG9jYWxOYW1lMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbG9jYWxOYW1lMDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YzlmM2QxCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9sb2NhbE5hbWUwMi5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgIFRoZSAiZ2V0TG9jYWxOYW1lKCkiIG1ldGhvZCBmb3IgYSBOb2RlCisgKiAgIHJldHVybnMgdGhlIGxvY2FsIHBhcnQgb2YgdGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoaXMgbm9kZSwKKyAqICAgYW5kIGZvciBub2RlcyBvZiBhbnkgdHlwZSBvdGhlciB0aGFuIEVMRU1FTlRfTk9ERSBhbmQgQVRUUklCVVRFX05PREUKKyAqICAgYW5kIG5vZGVzIGNyZWF0ZWQgd2l0aCBhIERPTSBMZXZlbCAxIG1ldGhvZCwgdGhpcyBpcyBudWxsLgorICogICAKKyAqICAgQ3JlYXRlIGFuIG5ldyBFbGVtZW50IHdpdGggdGhlIGNyZWF0ZUVsZW1lbnQoKSBtZXRob2QuCisgKiAgIEludm9rZSB0aGUgImdldExvY2FsTmFtZSgpIiBtZXRob2Qgb24gdGhlIG5ld2x5IGNyZWF0ZWQgZWxlbWVudCAgCisgKiAgIG5vZGUgd2lsbCBjYXVzZSAibnVsbCIgdG8gYmUgcmV0dXJuZWQuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU0xvY2FsTiI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU0xvY2FsTjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgbG9jYWxOYW1lMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGxvY2FsTmFtZTAyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBjcmVhdGVkTm9kZTsKKyAgICAgIFN0cmluZyBsb2NhbE5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBjcmVhdGVkTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50KCJ0ZXN0OmVtcGxveWVlIik7CisgICAgICBsb2NhbE5hbWUgPSBjcmVhdGVkTm9kZS5nZXRMb2NhbE5hbWUoKTsKKyAgICAgIGFzc2VydE51bGwoImxvY2FsTmFtZU51bGwiLCBsb2NhbE5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9sb2NhbE5hbWUwMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obG9jYWxOYW1lMDIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2xvY2FsTmFtZTAzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL2xvY2FsTmFtZTAzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODcyNGMyMQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbG9jYWxOYW1lMDMuamF2YQpAQCAtMCwwICsxLDk1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldExvY2FsTmFtZSgpIiBtZXRob2QgZm9yIGEgTm9kZQorICogICAgIHJldHVybnMgdGhlIGxvY2FsIHBhcnQgb2YgdGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoaXMgbm9kZSwKKyAqICAgICBhbmQgZm9yIG5vZGVzIG9mIGFueSB0eXBlIG90aGVyIHRoYW4gRUxFTUVOVF9OT0RFIGFuZCBBVFRSSUJVVEVfTk9ERQorICogICAgIGFuZCBub2RlcyBjcmVhdGVkIHdpdGggYSBET00gTGV2ZWwgMSBtZXRob2QsIHRoaXMgaXMgbnVsbC4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgZW1wbG95ZWVJZCBub2RlIGFuZCBnZXQgdGhlIGZpcnN0IGNoaWxkIG9mIHRoaXMgbm9kZS4KKyAqICAgICBTaW5jZSB0aGUgZmlyc3QgY2hpbGQgaXMgVGV4dCBub2RlIGludm9raW5nIHRoZSAiZ2V0TG9jYWxOYW1lKCkiICAgCisgKiAgICAgbWV0aG9kIHdpbGwgY2F1c2UgIm51bGwiIHRvIGJlIHJldHVybmVkLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNMb2NhbE4iPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNMb2NhbE48L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIGxvY2FsTmFtZTAzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBsb2NhbE5hbWUwMyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0RW1wbG95ZWU7CisgICAgICBOb2RlIHRleHROb2RlOworICAgICAgU3RyaW5nIGxvY2FsTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZUlkIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgdGV4dE5vZGUgPSB0ZXN0RW1wbG95ZWUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgbG9jYWxOYW1lID0gdGV4dE5vZGUuZ2V0TG9jYWxOYW1lKCk7CisgICAgICBhc3NlcnROdWxsKCJ0ZXh0Tm9kZUxvY2FsTmFtZSIsIGxvY2FsTmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL2xvY2FsTmFtZTAzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihsb2NhbE5hbWUwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbG9jYWxOYW1lMDQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbG9jYWxOYW1lMDQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOGUwNDdhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9sb2NhbE5hbWUwNC5qYXZhCkBAIC0wLDAgKzEsOTggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0TG9jYWxOYW1lKCkiIG1ldGhvZCBmb3IgYSBOb2RlCisgKiAgICAgcmV0dXJucyB0aGUgbG9jYWwgcGFydCBvZiB0aGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhpcyBub2RlLAorICogICAgIGFuZCBmb3Igbm9kZXMgb2YgYW55IHR5cGUgb3RoZXIgdGhhbiBFTEVNRU5UX05PREUgYW5kIEFUVFJJQlVURV9OT0RFCisgKiAgICAgYW5kIG5vZGVzIGNyZWF0ZWQgd2l0aCBhIERPTSBMZXZlbCAxIG1ldGhvZCwgdGhpcyBpcyBudWxsLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBmaXJzdCBlbXBsb3llZSBub2RlIGFuZCBpbnZva2UgdGhlICJnZXRMb2NhbE5hbWUoKSIgICAKKyAqICAgICBtZXRob2QuICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuICJlbXBsb3llZSIuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU0xvY2FsTiI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU0xvY2FsTjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgbG9jYWxOYW1lMDQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIGxvY2FsTmFtZTA0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RFbXBsb3llZTsKKyAgICAgIFN0cmluZyBlbXBsb3llZUxvY2FsTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgdGVzdEVtcGxveWVlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGVtcGxveWVlTG9jYWxOYW1lID0gdGVzdEVtcGxveWVlLmdldExvY2FsTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJsbmFtZSIsICJlbXBsb3llZSIsIGVtcGxveWVlTG9jYWxOYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbG9jYWxOYW1lMDQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKGxvY2FsTmFtZTA0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MzQ2YmEyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczAxLmphdmEKQEAgLTAsMCArMSwxMDggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVXNpbmcgdGhlIG1ldGhvZCBnZXROYW1lZEl0ZW1OUywgcmV0cmVpdmUgdGhlIGVudGl0eSAiZW50MSIgYW5kIG5vdGF0aW9uICJub3RhdGlvbjEiIAorICogIGZyb20gYSBOYW1lZE5vZGVNYXAgb2YgdGhpcyBEb2N1bWVudFR5cGVzIGVudGl0aWVzIGFuZCBub3RhdGlvbnMuCisgKiAgQm90aCBzaG91bGQgYmUgbnVsbCBzaW5jZSBlbnRpdGllcyBhbmQgbm90YXRpb25zIGFyZSBub3QgbmFtZXNwYWNlZC4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXROYW1lZEl0ZW1OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldE5hbWVkSXRlbU5TPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTQwNyI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTQwNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL01lbWJlci93M2MtZG9tLWlnLzIwMDNOb3YvMDAxNi5odG1sIj5odHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL01lbWJlci93M2MtZG9tLWlnLzIwMDNOb3YvMDAxNi5odG1sPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBuYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczAxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBOYW1lZE5vZGVNYXAgZW50aXRpZXM7CisgICAgICBOYW1lZE5vZGVNYXAgbm90YXRpb25zOworICAgICAgRW50aXR5IGVudGl0eTsKKyAgICAgIE5vdGF0aW9uIG5vdGF0aW9uOworICAgICAgU3RyaW5nIGVudGl0eU5hbWU7CisgICAgICBTdHJpbmcgbm90YXRpb25OYW1lOworICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgZW50aXRpZXMgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdGllc05vdE51bGwiLCBlbnRpdGllcyk7CisgICAgICBub3RhdGlvbnMgPSBkb2NUeXBlLmdldE5vdGF0aW9ucygpOworICAgICAgYXNzZXJ0Tm90TnVsbCgibm90YXRpb25zTm90TnVsbCIsIG5vdGF0aW9ucyk7CisgICAgICBlbnRpdHkgPSAoRW50aXR5KSBlbnRpdGllcy5nZXROYW1lZEl0ZW1OUyhudWxsTlMsICJlbnQxIik7CisgICAgICBhc3NlcnROdWxsKCJlbnRpdHlOdWxsIiwgZW50aXR5KTsKKyAgICAgIG5vdGF0aW9uID0gKE5vdGF0aW9uKSBub3RhdGlvbnMuZ2V0TmFtZWRJdGVtTlMobnVsbE5TLCAibm90YXRpb24xIik7CisgICAgICBhc3NlcnROdWxsKCJub3RhdGlvbk51bGwiLCBub3RhdGlvbik7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmExZGEwMWEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDIuamF2YQpAQCAtMCwwICsxLDEwMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCBnZXROYW1lZEl0ZW1OUyByZXRyaWV2ZXMgYSBub2RlIHNwZWNpZmllZCBieSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLiAKKyAqICAKKyAqICBVc2luZyB0aGUgbWV0aG9kIGdldE5hbWVkSXRlbU5TLCByZXRyZWl2ZSBhbiBhdHRyaWJ1dGUgbm9kZSBoYXZpbmcgbmFtZXNwYWNlVVJJPWh0dHA6Ly93d3cubmlzdC5nb3YKKyAqICBhbmQgbG9jYWxOYW1lPWRvbWVzdGljLCBmcm9tIGEgTmFtZWROb2RlTWFwIG9mIGF0dHJpYnV0ZSBub2RlcywgZm9yIHRoZSBzZWNvbmQgZWxlbWVudCAKKyAqICB3aG9zZSBuYW1lc3BhY2VVUkk9aHR0cDovL3d3dy5uaXN0LmdvdiBhbmQgbG9jYWxOYW1lPWFkZHJlc3MuICBWZXJpZnkgaWYgdGhlIGF0dHIgbm9kZSAKKyAqICBoYXMgYmVlbiByZXRyZWl2ZWQgc3VjY2Vzc2Z1bGx5IGJ5IGNoZWNraW5nIGl0cyBub2RlTmFtZSBhdHR0cmlidXRlLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldE5hbWVkSXRlbU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0TmFtZWRJdGVtTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIE5vZGUgZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBTdHJpbmcgYXR0ck5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImFkZHJlc3MiKTsKKyAgICAgIGVsZW1lbnQgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXR0cmlidXRlID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAiZG9tZXN0aWMiKTsKKyAgICAgIGF0dHJOYW1lID0gYXR0cmlidXRlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDIiLCAiZW1wOmRvbWVzdGljIiwgYXR0ck5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczAyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihuYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczAzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNzBlZTIzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczAzLmphdmEKQEAgLTAsMCArMSwxMDUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBtZXRob2QgZ2V0TmFtZWRJdGVtTlMgcmV0cmlldmVzIGEgbm9kZSBzcGVjaWZpZWQgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4gCisgKiAgIAorICogICAgIENyZWF0ZSBhIG5ldyBFbGVtZW50IG5vZGUgYW5kIGFkZCAyIG5ldyBhdHRyaWJ1dGUgbm9kZXMgaGF2aW5nIHRoZSBzYW1lIGxvY2FsIG5hbWUgYnV0IGRpZmZlcmVudAorICogICAgIG5hbWVzcGFjZSBuYW1lcyBhbmQgbmFtZXNwYWNlIHByZWZpeGVzIHRvIGl0LiAgVXNpbmcgdGhlIGdldE5hbWVkSXRlbU5TIHJldHJlaXZlIHRoZSBzZWNvbmQgYXR0cmlidXRlIG5vZGUuICAKKyAqICAgICBWZXJpZnkgaWYgdGhlIGF0dHIgbm9kZSBoYXMgYmVlbiByZXRyZWl2ZWQgc3VjY2Vzc2Z1bGx5IGJ5IGNoZWNraW5nIGl0cyBub2RlTmFtZSBhdHR0cmlidXRlLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldE5hbWVkSXRlbU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0TmFtZWRJdGVtTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIE5vZGUgZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgQXR0ciBuZXdBdHRyMTsKKyAgICAgIEF0dHIgbmV3QXR0cjI7CisgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJyb290Iik7CisgICAgICBuZXdBdHRyMSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL0wxIiwgIkwxOmF0dCIpOworICAgICAgbmV3QXR0cmlidXRlID0gKChFbGVtZW50KSAvKk5vZGUgKi9lbGVtZW50KS5zZXRBdHRyaWJ1dGVOb2RlTlMobmV3QXR0cjEpOworICAgICAgbmV3QXR0cjIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9MMiIsICJMMjphdHQiKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9ICgoRWxlbWVudCkgLypOb2RlICovZWxlbWVudCkuc2V0QXR0cmlidXRlTm9kZU5TKG5ld0F0dHIyKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vTDIiLCAiYXR0Iik7CisgICAgICBhdHRyTmFtZSA9IGF0dHJpYnV0ZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczAzIiwgIkwyOmF0dCIsIGF0dHJOYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwNC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGU5MDFiMwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwNC5qYXZhCkBAIC0wLDAgKzEsMTA2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgbWV0aG9kIGdldE5hbWVkSXRlbU5TIHJldHJpZXZlcyBhIG5vZGUgc3BlY2lmaWVkIGJ5IGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkuIAorICogICAKKyAqICAgICBSZXRyZWl2ZSB0aGUgc2Vjb25kIGFkZHJlc3MgZWxlbWVudCBub2RlIGhhdmluZyBsb2NhbE5hbWU9YWRycmVzcy4KKyAqICAgICBDcmVhdGUgYSBuZXcgYXR0cmlidXRlIG5vZGUgaGF2aW5nIHRoZSBzYW1lIG5hbWUgYXMgYW4gZXhpc3Rpbmcgbm9kZSBidXQgZGlmZmVyZW50IG5hbWVzcGFjZVVSSQorICogICAgIGFuZCBhZGQgaXQgdG8gdGhpcyBlbGVtZW50LiAgVXNpbmcgdGhlIGdldE5hbWVkSXRlbU5TIHJldHJlaXZlIHRoZSBuZXdseSBjcmVhdGVkIGF0dHJpYnV0ZSAKKyAqICAgICBub2RlIGZyb20gYSBub2RlbWFwIG9mIGF0dHJpYnV0ZXMgb2YgdGhlIHJldHJlaXZlIGVsZW1lbnQgbm9kZS4KKyAqICAgICBWZXJpZnkgaWYgdGhlIGF0dHIgbm9kZSBoYXMgYmVlbiByZXRyZWl2ZWQgc3VjY2Vzc2Z1bGx5IGJ5IGNoZWNraW5nIGl0cyBub2RlTmFtZSBhdHR0cmlidXRlLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldE5hbWVkSXRlbU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0TmFtZWRJdGVtTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICBBdHRyIG5ld0F0dHIxOworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJhZGRyZXNzIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBuZXdBdHRyMSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL0wxIiwgInN0cmVldCIpOworICAgICAgbmV3QXR0cmlidXRlID0gZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMobmV3QXR0cjEpOworICAgICAgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXR0cmlidXRlID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9MMSIsICJzdHJlZXQiKTsKKyAgICAgIGF0dHJOYW1lID0gYXR0cmlidXRlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDQiLCAic3RyZWV0IiwgYXR0ck5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczA0IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihuYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczA0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczA1LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NmY5MzdhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczA1LmphdmEKQEAgLTAsMCArMSw5OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIGdldE5hbWVkSXRlbU5TIHJldHJpZXZlcyBhIG5vZGUgc3BlY2lmaWVkIGJ5IGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkuIAorICogIAorICogIFJldHJlaWV2ZSB0aGUgc2Vjb25kIGFkZHJlc3MgZWxlbWVudCBhbmQgaXRzIGF0dHJpYnV0ZSBpbnRvIGEgbmFtZWQgbm9kZSBtYXAuCisgKiAgVHJ5IHJldHJlaXZpbmcgdGhlIHN0cmVldCBhdHRyaWJ1dGUgZnJvbSB0aGUgbmFtZWRub2RlbWFwIHVzaW5nIHRoZQorICogIGRlZmF1bHQgbmFtZXNwYWNlIHVyaSBhbmQgdGhlIHN0cmVldCBhdHRyaWJ1dGUgbmFtZS4gIFNpbmNlIHRoZSBkZWZhdWx0CisgKiAgbmFtZXNwYWNlIGRvZXNub3QgYXBwbHkgdG8gYXR0cmlidXRlcyB0aGlzIHNob3VsZCByZXR1cm4gbnVsbC4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXROYW1lZEl0ZW1OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldE5hbWVkSXRlbU5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBuYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczA1IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczA1KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIGVsZW1lbnQ7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJhZGRyZXNzIik7CisgICAgICBlbGVtZW50ID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKCIqIiwgInN0cmVldCIpOworICAgICAgYXNzZXJ0TnVsbCgibmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwNSIsIGF0dHJpYnV0ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDYuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwNi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRlZTVhOTkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDYuamF2YQpAQCAtMCwwICsxLDEwOSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgUmV0cmVpdmUgdGhlIHNlY29uZCBhZGRyZXNzIGVsZW1lbnQgbm9kZSBoYXZpbmcgbG9jYWxOYW1lPWFkcnJlc3MuICBSZXRyZWl2ZSB0aGUgYXR0cmlidXRlcyAKKyAqICAgICBvZiB0aGlzIGVsZW1lbnQgaW50byAyIG5vZGVtYXBzLiAgQ3JlYXRlIGEgbmV3IGF0dHJpYnV0ZSBub2RlIGFuZCBhZGQgaXQgdG8gdGhpcyBlbGVtZW50LiAgCisgKiAgICAgU2luY2UgTmFtZWROb2RlTWFwcyBhcmUgbGl2ZSBlYWNoIG9uZSBzaG91bGQgZ2V0IHVwZGF0ZWQsIHVzaW5nIHRoZSBnZXROYW1lZEl0ZW1OUyByZXRyZWl2ZSAKKyAqICAgICB0aGUgbmV3bHkgY3JlYXRlZCBhdHRyaWJ1dGUgZnJvbSBlYWNoIG5vZGUgbWFwLgorICogICAgIFZlcmlmeSBpZiB0aGUgYXR0ciBub2RlIGhhcyBiZWVuIHJldHJlaXZlZCBzdWNjZXNzZnVsbHkgYnkgY2hlY2tpbmcgaXRzIG5vZGVOYW1lIGF0dHRyaWJ1dGUuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0TmFtZWRJdGVtTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXROYW1lZEl0ZW1OUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwNiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwNihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXNNYXAxOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXNNYXAyOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICBBdHRyIG5ld0F0dHIxOworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJhZGRyZXNzIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyaWJ1dGVzTWFwMSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXR0cmlidXRlc01hcDIgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIG5ld0F0dHIxID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vTDEiLCAic3RyZWV0Iik7CisgICAgICBuZXdBdHRyaWJ1dGUgPSBlbGVtZW50LnNldEF0dHJpYnV0ZU5vZGVOUyhuZXdBdHRyMSk7CisgICAgICBhdHRyaWJ1dGUgPSAoQXR0cikgYXR0cmlidXRlc01hcDEuZ2V0TmFtZWRJdGVtTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9MMSIsICJzdHJlZXQiKTsKKyAgICAgIGF0dHJOYW1lID0gYXR0cmlidXRlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zTWFwMTA2IiwgInN0cmVldCIsIGF0dHJOYW1lKTsKKyAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzTWFwMi5nZXROYW1lZEl0ZW1OUygiaHR0cDovL3d3dy53My5vcmcvRE9NL0wxIiwgInN0cmVldCIpOworICAgICAgYXR0ck5hbWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnNNYXAyMDYiLCAic3RyZWV0IiwgYXR0ck5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczA2IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihuYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczA2LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YjJlZDA3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczAxLmphdmEKQEAgLTAsMCArMSw5OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCByZW1vdmVOYW1lZEl0ZW1OUyByZW1vdmVzIGEgbm9kZSBzcGVjaWZpZWQgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIAorICogIAorICogIFJldHJlaXZlIGFuIGF0dHJpYnV0ZSBub2RlIGFuZCB0aGVuIHJlbW92ZSBmcm9tIHRoZSBOYW1lZE5vZGVNYXAuICBWZXJpZnkgaWYgdGhlIGF0dHJpYnV0ZQorICogIG5vZGUgd2FzIGFjdHVhbGx5IHJlbW92ZSBmcm9tIHRoZSBub2RlIG1hcC4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1ENThCMTkzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRDU4QjE5MzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIGVsZW1lbnQ7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImFkZHJlc3MiKTsKKyAgICAgIGVsZW1lbnQgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXR0cmlidXRlID0gKEF0dHIpIGF0dHJpYnV0ZXMucmVtb3ZlTmFtZWRJdGVtTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAiZG9tZXN0aWMiKTsKKyAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImRvbWVzdGljIik7CisgICAgICBhc3NlcnROdWxsKCJuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczAxIiwgYXR0cmlidXRlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczAyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjRhNDUxOAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMi5qYXZhCkBAIC0wLDAgKzEsMTA5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgVGhlIG1ldGhvZCByZW1vdmVOYW1lZEl0ZW1OUyByZW1vdmVzIGEgbm9kZSBzcGVjaWZpZWQgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIAorICogICAgQSByZW1vdmVkIGF0dHJpYnV0ZSBtYXkgYmUga25vd24gdG8gaGF2ZSBhIGRlZmF1bHQgdmFsdWUgd2hlbiB0aGlzIG1hcCBjb250YWlucyB0aGUgCisgKiAgICBhdHRyaWJ1dGVzIGF0dGFjaGVkIHRvIGFuIGVsZW1lbnQsIGFzIHJldHVybmVkIGJ5IHRoZSBhdHRyaWJ1dGVzIGF0dHJpYnV0ZSBvZiB0aGUgTm9kZSAKKyAqICAgIGludGVyZmFjZS4gSWYgc28sIGFuIGF0dHJpYnV0ZSBpbW1lZGlhdGVseSBhcHBlYXJzIGNvbnRhaW5pbmcgdGhlIGRlZmF1bHQgdmFsdWUgYXMgd2VsbCAKKyAqICAgIGFzIHRoZSBjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSBVUkksIGxvY2FsIG5hbWUsIGFuZCBwcmVmaXggd2hlbiBhcHBsaWNhYmxlLgorICogICAgIAorICogIFJldHJlaXZlIGEgZGVmYXVsdCBhdHRyaWJ1dGUgbm9kZS4gIFJlbW92ZSBpdCBmcm9tIHRoZSBOb2RlTWFwLiAgQ2hlY2sgaWYgYSBuZXcgb25lIGltbWVkaWF0ZWx5CisgKiAgYXBwZWFycyBjb250YWluaW5nIHRoZSBkZWZhdWx0IHZhbHVlLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUQ1OEIxOTMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1ENThCMTkzPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUsCitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcudmFsaWRhdGluZworICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIGVsZW1lbnQ7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKyAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAiZW1wbG95ZWUiKTsKKyAgICAgIGVsZW1lbnQgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXR0cmlidXRlID0gKEF0dHIpIGF0dHJpYnV0ZXMucmVtb3ZlTmFtZWRJdGVtTlMobnVsbE5TLCAiZGVmYXVsdEF0dHIiKTsKKyAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKG51bGxOUywgImRlZmF1bHRBdHRyIik7CisgICAgICBhdHRyVmFsdWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczAyIiwgYXR0cmlidXRlKTsKKyAgICAgIGFzc2VydEVxdWFscygibmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMl9hdHRyVmFsdWUiLCAiZGVmYXVsdFZhbCIsIGF0dHJWYWx1ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2MWJhN2YKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDMuamF2YQpAQCAtMCwwICsxLDEwNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICBUaGUgbWV0aG9kIHJlbW92ZU5hbWVkSXRlbU5TIHJlbW92ZXMgYSBub2RlIHNwZWNpZmllZCBieSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgCisgKiAgICAgICAKKyAqICBDcmVhdGUgYSBuZXcgZWxlbWVudCBub2RlIGFuZCBhZGQgMiBuZXcgYXR0cmlidXRlIG5vZGVzIHRvIGl0IHRoYXQgaGF2ZSB0aGUgc2FtZSBsb2NhbE5hbWUKKyAqICBidXQgZGlmZmVyZW50IG5hbWVzcGFjZVVSSSdzLiAgUmVtb3ZlIHRoZSBmaXJzdCBhdHRyaWJ1dGUgbm9kZSBmcm9tIHRoZSBuYW1lZE5vZGVNYXAgb2YgdGhlCisgKiAgbmV3IGVsZW1lbnQgbm9kZSBhbmQgY2hlY2sgdG8gc2VlIHRoYXQgdGhlIHNlY29uZCBhdHRyaWJ1dGUgc3RpbGwgZXhpc3RzLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUQ1OEIxOTMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1ENThCMTkzPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczAzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczAzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIE5vZGUgZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBBdHRyIGF0dHJpYnV0ZTE7CisgICAgICBBdHRyIGF0dHJpYnV0ZTI7CisgICAgICBTdHJpbmcgbm9kZU5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJyb290Iik7CisgICAgICBhdHRyaWJ1dGUxID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vTDEiLCAiTDE6YXR0Iik7CisgICAgICBuZXdBdHRyaWJ1dGUgPSAoKEVsZW1lbnQpIC8qTm9kZSAqL2VsZW1lbnQpLnNldEF0dHJpYnV0ZU5vZGVOUyhhdHRyaWJ1dGUxKTsKKyAgICAgIGF0dHJpYnV0ZTIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9MMiIsICJMMjphdHQiKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9ICgoRWxlbWVudCkgLypOb2RlICovZWxlbWVudCkuc2V0QXR0cmlidXRlTm9kZU5TKGF0dHJpYnV0ZTIpOworICAgICAgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXR0cmlidXRlID0gKEF0dHIpIGF0dHJpYnV0ZXMucmVtb3ZlTmFtZWRJdGVtTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9MMSIsICJhdHQiKTsKKyAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vTDIiLCAiYXR0Iik7CisgICAgICBub2RlTmFtZSA9IGF0dHJpYnV0ZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczAyIiwgIkwyOmF0dCIsIG5vZGVOYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTdjMzYxYQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNC5qYXZhCkBAIC0wLDAgKzEsMTAyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgIFRoZSBtZXRob2QgcmVtb3ZlTmFtZWRJdGVtTlMgcmVtb3ZlcyBhIG5vZGUgc3BlY2lmaWVkIGJ5IGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSAKKyAqICAgICAgIAorICogIEF0dGVtcHQgdG8gcmVtb3ZlIHRoZSB4bWxucyBhbmQgZG1zdGMgYXR0cmlidXRlcyBvZiB0aGUgZmlyc3QgZWxlbWVudCBub2RlIHdpdGggdGhlIGxvY2FsTmFtZQorICogIGVtcGxveWVlLiAgVmVyaWZ5IGlmIHRoZSAyIGF0dHJpYnV0ZXMgd2VyZSBzdWNjZXNzZnVsbHkgcmVtb3ZlZC4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1ENThCMTkzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRDU4QjE5MzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIGVsZW1lbnQ7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIEF0dHIgYXR0cmlidXRlUmVtb3ZlZDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCIqIiwgImVtcGxveWVlIik7CisgICAgICBlbGVtZW50ID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGF0dHJpYnV0ZVJlbW92ZWQgPSAoQXR0cikgYXR0cmlidXRlcy5yZW1vdmVOYW1lZEl0ZW1OUygiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iLCAieG1sbnMiKTsKKyAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIsICJ4bWxucyIpOworICAgICAgYXNzZXJ0TnVsbCgibmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNF8xIiwgYXR0cmlidXRlKTsKKyAgICAgIGF0dHJpYnV0ZVJlbW92ZWQgPSAoQXR0cikgYXR0cmlidXRlcy5yZW1vdmVOYW1lZEl0ZW1OUygiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iLCAiZG1zdGMiKTsKKyAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIsICJkbXN0YyIpOworICAgICAgYXNzZXJ0TnVsbCgibmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNF8yIiwgYXR0cmlidXRlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA1LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDU5NzFmNwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNS5qYXZhCkBAIC0wLDAgKzEsMTMxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFJldHJlaXZlIGFuIGVudGl0eSBhbmQgbm90YXRpb24gbm9kZSBhbmQgcmVtb3ZlIHRoZSBmaXJzdCBub3RhdGlvbiBmcm9tIHRoZSAKKyAqICBlbnRpdHkgbm9kZSBtYXAgYW5kIGZpcnN0IGVudGl0eSBub2RlIGZyb20gdGhlIG5vdGF0aW9uIG1hcC4gIFNpbmNlIGJvdGggdGhlc2UKKyAqICBtYXBzIGFyZSByZWFkb25seSwgYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgc2hvdWxkIGJlIHJhaXNlZC4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1zZXROYW1lZEl0ZW1OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXNldE5hbWVkSXRlbU5TPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTQwNyI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTQwNzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL01lbWJlci93M2MtZG9tLWlnLzIwMDNOb3YvMDAxNi5odG1sIj5odHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL01lbWJlci93M2MtZG9tLWlnLzIwMDNOb3YvMDAxNi5odG1sPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA1IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA1KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdGllczsKKyAgICAgIE5hbWVkTm9kZU1hcCBub3RhdGlvbnM7CisgICAgICBOb2RlIHJlbW92ZWROb2RlOworICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBlbnRpdGllcyA9IGRvY1R5cGUuZ2V0RW50aXRpZXMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudGl0aWVzTm90TnVsbCIsIGVudGl0aWVzKTsKKyAgICAgIG5vdGF0aW9ucyA9IGRvY1R5cGUuZ2V0Tm90YXRpb25zKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJub3RhdGlvbnNOb3ROdWxsIiwgbm90YXRpb25zKTsKKyAgICAgIAorICAgICAgdHJ5IHsKKyAgICAgIHJlbW92ZWROb2RlID0gZW50aXRpZXMucmVtb3ZlTmFtZWRJdGVtTlMobnVsbE5TLCAiZW50MSIpOworICAgICAgZmFpbCgiZW50aXR5X3Rocm93X0RPTUV4Y2VwdGlvbiIpOworICAgICAKKyAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICBzd2l0Y2ggKGV4LmNvZGUpIHsKKyAgICAgIGNhc2UgOCA6IAorICAgICAgIGJyZWFrOworICAgICAgY2FzZSA3IDogCisgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICB0aHJvdyBleDsKKyAgICAgICAgICB9CisgICAgICB9IAorCisgICAgICB0cnkgeworICAgICAgcmVtb3ZlZE5vZGUgPSBub3RhdGlvbnMucmVtb3ZlTmFtZWRJdGVtTlMobnVsbE5TLCAibm90YXRpb24xIik7CisgICAgICBmYWlsKCJub3RhdGlvbl90aHJvd19ET01FeGNlcHRpb24iKTsKKyAgICAgCisgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgc3dpdGNoIChleC5jb2RlKSB7CisgICAgICBjYXNlIDggOiAKKyAgICAgICBicmVhazsKKyAgICAgIGNhc2UgNyA6IAorICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgdGhyb3cgZXg7CisgICAgICAgICAgfQorICAgICAgfSAKK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA2LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDJkNmVmZgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNi5qYXZhCkBAIC0wLDAgKzEsMTA3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgVGhlIG1ldGhvZCByZW1vdmVOYW1lZEl0ZW1OUyByZW1vdmVzIGEgbm9kZSB1c2luZyBpdHMgbmFtZXNwYWNlVVJJIGFuZCBsb2NhbE5hbWUgYW5kIAorICogICAgcmFpc2VzIGEgTk9UX0ZPVU5EX0VSUiBpZiB0aGVyZSBpcyBubyBub2RlIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lc3BhY2VVUkkgYW5kIAorICogICAgbG9jYWxOYW1lIGluIHRoaXMgbWFwCisgKiAgICAgCisgKiAgUmV0cmVpdmUgYW4gYXR0cmlidXRlIG5vZGUgaW50byBhIG5hbWVkbm9kZW1hcC4gIFdoaWxlIHJlbW92aW5nIGl0IGZyb20gdGhlIG1hcCBzcGVjaWZ5CisgKiAgYW4gaW5jb3JyZWN0IG5hbWVzcGFjZVVSSS4gIFRoaXMgc2hvdWxkIHJhaXNlIGEgTk9UX0ZPVU5EX0VSUi4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1ENThCMTkzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRDU4QjE5MzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIGVsZW1lbnQ7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImVtcGxveWVlIik7CisgICAgICBlbGVtZW50ID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgYXR0cmlidXRlID0gKEF0dHIpIGF0dHJpYnV0ZXMucmVtb3ZlTmFtZWRJdGVtTlMoImh0dHA6Ly93d3cuTmlzdC5nb3YiLCAiZG9tZXN0aWMiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT1RfRk9VTkRfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDYiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDYuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg2YjllZTQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDcuamF2YQpAQCAtMCwwICsxLDEwNyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgIFRoZSBtZXRob2QgcmVtb3ZlTmFtZWRJdGVtTlMgcmVtb3ZlcyBhIG5vZGUgdXNpbmcgaXRzIG5hbWVzcGFjZVVSSSBhbmQgbG9jYWxOYW1lIGFuZCAKKyAqICAgIHJhaXNlcyBhIE5PVF9GT1VORF9FUlIgaWYgdGhlcmUgaXMgbm8gbm9kZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZXNwYWNlVVJJIGFuZCAKKyAqICAgIGxvY2FsTmFtZSBpbiB0aGlzIG1hcAorICogICAgIAorICogIFJldHJlaXZlIGFuIGF0dHJpYnV0ZSBub2RlIGZyb20gYSBuYW1lZG5vZGVtYXAuICBXaGlsZSByZW1vdmluZyBpdCBmcm9tIHRoZSBtYXAgc3BlY2lmeQorICogIGFuIGluY29ycmVjdCBsb2NhbE5hbWUuICBUaGlzIHNob3VsZCByYWlzZSBhIE5PVF9GT1VORF9FUlIuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRDU4QjE5MyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUQ1OEIxOTM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDcgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDcoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgTm9kZSBlbGVtZW50OworICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJlbXBsb3llZSIpOworICAgICAgZWxlbWVudCA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLnJlbW92ZU5hbWVkSXRlbU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImRvbWVzdGljIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9UX0ZPVU5EX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA3IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA3LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA4LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDguamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YzRjYWQzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA4LmphdmEKQEAgLTAsMCArMSwxMTAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICBUaGUgbWV0aG9kIHJlbW92ZU5hbWVkSXRlbU5TIHJlbW92ZXMgYSBub2RlIHVzaW5nIGl0cyBuYW1lc3BhY2VVUkkgYW5kIGxvY2FsTmFtZSBhbmQgCisgKiAgICByYWlzZXMgYSBOT1RfRk9VTkRfRVJSIGlmIHRoZXJlIGlzIG5vIG5vZGUgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWVzcGFjZVVSSSBhbmQgCisgKiAgICBsb2NhbE5hbWUgaW4gdGhpcyBtYXAKKyAqICAgICAKKyAqICBSZXRyZWl2ZSBhbiBhdHRyaWJ1dGUgbm9kZSBmcm9tIGEgbmFtZWRub2RlbWFwLiAgUmVtb3ZlIHRoZSBhdHRyaWJ1dGUgbm9kZSBmcm9tIHRoZSBkb2N1bWVudAorICogIG9iamVjdC4gIFNpbmNlIE5hbWVkTm9kZU1hcHMgYXJlIGxpdmUgaXQgc2hvdWxkIGFsc28gYXV0b21hdGljYWxseSBnZXQgcmVtb3ZlZCBmcm9tIAorICogIHRoZSBub2RlIG1hcC4gIEFuZCBzbyBpZiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gcmVtb3ZlIGl0IHVzaW5nIHJlbW92ZUF0dHJpYnV0ZU5TLCB0aGlzIHNob3VsZCAKKyAqICByYWlzZSBhIE5PVF9GT1VORF9FUlIuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRDU4QjE5MyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUQ1OEIxOTM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDggZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDgoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJhZGRyZXNzIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImRvbWVzdGljIik7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLnJlbW92ZU5hbWVkSXRlbU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImRvbWVzdGljIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9UX0ZPVU5EX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA4IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA4LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA5LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMDRlNDJmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA5LmphdmEKQEAgLTAsMCArMSwxMDIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgVGhlIG1ldGhvZCByZW1vdmVOYW1lZEl0ZW1OUyByZW1vdmVzIGEgbm9kZSB1c2luZyBpdHMgbmFtZXNwYWNlVVJJIGFuZCBsb2NhbE5hbWUgYW5kIAorICogICAgcmFpc2VzIGEgTk9UX0ZPVU5EX0VSUiBpZiB0aGVyZSBpcyBubyBub2RlIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lc3BhY2VVUkkgYW5kIAorICogICAgbG9jYWxOYW1lIGluIHRoaXMgbWFwCisgKiAgICAgCisgKiAgUmV0cmVpdmUgYW4gYXR0cmlidXRlIG5vZGUuICBSZW1vdmUgdGhlIGF0dHJpYnV0ZSBub2RlIGZyb20gdGhlIG5vZGUgbWFwLiAgCisgKiAgQ2hlY2sgdGhlIGVsZW1lbnQgb2JqZWN0IHRvIGVuc3VyZSB0aGF0IHRoZSBhdHRyaWJ1dGUgbm9kZSBoYXMgYmVlbiByZW1vdmVkIGZyb20gaXQuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRDU4QjE5MyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUQ1OEIxOTM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDkgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDkoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgTmFtZWROb2RlTWFwIG5ld0F0dHJpYnV0ZXM7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImFkZHJlc3MiKTsKKyAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLnJlbW92ZU5hbWVkSXRlbU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImRvbWVzdGljIik7CisgICAgICBuZXdBdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBhdHRyaWJ1dGUgPSAoQXR0cikgbmV3QXR0cmlidXRlcy5nZXROYW1lZEl0ZW1OUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJkb21lc3RpYyIpOworICAgICAgYXNzZXJ0TnVsbCgibmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwOSIsIGF0dHJpYnV0ZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDkiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDkuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxMTI0NjMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDEuamF2YQpAQCAtMCwwICsxLDEwNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCBzZXROYW1lZEl0ZW1OUyBhZGRzIGEgbm9kZSB1c2luZyBpdHMgbmFtZXNwYWNlVVJJIGFuZCBsb2NhbE5hbWUuIElmIGEgbm9kZSB3aXRoIAorICogIHRoYXQgbmFtZXNwYWNlIFVSSSBhbmQgdGhhdCBsb2NhbCBuYW1lIGlzIGFscmVhZHkgcHJlc2VudCBpbiB0aGlzIG1hcCwgaXQgaXMgcmVwbGFjZWQgCisgKiAgYnkgdGhlIG5ldyBvbmUuCisgKiAgCisgKiAgUmV0cmVpdmUgdGhlIGZpcnN0IGVsZW1lbnQgd2hvc2UgbG9jYWxOYW1lIGlzIGFkZHJlc3MgYW5kIG5hbWVzcGFjZVVSSSBodHRwOi8vd3d3Lm5pc3QuZ292IiwgCisgKiAgYW5kIHB1dCBpdHMgYXR0cmlidXRlcyBpbnRvIGEgbmFtZWQgbm9kZSBtYXAuICBDcmVhdGUgYSBuZXcgYXR0cmlidXRlIG5vZGUgYW5kIGFkZCBpdCB0byB0aGlzIG1hcC4gIAorICogIFZlcmlmeSBpZiB0aGUgYXR0ciBub2RlIHdhcyBzdWNjZXNzZnVsbHkgYWRkZWQgYnkgY2hlY2tpbmcgdGhlIG5vZGVOYW1lIG9mIHRoZSByZXRyZWl2ZWQgYXR0dHJpYnV0ZS4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXROYW1lZEl0ZW1OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldE5hbWVkSXRlbU5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczAxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIE5vZGUgZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBBdHRyIG5ld0F0dHIxOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBTdHJpbmcgYXR0ck5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAiYWRkcmVzcyIpOworICAgICAgZWxlbWVudCA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBuZXdBdHRyMSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL0wxIiwgInN0cmVldHMiKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9ICgoRWxlbWVudCkgLypOb2RlICovZWxlbWVudCkuc2V0QXR0cmlidXRlTm9kZU5TKG5ld0F0dHIxKTsKKyAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vTDEiLCAic3RyZWV0cyIpOworICAgICAgYXR0ck5hbWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwMSIsICJzdHJlZXRzIiwgYXR0ck5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczAyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNjYwNjk0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczAyLmphdmEKQEAgLTAsMCArMSwxMDQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2Qgc2V0TmFtZWRJdGVtTlMgYWRkcyBhIG5vZGUgdXNpbmcgaXRzIG5hbWVzcGFjZVVSSSBhbmQgbG9jYWxOYW1lLiBJZiBhIG5vZGUgd2l0aCAKKyAqICB0aGF0IG5hbWVzcGFjZSBVUkkgYW5kIHRoYXQgbG9jYWwgbmFtZSBpcyBhbHJlYWR5IHByZXNlbnQgaW4gdGhpcyBtYXAsIGl0IGlzIHJlcGxhY2VkIAorICogIGJ5IHRoZSBuZXcgb25lLgorICogIAorICogIENyZWF0ZSBhIG5ldyBlbGVtZW50IGFuZCBhdHRyaWJ1dGUgTm9kZSBhbmQgYWRkIHRoZSBuZXdseSBjcmVhdGVkIGF0dHJpYnV0ZSBub2RlIHRvIHRoZSBlbGVtZW50cyAKKyAqICBOYW1lZE5vZGVNYXAuICBWZXJpZnkgaWYgdGhlIG5ldyBhdHRyIG5vZGUgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGFkZGVkIHRvIHRoZSBtYXAgYnkgY2hlY2tpbmcgCisgKiAgdGhlIG5vZGVOYW1lIG9mIHRoZSByZXRyZWl2ZWQgYXR0dHJpYnV0ZSBmcm9tIHRoZSBsaXN0IG9mIGF0dHJpYnV0ZSBub2RlcyBpbiB0aGlzIG1hcC4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1zZXROYW1lZEl0ZW1OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXNldE5hbWVkSXRlbU5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczAyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczAyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgQXR0ciBhdHRyaWJ1dGUxOworICAgICAgTm9kZSBuZXdOb2RlOworICAgICAgU3RyaW5nIGF0dHJOYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLCAicm9vdCIpOworICAgICAgYXR0cmlidXRlMSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL0wxIiwgIkwxOmF0dCIpOworICAgICAgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgbmV3Tm9kZSA9IGF0dHJpYnV0ZXMuc2V0TmFtZWRJdGVtTlMoYXR0cmlidXRlMSk7CisgICAgICBhdHRyaWJ1dGUgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW1OUygiaHR0cDovL3d3dy53My5vcmcvRE9NL0wxIiwgImF0dCIpOworICAgICAgYXR0ck5hbWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwMiIsICJMMTphdHQiLCBhdHRyTmFtZSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJjYzgyNzkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDMuamF2YQpAQCAtMCwwICsxLDEyNSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIHNldE5hbWVkSXRlbU5TIGFkZHMgYSBub2RlIHVzaW5nIGl0cyBuYW1lc3BhY2VVUkkgYW5kIGxvY2FsTmFtZSBhbmQgCisgKiAgcmFpc2VzIGEgV1JPTkdfRE9DVU1FTlRfRVJSIGlmIGFyZyB3YXMgY3JlYXRlZCBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIAorICogIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyBtYXAuCisgKiAgCisgKiAgUmV0cmVpZXZlIHRoZSBzZWNvbmQgZWxlbWVudCB3aG9zZSBsb2NhbCBuYW1lIGlzIGFkZHJlc3MgYW5kIGl0cyBhdHRyaWJ1dGUgaW50byBhIG5hbWVkIG5vZGUgbWFwLgorICogIERvIHRoZSBzYW1lIGZvciBhbm90aGVyIGRvY3VtZW50IGFuZCByZXRyZWl2ZSBpdHMgc3RyZWV0IGF0dHJpYnV0ZS4gIENhbGwgdGhlIHNldE5hbWVkSXRlbU5TCisgKiAgdXNpbmcgdGhlIGZpcnN0IG5hbWVkTm9kZU1hcCBhbmQgdGhlIHJldHJlaXZlIHN0cmVldCBhdHRyaWJ1dGUgb2YgdGhlIHNlY29uZC4gIFRoaXMgc2hvdWxkCisgKiAgcmFpc2UgYSBXUk9OR19ET0NVTUVOVF9FUlIuIAorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXNldE5hbWVkSXRlbU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtc2V0TmFtZWRJdGVtTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9NDA4Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9NDA4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczAzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczAzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50IGRvY0FsdDsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXNBbHQ7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0QWx0OworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgRWxlbWVudCBlbGVtZW50QWx0OworICAgICAgQXR0ciBhdHRyOworICAgICAgTm9kZSBuZXdOb2RlOworICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJhZGRyZXNzIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBkb2NBbHQgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0QWx0ID0gZG9jQWx0LmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiYWRkcmVzcyIpOworICAgICAgZWxlbWVudEFsdCA9IChFbGVtZW50KSBlbGVtZW50TGlzdEFsdC5pdGVtKDEpOworICAgICAgYXR0cmlidXRlc0FsdCA9IGVsZW1lbnRBbHQuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzQWx0LmdldE5hbWVkSXRlbU5TKG51bGxOUywgInN0cmVldCIpOworICAgICAgbmV3Tm9kZSA9IGF0dHJpYnV0ZXNBbHQucmVtb3ZlTmFtZWRJdGVtTlMobnVsbE5TLCAic3RyZWV0Iik7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ld05vZGUgPSBhdHRyaWJ1dGVzLnNldE5hbWVkSXRlbU5TKGF0dHIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfV1JPTkdfRE9DVU1FTlRfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ3NWI5NWMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDQuamF2YQpAQCAtMCwwICsxLDEyMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIHNldE5hbWVkSXRlbU5TIGFkZHMgYSBub2RlIHVzaW5nIGl0cyBuYW1lc3BhY2VVUkkgYW5kIGxvY2FsTmFtZSBhbmQgCisgKiAgcmFpc2VzIGEgV1JPTkdfRE9DVU1FTlRfRVJSIGlmIGFyZyB3YXMgY3JlYXRlZCBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIAorICogIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyBtYXAuCisgKiAgCisgKiAgUmV0cmVpZXZlIHRoZSBzZWNvbmQgZWxlbWVudCB3aG9zZSBsb2NhbCBuYW1lIGlzIGFkZHJlc3MgYW5kIGl0cyBhdHRyaWJ1dGUgaW50byBhIG5hbWVkIG5vZGUgbWFwLgorICogIENyZWF0ZSBhIG5ldyBkb2N1bWVudCBhbmQgYSBuZXcgYXR0cmlidXRlIG5vZGUgaW4gaXQuICBDYWxsIHRoZSBzZXROYW1lZEl0ZW1OUyB1c2luZyB0aGUgZmlyc3QgCisgKiAgbmFtZWROb2RlTWFwIGFuZCB0aGUgbmV3IGF0dHJpYnV0ZSBub2RlIGF0dHJpYnV0ZSBvZiB0aGUgbmV3IGRvY3VtZW50LiAgVGhpcyBzaG91bGQKKyAqICByYWlzZSBhIFdST05HX0RPQ1VNRU5UX0VSUi4gCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtc2V0TmFtZWRJdGVtTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1zZXROYW1lZEl0ZW1OUzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA0IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgRG9jdW1lbnQgZG9jQWx0OworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGUgPSBudWxsOworCisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgQXR0ciBhdHRyQWx0OworICAgICAgTm9kZSBuZXdOb2RlOworICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJhZGRyZXNzIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICBkb2NBbHQgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KG51bGxOUywgIm5ld0RvYyIsIGRvY1R5cGUpOworICAgICAgYXR0ckFsdCA9IGRvY0FsdC5jcmVhdGVBdHRyaWJ1dGVOUyhudWxsTlMsICJzdHJlZXQiKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3Tm9kZSA9IGF0dHJpYnV0ZXMuc2V0TmFtZWRJdGVtTlMoYXR0ckFsdCk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19XUk9OR19ET0NVTUVOVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA1LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjczZjQ2ZAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNS5qYXZhCkBAIC0wLDAgKzEsMTI1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFJldHJlaXZlIGFuIGVudGl0eSBhbmQgbm90YXRpb24gbm9kZSBhbmQgYWRkIHRoZSBmaXJzdCBub3RhdGlvbiB0byB0aGUgCisgKiAgbm90YXRpb24gbm9kZSBtYXAgYW5kIGZpcnN0IGVudGl0eSBub2RlIHRvIHRoZSBlbnRpdHkgbWFwLiAgU2luY2UgYm90aCB0aGVzZQorICogIG1hcHMgYXJlIGZvciByZWFkb25seSBub2RlLCBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBzaG91bGQgYmUgcmFpc2VkLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXNldE5hbWVkSXRlbU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtc2V0TmFtZWRJdGVtTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9NDA3Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9NDA3PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9saXN0cy53My5vcmcvQXJjaGl2ZXMvTWVtYmVyL3czYy1kb20taWcvMjAwM05vdi8wMDE2Lmh0bWwiPmh0dHA6Ly9saXN0cy53My5vcmcvQXJjaGl2ZXMvTWVtYmVyL3czYy1kb20taWcvMjAwM05vdi8wMDE2Lmh0bWw8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTmFtZWROb2RlTWFwIGVudGl0aWVzOworICAgICAgTmFtZWROb2RlTWFwIG5vdGF0aW9uczsKKyAgICAgIEVudGl0eSBlbnRpdHk7CisgICAgICBOb3RhdGlvbiBub3RhdGlvbjsKKyAgICAgIE5vZGUgbmV3Tm9kZTsKKyAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgZW50aXRpZXMgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdGllc05vdE51bGwiLCBlbnRpdGllcyk7CisgICAgICBub3RhdGlvbnMgPSBkb2NUeXBlLmdldE5vdGF0aW9ucygpOworICAgICAgYXNzZXJ0Tm90TnVsbCgibm90YXRpb25zTm90TnVsbCIsIG5vdGF0aW9ucyk7CisgICAgICBlbnRpdHkgPSAoRW50aXR5KSBlbnRpdGllcy5nZXROYW1lZEl0ZW0oImVudDEiKTsKKyAgICAgIG5vdGF0aW9uID0gKE5vdGF0aW9uKSBub3RhdGlvbnMuZ2V0TmFtZWRJdGVtKCJub3RhdGlvbjEiKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3Tm9kZSA9IGVudGl0aWVzLnNldE5hbWVkSXRlbU5TKGVudGl0eSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlJfZW50aXRpZXMiLCBzdWNjZXNzKTsKKyAgICAgIH0KKworICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3Tm9kZSA9IG5vdGF0aW9ucy5zZXROYW1lZEl0ZW1OUyhub3RhdGlvbik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlJfbm90YXRpb25zIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDYuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkzYzI4ODYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDYuamF2YQpAQCAtMCwwICsxLDExMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgUmV0cmVpZXZlIHRoZSBmaXJzdCBlbGVtZW50IHdob3NlIGxvY2FsTmFtZSBpcyBhZGRyZXNzIGFuZCBpdHMgYXR0cmlidXRlcyBpbnRvIGEgbmFtZWQgbm9kZSBtYXAuCisgKiAgUmV0cmVpdmluZyB0aGUgZG9tZXN0aWMgYXR0cmlidXRlIGZyb20gdGhlIG5hbWVkbm9kZW1hcC4gIAorICogIFJldHJlaWV2ZSB0aGUgc2Vjb25kIGVsZW1lbnQgd2hvc2UgbG9jYWxOYW1lIGlzIGFkZHJlc3MgYW5kIGl0cyBhdHRyaWJ1dGVzIGludG8gYSBuYW1lZCBub2RlIG1hcC4KKyAqICBJbnZva2Ugc2V0TmFtZWRJdGVtTlMgb24gdGhlIHNlY29uZCBOYW1lZE5vZGVNYXAgc3BlY2lmeWluZyB0aGUgZmlyc3QgZG9tZXN0aWMgYXR0cmlidXRlIGZyb20KKyAqICB0aGUgZmlyc3QgbWFwLiAgVGhpcyBzaG91bGQgcmFpc2UgYW4gSU5VU0VfQVRUUklCSVVURV9FUlIuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtc2V0TmFtZWRJdGVtTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1zZXROYW1lZEl0ZW1OUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cjsKKyAgICAgIE5vZGUgbmV3Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJhZGRyZXNzIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBhdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtTlMoImh0dHA6Ly93d3cudXNhLmNvbSIsICJkb21lc3RpYyIpOworICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXdOb2RlID0gYXR0cmlidXRlcy5zZXROYW1lZEl0ZW1OUyhhdHRyKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5VU0VfQVRUUklCVVRFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA2Iiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDYiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDYuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5NTgyY2YKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDcuamF2YQpAQCAtMCwwICsxLDExNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCBzZXROYW1lZEl0ZW1OUyBhZGRzIGEgbm9kZSB1c2luZyBpdHMgbmFtZXNwYWNlVVJJIGFuZCBsb2NhbE5hbWUgYW5kIAorICogIHJhaXNlcyBhIElOVVNFX0FUVFJJQlVURV9FUlIgUmFpc2VkIGlmIGFyZyBpcyBhbiBBdHRyIHRoYXQgaXMgYWxyZWFkeSBhbiAKKyAqICBhdHRyaWJ1dGUgb2YgYW5vdGhlciBFbGVtZW50IG9iamVjdC4gCisgKiAgCisgKiAgUmV0cmVpZXZlIHRoZSBhdHRyaWJ1dGVzIG9mIGZpcnN0IGVsZW1lbnQgd2hvc2UgbG9jYWxOYW1lIGlzIGFkZHJlc3MgaW50byBhIG5hbWVkIG5vZGUgbWFwLgorICogIFJldHJlaXZlIHRoZSBhdHRyaWJ1dGUgd2hvc2UgbmFtZXNwYWNlVVJJPWh0dHA6Ly93d3cudXNhLmNvbSBhbmQgbG9jYWxOYW1lPWRvbWVzdGljCisgKiAgZnJvbSB0aGUgTmFtZWROb2RlTWFwLiAgUmV0cmVpZXZlIHRoZSBhdHRyaWJ1dGVzIG9mIHNlY29uZCBlbGVtZW50IHdob3NlIGxvY2FsTmFtZSBpcyBhZGRyZXNzIAorICogIGludG8gYSBuYW1lZCBub2RlIG1hcC4gIENhbGwgdGhlIHNldE5hbWVkSXRlbU5TIG1ldGhvZCBvbiB0aGUgc2Vjb25kIG5vZGVtYXAgd2l0aCB0aGUgZG9tZXN0aWMgCisgKiAgYXR0cmlidXRlIHRoYXQgd2FzIHJldHJlaXZlZCBhbmQgcmVtb3ZlZCBmcm9tIHRoZSBmaXJzdCBub2RlTWFwIGFzIGFuIGFyZ3VtZW50LgorICogIEFzc3VtaW5nIHRoYXQgd2hlbiBhbiBhdHRyaWJ1dGUgaXMgcmVtb3ZlZCBmcm9tIGEgbm9kZW1hcCwgaXQgc3RpbGwgcmVtYWlucyBpbiB0aGUgZG9tdHJlZQorICogIGhpcyBzaG91bGQgcmFpc2UgYW4gSU5VU0VfQVRUUklCSVVURV9FUlIuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtc2V0TmFtZWRJdGVtTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1zZXROYW1lZEl0ZW1OUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwNyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cjsKKyAgICAgIE5vZGUgbmV3Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJhZGRyZXNzIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBhdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtTlMoImh0dHA6Ly93d3cudXNhLmNvbSIsICJkb21lc3RpYyIpOworICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXdOb2RlID0gYXR0cmlidXRlcy5zZXROYW1lZEl0ZW1OUyhhdHRyKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5VU0VfQVRUUklCVVRFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA3Iiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDciOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDcuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDguamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwOC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZkMDk4NWEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDguamF2YQpAQCAtMCwwICsxLDExMiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgcmFpc2VzIGEgSU5VU0VfQVRUUklCVVRFX0VSUiBSYWlzZWQgaWYgYXJnIGlzIGFuIEF0dHIgdGhhdCBpcyBhbHJlYWR5IGFuIAorICogICAgIGF0dHJpYnV0ZSBvZiBhbm90aGVyIEVsZW1lbnQgb2JqZWN0LiAKKyAqICBSZXRyZWlldmUgdGhlIGZpcnN0IGVsZW1lbnQgd2hvc2UgbG9jYWxOYW1lIGlzIGFkZHJlc3MgYW5kIGl0cyBhdHRyaWJ1dGVzIGludG8gYSBuYW1lZCBub2RlIG1hcC4KKyAqICBSZXRyZWl2aW5nIHRoZSBkb21lc3RpYyBhdHRyaWJ1dGUgZnJvbSB0aGUgbmFtZWRub2RlbWFwLiAgUmV0cmVpZXZlIHRoZSBzZWNvbmQgZWxlbWVudCB3aG9zZSAKKyAqICBsb2NhbE5hbWUgaXMgYWRkcmVzcyBhbmQgaXRzIGF0dHJpYnV0ZXMgaW50byBhIG5hbWVkIG5vZGUgbWFwLiBJbnZva2Ugc2V0TmFtZWRJdGVtTlMgb24gdGhlIAorICogIHNlY29uZCBOYW1lZE5vZGVNYXAgc3BlY2lmeWluZyB0aGUgYXR0cmlidXRlIGZyb20gdGhlIGZpcnN0IG1hcC4gIAorICogIFRoaXMgc2hvdWxkIHJhaXNlIGFuIElOVVNFX0FUVFJJQklVVEVfRVJSLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXNldE5hbWVkSXRlbU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtc2V0TmFtZWRJdGVtTlM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDggZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDgoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBBdHRyIGF0dHI7CisgICAgICBOb2RlIG5ld05vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiYWRkcmVzcyIpOworICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKCJodHRwOi8vd3d3LnVzYS5jb20iLCAiZG9tZXN0aWMiKTsKKyAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3Tm9kZSA9IGF0dHJpYnV0ZXMuc2V0TmFtZWRJdGVtTlMoYXR0cik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVVNFX0FUVFJJQlVURV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgibmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwOCIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA4IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA4LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA5LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTEwMmJhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA5LmphdmEKQEAgLTAsMCArMSwxMTggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCBzZXROYW1lZEl0ZW1OUyBhZGRzIGEgbm9kZSB1c2luZyBpdHMgbmFtZXNwYWNlVVJJIGFuZCBsb2NhbE5hbWUgYW5kIAorICogIHJhaXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBpZiB0aGlzIG1hcCBpcyByZWFkb25seS4KKyAqICAKKyAqICBDcmVhdGUgYSBuZXcgYXR0cmlidXRlIG5vZGUgYW5kIGF0dGVtcHQgdG8gYWRkIGl0IHRvIHRoZSBub2RlbWFwIG9mIGVudGl0aWVzIGFuZCBub3RhdGlvbnMKKyAqICBmb3IgdGhpcyBkb2N1bWVudHR5cGUuICBUaGlzIHNob3VsZCByZWFpc2UgYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtc2V0TmFtZWRJdGVtTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1zZXROYW1lZEl0ZW1OUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwOSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMwOShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBOYW1lZE5vZGVNYXAgZW50aXRpZXM7CisgICAgICBOYW1lZE5vZGVNYXAgbm90YXRpb25zOworICAgICAgQXR0ciBhdHRyOworICAgICAgTm9kZSBuZXdOb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIGVudGl0aWVzID0gZG9jVHlwZS5nZXRFbnRpdGllcygpOworICAgICAgbm90YXRpb25zID0gZG9jVHlwZS5nZXROb3RhdGlvbnMoKTsKKyAgICAgIGF0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgInRlc3QiKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3Tm9kZSA9IGVudGl0aWVzLnNldE5hbWVkSXRlbU5TKGF0dHIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSX2VudGl0aWVzIiwgc3VjY2Vzcyk7CisgICAgICB9CisKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ld05vZGUgPSBub3RhdGlvbnMuc2V0TmFtZWRJdGVtTlMoYXR0cik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlJfbm90YXRpb25zIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDkiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDkuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMTAuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMxMC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiZTY5NDAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMTAuamF2YQpAQCAtMCwwICsxLDExNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgbWV0aG9kIHNldE5hbWVkSXRlbU5TIGFkZHMgYSBub2RlIHVzaW5nIGl0cyBuYW1lc3BhY2VVUkkgYW5kIGxvY2FsTmFtZSBhbmQgCisgKiAgICAgcmFpc2VzIGEgSElFUkFSQ0hZX1JFUVVFU1RfRVJSIGlmIGFuIGF0dGVtcHQgaXMgbWFkZSB0byBhZGQgYSBub2RlIGRvZXNuJ3QgYmVsb25nIAorICogICAgIGluIHRoaXMgTmFtZWROb2RlTWFwLgorICogICBBdHRlbXB0IHRvIGFkZCBhbiBlbnRpdHkgdG8gYSBOYW1lZE5vZGVNYXAgb2YgYXR0cmlidXRlIG5vZGVzLAorICogICBTaW5jZSBub2RlcyBvZiB0aGlzIHR5cGUgY2Fubm90IGJlIGFkZGVkIHRvIHRoZSBhdHRyaWJ1dGUgbm9kZSBtYXAgYSBISUVSQVJDSFlfUkVRVUVTVF9FUlIKKyAqICAgc2hvdWxkIGJlIHJhaXNlZC4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1zZXROYW1lZEl0ZW1OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXNldE5hbWVkSXRlbU5TPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMTAgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMTAoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTmFtZWROb2RlTWFwIGVudGl0aWVzOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBFbnRpdHkgZW50aXR5OworICAgICAgTm90YXRpb24gbm90YXRpb247CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmV3Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBlbnRpdGllcyA9IGRvY1R5cGUuZ2V0RW50aXRpZXMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVudGl0aWVzTm90TnVsbCIsIGVudGl0aWVzKTsKKyAgICAgIGVudGl0eSA9IChFbnRpdHkpIGVudGl0aWVzLmdldE5hbWVkSXRlbSgiZW50MSIpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJhZGRyZXNzIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ld05vZGUgPSBhdHRyaWJ1dGVzLnNldE5hbWVkSXRlbU5TKGVudGl0eSk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19ISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMxMCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMxMC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMxMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczExLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2I5ZDFiNgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZWRub2RlbWFwc2V0bmFtZWRpdGVtbnMxMS5qYXZhCkBAIC0wLDAgKzEsMTE3IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSBtZXRob2Qgc2V0TmFtZWRJdGVtTlMgYWRkcyBhIG5vZGUgdXNpbmcgaXRzIG5hbWVzcGFjZVVSSSBhbmQgbG9jYWxOYW1lIGFuZCAKKyAqICAgICByYWlzZXMgYSBISUVSQVJDSFlfUkVRVUVTVF9FUlIgaWYgYW4gYXR0ZW1wdCBpcyBtYWRlIHRvIGFkZCBhIG5vZGUgZG9lc24ndCBiZWxvbmcgCisgKiAgICAgaW4gdGhpcyBOYW1lZE5vZGVNYXAuCisgKiAgIEF0dGVtcHQgdG8gYWRkIGEgbm90YXRpb24gbm9kZSB0byBhIE5hbWVkTm9kZU1hcCBvZiBhdHRyaWJ1dGUgbm9kZXMsCisgKiAgIFNpbmNlIG5vdGF0aW9ucyBub2RlcyBkbyBub3QgYmVsb25nIGluIHRoZSBhdHRyaWJ1dGUgbm9kZSBtYXAgYSBISUVSQVJDSFlfUkVRVUVTVF9FUlIKKyAqICAgc2hvdWxkIGJlIHJhaXNlZC4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1zZXROYW1lZEl0ZW1OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXNldE5hbWVkSXRlbU5TPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMTEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMTEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgTmFtZWROb2RlTWFwIG5vdGF0aW9uczsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgTm90YXRpb24gbm90YXRpb247CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgbmV3Tm9kZTsKKyAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgbm90YXRpb25zID0gZG9jVHlwZS5nZXROb3RhdGlvbnMoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoIm5vdGF0aW9uc05vdE51bGwiLCBub3RhdGlvbnMpOworICAgICAgbm90YXRpb24gPSAoTm90YXRpb24pIG5vdGF0aW9ucy5nZXROYW1lZEl0ZW0oIm5vdGF0aW9uMSIpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJhZGRyZXNzIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ld05vZGUgPSBhdHRyaWJ1dGVzLnNldE5hbWVkSXRlbU5TKG5vdGF0aW9uKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0hJRVJBUkNIWV9SRVFVRVNUX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczExIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczExLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lc3BhY2VVUkkwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lc3BhY2VVUkkwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdmM2I1ZDAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVzcGFjZVVSSTAxLmphdmEKQEAgLTAsMCArMSwxMDIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXROYW1lc3BhY2VVUkkoKSIgbWV0aG9kIGZvciBhbiBBdHRyaWJ1dGUKKyAqICAgICByZXR1cm5zIHRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoaXMgbm9kZSwgb3IgbnVsbCBpZiB1bnNwZWNpZmllZC4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgImVtcDphZGRyZXNzIiBub2RlIHdoaWNoIGhhcyBhbiBhdHRyaWJ1dGUgb2YgImVtcDpkaXN0cmljdCIKKyAqICAgICB0aGF0IGlzIHNwZWNpZmllZCBpbiB0aGUgRFRELgorICogICAgIEludm9rZSB0aGUgImdldE5hbWVzcGFjZVVSSSgpIiBtZXRob2Qgb24gdGhlIGF0dHJpYnV0ZS4gICAKKyAqICAgICBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gImh0dHA6Ly93d3cubmlzdC5nb3YiLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNuYW1lIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TbmFtZTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjM4Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjM4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBuYW1lc3BhY2VVUkkwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbmFtZXNwYWNlVVJJMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUsCitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcudmFsaWRhdGluZworICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcjsKKyAgICAgIEF0dHIgYWRkckF0dHI7CisgICAgICBTdHJpbmcgYXR0ck5hbWVzcGFjZVVSSTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6YWRkcmVzcyIpOworICAgICAgdGVzdEFkZHIgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGFkZHJBdHRyID0gdGVzdEFkZHIuZ2V0QXR0cmlidXRlTm9kZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImRpc3RyaWN0Iik7CisgICAgICBhdHRyTmFtZXNwYWNlVVJJID0gYWRkckF0dHIuZ2V0TmFtZXNwYWNlVVJJKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5hbWVzcGFjZVVSSSIsICJodHRwOi8vd3d3Lm5pc3QuZ292IiwgYXR0ck5hbWVzcGFjZVVSSSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25hbWVzcGFjZVVSSTAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihuYW1lc3BhY2VVUkkwMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZXNwYWNlVVJJMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZXNwYWNlVVJJMDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZTU0OGJhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lc3BhY2VVUkkwMi5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0TmFtZXNwYWNlVVJJKCkiIG1ldGhvZCBmb3IgYW4gQXR0cmlidXRlCisgKiAgICAgcmV0dXJucyB0aGUgbmFtZXNwYWNlIFVSSSBvZiB0aGlzIG5vZGUsIG9yIG51bGwgaWYgdW5zcGVjaWZpZWQuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIGZpcnN0IGVtcDphZGRyZXNzIG5vZGUgYW5kIGdldCB0aGUgZW1wOmRvbWVzdGljIGF0dHJpYnV0ZS4KKyAqICAgICBJbnZva2UgdGhlICJnZXROYW1lc3BhY2VVUkkoKSIgbWV0aG9kIG9uIHRoZSBhdHRyaWJ1dGUuICAgCisgKiAgICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuICJodHRwOi8vd3d3Lm5pc3QuZ292Ii4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TbmFtZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU25hbWU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVzcGFjZVVSSTAyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lc3BhY2VVUkkwMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgRWxlbWVudCB0ZXN0QWRkcjsKKyAgICAgIEF0dHIgYWRkckF0dHI7CisgICAgICBTdHJpbmcgYXR0ck5hbWVzcGFjZVVSSTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6YWRkcmVzcyIpOworICAgICAgdGVzdEFkZHIgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVtcEFkZHJlc3NOb3ROdWxsIiwgdGVzdEFkZHIpOworICAgICAgYWRkckF0dHIgPSB0ZXN0QWRkci5nZXRBdHRyaWJ1dGVOb2RlTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAiZG9tZXN0aWMiKTsKKyAgICAgIGF0dHJOYW1lc3BhY2VVUkkgPSBhZGRyQXR0ci5nZXROYW1lc3BhY2VVUkkoKTsKKyAgICAgIGFzc2VydEVxdWFscygibmFtZXNwYWNlVVJJIiwgImh0dHA6Ly93d3cubmlzdC5nb3YiLCBhdHRyTmFtZXNwYWNlVVJJKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbmFtZXNwYWNlVVJJMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5hbWVzcGFjZVVSSTAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lc3BhY2VVUkkwMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9uYW1lc3BhY2VVUkkwMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjliZTc3YWEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVzcGFjZVVSSTAzLmphdmEKQEAgLTAsMCArMSw5NyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldE5hbWVzcGFjZVVSSSgpIiBtZXRob2QgZm9yIGEgTm9kZQorICogICAgIHJldHVybnMgdGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhpcyBub2RlLCBvciBudWxsIGlmIHVuc3BlY2lmaWVkLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBmaXJzdCBlbXBsb3llZSBub2RlIGFuZCBpbnZva2UgdGhlICJnZXROYW1lc3BhY2VVUkkoKSIgICAKKyAqICAgICBtZXRob2QuICAgVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuICJodHRwOi8vd3d3Lm5pc3QuZ292Ii4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TbmFtZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU25hbWU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5hbWVzcGFjZVVSSTAzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBuYW1lc3BhY2VVUkkwMyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0RW1wbG95ZWU7CisgICAgICBTdHJpbmcgZW1wbG95ZWVOYW1lc3BhY2U7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIHRlc3RFbXBsb3llZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbXBsb3llZU5vdE51bGwiLCB0ZXN0RW1wbG95ZWUpOworICAgICAgZW1wbG95ZWVOYW1lc3BhY2UgPSB0ZXN0RW1wbG95ZWUuZ2V0TmFtZXNwYWNlVVJJKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5hbWVzcGFjZVVSSSIsICJodHRwOi8vd3d3Lm5pc3QuZ292IiwgZW1wbG95ZWVOYW1lc3BhY2UpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lc3BhY2VVUkkwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZXNwYWNlVVJJMDMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVzcGFjZVVSSTA0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25hbWVzcGFjZVVSSTA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWQ2MDJkYwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbmFtZXNwYWNlVVJJMDQuamF2YQpAQCAtMCwwICsxLDkwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldE5hbWVzcGFjZVVSSSgpIiBtZXRob2QgZm9yIGEgTm9kZQorICogICAgIHJldHVybnMgdGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhpcyBub2RlLCBvciBudWxsIGlmIHVuc3BlY2lmaWVkLgorICogICAgIAorICogICAgIFJldHJpZXZlIHRoZSBzZWNvbmQgZW1wbG95ZWUgbm9kZSBhbmQgaW52b2tlIHRoZSAiZ2V0TmFtZXNwYWNlVVJJKCkiICAgCisgKiAgICAgbWV0aG9kLiAgIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiAibnVsbCIuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU25hbWUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNuYW1lPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBuYW1lc3BhY2VVUkkwNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbmFtZXNwYWNlVVJJMDQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgU3RyaW5nIGVtcGxveWVlTmFtZXNwYWNlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgZW1wbG95ZWVOYW1lc3BhY2UgPSB0ZXN0RW1wbG95ZWUuZ2V0TmFtZXNwYWNlVVJJKCk7CisgICAgICBhc3NlcnROdWxsKCJ0aHJvd19OdWxsIiwgZW1wbG95ZWVOYW1lc3BhY2UpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9uYW1lc3BhY2VVUkkwNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obmFtZXNwYWNlVVJJMDQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVnZXRsb2NhbG5hbWUwMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2RlZ2V0bG9jYWxuYW1lMDMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZmY2NTFkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2RlZ2V0bG9jYWxuYW1lMDMuamF2YQpAQCAtMCwwICsxLDEwOSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCBnZXRMb2NhbE5hbWUgcmV0dXJucyB0aGUgbG9jYWwgcGFydCBvZiB0aGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhpcyBub2RlLgorICogIAorICogIENlYXRlIHR3byBuZXcgZWxlbWVudCBub2RlcyBhbmQgYXRyaWJ1dGUgbm9kZXMsIHdpdGggYW5kIHdpdGhvdXQgbmFtZXNwYWNlIHByZWZpeGVzLgorICogIFJldHJlaXZlIHRoZSBsb2NhbCBwYXJ0IG9mIHRoZWlyIHF1YWxpZmllZCBuYW1lcyB1c2luZyBnZXRMb2NhbE5hbWUgYW5kIHZlcnJpZnkKKyAqICBpZiBpdCBpcyBjb3JyZWN0LgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU0xvY2FsTiI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU0xvY2FsTjwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWdldGxvY2FsbmFtZTAzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlZ2V0bG9jYWxuYW1lMDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgRWxlbWVudCBxZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cjsKKyAgICAgIEF0dHIgcWF0dHI7CisgICAgICBTdHJpbmcgbG9jYWxFbGVtTmFtZTsKKyAgICAgIFN0cmluZyBsb2NhbFFFbGVtTmFtZTsKKyAgICAgIFN0cmluZyBsb2NhbEF0dHJOYW1lOworICAgICAgU3RyaW5nIGxvY2FsUUF0dHJOYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9lbGVtIiwgImVsZW0iKTsKKyAgICAgIHFlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvZWxlbSIsICJxdWFsOnFlbGVtIik7CisgICAgICBhdHRyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9hdHRyIiwgImF0dHIiKTsKKyAgICAgIHFhdHRyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9hdHRyIiwgInF1YWw6cWF0dHIiKTsKKyAgICAgIGxvY2FsRWxlbU5hbWUgPSBlbGVtZW50LmdldExvY2FsTmFtZSgpOworICAgICAgbG9jYWxRRWxlbU5hbWUgPSBxZWxlbWVudC5nZXRMb2NhbE5hbWUoKTsKKyAgICAgIGxvY2FsQXR0ck5hbWUgPSBhdHRyLmdldExvY2FsTmFtZSgpOworICAgICAgbG9jYWxRQXR0ck5hbWUgPSBxYXR0ci5nZXRMb2NhbE5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZWdldGxvY2FsbmFtZTAzX2xvY2FsRWxlbU5hbWUiLCAiZWxlbSIsIGxvY2FsRWxlbU5hbWUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlZ2V0bG9jYWxuYW1lMDNfbG9jYWxRRWxlbU5hbWUiLCAicWVsZW0iLCBsb2NhbFFFbGVtTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVnZXRsb2NhbG5hbWUwM19sb2NhbEF0dHJOYW1lIiwgImF0dHIiLCBsb2NhbEF0dHJOYW1lKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZWdldGxvY2FsbmFtZTAzX2xvY2FsUUF0dHJOYW1lIiwgInFhdHRyIiwgbG9jYWxRQXR0ck5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub2RlZ2V0bG9jYWxuYW1lMDMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVnZXRsb2NhbG5hbWUwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZWdldG5hbWVzcGFjZXVyaTAzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVnZXRuYW1lc3BhY2V1cmkwMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU0ZWU5ZmUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVnZXRuYW1lc3BhY2V1cmkwMy5qYXZhCkBAIC0wLDAgKzEsMTEzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2QgZ2V0TmFtZXNwYWNlVVJJIHJldHVybnMgdGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhpcyBub2RlLCBvciBudWxsIGlmIGl0IGlzIHVuc3BlY2lmaWVkCisgKiAgRm9yIG5vZGVzIG9mIGFueSB0eXBlIG90aGVyIHRoYW4gRUxFTUVOVF9OT0RFIGFuZCBBVFRSSUJVVEVfTk9ERSBhbmQgbm9kZXMgY3JlYXRlZCB3aXRoIAorICogIGEgRE9NIExldmVsIDEgbWV0aG9kLCBzdWNoIGFzIGNyZWF0ZUVsZW1lbnQgZnJvbSB0aGUgRG9jdW1lbnQgaW50ZXJmYWNlLCB0aGlzIGlzIGFsd2F5cyBudWxsLgorICogICAKKyAqICBDZWF0ZSB0d28gbmV3IGVsZW1lbnQgbm9kZXMgYW5kIGF0cmlidXRlIG5vZGVzLCB3aXRoIGFuZCB3aXRob3V0IG5hbWVzcGFjZSBwcmVmaXhlcy4KKyAqICBSZXRyZWl2ZSB0aGVpciBuYW1lc3BhY2VVUkkncyB1c2luZyBnZXROYW1lc3BhY2VVUkkgYW5kIHZlcnJpZnkgaWYgaXQgaXMgY29ycmVjdC4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNuYW1lIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TbmFtZTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlZ2V0bmFtZXNwYWNldXJpMDMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVnZXRuYW1lc3BhY2V1cmkwMyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBFbGVtZW50IGVsZW1lbnROUzsKKyAgICAgIEF0dHIgYXR0cjsKKyAgICAgIEF0dHIgYXR0ck5TOworICAgICAgU3RyaW5nIGVsZW1OU1VSSTsKKyAgICAgIFN0cmluZyBlbGVtTlNVUklOdWxsOworICAgICAgU3RyaW5nIGF0dHJOU1VSSTsKKyAgICAgIFN0cmluZyBhdHRyTlNVUklOdWxsOworICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUyhudWxsTlMsICJlbGVtIik7CisgICAgICBlbGVtZW50TlMgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9lbGVtIiwgInF1YWw6cWVsZW0iKTsKKyAgICAgIGF0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMobnVsbE5TLCAiYXR0ciIpOworICAgICAgYXR0ck5TID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9hdHRyIiwgInF1YWw6cWF0dHIiKTsKKyAgICAgIGVsZW1OU1VSSSA9IGVsZW1lbnROUy5nZXROYW1lc3BhY2VVUkkoKTsKKyAgICAgIGVsZW1OU1VSSU51bGwgPSBlbGVtZW50LmdldE5hbWVzcGFjZVVSSSgpOworICAgICAgYXR0ck5TVVJJID0gYXR0ck5TLmdldE5hbWVzcGFjZVVSSSgpOworICAgICAgYXR0ck5TVVJJTnVsbCA9IGF0dHIuZ2V0TmFtZXNwYWNlVVJJKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVnZXRuYW1lc3BhY2V1cmkwM19lbGVtTlNVUkkiLCAiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvZWxlbSIsIGVsZW1OU1VSSSk7CisgICAgICBhc3NlcnROdWxsKCJub2RlZ2V0bmFtZXNwYWNldXJpMDNfMSIsIGVsZW1OU1VSSU51bGwpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlZ2V0bmFtZXNwYWNldXJpMDNfYXR0ck5TVVJJIiwgImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L2F0dHIiLCBhdHRyTlNVUkkpOworICAgICAgYXNzZXJ0TnVsbCgibm9kZWdldG5hbWVzcGFjZXVyaTAzXzIiLCBhdHRyTlNVUklOdWxsKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbm9kZWdldG5hbWVzcGFjZXVyaTAzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlZ2V0bmFtZXNwYWNldXJpMDMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVnZXRvd25lcmRvY3VtZW50MDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZWdldG93bmVyZG9jdW1lbnQwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ5MGQ4NjYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVnZXRvd25lcmRvY3VtZW50MDEuamF2YQpAQCAtMCwwICsxLDk4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2QgZ2V0T3duZXJEb2N1bWVudCByZXR1cm5zIHRoZSBEb2N1bWVudCBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoaXMgbm9kZQorICogICAKKyAqICBDcmVhdGUgYSBuZXcgRG9jdW1lbnRUeXBlIG5vZGUuICBTaW5jZSB0aGlzIG5vZGUgaXMgbm90IHVzZWQgd2l0aCBhbnkgRG9jdW1lbnQgeWV0CisgKiAgdmVyaWZ5IGlmIHRoZSBvd25lckRvY3VtZW50IGlzIG51bGwuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjbm9kZS1vd25lckRvYyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI25vZGUtb3duZXJEb2M8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWdldG93bmVyZG9jdW1lbnQwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWdldG93bmVyZG9jdW1lbnQwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBvd25lckRvYzsKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIFN0cmluZyBudWxsSUQgPSBudWxsOworCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgZG9jVHlwZSA9IGRvbUltcGwuY3JlYXRlRG9jdW1lbnRUeXBlKCJteWRvYyIsIG51bGxJRCwgbnVsbElEKTsKKyAgICAgIG93bmVyRG9jID0gZG9jVHlwZS5nZXRPd25lckRvY3VtZW50KCk7CisgICAgICBhc3NlcnROdWxsKCJub2RlZ2V0b3duZXJkb2N1bWVudDAxIiwgb3duZXJEb2MpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub2RlZ2V0b3duZXJkb2N1bWVudDAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlZ2V0b3duZXJkb2N1bWVudDAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2RlZ2V0b3duZXJkb2N1bWVudDAyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVnZXRvd25lcmRvY3VtZW50MDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YzdiODlkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2RlZ2V0b3duZXJkb2N1bWVudDAyLmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCBnZXRPd25lckRvY3VtZW50IHJldHVybnMgdGhlIERvY3VtZW50IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBub2RlCisgKiAgIAorICogIENyZWF0ZSBhIG5ldyBEb2N1bWVudCBub2RlLiAgU2luY2UgdGhpcyBub2RlIGlzIG5vdCB1c2VkIHdpdGggYW55IERvY3VtZW50IHlldAorICogIHZlcmlmeSBpZiB0aGUgb3duZXJEb2N1bWVudCBpcyBudWxsLiAgQ3JlYXRlIGEgbmV3IGVsZW1lbnQgTm9kZSBvbiB0aGUgbmV3IERvY3VtZW50CisgKiAgb2JqZWN0LiAgQ2hlY2sgdGhlIG93bmVyRG9jdW1lbnQgb2YgdGhlIG5ldyBlbGVtZW50IG5vZGUuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjbm9kZS1vd25lckRvYyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI25vZGUtb3duZXJEb2M8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWdldG93bmVyZG9jdW1lbnQwMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWdldG93bmVyZG9jdW1lbnQwMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBuZXdEb2M7CisgICAgICBFbGVtZW50IG5ld0VsZW07CisgICAgICBEb2N1bWVudCBvd25lckRvY0RvYzsKKyAgICAgIERvY3VtZW50IG93bmVyRG9jRWxlbTsKKyAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgZG9jVHlwZSA9IGRvbUltcGwuY3JlYXRlRG9jdW1lbnRUeXBlKCJteWRvYyIsIG51bGxOUywgbnVsbE5TKTsKKyAgICAgIG5ld0RvYyA9IGRvbUltcGwuY3JlYXRlRG9jdW1lbnQoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgIm15ZG9jIiwgZG9jVHlwZSk7CisgICAgICBvd25lckRvY0RvYyA9IG5ld0RvYy5nZXRPd25lckRvY3VtZW50KCk7CisgICAgICBhc3NlcnROdWxsKCJub2RlZ2V0b3duZXJkb2N1bWVudDAyXzEiLCBvd25lckRvY0RvYyk7CisgICAgICBuZXdFbGVtID0gbmV3RG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLCAibXllbGVtIik7CisgICAgICBvd25lckRvY0VsZW0gPSBuZXdFbGVtLmdldE93bmVyRG9jdW1lbnQoKTsKKyAgICAgIGFzc2VydE5vdE51bGwoIm5vZGVnZXRvd25lcmRvY3VtZW50MDJfMiIsIG93bmVyRG9jRWxlbSk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVnZXRvd25lcmRvY3VtZW50MDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVnZXRvd25lcmRvY3VtZW50MDIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVnZXRwcmVmaXgwMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2RlZ2V0cHJlZml4MDMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yY2JhMGViCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2RlZ2V0cHJlZml4MDMuamF2YQpAQCAtMCwwICsxLDEwOSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlIG1ldGhvZCBnZXRQcmVmaXggcmV0dXJucyB0aGUgbmFtZXNwYWNlIHByZWZpeCBvZiB0aGlzIG5vZGUsIG9yIG51bGwgaWYgaXQgaXMgdW5zcGVjaWZpZWQuCisgKiAgIAorICogICBDZWF0ZSB0d28gbmV3IGVsZW1lbnQgbm9kZXMgYW5kIGF0cmlidXRlIG5vZGVzLCB3aXRoIGFuZCB3aXRob3V0IG5hbWVzcGFjZSBwcmVmaXhlcy4KKyAqICAgUmV0cmVpdmUgdGhlIHByZWZpeCBwYXJ0IG9mIHRoZWlyIHF1YWxpZmllZCBuYW1lcyB1c2luZyBnZXRQcmVmaXggYW5kIHZlcmlmeQorICogICBpZiBpdCBpcyBjb3JyZWN0LgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWdldHByZWZpeDAzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlZ2V0cHJlZml4MDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgRWxlbWVudCBxZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cjsKKyAgICAgIEF0dHIgcWF0dHI7CisgICAgICBTdHJpbmcgZWxlbU5vUHJlZml4OworICAgICAgU3RyaW5nIGVsZW1QcmVmaXg7CisgICAgICBTdHJpbmcgYXR0ck5vUHJlZml4OworICAgICAgU3RyaW5nIGF0dHJQcmVmaXg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L2VsZW0iLCAiZWxlbSIpOworICAgICAgcWVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9lbGVtIiwgInF1YWw6cWVsZW0iKTsKKyAgICAgIGF0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L2F0dHIiLCAiYXR0ciIpOworICAgICAgcWF0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L2F0dHIiLCAicXVhbDpxYXR0ciIpOworICAgICAgZWxlbU5vUHJlZml4ID0gZWxlbWVudC5nZXRQcmVmaXgoKTsKKyAgICAgIGVsZW1QcmVmaXggPSBxZWxlbWVudC5nZXRQcmVmaXgoKTsKKyAgICAgIGF0dHJOb1ByZWZpeCA9IGF0dHIuZ2V0UHJlZml4KCk7CisgICAgICBhdHRyUHJlZml4ID0gcWF0dHIuZ2V0UHJlZml4KCk7CisgICAgICBhc3NlcnROdWxsKCJub2RlZ2V0cHJlZml4MDNfMSIsIGVsZW1Ob1ByZWZpeCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVnZXRwcmVmaXgwM18yIiwgInF1YWwiLCBlbGVtUHJlZml4KTsKKyAgICAgIGFzc2VydE51bGwoIm5vZGVnZXRwcmVmaXgwM18zIiwgYXR0ck5vUHJlZml4KTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZWdldHByZWZpeDAzXzQiLCAicXVhbCIsIGF0dHJQcmVmaXgpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub2RlZ2V0cHJlZml4MDMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVnZXRwcmVmaXgwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZWhhc2F0dHJpYnV0ZXMwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2RlaGFzYXR0cmlidXRlczAxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDVjOTBkMgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZWhhc2F0dHJpYnV0ZXMwMS5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2QgaGFzQXR0cmlidXRlcyByZXR1cm5zIHdoZXRoZXIgdGhpcyBub2RlIChpZiBpdCBpcyBhbiBlbGVtZW50KSBoYXMgYW55IGF0dHJpYnV0ZXMuCisgKiAgUmV0cmVpdmUgYW4gZWxlbWVudCBub2RlIHdpdGhvdXQgYXR0cmlidXRlcy4gIFZlcmlmeSBpZiBoYXNBdHRyaWJ1dGVzIHJldHVybnMgZmFsc2UuCisgKiAgUmV0cmVpdmUgYW5vdGhlciBlbGVtZW50IG5vZGUgd2l0aCBhdHRyaWJ1dGVzLiAgVmVyaWZ5IGlmIGhhc0F0dHJpYnV0ZXMgcmV0dXJucyB0cnVlLiAKKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlSGFzQXR0cnMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlSGFzQXR0cnM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVoYXNhdHRyaWJ1dGVzMDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVoYXNhdHRyaWJ1dGVzMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBib29sZWFuIGhhc0F0dHJpYnV0ZXM7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBoYXNBdHRyaWJ1dGVzID0gZWxlbWVudC5oYXNBdHRyaWJ1dGVzKCk7CisgICAgICBhc3NlcnRGYWxzZSgibm9kZWhhc2F0dHJpYnV0ZXMwMV8xIiwgaGFzQXR0cmlidXRlcyk7CitlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgaGFzQXR0cmlidXRlcyA9IGVsZW1lbnQuaGFzQXR0cmlidXRlcygpOworICAgICAgYXNzZXJ0VHJ1ZSgibm9kZWhhc2F0dHJpYnV0ZXMwMV8yIiwgaGFzQXR0cmlidXRlcyk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVoYXNhdHRyaWJ1dGVzMDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVoYXNhdHRyaWJ1dGVzMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVoYXNhdHRyaWJ1dGVzMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZWhhc2F0dHJpYnV0ZXMwMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkzNjYwY2QKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVoYXNhdHRyaWJ1dGVzMDIuamF2YQpAQCAtMCwwICsxLDk5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKworUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKKworUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCisKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKwordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKKworUFVSUE9TRS4gIAorCisKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2QgaGFzQXR0cmlidXRlcyByZXR1cm5zIHdoZXRoZXIgdGhpcyBub2RlIChpZiBpdCBpcyBhbiBlbGVtZW50KSBoYXMgYW55IGF0dHJpYnV0ZXMuCisgKiAgUmV0cmlldmUgdGhlIGRvY1R5cGUgbm9kZS4gIFNpbmNlIHRoaXMgaXMgbm90IGFuIGVsZW1lbnQgbm9kZSBjaGVjayBpZiBoYXNBdHRyaWJ1dGVzIHJldHVybnMKKyAqICBudWxsLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVIYXNBdHRycyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVIYXNBdHRyczwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWhhc2F0dHJpYnV0ZXMwMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWhhc2F0dHJpYnV0ZXMwMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgYm9vbGVhbiBoYXNBdHRyaWJ1dGVzOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBoYXNBdHRyaWJ1dGVzID0gZG9jVHlwZS5oYXNBdHRyaWJ1dGVzKCk7CisgICAgICBhc3NlcnRGYWxzZSgibm9kZWhhc2F0dHJpYnV0ZXMwMiIsIGhhc0F0dHJpYnV0ZXMpOworfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub2RlaGFzYXR0cmlidXRlczAyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlaGFzYXR0cmlidXRlczAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2RlaGFzYXR0cmlidXRlczAzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVoYXNhdHRyaWJ1dGVzMDMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NTViOTM0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2RlaGFzYXR0cmlidXRlczAzLmphdmEKQEAgLTAsMCArMSw4OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIGhhc0F0dHJpYnV0ZXMgcmV0dXJucyB3aGV0aGVyIHRoaXMgbm9kZSAoaWYgaXQgaXMgYW4gZWxlbWVudCkgaGFzIGFueSBhdHRyaWJ1dGVzLgorICogIFJldHJlaXZlIGFuIGVsZW1lbnQgbm9kZSB3aXRoIGEgZGVmYXVsdCBhdHRyaWJ1dGVzLiAgVmVyaWZ5IGlmIGhhc0F0dHJpYnV0ZXMgcmV0dXJucyB0cnVlLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVIYXNBdHRycyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVIYXNBdHRyczwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWhhc2F0dHJpYnV0ZXMwMyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWhhc2F0dHJpYnV0ZXMwMyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgYm9vbGVhbiBoYXNBdHRyaWJ1dGVzOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDplbXBsb3llZSIpOworICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wRW1wbG95ZWVOb3ROdWxsIiwgZWxlbWVudCk7CisgICAgICBoYXNBdHRyaWJ1dGVzID0gZWxlbWVudC5oYXNBdHRyaWJ1dGVzKCk7CisgICAgICBhc3NlcnRUcnVlKCJoYXNBdHRyaWJ1dGVzIiwgaGFzQXR0cmlidXRlcyk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVoYXNhdHRyaWJ1dGVzMDMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVoYXNhdHRyaWJ1dGVzMDMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVoYXNhdHRyaWJ1dGVzMDQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZWhhc2F0dHJpYnV0ZXMwNC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVlZWYzZDAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVoYXNhdHRyaWJ1dGVzMDQuamF2YQpAQCAtMCwwICsxLDExMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCBoYXNBdHRyaWJ1dGVzIHJldHVybnMgd2hldGhlciB0aGlzIG5vZGUgKGlmIGl0IGlzIGFuIGVsZW1lbnQpIGhhcyBhbnkgYXR0cmlidXRlcy4KKyAqICBDcmVhdGUgYSBuZXcgRG9jdW1lbnQsIEVsZW1lbnQgYW5kIEF0dHIgbm9kZS4gIEFkZCB0aGUgQXR0ciB0byB0aGUgRWxlbWVudCBhbmQgYXBwZW5kIHRoZSAKKyAqICBFbGVtZW50IHRvIHRoZSBEb2N1bWVudC4gIFJldHJlaXZlIHRoZSBuZXdseSBjcmVhdGVkIGVsZW1lbnQgbm9kZSBmcm9tIHRoZSBkb2N1bWVudCBhbmQgY2hlY2sKKyAqICBpZiBpdCBoYXMgYXR0cmlidXRlcyB1c2luZyBoYXNBdHRyaWJ1dGVzLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVIYXNBdHRycyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVIYXNBdHRyczwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWhhc2F0dHJpYnV0ZXMwNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWhhc2F0dHJpYnV0ZXMwNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50IG5ld0RvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlID0gbnVsbDsKKworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIEVsZW1lbnQgZWxlbWVudFRlc3Q7CisgICAgICBFbGVtZW50IGVsZW1lbnREb2M7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIE5vZGUgc2V0Tm9kZTsKKyAgICAgIE5vZGUgYXBwZW5kZWRDaGlsZDsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgYm9vbGVhbiBoYXNBdHRyaWJ1dGVzOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgbmV3RG9jID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudCgiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLCAidGVzdCIsIGRvY1R5cGUpOworICAgICAgZWxlbWVudCA9IG5ld0RvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgImRvbTplbGVtIik7CisgICAgICBhdHRyaWJ1dGUgPSBuZXdEb2MuY3JlYXRlQXR0cmlidXRlKCJhdHRyIik7CisgICAgICBzZXROb2RlID0gZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlKGF0dHJpYnV0ZSk7CisgICAgICBlbGVtZW50RG9jID0gbmV3RG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGVsZW1lbnREb2MuYXBwZW5kQ2hpbGQoZWxlbWVudCk7CisgICAgICBlbGVtZW50TGlzdCA9IG5ld0RvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJlbGVtIik7CisgICAgICBlbGVtZW50VGVzdCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgaGFzQXR0cmlidXRlcyA9IGVsZW1lbnRUZXN0Lmhhc0F0dHJpYnV0ZXMoKTsKKyAgICAgIGFzc2VydFRydWUoIm5vZGVoYXNhdHRyaWJ1dGVzMDQiLCBoYXNBdHRyaWJ1dGVzKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbm9kZWhhc2F0dHJpYnV0ZXMwNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWhhc2F0dHJpYnV0ZXMwNC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZWlzc3VwcG9ydGVkMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZWlzc3VwcG9ydGVkMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NzQ3ZDk4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2RlaXNzdXBwb3J0ZWQwMS5qYXZhCkBAIC0wLDAgKzEsMTE2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2QgImlzU3VwcG9ydGVkKGZlYXR1cmUsdmVyc2lvbikiIFRlc3RzIHdoZXRoZXIgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiAKKyAqICBpbXBsZW1lbnRzIGEgc3BlY2lmaWMgZmVhdHVyZSBhbmQgdGhhdCBmZWF0dXJlIGlzIHN1cHBvcnRlZCBieSB0aGlzIG5vZGUuIAorICogIAorICogIENhbGwgdGhlIGlzU3VwcG9ydGVkIG1ldGhvZCBvbiB0aGUgZG9jdW1lbnQgZWxlbWVudCBub2RlIHdpdGggYSBjb21iaW5hdGlvbiBvZiBmZWF0dXJlcyAKKyAqICB2ZXJzaW9ucyBhbmQgdmVyc2lvbnMgYXMgYmVsb3cuICBWYWxpZCBmZWF0dXJlIG5hbWVzIGFyZSBjYXNlIGluc2Vuc2l0aXZlIGFuZCB2ZXJzaW9ucworICogICIyLjAiLCAiMS4wIiBhbmQgaWYgdGhlIHZlcnNpb24gaXMgbm90IHNwZWNpZmllZCwgc3VwcG9ydGluZyBhbnkgdmVyc2lvbiBvZiB0aGUgZmVhdHVyZQorICogIHNob3VsZCByZXR1cm4gdHJ1ZS4gIENoZWNrIGlmIHRoZSB2YWx1ZSByZXR1cm5lZCB2YWx1ZSB3YXMgdHJ1ZS4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtTm9kZS1zdXBwb3J0cyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1Ob2RlLXN1cHBvcnRzPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2RlaXNzdXBwb3J0ZWQwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZWlzc3VwcG9ydGVkMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBTdHJpbmcgdmVyc2lvbiA9ICIiOworICAgICAgU3RyaW5nIHZlcnNpb24xID0gIjEuMCI7CisgICAgICBTdHJpbmcgdmVyc2lvbjIgPSAiMi4wIjsKKyAgICAgIFN0cmluZyBmZWF0dXJlQ29yZTsKKyAgICAgIFN0cmluZyBmZWF0dXJlWE1MOworICAgICAgYm9vbGVhbiBzdWNjZXNzOworICAgICAgamF2YS51dGlsLkxpc3QgZmVhdHVyZXNYTUwgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgZmVhdHVyZXNYTUwuYWRkKCJYTUwiKTsKKyAgICAgIGZlYXR1cmVzWE1MLmFkZCgieG1MIik7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5MaXN0IGZlYXR1cmVzQ29yZSA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBmZWF0dXJlc0NvcmUuYWRkKCJDb3JlIik7CisgICAgICBmZWF0dXJlc0NvcmUuYWRkKCJDT1JFIik7CisgICAgICAKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGVsZW1lbnQgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA2MyA9IDA7IGluZGV4TjEwMDYzIDwgZmVhdHVyZXNYTUwuc2l6ZSgpOyBpbmRleE4xMDA2MysrKSB7CisgICAgICAgICAgZmVhdHVyZVhNTCA9IChTdHJpbmcpIGZlYXR1cmVzWE1MLmdldChpbmRleE4xMDA2Myk7CisgICAgc3VjY2VzcyA9IGVsZW1lbnQuaXNTdXBwb3J0ZWQoZmVhdHVyZVhNTCwgdmVyc2lvbik7CisgICAgICBhc3NlcnRUcnVlKCJub2RlaXNzdXBwb3J0ZWQwMV9YTUwxIiwgc3VjY2Vzcyk7CisgICAgICBzdWNjZXNzID0gZWxlbWVudC5pc1N1cHBvcnRlZChmZWF0dXJlWE1MLCB2ZXJzaW9uMSk7CisgICAgICBhc3NlcnRUcnVlKCJub2RlaXNzdXBwb3J0ZWQwMV9YTUwyIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDdDID0gMDsgaW5kZXhOMTAwN0MgPCBmZWF0dXJlc0NvcmUuc2l6ZSgpOyBpbmRleE4xMDA3QysrKSB7CisgICAgICAgICAgZmVhdHVyZUNvcmUgPSAoU3RyaW5nKSBmZWF0dXJlc0NvcmUuZ2V0KGluZGV4TjEwMDdDKTsKKyAgICBzdWNjZXNzID0gZWxlbWVudC5pc1N1cHBvcnRlZChmZWF0dXJlQ29yZSwgdmVyc2lvbik7CisgICAgICBhc3NlcnRUcnVlKCJub2RlaXNzdXBwb3J0ZWQwMV9Db3JlMSIsIHN1Y2Nlc3MpOworICAgICAgc3VjY2VzcyA9IGVsZW1lbnQuaXNTdXBwb3J0ZWQoZmVhdHVyZUNvcmUsIHZlcnNpb24xKTsKKyAgICAgIHN1Y2Nlc3MgPSBlbGVtZW50LmlzU3VwcG9ydGVkKGZlYXR1cmVDb3JlLCB2ZXJzaW9uMik7CisgICAgICBhc3NlcnRUcnVlKCJub2RlaXNzdXBwb3J0ZWQwMV9Db3JlMyIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVpc3N1cHBvcnRlZDAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlaXNzdXBwb3J0ZWQwMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZWlzc3VwcG9ydGVkMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZWlzc3VwcG9ydGVkMDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZGI2ZTFhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2RlaXNzdXBwb3J0ZWQwMi5qYXZhCkBAIC0wLDAgKzEsMTE2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2QgImlzU3VwcG9ydGVkKGZlYXR1cmUsdmVyc2lvbikiIFRlc3RzIHdoZXRoZXIgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiAKKyAqICBpbXBsZW1lbnRzIGEgc3BlY2lmaWMgZmVhdHVyZSBhbmQgdGhhdCBmZWF0dXJlIGlzIHN1cHBvcnRlZCBieSB0aGlzIG5vZGUuIAorICogIAorICogIENhbGwgdGhlIGlzU3VwcG9ydGVkIG1ldGhvZCBvbiBhIG5ldyBhdHRyaWJ1dGUgbm9kZSB3aXRoIGEgY29tYmluYXRpb24gb2YgZmVhdHVyZXMgCisgKiAgdmVyc2lvbnMgYW5kIHZlcnNpb25zIGFzIGJlbG93LiAgVmFsaWQgZmVhdHVyZSBuYW1lcyBhcmUgY2FzZSBpbnNlbnNpdGl2ZSBhbmQgdmVyc2lvbnMKKyAqICAiMi4wIiwgIjEuMCIgYW5kIGlmIHRoZSB2ZXJzaW9uIGlzIG5vdCBzcGVjaWZpZWQsIHN1cHBvcnRpbmcgYW55IHZlcnNpb24gb2YgdGhlIGZlYXR1cmUKKyAqICBzaG91bGQgcmV0dXJuIHRydWUuICBDaGVjayBpZiB0aGUgdmFsdWUgcmV0dXJuZWQgdmFsdWUgd2FzIHRydWUuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtTm9kZS1zdXBwb3J0czwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWlzc3VwcG9ydGVkMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVpc3N1cHBvcnRlZDAyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICBTdHJpbmcgdmVyc2lvbiA9ICIiOworICAgICAgU3RyaW5nIHZlcnNpb24xID0gIjEuMCI7CisgICAgICBTdHJpbmcgdmVyc2lvbjIgPSAiMi4wIjsKKyAgICAgIFN0cmluZyBmZWF0dXJlQ29yZTsKKyAgICAgIFN0cmluZyBmZWF0dXJlWE1MOworICAgICAgYm9vbGVhbiBzdWNjZXNzOworICAgICAgamF2YS51dGlsLkxpc3QgZmVhdHVyZXNYTUwgPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdCgpOworICAgICAgZmVhdHVyZXNYTUwuYWRkKCJYTUwiKTsKKyAgICAgIGZlYXR1cmVzWE1MLmFkZCgieG1MIik7CisgICAgICAKKyAgICAgIGphdmEudXRpbC5MaXN0IGZlYXR1cmVzQ29yZSA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBmZWF0dXJlc0NvcmUuYWRkKCJDb3JlIik7CisgICAgICBmZWF0dXJlc0NvcmUuYWRkKCJDT1JFIik7CisgICAgICAKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGF0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoIlRlc3RBdHRyIik7CisgICAgICBmb3IgKGludCBpbmRleE4xMDA2NCA9IDA7IGluZGV4TjEwMDY0IDwgZmVhdHVyZXNYTUwuc2l6ZSgpOyBpbmRleE4xMDA2NCsrKSB7CisgICAgICAgICAgZmVhdHVyZVhNTCA9IChTdHJpbmcpIGZlYXR1cmVzWE1MLmdldChpbmRleE4xMDA2NCk7CisgICAgc3VjY2VzcyA9IGF0dHJpYnV0ZS5pc1N1cHBvcnRlZChmZWF0dXJlWE1MLCB2ZXJzaW9uKTsKKyAgICAgIGFzc2VydFRydWUoIm5vZGVpc3N1cHBvcnRlZDAyX1hNTDEiLCBzdWNjZXNzKTsKKyAgICAgIHN1Y2Nlc3MgPSBhdHRyaWJ1dGUuaXNTdXBwb3J0ZWQoZmVhdHVyZVhNTCwgdmVyc2lvbjEpOworICAgICAgYXNzZXJ0VHJ1ZSgibm9kZWlzc3VwcG9ydGVkMDJfWE1MMiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgICBmb3IgKGludCBpbmRleE4xMDA3RCA9IDA7IGluZGV4TjEwMDdEIDwgZmVhdHVyZXNDb3JlLnNpemUoKTsgaW5kZXhOMTAwN0QrKykgeworICAgICAgICAgIGZlYXR1cmVDb3JlID0gKFN0cmluZykgZmVhdHVyZXNDb3JlLmdldChpbmRleE4xMDA3RCk7CisgICAgc3VjY2VzcyA9IGF0dHJpYnV0ZS5pc1N1cHBvcnRlZChmZWF0dXJlQ29yZSwgdmVyc2lvbik7CisgICAgICBhc3NlcnRUcnVlKCJub2RlaXNzdXBwb3J0ZWQwMl9Db3JlMSIsIHN1Y2Nlc3MpOworICAgICAgc3VjY2VzcyA9IGF0dHJpYnV0ZS5pc1N1cHBvcnRlZChmZWF0dXJlQ29yZSwgdmVyc2lvbjEpOworICAgICAgc3VjY2VzcyA9IGF0dHJpYnV0ZS5pc1N1cHBvcnRlZChmZWF0dXJlQ29yZSwgdmVyc2lvbjIpOworICAgICAgYXNzZXJ0VHJ1ZSgibm9kZWlzc3VwcG9ydGVkMDJfQ29yZTMiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub2RlaXNzdXBwb3J0ZWQwMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZWlzc3VwcG9ydGVkMDIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVpc3N1cHBvcnRlZDAzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVpc3N1cHBvcnRlZDAzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjU2NWM0MgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZWlzc3VwcG9ydGVkMDMuamF2YQpAQCAtMCwwICsxLDEwMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKworKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCisKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKworSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAorCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisKK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCisKK1BVUlBPU0UuICAKKworCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kICJpc1N1cHBvcnRlZChmZWF0dXJlLHZlcnNpb24pIiBUZXN0cyB3aGV0aGVyIHRoZSBET00gaW1wbGVtZW50YXRpb24gCisgKiAgaW1wbGVtZW50cyBhIHNwZWNpZmljIGZlYXR1cmUgYW5kIHRoYXQgZmVhdHVyZSBpcyBzdXBwb3J0ZWQgYnkgdGhpcyBub2RlLiAKKyAqICAKKyAqICBDYWxsIHRoZSBpc1N1cHBvcnRlZCBtZXRob2Qgc3BlY2lmeWluZyBlbXB0eSBzdHJpbmdzIGZvciBmZWF0dXJlIGFuZCB2ZXJzaW9uIG9uIGEgZG9jVHlwZQorICogIE5vZGUuICBDaGVjayBpZiB0aGUgdmFsdWUgcmV0dXJuZWQgdmFsdWUgd2FzIGZhbHNlLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1Ob2RlLXN1cHBvcnRzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVpc3N1cHBvcnRlZDAzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlaXNzdXBwb3J0ZWQwMyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgYm9vbGVhbiBzdWNjZXNzOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBzdWNjZXNzID0gZG9jVHlwZS5pc1N1cHBvcnRlZCgiIiwgIiIpOworICAgICAgYXNzZXJ0RmFsc2UoIm5vZGVpc3N1cHBvcnRlZDAzIiwgc3VjY2Vzcyk7Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVpc3N1cHBvcnRlZDAzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlaXNzdXBwb3J0ZWQwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZWlzc3VwcG9ydGVkMDQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZWlzc3VwcG9ydGVkMDQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMzE4MGM4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2RlaXNzdXBwb3J0ZWQwNC5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCAiaXNTdXBwb3J0ZWQoZmVhdHVyZSx2ZXJzaW9uKSIgVGVzdHMgd2hldGhlciB0aGUgRE9NIGltcGxlbWVudGF0aW9uIAorICogIGltcGxlbWVudHMgYSBzcGVjaWZpYyBmZWF0dXJlIGFuZCB0aGF0IGZlYXR1cmUgaXMgc3VwcG9ydGVkIGJ5IHRoaXMgbm9kZS4gCisgKiAgCisgKiAgQ2FsbCB0aGUgaXNTdXBwb3J0ZWQgbWV0aG9kIHNwZWNpZnlpbmcgZW1wdHkgc3RyaW5ncyBmb3IgZmVhdHVyZSBhbmQgdmVyc2lvbiBvbiBhIAorICogIG5ldyBFbnRpdHlSZWZlcmVuY2Ugbm9kZS4gIENoZWNrIGlmIHRoZSB2YWx1ZSByZXR1cm5lZCB2YWx1ZSB3YXMgZmFsc2UuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtTm9kZS1zdXBwb3J0czwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZWlzc3VwcG9ydGVkMDQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVpc3N1cHBvcnRlZDA0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRW50aXR5UmVmZXJlbmNlIGVudFJlZjsKKyAgICAgIGJvb2xlYW4gc3VjY2VzczsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGVudFJlZiA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDEiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZW50UmVmKTsKKyAgICAgIHN1Y2Nlc3MgPSBlbnRSZWYuaXNTdXBwb3J0ZWQoIlhNTCBDT1JFIiwgIiIpOworICAgICAgYXNzZXJ0RmFsc2UoIm5vZGVpc3N1cHBvcnRlZDA0Iiwgc3VjY2Vzcyk7Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVpc3N1cHBvcnRlZDA0IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlaXNzdXBwb3J0ZWQwNC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZWlzc3VwcG9ydGVkMDUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZWlzc3VwcG9ydGVkMDUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYWE1YTkwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2RlaXNzdXBwb3J0ZWQwNS5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKworUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKKworUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCisKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKwordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKKworUFVSUE9TRS4gIAorCisKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2QgImlzU3VwcG9ydGVkKGZlYXR1cmUsdmVyc2lvbikiIFRlc3RzIHdoZXRoZXIgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiAKKyAqICBpbXBsZW1lbnRzIGEgc3BlY2lmaWMgZmVhdHVyZSBhbmQgdGhhdCBmZWF0dXJlIGlzIHN1cHBvcnRlZCBieSB0aGlzIG5vZGUuIAorICogIAorICogIENhbGwgdGhlIGlzU3VwcG9ydGVkIG1ldGhvZCBzcGVjaWZ5aW5nIGJhZCB2YWx1ZXMgZm9yIGZlYXR1cmUgYW5kIHZlcnNpb24gb24gYSBuZXcgCisgKiAgUHJvY2Vzc2luZyBJbnN0cnVjdGlvbiBub2RlLiAgQ2hlY2sgaWYgdGhlIHZhbHVlIHJldHVybmVkIGZyb20gdGhpcyBtZXRob2QgdmFsdWUgd2FzIGZhbHNlLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1Ob2RlLXN1cHBvcnRzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHM8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVpc3N1cHBvcnRlZDA1IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2RlaXNzdXBwb3J0ZWQwNShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBwaTsKKyAgICAgIGJvb2xlYW4gc3VjY2VzczsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIHBpID0gZG9jLmNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbigiUElUYXJnZXQiLCAiUElEYXRhIik7CisgICAgICBzdWNjZXNzID0gcGkuaXNTdXBwb3J0ZWQoIi0iLCAiKyIpOworICAgICAgYXNzZXJ0RmFsc2UoIm5vZGVpc3N1cHBvcnRlZDA1Iiwgc3VjY2Vzcyk7Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVpc3N1cHBvcnRlZDA1IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2RlaXNzdXBwb3J0ZWQwNS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZW5vcm1hbGl6ZTAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVub3JtYWxpemUwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIyZDQ1NjMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVub3JtYWxpemUwMS5qYXZhCkBAIC0wLDAgKzEsMTkzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2QgIm5vcm1hbGl6ZSIgcHV0cyBhbGwgVGV4dCBub2RlcyBpbiB0aGUgZnVsbCBkZXB0aCBvZiB0aGUgc3ViLXRyZWUgdW5kZXJuZWF0aCAKKyAqICB0aGlzIE5vZGUsIGluY2x1ZGluZyBhdHRyaWJ1dGUgbm9kZXMsIGludG8gYSAibm9ybWFsIiBmb3JtIHdoZXJlIG9ubHkgc3RydWN0dXJlIAorICogIChlLmcuLCBlbGVtZW50cywgY29tbWVudHMsIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zLCBDREFUQSBzZWN0aW9ucywgYW5kIGVudGl0eSByZWZlcmVuY2VzKSAKKyAqICBzZXBhcmF0ZXMgVGV4dCBub2RlcywgaS5lLiwgdGhlcmUgYXJlIG5laXRoZXIgYWRqYWNlbnQgVGV4dCBub2RlcyBub3IgZW1wdHkgVGV4dCBub2Rlcy4gCisgKiAgCisgKiAgQ3JlYXRlIGEgZG9tIHRyZWUgY29uc2lzdGluZyBvZiBlbGVtZW50cywgY29tbWVudHMsIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zLCBDREFUQSBzZWN0aW9ucywgCisgKiAgYW5kIGVudGl0eSByZWZlcmVuY2VzIG5vZGVzIHNlcGVyYXRlZCBieSB0ZXh0IG5vZGVzLiAgQ2hlY2sgdGhlIGxlbmd0aCBvZiB0aGUgbm9kZSBsaXN0IG9mIGVhY2gKKyAqICBiZWZvcmUgYW5kIGFmdGVyIG5vcm1hbGl6ZSBoYXMgYmVlbiBjYWxsZWQuICAKKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1ub3JtYWxpemUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1ub3JtYWxpemU8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVub3JtYWxpemUwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZW5vcm1hbGl6ZTAxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudCBuZXdEb2M7CisgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZU51bGwgPSBudWxsOworCisgICAgICBFbGVtZW50IGRvY3VtZW50RWxlbWVudDsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDE7CisgICAgICBFbGVtZW50IGVsZW1lbnQyOworICAgICAgRWxlbWVudCBlbGVtZW50MzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDQ7CisgICAgICBFbGVtZW50IGVsZW1lbnQ1OworICAgICAgRWxlbWVudCBlbGVtZW50NjsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDc7CisgICAgICBUZXh0IHRleHQxOworICAgICAgVGV4dCB0ZXh0MjsKKyAgICAgIFRleHQgdGV4dDM7CisgICAgICBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gcGk7CisgICAgICBDREFUQVNlY3Rpb24gY0RhdGE7CisgICAgICBDb21tZW50IGNvbW1lbnQ7CisgICAgICBFbnRpdHlSZWZlcmVuY2UgZW50UmVmOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGFwcGVuZGVkQ2hpbGQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgIG5ld0RvYyA9IGRvbUltcGwuY3JlYXRlRG9jdW1lbnQoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgImRvbTpyb290IiwgZG9jVHlwZU51bGwpOworICAgICAgZWxlbWVudDEgPSBuZXdEb2MuY3JlYXRlRWxlbWVudCgiZWxlbWVudDEiKTsKKyAgICAgIGVsZW1lbnQyID0gbmV3RG9jLmNyZWF0ZUVsZW1lbnQoImVsZW1lbnQyIik7CisgICAgICBlbGVtZW50MyA9IG5ld0RvYy5jcmVhdGVFbGVtZW50KCJlbGVtZW50MyIpOworICAgICAgZWxlbWVudDQgPSBuZXdEb2MuY3JlYXRlRWxlbWVudCgiZWxlbWVudDQiKTsKKyAgICAgIGVsZW1lbnQ1ID0gbmV3RG9jLmNyZWF0ZUVsZW1lbnQoImVsZW1lbnQ1Iik7CisgICAgICBlbGVtZW50NiA9IG5ld0RvYy5jcmVhdGVFbGVtZW50KCJlbGVtZW50NiIpOworICAgICAgZWxlbWVudDcgPSBuZXdEb2MuY3JlYXRlRWxlbWVudCgiZWxlbWVudDciKTsKKyAgICAgIHRleHQxID0gbmV3RG9jLmNyZWF0ZVRleHROb2RlKCJ0ZXh0MSIpOworICAgICAgdGV4dDIgPSBuZXdEb2MuY3JlYXRlVGV4dE5vZGUoInRleHQyIik7CisgICAgICB0ZXh0MyA9IG5ld0RvYy5jcmVhdGVUZXh0Tm9kZSgidGV4dDMiKTsKKyAgICAgIGNEYXRhID0gbmV3RG9jLmNyZWF0ZUNEQVRBU2VjdGlvbigiQ2RhdGEiKTsKKyAgICAgIGNvbW1lbnQgPSBuZXdEb2MuY3JlYXRlQ29tbWVudCgiY29tbWVudCIpOworICAgICAgcGkgPSBuZXdEb2MuY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKCJQSVRhcmdldCIsICJQSURhdGEiKTsKKyAgICAgIGVudFJlZiA9IG5ld0RvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoIkVudFJlZiIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworICAgICAgZG9jdW1lbnRFbGVtZW50ID0gbmV3RG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGRvY3VtZW50RWxlbWVudC5hcHBlbmRDaGlsZChlbGVtZW50MSk7CisgICAgICBhcHBlbmRlZENoaWxkID0gZWxlbWVudDIuYXBwZW5kQ2hpbGQodGV4dDEpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGVsZW1lbnQyLmFwcGVuZENoaWxkKHRleHQyKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBlbGVtZW50Mi5hcHBlbmRDaGlsZCh0ZXh0Myk7CisgICAgICBhcHBlbmRlZENoaWxkID0gZWxlbWVudDEuYXBwZW5kQ2hpbGQoZWxlbWVudDIpOworICAgICAgdGV4dDEgPSAoVGV4dCkgdGV4dDEuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgIHRleHQyID0gKFRleHQpIHRleHQyLmNsb25lTm9kZShmYWxzZSk7CisgICAgICBhcHBlbmRlZENoaWxkID0gZWxlbWVudDMuYXBwZW5kQ2hpbGQoZW50UmVmKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBlbGVtZW50My5hcHBlbmRDaGlsZCh0ZXh0MSk7CisgICAgICBhcHBlbmRlZENoaWxkID0gZWxlbWVudDMuYXBwZW5kQ2hpbGQodGV4dDIpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGVsZW1lbnQxLmFwcGVuZENoaWxkKGVsZW1lbnQzKTsKKyAgICAgIHRleHQxID0gKFRleHQpIHRleHQxLmNsb25lTm9kZShmYWxzZSk7CisgICAgICB0ZXh0MiA9IChUZXh0KSB0ZXh0Mi5jbG9uZU5vZGUoZmFsc2UpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGVsZW1lbnQ0LmFwcGVuZENoaWxkKGNEYXRhKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBlbGVtZW50NC5hcHBlbmRDaGlsZCh0ZXh0MSk7CisgICAgICBhcHBlbmRlZENoaWxkID0gZWxlbWVudDQuYXBwZW5kQ2hpbGQodGV4dDIpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGVsZW1lbnQxLmFwcGVuZENoaWxkKGVsZW1lbnQ0KTsKKyAgICAgIHRleHQyID0gKFRleHQpIHRleHQyLmNsb25lTm9kZShmYWxzZSk7CisgICAgICB0ZXh0MyA9IChUZXh0KSB0ZXh0My5jbG9uZU5vZGUoZmFsc2UpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGVsZW1lbnQ1LmFwcGVuZENoaWxkKGNvbW1lbnQpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGVsZW1lbnQ1LmFwcGVuZENoaWxkKHRleHQyKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBlbGVtZW50NS5hcHBlbmRDaGlsZCh0ZXh0Myk7CisgICAgICBhcHBlbmRlZENoaWxkID0gZWxlbWVudDEuYXBwZW5kQ2hpbGQoZWxlbWVudDUpOworICAgICAgdGV4dDIgPSAoVGV4dCkgdGV4dDIuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgIHRleHQzID0gKFRleHQpIHRleHQzLmNsb25lTm9kZShmYWxzZSk7CisgICAgICBhcHBlbmRlZENoaWxkID0gZWxlbWVudDYuYXBwZW5kQ2hpbGQocGkpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGVsZW1lbnQ2LmFwcGVuZENoaWxkKHRleHQyKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBlbGVtZW50Ni5hcHBlbmRDaGlsZCh0ZXh0Myk7CisgICAgICBhcHBlbmRlZENoaWxkID0gZWxlbWVudDEuYXBwZW5kQ2hpbGQoZWxlbWVudDYpOworICAgICAgZW50UmVmID0gKEVudGl0eVJlZmVyZW5jZSkgZW50UmVmLmNsb25lTm9kZShmYWxzZSk7CisgICAgICB0ZXh0MSA9IChUZXh0KSB0ZXh0MS5jbG9uZU5vZGUoZmFsc2UpOworICAgICAgdGV4dDIgPSAoVGV4dCkgdGV4dDIuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgIHRleHQzID0gKFRleHQpIHRleHQzLmNsb25lTm9kZShmYWxzZSk7CisgICAgICBhcHBlbmRlZENoaWxkID0gZWxlbWVudDcuYXBwZW5kQ2hpbGQoZW50UmVmKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBlbGVtZW50Ny5hcHBlbmRDaGlsZCh0ZXh0MSk7CisgICAgICBhcHBlbmRlZENoaWxkID0gZWxlbWVudDcuYXBwZW5kQ2hpbGQodGV4dDIpOworICAgICAgYXBwZW5kZWRDaGlsZCA9IGVsZW1lbnQ3LmFwcGVuZENoaWxkKHRleHQzKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSBlbGVtZW50MS5hcHBlbmRDaGlsZChlbGVtZW50Nyk7CisgICAgICBlbGVtZW50TGlzdCA9IGVsZW1lbnQxLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGFzc2VydFNpemUoIm5vZGVOb3JtYWxpemUwMV8xQmVmIiwgNiwgZWxlbWVudExpc3QpOworICAgICAgZWxlbWVudExpc3QgPSBlbGVtZW50Mi5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBhc3NlcnRTaXplKCJub2RlTm9ybWFsaXplMDFfMkJlZiIsIDMsIGVsZW1lbnRMaXN0KTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZWxlbWVudDMuZ2V0Q2hpbGROb2RlcygpOworICAgICAgYXNzZXJ0U2l6ZSgibm9kZU5vcm1hbGl6ZTAxXzNCZWYiLCAzLCBlbGVtZW50TGlzdCk7CisgICAgICBlbGVtZW50TGlzdCA9IGVsZW1lbnQ0LmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGFzc2VydFNpemUoIm5vZGVOb3JtYWxpemUwMV80QmVmIiwgMywgZWxlbWVudExpc3QpOworICAgICAgZWxlbWVudExpc3QgPSBlbGVtZW50NS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBhc3NlcnRTaXplKCJub2RlTm9ybWFsaXplMDFfNUJlZiIsIDMsIGVsZW1lbnRMaXN0KTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZWxlbWVudDYuZ2V0Q2hpbGROb2RlcygpOworICAgICAgYXNzZXJ0U2l6ZSgibm9kZU5vcm1hbGl6ZTAxXzZCZWYiLCAzLCBlbGVtZW50TGlzdCk7CisgICAgICBlbGVtZW50TGlzdCA9IGVsZW1lbnQ3LmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGFzc2VydFNpemUoIm5vZGVOb3JtYWxpemUwMV83QmVmIiwgNCwgZWxlbWVudExpc3QpOworICAgICAgbmV3RG9jLm5vcm1hbGl6ZSgpOworICAgICAgZWxlbWVudExpc3QgPSBlbGVtZW50MS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBhc3NlcnRTaXplKCJub2RlTm9ybWFsaXplMDFfMUFmdCIsIDYsIGVsZW1lbnRMaXN0KTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZWxlbWVudDIuZ2V0Q2hpbGROb2RlcygpOworICAgICAgYXNzZXJ0U2l6ZSgibm9kZU5vcm1hbGl6ZTAxXzJBZnQiLCAxLCBlbGVtZW50TGlzdCk7CisgICAgICBlbGVtZW50TGlzdCA9IGVsZW1lbnQzLmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGFzc2VydFNpemUoIm5vZGVOb3JtYWxpemUwMV8zQWZ0IiwgMiwgZWxlbWVudExpc3QpOworICAgICAgZWxlbWVudExpc3QgPSBlbGVtZW50NC5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBhc3NlcnRTaXplKCJub2RlTm9ybWFsaXplMDFfNEFmdCIsIDIsIGVsZW1lbnRMaXN0KTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZWxlbWVudDUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgYXNzZXJ0U2l6ZSgibm9kZU5vcm1hbGl6ZTAxXzVBZnQiLCAyLCBlbGVtZW50TGlzdCk7CisgICAgICBlbGVtZW50TGlzdCA9IGVsZW1lbnQ2LmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGFzc2VydFNpemUoIm5vZGVOb3JtYWxpemUwMV82QWZ0IiwgMiwgZWxlbWVudExpc3QpOworICAgICAgZWxlbWVudExpc3QgPSBlbGVtZW50Ny5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBhc3NlcnRTaXplKCJub2RlTm9ybWFsaXplMDFfN0FmdCIsIDIsIGVsZW1lbnRMaXN0KTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbm9kZW5vcm1hbGl6ZTAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2Rlbm9ybWFsaXplMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2Rlc2V0cHJlZml4MDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZmQyZTUwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2Rlc2V0cHJlZml4MDEuamF2YQpAQCAtMCwwICsxLDEwMyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCBzZXRQcmVmaXggc2V0cyB0aGUgbmFtZXNwYWNlIHByZWZpeCBvZiB0aGlzIG5vZGUuICBOb3RlIHRoYXQgc2V0dGluZyB0aGlzIGF0dHJpYnV0ZSwgCisgKiAgd2hlbiBwZXJtaXR0ZWQsIGNoYW5nZXMgdGhlIG5vZGVOYW1lIGF0dHJpYnV0ZSwgd2hpY2ggaG9sZHMgdGhlIHF1YWxpZmllZCBuYW1lLCBhcyB3ZWxsIGFzIHRoZSAKKyAqICB0YWdOYW1lIGFuZCBuYW1lIGF0dHJpYnV0ZXMgb2YgdGhlIEVsZW1lbnQgYW5kIEF0dHIgaW50ZXJmYWNlcywgd2hlbiBhcHBsaWNhYmxlLgorICogIAorICogIENyZWF0ZSBhIG5ldyBlbGVtZW50IG5vZGUgd2l0aCBhIG5hbWVzcGFjZSBwcmVmaXguICBBZGQgaXQgdG8gYSBuZXcgRG9jdW1lbnRGcmFnbWVudCBOb2RlIHdpdGhvdXQKKyAqICBhIHByZWZpeC4gIENhbGwgc2V0UHJlZml4IG9uIHRoZSBlbGVtZW4gbm9kZS4gIENoZWNrIGlmIHRoZSBwcmVmaXggd2FzIHNldCBjb3JyZWN0bHkgb24gdGhlIGVsZW1lbnQuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2Rlc2V0cHJlZml4MDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVzZXRwcmVmaXgwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50RnJhZ21lbnQgZG9jRnJhZ21lbnQ7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBTdHJpbmcgZWxlbWVudFRhZ05hbWU7CisgICAgICBTdHJpbmcgZWxlbWVudE5vZGVOYW1lOworICAgICAgTm9kZSBhcHBlbmRlZENoaWxkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIHRydWUpOworICAgICAgZG9jRnJhZ21lbnQgPSBkb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOworICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgImVtcDphZGRyZXNzIik7CisgICAgICBhcHBlbmRlZENoaWxkID0gZG9jRnJhZ21lbnQuYXBwZW5kQ2hpbGQoZWxlbWVudCk7CisgICAgICBlbGVtZW50LnNldFByZWZpeCgiZG1zdGMiKTsKKyAgICAgIGVsZW1lbnRUYWdOYW1lID0gZWxlbWVudC5nZXRUYWdOYW1lKCk7CisgICAgICBlbGVtZW50Tm9kZU5hbWUgPSBlbGVtZW50LmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVzZXRwcmVmaXgwMV90YWduYW1lIiwgImRtc3RjOmFkZHJlc3MiLCBlbGVtZW50VGFnTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVzZXRwcmVmaXgwMV9ub2RlTmFtZSIsICJkbXN0YzphZGRyZXNzIiwgZWxlbWVudE5vZGVOYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbm9kZXNldHByZWZpeDAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2Rlc2V0cHJlZml4MDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2Rlc2V0cHJlZml4MDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZjcxMGQ3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2Rlc2V0cHJlZml4MDIuamF2YQpAQCAtMCwwICsxLDEwOCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCBzZXRQcmVmaXggc2V0cyB0aGUgbmFtZXNwYWNlIHByZWZpeCBvZiB0aGlzIG5vZGUuICBOb3RlIHRoYXQgc2V0dGluZyB0aGlzIGF0dHJpYnV0ZSwgCisgKiAgd2hlbiBwZXJtaXR0ZWQsIGNoYW5nZXMgdGhlIG5vZGVOYW1lIGF0dHJpYnV0ZSwgd2hpY2ggaG9sZHMgdGhlIHF1YWxpZmllZCBuYW1lLCBhcyB3ZWxsIGFzIHRoZSAKKyAqICB0YWdOYW1lIGFuZCBuYW1lIGF0dHJpYnV0ZXMgb2YgdGhlIEVsZW1lbnQgYW5kIEF0dHIgaW50ZXJmYWNlcywgd2hlbiBhcHBsaWNhYmxlLgorICogIENyZWF0ZSBhIG5ldyBhdHRyaWJ1dGUgbm9kZSBhbmQgYWRkIGl0IHRvIGFuIGVsZW1lbnQgbm9kZSB3aXRoIGFuIGV4aXN0aW5nIGF0dHJpYnV0ZSBoYXZpbmcKKyAqICB0aGUgc2FtZSBsb2NhbE5hbWUgYXMgdGhpcyBhdHRyaWJ1dGUgYnV0IGRpZmZlcmVudCBuYW1lc3BhY2VVUkkuICBDaGFuZ2UgdGhlIHByZWZpeCBvZiB0aGUKKyAqICBuZXdseSBjcmVhdGVkIGF0dHJpYnV0ZSB1c2luZyBzZXRQcmVmaXguICBDaGVjayBpZiB0aGUgbmV3IGF0dHJpYnV0ZSBub2RlTmFtZSBoYXMgY2hhbmdlZAorICogIGFuZCB0aGUgZXhpc3RpbmcgYXR0cmlidXRlIGlzIHRoZSBzYW1lLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZXNldHByZWZpeDAyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2Rlc2V0cHJlZml4MDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgQXR0ciBuZXdBdHRyaWJ1dGU7CisgICAgICBOb2RlIHNldE5vZGU7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgIFN0cmluZyBuZXdBdHRyTmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIG5ld0F0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLCAidGVzdDphZGRyZXNzIik7CisgICAgICBzZXROb2RlID0gZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMobmV3QXR0cmlidXRlKTsKKyAgICAgIG5ld0F0dHJpYnV0ZS5zZXRQcmVmaXgoImRvbSIpOworICAgICAgYXR0cmlidXRlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlTlMoImh0dHA6Ly93d3cudXNhLmNvbSIsICJkb21lc3RpYyIpOworICAgICAgYXR0ck5hbWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgIG5ld0F0dHJOYW1lID0gbmV3QXR0cmlidXRlLmdldE5vZGVOYW1lKCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVzZXRwcmVmaXgwMl9hdHRyTmFtZSIsICJkbXN0Yzpkb21lc3RpYyIsIGF0dHJOYW1lKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZXNldHByZWZpeDAyX25ld0F0dHJOYW1lIiwgImRvbTphZGRyZXNzIiwgbmV3QXR0ck5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub2Rlc2V0cHJlZml4MDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVzZXRwcmVmaXgwMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZXNldHByZWZpeDAzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNlYWY1YTcKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwMy5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2Qgc2V0UHJlZml4IHJhaXNlcyBhIE5BTUVTUEFDRV9FUlIgaWYgdGhlIG5hbWVzcGFjZVVSSSBvZiB0aGlzIG5vZGUgaXMgbnVsbC4KKyAqICAKKyAqICBDcmVhdGUgYSBuZXcgZWxlbWVudCBub2RlIHdpdGhvdXQgYSBuYW1lc3BhY2UgcHJlZml4LiAgQ2FsbCBzZXRQcmVmaXggb24gdGhlIG5ld2x5IGNyZWF0ZWQgZWxlbWVuZW50IG5vZGUuICAKKyAqICBDaGVjayBpZiBhIE5BTUVTUEFDRV9FUlIgaXMgdGhyb3duLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZXNldHByZWZpeDAzIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2Rlc2V0cHJlZml4MDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCJhZGRyZXNzIik7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVsZW1lbnQuc2V0UHJlZml4KCJ0ZXN0Iik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub2Rlc2V0cHJlZml4MDMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVzZXRwcmVmaXgwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZXNldHByZWZpeDA0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwNC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlkMTcwMzEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwNC5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2Qgc2V0UHJlZml4IHJhaXNlcyBhIE5BTUVTUEFDRV9FUlIgaWYgdGhlIG5hbWVzcGFjZVVSSSBvZiB0aGlzIG5vZGUgaXMgbnVsbC4KKyAqICBSZXRyZWl2ZSB0aGUgYSBkZWZhdWx0IEF0dHJpYnV0ZSBub2RlIHdoaWNoIGRvZXMgbm90IGhhdmUgYSBuYW1lc3BhY2UgcHJlZml4LiBDYWxsIHRoZSBzZXRQcmVmaXgKKyAqICBtZXRob2Qgb24gaXQuICBDaGVjayBpZiBhIE5BTUVTUEFDRV9FUlIgaXMgdGhyb3duLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2Rlc2V0cHJlZml4MDQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVzZXRwcmVmaXgwNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZSwKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy52YWxpZGF0aW5nCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDplbXBsb3llZSIpOworICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wRW1wbG95ZWVOb3ROdWxsIiwgZWxlbWVudCk7CisgICAgICBhdHRyaWJ1dGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5vZGVOUyhudWxsTlMsICJkZWZhdWx0QXR0ciIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhdHRyaWJ1dGUuc2V0UHJlZml4KCJ0ZXN0Iik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgibm9kZXNldHByZWZpeDA0Iiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXNldHByZWZpeDA0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2Rlc2V0cHJlZml4MDUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZXNldHByZWZpeDA1LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjliYTFjNgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZXNldHByZWZpeDA1LmphdmEKQEAgLTAsMCArMSwxMTAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCBzZXRQcmVmaXggcmFpc2VzIGEgTkFNRVNQQUNFX0VSUiBpZiB0aGUgc3BlY2lmaWVkIHByZWZpeCBpcyBtYWxmb3JtZWQuCisgKiAgQ3JlYXRlIGEgbmV3IG5hbWVzcGFjZSBhd2FyZSBlbGVtZW50IG5vZGUgYW5kIGNhbGwgdGhlIHNldFByZWZpeCBtZXRob2Qgb24gaXQgd2l0aCBzZXZlcmFsIG1hbGZvcm1lZAorICogIHByZWZpeCB2YWx1ZXMuICBDaGVjayBpZiBhIE5BTUVTUEFDRV9FUlIgaXMgdGhyb3duLgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgbm9kZXNldHByZWZpeDA1IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBub2Rlc2V0cHJlZml4MDUoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIFN0cmluZyBwcmVmaXhWYWx1ZTsKKyAgICAgIGphdmEudXRpbC5MaXN0IHByZWZpeFZhbHVlcyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0KCk7CisgICAgICBwcmVmaXhWYWx1ZXMuYWRkKCJfOiIpOworICAgICAgcHJlZml4VmFsdWVzLmFkZCgiOjAiKTsKKyAgICAgIHByZWZpeFZhbHVlcy5hZGQoIjoiKTsKKyAgICAgIHByZWZpeFZhbHVlcy5hZGQoIl86OiIpOworICAgICAgcHJlZml4VmFsdWVzLmFkZCgiYTowOmMiKTsKKyAgICAgIAorICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvTDIiLCAiZG9tOmVsZW0iKTsKKyAgICAgIGZvciAoaW50IGluZGV4TjEwMDUwID0gMDsgaW5kZXhOMTAwNTAgPCBwcmVmaXhWYWx1ZXMuc2l6ZSgpOyBpbmRleE4xMDA1MCsrKSB7CisgICAgICAgICAgcHJlZml4VmFsdWUgPSAoU3RyaW5nKSBwcmVmaXhWYWx1ZXMuZ2V0KGluZGV4TjEwMDUwKTsKKyAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVsZW1lbnQuc2V0UHJlZml4KHByZWZpeFZhbHVlKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9CisgIH0KKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbm9kZXNldHByZWZpeDA1IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2Rlc2V0cHJlZml4MDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwNi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2Rlc2V0cHJlZml4MDYuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MjkyZDczCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2Rlc2V0cHJlZml4MDYuamF2YQpAQCAtMCwwICsxLDk1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2Qgc2V0UHJlZml4IHJhaXNlcyBhIE5BTUVTUEFDRV9FUlIgaWYgdGhlIHNwZWNpZmllZCBwcmVmaXggaXMgInhtbCIgYW5kIHRoZSBuYW1lc3BhY2VVUkkgCisgKiAgb2YgdGhpcyBub2RlIGlzIGRpZmZlcmVudCBmcm9tICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiLgorICogIEludm9rZSB0aGUgc2V0UHJlZml4IG1ldGhvZCBvbiB0aGlzIEVsZW1lbnQgb2JqZWN0IHdpdGggbmFtZXNwYWNlVVJJIHRoYXQgaXMgZGlmZmVyZW50IGZyb20KKyAqICBodHRwOi8vd3d3Li53My5vcmcveG1sLzE5OTgvbmFtZXNwYWNlIGFuZCBhIHByZWZpeCB3aG9zZSB2YWx1ZXMgaXMgeG1sLiAgCisgKiAgQ2hlY2sgaWYgdGhlIE5BTUVTUEFDRV9FUlIgd2FzIHRocm93bi4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNQcmVmaXgiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNQcmVmaXg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIG5vZGVzZXRwcmVmaXgwNiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9kZXNldHByZWZpeDA2KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9MMiIsICJkb206ZWxlbSIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbGVtZW50LnNldFByZWZpeCgieG1sIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub2Rlc2V0cHJlZml4MDYiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVzZXRwcmVmaXgwNi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZXNldHByZWZpeDA3LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwNy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE5ZGNiNmUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwNy5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgVGhlIG1ldGhvZCBzZXRQcmVmaXggcmFpc2VzIGEgTkFNRVNQQUNFX0VSUiBpZiB0aGlzIG5vZGUgaXMgYW4gYXR0cmlidXRlIGFuZCB0aGUgc3BlY2lmaWVkIAorICogIHByZWZpeCBpcyAieG1sbnMiIGFuZCB0aGUgbmFtZXNwYWNlVVJJIG9mIHRoaXMgbm9kZSBpcyBkaWZmZXJlbnQgZnJvbSAKKyAqICAiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iLgorICogIENyZWF0ZSBhIG5ldyBhdHRyaWJ1dGUgbm9kZSB3aG9zZSBuYW1lc3BhY2VVUkkgaXMgZGlmZmVyZW50IGZvcm0gImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIgorICogIGFuZCBub2RlIHByZWZpeCBpcyAieG1sbnMiLgorICogIENoZWNrIGlmIHRoZSBOQU1FU1BBQ0VfRVJSIHdhcyB0aHJvd24uCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2Rlc2V0cHJlZml4MDcgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVzZXRwcmVmaXgwNyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGF0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvTDIiLCAiYWJjOmVsZW0iKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgYXR0cmlidXRlLnNldFByZWZpeCgieG1sbnMiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwNyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9kZXNldHByZWZpeDA3LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2Rlc2V0cHJlZml4MDguamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZXNldHByZWZpeDA4LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmRkYWQzMwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9kZXNldHByZWZpeDA4LmphdmEKQEAgLTAsMCArMSw5OCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICBUaGUgbWV0aG9kIHNldFByZWZpeCByYWlzZXMgYSBOQU1FU1BBQ0VfRVJSIGlmIHRoaXMgbm9kZSBpcyBhbiBhdHRyaWJ1dGUgYW5kIHRoZSBxdWFsaWZpZWROYW1lIAorICogIG9mIHRoaXMgbm9kZSBpcyAieG1sbnMKKyAqICBSZXRyZWl2ZSBhbiBhdHRyaWJ1dGUgbm9kZSB3aG9zZSBxdWFsaWZpZWROYW1lIGlzIHhtbG5zLiAgVHJ5IHNldHRpbmcgYSBwcmVmaXggb24gdGhpcyBub2RlLgorICogIENoZWNrIGlmIHRoZSBOQU1FU1BBQ0VfRVJSIHdhcyB0aHJvd24uCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2Rlc2V0cHJlZml4MDggZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVzZXRwcmVmaXgwOChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhdHRyaWJ1dGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5vZGUoInhtbG5zIik7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGF0dHJpYnV0ZS5zZXRQcmVmaXgoInhtbCIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05BTUVTUEFDRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvbm9kZXNldHByZWZpeDA4IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihub2Rlc2V0cHJlZml4MDguY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL25vZGVzZXRwcmVmaXgwOS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2Rlc2V0cHJlZml4MDkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MjY0ODlmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub2Rlc2V0cHJlZml4MDkuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogIFRoZSBtZXRob2Qgc2V0UHJlZml4IHJhaXNlcyBhIElOVkFMSURfQ0hBUkFDVEVSX0VSUiBpZiB0aGUgc3BlY2lmaWVkIHByZWZpeCBjb250YWlucyBhbiBpbGxlZ2FsIGNoYXJhY3Rlci4KKyAqICBDcmVhdGUgYSBuZXcgbmFtZXNwYWNlIGF3YXJlIGVsZW1lbnQgbm9kZSBhbmQgY2FsbCB0aGUgc2V0UHJlZml4IG1ldGhvZCBvbiBpdCB3aXRoIGEgcHJlZml4IGhhdmluZyAKKyAqICBhbiBpbnZhbGlkIGNoYXJhY3Rlci4gIENoZWNrIGlmIGEgTkFNRVNQQUNFX0VSUiBpcyB0aHJvd24uCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub2Rlc2V0cHJlZml4MDkgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG5vZGVzZXRwcmVmaXgwOShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgU3RyaW5nIHZhbHVlID0gIiMkJSYnKClAIjsKKyAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L0wyIiwgImRvbTplbGVtIik7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVsZW1lbnQuc2V0UHJlZml4KHZhbHVlKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOVkFMSURfQ0hBUkFDVEVSX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub2Rlc2V0cHJlZml4MDkiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG5vZGVzZXRwcmVmaXgwOS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9ybWFsaXplMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvbm9ybWFsaXplMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kM2I3NmJmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9ub3JtYWxpemUwMS5qYXZhCkBAIC0wLDAgKzEsMTAyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgIm5vcm1hbGl6ZSgpIiBtZXRob2QgcHV0cyBhbGwgdGhlIG5vZGVzIGluIHRoZSBmdWxsCisgKiAgICAgZGVwdGggb2YgdGhlIHN1Yi10cmVlIHVuZGVybmVhdGggdGhpcyBlbGVtZW50IGludG8gYSAKKyAqICAgICAibm9ybWFsIiBmb3JtLiAKKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgdGhpcmQgZW1wbG95ZWUgYW5kIGFjY2VzcyBpdHMgc2Vjb25kIGNoaWxkLgorICogICAgIFRoaXMgY2hpbGQgY29udGFpbnMgYSBibG9jayBvZiB0ZXh0IHRoYXQgaXMgc3ByZWFkIAorICogICAgIGFjcm9zcyBtdWx0aXBsZSBsaW5lcy4gICBUaGUgY29udGVudCBvZiB0aGUgIm5hbWUiIGNoaWxkCisgKiAgICAgc2hvdWxkIGJlIHBhcnNlZCBhbmQgdHJlYXRlZCBhcyBhIHNpbmdsZSBUZXh0IG5vZGUuCisgKiAgICAgVGhpcyBhcHBlYXJzIHRvIGJlIGEgZHVwbGljYXRlIG9mIGVsZW1lbnRub3JtYWxpemUueG1sIGluIERPTSBMMSBUZXN0IFN1aXRlCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtbm9ybWFsaXplIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtbm9ybWFsaXplPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELTcyQUI4MzU5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBub3JtYWxpemUwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgbm9ybWFsaXplMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCByb290OworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGZpcnN0Q2hpbGQ7CisgICAgICBOb2RlTGlzdCB0ZXh0TGlzdDsKKyAgICAgIENoYXJhY3RlckRhdGEgdGV4dE5vZGU7CisgICAgICBTdHJpbmcgZGF0YTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBmYWxzZSk7CisgICAgICByb290ID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgcm9vdC5ub3JtYWxpemUoKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gcm9vdC5nZXRFbGVtZW50c0J5VGFnTmFtZSgibmFtZSIpOworICAgICAgZmlyc3RDaGlsZCA9IGVsZW1lbnRMaXN0Lml0ZW0oMik7CisgICAgICB0ZXh0TGlzdCA9IGZpcnN0Q2hpbGQuZ2V0Q2hpbGROb2RlcygpOworICAgICAgdGV4dE5vZGUgPSAoQ2hhcmFjdGVyRGF0YSkgdGV4dExpc3QuaXRlbSgwKTsKKyAgICAgIGRhdGEgPSB0ZXh0Tm9kZS5nZXREYXRhKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRhdGEiLCAiUm9nZXJcbiBKb25lcyIsIGRhdGEpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9ub3JtYWxpemUwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4obm9ybWFsaXplMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL293bmVyRG9jdW1lbnQwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9vd25lckRvY3VtZW50MDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNzdmMzJhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9vd25lckRvY3VtZW50MDEuamF2YQpAQCAtMCwwICsxLDg2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldE93bmVyRG9jdW1lbnQoKSIgbWV0aG9kIHJldHVybnMgbnVsbCBpZiB0aGUgdGFyZ2V0CisgKiAgICAgbm9kZSBpdHNlbGYgaXMgYSBEb2N1bWVudFR5cGUgd2hpY2ggaXMgbm90IHVzZWQgd2l0aCBhbnkgZG9jdW1lbnQgeWV0LgorICogICAgIAorICogICAgIEludm9rZSB0aGUgImdldE93bmVyRG9jdW1lbnQoKSIgbWV0aG9kIG9uIHRoZSBtYXN0ZXIgCisgKiAgICAgZG9jdW1lbnQuICAgVGhlIERvY3VtZW50VHlwZSByZXR1cm5lZCBzaG91bGQgYmUgbnVsbC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNub2RlLW93bmVyRG9jIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjbm9kZS1vd25lckRvYzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgb3duZXJEb2N1bWVudDAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBvd25lckRvY3VtZW50MDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIG93bmVyRG9jdW1lbnQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgb3duZXJEb2N1bWVudCA9IChEb2N1bWVudFR5cGUpIGRvYy5nZXRPd25lckRvY3VtZW50KCk7CisgICAgICBhc3NlcnROdWxsKCJ0aHJvd19OdWxsIiwgb3duZXJEb2N1bWVudCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL293bmVyRG9jdW1lbnQwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4ob3duZXJEb2N1bWVudDAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9vd25lckVsZW1lbnQwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9vd25lckVsZW1lbnQwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI5ZmFlNmUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL293bmVyRWxlbWVudDAxLmphdmEKQEAgLTAsMCArMSw5NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRPd25lckVsZW1lbnQoKSIgd2lsbCByZXR1cm4gdGhlIEVsZW1lbnQgbm9kZSB0aGlzIGF0dHJpYnV0ZQorICogICBpcyBhdHRhY2hlZCB0byBvciBudWxsIGlmIHRoaXMgYXR0cmlidXRlIGlzIG5vdCBpbiB1c2UuICAKKyAqICAgR2V0IHRoZSAiZG9tZXN0aWMiIGF0dHJpYnV0ZSBmcm9tIHRoZSBmaXJzdCAiYWRkcmVzcyIgbm9kZS4KKyAqICAgQXBwbHkgdGhlICJnZXRPd25lckVsZW1lbnQoKSIgbWV0aG9kIHRvIGdldCB0aGUgRWxlbWVudCBhc3NvY2lhdGVkIAorICogICB3aXRoIHRoZSBhdHRyaWJ1dGUuICBUaGUgdmFsdWUgcmV0dXJuZWQgc2hvdWxkIGJlICJhZGRyZXNzIi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1GNjhEMDk1Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRjY4RDA5NTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgb3duZXJFbGVtZW50MDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG93bmVyRWxlbWVudDAxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGFkZHJlc3NMaXN0OworICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgQXR0ciBkb21lc3RpY0F0dHI7CisgICAgICBFbGVtZW50IGVsZW1lbnROb2RlOworICAgICAgU3RyaW5nIG5hbWU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgYWRkcmVzc0xpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3ROb2RlID0gYWRkcmVzc0xpc3QuaXRlbSgwKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBkb21lc3RpY0F0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oImRvbWVzdGljIik7CisgICAgICBlbGVtZW50Tm9kZSA9IGRvbWVzdGljQXR0ci5nZXRPd25lckVsZW1lbnQoKTsKKyAgICAgIG5hbWUgPSBlbGVtZW50Tm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0aHJvd19FcXVhbHMiLCAiYWRkcmVzcyIsIG5hbWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9vd25lckVsZW1lbnQwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4ob3duZXJFbGVtZW50MDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL293bmVyRWxlbWVudDAyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL293bmVyRWxlbWVudDAyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjEzOGMwNQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvb3duZXJFbGVtZW50MDIuamF2YQpAQCAtMCwwICsxLDg5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgImdldE93bmVyRWxlbWVudCgpIiB3aWxsIHJldHVybiB0aGUgRWxlbWVudCBub2RlIHRoaXMgYXR0cmlidXRlCisgKiAgIGlzIGF0dGFjaGVkIHRvIG9yIG51bGwgaWYgdGhpcyBhdHRyaWJ1dGUgaXMgbm90IGluIHVzZS4gIAorICogICBDcmVhdGUgYSBuZXcgYXR0cmlidXRlLgorICogICBBcHBseSB0aGUgImdldE93bmVyRWxlbWVudCgpIiBtZXRob2QgdG8gZ2V0IHRoZSBFbGVtZW50IGFzc29jaWF0ZWQgCisgKiAgIHdpdGggdGhlIGF0dHJpYnV0ZS4gIFRoZSB2YWx1ZSByZXR1cm5lZCBzaG91bGQgYmUgIm51bGwiIHNpbmNlIHRoaXMKKyAqICAgYXR0cmlidXRlIGlzIG5vdCBpbiB1c2UuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjQXR0ci1vd25lckVsZW1lbnQiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNBdHRyLW93bmVyRWxlbWVudDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgb3duZXJFbGVtZW50MDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIG93bmVyRWxlbWVudDAyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIEF0dHIgbmV3QXR0cjsKKyAgICAgIEVsZW1lbnQgZWxlbWVudE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgZmFsc2UpOworICAgICAgbmV3QXR0ciA9IGRvYy5jcmVhdGVBdHRyaWJ1dGUoIm5ld0F0dHJpYnV0ZSIpOworICAgICAgZWxlbWVudE5vZGUgPSBuZXdBdHRyLmdldE93bmVyRWxlbWVudCgpOworICAgICAgYXNzZXJ0TnVsbCgidGhyb3dfTnVsbCIsIGVsZW1lbnROb2RlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvb3duZXJFbGVtZW50MDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKG93bmVyRWxlbWVudDAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9wcmVmaXgwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9wcmVmaXgwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIzMzg0NTIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3ByZWZpeDAxLmphdmEKQEAgLTAsMCArMSw5MSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRQcmVmaXgoKSIgbWV0aG9kIGZvciBhIE5vZGUKKyAqICAgICByZXR1cm5zIHRoZSBuYW1lc3BhY2UgcHJlZml4IG9mIHRoZSBub2RlLAorICogICAgIGFuZCBmb3Igbm9kZXMgb2YgYW55IHR5cGUgb3RoZXIgdGhhbiBFTEVNRU5UX05PREUgYW5kIEFUVFJJQlVURV9OT0RFCisgKiAgICAgYW5kIG5vZGVzIGNyZWF0ZWQgd2l0aCBhIERPTSBMZXZlbCAxIG1ldGhvZCwgdGhpcyBpcyBudWxsLgorICogICAgIAorICogICAgIENyZWF0ZSBhbiBuZXcgRWxlbWVudCB3aXRoIHRoZSBjcmVhdGVFbGVtZW50KCkgbWV0aG9kLgorICogICAgIEludm9rZSB0aGUgImdldFByZWZpeCgpIiBtZXRob2Qgb24gdGhlIG5ld2x5IGNyZWF0ZWQgZWxlbWVudCAgIAorICogICAgIG5vZGUgd2lsbCBjYXVzZSAibnVsbCIgdG8gYmUgcmV0dXJuZWQuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgcHJlZml4MDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHByZWZpeDAxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBjcmVhdGVkTm9kZTsKKyAgICAgIFN0cmluZyBwcmVmaXg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBjcmVhdGVkTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50KCJ0ZXN0OmVtcGxveWVlIik7CisgICAgICBwcmVmaXggPSBjcmVhdGVkTm9kZS5nZXRQcmVmaXgoKTsKKyAgICAgIGFzc2VydE51bGwoInRocm93X051bGwiLCBwcmVmaXgpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9wcmVmaXgwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4ocHJlZml4MDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3ByZWZpeDAyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3ByZWZpeDAyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmVkM2YyOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MDIuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0UHJlZml4KCkiIG1ldGhvZAorICogICAgIHJldHVybnMgdGhlIG5hbWVzcGFjZSBwcmVmaXggb2YgdGhpcyBub2RlLCBvciBudWxsIGlmIHVuc3BlY2lmaWVkLgorICogICAgIEZvciBub2RlcyBvZiBhbnkgdHlwZSBvdGhlciB0aGFuIEVMRU1FTlRfTk9ERSBhbmQgQVRUUklCVVRFX05PREUsCisgKiAgICAgdGhpcyBpcyBhbHdheXMgbnVsbC4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgZW1wOmVtcGxveWVlSWQgbm9kZSBhbmQgZ2V0IHRoZSBmaXJzdCBjaGlsZCBvZiB0aGlzIG5vZGUuCisgKiAgICAgU2luY2UgdGhlIGZpcnN0IGNoaWxkIGlzIFRleHQgbm9kZSBpbnZva2luZyB0aGUgImdldFByZWZpeCgpIiAgIAorICogICAgIG1ldGhvZCB3aWxsIGNhdXNlICJudWxsIiB0byBiZSByZXR1cm5lZC4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBwcmVmaXgwMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgcHJlZml4MDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgTm9kZSB0ZXh0Tm9kZTsKKyAgICAgIFN0cmluZyBwcmVmaXg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmVtcGxveWVlSWQiKTsKKyAgICAgIHRlc3RFbXBsb3llZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbXBFbXBsb3llZU5vdE51bGwiLCB0ZXN0RW1wbG95ZWUpOworICAgICAgdGV4dE5vZGUgPSB0ZXN0RW1wbG95ZWUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgcHJlZml4ID0gdGV4dE5vZGUuZ2V0UHJlZml4KCk7CisgICAgICBhc3NlcnROdWxsKCJ0ZXh0Tm9kZVByZWZpeCIsIHByZWZpeCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3ByZWZpeDAyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihwcmVmaXgwMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MDMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MDMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMzI4NWQwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9wcmVmaXgwMy5qYXZhCkBAIC0wLDAgKzEsOTcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRQcmVmaXgoKSIgbWV0aG9kIGZvciBhIG5vZGUKKyAqICAgICByZXR1cm5zIHRoZSBuYW1lc3BhY2UgcHJlZml4IG9mIHRoaXMgbm9kZSwgb3IgbnVsbCBpZiBpdCBpcyB1bnNwZWNpZmllZC4KKyAqICAgICAKKyAqICAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgZW1wOmVtcGxveWVlIG5vZGUgYW5kIGludm9rZSB0aGUgZ2V0UHJlZml4KCkgbWV0aG9kLiIgICAKKyAqICAgICBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gImVtcCIuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgcHJlZml4MDMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHByZWZpeDAzKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RFbXBsb3llZTsKKyAgICAgIFN0cmluZyBwcmVmaXg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmVtcGxveWVlIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wRW1wbG95ZWVOb3ROdWxsIiwgdGVzdEVtcGxveWVlKTsKKyAgICAgIHByZWZpeCA9IHRlc3RFbXBsb3llZS5nZXRQcmVmaXgoKTsKKyAgICAgIGFzc2VydEVxdWFscygicHJlZml4IiwgImVtcCIsIHByZWZpeCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3ByZWZpeDAzIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihwcmVmaXgwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MDQuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MDQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NTZlMWY3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9wcmVmaXgwNC5qYXZhCkBAIC0wLDAgKzEsOTAgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0UHJlZml4KCkiIG1ldGhvZCBmb3IgYSBub2RlCisgKiAgICAgcmV0dXJucyB0aGUgbmFtZXNwYWNlIHByZWZpeCBvZiB0aGlzIG5vZGUsIG9yIG51bGwgaWYgaXQgaXMgdW5zcGVjaWZpZWQuCisgKiAgICAgCisgKiAgICAgUmV0cmlldmUgdGhlIGZpcnN0IGVtcGxveWVlIG5vZGUgYW5kIGludm9rZSB0aGUgZ2V0UHJlZml4KCkgbWV0aG9kLiIgICAKKyAqICAgICBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gIm51bGwiLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNQcmVmaXgiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNQcmVmaXg8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIHByZWZpeDA0IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBwcmVmaXgwNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0RW1wbG95ZWU7CisgICAgICBTdHJpbmcgcHJlZml4OworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgZmFsc2UpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICB0ZXN0RW1wbG95ZWUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgcHJlZml4ID0gdGVzdEVtcGxveWVlLmdldFByZWZpeCgpOworICAgICAgYXNzZXJ0TnVsbCgidGhyb3dfTnVsbCIsIHByZWZpeCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3ByZWZpeDA0IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihwcmVmaXgwNC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MDUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MDUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MWE0MjA1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9wcmVmaXgwNS5qYXZhCkBAIC0wLDAgKzEsMTA2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0UHJlZml4KHByZWZpeCkiIG1ldGhvZCByYWlzZXMgYSAKKyAqICAgICBOQU1FU1BBQ0VfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIG5vZGUgaXMgYW4gYXR0cmlidXRlCisgKiAgICAgYW5kIHRoZSBzcGVjaWZpZWQgcHJlZml4IGlzIHhtbG5zIGFuZCB0aGUgbmFtZXNwYWNlVVJJIGlzIGRpZmZlcmVudCBmcm9tCisgKiAgICAgaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy4KKyAqICAgICAKKyAqICAgICBBdHRlbXB0IHRvIGluc2VydCAieG1sbnMiIGFzIHRoZSBuZXcgbmFtZXNwYWNlIHByZWZpeCBvbiB0aGUgZW1wOmRvbWVzdGljCisgKiAgICAgYXR0cmlidXRlIHdpdGhpbiB0aGUgZW1wOmFkZHJlc3Mgbm9kZS4KKyAqICAgICBBbiBleGNlcHRpb24gc2hvdWxkIGJlIHJhaXNlZCBzaW5jZSB0aGUgbmFtZXNwYWNlVVJJIG9mIHRoaXMgbm9kZSBpcyBub3QgCisgKiAgICAgaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOQU1FU1BBQ0VfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNQcmVmaXgiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNQcmVmaXg8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1Ob2RlTlNQcmVmaXgnKS9zZXRyYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOQU1FU1BBQ0VfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELU5vZGVOU1ByZWZpeCcpL3NldHJhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05BTUVTUEFDRV9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIHByZWZpeDA1IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBwcmVmaXgwNShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBFbGVtZW50IGFkZHJOb2RlOworICAgICAgQXR0ciBhZGRyQXR0cjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICBhZGRyTm9kZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkck5vdE51bGwiLCBhZGRyTm9kZSk7CisgICAgICBhZGRyQXR0ciA9IGFkZHJOb2RlLmdldEF0dHJpYnV0ZU5vZGUoImVtcDpkb21lc3RpYyIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGRyQXR0ci5zZXRQcmVmaXgoInhtbG5zIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9wcmVmaXgwNSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4ocHJlZml4MDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3ByZWZpeDA2LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3ByZWZpeDA2LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmQwZTI1MQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MDYuamF2YQpAQCAtMCwwICsxLDEwNyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXRQcmVmaXgocHJlZml4KSIgbWV0aG9kIHJhaXNlcyBhIAorICogICAgIElOVkFMSURfQ0hBUkFDVEVSX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZAorICogICAgIHByZWZpeCBjb250YWlucyBhbiBpbGxlZ2FsIGNoYXJhY3Rlci4KKyAqICAgICAKKyAqICAgICBBdHRlbXB0IHRvIGluc2VydCBhIG5ldyBuYW1lc3BhY2UgcHJlZml4IG9uIHRoZSBmaXJzdCBlbXBsb3llZSBub2RlLgorICogICAgIEFuIGV4Y2VwdGlvbiBzaG91bGQgYmUgcmFpc2VkIHNpbmNlIHRoZSBuYW1lc3BhY2UgcHJlZml4IGhhcyBhbiBpbnZhbGlkIAorICogICAgIGNoYXJhY3Rlci4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtTm9kZU5TUHJlZml4Jykvc2V0cmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELU5vZGVOU1ByZWZpeCcpL3NldHJhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgcHJlZml4MDYgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHByZWZpeDA2KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVtcGxveWVlTm9kZS5zZXRQcmVmaXgoInByZV5maXggeG1sbnM9J2h0dHAvL3d3dy5uaXN0LmdvdiciKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOVkFMSURfQ0hBUkFDVEVSX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9wcmVmaXgwNiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4ocHJlZml4MDYuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3ByZWZpeDA3LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3ByZWZpeDA3LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTQxYTRlMQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MDcuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXRQcmVmaXgocHJlZml4KSIgbWV0aG9kIHJhaXNlcyBhIAorICogICAgIE5BTUVTUEFDRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQKKyAqICAgICBwcmVmaXggaWYgbWFsZm9ybWVkLgorICogICAgIAorICogICAgIEF0dGVtcHQgdG8gaW5zZXJ0IGEgbmV3IG5hbWVzcGFjZSBwcmVmaXggb24gdGhlIHNlY29uZCBlbXBsb3llZSBub2RlLgorICogICAgIEFuIGV4Y2VwdGlvbiBzaG91bGQgYmUgcmFpc2VkIHNpbmNlIHRoZSBuYW1lc3BhY2UgcHJlZml4IGlzIG1hbGZvcm1lZC4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05BTUVTUEFDRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtTm9kZU5TUHJlZml4Jykvc2V0cmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1Ob2RlTlNQcmVmaXgnKS9zZXRyYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOQU1FU1BBQ0VfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBwcmVmaXgwNyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgcHJlZml4MDcoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgZW1wbG95ZWVOb2RlLnNldFByZWZpeCgiZW1wOjoiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3ByZWZpeDA3IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihwcmVmaXgwNy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MDguamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MDguamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZmJkNWJmCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9wcmVmaXgwOC5qYXZhCkBAIC0wLDAgKzEsMTIyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICBUaGUgInNldFByZWZpeChwcmVmaXgpIiBtZXRob2QgY2F1c2VzIHRoZSAKKyAqICAgRE9NRXhjZXB0aW9uIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiB0byBiZSByYWlzZWQKKyAqICAgaWYgdGhlIG5vZGUgaXMgcmVhZG9ubHkuCisgKiAgIAorICogICBPYnRhaW4gdGhlIGNoaWxkcmVuIG9mIHRoZSBUSElSRCAiZ2VuZGVyIiBlbGVtZW50LiAgVGhlIGVsZW1lbnRzCisgKiAgIGNvbnRlbnQgaXMgYW4gZW50aXR5IHJlZmVyZW5jZS4gIEdldCB0aGUgRklSU1QgaXRlbSAKKyAqICAgZnJvbSB0aGUgZW50aXR5IHJlZmVyZW5jZSBhbmQgZXhlY3V0ZSB0aGUgInNldFByZWZpeChwcmVmaXgpIiBtZXRob2QuCisgKiAgIFRoaXMgY2F1c2VzIGEgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIERPTUV4Y2VwdGlvbiB0byBiZSB0aHJvd24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELU5vZGVOU1ByZWZpeCcpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1Ob2RlTlNQcmVmaXgnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIHByZWZpeDA4IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBwcmVmaXgwOChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGdlbmRlckxpc3Q7CisgICAgICBOb2RlIGdlbmRlck5vZGU7CisgICAgICBOb2RlIGVudFJlZjsKKyAgICAgIE5vZGUgZW50RWxlbWVudDsKKyAgICAgIE5vZGUgY3JlYXRlZE5vZGU7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgdHJ1ZSk7CisgICAgICBnZW5kZXJMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJnZW5kZXIiKTsKKyAgICAgIGdlbmRlck5vZGUgPSBnZW5kZXJMaXN0Lml0ZW0oMik7CisgICAgICBlbnRSZWYgPSBnZW5kZXJOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgIG5vZGVUeXBlID0gKGludCkgZW50UmVmLmdldE5vZGVUeXBlKCk7CisgICAgICAKKyAgICAgIGlmIChlcXVhbHMoMSwgbm9kZVR5cGUpKSB7CisgICAgICAgICAgZW50UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworICAgICAgfQorICAgIGVudEVsZW1lbnQgPSBlbnRSZWYuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50RWxlbWVudCIsIGVudEVsZW1lbnQpOworICAgICAgY3JlYXRlZE5vZGUgPSBkb2MuY3JlYXRlRWxlbWVudCgidGV4dDMiKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgZW50RWxlbWVudC5zZXRQcmVmaXgoIm5ld1ByZWZpeCIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3ByZWZpeDA4IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihwcmVmaXgwOC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MDkuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MDkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYjJlMDI3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9wcmVmaXgwOS5qYXZhCkBAIC0wLDAgKzEsMTEwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldFByZWZpeChwcmVmaXgpIiBtZXRob2QgcmFpc2VzIGEgCisgKiAgICAgTkFNRVNQQUNFX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBub2RlIGlzIGFuIGF0dHJpYnV0ZQorICogICAgIGFuZCB0aGUgcXVhbGlmaWVkTmFtZSBvZiB0aGlzIG5vZGUgaXMgeG1sbnMuIAorICogICAgIAorICogICAgIEF0dGVtcHQgdG8gc2V0IHRoZSBwcmVmaXggb24gdGhlIHhtbG5zIGF0dHJpYnV0ZSB3aXRoaW4gdGhlIGZvdXJ0aCBhZGRyZXNzCisgKiAgICAgZWxlbWVudC4KKyAqICAgICBBbiBleGNlcHRpb24gc2hvdWxkIGJlIHJhaXNlZCBzaW5jZSB0aGUgcXVhbGlmaWVkTmFtZSBvZiB0aGlzIGF0dHJpYnV0ZQorICogICAgIGlzICJ4bWxucyIuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOQU1FU1BBQ0VfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05BTUVTUEFDRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeDwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELU5vZGVOU1ByZWZpeCcpL3NldHJhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05BTUVTUEFDRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtTm9kZU5TUHJlZml4Jykvc2V0cmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgcHJlZml4MDkgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHByZWZpeDA5KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIEVsZW1lbnQgYWRkck5vZGU7CisgICAgICBBdHRyIGFkZHJBdHRyOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgYWRkck5vZGUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgzKTsKKyAgICAgIGFkZHJBdHRyID0gYWRkck5vZGUuZ2V0QXR0cmlidXRlTm9kZSgieG1sbnMiKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgYWRkckF0dHIuc2V0UHJlZml4KCJ4eHgiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3ByZWZpeDA5IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihwcmVmaXgwOS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MTAuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MTAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZGI2Yzg0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9wcmVmaXgxMC5qYXZhCkBAIC0wLDAgKzEsMTAyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldFByZWZpeChwcmVmaXgpIiBtZXRob2QgcmFpc2VzIGEgCisgKiAgICAgTkFNRVNQQUNFX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZAorICogICAgIHByZWZpeCBpcyB4bWwgYW5kIHRoZSBuYW1lc3BhY2VVUkkgaXMgZGlmZmVyZW50IGZyb20KKyAqICAgICBodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UuCisgKiAgICAgCisgKiAgICAgQXR0ZW1wdCB0byBpbnNlcnQgInhtbCIgYXMgdGhlIG5ldyBuYW1lc3BhY2UgcHJlZml4IG9uIHRoZSBmaXJzdCBlbXBsb3llZSBub2RlLgorICogICAgIEFuIGV4Y2VwdGlvbiBzaG91bGQgYmUgcmFpc2VkIHNpbmNlIHRoZSBuYW1lc3BhY2VVUkkgb2YgdGhpcyBub2RlIGlzIG5vdCAKKyAqICAgICBodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05BTUVTUEFDRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4PC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtTm9kZU5TUHJlZml4Jykvc2V0cmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1Ob2RlTlNQcmVmaXgnKS9zZXRyYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOQU1FU1BBQ0VfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBwcmVmaXgxMCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgcHJlZml4MTAoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBlbXBsb3llZU5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgZW1wbG95ZWVOb2RlLnNldFByZWZpeCgieG1sIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9wcmVmaXgxMCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4ocHJlZml4MTAuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3ByZWZpeDExLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3ByZWZpeDExLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGU2NDRhOAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHJlZml4MTEuamF2YQpAQCAtMCwwICsxLDEwMyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXRQcmVmaXgocHJlZml4KSIgbWV0aG9kIHJhaXNlcyBhIAorICogICAgIE5BTUVTUEFDRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQKKyAqICAgICBwcmVmaXggaXMgc2V0IG9uIGEgbm9kZSB3aXRoIGEgbmFtZXNwYWNlVVJJIHRoYXQgaXMgbnVsbC4KKyAqICAgICAKKyAqICAgICBBdHRlbXB0IHRvIGluc2VydCBhIG5ldyBuYW1lc3BhY2UgcHJlZml4IG9uIHRoZSBzZWNvbmQgZW1wbG95ZWUgbm9kZS4KKyAqICAgICBBbiBleGNlcHRpb24gc2hvdWxkIGJlIHJhaXNlZCBzaW5jZSB0aGUgbmFtZXNwYWNlIHByZWZpeCBpcyBzZXQKKyAqICAgICBvbiBhIG5vZGUgd2hvc2UgbmFtZXNwYWNlVVJJIGlzIG51bGwuIAorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOQU1FU1BBQ0VfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05BTUVTUEFDRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJycpL3NldHJhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05BTUVTUEFDRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnJykvc2V0cmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgcHJlZml4MTEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHByZWZpeDExKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgbmFtZXNwYWNlVVJJID0gZW1wbG95ZWVOb2RlLmdldE5hbWVzcGFjZVVSSSgpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbXBsb3llZU5vZGUuc2V0UHJlZml4KCJlbXBsb3llZTEiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3ByZWZpeDExIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihwcmVmaXgxMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHVibGljSWQwMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9wdWJsaWNJZDAxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTU2ZjJjNAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcHVibGljSWQwMS5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAiZ2V0UHVibGljSWQoKSIgbWV0aG9kIG9mIGEgZG9jdW1lbnR0eXBlIG5vZGUgY29udGFpbnMKKyAqICAgIHRoZSBwdWJsaWMgaWRlbnRpZmllciBhc3NvY2lhdGVkIHdpdGggdGhlIGV4dGVybmFsIHN1YnNldC4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGRvY3VtZW50dHlwZS4KKyAqICAgIEFwcGx5IHRoZSAiZ2V0UHVibGljSWQoKSIgbWV0aG9kLiAgVGhlIHN0cmluZyAiU1RBRkYiIHNob3VsZCBiZQorICogICAgcmV0dXJuZWQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtQ29yZS1Eb2NUeXBlLXB1YmxpY0lkIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtQ29yZS1Eb2NUeXBlLXB1YmxpY0lkPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBwdWJsaWNJZDAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBwdWJsaWNJZDAxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgZmFsc2UpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBTdHJpbmcgcHVibGljSWQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBmYWxzZSk7CisgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgIHB1YmxpY0lkID0gZG9jVHlwZS5nZXRQdWJsaWNJZCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0aHJvd19FcXVhbHMiLCAiU1RBRkYiLCBwdWJsaWNJZCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3B1YmxpY0lkMDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHB1YmxpY0lkMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3JlbW92ZUF0dHJpYnV0ZU5TMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcmVtb3ZlQXR0cmlidXRlTlMwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE1YTUzODQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3JlbW92ZUF0dHJpYnV0ZU5TMDEuamF2YQpAQCAtMCwwICsxLDEyMyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlbW92ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpIiBtZXRob2QgZm9yIGFuIGF0dHJpYnV0ZSBjYXVzZXMgdGhlIAorICogICAgRE9NRXhjZXB0aW9uIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiB0byBiZSByYWlzZWQKKyAqICAgIGlmIHRoZSBub2RlIGlzIHJlYWRvbmx5LgorICogICAgCisgKiAgICBPYnRhaW4gdGhlIGNoaWxkcmVuIG9mIHRoZSBUSElSRCAiZ2VuZGVyIiBlbGVtZW50LiAgVGhlIGVsZW1lbnRzCisgKiAgICBjb250ZW50IGlzIGFuIGVudGl0eSByZWZlcmVuY2UuICBUcnkgdG8gcmVtb3ZlIGFuIGF0dHJpYnV0ZQorICogICAgZnJvbSB0aGUgZW50aXR5IHJlZmVyZW5jZSBieSBleGVjdXRpbmcgdGhlIAorICogICAgInJlbW92ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpIiBtZXRob2QuCisgKiAgICBUaGlzIGNhdXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gdG8gYmUgdGhyb3duLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFJlbUF0TlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFJlbUF0TlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1FbFJlbUF0TlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRWxSZW1BdE5TJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyByZW1vdmVBdHRyaWJ1dGVOUzAxIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyByZW1vdmVBdHRyaWJ1dGVOUzAxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBnZW5kZXJMaXN0OworICAgICAgTm9kZSBnZW5kZXI7CisgICAgICBOb2RlIGdlbjsKKyAgICAgIE5vZGVMaXN0IGdMaXN0OworICAgICAgRWxlbWVudCBnZW5FbGVtZW50OworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBnZW5kZXJMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJnZW5kZXIiKTsKKyAgICAgIGdlbmRlciA9IGdlbmRlckxpc3QuaXRlbSgyKTsKKyAgICAgIGdlbiA9IGdlbmRlci5nZXRGaXJzdENoaWxkKCk7CisgICAgICBub2RlVHlwZSA9IChpbnQpIGdlbi5nZXROb2RlVHlwZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDEsIG5vZGVUeXBlKSkgeworICAgICAgICAgIGdlbiA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDQiKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZ2VuKTsKKyAgICAgIH0KKyAgICBnTGlzdCA9IGdlbi5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBnZW5FbGVtZW50ID0gKEVsZW1lbnQpIGdMaXN0Lml0ZW0oMCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJub3RudWxsIiwgZ2VuRWxlbWVudCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGdlbkVsZW1lbnQucmVtb3ZlQXR0cmlidXRlTlMoInd3dy54eXouY29tIiwgImxvY2FsMSIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3JlbW92ZUF0dHJpYnV0ZU5TMDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHJlbW92ZUF0dHJpYnV0ZU5TMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3JlbW92ZUF0dHJpYnV0ZU5TMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcmVtb3ZlQXR0cmlidXRlTlMwMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjliNTI3N2QKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3JlbW92ZUF0dHJpYnV0ZU5TMDIuamF2YQpAQCAtMCwwICsxLDExOCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlbW92ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpIiByZW1vdmVzIGFuIGF0dHJpYnV0ZSBieSAKKyAqICAgIGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkuICBJZiB0aGUgcmVtb3ZlZCBhdHRyaWJ1dGUgaGFzIGEKKyAqICAgIGRlZmF1bHQgdmFsdWUgaXQgaXMgaW1tZWRpYXRlbHkgcmVwbGFjZWQuICBUaGUgcmVwbGFjaW5nIGF0dHJpYnV0ZSBoYXMgdGhlIHNhbWUKKyAqICAgIG5hbWVzcGFjZSBVUkkgYW5kIGxvY2FsIG5hbWUsIGFzIHdlbGwgYXMgdGhlIG9yaWdpbmFsIHByZWZpeC4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBuYW1lZCAiZW1wOmxvY2FsIiBmcm9tIGVtcDphZGRyZXNzCisgKiAgICBub2RlLCB0aGVuIHJlbW92ZSB0aGUgImVtcDpsb2NhbCIgCisgKiAgICBhdHRyaWJ1dGUgYnkgaW52b2tpbmcgdGhlICJyZW1vdmVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKSIgbWV0aG9kLgorICogICAgVGhlICJlbXA6bG9jYWwiIGF0dHJpYnV0ZSBoYXMgYSBkZWZhdWx0IHZhbHVlIGRlZmluZWQgaW4gdGhlCisgKiAgICBEVEQgZmlsZSwgdGhhdCB2YWx1ZSBzaG91bGQgaW1tZWRpYXRlbHkgcmVwbGFjZSB0aGUgb2xkCisgKiAgICB2YWx1ZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFJlbUF0TlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFJlbUF0TlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzOCI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzODwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgcmVtb3ZlQXR0cmlidXRlTlMwMiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgcmVtb3ZlQXR0cmlidXRlTlMwMihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZSwKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy52YWxpZGF0aW5nCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEFkZHI7CisgICAgICBBdHRyIGFkZHJBdHRyOworICAgICAgU3RyaW5nIGF0dHI7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJOworICAgICAgU3RyaW5nIGxvY2FsTmFtZTsKKyAgICAgIFN0cmluZyBwcmVmaXg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6YWRkcmVzcyIpOworICAgICAgdGVzdEFkZHIgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgKChFbGVtZW50KSAvKk5vZGUgKi90ZXN0QWRkcikucmVtb3ZlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAibG9jYWwxIik7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGFkZHJBdHRyID0gKChFbGVtZW50KSAvKk5vZGUgKi90ZXN0QWRkcikuZ2V0QXR0cmlidXRlTm9kZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImxvY2FsMSIpOworICAgICAgYXR0ciA9ICgoRWxlbWVudCkgLypOb2RlICovdGVzdEFkZHIpLmdldEF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImxvY2FsMSIpOworICAgICAgbmFtZXNwYWNlVVJJID0gYWRkckF0dHIuZ2V0TmFtZXNwYWNlVVJJKCk7CisgICAgICBsb2NhbE5hbWUgPSBhZGRyQXR0ci5nZXRMb2NhbE5hbWUoKTsKKyAgICAgIHByZWZpeCA9IHRlc3RBZGRyLmdldFByZWZpeCgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyIiwgIkZBTFNFIiwgYXR0cik7CisgICAgICBhc3NlcnRFcXVhbHMoInVyaSIsICJodHRwOi8vd3d3Lm5pc3QuZ292IiwgbmFtZXNwYWNlVVJJKTsKKyAgICAgIGFzc2VydEVxdWFscygibG5hbWUiLCAibG9jYWwxIiwgbG9jYWxOYW1lKTsKKyAgICAgIGFzc2VydEVxdWFscygicHJlZml4IiwgImVtcCIsIHByZWZpeCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3JlbW92ZUF0dHJpYnV0ZU5TMDIiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHJlbW92ZUF0dHJpYnV0ZU5TMDIuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3JlbW92ZU5hbWVkSXRlbU5TMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcmVtb3ZlTmFtZWRJdGVtTlMwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRkZDVkNzYKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3JlbW92ZU5hbWVkSXRlbU5TMDEuamF2YQpAQCAtMCwwICsxLDEwNSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJyZW1vdmVOYW1lZEl0ZW1OUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKSIgbWV0aG9kIGZvciBhIAorICogICAgTmFtZWROb2RlTWFwIHNob3VsZCByZW1vdmUgYSBub2RlIHNwZWNpZmllZCBieSBsb2NhbE5hbWUgYW5kIG5hbWVzcGFjZVVSSS4KKyAqICAgIAorICogICAgUmV0cmlldmUgYSBsaXN0IG9mIGVsZW1lbnRzIHdpdGggdGFnIG5hbWUgImFkZHJlc3MiLgorICogICAgQWNjZXNzIHRoZSBzZWNvbmQgZWxlbWVudCBmcm9tIHRoZSBsaXN0IGFuZCBnZXQgaXRzIGF0dHJpYnV0ZXMuCisgKiAgICBUcnkgdG8gcmVtb3ZlIHRoZSBhdHRyaWJ1dGUgbm9kZSB3aXRoIGxvY2FsIG5hbWUgImRvbWVzdGljIgorICogICAgYW5kIG5hbWVzcGFjZSB1cmkgImh0dHA6Ly93d3cudXNhLmNvbSIgd2l0aCAKKyAqICAgIG1ldGhvZCByZW1vdmVOYW1lZEl0ZW1OUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKS4KKyAqICAgIENoZWNrIHRvIHNlZSBpZiB0aGUgbm9kZSBoYXMgYmVlbiByZW1vdmVkLiAKKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC0xMDc0NTc3NTQ5Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtMTA3NDU3NzU0OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgcmVtb3ZlTmFtZWRJdGVtTlMwMSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgcmVtb3ZlTmFtZWRJdGVtTlMwMShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RBZGRyZXNzOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBBdHRyIG5ld0F0dHI7CisgICAgICBOb2RlIHJlbW92ZWROb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEFkZHJlc3MgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgYXR0cmlidXRlcyA9IHRlc3RBZGRyZXNzLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHJlbW92ZWROb2RlID0gYXR0cmlidXRlcy5yZW1vdmVOYW1lZEl0ZW1OUygiaHR0cDovL3d3dy51c2EuY29tIiwgImRvbWVzdGljIik7CisgICAgICBhc3NlcnROb3ROdWxsKCJyZXR2YWwiLCByZW1vdmVkTm9kZSk7CisgICAgICBuZXdBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJkbXN0Yzpkb21lc3RpYyIpOworICAgICAgYXNzZXJ0TnVsbCgibm9kZVJlbW92ZWQiLCBuZXdBdHRyKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvcmVtb3ZlTmFtZWRJdGVtTlMwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4ocmVtb3ZlTmFtZWRJdGVtTlMwMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcmVtb3ZlTmFtZWRJdGVtTlMwMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9yZW1vdmVOYW1lZEl0ZW1OUzAyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmRjMzRmZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcmVtb3ZlTmFtZWRJdGVtTlMwMi5qYXZhCkBAIC0wLDAgKzEsMTA5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInJlbW92ZU5hbWVkSXRlbU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpIiBtZXRob2QgZm9yIGEgCisgKiAgICBOYW1lZE5vZGVNYXAgc2hvdWxkIHJhaXNlIE5PVF9GT1VORF9FUlIgRE9NRXhjZXB0aW9uIGlmCisgKiAgICB0aGVyZSBpcyBubyBub2RlIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lc3BhY2VVUkkgYW5kIGxvY2FsTmFtZSBpbiB0aGlzIG1hcC4KKyAqICAgIAorICogICAgUmV0cmlldmUgYSBsaXN0IG9mIGVsZW1lbnRzIHdpdGggdGFnIG5hbWUgImFkZHJlc3MiLgorICogICAgQWNjZXNzIHRoZSBzZWNvbmQgZWxlbWVudCBmcm9tIHRoZSBsaXN0IGFuZCBnZXQgaXRzIGF0dHJpYnV0ZXMuCisgKiAgICBUcnkgdG8gcmVtb3ZlIGFuIGF0dHJpYnV0ZSBub2RlIHdpdGggbG9jYWwgbmFtZSAiZG9tZXN0IgorICogICAgYW5kIG5hbWVzcGFjZSB1cmkgImh0dHA6Ly93d3cudXNhLmNvbSIgd2l0aCAKKyAqICAgIG1ldGhvZCByZW1vdmVOYW1lZEl0ZW1OUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKS4KKyAqICAgIFRoaXMgc2hvdWxkIHJhaXNlIE5PVF9GT1VORF9FUlIgRE9NRXhjZXB0aW9uLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT1RfRk9VTkRfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PVF9GT1VORF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXJlbW92ZU5hbWVkSXRlbU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtcmVtb3ZlTmFtZWRJdGVtTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1yZW1vdmVOYW1lZEl0ZW1OUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PVF9GT1VORF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtcmVtb3ZlTmFtZWRJdGVtTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT1RfRk9VTkRfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyByZW1vdmVOYW1lZEl0ZW1OUzAyIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyByZW1vdmVOYW1lZEl0ZW1OUzAyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cudXNhLmNvbSI7CisgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gImRvbWVzdCI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEFkZHJlc3M7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIE5vZGUgcmVtb3ZlZE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICB0ZXN0QWRkcmVzcyA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICBhdHRyaWJ1dGVzID0gdGVzdEFkZHJlc3MuZ2V0QXR0cmlidXRlcygpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZW1vdmVkTm9kZSA9IGF0dHJpYnV0ZXMucmVtb3ZlTmFtZWRJdGVtTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT1RfRk9VTkRfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9GT1VORF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvcmVtb3ZlTmFtZWRJdGVtTlMwMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4ocmVtb3ZlTmFtZWRJdGVtTlMwMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcmVtb3ZlTmFtZWRJdGVtTlMwMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9yZW1vdmVOYW1lZEl0ZW1OUzAzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2ZkMzEwZAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvcmVtb3ZlTmFtZWRJdGVtTlMwMy5qYXZhCkBAIC0wLDAgKzEsMTMwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICBUaGUgInJlbW92ZU5hbWVkSXRlbU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpIiBtZXRob2QgZm9yIGEgCisgKiAgIE5hbWVkTm9kZU1hcCBzaG91bGQgcmFpc2UgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIERPTUV4Y2VwdGlvbiBpZgorICogICB0aGlzIG1hcCBpcyByZWFkb25seS4KKyAqICAgCisgKiAgIFJldHJpZXZlIGEgbGlzdCBvZiAiZ2VuZGVyIiBlbGVtZW50cy4gR2V0IGFjY2VzcyB0byB0aGUgVEhJUkQgZWxlbWVudAorICogICB3aGljaCBjb250YWlucyBhbiBFTlRJVFlfUkVGRVJFTkNFIGNoaWxkIG5vZGUuICBUcnkgdG8gcmVtb3ZlIHRoZSBhdHRyaWJ1dGUKKyAqICAgaW4gdGhlIG5vZGUncyBtYXAgd2l0aCBtZXRob2QgcmVtb3ZlTmFtZWRJdGVtTlMobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSkuCisgKiAgIFRoaXMgc2hvdWxkIHJlc3VsdCBpbiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIKKyAqICAgRE9NRXhjZXB0aW9uLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1yZW1vdmVOYW1lZEl0ZW1OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXJlbW92ZU5hbWVkSXRlbU5TPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtcmVtb3ZlTmFtZWRJdGVtTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtcmVtb3ZlTmFtZWRJdGVtTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIHJlbW92ZU5hbWVkSXRlbU5TMDMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHJlbW92ZU5hbWVkSXRlbU5TMDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iOworICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9ICJsb2NhbDEiOworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RBZGRyZXNzOworICAgICAgTm9kZUxpc3Qgbkxpc3Q7CisgICAgICBOb2RlIGNoaWxkOworICAgICAgTm9kZUxpc3QgbjJMaXN0OworICAgICAgTm9kZSBjaGlsZDI7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIE5vZGUgcmVtb3ZlZE5vZGU7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJnZW5kZXIiKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIG5MaXN0ID0gdGVzdEFkZHJlc3MuZ2V0Q2hpbGROb2RlcygpOworICAgICAgY2hpbGQgPSBuTGlzdC5pdGVtKDApOworICAgICAgbm9kZVR5cGUgPSAoaW50KSBjaGlsZC5nZXROb2RlVHlwZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDEsIG5vZGVUeXBlKSkgeworICAgICAgICAgIGNoaWxkID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBjaGlsZCk7CisgICAgICB9CisgICAgbjJMaXN0ID0gY2hpbGQuZ2V0Q2hpbGROb2RlcygpOworICAgICAgY2hpbGQyID0gbjJMaXN0Lml0ZW0oMCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJub3RudWxsIiwgY2hpbGQyKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSBjaGlsZDIuZ2V0QXR0cmlidXRlcygpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZW1vdmVkTm9kZSA9IGF0dHJpYnV0ZXMucmVtb3ZlTmFtZWRJdGVtTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3JlbW92ZU5hbWVkSXRlbU5TMDMiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHJlbW92ZU5hbWVkSXRlbU5TMDMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNlMDk5MmIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDEuamF2YQpAQCAtMCwwICsxLDEwMyBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkkscXVhbGlmaWVkTmFtZSxWYWx1ZSkiIG1ldGhvZCByYWlzZXMgYSAKKyAqICAgIElOVkFMSURfQ0hBUkFDVEVSX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZAorICogICAgcHJlZml4IGNvbnRhaW5zIGFuIGlsbGVnYWwgY2hhcmFjdGVyLgorICogICAgCisgKiAgICBBdHRlbXB0IHRvIGFkZCBhIG5ldyBhdHRyaWJ1dGUgb24gdGhlIGZpcnN0IGVtcGxveWVlIG5vZGUuCisgKiAgICBBbiBleGNlcHRpb24gc2hvdWxkIGJlIHJhaXNlZCBzaW5jZSB0aGUgInF1YWxpZmllZE5hbWUiIGhhcyBhbiBpbnZhbGlkIAorICogICAgY2hhcmFjdGVyLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0dHJOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXR0ck5TPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRWxTZXRBdHRyTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRWxTZXRBdHRyTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIHNldEF0dHJpYnV0ZU5TMDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHNldEF0dHJpYnV0ZU5TMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5uaXN0LmdvdiI7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJlbXA6cXVhbD9uYW1lIjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0QWRkcjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICB0ZXN0QWRkciA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICgoRWxlbWVudCkgLypOb2RlICovdGVzdEFkZHIpLnNldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSwgIm5ld1ZhbHVlIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTlZBTElEX0NIQVJBQ1RFUl9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMwMSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oc2V0QXR0cmlidXRlTlMwMS5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMwMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOUzAyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWE4MzU2MQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMwMi5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lLHZhbHVlKSIgbWV0aG9kIHJhaXNlcyBhIAorICogICAgTkFNRVNQQUNFX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZAorICogICAgcXVhbGlmaWVkTmFtZSBpZiBtYWxmb3JtZWQuCisgKiAgICAKKyAqICAgIEF0dGVtcHQgdG8gYWRkIGEgbmV3IGF0dHJpYnV0ZSBvbiB0aGUgc2Vjb25kIGVtcGxveWVlIG5vZGUuCisgKiAgICBBbiBleGNlcHRpb24gc2hvdWxkIGJlIHJhaXNlZCBzaW5jZSB0aGUgInF1YWxpZmllZE5hbWUiIGlzIG1hbGZvcm1lZC4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05BTUVTUEFDRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0dHJOUzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELUVsU2V0QXR0ck5TJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1FbFNldEF0dHJOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05BTUVTUEFDRV9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIHNldEF0dHJpYnV0ZU5TMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHNldEF0dHJpYnV0ZU5TMDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5uaXN0LmdvdiI7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJlbXA6IjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0QWRkcjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDplbXBsb3llZSIpOworICAgICAgdGVzdEFkZHIgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgCisgICAgICB7CisgICAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgICAgLy8gICAgIE91ciBleGNlcHRpb24gcHJpb3JpdGllcyBkaWZmZXIgZnJvbSB0aGUgc3BlYworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICgoRWxlbWVudCkgLypOb2RlICovdGVzdEFkZHIpLnNldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSwgIm5ld1ZhbHVlIik7CisgICAgICAgICAgICAgZmFpbCgidGhyb3dfTkFNRVNQQUNFX0VSUiIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgfQorICAgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMwMiI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oc2V0QXR0cmlidXRlTlMwMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMwMy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOUzAzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDE3NzQ0OQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMwMy5qYXZhCkBAIC0wLDAgKzEsMTIxIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUsdmFsdWUpIiBtZXRob2QgZm9yIGFuIGF0dHJpYnV0ZSBjYXVzZXMgdGhlIAorICogICAgRE9NRXhjZXB0aW9uIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiB0byBiZSByYWlzZWQKKyAqICAgIGlmIHRoZSBub2RlIGlzIHJlYWRvbmx5LgorICogICAgCisgKiAgICBPYnRhaW4gdGhlIGNoaWxkcmVuIG9mIHRoZSBUSElSRCAiZ2VuZGVyIiBlbGVtZW50LiAgVGhlIGVsZW1lbnRzCisgKiAgICBjb250ZW50IGlzIGFuIGVudGl0eSByZWZlcmVuY2UuICBUcnkgdG8gc2V0IGFuIGF0dHJpYnV0ZQorICogICAgaW4gdGhlIGVudGl0eSByZWZlcmVuY2UgYnkgZXhlY3V0aW5nIHRoZSAKKyAqICAgICJzZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkkscXVhbGlmaWVkTmFtZSx2YWx1ZSkiIG1ldGhvZC4KKyAqICAgIFRoaXMgY2F1c2VzIGEgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIERPTUV4Y2VwdGlvbiB0byBiZSB0aHJvd24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdHRyTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1FbFNldEF0dHJOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1FbFNldEF0dHJOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgc2V0QXR0cmlidXRlTlMwMyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgc2V0QXR0cmlidXRlTlMwMyhmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJ3d3cueHl6LmNvbSI7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJlbXA6bG9jYWwxIjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGdlbmRlckxpc3Q7CisgICAgICBOb2RlIGdlbmRlcjsKKyAgICAgIE5vZGVMaXN0IGdlbkxpc3Q7CisgICAgICBOb2RlIGdlbjsKKyAgICAgIE5vZGVMaXN0IGdMaXN0OworICAgICAgRWxlbWVudCBnZW5FbGVtZW50OworICAgICAgaW50IG5vZGVUeXBlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBnZW5kZXJMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJnZW5kZXIiKTsKKyAgICAgIGdlbmRlciA9IGdlbmRlckxpc3QuaXRlbSgyKTsKKyAgICAgIGdlbkxpc3QgPSBnZW5kZXIuZ2V0Q2hpbGROb2RlcygpOworICAgICAgZ2VuID0gZ2VuTGlzdC5pdGVtKDApOworICAgICAgbm9kZVR5cGUgPSAoaW50KSBnZW4uZ2V0Tm9kZVR5cGUoKTsKKyAgICAgIAorICAgICAgaWYgKGVxdWFscygxLCBub2RlVHlwZSkpIHsKKyAgICAgICAgICBnZW4gPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQ0Iik7CisgICAgICBhc3NlcnROb3ROdWxsKCJjcmVhdGVkRW50UmVmTm90TnVsbCIsIGdlbik7CisgICAgICB9CisgICAgZ0xpc3QgPSBnZW4uZ2V0Q2hpbGROb2RlcygpOworICAgICAgZ2VuRWxlbWVudCA9IChFbGVtZW50KSBnTGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgibm90bnVsbCIsIGdlbkVsZW1lbnQpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBnZW5FbGVtZW50LnNldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSwgIm5ld1ZhbHVlIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oc2V0QXR0cmlidXRlTlMwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMwNC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOUzA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjcyZmM2MwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMwNC5qYXZhCkBAIC0wLDAgKzEsMTE2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUsdmFsdWUpIiBtZXRob2QgYWRkcyBhIG5ldyBhdHRyaWJ1dGUuCisgKiAgICBJZiBhbiBhdHRyaWJ1dGUgd2l0aCB0aGUgc2FtZSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJIGlzIGFscmVhZHkgcHJlc2VudAorICogICAgb24gdGhlIGVsZW1lbnQsIGl0cyBwcmVmaXggaXMgY2hhbmdlZCB0byBiZSB0aGUgcHJlZml4IHBhcnQgb2YgdGhlICJxdWFsaWZpZWROYW1lIiwKKyAqICAgIGFuZCBpdHMgdmFsZSBpcyBjaGFuZ2VkIHRvIGJlIHRoZSAidmFsdWUiIHBhcmFtdGVyLgorICogICAgbnVsbCB2YWx1ZSBpZiBubyBwcmV2aW91c2x5IGV4aXN0aW5nIEF0dHIgbm9kZSB3aXRoIHRoZQorICogICAgc2FtZSBuYW1lIHdhcyByZXBsYWNlZC4KKyAqICAgIAorICogICAgQWRkIGEgbmV3IGF0dHJpYnV0ZSB0byB0aGUgImVtcDphZGRyZXNzIiBlbGVtZW50LgorICogICAgQ2hlY2sgdG8gc2VlIGlmIHRoZSBuZXcgYXR0cmlidXRlIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBhZGRlZCB0byB0aGUgZG9jdW1lbnQKKyAqICAgIGJ5IGdldHRpbmcgdGhlIGF0dHJpYnV0ZXMgdmFsdWUsIG5hbWVzcGFjZSBVUkksIGxvY2FsIE5hbWUgYW5kIHByZWZpeC4KKyAqICAgIFRoZSBwcmVmaXggd2lsbCBiZSBjaGFuZ2VkIHRvIHRoZSBwcmVmaXggcGFydCBvZiB0aGUgInF1YWxpZmllZE5hbWUiIAorICogICAgYW5kIGl0cyB2YWx1ZSBjaGFuZ2VkIHRvIHRoZSAidmFsdWUiIHBhcmFtZXRlci4gICAgCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBzZXRBdHRyaWJ1dGVOUzA0IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBzZXRBdHRyaWJ1dGVOUzA0KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEFkZHI7CisgICAgICBBdHRyIGFkZHJBdHRyOworICAgICAgU3RyaW5nIHJlc3VsdEF0dHI7CisgICAgICBTdHJpbmcgcmVzdWx0TmFtZXNwYWNlVVJJOworICAgICAgU3RyaW5nIHJlc3VsdExvY2FsTmFtZTsKKyAgICAgIFN0cmluZyByZXN1bHRQcmVmaXg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6YWRkcmVzcyIpOworICAgICAgdGVzdEFkZHIgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkck5vdE51bGwiLCB0ZXN0QWRkcik7CisgICAgICAoKEVsZW1lbnQpIC8qTm9kZSAqL3Rlc3RBZGRyKS5zZXRBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJuZXdwcmVmaXg6em9uZSIsICJuZXdWYWx1ZSIpOworICAgICAgYWRkckF0dHIgPSAoKEVsZW1lbnQpIC8qTm9kZSAqL3Rlc3RBZGRyKS5nZXRBdHRyaWJ1dGVOb2RlTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAiem9uZSIpOworICAgICAgcmVzdWx0QXR0ciA9ICgoRWxlbWVudCkgLypOb2RlICovdGVzdEFkZHIpLmdldEF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgInpvbmUiKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0clZhbHVlIiwgIm5ld1ZhbHVlIiwgcmVzdWx0QXR0cik7CisgICAgICByZXN1bHROYW1lc3BhY2VVUkkgPSBhZGRyQXR0ci5nZXROYW1lc3BhY2VVUkkoKTsKKyAgICAgIGFzc2VydEVxdWFscygibnN1cmkiLCAiaHR0cDovL3d3dy5uaXN0LmdvdiIsIHJlc3VsdE5hbWVzcGFjZVVSSSk7CisgICAgICByZXN1bHRMb2NhbE5hbWUgPSBhZGRyQXR0ci5nZXRMb2NhbE5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibG5hbWUiLCAiem9uZSIsIHJlc3VsdExvY2FsTmFtZSk7CisgICAgICByZXN1bHRQcmVmaXggPSBhZGRyQXR0ci5nZXRQcmVmaXgoKTsKKyAgICAgIGFzc2VydEVxdWFscygicHJlZml4IiwgIm5ld3ByZWZpeCIsIHJlc3VsdFByZWZpeCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHNldEF0dHJpYnV0ZU5TMDQuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMwNS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4YzIzYmEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDUuamF2YQpAQCAtMCwwICsxLDEwMiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lLHZhbHVlKSIgbWV0aG9kIGFkZHMgYSBuZXcgYXR0cmlidXRlLgorICogICAgSWYgYW4gYXR0cmlidXRlIHdpdGggdGhlIHNhbWUgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSBpcyBhbHJlYWR5IHByZXNlbnQKKyAqICAgIG9uIHRoZSBlbGVtZW50LCBpdHMgcHJlZml4IGlzIGNoYW5nZWQgdG8gYmUgdGhlIHByZWZpeCBwYXJ0IG9mIHRoZSAicXVhbGlmaWVkTmFtZSIsCisgKiAgICBhbmQgaXRzIHZhbGUgaXMgY2hhbmdlZCB0byBiZSB0aGUgInZhbHVlIiBwYXJhbXRlci4KKyAqICAgIG51bGwgdmFsdWUgaWYgbm8gcHJldmlvdXNseSBleGlzdGluZyBBdHRyIG5vZGUgd2l0aCB0aGUKKyAqICAgIHNhbWUgbmFtZSB3YXMgcmVwbGFjZWQuCisgKiAgICAKKyAqICAgIEFkZCBhIG5ldyBhdHRyaWJ1dGUgdG8gdGhlICJlbXA6YWRkcmVzcyIgZWxlbWVudC4KKyAqICAgIENoZWNrIHRvIHNlZSBpZiB0aGUgbmV3IGF0dHJpYnV0ZSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYWRkZWQgdG8gdGhlIGRvY3VtZW50LgorICogICAgVGhlIG5ldyBhdHRyaWJ1dGUgIjxuZXdWYWx1ZT4iIGNvbnRhaW5zIG1hcmt1cCBhbmQgdGhlcmVmb3JlIGlzIGVzY2FwZWQKKyAqICAgIGJ5IHRoZSBpbXBsZW1lbnRhdGlvbi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEdldEF0dHJOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsR2V0QXR0ck5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBzZXRBdHRyaWJ1dGVOUzA1IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBzZXRBdHRyaWJ1dGVOUzA1KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gIm5ld0F0dHIiOworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5ld2F0dHIuY29tIjsKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gImVtcDpuZXdBdHRyIjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0QWRkcjsKKyAgICAgIEF0dHIgYWRkckF0dHI7CisgICAgICBTdHJpbmcgcmVzdWx0QXR0cjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICB0ZXN0QWRkciA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbXBBZGRyTm90TnVsbCIsIHRlc3RBZGRyKTsKKyAgICAgICgoRWxlbWVudCkgLypOb2RlICovdGVzdEFkZHIpLnNldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSwgIjxuZXdWYWx1ZT4iKTsKKyAgICAgIHJlc3VsdEF0dHIgPSAoKEVsZW1lbnQpIC8qTm9kZSAqL3Rlc3RBZGRyKS5nZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoInRocm93X0VxdWFscyIsICI8bmV3VmFsdWU+IiwgcmVzdWx0QXR0cik7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDUiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHNldEF0dHJpYnV0ZU5TMDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDYuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMwNi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY4N2ZlMzkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDYuamF2YQpAQCAtMCwwICsxLDEwNCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lLHZhbHVlKSIgbWV0aG9kIHJhaXNlcyBhIAorICogICAgTkFNRVNQQUNFX0VSUiBET01FeGNlcHRpb24gaWYgdGhlICJxdWFsaWZpZWROYW1lIiBoYXMgYQorICogICAgcHJlZml4IG9mICJ4bWwiIGFuZCB0aGUgbmFtZXNwYWNlVVJJIGlzIGRpZmZlcmVudCBmcm9tCisgKiAgICBodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UuCisgKiAgICAKKyAqICAgIEF0dGVtcHQgdG8gYWRkIGFuIGF0dHJpYnV0ZSB3aXRoIGEgcHJlZml4IG9mICJ4bWwiIGFzIHRoZSBvbiB0aGUgZmlyc3QgZW1wbG95ZWUgbm9kZS4KKyAqICAgIEFuIGV4Y2VwdGlvbiBzaG91bGQgYmUgcmFpc2VkIHNpbmNlIHRoZSBuYW1lc3BhY2VVUkkgb2YgdGhpcyBub2RlIGlzIG5vdCAKKyAqICAgIGh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZS4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOQU1FU1BBQ0VfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0dHJOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXR0ck5TPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRWxTZXRBdHRyTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOQU1FU1BBQ0VfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELUVsU2V0QXR0ck5TJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgc2V0QXR0cmlidXRlTlMwNiBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgc2V0QXR0cmlidXRlTlMwNihmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5pc3QuZ292IjsKKyAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gInhtbDpxdWFsaWZpZWROYW1lIjsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0QWRkcjsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICB0ZXN0QWRkciA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICgoRWxlbWVudCkgLypOb2RlICovdGVzdEFkZHIpLnNldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSwgIm5ld1ZhbHVlIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOUzA2IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihzZXRBdHRyaWJ1dGVOUzA2LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOUzA3LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOTAzZWViCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOUzA3LmphdmEKQEAgLTAsMCArMSwxMDUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSx2YWx1ZSkiIG1ldGhvZCByYWlzZXMgYSAKKyAqICAgIE5BTUVTUEFDRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHRoZSAicXVhbGlmaWVkTmFtZSIgaGFzIGEKKyAqICAgIHZhbHVlIG9mICJ4bWxucyIgYW5kIHRoZSBuYW1lc3BhY2VVUkkgaXMgZGlmZmVyZW50IGZyb20KKyAqICAgIGh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMuCisgKiAgICAKKyAqICAgIEF0dGVtcHQgdG8gYWRkIGFuIGF0dHJpYnV0ZSB3aXRoIGEgInF1YWxpZmllZE5hbWUiIG9mICJ4bWxucyIgYXMgdGhlIAorICogICAgb24gdGhlIGZpcnN0IGVtcGxveWVlIG5vZGUuCisgKiAgICBBbiBleGNlcHRpb24gc2hvdWxkIGJlIHJhaXNlZCBzaW5jZSB0aGUgbmFtZXNwYWNlVVJJIG9mIHRoaXMgbm9kZSBpcyBub3QgCisgKiAgICBodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOQU1FU1BBQ0VfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05BTUVTUEFDRV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdHRyTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1FbFNldEF0dHJOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05BTUVTUEFDRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRWxTZXRBdHRyTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOQU1FU1BBQ0VfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBzZXRBdHRyaWJ1dGVOUzA3IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAvKioKKyAgICAqIENvbnN0cnVjdG9yLgorICAgICogQHBhcmFtIGZhY3RvcnkgZG9jdW1lbnQgZmFjdG9yeSwgbWF5IG5vdCBiZSBudWxsCisgICAgKiBAdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGVzdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHBhcnNlciBjb25maWd1cmF0aW9uCisgICAgKi8KKyAgIHB1YmxpYyBzZXRBdHRyaWJ1dGVOUzA3KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cubmlzdC5nb3YiOworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAieG1sbnMiOworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RBZGRyOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgIHRlc3RBZGRyID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgKChFbGVtZW50KSAvKk5vZGUgKi90ZXN0QWRkcikuc2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lLCAibmV3VmFsdWUiKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDciOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHNldEF0dHJpYnV0ZU5TMDcuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDkuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMwOS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc4MTcxZDEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDkuamF2YQpAQCAtMCwwICsxLDExMSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lLHZhbHVlKSIgbWV0aG9kIGFkZHMgYSBuZXcgYXR0cmlidXRlLgorICogICAgSWYgYW4gYXR0cmlidXRlIHdpdGggdGhlIHNhbWUgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSBpcyBhbHJlYWR5IHByZXNlbnQKKyAqICAgIG9uIHRoZSBlbGVtZW50LCBpdHMgcHJlZml4IGlzIGNoYW5nZWQgdG8gYmUgdGhlIHByZWZpeCBwYXJ0IG9mIHRoZSAicXVhbGlmaWVkTmFtZSIsCisgKiAgICBhbmQgaXRzIHZhbGUgaXMgY2hhbmdlZCB0byBiZSB0aGUgInZhbHVlIiBwYXJhbXRlci4KKyAqICAgIG51bGwgdmFsdWUgaWYgbm8gcHJldmlvdXNseSBleGlzdGluZyBBdHRyIG5vZGUgd2l0aCB0aGUKKyAqICAgIHNhbWUgbmFtZSB3YXMgcmVwbGFjZWQuCisgKiAgICAKKyAqICAgIEFkZCBhIG5ldyBhdHRyaWJ1dGUgdG8gdGhlICJlbXA6YWRkcmVzcyIgZWxlbWVudC4KKyAqICAgIENoZWNrIHRvIHNlZSBpZiB0aGUgbmV3IGF0dHJpYnV0ZSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYWRkZWQgdG8gdGhlIGRvY3VtZW50CisgKiAgICBieSBnZXR0aW5nIHRoZSBhdHRyaWJ1dGVzIHZhbHVlLCBuYW1lc3BhY2UgVVJJLCBsb2NhbCBOYW1lIGFuZCBwcmVmaXguCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0dHJOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgc2V0QXR0cmlidXRlTlMwOSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgc2V0QXR0cmlidXRlTlMwOShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9ICJuZXdBdHRyIjsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5uZXdhdHRyLmNvbSI7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJlbXA6bmV3QXR0ciI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEFkZHI7CisgICAgICBBdHRyIGFkZHJBdHRyOworICAgICAgU3RyaW5nIHJlc3VsdEF0dHI7CisgICAgICBTdHJpbmcgcmVzdWx0TmFtZXNwYWNlVVJJOworICAgICAgU3RyaW5nIHJlc3VsdExvY2FsTmFtZTsKKyAgICAgIFN0cmluZyByZXN1bHRQcmVmaXg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6YWRkcmVzcyIpOworICAgICAgdGVzdEFkZHIgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkck5vdE51bGwiLCB0ZXN0QWRkcik7CisgICAgICAoKEVsZW1lbnQpIC8qTm9kZSAqL3Rlc3RBZGRyKS5zZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsICJuZXdWYWx1ZSIpOworICAgICAgYWRkckF0dHIgPSAoKEVsZW1lbnQpIC8qTm9kZSAqL3Rlc3RBZGRyKS5nZXRBdHRyaWJ1dGVOb2RlTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgcmVzdWx0QXR0ciA9ICgoRWxlbWVudCkgLypOb2RlICovdGVzdEFkZHIpLmdldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKKyAgICAgIGFzc2VydEVxdWFscygiYXR0clZhbHVlIiwgIm5ld1ZhbHVlIiwgcmVzdWx0QXR0cik7CisgICAgICByZXN1bHROYW1lc3BhY2VVUkkgPSBhZGRyQXR0ci5nZXROYW1lc3BhY2VVUkkoKTsKKyAgICAgIGFzc2VydEVxdWFscygibnN1cmkiLCAiaHR0cDovL3d3dy5uZXdhdHRyLmNvbSIsIHJlc3VsdE5hbWVzcGFjZVVSSSk7CisgICAgICByZXN1bHRMb2NhbE5hbWUgPSBhZGRyQXR0ci5nZXRMb2NhbE5hbWUoKTsKKyAgICAgIGFzc2VydEVxdWFscygibG5hbWUiLCAibmV3QXR0ciIsIHJlc3VsdExvY2FsTmFtZSk7CisgICAgICByZXN1bHRQcmVmaXggPSBhZGRyQXR0ci5nZXRQcmVmaXgoKTsKKyAgICAgIGFzc2VydEVxdWFscygicHJlZml4IiwgImVtcCIsIHJlc3VsdFByZWZpeCk7CisgICAgICB9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMDkiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHNldEF0dHJpYnV0ZU5TMDkuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMTAuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMxMC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjczMDUzYTgKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5TMTAuamF2YQpAQCAtMCwwICsxLDk2IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqIEVsZW1lbnQuc2V0QXR0cmlidXRlTlMgd2l0aCBhbiBlbXB0eSBxdWFsaWZpZWQgbmFtZSBzaG91bGQgY2F1c2UgYW4gSU5WQUxJRF9DSEFSQUNURVJfRVJSLgorKiBAYXV0aG9yIEN1cnQgQXJub2xkCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0dHJOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXR0ck5TPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRWxTZXRBdHRyTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRWxTZXRBdHRyTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTUyNSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTUyNTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgc2V0QXR0cmlidXRlTlMxMCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgc2V0QXR0cmlidXRlTlMxMChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAiaGNfc3RhZmYiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5leGFtcGxlLmdvdiI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEFkZHI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW0iKTsKKyAgICAgIHRlc3RBZGRyID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgKChFbGVtZW50KSAvKk5vZGUgKi90ZXN0QWRkcikuc2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCAiIiwgIm5ld1ZhbHVlIik7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTlZBTElEX0NIQVJBQ1RFUl9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTlMxMCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oc2V0QXR0cmlidXRlTlMxMC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTm9kZU5TMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTm9kZU5TMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMmNkMTUyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOb2RlTlMwMS5qYXZhCkBAIC0wLDAgKzEsMTE4IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0QXR0cmlidXRlTm9kZShuZXdBdHRyKSIgbWV0aG9kIHJhaXNlcyBhbiAKKyAqICAgICJJTlVTRV9BVFRSSUJVVEVfRVJSIERPTUV4Y2VwdGlvbiBpZiB0aGUgIm5ld0F0dHIiIAorICogICAgaXMgYWxyZWFkeSBhbiBhdHRyaWJ1dGUgb2YgYW5vdGhlciBlbGVtZW50LgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgZW1wOmFkZHJlc3MgYW5kIGFwcGVuZAorICogICAgYSBuZXdseSBjcmVhdGVkIGVsZW1lbnQuICBUaGUgImNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lKSIKKyAqICAgIGFuZCAic2V0QXR0cmlidXRlTm9kZU5TKG5ld0F0dHIpIiBtZXRob2RzIGFyZSBpbnZva2VkCisgKiAgICB0byBjcmVhdGUgYW5kIGFkZCBhIG5ldyBhdHRyaWJ1dGUgdG8gdGhlIG5ld2x5IGNyZWF0ZWQKKyAqICAgIEVsZW1lbnQuICBUaGUgInNldEF0dHJpYnV0ZU5vZGVOUyhuZXdBdHRyKSIgbWV0aG9kIGlzCisgKiAgICBvbmNlIGFnYWluIGNhbGxlZCB0byBhZGQgdGhlIG5ldyBhdHRyaWJ1dGUgY2F1c2luZyBhbgorICogICAgZXhjZXB0aW9uIHRvIGJlIHJhaXNlZCBzaW5jZSB0aGUgYXR0cmlidXRlIGlzIGFscmVhZHkKKyAqICAgIGFuIGF0dHJpYnV0ZSBvZiBhbm90aGVyIGVsZW1lbnQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVVNFX0FUVFJJQlVURV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdE5vZGVOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXROb2RlTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1FbFNldEF0Tm9kZU5TJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1FbFNldEF0Tm9kZU5TJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgc2V0QXR0cmlidXRlTm9kZU5TMDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHNldEF0dHJpYnV0ZU5vZGVOUzAxKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cubmV3YXR0ci5jb20iOworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiZW1wOm5ld0F0dHIiOworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBuZXdFbGVtZW50OworICAgICAgQXR0ciBuZXdBdHRyOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RBZGRyOworICAgICAgTm9kZSBhcHBlbmRlZENoaWxkOworICAgICAgQXR0ciBzZXRBdHRyMTsKKyAgICAgIEF0dHIgc2V0QXR0cjI7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6YWRkcmVzcyIpOworICAgICAgdGVzdEFkZHIgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkck5vdE51bGwiLCB0ZXN0QWRkcik7CisgICAgICBuZXdFbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnQoIm5ld0VsZW1lbnQiKTsKKyAgICAgIGFwcGVuZGVkQ2hpbGQgPSB0ZXN0QWRkci5hcHBlbmRDaGlsZChuZXdFbGVtZW50KTsKKyAgICAgIG5ld0F0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgIHNldEF0dHIxID0gbmV3RWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMobmV3QXR0cik7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldEF0dHIyID0gKChFbGVtZW50KSAvKk5vZGUgKi90ZXN0QWRkcikuc2V0QXR0cmlidXRlTm9kZU5TKG5ld0F0dHIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTlVTRV9BVFRSSUJVVEVfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOVVNFX0FUVFJJQlVURV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTm9kZU5TMDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHNldEF0dHJpYnV0ZU5vZGVOUzAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOb2RlTlMwMi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOb2RlTlMwMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiMjk2NWEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5vZGVOUzAyLmphdmEKQEAgLTAsMCArMSwxMjcgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0QXR0cmlidXRlTm9kZU5TKG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lLHZhbHVlKSIgbWV0aG9kIGZvciBhbiBhdHRyaWJ1dGUgY2F1c2VzIHRoZSAKKyAqICAgIERPTUV4Y2VwdGlvbiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgdG8gYmUgcmFpc2VkCisgKiAgICBpZiB0aGUgbm9kZSBpcyByZWFkb25seS4KKyAqICAgIAorICogICAgT2J0YWluIHRoZSBjaGlsZHJlbiBvZiB0aGUgVEhJUkQgImdlbmRlciIgZWxlbWVudC4gIFRoZSBlbGVtZW50cworICogICAgY29udGVudCBpcyBhbiBlbnRpdHkgcmVmZXJlbmNlLiAgVHJ5IHRvIHNldCBhbiBhdHRyaWJ1dGUKKyAqICAgIGluIHRoZSBlbnRpdHkgcmVmZXJlbmNlIGJ5IGV4ZWN1dGluZyB0aGUgCisgKiAgICAic2V0QXR0cmlidXRlTm9kZU5TKG5ld0F0dHIpIiBtZXRob2QuCisgKiAgICBUaGlzIGNhdXNlcyBhIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiBET01FeGNlcHRpb24gdG8gYmUgdGhyb3duLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0Tm9kZU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdE5vZGVOUzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELUVsU2V0QXROb2RlTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRWxTZXRBdE5vZGVOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgc2V0QXR0cmlidXRlTm9kZU5TMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHNldEF0dHJpYnV0ZU5vZGVOUzAyKGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKworICAgICAgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSAKKyAgICAgICAgICBuZXcgb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworb3JnLnczYy5kb210cy5Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5vdE5hbWVzcGFjZUF3YXJlCisgICAgICAgIH07CisgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHRlc3RGYWN0b3J5ID0gZmFjdG9yeS5uZXdJbnN0YW5jZShzZXR0aW5ncyk7CisgICAgICAgIHNldEZhY3RvcnkodGVzdEZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBnZW5kZXJMaXN0OworICAgICAgTm9kZSBnZW5kZXI7CisgICAgICBOb2RlTGlzdCBnZW5MaXN0OworICAgICAgTm9kZSBnZW47CisgICAgICBOb2RlTGlzdCBnTGlzdDsKKyAgICAgIEVsZW1lbnQgZ2VuRWxlbWVudDsKKyAgICAgIEF0dHIgbmV3QXR0cjsKKyAgICAgIEF0dHIgc2V0QXR0cjE7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIAorICAgICAgaWYgKCFpc0V4cGFuZEVudGl0eVJlZmVyZW5jZXMoKSkgeworICAgICAgICAgIGdlbmRlckxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImdlbmRlciIpOworICAgICAgZ2VuZGVyID0gZ2VuZGVyTGlzdC5pdGVtKDIpOworICAgICAgZ2VuTGlzdCA9IGdlbmRlci5nZXRDaGlsZE5vZGVzKCk7CisgICAgICBnZW4gPSBnZW5MaXN0Lml0ZW0oMCk7CisgICAgICB9IGVsc2UgeworICAgICAgICAgIGdlbiA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDQiKTsKKyAgICAgIH0KKyAgICAgICAgCisgICAgZ0xpc3QgPSBnZW4uZ2V0Q2hpbGROb2RlcygpOworICAgICAgZ2VuRWxlbWVudCA9IChFbGVtZW50KSBnTGlzdC5pdGVtKDApOworICAgICAgYXNzZXJ0Tm90TnVsbCgibm90bnVsbCIsIGdlbkVsZW1lbnQpOworICAgICAgbmV3QXR0ciA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygid3d3Lnh5ei5jb20iLCAiZW1wOmxvY2FsMSIpOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXRBdHRyMSA9IGdlbkVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZU5TKG5ld0F0dHIpOworICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5vZGVOUzAyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihzZXRBdHRyaWJ1dGVOb2RlTlMwMi5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTm9kZU5TMDMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTm9kZU5TMDMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MjE1YWNiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOb2RlTlMwMy5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0QXR0cmlidXRlTm9kZU5TKG5ld0F0dHIpIiBhZGRzIGEgbmV3IGF0dHJpYnV0ZS4KKyAqICAgIElmIGFuIGF0dHJpYnV0ZSB3aXRoIHRoYXQgbG9jYWwgbmFtZSBhbmQgdGhhdCBuYW1lc3BhY2VVUkkgaXMgYWxyZWFkeQorICogICAgcHJlc2VudCBpbiB0aGUgZWxlbWVudCwgaXQgaXMgcmVwbGFjZWQgYnkgdGhlIG5ldyBvbmUuCisgKiAgICAKKyAqICAgIFJldHJpZXZlIHRoZSBmaXJzdCBlbXA6YWRkcmVzcyBlbGVtZW50IGFuZCBhZGQgYSBuZXcgYXR0cmlidXRlCisgKiAgICB0byB0aGUgZWxlbWVudC4gIFNpbmNlIGFuIGF0dHJpYnV0ZSB3aXRoIHRoZSBzYW1lIGxvY2FsIG5hbWUKKyAqICAgIGFuZCBuYW1lc3BhY2VVUkkgYXMgdGhlIG5ld2x5IGNyZWF0ZWQgYXR0cmlidXRlIGRvZXMgbm90IGV4aXN0CisgKiAgICB0aGUgdmFsdWUgIm51bGwiIGlzIHJldHVybmVkLgorICogICAgVGhpcyB0ZXN0IHVzZXMgdGhlICJjcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKQorICogICAgbWV0aG9kIGZyb20gdGhlIERvY3VtZW50IGludGVyZmFjZSB0byBjcmVhdGUgdGhlIG5ldyBhdHRyaWJ1dGUgdG8gYWRkLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXROb2RlTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0Tm9kZU5TPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBzZXRBdHRyaWJ1dGVOb2RlTlMwMyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgc2V0QXR0cmlidXRlTm9kZU5TMDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5uZXdhdHRyLmNvbSI7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJlbXA6bmV3QXR0ciI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEFkZHI7CisgICAgICBBdHRyIG5ld0F0dHI7CisgICAgICBBdHRyIG5ld0FkZHJBdHRyOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGFzc2VydE5vdE51bGwoImVtcEFkZHJOb3ROdWxsIiwgdGVzdEFkZHIpOworICAgICAgbmV3QXR0ciA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgbmV3QWRkckF0dHIgPSAoKEVsZW1lbnQpIC8qTm9kZSAqL3Rlc3RBZGRyKS5zZXRBdHRyaWJ1dGVOb2RlTlMobmV3QXR0cik7CisgICAgICBhc3NlcnROdWxsKCJ0aHJvd19OdWxsIiwgbmV3QWRkckF0dHIpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOb2RlTlMwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oc2V0QXR0cmlidXRlTm9kZU5TMDMuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5vZGVOUzA0LmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5vZGVOUzA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjFiNzQyZAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTm9kZU5TMDQuamF2YQpAQCAtMCwwICsxLDEwNiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldEF0dHJpYnV0ZU5vZGVOUyhuZXdBdHRyKSIgYWRkcyBhIG5ldyBhdHRyaWJ1dGUuCisgKiAgICBJZiBhbiBhdHRyaWJ1dGUgd2l0aCB0aGF0IGxvY2FsIG5hbWUgYW5kIHRoYXQgbmFtZXNwYWNlVVJJIGlzIGFscmVhZHkKKyAqICAgIHByZXNlbnQgaW4gdGhlIGVsZW1lbnQsIGl0IGlzIHJlcGxhY2VkIGJ5IHRoZSBuZXcgb25lLgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgZmlyc3QgZW1wOmFkZHJlc3MgZWxlbWVudCBhbmQgYWRkIGEgbmV3IGF0dHJpYnV0ZQorICogICAgdG8gdGhlIGVsZW1lbnQuICBTaW5jZSBhbiBhdHRyaWJ1dGUgd2l0aCB0aGUgc2FtZSBsb2NhbCBuYW1lCisgKiAgICBhbmQgbmFtZXNwYWNlVVJJIGFscmVhZHkgZXhpc3RzLCBpdCBpcyByZXBsYWNlZCBieSB0aGUgbmV3IG9uZSBhbmQKKyAqICAgIHJldHVybnMgdGhlIHJlcGxhY2VkICJBdHRyIiBub2RlLgorICogICAgVGhpcyB0ZXN0IHVzZXMgdGhlICJjcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKQorICogICAgbWV0aG9kIGZyb20gdGhlIERvY3VtZW50IGludGVyZmFjZSB0byBjcmVhdGUgdGhlIG5ldyBhdHRyaWJ1dGUgdG8gYWRkLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1GNjhEMDk1PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBzZXRBdHRyaWJ1dGVOb2RlTlMwNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgc2V0QXR0cmlidXRlTm9kZU5TMDQoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0QWRkcjsKKyAgICAgIEF0dHIgbmV3QXR0cjsKKyAgICAgIEF0dHIgbmV3QWRkckF0dHI7CisgICAgICBTdHJpbmcgbmV3TmFtZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICB0ZXN0QWRkciA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJlbXBBZGRyTm90TnVsbCIsIHRlc3RBZGRyKTsKKyAgICAgIG5ld0F0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAieHh4OmRvbWVzdGljIik7CisgICAgICBuZXdBZGRyQXR0ciA9ICgoRWxlbWVudCkgLypOb2RlICovdGVzdEFkZHIpLnNldEF0dHJpYnV0ZU5vZGVOUyhuZXdBdHRyKTsKKyAgICAgIG5ld05hbWUgPSBuZXdBZGRyQXR0ci5nZXROb2RlTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTmFtZSIsICJlbXA6ZG9tZXN0aWMiLCBuZXdOYW1lKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvc2V0QXR0cmlidXRlTm9kZU5TMDQiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHNldEF0dHJpYnV0ZU5vZGVOUzA0LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOb2RlTlMwNS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOb2RlTlMwNS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjMjRkMzkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldEF0dHJpYnV0ZU5vZGVOUzA1LmphdmEKQEAgLTAsMCArMSwxMTQgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0QXR0cmlidXRlTm9kZU5TKG5ld0F0dHIpIiBtZXRob2QgcmFpc2VzIGFuIAorICogICAgIldST05HX0RPQ1VNRU5UX0VSUiBET01FeGNlcHRpb24gaWYgdGhlICJuZXdBdHRyIiAKKyAqICAgIHdhcyBjcmVhdGVkIGZyb20gYSBkaWZmZXJlbnQgZG9jdW1lbnQgdGhhbiB0aGUgb25lIHRoYXQKKyAqICAgIGNyZWF0ZWQgdGhpcyBkb2N1bWVudC4KKyAqICAgIAorICogICAgUmV0cmlldmUgdGhlIGZpcnN0IGVtcDphZGRyZXNzIGFuZCBhdHRlbXB0IHRvIHNldCBhIG5ldworICogICAgYXR0cmlidXRlIG5vZGUuICBUaGUgbmV3CisgKiAgICBhdHRyaWJ1dGUgd2FzIGNyZWF0ZWQgZnJvbSBhIGRvY3VtZW50IG90aGVyIHRoYW4gdGhlCisgKiAgICBvbmUgdGhhdCBjcmVhdGVkIHRoaXMgZWxlbWVudCwgdGhlcmVmb3JlIGEKKyAqICAgIFdST05HX0RPQ1VNRU5UX0VSUiBET01FeGNlcHRpb24gc2hvdWxkIGJlIHJhaXNlZC4KKyAqICAgIFRoaXMgdGVzdCB1c2VzIHRoZSAiY3JlYXRlQXR0cmlidXRlTlMobmV3QXR0cikiIG1ldGhvZAorICogICAgZnJvbSB0aGUgRG9jdW1lbnQgaW50ZXJmYWNlLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdXUk9OR19ET0NVTUVOVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nV1JPTkdfRE9DVU1FTlRfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0Tm9kZU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdE5vZGVOUzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELUVsU2V0QXROb2RlTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdXUk9OR19ET0NVTUVOVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRWxTZXRBdE5vZGVOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J1dST05HX0RPQ1VNRU5UX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgc2V0QXR0cmlidXRlTm9kZU5TMDUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHNldEF0dHJpYnV0ZU5vZGVOUzA1KGZpbmFsIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpICB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGZhY3RvcnkpOworCisgICAgLy8KKyAgICAvLyAgIGNoZWNrIGlmIGxvYWRlZCBkb2N1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgY29udGVudCB0eXBlCisgICAgLy8KKyAgICBTdHJpbmcgY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpOworICAgIHByZWxvYWQoY29udGVudFR5cGUsICJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5uZXdhdHRyLmNvbSI7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJlbXA6bmV3QXR0ciI7CisgICAgICBEb2N1bWVudCBkb2MxOworICAgICAgRG9jdW1lbnQgZG9jMjsKKyAgICAgIEF0dHIgbmV3QXR0cjsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0QWRkcjsKKyAgICAgIEF0dHIgc2V0QXR0cjE7CisgICAgICBkb2MxID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBkb2MyID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBuZXdBdHRyID0gZG9jMi5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MxLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6YWRkcmVzcyIpOworICAgICAgdGVzdEFkZHIgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgCisgICAgICB7CisgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXRBdHRyMSA9ICgoRWxlbWVudCkgLypOb2RlICovdGVzdEFkZHIpLnNldEF0dHJpYnV0ZU5vZGVOUyhuZXdBdHRyKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X1dST05HX0RPQ1VNRU5UX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9zZXRBdHRyaWJ1dGVOb2RlTlMwNSI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oc2V0QXR0cmlidXRlTm9kZU5TMDUuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldE5hbWVkSXRlbU5TMDEuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0TmFtZWRJdGVtTlMwMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2OWYwMjMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldE5hbWVkSXRlbU5TMDEuamF2YQpAQCAtMCwwICsxLDExOCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXROYW1lZEl0ZW1OUyhhcmcpIiBtZXRob2QgZm9yIGEgCisgKiAgICBOYW1lZE5vZGVNYXAgc2hvdWxkIHJhaXNlIElOVVNFX0FUVFJJQlVURV9FUlIgRE9NRXhjZXB0aW9uIGlmIAorICogICAgYXJnIGlzIGFuIEF0dHIgdGhhdCBpcyBhbHJlYWR5IGFuIGF0dHJpYnV0ZSBvZiBhbm90aGVyIEVsZW1lbnQgb2JqZWN0LgorICogICAgCisgKiAgICBSZXRyaWV2ZSBhbiBhdHRyIG5vZGUgZnJvbSB0aGUgdGhpcmQgImFkZHJlc3MiIGVsZW1lbnQgd2hvc2UgbG9jYWwgbmFtZQorICogICAgaXMgImRvbWVzdGljIiBhbmQgbmFtZXNwYWNlVVJJIGlzICJodHRwOi8vd3d3Lm5ldHplcm8uY29tIi4KKyAqICAgIEludm9rZSBtZXRob2Qgc2V0TmFtZWRJdGVtTlMoYXJnKSBvbiB0aGUgbWFwIG9mIHRoZSBmaXJzdCAiYWRkcmVzcyIgZWxlbWVudCB3aXRoCisgKiAgICBhcmcgYmVpbmcgdGhlIGF0dHIgbm9kZSBmcm9tIGFib3ZlLiAgTWV0aG9kIHNob3VsZCByYWlzZQorICogICAgSU5VU0VfQVRUUklCVVRFX0VSUiBET01FeGNlcHRpb24uCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVVNFX0FUVFJJQlVURV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKTwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtc2V0TmFtZWRJdGVtTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1zZXROYW1lZEl0ZW1OUzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELXNldE5hbWVkSXRlbU5TJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1zZXROYW1lZEl0ZW1OUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVVNFX0FUVFJJQlVURV9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIHNldE5hbWVkSXRlbU5TMDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHNldE5hbWVkSXRlbU5TMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworCisgICAgICBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSBzZXR0aW5ncyA9IAorICAgICAgICAgIG5ldyBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmdbXSB7CitvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmcubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgfTsKKyAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgdGVzdEZhY3RvcnkgPSBmYWN0b3J5Lm5ld0luc3RhbmNlKHNldHRpbmdzKTsKKyAgICAgICAgc2V0RmFjdG9yeSh0ZXN0RmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBhbm90aGVyRWxlbWVudDsKKyAgICAgIE5hbWVkTm9kZU1hcCBhbm90aGVyTWFwOworICAgICAgTm9kZSBhcmc7CisgICAgICBOb2RlIHRlc3RBZGRyZXNzOworICAgICAgTmFtZWROb2RlTWFwIG1hcDsKKyAgICAgIE5vZGUgc2V0Tm9kZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIGFub3RoZXJFbGVtZW50ID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIGFub3RoZXJNYXAgPSBhbm90aGVyRWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICBhcmcgPSBhbm90aGVyTWFwLmdldE5hbWVkSXRlbU5TKCJodHRwOi8vd3d3Lm5ldHplcm8uY29tIiwgImRvbWVzdGljIik7CisgICAgICB0ZXN0QWRkcmVzcyA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICBtYXAgPSB0ZXN0QWRkcmVzcy5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldE5vZGUgPSBtYXAuc2V0TmFtZWRJdGVtTlMoYXJnKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5VU0VfQVRUUklCVVRFX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTlVTRV9BVFRSSUJVVEVfRVJSIiwgc3VjY2Vzcyk7CisgICAgICB9Cit9CisgICAvKioKKyAgICAqICBHZXRzIFVSSSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlc3QuCisgICAgKiAgQHJldHVybiB1cmkgaWRlbnRpZmllciBvZiB0ZXN0CisgICAgKi8KKyAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0VVJJKCkgeworICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL2xldmVsMi9jb3JlL3NldE5hbWVkSXRlbU5TMDEiOworICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoaXMgdGVzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGxpbmUgYXJndW1lbnRzCisgICAgKi8KKyAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgRE9NVGVzdENhc2UuZG9NYWluKHNldE5hbWVkSXRlbU5TMDEuY2xhc3MsIGFyZ3MpOworICAgfQorfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldE5hbWVkSXRlbU5TMDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0TmFtZWRJdGVtTlMwMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFjMmI0YTMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldE5hbWVkSXRlbU5TMDIuamF2YQpAQCAtMCwwICsxLDExNCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJzZXROYW1lZEl0ZW1OUyhhcmcpIiBtZXRob2QgZm9yIGEgCisgKiAgICBOYW1lZE5vZGVNYXAgc2hvdWxkIHJhaXNlIFdST05HX0RPQ1VNRU5UX0VSUiBET01FeGNlcHRpb24gaWYgYXJnIHdhcworICogICAgY3JlYXRlZCBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyBtYXAuCisgKiAgICAKKyAqICAgIENyZWF0ZSBhbiBhdHRyIG5vZGUgaW4gYSBkaWZmZXJlbnQgZG9jdW1lbnQgd2l0aCBxdWFsaWZpZWROYW1lIGVxdWFscworICogICAgImRtc3RjOmRvbWVzdGljIiBhbmQgbmFtZXNwYWNlVVJJIGlzICJodHRwOi8vd3d3LnVzYS5jb20iLgorICogICAgQWNjZXNzIHRoZSBuYW1lZG5vZGVtYXAgb2YgdGhlIGZpcnN0ICJhZGRyZXNzIiBlbGVtZW50IGluIHRoaXMgZG9jdW1lbnQuCisgKiAgICBJbnZva2UgbWV0aG9kIHNldE5hbWVkSXRlbU5TKGFyZykgd2l0aCBhcmcgYmVpbmcgdGhlIGF0dHIgbm9kZSBmcm9tIGFib3ZlLgorICogICAgTWV0aG9kIHNob3VsZCByYWlzZSBXUk9OR19ET0NVTUVOVF9FUlIgRE9NRXhjZXB0aW9uLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdXUk9OR19ET0NVTUVOVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nV1JPTkdfRE9DVU1FTlRfRVJSJ10pPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1zZXROYW1lZEl0ZW1OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXNldE5hbWVkSXRlbU5TPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtc2V0TmFtZWRJdGVtTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdXUk9OR19ET0NVTUVOVF9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtc2V0TmFtZWRJdGVtTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdXUk9OR19ET0NVTUVOVF9FUlInXSk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIHNldE5hbWVkSXRlbU5TMDIgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHNldE5hbWVkSXRlbU5TMDIoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LnVzYS5jb20iOworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiZG1zdGM6ZG9tZXN0aWMiOworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnQgYW5vdGhlckRvYzsKKyAgICAgIE5vZGUgYXJnOworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIHRlc3RBZGRyZXNzOworICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICBOb2RlIHNldE5vZGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGFub3RoZXJEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGFyZyA9IGFub3RoZXJEb2MuY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgIGFyZy5zZXROb2RlVmFsdWUoIk1heWJlIik7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEFkZHJlc3MgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXR0cmlidXRlcyA9IHRlc3RBZGRyZXNzLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIAorICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgc2V0Tm9kZSA9IGF0dHJpYnV0ZXMuc2V0TmFtZWRJdGVtTlMoYXJnKTsKKyAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSKTsKKyAgICAgICAgIH0KKyAgICAgICAgIGFzc2VydFRydWUoInRocm93X1dST05HX0RPQ1VNRU5UX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9zZXROYW1lZEl0ZW1OUzAyIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihzZXROYW1lZEl0ZW1OUzAyLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zZXROYW1lZEl0ZW1OUzAzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3NldE5hbWVkSXRlbU5TMDMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNzAwMmQyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zZXROYW1lZEl0ZW1OUzAzLmphdmEKQEAgLTAsMCArMSwxMDUgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICAgIFRoZSAic2V0TmFtZWRJdGVtTlMoYXJnKSIgbWV0aG9kIGZvciBhIAorICogICAgTmFtZWROb2RlTWFwIHNob3VsZCBhZGQgYSBub2RlIHVzaW5nIGl0cyBuYW1lc3BhY2VVUkkgYW5kIGxvY2FsTmFtZSBnaXZlbiB0aGF0CisgKiAgICB0aGVyZSBpcyBubyBleGlzdGluZyBub2RlIHdpdGggdGhlIHNhbWUgbmFtZXNwYWNlVVJJIGFuZCBsb2NhbE5hbWUgaW4gdGhlIG1hcC4KKyAqICAgIAorICogICAgQ3JlYXRlIGFuIGF0dHIgbm9kZSB3aXRoIG5hbWVzcGFjZVVSSSAiaHR0cDovL3d3dy5uaXN0LmdvdiIscXVhbGlmaWVkTmFtZQorICogICAgInByZWZpeDpuZXdBdHRyIiBhbmQgdmFsdWUgIm5ld1ZhbHVlIi4KKyAqICAgIEludm9rZSBtZXRob2Qgc2V0TmFtZWRJdGVtTlMoYXJnKSBvbiB0aGUgbWFwIG9mIHRoZSBmaXJzdCAiYWRkcmVzcyIKKyAqICAgIGVsZW1lbnQgd2hlcmUgYXJnIGlzIGlkZW50aWZpZWQgYnkgdGhlIG5hbWVzcGFjZVVSSSBhbmQgcXVhbGlmaWVkTmFtZQorICogICAgZnJvbSBhYm92ZS4gIE1ldGhvZCBzaG91bGQgcmV0dXJuIHRoZSBuZXdseSBhZGRlZCBhdHRyIG5vZGUuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRjY4RDA4MCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUY2OEQwODA8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIHNldE5hbWVkSXRlbU5TMDMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHNldE5hbWVkSXRlbU5TMDMoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCB0cnVlKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5uaXN0LmdvdiI7CisgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJwcmVmaXg6bmV3QXR0ciI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlIGFyZzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSB0ZXN0QWRkcmVzczsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgTm9kZSByZXRub2RlOworICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgTm9kZSBzZXROb2RlOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgdHJ1ZSk7CisgICAgICBhcmcgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgIGFyZy5zZXROb2RlVmFsdWUoIm5ld1ZhbHVlIik7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgdGVzdEFkZHJlc3MgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgYXR0cmlidXRlcyA9IHRlc3RBZGRyZXNzLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIHNldE5vZGUgPSBhdHRyaWJ1dGVzLnNldE5hbWVkSXRlbU5TKGFyZyk7CisgICAgICByZXRub2RlID0gYXR0cmlidXRlcy5nZXROYW1lZEl0ZW1OUyhuYW1lc3BhY2VVUkksICJuZXdBdHRyIik7CisgICAgICB2YWx1ZSA9IHJldG5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInRocm93X0VxdWFscyIsICJuZXdWYWx1ZSIsIHZhbHVlKTsKKyAgICAgIH0KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvc2V0TmFtZWRJdGVtTlMwMyI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oc2V0TmFtZWRJdGVtTlMwMy5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0TmFtZWRJdGVtTlMwNC5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zZXROYW1lZEl0ZW1OUzA0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjJjZmZkZgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0TmFtZWRJdGVtTlMwNC5qYXZhCkBAIC0wLDAgKzEsMTMyIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbCAKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSAKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgCitQVVJQT1NFLiAgCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuY29yZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLio7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworCisKKy8qKgorICogICBUaGUgInNldE5hbWVkSXRlbU5TKGFyZykiIG1ldGhvZCBmb3IgYSAKKyAqICAgTmFtZWROb2RlTWFwIHNob3VsZCByYWlzZSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgRE9NRXhjZXB0aW9uIGlmIAorICogICB0aGlzIG1hcCBpcyByZWFkb25seS4KKyAqICAgCisgKiAgIFJldHJpZXZlIGEgbGlzdCBvZiAiZ2VuZGVyIiBlbGVtZW50cy4gR2V0IGFjY2VzcyB0byB0aGUgVEhJUkQgZWxlbWVudAorICogICB3aGljaCBjb250YWlucyBhbiBFTlRJVFlfUkVGRVJFTkNFIGNoaWxkIG5vZGUuICBHZXQgYWNjZXNzIHRvIHRoZSBub2RlJ3MKKyAqICAgbWFwLiBUcnkgdG8gYWRkIGFuIGF0dHJpYnV0ZSBub2RlIHNwZWNpZmllZCBieSBhcmcgd2l0aCAKKyAqICAgbWV0aG9kIHNldE5hbWVkSXRlbU5TKGFyZykuICBUaGlzIHNob3VsZCByZXN1bHQgaW4gTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSCisgKiAgIERPTUV4Y2VwdGlvbi4gCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXNldE5hbWVkSXRlbU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtc2V0TmFtZWRJdGVtTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1zZXROYW1lZEl0ZW1OUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1zZXROYW1lZEl0ZW1OUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgc2V0TmFtZWRJdGVtTlMwNCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgc2V0TmFtZWRJdGVtTlMwNChmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisKKyAgICAgIG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHNldHRpbmdzID0gCisgICAgICAgICAgbmV3IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKK29yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5uYW1lc3BhY2VBd2FyZQorICAgICAgICB9OworICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0ZXN0RmFjdG9yeSA9IGZhY3RvcnkubmV3SW5zdGFuY2Uoc2V0dGluZ3MpOworICAgICAgICBzZXRGYWN0b3J5KHRlc3RGYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyI7CisgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gImxvY2FsMSI7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEFkZHJlc3M7CisgICAgICBOb2RlTGlzdCBuTGlzdDsKKyAgICAgIE5vZGUgY2hpbGQ7CisgICAgICBOb2RlTGlzdCBuMkxpc3Q7CisgICAgICBOb2RlIGNoaWxkMjsKKyAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgTm9kZSBhcmc7CisgICAgICBOb2RlIHNldE5vZGU7CisgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCB0cnVlKTsKKyAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJnZW5kZXIiKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIG5MaXN0ID0gdGVzdEFkZHJlc3MuZ2V0Q2hpbGROb2RlcygpOworICAgICAgY2hpbGQgPSBuTGlzdC5pdGVtKDApOworICAgICAgbm9kZVR5cGUgPSAoaW50KSBjaGlsZC5nZXROb2RlVHlwZSgpOworICAgICAgCisgICAgICBpZiAoZXF1YWxzKDEsIG5vZGVUeXBlKSkgeworICAgICAgICAgIGNoaWxkID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBjaGlsZCk7CisgICAgICB9CisgICAgbjJMaXN0ID0gY2hpbGQuZ2V0Q2hpbGROb2RlcygpOworICAgICAgY2hpbGQyID0gbjJMaXN0Lml0ZW0oMCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJub3RudWxsIiwgY2hpbGQyKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSBjaGlsZDIuZ2V0QXR0cmlidXRlcygpOworICAgICAgYXJnID0gYXR0cmlidXRlcy5nZXROYW1lZEl0ZW1OUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7CisgICAgICAKKyAgICAgIHsKKyAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldE5vZGUgPSBhdHRyaWJ1dGVzLnNldE5hbWVkSXRlbU5TKGFyZyk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICB9CisgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgIH0KK30KKyAgIC8qKgorICAgICogIEdldHMgVVJJIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVzdC4KKyAgICAqICBAcmV0dXJuIHVyaSBpZGVudGlmaWVyIG9mIHRlc3QKKyAgICAqLworICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRVUkkoKSB7CisgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvbGV2ZWwyL2NvcmUvc2V0TmFtZWRJdGVtTlMwNCI7CisgICB9CisgICAvKioKKyAgICAqIFJ1bnMgdGhpcyB0ZXN0IGZyb20gdGhlIGNvbW1hbmQgbGluZS4KKyAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICAqLworICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgeworICAgICAgICBET01UZXN0Q2FzZS5kb01haW4oc2V0TmFtZWRJdGVtTlMwNC5jbGFzcywgYXJncyk7CisgICB9Cit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0TmFtZWRJdGVtTlMwNS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zZXROYW1lZEl0ZW1OUzA1LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTA5ZGFkNgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2NvcmUvc2V0TmFtZWRJdGVtTlMwNS5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwgCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAorUFVSUE9TRS4gIAorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmNvcmU7CisKK2ltcG9ydCBvcmcudzNjLmRvbS4qOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKKworCisvKioKKyAqICAgICBUaGUgInNldE5hbWVkSXRlbU5TKGFyZykiIG1ldGhvZCBmb3IgYSAKKyAqICAgIE5hbWVkTm9kZU1hcCBzaG91bGQgcmVwbGFjZSBhbiBleGlzdGluZyBub2RlIG4xIGZvdW5kIGluIHRoZSBtYXAgd2l0aCBhcmcgaWYgbjEKKyAqICAgIGhhcyB0aGUgc2FtZSBuYW1lc3BhY2VVUkkgYW5kIGxvY2FsTmFtZSBhcyBhcmcgYW5kIHJldHVybiBuMS4KKyAqICAgIAorICogICAgQ3JlYXRlIGFuIGF0dHJpYnV0ZSBub2RlIGluIHdpdGggbmFtZXNwYWNlVVJJICJodHRwOi8vd3d3LnVzYS5jb20iCisgKiAgICBhbmQgcXVhbGlmaWVkTmFtZSAiZG1zdGM6ZG9tZXN0aWMiIHdob3NlIHZhbHVlIGlzICJuZXdWYWwiLgorICogICAgSW52b2tlIG1ldGhvZCBzZXROYW1lZEl0ZW1OUyhhcmcpIG9uIHRoZSBtYXAgb2YgdGhlIGZpcnN0ICJhZGRyZXNzIgorICogICAgZWxlbWVudC4gTWV0aG9kIHNob3VsZCByZXR1cm4gdGhlIG9sZCBhdHRyaWJ1dGUgbm9kZSBpZGVudGlmaWVkCisgKiAgICBieSBuYW1lc3BhY2VVUkkgYW5kIHF1YWxpZmllZE5hbWUgZnJvbSBhYm92ZSx3aG9zZSB2YWx1ZSBpcyAiWWVzIi4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFNldEF0Tm9kZU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdE5vZGVOUzwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3Mgc2V0TmFtZWRJdGVtTlMwNSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgLyoqCisgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAqIEBwYXJhbSBmYWN0b3J5IGRvY3VtZW50IGZhY3RvcnksIG1heSBub3QgYmUgbnVsbAorICAgICogQHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24gVGhyb3duIGlmIHRlc3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBwYXJzZXIgY29uZmlndXJhdGlvbgorICAgICovCisgICBwdWJsaWMgc2V0TmFtZWRJdGVtTlMwNShmaW5hbCBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgdGhyb3dzIG9yZy53M2MuZG9tdHMuRE9NVGVzdEluY29tcGF0aWJsZUV4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmYWN0b3J5KTsKKworICAgIC8vCisgICAgLy8gICBjaGVjayBpZiBsb2FkZWQgZG9jdW1lbnRzIGFyZSBzdXBwb3J0ZWQgZm9yIGNvbnRlbnQgdHlwZQorICAgIC8vCisgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoKTsKKyAgICBwcmVsb2FkKGNvbnRlbnRUeXBlLCAic3RhZmZOUyIsIHRydWUpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LnVzYS5jb20iOworICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiZG1zdGM6ZG9tZXN0aWMiOworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgTm9kZSBhcmc7CisgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgIE5vZGUgdGVzdEFkZHJlc3M7CisgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgIE5vZGUgcmV0bm9kZTsKKyAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIHRydWUpOworICAgICAgYXJnID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICBhcmcuc2V0Tm9kZVZhbHVlKCJuZXdWYWx1ZSIpOworICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0QWRkcmVzcy5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICByZXRub2RlID0gYXR0cmlidXRlcy5zZXROYW1lZEl0ZW1OUyhhcmcpOworICAgICAgdmFsdWUgPSByZXRub2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJ0aHJvd19FcXVhbHMiLCAiWWVzIiwgdmFsdWUpOworICAgICAgfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9zZXROYW1lZEl0ZW1OUzA1IjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihzZXROYW1lZEl0ZW1OUzA1LmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zeXN0ZW1JZDAxLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9jb3JlL3N5c3RlbUlkMDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOTY5MDRiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvY29yZS9zeXN0ZW1JZDAxLmphdmEKQEAgLTAsMCArMSw5MCBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIAoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiAKK1BVUlBPU0UuICAKKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlOworCitpbXBvcnQgb3JnLnczYy5kb20uKjsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0Q2FzZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCisKKworLyoqCisgKiAgICAgVGhlICJnZXRTeXN0ZW1JZCgpIiBtZXRob2Qgb2YgYSBkb2N1bWVudHR5cGUgbm9kZSBjb250YWlucworICogICAgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgZXh0ZXJuYWwgc3Vic2V0LgorICogICAgCisgKiAgICBSZXRyaWV2ZSB0aGUgZG9jdW1lbnR0eXBlLgorICogICAgQXBwbHkgdGhlICJnZXRTeXN0ZW1JZCgpIiBtZXRob2QuICBUaGUgc3RyaW5nICJzdGFmZk5TLmR0ZCIgc2hvdWxkIGJlCisgKiAgICByZXR1cm5lZC4KKyogQGF1dGhvciBOSVNUCisqIEBhdXRob3IgTWFyeSBCcmFkeQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Db3JlLURvY1R5cGUtc3lzdGVtSWQiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Db3JlLURvY1R5cGUtc3lzdGVtSWQ8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIHN5c3RlbUlkMDEgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgIC8qKgorICAgICogQ29uc3RydWN0b3IuCisgICAgKiBAcGFyYW0gZmFjdG9yeSBkb2N1bWVudCBmYWN0b3J5LCBtYXkgbm90IGJlIG51bGwKKyAgICAqIEB0aHJvd3Mgb3JnLnczYy5kb210cy5ET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uIFRocm93biBpZiB0ZXN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggcGFyc2VyIGNvbmZpZ3VyYXRpb24KKyAgICAqLworICAgcHVibGljIHN5c3RlbUlkMDEoZmluYWwgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgIHRocm93cyBvcmcudzNjLmRvbXRzLkRPTVRlc3RJbmNvbXBhdGlibGVFeGNlcHRpb24geworICAgICAgc3VwZXIoZmFjdG9yeSk7CisKKyAgICAvLworICAgIC8vICAgY2hlY2sgaWYgbG9hZGVkIGRvY3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBjb250ZW50IHR5cGUKKyAgICAvLworICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKCk7CisgICAgcHJlbG9hZChjb250ZW50VHlwZSwgInN0YWZmTlMiLCBmYWxzZSk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgIFN0cmluZyBzeXN0ZW1JZDsKKyAgICAgIGludCBpbmRleDsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGZhbHNlKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgc3lzdGVtSWQgPSBkb2NUeXBlLmdldFN5c3RlbUlkKCk7CisgICAgICBhc3NlcnRVUklFcXVhbHMoInN5c3RlbUlkIiwgbnVsbCwgbnVsbCwgbnVsbCwgInN0YWZmTlMuZHRkIiwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgc3lzdGVtSWQpOworfQorICAgLyoqCisgICAgKiAgR2V0cyBVUkkgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZXN0LgorICAgICogIEByZXR1cm4gdXJpIGlkZW50aWZpZXIgb2YgdGVzdAorICAgICovCisgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldFVSSSgpIHsKKyAgICAgIHJldHVybiAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9sZXZlbDIvY29yZS9zeXN0ZW1JZDAxIjsKKyAgIH0KKyAgIC8qKgorICAgICogUnVucyB0aGlzIHRlc3QgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICovCisgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIERPTVRlc3RDYXNlLmRvTWFpbihzeXN0ZW1JZDAxLmNsYXNzLCBhcmdzKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvZXZlbnRzL1Rlc3RCYXRpay5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvZXZlbnRzL1Rlc3RCYXRpay5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA0NDkxMWQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9ldmVudHMvVGVzdEJhdGlrLmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5ldmVudHM7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkJhdGlrVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmc7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKK3B1YmxpYyBjbGFzcyBUZXN0QmF0aWsgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisgIHB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbgorICB7CisgICAgQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy53M2MuZG9tdHMubGV2ZWwyLmV2ZW50cy5hbGx0ZXN0cyIpOworICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9IHRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBCYXRpa1Rlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5KG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nWzBdKTsKKworICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgfQorCisKK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvZXZlbnRzL1Rlc3REZWZhdWx0TFMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2V2ZW50cy9UZXN0RGVmYXVsdExTLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjdmYWFjZAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2V2ZW50cy9UZXN0RGVmYXVsdExTLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZQorICogb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgorICogQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcworICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzCisgKiBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQorICogV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUworICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UKKyAqIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5ldmVudHM7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5MU0RvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKKy8qKgorICogVGVzdCBzdWl0ZSB0aGF0IHJ1bnMgYWxsIERPTSBMMiBFdmVudHMgdGVzdHMgdXNpbmcgdGhlCisgKiBEZWZhdWx0IExTIHBhcnNlciBpbiBkZWZhdWx0IGNvbmZpZ3VyYXRpb24uCisgKiAKKyAqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyAqIAorICovCitwdWJsaWMgY2xhc3MgVGVzdERlZmF1bHRMUyBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKwlwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworCQlDbGFzcyB0ZXN0Q2xhc3MgPQorCQkJQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoCisJCQkJIm9yZy53M2MuZG9tdHMubGV2ZWwyLmV2ZW50cy5hbGx0ZXN0cyIpOworCQlDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPQorCQkJdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKAorCQkJCW5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKwkJRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisJCQluZXcgTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KAorCQkJCUpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworCQlPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvZXZlbnRzL1Rlc3REZWZhdWx0TFNBbHRDb25maWcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2V2ZW50cy9UZXN0RGVmYXVsdExTQWx0Q29uZmlnLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjY5NzZhZgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2V2ZW50cy9UZXN0RGVmYXVsdExTQWx0Q29uZmlnLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZQorICogb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgorICogQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcworICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzCisgKiBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQorICogV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUworICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UKKyAqIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5ldmVudHM7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5MU0RvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKKy8qKgorICogVGVzdCBzdWl0ZSB0aGF0IHJ1bnMgYWxsIERPTSBMMiBFdmVudHMgdGVzdHMgdXNpbmcgdGhlCisgKiBEZWZhdWx0IExTIHBhcnNlciBpbiBhbiBhbHRlcm5hdGUgY29uZmlndXJhdGlvbgorICogCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3REZWZhdWx0TFNBbHRDb25maWcgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisJcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwkJQ2xhc3MgdGVzdENsYXNzID0KKwkJCUNsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKAorCQkJCSJvcmcudzNjLmRvbXRzLmxldmVsMi5ldmVudHMuYWxsdGVzdHMiKTsKKwkJQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0KKwkJCXRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcigKKwkJCQluZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisJCURPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorCQkJbmV3IExTRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKwkJCQlKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisKKwkJT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworCQlyZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKwl9CisKK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2V2ZW50cy9UZXN0RGVmYXVsdFBhcnNlci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvZXZlbnRzL1Rlc3REZWZhdWx0UGFyc2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmE1MWQyMwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2V2ZW50cy9UZXN0RGVmYXVsdFBhcnNlci5qYXZhCkBAIC0wLDAgKzEsNDMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuZXZlbnRzOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworcHVibGljIGNsYXNzIFRlc3REZWZhdWx0UGFyc2VyIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMi5ldmVudHMuYWxsdGVzdHMiKTsKKyAgICBDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPSB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorICAgICAgICBuZXcgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5KG51bGwsCisgICAgICAgICAgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24xKCkpOworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9ldmVudHMvVGVzdERlZmF1bHRQYXJzZXJBbHRDb25maWcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2V2ZW50cy9UZXN0RGVmYXVsdFBhcnNlckFsdENvbmZpZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1NmRhZTQKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9ldmVudHMvVGVzdERlZmF1bHRQYXJzZXJBbHRDb25maWcuamF2YQpAQCAtMCwwICsxLDQzIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwyLmV2ZW50czsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKK3B1YmxpYyBjbGFzcyBUZXN0RGVmYXVsdFBhcnNlckFsdENvbmZpZyBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKyAgcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uCisgIHsKKyAgICBDbGFzcyB0ZXN0Q2xhc3MgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLnczYy5kb210cy5sZXZlbDIuZXZlbnRzLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKyAgICAgICAgbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeShudWxsLAorICAgICAgICAgIEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMigpKTsKKworICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgfQorCisKK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvZXZlbnRzL1Rlc3RPcmFjbGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2V2ZW50cy9UZXN0T3JhY2xlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWRjMGE0ZgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2V2ZW50cy9UZXN0T3JhY2xlLmphdmEKQEAgLTAsMCArMSw2MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZgorICogVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgorICogQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcworICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzCisgKiBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQorICogV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUworICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UKKyAqIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5ldmVudHM7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiBUZXN0IHN1aXRlIHRoYXQgcnVucyBhbGwgRE9NIEwyIEV2ZW50cyB0ZXN0cyB1c2luZyB0aGUKKyAqIE9yYWNsZSBQYXJzZXIgZm9yIEphdmEgaW4gZGVmYXVsdCBjb25maWd1cmF0aW9uLgorICoKKyAqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0T3JhY2xlIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0b3IKKyAgICAgICAgICogQHJldHVybiB0ZXN0IHN1aXRlCisgICAgICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgIENsYXNzIHRlc3RDbGFzcyA9CisgICAgICAgICAgICAgICAgICAgICAgICBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy53M2MuZG9tdHMubGV2ZWwyLmV2ZW50cy5hbGx0ZXN0cyIpOworICAgICAgICAgICAgICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9CisgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IG9yYWNsZUZhY3RvcnkgPQorICAgICAgICAgICAgICAgICAgICAgICAgKERvY3VtZW50QnVpbGRlckZhY3RvcnkpIENsYXNzTG9hZGVyCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5sb2FkQ2xhc3MoIm9yYWNsZS54bWwuamF4cC5KWERvY3VtZW50QnVpbGRlckZhY3RvcnkiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubmV3SW5zdGFuY2UoKTsKKworICAgICAgICAgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JhY2xlRmFjdG9yeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24xKCkpOworCisgICAgICAgICAgICAgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICAgICAgICB9CisKK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2V2ZW50cy9UZXN0T3JhY2xlQWx0Q29uZmlnLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9ldmVudHMvVGVzdE9yYWNsZUFsdENvbmZpZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJhNmMyZjMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9ldmVudHMvVGVzdE9yYWNsZUFsdENvbmZpZy5qYXZhCkBAIC0wLDAgKzEsNjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YKKyAqIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4KKyAqIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZSBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcworICogcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKKyAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKKyAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlCisgKiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuZXZlbnRzOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKKy8qKgorICogVGVzdCBzdWl0ZSB0aGF0IHJ1bnMgYWxsIERPTSBMMiBFdmVudHMgdGVzdHMgdXNpbmcgdGhlCisgKiBPcmFjbGUgUGFyc2VyIGZvciBKYXZhIGluIGFuIGFsdGVybmF0aXZlIGNvbmZpZ3VyYXRpb24uCisgKgorICogQGF1dGhvciBDdXJ0IEFybm9sZAorICoKKyAqLworcHVibGljIGNsYXNzIFRlc3RPcmFjbGVBbHRDb25maWcgZXh0ZW5kcyBUZXN0U3VpdGUgeworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0b3IKKyAgICAgICAgICogQHJldHVybiB0ZXN0IHN1aXRlCisgICAgICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgIENsYXNzIHRlc3RDbGFzcyA9CisgICAgICAgICAgICAgICAgICAgICAgICBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy53M2MuZG9tdHMubGV2ZWwyLmV2ZW50cy5hbGx0ZXN0cyIpOworICAgICAgICAgICAgICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9CisgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IG9yYWNsZUZhY3RvcnkgPQorICAgICAgICAgICAgICAgICAgICAgICAgKERvY3VtZW50QnVpbGRlckZhY3RvcnkpIENsYXNzTG9hZGVyCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5sb2FkQ2xhc3MoIm9yYWNsZS54bWwuamF4cC5KWERvY3VtZW50QnVpbGRlckZhY3RvcnkiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubmV3SW5zdGFuY2UoKTsKKworICAgICAgICAgICAgICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JhY2xlRmFjdG9yeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24yKCkpOworCisgICAgICAgICAgICAgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICAgICAgICB9CisKK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2V2ZW50cy9UZXN0WGVyY2VzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9ldmVudHMvVGVzdFhlcmNlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjY2VkNzEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9ldmVudHMvVGVzdFhlcmNlcy5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuZXZlbnRzOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKK3B1YmxpYyBjbGFzcyBUZXN0WGVyY2VzIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMi5ldmVudHMuYWxsdGVzdHMiKTsKKyAgICBDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPSB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgeGVyY2VzRmFjdG9yeSA9IChEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KQorICAgICAgQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy5hcGFjaGUueGVyY2VzLmpheHAuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeUltcGwiKS5uZXdJbnN0YW5jZSgpOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkoeGVyY2VzRmFjdG9yeSwKKyAgICAgICAgICBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisKKworICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgfQorCisKK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvZXZlbnRzL1Rlc3RYZXJjZXNBbHRDb25maWcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2V2ZW50cy9UZXN0WGVyY2VzQWx0Q29uZmlnLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjA3OWM2ZgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2V2ZW50cy9UZXN0WGVyY2VzQWx0Q29uZmlnLmphdmEKQEAgLTAsMCArMSw0OCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5ldmVudHM7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworcHVibGljIGNsYXNzIFRlc3RYZXJjZXNBbHRDb25maWcgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisgIHB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbgorICB7CisgICAgQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy53M2MuZG9tdHMubGV2ZWwyLmV2ZW50cy5hbGx0ZXN0cyIpOworICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9IHRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB4ZXJjZXNGYWN0b3J5ID0gKERvY3VtZW50QnVpbGRlckZhY3RvcnkpCisgICAgICBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLmFwYWNoZS54ZXJjZXMuamF4cC5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbCIpLm5ld0luc3RhbmNlKCk7CisKKyAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKyAgICAgICAgbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSh4ZXJjZXNGYWN0b3J5LAorICAgICAgICAgIEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMigpKTsKKworICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgfQorCisKK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvaHRtbC9UZXN0RGVmYXVsdExTLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9odG1sL1Rlc3REZWZhdWx0TFMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNzg3MjZkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvaHRtbC9UZXN0RGVmYXVsdExTLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZQorICogb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgorICogQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcworICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzCisgKiBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQorICogV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUworICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UKKyAqIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5odG1sOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworCisvKioKKyAqIFRlc3Qgc3VpdGUgdGhhdCBydW5zIGFsbCBET00gTDIgSFRNTCB0ZXN0cyB1c2luZyB0aGUKKyAqIERlZmF1bHQgTFMgcGFyc2VyIGluIGRlZmF1bHQgY29uZmlndXJhdGlvbi4KKyAqIAorICogQGF1dGhvciBDdXJ0IEFybm9sZAorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0RGVmYXVsdExTIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworCXB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJCUNsYXNzIHRlc3RDbGFzcyA9CisJCQlDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygKKwkJCQkib3JnLnczYy5kb210cy5sZXZlbDIuaHRtbC5hbGx0ZXN0cyIpOworCQlDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPQorCQkJdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKAorCQkJCW5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKwkJRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisJCQluZXcgTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KAorCQkJCUpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworCQlPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvaHRtbC9UZXN0RGVmYXVsdExTQWx0Q29uZmlnLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMi9odG1sL1Rlc3REZWZhdWx0TFNBbHRDb25maWcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNmY3MGI5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvaHRtbC9UZXN0RGVmYXVsdExTQWx0Q29uZmlnLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZQorICogb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgorICogQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcworICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzCisgKiBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQorICogV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUworICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UKKyAqIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMi5odG1sOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworCisvKioKKyAqIFRlc3Qgc3VpdGUgdGhhdCBydW5zIGFsbCBET00gTDIgSFRNTCB0ZXN0cyB1c2luZyB0aGUKKyAqIERlZmF1bHQgTFMgcGFyc2VyIGluIGFuIGFsdGVybmF0aXZlIGNvbmZpZ3VyYXRpb24uCisgKiAKKyAqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyAqIAorICovCitwdWJsaWMgY2xhc3MgVGVzdERlZmF1bHRMU0FsdENvbmZpZyBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKwlwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworCQlDbGFzcyB0ZXN0Q2xhc3MgPQorCQkJQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoCisJCQkJIm9yZy53M2MuZG9tdHMubGV2ZWwyLmh0bWwuYWxsdGVzdHMiKTsKKwkJQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0KKwkJCXRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcigKKwkJCQluZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisJCURPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorCQkJbmV3IExTRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKwkJCQlKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisKKwkJT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworCQlyZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKwl9CisKK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2h0bWwvVGVzdFhlcmNlc0hUTUwuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwyL2h0bWwvVGVzdFhlcmNlc0hUTUwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MmIyMGY5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDIvaHRtbC9UZXN0WGVyY2VzSFRNTC5qYXZhCkBAIC0wLDAgKzEsNDMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDIuaHRtbDsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CitpbXBvcnQgb3JnLnczYy5kb210cy5YZXJjZXNIVE1MMkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK3B1YmxpYyBjbGFzcyBUZXN0WGVyY2VzSFRNTCBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKyAgcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uCisgIHsKKyAgICBDbGFzcyB0ZXN0Q2xhc3MgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLnczYy5kb210cy5sZXZlbDIuaHRtbC5hbGx0ZXN0cyIpOworICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9IHRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBYZXJjZXNIVE1MMkRvY3VtZW50QnVpbGRlckZhY3RvcnkoCisgICAgICAgICAgWGVyY2VzSFRNTDJEb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24xKCkpOworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy9jb3JlL1Rlc3RCYXRpay5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvY29yZS9UZXN0QmF0aWsuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMTI1NmJkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvY29yZS9UZXN0QmF0aWsuamF2YQpAQCAtMCwwICsxLDQ1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDMuY29yZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkJhdGlrVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmc7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKKy8qKgorICogCisgKiBSdW5zIHRlc3Qgc3VpdGUgdXNpbmcgQmF0aWsgU1ZHLgorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0QmF0aWsgZXh0ZW5kcyBUZXN0U3VpdGUgeworICAgIC8qKgorICAgICAqIEZhY3RvcnkgbWV0aG9kIGZvciBzdWl0ZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHN1aXRlCisgICAgICogQHRocm93cyBFeGNlcHRpb24gaWYgQmF0aWsgaXMgbm90IGF2YWlsYWJsZSBvciBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkCisgICAgICovCisJcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwkJQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoCisJCQkJIm9yZy53M2MuZG9tdHMubGV2ZWwzLmNvcmUuYWxsdGVzdHMiKTsKKwkJQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzCisJCQkJLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tde0RPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzfSk7CisJCURPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPSBuZXcgQmF0aWtUZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKwkJCQluZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1swXSk7CisJCU9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXXtmYWN0b3J5fSk7CisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL2NvcmUvVGVzdERlZmF1bHRMUy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvY29yZS9UZXN0RGVmYXVsdExTLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjllM2ExNQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL2NvcmUvVGVzdERlZmF1bHRMUy5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUKKyAqIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4KKyAqIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZSBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcworICogcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKKyAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKKyAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlCisgKiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDMuY29yZTsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkxTRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiBUZXN0IHN1aXRlIHRoYXQgcnVucyBhbGwgRE9NIEwzIENvcmUgdGVzdHMgdXNpbmcgdGhlCisgKiBhIHBhcnNlciBwcm92aWRlZCBieSBET00gTDMgQ29yZSBib290c3RyYXBwaW5nLgorICogCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3REZWZhdWx0TFMgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGluc3RhbmNlIG9mIHRlc3Qgc3VpdGUuCisgICAgICogCisgICAgICogQHJldHVybiB0ZXN0IHN1aXRlCisgICAgICogQHRocm93cyBFeGNlcHRpb24gaWYgdGVzdHMgb3IgaW1wbGVtZW50YXRpb24gY291bGQgbm90IGJlIGxvYWRlZAorICAgICAqLworCXB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJCUNsYXNzIHRlc3RDbGFzcyA9CisJCQlDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygKKwkJCQkib3JnLnczYy5kb210cy5sZXZlbDMuY29yZS5hbGx0ZXN0cyIpOworCQlDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPQorCQkJdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKAorCQkJCW5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKwkJRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisJCQluZXcgTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KAorCQkJCUpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworCQlPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvY29yZS9UZXN0RGVmYXVsdExTQWx0Q29uZmlnLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy9jb3JlL1Rlc3REZWZhdWx0TFNBbHRDb25maWcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xY2U0ZDc0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvY29yZS9UZXN0RGVmYXVsdExTQWx0Q29uZmlnLmphdmEKQEAgLTAsMCArMSw1NyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZQorICogb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgorICogQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcworICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzCisgKiBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQorICogV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUworICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UKKyAqIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMy5jb3JlOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworCisvKioKKyAqIFRlc3Qgc3VpdGUgdGhhdCBydW5zIGFsbCBET00gTDMgQ29yZSB0ZXN0cyB1c2luZyBhCisgKiBwYXJzZXIgcHJvdmlkZWQgYnkgRE9NIEwzIENvcmUgYm9vdHN0cmFwcGluZworICogaW4gYWx0ZXJuYXRpdmUgY29uZmlndXJhdGlvbgorICogCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3REZWZhdWx0TFNBbHRDb25maWcgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSB0ZXN0IHN1aXRlCisgICAgICogQHJldHVybiB0ZXN0IHN1aXRlCisgICAgICogQHRocm93cyBFeGNlcHRpb24gaWYgdGVzdHMgb3IgaW1wbGVtZW50YXRpb24gbm90IGxvYWRlZAorICAgICAqLworCXB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJCUNsYXNzIHRlc3RDbGFzcyA9CisJCQlDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygKKwkJCQkib3JnLnczYy5kb210cy5sZXZlbDMuY29yZS5hbGx0ZXN0cyIpOworCQlDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPQorCQkJdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKAorCQkJCW5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKwkJRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisJCQluZXcgTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KAorCQkJCUpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMigpKTsKKworCQlPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvY29yZS9UZXN0RGVmYXVsdFBhcnNlci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvY29yZS9UZXN0RGVmYXVsdFBhcnNlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU0MWExM2EKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy9jb3JlL1Rlc3REZWZhdWx0UGFyc2VyLmphdmEKQEAgLTAsMCArMSw1MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMy5jb3JlOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiBUZXN0IHN1aXRlIHVzaW5nIHRoZSBkZWZhdWx0IEpBWFAgcGFyc2VyIGluIHRoZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24KKyAqIAorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0RGVmYXVsdFBhcnNlciBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKyAgLyoqCisgICAgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIHRlc3Qgc3VpdGUKKyAgICAqIEByZXR1cm4gbmV3IHRlc3Qgc3VpdGUKKyAgICAqIEBleGNlcHRpb24gRXhjZXB0aW9uIGlmIHRlc3RzIG9yIGltcGxlbWVudGF0aW9uIGNhbiBiZSBjcmVhdGVkLiAKKyAgICAqLworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMy5jb3JlLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKyAgICAgICAgbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeShudWxsLAorICAgICAgICAgIEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgfQorCisKK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvY29yZS9UZXN0RGVmYXVsdFBhcnNlckFsdENvbmZpZy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvY29yZS9UZXN0RGVmYXVsdFBhcnNlckFsdENvbmZpZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdjZjAyNDEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy9jb3JlL1Rlc3REZWZhdWx0UGFyc2VyQWx0Q29uZmlnLmphdmEKQEAgLTAsMCArMSw1NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMy5jb3JlOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworCisKKy8qKgorICogVGVzdCBzdWl0ZSB1c2luZyB0aGUgZGVmYXVsdCBKQVhQIHBhcnNlciBpbiB0aGUgYWx0ZXJuYXRpdmUgY29uZmlndXJhdGlvbgorICogCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3REZWZhdWx0UGFyc2VyQWx0Q29uZmlnIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgdGVzdCBzdWl0ZQorICAgICAqIEByZXR1cm4gbmV3IHRlc3Qgc3VpdGUKKyAgICAgKiBAZXhjZXB0aW9uIEV4Y2VwdGlvbiBpZiB0ZXN0cyBvciBpbXBsZW1lbnRhdGlvbiBjYW4gYmUgY3JlYXRlZC4gCisgICAgICovCisgICAgCisgIHB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbgorICB7CisgICAgQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy53M2MuZG9tdHMubGV2ZWwzLmNvcmUuYWxsdGVzdHMiKTsKKyAgICBDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPSB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorICAgICAgICBuZXcgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5KG51bGwsCisgICAgICAgICAgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24yKCkpOworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy9jb3JlL1Rlc3RPcmFjbGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL2NvcmUvVGVzdE9yYWNsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2OTMyZWUKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy9jb3JlL1Rlc3RPcmFjbGUuamF2YQpAQCAtMCwwICsxLDYzIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mCisgKiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuCisgKiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMKKyAqIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZCisgKiBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTCisgKiBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZQorICogaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwzLmNvcmU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiBUZXN0IHN1aXRlIHRoYXQgcnVucyBhbGwgRE9NIEwzIENvcmUgdGVzdHMgdXNpbmcgdGhlCisgKiBPcmFjbGUgUGFyc2VyIGZvciBKYXZhIGluIGRlZmF1bHQgY29uZmlndXJhdGlvbi4KKyAqIAorICogQGF1dGhvciBDdXJ0IEFybm9sZAorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0T3JhY2xlIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworCS8qKgorCSAqIENvbnN0cnVjdG9yCisJICogQHJldHVybiB0ZXN0IHN1aXRlCisJICogQHRocm93cyBFeGNlcHRpb24KKwkgKi8KKwlwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworCQlDbGFzcyB0ZXN0Q2xhc3MgPQorCQkJQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoCisJCQkJIm9yZy53M2MuZG9tdHMubGV2ZWwzLmNvcmUuYWxsdGVzdHMiKTsKKwkJQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0KKwkJCXRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcigKKwkJCQluZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisJCURvY3VtZW50QnVpbGRlckZhY3Rvcnkgb3JhY2xlRmFjdG9yeSA9CisJCQkoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSkgQ2xhc3NMb2FkZXIKKwkJCQkuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKQorCQkJCS5sb2FkQ2xhc3MoIm9yYWNsZS54bWwuamF4cC5KWERvY3VtZW50QnVpbGRlckZhY3RvcnkiKQorCQkJCS5uZXdJbnN0YW5jZSgpOworCisJCURPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorCQkJbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKwkJCQlvcmFjbGVGYWN0b3J5LAorCQkJCUpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworCQlPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvY29yZS9UZXN0T3JhY2xlQWx0Q29uZmlnLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy9jb3JlL1Rlc3RPcmFjbGVBbHRDb25maWcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MzBhZjQ0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvY29yZS9UZXN0T3JhY2xlQWx0Q29uZmlnLmphdmEKQEAgLTAsMCArMSw2MiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZgorICogVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgorICogQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcworICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzCisgKiBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQorICogV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUworICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UKKyAqIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMy5jb3JlOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKKy8qKgorICogVGVzdCBzdWl0ZSB0aGF0IHJ1bnMgYWxsIERPTSBMMyBDb3JlIHRlc3RzIHVzaW5nIHRoZQorICogT3JhY2xlIFBhcnNlciBmb3IgSmF2YSBpbiBhbiBhbHRlcm5hdGl2ZSBjb25maWd1cmF0aW9uLgorICogCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3RPcmFjbGVBbHRDb25maWcgZXh0ZW5kcyBUZXN0U3VpdGUgeworCS8qKgorCSAqIENvbnN0cnVjdG9yCisJICogQHJldHVybiB0ZXN0IHN1aXRlCisJICogQHRocm93cyBFeGNlcHRpb24KKwkgKi8KKwlwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworCQlDbGFzcyB0ZXN0Q2xhc3MgPQorCQkJQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoCisJCQkJIm9yZy53M2MuZG9tdHMubGV2ZWwzLmNvcmUuYWxsdGVzdHMiKTsKKwkJQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0KKwkJCXRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcigKKwkJCQluZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisJCURvY3VtZW50QnVpbGRlckZhY3Rvcnkgb3JhY2xlRmFjdG9yeSA9CisJCQkoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSkgQ2xhc3NMb2FkZXIKKwkJCQkuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKQorCQkJCS5sb2FkQ2xhc3MoIm9yYWNsZS54bWwuamF4cC5KWERvY3VtZW50QnVpbGRlckZhY3RvcnkiKQorCQkJCS5uZXdJbnN0YW5jZSgpOworCisJCURPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorCQkJbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKwkJCQlvcmFjbGVGYWN0b3J5LAorCQkJCUpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMigpKTsKKworCQlPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvY29yZS9UZXN0WGVyY2VzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy9jb3JlL1Rlc3RYZXJjZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lN2YzYjI3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvY29yZS9UZXN0WGVyY2VzLmphdmEKQEAgLTAsMCArMSw1OCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZQorICogb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgorICogQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcworICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzCisgKiBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQorICogV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUworICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UKKyAqIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMy5jb3JlOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKKy8qKgorICogVGVzdCBzdWl0ZSB0aGF0IHJ1bnMgYWxsIERPTSBMMyBDb3JlIHRlc3RzIHVzaW5nIHRoZQorICogWGVyY2VzLUogaW4gZGVmYXVsdCBjb25maWd1cmF0aW9uLgorICogCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3RYZXJjZXMgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisJcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwkJQ2xhc3MgdGVzdENsYXNzID0KKwkJCUNsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKAorCQkJCSJvcmcudzNjLmRvbXRzLmxldmVsMy5jb3JlLmFsbHRlc3RzIik7CisJCUNvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9CisJCQl0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IoCisJCQkJbmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworCQlEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHhlcmNlc0ZhY3RvcnkgPQorCQkJKERvY3VtZW50QnVpbGRlckZhY3RvcnkpIENsYXNzTG9hZGVyCisJCQkJLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkKKwkJCQkubG9hZENsYXNzKCJvcmcuYXBhY2hlLnhlcmNlcy5qYXhwLkRvY3VtZW50QnVpbGRlckZhY3RvcnlJbXBsIikKKwkJCQkubmV3SW5zdGFuY2UoKTsKKworCQlET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKwkJCW5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkoCisJCQkJeGVyY2VzRmFjdG9yeSwKKwkJCQlKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisKKwkJT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworCQlyZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKwl9CisKK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL2NvcmUvVGVzdFhlcmNlc0FsdENvbmZpZy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvY29yZS9UZXN0WGVyY2VzQWx0Q29uZmlnLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjdkYzJhOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL2NvcmUvVGVzdFhlcmNlc0FsdENvbmZpZy5qYXZhCkBAIC0wLDAgKzEsNTggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUKKyAqIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4KKyAqIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZSBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcworICogcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKKyAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKKyAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlCisgKiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDMuY29yZTsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworCisvKioKKyAqIFRlc3Qgc3VpdGUgdGhhdCBydW5zIGFsbCBET00gTDMgQ29yZSB0ZXN0cyB1c2luZyB0aGUKKyAqIFhlcmNlcy1KIGluIGFuIGFsdGVybmF0aXZlIGNvbmZpZ3VyYXRpb24uCisgKiAKKyAqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyAqIAorICovCitwdWJsaWMgY2xhc3MgVGVzdFhlcmNlc0FsdENvbmZpZyBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKwlwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworCQlDbGFzcyB0ZXN0Q2xhc3MgPQorCQkJQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoCisJCQkJIm9yZy53M2MuZG9tdHMubGV2ZWwzLmNvcmUuYWxsdGVzdHMiKTsKKwkJQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0KKwkJCXRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcigKKwkJCQluZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisJCURvY3VtZW50QnVpbGRlckZhY3RvcnkgeGVyY2VzRmFjdG9yeSA9CisJCQkoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSkgQ2xhc3NMb2FkZXIKKwkJCQkuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKQorCQkJCS5sb2FkQ2xhc3MoIm9yZy5hcGFjaGUueGVyY2VzLmpheHAuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeUltcGwiKQorCQkJCS5uZXdJbnN0YW5jZSgpOworCisJCURPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorCQkJbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKwkJCQl4ZXJjZXNGYWN0b3J5LAorCQkJCUpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMigpKTsKKworCQlPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvbHMvVGVzdEJhdGlrLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy9scy9UZXN0QmF0aWsuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNzZjNjAwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvbHMvVGVzdEJhdGlrLmphdmEKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwzLmxzOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuQmF0aWtUZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZzsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiAKKyAqIFJ1bnMgdGVzdCBzdWl0ZSB1c2luZyBCYXRpayBTVkcuCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3RCYXRpayBleHRlbmRzIFRlc3RTdWl0ZSB7CisgICAgLyoqCisgICAgICogRmFjdG9yeSBtZXRob2QgZm9yIHN1aXRlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gc3VpdGUKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbiBpZiBCYXRpayBpcyBub3QgYXZhaWxhYmxlIG9yIGNvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQKKyAgICAgKi8KKwlwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworCQlDbGFzcyB0ZXN0Q2xhc3MgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygKKwkJCQkib3JnLnczYy5kb210cy5sZXZlbDMubHMuYWxsdGVzdHMiKTsKKwkJQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzCisJCQkJLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tde0RPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzfSk7CisJCURPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPSBuZXcgQmF0aWtUZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKwkJCQluZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1swXSk7CisJCU9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXXtmYWN0b3J5fSk7CisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL2xzL1Rlc3REZWZhdWx0TFMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL2xzL1Rlc3REZWZhdWx0TFMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYTIwZDZjCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvbHMvVGVzdERlZmF1bHRMUy5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUKKyAqIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4KKyAqIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZSBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcworICogcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKKyAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKKyAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlCisgKiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDMubHM7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5MU0RvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKKy8qKgorICogVGVzdCBzdWl0ZSB0aGF0IHJ1bnMgYWxsIERPTSBMMyBDb3JlIHRlc3RzIHVzaW5nIHRoZQorICogYSBwYXJzZXIgcHJvdmlkZWQgYnkgRE9NIEwzIENvcmUgYm9vdHN0cmFwcGluZy4KKyAqIAorICogQGF1dGhvciBDdXJ0IEFybm9sZAorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0RGVmYXVsdExTIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBpbnN0YW5jZSBvZiB0ZXN0IHN1aXRlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gdGVzdCBzdWl0ZQorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uIGlmIHRlc3RzIG9yIGltcGxlbWVudGF0aW9uIGNvdWxkIG5vdCBiZSBsb2FkZWQKKyAgICAgKi8KKwlwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworCQlDbGFzcyB0ZXN0Q2xhc3MgPQorCQkJQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoCisJCQkJIm9yZy53M2MuZG9tdHMubGV2ZWwzLmxzLmFsbHRlc3RzIik7CisJCUNvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9CisJCQl0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IoCisJCQkJbmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworCQlET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKwkJCW5ldyBMU0RvY3VtZW50QnVpbGRlckZhY3RvcnkoCisJCQkJSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24xKCkpOworCisJCU9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKwkJcmV0dXJuIG5ldyBKVW5pdFRlc3RTdWl0ZUFkYXB0ZXIoKERPTVRlc3RTdWl0ZSkgdGVzdCk7CisJfQorCit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy9scy9UZXN0RGVmYXVsdFBhcnNlci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvbHMvVGVzdERlZmF1bHRQYXJzZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYjMxN2QzCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvbHMvVGVzdERlZmF1bHRQYXJzZXIuamF2YQpAQCAtMCwwICsxLDUzIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwzLmxzOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiBUZXN0IHN1aXRlIHVzaW5nIHRoZSBkZWZhdWx0IEpBWFAgcGFyc2VyIGluIHRoZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24KKyAqIAorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0RGVmYXVsdFBhcnNlciBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKyAgLyoqCisgICAgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIHRlc3Qgc3VpdGUKKyAgICAqIEByZXR1cm4gbmV3IHRlc3Qgc3VpdGUKKyAgICAqIEBleGNlcHRpb24gRXhjZXB0aW9uIGlmIHRlc3RzIG9yIGltcGxlbWVudGF0aW9uIGNhbiBiZSBjcmVhdGVkLiAKKyAgICAqLworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMy5scy5hbGx0ZXN0cyIpOworICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9IHRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkobnVsbCwKKyAgICAgICAgICBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisKKyAgICBPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisgICAgcmV0dXJuIG5ldyBKVW5pdFRlc3RTdWl0ZUFkYXB0ZXIoKERPTVRlc3RTdWl0ZSkgdGVzdCk7CisgIH0KKworCit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL2xzL1Rlc3RPcmFjbGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL2xzL1Rlc3RPcmFjbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYzg4MmMwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvbHMvVGVzdE9yYWNsZS5qYXZhCkBAIC0wLDAgKzEsNjYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlCisgKiBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuCisgKiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMKKyAqIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZCisgKiBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTCisgKiBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZQorICogaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwzLmxzOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKKy8qKgorICogQSBKVW5pdCB0ZXN0IHN1aXRlIHRoYXQgd2lsbCBydW4gYWxsIExvYWQgYW5kIFNhdmUgdGVzdHMKKyAqIHVzaW5nIHRoZSBPcmFjbGUgWE1MIFBhcnNlciBmb3IgSmF2YQorICogCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKgorICovCitwdWJsaWMgY2xhc3MgVGVzdE9yYWNsZSBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKwkvKioKKwkgKiBDb25zdHJ1Y3RzIHRoZSB0ZXN0IHN1aXRlCisJICogCisJICogQHJldHVybiB0ZXN0IHN1aXRlCisJICogQHRocm93cyBFeGNlcHRpb24gY2FuIHRocm93IGNsYXNzIGxvYWQgZXhjZXB0aW9ucworCSAqIGlmIGNsYXNzIHBhdGggZG9lcyBub3QgY29udGFpbiBkb20zLWxzLmphciBvciAKKwkgKiB4bWxwYXJzZXJ2Mi5qYXIKKwkgKi8KKwlwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworCQlDbGFzcyB0ZXN0Q2xhc3MgPQorCQkJQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoCisJCQkJIm9yZy53M2MuZG9tdHMubGV2ZWwzLmxzLmFsbHRlc3RzIik7CisJCUNvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9CisJCQl0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IoCisJCQkJbmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworCQlEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGp4RmFjdG9yeSA9CisJCQkoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSkgQ2xhc3NMb2FkZXIKKwkJCQkuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKQorCQkJCS5sb2FkQ2xhc3MoIm9yYWNsZS54bWwuamF4cC5KWERvY3VtZW50QnVpbGRlckZhY3RvcnkiKQorCQkJCS5uZXdJbnN0YW5jZSgpOworCisJCURPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorCQkJbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKwkJCQlqeEZhY3RvcnksCisJCQkJSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24xKCkpOworCisJCU9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKwkJcmV0dXJuIG5ldyBKVW5pdFRlc3RTdWl0ZUFkYXB0ZXIoKERPTVRlc3RTdWl0ZSkgdGVzdCk7CisJfQorCit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy9scy9UZXN0WGVyY2VzLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy9scy9UZXN0WGVyY2VzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGExODM2NwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL2xzL1Rlc3RYZXJjZXMuamF2YQpAQCAtMCwwICsxLDU2IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwzLmxzOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKKy8qKgorICogQSBKVW5pdCB0ZXN0IHN1aXRlIHRoYXQgd2lsbCBydW4gYWxsIExvYWQgYW5kIFNhdmUgdGVzdHMKKyAqIHVzaW5nIFhlcmNlcy1KCisgKiAKKyAqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0WGVyY2VzIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMy5scy5hbGx0ZXN0cyIpOworICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9IHRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB4ZXJjZXNGYWN0b3J5ID0gKERvY3VtZW50QnVpbGRlckZhY3RvcnkpCisgICAgICBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLmFwYWNoZS54ZXJjZXMuamF4cC5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbCIpLm5ld0luc3RhbmNlKCk7CisKKyAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKyAgICAgICAgbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSh4ZXJjZXNGYWN0b3J5LAorICAgICAgICAgIEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy92YWxpZGF0aW9uL1Rlc3RCYXRpay5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvdmFsaWRhdGlvbi9UZXN0QmF0aWsuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMTk5NzY4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvdmFsaWRhdGlvbi9UZXN0QmF0aWsuamF2YQpAQCAtMCwwICsxLDQ1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgKiBQVVJQT1NFLgorICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDMudmFsaWRhdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkJhdGlrVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRvY3VtZW50QnVpbGRlclNldHRpbmc7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKKy8qKgorICogCisgKiBSdW5zIHRlc3Qgc3VpdGUgdXNpbmcgQmF0aWsgU1ZHLgorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0QmF0aWsgZXh0ZW5kcyBUZXN0U3VpdGUgeworICAgIC8qKgorICAgICAqIEZhY3RvcnkgbWV0aG9kIGZvciBzdWl0ZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHN1aXRlCisgICAgICogQHRocm93cyBFeGNlcHRpb24gaWYgQmF0aWsgaXMgbm90IGF2YWlsYWJsZSBvciBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkCisgICAgICovCisJcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwkJQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoCisJCQkJIm9yZy53M2MuZG9tdHMubGV2ZWwzLnZhbGlkYXRpb24uYWxsdGVzdHMiKTsKKwkJQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzCisJCQkJLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tde0RPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzfSk7CisJCURPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPSBuZXcgQmF0aWtUZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKwkJCQluZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1swXSk7CisJCU9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXXtmYWN0b3J5fSk7CisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL3ZhbGlkYXRpb24vVGVzdERlZmF1bHRMUy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvdmFsaWRhdGlvbi9UZXN0RGVmYXVsdExTLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzFkNzU5ZAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL3ZhbGlkYXRpb24vVGVzdERlZmF1bHRMUy5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUKKyAqIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4KKyAqIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZSBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcworICogcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKKyAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKKyAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlCisgKiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDMudmFsaWRhdGlvbjsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkxTRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiBUZXN0IHN1aXRlIHRoYXQgcnVucyBhbGwgRE9NIEwzIFZhbGlkYXRpb24gdGVzdHMgdXNpbmcgdGhlCisgKiBhIHBhcnNlciBwcm92aWRlZCBieSBET00gTDMgQ29yZSBib290c3RyYXBwaW5nLgorICogCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3REZWZhdWx0TFMgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGluc3RhbmNlIG9mIHRlc3Qgc3VpdGUuCisgICAgICogCisgICAgICogQHJldHVybiB0ZXN0IHN1aXRlCisgICAgICogQHRocm93cyBFeGNlcHRpb24gaWYgdGVzdHMgb3IgaW1wbGVtZW50YXRpb24gY291bGQgbm90IGJlIGxvYWRlZAorICAgICAqLworCXB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJCUNsYXNzIHRlc3RDbGFzcyA9CisJCQlDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygKKwkJCQkib3JnLnczYy5kb210cy5sZXZlbDMudmFsaWRhdGlvbi5hbGx0ZXN0cyIpOworCQlDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPQorCQkJdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKAorCQkJCW5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKwkJRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisJCQluZXcgTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KAorCQkJCUpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworCQlPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvdmFsaWRhdGlvbi9UZXN0RGVmYXVsdExTQWx0Q29uZmlnLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy92YWxpZGF0aW9uL1Rlc3REZWZhdWx0TFNBbHRDb25maWcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NjE2MGMyCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvdmFsaWRhdGlvbi9UZXN0RGVmYXVsdExTQWx0Q29uZmlnLmphdmEKQEAgLTAsMCArMSw1NyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZQorICogb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgorICogQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcworICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzCisgKiBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQorICogV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUworICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UKKyAqIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMy52YWxpZGF0aW9uOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworCisvKioKKyAqIFRlc3Qgc3VpdGUgdGhhdCBydW5zIGFsbCBET00gTDMgVmFsaWRhdGlvbiB0ZXN0cyB1c2luZyBhCisgKiBwYXJzZXIgcHJvdmlkZWQgYnkgRE9NIEwzIENvcmUgYm9vdHN0cmFwcGluZworICogaW4gYWx0ZXJuYXRpdmUgY29uZmlndXJhdGlvbgorICogCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3REZWZhdWx0TFNBbHRDb25maWcgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSB0ZXN0IHN1aXRlCisgICAgICogQHJldHVybiB0ZXN0IHN1aXRlCisgICAgICogQHRocm93cyBFeGNlcHRpb24gaWYgdGVzdHMgb3IgaW1wbGVtZW50YXRpb24gbm90IGxvYWRlZAorICAgICAqLworCXB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJCUNsYXNzIHRlc3RDbGFzcyA9CisJCQlDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygKKwkJCQkib3JnLnczYy5kb210cy5sZXZlbDMudmFsaWRhdGlvbi5hbGx0ZXN0cyIpOworCQlDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPQorCQkJdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKAorCQkJCW5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKwkJRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisJCQluZXcgTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KAorCQkJCUpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMigpKTsKKworCQlPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvdmFsaWRhdGlvbi9UZXN0RGVmYXVsdFBhcnNlci5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvdmFsaWRhdGlvbi9UZXN0RGVmYXVsdFBhcnNlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRkNTA0NjEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy92YWxpZGF0aW9uL1Rlc3REZWZhdWx0UGFyc2VyLmphdmEKQEAgLTAsMCArMSw1MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMy52YWxpZGF0aW9uOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiBUZXN0IHN1aXRlIHVzaW5nIHRoZSBkZWZhdWx0IEpBWFAgcGFyc2VyIGluIHRoZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24KKyAqIAorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0RGVmYXVsdFBhcnNlciBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKyAgLyoqCisgICAgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIHRlc3Qgc3VpdGUKKyAgICAqIEByZXR1cm4gbmV3IHRlc3Qgc3VpdGUKKyAgICAqIEBleGNlcHRpb24gRXhjZXB0aW9uIGlmIHRlc3RzIG9yIGltcGxlbWVudGF0aW9uIGNhbiBiZSBjcmVhdGVkLiAKKyAgICAqLworICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMy52YWxpZGF0aW9uLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKyAgICAgICAgbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeShudWxsLAorICAgICAgICAgIEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgfQorCisKK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvdmFsaWRhdGlvbi9UZXN0RGVmYXVsdFBhcnNlckFsdENvbmZpZy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvdmFsaWRhdGlvbi9UZXN0RGVmYXVsdFBhcnNlckFsdENvbmZpZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkwNGZhOTkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy92YWxpZGF0aW9uL1Rlc3REZWZhdWx0UGFyc2VyQWx0Q29uZmlnLmphdmEKQEAgLTAsMCArMSw1NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMy52YWxpZGF0aW9uOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworCisKKy8qKgorICogVGVzdCBzdWl0ZSB1c2luZyB0aGUgZGVmYXVsdCBKQVhQIHBhcnNlciBpbiB0aGUgYWx0ZXJuYXRpdmUgY29uZmlndXJhdGlvbgorICogCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3REZWZhdWx0UGFyc2VyQWx0Q29uZmlnIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgdGVzdCBzdWl0ZQorICAgICAqIEByZXR1cm4gbmV3IHRlc3Qgc3VpdGUKKyAgICAgKiBAZXhjZXB0aW9uIEV4Y2VwdGlvbiBpZiB0ZXN0cyBvciBpbXBsZW1lbnRhdGlvbiBjYW4gYmUgY3JlYXRlZC4gCisgICAgICovCisgICAgCisgIHB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbgorICB7CisgICAgQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy53M2MuZG9tdHMubGV2ZWwzLnZhbGlkYXRpb24uYWxsdGVzdHMiKTsKKyAgICBDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPSB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworICAgIERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorICAgICAgICBuZXcgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5KG51bGwsCisgICAgICAgICAgSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmdldENvbmZpZ3VyYXRpb24yKCkpOworCisgICAgT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworICAgIHJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworICB9CisKKworfQorCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy92YWxpZGF0aW9uL1Rlc3RPcmFjbGUuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL3ZhbGlkYXRpb24vVGVzdE9yYWNsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYxNzhkMjgKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy92YWxpZGF0aW9uL1Rlc3RPcmFjbGUuamF2YQpAQCAtMCwwICsxLDYzIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mCisgKiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuCisgKiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMKKyAqIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZCisgKiBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTCisgKiBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZQorICogaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwzLnZhbGlkYXRpb247CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiBUZXN0IHN1aXRlIHRoYXQgcnVucyBhbGwgRE9NIEwzIFZhbGlkYXRpb24gdGVzdHMgdXNpbmcgdGhlCisgKiBPcmFjbGUgUGFyc2VyIGZvciBKYXZhIGluIGRlZmF1bHQgY29uZmlndXJhdGlvbi4KKyAqIAorICogQGF1dGhvciBDdXJ0IEFybm9sZAorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0T3JhY2xlIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworCS8qKgorCSAqIENvbnN0cnVjdG9yCisJICogQHJldHVybiB0ZXN0IHN1aXRlCisJICogQHRocm93cyBFeGNlcHRpb24KKwkgKi8KKwlwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworCQlDbGFzcyB0ZXN0Q2xhc3MgPQorCQkJQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoCisJCQkJIm9yZy53M2MuZG9tdHMubGV2ZWwzLnZhbGlkYXRpb24uYWxsdGVzdHMiKTsKKwkJQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0KKwkJCXRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcigKKwkJCQluZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisJCURvY3VtZW50QnVpbGRlckZhY3Rvcnkgb3JhY2xlRmFjdG9yeSA9CisJCQkoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSkgQ2xhc3NMb2FkZXIKKwkJCQkuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKQorCQkJCS5sb2FkQ2xhc3MoIm9yYWNsZS54bWwuamF4cC5KWERvY3VtZW50QnVpbGRlckZhY3RvcnkiKQorCQkJCS5uZXdJbnN0YW5jZSgpOworCisJCURPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorCQkJbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKwkJCQlvcmFjbGVGYWN0b3J5LAorCQkJCUpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworCQlPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvdmFsaWRhdGlvbi9UZXN0T3JhY2xlQWx0Q29uZmlnLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy92YWxpZGF0aW9uL1Rlc3RPcmFjbGVBbHRDb25maWcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYmFjODNiCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMvdmFsaWRhdGlvbi9UZXN0T3JhY2xlQWx0Q29uZmlnLmphdmEKQEAgLTAsMCArMSw2MiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZgorICogVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgorICogQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcworICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzCisgKiBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQorICogV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUworICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UKKyAqIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMy52YWxpZGF0aW9uOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKKy8qKgorICogVGVzdCBzdWl0ZSB0aGF0IHJ1bnMgYWxsIERPTSBMMyBWYWxpZGF0aW9uIHRlc3RzIHVzaW5nIHRoZQorICogT3JhY2xlIFBhcnNlciBmb3IgSmF2YSBpbiBhbiBhbHRlcm5hdGl2ZSBjb25maWd1cmF0aW9uLgorICogCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3RPcmFjbGVBbHRDb25maWcgZXh0ZW5kcyBUZXN0U3VpdGUgeworCS8qKgorCSAqIENvbnN0cnVjdG9yCisJICogQHJldHVybiB0ZXN0IHN1aXRlCisJICogQHRocm93cyBFeGNlcHRpb24KKwkgKi8KKwlwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworCQlDbGFzcyB0ZXN0Q2xhc3MgPQorCQkJQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoCisJCQkJIm9yZy53M2MuZG9tdHMubGV2ZWwzLnZhbGlkYXRpb24uYWxsdGVzdHMiKTsKKwkJQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0KKwkJCXRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcigKKwkJCQluZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisJCURvY3VtZW50QnVpbGRlckZhY3Rvcnkgb3JhY2xlRmFjdG9yeSA9CisJCQkoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSkgQ2xhc3NMb2FkZXIKKwkJCQkuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKQorCQkJCS5sb2FkQ2xhc3MoIm9yYWNsZS54bWwuamF4cC5KWERvY3VtZW50QnVpbGRlckZhY3RvcnkiKQorCQkJCS5uZXdJbnN0YW5jZSgpOworCisJCURPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorCQkJbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKwkJCQlvcmFjbGVGYWN0b3J5LAorCQkJCUpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMigpKTsKKworCQlPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMveHBhdGgvVGVzdEJhdGlrLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy94cGF0aC9UZXN0QmF0aWsuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MWUyYWI1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMveHBhdGgvVGVzdEJhdGlrLmphdmEKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCitwYWNrYWdlIG9yZy53M2MuZG9tdHMubGV2ZWwzLnhwYXRoOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuQmF0aWtUZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuRG9jdW1lbnRCdWlsZGVyU2V0dGluZzsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiAKKyAqIFJ1bnMgdGVzdCBzdWl0ZSB1c2luZyBCYXRpayBTVkcuCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3RCYXRpayBleHRlbmRzIFRlc3RTdWl0ZSB7CisgICAgLyoqCisgICAgICogRmFjdG9yeSBtZXRob2QgZm9yIHN1aXRlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gc3VpdGUKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbiBpZiBCYXRpayBpcyBub3QgYXZhaWxhYmxlIG9yIGNvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQKKyAgICAgKi8KKwlwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworCQlDbGFzcyB0ZXN0Q2xhc3MgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygKKwkJCQkib3JnLnczYy5kb210cy5sZXZlbDMueHBhdGguYWxsdGVzdHMiKTsKKwkJQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzCisJCQkJLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tde0RPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzfSk7CisJCURPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPSBuZXcgQmF0aWtUZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKwkJCQluZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1swXSk7CisJCU9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXXtmYWN0b3J5fSk7CisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL3hwYXRoL1Rlc3REZWZhdWx0TFMuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL3hwYXRoL1Rlc3REZWZhdWx0TFMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZTRhNTZhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMveHBhdGgvVGVzdERlZmF1bHRMUy5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUKKyAqIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4KKyAqIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZSBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcworICogcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKKyAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKKyAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlCisgKiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDMueHBhdGg7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5MU0RvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKKy8qKgorICogVGVzdCBzdWl0ZSB0aGF0IHJ1bnMgYWxsIERPTSBMMyBYUGF0aCB0ZXN0cyB1c2luZyB0aGUKKyAqIGEgcGFyc2VyIHByb3ZpZGVkIGJ5IERPTSBMMyBDb3JlIGJvb3RzdHJhcHBpbmcuCisgKiAKKyAqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyAqIAorICovCitwdWJsaWMgY2xhc3MgVGVzdERlZmF1bHRMUyBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgaW5zdGFuY2Ugb2YgdGVzdCBzdWl0ZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRlc3Qgc3VpdGUKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbiBpZiB0ZXN0cyBvciBpbXBsZW1lbnRhdGlvbiBjb3VsZCBub3QgYmUgbG9hZGVkCisgICAgICovCisJcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwkJQ2xhc3MgdGVzdENsYXNzID0KKwkJCUNsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKAorCQkJCSJvcmcudzNjLmRvbXRzLmxldmVsMy54cGF0aC5hbGx0ZXN0cyIpOworCQlDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPQorCQkJdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKAorCQkJCW5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKwkJRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisJCQluZXcgTFNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KAorCQkJCUpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworCQlPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisJCXJldHVybiBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKChET01UZXN0U3VpdGUpIHRlc3QpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMveHBhdGgvVGVzdERlZmF1bHRMU0FsdENvbmZpZy5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMveHBhdGgvVGVzdERlZmF1bHRMU0FsdENvbmZpZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiYmU1MDIKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy94cGF0aC9UZXN0RGVmYXVsdExTQWx0Q29uZmlnLmphdmEKQEAgLTAsMCArMSw1NyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZQorICogb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbgorICogQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcworICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzCisgKiBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQorICogV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUworICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UKKyAqIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMy54cGF0aDsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkxTRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiBUZXN0IHN1aXRlIHRoYXQgcnVucyBhbGwgRE9NIEwzIFhQYXRoIHRlc3RzIHVzaW5nIGEKKyAqIHBhcnNlciBwcm92aWRlZCBieSBET00gTDMgWFBhdGggYm9vdHN0cmFwcGluZworICogaW4gYWx0ZXJuYXRpdmUgY29uZmlndXJhdGlvbgorICogCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3REZWZhdWx0TFNBbHRDb25maWcgZXh0ZW5kcyBUZXN0U3VpdGUgeworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSB0ZXN0IHN1aXRlCisgICAgICogQHJldHVybiB0ZXN0IHN1aXRlCisgICAgICogQHRocm93cyBFeGNlcHRpb24gaWYgdGVzdHMgb3IgaW1wbGVtZW50YXRpb24gbm90IGxvYWRlZAorICAgICAqLworCXB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJCUNsYXNzIHRlc3RDbGFzcyA9CisJCQlDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygKKwkJCQkib3JnLnczYy5kb210cy5sZXZlbDMueHBhdGguYWxsdGVzdHMiKTsKKwkJQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0KKwkJCXRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcigKKwkJCQluZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisJCURPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPQorCQkJbmV3IExTRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSgKKwkJCQlKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisKKwkJT2JqZWN0IHRlc3QgPSB0ZXN0Q29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHsgZmFjdG9yeSB9KTsKKworCQlyZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKwl9CisKK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL3hwYXRoL1Rlc3REZWZhdWx0UGFyc2VyLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy94cGF0aC9UZXN0RGVmYXVsdFBhcnNlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlY2FiYTEKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy94cGF0aC9UZXN0RGVmYXVsdFBhcnNlci5qYXZhCkBAIC0wLDAgKzEsNTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDMueHBhdGg7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuSkFYUERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworCisvKioKKyAqIFRlc3Qgc3VpdGUgdXNpbmcgdGhlIGRlZmF1bHQgSkFYUCBwYXJzZXIgaW4gdGhlIGRlZmF1bHQgY29uZmlndXJhdGlvbgorICogCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRlc3REZWZhdWx0UGFyc2VyIGV4dGVuZHMgVGVzdFN1aXRlIHsKKworICAvKioKKyAgICAqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgdGVzdCBzdWl0ZQorICAgICogQHJldHVybiBuZXcgdGVzdCBzdWl0ZQorICAgICogQGV4Y2VwdGlvbiBFeGNlcHRpb24gaWYgdGVzdHMgb3IgaW1wbGVtZW50YXRpb24gY2FuIGJlIGNyZWF0ZWQuIAorICAgICovCisgIHB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbgorICB7CisgICAgQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy53M2MuZG9tdHMubGV2ZWwzLnhwYXRoLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKyAgICAgICAgbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeShudWxsLAorICAgICAgICAgIEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKworICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgfQorCisKK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMveHBhdGgvVGVzdERlZmF1bHRQYXJzZXJBbHRDb25maWcuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL3hwYXRoL1Rlc3REZWZhdWx0UGFyc2VyQWx0Q29uZmlnLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWNjOTE0MQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL3hwYXRoL1Rlc3REZWZhdWx0UGFyc2VyQWx0Q29uZmlnLmphdmEKQEAgLTAsMCArMSw1NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMy54cGF0aDsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKKworCisvKioKKyAqIFRlc3Qgc3VpdGUgdXNpbmcgdGhlIGRlZmF1bHQgSkFYUCBwYXJzZXIgaW4gdGhlIGFsdGVybmF0aXZlIGNvbmZpZ3VyYXRpb24KKyAqIAorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0RGVmYXVsdFBhcnNlckFsdENvbmZpZyBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIHRlc3Qgc3VpdGUKKyAgICAgKiBAcmV0dXJuIG5ldyB0ZXN0IHN1aXRlCisgICAgICogQGV4Y2VwdGlvbiBFeGNlcHRpb24gaWYgdGVzdHMgb3IgaW1wbGVtZW50YXRpb24gY2FuIGJlIGNyZWF0ZWQuIAorICAgICAqLworICAgIAorICBwdWJsaWMgc3RhdGljIFRlc3RTdWl0ZSBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24KKyAgeworICAgIENsYXNzIHRlc3RDbGFzcyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKCJvcmcudzNjLmRvbXRzLmxldmVsMy54cGF0aC5hbGx0ZXN0cyIpOworICAgIENvbnN0cnVjdG9yIHRlc3RDb25zdHJ1Y3RvciA9IHRlc3RDbGFzcy5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbXSB7IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmNsYXNzIH0pOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkobnVsbCwKKyAgICAgICAgICBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisKKyAgICBPYmplY3QgdGVzdCA9IHRlc3RDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyBmYWN0b3J5IH0pOworCisgICAgcmV0dXJuIG5ldyBKVW5pdFRlc3RTdWl0ZUFkYXB0ZXIoKERPTVRlc3RTdWl0ZSkgdGVzdCk7CisgIH0KKworCit9CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL3hwYXRoL1Rlc3RYYWxhbi5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMveHBhdGgvVGVzdFhhbGFuLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODNmZmU3OQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9qYXZhL29yZy93M2MvZG9tdHMvbGV2ZWwzL3hwYXRoL1Rlc3RYYWxhbi5qYXZhCkBAIC0wLDAgKzEsNDggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCisKK3BhY2thZ2Ugb3JnLnczYy5kb210cy5sZXZlbDMueHBhdGg7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLlhhbGFuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CisKK3B1YmxpYyBjbGFzcyBUZXN0WGFsYW4gZXh0ZW5kcyBUZXN0U3VpdGUgeworCisgIHB1YmxpYyBzdGF0aWMgVGVzdFN1aXRlIHN1aXRlKCkgdGhyb3dzIEV4Y2VwdGlvbgorICB7CisgICAgQ2xhc3MgdGVzdENsYXNzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoIm9yZy53M2MuZG9tdHMubGV2ZWwzLnhwYXRoLmFsbHRlc3RzIik7CisgICAgQ29uc3RydWN0b3IgdGVzdENvbnN0cnVjdG9yID0gdGVzdENsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MgfSk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGpheHBGYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworCisgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9CisgICAgICAgIG5ldyBYYWxhbkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5KGpheHBGYWN0b3J5LAorICAgICAgICAgIFhhbGFuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisKKworICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgfQorCisKK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMveHBhdGgvVGVzdFhhbGFuQWx0Q29uZmlnLmphdmEgYi9kb20vc3JjL3Rlc3QvamF2YS9vcmcvdzNjL2RvbXRzL2xldmVsMy94cGF0aC9UZXN0WGFsYW5BbHRDb25maWcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNjhkMzQxCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvb3JnL3czYy9kb210cy9sZXZlbDMveHBhdGgvVGVzdFhhbGFuQWx0Q29uZmlnLmphdmEKQEAgLTAsMCArMSw0NyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRS4KKyAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorICovCisKKworcGFja2FnZSBvcmcudzNjLmRvbXRzLmxldmVsMy54cGF0aDsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdFN1aXRlOworaW1wb3J0IG9yZy53M2MuZG9tdHMuSlVuaXRUZXN0U3VpdGVBZGFwdGVyOworaW1wb3J0IG9yZy53M2MuZG9tdHMuWGFsYW5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworcHVibGljIGNsYXNzIFRlc3RYYWxhbkFsdENvbmZpZyBleHRlbmRzIFRlc3RTdWl0ZSB7CisKKyAgcHVibGljIHN0YXRpYyBUZXN0U3VpdGUgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uCisgIHsKKyAgICBDbGFzcyB0ZXN0Q2xhc3MgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcygib3JnLnczYy5kb210cy5sZXZlbDMueHBhdGguYWxsdGVzdHMiKTsKKyAgICBDb25zdHJ1Y3RvciB0ZXN0Q29uc3RydWN0b3IgPSB0ZXN0Q2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzW10geyBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5jbGFzcyB9KTsKKworICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgamF4cEZhY3RvcnkgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisKKyAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0KKyAgICAgICAgbmV3IFhhbGFuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkoamF4cEZhY3RvcnksCisgICAgICAgICAgWGFsYW5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMigpKTsKKworICAgIE9iamVjdCB0ZXN0ID0gdGVzdENvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7IGZhY3RvcnkgfSk7CisKKyAgICByZXR1cm4gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcigoRE9NVGVzdFN1aXRlKSB0ZXN0KTsKKyAgfQorCisKK30KKwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy93M2MvZG9tL0FsbFRlc3RzX0xldmVsMS5qYXZhIGIvZG9tL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy93M2MvZG9tL0FsbFRlc3RzX0xldmVsMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc3ODYzM2IKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3czYy9kb20vQWxsVGVzdHNfTGV2ZWwxLmphdmEKQEAgLTAsMCArMSw1MyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBHb29nbGUgSW5jLgorICogCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QKKyAqIHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mCisgKiB0aGUgTGljZW5zZSBhdAorICogCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqIAorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVAorICogV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlCisgKiBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgorICogdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkub3JnLnczYy5kb207CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkRPTVRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbXRzLkpVbml0VGVzdFN1aXRlQWRhcHRlcjsKKworLyoqCisgKiBMaXN0aW5nIG9mIGFsbCB0aGUgdGVzdHMgdGhhdCBhcmUgdG8gYmUgcnVuLgorICovCitwdWJsaWMgY2xhc3MgQWxsVGVzdHNfTGV2ZWwxIHsKKyAgICAvKnB1YmxpYyBzdGF0aWMgdm9pZCBydW4oKSB7CisgICAgICAgIFRlc3RSdW5uZXIubWFpbihuZXcgU3RyaW5nW10ge01haW5fQWxsVGVzdHMuY2xhc3MuZ2V0TmFtZSgpfSk7CisgICAgfSovCisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRlc3Qgc3VpdGUoKSB7CisgICAgICAgIC8vIGZyb20gaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvCisgICAgICAgIC8vIExldmVsIDEgQ29yZSB0ZXN0cworICAgICAgICBET01UZXN0U3VpdGUgZG9tU3VpdGU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5MSA9CisgICAgICAgICAgICAgICAgbmV3IEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeShudWxsLAorICAgICAgICAgICAgICAgIEpBWFBET01UZXN0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIC8vIGFuZHJvaWQ6IGNvYWxlc2NpbmcsIGVwYW5kLCBpZ25vcmV3aGl0ZXNwYWNlLCBuYW1lc3BhY2UsIE5PVCB2YWxpZGF0aW9uCisKKyAgICAgICAgICAgIGRvbVN1aXRlID0gbmV3IG9yZy53M2MuZG9tdHMubGV2ZWwxLmNvcmUuYWxsdGVzdHMoZmFjdG9yeTEpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oInByb2JsZW0gY3JlYXRpbmcgZG9tIHRlc3Qgc3VpdGUsICIrZS5nZXRDbGFzcygpLmdldE5hbWUoKSsiLCAiK2UuZ2V0TWVzc2FnZSgpLCBlKTsKKyAgICAgICAgfQorICAgICAgICBUZXN0U3VpdGUgc3VpdGUgPSBuZXcgSlVuaXRUZXN0U3VpdGVBZGFwdGVyKGRvbVN1aXRlKTsKKyAgICAgICAgcmV0dXJuIHN1aXRlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcvdzNjL2RvbS9BbGxUZXN0c19MZXZlbDIuamF2YSBiL2RvbS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcvdzNjL2RvbS9BbGxUZXN0c19MZXZlbDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZmYzZDBkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy93M2MvZG9tL0FsbFRlc3RzX0xldmVsMi5qYXZhCkBAIC0wLDAgKzEsNTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggR29vZ2xlIEluYy4KKyAqIAorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90CisgKiB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZgorICogdGhlIExpY2Vuc2UgYXQKKyAqIAorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKiAKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQKKyAqIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZQorICogTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKKyAqIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLm9yZy53M2MuZG9tOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IG9yZy53M2MuZG9tdHMuRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5ET01UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb210cy5KQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLnczYy5kb210cy5KVW5pdFRlc3RTdWl0ZUFkYXB0ZXI7CisKKy8qKgorICogTGlzdGluZyBvZiBhbGwgdGhlIHRlc3RzIHRoYXQgYXJlIHRvIGJlIHJ1bi4KKyAqLworcHVibGljIGNsYXNzIEFsbFRlc3RzX0xldmVsMiB7CisgICAgLypwdWJsaWMgc3RhdGljIHZvaWQgcnVuKCkgeworICAgICAgICBUZXN0UnVubmVyLm1haW4obmV3IFN0cmluZ1tdIHtNYWluX0FsbFRlc3RzLmNsYXNzLmdldE5hbWUoKX0pOworICAgIH0qLworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBUZXN0IHN1aXRlKCkgeworICAgICAgICAvLyBmcm9tIGh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0LworICAgICAgICAvLyBMZXZlbCAyIENvcmUgdGVzdHMKKyAgICAgICAgRE9NVGVzdFN1aXRlIGRvbVN1aXRlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTEgPQorICAgICAgICAgICAgICAgIG5ldyBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkobnVsbCwKKyAgICAgICAgICAgICAgICBKQVhQRE9NVGVzdERvY3VtZW50QnVpbGRlckZhY3RvcnkuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAvLyBhbmRyb2lkOiBjb2FsZXNjaW5nLCBlcGFuZCwgaWdub3Jld2hpdGVzcGFjZSwgbmFtZXNwYWNlLCBOT1QgdmFsaWRhdGlvbgorCisgICAgICAgICAgICBkb21TdWl0ZSA9IG5ldyBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlLmFsbHRlc3RzKGZhY3RvcnkxKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJwcm9ibGVtIGNyZWF0aW5nIGRvbSB0ZXN0IHN1aXRlIiwgZSk7CisgICAgICAgIH0KKyAgICAgICAgVGVzdFN1aXRlIHN1aXRlID0gbmV3IEpVbml0VGVzdFN1aXRlQWRhcHRlcihkb21TdWl0ZSk7CisgICAgICAgIHJldHVybiBzdWl0ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL01FVEEtSU5GL01BTklGRVNULk1GIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9NRVRBLUlORi9NQU5JRkVTVC5NRgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYWYzZWJhCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9NRVRBLUlORi9NQU5JRkVTVC5NRgpAQCAtMCwwICsxLDE2IEBACitNYW5pZmVzdC1WZXJzaW9uOiAyLjANCitDbGFzcy1QYXRoOiAgZG9tMy14bWwtYXBpcy5qYXIgZG9tMy14ZXJjZXNJbXBsLmphciB4bWxQYXJzZXJBUElzLmphciB4DQorIGVyY2VzSW1wbC5qYXIgeGVyY2VzLmphciB4bWw0ai5qYXIgeG1scGFyc2VydjIuamFyIGNyaW1zb24uamFyIHBhcnNlcg0KKyAuamFyIGpheHAuamFyIHhtbC1hcGlzLmphciBnbnVqYXhwLmphciBkb200ai1mdWxsLmphciBiYXRpay1zdmctZG9tLmoNCisgYXIgY3JpbXNvbi1wYXJzZXIuamFyIGF2YWxvbi1ydW4uamFyDQorQ3JlYXRlZC1CeTogMS40LjJfMDQgKFN1biBNaWNyb3N5c3RlbXMgSW5jLikNCitNYWluLUNsYXNzOiBvcmcudzNjLmRvbXRzLmxldmVsMi5jb3JlLmFsbHRlc3RzDQorDQorTmFtZTogb3JnL3czYy9kb210cy9sZXZlbDIvY29yZQ0KK0ltcGxlbWVudGF0aW9uLVRpdGxlOiBXM0MvTklTVCBUZXN0IFN1aXRlIGZvciBET00gTGV2ZWwgMiBDb3JlDQorU3BlY2lmaWNhdGlvbi1UaXRsZTogVzNDL05JU1QgVGVzdCBTdWl0ZSBmb3IgRE9NIExldmVsIDIgQ29yZQ0KK1NwZWNpZmljYXRpb24tVmVyc2lvbjogMC4wLjENCitTcGVjaWZpY2F0aW9uLVZlbmRvcjogV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bQ0KK0ltcGxlbWVudGF0aW9uLVZlcnNpb246IDAuMC4xDQorSW1wbGVtZW50YXRpb24tVmVuZG9yOiBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtIA0KKw0KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvYnVpbGQueG1sIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9idWlsZC54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTAwNjBlMAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvYnVpbGQueG1sCkBAIC0wLDAgKzEsMTA2IEBACis8IS0tIEpVbml0IGJ1aWxkIHNjcmlwdCB1c2luZyBhbnQgMS4zIC0tPg0KKzxwcm9qZWN0IG5hbWU9Imp1bml0IiBkZWZhdWx0PSJkaXN0IiBiYXNlZGlyPSIuIj4NCisJPHRhcmdldCBuYW1lPSJpbml0Ij4NCisJCTx0c3RhbXAvPg0KKwkJPHByb3BlcnR5IG5hbWU9InZlcnNpb24iIHZhbHVlPSIzLjciIC8+DQorCQk8cHJvcGVydHkgbmFtZT0iZGlzdCIgIHZhbHVlPSJqdW5pdCR7dmVyc2lvbn0iIC8+DQorCQk8cHJvcGVydHkgbmFtZT0idmVyc2lvbmZpbGUiICB2YWx1ZT0ianVuaXQvcnVubmVyL1ZlcnNpb24uamF2YSIgLz4NCisJCTxwcm9wZXJ0eSBuYW1lPSJ6aXBmaWxlIiAgdmFsdWU9IiR7ZGlzdH0uemlwIiAvPg0KKwk8L3RhcmdldD4NCisNCisJPHRhcmdldCBuYW1lPSJ2ZXJzaW9udGFnIiBkZXBlbmRzPSJpbml0Ij4NCisJCTxmaWx0ZXIgdG9rZW49InZlcnNpb24iIHZhbHVlPSIke3ZlcnNpb259IiAvPg0KKwkJPGNvcHkgDQorCQkJZmlsZT0iJHt2ZXJzaW9uZmlsZX0iIA0KKwkJCXRvZmlsZT0iJHt2ZXJzaW9uZmlsZX10bXAiIA0KKwkJCWZpbHRlcmluZz0ib24iDQorCQkvPg0KKwkJPG1vdmUgZmlsZT0iJHt2ZXJzaW9uZmlsZX10bXAiIHRvZmlsZT0iJHt2ZXJzaW9uZmlsZX0iIC8+DQorCTwvdGFyZ2V0Pg0KKw0KKwk8dGFyZ2V0IG5hbWU9ImJ1aWxkIiBkZXBlbmRzPSJ2ZXJzaW9udGFnIj4NCisJCTxqYXZhYyANCisJCQlzcmNkaXI9Ii4iDQorCQkJZGVzdGRpcj0iLiINCisJCQlkZWJ1Zz0ib24iDQorICAJCS8+CQ0KKwk8L3RhcmdldD4NCisNCisJPHRhcmdldCBuYW1lPSJkaXN0IiBkZXBlbmRzPSJidWlsZCI+DQorCQk8ZGVsZXRlIGRpcj0iJHtkaXN0fSIgLz4NCisJCTxta2RpciBkaXI9IiR7ZGlzdH0iIC8+DQorCQk8amFyIA0KKwkJCWphcmZpbGU9IiR7ZGlzdH0vc3JjLmphciINCisJCQliYXNlZGlyPSIuIg0KKwkJCWV4Y2x1ZGVzPSIke2Rpc3R9L3NyYy5qYXIsIGp1bml0L3Rlc3RzLyoqLCBqdW5pdC9zYW1wbGVzLyoqLCAqKi8qLmNsYXNzLCBkb2MvKiosIFJFQURNRS5odG1sLCBidWlsZC54bWwiDQorCQkvPg0KKwkJPGphciANCisJCQlqYXJmaWxlPSIke2Rpc3R9L2p1bml0LmphciINCisJCQliYXNlZGlyPSIuIg0KKwkJCWV4Y2x1ZGVzPSIke2Rpc3R9L2p1bml0LmphciwganVuaXQvdGVzdHMvKiosIGp1bml0L3NhbXBsZXMvKiosICoqLyouamF2YSwgZG9jLyoqLCBSRUFETUUuaHRtbCwgamFyLW1hbmlmZXN0LnR4dCINCisJCS8+DQorCQk8Y29weSB0b2Rpcj0iJHtkaXN0fS9qdW5pdC9zYW1wbGVzIj4NCisJCQk8ZmlsZXNldCBkaXI9Imp1bml0L3NhbXBsZXMiIC8+DQorCQk8L2NvcHk+DQorCQk8Y29weSB0b2Rpcj0iJHtkaXN0fS9qdW5pdC90ZXN0cyI+DQorCQkJPGZpbGVzZXQgZGlyPSJqdW5pdC90ZXN0cyIgLz4NCisJCTwvY29weT4NCisJCTxkZWxldGUgZmlsZT0iJHtkaXN0fS9qdW5pdC90ZXN0cy90ZXN0LmphciIvPg0KKwkJPGphciANCisJCQlqYXJmaWxlPSIke2Rpc3R9L2p1bml0L3Rlc3RzL3Rlc3QuamFyIg0KKwkJCWJhc2VkaXI9Ii4iDQorCQkJaW5jbHVkZXM9Imp1bml0L3Rlc3RzL0xvYWRlZEZyb21KYXIuY2xhc3MiDQorCQkvPg0KKwkJPG1rZGlyIGRpcj0iJHtkaXN0fS9qYXZhZG9jIiAvPg0KKwkJPGphdmFkb2MgDQorCQkJc291cmNlcGF0aD0iLiINCisJCQlwYWNrYWdlbmFtZXM9Imp1bml0LmZyYW1ld29yay4qLCBqdW5pdC5leHRlbnNpb25zLioiDQorCQkJZGVzdGRpcj0iJHtkaXN0fS9qYXZhZG9jIg0KKwkJCWF1dGhvcj0iZmFsc2UiDQorCQkJdmVyc2lvbj0iZmFsc2UiDQorCQkJdXNlPSJmYWxzZSINCisJCQl3aW5kb3d0aXRsZT0iSlVuaXQgQVBJIg0KKwkJLz4NCisJCTxjb3B5IHRvZGlyPSIke2Rpc3R9L2RvYyI+DQorCQkJPGZpbGVzZXQgZGlyPSJkb2MiLz4NCisJCTwvY29weT4JCQ0KKwkJPGNvcHkgZmlsZT0iUkVBRE1FLmh0bWwiIHRvZmlsZT0iJHtkaXN0fS9SRUFETUUuaHRtbCIgLz4NCisJCQ0KKwkJPGphdmEgY2xhc3NuYW1lPSJqdW5pdC50ZXh0dWkuVGVzdFJ1bm5lciIgZm9yaz0ieWVzIj4NCisJCQk8YXJnIHZhbHVlPSJqdW5pdC5zYW1wbGVzLkFsbFRlc3RzIiAvPg0KKwkJCTxjbGFzc3BhdGg+DQorCQkJCTxwYXRoZWxlbWVudCBsb2NhdGlvbj0iJHtkaXN0fSIgLz4NCisJCQkJPHBhdGhlbGVtZW50IGxvY2F0aW9uPSIke2Rpc3R9L2p1bml0LmphciIgLz4NCisJCQk8L2NsYXNzcGF0aD4NCisJCTwvamF2YT4NCisJPC90YXJnZXQ+DQorCQ0KKwk8dGFyZ2V0IG5hbWU9InppcCI+DQorCQk8IS0tICEhISBoYXJkIGNvZGUgbmFtZXMsIHZhcmlhYmxlIHN1YnN0aXR1dGlvbiBkb2Vzbid0IHdvcmsgISEhIC0tPg0KKwkJPHppcCANCisJCQl6aXBmaWxlPSJqdW5pdDMuNi56aXAiDQorCQkJYmFzZWRpcj0iLiINCisJCQlpbmNsdWRlcz0ianVuaXQzLjYvKioiDQorCQkvPg0KKwk8L3RhcmdldD4NCisJDQorCTx0YXJnZXQgbmFtZT0iYXd0dWkiIGRlcGVuZHM9ImRpc3QiPg0KKwkJPGphdmEgY2xhc3NuYW1lPSJqdW5pdC5hd3R1aS5UZXN0UnVubmVyIiBmb3JrPSJ5ZXMiPg0KKwkJCTxhcmcgdmFsdWU9Imp1bml0LnNhbXBsZXMuQWxsVGVzdHMiIC8+DQorCQkJPGNsYXNzcGF0aD4NCisJCQkJPHBhdGhlbGVtZW50IGxvY2F0aW9uPSIke2Rpc3R9IiAvPg0KKwkJCQk8cGF0aGVsZW1lbnQgbG9jYXRpb249IiR7ZGlzdH0vanVuaXQuamFyIiAvPg0KKwkJCTwvY2xhc3NwYXRoPg0KKwkJPC9qYXZhPg0KKwk8L3RhcmdldD4NCisJDQorCTx0YXJnZXQgbmFtZT0ic3dpbmd1aSIgZGVwZW5kcz0iZGlzdCI+DQorCQk8amF2YSBjbGFzc25hbWU9Imp1bml0LnN3aW5ndWkuVGVzdFJ1bm5lciIgZm9yaz0ieWVzIj4NCisJCQk8YXJnIHZhbHVlPSJqdW5pdC5zYW1wbGVzLkFsbFRlc3RzIiAvPg0KKwkJCTxjbGFzc3BhdGg+DQorCQkJCTxwYXRoZWxlbWVudCBsb2NhdGlvbj0iJHtkaXN0fSIgLz4NCisJCQkJPHBhdGhlbGVtZW50IGxvY2F0aW9uPSIke2Rpc3R9L2p1bml0LmphciIgLz4NCisJCQk8L2NsYXNzcGF0aD4NCisJCTwvamF2YT4NCisJPC90YXJnZXQ+DQorPC9wcm9qZWN0Pg0KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvaGNfbm9kdGRzdGFmZi5odG1sIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9oY19ub2R0ZHN0YWZmLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjk4ZDBiZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvaGNfbm9kdGRzdGFmZi5odG1sCkBAIC0wLDAgKzEsMTAgQEAKKzxodG1sPjxoZWFkPjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04Ij48dGl0bGU+aGNfbm9kdGRzdGFmZjwvdGl0bGU+PC9oZWFkPjxib2R5IG9ubG9hZD0icGFyZW50LmxvYWRDb21wbGV0ZSgpIj4KKyA8cD4KKyAgPGVtPkVNUDAwMDE8L2VtPgorICA8c3Ryb25nPk1hcmdhcmV0IE1hcnRpbjwvc3Ryb25nPgorICA8Y29kZT5BY2NvdW50YW50PC9jb2RlPiAgICAgICAgICAgCisgIDxzdXA+NTYsMDAwPC9zdXA+CisgIDx2YXI+RmVtYWxlPC92YXI+CisgIDxhY3JvbnltIHRpdGxlPSJZZXMiPjEyMzAgTm9ydGggQXZlLiBEYWxsYXMsIFRleGFzIDk4NTUxPC9hY3JvbnltPgorIDwvcD4KKzwvYm9keT48L2h0bWw+CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL2hjX25vZHRkc3RhZmYuc3ZnIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9oY19ub2R0ZHN0YWZmLnN2ZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OWYyNmY2Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9oY19ub2R0ZHN0YWZmLnN2ZwpAQCAtMCwwICsxLDEwIEBACis8c3ZnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiLz48aGVhZCB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCc+PHRpdGxlPmhjX25vZHRkc3RhZmY8L3RpdGxlPjwvaGVhZD48Ym9keSB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCc+CisgPHA+CisgIDxlbT5FTVAwMDAxPC9lbT4KKyAgPHN0cm9uZz5NYXJnYXJldCBNYXJ0aW48L3N0cm9uZz4KKyAgPGNvZGU+QWNjb3VudGFudDwvY29kZT4gICAgICAgICAgIAorICA8c3VwPjU2LDAwMDwvc3VwPgorICA8dmFyPkZlbWFsZTwvdmFyPgorICA8YWNyb255bSB0aXRsZT0iWWVzIj4xMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyA5ODU1MTwvYWNyb255bT4KKyA8L3A+Cis8L2JvZHk+PC9zdmc+CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL2hjX25vZHRkc3RhZmYueGh0bWwgYi9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL2hjX25vZHRkc3RhZmYueGh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGE1ZDhhOAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvaGNfbm9kdGRzdGFmZi54aHRtbApAQCAtMCwwICsxLDEwIEBACis8aHRtbCB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI+PGhlYWQ+PHRpdGxlPmhjX25vZHRkc3RhZmY8L3RpdGxlPjwvaGVhZD48Ym9keSBvbmxvYWQ9InBhcmVudC5sb2FkQ29tcGxldGUoKSI+CisgPHA+CisgIDxlbT5FTVAwMDAxPC9lbT4KKyAgPHN0cm9uZz5NYXJnYXJldCBNYXJ0aW48L3N0cm9uZz4KKyAgPGNvZGU+QWNjb3VudGFudDwvY29kZT4gICAgICAgICAgIAorICA8c3VwPjU2LDAwMDwvc3VwPgorICA8dmFyPkZlbWFsZTwvdmFyPgorICA8YWNyb255bSB0aXRsZT0iWWVzIj4xMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyA5ODU1MTwvYWNyb255bT4KKyA8L3A+Cis8L2JvZHk+PC9odG1sPgpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9oY19ub2R0ZHN0YWZmLnhtbCBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvaGNfbm9kdGRzdGFmZi54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODVjMDY5MwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvaGNfbm9kdGRzdGFmZi54bWwKQEAgLTAsMCArMSwxMCBAQAorPGh0bWwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPjxoZWFkPjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04Ii8+PHRpdGxlPmhjX25vZHRkc3RhZmY8L3RpdGxlPjwvaGVhZD48Ym9keSBvbmxvYWQ9InBhcmVudC5sb2FkQ29tcGxldGUoKSI+CisgPHA+CisgIDxlbT5FTVAwMDAxPC9lbT4KKyAgPHN0cm9uZz5NYXJnYXJldCBNYXJ0aW48L3N0cm9uZz4KKyAgPGNvZGU+QWNjb3VudGFudDwvY29kZT4gICAgICAgICAgIAorICA8c3VwPjU2LDAwMDwvc3VwPgorICA8dmFyPkZlbWFsZTwvdmFyPgorICA8YWNyb255bSB0aXRsZT0iWWVzIj4xMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyA5ODU1MTwvYWNyb255bT4KKyA8L3A+Cis8L2JvZHk+PC9odG1sPgpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9oY19zdGFmZi5odG1sIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9oY19zdGFmZi5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlhY2Y3NTAKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL2hjX3N0YWZmLmh0bWwKQEAgLTAsMCArMSw0OCBAQAorPCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEvL0VOIiAKKyAgICAiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQvc3RyaWN0LmR0ZCIgPgorPCEtLSBUaGlzIGlzIGNvbW1lbnQgbnVtYmVyIDEuLS0+Cis8aHRtbD48aGVhZD48bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD1VVEYtOCI+PHRpdGxlPmhjX3N0YWZmPC90aXRsZT48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJzdmd1bml0LmpzIj48L3NjcmlwdD48c2NyaXB0IGNoYXJzZXQ9IlVURi04IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ic3ZndGVzdC5qcyI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSd0ZXh0L2phdmFzY3JpcHQnPmZ1bmN0aW9uIGxvYWRDb21wbGV0ZSgpIHsgc3RhcnRUZXN0KCk7IH08L3NjcmlwdD48L2hlYWQ+PGJvZHkgb25sb2FkPSJwYXJlbnQubG9hZENvbXBsZXRlKCkiPgorIDxwPgorICA8ZW0+RU1QMDAwMTwvZW0+CisgIDxzdHJvbmc+TWFyZ2FyZXQgTWFydGluPC9zdHJvbmc+CisgIDxjb2RlPkFjY291bnRhbnQ8L2NvZGU+ICAgICAgICAgICAKKyAgPHN1cD41NiwwMDA8L3N1cD4KKyAgPHZhcj5GZW1hbGU8L3Zhcj4KKyAgPGFjcm9ueW0gdGl0bGU9IlllcyI+MTIzMCBOb3J0aCBBdmUuIERhbGxhcywgVGV4YXMgOTg1NTE8L2Fjcm9ueW0+CisgPC9wPgorIDxwPgorICA8ZW0+RU1QMDAwMjwvZW0+CisgIDxzdHJvbmc+TWFydGhhIFJheW5vbGRzVGhpcyBpcyBhIENEQVRBU2VjdGlvbiB3aXRoIEVudGl0eVJlZmVyZW5jZSBudW1iZXIgMiAmYW1wO2VudDI7CitUaGlzIGlzIGFuIGFkamFjZW50IENEQVRBU2VjdGlvbiB3aXRoIGEgcmVmZXJlbmNlIHRvIGEgdGFiICZhbXA7dGFiOzwvc3Ryb25nPgorICA8Y29kZT5TZWNyZXRhcnk8L2NvZGU+CisgIDxzdXA+MzUsMDAwPC9zdXA+CisgIDx2YXI+RmVtYWxlPC92YXI+CisgIDxhY3JvbnltIHRpdGxlPSJZZXMiIGNsYXNzPSJZZXMiPiZiZXRhOyBEYWxsYXMsICZnYW1tYTsKKyA5ODU1NDwvYWNyb255bT4KKyA8L3A+CisgPHA+CisgIDxlbT5FTVAwMDAzPC9lbT4KKyAgPHN0cm9uZz5Sb2dlcgorIEpvbmVzPC9zdHJvbmc+CisgIDxjb2RlPkRlcGFydG1lbnQgTWFuYWdlcjwvY29kZT4KKyAgPHN1cD4xMDAsMDAwPC9zdXA+CisgIDx2YXI+JmRlbHRhOzwvdmFyPgorICA8YWNyb255bSB0aXRsZT0iWWVzIiBjbGFzcz0iTm8iPlBPIEJveCAyNyBJcnZpbmcsIHRleGFzIDk4NTUzPC9hY3JvbnltPgorIDwvcD4KKyA8cD4KKyAgPGVtPkVNUDAwMDQ8L2VtPgorICA8c3Ryb25nPkplbnkgT2Nvbm5vcjwvc3Ryb25nPgorICA8Y29kZT5QZXJzb25uZWwgRGlyZWN0b3I8L2NvZGU+CisgIDxzdXA+OTUsMDAwPC9zdXA+CisgIDx2YXI+RmVtYWxlPC92YXI+CisgIDxhY3JvbnltIHRpdGxlPSJZZXMiIGNsYXNzPSJZJmFscGhhOyI+MjcgU291dGggUm9hZC4gRGFsbGFzLCBUZXhhcyA5ODU1NjwvYWNyb255bT4KKyA8L3A+CisgPHA+CisgIDxlbT5FTVAwMDA1PC9lbT4KKyAgPHN0cm9uZz5Sb2JlcnQgTXllcnM8L3N0cm9uZz4KKyAgPGNvZGU+Q29tcHV0ZXIgU3BlY2lhbGlzdDwvY29kZT4KKyAgPHN1cD45MCwwMDA8L3N1cD4KKyAgPHZhcj5tYWxlPC92YXI+CisgIDxhY3JvbnltIHRpdGxlPSJZZXMiPjE4MjEgTm9yZGljLiBSb2FkLCBJcnZpbmcgVGV4YXMgOTg1NTg8L2Fjcm9ueW0+CisgPC9wPgorPC9ib2R5PjwvaHRtbD4KZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvaGNfc3RhZmYuc3ZnIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9oY19zdGFmZi5zdmcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2QwY2M0NwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvaGNfc3RhZmYuc3ZnCkBAIC0wLDAgKzEsNzIgQEAKKzw/eG1sIHZlcnNpb249IjEuMCI/Pjw/VEVTVC1TVFlMRSBQSURBVEE/PgorPCFET0NUWVBFIHN2ZworICAgUFVCTElDICItLy9XM0MvL0RURCBYSFRNTCAxLjAgU3RyaWN0Ly9FTiIKKyAgICJ4aHRtbDEtc3RyaWN0LmR0ZCIgWworICAgPCFFTlRJVFkgYWxwaGEgIiYjOTQ1OyI+CisgICA8IUVOVElUWSBiZXRhICImIzk0NjsiPgorICAgPCFFTlRJVFkgZ2FtbWEgIiYjOTQ3OyI+CisgICA8IUVOVElUWSBkZWx0YSAiJiM5NDg7Ij4KKyAgIDwhRU5USVRZIGVwc2lsb24gIiYjOTQ5OyI+CisgICA8IUVOVElUWSBhbHBoYSAiJiM5NTA7Ij4KKyAgIDwhTk9UQVRJT04gbm90YXRpb24xIFBVQkxJQyAibm90YXRpb24xRmlsZSI+CisgICA8IU5PVEFUSU9OIG5vdGF0aW9uMiBTWVNURU0gIm5vdGF0aW9uMkZpbGUiPgorICAgPCFBVFRMSVNUIGFjcm9ueW0gZGlyIENEQVRBICJsdHIiPgorICAgPCFBVFRMSVNUIGhlYWQgeG1sbnMgQ0RBVEEgI0lNUExJRUQ+CisgICA8IUFUVExJU1QgYm9keSB4bWxucyBDREFUQSAjSU1QTElFRD4KKyAgIDwhRUxFTUVOVCBzdmcgKHJlY3QsIHNjcmlwdCwgaGVhZCwgYm9keSk+CisgICA8IUFUVExJU1Qgc3ZnIHhtbG5zIENEQVRBICNJTVBMSUVEPgorICAgPCFFTEVNRU5UIHJlY3QgRU1QVFk+CisgICA8IUFUVExJU1QgcmVjdAorICAgICAgICB4IENEQVRBICNJTVBMSUVECisgICAgICAgIHkgQ0RBVEEgI0lNUExJRUQKKyAgICAgICAgd2lkdGggQ0RBVEEgI0lNUExJRUQKKyAgICAgICAgaGVpZ2h0IENEQVRBICNJTVBMSUVEPiAgICAgICAgCisgICA8IUVOVElUWSBzdmd1bml0IFNZU1RFTSAic3ZndW5pdC5qcyI+ICAgCisgICA8IUVOVElUWSBzdmd0ZXN0IFNZU1RFTSAic3ZndGVzdC5qcyI+ICAgCitdPgorPCEtLSBUaGlzIGlzIGNvbW1lbnQgbnVtYmVyIDEuLS0+Cis8c3ZnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiLz48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+JnN2Z3Rlc3Q7JnN2Z3VuaXQ7PC9zY3JpcHQ+PGhlYWQgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwnPjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04Ii8+PHRpdGxlPmhjX3N0YWZmPC90aXRsZT48L2hlYWQ+PGJvZHkgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwnPgorIDxwPgorICA8ZW0+RU1QMDAwMTwvZW0+CisgIDxzdHJvbmc+TWFyZ2FyZXQgTWFydGluPC9zdHJvbmc+CisgIDxjb2RlPkFjY291bnRhbnQ8L2NvZGU+ICAgICAgICAgICAKKyAgPHN1cD41NiwwMDA8L3N1cD4KKyAgPHZhcj5GZW1hbGU8L3Zhcj4KKyAgPGFjcm9ueW0gdGl0bGU9IlllcyI+MTIzMCBOb3J0aCBBdmUuIERhbGxhcywgVGV4YXMgOTg1NTE8L2Fjcm9ueW0+CisgPC9wPgorIDxwPgorICA8ZW0+RU1QMDAwMjwvZW0+CisgIDxzdHJvbmc+TWFydGhhIFJheW5vbGRzVGhpcyBpcyBhIENEQVRBU2VjdGlvbiB3aXRoIEVudGl0eVJlZmVyZW5jZSBudW1iZXIgMiAmYW1wO2VudDI7CitUaGlzIGlzIGFuIGFkamFjZW50IENEQVRBU2VjdGlvbiB3aXRoIGEgcmVmZXJlbmNlIHRvIGEgdGFiICZhbXA7dGFiOzwvc3Ryb25nPgorICA8Y29kZT5TZWNyZXRhcnk8L2NvZGU+CisgIDxzdXA+MzUsMDAwPC9zdXA+CisgIDx2YXI+RmVtYWxlPC92YXI+CisgIDxhY3JvbnltIHRpdGxlPSJZZXMiIGNsYXNzPSJZZXMiPiZiZXRhOyBEYWxsYXMsICZnYW1tYTsKKyA5ODU1NDwvYWNyb255bT4KKyA8L3A+CisgPHA+CisgIDxlbT5FTVAwMDAzPC9lbT4KKyAgPHN0cm9uZz5Sb2dlcgorIEpvbmVzPC9zdHJvbmc+CisgIDxjb2RlPkRlcGFydG1lbnQgTWFuYWdlcjwvY29kZT4KKyAgPHN1cD4xMDAsMDAwPC9zdXA+CisgIDx2YXI+JmRlbHRhOzwvdmFyPgorICA8YWNyb255bSB0aXRsZT0iWWVzIiBjbGFzcz0iTm8iPlBPIEJveCAyNyBJcnZpbmcsIHRleGFzIDk4NTUzPC9hY3JvbnltPgorIDwvcD4KKyA8cD4KKyAgPGVtPkVNUDAwMDQ8L2VtPgorICA8c3Ryb25nPkplbnkgT2Nvbm5vcjwvc3Ryb25nPgorICA8Y29kZT5QZXJzb25uZWwgRGlyZWN0b3I8L2NvZGU+CisgIDxzdXA+OTUsMDAwPC9zdXA+CisgIDx2YXI+RmVtYWxlPC92YXI+CisgIDxhY3JvbnltIHRpdGxlPSJZZXMiIGNsYXNzPSJZJmFscGhhOyI+MjcgU291dGggUm9hZC4gRGFsbGFzLCBUZXhhcyA5ODU1NjwvYWNyb255bT4KKyA8L3A+CisgPHA+CisgIDxlbT5FTVAwMDA1PC9lbT4KKyAgPHN0cm9uZz5Sb2JlcnQgTXllcnM8L3N0cm9uZz4KKyAgPGNvZGU+Q29tcHV0ZXIgU3BlY2lhbGlzdDwvY29kZT4KKyAgPHN1cD45MCwwMDA8L3N1cD4KKyAgPHZhcj5tYWxlPC92YXI+CisgIDxhY3JvbnltIHRpdGxlPSJZZXMiPjE4MjEgTm9yZGljLiBSb2FkLCBJcnZpbmcgVGV4YXMgOTg1NTg8L2Fjcm9ueW0+CisgPC9wPgorPC9ib2R5Pjwvc3ZnPgpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9oY19zdGFmZi54aHRtbCBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvaGNfc3RhZmYueGh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmRmOWE3NAotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvaGNfc3RhZmYueGh0bWwKQEAgLTAsMCArMSw2MCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIj8+PD9URVNULVNUWUxFIFBJREFUQT8+Cis8IURPQ1RZUEUgaHRtbAorICAgUFVCTElDICItLy9XM0MvL0RURCBYSFRNTCAxLjAgU3RyaWN0Ly9FTiIKKyAgICJ4aHRtbDEtc3RyaWN0LmR0ZCIgWworICAgPCFFTlRJVFkgYWxwaGEgIiYjOTQ1OyI+CisgICA8IUVOVElUWSBiZXRhICImIzk0NjsiPgorICAgPCFFTlRJVFkgZ2FtbWEgIiYjOTQ3OyI+CisgICA8IUVOVElUWSBkZWx0YSAiJiM5NDg7Ij4KKyAgIDwhRU5USVRZIGVwc2lsb24gIiYjOTQ5OyI+CisgICA8IUVOVElUWSBhbHBoYSAiJiM5NTA7Ij4KKyAgIDwhTk9UQVRJT04gbm90YXRpb24xIFBVQkxJQyAibm90YXRpb24xRmlsZSI+CisgICA8IU5PVEFUSU9OIG5vdGF0aW9uMiBTWVNURU0gIm5vdGF0aW9uMkZpbGUiPgorICAgPCFBVFRMSVNUIGFjcm9ueW0gZGlyIENEQVRBICJsdHIiPgorXT4KKzwhLS0gVGhpcyBpcyBjb21tZW50IG51bWJlciAxLi0tPgorPGh0bWwgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwnPjxoZWFkPjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04Ii8+PHRpdGxlPmhjX3N0YWZmPC90aXRsZT48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJzdmd1bml0LmpzIi8+PHNjcmlwdCBjaGFyc2V0PSJVVEYtOCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9InN2Z3Rlc3QuanMiLz48c2NyaXB0IHR5cGU9J3RleHQvamF2YXNjcmlwdCc+ZnVuY3Rpb24gbG9hZENvbXBsZXRlKCkgeyBzdGFydFRlc3QoKTsgfTwvc2NyaXB0PjwvaGVhZD48Ym9keSBvbmxvYWQ9InBhcmVudC5sb2FkQ29tcGxldGUoKSI+CisgPHA+CisgIDxlbT5FTVAwMDAxPC9lbT4KKyAgPHN0cm9uZz5NYXJnYXJldCBNYXJ0aW48L3N0cm9uZz4KKyAgPGNvZGU+QWNjb3VudGFudDwvY29kZT4gICAgICAgICAgIAorICA8c3VwPjU2LDAwMDwvc3VwPgorICA8dmFyPkZlbWFsZTwvdmFyPgorICA8YWNyb255bSB0aXRsZT0iWWVzIj4xMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyA5ODU1MTwvYWNyb255bT4KKyA8L3A+CisgPHA+CisgIDxlbT5FTVAwMDAyPC9lbT4KKyAgPHN0cm9uZz5NYXJ0aGEgUmF5bm9sZHNUaGlzIGlzIGEgQ0RBVEFTZWN0aW9uIHdpdGggRW50aXR5UmVmZXJlbmNlIG51bWJlciAyICZhbXA7ZW50MjsKK1RoaXMgaXMgYW4gYWRqYWNlbnQgQ0RBVEFTZWN0aW9uIHdpdGggYSByZWZlcmVuY2UgdG8gYSB0YWIgJmFtcDt0YWI7PC9zdHJvbmc+CisgIDxjb2RlPlNlY3JldGFyeTwvY29kZT4KKyAgPHN1cD4zNSwwMDA8L3N1cD4KKyAgPHZhcj5GZW1hbGU8L3Zhcj4KKyAgPGFjcm9ueW0gdGl0bGU9IlllcyIgY2xhc3M9IlllcyI+JmJldGE7IERhbGxhcywgJmdhbW1hOworIDk4NTU0PC9hY3JvbnltPgorIDwvcD4KKyA8cD4KKyAgPGVtPkVNUDAwMDM8L2VtPgorICA8c3Ryb25nPlJvZ2VyCisgSm9uZXM8L3N0cm9uZz4KKyAgPGNvZGU+RGVwYXJ0bWVudCBNYW5hZ2VyPC9jb2RlPgorICA8c3VwPjEwMCwwMDA8L3N1cD4KKyAgPHZhcj4mZGVsdGE7PC92YXI+CisgIDxhY3JvbnltIHRpdGxlPSJZZXMiIGNsYXNzPSJObyI+UE8gQm94IDI3IElydmluZywgdGV4YXMgOTg1NTM8L2Fjcm9ueW0+CisgPC9wPgorIDxwPgorICA8ZW0+RU1QMDAwNDwvZW0+CisgIDxzdHJvbmc+SmVueSBPY29ubm9yPC9zdHJvbmc+CisgIDxjb2RlPlBlcnNvbm5lbCBEaXJlY3RvcjwvY29kZT4KKyAgPHN1cD45NSwwMDA8L3N1cD4KKyAgPHZhcj5GZW1hbGU8L3Zhcj4KKyAgPGFjcm9ueW0gdGl0bGU9IlllcyIgY2xhc3M9IlkmYWxwaGE7Ij4yNyBTb3V0aCBSb2FkLiBEYWxsYXMsIFRleGFzIDk4NTU2PC9hY3JvbnltPgorIDwvcD4KKyA8cD4KKyAgPGVtPkVNUDAwMDU8L2VtPgorICA8c3Ryb25nPlJvYmVydCBNeWVyczwvc3Ryb25nPgorICA8Y29kZT5Db21wdXRlciBTcGVjaWFsaXN0PC9jb2RlPgorICA8c3VwPjkwLDAwMDwvc3VwPgorICA8dmFyPm1hbGU8L3Zhcj4KKyAgPGFjcm9ueW0gdGl0bGU9IlllcyI+MTgyMSBOb3JkaWMuIFJvYWQsIElydmluZyBUZXhhcyA5ODU1ODwvYWNyb255bT4KKyA8L3A+Cis8L2JvZHk+PC9odG1sPgpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9oY19zdGFmZi54bWwgYi9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL2hjX3N0YWZmLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZGY5YTc0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9oY19zdGFmZi54bWwKQEAgLTAsMCArMSw2MCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIj8+PD9URVNULVNUWUxFIFBJREFUQT8+Cis8IURPQ1RZUEUgaHRtbAorICAgUFVCTElDICItLy9XM0MvL0RURCBYSFRNTCAxLjAgU3RyaWN0Ly9FTiIKKyAgICJ4aHRtbDEtc3RyaWN0LmR0ZCIgWworICAgPCFFTlRJVFkgYWxwaGEgIiYjOTQ1OyI+CisgICA8IUVOVElUWSBiZXRhICImIzk0NjsiPgorICAgPCFFTlRJVFkgZ2FtbWEgIiYjOTQ3OyI+CisgICA8IUVOVElUWSBkZWx0YSAiJiM5NDg7Ij4KKyAgIDwhRU5USVRZIGVwc2lsb24gIiYjOTQ5OyI+CisgICA8IUVOVElUWSBhbHBoYSAiJiM5NTA7Ij4KKyAgIDwhTk9UQVRJT04gbm90YXRpb24xIFBVQkxJQyAibm90YXRpb24xRmlsZSI+CisgICA8IU5PVEFUSU9OIG5vdGF0aW9uMiBTWVNURU0gIm5vdGF0aW9uMkZpbGUiPgorICAgPCFBVFRMSVNUIGFjcm9ueW0gZGlyIENEQVRBICJsdHIiPgorXT4KKzwhLS0gVGhpcyBpcyBjb21tZW50IG51bWJlciAxLi0tPgorPGh0bWwgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwnPjxoZWFkPjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04Ii8+PHRpdGxlPmhjX3N0YWZmPC90aXRsZT48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJzdmd1bml0LmpzIi8+PHNjcmlwdCBjaGFyc2V0PSJVVEYtOCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9InN2Z3Rlc3QuanMiLz48c2NyaXB0IHR5cGU9J3RleHQvamF2YXNjcmlwdCc+ZnVuY3Rpb24gbG9hZENvbXBsZXRlKCkgeyBzdGFydFRlc3QoKTsgfTwvc2NyaXB0PjwvaGVhZD48Ym9keSBvbmxvYWQ9InBhcmVudC5sb2FkQ29tcGxldGUoKSI+CisgPHA+CisgIDxlbT5FTVAwMDAxPC9lbT4KKyAgPHN0cm9uZz5NYXJnYXJldCBNYXJ0aW48L3N0cm9uZz4KKyAgPGNvZGU+QWNjb3VudGFudDwvY29kZT4gICAgICAgICAgIAorICA8c3VwPjU2LDAwMDwvc3VwPgorICA8dmFyPkZlbWFsZTwvdmFyPgorICA8YWNyb255bSB0aXRsZT0iWWVzIj4xMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyA5ODU1MTwvYWNyb255bT4KKyA8L3A+CisgPHA+CisgIDxlbT5FTVAwMDAyPC9lbT4KKyAgPHN0cm9uZz5NYXJ0aGEgUmF5bm9sZHNUaGlzIGlzIGEgQ0RBVEFTZWN0aW9uIHdpdGggRW50aXR5UmVmZXJlbmNlIG51bWJlciAyICZhbXA7ZW50MjsKK1RoaXMgaXMgYW4gYWRqYWNlbnQgQ0RBVEFTZWN0aW9uIHdpdGggYSByZWZlcmVuY2UgdG8gYSB0YWIgJmFtcDt0YWI7PC9zdHJvbmc+CisgIDxjb2RlPlNlY3JldGFyeTwvY29kZT4KKyAgPHN1cD4zNSwwMDA8L3N1cD4KKyAgPHZhcj5GZW1hbGU8L3Zhcj4KKyAgPGFjcm9ueW0gdGl0bGU9IlllcyIgY2xhc3M9IlllcyI+JmJldGE7IERhbGxhcywgJmdhbW1hOworIDk4NTU0PC9hY3JvbnltPgorIDwvcD4KKyA8cD4KKyAgPGVtPkVNUDAwMDM8L2VtPgorICA8c3Ryb25nPlJvZ2VyCisgSm9uZXM8L3N0cm9uZz4KKyAgPGNvZGU+RGVwYXJ0bWVudCBNYW5hZ2VyPC9jb2RlPgorICA8c3VwPjEwMCwwMDA8L3N1cD4KKyAgPHZhcj4mZGVsdGE7PC92YXI+CisgIDxhY3JvbnltIHRpdGxlPSJZZXMiIGNsYXNzPSJObyI+UE8gQm94IDI3IElydmluZywgdGV4YXMgOTg1NTM8L2Fjcm9ueW0+CisgPC9wPgorIDxwPgorICA8ZW0+RU1QMDAwNDwvZW0+CisgIDxzdHJvbmc+SmVueSBPY29ubm9yPC9zdHJvbmc+CisgIDxjb2RlPlBlcnNvbm5lbCBEaXJlY3RvcjwvY29kZT4KKyAgPHN1cD45NSwwMDA8L3N1cD4KKyAgPHZhcj5GZW1hbGU8L3Zhcj4KKyAgPGFjcm9ueW0gdGl0bGU9IlllcyIgY2xhc3M9IlkmYWxwaGE7Ij4yNyBTb3V0aCBSb2FkLiBEYWxsYXMsIFRleGFzIDk4NTU2PC9hY3JvbnltPgorIDwvcD4KKyA8cD4KKyAgPGVtPkVNUDAwMDU8L2VtPgorICA8c3Ryb25nPlJvYmVydCBNeWVyczwvc3Ryb25nPgorICA8Y29kZT5Db21wdXRlciBTcGVjaWFsaXN0PC9jb2RlPgorICA8c3VwPjkwLDAwMDwvc3VwPgorICA8dmFyPm1hbGU8L3Zhcj4KKyAgPGFjcm9ueW0gdGl0bGU9IlllcyI+MTgyMSBOb3JkaWMuIFJvYWQsIElydmluZyBUZXhhcyA5ODU1ODwvYWNyb255bT4KKyA8L3A+Cis8L2JvZHk+PC9odG1sPgpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9pbnRlcm5hbFN1YnNldDAxLmpzIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9pbnRlcm5hbFN1YnNldDAxLmpzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2OWRlMjkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL2ludGVybmFsU3Vic2V0MDEuanMKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvbm9kdGRzdGFmZi5zdmcgYi9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL25vZHRkc3RhZmYuc3ZnCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAxYWE4MjMKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL25vZHRkc3RhZmYuc3ZnCkBAIC0wLDAgKzEsMTEgQEAKKzw/eG1sIHZlcnNpb249IjEuMCI/PgorPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIi8+CisgPGVtcGxveWVlIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL0xldmVsLTEvRmlsZXMiPgorICA8ZW1wbG95ZWVJZD5FTVAwMDAxPC9lbXBsb3llZUlkPgorICA8bmFtZT5NYXJnYXJldCBNYXJ0aW48L25hbWU+CisgIDxwb3NpdGlvbj5BY2NvdW50YW50PC9wb3NpdGlvbj4gICAgICAgICAgIAorICA8c2FsYXJ5PjU2LDAwMDwvc2FsYXJ5PgorICA8Z2VuZGVyPkZlbWFsZTwvZ2VuZGVyPgorICA8YWRkcmVzcyBkb21lc3RpYz0iWWVzIj4xMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyA5ODU1MTwvYWRkcmVzcz4KKyA8L2VtcGxveWVlPgorPC9zdmc+CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL25vZHRkc3RhZmYueG1sIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9ub2R0ZHN0YWZmLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNTRhNWUxCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9ub2R0ZHN0YWZmLnhtbApAQCAtMCwwICsxLDExIEBACis8P3htbCB2ZXJzaW9uPSIxLjAiPz4KKzxzdGFmZj4KKyA8ZW1wbG95ZWU+CisgIDxlbXBsb3llZUlkPkVNUDAwMDE8L2VtcGxveWVlSWQ+CisgIDxuYW1lPk1hcmdhcmV0IE1hcnRpbjwvbmFtZT4KKyAgPHBvc2l0aW9uPkFjY291bnRhbnQ8L3Bvc2l0aW9uPiAgICAgICAgICAgCisgIDxzYWxhcnk+NTYsMDAwPC9zYWxhcnk+CisgIDxnZW5kZXI+RmVtYWxlPC9nZW5kZXI+CisgIDxhZGRyZXNzIGRvbWVzdGljPSJZZXMiPjEyMzAgTm9ydGggQXZlLiBEYWxsYXMsIFRleGFzIDk4NTUxPC9hZGRyZXNzPgorIDwvZW1wbG95ZWU+Cis8L3N0YWZmPgpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9zdGFmZi5kdGQgYi9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL3N0YWZmLmR0ZApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMmE5OTRkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9zdGFmZi5kdGQKQEAgLTAsMCArMSwxNyBAQAorPCFFTEVNRU5UIGVtcGxveWVlSWQgKCNQQ0RBVEEpPgorPCFFTEVNRU5UIG5hbWUgKCNQQ0RBVEEpPgorPCFFTEVNRU5UIHBvc2l0aW9uICgjUENEQVRBKT4KKzwhRUxFTUVOVCBzYWxhcnkgKCNQQ0RBVEEpPgorPCFFTEVNRU5UIGFkZHJlc3MgKCNQQ0RBVEEpPgorPCFFTEVNRU5UIGVudEVsZW1lbnQgKCAjUENEQVRBICkgPgorPCFFTEVNRU5UIGdlbmRlciAoICNQQ0RBVEEgfCBlbnRFbGVtZW50ICkqID4KKzwhRUxFTUVOVCBlbXBsb3llZSAoZW1wbG95ZWVJZCwgbmFtZSwgcG9zaXRpb24sIHNhbGFyeSwgZ2VuZGVyLCBhZGRyZXNzKSA+Cis8IUVMRU1FTlQgc3RhZmYgKGVtcGxveWVlKSs+Cis8IUFUVExJU1QgZW50RWxlbWVudCAKKyAgICAgICAgICBhdHRyMSBDREFUQSAiQXR0ciI+Cis8IUFUVExJU1QgYWRkcmVzcworICAgICAgICAgIGRvbWVzdGljIENEQVRBICNJTVBMSUVEIAorICAgICAgICAgIHN0cmVldCBDREFUQSAiWWVzIj4KKzwhQVRUTElTVCBlbnRFbGVtZW50IAorICAgICAgICAgIGRvbWVzdGljIENEQVRBICJNQUxFIiA+CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvc3RhZmYuc3ZnIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9zdGFmZi5zdmcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmQ2NzMyMwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvc3RhZmYuc3ZnCkBAIC0wLDAgKzEsNzIgQEAKKzw/eG1sIHZlcnNpb249IjEuMCI/Pjw/VEVTVC1TVFlMRSBQSURBVEE/PgorPCFET0NUWVBFIHN2ZyBTWVNURU0gInN0YWZmLmR0ZCIgWworICAgPCFFTlRJVFkgZW50MSAiZXMiPgorICAgPCFFTlRJVFkgZW50MiAiMTkwMCBEYWxsYXMgUm9hZCI+CisgICA8IUVOVElUWSBlbnQzICJUZXhhcyI+CisgICA8IUVOVElUWSBlbnQ0ICI8ZW50RWxlbWVudCBkb21lc3RpYz0nWWVzJz5FbGVtZW50IGRhdGE8L2VudEVsZW1lbnQ+PD9QSXRhcmdldCBQSWRhdGE/PiI+CisgICA8IUVOVElUWSBlbnQ1IFBVQkxJQyAiZW50aXR5VVJJIiAiZW50aXR5RmlsZSIgTkRBVEEgbm90YXRpb24xPgorICAgPCFFTlRJVFkgZW50MSAiVGhpcyBlbnRpdHkgc2hvdWxkIGJlIGRpc2NhcmRlZCI+CisgICA8IU5PVEFUSU9OIG5vdGF0aW9uMSBQVUJMSUMgIm5vdGF0aW9uMUZpbGUiPgorICAgPCFOT1RBVElPTiBub3RhdGlvbjIgU1lTVEVNICJub3RhdGlvbjJGaWxlIj4KKyAgIDwhQVRUTElTVCBlbXBsb3llZSB4bWxucyBDREFUQSAjSU1QTElFRD4KKyAgIDwhRUxFTUVOVCBzdmcgKHJlY3QsIHNjcmlwdCwgZW1wbG95ZWUrKT4KKyAgIDwhQVRUTElTVCBzdmcgCisgICAgICB4bWxucyBDREFUQSAjRklYRUQgImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgorICAgICAgbmFtZSBDREFUQSAjSU1QTElFRD4KKyAgIDwhRUxFTUVOVCByZWN0IEVNUFRZPgorICAgPCFBVFRMSVNUIHJlY3QgCisgICAgICB4IENEQVRBICNSRVFVSVJFRAorICAgICAgeSBDREFUQSAjUkVRVUlSRUQKKyAgICAgIHdpZHRoIENEQVRBICNSRVFVSVJFRAorICAgICAgaGVpZ2h0IENEQVRBICNSRVFVSVJFRD4KKyAgPCFFTEVNRU5UIHNjcmlwdCAoI1BDREFUQSk+CisgIDwhQVRUTElTVCBzY3JpcHQgdHlwZSBDREFUQSAjSU1QTElFRD4gICAgICAKKyAgPCFFTlRJVFkgc3ZndW5pdCBTWVNURU0gInN2Z3VuaXQuanMiPgorICA8IUVOVElUWSBzdmd0ZXN0IFNZU1RFTSAic3ZndGVzdC5qcyI+CitdPgorPCEtLSBUaGlzIGlzIGNvbW1lbnQgbnVtYmVyIDEuLS0+Cis8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiLz48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+JnN2Z3Rlc3Q7JnN2Z3VuaXQ7PC9zY3JpcHQ+CisgPGVtcGxveWVlIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL0xldmVsLTEvRmlsZXMiPgorICA8ZW1wbG95ZWVJZD5FTVAwMDAxPC9lbXBsb3llZUlkPgorICA8bmFtZT5NYXJnYXJldCBNYXJ0aW48L25hbWU+CisgIDxwb3NpdGlvbj5BY2NvdW50YW50PC9wb3NpdGlvbj4gICAgICAgICAgIAorICA8c2FsYXJ5PjU2LDAwMDwvc2FsYXJ5PgorICA8Z2VuZGVyPkZlbWFsZTwvZ2VuZGVyPgorICA8YWRkcmVzcyBkb21lc3RpYz0iWWVzIj4xMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyA5ODU1MTwvYWRkcmVzcz4KKyA8L2VtcGxveWVlPgorIDxlbXBsb3llZSB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9MZXZlbC0xL0ZpbGVzIj4KKyAgPGVtcGxveWVlSWQ+RU1QMDAwMjwvZW1wbG95ZWVJZD4KKyAgPG5hbWU+TWFydGhhIFJheW5vbGRzPCFbQ0RBVEFbVGhpcyBpcyBhIENEQVRBU2VjdGlvbiB3aXRoIEVudGl0eVJlZmVyZW5jZSBudW1iZXIgMiAmZW50MjtdXT4KKzwhW0NEQVRBW1RoaXMgaXMgYW4gYWRqYWNlbnQgQ0RBVEFTZWN0aW9uIHdpdGggYSByZWZlcmVuY2UgdG8gYSB0YWIgJnRhYjtdXT48L25hbWU+CisgIDxwb3NpdGlvbj5TZWNyZXRhcnk8L3Bvc2l0aW9uPgorICA8c2FsYXJ5PjM1LDAwMDwvc2FsYXJ5PgorICA8Z2VuZGVyPkZlbWFsZTwvZ2VuZGVyPgorICA8YWRkcmVzcyBkb21lc3RpYz0iWWVzIiBzdHJlZXQ9IlllcyI+JmVudDI7IERhbGxhcywgJmVudDM7CisgOTg1NTQ8L2FkZHJlc3M+CisgPC9lbXBsb3llZT4KKyA8ZW1wbG95ZWUgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvTGV2ZWwtMS9GaWxlcyI+CisgIDxlbXBsb3llZUlkPkVNUDAwMDM8L2VtcGxveWVlSWQ+CisgIDxuYW1lPlJvZ2VyCisgSm9uZXM8L25hbWU+CisgIDxwb3NpdGlvbj5EZXBhcnRtZW50IE1hbmFnZXI8L3Bvc2l0aW9uPgorICA8c2FsYXJ5PjEwMCwwMDA8L3NhbGFyeT4KKyAgPGdlbmRlcj4mZW50NDs8L2dlbmRlcj4KKyAgPGFkZHJlc3MgZG9tZXN0aWM9IlllcyIgc3RyZWV0PSJObyI+UE8gQm94IDI3IElydmluZywgdGV4YXMgOTg1NTM8L2FkZHJlc3M+CisgPC9lbXBsb3llZT4KKyA8ZW1wbG95ZWUgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvTGV2ZWwtMS9GaWxlcyI+CisgIDxlbXBsb3llZUlkPkVNUDAwMDQ8L2VtcGxveWVlSWQ+CisgIDxuYW1lPkplbnkgT2Nvbm5vcjwvbmFtZT4KKyAgPHBvc2l0aW9uPlBlcnNvbm5lbCBEaXJlY3RvcjwvcG9zaXRpb24+CisgIDxzYWxhcnk+OTUsMDAwPC9zYWxhcnk+CisgIDxnZW5kZXI+RmVtYWxlPC9nZW5kZXI+CisgIDxhZGRyZXNzIGRvbWVzdGljPSJZZXMiIHN0cmVldD0iWSZlbnQxOyI+MjcgU291dGggUm9hZC4gRGFsbGFzLCBUZXhhcyA5ODU1NjwvYWRkcmVzcz4KKyA8L2VtcGxveWVlPgorIDxlbXBsb3llZSB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9ET00tVGVzdC1TdWl0ZS9MZXZlbC0xL0ZpbGVzIj4KKyAgPGVtcGxveWVlSWQ+RU1QMDAwNTwvZW1wbG95ZWVJZD4KKyAgPG5hbWU+Um9iZXJ0IE15ZXJzPC9uYW1lPgorICA8cG9zaXRpb24+Q29tcHV0ZXIgU3BlY2lhbGlzdDwvcG9zaXRpb24+CisgIDxzYWxhcnk+OTAsMDAwPC9zYWxhcnk+CisgIDxnZW5kZXI+bWFsZTwvZ2VuZGVyPgorICA8YWRkcmVzcyBzdHJlZXQ9IlllcyI+MTgyMSBOb3JkaWMuIFJvYWQsIElydmluZyBUZXhhcyA5ODU1ODwvYWRkcmVzcz4KKyA8L2VtcGxveWVlPgorIDwvc3ZnPgpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9zdGFmZi54bWwgYi9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL3N0YWZmLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mODljNTEwCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9zdGFmZi54bWwKQEAgLTAsMCArMSw1NyBAQAorPD94bWwgdmVyc2lvbj0iMS4wIj8+PD9URVNULVNUWUxFIFBJREFUQT8+Cis8IURPQ1RZUEUgc3RhZmYgU1lTVEVNICJzdGFmZi5kdGQiIFsKKyAgIDwhRU5USVRZIGVudDEgImVzIj4KKyAgIDwhRU5USVRZIGVudDIgIjE5MDAgRGFsbGFzIFJvYWQiPgorICAgPCFFTlRJVFkgZW50MyAiVGV4YXMiPgorICAgPCFFTlRJVFkgZW50NCAiPGVudEVsZW1lbnQgZG9tZXN0aWM9J1llcyc+RWxlbWVudCBkYXRhPC9lbnRFbGVtZW50Pjw/UEl0YXJnZXQgUElkYXRhPz4iPgorICAgPCFFTlRJVFkgZW50NSBQVUJMSUMgImVudGl0eVVSSSIgImVudGl0eUZpbGUiIE5EQVRBIG5vdGF0aW9uMT4KKyAgIDwhRU5USVRZIGVudDEgIlRoaXMgZW50aXR5IHNob3VsZCBiZSBkaXNjYXJkZWQiPgorICAgPCFOT1RBVElPTiBub3RhdGlvbjEgUFVCTElDICJub3RhdGlvbjFGaWxlIj4KKyAgIDwhTk9UQVRJT04gbm90YXRpb24yIFNZU1RFTSAibm90YXRpb24yRmlsZSI+CitdPgorPCEtLSBUaGlzIGlzIGNvbW1lbnQgbnVtYmVyIDEuLS0+Cis8c3RhZmY+CisgPGVtcGxveWVlPgorICA8ZW1wbG95ZWVJZD5FTVAwMDAxPC9lbXBsb3llZUlkPgorICA8bmFtZT5NYXJnYXJldCBNYXJ0aW48L25hbWU+CisgIDxwb3NpdGlvbj5BY2NvdW50YW50PC9wb3NpdGlvbj4gICAgICAgICAgIAorICA8c2FsYXJ5PjU2LDAwMDwvc2FsYXJ5PgorICA8Z2VuZGVyPkZlbWFsZTwvZ2VuZGVyPgorICA8YWRkcmVzcyBkb21lc3RpYz0iWWVzIj4xMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyA5ODU1MTwvYWRkcmVzcz4KKyA8L2VtcGxveWVlPgorIDxlbXBsb3llZT4KKyAgPGVtcGxveWVlSWQ+RU1QMDAwMjwvZW1wbG95ZWVJZD4KKyAgPG5hbWU+TWFydGhhIFJheW5vbGRzPCFbQ0RBVEFbVGhpcyBpcyBhIENEQVRBU2VjdGlvbiB3aXRoIEVudGl0eVJlZmVyZW5jZSBudW1iZXIgMiAmZW50MjtdXT4KKzwhW0NEQVRBW1RoaXMgaXMgYW4gYWRqYWNlbnQgQ0RBVEFTZWN0aW9uIHdpdGggYSByZWZlcmVuY2UgdG8gYSB0YWIgJnRhYjtdXT48L25hbWU+CisgIDxwb3NpdGlvbj5TZWNyZXRhcnk8L3Bvc2l0aW9uPgorICA8c2FsYXJ5PjM1LDAwMDwvc2FsYXJ5PgorICA8Z2VuZGVyPkZlbWFsZTwvZ2VuZGVyPgorICA8YWRkcmVzcyBkb21lc3RpYz0iWWVzIiBzdHJlZXQ9IlllcyI+JmVudDI7IERhbGxhcywgJmVudDM7CisgOTg1NTQ8L2FkZHJlc3M+CisgPC9lbXBsb3llZT4KKyA8ZW1wbG95ZWU+CisgIDxlbXBsb3llZUlkPkVNUDAwMDM8L2VtcGxveWVlSWQ+CisgIDxuYW1lPlJvZ2VyCisgSm9uZXM8L25hbWU+CisgIDxwb3NpdGlvbj5EZXBhcnRtZW50IE1hbmFnZXI8L3Bvc2l0aW9uPgorICA8c2FsYXJ5PjEwMCwwMDA8L3NhbGFyeT4KKyAgPGdlbmRlcj4mZW50NDs8L2dlbmRlcj4KKyAgPGFkZHJlc3MgZG9tZXN0aWM9IlllcyIgc3RyZWV0PSJObyI+UE8gQm94IDI3IElydmluZywgdGV4YXMgOTg1NTM8L2FkZHJlc3M+CisgPC9lbXBsb3llZT4KKyA8ZW1wbG95ZWU+CisgIDxlbXBsb3llZUlkPkVNUDAwMDQ8L2VtcGxveWVlSWQ+CisgIDxuYW1lPkplbnkgT2Nvbm5vcjwvbmFtZT4KKyAgPHBvc2l0aW9uPlBlcnNvbm5lbCBEaXJlY3RvcjwvcG9zaXRpb24+CisgIDxzYWxhcnk+OTUsMDAwPC9zYWxhcnk+CisgIDxnZW5kZXI+RmVtYWxlPC9nZW5kZXI+CisgIDxhZGRyZXNzIGRvbWVzdGljPSJZZXMiIHN0cmVldD0iWSZlbnQxOyI+MjcgU291dGggUm9hZC4gRGFsbGFzLCBUZXhhcyA5ODU1NjwvYWRkcmVzcz4KKyA8L2VtcGxveWVlPgorIDxlbXBsb3llZT4KKyAgPGVtcGxveWVlSWQ+RU1QMDAwNTwvZW1wbG95ZWVJZD4KKyAgPG5hbWU+Um9iZXJ0IE15ZXJzPC9uYW1lPgorICA8cG9zaXRpb24+Q29tcHV0ZXIgU3BlY2lhbGlzdDwvcG9zaXRpb24+CisgIDxzYWxhcnk+OTAsMDAwPC9zYWxhcnk+CisgIDxnZW5kZXI+bWFsZTwvZ2VuZGVyPgorICA8YWRkcmVzcyBzdHJlZXQ9IlllcyI+MTgyMSBOb3JkaWMuIFJvYWQsIElydmluZyBUZXhhcyA5ODU1ODwvYWRkcmVzcz4KKyA8L2VtcGxveWVlPgorIDwvc3RhZmY+CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL3N0YWZmMi5kdGQgYi9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL3N0YWZmMi5kdGQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGJhYzhmMgotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvc3RhZmYyLmR0ZApAQCAtMCwwICsxLDI0IEBACis8IUVMRU1FTlQgZW1wbG95ZWVJZCAoI1BDREFUQSk+Cis8IUVMRU1FTlQgbmFtZSAoI1BDREFUQSk+Cis8IUVMRU1FTlQgcG9zaXRpb24gKCNQQ0RBVEEpPgorPCFFTEVNRU5UIHNhbGFyeSAoI1BDREFUQSk+Cis8IUVMRU1FTlQgYWRkcmVzcyAoI1BDREFUQSk+Cis8IUVMRU1FTlQgZ2VuZGVyICggI1BDREFUQSk+Cis8IUVMRU1FTlQgZW1wbG95ZWUgKGVtcGxveWVlSWQsIG5hbWUsIHBvc2l0aW9uLCBzYWxhcnksIGdlbmRlciwgYWRkcmVzcykgPgorPCFBVFRMSVNUIGVtcGxveWVlIHhtbG5zIENEQVRBICNJTVBMSUVEPgorPCFFTEVNRU5UIHN0YWZmIChlbXBsb3llZSkrPgorPCFFTEVNRU5UIHN2ZyAocmVjdCwgc2NyaXB0LCBlbXBsb3llZSspPgorPCFBVFRMSVNUIHN2ZyAKKyAgICAgIHhtbG5zIENEQVRBICNGSVhFRCAiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCisgICAgICBuYW1lIENEQVRBICNJTVBMSUVEPgorPCFFTEVNRU5UIHJlY3QgRU1QVFk+Cis8IUFUVExJU1QgcmVjdCAKKyAgICAgIHggQ0RBVEEgI1JFUVVJUkVECisgICAgICB5IENEQVRBICNSRVFVSVJFRAorICAgICAgd2lkdGggQ0RBVEEgI1JFUVVJUkVECisgICAgICBoZWlnaHQgQ0RBVEEgI1JFUVVJUkVEPgorPCFFTEVNRU5UIHNjcmlwdCAoI1BDREFUQSk+Cis8IUFUVExJU1Qgc2NyaXB0IHR5cGUgQ0RBVEEgI0lNUExJRUQ+ICAgICAgCis8IUVOVElUWSBzdmd1bml0IFNZU1RFTSAic3ZndW5pdC5qcyI+Cis8IUVOVElUWSBzdmd0ZXN0IFNZU1RFTSAiaW50ZXJuYWxTdWJzZXQwMS5qcyI+CisKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvc3RhZmYyLnN2ZyBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvc3RhZmYyLnN2ZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42Zjg5ZGFkCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9zdGFmZjIuc3ZnCkBAIC0wLDAgKzEsMTMgQEAKKzw/eG1sIHZlcnNpb249IjEuMCI/Pjw/VEVTVC1TVFlMRSBQSURBVEE/Pg0KKzwhRE9DVFlQRSBzdmcgU1lTVEVNICJzdGFmZjIuZHRkIiBbXT4NCis8IS0tIFRoaXMgaXMgY29tbWVudCBudW1iZXIgMS4tLT4NCis8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiLz48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+JnN2Z3Rlc3Q7JnN2Z3VuaXQ7PC9zY3JpcHQ+DQorIDxlbXBsb3llZSB4bWxucz0iaHR0cDovL3d3dy5leGFtcGxlLmNvbSI+DQorICA8ZW1wbG95ZWVJZD5FTVAwMDAxPC9lbXBsb3llZUlkPg0KKyAgPG5hbWU+TWFyZ2FyZXQgTWFydGluPC9uYW1lPg0KKyAgPHBvc2l0aW9uPkFjY291bnRhbnQ8L3Bvc2l0aW9uPiAgICAgICAgICAgDQorICA8c2FsYXJ5PjU2LDAwMDwvc2FsYXJ5Pg0KKyAgPGdlbmRlcj5GZW1hbGU8L2dlbmRlcj4NCisgIDxhZGRyZXNzPjEyMzAgTm9ydGggQXZlLiBEYWxsYXMsIFRleGFzIDk4NTUxPC9hZGRyZXNzPg0KKyA8L2VtcGxveWVlPg0KKyA8L3N2Zz4NCmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL3N0YWZmMi54bWwgYi9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL3N0YWZmMi54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDNkOWExMwotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvc3RhZmYyLnhtbApAQCAtMCwwICsxLDEzIEBACis8P3htbCB2ZXJzaW9uPSIxLjAiPz48P1RFU1QtU1RZTEUgUElEQVRBPz4KKzwhRE9DVFlQRSBzdGFmZiBTWVNURU0gInN0YWZmMi5kdGQiIFtdPgorPCEtLSBUaGlzIGlzIGNvbW1lbnQgbnVtYmVyIDEuLS0+Cis8c3RhZmY+CisgPGVtcGxveWVlPgorICA8ZW1wbG95ZWVJZD5FTVAwMDAxPC9lbXBsb3llZUlkPgorICA8bmFtZT5NYXJnYXJldCBNYXJ0aW48L25hbWU+CisgIDxwb3NpdGlvbj5BY2NvdW50YW50PC9wb3NpdGlvbj4gICAgICAgICAgIAorICA8c2FsYXJ5PjU2LDAwMDwvc2FsYXJ5PgorICA8Z2VuZGVyPkZlbWFsZTwvZ2VuZGVyPgorICA8YWRkcmVzcz4xMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyA5ODU1MTwvYWRkcmVzcz4KKyA8L2VtcGxveWVlPgorIDwvc3RhZmY+CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL3N0YWZmTlMuZHRkIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9zdGFmZk5TLmR0ZApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NjQzNzczCi0tLSAvZGV2L251bGwKKysrIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9zdGFmZk5TLmR0ZApAQCAtMCwwICsxLDQ1IEBACis8IUVMRU1FTlQgc3RhZmYgKGVtcGxveWVlKyxlbXA6ZW1wbG95ZWUsZW1wbG95ZWUpID4KKzwhRUxFTUVOVCBlbXBsb3llZSAoZW1wbG95ZWVJZCxuYW1lLHBvc2l0aW9uLHNhbGFyeSxnZW5kZXIsYWRkcmVzcykgPgorPCFBVFRMSVNUIGVtcGxveWVlIHhtbG5zIENEQVRBICNJTVBMSUVEPgorPCFBVFRMSVNUIGVtcGxveWVlIHhtbG5zOmRtc3RjIENEQVRBICNJTVBMSUVEPgorPCFBVFRMSVNUIGVtcGxveWVlIHhtbG5zOmVtcDIgQ0RBVEEgI0lNUExJRUQ+CisKKzwhRUxFTUVOVCBlbXBsb3llZUlkICgjUENEQVRBKSA+CisKKzwhRUxFTUVOVCBuYW1lICgjUENEQVRBKSA+CisKKzwhRUxFTUVOVCBwb3NpdGlvbiAoI1BDREFUQSkgPgorCis8IUVMRU1FTlQgc2FsYXJ5ICgjUENEQVRBKSA+CisKKzwhRUxFTUVOVCBlbnRFbGVtZW50MSAoI1BDREFUQSkgPgorPCFFTEVNRU5UIGdlbmRlciAoI1BDREFUQSB8IGVudEVsZW1lbnQxKSogPgorPCFBVFRMSVNUIGVudEVsZW1lbnQxIHhtbG5zOmxvY2FsMSBDREFUQSAjSU1QTElFRCA+CisKKzwhRUxFTUVOVCBhZGRyZXNzICgjUENEQVRBKSA+Cis8IUFUVExJU1QgYWRkcmVzcyBkbXN0Yzpkb21lc3RpYyBDREFUQSAjSU1QTElFRD4KKzwhQVRUTElTVCBhZGRyZXNzIHN0cmVldCBDREFUQSAjSU1QTElFRD4KKzwhQVRUTElTVCBhZGRyZXNzIGRvbWVzdGljIENEQVRBICNJTVBMSUVEPgorPCFBVFRMSVNUIGFkZHJlc3MgeG1sbnMgQ0RBVEEgI0lNUExJRUQ+CisKKzwhRUxFTUVOVCBlbXA6ZW1wbG95ZWUgKGVtcDplbXBsb3llZUlkLG5tOm5hbWUsZW1wOnBvc2l0aW9uLGVtcDpzYWxhcnksZW1wOmdlbmRlcixlbXA6YWRkcmVzcykgPgorPCFBVFRMSVNUIGVtcDplbXBsb3llZSB4bWxuczplbXAgQ0RBVEEgI0lNUExJRUQ+Cis8IUFUVExJU1QgZW1wOmVtcGxveWVlIHhtbG5zOm5tIENEQVRBICNJTVBMSUVEPgorPCFBVFRMSVNUIGVtcDplbXBsb3llZSBkZWZhdWx0QXR0ciBDREFUQSAnZGVmYXVsdFZhbCc+CisKKzwhRUxFTUVOVCBlbXA6ZW1wbG95ZWVJZCAoI1BDREFUQSkgPgorCis8IUVMRU1FTlQgbm06bmFtZSAoI1BDREFUQSkgPgorCis8IUVMRU1FTlQgZW1wOnBvc2l0aW9uICgjUENEQVRBKSA+CisKKzwhRUxFTUVOVCBlbXA6c2FsYXJ5ICgjUENEQVRBKSA+CisKKzwhRUxFTUVOVCBlbXA6Z2VuZGVyICgjUENEQVRBKSA+CisKKzwhRUxFTUVOVCBlbXA6YWRkcmVzcyAoI1BDREFUQSkgPgorPCFBVFRMSVNUIGVtcDphZGRyZXNzIGVtcDpkb21lc3RpYyBDREFUQSAjSU1QTElFRD4KKzwhQVRUTElTVCBlbXA6YWRkcmVzcyBzdHJlZXQgQ0RBVEEgI0lNUExJRUQ+Cis8IUFUVExJU1QgZW1wOmFkZHJlc3MgZW1wOnpvbmUgSUQgI0lNUExJRUQ+Cis8IUFUVExJU1QgZW1wOmFkZHJlc3MgZW1wOmRpc3RyaWN0IENEQVRBICdESVNUUklDVCc+Cis8IUFUVExJU1QgZW1wOmFkZHJlc3MgZW1wOmxvY2FsMSBDREFUQSAnRkFMU0UnPgpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9zdGFmZk5TLnN2ZyBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvc3RhZmZOUy5zdmcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2E3YzI2ZQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvc3RhZmZOUy5zdmcKQEAgLTAsMCArMSw3MyBAQAorPD94bWwgdmVyc2lvbj0iMS4wIj8+PD9URVNULVNUWUxFIFBJREFUQT8+Cis8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiU1RBRkYiICJzdGFmZk5TLmR0ZCIgCitbCisgICA8IUVOVElUWSBlbnQxICJlcyI+CisgICA8IUVOVElUWSBlbnQyICIxOTAwIERhbGxhcyBSb2FkIj4KKyAgIDwhRU5USVRZIGVudDMgIlRleGFzIj4KKyAgIDwhRU5USVRZIGVudDQgIjxlbnRFbGVtZW50MSB4bWxuczpsb2NhbDE9J3d3dy54eXouY29tJz5FbGVtZW50IGRhdGE8L2VudEVsZW1lbnQxPjw/UEl0YXJnZXQgUElkYXRhPz4iPgorICAgPCFFTlRJVFkgZW50NSBQVUJMSUMgImVudGl0eVVSSSIgImVudGl0eUZpbGUiIE5EQVRBIG5vdGF0aW9uMT4KKyAgIDwhRU5USVRZIGVudDYgUFVCTElDICJ1cmkiICJmaWxlIiBOREFUQSBub3RhdGlvbjI+CisgICA8IUVOVElUWSBlbnQxICJUaGlzIGVudGl0eSBzaG91bGQgYmUgZGlzY2FyZGVkIj4KKyAgIDwhTk9UQVRJT04gbm90YXRpb24xIFBVQkxJQyAibm90YXRpb24xRmlsZSI+CisgICA8IU5PVEFUSU9OIG5vdGF0aW9uMiBTWVNURU0gIm5vdGF0aW9uMkZpbGUiPgorICAgPCFFTEVNRU5UIHN2ZyAocmVjdCwgc2NyaXB0LCBlbXBsb3llZSssIGVtcDplbXBsb3llZSwgZW1wbG95ZWUqKT4KKyAgIDwhQVRUTElTVCBzdmcgCisgICAgICB4bWxucyBDREFUQSAjRklYRUQgImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgorICAgICAgbmFtZSBDREFUQSAjSU1QTElFRD4KKyAgIDwhRUxFTUVOVCByZWN0IEVNUFRZPgorICAgPCFBVFRMSVNUIHJlY3QgCisgICAgICB4IENEQVRBICNSRVFVSVJFRAorICAgICAgeSBDREFUQSAjUkVRVUlSRUQKKyAgICAgIHdpZHRoIENEQVRBICNSRVFVSVJFRAorICAgICAgaGVpZ2h0IENEQVRBICNSRVFVSVJFRD4KKyAgPCFFTEVNRU5UIHNjcmlwdCAoI1BDREFUQSk+CisgIDwhQVRUTElTVCBzY3JpcHQgdHlwZSBDREFUQSAjSU1QTElFRD4gICAgICAKKyAgPCFFTlRJVFkgc3ZndW5pdCBTWVNURU0gInN2Z3VuaXQuanMiPgorICA8IUVOVElUWSBzdmd0ZXN0IFNZU1RFTSAic3ZndGVzdC5qcyI+CitdPgorPCEtLSBUaGlzIGlzIGNvbW1lbnQgbnVtYmVyIDEuLS0+Cis8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiLz48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+JnN2Z3Rlc3Q7JnN2Z3VuaXQ7PC9zY3JpcHQ+CisgPGVtcGxveWVlIHhtbG5zPSJodHRwOi8vd3d3Lm5pc3QuZ292IiB4bWxuczpkbXN0Yz0iaHR0cDovL3d3dy51c2EuY29tIj4KKyAgPGVtcGxveWVlSWQ+RU1QMDAwMTwvZW1wbG95ZWVJZD4KKyAgPG5hbWU+TWFyZ2FyZXQgTWFydGluPC9uYW1lPgorICA8cG9zaXRpb24+QWNjb3VudGFudDwvcG9zaXRpb24+ICAgICAgICAgICAKKyAgPHNhbGFyeT41NiwwMDA8L3NhbGFyeT4KKyAgPGdlbmRlcj5GZW1hbGU8L2dlbmRlcj4KKyAgPGFkZHJlc3MgZG1zdGM6ZG9tZXN0aWM9IlllcyI+MTIzMCBOb3J0aCBBdmUuIERhbGxhcywgVGV4YXMgOTg1NTE8L2FkZHJlc3M+CisgPC9lbXBsb3llZT4KKyA8ZW1wbG95ZWUgeG1sbnM6ZG1zdGM9Imh0dHA6Ly93d3cudXNhLmNvbSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvRE9NLVRlc3QtU3VpdGUvTGV2ZWwtMi9GaWxlcyI+CisgIDxlbXBsb3llZUlkPkVNUDAwMDI8L2VtcGxveWVlSWQ+CisgIDxuYW1lPk1hcnRoYSBSYXlub2xkcworPCFbQ0RBVEFbVGhpcyBpcyBhIENEQVRBU2VjdGlvbiB3aXRoIEVudGl0eVJlZmVyZW5jZSBudW1iZXIgMiAmZW50MjtdXT4KKzwhW0NEQVRBW1RoaXMgaXMgYW4gYWRqYWNlbnQgQ0RBVEFTZWN0aW9uIHdpdGggYSByZWZlcmVuY2UgdG8gYSB0YWIgJnRhYjtdXT48L25hbWU+CisgIDxwb3NpdGlvbj5TZWNyZXRhcnk8L3Bvc2l0aW9uPgorICA8c2FsYXJ5PjM1LDAwMDwvc2FsYXJ5PgorICA8Z2VuZGVyPkZlbWFsZTwvZ2VuZGVyPgorICA8YWRkcmVzcyBkbXN0Yzpkb21lc3RpYz0iWWVzIiBzdHJlZXQ9IlllcyI+JmVudDI7IERhbGxhcywgJmVudDM7CisgOTg1NTQ8L2FkZHJlc3M+CisgPC9lbXBsb3llZT4KKyA8ZW1wbG95ZWUgeG1sbnM6ZG1zdGM9Imh0dHA6Ly93d3cubmV0emVyby5jb20iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL0xldmVsLTIvRmlsZXMiPgorICA8ZW1wbG95ZWVJZD5FTVAwMDAzPC9lbXBsb3llZUlkPgorICA8bmFtZT5Sb2dlcgorIEpvbmVzPC9uYW1lPgorICA8cG9zaXRpb24+RGVwYXJ0bWVudCBNYW5hZ2VyPC9wb3NpdGlvbj4KKyAgPHNhbGFyeT4xMDAsMDAwPC9zYWxhcnk+CisgIDxnZW5kZXI+JmVudDQ7PC9nZW5kZXI+CisgIDxhZGRyZXNzIGRtc3RjOmRvbWVzdGljPSJZZXMiIHN0cmVldD0iTm8iPlBPIEJveCAyNyBJcnZpbmcsIHRleGFzIDk4NTUzPC9hZGRyZXNzPgorIDwvZW1wbG95ZWU+CisgPGVtcDplbXBsb3llZSB4bWxuczplbXA9Imh0dHA6Ly93d3cubmlzdC5nb3YiIHhtbG5zOm5tPSJodHRwOi8vd3d3LmFsdGF2aXN0YS5jb20iID4gICAgPGVtcDplbXBsb3llZUlkPkVNUDAwMDQ8L2VtcDplbXBsb3llZUlkPgorICA8bm06bmFtZT5KZW55IE9jb25ub3I8L25tOm5hbWU+CisgIDxlbXA6cG9zaXRpb24+UGVyc29ubmVsIERpcmVjdG9yPC9lbXA6cG9zaXRpb24+CisgIDxlbXA6c2FsYXJ5Pjk1LDAwMDwvZW1wOnNhbGFyeT4KKyAgPGVtcDpnZW5kZXI+RmVtYWxlPC9lbXA6Z2VuZGVyPgorICA8ZW1wOmFkZHJlc3MgZW1wOmRvbWVzdGljPSJZZXMiIHN0cmVldD0iWSZlbnQxOyIgZW1wOnpvbmU9IkNBTkFEQSIgZW1wOmxvY2FsMT0iVFJVRSI+MjcgU291dGggUm9hZC4gRGFsbGFzLCB0ZXhhcyA5ODU1NjwvZW1wOmFkZHJlc3M+CisgPC9lbXA6ZW1wbG95ZWU+CisgPGVtcGxveWVlIHhtbG5zOmVtcDI9Imh0dHA6Ly93d3cubmlzdC5nb3YiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL0RPTS1UZXN0LVN1aXRlL0xldmVsLTIvRmlsZXMiPgorICA8ZW1wbG95ZWVJZD5FTVAwMDA1PC9lbXBsb3llZUlkPgorICA8bmFtZT5Sb2JlcnQgTXllcnM8L25hbWU+CisgIDxwb3NpdGlvbj5Db21wdXRlciBTcGVjaWFsaXN0PC9wb3NpdGlvbj4KKyAgPHNhbGFyeT45MCwwMDA8L3NhbGFyeT4KKyAgPGdlbmRlcj5tYWxlPC9nZW5kZXI+CisgIDxhZGRyZXNzIHN0cmVldD0iWWVzIiB4bWxucz0iaHR0cDovL3d3dy5uaXN0LmdvdiI+MTgyMSBOb3JkaWMuIFJvYWQsIElydmluZyBUZXhhcyA5ODU1ODwvYWRkcmVzcz4KKyA8L2VtcGxveWVlPgorIDwvc3ZnPgpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9zdGFmZk5TLnhtbCBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvc3RhZmZOUy54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWNiMTQ1OQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvc3RhZmZOUy54bWwKQEAgLTAsMCArMSw1OSBAQAorPD94bWwgdmVyc2lvbj0iMS4wIj8+PD9URVNULVNUWUxFIFBJREFUQT8+Cis8IURPQ1RZUEUgc3RhZmYgUFVCTElDICJTVEFGRiIgInN0YWZmTlMuZHRkIiAKK1sKKyAgIDwhRU5USVRZIGVudDEgImVzIj4KKyAgIDwhRU5USVRZIGVudDIgIjE5MDAgRGFsbGFzIFJvYWQiPgorICAgPCFFTlRJVFkgZW50MyAiVGV4YXMiPgorICAgPCFFTlRJVFkgZW50NCAiPGVudEVsZW1lbnQxIHhtbG5zOmxvY2FsMT0nd3d3Lnh5ei5jb20nPkVsZW1lbnQgZGF0YTwvZW50RWxlbWVudDE+PD9QSXRhcmdldCBQSWRhdGE/PiI+CisgICA8IUVOVElUWSBlbnQ1IFBVQkxJQyAiZW50aXR5VVJJIiAiZW50aXR5RmlsZSIgTkRBVEEgbm90YXRpb24xPgorICAgPCFFTlRJVFkgZW50NiBQVUJMSUMgInVyaSIgImZpbGUiIE5EQVRBIG5vdGF0aW9uMj4KKyAgIDwhRU5USVRZIGVudDEgIlRoaXMgZW50aXR5IHNob3VsZCBiZSBkaXNjYXJkZWQiPgorICAgPCFOT1RBVElPTiBub3RhdGlvbjEgUFVCTElDICJub3RhdGlvbjFGaWxlIj4KKyAgIDwhTk9UQVRJT04gbm90YXRpb24yIFNZU1RFTSAibm90YXRpb24yRmlsZSI+CitdPgorPCEtLSBUaGlzIGlzIGNvbW1lbnQgbnVtYmVyIDEuLS0+Cis8c3RhZmY+CisgPGVtcGxveWVlIHhtbG5zPSJodHRwOi8vd3d3Lm5pc3QuZ292IiB4bWxuczpkbXN0Yz0iaHR0cDovL3d3dy51c2EuY29tIj4KKyAgPGVtcGxveWVlSWQ+RU1QMDAwMTwvZW1wbG95ZWVJZD4KKyAgPG5hbWU+TWFyZ2FyZXQgTWFydGluPC9uYW1lPgorICA8cG9zaXRpb24+QWNjb3VudGFudDwvcG9zaXRpb24+ICAgICAgICAgICAKKyAgPHNhbGFyeT41NiwwMDA8L3NhbGFyeT4KKyAgPGdlbmRlcj5GZW1hbGU8L2dlbmRlcj4KKyAgPGFkZHJlc3MgZG1zdGM6ZG9tZXN0aWM9IlllcyI+MTIzMCBOb3J0aCBBdmUuIERhbGxhcywgVGV4YXMgOTg1NTE8L2FkZHJlc3M+CisgPC9lbXBsb3llZT4KKyA8ZW1wbG95ZWUgeG1sbnM6ZG1zdGM9Imh0dHA6Ly93d3cudXNhLmNvbSI+CisgIDxlbXBsb3llZUlkPkVNUDAwMDI8L2VtcGxveWVlSWQ+CisgIDxuYW1lPk1hcnRoYSBSYXlub2xkcworPCFbQ0RBVEFbVGhpcyBpcyBhIENEQVRBU2VjdGlvbiB3aXRoIEVudGl0eVJlZmVyZW5jZSBudW1iZXIgMiAmZW50MjtdXT4KKzwhW0NEQVRBW1RoaXMgaXMgYW4gYWRqYWNlbnQgQ0RBVEFTZWN0aW9uIHdpdGggYSByZWZlcmVuY2UgdG8gYSB0YWIgJnRhYjtdXT48L25hbWU+CisgIDxwb3NpdGlvbj5TZWNyZXRhcnk8L3Bvc2l0aW9uPgorICA8c2FsYXJ5PjM1LDAwMDwvc2FsYXJ5PgorICA8Z2VuZGVyPkZlbWFsZTwvZ2VuZGVyPgorICA8YWRkcmVzcyBkbXN0Yzpkb21lc3RpYz0iWWVzIiBzdHJlZXQ9IlllcyI+JmVudDI7IERhbGxhcywgJmVudDM7CisgOTg1NTQ8L2FkZHJlc3M+CisgPC9lbXBsb3llZT4KKyA8ZW1wbG95ZWUgeG1sbnM6ZG1zdGM9Imh0dHA6Ly93d3cubmV0emVyby5jb20iPgorICA8ZW1wbG95ZWVJZD5FTVAwMDAzPC9lbXBsb3llZUlkPgorICA8bmFtZT5Sb2dlcgorIEpvbmVzPC9uYW1lPgorICA8cG9zaXRpb24+RGVwYXJ0bWVudCBNYW5hZ2VyPC9wb3NpdGlvbj4KKyAgPHNhbGFyeT4xMDAsMDAwPC9zYWxhcnk+CisgIDxnZW5kZXI+JmVudDQ7PC9nZW5kZXI+CisgIDxhZGRyZXNzIGRtc3RjOmRvbWVzdGljPSJZZXMiIHN0cmVldD0iTm8iPlBPIEJveCAyNyBJcnZpbmcsIHRleGFzIDk4NTUzPC9hZGRyZXNzPgorIDwvZW1wbG95ZWU+CisgPGVtcDplbXBsb3llZSB4bWxuczplbXA9Imh0dHA6Ly93d3cubmlzdC5nb3YiIHhtbG5zOm5tPSJodHRwOi8vd3d3LmFsdGF2aXN0YS5jb20iID4gICAgPGVtcDplbXBsb3llZUlkPkVNUDAwMDQ8L2VtcDplbXBsb3llZUlkPgorICA8bm06bmFtZT5KZW55IE9jb25ub3I8L25tOm5hbWU+CisgIDxlbXA6cG9zaXRpb24+UGVyc29ubmVsIERpcmVjdG9yPC9lbXA6cG9zaXRpb24+CisgIDxlbXA6c2FsYXJ5Pjk1LDAwMDwvZW1wOnNhbGFyeT4KKyAgPGVtcDpnZW5kZXI+RmVtYWxlPC9lbXA6Z2VuZGVyPgorICA8ZW1wOmFkZHJlc3MgZW1wOmRvbWVzdGljPSJZZXMiIHN0cmVldD0iWSZlbnQxOyIgZW1wOnpvbmU9IkNBTkFEQSIgZW1wOmxvY2FsMT0iVFJVRSI+MjcgU291dGggUm9hZC4gRGFsbGFzLCB0ZXhhcyA5ODU1NjwvZW1wOmFkZHJlc3M+CisgPC9lbXA6ZW1wbG95ZWU+CisgPGVtcGxveWVlIHhtbG5zOmVtcDI9Imh0dHA6Ly93d3cubmlzdC5nb3YiPgorICA8ZW1wbG95ZWVJZD5FTVAwMDA1PC9lbXBsb3llZUlkPgorICA8bmFtZT5Sb2JlcnQgTXllcnM8L25hbWU+CisgIDxwb3NpdGlvbj5Db21wdXRlciBTcGVjaWFsaXN0PC9wb3NpdGlvbj4KKyAgPHNhbGFyeT45MCwwMDA8L3NhbGFyeT4KKyAgPGdlbmRlcj5tYWxlPC9nZW5kZXI+CisgIDxhZGRyZXNzIHN0cmVldD0iWWVzIiB4bWxucz0iaHR0cDovL3d3dy5uaXN0LmdvdiI+MTgyMSBOb3JkaWMuIFJvYWQsIElydmluZyBUZXhhcyA5ODU1ODwvYWRkcmVzcz4KKyA8L2VtcGxveWVlPgorIDwvc3RhZmY+CmRpZmYgLS1naXQgYS9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL3N2Z3Rlc3QuanMgYi9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL3N2Z3Rlc3QuanMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTY5ZGUyOQotLS0gL2Rldi9udWxsCisrKyBiL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMvc3ZndGVzdC5qcwpkaWZmIC0tZ2l0IGEvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9zdmd1bml0LmpzIGIvZG9tL3NyYy90ZXN0L3Jlc291cmNlcy9zdmd1bml0LmpzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2OWRlMjkKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL3N2Z3VuaXQuanMKZGlmZiAtLWdpdCBhL2RvbS9zcmMvdGVzdC9yZXNvdXJjZXMveGh0bWwxLXN0cmljdC5kdGQgYi9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL3hodG1sMS1zdHJpY3QuZHRkCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZlZmI3N2YKLS0tIC9kZXYvbnVsbAorKysgYi9kb20vc3JjL3Rlc3QvcmVzb3VyY2VzL3hodG1sMS1zdHJpY3QuZHRkCkBAIC0wLDAgKzEsNjUgQEAKKzwhLS0NCisNCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLCANCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUNCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsIA0KK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUNCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgDQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbg0KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgDQorUFVSUE9TRS4gIA0KKw0KK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLg0KKw0KKy0tPg0KKw0KKzwhLS0NCisNCitUaGlzIGlzIGEgcmFkaWNhbGx5IHNpbXBsaWZpZWQgRFREIGZvciB1c2UgaW4gdGhlIERPTSBUZXN0IFN1aXRlcw0KK2R1ZSB0byBhIFhNTCBub24tY29uZm9ybWFuY2Ugb2Ygb25lIGltcGxlbWVudGF0aW9uIGluIHByb2Nlc3NpbmcNCitwYXJhbWV0ZXIgZW50aXRpZXMuICBXaGVuIHRoYXQgbm9uLWNvbmZvcm1hbmNlIGlzIHJlc29sdmVkLA0KK3RoaXMgRFREIGNhbiBiZSByZXBsYWNlZCBieSB0aGUgbm9ybWFsIERURCBmb3IgWEhUTUwuDQorDQorLS0+DQorDQorDQorPCFFTEVNRU5UIGh0bWwgKGhlYWQsIGJvZHkpPg0KKzwhQVRUTElTVCBodG1sIHhtbG5zIENEQVRBICNJTVBMSUVEPg0KKzwhRUxFTUVOVCBoZWFkIChtZXRhLHRpdGxlLHNjcmlwdCopPg0KKzwhRUxFTUVOVCBtZXRhIEVNUFRZPg0KKzwhQVRUTElTVCBtZXRhIA0KKwlodHRwLWVxdWl2IENEQVRBICNJTVBMSUVEDQorCWNvbnRlbnQgQ0RBVEEgI0lNUExJRUQ+DQorPCFFTEVNRU5UIHRpdGxlICgjUENEQVRBKT4NCis8IUVMRU1FTlQgYm9keSAocCopPg0KKzwhQVRUTElTVCBib2R5IG9ubG9hZCBDREFUQSAjSU1QTElFRD4NCis8IUVMRU1FTlQgcCAoI1BDREFUQXxlbXxzdHJvbmd8Y29kZXxzdXB8dmFyfGFjcm9ueW18YWJicikqPg0KKzwhQVRUTElTVCBwIA0KKyAgeG1sbnM6ZG1zdGMgQ0RBVEEgI0lNUExJRUQNCisgIHhtbG5zOm5tIENEQVRBICNJTVBMSUVEDQorICB4bWxuczplbXAyIENEQVRBICNJTVBMSUVEDQorICBpZCBJRCAjSU1QTElFRCAgDQorPg0KKzwhRUxFTUVOVCBlbSAoI1BDREFUQSk+DQorPCFFTEVNRU5UIHNwYW4gKCNQQ0RBVEEpPg0KKzwhRUxFTUVOVCBzdHJvbmcgKCNQQ0RBVEEpPg0KKzwhRUxFTUVOVCBjb2RlICgjUENEQVRBKT4NCis8IUVMRU1FTlQgc3VwICgjUENEQVRBKT4NCis8IUVMRU1FTlQgdmFyICgjUENEQVRBfHNwYW4pKj4NCis8IUVMRU1FTlQgYWNyb255bSAoI1BDREFUQSk+DQorPCFBVFRMSVNUIGFjcm9ueW0NCisgICAgdGl0bGUgQ0RBVEEgI0lNUExJRUQNCisgICAgY2xhc3MgQ0RBVEEgI0lNUExJRUQNCisgICAgaWQgSUQgI0lNUExJRUQNCis+DQorPCFFTEVNRU5UIGFiYnIgKCNQQ0RBVEEpPg0KKzwhQVRUTElTVCBhYmJyDQorICAgIHRpdGxlIENEQVRBICNJTVBMSUVEDQorICAgIGNsYXNzIENEQVRBICNJTVBMSUVEDQorICAgIGlkIElEICNJTVBMSUVEDQorPg0KKzwhRUxFTUVOVCBzY3JpcHQgKCNQQ0RBVEEpPg0KKzwhQVRUTElTVCBzY3JpcHQgDQorICAgdHlwZSBDREFUQSAjSU1QTElFRA0KKyAgIHNyYyBDREFUQSAjSU1QTElFRA0KKyAgIGNoYXJzZXQgQ0RBVEEgI0lNUExJRUQ+ICAgICAgICAgIA0KZGlmZiAtLWdpdCBhL2V4cGVjdGF0aW9ucy9icm9rZW50ZXN0cy50eHQgYi9leHBlY3RhdGlvbnMvYnJva2VudGVzdHMudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhOTk1MmMKLS0tIC9kZXYvbnVsbAorKysgYi9leHBlY3RhdGlvbnMvYnJva2VudGVzdHMudHh0CkBAIC0wLDAgKzEsOTAwIEBACisvKgorICogVGhpcyBmaWxlIGNvbnRhaW5zIGV4cGVjdGF0aW9ucyBmb3IgdGVzdHMgdGhhdCB3ZSdkIGxpa2UgdG8gZXZlbnR1YWxseSBmaXgsIGJ1dCBhcmVuJ3QgdXJnZW50LgorICovCitbCit7CisgIGRlc2NyaXB0aW9uOiAiV2l0aG91dCBubyBzZWN1cml0eSBtYW5hZ2VyLCB3ZSBkb24ndCBjYXJlIGlmIGNoZWNrUGVybWlzc2lvbidzIGFyZ3VtZW50IGlzIG51bGwiLAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlcjJUZXN0I3Rlc3RfY2hlY2tQZXJtaXNzaW9uX051bGxQYXJhbWV0ZXIiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVECit9LAoreworICBkZXNjcmlwdGlvbjogIlRoaXMgdGVzdCBhbmQgdGVzdEdldEtlZXBBbGl2ZSBoYXZlIGJlZW4gZmFpbGluZyBpbiBvdXIgY29udGludW91cyBidWlsZCByZWNlbnRseS4iLAorICBuYW1lczogWworICAgICJsaWJjb3JlLmphdmEubmV0LlVSTENvbm5lY3Rpb25UZXN0I3Rlc3RDb25uZWN0VGltZW91dHMiLAorICAgICJsaWJjb3JlLmphdmEubmV0LlVSTENvbm5lY3Rpb25UZXN0I3Rlc3RHZXRLZWVwQWxpdmUiCisgIF0sCisgIGJ1ZzogMzQ0MTExMQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJvbiB0aGUgUkksIHdyaXRpbmcgdGhlIHR3byBoYWx2ZXMgb2YgdGhlIHN1cnJvZ2F0ZSBwYWlyIGluIHNlcGFyYXRlIHdyaXRlcworICAgICAgICAgIGlzIGFuIGVycm9yIGJlY2F1c2UgdGhlIENoYXJzZXRFbmNvZGVyIGRvZXNuJ3QgcmVtZW1iZXIgaXQncyBoYWxmLXdheSB0aHJvdWdoIGEKKyAgICAgICAgICBzdXJyb2dhdGUgcGFpciBhY3Jvc3MgdGhlIHR3byBjYWxscyEiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lczogWworICAgICJsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQuQ2hhcnNldEVuY29kZXJUZXN0I3Rlc3RDaGFyc2V0RW5jb2RlclN1cnJvZ2F0ZXNCcm9rZW5CeURlc2lnbl9JR05PUkVfUkkiLAorICAgICJsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQuQ2hhcnNldEVuY29kZXJUZXN0I3Rlc3RDaGFyc2V0RW5jb2RlclN1cnJvZ2F0ZXNCcm9rZW5CeURlc2lnbl9SRVBMQUNFX1JJIiwKKyAgICAibGliY29yZS5qYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRFbmNvZGVyVGVzdCN0ZXN0Q2hhcnNldEVuY29kZXJTdXJyb2dhdGVzQnJva2VuQnlEZXNpZ25fUkVQT1JUX1JJIgorICBdCit9LAoreworICBkZXNjcmlwdGlvbjogIldlJ3JlIHJldGlyaW5nIHRoZSBzZWN1cml0eSBtYW5hZ2VyLiBVbmZvcnR1bmF0ZWx5LCB0ZXN0cyBhbGwgb3ZlciB0aGUgcGxhY2UKKyAgICAgICAgICAgICAgICBuZWVkIHRvIGNoZWNrIHRoYXQgdGhleSdyZSBzZWN1cmUsIHNvIHRoZXkgYWxsIGZhaWwgd2hlbiB3ZSByZWZ1c2UgdG8gaW5zdGFsbAorICAgICAgICAgICAgICAgIGEgc2VjdXJpdHkgbWFuYWdlci4gVGhpcyBzdXBwcmVzc2VzIGFsbCBvZiB0aGVzZSBmYWlsdXJlcy4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBmYWlsdXJlOiAiZGlzYWJsZSBzZWN1cml0eU1hbmFnZXIiLAorICBwYXR0ZXJuOiAiLipqYXZhLmxhbmcuU2VjdXJpdHlFeGNlcHRpb25cXHMrYXQgamF2YS5sYW5nLlN5c3RlbS5zZXRTZWN1cml0eU1hbmFnZXIuKiIsCisgIGJ1ZzogMjU4NTI4NQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJpZ25vcmUgY29tcGlsYXRpb24gZXJyb3JzIGR1ZSB0byBkaWZmZXJlbnQgYXZhaWxhYmxlIEFQSXMiLAorICByZXN1bHQ6IENPTVBJTEVfRkFJTEVELAorICBmYWlsdXJlOiAiaWdub3JlIGNvbXBpbGF0aW9uIGVycm9ycyIsCisgIHBhdHRlcm46ICIuKlxcLmphdmE6XFxkKzogY2Fubm90IGZpbmQgc3ltYm9sLioiCit9LAoreworICBkZXNjcmlwdGlvbjogIlRoZXNlIHRlc3RzIGFzc2VydCB0aGUgZXhhY3QgYnl0ZXMgb2YgdGhlIGNvbXByZXNzZWQgZm9ybS4gU2luY2Ugd2UgdXNlIGEKKyAgICAgICAgICAgICAgICBkaWZmZXJlbnQgemxpYiBjb25maWd1cmF0aW9uLCB3ZSBnZXQgYSBkaWZmZXJlbnQgKGJ1dCB2YWxpZCkgY29tcHJlc3NlZCBmb3JtLiIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWVzOiBbCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5hcmNoaXZlLnRlc3RzLmphdmEudXRpbC56aXAuRGVmbGF0ZXJJbnB1dFN0cmVhbVRlc3QjdGVzdEF2YWlsYWJsZSIsCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5hcmNoaXZlLnRlc3RzLmphdmEudXRpbC56aXAuRGVmbGF0ZXJJbnB1dFN0cmVhbVRlc3QjdGVzdFJlYWQiLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkuYXJjaGl2ZS50ZXN0cy5qYXZhLnV0aWwuemlwLkRlZmxhdGVySW5wdXRTdHJlYW1UZXN0I3Rlc3RSZWFkQnl0ZUFycmF5SW50SW50IiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255LmFyY2hpdmUudGVzdHMuamF2YS51dGlsLnppcC5EZWZsYXRlclRlc3QjdGVzdF9kZWZsYXRlX2JlZm9yZVNldElucHV0IgorICBdCit9LAoreworICBkZXNjcmlwdGlvbjogIlRoZSBSSSBhdm9pZHMgYmxvY2tpbmcgY2FsbHMgd2hlbiAnXFxyJyBpcyB0aGUgbGFzdCBjaGFyYWN0ZXIuIFdlIGRvbid0CisgICAgICAgICAgICAgICAgYm90aGVyIHNpbmNlIHRoYXQgYWRkcyBjb21wbGV4aXR5IHRvIGV2ZXJ5IG90aGVyIHJlYWQgY2FsbCwgYW5kICdcXHInIGFzIHRoZQorICAgICAgICAgICAgICAgIGxhc3QgY2hhcmFjdGVyIHdpbGwgYmUgZGltaW5pc2hpbmdseSByYXJlIGFueXdheS4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAiamF2YS5pby5CdWZmZXJlZFJlYWRlci5SZWFkTGluZSIsCisgIHN1YnN0cmluZzogImphdmEubGFuZy5SdW50aW1lRXhjZXB0aW9uOiBSZWFkIHBhc3QgbGltaXQiCit9LAoreworICBkZXNjcmlwdGlvbjogIlRoZSBSSSBhdm9pZHMgYmxvY2tpbmcgY2FsbHMgd2hlbiAnXFxyJyBpcyB0aGUgbGFzdCBjaGFyYWN0ZXIuIFdlIGRvbid0CisgICAgICAgICAgICAgICAgYm90aGVyIHNpbmNlIHRoYXQgYWRkcyBjb21wbGV4aXR5IHRvIGV2ZXJ5IG90aGVyIHJlYWQgY2FsbCwgYW5kICdcXHInIGFzIHRoZQorICAgICAgICAgICAgICAgIGxhc3QgY2hhcmFjdGVyIHdpbGwgYmUgZGltaW5pc2hpbmdseSByYXJlIGFueXdheS4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAiamF2YS5pby5CdWZmZXJlZFJlYWRlci5SZWFkeSIsCisgIHN1YnN0cmluZzogIkhpdCBpbmZpbml0ZSB3YWl0IGNvbmRpdGlvbiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGhlIHRlc3QgaXMgY2hlY2tpbmcgdGhhdCB0aGUgaW1wbGVtZW50YXRpb24gZG9lc24ndCByZWFkIGFueSBjaGFyYWN0ZXJzCisgICAgICAgICAgICAgICAgZWFybGllciB0aGFuIGl0IGFic29sdXRlbHkgbmVlZHMgdG8uIFRoaXMgaXMgYSBib2d1cyByZXF1aXJlbWVudDsgc3RyZWFtcworICAgICAgICAgICAgICAgIGFyZSBhbGxvd2VkIHRvIGJ1ZmZlciBpbnB1dCBhcyBuZWNlc3NhcnkuIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogImphdmEuaW8uU3RyZWFtVG9rZW5pemVyLlJlc2V0IiwKKyAgc3Vic3RyaW5nOiAiVGVzdCBmYWlsZWQ6IHNob3VsZCBnZXQgdG9rZW4gWywgYnV0IGdldCAtMSIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGhlc2UgdGVzdHMgb25seSBwYXNzIGlmIHRoZSByb290IGxvZ2dlciBoYXNuJ3QgeWV0IGJlZW4gaW5pdGlhbGl6ZWQuIFRoZXkKKyAgICAgICAgICAgICAgICBpbmNvcnJlY3RseSBhc3N1bWUgdGhhdCByZXNldHRpbmcgdGhlIExvZ01hbmFnZXIgd2lsbCBjbGVhciB0aGUgcm9vdCBsb2dnZXIncworICAgICAgICAgICAgICAgIHJlc291cmNlIGJ1bmRsZTsgdGhpcyBpc24ndCB0aGUgY2FzZS4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255LmxvZ2dpbmcudGVzdHMuamF2YS51dGlsLmxvZ2dpbmcuT2xkTG9nZ2VyVGVzdCN0ZXN0R2V0TG9nZ2VyV2l0aFJlc19JbnZhbGlkUmVzb3VyY2VCdW5kbGUiLAorICBzdWJzdHJpbmc6ICJqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOiBSZXNvdXJjZSBidW5kbGUgbmFtZSAnaW1wb3NzaWJsZV9ub3RfZXhpc3RpbmcnIGlzIGluY29uc2lzdGVudCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGhlc2UgdGVzdHMgb25seSBwYXNzIGlmIHRoZSByb290IGxvZ2dlciBoYXNuJ3QgeWV0IGJlZW4gaW5pdGlhbGl6ZWQuIFRoZXkKKyAgICAgICAgICAgICAgICBpbmNvcnJlY3RseSBhc3N1bWUgdGhhdCByZXNldHRpbmcgdGhlIExvZ01hbmFnZXIgd2lsbCBjbGVhciB0aGUgcm9vdCBsb2dnZXIncworICAgICAgICAgICAgICAgIHJlc291cmNlIGJ1bmRsZTsgdGhpcyBpc24ndCB0aGUgY2FzZS4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255LmxvZ2dpbmcudGVzdHMuamF2YS51dGlsLmxvZ2dpbmcuTG9nZ2VyVGVzdCN0ZXN0R2V0TG9nZ2VyX0VtcHR5IiwKKyAgc3Vic3RyaW5nOiAianVuaXQuZnJhbWV3b3JrLkFzc2VydGlvbkZhaWxlZEVycm9yIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJUaGlzIHRlc3RzIGltcGxlbWVudGF0aW9uIGRldGFpbHMiLAorICByZXN1bHQ6IFVOU1VQUE9SVEVELAorICBuYW1lOiAiamF2YS51dGlsLkVudW1TZXQuT25lVW5pdmVyc2UiCit9LAoreworICBkZXNjcmlwdGlvbjogIkRhbHZpayBkb2Vzbid0IGluY2x1ZGUgdGhlIFN1bkpDRSBjcnlwdG8gcHJvdmlkZXIiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lczogWworICAgICJjb20uc3VuLmNyeXB0by5wcm92aWRlci5DaXBoZXIuQUVTLlRlc3Q0NTEzODMwIiwKKyAgICAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuQ2lwaGVyLkFFUy5UZXN0NDUxMjcwNCIsCisgICAgImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLkNpcGhlci5BRVMuVGVzdDQ1MTI1MjQiLAorICAgICJjb20uc3VuLmNyeXB0by5wcm92aWRlci5DaXBoZXIuQUVTLlRlc3Q0NTExNjc2IiwKKyAgICAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuQ2lwaGVyLkFFUy5UZXN0NDUxNzM1NSIKKyAgXSwKKyAgc3Vic3RyaW5nOiAiTm9DbGFzc0RlZkZvdW5kRXJyb3I6IGNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLlN1bkpDRSIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGFsdmlrIGRvZXNuJ3QgaW5jbHVkZSB0aGUgU3VuSkNFIGNyeXB0byBwcm92aWRlciIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJjb20uc3VuLmNyeXB0by5wcm92aWRlci5DaXBoZXIuQUVTLlRlc3RJU08xMDEyNlBhZGRpbmciLAorICBzdWJzdHJpbmc6ICIgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjogU3VuSkNFIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIHRoZSBTdW5KQ0UgY3J5cHRvIHByb3ZpZGVyIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLkNpcGhlci5BRVMuVGVzdDQ2MjYwNzAiLAorICBzdWJzdHJpbmc6ICJOb0NsYXNzRGVmRm91bmRFcnJvcjogY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuU3VuSkNFIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIHRoZSBTdW5KQ0UgY3J5cHRvIHByb3ZpZGVyIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuQ2lwaGVyLkFFUy5UZXN0U2hvcnRCdWZmZXIiLAorICAgICJjb20uc3VuLmNyeXB0by5wcm92aWRlci5DaXBoZXIuQ1RTLkNUU01vZGUiCisgIF0sCisgIHN1YnN0cmluZzogIlByb3ZpZGVyIFN1bkpDRSBpcyBub3QgYXZhaWxhYmxlIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIHRoZSBTdW5KQ0UgY3J5cHRvIHByb3ZpZGVyIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuQ2lwaGVyLkRFUy5EZXNBUElUZXN0IiwKKyAgICAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuQ2lwaGVyLkRFUy5Eb0ZpbmFsUmV0dXJuTGVuIiwKKyAgICAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuQ2lwaGVyLkRFUy5GbHVzaEJ1ZyIKKyAgXSwKKyAgc3Vic3RyaW5nOiAiamF2YS5sYW5nLk5vQ2xhc3NEZWZGb3VuZEVycm9yOiBjb20uc3VuLmNyeXB0by5wcm92aWRlci5TdW5KQ0UiCit9LAoreworICBkZXNjcmlwdGlvbjogIkRhbHZpayBkb2Vzbid0IGluY2x1ZGUgdGhlIFN1bkpDRSBjcnlwdG8gcHJvdmlkZXIiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuQ2lwaGVyLkRFUy5LZXlXcmFwcGluZyIsCisgIHN1YnN0cmluZzogIlByb3ZpZGVyIFN1bkpDRSBpcyBub3QgYXZhaWxhYmxlIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIHRoZSBTdW5KQ0UgY3J5cHRvIHByb3ZpZGVyIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuQ2lwaGVyLkRFUy5QYWRkaW5nVGVzdCIsCisgICAgImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLkNpcGhlci5ERVMuU2VhbHRlc3QiLAorICAgICJjb20uc3VuLmNyeXB0by5wcm92aWRlci5DaXBoZXIuREVTLlBlcmZvcm1hbmNlVGVzdCIKKyAgXSwKKyAgc3Vic3RyaW5nOiAiamF2YS5sYW5nLk5vQ2xhc3NEZWZGb3VuZEVycm9yOiBjb20uc3VuLmNyeXB0by5wcm92aWRlci5TdW5KQ0UiCit9LAoreworICBkZXNjcmlwdGlvbjogIkRhbHZpayBkb2Vzbid0IGluY2x1ZGUgdGhlIFN1bkpDRSBjcnlwdG8gcHJvdmlkZXIiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lczogWworICAgICJjb20uc3VuLmNyeXB0by5wcm92aWRlci5DaXBoZXIuUEJFLkRlY3J5cHRXaXRob3V0UGFyYW1ldGVycyIsCisgICAgImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLkNpcGhlci5QQkUuUEJFSW52YWxpZFBhcmFtc1Rlc3QiCisgIF0sCisgIHN1YnN0cmluZzogIlByb3ZpZGVyIFN1bkpDRSBpcyBub3QgYXZhaWxhYmxlIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIHRoZSBTdW5KQ0UgY3J5cHRvIHByb3ZpZGVyIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLkNpcGhlci5QQkUuUEJFS2V5c0FsZ29yaXRobU5hbWVzIiwKKyAgc3Vic3RyaW5nOiAiamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjogU3VuSkNFIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIHRoZSBTdW5KQ0UgY3J5cHRvIHByb3ZpZGVyIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuQ2lwaGVyLlBCRS5QQkVQYXJhbWV0ZXJzVGVzdCIsCisgICAgImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLkNpcGhlci5QQkUuUEtDUzEyT2lkIiwKKyAgICAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuQ2lwaGVyLlVUSUwuU3Ryb25nT3JVbmxpbWl0ZWQiLAorICAgICJjb20uc3VuLmNyeXB0by5wcm92aWRlci5DaXBoZXIuS2V5V3JhcC5OSVNUV3JhcEtBVCIKKyAgXSwKKyAgc3Vic3RyaW5nOiAiUHJvdmlkZXIgU3VuSkNFIGlzIG5vdCBhdmFpbGFibGUiCit9LAoreworICBkZXNjcmlwdGlvbjogIkRhbHZpayBkb2Vzbid0IGluY2x1ZGUgdGhlIFN1bkpDRSBjcnlwdG8gcHJvdmlkZXIiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuS2V5QWdyZWVtZW50LkRIR2VuU2VjcmV0S2V5IiwKKyAgc3Vic3RyaW5nOiAiamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjogU3VuSkNFIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIHRoZSBTdW5KQ0UgY3J5cHRvIHByb3ZpZGVyIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuS2V5QWdyZWVtZW50LkRIR2VuU2hhcmVkU2VjcmV0IiwKKyAgICAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuS2V5QWdyZWVtZW50LkRIS2V5QWdyZWVtZW50MyIsCisgICAgImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLktleUFncmVlbWVudC5ESEtleUZhY3RvcnkiLAorICAgICJjb20uc3VuLmNyeXB0by5wcm92aWRlci5LZXlBZ3JlZW1lbnQuREhLZXlHZW5TcGVlZCIKKyAgXSwKKyAgc3Vic3RyaW5nOiAiamF2YS5sYW5nLk5vQ2xhc3NEZWZGb3VuZEVycm9yOiBjb20uc3VuLmNyeXB0by5wcm92aWRlci5TdW5KQ0UiCit9LAoreworICBkZXNjcmlwdGlvbjogIkRhbHZpayBkb2Vzbid0IGluY2x1ZGUgdGhlIFN1bkpDRSBjcnlwdG8gcHJvdmlkZXIiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lczogWworICAgICJjb20uc3VuLmNyeXB0by5wcm92aWRlci5LZXlBZ3JlZW1lbnQuVGVzdEV4cG9uZW50U2l6ZSIsCisgICAgImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLktleUZhY3RvcnkuVGVzdFByb3ZpZGVyTGVhayIsCisgICAgImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLktleUZhY3RvcnkuUEJLREYySG1hY1NIQTFGYWN0b3J5VGVzdCIKKyAgXSwKKyAgc3Vic3RyaW5nOiAiamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjogU3VuSkNFIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIHRoZSBTdW5KQ0UgY3J5cHRvIHByb3ZpZGVyIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuS2V5R2VuZXJhdG9yLlRlc3Q0NjI4MDYyIiwKKyAgICAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuS2V5R2VuZXJhdG9yLlRlc3RFeHBsaWNpdEtleUxlbmd0aCIKKyAgXSwKKyAgc3Vic3RyaW5nOiAiamF2YS5sYW5nLk5vQ2xhc3NEZWZGb3VuZEVycm9yOiBjb20uc3VuLmNyeXB0by5wcm92aWRlci5TdW5KQ0UiCit9LAoreworICBkZXNjcmlwdGlvbjogIkRhbHZpayBkb2Vzbid0IGluY2x1ZGUgdGhlIFN1bkpDRSBjcnlwdG8gcHJvdmlkZXIiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuTWFjLkhtYWNQQkVTSEExIiwKKyAgc3Vic3RyaW5nOiAiamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjogU3VuSkNFIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIHRoZSBTdW5KQ0UgY3J5cHRvIHByb3ZpZGVyIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLk1hYy5IbWFjTUQ1IiwKKyAgc3Vic3RyaW5nOiAiamF2YS5sYW5nLk5vQ2xhc3NEZWZGb3VuZEVycm9yOiBjb20uc3VuLmNyeXB0by5wcm92aWRlci5TdW5KQ0UiCit9LAoreworICBkZXNjcmlwdGlvbjogIkRhbHZpayBkb2Vzbid0IGluY2x1ZGUgdGhlIFN1bkpDRSBjcnlwdG8gcHJvdmlkZXIiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuTWFjLk1hY0Nsb25lIiwKKyAgc3Vic3RyaW5nOiAiamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjogU3VuSkNFIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIHRoZSBTdW5KQ0UgY3J5cHRvIHByb3ZpZGVyIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgZmFpbHVyZTogIkpLUyBrZXlzdG9yZSBub3QgZm91bmQiLAorICBzdWJzdHJpbmc6ICJLZXlTdG9yZSBKS1MgaW1wbGVtZW50YXRpb24gbm90IGZvdW5kIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJUaGVzZSBOUEVzIGFsbCBoYXBwZW4gd2hpbGUgY2FsbGluZyBQcm92aWRlciNnZXROYW1lIG9uIHRoZSByZXN1bHQgb2YKKyAgICAgICAgICAgICAgICBTZWN1cml0eSNnZXRQcm92aWRlcigpLiBVbmZvcnR1bmF0ZWx5LCB0aGF0IG1ldGhvZCBpcyBwZXJtaXR0ZWQgdG8gcmV0dXJuCisgICAgICAgICAgICAgICAgbnVsbCBpZiB0aGUgc3lzdGVtIGhhcyBubyBwcm92aWRlciB3aXRoIHRoZSByZXF1ZXN0ZWQgbmFtZS4gQW5kIHNpbmNlIHdlIGRvbid0CisgICAgICAgICAgICAgICAgaGF2ZSB0aGUgU3VuSkNFIHByb3ZpZGVyLCB0ZXN0cyBmYWlsIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLkNpcGhlci5QQkUuUEtDUzEyQ2lwaGVyIiwKKyAgcGF0dGVybjogIi4qUEtDUzEyQ2lwaGVyLmphdmFcXDo4N1xcKS4qTnVsbFBvaW50ZXJFeGNlcHRpb24uKiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGhlc2UgTlBFcyBhbGwgaGFwcGVuIHdoaWxlIGNhbGxpbmcgUHJvdmlkZXIjZ2V0TmFtZSBvbiB0aGUgcmVzdWx0IG9mCisgICAgICAgICAgICAgICAgU2VjdXJpdHkjZ2V0UHJvdmlkZXIoKS4gVW5mb3J0dW5hdGVseSwgdGhhdCBtZXRob2QgaXMgcGVybWl0dGVkIHRvIHJldHVybgorICAgICAgICAgICAgICAgIG51bGwgaWYgdGhlIHN5c3RlbSBoYXMgbm8gcHJvdmlkZXIgd2l0aCB0aGUgcmVxdWVzdGVkIG5hbWUuIEFuZCBzaW5jZSB3ZSBkb24ndAorICAgICAgICAgICAgICAgIGhhdmUgdGhlIFN1bkpDRSBwcm92aWRlciwgdGVzdHMgZmFpbCIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJjb20uc3VuLmNyeXB0by5wcm92aWRlci5DaXBoZXIuUEJFLlBLQ1MxMkNpcGhlcktBVCIsCisgIHBhdHRlcm46ICIuKk51bGxQb2ludGVyRXhjZXB0aW9uLipQS0NTMTJDaXBoZXJLQVQuamF2YVxcOjE4M1xcKS4qIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJUaGVzZSBOUEVzIGFsbCBoYXBwZW4gd2hpbGUgY2FsbGluZyBQcm92aWRlciNnZXROYW1lIG9uIHRoZSByZXN1bHQgb2YKKyAgICAgICAgICAgICAgICBTZWN1cml0eSNnZXRQcm92aWRlcigpLiBVbmZvcnR1bmF0ZWx5LCB0aGF0IG1ldGhvZCBpcyBwZXJtaXR0ZWQgdG8gcmV0dXJuCisgICAgICAgICAgICAgICAgbnVsbCBpZiB0aGUgc3lzdGVtIGhhcyBubyBwcm92aWRlciB3aXRoIHRoZSByZXF1ZXN0ZWQgbmFtZS4gQW5kIHNpbmNlIHdlIGRvbid0CisgICAgICAgICAgICAgICAgaGF2ZSB0aGUgU3VuSkNFIHByb3ZpZGVyLCB0ZXN0cyBmYWlsIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLkNpcGhlci5SQzJBcmNGb3VyLkNpcGhlcktBVCIsCisgIHBhdHRlcm46ICIuKk51bGxQb2ludGVyRXhjZXB0aW9uLipDaXBoZXJLQVQuamF2YVxcOjIwNVxcKS4qIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJUaGVzZSBOUEVzIGFsbCBoYXBwZW4gd2hpbGUgY2FsbGluZyBQcm92aWRlciNnZXROYW1lIG9uIHRoZSByZXN1bHQgb2YKKyAgICAgICAgICAgICAgICBTZWN1cml0eSNnZXRQcm92aWRlcigpLiBVbmZvcnR1bmF0ZWx5LCB0aGF0IG1ldGhvZCBpcyBwZXJtaXR0ZWQgdG8gcmV0dXJuCisgICAgICAgICAgICAgICAgbnVsbCBpZiB0aGUgc3lzdGVtIGhhcyBubyBwcm92aWRlciB3aXRoIHRoZSByZXF1ZXN0ZWQgbmFtZS4gQW5kIHNpbmNlIHdlIGRvbid0CisgICAgICAgICAgICAgICAgaGF2ZSB0aGUgU3VuSkNFIHByb3ZpZGVyLCB0ZXN0cyBmYWlsIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLkNpcGhlci5SU0EuVGVzdE9BRVBfS0FUIiwKKyAgcGF0dGVybjogIi4qVGVzdE9BRVBfS0FULmphdmFcXDo2MlxcKS4qTnVsbFBvaW50ZXJFeGNlcHRpb24uKiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGhlc2UgTlBFcyBhbGwgaGFwcGVuIHdoaWxlIGNhbGxpbmcgUHJvdmlkZXIjZ2V0TmFtZSBvbiB0aGUgcmVzdWx0IG9mCisgICAgICAgICAgICAgICAgU2VjdXJpdHkjZ2V0UHJvdmlkZXIoKS4gVW5mb3J0dW5hdGVseSwgdGhhdCBtZXRob2QgaXMgcGVybWl0dGVkIHRvIHJldHVybgorICAgICAgICAgICAgICAgIG51bGwgaWYgdGhlIHN5c3RlbSBoYXMgbm8gcHJvdmlkZXIgd2l0aCB0aGUgcmVxdWVzdGVkIG5hbWUuIEFuZCBzaW5jZSB3ZSBkb24ndAorICAgICAgICAgICAgICAgIGhhdmUgdGhlIFN1bkpDRSBwcm92aWRlciwgdGVzdHMgZmFpbCIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJjb20uc3VuLmNyeXB0by5wcm92aWRlci5DaXBoZXIuUlNBLlRlc3RPQUVQIiwKKyAgcGF0dGVybjogIi4qVGVzdE9BRVAuamF2YVxcOjUwXFwpLipOdWxsUG9pbnRlckV4Y2VwdGlvbi4qIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJUaGVzZSBOUEVzIGFsbCBoYXBwZW4gd2hpbGUgY2FsbGluZyBQcm92aWRlciNnZXROYW1lIG9uIHRoZSByZXN1bHQgb2YKKyAgICAgICAgICAgICAgICBTZWN1cml0eSNnZXRQcm92aWRlcigpLiBVbmZvcnR1bmF0ZWx5LCB0aGF0IG1ldGhvZCBpcyBwZXJtaXR0ZWQgdG8gcmV0dXJuCisgICAgICAgICAgICAgICAgbnVsbCBpZiB0aGUgc3lzdGVtIGhhcyBubyBwcm92aWRlciB3aXRoIHRoZSByZXF1ZXN0ZWQgbmFtZS4gQW5kIHNpbmNlIHdlIGRvbid0CisgICAgICAgICAgICAgICAgaGF2ZSB0aGUgU3VuSkNFIHByb3ZpZGVyLCB0ZXN0cyBmYWlsIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLkNpcGhlci5SU0EuVGVzdE9BRVBQYXJhbWV0ZXJTcGVjIiwKKyAgcGF0dGVybjogIi4qVGVzdE9BRVBQYXJhbWV0ZXJTcGVjLmphdmFcXDoxMjRcXCkuKk51bGxQb2ludGVyRXhjZXB0aW9uLioiCit9LAoreworICBkZXNjcmlwdGlvbjogIlRoZXNlIE5QRXMgYWxsIGhhcHBlbiB3aGlsZSBjYWxsaW5nIFByb3ZpZGVyI2dldE5hbWUgb24gdGhlIHJlc3VsdCBvZgorICAgICAgICAgICAgICAgIFNlY3VyaXR5I2dldFByb3ZpZGVyKCkuIFVuZm9ydHVuYXRlbHksIHRoYXQgbWV0aG9kIGlzIHBlcm1pdHRlZCB0byByZXR1cm4KKyAgICAgICAgICAgICAgICBudWxsIGlmIHRoZSBzeXN0ZW0gaGFzIG5vIHByb3ZpZGVyIHdpdGggdGhlIHJlcXVlc3RlZCBuYW1lLiBBbmQgc2luY2Ugd2UgZG9uJ3QKKyAgICAgICAgICAgICAgICBoYXZlIHRoZSBTdW5KQ0UgcHJvdmlkZXIsIHRlc3RzIGZhaWwiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuQ2lwaGVyLlJTQS5UZXN0T0FFUFdpdGhQYXJhbXMiLAorICBwYXR0ZXJuOiAiLipUZXN0T0FFUFdpdGhQYXJhbXMuamF2YVxcOjU4XFwpLipOdWxsUG9pbnRlckV4Y2VwdGlvbi4qIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJUaGVzZSBOUEVzIGFsbCBoYXBwZW4gd2hpbGUgY2FsbGluZyBQcm92aWRlciNnZXROYW1lIG9uIHRoZSByZXN1bHQgb2YKKyAgICAgICAgICAgICAgICBTZWN1cml0eSNnZXRQcm92aWRlcigpLiBVbmZvcnR1bmF0ZWx5LCB0aGF0IG1ldGhvZCBpcyBwZXJtaXR0ZWQgdG8gcmV0dXJuCisgICAgICAgICAgICAgICAgbnVsbCBpZiB0aGUgc3lzdGVtIGhhcyBubyBwcm92aWRlciB3aXRoIHRoZSByZXF1ZXN0ZWQgbmFtZS4gQW5kIHNpbmNlIHdlIGRvbid0CisgICAgICAgICAgICAgICAgaGF2ZSB0aGUgU3VuSkNFIHByb3ZpZGVyLCB0ZXN0cyBmYWlsIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLkNpcGhlci5SU0EuVGVzdFJTQSIsCisgIHBhdHRlcm46ICIuKlRlc3RSU0EuamF2YVxcOjE3MVxcKS4qTnVsbFBvaW50ZXJFeGNlcHRpb24uKiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGhlc2UgTlBFcyBhbGwgaGFwcGVuIHdoaWxlIGNhbGxpbmcgUHJvdmlkZXIjZ2V0TmFtZSBvbiB0aGUgcmVzdWx0IG9mCisgICAgICAgICAgICAgICAgU2VjdXJpdHkjZ2V0UHJvdmlkZXIoKS4gVW5mb3J0dW5hdGVseSwgdGhhdCBtZXRob2QgaXMgcGVybWl0dGVkIHRvIHJldHVybgorICAgICAgICAgICAgICAgIG51bGwgaWYgdGhlIHN5c3RlbSBoYXMgbm8gcHJvdmlkZXIgd2l0aCB0aGUgcmVxdWVzdGVkIG5hbWUuIEFuZCBzaW5jZSB3ZSBkb24ndAorICAgICAgICAgICAgICAgIGhhdmUgdGhlIFN1bkpDRSBwcm92aWRlciwgdGVzdHMgZmFpbCIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJjb20uc3VuLmNyeXB0by5wcm92aWRlci5NYWMuSG1hY1NhbHRMZW5ndGhzIiwKKyAgcGF0dGVybjogIi4qSG1hY1NhbHRMZW5ndGhzLmphdmFcXDo4M1xcKS4qamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uLioiCit9LAoreworICBkZXNjcmlwdGlvbjogIlRoZXNlIE5QRXMgYWxsIGhhcHBlbiB3aGlsZSBjYWxsaW5nIFByb3ZpZGVyI2dldE5hbWUgb24gdGhlIHJlc3VsdCBvZgorICAgICAgICAgICAgICAgIFNlY3VyaXR5I2dldFByb3ZpZGVyKCkuIFVuZm9ydHVuYXRlbHksIHRoYXQgbWV0aG9kIGlzIHBlcm1pdHRlZCB0byByZXR1cm4KKyAgICAgICAgICAgICAgICBudWxsIGlmIHRoZSBzeXN0ZW0gaGFzIG5vIHByb3ZpZGVyIHdpdGggdGhlIHJlcXVlc3RlZCBuYW1lLiBBbmQgc2luY2Ugd2UgZG9uJ3QKKyAgICAgICAgICAgICAgICBoYXZlIHRoZSBTdW5KQ0UgcHJvdmlkZXIsIHRlc3RzIGZhaWwiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuTWFjLk1hY0tBVCIsCisgIHBhdHRlcm46ICIuKk1hY0tBVC5qYXZhXFw6MjI4XFwpLipqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24uKiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGhlc2UgdGVzdHMgY2FsbCBpbnRvIG1pc2MgU3VuIGNsYXNzZXMgdGhhdCB3ZSBkb24ndCBoYXZlIiwKKyAgcmVzdWx0OiBDT01QSUxFX0ZBSUxFRCwKKyAgbmFtZTogImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLktleUFncmVlbWVudC5ESEtleUFncmVlbWVudDIiLAorICBwYXR0ZXJuOiAiLipjYW5ub3QgZmluZCBzeW1ib2wuKnN1bi5taXNjLkhleER1bXBFbmNvZGVyLioiCit9LAoreworICBkZXNjcmlwdGlvbjogIlRoZXNlIHRlc3RzIGNhbGwgaW50byBtaXNjIFN1biBjbGFzc2VzIHRoYXQgd2UgZG9uJ3QgaGF2ZSIsCisgIHJlc3VsdDogQ09NUElMRV9GQUlMRUQsCisgIG5hbWU6ICJjb20uc3VuLmNyeXB0by5wcm92aWRlci5DaXBoZXIuS2V5V3JhcC5YTUxFbmNLQVQiLAorICBwYXR0ZXJuOiAiLipjYW5ub3QgZmluZCBzeW1ib2wuKnN1bi5taXNjLkJBU0U2NERlY29kZXIuKiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGhlc2UgdGVzdHMgY2FsbCBpbnRvIG1pc2MgU3VuIGNsYXNzZXMgdGhhdCB3ZSBkb24ndCBoYXZlIiwKKyAgcmVzdWx0OiBDT01QSUxFX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuVExTLlRlc3RLZXlNYXRlcmlhbCIsCisgICAgImNvbS5zdW4uY3J5cHRvLnByb3ZpZGVyLlRMUy5UZXN0TWFzdGVyU2VjcmV0IiwKKyAgICAiY29tLnN1bi5jcnlwdG8ucHJvdmlkZXIuVExTLlRlc3RQcmVtYXN0ZXIiLAorICAgICJjb20uc3VuLmNyeXB0by5wcm92aWRlci5UTFMuVGVzdFBSRiIKKyAgXSwKKyAgc3Vic3RyaW5nOiAicGFja2FnZSBzdW4uc2VjdXJpdHkuaW50ZXJuYWwuc3BlYyBkb2VzIG5vdCBleGlzdCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiV2UgZG9uJ3QgaGF2ZSBtb3N0IGNvbS5zdW4gcGFja2FnZXMuIiwKKyAgcmVzdWx0OiBDT01QSUxFX0ZBSUxFRCwKKyAgZmFpbHVyZTogIkRhbHZpayBkb2Vzbid0IGluY2x1ZGUgU3VuIHBhY2thZ2VzIiwKKyAgcGF0dGVybjogIi4qcGFja2FnZSAoY29tXFwuKT9zdW5cXC5bXFx3XFwuXSsgZG9lcyBub3QgZXhpc3QuKiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiV2UgZG9uJ3QgaGF2ZSBzZXZlcmFsIEphdmEgcGFja2FnZXMgZWl0aGVyLiIsCisgIHJlc3VsdDogQ09NUElMRV9GQUlMRUQsCisgIGZhaWx1cmU6ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIGFwcGxldHMiLAorICBzdWJzdHJpbmc6ICJwYWNrYWdlIGphdmEuYXBwbGV0IGRvZXMgbm90IGV4aXN0IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJXZSBkb24ndCBoYXZlIHNldmVyYWwgSmF2YSBwYWNrYWdlcyBlaXRoZXIuIiwKKyAgcmVzdWx0OiBDT01QSUxFX0ZBSUxFRCwKKyAgZmFpbHVyZTogIkRhbHZpayBkb2Vzbid0IGluY2x1ZGUgQVdUIChidWcgaXQgaGFzIGphdmEuYXd0LmZvbnQpIiwKKyAgcGF0dGVybjogIi4qcGFja2FnZSBqYXZhLmF3dChcXC5pbWFnZSk/IGRvZXMgbm90IGV4aXN0LioiCit9LAoreworICBkZXNjcmlwdGlvbjogIldlIGRvbid0IGhhdmUgc2V2ZXJhbCBKYXZhIHBhY2thZ2VzIGVpdGhlci4iLAorICByZXN1bHQ6ICJDT01QSUxFX0ZBSUxFRCIsCisgIGZhaWx1cmU6ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIE5JTy4yIiwKKyAgc3Vic3RyaW5nOiAicGFja2FnZSBqYXZhLm5pby5maWxlIGRvZXMgbm90IGV4aXN0IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJXZSBkb24ndCBoYXZlIHNldmVyYWwgSmF2YSBwYWNrYWdlcyBlaXRoZXIuIiwKKyAgcmVzdWx0OiAiQ09NUElMRV9GQUlMRUQiLAorICBmYWlsdXJlOiAiRGFsdmlrIGRvZXNuJ3QgaW5jbHVkZSBSTUkiLAorICBzdWJzdHJpbmc6ICJwYWNrYWdlIGphdmEucm1pIGRvZXMgbm90IGV4aXN0IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJXZSBkb24ndCBoYXZlIHNldmVyYWwgSmF2YSBwYWNrYWdlcyBlaXRoZXIuIiwKKyAgcmVzdWx0OiAiQ09NUElMRV9GQUlMRUQiLAorICBmYWlsdXJlOiAiRGFsdmlrIGRvZXNuJ3QgaW5jbHVkZSBKTkRJIiwKKyAgc3Vic3RyaW5nOiAicGFja2FnZSBqYXZheC5uYW1pbmcgZG9lcyBub3QgZXhpc3QiCit9LAoreworICBkZXNjcmlwdGlvbjogIldlIGRvbid0IGhhdmUgc2V2ZXJhbCBKYXZhIHBhY2thZ2VzIGVpdGhlci4iLAorICByZXN1bHQ6ICJDT01QSUxFX0ZBSUxFRCIsCisgIGZhaWx1cmU6ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIEpNWCIsCisgIHN1YnN0cmluZzogInBhY2thZ2UgamF2YS5sYW5nLm1hbmFnZW1lbnQgZG9lcyBub3QgZXhpc3QiCit9LAoreworICBkZXNjcmlwdGlvbjogIldlIGRvbid0IGhhdmUgc2V2ZXJhbCBKYXZhIHBhY2thZ2VzIGVpdGhlci4iLAorICByZXN1bHQ6ICJDT01QSUxFX0ZBSUxFRCIsCisgIGZhaWx1cmU6ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIFN3aW5nIiwKKyAgc3Vic3RyaW5nOiAicGFja2FnZSBqYXZheC5zd2luZy50cmVlIGRvZXMgbm90IGV4aXN0IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJXZSBkb24ndCBoYXZlIHNldmVyYWwgSmF2YSBwYWNrYWdlcyBlaXRoZXIuIiwKKyAgcmVzdWx0OiAiQ09NUElMRV9GQUlMRUQiLAorICBmYWlsdXJlOiAiRGFsdmlrIGRvZXNuJ3QgaW5jbHVkZSBqYXZheC5jcnlwdG8iLAorICBzdWJzdHJpbmc6ICJwYWNrYWdlIGphdmF4LnhtbC5jcnlwdG8gZG9lcyBub3QgZXhpc3QiCit9LAoreworICBkZXNjcmlwdGlvbjogIkRhbHZpayBkb2Vzbid0IGluY2x1ZGUgYSBjb20uc3VuLm5ldCBIVFRQIHNlcnZlciIsCisgIHJlc3VsdDogVU5TVVBQT1JURUQsCisgIG5hbWVzOiBbCisgICAgImNvbS5zdW4ubmV0Lmh0dHBzZXJ2ZXIiLAorICAgICJzdW4ubmV0Lnd3dyIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIEFXVCBleGNlcHQgdGhlIGZvbnQgcGFja2FnZSIsCisgIHJlc3VsdDogVU5TVVBQT1JURUQsCisgIG5hbWU6ICJqYXZhLmF3dCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGFsdmlrIGRvZXNuJ3QgaW5jbHVkZSBBV1QgZXhjZXB0IHRoZSBmb250IHBhY2thZ2UiLAorICByZXN1bHQ6ICJTVUNDRVNTIiwKKyAgbmFtZXM6IFsKKyAgICAiamF2YS5hd3QuRm9udENsYXNzIiwKKyAgICAiamF2YS5hd3QuZm9udCIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIGphdmEuYmVhbnMgZXhjZXB0IGZvciBwcm9wZXJ0eSBsaXN0ZW5lcnMiLAorICByZXN1bHQ6IFVOU1VQUE9SVEVELAorICBuYW1lOiAiamF2YS5iZWFucyIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGFsdmlrIGRvZXNuJ3QgaW5jbHVkZSBqYXZhLmJlYW5zIGV4Y2VwdCBmb3IgcHJvcGVydHkgbGlzdGVuZXJzIiwKKyAgcmVzdWx0OiAiU1VDQ0VTUyIsCisgIG5hbWU6ICJqYXZhLmJlYW5zLlByb3BlcnR5Q2hhbmdlU3VwcG9ydCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGFsdmlrIGRvZXNuJ3QgaW5jbHVkZSBqYXZhLmxhbmcuaW5zdHJ1bWVudCIsCisgIHJlc3VsdDogVU5TVVBQT1JURUQsCisgIG5hbWU6ICJqYXZhLmxhbmcuaW5zdHJ1bWVudCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGFsdmlrIGRvZXNuJ3QgaW5jbHVkZSBqYXZhLmxhbmcubWFuYWdlbWVudCIsCisgIHJlc3VsdDogVU5TVVBQT1JURUQsCisgIG5hbWU6ICJqYXZhLmxhbmcubWFuYWdlbWVudCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGFsdmlrIGRvZXNuJ3QgaW5jbHVkZSBSTUkiLAorICByZXN1bHQ6IFVOU1VQUE9SVEVELAorICBuYW1lczogWworICAgICJqYXZhLnJtaSIsCisgICAgInN1bi5ybWkiCisgIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGFsdmlrIGRvZXNuJ3QgaW5jbHVkZSBqYXZheC5pbWFnZWlvIiwKKyAgcmVzdWx0OiBVTlNVUFBPUlRFRCwKKyAgbmFtZTogImphdmF4LmltYWdlaW8iCit9LAoreworICBkZXNjcmlwdGlvbjogIkRhbHZpayBkb2Vzbid0IGluY2x1ZGUgamF2YXgubWFuYWdlbWVudCIsCisgIHJlc3VsdDogVU5TVVBQT1JURUQsCisgIG5hbWU6ICJqYXZheC5tYW5hZ2VtZW50IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBpbmNsdWRlIGphdmF4Lm5hbWluZyIsCisgIHJlc3VsdDogVU5TVVBQT1JURUQsCisgIG5hbWU6ICJqYXZheC5uYW1pbmciCit9LAoreworICBkZXNjcmlwdGlvbjogIkRhbHZpayBkb2Vzbid0IGluY2x1ZGUgamF2YXgucHJpbnQiLAorICByZXN1bHQ6IFVOU1VQUE9SVEVELAorICBuYW1lOiAiamF2YXgucHJpbnQiCit9LAoreworICBkZXNjcmlwdGlvbjogIkRhbHZpayBkb2Vzbid0IGluY2x1ZGUgamF2YXguc2NyaXB0IiwKKyAgcmVzdWx0OiBVTlNVUFBPUlRFRCwKKyAgbmFtZTogImphdmF4LnNjcmlwdCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGFsdmlrIGRvZXNuJ3QgaW5jbHVkZSBqYXZheC5zb3VuZCIsCisgIHJlc3VsdDogVU5TVVBQT1JURUQsCisgIG5hbWU6ICJqYXZheC5zb3VuZCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGFsdmlrIGRvZXNuJ3QgaW5jbHVkZSBqYXZheC5zd2luZyIsCisgIHJlc3VsdDogVU5TVVBQT1JURUQsCisgIG5hbWU6ICJqYXZheC5zd2luZyIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGFsdmlrIGRvZXNuJ3QgaW5jbHVkZSBzdW4ubWFuYWdlbWVudCIsCisgIHJlc3VsdDogVU5TVVBQT1JURUQsCisgIG5hbWU6ICJzdW4ubWFuYWdlbWVudCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGFsdmlrIGRvZXNuJ3QgaW5jbHVkZSBqYXZheC5zbWFydGNhcmRpbyIsCisgIHJlc3VsdDogVU5TVVBQT1JURUQsCisgIG5hbWU6ICJzdW4uc2VjdXJpdHkuc21hcnRjYXJkaW8iCit9LAoreworICBkZXNjcmlwdGlvbjogIk91ciBleGNlcHRpb24gbWVzc2FnZXMgZG9uJ3QgbWF0Y2ggdGhlIFJJcyIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWVzOiBbCisgICAgImphdmEubGFuZy5TdHJpbmdCdWlsZGVyLkV4Y2VwdGlvbnMiLAorICAgICJqYXZhLmxhbmcuU3RyaW5nQnVmZmVyLkV4Y2VwdGlvbnMiCisgIF0sCisgIHN1YnN0cmluZzogImdvdCBqYXZhLmxhbmcuU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbjogbnVsbCAtIEZBSUxFRCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiSUNVIGRvZXNuJ3QgbGlrZSAzLWxldHRlciBuYW1lcyBsaWtlIENTVCBiZWNhdXNlIHRoZXkncmUgYW1iaWd1b3VzLgorICAgICAgICAgICAgICAgIEhhcm1vbnkgcHJlZmVycyB0aGVtIGJlY2F1c2UgdGhleSdyZSBtb3JlIGh1bWFuIHJlYWRhYmxlLiBXZSdsbCBiZQorICAgICAgICAgICAgICAgIGNvbnNpc3RlbnQgd2l0aCBJQ1UsIHNpbmNlIHRoYXQgc2VlbXMgbGVhc3QgZnJhZ2lsZS4KKyAgICAgICAgICAgICAgICBTZWUgaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9IQVJNT05ZLTU0NjgKKyAgICAgICAgICAgICAgICBhbmQgaHR0cDovL2J1Z3MuaWN1LXByb2plY3Qub3JnL3RyYWMvdGlja2V0LzYxNzQiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLkRhdGVUZXN0I3Rlc3RfdG9TdHJpbmciLAorICBzdWJzdHJpbmc6ICJHTVQtMDc6MDAiCit9LAoreworICBkZXNjcmlwdGlvbjogIlRoZXNlIGhhcm1vbnkgdGVzdHMgYXJlIGJyb2tlbi4gVGhlIFJJIGRvZXNuJ3Qgc2hpcCB3aXRoIGVzX19UUkFESVRJT05BTCwgc28KKyAgICAgICAgICAgICAgICB0aGV5IGhhdmUgaW5jb3JyZWN0IGV4cGVjdGF0aW9ucy4KKyAgICAgICAgICAgICAgICBodHRwOi8vYi8yNjA4NzUwIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAib3JnLmFwYWNoZS5oYXJtb255LnRleHQudGVzdHMuamF2YS50ZXh0LlJ1bGVCYXNlZENvbGxhdG9yVGVzdCN0ZXN0R2V0Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yQ2hhcmFjdGVySXRlcmF0b3IiLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkudGV4dC50ZXN0cy5qYXZhLnRleHQuUnVsZUJhc2VkQ29sbGF0b3JUZXN0I3Rlc3RHZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3JTdHJpbmciCisgIF0sCisgIHN1YnN0cmluZzogImV4cGVjdGVkOjwxPiBidXQgd2FzOjwyPiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGhpcyB0ZXN0IGZhaWxzIGJlY2F1c2Ugb24gQW5kcm9pZCwgUnVsZUJhc2VkQ29sbGF0b3JzIGRlZmF1bHQgdG8KKyAgICAgICAgICAgICAgICBDQU5PTklDQUxfREVDT01QT1NJVElPTiwgbm90IE5PX0RFQ09NUE9TSVRJT04uIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogIm9yZy5hcGFjaGUuaGFybW9ueS50ZXh0LnRlc3RzLmphdmEudGV4dC5SdWxlQmFzZWRDb2xsYXRvclRlc3QjdGVzdEVxdWFsc09iamVjdCIsCisgIHN1YnN0cmluZzogImV4cGVjdGVkOjwwPiBidXQgd2FzOjwxPiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGhlc2UgSGFybW9ueSB0ZXN0cyBhcmUgZW5mb3JjaW5nIGEgYnVnZ3kgYmVoYXZpb3VyIGluIFRyZWVNYXAsIHByZXN1bWFibHkgdG8gYmUgYnVnLWNvbXBhdGlibGUKKyAgICAgICAgICAgICAgICB3aXRoIHRoZSBSSS4gT3VyIGltcGxlbWVudGF0aW9uIGlzIG1vcmUgY29uc2VydmF0aXZlIGFuZCB0aHJvd3Mgb24gdGhlIGJvZ3VzIGlucHV0cy4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLlRyZWVNYXBFeHRlbmRUZXN0I3Rlc3RfQXNjZW5kaW5nU3ViTWFwS2V5U2V0X2hlYWRTZXQiLAorICBzdWJzdHJpbmc6ICJqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOiAxMDAgbm90IGluIHJhbmdlICgxMDAuLjEwOV0iCit9LAoreworICBkZXNjcmlwdGlvbjogIlRoZXNlIEhhcm1vbnkgdGVzdHMgYXJlIGVuZm9yY2luZyBhIGJ1Z2d5IGJlaGF2aW91ciBpbiBUcmVlTWFwLCBwcmVzdW1hYmx5IHRvIGJlIGJ1Zy1jb21wYXRpYmxlCisgICAgICAgICAgICAgICAgd2l0aCB0aGUgUkkuIE91ciBpbXBsZW1lbnRhdGlvbiBpcyBtb3JlIGNvbnNlcnZhdGl2ZSBhbmQgdGhyb3dzIG9uIHRoZSBib2d1cyBpbnB1dHMuIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLlRyZWVNYXBFeHRlbmRUZXN0I3Rlc3RfQXNjZW5kaW5nU3ViTWFwS2V5U2V0X3RhaWxTZXQiLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuVHJlZU1hcEV4dGVuZFRlc3QjdGVzdF9EZXNjZW5kaW5nU3ViTWFwS2V5U2V0X2hlYWRTZXQiCisgIF0sCisgIHN1YnN0cmluZzogImphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb246IG51bGwgbm90IGluIHJhbmdlIFsxMDAuLjEwOSkiCit9LAoreworICBkZXNjcmlwdGlvbjogIlRoZXNlIEhhcm1vbnkgdGVzdHMgYXJlIGVuZm9yY2luZyBhIGJ1Z2d5IGJlaGF2aW91ciBpbiBUcmVlTWFwLCBwcmVzdW1hYmx5IHRvIGJlIGJ1Zy1jb21wYXRpYmxlCisgICAgICAgICAgICAgICAgd2l0aCB0aGUgUkkuIE91ciBpbXBsZW1lbnRhdGlvbiBpcyBtb3JlIGNvbnNlcnZhdGl2ZSBhbmQgdGhyb3dzIG9uIHRoZSBib2d1cyBpbnB1dHMuIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLlRyZWVNYXBFeHRlbmRUZXN0I3Rlc3RfRGVzY2VuZGluZ1N1Yk1hcF90YWlsTWFwIiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLlRyZWVNYXBFeHRlbmRUZXN0I3Rlc3RfRGVzY2VuZGluZ1N1Yk1hcEtleVNldF90YWlsU2V0IiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLlRyZWVNYXBFeHRlbmRUZXN0I3Rlc3RfU3ViTWFwX2hlYWRNYXAiCisgIF0sCisgIHN1YnN0cmluZzogImphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb246IDEwMCBub3QgaW4gcmFuZ2UgKDEwMC4uMTA5XSIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAid2h5IGFyZSB0aGV5IHVzaW5nIHJlZmxlY3Rpb24gdG8gdGVzdCBpbXBsZW1lbnRhdGlvbiBkZXRhaWxzPyIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuQXJyYXlzVGVzdCN0ZXN0X3N3YXBfSV9JXyRMamF2YV9sYW5nX09iamVjdCIsCisgIHN1YnN0cmluZzogImphdmEubGFuZy5Ob1N1Y2hNZXRob2RFeGNlcHRpb24iCit9LAoreworICBkZXNjcmlwdGlvbjogImFsbCB0aGVzZSB0ZXN0cyByZWx5IG9uIGEgSGFybW9ueSBidWcgd2hlcmUgVHJlZU1hcHMgbWF5IGhhdmUgYSBzaW5nbGV0b24gbnVsbCwgd2hpY2ggd2UgY2hvb3NlCisgICAgICAgICAgICAgICAgdG8gZGlzYWxsb3cuIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogIm9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmphdmEudXRpbC5TaW1wbGVJbW11dGFibGVFbnRyeVRlc3QjdGVzdF9TaW1wbGVJbW11dGFibGVFbnRyeV9Db25zdHJ1Y3Rvcl9MRW50cnkiLAorICBwYXR0ZXJuOiAiLipqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24uKmF0IGphdmEudXRpbC5UcmVlTWFwLmZpbmQuKiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiYWxsIHRoZXNlIHRlc3RzIHJlbHkgb24gYSBIYXJtb255IGJ1ZyB3aGVyZSBUcmVlTWFwcyBtYXkgaGF2ZSBhIHNpbmdsZXRvbiBudWxsLCB3aGljaCB3ZSBjaG9vc2UKKyAgICAgICAgICAgICAgICB0byBkaXNhbGxvdy4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lczogWworICAgICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuVHJlZU1hcFRlc3QjdGVzdF9jZWlsaW5nRW50cnkiLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuVHJlZU1hcFRlc3QjdGVzdF9jZWlsaW5nS2V5IiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLlRyZWVNYXBUZXN0I3Rlc3RfZmxvb3JFbnRyeSIsCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmphdmEudXRpbC5UcmVlTWFwVGVzdCN0ZXN0X2Zsb29yS2V5IiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLlRyZWVNYXBUZXN0I3Rlc3RfaGlnaGVyRW50cnkiLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuVHJlZU1hcFRlc3QjdGVzdF9oaWdoZXJLZXkiLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuVHJlZU1hcFRlc3QjdGVzdF9sb3dlckVudHJ5IiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLlRyZWVNYXBUZXN0I3Rlc3RfbG93ZXJLZXkiCisgIF0sCisgIHN1YnN0cmluZzogImphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiYWxsIHRoZXNlIHRlc3RzIHJlbHkgb24gYSBIYXJtb255IGJ1ZyB3aGVyZSBUcmVlTWFwcyBtYXkgaGF2ZSBhIHNpbmdsZXRvbiBudWxsLCB3aGljaCB3ZSBjaG9vc2UKKyAgICAgICAgICAgICAgICB0byBkaXNhbGxvdy4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLlRyZWVNYXBUZXN0I3Rlc3RfaWxsZWdhbEZpcnN0TnVsbEtleSIsCisgIHBhdHRlcm46ICIuKmphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbi4qYXQgamF2YS51dGlsLlRyZWVNYXAuZmluZC4qIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJ0aGlzIGlzIHRlc3RpbmcgZXhjZXB0aW9uIHByaW9yaXRpZXMiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLlRyZWVNYXBUZXN0I3Rlc3Rfc3ViTWFwTGphdmFfbGFuZ19PYmplY3RMamF2YV9sYW5nX09iamVjdCIsCisgIHN1YnN0cmluZzogImphdmEubGFuZy5DbGFzc0Nhc3RFeGNlcHRpb246IGphdmEubGFuZy5PYmplY3QiCit9LAoreworICBkZXNjcmlwdGlvbjogInRoZSBudWxsLWZyaWVuZGx5IGNvbXBhcmF0b3IgaXNuJ3Qgc3ltbWV0cmljIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogIm9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmphdmEudXRpbC5UcmVlTWFwVGVzdCN0ZXN0X3N1Yk1hcExqYXZhX2xhbmdfT2JqZWN0WkxqYXZhX2xhbmdfT2JqZWN0WiIsCisgIHN1YnN0cmluZzogImphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAid2UgZmFpbCBmYXN0IG9uIG5vdC1jb21wYXJhYmxlIG9iamVjdHMiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lczogWworICAgICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuVHJlZU1hcFRlc3QjdGVzdF9lcXVhbHMiLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuVHJlZU1hcFRlc3QjdGVzdF9wdXRMamF2YV9sYW5nX09iamVjdExqYXZhX2xhbmdfT2JqZWN0IgorICBdLAorICBzdWJzdHJpbmc6ICJqYXZhLmxhbmcuQ2xhc3NDYXN0RXhjZXB0aW9uOiBqYXZhLmxhbmcuT2JqZWN0IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJ0ZXN0cyB0aGF0IGRlcGVuZCBvbiB0aGUgaXRlcmF0aW9uIG9yZGVyIG9mIGEgaGFzaCIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuQ29sbGVjdGlvbnNUZXN0I3Rlc3RfdW5tb2RpZmlhYmxlX3RvU3RyaW5nX21ldGhvZHMiLAorICBzdWJzdHJpbmc6ICJleHBlY3RlZDo8Li4ub25lPTEsIHR3bz0yLi4uPiBidXQgd2FzOjwuLi50d289Miwgb25lPTEuLi4+IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJ0ZXN0cyB0aGF0IGRlcGVuZCBvbiB0aGUgaXRlcmF0aW9uIG9yZGVyIG9mIGEgaGFzaCIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuSGFzaHRhYmxlVGVzdCN0ZXN0X2tleVNldF9zdWJ0ZXN0MSIsCisgIHBhdHRlcm46ICIuKmphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24uKmF0IGphdmEudXRpbC5IYXNodGFibGUuKiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAidGVzdHMgdGhhdCBkZXBlbmQgb24gdGhlIGl0ZXJhdGlvbiBvcmRlciBvZiBhIGhhc2giLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLkhhc2h0YWJsZVRlc3QjdGVzdF9lbGVtZW50c19zdWJ0ZXN0MCIsCisgIHN1YnN0cmluZzogImp1bml0LmZyYW1ld29yay5Bc3NlcnRpb25GYWlsZWRFcnJvcjogdW5leHBlY3RlZDogYiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAidGVzdHMgdGhhdCBkZXBlbmQgb24gdGhlIGl0ZXJhdGlvbiBvcmRlciBvZiBhIGhhc2giLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLkhhc2hNYXBUZXN0I3Rlc3RfcmVoYXNoIiwKKyAgc3Vic3RyaW5nOiAianVuaXQuZnJhbWV3b3JrLkFzc2VydGlvbkZhaWxlZEVycm9yOiBleHBlY3RlZCBzYW1lIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJ0ZXN0cyB0aGF0IGRlcGVuZCBvbiB0aGUgaXRlcmF0aW9uIG9yZGVyIG9mIGEgaGFzaCIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuUHJvcGVydGllc1Rlc3QjdGVzdF9TZXF1ZW50aWFscHJvcGVydHlOYW1lcyIsCisgIHN1YnN0cmluZzogImV4cGVjdGVkOjxjdXJyZW50LmIua2V5PiBidXQgd2FzOjxjdXJyZW50LmEua2V5PiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAidGVzdHMgdGhhdCBkZXBlbmQgb24gdGhlIGl0ZXJhdGlvbiBvcmRlciBvZiBhIGhhc2giLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLlByb3BlcnRpZXNUZXN0I3Rlc3RfU2VxdWVudGlhbHN0cmluZ1Byb3BlcnR5TmFtZXMiLAorICBzdWJzdHJpbmc6ICJqdW5pdC5mcmFtZXdvcmsuQ29tcGFyaXNvbkZhaWx1cmUiCit9LAoreworICBkZXNjcmlwdGlvbjogInRlc3RzIHRoYXQgZGVwZW5kIG9uIHRoZSBpdGVyYXRpb24gb3JkZXIgb2YgYSBoYXNoIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogIm9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmphdmEudXRpbC5Qcm9wZXJ0aWVzVGVzdCN0ZXN0X3Byb3BlcnR5TmFtZXNfc2VxdWVuY2UiLAorICBzdWJzdHJpbmc6ICJqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0aW9uRmFpbGVkRXJyb3I6IGV4cGVjdGVkOjxjdXJyZW50LmIua2V5PiBidXQgd2FzOjxjdXJyZW50LmEua2V5PiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAidGVzdHMgdGhhdCB1c2Ugc2VjcmV0IHR5cGUgaW5mb3JtYXRpb24gdG8gcmVhc29uIGFib3V0IGJlaGF2aW9yIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogIm9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmphdmEudXRpbC5IYXNodGFibGVUZXN0I3Rlc3Rfa2V5U2V0IiwKKyAgc3Vic3RyaW5nOiAianVuaXQuZnJhbWV3b3JrLkNvbXBhcmlzb25GYWlsdXJlOiBOb3Qgc3luY2hyb25pemVkIGV4cGVjdGVkOjwuLi5Db2xsZWN0aW9ucyRTeW5jaHJvbml6ZWQuLi4+IGJ1dCB3YXM6PC4uLkhhc2h0YWJsZSRLZXkuLi4+IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJ0ZXN0cyB0aGF0IHVzZSBzZWNyZXQgdHlwZSBpbmZvcm1hdGlvbiB0byByZWFzb24gYWJvdXQgYmVoYXZpb3IiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLkhhc2h0YWJsZVRlc3QjdGVzdF9lbnRyeVNldCIsCisgIHN1YnN0cmluZzogImp1bml0LmZyYW1ld29yay5Db21wYXJpc29uRmFpbHVyZTogTm90IHN5bmNocm9uaXplZCBleHBlY3RlZDo8Li4uQ29sbGVjdGlvbnMkU3luY2hyb25pemVkLi4uPiBidXQgd2FzOjwuLi5IYXNodGFibGUkRW50cnkuLi4+IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJ0ZXN0cyB0aGF0IHVzZSBzZWNyZXQgdHlwZSBpbmZvcm1hdGlvbiB0byByZWFzb24gYWJvdXQgYmVoYXZpb3IiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLkhhc2h0YWJsZVRlc3QjdGVzdF92YWx1ZXMiLAorICBzdWJzdHJpbmc6ICJqdW5pdC5mcmFtZXdvcmsuQ29tcGFyaXNvbkZhaWx1cmU6IE5vdCBzeW5jaHJvbml6ZWQgZXhwZWN0ZWQ6PC4uLkNvbGxlY3Rpb25zJFN5bmNocm9uaXplZENvbGxlY3Rpb24+IGJ1dCB3YXM6PC4uLkhhc2h0YWJsZSRWYWx1ZXM+IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJ0aGlzIHRlc3QgaXMgaW52YWxpZCwgcHJveHkuZXF1YWxzIGlzbid0IHN5bW1ldHJpYyIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuSGFzaE1hcFRlc3QjdGVzdF9wcm94aWVzIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJ0aGlzIHRlc3QgaXMgaW52YWxpZCwgdGhlIG1vY2sgbWFwJ3MgZW50cnkgc2V0IGlzbid0IHRvIHNwZWMiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLkhhc2hNYXBUZXN0I3Rlc3RfcHV0QWxsTGphdmFfdXRpbF9NYXAiLAorICBzdWJzdHJpbmc6ICJqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24iCit9LAoreworICBkZXNjcmlwdGlvbjogInRoaXMgdGVzdCBhc3N1bWVzIHJlbW92ZSBhY3RzIG9uIGVxdWFscygpIGVxdWFsaXR5LCBub3QgY29tcGFyYXRvciBlcXVhbGl0eSIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuUHJpb3JpdHlRdWV1ZVRlc3QjdGVzdF9yZW1vdmVfTGphdmFfbGFuZ19PYmplY3RfdXNpbmdfY29tcGFyYXRvciIsCisgIHN1YnN0cmluZzogImp1bml0LmZyYW1ld29yay5Bc3NlcnRpb25GYWlsZWRFcnJvciIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAidGVzdHMgdGhhdCB2aW9sYXRlIHRoZSBBUEkgYW5kIHRoZW4gZ3Vlc3MgYWJvdXQgdGhlIG91dGNvbWVzIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogIm9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmphdmEudXRpbC5IYXNodGFibGVUZXN0I3Rlc3RfZ2V0TGphdmFfbGFuZ19PYmplY3QiLAorICBzdWJzdHJpbmc6ICJqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0aW9uRmFpbGVkRXJyb3IiCit9LAoreworICBkZXNjcmlwdGlvbjogInRoaXMgdGVzdCBhc3N1bWVzIEludGVnZXIudG9TdHJpbmcoKSBhbHdheXMgcmV0dXJucyBhIG5ldyBpbnN0YW5jZSIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwMlRlc3QjdGVzdF9jb250YWluc0tleUxqYXZhX2xhbmdfT2JqZWN0IiwKKyAgc3Vic3RyaW5nOiAianVuaXQuZnJhbWV3b3JrLkFzc2VydGlvbkZhaWxlZEVycm9yOiBSZXR1cm5lZCB0cnVlIGZvciBjb3B5IG9mIHZhbGlkIGtleSIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAidGVzdHMgdGhhdCBjYXN0IHRvIEhhcm1vbnktc3BlY2lmaWMgdHlwZXMiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBmYWlsdXJlOiAiYm9ndXMgY2FzdCB0byBoYXJtb255IEhhc2h0YWJsZSRLZXlFbnVtZXJhdGlvbiIsCisgIHN1YnN0cmluZzogImphdmEudXRpbC5IYXNodGFibGUkS2V5RW51bWVyYXRpb24iCit9LAoreworICBkZXNjcmlwdGlvbjogInRlc3RzIHRoYXQgY2FzdCB0byBIYXJtb255LXNwZWNpZmljIHR5cGVzIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgZmFpbHVyZTogImJvZ3VzIGNhc3QgdG8gSGFzaHRhYmxlJFZhbHVlRW51bWVyYXRpb24iLAorICBzdWJzdHJpbmc6ICJqYXZhLnV0aWwuSGFzaHRhYmxlJFZhbHVlRW51bWVyYXRpb24iCit9LAoreworICBkZXNjcmlwdGlvbjogInRlc3QgZG9lc24ndCBleHBlY3QgaXQsIGJ1dCB0aGUgc3BlYyBwZXJtaXRzIHRoZSBleGNlcHRpb24uIFJJIGFsc28gdGhyb3dzIGhlcmUuIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLlByaW9yaXR5UXVldWVUZXN0I3Rlc3RfcmVtb3ZlX0xqYXZhX2xhbmdfT2JqZWN0X25vdF9Db21wYXRpYmxlIiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLlByaW9yaXR5UXVldWVUZXN0I3Rlc3RfcmVtb3ZlX0xqYXZhX2xhbmdfT2JqZWN0X25vdF9leGlzdHMiCisgIF0sCisgIHN1YnN0cmluZzogImphdmEubGFuZy5DbGFzc0Nhc3RFeGNlcHRpb24iCit9LAoreworICBkZXNjcmlwdGlvbjogImxvY2FsaXphdGlvbiB0ZXN0cyB3aGVyZSBvdXIgZGF0YSBkaXNhZ3JlZSIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuTG9jYWxlVGVzdCN0ZXN0X2dldEF2YWlsYWJsZUxvY2FsZXMiLAorICBzdWJzdHJpbmc6ICJXcm9uZyBudW1iZXIgb2YgbG9jYWxlcyIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAidGVzdCB0aGF0IGVuZm9yY2UgcmVkdW5kYW50IGltcGxlbWVudHMgY2xhdXNlcyIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuTGlua2VkSGFzaE1hcFRlc3QjdGVzdF9nZXRJbnRlcmZhY2VzIiwKKyAgc3Vic3RyaW5nOiAianVuaXQuZnJhbWV3b3JrLkFzc2VydGlvbkZhaWxlZEVycm9yOiBleHBlY3RlZDo8Mz4gYnV0IHdhczo8Mj4iCit9LAoreworICBkZXNjcmlwdGlvbjogInRoaXMgaXMgdGVzdGluZyBleGNlcHRpb24gcHJpb3JpdGllcyIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJvcmcuYXBhY2hlLmhhcm1vbnkubmlvLnRlc3RzLmphdmEubmlvLmNoYW5uZWxzLkRhdGFncmFtQ2hhbm5lbFRlc3QjdGVzdFJlYWRCeXRlQnVmZmVyX3JlYWRPbmx5QnVmIiwKKyAgc3Vic3RyaW5nOiAiamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjogcmVhZC1vbmx5IGJ1ZmZlciIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiSUNVIGRvZXNuJ3QgcHJvdmlkZSBsb2NhbGl6ZWQgcGF0dGVybiBjaGFyYWN0ZXJzLCBhbmQgdGhlc2UgdGVzdHMgYXNzdW1lIHRoZSBsb2NhbGUgdGhleSdyZSB1c2luZyBoYXMgdGhlbS4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255LnRleHQudGVzdHMuamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXRUZXN0I3Rlc3RfYXBwbHlMb2NhbGl6ZWRQYXR0ZXJuTGphdmFfbGFuZ19TdHJpbmciLAorICBzdWJzdHJpbmc6ICJqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOiBJbnZhbGlkIHBhdHRlcm4gY2hhcmFjdGVyICd1JyBpbiAnR3VNdGtIbXNTRURGd1dhaEt6JyIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiSUNVIGRvZXNuJ3QgcHJvdmlkZSBsb2NhbGl6ZWQgcGF0dGVybiBjaGFyYWN0ZXJzLCBhbmQgdGhlc2UgdGVzdHMgYXNzdW1lIHRoZSBsb2NhbGUgdGhleSdyZSB1c2luZyBoYXMgdGhlbS4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255LnRleHQudGVzdHMuamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXRUZXN0I3Rlc3RfdG9Mb2NhbGl6ZWRQYXR0ZXJuIiwKKyAgc3Vic3RyaW5nOiAianVuaXQuZnJhbWV3b3JrLkFzc2VydGlvbkZhaWxlZEVycm9yOiBXcm9uZyBwYXR0ZXJuOiBHeU1ka0htc1NFREZ3V2FoS3oiCit9LAoreworICBkZXNjcmlwdGlvbjogIklDVSBkb2Vzbid0IHByb3ZpZGUgbG9jYWxpemVkIHBhdHRlcm4gY2hhcmFjdGVycywgYW5kIHRoZXNlIHRlc3RzIGFzc3VtZSB0aGUgbG9jYWxlIHRoZXkncmUgdXNpbmcgaGFzIHRoZW0uIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogIm9yZy5hcGFjaGUuaGFybW9ueS50ZXh0LnRlc3RzLmphdmEudGV4dC5EYXRlRm9ybWF0U3ltYm9sc1Rlc3QjdGVzdF9nZXRMb2NhbFBhdHRlcm5DaGFycyIsCisgIHN1YnN0cmluZzogImp1bml0LmZyYW1ld29yay5Db21wYXJpc29uRmFpbHVyZTogUmV0dXJuZWQgaW5jb3JyZWN0IHBhdHRlcm4gc3RyaW5nIGV4cGVjdGVkOjwuLi5ZZXVnQVp2Y0xRcVY+IGJ1dCB3YXM6PC4uLlo+IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJ3ZSBkb24ndCBzdXBwb3J0IHRoZSBDaGFyc2V0UHJvdmlkZXIgc3BpLCBzbyB3ZSBkb24ndCBoYXZlIFwibW9ja0NoYXJzZXQwMFwiLiIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJ0ZXN0cy5hcGkuamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0VGVzdCN0ZXN0X2F2YWlsYWJsZUNoYXJzZXRzIiwKKyAgc3Vic3RyaW5nOiAianVuaXQuZnJhbWV3b3JrLkFzc2VydGlvbkZhaWxlZEVycm9yIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJ3ZSBkb24ndCBzdXBwb3J0IHRoZSBDaGFyc2V0UHJvdmlkZXIgc3BpLCBzbyB3ZSBkb24ndCBoYXZlIFwibW9ja0NoYXJzZXQwMFwiLiIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJ0ZXN0cy5hcGkuamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0VGVzdCN0ZXN0X2Zvck5hbWVMU3RyaW5nIiwKKyAgc3Vic3RyaW5nOiAiamF2YS5uaW8uY2hhcnNldC5VbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb246IG1vY2tDaGFyc2V0MDAiCit9LAoreworICBkZXNjcmlwdGlvbjogInRoZSBhdmVyYWdlIGxlbmd0aCBvZiBwb3NzaWJsZSBVVEYtOCBzZXF1ZW5jZXMgaXMgMiBieXRlcy4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAidGVzdHMuYXBpLmphdmEubmlvLmNoYXJzZXQuVVRGQ2hhcnNldEVuY29kZXJUZXN0I3Rlc3RTcGVjaWZpY0RlZmF1bHRWYWx1ZSIsCisgIHN1YnN0cmluZzogImp1bml0LmZyYW1ld29yay5Bc3NlcnRpb25GYWlsZWRFcnJvcjogZXhwZWN0ZWQ6PDEuMT4gYnV0IHdhczo8Mi4wPiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiV2UgZG9uJ3QgcGVybWl0IHJ1bnRpbWUgc3dpdGNoaW5nIG9mIHRoZSBkZWZhdWx0IGNoYXJzZXQgKGFuZCBuZWl0aGVyIGRvZXMgdGhlIFJJKSIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJvcmcuYXBhY2hlLmhhcm1vbnkubmlvX2NoYXIudGVzdHMuamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0VGVzdCN0ZXN0X2RlZmF1bHRDaGFyc2V0IiwKKyAgc3Vic3RyaW5nOiAiZXhwZWN0ZWQ6PElTTy04ODU5LTE+IGJ1dCB3YXM6PFVURi04PiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAidGhpcyB0ZXN0IG5lZWRzIGV4dGVybmFsIGludGVyYWN0aW9uIiwKKyAgcmVzdWx0OiBVTlNVUFBPUlRFRCwKKyAgbmFtZXM6IFsKKyAgICAiY29tLnN1bi50b29scy5hdHRhY2guQXBwbGljYXRpb24iLAorICAgICJqYXZhLmlvLlN5c3RlbUluQXZhaWxhYmxlIiwKKyAgICAic3VuLmp2bXN0YXQudGVzdGxpYnJhcnkuU2xlZXBlciIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJ0aGVzZSBiZW5jaG1hcmtzIHRha2UgYSBsb25nIHRpbWUgYW5kIGRvbid0IGRlbW9uc3RyYXRlIGNvcnJlY3RuZXNzIiwKKyAgcmVzdWx0OiBVTlNVUFBPUlRFRCwKKyAgbmFtZXM6IFsKKyAgICAiamF2YS5sYW5nLkNsYXNzLlR5cGVDaGVja01pY3JvQmVuY2htYXJrIiwKKyAgICAiamF2YS5uaW8uQnVmZmVyLlN3YXBNaWNyb0JlbmNobWFyayIsCisgICAgImphdmEudXRpbC5BcnJheUxpc3QuUmFuZ2VDaGVja01pY3JvQmVuY2htYXJrIiwKKyAgICAiamF2YS51dGlsLkFycmF5TGlzdC5JdGVyYXRvck1pY3JvQmVuY2htYXJrIgorICBdCit9LAoreworICBkZXNjcmlwdGlvbjogIlRoZSBSSSBpcyBzdGlsbCBvbiBVbmljb2RlIDQuMCwgd2UncmUgb24gNS4yLCBhbmQgSGFybW9ueSBpcyBpbmNvbnNpc3RlbnQKKyAgICAgICAgICAgICAgICBiZXR3ZWVuIGl0cyB0ZXN0IGZvciBpc0phdmFJZGVudGlmaWVyUGFydChjaGFyKSBhbmQgaXNKYXZhSWRlbnRpZmllclBhcnQoaW50KS4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS5sYW5nLkNoYXJhY3RlclRlc3QjdGVzdF9pc0phdmFJZGVudGlmaWVyUGFydEMiCit9LAoreworICBkZXNjcmlwdGlvbjogIldlIHJlbW92ZWQgdGhpczogd2UgZG9uJ3Qgc3VwcG9ydCBQYWNrMjAwLiIsCisgIHJlc3VsdDogVU5TVVBQT1JURUQsCisgIG5hbWU6ICJvcmcuYXBhY2hlLmhhcm1vbnkuYXJjaGl2ZS50ZXN0cy5qYXZhLnV0aWwuamFyLlBhY2syMDBUZXN0IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJXZSByZW1vdmVkIHRoaXM6IHdlIGRvbid0IGNhY2hlIGNhbm9uaWNhbCBwYXRocy4iLAorICByZXN1bHQ6IFVOU1VQUE9SVEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS5pby5GaWxlQ2Fub25QYXRoQ2FjaGVUZXN0IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJXZSByZW1vdmVkIHRoaXM6IHdlIGRvbid0IHRocm93IE5vdFlldEltcGxlbWVudGVkRXhjZXB0aW9uLiIsCisgIHJlc3VsdDogVU5TVVBQT1JURUQsCisgIG5hbWU6ICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy51dGlsLk5ZSVRlc3QiCit9LAoreworICBkZXNjcmlwdGlvbjogIldlIHJlbW92ZWQgdGhpczogd2UgZG9uJ3Qgc3VwcG9ydCBsb2NhbGl6ZWQgZXhjZXB0aW9ucy4iLAorICByZXN1bHQ6IFVOU1VQUE9SVEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuaW50ZXJuYWwubmxzLk1lc3NhZ2VzVGVzdCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGhlc2UgdGVzdCBpbXBsZW1lbnRhdGlvbiBkZXRhaWxzIHdlIGRvbid0IHNoYXJlLiIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWVzOiBbCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS50ZXh0LnRlc3RzLmphdmEudGV4dC5CcmVha0l0ZXJhdG9yVGVzdCN0ZXN0X2dldEludCIsCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS50ZXh0LnRlc3RzLmphdmEudGV4dC5CcmVha0l0ZXJhdG9yVGVzdCN0ZXN0X2dldExvbmciLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkudGV4dC50ZXN0cy5qYXZhLnRleHQuQnJlYWtJdGVyYXRvclRlc3QjdGVzdF9nZXRTaG9ydCIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJUaGVzZSBmb3JtYXQgc3BlY2lmaWVycyBhcmUgZG9jdW1lbnRlZCB0byBub3QgdGFrZSBmbGFncywgYnV0IHRoZSBSSSBhY2NlcHRzIGFuZCBpZ25vcmVzIHRoZW0uIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogIm9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmphdmEudXRpbC5Gb3JtYXR0ZXJUZXN0I3Rlc3RfZm9ybWF0TGphdmFfbGFuZ19TdHJpbmckTGphdmFfbGFuZ19PYmplY3RfTGluZVNlcGFyYXRvciIsCisgIHN1YnN0cmluZzogImphdmEudXRpbC5JbGxlZ2FsRm9ybWF0RmxhZ3NFeGNlcHRpb246ICVuIGRvZXNuJ3QgdGFrZSBhbiBhcmd1bWVudCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGhlc2UgZm9ybWF0IHNwZWNpZmllcnMgYXJlIGRvY3VtZW50ZWQgdG8gbm90IHRha2UgZmxhZ3MsIGJ1dCB0aGUgUkkgYWNjZXB0cyBhbmQgaWdub3JlcyB0aGVtLiIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWVzOiBbCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmphdmEudXRpbC5Gb3JtYXR0ZXJUZXN0I3Rlc3RfZm9ybWF0TGphdmFfbGFuZ19TdHJpbmckTGphdmFfbGFuZ19PYmplY3RfUGVyY2VudCIsCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmphdmEudXRpbC5Gb3JtYXR0ZXJUZXN0I3Rlc3RfZm9ybWF0TGphdmFfbGFuZ19TdHJpbmckTGphdmFfbGFuZ19PYmplY3RfV2lkdGgiCisgIF0sCisgIHN1YnN0cmluZzogImphdmEudXRpbC5JbGxlZ2FsRm9ybWF0RmxhZ3NFeGNlcHRpb246ICUlIGRvZXNuJ3QgdGFrZSBhbiBhcmd1bWVudCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGhlc2UgdGVzdHMgZXhwZWN0IHRvIGJlIGFibGUgdG8gbG9hZCByZXNvdXJjZXMgZnJvbSB0aGUgZmlsZSBzeXN0ZW0iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lczogWworICAgICJsaWJjb3JlLmphdmEubGFuZy5PbGRDbGFzc1Rlc3QjdGVzdF9nZXRSZXNvdXJjZUFzU3RyZWFtTGphdmFfbGFuZ19TdHJpbmciLAorICAgICJsaWJjb3JlLmphdmEubGFuZy5PbGRDbGFzc1Rlc3QjdGVzdF9nZXRSZXNvdXJjZUFzU3RyZWFtX3dpdGhTaGFycENoYXIiLAorICAgICJsaWJjb3JlLmphdmEubGFuZy5PbGRDbGFzc1Rlc3QjdGVzdF9nZXRSZXNvdXJjZUxqYXZhX2xhbmdfU3RyaW5nIgorICBdCit9LAoreworICBkZXNjcmlwdGlvbjogIlNvbWUgdGVzdHMgKEV4Y2x1ZGVkUHJveHlUZXN0KSBjb25uZWN0IHRvIGEgcHVibGljIHdlYnNlcnZlciB0byBjaGVjayB0aGF0IHRoZSBIVFRQIGNsaWVudCB3b3JrcyIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIGZhaWx1cmU6ICJjb25uZWN0IHRvIHRoZSBJbnRlcm5ldCIsCisgIHBhdHRlcm46ICIuKmphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uOi4qamNsdGVzdC5hcGFjaGUub3JnLioiCit9LAoreworICBkZXNjcmlwdGlvbjogIlRoZXNlIHRlc3RzIHZpb2xhdGUgdmlzaWJpbGl0eSBydWxlcyB3aGVuIHRyeWluZyB0byB1bml0IHRlc3QgaW50ZXJuYWwgY2xhc3NlcyIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJqYXZheC5uZXQuc3NsLkRlZmF1bHRTU0xTb2NrZXRGYWN0b3J5VGVzdCIsCisgIHN1YnN0cmluZzogImphdmEubGFuZy5JbGxlZ2FsQWNjZXNzRXJyb3I6IHRyaWVkIHRvIGFjY2VzcyBjbGFzcyBqYXZheC5uZXQuc3NsLkRlZmF1bHRTU0xTb2NrZXRGYWN0b3J5IGZyb20gY2xhc3MgamF2YXgubmV0LnNzbC5EZWZhdWx0U1NMU29ja2V0RmFjdG9yeVRlc3QiCit9LAoreworICBkZXNjcmlwdGlvbjogIlRoZXNlIHRlc3RzIGV4cGVjdCB0byBiZSBjYWxsZWQgd2l0aCBjb21tYW5kbGluZSBhcmd1bWVudHMiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAiamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtLkZpbGVPcGVuTmVnIiwKKyAgc3Vic3RyaW5nOiAiamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogImphdmEuaW8uRmlsZU91dHB1dFN0cmVhbS5GaWxlT3BlblBvcyIsCisgIHN1YnN0cmluZzogImphdmEubGFuZy5BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iCit9CitdCmRpZmYgLS1naXQgYS9leHBlY3RhdGlvbnMvaWNlYm94LnR4dCBiL2V4cGVjdGF0aW9ucy9pY2Vib3gudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA5ZTA1ZTIKLS0tIC9kZXYvbnVsbAorKysgYi9leHBlY3RhdGlvbnMvaWNlYm94LnR4dApAQCAtMCwwICsxLDIxNCBAQAorLyoKKyAqIFRoaXMgZmlsZSBjb250YWlucyBleHBlY3RhdGlvbnMgZm9yIHRlc3RzIHRoYXQgd2UnZCBsaWtlIHRvIGV2ZW50dWFsbHkgZml4LCBidXQgYXJlbid0IHVyZ2VudC4KKyAqLworWworeworIGRlc2NyaXB0aW9uOiAiamF2YXNxbGl0ZSBkb2Vzbid0IGhvbm9yIHF1ZXJ5IHRpbWVvdXRzIiwKKyBidWc6IDUyMTM2MTQsCisgbmFtZXM6IFsKKyAgICJsaWJjb3JlLnNxbGl0ZS5RdWVyeVRpbWVvdXRUZXN0I3Rlc3RFeGVjdXRlVXBkYXRlIiwKKyAgICJsaWJjb3JlLnNxbGl0ZS5RdWVyeVRpbWVvdXRUZXN0I3Rlc3RQcmVwYXJlZFN0YXRlbWVudEZldGNoIiwKKyAgICJsaWJjb3JlLnNxbGl0ZS5RdWVyeVRpbWVvdXRUZXN0I3Rlc3RQcmVwYXJlZFN0YXRlbWVudFVwZGF0ZSIsCisgICAibGliY29yZS5zcWxpdGUuUXVlcnlUaW1lb3V0VGVzdCN0ZXN0VGltZW91dEFuZFN0YXRlbWVudFJldXNlIgorICBdCit9LAoreworICBkZXNjcmlwdGlvbjogIkRhbHZpayBkb2Vzbid0IHN1cHBvcnQgWE1MIFNjaGVtYXMsIERURHMgb3IgdmFsaWRhdGlvbiIsCisgIGJ1ZzogMzI2ODYzMCwKKyAgbmFtZTogImxpYmNvcmUueG1sLkRvbVRlc3QjdGVzdEVudGl0eURlY2xhcmF0aW9ucyIsCisgIHN1YnN0cmluZzogIlRoaXMgaW1wbGVtZW50YXRpb24gZG9lcyBub3QgcGFyc2UgZW50aXR5IGRlY2xhcmF0aW9ucyIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGFsdmlrIGRvZXNuJ3Qgc3VwcG9ydCBYTUwgU2NoZW1hcywgRFREcyBvciB2YWxpZGF0aW9uIiwKKyAgYnVnOiAzMjY4NjMwLAorICBuYW1lOiAibGliY29yZS54bWwuRG9tVGVzdCN0ZXN0R2V0V2hvbGVUZXh0V2l0aEVudGl0eVJlZmVyZW5jZSIsCisgIHN1YnN0cmluZzogIlRoaXMgaW1wbGVtZW50YXRpb24gZG9lc24ndCByZXNvbHZlIGVudGl0eSByZWZlcmVuY2VzIGluIGdldFdob2xlVGV4dCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGFsdmlrIGRvZXNuJ3Qgc3VwcG9ydCBYTUwgU2NoZW1hcywgRFREcyBvciB2YWxpZGF0aW9uIiwKKyAgbmFtZTogImxpYmNvcmUueG1sLkRvbVRlc3QjdGVzdEV4cGFuZGluZ0VudGl0eVJlZmVyZW5jZXNPZmYiLAorICBidWc6IDMyNjg2MzAsCisgIHN1YnN0cmluZzogIlRoaXMgaW1wbGVtZW50YXRpb24gZG9lc24ndCBpbmNsdWRlIGNoaWxkcmVuIGluIGVudGl0eSByZWZlcmVuY2VzIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBzdXBwb3J0IFhNTCBTY2hlbWFzLCBEVERzIG9yIHZhbGlkYXRpb24iLAorICBuYW1lOiAibGliY29yZS54bWwuRG9tVGVzdCN0ZXN0RXhwYW5kaW5nRW50aXR5UmVmZXJlbmNlc09uIiwKKyAgYnVnOiAzMjY4NjMwLAorICBzdWJzdHJpbmc6ICJUaGlzIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgZXhwYW5kIGVudGl0eSByZWZlcmVuY2VzIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBzdXBwb3J0IFhNTCBTY2hlbWFzLCBEVERzIG9yIHZhbGlkYXRpb24iLAorICBidWc6IDMyNjg2MzAsCisgIG5hbWU6ICJsaWJjb3JlLnhtbC5Eb21UZXN0I3Rlc3RJc0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZVdpdGhEZWNsYXJhdGlvbiIsCisgIHN1YnN0cmluZzogIlRoaXMgaW1wbGVtZW50YXRpb24gZG9lcyBub3QgcmVjb2duaXplIGVsZW1lbnQgY29udGVudCB3aGl0ZXNwYWNlIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBzdXBwb3J0IFhNTCBTY2hlbWFzLCBEVERzIG9yIHZhbGlkYXRpb24iLAorICBidWc6IDMyNjg2MzAsCisgIG5hbWU6ICJsaWJjb3JlLnhtbC5Eb21UZXN0I3Rlc3ROb3RhdGlvbnMiLAorICBzdWJzdHJpbmc6ICJUaGlzIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHBhcnNlIG5vdGF0aW9ucyIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGFsdmlrIGRvZXNuJ3Qgc3VwcG9ydCBYTUwgU2NoZW1hcywgRFREcyBvciB2YWxpZGF0aW9uIiwKKyAgYnVnOiAzMjY4NjMwLAorICBuYW1lczogWworICAgICJ0ZXN0cy5vcmcudzNjLmRvbS5IQ05vdGF0aW9uc1JlbW92ZU5hbWVkSXRlbU5TI3Rlc3RSZW1vdmVOYW1lZEl0ZW1OUyIsCisgICAgInRlc3RzLm9yZy53M2MuZG9tLkhDTm90YXRpb25zU2V0TmFtZWRJdGVtTlMjdGVzdE5vdGF0aW9uc1NldE5hbWVkSXRlbU5TIgorICBdCit9LAoreworICBkZXNjcmlwdGlvbjogIkRhbHZpayBkb2Vzbid0IHN1cHBvcnQgWE1MIFNjaGVtYXMsIERURHMgb3IgdmFsaWRhdGlvbiIsCisgIGJ1ZzogMzI2ODYzMCwKKyAgbmFtZTogImxpYmNvcmUueG1sLkRlY2xhcmF0aW9uVGVzdCN0ZXN0R2V0WG1sRW5jb2RpbmciLAorICBzdWJzdHJpbmc6ICJUaGlzIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgcGFyc2UgdGhlIGVuY29kaW5nIGZyb20gdGhlIFhNTCBkZWNsYXJhdGlvbiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGFsdmlrIGRvZXNuJ3Qgc3VwcG9ydCBYTUwgU2NoZW1hcywgRFREcyBvciB2YWxpZGF0aW9uIiwKKyAgYnVnOiAzMjY4NjMwLAorICBuYW1lOiAibGliY29yZS54bWwuRGVjbGFyYXRpb25UZXN0I3Rlc3RHZXRYbWxTdGFuZGFsb25lIiwKKyAgc3Vic3RyaW5nOiAiVGhpcyBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHBhcnNlIHN0YW5kYWxvbmUgZnJvbSB0aGUgWE1MIGRlY2xhcmF0aW9uIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBzdXBwb3J0IFhNTCBTY2hlbWFzLCBEVERzIG9yIHZhbGlkYXRpb24iLAorICBidWc6IDMyNjg2MzAsCisgIG5hbWU6ICJsaWJjb3JlLnhtbC5EZWNsYXJhdGlvblRlc3QjdGVzdEdldFhtbFZlcnNpb24iLAorICBzdWJzdHJpbmc6ICJUaGlzIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgcGFyc2UgdGhlIHZlcnNpb24gZnJvbSB0aGUgWE1MIGRlY2xhcmF0aW9uIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEYWx2aWsgZG9lc24ndCBzdXBwb3J0IFhNTCBTY2hlbWFzLCBEVERzIG9yIHZhbGlkYXRpb24iLAorICBidWc6IDMyNjg2MzAsCisgIG5hbWU6ICJsaWJjb3JlLnhtbC5Ob3JtYWxpemVUZXN0I3Rlc3RTY2hlbWFUeXBlRHRkIiwKKyAgc3Vic3RyaW5nOiAiVGhpcyBpbXBsZW1lbnRhdGlvbidzIHNldFBhcmFtZXRlcigpIHN1cHBvcnRzIGFuIHVuZXhwZWN0ZWQgdmFsdWU6IHNjaGVtYS10eXBlPWh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwiCit9LAoreworICBkZXNjcmlwdGlvbjogIkRhbHZpayBkb2Vzbid0IHN1cHBvcnQgWE1MIFNjaGVtYXMsIERURHMgb3IgdmFsaWRhdGlvbiIsCisgIGJ1ZzogMzI2ODYzMCwKKyAgbmFtZTogInRlc3RzLmFwaS5qYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJUZXN0I3Rlc3RTZXRFbnRpdHlSZXNvbHZlciIsCisgIHN1YnN0cmluZzogImphdmEubGFuZy5DbGFzc0Nhc3RFeGNlcHRpb246IG9yZy5hcGFjaGUuaGFybW9ueS54bWwuZG9tLkVudGl0eVJlZmVyZW5jZUltcGwiCit9LAoreworICBkZXNjcmlwdGlvbjogIkRhbHZpayBkb2Vzbid0IHN1cHBvcnQgWE1MIFNjaGVtYXMsIERURHMgb3IgdmFsaWRhdGlvbiIsCisgIGJ1ZzogMzI2ODYzMCwKKyAgbmFtZTogImxpYmNvcmUueG1sLkRlY2xhcmF0aW9uVGVzdC50ZXN0R2V0WG1sVmVyc2lvbiIsCisgIHN1YnN0cmluZzogIlRoaXMgaW1wbGVtZW50YXRpb24gZG9lc24ndCBwYXJzZSB0aGUgdmVyc2lvbiBmcm9tIHRoZSBYTUwgZGVjbGFyYXRpb24iCit9LAoreworICBkZXNjcmlwdGlvbjogInRoZSBsYWNrIG9mIHNjaGVtYSBwYXJzaW5nIGFsc28gZXh0ZW5kcyB0byBYTUwgcGFyc2luZyBpbiBwcmVmcyIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJvcmcuYXBhY2hlLmhhcm1vbnkucHJlZnMudGVzdHMuamF2YS51dGlsLnByZWZzLlByZWZlcmVuY2VzVGVzdCN0ZXN0SW1wb3J0UHJlZmVyZW5jZXMiLAorICBzdWJzdHJpbmc6ICJqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0aW9uRmFpbGVkRXJyb3I6IHNob3VsZCB0aHJvdyBJbnZhbGlkUHJlZmVyZW5jZXNGb3JtYXRFeGNlcHRpb24iCit9LAoreworICBkZXNjcmlwdGlvbjogIm1hbnkgdGVzdHMgYXR0ZW1wdCB0byBmb3JrIGEgSmF2YSBleGVjdXRhYmxlLCBidXQgZm9yayB0aGUgd3Jvbmcgb25lIiwKKyAgcmVzdWx0OiAiRVhFQ19GQUlMRUQiLAorICBmYWlsdXJlOiAic2hvdWxkIGZvcmsgYSBkYWx2aWt2bSwgbm90IGEgSlZNIiwKKyAgc3Vic3RyaW5nOiAiL3N5c3RlbS9iaW4uKklPRXhjZXB0aW9uIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJhIGxvdyBpbXBhY3QgYnVnLCB3ZSBjYW4ndCBwcm9kdWNlIHRpbnkgcmFuZG9tLCBwcm9iYWJsZSBwcmltZSBiaWcgaW50ZWdlcnMiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAidGVzdHMuYXBpLmphdmEubWF0aC5CaWdJbnRlZ2VyVGVzdCN0ZXN0X0NvbnN0cnVjdG9ySUlMamF2YV91dGlsX1JhbmRvbSIsCisgIHN1YnN0cmluZzogImp1bml0LmZyYW1ld29yay5Bc3NlcnRpb25GYWlsZWRFcnJvcjogUmFuZG9tIG51bWJlciBvbmUgaXMgdG9vIGJpZyIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAid2UgZG9uJ3Qgc3VwcG9ydCBDQU5PTl9FUSBpbiByZWdleAorICAgICAgICAgICAgICAgIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9ODU5MiIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWVzOiBbCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS50ZXN0cy5qYXZhLnV0aWwucmVnZXguUGF0dGVyblRlc3QjdGVzdENhbm9uRXFGbGFnV2l0aFN1cHBsZW1lbnRhcnlDaGFyYWN0ZXJzIiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255LnRlc3RzLmphdmEudXRpbC5yZWdleC5QYXR0ZXJuVGVzdCN0ZXN0Q2Fub25FcUZsYWciLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkudGVzdHMuamF2YS51dGlsLnJlZ2V4LlBhdHRlcm5FcnJvclRlc3QjdGVzdENvbXBpbGVFcnJvcnMiLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkudGVzdHMuamF2YS51dGlsLnJlZ2V4LlBhdHRlcm5UZXN0I3Rlc3RDb21waWxlTm9uQ2FwdEdyb3VwIiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255LnRlc3RzLmphdmEudXRpbC5yZWdleC5QYXR0ZXJuVGVzdCN0ZXN0SW5kZXhlc0Nhbm9uaWNhbEVxIgorICBdLAorICBzdWJzdHJpbmc6ICJVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbjogQ0FOT05fRVEgZmxhZyBub3Qgc3VwcG9ydGVkIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJsb3ctaW1wYWN0IFhNTCBidWdzOiIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJsaWJjb3JlLnhtbC5Eb21UZXN0I3Rlc3RBdHRyaWJ1dGVOYW1lZElkSXNOb3RBbklkQnlEZWZhdWx0IiwKKyAgc3Vic3RyaW5nOiAiVGhpcyBpbXBsZW1lbnRhdGlvbiBpbmNvcnJlY3RseSBpbnRlcnByZXRzIHRoZSBcImlkXCIgYXR0cmlidXRlIGFzIGFuIGlkZW50aWZpZXIgYnkgZGVmYXVsdCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAibG93LWltcGFjdCBYTUwgYnVnczoiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAibGliY29yZS54bWwuRG9tVGVzdCN0ZXN0RG9jdW1lbnRBZGRDaGlsZCIsCisgIHN1YnN0cmluZzogIkRvY3VtZW50IG5vZGVzIHNob3VsZG4ndCBhY2NlcHQgY2hpbGQgbm9kZXMiCit9LAoreworICBkZXNjcmlwdGlvbjogImxvdy1pbXBhY3QgWE1MIGJ1Z3M6IiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogImxpYmNvcmUueG1sLkRvbVRlc3QjdGVzdEVsZW1lbnRUcmF2ZXJzYWxGZWF0dXJlIiwKKyAgc3Vic3RyaW5nOiAiVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBleHBlY3RlZCB0byBzdXBwb3J0IEVsZW1lbnRUcmF2ZXJzYWwgdi4gMS4wIGJ1dCBkb2VzIG5vdC4iCit9LAoreworICBkZXNjcmlwdGlvbjogImxvdy1pbXBhY3QgWE1MIGJ1Z3M6IiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogImxpYmNvcmUueG1sLkRvbVRlc3QjdGVzdExvYWRTYXZlRmVhdHVyZSIsCisgIHN1YnN0cmluZzogIlRoaXMgaW1wbGVtZW50YXRpb24gaXMgZXhwZWN0ZWQgdG8gc3VwcG9ydCBMUyB2LiAzLjAgYnV0IGRvZXMgbm90LiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAibG93LWltcGFjdCBYTUwgYnVnczoiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAibGliY29yZS54bWwuU2F4VGVzdCN0ZXN0WWVzUHJlZml4ZXNZZXNOYW1lc3BhY2VzIiwKKyAgc3Vic3RyaW5nOiAiVGhlICduYW1lc3BhY2UtcHJlZml4JyBmZWF0dXJlIGlzIG5vdCBzdXBwb3J0ZWQgd2hpbGUgdGhlICduYW1lc3BhY2VzJyBmZWF0dXJlIGlzIGVuYWJsZWQuIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJsb3ctaW1wYWN0IFhNTCBidWdzOiIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJ0ZXN0cy5hcGkuamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeVRlc3QjdGVzdF9uZXdJbnN0YW5jZSIsCisgIHN1YnN0cmluZzogIkV4cGVjdGVkIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3Igd2FzIG5vdCB0aHJvd24iCit9LAoreworICBkZXNjcmlwdGlvbjogImxvdy1pbXBhY3QgWE1MIGJ1Z3M6IiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAidGVzdHMuYXBpLmphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3RvcnlUZXN0I3Rlc3RfaXNTZXRYSW5jbHVkZUF3YXJlIiwKKyAgICAidGVzdHMuYXBpLmphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlclRlc3QjdGVzdElzWEluY2x1ZGVBd2FyZSIsCisgICAgInRlc3RzLmFwaS5qYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5VGVzdCN0ZXN0X3NldElzWEluY2x1ZGVBd2FyZSIsCisgICAgInRlc3RzLmFwaS5qYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJUZXN0I3Rlc3RJc1hJbmNsdWRlQXdhcmUiCisgIF0sCisgIHN1YnN0cmluZzogImphdmEubGFuZy5VbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbjogVGhpcyBwYXJzZXIgZG9lcyBub3Qgc3VwcG9ydCBzcGVjaWZpY2F0aW9uIFwiVW5rbm93blwiIHZlcnNpb24gXCIwLjBcIiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiYSBsb3ctaW1wYWN0IGJ1ZzogXCJTaGFyZWQgRmlsZURlc2NyaXB0b3JzIGdldCBjbG9zZWQgdG9vIGVhcmx5XCIKKyAgICAgICAgICAgICAgICAgIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9NTkyMyIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJqYXZhLmlvLkZpbGVEZXNjcmlwdG9yLkZpbmFsaXplIiwKKyAgcGF0dGVybjogIi4qamF2YS5pby5JT0V4Y2VwdGlvbi4qb3BlbkNoZWNrLioiCit9LAoreworICBkZXNjcmlwdGlvbjogImEgbG93LWltcGFjdCBidWcsIGFsc28gcHJlc2VudCBpbiBDcm9ja2ZvcmQncyBpbXBsZW1lbnRhdGlvbiBvZiBvcmcuanNvbiIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJvcmcuanNvbi5QYXJzaW5nVGVzdCN0ZXN0NjRCaXRIZXhWYWx1ZXMiLAorICBzdWJzdHJpbmc6ICJMYXJnZSBoZXggbG9uZ3Mgc2hvdWxkbid0IGJlIHlpZWxkIGludHMgb3Igc3RyaW5ncyBleHBlY3RlZDo8LTE+IGJ1dCB3YXM6PDB4RkZGRkZGRkZGRkZGRkZGRj4iCit9LAoreworICBkZXNjcmlwdGlvbjogInRoaXMgdGVzdCBuZWVkcyB0byBiZSBmaXhlZC4gV2Ugc3VwcGx5IG9wdGlvbmFsIHFuYW1lcywgYnV0IHRoaXMgdGVzdCBkb2Vzbid0IGV4cGVjdCB0aGVtIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogInRlc3RzLmFwaS5qYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJUZXN0I3Rlc3RfcGFyc2VMamF2YV9pb19JbnB1dFN0cmVhbUxvcmdfeG1sX3NheF9oZWxwZXJzX0RlZmF1bHRIYW5kbGVyTGphdmFfbGFuZ19TdHJpbmciCit9LAoreworICBkZXNjcmlwdGlvbjogInRoZXNlIGVuZm9yY2UgYSBidWcgd2hlcmUgYW4gZXhjZXB0aW9uIGlzIGluY29ycmVjdGx5IHVudGhyb3duLCBidXQgc2hvdWxkIG1heWJlIGJlIGZpeGVkIGZvcgorICAgICAgICAgICAgICAgIGNvbXBhdGliaWxpdHkuIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogIm9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmphdmEudXRpbC5UcmVlTWFwVGVzdCN0ZXN0X2hlYWRNYXBMamF2YV9sYW5nX09iamVjdFpMIiwKKyAgc3Vic3RyaW5nOiAiamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjogbnVsbCBub3QgaW4gcmFuZ2UgLi4uNSkiCit9LAoreworICBkZXNjcmlwdGlvbjogInRoZXNlIGVuZm9yY2UgYSBidWcgd2hlcmUgYW4gZXhjZXB0aW9uIGlzIGluY29ycmVjdGx5IHVudGhyb3duLCBidXQgc2hvdWxkIG1heWJlIGJlIGZpeGVkIGZvcgorICAgICAgICAgICAgICAgIGNvbXBhdGliaWxpdHkuIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS51dGlsLlRyZWVNYXBUZXN0I3Rlc3RfdGFpbE1hcExqYXZhX2xhbmdfT2JqZWN0WkwiLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLnV0aWwuVHJlZU1hcFRlc3QjdGVzdF9kZXNjZW5kaW5nTWFwX3N1Yk1hcCIKKyAgXSwKKyAgc3Vic3RyaW5nOiAiamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjogNSBub3QgaW4gcmFuZ2UgKDUuLi4iCit9LAoreworICBkZXNjcmlwdGlvbjogIkJvdW5jeUNhc3RsZSBhbGxvd3MgdW5yZWNvZ25pemVkIGFsZ29yaXRobXMsIGJ1dCBSSSBkb2VzIG5vdCwgbm90IGNsZWFyIGlmIHRoaXMgaXMgYSBidWciLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uS2V5QWdyZWVtZW50VGVzdCN0ZXN0X2dlbmVyYXRlU2VjcmV0TGphdmFfbGFuZ19TdHJpbmciLAorICBzdWJzdHJpbmc6ICJqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0aW9uRmFpbGVkRXJyb3I6IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBleHBlY3RlZCIKK30KK10KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9leHBlY3RhdGlvbnMva25vd25mYWlsdXJlcy50eHQgYi9leHBlY3RhdGlvbnMva25vd25mYWlsdXJlcy50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzkxNWExMAotLS0gL2Rldi9udWxsCisrKyBiL2V4cGVjdGF0aW9ucy9rbm93bmZhaWx1cmVzLnR4dApAQCAtMCwwICsxLDE3MzUgQEAKKy8qCisgKiBUaGlzIGZpbGUgY29udGFpbnMgZXhwZWN0YXRpb25zIGZvciB0ZXN0cyB0aGF0IHdlcmUgYW5ub3RhdGVkIHdpdGggQEtub3duRmFpbHVyZSBhdCB0aGUgdGltZQorICovCitbCit7CisgIGRlc2NyaXB0aW9uOiAiUGFja2FnZS5nZXRQYWNrYWdlcygpLCBDbGFzc0xvYWRlci5nZXRQYWNrYWdlcygpIGJvdGggb21pdCByZXN1bHRzIiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5sYW5nLlBhY2thZ2VUZXN0I3Rlc3RHZXRQYWNrYWdlcyIsCisgIGJ1ZzogNTE3MTEzNgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEZXNlcmlhbGl6YXRpb24gc2hvdWxkbid0IHNldCB0cmFuc2llbnQgZmllbGRzIiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5pby5TZXJpYWxpemF0aW9uVGVzdCN0ZXN0U2VyaWFsaXplRmllbGRNYWRlVHJhbnNpZW50IiwKKyAgYnVnOiA0NDcxMjQ5Cit9LAoreworICBkZXNjcmlwdGlvbjogIkludmVzdGlnYXRlIEludGVycnVwdGVkSU9FeGNlcHRpb24gKyBJbnB1dFN0cmVhbS5yZWFkKCksIE91dHB1dFN0cmVhbS53cml0ZSgpIiwKKyAgbmFtZXM6IFsKKyAgICAibGliY29yZS5qYXZhLmlvLkludGVycnVwdGVkU3RyZWFtVGVzdCN0ZXN0SW50ZXJydXB0U29ja2V0SW5wdXRTdHJlYW0iLAorICAgICJsaWJjb3JlLmphdmEuaW8uSW50ZXJydXB0ZWRTdHJlYW1UZXN0I3Rlc3RJbnRlcnJ1cHRTb2NrZXRPdXRwdXRTdHJlYW0iCisgIF0sCisgIGJ1ZzogNDE4MTczOAorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJTaW1wbGVEYXRlRm9ybWF0IGFzc3VtZXMgRFNUIGFsd2F5cyB1c2VzIDYwIG1pbnV0ZSBvZmZzZXQ7IHRoaXMgZmFpbHMgZm9yIHpvbmVzIGxpa2UgTG9yZCBIb3dlIERheWxpZ2h0IFRpbWUiLAorICBuYW1lOiAibGliY29yZS5qYXZhLnRleHQuU2ltcGxlRGF0ZUZvcm1hdFRlc3QjdGVzdERzdFpvbmVXaXRoTm9uRHN0VGltZXN0YW1wRm9yTm9uSG91ckRzdFpvbmUiLAorICBidWc6IDQ3MjM0MTIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRW5jb2RlZCBieXRlcyBkb24ndCBtYXRjaCBmb3IgRUMgZWxsaXB0aWMgY3VydmUga2V5cyBjcmVhdGVkIHRocm91Z2ggS2V5RmFjdG9yeS5nZW5lcmF0ZVByaXZhdGUoKSIsCisgIG5hbWVzOiBbCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5LktleUZhY3RvcnkyVGVzdCN0ZXN0X2dlbmVyYXRlUHJpdmF0ZUxqYXZhX3NlY3VyaXR5X3NwZWNfS2V5U3BlYyIsCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5LktleUZhY3RvcnkyVGVzdCN0ZXN0X2dldEtleVNwZWNMamF2YV9zZWN1cml0eV9LZXlMamF2YV9sYW5nX0NsYXNzIgorICBdLAorICBidWc6IDM0ODMzNjUKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRXhwYXQgdXNlcyBhbiB1bmJvdW5kZWQgbnVtYmVyIG9mIGdsb2JhbCByZWZlcmVuY2VzIiwKKyAgbmFtZTogImxpYmNvcmUueG1sLkV4cGF0U2F4UGFyc2VyVGVzdCN0ZXN0R2xvYmFsUmVmZXJlbmNlVGFibGVPdmVyZmxvdyIsCisgIGJ1ZzogMjc3MjYyOAorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJUZXN0IGZhaWxzLCBJbnRlcm1lZGlhdGUgY2VydGlmaWNhdGUgbGFja3MgQmFzaWNDb25zdHJhaW50cyIsCisgIG5hbWU6ICJjb20uYW5kcm9pZC5vcmcuYm91bmN5Y2FzdGxlLmpjZS5wcm92aWRlci5QS0lYQ2VydFBhdGhWYWxpZGF0b3JTcGlUZXN0I3Rlc3RUcnVzdEFuZFJlbW90ZUNlcnRpZmljYXRlc1dpdGhEaWZmZXJlbnRFbmNvZGluZ3MiLAorICBidWc6IDM0NzQ2NDgKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiREhQYXJhbWV0ZXJzSGVscGVyLmdlbmVyYXRlU2FmZVByaW1lcyBzb21ldGltZXMgdGFrZXMgbG9uZyB0aW1lLCBvdGhlciB0aW1lcyB0YWtlcyBhIHZlcnkgbG9uZyB0aW1lIiwKKyAgbmFtZTogIm9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvLmludGVyZmFjZXMuREhQcml2YXRlS2V5VGVzdCN0ZXN0X2dldFBhcmFtcyIsCisgIGJ1ZzogMzQ3NDQ0NgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJLZXlBZ3JlZW1lbnRGdW5jdGlvbmFsVGVzdCB0aW1lcyBvdXQgZXZlbiB3aXRoIGFuIGFic3VyZGx5IGxvbmcgdGltZW91dCIsCisgIG5hbWU6ICJvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0by5mdW5jLktleUFncmVlbWVudEZ1bmN0aW9uYWxUZXN0I3Rlc3RfS2V5QWdyZWVtZW50IiwKKyAgYnVnOiAzNDczMzAwCit9LAoreworICBkZXNjcmlwdGlvbjogIkNpcGhlclRlc3QudGVzdF9kb0ZpbmFsKCkgaXMgZmxha3kiLAorICBuYW1lOiAib3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uQ2lwaGVyVGVzdCN0ZXN0X2RvRmluYWwiLAorICBidWc6IDM0Njk4NzIKK30sCit7CisgIG5hbWU6ICJsaWJjb3JlLmphdmEubGFuZy5TdHJpbmdUZXN0I3Rlc3RDYXNlTWFwcGluZ19lbl9VUyIsCisgIGJ1ZzogMzM4NzY1NQorfSwKK3sKKyAgbmFtZTogIm9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvLkNpcGhlclRlc3QjdGVzdEdldE1heEFsbG93ZWRLZXlMZW5ndGgiLAorICBidWc6IDMzODc2ODgKK30sCit7CisgIG5hbWU6ICJsaWJjb3JlLmphdmEuaW8uRmlsZVRlc3QjdGVzdF9lbXB0eUZpbGVuYW1lIiwKKyAgYnVnOiAzMzg3NzU4Cit9LAoreworICBkZXNjcmlwdGlvbjogIlR1cmtpc2ggZG90bGVzcyBpIGJlaGF2ZXMgZGlmZmVyZW50bHkgb24gZGFsdmlrIHZzLiBSSSIsCisgIG5hbWVzOiBbCisgICAgImxpYmNvcmUuamF2YS5sYW5nLlN0cmluZ1Rlc3QjdGVzdENoYW5nZUNhc2VfZW5fVVMiLAorICAgICJsaWJjb3JlLmphdmEubGFuZy5TdHJpbmdUZXN0I3Rlc3RFcXVhbHNJZ25vcmVDYXNlX2VuX1VTIiwKKyAgICAibGliY29yZS5qYXZhLmxhbmcuU3RyaW5nVGVzdCN0ZXN0RXF1YWxzSWdub3JlQ2FzZV90cl9UUiIKKyAgXSwKKyAgYnVnOiAzMzI1Nzk5Cit9LAoreworICBkZXNjcmlwdGlvbjogIkt4bWxQdWxsUGFyc2VyIGRvZXNuJ3QgZW5mb3JjZSB0b3AtbGV2ZWwgZG9jdW1lbnQgZWxlbWVudCIsCisgIG5hbWVzOiBbCisgICAgImxpYmNvcmUueG1sLkt4bWxQdWxsUGFyc2VyRHRkVGVzdCN0ZXN0RG9jdHlwZUluRG9jdW1lbnRFbGVtZW50IiwKKyAgICAibGliY29yZS54bWwuS3htbFB1bGxQYXJzZXJEdGRUZXN0I3Rlc3REb2N0eXBlQWZ0ZXJEb2N1bWVudEVsZW1lbnQiCisgIF0sCisgIGJ1ZzogMzQ1MjI3NAorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJVUkxDb25uZWN0aW9uIGZhaWxzIG9uIFVSTHMgY29udGFpbmluZyB7fSIsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEubmV0LlVSTENvbm5lY3Rpb25UZXN0I3Rlc3RNYWxmb3JtZWRVcmwiLAorICBidWc6IDExNTg3ODAsCisgIHN1YnN0cmluZzogImphdmEubmV0LlVSSVN5bnRheEV4Y2VwdGlvbiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGVzdCByZWdyZXNzaW9uIiwKKyAgbmFtZTogImxpYmNvcmUuamF2YXguY3J5cHRvLnNwZWMuS2V5RmFjdG9yeVRlc3REU0EjdGVzdEtleUZhY3RvcnkiLAorICBzdWJzdHJpbmc6ICJub3QgaW1wbGVtZW50ZWQgeWV0IiwKKyAgYnVnOiAzMjg2NTkyCit9LAoreworICBkZXNjcmlwdGlvbjogIkt4bWxQYXJzZXIgZG9lc24ndCBleHBvc2UgRFREIHRleHQiLAorICBuYW1lOiAibGliY29yZS54bWwuS3htbFB1bGxQYXJzZXJEdGRUZXN0I3Rlc3REb2N0eXBlV2l0aE5leHRUb2tlbiIsCisgIGJ1ZzogMzI0MTQ5MgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJFeHBhdCByZWxheGVkIGlzIGRpZmZlcmVudCBmcm9tIEt4bWwgcmVsYXhlZCIsCisgIG5hbWVzOiBbCisgICAgImxpYmNvcmUueG1sLkV4cGF0UHVsbFBhcnNlclRlc3QjdGVzdEF0dHJpYnV0ZU5vVmFsdWVXaXRoUmVsYXhlZCIsCisgICAgImxpYmNvcmUueG1sLkV4cGF0UHVsbFBhcnNlclRlc3QjdGVzdEF0dHJpYnV0ZVVucXVvdGVkVmFsdWVXaXRoUmVsYXhlZCIsCisgICAgImxpYmNvcmUueG1sLkV4cGF0UHVsbFBhcnNlclRlc3QjdGVzdE1pc3NpbmdFbnRpdGllc1dpdGhSZWxheGVkIiwKKyAgICAibGliY29yZS54bWwuRXhwYXRQdWxsUGFyc2VyVGVzdCN0ZXN0VW50ZXJtaW5hdGVkRW50aXR5V2l0aFJlbGF4ZWQiCisgIF0sCisgIGJ1ZzogMzA5MDU1MAorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJFeHBhdFB1bGxQYXJzZXIgZG9lc24ndCBzdXBwb3J0IG5leHRUb2tlbigpIG9yIGxpbmUgbnVtYmVycyIsCisgIG5hbWVzOiBbCisgICAgImxpYmNvcmUueG1sLkV4cGF0UHVsbFBhcnNlckR0ZFRlc3QjdGVzdERvY3R5cGVXaXRoTmV4dFRva2VuIiwKKyAgICAibGliY29yZS54bWwuRXhwYXRQdWxsUGFyc2VyVGVzdCN0ZXN0Q2RhdGFVc2luZ05leHRUb2tlbiIsCisgICAgImxpYmNvcmUueG1sLkV4cGF0UHVsbFBhcnNlclRlc3QjdGVzdENvbW1lbnRVc2luZ05leHRUb2tlbiIsCisgICAgImxpYmNvcmUueG1sLkV4cGF0UHVsbFBhcnNlclRlc3QjdGVzdEN1c3RvbUVudGl0aWVzQXJlTm90RXZhbHVhdGVkIiwKKyAgICAibGliY29yZS54bWwuRXhwYXRQdWxsUGFyc2VyVGVzdCN0ZXN0Q3VzdG9tRW50aXRpZXNVc2luZ05leHQiLAorICAgICJsaWJjb3JlLnhtbC5FeHBhdFB1bGxQYXJzZXJUZXN0I3Rlc3RDdXN0b21FbnRpdGllc1VzaW5nTmV4dFRva2VuIiwKKyAgICAibGliY29yZS54bWwuRXhwYXRQdWxsUGFyc2VyVGVzdCN0ZXN0RW1wdHlDZGF0YVVzaW5nTmV4dFRva2VuIiwKKyAgICAibGliY29yZS54bWwuRXhwYXRQdWxsUGFyc2VyVGVzdCN0ZXN0RW1wdHlDb21tZW50IiwKKyAgICAibGliY29yZS54bWwuRXhwYXRQdWxsUGFyc2VyVGVzdCN0ZXN0RW1wdHlFbnRpdHlSZWZlcmVuY2VVc2luZ05leHQiLAorICAgICJsaWJjb3JlLnhtbC5FeHBhdFB1bGxQYXJzZXJUZXN0I3Rlc3RFbXB0eUVudGl0eVJlZmVyZW5jZVVzaW5nTmV4dFRva2VuIiwKKyAgICAibGliY29yZS54bWwuRXhwYXRQdWxsUGFyc2VyVGVzdCN0ZXN0RW50aXR5SW5BdHRyaWJ1dGVVc2luZ05leHRUb2tlbiIsCisgICAgImxpYmNvcmUueG1sLkV4cGF0UHVsbFBhcnNlclRlc3QjdGVzdExpbmVzQW5kQ29sdW1ucyIsCisgICAgImxpYmNvcmUueG1sLkV4cGF0UHVsbFBhcnNlclRlc3QjdGVzdE1pc3NpbmdFbnRpdGllc0luQXR0cmlidXRlc1VzaW5nTmV4dFRva2VuIiwKKyAgICAibGliY29yZS54bWwuRXhwYXRQdWxsUGFyc2VyVGVzdCN0ZXN0TWlzc2luZ0VudGl0aWVzSW5BdHRyaWJ1dGVzVXNpbmdOZXh0VG9rZW5XaXRoUmVsYXhlZCIsCisgICAgImxpYmNvcmUueG1sLkV4cGF0UHVsbFBhcnNlclRlc3QjdGVzdE1pc3NpbmdFbnRpdGllc0luQXR0cmlidXRlc1VzaW5nTmV4dFdpdGhSZWxheGVkIiwKKyAgICAibGliY29yZS54bWwuRXhwYXRQdWxsUGFyc2VyVGVzdCN0ZXN0TWlzc2luZ0VudGl0aWVzVXNpbmdOZXh0VG9rZW4iLAorICAgICJsaWJjb3JlLnhtbC5FeHBhdFB1bGxQYXJzZXJUZXN0I3Rlc3RNaXNzaW5nRW50aXRpZXNVc2luZ05leHRUb2tlbldpdGhSZWxheGVkIiwKKyAgICAibGliY29yZS54bWwuRXhwYXRQdWxsUGFyc2VyVGVzdCN0ZXN0UHJvY2Vzc2luZ0luc3RydWN0aW9uVXNpbmdOZXh0VG9rZW4iLAorICAgICJsaWJjb3JlLnhtbC5FeHBhdFB1bGxQYXJzZXJUZXN0I3Rlc3RSZWd1bGFyTnVtZXJpY0VudGl0aWVzIiwKKyAgICAibGliY29yZS54bWwuRXhwYXRQdWxsUGFyc2VyVGVzdCN0ZXN0V2hpdGVzcGFjZVVzaW5nTmV4dFRva2VuIiwKKyAgICAibGliY29yZS54bWwuRXhwYXRQdWxsUGFyc2VyVGVzdCN0ZXN0WG1sRGVjbGFyYXRpb24iLAorICAgICJsaWJjb3JlLnhtbC5FeHBhdFB1bGxQYXJzZXJUZXN0I3Rlc3RYbWxEZWNsYXJhdGlvbkV4dHJhQXR0cmlidXRlcyIKKyAgXSwKKyAgYnVnOiAzMDkwNTUwCit9LAoreworICBkZXNjcmlwdGlvbjogIkV4cGF0UHVsbFBhcnNlciBkb2Vzbid0IGhhbmRsZSBzdXJyb2dhdGVzIHByb3Blcmx5IiwKKyAgbmFtZTogImxpYmNvcmUueG1sLkV4cGF0UHVsbFBhcnNlclRlc3QjdGVzdENoYXJhY3RlclJlZmVyZW5jZU9mTGFzdFV0ZjE2U3Vycm9nYXRlIiwKKyAgYnVnOiAzMDkwNTUwCit9LAoreworICBkZXNjcmlwdGlvbjogIlJhbmRvbUFjY2Vzc0ZpbGUgbWlzc2luZyBmaW5hbGl6ZXIiLAorICBuYW1lOiAibGliY29yZS5qYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGVUZXN0I3Rlc3RSYW5kb21BY2Nlc3NGaWxlSGFzQ2xlYW51cEZpbmFsaXplciIsCisgIGJ1ZzogMzAxNTAyMworfSwKK3sKKyAgZGVzY3JpcHRpb246ICJJQ1Ugc2VlbXMgdG8gdHJlYXQgdW5rbm93biBhbmQgaW52YWxpZCBsb2NhbGVzIGRpZmZlcmVudGx5IiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS50ZXh0LkRhdGVGb3JtYXRTeW1ib2xzVGVzdCN0ZXN0X2dldEluc3RhbmNlX3Vua25vd25fbG9jYWxlIiwKKyAgYnVnOiAyNTQxNzU3Cit9LAoreworICBkZXNjcmlwdGlvbjogIlJvb3QgbG9jYWxlIHVzZXMgSU5GIGZvciBpbmZpbml0eSBidXQgdW5rbm93biBsb2NhbGVzIHVzZSBcdTIyMWUiLAorICBuYW1lOiAibGliY29yZS5qYXZhLnRleHQuRGVjaW1hbEZvcm1hdFN5bWJvbHNUZXN0I3Rlc3RfZ2V0SW5zdGFuY2VfdW5rbm93bl9vcl9pbnZhbGlkX2xvY2FsZSIsCisgIGJ1ZzogMzA1NjYxNworfSwKK3sKKyAgZGVzY3JpcHRpb246ICJNaW5pbWFsIGRheXMgaW4gZmlyc3Qgd2VlayBpcyBicm9rZW4iLAorICBuYW1lczogWworICAgICJsaWJjb3JlLmphdmEudGV4dC5PbGRTaW1wbGVEYXRlRm9ybWF0VGVzdCN0ZXN0Rm9ybWF0dGluZ1dlZWtPZlllYXIiLAorICAgICJsaWJjb3JlLmphdmEudGV4dC5PbGRTaW1wbGVEYXRlRm9ybWF0VGVzdCN0ZXN0RGVmYXVsdE1pbmltYWxEYXlzSW5GaXJzdFdlZWsiCisgIF0sCisgIGJ1ZzogMTYxMzcwOQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJDdXN0b20gU2ltcGxlVGltZVpvbmVzIG5vdCBob25vcmVkIGJ5IFNpbXBsZURhdGVGb3JtYXQiLAorICBuYW1lOiAibGliY29yZS5qYXZhLnRleHQuT2xkU2ltcGxlRGF0ZUZvcm1hdFRlc3QjdGVzdEZvcm1hdHRpbmdUaW1lem9uZXMiLAorICBidWc6IDMwNDkwMTQKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiTmFOIGNoYXJhY3RlciBub3QgZm91bmQgd2hlbiBkZXNlcmlhbGl6aW5nIERlY2ltYWxGb3JtYXRTeW1ib2xzIiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS50ZXh0Lk9sZERlY2ltYWxGb3JtYXRTeW1ib2xzVGVzdCN0ZXN0X1JJSGFybW9ueV9jb21wYXRpYmxlIiwKKyAgYnVnOiAzMDU2NzkyCit9LAoreworICBkZXNjcmlwdGlvbjogIkRlY2ltYWxGb3JtYXQuZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcigpIGlzIGZhaWxpbmcgdGVzdHMiLAorICBuYW1lczogWworICAgICJsaWJjb3JlLmphdmEudGV4dC5PbGREZWNpbWFsRm9ybWF0VGVzdCN0ZXN0X2Zvcm1hdFRvQ2hhcmFjdGVySXRlcmF0b3IiLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkudGV4dC50ZXN0cy5qYXZhLnRleHQuRGVjaW1hbEZvcm1hdFRlc3QjdGVzdF9mb3JtYXRUb0NoYXJhY3Rlckl0ZXJhdG9yTGphdmFfbGFuZ19PYmplY3QiLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkudGV4dC50ZXN0cy5qYXZhLnRleHQuRGVjaW1hbEZvcm1hdFRlc3QjdGVzdF9mb3JtYXRUb0NoYXJhY3Rlckl0ZXJhdG9yTGphdmFfbGFuZ19PYmplY3RfX0FyaXRobWV0aWNFeGNlcHRpb24iCisgIF0sCisgIGJ1ZzogMzA1Njg2NQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEZWNpbWFsRm9ybWF0LnBhcnNlIHJldHVybnMgd3JvbmcgdHlwZSB3aXRoIG11bHRpcGxpZXI6IGV4cGVjdGVkIExvbmcgYnV0IHdhcyBEb3VibGUiLAorICBuYW1lOiAibGliY29yZS5qYXZhLnRleHQuT2xkRGVjaW1hbEZvcm1hdFRlc3QjdGVzdF9wYXJzZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfdGV4dF9QYXJzZVBvc2l0aW9uIiwKKyAgYnVnOiAzMDU3MDgwCit9LAoreworICBkZXNjcmlwdGlvbjogIkRlY2ltYWxGb3JtYXQgRmllbGRQb3NpdGlvbiBub3QgdXBkYXRlZCB3aXRoIGNvcnJlY3QgYmVnaW4gYW5kIGVuZCBpbmRpY2VzIiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS50ZXh0Lk9sZERlY2ltYWxGb3JtYXRUZXN0I3Rlc3RfZm9ybWF0RExqYXZhX2xhbmdfU3RyaW5nQnVmZmVyTGphdmFfdGV4dF9GaWVsZFBvc2l0aW9uIiwKKyAgYnVnOiAzMDU3MDkwCit9LAoreworICBkZXNjcmlwdGlvbjogImZpbmFsaXplKCkgY2FsbGVkIG9uIG9iamVjdHMgd2hvc2UgY29uc3RydWN0b3IgZGlkbid0IGNvbXBsZXRlIG5vcm1hbGx5IiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5sYW5nLlN5c3RlbVRlc3QjdGVzdEJhY2tGcm9tVGhlRGVhZCIsCisgIGJ1ZzogMzM0MjM0MworfSwKK3sKKyAgZGVzY3JpcHRpb246ICJEZWNpbWFsRm9ybWF0IGlzIGxpbWl0ZWQgdG8gMTI3IGRpZ2l0cyIsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEudGV4dC5EZWNpbWFsRm9ybWF0VGVzdCN0ZXN0X3NldE1heGltdW1JbnRlZ2VyRGlnaXRzIiwKKyAgYnVnOiAyNDAwNDI5Cit9LAoreworICBkZXNjcmlwdGlvbjogIkNvbmN1cnJlbnQgY2xvc2UgdGVzdHMgZmFpbCBvbiB0aGUgZGV2aWNlIiwKKyAgbmFtZXM6IFsKKyAgICAibGliY29yZS5qYXZhLm5ldC5Db25jdXJyZW50Q2xvc2VUZXN0I3Rlc3RfY29ubmVjdCIsCisgICAgImxpYmNvcmUuamF2YS5uZXQuQ29uY3VycmVudENsb3NlVGVzdCN0ZXN0X2Nvbm5lY3Rfbm9uQmxvY2tpbmciCisgIF0sCisgIG1vZGVzOiBbICJkZXZpY2UiIF0sCisgIGJ1ZzogMzA0NDc3MgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJIVFRQUyBjb25uZWN0aW9ucyBzaG91bGQgbm90IGJlIHBvb2xlZC4iLAorICBuYW1lOiAibGliY29yZS5qYXZhLm5ldC5VUkxDb25uZWN0aW9uVGVzdCN0ZXN0Q29ubmVjdFZpYUh0dHBzUmV1c2luZ0Nvbm5lY3Rpb25zRGlmZmVyZW50RmFjdG9yaWVzIiwKKyAgYnVnOiAzMDQyMTkyCit9LAoreworICBkZXNjcmlwdGlvbjogIkNvb2tpZSB0ZXN0cyBmYWlsaW5nIG9uIHRoZSBob3N0IiwKKyAgYnVnOiAzMDQxOTIwLAorICBuYW1lczogWworICAgICJsaWJjb3JlLmphdmEubmV0LkNvb2tpZXNUZXN0I3Rlc3ROZXRzY2FwZVJlc3BvbnNlIiwKKyAgICAibGliY29yZS5qYXZhLm5ldC5Db29raWVzVGVzdCN0ZXN0UXVvdGVkQXR0cmlidXRlVmFsdWVzIiwKKyAgICAibGliY29yZS5qYXZhLm5ldC5Db29raWVzVGVzdCN0ZXN0UmZjMjEwOVJlc3BvbnNlIiwKKyAgICAibGliY29yZS5qYXZhLm5ldC5Db29raWVzVGVzdCN0ZXN0UmZjMjk2NVJlc3BvbnNlIiwKKyAgICAibGliY29yZS5qYXZhLm5ldC5Db29raWVzVGVzdCN0ZXN0U2VuZGluZ0Nvb2tpZXNGcm9tU3RvcmUiCisgIF0sCisgIG1vZGVzOiBbICJob3N0IiBdCit9LAoreworICBkZXNjcmlwdGlvbjogIk1hdGggZmFpbHVyZXMgd2hlbiBydW5uaW5nIG9uIHRoZSBob3N0IiwKKyAgbmFtZXM6IFsKKyAgICAibGliY29yZS5qYXZhLmxhbmcuT2xkQW5kcm9pZFN0cmljdE1hdGhUZXN0I3Rlc3RMb2cxcEQiLAorICAgICJsaWJjb3JlLmphdmEubGFuZy5PbGRBbmRyb2lkU3RyaWN0TWF0aFRlc3QjdGVzdFJpbnREIiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS5sYW5nLk1hdGhUZXN0I3Rlc3RfY2JydF9EIiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS5sYW5nLk1hdGhUZXN0I3Rlc3RfcG93REQiLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLmxhbmcuTWF0aFRlc3QjdGVzdF9zaW5oX0QiLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLmxhbmcuU3RyaWN0TWF0aFRlc3QjdGVzdF9sb2cxcF9EIiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS5sYW5nLlN0cmljdE1hdGhUZXN0I3Rlc3RfcmludEQiCisgIF0sCisgIGJ1ZzogMjkzMTk1OSwKKyAgbW9kZXM6IFsgImhvc3QiIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRG91YmxlLnBhcnNlRG91YmxlKCkudG9TdHJpbmcgZG9lcyB3cm9uZyByb3VuZGluZyIsCisgIG5hbWVzOiBbCisgICAgImxpYmNvcmUuamF2YS5sYW5nLk9sZERvdWJsZVRlc3QjdGVzdF9wYXJzZURvdWJsZUxqYXZhX2xhbmdfU3RyaW5nIiwKKyAgICAibGliY29yZS5qYXZhLmxhbmcuRG91YmxlVGVzdCN0ZXN0UGFyc2VMYXJnZXN0U3Vibm9ybWFsRG91YmxlUHJlY2lzaW9uIgorICBdLAorICBidWc6IDE2MDc5MzgKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiV2UgZmFrZSBzdXBwb3J0IGZvciB0aGVzZSBieSBzdWJzdGl0dXRpbmcgc2ltaWxhciAoYnV0IG5vdCBpZGVudGljYWwpIGNoYXJzZXRzIiwKKyAgbmFtZXM6IFsKKyAgICAibGliY29yZS5qYXZhLm5pby5jaGFyc2V0Lk9sZENoYXJzZXRfTXVsdGlCeXRlX0JpZzUjdGVzdF9EZWNvZGUiLAorICAgICJsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQuT2xkQ2hhcnNldF9NdWx0aUJ5dGVfQmlnNSN0ZXN0X0VuY29kZSIsCisgICAgImxpYmNvcmUuamF2YS5uaW8uY2hhcnNldC5PbGRDaGFyc2V0X011bHRpQnl0ZV9FVUNfSlAjdGVzdF9Db2RlY0R5bmFtaWMiLAorICAgICJsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQuT2xkQ2hhcnNldF9NdWx0aUJ5dGVfRVVDX0pQI3Rlc3RfRGVjb2RlIiwKKyAgICAibGliY29yZS5qYXZhLm5pby5jaGFyc2V0Lk9sZENoYXJzZXRfTXVsdGlCeXRlX0VVQ19KUCN0ZXN0X0VuY29kZSIsCisgICAgImxpYmNvcmUuamF2YS5uaW8uY2hhcnNldC5PbGRDaGFyc2V0X011bHRpQnl0ZV9HQjIzMTIjdGVzdF9EZWNvZGUiLAorICAgICJsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQuT2xkQ2hhcnNldF9NdWx0aUJ5dGVfR0IyMzEyI3Rlc3RfRW5jb2RlIiwKKyAgICAibGliY29yZS5qYXZhLm5pby5jaGFyc2V0Lk9sZENoYXJzZXRfTXVsdGlCeXRlX0dCMjMxMiN0ZXN0X25hbWVNYXRjaCIsCisgICAgImxpYmNvcmUuamF2YS5uaW8uY2hhcnNldC5PbGRDaGFyc2V0X011bHRpQnl0ZV9HQksjdGVzdF9EZWNvZGUiLAorICAgICJsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQuT2xkQ2hhcnNldF9NdWx0aUJ5dGVfR0JLI3Rlc3RfRW5jb2RlIiwKKyAgICAibGliY29yZS5qYXZhLm5pby5jaGFyc2V0Lk9sZENoYXJzZXRfTXVsdGlCeXRlX0lTT18yMDIyX0pQI3Rlc3RfRGVjb2RlIiwKKyAgICAibGliY29yZS5qYXZhLm5pby5jaGFyc2V0Lk9sZENoYXJzZXRfTXVsdGlCeXRlX0lTT18yMDIyX0pQI3Rlc3RfRW5jb2RlIiwKKyAgICAibGliY29yZS5qYXZhLm5pby5jaGFyc2V0Lk9sZENoYXJzZXRfTXVsdGlCeXRlX3hfd2luZG93c185NTAjdGVzdF9FbmNvZGUiLAorICAgICJsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQuT2xkQ2hhcnNldF9NdWx0aUJ5dGVfeF93aW5kb3dzXzk1MCN0ZXN0X25hbWVNYXRjaCIKKyAgXSwKKyAgYnVnOiAyOTg1OTAxCit9LAoreworICBkZXNjcmlwdGlvbjogIlVURi0xNiBhbmQgVVRGLTMyIGVuY29kZXJzIGRvbid0IHdyaXRlIGJpZy1lbmRpYW4gb3V0cHV0IG9uIGxpdHRsZS1lbmRpYW4gZGV2aWNlcyIsCisgIG5hbWVzOiBbCisgICAgImxpYmNvcmUuamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0RW5jb2RlclRlc3QjdGVzdF9kZWZhdWx0UmVwbGFjZW1lbnRCeXRlc1V0Zl8xNiIsCisgICAgImxpYmNvcmUuamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0VGVzdCN0ZXN0X1VURl8xNiIsCisgICAgImxpYmNvcmUuamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0VGVzdCN0ZXN0X1VURl8zMiIsCisgICAgImxpYmNvcmUuamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0VGVzdCN0ZXN0X1VURl8xNkJFIiwKKyAgICAibGliY29yZS5qYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRUZXN0I3Rlc3RfVVRGXzE2TEUiLAorICAgICJsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQuQ2hhcnNldFRlc3QjdGVzdF9VVEZfMzJCRSIsCisgICAgImxpYmNvcmUuamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0VGVzdCN0ZXN0X1VURl8zMkxFIiwKKyAgICAibGliY29yZS5qYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRUZXN0I3Rlc3RfeF9VVEZfMTZMRV9CT00iLAorICAgICJsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQuQ2hhcnNldFRlc3QjdGVzdF9YX1VURl8zMkJFX0JPTSIsCisgICAgImxpYmNvcmUuamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0VGVzdCN0ZXN0X1hfVVRGXzMyTEVfQk9NIiwKKyAgICAibGliY29yZS5qYXZhLm5pby5jaGFyc2V0Lk9sZENoYXJzZXRfTXVsdGlCeXRlX1VURl8xNiN0ZXN0X0VuY29kZSIKKyAgXSwKKyAgYnVnOiAyNzAyNDExCit9LAoreworICBkZXNjcmlwdGlvbjogIlByZS1OSU8gYWxpYXNlcyBub3QgaW1wbGVtZW50ZWQiLAorICBuYW1lOiAibGliY29yZS5qYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRUZXN0I3Rlc3RfcHJlTmlvQWxpYXNlcyIsCisgIGJ1ZzogMzAzMjY5NworfSwKK3sKKyAgZGVzY3JpcHRpb246ICJIVFRQUyBwcm94eSBicm9rZW4gb24gaG9zdCIsCisgIG5hbWVzOiBbCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmludGVybmFsLm5ldC53d3cucHJvdG9jb2wuaHR0cHMuSHR0cHNVUkxDb25uZWN0aW9uVGVzdCN0ZXN0Q29uc2VxdWVudFByb3h5Q29ubmVjdGlvbiIsCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmludGVybmFsLm5ldC53d3cucHJvdG9jb2wuaHR0cHMuSHR0cHNVUkxDb25uZWN0aW9uVGVzdCN0ZXN0UHJveHlBdXRoQ29ubmVjdGlvbiIsCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmludGVybmFsLm5ldC53d3cucHJvdG9jb2wuaHR0cHMuSHR0cHNVUkxDb25uZWN0aW9uVGVzdCN0ZXN0UHJveHlBdXRoQ29ubmVjdGlvbl9kb091dHB1dCIsCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmludGVybmFsLm5ldC53d3cucHJvdG9jb2wuaHR0cHMuSHR0cHNVUkxDb25uZWN0aW9uVGVzdCN0ZXN0UHJveHlDb25uZWN0aW9uIiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuaW50ZXJuYWwubmV0Lnd3dy5wcm90b2NvbC5odHRwcy5IdHRwc1VSTENvbm5lY3Rpb25UZXN0I3Rlc3RQcm94eUNvbm5lY3Rpb25fTm90X0ZvdW5kX1Jlc3BvbnNlIgorICBdLAorICBidWc6IDMwMzI4NzUsCisgIG1vZGVzOiBbICJob3N0IiBdCit9LAoreworICBkZXNjcmlwdGlvbjogIkZhaWxzIGluIENUUyBidXQgcGFzc2VzIHVuZGVyIHJ1bi1jb3JlLXRlc3RzIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5pby5PbGRGaWxlVGVzdCN0ZXN0X2RlbGV0ZU9uRXhpdCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRmFpbHMgaW4gQ1RTIGJ1dCBwYXNzZXMgdW5kZXIgcnVuLWNvcmUtdGVzdHMiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAidGVzdHMuYXBpLmphdmEuaW8uU2VyaWFsaXphdGlvblN0cmVzc1Rlc3Q0I3Rlc3Rfd3JpdGVPYmplY3RfUHJveHkiCit9LAoreworICBkZXNjcmlwdGlvbjogIkRlZmluaW5nIGNsYXNzZXMgZnJvbSBieXRlW10gbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5sYW5nLk9sZENsYXNzVGVzdCN0ZXN0X2dldENsYXNzZXNfc3VidGVzdDAiCit9LAoreworICBkZXNjcmlwdGlvbjogIlRoZXJlIGlzIG5vIHByb3RlY3Rpb24gZG9tYWluIHNldCBpbiBBbmRyb2lkLiIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEubGFuZy5PbGRDbGFzc1Rlc3QjdGVzdF9nZXRQcm90ZWN0aW9uRG9tYWluIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJGYWlscyBpbiBDVFMgYnV0IHBhc3NlcyB1bmRlciBydW4tY29yZS10ZXN0cyIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWVzOiBbCisgICAgInRlc3RzLmFwaS5qYXZhLm5ldC5NdWx0aWNhc3RTb2NrZXRUZXN0I3Rlc3Rfam9pbkdyb3VwTGphdmFfbmV0X1NvY2tldEFkZHJlc3NMamF2YV9uZXRfTmV0d29ya0ludGVyZmFjZSIsCisgICAgInRlc3RzLmFwaS5qYXZhLnV0aWwuRm9ybWF0dGVyVGVzdCN0ZXN0X2Zvcm1hdExqYXZhX2xhbmdfU3RyaW5nJExqYXZhX2xhbmdfT2JqZWN0X0RhdGVUaW1lQ29udmVyc2lvbiIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJSdW50aW1lLmdldFJ1bnRpbWUoKS50cmFjZU1ldGhvZENhbGxzKHRydWUpIGRvZXNuJ3QgcmV0dXJuIG9uIHRoZSBob3N0LCBmYWlscyBpbiBDVFMiLAorICBidWc6IDM0NDc5NjQsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEubGFuZy5PbGRSdW50aW1lVGVzdCN0ZXN0X3RyYWNlTWV0aG9kQ2FsbHMiCit9LAoreworICBkZXNjcmlwdGlvbjogIkl0J3Mgbm90IGFsbG93ZWQgdG8gcGFzcyBudWxsIGFzIHBhcmVudCBjbGFzcyBsb2FkZXIgdG8gYSBuZXcgQ2xhc3NMb2FkZXIgYW55bW9yZS4gTWF5YmUgd2UgbmVlZAorICAgICAgICAgICAgICAgIHRvIGNoYW5nZSBVUkxDbGFzc0xvYWRlciB0byBhbGxvdyB0aGlzPyBJdCdzIG5vdCBzcGVjaWZpZWQuIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogInRlc3RzLmFwaS5qYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGVUZXN0I3Rlc3RfZ2V0QnVuZGxlTGphdmFfbGFuZ19TdHJpbmdMamF2YV91dGlsX0xvY2FsZUxqYXZhX2xhbmdfQ2xhc3NMb2FkZXIiCit9LAoreworICBkZXNjcmlwdGlvbjogIkZhaWxzIGluIENUUyBidXQgcGFzc2VzIHVuZGVyIHJ1bi1jb3JlLXRlc3RzIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAidGVzdHMuYXBpLmphdmEubmlvLmNoYXJzZXQuQ2hhcnNldFByb3ZpZGVyVGVzdCN0ZXN0Rm9yTmFtZV9JbnN1ZmZpY2llbnRQcml2aWxlZ2UiLAorICAgICJ0ZXN0cy5hcGkuamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0UHJvdmlkZXJUZXN0I3Rlc3RJc1N1cHBvcnRlZF9BbmRfRm9yTmFtZV9Ob3JtYWxQcm92aWRlciIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJGYWlscyAocHJvYmFibHkpIGJlY2F1c2Ugbm8gcHJvdGVjdGlvbiBkb21haW4gaXMgc2V0LiIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWVzOiBbCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXIyVGVzdCN0ZXN0X2NoZWNrUGVybWlzc2lvbl9JbnZhbGlkUGVybWlzc2lvbiIsCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXIyVGVzdCN0ZXN0X2RvUHJpdmlsZWdlZExqYXZhX3NlY3VyaXR5X1ByaXZpbGVnZWRBY3Rpb24iLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyMlRlc3QjdGVzdF9kb1ByaXZpbGVnZWRMamF2YV9zZWN1cml0eV9Qcml2aWxlZ2VkQWN0aW9uTGphdmFfc2VjdXJpdHlfQWNjZXNzQ29udHJvbENvbnRleHQiLAorICAgICJvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyMlRlc3QjdGVzdF9kb1ByaXZpbGVnZWRMamF2YV9zZWN1cml0eV9Qcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uIiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlcjJUZXN0I3Rlc3RfZG9Qcml2aWxlZ2VkTGphdmFfc2VjdXJpdHlfUHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbkxqYXZhX3NlY3VyaXR5X0FjY2Vzc0NvbnRyb2xDb250ZXh0IgorICBdCit9LAoreworICBkZXNjcmlwdGlvbjogIkFuZHJvaWQgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgUkkgdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogIm9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5LlNpZ25hdHVyZVRlc3QjdGVzdFVwZGF0ZWJ5dGVBcnJheWludGludDIiCit9LAoreworICBkZXNjcmlwdGlvbjogIkFuZHJvaWQgZG9lc24ndCBzdXBwb3J0IHByb3RlY3Rpb24gZG9tYWlucy4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAidGVzdHMuYXBpLmphdmEuc2VjdXJpdHkuUGVybWlzc2lvbkNvbGxlY3Rpb25UZXN0I3Rlc3RfaW1wbGllc0xqYXZhX3NlY3VyaXR5X1Blcm1pc3Npb24iCit9LAoreworICBkZXNjcmlwdGlvbjogIkFuZHJvaWQgZG9lc24ndCBhbGxvdyBudWxsIHBhcmVudC4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAidGVzdHMuamF2YS5zZWN1cml0eS5TZWN1cmVDbGFzc0xvYWRlclRlc3QjdGVzdFNlY3VyZUNsYXNzTG9hZGVyQ2xhc3NMb2FkZXIiCit9LAoreworICBkZXNjcmlwdGlvbjogIkFzc2VydGlvbiBkb2VzIG5vdCBldmFsdWF0ZSB0byB0cnVlLi4uIFdvcmtzIGluIGphdmF4LkNlcnRpZmljYXRlIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogInRlc3RzLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVUZXN0I3Rlc3RHZXRFbmNvZGVkIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJOb3QgYWxsIERyaXZlcnMgYXJlIGxvYWRlZCBpbiB0ZXN0c2V0dXAuIENsYXNzTG9hZGVyIGlzc3VlIGluIERyaXZlck1hbmFnZXIuIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogIm9yZy5hcGFjaGUuaGFybW9ueS5zcWwudGVzdHMuamF2YS5zcWwuRHJpdmVyTWFuYWdlclRlc3QjdGVzdERlcmVnaXN0ZXJEcml2ZXIiCit9LAoreworICBkZXNjcmlwdGlvbjogIm5vdCBzdXBwb3J0ZWQiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lczogWworICAgICJ0ZXN0cy5qYXZhLnNxbC5TZWxlY3RGdW5jdGlvbmFsaXR5VGVzdCN0ZXN0X1NlbGVjdFJpZ2h0T3V0ZXJKb2luIiwKKyAgICAidGVzdHMuamF2YS5zcWwuVXBkYXRlRnVuY3Rpb25hbGl0eVRlc3QyI3Rlc3RVcGRhdGUyIiwKKyAgICAidGVzdHMuamF2YS5zcWwuVXBkYXRlRnVuY3Rpb25hbGl0eVRlc3QyI3Rlc3RVcGRhdGU0IiwKKyAgICAidGVzdHMuamF2YS5zcWwuVXBkYXRlRnVuY3Rpb25hbGl0eVRlc3QyI3Rlc3RVcGRhdGU2IiwKKyAgICAidGVzdHMuamF2YS5zcWwuVXBkYXRlRnVuY3Rpb25hbGl0eVRlc3QyI3Rlc3RVcGRhdGU3IiwKKyAgICAidGVzdHMuamF2YS5zcWwuRGVsZXRlRnVuY3Rpb25hbGl0eVRlc3QjdGVzdERlbGV0ZTYiCisgIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAiTm90IHN1cHBvcnRlZCA6IHBhdHRlcm4gd2l0aCAlIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFUZXN0I3Rlc3RfZ2V0Q29sdW1uc0FyYml0cmFyeSIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiV2lsZGNhcmQgb3BlcmF0b3IgZG9lcyBub3Qgc2VlbSB3byB3b3JrIGNvcnJlY3RseS4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9nZXRDb2x1bW5zU3BlY2lmaWMiCit9LAoreworICBkZXNjcmlwdGlvbjogIk5vdCBzdXBwb3J0ZWQgb3BzIGFwcGxpZWQ6IHRlc3QgZmFpbHMgb24gYXJndW1lbnRzOiAnJywgJycsICclJywgJyUnIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFUZXN0I3Rlc3RfZ2V0Q29sdW1uc1RhYmxlV2l0aE5vQ2F0YWxvZ1NjaGVtYSIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiKFRpY2tldCA5MSkgVGFibGVzIGFwcGx5IGZvcmVpZ24ga2V5IGNvbnN0cmFpbnQuIENhdGFsb2dzIG5vdCBzdXBwb3J0ZWQiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9nZXRDcm9zc1JlZmVyZW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZyIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGlja2V0IDk4IiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9nZXREYXRhYmFzZU1ham9yVmVyc2lvbiIsCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFUZXN0I3Rlc3RfZ2V0RGF0YWJhc2VNaW5vclZlcnNpb24iLAorICAgICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhVGVzdCN0ZXN0X2dldERhdGFiYXNlUHJvZHVjdE5hbWUiLAorICAgICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhVGVzdCN0ZXN0X2dldERhdGFiYXNlUHJvZHVjdFZlcnNpb24iLAorICAgICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhVGVzdCN0ZXN0X2dldERlZmF1bHRUcmFuc2FjdGlvbklzb2xhdGlvbiIsCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFUZXN0I3Rlc3RfZ2V0RHJpdmVyTmFtZSIsCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFUZXN0I3Rlc3RfZ2V0RHJpdmVyVmVyc2lvbiIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJLZXlzIGFyZSBub3Qgc3VwcG9ydGVkOiBUaWNrZXQgOTEiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9nZXRJbXBvcnRlZEtleXNMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmciCit9LAoreworICBkZXNjcmlwdGlvbjogIlRpY2tldCA5OCIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWVzOiBbCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFUZXN0I3Rlc3RfZ2V0SkRCQ01ham9yVmVyc2lvbiIsCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFUZXN0I3Rlc3RfZ2V0SkRCQ01pbm9yVmVyc2lvbiIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJOb3Qgc3VwcG9ydGVkIGZlYXR1cmUsIFRpY2tldCA5OC4gQnJva2VuIGJlY2F1c2UgTlVNRVJJQ19GVU5DVElPTlMgbm90IGNvbXBsZXRlLiBXaGVuIGZpeGVkCisgICAgICAgICAgICAgICAgY2hhbmdlIHRvIEBLbm93bkZhaWx1cmUiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9nZXROdW1lcmljRnVuY3Rpb25zIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJUaWNrZXQgOTEgOiByZWxpZXMgb24gbm90IHN1cHBvcnRlZCBmZWF0dXJlczogZ2V0Q2F0YWxvZywga2V5cyIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhVGVzdCN0ZXN0X2dldFByaW1hcnlLZXlzTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJUaWNrZXQgOTgiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lczogWworICAgICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhVGVzdCN0ZXN0X2dldFJlc3VsdFNldEhvbGRhYmlsaXR5IiwKKyAgICAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9nZXRTUUxLZXl3b3JkcyIsCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFUZXN0I3Rlc3RfZ2V0U1FMU3RhdGVUeXBlIiwKKyAgICAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9nZXRTY2hlbWFzIiwKKyAgICAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9nZXRTZWFyY2hTdHJpbmdFc2NhcGUiCisgIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAibm90IHN1cHBvcnRlZCIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWVzOiBbCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFUZXN0I3Rlc3RfZ2V0U3RyaW5nRnVuY3Rpb25zIiwKKyAgICAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9nZXRTeXN0ZW1GdW5jdGlvbnMiCisgIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAiVGlja2V0IDk4IiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFUZXN0I3Rlc3RfZ2V0VGFibGVUeXBlcyIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiSWYgbm8gc2NoZW1hIGlzIGFzc29jaWF0ZWQ6IHJldHVybnMgZW1wdHkgc3RyaW5nIHdoZXJlIGFjdHVhbGx5IG51bGwgYmUgcmV0dXJuZWQ/LiBUaWNrZXQgOTgiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9nZXRUYWJsZXNMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmckTGphdmFfbGFuZ19TdHJpbmciCit9LAoreworICBkZXNjcmlwdGlvbjogIm5vdCBzdXBwb3J0ZWQiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lczogWworICAgICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhVGVzdCN0ZXN0X2dldFRpbWVEYXRlRnVuY3Rpb25zIiwKKyAgICAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9nZXRUeXBlSW5mbyIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJUaWNrZXQgOTgiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lczogWworICAgICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhVGVzdCN0ZXN0X2dldFVSTCIsCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFUZXN0I3Rlc3RfaW5zZXJ0c0FyZURldGVjdGVkSSIsCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFUZXN0I3Rlc3RfaXNSZWFkT25seSIsCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFUZXN0I3Rlc3Rfb3RoZXJzRGVsZXRlc0FyZVZpc2libGVJIiwKKyAgICAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9vdGhlcnNJbnNlcnRzQXJlVmlzaWJsZUkiLAorICAgICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhVGVzdCN0ZXN0X290aGVyc1VwZGF0ZXNBcmVWaXNpYmxlSSIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJub3Qgc3VwcG9ydGVkLiBTUUxFeGNlcHRpb24gY2hlY2tpbmcgdGVzdCBmYWlscyIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhVGVzdCN0ZXN0X3N1cHBvcnRzQ29sdW1uQWxpYXNpbmciCit9LAoreworICBkZXNjcmlwdGlvbjogImV4Y2VwdGlvbiB0ZXN0IGZhaWxzIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZXM6IFsKKyAgICAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9zdXBwb3J0c0V4cHJlc3Npb25zSW5PcmRlckJ5IiwKKyAgICAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9zdXBwb3J0c0dyb3VwQnkiLAorICAgICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhVGVzdCN0ZXN0X3N1cHBvcnRzR3JvdXBCeVVucmVsYXRlZCIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJUaWNrZXQgOTgiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9zdXBwb3J0c05vbk51bGxhYmxlQ29sdW1ucyIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiZXhjZXB0aW9uIHRlc3QgZmFpbHMiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lczogWworICAgICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhVGVzdCN0ZXN0X3N1cHBvcnRzT3JkZXJCeVVucmVsYXRlZCIsCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFUZXN0I3Rlc3Rfc3VwcG9ydHNTZWxlY3RGb3JVcGRhdGUiLAorICAgICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhVGVzdCN0ZXN0X3N1cHBvcnRzU3VicXVlcmllc0luRXhpc3RzIiwKKyAgICAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YVRlc3QjdGVzdF9zdXBwb3J0c1RhYmxlQ29ycmVsYXRpb25OYW1lcyIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJOb3Qgc3VwcG9ydGVkIG9wcyBhcHBsaWVkIiwKKyAgcmVzdWx0OiBFWEVDX0ZBSUxFRCwKKyAgbmFtZTogInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFOb3RTdXBwb3J0ZWRUZXN0I3Rlc3RfYWxsVGFibGVzQXJlU2VsZWN0YWJsZSIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAibm90IHN1cHBvcnRlZCIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhTm90U3VwcG9ydGVkVGVzdCN0ZXN0X2RvZXNNYXhSb3dTaXplSW5jbHVkZUJsb2JzIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJub3Qgc3VwcG9ydGVkLiBQcml2aWxlZ2VzIGFyZSBub3Qgc3VwcG9ydGVkLiIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhTm90U3VwcG9ydGVkVGVzdCN0ZXN0X2dldENvbHVtblByaXZpbGVnZXNMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZyIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAibm90IHN1cHBvcnRlZCIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWVzOiBbCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFOb3RTdXBwb3J0ZWRUZXN0I3Rlc3RfZ2V0RXhwb3J0ZWRLZXlzTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nIiwKKyAgICAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YU5vdFN1cHBvcnRlZFRlc3QjdGVzdF9nZXRJbmRleEluZm9MamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdaWiIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJFeGNlcHRpb24gdGVzdCBmYWlscyIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWVzOiBbCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFOb3RTdXBwb3J0ZWRUZXN0I3Rlc3RfZ2V0TWF4VGFibGVOYW1lTGVuZ3RoIiwKKyAgICAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YU5vdFN1cHBvcnRlZFRlc3QjdGVzdF9nZXRNYXhUYWJsZXNJblNlbGVjdCIsCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFOb3RTdXBwb3J0ZWRUZXN0I3Rlc3RfZ2V0TWF4VXNlck5hbWVMZW5ndGgiLAorICAgICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhTm90U3VwcG9ydGVkVGVzdCN0ZXN0X2dldFByb2NlZHVyZVRlcm0iLAorICAgICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhTm90U3VwcG9ydGVkVGVzdCN0ZXN0X2dldFNjaGVtYVRlcm0iCisgIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAibm90IHN1cHBvcnRlZC4gUHJpdmlsZWdlcyBhcmUgbm90IHN1cHBvcnRlZC4iLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YU5vdFN1cHBvcnRlZFRlc3QjdGVzdF9nZXRUYWJsZVByaXZpbGVnZXNMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmciCit9LAoreworICBkZXNjcmlwdGlvbjogIk5vdCBzdXBwb3J0ZWQgb3BzIGFwcGxpZWQiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YU5vdFN1cHBvcnRlZFRlc3QjdGVzdF9nZXRWZXJzaW9uQ29sdW1uc0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZyIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRXhjZXB0aW9uIHRlc3QgZmFpbHMiLAorICByZXN1bHQ6IEVYRUNfRkFJTEVELAorICBuYW1lOiAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YU5vdFN1cHBvcnRlZFRlc3QjdGVzdF9pc0NhdGFsb2dBdFN0YXJ0IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJub3Qgc3VwcG9ydGVkIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lczogWworICAgICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhTm90U3VwcG9ydGVkVGVzdCN0ZXN0X2xvY2F0b3JzVXBkYXRlQ29weSIsCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFOb3RTdXBwb3J0ZWRUZXN0I3Rlc3Rfc3VwcG9ydHNBTlNJOTJFbnRyeUxldmVsU1FMIiwKKyAgICAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YU5vdFN1cHBvcnRlZFRlc3QjdGVzdF9zdXBwb3J0c0RhdGFEZWZpbml0aW9uQW5kRGF0YU1hbmlwdWxhdGlvblRyYW5zYWN0aW9ucyIsCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFOb3RTdXBwb3J0ZWRUZXN0I3Rlc3Rfc3VwcG9ydHNNaW5pbXVtU1FMR3JhbW1hciIsCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFOb3RTdXBwb3J0ZWRUZXN0I3Rlc3Rfc3VwcG9ydHNSZXN1bHRTZXRUeXBlSSIsCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFOb3RTdXBwb3J0ZWRUZXN0I3Rlc3Rfc3VwcG9ydHNTdWJxdWVyaWVzSW5Db21wYXJpc29ucyIsCisgICAgInRlc3RzLmphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGFOb3RTdXBwb3J0ZWRUZXN0I3Rlc3Rfc3VwcG9ydHNTdWJxdWVyaWVzSW5JbnMiLAorICAgICJ0ZXN0cy5qYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhTm90U3VwcG9ydGVkVGVzdCN0ZXN0X3N1cHBvcnRzVHJhbnNhY3Rpb25zIiwKKyAgICAidGVzdHMuamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YU5vdFN1cHBvcnRlZFRlc3QjdGVzdF91c2VzTG9jYWxGaWxlcyIsCisgICAgImxpYmNvcmUuamF2YS5zcWwuT2xkQ29ubmVjdGlvblRlc3QjdGVzdENsZWFyV2FybmluZ3MiLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZENvbm5lY3Rpb25UZXN0I3Rlc3RDcmVhdGVTdGF0ZW1lbnRJbnRJbnRJbnROb3RTdXBwb3J0ZWQiCisgIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAiU2Nyb2xsaW5nIG9uIGEgZm9yd2FyZCBvbmx5IFJTIG5vdCBhbGxvd2VkLiBjb25uLmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkQ29ubmVjdGlvblRlc3QjdGVzdENyZWF0ZVN0YXRlbWVudF9pbnRfaW50IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJub3Qgc3VwcG9ydGVkIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lczogWworICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZENvbm5lY3Rpb25UZXN0I3Rlc3RHZXRDYXRhbG9nIiwKKyAgICAibGliY29yZS5qYXZhLnNxbC5PbGRDb25uZWN0aW9uVGVzdCN0ZXN0R2V0SG9sZGFiaWxpdHkiCisgIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAiY29ubi5jbG9zZSgpIGRvZXMgbm90IHdyYXAgdXAiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZENvbm5lY3Rpb25UZXN0I3Rlc3RHZXRNZXRhRGF0YSIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAibm90IHN1cHBvcnRlZCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZXM6IFsKKyAgICAibGliY29yZS5qYXZhLnNxbC5PbGRDb25uZWN0aW9uVGVzdCN0ZXN0R2V0VHJhbnNhY3Rpb25Jc29sYXRpb24iLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZENvbm5lY3Rpb25UZXN0I3Rlc3RHZXRXYXJuaW5ncyIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJjb25uLmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkQ29ubmVjdGlvblRlc3QjdGVzdElzUmVhZE9ubHkiCit9LAoreworICBkZXNjcmlwdGlvbjogIm5vdCBzdXBwb3J0ZWQiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWVzOiBbCisgICAgImxpYmNvcmUuamF2YS5zcWwuT2xkQ29ubmVjdGlvblRlc3QjdGVzdFByZXBhcmVTdGF0ZW1lbnROb3RTdXBwb3J0ZWQiLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZENvbm5lY3Rpb25UZXN0I3Rlc3RQcmVwYXJlU3RhdGVtZW50X1N0cmluZ19pbnQiCisgIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAiY29ubi5jbG9zZSgpIGRvZXMgbm90IHdyYXAgdXAiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZENvbm5lY3Rpb25UZXN0I3Rlc3RTZXRBdXRvQ29tbWl0IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJub3Qgc3VwcG9ydGVkIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lczogWworICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZENvbm5lY3Rpb25UZXN0I3Rlc3RTZXRIb2xkYWJpbGl0eSIsCisgICAgImxpYmNvcmUuamF2YS5zcWwuT2xkQ29ubmVjdGlvblRlc3QjdGVzdFNldFJlYWRPbmx5IgorICBdCit9LAoreworICBkZXNjcmlwdGlvbjogIkZpcnN0IEV4Y2VwdGlvbiB0ZXN0IGZhaWxzOiBwYXJhbWV0ZXJzIG5vdCBjbGVhcmVkLiIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUHJlcGFyZWRTdGF0ZW1lbnRUZXN0I3Rlc3RDbGVhclBhcmFtZXRlcnMiCit9LAoreworICBkZXNjcmlwdGlvbjogInByZXBhcmVkU3RhdGVtZW50LmV4ZWN1dGUoKSBkb2VzIG5vdCByZXR1cm4gZmFsc2Ugb24gdXBkYXRlLiIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUHJlcGFyZWRTdGF0ZW1lbnRUZXN0I3Rlc3RFeGVjdXRlIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJpdCBpcyBub3QgcG9zc2libGUgdG8gaW52b2tlIHRoZSBtZXRob2QgZ2V0TWV0YURhdGEgb24gYSBQcmVwYXJlZFN0YXRlbWVudCBvYmplY3QgYmVmb3JlIGl0IGlzCisgICAgICAgICAgICAgICAgZXhlY3V0ZWQ6IGdvdCBOdWxsUG9pbnRlckV4Y2VwdGlvbi5UZXN0IHBhc3NlcyBvbiBSSS4iLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZFByZXBhcmVkU3RhdGVtZW50VGVzdCN0ZXN0R2V0TWV0YURhdGEiCit9LAoreworICBkZXNjcmlwdGlvbjogInByZXBhcmVkU3RhdGVtZW50LmV4ZWN1dGUoKSBkb2VzIG5vdCByZXR1cm4gZmFsc2Ugb24gdXBkYXRlLiIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUHJlcGFyZWRTdGF0ZW1lbnRUZXN0I3Rlc3RTZXRCaWdEZWNpbWFsIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJleGNlcHRpb24gdGVzdCBmYWlscyIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZXM6IFsKKyAgICAibGliY29yZS5qYXZhLnNxbC5PbGRQcmVwYXJlZFN0YXRlbWVudFRlc3QjdGVzdFNldEJvb2xlYW4iLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZFByZXBhcmVkU3RhdGVtZW50VGVzdCN0ZXN0U2V0Qnl0ZSIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJwcmVwYXJlZFN0YXRlbWVudC5leGVjdXRlKCkgZG9lcyBub3QgcmV0dXJuIGZhbHNlIG9uIHVwZGF0ZS4iLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZFByZXBhcmVkU3RhdGVtZW50VGVzdCN0ZXN0U2V0Qnl0ZXMiCit9LAoreworICBkZXNjcmlwdGlvbjogInByZXBhcmVkU3RhdGVtZW50LmV4ZWN1dGUoKSBkb2VzIG5vdCByZXR1cm4gZmFsc2Ugb24gdXBkYXRlLiBTZXR0aW5nIGEgZGF0YSBmb3IgYSBkZWNsYXJlZAorICAgICAgICAgICAgICAgIElOVEVHRVIgc2hvdWxkIHRocm93IEV4Y2VwdGlvbiIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUHJlcGFyZWRTdGF0ZW1lbnRUZXN0I3Rlc3RTZXREYXRlX2ludF9EYXRlIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJwcmVwYXJlZFN0YXRlbWVudC5leGVjdXRlKCkgZG9lcyBub3QgcmV0dXJuIGZhbHNlIG9uIHVwZGF0ZS4iLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZFByZXBhcmVkU3RhdGVtZW50VGVzdCN0ZXN0U2V0RGF0ZV9pbnRfRGF0ZV9DYWxlbmRhciIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiZXhjZXB0aW9uIHRlc3QgZmFpbHMiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWVzOiBbCisgICAgImxpYmNvcmUuamF2YS5zcWwuT2xkUHJlcGFyZWRTdGF0ZW1lbnRUZXN0I3Rlc3RTZXREb3VibGUiLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZFByZXBhcmVkU3RhdGVtZW50VGVzdCN0ZXN0U2V0RmxvYXQiLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZFByZXBhcmVkU3RhdGVtZW50VGVzdCN0ZXN0U2V0SW50IiwKKyAgICAibGliY29yZS5qYXZhLnNxbC5PbGRQcmVwYXJlZFN0YXRlbWVudFRlc3QjdGVzdFNldExvbmciLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZFByZXBhcmVkU3RhdGVtZW50VGVzdCN0ZXN0U2V0T2JqZWN0X2ludF9PYmplY3QiCisgIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRmFpbHMgZm9yIFR5cGVzLkRBVEUiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWVzOiBbCisgICAgImxpYmNvcmUuamF2YS5zcWwuT2xkUHJlcGFyZWRTdGF0ZW1lbnRUZXN0I3Rlc3RTZXRPYmplY3RfaW50X09iamVjdF9pbnQiLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZFByZXBhcmVkU3RhdGVtZW50VGVzdCN0ZXN0U2V0T2JqZWN0X2ludF9PYmplY3RfaW50X2ludCIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJleGNlcHRpb24gdGVzdCBmYWlscyIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZXM6IFsKKyAgICAibGliY29yZS5qYXZhLnNxbC5PbGRQcmVwYXJlZFN0YXRlbWVudFRlc3QjdGVzdFNldFNob3J0IiwKKyAgICAibGliY29yZS5qYXZhLnNxbC5PbGRQcmVwYXJlZFN0YXRlbWVudFRlc3QjdGVzdFNldFN0cmluZ19jaGFyRmllbGQiLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZFByZXBhcmVkU3RhdGVtZW50VGVzdCN0ZXN0U2V0U3RyaW5nX2xvbmdUZXh0RmllbGQiCisgIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAic3RhdGVtZW50LmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUHJlcGFyZWRTdGF0ZW1lbnRUZXN0I3Rlc3RTZXRTdHJpbmdfdGlueVRleHRGaWVsZCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAicHJlcGFyZWRTdGF0ZW1lbnQuZXhlY3V0ZSgpIGRvZXMgbm90IHJldHVybiBGYWxzZSBvbiB1cGRhdGUuIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAibGliY29yZS5qYXZhLnNxbC5PbGRQcmVwYXJlZFN0YXRlbWVudFRlc3QjdGVzdFNldFRpbWVfaW50X1RpbWVfQ2FsZW5kYXIiCit9LAoreworICBkZXNjcmlwdGlvbjogInN0YXRlbWVudC5jbG9zZSgpIGRvZXMgbm90IHdyYXAgdXAiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZFByZXBhcmVkU3RhdGVtZW50VGVzdCN0ZXN0U2V0VGltZWludF9UaW1lIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJwcmVwYXJlZFN0YXRlbWVudC5leGVjdXRlKCkgZG9lcyBub3QgcmV0dXJuIGZhbHNlIG9uIHVwZGF0ZS4iLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWVzOiBbCisgICAgImxpYmNvcmUuamF2YS5zcWwuT2xkUHJlcGFyZWRTdGF0ZW1lbnRUZXN0I3Rlc3RTZXRUaW1lc3RhbXBJbnRUaW1lc3RhbXBDYWxlbmRhciIsCisgICAgImxpYmNvcmUuamF2YS5zcWwuT2xkUHJlcGFyZWRTdGF0ZW1lbnRUZXN0I3Rlc3RTZXRUaW1lc3RhbXBfaW50X1RpbWVzdGFtcCIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJsYXN0IGFzc2VydGlvbiBmYWlsczogaW52YWxpZCBjb252ZXJzaW9uLiBUZXN0IHBhc3NlcyBvbiBSSSIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZXM6IFsKKyAgICAibGliY29yZS5qYXZhLnNxbC5PbGRSZXN1bHRTZXRHZXR0ZXJUZXN0cyN0ZXN0R2V0Qnl0ZXNTdHJpbmdCaW5hcnkiLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZFJlc3VsdFNldEdldHRlclRlc3RzI3Rlc3RHZXRCeXRlc1N0cmluZ1ZhcmJpbmFyeSIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJXcm9uZyB2YWx1ZSByZXR1cm5lZCBmb3IgTG9uZzogamF2YS5sYW5nLlN0cmluZyAoVkFSQ0hBUikiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZFJlc3VsdFNldEdldHRlclRlc3RzI3Rlc3RHZXRNZXRhRGF0YSIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiV3JvbmcgdmFsdWUgcmV0dXJuZWQgZm9yIExvbmc6IGphdmEubGFuZy5TdHJpbmciLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWVzOiBbCisgICAgImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0R2V0dGVyVGVzdHMjdGVzdEdldE9iamVjdEludCIsCisgICAgImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0R2V0dGVyVGVzdHMjdGVzdEdldE9iamVjdFN0cmluZyIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJJZiB0aGVyZSBpcyBubyBjdXJyZW50IHJvdyAwIG11c3QgYmUgcmV0dXJuZWQuIHJlcy5jbG9zZSgpIGRvZXMgbm90IHdyYXAgdXAiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZFJlc3VsdFNldEdldHRlclRlc3RzI3Rlc3RHZXRSb3ciCit9LAoreworICBkZXNjcmlwdGlvbjogIkFjY29yZGluZyB0byBzcGVjIGluZm8uZ2V0U3RhdGVtZW50IHNob3VsZCByZXR1cm4gbnVsbCBidXQgYW4gZXhjZXB0aW9uIGlzIHRocm93bjogc3RhbGUgcmVzdWx0CisgICAgICAgICAgICAgICAgc2V0LiIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0R2V0dGVyVGVzdHMjdGVzdEdldFN0YXRlbWVudCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiZ2V0VGltZSBzaG91bGQgcmV0dXJuIFRpbWUgdmFsdWUgZm9yIGEgVElNRVNUQU1QIHR5cGUgYnV0IHJldHVybnMgbnVsbCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0R2V0dGVyVGVzdHMjdGVzdEdldFRpbWVJbnQiCit9LAoreworICBkZXNjcmlwdGlvbjogImdldFRpbWUgb24gVElNRVNUQU1QIHZhbHVlIGZhaWxzOiByZXR1cm5zIG51bGwiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZFJlc3VsdFNldEdldHRlclRlc3RzI3Rlc3RHZXRUaW1lSW50Q2FsZW5kYXIiCit9LAoreworICBkZXNjcmlwdGlvbjogImdldFRpbWUgc2hvdWxkIHJldHVybiBhIFRpbWUgdmFsdWUgZm9yIGEgVElNRVNUQU1QIHR5cGUgYnV0IHJldHVybnMgbnVsbCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0R2V0dGVyVGVzdHMjdGVzdEdldFRpbWVTdHJpbmciCit9LAoreworICBkZXNjcmlwdGlvbjogImdldFRpbWUgb24gVElNRVNUQU1QIHZhbHVlIGZhaWxzOiByZXR1cm5zIG51bGwiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZFJlc3VsdFNldEdldHRlclRlc3RzI3Rlc3RHZXRUaW1lU3RyaW5nQ2FsZW5kYXIiCit9LAoreworICBkZXNjcmlwdGlvbjogInJlcy5jbG9zZSgpIGRvZXMgbm90IHdyYXAgdXAiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZFJlc3VsdFNldEdldHRlclRlc3RzI3Rlc3RHZXRUeXBlIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJub3Qgc3VwcG9ydGVkIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAibGliY29yZS5qYXZhLnNxbC5PbGRSZXN1bHRTZXRNZXRhRGF0YVRlc3QjdGVzdEdldENhdGFsb2dOYW1lIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJTUUxFeGNlcHRpb24gY2hlY2tpbmcgdGVzdCBmYWlscyIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0TWV0YURhdGFUZXN0I3Rlc3RHZXRDb2x1bW5Db3VudCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAibm90IHN1cHBvcnRlZCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0TWV0YURhdGFUZXN0I3Rlc3RHZXRDb2x1bW5EaXNwbGF5U2l6ZSIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiQ29sdW1uIGxhYmVsIGhhcyBmb3JtYXQgVEFCTEUuQ09MVU1OIGV4cGVjdGVkOiBDT0xVTU4iLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWVzOiBbCisgICAgImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0TWV0YURhdGFUZXN0I3Rlc3RHZXRDb2x1bW5MYWJlbCIsCisgICAgImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0TWV0YURhdGFUZXN0I3Rlc3RHZXRDb2x1bW5OYW1lIgorICBdCit9LAoreworICBkZXNjcmlwdGlvbjogIm5vdCBzdXBwb3J0ZWQiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZFJlc3VsdFNldE1ldGFEYXRhVGVzdCN0ZXN0R2V0UHJlY2lzaW9uIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJOb3Qgc3VwcG9ydGVkIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAibGliY29yZS5qYXZhLnNxbC5PbGRSZXN1bHRTZXRNZXRhRGF0YVRlc3QjdGVzdEdldFNjYWxlIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJub3Qgc3VwcG9ydGVkIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAibGliY29yZS5qYXZhLnNxbC5PbGRSZXN1bHRTZXRNZXRhRGF0YVRlc3QjdGVzdEdldFNjaGVtYSIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRm9yIGludCA9IDAsIGV4Y2VwdGlvbiBleHBlY3RlZCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0TWV0YURhdGFUZXN0I3Rlc3RHZXRUYWJsZU5hbWUiCit9LAoreworICBkZXNjcmlwdGlvbjogIm5vdCBzdXBwb3J0ZWQiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWVzOiBbCisgICAgImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0TWV0YURhdGFUZXN0I3Rlc3RJc0Nhc2VTZW5zaXRpdmUiLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZFJlc3VsdFNldE1ldGFEYXRhVGVzdCN0ZXN0SXNDdXJyZW5jeSIsCisgICAgImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0TWV0YURhdGFUZXN0I3Rlc3RJc0RlZmluaXRseVdyaXRhYmxlIiwKKyAgICAibGliY29yZS5qYXZhLnNxbC5PbGRSZXN1bHRTZXRNZXRhRGF0YVRlc3QjdGVzdElzTnVsbGFibGUiLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZFJlc3VsdFNldE1ldGFEYXRhVGVzdCN0ZXN0SXNSZWFkT25seSIsCisgICAgImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0TWV0YURhdGFUZXN0I3Rlc3RJc1NlYXJjaGFibGUiLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZFJlc3VsdFNldE1ldGFEYXRhVGVzdCN0ZXN0SXNTaWduZWQiLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZFJlc3VsdFNldE1ldGFEYXRhVGVzdCN0ZXN0SXNXcml0YWJsZSIsCisgICAgImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0TWV0YURhdGFUZXN0I3Rlc3Rpc0F1dG9JbmNyZW1lbnQiCisgIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAicmVzLmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0VGVzdCN0ZXN0QWZ0ZXJMYXN0IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJzdGF0ZW1lbnQuY2xvc2UoKSBkb2VzIG5vdCB3cmFwIHVwIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAibGliY29yZS5qYXZhLnNxbC5PbGRSZXN1bHRTZXRUZXN0I3Rlc3RCZWZvcmVGaXJzdCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiTm90IHN1cHBvcnRlZCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0VGVzdCN0ZXN0Q2xlYXJXYXJuaW5ncyIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiUmVzdWx0c2V0LmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZXM6IFsKKyAgICAibGliY29yZS5qYXZhLnNxbC5PbGRSZXN1bHRTZXRUZXN0I3Rlc3RDbG9zZTEiLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZFJlc3VsdFNldFRlc3QjdGVzdE5leHQiCisgIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAibm8gZXhjZXB0aW9uIGlzIHRocm93biB3aGVuIG1vdmluZyBjdXJzb3IgYmFja3dhcmRzIG9uIGZvcndhcmQgb25seSBzdGF0ZW1lbnQiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZFJlc3VsdFNldFRlc3QjdGVzdFJlbGF0aXZlIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJTY3JvbGxhYmxlIHJlc3VsdFNldC4gTm90IHN1cHBvcnRlZCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0VGVzdCN0ZXN0UmVsYXRpdmVTY3JvbGxhYmxlUmVzdWx0U2V0IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJub3Qgc3VwcG9ydGVkIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAibGliY29yZS5qYXZhLnNxbC5PbGRSZXN1bHRTZXRUZXN0I3Rlc3RVcGRhdGVPYmplY3RTdHJpbmdPYmplY3QiCit9LAoreworICBkZXNjcmlwdGlvbjogIkZlYXR1cmUgbm90IHN1cHBvcnRlZCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0VGVzdCN0ZXN0VXBkYXRlU3RyaW5nU3RyaW5nU3RyaW5nIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJ0aGUgZGVmYXVsdCB0ZXN0cywgYW5kIGV4Y2VwdGlvbiB0ZXN0cyBmYWlsLiIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0VGVzdCN0ZXN0V2FzTnVsbCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAic3RhdGVtZW50LmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZXM6IFsKKyAgICAibGliY29yZS5qYXZhLnNxbC5PbGRSZXN1bHRTZXRUZXN0I3Rlc3R0ZXN0Rmlyc3QiLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZFJlc3VsdFNldFRlc3QjdGVzdHRlc3RJc0FmdGVyTGFzdCIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJJbiBTZWNvbmQgY29kZSBibG9jayBhc3NlcnRpb24gZmFpbHMuIHN0YXRlbWVudC4gY2xvc2UoKSBkb2VzIG5vdCB3cmFwIHVwIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAibGliY29yZS5qYXZhLnNxbC5PbGRSZXN1bHRTZXRUZXN0I3Rlc3R0ZXN0SXNCZWZvcmVGaXJzdCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAic3RhdGVtZW50LmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0VGVzdCN0ZXN0dGVzdElzRmlyc3QiCit9LAoreworICBkZXNjcmlwdGlvbjogIlNlY29uZCBibG9jayBmaXJzdCBhc3NlcnRpb24gZmFpbHMuIElzIExhc3Qgc2hvdWxkIGV2YWx1YXRlIHRydWUgaWYgdGhlIHJvdyBvbiB3aGljaCB0aGUgY3Vyc29yCisgICAgICAgICAgICAgICAgaXMgYWN0dWFsbHkgcHJvdmlkZXMgYSByZXN1bHQuc3RhdGVtZW50LmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0VGVzdCN0ZXN0dGVzdElzTGFzdCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAic3RhdGVtZW50LmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkUmVzdWx0U2V0VGVzdCN0ZXN0dGVzdExhc3QiCit9LAoreworICBkZXNjcmlwdGlvbjogIkJ1ZyBpbiBpbXBsZW1lbnRhdGlvbiBvZiBjYW5jZWw6IERvZXMgbm90IGZ1bGZpbGwgc3BlYy4iLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZFN0YXRlbWVudFRlc3QjdGVzdENhbmNlbCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAic3RhdGVtZW50LmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkU3RhdGVtZW50VGVzdCN0ZXN0Q2xvc2UiCit9LAoreworICBkZXNjcmlwdGlvbjogIlJldHVybiB2YWx1ZSB3cm9uZyBmb3IgcXVlcmllcyBiZWxvdy4iLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZFN0YXRlbWVudFRlc3QjdGVzdEV4ZWN1dGUiCit9LAoreworICBkZXNjcmlwdGlvbjogImFsd2F5cyByZXR1cm5zIDEgZm9yIG5vLiBvZiB1cGRhdGVzIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAibGliY29yZS5qYXZhLnNxbC5PbGRTdGF0ZW1lbnRUZXN0I3Rlc3RFeGVjdXRlQmF0Y2giCit9LAoreworICBkZXNjcmlwdGlvbjogIkRvZXMgdGhyb3cgYW4gZXhjZXB0aW9uIG9uIG5vbiBzZWxlY3Qgc3RhdGVtZW50LiIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkU3RhdGVtZW50VGVzdCN0ZXN0RXhlY3V0ZVF1ZXJ5X1N0cmluZyIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiU3BlYyBpcyBub3QgcHJlY2lzZSBlbm91Z2g6IHNob3VsZCBiZTogbnVtYmVyIG9mIHJvd3MgYWZmZWN0ZWQuIGVnLiB0byBiZSBjb25zaXN0ZW50IGZvciBkZWxldGVzOgorICAgICAgICAgICAgICAgICdkZWxldGUgZnJvbSBzMTsnIHNob3VsZCBiZSBkaWZmZXJlbnQgZnJvbSAnZGVsZXRlIGZyb20gczEgd2hlcmUgYzEgPSAxOyciLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZFN0YXRlbWVudFRlc3QjdGVzdEV4ZWN1dGVVcGRhdGVfU3RyaW5nIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJzdGF0ZW1lbnQuY2xvc2UoKSBkb2VzIG5vdCB3cmFwIHVwIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lczogWworICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZFN0YXRlbWVudFRlc3QjdGVzdEdldENvbm5lY3Rpb24iLAorICAgICJsaWJjb3JlLmphdmEuc3FsLk9sZFN0YXRlbWVudFRlc3QjdGVzdEdldEZldGNoRGlyZWN0aW9uIiwKKyAgICAibGliY29yZS5qYXZhLnNxbC5PbGRTdGF0ZW1lbnRUZXN0I3Rlc3RHZXRGZXRjaFNpemUiCisgIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAibm90IHN1cHBvcnRlZCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkU3RhdGVtZW50VGVzdCN0ZXN0R2V0TW9yZVJlc3VsdHMiCit9LAoreworICBkZXNjcmlwdGlvbjogIkFuIG90aGVyIHZhbHVlIGlzIHJldHVybmVkIHRoYW4gd2FzIHNldCAoWCAqIDEwMDApIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAibGliY29yZS5qYXZhLnNxbC5PbGRTdGF0ZW1lbnRUZXN0I3Rlc3RHZXRRdWVyeVRpbWVvdXQiCit9LAoreworICBkZXNjcmlwdGlvbjogIkRvZXMgbm90IHJldHVybiBudWxsIG9uIHVwZGF0ZSBjb3VudCA+IDAgKG5vdCBhIHNlbGVjdCBzdGF0ZW1lbnQpIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAibGliY29yZS5qYXZhLnNxbC5PbGRTdGF0ZW1lbnRUZXN0I3Rlc3RHZXRSZXN1bHRTZXQiCit9LAoreworICBkZXNjcmlwdGlvbjogIk5vdCBzdXBwb3J0ZWQiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLmphdmEuc3FsLk9sZFN0YXRlbWVudFRlc3QjdGVzdEdldFJlc3VsdFNldENvbmN1cnJlbmN5IgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJUZXN0IGZvciBkZWZhdWx0IHZhbHVlIGZhaWxzIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAibGliY29yZS5qYXZhLnNxbC5PbGRTdGF0ZW1lbnRUZXN0I3Rlc3RHZXRSZXN1bHRTZXRIb2xkYWJpbGl0eSIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAibm90IGZ1bGx5IHN1cHBvcnRlZCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkU3RhdGVtZW50VGVzdCN0ZXN0R2V0UmVzdWx0U2V0VHlwZSIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAic3RhdGVtZW50LmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuamF2YS5zcWwuT2xkU3RhdGVtZW50VGVzdCN0ZXN0R2V0VXBkYXRlQ291bnQiCit9LAoreworICBkZXNjcmlwdGlvbjogIkhhbmRzaGFrZSBTdGF0dXMgaXMgbmV2ZXIgZmluaXNoZWQuIE5QRSBpbiBDbGllbnRTZXNzaW9uQ29udGV4dCRIb3N0QW5kUG9ydC5oYXNoQ29kZSgpIHdoZW4gaG9zdAorICAgICAgICAgICAgICAgIGlzIG51bGwiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJ0ZXN0cy5hcGkuamF2YXgubmV0LnNzbC5TU0xFbmdpbmVUZXN0I3Rlc3RIYW5kc2hha2UiCit9LAoreworICBkZXNjcmlwdGlvbjogIm9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2UuU1NMRW5naW5lSW1wbCNnZXREZWxlZ2F0ZWRUYXNrKCkgdGhyb3dzIE5QRSBpbnN0ZWFkIG9mCisgICAgICAgICAgICAgICAgcmV0dXJuaW5nIG51bGwiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJ0ZXN0cy5hcGkuamF2YXgubmV0LnNzbC5TU0xFbmdpbmVUZXN0I3Rlc3RfZ2V0RGVsZWdhdGVkVGFzayIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRml4ZWQgaW4gRG9udXRCdXJnZXIsIGJvdW5kYXJ5IGNoZWNrcyBtaXNzaW5nIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAidGVzdHMuYXBpLmphdmF4Lm5ldC5zc2wuU1NMRW5naW5lVGVzdCN0ZXN0X3Vud3JhcF8wMiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRml4ZWQgb24gRG9udXRCdXJnZXIsIFdyb25nIEV4Y2VwdGlvbiB0aHJvd24iLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWVzOiBbCisgICAgInRlc3RzLmFwaS5qYXZheC5uZXQuc3NsLlNTTEVuZ2luZVRlc3QjdGVzdF91bndyYXBfMDMiLAorICAgICJ0ZXN0cy5hcGkuamF2YXgubmV0LnNzbC5TU0xFbmdpbmVUZXN0I3Rlc3RfdW53cmFwXzA0IiwKKyAgICAidGVzdHMuYXBpLmphdmF4Lm5ldC5zc2wuU1NMRW5naW5lVGVzdCN0ZXN0X3Vud3JhcF9CeXRlQnVmZmVyJEJ5dGVCdWZmZXJfMDIiLAorICAgICJ0ZXN0cy5hcGkuamF2YXgubmV0LnNzbC5TU0xFbmdpbmVUZXN0I3Rlc3RfdW53cmFwX0J5dGVCdWZmZXIkQnl0ZUJ1ZmZlcl8wMyIsCisgICAgInRlc3RzLmFwaS5qYXZheC5uZXQuc3NsLlNTTEVuZ2luZVRlc3QjdGVzdF91bndyYXBfQnl0ZUJ1ZmZlcl9CeXRlQnVmZmVyXzAyIiwKKyAgICAidGVzdHMuYXBpLmphdmF4Lm5ldC5zc2wuU1NMRW5naW5lVGVzdCN0ZXN0X3Vud3JhcF9CeXRlQnVmZmVyX0J5dGVCdWZmZXJfMDMiCisgIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRml4ZWQgaW4gRG9udXRCdXJnZXIsIGJvdW5kYXJ5IGNoZWNrcyBtaXNzaW5nIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAidGVzdHMuYXBpLmphdmF4Lm5ldC5zc2wuU1NMRW5naW5lVGVzdCN0ZXN0X3dyYXBfMDIiCit9LAoreworICBkZXNjcmlwdGlvbjogIkZpeGVkIG9uIERvbnV0QnVyZ2VyLCBXcm9uZyBFeGNlcHRpb24gdGhyb3duIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lczogWworICAgICJ0ZXN0cy5hcGkuamF2YXgubmV0LnNzbC5TU0xFbmdpbmVUZXN0I3Rlc3Rfd3JhcF8wNCIsCisgICAgInRlc3RzLmFwaS5qYXZheC5uZXQuc3NsLlNTTEVuZ2luZVRlc3QjdGVzdF93cmFwX0J5dGVCdWZmZXIkQnl0ZUJ1ZmZlcl8wMyIsCisgICAgInRlc3RzLmFwaS5qYXZheC5uZXQuc3NsLlNTTEVuZ2luZVRlc3QjdGVzdF93cmFwX0J5dGVCdWZmZXJfQnl0ZUJ1ZmZlcl8wMyIKKyAgXQorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMgb2JqZWN0IGlzIG5vdCBzdXBwb3J0ZWQgYW5kIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gd2FzCisgICAgICAgICAgICAgICAgdGhyb3duLiIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogInRlc3RzLmFwaS5qYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlckZhY3RvcnkxVGVzdCN0ZXN0X2luaXRMamF2YXhfbmV0X3NzbF9NYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMiCit9LAoreworICBkZXNjcmlwdGlvbjogIkhvc3RuYW1lVmVyaWZpZXIgZG9lc24ndCB2ZXJpZnkgSVAgYWRkcmVzc2VzIiwKKyAgYnVnOiAzMjk5MTg4LAorICBuYW1lOiAidGVzdHMuYXBpLmphdmF4Lm5ldC5zc2wuSG9zdG5hbWVWZXJpZmllclRlc3QjdGVzdFZlcmlmeUlwQWRkcmVzcyIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiTk8gU0VSVkVSIENFUlRJRklDQVRFIEZPVU5EIC0gc2VsZWN0U3VpdGUgc2hvdWxkIG5vdCBwaWNrIGEgc3VpdGUgdGhhdCBuZWVkcyBhIGNlcnRpZmljYXRlIGlmIGl0IGlzIG1pc3NpbmciLAorICBidWc6IDMwNDUxNjMsCisgIG5hbWU6ICJsaWJjb3JlLmphdmF4Lm5ldC5zc2wuU1NMRW5naW5lVGVzdCN0ZXN0X1NTTEVuZ2luZV9iZWdpbkhhbmRzaGFrZV9ub0tleVN0b3JlIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJBbGVydEV4Y2VwdGlvbiBpbnN0ZWFkIG9mIFNTTEV4Y2VwdGlvbiIsCisgIGJ1ZzogMzA0NTE2MywKKyAgbmFtZTogImxpYmNvcmUuamF2YXgubmV0LnNzbC5TU0xFbmdpbmVUZXN0I3Rlc3RfU1NMRW5naW5lX3NldEVuYWJsZVNlc3Npb25DcmVhdGlvbl9jbGllbnQiCit9LAoreworICBkZXNjcmlwdGlvbjogIlNTTEV4Y2VwdGlvbiBpbnN0ZWFkIG9mIGZhaWx1cmUgdG8gaGFuZHNoYWtlIiwKKyAgYnVnOiAzMDQ1MTYzLAorICBuYW1lOiAibGliY29yZS5qYXZheC5uZXQuc3NsLlNTTEVuZ2luZVRlc3QjdGVzdF9TU0xFbmdpbmVfc2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uX3NlcnZlciIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiU1NMSGFuZHNoYWtlRXhjZXB0aW9uIGluc3RlYWQgb2YgZmFpbHVyZSB0byBoYW5kc2hha2UiLAorICBidWc6IDMwNDUxNjMsCisgIG5hbWU6ICJsaWJjb3JlLmphdmF4Lm5ldC5zc2wuU1NMRW5naW5lVGVzdCN0ZXN0X1NTTEVuZ2luZV9zZXRVc2VDbGllbnRNb2RlIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJtZXRob2QgdGVzdCBmYWlscyBvbmNlIGluIGEgd2hpbGUuIENhbm5vdCBiZSBzdXJlIHRoYXQgZXhjZXB0aW9uIGlzIHRocm93biBpbiBldmVyeSB0ZXN0IGV4ZWN1dGlvbi4iLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLnNxbGl0ZS5PbGREYXRhYmFzZVRlc3QjdGVzdEJ1c3lfaGFuZGxlciIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiRGF0YWJhc2UgZG9lcyBub3QgbG9jayB2YWx1ZXMiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLnNxbGl0ZS5PbGREYXRhYmFzZVRlc3QjdGVzdEJ1c3lfdGltZW91dCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiUmV0dXJucyB3cm9uZyBudW1iZXIgZm9yIHVwZGF0ZXM6IHJldHVybnMgdmFsdWUgPiAxIGZvciBzZWxlY3QuIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAibGliY29yZS5zcWxpdGUuT2xkRGF0YWJhc2VUZXN0I3Rlc3RDaGFuZ2VzIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJBZ2dyZWdhdGlvbiBmdW5jdGlvbiBub3QgY2FsbGVkIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAibGliY29yZS5zcWxpdGUuT2xkRGF0YWJhc2VUZXN0I3Rlc3RDcmVhdGVfYWdncmVnYXRlIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJSZWFzb24gZm9yIGZhaWx1cmUgdW5rbm93bjogRGF0YWJhc2Ugc2hvdWxkIGJlIGxvY2tlZC4gU3BlY2lmaWNhdGlvbiBvZiBpbnRlcnJ1cHQgaXMgc2NhcmNlLiIsCisgIHJlc3VsdDogRVhFQ19GQUlMRUQsCisgIG5hbWU6ICJsaWJjb3JlLnNxbGl0ZS5PbGREYXRhYmFzZVRlc3QjdGVzdEludGVycnVwdCIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAibm90IHN1cHBvcnRlZCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuc3FsaXRlLk9sZERhdGFiYXNlVGVzdCN0ZXN0T3Blbl9ibG9iIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJDYWxsYmFjayBuZXZlciBtYWRlIGZvciBhdXRob3JpemF0aW9uLiBSZXN1bHRzIG9mIHByaXZhdGUgdGFibGUgYXJlIHJldHVybmVkIHdpdGhvdXQgZnVydGhlciBjaGVja3MuIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lOiAibGliY29yZS5zcWxpdGUuT2xkRGF0YWJhc2VUZXN0I3Rlc3RTZXRfYXV0aG9yaXplciIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiQVNDSUkgZW5jb2RpbmcgZG9lcyBub3Qgd29yazogYSBVVEYgZW5jb2RlZCB2YWwgaXMgcmV0dXJuZWQuIFNwZWMgaXMgbm90IHN1ZmZpY2llbnQuIE1pZ2h0IGJlIHRoYXQgdGVzdCBpbXBsIGlzIHdyb25nIG9yIFN0cmluZyBjb25zdHJ1Y3RvciBmb3IgdGhlIEFTQ0lJIGVuY29kaW5nLiIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuc3FsaXRlLk9sZERhdGFiYXNlVGVzdCN0ZXN0U2V0X2VuY29kaW5nIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJkYi5vcGVuX2Jsb2IgaXMgbm90IHN1cHBvcnRlZC4iLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLnNxbGl0ZS5PbGRCbG9iVGVzdCN0ZXN0QmxvYiIKK30sCit7CisgIGRlc2NyaXB0aW9uOiAiV3JvbmcgdmFsdWUgaXMgcmV0dXJuZWQgaW4gY2FzZSBvZiBhIHByZXBhcmVkIHN0YXRlbWVudCB0byB3aGljaCBhICcqJyBib3VuZCIsCisgIGJ1ZzogMzQwMzcwNiwKKyAgbmFtZTogImxpYmNvcmUuc3FsaXRlLk9sZFN0bXRUZXN0I3Rlc3RDb2x1bW5fY291bnQiCit9LAoreworICBkZXNjcmlwdGlvbjogIlplcm9CbG9iIG5vdCBzdXBwb3J0ZWQiLAorICBidWc6IDM0MDM3MDYsCisgIG5hbWU6ICJsaWJjb3JlLnNxbGl0ZS5PbGRGdW5jdGlvbkNvbnRleHRUZXN0I3Rlc3RTZXRfcmVzdWx0X3plcm9ibG9iIgorfSwKK3sKKyAgZGVzY3JpcHRpb246ICJTUUxpdGUgdGVzdCBmYWlsIiwKKyAgYnVnOiAzNDAzNzA2LAorICBuYW1lczogWworICAgICJsaWJjb3JlLnNxbGl0ZS5PbGREYXRhYmFzZVRlc3QjdGVzdEdldF90YWJsZVN0cmluZyIsCisgICAgImxpYmNvcmUuc3FsaXRlLk9sZERhdGFiYXNlVGVzdCN0ZXN0R2V0X3RhYmxlU3RyaW5nU3RyaW5nQXJyYXlUYWJsZVJlc3VsdCIsCisgICAgImxpYmNvcmUuc3FsaXRlLk9sZFN0bXRUZXN0I3Rlc3RDb2x1bW5fdHlwZSIKKyAgXQorfSwKK3sKKyAgbW9kZXM6IFsgImp2bSIgXSwKKyAgZGVzY3JpcHRpb246ICJUaGUgUkkncyBmb3JtYXR0ZXIgZG9lc24ndCBsb2NhbGl6ZSBhcmFiaWMgcHJvcGVybHkiLAorICBuYW1lczogWworICAgICJsaWJjb3JlLmphdmEudXRpbC5Gb3JtYXR0ZXJUZXN0I3Rlc3RfbnVtYmVyTG9jYWxpemF0aW9uIiwKKyAgICAibGliY29yZS5qYXZhLnV0aWwuRm9ybWF0dGVyVGVzdCN0ZXN0X3VwcGVyY2FzZUNvbnZlcnNpb25zIgorICBdLAorICByZXN1bHQ6IEVYRUNfRkFJTEVECit9LAoreworICBkZXNjcmlwdGlvbjogIkFuZHJvaWQncyBYU0xUIGltcGxlbWVudGF0aW9uIGZhaWxzIDUyNCBvZiAzMTczIE9BU0lTIHRlc3RzIiwKKyAgYnVnOiA0MTkzNTk5LAorICBuYW1lczogWworICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRNaXNzcGVjaWZpZWRUZXN0I3Rlc3QiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5CVlRzX2J2dDAwNSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkJWVHNfYnZ0MDE3IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuQlZUc19idnQwMTgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5CVlRzX2J2dDAxOSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkJWVHNfYnZ0MDIwIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuQlZUc19idnQwMjIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5CVlRzX2J2dDAyNCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkJWVHNfYnZ0MDI5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuQlZUc19idnQwMzMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5CVlRzX2J2dDAzNCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkJWVHNfYnZ0MDM4IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuQlZUc19idnQwMzkiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5CVlRzX2J2dDA0NCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkJWVHNfYnZ0MDQ1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuQlZUc19idnQwNDciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5CVlRzX2J2dDA1MiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkJWVHNfYnZ0MDU0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuQlZUc19idnQwNTUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5CVlRzX2J2dDA1NiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkJWVHNfYnZ0MDU4IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuQlZUc19idnQwNjEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5CVlRzX2J2dDA2MiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkJWVHNfYnZ0MDYzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuQlZUc19idnQwNjQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5CVlRzX2J2dDA2NyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkJWVHNfYnZ0MDY5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuQlZUc19idnQwNzAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5CVlRzX2J2dDA3NCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkJWVHNfYnZ0MDc1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuQlZUc19idnQwNzciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5CVlRzX2J2dDA3OSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkJWVHNfYnZ0MDgzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuQlZUc19idnQwODUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5CVlRzX2J2dDA4NiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkJWVHNfYnZ0MDg5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuQlZUc19idnQwOTAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5CVlRzX2J2dDA5MSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkJWVHNfYnZ0MDk0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuQlZUc19idnQwOTUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5CVlRzX2J2dDA5OCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkNvbXBsZXRlbmVzc19fODQzNjEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5FcnJvcnNfZXJyMDAzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuRXJyb3JzX2VycjAwNCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkVycm9yc19lcnIwMDUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5FcnJvcnNfZXJyMDA2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuRXJyb3JzX2VycjAxMCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkVycm9yc19lcnIwMTEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5FcnJvcnNfZXJyMDEyIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuRXJyb3JzX2VycjAxMyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkVycm9yc19lcnIwMjYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5FcnJvcnNfZXJyMDI5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuRXJyb3JzX2VycjAzMSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkVycm9yc19lcnIwMzgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5FcnJvcnNfZXJyMDQ0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuRXJyb3JzX2VycjA0OCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkVycm9yc19lcnIwNDkiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5FcnJvcnNfZXJyMDUwIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuRXJyb3JzX2VycjA1MSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkVycm9yc19lcnIwNTkiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5FcnJvcnNfZXJyMDYyIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuRXJyb3JzX2VycjA2NSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkVycm9yc19lcnIwNzMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5FcnJvcnNfZXJyMDc1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuRXJyb3JzX2VycjA3NiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkVycm9yc19lcnIwNzgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5FcnJvcnNfZXJyMDkzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuRXJyb3JzX2VycjEwMyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLkVycm9yc19lcnIxMDYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5FcnJvcnNfZXJyMTA4IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuRXJyb3JzX3hzbF90ZW1wbGF0ZV9jb21wbGljYXRlZF9tYXRjaF9wYXR0ZXJuX3dpdGhfdmFyaWFibGVfcmVmIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuTWlzY2VsbGFuZW91c19fODQ0MjMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5NaXNjZWxsYW5lb3VzX184NDQyNCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLk1pc2NlbGxhbmVvdXNfXzg0NDI2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuTWlzY2VsbGFuZW91c19fODQ0MjciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5NaXNjZWxsYW5lb3VzX184NDQzNSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLk1pc2NlbGxhbmVvdXNfXzkxMTgzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuWFNMVEZ1bmN0aW9uc19Cb29sZWFuRnVuY3Rpb24iLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX0J1Zzc2MDU0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuWFNMVEZ1bmN0aW9uc19Eb2N1bWVudEZ1bmN0aW9uV2l0aEFic29sdXRlQXJndW1lbnQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX0RvY3VtZW50RnVuY3Rpb25XaXRoRW50aXR5UmVmIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuWFNMVEZ1bmN0aW9uc19FbGVtZW50QXZhaWxGdW5jdGlvbkZhbHNlVGVzdCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLlhTTFRGdW5jdGlvbnNfR2VuZXJlYXRlSWRBcHBsaWVkVG9OYW1lc3BhY2VOb2Rlc09uRGlmZmVyZW50RWxlbWVudHMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX1Rlc3RJZEZ1bmNJbkNvbXBsZXhTdHJ1Y3QiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX1Rlc3RPZklkRnVuY3Rpb24iLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX18xMDAwMiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLlhTTFRGdW5jdGlvbnNfXzEwMDAzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuWFNMVEZ1bmN0aW9uc19fMTAwMDQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX18xMDAwNSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLlhTTFRGdW5jdGlvbnNfXzEwMDA2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuWFNMVEZ1bmN0aW9uc19fMTAwMDciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX18xMDAwOCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLlhTTFRGdW5jdGlvbnNfXzEwMDA5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuWFNMVEZ1bmN0aW9uc19fMTAwMTAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX18xMDAxMSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLlhTTFRGdW5jdGlvbnNfXzEwMDEyIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuWFNMVEZ1bmN0aW9uc19fMTAwMTMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX18xMDAxNCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLlhTTFRGdW5jdGlvbnNfXzEwMDE1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuWFNMVEZ1bmN0aW9uc19fMTAwMTYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX18xMDAxNyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLlhTTFRGdW5jdGlvbnNfXzEwMDE4IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuWFNMVEZ1bmN0aW9uc19fMTAwMTkiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX18xMDAyMCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLlhTTFRGdW5jdGlvbnNfXzEwMDIxIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuWFNMVEZ1bmN0aW9uc19fMTAwMjIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX18xMDAyMyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLlhTTFRGdW5jdGlvbnNfXzEwMDI0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuWFNMVEZ1bmN0aW9uc19fMTAwMjUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX18xMDAyNiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLlhTTFRGdW5jdGlvbnNfXzEwMDQ5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuWFNMVEZ1bmN0aW9uc19fODQwNDgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX184NDA0OSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLlhTTFRGdW5jdGlvbnNfXzg0MDUwIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuWFNMVEZ1bmN0aW9uc19fODQxNzAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX184NDE3MiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLlhTTFRGdW5jdGlvbnNfX0V1cm9wZWFuUGF0dGVybiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLlhTTFRGdW5jdGlvbnNfX05vbl9EaWdpdFBhdHRlcm4iLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX19QYXR0ZXJuLXNlcGFyYXRvciIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLlhTTFRGdW5jdGlvbnNfX2N1cnJlbmN5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuWFNMVEZ1bmN0aW9uc19fZGVmYXVsdFBhdHRlcm4iLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX19taW5pbWFsVmFsdWUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX19taW5pbXVtVmFsdWUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNNaXhlZC5YU0xURnVuY3Rpb25zX19wZXJjZW50UGF0dGVybiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I01peGVkLlhTTFRGdW5jdGlvbnNfX3NwZWNpYWxDaGFySW5QYXR0ZXJuIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjTWl4ZWQuWFNMVEZ1bmN0aW9uc19fdGVzdE9uLTAuMDAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYUGF0aC1EYXRhLU1vZGVsLlZhcmlhYmxlc19Vc2VEb2N1bWVudEZuVG9SZXR1cm5Sb290Tm9kZSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hQYXRoLURhdGEtTW9kZWwuVmFyaWFibGVzX1ZhcmlhYmxlV2l0aGluVmFyaWFibGUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYUGF0aC1EYXRhLU1vZGVsLlZhcmlhYmxlc19fNzgxMTciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYUGF0aC1EYXRhLU1vZGVsLlZhcmlhYmxlc19fNzgxMjAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYUGF0aC1EYXRhLU1vZGVsLlZhcmlhYmxlc19fNzgxMjUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYUGF0aC1EYXRhLU1vZGVsLlZhcmlhYmxlc19fNzgxNjEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYUGF0aC1EYXRhLU1vZGVsLlZhcmlhYmxlc19fNzgzNTYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYUGF0aC1EYXRhLU1vZGVsLlZhcmlhYmxlc19fNzgzNjAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYUGF0aC1EYXRhLU1vZGVsLlZhcmlhYmxlc19fODQ2MzMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYUGF0aC1EYXRhLU1vZGVsLlZhcmlhYmxlc19fODQ2MzQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYUGF0aC1EYXRhLU1vZGVsLlZhcmlhYmxlc19fODQ2MzYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYUGF0aC1EYXRhLU1vZGVsLlZhcmlhYmxlc19fODQ2MzciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYUGF0aC1EYXRhLU1vZGVsLlZhcmlhYmxlc19fODQ2OTciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYUGF0aC1EYXRhLU1vZGVsLlZhcmlhYmxlc19fODQ3MDkiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYUGF0aC1EYXRhLU1vZGVsLlZhcmlhYmxlc19fODQ3MTAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYUGF0aC1EYXRhLU1vZGVsLlZhcmlhYmxlc19fODQ3MTIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULURhdGEtTWFuaXB1bGF0aW9uLktleXNfUGVyZlJlcHJvMiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtRGF0YS1NYW5pcHVsYXRpb24uS2V5c19QZXJmUmVwcm8zIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1EYXRhLU1hbmlwdWxhdGlvbi5LZXlzX185MTgzMiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtRGF0YS1NYW5pcHVsYXRpb24uS2V5c19fOTE4MzMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULURhdGEtTWFuaXB1bGF0aW9uLktleXNfXzkxODM2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1EYXRhLU1hbmlwdWxhdGlvbi5LZXlzX185MTg1OSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtRGF0YS1NYW5pcHVsYXRpb24uU29ydGluZ19Tb3J0RXhwcldpdGhDdXJyZW50SW5zaWRlRm9yRWFjaDEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULURhdGEtTWFuaXB1bGF0aW9uLlNvcnRpbmdfU29ydF9Tb3J0VGV4dFdpdGhOb25UZXh0Q2hhcmFjdGVycyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtRGF0YS1NYW5pcHVsYXRpb24uU29ydGluZ19Tb3J0X1RleHROb2Rlc1NwYW5NdWx0aXBsZUxpbmVzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1EYXRhLU1hbmlwdWxhdGlvbi5Tb3J0aW5nX1R1cmtpc2hJU29ydGluZ1Rlc3QiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULURhdGEtTWFuaXB1bGF0aW9uLlNvcnRpbmdfXzc3NTE2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1EYXRhLU1hbmlwdWxhdGlvbi5Tb3J0aW5nX183NzUyNSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtRGF0YS1NYW5pcHVsYXRpb24uU29ydGluZ19fNzc5NzciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULURhdGEtTWFuaXB1bGF0aW9uLlNvcnRpbmdfXzc4MTkxIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1EYXRhLU1hbmlwdWxhdGlvbi5Tb3J0aW5nX183ODI4NiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtRGF0YS1NYW5pcHVsYXRpb24uU29ydGluZ19fNzgyOTEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULURhdGEtTWFuaXB1bGF0aW9uLlNvcnRpbmdfXzg0MDA2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1EYXRhLU1hbmlwdWxhdGlvbi5Tb3J0aW5nX185MTY4OSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtRGF0YS1NYW5pcHVsYXRpb24uU29ydGluZ19fOTE2OTEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULURhdGEtTWFuaXB1bGF0aW9uLlNvcnRpbmdfXzkxNjkzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1EYXRhLU1hbmlwdWxhdGlvbi5Tb3J0aW5nX185MTY5NCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtRGF0YS1NYW5pcHVsYXRpb24uU29ydGluZ19fOTE2OTUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULURhdGEtTWFuaXB1bGF0aW9uLlNvcnRpbmdfXzkxNjk2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1EYXRhLU1hbmlwdWxhdGlvbi5Tb3J0aW5nX185MTY5NyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtRGF0YS1NYW5pcHVsYXRpb24uU29ydGluZ19fOTE2OTgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULURhdGEtTWFuaXB1bGF0aW9uLlNvcnRpbmdfXzkxNjk5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1EYXRhLU1hbmlwdWxhdGlvbi5Tb3J0aW5nX185MTcwMCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtRGF0YS1NYW5pcHVsYXRpb24uU29ydGluZ19fOTE3MDEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULURhdGEtTWFuaXB1bGF0aW9uLlNvcnRpbmdfXzkxNzA0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1EYXRhLU1hbmlwdWxhdGlvbi5Tb3J0aW5nX185MTcwNSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtRGF0YS1NYW5pcHVsYXRpb24uU29ydGluZ19fOTE3NTIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULURhdGEtTWFuaXB1bGF0aW9uLlNvcnRpbmdfXzkxNzUzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1EYXRhLU1vZGVsLldoaXRlc3BhY2VzX185MTQyMiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtRGF0YS1Nb2RlbC5XaGl0ZXNwYWNlc19fOTE0MjMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULURhdGEtTW9kZWwuV2hpdGVzcGFjZXNfXzkxNDI1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1EYXRhLU1vZGVsLldoaXRlc3BhY2VzX185MTQyOCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtRGF0YS1Nb2RlbC5XaGl0ZXNwYWNlc19fOTE0NDMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULURhdGEtTW9kZWwuV2hpdGVzcGFjZXNfXzkxNDQ0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1FeHRlbmRhYmlsaXR5LkZhbGxiYWNrX185MTgyNSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtRXh0ZW5kYWJpbGl0eS5Gb3J3YXJkQ29tcF9fOTE4NDEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULUV4dGVuZGFiaWxpdHkuRm9yd2FyZENvbXBfXzkxODQ0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1FeHRlbmRhYmlsaXR5LkZvcndhcmRDb21wX185MTg0OCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtRXh0ZW5kYWJpbGl0eS5Gb3J3YXJkQ29tcF9fOTE4NDkiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULUV4dGVuZGFiaWxpdHkuRm9yd2FyZENvbXBfXzkxODUzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1FeHRlbmRhYmlsaXR5LkZvcndhcmRDb21wX185MTg1NiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9BbXBlcnNhbmRXaXRoaW5IdG1sQXR0cmlidXRlIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X0RvY3R5cGVQdWJsaWNBbmRTeXN0ZW1BdHRyaWJ1dGUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfRG9jdHlwZVB1YmxpY0F0dHJpYnV0ZSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9Eb2N0eXBlU3lzdGVtQXR0cmlidXRlIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X0VtcHR5RWxlbWVudDEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfRW50aXR5UmVmSW5BdHRyaWJIdG1sIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X0h0bWxPdXRwdXRXaXRoQW1wZXJzYW5kQ3VybHlCcmFja2V0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X0h0bWxPdXRwdXRXaXRoTGVzc1RoYW5JbkF0dHJpYnV0ZSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9IdG1sX09wX0hyZWZfQXR0cl9ub25fYXNjaWlfdmFsdWUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfTWVkaWFUeXBlVGVzdCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9NZXRob2RFcXVhbHNIdG1sV2l0aG91dEluZGVudFNldCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9Nb2RpZmllZDg0NDMzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X091dHB1dF9Vc2VTdGFuZEFsb25lQXR0cmlidXRlV2l0aE11bHRpcGxlUm9vdHMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfU2lnbkluSHJlZkF0dHJpYnV0ZSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9Vc2VMaXRlcmFsUmVzdWx0RWxlbWVudEhlYWQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzc3OTI5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X183NzkzMCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fNzc5MzYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzc3OTM5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X183Nzk0MCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fNzc5NjYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzc4MTc1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X183ODE3NiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fNzgxNzciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzc4MTgwIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X183ODIyMSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fNzgyMjIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzc4MjIzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X183ODIyNCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fNzgyMjUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzc4MjI2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X183ODIyNyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fNzgyMjkiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzg0MDEwIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X184NDAxMSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fODQwMTIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzg0MDE1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X184NDAxNiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fODQwMTciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzg0MDE4IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X184NDAxOSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fODQwMjAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzg0MDIxIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X184NDAyMiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fODQwMjUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzg0MTY1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X184NDI2MCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fODQyNjQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzg0MjcxIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X184NDI3MyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fODQyNzciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzg0MjgwIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X184NDI4MiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fODQyODUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzg0MzA2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X184NDMwOSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fODQzNzQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzg0NDI4IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X184NDQyOSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fODQ0MzIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzg0NDMzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X184NDQzNCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fODQ0NTIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzg0NDUzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X184NDQ1NCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fODQ0NTUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzg0NDU2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X184NDQ1NyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fODQ0NTgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzg0NDU5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1PdXRwdXQuT3V0cHV0X184NDQ2MCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtT3V0cHV0Lk91dHB1dF9fODQ0NjEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULU91dHB1dC5PdXRwdXRfXzg0NDYyIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5BVlRzX183NzUzNiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuQVZUc19fNzc1NjIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkFWVHNfXzc3NTY0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5BVlRzX183NzU3NCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuQVZUc19fNzc1OTEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkFWVHNfXzc3NTk2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5BVlRzX183NzU5OSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuQXR0cmlidXRlU2V0c19SZWZUb1VuZGVmaW5lZEF0dHJpYnV0ZVNldCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuQXR0cmlidXRlU2V0c19fOTEwMzUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkF0dHJpYnV0ZVNldHNfXzkxMDM4IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5BdHRyaWJ1dGVTZXRzX185MTA4MCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuQXR0cmlidXRlU2V0c19fOTEwODEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkF0dHJpYnV0ZVNldHNfXzkxMDgzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5BdHRyaWJ1dGVTZXRzX185MTA5OCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuQXR0cmlidXRlU2V0c19fOTExMDAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkF0dHJpYnV0ZVNldHNfXzkxMTE5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5BdHRyaWJ1dGVzX0F0dHJpYnV0ZV9BdHRyaWJ1dGVXaXRoRW1wdHlOYW1lIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5BdHRyaWJ1dGVzX0F0dHJpYnV0ZV9FbXB0eU5hbWVBdHRyaWJ1dGVXaXRoTlMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkF0dHJpYnV0ZXNfQXR0cmlidXRlX0ludmFsaWROYW1lc3BhY2VQcmVmaXgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkF0dHJpYnV0ZXNfQXR0cmlidXRlX1VzZVhtbG5zTnNBc05hbWVzcGFjZUZvckF0dHJpYnV0ZSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuQXR0cmlidXRlc19fNzgzNjUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkF0dHJpYnV0ZXNfXzc4MzY5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5BdHRyaWJ1dGVzX183ODM3MyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuQXR0cmlidXRlc19fNzgzNzQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkF0dHJpYnV0ZXNfXzc4Mzc2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5BdHRyaWJ1dGVzX183ODM3OCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuQXR0cmlidXRlc19fNzgzODYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkF0dHJpYnV0ZXNfXzgxNDg3IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5BdHRyaWJ1dGVzX184MTU1MSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuQXR0cmlidXRlc19fODk0NjMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkF0dHJpYnV0ZXNfXzg5NDY0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5BdHRyaWJ1dGVzX184OTQ2NSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuQ29weWluZ19SZXN1bHRUcmVlRnJhZ21lbnRXaXRoRXNjYXBlZFRleHQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkVsZW1lbnRzX0VsZW1lbnRfRWxlbWVudFdpdGhOU0Zyb21OYW1lRm4iLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkVsZW1lbnRzX0VsZW1lbnRfRWxlbWVudFdpdGhOb05hbWVTcGVjaWZpZWQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkVsZW1lbnRzX0VsZW1lbnRfRWxlbWVudFdpdGhOb05hbWVTcGVjaWZpZWRCdXRWYWxpZE5TIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5FbGVtZW50c19FbGVtZW50X1VzZVhzbEVsZW1lbnRXSXRoTmFtZXNwYWNlRXF1YWxUb1htbG5zVXJpIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5FbGVtZW50c19FbGVtZW50X1VzZVhzbEVsZW1lbnRXaXRoTmFtZVNwYWNlQXR0ckVxdWFsVG9YbWxuc1VyaSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuRWxlbWVudHNfXzc4MzQ3IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5FbGVtZW50c19fNzgzNTgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkVsZW1lbnRzX183ODM2MiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuRWxlbWVudHNfXzc4MzYzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5FbGVtZW50c19fODM5NjgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkVsZW1lbnRzX184OTE3MSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuRWxlbWVudHNfXzg5NzE2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5FbGVtZW50c19fODk3MTciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkVsZW1lbnRzX184OTcxOCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuRm9ybWF0TnVtYmVyX0RlY2ltYWxGb3JtYXRTYW1lQ2hhckZvckRlY2ltYWxBbmRHcnBTZXAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkZvcm1hdE51bWJlcl9EZWNpbWFsRm9ybWF0WmVyb0RpZ2l0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5Gb3JtYXROdW1iZXJfRGVjaW1hbEZvcm1hdFplcm9EaWdpdDEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLkZvcm1hdE51bWJlcl9EZWNpbWFsRm9ybWF0WmVyb0RpZ2l0MiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuRm9ybWF0TnVtYmVyX0Zvcm1hdE51bWJlcl9TZW1pQ29sb25EZWxpbWl0c1RvV2hpdGVzcGFjZSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuRm9ybWF0TnVtYmVyX1Rlc3RHcnBTZXByIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5Gb3JtYXROdW1iZXJfVmFsdWVPZl9Gb3JtYXROdW1iZXJXaXRob3V0UG9zaXRpdmVOdW1iZXJGb3JtYXRQYXR0ZXJuIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OYW1lc3BhY2VfWFBhdGhfQ29uZmxpY3RfWFBhdGhfWFNMVCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuTmFtZXNwYWNlX1hQYXRoX0RlZmF1bHROYW1lc3BhY2UiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLk5hbWVzcGFjZV9YUGF0aF9OYXZpZ2F0b3JNZXRob2RzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OYW1lc3BhY2VfWFBhdGhfUHJlZGVmaW5lZFByZWZpeF9YTUwiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLk5hbWVzcGFjZV9YUGF0aF9QcmVkZWZpbmVkUHJlZml4X1hNTE5TIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OYW1lc3BhY2VfWFBhdGhfU2FtZVF1ZXJ5X0RpZmZOYW1lc3BhY2UiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLk5hbWVzcGFjZV9YUGF0aF9TY29waW5nUnVsZXMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLk51bWJlcl9OYU5PckludmFsaWRWYWx1ZSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuTnVtYmVyX1ZhbHVlQXNFbXB0eU5vZGVzZXQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLk51bWJlcl9WYWx1ZUFzTm9kZXNldFRlc3QxIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzg0NjgzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzg0Njg3IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzg0NjkyIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzg0Njk0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzg0Njk5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzg0NzAwIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzg0NzA1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzg0NzE1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzg0NzE2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzg0NzE3IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzg0NzIyIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzg0NzIzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzg0NzI0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzg0NzI1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzkxMDI2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzkxMDI3IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzkxMDI4IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5OdW1iZXJfXzkxMDI5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb25fSW52YWxpZFBJTmFtZTEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLlByb2Nlc3NpbmdJbnN0cnVjdGlvbl9fNzgxOTYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLlByb2Nlc3NpbmdJbnN0cnVjdGlvbl9fNzgyMDIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLlByb2Nlc3NpbmdJbnN0cnVjdGlvbl9fNzgyMDQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLlByb2Nlc3NpbmdJbnN0cnVjdGlvbl9fNzgyMTciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLlByb2Nlc3NpbmdJbnN0cnVjdGlvbl9fNzgyMTgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLlByb2Nlc3NpbmdJbnN0cnVjdGlvbl9fNzgyMTkiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLlRleHRfRG9lV2l0aENkYXRhSW5UZXh0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5UZXh0X01vZGlmaWVkNzgzMTEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLlRleHRfXzc4MjQ1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5UZXh0X183ODI3MiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuVGV4dF9fNzgyNzMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLlRleHRfXzc4Mjc0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5UZXh0X183ODI3NSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuVGV4dF9fNzgyNzYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLlRleHRfXzc4MjgxIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5UZXh0X183ODMwOCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuVGV4dF9fNzgzMDkiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLlRleHRfXzc4MzExIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5UZXh0X21vZGlmaWVkNzgzMDgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLlRleHRfbW9kaWZpZWQ3ODMwOSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuYXR0cmlic2V0X2F0dHJpYnNldDEwIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5hdHRyaWJzZXRfYXR0cmlic2V0MTciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmF0dHJpYnNldF9hdHRyaWJzZXQyNyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuYXR0cmlic2V0X2F0dHJpYnNldDI5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5hdHRyaWJzZXRfYXR0cmlic2V0MzEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmF0dHJpYnNldF9hdHRyaWJzZXQzMiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuYXR0cmlic2V0X2F0dHJpYnNldDQwIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5hdHRyaWJzZXRfYXR0cmlic2V0NDEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmF0dHJpYnNldF9hdHRyaWJzZXQ0MiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuYXR0cmlidmFsdGVtcGxhdGVfYXR0cmlidmFsdGVtcGxhdGUwOCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuY29weV9jb3B5MTYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmNvcHlfY29weTE5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5jb3B5X2NvcHkyMCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuY29weV9jb3B5MjEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmNvcHlfY29weTIyIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5jb3B5X2NvcHkzOCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuY29weV9jb3B5NTYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmNvcHlfY29weTU4IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5jb3B5X2NvcHk2MCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuZXh0ZW5kX2V4dGVuZDAyIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5leHRlbmRfZXh0ZW5kMDQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5MDQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5MjIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5MjQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5MjYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5MzEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5MzciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5MzgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5MzkiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5NDAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5NDEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5NDIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5NDMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5NTUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5NTYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5NTciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5NTgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5NjAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5NjEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLmlka2V5X2lka2V5NjIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm1hdGNoX21hdGNoMTEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm1lc3NhZ2VfbWVzc2FnZTE1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5uYW1lc3BhY2VfbmFtZXNwYWNlMzIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm5hbWVzcGFjZV9uYW1lc3BhY2UzNCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUubnVtYmVyZm9ybWF0X251bWJlcmZvcm1hdDA3IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5udW1iZXJmb3JtYXRfbnVtYmVyZm9ybWF0MzUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm51bWJlcmluZ19udW1iZXJpbmcxNCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUubnVtYmVyaW5nX251bWJlcmluZzE3IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5udW1iZXJpbmdfbnVtYmVyaW5nNzkiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm51bWJlcmluZ19udW1iZXJpbmc5MSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDAxIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5vdXRwdXRfb3V0cHV0MDIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm91dHB1dF9vdXRwdXQwMyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDA0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5vdXRwdXRfb3V0cHV0MDUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm91dHB1dF9vdXRwdXQwNiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDA4IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5vdXRwdXRfb3V0cHV0MDkiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm91dHB1dF9vdXRwdXQxMCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDExMCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDExMSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDExMyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDE3IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5vdXRwdXRfb3V0cHV0MjIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm91dHB1dF9vdXRwdXQyNSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDI2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5vdXRwdXRfb3V0cHV0MjgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm91dHB1dF9vdXRwdXQzMiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDMzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5vdXRwdXRfb3V0cHV0MzQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm91dHB1dF9vdXRwdXQzNSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDM2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5vdXRwdXRfb3V0cHV0MzciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm91dHB1dF9vdXRwdXQzOCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDM5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5vdXRwdXRfb3V0cHV0NDAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm91dHB1dF9vdXRwdXQ0OCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDQ5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5vdXRwdXRfb3V0cHV0NTAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm91dHB1dF9vdXRwdXQ1MiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDU5IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5vdXRwdXRfb3V0cHV0NjAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm91dHB1dF9vdXRwdXQ2MSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDYyIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5vdXRwdXRfb3V0cHV0NzAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm91dHB1dF9vdXRwdXQ3MiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDczIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5vdXRwdXRfb3V0cHV0NzQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLm91dHB1dF9vdXRwdXQ3NSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUub3V0cHV0X291dHB1dDg2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5wcm9jZXNzb3JpbmZvX3Byb2Nlc3NvcmluZm8wMyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUuc2VsZWN0X3NlbGVjdDczIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5zZWxlY3Rfc2VsZWN0NzQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVJlc3VsdC1UcmVlLnNvcnRfc29ydDA4IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS5zb3J0X3NvcnQyNyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtUmVzdWx0LVRyZWUudmVyX3ZlcjA1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1SZXN1bHQtVHJlZS52ZXJfdmVyMDYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5JbXBvcnRfXzg0NjE0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuSW1wb3J0X184NDYxNSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLkltcG9ydF9fOTEwMzIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5JbXBvcnRfXzkxMTQ4IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuSW1wb3J0X185MTE1MCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLkltcG9ydF9fOTExNTEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5JbXBvcnRfXzkxMTU2IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuSW1wb3J0X185MTE1NyIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLkltcG9ydF9fOTExNTgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5JbXBvcnRfXzkxMTY1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuSW5jbHVkZV9JbmNsdWRlX0luY2x1ZGVTdHlsZXNoZWV0V2l0aG91dFhzbE5hbWVzcGFjZSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLkluY2x1ZGVfSW5jbHVkZV9JbmNsdWRlZFN0eWxlc2hlZXRTaG91bGRIYXZlRGlmZmVyZW50QmFzZVVyaSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLkluY2x1ZGVfTmVzdGVkSW5jbHVkZXMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5JbmNsdWRlX1JlbFVyaVRlc3QxIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuSW5jbHVkZV9SZWxVcmlUZXN0MiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLkluY2x1ZGVfUmVsVXJpVGVzdDMiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5JbmNsdWRlX1JlbFVyaVRlc3Q0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuSW5jbHVkZV9SZWxVcmlUZXN0NSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLkluY2x1ZGVfUmVsVXJpVGVzdDYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5JbmNsdWRlX183NzQ4OSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLkluY2x1ZGVfXzc3NTA0IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuSW5jbHVkZV9fNzc1MTUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5JbmNsdWRlX183NzczNiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLkluY2x1ZGVfXzc3NzQ1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuSW5jbHVkZV9fNzc3NTAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5JbmNsdWRlX183Nzc1MSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLkluY2x1ZGVfXzc4Mjk1IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuSW5jbHVkZV9fNzgyOTYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5JbmNsdWRlX183ODM5OCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLkluY2x1ZGVfXzg0NDYzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuSW5jbHVkZV9fODQ0NjQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5OYW1lc3BhY2UtYWxpYXNfTlNBbGlhc19Jbl9JbXBvcnQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5OYW1lc3BhY2UtYWxpYXNfTmFtZXNwYWNlLUFsaWFzX05TQWxpYXNGb3JEZWZhdWx0V2l0aEV4Y2x1ZGVSZXNQcmVmIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuTmFtZXNwYWNlLWFsaWFzX05hbWVzcGFjZS1BbGlhc19UZXN0MSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLk5hbWVzcGFjZS1hbGlhc19OYW1lc3BhY2UtQWxpYXNfVGVzdDIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5OYW1lc3BhY2UtYWxpYXNfTmFtZXNwYWNlLUFsaWFzX1dpdGhpblJURiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLk5hbWVzcGFjZS1hbGlhc19fOTE3ODEiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5OYW1lc3BhY2UtYWxpYXNfXzkxNzgyIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuTmFtZXNwYWNlLWFsaWFzX185MTc4NSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLk5hbWVzcGFjZS1hbGlhc19fOTE3ODYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5OYW1lc3BhY2VfQ2hlY2tYbWxuc1Jlc2V0T25SZXN1bHRUcmVlIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuTmFtZXNwYWNlX183NzY1NSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLk5hbWVzcGFjZV9fNzc2NjUiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5OYW1lc3BhY2VfXzc3NjcwIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuTmFtZXNwYWNlX183NzY3NSIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLk5hbWVzcGFjZV9fNzgwMjciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5TdHlsZXNoZWV0X185MTgwMiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLlN0eWxlc2hlZXRfXzkxODAzIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuU3R5bGVzaGVldF9fOTE4MDQiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5TdHlsZXNoZWV0X185MTgwNiIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLlN0eWxlc2hlZXRfXzkxODA3IiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuU3R5bGVzaGVldF9fOTE4MDgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVN0cnVjdHVyZS5TdHlsZXNoZWV0X185MTgxMCIsCisgICAgImxpYmNvcmUueG1sLlhzbHRYUGF0aENvbmZvcm1hbmNlVGVzdFN1aXRlJFhzbHRUZXN0I1hTTFQtU3RydWN0dXJlLlN0eWxlc2hlZXRfXzkxODExIiwKKyAgICAibGliY29yZS54bWwuWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUkWHNsdFRlc3QjWFNMVC1TdHJ1Y3R1cmUuU3R5bGVzaGVldF9fOTE4MTYiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVRlbXBsYXRlLkNvbmZsaWN0UmVzb2x1dGlvbl9fNzc2MTkiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVRlbXBsYXRlLkNvbmZsaWN0UmVzb2x1dGlvbl9fNzc2MjIiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVRlbXBsYXRlLkNvbmZsaWN0UmVzb2x1dGlvbl9fNzc4NzAiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVRlbXBsYXRlLkNvbmZsaWN0UmVzb2x1dGlvbl9fNzc4NzkiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVRlbXBsYXRlLkNvbmZsaWN0UmVzb2x1dGlvbl9fNzc4OTciLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVRlbXBsYXRlLkNvbmZsaWN0UmVzb2x1dGlvbl9fNzc4OTgiLAorICAgICJsaWJjb3JlLnhtbC5Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSRYc2x0VGVzdCNYU0xULVRlbXBsYXRlLkNvbmZsaWN0UmVzb2x1dGlvbl9fNzc5MDIiCisgIF0KK30sCit7CisgIGRlc2NyaXB0aW9uOiAiQW5kcm9pZCdzIFhQYXRoIGZhaWxzIDI5IG9mIDI1MCBKYXhlbiBYUGF0aCB0ZXN0cyIsCisgIGJ1ZzogMzI3MDc2MSwKKyAgbmFtZXM6IFsKKyAgICAibGliY29yZS54bWwuSmF4ZW5YUGF0aFRlc3RTdWl0ZSQzI3htbC9kZWZhdWx0TmFtZXNwYWNlLnhtbCAvIC9kdW1teTphL2R1bW15OmIvZHVtbXk6YyIsCisgICAgImxpYmNvcmUueG1sLkpheGVuWFBhdGhUZXN0U3VpdGUkMyN4bWwvZXZhbHVhdGUueG1sIC8gLy9tZXRhdGVzdFsgZXZhbHVhdGUoQHNlbGVjdCkgPSAuIF0iLAorICAgICJsaWJjb3JlLnhtbC5KYXhlblhQYXRoVGVzdFN1aXRlJDMjeG1sL2V2YWx1YXRlLnhtbCAvIGV2YWx1YXRlKCcvL2p1bXBzLyonKSIsCisgICAgImxpYmNvcmUueG1sLkpheGVuWFBhdGhUZXN0U3VpdGUkMyN4bWwvZXZhbHVhdGUueG1sIC8gZXZhbHVhdGUoJy8vanVtcHMvKicpL2RvZyIsCisgICAgImxpYmNvcmUueG1sLkpheGVuWFBhdGhUZXN0U3VpdGUkMyN4bWwvZXZhbHVhdGUueG1sIC8gZXZhbHVhdGUoJy8vanVtcHMvb2JqZWN0JykvZG9nIiwKKyAgICAibGliY29yZS54bWwuSmF4ZW5YUGF0aFRlc3RTdWl0ZSQzI3htbC9ldmFsdWF0ZS54bWwgLyBldmFsdWF0ZSgnLy9qdW1wcy9vYmplY3QnKS9ldmFsdWF0ZSIsCisgICAgImxpYmNvcmUueG1sLkpheGVuWFBhdGhUZXN0U3VpdGUkMyN4bWwvZXZhbHVhdGUueG1sIC8gZXZhbHVhdGUoJy8vanVtcHMvb2JqZWN0L2RvZycpIiwKKyAgICAibGliY29yZS54bWwuSmF4ZW5YUGF0aFRlc3RTdWl0ZSQzI3htbC9uYW1lc3BhY2VzLnhtbCAvIC9mb286YSIsCisgICAgImxpYmNvcmUueG1sLkpheGVuWFBhdGhUZXN0U3VpdGUkMyN4bWwvbmFtZXNwYWNlcy54bWwgLyAvZm9vOmEvYiIsCisgICAgImxpYmNvcmUueG1sLkpheGVuWFBhdGhUZXN0U3VpdGUkMyN4bWwvbmFtZXNwYWNlcy54bWwgLyAvdm9vOmEvYi9jIiwKKyAgICAibGliY29yZS54bWwuSmF4ZW5YUGF0aFRlc3RTdWl0ZSQzI3htbC9uYW1lc3BhY2VzLnhtbCAvIC92b286YS9iYXI6ZiIsCisgICAgImxpYmNvcmUueG1sLkpheGVuWFBhdGhUZXN0U3VpdGUkMyN4bWwvdGVzdE5hbWVzcGFjZXMueG1sIC8gLy9uYW1lc3BhY2U6OioiLAorICAgICJsaWJjb3JlLnhtbC5KYXhlblhQYXRoVGVzdFN1aXRlJDMjeG1sL3Rlc3ROYW1lc3BhY2VzLnhtbCAvVGVtcGxhdGUvQXBwbGljYXRpb24xIC8vbmFtZXNwYWNlOjoqIiwKKyAgICAibGliY29yZS54bWwuSmF4ZW5YUGF0aFRlc3RTdWl0ZSQzI3htbC90ZXN0TmFtZXNwYWNlcy54bWwgL1RlbXBsYXRlL0FwcGxpY2F0aW9uMSAvL25hbWVzcGFjZTo6eHBsdCIsCisgICAgImxpYmNvcmUueG1sLkpheGVuWFBhdGhUZXN0U3VpdGUkMyN4bWwvdGV4dC54bWwgLyBkb2N1bWVudCgneG1sL3dlYi54bWwnKSIsCisgICAgImxpYmNvcmUueG1sLkpheGVuWFBhdGhUZXN0U3VpdGUkNCN4bWwvbWVzc2FnZS54bWwgLyBkb2N1bWVudCgneG1sL21lc3NhZ2UueG1sJykvbWVzc2FnZS9ib2R5L2RhdGEvaXRlbXMvaXRlbVtuYW1lL3RleHQoKT0ncGFyZW50aW5mbyddL3ZhbHVlIiwKKyAgICAibGliY29yZS54bWwuSmF4ZW5YUGF0aFRlc3RTdWl0ZSQ0I3htbC9uYW1lc3BhY2VzLnhtbCAvIC9mb286YS9hbGlhczp4L2FsaWFzOnkiLAorICAgICJsaWJjb3JlLnhtbC5KYXhlblhQYXRoVGVzdFN1aXRlJDQjeG1sL25hbWVzcGFjZXMueG1sIC8gL2ZvbzphL2IvYyIsCisgICAgImxpYmNvcmUueG1sLkpheGVuWFBhdGhUZXN0U3VpdGUkNCN4bWwvbmFtZXNwYWNlcy54bWwgLyAvZm9vOmEvZm9vOmQvZm9vOmUiLAorICAgICJsaWJjb3JlLnhtbC5KYXhlblhQYXRoVGVzdFN1aXRlJDQjeG1sL25hbWVzcGFjZXMueG1sIC8gL2ZvbzphL2Zvbzp4L2Zvbzp5IiwKKyAgICAibGliY29yZS54bWwuSmF4ZW5YUGF0aFRlc3RTdWl0ZSQ0I3htbC90ZXh0LnhtbCAvIGRvY3VtZW50KCd4bWwvd2ViLnhtbCcpL3dlYi1hcHAvc2VydmxldFsxXS9zZXJ2bGV0LW5hbWUiLAorICAgICJsaWJjb3JlLnhtbC5KYXhlblhQYXRoVGVzdFN1aXRlJDQjeG1sL3RleHQueG1sIC9mb28vYmFyL2NoZWVzZVsxXSBjb25jYXQoLi9AaWQsZG9jdW1lbnQoJ3htbC93ZWIueG1sJykvd2ViLWFwcC9zZXJ2bGV0WzFdL3NlcnZsZXQtbmFtZSwuL0BpZCkiLAorICAgICJsaWJjb3JlLnhtbC5KYXhlblhQYXRoVGVzdFN1aXRlJDQjeG1sL3dlYi54bWwgL3dlYi1hcHAvc2VydmxldFsxXSBlbmRzLXdpdGgoIHNlcnZsZXQtY2xhc3MsICdTJyApIiwKKyAgICAibGliY29yZS54bWwuSmF4ZW5YUGF0aFRlc3RTdWl0ZSQ0I3htbC93ZWIueG1sIC93ZWItYXBwL3NlcnZsZXRbMV0gZW5kcy13aXRoKCBzZXJ2bGV0LWNsYXNzLCAnU2VydmxldCcgKSIsCisgICAgImxpYmNvcmUueG1sLkpheGVuWFBhdGhUZXN0U3VpdGUkNCN4bWwvd2ViLnhtbCAvd2ViLWFwcC9zZXJ2bGV0WzFdIGxvd2VyLWNhc2UoIHNlcnZsZXQtY2xhc3MgKSIsCisgICAgImxpYmNvcmUueG1sLkpheGVuWFBhdGhUZXN0U3VpdGUkNCN4bWwvd2ViLnhtbCAvd2ViLWFwcC9zZXJ2bGV0WzFdIHVwcGVyLWNhc2UoIHNlcnZsZXQtY2xhc3MgKSIsCisgICAgImxpYmNvcmUueG1sLkpheGVuWFBhdGhUZXN0U3VpdGUkNCN4bWwvd2ViLnhtbCAvd2ViLWFwcC9zZXJ2bGV0WzFdIHVwcGVyLWNhc2UoIHNlcnZsZXQtY2xhc3MsICdlcy1FUy1UcmFkaXRpb25hbF9XSU4nICkiLAorICAgICJsaWJjb3JlLnhtbC5KYXhlblhQYXRoVGVzdFN1aXRlJDQjeG1sL3dlYi54bWwgL3dlYi1hcHAvc2VydmxldFsxXSB1cHBlci1jYXNlKCBzZXJ2bGV0LWNsYXNzLCAnZnInICkiLAorICAgICJsaWJjb3JlLnhtbC5KYXhlblhQYXRoVGVzdFN1aXRlJDQjeG1sL3dlYi54bWwgL3dlYi1hcHAvc2VydmxldFsxXSB1cHBlci1jYXNlKCBzZXJ2bGV0LWNsYXNzLCAnZnItQ0EnICkiCisgIF0KK30KK10KZGlmZiAtLWdpdCBhL2V4cGVjdGF0aW9ucy90YWdnZWR0ZXN0cy50eHQgYi9leHBlY3RhdGlvbnMvdGFnZ2VkdGVzdHMudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg4Mzg2NGMKLS0tIC9kZXYvbnVsbAorKysgYi9leHBlY3RhdGlvbnMvdGFnZ2VkdGVzdHMudHh0CkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiBUaGlzIGZpbGUgY29udGFpbnMgZXhwZWN0YXRpb25zIGZvciB0ZXN0cyB0aGF0IHJlcXVpcmUgc3VwcG9ydCBmcm9tIHRoZSB0ZXN0IHJ1bm5lciB0byBjb21wbGV0ZQorICogc3VjY2Vzc2Z1bGx5LgorICovCitbCit7CisgIGRlc2NyaXB0aW9uOiAibGFyZ2UgdGVzdHMiLAorICByZXN1bHQ6IFNVQ0NFU1MsCisgIG5hbWVzOiBbCisgICAgImphdmEudXRpbC5FbnVtU2V0LkVudW1TZXRCYXNoIiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255LnRlc3RzLmphdmEudXRpbC5yZWdleC5NYXRjaGVyVGVzdCN0ZXN0QWxsQ29kZVBvaW50cyIsCisgICAgImxpYmNvcmUuamF2YXgubmV0LnNzbC5TU0xTb2NrZXRUZXN0IiwKKyAgICAib3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uZnVuYy5LZXlBZ3JlZW1lbnRGdW5jdGlvbmFsVGVzdCIsCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvLmludGVyZmFjZXMuREhQcml2YXRlS2V5VGVzdCIsCisgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvLmludGVyZmFjZXMuREhQdWJsaWNLZXlUZXN0IiwKKyAgICAiamF2YS5pby5QaXBlZElucHV0U3RyZWFtLkNsb3NlQW5kQXZhaWxhYmxlUkMiLAorICAgICJqYXZhLmlvLlByaW50U3RyZWFtLk92ZXJzeW5jaHJvbml6ZWRUZXN0IiwKKyAgICAiamF2YS5pby5QcmludFdyaXRlci5PdmVyc3luY2hyb25pemVkVGVzdCIsCisgICAgImphdmEubGFuZy5TdHJpbmcuU3BsaXQiLAorICAgICJqYXZhLmxhbmcucmVmLlNvZnRSZWZlcmVuY2UuUGluIiwKKyAgICAiamF2YS5tYXRoLkJpZ0ludGVnZXIuQmlnSW50ZWdlclRlc3QiLAorICAgICJqYXZhLm5ldC5NdWx0aWNhc3RTb2NrZXQuVGVzdCIsCisgICAgImphdmEubmV0LlNvY2tldC5Jbmhlcml0VGltZW91dCIsCisgICAgImphdmEubmV0LlNvY2tldC5yZXNldC5UZXN0IiwKKyAgICAiamF2YS5uZXQuVVJMQ29ubmVjdGlvbi5UaW1lb3V0VGVzdCIsCisgICAgImphdmEubmlvLmNoYW5uZWxzLkRhdGFncmFtQ2hhbm5lbC5Db25uZWN0ZWRTZW5kIiwKKyAgICAiamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWwuRXhwYW5kaW5nTWFwIiwKKyAgICAiamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWwuVHJhbnNmZXJzIiwKKyAgICAiamF2YS5uaW8uY2hhbm5lbHMuU29ja2V0Q2hhbm5lbC5PcGVuIiwKKyAgICAiamF2YS50ZXh0LkJpZGkuQnVnNjY2NTAyOCIsCisgICAgImphdmEudXRpbC5Db2xsZWN0aW9ucy5GaW5kU3ViTGlzdCIsCisgICAgImphdmEudXRpbC5Mb2NhbGUuQnVnNDUxODc5NyIsCisgICAgImphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZS5Db250cm9sLlN0cmVzc1Rlc3QiLAorICAgICJqYXZhLnV0aWwuV2Vha0hhc2hNYXAuR0NEdXJpbmdJdGVyYXRpb24iLAorICAgICJqYXZhLnV0aWwuY29uY3VycmVudC5GdXR1cmVUYXNrLlRocm93IiwKKyAgICAiamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3MuUmVlbnRyYW50UmVhZFdyaXRlTG9jay5NYXBMb29wcyIsCisgICAgImphdmEudXRpbC56aXAuTGFyZ2VaaXAiLAorICAgICJqYXZhLnV0aWwuemlwLlppcEZpbGUuTGFyZ2VaaXBGaWxlIiwKKyAgICAiamF2YS51dGlsLnppcC5aaXBGaWxlLk1hbnlFbnRyaWVzIiwKKyAgICAic3VuLm5pby5jcy5GaW5kT25lQ2hhckVuY29kZXJCdWdzIiwKKyAgICAic3VuLm5pby5jcy5TdXJyb2dhdGVHQjE4MDMwVGVzdCIKKyAgXSwKKyAgInRhZ3MiOiBbICJsYXJnZSIgXQorfQorXQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2luY2x1ZGUvTG9jYWxBcnJheS5oIGIvaW5jbHVkZS9Mb2NhbEFycmF5LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmFiNzA4YQotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvTG9jYWxBcnJheS5oCkBAIC0wLDAgKzEsNzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIExPQ0FMX0FSUkFZX0hfaW5jbHVkZWQKKyNkZWZpbmUgTE9DQUxfQVJSQVlfSF9pbmNsdWRlZAorCisjaW5jbHVkZSA8Y3N0ZGRlZj4KKyNpbmNsdWRlIDxuZXc+CisKKy8qKgorICogQSBmaXhlZC1zaXplIGFycmF5IHdpdGggYSBzaXplIGhpbnQuIFRoYXQgbnVtYmVyIG9mIGJ5dGVzIHdpbGwgYmUgYWxsb2NhdGVkCisgKiBvbiB0aGUgc3RhY2ssIGFuZCB1c2VkIGlmIHBvc3NpYmxlLCBidXQgaWYgbW9yZSBieXRlcyBhcmUgcmVxdWVzdGVkIGF0CisgKiBjb25zdHJ1Y3Rpb24gdGltZSwgYSBidWZmZXIgd2lsbCBiZSBhbGxvY2F0ZWQgb24gdGhlIGhlYXAgKGFuZCBkZWFsbG9jYXRlZAorICogYnkgdGhlIGRlc3RydWN0b3IpLgorICoKKyAqIFRoZSBBUEkgaXMgaW50ZW5kZWQgdG8gYmUgYSBjb21wYXRpYmxlIHN1YnNldCBvZiBDKysweCdzIHN0ZDo6YXJyYXkuCisgKi8KK3RlbXBsYXRlIDxzaXplX3QgU1RBQ0tfQllURV9DT1VOVD4KK2NsYXNzIExvY2FsQXJyYXkgeworcHVibGljOgorICAgIC8qKgorICAgICAqIEFsbG9jYXRlcyBhIG5ldyBmaXhlZC1zaXplIGFycmF5IG9mIHRoZSBnaXZlbiBzaXplLiBJZiB0aGlzIHNpemUgaXMKKyAgICAgKiBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHRlbXBsYXRlIHBhcmFtZXRlciBTVEFDS19CWVRFX0NPVU5ULCBhbgorICAgICAqIGludGVybmFsIG9uLXN0YWNrIGJ1ZmZlciB3aWxsIGJlIHVzZWQuIE90aGVyd2lzZSBhIGhlYXAgYnVmZmVyIHdpbGwKKyAgICAgKiBiZSBhbGxvY2F0ZWQuCisgICAgICovCisgICAgTG9jYWxBcnJheShzaXplX3QgZGVzaXJlZEJ5dGVDb3VudCkgOiBtU2l6ZShkZXNpcmVkQnl0ZUNvdW50KSB7CisgICAgICAgIGlmIChkZXNpcmVkQnl0ZUNvdW50ID4gU1RBQ0tfQllURV9DT1VOVCkgeworICAgICAgICAgICAgbVB0ciA9IG5ldyBjaGFyW21TaXplXTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG1QdHIgPSAmbU9uU3RhY2tCdWZmZXJbMF07CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGcmVlcyB0aGUgaGVhcC1hbGxvY2F0ZWQgYnVmZmVyLCBpZiB0aGVyZSB3YXMgb25lLgorICAgICAqLworICAgIH5Mb2NhbEFycmF5KCkgeworICAgICAgICBpZiAobVB0ciAhPSAmbU9uU3RhY2tCdWZmZXJbMF0pIHsKKyAgICAgICAgICAgIGRlbGV0ZVtdIG1QdHI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBDYXBhY2l0eS4KKyAgICBzaXplX3Qgc2l6ZSgpIHsgcmV0dXJuIG1TaXplOyB9CisgICAgYm9vbCBlbXB0eSgpIHsgcmV0dXJuIG1TaXplID09IDA7IH0KKworICAgIC8vIEVsZW1lbnQgYWNjZXNzLgorICAgIGNoYXImIG9wZXJhdG9yW10oc2l6ZV90IG4pIHsgcmV0dXJuIG1QdHJbbl07IH0KKyAgICBjb25zdCBjaGFyJiBvcGVyYXRvcltdKHNpemVfdCBuKSBjb25zdCB7IHJldHVybiBtUHRyW25dOyB9CisKK3ByaXZhdGU6CisgICAgY2hhciBtT25TdGFja0J1ZmZlcltTVEFDS19CWVRFX0NPVU5UXTsKKyAgICBjaGFyKiBtUHRyOworICAgIHNpemVfdCBtU2l6ZTsKKworICAgIC8vIERpc2FsbG93IGNvcHkgYW5kIGFzc2lnbm1lbnQuCisgICAgTG9jYWxBcnJheShjb25zdCBMb2NhbEFycmF5Jik7CisgICAgdm9pZCBvcGVyYXRvcj0oY29uc3QgTG9jYWxBcnJheSYpOworfTsKKworI2VuZGlmIC8vIExPQ0FMX0FSUkFZX0hfaW5jbHVkZWQKZGlmZiAtLWdpdCBhL2luY2x1ZGUvU2NvcGVkQnl0ZXMuaCBiL2luY2x1ZGUvU2NvcGVkQnl0ZXMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYjI2MTRiCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS9TY29wZWRCeXRlcy5oCkBAIC0wLDAgKzEsODAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIFNDT1BFRF9CWVRFU19IX2luY2x1ZGVkCisjZGVmaW5lIFNDT1BFRF9CWVRFU19IX2luY2x1ZGVkCisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisKKy8qKgorICogU2NvcGVkQnl0ZXNSTyBhbmQgU2NvcGVkQnl0ZXNSVyBhdHRlbXB0IHRvIHBhcGVyIG92ZXIgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gYnl0ZVtdcyBhbmQKKyAqIEJ5dGVCdWZmZXJzLiBUaGlzIGluIHR1cm4gaGVscHMgcGFwZXIgb3ZlciB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBub24tZGlyZWN0IEJ5dGVCdWZmZXJzIGJhY2tlZAorICogYnkgYnl0ZVtdcywgZGlyZWN0IEJ5dGVCdWZmZXJzIGJhY2tlZCBieSBieXRlc1tdcywgYW5kIGRpcmVjdCBCeXRlQnVmZmVycyBub3QgYmFja2VkIGJ5IGJ5dGVbXXMuCisgKiAoT24gQW5kcm9pZCwgdGhpcyBsYXN0IGdyb3VwIG9ubHkgY29udGFpbnMgTWFwcGVkQnl0ZUJ1ZmZlcnMuKQorICovCit0ZW1wbGF0ZTxib29sIHJlYWRPbmx5PgorY2xhc3MgU2NvcGVkQnl0ZXMgeworcHVibGljOgorICAgIFNjb3BlZEJ5dGVzKEpOSUVudiogZW52LCBqb2JqZWN0IG9iamVjdCkKKyAgICA6IG1FbnYoZW52KSwgbU9iamVjdChvYmplY3QpLCBtQnl0ZUFycmF5KE5VTEwpLCBtUHRyKE5VTEwpCisgICAgeworICAgICAgICBpZiAobU9iamVjdCA9PSBOVUxMKSB7CisgICAgICAgICAgICBqbmlUaHJvd051bGxQb2ludGVyRXhjZXB0aW9uKG1FbnYsIE5VTEwpOworICAgICAgICB9IGVsc2UgaWYgKG1FbnYtPklzSW5zdGFuY2VPZihtT2JqZWN0LCBKbmlDb25zdGFudHM6OmJ5dGVBcnJheUNsYXNzKSkgeworICAgICAgICAgICAgbUJ5dGVBcnJheSA9IHJlaW50ZXJwcmV0X2Nhc3Q8amJ5dGVBcnJheT4obU9iamVjdCk7CisgICAgICAgICAgICBtUHRyID0gbUVudi0+R2V0Qnl0ZUFycmF5RWxlbWVudHMobUJ5dGVBcnJheSwgTlVMTCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBtUHRyID0gcmVpbnRlcnByZXRfY2FzdDxqYnl0ZSo+KG1FbnYtPkdldERpcmVjdEJ1ZmZlckFkZHJlc3MobU9iamVjdCkpOworICAgICAgICB9CisgICAgfQorCisgICAgflNjb3BlZEJ5dGVzKCkgeworICAgICAgICBpZiAobUJ5dGVBcnJheSAhPSBOVUxMKSB7CisgICAgICAgICAgICBtRW52LT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMobUJ5dGVBcnJheSwgbVB0ciwgcmVhZE9ubHkgPyBKTklfQUJPUlQgOiAwKTsKKyAgICAgICAgfQorICAgIH0KKworcHJpdmF0ZToKKyAgICBKTklFbnYqIG1FbnY7CisgICAgam9iamVjdCBtT2JqZWN0OworICAgIGpieXRlQXJyYXkgbUJ5dGVBcnJheTsKKworcHJvdGVjdGVkOgorICAgIGpieXRlKiBtUHRyOworCitwcml2YXRlOgorICAgIC8vIERpc2FsbG93IGNvcHkgYW5kIGFzc2lnbm1lbnQuCisgICAgU2NvcGVkQnl0ZXMoY29uc3QgU2NvcGVkQnl0ZXMmKTsKKyAgICB2b2lkIG9wZXJhdG9yPShjb25zdCBTY29wZWRCeXRlcyYpOworfTsKKworY2xhc3MgU2NvcGVkQnl0ZXNSTyA6IHB1YmxpYyBTY29wZWRCeXRlczx0cnVlPiB7CitwdWJsaWM6CisgICAgU2NvcGVkQnl0ZXNSTyhKTklFbnYqIGVudiwgam9iamVjdCBvYmplY3QpIDogU2NvcGVkQnl0ZXM8dHJ1ZT4oZW52LCBvYmplY3QpIHt9CisgICAgY29uc3QgamJ5dGUqIGdldCgpIGNvbnN0IHsKKyAgICAgICAgcmV0dXJuIG1QdHI7CisgICAgfQorfTsKKworY2xhc3MgU2NvcGVkQnl0ZXNSVyA6IHB1YmxpYyBTY29wZWRCeXRlczxmYWxzZT4geworcHVibGljOgorICAgIFNjb3BlZEJ5dGVzUlcoSk5JRW52KiBlbnYsIGpvYmplY3Qgb2JqZWN0KSA6IFNjb3BlZEJ5dGVzPGZhbHNlPihlbnYsIG9iamVjdCkge30KKyAgICBqYnl0ZSogZ2V0KCkgeworICAgICAgICByZXR1cm4gbVB0cjsKKyAgICB9Cit9OworCisjZW5kaWYgIC8vIFNDT1BFRF9CWVRFU19IX2luY2x1ZGVkCmRpZmYgLS1naXQgYS9pbmNsdWRlL1Njb3BlZEZkLmggYi9pbmNsdWRlL1Njb3BlZEZkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDJiNzkzNQotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvU2NvcGVkRmQuaApAQCAtMCwwICsxLDQ2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBTQ09QRURfRkRfSF9pbmNsdWRlZAorI2RlZmluZSBTQ09QRURfRkRfSF9pbmNsdWRlZAorCisjaW5jbHVkZSA8dW5pc3RkLmg+CisKKy8vIEEgc21hcnQgcG9pbnRlciB0aGF0IGNsb3NlcyB0aGUgZ2l2ZW4gZmQgb24gZ29pbmcgb3V0IG9mIHNjb3BlLgorLy8gVXNlIHRoaXMgd2hlbiB0aGUgZmQgaXMgaW5jaWRlbnRhbCB0byB0aGUgcHVycG9zZSBvZiB5b3VyIGZ1bmN0aW9uLAorLy8gYnV0IG5lZWRzIHRvIGJlIGNsZWFuZWQgdXAgb24gZXhpdC4KK2NsYXNzIFNjb3BlZEZkIHsKK3B1YmxpYzoKKyAgICBleHBsaWNpdCBTY29wZWRGZChpbnQgZmQpIDogZmQoZmQpIHsKKyAgICB9CisKKyAgICB+U2NvcGVkRmQoKSB7CisgICAgICAgIGNsb3NlKGZkKTsKKyAgICB9CisKKyAgICBpbnQgZ2V0KCkgY29uc3QgeworICAgICAgICByZXR1cm4gZmQ7CisgICAgfQorCitwcml2YXRlOgorICAgIGludCBmZDsKKworICAgIC8vIERpc2FsbG93IGNvcHkgYW5kIGFzc2lnbm1lbnQuCisgICAgU2NvcGVkRmQoY29uc3QgU2NvcGVkRmQmKTsKKyAgICB2b2lkIG9wZXJhdG9yPShjb25zdCBTY29wZWRGZCYpOworfTsKKworI2VuZGlmICAvLyBTQ09QRURfRkRfSF9pbmNsdWRlZApkaWZmIC0tZ2l0IGEvaW5jbHVkZS9TY29wZWRKYXZhVW5pY29kZVN0cmluZy5oIGIvaW5jbHVkZS9TY29wZWRKYXZhVW5pY29kZVN0cmluZy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxMDhhNmIKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL1Njb3BlZEphdmFVbmljb2RlU3RyaW5nLmgKQEAgLTAsMCArMSw1NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKiAKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKiAKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKiAKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgU0NPUEVEX0pBVkFfVU5JQ09ERV9TVFJJTkdfSF9pbmNsdWRlZAorI2RlZmluZSBTQ09QRURfSkFWQV9VTklDT0RFX1NUUklOR19IX2luY2x1ZGVkCisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisjaW5jbHVkZSAidW5pY29kZS91bmlzdHIuaCIKKworLy8gQSBzbWFydCBwb2ludGVyIHRoYXQgcHJvdmlkZXMgYWNjZXNzIHRvIGFuIElDVSBVbmljb2RlU3RyaW5nIGdpdmVuIGEgSk5JCisvLyBqc3RyaW5nLiBXZSBnaXZlIElDVSBhIGRpcmVjdCBwb2ludGVyIHRvIHRoZSBjaGFyYWN0ZXJzIG9uIHRoZSBKYXZhIGhlYXAuCisvLyBJdCdzIGNsZXZlciBlbm91Z2ggdG8gY29weS1vbi13cml0ZSBpZiBuZWNlc3NhcnkuCitjbGFzcyBTY29wZWRKYXZhVW5pY29kZVN0cmluZyB7CitwdWJsaWM6CisgICAgU2NvcGVkSmF2YVVuaWNvZGVTdHJpbmcoSk5JRW52KiBlbnYsIGpzdHJpbmcgcykgOiBtRW52KGVudiksIG1TdHJpbmcocykgeworICAgICAgICBtQ2hhcnMgPSBlbnYtPkdldFN0cmluZ0NoYXJzKG1TdHJpbmcsIE5VTEwpOworICAgICAgICBjb25zdCBpbnQzMl90IGNoYXJDb3VudCA9IGVudi0+R2V0U3RyaW5nTGVuZ3RoKG1TdHJpbmcpOworICAgICAgICBtVW5pY29kZVN0cmluZy5zZXRUbyhmYWxzZSwgbUNoYXJzLCBjaGFyQ291bnQpOworICAgIH0KKworICAgIH5TY29wZWRKYXZhVW5pY29kZVN0cmluZygpIHsKKyAgICAgICAgbUVudi0+UmVsZWFzZVN0cmluZ0NoYXJzKG1TdHJpbmcsIG1DaGFycyk7CisgICAgfQorCisgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdW5pY29kZVN0cmluZygpIGNvbnN0IHsKKyAgICAgICAgcmV0dXJuIG1Vbmljb2RlU3RyaW5nOworICAgIH0KKworICAgIFVuaWNvZGVTdHJpbmcmIHVuaWNvZGVTdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBtVW5pY29kZVN0cmluZzsKKyAgICB9CisKK3ByaXZhdGU6CisgICAgSk5JRW52KiBtRW52OworICAgIGpzdHJpbmcgbVN0cmluZzsKKyAgICBjb25zdCBVQ2hhciogbUNoYXJzOworICAgIFVuaWNvZGVTdHJpbmcgbVVuaWNvZGVTdHJpbmc7CisKKyAgICAvLyBEaXNhbGxvdyBjb3B5IGFuZCBhc3NpZ25tZW50LgorICAgIFNjb3BlZEphdmFVbmljb2RlU3RyaW5nKGNvbnN0IFNjb3BlZEphdmFVbmljb2RlU3RyaW5nJik7CisgICAgdm9pZCBvcGVyYXRvcj0oY29uc3QgU2NvcGVkSmF2YVVuaWNvZGVTdHJpbmcmKTsKK307CisKKyNlbmRpZiAgLy8gU0NPUEVEX0pBVkFfVU5JQ09ERV9TVFJJTkdfSF9pbmNsdWRlZApkaWZmIC0tZ2l0IGEvaW5jbHVkZS9TY29wZWRMb2NhbEZyYW1lLmggYi9pbmNsdWRlL1Njb3BlZExvY2FsRnJhbWUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNWI2YWQ4Ci0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS9TY29wZWRMb2NhbEZyYW1lLmgKQEAgLTAsMCArMSw0MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKiAKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKiAKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKiAKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgU0NPUEVEX0xPQ0FMX0ZSQU1FX0hfaW5jbHVkZWQKKyNkZWZpbmUgU0NPUEVEX0xPQ0FMX0ZSQU1FX0hfaW5jbHVkZWQKKworI2luY2x1ZGUgIkpOSUhlbHAuaCIKKworY2xhc3MgU2NvcGVkTG9jYWxGcmFtZSB7CitwdWJsaWM6CisgICAgU2NvcGVkTG9jYWxGcmFtZShKTklFbnYqIGVudikgOiBtRW52KGVudikgeworICAgICAgICBtRW52LT5QdXNoTG9jYWxGcmFtZSgxMjgpOworICAgIH0KKworICAgIH5TY29wZWRMb2NhbEZyYW1lKCkgeworICAgICAgICBtRW52LT5Qb3BMb2NhbEZyYW1lKE5VTEwpOworICAgIH0KKworcHJpdmF0ZToKKyAgICBKTklFbnYqIG1FbnY7CisKKyAgICAvLyBEaXNhbGxvdyBjb3B5IGFuZCBhc3NpZ25tZW50LgorICAgIFNjb3BlZExvY2FsRnJhbWUoY29uc3QgU2NvcGVkTG9jYWxGcmFtZSYpOworICAgIHZvaWQgb3BlcmF0b3I9KGNvbnN0IFNjb3BlZExvY2FsRnJhbWUmKTsKK307CisKKyNlbmRpZiAgLy8gU0NPUEVEX0xPQ0FMX0ZSQU1FX0hfaW5jbHVkZWQKZGlmZiAtLWdpdCBhL2luY2x1ZGUvU2NvcGVkTG9jYWxSZWYuaCBiL2luY2x1ZGUvU2NvcGVkTG9jYWxSZWYuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NGVlMTFhCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS9TY29wZWRMb2NhbFJlZi5oCkBAIC0wLDAgKzEsNTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIFNDT1BFRF9MT0NBTF9SRUZfSF9pbmNsdWRlZAorI2RlZmluZSBTQ09QRURfTE9DQUxfUkVGX0hfaW5jbHVkZWQKKworI2luY2x1ZGUgIkpOSUhlbHAuaCIKKworLy8gQSBzbWFydCBwb2ludGVyIHRoYXQgZGVsZXRlcyBhIEpOSSBsb2NhbCByZWZlcmVuY2Ugd2hlbiBpdCBnb2VzIG91dCBvZiBzY29wZS4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitjbGFzcyBTY29wZWRMb2NhbFJlZiB7CitwdWJsaWM6CisgICAgU2NvcGVkTG9jYWxSZWYoSk5JRW52KiBlbnYsIFQgbG9jYWxSZWYpCisgICAgOiBtRW52KGVudiksIG1Mb2NhbFJlZihsb2NhbFJlZikKKyAgICB7CisgICAgfQorCisgICAgflNjb3BlZExvY2FsUmVmKCkgeworICAgICAgICByZXNldCgpOworICAgIH0KKworICAgIHZvaWQgcmVzZXQoKSB7CisgICAgICAgIGlmIChtTG9jYWxSZWYgIT0gTlVMTCkgeworICAgICAgICAgICAgbUVudi0+RGVsZXRlTG9jYWxSZWYobUxvY2FsUmVmKTsKKyAgICAgICAgICAgIG1Mb2NhbFJlZiA9IE5VTEw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBUIGdldCgpIGNvbnN0IHsKKyAgICAgICAgcmV0dXJuIG1Mb2NhbFJlZjsKKyAgICB9CisKK3ByaXZhdGU6CisgICAgSk5JRW52KiBtRW52OworICAgIFQgbUxvY2FsUmVmOworCisgICAgLy8gRGlzYWxsb3cgY29weSBhbmQgYXNzaWdubWVudC4KKyAgICBTY29wZWRMb2NhbFJlZihjb25zdCBTY29wZWRMb2NhbFJlZiYpOworICAgIHZvaWQgb3BlcmF0b3I9KGNvbnN0IFNjb3BlZExvY2FsUmVmJik7Cit9OworCisjZW5kaWYgIC8vIFNDT1BFRF9MT0NBTF9SRUZfSF9pbmNsdWRlZApkaWZmIC0tZ2l0IGEvaW5jbHVkZS9TY29wZWRQcmltaXRpdmVBcnJheS5oIGIvaW5jbHVkZS9TY29wZWRQcmltaXRpdmVBcnJheS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA3OWU5OGMKLS0tIC9kZXYvbnVsbAorKysgYi9pbmNsdWRlL1Njb3BlZFByaW1pdGl2ZUFycmF5LmgKQEAgLTAsMCArMSwxMDggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIFNDT1BFRF9QUklNSVRJVkVfQVJSQVlfSF9pbmNsdWRlZAorI2RlZmluZSBTQ09QRURfUFJJTUlUSVZFX0FSUkFZX0hfaW5jbHVkZWQKKworI2luY2x1ZGUgIkpOSUhlbHAuaCIKKworLy8gU2NvcGVkQm9vbGVhbkFycmF5Uk8sIFNjb3BlZEJ5dGVBcnJheVJPLCBTY29wZWRDaGFyQXJyYXlSTywgU2NvcGVkRG91YmxlQXJyYXlSTywKKy8vIFNjb3BlZEZsb2F0QXJyYXlSTywgU2NvcGVkSW50QXJyYXlSTywgU2NvcGVkTG9uZ0FycmF5Uk8sIGFuZCBTY29wZWRTaG9ydEFycmF5Uk8gcHJvdmlkZQorLy8gY29udmVuaWVudCByZWFkLW9ubHkgYWNjZXNzIHRvIEphdmEgYXJyYXlzIGZyb20gSk5JIGNvZGUuIFRoaXMgaXMgY2hlYXBlciB0aGFuIHJlYWQtd3JpdGUKKy8vIGFjY2VzcyBhbmQgc2hvdWxkIGJlIHVzZWQgYnkgZGVmYXVsdC4KKyNkZWZpbmUgSU5TVEFOVElBVEVfU0NPUEVEX1BSSU1JVElWRV9BUlJBWV9STyhQUklNSVRJVkVfVFlQRSwgTkFNRSkgXAorICAgIGNsYXNzIFNjb3BlZCAjIyBOQU1FICMjIEFycmF5Uk8geyBcCisgICAgcHVibGljOiBcCisgICAgICAgIFNjb3BlZCAjIyBOQU1FICMjIEFycmF5Uk8oSk5JRW52KiBlbnYsIFBSSU1JVElWRV9UWVBFICMjIEFycmF5IGphdmFBcnJheSkgXAorICAgICAgICA6IG1FbnYoZW52KSwgbUphdmFBcnJheShqYXZhQXJyYXkpLCBtUmF3QXJyYXkoTlVMTCkgeyBcCisgICAgICAgICAgICBpZiAobUphdmFBcnJheSA9PSBOVUxMKSB7IFwKKyAgICAgICAgICAgICAgICBqbmlUaHJvd051bGxQb2ludGVyRXhjZXB0aW9uKG1FbnYsIE5VTEwpOyBcCisgICAgICAgICAgICB9IGVsc2UgeyBcCisgICAgICAgICAgICAgICAgbVJhd0FycmF5ID0gbUVudi0+R2V0ICMjIE5BTUUgIyMgQXJyYXlFbGVtZW50cyhtSmF2YUFycmF5LCBOVUxMKTsgXAorICAgICAgICAgICAgfSBcCisgICAgICAgIH0gXAorICAgICAgICB+U2NvcGVkICMjIE5BTUUgIyMgQXJyYXlSTygpIHsgXAorICAgICAgICAgICAgaWYgKG1SYXdBcnJheSkgeyBcCisgICAgICAgICAgICAgICAgbUVudi0+UmVsZWFzZSAjIyBOQU1FICMjIEFycmF5RWxlbWVudHMobUphdmFBcnJheSwgbVJhd0FycmF5LCBKTklfQUJPUlQpOyBcCisgICAgICAgICAgICB9IFwKKyAgICAgICAgfSBcCisgICAgICAgIGNvbnN0IFBSSU1JVElWRV9UWVBFKiBnZXQoKSBjb25zdCB7IHJldHVybiBtUmF3QXJyYXk7IH0gXAorICAgICAgICBjb25zdCBQUklNSVRJVkVfVFlQRSYgb3BlcmF0b3JbXShzaXplX3QgbikgY29uc3QgeyByZXR1cm4gbVJhd0FycmF5W25dOyB9IFwKKyAgICAgICAgc2l6ZV90IHNpemUoKSBjb25zdCB7IHJldHVybiBtRW52LT5HZXRBcnJheUxlbmd0aChtSmF2YUFycmF5KTsgfSBcCisgICAgcHJpdmF0ZTogXAorICAgICAgICBKTklFbnYqIG1FbnY7IFwKKyAgICAgICAgUFJJTUlUSVZFX1RZUEUgIyMgQXJyYXkgbUphdmFBcnJheTsgXAorICAgICAgICBQUklNSVRJVkVfVFlQRSogbVJhd0FycmF5OyBcCisgICAgICAgIFNjb3BlZCAjIyBOQU1FICMjIEFycmF5Uk8oY29uc3QgU2NvcGVkICMjIE5BTUUgIyMgQXJyYXlSTyYpOyBcCisgICAgICAgIHZvaWQgb3BlcmF0b3I9KGNvbnN0IFNjb3BlZCAjIyBOQU1FICMjIEFycmF5Uk8mKTsgXAorICAgIH0KKworSU5TVEFOVElBVEVfU0NPUEVEX1BSSU1JVElWRV9BUlJBWV9STyhqYm9vbGVhbiwgQm9vbGVhbik7CitJTlNUQU5USUFURV9TQ09QRURfUFJJTUlUSVZFX0FSUkFZX1JPKGpieXRlLCBCeXRlKTsKK0lOU1RBTlRJQVRFX1NDT1BFRF9QUklNSVRJVkVfQVJSQVlfUk8oamNoYXIsIENoYXIpOworSU5TVEFOVElBVEVfU0NPUEVEX1BSSU1JVElWRV9BUlJBWV9STyhqZG91YmxlLCBEb3VibGUpOworSU5TVEFOVElBVEVfU0NPUEVEX1BSSU1JVElWRV9BUlJBWV9STyhqZmxvYXQsIEZsb2F0KTsKK0lOU1RBTlRJQVRFX1NDT1BFRF9QUklNSVRJVkVfQVJSQVlfUk8oamludCwgSW50KTsKK0lOU1RBTlRJQVRFX1NDT1BFRF9QUklNSVRJVkVfQVJSQVlfUk8oamxvbmcsIExvbmcpOworSU5TVEFOVElBVEVfU0NPUEVEX1BSSU1JVElWRV9BUlJBWV9STyhqc2hvcnQsIFNob3J0KTsKKworI3VuZGVmIElOU1RBTlRJQVRFX1NDT1BFRF9QUklNSVRJVkVfQVJSQVlfUk8KKworLy8gU2NvcGVkQm9vbGVhbkFycmF5UlcsIFNjb3BlZEJ5dGVBcnJheVJXLCBTY29wZWRDaGFyQXJyYXlSVywgU2NvcGVkRG91YmxlQXJyYXlSVywKKy8vIFNjb3BlZEZsb2F0QXJyYXlSVywgU2NvcGVkSW50QXJyYXlSVywgU2NvcGVkTG9uZ0FycmF5UlcsIGFuZCBTY29wZWRTaG9ydEFycmF5UlcgcHJvdmlkZQorLy8gY29udmVuaWVudCByZWFkLXdyaXRlIGFjY2VzcyB0byBKYXZhIGFycmF5cyBmcm9tIEpOSSBjb2RlLiBUaGVzZSBhcmUgbW9yZSBleHBlbnNpdmUsCisvLyBzaW5jZSB0aGV5IGVudGFpbCBhIGNvcHkgYmFjayBvbnRvIHRoZSBKYXZhIGhlYXAsIGFuZCBzaG91bGQgb25seSBiZSB1c2VkIHdoZW4gbmVjZXNzYXJ5LgorI2RlZmluZSBJTlNUQU5USUFURV9TQ09QRURfUFJJTUlUSVZFX0FSUkFZX1JXKFBSSU1JVElWRV9UWVBFLCBOQU1FKSBcCisgICAgY2xhc3MgU2NvcGVkICMjIE5BTUUgIyMgQXJyYXlSVyB7IFwKKyAgICBwdWJsaWM6IFwKKyAgICAgICAgU2NvcGVkICMjIE5BTUUgIyMgQXJyYXlSVyhKTklFbnYqIGVudiwgUFJJTUlUSVZFX1RZUEUgIyMgQXJyYXkgamF2YUFycmF5KSBcCisgICAgICAgIDogbUVudihlbnYpLCBtSmF2YUFycmF5KGphdmFBcnJheSksIG1SYXdBcnJheShOVUxMKSB7IFwKKyAgICAgICAgICAgIGlmIChtSmF2YUFycmF5ID09IE5VTEwpIHsgXAorICAgICAgICAgICAgICAgIGpuaVRocm93TnVsbFBvaW50ZXJFeGNlcHRpb24obUVudiwgTlVMTCk7IFwKKyAgICAgICAgICAgIH0gZWxzZSB7IFwKKyAgICAgICAgICAgICAgICBtUmF3QXJyYXkgPSBtRW52LT5HZXQgIyMgTkFNRSAjIyBBcnJheUVsZW1lbnRzKG1KYXZhQXJyYXksIE5VTEwpOyBcCisgICAgICAgICAgICB9IFwKKyAgICAgICAgfSBcCisgICAgICAgIH5TY29wZWQgIyMgTkFNRSAjIyBBcnJheVJXKCkgeyBcCisgICAgICAgICAgICBpZiAobVJhd0FycmF5KSB7IFwKKyAgICAgICAgICAgICAgICBtRW52LT5SZWxlYXNlICMjIE5BTUUgIyMgQXJyYXlFbGVtZW50cyhtSmF2YUFycmF5LCBtUmF3QXJyYXksIDApOyBcCisgICAgICAgICAgICB9IFwKKyAgICAgICAgfSBcCisgICAgICAgIGNvbnN0IFBSSU1JVElWRV9UWVBFKiBnZXQoKSBjb25zdCB7IHJldHVybiBtUmF3QXJyYXk7IH0gXAorICAgICAgICBjb25zdCBQUklNSVRJVkVfVFlQRSYgb3BlcmF0b3JbXShzaXplX3QgbikgY29uc3QgeyByZXR1cm4gbVJhd0FycmF5W25dOyB9IFwKKyAgICAgICAgUFJJTUlUSVZFX1RZUEUqIGdldCgpIHsgcmV0dXJuIG1SYXdBcnJheTsgfSBcCisgICAgICAgIFBSSU1JVElWRV9UWVBFJiBvcGVyYXRvcltdKHNpemVfdCBuKSB7IHJldHVybiBtUmF3QXJyYXlbbl07IH0gXAorICAgICAgICBzaXplX3Qgc2l6ZSgpIGNvbnN0IHsgcmV0dXJuIG1FbnYtPkdldEFycmF5TGVuZ3RoKG1KYXZhQXJyYXkpOyB9IFwKKyAgICBwcml2YXRlOiBcCisgICAgICAgIEpOSUVudiogbUVudjsgXAorICAgICAgICBQUklNSVRJVkVfVFlQRSAjIyBBcnJheSBtSmF2YUFycmF5OyBcCisgICAgICAgIFBSSU1JVElWRV9UWVBFKiBtUmF3QXJyYXk7IFwKKyAgICAgICAgU2NvcGVkICMjIE5BTUUgIyMgQXJyYXlSVyhjb25zdCBTY29wZWQgIyMgTkFNRSAjIyBBcnJheVJXJik7IFwKKyAgICAgICAgdm9pZCBvcGVyYXRvcj0oY29uc3QgU2NvcGVkICMjIE5BTUUgIyMgQXJyYXlSVyYpOyBcCisgICAgfQorCitJTlNUQU5USUFURV9TQ09QRURfUFJJTUlUSVZFX0FSUkFZX1JXKGpib29sZWFuLCBCb29sZWFuKTsKK0lOU1RBTlRJQVRFX1NDT1BFRF9QUklNSVRJVkVfQVJSQVlfUlcoamJ5dGUsIEJ5dGUpOworSU5TVEFOVElBVEVfU0NPUEVEX1BSSU1JVElWRV9BUlJBWV9SVyhqY2hhciwgQ2hhcik7CitJTlNUQU5USUFURV9TQ09QRURfUFJJTUlUSVZFX0FSUkFZX1JXKGpkb3VibGUsIERvdWJsZSk7CitJTlNUQU5USUFURV9TQ09QRURfUFJJTUlUSVZFX0FSUkFZX1JXKGpmbG9hdCwgRmxvYXQpOworSU5TVEFOVElBVEVfU0NPUEVEX1BSSU1JVElWRV9BUlJBWV9SVyhqaW50LCBJbnQpOworSU5TVEFOVElBVEVfU0NPUEVEX1BSSU1JVElWRV9BUlJBWV9SVyhqbG9uZywgTG9uZyk7CitJTlNUQU5USUFURV9TQ09QRURfUFJJTUlUSVZFX0FSUkFZX1JXKGpzaG9ydCwgU2hvcnQpOworCisjdW5kZWYgSU5TVEFOVElBVEVfU0NPUEVEX1BSSU1JVElWRV9BUlJBWV9SVworCisjZW5kaWYgIC8vIFNDT1BFRF9QUklNSVRJVkVfQVJSQVlfSF9pbmNsdWRlZApkaWZmIC0tZ2l0IGEvaW5jbHVkZS9TY29wZWRQdGhyZWFkTXV0ZXhMb2NrLmggYi9pbmNsdWRlL1Njb3BlZFB0aHJlYWRNdXRleExvY2suaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MGY0NTk2Ci0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS9TY29wZWRQdGhyZWFkTXV0ZXhMb2NrLmgKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgU0NPUEVEX1BUSFJFQURfTVVURVhfTE9DS19IX2luY2x1ZGVkCisjZGVmaW5lIFNDT1BFRF9QVEhSRUFEX01VVEVYX0xPQ0tfSF9pbmNsdWRlZAorCisjaW5jbHVkZSA8cHRocmVhZC5oPgorCisvKioKKyAqIExvY2tzIGFuZCB1bmxvY2tzIGEgcHRocmVhZF9tdXRleF90IGFzIGl0IGdvZXMgaW4gYW5kIG91dCBvZiBzY29wZS4KKyAqLworY2xhc3MgU2NvcGVkUHRocmVhZE11dGV4TG9jayB7CitwdWJsaWM6CisgICAgZXhwbGljaXQgU2NvcGVkUHRocmVhZE11dGV4TG9jayhwdGhyZWFkX211dGV4X3QqIG11dGV4KSA6IG1NdXRleFB0cihtdXRleCkgeworICAgICAgICBwdGhyZWFkX211dGV4X2xvY2sobU11dGV4UHRyKTsKKyAgICB9CisKKyAgICB+U2NvcGVkUHRocmVhZE11dGV4TG9jaygpIHsKKyAgICAgICAgcHRocmVhZF9tdXRleF91bmxvY2sobU11dGV4UHRyKTsKKyAgICB9CisKK3ByaXZhdGU6CisgICAgcHRocmVhZF9tdXRleF90KiBtTXV0ZXhQdHI7CisKKyAgICAvLyBEaXNhbGxvdyBjb3B5IGFuZCBhc3NpZ25tZW50LgorICAgIFNjb3BlZFB0aHJlYWRNdXRleExvY2soY29uc3QgU2NvcGVkUHRocmVhZE11dGV4TG9jayYpOworICAgIHZvaWQgb3BlcmF0b3I9KGNvbnN0IFNjb3BlZFB0aHJlYWRNdXRleExvY2smKTsKK307CisKKyNlbmRpZiAgLy8gU0NPUEVEX1BUSFJFQURfTVVURVhfTE9DS19IX2luY2x1ZGVkCmRpZmYgLS1naXQgYS9pbmNsdWRlL1Njb3BlZFN0cmluZ0NoYXJzLmggYi9pbmNsdWRlL1Njb3BlZFN0cmluZ0NoYXJzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjU5Yjc4NgotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvU2NvcGVkU3RyaW5nQ2hhcnMuaApAQCAtMCwwICsxLDUxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBTQ09QRURfU1RSSU5HX0NIQVJTX0hfaW5jbHVkZWQKKyNkZWZpbmUgU0NPUEVEX1NUUklOR19DSEFSU19IX2luY2x1ZGVkCisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisKKy8vIEEgc21hcnQgcG9pbnRlciB0aGF0IHByb3ZpZGVzIGFjY2VzcyB0byBhIGpjaGFyKiBnaXZlbiBhIEpOSSBqc3RyaW5nLgorY2xhc3MgU2NvcGVkU3RyaW5nQ2hhcnMgeworcHVibGljOgorICAgIFNjb3BlZFN0cmluZ0NoYXJzKEpOSUVudiogZW52LCBqc3RyaW5nIHMpIDogbUVudihlbnYpLCBtU3RyaW5nKHMpLCBtU2l6ZSgwKSB7CisgICAgICAgIG1DaGFycyA9IGVudi0+R2V0U3RyaW5nQ2hhcnMobVN0cmluZywgTlVMTCk7CisgICAgICAgIGlmIChtQ2hhcnMgIT0gTlVMTCkgeworICAgICAgICAgICAgbVNpemUgPSBlbnYtPkdldFN0cmluZ0xlbmd0aChtU3RyaW5nKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIH5TY29wZWRTdHJpbmdDaGFycygpIHsKKyAgICAgICAgbUVudi0+UmVsZWFzZVN0cmluZ0NoYXJzKG1TdHJpbmcsIG1DaGFycyk7CisgICAgfQorCisgICAgY29uc3QgamNoYXIqIGdldCgpIGNvbnN0IHsgcmV0dXJuIG1DaGFyczsgfQorICAgIGNvbnN0IGpjaGFyJiBvcGVyYXRvcltdKHNpemVfdCBuKSBjb25zdCB7IHJldHVybiBtQ2hhcnNbbl07IH0KKyAgICBzaXplX3Qgc2l6ZSgpIGNvbnN0IHsgcmV0dXJuIG1TaXplOyB9CisKK3ByaXZhdGU6CisgICAgSk5JRW52KiBtRW52OworICAgIGpzdHJpbmcgbVN0cmluZzsKKyAgICBjb25zdCBqY2hhciogbUNoYXJzOworICAgIHNpemVfdCBtU2l6ZTsKKworICAgIC8vIERpc2FsbG93IGNvcHkgYW5kIGFzc2lnbm1lbnQuCisgICAgU2NvcGVkU3RyaW5nQ2hhcnMoY29uc3QgU2NvcGVkU3RyaW5nQ2hhcnMmKTsKKyAgICB2b2lkIG9wZXJhdG9yPShjb25zdCBTY29wZWRTdHJpbmdDaGFycyYpOworfTsKKworI2VuZGlmICAvLyBTQ09QRURfU1RSSU5HX0NIQVJTX0hfaW5jbHVkZWQKZGlmZiAtLWdpdCBhL2luY2x1ZGUvU2NvcGVkVXRmQ2hhcnMuaCBiL2luY2x1ZGUvU2NvcGVkVXRmQ2hhcnMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NDkyYTBjCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS9TY29wZWRVdGZDaGFycy5oCkBAIC0wLDAgKzEsNzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIFNDT1BFRF9VVEZfQ0hBUlNfSF9pbmNsdWRlZAorI2RlZmluZSBTQ09QRURfVVRGX0NIQVJTX0hfaW5jbHVkZWQKKworI2luY2x1ZGUgIkpOSUhlbHAuaCIKKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworLy8gQSBzbWFydCBwb2ludGVyIHRoYXQgcHJvdmlkZXMgcmVhZC1vbmx5IGFjY2VzcyB0byBhIEphdmEgc3RyaW5nJ3MgVVRGIGNoYXJzLgorLy8gVW5saWtlIEdldFN0cmluZ1VURkNoYXJzLCB3ZSB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiByYXRoZXIgdGhhbiBhYm9ydCBpZgorLy8gcGFzc2VkIGEgbnVsbCBqc3RyaW5nLCBhbmQgY19zdHIgd2lsbCByZXR1cm4gTlVMTC4KKy8vIFRoaXMgbWFrZXMgdGhlIGNvcnJlY3QgaWRpb20gdmVyeSBzaW1wbGU6CisvLworLy8gICBTY29wZWRVdGZDaGFycyBuYW1lKGVudiwgamF2YU5hbWUpOworLy8gICBpZiAobmFtZS5jX3N0cigpID09IE5VTEwpIHsKKy8vICAgICAgIHJldHVybiBOVUxMOworLy8gICB9CitjbGFzcyBTY29wZWRVdGZDaGFycyB7CitwdWJsaWM6CisgICAgU2NvcGVkVXRmQ2hhcnMoSk5JRW52KiBlbnYsIGpzdHJpbmcgcykKKyAgICA6IG1FbnYoZW52KSwgbVN0cmluZyhzKQorICAgIHsKKyAgICAgICAgaWYgKHMgPT0gTlVMTCkgeworICAgICAgICAgICAgbVV0ZkNoYXJzID0gTlVMTDsKKyAgICAgICAgICAgIGpuaVRocm93TnVsbFBvaW50ZXJFeGNlcHRpb24oZW52LCBOVUxMKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG1VdGZDaGFycyA9IGVudi0+R2V0U3RyaW5nVVRGQ2hhcnMocywgTlVMTCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICB+U2NvcGVkVXRmQ2hhcnMoKSB7CisgICAgICAgIGlmIChtVXRmQ2hhcnMpIHsKKyAgICAgICAgICAgIG1FbnYtPlJlbGVhc2VTdHJpbmdVVEZDaGFycyhtU3RyaW5nLCBtVXRmQ2hhcnMpOworICAgICAgICB9CisgICAgfQorCisgICAgY29uc3QgY2hhciogY19zdHIoKSBjb25zdCB7CisgICAgICAgIHJldHVybiBtVXRmQ2hhcnM7CisgICAgfQorCisgICAgc2l6ZV90IHNpemUoKSBjb25zdCB7CisgICAgICAgIHJldHVybiBzdHJsZW4obVV0ZkNoYXJzKTsKKyAgICB9CisKKyAgICAvLyBFbGVtZW50IGFjY2Vzcy4KKyAgICBjb25zdCBjaGFyJiBvcGVyYXRvcltdKHNpemVfdCBuKSBjb25zdCB7CisgICAgICAgIHJldHVybiBtVXRmQ2hhcnNbbl07CisgICAgfQorCitwcml2YXRlOgorICAgIEpOSUVudiogbUVudjsKKyAgICBqc3RyaW5nIG1TdHJpbmc7CisgICAgY29uc3QgY2hhciogbVV0ZkNoYXJzOworCisgICAgLy8gRGlzYWxsb3cgY29weSBhbmQgYXNzaWdubWVudC4KKyAgICBTY29wZWRVdGZDaGFycyhjb25zdCBTY29wZWRVdGZDaGFycyYpOworICAgIHZvaWQgb3BlcmF0b3I9KGNvbnN0IFNjb3BlZFV0ZkNoYXJzJik7Cit9OworCisjZW5kaWYgIC8vIFNDT1BFRF9VVEZfQ0hBUlNfSF9pbmNsdWRlZApkaWZmIC0tZ2l0IGEvaW5jbHVkZS9TdGF0aWNBc3NlcnQuaCBiL2luY2x1ZGUvU3RhdGljQXNzZXJ0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWI4MDliMwotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvU3RhdGljQXNzZXJ0LmgKQEAgLTAsMCArMSwyOCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgU1RBVElDX0FTU0VSVF9IX2luY2x1ZGVkCisjZGVmaW5lIFNUQVRJQ19BU1NFUlRfSF9pbmNsdWRlZAorCisvKioKKyAqIFNpbWlsYXIgdG8gQysrMHgncyBzdGF0aWNfYXNzZXJ0LiBNZXNzYWdlIGFyZ3VtZW50IG11c3QgYmUgYSB2YWxpZCBpZGVudGlmaWVyLCBub3QgYSBzdHJpbmcuCisgKiBDYWxsZWQgQ09NUElMRV9BU1NFUlQgaW4gR29vZ2xlLCBDT01QSUxFX1RJTUVfQVNTRVJUIGluIG90aGVyIHBsYWNlcy4gVGhpcyBpcyB0aGUgdXN1YWwgR29vZ2xlCisgKiBpbXBsZW1lbnRhdGlvbi4KKyAqLworI2RlZmluZSBTVEFUSUNfQVNTRVJUKGV4cCwgbXNnKSB0eXBlZGVmIFN0YXRpY0Fzc2VydDwoYm9vbChleHApKT4gbXNnW2Jvb2woZXhwKSA/IDEgOiAtMV0KK3RlbXBsYXRlIDxib29sPiBzdHJ1Y3QgU3RhdGljQXNzZXJ0IHt9OworCisjZW5kaWYgIC8vIFNUQVRJQ19BU1NFUlRfSF9pbmNsdWRlZApkaWZmIC0tZ2l0IGEvaW5jbHVkZS9VbmlxdWVQdHIuaCBiL2luY2x1ZGUvVW5pcXVlUHRyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzFkYjM3NwotLS0gL2Rldi9udWxsCisrKyBiL2luY2x1ZGUvVW5pcXVlUHRyLmgKQEAgLTAsMCArMSwyMzEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIFVOSVFVRV9QVFJfSF9pbmNsdWRlZAorI2RlZmluZSBVTklRVUVfUFRSX0hfaW5jbHVkZWQKKworI2luY2x1ZGUgPGNzdGRsaWI+IC8vIEZvciBOVUxMLgorCisvLyBEZWZhdWx0IGRlbGV0ZXIgZm9yIHBvaW50ZXIgdHlwZXMuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KK3N0cnVjdCBEZWZhdWx0RGVsZXRlIHsKKyAgICBlbnVtIHsgdHlwZV9tdXN0X2JlX2NvbXBsZXRlID0gc2l6ZW9mKFQpIH07CisgICAgRGVmYXVsdERlbGV0ZSgpIHt9CisgICAgdm9pZCBvcGVyYXRvcigpKFQqIHApIGNvbnN0IHsKKyAgICAgICAgZGVsZXRlIHA7CisgICAgfQorfTsKKworLy8gRGVmYXVsdCBkZWxldGVyIGZvciBhcnJheSB0eXBlcy4KK3RlbXBsYXRlIDx0eXBlbmFtZSBUPgorc3RydWN0IERlZmF1bHREZWxldGU8VFtdPiB7CisgICAgZW51bSB7IHR5cGVfbXVzdF9iZV9jb21wbGV0ZSA9IHNpemVvZihUKSB9OworICAgIHZvaWQgb3BlcmF0b3IoKShUKiBwKSBjb25zdCB7CisgICAgICAgIGRlbGV0ZVtdIHA7CisgICAgfQorfTsKKworLy8gQSBzbWFydCBwb2ludGVyIHRoYXQgZGVsZXRlcyB0aGUgZ2l2ZW4gcG9pbnRlciBvbiBkZXN0cnVjdGlvbi4KKy8vIEVxdWl2YWxlbnQgdG8gQysrMHgncyBzdGQ6OnVuaXF1ZV9wdHIgKGEgY29tYmluYXRpb24gb2YgYm9vc3Q6OnNjb3BlZF9wdHIKKy8vIGFuZCBib29zdDo6c2NvcGVkX2FycmF5KS4KKy8vIE5hbWVkIHRvIGJlIGluIGtlZXBpbmcgd2l0aCBBbmRyb2lkIHN0eWxlIGJ1dCBhbHNvIHRvIGF2b2lkCisvLyBjb2xsaXNpb24gd2l0aCBhbnkgb3RoZXIgaW1wbGVtZW50YXRpb24sIHVudGlsIHdlIGNhbiBzd2l0Y2ggb3ZlcgorLy8gdG8gdW5pcXVlX3B0ci4KKy8vIFVzZSB0aHVzOgorLy8gICBVbmlxdWVQdHI8Qz4gYyhuZXcgQyk7Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRCA9IERlZmF1bHREZWxldGU8VD4gPgorY2xhc3MgVW5pcXVlUHRyIHsKK3B1YmxpYzoKKyAgICAvLyBDb25zdHJ1Y3QgYSBuZXcgVW5pcXVlUHRyLCB0YWtpbmcgb3duZXJzaGlwIG9mIHRoZSBnaXZlbiByYXcgcG9pbnRlci4KKyAgICBleHBsaWNpdCBVbmlxdWVQdHIoVCogcHRyID0gTlVMTCkgOiBtUHRyKHB0cikgeworICAgIH0KKworICAgIH5VbmlxdWVQdHIoKSB7CisgICAgICAgIHJlc2V0KCk7CisgICAgfQorCisgICAgLy8gQWNjZXNzb3JzLgorICAgIFQmIG9wZXJhdG9yKigpIGNvbnN0IHsgcmV0dXJuICptUHRyOyB9CisgICAgVCogb3BlcmF0b3ItPigpIGNvbnN0IHsgcmV0dXJuIG1QdHI7IH0KKyAgICBUKiBnZXQoKSBjb25zdCB7IHJldHVybiBtUHRyOyB9CisKKyAgICAvLyBSZXR1cm5zIHRoZSByYXcgcG9pbnRlciBhbmQgaGFuZHMgb3ZlciBvd25lcnNoaXAgdG8gdGhlIGNhbGxlci4KKyAgICAvLyBUaGUgcG9pbnRlciB3aWxsIG5vdCBiZSBkZWxldGVkIGJ5IFVuaXF1ZVB0ci4KKyAgICBUKiByZWxlYXNlKCkgX19hdHRyaWJ1dGVfXygod2Fybl91bnVzZWRfcmVzdWx0KSkgeworICAgICAgICBUKiByZXN1bHQgPSBtUHRyOworICAgICAgICBtUHRyID0gTlVMTDsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvLyBUYWtlcyBvd25lcnNoaXAgb2YgdGhlIGdpdmVuIHJhdyBwb2ludGVyLgorICAgIC8vIElmIHRoaXMgc21hcnQgcG9pbnRlciBwcmV2aW91c2x5IG93bmVkIGEgZGlmZmVyZW50IHJhdyBwb2ludGVyLCB0aGF0CisgICAgLy8gcmF3IHBvaW50ZXIgd2lsbCBiZSBmcmVlZC4KKyAgICB2b2lkIHJlc2V0KFQqIHB0ciA9IE5VTEwpIHsKKyAgICAgICAgaWYgKHB0ciAhPSBtUHRyKSB7CisgICAgICAgICAgICBEKCkobVB0cik7CisgICAgICAgICAgICBtUHRyID0gcHRyOworICAgICAgICB9CisgICAgfQorCitwcml2YXRlOgorICAgIC8vIFRoZSByYXcgcG9pbnRlci4KKyAgICBUKiBtUHRyOworCisgICAgLy8gQ29tcGFyaW5nIHVuaXF1ZSBwb2ludGVycyBpcyBwcm9iYWJseSBhIG1pc3Rha2UsIHNpbmNlIHRoZXkncmUgdW5pcXVlLgorICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBUMj4gYm9vbCBvcGVyYXRvcj09KGNvbnN0IFVuaXF1ZVB0cjxUMj4mIHApIGNvbnN0OworICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBUMj4gYm9vbCBvcGVyYXRvciE9KGNvbnN0IFVuaXF1ZVB0cjxUMj4mIHApIGNvbnN0OworCisgICAgLy8gRGlzYWxsb3cgY29weSBhbmQgYXNzaWdubWVudC4KKyAgICBVbmlxdWVQdHIoY29uc3QgVW5pcXVlUHRyJik7CisgICAgdm9pZCBvcGVyYXRvcj0oY29uc3QgVW5pcXVlUHRyJik7Cit9OworCisvLyBQYXJ0aWFsIHNwZWNpYWxpemF0aW9uIGZvciBhcnJheSB0eXBlcy4gTGlrZSBzdGQ6OnVuaXF1ZV9wdHIsIHRoaXMgcmVtb3ZlcworLy8gb3BlcmF0b3IqIGFuZCBvcGVyYXRvci0+IGJ1dCBhZGRzIG9wZXJhdG9yW10uCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRD4KK2NsYXNzIFVuaXF1ZVB0cjxUW10sIEQ+IHsKK3B1YmxpYzoKKyAgICBleHBsaWNpdCBVbmlxdWVQdHIoVCogcHRyID0gTlVMTCkgOiBtUHRyKHB0cikgeworICAgIH0KKworICAgIH5VbmlxdWVQdHIoKSB7CisgICAgICAgIHJlc2V0KCk7CisgICAgfQorCisgICAgVCYgb3BlcmF0b3JbXShzaXplX3QgaSkgY29uc3QgeworICAgICAgICByZXR1cm4gbVB0cltpXTsKKyAgICB9CisgICAgVCogZ2V0KCkgY29uc3QgeyByZXR1cm4gbVB0cjsgfQorCisgICAgVCogcmVsZWFzZSgpIF9fYXR0cmlidXRlX18oKHdhcm5fdW51c2VkX3Jlc3VsdCkpIHsKKyAgICAgICAgVCogcmVzdWx0ID0gbVB0cjsKKyAgICAgICAgbVB0ciA9IE5VTEw7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgdm9pZCByZXNldChUKiBwdHIgPSBOVUxMKSB7CisgICAgICAgIGlmIChwdHIgIT0gbVB0cikgeworICAgICAgICAgICAgRCgpKG1QdHIpOworICAgICAgICAgICAgbVB0ciA9IHB0cjsKKyAgICAgICAgfQorICAgIH0KKworcHJpdmF0ZToKKyAgICBUKiBtUHRyOworCisgICAgLy8gRGlzYWxsb3cgY29weSBhbmQgYXNzaWdubWVudC4KKyAgICBVbmlxdWVQdHIoY29uc3QgVW5pcXVlUHRyJik7CisgICAgdm9pZCBvcGVyYXRvcj0oY29uc3QgVW5pcXVlUHRyJik7Cit9OworCisjaWYgVU5JUVVFX1BUUl9URVNUUworCisvLyBSdW4gdGhlc2UgdGVzdHMgd2l0aDoKKy8vIGcrKyAtZyAtRFVOSVFVRV9QVFJfVEVTVFMgLXggYysrIFVuaXF1ZVB0ci5oICYmIC4vYS5vdXQKKworI2luY2x1ZGUgPHN0ZGlvLmg+CisKK3N0YXRpYyB2b2lkIGFzc2VydChib29sIGIpIHsKKyAgICBpZiAoIWIpIHsKKyAgICAgICAgZnByaW50ZihzdGRlcnIsICJGQUlMXG4iKTsKKyAgICAgICAgYWJvcnQoKTsKKyAgICB9CisgICAgZnByaW50ZihzdGRlcnIsICJPS1xuIik7Cit9CitzdGF0aWMgaW50IGNDb3VudCA9IDA7CitzdHJ1Y3QgQyB7CisgICAgQygpIHsgKytjQ291bnQ7IH0KKyAgICB+QygpIHsgLS1jQ291bnQ7IH0KK307CitzdGF0aWMgYm9vbCBmcmVlZCA9IGZhbHNlOworc3RydWN0IEZyZWVyIHsKKyAgICB2b2lkIG9wZXJhdG9yKCkoaW50KiBwKSB7CisgICAgICAgIGFzc2VydCgqcCA9PSAxMjMpOworICAgICAgICBmcmVlKHApOworICAgICAgICBmcmVlZCA9IHRydWU7CisgICAgfQorfTsKKworaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqIGFyZ3ZbXSkgeworICAgIC8vCisgICAgLy8gVW5pcXVlUHRyPFQ+IHRlc3RzLi4uCisgICAgLy8KKworICAgIC8vIENhbiB3ZSBmcmVlIGEgc2luZ2xlIG9iamVjdD8KKyAgICB7CisgICAgICAgIFVuaXF1ZVB0cjxDPiBjKG5ldyBDKTsKKyAgICAgICAgYXNzZXJ0KGNDb3VudCA9PSAxKTsKKyAgICB9CisgICAgYXNzZXJ0KGNDb3VudCA9PSAwKTsKKyAgICAvLyBEb2VzIHJlbGVhc2Ugd29yaz8KKyAgICBDKiByYXdDOworICAgIHsKKyAgICAgICAgVW5pcXVlUHRyPEM+IGMobmV3IEMpOworICAgICAgICBhc3NlcnQoY0NvdW50ID09IDEpOworICAgICAgICByYXdDID0gYy5yZWxlYXNlKCk7CisgICAgfQorICAgIGFzc2VydChjQ291bnQgPT0gMSk7CisgICAgZGVsZXRlIHJhd0M7CisgICAgLy8gRG9lcyByZXNldCB3b3JrPworICAgIHsKKyAgICAgICAgVW5pcXVlUHRyPEM+IGMobmV3IEMpOworICAgICAgICBhc3NlcnQoY0NvdW50ID09IDEpOworICAgICAgICBjLnJlc2V0KG5ldyBDKTsKKyAgICAgICAgYXNzZXJ0KGNDb3VudCA9PSAxKTsKKyAgICB9CisgICAgYXNzZXJ0KGNDb3VudCA9PSAwKTsKKworICAgIC8vCisgICAgLy8gVW5pcXVlUHRyPFRbXT4gdGVzdHMuLi4KKyAgICAvLworCisgICAgLy8gQ2FuIHdlIGZyZWUgYW4gYXJyYXk/CisgICAgeworICAgICAgICBVbmlxdWVQdHI8Q1tdPiBjcyhuZXcgQ1s0XSk7CisgICAgICAgIGFzc2VydChjQ291bnQgPT0gNCk7CisgICAgfQorICAgIGFzc2VydChjQ291bnQgPT0gMCk7CisgICAgLy8gRG9lcyByZWxlYXNlIHdvcms/CisgICAgeworICAgICAgICBVbmlxdWVQdHI8Q1tdPiBjKG5ldyBDWzRdKTsKKyAgICAgICAgYXNzZXJ0KGNDb3VudCA9PSA0KTsKKyAgICAgICAgcmF3QyA9IGMucmVsZWFzZSgpOworICAgIH0KKyAgICBhc3NlcnQoY0NvdW50ID09IDQpOworICAgIGRlbGV0ZVtdIHJhd0M7CisgICAgLy8gRG9lcyByZXNldCB3b3JrPworICAgIHsKKyAgICAgICAgVW5pcXVlUHRyPENbXT4gYyhuZXcgQ1s0XSk7CisgICAgICAgIGFzc2VydChjQ291bnQgPT0gNCk7CisgICAgICAgIGMucmVzZXQobmV3IENbMl0pOworICAgICAgICBhc3NlcnQoY0NvdW50ID09IDIpOworICAgIH0KKyAgICBhc3NlcnQoY0NvdW50ID09IDApOworCisgICAgLy8KKyAgICAvLyBDdXN0b20gZGVsZXRlciB0ZXN0cy4uLgorICAgIC8vCisgICAgYXNzZXJ0KCFmcmVlZCk7CisgICAgeworICAgICAgICBVbmlxdWVQdHI8aW50LCBGcmVlcj4gaShyZWludGVycHJldF9jYXN0PGludCo+KG1hbGxvYyhzaXplb2YoaW50KSkpKTsKKyAgICAgICAgKmkgPSAxMjM7CisgICAgfQorICAgIGFzc2VydChmcmVlZCk7CisgICAgcmV0dXJuIDA7Cit9CisjZW5kaWYKKworI2VuZGlmICAvLyBVTklRVUVfUFRSX0hfaW5jbHVkZWQKZGlmZiAtLWdpdCBhL2pzb24vTU9EVUxFX0xJQ0VOU0VfQlNEX0xJS0UgYi9qc29uL01PRFVMRV9MSUNFTlNFX0JTRF9MSUtFCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2OWRlMjkKLS0tIC9kZXYvbnVsbAorKysgYi9qc29uL01PRFVMRV9MSUNFTlNFX0JTRF9MSUtFCmRpZmYgLS1naXQgYS9qc29uL3NyYy9tYWluL2phdmEvb3JnL2pzb24vSlNPTi5qYXZhIGIvanNvbi9zcmMvbWFpbi9qYXZhL29yZy9qc29uL0pTT04uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYjMyZTY5Ci0tLSAvZGV2L251bGwKKysrIGIvanNvbi9zcmMvbWFpbi9qYXZhL29yZy9qc29uL0pTT04uamF2YQpAQCAtMCwwICsxLDExNiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmpzb247CisKK2NsYXNzIEpTT04geworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGlucHV0IGlmIGl0IGlzIGEgSlNPTi1wZXJtaXNzaWJsZSB2YWx1ZTsgdGhyb3dzIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgZG91YmxlIGNoZWNrRG91YmxlKGRvdWJsZSBkKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChEb3VibGUuaXNJbmZpbml0ZShkKSB8fCBEb3VibGUuaXNOYU4oZCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBKU09ORXhjZXB0aW9uKCJGb3JiaWRkZW4gbnVtZXJpYyB2YWx1ZTogIiArIGQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkOworICAgIH0KKworICAgIHN0YXRpYyBCb29sZWFuIHRvQm9vbGVhbihPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQm9vbGVhbikgeworICAgICAgICAgICAgcmV0dXJuIChCb29sZWFuKSB2YWx1ZTsKKyAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykgeworICAgICAgICAgICAgU3RyaW5nIHN0cmluZ1ZhbHVlID0gKFN0cmluZykgdmFsdWU7CisgICAgICAgICAgICBpZiAoInRydWUiLmVxdWFsc0lnbm9yZUNhc2Uoc3RyaW5nVmFsdWUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9IGVsc2UgaWYgKCJmYWxzZSIuZXF1YWxzSWdub3JlQ2FzZShzdHJpbmdWYWx1ZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgc3RhdGljIERvdWJsZSB0b0RvdWJsZShPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRG91YmxlKSB7CisgICAgICAgICAgICByZXR1cm4gKERvdWJsZSkgdmFsdWU7CisgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBOdW1iZXIpIHsKKyAgICAgICAgICAgIHJldHVybiAoKE51bWJlcikgdmFsdWUpLmRvdWJsZVZhbHVlKCk7CisgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIERvdWJsZS52YWx1ZU9mKChTdHJpbmcpIHZhbHVlKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgc3RhdGljIEludGVnZXIgdG9JbnRlZ2VyKE9iamVjdCB2YWx1ZSkgeworICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBJbnRlZ2VyKSB7CisgICAgICAgICAgICByZXR1cm4gKEludGVnZXIpIHZhbHVlOworICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgTnVtYmVyKSB7CisgICAgICAgICAgICByZXR1cm4gKChOdW1iZXIpIHZhbHVlKS5pbnRWYWx1ZSgpOworICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiAoaW50KSBEb3VibGUucGFyc2VEb3VibGUoKFN0cmluZykgdmFsdWUpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBzdGF0aWMgTG9uZyB0b0xvbmcoT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExvbmcpIHsKKyAgICAgICAgICAgIHJldHVybiAoTG9uZykgdmFsdWU7CisgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBOdW1iZXIpIHsKKyAgICAgICAgICAgIHJldHVybiAoKE51bWJlcikgdmFsdWUpLmxvbmdWYWx1ZSgpOworICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiAobG9uZykgRG91YmxlLnBhcnNlRG91YmxlKChTdHJpbmcpIHZhbHVlKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgc3RhdGljIFN0cmluZyB0b1N0cmluZyhPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKSB7CisgICAgICAgICAgICByZXR1cm4gKFN0cmluZykgdmFsdWU7CisgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIFN0cmluZy52YWx1ZU9mKHZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIEpTT05FeGNlcHRpb24gdHlwZU1pc21hdGNoKE9iamVjdCBpbmRleE9yTmFtZSwgT2JqZWN0IGFjdHVhbCwKKyAgICAgICAgICAgIFN0cmluZyByZXF1aXJlZFR5cGUpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFjdHVhbCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSlNPTkV4Y2VwdGlvbigiVmFsdWUgYXQgIiArIGluZGV4T3JOYW1lICsgIiBpcyBudWxsLiIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IEpTT05FeGNlcHRpb24oIlZhbHVlICIgKyBhY3R1YWwgKyAiIGF0ICIgKyBpbmRleE9yTmFtZQorICAgICAgICAgICAgICAgICAgICArICIgb2YgdHlwZSAiICsgYWN0dWFsLmdldENsYXNzKCkuZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgICAgICsgIiBjYW5ub3QgYmUgY29udmVydGVkIHRvICIgKyByZXF1aXJlZFR5cGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBKU09ORXhjZXB0aW9uIHR5cGVNaXNtYXRjaChPYmplY3QgYWN0dWFsLCBTdHJpbmcgcmVxdWlyZWRUeXBlKQorICAgICAgICAgICAgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBpZiAoYWN0dWFsID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBKU09ORXhjZXB0aW9uKCJWYWx1ZSBpcyBudWxsLiIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IEpTT05FeGNlcHRpb24oIlZhbHVlICIgKyBhY3R1YWwKKyAgICAgICAgICAgICAgICAgICAgKyAiIG9mIHR5cGUgIiArIGFjdHVhbC5nZXRDbGFzcygpLmdldE5hbWUoKQorICAgICAgICAgICAgICAgICAgICArICIgY2Fubm90IGJlIGNvbnZlcnRlZCB0byAiICsgcmVxdWlyZWRUeXBlKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2pzb24vc3JjL21haW4vamF2YS9vcmcvanNvbi9KU09OQXJyYXkuamF2YSBiL2pzb24vc3JjL21haW4vamF2YS9vcmcvanNvbi9KU09OQXJyYXkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hODg1MTI1Ci0tLSAvZGV2L251bGwKKysrIGIvanNvbi9zcmMvbWFpbi9qYXZhL29yZy9qc29uL0pTT05BcnJheS5qYXZhCkBAIC0wLDAgKzEsNTg1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuanNvbjsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8vIE5vdGU6IHRoaXMgY2xhc3Mgd2FzIHdyaXR0ZW4gd2l0aG91dCBpbnNwZWN0aW5nIHRoZSBub24tZnJlZSBvcmcuanNvbiBzb3VyY2Vjb2RlLgorCisvKioKKyAqIEEgZGVuc2UgaW5kZXhlZCBzZXF1ZW5jZSBvZiB2YWx1ZXMuIFZhbHVlcyBtYXkgYmUgYW55IG1peCBvZgorICoge0BsaW5rIEpTT05PYmplY3QgSlNPTk9iamVjdHN9LCBvdGhlciB7QGxpbmsgSlNPTkFycmF5IEpTT05BcnJheXN9LCBTdHJpbmdzLAorICogQm9vbGVhbnMsIEludGVnZXJzLCBMb25ncywgRG91Ymxlcywge0Bjb2RlIG51bGx9IG9yIHtAbGluayBKU09OT2JqZWN0I05VTEx9LgorICogVmFsdWVzIG1heSBub3QgYmUge0BsaW5rIERvdWJsZSNpc05hTigpIE5hTnN9LCB7QGxpbmsgRG91YmxlI2lzSW5maW5pdGUoKQorICogaW5maW5pdGllc30sIG9yIG9mIGFueSB0eXBlIG5vdCBsaXN0ZWQgaGVyZS4KKyAqCisgKiA8cD57QGNvZGUgSlNPTkFycmF5fSBoYXMgdGhlIHNhbWUgdHlwZSBjb2VyY2lvbiBiZWhhdmlvciBhbmQKKyAqIG9wdGlvbmFsL21hbmRhdG9yeSBhY2Nlc3NvcnMgYXMge0BsaW5rIEpTT05PYmplY3R9LiBTZWUgdGhhdCBjbGFzcycKKyAqIGRvY3VtZW50YXRpb24gZm9yIGRldGFpbHMuCisgKgorICogPHA+PHN0cm9uZz5XYXJuaW5nOjwvc3Ryb25nPiB0aGlzIGNsYXNzIHJlcHJlc2VudHMgbnVsbCBpbiB0d28gaW5jb21wYXRpYmxlCisgKiB3YXlzOiB0aGUgc3RhbmRhcmQgSmF2YSB7QGNvZGUgbnVsbH0gcmVmZXJlbmNlLCBhbmQgdGhlIHNlbnRpbmVsIHZhbHVlIHtAbGluaworICogSlNPTk9iamVjdCNOVUxMfS4gSW4gcGFydGljdWxhciwge0Bjb2RlIGdldH0gZmFpbHMgaWYgdGhlIHJlcXVlc3RlZCBpbmRleAorICogaG9sZHMgdGhlIG51bGwgcmVmZXJlbmNlLCBidXQgc3VjY2VlZHMgaWYgaXQgaG9sZHMge0Bjb2RlIEpTT05PYmplY3QuTlVMTH0uCisgKgorICogPHA+SW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgYXJlIG5vdCB0aHJlYWQgc2FmZS4gQWx0aG91Z2ggdGhpcyBjbGFzcyBpcworICogbm9uZmluYWwsIGl0IHdhcyBub3QgZGVzaWduZWQgZm9yIGluaGVyaXRhbmNlIGFuZCBzaG91bGQgbm90IGJlIHN1YmNsYXNzZWQuCisgKiBJbiBwYXJ0aWN1bGFyLCBzZWxmLXVzZSBieSBvdmVycmlkYWJsZSBtZXRob2RzIGlzIG5vdCBzcGVjaWZpZWQuIFNlZQorICogPGk+RWZmZWN0aXZlIEphdmE8L2k+IEl0ZW0gMTcsICJEZXNpZ24gYW5kIERvY3VtZW50IG9yIGluaGVyaXRhbmNlIG9yIGVsc2UKKyAqIHByb2hpYml0IGl0IiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KKyAqLworcHVibGljIGNsYXNzIEpTT05BcnJheSB7CisKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8T2JqZWN0PiB2YWx1ZXM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIEpTT05BcnJheX0gd2l0aCBubyB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIEpTT05BcnJheSgpIHsKKyAgICAgICAgdmFsdWVzID0gbmV3IEFycmF5TGlzdDxPYmplY3Q+KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgSlNPTkFycmF5fSBieSBjb3B5aW5nIGFsbCB2YWx1ZXMgZnJvbSB0aGUgZ2l2ZW4KKyAgICAgKiBjb2xsZWN0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGNvcHlGcm9tIGEgY29sbGVjdGlvbiB3aG9zZSB2YWx1ZXMgYXJlIG9mIHN1cHBvcnRlZCB0eXBlcy4KKyAgICAgKiAgICAgVW5zdXBwb3J0ZWQgdmFsdWVzIGFyZSBub3QgcGVybWl0dGVkIGFuZCB3aWxsIHlpZWxkIGFuIGFycmF5IGluIGFuCisgICAgICogICAgIGluY29uc2lzdGVudCBzdGF0ZS4KKyAgICAgKi8KKyAgICAvKiBBY2NlcHQgYSByYXcgdHlwZSBmb3IgQVBJIGNvbXBhdGliaWxpdHkgKi8KKyAgICBwdWJsaWMgSlNPTkFycmF5KENvbGxlY3Rpb24gY29weUZyb20pIHsKKyAgICAgICAgdGhpcygpOworICAgICAgICBDb2xsZWN0aW9uPD8+IGNvcHlGcm9tVHlwZWQgPSAoQ29sbGVjdGlvbjw/PikgY29weUZyb207CisgICAgICAgIHZhbHVlcy5hZGRBbGwoY29weUZyb21UeXBlZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgSlNPTkFycmF5fSB3aXRoIHZhbHVlcyBmcm9tIHRoZSBuZXh0IGFycmF5IGluIHRoZQorICAgICAqIHRva2VuZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhZEZyb20gYSB0b2tlbmVyIHdob3NlIG5leHRWYWx1ZSgpIG1ldGhvZCB3aWxsIHlpZWxkIGEKKyAgICAgKiAgICAge0Bjb2RlIEpTT05BcnJheX0uCisgICAgICogQHRocm93cyBKU09ORXhjZXB0aW9uIGlmIHRoZSBwYXJzZSBmYWlscyBvciBkb2Vzbid0IHlpZWxkIGEKKyAgICAgKiAgICAge0Bjb2RlIEpTT05BcnJheX0uCisgICAgICovCisgICAgcHVibGljIEpTT05BcnJheShKU09OVG9rZW5lciByZWFkRnJvbSkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICAvKgorICAgICAgICAgKiBHZXR0aW5nIHRoZSBwYXJzZXIgdG8gcG9wdWxhdGUgdGhpcyBjb3VsZCBnZXQgdHJpY2t5LiBJbnN0ZWFkLCBqdXN0CisgICAgICAgICAqIHBhcnNlIHRvIHRlbXBvcmFyeSBKU09OQXJyYXkgYW5kIHRoZW4gc3RlYWwgdGhlIGRhdGEgZnJvbSB0aGF0LgorICAgICAgICAgKi8KKyAgICAgICAgT2JqZWN0IG9iamVjdCA9IHJlYWRGcm9tLm5leHRWYWx1ZSgpOworICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgSlNPTkFycmF5KSB7CisgICAgICAgICAgICB2YWx1ZXMgPSAoKEpTT05BcnJheSkgb2JqZWN0KS52YWx1ZXM7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBKU09OLnR5cGVNaXNtYXRjaChvYmplY3QsICJKU09OQXJyYXkiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEpTT05BcnJheX0gd2l0aCB2YWx1ZXMgZnJvbSB0aGUgSlNPTiBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0ganNvbiBhIEpTT04tZW5jb2RlZCBzdHJpbmcgY29udGFpbmluZyBhbiBhcnJheS4KKyAgICAgKiBAdGhyb3dzIEpTT05FeGNlcHRpb24gaWYgdGhlIHBhcnNlIGZhaWxzIG9yIGRvZXNuJ3QgeWllbGQgYSB7QGNvZGUKKyAgICAgKiAgICAgSlNPTkFycmF5fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTkFycmF5KFN0cmluZyBqc29uKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMobmV3IEpTT05Ub2tlbmVyKGpzb24pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgdmFsdWVzIGluIHRoaXMgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIGludCBsZW5ndGgoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZXMuc2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMge0Bjb2RlIHZhbHVlfSB0byB0aGUgZW5kIG9mIHRoaXMgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIEpTT05BcnJheSBwdXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICB2YWx1ZXMuYWRkKHZhbHVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyB7QGNvZGUgdmFsdWV9IHRvIHRoZSBlbmQgb2YgdGhpcyBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZSBhIGZpbml0ZSB2YWx1ZS4gTWF5IG5vdCBiZSB7QGxpbmsgRG91YmxlI2lzTmFOKCkgTmFOc30gb3IKKyAgICAgKiAgICAge0BsaW5rIERvdWJsZSNpc0luZmluaXRlKCkgaW5maW5pdGllc30uCisgICAgICogQHJldHVybiB0aGlzIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyBKU09OQXJyYXkgcHV0KGRvdWJsZSB2YWx1ZSkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICB2YWx1ZXMuYWRkKEpTT04uY2hlY2tEb3VibGUodmFsdWUpKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyB7QGNvZGUgdmFsdWV9IHRvIHRoZSBlbmQgb2YgdGhpcyBhcnJheS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTkFycmF5IHB1dChpbnQgdmFsdWUpIHsKKyAgICAgICAgdmFsdWVzLmFkZCh2YWx1ZSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMge0Bjb2RlIHZhbHVlfSB0byB0aGUgZW5kIG9mIHRoaXMgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIEpTT05BcnJheSBwdXQobG9uZyB2YWx1ZSkgeworICAgICAgICB2YWx1ZXMuYWRkKHZhbHVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyB7QGNvZGUgdmFsdWV9IHRvIHRoZSBlbmQgb2YgdGhpcyBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZSBhIHtAbGluayBKU09OT2JqZWN0fSwge0BsaW5rIEpTT05BcnJheX0sIFN0cmluZywgQm9vbGVhbiwKKyAgICAgKiAgICAgSW50ZWdlciwgTG9uZywgRG91YmxlLCB7QGxpbmsgSlNPTk9iamVjdCNOVUxMfSwgb3Ige0Bjb2RlIG51bGx9LiBNYXkKKyAgICAgKiAgICAgbm90IGJlIHtAbGluayBEb3VibGUjaXNOYU4oKSBOYU5zfSBvciB7QGxpbmsgRG91YmxlI2lzSW5maW5pdGUoKQorICAgICAqICAgICBpbmZpbml0aWVzfS4gVW5zdXBwb3J0ZWQgdmFsdWVzIGFyZSBub3QgcGVybWl0dGVkIGFuZCB3aWxsIGNhdXNlIHRoZQorICAgICAqICAgICBhcnJheSB0byBiZSBpbiBhbiBpbmNvbnNpc3RlbnQgc3RhdGUuCisgICAgICogQHJldHVybiB0aGlzIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyBKU09OQXJyYXkgcHV0KE9iamVjdCB2YWx1ZSkgeworICAgICAgICB2YWx1ZXMuYWRkKHZhbHVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgYXQge0Bjb2RlIGluZGV4fSB0byB7QGNvZGUgdmFsdWV9LCBudWxsIHBhZGRpbmcgdGhpcyBhcnJheQorICAgICAqIHRvIHRoZSByZXF1aXJlZCBsZW5ndGggaWYgbmVjZXNzYXJ5LiBJZiBhIHZhbHVlIGFscmVhZHkgZXhpc3RzIGF0IHtAY29kZQorICAgICAqIGluZGV4fSwgaXQgd2lsbCBiZSByZXBsYWNlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTkFycmF5IHB1dChpbnQgaW5kZXgsIGJvb2xlYW4gdmFsdWUpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHB1dChpbmRleCwgKEJvb2xlYW4pIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBhdCB7QGNvZGUgaW5kZXh9IHRvIHtAY29kZSB2YWx1ZX0sIG51bGwgcGFkZGluZyB0aGlzIGFycmF5CisgICAgICogdG8gdGhlIHJlcXVpcmVkIGxlbmd0aCBpZiBuZWNlc3NhcnkuIElmIGEgdmFsdWUgYWxyZWFkeSBleGlzdHMgYXQge0Bjb2RlCisgICAgICogaW5kZXh9LCBpdCB3aWxsIGJlIHJlcGxhY2VkLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlIGEgZmluaXRlIHZhbHVlLiBNYXkgbm90IGJlIHtAbGluayBEb3VibGUjaXNOYU4oKSBOYU5zfSBvcgorICAgICAqICAgICB7QGxpbmsgRG91YmxlI2lzSW5maW5pdGUoKSBpbmZpbml0aWVzfS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIEpTT05BcnJheSBwdXQoaW50IGluZGV4LCBkb3VibGUgdmFsdWUpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHB1dChpbmRleCwgKERvdWJsZSkgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIGF0IHtAY29kZSBpbmRleH0gdG8ge0Bjb2RlIHZhbHVlfSwgbnVsbCBwYWRkaW5nIHRoaXMgYXJyYXkKKyAgICAgKiB0byB0aGUgcmVxdWlyZWQgbGVuZ3RoIGlmIG5lY2Vzc2FyeS4gSWYgYSB2YWx1ZSBhbHJlYWR5IGV4aXN0cyBhdCB7QGNvZGUKKyAgICAgKiBpbmRleH0sIGl0IHdpbGwgYmUgcmVwbGFjZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIEpTT05BcnJheSBwdXQoaW50IGluZGV4LCBpbnQgdmFsdWUpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHB1dChpbmRleCwgKEludGVnZXIpIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBhdCB7QGNvZGUgaW5kZXh9IHRvIHtAY29kZSB2YWx1ZX0sIG51bGwgcGFkZGluZyB0aGlzIGFycmF5CisgICAgICogdG8gdGhlIHJlcXVpcmVkIGxlbmd0aCBpZiBuZWNlc3NhcnkuIElmIGEgdmFsdWUgYWxyZWFkeSBleGlzdHMgYXQge0Bjb2RlCisgICAgICogaW5kZXh9LCBpdCB3aWxsIGJlIHJlcGxhY2VkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyBKU09OQXJyYXkgcHV0KGludCBpbmRleCwgbG9uZyB2YWx1ZSkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcHV0KGluZGV4LCAoTG9uZykgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIGF0IHtAY29kZSBpbmRleH0gdG8ge0Bjb2RlIHZhbHVlfSwgbnVsbCBwYWRkaW5nIHRoaXMgYXJyYXkKKyAgICAgKiB0byB0aGUgcmVxdWlyZWQgbGVuZ3RoIGlmIG5lY2Vzc2FyeS4gSWYgYSB2YWx1ZSBhbHJlYWR5IGV4aXN0cyBhdCB7QGNvZGUKKyAgICAgKiBpbmRleH0sIGl0IHdpbGwgYmUgcmVwbGFjZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUgYSB7QGxpbmsgSlNPTk9iamVjdH0sIHtAbGluayBKU09OQXJyYXl9LCBTdHJpbmcsIEJvb2xlYW4sCisgICAgICogICAgIEludGVnZXIsIExvbmcsIERvdWJsZSwge0BsaW5rIEpTT05PYmplY3QjTlVMTH0sIG9yIHtAY29kZSBudWxsfS4gTWF5CisgICAgICogICAgIG5vdCBiZSB7QGxpbmsgRG91YmxlI2lzTmFOKCkgTmFOc30gb3Ige0BsaW5rIERvdWJsZSNpc0luZmluaXRlKCkKKyAgICAgKiAgICAgaW5maW5pdGllc30uCisgICAgICogQHJldHVybiB0aGlzIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyBKU09OQXJyYXkgcHV0KGludCBpbmRleCwgT2JqZWN0IHZhbHVlKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIE51bWJlcikgeworICAgICAgICAgICAgLy8gZGV2aWF0ZSBmcm9tIHRoZSBvcmlnaW5hbCBieSBjaGVja2luZyBhbGwgTnVtYmVycywgbm90IGp1c3QgZmxvYXRzICYgZG91YmxlcworICAgICAgICAgICAgSlNPTi5jaGVja0RvdWJsZSgoKE51bWJlcikgdmFsdWUpLmRvdWJsZVZhbHVlKCkpOworICAgICAgICB9CisgICAgICAgIHdoaWxlICh2YWx1ZXMuc2l6ZSgpIDw9IGluZGV4KSB7CisgICAgICAgICAgICB2YWx1ZXMuYWRkKG51bGwpOworICAgICAgICB9CisgICAgICAgIHZhbHVlcy5zZXQoaW5kZXgsIHZhbHVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgYXJyYXkgaGFzIG5vIHZhbHVlIGF0IHtAY29kZSBpbmRleH0sIG9yIGlmIGl0cyB2YWx1ZQorICAgICAqIGlzIHRoZSB7QGNvZGUgbnVsbH0gcmVmZXJlbmNlIG9yIHtAbGluayBKU09OT2JqZWN0I05VTEx9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzTnVsbChpbnQgaW5kZXgpIHsKKyAgICAgICAgT2JqZWN0IHZhbHVlID0gb3B0KGluZGV4KTsKKyAgICAgICAgcmV0dXJuIHZhbHVlID09IG51bGwgfHwgdmFsdWUgPT0gSlNPTk9iamVjdC5OVUxMOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIGF0IHtAY29kZSBpbmRleH0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEpTT05FeGNlcHRpb24gaWYgdGhpcyBhcnJheSBoYXMgbm8gdmFsdWUgYXQge0Bjb2RlIGluZGV4fSwgb3IgaWYKKyAgICAgKiAgICAgdGhhdCB2YWx1ZSBpcyB0aGUge0Bjb2RlIG51bGx9IHJlZmVyZW5jZS4gVGhpcyBtZXRob2QgcmV0dXJucworICAgICAqICAgICBub3JtYWxseSBpZiB0aGUgdmFsdWUgaXMge0Bjb2RlIEpTT05PYmplY3QjTlVMTH0uCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXQoaW50IGluZGV4KSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBPYmplY3QgdmFsdWUgPSB2YWx1ZXMuZ2V0KGluZGV4KTsKKyAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEpTT05FeGNlcHRpb24oIlZhbHVlIGF0ICIgKyBpbmRleCArICIgaXMgbnVsbC4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSlNPTkV4Y2VwdGlvbigiSW5kZXggIiArIGluZGV4ICsgIiBvdXQgb2YgcmFuZ2UgWzAuLiIgKyB2YWx1ZXMuc2l6ZSgpICsgIikiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIGF0IHtAY29kZSBpbmRleH0sIG9yIG51bGwgaWYgdGhlIGFycmF5IGhhcyBubyB2YWx1ZQorICAgICAqIGF0IHtAY29kZSBpbmRleH0uCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBvcHQoaW50IGluZGV4KSB7CisgICAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gdmFsdWVzLnNpemUoKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHZhbHVlcy5nZXQoaW5kZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIGF0IHtAY29kZSBpbmRleH0gaWYgaXQgZXhpc3RzIGFuZCBpcyBhIGJvb2xlYW4gb3IgY2FuCisgICAgICogYmUgY29lcmNlZCB0byBhIGJvb2xlYW4uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEpTT05FeGNlcHRpb24gaWYgdGhlIHZhbHVlIGF0IHtAY29kZSBpbmRleH0gZG9lc24ndCBleGlzdCBvcgorICAgICAqICAgICBjYW5ub3QgYmUgY29lcmNlZCB0byBhIGJvb2xlYW4uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0Qm9vbGVhbihpbnQgaW5kZXgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0IG9iamVjdCA9IGdldChpbmRleCk7CisgICAgICAgIEJvb2xlYW4gcmVzdWx0ID0gSlNPTi50b0Jvb2xlYW4ob2JqZWN0KTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBKU09OLnR5cGVNaXNtYXRjaChpbmRleCwgb2JqZWN0LCAiYm9vbGVhbiIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgYXQge0Bjb2RlIGluZGV4fSBpZiBpdCBleGlzdHMgYW5kIGlzIGEgYm9vbGVhbiBvciBjYW4KKyAgICAgKiBiZSBjb2VyY2VkIHRvIGEgYm9vbGVhbi4gUmV0dXJucyBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gb3B0Qm9vbGVhbihpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIG9wdEJvb2xlYW4oaW5kZXgsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBhdCB7QGNvZGUgaW5kZXh9IGlmIGl0IGV4aXN0cyBhbmQgaXMgYSBib29sZWFuIG9yIGNhbgorICAgICAqIGJlIGNvZXJjZWQgdG8gYSBib29sZWFuLiBSZXR1cm5zIHtAY29kZSBmYWxsYmFja30gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG9wdEJvb2xlYW4oaW50IGluZGV4LCBib29sZWFuIGZhbGxiYWNrKSB7CisgICAgICAgIE9iamVjdCBvYmplY3QgPSBvcHQoaW5kZXgpOworICAgICAgICBCb29sZWFuIHJlc3VsdCA9IEpTT04udG9Cb29sZWFuKG9iamVjdCk7CisgICAgICAgIHJldHVybiByZXN1bHQgIT0gbnVsbCA/IHJlc3VsdCA6IGZhbGxiYWNrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIGF0IHtAY29kZSBpbmRleH0gaWYgaXQgZXhpc3RzIGFuZCBpcyBhIGRvdWJsZSBvciBjYW4KKyAgICAgKiBiZSBjb2VyY2VkIHRvIGEgZG91YmxlLgorICAgICAqCisgICAgICogQHRocm93cyBKU09ORXhjZXB0aW9uIGlmIHRoZSB2YWx1ZSBhdCB7QGNvZGUgaW5kZXh9IGRvZXNuJ3QgZXhpc3Qgb3IKKyAgICAgKiAgICAgY2Fubm90IGJlIGNvZXJjZWQgdG8gYSBkb3VibGUuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBnZXREb3VibGUoaW50IGluZGV4KSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdCBvYmplY3QgPSBnZXQoaW5kZXgpOworICAgICAgICBEb3VibGUgcmVzdWx0ID0gSlNPTi50b0RvdWJsZShvYmplY3QpOworICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IEpTT04udHlwZU1pc21hdGNoKGluZGV4LCBvYmplY3QsICJkb3VibGUiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIGF0IHtAY29kZSBpbmRleH0gaWYgaXQgZXhpc3RzIGFuZCBpcyBhIGRvdWJsZSBvciBjYW4KKyAgICAgKiBiZSBjb2VyY2VkIHRvIGEgZG91YmxlLiBSZXR1cm5zIHtAY29kZSBOYU59IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIG9wdERvdWJsZShpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIG9wdERvdWJsZShpbmRleCwgRG91YmxlLk5hTik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgYXQge0Bjb2RlIGluZGV4fSBpZiBpdCBleGlzdHMgYW5kIGlzIGEgZG91YmxlIG9yIGNhbgorICAgICAqIGJlIGNvZXJjZWQgdG8gYSBkb3VibGUuIFJldHVybnMge0Bjb2RlIGZhbGxiYWNrfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBvcHREb3VibGUoaW50IGluZGV4LCBkb3VibGUgZmFsbGJhY2spIHsKKyAgICAgICAgT2JqZWN0IG9iamVjdCA9IG9wdChpbmRleCk7CisgICAgICAgIERvdWJsZSByZXN1bHQgPSBKU09OLnRvRG91YmxlKG9iamVjdCk7CisgICAgICAgIHJldHVybiByZXN1bHQgIT0gbnVsbCA/IHJlc3VsdCA6IGZhbGxiYWNrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIGF0IHtAY29kZSBpbmRleH0gaWYgaXQgZXhpc3RzIGFuZCBpcyBhbiBpbnQgb3IKKyAgICAgKiBjYW4gYmUgY29lcmNlZCB0byBhbiBpbnQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEpTT05FeGNlcHRpb24gaWYgdGhlIHZhbHVlIGF0IHtAY29kZSBpbmRleH0gZG9lc24ndCBleGlzdCBvcgorICAgICAqICAgICBjYW5ub3QgYmUgY29lcmNlZCB0byBhIGludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEludChpbnQgaW5kZXgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0IG9iamVjdCA9IGdldChpbmRleCk7CisgICAgICAgIEludGVnZXIgcmVzdWx0ID0gSlNPTi50b0ludGVnZXIob2JqZWN0KTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBKU09OLnR5cGVNaXNtYXRjaChpbmRleCwgb2JqZWN0LCAiaW50Iik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBhdCB7QGNvZGUgaW5kZXh9IGlmIGl0IGV4aXN0cyBhbmQgaXMgYW4gaW50IG9yCisgICAgICogY2FuIGJlIGNvZXJjZWQgdG8gYW4gaW50LiBSZXR1cm5zIDAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgb3B0SW50KGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gb3B0SW50KGluZGV4LCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBhdCB7QGNvZGUgaW5kZXh9IGlmIGl0IGV4aXN0cyBhbmQgaXMgYW4gaW50IG9yCisgICAgICogY2FuIGJlIGNvZXJjZWQgdG8gYW4gaW50LiBSZXR1cm5zIHtAY29kZSBmYWxsYmFja30gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgb3B0SW50KGludCBpbmRleCwgaW50IGZhbGxiYWNrKSB7CisgICAgICAgIE9iamVjdCBvYmplY3QgPSBvcHQoaW5kZXgpOworICAgICAgICBJbnRlZ2VyIHJlc3VsdCA9IEpTT04udG9JbnRlZ2VyKG9iamVjdCk7CisgICAgICAgIHJldHVybiByZXN1bHQgIT0gbnVsbCA/IHJlc3VsdCA6IGZhbGxiYWNrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIGF0IHtAY29kZSBpbmRleH0gaWYgaXQgZXhpc3RzIGFuZCBpcyBhIGxvbmcgb3IKKyAgICAgKiBjYW4gYmUgY29lcmNlZCB0byBhIGxvbmcuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEpTT05FeGNlcHRpb24gaWYgdGhlIHZhbHVlIGF0IHtAY29kZSBpbmRleH0gZG9lc24ndCBleGlzdCBvcgorICAgICAqICAgICBjYW5ub3QgYmUgY29lcmNlZCB0byBhIGxvbmcuCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0TG9uZyhpbnQgaW5kZXgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0IG9iamVjdCA9IGdldChpbmRleCk7CisgICAgICAgIExvbmcgcmVzdWx0ID0gSlNPTi50b0xvbmcob2JqZWN0KTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBKU09OLnR5cGVNaXNtYXRjaChpbmRleCwgb2JqZWN0LCAibG9uZyIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgYXQge0Bjb2RlIGluZGV4fSBpZiBpdCBleGlzdHMgYW5kIGlzIGEgbG9uZyBvcgorICAgICAqIGNhbiBiZSBjb2VyY2VkIHRvIGEgbG9uZy4gUmV0dXJucyAwIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBvcHRMb25nKGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gb3B0TG9uZyhpbmRleCwgMEwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIGF0IHtAY29kZSBpbmRleH0gaWYgaXQgZXhpc3RzIGFuZCBpcyBhIGxvbmcgb3IKKyAgICAgKiBjYW4gYmUgY29lcmNlZCB0byBhIGxvbmcuIFJldHVybnMge0Bjb2RlIGZhbGxiYWNrfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGxvbmcgb3B0TG9uZyhpbnQgaW5kZXgsIGxvbmcgZmFsbGJhY2spIHsKKyAgICAgICAgT2JqZWN0IG9iamVjdCA9IG9wdChpbmRleCk7CisgICAgICAgIExvbmcgcmVzdWx0ID0gSlNPTi50b0xvbmcob2JqZWN0KTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdCAhPSBudWxsID8gcmVzdWx0IDogZmFsbGJhY2s7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgYXQge0Bjb2RlIGluZGV4fSBpZiBpdCBleGlzdHMsIGNvZXJjaW5nIGl0IGlmCisgICAgICogbmVjZXNzYXJ5LgorICAgICAqCisgICAgICogQHRocm93cyBKU09ORXhjZXB0aW9uIGlmIG5vIHN1Y2ggdmFsdWUgZXhpc3RzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nKGludCBpbmRleCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBPYmplY3Qgb2JqZWN0ID0gZ2V0KGluZGV4KTsKKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IEpTT04udG9TdHJpbmcob2JqZWN0KTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBKU09OLnR5cGVNaXNtYXRjaChpbmRleCwgb2JqZWN0LCAiU3RyaW5nIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBhdCB7QGNvZGUgaW5kZXh9IGlmIGl0IGV4aXN0cywgY29lcmNpbmcgaXQgaWYKKyAgICAgKiBuZWNlc3NhcnkuIFJldHVybnMgdGhlIGVtcHR5IHN0cmluZyBpZiBubyBzdWNoIHZhbHVlIGV4aXN0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIG9wdFN0cmluZyhpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIG9wdFN0cmluZyhpbmRleCwgIiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIGF0IHtAY29kZSBpbmRleH0gaWYgaXQgZXhpc3RzLCBjb2VyY2luZyBpdCBpZgorICAgICAqIG5lY2Vzc2FyeS4gUmV0dXJucyB7QGNvZGUgZmFsbGJhY2t9IGlmIG5vIHN1Y2ggdmFsdWUgZXhpc3RzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgb3B0U3RyaW5nKGludCBpbmRleCwgU3RyaW5nIGZhbGxiYWNrKSB7CisgICAgICAgIE9iamVjdCBvYmplY3QgPSBvcHQoaW5kZXgpOworICAgICAgICBTdHJpbmcgcmVzdWx0ID0gSlNPTi50b1N0cmluZyhvYmplY3QpOworICAgICAgICByZXR1cm4gcmVzdWx0ICE9IG51bGwgPyByZXN1bHQgOiBmYWxsYmFjazsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBhdCB7QGNvZGUgaW5kZXh9IGlmIGl0IGV4aXN0cyBhbmQgaXMgYSB7QGNvZGUKKyAgICAgKiBKU09OQXJyYXl9LgorICAgICAqCisgICAgICogQHRocm93cyBKU09ORXhjZXB0aW9uIGlmIHRoZSB2YWx1ZSBkb2Vzbid0IGV4aXN0IG9yIGlzIG5vdCBhIHtAY29kZQorICAgICAqICAgICBKU09OQXJyYXl9LgorICAgICAqLworICAgIHB1YmxpYyBKU09OQXJyYXkgZ2V0SlNPTkFycmF5KGludCBpbmRleCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBPYmplY3Qgb2JqZWN0ID0gZ2V0KGluZGV4KTsKKyAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIEpTT05BcnJheSkgeworICAgICAgICAgICAgcmV0dXJuIChKU09OQXJyYXkpIG9iamVjdDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IEpTT04udHlwZU1pc21hdGNoKGluZGV4LCBvYmplY3QsICJKU09OQXJyYXkiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIGF0IHtAY29kZSBpbmRleH0gaWYgaXQgZXhpc3RzIGFuZCBpcyBhIHtAY29kZQorICAgICAqIEpTT05BcnJheX0uIFJldHVybnMgbnVsbCBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIEpTT05BcnJheSBvcHRKU09OQXJyYXkoaW50IGluZGV4KSB7CisgICAgICAgIE9iamVjdCBvYmplY3QgPSBvcHQoaW5kZXgpOworICAgICAgICByZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgSlNPTkFycmF5ID8gKEpTT05BcnJheSkgb2JqZWN0IDogbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBhdCB7QGNvZGUgaW5kZXh9IGlmIGl0IGV4aXN0cyBhbmQgaXMgYSB7QGNvZGUKKyAgICAgKiBKU09OT2JqZWN0fS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSlNPTkV4Y2VwdGlvbiBpZiB0aGUgdmFsdWUgZG9lc24ndCBleGlzdCBvciBpcyBub3QgYSB7QGNvZGUKKyAgICAgKiAgICAgSlNPTk9iamVjdH0uCisgICAgICovCisgICAgcHVibGljIEpTT05PYmplY3QgZ2V0SlNPTk9iamVjdChpbnQgaW5kZXgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0IG9iamVjdCA9IGdldChpbmRleCk7CisgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBKU09OT2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gKEpTT05PYmplY3QpIG9iamVjdDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IEpTT04udHlwZU1pc21hdGNoKGluZGV4LCBvYmplY3QsICJKU09OT2JqZWN0Iik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBhdCB7QGNvZGUgaW5kZXh9IGlmIGl0IGV4aXN0cyBhbmQgaXMgYSB7QGNvZGUKKyAgICAgKiBKU09OT2JqZWN0fS4gUmV0dXJucyBudWxsIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTk9iamVjdCBvcHRKU09OT2JqZWN0KGludCBpbmRleCkgeworICAgICAgICBPYmplY3Qgb2JqZWN0ID0gb3B0KGluZGV4KTsKKyAgICAgICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIEpTT05PYmplY3QgPyAoSlNPTk9iamVjdCkgb2JqZWN0IDogbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IG9iamVjdCB3aG9zZSB2YWx1ZXMgYXJlIHRoZSB2YWx1ZXMgaW4gdGhpcyBhcnJheSwgYW5kIHdob3NlCisgICAgICogbmFtZXMgYXJlIHRoZSB2YWx1ZXMgaW4ge0Bjb2RlIG5hbWVzfS4gTmFtZXMgYW5kIHZhbHVlcyBhcmUgcGFpcmVkIHVwIGJ5CisgICAgICogaW5kZXggZnJvbSAwIHRocm91Z2ggdG8gdGhlIHNob3J0ZXIgYXJyYXkncyBsZW5ndGguIE5hbWVzIHRoYXQgYXJlIG5vdAorICAgICAqIHN0cmluZ3Mgd2lsbCBiZSBjb2VyY2VkIHRvIHN0cmluZ3MuIFRoaXMgbWV0aG9kIHJldHVybnMgbnVsbCBpZiBlaXRoZXIKKyAgICAgKiBhcnJheSBpcyBlbXB0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTk9iamVjdCB0b0pTT05PYmplY3QoSlNPTkFycmF5IG5hbWVzKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05PYmplY3QgcmVzdWx0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgaW50IGxlbmd0aCA9IE1hdGgubWluKG5hbWVzLmxlbmd0aCgpLCB2YWx1ZXMuc2l6ZSgpKTsKKyAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IEpTT04udG9TdHJpbmcobmFtZXMub3B0KGkpKTsKKyAgICAgICAgICAgIHJlc3VsdC5wdXQobmFtZSwgb3B0KGkpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgc3RyaW5nIGJ5IGFsdGVybmF0aW5nIHRoaXMgYXJyYXkncyB2YWx1ZXMgd2l0aCB7QGNvZGUKKyAgICAgKiBzZXBhcmF0b3J9LiBUaGlzIGFycmF5J3Mgc3RyaW5nIHZhbHVlcyBhcmUgcXVvdGVkIGFuZCBoYXZlIHRoZWlyIHNwZWNpYWwKKyAgICAgKiBjaGFyYWN0ZXJzIGVzY2FwZWQuIEZvciBleGFtcGxlLCB0aGUgYXJyYXkgY29udGFpbmluZyB0aGUgc3RyaW5ncyAnMTIiCisgICAgICogcGl6emEnLCAndGFjbycgYW5kICdzb2RhJyBqb2luZWQgb24gJysnIHJldHVybnMgdGhpczoKKyAgICAgKiA8cHJlPiIxMlwiIHBpenphIisidGFjbyIrInNvZGEiPC9wcmU+CisgICAgICovCisgICAgcHVibGljIFN0cmluZyBqb2luKFN0cmluZyBzZXBhcmF0b3IpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTlN0cmluZ2VyIHN0cmluZ2VyID0gbmV3IEpTT05TdHJpbmdlcigpOworICAgICAgICBzdHJpbmdlci5vcGVuKEpTT05TdHJpbmdlci5TY29wZS5OVUxMLCAiIik7CisgICAgICAgIGZvciAoaW50IGkgPSAwLCBzaXplID0gdmFsdWVzLnNpemUoKTsgaSA8IHNpemU7IGkrKykgeworICAgICAgICAgICAgaWYgKGkgPiAwKSB7CisgICAgICAgICAgICAgICAgc3RyaW5nZXIub3V0LmFwcGVuZChzZXBhcmF0b3IpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3RyaW5nZXIudmFsdWUodmFsdWVzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgc3RyaW5nZXIuY2xvc2UoSlNPTlN0cmluZ2VyLlNjb3BlLk5VTEwsIEpTT05TdHJpbmdlci5TY29wZS5OVUxMLCAiIik7CisgICAgICAgIHJldHVybiBzdHJpbmdlci5vdXQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmNvZGVzIHRoaXMgYXJyYXkgYXMgYSBjb21wYWN0IEpTT04gc3RyaW5nLCBzdWNoIGFzOgorICAgICAqIDxwcmU+Wzk0MDQzLDkwMjEwXTwvcHJlPgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgSlNPTlN0cmluZ2VyIHN0cmluZ2VyID0gbmV3IEpTT05TdHJpbmdlcigpOworICAgICAgICAgICAgd3JpdGVUbyhzdHJpbmdlcik7CisgICAgICAgICAgICByZXR1cm4gc3RyaW5nZXIudG9TdHJpbmcoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEVuY29kZXMgdGhpcyBhcnJheSBhcyBhIGh1bWFuIHJlYWRhYmxlIEpTT04gc3RyaW5nIGZvciBkZWJ1Z2dpbmcsIHN1Y2gKKyAgICAgKiBhczoKKyAgICAgKiA8cHJlPgorICAgICAqIFsKKyAgICAgKiAgICAgOTQwNDMsCisgICAgICogICAgIDkwMjEwCisgICAgICogXTwvcHJlPgorICAgICAqCisgICAgICogQHBhcmFtIGluZGVudFNwYWNlcyB0aGUgbnVtYmVyIG9mIHNwYWNlcyB0byBpbmRlbnQgZm9yIGVhY2ggbGV2ZWwgb2YKKyAgICAgKiAgICAgbmVzdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGludCBpbmRlbnRTcGFjZXMpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTlN0cmluZ2VyIHN0cmluZ2VyID0gbmV3IEpTT05TdHJpbmdlcihpbmRlbnRTcGFjZXMpOworICAgICAgICB3cml0ZVRvKHN0cmluZ2VyKTsKKyAgICAgICAgcmV0dXJuIHN0cmluZ2VyLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgdm9pZCB3cml0ZVRvKEpTT05TdHJpbmdlciBzdHJpbmdlcikgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBzdHJpbmdlci5hcnJheSgpOworICAgICAgICBmb3IgKE9iamVjdCB2YWx1ZSA6IHZhbHVlcykgeworICAgICAgICAgICAgc3RyaW5nZXIudmFsdWUodmFsdWUpOworICAgICAgICB9CisgICAgICAgIHN0cmluZ2VyLmVuZEFycmF5KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICByZXR1cm4gbyBpbnN0YW5jZW9mIEpTT05BcnJheSAmJiAoKEpTT05BcnJheSkgbykudmFsdWVzLmVxdWFscyh2YWx1ZXMpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAvLyBkaXZlcmdlIGZyb20gdGhlIG9yaWdpbmFsLCB3aGljaCBkb2Vzbid0IGltcGxlbWVudCBoYXNoQ29kZQorICAgICAgICByZXR1cm4gdmFsdWVzLmhhc2hDb2RlKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvanNvbi9zcmMvbWFpbi9qYXZhL29yZy9qc29uL0pTT05FeGNlcHRpb24uamF2YSBiL2pzb24vc3JjL21haW4vamF2YS9vcmcvanNvbi9KU09ORXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmM2NmViOAotLS0gL2Rldi9udWxsCisrKyBiL2pzb24vc3JjL21haW4vamF2YS9vcmcvanNvbi9KU09ORXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmpzb247CisKKy8vIE5vdGU6IHRoaXMgY2xhc3Mgd2FzIHdyaXR0ZW4gd2l0aG91dCBpbnNwZWN0aW5nIHRoZSBub24tZnJlZSBvcmcuanNvbiBzb3VyY2Vjb2RlLgorCisvKioKKyAqIFRocm93biB0byBpbmRpY2F0ZSBhIHByb2JsZW0gd2l0aCB0aGUgSlNPTiBBUEkuIFN1Y2ggcHJvYmxlbXMgaW5jbHVkZToKKyAqIDx1bD4KKyAqICAgPGxpPkF0dGVtcHRzIHRvIHBhcnNlIG9yIGNvbnN0cnVjdCBtYWxmb3JtZWQgZG9jdW1lbnRzCisgKiAgIDxsaT5Vc2Ugb2YgbnVsbCBhcyBhIG5hbWUKKyAqICAgPGxpPlVzZSBvZiBudW1lcmljIHR5cGVzIG5vdCBhdmFpbGFibGUgdG8gSlNPTiwgc3VjaCBhcyB7QGxpbmsKKyAqICAgICAgIERvdWJsZSNpc05hTigpIE5hTnN9IG9yIHtAbGluayBEb3VibGUjaXNJbmZpbml0ZSgpIGluZmluaXRpZXN9LgorICogICA8bGk+TG9va3VwcyB1c2luZyBhbiBvdXQgb2YgcmFuZ2UgaW5kZXggb3Igbm9uZXhpc3RlbnQgbmFtZQorICogICA8bGk+VHlwZSBtaXNtYXRjaGVzIG9uIGxvb2t1cHMKKyAqIDwvdWw+CisgKgorICogPHA+QWx0aG91Z2ggdGhpcyBpcyBhIGNoZWNrZWQgZXhjZXB0aW9uLCBpdCBpcyByYXJlbHkgcmVjb3ZlcmFibGUuIE1vc3QKKyAqIGNhbGxlcnMgc2hvdWxkIHNpbXBseSB3cmFwIHRoaXMgZXhjZXB0aW9uIGluIGFuIHVuY2hlY2tlZCBleGNlcHRpb24gYW5kCisgKiByZXRocm93OgorICogPHByZT4gIHB1YmxpYyBKU09OQXJyYXkgdG9KU09OT2JqZWN0KCkgeworICogICAgIHRyeSB7CisgKiAgICAgICAgIEpTT05PYmplY3QgcmVzdWx0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAqICAgICAgICAgLi4uCisgKiAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgKiAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICogICAgIH0KKyAqIH08L3ByZT4KKyAqLworcHVibGljIGNsYXNzIEpTT05FeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworCisgICAgcHVibGljIEpTT05FeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICAgICAgc3VwZXIocyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvanNvbi9zcmMvbWFpbi9qYXZhL29yZy9qc29uL0pTT05PYmplY3QuamF2YSBiL2pzb24vc3JjL21haW4vamF2YS9vcmcvanNvbi9KU09OT2JqZWN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTdjYTczNQotLS0gL2Rldi9udWxsCisrKyBiL2pzb24vc3JjL21haW4vamF2YS9vcmcvanNvbi9KU09OT2JqZWN0LmphdmEKQEAgLTAsMCArMSw3MjAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5qc29uOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLy8gTm90ZTogdGhpcyBjbGFzcyB3YXMgd3JpdHRlbiB3aXRob3V0IGluc3BlY3RpbmcgdGhlIG5vbi1mcmVlIG9yZy5qc29uIHNvdXJjZWNvZGUuCisKKy8qKgorICogQSBtb2RpZmlhYmxlIHNldCBvZiBuYW1lL3ZhbHVlIG1hcHBpbmdzLiBOYW1lcyBhcmUgdW5pcXVlLCBub24tbnVsbCBzdHJpbmdzLgorICogVmFsdWVzIG1heSBiZSBhbnkgbWl4IG9mIHtAbGluayBKU09OT2JqZWN0IEpTT05PYmplY3RzfSwge0BsaW5rIEpTT05BcnJheQorICogSlNPTkFycmF5c30sIFN0cmluZ3MsIEJvb2xlYW5zLCBJbnRlZ2VycywgTG9uZ3MsIERvdWJsZXMgb3Ige0BsaW5rICNOVUxMfS4KKyAqIFZhbHVlcyBtYXkgbm90IGJlIHtAY29kZSBudWxsfSwge0BsaW5rIERvdWJsZSNpc05hTigpIE5hTnN9LCB7QGxpbmsKKyAqIERvdWJsZSNpc0luZmluaXRlKCkgaW5maW5pdGllc30sIG9yIG9mIGFueSB0eXBlIG5vdCBsaXN0ZWQgaGVyZS4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGNhbiBjb2VyY2UgdmFsdWVzIHRvIGFub3RoZXIgdHlwZSB3aGVuIHJlcXVlc3RlZC4KKyAqIDx1bD4KKyAqICAgPGxpPldoZW4gdGhlIHJlcXVlc3RlZCB0eXBlIGlzIGEgYm9vbGVhbiwgc3RyaW5ncyB3aWxsIGJlIGNvZXJjZWQgdXNpbmcgYQorICogICAgICAgY2FzZS1pbnNlbnNpdGl2ZSBjb21wYXJpc29uIHRvICJ0cnVlIiBhbmQgImZhbHNlIi4KKyAqICAgPGxpPldoZW4gdGhlIHJlcXVlc3RlZCB0eXBlIGlzIGEgZG91YmxlLCBvdGhlciB7QGxpbmsgTnVtYmVyfSB0eXBlcyB3aWxsCisgKiAgICAgICBiZSBjb2VyY2VkIHVzaW5nIHtAbGluayBOdW1iZXIjZG91YmxlVmFsdWUoKSBkb3VibGVWYWx1ZX0uIFN0cmluZ3MKKyAqICAgICAgIHRoYXQgY2FuIGJlIGNvZXJjZWQgdXNpbmcge0BsaW5rIERvdWJsZSN2YWx1ZU9mKFN0cmluZyl9IHdpbGwgYmUuCisgKiAgIDxsaT5XaGVuIHRoZSByZXF1ZXN0ZWQgdHlwZSBpcyBhbiBpbnQsIG90aGVyIHtAbGluayBOdW1iZXJ9IHR5cGVzIHdpbGwKKyAqICAgICAgIGJlIGNvZXJjZWQgdXNpbmcge0BsaW5rIE51bWJlciNpbnRWYWx1ZSgpIGludFZhbHVlfS4gU3RyaW5ncworICogICAgICAgdGhhdCBjYW4gYmUgY29lcmNlZCB1c2luZyB7QGxpbmsgRG91YmxlI3ZhbHVlT2YoU3RyaW5nKX0gd2lsbCBiZSwKKyAqICAgICAgIGFuZCB0aGVuIGNhc3QgdG8gaW50LgorICogICA8bGk+V2hlbiB0aGUgcmVxdWVzdGVkIHR5cGUgaXMgYSBsb25nLCBvdGhlciB7QGxpbmsgTnVtYmVyfSB0eXBlcyB3aWxsCisgKiAgICAgICBiZSBjb2VyY2VkIHVzaW5nIHtAbGluayBOdW1iZXIjbG9uZ1ZhbHVlKCkgbG9uZ1ZhbHVlfS4gU3RyaW5ncworICogICAgICAgdGhhdCBjYW4gYmUgY29lcmNlZCB1c2luZyB7QGxpbmsgRG91YmxlI3ZhbHVlT2YoU3RyaW5nKX0gd2lsbCBiZSwKKyAqICAgICAgIGFuZCB0aGVuIGNhc3QgdG8gbG9uZy4gVGhpcyB0d28tc3RlcCBjb252ZXJzaW9uIGlzIGxvc3N5IGZvciB2ZXJ5CisgKiAgICAgICBsYXJnZSB2YWx1ZXMuIEZvciBleGFtcGxlLCB0aGUgc3RyaW5nICI5MjIzMzcyMDM2ODU0Nzc1ODA2IiB5aWVsZHMgdGhlCisgKiAgICAgICBsb25nIDkyMjMzNzIwMzY4NTQ3NzU4MDcuCisgKiAgIDxsaT5XaGVuIHRoZSByZXF1ZXN0ZWQgdHlwZSBpcyBhIFN0cmluZywgb3RoZXIgbm9uLW51bGwgdmFsdWVzIHdpbGwgYmUKKyAqICAgICAgIGNvZXJjZWQgdXNpbmcge0BsaW5rIFN0cmluZyN2YWx1ZU9mKE9iamVjdCl9LiBBbHRob3VnaCBudWxsIGNhbm5vdCBiZQorICogICAgICAgY29lcmNlZCwgdGhlIHNlbnRpbmVsIHZhbHVlIHtAbGluayBKU09OT2JqZWN0I05VTEx9IGlzIGNvZXJjZWQgdG8gdGhlCisgKiAgICAgICBzdHJpbmcgIm51bGwiLgorICogPC91bD4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGNhbiBsb29rIHVwIGJvdGggbWFuZGF0b3J5IGFuZCBvcHRpb25hbCB2YWx1ZXM6CisgKiA8dWw+CisgKiAgIDxsaT5Vc2UgPGNvZGU+Z2V0PGk+VHlwZTwvaT4oKTwvY29kZT4gdG8gcmV0cmlldmUgYSBtYW5kYXRvcnkgdmFsdWUuIFRoaXMKKyAqICAgICAgIGZhaWxzIHdpdGggYSB7QGNvZGUgSlNPTkV4Y2VwdGlvbn0gaWYgdGhlIHJlcXVlc3RlZCBuYW1lIGhhcyBubyB2YWx1ZQorICogICAgICAgb3IgaWYgdGhlIHZhbHVlIGNhbm5vdCBiZSBjb2VyY2VkIHRvIHRoZSByZXF1ZXN0ZWQgdHlwZS4KKyAqICAgPGxpPlVzZSA8Y29kZT5vcHQ8aT5UeXBlPC9pPigpPC9jb2RlPiB0byByZXRyaWV2ZSBhbiBvcHRpb25hbCB2YWx1ZS4gVGhpcworICogICAgICAgcmV0dXJucyBhIHN5c3RlbS0gb3IgdXNlci1zdXBwbGllZCBkZWZhdWx0IGlmIHRoZSByZXF1ZXN0ZWQgbmFtZSBoYXMgbm8KKyAqICAgICAgIHZhbHVlIG9yIGlmIHRoZSB2YWx1ZSBjYW5ub3QgYmUgY29lcmNlZCB0byB0aGUgcmVxdWVzdGVkIHR5cGUuCisgKiA8L3VsPgorICoKKyAqIDxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gdGhpcyBjbGFzcyByZXByZXNlbnRzIG51bGwgaW4gdHdvIGluY29tcGF0aWJsZQorICogd2F5czogdGhlIHN0YW5kYXJkIEphdmEge0Bjb2RlIG51bGx9IHJlZmVyZW5jZSwgYW5kIHRoZSBzZW50aW5lbCB2YWx1ZSB7QGxpbmsKKyAqIEpTT05PYmplY3QjTlVMTH0uIEluIHBhcnRpY3VsYXIsIGNhbGxpbmcge0Bjb2RlIHB1dChuYW1lLCBudWxsKX0gcmVtb3ZlcyB0aGUKKyAqIG5hbWVkIGVudHJ5IGZyb20gdGhlIG9iamVjdCBidXQge0Bjb2RlIHB1dChuYW1lLCBKU09OT2JqZWN0Lk5VTEwpfSBzdG9yZXMgYW4KKyAqIGVudHJ5IHdob3NlIHZhbHVlIGlzIHtAY29kZSBKU09OT2JqZWN0Lk5VTEx9LgorICoKKyAqIDxwPkluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIGFyZSBub3QgdGhyZWFkIHNhZmUuIEFsdGhvdWdoIHRoaXMgY2xhc3MgaXMKKyAqIG5vbmZpbmFsLCBpdCB3YXMgbm90IGRlc2lnbmVkIGZvciBpbmhlcml0YW5jZSBhbmQgc2hvdWxkIG5vdCBiZSBzdWJjbGFzc2VkLgorICogSW4gcGFydGljdWxhciwgc2VsZi11c2UgYnkgb3ZlcnJpZGVhYmxlIG1ldGhvZHMgaXMgbm90IHNwZWNpZmllZC4gU2VlCisgKiA8aT5FZmZlY3RpdmUgSmF2YTwvaT4gSXRlbSAxNywgIkRlc2lnbiBhbmQgRG9jdW1lbnQgb3IgaW5oZXJpdGFuY2Ugb3IgZWxzZQorICogcHJvaGliaXQgaXQiIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgorICovCitwdWJsaWMgY2xhc3MgSlNPTk9iamVjdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBEb3VibGUgTkVHQVRJVkVfWkVSTyA9IC0wZDsKKworICAgIC8qKgorICAgICAqIEEgc2VudGluZWwgdmFsdWUgdXNlZCB0byBleHBsaWNpdGx5IGRlZmluZSBhIG5hbWUgd2l0aCBubyB2YWx1ZS4gVW5saWtlCisgICAgICoge0Bjb2RlIG51bGx9LCBuYW1lcyB3aXRoIHRoaXMgdmFsdWU6CisgICAgICogPHVsPgorICAgICAqICAgPGxpPnNob3cgdXAgaW4gdGhlIHtAbGluayAjbmFtZXN9IGFycmF5CisgICAgICogICA8bGk+c2hvdyB1cCBpbiB0aGUge0BsaW5rICNrZXlzfSBpdGVyYXRvcgorICAgICAqICAgPGxpPnJldHVybiB7QGNvZGUgdHJ1ZX0gZm9yIHtAbGluayAjaGFzKFN0cmluZyl9CisgICAgICogICA8bGk+ZG8gbm90IHRocm93IG9uIHtAbGluayAjZ2V0KFN0cmluZyl9CisgICAgICogICA8bGk+YXJlIGluY2x1ZGVkIGluIHRoZSBlbmNvZGVkIEpTT04gc3RyaW5nLgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIHZhbHVlIHZpb2xhdGVzIHRoZSBnZW5lcmFsIGNvbnRyYWN0IG9mIHtAbGluayBPYmplY3QjZXF1YWxzfSBieQorICAgICAqIHJldHVybmluZyB0cnVlIHdoZW4gY29tcGFyZWQgdG8ge0Bjb2RlIG51bGx9LiBJdHMge0BsaW5rICN0b1N0cmluZ30KKyAgICAgKiBtZXRob2QgcmV0dXJucyAibnVsbCIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBPYmplY3QgTlVMTCA9IG5ldyBPYmplY3QoKSB7CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIHJldHVybiBvID09IHRoaXMgfHwgbyA9PSBudWxsOyAvLyBBUEkgc3BlY2lmaWVzIHRoaXMgYnJva2VuIGVxdWFscyBpbXBsZW1lbnRhdGlvbgorICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuICJudWxsIjsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIE9iamVjdD4gbmFtZVZhbHVlUGFpcnM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIEpTT05PYmplY3R9IHdpdGggbm8gbmFtZS92YWx1ZSBtYXBwaW5ncy4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTk9iamVjdCgpIHsKKyAgICAgICAgbmFtZVZhbHVlUGFpcnMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIE9iamVjdD4oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBKU09OT2JqZWN0fSBieSBjb3B5aW5nIGFsbCBuYW1lL3ZhbHVlIG1hcHBpbmdzIGZyb20KKyAgICAgKiB0aGUgZ2l2ZW4gbWFwLgorICAgICAqCisgICAgICogQHBhcmFtIGNvcHlGcm9tIGEgbWFwIHdob3NlIGtleXMgYXJlIG9mIHR5cGUge0BsaW5rIFN0cmluZ30gYW5kIHdob3NlCisgICAgICogICAgIHZhbHVlcyBhcmUgb2Ygc3VwcG9ydGVkIHR5cGVzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgYW55IG9mIHRoZSBtYXAncyBrZXlzIGFyZSBudWxsLgorICAgICAqLworICAgIC8qIChhY2NlcHQgYSByYXcgdHlwZSBmb3IgQVBJIGNvbXBhdGliaWxpdHkpICovCisgICAgcHVibGljIEpTT05PYmplY3QoTWFwIGNvcHlGcm9tKSB7CisgICAgICAgIHRoaXMoKTsKKyAgICAgICAgTWFwPD8sID8+IGNvbnRlbnRzVHlwZWQgPSAoTWFwPD8sID8+KSBjb3B5RnJvbTsKKyAgICAgICAgZm9yIChNYXAuRW50cnk8PywgPz4gZW50cnkgOiBjb250ZW50c1R5cGVkLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBEZXZpYXRlIGZyb20gdGhlIG9yaWdpbmFsIGJ5IGNoZWNraW5nIHRoYXQga2V5cyBhcmUgbm9uLW51bGwgYW5kCisgICAgICAgICAgICAgKiBvZiB0aGUgcHJvcGVyIHR5cGUuIChXZSBzdGlsbCBkZWZlciB2YWxpZGF0aW5nIHRoZSB2YWx1ZXMpLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBTdHJpbmcga2V5ID0gKFN0cmluZykgZW50cnkuZ2V0S2V5KCk7CisgICAgICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG5hbWVWYWx1ZVBhaXJzLnB1dChrZXksIGVudHJ5LmdldFZhbHVlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgSlNPTk9iamVjdH0gd2l0aCBuYW1lL3ZhbHVlIG1hcHBpbmdzIGZyb20gdGhlIG5leHQKKyAgICAgKiBvYmplY3QgaW4gdGhlIHRva2VuZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhZEZyb20gYSB0b2tlbmVyIHdob3NlIG5leHRWYWx1ZSgpIG1ldGhvZCB3aWxsIHlpZWxkIGEKKyAgICAgKiAgICAge0Bjb2RlIEpTT05PYmplY3R9LgorICAgICAqIEB0aHJvd3MgSlNPTkV4Y2VwdGlvbiBpZiB0aGUgcGFyc2UgZmFpbHMgb3IgZG9lc24ndCB5aWVsZCBhCisgICAgICogICAgIHtAY29kZSBKU09OT2JqZWN0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTk9iamVjdChKU09OVG9rZW5lciByZWFkRnJvbSkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICAvKgorICAgICAgICAgKiBHZXR0aW5nIHRoZSBwYXJzZXIgdG8gcG9wdWxhdGUgdGhpcyBjb3VsZCBnZXQgdHJpY2t5LiBJbnN0ZWFkLCBqdXN0CisgICAgICAgICAqIHBhcnNlIHRvIHRlbXBvcmFyeSBKU09OT2JqZWN0IGFuZCB0aGVuIHN0ZWFsIHRoZSBkYXRhIGZyb20gdGhhdC4KKyAgICAgICAgICovCisgICAgICAgIE9iamVjdCBvYmplY3QgPSByZWFkRnJvbS5uZXh0VmFsdWUoKTsKKyAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIEpTT05PYmplY3QpIHsKKyAgICAgICAgICAgIHRoaXMubmFtZVZhbHVlUGFpcnMgPSAoKEpTT05PYmplY3QpIG9iamVjdCkubmFtZVZhbHVlUGFpcnM7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBKU09OLnR5cGVNaXNtYXRjaChvYmplY3QsICJKU09OT2JqZWN0Iik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBKU09OT2JqZWN0fSB3aXRoIG5hbWUvdmFsdWUgbWFwcGluZ3MgZnJvbSB0aGUgSlNPTgorICAgICAqIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBqc29uIGEgSlNPTi1lbmNvZGVkIHN0cmluZyBjb250YWluaW5nIGFuIG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIEpTT05FeGNlcHRpb24gaWYgdGhlIHBhcnNlIGZhaWxzIG9yIGRvZXNuJ3QgeWllbGQgYSB7QGNvZGUKKyAgICAgKiAgICAgSlNPTk9iamVjdH0uCisgICAgICovCisgICAgcHVibGljIEpTT05PYmplY3QoU3RyaW5nIGpzb24pIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhuZXcgSlNPTlRva2VuZXIoanNvbikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEpTT05PYmplY3R9IGJ5IGNvcHlpbmcgbWFwcGluZ3MgZm9yIHRoZSBsaXN0ZWQgbmFtZXMKKyAgICAgKiBmcm9tIHRoZSBnaXZlbiBvYmplY3QuIE5hbWVzIHRoYXQgYXJlbid0IHByZXNlbnQgaW4ge0Bjb2RlIGNvcHlGcm9tfSB3aWxsCisgICAgICogYmUgc2tpcHBlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTk9iamVjdChKU09OT2JqZWN0IGNvcHlGcm9tLCBTdHJpbmdbXSBuYW1lcykgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICB0aGlzKCk7CisgICAgICAgIGZvciAoU3RyaW5nIG5hbWUgOiBuYW1lcykgeworICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gY29weUZyb20ub3B0KG5hbWUpOworICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBuYW1lVmFsdWVQYWlycy5wdXQobmFtZSwgdmFsdWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIG5hbWUvdmFsdWUgbWFwcGluZ3MgaW4gdGhpcyBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGludCBsZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBuYW1lVmFsdWVQYWlycy5zaXplKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFwcyB7QGNvZGUgbmFtZX0gdG8ge0Bjb2RlIHZhbHVlfSwgY2xvYmJlcmluZyBhbnkgZXhpc3RpbmcgbmFtZS92YWx1ZQorICAgICAqIG1hcHBpbmcgd2l0aCB0aGUgc2FtZSBuYW1lLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTk9iamVjdCBwdXQoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgbmFtZVZhbHVlUGFpcnMucHV0KGNoZWNrTmFtZShuYW1lKSwgdmFsdWUpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXBzIHtAY29kZSBuYW1lfSB0byB7QGNvZGUgdmFsdWV9LCBjbG9iYmVyaW5nIGFueSBleGlzdGluZyBuYW1lL3ZhbHVlCisgICAgICogbWFwcGluZyB3aXRoIHRoZSBzYW1lIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUgYSBmaW5pdGUgdmFsdWUuIE1heSBub3QgYmUge0BsaW5rIERvdWJsZSNpc05hTigpIE5hTnN9IG9yCisgICAgICogICAgIHtAbGluayBEb3VibGUjaXNJbmZpbml0ZSgpIGluZmluaXRpZXN9LgorICAgICAqIEByZXR1cm4gdGhpcyBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIEpTT05PYmplY3QgcHV0KFN0cmluZyBuYW1lLCBkb3VibGUgdmFsdWUpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgbmFtZVZhbHVlUGFpcnMucHV0KGNoZWNrTmFtZShuYW1lKSwgSlNPTi5jaGVja0RvdWJsZSh2YWx1ZSkpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXBzIHtAY29kZSBuYW1lfSB0byB7QGNvZGUgdmFsdWV9LCBjbG9iYmVyaW5nIGFueSBleGlzdGluZyBuYW1lL3ZhbHVlCisgICAgICogbWFwcGluZyB3aXRoIHRoZSBzYW1lIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBKU09OT2JqZWN0IHB1dChTdHJpbmcgbmFtZSwgaW50IHZhbHVlKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIG5hbWVWYWx1ZVBhaXJzLnB1dChjaGVja05hbWUobmFtZSksIHZhbHVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFwcyB7QGNvZGUgbmFtZX0gdG8ge0Bjb2RlIHZhbHVlfSwgY2xvYmJlcmluZyBhbnkgZXhpc3RpbmcgbmFtZS92YWx1ZQorICAgICAqIG1hcHBpbmcgd2l0aCB0aGUgc2FtZSBuYW1lLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTk9iamVjdCBwdXQoU3RyaW5nIG5hbWUsIGxvbmcgdmFsdWUpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgbmFtZVZhbHVlUGFpcnMucHV0KGNoZWNrTmFtZShuYW1lKSwgdmFsdWUpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXBzIHtAY29kZSBuYW1lfSB0byB7QGNvZGUgdmFsdWV9LCBjbG9iYmVyaW5nIGFueSBleGlzdGluZyBuYW1lL3ZhbHVlCisgICAgICogbWFwcGluZyB3aXRoIHRoZSBzYW1lIG5hbWUuIElmIHRoZSB2YWx1ZSBpcyB7QGNvZGUgbnVsbH0sIGFueSBleGlzdGluZworICAgICAqIG1hcHBpbmcgZm9yIHtAY29kZSBuYW1lfSBpcyByZW1vdmVkLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlIGEge0BsaW5rIEpTT05PYmplY3R9LCB7QGxpbmsgSlNPTkFycmF5fSwgU3RyaW5nLCBCb29sZWFuLAorICAgICAqICAgICBJbnRlZ2VyLCBMb25nLCBEb3VibGUsIHtAbGluayAjTlVMTH0sIG9yIHtAY29kZSBudWxsfS4gTWF5IG5vdCBiZQorICAgICAqICAgICB7QGxpbmsgRG91YmxlI2lzTmFOKCkgTmFOc30gb3Ige0BsaW5rIERvdWJsZSNpc0luZmluaXRlKCkKKyAgICAgKiAgICAgaW5maW5pdGllc30uCisgICAgICogQHJldHVybiB0aGlzIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTk9iamVjdCBwdXQoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgbmFtZVZhbHVlUGFpcnMucmVtb3ZlKG5hbWUpOworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTnVtYmVyKSB7CisgICAgICAgICAgICAvLyBkZXZpYXRlIGZyb20gdGhlIG9yaWdpbmFsIGJ5IGNoZWNraW5nIGFsbCBOdW1iZXJzLCBub3QganVzdCBmbG9hdHMgJiBkb3VibGVzCisgICAgICAgICAgICBKU09OLmNoZWNrRG91YmxlKCgoTnVtYmVyKSB2YWx1ZSkuZG91YmxlVmFsdWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgbmFtZVZhbHVlUGFpcnMucHV0KGNoZWNrTmFtZShuYW1lKSwgdmFsdWUpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVpdmFsZW50IHRvIHtAY29kZSBwdXQobmFtZSwgdmFsdWUpfSB3aGVuIGJvdGggcGFyYW1ldGVycyBhcmUgbm9uLW51bGw7CisgICAgICogZG9lcyBub3RoaW5nIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTk9iamVjdCBwdXRPcHQoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBpZiAobmFtZSA9PSBudWxsIHx8IHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICB9CisgICAgICAgIHJldHVybiBwdXQobmFtZSwgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMge0Bjb2RlIHZhbHVlfSB0byB0aGUgYXJyYXkgYWxyZWFkeSBtYXBwZWQgdG8ge0Bjb2RlIG5hbWV9LiBJZgorICAgICAqIHRoaXMgb2JqZWN0IGhhcyBubyBtYXBwaW5nIGZvciB7QGNvZGUgbmFtZX0sIHRoaXMgaW5zZXJ0cyBhIG5ldyBtYXBwaW5nLgorICAgICAqIElmIHRoZSBtYXBwaW5nIGV4aXN0cyBidXQgaXRzIHZhbHVlIGlzIG5vdCBhbiBhcnJheSwgdGhlIGV4aXN0aW5nCisgICAgICogYW5kIG5ldyB2YWx1ZXMgYXJlIGluc2VydGVkIGluIG9yZGVyIGludG8gYSBuZXcgYXJyYXkgd2hpY2ggaXMgaXRzZWxmCisgICAgICogbWFwcGVkIHRvIHtAY29kZSBuYW1lfS4gSW4gYWdncmVnYXRlLCB0aGlzIGFsbG93cyB2YWx1ZXMgdG8gYmUgYWRkZWQgdG8gYQorICAgICAqIG1hcHBpbmcgb25lIGF0IGEgdGltZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZSBhIHtAbGluayBKU09OT2JqZWN0fSwge0BsaW5rIEpTT05BcnJheX0sIFN0cmluZywgQm9vbGVhbiwKKyAgICAgKiAgICAgSW50ZWdlciwgTG9uZywgRG91YmxlLCB7QGxpbmsgI05VTEx9IG9yIG51bGwuIE1heSBub3QgYmUge0BsaW5rCisgICAgICogICAgIERvdWJsZSNpc05hTigpIE5hTnN9IG9yIHtAbGluayBEb3VibGUjaXNJbmZpbml0ZSgpIGluZmluaXRpZXN9LgorICAgICAqLworICAgIHB1YmxpYyBKU09OT2JqZWN0IGFjY3VtdWxhdGUoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBPYmplY3QgY3VycmVudCA9IG5hbWVWYWx1ZVBhaXJzLmdldChjaGVja05hbWUobmFtZSkpOworICAgICAgICBpZiAoY3VycmVudCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gcHV0KG5hbWUsIHZhbHVlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNoZWNrIGluIGFjY3VtdWxhdGUsIHNpbmNlIGFycmF5LnB1dChPYmplY3QpIGRvZXNuJ3QgZG8gYW55IGNoZWNraW5nCisgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIE51bWJlcikgeworICAgICAgICAgICAgSlNPTi5jaGVja0RvdWJsZSgoKE51bWJlcikgdmFsdWUpLmRvdWJsZVZhbHVlKCkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGN1cnJlbnQgaW5zdGFuY2VvZiBKU09OQXJyYXkpIHsKKyAgICAgICAgICAgIEpTT05BcnJheSBhcnJheSA9IChKU09OQXJyYXkpIGN1cnJlbnQ7CisgICAgICAgICAgICBhcnJheS5wdXQodmFsdWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgSlNPTkFycmF5IGFycmF5ID0gbmV3IEpTT05BcnJheSgpOworICAgICAgICAgICAgYXJyYXkucHV0KGN1cnJlbnQpOworICAgICAgICAgICAgYXJyYXkucHV0KHZhbHVlKTsKKyAgICAgICAgICAgIG5hbWVWYWx1ZVBhaXJzLnB1dChuYW1lLCBhcnJheSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgU3RyaW5nIGNoZWNrTmFtZShTdHJpbmcgbmFtZSkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSlNPTkV4Y2VwdGlvbigiTmFtZXMgbXVzdCBiZSBub24tbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIG5hbWVkIG1hcHBpbmcgaWYgaXQgZXhpc3RzOyBkb2VzIG5vdGhpbmcgb3RoZXJ3aXNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgcHJldmlvdXNseSBtYXBwZWQgYnkge0Bjb2RlIG5hbWV9LCBvciBudWxsIGlmIHRoZXJlIHdhcworICAgICAqICAgICBubyBzdWNoIG1hcHBpbmcuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCByZW1vdmUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIG5hbWVWYWx1ZVBhaXJzLnJlbW92ZShuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBvYmplY3QgaGFzIG5vIG1hcHBpbmcgZm9yIHtAY29kZSBuYW1lfSBvciBpZiBpdCBoYXMKKyAgICAgKiBhIG1hcHBpbmcgd2hvc2UgdmFsdWUgaXMge0BsaW5rICNOVUxMfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc051bGwoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgT2JqZWN0IHZhbHVlID0gbmFtZVZhbHVlUGFpcnMuZ2V0KG5hbWUpOworICAgICAgICByZXR1cm4gdmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSA9PSBOVUxMOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIG9iamVjdCBoYXMgYSBtYXBwaW5nIGZvciB7QGNvZGUgbmFtZX0uIFRoZSBtYXBwaW5nCisgICAgICogbWF5IGJlIHtAbGluayAjTlVMTH0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzKFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiBuYW1lVmFsdWVQYWlycy5jb250YWluc0tleShuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBtYXBwZWQgYnkge0Bjb2RlIG5hbWV9LgorICAgICAqCisgICAgICogQHRocm93cyBKU09ORXhjZXB0aW9uIGlmIG5vIHN1Y2ggbWFwcGluZyBleGlzdHMuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXQoU3RyaW5nIG5hbWUpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0IHJlc3VsdCA9IG5hbWVWYWx1ZVBhaXJzLmdldChuYW1lKTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSlNPTkV4Y2VwdGlvbigiTm8gdmFsdWUgZm9yICIgKyBuYW1lKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG1hcHBlZCBieSB7QGNvZGUgbmFtZX0sIG9yIG51bGwgaWYgbm8gc3VjaCBtYXBwaW5nCisgICAgICogZXhpc3RzLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3Qgb3B0KFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiBuYW1lVmFsdWVQYWlycy5nZXQobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgbWFwcGVkIGJ5IHtAY29kZSBuYW1lfSBpZiBpdCBleGlzdHMgYW5kIGlzIGEgYm9vbGVhbiBvcgorICAgICAqIGNhbiBiZSBjb2VyY2VkIHRvIGEgYm9vbGVhbi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSlNPTkV4Y2VwdGlvbiBpZiB0aGUgbWFwcGluZyBkb2Vzbid0IGV4aXN0IG9yIGNhbm5vdCBiZSBjb2VyY2VkCisgICAgICogICAgIHRvIGEgYm9vbGVhbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRCb29sZWFuKFN0cmluZyBuYW1lKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdCBvYmplY3QgPSBnZXQobmFtZSk7CisgICAgICAgIEJvb2xlYW4gcmVzdWx0ID0gSlNPTi50b0Jvb2xlYW4ob2JqZWN0KTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBKU09OLnR5cGVNaXNtYXRjaChuYW1lLCBvYmplY3QsICJib29sZWFuIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBtYXBwZWQgYnkge0Bjb2RlIG5hbWV9IGlmIGl0IGV4aXN0cyBhbmQgaXMgYSBib29sZWFuIG9yCisgICAgICogY2FuIGJlIGNvZXJjZWQgdG8gYSBib29sZWFuLiBSZXR1cm5zIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBvcHRCb29sZWFuKFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiBvcHRCb29sZWFuKG5hbWUsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBtYXBwZWQgYnkge0Bjb2RlIG5hbWV9IGlmIGl0IGV4aXN0cyBhbmQgaXMgYSBib29sZWFuIG9yCisgICAgICogY2FuIGJlIGNvZXJjZWQgdG8gYSBib29sZWFuLiBSZXR1cm5zIHtAY29kZSBmYWxsYmFja30gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG9wdEJvb2xlYW4oU3RyaW5nIG5hbWUsIGJvb2xlYW4gZmFsbGJhY2spIHsKKyAgICAgICAgT2JqZWN0IG9iamVjdCA9IG9wdChuYW1lKTsKKyAgICAgICAgQm9vbGVhbiByZXN1bHQgPSBKU09OLnRvQm9vbGVhbihvYmplY3QpOworICAgICAgICByZXR1cm4gcmVzdWx0ICE9IG51bGwgPyByZXN1bHQgOiBmYWxsYmFjazsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBtYXBwZWQgYnkge0Bjb2RlIG5hbWV9IGlmIGl0IGV4aXN0cyBhbmQgaXMgYSBkb3VibGUgb3IKKyAgICAgKiBjYW4gYmUgY29lcmNlZCB0byBhIGRvdWJsZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSlNPTkV4Y2VwdGlvbiBpZiB0aGUgbWFwcGluZyBkb2Vzbid0IGV4aXN0IG9yIGNhbm5vdCBiZSBjb2VyY2VkCisgICAgICogICAgIHRvIGEgZG91YmxlLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgZ2V0RG91YmxlKFN0cmluZyBuYW1lKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdCBvYmplY3QgPSBnZXQobmFtZSk7CisgICAgICAgIERvdWJsZSByZXN1bHQgPSBKU09OLnRvRG91YmxlKG9iamVjdCk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgSlNPTi50eXBlTWlzbWF0Y2gobmFtZSwgb2JqZWN0LCAiZG91YmxlIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBtYXBwZWQgYnkge0Bjb2RlIG5hbWV9IGlmIGl0IGV4aXN0cyBhbmQgaXMgYSBkb3VibGUgb3IKKyAgICAgKiBjYW4gYmUgY29lcmNlZCB0byBhIGRvdWJsZS4gUmV0dXJucyB7QGNvZGUgTmFOfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBvcHREb3VibGUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIG9wdERvdWJsZShuYW1lLCBEb3VibGUuTmFOKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBtYXBwZWQgYnkge0Bjb2RlIG5hbWV9IGlmIGl0IGV4aXN0cyBhbmQgaXMgYSBkb3VibGUgb3IKKyAgICAgKiBjYW4gYmUgY29lcmNlZCB0byBhIGRvdWJsZS4gUmV0dXJucyB7QGNvZGUgZmFsbGJhY2t9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIG9wdERvdWJsZShTdHJpbmcgbmFtZSwgZG91YmxlIGZhbGxiYWNrKSB7CisgICAgICAgIE9iamVjdCBvYmplY3QgPSBvcHQobmFtZSk7CisgICAgICAgIERvdWJsZSByZXN1bHQgPSBKU09OLnRvRG91YmxlKG9iamVjdCk7CisgICAgICAgIHJldHVybiByZXN1bHQgIT0gbnVsbCA/IHJlc3VsdCA6IGZhbGxiYWNrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG1hcHBlZCBieSB7QGNvZGUgbmFtZX0gaWYgaXQgZXhpc3RzIGFuZCBpcyBhbiBpbnQgb3IKKyAgICAgKiBjYW4gYmUgY29lcmNlZCB0byBhbiBpbnQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEpTT05FeGNlcHRpb24gaWYgdGhlIG1hcHBpbmcgZG9lc24ndCBleGlzdCBvciBjYW5ub3QgYmUgY29lcmNlZAorICAgICAqICAgICB0byBhbiBpbnQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRJbnQoU3RyaW5nIG5hbWUpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0IG9iamVjdCA9IGdldChuYW1lKTsKKyAgICAgICAgSW50ZWdlciByZXN1bHQgPSBKU09OLnRvSW50ZWdlcihvYmplY3QpOworICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IEpTT04udHlwZU1pc21hdGNoKG5hbWUsIG9iamVjdCwgImludCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgbWFwcGVkIGJ5IHtAY29kZSBuYW1lfSBpZiBpdCBleGlzdHMgYW5kIGlzIGFuIGludCBvcgorICAgICAqIGNhbiBiZSBjb2VyY2VkIHRvIGFuIGludC4gUmV0dXJucyAwIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IG9wdEludChTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gb3B0SW50KG5hbWUsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG1hcHBlZCBieSB7QGNvZGUgbmFtZX0gaWYgaXQgZXhpc3RzIGFuZCBpcyBhbiBpbnQgb3IKKyAgICAgKiBjYW4gYmUgY29lcmNlZCB0byBhbiBpbnQuIFJldHVybnMge0Bjb2RlIGZhbGxiYWNrfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGludCBvcHRJbnQoU3RyaW5nIG5hbWUsIGludCBmYWxsYmFjaykgeworICAgICAgICBPYmplY3Qgb2JqZWN0ID0gb3B0KG5hbWUpOworICAgICAgICBJbnRlZ2VyIHJlc3VsdCA9IEpTT04udG9JbnRlZ2VyKG9iamVjdCk7CisgICAgICAgIHJldHVybiByZXN1bHQgIT0gbnVsbCA/IHJlc3VsdCA6IGZhbGxiYWNrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG1hcHBlZCBieSB7QGNvZGUgbmFtZX0gaWYgaXQgZXhpc3RzIGFuZCBpcyBhIGxvbmcgb3IKKyAgICAgKiBjYW4gYmUgY29lcmNlZCB0byBhIGxvbmcuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEpTT05FeGNlcHRpb24gaWYgdGhlIG1hcHBpbmcgZG9lc24ndCBleGlzdCBvciBjYW5ub3QgYmUgY29lcmNlZAorICAgICAqICAgICB0byBhIGxvbmcuCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0TG9uZyhTdHJpbmcgbmFtZSkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBPYmplY3Qgb2JqZWN0ID0gZ2V0KG5hbWUpOworICAgICAgICBMb25nIHJlc3VsdCA9IEpTT04udG9Mb25nKG9iamVjdCk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgSlNPTi50eXBlTWlzbWF0Y2gobmFtZSwgb2JqZWN0LCAibG9uZyIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgbWFwcGVkIGJ5IHtAY29kZSBuYW1lfSBpZiBpdCBleGlzdHMgYW5kIGlzIGEgbG9uZyBvcgorICAgICAqIGNhbiBiZSBjb2VyY2VkIHRvIGEgbG9uZy4gUmV0dXJucyAwIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBvcHRMb25nKFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiBvcHRMb25nKG5hbWUsIDBMKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBtYXBwZWQgYnkge0Bjb2RlIG5hbWV9IGlmIGl0IGV4aXN0cyBhbmQgaXMgYSBsb25nIG9yCisgICAgICogY2FuIGJlIGNvZXJjZWQgdG8gYSBsb25nLiBSZXR1cm5zIHtAY29kZSBmYWxsYmFja30gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIG9wdExvbmcoU3RyaW5nIG5hbWUsIGxvbmcgZmFsbGJhY2spIHsKKyAgICAgICAgT2JqZWN0IG9iamVjdCA9IG9wdChuYW1lKTsKKyAgICAgICAgTG9uZyByZXN1bHQgPSBKU09OLnRvTG9uZyhvYmplY3QpOworICAgICAgICByZXR1cm4gcmVzdWx0ICE9IG51bGwgPyByZXN1bHQgOiBmYWxsYmFjazsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBtYXBwZWQgYnkge0Bjb2RlIG5hbWV9IGlmIGl0IGV4aXN0cywgY29lcmNpbmcgaXQgaWYKKyAgICAgKiBuZWNlc3NhcnkuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEpTT05FeGNlcHRpb24gaWYgbm8gc3VjaCBtYXBwaW5nIGV4aXN0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFN0cmluZyhTdHJpbmcgbmFtZSkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBPYmplY3Qgb2JqZWN0ID0gZ2V0KG5hbWUpOworICAgICAgICBTdHJpbmcgcmVzdWx0ID0gSlNPTi50b1N0cmluZyhvYmplY3QpOworICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IEpTT04udHlwZU1pc21hdGNoKG5hbWUsIG9iamVjdCwgIlN0cmluZyIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgbWFwcGVkIGJ5IHtAY29kZSBuYW1lfSBpZiBpdCBleGlzdHMsIGNvZXJjaW5nIGl0IGlmCisgICAgICogbmVjZXNzYXJ5LiBSZXR1cm5zIHRoZSBlbXB0eSBzdHJpbmcgaWYgbm8gc3VjaCBtYXBwaW5nIGV4aXN0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIG9wdFN0cmluZyhTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gb3B0U3RyaW5nKG5hbWUsICIiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBtYXBwZWQgYnkge0Bjb2RlIG5hbWV9IGlmIGl0IGV4aXN0cywgY29lcmNpbmcgaXQgaWYKKyAgICAgKiBuZWNlc3NhcnkuIFJldHVybnMge0Bjb2RlIGZhbGxiYWNrfSBpZiBubyBzdWNoIG1hcHBpbmcgZXhpc3RzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgb3B0U3RyaW5nKFN0cmluZyBuYW1lLCBTdHJpbmcgZmFsbGJhY2spIHsKKyAgICAgICAgT2JqZWN0IG9iamVjdCA9IG9wdChuYW1lKTsKKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IEpTT04udG9TdHJpbmcob2JqZWN0KTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdCAhPSBudWxsID8gcmVzdWx0IDogZmFsbGJhY2s7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgbWFwcGVkIGJ5IHtAY29kZSBuYW1lfSBpZiBpdCBleGlzdHMgYW5kIGlzIGEge0Bjb2RlCisgICAgICogSlNPTkFycmF5fS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSlNPTkV4Y2VwdGlvbiBpZiB0aGUgbWFwcGluZyBkb2Vzbid0IGV4aXN0IG9yIGlzIG5vdCBhIHtAY29kZQorICAgICAqICAgICBKU09OQXJyYXl9LgorICAgICAqLworICAgIHB1YmxpYyBKU09OQXJyYXkgZ2V0SlNPTkFycmF5KFN0cmluZyBuYW1lKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdCBvYmplY3QgPSBnZXQobmFtZSk7CisgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBKU09OQXJyYXkpIHsKKyAgICAgICAgICAgIHJldHVybiAoSlNPTkFycmF5KSBvYmplY3Q7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBKU09OLnR5cGVNaXNtYXRjaChuYW1lLCBvYmplY3QsICJKU09OQXJyYXkiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG1hcHBlZCBieSB7QGNvZGUgbmFtZX0gaWYgaXQgZXhpc3RzIGFuZCBpcyBhIHtAY29kZQorICAgICAqIEpTT05BcnJheX0uIFJldHVybnMgbnVsbCBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIEpTT05BcnJheSBvcHRKU09OQXJyYXkoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgT2JqZWN0IG9iamVjdCA9IG9wdChuYW1lKTsKKyAgICAgICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIEpTT05BcnJheSA/IChKU09OQXJyYXkpIG9iamVjdCA6IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgbWFwcGVkIGJ5IHtAY29kZSBuYW1lfSBpZiBpdCBleGlzdHMgYW5kIGlzIGEge0Bjb2RlCisgICAgICogSlNPTk9iamVjdH0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEpTT05FeGNlcHRpb24gaWYgdGhlIG1hcHBpbmcgZG9lc24ndCBleGlzdCBvciBpcyBub3QgYSB7QGNvZGUKKyAgICAgKiAgICAgSlNPTk9iamVjdH0uCisgICAgICovCisgICAgcHVibGljIEpTT05PYmplY3QgZ2V0SlNPTk9iamVjdChTdHJpbmcgbmFtZSkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBPYmplY3Qgb2JqZWN0ID0gZ2V0KG5hbWUpOworICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgSlNPTk9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIChKU09OT2JqZWN0KSBvYmplY3Q7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBKU09OLnR5cGVNaXNtYXRjaChuYW1lLCBvYmplY3QsICJKU09OT2JqZWN0Iik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBtYXBwZWQgYnkge0Bjb2RlIG5hbWV9IGlmIGl0IGV4aXN0cyBhbmQgaXMgYSB7QGNvZGUKKyAgICAgKiBKU09OT2JqZWN0fS4gUmV0dXJucyBudWxsIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTk9iamVjdCBvcHRKU09OT2JqZWN0KFN0cmluZyBuYW1lKSB7CisgICAgICAgIE9iamVjdCBvYmplY3QgPSBvcHQobmFtZSk7CisgICAgICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBKU09OT2JqZWN0ID8gKEpTT05PYmplY3QpIG9iamVjdCA6IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSB3aXRoIHRoZSB2YWx1ZXMgY29ycmVzcG9uZGluZyB0byB7QGNvZGUgbmFtZXN9LiBUaGUKKyAgICAgKiBhcnJheSBjb250YWlucyBudWxsIGZvciBuYW1lcyB0aGF0IGFyZW4ndCBtYXBwZWQuIFRoaXMgbWV0aG9kIHJldHVybnMKKyAgICAgKiBudWxsIGlmIHtAY29kZSBuYW1lc30gaXMgZWl0aGVyIG51bGwgb3IgZW1wdHkuCisgICAgICovCisgICAgcHVibGljIEpTT05BcnJheSB0b0pTT05BcnJheShKU09OQXJyYXkgbmFtZXMpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTkFycmF5IHJlc3VsdCA9IG5ldyBKU09OQXJyYXkoKTsKKyAgICAgICAgaWYgKG5hbWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGludCBsZW5ndGggPSBuYW1lcy5sZW5ndGgoKTsKKyAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IEpTT04udG9TdHJpbmcobmFtZXMub3B0KGkpKTsKKyAgICAgICAgICAgIHJlc3VsdC5wdXQob3B0KG5hbWUpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igb2YgdGhlIHtAY29kZSBTdHJpbmd9IG5hbWVzIGluIHRoaXMgb2JqZWN0LiBUaGUKKyAgICAgKiByZXR1cm5lZCBpdGVyYXRvciBzdXBwb3J0cyB7QGxpbmsgSXRlcmF0b3IjcmVtb3ZlKCkgcmVtb3ZlfSwgd2hpY2ggd2lsbAorICAgICAqIHJlbW92ZSB0aGUgY29ycmVzcG9uZGluZyBtYXBwaW5nIGZyb20gdGhpcyBvYmplY3QuIElmIHRoaXMgb2JqZWN0IGlzCisgICAgICogbW9kaWZpZWQgYWZ0ZXIgdGhlIGl0ZXJhdG9yIGlzIHJldHVybmVkLCB0aGUgaXRlcmF0b3IncyBiZWhhdmlvciBpcworICAgICAqIHVuZGVmaW5lZC4gVGhlIG9yZGVyIG9mIHRoZSBrZXlzIGlzIHVuZGVmaW5lZC4KKyAgICAgKi8KKyAgICAvKiBSZXR1cm4gYSByYXcgdHlwZSBmb3IgQVBJIGNvbXBhdGliaWxpdHkgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3Iga2V5cygpIHsKKyAgICAgICAgcmV0dXJuIG5hbWVWYWx1ZVBhaXJzLmtleVNldCgpLml0ZXJhdG9yKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIHRoZSBzdHJpbmcgbmFtZXMgaW4gdGhpcyBvYmplY3QuIFRoaXMgbWV0aG9kCisgICAgICogcmV0dXJucyBudWxsIGlmIHRoaXMgb2JqZWN0IGNvbnRhaW5zIG5vIG1hcHBpbmdzLgorICAgICAqLworICAgIHB1YmxpYyBKU09OQXJyYXkgbmFtZXMoKSB7CisgICAgICAgIHJldHVybiBuYW1lVmFsdWVQYWlycy5pc0VtcHR5KCkKKyAgICAgICAgICAgICAgICA/IG51bGwKKyAgICAgICAgICAgICAgICA6IG5ldyBKU09OQXJyYXkobmV3IEFycmF5TGlzdDxTdHJpbmc+KG5hbWVWYWx1ZVBhaXJzLmtleVNldCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlcyB0aGlzIG9iamVjdCBhcyBhIGNvbXBhY3QgSlNPTiBzdHJpbmcsIHN1Y2ggYXM6CisgICAgICogPHByZT57InF1ZXJ5IjoiUGl6emEiLCJsb2NhdGlvbnMiOls5NDA0Myw5MDIxMF19PC9wcmU+CisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBKU09OU3RyaW5nZXIgc3RyaW5nZXIgPSBuZXcgSlNPTlN0cmluZ2VyKCk7CisgICAgICAgICAgICB3cml0ZVRvKHN0cmluZ2VyKTsKKyAgICAgICAgICAgIHJldHVybiBzdHJpbmdlci50b1N0cmluZygpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlcyB0aGlzIG9iamVjdCBhcyBhIGh1bWFuIHJlYWRhYmxlIEpTT04gc3RyaW5nIGZvciBkZWJ1Z2dpbmcsIHN1Y2gKKyAgICAgKiBhczoKKyAgICAgKiA8cHJlPgorICAgICAqIHsKKyAgICAgKiAgICAgInF1ZXJ5IjogIlBpenphIiwKKyAgICAgKiAgICAgImxvY2F0aW9ucyI6IFsKKyAgICAgKiAgICAgICAgIDk0MDQzLAorICAgICAqICAgICAgICAgOTAyMTAKKyAgICAgKiAgICAgXQorICAgICAqIH08L3ByZT4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRlbnRTcGFjZXMgdGhlIG51bWJlciBvZiBzcGFjZXMgdG8gaW5kZW50IGZvciBlYWNoIGxldmVsIG9mCisgICAgICogICAgIG5lc3RpbmcuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZyhpbnQgaW5kZW50U3BhY2VzKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05TdHJpbmdlciBzdHJpbmdlciA9IG5ldyBKU09OU3RyaW5nZXIoaW5kZW50U3BhY2VzKTsKKyAgICAgICAgd3JpdGVUbyhzdHJpbmdlcik7CisgICAgICAgIHJldHVybiBzdHJpbmdlci50b1N0cmluZygpOworICAgIH0KKworICAgIHZvaWQgd3JpdGVUbyhKU09OU3RyaW5nZXIgc3RyaW5nZXIpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgc3RyaW5nZXIub2JqZWN0KCk7CisgICAgICAgIGZvciAoTWFwLkVudHJ5PFN0cmluZywgT2JqZWN0PiBlbnRyeSA6IG5hbWVWYWx1ZVBhaXJzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIHN0cmluZ2VyLmtleShlbnRyeS5nZXRLZXkoKSkudmFsdWUoZW50cnkuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgc3RyaW5nZXIuZW5kT2JqZWN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlcyB0aGUgbnVtYmVyIGFzIGEgSlNPTiBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbnVtYmVyIGEgZmluaXRlIHZhbHVlLiBNYXkgbm90IGJlIHtAbGluayBEb3VibGUjaXNOYU4oKSBOYU5zfSBvcgorICAgICAqICAgICB7QGxpbmsgRG91YmxlI2lzSW5maW5pdGUoKSBpbmZpbml0aWVzfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBudW1iZXJUb1N0cmluZyhOdW1iZXIgbnVtYmVyKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChudW1iZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEpTT05FeGNlcHRpb24oIk51bWJlciBtdXN0IGJlIG5vbi1udWxsIik7CisgICAgICAgIH0KKworICAgICAgICBkb3VibGUgZG91YmxlVmFsdWUgPSBudW1iZXIuZG91YmxlVmFsdWUoKTsKKyAgICAgICAgSlNPTi5jaGVja0RvdWJsZShkb3VibGVWYWx1ZSk7CisKKyAgICAgICAgLy8gdGhlIG9yaWdpbmFsIHJldHVybnMgIi0wIiBpbnN0ZWFkIG9mICItMC4wIiBmb3IgbmVnYXRpdmUgemVybworICAgICAgICBpZiAobnVtYmVyLmVxdWFscyhORUdBVElWRV9aRVJPKSkgeworICAgICAgICAgICAgcmV0dXJuICItMCI7CisgICAgICAgIH0KKworICAgICAgICBsb25nIGxvbmdWYWx1ZSA9IG51bWJlci5sb25nVmFsdWUoKTsKKyAgICAgICAgaWYgKGRvdWJsZVZhbHVlID09IChkb3VibGUpIGxvbmdWYWx1ZSkgeworICAgICAgICAgICAgcmV0dXJuIExvbmcudG9TdHJpbmcobG9uZ1ZhbHVlKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBudW1iZXIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmNvZGVzIHtAY29kZSBkYXRhfSBhcyBhIEpTT04gc3RyaW5nLiBUaGlzIGFwcGxpZXMgcXVvdGVzIGFuZCBhbnkKKyAgICAgKiBuZWNlc3NhcnkgY2hhcmFjdGVyIGVzY2FwaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGEgdGhlIHN0cmluZyB0byBlbmNvZGUuIE51bGwgd2lsbCBiZSBpbnRlcnByZXRlZCBhcyBhbiBlbXB0eQorICAgICAqICAgICBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgcXVvdGUoU3RyaW5nIGRhdGEpIHsKKyAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuICJcIlwiIjsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgSlNPTlN0cmluZ2VyIHN0cmluZ2VyID0gbmV3IEpTT05TdHJpbmdlcigpOworICAgICAgICAgICAgc3RyaW5nZXIub3BlbihKU09OU3RyaW5nZXIuU2NvcGUuTlVMTCwgIiIpOworICAgICAgICAgICAgc3RyaW5nZXIudmFsdWUoZGF0YSk7CisgICAgICAgICAgICBzdHJpbmdlci5jbG9zZShKU09OU3RyaW5nZXIuU2NvcGUuTlVMTCwgSlNPTlN0cmluZ2VyLlNjb3BlLk5VTEwsICIiKTsKKyAgICAgICAgICAgIHJldHVybiBzdHJpbmdlci50b1N0cmluZygpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvanNvbi9zcmMvbWFpbi9qYXZhL29yZy9qc29uL0pTT05TdHJpbmdlci5qYXZhIGIvanNvbi9zcmMvbWFpbi9qYXZhL29yZy9qc29uL0pTT05TdHJpbmdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRkM2IyYTcKLS0tIC9kZXYvbnVsbAorKysgYi9qc29uL3NyYy9tYWluL2phdmEvb3JnL2pzb24vSlNPTlN0cmluZ2VyLmphdmEKQEAgLTAsMCArMSw0MzIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5qc29uOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvLyBOb3RlOiB0aGlzIGNsYXNzIHdhcyB3cml0dGVuIHdpdGhvdXQgaW5zcGVjdGluZyB0aGUgbm9uLWZyZWUgb3JnLmpzb24gc291cmNlY29kZS4KKworLyoqCisgKiBJbXBsZW1lbnRzIHtAbGluayBKU09OT2JqZWN0I3RvU3RyaW5nfSBhbmQge0BsaW5rIEpTT05BcnJheSN0b1N0cmluZ30uIE1vc3QKKyAqIGFwcGxpY2F0aW9uIGRldmVsb3BlcnMgc2hvdWxkIHVzZSB0aG9zZSBtZXRob2RzIGRpcmVjdGx5IGFuZCBkaXNyZWdhcmQgdGhpcworICogQVBJLiBGb3IgZXhhbXBsZTo8cHJlPgorICogSlNPTk9iamVjdCBvYmplY3QgPSAuLi4KKyAqIFN0cmluZyBqc29uID0gb2JqZWN0LnRvU3RyaW5nKCk7PC9wcmU+CisgKgorICogPHA+U3RyaW5nZXJzIG9ubHkgZW5jb2RlIHdlbGwtZm9ybWVkIEpTT04gc3RyaW5ncy4gSW4gcGFydGljdWxhcjoKKyAqIDx1bD4KKyAqICAgPGxpPlRoZSBzdHJpbmdlciBtdXN0IGhhdmUgZXhhY3RseSBvbmUgdG9wLWxldmVsIGFycmF5IG9yIG9iamVjdC4KKyAqICAgPGxpPkxleGljYWwgc2NvcGVzIG11c3QgYmUgYmFsYW5jZWQ6IGV2ZXJ5IGNhbGwgdG8ge0BsaW5rICNhcnJheX0gbXVzdAorICogICAgICAgaGF2ZSBhIG1hdGNoaW5nIGNhbGwgdG8ge0BsaW5rICNlbmRBcnJheX0gYW5kIGV2ZXJ5IGNhbGwgdG8ge0BsaW5rCisgKiAgICAgICAjb2JqZWN0fSBtdXN0IGhhdmUgYSBtYXRjaGluZyBjYWxsIHRvIHtAbGluayAjZW5kT2JqZWN0fS4KKyAqICAgPGxpPkFycmF5cyBtYXkgbm90IGNvbnRhaW4ga2V5cyAocHJvcGVydHkgbmFtZXMpLgorICogICA8bGk+T2JqZWN0cyBtdXN0IGFsdGVybmF0ZSBrZXlzIChwcm9wZXJ0eSBuYW1lcykgYW5kIHZhbHVlcy4KKyAqICAgPGxpPlZhbHVlcyBhcmUgaW5zZXJ0ZWQgd2l0aCBlaXRoZXIgbGl0ZXJhbCB7QGxpbmsgI3ZhbHVlKE9iamVjdCkgdmFsdWV9CisgKiAgICAgICBjYWxscywgb3IgYnkgbmVzdGluZyBhcnJheXMgb3Igb2JqZWN0cy4KKyAqIDwvdWw+CisgKiBDYWxscyB0aGF0IHdvdWxkIHJlc3VsdCBpbiBhIG1hbGZvcm1lZCBKU09OIHN0cmluZyB3aWxsIGZhaWwgd2l0aCBhCisgKiB7QGxpbmsgSlNPTkV4Y2VwdGlvbn0uCisgKgorICogPHA+VGhpcyBjbGFzcyBwcm92aWRlcyBubyBmYWNpbGl0eSBmb3IgcHJldHR5LXByaW50aW5nIChpZS4gaW5kZW50aW5nKQorICogb3V0cHV0LiBUbyBlbmNvZGUgaW5kZW50ZWQgb3V0cHV0LCB1c2Uge0BsaW5rIEpTT05PYmplY3QjdG9TdHJpbmcoaW50KX0gb3IKKyAqIHtAbGluayBKU09OQXJyYXkjdG9TdHJpbmcoaW50KX0uCisgKgorICogPHA+U29tZSBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlIEFQSSBzdXBwb3J0IGF0IG1vc3QgMjAgbGV2ZWxzIG9mIG5lc3RpbmcuCisgKiBBdHRlbXB0cyB0byBjcmVhdGUgbW9yZSB0aGFuIDIwIGxldmVscyBvZiBuZXN0aW5nIG1heSBmYWlsIHdpdGggYSB7QGxpbmsKKyAqIEpTT05FeGNlcHRpb259LgorICoKKyAqIDxwPkVhY2ggc3RyaW5nZXIgbWF5IGJlIHVzZWQgdG8gZW5jb2RlIGEgc2luZ2xlIHRvcCBsZXZlbCB2YWx1ZS4gSW5zdGFuY2VzIG9mCisgKiB0aGlzIGNsYXNzIGFyZSBub3QgdGhyZWFkIHNhZmUuIEFsdGhvdWdoIHRoaXMgY2xhc3MgaXMgbm9uZmluYWwsIGl0IHdhcyBub3QKKyAqIGRlc2lnbmVkIGZvciBpbmhlcml0YW5jZSBhbmQgc2hvdWxkIG5vdCBiZSBzdWJjbGFzc2VkLiBJbiBwYXJ0aWN1bGFyLAorICogc2VsZi11c2UgYnkgb3ZlcnJpZGVhYmxlIG1ldGhvZHMgaXMgbm90IHNwZWNpZmllZC4gU2VlIDxpPkVmZmVjdGl2ZSBKYXZhPC9pPgorICogSXRlbSAxNywgIkRlc2lnbiBhbmQgRG9jdW1lbnQgb3IgaW5oZXJpdGFuY2Ugb3IgZWxzZSBwcm9oaWJpdCBpdCIgZm9yIGZ1cnRoZXIKKyAqIGluZm9ybWF0aW9uLgorICovCitwdWJsaWMgY2xhc3MgSlNPTlN0cmluZ2VyIHsKKworICAgIC8qKiBUaGUgb3V0cHV0IGRhdGEsIGNvbnRhaW5pbmcgYXQgbW9zdCBvbmUgdG9wLWxldmVsIGFycmF5IG9yIG9iamVjdC4gKi8KKyAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIG91dCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisKKyAgICAvKioKKyAgICAgKiBMZXhpY2FsIHNjb3BpbmcgZWxlbWVudHMgd2l0aGluIHRoaXMgc3RyaW5nZXIsIG5lY2Vzc2FyeSB0byBpbnNlcnQgdGhlCisgICAgICogYXBwcm9wcmlhdGUgc2VwYXJhdG9yIGNoYXJhY3RlcnMgKGllLiBjb21tYXMgYW5kIGNvbG9ucykgYW5kIHRvIGRldGVjdAorICAgICAqIG5lc3RpbmcgZXJyb3JzLgorICAgICAqLworICAgIGVudW0gU2NvcGUgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBBbiBhcnJheSB3aXRoIG5vIGVsZW1lbnRzIHJlcXVpcmVzIG5vIHNlcGFyYXRvcnMgb3IgbmV3bGluZXMgYmVmb3JlCisgICAgICAgICAqIGl0IGlzIGNsb3NlZC4KKyAgICAgICAgICovCisgICAgICAgIEVNUFRZX0FSUkFZLAorCisgICAgICAgIC8qKgorICAgICAgICAgKiBBIGFycmF5IHdpdGggYXQgbGVhc3Qgb25lIHZhbHVlIHJlcXVpcmVzIGEgY29tbWEgYW5kIG5ld2xpbmUgYmVmb3JlCisgICAgICAgICAqIHRoZSBuZXh0IGVsZW1lbnQuCisgICAgICAgICAqLworICAgICAgICBOT05FTVBUWV9BUlJBWSwKKworICAgICAgICAvKioKKyAgICAgICAgICogQW4gb2JqZWN0IHdpdGggbm8ga2V5cyBvciB2YWx1ZXMgcmVxdWlyZXMgbm8gc2VwYXJhdG9ycyBvciBuZXdsaW5lcworICAgICAgICAgKiBiZWZvcmUgaXQgaXMgY2xvc2VkLgorICAgICAgICAgKi8KKyAgICAgICAgRU1QVFlfT0JKRUNULAorCisgICAgICAgIC8qKgorICAgICAgICAgKiBBbiBvYmplY3Qgd2hvc2UgbW9zdCByZWNlbnQgZWxlbWVudCBpcyBhIGtleS4gVGhlIG5leHQgZWxlbWVudCBtdXN0CisgICAgICAgICAqIGJlIGEgdmFsdWUuCisgICAgICAgICAqLworICAgICAgICBEQU5HTElOR19LRVksCisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEFuIG9iamVjdCB3aXRoIGF0IGxlYXN0IG9uZSBuYW1lL3ZhbHVlIHBhaXIgcmVxdWlyZXMgYSBjb21tYSBhbmQKKyAgICAgICAgICogbmV3bGluZSBiZWZvcmUgdGhlIG5leHQgZWxlbWVudC4KKyAgICAgICAgICovCisgICAgICAgIE5PTkVNUFRZX09CSkVDVCwKKworICAgICAgICAvKioKKyAgICAgICAgICogQSBzcGVjaWFsIGJyYWNrZXRsZXNzIGFycmF5IG5lZWRlZCBieSBKU09OU3RyaW5nZXIuam9pbigpIGFuZAorICAgICAgICAgKiBKU09OT2JqZWN0LnF1b3RlKCkgb25seS4gTm90IHVzZWQgZm9yIEpTT04gZW5jb2RpbmcuCisgICAgICAgICAqLworICAgICAgICBOVUxMLAorICAgIH0KKworICAgIC8qKgorICAgICAqIFVubGlrZSB0aGUgb3JpZ2luYWwgaW1wbGVtZW50YXRpb24sIHRoaXMgc3RhY2sgaXNuJ3QgbGltaXRlZCB0byAyMAorICAgICAqIGxldmVscyBvZiBuZXN0aW5nLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgTGlzdDxTY29wZT4gc3RhY2sgPSBuZXcgQXJyYXlMaXN0PFNjb3BlPigpOworCisgICAgLyoqCisgICAgICogQSBzdHJpbmcgY29udGFpbmluZyBhIGZ1bGwgc2V0IG9mIHNwYWNlcyBmb3IgYSBzaW5nbGUgbGV2ZWwgb2YKKyAgICAgKiBpbmRlbnRhdGlvbiwgb3IgbnVsbCBmb3Igbm8gcHJldHR5IHByaW50aW5nLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGluZGVudDsKKworICAgIHB1YmxpYyBKU09OU3RyaW5nZXIoKSB7CisgICAgICAgIGluZGVudCA9IG51bGw7CisgICAgfQorCisgICAgSlNPTlN0cmluZ2VyKGludCBpbmRlbnRTcGFjZXMpIHsKKyAgICAgICAgY2hhcltdIGluZGVudENoYXJzID0gbmV3IGNoYXJbaW5kZW50U3BhY2VzXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoaW5kZW50Q2hhcnMsICcgJyk7CisgICAgICAgIGluZGVudCA9IG5ldyBTdHJpbmcoaW5kZW50Q2hhcnMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEJlZ2lucyBlbmNvZGluZyBhIG5ldyBhcnJheS4gRWFjaCBjYWxsIHRvIHRoaXMgbWV0aG9kIG11c3QgYmUgcGFpcmVkIHdpdGgKKyAgICAgKiBhIGNhbGwgdG8ge0BsaW5rICNlbmRBcnJheX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgc3RyaW5nZXIuCisgICAgICovCisgICAgcHVibGljIEpTT05TdHJpbmdlciBhcnJheSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG9wZW4oU2NvcGUuRU1QVFlfQVJSQVksICJbIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5kcyBlbmNvZGluZyB0aGUgY3VycmVudCBhcnJheS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBzdHJpbmdlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTlN0cmluZ2VyIGVuZEFycmF5KCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICByZXR1cm4gY2xvc2UoU2NvcGUuRU1QVFlfQVJSQVksIFNjb3BlLk5PTkVNUFRZX0FSUkFZLCAiXSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEJlZ2lucyBlbmNvZGluZyBhIG5ldyBvYmplY3QuIEVhY2ggY2FsbCB0byB0aGlzIG1ldGhvZCBtdXN0IGJlIHBhaXJlZAorICAgICAqIHdpdGggYSBjYWxsIHRvIHtAbGluayAjZW5kT2JqZWN0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBzdHJpbmdlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTlN0cmluZ2VyIG9iamVjdCgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG9wZW4oU2NvcGUuRU1QVFlfT0JKRUNULCAieyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuZHMgZW5jb2RpbmcgdGhlIGN1cnJlbnQgb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIHN0cmluZ2VyLgorICAgICAqLworICAgIHB1YmxpYyBKU09OU3RyaW5nZXIgZW5kT2JqZWN0KCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICByZXR1cm4gY2xvc2UoU2NvcGUuRU1QVFlfT0JKRUNULCBTY29wZS5OT05FTVBUWV9PQkpFQ1QsICJ9Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW50ZXJzIGEgbmV3IHNjb3BlIGJ5IGFwcGVuZGluZyBhbnkgbmVjZXNzYXJ5IHdoaXRlc3BhY2UgYW5kIHRoZSBnaXZlbgorICAgICAqIGJyYWNrZXQuCisgICAgICovCisgICAgSlNPTlN0cmluZ2VyIG9wZW4oU2NvcGUgZW1wdHksIFN0cmluZyBvcGVuQnJhY2tldCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBpZiAoc3RhY2suaXNFbXB0eSgpICYmIG91dC5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBKU09ORXhjZXB0aW9uKCJOZXN0aW5nIHByb2JsZW06IG11bHRpcGxlIHRvcC1sZXZlbCByb290cyIpOworICAgICAgICB9CisgICAgICAgIGJlZm9yZVZhbHVlKCk7CisgICAgICAgIHN0YWNrLmFkZChlbXB0eSk7CisgICAgICAgIG91dC5hcHBlbmQob3BlbkJyYWNrZXQpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhlIGN1cnJlbnQgc2NvcGUgYnkgYXBwZW5kaW5nIGFueSBuZWNlc3Nhcnkgd2hpdGVzcGFjZSBhbmQgdGhlCisgICAgICogZ2l2ZW4gYnJhY2tldC4KKyAgICAgKi8KKyAgICBKU09OU3RyaW5nZXIgY2xvc2UoU2NvcGUgZW1wdHksIFNjb3BlIG5vbmVtcHR5LCBTdHJpbmcgY2xvc2VCcmFja2V0KSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIFNjb3BlIGNvbnRleHQgPSBwZWVrKCk7CisgICAgICAgIGlmIChjb250ZXh0ICE9IG5vbmVtcHR5ICYmIGNvbnRleHQgIT0gZW1wdHkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBKU09ORXhjZXB0aW9uKCJOZXN0aW5nIHByb2JsZW0iKTsKKyAgICAgICAgfQorCisgICAgICAgIHN0YWNrLnJlbW92ZShzdGFjay5zaXplKCkgLSAxKTsKKyAgICAgICAgaWYgKGNvbnRleHQgPT0gbm9uZW1wdHkpIHsKKyAgICAgICAgICAgIG5ld2xpbmUoKTsKKyAgICAgICAgfQorICAgICAgICBvdXQuYXBwZW5kKGNsb3NlQnJhY2tldCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9uIHRoZSB0b3Agb2YgdGhlIHN0YWNrLgorICAgICAqLworICAgIHByaXZhdGUgU2NvcGUgcGVlaygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHN0YWNrLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEpTT05FeGNlcHRpb24oIk5lc3RpbmcgcHJvYmxlbSIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzdGFjay5nZXQoc3RhY2suc2l6ZSgpIC0gMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwbGFjZSB0aGUgdmFsdWUgb24gdGhlIHRvcCBvZiB0aGUgc3RhY2sgd2l0aCB0aGUgZ2l2ZW4gdmFsdWUuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlcGxhY2VUb3AoU2NvcGUgdG9wT2ZTdGFjaykgeworICAgICAgICBzdGFjay5zZXQoc3RhY2suc2l6ZSgpIC0gMSwgdG9wT2ZTdGFjayk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlcyB7QGNvZGUgdmFsdWV9LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlIGEge0BsaW5rIEpTT05PYmplY3R9LCB7QGxpbmsgSlNPTkFycmF5fSwgU3RyaW5nLCBCb29sZWFuLAorICAgICAqICAgICBJbnRlZ2VyLCBMb25nLCBEb3VibGUgb3IgbnVsbC4gTWF5IG5vdCBiZSB7QGxpbmsgRG91YmxlI2lzTmFOKCkgTmFOc30KKyAgICAgKiAgICAgb3Ige0BsaW5rIERvdWJsZSNpc0luZmluaXRlKCkgaW5maW5pdGllc30uCisgICAgICogQHJldHVybiB0aGlzIHN0cmluZ2VyLgorICAgICAqLworICAgIHB1YmxpYyBKU09OU3RyaW5nZXIgdmFsdWUoT2JqZWN0IHZhbHVlKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzdGFjay5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBKU09ORXhjZXB0aW9uKCJOZXN0aW5nIHByb2JsZW0iKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEpTT05BcnJheSkgeworICAgICAgICAgICAgKChKU09OQXJyYXkpIHZhbHVlKS53cml0ZVRvKHRoaXMpOworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisKKyAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEpTT05PYmplY3QpIHsKKyAgICAgICAgICAgICgoSlNPTk9iamVjdCkgdmFsdWUpLndyaXRlVG8odGhpcyk7CisgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgfQorCisgICAgICAgIGJlZm9yZVZhbHVlKCk7CisKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwKKyAgICAgICAgICAgICAgICB8fCB2YWx1ZSBpbnN0YW5jZW9mIEJvb2xlYW4KKyAgICAgICAgICAgICAgICB8fCB2YWx1ZSA9PSBKU09OT2JqZWN0Lk5VTEwpIHsKKyAgICAgICAgICAgIG91dC5hcHBlbmQodmFsdWUpOworCisgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBOdW1iZXIpIHsKKyAgICAgICAgICAgIG91dC5hcHBlbmQoSlNPTk9iamVjdC5udW1iZXJUb1N0cmluZygoTnVtYmVyKSB2YWx1ZSkpOworCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzdHJpbmcodmFsdWUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmNvZGVzIHtAY29kZSB2YWx1ZX0gdG8gdGhpcyBzdHJpbmdlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBzdHJpbmdlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgSlNPTlN0cmluZ2VyIHZhbHVlKGJvb2xlYW4gdmFsdWUpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHN0YWNrLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEpTT05FeGNlcHRpb24oIk5lc3RpbmcgcHJvYmxlbSIpOworICAgICAgICB9CisgICAgICAgIGJlZm9yZVZhbHVlKCk7CisgICAgICAgIG91dC5hcHBlbmQodmFsdWUpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmNvZGVzIHtAY29kZSB2YWx1ZX0gdG8gdGhpcyBzdHJpbmdlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZSBhIGZpbml0ZSB2YWx1ZS4gTWF5IG5vdCBiZSB7QGxpbmsgRG91YmxlI2lzTmFOKCkgTmFOc30gb3IKKyAgICAgKiAgICAge0BsaW5rIERvdWJsZSNpc0luZmluaXRlKCkgaW5maW5pdGllc30uCisgICAgICogQHJldHVybiB0aGlzIHN0cmluZ2VyLgorICAgICAqLworICAgIHB1YmxpYyBKU09OU3RyaW5nZXIgdmFsdWUoZG91YmxlIHZhbHVlKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzdGFjay5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBKU09ORXhjZXB0aW9uKCJOZXN0aW5nIHByb2JsZW0iKTsKKyAgICAgICAgfQorICAgICAgICBiZWZvcmVWYWx1ZSgpOworICAgICAgICBvdXQuYXBwZW5kKEpTT05PYmplY3QubnVtYmVyVG9TdHJpbmcodmFsdWUpKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlcyB7QGNvZGUgdmFsdWV9IHRvIHRoaXMgc3RyaW5nZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgc3RyaW5nZXIuCisgICAgICovCisgICAgcHVibGljIEpTT05TdHJpbmdlciB2YWx1ZShsb25nIHZhbHVlKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzdGFjay5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBKU09ORXhjZXB0aW9uKCJOZXN0aW5nIHByb2JsZW0iKTsKKyAgICAgICAgfQorICAgICAgICBiZWZvcmVWYWx1ZSgpOworICAgICAgICBvdXQuYXBwZW5kKHZhbHVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHN0cmluZyhTdHJpbmcgdmFsdWUpIHsKKyAgICAgICAgb3V0LmFwcGVuZCgiXCIiKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDAsIGxlbmd0aCA9IHZhbHVlLmxlbmd0aCgpOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNoYXIgYyA9IHZhbHVlLmNoYXJBdChpKTsKKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIEZyb20gUkZDIDQ2MjcsICJBbGwgVW5pY29kZSBjaGFyYWN0ZXJzIG1heSBiZSBwbGFjZWQgd2l0aGluIHRoZQorICAgICAgICAgICAgICogcXVvdGF0aW9uIG1hcmtzIGV4Y2VwdCBmb3IgdGhlIGNoYXJhY3RlcnMgdGhhdCBtdXN0IGJlIGVzY2FwZWQ6CisgICAgICAgICAgICAgKiBxdW90YXRpb24gbWFyaywgcmV2ZXJzZSBzb2xpZHVzLCBhbmQgdGhlIGNvbnRyb2wgY2hhcmFjdGVycworICAgICAgICAgICAgICogKFUrMDAwMCB0aHJvdWdoIFUrMDAxRikuIgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBzd2l0Y2ggKGMpIHsKKyAgICAgICAgICAgICAgICBjYXNlICciJzoKKyAgICAgICAgICAgICAgICBjYXNlICdcXCc6CisgICAgICAgICAgICAgICAgY2FzZSAnLyc6CisgICAgICAgICAgICAgICAgICAgIG91dC5hcHBlbmQoJ1xcJykuYXBwZW5kKGMpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICAgIGNhc2UgJ1x0JzoKKyAgICAgICAgICAgICAgICAgICAgb3V0LmFwcGVuZCgiXFx0Iik7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICAgICAgY2FzZSAnXGInOgorICAgICAgICAgICAgICAgICAgICBvdXQuYXBwZW5kKCJcXGIiKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICBjYXNlICdcbic6CisgICAgICAgICAgICAgICAgICAgIG91dC5hcHBlbmQoIlxcbiIpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICAgIGNhc2UgJ1xyJzoKKyAgICAgICAgICAgICAgICAgICAgb3V0LmFwcGVuZCgiXFxyIik7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICAgICAgY2FzZSAnXGYnOgorICAgICAgICAgICAgICAgICAgICBvdXQuYXBwZW5kKCJcXGYiKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICBpZiAoYyA8PSAweDFGKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBvdXQuYXBwZW5kKFN0cmluZy5mb3JtYXQoIlxcdSUwNHgiLCAoaW50KSBjKSk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBvdXQuYXBwZW5kKGMpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgIH0KKyAgICAgICAgb3V0LmFwcGVuZCgiXCIiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgbmV3bGluZSgpIHsKKyAgICAgICAgaWYgKGluZGVudCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBvdXQuYXBwZW5kKCJcbiIpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN0YWNrLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICBvdXQuYXBwZW5kKGluZGVudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmNvZGVzIHRoZSBrZXkgKHByb3BlcnR5IG5hbWUpIHRvIHRoaXMgc3RyaW5nZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgZm9ydGhjb21pbmcgdmFsdWUuIE1heSBub3QgYmUgbnVsbC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgc3RyaW5nZXIuCisgICAgICovCisgICAgcHVibGljIEpTT05TdHJpbmdlciBrZXkoU3RyaW5nIG5hbWUpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEpTT05FeGNlcHRpb24oIk5hbWVzIG11c3QgYmUgbm9uLW51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBiZWZvcmVLZXkoKTsKKyAgICAgICAgc3RyaW5nKG5hbWUpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIGFueSBuZWNlc3Nhcnkgc2VwYXJhdG9ycyBhbmQgd2hpdGVzcGFjZSBiZWZvcmUgYSBuYW1lLiBBbHNvCisgICAgICogYWRqdXN0cyB0aGUgc3RhY2sgdG8gZXhwZWN0IHRoZSBrZXkncyB2YWx1ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYmVmb3JlS2V5KCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBTY29wZSBjb250ZXh0ID0gcGVlaygpOworICAgICAgICBpZiAoY29udGV4dCA9PSBTY29wZS5OT05FTVBUWV9PQkpFQ1QpIHsgLy8gZmlyc3QgaW4gb2JqZWN0CisgICAgICAgICAgICBvdXQuYXBwZW5kKCcsJyk7CisgICAgICAgIH0gZWxzZSBpZiAoY29udGV4dCAhPSBTY29wZS5FTVBUWV9PQkpFQ1QpIHsgLy8gbm90IGluIGFuIG9iamVjdCEKKyAgICAgICAgICAgIHRocm93IG5ldyBKU09ORXhjZXB0aW9uKCJOZXN0aW5nIHByb2JsZW0iKTsKKyAgICAgICAgfQorICAgICAgICBuZXdsaW5lKCk7CisgICAgICAgIHJlcGxhY2VUb3AoU2NvcGUuREFOR0xJTkdfS0VZKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIGFueSBuZWNlc3Nhcnkgc2VwYXJhdG9ycyBhbmQgd2hpdGVzcGFjZSBiZWZvcmUgYSBsaXRlcmFsIHZhbHVlLAorICAgICAqIGlubGluZSBhcnJheSwgb3IgaW5saW5lIG9iamVjdC4gQWxzbyBhZGp1c3RzIHRoZSBzdGFjayB0byBleHBlY3QgZWl0aGVyIGEKKyAgICAgKiBjbG9zaW5nIGJyYWNrZXQgb3IgYW5vdGhlciBlbGVtZW50LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBiZWZvcmVWYWx1ZSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHN0YWNrLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgU2NvcGUgY29udGV4dCA9IHBlZWsoKTsKKyAgICAgICAgaWYgKGNvbnRleHQgPT0gU2NvcGUuRU1QVFlfQVJSQVkpIHsgLy8gZmlyc3QgaW4gYXJyYXkKKyAgICAgICAgICAgIHJlcGxhY2VUb3AoU2NvcGUuTk9ORU1QVFlfQVJSQVkpOworICAgICAgICAgICAgbmV3bGluZSgpOworICAgICAgICB9IGVsc2UgaWYgKGNvbnRleHQgPT0gU2NvcGUuTk9ORU1QVFlfQVJSQVkpIHsgLy8gYW5vdGhlciBpbiBhcnJheQorICAgICAgICAgICAgb3V0LmFwcGVuZCgnLCcpOworICAgICAgICAgICAgbmV3bGluZSgpOworICAgICAgICB9IGVsc2UgaWYgKGNvbnRleHQgPT0gU2NvcGUuREFOR0xJTkdfS0VZKSB7IC8vIHZhbHVlIGZvciBrZXkKKyAgICAgICAgICAgIG91dC5hcHBlbmQoaW5kZW50ID09IG51bGwgPyAiOiIgOiAiOiAiKTsKKyAgICAgICAgICAgIHJlcGxhY2VUb3AoU2NvcGUuTk9ORU1QVFlfT0JKRUNUKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb250ZXh0ICE9IFNjb3BlLk5VTEwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBKU09ORXhjZXB0aW9uKCJOZXN0aW5nIHByb2JsZW0iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGVuY29kZWQgSlNPTiBzdHJpbmcuCisgICAgICoKKyAgICAgKiA8cD5JZiBpbnZva2VkIHdpdGggdW50ZXJtaW5hdGVkIGFycmF5cyBvciB1bmNsb3NlZCBvYmplY3RzLCB0aGlzIG1ldGhvZCdzCisgICAgICogcmV0dXJuIHZhbHVlIGlzIHVuZGVmaW5lZC4KKyAgICAgKgorICAgICAqIDxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gYWx0aG91Z2ggaXQgY29udHJhZGljdHMgdGhlIGdlbmVyYWwgY29udHJhY3QKKyAgICAgKiBvZiB7QGxpbmsgT2JqZWN0I3RvU3RyaW5nfSwgdGhpcyBtZXRob2QgcmV0dXJucyBudWxsIGlmIHRoZSBzdHJpbmdlcgorICAgICAqIGNvbnRhaW5zIG5vIGRhdGEuCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBvdXQubGVuZ3RoKCkgPT0gMCA/IG51bGwgOiBvdXQudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9qc29uL3NyYy9tYWluL2phdmEvb3JnL2pzb24vSlNPTlRva2VuZXIuamF2YSBiL2pzb24vc3JjL21haW4vamF2YS9vcmcvanNvbi9KU09OVG9rZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmViZmFiZTQKLS0tIC9kZXYvbnVsbAorKysgYi9qc29uL3NyYy9tYWluL2phdmEvb3JnL2pzb24vSlNPTlRva2VuZXIuamF2YQpAQCAtMCwwICsxLDYxMSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmpzb247CisKKy8vIE5vdGU6IHRoaXMgY2xhc3Mgd2FzIHdyaXR0ZW4gd2l0aG91dCBpbnNwZWN0aW5nIHRoZSBub24tZnJlZSBvcmcuanNvbiBzb3VyY2Vjb2RlLgorCisvKioKKyAqIFBhcnNlcyBhIEpTT04gKDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzQ2MjcudHh0Ij5SRkMgNDYyNzwvYT4pCisgKiBlbmNvZGVkIHN0cmluZyBpbnRvIHRoZSBjb3JyZXNwb25kaW5nIG9iamVjdC4gTW9zdCBjbGllbnRzIG9mCisgKiB0aGlzIGNsYXNzIHdpbGwgdXNlIG9ubHkgbmVlZCB0aGUge0BsaW5rICNKU09OVG9rZW5lcihTdHJpbmcpIGNvbnN0cnVjdG9yfQorICogYW5kIHtAbGluayAjbmV4dFZhbHVlfSBtZXRob2QuIEV4YW1wbGUgdXNhZ2U6IDxwcmU+CisgKiBTdHJpbmcganNvbiA9ICJ7IgorICogICAgICAgICArICIgIFwicXVlcnlcIjogXCJQaXp6YVwiLCAiCisgKiAgICAgICAgICsgIiAgXCJsb2NhdGlvbnNcIjogWyA5NDA0MywgOTAyMTAgXSAiCisgKiAgICAgICAgICsgIn0iOworICoKKyAqIEpTT05PYmplY3Qgb2JqZWN0ID0gKEpTT05PYmplY3QpIG5ldyBKU09OVG9rZW5lcihqc29uKS5uZXh0VmFsdWUoKTsKKyAqIFN0cmluZyBxdWVyeSA9IG9iamVjdC5nZXRTdHJpbmcoInF1ZXJ5Iik7CisgKiBKU09OQXJyYXkgbG9jYXRpb25zID0gb2JqZWN0LmdldEpTT05BcnJheSgibG9jYXRpb25zIik7PC9wcmU+CisgKgorICogPHA+Rm9yIGJlc3QgaW50ZXJvcGVyYWJpbGl0eSBhbmQgcGVyZm9ybWFuY2UgdXNlIEpTT04gdGhhdCBjb21wbGllcyB3aXRoCisgKiBSRkMgNDYyNywgc3VjaCBhcyB0aGF0IGdlbmVyYXRlZCBieSB7QGxpbmsgSlNPTlN0cmluZ2VyfS4gRm9yIGxlZ2FjeSByZWFzb25zCisgKiB0aGlzIHBhcnNlciBpcyBsZW5pZW50LCBzbyBhIHN1Y2Nlc3NmdWwgcGFyc2UgZG9lcyBub3QgaW5kaWNhdGUgdGhhdCB0aGUKKyAqIGlucHV0IHN0cmluZyB3YXMgdmFsaWQgSlNPTi4gQWxsIG9mIHRoZSBmb2xsb3dpbmcgc3ludGF4IGVycm9ycyB3aWxsIGJlCisgKiBpZ25vcmVkOgorICogPHVsPgorICogICA8bGk+RW5kIG9mIGxpbmUgY29tbWVudHMgc3RhcnRpbmcgd2l0aCB7QGNvZGUgLy99IG9yIHtAY29kZSAjfSBhbmQgZW5kaW5nCisgKiAgICAgICB3aXRoIGEgbmV3bGluZSBjaGFyYWN0ZXIuCisgKiAgIDxsaT5DLXN0eWxlIGNvbW1lbnRzIHN0YXJ0aW5nIHdpdGgge0Bjb2RlIC8qfSBhbmQgZW5kaW5nIHdpdGgKKyAqICAgICAgIHtAY29kZSAqfXtAY29kZSAvfS4gU3VjaCBjb21tZW50cyBtYXkgbm90IGJlIG5lc3RlZC4KKyAqICAgPGxpPlN0cmluZ3MgdGhhdCBhcmUgdW5xdW90ZWQgb3Ige0Bjb2RlICdzaW5nbGUgcXVvdGVkJ30uCisgKiAgIDxsaT5IZXhhZGVjaW1hbCBpbnRlZ2VycyBwcmVmaXhlZCB3aXRoIHtAY29kZSAweH0gb3Ige0Bjb2RlIDBYfS4KKyAqICAgPGxpPk9jdGFsIGludGVnZXJzIHByZWZpeGVkIHdpdGgge0Bjb2RlIDB9LgorICogICA8bGk+QXJyYXkgZWxlbWVudHMgc2VwYXJhdGVkIGJ5IHtAY29kZSA7fS4KKyAqICAgPGxpPlVubmVjZXNzYXJ5IGFycmF5IHNlcGFyYXRvcnMuIFRoZXNlIGFyZSBpbnRlcnByZXRlZCBhcyBpZiBudWxsIHdhcyB0aGUKKyAqICAgICAgIG9taXR0ZWQgdmFsdWUuCisgKiAgIDxsaT5LZXktdmFsdWUgcGFpcnMgc2VwYXJhdGVkIGJ5IHtAY29kZSA9fSBvciB7QGNvZGUgPT59LgorICogICA8bGk+S2V5LXZhbHVlIHBhaXJzIHNlcGFyYXRlZCBieSB7QGNvZGUgO30uCisgKiA8L3VsPgorICoKKyAqIDxwPkVhY2ggdG9rZW5lciBtYXkgYmUgdXNlZCB0byBwYXJzZSBhIHNpbmdsZSBKU09OIHN0cmluZy4gSW5zdGFuY2VzIG9mIHRoaXMKKyAqIGNsYXNzIGFyZSBub3QgdGhyZWFkIHNhZmUuIEFsdGhvdWdoIHRoaXMgY2xhc3MgaXMgbm9uZmluYWwsIGl0IHdhcyBub3QKKyAqIGRlc2lnbmVkIGZvciBpbmhlcml0YW5jZSBhbmQgc2hvdWxkIG5vdCBiZSBzdWJjbGFzc2VkLiBJbiBwYXJ0aWN1bGFyLAorICogc2VsZi11c2UgYnkgb3ZlcnJpZGVhYmxlIG1ldGhvZHMgaXMgbm90IHNwZWNpZmllZC4gU2VlIDxpPkVmZmVjdGl2ZSBKYXZhPC9pPgorICogSXRlbSAxNywgIkRlc2lnbiBhbmQgRG9jdW1lbnQgb3IgaW5oZXJpdGFuY2Ugb3IgZWxzZSBwcm9oaWJpdCBpdCIgZm9yIGZ1cnRoZXIKKyAqIGluZm9ybWF0aW9uLgorICovCitwdWJsaWMgY2xhc3MgSlNPTlRva2VuZXIgeworCisgICAgLyoqIFRoZSBpbnB1dCBKU09OLiAqLworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGluOworCisgICAgLyoqCisgICAgICogVGhlIGluZGV4IG9mIHRoZSBuZXh0IGNoYXJhY3RlciB0byBiZSByZXR1cm5lZCBieSB7QGxpbmsgI25leHR9LiBXaGVuCisgICAgICogdGhlIGlucHV0IGlzIGV4aGF1c3RlZCwgdGhpcyBlcXVhbHMgdGhlIGlucHV0J3MgbGVuZ3RoLgorICAgICAqLworICAgIHByaXZhdGUgaW50IHBvczsKKworICAgIC8qKgorICAgICAqIEBwYXJhbSBpbiBKU09OIGVuY29kZWQgc3RyaW5nLiBOdWxsIGlzIG5vdCBwZXJtaXR0ZWQgYW5kIHdpbGwgeWllbGQgYQorICAgICAqICAgICB0b2tlbmVyIHRoYXQgdGhyb3dzIHtAY29kZSBOdWxsUG9pbnRlckV4Y2VwdGlvbnN9IHdoZW4gbWV0aG9kcyBhcmUKKyAgICAgKiAgICAgY2FsbGVkLgorICAgICAqLworICAgIHB1YmxpYyBKU09OVG9rZW5lcihTdHJpbmcgaW4pIHsKKyAgICAgICAgLy8gY29uc3VtZSBhbiBvcHRpb25hbCBieXRlIG9yZGVyIG1hcmsgKEJPTSkgaWYgaXQgZXhpc3RzCisgICAgICAgIGlmIChpbiAhPSBudWxsICYmIGluLnN0YXJ0c1dpdGgoIlx1ZmVmZiIpKSB7CisgICAgICAgICAgICBpbiA9IGluLnN1YnN0cmluZygxKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmluID0gaW47CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCB2YWx1ZSBmcm9tIHRoZSBpbnB1dC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSB7QGxpbmsgSlNPTk9iamVjdH0sIHtAbGluayBKU09OQXJyYXl9LCBTdHJpbmcsIEJvb2xlYW4sCisgICAgICogICAgIEludGVnZXIsIExvbmcsIERvdWJsZSBvciB7QGxpbmsgSlNPTk9iamVjdCNOVUxMfS4KKyAgICAgKiBAdGhyb3dzIEpTT05FeGNlcHRpb24gaWYgdGhlIGlucHV0IGlzIG1hbGZvcm1lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IG5leHRWYWx1ZSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGMgPSBuZXh0Q2xlYW5JbnRlcm5hbCgpOworICAgICAgICBzd2l0Y2ggKGMpIHsKKyAgICAgICAgICAgIGNhc2UgLTE6CisgICAgICAgICAgICAgICAgdGhyb3cgc3ludGF4RXJyb3IoIkVuZCBvZiBpbnB1dCIpOworCisgICAgICAgICAgICBjYXNlICd7JzoKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVhZE9iamVjdCgpOworCisgICAgICAgICAgICBjYXNlICdbJzoKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVhZEFycmF5KCk7CisKKyAgICAgICAgICAgIGNhc2UgJ1wnJzoKKyAgICAgICAgICAgIGNhc2UgJyInOgorICAgICAgICAgICAgICAgIHJldHVybiBuZXh0U3RyaW5nKChjaGFyKSBjKTsKKworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICBwb3MtLTsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVhZExpdGVyYWwoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgaW50IG5leHRDbGVhbkludGVybmFsKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICB3aGlsZSAocG9zIDwgaW4ubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgIGludCBjID0gaW4uY2hhckF0KHBvcysrKTsKKyAgICAgICAgICAgIHN3aXRjaCAoYykgeworICAgICAgICAgICAgICAgIGNhc2UgJ1x0JzoKKyAgICAgICAgICAgICAgICBjYXNlICcgJzoKKyAgICAgICAgICAgICAgICBjYXNlICdcbic6CisgICAgICAgICAgICAgICAgY2FzZSAnXHInOgorICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKworICAgICAgICAgICAgICAgIGNhc2UgJy8nOgorICAgICAgICAgICAgICAgICAgICBpZiAocG9zID09IGluLmxlbmd0aCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYzsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGNoYXIgcGVlayA9IGluLmNoYXJBdChwb3MpOworICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHBlZWspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJyonOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNraXAgYSAvKiBjLXN0eWxlIGNvbW1lbnQgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY29tbWVudEVuZCA9IGluLmluZGV4T2YoIiovIiwgcG9zKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWVudEVuZCA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBzeW50YXhFcnJvcigiVW50ZXJtaW5hdGVkIGNvbW1lbnQiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zID0gY29tbWVudEVuZCArIDI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJy8nOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNraXAgYSAvLyBlbmQtb2YtbGluZSBjb21tZW50CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zKys7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2tpcFRvRW5kT2ZMaW5lKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGM7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGNhc2UgJyMnOgorICAgICAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAgICAgKiBTa2lwIGEgIyBoYXNoIGVuZC1vZi1saW5lIGNvbW1lbnQuIFRoZSBKU09OIFJGQyBkb2Vzbid0CisgICAgICAgICAgICAgICAgICAgICAqIHNwZWNpZnkgdGhpcyBiZWhhdmlvciwgYnV0IGl0J3MgcmVxdWlyZWQgdG8gcGFyc2UKKyAgICAgICAgICAgICAgICAgICAgICogZXhpc3RpbmcgZG9jdW1lbnRzLiBTZWUgaHR0cDovL2IvMjU3MTQyMy4KKyAgICAgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgICAgIHNraXBUb0VuZE9mTGluZSgpOworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKworICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBjOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkdmFuY2VzIHRoZSBwb3NpdGlvbiB1bnRpbCBhZnRlciB0aGUgbmV4dCBuZXdsaW5lIGNoYXJhY3Rlci4gSWYgdGhlIGxpbmUKKyAgICAgKiBpcyB0ZXJtaW5hdGVkIGJ5ICJcclxuIiwgdGhlICdcbicgbXVzdCBiZSBjb25zdW1lZCBhcyB3aGl0ZXNwYWNlIGJ5IHRoZQorICAgICAqIGNhbGxlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2tpcFRvRW5kT2ZMaW5lKCkgeworICAgICAgICBmb3IgKDsgcG9zIDwgaW4ubGVuZ3RoKCk7IHBvcysrKSB7CisgICAgICAgICAgICBjaGFyIGMgPSBpbi5jaGFyQXQocG9zKTsKKyAgICAgICAgICAgIGlmIChjID09ICdccicgfHwgYyA9PSAnXG4nKSB7CisgICAgICAgICAgICAgICAgcG9zKys7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgdXAgdG8gYnV0IG5vdCBpbmNsdWRpbmcge0Bjb2RlIHF1b3RlfSwgdW5lc2NhcGluZyBhbnkKKyAgICAgKiBjaGFyYWN0ZXIgZXNjYXBlIHNlcXVlbmNlcyBlbmNvdW50ZXJlZCBhbG9uZyB0aGUgd2F5LiBUaGUgb3BlbmluZyBxdW90ZQorICAgICAqIHNob3VsZCBoYXZlIGFscmVhZHkgYmVlbiByZWFkLiBUaGlzIGNvbnN1bWVzIHRoZSBjbG9zaW5nIHF1b3RlLCBidXQgZG9lcworICAgICAqIG5vdCBpbmNsdWRlIGl0IGluIHRoZSByZXR1cm5lZCBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcXVvdGUgZWl0aGVyICcgb3IgIi4KKyAgICAgKiBAdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiBpZiBhbnkgdW5pY29kZSBlc2NhcGUgc2VxdWVuY2VzIGFyZQorICAgICAqICAgICBtYWxmb3JtZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBuZXh0U3RyaW5nKGNoYXIgcXVvdGUpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogRm9yIHN0cmluZ3MgdGhhdCBhcmUgZnJlZSBvZiBlc2NhcGUgc2VxdWVuY2VzLCB3ZSBjYW4ganVzdCBleHRyYWN0CisgICAgICAgICAqIHRoZSByZXN1bHQgYXMgYSBzdWJzdHJpbmcgb2YgdGhlIGlucHV0LiBCdXQgaWYgd2UgZW5jb3VudGVyIGFuIGVzY2FwZQorICAgICAgICAgKiBzZXF1ZW5jZSwgd2UgbmVlZCB0byB1c2UgYSBTdHJpbmdCdWlsZGVyIHRvIGNvbXBvc2UgdGhlIHJlc3VsdC4KKyAgICAgICAgICovCisgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVpbGRlciA9IG51bGw7CisKKyAgICAgICAgLyogdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgbm90IHlldCBhcHBlbmRlZCB0byB0aGUgYnVpbGRlci4gKi8KKyAgICAgICAgaW50IHN0YXJ0ID0gcG9zOworCisgICAgICAgIHdoaWxlIChwb3MgPCBpbi5sZW5ndGgoKSkgeworICAgICAgICAgICAgaW50IGMgPSBpbi5jaGFyQXQocG9zKyspOworICAgICAgICAgICAgaWYgKGMgPT0gcXVvdGUpIHsKKyAgICAgICAgICAgICAgICBpZiAoYnVpbGRlciA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGEgbmV3IHN0cmluZyBhdm9pZHMgbGVha2luZyBtZW1vcnkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoaW4uc3Vic3RyaW5nKHN0YXJ0LCBwb3MgLSAxKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoaW4sIHN0YXJ0LCBwb3MgLSAxKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChjID09ICdcXCcpIHsKKyAgICAgICAgICAgICAgICBpZiAocG9zID09IGluLmxlbmd0aCgpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IHN5bnRheEVycm9yKCJVbnRlcm1pbmF0ZWQgZXNjYXBlIHNlcXVlbmNlIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChidWlsZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKGluLCBzdGFydCwgcG9zIC0gMSk7CisgICAgICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQocmVhZEVzY2FwZUNoYXJhY3RlcigpKTsKKyAgICAgICAgICAgICAgICBzdGFydCA9IHBvczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRocm93IHN5bnRheEVycm9yKCJVbnRlcm1pbmF0ZWQgc3RyaW5nIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVW5lc2NhcGVzIHRoZSBjaGFyYWN0ZXIgaWRlbnRpZmllZCBieSB0aGUgY2hhcmFjdGVyIG9yIGNoYXJhY3RlcnMgdGhhdAorICAgICAqIGltbWVkaWF0ZWx5IGZvbGxvdyBhIGJhY2tzbGFzaC4gVGhlIGJhY2tzbGFzaCAnXCcgc2hvdWxkIGhhdmUgYWxyZWFkeQorICAgICAqIGJlZW4gcmVhZC4gVGhpcyBzdXBwb3J0cyBib3RoIHVuaWNvZGUgZXNjYXBlcyAidTAwMEEiIGFuZCB0d28tY2hhcmFjdGVyCisgICAgICogZXNjYXBlcyAiXG4iLgorICAgICAqCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24gaWYgYW55IHVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlcyBhcmUKKyAgICAgKiAgICAgbWFsZm9ybWVkLgorICAgICAqLworICAgIHByaXZhdGUgY2hhciByZWFkRXNjYXBlQ2hhcmFjdGVyKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBjaGFyIGVzY2FwZWQgPSBpbi5jaGFyQXQocG9zKyspOworICAgICAgICBzd2l0Y2ggKGVzY2FwZWQpIHsKKyAgICAgICAgICAgIGNhc2UgJ3UnOgorICAgICAgICAgICAgICAgIGlmIChwb3MgKyA0ID4gaW4ubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgc3ludGF4RXJyb3IoIlVudGVybWluYXRlZCBlc2NhcGUgc2VxdWVuY2UiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgU3RyaW5nIGhleCA9IGluLnN1YnN0cmluZyhwb3MsIHBvcyArIDQpOworICAgICAgICAgICAgICAgIHBvcyArPSA0OworICAgICAgICAgICAgICAgIHJldHVybiAoY2hhcikgSW50ZWdlci5wYXJzZUludChoZXgsIDE2KTsKKworICAgICAgICAgICAgY2FzZSAndCc6CisgICAgICAgICAgICAgICAgcmV0dXJuICdcdCc7CisKKyAgICAgICAgICAgIGNhc2UgJ2InOgorICAgICAgICAgICAgICAgIHJldHVybiAnXGInOworCisgICAgICAgICAgICBjYXNlICduJzoKKyAgICAgICAgICAgICAgICByZXR1cm4gJ1xuJzsKKworICAgICAgICAgICAgY2FzZSAncic6CisgICAgICAgICAgICAgICAgcmV0dXJuICdccic7CisKKyAgICAgICAgICAgIGNhc2UgJ2YnOgorICAgICAgICAgICAgICAgIHJldHVybiAnXGYnOworCisgICAgICAgICAgICBjYXNlICdcJyc6CisgICAgICAgICAgICBjYXNlICciJzoKKyAgICAgICAgICAgIGNhc2UgJ1xcJzoKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIGVzY2FwZWQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIG51bGwsIGJvb2xlYW4sIG51bWVyaWMgb3IgdW5xdW90ZWQgc3RyaW5nIGxpdGVyYWwgdmFsdWUuIE51bWVyaWMKKyAgICAgKiB2YWx1ZXMgd2lsbCBiZSByZXR1cm5lZCBhcyBhbiBJbnRlZ2VyLCBMb25nLCBvciBEb3VibGUsIGluIHRoYXQgb3JkZXIgb2YKKyAgICAgKiBwcmVmZXJlbmNlLgorICAgICAqLworICAgIHByaXZhdGUgT2JqZWN0IHJlYWRMaXRlcmFsKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbGl0ZXJhbCA9IG5leHRUb0ludGVybmFsKCJ7fVtdL1xcOiw9OyMgXHRcZiIpOworCisgICAgICAgIGlmIChsaXRlcmFsLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHRocm93IHN5bnRheEVycm9yKCJFeHBlY3RlZCBsaXRlcmFsIHZhbHVlIik7CisgICAgICAgIH0gZWxzZSBpZiAoIm51bGwiLmVxdWFsc0lnbm9yZUNhc2UobGl0ZXJhbCkpIHsKKyAgICAgICAgICAgIHJldHVybiBKU09OT2JqZWN0Lk5VTEw7CisgICAgICAgIH0gZWxzZSBpZiAoInRydWUiLmVxdWFsc0lnbm9yZUNhc2UobGl0ZXJhbCkpIHsKKyAgICAgICAgICAgIHJldHVybiBCb29sZWFuLlRSVUU7CisgICAgICAgIH0gZWxzZSBpZiAoImZhbHNlIi5lcXVhbHNJZ25vcmVDYXNlKGxpdGVyYWwpKSB7CisgICAgICAgICAgICByZXR1cm4gQm9vbGVhbi5GQUxTRTsKKyAgICAgICAgfQorCisgICAgICAgIC8qIHRyeSB0byBwYXJzZSBhcyBhbiBpbnRlZ3JhbCB0eXBlLi4uICovCisgICAgICAgIGlmIChsaXRlcmFsLmluZGV4T2YoJy4nKSA9PSAtMSkgeworICAgICAgICAgICAgaW50IGJhc2UgPSAxMDsKKyAgICAgICAgICAgIFN0cmluZyBudW1iZXIgPSBsaXRlcmFsOworICAgICAgICAgICAgaWYgKG51bWJlci5zdGFydHNXaXRoKCIweCIpIHx8IG51bWJlci5zdGFydHNXaXRoKCIwWCIpKSB7CisgICAgICAgICAgICAgICAgbnVtYmVyID0gbnVtYmVyLnN1YnN0cmluZygyKTsKKyAgICAgICAgICAgICAgICBiYXNlID0gMTY7CisgICAgICAgICAgICB9IGVsc2UgaWYgKG51bWJlci5zdGFydHNXaXRoKCIwIikgJiYgbnVtYmVyLmxlbmd0aCgpID4gMSkgeworICAgICAgICAgICAgICAgIG51bWJlciA9IG51bWJlci5zdWJzdHJpbmcoMSk7CisgICAgICAgICAgICAgICAgYmFzZSA9IDg7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGxvbmcgbG9uZ1ZhbHVlID0gTG9uZy5wYXJzZUxvbmcobnVtYmVyLCBiYXNlKTsKKyAgICAgICAgICAgICAgICBpZiAobG9uZ1ZhbHVlIDw9IEludGVnZXIuTUFYX1ZBTFVFICYmIGxvbmdWYWx1ZSA+PSBJbnRlZ2VyLk1JTl9WQUxVRSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGludCkgbG9uZ1ZhbHVlOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBsb25nVmFsdWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAqIFRoaXMgb25seSBoYXBwZW5zIGZvciBpbnRlZ3JhbCBudW1iZXJzIGdyZWF0ZXIgdGhhbgorICAgICAgICAgICAgICAgICAqIExvbmcuTUFYX1ZBTFVFLCBudW1iZXJzIGluIGV4cG9uZW50aWFsIGZvcm0gKDVlLTEwKSBhbmQKKyAgICAgICAgICAgICAgICAgKiB1bnF1b3RlZCBzdHJpbmdzLiBGYWxsIHRocm91Z2ggdG8gdHJ5IGZsb2F0aW5nIHBvaW50LgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyogLi4ubmV4dCB0cnkgdG8gcGFyc2UgYXMgYSBmbG9hdGluZyBwb2ludC4uLiAqLworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIERvdWJsZS52YWx1ZU9mKGxpdGVyYWwpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLyogLi4uIGZpbmFsbHkgZ2l2ZSB1cC4gV2UgaGF2ZSBhbiB1bnF1b3RlZCBzdHJpbmcgKi8KKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcobGl0ZXJhbCk7IC8vIGEgbmV3IHN0cmluZyBhdm9pZHMgbGVha2luZyBtZW1vcnkKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgdXAgdG8gYnV0IG5vdCBpbmNsdWRpbmcgYW55IG9mIHRoZSBnaXZlbiBjaGFyYWN0ZXJzIG9yCisgICAgICogYSBuZXdsaW5lIGNoYXJhY3Rlci4gVGhpcyBkb2VzIG5vdCBjb25zdW1lIHRoZSBleGNsdWRlZCBjaGFyYWN0ZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgbmV4dFRvSW50ZXJuYWwoU3RyaW5nIGV4Y2x1ZGVkKSB7CisgICAgICAgIGludCBzdGFydCA9IHBvczsKKyAgICAgICAgZm9yICg7IHBvcyA8IGluLmxlbmd0aCgpOyBwb3MrKykgeworICAgICAgICAgICAgY2hhciBjID0gaW4uY2hhckF0KHBvcyk7CisgICAgICAgICAgICBpZiAoYyA9PSAnXHInIHx8IGMgPT0gJ1xuJyB8fCBleGNsdWRlZC5pbmRleE9mKGMpICE9IC0xKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGluLnN1YnN0cmluZyhzdGFydCwgcG9zKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW4uc3Vic3RyaW5nKHN0YXJ0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHNlcXVlbmNlIG9mIGtleS92YWx1ZSBwYWlycyBhbmQgdGhlIHRyYWlsaW5nIGNsb3NpbmcgYnJhY2UgJ30nIG9mCisgICAgICogYW4gb2JqZWN0LiBUaGUgb3BlbmluZyBicmFjZSAneycgc2hvdWxkIGhhdmUgYWxyZWFkeSBiZWVuIHJlYWQuCisgICAgICovCisgICAgcHJpdmF0ZSBKU09OT2JqZWN0IHJlYWRPYmplY3QoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05PYmplY3QgcmVzdWx0ID0gbmV3IEpTT05PYmplY3QoKTsKKworICAgICAgICAvKiBQZWVrIHRvIHNlZSBpZiB0aGlzIGlzIHRoZSBlbXB0eSBvYmplY3QuICovCisgICAgICAgIGludCBmaXJzdCA9IG5leHRDbGVhbkludGVybmFsKCk7CisgICAgICAgIGlmIChmaXJzdCA9PSAnfScpIHsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0gZWxzZSBpZiAoZmlyc3QgIT0gLTEpIHsKKyAgICAgICAgICAgIHBvcy0tOworICAgICAgICB9CisKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIE9iamVjdCBuYW1lID0gbmV4dFZhbHVlKCk7CisgICAgICAgICAgICBpZiAoIShuYW1lIGluc3RhbmNlb2YgU3RyaW5nKSkgeworICAgICAgICAgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgc3ludGF4RXJyb3IoIk5hbWVzIGNhbm5vdCBiZSBudWxsIik7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgc3ludGF4RXJyb3IoIk5hbWVzIG11c3QgYmUgc3RyaW5ncywgYnV0ICIgKyBuYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGlzIG9mIHR5cGUgIiArIG5hbWUuZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIEV4cGVjdCB0aGUgbmFtZS92YWx1ZSBzZXBhcmF0b3IgdG8gYmUgZWl0aGVyIGEgY29sb24gJzonLCBhbgorICAgICAgICAgICAgICogZXF1YWxzIHNpZ24gJz0nLCBvciBhbiBhcnJvdyAiPT4iLiBUaGUgbGFzdCB0d28gYXJlIGJvZ3VzIGJ1dCB3ZQorICAgICAgICAgICAgICogaW5jbHVkZSB0aGVtIGJlY2F1c2UgdGhhdCdzIHdoYXQgdGhlIG9yaWdpbmFsIGltcGxlbWVudGF0aW9uIGRpZC4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaW50IHNlcGFyYXRvciA9IG5leHRDbGVhbkludGVybmFsKCk7CisgICAgICAgICAgICBpZiAoc2VwYXJhdG9yICE9ICc6JyAmJiBzZXBhcmF0b3IgIT0gJz0nKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgc3ludGF4RXJyb3IoIkV4cGVjdGVkICc6JyBhZnRlciAiICsgbmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocG9zIDwgaW4ubGVuZ3RoKCkgJiYgaW4uY2hhckF0KHBvcykgPT0gJz4nKSB7CisgICAgICAgICAgICAgICAgcG9zKys7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJlc3VsdC5wdXQoKFN0cmluZykgbmFtZSwgbmV4dFZhbHVlKCkpOworCisgICAgICAgICAgICBzd2l0Y2ggKG5leHRDbGVhbkludGVybmFsKCkpIHsKKyAgICAgICAgICAgICAgICBjYXNlICd9JzoKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgICAgICBjYXNlICc7JzoKKyAgICAgICAgICAgICAgICBjYXNlICcsJzoKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgc3ludGF4RXJyb3IoIlVudGVybWluYXRlZCBvYmplY3QiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgc2VxdWVuY2Ugb2YgdmFsdWVzIGFuZCB0aGUgdHJhaWxpbmcgY2xvc2luZyBicmFjZSAnXScgb2YgYW4KKyAgICAgKiBhcnJheS4gVGhlIG9wZW5pbmcgYnJhY2UgJ1snIHNob3VsZCBoYXZlIGFscmVhZHkgYmVlbiByZWFkLiBOb3RlIHRoYXQKKyAgICAgKiAiW10iIHlpZWxkcyBhbiBlbXB0eSBhcnJheSwgYnV0ICJbLF0iIHJldHVybnMgYSB0d28tZWxlbWVudCBhcnJheQorICAgICAqIGVxdWl2YWxlbnQgdG8gIltudWxsLG51bGxdIi4KKyAgICAgKi8KKyAgICBwcml2YXRlIEpTT05BcnJheSByZWFkQXJyYXkoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05BcnJheSByZXN1bHQgPSBuZXcgSlNPTkFycmF5KCk7CisKKyAgICAgICAgLyogdG8gY292ZXIgaW5wdXQgdGhhdCBlbmRzIHdpdGggIixdIi4gKi8KKyAgICAgICAgYm9vbGVhbiBoYXNUcmFpbGluZ1NlcGFyYXRvciA9IGZhbHNlOworCisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBzd2l0Y2ggKG5leHRDbGVhbkludGVybmFsKCkpIHsKKyAgICAgICAgICAgICAgICBjYXNlIC0xOgorICAgICAgICAgICAgICAgICAgICB0aHJvdyBzeW50YXhFcnJvcigiVW50ZXJtaW5hdGVkIGFycmF5Iik7CisgICAgICAgICAgICAgICAgY2FzZSAnXSc6CisgICAgICAgICAgICAgICAgICAgIGlmIChoYXNUcmFpbGluZ1NlcGFyYXRvcikgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1dChudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgICAgIGNhc2UgJywnOgorICAgICAgICAgICAgICAgIGNhc2UgJzsnOgorICAgICAgICAgICAgICAgICAgICAvKiBBIHNlcGFyYXRvciB3aXRob3V0IGEgdmFsdWUgZmlyc3QgbWVhbnMgIm51bGwiLiAqLworICAgICAgICAgICAgICAgICAgICByZXN1bHQucHV0KG51bGwpOworICAgICAgICAgICAgICAgICAgICBoYXNUcmFpbGluZ1NlcGFyYXRvciA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgIHBvcy0tOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXN1bHQucHV0KG5leHRWYWx1ZSgpKTsKKworICAgICAgICAgICAgc3dpdGNoIChuZXh0Q2xlYW5JbnRlcm5hbCgpKSB7CisgICAgICAgICAgICAgICAgY2FzZSAnXSc6CisgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICAgICAgY2FzZSAnLCc6CisgICAgICAgICAgICAgICAgY2FzZSAnOyc6CisgICAgICAgICAgICAgICAgICAgIGhhc1RyYWlsaW5nU2VwYXJhdG9yID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgc3ludGF4RXJyb3IoIlVudGVybWluYXRlZCBhcnJheSIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBleGNlcHRpb24gY29udGFpbmluZyB0aGUgZ2l2ZW4gbWVzc2FnZSBwbHVzIHRoZSBjdXJyZW50CisgICAgICogcG9zaXRpb24gYW5kIHRoZSBlbnRpcmUgaW5wdXQgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBKU09ORXhjZXB0aW9uIHN5bnRheEVycm9yKFN0cmluZyBtZXNzYWdlKSB7CisgICAgICAgIHJldHVybiBuZXcgSlNPTkV4Y2VwdGlvbihtZXNzYWdlICsgdGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQgdGhlIGVudGlyZSBpbnB1dCBzdHJpbmcuCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIC8vIGNvbnNpc3RlbnQgd2l0aCB0aGUgb3JpZ2luYWwgaW1wbGVtZW50YXRpb24KKyAgICAgICAgcmV0dXJuICIgYXQgY2hhcmFjdGVyICIgKyBwb3MgKyAiIG9mICIgKyBpbjsKKyAgICB9CisKKyAgICAvKgorICAgICAqIExlZ2FjeSBBUElzLgorICAgICAqCisgICAgICogTm9uZSBvZiB0aGUgbWV0aG9kcyBiZWxvdyBhcmUgb24gdGhlIGNyaXRpY2FsIHBhdGggb2YgcGFyc2luZyBKU09OCisgICAgICogZG9jdW1lbnRzLiBUaGV5IGV4aXN0IG9ubHkgYmVjYXVzZSB0aGV5IHdlcmUgZXhwb3NlZCBieSB0aGUgb3JpZ2luYWwKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBhbmQgbWF5IGJlIHVzZWQgYnkgc29tZSBjbGllbnRzLgorICAgICAqLworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIHVudGlsIHRoZSBpbnB1dCBoYXMgYmVlbiBleGhhdXN0ZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbW9yZSgpIHsKKyAgICAgICAgcmV0dXJuIHBvcyA8IGluLmxlbmd0aCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgYXZhaWxhYmxlIGNoYXJhY3Rlciwgb3IgdGhlIG51bGwgY2hhcmFjdGVyICdcMCcgaWYgYWxsCisgICAgICogaW5wdXQgaGFzIGJlZW4gZXhoYXVzdGVkLiBUaGUgcmV0dXJuIHZhbHVlIG9mIHRoaXMgbWV0aG9kIGlzIGFtYmlndW91cworICAgICAqIGZvciBKU09OIHN0cmluZ3MgdGhhdCBjb250YWluIHRoZSBjaGFyYWN0ZXIgJ1wwJy4KKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhciBuZXh0KCkgeworICAgICAgICByZXR1cm4gcG9zIDwgaW4ubGVuZ3RoKCkgPyBpbi5jaGFyQXQocG9zKyspIDogJ1wwJzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGF2YWlsYWJsZSBjaGFyYWN0ZXIgaWYgaXQgZXF1YWxzIHtAY29kZSBjfS4gT3RoZXJ3aXNlIGFuCisgICAgICogZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhciBuZXh0KGNoYXIgYykgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBjaGFyIHJlc3VsdCA9IG5leHQoKTsKKyAgICAgICAgaWYgKHJlc3VsdCAhPSBjKSB7CisgICAgICAgICAgICB0aHJvdyBzeW50YXhFcnJvcigiRXhwZWN0ZWQgIiArIGMgKyAiIGJ1dCB3YXMgIiArIHJlc3VsdCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGNoYXJhY3RlciB0aGF0IGlzIG5vdCB3aGl0ZXNwYWNlIGFuZCBkb2VzIG5vdCBiZWxvbmcgdG8KKyAgICAgKiBhIGNvbW1lbnQuIElmIHRoZSBpbnB1dCBpcyBleGhhdXN0ZWQgYmVmb3JlIHN1Y2ggYSBjaGFyYWN0ZXIgY2FuIGJlCisgICAgICogZm91bmQsIHRoZSBudWxsIGNoYXJhY3RlciAnXDAnIGlzIHJldHVybmVkLiBUaGUgcmV0dXJuIHZhbHVlIG9mIHRoaXMKKyAgICAgKiBtZXRob2QgaXMgYW1iaWd1b3VzIGZvciBKU09OIHN0cmluZ3MgdGhhdCBjb250YWluIHRoZSBjaGFyYWN0ZXIgJ1wwJy4KKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhciBuZXh0Q2xlYW4oKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGludCBuZXh0Q2xlYW5JbnQgPSBuZXh0Q2xlYW5JbnRlcm5hbCgpOworICAgICAgICByZXR1cm4gbmV4dENsZWFuSW50ID09IC0xID8gJ1wwJyA6IChjaGFyKSBuZXh0Q2xlYW5JbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCB7QGNvZGUgbGVuZ3RofSBjaGFyYWN0ZXJzIG9mIHRoZSBpbnB1dC4KKyAgICAgKgorICAgICAqIDxwPlRoZSByZXR1cm5lZCBzdHJpbmcgc2hhcmVzIGl0cyBiYWNraW5nIGNoYXJhY3RlciBhcnJheSB3aXRoIHRoaXMKKyAgICAgKiB0b2tlbmVyJ3MgaW5wdXQgc3RyaW5nLiBJZiBhIHJlZmVyZW5jZSB0byB0aGUgcmV0dXJuZWQgc3RyaW5nIG1heSBiZSBoZWxkCisgICAgICogaW5kZWZpbml0ZWx5LCB5b3Ugc2hvdWxkIHVzZSB7QGNvZGUgbmV3IFN0cmluZyhyZXN1bHQpfSB0byBjb3B5IGl0IGZpcnN0CisgICAgICogdG8gYXZvaWQgbWVtb3J5IGxlYWtzLgorICAgICAqCisgICAgICogQHRocm93cyBKU09ORXhjZXB0aW9uIGlmIHRoZSByZW1haW5pbmcgaW5wdXQgaXMgbm90IGxvbmcgZW5vdWdoIHRvCisgICAgICogICAgIHNhdGlzZnkgdGhpcyByZXF1ZXN0LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgbmV4dChpbnQgbGVuZ3RoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwb3MgKyBsZW5ndGggPiBpbi5sZW5ndGgoKSkgeworICAgICAgICAgICAgdGhyb3cgc3ludGF4RXJyb3IobGVuZ3RoICsgIiBpcyBvdXQgb2YgYm91bmRzIik7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGluLnN1YnN0cmluZyhwb3MsIHBvcyArIGxlbmd0aCk7CisgICAgICAgIHBvcyArPSBsZW5ndGg7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0BsaW5rIFN0cmluZyN0cmltIHRyaW1tZWR9IHN0cmluZyBob2xkaW5nIHRoZSBjaGFyYWN0ZXJzIHVwCisgICAgICogdG8gYnV0IG5vdCBpbmNsdWRpbmcgdGhlIGZpcnN0IG9mOgorICAgICAqIDx1bD4KKyAgICAgKiAgIDxsaT5hbnkgY2hhcmFjdGVyIGluIHtAY29kZSBleGNsdWRlZH0KKyAgICAgKiAgIDxsaT5hIG5ld2xpbmUgY2hhcmFjdGVyICdcbicKKyAgICAgKiAgIDxsaT5hIGNhcnJpYWdlIHJldHVybiAnXHInCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPlRoZSByZXR1cm5lZCBzdHJpbmcgc2hhcmVzIGl0cyBiYWNraW5nIGNoYXJhY3RlciBhcnJheSB3aXRoIHRoaXMKKyAgICAgKiB0b2tlbmVyJ3MgaW5wdXQgc3RyaW5nLiBJZiBhIHJlZmVyZW5jZSB0byB0aGUgcmV0dXJuZWQgc3RyaW5nIG1heSBiZSBoZWxkCisgICAgICogaW5kZWZpbml0ZWx5LCB5b3Ugc2hvdWxkIHVzZSB7QGNvZGUgbmV3IFN0cmluZyhyZXN1bHQpfSB0byBjb3B5IGl0IGZpcnN0CisgICAgICogdG8gYXZvaWQgbWVtb3J5IGxlYWtzLgorICAgICAqCisgICAgICogQHJldHVybiBhIHBvc3NpYmx5LWVtcHR5IHN0cmluZworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgbmV4dFRvKFN0cmluZyBleGNsdWRlZCkgeworICAgICAgICBpZiAoZXhjbHVkZWQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5leHRUb0ludGVybmFsKGV4Y2x1ZGVkKS50cmltKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgbmV4dFRvKFN0cmluZy52YWx1ZU9mKGV4Y2x1ZGVkKSl9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgbmV4dFRvKGNoYXIgZXhjbHVkZWQpIHsKKyAgICAgICAgcmV0dXJuIG5leHRUb0ludGVybmFsKFN0cmluZy52YWx1ZU9mKGV4Y2x1ZGVkKSkudHJpbSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkdmFuY2VzIHBhc3QgYWxsIGlucHV0IHVwIHRvIGFuZCBpbmNsdWRpbmcgdGhlIG5leHQgb2NjdXJyZW5jZSBvZgorICAgICAqIHtAY29kZSB0aHJ1fS4gSWYgdGhlIHJlbWFpbmluZyBpbnB1dCBkb2Vzbid0IGNvbnRhaW4ge0Bjb2RlIHRocnV9LCB0aGUKKyAgICAgKiBpbnB1dCBpcyBleGhhdXN0ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2tpcFBhc3QoU3RyaW5nIHRocnUpIHsKKyAgICAgICAgaW50IHRocnVTdGFydCA9IGluLmluZGV4T2YodGhydSwgcG9zKTsKKyAgICAgICAgcG9zID0gdGhydVN0YXJ0ID09IC0xID8gaW4ubGVuZ3RoKCkgOiAodGhydVN0YXJ0ICsgdGhydS5sZW5ndGgoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWR2YW5jZXMgcGFzdCBhbGwgaW5wdXQgdXAgdG8gYnV0IG5vdCBpbmNsdWRpbmcgdGhlIG5leHQgb2NjdXJyZW5jZSBvZgorICAgICAqIHtAY29kZSB0b30uIElmIHRoZSByZW1haW5pbmcgaW5wdXQgZG9lc24ndCBjb250YWluIHtAY29kZSB0b30sIHRoZSBpbnB1dAorICAgICAqIGlzIHVuY2hhbmdlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhciBza2lwVG8oY2hhciB0bykgeworICAgICAgICBpbnQgaW5kZXggPSBpbi5pbmRleE9mKHRvLCBwb3MpOworICAgICAgICBpZiAoaW5kZXggIT0gLTEpIHsKKyAgICAgICAgICAgIHBvcyA9IGluZGV4OworICAgICAgICAgICAgcmV0dXJuIHRvOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuICdcMCc7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVbnJlYWRzIHRoZSBtb3N0IHJlY2VudCBjaGFyYWN0ZXIgb2YgaW5wdXQuIElmIG5vIGlucHV0IGNoYXJhY3RlcnMgaGF2ZQorICAgICAqIGJlZW4gcmVhZCwgdGhlIGlucHV0IGlzIHVuY2hhbmdlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBiYWNrKCkgeworICAgICAgICBpZiAoLS1wb3MgPT0gLTEpIHsKKyAgICAgICAgICAgIHBvcyA9IDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbnRlZ2VyIFswLi4xNV0gdmFsdWUgZm9yIHRoZSBnaXZlbiBoZXggY2hhcmFjdGVyLCBvciAtMQorICAgICAqIGZvciBub24taGV4IGlucHV0LgorICAgICAqCisgICAgICogQHBhcmFtIGhleCBhIGNoYXJhY3RlciBpbiB0aGUgcmFuZ2VzIFswLTldLCBbQS1GXSBvciBbYS1mXS4gQW55IG90aGVyCisgICAgICogICAgIGNoYXJhY3RlciB3aWxsIHlpZWxkIGEgLTEgcmVzdWx0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGRlaGV4Y2hhcihjaGFyIGhleCkgeworICAgICAgICBpZiAoaGV4ID49ICcwJyAmJiBoZXggPD0gJzknKSB7CisgICAgICAgICAgICByZXR1cm4gaGV4IC0gJzAnOworICAgICAgICB9IGVsc2UgaWYgKGhleCA+PSAnQScgJiYgaGV4IDw9ICdGJykgeworICAgICAgICAgICAgcmV0dXJuIGhleCAtICdBJyArIDEwOworICAgICAgICB9IGVsc2UgaWYgKGhleCA+PSAnYScgJiYgaGV4IDw9ICdmJykgeworICAgICAgICAgICAgcmV0dXJuIGhleCAtICdhJyArIDEwOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvanNvbi9zcmMvdGVzdC9qYXZhL29yZy9qc29uL0pTT05BcnJheVRlc3QuamF2YSBiL2pzb24vc3JjL3Rlc3QvamF2YS9vcmcvanNvbi9KU09OQXJyYXlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWU3MmFmMgotLS0gL2Rldi9udWxsCisrKyBiL2pzb24vc3JjL3Rlc3QvamF2YS9vcmcvanNvbi9KU09OQXJyYXlUZXN0LmphdmEKQEAgLTAsMCArMSw1NDEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5qc29uOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRoaXMgYmxhY2sgYm94IHRlc3Qgd2FzIHdyaXR0ZW4gd2l0aG91dCBpbnNwZWN0aW5nIHRoZSBub24tZnJlZSBvcmcuanNvbiBzb3VyY2Vjb2RlLgorICovCitwdWJsaWMgY2xhc3MgSlNPTkFycmF5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eUFycmF5KCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OQXJyYXkgYXJyYXkgPSBuZXcgSlNPTkFycmF5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBhcnJheS5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgYXJyYXkuam9pbigiIEFORCAiKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcnJheS5nZXQoMCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcnJheS5nZXRCb29sZWFuKDApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygiW10iLCBhcnJheS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbXSIsIGFycmF5LnRvU3RyaW5nKDQpKTsKKworICAgICAgICAvLyBvdXQgb2YgYm91bmRzIGlzIGNvLW9wdGVkIHdpdGggZGVmYXVsdGluZworICAgICAgICBhc3NlcnRUcnVlKGFycmF5LmlzTnVsbCgwKSk7CisgICAgICAgIGFzc2VydE51bGwoYXJyYXkub3B0KDApKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoYXJyYXkub3B0Qm9vbGVhbigwKSk7CisgICAgICAgIGFzc2VydFRydWUoYXJyYXkub3B0Qm9vbGVhbigwLCB0cnVlKSk7CisKKyAgICAgICAgLy8gYm9ndXMgKGJ1dCBkb2N1bWVudGVkKSBiZWhhdmlvdXI6IHJldHVybnMgbnVsbCByYXRoZXIgdGhhbiBhbiBlbXB0eSBvYmplY3QhCisgICAgICAgIGFzc2VydE51bGwoYXJyYXkudG9KU09OT2JqZWN0KG5ldyBKU09OQXJyYXkoKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHNBbmRIYXNoQ29kZSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTkFycmF5IGEgPSBuZXcgSlNPTkFycmF5KCk7CisgICAgICAgIEpTT05BcnJheSBiID0gbmV3IEpTT05BcnJheSgpOworICAgICAgICBhc3NlcnRUcnVlKGEuZXF1YWxzKGIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlcXVhbHMoKSBub3QgY29uc2lzdGVudCB3aXRoIGhhc2hDb2RlKCkiLCBhLmhhc2hDb2RlKCksIGIuaGFzaENvZGUoKSk7CisKKyAgICAgICAgYS5wdXQodHJ1ZSk7CisgICAgICAgIGEucHV0KGZhbHNlKTsKKyAgICAgICAgYi5wdXQodHJ1ZSk7CisgICAgICAgIGIucHV0KGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhLmVxdWFscyhiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhhLmhhc2hDb2RlKCksIGIuaGFzaENvZGUoKSk7CisKKyAgICAgICAgYi5wdXQodHJ1ZSk7CisgICAgICAgIGFzc2VydEZhbHNlKGEuZXF1YWxzKGIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhLmhhc2hDb2RlKCkgIT0gYi5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qm9vbGVhbnMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05BcnJheSBhcnJheSA9IG5ldyBKU09OQXJyYXkoKTsKKyAgICAgICAgYXJyYXkucHV0KHRydWUpOworICAgICAgICBhcnJheS5wdXQoZmFsc2UpOworICAgICAgICBhcnJheS5wdXQoMiwgZmFsc2UpOworICAgICAgICBhcnJheS5wdXQoMywgZmFsc2UpOworICAgICAgICBhcnJheS5wdXQoMiwgdHJ1ZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiW3RydWUsZmFsc2UsdHJ1ZSxmYWxzZV0iLCBhcnJheS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGFycmF5Lmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJvb2xlYW4uVFJVRSwgYXJyYXkuZ2V0KDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJvb2xlYW4uRkFMU0UsIGFycmF5LmdldCgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhCb29sZWFuLlRSVUUsIGFycmF5LmdldCgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhCb29sZWFuLkZBTFNFLCBhcnJheS5nZXQoMykpOworICAgICAgICBhc3NlcnRGYWxzZShhcnJheS5pc051bGwoMCkpOworICAgICAgICBhc3NlcnRGYWxzZShhcnJheS5pc051bGwoMSkpOworICAgICAgICBhc3NlcnRGYWxzZShhcnJheS5pc051bGwoMikpOworICAgICAgICBhc3NlcnRGYWxzZShhcnJheS5pc051bGwoMykpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgYXJyYXkub3B0Qm9vbGVhbigwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgYXJyYXkub3B0Qm9vbGVhbigxLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBhcnJheS5vcHRCb29sZWFuKDIsIGZhbHNlKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgYXJyYXkub3B0Qm9vbGVhbigzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidHJ1ZSIsIGFycmF5LmdldFN0cmluZygwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZmFsc2UiLCBhcnJheS5nZXRTdHJpbmcoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRydWUiLCBhcnJheS5vcHRTdHJpbmcoMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZhbHNlIiwgYXJyYXkub3B0U3RyaW5nKDMsICJ4IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIltcbiAgICAgdHJ1ZSxcbiAgICAgZmFsc2UsXG4gICAgIHRydWUsXG4gICAgIGZhbHNlXG5dIiwgYXJyYXkudG9TdHJpbmcoNSkpOworCisgICAgICAgIEpTT05BcnJheSBvdGhlciA9IG5ldyBKU09OQXJyYXkoKTsKKyAgICAgICAgb3RoZXIucHV0KHRydWUpOworICAgICAgICBvdGhlci5wdXQoZmFsc2UpOworICAgICAgICBvdGhlci5wdXQodHJ1ZSk7CisgICAgICAgIG90aGVyLnB1dChmYWxzZSk7CisgICAgICAgIGFzc2VydFRydWUoYXJyYXkuZXF1YWxzKG90aGVyKSk7CisgICAgICAgIG90aGVyLnB1dCh0cnVlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoYXJyYXkuZXF1YWxzKG90aGVyKSk7CisKKyAgICAgICAgb3RoZXIgPSBuZXcgSlNPTkFycmF5KCk7CisgICAgICAgIG90aGVyLnB1dCgidHJ1ZSIpOworICAgICAgICBvdGhlci5wdXQoImZhbHNlIik7CisgICAgICAgIG90aGVyLnB1dCgidHJ1RSIpOworICAgICAgICBvdGhlci5wdXQoIkZBTFNFIik7CisgICAgICAgIGFzc2VydEZhbHNlKGFycmF5LmVxdWFscyhvdGhlcikpOworICAgICAgICBhc3NlcnRGYWxzZShvdGhlci5lcXVhbHMoYXJyYXkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIG90aGVyLmdldEJvb2xlYW4oMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIG90aGVyLm9wdEJvb2xlYW4oMSwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgb3RoZXIub3B0Qm9vbGVhbigyKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgb3RoZXIuZ2V0Qm9vbGVhbigzKSk7CisgICAgfQorCisgICAgLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD0xNjQxMQorICAgIHB1YmxpYyB2b2lkIHRlc3RDb2VyY2VTdHJpbmdUb0Jvb2xlYW4oKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05BcnJheSBhcnJheSA9IG5ldyBKU09OQXJyYXkoKTsKKyAgICAgICAgYXJyYXkucHV0KCJtYXliZSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXJyYXkuZ2V0Qm9vbGVhbigwKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgYXJyYXkub3B0Qm9vbGVhbigwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBhcnJheS5vcHRCb29sZWFuKDAsIHRydWUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TnVsbHMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05BcnJheSBhcnJheSA9IG5ldyBKU09OQXJyYXkoKTsKKyAgICAgICAgYXJyYXkucHV0KDMsIG51bGwpOworICAgICAgICBhcnJheS5wdXQoMCwgSlNPTk9iamVjdC5OVUxMKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGFycmF5Lmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbbnVsbCxudWxsLG51bGwsbnVsbF0iLCBhcnJheS50b1N0cmluZygpKTsKKworICAgICAgICAvLyB0aGVyZSdzIDIgd2F5cyB0byByZXByZXNlbnQgbnVsbDsgZWFjaCBiZWhhdmVzIGRpZmZlcmVudGx5IQorICAgICAgICBhc3NlcnRFcXVhbHMoSlNPTk9iamVjdC5OVUxMLCBhcnJheS5nZXQoMCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXJyYXkuZ2V0KDEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYXJyYXkuZ2V0KDIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYXJyYXkuZ2V0KDMpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoSlNPTk9iamVjdC5OVUxMLCBhcnJheS5vcHQoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgYXJyYXkub3B0KDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGFycmF5Lm9wdCgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBhcnJheS5vcHQoMykpOworICAgICAgICBhc3NlcnRUcnVlKGFycmF5LmlzTnVsbCgwKSk7CisgICAgICAgIGFzc2VydFRydWUoYXJyYXkuaXNOdWxsKDEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhcnJheS5pc051bGwoMikpOworICAgICAgICBhc3NlcnRUcnVlKGFycmF5LmlzTnVsbCgzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibnVsbCIsIGFycmF5Lm9wdFN0cmluZygwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgYXJyYXkub3B0U3RyaW5nKDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBhcnJheS5vcHRTdHJpbmcoMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGFycmF5Lm9wdFN0cmluZygzKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3VyIGJlaGF2aW91ciBpcyBxdWVzdGlvbmVkIGJ5IHRoaXMgYnVnOgorICAgICAqIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9NzI1NworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZU51bGxZaWVsZHNKU09OT2JqZWN0TnVsbCgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTkFycmF5IGFycmF5ID0gbmV3IEpTT05BcnJheSgiW1wibnVsbFwiLG51bGxdIik7CisgICAgICAgIGFycmF5LnB1dChudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJudWxsIiwgYXJyYXkuZ2V0KDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEpTT05PYmplY3QuTlVMTCwgYXJyYXkuZ2V0KDEpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFycmF5LmdldCgyKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJudWxsIiwgYXJyYXkuZ2V0U3RyaW5nKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJudWxsIiwgYXJyYXkuZ2V0U3RyaW5nKDEpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFycmF5LmdldFN0cmluZygyKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TnVtYmVycygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTkFycmF5IGFycmF5ID0gbmV3IEpTT05BcnJheSgpOworICAgICAgICBhcnJheS5wdXQoRG91YmxlLk1JTl9WQUxVRSk7CisgICAgICAgIGFycmF5LnB1dCg5MjIzMzcyMDM2ODU0Nzc1ODA2TCk7CisgICAgICAgIGFycmF5LnB1dChEb3VibGUuTUFYX1ZBTFVFKTsKKyAgICAgICAgYXJyYXkucHV0KC0wZCk7CisgICAgICAgIGFzc2VydEVxdWFscyg0LCBhcnJheS5sZW5ndGgoKSk7CisKKyAgICAgICAgLy8gdG9TdHJpbmcoKSBhbmQgZ2V0U3RyaW5nKGludCkgcmV0dXJuIGRpZmZlcmVudCB2YWx1ZXMgZm9yIC0wZAorICAgICAgICBhc3NlcnRFcXVhbHMoIls0LjlFLTMyNCw5MjIzMzcyMDM2ODU0Nzc1ODA2LDEuNzk3NjkzMTM0ODYyMzE1N0UzMDgsLTBdIiwgYXJyYXkudG9TdHJpbmcoKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5NSU5fVkFMVUUsIGFycmF5LmdldCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg5MjIzMzcyMDM2ODU0Nzc1ODA2TCwgYXJyYXkuZ2V0KDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5NQVhfVkFMVUUsIGFycmF5LmdldCgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMGQsIGFycmF5LmdldCgzKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuTUlOX1ZBTFVFLCBhcnJheS5nZXREb3VibGUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoOS4yMjMzNzIwMzY4NTQ3NzZFMTgsIGFycmF5LmdldERvdWJsZSgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuTUFYX1ZBTFVFLCBhcnJheS5nZXREb3VibGUoMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTBkLCBhcnJheS5nZXREb3VibGUoMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYXJyYXkuZ2V0TG9uZygwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg5MjIzMzcyMDM2ODU0Nzc1ODA2TCwgYXJyYXkuZ2V0TG9uZygxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhMb25nLk1BWF9WQUxVRSwgYXJyYXkuZ2V0TG9uZygyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBhcnJheS5nZXRMb25nKDMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGFycmF5LmdldEludCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMiwgYXJyYXkuZ2V0SW50KDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEludGVnZXIuTUFYX1ZBTFVFLCBhcnJheS5nZXRJbnQoMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYXJyYXkuZ2V0SW50KDMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5NSU5fVkFMVUUsIGFycmF5Lm9wdCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuTUlOX1ZBTFVFLCBhcnJheS5vcHREb3VibGUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYXJyYXkub3B0TG9uZygwLCAxTCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYXJyYXkub3B0SW50KDAsIDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI0LjlFLTMyNCIsIGFycmF5LmdldFN0cmluZygwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiOTIyMzM3MjAzNjg1NDc3NTgwNiIsIGFycmF5LmdldFN0cmluZygxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMS43OTc2OTMxMzQ4NjIzMTU3RTMwOCIsIGFycmF5LmdldFN0cmluZygyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLTAuMCIsIGFycmF5LmdldFN0cmluZygzKSk7CisKKyAgICAgICAgSlNPTkFycmF5IG90aGVyID0gbmV3IEpTT05BcnJheSgpOworICAgICAgICBvdGhlci5wdXQoRG91YmxlLk1JTl9WQUxVRSk7CisgICAgICAgIG90aGVyLnB1dCg5MjIzMzcyMDM2ODU0Nzc1ODA2TCk7CisgICAgICAgIG90aGVyLnB1dChEb3VibGUuTUFYX1ZBTFVFKTsKKyAgICAgICAgb3RoZXIucHV0KC0wZCk7CisgICAgICAgIGFzc2VydFRydWUoYXJyYXkuZXF1YWxzKG90aGVyKSk7CisgICAgICAgIG90aGVyLnB1dCgwLCAwTCk7CisgICAgICAgIGFzc2VydEZhbHNlKGFycmF5LmVxdWFscyhvdGhlcikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdHJpbmdzKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OQXJyYXkgYXJyYXkgPSBuZXcgSlNPTkFycmF5KCk7CisgICAgICAgIGFycmF5LnB1dCgidHJ1ZSIpOworICAgICAgICBhcnJheS5wdXQoIjUuNSIpOworICAgICAgICBhcnJheS5wdXQoIjkyMjMzNzIwMzY4NTQ3NzU4MDYiKTsKKyAgICAgICAgYXJyYXkucHV0KCJudWxsIik7CisgICAgICAgIGFycmF5LnB1dCgiNVwiOCcgdGFsbCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgYXJyYXkubGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIltcInRydWVcIixcIjUuNVwiLFwiOTIyMzM3MjAzNjg1NDc3NTgwNlwiLFwibnVsbFwiLFwiNVxcXCI4JyB0YWxsXCJdIiwKKyAgICAgICAgICAgICAgICBhcnJheS50b1N0cmluZygpKTsKKworICAgICAgICAvLyBhbHRob3VnaCB0aGUgZG9jdW1lbnRhdGlvbiBkb2Vzbid0IG1lbnRpb24gaXQsIGpvaW4oKSBlc2NhcGVzIHRleHQgYW5kIHdyYXBzCisgICAgICAgIC8vIHN0cmluZ3MgaW4gcXVvdGVzCisgICAgICAgIGFzc2VydEVxdWFscygiXCJ0cnVlXCIgXCI1LjVcIiBcIjkyMjMzNzIwMzY4NTQ3NzU4MDZcIiBcIm51bGxcIiBcIjVcXFwiOCcgdGFsbFwiIiwKKyAgICAgICAgICAgICAgICBhcnJheS5qb2luKCIgIikpOworCisgICAgICAgIGFzc2VydEVxdWFscygidHJ1ZSIsIGFycmF5LmdldCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibnVsbCIsIGFycmF5LmdldFN0cmluZygzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiNVwiOCcgdGFsbCIsIGFycmF5LmdldFN0cmluZyg0KSk7CisgICAgICAgIGFzc2VydEVxdWFscygidHJ1ZSIsIGFycmF5Lm9wdCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiNS41IiwgYXJyYXkub3B0U3RyaW5nKDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI5MjIzMzcyMDM2ODU0Nzc1ODA2IiwgYXJyYXkub3B0U3RyaW5nKDIsIG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJudWxsIiwgYXJyYXkub3B0U3RyaW5nKDMsICItMSIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoYXJyYXkuaXNOdWxsKDApKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoYXJyYXkuaXNOdWxsKDMpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgYXJyYXkuZ2V0Qm9vbGVhbigwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBhcnJheS5vcHRCb29sZWFuKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGFycmF5Lm9wdEJvb2xlYW4oMCwgZmFsc2UpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGFycmF5Lm9wdEludCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMiwgYXJyYXkub3B0SW50KDAsIC0yKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUuNWQsIGFycmF5LmdldERvdWJsZSgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg1TCwgYXJyYXkuZ2V0TG9uZygxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBhcnJheS5nZXRJbnQoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgYXJyYXkub3B0SW50KDEsIDMpKTsKKworICAgICAgICAvLyBUaGUgbGFzdCBkaWdpdCBvZiB0aGUgc3RyaW5nIGlzIGEgNiBidXQgZ2V0TG9uZyByZXR1cm5zIGEgNy4gSXQncyBwcm9iYWJseSBwYXJzaW5nIGFzIGEKKyAgICAgICAgLy8gZG91YmxlIGFuZCB0aGVuIGNvbnZlcnRpbmcgdGhhdCB0byBhIGxvbmcuIFRoaXMgaXMgY29uc2lzdGVudCB3aXRoIEphdmFTY3JpcHQuCisgICAgICAgIGFzc2VydEVxdWFscyg5MjIzMzcyMDM2ODU0Nzc1ODA3TCwgYXJyYXkuZ2V0TG9uZygyKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg5LjIyMzM3MjAzNjg1NDc3NkUxOCwgYXJyYXkuZ2V0RG91YmxlKDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEludGVnZXIuTUFYX1ZBTFVFLCBhcnJheS5nZXRJbnQoMikpOworCisgICAgICAgIGFzc2VydEZhbHNlKGFycmF5LmlzTnVsbCgzKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcnJheS5nZXREb3VibGUoMyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuTmFOLCBhcnJheS5vcHREb3VibGUoMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEuMGQsIGFycmF5Lm9wdERvdWJsZSgzLCAtMS4wZCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RKb2luKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OQXJyYXkgYXJyYXkgPSBuZXcgSlNPTkFycmF5KCk7CisgICAgICAgIGFycmF5LnB1dChudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJudWxsIiwgYXJyYXkuam9pbigiICYgIikpOworICAgICAgICBhcnJheS5wdXQoIlwiIik7CisgICAgICAgIGFzc2VydEVxdWFscygibnVsbCAmIFwiXFxcIlwiIiwgYXJyYXkuam9pbigiICYgIikpOworICAgICAgICBhcnJheS5wdXQoNSk7CisgICAgICAgIGFzc2VydEVxdWFscygibnVsbCAmIFwiXFxcIlwiICYgNSIsIGFycmF5LmpvaW4oIiAmICIpKTsKKyAgICAgICAgYXJyYXkucHV0KHRydWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm51bGwgJiBcIlxcXCJcIiAmIDUgJiB0cnVlIiwgYXJyYXkuam9pbigiICYgIikpOworICAgICAgICBhcnJheS5wdXQobmV3IEpTT05BcnJheShBcnJheXMuYXNMaXN0KHRydWUsIGZhbHNlKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm51bGwgJiBcIlxcXCJcIiAmIDUgJiB0cnVlICYgW3RydWUsZmFsc2VdIiwgYXJyYXkuam9pbigiICYgIikpOworICAgICAgICBhcnJheS5wdXQobmV3IEpTT05PYmplY3QoQ29sbGVjdGlvbnMuc2luZ2xldG9uTWFwKCJ4IiwgNikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJudWxsICYgXCJcXFwiXCIgJiA1ICYgdHJ1ZSAmIFt0cnVlLGZhbHNlXSAmIHtcInhcIjo2fSIsIGFycmF5LmpvaW4oIiAmICIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Sm9pbldpdGhOdWxsKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OQXJyYXkgYXJyYXkgPSBuZXcgSlNPTkFycmF5KEFycmF5cy5hc0xpc3QoNSwgNikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjVudWxsNiIsIGFycmF5LmpvaW4obnVsbCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RKb2luV2l0aFNwZWNpYWxDaGFyYWN0ZXJzKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OQXJyYXkgYXJyYXkgPSBuZXcgSlNPTkFycmF5KEFycmF5cy5hc0xpc3QoNSwgNikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjVcIjYiLCBhcnJheS5qb2luKCJcIiIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9KU09OT2JqZWN0KCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OQXJyYXkga2V5cyA9IG5ldyBKU09OQXJyYXkoKTsKKyAgICAgICAga2V5cy5wdXQoImEiKTsKKyAgICAgICAga2V5cy5wdXQoImIiKTsKKworICAgICAgICBKU09OQXJyYXkgdmFsdWVzID0gbmV3IEpTT05BcnJheSgpOworICAgICAgICB2YWx1ZXMucHV0KDUuNWQpOworICAgICAgICB2YWx1ZXMucHV0KGZhbHNlKTsKKworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IHZhbHVlcy50b0pTT05PYmplY3Qoa2V5cyk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LjVkLCBvYmplY3QuZ2V0KCJhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIG9iamVjdC5nZXQoImIiKSk7CisKKyAgICAgICAga2V5cy5wdXQoMCwgImEiKTsKKyAgICAgICAgdmFsdWVzLnB1dCgwLCAxMS4wZCk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LjVkLCBvYmplY3QuZ2V0KCJhIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUb0pTT05PYmplY3RXaXRoTnVsbHMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05BcnJheSBrZXlzID0gbmV3IEpTT05BcnJheSgpOworICAgICAgICBrZXlzLnB1dCgiYSIpOworICAgICAgICBrZXlzLnB1dCgiYiIpOworCisgICAgICAgIEpTT05BcnJheSB2YWx1ZXMgPSBuZXcgSlNPTkFycmF5KCk7CisgICAgICAgIHZhbHVlcy5wdXQoNS41ZCk7CisgICAgICAgIHZhbHVlcy5wdXQobnVsbCk7CisKKyAgICAgICAgLy8gbnVsbCB2YWx1ZXMgYXJlIHN0cmlwcGVkIQorICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IHZhbHVlcy50b0pTT05PYmplY3Qoa2V5cyk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBvYmplY3QubGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRGYWxzZShvYmplY3QuaGFzKCJiIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIntcImFcIjo1LjV9Iiwgb2JqZWN0LnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUb0pTT05PYmplY3RNb3JlTmFtZXNUaGFuVmFsdWVzKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OQXJyYXkga2V5cyA9IG5ldyBKU09OQXJyYXkoKTsKKyAgICAgICAga2V5cy5wdXQoImEiKTsKKyAgICAgICAga2V5cy5wdXQoImIiKTsKKyAgICAgICAgSlNPTkFycmF5IHZhbHVlcyA9IG5ldyBKU09OQXJyYXkoKTsKKyAgICAgICAgdmFsdWVzLnB1dCg1LjVkKTsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSB2YWx1ZXMudG9KU09OT2JqZWN0KGtleXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgb2JqZWN0Lmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUuNWQsIG9iamVjdC5nZXQoImEiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRvSlNPTk9iamVjdE1vcmVWYWx1ZXNUaGFuTmFtZXMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05BcnJheSBrZXlzID0gbmV3IEpTT05BcnJheSgpOworICAgICAgICBrZXlzLnB1dCgiYSIpOworICAgICAgICBKU09OQXJyYXkgdmFsdWVzID0gbmV3IEpTT05BcnJheSgpOworICAgICAgICB2YWx1ZXMucHV0KDUuNWQpOworICAgICAgICB2YWx1ZXMucHV0KDExLjBkKTsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSB2YWx1ZXMudG9KU09OT2JqZWN0KGtleXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgb2JqZWN0Lmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUuNWQsIG9iamVjdC5nZXQoImEiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRvSlNPTk9iamVjdE51bGxLZXkoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05BcnJheSBrZXlzID0gbmV3IEpTT05BcnJheSgpOworICAgICAgICBrZXlzLnB1dChKU09OT2JqZWN0Lk5VTEwpOworICAgICAgICBKU09OQXJyYXkgdmFsdWVzID0gbmV3IEpTT05BcnJheSgpOworICAgICAgICB2YWx1ZXMucHV0KDUuNWQpOworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IHZhbHVlcy50b0pTT05PYmplY3Qoa2V5cyk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBvYmplY3QubGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNS41ZCwgb2JqZWN0LmdldCgibnVsbCIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHV0VW5zdXBwb3J0ZWROdW1iZXJzKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OQXJyYXkgYXJyYXkgPSBuZXcgSlNPTkFycmF5KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFycmF5LnB1dChEb3VibGUuTmFOKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFycmF5LnB1dCgwLCBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYXJyYXkucHV0KDAsIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1dFVuc3VwcG9ydGVkTnVtYmVyc0FzT2JqZWN0KCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OQXJyYXkgYXJyYXkgPSBuZXcgSlNPTkFycmF5KCk7CisgICAgICAgIGFycmF5LnB1dChEb3VibGUudmFsdWVPZihEb3VibGUuTmFOKSk7CisgICAgICAgIGFycmF5LnB1dChEb3VibGUudmFsdWVPZihEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpKTsKKyAgICAgICAgYXJyYXkucHV0KERvdWJsZS52YWx1ZU9mKERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgYXJyYXkudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWx0aG91Z2ggSlNPTkFycmF5IGlzIHVzdWFsbHkgZGVmZW5zaXZlIGFib3V0IHdoaWNoIG51bWJlcnMgaXQgYWNjZXB0cywKKyAgICAgKiBpdCBkb2Vzbid0IGNoZWNrIGlucHV0cyBpbiBpdHMgY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZVdpdGhVbnN1cHBvcnRlZE51bWJlcnMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05BcnJheSBhcnJheSA9IG5ldyBKU09OQXJyYXkoQXJyYXlzLmFzTGlzdCg1LjUsIERvdWJsZS5OYU4pKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGFycmF5Lmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUuNSwgYXJyYXkuZ2V0RG91YmxlKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5OYU4sIGFycmF5LmdldERvdWJsZSgxKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRvU3RyaW5nV2l0aFVuc3VwcG9ydGVkTnVtYmVycygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgLy8gd2hlbiB0aGUgYXJyYXkgY29udGFpbnMgYW4gdW5zdXBwb3J0ZWQgbnVtYmVyLCB0b1N0cmluZyByZXR1cm5zIG51bGwhCisgICAgICAgIEpTT05BcnJheSBhcnJheSA9IG5ldyBKU09OQXJyYXkoQXJyYXlzLmFzTGlzdCg1LjUsIERvdWJsZS5OYU4pKTsKKyAgICAgICAgYXNzZXJ0TnVsbChhcnJheS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TGlzdENvbnN0cnVjdG9yQ29waWVzQ29udGVudHMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIExpc3Q8T2JqZWN0PiBjb250ZW50cyA9IEFycmF5cy48T2JqZWN0PmFzTGlzdCg1KTsKKyAgICAgICAgSlNPTkFycmF5IGFycmF5ID0gbmV3IEpTT05BcnJheShjb250ZW50cyk7CisgICAgICAgIGNvbnRlbnRzLnNldCgwLCAxMCk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBhcnJheS5nZXQoMCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUb2tlbmVyQ29uc3RydWN0b3IoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05BcnJheSBvYmplY3QgPSBuZXcgSlNPTkFycmF5KG5ldyBKU09OVG9rZW5lcigiW2ZhbHNlXSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG9iamVjdC5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgb2JqZWN0LmdldCgwKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRva2VuZXJDb25zdHJ1Y3Rvcldyb25nVHlwZSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKU09OQXJyYXkobmV3IEpTT05Ub2tlbmVyKCJ7XCJmb29cIjogZmFsc2V9IikpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUb2tlbmVyQ29uc3RydWN0b3JOdWxsKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05BcnJheSgoSlNPTlRva2VuZXIpIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9rZW5lckNvbnN0cnVjdG9yUGFyc2VGYWlsKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05BcnJheShuZXcgSlNPTlRva2VuZXIoIlsiKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChTdGFja092ZXJmbG93RXJyb3IgZSkgeworICAgICAgICAgICAgZmFpbCgiU3RhY2sgb3ZlcmZsb3dlZCBvbiBpbnB1dDogXCJbXCIiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdHJpbmdDb25zdHJ1Y3RvcigpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTkFycmF5IG9iamVjdCA9IG5ldyBKU09OQXJyYXkoIltmYWxzZV0iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG9iamVjdC5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgb2JqZWN0LmdldCgwKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0cmluZ0NvbnN0cnVjdG9yV3JvbmdUeXBlKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05BcnJheSgie1wiZm9vXCI6IGZhbHNlfSIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdHJpbmdDb25zdHJ1Y3Rvck51bGwoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTkFycmF5KChTdHJpbmcpIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RyaW5nQ29uc3RydWN0b3JQYXJzZUZhaWwoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTkFycmF5KCJbIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChTdGFja092ZXJmbG93RXJyb3IgZSkgeworICAgICAgICAgICAgZmFpbCgiU3RhY2sgb3ZlcmZsb3dlZCBvbiBpbnB1dDogXCJbXCIiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGUoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05BcnJheSBhcnJheSA9IG5ldyBKU09OQXJyYXkoQXJyYXlzLmFzTGlzdCg1LjUsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGFycmF5Lmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUuNSwgYXJyYXkuZ2V0RG91YmxlKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGFycmF5LmdldCgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWzUuNSx0cnVlXSIsIGFycmF5LnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBY2Nlc3NPdXRPZkJvdW5kcygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTkFycmF5IGFycmF5ID0gbmV3IEpTT05BcnJheSgpOworICAgICAgICBhcnJheS5wdXQoImZvbyIpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgYXJyYXkub3B0KDMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGFycmF5Lm9wdCgtMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGFycmF5Lm9wdFN0cmluZygzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgYXJyYXkub3B0U3RyaW5nKC0zKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcnJheS5nZXQoMyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcnJheS5nZXQoLTMpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYXJyYXkuZ2V0U3RyaW5nKDMpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYXJyYXkuZ2V0U3RyaW5nKC0zKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9qc29uL3NyYy90ZXN0L2phdmEvb3JnL2pzb24vSlNPTk9iamVjdFRlc3QuamF2YSBiL2pzb24vc3JjL3Rlc3QvamF2YS9vcmcvanNvbi9KU09OT2JqZWN0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUxOTJiMDMKLS0tIC9kZXYvbnVsbAorKysgYi9qc29uL3NyYy90ZXN0L2phdmEvb3JnL2pzb24vSlNPTk9iamVjdFRlc3QuamF2YQpAQCAtMCwwICsxLDk2NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmpzb247CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnRGVjaW1hbDsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUaGlzIGJsYWNrIGJveCB0ZXN0IHdhcyB3cml0dGVuIHdpdGhvdXQgaW5zcGVjdGluZyB0aGUgbm9uLWZyZWUgb3JnLmpzb24gc291cmNlY29kZS4KKyAqLworcHVibGljIGNsYXNzIEpTT05PYmplY3RUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdEVtcHR5T2JqZWN0KCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IG5ldyBKU09OT2JqZWN0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBvYmplY3QubGVuZ3RoKCkpOworCisgICAgICAgIC8vIGJvZ3VzIChidXQgZG9jdW1lbnRlZCkgYmVoYXZpb3VyOiByZXR1cm5zIG51bGwgcmF0aGVyIHRoYW4gdGhlIGVtcHR5IG9iamVjdCEKKyAgICAgICAgYXNzZXJ0TnVsbChvYmplY3QubmFtZXMoKSk7CisKKyAgICAgICAgLy8gcmV0dXJucyBudWxsIHJhdGhlciB0aGFuIGFuIGVtcHR5IGFycmF5IQorICAgICAgICBhc3NlcnROdWxsKG9iamVjdC50b0pTT05BcnJheShuZXcgSlNPTkFycmF5KCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ7fSIsIG9iamVjdC50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ7fSIsIG9iamVjdC50b1N0cmluZyg1KSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmplY3QuZ2V0KCJmb28iKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iamVjdC5nZXRCb29sZWFuKCJmb28iKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iamVjdC5nZXREb3VibGUoImZvbyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgb2JqZWN0LmdldEludCgiZm9vIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmplY3QuZ2V0SlNPTkFycmF5KCJmb28iKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iamVjdC5nZXRKU09OT2JqZWN0KCJmb28iKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iamVjdC5nZXRMb25nKCJmb28iKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iamVjdC5nZXRTdHJpbmcoImZvbyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZShvYmplY3QuaGFzKCJmb28iKSk7CisgICAgICAgIGFzc2VydFRydWUob2JqZWN0LmlzTnVsbCgiZm9vIikpOyAvLyBpc051bGwgYWxzbyBtZWFucyAiaXMgbm90IHByZXNlbnQiCisgICAgICAgIGFzc2VydE51bGwob2JqZWN0Lm9wdCgiZm9vIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIG9iamVjdC5vcHRCb29sZWFuKCJmb28iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBvYmplY3Qub3B0Qm9vbGVhbigiZm9vIiwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLk5hTiwgb2JqZWN0Lm9wdERvdWJsZSgiZm9vIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoNS4wLCBvYmplY3Qub3B0RG91YmxlKCJmb28iLCA1LjApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG9iamVjdC5vcHRJbnQoImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIG9iamVjdC5vcHRJbnQoImZvbyIsIDUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG9iamVjdC5vcHRKU09OQXJyYXkoImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG9iamVjdC5vcHRKU09OT2JqZWN0KCJmb28iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBvYmplY3Qub3B0TG9uZygiZm9vIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoTG9uZy5NQVhfVkFMVUUtMSwgb2JqZWN0Lm9wdExvbmcoImZvbyIsIExvbmcuTUFYX1ZBTFVFLTEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBvYmplY3Qub3B0U3RyaW5nKCJmb28iKSk7IC8vIGVtcHR5IHN0cmluZyBpcyBkZWZhdWx0IQorICAgICAgICBhc3NlcnRFcXVhbHMoImJhciIsIG9iamVjdC5vcHRTdHJpbmcoImZvbyIsICJiYXIiKSk7CisgICAgICAgIGFzc2VydE51bGwob2JqZWN0LnJlbW92ZSgiZm9vIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHNBbmRIYXNoQ29kZSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTk9iamVjdCBhID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgSlNPTk9iamVjdCBiID0gbmV3IEpTT05PYmplY3QoKTsKKworICAgICAgICAvLyBKU09OIG9iamVjdCBkb2Vzbid0IG92ZXJyaWRlIGVpdGhlciBlcXVhbHMgb3IgaGFzaENvZGUgKCEpCisgICAgICAgIGFzc2VydEZhbHNlKGEuZXF1YWxzKGIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGEuaGFzaENvZGUoKSwgU3lzdGVtLmlkZW50aXR5SGFzaENvZGUoYSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXQoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgT2JqZWN0IHZhbHVlID0gbmV3IE9iamVjdCgpOworICAgICAgICBvYmplY3QucHV0KCJmb28iLCB2YWx1ZSk7CisgICAgICAgIG9iamVjdC5wdXQoImJhciIsIG5ldyBPYmplY3QoKSk7CisgICAgICAgIG9iamVjdC5wdXQoImJheiIsIG5ldyBPYmplY3QoKSk7CisgICAgICAgIGFzc2VydFNhbWUodmFsdWUsIG9iamVjdC5nZXQoImZvbyIpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iamVjdC5nZXQoIkZPTyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgb2JqZWN0LnB1dChudWxsLCB2YWx1ZSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmplY3QuZ2V0KG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQdXQoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgYXNzZXJ0U2FtZShvYmplY3QsIG9iamVjdC5wdXQoImZvbyIsIHRydWUpKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiZm9vIiwgZmFsc2UpOworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIG9iamVjdC5nZXQoImZvbyIpKTsKKworICAgICAgICBvYmplY3QucHV0KCJmb28iLCA1LjBkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUuMGQsIG9iamVjdC5nZXQoImZvbyIpKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiZm9vIiwgMCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBvYmplY3QuZ2V0KCJmb28iKSk7CisgICAgICAgIG9iamVjdC5wdXQoImJhciIsIExvbmcuTUFYX1ZBTFVFIC0gMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhMb25nLk1BWF9WQUxVRSAtIDEsIG9iamVjdC5nZXQoImJhciIpKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiYmF6IiwgIngiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4Iiwgb2JqZWN0LmdldCgiYmF6IikpOworICAgICAgICBvYmplY3QucHV0KCJiYXIiLCBKU09OT2JqZWN0Lk5VTEwpOworICAgICAgICBhc3NlcnRTYW1lKEpTT05PYmplY3QuTlVMTCwgb2JqZWN0LmdldCgiYmFyIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQdXROdWxsUmVtb3ZlcygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdCgpOworICAgICAgICBvYmplY3QucHV0KCJmb28iLCAiYmFyIik7CisgICAgICAgIG9iamVjdC5wdXQoImZvbyIsIG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgb2JqZWN0Lmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uob2JqZWN0LmhhcygiZm9vIikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2JqZWN0LmdldCgiZm9vIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1dE9wdCgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdCgpOworICAgICAgICBvYmplY3QucHV0KCJmb28iLCAiYmFyIik7CisgICAgICAgIG9iamVjdC5wdXRPcHQoImZvbyIsIG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJhciIsIG9iamVjdC5nZXQoImZvbyIpKTsKKyAgICAgICAgb2JqZWN0LnB1dE9wdChudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG9iamVjdC5sZW5ndGgoKSk7CisgICAgICAgIG9iamVjdC5wdXRPcHQobnVsbCwgImJhciIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgb2JqZWN0Lmxlbmd0aCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHV0T3B0VW5zdXBwb3J0ZWROdW1iZXJzKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IG5ldyBKU09OT2JqZWN0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmplY3QucHV0T3B0KCJmb28iLCBEb3VibGUuTmFOKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iamVjdC5wdXRPcHQoImZvbyIsIERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmplY3QucHV0T3B0KCJmb28iLCBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmUoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiZm9vIiwgImJhciIpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgb2JqZWN0LnJlbW92ZShudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBvYmplY3QucmVtb3ZlKCIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBvYmplY3QucmVtb3ZlKCJiYXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYmFyIiwgb2JqZWN0LnJlbW92ZSgiZm9vIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgb2JqZWN0LnJlbW92ZSgiZm9vIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCb29sZWFucygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdCgpOworICAgICAgICBvYmplY3QucHV0KCJmb28iLCB0cnVlKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiYmFyIiwgZmFsc2UpOworICAgICAgICBvYmplY3QucHV0KCJiYXoiLCAidHJ1ZSIpOworICAgICAgICBvYmplY3QucHV0KCJxdXV4IiwgImZhbHNlIik7CisgICAgICAgIGFzc2VydEVxdWFscyg0LCBvYmplY3QubGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgb2JqZWN0LmdldEJvb2xlYW4oImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBvYmplY3QuZ2V0Qm9vbGVhbigiYmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgb2JqZWN0LmdldEJvb2xlYW4oImJheiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBvYmplY3QuZ2V0Qm9vbGVhbigicXV1eCIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uob2JqZWN0LmlzTnVsbCgiZm9vIikpOworICAgICAgICBhc3NlcnRGYWxzZShvYmplY3QuaXNOdWxsKCJxdXV4IikpOworICAgICAgICBhc3NlcnRUcnVlKG9iamVjdC5oYXMoImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShvYmplY3QuaGFzKCJxdXV4IikpOworICAgICAgICBhc3NlcnRGYWxzZShvYmplY3QuaGFzKCJtaXNzaW5nIikpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgb2JqZWN0Lm9wdEJvb2xlYW4oImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBvYmplY3Qub3B0Qm9vbGVhbigiYmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgb2JqZWN0Lm9wdEJvb2xlYW4oImJheiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBvYmplY3Qub3B0Qm9vbGVhbigicXV1eCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBvYmplY3Qub3B0Qm9vbGVhbigibWlzc2luZyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIG9iamVjdC5vcHRCb29sZWFuKCJmb28iLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgb2JqZWN0Lm9wdEJvb2xlYW4oImJhciIsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIG9iamVjdC5vcHRCb29sZWFuKCJiYXoiLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgb2JqZWN0Lm9wdEJvb2xlYW4oInF1dXgiLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBvYmplY3Qub3B0Qm9vbGVhbigibWlzc2luZyIsIHRydWUpKTsKKworICAgICAgICBvYmplY3QucHV0KCJmb28iLCAidHJ1RSIpOworICAgICAgICBvYmplY3QucHV0KCJiYXIiLCAiRkFMU0UiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIG9iamVjdC5nZXRCb29sZWFuKCJmb28iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgb2JqZWN0LmdldEJvb2xlYW4oImJhciIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIG9iamVjdC5vcHRCb29sZWFuKCJmb28iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgb2JqZWN0Lm9wdEJvb2xlYW4oImJhciIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIG9iamVjdC5vcHRCb29sZWFuKCJmb28iLCBmYWxzZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIG9iamVjdC5vcHRCb29sZWFuKCJiYXIiLCBmYWxzZSkpOworICAgIH0KKworICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9MTY0MTEKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29lcmNlU3RyaW5nVG9Cb29sZWFuKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IG5ldyBKU09OT2JqZWN0KCk7CisgICAgICAgIG9iamVjdC5wdXQoImZvbyIsICJtYXliZSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2JqZWN0LmdldEJvb2xlYW4oImZvbyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBvYmplY3Qub3B0Qm9vbGVhbigiZm9vIikpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgb2JqZWN0Lm9wdEJvb2xlYW4oImZvbyIsIHRydWUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TnVtYmVycygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdCgpOworICAgICAgICBvYmplY3QucHV0KCJmb28iLCBEb3VibGUuTUlOX1ZBTFVFKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiYmFyIiwgOTIyMzM3MjAzNjg1NDc3NTgwNkwpOworICAgICAgICBvYmplY3QucHV0KCJiYXoiLCBEb3VibGUuTUFYX1ZBTFVFKTsKKyAgICAgICAgb2JqZWN0LnB1dCgicXV1eCIsIC0wZCk7CisgICAgICAgIGFzc2VydEVxdWFscyg0LCBvYmplY3QubGVuZ3RoKCkpOworCisgICAgICAgIFN0cmluZyB0b1N0cmluZyA9IG9iamVjdC50b1N0cmluZygpOworICAgICAgICBhc3NlcnRUcnVlKHRvU3RyaW5nLCB0b1N0cmluZy5jb250YWlucygiXCJmb29cIjo0LjlFLTMyNCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0b1N0cmluZywgdG9TdHJpbmcuY29udGFpbnMoIlwiYmFyXCI6OTIyMzM3MjAzNjg1NDc3NTgwNiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0b1N0cmluZywgdG9TdHJpbmcuY29udGFpbnMoIlwiYmF6XCI6MS43OTc2OTMxMzQ4NjIzMTU3RTMwOCIpKTsKKworICAgICAgICAvLyB0b1N0cmluZygpIGFuZCBnZXRTdHJpbmcoKSByZXR1cm4gZGlmZmVyZW50IHZhbHVlcyBmb3IgLTBkIQorICAgICAgICBhc3NlcnRUcnVlKHRvU3RyaW5nLCB0b1N0cmluZy5jb250YWlucygiXCJxdXV4XCI6LTB9IikgLy8gbm8gdHJhaWxpbmcgZGVjaW1hbCBwb2ludAorICAgICAgICAgICAgICAgIHx8IHRvU3RyaW5nLmNvbnRhaW5zKCJcInF1dXhcIjotMCwiKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5NSU5fVkFMVUUsIG9iamVjdC5nZXQoImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDkyMjMzNzIwMzY4NTQ3NzU4MDZMLCBvYmplY3QuZ2V0KCJiYXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuTUFYX1ZBTFVFLCBvYmplY3QuZ2V0KCJiYXoiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMGQsIG9iamVjdC5nZXQoInF1dXgiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuTUlOX1ZBTFVFLCBvYmplY3QuZ2V0RG91YmxlKCJmb28iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg5LjIyMzM3MjAzNjg1NDc3NkUxOCwgb2JqZWN0LmdldERvdWJsZSgiYmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLk1BWF9WQUxVRSwgb2JqZWN0LmdldERvdWJsZSgiYmF6IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTBkLCBvYmplY3QuZ2V0RG91YmxlKCJxdXV4IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgb2JqZWN0LmdldExvbmcoImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDkyMjMzNzIwMzY4NTQ3NzU4MDZMLCBvYmplY3QuZ2V0TG9uZygiYmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoTG9uZy5NQVhfVkFMVUUsIG9iamVjdC5nZXRMb25nKCJiYXoiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBvYmplY3QuZ2V0TG9uZygicXV1eCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG9iamVjdC5nZXRJbnQoImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0yLCBvYmplY3QuZ2V0SW50KCJiYXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLk1BWF9WQUxVRSwgb2JqZWN0LmdldEludCgiYmF6IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgb2JqZWN0LmdldEludCgicXV1eCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5NSU5fVkFMVUUsIG9iamVjdC5vcHQoImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDkyMjMzNzIwMzY4NTQ3NzU4MDZMLCBvYmplY3Qub3B0TG9uZygiYmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLk1BWF9WQUxVRSwgb2JqZWN0Lm9wdERvdWJsZSgiYmF6IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgb2JqZWN0Lm9wdEludCgicXV1eCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5NSU5fVkFMVUUsIG9iamVjdC5vcHQoImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDkyMjMzNzIwMzY4NTQ3NzU4MDZMLCBvYmplY3Qub3B0TG9uZygiYmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLk1BWF9WQUxVRSwgb2JqZWN0Lm9wdERvdWJsZSgiYmF6IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgb2JqZWN0Lm9wdEludCgicXV1eCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5NSU5fVkFMVUUsIG9iamVjdC5vcHREb3VibGUoImZvbyIsIDUuMGQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDkyMjMzNzIwMzY4NTQ3NzU4MDZMLCBvYmplY3Qub3B0TG9uZygiYmFyIiwgMUwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExvbmcuTUFYX1ZBTFVFLCBvYmplY3Qub3B0TG9uZygiYmF6IiwgMUwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG9iamVjdC5vcHRJbnQoInF1dXgiLCAtMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjQuOUUtMzI0Iiwgb2JqZWN0LmdldFN0cmluZygiZm9vIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjkyMjMzNzIwMzY4NTQ3NzU4MDYiLCBvYmplY3QuZ2V0U3RyaW5nKCJiYXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMS43OTc2OTMxMzQ4NjIzMTU3RTMwOCIsIG9iamVjdC5nZXRTdHJpbmcoImJheiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCItMC4wIiwgb2JqZWN0LmdldFN0cmluZygicXV1eCIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmxvYXRzKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IG5ldyBKU09OT2JqZWN0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmplY3QucHV0KCJmb28iLCAoRmxvYXQpIEZsb2F0Lk5hTik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmplY3QucHV0KCJmb28iLCAoRmxvYXQpIEZsb2F0Lk5FR0FUSVZFX0lORklOSVRZKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iamVjdC5wdXQoImZvbyIsIChGbG9hdCkgRmxvYXQuUE9TSVRJVkVfSU5GSU5JVFkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RPdGhlck51bWJlcnMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIE51bWJlciBuYW4gPSBuZXcgTnVtYmVyKCkgeworICAgICAgICAgICAgcHVibGljIGludCBpbnRWYWx1ZSgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyBsb25nIGxvbmdWYWx1ZSgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyBmbG9hdCBmbG9hdFZhbHVlKCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIGRvdWJsZSBkb3VibGVWYWx1ZSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gRG91YmxlLk5hTjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgICAgIHJldHVybiAieCI7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2JqZWN0LnB1dCgiZm9vIiwgbmFuKTsKKyAgICAgICAgICAgIGZhaWwoIk9iamVjdC5wdXQoKSBhY2NlcHRlZCBhIE5hTiAodmlhIGEgY3VzdG9tIE51bWJlciBjbGFzcykiKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9yZWlnbk9iamVjdHMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdCBmb3JlaWduID0gbmV3IE9iamVjdCgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgICAgIHJldHVybiAieCI7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgLy8gZm9yZWlnbiBvYmplY3QgdHlwZXMgYXJlIGFjY2VwdGVkIGFuZCB0cmVhdGVkIGFzIFN0cmluZ3MhCisgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiZm9vIiwgZm9yZWlnbik7CisgICAgICAgIGFzc2VydEVxdWFscygie1wiZm9vXCI6XCJ4XCJ9Iiwgb2JqZWN0LnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROdWxsS2V5cygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKU09OT2JqZWN0KCkucHV0KG51bGwsIGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKU09OT2JqZWN0KCkucHV0KG51bGwsIDAuMGQpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05PYmplY3QoKS5wdXQobnVsbCwgNSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTk9iamVjdCgpLnB1dChudWxsLCA1TCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTk9iamVjdCgpLnB1dChudWxsLCAiZm9vIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0cmluZ3MoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiZm9vIiwgInRydWUiKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiYmFyIiwgIjUuNSIpOworICAgICAgICBvYmplY3QucHV0KCJiYXoiLCAiOTIyMzM3MjAzNjg1NDc3NTgwNiIpOworICAgICAgICBvYmplY3QucHV0KCJxdXV4IiwgIm51bGwiKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiaGVpZ2h0IiwgIjVcIjgnIHRhbGwiKTsKKworICAgICAgICBhc3NlcnRUcnVlKG9iamVjdC50b1N0cmluZygpLmNvbnRhaW5zKCJcImZvb1wiOlwidHJ1ZVwiIikpOworICAgICAgICBhc3NlcnRUcnVlKG9iamVjdC50b1N0cmluZygpLmNvbnRhaW5zKCJcImJhclwiOlwiNS41XCIiKSk7CisgICAgICAgIGFzc2VydFRydWUob2JqZWN0LnRvU3RyaW5nKCkuY29udGFpbnMoIlwiYmF6XCI6XCI5MjIzMzcyMDM2ODU0Nzc1ODA2XCIiKSk7CisgICAgICAgIGFzc2VydFRydWUob2JqZWN0LnRvU3RyaW5nKCkuY29udGFpbnMoIlwicXV1eFwiOlwibnVsbFwiIikpOworICAgICAgICBhc3NlcnRUcnVlKG9iamVjdC50b1N0cmluZygpLmNvbnRhaW5zKCJcImhlaWdodFwiOlwiNVxcXCI4JyB0YWxsXCIiKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0cnVlIiwgb2JqZWN0LmdldCgiZm9vIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm51bGwiLCBvYmplY3QuZ2V0U3RyaW5nKCJxdXV4IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjVcIjgnIHRhbGwiLCBvYmplY3QuZ2V0U3RyaW5nKCJoZWlnaHQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidHJ1ZSIsIG9iamVjdC5vcHQoImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI1LjUiLCBvYmplY3Qub3B0U3RyaW5nKCJiYXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidHJ1ZSIsIG9iamVjdC5vcHRTdHJpbmcoImZvbyIsICJ4IikpOworICAgICAgICBhc3NlcnRGYWxzZShvYmplY3QuaXNOdWxsKCJmb28iKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIG9iamVjdC5nZXRCb29sZWFuKCJmb28iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBvYmplY3Qub3B0Qm9vbGVhbigiZm9vIikpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgb2JqZWN0Lm9wdEJvb2xlYW4oImZvbyIsIGZhbHNlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBvYmplY3Qub3B0SW50KCJmb28iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMiwgb2JqZWN0Lm9wdEludCgiZm9vIiwgLTIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoNS41ZCwgb2JqZWN0LmdldERvdWJsZSgiYmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoNUwsIG9iamVjdC5nZXRMb25nKCJiYXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBvYmplY3QuZ2V0SW50KCJiYXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBvYmplY3Qub3B0SW50KCJiYXIiLCAzKSk7CisKKyAgICAgICAgLy8gVGhlIGxhc3QgZGlnaXQgb2YgdGhlIHN0cmluZyBpcyBhIDYgYnV0IGdldExvbmcgcmV0dXJucyBhIDcuIEl0J3MgcHJvYmFibHkgcGFyc2luZyBhcyBhCisgICAgICAgIC8vIGRvdWJsZSBhbmQgdGhlbiBjb252ZXJ0aW5nIHRoYXQgdG8gYSBsb25nLiBUaGlzIGlzIGNvbnNpc3RlbnQgd2l0aCBKYXZhU2NyaXB0LgorICAgICAgICBhc3NlcnRFcXVhbHMoOTIyMzM3MjAzNjg1NDc3NTgwN0wsIG9iamVjdC5nZXRMb25nKCJiYXoiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg5LjIyMzM3MjAzNjg1NDc3NkUxOCwgb2JqZWN0LmdldERvdWJsZSgiYmF6IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoSW50ZWdlci5NQVhfVkFMVUUsIG9iamVjdC5nZXRJbnQoImJheiIpKTsKKworICAgICAgICBhc3NlcnRGYWxzZShvYmplY3QuaXNOdWxsKCJxdXV4IikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2JqZWN0LmdldERvdWJsZSgicXV1eCIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLk5hTiwgb2JqZWN0Lm9wdERvdWJsZSgicXV1eCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLjBkLCBvYmplY3Qub3B0RG91YmxlKCJxdXV4IiwgLTEuMGQpKTsKKworICAgICAgICBvYmplY3QucHV0KCJmb28iLCAiVFJVRSIpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgb2JqZWN0LmdldEJvb2xlYW4oImZvbyIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SlNPTk9iamVjdHMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gbmV3IEpTT05PYmplY3QoKTsKKworICAgICAgICBKU09OQXJyYXkgYSA9IG5ldyBKU09OQXJyYXkoKTsKKyAgICAgICAgSlNPTk9iamVjdCBiID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiZm9vIiwgYSk7CisgICAgICAgIG9iamVjdC5wdXQoImJhciIsIGIpOworCisgICAgICAgIGFzc2VydFNhbWUoYSwgb2JqZWN0LmdldEpTT05BcnJheSgiZm9vIikpOworICAgICAgICBhc3NlcnRTYW1lKGIsIG9iamVjdC5nZXRKU09OT2JqZWN0KCJiYXIiKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmplY3QuZ2V0SlNPTk9iamVjdCgiZm9vIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmplY3QuZ2V0SlNPTkFycmF5KCJiYXIiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGEsIG9iamVjdC5vcHRKU09OQXJyYXkoImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGIsIG9iamVjdC5vcHRKU09OT2JqZWN0KCJiYXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBvYmplY3Qub3B0SlNPTkFycmF5KCJiYXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBvYmplY3Qub3B0SlNPTk9iamVjdCgiZm9vIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROdWxsQ29lcmNpb25Ub1N0cmluZygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdCgpOworICAgICAgICBvYmplY3QucHV0KCJmb28iLCBKU09OT2JqZWN0Lk5VTEwpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm51bGwiLCBvYmplY3QuZ2V0U3RyaW5nKCJmb28iKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFycmF5Q29lcmNpb24oKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiZm9vIiwgIlt0cnVlXSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2JqZWN0LmdldEpTT05BcnJheSgiZm9vIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE9iamVjdENvZXJjaW9uKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IG5ldyBKU09OT2JqZWN0KCk7CisgICAgICAgIG9iamVjdC5wdXQoImZvbyIsICJ7fSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2JqZWN0LmdldEpTT05PYmplY3QoImZvbyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBY2N1bXVsYXRlVmFsdWVDaGVja2luZygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2JqZWN0LmFjY3VtdWxhdGUoImZvbyIsIERvdWJsZS5OYU4pOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBvYmplY3QuYWNjdW11bGF0ZSgiZm9vIiwgMSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmplY3QuYWNjdW11bGF0ZSgiZm9vIiwgRG91YmxlLk5hTik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIG9iamVjdC5hY2N1bXVsYXRlKCJmb28iLCAyKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iamVjdC5hY2N1bXVsYXRlKCJmb28iLCBEb3VibGUuTmFOKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9KU09OQXJyYXkoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgT2JqZWN0IHZhbHVlID0gbmV3IE9iamVjdCgpOworICAgICAgICBvYmplY3QucHV0KCJmb28iLCB0cnVlKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiYmFyIiwgNS4wZCk7CisgICAgICAgIG9iamVjdC5wdXQoImJheiIsIC0wLjBkKTsKKyAgICAgICAgb2JqZWN0LnB1dCgicXV1eCIsIHZhbHVlKTsKKworICAgICAgICBKU09OQXJyYXkgbmFtZXMgPSBuZXcgSlNPTkFycmF5KCk7CisgICAgICAgIG5hbWVzLnB1dCgiYmF6Iik7CisgICAgICAgIG5hbWVzLnB1dCgicXV1eCIpOworICAgICAgICBuYW1lcy5wdXQoImZvbyIpOworCisgICAgICAgIEpTT05BcnJheSBhcnJheSA9IG9iamVjdC50b0pTT05BcnJheShuYW1lcyk7CisgICAgICAgIGFzc2VydEVxdWFscygtMC4wZCwgYXJyYXkuZ2V0KDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHZhbHVlLCBhcnJheS5nZXQoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgYXJyYXkuZ2V0KDIpKTsKKworICAgICAgICBvYmplY3QucHV0KCJmb28iLCBmYWxzZSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBhcnJheS5nZXQoMikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUb0pTT05BcnJheU1pc3NpbmdOYW1lcygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdCgpOworICAgICAgICBvYmplY3QucHV0KCJmb28iLCB0cnVlKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiYmFyIiwgNS4wZCk7CisgICAgICAgIG9iamVjdC5wdXQoImJheiIsIEpTT05PYmplY3QuTlVMTCk7CisKKyAgICAgICAgSlNPTkFycmF5IG5hbWVzID0gbmV3IEpTT05BcnJheSgpOworICAgICAgICBuYW1lcy5wdXQoImJhciIpOworICAgICAgICBuYW1lcy5wdXQoImZvbyIpOworICAgICAgICBuYW1lcy5wdXQoInF1dXgiKTsKKyAgICAgICAgbmFtZXMucHV0KCJiYXoiKTsKKworICAgICAgICBKU09OQXJyYXkgYXJyYXkgPSBvYmplY3QudG9KU09OQXJyYXkobmFtZXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgYXJyYXkubGVuZ3RoKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscyg1LjBkLCBhcnJheS5nZXQoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgYXJyYXkuZ2V0KDEpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFycmF5LmdldCgyKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKEpTT05PYmplY3QuTlVMTCwgYXJyYXkuZ2V0KDMpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9KU09OQXJyYXlOdWxsKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IG5ldyBKU09OT2JqZWN0KCk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBvYmplY3QudG9KU09OQXJyYXkobnVsbCkpOworICAgICAgICBvYmplY3QucHV0KCJmb28iLCA1KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iamVjdC50b0pTT05BcnJheShudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9KU09OQXJyYXlFbmRzVXBFbXB0eSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdCgpOworICAgICAgICBvYmplY3QucHV0KCJmb28iLCA1KTsKKyAgICAgICAgSlNPTkFycmF5IGFycmF5ID0gbmV3IEpTT05BcnJheSgpOworICAgICAgICBhcnJheS5wdXQoImJhciIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgb2JqZWN0LnRvSlNPTkFycmF5KGFycmF5KS5sZW5ndGgoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRvSlNPTkFycmF5Tm9uU3RyaW5nKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IG5ldyBKU09OT2JqZWN0KCk7CisgICAgICAgIG9iamVjdC5wdXQoImZvbyIsIDUpOworICAgICAgICBvYmplY3QucHV0KCJudWxsIiwgMTApOworICAgICAgICBvYmplY3QucHV0KCJmYWxzZSIsIDE1KTsKKworICAgICAgICBKU09OQXJyYXkgbmFtZXMgPSBuZXcgSlNPTkFycmF5KCk7CisgICAgICAgIG5hbWVzLnB1dChKU09OT2JqZWN0Lk5VTEwpOworICAgICAgICBuYW1lcy5wdXQoZmFsc2UpOworICAgICAgICBuYW1lcy5wdXQoImZvbyIpOworCisgICAgICAgIC8vIGFycmF5IGVsZW1lbnRzIGFyZSBjb252ZXJ0ZWQgdG8gc3RyaW5ncyB0byBkbyBuYW1lIGxvb2t1cHMgb24gdGhlIG1hcCEKKyAgICAgICAgSlNPTkFycmF5IGFycmF5ID0gb2JqZWN0LnRvSlNPTkFycmF5KG5hbWVzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGFycmF5Lmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEwLCBhcnJheS5nZXQoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTUsIGFycmF5LmdldCgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBhcnJheS5nZXQoMikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQdXRVbnN1cHBvcnRlZE51bWJlcnMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iamVjdC5wdXQoImZvbyIsIERvdWJsZS5OYU4pOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgb2JqZWN0LnB1dCgiZm9vIiwgRG91YmxlLk5FR0FUSVZFX0lORklOSVRZKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iamVjdC5wdXQoImZvbyIsIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1dFVuc3VwcG9ydGVkTnVtYmVyc0FzT2JqZWN0cygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2JqZWN0LnB1dCgiZm9vIiwgKERvdWJsZSkgRG91YmxlLk5hTik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmplY3QucHV0KCJmb28iLCAoRG91YmxlKSBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgb2JqZWN0LnB1dCgiZm9vIiwgKERvdWJsZSkgRG91YmxlLlBPU0lUSVZFX0lORklOSVRZKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbHRob3VnaCBKU09OT2JqZWN0IGlzIHVzdWFsbHkgZGVmZW5zaXZlIGFib3V0IHdoaWNoIG51bWJlcnMgaXQgYWNjZXB0cywKKyAgICAgKiBpdCBkb2Vzbid0IGNoZWNrIGlucHV0cyBpbiBpdHMgY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZVdpdGhVbnN1cHBvcnRlZE51bWJlcnMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIE1hcDxTdHJpbmcsIE9iamVjdD4gY29udGVudHMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIE9iamVjdD4oKTsKKyAgICAgICAgY29udGVudHMucHV0KCJmb28iLCBEb3VibGUuTmFOKTsKKyAgICAgICAgY29udGVudHMucHV0KCJiYXIiLCBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpOworICAgICAgICBjb250ZW50cy5wdXQoImJheiIsIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSk7CisKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdChjb250ZW50cyk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuTmFOLCBvYmplY3QuZ2V0KCJmb28iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFksIG9iamVjdC5nZXQoImJhciIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgb2JqZWN0LmdldCgiYmF6IikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUb1N0cmluZ1dpdGhVbnN1cHBvcnRlZE51bWJlcnMoKSB7CisgICAgICAgIC8vIHdoZW4gdGhlIG9iamVjdCBjb250YWlucyBhbiB1bnN1cHBvcnRlZCBudW1iZXIsIHRvU3RyaW5nIHJldHVybnMgbnVsbCEKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdChDb2xsZWN0aW9ucy5zaW5nbGV0b25NYXAoImZvbyIsIERvdWJsZS5OYU4pKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG9iamVjdC50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFwQ29uc3RydWN0b3JDb3BpZXNDb250ZW50cygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgTWFwPFN0cmluZywgT2JqZWN0PiBjb250ZW50cyA9IG5ldyBIYXNoTWFwPFN0cmluZywgT2JqZWN0PigpOworICAgICAgICBjb250ZW50cy5wdXQoImZvbyIsIDUpOworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IG5ldyBKU09OT2JqZWN0KGNvbnRlbnRzKTsKKyAgICAgICAgY29udGVudHMucHV0KCJmb28iLCAxMCk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBvYmplY3QuZ2V0KCJmb28iKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1hcENvbnN0cnVjdG9yV2l0aEJvZ3VzRW50cmllcygpIHsKKyAgICAgICAgTWFwPE9iamVjdCwgT2JqZWN0PiBjb250ZW50cyA9IG5ldyBIYXNoTWFwPE9iamVjdCwgT2JqZWN0PigpOworICAgICAgICBjb250ZW50cy5wdXQoNSwgNSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKU09OT2JqZWN0KGNvbnRlbnRzKTsKKyAgICAgICAgICAgIGZhaWwoIkpTT05PYmplY3QgY29uc3RydWN0b3IgZG9lc24ndCB2YWxpZGF0ZSBpdHMgaW5wdXQhIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9rZW5lckNvbnN0cnVjdG9yKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IG5ldyBKU09OT2JqZWN0KG5ldyBKU09OVG9rZW5lcigie1wiZm9vXCI6IGZhbHNlfSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG9iamVjdC5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgb2JqZWN0LmdldCgiZm9vIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUb2tlbmVyQ29uc3RydWN0b3JXcm9uZ1R5cGUoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTk9iamVjdChuZXcgSlNPTlRva2VuZXIoIltcImZvb1wiLCBmYWxzZV0iKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRva2VuZXJDb25zdHJ1Y3Rvck51bGwoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTk9iamVjdCgoSlNPTlRva2VuZXIpIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9rZW5lckNvbnN0cnVjdG9yUGFyc2VGYWlsKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05PYmplY3QobmV3IEpTT05Ub2tlbmVyKCJ7IikpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdHJpbmdDb25zdHJ1Y3RvcigpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdCgie1wiZm9vXCI6IGZhbHNlfSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgb2JqZWN0Lmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBvYmplY3QuZ2V0KCJmb28iKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0cmluZ0NvbnN0cnVjdG9yV3JvbmdUeXBlKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05PYmplY3QoIltcImZvb1wiLCBmYWxzZV0iKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RyaW5nQ29uc3RydWN0b3JOdWxsKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05PYmplY3QoKFN0cmluZykgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdHJpbmdvbnN0cnVjdG9yUGFyc2VGYWlsKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05PYmplY3QoInsiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29weUNvbnN0cnVjdG9yKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IHNvdXJjZSA9IG5ldyBKU09OT2JqZWN0KCk7CisgICAgICAgIHNvdXJjZS5wdXQoImEiLCBKU09OT2JqZWN0Lk5VTEwpOworICAgICAgICBzb3VyY2UucHV0KCJiIiwgZmFsc2UpOworICAgICAgICBzb3VyY2UucHV0KCJjIiwgNSk7CisKKyAgICAgICAgSlNPTk9iamVjdCBjb3B5ID0gbmV3IEpTT05PYmplY3Qoc291cmNlLCBuZXcgU3RyaW5nW10geyAiYSIsICJjIiB9KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGNvcHkubGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoSlNPTk9iamVjdC5OVUxMLCBjb3B5LmdldCgiYSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIGNvcHkuZ2V0KCJjIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgY29weS5vcHQoImIiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvcHlDb25zdHJ1Y3Rvck1pc3NpbmdOYW1lKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IHNvdXJjZSA9IG5ldyBKU09OT2JqZWN0KCk7CisgICAgICAgIHNvdXJjZS5wdXQoImEiLCBKU09OT2JqZWN0Lk5VTEwpOworICAgICAgICBzb3VyY2UucHV0KCJiIiwgZmFsc2UpOworICAgICAgICBzb3VyY2UucHV0KCJjIiwgNSk7CisKKyAgICAgICAgSlNPTk9iamVjdCBjb3B5ID0gbmV3IEpTT05PYmplY3Qoc291cmNlLCBuZXcgU3RyaW5nW117ICJhIiwgImMiLCAiZCIgfSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBjb3B5Lmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEpTT05PYmplY3QuTlVMTCwgY29weS5nZXQoImEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBjb3B5LmdldCgiYyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGNvcHkub3B0SW50KCJiIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBY2N1bXVsYXRlTXV0YXRlc0luUGxhY2UoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiZm9vIiwgNSk7CisgICAgICAgIG9iamVjdC5hY2N1bXVsYXRlKCJmb28iLCA2KTsKKyAgICAgICAgSlNPTkFycmF5IGFycmF5ID0gb2JqZWN0LmdldEpTT05BcnJheSgiZm9vIik7CisgICAgICAgIGFzc2VydEVxdWFscygiWzUsNl0iLCBhcnJheS50b1N0cmluZygpKTsKKyAgICAgICAgb2JqZWN0LmFjY3VtdWxhdGUoImZvbyIsIDcpOworICAgICAgICBhc3NlcnRFcXVhbHMoIls1LDYsN10iLCBhcnJheS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWNjdW11bGF0ZUV4aXN0aW5nQXJyYXkoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05BcnJheSBhcnJheSA9IG5ldyBKU09OQXJyYXkoKTsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdCgpOworICAgICAgICBvYmplY3QucHV0KCJmb28iLCBhcnJheSk7CisgICAgICAgIG9iamVjdC5hY2N1bXVsYXRlKCJmb28iLCA1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbNV0iLCBhcnJheS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWNjdW11bGF0ZVB1dEFycmF5KCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IG5ldyBKU09OT2JqZWN0KCk7CisgICAgICAgIG9iamVjdC5hY2N1bXVsYXRlKCJmb28iLCA1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ7XCJmb29cIjo1fSIsIG9iamVjdC50b1N0cmluZygpKTsKKyAgICAgICAgb2JqZWN0LmFjY3VtdWxhdGUoImZvbyIsIG5ldyBKU09OQXJyYXkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygie1wiZm9vXCI6WzUsW11dfSIsIG9iamVjdC50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWNjdW11bGF0ZU51bGwoKSB7CisgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iamVjdC5hY2N1bXVsYXRlKG51bGwsIDUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eVN0cmluZ0tleSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdCgpOworICAgICAgICBvYmplY3QucHV0KCIiLCA1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIG9iamVjdC5nZXQoIiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ7XCJcIjo1fSIsIG9iamVjdC50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TnVsbFZhbHVlKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IG5ldyBKU09OT2JqZWN0KCk7CisgICAgICAgIG9iamVjdC5wdXQoImZvbyIsIEpTT05PYmplY3QuTlVMTCk7CisgICAgICAgIG9iamVjdC5wdXQoImJhciIsIG51bGwpOworCisgICAgICAgIC8vIHRoZXJlIGFyZSB0d28gd2F5cyB0byByZXByZXNlbnQgbnVsbDsgZWFjaCBiZWhhdmVzIGRpZmZlcmVudGx5IQorICAgICAgICBhc3NlcnRUcnVlKG9iamVjdC5oYXMoImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uob2JqZWN0LmhhcygiYmFyIikpOworICAgICAgICBhc3NlcnRUcnVlKG9iamVjdC5pc051bGwoImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShvYmplY3QuaXNOdWxsKCJiYXIiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEhhcygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdCgpOworICAgICAgICBvYmplY3QucHV0KCJmb28iLCA1KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShvYmplY3QuaGFzKCJmb28iKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG9iamVjdC5oYXMoImJhciIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uob2JqZWN0LmhhcyhudWxsKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE9wdE51bGwoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiZm9vIiwgImJhciIpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgb2JqZWN0Lm9wdChudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgb2JqZWN0Lm9wdEJvb2xlYW4obnVsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLk5hTiwgb2JqZWN0Lm9wdERvdWJsZShudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBvYmplY3Qub3B0SW50KG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDBMLCBvYmplY3Qub3B0TG9uZyhudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBvYmplY3Qub3B0SlNPTkFycmF5KG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG9iamVjdC5vcHRKU09OT2JqZWN0KG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBvYmplY3Qub3B0U3RyaW5nKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIG9iamVjdC5vcHRCb29sZWFuKG51bGwsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAuMGQsIG9iamVjdC5vcHREb3VibGUobnVsbCwgMC4wZCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgb2JqZWN0Lm9wdEludChudWxsLCAxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxTCwgb2JqZWN0Lm9wdExvbmcobnVsbCwgMUwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiYXoiLCBvYmplY3Qub3B0U3RyaW5nKG51bGwsICJiYXoiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRvU3RyaW5nV2l0aEluZGVudEZhY3RvcigpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTk9iamVjdCBvYmplY3QgPSBuZXcgSlNPTk9iamVjdCgpOworICAgICAgICBvYmplY3QucHV0KCJmb28iLCBuZXcgSlNPTkFycmF5KEFycmF5cy5hc0xpc3QoNSwgNikpKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiYmFyIiwgbmV3IEpTT05PYmplY3QoKSk7CisgICAgICAgIFN0cmluZyBmb29iYXIgPSAie1xuIiArCisgICAgICAgICAgICAgICAgIiAgICAgXCJmb29cIjogW1xuIiArCisgICAgICAgICAgICAgICAgIiAgICAgICAgICA1LFxuIiArCisgICAgICAgICAgICAgICAgIiAgICAgICAgICA2XG4iICsKKyAgICAgICAgICAgICAgICAiICAgICBdLFxuIiArCisgICAgICAgICAgICAgICAgIiAgICAgXCJiYXJcIjoge31cbiIgKworICAgICAgICAgICAgICAgICJ9IjsKKyAgICAgICAgU3RyaW5nIGJhcmZvbyA9ICJ7XG4iICsKKyAgICAgICAgICAgICAgICAiICAgICBcImJhclwiOiB7fSxcbiIgKworICAgICAgICAgICAgICAgICIgICAgIFwiZm9vXCI6IFtcbiIgKworICAgICAgICAgICAgICAgICIgICAgICAgICAgNSxcbiIgKworICAgICAgICAgICAgICAgICIgICAgICAgICAgNlxuIiArCisgICAgICAgICAgICAgICAgIiAgICAgXVxuIiArCisgICAgICAgICAgICAgICAgIn0iOworICAgICAgICBTdHJpbmcgc3RyaW5nID0gb2JqZWN0LnRvU3RyaW5nKDUpOworICAgICAgICBhc3NlcnRUcnVlKHN0cmluZywgZm9vYmFyLmVxdWFscyhzdHJpbmcpIHx8IGJhcmZvby5lcXVhbHMoc3RyaW5nKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5hbWVzKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IG5ldyBKU09OT2JqZWN0KCk7CisgICAgICAgIG9iamVjdC5wdXQoImZvbyIsIDUpOworICAgICAgICBvYmplY3QucHV0KCJiYXIiLCA2KTsKKyAgICAgICAgb2JqZWN0LnB1dCgiYmF6IiwgNyk7CisgICAgICAgIEpTT05BcnJheSBhcnJheSA9IG9iamVjdC5uYW1lcygpOworICAgICAgICBhc3NlcnRUcnVlKGFycmF5LnRvU3RyaW5nKCkuY29udGFpbnMoImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhcnJheS50b1N0cmluZygpLmNvbnRhaW5zKCJiYXIiKSk7CisgICAgICAgIGFzc2VydFRydWUoYXJyYXkudG9TdHJpbmcoKS5jb250YWlucygiYmF6IikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlzRW1wdHlPYmplY3QoKSB7CisgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uob2JqZWN0LmtleXMoKS5oYXNOZXh0KCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2JqZWN0LmtleXMoKS5uZXh0KCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEtleXMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiZm9vIiwgNSk7CisgICAgICAgIG9iamVjdC5wdXQoImJhciIsIDYpOworICAgICAgICBvYmplY3QucHV0KCJmb28iLCA3KTsKKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBrZXlzID0gKEl0ZXJhdG9yPFN0cmluZz4pIG9iamVjdC5rZXlzKCk7CisgICAgICAgIFNldDxTdHJpbmc+IHJlc3VsdCA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShrZXlzLmhhc05leHQoKSk7CisgICAgICAgIHJlc3VsdC5hZGQoa2V5cy5uZXh0KCkpOworICAgICAgICBhc3NlcnRUcnVlKGtleXMuaGFzTmV4dCgpKTsKKyAgICAgICAgcmVzdWx0LmFkZChrZXlzLm5leHQoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGtleXMuaGFzTmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBIYXNoU2V0PFN0cmluZz4oQXJyYXlzLmFzTGlzdCgiZm9vIiwgImJhciIpKSwgcmVzdWx0KTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5cy5uZXh0KCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE11dGF0aW5nS2V5c011dGF0ZXNPYmplY3QoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gbmV3IEpTT05PYmplY3QoKTsKKyAgICAgICAgb2JqZWN0LnB1dCgiZm9vIiwgNSk7CisgICAgICAgIEl0ZXJhdG9yIGtleXMgPSBvYmplY3Qua2V5cygpOworICAgICAgICBrZXlzLm5leHQoKTsKKyAgICAgICAga2V5cy5yZW1vdmUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG9iamVjdC5sZW5ndGgoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFF1b3RlKCkgeworICAgICAgICAvLyBjb3ZlcmVkIGJ5IEpTT05TdHJpbmdlclRlc3QudGVzdEVzY2FwaW5nCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFF1b3RlTnVsbCgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJcIlwiIiwgSlNPTk9iamVjdC5xdW90ZShudWxsKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE51bWJlclRvU3RyaW5nKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoIjUiLCBKU09OT2JqZWN0Lm51bWJlclRvU3RyaW5nKDUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCItMCIsIEpTT05PYmplY3QubnVtYmVyVG9TdHJpbmcoLTAuMGQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI5MjIzMzcyMDM2ODU0Nzc1ODA2IiwgSlNPTk9iamVjdC5udW1iZXJUb1N0cmluZyg5MjIzMzcyMDM2ODU0Nzc1ODA2TCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjQuOUUtMzI0IiwgSlNPTk9iamVjdC5udW1iZXJUb1N0cmluZyhEb3VibGUuTUlOX1ZBTFVFKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMS43OTc2OTMxMzQ4NjIzMTU3RTMwOCIsIEpTT05PYmplY3QubnVtYmVyVG9TdHJpbmcoRG91YmxlLk1BWF9WQUxVRSkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgSlNPTk9iamVjdC5udW1iZXJUb1N0cmluZyhEb3VibGUuTmFOKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEpTT05PYmplY3QubnVtYmVyVG9TdHJpbmcoRG91YmxlLk5FR0FUSVZFX0lORklOSVRZKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEpTT05PYmplY3QubnVtYmVyVG9TdHJpbmcoRG91YmxlLlBPU0lUSVZFX0lORklOSVRZKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIwLjAwMSIsIEpTT05PYmplY3QubnVtYmVyVG9TdHJpbmcobmV3IEJpZ0RlY2ltYWwoIjAuMDAxIikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI5MjIzMzcyMDM2ODU0Nzc1ODA2IiwKKyAgICAgICAgICAgICAgICBKU09OT2JqZWN0Lm51bWJlclRvU3RyaW5nKG5ldyBCaWdJbnRlZ2VyKCI5MjIzMzcyMDM2ODU0Nzc1ODA2IikpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEpTT05PYmplY3QubnVtYmVyVG9TdHJpbmcobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvanNvbi9zcmMvdGVzdC9qYXZhL29yZy9qc29uL0pTT05TdHJpbmdlclRlc3QuamF2YSBiL2pzb24vc3JjL3Rlc3QvamF2YS9vcmcvanNvbi9KU09OU3RyaW5nZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWU0ZTBlYwotLS0gL2Rldi9udWxsCisrKyBiL2pzb24vc3JjL3Rlc3QvamF2YS9vcmcvanNvbi9KU09OU3RyaW5nZXJUZXN0LmphdmEKQEAgLTAsMCArMSwzNTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5qc29uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRoaXMgYmxhY2sgYm94IHRlc3Qgd2FzIHdyaXR0ZW4gd2l0aG91dCBpbnNwZWN0aW5nIHRoZSBub24tZnJlZSBvcmcuanNvbiBzb3VyY2Vjb2RlLgorICovCitwdWJsaWMgY2xhc3MgSlNPTlN0cmluZ2VyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eVN0cmluZ2VyKCkgeworICAgICAgICAvLyB3aHkgaXNuJ3QgdGhpcyB0aGUgZW1wdHkgc3RyaW5nPworICAgICAgICBhc3NlcnROdWxsKG5ldyBKU09OU3RyaW5nZXIoKS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmFsdWVKU09OTnVsbCgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTlN0cmluZ2VyIHN0cmluZ2VyID0gbmV3IEpTT05TdHJpbmdlcigpOworICAgICAgICBzdHJpbmdlci5hcnJheSgpOworICAgICAgICBzdHJpbmdlci52YWx1ZShKU09OT2JqZWN0Lk5VTEwpOworICAgICAgICBzdHJpbmdlci5lbmRBcnJheSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIltudWxsXSIsIHN0cmluZ2VyLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eU9iamVjdCgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTlN0cmluZ2VyIHN0cmluZ2VyID0gbmV3IEpTT05TdHJpbmdlcigpOworICAgICAgICBzdHJpbmdlci5vYmplY3QoKTsKKyAgICAgICAgc3RyaW5nZXIuZW5kT2JqZWN0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygie30iLCBzdHJpbmdlci50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW1wdHlBcnJheSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTlN0cmluZ2VyIHN0cmluZ2VyID0gbmV3IEpTT05TdHJpbmdlcigpOworICAgICAgICBzdHJpbmdlci5hcnJheSgpOworICAgICAgICBzdHJpbmdlci5lbmRBcnJheSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIltdIiwgc3RyaW5nZXIudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFycmF5KCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OU3RyaW5nZXIgc3RyaW5nZXIgPSBuZXcgSlNPTlN0cmluZ2VyKCk7CisgICAgICAgIHN0cmluZ2VyLmFycmF5KCk7CisgICAgICAgIHN0cmluZ2VyLnZhbHVlKGZhbHNlKTsKKyAgICAgICAgc3RyaW5nZXIudmFsdWUoNS4wKTsKKyAgICAgICAgc3RyaW5nZXIudmFsdWUoNUwpOworICAgICAgICBzdHJpbmdlci52YWx1ZSgiZml2ZSIpOworICAgICAgICBzdHJpbmdlci52YWx1ZShudWxsKTsKKyAgICAgICAgc3RyaW5nZXIuZW5kQXJyYXkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbZmFsc2UsNSw1LFwiZml2ZVwiLG51bGxdIiwgc3RyaW5nZXIudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFZhbHVlT2JqZWN0TWV0aG9kcygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTlN0cmluZ2VyIHN0cmluZ2VyID0gbmV3IEpTT05TdHJpbmdlcigpOworICAgICAgICBzdHJpbmdlci5hcnJheSgpOworICAgICAgICBzdHJpbmdlci52YWx1ZShCb29sZWFuLkZBTFNFKTsKKyAgICAgICAgc3RyaW5nZXIudmFsdWUoRG91YmxlLnZhbHVlT2YoNS4wKSk7CisgICAgICAgIHN0cmluZ2VyLnZhbHVlKExvbmcudmFsdWVPZig1TCkpOworICAgICAgICBzdHJpbmdlci5lbmRBcnJheSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIltmYWxzZSw1LDVdIiwgc3RyaW5nZXIudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEtleVZhbHVlKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OU3RyaW5nZXIgc3RyaW5nZXIgPSBuZXcgSlNPTlN0cmluZ2VyKCk7CisgICAgICAgIHN0cmluZ2VyLm9iamVjdCgpOworICAgICAgICBzdHJpbmdlci5rZXkoImEiKS52YWx1ZShmYWxzZSk7CisgICAgICAgIHN0cmluZ2VyLmtleSgiYiIpLnZhbHVlKDUuMCk7CisgICAgICAgIHN0cmluZ2VyLmtleSgiYyIpLnZhbHVlKDVMKTsKKyAgICAgICAgc3RyaW5nZXIua2V5KCJkIikudmFsdWUoImZpdmUiKTsKKyAgICAgICAgc3RyaW5nZXIua2V5KCJlIikudmFsdWUobnVsbCk7CisgICAgICAgIHN0cmluZ2VyLmVuZE9iamVjdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIntcImFcIjpmYWxzZSwiICsKKyAgICAgICAgICAgICAgICAiXCJiXCI6NSwiICsKKyAgICAgICAgICAgICAgICAiXCJjXCI6NSwiICsKKyAgICAgICAgICAgICAgICAiXCJkXCI6XCJmaXZlXCIsIiArCisgICAgICAgICAgICAgICAgIlwiZVwiOm51bGx9Iiwgc3RyaW5nZXIudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB3aGF0IGhhcHBlbnMgd2hlbiBleHRyZW1lIHZhbHVlcyBhcmUgZW1pdHRlZC4gU3VjaCB2YWx1ZXMgYXJlIGxpa2VseQorICAgICAqIHRvIGJlIHJvdW5kZWQgZHVyaW5nIHBhcnNpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE51bWVyaWNSZXByZXNlbnRhdGlvbnMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05TdHJpbmdlciBzdHJpbmdlciA9IG5ldyBKU09OU3RyaW5nZXIoKTsKKyAgICAgICAgc3RyaW5nZXIuYXJyYXkoKTsKKyAgICAgICAgc3RyaW5nZXIudmFsdWUoTG9uZy5NQVhfVkFMVUUpOworICAgICAgICBzdHJpbmdlci52YWx1ZShEb3VibGUuTUlOX1ZBTFVFKTsKKyAgICAgICAgc3RyaW5nZXIuZW5kQXJyYXkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbOTIyMzM3MjAzNjg1NDc3NTgwNyw0LjlFLTMyNF0iLCBzdHJpbmdlci50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V2VpcmROdW1iZXJzKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05TdHJpbmdlcigpLmFycmF5KCkudmFsdWUoRG91YmxlLk5hTik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlN0cmluZ2VyKCkuYXJyYXkoKS52YWx1ZShEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05TdHJpbmdlcigpLmFycmF5KCkudmFsdWUoRG91YmxlLlBPU0lUSVZFX0lORklOSVRZKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBKU09OU3RyaW5nZXIgc3RyaW5nZXIgPSBuZXcgSlNPTlN0cmluZ2VyKCk7CisgICAgICAgIHN0cmluZ2VyLmFycmF5KCk7CisgICAgICAgIHN0cmluZ2VyLnZhbHVlKC0wLjBkKTsKKyAgICAgICAgc3RyaW5nZXIudmFsdWUoMC4wZCk7CisgICAgICAgIHN0cmluZ2VyLmVuZEFycmF5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiWy0wLDBdIiwgc3RyaW5nZXIudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1pc21hdGNoZWRTY29wZXMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlN0cmluZ2VyKCkua2V5KCJhIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlN0cmluZ2VyKCkudmFsdWUoImEiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKU09OU3RyaW5nZXIoKS5lbmRPYmplY3QoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKU09OU3RyaW5nZXIoKS5lbmRBcnJheSgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05TdHJpbmdlcigpLmFycmF5KCkuZW5kT2JqZWN0KCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlN0cmluZ2VyKCkub2JqZWN0KCkuZW5kQXJyYXkoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKU09OU3RyaW5nZXIoKS5vYmplY3QoKS5rZXkoImEiKS5rZXkoImEiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKU09OU3RyaW5nZXIoKS5vYmplY3QoKS52YWx1ZShmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE51bGxLZXkoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlN0cmluZ2VyKCkub2JqZWN0KCkua2V5KG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXBlYXRlZEtleSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTlN0cmluZ2VyIHN0cmluZ2VyID0gbmV3IEpTT05TdHJpbmdlcigpOworICAgICAgICBzdHJpbmdlci5vYmplY3QoKTsKKyAgICAgICAgc3RyaW5nZXIua2V5KCJhIikudmFsdWUodHJ1ZSk7CisgICAgICAgIHN0cmluZ2VyLmtleSgiYSIpLnZhbHVlKGZhbHNlKTsKKyAgICAgICAgc3RyaW5nZXIuZW5kT2JqZWN0KCk7CisgICAgICAgIC8vIEpTT05TdHJpbmdlciBkb2Vzbid0IGF0dGVtcHQgdG8gZGV0ZWN0IGR1cGxpY2F0ZXMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ7XCJhXCI6dHJ1ZSxcImFcIjpmYWxzZX0iLCBzdHJpbmdlci50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW1wdHlLZXkoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05TdHJpbmdlciBzdHJpbmdlciA9IG5ldyBKU09OU3RyaW5nZXIoKTsKKyAgICAgICAgc3RyaW5nZXIub2JqZWN0KCk7CisgICAgICAgIHN0cmluZ2VyLmtleSgiIikudmFsdWUoZmFsc2UpOworICAgICAgICBzdHJpbmdlci5lbmRPYmplY3QoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ7XCJcIjpmYWxzZX0iLCBzdHJpbmdlci50b1N0cmluZygpKTsgLy8gbGVnaXQgYmVoYXZpb3VyIQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFc2NhcGluZygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXNjYXBlZEFsbFdheXMoImEiLCAiYSIpOworICAgICAgICBhc3NlcnRFc2NhcGVkQWxsV2F5cygiYVxcXCIiLCAiYVwiIik7CisgICAgICAgIGFzc2VydEVzY2FwZWRBbGxXYXlzKCJcXFwiIiwgIlwiIik7CisgICAgICAgIGFzc2VydEVzY2FwZWRBbGxXYXlzKCI6IiwgIjoiKTsKKyAgICAgICAgYXNzZXJ0RXNjYXBlZEFsbFdheXMoIiwiLCAiLCIpOworICAgICAgICBhc3NlcnRFc2NhcGVkQWxsV2F5cygiXFxiIiwgIlxiIik7CisgICAgICAgIGFzc2VydEVzY2FwZWRBbGxXYXlzKCJcXGYiLCAiXGYiKTsKKyAgICAgICAgYXNzZXJ0RXNjYXBlZEFsbFdheXMoIlxcbiIsICJcbiIpOworICAgICAgICBhc3NlcnRFc2NhcGVkQWxsV2F5cygiXFxyIiwgIlxyIik7CisgICAgICAgIGFzc2VydEVzY2FwZWRBbGxXYXlzKCJcXHQiLCAiXHQiKTsKKyAgICAgICAgYXNzZXJ0RXNjYXBlZEFsbFdheXMoIiAiLCAiICIpOworICAgICAgICBhc3NlcnRFc2NhcGVkQWxsV2F5cygiXFxcXCIsICJcXCIpOworICAgICAgICBhc3NlcnRFc2NhcGVkQWxsV2F5cygieyIsICJ7Iik7CisgICAgICAgIGFzc2VydEVzY2FwZWRBbGxXYXlzKCJ9IiwgIn0iKTsKKyAgICAgICAgYXNzZXJ0RXNjYXBlZEFsbFdheXMoIlsiLCAiWyIpOworICAgICAgICBhc3NlcnRFc2NhcGVkQWxsV2F5cygiXSIsICJdIik7CisgICAgICAgIGFzc2VydEVzY2FwZWRBbGxXYXlzKCJcXHUwMDAwIiwgIlwwIik7CisgICAgICAgIGFzc2VydEVzY2FwZWRBbGxXYXlzKCJcXHUwMDE5IiwgIlx1MDAxOSIpOworICAgICAgICBhc3NlcnRFc2NhcGVkQWxsV2F5cygiICIsICJcdTAwMjAiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0RXNjYXBlZEFsbFdheXMoU3RyaW5nIGVzY2FwZWQsIFN0cmluZyBvcmlnaW5hbCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoIntcIiIgKyBlc2NhcGVkICsgIlwiOmZhbHNlfSIsCisgICAgICAgICAgICAgICAgbmV3IEpTT05TdHJpbmdlcigpLm9iamVjdCgpLmtleShvcmlnaW5hbCkudmFsdWUoZmFsc2UpLmVuZE9iamVjdCgpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIntcImFcIjpcIiIgKyBlc2NhcGVkICsgIlwifSIsCisgICAgICAgICAgICAgICAgbmV3IEpTT05TdHJpbmdlcigpLm9iamVjdCgpLmtleSgiYSIpLnZhbHVlKG9yaWdpbmFsKS5lbmRPYmplY3QoKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbXCIiICsgZXNjYXBlZCArICJcIl0iLAorICAgICAgICAgICAgICAgIG5ldyBKU09OU3RyaW5nZXIoKS5hcnJheSgpLnZhbHVlKG9yaWdpbmFsKS5lbmRBcnJheSgpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlwiIiArIGVzY2FwZWQgKyAiXCIiLCBKU09OT2JqZWN0LnF1b3RlKG9yaWdpbmFsKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEpTT05BcnJheUFzVmFsdWUoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05BcnJheSBhcnJheSA9IG5ldyBKU09OQXJyYXkoKTsKKyAgICAgICAgYXJyYXkucHV0KGZhbHNlKTsKKyAgICAgICAgSlNPTlN0cmluZ2VyIHN0cmluZ2VyID0gbmV3IEpTT05TdHJpbmdlcigpOworICAgICAgICBzdHJpbmdlci5hcnJheSgpOworICAgICAgICBzdHJpbmdlci52YWx1ZShhcnJheSk7CisgICAgICAgIHN0cmluZ2VyLmVuZEFycmF5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiW1tmYWxzZV1dIiwgc3RyaW5nZXIudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEpTT05PYmplY3RBc1ZhbHVlKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IG5ldyBKU09OT2JqZWN0KCk7CisgICAgICAgIG9iamVjdC5wdXQoImEiLCBmYWxzZSk7CisgICAgICAgIEpTT05TdHJpbmdlciBzdHJpbmdlciA9IG5ldyBKU09OU3RyaW5nZXIoKTsKKyAgICAgICAgc3RyaW5nZXIub2JqZWN0KCk7CisgICAgICAgIHN0cmluZ2VyLmtleSgiYiIpLnZhbHVlKG9iamVjdCk7CisgICAgICAgIHN0cmluZ2VyLmVuZE9iamVjdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIntcImJcIjp7XCJhXCI6ZmFsc2V9fSIsIHN0cmluZ2VyLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBcnJheU5lc3RpbmdNYXhEZXB0aFN1cHBvcnRzMjAoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05TdHJpbmdlciBzdHJpbmdlciA9IG5ldyBKU09OU3RyaW5nZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDsgaSsrKSB7CisgICAgICAgICAgICBzdHJpbmdlci5hcnJheSgpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjA7IGkrKykgeworICAgICAgICAgICAgc3RyaW5nZXIuZW5kQXJyYXkoKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIltbW1tbW1tbW1tbW1tbW1tbW1tbXV1dXV1dXV1dXV1dXV1dXV1dXV0iLCBzdHJpbmdlci50b1N0cmluZygpKTsKKworICAgICAgICBzdHJpbmdlciA9IG5ldyBKU09OU3RyaW5nZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDsgaSsrKSB7CisgICAgICAgICAgICBzdHJpbmdlci5hcnJheSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE9iamVjdE5lc3RpbmdNYXhEZXB0aFN1cHBvcnRzMjAoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05TdHJpbmdlciBzdHJpbmdlciA9IG5ldyBKU09OU3RyaW5nZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDsgaSsrKSB7CisgICAgICAgICAgICBzdHJpbmdlci5vYmplY3QoKTsKKyAgICAgICAgICAgIHN0cmluZ2VyLmtleSgiYSIpOworICAgICAgICB9CisgICAgICAgIHN0cmluZ2VyLnZhbHVlKGZhbHNlKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDsgaSsrKSB7CisgICAgICAgICAgICBzdHJpbmdlci5lbmRPYmplY3QoKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIntcImFcIjp7XCJhXCI6e1wiYVwiOntcImFcIjp7XCJhXCI6e1wiYVwiOntcImFcIjp7XCJhXCI6e1wiYVwiOntcImFcIjoiICsKKyAgICAgICAgICAgICAgICAie1wiYVwiOntcImFcIjp7XCJhXCI6e1wiYVwiOntcImFcIjp7XCJhXCI6e1wiYVwiOntcImFcIjp7XCJhXCI6e1wiYVwiOmZhbHNlIiArCisgICAgICAgICAgICAgICAgIn19fX19fX19fX19fX19fX19fX19Iiwgc3RyaW5nZXIudG9TdHJpbmcoKSk7CisKKyAgICAgICAgc3RyaW5nZXIgPSBuZXcgSlNPTlN0cmluZ2VyKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjA7IGkrKykgeworICAgICAgICAgICAgc3RyaW5nZXIub2JqZWN0KCk7CisgICAgICAgICAgICBzdHJpbmdlci5rZXkoImEiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNaXhlZE1heERlcHRoU3VwcG9ydHMyMCgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTlN0cmluZ2VyIHN0cmluZ2VyID0gbmV3IEpTT05TdHJpbmdlcigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDIwOyBpKz0yKSB7CisgICAgICAgICAgICBzdHJpbmdlci5hcnJheSgpOworICAgICAgICAgICAgc3RyaW5nZXIub2JqZWN0KCk7CisgICAgICAgICAgICBzdHJpbmdlci5rZXkoImEiKTsKKyAgICAgICAgfQorICAgICAgICBzdHJpbmdlci52YWx1ZShmYWxzZSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjA7IGkrPTIpIHsKKyAgICAgICAgICAgIHN0cmluZ2VyLmVuZE9iamVjdCgpOworICAgICAgICAgICAgc3RyaW5nZXIuZW5kQXJyYXkoKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIlt7XCJhXCI6W3tcImFcIjpbe1wiYVwiOlt7XCJhXCI6W3tcImFcIjoiICsKKyAgICAgICAgICAgICAgICAiW3tcImFcIjpbe1wiYVwiOlt7XCJhXCI6W3tcImFcIjpbe1wiYVwiOmZhbHNlIiArCisgICAgICAgICAgICAgICAgIn1dfV19XX1dfV19XX1dfV19XX1dIiwgc3RyaW5nZXIudG9TdHJpbmcoKSk7CisKKyAgICAgICAgc3RyaW5nZXIgPSBuZXcgSlNPTlN0cmluZ2VyKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjA7IGkrPTIpIHsKKyAgICAgICAgICAgIHN0cmluZ2VyLmFycmF5KCk7CisgICAgICAgICAgICBzdHJpbmdlci5vYmplY3QoKTsKKyAgICAgICAgICAgIHN0cmluZ2VyLmtleSgiYSIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1heERlcHRoV2l0aEFycmF5VmFsdWUoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05BcnJheSBhcnJheSA9IG5ldyBKU09OQXJyYXkoKTsKKyAgICAgICAgYXJyYXkucHV0KGZhbHNlKTsKKworICAgICAgICBKU09OU3RyaW5nZXIgc3RyaW5nZXIgPSBuZXcgSlNPTlN0cmluZ2VyKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjA7IGkrKykgeworICAgICAgICAgICAgc3RyaW5nZXIuYXJyYXkoKTsKKyAgICAgICAgfQorICAgICAgICBzdHJpbmdlci52YWx1ZShhcnJheSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjA7IGkrKykgeworICAgICAgICAgICAgc3RyaW5nZXIuZW5kQXJyYXkoKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIltbW1tbW1tbW1tbW1tbW1tbW1tbW2ZhbHNlXV1dXV1dXV1dXV1dXV1dXV1dXV1dIiwgc3RyaW5nZXIudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1heERlcHRoV2l0aE9iamVjdFZhbHVlKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IG9iamVjdCA9IG5ldyBKU09OT2JqZWN0KCk7CisgICAgICAgIG9iamVjdC5wdXQoImEiLCBmYWxzZSk7CisgICAgICAgIEpTT05TdHJpbmdlciBzdHJpbmdlciA9IG5ldyBKU09OU3RyaW5nZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDsgaSsrKSB7CisgICAgICAgICAgICBzdHJpbmdlci5vYmplY3QoKTsKKyAgICAgICAgICAgIHN0cmluZ2VyLmtleSgiYiIpOworICAgICAgICB9CisgICAgICAgIHN0cmluZ2VyLnZhbHVlKG9iamVjdCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjA7IGkrKykgeworICAgICAgICAgICAgc3RyaW5nZXIuZW5kT2JqZWN0KCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ7XCJiXCI6e1wiYlwiOntcImJcIjp7XCJiXCI6e1wiYlwiOntcImJcIjp7XCJiXCI6e1wiYlwiOntcImJcIjp7XCJiXCI6IiArCisgICAgICAgICAgICAgICAgIntcImJcIjp7XCJiXCI6e1wiYlwiOntcImJcIjp7XCJiXCI6e1wiYlwiOntcImJcIjp7XCJiXCI6e1wiYlwiOntcImJcIjoiICsKKyAgICAgICAgICAgICAgICAie1wiYVwiOmZhbHNlfX19fX19fX19fX19fX19fX19fX19Iiwgc3RyaW5nZXIudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE11bHRpcGxlUm9vdHMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05TdHJpbmdlciBzdHJpbmdlciA9IG5ldyBKU09OU3RyaW5nZXIoKTsKKyAgICAgICAgc3RyaW5nZXIuYXJyYXkoKTsKKyAgICAgICAgc3RyaW5nZXIuZW5kQXJyYXkoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0cmluZ2VyLm9iamVjdCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2pzb24vc3JjL3Rlc3QvamF2YS9vcmcvanNvbi9KU09OVG9rZW5lclRlc3QuamF2YSBiL2pzb24vc3JjL3Rlc3QvamF2YS9vcmcvanNvbi9KU09OVG9rZW5lclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZTNhNTlhCi0tLSAvZGV2L251bGwKKysrIGIvanNvbi9zcmMvdGVzdC9qYXZhL29yZy9qc29uL0pTT05Ub2tlbmVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjIwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuanNvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5Bc3NlcnRpb25GYWlsZWRFcnJvcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGhpcyBibGFjayBib3ggdGVzdCB3YXMgd3JpdHRlbiB3aXRob3V0IGluc3BlY3RpbmcgdGhlIG5vbi1mcmVlIG9yZy5qc29uIHNvdXJjZWNvZGUuCisgKi8KK3B1YmxpYyBjbGFzcyBKU09OVG9rZW5lclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TnVsbHMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIC8vIEpTT05Ub2tlbmVyIGFjY2VwdHMgbnVsbCwgb25seSB0byBmYWlsIGxhdGVyIG9uIGFsbW9zdCBhbGwgQVBJcyEKKyAgICAgICAgbmV3IEpTT05Ub2tlbmVyKG51bGwpLmJhY2soKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05Ub2tlbmVyKG51bGwpLm1vcmUoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKU09OVG9rZW5lcihudWxsKS5uZXh0KCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlRva2VuZXIobnVsbCkubmV4dCgzKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKU09OVG9rZW5lcihudWxsKS5uZXh0KCdBJyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlRva2VuZXIobnVsbCkubmV4dENsZWFuKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlRva2VuZXIobnVsbCkubmV4dFN0cmluZygnIicpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05Ub2tlbmVyKG51bGwpLm5leHRUbygnQScpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05Ub2tlbmVyKG51bGwpLm5leHRUbygiQUJDIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlRva2VuZXIobnVsbCkubmV4dFZhbHVlKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlRva2VuZXIobnVsbCkuc2tpcFBhc3QoIkFCQyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05Ub2tlbmVyKG51bGwpLnNraXBUbygnQScpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoImZvbyEgYXQgY2hhcmFjdGVyIDAgb2YgbnVsbCIsCisgICAgICAgICAgICAgICAgbmV3IEpTT05Ub2tlbmVyKG51bGwpLnN5bnRheEVycm9yKCJmb28hIikuZ2V0TWVzc2FnZSgpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIiBhdCBjaGFyYWN0ZXIgMCBvZiBudWxsIiwgbmV3IEpTT05Ub2tlbmVyKG51bGwpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eVN0cmluZygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTlRva2VuZXIgYmFja1Rva2VuZXIgPSBuZXcgSlNPTlRva2VuZXIoIiIpOworICAgICAgICBiYWNrVG9rZW5lci5iYWNrKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiIGF0IGNoYXJhY3RlciAwIG9mICIsIGJhY2tUb2tlbmVyLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRGYWxzZShuZXcgSlNPTlRva2VuZXIoIiIpLm1vcmUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygnXDAnLCBuZXcgSlNPTlRva2VuZXIoIiIpLm5leHQoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlRva2VuZXIoIiIpLm5leHQoMyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05Ub2tlbmVyKCIiKS5uZXh0KCdBJyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygnXDAnLCBuZXcgSlNPTlRva2VuZXIoIiIpLm5leHRDbGVhbigpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKU09OVG9rZW5lcigiIikubmV4dFN0cmluZygnIicpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIG5ldyBKU09OVG9rZW5lcigiIikubmV4dFRvKCdBJykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIG5ldyBKU09OVG9rZW5lcigiIikubmV4dFRvKCJBQkMiKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlRva2VuZXIoIiIpLm5leHRWYWx1ZSgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBuZXcgSlNPTlRva2VuZXIoIiIpLnNraXBQYXN0KCJBQkMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdcMCcsIG5ldyBKU09OVG9rZW5lcigiIikuc2tpcFRvKCdBJykpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZvbyEgYXQgY2hhcmFjdGVyIDAgb2YgIiwKKyAgICAgICAgICAgICAgICBuZXcgSlNPTlRva2VuZXIoIiIpLnN5bnRheEVycm9yKCJmb28hIikuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIgYXQgY2hhcmFjdGVyIDAgb2YgIiwgbmV3IEpTT05Ub2tlbmVyKCIiKS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2hhcmFjdGVyTmF2aWdhdGlvbigpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTlRva2VuZXIgYWJjZGVUb2tlbmVyID0gbmV3IEpTT05Ub2tlbmVyKCJBQkNERSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ0EnLCBhYmNkZVRva2VuZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdCJywgYWJjZGVUb2tlbmVyLm5leHQoJ0InKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQ0QiLCBhYmNkZVRva2VuZXIubmV4dCgyKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhYmNkZVRva2VuZXIubmV4dCgyKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdFJywgYWJjZGVUb2tlbmVyLm5leHRDbGVhbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdcMCcsIGFiY2RlVG9rZW5lci5uZXh0KCkpOworICAgICAgICBhc3NlcnRGYWxzZShhYmNkZVRva2VuZXIubW9yZSgpKTsKKyAgICAgICAgYWJjZGVUb2tlbmVyLmJhY2soKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhYmNkZVRva2VuZXIubW9yZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdFJywgYWJjZGVUb2tlbmVyLm5leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEJhY2tOZXh0QW5kTW9yZSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTlRva2VuZXIgYWJjVG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiQUJDIik7CisgICAgICAgIGFzc2VydFRydWUoYWJjVG9rZW5lci5tb3JlKCkpOworICAgICAgICBhYmNUb2tlbmVyLm5leHQoKTsKKyAgICAgICAgYWJjVG9rZW5lci5uZXh0KCk7CisgICAgICAgIGFzc2VydFRydWUoYWJjVG9rZW5lci5tb3JlKCkpOworICAgICAgICBhYmNUb2tlbmVyLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoYWJjVG9rZW5lci5tb3JlKCkpOworICAgICAgICBhYmNUb2tlbmVyLmJhY2soKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhYmNUb2tlbmVyLm1vcmUoKSk7CisgICAgICAgIGFiY1Rva2VuZXIubmV4dCgpOworICAgICAgICBhc3NlcnRGYWxzZShhYmNUb2tlbmVyLm1vcmUoKSk7CisgICAgICAgIGFiY1Rva2VuZXIuYmFjaygpOworICAgICAgICBhYmNUb2tlbmVyLmJhY2soKTsKKyAgICAgICAgYWJjVG9rZW5lci5iYWNrKCk7CisgICAgICAgIGFiY1Rva2VuZXIuYmFjaygpOyAvLyB5b3UgY2FuIGJhY2sgdXAgYmVmb3JlIHRoZSBiZWdpbm5pbmcgb2YgYSBTdHJpbmchCisgICAgICAgIGFzc2VydEVxdWFscygnQScsIGFiY1Rva2VuZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV4dE1hdGNoaW5nKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OVG9rZW5lciBhYmNkVG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiQUJDRCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ0EnLCBhYmNkVG9rZW5lci5uZXh0KCdBJykpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWJjZFRva2VuZXIubmV4dCgnQycpOyAvLyBhbHRob3VnaCBpdCBmYWlsZWQsIHRoaXMgb3AgY29uc3VtZXMgYSBjaGFyYWN0ZXIgb2YgaW5wdXQKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdDJywgYWJjZFRva2VuZXIubmV4dCgnQycpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdEJywgYWJjZFRva2VuZXIubmV4dCgnRCcpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFiY2RUb2tlbmVyLm5leHQoJ0UnKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV4dE4oKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05Ub2tlbmVyIGFiY2RlVG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiQUJDREVGIik7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgYWJjZGVUb2tlbmVyLm5leHQoMCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWJjZGVUb2tlbmVyLm5leHQoNyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiQUJDIiwgYWJjZGVUb2tlbmVyLm5leHQoMykpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWJjZGVUb2tlbmVyLm5leHQoNCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5leHROV2l0aEFsbFJlbWFpbmluZygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTlRva2VuZXIgdG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiQUJDREVGIik7CisgICAgICAgIHRva2VuZXIubmV4dCgzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRva2VuZXIubmV4dCgzKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnRpb25GYWlsZWRFcnJvciBlcnJvciA9IG5ldyBBc3NlcnRpb25GYWlsZWRFcnJvcigib2ZmLWJ5LW9uZSBlcnJvcj8iKTsKKyAgICAgICAgICAgIGVycm9yLmluaXRDYXVzZShlKTsKKyAgICAgICAgICAgIHRocm93IGVycm9yOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5leHQwKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OVG9rZW5lciB0b2tlbmVyID0gbmV3IEpTT05Ub2tlbmVyKCJBQkNERUYiKTsKKyAgICAgICAgdG9rZW5lci5uZXh0KDUpOworICAgICAgICB0b2tlbmVyLm5leHQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRva2VuZXIubmV4dCgwKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBFcnJvciBlcnJvciA9IG5ldyBBc3NlcnRpb25GYWlsZWRFcnJvcigiUmV0dXJuaW5nIGFuIGVtcHR5IHN0cmluZyBzaG91bGQgYmUgdmFsaWQiKTsKKyAgICAgICAgICAgIGVycm9yLmluaXRDYXVzZShlKTsKKyAgICAgICAgICAgIHRocm93IGVycm9yOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5leHRDbGVhbkNvbW1lbnRzKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OVG9rZW5lciB0b2tlbmVyID0gbmV3IEpTT05Ub2tlbmVyKAorICAgICAgICAgICAgICAgICIgIEEgIC8qWFgqL0IvKlhYLy9YWFxuLy9YWFxuWFgqL0MvL1gvL1gvL1hcbkQvKlgqLy8vWFxuIik7CisgICAgICAgIGFzc2VydEVxdWFscygnQScsIHRva2VuZXIubmV4dENsZWFuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ0InLCB0b2tlbmVyLm5leHRDbGVhbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdDJywgdG9rZW5lci5uZXh0Q2xlYW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygnRCcsIHRva2VuZXIubmV4dENsZWFuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ1wwJywgdG9rZW5lci5uZXh0Q2xlYW4oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5leHRDbGVhbk5lc3RlZENTdHlsZUNvbW1lbnRzKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OVG9rZW5lciB0b2tlbmVyID0gbmV3IEpTT05Ub2tlbmVyKCJBIC8qIEIgLyogQyAqLyBEICovIEUiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdBJywgdG9rZW5lci5uZXh0Q2xlYW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygnRCcsIHRva2VuZXIubmV4dENsZWFuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoJyonLCB0b2tlbmVyLm5leHRDbGVhbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCcvJywgdG9rZW5lci5uZXh0Q2xlYW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygnRScsIHRva2VuZXIubmV4dENsZWFuKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNvbWUgYXBwbGljYXRpb25zIHJlbHkgb24gcGFyc2luZyAnIycgdG8gbGVhZCBhbiBlbmQtb2YtbGluZSBjb21tZW50LgorICAgICAqIGh0dHA6Ly9iLzI1NzE0MjMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV4dENsZWFuSGFzaENvbW1lbnRzKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OVG9rZW5lciB0b2tlbmVyID0gbmV3IEpTT05Ub2tlbmVyKCJBICMgQiAqLyAvKiBDICovIFxuRCAjIik7CisgICAgICAgIGFzc2VydEVxdWFscygnQScsIHRva2VuZXIubmV4dENsZWFuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ0QnLCB0b2tlbmVyLm5leHRDbGVhbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdcMCcsIHRva2VuZXIubmV4dENsZWFuKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROZXh0Q2xlYW5Db21tZW50c1RyYWlsaW5nU2luZ2xlU2xhc2goKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIEpTT05Ub2tlbmVyIHRva2VuZXIgPSBuZXcgSlNPTlRva2VuZXIoIiAvIFMgLyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoJy8nLCB0b2tlbmVyLm5leHRDbGVhbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdTJywgdG9rZW5lci5uZXh0Q2xlYW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygnLycsIHRva2VuZXIubmV4dENsZWFuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5leHRDbGVhbiBkb2Vzbid0IGNvbnN1bWUgYSB0cmFpbGluZyBzbGFzaCIsCisgICAgICAgICAgICAgICAgJ1wwJywgdG9rZW5lci5uZXh0Q2xlYW4oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5leHRDbGVhblRyYWlsaW5nT3BlbkNvbW1lbnQoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlRva2VuZXIoIiAgLyogIikubmV4dENsZWFuKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygnXDAnLCBuZXcgSlNPTlRva2VuZXIoIiAgLy8gIikubmV4dENsZWFuKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROZXh0Q2xlYW5OZXdsaW5lRGVsaW1pdGVycygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdCJywgbmV3IEpTT05Ub2tlbmVyKCIgIC8vIFxyXG4gIEIgIikubmV4dENsZWFuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ0InLCBuZXcgSlNPTlRva2VuZXIoIiAgLy8gXG4gIEIgIikubmV4dENsZWFuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ0InLCBuZXcgSlNPTlRva2VuZXIoIiAgLy8gXHIgIEIgIikubmV4dENsZWFuKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROZXh0Q2xlYW5Ta2lwcGVkV2hpdGVzcGFjZSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyYWN0ZXIgdGFidWxhdGlvbiIsICdBJywgbmV3IEpTT05Ub2tlbmVyKCJcdEEiKS5uZXh0Q2xlYW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibGluZSBmZWVkIiwgICAgICAgICAgICAnQScsIG5ldyBKU09OVG9rZW5lcigiXG5BIikubmV4dENsZWFuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImNhcnJpYWdlIHJldHVybiIsICAgICAgJ0EnLCBuZXcgSlNPTlRva2VuZXIoIlxyQSIpLm5leHRDbGVhbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzcGFjZSIsICAgICAgICAgICAgICAgICdBJywgbmV3IEpTT05Ub2tlbmVyKCIgQSIpLm5leHRDbGVhbigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB3aGljaCBjaGFyYWN0ZXJzIHRva2VuZXIgdHJlYXRzIGFzIGlnbm9yYWJsZSB3aGl0ZXNwYWNlLiBTZWUgS2V2aW4gQm91cnJpbGxpb24ncworICAgICAqIDxhIGhyZWY9Imh0dHBzOi8vc3ByZWFkc2hlZXRzLmdvb2dsZS5jb20vcHViP2tleT1wZDhkQVF5SGJkZXdSc25FNXg1R3pLUSI+bGlzdAorICAgICAqIG9mIHdoaXRlc3BhY2UgY2hhcmFjdGVyczwvYT4uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE5leHRDbGVhblJldGFpbmVkV2hpdGVzcGFjZSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0Tm90Q2xlYW4oIm51bGwiLCAgICAgICAgICAgICAgICAgICAgICAnXHUwMDAwJyk7CisgICAgICAgIGFzc2VydE5vdENsZWFuKCJuZXh0IGxpbmUiLCAgICAgICAgICAgICAgICAgJ1x1MDA4NScpOworICAgICAgICBhc3NlcnROb3RDbGVhbigibm9uLWJyZWFraW5nIHNwYWNlIiwgICAgICAgICdcdTAwYTAnKTsKKyAgICAgICAgYXNzZXJ0Tm90Q2xlYW4oIm9naGFtIHNwYWNlIG1hcmsiLCAgICAgICAgICAnXHUxNjgwJyk7CisgICAgICAgIGFzc2VydE5vdENsZWFuKCJtb25nb2xpYW4gdm93ZWwgc2VwYXJhdG9yIiwgJ1x1MTgwZScpOworICAgICAgICBhc3NlcnROb3RDbGVhbigiZW4gcXVhZCIsICAgICAgICAgICAgICAgICAgICdcdTIwMDAnKTsKKyAgICAgICAgYXNzZXJ0Tm90Q2xlYW4oImVtIHF1YWQiLCAgICAgICAgICAgICAgICAgICAnXHUyMDAxJyk7CisgICAgICAgIGFzc2VydE5vdENsZWFuKCJlbiBzcGFjZSIsICAgICAgICAgICAgICAgICAgJ1x1MjAwMicpOworICAgICAgICBhc3NlcnROb3RDbGVhbigiZW0gc3BhY2UiLCAgICAgICAgICAgICAgICAgICdcdTIwMDMnKTsKKyAgICAgICAgYXNzZXJ0Tm90Q2xlYW4oInRocmVlLXBlci1lbSBzcGFjZSIsICAgICAgICAnXHUyMDA0Jyk7CisgICAgICAgIGFzc2VydE5vdENsZWFuKCJmb3VyLXBlci1lbSBzcGFjZSIsICAgICAgICAgJ1x1MjAwNScpOworICAgICAgICBhc3NlcnROb3RDbGVhbigic2l4LXBlci1lbSBzcGFjZSIsICAgICAgICAgICdcdTIwMDYnKTsKKyAgICAgICAgYXNzZXJ0Tm90Q2xlYW4oImZpZ3VyZSBzcGFjZSIsICAgICAgICAgICAgICAnXHUyMDA3Jyk7CisgICAgICAgIGFzc2VydE5vdENsZWFuKCJwdW5jdHVhdGlvbiBzcGFjZSIsICAgICAgICAgJ1x1MjAwOCcpOworICAgICAgICBhc3NlcnROb3RDbGVhbigidGhpbiBzcGFjZSIsICAgICAgICAgICAgICAgICdcdTIwMDknKTsKKyAgICAgICAgYXNzZXJ0Tm90Q2xlYW4oImhhaXIgc3BhY2UiLCAgICAgICAgICAgICAgICAnXHUyMDBhJyk7CisgICAgICAgIGFzc2VydE5vdENsZWFuKCJ6ZXJvLXdpZHRoIHNwYWNlIiwgICAgICAgICAgJ1x1MjAwYicpOworICAgICAgICBhc3NlcnROb3RDbGVhbigibGVmdC10by1yaWdodCBtYXJrIiwgICAgICAgICdcdTIwMGUnKTsKKyAgICAgICAgYXNzZXJ0Tm90Q2xlYW4oInJpZ2h0LXRvLWxlZnQgbWFyayIsICAgICAgICAnXHUyMDBmJyk7CisgICAgICAgIGFzc2VydE5vdENsZWFuKCJsaW5lIHNlcGFyYXRvciIsICAgICAgICAgICAgJ1x1MjAyOCcpOworICAgICAgICBhc3NlcnROb3RDbGVhbigicGFyYWdyYXBoIHNlcGFyYXRvciIsICAgICAgICdcdTIwMjknKTsKKyAgICAgICAgYXNzZXJ0Tm90Q2xlYW4oIm5hcnJvdyBub24tYnJlYWtpbmcgc3BhY2UiLCAnXHUyMDJmJyk7CisgICAgICAgIGFzc2VydE5vdENsZWFuKCJtZWRpdW0gbWF0aGVtYXRpY2FsIHNwYWNlIiwgJ1x1MjA1ZicpOworICAgICAgICBhc3NlcnROb3RDbGVhbigiaWRlb2dyYXBoaWMgc3BhY2UiLCAgICAgICAgICdcdTMwMDAnKTsKKyAgICAgICAgYXNzZXJ0Tm90Q2xlYW4oImxpbmUgdGFidWxhdGlvbiIsICAgICAgICAgICAnXHUwMDBiJyk7CisgICAgICAgIGFzc2VydE5vdENsZWFuKCJmb3JtIGZlZWQiLCAgICAgICAgICAgICAgICAgJ1x1MDAwYycpOworICAgICAgICBhc3NlcnROb3RDbGVhbigiaW5mb3JtYXRpb24gc2VwYXJhdG9yIDQiLCAgICdcdTAwMWMnKTsKKyAgICAgICAgYXNzZXJ0Tm90Q2xlYW4oImluZm9ybWF0aW9uIHNlcGFyYXRvciAzIiwgICAnXHUwMDFkJyk7CisgICAgICAgIGFzc2VydE5vdENsZWFuKCJpbmZvcm1hdGlvbiBzZXBhcmF0b3IgMiIsICAgJ1x1MDAxZScpOworICAgICAgICBhc3NlcnROb3RDbGVhbigiaW5mb3JtYXRpb24gc2VwYXJhdG9yIDEiLCAgICdcdTAwMWYnKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0Tm90Q2xlYW4oU3RyaW5nIG5hbWUsIGNoYXIgYykgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSBjaGFyYWN0ZXIgIiArIG5hbWUgKyAiIGlzIG5vdCB3aGl0ZXNwYWNlIGFjY29yZGluZyB0byB0aGUgSlNPTiBzcGVjLiIsCisgICAgICAgICAgICAgICAgYywgbmV3IEpTT05Ub2tlbmVyKG5ldyBTdHJpbmcobmV3IGNoYXJbXSB7IGMsICdBJyB9KSkubmV4dENsZWFuKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROZXh0U3RyaW5nKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIG5ldyBKU09OVG9rZW5lcigiJyIpLm5leHRTdHJpbmcoJ1wnJykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIG5ldyBKU09OVG9rZW5lcigiXCIiKS5uZXh0U3RyaW5nKCdcIicpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkMiLCBuZXcgSlNPTlRva2VuZXIoIkFCQydERUYiKS5uZXh0U3RyaW5nKCdcJycpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkMiLCBuZXcgSlNPTlRva2VuZXIoIkFCQycnJ0RFRiIpLm5leHRTdHJpbmcoJ1wnJykpOworCisgICAgICAgIC8vIG5leHRTdHJpbmcgcGVybWl0cyBzbGFzaC1lc2NhcGluZyBvZiBhcmJpdHJhcnkgY2hhcmFjdGVycyEKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkMiLCBuZXcgSlNPTlRva2VuZXIoIkFcXEJcXEMnREVGIikubmV4dFN0cmluZygnXCcnKSk7CisKKyAgICAgICAgSlNPTlRva2VuZXIgdG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiICdhYmMnICdkZWYnIFwiZ2hpXCIiKTsKKyAgICAgICAgdG9rZW5lci5uZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygnXCcnLCB0b2tlbmVyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYWJjIiwgdG9rZW5lci5uZXh0U3RyaW5nKCdcJycpKTsKKyAgICAgICAgdG9rZW5lci5uZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygnXCcnLCB0b2tlbmVyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZGVmIiwgdG9rZW5lci5uZXh0U3RyaW5nKCdcJycpKTsKKyAgICAgICAgdG9rZW5lci5uZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygnIicsIHRva2VuZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnaGkiLCB0b2tlbmVyLm5leHRTdHJpbmcoJ1wiJykpOworICAgICAgICBhc3NlcnRGYWxzZSh0b2tlbmVyLm1vcmUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5leHRTdHJpbmdOb0RlbGltaXRlcigpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKU09OVG9rZW5lcigiIikubmV4dFN0cmluZygnXCcnKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBKU09OVG9rZW5lciB0b2tlbmVyID0gbmV3IEpTT05Ub2tlbmVyKCIgJ2FiYyIpOworICAgICAgICB0b2tlbmVyLm5leHQoKTsKKyAgICAgICAgdG9rZW5lci5uZXh0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2tlbmVyLm5leHQoJ1wnJyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5leHRTdHJpbmdFc2NhcGVkUXVvdGUoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlRva2VuZXIoImFiY1xcIikubmV4dFN0cmluZygnIicpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHdlJ3JlIG1peGluZyBKYXZhIGVzY2FwaW5nIGxpa2UgXCIgYW5kIEphdmFTY3JpcHQgZXNjYXBpbmcgbGlrZSBcXFwiCisgICAgICAgIC8vIHdoaWNoIG1ha2VzIHRoZXNlIHRlc3RzIGV4dHJhIHRyaWNreSB0byByZWFkIQorICAgICAgICBhc3NlcnRFcXVhbHMoImFiY1wiZGVmIiwgbmV3IEpTT05Ub2tlbmVyKCJhYmNcXFwiZGVmXCJnaGkiKS5uZXh0U3RyaW5nKCciJykpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFiY1xcZGVmIiwgbmV3IEpTT05Ub2tlbmVyKCJhYmNcXFxcZGVmXCJnaGkiKS5uZXh0U3RyaW5nKCciJykpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFiYy9kZWYiLCBuZXcgSlNPTlRva2VuZXIoImFiY1xcL2RlZlwiZ2hpIikubmV4dFN0cmluZygnIicpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhYmNcYmRlZiIsIG5ldyBKU09OVG9rZW5lcigiYWJjXFxiZGVmXCJnaGkiKS5uZXh0U3RyaW5nKCciJykpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFiY1xmZGVmIiwgbmV3IEpTT05Ub2tlbmVyKCJhYmNcXGZkZWZcImdoaSIpLm5leHRTdHJpbmcoJyInKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYWJjXG5kZWYiLCBuZXcgSlNPTlRva2VuZXIoImFiY1xcbmRlZlwiZ2hpIikubmV4dFN0cmluZygnIicpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhYmNccmRlZiIsIG5ldyBKU09OVG9rZW5lcigiYWJjXFxyZGVmXCJnaGkiKS5uZXh0U3RyaW5nKCciJykpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFiY1x0ZGVmIiwgbmV3IEpTT05Ub2tlbmVyKCJhYmNcXHRkZWZcImdoaSIpLm5leHRTdHJpbmcoJyInKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5leHRTdHJpbmdVbmljb2RlRXNjYXBlZCgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgLy8gd2UncmUgbWl4aW5nIEphdmEgZXNjYXBpbmcgbGlrZSBcXCBhbmQgSmF2YVNjcmlwdCBlc2NhcGluZyBsaWtlIFxcdQorICAgICAgICBhc3NlcnRFcXVhbHMoImFiYyBkZWYiLCBuZXcgSlNPTlRva2VuZXIoImFiY1xcdTAwMjBkZWZcImdoaSIpLm5leHRTdHJpbmcoJyInKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYWJjVTAwMjBkZWYiLCBuZXcgSlNPTlRva2VuZXIoImFiY1xcVTAwMjBkZWZcImdoaSIpLm5leHRTdHJpbmcoJyInKSk7CisKKyAgICAgICAgLy8gSlNPTiByZXF1aXJlcyA0IGhleCBjaGFyYWN0ZXJzIGFmdGVyIGEgdW5pY29kZSBlc2NhcGUKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKU09OVG9rZW5lcigiYWJjXFx1MDAyXCIiKS5uZXh0U3RyaW5nKCciJyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlRva2VuZXIoImFiY1xcdSIpLm5leHRTdHJpbmcoJyInKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKU09OVG9rZW5lcigiYWJjXFx1ICAgIFwiIikubmV4dFN0cmluZygnIicpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiYWJjXCJkZWYiLCBuZXcgSlNPTlRva2VuZXIoImFiY1xcdTAwMjJkZWZcImdoaSIpLm5leHRTdHJpbmcoJyInKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlRva2VuZXIoImFiY1xcdTAwMEdcIiIpLm5leHRTdHJpbmcoJyInKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROZXh0U3RyaW5nTm9uUXVvdGUoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiQUIiLCBuZXcgSlNPTlRva2VuZXIoIkFCQyIpLm5leHRTdHJpbmcoJ0MnKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJDRCIsIG5ldyBKU09OVG9rZW5lcigiQUJcXENEQyIpLm5leHRTdHJpbmcoJ0MnKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJcbkMiLCBuZXcgSlNPTlRva2VuZXIoIkFCXFxuQ24iKS5uZXh0U3RyaW5nKCduJykpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROZXh0VG8oKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJDIiwgbmV3IEpTT05Ub2tlbmVyKCJBQkNERUZHIikubmV4dFRvKCJESEkiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJDREVGIiwgbmV3IEpTT05Ub2tlbmVyKCJBQkNERUYiKS5uZXh0VG8oIiIpKTsKKworICAgICAgICBKU09OVG9rZW5lciB0b2tlbmVyID0gbmV3IEpTT05Ub2tlbmVyKCJBQkNcckRFRlxuR0hJXHJcbkpLTCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFCQyIsIHRva2VuZXIubmV4dFRvKCJNIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ1xyJywgdG9rZW5lci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkRFRiIsIHRva2VuZXIubmV4dFRvKCJNIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ1xuJywgdG9rZW5lci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkdISSIsIHRva2VuZXIubmV4dFRvKCJNIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ1xyJywgdG9rZW5lci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ1xuJywgdG9rZW5lci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkpLTCIsIHRva2VuZXIubmV4dFRvKCJNIikpOworCisgICAgICAgIHRva2VuZXIgPSBuZXcgSlNPTlRva2VuZXIoIkFCQ0RFRkdISSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFCQyIsIHRva2VuZXIubmV4dFRvKCJERUYiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgdG9rZW5lci5uZXh0VG8oIkRFRiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdEJywgdG9rZW5lci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHRva2VuZXIubmV4dFRvKCJERUYiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygnRScsIHRva2VuZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB0b2tlbmVyLm5leHRUbygiREVGIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ0YnLCB0b2tlbmVyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiR0hJIiwgdG9rZW5lci5uZXh0VG8oIkRFRiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB0b2tlbmVyLm5leHRUbygiREVGIikpOworCisgICAgICAgIHRva2VuZXIgPSBuZXcgSlNPTlRva2VuZXIoIiBcdCBcZkFCQyBcdCBERUYiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkMiLCB0b2tlbmVyLm5leHRUbygiREVGIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ0QnLCB0b2tlbmVyLm5leHQoKSk7CisKKyAgICAgICAgdG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiIFx0IFxmQUJDIFxuIERFRiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFCQyIsIHRva2VuZXIubmV4dFRvKCJcbiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB0b2tlbmVyLm5leHRUbygiXG4iKSk7CisKKyAgICAgICAgdG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2tlbmVyLm5leHRUbyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5leHRUb1RyaW1taW5nKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIkFCQyIsIG5ldyBKU09OVG9rZW5lcigiXHQgQUJDIFx0REVGIikubmV4dFRvKCJERSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkMiLCBuZXcgSlNPTlRva2VuZXIoIlx0IEFCQyBcdERFRiIpLm5leHRUbygnRCcpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV4dFRvVHJhaWxpbmcoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJDIERFRiIsIG5ldyBKU09OVG9rZW5lcigiXHQgQUJDIERFRiBcdCIpLm5leHRUbygiRyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkMgREVGIiwgbmV3IEpTT05Ub2tlbmVyKCJcdCBBQkMgREVGIFx0IikubmV4dFRvKCdHJykpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROZXh0VG9Eb2VzbnRTdG9wT25OdWxsKCkgeworICAgICAgICBTdHJpbmcgbWVzc2FnZSA9ICJuZXh0VG8oKSBzaG91bGRuJ3Qgc3RvcCBhZnRlciBcXDAgY2hhcmFjdGVycyI7CisgICAgICAgIEpTT05Ub2tlbmVyIHRva2VuZXIgPSBuZXcgSlNPTlRva2VuZXIoIiBcMFx0IFxmQUJDIFxuIERFRiIpOworICAgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgIkFCQyIsIHRva2VuZXIubmV4dFRvKCJEIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgJ1xuJywgdG9rZW5lci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgIiIsIHRva2VuZXIubmV4dFRvKCJEIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROZXh0VG9Db25zdW1lc051bGwoKSB7CisgICAgICAgIFN0cmluZyBtZXNzYWdlID0gIm5leHRUbyBzaG91bGRuJ3QgY29uc3VtZSBcXDAuIjsKKyAgICAgICAgSlNPTlRva2VuZXIgdG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiQUJDXDBERUYiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsICJBQkMiLCB0b2tlbmVyLm5leHRUbygiXDAiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLCAnXDAnLCB0b2tlbmVyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLCAiREVGIiwgdG9rZW5lci5uZXh0VG8oIlwwIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTa2lwUGFzdCgpIHsKKyAgICAgICAgSlNPTlRva2VuZXIgdG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiQUJDREVGIik7CisgICAgICAgIHRva2VuZXIuc2tpcFBhc3QoIkFCQyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ0QnLCB0b2tlbmVyLm5leHQoKSk7CisgICAgICAgIHRva2VuZXIuc2tpcFBhc3QoIkVGIik7CisgICAgICAgIGFzc2VydEVxdWFscygnXDAnLCB0b2tlbmVyLm5leHQoKSk7CisKKyAgICAgICAgdG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiQUJDREVGIik7CisgICAgICAgIHRva2VuZXIuc2tpcFBhc3QoIkFCQ0RFRiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ1wwJywgdG9rZW5lci5uZXh0KCkpOworCisgICAgICAgIHRva2VuZXIgPSBuZXcgSlNPTlRva2VuZXIoIkFCQ0RFRiIpOworICAgICAgICB0b2tlbmVyLnNraXBQYXN0KCJHIik7CisgICAgICAgIGFzc2VydEVxdWFscygnXDAnLCB0b2tlbmVyLm5leHQoKSk7CisKKyAgICAgICAgdG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiQUJDXDBBQkMiKTsKKyAgICAgICAgdG9rZW5lci5za2lwUGFzdCgiQUJDIik7CisgICAgICAgIGFzc2VydEVxdWFscygnXDAnLCB0b2tlbmVyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygnQScsIHRva2VuZXIubmV4dCgpKTsKKworICAgICAgICB0b2tlbmVyID0gbmV3IEpTT05Ub2tlbmVyKCJcMEFCQyIpOworICAgICAgICB0b2tlbmVyLnNraXBQYXN0KCJBQkMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdcMCcsIHRva2VuZXIubmV4dCgpKTsKKworICAgICAgICB0b2tlbmVyID0gbmV3IEpTT05Ub2tlbmVyKCJBQkNcbkRFRiIpOworICAgICAgICB0b2tlbmVyLnNraXBQYXN0KCJERUYiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdcMCcsIHRva2VuZXIubmV4dCgpKTsKKworICAgICAgICB0b2tlbmVyID0gbmV3IEpTT05Ub2tlbmVyKCJBQkMiKTsKKyAgICAgICAgdG9rZW5lci5za2lwUGFzdCgiQUJDREVGIik7CisgICAgICAgIGFzc2VydEVxdWFscygnXDAnLCB0b2tlbmVyLm5leHQoKSk7CisKKyAgICAgICAgdG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiQUJDREFCQ0RBQkNEIik7CisgICAgICAgIHRva2VuZXIuc2tpcFBhc3QoIkFCQyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ0QnLCB0b2tlbmVyLm5leHQoKSk7CisgICAgICAgIHRva2VuZXIuc2tpcFBhc3QoIkFCQyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ0QnLCB0b2tlbmVyLm5leHQoKSk7CisgICAgICAgIHRva2VuZXIuc2tpcFBhc3QoIkFCQyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ0QnLCB0b2tlbmVyLm5leHQoKSk7CisKKyAgICAgICAgdG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2tlbmVyLnNraXBQYXN0KG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2tpcFRvKCkgeworICAgICAgICBKU09OVG9rZW5lciB0b2tlbmVyID0gbmV3IEpTT05Ub2tlbmVyKCJBQkNERUYiKTsKKyAgICAgICAgdG9rZW5lci5za2lwVG8oJ0EnKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdBJywgdG9rZW5lci5uZXh0KCkpOworICAgICAgICB0b2tlbmVyLnNraXBUbygnRCcpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ0QnLCB0b2tlbmVyLm5leHQoKSk7CisgICAgICAgIHRva2VuZXIuc2tpcFRvKCdHJyk7CisgICAgICAgIGFzc2VydEVxdWFscygnRScsIHRva2VuZXIubmV4dCgpKTsKKyAgICAgICAgdG9rZW5lci5za2lwVG8oJ0EnKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdGJywgdG9rZW5lci5uZXh0KCkpOworCisgICAgICAgIHRva2VuZXIgPSBuZXcgSlNPTlRva2VuZXIoIkFCQ1xuREVGIik7CisgICAgICAgIHRva2VuZXIuc2tpcFRvKCdGJyk7CisgICAgICAgIGFzc2VydEVxdWFscygnRicsIHRva2VuZXIubmV4dCgpKTsKKworICAgICAgICB0b2tlbmVyID0gbmV3IEpTT05Ub2tlbmVyKCJBQkNmREVGIik7CisgICAgICAgIHRva2VuZXIuc2tpcFRvKCdGJyk7CisgICAgICAgIGFzc2VydEVxdWFscygnRicsIHRva2VuZXIubmV4dCgpKTsKKworICAgICAgICB0b2tlbmVyID0gbmV3IEpTT05Ub2tlbmVyKCJBQkMvKiBERUYgKi8iKTsKKyAgICAgICAgdG9rZW5lci5za2lwVG8oJ0QnKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdEJywgdG9rZW5lci5uZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTa2lwVG9TdG9wc09uTnVsbCgpIHsKKyAgICAgICAgSlNPTlRva2VuZXIgdG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiQUJDXDBERUYiKTsKKyAgICAgICAgdG9rZW5lci5za2lwVG8oJ0YnKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJza2lwVG8gc2hvdWxkbid0IHN0b3Agd2hlbiBpdCBzZWVzICdcXDAnIiwgJ0YnLCB0b2tlbmVyLm5leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEJvbUlnbm9yZWRBc0ZpcnN0Q2hhcmFjdGVyT2ZEb2N1bWVudCgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTlRva2VuZXIgdG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiXHVmZWZmW10iKTsKKyAgICAgICAgSlNPTkFycmF5IGFycmF5ID0gKEpTT05BcnJheSkgdG9rZW5lci5uZXh0VmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGFycmF5Lmxlbmd0aCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qm9tVHJlYXRlZEFzQ2hhcmFjdGVySW5SZXN0T2ZEb2N1bWVudCgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgSlNPTlRva2VuZXIgdG9rZW5lciA9IG5ldyBKU09OVG9rZW5lcigiW1x1ZmVmZl0iKTsKKyAgICAgICAgSlNPTkFycmF5IGFycmF5ID0gKEpTT05BcnJheSkgdG9rZW5lci5uZXh0VmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGFycmF5Lmxlbmd0aCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVoZXhjaGFyKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIDAsIEpTT05Ub2tlbmVyLmRlaGV4Y2hhcignMCcpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCAxLCBKU09OVG9rZW5lci5kZWhleGNoYXIoJzEnKSk7CisgICAgICAgIGFzc2VydEVxdWFscyggMiwgSlNPTlRva2VuZXIuZGVoZXhjaGFyKCcyJykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIDMsIEpTT05Ub2tlbmVyLmRlaGV4Y2hhcignMycpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCA0LCBKU09OVG9rZW5lci5kZWhleGNoYXIoJzQnKSk7CisgICAgICAgIGFzc2VydEVxdWFscyggNSwgSlNPTlRva2VuZXIuZGVoZXhjaGFyKCc1JykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIDYsIEpTT05Ub2tlbmVyLmRlaGV4Y2hhcignNicpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCA3LCBKU09OVG9rZW5lci5kZWhleGNoYXIoJzcnKSk7CisgICAgICAgIGFzc2VydEVxdWFscyggOCwgSlNPTlRva2VuZXIuZGVoZXhjaGFyKCc4JykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIDksIEpTT05Ub2tlbmVyLmRlaGV4Y2hhcignOScpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEwLCBKU09OVG9rZW5lci5kZWhleGNoYXIoJ0EnKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMSwgSlNPTlRva2VuZXIuZGVoZXhjaGFyKCdCJykpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTIsIEpTT05Ub2tlbmVyLmRlaGV4Y2hhcignQycpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEzLCBKU09OVG9rZW5lci5kZWhleGNoYXIoJ0QnKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxNCwgSlNPTlRva2VuZXIuZGVoZXhjaGFyKCdFJykpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTUsIEpTT05Ub2tlbmVyLmRlaGV4Y2hhcignRicpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEwLCBKU09OVG9rZW5lci5kZWhleGNoYXIoJ2EnKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMSwgSlNPTlRva2VuZXIuZGVoZXhjaGFyKCdiJykpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTIsIEpTT05Ub2tlbmVyLmRlaGV4Y2hhcignYycpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEzLCBKU09OVG9rZW5lci5kZWhleGNoYXIoJ2QnKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxNCwgSlNPTlRva2VuZXIuZGVoZXhjaGFyKCdlJykpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTUsIEpTT05Ub2tlbmVyLmRlaGV4Y2hhcignZicpKTsKKworICAgICAgICBmb3IgKGludCBjID0gMDsgYyA8PSAweEZGRkY7IGMrKykgeworICAgICAgICAgICAgaWYgKChjID49ICcwJyAmJiBjIDw9ICc5JykgfHwgKGMgPj0gJ0EnICYmIGMgPD0gJ0YnKSB8fCAoYyA+PSAnYScgJiYgYyA8PSAnZicpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImRlaGV4Y2hhciAiICsgYywgLTEsIEpTT05Ub2tlbmVyLmRlaGV4Y2hhcigoY2hhcikgYykpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvanNvbi9zcmMvdGVzdC9qYXZhL29yZy9qc29uL1BhcnNpbmdUZXN0LmphdmEgYi9qc29uL3NyYy90ZXN0L2phdmEvb3JnL2pzb24vUGFyc2luZ1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMzhjMzY3Ci0tLSAvZGV2L251bGwKKysrIGIvanNvbi9zcmMvdGVzdC9qYXZhL29yZy9qc29uL1BhcnNpbmdUZXN0LmphdmEKQEAgLTAsMCArMSwyNjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5qc29uOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIFBhcnNpbmdUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNpbmdOb09iamVjdHMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSlNPTlRva2VuZXIoIiIpLm5leHRWYWx1ZSgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzaW5nTGl0ZXJhbHMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFBhcnNlZChCb29sZWFuLlRSVUUsICJ0cnVlIik7CisgICAgICAgIGFzc2VydFBhcnNlZChCb29sZWFuLkZBTFNFLCAiZmFsc2UiKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKEpTT05PYmplY3QuTlVMTCwgIm51bGwiKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKEpTT05PYmplY3QuTlVMTCwgIk5VTEwiKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKEJvb2xlYW4uRkFMU0UsICJGYWxzZSIpOworICAgICAgICBhc3NlcnRQYXJzZWQoQm9vbGVhbi5UUlVFLCAidHJ1RSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzaW5nUXVvdGVkU3RyaW5ncygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKCJhYmMiLCAiXCJhYmNcIiIpOworICAgICAgICBhc3NlcnRQYXJzZWQoIjEyMyIsICJcIjEyM1wiIik7CisgICAgICAgIGFzc2VydFBhcnNlZCgiZm9vXG5iYXIiLCAiXCJmb29cXG5iYXJcIiIpOworICAgICAgICBhc3NlcnRQYXJzZWQoImZvbyBiYXIiLCAiXCJmb29cXHUwMDIwYmFyXCIiKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKCJcInt9W10vXFw6LD07IyIsICJcIlxcXCJ7fVtdL1xcXFw6LD07I1wiIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNpbmdTaW5nbGVRdW90ZWRTdHJpbmdzKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBhc3NlcnRQYXJzZWQoImFiYyIsICInYWJjJyIpOworICAgICAgICBhc3NlcnRQYXJzZWQoIjEyMyIsICInMTIzJyIpOworICAgICAgICBhc3NlcnRQYXJzZWQoImZvb1xuYmFyIiwgIidmb29cXG5iYXInIik7CisgICAgICAgIGFzc2VydFBhcnNlZCgiZm9vIGJhciIsICInZm9vXFx1MDAyMGJhciciKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKCJcInt9W10vXFw6LD07IyIsICInXFxcInt9W10vXFxcXDosPTsjJyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzaW5nVW5xdW90ZWRTdHJpbmdzKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBhc3NlcnRQYXJzZWQoImFiYyIsICJhYmMiKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKCIxMjNhYmMiLCAiMTIzYWJjIik7CisgICAgICAgIGFzc2VydFBhcnNlZCgiMTIzZTB4IiwgIjEyM2UweCIpOworICAgICAgICBhc3NlcnRQYXJzZWQoIjEyM2UiLCAiMTIzZSIpOworICAgICAgICBhc3NlcnRQYXJzZWQoIjEyM2VlMjEiLCAiMTIzZWUyMSIpOworICAgICAgICBhc3NlcnRQYXJzZWQoIjB4RkZGRkZGRkZGRkZGRkZGRkYiLCAiMHhGRkZGRkZGRkZGRkZGRkZGRiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVuZm9ydHVuYXRlbHkgdGhlIG9yaWdpbmFsIGltcGxlbWVudGF0aW9uIGF0dGVtcHRzIHRvIGZpZ3VyZSBvdXQgd2hhdAorICAgICAqIEphdmEgbnVtYmVyIHR5cGUgYmVzdCBzdWl0cyBhbiBpbnB1dCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2luZ051bWJlcnNUaGF0QXJlQmVzdFJlcHJlc2VudGVkQXNMb25ncygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKDkyMjMzNzIwMzY4NTQ3NzU4MDdMLCAiOTIyMzM3MjAzNjg1NDc3NTgwNyIpOworICAgICAgICBhc3NlcnRQYXJzZWQoOTIyMzM3MjAzNjg1NDc3NTgwNkwsICI5MjIzMzcyMDM2ODU0Nzc1ODA2Iik7CisgICAgICAgIGFzc2VydFBhcnNlZCgtOTIyMzM3MjAzNjg1NDc3NTgwOEwsICItOTIyMzM3MjAzNjg1NDc3NTgwOCIpOworICAgICAgICBhc3NlcnRQYXJzZWQoLTkyMjMzNzIwMzY4NTQ3NzU4MDdMLCAiLTkyMjMzNzIwMzY4NTQ3NzU4MDciKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2luZ051bWJlcnNUaGF0QXJlQmVzdFJlcHJlc2VudGVkQXNJbnRlZ2VycygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKDAsICIwIik7CisgICAgICAgIGFzc2VydFBhcnNlZCg1LCAiNSIpOworICAgICAgICBhc3NlcnRQYXJzZWQoLTIxNDc0ODM2NDgsICItMjE0NzQ4MzY0OCIpOworICAgICAgICBhc3NlcnRQYXJzZWQoMjE0NzQ4MzY0NywgIjIxNDc0ODM2NDciKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2luZ05lZ2F0aXZlWmVybygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKDAsICItMCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzaW5nSW50ZWdlcnNXaXRoQWRkaXRpb25hbFByZWNpc2lvbllpZWxkRG91YmxlcygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKDFkLCAiMS4wMCIpOworICAgICAgICBhc3NlcnRQYXJzZWQoMWQsICIxLjAiKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKDBkLCAiMC4wIik7CisgICAgICAgIGFzc2VydFBhcnNlZCgtMGQsICItMC4wIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNpbmdOdW1iZXJzVGhhdEFyZUJlc3RSZXByZXNlbnRlZEFzRG91YmxlcygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKDkuMjIzMzcyMDM2ODU0Nzc2RTE4LCAiOTIyMzM3MjAzNjg1NDc3NTgwOCIpOworICAgICAgICBhc3NlcnRQYXJzZWQoLTkuMjIzMzcyMDM2ODU0Nzc2RTE4LCAiLTkyMjMzNzIwMzY4NTQ3NzU4MDkiKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKDEuNzk3NjkzMTM0ODYyMzE1N0UzMDgsICIxLjc5NzY5MzEzNDg2MjMxNTdlMzA4Iik7CisgICAgICAgIGFzc2VydFBhcnNlZCgyLjIyNTA3Mzg1ODUwNzIwMTRFLTMwOCwgIjIuMjI1MDczODU4NTA3MjAxNEUtMzA4Iik7CisgICAgICAgIGFzc2VydFBhcnNlZCg0LjlFLTMyNCwgIjQuOUUtMzI0Iik7CisgICAgICAgIGFzc2VydFBhcnNlZCg0LjlFLTMyNCwgIjQuOWUtMzI0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNpbmdPY3RhbE51bWJlcnMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFBhcnNlZCg1LCAiMDUiKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKDgsICIwMTAiKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKDEwNDYsICIwMjAyNiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzaW5nSGV4TnVtYmVycygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKDUsICIweDUiKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKDE2LCAiMHgxMCIpOworICAgICAgICBhc3NlcnRQYXJzZWQoODIzMCwgIjB4MjAyNiIpOworICAgICAgICBhc3NlcnRQYXJzZWQoMTgwMTUwMDEwLCAiMHhBQkNERUZBIik7CisgICAgICAgIGFzc2VydFBhcnNlZCgyMDc3MDkzODAzLCAiMHg3QkNERUZBQiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzaW5nTGFyZ2VIZXhWYWx1ZXMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFBhcnNlZChJbnRlZ2VyLk1BWF9WQUxVRSwgIjB4N0ZGRkZGRkYiKTsKKyAgICAgICAgU3RyaW5nIG1lc3NhZ2UgPSAiSGV4IHZhbHVlcyBhcmUgcGFyc2VkIGFzIFN0cmluZ3MgaWYgdGhlaXIgc2lnbmVkICIgKworICAgICAgICAgICAgICAgICJ2YWx1ZSBpcyBncmVhdGVyIHRoYW4gSW50ZWdlci5NQVhfVkFMVUUuIjsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKG1lc3NhZ2UsIDB4ODAwMDAwMDBMLCAiMHg4MDAwMDAwMCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Q2NEJpdEhleFZhbHVlcygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKCJMYXJnZSBoZXggbG9uZ3Mgc2hvdWxkbid0IGJlIHlpZWxkIGludHMgb3Igc3RyaW5ncyIsCisgICAgICAgICAgICAgICAgLTFMLCAiMHhGRkZGRkZGRkZGRkZGRkZGIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNpbmdXaXRoQ29tbWVudHNBbmRXaGl0ZXNwYWNlKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBhc3NlcnRQYXJzZWQoImJheiIsICIgIC8vIGZvbyBiYXIgXG4gYmF6Iik7CisgICAgICAgIGFzc2VydFBhcnNlZCgiYmF6IiwgIiAgLy8gZm9vIGJhciBcciBiYXoiKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKCJiYXoiLCAiICAvLyBmb28gYmFyIFxyXG4gYmF6Iik7CisgICAgICAgIGFzc2VydFBhcnNlZCgiYmF6IiwgIiAgIyBmb28gYmFyIFxuIGJheiIpOworICAgICAgICBhc3NlcnRQYXJzZWQoImJheiIsICIgICMgZm9vIGJhciBcciBiYXoiKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKCJiYXoiLCAiICAjIGZvbyBiYXIgXHJcbiBiYXoiKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKDUsICIgIC8qIGZvbyBiYXIgXG4gYmF6ICovIDUiKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKDUsICIgIC8qIGZvbyBiYXIgXG4gYmF6ICovIDUgLy8gcXV1eCIpOworICAgICAgICBhc3NlcnRQYXJzZWQoNSwgIiAgNSAgICIpOworICAgICAgICBhc3NlcnRQYXJzZWQoNSwgIiAgNSAgXHJcblx0ICIpOworICAgICAgICBhc3NlcnRQYXJzZWQoNSwgIlxyXG5cdCAgIDUgIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNpbmdBcnJheXMoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFBhcnNlZChhcnJheSgpLCAiW10iKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKGFycmF5KDUsIDYsIHRydWUpLCAiWzUsNix0cnVlXSIpOworICAgICAgICBhc3NlcnRQYXJzZWQoYXJyYXkoNSwgNiwgYXJyYXkoKSksICJbNSw2LFtdXSIpOworICAgICAgICBhc3NlcnRQYXJzZWQoYXJyYXkoNSwgNiwgNyksICJbNTs2OzddIik7CisgICAgICAgIGFzc2VydFBhcnNlZChhcnJheSg1LCA2LCA3KSwgIls1ICAsIDYgXHQ7IFxyXG4gN1xuXSIpOworICAgICAgICBhc3NlcnRQYXJzZWQoYXJyYXkoNSwgNiwgNywgbnVsbCksICJbNSw2LDcsXSIpOworICAgICAgICBhc3NlcnRQYXJzZWQoYXJyYXkobnVsbCwgbnVsbCksICJbLF0iKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKGFycmF5KDUsIG51bGwsIG51bGwsIG51bGwsIDUpLCAiWzUsLCwsNV0iKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKGFycmF5KG51bGwsIDUpLCAiWyw1XSIpOworICAgICAgICBhc3NlcnRQYXJzZWQoYXJyYXkobnVsbCwgbnVsbCwgbnVsbCksICJbLCxdIik7CisgICAgICAgIGFzc2VydFBhcnNlZChhcnJheShudWxsLCBudWxsLCBudWxsLCA1KSwgIlssLCw1XSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzaW5nT2JqZWN0cygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKG9iamVjdCgiZm9vIiwgNSksICJ7XCJmb29cIjogNX0iKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKG9iamVjdCgiZm9vIiwgNSksICJ7Zm9vOiA1fSIpOworICAgICAgICBhc3NlcnRQYXJzZWQob2JqZWN0KCJmb28iLCA1LCAiYmFyIiwgImJheiIpLCAie1wiZm9vXCI6IDUsIFwiYmFyXCI6IFwiYmF6XCJ9Iik7CisgICAgICAgIGFzc2VydFBhcnNlZChvYmplY3QoImZvbyIsIDUsICJiYXIiLCAiYmF6IiksICJ7XCJmb29cIjogNTsgXCJiYXJcIjogXCJiYXpcIn0iKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKG9iamVjdCgiZm9vIiwgNSwgImJhciIsICJiYXoiKSwgIntcImZvb1wiPSA1OyBcImJhclwiPSBcImJhelwifSIpOworICAgICAgICBhc3NlcnRQYXJzZWQob2JqZWN0KCJmb28iLCA1LCAiYmFyIiwgImJheiIpLCAie1wiZm9vXCI9PiA1OyBcImJhclwiPT4gXCJiYXpcIn0iKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKG9iamVjdCgiZm9vIiwgb2JqZWN0KCksICJiYXIiLCBhcnJheSgpKSwgIntcImZvb1wiPT4ge307IFwiYmFyXCI9PiBbXX0iKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VkKG9iamVjdCgiZm9vIiwgb2JqZWN0KCJmb28iLCBhcnJheSg1LCA2KSkpLCAie1wiZm9vXCI6IHtcImZvb1wiOiBbNSwgNl19fSIpOworICAgICAgICBhc3NlcnRQYXJzZWQob2JqZWN0KCJmb28iLCBvYmplY3QoImZvbyIsIGFycmF5KDUsIDYpKSksICJ7XCJmb29cIjpcblx0e1x0IFwiZm9vXCI6WzUsXHI2XX19Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN5bnRheFByb2JsZW1VbnRlcm1pbmF0ZWRPYmplY3QoKSB7CisgICAgICAgIGFzc2VydFBhcnNlRmFpbCgieyIpOworICAgICAgICBhc3NlcnRQYXJzZUZhaWwoIntcImZvb1wiIik7CisgICAgICAgIGFzc2VydFBhcnNlRmFpbCgie1wiZm9vXCI6Iik7CisgICAgICAgIGFzc2VydFBhcnNlRmFpbCgie1wiZm9vXCI6YmFyIik7CisgICAgICAgIGFzc2VydFBhcnNlRmFpbCgie1wiZm9vXCI6YmFyLCIpOworICAgICAgICBhc3NlcnRQYXJzZUZhaWwoIntcImZvb1wiOmJhcixcImJhelwiIik7CisgICAgICAgIGFzc2VydFBhcnNlRmFpbCgie1wiZm9vXCI6YmFyLFwiYmF6XCI6Iik7CisgICAgICAgIGFzc2VydFBhcnNlRmFpbCgie1wiZm9vXCI6YmFyLFwiYmF6XCI6dHJ1ZSIpOworICAgICAgICBhc3NlcnRQYXJzZUZhaWwoIntcImZvb1wiOmJhcixcImJhelwiOnRydWUsIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN5bnRheFByb2JsZW1FbXB0eVN0cmluZygpIHsKKyAgICAgICAgYXNzZXJ0UGFyc2VGYWlsKCIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3ludGF4UHJvYmxlbVVudGVybWluYXRlZEFycmF5KCkgeworICAgICAgICBhc3NlcnRQYXJzZUZhaWwoIlsiKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VGYWlsKCJbLCIpOworICAgICAgICBhc3NlcnRQYXJzZUZhaWwoIlssLCIpOworICAgICAgICBhc3NlcnRQYXJzZUZhaWwoIlt0cnVlIik7CisgICAgICAgIGFzc2VydFBhcnNlRmFpbCgiW3RydWUsIik7CisgICAgICAgIGFzc2VydFBhcnNlRmFpbCgiW3RydWUsLCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTeW50YXhQcm9ibGVtTWFsZm9ybWVkT2JqZWN0KCkgeworICAgICAgICBhc3NlcnRQYXJzZUZhaWwoIns6fSIpOworICAgICAgICBhc3NlcnRQYXJzZUZhaWwoIntcImtleVwiOn0iKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VGYWlsKCJ7OnRydWV9Iik7CisgICAgICAgIGFzc2VydFBhcnNlRmFpbCgie1wia2V5XCI6dHJ1ZTp9Iik7CisgICAgICAgIGFzc2VydFBhcnNlRmFpbCgie251bGw6dHJ1ZX0iKTsKKyAgICAgICAgYXNzZXJ0UGFyc2VGYWlsKCJ7dHJ1ZTp0cnVlfSIpOworICAgICAgICBhc3NlcnRQYXJzZUZhaWwoInsweEZGOnRydWV9Iik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydFBhcnNlRmFpbChTdHJpbmcgbWFsZm9ybWVkSnNvbikgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEpTT05Ub2tlbmVyKG1hbGZvcm1lZEpzb24pLm5leHRWYWx1ZSgpOworICAgICAgICAgICAgZmFpbCgiU3VjY2Vzc2Z1bGx5IHBhcnNlZDogXCIiICsgbWFsZm9ybWVkSnNvbiArICJcIiIpOworICAgICAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoU3RhY2tPdmVyZmxvd0Vycm9yIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlN0YWNrIG92ZXJmbG93ZWQgb24gaW5wdXQ6IFwiIiArIG1hbGZvcm1lZEpzb24gKyAiXCIiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgSlNPTkFycmF5IGFycmF5KE9iamVjdC4uLiBlbGVtZW50cykgeworICAgICAgICByZXR1cm4gbmV3IEpTT05BcnJheShBcnJheXMuYXNMaXN0KGVsZW1lbnRzKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBKU09OT2JqZWN0IG9iamVjdChPYmplY3QuLi4ga2V5VmFsdWVQYWlycykgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBKU09OT2JqZWN0IHJlc3VsdCA9IG5ldyBKU09OT2JqZWN0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga2V5VmFsdWVQYWlycy5sZW5ndGg7IGkrPTIpIHsKKyAgICAgICAgICAgIHJlc3VsdC5wdXQoKFN0cmluZykga2V5VmFsdWVQYWlyc1tpXSwga2V5VmFsdWVQYWlyc1tpKzFdKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRQYXJzZWQoU3RyaW5nIG1lc3NhZ2UsIE9iamVjdCBleHBlY3RlZCwgU3RyaW5nIGpzb24pIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0IGFjdHVhbCA9IG5ldyBKU09OVG9rZW5lcihqc29uKS5uZXh0VmFsdWUoKTsKKyAgICAgICAgYWN0dWFsID0gY2Fub25pY2FsaXplKGFjdHVhbCk7CisgICAgICAgIGV4cGVjdGVkID0gY2Fub25pY2FsaXplKGV4cGVjdGVkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGb3IgaW5wdXQgXCIiICsganNvbiArICJcIiAiICsgbWVzc2FnZSwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydFBhcnNlZChPYmplY3QgZXhwZWN0ZWQsIFN0cmluZyBqc29uKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFBhcnNlZCgiIiwgZXhwZWN0ZWQsIGpzb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNpbmNlIHRoZXkgZG9uJ3QgaW1wbGVtZW50IGVxdWFscyBvciBoYXNoQ29kZSBwcm9wZXJseSwgdGhpcyByZWN1cnNpdmVseQorICAgICAqIHJlcGxhY2VzIEpTT05PYmplY3RzIHdpdGggYW4gZXF1aXZhbGVudCBIYXNoTWFwLCBhbmQgSlNPTkFycmF5cyB3aXRoIHRoZQorICAgICAqIGVxdWl2YWxlbnQgQXJyYXlMaXN0LgorICAgICAqLworICAgIHByaXZhdGUgT2JqZWN0IGNhbm9uaWNhbGl6ZShPYmplY3QgaW5wdXQpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlucHV0IGluc3RhbmNlb2YgSlNPTkFycmF5KSB7CisgICAgICAgICAgICBKU09OQXJyYXkgYXJyYXkgPSAoSlNPTkFycmF5KSBpbnB1dDsKKyAgICAgICAgICAgIExpc3Q8T2JqZWN0PiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PE9iamVjdD4oKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQoY2Fub25pY2FsaXplKGFycmF5Lm9wdChpKSkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfSBlbHNlIGlmIChpbnB1dCBpbnN0YW5jZW9mIEpTT05PYmplY3QpIHsKKyAgICAgICAgICAgIEpTT05PYmplY3Qgb2JqZWN0ID0gKEpTT05PYmplY3QpIGlucHV0OworICAgICAgICAgICAgTWFwPFN0cmluZywgT2JqZWN0PiByZXN1bHQgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIE9iamVjdD4oKTsKKyAgICAgICAgICAgIGZvciAoSXRlcmF0b3I8Pz4gaSA9IG9iamVjdC5rZXlzKCk7IGkuaGFzTmV4dCgpOyApIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcga2V5ID0gKFN0cmluZykgaS5uZXh0KCk7CisgICAgICAgICAgICAgICAgcmVzdWx0LnB1dChrZXksIGNhbm9uaWNhbGl6ZShvYmplY3QuZ2V0KGtleSkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gaW5wdXQ7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9qc29uL3NyYy90ZXN0L2phdmEvb3JnL2pzb24vU2VsZlVzZVRlc3QuamF2YSBiL2pzb24vc3JjL3Rlc3QvamF2YS9vcmcvanNvbi9TZWxmVXNlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE1YTA4MjQKLS0tIC9kZXYvbnVsbAorKysgYi9qc29uL3NyYy90ZXN0L2phdmEvb3JnL2pzb24vU2VsZlVzZVRlc3QuamF2YQpAQCAtMCwwICsxLDIyOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmpzb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGhlc2UgdGVzdHMgY2hlY2tzIHNlbGYgdXNlIGNhbGxzLiBGb3IgdGhlIG1vc3QgcGFydCB3ZSBkb2Vzbid0IGF0dGVtcHQgdG8KKyAqIGNvdmVyIHNlbGYtdXNlLCBleGNlcHQgaW4gdGhvc2UgY2FzZXMgd2hlcmUgb3VyIGNsZWFuIHJvb20gaW1wbGVtZW50YXRpb24KKyAqIGRvZXMgaXQuCisgKgorICogPHA+VGhpcyBibGFjayBib3ggdGVzdCB3YXMgd3JpdHRlbiB3aXRob3V0IGluc3BlY3RpbmcgdGhlIG5vbi1mcmVlIG9yZy5qc29uCisgKiBzb3VyY2Vjb2RlLgorICovCitwdWJsaWMgY2xhc3MgU2VsZlVzZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIGludCBvYmplY3RQdXRDYWxscyA9IDA7CisgICAgcHJpdmF0ZSBpbnQgb2JqZWN0R2V0Q2FsbHMgPSAwOworICAgIHByaXZhdGUgaW50IG9iamVjdE9wdENhbGxzID0gMDsKKyAgICBwcml2YXRlIGludCBvYmplY3RPcHRUeXBlQ2FsbHMgPSAwOworICAgIHByaXZhdGUgaW50IGFycmF5UHV0Q2FsbHMgPSAwOworICAgIHByaXZhdGUgaW50IGFycmF5R2V0Q2FsbHMgPSAwOworICAgIHByaXZhdGUgaW50IGFycmF5T3B0Q2FsbHMgPSAwOworICAgIHByaXZhdGUgaW50IGFycmF5T3B0VHlwZUNhbGxzID0gMDsKKyAgICBwcml2YXRlIGludCB0b2tlbmVyTmV4dENhbGxzID0gMDsKKyAgICBwcml2YXRlIGludCB0b2tlbmVyTmV4dFZhbHVlQ2FsbHMgPSAwOworCisgICAgcHJpdmF0ZSBmaW5hbCBKU09OT2JqZWN0IG9iamVjdCA9IG5ldyBKU09OT2JqZWN0KCkgeworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEpTT05PYmplY3QgcHV0KFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgICAgIG9iamVjdFB1dENhbGxzKys7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIucHV0KG5hbWUsIHZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBAT3ZlcnJpZGUgcHVibGljIE9iamVjdCBnZXQoU3RyaW5nIG5hbWUpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgICAgIG9iamVjdEdldENhbGxzKys7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0KG5hbWUpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgT2JqZWN0IG9wdChTdHJpbmcgbmFtZSkgeworICAgICAgICAgICAgb2JqZWN0T3B0Q2FsbHMrKzsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5vcHQobmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIG9wdEJvb2xlYW4oU3RyaW5nIGtleSwgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKKyAgICAgICAgICAgIG9iamVjdE9wdFR5cGVDYWxscysrOworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLm9wdEJvb2xlYW4oa2V5LCBkZWZhdWx0VmFsdWUpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgZG91YmxlIG9wdERvdWJsZShTdHJpbmcga2V5LCBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CisgICAgICAgICAgICBvYmplY3RPcHRUeXBlQ2FsbHMrKzsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5vcHREb3VibGUoa2V5LCBkZWZhdWx0VmFsdWUpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IG9wdEludChTdHJpbmcga2V5LCBpbnQgZGVmYXVsdFZhbHVlKSB7CisgICAgICAgICAgICBvYmplY3RPcHRUeXBlQ2FsbHMrKzsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5vcHRJbnQoa2V5LCBkZWZhdWx0VmFsdWUpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgbG9uZyBvcHRMb25nKFN0cmluZyBrZXksIGxvbmcgZGVmYXVsdFZhbHVlKSB7CisgICAgICAgICAgICBvYmplY3RPcHRUeXBlQ2FsbHMrKzsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5vcHRMb25nKGtleSwgZGVmYXVsdFZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyBvcHRTdHJpbmcoU3RyaW5nIGtleSwgU3RyaW5nIGRlZmF1bHRWYWx1ZSkgeworICAgICAgICAgICAgb2JqZWN0T3B0VHlwZUNhbGxzKys7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIub3B0U3RyaW5nKGtleSwgZGVmYXVsdFZhbHVlKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBwcml2YXRlIGZpbmFsIEpTT05BcnJheSBhcnJheSA9IG5ldyBKU09OQXJyYXkoKSB7CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgSlNPTkFycmF5IHB1dChpbnQgaW5kZXgsIE9iamVjdCB2YWx1ZSkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICAgICAgYXJyYXlQdXRDYWxscysrOworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnB1dChpbmRleCwgdmFsdWUpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgT2JqZWN0IGdldChpbnQgaW5kZXgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGFycmF5R2V0Q2FsbHMrKzsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXQoaW5kZXgpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgT2JqZWN0IG9wdChpbnQgaW5kZXgpIHsKKyAgICAgICAgICAgIGFycmF5T3B0Q2FsbHMrKzsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5vcHQoaW5kZXgpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBvcHRCb29sZWFuKGludCBpbmRleCwgYm9vbGVhbiBmYWxsYmFjaykgeworICAgICAgICAgICAgYXJyYXlPcHRUeXBlQ2FsbHMrKzsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5vcHRCb29sZWFuKGluZGV4LCBmYWxsYmFjayk7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBkb3VibGUgb3B0RG91YmxlKGludCBpbmRleCwgZG91YmxlIGZhbGxiYWNrKSB7CisgICAgICAgICAgICBhcnJheU9wdFR5cGVDYWxscysrOworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLm9wdERvdWJsZShpbmRleCwgZmFsbGJhY2spOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgbG9uZyBvcHRMb25nKGludCBpbmRleCwgbG9uZyBmYWxsYmFjaykgeworICAgICAgICAgICAgYXJyYXlPcHRUeXBlQ2FsbHMrKzsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5vcHRMb25nKGluZGV4LCBmYWxsYmFjayk7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgb3B0U3RyaW5nKGludCBpbmRleCwgU3RyaW5nIGZhbGxiYWNrKSB7CisgICAgICAgICAgICBhcnJheU9wdFR5cGVDYWxscysrOworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLm9wdFN0cmluZyhpbmRleCwgZmFsbGJhY2spOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IG9wdEludChpbnQgaW5kZXgsIGludCBmYWxsYmFjaykgeworICAgICAgICAgICAgYXJyYXlPcHRUeXBlQ2FsbHMrKzsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5vcHRJbnQoaW5kZXgsIGZhbGxiYWNrKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBwcml2YXRlIGZpbmFsIEpTT05Ub2tlbmVyIHRva2VuZXIgPSBuZXcgSlNPTlRva2VuZXIoIntcImZvb1wiOiBbdHJ1ZV19IikgeworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGNoYXIgbmV4dCgpIHsKKyAgICAgICAgICAgIHRva2VuZXJOZXh0Q2FsbHMrKzsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5uZXh0KCk7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgbmV4dFZhbHVlKCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICAgICAgdG9rZW5lck5leHRWYWx1ZUNhbGxzKys7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIubmV4dFZhbHVlKCk7CisgICAgICAgIH0KKyAgICB9OworCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T2JqZWN0UHV0KCkgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgICAgICBvYmplY3QucHV0T3B0KCJmb28iLCAiYmFyIik7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBvYmplY3RQdXRDYWxscyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE9iamVjdEFjY3VtdWxhdGUoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIG9iamVjdC5hY2N1bXVsYXRlKCJmb28iLCAiYmFyIik7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBvYmplY3RQdXRDYWxscyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE9iamVjdEdldEJvb2xlYW4oKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIG9iamVjdC5wdXQoImZvbyIsICJ0cnVlIik7CisgICAgICAgIG9iamVjdC5nZXRCb29sZWFuKCJmb28iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG9iamVjdEdldENhbGxzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T2JqZWN0T3B0VHlwZSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgb2JqZWN0Lm9wdEJvb2xlYW4oImZvbyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgb2JqZWN0T3B0Q2FsbHMpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgb2JqZWN0T3B0VHlwZUNhbGxzKTsKKyAgICAgICAgb2JqZWN0Lm9wdERvdWJsZSgiZm9vIik7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBvYmplY3RPcHRDYWxscyk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBvYmplY3RPcHRUeXBlQ2FsbHMpOworICAgICAgICBvYmplY3Qub3B0SW50KCJmb28iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIG9iamVjdE9wdENhbGxzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIG9iamVjdE9wdFR5cGVDYWxscyk7CisgICAgICAgIG9iamVjdC5vcHRMb25nKCJmb28iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIG9iamVjdE9wdENhbGxzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIG9iamVjdE9wdFR5cGVDYWxscyk7CisgICAgICAgIG9iamVjdC5vcHRTdHJpbmcoImZvbyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgb2JqZWN0T3B0Q2FsbHMpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgb2JqZWN0T3B0VHlwZUNhbGxzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9KU09OQXJyYXkoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIG9iamVjdC5wdXQoImZvbyIsIDUpOworICAgICAgICBvYmplY3QucHV0KCJiYXIiLCAxMCk7CisgICAgICAgIGFycmF5LnB1dCgiZm9vIik7CisgICAgICAgIGFycmF5LnB1dCgiYmF6Iik7CisgICAgICAgIGFycmF5LnB1dCgiYmFyIik7CisgICAgICAgIG9iamVjdC50b0pTT05BcnJheShhcnJheSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBhcnJheU9wdENhbGxzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGFycmF5T3B0VHlwZUNhbGxzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIG9iamVjdE9wdENhbGxzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG9iamVjdE9wdFR5cGVDYWxscyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1dEF0SW5kZXgoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIGFycmF5LnB1dCgxMCwgZmFsc2UpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgYXJyYXlQdXRDYWxscyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdElzTnVsbCgpIHsKKyAgICAgICAgYXJyYXkuaXNOdWxsKDUpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgYXJyYXlPcHRDYWxscyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFycmF5R2V0VHlwZSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXJyYXkucHV0KHRydWUpOworICAgICAgICBhcnJheS5nZXRCb29sZWFuKDApOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgYXJyYXlHZXRDYWxscyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFycmF5T3B0VHlwZSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXJyYXkub3B0Qm9vbGVhbigzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGFycmF5T3B0Q2FsbHMpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgYXJyYXlPcHRUeXBlQ2FsbHMpOworICAgICAgICBhcnJheS5vcHREb3VibGUoMyk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBhcnJheU9wdENhbGxzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGFycmF5T3B0VHlwZUNhbGxzKTsKKyAgICAgICAgYXJyYXkub3B0SW50KDMpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgYXJyYXlPcHRDYWxscyk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBhcnJheU9wdFR5cGVDYWxscyk7CisgICAgICAgIGFycmF5Lm9wdExvbmcoMyk7CisgICAgICAgIGFzc2VydEVxdWFscyg0LCBhcnJheU9wdENhbGxzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGFycmF5T3B0VHlwZUNhbGxzKTsKKyAgICAgICAgYXJyYXkub3B0U3RyaW5nKDMpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgYXJyYXlPcHRDYWxscyk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBhcnJheU9wdFR5cGVDYWxscyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRvSlNPTk9iamVjdCgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgYXJyYXkucHV0KCJmb28iKTsKKyAgICAgICAgYXJyYXkucHV0KCJiYXoiKTsKKyAgICAgICAgYXJyYXkucHV0KCJiYXIiKTsKKyAgICAgICAgSlNPTkFycmF5IHZhbHVlcyA9IG5ldyBKU09OQXJyYXkoKTsKKyAgICAgICAgdmFsdWVzLnB1dCg1LjVkKTsKKyAgICAgICAgdmFsdWVzLnB1dCgxMWQpOworICAgICAgICB2YWx1ZXMucHV0KDMwKTsKKyAgICAgICAgdmFsdWVzLnRvSlNPTk9iamVjdChhcnJheSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBhcnJheU9wdENhbGxzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGFycmF5T3B0VHlwZUNhbGxzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV4dEV4cGVjdGluZygpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgdG9rZW5lci5uZXh0KCd7Jyk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCB0b2tlbmVyTmV4dENhbGxzKTsKKyAgICAgICAgdG9rZW5lci5uZXh0KCdcIicpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgdG9rZW5lck5leHRDYWxscyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5leHRWYWx1ZSgpIHRocm93cyBKU09ORXhjZXB0aW9uIHsKKyAgICAgICAgdG9rZW5lci5uZXh0VmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIHRva2VuZXJOZXh0VmFsdWVDYWxscyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvanVuaXQvTU9EVUxFX0xJQ0VOU0VfQ1BMIGIvanVuaXQvTU9EVUxFX0xJQ0VOU0VfQ1BMCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU0MWRiYjUKLS0tIC9kZXYvbnVsbAorKysgYi9qdW5pdC9NT0RVTEVfTElDRU5TRV9DUEwKQEAgLTAsMCArMSBAQAoraHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9jcGwxLjAucGhwCmRpZmYgLS1naXQgYS9qdW5pdC9zcmMvbWFpbi9qYXZhL2p1bml0L2V4dGVuc2lvbnMvQWN0aXZlVGVzdFN1aXRlLmphdmEgYi9qdW5pdC9zcmMvbWFpbi9qYXZhL2p1bml0L2V4dGVuc2lvbnMvQWN0aXZlVGVzdFN1aXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGI2Mjg1MwotLS0gL2Rldi9udWxsCisrKyBiL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZXh0ZW5zaW9ucy9BY3RpdmVUZXN0U3VpdGUuamF2YQpAQCAtMCwwICsxLDY0IEBACitwYWNrYWdlIGp1bml0LmV4dGVuc2lvbnM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuKjsKKworLyoqCisgKiBBIFRlc3RTdWl0ZSBmb3IgYWN0aXZlIFRlc3RzLiBJdCBydW5zIGVhY2gKKyAqIHRlc3QgaW4gYSBzZXBhcmF0ZSB0aHJlYWQgYW5kIHdhaXRzIHVudGlsIGFsbAorICogdGhyZWFkcyBoYXZlIHRlcm1pbmF0ZWQuCisgKiAtLSBBYXJodXMgUmFkaXNzb24gU2NhbmRpbmF2aWFuIENlbnRlciAxMXRoIGZsb29yCisgKi8KK3B1YmxpYyBjbGFzcyBBY3RpdmVUZXN0U3VpdGUgZXh0ZW5kcyBUZXN0U3VpdGUgeworICAgIHByaXZhdGUgdm9sYXRpbGUgaW50IGZBY3RpdmVUZXN0RGVhdGhDb3VudDsKKworICAgIHB1YmxpYyBBY3RpdmVUZXN0U3VpdGUoKSB7CisgICAgfQorCisgICAgcHVibGljIEFjdGl2ZVRlc3RTdWl0ZShDbGFzcyB0aGVDbGFzcykgeworICAgICAgICBzdXBlcih0aGVDbGFzcyk7CisgICAgfQorCisgICAgcHVibGljIEFjdGl2ZVRlc3RTdWl0ZShTdHJpbmcgbmFtZSkgeworICAgICAgICBzdXBlciAobmFtZSk7CisgICAgfQorCisgICAgcHVibGljIEFjdGl2ZVRlc3RTdWl0ZShDbGFzcyB0aGVDbGFzcywgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgc3VwZXIodGhlQ2xhc3MsIG5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJ1bihUZXN0UmVzdWx0IHJlc3VsdCkgeworICAgICAgICBmQWN0aXZlVGVzdERlYXRoQ291bnQ9IDA7CisgICAgICAgIHN1cGVyLnJ1bihyZXN1bHQpOworICAgICAgICB3YWl0VW50aWxGaW5pc2hlZCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoZmluYWwgVGVzdCB0ZXN0LCBmaW5hbCBUZXN0UmVzdWx0IHJlc3VsdCkgeworICAgICAgICBUaHJlYWQgdD0gbmV3IFRocmVhZCgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAvLyBpbmxpbmVkIGR1ZSB0byBsaW1pdGF0aW9uIGluIFZBL0phdmEKKyAgICAgICAgICAgICAgICAgICAgLy9BY3RpdmVUZXN0U3VpdGUuc3VwZXIucnVuVGVzdCh0ZXN0LCByZXN1bHQpOworICAgICAgICAgICAgICAgICAgICB0ZXN0LnJ1bihyZXN1bHQpOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIEFjdGl2ZVRlc3RTdWl0ZS50aGlzLnJ1bkZpbmlzaGVkKHRlc3QpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgdC5zdGFydCgpOworICAgIH0KKworICAgIHN5bmNocm9uaXplZCB2b2lkIHdhaXRVbnRpbEZpbmlzaGVkKCkgeworICAgICAgICB3aGlsZSAoZkFjdGl2ZVRlc3REZWF0aENvdW50IDwgdGVzdENvdW50KCkpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgd2FpdCgpOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHJldHVybjsgLy8gaWdub3JlCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzeW5jaHJvbml6ZWQgcHVibGljIHZvaWQgcnVuRmluaXNoZWQoVGVzdCB0ZXN0KSB7CisgICAgICAgIGZBY3RpdmVUZXN0RGVhdGhDb3VudCsrOworICAgICAgICBub3RpZnlBbGwoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9qdW5pdC9zcmMvbWFpbi9qYXZhL2p1bml0L2V4dGVuc2lvbnMvRXhjZXB0aW9uVGVzdENhc2UuamF2YSBiL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZXh0ZW5zaW9ucy9FeGNlcHRpb25UZXN0Q2FzZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlNjRiNWIKLS0tIC9kZXYvbnVsbAorKysgYi9qdW5pdC9zcmMvbWFpbi9qYXZhL2p1bml0L2V4dGVuc2lvbnMvRXhjZXB0aW9uVGVzdENhc2UuamF2YQpAQCAtMCwwICsxLDQ2IEBACitwYWNrYWdlIGp1bml0LmV4dGVuc2lvbnM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuKjsKKworLyoqCisgKiBBIFRlc3RDYXNlIHRoYXQgZXhwZWN0cyBhbiBFeGNlcHRpb24gb2YgY2xhc3MgZkV4cGVjdGVkIHRvIGJlIHRocm93bi4KKyAqIFRoZSBvdGhlciB3YXkgdG8gY2hlY2sgdGhhdCBhbiBleHBlY3RlZCBleGNlcHRpb24gaXMgdGhyb3duIGlzOgorICogPHByZT4KKyAqIHRyeSB7CisgKiAgIHNob3VsZFRocm93KCk7CisgKiB9CisgKiBjYXRjaCAoU3BlY2lhbEV4Y2VwdGlvbiBlKSB7CisgKiAgIHJldHVybjsKKyAqIH0KKyAqIGZhaWwoIkV4cGVjdGVkIFNwZWNpYWxFeGNlcHRpb24iKTsKKyAqIDwvcHJlPgorICoKKyAqIFRvIHVzZSBFeGNlcHRpb25UZXN0Q2FzZSwgY3JlYXRlIGEgVGVzdENhc2UgbGlrZToKKyAqIDxwcmU+CisgKiBuZXcgRXhjZXB0aW9uVGVzdENhc2UoInRlc3RTaG91bGRUaHJvdyIsIFNwZWNpYWxFeGNlcHRpb24uY2xhc3MpOworICogPC9wcmU+CisgKi8KK3B1YmxpYyBjbGFzcyBFeGNlcHRpb25UZXN0Q2FzZSBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBDbGFzcyBmRXhwZWN0ZWQ7CisKKyAgICBwdWJsaWMgRXhjZXB0aW9uVGVzdENhc2UoU3RyaW5nIG5hbWUsIENsYXNzIGV4Y2VwdGlvbikgeworICAgICAgICBzdXBlcihuYW1lKTsKKyAgICAgICAgZkV4cGVjdGVkPSBleGNlcHRpb247CisgICAgfQorICAgIC8qKgorICAgICAqIEV4ZWN1dGUgdGhlIHRlc3QgbWV0aG9kIGV4cGVjdGluZyB0aGF0IGFuIEV4Y2VwdGlvbiBvZgorICAgICAqIGNsYXNzIGZFeHBlY3RlZCBvciBvbmUgb2YgaXRzIHN1YmNsYXNzZXMgd2lsbCBiZSB0aHJvd24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdXBlci5ydW5UZXN0KCk7CisgICAgICAgIH0KKyAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAoZkV4cGVjdGVkLmlzQXNzaWduYWJsZUZyb20oZS5nZXRDbGFzcygpKSkKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgfQorICAgICAgICBmYWlsKCJFeHBlY3RlZCBleGNlcHRpb24gIiArIGZFeHBlY3RlZCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9leHRlbnNpb25zL1JlcGVhdGVkVGVzdC5qYXZhIGIvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9leHRlbnNpb25zL1JlcGVhdGVkVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM0ZjI1NDEKLS0tIC9kZXYvbnVsbAorKysgYi9qdW5pdC9zcmMvbWFpbi9qYXZhL2p1bml0L2V4dGVuc2lvbnMvUmVwZWF0ZWRUZXN0LmphdmEKQEAgLTAsMCArMSwzMSBAQAorcGFja2FnZSBqdW5pdC5leHRlbnNpb25zOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLio7CisKKy8qKgorICogQSBEZWNvcmF0b3IgdGhhdCBydW5zIGEgdGVzdCByZXBlYXRlZGx5LgorICoKKyAqLworcHVibGljIGNsYXNzIFJlcGVhdGVkVGVzdCBleHRlbmRzICBUZXN0RGVjb3JhdG9yIHsKKyAgICBwcml2YXRlIGludCBmVGltZXNSZXBlYXQ7CisKKyAgICBwdWJsaWMgUmVwZWF0ZWRUZXN0KFRlc3QgdGVzdCwgaW50IHJlcGVhdCkgeworICAgICAgICBzdXBlcih0ZXN0KTsKKyAgICAgICAgaWYgKHJlcGVhdCA8IDApCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJSZXBldGl0aW9uIGNvdW50IG11c3QgYmUgPiAwIik7CisgICAgICAgIGZUaW1lc1JlcGVhdD0gcmVwZWF0OworICAgIH0KKyAgICBwdWJsaWMgaW50IGNvdW50VGVzdENhc2VzKCkgeworICAgICAgICByZXR1cm4gc3VwZXIuY291bnRUZXN0Q2FzZXMoKSpmVGltZXNSZXBlYXQ7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHJ1bihUZXN0UmVzdWx0IHJlc3VsdCkgeworICAgICAgICBmb3IgKGludCBpPSAwOyBpIDwgZlRpbWVzUmVwZWF0OyBpKyspIHsKKyAgICAgICAgICAgIGlmIChyZXN1bHQuc2hvdWxkU3RvcCgpKQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgc3VwZXIucnVuKHJlc3VsdCk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCkrIihyZXBlYXRlZCkiOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZXh0ZW5zaW9ucy9UZXN0RGVjb3JhdG9yLmphdmEgYi9qdW5pdC9zcmMvbWFpbi9qYXZhL2p1bml0L2V4dGVuc2lvbnMvVGVzdERlY29yYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNmYmQwMjEKLS0tIC9kZXYvbnVsbAorKysgYi9qdW5pdC9zcmMvbWFpbi9qYXZhL2p1bml0L2V4dGVuc2lvbnMvVGVzdERlY29yYXRvci5qYXZhCkBAIC0wLDAgKzEsMzggQEAKK3BhY2thZ2UganVuaXQuZXh0ZW5zaW9uczsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay4qOworCisvKioKKyAqIEEgRGVjb3JhdG9yIGZvciBUZXN0cy4gVXNlIFRlc3REZWNvcmF0b3IgYXMgdGhlIGJhc2UgY2xhc3MKKyAqIGZvciBkZWZpbmluZyBuZXcgdGVzdCBkZWNvcmF0b3JzLiBUZXN0IGRlY29yYXRvciBzdWJjbGFzc2VzCisgKiBjYW4gYmUgaW50cm9kdWNlZCB0byBhZGQgYmVoYXZpb3IgYmVmb3JlIG9yIGFmdGVyIGEgdGVzdAorICogaXMgcnVuLgorICoKKyAqLworcHVibGljIGNsYXNzIFRlc3REZWNvcmF0b3IgZXh0ZW5kcyBBc3NlcnQgaW1wbGVtZW50cyBUZXN0IHsKKyAgICBwcm90ZWN0ZWQgVGVzdCBmVGVzdDsKKworICAgIHB1YmxpYyBUZXN0RGVjb3JhdG9yKFRlc3QgdGVzdCkgeworICAgICAgICBmVGVzdD0gdGVzdDsKKyAgICB9CisgICAgLyoqCisgICAgICogVGhlIGJhc2ljIHJ1biBiZWhhdmlvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBiYXNpY1J1bihUZXN0UmVzdWx0IHJlc3VsdCkgeworICAgICAgICBmVGVzdC5ydW4ocmVzdWx0KTsKKyAgICB9CisgICAgcHVibGljIGludCBjb3VudFRlc3RDYXNlcygpIHsKKyAgICAgICAgcmV0dXJuIGZUZXN0LmNvdW50VGVzdENhc2VzKCk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHJ1bihUZXN0UmVzdWx0IHJlc3VsdCkgeworICAgICAgICBiYXNpY1J1bihyZXN1bHQpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBmVGVzdC50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyBUZXN0IGdldFRlc3QoKSB7CisgICAgICAgIHJldHVybiBmVGVzdDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9qdW5pdC9zcmMvbWFpbi9qYXZhL2p1bml0L2V4dGVuc2lvbnMvVGVzdFNldHVwLmphdmEgYi9qdW5pdC9zcmMvbWFpbi9qYXZhL2p1bml0L2V4dGVuc2lvbnMvVGVzdFNldHVwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzY1MTUwMQotLS0gL2Rldi9udWxsCisrKyBiL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZXh0ZW5zaW9ucy9UZXN0U2V0dXAuamF2YQpAQCAtMCwwICsxLDM3IEBACitwYWNrYWdlIGp1bml0LmV4dGVuc2lvbnM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuKjsKKworLyoqCisgKiBBIERlY29yYXRvciB0byBzZXQgdXAgYW5kIHRlYXIgZG93biBhZGRpdGlvbmFsIGZpeHR1cmUgc3RhdGUuCisgKiBTdWJjbGFzcyBUZXN0U2V0dXAgYW5kIGluc2VydCBpdCBpbnRvIHlvdXIgdGVzdHMgd2hlbiB5b3Ugd2FudAorICogdG8gc2V0IHVwIGFkZGl0aW9uYWwgc3RhdGUgb25jZSBiZWZvcmUgdGhlIHRlc3RzIGFyZSBydW4uCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0U2V0dXAgZXh0ZW5kcyBUZXN0RGVjb3JhdG9yIHsKKworICAgIHB1YmxpYyBUZXN0U2V0dXAoVGVzdCB0ZXN0KSB7CisgICAgICAgIHN1cGVyKHRlc3QpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCBydW4oZmluYWwgVGVzdFJlc3VsdCByZXN1bHQpIHsKKyAgICAgICAgUHJvdGVjdGFibGUgcD0gbmV3IFByb3RlY3RhYmxlKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcHJvdGVjdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgIHNldFVwKCk7CisgICAgICAgICAgICAgICAgYmFzaWNSdW4ocmVzdWx0KTsKKyAgICAgICAgICAgICAgICB0ZWFyRG93bigpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICByZXN1bHQucnVuUHJvdGVjdGVkKHRoaXMsIHApOworICAgIH0KKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLiBPdmVycmlkZSB0byBzZXQgdXAgYWRkaXRpb25hbCBmaXh0dXJlCisgICAgICogc3RhdGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB9CisgICAgLyoqCisgICAgICogVGVhcnMgZG93biB0aGUgZml4dHVyZS4gT3ZlcnJpZGUgdG8gdGVhciBkb3duIHRoZSBhZGRpdGlvbmFsCisgICAgICogZml4dHVyZSBzdGF0ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgIH0KK30KZGlmZiAtLWdpdCBhL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZXh0ZW5zaW9ucy9wYWNrYWdlLmh0bWwgYi9qdW5pdC9zcmMvbWFpbi9qYXZhL2p1bml0L2V4dGVuc2lvbnMvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZiNGJlNzIKLS0tIC9kZXYvbnVsbAorKysgYi9qdW5pdC9zcmMvbWFpbi9qYXZhL2p1bml0L2V4dGVuc2lvbnMvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsNiBAQAorPEhUTUw+Cis8Qk9EWT4KK1V0aWxpdHkgY2xhc3NlcyBzdXBwb3J0aW5nIHRoZSBqdW5pdCB0ZXN0IGZyYW1ld29yay4KK3tAaGlkZX0gLSBOb3QgbmVlZGVkIGZvciAxLjAgU0RLIAorPC9CT0RZPgorPC9IVE1MPgpkaWZmIC0tZ2l0IGEvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9mcmFtZXdvcmsvQXNzZXJ0LmphdmEgYi9qdW5pdC9zcmMvbWFpbi9qYXZhL2p1bml0L2ZyYW1ld29yay9Bc3NlcnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yODk0NDlhCi0tLSAvZGV2L251bGwKKysrIGIvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9mcmFtZXdvcmsvQXNzZXJ0LmphdmEKQEAgLTAsMCArMSwyOTEgQEAKK3BhY2thZ2UganVuaXQuZnJhbWV3b3JrOworCisvKioKKyAqIEEgc2V0IG9mIGFzc2VydCBtZXRob2RzLiAgTWVzc2FnZXMgYXJlIG9ubHkgZGlzcGxheWVkIHdoZW4gYW4gYXNzZXJ0IGZhaWxzLgorICovCisKK3B1YmxpYyBjbGFzcyBBc3NlcnQgeworICAgIC8qKgorICAgICAqIFByb3RlY3QgY29uc3RydWN0b3Igc2luY2UgaXQgaXMgYSBzdGF0aWMgb25seSBjbGFzcworICAgICAqLworICAgIHByb3RlY3RlZCBBc3NlcnQoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzZXJ0cyB0aGF0IGEgY29uZGl0aW9uIGlzIHRydWUuIElmIGl0IGlzbid0IGl0IHRocm93cworICAgICAqIGFuIEFzc2VydGlvbkZhaWxlZEVycm9yIHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UuCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydFRydWUoU3RyaW5nIG1lc3NhZ2UsIGJvb2xlYW4gY29uZGl0aW9uKSB7CisgICAgICAgIGlmICghY29uZGl0aW9uKQorICAgICAgICAgICAgZmFpbChtZXNzYWdlKTsKKyAgICB9CisgICAgLyoqCisgICAgICogQXNzZXJ0cyB0aGF0IGEgY29uZGl0aW9uIGlzIHRydWUuIElmIGl0IGlzbid0IGl0IHRocm93cworICAgICAqIGFuIEFzc2VydGlvbkZhaWxlZEVycm9yLgorICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRUcnVlKGJvb2xlYW4gY29uZGl0aW9uKSB7CisgICAgICAgIGFzc2VydFRydWUobnVsbCwgY29uZGl0aW9uKTsKKyAgICB9CisgICAgLyoqCisgICAgICogQXNzZXJ0cyB0aGF0IGEgY29uZGl0aW9uIGlzIGZhbHNlLiBJZiBpdCBpc24ndCBpdCB0aHJvd3MKKyAgICAgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlLgorICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRGYWxzZShTdHJpbmcgbWVzc2FnZSwgYm9vbGVhbiBjb25kaXRpb24pIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLCAhY29uZGl0aW9uKTsKKyAgICB9CisgICAgLyoqCisgICAgICogQXNzZXJ0cyB0aGF0IGEgY29uZGl0aW9uIGlzIGZhbHNlLiBJZiBpdCBpc24ndCBpdCB0aHJvd3MKKyAgICAgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvci4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RmFsc2UoYm9vbGVhbiBjb25kaXRpb24pIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobnVsbCwgY29uZGl0aW9uKTsKKyAgICB9CisgICAgLyoqCisgICAgICogRmFpbHMgYSB0ZXN0IHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UuCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyB2b2lkIGZhaWwoU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkZhaWxlZEVycm9yKG1lc3NhZ2UpOworICAgIH0KKyAgICAvKioKKyAgICAgKiBGYWlscyBhIHRlc3Qgd2l0aCBubyBtZXNzYWdlLgorICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgdm9pZCBmYWlsKCkgeworICAgICAgICBmYWlsKG51bGwpOworICAgIH0KKyAgICAvKioKKyAgICAgKiBBc3NlcnRzIHRoYXQgdHdvIG9iamVjdHMgYXJlIGVxdWFsLiBJZiB0aGV5IGFyZSBub3QKKyAgICAgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciBpcyB0aHJvd24gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKFN0cmluZyBtZXNzYWdlLCBPYmplY3QgZXhwZWN0ZWQsIE9iamVjdCBhY3R1YWwpIHsKKyAgICAgICAgaWYgKGV4cGVjdGVkID09IG51bGwgJiYgYWN0dWFsID09IG51bGwpCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIGlmIChleHBlY3RlZCAhPSBudWxsICYmIGV4cGVjdGVkLmVxdWFscyhhY3R1YWwpKQorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICBmYWlsTm90RXF1YWxzKG1lc3NhZ2UsIGV4cGVjdGVkLCBhY3R1YWwpOworICAgIH0KKyAgICAvKioKKyAgICAgKiBBc3NlcnRzIHRoYXQgdHdvIG9iamVjdHMgYXJlIGVxdWFsLiBJZiB0aGV5IGFyZSBub3QKKyAgICAgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciBpcyB0aHJvd24uCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFscyhPYmplY3QgZXhwZWN0ZWQsIE9iamVjdCBhY3R1YWwpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGV4cGVjdGVkLCBhY3R1YWwpOworICAgIH0KKyAgICAvKioKKyAgICAgKiBBc3NlcnRzIHRoYXQgdHdvIFN0cmluZ3MgYXJlIGVxdWFsLgorICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIG1lc3NhZ2UsIFN0cmluZyBleHBlY3RlZCwgU3RyaW5nIGFjdHVhbCkgeworICAgICAgICBpZiAoZXhwZWN0ZWQgPT0gbnVsbCAmJiBhY3R1YWwgPT0gbnVsbCkKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgaWYgKGV4cGVjdGVkICE9IG51bGwgJiYgZXhwZWN0ZWQuZXF1YWxzKGFjdHVhbCkpCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIHRocm93IG5ldyBDb21wYXJpc29uRmFpbHVyZShtZXNzYWdlLCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgICB9CisgICAgLyoqCisgICAgICogQXNzZXJ0cyB0aGF0IHR3byBTdHJpbmdzIGFyZSBlcXVhbC4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKFN0cmluZyBleHBlY3RlZCwgU3RyaW5nIGFjdHVhbCkgeworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgfQorICAgIC8qKgorICAgICAqIEFzc2VydHMgdGhhdCB0d28gZG91YmxlcyBhcmUgZXF1YWwgY29uY2VybmluZyBhIGRlbHRhLiAgSWYgdGhleSBhcmUgbm90CisgICAgICogYW4gQXNzZXJ0aW9uRmFpbGVkRXJyb3IgaXMgdGhyb3duIHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UuICBJZiB0aGUgZXhwZWN0ZWQKKyAgICAgKiB2YWx1ZSBpcyBpbmZpbml0eSB0aGVuIHRoZSBkZWx0YSB2YWx1ZSBpcyBpZ25vcmVkLgorICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIG1lc3NhZ2UsIGRvdWJsZSBleHBlY3RlZCwgZG91YmxlIGFjdHVhbCwgZG91YmxlIGRlbHRhKSB7CisgICAgICAgIC8vIGhhbmRsZSBpbmZpbml0eSBzcGVjaWFsbHkgc2luY2Ugc3VidHJhY3RpbmcgdG8gaW5maW5pdGUgdmFsdWVzIGdpdmVzIE5hTiBhbmQgdGhlCisgICAgICAgIC8vIHRoZSBmb2xsb3dpbmcgdGVzdCBmYWlscworICAgICAgICBpZiAoRG91YmxlLmlzSW5maW5pdGUoZXhwZWN0ZWQpKSB7CisgICAgICAgICAgICBpZiAoIShleHBlY3RlZCA9PSBhY3R1YWwpKQorICAgICAgICAgICAgICAgIGZhaWxOb3RFcXVhbHMobWVzc2FnZSwgbmV3IERvdWJsZShleHBlY3RlZCksIG5ldyBEb3VibGUoYWN0dWFsKSk7CisgICAgICAgIH0gZWxzZSBpZiAoIShNYXRoLmFicyhleHBlY3RlZC1hY3R1YWwpIDw9IGRlbHRhKSkgLy8gQmVjYXVzZSBjb21wYXJpc29uIHdpdGggTmFOIGFsd2F5cyByZXR1cm5zIGZhbHNlCisgICAgICAgICAgICBmYWlsTm90RXF1YWxzKG1lc3NhZ2UsIG5ldyBEb3VibGUoZXhwZWN0ZWQpLCBuZXcgRG91YmxlKGFjdHVhbCkpOworICAgIH0KKyAgICAvKioKKyAgICAgKiBBc3NlcnRzIHRoYXQgdHdvIGRvdWJsZXMgYXJlIGVxdWFsIGNvbmNlcm5pbmcgYSBkZWx0YS4gSWYgdGhlIGV4cGVjdGVkCisgICAgICogdmFsdWUgaXMgaW5maW5pdHkgdGhlbiB0aGUgZGVsdGEgdmFsdWUgaXMgaWdub3JlZC4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKGRvdWJsZSBleHBlY3RlZCwgZG91YmxlIGFjdHVhbCwgZG91YmxlIGRlbHRhKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBleHBlY3RlZCwgYWN0dWFsLCBkZWx0YSk7CisgICAgfQorICAgIC8qKgorICAgICAqIEFzc2VydHMgdGhhdCB0d28gZmxvYXRzIGFyZSBlcXVhbCBjb25jZXJuaW5nIGEgZGVsdGEuIElmIHRoZXkgYXJlIG5vdAorICAgICAqIGFuIEFzc2VydGlvbkZhaWxlZEVycm9yIGlzIHRocm93biB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlLiAgSWYgdGhlIGV4cGVjdGVkCisgICAgICogdmFsdWUgaXMgaW5maW5pdHkgdGhlbiB0aGUgZGVsdGEgdmFsdWUgaXMgaWdub3JlZC4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKFN0cmluZyBtZXNzYWdlLCBmbG9hdCBleHBlY3RlZCwgZmxvYXQgYWN0dWFsLCBmbG9hdCBkZWx0YSkgeworICAgICAgICAgLy8gaGFuZGxlIGluZmluaXR5IHNwZWNpYWxseSBzaW5jZSBzdWJ0cmFjdGluZyB0byBpbmZpbml0ZSB2YWx1ZXMgZ2l2ZXMgTmFOIGFuZCB0aGUKKyAgICAgICAgLy8gdGhlIGZvbGxvd2luZyB0ZXN0IGZhaWxzCisgICAgICAgIGlmIChGbG9hdC5pc0luZmluaXRlKGV4cGVjdGVkKSkgeworICAgICAgICAgICAgaWYgKCEoZXhwZWN0ZWQgPT0gYWN0dWFsKSkKKyAgICAgICAgICAgICAgICBmYWlsTm90RXF1YWxzKG1lc3NhZ2UsIG5ldyBGbG9hdChleHBlY3RlZCksIG5ldyBGbG9hdChhY3R1YWwpKTsKKyAgICAgICAgfSBlbHNlIGlmICghKE1hdGguYWJzKGV4cGVjdGVkLWFjdHVhbCkgPD0gZGVsdGEpKQorICAgICAgICAgICAgICBmYWlsTm90RXF1YWxzKG1lc3NhZ2UsIG5ldyBGbG9hdChleHBlY3RlZCksIG5ldyBGbG9hdChhY3R1YWwpKTsKKyAgICB9CisgICAgLyoqCisgICAgICogQXNzZXJ0cyB0aGF0IHR3byBmbG9hdHMgYXJlIGVxdWFsIGNvbmNlcm5pbmcgYSBkZWx0YS4gSWYgdGhlIGV4cGVjdGVkCisgICAgICogdmFsdWUgaXMgaW5maW5pdHkgdGhlbiB0aGUgZGVsdGEgdmFsdWUgaXMgaWdub3JlZC4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKGZsb2F0IGV4cGVjdGVkLCBmbG9hdCBhY3R1YWwsIGZsb2F0IGRlbHRhKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBleHBlY3RlZCwgYWN0dWFsLCBkZWx0YSk7CisgICAgfQorICAgIC8qKgorICAgICAqIEFzc2VydHMgdGhhdCB0d28gbG9uZ3MgYXJlIGVxdWFsLiBJZiB0aGV5IGFyZSBub3QKKyAgICAgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciBpcyB0aHJvd24gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKFN0cmluZyBtZXNzYWdlLCBsb25nIGV4cGVjdGVkLCBsb25nIGFjdHVhbCkgeworICAgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgbmV3IExvbmcoZXhwZWN0ZWQpLCBuZXcgTG9uZyhhY3R1YWwpKTsKKyAgICB9CisgICAgLyoqCisgICAgICogQXNzZXJ0cyB0aGF0IHR3byBsb25ncyBhcmUgZXF1YWwuCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFscyhsb25nIGV4cGVjdGVkLCBsb25nIGFjdHVhbCkgeworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgfQorICAgIC8qKgorICAgICAqIEFzc2VydHMgdGhhdCB0d28gYm9vbGVhbnMgYXJlIGVxdWFsLiBJZiB0aGV5IGFyZSBub3QKKyAgICAgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciBpcyB0aHJvd24gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKFN0cmluZyBtZXNzYWdlLCBib29sZWFuIGV4cGVjdGVkLCBib29sZWFuIGFjdHVhbCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsIG5ldyBCb29sZWFuKGV4cGVjdGVkKSwgbmV3IEJvb2xlYW4oYWN0dWFsKSk7CisgICAgICB9CisgICAgLyoqCisgICAgICogQXNzZXJ0cyB0aGF0IHR3byBib29sZWFucyBhcmUgZXF1YWwuCisgICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoYm9vbGVhbiBleHBlY3RlZCwgYm9vbGVhbiBhY3R1YWwpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGV4cGVjdGVkLCBhY3R1YWwpOworICAgIH0KKyAgICAvKioKKyAgICAgKiBBc3NlcnRzIHRoYXQgdHdvIGJ5dGVzIGFyZSBlcXVhbC4gSWYgdGhleSBhcmUgbm90CisgICAgICogYW4gQXNzZXJ0aW9uRmFpbGVkRXJyb3IgaXMgdGhyb3duIHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UuCisgICAgICovCisgICAgICBzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKFN0cmluZyBtZXNzYWdlLCBieXRlIGV4cGVjdGVkLCBieXRlIGFjdHVhbCkgeworICAgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgbmV3IEJ5dGUoZXhwZWN0ZWQpLCBuZXcgQnl0ZShhY3R1YWwpKTsKKyAgICB9CisgICAgLyoqCisgICAgICAgICogQXNzZXJ0cyB0aGF0IHR3byBieXRlcyBhcmUgZXF1YWwuCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFscyhieXRlIGV4cGVjdGVkLCBieXRlIGFjdHVhbCkgeworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgfQorICAgIC8qKgorICAgICAqIEFzc2VydHMgdGhhdCB0d28gY2hhcnMgYXJlIGVxdWFsLiBJZiB0aGV5IGFyZSBub3QKKyAgICAgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciBpcyB0aHJvd24gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS4KKyAgICAgKi8KKyAgICAgIHN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIG1lc3NhZ2UsIGNoYXIgZXhwZWN0ZWQsIGNoYXIgYWN0dWFsKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgbmV3IENoYXJhY3RlcihleHBlY3RlZCksIG5ldyBDaGFyYWN0ZXIoYWN0dWFsKSk7CisgICAgICB9CisgICAgLyoqCisgICAgICogQXNzZXJ0cyB0aGF0IHR3byBjaGFycyBhcmUgZXF1YWwuCisgICAgICovCisgICAgICBzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKGNoYXIgZXhwZWN0ZWQsIGNoYXIgYWN0dWFsKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgICB9CisgICAgLyoqCisgICAgICogQXNzZXJ0cyB0aGF0IHR3byBzaG9ydHMgYXJlIGVxdWFsLiBJZiB0aGV5IGFyZSBub3QKKyAgICAgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciBpcyB0aHJvd24gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKFN0cmluZyBtZXNzYWdlLCBzaG9ydCBleHBlY3RlZCwgc2hvcnQgYWN0dWFsKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgbmV3IFNob3J0KGV4cGVjdGVkKSwgbmV3IFNob3J0KGFjdHVhbCkpOworICAgIH0KKyAgICAgIC8qKgorICAgICAqIEFzc2VydHMgdGhhdCB0d28gc2hvcnRzIGFyZSBlcXVhbC4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKHNob3J0IGV4cGVjdGVkLCBzaG9ydCBhY3R1YWwpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGV4cGVjdGVkLCBhY3R1YWwpOworICAgIH0KKyAgICAvKioKKyAgICAgKiBBc3NlcnRzIHRoYXQgdHdvIGludHMgYXJlIGVxdWFsLiBJZiB0aGV5IGFyZSBub3QKKyAgICAgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciBpcyB0aHJvd24gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS4KKyAgICAgKi8KKyAgICAgIHN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIG1lc3NhZ2UsIGludCBleHBlY3RlZCwgaW50IGFjdHVhbCkgeworICAgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgbmV3IEludGVnZXIoZXhwZWN0ZWQpLCBuZXcgSW50ZWdlcihhY3R1YWwpKTsKKyAgICAgIH0KKyAgICAgIC8qKgorICAgICAgICAqIEFzc2VydHMgdGhhdCB0d28gaW50cyBhcmUgZXF1YWwuCisgICAgICovCisgICAgICBzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKGludCBleHBlY3RlZCwgaW50IGFjdHVhbCkgeworICAgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgICB9CisgICAgLyoqCisgICAgICogQXNzZXJ0cyB0aGF0IGFuIG9iamVjdCBpc24ndCBudWxsLgorICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnROb3ROdWxsKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChudWxsLCBvYmplY3QpOworICAgIH0KKyAgICAvKioKKyAgICAgKiBBc3NlcnRzIHRoYXQgYW4gb2JqZWN0IGlzbid0IG51bGwuIElmIGl0IGlzCisgICAgICogYW4gQXNzZXJ0aW9uRmFpbGVkRXJyb3IgaXMgdGhyb3duIHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UuCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydE5vdE51bGwoU3RyaW5nIG1lc3NhZ2UsIE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLCBvYmplY3QgIT0gbnVsbCk7CisgICAgfQorICAgIC8qKgorICAgICAqIEFzc2VydHMgdGhhdCBhbiBvYmplY3QgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0TnVsbChPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGFzc2VydE51bGwobnVsbCwgb2JqZWN0KTsKKyAgICB9CisgICAgLyoqCisgICAgICogQXNzZXJ0cyB0aGF0IGFuIG9iamVjdCBpcyBudWxsLiAgSWYgaXQgaXMgbm90CisgICAgICogYW4gQXNzZXJ0aW9uRmFpbGVkRXJyb3IgaXMgdGhyb3duIHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UuCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydE51bGwoU3RyaW5nIG1lc3NhZ2UsIE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLCBvYmplY3QgPT0gbnVsbCk7CisgICAgfQorICAgIC8qKgorICAgICAqIEFzc2VydHMgdGhhdCB0d28gb2JqZWN0cyByZWZlciB0byB0aGUgc2FtZSBvYmplY3QuIElmIHRoZXkgYXJlIG5vdAorICAgICAqIGFuIEFzc2VydGlvbkZhaWxlZEVycm9yIGlzIHRocm93biB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlLgorICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRTYW1lKFN0cmluZyBtZXNzYWdlLCBPYmplY3QgZXhwZWN0ZWQsIE9iamVjdCBhY3R1YWwpIHsKKyAgICAgICAgaWYgKGV4cGVjdGVkID09IGFjdHVhbCkKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgZmFpbE5vdFNhbWUobWVzc2FnZSwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgfQorICAgIC8qKgorICAgICAqIEFzc2VydHMgdGhhdCB0d28gb2JqZWN0cyByZWZlciB0byB0aGUgc2FtZSBvYmplY3QuIElmIHRoZXkgYXJlIG5vdAorICAgICAqIHRoZSBzYW1lIGFuIEFzc2VydGlvbkZhaWxlZEVycm9yIGlzIHRocm93bi4KKyAgICAgKi8KKyAgICBzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0U2FtZShPYmplY3QgZXhwZWN0ZWQsIE9iamVjdCBhY3R1YWwpIHsKKyAgICAgICAgYXNzZXJ0U2FtZShudWxsLCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgICB9CisgICAgIC8qKgorICAgICAgKiBBc3NlcnRzIHRoYXQgdHdvIG9iamVjdHMgZG8gbm90IHJlZmVyIHRvIHRoZSBzYW1lIG9iamVjdC4gSWYgdGhleSBhcmUKKyAgICAgICogYW4gQXNzZXJ0aW9uRmFpbGVkRXJyb3IgaXMgdGhyb3duIHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UuCisgICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnROb3RTYW1lKFN0cmluZyBtZXNzYWdlLCBPYmplY3QgZXhwZWN0ZWQsIE9iamVjdCBhY3R1YWwpIHsKKyAgICAgICAgaWYgKGV4cGVjdGVkID09IGFjdHVhbCkKKyAgICAgICAgICAgIGZhaWxTYW1lKG1lc3NhZ2UpOworICAgIH0KKyAgICAvKioKKyAgICAgKiBBc3NlcnRzIHRoYXQgdHdvIG9iamVjdHMgZG8gbm90IHJlZmVyIHRvIHRoZSBzYW1lIG9iamVjdC4gSWYgdGhleSBhcmUKKyAgICAgKiB0aGUgc2FtZSBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciBpcyB0aHJvd24uCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydE5vdFNhbWUoT2JqZWN0IGV4cGVjdGVkLCBPYmplY3QgYWN0dWFsKSB7CisgICAgICAgIGFzc2VydE5vdFNhbWUobnVsbCwgZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgfQorCisgICAgc3RhdGljIHByaXZhdGUgdm9pZCBmYWlsU2FtZShTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICBTdHJpbmcgZm9ybWF0dGVkPSAiIjsKKyAgICAgICAgIGlmIChtZXNzYWdlICE9IG51bGwpCisgICAgICAgICAgICAgZm9ybWF0dGVkPSBtZXNzYWdlKyIgIjsKKyAgICAgICAgIGZhaWwoZm9ybWF0dGVkKyJleHBlY3RlZCBub3Qgc2FtZSIpOworICAgIH0KKworICAgIHN0YXRpYyBwcml2YXRlIHZvaWQgZmFpbE5vdFNhbWUoU3RyaW5nIG1lc3NhZ2UsIE9iamVjdCBleHBlY3RlZCwgT2JqZWN0IGFjdHVhbCkgeworICAgICAgICBTdHJpbmcgZm9ybWF0dGVkPSAiIjsKKyAgICAgICAgaWYgKG1lc3NhZ2UgIT0gbnVsbCkKKyAgICAgICAgICAgIGZvcm1hdHRlZD0gbWVzc2FnZSsiICI7CisgICAgICAgIGZhaWwoZm9ybWF0dGVkKyJleHBlY3RlZCBzYW1lOjwiK2V4cGVjdGVkKyI+IHdhcyBub3Q6PCIrYWN0dWFsKyI+Iik7CisgICAgfQorCisgICAgc3RhdGljIHByaXZhdGUgdm9pZCBmYWlsTm90RXF1YWxzKFN0cmluZyBtZXNzYWdlLCBPYmplY3QgZXhwZWN0ZWQsIE9iamVjdCBhY3R1YWwpIHsKKyAgICAgICAgZmFpbChmb3JtYXQobWVzc2FnZSwgZXhwZWN0ZWQsIGFjdHVhbCkpOworICAgIH0KKworICAgIHN0YXRpYyBTdHJpbmcgZm9ybWF0KFN0cmluZyBtZXNzYWdlLCBPYmplY3QgZXhwZWN0ZWQsIE9iamVjdCBhY3R1YWwpIHsKKyAgICAgICAgU3RyaW5nIGZvcm1hdHRlZD0gIiI7CisgICAgICAgIGlmIChtZXNzYWdlICE9IG51bGwpCisgICAgICAgICAgICBmb3JtYXR0ZWQ9IG1lc3NhZ2UrIiAiOworICAgICAgICByZXR1cm4gZm9ybWF0dGVkKyJleHBlY3RlZDo8IitleHBlY3RlZCsiPiBidXQgd2FzOjwiK2FjdHVhbCsiPiI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9mcmFtZXdvcmsvQXNzZXJ0aW9uRmFpbGVkRXJyb3IuamF2YSBiL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL0Fzc2VydGlvbkZhaWxlZEVycm9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTljYjNhMwotLS0gL2Rldi9udWxsCisrKyBiL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL0Fzc2VydGlvbkZhaWxlZEVycm9yLmphdmEKQEAgLTAsMCArMSwxMyBAQAorcGFja2FnZSBqdW5pdC5mcmFtZXdvcms7CisKKy8qKgorICogVGhyb3duIHdoZW4gYW4gYXNzZXJ0aW9uIGZhaWxlZC4KKyAqLworcHVibGljIGNsYXNzIEFzc2VydGlvbkZhaWxlZEVycm9yIGV4dGVuZHMgRXJyb3IgeworCisgICAgcHVibGljIEFzc2VydGlvbkZhaWxlZEVycm9yICgpIHsKKyAgICB9CisgICAgcHVibGljIEFzc2VydGlvbkZhaWxlZEVycm9yIChTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICBzdXBlciAobWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9mcmFtZXdvcmsvQ29tcGFyaXNvbkZhaWx1cmUuamF2YSBiL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL0NvbXBhcmlzb25GYWlsdXJlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2NkNDc2YgotLS0gL2Rldi9udWxsCisrKyBiL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL0NvbXBhcmlzb25GYWlsdXJlLmphdmEKQEAgLTAsMCArMSw2OCBAQAorcGFja2FnZSBqdW5pdC5mcmFtZXdvcms7CisKKy8qKgorICogVGhyb3duIHdoZW4gYW4gYXNzZXJ0IGVxdWFscyBmb3IgU3RyaW5ncyBmYWlsZWQuCisgKgorICogSW5zcGlyZWQgYnkgYSBwYXRjaCBmcm9tIEFsZXggQ2hhZmZlZSBtYWlsdG86YWxleEBwdXJwbGV0ZWNoLmNvbQorICovCitwdWJsaWMgY2xhc3MgQ29tcGFyaXNvbkZhaWx1cmUgZXh0ZW5kcyBBc3NlcnRpb25GYWlsZWRFcnJvciB7CisgICAgcHJpdmF0ZSBTdHJpbmcgZkV4cGVjdGVkOworICAgIHByaXZhdGUgU3RyaW5nIGZBY3R1YWw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgY29tcGFyaXNvbiBmYWlsdXJlLgorICAgICAqIEBwYXJhbSBtZXNzYWdlIHRoZSBpZGVudGlmeWluZyBtZXNzYWdlIG9yIG51bGwKKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWQgdGhlIGV4cGVjdGVkIHN0cmluZyB2YWx1ZQorICAgICAqIEBwYXJhbSBhY3R1YWwgdGhlIGFjdHVhbCBzdHJpbmcgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29tcGFyaXNvbkZhaWx1cmUgKFN0cmluZyBtZXNzYWdlLCBTdHJpbmcgZXhwZWN0ZWQsIFN0cmluZyBhY3R1YWwpIHsKKyAgICAgICAgc3VwZXIgKG1lc3NhZ2UpOworICAgICAgICBmRXhwZWN0ZWQ9IGV4cGVjdGVkOworICAgICAgICBmQWN0dWFsPSBhY3R1YWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyAiLi4uIiBpbiBwbGFjZSBvZiBjb21tb24gcHJlZml4IGFuZCAiLi4uIiBpbgorICAgICAqIHBsYWNlIG9mIGNvbW1vbiBzdWZmaXggYmV0d2VlbiBleHBlY3RlZCBhbmQgYWN0dWFsLgorICAgICAqCisgICAgICogQHNlZSBqYXZhLmxhbmcuVGhyb3dhYmxlI2dldE1lc3NhZ2UoKQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKyAgICAgICAgaWYgKGZFeHBlY3RlZCA9PSBudWxsIHx8IGZBY3R1YWwgPT0gbnVsbCkKKyAgICAgICAgICAgIHJldHVybiBBc3NlcnQuZm9ybWF0KHN1cGVyLmdldE1lc3NhZ2UoKSwgZkV4cGVjdGVkLCBmQWN0dWFsKTsKKworICAgICAgICBpbnQgZW5kPSBNYXRoLm1pbihmRXhwZWN0ZWQubGVuZ3RoKCksIGZBY3R1YWwubGVuZ3RoKCkpOworCisgICAgICAgIGludCBpPSAwOworICAgICAgICBmb3IgKDsgaSA8IGVuZDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoZkV4cGVjdGVkLmNoYXJBdChpKSAhPSBmQWN0dWFsLmNoYXJBdChpKSkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpbnQgaj0gZkV4cGVjdGVkLmxlbmd0aCgpLTE7CisgICAgICAgIGludCBrPSBmQWN0dWFsLmxlbmd0aCgpLTE7CisgICAgICAgIGZvciAoOyBrID49IGkgJiYgaiA+PSBpOyBrLS0sai0tKSB7CisgICAgICAgICAgICBpZiAoZkV4cGVjdGVkLmNoYXJBdChqKSAhPSBmQWN0dWFsLmNoYXJBdChrKSkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgYWN0dWFsLCBleHBlY3RlZDsKKworICAgICAgICAvLyBlcXVhbCBzdHJpbmdzCisgICAgICAgIGlmIChqIDwgaSAmJiBrIDwgaSkgeworICAgICAgICAgICAgZXhwZWN0ZWQ9IGZFeHBlY3RlZDsKKyAgICAgICAgICAgIGFjdHVhbD0gZkFjdHVhbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGV4cGVjdGVkPSBmRXhwZWN0ZWQuc3Vic3RyaW5nKGksIGorMSk7CisgICAgICAgICAgICBhY3R1YWw9IGZBY3R1YWwuc3Vic3RyaW5nKGksIGsrMSk7CisgICAgICAgICAgICBpZiAoaSA8PSBlbmQgJiYgaSA+IDApIHsKKyAgICAgICAgICAgICAgICBleHBlY3RlZD0gIi4uLiIrZXhwZWN0ZWQ7CisgICAgICAgICAgICAgICAgYWN0dWFsPSAiLi4uIithY3R1YWw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChqIDwgZkV4cGVjdGVkLmxlbmd0aCgpLTEpCisgICAgICAgICAgICAgICAgZXhwZWN0ZWQ9IGV4cGVjdGVkKyIuLi4iOworICAgICAgICAgICAgaWYgKGsgPCBmQWN0dWFsLmxlbmd0aCgpLTEpCisgICAgICAgICAgICAgICAgYWN0dWFsPSBhY3R1YWwrIi4uLiI7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIEFzc2VydC5mb3JtYXQoc3VwZXIuZ2V0TWVzc2FnZSgpLCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9qdW5pdC9zcmMvbWFpbi9qYXZhL2p1bml0L2ZyYW1ld29yay9Qcm90ZWN0YWJsZS5qYXZhIGIvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9mcmFtZXdvcmsvUHJvdGVjdGFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YTYzYzk2Ci0tLSAvZGV2L251bGwKKysrIGIvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9mcmFtZXdvcmsvUHJvdGVjdGFibGUuamF2YQpAQCAtMCwwICsxLDE0IEBACitwYWNrYWdlIGp1bml0LmZyYW1ld29yazsKKworLyoqCisgKiBBIDxlbT5Qcm90ZWN0YWJsZTwvZW0+IGNhbiBiZSBydW4gYW5kIGNhbiB0aHJvdyBhIFRocm93YWJsZS4KKyAqCisgKiBAc2VlIFRlc3RSZXN1bHQKKyAqLworcHVibGljIGludGVyZmFjZSBQcm90ZWN0YWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBSdW4gdGhlIHRoZSBmb2xsb3dpbmcgbWV0aG9kIHByb3RlY3RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBwcm90ZWN0KCkgdGhyb3dzIFRocm93YWJsZTsKK30KZGlmZiAtLWdpdCBhL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL1Rlc3QuamF2YSBiL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NGYyNWNmCi0tLSAvZGV2L251bGwKKysrIGIvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9mcmFtZXdvcmsvVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTcgQEAKK3BhY2thZ2UganVuaXQuZnJhbWV3b3JrOworCisvKioKKyAqIEEgPGVtPlRlc3Q8L2VtPiBjYW4gYmUgcnVuIGFuZCBjb2xsZWN0IGl0cyByZXN1bHRzLgorICoKKyAqIEBzZWUgVGVzdFJlc3VsdAorICovCitwdWJsaWMgaW50ZXJmYWNlIFRlc3QgeworICAgIC8qKgorICAgICAqIENvdW50cyB0aGUgbnVtYmVyIG9mIHRlc3QgY2FzZXMgdGhhdCB3aWxsIGJlIHJ1biBieSB0aGlzIHRlc3QuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBjb3VudFRlc3RDYXNlcygpOworICAgIC8qKgorICAgICAqIFJ1bnMgYSB0ZXN0IGFuZCBjb2xsZWN0cyBpdHMgcmVzdWx0IGluIGEgVGVzdFJlc3VsdCBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBydW4oVGVzdFJlc3VsdCByZXN1bHQpOworfQpkaWZmIC0tZ2l0IGEvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9mcmFtZXdvcmsvVGVzdENhc2UuamF2YSBiL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL1Rlc3RDYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjI5ZThkMgotLS0gL2Rldi9udWxsCisrKyBiL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL1Rlc3RDYXNlLmphdmEKQEAgLTAsMCArMSwxOTcgQEAKK3BhY2thZ2UganVuaXQuZnJhbWV3b3JrOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuKjsKKworLyoqCisgKiBBIHRlc3QgY2FzZSBkZWZpbmVzIHRoZSBmaXh0dXJlIHRvIHJ1biBtdWx0aXBsZSB0ZXN0cy4gVG8gZGVmaW5lIGEgdGVzdCBjYXNlPGJyPgorICogMSkgaW1wbGVtZW50IGEgc3ViY2xhc3Mgb2YgVGVzdENhc2U8YnI+CisgKiAyKSBkZWZpbmUgaW5zdGFuY2UgdmFyaWFibGVzIHRoYXQgc3RvcmUgdGhlIHN0YXRlIG9mIHRoZSBmaXh0dXJlPGJyPgorICogMykgaW5pdGlhbGl6ZSB0aGUgZml4dHVyZSBzdGF0ZSBieSBvdmVycmlkaW5nIDxjb2RlPnNldFVwPC9jb2RlPjxicj4KKyAqIDQpIGNsZWFuLXVwIGFmdGVyIGEgdGVzdCBieSBvdmVycmlkaW5nIDxjb2RlPnRlYXJEb3duPC9jb2RlPi48YnI+CisgKiBFYWNoIHRlc3QgcnVucyBpbiBpdHMgb3duIGZpeHR1cmUgc28gdGhlcmUKKyAqIGNhbiBiZSBubyBzaWRlIGVmZmVjdHMgYW1vbmcgdGVzdCBydW5zLgorICogSGVyZSBpcyBhbiBleGFtcGxlOgorICogPHByZT4KKyAqIHB1YmxpYyBjbGFzcyBNYXRoVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAqICAgICBwcm90ZWN0ZWQgZG91YmxlIGZWYWx1ZTE7CisgKiAgICAgcHJvdGVjdGVkIGRvdWJsZSBmVmFsdWUyOworICoKKyAqICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICogICAgICAgICBmVmFsdWUxPSAyLjA7CisgKiAgICAgICAgIGZWYWx1ZTI9IDMuMDsKKyAqICAgICB9CisgKiB9CisgKiA8L3ByZT4KKyAqCisgKiBGb3IgZWFjaCB0ZXN0IGltcGxlbWVudCBhIG1ldGhvZCB3aGljaCBpbnRlcmFjdHMKKyAqIHdpdGggdGhlIGZpeHR1cmUuIFZlcmlmeSB0aGUgZXhwZWN0ZWQgcmVzdWx0cyB3aXRoIGFzc2VydGlvbnMgc3BlY2lmaWVkCisgKiBieSBjYWxsaW5nIDxjb2RlPmFzc2VydFRydWU8L2NvZGU+IHdpdGggYSBib29sZWFuLgorICogPHByZT4KKyAqICAgIHB1YmxpYyB2b2lkIHRlc3RBZGQoKSB7CisgKiAgICAgICAgZG91YmxlIHJlc3VsdD0gZlZhbHVlMSArIGZWYWx1ZTI7CisgKiAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQgPT0gNS4wKTsKKyAqICAgIH0KKyAqIDwvcHJlPgorICogT25jZSB0aGUgbWV0aG9kcyBhcmUgZGVmaW5lZCB5b3UgY2FuIHJ1biB0aGVtLiBUaGUgZnJhbWV3b3JrIHN1cHBvcnRzCisgKiBib3RoIGEgc3RhdGljIHR5cGUgc2FmZSBhbmQgbW9yZSBkeW5hbWljIHdheSB0byBydW4gYSB0ZXN0LgorICogSW4gdGhlIHN0YXRpYyB3YXkgeW91IG92ZXJyaWRlIHRoZSBydW5UZXN0IG1ldGhvZCBhbmQgZGVmaW5lIHRoZSBtZXRob2QgdG8KKyAqIGJlIGludm9rZWQuIEEgY29udmVuaWVudCB3YXkgdG8gZG8gc28gaXMgd2l0aCBhbiBhbm9ueW1vdXMgaW5uZXIgY2xhc3MuCisgKiA8cHJlPgorICogVGVzdENhc2UgdGVzdD0gbmV3IE1hdGhUZXN0KCJhZGQiKSB7CisgKiAgICAgICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHsKKyAqICAgICAgICAgICAgdGVzdEFkZCgpOworICogICAgICAgIH0KKyAqIH07CisgKiB0ZXN0LnJ1bigpOworICogPC9wcmU+CisgKiBUaGUgZHluYW1pYyB3YXkgdXNlcyByZWZsZWN0aW9uIHRvIGltcGxlbWVudCA8Y29kZT5ydW5UZXN0PC9jb2RlPi4gSXQgZHluYW1pY2FsbHkgZmluZHMKKyAqIGFuZCBpbnZva2VzIGEgbWV0aG9kLgorICogSW4gdGhpcyBjYXNlIHRoZSBuYW1lIG9mIHRoZSB0ZXN0IGNhc2UgaGFzIHRvIGNvcnJlc3BvbmQgdG8gdGhlIHRlc3QgbWV0aG9kCisgKiB0byBiZSBydW4uCisgKiA8cHJlPgorICogVGVzdENhc2U9IG5ldyBNYXRoVGVzdCgidGVzdEFkZCIpOworICogdGVzdC5ydW4oKTsKKyAqIDwvcHJlPgorICogVGhlIHRlc3RzIHRvIGJlIHJ1biBjYW4gYmUgY29sbGVjdGVkIGludG8gYSBUZXN0U3VpdGUuIEpVbml0IHByb3ZpZGVzCisgKiBkaWZmZXJlbnQgPGk+dGVzdCBydW5uZXJzPC9pPiB3aGljaCBjYW4gcnVuIGEgdGVzdCBzdWl0ZSBhbmQgY29sbGVjdCB0aGUgcmVzdWx0cy4KKyAqIEEgdGVzdCBydW5uZXIgZWl0aGVyIGV4cGVjdHMgYSBzdGF0aWMgbWV0aG9kIDxjb2RlPnN1aXRlPC9jb2RlPiBhcyB0aGUgZW50cnkKKyAqIHBvaW50IHRvIGdldCBhIHRlc3QgdG8gcnVuIG9yIGl0IHdpbGwgZXh0cmFjdCB0aGUgc3VpdGUgYXV0b21hdGljYWxseS4KKyAqIDxwcmU+CisgKiBwdWJsaWMgc3RhdGljIFRlc3Qgc3VpdGUoKSB7CisgKiAgICAgIHN1aXRlLmFkZFRlc3QobmV3IE1hdGhUZXN0KCJ0ZXN0QWRkIikpOworICogICAgICBzdWl0ZS5hZGRUZXN0KG5ldyBNYXRoVGVzdCgidGVzdERpdmlkZUJ5WmVybyIpKTsKKyAqICAgICAgcmV0dXJuIHN1aXRlOworICogIH0KKyAqIDwvcHJlPgorICogQHNlZSBUZXN0UmVzdWx0CisgKiBAc2VlIFRlc3RTdWl0ZQorICovCisKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBUZXN0Q2FzZSBleHRlbmRzIEFzc2VydCBpbXBsZW1lbnRzIFRlc3QgeworICAgIC8qKgorICAgICAqIHRoZSBuYW1lIG9mIHRoZSB0ZXN0IGNhc2UKKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBmTmFtZTsKKworICAgIC8qKgorICAgICAqIE5vLWFyZyBjb25zdHJ1Y3RvciB0byBlbmFibGUgc2VyaWFsaXphdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBub3QgaW50ZW5kZWQgdG8gYmUgdXNlZCBieSBtZXJlIG1vcnRhbHMgd2l0aG91dCBjYWxsaW5nIHNldE5hbWUoKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGVzdENhc2UoKSB7CisgICAgICAgIGZOYW1lPSBudWxsOworICAgIH0KKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgdGVzdCBjYXNlIHdpdGggdGhlIGdpdmVuIG5hbWUuCisgICAgICovCisgICAgcHVibGljIFRlc3RDYXNlKFN0cmluZyBuYW1lKSB7CisgICAgICAgIGZOYW1lPSBuYW1lOworICAgIH0KKyAgICAvKioKKyAgICAgKiBDb3VudHMgdGhlIG51bWJlciBvZiB0ZXN0IGNhc2VzIGV4ZWN1dGVkIGJ5IHJ1bihUZXN0UmVzdWx0IHJlc3VsdCkuCisgICAgICovCisgICAgcHVibGljIGludCBjb3VudFRlc3RDYXNlcygpIHsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBkZWZhdWx0IFRlc3RSZXN1bHQgb2JqZWN0CisgICAgICoKKyAgICAgKiBAc2VlIFRlc3RSZXN1bHQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgVGVzdFJlc3VsdCBjcmVhdGVSZXN1bHQoKSB7CisgICAgICAgIHJldHVybiBuZXcgVGVzdFJlc3VsdCgpOworICAgIH0KKyAgICAvKioKKyAgICAgKiBBIGNvbnZlbmllbmNlIG1ldGhvZCB0byBydW4gdGhpcyB0ZXN0LCBjb2xsZWN0aW5nIHRoZSByZXN1bHRzIHdpdGggYQorICAgICAqIGRlZmF1bHQgVGVzdFJlc3VsdCBvYmplY3QuCisgICAgICoKKyAgICAgKiBAc2VlIFRlc3RSZXN1bHQKKyAgICAgKi8KKyAgICBwdWJsaWMgVGVzdFJlc3VsdCBydW4oKSB7CisgICAgICAgIFRlc3RSZXN1bHQgcmVzdWx0PSBjcmVhdGVSZXN1bHQoKTsKKyAgICAgICAgcnVuKHJlc3VsdCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZSBhbmQgY29sbGVjdHMgdGhlIHJlc3VsdHMgaW4gVGVzdFJlc3VsdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBydW4oVGVzdFJlc3VsdCByZXN1bHQpIHsKKyAgICAgICAgcmVzdWx0LnJ1bih0aGlzKTsKKyAgICB9CisgICAgLyoqCisgICAgICogUnVucyB0aGUgYmFyZSB0ZXN0IHNlcXVlbmNlLgorICAgICAqIEBleGNlcHRpb24gVGhyb3dhYmxlIGlmIGFueSBleGNlcHRpb24gaXMgdGhyb3duCisgICAgICovCisgICAgcHVibGljIHZvaWQgcnVuQmFyZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBzZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcnVuVGVzdCgpOworICAgICAgICB9CisgICAgICAgIGZpbmFsbHkgeworICAgICAgICAgICAgdGVhckRvd24oKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBPdmVycmlkZSB0byBydW4gdGhlIHRlc3QgYW5kIGFzc2VydCBpdHMgc3RhdGUuCisgICAgICogQGV4Y2VwdGlvbiBUaHJvd2FibGUgaWYgYW55IGV4Y2VwdGlvbiBpcyB0aHJvd24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIGFzc2VydE5vdE51bGwoZk5hbWUpOworICAgICAgICBNZXRob2QgcnVuTWV0aG9kPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gdXNlIGdldE1ldGhvZCB0byBnZXQgYWxsIHB1YmxpYyBpbmhlcml0ZWQKKyAgICAgICAgICAgIC8vIG1ldGhvZHMuIGdldERlY2xhcmVkTWV0aG9kcyByZXR1cm5zIGFsbAorICAgICAgICAgICAgLy8gbWV0aG9kcyBvZiB0aGlzIGNsYXNzIGJ1dCBleGNsdWRlcyB0aGUKKyAgICAgICAgICAgIC8vIGluaGVyaXRlZCBvbmVzLgorICAgICAgICAgICAgcnVuTWV0aG9kPSBnZXRDbGFzcygpLmdldE1ldGhvZChmTmFtZSwgKENsYXNzW10pIG51bGwpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiTWV0aG9kIFwiIitmTmFtZSsiXCIgbm90IGZvdW5kIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFNb2RpZmllci5pc1B1YmxpYyhydW5NZXRob2QuZ2V0TW9kaWZpZXJzKCkpKSB7CisgICAgICAgICAgICBmYWlsKCJNZXRob2QgXCIiK2ZOYW1lKyJcIiBzaG91bGQgYmUgcHVibGljIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcnVuTWV0aG9kLmludm9rZSh0aGlzLCAoT2JqZWN0W10pIG51bGwpOworICAgICAgICB9CisgICAgICAgIGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUuZmlsbEluU3RhY2tUcmFjZSgpOworICAgICAgICAgICAgdGhyb3cgZS5nZXRUYXJnZXRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLmZpbGxJblN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0KKyAgICB9CisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uCisgICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB9CisgICAgLyoqCisgICAgICogVGVhcnMgZG93biB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIGNsb3NlIGEgbmV0d29yayBjb25uZWN0aW9uLgorICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBhZnRlciBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB9CisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdGVzdCBjYXNlCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIGdldE5hbWUoKSArICIoIiArIGdldENsYXNzKCkuZ2V0TmFtZSgpICsgIikiOworICAgIH0KKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBuYW1lIG9mIGEgVGVzdENhc2UKKyAgICAgKiBAcmV0dXJuIHJldHVybnMgYSBTdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBmTmFtZTsKKyAgICB9CisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmFtZSBvZiBhIFRlc3RDYXNlCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgdG8gc2V0CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TmFtZShTdHJpbmcgbmFtZSkgeworICAgICAgICBmTmFtZT0gbmFtZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9qdW5pdC9zcmMvbWFpbi9qYXZhL2p1bml0L2ZyYW1ld29yay9UZXN0RmFpbHVyZS5qYXZhIGIvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9mcmFtZXdvcmsvVGVzdEZhaWx1cmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NTYxNGEzCi0tLSAvZGV2L251bGwKKysrIGIvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9mcmFtZXdvcmsvVGVzdEZhaWx1cmUuamF2YQpAQCAtMCwwICsxLDU3IEBACitwYWNrYWdlIGp1bml0LmZyYW1ld29yazsKKworaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CitpbXBvcnQgamF2YS5pby5TdHJpbmdXcml0ZXI7CisKKworLyoqCisgKiBBIDxjb2RlPlRlc3RGYWlsdXJlPC9jb2RlPiBjb2xsZWN0cyBhIGZhaWxlZCB0ZXN0IHRvZ2V0aGVyIHdpdGgKKyAqIHRoZSBjYXVnaHQgZXhjZXB0aW9uLgorICogQHNlZSBUZXN0UmVzdWx0CisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0RmFpbHVyZSBleHRlbmRzIE9iamVjdCB7CisgICAgcHJvdGVjdGVkIFRlc3QgZkZhaWxlZFRlc3Q7CisgICAgcHJvdGVjdGVkIFRocm93YWJsZSBmVGhyb3duRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgVGVzdEZhaWx1cmUgd2l0aCB0aGUgZ2l2ZW4gdGVzdCBhbmQgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBUZXN0RmFpbHVyZShUZXN0IGZhaWxlZFRlc3QsIFRocm93YWJsZSB0aHJvd25FeGNlcHRpb24pIHsKKyAgICAgICAgZkZhaWxlZFRlc3Q9IGZhaWxlZFRlc3Q7CisgICAgICAgIGZUaHJvd25FeGNlcHRpb249IHRocm93bkV4Y2VwdGlvbjsKKyAgICB9CisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZmFpbGVkIHRlc3QuCisgICAgICovCisgICAgcHVibGljIFRlc3QgZmFpbGVkVGVzdCgpIHsKKyAgICAgICAgcmV0dXJuIGZGYWlsZWRUZXN0OworICAgIH0KKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0aHJvd24gZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBUaHJvd2FibGUgdGhyb3duRXhjZXB0aW9uKCkgeworICAgICAgICByZXR1cm4gZlRocm93bkV4Y2VwdGlvbjsKKyAgICB9CisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSBmYWlsdXJlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1ZmZlciBidWZmZXI9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgYnVmZmVyLmFwcGVuZChmRmFpbGVkVGVzdCsiOiAiK2ZUaHJvd25FeGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZygpOworICAgIH0KKyAgICBwdWJsaWMgU3RyaW5nIHRyYWNlKCkgeworICAgICAgICBTdHJpbmdXcml0ZXIgc3RyaW5nV3JpdGVyPSBuZXcgU3RyaW5nV3JpdGVyKCk7CisgICAgICAgIFByaW50V3JpdGVyIHdyaXRlcj0gbmV3IFByaW50V3JpdGVyKHN0cmluZ1dyaXRlcik7CisgICAgICAgIHRocm93bkV4Y2VwdGlvbigpLnByaW50U3RhY2tUcmFjZSh3cml0ZXIpOworICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyPSBzdHJpbmdXcml0ZXIuZ2V0QnVmZmVyKCk7CisgICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKKyAgICB9CisgICAgcHVibGljIFN0cmluZyBleGNlcHRpb25NZXNzYWdlKCkgeworICAgICAgICByZXR1cm4gdGhyb3duRXhjZXB0aW9uKCkuZ2V0TWVzc2FnZSgpOworICAgIH0KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0ZhaWx1cmUoKSB7CisgICAgICAgIHJldHVybiB0aHJvd25FeGNlcHRpb24oKSBpbnN0YW5jZW9mIEFzc2VydGlvbkZhaWxlZEVycm9yOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL1Rlc3RMaXN0ZW5lci5qYXZhIGIvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9mcmFtZXdvcmsvVGVzdExpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDFjNmNjZgotLS0gL2Rldi9udWxsCisrKyBiL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL1Rlc3RMaXN0ZW5lci5qYXZhCkBAIC0wLDAgKzEsMjMgQEAKK3BhY2thZ2UganVuaXQuZnJhbWV3b3JrOworCisvKioKKyAqIEEgTGlzdGVuZXIgZm9yIHRlc3QgcHJvZ3Jlc3MKKyAqLworcHVibGljIGludGVyZmFjZSBUZXN0TGlzdGVuZXIgeworICAgIC8qKgorICAgICAgKiBBbiBlcnJvciBvY2N1cnJlZC4KKyAgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkRXJyb3IoVGVzdCB0ZXN0LCBUaHJvd2FibGUgdCk7CisgICAgLyoqCisgICAgICAqIEEgZmFpbHVyZSBvY2N1cnJlZC4KKyAgICAgICovCisgICAgIHB1YmxpYyB2b2lkIGFkZEZhaWx1cmUoVGVzdCB0ZXN0LCBBc3NlcnRpb25GYWlsZWRFcnJvciB0KTsKKyAgICAvKioKKyAgICAgKiBBIHRlc3QgZW5kZWQuCisgICAgICovCisgICAgIHB1YmxpYyB2b2lkIGVuZFRlc3QoVGVzdCB0ZXN0KTsKKyAgICAvKioKKyAgICAgKiBBIHRlc3Qgc3RhcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdGFydFRlc3QoVGVzdCB0ZXN0KTsKK30KZGlmZiAtLWdpdCBhL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL1Rlc3RSZXN1bHQuamF2YSBiL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL1Rlc3RSZXN1bHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iY2NhMWRlCi0tLSAvZGV2L251bGwKKysrIGIvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9mcmFtZXdvcmsvVGVzdFJlc3VsdC5qYXZhCkBAIC0wLDAgKzEsMTY2IEBACitwYWNrYWdlIGp1bml0LmZyYW1ld29yazsKKworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworCisvKioKKyAqIEEgPGNvZGU+VGVzdFJlc3VsdDwvY29kZT4gY29sbGVjdHMgdGhlIHJlc3VsdHMgb2YgZXhlY3V0aW5nCisgKiBhIHRlc3QgY2FzZS4gSXQgaXMgYW4gaW5zdGFuY2Ugb2YgdGhlIENvbGxlY3RpbmcgUGFyYW1ldGVyIHBhdHRlcm4uCisgKiBUaGUgdGVzdCBmcmFtZXdvcmsgZGlzdGluZ3Vpc2hlcyBiZXR3ZWVuIDxpPmZhaWx1cmVzPC9pPiBhbmQgPGk+ZXJyb3JzPC9pPi4KKyAqIEEgZmFpbHVyZSBpcyBhbnRpY2lwYXRlZCBhbmQgY2hlY2tlZCBmb3Igd2l0aCBhc3NlcnRpb25zLiBFcnJvcnMgYXJlCisgKiB1bmFudGljaXBhdGVkIHByb2JsZW1zIGxpa2UgYW4gPGNvZGU+QXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uPC9jb2RlPi4KKyAqCisgKiBAc2VlIFRlc3QKKyAqLworcHVibGljIGNsYXNzIFRlc3RSZXN1bHQgZXh0ZW5kcyBPYmplY3QgeworICAgIHByb3RlY3RlZCBWZWN0b3IgZkZhaWx1cmVzOworICAgIHByb3RlY3RlZCBWZWN0b3IgZkVycm9yczsKKyAgICBwcm90ZWN0ZWQgVmVjdG9yIGZMaXN0ZW5lcnM7CisgICAgcHJvdGVjdGVkIGludCBmUnVuVGVzdHM7CisgICAgcHJpdmF0ZSBib29sZWFuIGZTdG9wOworCisgICAgcHVibGljIFRlc3RSZXN1bHQoKSB7CisgICAgICAgIGZGYWlsdXJlcz0gbmV3IFZlY3RvcigpOworICAgICAgICBmRXJyb3JzPSBuZXcgVmVjdG9yKCk7CisgICAgICAgIGZMaXN0ZW5lcnM9IG5ldyBWZWN0b3IoKTsKKyAgICAgICAgZlJ1blRlc3RzPSAwOworICAgICAgICBmU3RvcD0gZmFsc2U7CisgICAgfQorICAgIC8qKgorICAgICAqIEFkZHMgYW4gZXJyb3IgdG8gdGhlIGxpc3Qgb2YgZXJyb3JzLiBUaGUgcGFzc2VkIGluIGV4Y2VwdGlvbgorICAgICAqIGNhdXNlZCB0aGUgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFkZEVycm9yKFRlc3QgdGVzdCwgVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgZkVycm9ycy5hZGRFbGVtZW50KG5ldyBUZXN0RmFpbHVyZSh0ZXN0LCB0KSk7CisgICAgICAgIGZvciAoRW51bWVyYXRpb24gZT0gY2xvbmVMaXN0ZW5lcnMoKS5lbGVtZW50cygpOyBlLmhhc01vcmVFbGVtZW50cygpOyApIHsKKyAgICAgICAgICAgICgoVGVzdExpc3RlbmVyKWUubmV4dEVsZW1lbnQoKSkuYWRkRXJyb3IodGVzdCwgdCk7CisgICAgICAgIH0KKyAgICB9CisgICAgLyoqCisgICAgICogQWRkcyBhIGZhaWx1cmUgdG8gdGhlIGxpc3Qgb2YgZmFpbHVyZXMuIFRoZSBwYXNzZWQgaW4gZXhjZXB0aW9uCisgICAgICogY2F1c2VkIHRoZSBmYWlsdXJlLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhZGRGYWlsdXJlKFRlc3QgdGVzdCwgQXNzZXJ0aW9uRmFpbGVkRXJyb3IgdCkgeworICAgICAgICBmRmFpbHVyZXMuYWRkRWxlbWVudChuZXcgVGVzdEZhaWx1cmUodGVzdCwgdCkpOworICAgICAgICBmb3IgKEVudW1lcmF0aW9uIGU9IGNsb25lTGlzdGVuZXJzKCkuZWxlbWVudHMoKTsgZS5oYXNNb3JlRWxlbWVudHMoKTsgKSB7CisgICAgICAgICAgICAoKFRlc3RMaXN0ZW5lcillLm5leHRFbGVtZW50KCkpLmFkZEZhaWx1cmUodGVzdCwgdCk7CisgICAgICAgIH0KKyAgICB9CisgICAgLyoqCisgICAgICogUmVnaXN0ZXJzIGEgVGVzdExpc3RlbmVyCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFkZExpc3RlbmVyKFRlc3RMaXN0ZW5lciBsaXN0ZW5lcikgeworICAgICAgICBmTGlzdGVuZXJzLmFkZEVsZW1lbnQobGlzdGVuZXIpOworICAgIH0KKyAgICAvKioKKyAgICAgKiBVbnJlZ2lzdGVycyBhIFRlc3RMaXN0ZW5lcgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZW1vdmVMaXN0ZW5lcihUZXN0TGlzdGVuZXIgbGlzdGVuZXIpIHsKKyAgICAgICAgZkxpc3RlbmVycy5yZW1vdmVFbGVtZW50KGxpc3RlbmVyKTsKKyAgICB9CisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhlIGxpc3RlbmVycy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCBWZWN0b3IgY2xvbmVMaXN0ZW5lcnMoKSB7CisgICAgICAgIHJldHVybiAoVmVjdG9yKWZMaXN0ZW5lcnMuY2xvbmUoKTsKKyAgICB9CisgICAgLyoqCisgICAgICogSW5mb3JtcyB0aGUgcmVzdWx0IHRoYXQgYSB0ZXN0IHdhcyBjb21wbGV0ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZW5kVGVzdChUZXN0IHRlc3QpIHsKKyAgICAgICAgZm9yIChFbnVtZXJhdGlvbiBlPSBjbG9uZUxpc3RlbmVycygpLmVsZW1lbnRzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7ICkgeworICAgICAgICAgICAgKChUZXN0TGlzdGVuZXIpZS5uZXh0RWxlbWVudCgpKS5lbmRUZXN0KHRlc3QpOworICAgICAgICB9CisgICAgfQorICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBkZXRlY3RlZCBlcnJvcnMuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZXJyb3JDb3VudCgpIHsKKyAgICAgICAgcmV0dXJuIGZFcnJvcnMuc2l6ZSgpOworICAgIH0KKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIEVudW1lcmF0aW9uIGZvciB0aGUgZXJyb3JzCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBFbnVtZXJhdGlvbiBlcnJvcnMoKSB7CisgICAgICAgIHJldHVybiBmRXJyb3JzLmVsZW1lbnRzKCk7CisgICAgfQorICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBkZXRlY3RlZCBmYWlsdXJlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBmYWlsdXJlQ291bnQoKSB7CisgICAgICAgIHJldHVybiBmRmFpbHVyZXMuc2l6ZSgpOworICAgIH0KKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIEVudW1lcmF0aW9uIGZvciB0aGUgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEVudW1lcmF0aW9uIGZhaWx1cmVzKCkgeworICAgICAgICByZXR1cm4gZkZhaWx1cmVzLmVsZW1lbnRzKCk7CisgICAgfQorICAgIC8qKgorICAgICAqIFJ1bnMgYSBUZXN0Q2FzZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBydW4oZmluYWwgVGVzdENhc2UgdGVzdCkgeworICAgICAgICBzdGFydFRlc3QodGVzdCk7CisgICAgICAgIFByb3RlY3RhYmxlIHA9IG5ldyBQcm90ZWN0YWJsZSgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHByb3RlY3QoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgICAgICAgICB0ZXN0LnJ1bkJhcmUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgcnVuUHJvdGVjdGVkKHRlc3QsIHApOworCisgICAgICAgIGVuZFRlc3QodGVzdCk7CisgICAgfQorICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBydW4gdGVzdHMuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgcnVuQ291bnQoKSB7CisgICAgICAgIHJldHVybiBmUnVuVGVzdHM7CisgICAgfQorICAgIC8qKgorICAgICAqIFJ1bnMgYSBUZXN0Q2FzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBydW5Qcm90ZWN0ZWQoZmluYWwgVGVzdCB0ZXN0LCBQcm90ZWN0YWJsZSBwKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwLnByb3RlY3QoKTsKKyAgICAgICAgfQorICAgICAgICBjYXRjaCAoQXNzZXJ0aW9uRmFpbGVkRXJyb3IgZSkgeworICAgICAgICAgICAgYWRkRmFpbHVyZSh0ZXN0LCBlKTsKKyAgICAgICAgfQorICAgICAgICBjYXRjaCAoVGhyZWFkRGVhdGggZSkgeyAvLyBkb24ndCBjYXRjaCBUaHJlYWREZWF0aCBieSBhY2NpZGVudAorICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgfQorICAgICAgICBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgICAgIGFkZEVycm9yKHRlc3QsIGUpOworICAgICAgICB9CisgICAgfQorICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSB0ZXN0IHJ1biBzaG91bGQgc3RvcAorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBzaG91bGRTdG9wKCkgeworICAgICAgICByZXR1cm4gZlN0b3A7CisgICAgfQorICAgIC8qKgorICAgICAqIEluZm9ybXMgdGhlIHJlc3VsdCB0aGF0IGEgdGVzdCB3aWxsIGJlIHN0YXJ0ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc3RhcnRUZXN0KFRlc3QgdGVzdCkgeworICAgICAgICBmaW5hbCBpbnQgY291bnQ9IHRlc3QuY291bnRUZXN0Q2FzZXMoKTsKKyAgICAgICAgc3luY2hyb25pemVkKHRoaXMpIHsKKyAgICAgICAgICAgIGZSdW5UZXN0cys9IGNvdW50OworICAgICAgICB9CisgICAgICAgIGZvciAoRW51bWVyYXRpb24gZT0gY2xvbmVMaXN0ZW5lcnMoKS5lbGVtZW50cygpOyBlLmhhc01vcmVFbGVtZW50cygpOyApIHsKKyAgICAgICAgICAgICgoVGVzdExpc3RlbmVyKWUubmV4dEVsZW1lbnQoKSkuc3RhcnRUZXN0KHRlc3QpOworICAgICAgICB9CisgICAgfQorICAgIC8qKgorICAgICAqIE1hcmtzIHRoYXQgdGhlIHRlc3QgcnVuIHNob3VsZCBzdG9wLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzdG9wKCkgeworICAgICAgICBmU3RvcD0gdHJ1ZTsKKyAgICB9CisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBlbnRpcmUgdGVzdCB3YXMgc3VjY2Vzc2Z1bCBvciBub3QuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIHdhc1N1Y2Nlc3NmdWwoKSB7CisgICAgICAgIHJldHVybiBmYWlsdXJlQ291bnQoKSA9PSAwICYmIGVycm9yQ291bnQoKSA9PSAwOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL1Rlc3RTdWl0ZS5qYXZhIGIvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9mcmFtZXdvcmsvVGVzdFN1aXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDJkZjJiNwotLS0gL2Rldi9udWxsCisrKyBiL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL1Rlc3RTdWl0ZS5qYXZhCkBAIC0wLDAgKzEsMjY3IEBACitwYWNrYWdlIGp1bml0LmZyYW1ld29yazsKKworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CitpbXBvcnQgamF2YS5pby5TdHJpbmdXcml0ZXI7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuKjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworLyoqCisgKiBBIDxjb2RlPlRlc3RTdWl0ZTwvY29kZT4gaXMgYSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IG9mIFRlc3RzLgorICogSXQgcnVucyBhIGNvbGxlY3Rpb24gb2YgdGVzdCBjYXNlcy4gSGVyZSBpcyBhbiBleGFtcGxlIHVzaW5nCisgKiB0aGUgZHluYW1pYyB0ZXN0IGRlZmluaXRpb24uCisgKiA8cHJlPgorICogVGVzdFN1aXRlIHN1aXRlPSBuZXcgVGVzdFN1aXRlKCk7CisgKiBzdWl0ZS5hZGRUZXN0KG5ldyBNYXRoVGVzdCgidGVzdEFkZCIpKTsKKyAqIHN1aXRlLmFkZFRlc3QobmV3IE1hdGhUZXN0KCJ0ZXN0RGl2aWRlQnlaZXJvIikpOworICogPC9wcmU+CisgKiBBbHRlcm5hdGl2ZWx5LCBhIFRlc3RTdWl0ZSBjYW4gZXh0cmFjdCB0aGUgdGVzdHMgdG8gYmUgcnVuIGF1dG9tYXRpY2FsbHkuCisgKiBUbyBkbyBzbyB5b3UgcGFzcyB0aGUgY2xhc3Mgb2YgeW91ciBUZXN0Q2FzZSBjbGFzcyB0byB0aGUKKyAqIFRlc3RTdWl0ZSBjb25zdHJ1Y3Rvci4KKyAqIDxwcmU+CisgKiBUZXN0U3VpdGUgc3VpdGU9IG5ldyBUZXN0U3VpdGUoTWF0aFRlc3QuY2xhc3MpOworICogPC9wcmU+CisgKiBUaGlzIGNvbnN0cnVjdG9yIGNyZWF0ZXMgYSBzdWl0ZSB3aXRoIGFsbCB0aGUgbWV0aG9kcworICogc3RhcnRpbmcgd2l0aCAidGVzdCIgdGhhdCB0YWtlIG5vIGFyZ3VtZW50cy4KKyAqCisgKiBAc2VlIFRlc3QKKyAqLworcHVibGljIGNsYXNzIFRlc3RTdWl0ZSBpbXBsZW1lbnRzIFRlc3QgeworCisgICAgcHJpdmF0ZSBWZWN0b3IgZlRlc3RzPSBuZXcgVmVjdG9yKDEwKTsKKyAgICBwcml2YXRlIFN0cmluZyBmTmFtZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gZW1wdHkgVGVzdFN1aXRlLgorICAgICAqLworICAgIHB1YmxpYyBUZXN0U3VpdGUoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIFRlc3RTdWl0ZSBmcm9tIHRoZSBnaXZlbiBjbGFzcyB3aXRoIHRoZSBnaXZlbiBuYW1lLgorICAgICAqIEBzZWUgVGVzdFN1aXRlI1Rlc3RTdWl0ZShDbGFzcykKKyAgICAgKi8KKyAgICBwdWJsaWMgVGVzdFN1aXRlKENsYXNzIHRoZUNsYXNzLCBTdHJpbmcgbmFtZSkgeworICAgICAgICB0aGlzKHRoZUNsYXNzKTsKKyAgICAgICAgc2V0TmFtZShuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgVGVzdFN1aXRlIGZyb20gdGhlIGdpdmVuIGNsYXNzLiBBZGRzIGFsbCB0aGUgbWV0aG9kcworICAgICAqIHN0YXJ0aW5nIHdpdGggInRlc3QiIGFzIHRlc3QgY2FzZXMgdG8gdGhlIHN1aXRlLgorICAgICAqIFBhcnRzIG9mIHRoaXMgbWV0aG9kIHdhcyB3cml0dGVuIGF0IDIzMzcgbWV0ZXJzIGluIHRoZSBIdWZmaWh1dHRlLAorICAgICAqIEthbnRvbiBVcmkKKyAgICAgKi8KKyAgICAgcHVibGljIFRlc3RTdWl0ZShmaW5hbCBDbGFzcyB0aGVDbGFzcykgeworICAgICAgICBmTmFtZT0gdGhlQ2xhc3MuZ2V0TmFtZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZ2V0VGVzdENvbnN0cnVjdG9yKHRoZUNsYXNzKTsgLy8gQXZvaWQgZ2VuZXJhdGluZyBtdWx0aXBsZSBlcnJvciBtZXNzYWdlcworICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYWRkVGVzdCh3YXJuaW5nKCJDbGFzcyAiK3RoZUNsYXNzLmdldE5hbWUoKSsiIGhhcyBubyBwdWJsaWMgY29uc3RydWN0b3IgVGVzdENhc2UoU3RyaW5nIG5hbWUpIG9yIFRlc3RDYXNlKCkiKSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAoIU1vZGlmaWVyLmlzUHVibGljKHRoZUNsYXNzLmdldE1vZGlmaWVycygpKSkgeworICAgICAgICAgICAgYWRkVGVzdCh3YXJuaW5nKCJDbGFzcyAiK3RoZUNsYXNzLmdldE5hbWUoKSsiIGlzIG5vdCBwdWJsaWMiKSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBDbGFzcyBzdXBlckNsYXNzPSB0aGVDbGFzczsKKyAgICAgICAgVmVjdG9yIG5hbWVzPSBuZXcgVmVjdG9yKCk7CisgICAgICAgIHdoaWxlIChUZXN0LmNsYXNzLmlzQXNzaWduYWJsZUZyb20oc3VwZXJDbGFzcykpIHsKKyAgICAgICAgICAgIE1ldGhvZFtdIG1ldGhvZHM9IHN1cGVyQ2xhc3MuZ2V0RGVjbGFyZWRNZXRob2RzKCk7CisgICAgICAgICAgICBmb3IgKGludCBpPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGFkZFRlc3RNZXRob2QobWV0aG9kc1tpXSwgbmFtZXMsIHRoZUNsYXNzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHN1cGVyQ2xhc3M9IHN1cGVyQ2xhc3MuZ2V0U3VwZXJjbGFzcygpOworICAgICAgICB9CisgICAgICAgIGlmIChmVGVzdHMuc2l6ZSgpID09IDApCisgICAgICAgICAgICBhZGRUZXN0KHdhcm5pbmcoIk5vIHRlc3RzIGZvdW5kIGluICIrdGhlQ2xhc3MuZ2V0TmFtZSgpKSk7CisgICAgfQorCisgICAgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBlbXB0eSBUZXN0U3VpdGUuCisgICAgICovCisgICAgcHVibGljIFRlc3RTdWl0ZShTdHJpbmcgbmFtZSkgeworICAgICAgICBzZXROYW1lKG5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSB0ZXN0IHRvIHRoZSBzdWl0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRUZXN0KFRlc3QgdGVzdCkgeworICAgICAgICBmVGVzdHMuYWRkRWxlbWVudCh0ZXN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSB0ZXN0cyBmcm9tIHRoZSBnaXZlbiBjbGFzcyB0byB0aGUgc3VpdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRUZXN0U3VpdGUoQ2xhc3MgdGVzdENsYXNzKSB7CisgICAgICAgIGFkZFRlc3QobmV3IFRlc3RTdWl0ZSh0ZXN0Q2xhc3MpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYWRkVGVzdE1ldGhvZChNZXRob2QgbSwgVmVjdG9yIG5hbWVzLCBDbGFzcyB0aGVDbGFzcykgeworICAgICAgICBTdHJpbmcgbmFtZT0gbS5nZXROYW1lKCk7CisgICAgICAgIGlmIChuYW1lcy5jb250YWlucyhuYW1lKSkKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgaWYgKCEgaXNQdWJsaWNUZXN0TWV0aG9kKG0pKSB7CisgICAgICAgICAgICBpZiAoaXNUZXN0TWV0aG9kKG0pKQorICAgICAgICAgICAgICAgIGFkZFRlc3Qod2FybmluZygiVGVzdCBtZXRob2QgaXNuJ3QgcHVibGljOiAiK20uZ2V0TmFtZSgpKSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgbmFtZXMuYWRkRWxlbWVudChuYW1lKTsKKyAgICAgICAgYWRkVGVzdChjcmVhdGVUZXN0KHRoZUNsYXNzLCBuYW1lKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogLi4uYXMgdGhlIG1vb24gc2V0cyBvdmVyIHRoZSBlYXJseSBtb3JuaW5nIE1lcmxpbiwgT3JlZ29uCisgICAgICogbW91bnRhaW5zLCBvdXIgaW50cmVwaWQgYWR2ZW50dXJlcnMgdHlwZS4uLgorICAgICAqLworICAgIHN0YXRpYyBwdWJsaWMgVGVzdCBjcmVhdGVUZXN0KENsYXNzIHRoZUNsYXNzLCBTdHJpbmcgbmFtZSkgeworICAgICAgICBDb25zdHJ1Y3RvciBjb25zdHJ1Y3RvcjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbnN0cnVjdG9yPSBnZXRUZXN0Q29uc3RydWN0b3IodGhlQ2xhc3MpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIHdhcm5pbmcoIkNsYXNzICIrdGhlQ2xhc3MuZ2V0TmFtZSgpKyIgaGFzIG5vIHB1YmxpYyBjb25zdHJ1Y3RvciBUZXN0Q2FzZShTdHJpbmcgbmFtZSkgb3IgVGVzdENhc2UoKSIpOworICAgICAgICB9CisgICAgICAgIE9iamVjdCB0ZXN0OworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGNvbnN0cnVjdG9yLmdldFBhcmFtZXRlclR5cGVzKCkubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgICAgICB0ZXN0PSBjb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0WzBdKTsKKyAgICAgICAgICAgICAgICBpZiAodGVzdCBpbnN0YW5jZW9mIFRlc3RDYXNlKQorICAgICAgICAgICAgICAgICAgICAoKFRlc3RDYXNlKSB0ZXN0KS5zZXROYW1lKG5hbWUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0ZXN0PSBjb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W117bmFtZX0pOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybih3YXJuaW5nKCJDYW5ub3QgaW5zdGFudGlhdGUgdGVzdCBjYXNlOiAiK25hbWUrIiAoIitleGNlcHRpb25Ub1N0cmluZyhlKSsiKSIpKTsKKyAgICAgICAgfSBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4od2FybmluZygiRXhjZXB0aW9uIGluIGNvbnN0cnVjdG9yOiAiK25hbWUrIiAoIitleGNlcHRpb25Ub1N0cmluZyhlLmdldFRhcmdldEV4Y2VwdGlvbigpKSsiKSIpKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4od2FybmluZygiQ2Fubm90IGFjY2VzcyB0ZXN0IGNhc2U6ICIrbmFtZSsiICgiK2V4Y2VwdGlvblRvU3RyaW5nKGUpKyIpIikpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoVGVzdCkgdGVzdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGUgc3RhY2sgdHJhY2UgaW50byBhIHN0cmluZworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBleGNlcHRpb25Ub1N0cmluZyhUaHJvd2FibGUgdCkgeworICAgICAgICBTdHJpbmdXcml0ZXIgc3RyaW5nV3JpdGVyPSBuZXcgU3RyaW5nV3JpdGVyKCk7CisgICAgICAgIFByaW50V3JpdGVyIHdyaXRlcj0gbmV3IFByaW50V3JpdGVyKHN0cmluZ1dyaXRlcik7CisgICAgICAgIHQucHJpbnRTdGFja1RyYWNlKHdyaXRlcik7CisgICAgICAgIHJldHVybiBzdHJpbmdXcml0ZXIudG9TdHJpbmcoKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIENvdW50cyB0aGUgbnVtYmVyIG9mIHRlc3QgY2FzZXMgdGhhdCB3aWxsIGJlIHJ1biBieSB0aGlzIHRlc3QuCisgICAgICovCisgICAgcHVibGljIGludCBjb3VudFRlc3RDYXNlcygpIHsKKyAgICAgICAgaW50IGNvdW50PSAwOworICAgICAgICBmb3IgKEVudW1lcmF0aW9uIGU9IHRlc3RzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7ICkgeworICAgICAgICAgICAgVGVzdCB0ZXN0PSAoVGVzdCllLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICBjb3VudD0gY291bnQgKyB0ZXN0LmNvdW50VGVzdENhc2VzKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvdW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBjb25zdHJ1Y3RvciB3aGljaCB0YWtlcyBhIHNpbmdsZSBTdHJpbmcgYXMKKyAgICAgKiBpdHMgYXJndW1lbnQgb3IgYSBubyBhcmcgY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDb25zdHJ1Y3RvciBnZXRUZXN0Q29uc3RydWN0b3IoQ2xhc3MgdGhlQ2xhc3MpIHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24geworICAgICAgICBDbGFzc1tdIGFyZ3M9IHsgU3RyaW5nLmNsYXNzIH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gdGhlQ2xhc3MuZ2V0Q29uc3RydWN0b3IoYXJncyk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBmYWxsIHRocm91Z2gKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhlQ2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzWzBdKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNQdWJsaWNUZXN0TWV0aG9kKE1ldGhvZCBtKSB7CisgICAgICAgIHJldHVybiBpc1Rlc3RNZXRob2QobSkgJiYgTW9kaWZpZXIuaXNQdWJsaWMobS5nZXRNb2RpZmllcnMoKSk7CisgICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBpc1Rlc3RNZXRob2QoTWV0aG9kIG0pIHsKKyAgICAgICAgU3RyaW5nIG5hbWU9IG0uZ2V0TmFtZSgpOworICAgICAgICBDbGFzc1tdIHBhcmFtZXRlcnM9IG0uZ2V0UGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgQ2xhc3MgcmV0dXJuVHlwZT0gbS5nZXRSZXR1cm5UeXBlKCk7CisgICAgICAgIHJldHVybiBwYXJhbWV0ZXJzLmxlbmd0aCA9PSAwICYmIG5hbWUuc3RhcnRzV2l0aCgidGVzdCIpICYmIHJldHVyblR5cGUuZXF1YWxzKFZvaWQuVFlQRSk7CisgICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3RzIGFuZCBjb2xsZWN0cyB0aGVpciByZXN1bHQgaW4gYSBUZXN0UmVzdWx0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJ1bihUZXN0UmVzdWx0IHJlc3VsdCkgeworICAgICAgICBmb3IgKEVudW1lcmF0aW9uIGU9IHRlc3RzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7ICkgeworICAgICAgICAgICAgICBpZiAocmVzdWx0LnNob3VsZFN0b3AoKSApCisgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIFRlc3QgdGVzdD0gKFRlc3QpZS5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgcnVuVGVzdCh0ZXN0LCByZXN1bHQpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcnVuVGVzdChUZXN0IHRlc3QsIFRlc3RSZXN1bHQgcmVzdWx0KSB7CisgICAgICAgIHRlc3QucnVuKHJlc3VsdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGVzdCBhdCB0aGUgZ2l2ZW4gaW5kZXgKKyAgICAgKi8KKyAgICBwdWJsaWMgVGVzdCB0ZXN0QXQoaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiAoVGVzdClmVGVzdHMuZWxlbWVudEF0KGluZGV4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgdGVzdHMgaW4gdGhpcyBzdWl0ZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgdGVzdENvdW50KCkgeworICAgICAgICByZXR1cm4gZlRlc3RzLnNpemUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0ZXN0cyBhcyBhbiBlbnVtZXJhdGlvbgorICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbiB0ZXN0cygpIHsKKyAgICAgICAgcmV0dXJuIGZUZXN0cy5lbGVtZW50cygpOworICAgIH0KKworICAgIC8qKgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIGlmIChnZXROYW1lKCkgIT0gbnVsbCkKKyAgICAgICAgICAgIHJldHVybiBnZXROYW1lKCk7CisgICAgICAgIHJldHVybiBzdXBlci50b1N0cmluZygpOworICAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBzdWl0ZS4KKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSB0byBzZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROYW1lKFN0cmluZyBuYW1lKSB7CisgICAgICAgIGZOYW1lPSBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHN1aXRlLiBOb3QgYWxsCisgICAgICogdGVzdCBzdWl0ZXMgaGF2ZSBhIG5hbWUgYW5kIHRoaXMgbWV0aG9kCisgICAgICogY2FuIHJldHVybiBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIGZOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB0ZXN0IHdoaWNoIHdpbGwgZmFpbCBhbmQgbG9nIGEgd2FybmluZyBtZXNzYWdlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFRlc3Qgd2FybmluZyhmaW5hbCBTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICByZXR1cm4gbmV3IFRlc3RDYXNlKCJ3YXJuaW5nIikgeworICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgcnVuVGVzdCgpIHsKKyAgICAgICAgICAgICAgICBmYWlsKG1lc3NhZ2UpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL3BhY2thZ2UuaHRtbCBiL2p1bml0L3NyYy9tYWluL2phdmEvanVuaXQvZnJhbWV3b3JrL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NzBkNDcwCi0tLSAvZGV2L251bGwKKysrIGIvanVuaXQvc3JjL21haW4vamF2YS9qdW5pdC9mcmFtZXdvcmsvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsNSBAQAorPEhUTUw+Cis8Qk9EWT4KK1RoZSBqdW5pdCB0ZXN0IGZyYW1ld29yay4KKzwvQk9EWT4KKzwvSFRNTD4KZGlmZiAtLWdpdCBhL2x1bmkvTU9EVUxFX0xJQ0VOU0VfQVBBQ0hFMiBiL2x1bmkvTU9EVUxFX0xJQ0VOU0VfQVBBQ0hFMgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjlkZTI5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9NT0RVTEVfTElDRU5TRV9BUEFDSEUyCmRpZmYgLS1naXQgYS9sdW5pL01PRFVMRV9MSUNFTlNFX0JTRF9MSUtFIGIvbHVuaS9NT0RVTEVfTElDRU5TRV9CU0RfTElLRQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZmZjZDMzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9NT0RVTEVfTElDRU5TRV9CU0RfTElLRQpAQCAtMCwwICsxIEBACitGb3IgQm91bmN5IENhc3RsZQpkaWZmIC0tZ2l0IGEvbHVuaS9NT0RVTEVfTElDRU5TRV9XM0MgYi9sdW5pL01PRFVMRV9MSUNFTlNFX1czQwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZjQxMTA2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9NT0RVTEVfTElDRU5TRV9XM0MKQEAgLTAsMCArMSwzIEBACitGb3Igb3JnLnczYy5kb20gY29kZS4KKworU2VlIDxodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLz4uCmRpZmYgLS1naXQgYS9sdW5pL2JvdW5jeWNhc3RsZS1saWNlbnNlLnR4dCBiL2x1bmkvYm91bmN5Y2FzdGxlLWxpY2Vuc2UudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNmZWVmNzIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL2JvdW5jeWNhc3RsZS1saWNlbnNlLnR4dApAQCAtMCwwICsxLDIxIEBACitDb3B5cmlnaHQgKGMpIDIwMDAgLSAyMDA2IFRoZSBMZWdpb24gT2YgVGhlIEJvdW5jeSBDYXN0bGUKKyhodHRwOi8vd3d3LmJvdW5jeWNhc3RsZS5vcmcpCisKK1Blcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZworYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlCisiU29mdHdhcmUiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nCit3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsCitkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8KK3Blcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0bwordGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgorCitUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZQoraW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCisKK1RIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELAorRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GCitNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuCitJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWQorQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwKK1RPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFCitTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KZGlmZiAtLWdpdCBhL2x1bmkvbGljZW5zZS5odG1sIGIvbHVuaS9saWNlbnNlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjkwNWRkZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvbGljZW5zZS5odG1sCkBAIC0wLDAgKzEsNTEgQEAKKzxodG1sPgorCis8aGVhZD4KKzxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXVzLWFzY2lpIj48L21ldGE+Cis8dGl0bGU+SUNVIExpY2Vuc2UgLSBJQ1UgMS44LjEgYW5kIGxhdGVyPC90aXRsZT4KKzwvaGVhZD4KKworPGJvZHkgQkdDT0xPUj0iI2ZmZmZmZiI+Cis8aDI+SUNVIExpY2Vuc2UgLSBJQ1UgMS44LjEgYW5kIGxhdGVyPC9oMj4KKworPHA+Q09QWVJJR0hUIEFORCBQRVJNSVNTSU9OIE5PVElDRTwvcD4KKworPHA+CitDb3B5cmlnaHQgKGMpIDE5OTUtMjAwNiBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZCBvdGhlcnMKKzwvcD4KKzxwPgorQWxsIHJpZ2h0cyByZXNlcnZlZC4KKzwvcD4KKzxwPgorUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQorb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksCit0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uCit0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgYW5kL29yIHNlbGwKK2NvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucwordG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBwcm92aWRlZCB0aGF0IHRoZSBhYm92ZQorY29weXJpZ2h0IG5vdGljZShzKSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcworb2YgdGhlIFNvZnR3YXJlIGFuZCB0aGF0IGJvdGggdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UocykgYW5kIHRoaXMKK3Blcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nIGRvY3VtZW50YXRpb24uCis8L3A+Cis8cD4KK1RIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SIElNUExJRUQsIAorSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEKK1BBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5UIE9GIFRISVJEIFBBUlRZIFJJR0hUUy4gSU4gTk8gRVZFTlQgU0hBTEwKK1RIRSBDT1BZUklHSFQgSE9MREVSIE9SIEhPTERFUlMgSU5DTFVERUQgSU4gVEhJUyBOT1RJQ0UgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sCitPUiBBTlkgU1BFQ0lBTCBJTkRJUkVDVCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMsIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIKK1JFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULAorTkVHTElHRU5DRSBPUiBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUKK1VTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgorPC9wPgorPHA+CitFeGNlcHQgYXMgY29udGFpbmVkIGluIHRoaXMgbm90aWNlLCB0aGUgbmFtZSBvZiBhIGNvcHlyaWdodCBob2xkZXIgc2hhbGwgbm90IGJlCit1c2VkIGluIGFkdmVydGlzaW5nIG9yIG90aGVyd2lzZSB0byBwcm9tb3RlIHRoZSBzYWxlLCB1c2Ugb3Igb3RoZXIgZGVhbGluZ3MgaW4KK3RoaXMgU29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIGF1dGhvcml6YXRpb24gb2YgdGhlIGNvcHlyaWdodCBob2xkZXIuCis8L3A+CisKKzxocj4KKzxwPjxzbWFsbD4KK0FsbCB0cmFkZW1hcmtzIGFuZCByZWdpc3RlcmVkIHRyYWRlbWFya3MgbWVudGlvbmVkIGhlcmVpbiBhcmUgdGhlIHByb3BlcnR5IG9mIHRoZWlyIHJlc3BlY3RpdmUgb3duZXJzLgorPC9zbWFsbD48L3A+Cis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL1JFQURNRS5jYWNlcnRzIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9SRUFETUUuY2FjZXJ0cwpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi5lOTA1YTY4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9SRUFETUUuY2FjZXJ0cwpAQCAtMCwwICsxLDcgQEAKK1RoZSBmaWxlbmFtZXMgaW4gdGhlIGNhY2VydHMgZGlyZWN0b3J5IGFyZSBpbiB0aGUgZm9ybWF0IG9mIDxoYXNoPi48bj4KK3doZXJlICJoYXNoIiBpcyB0aGUgc3ViamVjdCBoYXNoIHByb2R1Y2VkIGJ5OgorCisgICAgb3BlbnNzbCB4NTA5IC1zdWJqZWN0X2hhc2ggLWluIGZpbGVuYW1lCisKK2FuZCB0aGUgIm4iIGlzIGEgdW5pcXVlIGludGVnZXIgaWRlbnRpZmllciBzdGFydGluZyBhdCAwIHRvIGRlYWwKK3dpdGggY29sbGlzaW9ucy4gU2VlIE9wZW5TU0wncyBjX3JlaGFzaCBtYW5wYWdlIGZvciBkZXRhaWxzLgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzAwNjczYjViLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMDA2NzNiNWIuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMTNlNjQ0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzAwNjczYjViLjAKQEAgLTAsMCArMSw4MyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFSURDQ0F3aWdBd0lCQWdJUU5FN1ZWeURWN2V4SjlDL09OOXNyYlRBTkJna3Foa2lHOXcwQkFRVUZBRENCCitxVEVMTUFrR0ExVUVCaE1DVlZNeEZUQVRCZ05WQkFvVERIUm9ZWGQwWlN3Z1NXNWpMakVvTUNZR0ExVUVDeE1mCitRMlZ5ZEdsbWFXTmhkR2x2YmlCVFpYSjJhV05sY3lCRWFYWnBjMmx2YmpFNE1EWUdBMVVFQ3hNdktHTXBJREl3CitNRFlnZEdoaGQzUmxMQ0JKYm1NdUlDMGdSbTl5SUdGMWRHaHZjbWw2WldRZ2RYTmxJRzl1YkhreEh6QWRCZ05WCitCQU1URm5Sb1lYZDBaU0JRY21sdFlYSjVJRkp2YjNRZ1EwRXdIaGNOTURZeE1URTNNREF3TURBd1doY05Nell3CitOekUyTWpNMU9UVTVXakNCcVRFTE1Ba0dBMVVFQmhNQ1ZWTXhGVEFUQmdOVkJBb1RESFJvWVhkMFpTd2dTVzVqCitMakVvTUNZR0ExVUVDeE1mUTJWeWRHbG1hV05oZEdsdmJpQlRaWEoyYVdObGN5QkVhWFpwYzJsdmJqRTRNRFlHCitBMVVFQ3hNdktHTXBJREl3TURZZ2RHaGhkM1JsTENCSmJtTXVJQzBnUm05eUlHRjFkR2h2Y21sNlpXUWdkWE5sCitJRzl1YkhreEh6QWRCZ05WQkFNVEZuUm9ZWGQwWlNCUWNtbHRZWEo1SUZKdmIzUWdRMEV3Z2dFaU1BMEdDU3FHCitTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDc29QRDdnRm5Vbk1la3o1MmhXWE1KRUVVTURTeHVhUEZzCitXMGhvU1ZrMy9Bc3pHY0ozZjh3UUxaVTBIT2JyVFFtbkhOSzR5WmMyQXJlSjFDUmZCc0RNUkpTVWpRSmliK3RhCiszUkdOS0pwY2hKQVFlZzI5ZEdZdmFqaWc0dFZVUk9zZEI1OEh1bS91NmYxT0N5bjFQb1NnQWZHY3EvZ2Nmb21rCis2S0hZY1dVTm8xRjc3cnpTSW1BTnVWdWQzN3I4VVZzTHI1aXk2UzdwQk9oaWg5NHJ5TmRPd1V4a0h0M1BoMWk2CitTay9LYUFjZEhKMUt4dFV2a2N4OGNYSWN4Y0JuNnpMOXlaSmNsTnFGd0p1L1UzMHJDZlNNblpFZmwycFN5OTRKCitOcVIzMkh1SFVFVFZQbTRwYWZzNVNTWWVDYVdBZTBBdDYrZ25oY24rWWYxKzVueVhIZFdkQWdNQkFBR2pRakJBCitNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEZ1lEVlIwUEFRSC9CQVFEQWdFR01CMEdBMVVkRGdRV0JCUjdXMFhQCityODdMZXYweGtocHF0dk5HNjFkSVVEQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFlUkhBUzdPUnR2enc2V2ZVCitEVzVGdmxYb2s5TE9Bei90MmlXd0hWZkxIanAyb0V6c1VIYm9aSElNcEtueHVJdlcxb2VFdXpMbFFSSEFkOW16CitZSjNyRzlYUmJrUkVxYVlCN0ZWaUhYZTRYSTVJU1h5Y08xY1JySzF6TjQ0dmVGeVFhRWZaWUdEbS9BYzlJaUFYCit4UGNXNmNUWWN2bkljM3pmRmk4VnFUNzlhaWUyb2V0YXVwZ2YxZU5OWkFxZEU4aGh1dlU1SEllNnVMMTdJbi8yCisvcXhBZWVXc0VHODlqeHQ1ZG92RU43TWhHSVRsTmdEcll5Q1p1ZW4rTXdTN1FjakJBdmxFWXlDZWdjNUMwOVkvCitMSGJUWTV4WjNZK200UTZnTGtIM0xwVkh6N3o5TS9QMkMyRitmcEVyZ1VmQ0p6RHVweEJkTjQ5Y09TdmtCUEI3CitqVmFNYUE9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgMzQ6NGU6ZDU6NTc6MjA6ZDU6ZWQ6ZWM6NDk6ZjQ6MmY6Y2U6Mzc6ZGI6MmI6NmQKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgTz10aGF3dGUsIEluYy4sIE9VPUNlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24sIE9VPShjKSAyMDA2IHRoYXd0ZSwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5LCBDTj10aGF3dGUgUHJpbWFyeSBSb290IENBCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBOb3YgMTcgMDA6MDA6MDAgMjAwNiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEp1bCAxNiAyMzo1OTo1OSAyMDM2IEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPXRoYXd0ZSwgSW5jLiwgT1U9Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbiwgT1U9KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHksIENOPXRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmFjOmEwOmYwOmZiOjgwOjU5OmQ0OjljOmM3OmE0OmNmOjlkOmExOjU5OgorICAgICAgICAgICAgICAgICAgICA3MzowOToxMDo0NTowYzowZDoyYzo2ZTo2ODpmMTo2Yzo1Yjo0ODo2ODo0OToKKyAgICAgICAgICAgICAgICAgICAgNTk6Mzc6ZmM6MGI6MzM6MTk6YzI6Nzc6N2Y6Y2M6MTA6MmQ6OTU6MzQ6MWM6CisgICAgICAgICAgICAgICAgICAgIGU2OmViOjRkOjA5OmE3OjFjOmQyOmI4OmM5Ojk3OjM2OjAyOmI3Ojg5OmQ0OgorICAgICAgICAgICAgICAgICAgICAyNDo1ZjowNjpjMDpjYzo0NDo5NDo5NDo4ZDowMjo2Mjo2ZjplYjo1YTpkZDoKKyAgICAgICAgICAgICAgICAgICAgMTE6OGQ6Mjg6OWE6NWM6ODQ6OTA6MTA6N2E6MGQ6YmQ6NzQ6NjY6MmY6NmE6CisgICAgICAgICAgICAgICAgICAgIDM4OmEwOmUyOmQ1OjU0OjQ0OmViOjFkOjA3OjlmOjA3OmJhOjZmOmVlOmU5OgorICAgICAgICAgICAgICAgICAgICBmZDo0ZTowYjoyOTpmNTozZTo4NDphMDowMTpmMTo5YzphYjpmODoxYzo3ZToKKyAgICAgICAgICAgICAgICAgICAgODk6YTQ6ZTg6YTE6ZDg6NzE6NjU6MGQ6YTM6NTE6N2I6ZWU6YmM6ZDI6MjI6CisgICAgICAgICAgICAgICAgICAgIDYwOjBkOmI5OjViOjlkOmRmOmJhOmZjOjUxOjViOjBiOmFmOjk4OmIyOmU5OgorICAgICAgICAgICAgICAgICAgICAyZTplOTowNDplODo2Mjo4NzpkZToyYjpjODpkNzo0ZTpjMTo0Yzo2NDoxZToKKyAgICAgICAgICAgICAgICAgICAgZGQ6Y2Y6ODc6NTg6YmE6NGE6NGY6Y2E6Njg6MDc6MWQ6MWM6OWQ6NGE6YzY6CisgICAgICAgICAgICAgICAgICAgIGQ1OjJmOjkxOmNjOjdjOjcxOjcyOjFjOmM1OmMwOjY3OmViOjMyOmZkOmM5OgorICAgICAgICAgICAgICAgICAgICA5Mjo1Yzo5NDpkYTo4NTpjMDo5YjpiZjo1Mzo3ZDoyYjowOTpmNDo4Yzo5ZDoKKyAgICAgICAgICAgICAgICAgICAgOTE6MWY6OTc6NmE6NTI6Y2I6ZGU6MDk6MzY6YTQ6Nzc6ZDg6N2I6ODc6NTA6CisgICAgICAgICAgICAgICAgICAgIDQ0OmQ1OjNlOjZlOjI5OjY5OmZiOjM5OjQ5OjI2OjFlOjA5OmE1OjgwOjdiOgorICAgICAgICAgICAgICAgICAgICA0MDoyZDplYjplODoyNzo4NTpjOTpmZTo2MTpmZDo3ZTplNjo3Yzo5NzoxZDoKKyAgICAgICAgICAgICAgICAgICAgZDU6OWQKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICA3Qjo1Qjo0NTpDRjpBRjpDRTpDQjo3QTpGRDozMTo5MjoxQTo2QTpCNjpGMzo0NjpFQjo1Nzo0ODo1MAorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA3OToxMTpjMDo0YjpiMzo5MTpiNjpmYzpmMDplOTo2NzpkNDowZDo2ZTo0NTpiZTo1NTplODoKKyAgICAgICAgOTM6ZDI6Y2U6MDM6M2Y6ZWQ6ZGE6MjU6YjA6MWQ6NTc6Y2I6MWU6M2E6NzY6YTA6NGM6ZWM6CisgICAgICAgIDUwOjc2OmU4OjY0OjcyOjBjOmE0OmE5OmYxOmI4OjhiOmQ2OmQ2Ojg3Ojg0OmJiOjMyOmU1OgorICAgICAgICA0MToxMTpjMDo3NzpkOTpiMzo2MDo5ZDplYjoxYjpkNTpkMTo2ZTo0NDo0NDphOTphNjowMToKKyAgICAgICAgZWM6NTU6NjI6MWQ6Nzc6Yjg6NWM6OGU6NDg6NDk6N2M6OWM6M2I6NTc6MTE6YWM6YWQ6NzM6CisgICAgICAgIDM3OjhlOjJmOjc4OjVjOjkwOjY4OjQ3OmQ5OjYwOjYwOmU2OmZjOjA3OjNkOjIyOjIwOjE3OgorICAgICAgICBjNDpmNzoxNjplOTpjNDpkODo3MjpmOTpjODo3Mzo3YzpkZjoxNjoyZjoxNTphOTozZTpmZDoKKyAgICAgICAgNmE6Mjc6YjY6YTE6ZWI6NWE6YmE6OTg6MWY6ZDU6ZTM6NGQ6NjQ6MGE6OWQ6MTM6Yzg6NjE6CisgICAgICAgIGJhOmY1OjM5OjFjOjg3OmJhOmI4OmJkOjdiOjIyOjdmOmY2OmZlOmFjOjQwOjc5OmU1OmFjOgorICAgICAgICAxMDo2ZjozZDo4ZjoxYjo3OTo3Njo4YjpjNDozNzpiMzoyMToxODo4NDplNTozNjowMDplYjoKKyAgICAgICAgNjM6MjA6OTk6Yjk6ZTk6ZmU6MzM6MDQ6YmI6NDE6Yzg6YzE6MDI6Zjk6NDQ6NjM6MjA6OWU6CisgICAgICAgIDgxOmNlOjQyOmQzOmQ2OjNmOjJjOjc2OmQzOjYzOjljOjU5OmRkOjhmOmE2OmUxOjBlOmEwOgorICAgICAgICAyZTo0MTpmNzoyZTo5NTo0NzpjZjpiYzpmZDozMzpmMzpmNjowYjo2MTo3ZTo3ZTo5MToyYjoKKyAgICAgICAgODE6NDc6YzI6Mjc6MzA6ZWU6YTc6MTA6NWQ6Mzc6OGY6NWM6Mzk6MmI6ZTQ6MDQ6ZjA6N2I6CisgICAgICAgIDhkOjU2OjhjOjY4CitTSEExIEZpbmdlcnByaW50PTkxOkM2OkQ2OkVFOjNFOjhBOkM4OjYzOjg0OkU1OjQ4OkMyOjk5OjI5OjVDOjc1OjZDOjgxOjdCOjgxCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMDNlMTZmNmMuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8wM2UxNmY2Yy4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRjZGYyNzQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMDNlMTZmNmMuMApAQCAtMCwwICsxLDc4IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUVFakNDQXZxZ0F3SUJBZ0lQQU1FQWl6dzhpQkhSUHZaajdOOUFNQTBHQ1NxR1NJYjNEUUVCQkFVQU1IQXgKK0t6QXBCZ05WQkFzVElrTnZjSGx5YVdkb2RDQW9ZeWtnTVRrNU55Qk5hV055YjNOdlpuUWdRMjl5Y0M0eEhqQWMKK0JnTlZCQXNURlUxcFkzSnZjMjltZENCRGIzSndiM0poZEdsdmJqRWhNQjhHQTFVRUF4TVlUV2xqY205emIyWjAKK0lGSnZiM1FnUVhWMGFHOXlhWFI1TUI0WERUazNNREV4TURBM01EQXdNRm9YRFRJd01USXpNVEEzTURBd01Gb3cKK2NERXJNQ2tHQTFVRUN4TWlRMjl3ZVhKcFoyaDBJQ2hqS1NBeE9UazNJRTFwWTNKdmMyOW1kQ0JEYjNKd0xqRWUKK01Cd0dBMVVFQ3hNVlRXbGpjbTl6YjJaMElFTnZjbkJ2Y21GMGFXOXVNU0V3SHdZRFZRUURFeGhOYVdOeWIzTnYKK1puUWdVbTl2ZENCQmRYUm9iM0pwZEhrd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUIKK0FRQ3BBcjNCY09ZNzhrNGJLSitYZUY0dzZxS3BqU1ZmK1A2VlRLTzMvcDJpSUQ1OFVhS2JvbzlnTW12UlFtUjUKKzdxeDJ5VlRhOHV1Y2hoeVBuNFJtczhWcmVtSWoxaDA4M2c4Qmt1aVd4TDh0WnBxYWFDYVowRG9zdnd5MVdDYkIKK1J1Y0tQamlXTEtrb09hanNTWU5DNDRRUHU1cHNWV0dzZ255aFlDMTNUT21adEdRN21sQWNNUWdrRkorcDU1RXIKK0dPWTltR01VWUZnRlpaOGROMUtIOTZmdmxBTEdHOU8vVlVXemlZQy9PdXhVbEU2dS9hZDZiWFJPcnhqTWxna28KK0lRQlhrR0JwTjd0TEVnYzhWdjliKzZSbUNnaW0wb0ZXVisrMk8xNFdnWGNFMnZhK3JvQ1YvckROZjlhbkduSmMKK1BNcTg4QWlqSWpDekJvWEpzeUIzRTRYZkFnTUJBQUdqZ2Fnd2dhVXdnYUlHQTFVZEFRU0JtakNCbDRBUVc5QncKKzcybHluaU5SZmhTeVRZNy95NkZ5TUhBeEt6QXBCZ05WQkFzVElrTnZjSGx5YVdkb2RDQW9ZeWtnTVRrNU55Qk4KK2FXTnliM052Wm5RZ1EyOXljQzR4SGpBY0JnTlZCQXNURlUxcFkzSnZjMjltZENCRGIzSndiM0poZEdsdmJqRWgKK01COEdBMVVFQXhNWVRXbGpjbTl6YjJaMElGSnZiM1FnUVhWMGFHOXlhWFI1Z2c4QXdRQ0xQRHlJRWRFKzltUHMKKzMwQXdEUVlKS29aSWh2Y05BUUVFQlFBRGdnRUJBSlhvQzhDTjg1Y1lOZTI0QVNUWWR4SHpYR0F5bjU0THl6NEYKK2tZaVB5VHJtSWZMd1Y1TXN0YUJIeUdMdi9OZk1PenRhcVRaVWFmNGtiVC9KektyZUJYemRNWTA5bnhCd2FydisKK0VrOFlhY0Q4MEVQakVWb2dUK3BpZTYrcUdjZ3JOeVV0dm1XaEVvb2xEMk9qOTFRYytTSEoxaFh6VXF4dVF6SUgKKy9ZSVgrT1ZuYkExUjlyM3hVc2U5NThRdy9DQXhDWWdkbFNrYVRkVWRBcVh4Z09BRHRGdjBzZDNJVis1bFNjZFMKK1ZMYTBBeWdTLzVEVzhBaVBmcmlYeGFzM0xPUjY1S2gzNDNhZ0FOQnFQOEhTTm9yZ1FSS29OV29iYXRzMTRkUWMKK0JPU29SUVRJV2pNNGJrMGNEV0szQ3FLTTA5VlVQMGJOSEZXbWNOc1NPb2VUZForbjBxQT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIGMxOjAwOjhiOjNjOjNjOjg4OjExOmQxOjNlOmY2OjYzOmVjOmRmOjQwCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IG1kNVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogT1U9Q29weXJpZ2h0IChjKSAxOTk3IE1pY3Jvc29mdCBDb3JwLiwgT1U9TWljcm9zb2Z0IENvcnBvcmF0aW9uLCBDTj1NaWNyb3NvZnQgUm9vdCBBdXRob3JpdHkKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEphbiAxMCAwNzowMDowMCAxOTk3IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogRGVjIDMxIDA3OjAwOjAwIDIwMjAgR01UCisgICAgICAgIFN1YmplY3Q6IE9VPUNvcHlyaWdodCAoYykgMTk5NyBNaWNyb3NvZnQgQ29ycC4sIE9VPU1pY3Jvc29mdCBDb3Jwb3JhdGlvbiwgQ049TWljcm9zb2Z0IFJvb3QgQXV0aG9yaXR5CisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDphOTowMjpiZDpjMTo3MDplNjozYjpmMjo0ZToxYjoyODo5Zjo5Nzo3ODoKKyAgICAgICAgICAgICAgICAgICAgNWU6MzA6ZWE6YTI6YTk6OGQ6MjU6NWY6Zjg6ZmU6OTU6NGM6YTM6Yjc6ZmU6CisgICAgICAgICAgICAgICAgICAgIDlkOmEyOjIwOjNlOjdjOjUxOmEyOjliOmEyOjhmOjYwOjMyOjZiOmQxOjQyOgorICAgICAgICAgICAgICAgICAgICA2NDo3OTplZTphYzo3NjpjOTo1NDpkYTpmMjplYjo5Yzo4NjoxYzo4Zjo5ZjoKKyAgICAgICAgICAgICAgICAgICAgODQ6NjY6YjM6YzU6NmI6N2E6NjI6MjM6ZDY6MWQ6M2M6ZGU6MGY6MDE6OTI6CisgICAgICAgICAgICAgICAgICAgIGU4Ojk2OmM0OmJmOjJkOjY2OjlhOjlhOjY4OjI2Ojk5OmQwOjNhOjJjOmJmOgorICAgICAgICAgICAgICAgICAgICAwYzpiNTo1ODoyNjpjMTo0NjplNzowYTozZTozODo5NjoyYzphOToyODozOToKKyAgICAgICAgICAgICAgICAgICAgYTg6ZWM6NDk6ODM6NDI6ZTM6ODQ6MGY6YmI6OWE6NmM6NTU6NjE6YWM6ODI6CisgICAgICAgICAgICAgICAgICAgIDdjOmExOjYwOjJkOjc3OjRjOmU5Ojk5OmI0OjY0OjNiOjlhOjUwOjFjOjMxOgorICAgICAgICAgICAgICAgICAgICAwODoyNDoxNDo5ZjphOTplNzo5MToyYjoxODplNjozZDo5ODo2MzoxNDo2MDoKKyAgICAgICAgICAgICAgICAgICAgNTg6MDU6NjU6OWY6MWQ6Mzc6NTI6ODc6Zjc6YTc6ZWY6OTQ6MDI6YzY6MWI6CisgICAgICAgICAgICAgICAgICAgIGQzOmJmOjU1OjQ1OmIzOjg5OjgwOmJmOjNhOmVjOjU0Ojk0OjRlOmFlOmZkOgorICAgICAgICAgICAgICAgICAgICBhNzo3YTo2ZDo3NDo0ZTphZjoxODpjYzo5NjowOToyODoyMTowMDo1Nzo5MDoKKyAgICAgICAgICAgICAgICAgICAgNjA6Njk6Mzc6YmI6NGI6MTI6MDc6M2M6NTY6ZmY6NWI6ZmI6YTQ6NjY6MGE6CisgICAgICAgICAgICAgICAgICAgIDA4OmE2OmQyOjgxOjU2OjU3OmVmOmI2OjNiOjVlOjE2OjgxOjc3OjA0OmRhOgorICAgICAgICAgICAgICAgICAgICBmNjpiZTphZTo4MDo5NTpmZTpiMDpjZDo3ZjpkNjphNzoxYTo3Mjo1YzozYzoKKyAgICAgICAgICAgICAgICAgICAgY2E6YmM6ZjA6MDg6YTM6MjI6MzA6YjM6MDY6ODU6Yzk6YjM6MjA6Nzc6MTM6CisgICAgICAgICAgICAgICAgICAgIDg1OmRmCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIDIuNS4yOS4xOiAKKyAgICAgICAgICAgICAgICAwLi4uLlsucC5pci4jUX4uLk0uLi4ucjBwMSswKS4uVS4uLiJDb3B5cmlnaHQgKGMpIDE5OTcgTWljcm9zb2Z0IENvcnAuMS4wLi4uVS4uLi5NaWNyb3NvZnQgQ29ycG9yYXRpb24xITAuLi5VLi4uLk1pY3Jvc29mdCBSb290IEF1dGhvcml0eS4uLi4uLjw8Li4uPi5jLi5ACisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogbWQ1V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgOTU6ZTg6MGI6YzA6OGQ6ZjM6OTc6MTg6MzU6ZWQ6Yjg6MDE6MjQ6ZDg6Nzc6MTE6ZjM6NWM6CisgICAgICAgIDYwOjMyOjlmOjllOjBiOmNiOjNlOjA1OjkxOjg4OjhmOmM5OjNhOmU2OjIxOmYyOmYwOjU3OgorICAgICAgICA5MzoyYzpiNTphMDo0NzpjODo2MjplZjpmYzpkNzpjYzozYjozYjo1YTphOTozNjo1NDo2OToKKyAgICAgICAgZmU6MjQ6NmQ6M2Y6Yzk6Y2M6YWE6ZGU6MDU6N2M6ZGQ6MzE6OGQ6M2Q6OWY6MTA6NzA6NmE6CisgICAgICAgIGJiOmZlOjEyOjRmOjE4OjY5OmMwOmZjOmQwOjQzOmUzOjExOjVhOjIwOjRmOmVhOjYyOjdiOgorICAgICAgICBhZjphYToxOTpjODoyYjozNzoyNToyZDpiZTo2NTphMToxMjo4YToyNTowZjo2MzphMzpmNzoKKyAgICAgICAgNTQ6MWM6Zjk6MjE6Yzk6ZDY6MTU6ZjM6NTI6YWM6NmU6NDM6MzI6MDc6ZmQ6ODI6MTc6Zjg6CisgICAgICAgIGU1OjY3OjZjOjBkOjUxOmY2OmJkOmYxOjUyOmM3OmJkOmU3OmM0OjMwOmZjOjIwOjMxOjA5OgorICAgICAgICA4ODoxZDo5NToyOToxYTo0ZDpkNToxZDowMjphNTpmMTo4MDplMDowMzpiNDo1YjpmNDpiMToKKyAgICAgICAgZGQ6Yzg6NTc6ZWU6NjU6NDk6Yzc6NTI6NTQ6YjY6YjQ6MDM6Mjg6MTI6ZmY6OTA6ZDY6ZjA6CisgICAgICAgIDA4OjhmOjdlOmI4Ojk3OmM1OmFiOjM3OjJjOmU0OjdhOmU0OmE4Ojc3OmUzOjc2OmEwOjAwOgorICAgICAgICBkMDo2YTozZjpjMTpkMjozNjo4YTplMDo0MToxMjphODozNTo2YToxYjo2YTpkYjozNTplMToKKyAgICAgICAgZDQ6MWM6MDQ6ZTQ6YTg6NDU6MDQ6Yzg6NWE6MzM6Mzg6NmU6NGQ6MWM6MGQ6NjI6Yjc6MGE6CisgICAgICAgIGEyOjhjOmQzOmQ1OjU0OjNmOjQ2OmNkOjFjOjU1OmE2OjcwOmRiOjEyOjNhOjg3OjkzOjc1OgorICAgICAgICA5ZjphNzpkMjphMAorU0hBMSBGaW5nZXJwcmludD1BNDozNDo4OToxNTo5QTo1MjowRjowRDo5MzpEMDozMjpDQzpBRjozNzpFNzpGRToyMDpBODpCNDoxOQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzA4YWVmN2JiLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMDhhZWY3YmIuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMTlkMzZkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzA4YWVmN2JiLjAKQEAgLTAsMCArMSw5MyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFdlRDQ0E2V2dBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUVVGQURDQmhURUxNQWtHQTFVRUJoTUNWVk14CitJREFlQmdOVkJBb01GMWRsYkd4eklFWmhjbWR2SUZkbGJHeHpVMlZqZFhKbE1Sd3dHZ1lEVlFRTERCTlhaV3hzCitjeUJHWVhKbmJ5QkNZVzVySUU1Qk1UWXdOQVlEVlFRRERDMVhaV3hzYzFObFkzVnlaU0JRZFdKc2FXTWdVbTl2CitkQ0JEWlhKMGFXWnBZMkYwWlNCQmRYUm9iM0pwZEhrd0hoY05NRGN4TWpFek1UY3dOelUwV2hjTk1qSXhNakUwCitNREF3TnpVMFdqQ0JoVEVMTUFrR0ExVUVCaE1DVlZNeElEQWVCZ05WQkFvTUYxZGxiR3h6SUVaaGNtZHZJRmRsCitiR3h6VTJWamRYSmxNUnd3R2dZRFZRUUxEQk5YWld4c2N5QkdZWEpuYnlCQ1lXNXJJRTVCTVRZd05BWURWUVFECitEQzFYWld4c2MxTmxZM1Z5WlNCUWRXSnNhV01nVW05dmRDQkRaWEowYVdacFkyRjBaU0JCZFhSb2IzSnBkSGt3CitnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFEdWI3UzllZUtQQ0NHZU9BUkJKZStyCitXeHhUa3F4dG50M0N4QzVGbEFNMWlHZDBWK1BmakxpbmRvODc5NmpFMnlsakRwRm9Ob3FYam9weGFBa0g1T2pVCitEay80MWl0TXBCYjU3ME9ZajdPZVV0OXRrVG1QT0wxM2kwTmo2N2VUL0RCTUhBR1R0aFA3OTZFZnZ5WGhkRGNzCitIcVJlUEdqNFM3OE51UjR1TnVpcDVLZjREOHVDZFh3MUxTTFd3cjhMODdUOGJKVmhIbGZYQklFeWcxSjU1b05qCit6N2ZMWTRzUjRyMWU2L2FON1pWeUtMU3NFbUxwU2pQbWd6S3VCWFdWdllTVjJ5cGNtNDR1RExpQkswSG1PRmFmCitTWnRzZHZxS1hmY0JlWUY4d1lOQUJmNXgvUXcvekU1Z0NRNWxSeEF2QWNBRlA0LzRzMEh2V2tKK1dlL1Nsd3hsCitBZ01CQUFHamdnRTBNSUlCTURBUEJnTlZIUk1CQWY4RUJUQURBUUgvTURrR0ExVWRId1F5TURBd0xxQXNvQ3FHCitLR2gwZEhBNkx5OWpjbXd1Y0d0cExuZGxiR3h6Wm1GeVoyOHVZMjl0TDNkemNISmpZUzVqY213d0RnWURWUjBQCitBUUgvQkFRREFnSEdNQjBHQTFVZERnUVdCQlFtbFJrUTJlaWhsNUgvM0JuWnRRUSswbk1LYWpDQnNnWURWUjBqCitCSUdxTUlHbmdCUW1sUmtRMmVpaGw1SC8zQm5adFFRKzBuTUthcUdCaTZTQmlEQ0JoVEVMTUFrR0ExVUVCaE1DCitWVk14SURBZUJnTlZCQW9NRjFkbGJHeHpJRVpoY21kdklGZGxiR3h6VTJWamRYSmxNUnd3R2dZRFZRUUxEQk5YCitaV3hzY3lCR1lYSm5ieUJDWVc1cklFNUJNVFl3TkFZRFZRUUREQzFYWld4c2MxTmxZM1Z5WlNCUWRXSnNhV01nCitVbTl2ZENCRFpYSjBhV1pwWTJGMFpTQkJkWFJvYjNKcGRIbUNBUUV3RFFZSktvWklodmNOQVFFRkJRQURnZ0VCCitBTGtWc1VTUnpDUElLMDEzNC9pYWV5Y056WEs3bVFES2ZHWVpVTWJWbU8ycnZ3TmE1VTNsSHNoUGNaZUcxZU1kCisvWkRKUEhWM1YzcDkrTjcwMU5YM2xlWjBiaDA4cm55ZDJ3SURCU3h4U3lVK0IrTmVtdlZtRnltSUdqaWZ6NnBCCitBNFNYYTVNNGVzb3dSQnNrUkRQUTVOSGNLRGowRTBNMU5TbGpxSHlpdGEwNHBPMnQvY2FhSC8rWGMvNzdzelduCitrNGJHZHBFQTVxeFJGc1FuTWx6YmM5cWxrMWVPUG0wMUpnaFoxZWRFMTNZZ1krZXNFMmZEYmJGd1JuelZsaEU5CitpVzlkcUtIcmpRcmF3eDB6YktQcVp4bWFtWDlMUFlOUktoM0tMNFlNb240UUxTdlVGcFVMQjZvdUZKSkp0eWx2CisyRzB4ZmZYOG9SQUhoODR2V2R3K1dOcz0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMSAoMHgxKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPVdlbGxzIEZhcmdvIFdlbGxzU2VjdXJlLCBPVT1XZWxscyBGYXJnbyBCYW5rIE5BLCBDTj1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IERlYyAxMyAxNzowNzo1NCAyMDA3IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogRGVjIDE0IDAwOjA3OjU0IDIwMjIgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89V2VsbHMgRmFyZ28gV2VsbHNTZWN1cmUsIE9VPVdlbGxzIEZhcmdvIEJhbmsgTkEsIENOPVdlbGxzU2VjdXJlIFB1YmxpYyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6ZWU6NmY6YjQ6YmQ6Nzk6ZTI6OGY6MDg6MjE6OWU6Mzg6MDQ6NDE6MjU6CisgICAgICAgICAgICAgICAgICAgIGVmOmFiOjViOjFjOjUzOjkyOmFjOjZkOjllOmRkOmMyOmM0OjJlOjQ1Ojk0OgorICAgICAgICAgICAgICAgICAgICAwMzozNTo4ODo2Nzo3NDo1NzplMzpkZjo4YzpiODphNzo3Njo4ZjozYjpmNzoKKyAgICAgICAgICAgICAgICAgICAgYTg6YzQ6ZGI6Mjk6NjM6MGU6OTE6Njg6MzY6OGE6OTc6OGU6OGE6NzE6Njg6CisgICAgICAgICAgICAgICAgICAgIDA5OjA3OmU0OmU4OmQ0OjBlOjRmOmY4OmQ2OjJiOjRjOmE0OjE2OmY5OmVmOgorICAgICAgICAgICAgICAgICAgICA0Mzo5ODo4ZjpiMzo5ZTo1MjpkZjo2ZDo5MTozOTo4ZjozODpiZDo3Nzo4YjoKKyAgICAgICAgICAgICAgICAgICAgNDM6NjM6ZWI6Yjc6OTM6ZmM6MzA6NGM6MWM6MDE6OTM6YjY6MTM6ZmI6Zjc6CisgICAgICAgICAgICAgICAgICAgIGExOjFmOmJmOjI1OmUxOjc0OjM3OjJjOjFlOmE0OjVlOjNjOjY4OmY4OjRiOgorICAgICAgICAgICAgICAgICAgICBiZjowZDpiOToxZToyZTozNjplODphOTplNDphNzpmODowZjpjYjo4Mjo3NToKKyAgICAgICAgICAgICAgICAgICAgN2M6MzU6MmQ6MjI6ZDY6YzI6YmY6MGI6ZjM6YjQ6ZmM6NmM6OTU6NjE6MWU6CisgICAgICAgICAgICAgICAgICAgIDU3OmQ3OjA0OjgxOjMyOjgzOjUyOjc5OmU2OjgzOjYzOmNmOmI3OmNiOjYzOgorICAgICAgICAgICAgICAgICAgICA4YjoxMTplMjpiZDo1ZTplYjpmNjo4ZDplZDo5NTo3MjoyODpiNDphYzoxMjoKKyAgICAgICAgICAgICAgICAgICAgNjI6ZTk6NGE6MzM6ZTY6ODM6MzI6YWU6MDU6NzU6OTU6YmQ6ODQ6OTU6ZGI6CisgICAgICAgICAgICAgICAgICAgIDJhOjVjOjliOjhlOjJlOjBjOmI4OjgxOjJiOjQxOmU2OjM4OjU2OjlmOjQ5OgorICAgICAgICAgICAgICAgICAgICA5Yjo2Yzo3NjpmYTo4YTo1ZDpmNzowMTo3OTo4MTo3YzpjMTo4Mzo0MDowNToKKyAgICAgICAgICAgICAgICAgICAgZmU6NzE6ZmQ6MGM6M2Y6Y2M6NGU6NjA6MDk6MGU6NjU6NDc6MTA6MmY6MDE6CisgICAgICAgICAgICAgICAgICAgIGMwOjA1OjNmOjhmOmY4OmIzOjQxOmVmOjVhOjQyOjdlOjU5OmVmOmQyOjk3OgorICAgICAgICAgICAgICAgICAgICAwYzo2NQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIENSTCBEaXN0cmlidXRpb24gUG9pbnRzOiAKKyAgICAgICAgICAgICAgICBVUkk6aHR0cDovL2NybC5wa2kud2VsbHNmYXJnby5jb20vd3NwcmNhLmNybAorCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIERpZ2l0YWwgU2lnbmF0dXJlLCBOb24gUmVwdWRpYXRpb24sIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgMjY6OTU6MTk6MTA6RDk6RTg6QTE6OTc6OTE6RkY6REM6MTk6RDk6QjU6MDQ6M0U6RDI6NzM6MEE6NkEKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOjI2Ojk1OjE5OjEwOkQ5OkU4OkExOjk3OjkxOkZGOkRDOjE5OkQ5OkI1OjA0OjNFOkQyOjczOjBBOjZBCisgICAgICAgICAgICAgICAgRGlyTmFtZTovQz1VUy9PPVdlbGxzIEZhcmdvIFdlbGxzU2VjdXJlL09VPVdlbGxzIEZhcmdvIEJhbmsgTkEvQ049V2VsbHNTZWN1cmUgUHVibGljIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5CisgICAgICAgICAgICAgICAgc2VyaWFsOjAxCisKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgYjk6MTU6YjE6NDQ6OTE6Y2M6MjM6Yzg6MmI6NGQ6Nzc6ZTM6Zjg6OWE6N2I6Mjc6MGQ6Y2Q6CisgICAgICAgIDcyOmJiOjk5OjAwOmNhOjdjOjY2OjE5OjUwOmM2OmQ1Ojk4OmVkOmFiOmJmOjAzOjVhOmU1OgorICAgICAgICA0ZDplNToxZTpjODo0Zjo3MTo5Nzo4NjpkNTplMzoxZDpmZDo5MDpjOTozYzo3NTo3Nzo1NzoKKyAgICAgICAgN2E6N2Q6Zjg6ZGU6ZjQ6ZDQ6ZDU6Zjc6OTU6ZTY6NzQ6NmU6MWQ6M2M6YWU6N2M6OWQ6ZGI6CisgICAgICAgIDAyOjAzOjA1OjJjOjcxOjRiOjI1OjNlOjA3OmUzOjVlOjlhOmY1OjY2OjE3OjI5Ojg4OjFhOgorICAgICAgICAzODo5ZjpjZjphYTo0MTowMzo4NDo5Nzo2Yjo5MzozODo3YTpjYTozMDo0NDoxYjoyNDo0NDoKKyAgICAgICAgMzM6ZDA6ZTQ6ZDE6ZGM6Mjg6Mzg6ZjQ6MTM6NDM6MzU6MzU6Mjk6NjM6YTg6N2M6YTI6YjU6CisgICAgICAgIGFkOjM4OmE0OmVkOmFkOmZkOmM2OjlhOjFmOmZmOjk3OjczOmZlOmZiOmIzOjM1OmE3OjkzOgorICAgICAgICA4NjpjNjo3Njo5MTowMDplNjphYzo1MToxNjpjNDoyNzozMjo1YzpkYjo3MzpkYTphNTo5MzoKKyAgICAgICAgNTc6OGU6M2U6NmQ6MzU6MjY6MDg6NTk6ZDU6ZTc6NDQ6ZDc6NzY6MjA6NjM6ZTc6YWM6MTM6CisgICAgICAgIDY3OmMzOjZkOmIxOjcwOjQ2OjdjOmQ1Ojk2OjExOjNkOjg5OjZmOjVkOmE4OmExOmViOjhkOgorICAgICAgICAwYTpkYTpjMzoxZDozMzo2YzphMzplYTo2NzoxOTo5YTo5OTo3Zjo0YjozZDo4Mzo1MToyYToKKyAgICAgICAgMWQ6Y2E6MmY6ODY6MGM6YTI6N2U6MTA6MmQ6MmI6ZDQ6MTY6OTU6MGI6MDc6YWE6MmU6MTQ6CisgICAgICAgIDkyOjQ5OmI3OjI5OjZmOmQ4OjZkOjMxOjdkOmY1OmZjOmExOjEwOjA3Ojg3OmNlOjJmOjU5OgorICAgICAgICBkYzozZTo1ODpkYgorU0hBMSBGaW5nZXJwcmludD1FNzpCNDpGNjo5RDo2MTpFQzo5MDo2OTpEQjo3RTo5MDpBNzo0MDoxQTozQzpGNDo3RDo0RjpFODpFRQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzBkMTg4ZDg5LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMGQxODhkODkuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMGFiOGJlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzBkMTg4ZDg5LjAKQEAgLTAsMCArMSw4MCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEdGpDQ0FwNmdBd0lCQWdJUVJKbU5QTUFESjcyY2RwVzU2dHVzdFRBTkJna3Foa2lHOXcwQkFRVUZBREIxCitNUXN3Q1FZRFZRUUdFd0pVVWpFb01DWUdBMVVFQ2hNZlJXeGxhM1J5YjI1cGF5QkNhV3huYVNCSGRYWmxibXhwCitaMmtnUVM1VExqRThNRG9HQTFVRUF4TXpaUzFIZFhabGJpQkxiMnNnUld4bGEzUnliMjVwYXlCVFpYSjBhV1pwCithMkVnU0dsNmJXVjBJRk5oWjJ4aGVXbGphWE5wTUI0WERUQTNNREV3TkRFeE16STBPRm9YRFRFM01ERXdOREV4CitNekkwT0Zvd2RURUxNQWtHQTFVRUJoTUNWRkl4S0RBbUJnTlZCQW9USDBWc1pXdDBjbTl1YVdzZ1FtbHNaMmtnCitSM1YyWlc1c2FXZHBJRUV1VXk0eFBEQTZCZ05WQkFNVE0yVXRSM1YyWlc0Z1MyOXJJRVZzWld0MGNtOXVhV3NnCitVMlZ5ZEdsbWFXdGhJRWhwZW0xbGRDQlRZV2RzWVhscFkybHphVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECitnZ0VQQURDQ0FRb0NnZ0VCQU1NU0lKNndYZ0JsalU1R3U0QmM2U3dHbDlYemNzbHd1ZWRMWllEQlM3NStQTmRVCitNWlRlMVJLNlV4WUM2bGhqNzF2WTgrMHFHcXB4U0tQY0VDMWZYK3RjUzV5V0NFSWxLQkhNaWxwaUFWRFY2d2xUCitML2pEai82ei9QMmRvdU5mZmI3dEMrQmc2Mm5zTSszWWpmc1NTWU1BeVl1WGpEdHpLakt6RXZlNVRmTDBUVzNICis1dFltTndqeTJmMXJYS1BsU0Z4WXZFSytBMXFCdWh3MURBRFQ5U04rY1RBSUpqamNKUkZITGZPNkl4Q2x2N3dDCis5ME5leC82d04xQ1pldytUenVaRExNTitEZkljUTJaZ3kyRXhSNGVqVDY2OVZteE12THo0QmNwazlPazBvU3kxCitjK0hDUHVqSXlUUWxDRnp6N2FiSGxKK3RpRU1sMStFNVlQNnNPVmtDQXdFQUFhTkNNRUF3RGdZRFZSMFBBUUgvCitCQVFEQWdFR01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZKL3VSTE9VMWZxUlR5N1pWWm9FCitWdHN0eE51bE1BMEdDU3FHU0liM0RRRUJCUVVBQTRJQkFRQi9YN2xUVzJNOWRUTG4rc1IwR3N0RzMwWnBIRkxQCitxay9DYU92L2dLbFI2RDFpZDRrOUNuVTU4VzVkRjRkdmFBWEJsR3paWGQvYXNsbkxwUkNLeXN3NXpaL3JUdDVTCisvd3p3OUpLcDhteFRxNXZTUjZBZmRQZWJtdkV2Rlo5NlpEQVlCendxRDJmSy9BK0pZWjFscFR6bHZCTmJDTnZqCisvKzI3QnJ0cUJyRjZUMlhHZ3YwZW5JdTFEZTVJdTdpOXFnaTArNk44eTUvTmtIWmNocFo0VndwbStWZ2FuZjJYCitLV0RlRWFhUUhCa2M3Z0dXSWpRMExwSDV0OFFuMFh2bXYvdUFSRm9XNWV2ZzFBbzR2T1NSNDlYclhNR3MzeHRxCitmSjdsZGRLMmw0ZmJ6SWNyUXpxRUNLK3JQTnYzUEdZeGhyQ2RVM250K0NQZVF1TXRndkVQNWZxWAorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgNDQ6OTk6OGQ6M2M6YzA6MDM6Mjc6YmQ6OWM6NzY6OTU6Yjk6ZWE6ZGI6YWM6YjUKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1UUiwgTz1FbGVrdHJvbmlrIEJpbGdpIEd1dmVubGlnaSBBLlMuLCBDTj1lLUd1dmVuIEtvayBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2FnbGF5aWNpc2kKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEphbiAgNCAxMTozMjo0OCAyMDA3IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogSmFuICA0IDExOjMyOjQ4IDIwMTcgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VFIsIE89RWxla3Ryb25payBCaWxnaSBHdXZlbmxpZ2kgQS5TLiwgQ049ZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhZ2xheWljaXNpCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpjMzoxMjoyMDo5ZTpiMDo1ZTowMDo2NTo4ZDo0ZTo0NjpiYjo4MDo1YzoKKyAgICAgICAgICAgICAgICAgICAgZTk6MmM6MDY6OTc6ZDU6ZjM6NzI6Yzk6NzA6Yjk6ZTc6NGI6NjU6ODA6YzE6CisgICAgICAgICAgICAgICAgICAgIDRiOmJlOjdlOjNjOmQ3OjU0OjMxOjk0OmRlOmQ1OjEyOmJhOjUzOjE2OjAyOgorICAgICAgICAgICAgICAgICAgICBlYTo1ODo2MzplZjo1YjpkODpmMzplZDoyYToxYTphYTo3MTo0ODphMzpkYzoKKyAgICAgICAgICAgICAgICAgICAgMTA6MmQ6NWY6NWY6ZWI6NWM6NGI6OWM6OTY6MDg6NDI6MjU6Mjg6MTE6Y2M6CisgICAgICAgICAgICAgICAgICAgIDhhOjVhOjYyOjAxOjUwOmQ1OmViOjA5OjUzOjJmOmY4OmMzOjhmOmZlOmIzOgorICAgICAgICAgICAgICAgICAgICBmYzpmZDo5ZDphMjplMzo1Zjo3ZDpiZTplZDowYjplMDo2MDplYjo2OTplYzoKKyAgICAgICAgICAgICAgICAgICAgMzM6ZWQ6ZDg6OGQ6ZmI6MTI6NDk6ODM6MDA6Yzk6OGI6OTc6OGM6M2I6NzM6CisgICAgICAgICAgICAgICAgICAgIDJhOjMyOmIzOjEyOmY3OmI5OjRkOmYyOmY0OjRkOjZkOmM3OmU2OmQ2OjI2OgorICAgICAgICAgICAgICAgICAgICAzNzowODpmMjpkOTpmZDo2Yjo1YzphMzplNTo0ODo1Yzo1ODpiYzo0MjpiZToKKyAgICAgICAgICAgICAgICAgICAgMDM6NWE6ODE6YmE6MWM6MzU6MGM6MDA6ZDM6ZjU6MjM6N2U6NzE6MzA6MDg6CisgICAgICAgICAgICAgICAgICAgIDI2OjM4OmRjOjI1OjExOjQ3OjJkOmYzOmJhOjIzOjEwOmE1OmJmOmJjOjAyOgorICAgICAgICAgICAgICAgICAgICBmNzo0Mzo1ZTpjNzpmZTpiMDozNzo1MDo5OTo3YjowZjo5MzpjZTplNjo0MzoKKyAgICAgICAgICAgICAgICAgICAgMmM6YzM6N2U6MGQ6ZjI6MWM6NDM6NjY6NjA6Y2I6NjE6MzE6NDc6ODc6YTM6CisgICAgICAgICAgICAgICAgICAgIDRmOmFlOmJkOjU2OjZjOjRjOmJjOmJjOmY4OjA1OmNhOjY0OmY0OmU5OjM0OgorICAgICAgICAgICAgICAgICAgICBhMToyYzpiNTo3MzplMTpjMjozZTplODpjODpjOTozNDoyNTowODo1YzpmMzoKKyAgICAgICAgICAgICAgICAgICAgZWQ6YTY6Yzc6OTQ6OWY6YWQ6ODg6NDM6MjU6ZDc6ZTE6Mzk6NjA6ZmU6YWM6CisgICAgICAgICAgICAgICAgICAgIDM5OjU5CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgOUY6RUU6NDQ6QjM6OTQ6RDU6RkE6OTE6NEY6MkU6RDk6NTU6OUE6MDQ6NTY6REI6MkQ6QzQ6REI6QTUKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgN2Y6NWY6Yjk6NTM6NWI6NjM6M2Q6NzU6MzI6ZTc6ZmE6YzQ6NzQ6MWE6Y2I6NDY6ZGY6NDY6CisgICAgICAgIDY5OjFjOjUyOmNmOmFhOjRmOmMyOjY4OmViOmZmOjgwOmE5OjUxOmU4OjNkOjYyOjc3Ojg5OgorICAgICAgICAzZDowYTo3NTozOTpmMTo2ZTo1ZDoxNzo4Nzo2Zjo2ODowNTpjMTo5NDo2YzpkOTo1ZDpkZjoKKyAgICAgICAgZGE6YjI6NTk6Y2I6YTU6MTA6OGE6Y2E6Y2M6Mzk6Y2Q6OWY6ZWI6NGU6ZGU6NTI6ZmY6MGM6CisgICAgICAgIGYwOmY0OjkyOmE5OmYyOjZjOjUzOmFiOjliOmQyOjQ3OmEwOjFmOjc0OmY3OjliOjlhOmYxOgorICAgICAgICAyZjoxNTo5Zjo3YTo2NDozMDoxODowNzozYzoyYTowZjo2NzpjYTpmYzowZjo4OTo2MTo5ZDoKKyAgICAgICAgNjU6YTU6M2M6ZTU6YmM6MTM6NWI6MDg6ZGI6ZTM6ZmY6ZWQ6YmI6MDY6YmI6NmE6MDY6YjE6CisgICAgICAgIDdhOjRmOjY1OmM2OjgyOmZkOjFlOjljOjhiOmI1OjBkOmVlOjQ4OmJiOmI4OmJkOmFhOjA4OgorICAgICAgICBiNDpmYjphMzo3YzpjYjo5ZjpjZDo5MDo3Njo1Yzo4Njo5Njo3ODo1NzowYTo2NjpmOTo1ODoKKyAgICAgICAgMWE6OWQ6ZmQ6OTc6Mjk6NjA6ZGU6MTE6YTY6OTA6MWM6MTk6MWM6ZWU6MDE6OTY6MjI6MzQ6CisgICAgICAgIDM0OjJlOjkxOmY5OmI3OmM0OjI3OmQxOjdiOmU2OmJmOmZiOjgwOjQ0OjVhOjE2OmU1OmViOgorICAgICAgICBlMDpkNDowYTozODpiYzplNDo5MTplMzpkNTplYjo1YzpjMTphYzpkZjoxYjo2YTo3Yzo5ZToKKyAgICAgICAgZTU6NzU6ZDI6YjY6OTc6ODc6ZGI6Y2M6ODc6MmI6NDM6M2E6ODQ6MDg6YWY6YWI6M2M6ZGI6CisgICAgICAgIGY3OjNjOjY2OjMxOjg2OmIwOjlkOjUzOjc5OmVkOmY4OjIzOmRlOjQyOmUzOjJkOjgyOmYxOgorICAgICAgICAwZjplNTpmYTo5NworU0hBMSBGaW5nZXJwcmludD1ERDpFMTpEMjpBOTowMTo4MDoyRToxRDo4Nzo1RTo4NDpCMzo4MDo3RTo0QjpCMTpGRDo5OTo0MTozNApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzEwNTMxMzUyLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMTA1MzEzNTIuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40OTcxZDAwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzEwNTMxMzUyLjAKQEAgLTAsMCArMSw4MSBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEN3pDQ0F0ZWdBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUXNGQURDQm1ERUxNQWtHQTFVRUJoTUNWVk14CitFREFPQmdOVkJBZ1RCMEZ5YVhwdmJtRXhFekFSQmdOVkJBY1RDbE5qYjNSMGMyUmhiR1V4SlRBakJnTlZCQW9UCitIRk4wWVhKbWFXVnNaQ0JVWldOb2JtOXNiMmRwWlhNc0lFbHVZeTR4T3pBNUJnTlZCQU1UTWxOMFlYSm1hV1ZzCitaQ0JUWlhKMmFXTmxjeUJTYjI5MElFTmxjblJwWm1sallYUmxJRUYxZEdodmNtbDBlU0F0SUVjeU1CNFhEVEE1CitNRGt3TVRBd01EQXdNRm9YRFRNM01USXpNVEl6TlRrMU9Wb3dnWmd4Q3pBSkJnTlZCQVlUQWxWVE1SQXdEZ1lECitWUVFJRXdkQmNtbDZiMjVoTVJNd0VRWURWUVFIRXdwVFkyOTBkSE5rWVd4bE1TVXdJd1lEVlFRS0V4eFRkR0Z5CitabWxsYkdRZ1ZHVmphRzV2Ykc5bmFXVnpMQ0JKYm1NdU1Uc3dPUVlEVlFRREV6SlRkR0Z5Wm1sbGJHUWdVMlZ5CitkbWxqWlhNZ1VtOXZkQ0JEWlhKMGFXWnBZMkYwWlNCQmRYUm9iM0pwZEhrZ0xTQkhNakNDQVNJd0RRWUpLb1pJCitodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU5VTU9zUXErVTdpOWI0WmwxK09pRk94SHovTHo1OGdFMjBwCitPc2dQZlR6M2EzWTRZOWsyWUtpYlhsd0FnTEl2V1gvMmgva2xRNGJuYVJ0U21wRGhjZVBZTFExT2IvYklTZG0yCis4eHBXcml1MmRCVHJ6L3NtNHhxNkhaWXVhanRZbElsSFZ2OGxvSk53VTRQYWhIUVV3MmVlQkdnNjM0NUFXaDFLCitUczlEa1R2blZ0WUFjTXRTN250OXJqcm52REg1UmZiQ1lNOFRXUUlyZ013MFI5KzUzcEJsYlFMUExKR21wdWZlCitoUmhKZkdaT296cHRxYlh1TkM2NkRRTzRNOTlINjdGcmpTWFptODZCMFVWR01wWndoOTRDRGtsRGhiWnNjN3RrCis2bUZCck1uVVZOK0hMOGNpc2liTW4xbFVhSi84dmlvdnhGVWNkVUJnRjRVQ1ZUbUxmd1VDQXdFQUFhTkNNRUF3CitEd1lEVlIwVEFRSC9CQVV3QXdFQi96QU9CZ05WSFE4QkFmOEVCQU1DQVFZd0hRWURWUjBPQkJZRUZKeGZBTitxCitBZGN3S3ppSW9yaHRTcHp5RVpHRE1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQkxOcWFFZDJuZE94bWZaeU1JCitidzVoeWYyRTNGL1lOb0hOMkJ0QkxaOWczY2NhYU5uUmJvYmhpQ1BQRTk1RHorSTBzd1NkSHluVnYvaGV5TlhCCit2ZTZTYnpKMDhwR0NMNzJDUW5xdEtyY2dmVTI4ZWxVU3doWHF2ZmRxbFM1c2RKL1BITFR5eFFHamhkQnlQcTF6Citxd3ViZFF4dFJiZU9sS3lXTjdXZzBJOFZSdzdqNklQZGovM3ZRUUYzekNlcFlvVXo4amNJNzNIUGR3YmV5QmtkCitpRURQZlVZZC94N0g0YzcvSTl2RytvMVZUcWtDNTBjUlJqNzAvYjE3S1NhN3FXRmlOeWkyTFNyMkVJWmt5WENuCiswcTIzS1hCNTZqemFZeVdmL1dpM01PeHcrM1dLdDIxZ1o3SWV5TG5wMktodkFvdG5EVTBtVjNIYUlQekJTbENOCitzU2k2CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDAgKDB4MCkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBTVD1Bcml6b25hLCBMPVNjb3R0c2RhbGUsIE89U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLiwgQ049U3RhcmZpZWxkIFNlcnZpY2VzIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IFNlcCAgMSAwMDowMDowMCAyMDA5IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogRGVjIDMxIDIzOjU5OjU5IDIwMzcgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIFNUPUFyaXpvbmEsIEw9U2NvdHRzZGFsZSwgTz1TdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuLCBDTj1TdGFyZmllbGQgU2VydmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMgorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6ZDU6MGM6M2E6YzQ6MmE6Zjk6NGU6ZTI6ZjU6YmU6MTk6OTc6NWY6OGU6CisgICAgICAgICAgICAgICAgICAgIDg4OjUzOmIxOjFmOjNmOmNiOmNmOjlmOjIwOjEzOjZkOjI5OjNhOmM4OjBmOgorICAgICAgICAgICAgICAgICAgICA3ZDozYzpmNzo2Yjo3NjozODo2MzpkOTozNjo2MDphODo5Yjo1ZTo1YzowMDoKKyAgICAgICAgICAgICAgICAgICAgODA6YjI6MmY6NTk6N2Y6ZjY6ODc6Zjk6MjU6NDM6ODY6ZTc6Njk6MWI6NTI6CisgICAgICAgICAgICAgICAgICAgIDlhOjkwOmUxOjcxOmUzOmQ4OjJkOjBkOjRlOjZmOmY2OmM4OjQ5OmQ5OmI2OgorICAgICAgICAgICAgICAgICAgICBmMzoxYTo1NjphZToyYjpiNjo3NDoxNDplYjpjZjpmYjoyNjplMzoxYTpiYToKKyAgICAgICAgICAgICAgICAgICAgMWQ6OTY6MmU6NmE6M2I6NTg6OTQ6ODk6NDc6NTY6ZmY6MjU6YTA6OTM6NzA6CisgICAgICAgICAgICAgICAgICAgIDUzOjgzOmRhOjg0Ojc0OjE0OmMzOjY3OjllOjA0OjY4OjNhOmRmOjhlOjQwOgorICAgICAgICAgICAgICAgICAgICA1YToxZDo0YTo0ZTpjZjo0Mzo5MTozYjplNzo1NjpkNjowMDo3MDpjYjo1MjoKKyAgICAgICAgICAgICAgICAgICAgZWU6N2I6N2Q6YWU6M2E6ZTc6YmM6MzE6Zjk6NDU6ZjY6YzI6NjA6Y2Y6MTM6CisgICAgICAgICAgICAgICAgICAgIDU5OjAyOjJiOjgwOmNjOjM0OjQ3OmRmOmI5OmRlOjkwOjY1OjZkOjAyOmNmOgorICAgICAgICAgICAgICAgICAgICAyYzo5MTphNjphNjplNzpkZTo4NToxODo0OTo3Yzo2Njo0ZTphMzozYTo2ZDoKKyAgICAgICAgICAgICAgICAgICAgYTk6YjU6ZWU6MzQ6MmU6YmE6MGQ6MDM6Yjg6MzM6ZGY6NDc6ZWI6YjE6NmI6CisgICAgICAgICAgICAgICAgICAgIDhkOjI1OmQ5OjliOmNlOjgxOmQxOjQ1OjQ2OjMyOjk2OjcwOjg3OmRlOjAyOgorICAgICAgICAgICAgICAgICAgICAwZTo0OTo0Mzo4NTpiNjo2Yzo3MzpiYjo2NDplYTo2MTo0MTphYzpjOTpkNDoKKyAgICAgICAgICAgICAgICAgICAgNTQ6ZGY6ODc6MmY6Yzc6MjI6YjI6MjY6Y2M6OWY6NTk6NTQ6Njg6OWY6ZmM6CisgICAgICAgICAgICAgICAgICAgIGJlOjJhOjJmOmM0OjU1OjFjOjc1OjQwOjYwOjE3Ojg1OjAyOjU1OjM5OjhiOgorICAgICAgICAgICAgICAgICAgICA3ZjowNQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDlDOjVGOjAwOkRGOkFBOjAxOkQ3OjMwOjJCOjM4Ojg4OkEyOkI4OjZEOjRBOjlDOkYyOjExOjkxOjgzCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgNGI6MzY6YTY6ODQ6Nzc6Njk6ZGQ6M2I6MTk6OWY6Njc6MjM6MDg6NmY6MGU6NjE6Yzk6ZmQ6CisgICAgICAgIDg0OmRjOjVmOmQ4OjM2OjgxOmNkOmQ4OjFiOjQxOjJkOjlmOjYwOmRkOmM3OjFhOjY4OmQ5OgorICAgICAgICBkMTo2ZTo4NjplMTo4ODoyMzpjZjoxMzpkZTo0MzpjZjplMjozNDpiMzowNDo5ZDoxZjoyOToKKyAgICAgICAgZDU6YmY6Zjg6NWU6Yzg6ZDU6YzE6YmQ6ZWU6OTI6NmY6MzI6NzQ6ZjI6OTE6ODI6MmY6YmQ6CisgICAgICAgIDgyOjQyOjdhOmFkOjJhOmI3OjIwOjdkOjRkOmJjOjdhOjU1OjEyOmMyOjE1OmVhOmJkOmY3OgorICAgICAgICA2YTo5NToyZTo2Yzo3NDo5ZjpjZjoxYzpiNDpmMjpjNTowMTphMzo4NTpkMDo3MjozZTphZDoKKyAgICAgICAgNzM6YWI6MGI6OWI6NzU6MGM6NmQ6NDU6Yjc6OGU6OTQ6YWM6OTY6Mzc6YjU6YTA6ZDA6OGY6CisgICAgICAgIDE1OjQ3OjBlOmUzOmU4OjgzOmRkOjhmOmZkOmVmOjQxOjAxOjc3OmNjOjI3OmE5OjYyOjg1OgorICAgICAgICAzMzpmMjozNzowODplZjo3MTpjZjo3NzowNjpkZTpjODoxOToxZDo4ODo0MDpjZjo3ZDo0NjoKKyAgICAgICAgMWQ6ZmY6MWU6Yzc6ZTE6Y2U6ZmY6MjM6ZGI6YzY6ZmE6OGQ6NTU6NGU6YTk6MDI6ZTc6NDc6CisgICAgICAgIDExOjQ2OjNlOmY0OmZkOmJkOjdiOjI5OjI2OmJiOmE5OjYxOjYyOjM3OjI4OmI2OjJkOjJhOgorICAgICAgICBmNjoxMDo4Njo2NDpjOTo3MDphNzpkMjphZDpiNzoyOTo3MDo3OTplYTozYzpkYTo2MzoyNToKKyAgICAgICAgOWY6ZmQ6Njg6Yjc6MzA6ZWM6NzA6ZmI6NzU6OGE6Yjc6NmQ6NjA6Njc6YjI6MWU6Yzg6Yjk6CisgICAgICAgIGU5OmQ4OmE4OjZmOjAyOjhiOjY3OjBkOjRkOjI2OjU3OjcxOmRhOjIwOmZjOmMxOjRhOjUwOgorICAgICAgICA4ZDpiMToyODpiYQorU0hBMSBGaW5nZXJwcmludD05Mjo1QTo4Rjo4RDoyQzo2RDowNDpFMDo2Njo1Rjo1OTo2QTpGRjoyMjpEODo2MzpFODoyNTo2RjozRgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzExMWU2MjczLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMTExZTYyNzMuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZGI4ZDc3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzExMWU2MjczLjAKQEAgLTAsMCArMSw4NiBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEdWpDQ0FxS2dBd0lCQWdJTEJBQUFBQUFCRDRZbTVnMHdEUVlKS29aSWh2Y05BUUVGQlFBd1RERWdNQjRHCitBMVVFQ3hNWFIyeHZZbUZzVTJsbmJpQlNiMjkwSUVOQklDMGdVakl4RXpBUkJnTlZCQW9UQ2tkc2IySmhiRk5wCitaMjR4RXpBUkJnTlZCQU1UQ2tkc2IySmhiRk5wWjI0d0hoY05NRFl4TWpFMU1EZ3dNREF3V2hjTk1qRXhNakUxCitNRGd3TURBd1dqQk1NU0F3SGdZRFZRUUxFeGRIYkc5aVlXeFRhV2R1SUZKdmIzUWdRMEVnTFNCU01qRVRNQkVHCitBMVVFQ2hNS1IyeHZZbUZzVTJsbmJqRVRNQkVHQTFVRUF4TUtSMnh2WW1Gc1UybG5iakNDQVNJd0RRWUpLb1pJCitodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUtiUEpBNitMbThvbVVWQ3hLcytJVlNiQzlOL2hIRDZFclBMCit2NGRmeG4rRzA3SXdYTmI5cmZGNzNPWDRZSllKa2hEMTBGUGUrM3QrYzRpc1VvaDdTcWJLU2FaZXFLZU1XaEc4Citlb0xydm96cHM2eVdKUWVYU3BrcUJ5KzBIbmUvaWcrMUFud2JscmpGdVRvc3ZOWVN1ZXRaZmVMUUJvWmZYa2xxCit0VGxlaURUc3ZIZ01DSmlFYktqTlM3U2dmUXg1VGZDNExjc2h5dFZzVzMzaG9DbUVvZm5UbEVuTEpHS1JJTHpkCitDOVhaelBucUp3b3JjNUhHblJ1c3lNdm80S0QwTDVDTFRmdXdOaHYyR1hxRjRHM3lZUk9JWEovZ2t3cFJsNHBhCit6cStyMWZlcUNhcGd2ZHpaWDk5eXFXQVRYZ0FCeVVyNlA2VHFCd01oQW82Q3lnUENtNDhDQXdFQUFhT0JuRENCCittVEFPQmdOVkhROEJBZjhFQkFNQ0FRWXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVVtK0lICitWMmNjSHNCcUJ0NVp0Sm90Mzl3WmhpNHdOZ1lEVlIwZkJDOHdMVEFyb0NtZ0o0WWxhSFIwY0RvdkwyTnliQzVuCitiRzlpWVd4emFXZHVMbTVsZEM5eWIyOTBMWEl5TG1OeWJEQWZCZ05WSFNNRUdEQVdnQlNiNGdkWFp4d2V3R29HCiszbG0wbWkzZjNCbUdMakFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBbVlGVGh4eG9sNGFSN09CS3VFUUxxNEdzCitKMC9Xd2JnY1EzaXpESnI4Nml3OGJtRWJUVXNwOVo4RkhTYkJ1T21EQUdKRnRxa0lrN21wTTBzWW1zTDRoNGhPCisyOTF4TkJyQlZOcEdQK0RUS3F0dFZDTDFPbUxOSUcrNktZblgzWkh1MDF5aVBxRmJRZlhmNVdSRExlblZPYXZTCitvdCszaTlEQWdCa2NSY0F0ak9qNExhUjBWa25GQmJWUEZkNXVSSGc1aDZoK3UvTjVHSkc3OUcrZHdmQ01OWXhkCitBZnZEYmJudlJHMTVSakYrQ3Y2cGdzSC83NnR1SU1SUXlWK2RUWnNYakF6bEFjbWdRV3B6VS9xbFVMUnVKUS83CitUQmowL1ZMWmptbXg2QkVQM29qWSt4MUo5NnJlbGM4Z2VNSmdFdHNsUUl4cS9INUNPRUJrRXZlZWdlR1RMZz09CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICAwNDowMDowMDowMDowMDowMTowZjo4NjoyNjplNjowZAorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBPVT1HbG9iYWxTaWduIFJvb3QgQ0EgLSBSMiwgTz1HbG9iYWxTaWduLCBDTj1HbG9iYWxTaWduCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBEZWMgMTUgMDg6MDA6MDAgMjAwNiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IERlYyAxNSAwODowMDowMCAyMDIxIEdNVAorICAgICAgICBTdWJqZWN0OiBPVT1HbG9iYWxTaWduIFJvb3QgQ0EgLSBSMiwgTz1HbG9iYWxTaWduLCBDTj1HbG9iYWxTaWduCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDphNjpjZjoyNDowZTpiZToyZTo2ZjoyODo5OTo0NTo0MjpjNDphYjozZToKKyAgICAgICAgICAgICAgICAgICAgMjE6NTQ6OWI6MGI6ZDM6N2Y6ODQ6NzA6ZmE6MTI6YjM6Y2I6YmY6ODc6NWY6CisgICAgICAgICAgICAgICAgICAgIGM2OjdmOjg2OmQzOmIyOjMwOjVjOmQ2OmZkOmFkOmYxOjdiOmRjOmU1OmY4OgorICAgICAgICAgICAgICAgICAgICA2MDo5NjowOTo5MjoxMDpmNTpkMDo1MzpkZTpmYjo3Yjo3ZTo3Mzo4ODphYzoKKyAgICAgICAgICAgICAgICAgICAgNTI6ODg6N2I6NGE6YTY6Y2E6NDk6YTY6NWU6YTg6YTc6OGM6NWE6MTE6YmM6CisgICAgICAgICAgICAgICAgICAgIDdhOjgyOmViOmJlOjhjOmU5OmIzOmFjOjk2OjI1OjA3Ojk3OjRhOjk5OjJhOgorICAgICAgICAgICAgICAgICAgICAwNzoyZjpiNDoxZTo3NzpiZjo4YTowZjpiNTowMjo3YzoxYjo5NjpiODpjNToKKyAgICAgICAgICAgICAgICAgICAgYjk6M2E6MmM6YmM6ZDY6MTI6Yjk6ZWI6NTk6N2Q6ZTI6ZDA6MDY6ODY6NWY6CisgICAgICAgICAgICAgICAgICAgIDVlOjQ5OjZhOmI1OjM5OjVlOjg4OjM0OmVjOmJjOjc4OjBjOjA4Ojk4Ojg0OgorICAgICAgICAgICAgICAgICAgICA2YzphODpjZDo0YjpiNDphMDo3ZDowYzo3OTo0ZDpmMDpiODoyZDpjYjoyMToKKyAgICAgICAgICAgICAgICAgICAgY2E6ZDU6NmM6NWI6N2Q6ZTE6YTA6Mjk6ODQ6YTE6Zjk6ZDM6OTQ6NDk6Y2I6CisgICAgICAgICAgICAgICAgICAgIDI0OjYyOjkxOjIwOmJjOmRkOjBiOmQ1OmQ5OmNjOmY5OmVhOjI3OjBhOjJiOgorICAgICAgICAgICAgICAgICAgICA3Mzo5MTpjNjo5ZDoxYjphYzpjODpjYjplODplMDphMDpmNDoyZjo5MDo4YjoKKyAgICAgICAgICAgICAgICAgICAgNGQ6ZmI6YjA6MzY6MWI6ZjY6MTk6N2E6ODU6ZTA6NmQ6ZjI6NjE6MTM6ODg6CisgICAgICAgICAgICAgICAgICAgIDVjOjlmOmUwOjkzOjBhOjUxOjk3OjhhOjVhOmNlOmFmOmFiOmQ1OmY3OmFhOgorICAgICAgICAgICAgICAgICAgICAwOTphYTo2MDpiZDpkYzpkOTo1ZjpkZjo3MjphOTo2MDoxMzo1ZTowMDowMToKKyAgICAgICAgICAgICAgICAgICAgYzk6NGE6ZmE6M2Y6YTQ6ZWE6MDc6MDM6MjE6MDI6OGU6ODI6Y2E6MDM6YzI6CisgICAgICAgICAgICAgICAgICAgIDliOjhmCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgOUI6RTI6MDc6NTc6Njc6MUM6MUU6QzA6NkE6MDY6REU6NTk6QjQ6OUE6MkQ6REY6REM6MTk6ODY6MkUKKyAgICAgICAgICAgIFg1MDl2MyBDUkwgRGlzdHJpYnV0aW9uIFBvaW50czogCisgICAgICAgICAgICAgICAgVVJJOmh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5uZXQvcm9vdC1yMi5jcmwKKworICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6OUI6RTI6MDc6NTc6Njc6MUM6MUU6QzA6NkE6MDY6REU6NTk6QjQ6OUE6MkQ6REY6REM6MTk6ODY6MkUKKworICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA5OTo4MTo1Mzo4NzoxYzo2ODo5Nzo4Njo5MTplYzplMDo0YTpiODo0NDowYjphYjo4MTphYzoKKyAgICAgICAgMjc6NGY6ZDY6YzE6Yjg6MWM6NDM6Nzg6YjM6MGM6OWE6ZmM6ZWE6MmM6M2M6NmU6NjE6MWI6CisgICAgICAgIDRkOjRiOjI5OmY1OjlmOjA1OjFkOjI2OmMxOmI4OmU5OjgzOjAwOjYyOjQ1OmI2OmE5OjA4OgorICAgICAgICA5MzpiOTphOTozMzo0YjoxODo5YTpjMjpmODo4Nzo4ODo0ZTpkYjpkZDo3MTozNDoxYTpjMToKKyAgICAgICAgNTQ6ZGE6NDY6M2Y6ZTA6ZDM6MmE6YWI6NmQ6NTQ6MjI6ZjU6M2E6NjI6Y2Q6MjA6NmY6YmE6CisgICAgICAgIDI5Ojg5OmQ3OmRkOjkxOmVlOmQzOjVjOmEyOjNlOmExOjViOjQxOmY1OmRmOmU1OjY0OjQzOgorICAgICAgICAyZDplOTpkNTozOTphYjpkMjphMjpkZjpiNzo4YjpkMDpjMDo4MDoxOToxYzo0NTpjMDoyZDoKKyAgICAgICAgOGM6ZTg6Zjg6MmQ6YTQ6NzQ6NTY6NDk6YzU6MDU6YjU6NGY6MTU6ZGU6NmU6NDQ6Nzg6Mzk6CisgICAgICAgIDg3OmE4OjdlOmJiOmYzOjc5OjE4OjkxOmJiOmY0OjZmOjlkOmMxOmYwOjhjOjM1OjhjOjVkOgorICAgICAgICAwMTpmYjpjMzo2ZDpiOTplZjo0NDo2ZDo3OTo0NjozMTo3ZTowYTpmZTphOTo4MjpjMTpmZjoKKyAgICAgICAgZWY6YWI6NmU6MjA6YzQ6NTA6Yzk6NWY6OWQ6NGQ6OWI6MTc6OGM6MGM6ZTU6MDE6Yzk6YTA6CisgICAgICAgIDQxOjZhOjczOjUzOmZhOmE1OjUwOmI0OjZlOjI1OjBmOmZiOjRjOjE4OmY0OmZkOjUyOmQ5OgorICAgICAgICA4ZTo2OTpiMTplODoxMTowZjpkZTo4ODpkODpmYjoxZDo0OTpmNzphYTpkZTo5NTpjZjoyMDoKKyAgICAgICAgNzg6YzI6NjA6MTI6ZGI6MjU6NDA6OGM6NmE6ZmM6N2U6NDI6Mzg6NDA6NjQ6MTI6Zjc6OWU6CisgICAgICAgIDgxOmUxOjkzOjJlCitTSEExIEZpbmdlcnByaW50PTc1OkUwOkFCOkI2OjEzOjg1OjEyOjI3OjFDOjA0OkY4OjVGOkREOkRFOjM4OkU0OkI3OjI0OjJFOkZFCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMTE1NWM5NGIuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8xMTU1Yzk0Yi4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5ZDAzOWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMTE1NWM5NGIuMApAQCAtMCwwICsxLDg3IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUVWekNDQXorZ0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRVUZBRENCblRFTE1Ba0dBMVVFQmhNQ1JWTXgKK0lqQWdCZ05WQkFjVEdVTXZJRTExYm5SaGJtVnlJREkwTkNCQ1lYSmpaV3h2Ym1FeFFqQkFCZ05WQkFNVE9VRjEKK2RHOXlhV1JoWkNCa1pTQkRaWEowYVdacFkyRmphVzl1SUVacGNtMWhjSEp2Wm1WemFXOXVZV3dnUTBsR0lFRTIKK01qWXpOREEyT0RFbU1DUUdDU3FHU0liM0RRRUpBUllYWTJGQVptbHliV0Z3Y205bVpYTnBiMjVoYkM1amIyMHcKK0hoY05NREV4TURJME1qSXdNREF3V2hjTk1UTXhNREkwTWpJd01EQXdXakNCblRFTE1Ba0dBMVVFQmhNQ1JWTXgKK0lqQWdCZ05WQkFjVEdVTXZJRTExYm5SaGJtVnlJREkwTkNCQ1lYSmpaV3h2Ym1FeFFqQkFCZ05WQkFNVE9VRjEKK2RHOXlhV1JoWkNCa1pTQkRaWEowYVdacFkyRmphVzl1SUVacGNtMWhjSEp2Wm1WemFXOXVZV3dnUTBsR0lFRTIKK01qWXpOREEyT0RFbU1DUUdDU3FHU0liM0RRRUpBUllYWTJGQVptbHliV0Z3Y205bVpYTnBiMjVoYkM1amIyMHcKK2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURuSXdOdmJ5T2xYbmpPbFN6dGxCNXUKK0NwNEJ4K293MFN5ZDNUZm9tNWg1VnRQOGM5L1FpdDVWajFINVd1cmV0WERFN2FUdC82TU5iZzlrVURHdkFTZFkKK3J2NXNwMG92RnkzVGM5VVRISTlacFRRc0hWUUVSYzFvdUtEQUE2WFBoVUpIbFNoYnorK0FiT0NRbDRvQlBCM3oKK2h4QXdKa2g5MS96cG5aRngvMEdhcVVDMU41d3BJRThmVXVPZ2ZSTnRWTGNLM3VscVRnZXNyQmxmM0g1aWRQYXkKK0JRQzZoYUQ5SFRodXkxcTdocnlVWnpNMWd5d2ZJODM0eUpGeHpKZUw3NjRQM0NrREc4QTU2M0R0d1c0TzJHY0wKK2lhbThOZVR2dGpTMHBiYkVMYVcrME1PVUpFamIzNWJUQUxWbUdvdG1CUS9kUHovTFA2cGVta3I0dEVydmxUY2IKK0FnTUJBQUdqZ1o4d2dad3dLZ1lEVlIwUkJDTXdJWVlmYUhSMGNEb3ZMM2QzZHk1bWFYSnRZWEJ5YjJabGMybHYKK2JtRnNMbU52YlRBU0JnTlZIUk1CQWY4RUNEQUdBUUgvQWdFQk1Dc0dBMVVkRUFRa01DS0FEekl3TURFeE1ESTAKK01qSXdNREF3V29FUE1qQXhNekV3TWpReU1qQXdNREJhTUE0R0ExVWREd0VCL3dRRUF3SUJCakFkQmdOVkhRNEUKK0ZnUVVNd3VnWnRIcTJzN2VZcE1FS0ZLMUZIODRhTGN3RFFZSktvWklodmNOQVFFRkJRQURnZ0VCQUVkei9vMG4KK1ZQRDExSGVjSjNsWFY3Y1ZWdXpIMkZpM0FRTDBNKzJUVUlpZWZFYXh2VDhVYi9HelIwaUxqSmNHMStwK28xd3EKK3UwMHZSK0w0T1FiSm5DNHhHZ040OUx3NHhpS0xNekh3RmdRRWZmbDI1RXZYd09hRDdGbk1QOTcvVDJ1M1ozNm0KK2hvRXlJd09keVBkZndVcGdwWktwc2FTZ1lNTjRoN01pOHlyclc2bnRCYXMzRDdIaTA1VjJZMVowakZoeUd6ZmwKK1pLRytUUXlUbUF5WDlvZHRzei9ueTRDbTdZakhYMUJpQXVpWmRCYlE1clE1OFNmTHlFRFc0NFlRcVNNU2t1QnAKK1FXT25yeVVMd01XU3l4NllvMXE2eFRNUG9KY0IzWC9nZTlZR1ZNK2g0azA0NjB0UXRjc205TXJhY0VwcW9lSjUKK3F1R25NL2I5U2gvMjJXQT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMSAoMHgxKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPUVTLCBMPUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmEsIENOPUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2OC9lbWFpbEFkZHJlc3M9Y2FAZmlybWFwcm9mZXNpb25hbC5jb20KKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IE9jdCAyNCAyMjowMDowMCAyMDAxIEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogT2N0IDI0IDIyOjAwOjAwIDIwMTMgR01UCisgICAgICAgIFN1YmplY3Q6IEM9RVMsIEw9Qy8gTXVudGFuZXIgMjQ0IEJhcmNlbG9uYSwgQ049QXV0b3JpZGFkIGRlIENlcnRpZmljYWNpb24gRmlybWFwcm9mZXNpb25hbCBDSUYgQTYyNjM0MDY4L2VtYWlsQWRkcmVzcz1jYUBmaXJtYXByb2Zlc2lvbmFsLmNvbQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6ZTc6MjM6MDM6NmY6NmY6MjM6YTU6NWU6Nzg6Y2U6OTU6MmM6ZWQ6OTQ6CisgICAgICAgICAgICAgICAgICAgIDFlOjZlOjBhOjllOjAxOmM3OmVhOjMwOmQxOjJjOjlkOmRkOjM3OmU4OjliOgorICAgICAgICAgICAgICAgICAgICA5ODo3OTo1NjpkMzpmYzo3MzpkZjpkMDo4YTpkZTo1NTo4Zjo1MTpmOTo1YToKKyAgICAgICAgICAgICAgICAgICAgZWE6ZGU6YjU6NzA6YzQ6ZWQ6YTQ6ZWQ6ZmY6YTM6MGQ6NmU6MGY6NjQ6NTA6CisgICAgICAgICAgICAgICAgICAgIDMxOmFmOjAxOjI3OjU4OmFlOmZlOjZjOmE3OjRhOjJmOjE3OjJkOmQzOjczOgorICAgICAgICAgICAgICAgICAgICBkNToxMzoxYzo4Zjo1OTphNTozNDoyYzoxZDo1NDowNDo0NTpjZDo2ODpiODoKKyAgICAgICAgICAgICAgICAgICAgYTA6YzA6MDM6YTU6Y2Y6ODU6NDI6NDc6OTU6Mjg6NWI6Y2Y6ZWY6ODA6NmM6CisgICAgICAgICAgICAgICAgICAgIGUwOjkwOjk3OjhhOjAxOjNjOjFkOmYzOjg3OjEwOjMwOjI2OjQ4OjdkOmQ3OgorICAgICAgICAgICAgICAgICAgICBmYzplOTo5ZDo5MTo3MTpmZjo0MTo5YTphOTo0MDpiNTozNzo5YzoyOToyMDoKKyAgICAgICAgICAgICAgICAgICAgNGY6MWY6NTI6ZTM6YTA6N2Q6MTM6NmQ6NTQ6Yjc6MGE6ZGU6ZTk6NmE6NGU6CisgICAgICAgICAgICAgICAgICAgIDA3OmFjOmFjOjE5OjVmOmRjOjdlOjYyOjc0OmY2OmIyOjA1OjAwOmJhOjg1OgorICAgICAgICAgICAgICAgICAgICBhMDpmZDoxZDozODo2ZTpjYjo1YTpiYjo4NjpiYzo5NDo2NzozMzozNTo4MzoKKyAgICAgICAgICAgICAgICAgICAgMmM6MWY6MjM6Y2Q6Zjg6Yzg6OTE6NzE6Y2M6OTc6OGI6ZWY6YWU6MGY6ZGM6CisgICAgICAgICAgICAgICAgICAgIDI5OjAzOjFiOmMwOjM5OmViOjcwOmVkOmMxOjZlOjBlOmQ4OjY3OjBiOjg5OgorICAgICAgICAgICAgICAgICAgICBhOTpiYzozNTplNDplZjpiNjozNDpiNDphNTpiNjpjNDoyZDphNTpiZTpkMDoKKyAgICAgICAgICAgICAgICAgICAgYzM6OTQ6MjQ6NDg6ZGI6ZGY6OTY6ZDM6MDA6YjU6NjY6MWE6OGI6NjY6MDU6CisgICAgICAgICAgICAgICAgICAgIDBmOmRkOjNmOjNmOmNiOjNmOmFhOjVlOjlhOjRhOmY4OmI0OjRhOmVmOjk1OgorICAgICAgICAgICAgICAgICAgICAzNzoxYgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBBbHRlcm5hdGl2ZSBOYW1lOiAKKyAgICAgICAgICAgICAgICBVUkk6aHR0cDovL3d3dy5maXJtYXByb2Zlc2lvbmFsLmNvbQorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUsIHBhdGhsZW46MQorICAgICAgICAgICAgWDUwOXYzIFByaXZhdGUgS2V5IFVzYWdlIFBlcmlvZDogCisgICAgICAgICAgICAgICAgTm90IEJlZm9yZTogT2N0IDI0IDIyOjAwOjAwIDIwMDEgR01ULCBOb3QgQWZ0ZXI6IE9jdCAyNCAyMjowMDowMCAyMDEzIEdNVAorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDMzOjBCOkEwOjY2OkQxOkVBOkRBOkNFOkRFOjYyOjkzOjA0OjI4OjUyOkI1OjE0OjdGOjM4OjY4OkI3CisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDQ3OjczOmZlOjhkOjI3OjU0OmYwOmY1OmQ0Ojc3OjljOjI3Ojc5OjU3OjU3OmI3OjE1OjU2OgorICAgICAgICBlYzpjNzpkODo1ODpiNzowMTowMjpmNDozMzplZDo5Mzo1MDo4ODo5ZTo3Yzo0NjpiMTpiZDoKKyAgICAgICAgM2Y6MTQ6NmY6ZjE6YjM6NDc6NDg6OGI6OGM6OTc6MDY6ZDc6ZWE6N2U6YTM6NWM6MmE6YmI6CisgICAgICAgIDRkOjJmOjQ3OmUyOmY4OjM5OjA2OmM5OjljOjJlOjMxOjFhOjAzOjc4OmY0OmJjOjM4OmM2OgorICAgICAgICAyMjo4YjozMzozMTpmMDoxNjowNDowNDo3ZDpmOTo3NjplNDo0YjpkNzpjMDplNjo4MzplYzoKKyAgICAgICAgNTk6Y2M6M2Y6ZGU6ZmY6NGY6NmI6Yjc6Njc6N2U6YTY6ODY6ODE6MzI6MjM6MDM6OWQ6Yzg6CisgICAgICAgIGY3OjVmOmMxOjRhOjYwOmE1OjkyOmE5OmIxOmE0OmEwOjYwOmMzOjc4Ojg3OmIzOjIyOmYzOgorICAgICAgICAyYTplYjo1YjphOTplZDowNTphYjozNzowZjpiMTplMjpkMzo5NTo3Njo2Mzo1Njo3NDo4YzoKKyAgICAgICAgNTg6NzI6MWI6Mzc6ZTU6NjQ6YTE6YmU6NGQ6MGM6OTM6OTg6MGM6OTc6ZjY6ODc6NmQ6YjM6CisgICAgICAgIDNmOmU3OmNiOjgwOmE2OmVkOjg4OmM3OjVmOjUwOjYyOjAyOmU4Ojk5Ojc0OjE2OmQwOmU2OgorICAgICAgICBiNDozOTpmMToyNzpjYjpjODo0MDpkNjplMzo4NjoxMDphOToyMzoxMjo5MjplMDo2OTo0MToKKyAgICAgICAgNjM6YTc6YWY6MjU6MGI6YzA6YzU6OTI6Y2I6MWU6OTg6YTM6NWE6YmE6YzU6MzM6MGY6YTA6CisgICAgICAgIDk3OjAxOmRkOjdmOmUwOjdiOmQ2OjA2OjU0OmNmOmExOmUyOjRkOjM4OmViOjRiOjUwOmI1OgorICAgICAgICBjYjoyNjpmNDpjYTpkYTo3MDo0YTo2YTphMTplMjo3OTphYTplMTphNzozMzpmNjpmZDo0YToKKyAgICAgICAgMWY6ZjY6ZDk6NjAKK1NIQTEgRmluZ2VycHJpbnQ9QTk6NjI6OEY6NEI6OTg6QTk6MUI6NDg6MzU6QkE6RDI6QzE6NDY6MzI6ODY6QkI6NjY6NjQ6NkE6OEMKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8xMTlhZmMyZS4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzExOWFmYzJlLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTRiOWQzMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8xMTlhZmMyZS4wCkBAIC0wLDAgKzEsOTggQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRTVqQ0NBODZnQXdJQkFnSUVPNDVML0RBTkJna3Foa2lHOXcwQkFRVUZBREJkTVJnd0ZnWUpLb1pJaHZjTgorQVFrQkZnbHdhMmxBYzJzdVpXVXhDekFKQmdOVkJBWVRBa1ZGTVNJd0lBWURWUVFLRXhsQlV5QlRaWEowYVdacAorZEhObFpYSnBiV2x6YTJWemEzVnpNUkF3RGdZRFZRUURFd2RLZFhWeUxWTkxNQjRYRFRBeE1EZ3pNREUwTWpNdworTVZvWERURTJNRGd5TmpFME1qTXdNVm93WFRFWU1CWUdDU3FHU0liM0RRRUpBUllKY0d0cFFITnJMbVZsTVFzdworQ1FZRFZRUUdFd0pGUlRFaU1DQUdBMVVFQ2hNWlFWTWdVMlZ5ZEdsbWFYUnpaV1Z5YVcxcGMydGxjMnQxY3pFUQorTUE0R0ExVUVBeE1IU25WMWNpMVRTekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQgorQUlGeE5qNHpCOWJqTUkwVGZuY3lSc3ZQR2JKZ01VYVhodlNZUnFUQ1pVWFAwMEI4NDFvaXFCQjRNOHlJc2RPQgorU3ZaaUYzdGZUUW91ME0rTEkrNVBBazY3Nnc3S3ZSaGo2SUFjamVFY2pUM2cvMXRmNm1UbGwrZy9tWDhNQ2dregorQUJwVHB5SGhPRXZXZ3h1dHIyVEMrUng2akdaSVRXWWZHQXJpUHJzZkIyV1RoYmthc0xuRSt3MFI5dlhXK1J2SAorTEN1M0dGSCs0SHYycUVpdmJEdFBMKy80MFVjZUpsZndVUjB6bHYvdldUM2FUZEVWTk1mcVB4WkllNUVjZ0VNUAorUGJnRlB0R3psYzNZeWcvQ1EyZmJ0NVBnSW9JdXZ2Vm9LSU81d1R0cGV5RGFUcHh0NGJyTmozcHNzQWtpMTRzTAorMnh6VldpWmJEY0RxNVdEUW4vNDEzejhDQXdFQUFhT0NBYXd3Z2dHb01BOEdBMVVkRXdFQi93UUZNQU1CQWY4dworZ2dFV0JnTlZIU0FFZ2dFTk1JSUJDVENDQVFVR0Npc0dBUVFCemg4QkFRRXdnZll3Z2RBR0NDc0dBUVVGQndJQworTUlIREhvSEFBRk1BWlFCbEFDQUFjd0JsQUhJQWRBQnBBR1lBYVFCckFHRUFZUUIwQUNBQWJ3QnVBQ0FBZGdEaworQUd3QWFnQmhBSE1BZEFCaEFIUUFkUUJrQUNBQVFRQlRBQzBBYVFCekFDQUFVd0JsQUhJQWRBQnBBR1lBYVFCMAorQUhNQVpRQmxBSElBYVFCdEFHa0Fjd0JyQUdVQWN3QnJBSFVBY3dBZ0FHRUFiQUJoQUcwQUxRQlRBRXNBSUFCegorQUdVQWNnQjBBR2tBWmdCcEFHc0FZUUJoQUhRQWFRQmtBR1VBSUFCckFHa0FiZ0J1QUdrQWRBQmhBRzBBYVFCegorQUdVQWF3QnpNQ0VHQ0NzR0FRVUZCd0lCRmhWb2RIUndPaTh2ZDNkM0xuTnJMbVZsTDJOd2N5OHdLd1lEVlIwZgorQkNRd0lqQWdvQjZnSElZYWFIUjBjRG92TDNkM2R5NXpheTVsWlM5cWRYVnlMMk55YkM4d0hRWURWUjBPQkJZRQorRkFTcWVrZWo1SW12R3M4S1FLY1lQMi92NlgyK01COEdBMVVkSXdRWU1CYUFGQVNxZWtlajVJbXZHczhLUUtjWQorUDIvdjZYMitNQTRHQTFVZER3RUIvd1FFQXdJQjVqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFlOEVZbEZPaQorQ2ZQK0ptZWFVT1REQlM4ck5YaVJUSHlvRVJGNVRFbFpyTWozaFdWY1JyczdFS0FDcjgxUHRjdzJLdXhkL3UrZwora2NtMmsyOThnRlRzeHdod0RZNzdndXdxWUhocE5qYlJ4WnlMYWJWQXlKUmxkL0pYSVdZN3pvVkF0ak5qR3I5NQorSHZ4Y0hkTWRreHVMREYyRnZaa3dNaGdKa1ZMcGZLRzYvMlNTbXV6K05lNk1MNjc4SUlic1N0NGJlREkzcG9IUworbmE5YUVoYkttVnY4YjIwT3hhQWVoc21SMEZ5WWdsOWpESXBhcTlpVnBzekxpdGEvWkV1T3lvcXlzT2toTXA2cQorcUlXWU5JRTVJVHVvT2xJeVBmWnJONFlHV2hXWTNQQVJadjQwSUxjRDlFRVFmVG1FZVpaeVk3YVdBdVZydWEwWgorVGJ2R1JOczJ5eXFjamc9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiA5OTkxODEzMDggKDB4M2I4ZTRiZmMpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IGVtYWlsQWRkcmVzcz1wa2lAc2suZWUsIEM9RUUsIE89QVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1cywgQ049SnV1ci1TSworICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogQXVnIDMwIDE0OjIzOjAxIDIwMDEgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBBdWcgMjYgMTQ6MjM6MDEgMjAxNiBHTVQKKyAgICAgICAgU3ViamVjdDogZW1haWxBZGRyZXNzPXBraUBzay5lZSwgQz1FRSwgTz1BUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzLCBDTj1KdXVyLVNLCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDo4MTo3MTozNjozZTozMzowNzpkNjplMzozMDo4ZDoxMzo3ZTo3NzozMjoKKyAgICAgICAgICAgICAgICAgICAgNDY6Y2I6Y2Y6MTk6YjI6NjA6MzE6NDY6OTc6ODY6ZjQ6OTg6NDY6YTQ6YzI6CisgICAgICAgICAgICAgICAgICAgIDY1OjQ1OmNmOmQzOjQwOjdjOmUzOjVhOjIyOmE4OjEwOjc4OjMzOmNjOjg4OgorICAgICAgICAgICAgICAgICAgICBiMTpkMzo4MTo0YTpmNjo2MjoxNzo3Yjo1Zjo0ZDowYToyZTpkMDpjZjo4YjoKKyAgICAgICAgICAgICAgICAgICAgMjM6ZWU6NGY6MDI6NGU6YmI6ZWI6MGU6Y2E6YmQ6MTg6NjM6ZTg6ODA6MWM6CisgICAgICAgICAgICAgICAgICAgIDhkOmUxOjFjOjhkOjNkOmUwOmZmOjViOjVmOmVhOjY0OmU1Ojk3OmU4OjNmOgorICAgICAgICAgICAgICAgICAgICA5OTo3ZjowYzowYTowOTozMzowMDoxYTo1MzphNzoyMTplMTozODo0YjpkNjoKKyAgICAgICAgICAgICAgICAgICAgODM6MWI6YWQ6YWY6NjQ6YzI6Zjk6MWM6N2E6OGM6NjY6NDg6NGQ6NjY6MWY6CisgICAgICAgICAgICAgICAgICAgIDE4OjBhOmUyOjNlOmJiOjFmOjA3OjY1OjkzOjg1OmI5OjFhOmIwOmI5OmM0OgorICAgICAgICAgICAgICAgICAgICBmYjowZDoxMTpmNjpmNTpkNjpmOToxYjpjNzoyYzoyYjpiNzoxODo1MTpmZToKKyAgICAgICAgICAgICAgICAgICAgZTA6N2I6ZjY6YTg6NDg6YWY6NmM6M2I6NGY6MmY6ZWY6Zjg6ZDE6NDc6MWU6CisgICAgICAgICAgICAgICAgICAgIDI2OjU3OmYwOjUxOjFkOjMzOjk2OmZmOmVmOjU5OjNkOmRhOjRkOmQxOjE1OgorICAgICAgICAgICAgICAgICAgICAzNDpjNzplYTozZjoxNjo0ODo3Yjo5MToxYzo4MDo0MzowZjozZDpiODowNToKKyAgICAgICAgICAgICAgICAgICAgM2U6ZDE6YjM6OTU6Y2Q6ZDg6Y2E6MGY6YzI6NDM6Njc6ZGI6Yjc6OTM6ZTA6CisgICAgICAgICAgICAgICAgICAgIDIyOjgyOjJlOmJlOmY1OjY4OjI4OjgzOmI5OmMxOjNiOjY5OjdiOjIwOmRhOgorICAgICAgICAgICAgICAgICAgICA0ZTo5Yzo2ZDplMTpiYTpjZDo4Zjo3YTo2YzpiMDowOToyMjpkNzo4YjowYjoKKyAgICAgICAgICAgICAgICAgICAgZGI6MWM6ZDU6NWE6MjY6NWI6MGQ6YzA6ZWE6ZTU6NjA6ZDA6OWY6ZmU6MzU6CisgICAgICAgICAgICAgICAgICAgIGRmOjNmCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgQ2VydGlmaWNhdGUgUG9saWNpZXM6IAorICAgICAgICAgICAgICAgIFBvbGljeTogMS4zLjYuMS40LjEuMTAwMTUuMS4xLjEKKyAgICAgICAgICAgICAgICAgIFVzZXIgTm90aWNlOgorICAgICAgICAgICAgICAgICAgICBFeHBsaWNpdCBUZXh0OiAKKyAgICAgICAgICAgICAgICAgIENQUzogaHR0cDovL3d3dy5zay5lZS9jcHMvCisKKyAgICAgICAgICAgIFg1MDl2MyBDUkwgRGlzdHJpYnV0aW9uIFBvaW50czogCisgICAgICAgICAgICAgICAgVVJJOmh0dHA6Ly93d3cuc2suZWUvanV1ci9jcmwvCisKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICAwNDpBQTo3QTo0NzpBMzpFNDo4OTpBRjoxQTpDRjowQTo0MDpBNzoxODozRjo2RjpFRjpFOTo3RDpCRQorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6MDQ6QUE6N0E6NDc6QTM6RTQ6ODk6QUY6MUE6Q0Y6MEE6NDA6QTc6MTg6M0Y6NkY6RUY6RTk6N0Q6QkUKKworICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBEaWdpdGFsIFNpZ25hdHVyZSwgTm9uIFJlcHVkaWF0aW9uLCBLZXkgRW5jaXBoZXJtZW50LCBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA3YjpjMToxODo5NDo1MzphMjowOTpmMzpmZToyNjo2Nzo5YTo1MDplNDpjMzowNToyZjoyYjoKKyAgICAgICAgMzU6Nzg6OTE6NGM6N2M6YTg6MTE6MTE6Nzk6NGM6NDk6NTk6YWM6Yzg6Zjc6ODU6NjU6NWM6CisgICAgICAgIDQ2OmJiOjNiOjEwOmEwOjAyOmFmOmNkOjRmOmI1OmNjOjM2OjJhOmVjOjVkOmZlOmVmOmEwOgorICAgICAgICA5MTpjOTpiNjo5Mzo2Zjo3Yzo4MDo1NDplYzpjNzowODo3MDowZDo4ZTpmYjo4MjplYzoyYToKKyAgICAgICAgNjA6Nzg6Njk6MzY6MzY6ZDE6YzU6OWM6OGI6Njk6YjU6NDA6Yzg6OTQ6NjU6Nzc6ZjI6NTc6CisgICAgICAgIDIxOjY2OjNiOmNlOjg1OjQwOmI2OjMzOjYzOjFhOmJmOjc5OjFlOmZjOjVjOjFkOmQzOjFkOgorICAgICAgICA5MzoxYjo4YjowYzo1ZDo4NTpiZDo5OTozMDozMjoxODowOTo5MTo1MjplOTo3YzphMTpiYToKKyAgICAgICAgZmY6NjQ6OTI6OWE6ZWM6ZmU6MzU6ZWU6OGM6MmY6YWU6ZmM6MjA6ODY6ZWM6NGE6ZGU6MWI6CisgICAgICAgIDc4OjMyOjM3OmE2OjgxOmQyOjlkOmFmOjVhOjEyOjE2OmNhOjk5OjViOmZjOjZmOjZkOjBlOgorICAgICAgICBjNTphMDoxZTo4NjpjOTo5MTpkMDo1Yzo5ODo4Mjo1Zjo2MzowYzo4YTo1YTphYjpkODo5NToKKyAgICAgICAgYTY6Y2M6Y2I6OGE6ZDY6YmY6NjQ6NGI6OGU6Y2E6OGE6YjI6YjA6ZTk6MjE6MzI6OWU6YWE6CisgICAgICAgIGE4Ojg1Ojk4OjM0OjgxOjM5OjIxOjNiOmE4OjNhOjUyOjMyOjNkOmY2OjZiOjM3Ojg2OjA2OgorICAgICAgICA1YToxNTo5ODpkYzpmMDoxMTo2NjpmZTozNDoyMDpiNzowMzpmNDo0MToxMDo3ZDozOTo4NDoKKyAgICAgICAgNzk6OTY6NzI6NjM6YjY6OTY6MDI6ZTU6NmI6Yjk6YWQ6MTk6NGQ6YmI6YzY6NDQ6ZGI6MzY6CisgICAgICAgIGNiOjJhOjljOjhlCitTSEExIEZpbmdlcnByaW50PTQwOjlEOjRCOkQ5OjE3OkI1OjVDOjI3OkI2OjlCOjY0OkNCOjk4OjIyOjQ0OjBEOkNEOjA5OkI4Ojg5CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMTFhMDliMzguMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8xMWEwOWIzOC4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ4ZGJjNzMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMTFhMDliMzguMApAQCAtMCwwICsxLDEwOCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlGR1RDQ0JBR2dBd0lCQWdJRVBraTl4REFOQmdrcWhraUc5dzBCQVFVRkFEQXhNUXN3Q1FZRFZRUUdFd0pFCitTekVNTUFvR0ExVUVDaE1EVkVSRE1SUXdFZ1lEVlFRREV3dFVSRU1nVDBORlV5QkRRVEFlRncwd016QXlNVEV3CitPRE01TXpCYUZ3MHpOekF5TVRFd09UQTVNekJhTURFeEN6QUpCZ05WQkFZVEFrUkxNUXd3Q2dZRFZRUUtFd05VCitSRU14RkRBU0JnTlZCQU1UQzFSRVF5QlBRMFZUSUVOQk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCitNSUlCQ2dLQ0FRRUFyR0wyWVNDeXo4REdoZGZqZWViTTdmSTVrcVNYTG1TamhGdUhuRXo5cFBQRVh5RzlWaERyCisyeTVoN0pOcDQ2UE12Wm5EQmZ3R3VNbzJIUDZRamtsTXhGYWFMMWE4ejNzTThXOUhwZzFEVGVMcEhUazB6WTBzCisyUktZK2VQaHdVcDhoampFcWNSaGlOSmVyeG9tVGRYa29DSkhoTmxrdHhtVy9Pd1o1TEtYSms1S1RNdVBKSXRVCitHQnhJWVh2VmlHamFYYlhxelJvd3dZQ0RkbENxVDlIVTNUanc3eGIwNFF4UUJyL3ErM3BKb1NnckhQYjhGVEtqCitkR3FQcWNOaUtYRXg1VHVrWUJkZWRPYmFFKzNwSHg4YjBiSm9jOFlRTkhWR0VCRGprQUIyUU11THQwTUpJZityCitUcFBHV09tbGd0dDN4RHFac1hLVlNRVHd0eXY2ZTFtTzNRSURBUUFCbzRJQ056Q0NBak13RHdZRFZSMFRBUUgvCitCQVV3QXdFQi96QU9CZ05WSFE4QkFmOEVCQU1DQVFZd2dld0dBMVVkSUFTQjVEQ0I0VENCM2dZSUtvRlFnU2tCCitBUUV3Z2RFd0x3WUlLd1lCQlFVSEFnRVdJMmgwZEhBNkx5OTNkM2N1WTJWeWRHbG1hV3RoZEM1a2F5OXlaWEJ2CitjMmwwYjNKNU1JR2RCZ2dyQmdFRkJRY0NBakNCa0RBS0ZnTlVSRU13QXdJQkFScUJnVU5sY25ScFptbHJZWFJsCitjaUJtY21FZ1pHVnVibVVnUTBFZ2RXUnpkR1ZrWlhNZ2RXNWtaWElnVDBsRUlERXVNaTR5TURndU1UWTVMakV1CitNUzR4TGlCRFpYSjBhV1pwWTJGMFpYTWdabkp2YlNCMGFHbHpJRU5CSUdGeVpTQnBjM04xWldRZ2RXNWtaWElnCitUMGxFSURFdU1pNHlNRGd1TVRZNUxqRXVNUzR4TGpBUkJnbGdoa2dCaHZoQ0FRRUVCQU1DQUFjd2dZRUdBMVVkCitId1I2TUhnd1NLQkdvRVNrUWpCQU1Rc3dDUVlEVlFRR0V3SkVTekVNTUFvR0ExVUVDaE1EVkVSRE1SUXdFZ1lECitWUVFERXd0VVJFTWdUME5GVXlCRFFURU5NQXNHQTFVRUF4TUVRMUpNTVRBc29DcWdLSVltYUhSMGNEb3ZMMk55CitiQzV2WTJWekxtTmxjblJwWm1scllYUXVaR3N2YjJObGN5NWpjbXd3S3dZRFZSMFFCQ1F3SW9BUE1qQXdNekF5CitNVEV3T0RNNU16QmFnUTh5TURNM01ESXhNVEE1TURrek1Gb3dId1lEVlIwakJCZ3dGb0FVWUxXRjdGWmtmaElaCitKMmNkVUJWTGM2NDcrUkl3SFFZRFZSME9CQllFRkdDMWhleFdaSDRTR1NkbkhWQVZTM091Ty9rU01CMEdDU3FHCitTSWIyZlFkQkFBUVFNQTRiQ0ZZMkxqQTZOQzR3QXdJRWtEQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFDcm9tCitKa2JUYzZnSjgyc0xNSm45aXVGWGVoSFR1SlRYQ1JCdW83RTRBOUcyOGtOQktXS25jdGo3ZkFYbU1YQW5WQmhPCitpbnhPNWRIS2pIaUl6eHZUa0l2bUkvZ0xEak5EZlp6aUNobVB5UUUrZEYxMHlZc2NBK1VZeUFGTVA4dVhCVjJZCitjYWFZYjdaOHZUZC92dUdUSlcxdjhBcXRGeGpoQTd3SEtjaXRKdWo0WWZEOUlRbCttbzZwYUgxSVluSzlBT29CCittYmdHZ2xHQlR2SDF0SkZVdVNONkFKcWZYWTNnUEdTNUdoS1NLc2VDUkhJNTNPSTh4dGhWOVJWT3lBVU8yOGJRCitZcWJzRmJTMUFvTGJySXlpZ2ZDYm1USDFJQ0NvaUdFS0I1K1UvTkRYRzh3dUYvTUVKM1puNjFTRC9hU1FmZ1k5CitCS05ETGRyOEMyTHFMMTlpVXc9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAxMDQ0OTU0NTY0ICgweDNlNDhiZGM0KQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPURLLCBPPVREQywgQ049VERDIE9DRVMgQ0EKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEZlYiAxMSAwODozOTozMCAyMDAzIEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogRmViIDExIDA5OjA5OjMwIDIwMzcgR01UCisgICAgICAgIFN1YmplY3Q6IEM9REssIE89VERDLCBDTj1UREMgT0NFUyBDQQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YWM6NjI6ZjY6NjE6MjA6YjI6Y2Y6YzA6YzY6ODU6ZDc6ZTM6Nzk6ZTY6CisgICAgICAgICAgICAgICAgICAgIGNjOmVkOmYyOjM5OjkyOmE0Ojk3OjJlOjY0OmEzOjg0OjViOjg3OjljOjRjOgorICAgICAgICAgICAgICAgICAgICBmZDphNDpmMzpjNDo1ZjoyMTpiZDo1NjoxMDplYjpkYjoyZTo2MTplYzo5MzoKKyAgICAgICAgICAgICAgICAgICAgNjk6ZTM6YTM6Y2M6YmQ6OTk6YzM6MDU6ZmM6MDY6Yjg6Y2E6MzY6MWM6ZmU6CisgICAgICAgICAgICAgICAgICAgIDkwOjhlOjQ5OjRjOmM0OjU2OjlhOjJmOjU2OmJjOmNmOjdiOjBjOmYxOjZmOgorICAgICAgICAgICAgICAgICAgICA0NzphNjowZDo0Mzo0ZDplMjplOToxZDozOTozNDpjZDo4ZDoyYzpkOToxMjoKKyAgICAgICAgICAgICAgICAgICAgOTg6Zjk6ZTM6ZTE6YzE6NGE6N2M6ODY6Mzg6YzQ6YTk6YzQ6NjE6ODg6ZDI6CisgICAgICAgICAgICAgICAgICAgIDVlOmFmOjFhOjI2OjRkOmQ1OmU0OmEwOjIyOjQ3Ojg0OmQ5OjY0OmI3OjE5OgorICAgICAgICAgICAgICAgICAgICA5NjpmYzplYzoxOTplNDpiMjo5NzoyNjo0ZTo0YTo0YzpjYjo4ZjoyNDo4YjoKKyAgICAgICAgICAgICAgICAgICAgNTQ6MTg6MWM6NDg6NjE6N2I6ZDU6ODg6Njg6ZGE6NWQ6YjU6ZWE6Y2Q6MWE6CisgICAgICAgICAgICAgICAgICAgIDMwOmMxOjgwOjgzOjc2OjUwOmFhOjRmOmQxOmQ0OmRkOjM4OmYwOmVmOjE2OgorICAgICAgICAgICAgICAgICAgICBmNDplMTowYzo1MDowNjpiZjplYTpmYjo3YTo0OTphMToyODoyYjoxYzpmNjoKKyAgICAgICAgICAgICAgICAgICAgZmM6MTU6MzI6YTM6NzQ6NmE6OGY6YTk6YzM6NjI6Mjk6NzE6MzE6ZTU6M2I6CisgICAgICAgICAgICAgICAgICAgIGE0OjYwOjE3OjVlOjc0OmU2OmRhOjEzOmVkOmU5OjFmOjFmOjFiOmQxOmIyOgorICAgICAgICAgICAgICAgICAgICA2ODo3MzpjNjoxMDozNDo3NTo0NjoxMDoxMDplMzo5MDowMDo3Njo0MDpjYjoKKyAgICAgICAgICAgICAgICAgICAgOGI6Yjc6NDM6MDk6MjE6ZmY6YWI6NGU6OTM6YzY6NTg6ZTk6YTU6ODI6ZGI6CisgICAgICAgICAgICAgICAgICAgIDc3OmM0OjNhOjk5OmIxOjcyOjk1OjQ5OjA0OmYwOmI3OjJiOmZhOjdiOjU5OgorICAgICAgICAgICAgICAgICAgICA4ZTpkZAorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIENlcnRpZmljYXRlIFBvbGljaWVzOiAKKyAgICAgICAgICAgICAgICBQb2xpY3k6IDEuMi4yMDguMTY5LjEuMS4xCisgICAgICAgICAgICAgICAgICBDUFM6IGh0dHA6Ly93d3cuY2VydGlmaWthdC5kay9yZXBvc2l0b3J5CisgICAgICAgICAgICAgICAgICBVc2VyIE5vdGljZToKKyAgICAgICAgICAgICAgICAgICAgT3JnYW5pemF0aW9uOiBUREMKKyAgICAgICAgICAgICAgICAgICAgTnVtYmVyOiAxCisgICAgICAgICAgICAgICAgICAgIEV4cGxpY2l0IFRleHQ6IENlcnRpZmlrYXRlciBmcmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4xLiBDZXJ0aWZpY2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4xLgorCisgICAgICAgICAgICBOZXRzY2FwZSBDZXJ0IFR5cGU6IAorICAgICAgICAgICAgICAgIFNTTCBDQSwgUy9NSU1FIENBLCBPYmplY3QgU2lnbmluZyBDQQorICAgICAgICAgICAgWDUwOXYzIENSTCBEaXN0cmlidXRpb24gUG9pbnRzOiAKKyAgICAgICAgICAgICAgICBEaXJOYW1lOi9DPURLL089VERDL0NOPVREQyBPQ0VTIENBL0NOPUNSTDEKKyAgICAgICAgICAgICAgICBVUkk6aHR0cDovL2NybC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwKKworICAgICAgICAgICAgWDUwOXYzIFByaXZhdGUgS2V5IFVzYWdlIFBlcmlvZDogCisgICAgICAgICAgICAgICAgTm90IEJlZm9yZTogRmViIDExIDA4OjM5OjMwIDIwMDMgR01ULCBOb3QgQWZ0ZXI6IEZlYiAxMSAwOTowOTozMCAyMDM3IEdNVAorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6NjA6QjU6ODU6RUM6NTY6NjQ6N0U6MTI6MTk6Mjc6Njc6MUQ6NTA6MTU6NEI6NzM6QUU6M0I6Rjk6MTIKKworICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDYwOkI1Ojg1OkVDOjU2OjY0OjdFOjEyOjE5OjI3OjY3OjFEOjUwOjE1OjRCOjczOkFFOjNCOkY5OjEyCisgICAgICAgICAgICAxLjIuODQwLjExMzUzMy43LjY1LjA6IAorICAgICAgICAgICAgICAgIDAuLi5WNi4wOjQuMC4uLi4KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMGE6YmE6MjY6MjY6NDY6ZDM6NzM6YTg6MDk6ZjM6NmI6MGI6MzA6OTk6ZmQ6OGE6ZTE6NTc6CisgICAgICAgIDdhOjExOmQzOmI4Ojk0OmQ3OjA5OjEwOjZlOmEzOmIxOjM4OjAzOmQxOmI2OmYyOjQzOjQxOgorICAgICAgICAyOTo2MjphNzo3MjpkODpmYjo3YzowNTplNjozMTo3MDoyNzo1NDoxODo0ZTo4YTo3Yzo0ZToKKyAgICAgICAgZTU6ZDE6Y2E6OGM6Nzg6ODg6Y2Y6MWI6ZDM6OTA6OGI6ZTY6MjM6Zjg6MGI6MGU6MzM6NDM6CisgICAgICAgIDdkOjljOmUyOjBhOjE5OjhmOmM5OjAxOjNlOjc0OjVkOjc0OmM5OjhiOjFjOjAzOmU1OjE4OgorICAgICAgICBjODowMTo0YzozZjpjYjo5NzowNTo1ZDo5ODo3MTphNjo5ODo2ZjpiNjo3YzpiZDozNzo3ZjoKKyAgICAgICAgYmU6ZTE6OTM6MjU6NmQ6NmY6ZjA6MGE6YWQ6MTc6MTg6ZTE6MDM6YmM6MDc6Mjk6Yzg6YWQ6CisgICAgICAgIDI2OmU4OmY4OjYxOmYwOmZkOjIxOjA5OjdlOjlhOjhlOmE5OjY4OjdkOjQ4OjYyOjcyOmJkOgorICAgICAgICAwMDplYTowMTo5OTpiODowNjo4Mjo1MTo4MTo0ZTpmMTpmNTpiNDo5MTo1NDpiOToyMzo3YToKKyAgICAgICAgMDA6OWE6OWY6NWQ6OGQ6ZTA6M2M6NjQ6Yjk6MWE6MTI6OTI6MmE6Yzc6ODI6NDQ6NzI6Mzk6CisgICAgICAgIGRjOmUyOjNjOmM2OmQ4OjU1OmY1OjE1OjRlOmM4OjA1OjBlOmRiOmM2OmQwOjYyOmE2OmVjOgorICAgICAgICAxNTpiNDpiNTowMjo4MjpkYjphYzo4YzphMjo4MTpmMDo5Yjo5OTozMTpmNToyMDoyMDphODoKKyAgICAgICAgODg6NjE6MGE6MDc6OWY6OTQ6ZmM6ZDA6ZDc6MWI6Y2M6MmU6MTc6ZjM6MDQ6Mjc6NzY6Njc6CisgICAgICAgIGViOjU0OjgzOmZkOmE0OjkwOjdlOjA2OjNkOjA0OmEzOjQzOjJkOmRhOmZjOjBiOjYyOmVhOgorICAgICAgICAyZjo1Zjo2Mjo1MworU0hBMSBGaW5nZXJwcmludD04Nzo4MTpDMjo1QTo5NjpCRDpDMjpGQjo0Qzo2NTowNjo0RjpGOTozOTowQjoyNjowNDo4QTowRTowMQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzEyZDU1ODQ1LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMTJkNTU4NDUuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YjA2Y2Y2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzEyZDU1ODQ1LjAKQEAgLTAsMCArMSw3OCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEU2pDQ0FqS2dBd0lCQWdJUVJLK3dnTmFqSjdxSk1EbUdMdmhBYXpBTkJna3Foa2lHOXcwQkFRVUZBREEvCitNU1F3SWdZRFZRUUtFeHRFYVdkcGRHRnNJRk5wWjI1aGRIVnlaU0JVY25WemRDQkRieTR4RnpBVkJnTlZCQU1UCitEa1JUVkNCU2IyOTBJRU5CSUZnek1CNFhEVEF3TURrek1ESXhNVEl4T1ZvWERUSXhNRGt6TURFME1ERXhOVm93CitQekVrTUNJR0ExVUVDaE1iUkdsbmFYUmhiQ0JUYVdkdVlYUjFjbVVnVkhKMWMzUWdRMjh1TVJjd0ZRWURWUVFECitFdzVFVTFRZ1VtOXZkQ0JEUVNCWU16Q0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCCitBTit2NlpkUUNJTlh0TXhpWmZhUWd1ekgweXhyTU1wYjdObkRmY2RBd1JnVWkrRG9NM1pKS3VNL0lVbVRyRTRPCityejVJeTJYdS9OTWhEMlhTS3RreWo0emw5M2V3RW51MWxjQ0pvNm02N1hNdWVnd0dNb09pZm9vVU1NMFJvT0VxCitPTGw1Q2pIOVVMMkFaZCszVVdPRHlPS0lZZXBMWVlIc1VtdTVvdUpMR2lpZlNLT2VETm9Kamo0WExoN2RJTjliCit4aXFLcXk2OWNLM0ZDeG9sa0hSeXhYdHFxelRXTUluLzVXZ1RlMVFMeU5hdTdGcWNraDQ5WkxPTXh0Ky95VUZ3Cis3Qlp5MVNic09GVTVROUQ4L1JoY1FQR1g2OVdhbTQwZHV0b2x1Y2JZMzhFVkFqcXIybTd4UGk3MVhBaWNQTmFECithZVFRbXhrcXRpbFg0K1U5bTUvd0FsMENBd0VBQWFOQ01FQXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QU9CZ05WCitIUThCQWY4RUJBTUNBUVl3SFFZRFZSME9CQllFRk1TbnNhUjdMSEg2MitGTGtIWC94QlZnaFlrUU1BMEdDU3FHCitTSWIzRFFFQkJRVUFBNElCQVFDakdpeWJGd0JjcVI3dUtHWTNPcitEeHo5THd3bWdsU0JkNDlsWlJOSStEVDY5Citpa3VnZEIvT0VJS2NkQm9kZnBnYTNjc1RTN01nUk9TUjZjejhmYVhiYXVYKzV2M2dUdDIzQURxMWNFbXY4dVhyCitBdkhSQW9zWnk1UTZYa2pFR0I1WUdWOGVBbHJ3RFBHeHJhbmNXWWFMYnVtUjlZYksrcmxtTTZwWlc4N2lweFp6CitSOHNyekptd04walA0MVpMOWM4UERISXloOGJ3Ukx0VGNtMUQ5U1pJbWxKbnQxaXIvbWQyY1hqYkRhSldGQk01CitKREdGb3FnQ1dqQkg0ZDFRQjd3Q0NaQUE2MlJqWUpzV3ZJakpFdWJTZlpHTCtUMHlqV1cwNlh5eFYzYnF4YllvCitPYjhWWlJ6STluZVdhZ3FOZHd2WWtRc0VqZ2ZiS2JZSzdwMkNOVFVRCistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICA0NDphZjpiMDo4MDpkNjphMzoyNzpiYTo4OTozMDozOTo4NjoyZTpmODo0MDo2YgorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBPPURpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLiwgQ049RFNUIFJvb3QgQ0EgWDMKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IFNlcCAzMCAyMToxMjoxOSAyMDAwIEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogU2VwIDMwIDE0OjAxOjE1IDIwMjEgR01UCisgICAgICAgIFN1YmplY3Q6IE89RGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uLCBDTj1EU1QgUm9vdCBDQSBYMworICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6ZGY6YWY6ZTk6OTc6NTA6MDg6ODM6NTc6YjQ6Y2M6NjI6NjU6ZjY6OTA6CisgICAgICAgICAgICAgICAgICAgIDgyOmVjOmM3OmQzOjJjOjZiOjMwOmNhOjViOmVjOmQ5OmMzOjdkOmM3OjQwOgorICAgICAgICAgICAgICAgICAgICBjMToxODoxNDo4YjplMDplODozMzo3Njo0OToyYTplMzozZjoyMTo0OTo5MzoKKyAgICAgICAgICAgICAgICAgICAgYWM6NGU6MGU6YWY6M2U6NDg6Y2I6NjU6ZWU6ZmM6ZDM6MjE6MGY6NjU6ZDI6CisgICAgICAgICAgICAgICAgICAgIDJhOmQ5OjMyOjhmOjhjOmU1OmY3Ojc3OmIwOjEyOjdiOmI1Ojk1OmMwOjg5OgorICAgICAgICAgICAgICAgICAgICBhMzphOTpiYTplZDo3MzoyZTo3YTowYzowNjozMjo4MzphMjo3ZTo4YToxNDoKKyAgICAgICAgICAgICAgICAgICAgMzA6Y2Q6MTE6YTA6ZTE6MmE6Mzg6Yjk6Nzk6MGE6MzE6ZmQ6NTA6YmQ6ODA6CisgICAgICAgICAgICAgICAgICAgIDY1OmRmOmI3OjUxOjYzOjgzOmM4OmUyOjg4OjYxOmVhOjRiOjYxOjgxOmVjOgorICAgICAgICAgICAgICAgICAgICA1Mjo2YjpiOTphMjplMjo0YjoxYToyODo5Zjo0ODphMzo5ZTowYzpkYTowOToKKyAgICAgICAgICAgICAgICAgICAgOGU6M2U6MTc6MmU6MWU6ZGQ6MjA6ZGY6NWI6YzY6MmE6OGE6YWI6MmU6YmQ6CisgICAgICAgICAgICAgICAgICAgIDcwOmFkOmM1OjBiOjFhOjI1OjkwOjc0OjcyOmM1OjdiOjZhOmFiOjM0OmQ2OgorICAgICAgICAgICAgICAgICAgICAzMDo4OTpmZjplNTo2ODoxMzo3Yjo1NDowYjpjODpkNjphZTplYzo1YTo5YzoKKyAgICAgICAgICAgICAgICAgICAgOTI6MWU6M2Q6NjQ6YjM6OGM6YzY6ZGY6YmY6Yzk6NDE6NzA6ZWM6MTY6NzI6CisgICAgICAgICAgICAgICAgICAgIGQ1OjI2OmVjOjM4OjU1OjM5OjQzOmQwOmZjOmZkOjE4OjVjOjQwOmYxOjk3OgorICAgICAgICAgICAgICAgICAgICBlYjpkNTo5YTo5Yjo4ZDoxZDpiYTpkYToyNTpiOTpjNjpkODpkZjpjMToxNToKKyAgICAgICAgICAgICAgICAgICAgMDI6M2E6YWI6ZGE6NmU6ZjE6M2U6MmU6ZjU6NWM6MDg6OWM6M2M6ZDY6ODM6CisgICAgICAgICAgICAgICAgICAgIDY5OmU0OjEwOjliOjE5OjJhOmI2OjI5OjU3OmUzOmU1OjNkOjliOjlmOmYwOgorICAgICAgICAgICAgICAgICAgICAwMjo1ZAorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEM0OkE3OkIxOkE0OjdCOjJDOjcxOkZBOkRCOkUxOjRCOjkwOjc1OkZGOkM0OjE1OjYwOjg1Ojg5OjEwCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIGEzOjFhOjJjOjliOjE3OjAwOjVjOmE5OjFlOmVlOjI4OjY2OjM3OjNhOmJmOjgzOmM3OjNmOgorICAgICAgICA0YjpjMzowOTphMDo5NToyMDo1ZDplMzpkOTo1OTo0NDpkMjozZTowZDozZTpiZDo4YTo0YjoKKyAgICAgICAgYTA6NzQ6MWY6Y2U6MTA6ODI6OWM6NzQ6MWE6MWQ6N2U6OTg6MWE6ZGQ6Y2I6MTM6NGI6YjM6CisgICAgICAgIDIwOjQ0OmU0OjkxOmU5OmNjOmZjOjdkOmE1OmRiOjZhOmU1OmZlOmU2OmZkOmUwOjRlOmRkOgorICAgICAgICBiNzowMDozYTpiNTo3MDo0OTphZjpmMjplNTplYjowMjpmMTpkMTowMjo4YjoxOTpjYjo5NDoKKyAgICAgICAgM2E6NWU6NDg6YzQ6MTg6MWU6NTg6MTk6NWY6MWU6MDI6NWE6ZjA6MGM6ZjE6YjE6YWQ6YTk6CisgICAgICAgIGRjOjU5Ojg2OjhiOjZlOmU5OjkxOmY1Ojg2OmNhOmZhOmI5OjY2OjMzOmFhOjU5OjViOmNlOgorICAgICAgICBlMjphNzoxNjo3Mzo0NzpjYjoyYjpjYzo5OTpiMDozNzo0ODpjZjplMzo1Njo0YjpmNTpjZjoKKyAgICAgICAgMGY6MGM6NzI6MzI6ODc6YzY6ZjA6NDQ6YmI6NTM6NzI6NmQ6NDM6ZjU6MjY6NDg6OWE6NTI6CisgICAgICAgIDY3OmI3OjU4OmFiOmZlOjY3Ojc2OjcxOjc4OmRiOjBkOmEyOjU2OjE0OjEzOjM5OjI0OjMxOgorICAgICAgICA4NTphMjphODowMjo1YTozMDo0NzplMTpkZDo1MDowNzpiYzowMjowOTo5MDowMDplYjo2NDoKKyAgICAgICAgNjM6NjA6OWI6MTY6YmM6ODg6Yzk6MTI6ZTY6ZDI6N2Q6OTE6OGI6Zjk6M2Q6MzI6OGQ6NjU6CisgICAgICAgIGI0OmU5OjdjOmIxOjU3Ojc2OmVhOmM1OmI2OjI4OjM5OmJmOjE1OjY1OjFjOmM4OmY2Ojc3OgorICAgICAgICA5Njo2YTowYTo4ZDo3NzowYjpkODo5MTowYjowNDo4ZTowNzpkYjoyOTpiNjowYTplZTo5ZDoKKyAgICAgICAgODI6MzU6MzU6MTAKK1NIQTEgRmluZ2VycHJpbnQ9REE6Qzk6MDI6NEY6NTQ6RDg6RjY6REY6OTQ6OTM6NUY6QjE6NzM6MjY6Mzg6Q0E6NkE6RDc6N0M6MTMKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8xN2I1MWZlNi4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzE3YjUxZmU2LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGFkZjQ4NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8xN2I1MWZlNi4wCkBAIC0wLDAgKzEsODUgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRGtqQ0NBbnFnQXdJQkFnSVJBSVc5Uy9QWTJ1TnA5cFRYWDhPbFJDTXdEUVlKS29aSWh2Y05BUUVGQlFBdworUFRFTE1Ba0dBMVVFQmhNQ1JsSXhFVEFQQmdOVkJBb1RDRU5sY25Sd2JIVnpNUnN3R1FZRFZRUURFeEpEYkdGegorY3lBeUlGQnlhVzFoY25rZ1EwRXdIaGNOT1Rrd056QTNNVGN3TlRBd1doY05NVGt3TnpBMk1qTTFPVFU1V2pBOQorTVFzd0NRWURWUVFHRXdKR1VqRVJNQThHQTFVRUNoTUlRMlZ5ZEhCc2RYTXhHekFaQmdOVkJBTVRFa05zWVhOegorSURJZ1VISnBiV0Z5ZVNCRFFUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU54UQorbHRBUytEWFNDSGg2dGxKdy9XL3V6N2tSeTExMzRlenBmZ1NOMXN4dmMwTlhZS3d6Q2tUc0ExOGNnQ1NSNWFpUgorVmhLQzkrQXI5TnV1WVM2SkVJMXJiTHF6QXIzVk5zVklOeVBpOEZvM1VqTVhFdUxSWUUyK0wwRVI0L1lYSlF5TAora2NBYm1YdVpWZzJ2N3RLOFIxZmplVWw3TklrbkpJVGVzZXpwV0U3K1R0OWF2a0d0ckFqRkdBN3YwbFB1Yk5DZAorRWdFVGpkeUFZdmVWcVVTSVNuRk9ZRldlMnlNWmVWWUhERDlqQzF5dzRyNStGZnlVTTFoQk9IVEU0WStMM3lhcworSDdXTE83ZERXV3V3SktadGtJdkVjdXBkTTVpM3k5NWVlKytVOFJzK3lza2h3Y1dZQXFxaTlsdDNtL1YrbGxVMAorSEdkcHdQRkM0MGVzL0NnY1psVUNBd0VBQWFPQmpEQ0JpVEFQQmdOVkhSTUVDREFHQVFIL0FnRUtNQXNHQTFVZAorRHdRRUF3SUJCakFkQmdOVkhRNEVGZ1FVNDNNdDM4c09LQXplM2JPa3lubTRqcnZvTUlrd0VRWUpZSVpJQVliNAorUWdFQkJBUURBZ0VHTURjR0ExVWRId1F3TUM0d0xLQXFvQ2lHSm1oMGRIQTZMeTkzZDNjdVkyVnlkSEJzZFhNdQorWTI5dEwwTlNUQzlqYkdGemN6SXVZM0pzTUEwR0NTcUdTSWIzRFFFQkJRVUFBNElCQVFDblZNK0lSQm5MMzlSLworQU45V00ySzE5MUVCa092RFA5R0lST2trWGUvbkZMMGd0NW84QVA1dG45dVEzTmYwWXRhTGNGM241UVJJcVdoOAoreWZGQzgyeC94WHA4SFZHSXV0SUtQaWRkM2kxUlR0TVRaR25rTHVQVDU1c0ptYWJnbFp2T0d0ZC92anpPVXJNUgorRmNFUEY4MER1NXdsRmJxaWRvbjhCdkVZMEpOTERueUN0NlgwOWwvKzdVQ21uWVIwT2JuY0hvVVcyaWtiaGlNQQoreWJ1SmZtNkFpQjR2RkxRREpLZ3lid09hUnl3d3ZsYkdwMElDY0J2cVFOaTZCUU53QjZTVy8vMUlNd3JoM0tXQgora0p0TjNYM241N0xOWE1ocWxmaWw5bzNFWFhnSXZuc0cxa25QR1RaUUl5NEk1cDRGVFVjWTFSYnBzZGEyRU5XNworbDcraWpyUlUKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDg1OmJkOjRiOmYzOmQ4OmRhOmUzOjY5OmY2Ojk0OmQ3OjVmOmMzOmE1OjQ0OjIzCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9RlIsIE89Q2VydHBsdXMsIENOPUNsYXNzIDIgUHJpbWFyeSBDQQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogSnVsICA3IDE3OjA1OjAwIDE5OTkgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBKdWwgIDYgMjM6NTk6NTkgMjAxOSBHTVQKKyAgICAgICAgU3ViamVjdDogQz1GUiwgTz1DZXJ0cGx1cywgQ049Q2xhc3MgMiBQcmltYXJ5IENBCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpkYzo1MDo5NjpkMDoxMjpmODozNTpkMjowODo3ODo3YTpiNjo1Mjo3MDoKKyAgICAgICAgICAgICAgICAgICAgZmQ6NmY6ZWU6Y2Y6Yjk6MTE6Y2I6NWQ6Nzc6ZTE6ZWM6ZTk6N2U6MDQ6OGQ6CisgICAgICAgICAgICAgICAgICAgIGQ2OmNjOjZmOjczOjQzOjU3OjYwOmFjOjMzOjBhOjQ0OmVjOjAzOjVmOjFjOgorICAgICAgICAgICAgICAgICAgICA4MDoyNDo5MTplNTphODo5MTo1NjoxMjo4MjpmNzplMDoyYjpmNDpkYjphZToKKyAgICAgICAgICAgICAgICAgICAgNjE6MmU6ODk6MTA6OGQ6NmI6NmM6YmE6YjM6MDI6YmQ6ZDU6MzY6YzU6NDg6CisgICAgICAgICAgICAgICAgICAgIDM3OjIzOmUyOmYwOjVhOjM3OjUyOjMzOjE3OjEyOmUyOmQxOjYwOjRkOmJlOgorICAgICAgICAgICAgICAgICAgICAyZjo0MToxMTplMzpmNjoxNzoyNTowYzo4Yjo5MTpjMDoxYjo5OTo3Yjo5OToKKyAgICAgICAgICAgICAgICAgICAgNTY6MGQ6YWY6ZWU6ZDI6YmM6NDc6NTc6ZTM6Nzk6NDk6N2I6MzQ6ODk6Mjc6CisgICAgICAgICAgICAgICAgICAgIDI0Ojg0OmRlOmIxOmVjOmU5OjU4OjRlOmZlOjRlOmRmOjVhOmJlOjQxOmFkOgorICAgICAgICAgICAgICAgICAgICBhYzowODpjNToxODowZTplZjpkMjo1MzplZTo2YzpkMDo5ZDoxMjowMToxMzoKKyAgICAgICAgICAgICAgICAgICAgOGQ6ZGM6ODA6NjI6Zjc6OTU6YTk6NDQ6ODg6NGE6NzE6NGU6NjA6NTU6OWU6CisgICAgICAgICAgICAgICAgICAgIGRiOjIzOjE5Ojc5OjU2OjA3OjBjOjNmOjYzOjBiOjVjOmIwOmUyOmJlOjdlOgorICAgICAgICAgICAgICAgICAgICAxNTpmYzo5NDozMzo1ODo0MTozODo3NDpjNDplMTo4Zjo4YjpkZjoyNjphYzoKKyAgICAgICAgICAgICAgICAgICAgMWY6YjU6OGI6M2I6Yjc6NDM6NTk6NmI6YjA6MjQ6YTY6NmQ6OTA6OGI6YzQ6CisgICAgICAgICAgICAgICAgICAgIDcyOmVhOjVkOjMzOjk4OmI3OmNiOmRlOjVlOjdiOmVmOjk0OmYxOjFiOjNlOgorICAgICAgICAgICAgICAgICAgICBjYTpjOToyMTpjMTpjNTo5ODowMjphYTphMjpmNjo1Yjo3Nzo5YjpmNTo3ZToKKyAgICAgICAgICAgICAgICAgICAgOTY6NTU6MzQ6MWM6Njc6Njk6YzA6ZjE6NDI6ZTM6NDc6YWM6ZmM6Mjg6MWM6CisgICAgICAgICAgICAgICAgICAgIDY2OjU1CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogCisgICAgICAgICAgICAgICAgQ0E6VFJVRSwgcGF0aGxlbjoxMAorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBFMzo3MzoyRDpERjpDQjowRToyODowQzpERTpERDpCMzpBNDpDQTo3OTpCODo4RTpCQjpFODozMDo4OQorICAgICAgICAgICAgTmV0c2NhcGUgQ2VydCBUeXBlOiAKKyAgICAgICAgICAgICAgICBTU0wgQ0EsIFMvTUlNRSBDQQorICAgICAgICAgICAgWDUwOXYzIENSTCBEaXN0cmlidXRpb24gUG9pbnRzOiAKKyAgICAgICAgICAgICAgICBVUkk6aHR0cDovL3d3dy5jZXJ0cGx1cy5jb20vQ1JML2NsYXNzMi5jcmwKKworICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBhNzo1NDpjZjo4ODo0NDoxOTpjYjpkZjpkNDo3ZjowMDpkZjo1NjozMzo2MjpiNTpmNzo1MToKKyAgICAgICAgMDE6OTA6ZWI6YzM6M2Y6ZDE6ODg6NDQ6ZTk6MjQ6NWQ6ZWY6ZTc6MTQ6YmQ6MjA6Yjc6OWE6CisgICAgICAgIDNjOjAwOmZlOjZkOjlmOmRiOjkwOmRjOmQ3OmY0OjYyOmQ2OjhiOjcwOjVkOmU3OmU1OjA0OgorICAgICAgICA0ODphOTo2ODo3YzpjOTpmMTo0MjpmMzo2Yzo3ZjpjNTo3YTo3YzoxZDo1MTo4ODpiYTpkMjoKKyAgICAgICAgMGE6M2U6Mjc6NWQ6ZGU6MmQ6NTE6NGU6ZDM6MTM6NjQ6Njk6ZTQ6MmU6ZTM6ZDM6ZTc6OWI6CisgICAgICAgIDA5Ojk5OmE2OmUwOjk1OjliOmNlOjFhOmQ3OjdmOmJlOjNjOmNlOjUyOmIzOjExOjE1OmMxOgorICAgICAgICAwZjoxNzpjZDowMzpiYjo5YzoyNToxNTpiYTphMjo3Njo4OTpmYzowNjpmMToxODpkMDo5MzoKKyAgICAgICAgNGI6MGU6N2M6ODI6Yjc6YTU6ZjQ6ZjY6NWY6ZmU6ZWQ6NDA6YTY6OWQ6ODQ6NzQ6Mzk6Yjk6CisgICAgICAgIGRjOjFlOjg1OjE2OmRhOjI5OjFiOjg2OjIzOjAwOmM5OmJiOjg5OjdlOjZlOjgwOjg4OjFlOgorICAgICAgICAyZjoxNDpiNDowMzoyNDphODozMjo2ZjowMzo5YTo0NzoyYzozMDpiZTo1NjpjNjphNzo0MjoKKyAgICAgICAgMDI6NzA6MWI6ZWE6NDA6ZDg6YmE6MDU6MDM6NzA6MDc6YTQ6OTY6ZmY6ZmQ6NDg6MzM6MGE6CisgICAgICAgIGUxOmRjOmE1OjgxOjkwOjliOjRkOmRkOjdkOmU3OmU3OmIyOmNkOjVjOmM4OjZhOjk1OmY4OgorICAgICAgICBhNTpmNjo4ZDpjNDo1ZDo3ODowODpiZTo3YjowNjpkNjo0OTpjZjoxOTozNjo1MDoyMzoyZToKKyAgICAgICAgMDg6ZTY6OWU6MDU6NGQ6NDc6MTg6ZDU6MTY6ZTk6YjE6ZDY6YjY6MTA6ZDU6YmI6OTc6YmY6CisgICAgICAgIGEyOjhlOmI0OjU0CitTSEExIEZpbmdlcnByaW50PTc0OjIwOjc0OjQxOjcyOjlDOkREOjkyOkVDOjc5OjMxOkQ4OjIzOjEwOjhEOkMyOjgxOjkyOkUyOkJCCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMTkyMGNhY2IuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8xOTIwY2FjYi4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE5MGFlYTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMTkyMGNhY2IuMApAQCAtMCwwICsxLDEwOSBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlHQnpDQ0JPK2dBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUVVGQURDQnNqRUxNQWtHQTFVRUJoTUNSVk14CitEekFOQmdOVkJBZ1RCazFoWkhKcFpERVBNQTBHQTFVRUJ4TUdUV0ZrY21sa01TOHdMUVlEVlFRS0V5WkpVRk1nCitRMlZ5ZEdsbWFXTmhkR2x2YmlCQmRYUm9iM0pwZEhrZ2N5NXNMaUJwY0hORFFURU9NQXdHQTFVRUN4TUZhWEJ6CitRMEV4SFRBYkJnTlZCQU1URkdsd2MwTkJJRWRzYjJKaGJDQkRRU0JTYjI5ME1TRXdId1lKS29aSWh2Y05BUWtCCitGaEpuYkc5aVlXd3dNVUJwY0hOallTNWpiMjB3SGhjTk1Ea3dPVEEzTVRRek9EUTBXaGNOTWpreE1qSTFNVFF6CitPRFEwV2pDQnNqRUxNQWtHQTFVRUJoTUNSVk14RHpBTkJnTlZCQWdUQmsxaFpISnBaREVQTUEwR0ExVUVCeE1HCitUV0ZrY21sa01TOHdMUVlEVlFRS0V5WkpVRk1nUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa2djeTVzCitMaUJwY0hORFFURU9NQXdHQTFVRUN4TUZhWEJ6UTBFeEhUQWJCZ05WQkFNVEZHbHdjME5CSUVkc2IySmhiQ0JECitRU0JTYjI5ME1TRXdId1lKS29aSWh2Y05BUWtCRmhKbmJHOWlZV3d3TVVCcGNITmpZUzVqYjIwd2dnRWlNQTBHCitDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ243OHlBTUxDUkpFK3dhUGpEeWkwVk9GVllndUk0CitZN0QzbzVKdmc3aXdYckNNckZTeGQ5QlE0SmV6a0syS3N4ODVLMFZXOTZyaTMzeXk3RzlUTDVyTDBPWm15OGtUCis2SExpdE0weFY0Y1N0WlBvK25MTzZrZnlqTFN3WTljRUFMZGtOam1YNkpYeGlQbHhEUU1uakdIUENJT1dUNFBGCitUdWhjK0FadzhRS3FIQjZweUtwKzUxM05qVHdVYjJmUUc2a2pTSXNoS0RxS1RPWVJNZmtoTHJKblpzWXBicFNUCit6MENXL0xBOXY3SzBrNzlXY2JhbFFZZXdXTFZaSXloSnVKajVVQjR0RlNnTFRLeEowWVNwbTVybmNsUzNPTkRiCit5ZjZwYzlWdEVNMk9kZXYrbC8yQVBQeTAyRWowbVVZTGlCU2t0aTdiVEdEMEljRnNnSlVVMWEvVkFnTUJBQUdqCitnZ0lrTUlJQ0lEQWRCZ05WSFE0RUZnUVVGYWFXZ0xFVlN6SER3cHoyNXhNTFMvTVl6WVl3Z2Q4R0ExVWRJd1NCCisxekNCMUlBVUZhYVdnTEVWU3pIRHdwejI1eE1MUy9NWXpZYWhnYmlrZ2JVd2diSXhDekFKQmdOVkJBWVRBa1ZUCitNUTh3RFFZRFZRUUlFd1pOWVdSeWFXUXhEekFOQmdOVkJBY1RCazFoWkhKcFpERXZNQzBHQTFVRUNoTW1TVkJUCitJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNUlITXViQzRnYVhCelEwRXhEakFNQmdOVkJBc1RCV2x3CitjME5CTVIwd0d3WURWUVFERXhScGNITkRRU0JIYkc5aVlXd2dRMEVnVW05dmRERWhNQjhHQ1NxR1NJYjNEUUVKCitBUllTWjJ4dlltRnNNREZBYVhCelkyRXVZMjl0Z2dFQU1Bd0dBMVVkRXdRRk1BTUJBZjh3Q3dZRFZSMFBCQVFECitBZ0VHTUVjR0ExVWRKUVJBTUQ0R0NDc0dBUVVGQndNQkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3TUdDQ3NHCitBUVVGQndNRUJnZ3JCZ0VGQlFjRENBWUtLd1lCQkFHQ053b0RCREFkQmdOVkhSRUVGakFVZ1JKbmJHOWlZV3d3CitNVUJwY0hOallTNWpiMjB3SFFZRFZSMFNCQll3RklFU1oyeHZZbUZzTURGQWFYQnpZMkV1WTI5dE1FRUdBMVVkCitId1E2TURnd05xQTBvREtHTUdoMGRIQTZMeTlqY214bmJHOWlZV3d3TVM1cGNITmpZUzVqYjIwdlkzSnNMMk55CitiR2RzYjJKaGJEQXhMbU55YkRBNEJnZ3JCZ0VGQlFjQkFRUXNNQ293S0FZSUt3WUJCUVVITUFHR0hHaDBkSEE2CitMeTlqY214bmJHOWlZV3d3TVM1cGNITmpZUzVqYjIwd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFCajBydjZBCitENDdCZDIraVdrZElueU5Wb1ZOcitWMm5NS1VrdmtNditNSFJWL2srTElBbHpFYXBOdk5KV3gzMmZOZGpzMDArCitlUGFudEFKMytIa05QbXJMR0dDNC9RQ3ZETjFVNDFTUElqM3pFRzhSRGJVZWVvMG56QWk0VzhPNEdsOHJwMkEvCitBQnozRDF4Q1ptU2VoeEtBY0luZytsY29EazRmRUMvWkJZQzJnQzhjYWZEMnRtVTBCVy9LMlQ3NDFGMDNNc2U0CitLOHovYzVNQWNlQUJ5S3BEdmFueHp2cUErZkZERXBHbVplVmdCMDFIdWlzdkJQWktoU21JWlJESnNsTmluR3liCitZRndhRzlPdXhSMXltUWIvQmN5R0puTzAxRlFGM1I1ckFEdTNpZWpqa1FJZ0V1dnY2ZjRLS1NPQkk2TUEybkRNCitrbDgzSTlBY2V6VmNBM289CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDAgKDB4MCkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1FUywgU1Q9TWFkcmlkLCBMPU1hZHJpZCwgTz1JUFMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgcy5sLiBpcHNDQSwgT1U9aXBzQ0EsIENOPWlwc0NBIEdsb2JhbCBDQSBSb290L2VtYWlsQWRkcmVzcz1nbG9iYWwwMUBpcHNjYS5jb20KKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IFNlcCAgNyAxNDozODo0NCAyMDA5IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogRGVjIDI1IDE0OjM4OjQ0IDIwMjkgR01UCisgICAgICAgIFN1YmplY3Q6IEM9RVMsIFNUPU1hZHJpZCwgTD1NYWRyaWQsIE89SVBTIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IHMubC4gaXBzQ0EsIE9VPWlwc0NBLCBDTj1pcHNDQSBHbG9iYWwgQ0EgUm9vdC9lbWFpbEFkZHJlc3M9Z2xvYmFsMDFAaXBzY2EuY29tCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDphNzplZjpjYzo4MDozMDpiMDo5MToyNDo0ZjpiMDo2ODpmODpjMzpjYToKKyAgICAgICAgICAgICAgICAgICAgMmQ6MTU6Mzg6NTU6NTg6ODI6ZTI6Mzg6NjM6YjA6Zjc6YTM6OTI6NmY6ODM6CisgICAgICAgICAgICAgICAgICAgIGI4OmIwOjVlOmIwOjhjOmFjOjU0OmIxOjc3OmQwOjUwOmUwOjk3OmIzOjkwOgorICAgICAgICAgICAgICAgICAgICBhZDo4YTpiMzoxZjozOToyYjo0NTo1NjpmNzphYTplMjpkZjo3YzpiMjplYzoKKyAgICAgICAgICAgICAgICAgICAgNmY6NTM6MmY6OWE6Y2I6ZDA6ZTY6NjY6Y2I6Yzk6MTM6ZTg6NzI6ZTI6YjQ6CisgICAgICAgICAgICAgICAgICAgIGNkOjMxOjU3Ojg3OjEyOmI1OjkzOmU4OmZhOjcyOmNlOmVhOjQ3OmYyOjhjOgorICAgICAgICAgICAgICAgICAgICBiNDpiMDo2MzpkNzowNDowMDpiNzo2NDozNjozOTo5NzplODo5NTpmMTo4ODoKKyAgICAgICAgICAgICAgICAgICAgZjk6NzE6MGQ6MDM6Mjc6OGM6NjE6Y2Y6MDg6ODM6OTY6NGY6ODM6YzU6NGU6CisgICAgICAgICAgICAgICAgICAgIGU4OjVjOmY4OjA2OjcwOmYxOjAyOmFhOjFjOjFlOmE5OmM4OmFhOjdlOmU3OgorICAgICAgICAgICAgICAgICAgICA1ZDpjZDo4ZDozYzoxNDo2Zjo2NzpkMDoxYjphOToyMzo0ODo4YjoyMToyODoKKyAgICAgICAgICAgICAgICAgICAgM2E6OGE6NGM6ZTY6MTE6MzE6Zjk6MjE6MmU6YjI6Njc6NjY6YzY6Mjk6NmU6CisgICAgICAgICAgICAgICAgICAgIDk0OjkzOmNmOjQwOjk2OmZjOmIwOjNkOmJmOmIyOmI0OjkzOmJmOjU2OjcxOgorICAgICAgICAgICAgICAgICAgICBiNjphNTo0MTo4NzpiMDo1ODpiNTo1OToyMzoyODo0OTpiODo5ODpmOTo1MDoKKyAgICAgICAgICAgICAgICAgICAgMWU6MmQ6MTU6Mjg6MGI6NGM6YWM6NDk6ZDE6ODQ6YTk6OWI6OWE6ZTc6NzI6CisgICAgICAgICAgICAgICAgICAgIDU0OmI3OjM4OmQwOmRiOmM5OmZlOmE5OjczOmQ1OjZkOjEwOmNkOjhlOjc1OgorICAgICAgICAgICAgICAgICAgICBlYjpmZTo5NzpmZDo4MDozYzpmYzpiNDpkODo0ODpmNDo5OTo0NjowYjo4ODoKKyAgICAgICAgICAgICAgICAgICAgMTQ6YTQ6YjY6MmU6ZGI6NGM6NjA6ZjQ6MjE6YzE6NmM6ODA6OTU6MTQ6ZDU6CisgICAgICAgICAgICAgICAgICAgIGFmOmQ1CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICAxNTpBNjo5Njo4MDpCMToxNTo0QjozMTpDMzpDMjo5QzpGNjpFNzoxMzowQjo0QjpGMzoxODpDRDo4NgorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6MTU6QTY6OTY6ODA6QjE6MTU6NEI6MzE6QzM6QzI6OUM6RjY6RTc6MTM6MEI6NEI6RjM6MTg6Q0Q6ODYKKyAgICAgICAgICAgICAgICBEaXJOYW1lOi9DPUVTL1NUPU1hZHJpZC9MPU1hZHJpZC9PPUlQUyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBzLmwuIGlwc0NBL09VPWlwc0NBL0NOPWlwc0NBIEdsb2JhbCBDQSBSb290L2VtYWlsQWRkcmVzcz1nbG9iYWwwMUBpcHNjYS5jb20KKyAgICAgICAgICAgICAgICBzZXJpYWw6MDAKKworICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiAKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiAKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIEV4dGVuZGVkIEtleSBVc2FnZTogCisgICAgICAgICAgICAgICAgVExTIFdlYiBTZXJ2ZXIgQXV0aGVudGljYXRpb24sIFRMUyBXZWIgQ2xpZW50IEF1dGhlbnRpY2F0aW9uLCBDb2RlIFNpZ25pbmcsIEUtbWFpbCBQcm90ZWN0aW9uLCBUaW1lIFN0YW1waW5nLCBNaWNyb3NvZnQgRW5jcnlwdGVkIEZpbGUgU3lzdGVtCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBBbHRlcm5hdGl2ZSBOYW1lOiAKKyAgICAgICAgICAgICAgICBlbWFpbDpnbG9iYWwwMUBpcHNjYS5jb20KKyAgICAgICAgICAgIFg1MDl2MyBJc3N1ZXIgQWx0ZXJuYXRpdmUgTmFtZTogCisgICAgICAgICAgICAgICAgZW1haWw6Z2xvYmFsMDFAaXBzY2EuY29tCisgICAgICAgICAgICBYNTA5djMgQ1JMIERpc3RyaWJ1dGlvbiBQb2ludHM6IAorICAgICAgICAgICAgICAgIFVSSTpodHRwOi8vY3JsZ2xvYmFsMDEuaXBzY2EuY29tL2NybC9jcmxnbG9iYWwwMS5jcmwKKworICAgICAgICAgICAgQXV0aG9yaXR5IEluZm9ybWF0aW9uIEFjY2VzczogCisgICAgICAgICAgICAgICAgT0NTUCAtIFVSSTpodHRwOi8vY3JsZ2xvYmFsMDEuaXBzY2EuY29tCisKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMTg6ZjQ6YWU6ZmU6ODA6MGY6OGU6YzE6Nzc6NmY6YTI6NWE6NDc6NDg6OWY6MjM6NTU6YTE6CisgICAgICAgIDUzOjZiOmY5OjVkOmE3OjMwOmE1OjI0OmJlOjQzOjJmOmY4OmMxOmQxOjU3OmY5OjNlOjJjOgorICAgICAgICA4MDoyNTpjYzo0NjphOTozNjpmMzo0OTo1YjoxZDpmNjo3YzpkNzo2MzpiMzo0ZDozZTo3ODoKKyAgICAgICAgZjY6YTc6YjQ6MDI6Nzc6Zjg6Nzk6MGQ6M2U6NmE6Y2I6MTg6NjA6Yjg6ZmQ6MDA6YWY6MGM6CisgICAgICAgIGRkOjU0OmUzOjU0OjhmOjIyOjNkOmYzOjEwOjZmOjExOjBkOmI1OjFlOjdhOjhkOjI3OmNjOgorICAgICAgICAwODpiODo1YjpjMzpiODoxYTo1ZjoyYjphNzo2MDozZjowMDoxYzpmNzowZjo1Yzo0Mjo2NjoKKyAgICAgICAgNjQ6OWU6ODc6MTI6ODA6NzA6ODk6ZTA6ZmE6NTc6Mjg6MGU6NGU6MWY6MTA6MmY6ZDk6MDU6CisgICAgICAgIDgwOmI2OjgwOjJmOjFjOjY5OmYwOmY2OmI2OjY1OjM0OjA1OjZmOmNhOmQ5OjNlOmY4OmQ0OgorICAgICAgICA1ZDozNzozMjpjNzpiODoyYjpjYzpmZjo3Mzo5MzowMDo3MTplMDowMTpjODphYTo0MzpiZDoKKyAgICAgICAgYTk6ZjE6Y2U6ZmE6ODA6Zjk6ZjE6NDM6MTI6OTE6YTY6NjU6ZTU6NjA6MDc6NGQ6NDc6YmE6CisgICAgICAgIDJiOjJmOjA0OmY2OjRhOjg1OjI5Ojg4OjY1OjEwOmM5OmIyOjUzOjYyOjljOjZjOjliOjYwOgorICAgICAgICA1YzoxYToxYjpkMzphZTpjNToxZDo3Mjo5OTowNjpmZjowNTpjYzo4NjoyNjo3MzpiNDpkNDoKKyAgICAgICAgNTQ6MDU6ZGQ6MWU6NmI6MDA6M2I6Yjc6ODk6ZTg6ZTM6OTE6MDI6MjA6MTI6ZWI6ZWY6ZTk6CisgICAgICAgIGZlOjBhOjI5OjIzOjgxOjIzOmEzOjAwOmRhOjcwOmNjOjkyOjVmOjM3OjIzOmQwOjFjOjdiOgorICAgICAgICAzNTo1YzowMzo3YQorU0hBMSBGaW5nZXJwcmludD0zQzo3MTpENzowRTozNTpBNTpEQTpBODpCMjpFMzo4MToyRDpDMzo2Nzo3NDoxNzpGNTo5OTowRDpGMwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzFkYWMzMDAzLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMWRhYzMwMDMuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MGVhOTgxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzFkYWMzMDAzLjAKQEAgLTAsMCArMSw4OCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFQ1RDQ0F2R2dBd0lCQWdJUURWNlpDdGFkdDNqczJBZFdPNFlWMlRBTkJna3Foa2lHOXcwQkFRVUZBREJiCitNUXN3Q1FZRFZRUUdFd0pWVXpFZ01CNEdBMVVFQ2hNWFJHbG5hWFJoYkNCVGFXZHVZWFIxY21VZ1ZISjFjM1F4CitFVEFQQmdOVkJBc1RDRVJUVkNCQlEwVlRNUmN3RlFZRFZRUURFdzVFVTFRZ1FVTkZVeUJEUVNCWU5qQWVGdzB3CitNekV4TWpBeU1URTVOVGhhRncweE56RXhNakF5TVRFNU5UaGFNRnN4Q3pBSkJnTlZCQVlUQWxWVE1TQXdIZ1lECitWUVFLRXhkRWFXZHBkR0ZzSUZOcFoyNWhkSFZ5WlNCVWNuVnpkREVSTUE4R0ExVUVDeE1JUkZOVUlFRkRSVk14CitGekFWQmdOVkJBTVREa1JUVkNCQlEwVlRJRU5CSUZnMk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCitNSUlCQ2dLQ0FRRUF1VDMxTE1tVTNIV0tsVjFqNklSM2RtYTVXWkZjUnQyU1BwLzVEZ08wUFdHU3ZTTW10V1B1CitrdEtlMWp6SURaQmZaSUd4cUFnTlROajUwd1VvVXJRQkpjV1ZIQXgrUGhDRWRjL0JHWkZqeitpb2tZaTVRMUs3CitnTEZWaVlzeCt0QzNkcjVCUFRDYXBDSWxGM1BvSHVMVHJDcTlXemdoMVNwTDExVjk0enBWdmRkdGF3SlhhK1pICitmQWpJZ3JyZXA0YzlvVzI0TUZiQ3N3S0JYeTMxNHBvd0dDaTRadFBMQVpadjZvcEZWZGJnbmY5bkt4Y0NwazRhCithaEVMZnJkNzU1aldqSFp2d1R2YlVKTis1ZENPSHplNHZickduMnpwZkRQeU1qd21SL29uSkFMSmZoMWJpRUlUCithalY4ZlRYcExtYVJjcFBWTWliRWRQVlRvN05kbXZZSnl3SURBUUFCbzRISU1JSEZNQThHQTFVZEV3RUIvd1FGCitNQU1CQWY4d0RnWURWUjBQQVFIL0JBUURBZ0hHTUI4R0ExVWRFUVFZTUJhQkZIQnJhUzF2Y0hOQWRISjFjM1JrCitjM1F1WTI5dE1HSUdBMVVkSUFSYk1Ga3dWd1lLWUlaSUFXVURBZ0VCQVRCSk1FY0dDQ3NHQVFVRkJ3SUJGanRvCitkSFJ3T2k4dmQzZDNMblJ5ZFhOMFpITjBMbU52YlM5alpYSjBhV1pwWTJGMFpYTXZjRzlzYVdONUwwRkRSVk10CithVzVrWlhndWFIUnRiREFkQmdOVkhRNEVGZ1FVQ1hJR1RoaEREK1hXek1OcWl6RjdlSStvZzdnd0RRWUpLb1pJCitodmNOQVFFRkJRQURnZ0VCQUtQWWp0YXkyODRGNXpMTkFkTUVBK1YyNUZZcm5KbVE2QWd3Yk45OVBlN2x2N1VrCitRSVJKNGRFb3JzVENPbE13aVBIMWQyNVJ5dnIvbWE4a1h4dWcvZktzaE1yZnFmQmZCQzZ0RnI4aGx4Q0JQZVAvCitoNDB5M0pUbFI0cGVhaFBKbEpVOTB1N0lOSlhRZ05TdE1naUFWRHpndlZKVDExSjhzbWsvZjNyUGFuVEsrZ1FxCituRXhhQnFYcElLMUZaZzlwOGQyLzZlTXlpL3Jnd1laTmNqd3UySk40Q2lyNDJOSW5QUm1KWDFwN2lqdk1ETnBSCityc2NMOXl1d053WHN2RmNqNGpqU20yanpWaEtJVDBKOHVESEV0ZHZreUNFMDZVZ1JOZTc2eDVKWHhaODA1TWYyCis5dzRMVEp4b2VIdHhNY2ZySHVCblFmTzNvS2ZONVhvek5tcjZtaXM9CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICAwZDo1ZTo5OTowYTpkNjo5ZDpiNzo3ODplYzpkODowNzo1NjozYjo4NjoxNTpkOQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPURpZ2l0YWwgU2lnbmF0dXJlIFRydXN0LCBPVT1EU1QgQUNFUywgQ049RFNUIEFDRVMgQ0EgWDYKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IE5vdiAyMCAyMToxOTo1OCAyMDAzIEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogTm92IDIwIDIxOjE5OjU4IDIwMTcgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89RGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QsIE9VPURTVCBBQ0VTLCBDTj1EU1QgQUNFUyBDQSBYNgorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6Yjk6M2Q6ZjU6MmM6Yzk6OTQ6ZGM6NzU6OGE6OTU6NWQ6NjM6ZTg6ODQ6CisgICAgICAgICAgICAgICAgICAgIDc3Ojc2OjY2OmI5OjU5OjkxOjVjOjQ2OmRkOjkyOjNlOjlmOmY5OjBlOjAzOgorICAgICAgICAgICAgICAgICAgICBiNDozZDo2MTo5MjpiZDoyMzoyNjpiNTo2MzplZTo5MjpkMjo5ZTpkNjozYzoKKyAgICAgICAgICAgICAgICAgICAgYzg6MGQ6OTA6NWY6NjQ6ODE6YjE6YTg6MDg6MGQ6NGM6ZDg6Zjk6ZDM6MDU6CisgICAgICAgICAgICAgICAgICAgIDI4OjUyOmI0OjAxOjI1OmM1Ojk1OjFjOjBjOjdlOjNlOjEwOjg0Ojc1OmNmOgorICAgICAgICAgICAgICAgICAgICBjMToxOTo5MTo2MzpjZjplODphODo5MTo4ODpiOTo0Mzo1MjpiYjo4MDpiMToKKyAgICAgICAgICAgICAgICAgICAgNTU6ODk6OGI6MzE6ZmE6ZDA6Yjc6NzY6YmU6NDE6M2Q6MzA6OWE6YTQ6MjI6CisgICAgICAgICAgICAgICAgICAgIDI1OjE3OjczOmU4OjFlOmUyOmQzOmFjOjJhOmJkOjViOjM4OjIxOmQ1OjJhOgorICAgICAgICAgICAgICAgICAgICA0YjpkNzo1NTo3ZDplMzozYTo1NTpiZDpkNzo2ZDo2YjowMjo1Nzo2YjplNjoKKyAgICAgICAgICAgICAgICAgICAgNDc6N2M6MDg6Yzg6ODI6YmE6ZGU6YTc6ODc6M2Q6YTE6NmQ6Yjg6MzA6NTY6CisgICAgICAgICAgICAgICAgICAgIGMyOmIzOjAyOjgxOjVmOjJkOmY1OmUyOjlhOjMwOjE4OjI4OmI4OjY2OmQzOgorICAgICAgICAgICAgICAgICAgICBjYjowMTo5Njo2ZjplYTo4YTo0NTo1NTpkNjplMDo5ZDpmZjo2NzoyYjoxNzoKKyAgICAgICAgICAgICAgICAgICAgMDI6YTY6NGU6MWE6NmE6MTE6MGI6N2U6Yjc6N2I6ZTc6OTg6ZDY6OGM6NzY6CisgICAgICAgICAgICAgICAgICAgIDZmOmMxOjNiOmRiOjUwOjkzOjdlOmU1OmQwOjhlOjFmOjM3OmI4OmJkOmJhOgorICAgICAgICAgICAgICAgICAgICBjNjo5Zjo2YzplOTo3YzozMzpmMjozMjozYzoyNjo0NzpmYToyNzoyNDowMjoKKyAgICAgICAgICAgICAgICAgICAgYzk6N2U6MWQ6NWI6ODg6NDI6MTM6NmE6MzU6N2M6N2Q6MzU6ZTk6MmU6NjY6CisgICAgICAgICAgICAgICAgICAgIDkxOjcyOjkzOmQ1OjMyOjI2OmM0Ojc0OmY1OjUzOmEzOmIzOjVkOjlhOmY2OgorICAgICAgICAgICAgICAgICAgICAwOTpjYgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBEaWdpdGFsIFNpZ25hdHVyZSwgTm9uIFJlcHVkaWF0aW9uLCBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgQWx0ZXJuYXRpdmUgTmFtZTogCisgICAgICAgICAgICAgICAgZW1haWw6cGtpLW9wc0B0cnVzdGRzdC5jb20KKyAgICAgICAgICAgIFg1MDl2MyBDZXJ0aWZpY2F0ZSBQb2xpY2llczogCisgICAgICAgICAgICAgICAgUG9saWN5OiAyLjE2Ljg0MC4xLjEwMS4zLjIuMS4xLjEKKyAgICAgICAgICAgICAgICAgIENQUzogaHR0cDovL3d3dy50cnVzdGRzdC5jb20vY2VydGlmaWNhdGVzL3BvbGljeS9BQ0VTLWluZGV4Lmh0bWwKKworICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDA5OjcyOjA2OjRFOjE4OjQzOjBGOkU1OkQ2OkNDOkMzOjZBOjhCOjMxOjdCOjc4OjhGOkE4OjgzOkI4CisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIGEzOmQ4OjhlOmQ2OmIyOmRiOmNlOjA1OmU3OjMyOmNkOjAxOmQzOjA0OjAzOmU1Ojc2OmU0OgorICAgICAgICA1NjoyYjo5Yzo5OTo5MDplODowODozMDo2YzpkZjo3ZDozZDplZTplNTpiZjpiNToyNDo0MDoKKyAgICAgICAgODQ6NDk6ZTE6ZDE6Mjg6YWU6YzQ6YzI6M2E6NTM6MzA6ODg6ZjE6ZjU6Nzc6NmU6NTE6Y2E6CisgICAgICAgIGZhOmZmOjk5OmFmOjI0OjVmOjFiOmEwOmZkOmYyOmFjOjg0OmNhOmRmOmE5OmYwOjVmOjA0OgorICAgICAgICAyZTphZDoxNjpiZjoyMTo5NzoxMDo4MTozZDplMzpmZjo4Nzo4ZDozMjpkYzo5NDplNTo0NzoKKyAgICAgICAgOGE6NWU6NmE6MTM6Yzk6OTQ6OTU6M2Q6ZDI6ZWU6Yzg6MzQ6OTU6ZDA6ODA6ZDQ6YWQ6MzI6CisgICAgICAgIDA4OjgwOjU0OjNjOmUwOmJkOjUyOjUzOmQ3OjUyOjdjOmIyOjY5OjNmOjdmOjdhOmNmOjZhOgorICAgICAgICA3NDpjYTpmYTowNDoyYTo5Yzo0Yzo1YTowNjphNTplOToyMDphZDo0NTo2NjowZjo2OTpmMToKKyAgICAgICAgZGQ6YmY6ZTk6ZTM6MzI6OGI6ZmE6ZTA6YzE6ODY6NGQ6NzI6M2M6MmU6ZDg6OTM6Nzg6MGE6CisgICAgICAgIDJhOmY4OmQ4OmQyOjI3OjNkOjE5Ojg5OjVmOjVhOjdiOjhhOjNiOmNjOjBjOmRhOjUxOmFlOgorICAgICAgICBjNzowYjpmNzoyYjpiMDozNzowNTplYzpiYzo1NzoyMzplMjozODpkMjo5Yjo2ODpmMzo1NjoKKyAgICAgICAgMTI6ODg6NGY6NDI6N2M6Yjg6MzE6YzQ6YjU6ZGI6ZTQ6Yzg6MjE6MzQ6ZTk6NDg6MTE6MzU6CisgICAgICAgIGVlOmZhOmM3OjkyOjU3OmM1OjlmOjM0OmU0OmM3OmY2OmY3OjBlOjBiOjRjOjljOjY4Ojc4OgorICAgICAgICA3Yjo3MTozMTpjNzplYjoxZTplMDo2Nzo0MTpmMzpiNzphMDphNzpjZDplNTo3YTozMzozNjoKKyAgICAgICAgNmE6ZmE6OWE6MmIKK1NIQTEgRmluZ2VycHJpbnQ9NDA6NTQ6REE6NkY6MUM6M0Y6NDA6NzQ6QUM6RUQ6MEY6RUM6Q0Q6REI6Nzk6RDE6NTM6RkI6OTA6MUQKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8xZGJkZGE1Yi4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzFkYmRkYTViLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDk2YTEzNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8xZGJkZGE1Yi4wCkBAIC0wLDAgKzEsNzIgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJQytUQ0NBbUtnQXdJQkFnSUVOdkViR1RBTkJna3Foa2lHOXcwQkFRVUZBREEyTVFzd0NRWURWUVFHRXdKRgorVXpFTk1Bc0dBMVVFQ2hNRVJrNU5WREVZTUJZR0ExVUVDeE1QUms1TlZDQkRiR0Z6WlNBeUlFTkJNQjRYRFRrNQorTURNeE9ERTBOVFl4T1ZvWERURTVNRE14T0RFMU1qWXhPVm93TmpFTE1Ba0dBMVVFQmhNQ1JWTXhEVEFMQmdOVgorQkFvVEJFWk9UVlF4R0RBV0JnTlZCQXNURDBaT1RWUWdRMnhoYzJVZ01pQkRRVENCblRBTkJna3Foa2lHOXcwQgorQVFFRkFBT0Jpd0F3Z1ljQ2dZRUFtRCt0R1RhVFBUNytka0lVL1RWdjhmcXRJbnBZNDBiUVhjWmErV0l0anpGZQorL3JRdy9sQjByTmFkSGVCaXhrbmRGQko5Y1F1c0JzRS8xd2FINEpDSjF1WGpBN0x5SjdHZk04aXFhelpLbzhRLworZVVHZGlVWXZLejVqMURoV2thb2RzUTFDZFUzemgwN2pEMDNNdEd5L1loT0g2dENianJiaS94bjBsQW5WbG1FQworQVFPamdnRVVNSUlCRURBUkJnbGdoa2dCaHZoQ0FRRUVCQU1DQUFjd1dBWURWUjBmQkZFd1R6Qk5vRXVnU2FSSAorTUVVeEN6QUpCZ05WQkFZVEFrVlRNUTB3Q3dZRFZRUUtFd1JHVGsxVU1SZ3dGZ1lEVlFRTEV3OUdUazFVSUVOcworWVhObElESWdRMEV4RFRBTEJnTlZCQU1UQkVOU1RERXdLd1lEVlIwUUJDUXdJb0FQTVRrNU9UQXpNVGd4TkRVMgorTVRsYWdROHlNREU1TURNeE9ERTBOVFl4T1Zvd0N3WURWUjBQQkFRREFnRUdNQjhHQTFVZEl3UVlNQmFBRkVDYQorZGtTWGRBZkVyQlRMSG8xUE9rVjhNTmRoTUIwR0ExVWREZ1FXQkJSQW1uWkVsM1FIeEt3VXl4Nk5UenBGZkREWAorWVRBTUJnTlZIUk1FQlRBREFRSC9NQmtHQ1NxR1NJYjJmUWRCQUFRTU1Bb2JCRlkwTGpBREFnU1FNQTBHQ1NxRworU0liM0RRRUJCUVVBQTRHQkFHRk1vSHhaWTF0bStPNWxFODVEZ0VlNXNqWEp5SVRIYTNOZ1JlU2RONTMxamlXNQorK2FxcXl1UDRRNXd2b0lrRnNVVXlsQ29lQTQxZHB0N1BWNVhhM3laZ1g4dmZsUjY0emdqWStJckpUNmxvZFpQagorTHdWTVpHQUNva0llYjRab1pWVU8yRU52OHBFeFBxTkhQQ2dGcjBXMm5TSk1KbnRMZlZzVitSbEczd2hkCistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDkyMTc3MDc3NyAoMHgzNmYxMWIxOSkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1FUywgTz1GTk1ULCBPVT1GTk1UIENsYXNlIDIgQ0EKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IE1hciAxOCAxNDo1NjoxOSAxOTk5IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogTWFyIDE4IDE1OjI2OjE5IDIwMTkgR01UCisgICAgICAgIFN1YmplY3Q6IEM9RVMsIE89Rk5NVCwgT1U9Rk5NVCBDbGFzZSAyIENBCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMTAyNCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMTAyNCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDo5ODozZjphZDoxOTozNjo5MzozZDozZTpmZTo3Njo0MjoxNDpmZDozNToKKyAgICAgICAgICAgICAgICAgICAgNmY6ZjE6ZmE6YWQ6MjI6N2E6NTg6ZTM6NDY6ZDA6NWQ6YzY6NWE6Zjk6NjI6CisgICAgICAgICAgICAgICAgICAgIDJkOjhmOjMxOjVlOmZlOmI0OjMwOmZlOjUwOjc0OmFjOmQ2OjlkOjFkOmUwOgorICAgICAgICAgICAgICAgICAgICA2MjpjNjo0OTpkZDoxNDoxMjo3ZDo3MTowYjphYzowNjpjMTozZjpkNzowNjoKKyAgICAgICAgICAgICAgICAgICAgODc6ZTA6OTA6ODk6ZDY6ZTU6ZTM6MDM6YjI6ZjI6Mjc6YjE6OWY6MzM6Yzg6CisgICAgICAgICAgICAgICAgICAgIGFhOjZiOjM2OjRhOmEzOmM0OjNmOjc5OjQxOjlkOjg5OjQ2OjJmOjJiOjNlOgorICAgICAgICAgICAgICAgICAgICA2MzpkNDozODo1Njo5MTphYToxZDpiMTowZDo0Mjo3NTo0ZDpmMzo4Nzo0ZToKKyAgICAgICAgICAgICAgICAgICAgZTM6MGY6NGQ6Y2M6YjQ6NmM6YmY6NjI6MTM6ODc6ZWE6ZDA6OWI6OGU6YjY6CisgICAgICAgICAgICAgICAgICAgIGUyOmZmOjE5OmY0Ojk0OjA5OmQ1Ojk2OjYxCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDMgKDB4MykKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBOZXRzY2FwZSBDZXJ0IFR5cGU6IAorICAgICAgICAgICAgICAgIFNTTCBDQSwgUy9NSU1FIENBLCBPYmplY3QgU2lnbmluZyBDQQorICAgICAgICAgICAgWDUwOXYzIENSTCBEaXN0cmlidXRpb24gUG9pbnRzOiAKKyAgICAgICAgICAgICAgICBEaXJOYW1lOi9DPUVTL089Rk5NVC9PVT1GTk1UIENsYXNlIDIgQ0EvQ049Q1JMMQorCisgICAgICAgICAgICBYNTA5djMgUHJpdmF0ZSBLZXkgVXNhZ2UgUGVyaW9kOiAKKyAgICAgICAgICAgICAgICBOb3QgQmVmb3JlOiBNYXIgMTggMTQ6NTY6MTkgMTk5OSBHTVQsIE5vdCBBZnRlcjogTWFyIDE4IDE0OjU2OjE5IDIwMTkgR01UCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiAKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6NDA6OUE6NzY6NDQ6OTc6NzQ6MDc6QzQ6QUM6MTQ6Q0I6MUU6OEQ6NEY6M0E6NDU6N0M6MzA6RDc6NjEKKworICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDQwOjlBOjc2OjQ0Ojk3Ojc0OjA3OkM0OkFDOjE0OkNCOjFFOjhEOjRGOjNBOjQ1OjdDOjMwOkQ3OjYxCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIDEuMi44NDAuMTEzNTMzLjcuNjUuMDogCisgICAgICAgICAgICAgICAgMAorLi5WNC4wLi4uLgorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA2MTo0YzphMDo3Yzo1OTo2Mzo1Yjo2NjpmODplZTo2NToxMzpjZTo0Mzo4MDo0NzpiOTpiMjoKKyAgICAgICAgMzU6Yzk6Yzg6ODQ6Yzc6NmI6NzM6NjA6NDU6ZTQ6OWQ6Mzc6OWQ6ZjU6OGU6MjU6Yjk6Zjk6CisgICAgICAgIGFhOmFhOmNhOmUzOmY4OjQzOjljOjJmOmEwOjg5OjA1OmIxOjQ1OjMyOjk0OjJhOjFlOjAzOgorICAgICAgICA4ZDo1ZDphNjpkZTpjZjo1Nzo5NTpkYTpkZjoyNjo2MDo1ZjpjYjpkZjo5NToxZTpiODpjZToKKyAgICAgICAgMDg6ZDg6Zjg6OGE6Yzk6NGY6YTk6Njg6NzU6OTM6ZTM6MmY6MDU6NGM6NjQ6NjA6MDI6YTI6CisgICAgICAgIDQyOjFlOjZmOjg2OjY4OjY1OjU1OjBlOmQ4OjQzOjZmOmYyOjkxOjMxOjNlOmEzOjQ3OjNjOgorICAgICAgICAyODowNTphZjo0NTpiNjo5ZDoyMjo0YzoyNjo3Yjo0Yjo3ZDo1YjoxNTpmOToxOTo0NjpkZjoKKyAgICAgICAgMDg6NWQKK1NIQTEgRmluZ2VycHJpbnQ9NDM6Rjk6QjE6MTA6RDU6QkE6RkQ6NDg6MjI6NTI6MzE6QjA6RDA6MDg6MkI6Mzc6MkY6RUY6OUE6NTQKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8xZGNkNmY0Yy4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzFkY2Q2ZjRjLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjA5ZDRkNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8xZGNkNmY0Yy4wCkBAIC0wLDAgKzEsMTIxIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUZjakNDQTFxZ0F3SUJBZ0lRSDUxWld0Y3Z3Z1pFcFlBSWFlTmU5akFOQmdrcWhraUc5dzBCQVFVRkFEQS8KK01Rc3dDUVlEVlFRR0V3SlVWekV3TUM0R0ExVUVDZ3duUjI5MlpYSnViV1Z1ZENCU2IyOTBJRU5sY25ScFptbGoKK1lYUnBiMjRnUVhWMGFHOXlhWFI1TUI0WERUQXlNVEl3TlRFek1qTXpNMW9YRFRNeU1USXdOVEV6TWpNek0xb3cKK1B6RUxNQWtHQTFVRUJoTUNWRmN4TURBdUJnTlZCQW9NSjBkdmRtVnlibTFsYm5RZ1VtOXZkQ0JEWlhKMGFXWnAKK1kyRjBhVzl1SUVGMWRHaHZjbWwwZVRDQ0FpSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnSVBBRENDQWdvQ2dnSUIKK0FKb2x1T3pNb25Xb2UvZk9XMW1LeWRHR0VnaFU3Snp5NTBiMmlQTjg2YVhmVEVjMnBCc0JISDhlVjRxTnc4WFIKK0llUGFKRDlJSy91ZkxxR1U1eXdjazlHL0d3R0hVNW5PcC9VS0lYWjMvNm0zeG5PVVQwYjNFRWszK3FoWlNWMXEKK2dRZFc4b3I1QnREM2NDSk50TGRCdVRLNHNmQ3h3NXcvY1AxVDNZR3EyR040OXRoVGJxR3Nhb1FrY2xTR3h0S3kKK3lod09lWUhXdFhCaUNBRXVUazhPMVJHdnFhL2xtci9jeklkdEp1VEpWNkw3bHZuTTRUOVRqR3hNZnB0VENBdHMKK0YvdG55TUt0c2MyQXRKZmNkZ0VXRmVscTE2VGhlRWZPaHRYN01mUDZNYjQwcWlqN2NFd2RTY2V2TEoxdFpxYTIKK2pXUit0U0JxblR1QnRvOUFBR2RMaVlhNHpHWCtGVlBwQk1IV1h4MUUxd292SjVwR2ZhRU5kYTFVaGhYY1NUdngKK2xzNFBtNkRzbzNwZHZ0VXFkVUxsZTk2bHRxcXZLS3lza0t3NHQ5Vm9OU1o2M1BjNzgvMUZtOUc3UTNodWIvRkMKK1ZHcVk4QTJ0bCtsU1h1blZhbkxlYXZjYllCVDBwZVMyY1dlcUgrcmlUY0ZDUVA1blJoYzRMMGMvY1p5dTVTSEsKK1lTMXRCNmlFZkMzdVVTWHhZNUNlL2VGWGlHdnZpaU50c2VhOVA2M1JQWllMaFkzTmF5ZTd0d1diN0x1UnFRb0gKK0VnS1hUaUNROFA4Tkh1SkJPOU5BT3VlTlhkcG01QUt3QjFLWVhBNk9NNXpDcHBYN1ZSbHVUSTZ1U3crOXdUaE4KK1hvK0VIV2JOeFdDV3RGSmFCWW1PbFhxWXdaRThsU095RHZSNXRNbDh3VW9oQWdNQkFBR2phakJvTUIwR0ExVWQKK0RnUVdCQlRNek8vTUtXQ2tPN0dTdGp6Nk1tS1ByQ1VWT3pBTUJnTlZIUk1FQlRBREFRSC9NRGtHQkdjcUJ3QUUKK01UQXZNQzBDQVFBd0NRWUZLdzREQWhvRkFEQUhCZ1ZuS2dNQUFBUVVBNXZ3SWhQL2xTZzIwOXlld0RMN01UcUsKK1VXVXdEUVlKS29aSWh2Y05BUUVGQlFBRGdnSUJBRUNBU3ZvbXljNWVNTjFQaG5SMldQV3VzNE16ZUtSNmRCY1oKK1R1bFN0Ym5nQ25SaXFtaktlS0JNbW80c0l5N1ZhaElrdjlSbzA0clEySnlmdEI4TTNqaCtWemo4amVKUFhneWYKK3F6dlMvM1dYeTZUalp3ai81Y0FXdFVnQmZlbjVDdjhiNVdwcHYzZ2hxTUtuSTZtR3EzWlc2QTRNOWhQZEttYUsKK1pFazlHaGlIa0FTZlFsSzNUOHYrUjBGMk5lLy9BSFkyUlRLYnhrYUZYZUlrc0I3alNKYVlWMGVVVlhvUFFiRkUKK0pQUEIvaHBydjRqOXdhYmFrMkJlZ1VxWklKeElaaG0xQUhsVUQ3Z3NMMHU4cVYxYllIK01oNlhnVW1NcXZ0ZzcKK2hVQVYvaDYyWlQvRlM5cCt0WG8xS2FNdWVwaGdJcVAwZlNkT0xlcTBkRHpwRDZRekR4QVJ2Qk1CMXVVTzA3KzEKK0VxTGhSU1BBekFodVliZUpxNFBqSkI3bVhRZm5IeUErejJmSTU2d3diU2RMYUc1TEtsd0NDRFRiK0hia1o2TW0KK25EK2lNc0pLeFlFWU1SQldxb1R2TFFyL3VCOTMwcitsV0tCaTVOZExrWFdOaVlDWWZtM0xVMDVlci9heWw0V1gKK3VkcFZCcmtrN3RmR09CNWpHeEk3bGVGWXJQTGZoTlZmbVM4TlZWdm1PTnN1UDNMcFNJWEx1eWtUang0NFZibnoKK3NzUXdtU05PWGZKSW9SSU0zQktRQ1pCVWtRTThSK1hWeVdYZ3QwdDk3RWZUc3dzK3JaN1FkQUFPNjcxUnJjRGUKK0xNRERhdjd2M0F1bitrYmZZTnVjcGxsUWRTTnBjNU95K2Z3QzAwZm1jYzRRQXU0bmpJVC9yRVVORTF5RE11QWwKK3BZWXNmUFFTCistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICAxZjo5ZDo1OTo1YTpkNzoyZjpjMjowNjo0NDphNTo4MDowODo2OTplMzo1ZTpmNgorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVRXLCBPPUdvdmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogRGVjICA1IDEzOjIzOjMzIDIwMDIgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBEZWMgIDUgMTM6MjM6MzMgMjAzMiBHTVQKKyAgICAgICAgU3ViamVjdDogQz1UVywgTz1Hb3Zlcm5tZW50IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICg0MDk2IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICg0MDk2IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOjlhOjI1OmI4OmVjOmNjOmEyOjc1OmE4OjdiOmY3OmNlOjViOjU5OjhhOgorICAgICAgICAgICAgICAgICAgICBjOTpkMTo4NjoxMjowODo1NDplYzo5YzpmMjplNzo0NjpmNjo4ODpmMzo3YzoKKyAgICAgICAgICAgICAgICAgICAgZTk6YTU6ZGY6NGM6NDc6MzY6YTQ6MWI6MDE6MWM6N2Y6MWU6NTc6OGE6OGQ6CisgICAgICAgICAgICAgICAgICAgIGMzOmM1OmQxOjIxOmUzOmRhOjI0OjNmOjQ4OjJiOmZiOjlmOjJlOmExOjk0OgorICAgICAgICAgICAgICAgICAgICBlNzoyYzoxYzo5MzpkMTpiZjoxYjowMTo4Nzo1Mzo5OTpjZTphNzpmNTowYToKKyAgICAgICAgICAgICAgICAgICAgMjE6NzY6Nzc6ZmY6YTk6Yjc6YzY6NzM6OTQ6NGY6NDY6Zjc6MTA6NDk6Mzc6CisgICAgICAgICAgICAgICAgICAgIGZhOmE4OjU5OjQ5OjVkOjZhOjgxOjA3OjU2OmYyOjhhOmY5OjA2OmQwOmY3OgorICAgICAgICAgICAgICAgICAgICA3MDoyMjo0ZDpiNDpiNzo0MTpiOTozMjpiODpiMTpmMDpiMTpjMzo5YzozZjoKKyAgICAgICAgICAgICAgICAgICAgNzA6ZmQ6NTM6ZGQ6ODE6YWE6ZDg6NjM6Nzg6ZjY6ZDg6NTM6NmU6YTE6YWM6CisgICAgICAgICAgICAgICAgICAgIDZhOjg0OjI0OjcyOjU0Ojg2OmM2OmQyOmIyOmNhOjFjOjBlOjc5OjgxOmQ2OgorICAgICAgICAgICAgICAgICAgICBiNTo3MDo2MjowODowMToyZTo0ZTo0ZjowZTpkNToxMTphZjphOTphZjplNToKKyAgICAgICAgICAgICAgICAgICAgOWE6YmY6ZGM6Y2M6ODc6NmQ6MjY6ZTQ6Yzk6NTc6YTI6ZmI6OTY6Zjk6Y2M6CisgICAgICAgICAgICAgICAgICAgIGUxOjNmOjUzOjhjOjZjOjRjOjdlOjliOjUzOjA4OjBiOjZjOjE3OmZiOjY3OgorICAgICAgICAgICAgICAgICAgICBjODpjMjphZDpiMTpjZDo4MDpiNDo5NzpkYzo3NjowMToxNjoxNTplOTo2YToKKyAgICAgICAgICAgICAgICAgICAgZDc6YTQ6ZTE6Nzg6NDc6Y2U6ODY6ZDU6ZmI6MzE6ZjM6ZmE6MzE6YmU6MzQ6CisgICAgICAgICAgICAgICAgICAgIGFhOjI4OmZiOjcwOjRjOjFkOjQ5OmM3OmFmOjJjOjlkOjZkOjY2OmE2OmI2OgorICAgICAgICAgICAgICAgICAgICA4ZDo2NDo3ZTpiNToyMDo2YTo5ZDozYjo4MTpiNjo4Zjo0MDowMDo2Nzo0YjoKKyAgICAgICAgICAgICAgICAgICAgODk6ODY6Yjg6Y2M6NjU6ZmU6MTU6NTM6ZTk6MDQ6YzE6ZDY6NWY6MWQ6NDQ6CisgICAgICAgICAgICAgICAgICAgIGQ3OjBhOjJmOjI3OjlhOjQ2OjdkOmExOjBkOjc1OmFkOjU0Ojg2OjE1OmRjOgorICAgICAgICAgICAgICAgICAgICA0OTozYjpmMTo5NjpjZTowZjo5YjphMDplYzphMzo3YTo1ZDpiZTpkNToyYToKKyAgICAgICAgICAgICAgICAgICAgNzU6NDI6ZTU6N2I6ZGU6YTU6YjY6YWE6YWY6Mjg6YWM6YWM6OTA6YWM6Mzg6CisgICAgICAgICAgICAgICAgICAgIGI3OmQ1OjY4OjM1OjI2OjdhOmRjOmY3OjNiOmYzOmZkOjQ1OjliOmQxOmJiOgorICAgICAgICAgICAgICAgICAgICA0Mzo3ODo2ZTo2ZjpmMTo0Mjo1NDo2YTo5ODpmMDowZDphZDo5NzplOTo1MjoKKyAgICAgICAgICAgICAgICAgICAgNWU6ZTk6ZDU6NmE6NzI6ZGU6NmE6Zjc6MWI6NjA6MTQ6ZjQ6YTU6ZTQ6YjY6CisgICAgICAgICAgICAgICAgICAgIDcxOjY3OmFhOjFmOmVhOmUyOjRkOmMxOjQyOjQwOmZlOjY3OjQ2OjE3OjM4OgorICAgICAgICAgICAgICAgICAgICAyZjo0NzozZjo3MTo5YzphZTplNToyMTpjYTo2MToyZDo2ZDowNzphODo4NDoKKyAgICAgICAgICAgICAgICAgICAgN2M6MmQ6ZWU6NTE6MjU6ZjE6NjM6OTA6OWU6ZmQ6ZTE6NTc6ODg6NmI6ZWY6CisgICAgICAgICAgICAgICAgICAgIDhhOjIzOjZkOmIxOmU2OmJkOjNmOmFkOmQxOjNkOjk2OjBiOjg1OjhkOmNkOgorICAgICAgICAgICAgICAgICAgICA2YjoyNzpiYjpiNzowNTo5YjplYzpiYjo5MTphOTowYTowNzoxMjowMjo5NzoKKyAgICAgICAgICAgICAgICAgICAgNGU6MjA6OTA6ZjA6ZmY6MGQ6MWU6ZTI6NDE6M2I6ZDM6NDA6M2E6ZTc6OGQ6CisgICAgICAgICAgICAgICAgICAgIDVkOmRhOjY2OmU0OjAyOmIwOjA3OjUyOjk4OjVjOjBlOjhlOjMzOjljOmMyOgorICAgICAgICAgICAgICAgICAgICBhNjo5NTpmYjo1NToxOTo2ZTo0Yzo4ZTphZTo0YjowZjpiZDpjMTozODo0ZDoKKyAgICAgICAgICAgICAgICAgICAgNWU6OGY6ODQ6MWQ6NjY6Y2Q6YzU6NjA6OTY6YjQ6NTI6NWE6MDU6ODk6OGU6CisgICAgICAgICAgICAgICAgICAgIDk1OjdhOjk4OmMxOjkxOjNjOjk1OjIzOmIyOjBlOmY0Ojc5OmI0OmM5OjdjOgorICAgICAgICAgICAgICAgICAgICBjMTo0YToyMQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgQ0M6Q0M6RUY6Q0M6Mjk6NjA6QTQ6M0I6QjE6OTI6QjY6M0M6RkE6MzI6NjI6OEY6QUM6MjU6MTU6M0IKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgc2V0Q2V4dC1oYXNoZWRSb290OiAKKyAgICAgICAgICAgICAgICAwLzAtLi4uMC4uLisuLi4uLi4wLi4uZyouLi4uLi4uLiIuLi4oNi4uLi4yLjE6LlFlCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDQwOjgwOjRhOmZhOjI2OmM5OmNlOjVlOjMwOmRkOjRmOjg2Ojc0Ojc2OjU4OmY1OmFlOmIzOgorICAgICAgICA4MzozMzo3ODphNDo3YTo3NDoxNzoxOTo0ZTplOTo1MjpiNTpiOTplMDowYTo3NDo2MjphYToKKyAgICAgICAgNjg6Y2E6Nzg6YTA6NGM6OWE6OGU6MmM6MjM6MmU6ZDU6NmE6MTI6MjQ6YmY6ZDQ6Njg6ZDM6CisgICAgICAgIDhhOmQwOmQ4OjljOjlmOmI0OjFmOjBjOmRlOjM4OjdlOjU3OjM4OmZjOjhkOmUyOjRmOjVlOgorICAgICAgICAwYzo5ZjphYjozYjpkMjpmZjo3NTo5NzpjYjphNDplMzo2NzowODpmZjplNTpjMDoxNjpiNToKKyAgICAgICAgNDg6MDE6N2Q6ZTk6Zjk6MGE6ZmY6MWI6ZTU6NmE6Njk6YmY6Nzg6MjE6YTg6YzI6YTc6MjM6CisgICAgICAgIGE5Ojg2OmFiOjc2OjU2OmU4OjBlOjBjOmY2OjEzOmRkOjJhOjY2OjhhOjY0OjQ5OjNkOjFhOgorICAgICAgICAxODo4Nzo5MDowNDo5Zjo0Mjo1MjpiNzo0ZjpjYjpmZTo0Nzo0MTo3NjozNTplZjpmZjowMDoKKyAgICAgICAgNzY6MzY6NDU6MzI6OWI6YzY6NDY6ODU6NWQ6ZTI6MjQ6YjA6MWU6ZTM6NDg6OTY6OTg6NTc6CisgICAgICAgIDQ3Ojk0OjU1OjdhOjBmOjQxOmIxOjQ0OjI0OmYzOmMxOmZlOjFhOjZiOmJmOjg4OmZkOmMxOgorICAgICAgICBhNjpkYTo5Mzo2MDo1ZTo4MTo0YTo5OToyMDo5Yzo0ODo2NjoxOTpiNTowMDo3OTo1NDowZjoKKyAgICAgICAgYjg6MmM6MmY6NGI6YmM6YTk6NWQ6NWI6NjA6N2Y6OGM6ODc6YTU6ZTA6NTI6NjM6MmE6YmU6CisgICAgICAgIGQ4OjNiOjg1OjQwOjE1OmZlOjFlOmI2OjY1OjNmOmM1OjRiOmRhOjdlOmI1OjdhOjM1OjI5OgorICAgICAgICBhMzoyZTo3YTo5ODo2MDoyMjphMzpmNDo3ZDoyNzo0ZToyZDplYTpiNDo3NDozYzplOTowZjoKKyAgICAgICAgYTQ6MzM6MGY6MTA6MTE6YmM6MTM6MDE6ZDY6ZTU6MGU6ZDM6YmY6YjU6MTI6YTI6ZTE6NDU6CisgICAgICAgIDIzOmMwOmNjOjA4OjZlOjYxOmI3Ojg5OmFiOjgzOmUzOjI0OjFlOmU2OjVkOjA3OmU3OjFmOgorICAgICAgICAyMDozZTpjZjo2NzpjODplNzphYzozMDo2ZDoyNzo0Yjo2ODo2ZTo0YjoyYTo1YzowMjowODoKKyAgICAgICAgMzQ6ZGI6Zjg6NzY6ZTQ6Njc6YTM6MjY6OWM6M2Y6YTI6MzI6YzI6NGE6YzU6ODE6MTg6MzE6CisgICAgICAgIDEwOjU2OmFhOjg0OmVmOjJkOjBhOmZmOmI4OjFmOjc3OmQyOmJmOmE1OjU4OmEwOjYyOmU0OgorICAgICAgICBkNzo0Yjo5MTo3NTo4ZDo4OTo4MDo5ODo3ZTo2ZDpjYjo1Mzo0ZTo1ZTphZjpmNjpiMjo5NzoKKyAgICAgICAgODU6OTc6Yjk6ZGE6NTU6MDY6Yjk6MjQ6ZWU6ZDc6YzY6Mzg6MWU6NjM6MWI6MTI6M2I6OTU6CisgICAgICAgIGUxOjU4OmFjOmYyOmRmOjg0OmQ1OjVmOjk5OjJmOjBkOjU1OjViOmU2OjM4OmRiOjJlOjNmOgorICAgICAgICA3MjplOTo0ODo4NTpjYjpiYjoyOToxMzo4ZjoxZTozODo1NTpiOTpmMzpiMjpjNDozMDo5OToKKyAgICAgICAgMjM6NGU6NWQ6ZjI6NDg6YTE6MTI6MGM6ZGM6MTI6OTA6MDk6OTA6NTQ6OTE6MDM6M2M6NDc6CisgICAgICAgIGU1OmQ1OmM5OjY1OmUwOmI3OjRiOjdkOmVjOjQ3OmQzOmIzOjBiOjNlOmFkOjllOmQwOjc0OgorICAgICAgICAwMDowZTplYjpiZDo1MTphZDpjMDpkZToyYzpjMDpjMzo2YTpmZTplZjpkYzowYjphNzpmYToKKyAgICAgICAgNDY6ZGY6NjA6ZGI6OWM6YTY6NTk6NTA6NzU6MjM6Njk6NzM6OTM6YjI6Zjk6ZmM6MDI6ZDM6CisgICAgICAgIDQ3OmU2OjcxOmNlOjEwOjAyOmVlOjI3OjhjOjg0OmZmOmFjOjQ1OjBkOjEzOjVjOjgzOjMyOgorICAgICAgICBlMDoyNTphNTo4NjoyYzo3YzpmNDoxMgorU0hBMSBGaW5nZXJwcmludD1GNDo4QjoxMTpCRjpERTpBQjpCRTo5NDo1NDoyMDo3MTpFNjo0MTpERTo2QjpCRTo4ODoyQjo0MDpCOQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzFkZjVlYzQ3LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMWRmNWVjNDcuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNTZjN2EzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzFkZjVlYzQ3LjAKQEAgLTAsMCArMSw4NCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlENFRDQ0FzbWdBd0lCQWdJT1l5VUFBUUFDRkkwekZRTGtiUFF3RFFZSktvWklodmNOQVFFRkJRQXdlekVMCitNQWtHQTFVRUJoTUNSRVV4SERBYUJnTlZCQW9URTFSRElGUnlkWE4wUTJWdWRHVnlJRWR0WWtneEpEQWlCZ05WCitCQXNURzFSRElGUnlkWE4wUTJWdWRHVnlJRlZ1YVhabGNuTmhiQ0JEUVRFb01DWUdBMVVFQXhNZlZFTWdWSEoxCitjM1JEWlc1MFpYSWdWVzVwZG1WeWMyRnNJRU5CSUVsSlNUQWVGdzB3T1RBNU1Ea3dPREUxTWpkYUZ3MHlPVEV5CitNekV5TXpVNU5UbGFNSHN4Q3pBSkJnTlZCQVlUQWtSRk1Sd3dHZ1lEVlFRS0V4TlVReUJVY25WemRFTmxiblJsCitjaUJIYldKSU1TUXdJZ1lEVlFRTEV4dFVReUJVY25WemRFTmxiblJsY2lCVmJtbDJaWEp6WVd3Z1EwRXhLREFtCitCZ05WQkFNVEgxUkRJRlJ5ZFhOMFEyVnVkR1Z5SUZWdWFYWmxjbk5oYkNCRFFTQkpTVWt3Z2dFaU1BMEdDU3FHCitTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFEQzJweGlzTGx4RXJBTHlCcFhzcTZERkptek5FdWJrS0xGCis1K2N2QXFCTkxhVDZoZHFiSllVdFFDZ2diZXJndmJGSWd5SXBSSjlPZys0MVVSTnpkTlc4OGpCbWxGUEFRRFl2CitESVJsemc5dXdsaVQ2Q3dMT3VuQmp2dnlhOG84NHB4T2p1VDVmZE1ubnh2VlozaUhMWDhMUjdQSDZNbElmSzh2Cit6QXJaUWUrZi9wcmhzcTc1VTdYbDZVYWZZT1BmamROLys1WitzN1Z5K0V1dENIbk5hWWxBSi9VcXdhMUQ3S1JUCit5R0cyOTlKNUttY1lka2h0V3lVQjBTYkZ0MWRwSXhWYllZcXQ4QnN0MmE5YzhTYVFhYW5WREVEMU00QkRqNXlqCitkaXBGdEsrL2Z6NkhQM2JGelNyZUlNVVdXTXY1Ry9VUHl3MFJVbVM0MG5aaWQ0UHhXSi8vQWdNQkFBR2pZekJoCitNQjhHQTFVZEl3UVlNQmFBRkZibjRWc2xRNERnOW96aGNieU81WUF2eEVqaU1BOEdBMVVkRXdFQi93UUZNQU1CCitBZjh3RGdZRFZSMFBBUUgvQkFRREFnRUdNQjBHQTFVZERnUVdCQlJXNStGYkpVT0E0UGFNNFhHOGp1V0FMOFJJCis0akFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBZzhldjZuOU5Danc1c1dpK2UyMkpMdW16Q2VjWVY0MkZtaGZ6Citka0pRRXcvSGtHOHpyY1ZKWUN0c1NWZ1oxT0srdDcrclNieVV5S3UrS0d3V2FPRElsMFlnb0dobllJZzVJRkhZCithQUVSenFmMkVRZjI3T3lzR2greVptNVdaMkI2ZEY3QWJaYzJyclVOWFdaendDVXlSZGhLQmdlUHhMY0hzVTBHCitEZUdsNi9SMXlycWMwTDJ6MHpJa1RPNSs0bllFUzBsVDJQTHBWRFA4NVhFZlBSUmNsa3Z4T3ZJQXUyeTArcFpWCitDSWdKd2N5UkdTbXdJQzMveXppa1FPRVh2bmxoZ1A4SEE0Wk1UbnNHbnhHR2pZbnVKOFRiNHJ3WmpndkR3eFBICitMUU5qTzlQbzVLSXF3b0lJbEJaVThPOGZKNUFsdUEwT0tCdEhkMGU5SEtnbDhaUzBaZz09CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICA2MzoyNTowMDowMTowMDowMjoxNDo4ZDozMzoxNTowMjplNDo2YzpmNAorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPURFLCBPPVRDIFRydXN0Q2VudGVyIEdtYkgsIE9VPVRDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSwgQ049VEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogU2VwICA5IDA4OjE1OjI3IDIwMDkgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBEZWMgMzEgMjM6NTk6NTkgMjAyOSBHTVQKKyAgICAgICAgU3ViamVjdDogQz1ERSwgTz1UQyBUcnVzdENlbnRlciBHbWJILCBPVT1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EsIENOPVRDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmMyOmRhOjljOjYyOmIwOmI5OjcxOjEyOmIwOjBiOmM4OjFhOjU3OmIyOgorICAgICAgICAgICAgICAgICAgICBhZTo4MzoxNDo5OTpiMzozNDo0Yjo5Yjo5MDphMjpjNTplNzplNzoyZjowMjoKKyAgICAgICAgICAgICAgICAgICAgYTA6NGQ6MmQ6YTQ6ZmE6ODU6ZGE6OWI6MjU6ODU6MmQ6NDA6Mjg6MjA6NmQ6CisgICAgICAgICAgICAgICAgICAgIGVhOmUwOmJkOmIxOjQ4OjgzOjIyOjI5OjQ0OjlmOjRlOjgzOmVlOjM1OjUxOgorICAgICAgICAgICAgICAgICAgICAxMzo3Mzo3NDpkNTpiYzpmMjozMDo2Njo5NDo1MzpjMDo0MDozNjoyZjowYzoKKyAgICAgICAgICAgICAgICAgICAgODQ6NjU6Y2U6MGY6NmU6YzI6NTg6OTM6ZTg6MmM6MGI6M2E6ZTk6YzE6OGU6CisgICAgICAgICAgICAgICAgICAgIGZiOmYyOjZiOmNhOjNjOmUyOjljOjRlOjhlOmU0OmY5OjdkOmQzOjI3OjlmOgorICAgICAgICAgICAgICAgICAgICAxYjpkNTo2Nzo3ODo4NzoyZDo3ZjowYjo0NzpiMzpjNzplODpjOTo0ODo3YzoKKyAgICAgICAgICAgICAgICAgICAgYWY6MmY6Y2M6MGE6ZDk6NDE6ZWY6OWY6ZmU6OWE6ZTE6YjI6YWU6Zjk6NTM6CisgICAgICAgICAgICAgICAgICAgIGI1OmU1OmU5OjQ2OjlmOjYwOmUzOmRmOjhkOmQzOjdmOmZiOjk2OjdlOmIzOgorICAgICAgICAgICAgICAgICAgICBiNTo3MjpmODo0YjphZDowODo3OTpjZDo2OTo4OTo0MDoyNzpmNToyYTpjMToKKyAgICAgICAgICAgICAgICAgICAgYWQ6NDM6ZWM6YTQ6NTM6Yzg6NjE6YjY6Zjc6ZDI6Nzk6MmE6Njc6MTg6NzY6CisgICAgICAgICAgICAgICAgICAgIDQ4OjZkOjViOjI1OjAxOmQxOjI2OmM1OmI3OjU3OjY5OjIzOjE1OjViOjYxOgorICAgICAgICAgICAgICAgICAgICA4YTphZDpmMDoxYjoyZDpkOTphZjo1YzpmMToyNjo5MDo2OTphOTpkNTowYzoKKyAgICAgICAgICAgICAgICAgICAgNDA6ZjU6MzM6ODA6NDM6OGY6OWM6YTM6NzY6MmE6NDU6YjQ6YWY6YmY6N2Y6CisgICAgICAgICAgICAgICAgICAgIDNlOjg3OjNmOjc2OmM1OmNkOjJhOmRlOjIwOmM1OjE2OjU4OmNiOmY5OjFiOgorICAgICAgICAgICAgICAgICAgICBmNTowZjpjYjowZDoxMTo1Mjo2NDpiODpkMjo3Njo2Mjo3Nzo4MzpmMTo1ODoKKyAgICAgICAgICAgICAgICAgICAgOWY6ZmYKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6NTY6RTc6RTE6NUI6MjU6NDM6ODA6RTA6RjY6OEM6RTE6NzE6QkM6OEU6RTU6ODA6MkY6QzQ6NDg6RTIKKworICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICA1NjpFNzpFMTo1QjoyNTo0Mzo4MDpFMDpGNjo4QzpFMTo3MTpCQzo4RTpFNTo4MDoyRjpDNDo0ODpFMgorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA4MzpjNzphZjplYTo3Zjo0ZDowYTozYzozOTpiMTo2ODpiZTo3Yjo2ZDo4OToyZTplOTpiMzoKKyAgICAgICAgMDk6ZTc6MTg6NTc6OGQ6ODU6OWE6MTc6ZjM6NzY6NDI6NTA6MTM6MGY6Yzc6OTA6NmY6MzM6CisgICAgICAgIGFkOmM1OjQ5OjYwOjJiOjZjOjQ5OjU4OjE5OmQ0OmUyOmJlOmI3OmJmOmFiOjQ5OmJjOjk0OgorICAgICAgICBjODphYjpiZToyODo2YzoxNjo2ODplMDpjODo5Nzo0NjoyMDphMDo2ODo2Nzo2MDo4ODozOToKKyAgICAgICAgMjA6NTE6ZDg6Njg6MDE6MTE6Y2U6YTc6ZjY6MTE6MDc6ZjY6ZWM6ZWM6YWM6MWE6MWY6YjI6CisgICAgICAgIDY2OjZlOjU2OjY3OjYwOjdhOjc0OjVlOmMwOjZkOjk3OjM2OmFlOmI1OjBkOjVkOjY2OjczOgorICAgICAgICBjMDoyNTozMjo0NTpkODo0YTowNjowNzo4ZjpjNDpiNzowNzpiMTo0ZDowNjowZDplMTphNToKKyAgICAgICAgZWI6ZjQ6NzU6Y2E6YmE6OWM6ZDA6YmQ6YjM6ZDM6MzI6MjQ6NGM6ZWU6N2U6ZTI6NzY6MDQ6CisgICAgICAgIDRiOjQ5OjUzOmQ4OmYyOmU5OjU0OjMzOmZjOmU1OjcxOjFmOjNkOjE0OjVjOjk2OjRiOmYxOgorICAgICAgICAzYTpmMjowMDpiYjo2YzpiNDpmYTo5Njo1NTowODo4ODowOTpjMTpjYzo5MToxOToyOTpiMDoKKyAgICAgICAgMjA6MmQ6ZmY6Y2I6Mzg6YTQ6NDA6ZTE6MTc6YmU6Nzk6NjE6ODA6ZmY6MDc6MDM6ODY6NGM6CisgICAgICAgIDRlOjdiOjA2OjlmOjExOjg2OjhkOjg5OmVlOjI3OmM0OmRiOmUyOmJjOjE5OjhlOjBiOmMzOgorICAgICAgICBjMzoxMzpjNzoyZDowMzo2MzozYjpkMzplODplNDphMjoyYTpjMjo4MjowODo5NDoxNjo1NDoKKyAgICAgICAgZjA6ZWY6MWY6Mjc6OTA6MjU6Yjg6MGQ6MGU6Mjg6MWI6NDc6Nzc6NDc6YmQ6MWM6YTg6MjU6CisgICAgICAgIGYxOjk0OmI0OjY2CitTSEExIEZpbmdlcnByaW50PTk2OjU2OkNEOjdCOjU3Ojk2Ojk4Ojk1OkQwOkUxOjQxOjQ2OjY4OjA2OkZCOkI4OkM2OjExOjA2Ojg3CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMWU4ZTcyMDEuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8xZThlNzIwMS4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA4NmQ1NGYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMWU4ZTcyMDEuMApAQCAtMCwwICsxLDc5IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSURYekNDQWtlZ0F3SUJBZ0lMQkFBQUFBQUJJVmhUQ0tJd0RRWUpLb1pJaHZjTkFRRUxCUUF3VERFZ01CNEcKK0ExVUVDeE1YUjJ4dlltRnNVMmxuYmlCU2IyOTBJRU5CSUMwZ1VqTXhFekFSQmdOVkJBb1RDa2RzYjJKaGJGTnAKK1oyNHhFekFSQmdOVkJBTVRDa2RzYjJKaGJGTnBaMjR3SGhjTk1Ea3dNekU0TVRBd01EQXdXaGNOTWprd016RTQKK01UQXdNREF3V2pCTU1TQXdIZ1lEVlFRTEV4ZEhiRzlpWVd4VGFXZHVJRkp2YjNRZ1EwRWdMU0JTTXpFVE1CRUcKK0ExVUVDaE1LUjJ4dlltRnNVMmxuYmpFVE1CRUdBMVVFQXhNS1IyeHZZbUZzVTJsbmJqQ0NBU0l3RFFZSktvWkkKK2h2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTXdsZHBCNUJuZ2lGdlhBZzdhRXlpaWUvUVYyRWNXdGlITDgKK1JnSkR4N0tLblFSZkpNc3VTK0ZnZ2tiaFVxc01nVWR3Yk4xazBldjFMS01QZ2owTUs2NlgxN1lVaGhCNXV6c1QKK2dIZU1DT0ZKMG1waUx4OWUrcFpvMzRrbmxUaWZCdGMreWNzbVdRMXozckRJNlNZT2d4WEc3MXVMMGdSZ3lrbW0KK0tQWnBPL2JMeUNpUjVaMktZVmMzckhRVTNIVGdPdTV5THk2Yys5Qzd2L1U5QU9FR00raUNLNjVUcGpvV2M0emQKK1FRNGdPc0MwcDZIcHNrK1FMakpnNlZmTHVRU1NhR2psT0NaZ2RiS2ZkLytSRk8rdUlFbjhyVUFWU05FQ01XRVoKK1hyaVg3NjEzdDJTYWVyOWZ3UlB2bTJMN0RXemdWR2tXcVFQYWJ1bURrM0YyeG1tRmdoY0NBd0VBQWFOQ01FQXcKK0RnWURWUjBQQVFIL0JBUURBZ0VHTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRkkvd1MzK28KK0xrVWtyazFRK21PYWk5N2kzUnU4TUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFCTFFOdkFVS3IreUF6djk1WlUKK1JVbTdsZ0FKUWF5ekU0YUdLQWN6eW12bWRMbTZBQzJ1cEFyVDlmSHhENHEvYzJkS2c4ZEVlM2pncjI1c2J3TXAKK2pqTTVSY09PNUxsWGJLcjhFcGJzVThZdDVDUnN1WlJqKzl4VGFHZFdQb080enpVaHc4bG8vczdhd2xPcXpKQ0sKKzZmQmRSb3lWM1hwWUtCb3ZIZDdOQURkQmorMUViZGRUS0pkKzgyY0VIaFhYaXBhMDA5NU1KNlJNRzNOemR2UVgKK21jSWZlZzdqTFFpdENod3MvenlyVlE0UGtYNDI2OE5YU2I3aExpMThZSXZEUVZFVEk1M085ekpybEFHb21lY3MKK014ODZPeVhTaGtET095eUdlTWxoTHhTNjd0dFZiOStFN2dVSlRiMG8ySExPMDJKUVpSN3JrcGVETWRtenRjcEgKK1dEOWYKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDA0OjAwOjAwOjAwOjAwOjAxOjIxOjU4OjUzOjA4OmEyCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTI1NldpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogT1U9R2xvYmFsU2lnbiBSb290IENBIC0gUjMsIE89R2xvYmFsU2lnbiwgQ049R2xvYmFsU2lnbgorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTWFyIDE4IDEwOjAwOjAwIDIwMDkgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBNYXIgMTggMTA6MDA6MDAgMjAyOSBHTVQKKyAgICAgICAgU3ViamVjdDogT1U9R2xvYmFsU2lnbiBSb290IENBIC0gUjMsIE89R2xvYmFsU2lnbiwgQ049R2xvYmFsU2lnbgorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6Y2M6MjU6NzY6OTA6Nzk6MDY6Nzg6MjI6MTY6ZjU6YzA6ODM6YjY6ODQ6CisgICAgICAgICAgICAgICAgICAgIGNhOjI4OjllOmZkOjA1Ojc2OjExOmM1OmFkOjg4OjcyOmZjOjQ2OjAyOjQzOgorICAgICAgICAgICAgICAgICAgICBjNzpiMjo4YTo5ZDowNDo1ZjoyNDpjYjoyZTo0YjplMTo2MDo4Mjo0NjplMToKKyAgICAgICAgICAgICAgICAgICAgNTI6YWI6MGM6ODE6NDc6NzA6NmM6ZGQ6NjQ6ZDE6ZWI6ZjU6MmM6YTM6MGY6CisgICAgICAgICAgICAgICAgICAgIDgyOjNkOjBjOjJiOmFlOjk3OmQ3OmI2OjE0Ojg2OjEwOjc5OmJiOjNiOjEzOgorICAgICAgICAgICAgICAgICAgICA4MDo3Nzo4YzowODplMTo0OTpkMjo2YTo2MjoyZjoxZjo1ZTpmYTo5Njo2ODoKKyAgICAgICAgICAgICAgICAgICAgZGY6ODk6Mjc6OTU6Mzg6OWY6MDY6ZDc6M2U6Yzk6Y2I6MjY6NTk6MGQ6NzM6CisgICAgICAgICAgICAgICAgICAgIGRlOmIwOmM4OmU5OjI2OjBlOjgzOjE1OmM2OmVmOjViOjhiOmQyOjA0OjYwOgorICAgICAgICAgICAgICAgICAgICBjYTo0OTphNjoyODpmNjo2OTozYjpmNjpjYjpjODoyODo5MTplNTo5ZDo4YToKKyAgICAgICAgICAgICAgICAgICAgNjE6NTc6Mzc6YWM6NzQ6MTQ6ZGM6NzQ6ZTA6M2E6ZWU6NzI6MmY6MmU6OWM6CisgICAgICAgICAgICAgICAgICAgIGZiOmQwOmJiOmJmOmY1OjNkOjAwOmUxOjA2OjMzOmU4OjgyOjJiOmFlOjUzOgorICAgICAgICAgICAgICAgICAgICBhNjozYToxNjo3Mzo4YzpkZDo0MTowZToyMDozYTpjMDpiNDphNzphMTplOToKKyAgICAgICAgICAgICAgICAgICAgYjI6NGY6OTA6MmU6MzI6NjA6ZTk6NTc6Y2I6Yjk6MDQ6OTI6Njg6Njg6ZTU6CisgICAgICAgICAgICAgICAgICAgIDM4OjI2OjYwOjc1OmIyOjlmOjc3OmZmOjkxOjE0OmVmOmFlOjIwOjQ5OmZjOgorICAgICAgICAgICAgICAgICAgICBhZDo0MDoxNTo0ODpkMTowMjozMTo2MToxOTo1ZTpiODo5NzplZjphZDo3NzoKKyAgICAgICAgICAgICAgICAgICAgYjc6NjQ6OWE6N2E6YmY6NWY6YzE6MTM6ZWY6OWI6NjI6ZmI6MGQ6NmM6ZTA6CisgICAgICAgICAgICAgICAgICAgIDU0OjY5OjE2OmE5OjAzOmRhOjZlOmU5OjgzOjkzOjcxOjc2OmM2OjY5Ojg1OgorICAgICAgICAgICAgICAgICAgICA4MjoxNworICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDhGOkYwOjRCOjdGOkE4OjJFOjQ1OjI0OkFFOjREOjUwOkZBOjYzOjlBOjhCOkRFOkUyOkREOjFCOkJDCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgNGI6NDA6ZGI6YzA6NTA6YWE6ZmU6Yzg6MGM6ZWY6Zjc6OTY6NTQ6NDU6NDk6YmI6OTY6MDA6CisgICAgICAgIDA5OjQxOmFjOmIzOjEzOjg2Ojg2OjI4OjA3OjMzOmNhOjZiOmU2Ojc0OmI5OmJhOjAwOjJkOgorICAgICAgICBhZTphNDowYTpkMzpmNTpmMTpmMTowZjo4YTpiZjo3Mzo2Nzo0YTo4MzpjNzo0NDo3Yjo3ODoKKyAgICAgICAgZTA6YWY6NmU6NmM6NmY6MDM6Mjk6OGU6MzM6Mzk6NDU6YzM6OGU6ZTQ6Yjk6NTc6NmM6YWE6CisgICAgICAgIGZjOjEyOjk2OmVjOjUzOmM2OjJkOmU0OjI0OjZjOmI5Ojk0OjYzOmZiOmRjOjUzOjY4OjY3OgorICAgICAgICA1NjozZTo4MzpiODpjZjozNToyMTpjMzpjOTo2ODpmZTpjZTpkYTpjMjo1MzphYTpjYzo5MDoKKyAgICAgICAgOGE6ZTk6ZjA6NWQ6NDY6OGM6OTU6ZGQ6N2E6NTg6Mjg6MWE6MmY6MWQ6ZGU6Y2Q6MDA6Mzc6CisgICAgICAgIDQxOjhmOmVkOjQ0OjZkOmQ3OjUzOjI4Ojk3OjdlOmYzOjY3OjA0OjFlOjE1OmQ3OjhhOjk2OgorICAgICAgICBiNDpkMzpkZTo0YzoyNzphNDo0YzoxYjo3Mzo3Mzo3NjpmNDoxNzo5OTpjMjoxZjo3YTowZToKKyAgICAgICAgZTM6MmQ6MDg6YWQ6MGE6MWM6MmM6ZmY6M2M6YWI6NTU6MGU6MGY6OTE6N2U6MzY6ZWI6YzM6CisgICAgICAgIDU3OjQ5OmJlOmUxOjJlOjJkOjdjOjYwOjhiOmMzOjQxOjUxOjEzOjIzOjlkOmNlOmY3OjMyOgorICAgICAgICA2Yjo5NDowMTphODo5OTplNzoyYzozMzoxZjozYTozYjoyNTpkMjo4Njo0MDpjZTozYjoyYzoKKyAgICAgICAgODY6Nzg6Yzk6NjE6MmY6MTQ6YmE6ZWU6ZGI6NTU6NmY6ZGY6ODQ6ZWU6MDU6MDk6NGQ6YmQ6CisgICAgICAgIDI4OmQ4OjcyOmNlOmQzOjYyOjUwOjY1OjFlOmViOjkyOjk3OjgzOjMxOmQ5OmIzOmI1OmNhOgorICAgICAgICA0Nzo1ODozZjo1ZgorU0hBMSBGaW5nZXJwcmludD1ENjo5Qjo1NjoxMTo0ODpGMDoxQzo3NzpDNTo0NTo3ODpDMTowOToyNjpERjo1Qjo4NTo2OTo3NjpBRApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzFlYjM3YmRmLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMWViMzdiZGYuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MTE5ZTNjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzFlYjM3YmRmLjAKQEAgLTAsMCArMSwxNDAgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJSFR6Q0NCVGVnQXdJQkFnSUpBS1BhUW42a3NhN2FNQTBHQ1NxR1NJYjNEUUVCQlFVQU1JR3VNUXN3Q1FZRAorVlFRR0V3SkZWVEZETUVFR0ExVUVCeE02VFdGa2NtbGtJQ2h6WldVZ1kzVnljbVZ1ZENCaFpHUnlaWE56SUdGMAorSUhkM2R5NWpZVzFsY21acGNtMWhMbU52YlM5aFpHUnlaWE56S1RFU01CQUdBMVVFQlJNSlFUZ3lOelF6TWpnMworTVJzd0dRWURWUVFLRXhKQlF5QkRZVzFsY21acGNtMWhJRk11UVM0eEtUQW5CZ05WQkFNVElFTm9ZVzFpWlhKegorSUc5bUlFTnZiVzFsY21ObElGSnZiM1FnTFNBeU1EQTRNQjRYRFRBNE1EZ3dNVEV5TWprMU1Gb1hEVE00TURjegorTVRFeU1qazFNRm93Z2E0eEN6QUpCZ05WQkFZVEFrVlZNVU13UVFZRFZRUUhFenBOWVdSeWFXUWdLSE5sWlNCagorZFhKeVpXNTBJR0ZrWkhKbGMzTWdZWFFnZDNkM0xtTmhiV1Z5Wm1seWJXRXVZMjl0TDJGa1pISmxjM01wTVJJdworRUFZRFZRUUZFd2xCT0RJM05ETXlPRGN4R3pBWkJnTlZCQW9URWtGRElFTmhiV1Z5Wm1seWJXRWdVeTVCTGpFcAorTUNjR0ExVUVBeE1nUTJoaGJXSmxjbk1nYjJZZ1EyOXRiV1Z5WTJVZ1VtOXZkQ0F0SURJd01EZ3dnZ0lpTUEwRworQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUUN2QU10d055dUFXa282YkhpVWZhTi9HaC8yTmRXOQorMjhzTlJISStKcktRVXJwak95aFliNld6YlpTbTg5MWtERlgyOXVmeUlpS0FYdUZpeHJZcDRZRnM4ci9sZlRKcQorVktBeUdWbitINHZYUFdDR2hTUnY0eEd6ZHo0Z2xqVWhhN01JMlhBdVpQZUVrbFBXRHJDUWlvcmpoNDBHMDcyUQorRHVLWm9SdUdEdHFhQ3JzTFlWQUdVdkdlZjNic3l3L1FIZzNQbVRBOUhNUkZFRmlzMXRQbzErWHF4UUVIZDlaUgorNWdOL2lraWxUV2gxdWVtOG5rNFpjZlV5UzV4dFlCa0wrOHlkZGR5L0pzMlBrM2c1ZVhOZUpRN0tYT3QzRWdmTAorWkVGSGNwT3JVTVByQ1haa05OSTV0M1lSQ1ExMlJjU3ByajFxcjdWOVpTK1VXQkRzWEh5dmZ1SzJHTm5RbTA1YQorU2QrcFpndk1QTVo0ZktlY0hlUE9qbE8rQmQ1Z0QydmxHdHMvNCtFaHlTbkI4ZXNIbkZJYkFVUlJQSHNsMThUbAorVWxSZEpRZktGaUM0cmVSQjdub0kvcGx2ZzZhUkFyQnNObFZxNTMzMWx1YktnZGFYOFpTRDZlMndzV3NTYVI2cworKzEycHhaanB0RnRZZXI0OW9rUTZZMW5VQ3lYZUcwKzk1UUdlemRJcDFaOFhHUXB2dnd5UTB3bGYyZU9LTmN4NQorV2swWk41SzN4TUd0ci9SNUpKcXlBUXV4cjF5Vzg0QXkrMXc5bVBHZ1AwcmV2cStVTHRsVm1oZHVZSjFqYkxoagoreWE2QlhCZzE0SkM3dmp4UE55SzVmdXZQbm5jaHBqMDRnZnRJMmpFOUsrT0o5ZEMxdlg3Z1VNUVNpYk1qbWhBeAoraGR1dWIrODRNeGgyRVFJREFRQUJvNElCYkRDQ0FXZ3dFZ1lEVlIwVEFRSC9CQWd3QmdFQi93SUJEREFkQmdOVgorSFE0RUZnUVUrU1NzRDdLMStIbkErbUNJRzhUWlRRS2VGeGt3Z2VNR0ExVWRJd1NCMnpDQjJJQVUrU1NzRDdLMQorK0huQSttQ0lHOFRaVFFLZUZ4bWhnYlNrZ2JFd2dhNHhDekFKQmdOVkJBWVRBa1ZWTVVNd1FRWURWUVFIRXpwTgorWVdSeWFXUWdLSE5sWlNCamRYSnlaVzUwSUdGa1pISmxjM01nWVhRZ2QzZDNMbU5oYldWeVptbHliV0V1WTI5dAorTDJGa1pISmxjM01wTVJJd0VBWURWUVFGRXdsQk9ESTNORE15T0RjeEd6QVpCZ05WQkFvVEVrRkRJRU5oYldWeQorWm1seWJXRWdVeTVCTGpFcE1DY0dBMVVFQXhNZ1EyaGhiV0psY25NZ2IyWWdRMjl0YldWeVkyVWdVbTl2ZENBdAorSURJd01EaUNDUUNqMmtKK3BMR3UyakFPQmdOVkhROEJBZjhFQkFNQ0FRWXdQUVlEVlIwZ0JEWXdOREF5QmdSVgorSFNBQU1Db3dLQVlJS3dZQkJRVUhBZ0VXSEdoMGRIQTZMeTl3YjJ4cFkza3VZMkZ0WlhKbWFYSnRZUzVqYjIwdworRFFZSktvWklodmNOQVFFRkJRQURnZ0lCQUpBU3J5STF3cU01OEM3ZTZiWHBlSHhJdmo5OVJaSmU2ZHF4R2Z3VworUEorMFcyYWVhdWZEdVYySTZBK3R6eU1QM2lVNlhzeFBwY0cxTGF3azBsZ0gzcUxQYVlSZ00rZ1FEUk9wSTlDRgorNVk1N3BwNDljaE55TS9XcWZjWmpId2owL2dGL0pNOHJMRlFKM3VJcmJaTEdPVThXNmp4K2VrYlVSV3BHcU90MQorZ2xhbnE2QjhhQk16OXAwdzhHOG5PU1FqS3BEOWtDazE4cFBmTktYRzkvanZqQTlpU255dTAvVlUrSTIybWxhSAorRm9JNk02dGFJZ2ozZ3JycUx1QkhtclMxUmFNRk85bmNMa1ZBTytyY2YrZzc2OUhzSnRnMXBEREZPcXhYbnJOMgorcFNCNytSNUtCV0lCcGloMVlKZVNEVzQrVFRkRERaSVZuQmdpelZHWm9Da2FQRitLTWpOYk1NZUpMMGVZRDZNRAoreHZieHJOOHk4Tm1CR3VTY3ZmYUFGUERSTExtRjlkaWpzY2lsSWVVY0U1ZnVEcjNmS2Fudk5GTmIwK1JxRTRRRwordGpJQ3hGS3VJdExjc2lGQ0d0cEE4Q25KN0FvTVhPTFF1c3hJMHpjS3pCSUtpbm13UFFOL2FVdjBOQ0I5c3pUcQoramt0azlUNzlzeU5uRlEwRXVQQXR3UWxSUExKc0ZmQ2xJOWVEZE9UbExzbittQ2RDeHF2R25yRFFXemlsbTFEZQorZmhpWXRVVTc5bm0wNlBjYWV3YUQrOUNMMnJ2SHZSaXJDRzg4Z0d0QVB4a1p1bVdLNXI3VlhOTTIxKzlBVWlSZworT0djRU1leVA4NExHM3JsVjh6c3hrVnJjdFFnVnJYWWxDZzE3TG9maURLWUd2Q1lRYlRlZDdOMTRqSHlBeGZEWgorZDBqUQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgYTM6ZGE6NDI6N2U6YTQ6YjE6YWU6ZGEKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1FVSwgTD1NYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpL3NlcmlhbE51bWJlcj1BODI3NDMyODcsIE89QUMgQ2FtZXJmaXJtYSBTLkEuLCBDTj1DaGFtYmVycyBvZiBDb21tZXJjZSBSb290IC0gMjAwOAorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogQXVnICAxIDEyOjI5OjUwIDIwMDggR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBKdWwgMzEgMTI6Mjk6NTAgMjAzOCBHTVQKKyAgICAgICAgU3ViamVjdDogQz1FVSwgTD1NYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpL3NlcmlhbE51bWJlcj1BODI3NDMyODcsIE89QUMgQ2FtZXJmaXJtYSBTLkEuLCBDTj1DaGFtYmVycyBvZiBDb21tZXJjZSBSb290IC0gMjAwOAorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDQwOTYgYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDQwOTYgYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YWY6MDA6Y2I6NzA6Mzc6MmI6ODA6NWE6NGE6M2E6NmM6Nzg6OTQ6N2Q6CisgICAgICAgICAgICAgICAgICAgIGEzOjdmOjFhOjFmOmY2OjM1OmQ1OmJkOmRiOmNiOjBkOjQ0OjcyOjNlOjI2OgorICAgICAgICAgICAgICAgICAgICBiMjo5MDo1MjpiYTo2MzozYjoyODo1ODo2ZjphNTpiMzo2ZDo5NDphNjpmMzoKKyAgICAgICAgICAgICAgICAgICAgZGQ6NjQ6MGM6NTU6ZjY6ZjY6ZTc6ZjI6MjI6MjI6ODA6NWU6ZTE6NjI6YzY6CisgICAgICAgICAgICAgICAgICAgIGI2OjI5OmUxOjgxOjZjOmYyOmJmOmU1OjdkOjMyOjZhOjU0OmEwOjMyOjE5OgorICAgICAgICAgICAgICAgICAgICA1OTpmZToxZjo4YjpkNzozZDo2MDo4Njo4NToyNDo2ZjplMzoxMTpiMzo3NzoKKyAgICAgICAgICAgICAgICAgICAgM2U6MjA6OTY6MzU6MjE6NmI6YjM6MDg6ZDk6NzA6MmU6NjQ6Zjc6ODQ6OTI6CisgICAgICAgICAgICAgICAgICAgIDUzOmQ2OjBlOmIwOjkwOjhhOjhhOmUzOjg3OjhkOjA2OmQzOmJkOjkwOjBlOgorICAgICAgICAgICAgICAgICAgICBlMjo5OTphMToxYjo4NjowZTpkYTo5YTowYTpiYjowYjo2MTo1MDowNjo1MjoKKyAgICAgICAgICAgICAgICAgICAgZjE6OWU6N2Y6NzY6ZWM6Y2I6MGY6ZDA6MWU6MGQ6Y2Y6OTk6MzA6M2Q6MWM6CisgICAgICAgICAgICAgICAgICAgIGM0OjQ1OjEwOjU4OmFjOmQ2OmQzOmU4OmQ3OmU1OmVhOmM1OjAxOjA3Ojc3OgorICAgICAgICAgICAgICAgICAgICBkNjo1MTplNjowMzo3Zjo4YTo0ODphNTo0ZDo2ODo3NTpiOTplOTpiYzo5ZToKKyAgICAgICAgICAgICAgICAgICAgNGU6MTk6NzE6ZjU6MzI6NGI6OWM6NmQ6NjA6MTk6MGI6ZmI6Y2M6OWQ6NzU6CisgICAgICAgICAgICAgICAgICAgIGRjOmJmOjI2OmNkOjhmOjkzOjc4OjM5Ojc5OjczOjVlOjI1OjBlOmNhOjVjOgorICAgICAgICAgICAgICAgICAgICBlYjo3NzoxMjowNzpjYjo2NDo0MTo0Nzo3Mjo5MzphYjo1MDpjMzplYjowOToKKyAgICAgICAgICAgICAgICAgICAgNzY6NjQ6MzQ6ZDI6Mzk6Yjc6NzY6MTE6MDk6MGQ6NzY6NDU6YzQ6YTk6YWU6CisgICAgICAgICAgICAgICAgICAgIDNkOjZhOmFmOmI1OjdkOjY1OjJmOjk0OjU4OjEwOmVjOjVjOjdjOmFmOjdlOgorICAgICAgICAgICAgICAgICAgICBlMjpiNjoxODpkOTpkMDo5Yjo0ZTo1YTo0OTpkZjphOTo2NjowYjpjYzozYzoKKyAgICAgICAgICAgICAgICAgICAgYzY6Nzg6N2M6YTc6OWM6MWQ6ZTM6Y2U6OGU6NTM6YmU6MDU6ZGU6NjA6MGY6CisgICAgICAgICAgICAgICAgICAgIDZiOmU1OjFhOmRiOjNmOmUzOmUxOjIxOmM5OjI5OmMxOmYxOmViOjA3OjljOgorICAgICAgICAgICAgICAgICAgICA1MjoxYjowMTo0NDo1MTozYzo3YjoyNTpkNzpjNDplNTo1Mjo1NDo1ZDoyNToKKyAgICAgICAgICAgICAgICAgICAgMDc6Y2E6MTY6MjA6Yjg6YWQ6ZTQ6NDE6ZWU6N2E6MDg6ZmU6OTk6NmY6ODM6CisgICAgICAgICAgICAgICAgICAgIGE2OjkxOjAyOmIwOjZjOjM2OjU1OjZhOmU3OjdkOmY1Ojk2OmU2OmNhOjgxOgorICAgICAgICAgICAgICAgICAgICBkNjo5NzpmMTo5NDo4MzplOTplZDpiMDpiMTo2YjoxMjo2OToxZTphYzpmYjoKKyAgICAgICAgICAgICAgICAgICAgNWQ6YTk6YzU6OTg6ZTk6YjQ6NWI6NTg6N2E6YmU6M2Q6YTI6NDQ6M2E6NjM6CisgICAgICAgICAgICAgICAgICAgIDU5OmQ0OjBiOjI1OmRlOjFiOjRmOmJkOmU1OjAxOjllOmNkOmQyOjI5OmQ1OgorICAgICAgICAgICAgICAgICAgICA5ZjoxNzoxOTowYTo2ZjpiZjowYzo5MDpkMzowOTo1ZjpkOTplMzo4YTozNToKKyAgICAgICAgICAgICAgICAgICAgY2M6Nzk6NWE6NGQ6MTk6Mzc6OTI6Yjc6YzQ6YzE6YWQ6YWY6ZjQ6Nzk6MjQ6CisgICAgICAgICAgICAgICAgICAgIDlhOmIyOjAxOjBiOmIxOmFmOjVjOjk2OmYzOjgwOjMyOmZiOjVjOjNkOjk4OgorICAgICAgICAgICAgICAgICAgICBmMTphMDozZjo0YTpkZTpiZTphZjo5NDoyZTpkOTo1NTo5YToxNzo2ZTo2MDoKKyAgICAgICAgICAgICAgICAgICAgOWQ6NjM6NmM6Yjg6NjM6Yzk6YWU6ODE6NWM6MTg6MzU6ZTA6OTA6YmI6YmU6CisgICAgICAgICAgICAgICAgICAgIDNjOjRmOjM3OjIyOmI5OjdlOmViOmNmOjllOjc3OjIxOmE2OjNkOjM4OjgxOgorICAgICAgICAgICAgICAgICAgICBmYjo0ODpkYTozMTozZDoyYjplMzo4OTpmNTpkMDpiNTpiZDo3ZTplMDo1MDoKKyAgICAgICAgICAgICAgICAgICAgYzQ6MTI6ODk6YjM6MjM6OWE6MTA6MzE6ODU6ZGI6YWU6NmY6ZWY6Mzg6MzM6CisgICAgICAgICAgICAgICAgICAgIDE4Ojc2OjExCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFLCBwYXRobGVuOjEyCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgRjk6MjQ6QUM6MEY6QjI6QjU6Rjg6Nzk6QzA6RkE6NjA6ODg6MUI6QzQ6RDk6NEQ6MDI6OUU6MTc6MTkKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOkY5OjI0OkFDOjBGOkIyOkI1OkY4Ojc5OkMwOkZBOjYwOjg4OjFCOkM0OkQ5OjREOjAyOjlFOjE3OjE5CisgICAgICAgICAgICAgICAgRGlyTmFtZTovQz1FVS9MPU1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRkcmVzcykvc2VyaWFsTnVtYmVyPUE4Mjc0MzI4Ny9PPUFDIENhbWVyZmlybWEgUy5BLi9DTj1DaGFtYmVycyBvZiBDb21tZXJjZSBSb290IC0gMjAwOAorICAgICAgICAgICAgICAgIHNlcmlhbDpBMzpEQTo0Mjo3RTpBNDpCMTpBRTpEQQorCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQ2VydGlmaWNhdGUgUG9saWNpZXM6IAorICAgICAgICAgICAgICAgIFBvbGljeTogWDUwOXYzIEFueSBQb2xpY3kKKyAgICAgICAgICAgICAgICAgIENQUzogaHR0cDovL3BvbGljeS5jYW1lcmZpcm1hLmNvbQorCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDkwOjEyOmFmOjIyOjM1OmMyOmEzOjM5OmYwOjJlOmRlOmU5OmI1OmU5Ojc4OjdjOjQ4OmJlOgorICAgICAgICAzZjo3ZDo0NTo5Mjo1ZTplOTpkYTpiMToxOTpmYzoxNjozYzo5ZjpiNDo1Yjo2Njo5ZTo2YToKKyAgICAgICAgZTc6YzM6Yjk6NWQ6ODg6ZTg6MGY6YWQ6Y2Y6MjM6MGY6ZGU6MjU6M2E6NWU6Y2M6NGY6YTU6CisgICAgICAgIGMxOmI1OjJkOmFjOjI0OmQyOjU4OjA3OmRlOmEyOmNmOjY5Ojg0OjYwOjMzOmU4OjEwOjBkOgorICAgICAgICAxMzphOToyMzpkMDo4NTplNTo4ZTo3YjphNjo5ZTozZDo3MjoxMzo3MjozMzpmNTphYTo3ZDoKKyAgICAgICAgYzY6NjM6MWY6MDg6ZjQ6ZmU6MDE6N2Y6MjQ6Y2Y6MmI6MmM6NTQ6MDk6ZGU6ZTI6MmI6NmQ6CisgICAgICAgIDkyOmM2OjM5OjRmOjE2OmVhOjNjOjdlOjdhOjQ2OmQ0OjQ1OjZhOjQ2OmE4OmViOjc1OjgyOgorICAgICAgICA1NjphNzphYjphMDo3Yzo2ODoxMzozMzpmNjo5ZDozMDpmMDo2ZjoyNzozOToyNDoyMzoyYToKKyAgICAgICAgOTA6ZmQ6OTA6Mjk6MzU6ZjI6OTM6ZGY6MzQ6YTU6YzY6Zjc6Zjg6ZWY6OGM6MGY6NjI6NGE6CisgICAgICAgIDdjOmFlOmQzOmY1OjU0OmY4OjhkOmI2OjlhOjU2Ojg3OjE2OjgyOjNhOjMzOmFiOjVhOjIyOgorICAgICAgICAwODpmNzo4MjpiYTplYToyZTplMDo0Nzo5YTpiNDpiNTo0NTphMzowNTozYjpkOTpkYzoyZToKKyAgICAgICAgNDU6NDA6M2I6ZWE6ZGM6N2Y6ZTg6M2I6ZWI6ZDE6ZWM6MjY6ZDg6MzU6YTQ6MzA6YzU6M2E6CisgICAgICAgIGFjOjU3OjllOmIzOjc2OmE1OjIwOjdiOmY5OjFlOjRhOjA1OjYyOjAxOmE2OjI4Ojc1OjYwOgorICAgICAgICA5Nzo5MjowZDo2ZTozZTo0ZDozNzo0MzowZDo5MjoxNTo5YzoxODoyMjpjZDo1MTo5OTphMDoKKyAgICAgICAgMjk6MWE6M2M6NWY6OGE6MzI6MzM6NWI6MzA6Yzc6ODk6MmY6NDc6OTg6MGY6YTM6MDM6YzY6CisgICAgICAgIGY2OmYxOmFjOmRmOjMyOmYwOmQ5OjgxOjFhOmU0OjljOmJkOmY2OjgwOjE0OmYwOmQxOjJjOgorICAgICAgICBiOTo4NTpmNTpkODphMzpiMTpjODphNToyMTplNToxYzoxMzo5NzplZTowZTpiZDpkZjoyOToKKyAgICAgICAgYTk6ZWY6MzQ6NTM6NWI6ZDM6ZTQ6NmE6MTM6ODQ6MDY6YjY6MzI6MDI6YzQ6NTI6YWU6MjI6CisgICAgICAgIGQyOmRjOmIyOjIxOjQyOjFhOmRhOjQwOmYwOjI5OmM5OmVjOjBhOjBjOjVjOmUyOmQwOmJhOgorICAgICAgICBjYzo0ODpkMzozNzowYTpjYzoxMjowYTo4YTo3OTpiMDozZDowMzo3Zjo2OTo0YjpmNDozNDoKKyAgICAgICAgMjA6N2Q6YjM6MzQ6ZWE6OGU6NGI6NjQ6ZjU6M2U6ZmQ6YjM6MjM6Njc6MTU6MGQ6MDQ6Yjg6CisgICAgICAgIGYwOjJkOmMxOjA5OjUxOjNjOmIyOjZjOjE1OmYwOmE1OjIzOmQ3OjgzOjc0OmU0OmU1OjJlOgorICAgICAgICBjOTpmZTo5ODoyNzo0MjpjNjphYjpjNjo5ZTpiMDpkMDo1YjozODphNTo5Yjo1MDpkZTo3ZToKKyAgICAgICAgMTg6OTg6YjU6NDU6M2I6ZjY6Nzk6YjQ6ZTg6Zjc6MWE6N2I6MDY6ODM6ZmI6ZDA6OGI6ZGE6CisgICAgICAgIGJiOmM3OmJkOjE4OmFiOjA4OjZmOjNjOjgwOjZiOjQwOjNmOjE5OjE5OmJhOjY1OjhhOmU2OgorICAgICAgICBiZTpkNTo1YzpkMzozNjpkNzplZjo0MDo1MjoyNDo2MDozODo2NzowNDozMTplYzo4ZjpmMzoKKyAgICAgICAgODI6YzY6ZGU6Yjk6NTU6ZjM6M2I6MzE6OTE6NWE6ZGM6YjU6MDg6MTU6YWQ6NzY6MjU6MGE6CisgICAgICAgIDBkOjdiOjJlOjg3OmUyOjBjOmE2OjA2OmJjOjI2OjEwOjZkOjM3OjlkOmVjOmRkOjc4OjhjOgorICAgICAgICA3Yzo4MDpjNTpmMDpkOTo3Nzo0ODpkMAorU0hBMSBGaW5nZXJwcmludD03ODo2QTo3NDpBQzo3NjpBQjoxNDo3Rjo5Qzo2QTozMDo1MDpCQTo5RTpBODo3RTpGRTo5QTpDRTozQwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzIxOWQ5NDk5LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMjE5ZDk0OTkuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YzhmZGE0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzIxOWQ5NDk5LjAKQEAgLTAsMCArMSw4NCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFQURDQ0F1aWdBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUVVGQURCak1Rc3dDUVlEVlFRR0V3SlZVekVoCitNQjhHQTFVRUNoTVlWR2hsSUVkdklFUmhaR1I1SUVkeWIzVndMQ0JKYm1NdU1URXdMd1lEVlFRTEV5aEhieUJFCitZV1JrZVNCRGJHRnpjeUF5SUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNQjRYRFRBME1EWXlPVEUzCitNRFl5TUZvWERUTTBNRFl5T1RFM01EWXlNRm93WXpFTE1Ba0dBMVVFQmhNQ1ZWTXhJVEFmQmdOVkJBb1RHRlJvCitaU0JIYnlCRVlXUmtlU0JIY205MWNDd2dTVzVqTGpFeE1DOEdBMVVFQ3hNb1IyOGdSR0ZrWkhrZ1EyeGhjM01nCitNaUJEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVUQ0NBU0F3RFFZSktvWklodmNOQVFFQkJRQURnZ0VOCitBRENDQVFnQ2dnRUJBTjZkMStwWEdFbWhXK3ZYWDBpRzZyN2QvK1R2Wnh6MFpXaXpWM0dnWG5lNzdadEo2WENBCitQVllZWXdodjJ2TE0wRDkvQWxRaVZCRFlzb0hVd0hVOVMzL0hkOE0rZUtzYUE3VWdheTlxSzdIRmlIN0V1eDZ3Cit3ZGhGSjIrcU4xajNoeWJYMkMzMnFSZTNIM0kyVHFZWFAyV1lrdHNxYmwyaS9vamdDOTUvNVkwVjRldkxPdFhpCitFcUlUTGRpT3IxOFNQYUFJQlFpMlhLVmxPQVJGbVI2allHQjB4VUdsY21JYllzVWZiMThhUXI0Q1VXV29yaU1ZCithdng0QTZsTmY0REQrcXRhL0tGQXBNb1pGdjZ5eU85ZWN3M3VkNzJhOW5tWXZMRUhaNklWRGQyZ1dNWkVld28rCitZaWhmdWtFSFUxalBFWDQ0ZE1YNC83VnBrSStFZE9xWEc2OENBUU9qZ2NBd2diMHdIUVlEVlIwT0JCWUVGTkxFCitzTktSMUV3UmNiTmh5ejJoL3Qyb2F0VGpNSUdOQmdOVkhTTUVnWVV3Z1lLQUZOTEVzTktSMUV3UmNiTmh5ejJoCisvdDJvYXRUam9XZWtaVEJqTVFzd0NRWURWUVFHRXdKVlV6RWhNQjhHQTFVRUNoTVlWR2hsSUVkdklFUmhaR1I1CitJRWR5YjNWd0xDQkpibU11TVRFd0x3WURWUVFMRXloSGJ5QkVZV1JrZVNCRGJHRnpjeUF5SUVObGNuUnBabWxqCitZWFJwYjI0Z1FYVjBhRzl5YVhSNWdnRUFNQXdHQTFVZEV3UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUZCUUFECitnZ0VCQURKTDg3TEtQcEg4RXNhaEI0eU9kNkF6QmhSY2tCNFk5d2ltUFFvWitZZUFFVzVwNUpZWE1QODBrV055CitPTzdNSEFHakhaUW9wREgyZXNSVTEvYmxNVmdEb3N6T1l0dVVSWE8xdjBYSkpMWFZnZ0t0STNscGpiaTJUYzdQCitUTW96SStnY2lLcWRpMEZ1RnNrZzVZbWV6VHZhY1BkK21TWWdGRlFscTI1emhlYWJJWjBLYklJT3FQakNEUG9RCitIbXlXNzRjTnhBOWhpNjN1Z3l1VitJNlNoSEk1NnlEcWcrMkR6WmR1Q0x6clRpYTJjeXZrMC9aTS9pWng0bUVSCitkRXIvVnhxSEQzVklMczlSYVJlZ0FoSmhsZFhSUUxJUVRPN0VyQkJEcHFXZUN0V1ZZcG9OejRpQ3hUSU01Q3VmCitSZVlObnlpY3Nia3FXbGV0TncrdkhYL2J2Wjg9CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDAgKDB4MCkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgTz1UaGUgR28gRGFkZHkgR3JvdXAsIEluYy4sIE9VPUdvIERhZGR5IENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEp1biAyOSAxNzowNjoyMCAyMDA0IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogSnVuIDI5IDE3OjA2OjIwIDIwMzQgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuLCBPVT1HbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5CisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpkZTo5ZDpkNzplYTo1NzoxODo0OTphMTo1YjplYjpkNzo1Zjo0ODo4NjoKKyAgICAgICAgICAgICAgICAgICAgZWE6YmU6ZGQ6ZmY6ZTQ6ZWY6Njc6MWM6ZjQ6NjU6Njg6YjM6NTc6NzE6YTA6CisgICAgICAgICAgICAgICAgICAgIDVlOjc3OmJiOmVkOjliOjQ5OmU5OjcwOjgwOjNkOjU2OjE4OjYzOjA4OjZmOgorICAgICAgICAgICAgICAgICAgICBkYTpmMjpjYzpkMDozZjo3ZjowMjo1NDoyMjo1NDoxMDpkODpiMjo4MTpkNDoKKyAgICAgICAgICAgICAgICAgICAgYzA6NzU6M2Q6NGI6N2Y6Yzc6Nzc6YzM6M2U6Nzg6YWI6MWE6MDM6YjU6MjA6CisgICAgICAgICAgICAgICAgICAgIDZiOjJmOjZhOjJiOmIxOmM1Ojg4OjdlOmM0OmJiOjFlOmIwOmMxOmQ4OjQ1OgorICAgICAgICAgICAgICAgICAgICAyNzo2ZjphYTozNzo1ODpmNzo4NzoyNjpkNzpkODoyZDpmNjphOToxNzpiNzoKKyAgICAgICAgICAgICAgICAgICAgMWY6NzI6MzY6NGU6YTY6MTc6M2Y6NjU6OTg6OTI6ZGI6MmE6NmU6NWQ6YTI6CisgICAgICAgICAgICAgICAgICAgIGZlOjg4OmUwOjBiOmRlOjdmOmU1OjhkOjE1OmUxOmViOmNiOjNhOmQ1OmUyOgorICAgICAgICAgICAgICAgICAgICAxMjphMjoxMzoyZDpkODo4ZTphZjo1ZjoxMjozZDphMDowODowNTowODpiNjoKKyAgICAgICAgICAgICAgICAgICAgNWM6YTU6NjU6Mzg6MDQ6NDU6OTk6MWU6YTM6NjA6NjA6NzQ6YzU6NDE6YTU6CisgICAgICAgICAgICAgICAgICAgIDcyOjYyOjFiOjYyOmM1OjFmOjZmOjVmOjFhOjQyOmJlOjAyOjUxOjY1OmE4OgorICAgICAgICAgICAgICAgICAgICBhZToyMzoxODo2YTpmYzo3ODowMzphOTo0ZDo3Zjo4MDpjMzpmYTphYjo1YToKKyAgICAgICAgICAgICAgICAgICAgZmM6YTE6NDA6YTQ6Y2E6MTk6MTY6ZmU6YjI6Yzg6ZWY6NWU6NzM6MGQ6ZWU6CisgICAgICAgICAgICAgICAgICAgIDc3OmJkOjlhOmY2Ojc5Ojk4OmJjOmIxOjA3OjY3OmEyOjE1OjBkOmRkOmEwOgorICAgICAgICAgICAgICAgICAgICA1ODpjNjo0NDo3YjowYTozZTo2MjoyODo1ZjpiYTo0MTowNzo1Mzo1ODpjZjoKKyAgICAgICAgICAgICAgICAgICAgMTE6N2U6Mzg6NzQ6YzU6Zjg6ZmY6YjU6Njk6OTA6OGY6ODQ6NzQ6ZWE6OTc6CisgICAgICAgICAgICAgICAgICAgIDFiOmFmCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDMgKDB4MykKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgRDI6QzQ6QjA6RDI6OTE6RDQ6NEM6MTE6NzE6QjM6NjE6Q0I6M0Q6QTE6RkU6REQ6QTg6NkE6RDQ6RTMKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOkQyOkM0OkIwOkQyOjkxOkQ0OjRDOjExOjcxOkIzOjYxOkNCOjNEOkExOkZFOkREOkE4OjZBOkQ0OkUzCisgICAgICAgICAgICAgICAgRGlyTmFtZTovQz1VUy9PPVRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLi9PVT1HbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5CisgICAgICAgICAgICAgICAgc2VyaWFsOjAwCisKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAzMjo0YjpmMzpiMjpjYTozZTo5MTpmYzoxMjpjNjphMTowNzo4Yzo4ZTo3NzphMDozMzowNjoKKyAgICAgICAgMTQ6NWM6OTA6MWU6MTg6Zjc6MDg6YTY6M2Q6MGE6MTk6Zjk6ODc6ODA6MTE6NmU6Njk6ZTQ6CisgICAgICAgIDk2OjE3OjMwOmZmOjM0OjkxOjYzOjcyOjM4OmVlOmNjOjFjOjAxOmEzOjFkOjk0OjI4OmE0OgorICAgICAgICAzMTpmNjo3YTpjNDo1NDpkNzpmNjplNTozMTo1ODowMzphMjpjYzpjZTo2MjpkYjo5NDo0NToKKyAgICAgICAgNzM6YjU6YmY6NDU6Yzk6MjQ6YjU6ZDU6ODI6MDI6YWQ6MjM6Nzk6Njk6OGQ6Yjg6YjY6NGQ6CisgICAgICAgIGNlOmNmOjRjOmNhOjMzOjIzOmU4OjFjOjg4OmFhOjlkOjhiOjQxOjZlOjE2OmM5OjIwOmU1OgorICAgICAgICA4OTo5ZTpjZDozYjpkYTo3MDpmNzo3ZTo5OToyNjoyMDoxNDo1NDoyNTphYjo2ZTo3Mzo4NToKKyAgICAgICAgZTY6OWI6MjE6OWQ6MGE6NmM6ODI6MGU6YTg6Zjg6YzI6MGM6ZmE6MTA6MWU6NmM6OTY6ZWY6CisgICAgICAgIDg3OjBkOmM0OjBmOjYxOjhiOmFkOmVlOjgzOjJiOjk1OmY4OjhlOjkyOjg0OjcyOjM5OmViOgorICAgICAgICAyMDplYTo4MzplZDo4MzpjZDo5Nzo2ZTowODpiYzplYjo0ZToyNjpiNjo3MzoyYjplNDpkMzoKKyAgICAgICAgZjY6NGM6ZmU6MjY6NzE6ZTI6NjE6MTE6NzQ6NGE6ZmY6NTc6MWE6ODc6MGY6NzU6NDg6MmU6CisgICAgICAgIGNmOjUxOjY5OjE3OmEwOjAyOjEyOjYxOjk1OmQ1OmQxOjQwOmIyOjEwOjRjOmVlOmM0OmFjOgorICAgICAgICAxMDo0MzphNjphNTo5ZTowYTpkNTo5NTo2Mjo5YTowZDpjZjo4ODo4MjpjNTozMjowYzplNDoKKyAgICAgICAgMmI6OWY6NDU6ZTY6MGQ6OWY6Mjg6OWM6YjE6Yjk6MmE6NWE6NTc6YWQ6Mzc6MGY6YWY6MWQ6CisgICAgICAgIDdmOmRiOmJkOjlmCitTSEExIEZpbmdlcnByaW50PTI3Ojk2OkJBOkU2OjNGOjE4OjAxOkUyOjc3OjI2OjFCOkEwOkQ3Ojc3OjcwOjAyOjhGOjIwOkVFOkU0CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMjNmNGM0OTAuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8yM2Y0YzQ5MC4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjViNTNiYWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMjNmNGM0OTAuMApAQCAtMCwwICsxLDg0IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUVEekNDQXZlZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRVUZBREJvTVFzd0NRWURWUVFHRXdKVlV6RWwKK01DTUdBMVVFQ2hNY1UzUmhjbVpwWld4a0lGUmxZMmh1YjJ4dloybGxjeXdnU1c1akxqRXlNREFHQTFVRUN4TXAKK1UzUmhjbVpwWld4a0lFTnNZWE56SURJZ1EyVnlkR2xtYVdOaGRHbHZiaUJCZFhSb2IzSnBkSGt3SGhjTk1EUXcKK05qSTVNVGN6T1RFMldoY05NelF3TmpJNU1UY3pPVEUyV2pCb01Rc3dDUVlEVlFRR0V3SlZVekVsTUNNR0ExVUUKK0NoTWNVM1JoY21acFpXeGtJRlJsWTJodWIyeHZaMmxsY3l3Z1NXNWpMakV5TURBR0ExVUVDeE1wVTNSaGNtWnAKK1pXeGtJRU5zWVhOeklESWdRMlZ5ZEdsbWFXTmhkR2x2YmlCQmRYUm9iM0pwZEhrd2dnRWdNQTBHQ1NxR1NJYjMKK0RRRUJBUVVBQTRJQkRRQXdnZ0VJQW9JQkFRQzNNc2orNlhHbUJJV3REQkZrMzg1Tjc4Z0RHSWMvb2F2N1BLYWYKKzhNT2gydFRZYml0VGtQc2twRDZFOEo3b1gremxKMFQxS0tZL2U5N2dLdkRJcjFNdm5zb0ZBWk1lajJZY09hZE4KKytscTJjd1FsWnV0M2YrZFp4a3FaSlJSVTZ5Ykg4MzhaMVRCd2o2K3dSaXIvcmVzcDdkZWZxZ1NIbzlUNWlhVTAKK1g5dERrWUkyMldZOHNiaTVndjJjT2o0UXlEdnZCbVZtZXBzWkdEMy9jVkU4TUM1ZnZqMTNjN0pkQm16REkxYWEKK0s0VW1raHluQXJQa1B3MnZDSG1DdURZOTZwelROYk84YWNyMXpKM28vV1NORjRBemJsNUtYWm5KSG9lMG5SckEKKzFXNFROU05lMzV0ZlBlL1c5M2JDNmo2N2VBMGNRbWRyQk5qNDF0cHZpL0pFb0FHckFnRURvNEhGTUlIQ01CMEcKK0ExVWREZ1FXQkJTL1g3ZlJ6dDBmaHZSYlZhemMxeERDRHFtSTV6Q0JrZ1lEVlIwakJJR0tNSUdIZ0JTL1g3ZlIKK3p0MGZodlJiVmF6YzF4RENEcW1JNTZGc3BHb3dhREVMTUFrR0ExVUVCaE1DVlZNeEpUQWpCZ05WQkFvVEhGTjAKK1lYSm1hV1ZzWkNCVVpXTm9ibTlzYjJkcFpYTXNJRWx1WXk0eE1qQXdCZ05WQkFzVEtWTjBZWEptYVdWc1pDQkQKK2JHRnpjeUF5SUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVnZ0VBTUF3R0ExVWRFd1FGTUFNQkFmOHcKK0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFBV2RQNGlkMGNrYVZhR3NhZlB6V2RxYkFZY2FUMWVwb1hrSkt0djMKK0w3SWV6TWRlYXRpRGg2R1g3MGsxUG5jR1FWaGl2NDVZdUFwblAreXozU0ZtSDhsVStuTE1QVXhBMklHdmQ1NkQKK2VydWl4L1UwRjQ3WkVVRDAvQ3dxVFJWL3AySmRMaVhUQUFzZ0doMW8rUmU0OUwyTDdTaFozVTBXaXhlRHlMSmwKK3h5MTZwYXE4VTRadDNWZWt5dmdnUVF0bzhQVDdkTDVXWFhwNTlma2RoZU10bGI3MWNaQkR6STBmbWdBS2h5bnAKK1ZTSllBQ1BxNHhKREtWdEhDTjJNUVdwbEJxamxJYXBCdEpVaGxibDkwVFNyRTlhdHZOemlQVG5OdlQ1MWNLRVkKK1dRUEpJclNQbk5WZUt0ZWx0dFFLYmZpM1FCRkdtaDk1RG1LL0Q1ZnM0QzhmRjVRPQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAwICgweDApCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9VVMsIE89U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLiwgT1U9U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEp1biAyOSAxNzozOToxNiAyMDA0IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogSnVuIDI5IDE3OjM5OjE2IDIwMzQgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLiwgT1U9U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmI3OjMyOmM4OmZlOmU5OjcxOmE2OjA0Ojg1OmFkOjBjOjExOjY0OmRmOgorICAgICAgICAgICAgICAgICAgICBjZTo0ZDplZjpjODowMzoxODo4NzozZjphMTphYjpmYjozYzphNjo5ZjpmMDoKKyAgICAgICAgICAgICAgICAgICAgYzM6YTE6ZGE6ZDQ6ZDg6NmU6MmI6NTM6OTA6ZmI6MjQ6YTQ6M2U6ODQ6ZjA6CisgICAgICAgICAgICAgICAgICAgIDllOmU4OjVmOmVjOmU1OjI3OjQ0OmY1OjI4OmE2OjNmOjdiOmRlOmUwOjJhOgorICAgICAgICAgICAgICAgICAgICBmMDpjODphZjo1MzoyZjo5ZTpjYTowNTowMTo5MzoxZTo4Zjo2NjoxYzozOToKKyAgICAgICAgICAgICAgICAgICAgYTc6NGQ6ZmE6NWE6YjY6NzM6MDQ6MjU6NjY6ZWI6Nzc6N2Y6ZTc6NTk6YzY6CisgICAgICAgICAgICAgICAgICAgIDRhOjk5OjI1OjE0OjU0OmViOjI2OmM3OmYzOjdmOjE5OmQ1OjMwOjcwOjhmOgorICAgICAgICAgICAgICAgICAgICBhZjpiMDo0NjoyYTpmZjphZDplYjoyOTplZDpkNzo5ZjphYTowNDo4NzphMzoKKyAgICAgICAgICAgICAgICAgICAgZDQ6Zjk6ODk6YTU6MzQ6NWY6ZGI6NDM6OTE6ODI6MzY6ZDk6NjY6M2M6YjE6CisgICAgICAgICAgICAgICAgICAgIGI4OmI5OjgyOmZkOjljOjNhOjNlOjEwOmM4OjNiOmVmOjA2OjY1OjY2OjdhOgorICAgICAgICAgICAgICAgICAgICA5YjoxOToxODozZDpmZjo3MTo1MTozYzozMDoyZTo1ZjpiZTozZDo3Nzo3MzoKKyAgICAgICAgICAgICAgICAgICAgYjI6NWQ6MDY6NmM6YzM6MjM6NTY6OWE6MmI6ODU6MjY6OTI6MWM6YTc6MDI6CisgICAgICAgICAgICAgICAgICAgIGIzOmU0OjNmOjBkOmFmOjA4Ojc5OjgyOmI4OjM2OjNkOmVhOjljOmQzOjM1OgorICAgICAgICAgICAgICAgICAgICBiMzpiYzo2OTpjYTpmNTpjYzo5ZDplODpmZDo2NDo4ZDoxNzo4MDozMzo2ZToKKyAgICAgICAgICAgICAgICAgICAgNWU6NGE6NWQ6OTk6Yzk6MWU6ODc6YjQ6OWQ6MWE6YzA6ZDU6NmU6MTM6MzU6CisgICAgICAgICAgICAgICAgICAgIDIzOjVlOmRmOjliOjVmOjNkOmVmOmQ2OmY3Ojc2OmMyOmVhOjNlOmJiOjc4OgorICAgICAgICAgICAgICAgICAgICAwZDoxYzo0Mjo2Nzo2YjowNDpkODpmODpkNjpkYTo2Zjo4YjpmMjo0NDphMDoKKyAgICAgICAgICAgICAgICAgICAgMDE6YWIKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogMyAoMHgzKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBCRjo1RjpCNzpEMTpDRTpERDoxRjo4NjpGNDo1Qjo1NTpBQzpEQzpENzoxMDpDMjowRTpBOTo4ODpFNworICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6QkY6NUY6Qjc6RDE6Q0U6REQ6MUY6ODY6RjQ6NUI6NTU6QUM6REM6RDc6MTA6QzI6MEU6QTk6ODg6RTcKKyAgICAgICAgICAgICAgICBEaXJOYW1lOi9DPVVTL089U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLi9PVT1TdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQorICAgICAgICAgICAgICAgIHNlcmlhbDowMAorCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMDU6OWQ6M2Y6ODg6OWQ6ZDE6Yzk6MWE6NTU6YTE6YWM6Njk6ZjM6ZjM6NTk6ZGE6OWI6MDE6CisgICAgICAgIDg3OjFhOjRmOjU3OmE5OmExOjc5OjA5OjJhOmRiOmY3OjJmOmIyOjFlOmNjOmM3OjVlOjZhOgorICAgICAgICBkODo4Mzo4NzphMTo5NzplZjo0OTozNTozZTo3NzowNjo0MTo1ODo2MjpiZjo4ZTo1ODpiODoKKyAgICAgICAgMGE6Njc6M2Y6ZWM6YjM6ZGQ6MjE6NjY6MWY6Yzk6NTQ6ZmE6NzI6Y2M6M2Q6NGM6NDA6ZDg6CisgICAgICAgIDgxOmFmOjc3OjllOjgzOjdhOmJiOmEyOmM3OmY1OjM0OjE3OjhlOmQ5OjExOjQwOmY0OmZjOgorICAgICAgICAyYzoyYTo0ZDoxNTo3ZjphNzo2Mjo1ZDoyZToyNTpkMzowMDowYjoyMDoxYToxZDo2ODpmOToKKyAgICAgICAgMTc6Yjg6ZjQ6YmQ6OGI6ZWQ6Mjg6NTk6ZGQ6NGQ6MTY6OGI6MTc6ODM6Yzg6YjI6NjU6Yzc6CisgICAgICAgIDJkOjdhOmE1OmFhOmJjOjUzOjg2OjZkOmRkOjU3OmE0OmNhOmY4OjIwOjQxOjBiOjY4OmYwOgorICAgICAgICBmNDpmYjo3NDpiZTo1Njo1ZDo3YTo3OTpmNTpmOToxZDo4NTplMzoyZDo5NTpiZTpmNTo3MToKKyAgICAgICAgOTA6NDM6Y2M6OGQ6MWY6OWE6MDA6MGE6ODc6Mjk6ZTk6NTU6MjI6NTg6MDA6MjM6ZWE6ZTM6CisgICAgICAgIDEyOjQzOjI5OjViOjQ3OjA4OmRkOjhjOjQxOjZhOjY1OjA2OmE4OmU1OjIxOmFhOjQxOmI0OgorICAgICAgICA5NToyMTo5NTpiOTo3ZDpkMTozNDphYjoxMzpkNjphZDpiYzpkYzplMjozZDozOTpjZDpiZDoKKyAgICAgICAgM2U6NzU6NzA6YTE6MTg6NTk6MDM6Yzk6MjI6YjQ6OGY6OWM6ZDU6NWU6MmE6ZDc6YTU6YjY6CisgICAgICAgIGQ0OjBhOjZkOmY4OmI3OjQwOjExOjQ2OjlhOjFmOjc5OjBlOjYyOmJmOjBmOjk3OmVjOmUwOgorICAgICAgICAyZjoxZjoxNzo5NAorU0hBMSBGaW5nZXJwcmludD1BRDo3RToxQzoyODpCMDo2NDpFRjo4Rjo2MDowMzo0MDoyMDoxNDpDMzpEMDpFMzozNzowRTpCNTo4QQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzI3YWY3OTBkLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMjdhZjc5MGQuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNDNlNmU2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzI3YWY3OTBkLjAKQEAgLTAsMCArMSw1NSBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlDcmpDQ0FqV2dBd0lCQWdJUVBMTDBTQW9BNHY3ckpEdGVZRDdEYXpBS0JnZ3Foa2pPUFFRREF6Q0JtREVMCitNQWtHQTFVRUJoTUNWVk14RmpBVUJnTlZCQW9URFVkbGIxUnlkWE4wSUVsdVl5NHhPVEEzQmdOVkJBc1RNQ2hqCitLU0F5TURBM0lFZGxiMVJ5ZFhOMElFbHVZeTRnTFNCR2IzSWdZWFYwYUc5eWFYcGxaQ0IxYzJVZ2IyNXNlVEUyCitNRFFHQTFVRUF4TXRSMlZ2VkhKMWMzUWdVSEpwYldGeWVTQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwCitlU0F0SUVjeU1CNFhEVEEzTVRFd05UQXdNREF3TUZvWERUTTRNREV4T0RJek5UazFPVm93Z1pneEN6QUpCZ05WCitCQVlUQWxWVE1SWXdGQVlEVlFRS0V3MUhaVzlVY25WemRDQkpibU11TVRrd053WURWUVFMRXpBb1l5a2dNakF3CitOeUJIWlc5VWNuVnpkQ0JKYm1NdUlDMGdSbTl5SUdGMWRHaHZjbWw2WldRZ2RYTmxJRzl1YkhreE5qQTBCZ05WCitCQU1UTFVkbGIxUnlkWE4wSUZCeWFXMWhjbmtnUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa2dMU0JICitNakIyTUJBR0J5cUdTTTQ5QWdFR0JTdUJCQUFpQTJJQUJCV3g2UDBERlVQbHJPdUhOeEZpNzlLRE5sSjlSVmNMCitTbzE3VkRzNmJsOFZBc0JRcHM4bEwzM0tTTGpIVUdNY0tpRUlmSm8yMkF2KzBTYkZXREV3S0NYelhWMmp1TGFsCit0Skx0YkN5ZjY5MURpYUk4UzBpUkhWRHNKdC9XWUM2OUlhTkNNRUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFPCitCZ05WSFE4QkFmOEVCQU1DQVFZd0hRWURWUjBPQkJZRUZCVmZOVmRSVmZzbHNxMERhZndCby9xK0VWWFZNQW9HCitDQ3FHU000OUJBTURBMmNBTUdRQ01HU1dXYWJvQ2Q2THV2cGFpSWp3SDVIVFJxanlTa3dDWS90c1h6amJMa0dUCitxUTdtbmR3eEhMS2dweGdjZWVISE5nSXdPbGF2bW5Sczl2dUQ0RFBUQ0YraG5NSmJuMGJXdHN1UkJtT2lCdWN6CityRDZvZ1JMUXk3clFrZ3UybnBhcUJBK0sKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDNjOmIyOmY0OjQ4OjBhOjAwOmUyOmZlOmViOjI0OjNiOjVlOjYwOjNlOmMzOjZiCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IGVjZHNhLXdpdGgtU0hBMzg0CisgICAgICAgIElzc3VlcjogQz1VUywgTz1HZW9UcnVzdCBJbmMuLCBPVT0oYykgMjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHksIENOPUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMgorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTm92ICA1IDAwOjAwOjAwIDIwMDcgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBKYW4gMTggMjM6NTk6NTkgMjAzOCBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgTz1HZW9UcnVzdCBJbmMuLCBPVT0oYykgMjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHksIENOPUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMgorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiBpZC1lY1B1YmxpY0tleQorICAgICAgICAgICAgRUMgUHVibGljIEtleToKKyAgICAgICAgICAgICAgICBwdWI6IAorICAgICAgICAgICAgICAgICAgICAwNDoxNTpiMTplODpmZDowMzoxNTo0MzplNTphYzplYjo4NzozNzoxMTo2MjoKKyAgICAgICAgICAgICAgICAgICAgZWY6ZDI6ODM6MzY6NTI6N2Q6NDU6NTc6MGI6NGE6OGQ6N2I6NTQ6M2I6M2E6CisgICAgICAgICAgICAgICAgICAgIDZlOjVmOjE1OjAyOmMwOjUwOmE2OmNmOjI1OjJmOjdkOmNhOjQ4OmI4OmM3OgorICAgICAgICAgICAgICAgICAgICA1MDo2MzoxYzoyYToyMTowODo3Yzo5YTozNjpkODowYjpmZTpkMToyNjpjNToKKyAgICAgICAgICAgICAgICAgICAgNTg6MzE6MzA6Mjg6MjU6ZjM6NWQ6NWQ6YTM6Yjg6YjY6YTU6YjQ6OTI6ZWQ6CisgICAgICAgICAgICAgICAgICAgIDZjOjJjOjlmOmViOmRkOjQzOjg5OmEyOjNjOjRiOjQ4OjkxOjFkOjUwOmVjOgorICAgICAgICAgICAgICAgICAgICAyNjpkZjpkNjo2MDoyZTpiZDoyMQorICAgICAgICAgICAgICAgIEFTTjEgT0lEOiBzZWNwMzg0cjEKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDE1OjVGOjM1OjU3OjUxOjU1OkZCOjI1OkIyOkFEOjAzOjY5OkZDOjAxOkEzOkZBOkJFOjExOjU1OkQ1CisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogZWNkc2Etd2l0aC1TSEEzODQKKyAgICAgICAgMzA6NjQ6MDI6MzA6NjQ6OTY6NTk6YTY6ZTg6MDk6ZGU6OGI6YmE6ZmE6NWE6ODg6ODg6ZjA6CisgICAgICAgIDFmOjkxOmQzOjQ2OmE4OmYyOjRhOjRjOjAyOjYzOmZiOjZjOjVmOjM4OmRiOjJlOjQxOjkzOgorICAgICAgICBhOTowZTplNjo5ZDpkYzozMToxYzpiMjphMDphNzoxODoxYzo3OTplMTpjNzozNjowMjozMDoKKyAgICAgICAgM2E6NTY6YWY6OWE6NzQ6NmM6ZjY6ZmI6ODM6ZTA6MzM6ZDM6MDg6NWY6YTE6OWM6YzI6NWI6CisgICAgICAgIDlmOjQ2OmQ2OmI2OmNiOjkxOjA2OjYzOmEyOjA2OmU3OjMzOmFjOjNlOmE4OjgxOjEyOmQwOgorICAgICAgICBjYjpiYTpkMDo5MjowYjpiNjo5ZTo5NjphYTowNDowZjo4YQorU0hBMSBGaW5nZXJwcmludD04RDoxNzo4NDpENTozNzpGMzowMzo3RDpFQzo3MDpGRTo1Nzo4Qjo1MTo5QTo5OTpFNjoxMDpENzpCMApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzJhZmM1N2FhLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMmFmYzU3YWEuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZjQzNjQ0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzJhZmM1N2FhLjAKQEAgLTAsMCArMSw4OSBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFcWpDQ0E1S2dBd0lCQWdJT0xtb0FBUUFDSDlkU0lTd1JYRHN3RFFZSktvWklodmNOQVFFRkJRQXdkakVMCitNQWtHQTFVRUJoTUNSRVV4SERBYUJnTlZCQW9URTFSRElGUnlkWE4wUTJWdWRHVnlJRWR0WWtneElqQWdCZ05WCitCQXNUR1ZSRElGUnlkWE4wUTJWdWRHVnlJRU5zWVhOeklESWdRMEV4SlRBakJnTlZCQU1USEZSRElGUnlkWE4wCitRMlZ1ZEdWeUlFTnNZWE56SURJZ1EwRWdTVWt3SGhjTk1EWXdNVEV5TVRRek9EUXpXaGNOTWpVeE1qTXhNakkxCitPVFU1V2pCMk1Rc3dDUVlEVlFRR0V3SkVSVEVjTUJvR0ExVUVDaE1UVkVNZ1ZISjFjM1JEWlc1MFpYSWdSMjFpCitTREVpTUNBR0ExVUVDeE1aVkVNZ1ZISjFjM1JEWlc1MFpYSWdRMnhoYzNNZ01pQkRRVEVsTUNNR0ExVUVBeE1jCitWRU1nVkhKMWMzUkRaVzUwWlhJZ1EyeGhjM01nTWlCRFFTQkpTVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECitnZ0VQQURDQ0FRb0NnZ0VCQUt1QWg1dU84TU44aDlmb0pJSVJzenpkUTJMdStNTkYydWpob0YvUktyTHFrMmpmCit0TWpXUStuRWRWbC8vT0VkK0RGd0l4dUluaWU1ZS8wNjBzbXA2UlF2a0w0RFVzRkp6ZmI5NUFobUMxZUtva0tnCit1TlYvYVZ5UU1yS1hEY3BLM0VZK0FsV0pVK01hV3NzMnhnZFc5NHpQRWZSTXV6QndCSldsOWptTS9YT0JDSDJKCitYakllSXFraVJVdXdaaTR3eko5bC9mekxnYW54NER1dm80YlJpZXJFUlhsUVhhN3BJWFNTVFl0WmdvK1U0K2xLCis4ZWRKc0JUajlXTEwxWEs5SDduU242RE5xUG9CeU5rTjM5cjhSNTJ6eUZUZlNVcnhJYW4rR0U3dVNOUVp1Kzk5Cis1T0tkeTF1MmJ2L2p6VnJuZElJRnVvQWxPTXZrYVo2dlFhb2FoUFVDQXdFQUFhT0NBVFF3Z2dFd01BOEdBMVVkCitFd0VCL3dRRk1BTUJBZjh3RGdZRFZSMFBBUUgvQkFRREFnRUdNQjBHQTFVZERnUVdCQlRqcTFSTWdLSGJWa08zCitrVXJMODRKNkUxd0lxekNCN1FZRFZSMGZCSUhsTUlIaU1JSGZvSUhjb0lIWmhqVm9kSFJ3T2k4dmQzZDNMblJ5CitkWE4wWTJWdWRHVnlMbVJsTDJOeWJDOTJNaTkwWTE5amJHRnpjMTh5WDJOaFgwbEpMbU55YklhQm4yeGtZWEE2CitMeTkzZDNjdWRISjFjM1JqWlc1MFpYSXVaR1V2UTA0OVZFTWxNakJVY25WemRFTmxiblJsY2lVeU1FTnNZWE56CitKVEl3TWlVeU1FTkJKVEl3U1Vrc1R6MVVReVV5TUZSeWRYTjBRMlZ1ZEdWeUpUSXdSMjFpU0N4UFZUMXliMjkwCitZMlZ5ZEhNc1JFTTlkSEoxYzNSalpXNTBaWElzUkVNOVpHVS9ZMlZ5ZEdsbWFXTmhkR1ZTWlhadlkyRjBhVzl1CitUR2x6ZEQ5aVlYTmxQekFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBak5mZmZ1NGJnQkN6Zy9YYkVlcHJTNmlTCitHTm4zQnpuMUxMNEdkWHBvVXhVYzZrcnRYdndqc2hPZzB3bi85dll1YTBGeGVjM2liZjJ1V1d1RkhiaE9JcHJ0Citaamx1UzVUbVZmd0xHNHQzd1ZNVFpvblpLTmFMODBWS1k3Zjlld3RoWGJodHZzUGNXM25TN1libG9rMitYblI4CithdTBXT0I5L1dJRmFHdXN5aUMyeTh6bDNnSzlldG1GMUtkc2pUWWpLVUNqTGhkTFRFS0paYnRPVFZBQjZva2FWCitoZ1djcVJtWTVURnlEQURpWjlsQTRDUXplMjhzdVZ5clpaMHNySGJxTlpuMWw3a1BKT3pIZGlFb1phNVg2QWVJCitkVXBXb05JRk9xVG1qWktJTFBQeTRjSEdZZHRCeGNlYjl3NGFVVVhDWVd2Y1pDY1hqRnEzMm5Rb3paZmt2UT09CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICAyZTo2YTowMDowMTowMDowMjoxZjpkNzo1MjoyMToyYzoxMTo1YzozYgorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPURFLCBPPVRDIFRydXN0Q2VudGVyIEdtYkgsIE9VPVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EsIENOPVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EgSUkKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEphbiAxMiAxNDozODo0MyAyMDA2IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogRGVjIDMxIDIyOjU5OjU5IDIwMjUgR01UCisgICAgICAgIFN1YmplY3Q6IEM9REUsIE89VEMgVHJ1c3RDZW50ZXIgR21iSCwgT1U9VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSwgQ049VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YWI6ODA6ODc6OWI6OGU6ZjA6YzM6N2M6ODc6ZDc6ZTg6MjQ6ODI6MTE6CisgICAgICAgICAgICAgICAgICAgIGIzOjNjOmRkOjQzOjYyOmVlOmY4OmMzOjQ1OmRhOmU4OmUxOmEwOjVmOmQxOgorICAgICAgICAgICAgICAgICAgICAyYTpiMjplYTo5Mzo2ODpkZjpiNDpjODpkNjo0MzplOTpjNDo3NTo1OTo3ZjoKKyAgICAgICAgICAgICAgICAgICAgZmM6ZTE6MWQ6Zjg6MzE6NzA6MjM6MWI6ODg6OWU6Mjc6Yjk6N2I6ZmQ6M2E6CisgICAgICAgICAgICAgICAgICAgIGQyOmM5OmE5OmU5OjE0OjJmOjkwOmJlOjAzOjUyOmMxOjQ5OmNkOmY2OmZkOgorICAgICAgICAgICAgICAgICAgICBlNDowODo2NjowYjo1Nzo4YTphMjo0MjphMDpiODpkNTo3Zjo2OTo1Yzo5MDoKKyAgICAgICAgICAgICAgICAgICAgMzI6YjI6OTc6MGQ6Y2E6NGE6ZGM6NDY6M2U6MDI6NTU6ODk6NTM6ZTM6MWE6CisgICAgICAgICAgICAgICAgICAgIDVhOmNiOjM2OmM2OjA3OjU2OmY3OjhjOmNmOjExOmY0OjRjOmJiOjMwOjcwOgorICAgICAgICAgICAgICAgICAgICAwNDo5NTphNTpmNjozOTo4YzpmZDo3Mzo4MTowODo3ZDo4OTo1ZTozMjoxZToKKyAgICAgICAgICAgICAgICAgICAgMjI6YTk6MjI6NDU6NGI6YjA6NjY6MmU6MzA6Y2M6OWY6NjU6ZmQ6ZmM6Y2I6CisgICAgICAgICAgICAgICAgICAgIDgxOmE5OmYxOmUwOjNiOmFmOmEzOjg2OmQxOjg5OmVhOmM0OjQ1Ojc5OjUwOgorICAgICAgICAgICAgICAgICAgICA1ZDphZTplOToyMTo3NDo5Mjo0ZDo4Yjo1OTo4Mjo4Zjo5NDplMzplOTo0YToKKyAgICAgICAgICAgICAgICAgICAgZjE6ZTc6NDk6YjA6MTQ6ZTM6ZjU6NjI6Y2I6ZDU6NzI6YmQ6MWY6Yjk6ZDI6CisgICAgICAgICAgICAgICAgICAgIDlmOmEwOmNkOmE4OmZhOjAxOmM4OmQ5OjBkOmRmOmRhOmZjOjQ3OjlkOmIzOgorICAgICAgICAgICAgICAgICAgICBjODo1NDpkZjo0OTo0YTpmMToyMTphOTpmZToxODo0ZTplZTo0ODpkNDoxOToKKyAgICAgICAgICAgICAgICAgICAgYmI6ZWY6N2Q6ZTQ6ZTI6OWQ6Y2I6NWI6YjY6NmU6ZmY6ZTM6Y2Q6NWE6ZTc6CisgICAgICAgICAgICAgICAgICAgIDc0OjgyOjA1OmJhOjgwOjI1OjM4OmNiOmU0OjY5OjllOmFmOjQxOmFhOjFhOgorICAgICAgICAgICAgICAgICAgICA4NDpmNQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEUzOkFCOjU0OjRDOjgwOkExOkRCOjU2OjQzOkI3OjkxOjRBOkNCOkYzOjgyOjdBOjEzOjVDOjA4OkFCCisgICAgICAgICAgICBYNTA5djMgQ1JMIERpc3RyaWJ1dGlvbiBQb2ludHM6IAorICAgICAgICAgICAgICAgIFVSSTpodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybAorICAgICAgICAgICAgICAgIFVSSTpsZGFwOi8vd3d3LnRydXN0Y2VudGVyLmRlL0NOPVRDJTIwVHJ1c3RDZW50ZXIlMjBDbGFzcyUyMDIlMjBDQSUyMElJLE89VEMlMjBUcnVzdENlbnRlciUyMEdtYkgsT1U9cm9vdGNlcnRzLERDPXRydXN0Y2VudGVyLERDPWRlP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q/YmFzZT8KKworICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA4YzpkNzpkZjo3ZTplZToxYjo4MDoxMDpiMzo4MzpmNTpkYjoxMTplYTo2Yjo0YjphODo5MjoKKyAgICAgICAgMTg6ZDk6Zjc6MDc6Mzk6ZjU6MmM6YmU6MDY6NzU6N2E6Njg6NTM6MTU6MWM6ZWE6NGE6ZWQ6CisgICAgICAgIDVlOmZjOjIzOmIyOjEzOmEwOmQzOjA5OmZmOmY2OmY2OjJlOjZiOjQxOjcxOjc5OmNkOmUyOgorICAgICAgICA2ZDpmZDphZTo1OTo2Yjo4NToxZDpiODo0ZToyMjo5YTplZDo2NjozOTo2ZTo0Yjo5NDplNjoKKyAgICAgICAgNTU6ZmM6MGI6MWI6OGI6Nzc6YzE6NTM6MTM6NjY6ODk6ZDk6Mjg6ZDY6OGI6ZjM6NDU6NGE6CisgICAgICAgIDYzOmI3OmZkOjdiOjBiOjYxOjVkOmI4OjZkOmJlOmMzOmRjOjViOjc5OmQyOmVkOjg2OmU1OgorICAgICAgICBhMjo0ZDpiZTo1ZTo3NDo3Yzo2YTplZDoxNjozODoxZjo3Zjo1ODo4MTo1YToxYTplYjozMjoKKyAgICAgICAgODg6MmQ6YjI6ZjM6Mzk6Nzc6ODA6YWY6NWU6YjY6NjE6NzU6Mjk6ZGI6MjM6NGQ6ODg6Y2E6CisgICAgICAgIDUwOjI4OmNiOjg1OmQyOmQzOjEwOmEyOjU5OjZlOmQzOjkzOjU0OjAwOjdhOmEyOjQ2Ojk1OgorICAgICAgICA4NjowNTo5YzphOToxOTo5ODplNTozMTo3MjowYzowMDplMjo2NzpkOTo0MDplMDoyNDozMzoKKyAgICAgICAgN2I6NmY6MmM6Yjk6NWM6YWI6NjU6OWQ6MmM6YWM6NzY6ZWE6MzU6OTk6ZjU6OTc6Yjk6MGY6CisgICAgICAgIDI0OmVjOmM3Ojc2OjIxOjI4OjY1OmFlOjU3OmU4OjA3Ojg4Ojc1OjRhOjU2OmEwOmQyOjA1OgorICAgICAgICAzYTphNDplNjo4ZDo5Mjo4ODoyYzpmMzpmMjplMTpjMTpjNjo2MTpkYjo0MTpjNTpjNzo5YjoKKyAgICAgICAgZjc6MGU6MWE6NTE6NDU6YzI6NjE6NmI6ZGM6NjQ6Mjc6MTc6OGM6NWE6Yjc6ZGE6NzQ6Mjg6CisgICAgICAgIGNkOjk3OmU0OmJkCitTSEExIEZpbmdlcnByaW50PUFFOjUwOjgzOkVEOjdDOkY0OjVDOkJDOjhGOjYxOkM2OjIxOkZFOjY4OjVEOjc5OjQyOjIxOjE1OjZFCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMmU4NzE0Y2IuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8yZTg3MTRjYi4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFlODJmYWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMmU4NzE0Y2IuMApAQCAtMCwwICsxLDEwMyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlGVWpDQ0JEcWdBd0lCQWdJQkFqQU5CZ2txaGtpRzl3MEJBUVVGQURCa01Rc3dDUVlEVlFRR0V3SkxVakVOCitNQXNHQTFVRUNoTUVTMGxUUVRFdU1Dd0dBMVVFQ3hNbFMyOXlaV0VnUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvCitiM0pwZEhrZ1EyVnVkSEpoYkRFV01CUUdBMVVFQXhNTlMwbFRRU0JTYjI5MFEwRWdNekFlRncwd05ERXhNVGt3CitOak01TlRGYUZ3MHhOREV4TVRrd05qTTVOVEZhTUdReEN6QUpCZ05WQkFZVEFrdFNNUTB3Q3dZRFZRUUtFd1JMCitTVk5CTVM0d0xBWURWUVFMRXlWTGIzSmxZU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVTQkRaVzUwCitjbUZzTVJZd0ZBWURWUVFERXcxTFNWTkJJRkp2YjNSRFFTQXpNSUlCSURBTkJna3Foa2lHOXcwQkFRRUZBQU9DCitBUTBBTUlJQkNBS0NBUUVBM3JydEYyV3UwYjFLUGF6YmdITE1XT0huNFpQYXpEQjZ6KzhMcmkyblE2dS9wMExQCitDRllJcEVjZGZmcUc3OWd3bHlZMFlUeUFEdmpVNjUvOElqQWJvVzArNDB6U1ZVNFdRRGZDOWdkdTJ3ZTFwWXlXCitnZUtiWEg2VVljak9oRHl4K2dEbWN0TUpoWGZwM0Y0aFQ3VGtUdlRpRjZ0UXJ4ei9vVGxZZFZzU3NwYTVqZkJ3CitZa2hiVmlncXBZZVJOcmtlSlBXNXVudTJVbEZiRjFwZ0JXeWN3dWJHakQ3NTZ0MDhqUCtKM2tOd3JCMjQ4WFhOCitPTXBURFVkb2FzWThHTXE5NGJTK0R2VFE0OUlUK3JCUkVSSFVRYXZvOURtTzRUU0VUd3VUcW1vNC9PWEdlRWV1CitkaGY2b1lBM0JnQVZDUDFySTQ3NmNnMlYxa3Rpc1dqQzNUU2JYUUlCQTZPQ0FnOHdnZ0lMTUI4R0ExVWRJd1FZCitNQmFBRkkrQjhOcW16WFE4dm1iMEZXdEdwUDRHS015cU1CMEdBMVVkRGdRV0JCU1BnZkRhcHMxMFBMNW05QlZyCitScVQrQmlqTXFqQU9CZ05WSFE4QkFmOEVCQU1DQVFZd2dnRXVCZ05WSFNBRWdnRWxNSUlCSVRDQ0FSMEdCRlVkCitJQUF3Z2dFVE1EQUdDQ3NHQVFVRkJ3SUJGaVJvZEhSd09pOHZkM2QzTG5KdmIzUmpZUzV2Y2k1cmNpOXlZMkV2CitZM0J6TG1oMGJXd3dnZDRHQ0NzR0FRVUZCd0lDTUlIUkhvSE94M1FBSU1kNHlaM0JITEtVQUNDczljZDR4M2pKCituY0VjeDRXeXlMTGtBQ2dBVkFCb0FHa0Fjd0FnQUdNQVpRQnlBSFFBYVFCbUFHa0FZd0JoQUhRQVpRQWdBR2tBCitjd0FnQUdFQVl3QmpBSElBWlFCa0FHa0FkQUJsQUdRQUlBQjFBRzRBWkFCbEFISUFJQUJGQUd3QVpRQmpBSFFBCitjZ0J2QUc0QWFRQmpBQ0FBVXdCcEFHY0FiZ0JoQUhRQWRRQnlBR1VBSUFCQkFHTUFkQUFnQUc4QVpnQWdBSFFBCithQUJsQUNBQVVnQmxBSEFBZFFCaUFHd0FhUUJqQUNBQWJ3Qm1BQ0FBU3dCdkFISUFaUUJoQUNrd013WURWUjBSCitCQ3d3S3FRb01DWXhKREFpQmdOVkJBTU1HKzJWbk9xMXJleWdsZXV6dE91enRPMll1T3luaE8yZHBleWJrREF6CitCZ05WSFJJRUxEQXFwQ2d3SmpFa01DSUdBMVVFQXd3YjdaV2M2cld0N0tDVjY3TzA2N08wN1ppNDdLZUU3WjJsCis3SnVRTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3REFZRFZSMGtCQVV3QTRBQkFEQU5CZ2txaGtpRzl3MEJBUVVGCitBQU9DQVFFQXo5YjNEdjJ3akc0RkZZNm9YQ3V5V3RFZVY2WmVHS3FDRVFqOG1iZGJwK1BJMHFMVCtTUTA5K1BrCityb2xVUjlOcFNjbUF3UkhyNGluSDlnYUxYN3JpWHMrcnc4N1A3cElsM0o4NUhnNEQ5TjZRVzZGd21WekhjMDdKCitwSFZKZXlXaG40S1NqVTNzWWNVTU1xZkhPRGlBVlRvcWd4MmNaSG01RGFjMVNtanZqLzhGMkxwT1ZtSFkrRXB3CittQWlXazloZ3h6cnNYNThkS3pWUFNCU2htcnR2N3RJRGhsUHhFTWNIVkdKZU5vN2lIQ3NkRjAzbTlWcnZpcnFDCis2SGZaS0JGK040ZEtsQXJKUU9rMXBUcjdaRDd5WHhaNjgzYlh6dTQvUkIxRnFsOFJxbE1jT2g5U1VXSlVENk9RCitOYzlOYjdySHZpd0o4VFg0QWJzazNUQzhTQS91MlE9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAyICgweDIpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9S1IsIE89S0lTQSwgT1U9S29yZWEgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgQ2VudHJhbCwgQ049S0lTQSBSb290Q0EgMworICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTm92IDE5IDA2OjM5OjUxIDIwMDQgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBOb3YgMTkgMDY6Mzk6NTEgMjAxNCBHTVQKKyAgICAgICAgU3ViamVjdDogQz1LUiwgTz1LSVNBLCBPVT1Lb3JlYSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDZW50cmFsLCBDTj1LSVNBIFJvb3RDQSAzCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpkZTpiYTplZDoxNzo2NTphZTpkMTpiZDo0YTozZDphYzpkYjo4MDo3MjoKKyAgICAgICAgICAgICAgICAgICAgY2M6NTg6ZTE6ZTc6ZTE6OTM6ZGE6Y2M6MzA6N2E6Y2Y6ZWY6MGI6YWU6MmQ6CisgICAgICAgICAgICAgICAgICAgIGE3OjQzOmFiOmJmOmE3OjQyOmNmOjA4OjU2OjA4OmE0OjQ3OjFkOjdkOmZhOgorICAgICAgICAgICAgICAgICAgICA4NjplZjpkODozMDo5NzoyNjozNDo2MTozYzo4MDowZTpmODpkNDplYjo5ZjoKKyAgICAgICAgICAgICAgICAgICAgZmM6MjI6MzA6MWI6YTE6NmQ6M2U6ZTM6NGM6ZDI6NTU6NGU6MTY6NDA6Mzc6CisgICAgICAgICAgICAgICAgICAgIGMyOmY2OjA3OjZlOmRiOjA3OmI1OmE1OjhjOjk2OjgxOmUyOjliOjVjOjdlOgorICAgICAgICAgICAgICAgICAgICA5NDo2MTpjODpjZTo4NDozYzpiMTpmYTowMDplNjo3MjpkMzowOTo4NTo3NzoKKyAgICAgICAgICAgICAgICAgICAgZTk6ZGM6NWU6MjE6NGY6YjQ6ZTQ6NGU6ZjQ6ZTI6MTc6YWI6NTA6YWY6MWM6CisgICAgICAgICAgICAgICAgICAgIGZmOmExOjM5OjU4Ojc1OjViOjEyOmIyOjk2OmI5OjhkOmYwOjcwOjYyOjQ4OgorICAgICAgICAgICAgICAgICAgICA1Yjo1NjoyODoyYTphNTo4Nzo5MTozNjpiOToxZToyNDpmNTpiOTpiYTo3YjoKKyAgICAgICAgICAgICAgICAgICAgYjY6NTI6NTE6NWI6MTc6NWE6NjA6MDU6NmM6OWM6YzI6ZTY6YzY6OGM6M2U6CisgICAgICAgICAgICAgICAgICAgIGY5OmVhOmRkOjNjOjhjOmZmOjg5OmRlOjQzOjcwOmFjOjFkOmI4OmYxOjc1OgorICAgICAgICAgICAgICAgICAgICBjZDozODpjYTo1MzowZDo0Nzo2ODo2YTpjNjozYzoxODpjYTpiZDplMTpiNDoKKyAgICAgICAgICAgICAgICAgICAgYmU6MGU6ZjQ6ZDA6ZTM6ZDI6MTM6ZmE6YjA6NTE6MTE6MTE6ZDQ6NDE6YWI6CisgICAgICAgICAgICAgICAgICAgIGU4OmY0OjM5OjhlOmUxOjM0Ojg0OjRmOjBiOjkzOmFhOjZhOjM4OmZjOmU1OgorICAgICAgICAgICAgICAgICAgICBjNjo3ODo0NzphZTo3NjoxNzpmYTphMTo4MDozNzowNjowMDoxNTowODpmZDoKKyAgICAgICAgICAgICAgICAgICAgNmI6MjM6OGU6ZmE6NzI6MGQ6OTU6ZDY6NGI6NjI6YjE6Njg6YzI6ZGQ6MzQ6CisgICAgICAgICAgICAgICAgICAgIDliOjVkCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDMgKDB4MykKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQXV0aG9yaXR5IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBrZXlpZDo4Rjo4MTpGMDpEQTpBNjpDRDo3NDozQzpCRTo2NjpGNDoxNTo2Qjo0NjpBNDpGRTowNjoyODpDQzpBQQorCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgOEY6ODE6RjA6REE6QTY6Q0Q6NzQ6M0M6QkU6NjY6RjQ6MTU6NkI6NDY6QTQ6RkU6MDY6Mjg6Q0M6QUEKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBDZXJ0aWZpY2F0ZSBQb2xpY2llczogCisgICAgICAgICAgICAgICAgUG9saWN5OiBYNTA5djMgQW55IFBvbGljeQorICAgICAgICAgICAgICAgICAgQ1BTOiBodHRwOi8vd3d3LnJvb3RjYS5vci5rci9yY2EvY3BzLmh0bWwKKyAgICAgICAgICAgICAgICAgIFVzZXIgTm90aWNlOgorICAgICAgICAgICAgICAgICAgICBFeHBsaWNpdCBUZXh0OiDHdAorCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBBbHRlcm5hdGl2ZSBOYW1lOiAKKyAgICAgICAgICAgICAgICBEaXJOYW1lOi9DTj1ceEVEXHg5NVx4OUNceEVBXHhCNVx4QURceEVDXHhBMFx4OTVceEVCXHhCM1x4QjRceEVCXHhCM1x4QjRceEVEXHg5OFx4QjhceEVDXHhBN1x4ODRceEVEXHg5RFx4QTVceEVDXHg5Qlx4OTAKKyAgICAgICAgICAgIFg1MDl2MyBJc3N1ZXIgQWx0ZXJuYXRpdmUgTmFtZTogCisgICAgICAgICAgICAgICAgRGlyTmFtZTovQ049XHhFRFx4OTVceDlDXHhFQVx4QjVceEFEXHhFQ1x4QTBceDk1XHhFQlx4QjNceEI0XHhFQlx4QjNceEI0XHhFRFx4OThceEI4XHhFQ1x4QTdceDg0XHhFRFx4OURceEE1XHhFQ1x4OUJceDkwCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIFBvbGljeSBDb25zdHJhaW50czogCisgICAgICAgICAgICAgICAgUmVxdWlyZSBFeHBsaWNpdCBQb2xpY3k6MAorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBjZjpkNjpmNzowZTpmZDpiMDo4Yzo2ZTowNToxNTo4ZTphODo1YzoyYjpiMjo1YTpkMToxZToKKyAgICAgICAgNTc6YTY6NWU6MTg6YWE6ODI6MTE6MDg6ZmM6OTk6Yjc6NWI6YTc6ZTM6Yzg6ZDI6YTI6ZDM6CisgICAgICAgIGY5OjI0OjM0OmY3OmUzOmU0OmFlOjg5OjU0OjQ3OmQzOjY5OjQ5OmM5OjgwOmMxOjExOmViOgorICAgICAgICBlMjoyOTpjNzpmNjowNjo4Yjo1ZjpiYTplMjo1ZTpjZjphYjpjMzpjZTpjZjplZTo5MjoyNToKKyAgICAgICAgZGM6OWY6Mzk6MWU6MGU6MDM6ZjQ6ZGU6OTA6NWI6YTE6NzA6OTk6NWM6Yzc6NzM6NGU6Yzk6CisgICAgICAgIGE0Ojc1OjQ5OjdiOjI1OmExOjlmOjgyOjkyOjhkOjRkOmVjOjYxOmM1OjBjOjMyOmE3OmM3OgorICAgICAgICAzODozODo4MDo1NTozYToyYTo4MzoxZDo5Yzo2NDo3OTpiOTowZDphNzozNTo0YTo2ODplZjoKKyAgICAgICAgOGY6ZmY6MDU6ZDg6YmE6NGU6NTY6NjE6ZDg6Zjg6NGE6NzA6OTg6MDg6OTY6OTM6ZDg6NjA6CisgICAgICAgIGM3OjNhOmVjOjVmOjlmOjFkOjJiOjM1OjRmOjQ4OjE0OmExOjlhOmJiOjZmOmVlOmQyOjAzOgorICAgICAgICA4Njo1MzpmMToxMDpjNzowNzo1NDo2Mjo1ZTozNjo4ZTplMjoxYzoyYjoxZDoxNzo0ZDplNjoKKyAgICAgICAgZjU6NWE6ZWY6OGE6YmE6ODI6ZTg6Nzc6ZDk6Mjg6MTE6N2U6Mzc6ODc6NGE6OTQ6MGE6Yzk6CisgICAgICAgIDQwOmU5OjM1OmE1OjNhOmZiOjY0OjNlOmYyOjVmOjE2OjdhOmYzOjc2OmQ3OmNlOmVlOjNmOgorICAgICAgICA0NDoxZDo0NTphYTo1ZjoxMTphYTo1MzoxYzozYToxZjo1Mjo1MTo2Mjo1NDowZjphMzo5MDoKKyAgICAgICAgMzU6Y2Y6NGQ6NmY6YmE6Yzc6YmU6MmM6MDk6ZjE6MzU6Zjg6MDE6YmI6MjQ6ZGQ6MzA6YmM6CisgICAgICAgIDQ4OjBmOmVlOmQ5CitTSEExIEZpbmdlcnByaW50PTVGOjRFOjFGOkNGOjMxOkI3OjkxOjNCOjg1OjBCOjU0OkY2OkU1OkZGOjUwOjFBOjJCOjZGOkM2OkNGCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMmZhODcwMTkuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8yZmE4NzAxOS4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE3OTc5NTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMmZhODcwMTkuMApAQCAtMCwwICsxLDg0IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUQ1akNDQXM2Z0F3SUJBZ0lRVjhzemI4SmNGdVpIRmhmamtERm80REFOQmdrcWhraUc5dzBCQVFVRkFEQmkKK01Rc3dDUVlEVlFRR0V3SlZVekVoTUI4R0ExVUVDaE1ZVG1WMGQyOXlheUJUYjJ4MWRHbHZibk1nVEM1TUxrTXUKK01UQXdMZ1lEVlFRREV5ZE9aWFIzYjNKcklGTnZiSFYwYVc5dWN5QkRaWEowYVdacFkyRjBaU0JCZFhSb2IzSnAKK2RIa3dIaGNOTURZeE1qQXhNREF3TURBd1doY05Namt4TWpNeE1qTTFPVFU1V2pCaU1Rc3dDUVlEVlFRR0V3SlYKK1V6RWhNQjhHQTFVRUNoTVlUbVYwZDI5eWF5QlRiMngxZEdsdmJuTWdUQzVNTGtNdU1UQXdMZ1lEVlFRREV5ZE8KK1pYUjNiM0pySUZOdmJIVjBhVzl1Y3lCRFpYSjBhV1pwWTJGMFpTQkJkWFJvYjNKcGRIa3dnZ0VpTUEwR0NTcUcKK1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURrdkg2U01HM0cySTRyQzd4R3p1QW5sdDdlK2ZvUzB6d3oKK2M3TUVMN3h4ak9XZnRpSmdQbDlkemduL2dnd2JtbEZRR2lhSjNkVmhYUm5jRWc4dENxSkRYUmZRTkpJZzZuUFAKK09Dd0dKZ2w2Y3ZmNlVETDR3cFBUYWFJanprR3h6T1RWSHpiUmlqcjRqR1BpRkZscDdRM1RmMnZvdUFQbFQycmwKK21HTnBTQVcrTHY4enR1bVhXV240WnhtdWsyR1dSQlhUY3JBL3ZHcDk3RWgvamNPcnFuRXJVMmxCVXpTMXNMbkYKK0JnckVzRVgxUVYxdWlVVjdQVHNtakhUQzVkTFJmYklSMVB0WU1pS2FnTW5jL1F6cGYxNERsODQ3QUJTSEozQTQKK3FZNXVzeWQybUZIZ0JlTWhxeHJWaFNJOEtiV2FGc1dBcVBTN2F6Q1BMMFlDb3JFTUl1RFRBZ01CQUFHamdaY3cKK2daUXdIUVlEVlIwT0JCWUVGQ0V3eWZzQTEwNlkyb2VxS3RDbkxyRkFNYWRNTUE0R0ExVWREd0VCL3dRRUF3SUIKK0JqQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01GSUdBMVVkSHdSTE1Fa3dSNkJGb0VPR1FXaDBkSEE2THk5amNtd3UKK2JtVjBjMjlzYzNOc0xtTnZiUzlPWlhSM2IzSnJVMjlzZFhScGIyNXpRMlZ5ZEdsbWFXTmhkR1ZCZFhSb2IzSnAKK2RIa3VZM0pzTUEwR0NTcUdTSWIzRFFFQkJRVUFBNElCQVFDN3Jrdm50MWZyZjZvdHQzTkhoV3JCNUtVZDVPYzgKKzZmUlpaWGUxZWx0YWpTVTI0SHFYTGpqQVYyQ0RtQWFEbjdsMmVtNVE0THFJTFB4RnpCaXdtWlZSRHV3ZHVJai8KK2gxQWNnc0xqNERLQXY2QUxSOGpETWUrWlp6S0FUeGNoZVF4cFhONWVOSzRDdFNicVVOOS9HR1VzeWZKajRha0gKKy9ueHhIMnN6SkdvZUJmY0ZhTUJxRXNzdVhtSExyaWpUZnNLMFpwRW1Yend1SkYvTFdBL3JLT3l2RVpiejNIdHYKK3dLZUk4bE4zczJCZXJxNG8yalVzYnpSRjB5YmgzdXhiVHlkckZueTlSQVFZZ3JPSmVSY1FjVDE2b2haTzlRSE4KK3BHeGxhS0ZKZGx4RHlkaThObWRzcFpTMTFNeTV2V28xVmlIZTJNUHIrOHVrWUV5d1ZhQ2dlMWV5CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICA1NzpjYjozMzo2ZjpjMjo1YzoxNjplNjo0NzoxNjoxNzplMzo5MDozMTo2ODplMAorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPU5ldHdvcmsgU29sdXRpb25zIEwuTC5DLiwgQ049TmV0d29yayBTb2x1dGlvbnMgQ2VydGlmaWNhdGUgQXV0aG9yaXR5CisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBEZWMgIDEgMDA6MDA6MDAgMjAwNiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IERlYyAzMSAyMzo1OTo1OSAyMDI5IEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPU5ldHdvcmsgU29sdXRpb25zIEwuTC5DLiwgQ049TmV0d29yayBTb2x1dGlvbnMgQ2VydGlmaWNhdGUgQXV0aG9yaXR5CisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDplNDpiYzo3ZTo5MjozMDo2ZDpjNjpkODo4ZToyYjowYjpiYzo0NjpjZToKKyAgICAgICAgICAgICAgICAgICAgZTA6Mjc6OTY6ZGU6ZGU6Zjk6ZmE6MTI6ZDM6M2M6MzM6NzM6YjM6MDQ6MmY6CisgICAgICAgICAgICAgICAgICAgIGJjOjcxOjhjOmU1OjlmOmI2OjIyOjYwOjNlOjVmOjVkOmNlOjA5OmZmOjgyOgorICAgICAgICAgICAgICAgICAgICAwYzoxYjo5YTo1MTo1MDoxYToyNjo4OTpkZDpkNTo2MTo1ZDoxOTpkYzoxMjoKKyAgICAgICAgICAgICAgICAgICAgMGY6MmQ6MGE6YTI6NDM6NWQ6MTc6ZDA6MzQ6OTI6MjA6ZWE6NzM6Y2Y6Mzg6CisgICAgICAgICAgICAgICAgICAgIDJjOjA2OjI2OjA5OjdhOjcyOmY3OmZhOjUwOjMyOmY4OmMyOjkzOmQzOjY5OgorICAgICAgICAgICAgICAgICAgICBhMjoyMzpjZTo0MTpiMTpjYzplNDpkNToxZjozNjpkMTo4YTozYTpmODo4YzoKKyAgICAgICAgICAgICAgICAgICAgNjM6ZTI6MTQ6NTk6Njk6ZWQ6MGQ6ZDM6N2Y6NmI6ZTg6Yjg6MDM6ZTU6NGY6CisgICAgICAgICAgICAgICAgICAgIDZhOmU1Ojk4OjYzOjY5OjQ4OjA1OmJlOjJlOmZmOjMzOmI2OmU5Ojk3OjU5OgorICAgICAgICAgICAgICAgICAgICA2OTpmODo2NzoxOTphZTo5Mzo2MTo5Njo0NDoxNTpkMzo3MjpiMDozZjpiYzoKKyAgICAgICAgICAgICAgICAgICAgNmE6N2Q6ZWM6NDg6N2Y6OGQ6YzM6YWI6YWE6NzE6MmI6NTM6Njk6NDE6NTM6CisgICAgICAgICAgICAgICAgICAgIDM0OmI1OmIwOmI5OmM1OjA2OjBhOmM0OmIwOjQ1OmY1OjQxOjVkOjZlOjg5OgorICAgICAgICAgICAgICAgICAgICA0NTo3YjozZDozYjoyNjo4Yzo3NDpjMjplNTpkMjpkMTo3ZDpiMjoxMTpkNDoKKyAgICAgICAgICAgICAgICAgICAgZmI6NTg6MzI6MjI6OWE6ODA6Yzk6ZGM6ZmQ6MGM6ZTk6N2Y6NWU6MDM6OTc6CisgICAgICAgICAgICAgICAgICAgIGNlOjNiOjAwOjE0Ojg3OjI3OjcwOjM4OmE5OjhlOjZlOmIzOjI3Ojc2Ojk4OgorICAgICAgICAgICAgICAgICAgICA1MTplMDowNTplMzoyMTphYjoxYTpkNTo4NToyMjozYzoyOTpiNTo5YToxNjoKKyAgICAgICAgICAgICAgICAgICAgYzU6ODA6YTg6ZjQ6YmI6NmI6MzA6OGY6MmY6NDY6MDI6YTI6YjE6MGM6MjI6CisgICAgICAgICAgICAgICAgICAgIGUwOmQzCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICAyMTozMDpDOTpGQjowMDpENzo0RTo5ODpEQTo4NzpBQToyQTpEMDpBNzoyRTpCMTo0MDozMTpBNzo0QworICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBDUkwgRGlzdHJpYnV0aW9uIFBvaW50czogCisgICAgICAgICAgICAgICAgVVJJOmh0dHA6Ly9jcmwubmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsCisKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgYmI6YWU6NGI6ZTc6Yjc6NTc6ZWI6N2Y6YWE6MmQ6Yjc6NzM6NDc6ODU6NmE6YzE6ZTQ6YTU6CisgICAgICAgIDFkOmU0OmU3OjNjOmU5OmY0OjU5OjY1Ojc3OmI1OjdhOjViOjVhOjhkOjI1OjM2OmUwOjdhOgorICAgICAgICA5NzoyZTozODpjMDo1Nzo2MDo4Mzo5ODowNjo4Mzo5ZjpiOTo3Njo3YTo2ZTo1MDplMDpiYToKKyAgICAgICAgODg6MmM6ZmM6NDU6Y2M6MTg6YjA6OTk6OTU6NTE6MGU6ZWM6MWQ6Yjg6ODg6ZmY6ODc6NTA6CisgICAgICAgIDFjOjgyOmMyOmUzOmUwOjMyOjgwOmJmOmEwOjBiOjQ3OmM4OmMzOjMxOmVmOjk5OjY3OjMyOgorICAgICAgICA4MDo0ZjoxNzoyMTo3OTowYzo2OTo1YzpkZTo1ZTozNDphZTowMjpiNToyNjplYTo1MDpkZjoKKyAgICAgICAgN2Y6MTg6NjU6MmM6Yzk6ZjI6NjM6ZTE6YTk6MDc6ZmU6N2M6NzE6MWY6NmI6MzM6MjQ6NmE6CisgICAgICAgIDFlOjA1OmY3OjA1OjY4OmMwOjZhOjEyOmNiOjJlOjVlOjYxOmNiOmFlOjI4OmQzOjdlOmMyOgorICAgICAgICBiNDo2Njo5MToyNjo1ZjozYzoyZToyNDo1ZjpjYjo1ODowZjplYjoyODplYzphZjoxMTo5NjoKKyAgICAgICAgZjM6ZGM6N2I6NmY6YzA6YTc6ODg6ZjI6NTM6Nzc6YjM6NjA6NWU6YWU6YWU6Mjg6ZGE6MzU6CisgICAgICAgIDJjOjZmOjM0OjQ1OmQzOjI2OmUxOmRlOmVjOjViOjRmOjI3OjZiOjE2OjdjOmJkOjQ0OjA0OgorICAgICAgICAxODo4MjpiMzo4OTo3OToxNzoxMDo3MTozZDo3YTphMjoxNjo0ZTpmNTowMTpjZDphNDo2YzoKKyAgICAgICAgNjU6Njg6YTE6NDk6NzY6NWM6NDM6Yzk6ZDg6YmM6MzY6Njc6NmM6YTU6OTQ6YjU6ZDQ6Y2M6CisgICAgICAgIGI5OmJkOjZhOjM1OjU2OjIxOmRlOmQ4OmMzOmViOmZiOmNiOmE0OjYwOjRjOmIwOjU1OmEwOgorICAgICAgICBhMDo3Yjo1NzpiMgorU0hBMSBGaW5nZXJwcmludD03NDpGODpBMzpDMzpFRjpFNzpCMzo5MDowNjo0Qjo4Mzo5MDozQzoyMTo2NDo2MDoyMDpFNTpERjpDRQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzJmYjE4NTBhLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMmZiMTg1MGEuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ODQ5ZDI1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzJmYjE4NTBhLjAKQEAgLTAsMCArMSwxMjQgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRnBEQ0NBNHlnQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFVRkFEQmpNUXN3Q1FZRFZRUUdFd0pWVXpFYworTUJvR0ExVUVDaE1UUVcxbGNtbGpZU0JQYm14cGJtVWdTVzVqTGpFMk1EUUdBMVVFQXhNdFFXMWxjbWxqWVNCUAorYm14cGJtVWdVbTl2ZENCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlU0F5TUI0WERUQXlNRFV5T0RBMgorTURBd01Gb1hEVE0zTURreU9URTBNRGd3TUZvd1l6RUxNQWtHQTFVRUJoTUNWVk14SERBYUJnTlZCQW9URTBGdAorWlhKcFkyRWdUMjVzYVc1bElFbHVZeTR4TmpBMEJnTlZCQU1UTFVGdFpYSnBZMkVnVDI1c2FXNWxJRkp2YjNRZworUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa2dNakNDQWlJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dJUAorQURDQ0Fnb0NnZ0lCQU14QlJSM3BQVTBROW95eFFjbmdYc3NOdDc5SGM5UHdWVTNkeGd6NnNXWUZhczE0dE53QworMjA2Qjg5ZW5mSEc4ZFdPZ1hlTUhERWpzSmNRRElQVC9EanNTLzV1TjRjYlZHN1J0SXVPeDIzOGhaSytHdkZjaQorS3RaSGdWZEVnbFpUdllZVUFRdjhmM1NrV3E3eHVoRzFtMWhhZ0xRM2VBa3pmREpIQTF6RXBZTkk5RmRXYm9FMgorSnhoUDdKc293dFMwMTN3TVBnd3IzOG9FMThhTzZsaE9xS1NsR0J4c1JaaWpRZEV0MHNkdGpSbnhyWG0zZ1QrOQorQm9JbkxSQllCYlY0QmJrdjJ3eHJrSkIrRkZrNHU1UWtFK1hSblJUZjA0Sk5SdkNBT1ZJeUQrT0VzbnBEOGw3ZQorWHo4ZDNlT3lHNkNoS2lNRGJpNEJGWWRjcG5WMXg1ZGh2dDZHM05SSTI3MHF2MHBWMnVoOVVQdTBnQmU0bEw4QgorUGVyYXVuemdXR2NYdVZqZ2lJWkdaMnlkRUVkWU10QTFmSGtxa0tKYUVCRWpOYTB2ek9SS1c2ZklKL0tEM2w2NworWG5mbjZLVnVZOElOWFdIUWpOSnNXaUVPeWlpanppcnBsY2RJejVadkhaSWx5TWJHd2NFTUJhd214TkoxMHVFcQorWjhBOVc2V2E2ODk3R3FpZEZFWGxENkNhWmQ0dktMM09iNVJtZzBncDJPcGxqSytUMldTZlZWY212Mi9MTnpHWgorbzJDN0hLMkpOREppdUVNaEJuSU1vVnh0UnNYNktjOHczb25jY1Z2ZHRqYyszMUQxdUFjbEp1Vzh0ZjQ4QXJPMworK0w1RHdZY1JsSjRqYkJlS3VJb25ERlJIOEttendJQ01vQ2ZySFJuakI0NTNjTW9yOUgxMjRIaG5BZ01CQUFHagorWXpCaE1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZFMUZ3V2c0dTNPcGFhRWc1KzMxSXFFagorRk5lZU1COEdBMVVkSXdRWU1CYUFGRTFGd1dnNHUzT3BhYUVnNSszMUlxRWpGTmVlTUE0R0ExVWREd0VCL3dRRQorQXdJQmhqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FnRUFaMnNHdVY5Rk95cExNN1BtRzJ0WlRpTE11YmVrSmNtbgoreFBCVWxndGs4N0ZZVDE1Ui9MS1hleWRsd3VYSzV3ME1KWHRpNC9xZnRJZTNSVWF2ZzZXWFNJeWx2ZkVXSzV0MgorTEhvMVlHd1JnSmZNcVpKUzVpdm1hZTJwK0RZdExIZS9ZVWpSWXd1NVcxTHRHTEJEUWlLbXNYZXUzbW5GemNjYworb2JHbEhCRDdHTDRhY04zQmtrdStLVnFkUHpXKzVYMVIrRlhnSlhVamh4NWMzTHFkc0t5emFkc1hnOG4zM2d5OAorQ055Um5xalExeFUzYzZVMXVQeCt4VVJBQnNQcitDS0FYRWZPQXVNUm4wVC8vWm95ekgxa1VRN3JWeVoyT3VNZQorSWp6Q3BqYmRHZStuL0JMekpzQlpNWVZNbk5qUDM2VE16Q21ULzVSdGRsd1RDSmZ5N2FVTFRkM295V2dPWnRNQQorRGpNU1c3eVY1VEtRcUxQR2JJT3RkKzZMZm42eHFhdlQ0Zkcyd0xIcWlNRG4wNURwS0pLVWUyaDdseW9LWnkyRgorQWpnUTVBTmgxTm9sTnNjSVdDMmhwMUd2TUFwSjlhWnBod2N0UkVaMmppcmxtanZYR0tMOG5EZ1F6TVk3MHJVWAorT20vOXJpVzk5WEpaWkxGMEtqaGZHRXpmejNFRVdqYlV2eStabk9qWnVyR1Y1Z0pMSWFGYjFjRlBqNjVwYlZQYgorQVpPMVhCNFkzV1JheWhnb1BtTUVFZjBjalFBUHVEZmZaNHFkWnFrQ2FwSC9FOG92WFlPOGg1TnMzQ1JSRmdRbAorWnZxejJjSzZLYjZhU0RpQ21mUy9PMG94R2ZtL2ppRXpGTXBQVkYvN3p2dVBjWC85WGhtZ0QwdVJ1TVJVdkFhdworUlk4bWthS08vcWs9CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDEgKDB4MSkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgTz1BbWVyaWNhIE9ubGluZSBJbmMuLCBDTj1BbWVyaWNhIE9ubGluZSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IDIKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IE1heSAyOCAwNjowMDowMCAyMDAyIEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogU2VwIDI5IDE0OjA4OjAwIDIwMzcgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89QW1lcmljYSBPbmxpbmUgSW5jLiwgQ049QW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoNDA5NiBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoNDA5NiBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpjYzo0MTo0NToxZDplOTozZDo0ZDoxMDpmNjo4YzpiMTo0MTpjOTplMDoKKyAgICAgICAgICAgICAgICAgICAgNWU6Y2I6MGQ6Yjc6YmY6NDc6NzM6ZDM6ZjA6NTU6NGQ6ZGQ6YzY6MGM6ZmE6CisgICAgICAgICAgICAgICAgICAgIGIxOjY2OjA1OjZhOmNkOjc4OmI0OmRjOjAyOmRiOjRlOjgxOmYzOmQ3OmE3OgorICAgICAgICAgICAgICAgICAgICA3Yzo3MTpiYzo3NTo2MzphMDo1ZDplMzowNzowYzo0ODplYzoyNTpjNDowMzoKKyAgICAgICAgICAgICAgICAgICAgMjA6ZjQ6ZmY6MGU6M2I6MTI6ZmY6OWI6OGQ6ZTE6YzY6ZDU6MWI6YjQ6NmQ6CisgICAgICAgICAgICAgICAgICAgIDIyOmUzOmIxOmRiOjdmOjIxOjY0OmFmOjg2OmJjOjU3OjIyOjJhOmQ2OjQ3OgorICAgICAgICAgICAgICAgICAgICA4MTo1Nzo0NDo4Mjo1Njo1MzpiZDo4NjoxNDowMTowYjpmYzo3Zjo3NDphNDoKKyAgICAgICAgICAgICAgICAgICAgNWE6YWU6ZjE6YmE6MTE6YjU6OWI6NTg6NWE6ODA6YjQ6Mzc6Nzg6MDk6MzM6CisgICAgICAgICAgICAgICAgICAgIDdjOjMyOjQ3OjAzOjVjOmM0OmE1OjgzOjQ4OmY0OjU3OjU2OjZlOjgxOjM2OgorICAgICAgICAgICAgICAgICAgICAyNzoxODo0ZjplYzo5YjoyODpjMjpkNDpiNDpkNzo3YzowYzozZTowYzoyYjoKKyAgICAgICAgICAgICAgICAgICAgZGY6Y2E6MDQ6ZDc6YzY6OGU6ZWE6NTg6NGU6YTg6YTQ6YTU6MTg6MWM6NmM6CisgICAgICAgICAgICAgICAgICAgIDQ1Ojk4OmEzOjQxOmQxOjJkOmQyOmM3OjZkOjhkOjE5OmYxOmFkOjc5OmI3OgorICAgICAgICAgICAgICAgICAgICA4MTozZjpiZDowNjo4MjoyNzoyZDoxMDo1ODowNTpiNTo3ODowNTpiOToyZjoKKyAgICAgICAgICAgICAgICAgICAgZGI6MGM6NmI6OTA6OTA6N2U6MTQ6NTk6Mzg6YmI6OTQ6MjQ6MTM6ZTU6ZDE6CisgICAgICAgICAgICAgICAgICAgIDlkOjE0OmRmOmQzOjgyOjRkOjQ2OmYwOjgwOjM5OjUyOjMyOjBmOmUzOjg0OgorICAgICAgICAgICAgICAgICAgICBiMjo3YTo0MzpmMjo1ZTpkZTo1ZjozZjoxZDpkZDplMzpiMjoxYjphMDphMToKKyAgICAgICAgICAgICAgICAgICAgMmE6MjM6MDM6NmU6MmU6MDE6MTU6ODc6NWM6YTY6NzU6NzU6Yzc6OTc6NjE6CisgICAgICAgICAgICAgICAgICAgIGJlOmRlOjg2OmRjOmQ0OjQ4OmRiOmJkOjJhOmJmOjRhOjU1OmRhOmU4OjdkOgorICAgICAgICAgICAgICAgICAgICA1MDpmYjpiNDo4MDoxNzpiODo5NDpiZjowMTozZDplYTpkYTpiYTo3YzplMDoKKyAgICAgICAgICAgICAgICAgICAgNTg6Njc6MTc6Yjk6NTg6ZTA6ODg6ODY6NDY6Njc6NmM6OWQ6MTA6NDc6NTg6CisgICAgICAgICAgICAgICAgICAgIDMyOmQwOjM1OjdjOjc5OjJhOjkwOmEyOjVhOjEwOjExOjIzOjM1OmFkOjJmOgorICAgICAgICAgICAgICAgICAgICBjYzplNDo0YTo1YjphNzpjODoyNzpmMjo4MzpkZTo1ZTpiYjo1ZTo3NzplNzoKKyAgICAgICAgICAgICAgICAgICAgZTg6YTU6NmU6NjM6YzI6MGQ6NWQ6NjE6ZDA6OGM6ZDI6NmM6NWE6MjE6MGU6CisgICAgICAgICAgICAgICAgICAgIGNhOjI4OmEzOmNlOjJhOmU5Ojk1OmM3OjQ4OmNmOjk2OjZmOjFkOjkyOjI1OgorICAgICAgICAgICAgICAgICAgICBjODpjNjpjNjpjMTpjMTowYzowNTphYzoyNjpjNDpkMjo3NTpkMjplMToyYToKKyAgICAgICAgICAgICAgICAgICAgNjc6YzA6M2Q6NWI6YTU6OWE6ZWI6Y2Y6N2I6MWE6YTg6OWQ6MTQ6NDU6ZTU6CisgICAgICAgICAgICAgICAgICAgIDBmOmEwOjlhOjY1OmRlOjJmOjI4OmJkOmNlOjZmOjk0OjY2OjgzOjQ4OjI5OgorICAgICAgICAgICAgICAgICAgICBkODplYTo2NTo4YzphZjo5MzpkOTo2NDo5Zjo1NTo1NzoyNjpiZjo2ZjpjYjoKKyAgICAgICAgICAgICAgICAgICAgMzc6MzE6OTk6YTM6NjA6YmI6MWM6YWQ6ODk6MzQ6MzI6NjI6Yjg6NDM6MjE6CisgICAgICAgICAgICAgICAgICAgIDA2OjcyOjBjOmExOjVjOjZkOjQ2OmM1OmZhOjI5OmNmOjMwOmRlOjg5OmRjOgorICAgICAgICAgICAgICAgICAgICA3MTo1YjpkZDpiNjozNzozZTpkZjo1MDpmNTpiODowNzoyNToyNjplNTpiYzoKKyAgICAgICAgICAgICAgICAgICAgYjU6ZmU6M2M6MDI6YjM6Yjc6Zjg6YmU6NDM6YzE6ODc6MTE6OTQ6OWU6MjM6CisgICAgICAgICAgICAgICAgICAgIDZjOjE3OjhhOmI4OjhhOjI3OjBjOjU0OjQ3OmYwOmE5OmIzOmMwOjgwOjhjOgorICAgICAgICAgICAgICAgICAgICBhMDoyNzplYjoxZDoxOTplMzowNzo4ZTo3Nzo3MDpjYToyYjpmNDo3ZDo3NjoKKyAgICAgICAgICAgICAgICAgICAgZTA6Nzg6NjcKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICA0RDo0NTpDMTo2ODozODpCQjo3MzpBOTo2OTpBMToyMDpFNzpFRDpGNToyMjpBMToyMzoxNDpENzo5RQorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6NEQ6NDU6QzE6Njg6Mzg6QkI6NzM6QTk6Njk6QTE6MjA6RTc6RUQ6RjU6MjI6QTE6MjM6MTQ6RDc6OUUKKworICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBEaWdpdGFsIFNpZ25hdHVyZSwgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgNjc6NmI6MDY6Yjk6NWY6NDU6M2I6MmE6NGI6MzM6YjM6ZTY6MWI6NmI6NTk6NGU6MjI6Y2M6CisgICAgICAgIGI5OmI3OmE0OjI1OmM5OmE3OmM0OmYwOjU0Ojk2OjBiOjY0OmYzOmIxOjU4OjRmOjVlOjUxOgorICAgICAgICBmYzpiMjo5Nzo3YjoyNzo2NTpjMjplNTpjYTplNzowZDowYzoyNTo3Yjo2MjplMzpmYTo5ZjoKKyAgICAgICAgYjQ6ODc6Yjc6NDU6NDY6YWY6ODM6YTU6OTc6NDg6OGM6YTU6YmQ6ZjE6MTY6MmI6OWI6NzY6CisgICAgICAgIDJjOjdhOjM1OjYwOjZjOjExOjgwOjk3OmNjOmE5OjkyOjUyOmU2OjJiOmU2OjY5OmVkOmE5OgorICAgICAgICBmODozNjoyZDoyYzo3NzpiZjo2MTo0ODpkMTo2MzowYjpiOTo1Yjo1MjplZDoxODpiMDo0MzoKKyAgICAgICAgNDI6MjI6YTY6YjE6Nzc6YWU6ZGU6Njk6YzU6Y2Q6Yzc6MWM6YTE6YjE6YTU6MWM6MTA6ZmI6CisgICAgICAgIDE4OmJlOjFhOjcwOmRkOmMxOjkyOjRiOmJlOjI5OjVhOjlkOjNmOjM1OmJlOmU1OjdkOjUxOgorICAgICAgICBmODo1NTplMDoyNTo3NToyMzo4NzoxZTo1YzpkYzpiYTo5ZDpiMDphYzpiMzo2OTpkYjoxNzoKKyAgICAgICAgODM6Yzk6Zjc6ZGU6MGM6YmM6MDg6ZGM6OTE6OWU6YTg6ZDA6ZDc6MTU6Mzc6NzM6YTU6MzU6CisgICAgICAgIGI4OmZjOjdlOmM1OjQ0OjQwOjA2OmMzOmViOmY4OjIyOjgwOjVjOjQ3OmNlOjAyOmUzOjExOgorICAgICAgICA5Zjo0NDpmZjpmZDo5YTozMjpjYzo3ZDo2NDo1MTowZTplYjo1NzoyNjo3NjozYTplMzoxZToKKyAgICAgICAgMjI6M2M6YzI6YTY6MzY6ZGQ6MTk6ZWY6YTc6ZmM6MTI6ZjM6MjY6YzA6NTk6MzE6ODU6NGM6CisgICAgICAgIDljOmQ4OmNmOmRmOmE0OmNjOmNjOjI5OjkzOmZmOjk0OjZkOjc2OjVjOjEzOjA4Ojk3OmYyOgorICAgICAgICBlZDphNTowYjo0ZDpkZDplODpjOTo2ODowZTo2NjpkMzowMDowZTozMzoxMjo1YjpiYzo5NToKKyAgICAgICAgZTU6MzI6OTA6YTg6YjM6YzY6NmM6ODM6YWQ6Nzc6ZWU6OGI6N2U6N2U6YjE6YTk6YWI6ZDM6CisgICAgICAgIGUxOmYxOmI2OmMwOmIxOmVhOjg4OmMwOmU3OmQzOjkwOmU5OjI4OjkyOjk0OjdiOjY4OjdiOgorICAgICAgICA5NzoyYTowYTo2NzoyZDo4NTowMjozODoxMDplNDowMzo2MTpkNDpkYToyNTozNjpjNzowODoKKyAgICAgICAgNTg6MmQ6YTE6YTc6NTE6YWY6MzA6MGE6NDk6ZjU6YTY6Njk6ODc6MDc6MmQ6NDQ6NDY6NzY6CisgICAgICAgIDhlOjJhOmU1OjlhOjNiOmQ3OjE4OmEyOmZjOjljOjM4OjEwOmNjOmM2OjNiOmQyOmI1OjE3OgorICAgICAgICAzYTo2ZjpmZDphZToyNTpiZDpmNTo3Mjo1OTo2NDpiMTo3NDoyYTozODo1ZjoxODo0YzpkZjoKKyAgICAgICAgY2Y6NzE6MDQ6NWE6MzY6ZDQ6YmY6MmY6OTk6OWM6ZTg6ZDk6YmE6YjE6OTU6ZTY6MDI6NGI6CisgICAgICAgIDIxOmExOjViOmQ1OmMxOjRmOjhmOmFlOjY5OjZkOjUzOmRiOjAxOjkzOmI1OjVjOjFlOjE4OgorICAgICAgICBkZDo2NDo1YTpjYToxODoyODozZTo2MzowNDoxMTpmZDoxYzo4ZDowMDowZjpiODozNzpkZjoKKyAgICAgICAgNjc6OGE6OWQ6NjY6YTk6MDI6NmE6OTE6ZmY6MTM6Y2E6MmY6NWQ6ODM6YmM6ODc6OTM6NmM6CisgICAgICAgIGRjOjI0OjUxOjE2OjA0OjI1OjY2OmZhOmIzOmQ5OmMyOmJhOjI5OmJlOjlhOjQ4OjM4OjgyOgorICAgICAgICA5OTpmNDpiZjozYjo0YTozMToxOTpmOTpiZjo4ZToyMTozMzoxNDpjYTo0Zjo1NDo1ZjpmYjoKKyAgICAgICAgY2U6ZmI6OGY6NzE6N2Y6ZmQ6NWU6MTk6YTA6MGY6NGI6OTE6Yjg6YzQ6NTQ6YmM6MDY6YjA6CisgICAgICAgIDQ1OjhmOjI2OjkxOmEyOjhlOmZlOmE5CitTSEExIEZpbmdlcnByaW50PTg1OkI1OkZGOjY3OjlCOjBDOjc5Ojk2OjFGOkM4OjZFOjQ0OjIyOjAwOjQ2OjEzOkRCOjE3OjkyOjg0CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMzM4MTVlMTUuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8zMzgxNWUxNS4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg1Yzk2MWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMzM4MTVlMTUuMApAQCAtMCwwICsxLDE0OSBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlIeVRDQ0JiR2dBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUVVGQURCOU1Rc3dDUVlEVlFRR0V3SkpUREVXCitNQlFHQTFVRUNoTU5VM1JoY25SRGIyMGdUSFJrTGpFck1Da0dBMVVFQ3hNaVUyVmpkWEpsSUVScFoybDBZV3dnCitRMlZ5ZEdsbWFXTmhkR1VnVTJsbmJtbHVaekVwTUNjR0ExVUVBeE1nVTNSaGNuUkRiMjBnUTJWeWRHbG1hV05oCitkR2x2YmlCQmRYUm9iM0pwZEhrd0hoY05NRFl3T1RFM01UazBOak0yV2hjTk16WXdPVEUzTVRrME5qTTJXakI5CitNUXN3Q1FZRFZRUUdFd0pKVERFV01CUUdBMVVFQ2hNTlUzUmhjblJEYjIwZ1RIUmtMakVyTUNrR0ExVUVDeE1pCitVMlZqZFhKbElFUnBaMmwwWVd3Z1EyVnlkR2xtYVdOaGRHVWdVMmxuYm1sdVp6RXBNQ2NHQTFVRUF4TWdVM1JoCitjblJEYjIwZ1EyVnlkR2xtYVdOaGRHbHZiaUJCZFhSb2IzSnBkSGt3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBCitBNElDRHdBd2dnSUtBb0lDQVFEQmlOc0p2R3hHZkhpZmxYdTFNNUR5Y21MV3dUWWdJaVJlenVsMzhrTUtvZ1prCitwTXlPTnZnNDVpUHdibTJ4UE4xeW80VWNvZE05dERNcjB5K3YvdXF3UVZsbnRzUUdmUXFlZElYV2VVeUFOM3JmCitPUVZTV2ZmMEcwWkRwTktGaGRMRGNmTjFZalM2TElwL0hvL3U3VFRRRWNlV3pWSTl1alBXM1UzZUN6dEtTNS9DCitKaS82dFJZY2NqVjN5anhkNXNyaEpvc2FOblpjQWR0MEZDWCs3YldnaUEvZGVNb3RId2VYTUFFdGNubjZSdFlUCitLcWk1cHF1RFNSM2w4dS9kNUFHT0dBcVBZMU1XaFdLcERoazZ6TFZtcHNKcmRBZmtLK0YyUHJSdDJQWkU0WE5pCitIenZFdnFCVFZpVnNVUW4zcXF2S3YzYjliWnZ6bmR1L1BXYThERmFxcjVoSWxUcEwzNmRZVU5rNGRhbGI2a01NCitBditaNitoc1RYQmJLV1djM2FwZHpLOEJNZXdNNjlLTjZPcWNlK1p1OXlkbURCcEkxMjVDNHovZUlUNTc0UTF3CisrMk9xcUd3YVZMUmNKWHJKb3NtTEZxYTdMSDRYWGdWTldHNFNIUUh1RWhBTnhqSi9HUC84OVByTmJwSG9Oa20rCitHa2hwaThLV1RSb1NzbWtYd1FxUTF2cDVJa2kvdW50cCtIREgrbm8zMk5nTjBuWlBWLytRdCtPUjB0M3Z3bUMzCitaenJkL3FxYzhOU0xmM0lpenNhZmw3YjRyNHFnRUtqWit4akd0clZjVWp5SnRoa3Fjd0VLRHdPekVtRHllaStCCisyNk51L3lZd2wvV0wzWWxYdHEwOXM2OHJ4YmQyQXZDbDFpdWFoaFFxY3Ziak00eGRDVXNUMzd1TWRCTlNTd0lECitBUUFCbzRJQ1VqQ0NBazR3REFZRFZSMFRCQVV3QXdFQi96QUxCZ05WSFE4RUJBTUNBYTR3SFFZRFZSME9CQllFCitGRTRMN3hxa1FGdWxGMm1ITU1vMGFFUFFRYTd5TUdRR0ExVWRId1JkTUZzd0xLQXFvQ2lHSm1oMGRIQTZMeTlqCitaWEowTG5OMFlYSjBZMjl0TG05eVp5OXpabk5qWVMxamNtd3VZM0pzTUN1Z0thQW5oaVZvZEhSd09pOHZZM0pzCitMbk4wWVhKMFkyOXRMbTl5Wnk5elpuTmpZUzFqY213dVkzSnNNSUlCWFFZRFZSMGdCSUlCVkRDQ0FWQXdnZ0ZNCitCZ3NyQmdFRUFZRzFOd0VCQVRDQ0FUc3dMd1lJS3dZQkJRVUhBZ0VXSTJoMGRIQTZMeTlqWlhKMExuTjBZWEowCitZMjl0TG05eVp5OXdiMnhwWTNrdWNHUm1NRFVHQ0NzR0FRVUZCd0lCRmlsb2RIUndPaTh2WTJWeWRDNXpkR0Z5CitkR052YlM1dmNtY3ZhVzUwWlhKdFpXUnBZWFJsTG5Ca1pqQ0IwQVlJS3dZQkJRVUhBZ0l3Z2NNd0p4WWdVM1JoCitjblFnUTI5dGJXVnlZMmxoYkNBb1UzUmhjblJEYjIwcElFeDBaQzR3QXdJQkFScUJsMHhwYldsMFpXUWdUR2xoCitZbWxzYVhSNUxDQnlaV0ZrSUhSb1pTQnpaV04wYVc5dUlDcE1aV2RoYkNCTWFXMXBkR0YwYVc5dWN5b2diMllnCitkR2hsSUZOMFlYSjBRMjl0SUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVJRkJ2YkdsamVTQmhkbUZwCitiR0ZpYkdVZ1lYUWdhSFIwY0RvdkwyTmxjblF1YzNSaGNuUmpiMjB1YjNKbkwzQnZiR2xqZVM1d1pHWXdFUVlKCitZSVpJQVliNFFnRUJCQVFEQWdBSE1EZ0dDV0NHU0FHRytFSUJEUVFyRmlsVGRHRnlkRU52YlNCR2NtVmxJRk5UCitUQ0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVUQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FnRUFGbXlaCis5R1lNTlBYUWhWNTlDdXphRUU0NEhGN2ZwaVVGUzVFeXdlZzc4VDNkUkFsYkIwbUtLY3RtQXJleG12Y2xtQWs4CitqaHZoM1RhSEswdTdhTk01WmoyZ0pzZnlPWkVkVWF1Q2UzN1Z6bHJrNGdOWGNHbVhDUGxlV0tZSzM0d0dta1VXCitGamdLWGxmMllzZDZBZ1htdkI2MThwNzBxU21EK0xJVTQyNG9oMFREa0JyZU9LazhyRU5OWkVYTzNTaXBYUEp6Citld1Q0RitpcnNmTXVYR1J1Y3pFNkVyaThzeEhrZlkrQlVabzdqWW4wVFpObWV6d0Q3ZE9hSFpyelpWRDFvTkIxCitueSt2OE9xQ1E1ajRhWnlKZWNSRGprWnk0MlEyRXEvM0pSNDRpWkIzZnNOcmFybkR5MFJMckhpUWkrZkhMQjVMCitFVVRJTkZJbnpRcGRuNFhCaWRVYWVQS1ZFRk15M1lDRVpuWFp0V2dvKzJFdXZvU29PTUNaRW9hbEhtZGtyUVl1CitMNmx3aGNlV0QzeUpaZldPUTFRT3E5MmxnRG1VWU1BMHlaWndMS01TOVI5SWU3MGNmbXUzblpEMElqdXUrUHdxCit5dnFDVXFEdnIwdFZrK3ZCdGZBaWk2dzBUaVlpQktHSExIVkt0K1Y5RTllNERHVEFOdExKTDRZU2pDTUp3UnVDCitPM05KbzJwWGg1VGwxbmpGbVVOajQwM2dkeTNoWlpseWFRUWFSd25tRHdGV0pQc2Z2dzU1cVZndXVjUUpBWDZWCit1bTBBQmo2eTZrb1FPZGpRSy9XLzdIVy9sd0xGQ1JzSTNGVTM0b0g3TjRSRFlpREs1MVpMWmVyK2JNRWtreVNoCitOT3NGLzVvaXJwdDlQL0ZsVVFxbU1HcXo5SWdjZ0EzOGNvcm9nMTQ9CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDEgKDB4MSkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1JTCwgTz1TdGFydENvbSBMdGQuLCBPVT1TZWN1cmUgRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWduaW5nLCBDTj1TdGFydENvbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogU2VwIDE3IDE5OjQ2OjM2IDIwMDYgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBTZXAgMTcgMTk6NDY6MzYgMjAzNiBHTVQKKyAgICAgICAgU3ViamVjdDogQz1JTCwgTz1TdGFydENvbSBMdGQuLCBPVT1TZWN1cmUgRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWduaW5nLCBDTj1TdGFydENvbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDQwOTYgYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDQwOTYgYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YzE6ODg6ZGI6MDk6YmM6NmM6NDY6N2M6Nzg6OWY6OTU6N2I6YjU6MzM6CisgICAgICAgICAgICAgICAgICAgIDkwOmYyOjcyOjYyOmQ2OmMxOjM2OjIwOjIyOjI0OjVlOmNlOmU5Ojc3OmYyOgorICAgICAgICAgICAgICAgICAgICA0MzowYTphMjowNjo2NDphNDpjYzo4ZTozNjpmODozODplNjoyMzpmMDo2ZToKKyAgICAgICAgICAgICAgICAgICAgNmQ6YjE6M2M6ZGQ6NzI6YTM6ODU6MWM6YTE6ZDM6M2Q6YjQ6MzM6MmI6ZDM6CisgICAgICAgICAgICAgICAgICAgIDJmOmFmOmZlOmVhOmIwOjQxOjU5OjY3OmI2OmM0OjA2OjdkOjBhOjllOjc0OgorICAgICAgICAgICAgICAgICAgICA4NTpkNjo3OTo0Yzo4MDozNzo3YTpkZjozOTowNTo1Mjo1OTpmNzpmNDoxYjoKKyAgICAgICAgICAgICAgICAgICAgNDY6NDM6YTQ6ZDI6ODU6ODU6ZDI6YzM6NzE6ZjM6NzU6NjI6MzQ6YmE6MmM6CisgICAgICAgICAgICAgICAgICAgIDhhOjdmOjFlOjhmOmVlOmVkOjM0OmQwOjExOmM3Ojk2OmNkOjUyOjNkOmJhOgorICAgICAgICAgICAgICAgICAgICAzMzpkNjpkZDo0ZDpkZTowYjozYjo0YTo0Yjo5ZjpjMjoyNjoyZjpmYTpiNToKKyAgICAgICAgICAgICAgICAgICAgMTY6MWM6NzI6MzU6Nzc6Y2E6M2M6NWQ6ZTY6Y2E6ZTE6MjY6OGI6MWE6MzY6CisgICAgICAgICAgICAgICAgICAgIDc2OjVjOjAxOmRiOjc0OjE0OjI1OmZlOmVkOmI1OmEwOjg4OjBmOmRkOjc4OgorICAgICAgICAgICAgICAgICAgICBjYToyZDoxZjowNzo5NzozMDowMToyZDo3Mjo3OTpmYTo0NjpkNjoxMzoyYToKKyAgICAgICAgICAgICAgICAgICAgYTg6Yjk6YTY6YWI6ODM6NDk6MWQ6ZTU6ZjI6ZWY6ZGQ6ZTQ6MDE6OGU6MTg6CisgICAgICAgICAgICAgICAgICAgIDBhOjhmOjYzOjUzOjE2Ojg1OjYyOmE5OjBlOjE5OjNhOmNjOmI1OjY2OmE2OgorICAgICAgICAgICAgICAgICAgICBjMjo2Yjo3NDowNzplNDoyYjplMTo3NjozZTpiNDo2ZDpkODpmNjo0NDplMToKKyAgICAgICAgICAgICAgICAgICAgNzM6NjI6MWY6M2I6YzQ6YmU6YTA6NTM6NTY6MjU6NmM6NTE6MDk6Zjc6YWE6CisgICAgICAgICAgICAgICAgICAgIGFiOmNhOmJmOjc2OmZkOjZkOjliOmYzOjlkOmRiOmJmOjNkOjY2OmJjOjBjOgorICAgICAgICAgICAgICAgICAgICA1NjphYTphZjo5ODo0ODo5NTozYTo0YjpkZjphNzo1ODo1MDpkOTozODo3NToKKyAgICAgICAgICAgICAgICAgICAgYTk6NWI6ZWE6NDM6MGM6MDI6ZmY6OTk6ZWI6ZTg6NmM6NGQ6NzA6NWI6Mjk6CisgICAgICAgICAgICAgICAgICAgIDY1OjljOmRkOmFhOjVkOmNjOmFmOjAxOjMxOmVjOjBjOmViOmQyOjhkOmU4OgorICAgICAgICAgICAgICAgICAgICBlYTo5Yzo3YjplNjo2ZTpmNzoyNzo2NjowYzoxYTo0ODpkNzo2ZTo0MjplMzoKKyAgICAgICAgICAgICAgICAgICAgM2Y6ZGU6MjE6M2U6N2I6ZTE6MGQ6NzA6ZmI6NjM6YWE6YTg6NmM6MWE6NTQ6CisgICAgICAgICAgICAgICAgICAgIGI0OjVjOjI1OjdhOmM5OmEyOmM5OjhiOjE2OmE2OmJiOjJjOjdlOjE3OjVlOgorICAgICAgICAgICAgICAgICAgICAwNTo0ZDo1ODo2ZToxMjoxZDowMTplZToxMjoxMDowZDpjNjozMjo3ZjoxODoKKyAgICAgICAgICAgICAgICAgICAgZmY6ZmM6ZjQ6ZmE6Y2Q6NmU6OTE6ZTg6MzY6NDk6YmU6MWE6NDg6Njk6OGI6CisgICAgICAgICAgICAgICAgICAgIGMyOjk2OjRkOjFhOjEyOmIyOjY5OjE3OmMxOjBhOjkwOmQ2OmZhOjc5OjIyOgorICAgICAgICAgICAgICAgICAgICA0ODpiZjpiYTo3Yjo2OTpmODo3MDpjNzpmYTo3YTozNzpkODpkODowZDpkMjoKKyAgICAgICAgICAgICAgICAgICAgNzY6NGY6NTc6ZmY6OTA6Yjc6ZTM6OTE6ZDI6ZGQ6ZWY6YzI6NjA6Yjc6Njc6CisgICAgICAgICAgICAgICAgICAgIDNhOmRkOmZlOmFhOjljOmYwOmQ0OjhiOjdmOjcyOjIyOmNlOmM2OjlmOjk3OgorICAgICAgICAgICAgICAgICAgICBiNjpmODphZjo4YTphMDoxMDphODpkOTpmYjoxODpjNjpiNjpiNTo1Yzo1MjoKKyAgICAgICAgICAgICAgICAgICAgM2M6ODk6YjY6MTk6MmE6NzM6MDE6MGE6MGY6MDM6YjM6MTI6NjA6ZjI6N2E6CisgICAgICAgICAgICAgICAgICAgIDJmOjgxOmRiOmEzOjZlOmZmOjI2OjMwOjk3OmY1OjhiOmRkOjg5OjU3OmI2OgorICAgICAgICAgICAgICAgICAgICBhZDozZDpiMzphZjoyYjpjNTpiNzo3NjowMjpmMDphNTpkNjoyYjo5YTo4NjoKKyAgICAgICAgICAgICAgICAgICAgMTQ6MmE6NzI6ZjY6ZTM6MzM6OGM6NWQ6MDk6NGI6MTM6ZGY6YmI6OGM6NzQ6CisgICAgICAgICAgICAgICAgICAgIDEzOjUyOjRiCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogCisgICAgICAgICAgICAgICAgRGlnaXRhbCBTaWduYXR1cmUsIEtleSBFbmNpcGhlcm1lbnQsIEtleSBBZ3JlZW1lbnQsIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgNEU6MEI6RUY6MUE6QTQ6NDA6NUI6QTU6MTc6Njk6ODc6MzA6Q0E6MzQ6Njg6NDM6RDA6NDE6QUU6RjIKKyAgICAgICAgICAgIFg1MDl2MyBDUkwgRGlzdHJpYnV0aW9uIFBvaW50czogCisgICAgICAgICAgICAgICAgVVJJOmh0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsCisgICAgICAgICAgICAgICAgVVJJOmh0dHA6Ly9jcmwuc3RhcnRjb20ub3JnL3Nmc2NhLWNybC5jcmwKKworICAgICAgICAgICAgWDUwOXYzIENlcnRpZmljYXRlIFBvbGljaWVzOiAKKyAgICAgICAgICAgICAgICBQb2xpY3k6IDEuMy42LjEuNC4xLjIzMjIzLjEuMS4xCisgICAgICAgICAgICAgICAgICBDUFM6IGh0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmCisgICAgICAgICAgICAgICAgICBDUFM6IGh0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9pbnRlcm1lZGlhdGUucGRmCisgICAgICAgICAgICAgICAgICBVc2VyIE5vdGljZToKKyAgICAgICAgICAgICAgICAgICAgT3JnYW5pemF0aW9uOiBTdGFydCBDb21tZXJjaWFsIChTdGFydENvbSkgTHRkLgorICAgICAgICAgICAgICAgICAgICBOdW1iZXI6IDEKKyAgICAgICAgICAgICAgICAgICAgRXhwbGljaXQgVGV4dDogTGltaXRlZCBMaWFiaWxpdHksIHJlYWQgdGhlIHNlY3Rpb24gKkxlZ2FsIExpbWl0YXRpb25zKiBvZiB0aGUgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUG9saWN5IGF2YWlsYWJsZSBhdCBodHRwOi8vY2VydC5zdGFydGNvbS5vcmcvcG9saWN5LnBkZgorCisgICAgICAgICAgICBOZXRzY2FwZSBDZXJ0IFR5cGU6IAorICAgICAgICAgICAgICAgIFNTTCBDQSwgUy9NSU1FIENBLCBPYmplY3QgU2lnbmluZyBDQQorICAgICAgICAgICAgTmV0c2NhcGUgQ29tbWVudDogCisgICAgICAgICAgICAgICAgU3RhcnRDb20gRnJlZSBTU0wgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMTY6NmM6OTk6ZjQ6NjY6MGM6MzQ6ZjU6ZDA6ODU6NWU6N2Q6MGE6ZWM6ZGE6MTA6NGU6Mzg6CisgICAgICAgIDFjOjVlOmRmOmE2OjI1OjA1OjRiOjkxOjMyOmMxOmU4OjNiOmYxOjNkOmRkOjQ0OjA5OjViOgorICAgICAgICAwNzo0OTo4YToyOTpjYjo2NjowMjpiNzpiMTo5YTpmNzoyNTo5ODowOTozYzo4ZToxYjplMToKKyAgICAgICAgZGQ6MzY6ODc6MmI6NGI6YmI6Njg6ZDM6Mzk6NjY6M2Q6YTA6MjY6Yzc6ZjI6Mzk6OTE6MWQ6CisgICAgICAgIDUxOmFiOjgyOjdiOjdlOmQ1OmNlOjVhOmU0OmUyOjAzOjU3OjcwOjY5Ojk3OjA4OmY5OjVlOgorICAgICAgICA1ODphNjowYTpkZjo4YzowNjo5YTo0NToxNjoxNjozODowYTo1ZTo1NzpmNjo2MjpjNzo3YToKKyAgICAgICAgMDI6MDU6ZTY6YmM6MWU6YjU6ZjI6OWU6ZjQ6YTk6Mjk6ODM6Zjg6YjI6MTQ6ZTM6NmU6Mjg6CisgICAgICAgIDg3OjQ0OmMzOjkwOjFhOmRlOjM4OmE5OjNjOmFjOjQzOjRkOjY0OjQ1OmNlOmRkOjI4OmE5OgorICAgICAgICA1YzpmMjo3Mzo3YjowNDpmODoxNzplODphYjpiMTpmMzoyZTo1Yzo2NDo2ZTo3MzozMTozYToKKyAgICAgICAgMTI6Yjg6YmM6YjM6MTE6ZTQ6N2Q6OGY6ODE6NTE6OWE6M2I6OGQ6ODk6ZjQ6NGQ6OTM6NjY6CisgICAgICAgIDdiOjNjOjAzOmVkOmQzOjlhOjFkOjlhOmYzOjY1OjUwOmY1OmEwOmQwOjc1OjlmOjJmOmFmOgorICAgICAgICBmMDplYTo4Mjo0Mzo5ODpmODo2OTo5Yzo4OTo3OTpjNDo0Mzo4ZTo0Njo3MjplMzo2NDozNjoKKyAgICAgICAgMTI6YWY6Zjc6MjU6MWU6Mzg6ODk6OTA6Nzc6N2U6YzM6NmI6NmE6Yjk6YzM6Y2I6NDQ6NGI6CisgICAgICAgIGFjOjc4OjkwOjhiOmU3OmM3OjJjOjFlOjRiOjExOjQ0OmM4OjM0OjUyOjI3OmNkOjBhOjVkOgorICAgICAgICA5Zjo4NTpjMTo4OTpkNToxYTo3ODpmMjo5NToxMDo1MzozMjpkZDo4MDo4NDo2Njo3NTpkOToKKyAgICAgICAgYjU6Njg6Mjg6ZmI6NjE6MmU6YmU6ODQ6YTg6Mzg6YzA6OTk6MTI6ODY6YTU6MWU6Njc6NjQ6CisgICAgICAgIGFkOjA2OjJlOjJmOmE5OjcwOjg1OmM3Ojk2OjBmOjdjOjg5OjY1OmY1OjhlOjQzOjU0OjBlOgorICAgICAgICBhYjpkZDphNTo4MDozOTo5NDo2MDpjMDozNDpjOTo5Njo3MDoyYzphMzoxMjpmNToxZjo0ODoKKyAgICAgICAgN2I6YmQ6MWM6N2U6NmI6Yjc6OWQ6OTA6ZjQ6MjI6M2I6YWU6Zjg6ZmM6MmE6Y2E6ZmE6ODI6CisgICAgICAgIDUyOmEwOmVmOmFmOjRiOjU1OjkzOmViOmMxOmI1OmYwOjIyOjhiOmFjOjM0OjRlOjI2OjIyOgorICAgICAgICAwNDphMTo4NzoyYzo3NTo0YTpiNzplNTo3ZDoxMzpkNzpiODowYzo2NDpjMDozNjpkMjpjOToKKyAgICAgICAgMmY6ODY6MTI6OGM6MjM6MDk6YzE6MWI6ODI6M2I6NzM6NDk6YTM6NmE6NTc6ODc6OTQ6ZTU6CisgICAgICAgIGQ2Ojc4OmM1Ojk5OjQzOjYzOmUzOjRkOmUwOjc3OjJkOmUxOjY1Ojk5OjcyOjY5OjA0OjFhOgorICAgICAgICA0NzowOTplNjowZjowMTo1NjoyNDpmYjoxZjpiZjowZTo3OTphOTo1ODoyZTpiOTpjNDowOToKKyAgICAgICAgMDE6N2U6OTU6YmE6NmQ6MDA6MDY6M2U6YjI6ZWE6NGE6MTA6Mzk6ZDg6ZDA6MmI6ZjU6YmY6CisgICAgICAgIGVjOjc1OmJmOjk3OjAyOmM1OjA5OjFiOjA4OmRjOjU1OjM3OmUyOjgxOmZiOjM3Ojg0OjQzOgorICAgICAgICA2MjoyMDpjYTplNzo1Njo0Yjo2NTplYTpmZTo2YzpjMToyNDo5MzoyNDphMTozNDplYjowNToKKyAgICAgICAgZmY6OWE6MjI6YWU6OWI6N2Q6M2Y6ZjE6NjU6NTE6MGE6YTY6MzA6NmE6YjM6ZjQ6ODg6MWM6CisgICAgICAgIDgwOjBkOmZjOjcyOjhhOmU4OjgzOjVlCitTSEExIEZpbmdlcnByaW50PTNFOjJCOkY3OkYyOjAzOjFCOjk2OkYzOjhDOkU2OkM0OkQ4OkE4OjVEOjNFOjJEOjU4OjQ3OjZBOjBGCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMzQzZWI2Y2IuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8zNDNlYjZjYi4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVjY2ZiMmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMzQzZWI2Y2IuMApAQCAtMCwwICsxLDg2IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSURvVENDQW9tZ0F3SUJBZ0lMQkFBQUFBQUJENFdxTFVnd0RRWUpLb1pJaHZjTkFRRUZCUUF3T3pFWU1CWUcKK0ExVUVDaE1QUTNsaVpYSjBjblZ6ZEN3Z1NXNWpNUjh3SFFZRFZRUURFeFpEZVdKbGNuUnlkWE4wSUVkc2IySmgKK2JDQlNiMjkwTUI0WERUQTJNVEl4TlRBNE1EQXdNRm9YRFRJeE1USXhOVEE0TURBd01Gb3dPekVZTUJZR0ExVUUKK0NoTVBRM2xpWlhKMGNuVnpkQ3dnU1c1ak1SOHdIUVlEVlFRREV4WkRlV0psY25SeWRYTjBJRWRzYjJKaGJDQlMKK2IyOTBNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQStNaTh2UlJRWmhQLzhOTjUKKzdDUHl0eHJIam9YeEVuT21HYW9RMjV5aVpYUmFkejVSZlZiMjNDTzIxTzFmV0xFM1RkVkpEbTcxYW9mVzBvelMKK0o4YmkvemFmbUdXZ0UwN0dLbVNiMVpBU3p4UUc5RHZqMUNpKzZBNzRxMDVJbEcyT2xURVFYTzJpTGIzVk9tMnkKK0hMdGd3RVpMQWZWSnJuNUdpdEIwamFFTUFzN3UvT2VQdUd0bTgzOUVBTDltSlJRcjNSQXdIUWVXUDAzMmE3aVAKK3Qzc01wVGpyM2tmYjFWMDUvSWluODljcWRQSG9XcUk3bjFDNnBveEZOY0pRWlpYY1k0THYzYjkzVFp4aXlXTnoKK0Z0QXBEMG1wU1BDenFyZHN4YWN3T1VCZHJzVGlYU1pUOE00Y0l3aGhxSlFadWdSaVFPd2ZPSEIzRWdaeHB6QVkKK1hTVW5wUUlEQVFBQm80R2xNSUdpTUE0R0ExVWREd0VCL3dRRUF3SUJCakFQQmdOVkhSTUJBZjhFQlRBREFRSC8KK01CMEdBMVVkRGdRV0JCUzJDSHNOZXN5c0lFeUdWakplejZ0dWhTMXdWekEvQmdOVkhSOEVPREEyTURTZ01xQXcKK2hpNW9kSFJ3T2k4dmQzZDNNaTV3ZFdKc2FXTXRkSEoxYzNRdVkyOXRMMk55YkM5amRDOWpkSEp2YjNRdVkzSnMKK01COEdBMVVkSXdRWU1CYUFGTFlJZXcxNnpLd2dUSVpXTWw3UHEyNkZMWEJYTUEwR0NTcUdTSWIzRFFFQkJRVUEKK0E0SUJBUUJXN3dvam9GUk9sWmZKK0luYVJjSFVvd0FsOUI4VHE3ZWpoVmhwd2pDdDJCV0tMZVBKellGYStITWoKK1dxZDhCZlA5SWpzTzBRYkUyelpNY3dTTzViQWk1TVh6THFYWkkrTzRUa29ncDI0Q0pKOGlZR2Q3aXgxeUNjVXgKK1hPbDVuNEJIUGEyaEN3Y1VQVWYvQTJrYURBdEU1Mk1scDMreXliaDJoTzBqOW4wSHEwViswOSt6dittS3RzMm8KK29tY3JVdFczWmZBNVRHT2drWG1UVWc5VTNZTzduOUdQcDFOenc4di9NT3g4QkxqWVJCK1RYM0VKSXJkdVB1b2MKK0EwNmRHaUJoKzRFMzdGNzhDa1dyMStjWFZkQ2c2bUNicHZiampGc3B3Z1pnRkowdGwweXBreFdkWWNRQlgwalcKK1dMMVdNUkpPRWNnaDRMTVJrV1hidEthSU9NNVYKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDA0OjAwOjAwOjAwOjAwOjAxOjBmOjg1OmFhOjJkOjQ4CisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IE89Q3liZXJ0cnVzdCwgSW5jLCBDTj1DeWJlcnRydXN0IEdsb2JhbCBSb290CisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBEZWMgMTUgMDg6MDA6MDAgMjAwNiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IERlYyAxNSAwODowMDowMCAyMDIxIEdNVAorICAgICAgICBTdWJqZWN0OiBPPUN5YmVydHJ1c3QsIEluYywgQ049Q3liZXJ0cnVzdCBHbG9iYWwgUm9vdAorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6Zjg6Yzg6YmM6YmQ6MTQ6NTA6NjY6MTM6ZmY6ZjA6ZDM6Nzk6ZWM6MjM6CisgICAgICAgICAgICAgICAgICAgIGYyOmI3OjFhOmM3OjhlOjg1OmYxOjEyOjczOmE2OjE5OmFhOjEwOmRiOjljOgorICAgICAgICAgICAgICAgICAgICBhMjo2NTo3NDo1YTo3NzozZTo1MTo3ZDo1NjpmNjpkYzoyMzpiNjpkNDplZDoKKyAgICAgICAgICAgICAgICAgICAgNWY6NTg6YjE6Mzc6NGQ6ZDU6NDk6MGU6NmU6ZjU6NmE6ODc6ZDY6ZDI6OGM6CisgICAgICAgICAgICAgICAgICAgIGQyOjI3OmM2OmUyOmZmOjM2OjlmOjk4OjY1OmEwOjEzOjRlOmM2OjJhOjY0OgorICAgICAgICAgICAgICAgICAgICA5YjpkNTo5MDoxMjpjZjoxNDowNjpmNDozYjplMzpkNDoyODpiZTplODowZToKKyAgICAgICAgICAgICAgICAgICAgZjg6YWI6NGU6NDg6OTQ6NmQ6OGU6OTU6MzE6MTA6NWM6ZWQ6YTI6MmQ6YmQ6CisgICAgICAgICAgICAgICAgICAgIGQ1OjNhOjZkOmIyOjFjOmJiOjYwOmMwOjQ2OjRiOjAxOmY1OjQ5OmFlOjdlOgorICAgICAgICAgICAgICAgICAgICA0Njo4YTpkMDo3NDo4ZDphMTowYzowMjpjZTplZTpmYzplNzo4ZjpiODo2YjoKKyAgICAgICAgICAgICAgICAgICAgNjY6ZjM6N2Y6NDQ6MDA6YmY6NjY6MjU6MTQ6MmI6ZGQ6MTA6MzA6MWQ6MDc6CisgICAgICAgICAgICAgICAgICAgIDk2OjNmOjRkOmY2OjZiOmI4OjhmOmI3OjdiOjBjOmE1OjM4OmViOmRlOjQ3OgorICAgICAgICAgICAgICAgICAgICBkYjpkNTo1ZDozOTpmYzo4ODphNzpmMzpkNzoyYTo3NDpmMTplODo1YTphMjoKKyAgICAgICAgICAgICAgICAgICAgM2I6OWY6NTA6YmE6YTY6OGM6NDU6MzU6YzI6NTA6NjU6OTU6ZGM6NjM6ODI6CisgICAgICAgICAgICAgICAgICAgIGVmOmRkOmJmOjc3OjRkOjljOjYyOmM5OjYzOjczOjE2OmQwOjI5OjBmOjQ5OgorICAgICAgICAgICAgICAgICAgICBhOTo0ODpmMDpiMzphYTpiNzo2YzpjNTphNzozMDozOTo0MDo1ZDphZTpjNDoKKyAgICAgICAgICAgICAgICAgICAgZTI6NWQ6MjY6NTM6ZjA6Y2U6MWM6MjM6MDg6NjE6YTg6OTQ6MTk6YmE6MDQ6CisgICAgICAgICAgICAgICAgICAgIDYyOjQwOmVjOjFmOjM4OjcwOjc3OjEyOjA2OjcxOmE3OjMwOjE4OjVkOjI1OgorICAgICAgICAgICAgICAgICAgICAyNzphNQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEI2OjA4OjdCOjBEOjdBOkNDOkFDOjIwOjRDOjg2OjU2OjMyOjVFOkNGOkFCOjZFOjg1OjJEOjcwOjU3CisgICAgICAgICAgICBYNTA5djMgQ1JMIERpc3RyaWJ1dGlvbiBQb2ludHM6IAorICAgICAgICAgICAgICAgIFVSSTpodHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsCisKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOkI2OjA4OjdCOjBEOjdBOkNDOkFDOjIwOjRDOjg2OjU2OjMyOjVFOkNGOkFCOjZFOjg1OjJEOjcwOjU3CisKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgNTY6ZWY6MGE6MjM6YTA6NTQ6NGU6OTU6OTc6Yzk6Zjg6ODk6ZGE6NDU6YzE6ZDQ6YTM6MDA6CisgICAgICAgIDI1OmY0OjFmOjEzOmFiOmI3OmEzOjg1OjU4OjY5OmMyOjMwOmFkOmQ4OjE1OjhhOjJkOmUzOgorICAgICAgICBjOTpjZDo4MTo1YTpmODo3MzoyMzo1YTphNzo3YzowNTpmMzpmZDoyMjozYjowZTpkMTowNjoKKyAgICAgICAgYzQ6ZGI6MzY6NGM6NzM6MDQ6OGU6ZTU6YjA6MjI6ZTQ6YzU6ZjM6MmU6YTU6ZDk6MjM6ZTM6CisgICAgICAgIGI4OjRlOjRhOjIwOmE3OjZlOjAyOjI0OjlmOjIyOjYwOjY3OjdiOjhiOjFkOjcyOjA5OmM1OgorICAgICAgICAzMTo1YzplOTo3OTo5Zjo4MDo0NzozZDphZDphMTowYjowNzoxNDozZDo0NzpmZjowMzo2OToKKyAgICAgICAgMWE6MGM6MGI6NDQ6ZTc6NjM6MjU6YTc6N2Y6YjI6Yzk6Yjg6NzY6ODQ6ZWQ6MjM6ZjY6N2Q6CisgICAgICAgIDA3OmFiOjQ1OjdlOmQzOmRmOmIzOmJmOmU5OjhhOmI2OmNkOmE4OmEyOjY3OjJiOjUyOmQ1OgorICAgICAgICBiNzo2NTpmMDozOTo0Yzo2MzphMDo5MTo3OTo5Mzo1MjowZjo1NDpkZDo4MzpiYjo5ZjpkMToKKyAgICAgICAgOGY6YTc6NTM6NzM6YzM6Y2I6ZmY6MzA6ZWM6N2M6MDQ6Yjg6ZDg6NDQ6MWY6OTM6NWY6NzE6CisgICAgICAgIDA5OjIyOmI3OjZlOjNlOmVhOjFjOjAzOjRlOjlkOjFhOjIwOjYxOmZiOjgxOjM3OmVjOjVlOgorICAgICAgICBmYzowYTo0NTphYjpkNzplNzoxNzo1NTpkMDphMDplYTo2MDo5YjphNjpmNjplMzo4Yzo1YjoKKyAgICAgICAgMjk6YzI6MDY6NjA6MTQ6OWQ6MmQ6OTc6NGM6YTk6OTM6MTU6OWQ6NjE6YzQ6MDE6NWY6NDg6CisgICAgICAgIGQ2OjU4OmJkOjU2OjMxOjEyOjRlOjExOmM4OjIxOmUwOmIzOjExOjkxOjY1OmRiOmI0OmE2OgorICAgICAgICA4ODozODpjZTo1NQorU0hBMSBGaW5nZXJwcmludD01Rjo0MzpFNTpCMTpCRjpGODo3ODo4QzpBQzoxQzpDNzpDQTo0QTo5QTpDNjoyMjoyQjpDQzozNDpDNgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzM5OWU3NzU5LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvMzk5ZTc3NTkuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MWU0MWFmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzM5OWU3NzU5LjAKQEAgLTAsMCArMSw4MyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEcnpDQ0FwZWdBd0lCQWdJUUNEdmdWcEJDUnJHaGRXckpXWkhIU2pBTkJna3Foa2lHOXcwQkFRVUZBREJoCitNUXN3Q1FZRFZRUUdFd0pWVXpFVk1CTUdBMVVFQ2hNTVJHbG5hVU5sY25RZ1NXNWpNUmt3RndZRFZRUUxFeEIzCitkM2N1WkdsbmFXTmxjblF1WTI5dE1TQXdIZ1lEVlFRREV4ZEVhV2RwUTJWeWRDQkhiRzlpWVd3Z1VtOXZkQ0JECitRVEFlRncwd05qRXhNVEF3TURBd01EQmFGdzB6TVRFeE1UQXdNREF3TURCYU1HRXhDekFKQmdOVkJBWVRBbFZUCitNUlV3RXdZRFZRUUtFd3hFYVdkcFEyVnlkQ0JKYm1NeEdUQVhCZ05WQkFzVEVIZDNkeTVrYVdkcFkyVnlkQzVqCitiMjB4SURBZUJnTlZCQU1URjBScFoybERaWEowSUVkc2IySmhiQ0JTYjI5MElFTkJNSUlCSWpBTkJna3Foa2lHCis5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBNGp2aEVYTGVxS1RUbzFlcVVLS1BDM2VReWFLbDdoTE9sbHNCCitDU0RNQVpPblRqQzNVL2REeEdrQVY1M2lqU0xkaHdaQUFJRUp6czRiZzcvZnpUdHhSdUxXWnNjRnMzWW5Gbzk3CituaDZWZmU2M1NLTUkydGF2ZWd3NUJtVi9TbDBmdkJmNHE3N3VLTmQwZjNwNG1WbUZhRzVjSXpKTHYwN0E2RnB0Cis0M0MvZHhDLy9BSDJoZG1vUkJCWU1xbDFHTlhSb3I1SDRpZHE5Sm96K0VrSVlJdlVYN1E2aEwraHFrcE1mVDdQCitUMTlzZGw2Z1N6ZVJudHdpNW0zT0ZCcU9hc3YremJNVVpCZkhXeW1lTXIveTd2clRDMExVcTdkQk10b00xTy80CitnZFc3alZnL3RSdm9TU2lpY05veEJOMzNzaGJ5VEFwT0I2anRTajFldFgramtNT3ZKd0lEQVFBQm8yTXdZVEFPCitCZ05WSFE4QkFmOEVCQU1DQVlZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVUE5NVFOVmJSCitUTHRtOEtQaUd4dkRsN0k5MFZVd0h3WURWUjBqQkJnd0ZvQVVBOTVRTlZiUlRMdG04S1BpR3h2RGw3STkwVlV3CitEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBTXVjTjZwSUV4SUsrdDFFbkU5U3NQVGZyZ1QxZVhrSW95UVkvRXNyCitoTUF0dWRYSC92VEJIMWpMdUcyY2VuVG5tQ21yRWJYamNLQ2h6VXlJbVpPTWtYRGlxdzhjdnBPcC8yUFY1QWRnCiswNk8vblZzSjhkV080MVAwam1QNlA2ZmJ0R2JmWW1iVzBXNUJqZkl0dGVwM1NwK2RXT0lyV2NCQUkrMHRLSUpGCitQbmxVa2lhWTRJQklxRGZ2OE5aNVlCYmVyT2dPelc2c1JCYzRMMG5hNFVVK0tyazJVODg2VUFiM0x1akVWMGxzCitZU0VZMVFTdGVEd3NPb0JycCt1dkZSVHAySW5CdVRoczRwRnNpdjlrdVhjbFZ6REFHeVNqNGR6cDMwZDh0YlFrCitDQVV3N0MyOUM3OUZ2MUM1cWZQcm1BRVNyY2lJeHBnMFg0MEtQTWJwMVpXVmJkND0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDA4OjNiOmUwOjU2OjkwOjQyOjQ2OmIxOmExOjc1OjZhOmM5OjU5OjkxOmM3OjRhCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9VVMsIE89RGlnaUNlcnQgSW5jLCBPVT13d3cuZGlnaWNlcnQuY29tLCBDTj1EaWdpQ2VydCBHbG9iYWwgUm9vdCBDQQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTm92IDEwIDAwOjAwOjAwIDIwMDYgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBOb3YgMTAgMDA6MDA6MDAgMjAzMSBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgTz1EaWdpQ2VydCBJbmMsIE9VPXd3dy5kaWdpY2VydC5jb20sIENOPURpZ2lDZXJ0IEdsb2JhbCBSb290IENBCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDplMjozYjplMToxMTo3MjpkZTphODphNDpkMzphMzo1NzphYTo1MDphMjoKKyAgICAgICAgICAgICAgICAgICAgOGY6MGI6Nzc6OTA6Yzk6YTI6YTU6ZWU6MTI6Y2U6OTY6NWI6MDE6MDk6MjA6CisgICAgICAgICAgICAgICAgICAgIGNjOjAxOjkzOmE3OjRlOjMwOmI3OjUzOmY3OjQzOmM0OjY5OjAwOjU3OjlkOgorICAgICAgICAgICAgICAgICAgICBlMjo4ZDoyMjpkZDo4NzowNjo0MDowMDo4MTowOTpjZTpjZToxYjo4MzpiZjoKKyAgICAgICAgICAgICAgICAgICAgZGY6Y2Q6M2I6NzE6NDY6ZTI6ZDY6NjY6Yzc6MDU6YjM6NzY6Mjc6MTY6OGY6CisgICAgICAgICAgICAgICAgICAgIDdiOjllOjFlOjk1OjdkOmVlOmI3OjQ4OmEzOjA4OmRhOmQ2OmFmOjdhOjBjOgorICAgICAgICAgICAgICAgICAgICAzOTowNjo2NTo3Zjo0YTo1ZDoxZjpiYzoxNzpmODphYjpiZTplZToyODpkNzoKKyAgICAgICAgICAgICAgICAgICAgNzQ6N2Y6N2E6Nzg6OTk6NTk6ODU6Njg6NmU6NWM6MjM6MzI6NGI6YmY6NGU6CisgICAgICAgICAgICAgICAgICAgIGMwOmU4OjVhOjZkOmUzOjcwOmJmOjc3OjEwOmJmOmZjOjAxOmY2Ojg1OmQ5OgorICAgICAgICAgICAgICAgICAgICBhODo0NDoxMDo1ODozMjphOTo3NToxODpkNTpkMTphMjpiZTo0NzplMjoyNzoKKyAgICAgICAgICAgICAgICAgICAgNmE6ZjQ6OWE6MzM6Zjg6NDk6MDg6NjA6OGI6ZDQ6NWY6YjQ6M2E6ODQ6YmY6CisgICAgICAgICAgICAgICAgICAgIGExOmFhOjRhOjRjOjdkOjNlOmNmOjRmOjVmOjZjOjc2OjVlOmEwOjRiOjM3OgorICAgICAgICAgICAgICAgICAgICA5MTo5ZTpkYzoyMjplNjo2ZDpjZToxNDoxYTo4ZTo2YTpjYjpmZTpjZDpiMzoKKyAgICAgICAgICAgICAgICAgICAgMTQ6NjQ6MTc6Yzc6NWI6Mjk6OWU6MzI6YmY6ZjI6ZWU6ZmE6ZDM6MGI6NDI6CisgICAgICAgICAgICAgICAgICAgIGQ0OmFiOmI3OjQxOjMyOmRhOjBjOmQ0OmVmOmY4OjgxOmQ1OmJiOjhkOjU4OgorICAgICAgICAgICAgICAgICAgICAzZjpiNToxYjplODo0OToyODphMjo3MDpkYTozMTowNDpkZDpmNzpiMjoxNjoKKyAgICAgICAgICAgICAgICAgICAgZjI6NGM6MGE6NGU6MDc6YTg6ZWQ6NGE6M2Q6NWU6YjU6N2Y6YTM6OTA6YzM6CisgICAgICAgICAgICAgICAgICAgIGFmOjI3CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgRGlnaXRhbCBTaWduYXR1cmUsIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDAzOkRFOjUwOjM1OjU2OkQxOjRDOkJCOjY2OkYwOkEzOkUyOjFCOjFCOkMzOjk3OkIyOjNEOkQxOjU1CisgICAgICAgICAgICBYNTA5djMgQXV0aG9yaXR5IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBrZXlpZDowMzpERTo1MDozNTo1NjpEMTo0QzpCQjo2NjpGMDpBMzpFMjoxQjoxQjpDMzo5NzpCMjozRDpEMTo1NQorCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIGNiOjljOjM3OmFhOjQ4OjEzOjEyOjBhOmZhOmRkOjQ0OjljOjRmOjUyOmIwOmY0OmRmOmFlOgorICAgICAgICAwNDpmNTo3OTo3OTowODphMzoyNDoxODpmYzo0YjoyYjo4NDpjMDoyZDpiOTpkNTpjNzpmZToKKyAgICAgICAgZjQ6YzE6MWY6NTg6Y2I6Yjg6NmQ6OWM6N2E6NzQ6ZTc6OTg6Mjk6YWI6MTE6YjU6ZTM6NzA6CisgICAgICAgIGEwOmExOmNkOjRjOjg4Ojk5OjkzOjhjOjkxOjcwOmUyOmFiOjBmOjFjOmJlOjkzOmE5OmZmOgorICAgICAgICA2MzpkNTplNDowNzo2MDpkMzphMzpiZjo5ZDo1YjowOTpmMTpkNTo4ZTplMzo1MzpmNDo4ZToKKyAgICAgICAgNjM6ZmE6M2Y6YTc6ZGI6YjQ6NjY6ZGY6NjI6NjY6ZDY6ZDE6NmU6NDE6OGQ6ZjI6MmQ6YjU6CisgICAgICAgIGVhOjc3OjRhOjlmOjlkOjU4OmUyOjJiOjU5OmMwOjQwOjIzOmVkOjJkOjI4OjgyOjQ1OjNlOgorICAgICAgICA3OTo1NDo5MjoyNjo5ODplMDo4MDo0ODphODozNzplZjpmMDpkNjo3OTo2MDoxNjpkZTphYzoKKyAgICAgICAgZTg6MGU6Y2Q6NmU6YWM6NDQ6MTc6Mzg6MmY6NDk6ZGE6ZTE6NDU6M2U6MmE6Yjk6MzY6NTM6CisgICAgICAgIGNmOjNhOjUwOjA2OmY3OjJlOmU4OmM0OjU3OjQ5OjZjOjYxOjIxOjE4OmQ1OjA0OmFkOjc4OgorICAgICAgICAzYzoyYzozYTo4MDo2YjphNzplYjphZjoxNToxNDplOTpkODo4OTpjMTpiOTozODo2YzplMjoKKyAgICAgICAgOTE6NmM6OGE6ZmY6NjQ6Yjk6Nzc6MjU6NTc6MzA6YzA6MWI6MjQ6YTM6ZTE6ZGM6ZTk6ZGY6CisgICAgICAgIDQ3OjdjOmI1OmI0OjI0OjA4OjA1OjMwOmVjOjJkOmJkOjBiOmJmOjQ1OmJmOjUwOmI5OmE5OgorICAgICAgICBmMzplYjo5ODowMToxMjphZDpjODo4ODpjNjo5ODozNDo1Zjo4ZDowYTozYzpjNjplOTpkNToKKyAgICAgICAgOTU6OTU6NmQ6ZGUKK1NIQTEgRmluZ2VycHJpbnQ9QTg6OTg6NUQ6M0E6NjU6RTU6RTU6QzQ6QjI6RDc6RDY6NkQ6NDA6QzY6REQ6MkY6QjE6OUM6NTQ6MzYKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8zYTNiMDJjZS4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzNhM2IwMmNlLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGI3NDRmNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8zYTNiMDJjZS4wCkBAIC0wLDAgKzEsODQgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRDhUQ0NBdG1nQXdJQkFnSVFRVDF5eC9Sckg0RkRmZkhTS0ZUZm1qQU5CZ2txaGtpRzl3MEJBUVVGQURDQgoraWpFTE1Ba0dBMVVFQmhNQ1EwZ3hFREFPQmdOVkJBb1RCMWRKVTJWTFpYa3hHekFaQmdOVkJBc1RFa052Y0hseQorYVdkb2RDQW9ZeWtnTWpBd05URWlNQ0FHQTFVRUN4TVpUMGxUVkVVZ1JtOTFibVJoZEdsdmJpQkZibVJ2Y25ObAorWkRFb01DWUdBMVVFQXhNZlQwbFRWRVVnVjBsVFpVdGxlU0JIYkc5aVlXd2dVbTl2ZENCSFFTQkRRVEFlRncwdworTlRFeU1URXhOakF6TkRSYUZ3MHpOekV5TVRFeE5qQTVOVEZhTUlHS01Rc3dDUVlEVlFRR0V3SkRTREVRTUE0RworQTFVRUNoTUhWMGxUWlV0bGVURWJNQmtHQTFVRUN4TVNRMjl3ZVhKcFoyaDBJQ2hqS1NBeU1EQTFNU0l3SUFZRAorVlFRTEV4bFBTVk5VUlNCR2IzVnVaR0YwYVc5dUlFVnVaRzl5YzJWa01TZ3dKZ1lEVlFRREV4OVBTVk5VUlNCWAorU1ZObFMyVjVJRWRzYjJKaGJDQlNiMjkwSUVkQklFTkJNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QQorTUlJQkNnS0NBUUVBeTArekFKczlOdDM1MFVscWF4QkpIK3pZSzdMRytES0JLVU9WVEpvWkl5RVZSZDdqeUJ4UgorVlZ1dWsrZzMveXRyNmRUcXZpcmRxRkVyMTJiRFlWeGdBc2oxem5KN083anlUbVVJbXMya2FobkJBYnR6cHRmMgordzkzTnZLU0x0WmxodUFHaW85Uk4xQVU5a2EzNHRBaHhaSzl3OFJ4cmZ2YkRkNTBrYzN2a0RJemgyVGJobVlzRgorbVF2dFJURUp5c0lBMi9keW9KYXFsWWZRanNlMllYTU5kbWFNM0J1MFk2S2ZmNU1UTVBHaEo5dloveXhWaUpHZworNEU4SHNDaFdqQmdibDBTT2lkM2dGMjduS3UrUE9Rb3hoSUxZUUJSSkxucEI1S2YrNDJUTXdWbHhTeXdocDF0OQorNEIzUkxvR2J3OWhvOTcyV0c2eHdzUllVQzl0Z3VTWUJCUUlEQVFBQm8xRXdUekFMQmdOVkhROEVCQU1DQVlZdworRHdZRFZSMFRBUUgvQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVc3dOK3JqYThzSG5SM0pRbXRoRytJYkpwaHBRdworRUFZSkt3WUJCQUdDTnhVQkJBTUNBUUF3RFFZSktvWklodmNOQVFFRkJRQURnZ0VCQUV1aC93dUhiclA1d1VPeAorU1BNb3dCMHV5UWxCK3BRQUhLU2txMGxQanowZTcwMXZ2YnlrOXZJbU1Na1F5aDJJKzNRWkg0VkZ2YkJzVWZrMgorZnR2MVRESTZRVTliUjgvb0N5MjJ4Qm1kZE1WSHhqdHFENndVMnp6MGM1eXBCZDhBM0hSNCt2ZzFZRmtDRXhoOAordlB0TnNDQnRRN3RnTUhwbk0xekZtZEg0TFRsU2MvdU1xcGNsWEhMWkNCNnJUanpqZ1RHZkE2Yjd3UDRwaUZYYQoraE5WUUE3YmloS09tTnFvUk9nSGhHRXZXUkdpelBmbFRkSVN6UnBGR2xnQzNnQ3kyNGVNUTR0dWk1eWlQQVpaaQorRmo0QTR4eWxOb0VZb2t4U2RzQVJvMjdtSGJyaldyNDJVOFUrZFkrR2FTbFlVN1djdTIrZlhNVVk3TjB2NFpqSgorL0w3ZkNnMD0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDQxOjNkOjcyOmM3OmY0OjZiOjFmOjgxOjQzOjdkOmYxOmQyOjI4OjU0OmRmOjlhCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9Q0gsIE89V0lTZUtleSwgT1U9Q29weXJpZ2h0IChjKSAyMDA1LCBPVT1PSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkLCBDTj1PSVNURSBXSVNlS2V5IEdsb2JhbCBSb290IEdBIENBCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBEZWMgMTEgMTY6MDM6NDQgMjAwNSBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IERlYyAxMSAxNjowOTo1MSAyMDM3IEdNVAorICAgICAgICBTdWJqZWN0OiBDPUNILCBPPVdJU2VLZXksIE9VPUNvcHlyaWdodCAoYykgMjAwNSwgT1U9T0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZCwgQ049T0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6Y2I6NGY6YjM6MDA6OWI6M2Q6MzY6ZGQ6Zjk6ZDE6NDk6NmE6NmI6MTA6CisgICAgICAgICAgICAgICAgICAgIDQ5OjFmOmVjOmQ4OjJiOmIyOmM2OmY4OjMyOjgxOjI5OjQzOjk1OjRjOjlhOgorICAgICAgICAgICAgICAgICAgICAxOToyMzoyMToxNTo0NTpkZTplMzpjODoxYzo1MTo1NTo1YjphZTo5MzplODoKKyAgICAgICAgICAgICAgICAgICAgMzc6ZmY6MmI6NmI6ZTk6ZDQ6ZWE6YmU6MmE6ZGQ6YTg6NTE6MmI6ZDc6NjY6CisgICAgICAgICAgICAgICAgICAgIGMzOjYxOjVjOjYwOjAyOmM4OmY1OmNlOjcyOjdiOjNiOmI4OmYyOjRlOjY1OgorICAgICAgICAgICAgICAgICAgICAwODo5YTpjZDphNDo2YToxOTpjMTowMTpiYjo3MzphNjpkNzpmNjpjMzpkZDoKKyAgICAgICAgICAgICAgICAgICAgY2Q6YmM6YTQ6OGI6YjU6OTk6NjE6Yjg6MDE6YTI6YTM6ZDQ6NGQ6ZDQ6MDU6CisgICAgICAgICAgICAgICAgICAgIDNkOjkxOmFkOmY4OmI0OjA4OjcxOjY0OmFmOjcwOmYxOjFjOjZiOjdlOmY2OgorICAgICAgICAgICAgICAgICAgICBjMzo3Nzo5ZDoyNDo3Mzo3YjplNDowYzo4YzplMTpkOTozNjplMTo5OTo4YjoKKyAgICAgICAgICAgICAgICAgICAgMDU6OTk6MGI6ZWQ6NDU6MzE6MDk6Y2E6YzI6MDA6ZGI6Zjc6NzI6YTA6OTY6CisgICAgICAgICAgICAgICAgICAgIGFhOjk1Ojg3OmQwOjhlOmM3OmI2OjYxOjczOjBkOjc2OjY2OjhjOmRjOjFiOgorICAgICAgICAgICAgICAgICAgICBiNDo2MzphMjo5Zjo3Zjo5MzoxMzozMDpmMTphMToyNzpkYjpkOTpmZjoyYzoKKyAgICAgICAgICAgICAgICAgICAgNTU6ODg6OTE6YTA6ZTA6NGY6MDc6YjA6Mjg6NTY6OGM6MTg6MWI6OTc6NDQ6CisgICAgICAgICAgICAgICAgICAgIDhlOjg5OmRkOmUwOjE3OjZlOmU3OjJhOmVmOjhmOjM5OjBhOjMxOjg0OjgyOgorICAgICAgICAgICAgICAgICAgICBkODo0MDoxNDo0OToyZTo3YTo0MTplNDphNzpmZTplMzo2NDpjYzpjMTo1OToKKyAgICAgICAgICAgICAgICAgICAgNzE6NGI6MmM6MjE6YTc6NWI6N2Q6ZTA6MWQ6ZDE6MmU6ODE6OWI6YzM6ZDg6CisgICAgICAgICAgICAgICAgICAgIDY4OmY3OmJkOjk2OjFiOmFjOjcwOmIxOjE2OjE0OjBiOmRiOjYwOmI5OjI2OgorICAgICAgICAgICAgICAgICAgICAwMTowNQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiAKKyAgICAgICAgICAgICAgICBEaWdpdGFsIFNpZ25hdHVyZSwgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgQjM6MDM6N0U6QUU6MzY6QkM6QjA6Nzk6RDE6REM6OTQ6MjY6QjY6MTE6QkU6MjE6QjI6Njk6ODY6OTQKKyAgICAgICAgICAgIDEuMy42LjEuNC4xLjMxMS4yMS4xOiAKKyAgICAgICAgICAgICAgICAuLi4KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgNGI6YTE6ZmY6MGI6ODc6NmU6YjM6Zjk6YzE6NDM6YjE6NDg6ZjM6Mjg6YzA6MWQ6MmU6Yzk6CisgICAgICAgIDA5OjQxOmZhOjk0OjAwOjFjOmE0OmE0OmFiOjQ5OjRmOjhmOjNkOjFlOmVmOjRkOjZmOmJkOgorICAgICAgICBiYzphNDpmNjpmMjoyNjozMDpjOToxMDpjYToxZDo4ODpmYjo3NDoxOToxZjo4NTo0NTpiZDoKKyAgICAgICAgYjA6NmM6NTE6Zjk6MzY6N2U6ZGI6ZjU6NGM6MzI6M2E6NDE6NGY6NWI6NDc6Y2Y6ZTg6MGI6CisgICAgICAgIDJkOmI2OmM0OjE5OjlkOjc0OmM1OjQ3OmM2OjNiOjZhOjBmOmFjOjE0OmRiOjNjOmY0OjczOgorICAgICAgICA5YzphOTowNTpkZjowMDpkYzo3NDo3ODpmYTpmODozNTo2MDo1OTowMjoxMzoxODo3YzpiYzoKKyAgICAgICAgZmI6NGQ6YjA6MjA6NmQ6NDM6YmI6NjA6MzA6N2E6Njc6MzM6NWM6YzU6OTk6ZDE6Zjg6MmQ6CisgICAgICAgIDM5OjUyOjczOmZiOjhjOmFhOjk3OjI1OjVjOjcyOmQ5OjA4OjFlOmFiOjRlOjNjOmUzOjgxOgorICAgICAgICAzMTo5ZjowMzphNjpmYjpjMDpmZToyOTo4ODo1NTpkYTo4NDpkNTo1MDowMzpiNjplMjo4NDoKKyAgICAgICAgYTM6YTY6MzY6YWE6MTE6M2E6MDE6ZTE6MTg6NGI6ZDY6NDQ6Njg6YjM6M2Q6Zjk6NTM6NzQ6CisgICAgICAgIDg0OmIzOjQ2OjkxOjQ2Ojk2OjAwOmI3OjgwOjJjOmI2OmUxOmUzOjEwOmUyOmRiOmEyOmU3OgorICAgICAgICAyODo4ZjowMTo5Njo2MjoxNjozZTowMDplMzoxYzphNTozNjo4MToxODphMjo0Yzo1Mjo3NjoKKyAgICAgICAgYzA6MTE6YTM6NmU6ZTY6MWQ6YmE6ZTM6NWE6YmU6MzY6NTM6YzU6M2U6NzU6OGY6ODY6Njk6CisgICAgICAgIDI5OjU4OjUzOmI1OjljOmJiOjZmOjlmOjVjOmM1OjE4OmVjOmRkOjJmOmUxOjk4OmM5OmZjOgorICAgICAgICBiZTpkZjowYTowZAorU0hBMSBGaW5nZXJwcmludD01OToyMjpBMTpFMTo1QTpFQToxNjozNToyMTpGODo5ODozOTo2QTo0Njo0NjpCMDo0NDoxQjowRjpBOQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzNhZDQ4YTkxLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvM2FkNDhhOTEuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNDQwOWEwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzNhZDQ4YTkxLjAKQEAgLTAsMCArMSw3OCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEZHpDQ0FsK2dBd0lCQWdJRUFnQUF1VEFOQmdrcWhraUc5dzBCQVFVRkFEQmFNUXN3Q1FZRFZRUUdFd0pKCitSVEVTTUJBR0ExVUVDaE1KUW1Gc2RHbHRiM0psTVJNd0VRWURWUVFMRXdwRGVXSmxjbFJ5ZFhOME1TSXdJQVlECitWUVFERXhsQ1lXeDBhVzF2Y21VZ1EzbGlaWEpVY25WemRDQlNiMjkwTUI0WERUQXdNRFV4TWpFNE5EWXdNRm9YCitEVEkxTURVeE1qSXpOVGt3TUZvd1dqRUxNQWtHQTFVRUJoTUNTVVV4RWpBUUJnTlZCQW9UQ1VKaGJIUnBiVzl5CitaVEVUTUJFR0ExVUVDeE1LUTNsaVpYSlVjblZ6ZERFaU1DQUdBMVVFQXhNWlFtRnNkR2x0YjNKbElFTjVZbVZ5CitWSEoxYzNRZ1VtOXZkRENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFLTUV1eUtyCittRDFYNkNaeW1yVjUxQ25pNGVpVmdMR3c0MXVPS3ltYVpOK2hYZTJ3Q1FWdDJ5Z3V6bUtpWXY2MGlOb1M2empyCitJWjNBUVNzQlVudUlkOU1jajhlNnVZaTFhZ25uYytnUlFLZlJ6TXBpalMzbGp3dW1VTktvVU1NbzZ2V3JKWWVLCittcFljcVdlNFB3elY5L2xTRXkvQ0c5VndjUENQd0JMS0JzdWE0ZG5LTTNwMzF2anN1ZkZvUkVKSUU5TEF3cVN1CitYbUQrdHFZRi9MVGRCMWtDMUZrWW1HUDFwV1Bna0F4OVhiSUdldk9GNnV2VUE2NWVoRDVmL3hYdGFiejVPVFp5CitkYzkzVWszenlaQXN1VDNseVNOVFB4OGttQ0ZjQjVrcHZjWTY3T2R1aGpwcmwzUmpNNzFvR0RId2VJMTJ2L3llCitqbDBxaHFkTmtOd25HamtDQXdFQUFhTkZNRU13SFFZRFZSME9CQllFRk9XZFdUQ0NSMWpNclBvSVZEYUdlenExCitCRTN3TUJJR0ExVWRFd0VCL3dRSU1BWUJBZjhDQVFNd0RnWURWUjBQQVFIL0JBUURBZ0VHTUEwR0NTcUdTSWIzCitEUUVCQlFVQUE0SUJBUUNGREYyTzVHOVJhRUlGb04yN1R5Y2xoQU85OTJUOUxkY3c0NlFRRit2YUtTbTJlVDkyCis5aGtUSTdnUUN2bFlwTlJoY0wwRVlXb1NpaGZWQ3IzRnZEQjgxdWtNSlkyR1FFL3N6S04rT01ZM0VVL3QzV2d4Citqa3pTc3dGMDdyNTFYZ2RJR245dy94WmNoTUI1aGJnRi9YKytaUkdqRDhBQ3RQaFNOemtFMWFreGVoaS9vQ3IwCitFcG4zbzBXQzR6eGU5WjJldGNpZWZDN0lwSjVPQ0JSTGJmMXdiV3NhWTcxazVoKzN6dkR5bnk2N0c3ZnlVSWh6Citrc0xpNHhhTm1qSUNxNDRZM2VrUUVlNStOYXVRcno0d2xIclFNejJuWlEvMS9JNmVZczlIUkN3Qlhic2R0VExTCitSOUk0THREK2dkd3lhaDYxN2p6Vi9PZUJIUm5ESkVMcVl6bXAKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMzM1NTQ2MTcgKDB4MjAwMDBiOSkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1JRSwgTz1CYWx0aW1vcmUsIE9VPUN5YmVyVHJ1c3QsIENOPUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3QKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IE1heSAxMiAxODo0NjowMCAyMDAwIEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogTWF5IDEyIDIzOjU5OjAwIDIwMjUgR01UCisgICAgICAgIFN1YmplY3Q6IEM9SUUsIE89QmFsdGltb3JlLCBPVT1DeWJlclRydXN0LCBDTj1CYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290CisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDphMzowNDpiYjoyMjphYjo5ODozZDo1NzplODoyNjo3Mjo5YTpiNTo3OToKKyAgICAgICAgICAgICAgICAgICAgZDQ6Mjk6ZTI6ZTE6ZTg6OTU6ODA6YjE6YjA6ZTM6NWI6OGU6MmI6Mjk6OWE6CisgICAgICAgICAgICAgICAgICAgIDY0OmRmOmExOjVkOmVkOmIwOjA5OjA1OjZkOmRiOjI4OjJlOmNlOjYyOmEyOgorICAgICAgICAgICAgICAgICAgICA2MjpmZTpiNDo4ODpkYToxMjplYjozODplYjoyMTo5ZDpjMDo0MToyYjowMToKKyAgICAgICAgICAgICAgICAgICAgNTI6N2I6ODg6Nzc6ZDM6MWM6OGY6Yzc6YmE6Yjk6ODg6YjU6NmE6MDk6ZTc6CisgICAgICAgICAgICAgICAgICAgIDczOmU4OjExOjQwOmE3OmQxOmNjOmNhOjYyOjhkOjJkOmU1OjhmOjBiOmE2OgorICAgICAgICAgICAgICAgICAgICA1MDpkMjphODo1MDpjMzoyODplYTpmNTphYjoyNTo4Nzo4YTo5YTo5NjoxYzoKKyAgICAgICAgICAgICAgICAgICAgYTk6Njc6Yjg6M2Y6MGM6ZDU6Zjc6Zjk6NTI6MTM6MmY6YzI6MWI6ZDU6NzA6CisgICAgICAgICAgICAgICAgICAgIDcwOmYwOjhmOmMwOjEyOmNhOjA2OmNiOjlhOmUxOmQ5OmNhOjMzOjdhOjc3OgorICAgICAgICAgICAgICAgICAgICBkNjpmODplYzpiOTpmMTo2ODo0NDo0Mjo0ODoxMzpkMjpjMDpjMjphNDphZToKKyAgICAgICAgICAgICAgICAgICAgNWU6NjA6ZmU6YjY6YTY6MDU6ZmM6YjQ6ZGQ6MDc6NTk6MDI6ZDQ6NTk6MTg6CisgICAgICAgICAgICAgICAgICAgIDk4OjYzOmY1OmE1OjYzOmUwOjkwOjBjOjdkOjVkOmIyOjA2OjdhOmYzOjg1OgorICAgICAgICAgICAgICAgICAgICBlYTplYjpkNDowMzphZTo1ZTo4NDozZTo1ZjpmZjoxNTplZDo2OTpiYzpmOToKKyAgICAgICAgICAgICAgICAgICAgMzk6MzY6NzI6NzU6Y2Y6Nzc6NTI6NGQ6ZjM6Yzk6OTA6MmM6Yjk6M2Q6ZTU6CisgICAgICAgICAgICAgICAgICAgIGM5OjIzOjUzOjNmOjFmOjI0Ojk4OjIxOjVjOjA3Ojk5OjI5OmJkOmM2OjNhOgorICAgICAgICAgICAgICAgICAgICBlYzplNzo2ZTo4NjozYTo2Yjo5Nzo3NDo2MzozMzpiZDo2ODoxODozMTpmMDoKKyAgICAgICAgICAgICAgICAgICAgNzg6OGQ6NzY6YmY6ZmM6OWU6OGU6NWQ6MmE6ODY6YTc6NGQ6OTA6ZGM6Mjc6CisgICAgICAgICAgICAgICAgICAgIDFhOjM5CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBFNTo5RDo1OTozMDo4Mjo0Nzo1ODpDQzpBQzpGQTowODo1NDozNjo4Njo3QjozQTpCNTowNDo0RDpGMAorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUsIHBhdGhsZW46MworICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA4NTowYzo1ZDo4ZTplNDo2Zjo1MTo2ODo0MjowNTphMDpkZDpiYjo0ZjoyNzoyNTo4NDowMzoKKyAgICAgICAgYmQ6Zjc6NjQ6ZmQ6MmQ6ZDc6MzA6ZTM6YTQ6MTA6MTc6ZWI6ZGE6Mjk6Mjk6YjY6Nzk6M2Y6CisgICAgICAgIDc2OmY2OjE5OjEzOjIzOmI4OjEwOjBhOmY5OjU4OmE0OmQ0OjYxOjcwOmJkOjA0OjYxOjZhOgorICAgICAgICAxMjo4YToxNzpkNTowYTpiZDpjNTpiYzozMDo3YzpkNjplOTowYzoyNTo4ZDo4Njo0MDo0ZjoKKyAgICAgICAgZWM6Y2M6YTM6N2U6Mzg6YzY6Mzc6MTE6NGY6ZWQ6ZGQ6Njg6MzE6OGU6NGM6ZDI6YjM6MDE6CisgICAgICAgIDc0OmVlOmJlOjc1OjVlOjA3OjQ4OjFhOjdmOjcwOmZmOjE2OjVjOjg0OmMwOjc5Ojg1OmI4OgorICAgICAgICAwNTpmZDo3ZjpiZTo2NToxMTphMzowZjpjMDowMjpiNDpmODo1MjozNzozOTowNDpkNTphOToKKyAgICAgICAgMzE6N2E6MTg6YmY6YTA6MmE6ZjQ6MTI6OTk6Zjc6YTM6NDU6ODI6ZTM6M2M6NWU6ZjU6OWQ6CisgICAgICAgIDllOmI1OmM4OjllOjdjOjJlOmM4OmE0OjllOjRlOjA4OjE0OjRiOjZkOmZkOjcwOjZkOjZiOgorICAgICAgICAxYTo2MzpiZDo2NDplNjoxZjpiNzpjZTpmMDpmMjo5ZjoyZTpiYjoxYjpiNzpmMjo1MDo4ODoKKyAgICAgICAgNzM6OTI6YzI6ZTI6ZTM6MTY6OGQ6OWE6MzI6MDI6YWI6OGU6MTg6ZGQ6ZTk6MTA6MTE6ZWU6CisgICAgICAgIDdlOjM1OmFiOjkwOmFmOjNlOjMwOjk0OjdhOmQwOjMzOjNkOmE3OjY1OjBmOmY1OmZjOjhlOgorICAgICAgICA5ZTo2MjpjZjo0Nzo0NDoyYzowMTo1ZDpiYjoxZDpiNTozMjpkMjo0NzpkMjozODoyZTpkMDoKKyAgICAgICAgZmU6ODE6ZGM6MzI6NmE6MWU6YjU6ZWU6M2M6ZDU6ZmM6ZTc6ODE6MWQ6MTk6YzM6MjQ6NDI6CisgICAgICAgIGVhOjYzOjM5OmE5CitTSEExIEZpbmdlcnByaW50PUQ0OkRFOjIwOkQwOjVFOjY2OkZDOjUzOkZFOjFBOjUwOjg4OjJDOjc4OkRCOjI4OjUyOkNBOkU0Ojc0CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvM2M1OGY5MDYuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8zYzU4ZjkwNi4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVjZDg5ZGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvM2M1OGY5MDYuMApAQCAtMCwwICsxLDg3IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUVOakNDQXg2Z0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRVUZBREJ2TVFzd0NRWURWUVFHRXdKVFJURVUKK01CSUdBMVVFQ2hNTFFXUmtWSEoxYzNRZ1FVSXhKakFrQmdOVkJBc1RIVUZrWkZSeWRYTjBJRVY0ZEdWeWJtRnMKK0lGUlVVQ0JPWlhSM2IzSnJNU0l3SUFZRFZRUURFeGxCWkdSVWNuVnpkQ0JGZUhSbGNtNWhiQ0JEUVNCU2IyOTAKK01CNFhEVEF3TURVek1ERXdORGd6T0ZvWERUSXdNRFV6TURFd05EZ3pPRm93YnpFTE1Ba0dBMVVFQmhNQ1UwVXgKK0ZEQVNCZ05WQkFvVEMwRmtaRlJ5ZFhOMElFRkNNU1l3SkFZRFZRUUxFeDFCWkdSVWNuVnpkQ0JGZUhSbGNtNWgKK2JDQlVWRkFnVG1WMGQyOXlhekVpTUNBR0ExVUVBeE1aUVdSa1ZISjFjM1FnUlhoMFpYSnVZV3dnUTBFZ1VtOXYKK2REQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUxmM0dqUG04Z0FFTFRuZ1RsdnQKK0g3eHNEODIxK2lPMnp0NmJFVE9YcENsTWZaT2Z2VXE4ayswREd1T1B6K1Z0VUZyV2x5bVVXb0N3U1hyYkxwWDkKK3VNcS9Oemd0SGo2UlFhMXdWc2Z3VHovb01wNTB5c2lRVk9uR1h3OTRuWnBBUEE2c1lhcGVGSStlaDZGcVVOelgKK21rNnZCYk9tY1pTY2NiTlFZQXJIRTUwNEI0WUNxT21vYVNZWWtLdE1zRThqcXpwUGhOamZ6cC9oYVcrNzEwTFgKK2EwVGt4NjN1YlVGZmNscHhDRGV6ZVdXa1dhQ1VOL2NBTHczQ2tuTGEwRGh5MnhTb1JjUmRLbjIzdE5iRTdxek4KK0UwUzN5U3ZkUXdBbCttRzVhV3BZSXhHM3B6T1BWblZaOWMwcDEwYTNDaXRsdHROQ2J4V3l1SHY3NytsZFU5VTAKK1dpY0NBd0VBQWFPQjNEQ0IyVEFkQmdOVkhRNEVGZ1FVcmIyWWVqUzBKdmY2eENaVTd3Tzk0Q1RMVkJvd0N3WUQKK1ZSMFBCQVFEQWdFR01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d2daa0dBMVVkSXdTQmtUQ0Jqb0FVcmIyWWVqUzAKK0p2ZjZ4Q1pVN3dPOTRDVExWQnFoYzZSeE1HOHhDekFKQmdOVkJBWVRBbE5GTVJRd0VnWURWUVFLRXd0QlpHUlUKK2NuVnpkQ0JCUWpFbU1DUUdBMVVFQ3hNZFFXUmtWSEoxYzNRZ1JYaDBaWEp1WVd3Z1ZGUlFJRTVsZEhkdmNtc3gKK0lqQWdCZ05WQkFNVEdVRmtaRlJ5ZFhOMElFVjRkR1Z5Ym1Gc0lFTkJJRkp2YjNTQ0FRRXdEUVlKS29aSWh2Y04KK0FRRUZCUUFEZ2dFQkFMQ2I0SVVsd3RZajRnK1dCcEtkUVppYzJZUjVnZGtlV3hRSEl6WmxqN0RZZDd1c1FXeEgKK1lJTlJzUGt5UGVmODlpWVR4NEFXcGI5YS9JZlBlSG1KSVpyaVRBY0toalc4OHQ1UnhOS1d0OXgrVHU1dy9SdzUKKzZ3d0NVUlF0anIwVzRNSGZSblhuSkszczlFSzBoWk53RUdlNm5RWTFTaGpUSzNyTVVVS2hlbVBSNXJ1aHhTdkMKK05yNFREZWE5WTM1NWU2Y0pEVUNyYXQyUGlzUDI5b3dhUWdWUjFFWDFuNmRpSVdnVklFTThtZWQ4dlNUWXFaRVgKK2M0Zy9WaHN4T0JpMGNRK2F6Y2dPbm80dUcrR01tSVBMSHpIeFJFekdCSE5KZG1BUHgvaTlGNEJyTHVuTVRBNWEKK21ua1BJQW91MVo1akpoNVZrcFRZZ2hkYWU5Qzh4NDlPaGdRPQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAxICgweDEpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9U0UsIE89QWRkVHJ1c3QgQUIsIE9VPUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrLCBDTj1BZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290CisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBNYXkgMzAgMTA6NDg6MzggMjAwMCBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IE1heSAzMCAxMDo0ODozOCAyMDIwIEdNVAorICAgICAgICBTdWJqZWN0OiBDPVNFLCBPPUFkZFRydXN0IEFCLCBPVT1BZGRUcnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yaywgQ049QWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9vdAorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6Yjc6Zjc6MWE6MzM6ZTY6ZjI6MDA6MDQ6MmQ6Mzk6ZTA6NGU6NWI6ZWQ6CisgICAgICAgICAgICAgICAgICAgIDFmOmJjOjZjOjBmOmNkOmI1OmZhOjIzOmI2OmNlOmRlOjliOjExOjMzOjk3OgorICAgICAgICAgICAgICAgICAgICBhNDoyOTo0Yzo3ZDo5Mzo5ZjpiZDo0YTpiYzo5MzplZDowMzoxYTplMzo4ZjoKKyAgICAgICAgICAgICAgICAgICAgY2Y6ZTU6NmQ6NTA6NWE6ZDY6OTc6Mjk6OTQ6NWE6ODA6YjA6NDk6N2E6ZGI6CisgICAgICAgICAgICAgICAgICAgIDJlOjk1OmZkOmI4OmNhOmJmOjM3OjM4OjJkOjFlOjNlOjkxOjQxOmFkOjcwOgorICAgICAgICAgICAgICAgICAgICA1NjpjNzpmMDo0ZjozZjplODozMjo5ZTo3NDpjYTpjODo5MDo1NDplOTpjNjoKKyAgICAgICAgICAgICAgICAgICAgNWY6MGY6Nzg6OWQ6OWE6NDA6M2M6MGU6YWM6NjE6YWE6NWU6MTQ6OGY6OWU6CisgICAgICAgICAgICAgICAgICAgIDg3OmExOjZhOjUwOmRjOmQ3OjlhOjRlOmFmOjA1OmIzOmE2OjcxOjk0OjljOgorICAgICAgICAgICAgICAgICAgICA3MTpiMzo1MDo2MDowYTpjNzoxMzo5ZDozODowNzo4NjowMjphODplOTphODoKKyAgICAgICAgICAgICAgICAgICAgNjk6MjY6MTg6OTA6YWI6NGM6YjA6NGY6MjM6YWI6M2E6NGY6ODQ6ZDg6ZGY6CisgICAgICAgICAgICAgICAgICAgIGNlOjlmOmUxOjY5OjZmOmJiOmQ3OjQyOmQ3OjZiOjQ0OmU0OmM3OmFkOmVlOgorICAgICAgICAgICAgICAgICAgICA2ZDo0MTo1Zjo3Mjo1YTo3MTowODozNzpiMzo3OTo2NTphNDo1OTphMDo5NDoKKyAgICAgICAgICAgICAgICAgICAgMzc6Zjc6MDA6MmY6MGQ6YzI6OTI6NzI6ZGE6ZDA6Mzg6NzI6ZGI6MTQ6YTg6CisgICAgICAgICAgICAgICAgICAgIDQ1OmM0OjVkOjJhOjdkOmI3OmI0OmQ2OmM0OmVlOmFjOmNkOjEzOjQ0OmI3OgorICAgICAgICAgICAgICAgICAgICBjOToyYjpkZDo0MzowMDoyNTpmYTo2MTpiOTo2OTo2YTo1ODoyMzoxMTpiNzoKKyAgICAgICAgICAgICAgICAgICAgYTc6MzM6OGY6NTY6NzU6NTk6ZjU6Y2Q6Mjk6ZDc6NDY6Yjc6MGE6MmI6NjU6CisgICAgICAgICAgICAgICAgICAgIGI2OmQzOjQyOjZmOjE1OmIyOmI4OjdiOmZiOmVmOmU5OjVkOjUzOmQ1OjM0OgorICAgICAgICAgICAgICAgICAgICA1YToyNworICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgQUQ6QkQ6OTg6N0E6MzQ6QjQ6MjY6Rjc6RkE6QzQ6MjY6NTQ6RUY6MDM6QkQ6RTA6MjQ6Q0I6NTQ6MUEKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6QUQ6QkQ6OTg6N0E6MzQ6QjQ6MjY6Rjc6RkE6QzQ6MjY6NTQ6RUY6MDM6QkQ6RTA6MjQ6Q0I6NTQ6MUEKKyAgICAgICAgICAgICAgICBEaXJOYW1lOi9DPVNFL089QWRkVHJ1c3QgQUIvT1U9QWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsvQ049QWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9vdAorICAgICAgICAgICAgICAgIHNlcmlhbDowMQorCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIGIwOjliOmUwOjg1OjI1OmMyOmQ2OjIzOmUyOjBmOjk2OjA2OjkyOjlkOjQxOjk4OjljOmQ5OgorICAgICAgICA4NDo3OTo4MTpkOToxZTo1YjoxNDowNzoyMzozNjo2NTo4ZjpiMDpkODo3NzpiYjphYzo0MToKKyAgICAgICAgNmM6NDc6NjA6ODM6NTE6YjA6Zjk6MzI6M2Q6ZTc6ZmM6ZjY6MjY6MTM6Yzc6ODA6MTY6YTU6CisgICAgICAgIGJmOjVhOmZjOjg3OmNmOjc4Ojc5Ojg5OjIxOjlhOmUyOjRjOjA3OjBhOjg2OjM1OmJjOmYyOgorICAgICAgICBkZTo1MTpjNDpkMjo5NjpiNzpkYzo3ZTo0ZTplZTo3MDpmZDoxYzozOTplYjowYzowMjo1MToKKyAgICAgICAgMTQ6MmQ6OGU6YmQ6MTY6ZTA6YzE6ZGY6NDY6NzU6ZTc6MjQ6YWQ6ZWM6ZjQ6NDI6YjQ6ODU6CisgICAgICAgIDkzOjcwOjEwOjY3OmJhOjlkOjA2OjM1OjRhOjE4OmQzOjJiOjdhOmNjOjUxOjQyOmExOjdhOgorICAgICAgICA2MzpkMTplNjpiYjphMTpjNToyYjpjMjozNjpiZToxMzowZDplNjpiZDo2Mzo3ZTo3OTo3YjoKKyAgICAgICAgYTc6MDk6MGQ6NDA6YWI6NmE6ZGQ6OGY6OGE6YzM6ZjY6ZjY6OGM6MWE6NDI6MDU6NTE6ZDQ6CisgICAgICAgIDQ1OmY1OjlmOmE3OjYyOjIxOjY4OjE1OjIwOjQzOjNjOjk5OmU3OjdjOmJkOjI0OmQ4OmE5OgorICAgICAgICA5MToxNzo3Mzo4ODozZjo1NjoxYjozMTozODoxODpiNDo3MTowZjo5YTpjZDpjODowZTo5ZToKKyAgICAgICAgOGU6MmU6MWI6ZTE6OGM6OTg6ODM6Y2I6MWY6MzE6ZjE6NDQ6NGM6YzY6MDQ6NzM6NDk6NzY6CisgICAgICAgIDYwOjBmOmM3OmY4OmJkOjE3OjgwOjZiOjJlOmU5OmNjOjRjOjBlOjVhOjlhOjc5OjBmOjIwOgorICAgICAgICAwYToyZTpkNTo5ZTo2MzoyNjoxZTo1NTo5Mjo5NDpkODo4MjoxNzo1YTo3YjpkMDpiYzpjNzoKKyAgICAgICAgOGY6NGU6ODY6MDQKK1NIQTEgRmluZ2VycHJpbnQ9MDI6RkE6RjM6RTI6OTE6NDM6NTQ6Njg6NjA6Nzg6NTc6Njk6NEQ6RjU6RTQ6NUI6Njg6ODU6MTg6NjgKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8zYzg2MGQ1MS4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzNjODYwZDUxLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTA3MzcyNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8zYzg2MGQ1MS4wCkBAIC0wLDAgKzEsMTI5IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUZ1akNDQTZLZ0F3SUJBZ0lKQUx0QUhFUDFYayt3TUEwR0NTcUdTSWIzRFFFQkJRVUFNRVV4Q3pBSkJnTlYKK0JBWVRBa05JTVJVd0V3WURWUVFLRXd4VGQybHpjMU5wWjI0Z1FVY3hIekFkQmdOVkJBTVRGbE4zYVhOelUybG4KK2JpQkhiMnhrSUVOQklDMGdSekl3SGhjTk1EWXhNREkxTURnek1ETTFXaGNOTXpZeE1ESTFNRGd6TURNMVdqQkYKK01Rc3dDUVlEVlFRR0V3SkRTREVWTUJNR0ExVUVDaE1NVTNkcGMzTlRhV2R1SUVGSE1SOHdIUVlEVlFRREV4WlQKK2QybHpjMU5wWjI0Z1IyOXNaQ0JEUVNBdElFY3lNSUlDSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQWc4QU1JSUMKK0NnS0NBZ0VBcitUdWZvc2tEaEp1cVZBdEZrUTdrcEpjeXJoZGhKSkNFeXE4WlZlQ1FENVhKTTFRaXlVcXQyLzgKKzc2TFF3QjhDSkVvVGxvOGpFK1lvV0FDalI4Y0dwNFFqSzd1OWxpdC9WY3lMd1ZjZkRtSmxEOTA5Vm9wejJxNSsKK2JicUJISDVDakNBMTJVTk5oUHFFMjFJczh3NG5kd3RydnhFdmNuaWZMdGcrNWhnM1dpcHkrZHBpa0pLVnloK2MKKzZiTThLOHZ6QVJPL1dzL0J0UXBndmQyMW1XUlR1S0NXczIvaUpuZVJqT0JpRUFLZk5BK2sxWkl6VWQ2K2picUUKK2VtQThhdHVmSyt6ZTNnRS9iazNsVUliTHRLL3RSRURGeWxxTTJ0SXJmS2p1dnFibENxb09wZDhGVXJkVnh5SmQKK01tcVhsMk1UMjhuYmVUWjdoVHBLeFZLSitTVG5uWGVwZ3Y5VkhLVnhhU3ZSQWlUeXN5YlVhOW9FVmVYQkNzZHQKK01EZVFLdVNlRkROZUZoZFZ4VnUxeXpTSmt2R2RKbytoQjlUR3NuaFEyd3dNQzN3TGpFSFh1ZW5kaklqM28wMnkKK01zellGOXJOdDg1bW5kVDlYdis5bHo0cGRlZCtwMkpZcnlVMHBVSEhQYndOVU1vREF3OElXaCtWYzNoaXY2OXkKK0ZHa09wZVVERG5pT0ppaEM4QWNMWWlBUVp6bEcrcWtEekFRNGVtYnZJSU8xakVwV2pwRUEvSTVjZ3Q2SW9NUGkKK2FHNTlqZTg4M1dYMFhheFI3eVNBcnFwV2wyLzVyWDNhWVQrWWR6eWxrYlljakNiYVphSUpiY0hpVk9PNXlreE0KK2dJOTNlMkNhSHQrMjhrZ2VEcnBPVkcyWTRPR2lHcUozVU0vRVk1THNSeG1kNitacnpzRUNBd0VBQWFPQnJEQ0IKK3FUQU9CZ05WSFE4QkFmOEVCQU1DQVFZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVVd5VjcKK2xxUmxVWDY0T2ZQQWVHWmU2RHJuOE80d0h3WURWUjBqQkJnd0ZvQVVXeVY3bHFSbFVYNjRPZlBBZUdaZTZEcm4KKzhPNHdSZ1lEVlIwZ0JEOHdQVEE3QmdsZ2hYUUJXUUVDQVFFd0xqQXNCZ2dyQmdFRkJRY0NBUllnYUhSMGNEb3YKK0wzSmxjRzl6YVhSdmNua3VjM2RwYzNOemFXZHVMbU52YlM4d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dJQkFDZTYKKzQ1Ujg4YTdBM2hmbTVkalY5VlN3Zy9TN3pWNEZlMCtmZFdhdlBPaFdmdnh5ZURnRDJTdGlHd0M1K09sZ3pjek8KK1VZckhVREZ1NFVwK0dDOXBXYlk5WklFcjQ0T0U1aUtIam4zZzdnS1pZYmdlOUxncmlCSVdoTUl4a3ppV01hYTUKK08xTS93eVNUVmx0cGt1ekZ3YnM0QU9Qc0Y2bTQzTWQ4QVlPZk1rZTZVaUkwSFRKNkNWYW5mQ1UycVQxTDJzQ0MKK2J3cTdFc2lIU3ljUitSNHR4NU0vbnR0ZkptdFMyUzZLOFJUR1JJMFZxYmUvdmQ2bUd1NnVMZnRJZHhmK3UreXYKK0dQVXFVZkE1aEplVmJHNGJ3eXZFZEdCNUpiQUtKOS9mWHRJNXowVjlRa3Zmc3l3ZXhjWmR5bFU2b0p4cG1vL2EKKzc3S3dQSitIYkJJclpYQVZVakVhSk05dk1TTlFINHhQanlQRGRFRmpIRldvRk4wKzRGRlF6L0ViTUZZT2tyQ0MKK2hkaUR5eUprdkMyNEpkVlVvcmdHNnEyU3BDU2d3WWExU2hOcVI4OHVDMWFWVk12T210dHF0S2F5MjBFSWhpZDMKKzkycWdRbXdMT003WGRWQXlrc0xmS3pBaVNORFZRVGdsWGFUcFhaL0dsSFhRUmYwd2wwT1BrS3NLeDRaellFcHAKK0xkNmxlTmNHMm1xZVN6NTNPaUFUSWdIUXYyaWVZMkJyTlUwTGJicWhQY0NUNEg4anMxV3RjaVZPUnZuU0Z1K3cKK1pNRUJudW5Lb0dxWURzL1lZUEl2U2Jqa1F1RTROUmIweUc1UDk0Rlc2THFqdmlPdnJ2MXZBK0FDT3pCMitodHQKK1FjOEJzZW00eVdiMDJ5YnpPcVIwOGtra1c4bXcwRmZCK2o1NjRaZkoKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIGJiOjQwOjFjOjQzOmY1OjVlOjRmOmIwCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9Q0gsIE89U3dpc3NTaWduIEFHLCBDTj1Td2lzc1NpZ24gR29sZCBDQSAtIEcyCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBPY3QgMjUgMDg6MzA6MzUgMjAwNiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IE9jdCAyNSAwODozMDozNSAyMDM2IEdNVAorICAgICAgICBTdWJqZWN0OiBDPUNILCBPPVN3aXNzU2lnbiBBRywgQ049U3dpc3NTaWduIEdvbGQgQ0EgLSBHMgorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDQwOTYgYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDQwOTYgYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YWY6ZTQ6ZWU6N2U6OGI6MjQ6MGU6MTI6NmU6YTk6NTA6MmQ6MTY6NDQ6CisgICAgICAgICAgICAgICAgICAgIDNiOjkyOjkyOjVjOmNhOmI4OjVkOjg0OjkyOjQyOjEzOjJhOmJjOjY1OjU3OgorICAgICAgICAgICAgICAgICAgICA4Mjo0MDozZTo1NzoyNDpjZDo1MDo4YjoyNToyYTpiNzo2ZjpmYzplZjphMjoKKyAgICAgICAgICAgICAgICAgICAgZDA6YzA6MWY6MDI6MjQ6NGE6MTM6OTY6OGY6MjM6MTM6ZTY6Mjg6NTg6MDA6CisgICAgICAgICAgICAgICAgICAgIGEzOjQ3OmM3OjA2OmE3Ojg0OjIzOjJiOmJiOmJkOjk2OjJiOjdmOjU1OmNjOgorICAgICAgICAgICAgICAgICAgICA4YjpjMTo1NzoxZjowZTo2Mjo2NTowZjpkZDozZDo1Njo4YTo3MzpkYTphZToKKyAgICAgICAgICAgICAgICAgICAgN2U6NmQ6YmE6ODE6MWM6N2U6NDI6OGM6MjA6MzU6ZDk6NDM6NGQ6ODQ6ZmE6CisgICAgICAgICAgICAgICAgICAgIDg0OmRiOjUyOjJjOmYzOjBlOjI3Ojc3OjBiOjZiOmJmOjExOjJmOjcyOjc4OgorICAgICAgICAgICAgICAgICAgICA5ZjoyZTpkODozZTplNjoxODozNzo1YToyYTo3MjpmOTpkYTo2Mjo5MDo5MjoKKyAgICAgICAgICAgICAgICAgICAgOTU6Y2E6MWY6OWM6ZTk6YjM6M2M6MmI6Y2I6ZjM6MDE6MTM6YmY6NWE6Y2Y6CisgICAgICAgICAgICAgICAgICAgIGMxOmI1OjBhOjYwOmJkOmRkOmI1Ojk5OjY0OjUzOmI4OmEwOjk2OmIzOjZmOgorICAgICAgICAgICAgICAgICAgICBlMjoyNjo3Nzo5MTo4YzplMDo2MjoxMDowMjo5ZjozNDowZjphNDpkNTo5MjoKKyAgICAgICAgICAgICAgICAgICAgMzM6NTE6ZGU6YmU6OGQ6YmE6ODQ6N2E6NjA6M2M6NmE6ZGI6OWY6MmI6ZWM6CisgICAgICAgICAgICAgICAgICAgIGRlOmRlOjAxOjNmOjZlOjRkOmU1OjUwOjg2OmNiOmI0OmFmOmVkOjQ0OjQwOgorICAgICAgICAgICAgICAgICAgICBjNTpjYTo1YTo4YzpkYTpkMjoyYjo3YzphODplZTpiZTphNjplNTowYTphYToKKyAgICAgICAgICAgICAgICAgICAgMGU6YTU6ZGY6MDU6NTI6Yjc6NTU6Yzc6MjI6NWQ6MzI6NmE6OTc6OTc6NjM6CisgICAgICAgICAgICAgICAgICAgIDEzOmRiOmM5OmRiOjc5OjM2OjdiOjg1OjNhOjRhOmM1OjUyOjg5OmY5OjI0OgorICAgICAgICAgICAgICAgICAgICBlNzo5ZDo3NzphOTo4MjpmZjo1NToxYzphNTo3MTo2OToyYjpkMTowMjoyNDoKKyAgICAgICAgICAgICAgICAgICAgZjI6YjM6MjY6ZDQ6NmI6ZGE6MDQ6NTU6ZTU6YzE6MGE6Yzc6NmQ6MzA6Mzc6CisgICAgICAgICAgICAgICAgICAgIDkwOjJhOmU0OjllOjE0OjMzOjVlOjE2OjE3OjU1OmM1OjViOmI1OmNiOjM0OgorICAgICAgICAgICAgICAgICAgICA4OTo5MjpmMTo5ZDoyNjo4ZjphMTowNzpkNDpjNjpiMjo3ODo1MDpkYjowYzoKKyAgICAgICAgICAgICAgICAgICAgMGM6MGI6N2M6MGI6OGM6NDE6ZDc6Yjk6ZTk6ZGQ6OGM6ODg6Zjc6YTM6NGQ6CisgICAgICAgICAgICAgICAgICAgIGIyOjMyOmNjOmQ4OjE3OmRhOmNkOmI3OmNlOjY2OjlkOmQ0OmZkOjVlOmZmOgorICAgICAgICAgICAgICAgICAgICBiZDo5NzozZToyOTo3NTplNzo3ZTphNzo2Mjo1ODphZjoyNTozNDphNTo0MToKKyAgICAgICAgICAgICAgICAgICAgYzc6M2Q6YmM6MGQ6NTA6Y2E6MDM6MDM6MGY6MDg6NWE6MWY6OTU6NzM6Nzg6CisgICAgICAgICAgICAgICAgICAgIDYyOmJmOmFmOjcyOjE0OjY5OjBlOmE1OmU1OjAzOjBlOjc4OjhlOjI2OjI4OgorICAgICAgICAgICAgICAgICAgICA0MjpmMDowNzowYjo2MjoyMDoxMDo2NzozOTo0NjpmYTphOTowMzpjYzowNDoKKyAgICAgICAgICAgICAgICAgICAgMzg6N2E6NjY6ZWY6MjA6ODM6YjU6OGM6NGE6NTY6OGU6OTE6MDA6ZmM6OGU6CisgICAgICAgICAgICAgICAgICAgIDVjOjgyOmRlOjg4OmEwOmMzOmUyOjY4OjZlOjdkOjhkOmVmOjNjOmRkOjY1OgorICAgICAgICAgICAgICAgICAgICBmNDo1ZDphYzo1MTplZjoyNDo4MDphZTphYTo1Njo5Nzo2ZjpmOTphZDo3ZDoKKyAgICAgICAgICAgICAgICAgICAgZGE6NjE6M2Y6OTg6Nzc6M2M6YTU6OTE6YjY6MWM6OGM6MjY6ZGE6NjU6YTI6CisgICAgICAgICAgICAgICAgICAgIDA5OjZkOmMxOmUyOjU0OmUzOmI5OmNhOjRjOjRjOjgwOjhmOjc3OjdiOjYwOgorICAgICAgICAgICAgICAgICAgICA5YToxZTpkZjpiNjpmMjo0ODoxZTowZTpiYTo0ZTo1NDo2ZDo5ODplMDplMToKKyAgICAgICAgICAgICAgICAgICAgYTI6MWE6YTI6Nzc6NTA6Y2Y6YzQ6NjM6OTI6ZWM6NDc6MTk6OWQ6ZWI6ZTY6CisgICAgICAgICAgICAgICAgICAgIDZiOmNlOmMxCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgNUI6MjU6N0I6OTY6QTQ6NjU6NTE6N0U6Qjg6Mzk6RjM6QzA6Nzg6NjY6NUU6RTg6M0E6RTc6RjA6RUUKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOjVCOjI1OjdCOjk2OkE0OjY1OjUxOjdFOkI4OjM5OkYzOkMwOjc4OjY2OjVFOkU4OjNBOkU3OkYwOkVFCisKKyAgICAgICAgICAgIFg1MDl2MyBDZXJ0aWZpY2F0ZSBQb2xpY2llczogCisgICAgICAgICAgICAgICAgUG9saWN5OiAyLjE2Ljc1Ni4xLjg5LjEuMi4xLjEKKyAgICAgICAgICAgICAgICAgIENQUzogaHR0cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8KKworICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAyNzpiYTplMzo5NDo3YzpmMTphZTpjMDpkZToxNzplNjplNTpkODpkNTpmNTo1NDpiMDo4MzoKKyAgICAgICAgZjQ6YmI6Y2Q6NWU6MDU6N2I6NGY6OWY6NzU6NjY6YWY6M2M6ZTg6NTY6N2U6ZmM6NzI6Nzg6CisgICAgICAgIDM4OjAzOmQ5OjJiOjYyOjFiOjAwOmI5OmY4OmU5OjYwOmNkOmNjOmNlOjUxOjhhOmM3OjUwOgorICAgICAgICAzMTo2ZTplMTo0YTo3ZToxODoyZjo2OTo1OTpiNjozZDo2NDo4MToyYjplMzo4Mzo4NDplNjoKKyAgICAgICAgMjI6ODc6OGU6N2Q6ZTA6ZWU6MDI6OTk6NjE6Yjg6MWU6ZjQ6Yjg6MmI6ODg6MTI6MTY6ODQ6CisgICAgICAgIGMyOjMxOjkzOjM4Ojk2OjMxOmE2OmI5OjNiOjUzOjNmOmMzOjI0OjkzOjU2OjViOjY5OjkyOgorICAgICAgICBlYzpjNTpjMTpiYjozODowMDplMzplYzoxNzphOTpiODpkYzpjNzo3YzowMTo4Mzo5ZjozMjoKKyAgICAgICAgNDc6YmE6NTI6MjI6MzQ6MWQ6MzI6N2E6MDk6NTY6YTc6N2M6MjU6MzY6YTk6M2Q6NGI6ZGE6CisgICAgICAgIGMwOjgyOjZmOjBhOmJiOjEyOmM4Ojg3OjRiOjI3OjExOmY5OjFlOjJkOmM3OjkzOjNmOjllOgorICAgICAgICBkYjo1ZjoyNjo2Yjo1MjpkOToyZTo4YTpmMToxNDpjNjo0NDo4ZDoxNTphOTpiNzpiZjpiZDoKKyAgICAgICAgZGU6YTY6MWE6ZWU6YWU6MmQ6ZmI6NDg6Nzc6MTc6ZmU6YmI6ZWM6YWY6MTg6ZjU6MmE6NTE6CisgICAgICAgIGYwOjM5Ojg0Ojk3Ojk1OjZjOjZlOjFiOmMzOjJiOmM0Ojc0OjYwOjc5OjI1OmIwOjBhOjI3OgorICAgICAgICBkZjpkZjo1ZTpkMjozOTpjZjo0NTo3ZDo0Mjo0YjpkZjpiMzoyYzoxZTpjNTpjNjo1ZDpjYToKKyAgICAgICAgNTU6M2E6YTA6OWM6Njk6OWE6OGY6ZGE6ZWY6YjI6YjA6M2M6OWY6ODc6NmM6MTI6MmI6NjU6CisgICAgICAgIDcwOjE1OjUyOjMxOjFhOjI0OmNmOjZmOjMxOjIzOjUwOjFmOjhjOjRmOjhmOjIzOmMzOjc0OgorICAgICAgICA0MTo2MzoxYzo1NTphODoxNDpkZDozZTplMDo1MTo1MDpjZjpmMToxYjozMDo1NjowZTo5MjoKKyAgICAgICAgYjA6ODI6ODU6ZDg6ODM6Y2I6MjI6NjQ6YmM6MmQ6Yjg6MjU6ZDU6NTQ6YTI6Yjg6MDY6ZWE6CisgICAgICAgIGFkOjkyOmE0OjI0OmEwOmMxOjg2OmI1OjRhOjEzOjZhOjQ3OmNmOjJlOjBiOjU2Ojk1OjU0OgorICAgICAgICBjYjpjZTo5YTpkYjo2YTpiNDphNjpiMjpkYjo0MTowODo4NjoyNzo3NzpmNzo2YTphMDo0MjoKKyAgICAgICAgNmM6MGI6Mzg6Y2U6ZDc6NzU6NTA6MzI6OTI6YzI6ZGY6MmI6MzA6MjI6NDg6ZDA6ZDU6NDE6CisgICAgICAgIDM4OjI1OjVkOmE0OmU5OjVkOjlmOmM2Ojk0Ojc1OmQwOjQ1OmZkOjMwOjk3OjQzOjhmOjkwOgorICAgICAgICBhYjowYTpjNzo4Njo3Mzo2MDo0YTo2OToyZDpkZTphNTo3ODpkNzowNjpkYTo2YTo5ZTo0YjoKKyAgICAgICAgM2U6Nzc6M2E6MjA6MTM6MjI6MDE6ZDA6YmY6Njg6OWU6NjM6NjA6NmI6MzU6NGQ6MGI6NmQ6CisgICAgICAgIGJhOmExOjNkOmMwOjkzOmUwOjdmOjIzOmIzOjU1OmFkOjcyOjI1OjRlOjQ2OmY5OmQyOjE2OgorICAgICAgICBlZjpiMDo2NDpjMTowMTo5ZTplOTpjYTphMDo2YTo5ODowZTpjZjpkODo2MDpmMjoyZjo0OToKKyAgICAgICAgYjg6ZTQ6NDI6ZTE6Mzg6MzU6MTY6ZjQ6Yzg6NmU6NGY6Zjc6ODE6NTY6ZTg6YmE6YTM6YmU6CisgICAgICAgIDIzOmFmOmFlOmZkOjZmOjAzOmUwOjAyOjNiOjMwOjc2OmZhOjFiOjZkOjQxOmNmOjAxOmIxOgorICAgICAgICBlOTpiODpjOTo2NjpmNDpkYjoyNjpmMzozYTphNDo3NDpmMjo0OToyNDo1YjpjOTpiMDpkMDoKKyAgICAgICAgNTc6YzE6ZmE6M2U6N2E6ZTE6OTc6YzkKK1NIQTEgRmluZ2VycHJpbnQ9RDg6QzU6Mzg6OEE6Qjc6MzA6MUI6MUI6NkU6RDQ6N0E6RTY6NDU6MjU6M0E6NkY6OUY6MUE6Mjc6NjEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8zZDQ0MWRlOC4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzNkNDQxZGU4LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGU0ZTc2NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8zZDQ0MWRlOC4wCkBAIC0wLDAgKzEsMTI1IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUZ5akNDQTdLZ0F3SUJBZ0lFQUppV2pEQU5CZ2txaGtpRzl3MEJBUXNGQURCYU1Rc3dDUVlEVlFRR0V3Sk8KK1RERWVNQndHQTFVRUNnd1ZVM1JoWVhRZ1pHVnlJRTVsWkdWeWJHRnVaR1Z1TVNzd0tRWURWUVFERENKVGRHRmgKK2RDQmtaWElnVG1Wa1pYSnNZVzVrWlc0Z1VtOXZkQ0JEUVNBdElFY3lNQjRYRFRBNE1ETXlOakV4TVRneE4xb1gKK0RUSXdNRE15TlRFeE1ETXhNRm93V2pFTE1Ba0dBMVVFQmhNQ1Rrd3hIakFjQmdOVkJBb01GVk4wWVdGMElHUmwKK2NpQk9aV1JsY214aGJtUmxiakVyTUNrR0ExVUVBd3dpVTNSaFlYUWdaR1Z5SUU1bFpHVnliR0Z1WkdWdUlGSnYKK2IzUWdRMEVnTFNCSE1qQ0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCQU1WWjUyOTEKK3FqNUxuTFc0cko0TDVQblp5cXRkajdVNUVJTFhyMUhnTytFQVNHclAydUVHUXhHWnFoUWxFcTBpNkFCdFE4U3AKK3VPVWZpVXRudldGSTcvM1M0R0NJNWJrWVlDakRkeXV0c0RlcU45NWtXU3BHVitSTHVmZzNmTlUyNTREQnR2UFUKK1o1dVc2TTdYeGdwVDBHdEpsdk9qQ3dWM1NQY2w1WENzTUJRZ0plTi9kVnJsU1BoT2V3TUhCUHFDWVlkdThEdkUKK3BNZlE5WFErcFYwYUNQS2JKZEwyckFRbVBsVTZZaWlsZTdJd3IvZzN3dEc2MWpqOTlPOUpNRGVaSmlGSWhRR3AKKzVSYm4zSkJWM3cvb09NMlpOeUZQWGZVaWIyckZFaFpnRjFYeVpXYW1wekNST01FNEhZWUVoTG9hSlhoZW5hL00KK1VHRFdFNGRTN1dNZmJXVjl3aFVZZE1yaGZtUXBqSExZRmhOOUMwbEs4U2diSUhScnhUM2RzS3BJQ1QwdWdwVE4KK0dtWFpLNGlhbWJ3WWZwL3VmV1o4UHIyVXVJSE96Wmd3ZU1Gdlo5QytYK0JvN2Q3aXNja3NXWGlTcXQ4cllHUHkKKzVWNjU0OHI2ZjFDR1BxSTBHQXdKYUNnUkhPVGh1VncrUjdveVB4ak1XNFQxODJ0MHhISjA0ZU9Mb0VxOWpXWXYKKzZxMDEyaURUaUlKaDhCSWl0cnpRMWFUc3IxU0lKU1E4cDIyeGNpay9QbGVtZjFXdmJpYkcvdWZNUUZ4UlJJRUsKK2VONUt6bFcvSGRYWnQxYnY4SGIvQzNtMXI3MzdxV21SUnBkb2dCUTJIYk4vdXltWU5xVWcrb0pnWWpPazdOYTYKK0I2ZHV4YzhVcHVmV2tqVFlnZlg4SFYycVhCNzJvMDA3dVBjNUFnTUJBQUdqZ1pjd2daUXdEd1lEVlIwVEFRSC8KK0JBVXdBd0VCL3pCU0JnTlZIU0FFU3pCSk1FY0dCRlVkSUFBd1B6QTlCZ2dyQmdFRkJRY0NBUll4YUhSMGNEb3YKK0wzZDNkeTV3YTJsdmRtVnlhR1ZwWkM1dWJDOXdiMnhwWTJsbGN5OXliMjkwTFhCdmJHbGplUzFITWpBT0JnTlYKK0hROEJBZjhFQkFNQ0FRWXdIUVlEVlIwT0JCWUVGSkZvTW9jVkhZbml0ZkdzTmlnMGpRdDhZb2pyTUEwR0NTcUcKK1NJYjNEUUVCQ3dVQUE0SUNBUUNvUVVwbktwS0JnbEJ1NGRmWXN6azc4d0lWQ1ZCUjd5MjlKSHVJaGp2NXRMeVMKK0NaYTU5c0NySTJBR2VZd1JUbEhTZVlBeis1MUl2dXhCUTRFZmZrZEFIT1Y2Q01xcWkzV3RGTVRDNkdZOGdnZW4KKzVpZUNXeGptRDI3WlVENktRaGdweHJSVy9GWVFvQVVYdlF3amYvU1Q3WndhVWI3ZFJVRy9rU1MwSDR6cFg4OTcKK0labWZsWjg1T2tZY2JQbk5lNXlRelNpcHg2bFZ1NnhpTkdJMUUwc1VPbFdEdVlhTmtxYkc5QWNsVk13V1Z4SksKK2duaklGTmtYZ2lZdFhTQWZlYTcrMUhBV0ZwV0QyRFU1LzFKZGRSd1d4Uk5WejBmTWRXVlNTdDd3c0tma0NwWUwKKys2M0M0aVdFc3Qza3ZYNVpiSnZ3OE5qbnl2THBsemgraWI3TSt6a1hZVDl5MnpxUjJHVUJHUjJ0VUtSWENueEwKK3ZKeHhjeXBGVVJtRnpJNzlSNmQwbFIybzBhOU9GN0ZwSnNLcWVGZGJ4VTJuNVo0RkY1VEtzbCtnU1JpTk5Pa20KK2JFZ2VxbWlTQmVHQ2MxcWIzQWRiQ0cxOW5kZU5JZG44RkNDcXdrWGZQK2NBc2xIa3d2Z0Z1WGthakRUem5sdmsKK04xdHJTdDhzVjRwQVdqYTYzWFZFQ0RkQ2NBeiszRjRob0tPS3dKQ2NhTnBRNWtVUVIzaTJUdEpseWNNMzMrRkMKK1k3QlhOMFV0ZTRxY3Z3WHFaVlV6OXprUXhTZ3FJWG9iaXNRaytUOFZ5Sm9WSVBWVllwYnRiWk5Rdk9TcWVLM1oKK3l3cGxoNlptd2NTQm8zYzZXQjRMN29PTG5SN1NVcVRNSFcrd21HMlVNYlg0Y1FyY3VmeDlNbURtNjYrS0FRPT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMTAwMDAwMTIgKDB4OTg5NjhjKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9TkwsIE89U3RhYXQgZGVyIE5lZGVybGFuZGVuLCBDTj1TdGFhdCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBNYXIgMjYgMTE6MTg6MTcgMjAwOCBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IE1hciAyNSAxMTowMzoxMCAyMDIwIEdNVAorICAgICAgICBTdWJqZWN0OiBDPU5MLCBPPVN0YWF0IGRlciBOZWRlcmxhbmRlbiwgQ049U3RhYXQgZGVyIE5lZGVybGFuZGVuIFJvb3QgQ0EgLSBHMgorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDQwOTYgYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDQwOTYgYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YzU6NTk6ZTc6NmY6NzU6YWE6M2U6NGI6OWM6YjU6Yjg6YWM6OWU6MGI6CisgICAgICAgICAgICAgICAgICAgIGU0OmY5OmQ5OmNhOmFiOjVkOjhmOmI1OjM5OjEwOjgyOmQ3OmFmOjUxOmUwOgorICAgICAgICAgICAgICAgICAgICAzYjplMTowMDo0ODo2YTpjZjpkYTplMTowNjo0MzoxMTo5OTphYToxNDoyNToKKyAgICAgICAgICAgICAgICAgICAgMTI6YWQ6MjI6ZTg6MDA6NmQ6NDM6YzQ6YTk6Yjg6ZTU6MWY6ODk6NGI6Njc6CisgICAgICAgICAgICAgICAgICAgIGJkOjYxOjQ4OmVmOmZkOmQyOmUwOjYwOjg4OmU1OmI5OjE4OjYwOjI4OmMzOgorICAgICAgICAgICAgICAgICAgICA3NzoyYjphZDpiMDozNzphYTozNzpkZTo2NDo1OToyYTo0Njo1NzplNDo0YjoKKyAgICAgICAgICAgICAgICAgICAgYjk6Zjg6Mzc6N2M6ZDU6MzY6ZTc6ODA6YzE6YjY6ZjM6ZDQ6Njc6OWI6OTY6CisgICAgICAgICAgICAgICAgICAgIGU4OmNlOmQ3OmM2OjBhOjUzOmQwOjZiOjQ5Ojk2OmYzOmEzOjBiOjA1Ojc3OgorICAgICAgICAgICAgICAgICAgICA0ODpmNzoyNTplNTo3MDphYzozMDoxNDoyMDoyNTplMzo3Zjo3NTo1YTplNToKKyAgICAgICAgICAgICAgICAgICAgNDg6Zjg6NGU6N2I6MDM6MDc6MDQ6ZmE6ODI6NjE6ODc6NmU6ZjA6M2I6YzQ6CisgICAgICAgICAgICAgICAgICAgIGE0OmM3OmQwOmY1Ojc0OjNlOmE1OjVkOjFhOjA4OmYyOjliOjI1OmQyOmY2OgorICAgICAgICAgICAgICAgICAgICBhYzowNDoyNjozZTo1NTozYTo2MjoyODphNTo3YjpiMjozMDphZjpmODozNzoKKyAgICAgICAgICAgICAgICAgICAgYzI6ZDE6YmE6ZDY6Mzg6ZmQ6ZjQ6ZWY6NDk6MzA6Mzc6OTk6MjY6MjE6NDg6CisgICAgICAgICAgICAgICAgICAgIDg1OjAxOmE5OmU1OjE2OmU3OmRjOjkwOjU1OmRmOjBmOmU4OjM4OmNkOjk5OgorICAgICAgICAgICAgICAgICAgICAzNzoyMTo0Zjo1ZDpmNToyMjo2Zjo2YTpjNToxMjoxNjo2MDoxNzo1NTpmMjoKKyAgICAgICAgICAgICAgICAgICAgNjU6NjY6YTY6YTc6MzA6OTE6Mzg6YzE6Mzg6MWQ6ODY6MDQ6ODQ6YmE6MWE6CisgICAgICAgICAgICAgICAgICAgIDI1Ojc4OjVlOjlkOmFmOmNjOjUwOjYwOmQ2OjEzOjg3OjUyOmVkOjYzOjFmOgorICAgICAgICAgICAgICAgICAgICA2ZDo2NTo3ZDpjMjoxNToxODo3NDpjYTplMTo3ZTo2NDoyOTo4Yzo3MjpkODoKKyAgICAgICAgICAgICAgICAgICAgMTY6MTM6N2Q6MGI6NDk6NGE6ZjE6Mjg6MWI6MjA6NzQ6NmI6YzU6M2Q6ZGQ6CisgICAgICAgICAgICAgICAgICAgIGIwOmFhOjQ4OjA5OjNkOjJlOjgyOjk0OmNkOjFhOjY1OmQ5OjJiOjg4OjlhOgorICAgICAgICAgICAgICAgICAgICA5OTpiYzoxODo3ZTo5ZjplZTo3ZDo2Njo3YzozZTpiZDo5NDpiODo4MTpjZToKKyAgICAgICAgICAgICAgICAgICAgY2Q6OTg6MzA6Nzg6YzE6NmY6Njc6ZDA6YmU6NWY6ZTA6Njg6ZWQ6ZGU6ZTI6CisgICAgICAgICAgICAgICAgICAgIGIxOmM5OjJjOjU5Ojc4OjkyOmFhOmRmOjJiOjYwOjYzOmYyOmU1OjVlOmI5OgorICAgICAgICAgICAgICAgICAgICBlMzpjYTpmYTo3Zjo1MDo4NjozZTphMjozNDoxODowYzowOTo2ODoyODoxMToKKyAgICAgICAgICAgICAgICAgICAgMWM6ZTQ6ZTE6Yjk6NWM6M2U6NDc6YmE6MzI6M2Y6MTg6Y2M6NWI6ODQ6ZjU6CisgICAgICAgICAgICAgICAgICAgIGYzOjZiOjc0OmM0OjcyOjc0OmUxOmUzOjhiOmEwOjRhOmJkOjhkOjY2OjJmOgorICAgICAgICAgICAgICAgICAgICBlYTphZDozNTpkYToyMDpkMzo4ODo4Mjo2MTpmMDoxMjoyMjpiNjpiYzpkMDoKKyAgICAgICAgICAgICAgICAgICAgZDU6YTQ6ZWM6YWY6NTQ6ODg6MjU6MjQ6M2M6YTc6NmQ6YjE6NzI6Mjk6M2Y6CisgICAgICAgICAgICAgICAgICAgIDNlOjU3OmE2OjdmOjU1OmFmOjZlOjI2OmM2OmZlOmU3OmNjOjQwOjVjOjUxOgorICAgICAgICAgICAgICAgICAgICA0NDo4MTowYTo3ODpkZTo0YTpjZTo1NTpiZjoxZDpkNTpkOTpiNzo1NjplZjoKKyAgICAgICAgICAgICAgICAgICAgZjA6NzY6ZmY6MGI6Nzk6YjU6YWY6YmQ6ZmI6YTk6Njk6OTE6NDY6OTc6Njg6CisgICAgICAgICAgICAgICAgICAgIDgwOjE0OjM2OjFkOmIzOjdmOmJiOjI5Ojk4OjM2OmE1OjIwOmZhOjgyOjYwOgorICAgICAgICAgICAgICAgICAgICA2MjozMzphNDplYzpkNjpiYTowNzphNzo2ZTpjNTpjZjoxNDphNjplNzpkNjoKKyAgICAgICAgICAgICAgICAgICAgOTI6MzQ6ZDg6ODE6ZjU6ZmM6MWQ6NWQ6YWE6NWM6MWU6ZjY6YTM6NGQ6M2I6CisgICAgICAgICAgICAgICAgICAgIGI4OmY3OjM5CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgQ2VydGlmaWNhdGUgUG9saWNpZXM6IAorICAgICAgICAgICAgICAgIFBvbGljeTogWDUwOXYzIEFueSBQb2xpY3kKKyAgICAgICAgICAgICAgICAgIENQUzogaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMgorCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgOTE6Njg6MzI6ODc6MTU6MUQ6ODk6RTI6QjU6RjE6QUM6MzY6Mjg6MzQ6OEQ6MEI6N0M6NjI6ODg6RUIKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBhODo0MTo0YTo2NzoyYTo5Mjo4MTo4Mjo1MDo2ZTplMTpkNzpkODpiMzozOTozYjpmMzowMjoKKyAgICAgICAgMTU6MDk6NTA6NTE6ZWY6MmQ6YmQ6MjQ6N2I6ODg6ODY6M2I6Zjk6YjQ6YmM6OTI6MDk6OTY6CisgICAgICAgIGI5OmY2OmMwOmFiOjIzOjYwOjA2Ojc5OjhjOjExOjRlOjUxOmQyOjc5OjgwOjMzOmZiOjlkOgorICAgICAgICA0ODpiZTplYzo0MTo0Mzo4MToxZjo3ZTo0Nzo0MDoxYzplNTo3YTowODpjYTphYTo4Yjo3NToKKyAgICAgICAgYWQ6MTQ6YzQ6YzI6ZTg6NjY6M2M6ODI6MDc6YTc6ZTY6Mjc6ODI6NWI6MTg6ZTY6MGY6NmU6CisgICAgICAgIGQ5OjUwOjNlOjhhOjQyOjE4OjI5OmM2OmI0OjU2OmZjOjU2OjEwOmEwOjA1OjE3OmJkOjBjOgorICAgICAgICAyMzo3ZjpmNDo5MzplZDo5YzoxYTo1MTpiZTpkZDo0NTo0MTpiZjo5MToyNDpiNDoxZjo4YzoKKyAgICAgICAgZTk6NWY6Y2Y6N2I6MjE6OTk6OWY6OTU6OWY6Mzk6M2E6NDY6MWM6NmM6Zjk6Y2Q6N2I6OWM6CisgICAgICAgIDkwOmNkOjI4OmE5OmM3OmE5OjU1OmJiOmFjOjYyOjM0OjYyOjM1OjEzOjRiOjE0OjNhOjU1OgorICAgICAgICA4MzpiOTo4Njo4ZDo5MjphNjpjNjpmNDowNzoyNTo1NDpjYzoxNjo1NzoxMjo0YTo4Mjo3ODoKKyAgICAgICAgYzg6MTQ6ZDk6MTc6ODI6MjY6MmQ6NWQ6MjA6MWY6Nzk6YWU6ZmU6ZDQ6NzA6MTY6MTY6OTU6CisgICAgICAgIDgzOmQ4OjM1OjM5OmZmOjUyOjVkOjc1OjFjOjE2OmM1OjEzOjU1OmNmOjQ3OmNjOjc1OjY1OgorICAgICAgICA1Mjo0YTpkZTpmMDpiMDphNzplNDowYTo5NjowYjpmYjphZDpjMjplMjoyNTo4NDpiMjpkZDoKKyAgICAgICAgZTQ6YmQ6N2U6NTk6NmM6OWI6ZjA6ZjA6ZDg6ZTc6Y2E6ZjI6ZTk6OTc6Mzg6N2U6ODk6YmU6CisgICAgICAgIGNjOmZiOjM5OjE3OjYxOjNmOjcyOmRiOjNhOjkxOmQ4OjY1OjAxOjE5OjFkOmFkOjUwOmE0OgorICAgICAgICA1NzowYTo3Yzo0YjpiYzo5Yzo3MTo3MzoyYTo0NTo1MToxOTo4NTpjYzo4ZTpmZDo0NzphNzoKKyAgICAgICAgNzQ6OTU6MWQ6YTg6ZDE6YWY6NGU6MTc6YjE6Njk6MjY6YzI6YWE6Nzg6NTc6NWI6YzU6NGQ6CisgICAgICAgIGE3OmU1OjllOjA1OjE3Ojk0OmNhOmIyOjVmOmEwOjQ5OjE4OjhkOjM0OmU5OjI2OjZjOjQ4OgorICAgICAgICAxZTphYTo2ODo5MjowNTplMTo4Mjo3Mzo1YTo5YjpkYzowNzo1YjowODo2ZDo3ZDo5ZDpkNzoKKyAgICAgICAgOGQ6MjE6ZDk6ZmM6MTQ6MjA6YWE6YzI6NDU6ZGY6M2Y6ZTc6MDA6YjI6NTE6ZTQ6YzI6Zjg6CisgICAgICAgIDA1OmI5Ojc5OjFhOjhjOjM0OmYzOjllOjViOmU0OjM3OjViOjZiOjRhOmRmOjJjOjU3OjhhOgorICAgICAgICA0MDo1YTozNjpiYTpkZDo3NTo0NDowODozNzo0Mjo3MDowYzpmZTpkYzo1ZToyMTphMDphMzoKKyAgICAgICAgOGE6YzA6OTA6OWM6Njg6ZGE6NTA6ZTY6NDU6MTA6NDc6Nzg6YjY6NGU6ZDI6NjU6Yzk6YzM6CisgICAgICAgIDM3OmRmOmUxOjQyOjYzOmIwOjU3OjM3OjQ1OjJkOjdiOjhhOjljOmJmOjA1OmVhOjY1OjU1OgorICAgICAgICAzMzpmNzozOToxMDpjNToyODoyYToyMTo3YToxYjo4YTpjNDoyNDpmOTozZjoxNTpjODo5YToKKyAgICAgICAgMTU6MjA6ZjU6NTU6NjI6OTY6ZWQ6NmQ6OTM6NTA6YmM6ZTQ6YWE6Nzg6YWQ6ZDk6Y2I6MGE6CisgICAgICAgIDY1Ojg3OmE2OjY2OmMxOmM0OjgxOmEzOjc3OjNhOjU4OjFlOjBiOmVlOjgzOjhiOjlkOjFlOgorICAgICAgICBkMjo1MjphNDpjYzoxZDo2ZjpiMDo5ODo2ZDo5NDozMTpiNTpmODo3MTowYTpkYzpiOTpmYzoKKyAgICAgICAgN2Q6MzI6NjA6ZTY6ZWI6YWY6OGE6MDEKK1NIQTEgRmluZ2VycHJpbnQ9NTk6QUY6ODI6Nzk6OTE6ODY6Qzc6QjQ6NzU6MDc6Q0I6Q0Y6MDM6NTc6NDY6RUI6MDQ6REQ6Qjc6MTYKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8zZTcyNzFlOC4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzNlNzI3MWU4LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzNlODZmOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy8zZTcyNzFlOC4wCkBAIC0wLDAgKzEsODIgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRUtqQ0NBeEtnQXdJQkFnSUVPR1BlK0RBTkJna3Foa2lHOXcwQkFRVUZBRENCdERFVU1CSUdBMVVFQ2hNTAorUlc1MGNuVnpkQzV1WlhReFFEQStCZ05WQkFzVU4zZDNkeTVsYm5SeWRYTjBMbTVsZEM5RFVGTmZNakEwT0NCcAorYm1OdmNuQXVJR0o1SUhKbFppNGdLR3hwYldsMGN5QnNhV0ZpTGlreEpUQWpCZ05WQkFzVEhDaGpLU0F4T1RrNQorSUVWdWRISjFjM1F1Ym1WMElFeHBiV2wwWldReE16QXhCZ05WQkFNVEtrVnVkSEoxYzNRdWJtVjBJRU5sY25ScAorWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1SUNneU1EUTRLVEFlRncwNU9URXlNalF4TnpVd05URmFGdzB5T1RBMworTWpReE5ERTFNVEphTUlHME1SUXdFZ1lEVlFRS0V3dEZiblJ5ZFhOMExtNWxkREZBTUQ0R0ExVUVDeFEzZDNkMworTG1WdWRISjFjM1F1Ym1WMEwwTlFVMTh5TURRNElHbHVZMjl5Y0M0Z1lua2djbVZtTGlBb2JHbHRhWFJ6SUd4cAorWVdJdUtURWxNQ01HQTFVRUN4TWNLR01wSURFNU9Ua2dSVzUwY25WemRDNXVaWFFnVEdsdGFYUmxaREV6TURFRworQTFVRUF4TXFSVzUwY25WemRDNXVaWFFnUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa2dLREl3TkRncAorTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFyVTFMcVJLR3N1cWpJQWNWRm1RcQorSzB2UnZ3dEtUWTd0Z0hhbFo3ZDRRTUJ6UXNob3dOdFRLOTFldUhhWU5aT0xHcDE4RXpvT0gxdTNIcy9sSkJRZQorc1lHcGpYMjR6R3RMQS9FQ0ROeXJwVUFrQUg5MGxLR2RDQ216aUF2MWgzZWRWYzNrdzM3WGFtU3JoUlNHbFZ1WAorTWxCdlBjaTZaZ3pqL0wyNFNjRjJpVWtaL2NDb3ZZbWpaeS9Hbjd4eEdXQzRMZWtzeVpCMlpudVU0cTk0MW1WVAorWFR6V25MTFBLUVA1TDZSUXN0Ukl6Z1V5VllyOXNtUk1EdVNZQjNYYmY5KzVDRlZnaFRBcCtYdElwR21HNHpVLworSG9aZGVub1Z2ZThBamhVaVZCY0FrQ2FUdkE1SmFKRy8rRWZUblpWQ3dRNU4zMjhtejhNWUlXSm1RM0RXMWNBSAorNFFJREFRQUJvMEl3UURBT0JnTlZIUThCQWY4RUJBTUNBUVl3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFkQmdOVgorSFE0RUZnUVVWZVNCMFJHQXZ0aUp1UWlqTWZtaEpBa1d1WEF3RFFZSktvWklodmNOQVFFRkJRQURnZ0VCQUR1YgorajFhYk1PZFRtWHg2ZWFkTmw5Y1psWkQ3QmgvS00zeEdZNCtXWmlUNlFCc2hKOHJtY25QeVQvNHhtZjNJREV4bworVThhQWdoT1krcmF0MmwwOThjNXU5aFVSbElJTTdqK1ZyeEdyRDljdjNoOERqMWNzSHNtN21ocEVsZXNZVDZZZgorelgxWEVDK2JCQWxhaExWdTJCMDY0ZGFlMFd4NVhua2NGTVhqMEV5VE8yVTg3ZDg5dnFibGxSckR0Um5EdlY1YgordS84ajcyZ1p5eEtUSjF3RExXOHcwQjYyR3F6ZVd2ZlJxcWducHY1NWdjUjVtVE5YdWhLd3FlQkNiSlBLVnQ3KworYllRTENJdCtqZXJYbUNIRzgrYzhlUzllbk5GTUZZM2g3Q0kzekpwREM1ZmNnSkNOczJlYmIwZ0lGVmJQdi9FcgorZkY2YWR1bFprTVY4Z3pVUlpWRT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogOTQ2MDY5MjQwICgweDM4NjNkZWY4KQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBPPUVudHJ1c3QubmV0LCBPVT13d3cuZW50cnVzdC5uZXQvQ1BTXzIwNDggaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pLCBPVT0oYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVkLCBDTj1FbnRydXN0Lm5ldCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAoMjA0OCkKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IERlYyAyNCAxNzo1MDo1MSAxOTk5IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogSnVsIDI0IDE0OjE1OjEyIDIwMjkgR01UCisgICAgICAgIFN1YmplY3Q6IE89RW50cnVzdC5uZXQsIE9VPXd3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLiksIE9VPShjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQsIENOPUVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YWQ6NGQ6NGI6YTk6MTI6ODY6YjI6ZWE6YTM6MjA6MDc6MTU6MTY6NjQ6CisgICAgICAgICAgICAgICAgICAgIDJhOjJiOjRiOmQxOmJmOjBiOjRhOjRkOjhlOmVkOjgwOjc2OmE1OjY3OmI3OgorICAgICAgICAgICAgICAgICAgICA3ODo0MDpjMDo3Mzo0MjpjODo2ODpjMDpkYjo1MzoyYjpkZDo1ZTpiODo3NjoKKyAgICAgICAgICAgICAgICAgICAgOTg6MzU6OTM6OGI6MWE6OWQ6N2M6MTM6M2E6MGU6MWY6NWI6Yjc6MWU6Y2Y6CisgICAgICAgICAgICAgICAgICAgIGU1OjI0OjE0OjFlOmIxOjgxOmE5OjhkOjdkOmI4OmNjOjZiOjRiOjAzOmYxOgorICAgICAgICAgICAgICAgICAgICAwMjowYzpkYzphYjphNTo0MDoyNDowMDo3Zjo3NDo5NDphMTo5ZDowODoyOToKKyAgICAgICAgICAgICAgICAgICAgYjM6ODg6MGI6ZjU6ODc6Nzc6OWQ6NTU6Y2Q6ZTQ6YzM6N2U6ZDc6NmE6NjQ6CisgICAgICAgICAgICAgICAgICAgIGFiOjg1OjE0Ojg2Ojk1OjViOjk3OjMyOjUwOjZmOjNkOmM4OmJhOjY2OjBjOgorICAgICAgICAgICAgICAgICAgICBlMzpmYzpiZDpiODo0OTpjMTo3Njo4OTo0OToxOTpmZDpjMDphODpiZDo4OToKKyAgICAgICAgICAgICAgICAgICAgYTM6Njc6MmY6YzY6OWY6YmM6NzE6MTk6NjA6Yjg6MmQ6ZTk6MmM6Yzk6OTA6CisgICAgICAgICAgICAgICAgICAgIDc2OjY2OjdiOjk0OmUyOmFmOjc4OmQ2OjY1OjUzOjVkOjNjOmQ2OjljOmIyOgorICAgICAgICAgICAgICAgICAgICBjZjoyOTowMzpmOToyZjphNDo1MDpiMjpkNDo0ODpjZTowNTozMjo1NTo4YToKKyAgICAgICAgICAgICAgICAgICAgZmQ6YjI6NjQ6NGM6MGU6ZTQ6OTg6MDc6NzU6ZGI6N2Y6ZGY6Yjk6MDg6NTU6CisgICAgICAgICAgICAgICAgICAgIDYwOjg1OjMwOjI5OmY5OjdiOjQ4OmE0OjY5Ojg2OmUzOjM1OjNmOjFlOjg2OgorICAgICAgICAgICAgICAgICAgICA1ZDo3YTo3YToxNTpiZDplZjowMDo4ZToxNToyMjo1NDoxNzowMDo5MDoyNjoKKyAgICAgICAgICAgICAgICAgICAgOTM6YmM6MGU6NDk6Njg6OTE6YmY6Zjg6NDc6ZDM6OWQ6OTU6NDI6YzE6MGU6CisgICAgICAgICAgICAgICAgICAgIDRkOmRmOjZmOjI2OmNmOmMzOjE4OjIxOjYyOjY2OjQzOjcwOmQ2OmQ1OmMwOgorICAgICAgICAgICAgICAgICAgICAwNzplMQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDU1OkU0OjgxOkQxOjExOjgwOkJFOkQ4Ojg5OkI5OjA4OkEzOjMxOkY5OkExOjI0OjA5OjE2OkI5OjcwCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDNiOjliOjhmOjU2OjliOjMwOmU3OjUzOjk5OjdjOjdhOjc5OmE3OjRkOjk3OmQ3OjE5Ojk1OgorICAgICAgICA5MDpmYjowNjoxZjpjYTozMzo3Yzo0Njo2Mzo4Zjo5Njo2NjoyNDpmYTo0MDoxYjoyMToyNzoKKyAgICAgICAgY2E6ZTY6NzI6NzM6ZjI6NGY6ZmU6MzE6OTk6ZmQ6Yzg6MGM6NGM6Njg6NTM6YzY6ODA6ODI6CisgICAgICAgIDEzOjk4OmZhOmI2OmFkOmRhOjVkOjNkOmYxOmNlOjZlOmY2OjE1OjExOjk0OjgyOjBjOmVlOgorICAgICAgICAzZjo5NTphZjoxMTphYjowZjpkNzoyZjpkZToxZjowMzo4Zjo1NzoyYzoxZTpjOTpiYjo5YToKKyAgICAgICAgMWE6NDQ6OTU6ZWI6MTg6NGY6YTY6MWY6Y2Q6N2Q6NTc6MTA6MmY6OWI6MDQ6MDk6NWE6ODQ6CisgICAgICAgIGI1OjZlOmQ4OjFkOjNhOmUxOmQ2OjllOmQxOjZjOjc5OjVlOjc5OjFjOjE0OmM1OmUzOmQwOgorICAgICAgICA0Yzo5MzozYjo2NTozYzplZDpkZjozZDpiZTphNjplNTo5NToxYTpjMzpiNToxOTpjMzpiZDoKKyAgICAgICAgNWU6NWI6YmI6ZmY6MjM6ZWY6Njg6MTk6Y2I6MTI6OTM6Mjc6NWM6MDM6MmQ6NmY6MzA6ZDA6CisgICAgICAgIDFlOmI2OjFhOmFjOmRlOjVhOmY3OmQxOmFhOmE4OjI3OmE2OmZlOjc5OjgxOmM0Ojc5Ojk5OgorICAgICAgICAzMzo1NzpiYToxMjpiMDphOTplMDo0Mjo2Yzo5MzpjYTo1NjpkZTpmZTo2ZDo4NDowYjowODoKKyAgICAgICAgOGI6N2U6OGQ6ZWE6ZDc6OTg6MjE6YzY6ZjM6ZTc6M2M6Nzk6MmY6NWU6OWM6ZDE6NGM6MTU6CisgICAgICAgIDhkOmUxOmVjOjIyOjM3OmNjOjlhOjQzOjBiOjk3OmRjOjgwOjkwOjhkOmIzOjY3OjliOjZmOgorICAgICAgICA0ODowODoxNTo1NjpjZjpiZjpmMToyYjo3Yzo1ZTo5YTo3NjplOTo1OTo5MDpjNTo3Yzo4MzoKKyAgICAgICAgMzU6MTE6NjU6NTEKK1NIQTEgRmluZ2VycHJpbnQ9NTA6MzA6MDY6MDk6MUQ6OTc6RDQ6RjU6QUU6Mzk6Rjc6Q0I6RTc6OTI6N0Q6N0Q6NjU6MkQ6MzQ6MzEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy80MTg1OTViOS4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzQxODU5NWI5LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDZlYTliYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy80MTg1OTViOS4wCkBAIC0wLDAgKzEsODcgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRkZ6Q0NBLytnQXdJQkFnSUJFVEFOQmdrcWhraUc5dzBCQVFVRkFEQ0NBU3N4Q3pBSkJnTlZCQVlUQWxSUworTVJnd0ZnWURWUVFIREE5SFpXSjZaU0F0SUV0dlkyRmxiR2t4UnpCRkJnTlZCQW9NUGxURHZISnJhWGxsSUVKcAorYkdsdGMyVnNJSFpsSUZSbGEyNXZiRzlxYVdzZ1FYSmh4WjkweExGeWJXRWdTM1Z5ZFcxMUlDMGdWTU9jUXNTdworVkVGTE1VZ3dSZ1lEVlFRTEREOVZiSFZ6WVd3Z1JXeGxhM1J5YjI1cGF5QjJaU0JMY21sd2RHOXNiMnBwSUVGeQorWWNXZmRNU3hjbTFoSUVWdWMzUnBkTU84YzhPOElDMGdWVVZMUVVVeEl6QWhCZ05WQkFzTUdrdGhiWFVnVTJWeQorZEdsbWFXdGhjM2x2YmlCTlpYSnJaWHBwTVVvd1NBWURWUVFEREVGVXc1eEN4TEJVUVVzZ1ZVVkxRVVVnUzhPMgorYXlCVFpYSjBhV1pwYTJFZ1NHbDZiV1YwSUZOaHhKOXNZWG5Fc1dQRXNYUEVzU0F0SUZQRHZITER2RzBnTXpBZQorRncwd056QTRNalF4TVRNM01EZGFGdzB4TnpBNE1qRXhNVE0zTURkYU1JSUJLekVMTUFrR0ExVUVCaE1DVkZJeAorR0RBV0JnTlZCQWNNRDBkbFlucGxJQzBnUzI5allXVnNhVEZITUVVR0ExVUVDZ3crVk1POGNtdHBlV1VnUW1scworYVcxelpXd2dkbVVnVkdWcmJtOXNiMnBwYXlCQmNtSEZuM1RFc1hKdFlTQkxkWEoxYlhVZ0xTQlV3NXhDeExCVQorUVVzeFNEQkdCZ05WQkFzTVAxVnNkWE5oYkNCRmJHVnJkSEp2Ym1scklIWmxJRXR5YVhCMGIyeHZhbWtnUVhKaAoreFo5MHhMRnliV0VnUlc1emRHbDB3N3h6dzd3Z0xTQlZSVXRCUlRFak1DRUdBMVVFQ3d3YVMyRnRkU0JUWlhKMAorYVdacGEyRnplVzl1SUUxbGNtdGxlbWt4U2pCSUJnTlZCQU1NUVZURG5FTEVzRlJCU3lCVlJVdEJSU0JMdzdacgorSUZObGNuUnBabWxyWVNCSWFYcHRaWFFnVTJIRW4yeGhlY1N4WThTeGM4U3hJQzBnVThPOGNzTzhiU0F6TUlJQgorSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQWltMUwveENJT3NQMmZwVG82aUJrY0s0aAorZ2I0NmV6emI4UjFTZjFuNjh5Sk1sYUNRdkVoT0Vhdjd0N1dOZW9Nb2pDWkcyRTZWUUlkaG44V2ViWUdIVjJ5SworTzdSbTZzeEEvT09xYkxMTEFkc3l2OUxyaGMraERWWERXemhYY0xoMXhublJGRER0RzFoYmErODE4cUVoVHNYTworZkpsZmJMbTRJcE5RcDgxTWNHcSthZ1YvRTV3ckh1citSODRFcFcrc2t5NThLNStlZVJPUjZPcWV5amgxam1LdworbFpNcTVkL3BYcGR1SUY5ZmhIcEVPUmxBSExwVksvc3dzb0h2aE9QYzdKZzRPUU9GQ0tsVUF3VXA4TW1QaStvTAoraG1VWkVkUHBDU1BlYUpNRHlUWWNJVzdPakdieG1URFkxN1BESGZpQkxxaTlnZ3RtL29MTDRlQWFnc05BZ1FJRAorQVFBQm8wSXdRREFkQmdOVkhRNEVGZ1FVdllpSHlZLzJwQW9McXV2Ri9wRWpuYXRLaWpJd0RnWURWUjBQQVFILworQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBQjE4K2ttUAorTk9tM0pwSVdtZ1YwNTB2UWJUbHN3eWIyenJneHZNVGZ2Q3I0TjVFWTNBVElaSmtyR0cyQUExbkpydmhZMEQ3dAord3lPZmFUeUdPQnllNzlvbmVOR0VOM0dLUEVzNXozNUZCdFl0MklwTmVCTFdyY0xUeTlMUVFmTW1Oa3FibFd3TQorN3VYUlF5ZG13WWozZXJNZ2JPcXdhU3ZISU9nTUE4UkJCWm5pUCtScitLQ0dnY2VFeGgvVlM0RVNzaFloTEJPaAorZ0xKZURFb1RuaURZWWtDcmtPcGtTaStzRFFFU2VVV29MNGNaYU1qaWhjY3dzblg1T0QreXdKTzBhK0lEUk01bgorb04rSjFxMk1kcU1UdzVSaEsydlpiTUVIQ2lJSGhXeUZKRWFwdmorTGVJU0NmaVFNbmYyQk4rTWxxTzAyVHBVcworeVp5UTJ1eXBRanl0dGdJPQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAxNyAoMHgxMSkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1UUiwgTD1HZWJ6ZSAtIEtvY2FlbGksIE89VFx4QzNceEJDcmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmFceEM1XHg5RnRceEM0XHhCMXJtYSBLdXJ1bXUgLSBUXHhDM1x4OUNCXHhDNFx4QjBUQUssIE9VPVVsdXNhbCBFbGVrdHJvbmlrIHZlIEtyaXB0b2xvamkgQXJhXHhDNVx4OUZ0XHhDNFx4QjFybWEgRW5zdGl0XHhDM1x4QkNzXHhDM1x4QkMgLSBVRUtBRSwgT1U9S2FtdSBTZXJ0aWZpa2FzeW9uIE1lcmtlemksIENOPVRceEMzXHg5Q0JceEM0XHhCMFRBSyBVRUtBRSBLXHhDM1x4QjZrIFNlcnRpZmlrYSBIaXptZXQgU2FceEM0XHg5RmxheVx4QzRceEIxY1x4QzRceEIxc1x4QzRceEIxIC0gU1x4QzNceEJDclx4QzNceEJDbSAzCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBBdWcgMjQgMTE6Mzc6MDcgMjAwNyBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEF1ZyAyMSAxMTozNzowNyAyMDE3IEdNVAorICAgICAgICBTdWJqZWN0OiBDPVRSLCBMPUdlYnplIC0gS29jYWVsaSwgTz1UXHhDM1x4QkNya2l5ZSBCaWxpbXNlbCB2ZSBUZWtub2xvamlrIEFyYVx4QzVceDlGdFx4QzRceEIxcm1hIEt1cnVtdSAtIFRceEMzXHg5Q0JceEM0XHhCMFRBSywgT1U9VWx1c2FsIEVsZWt0cm9uaWsgdmUgS3JpcHRvbG9qaSBBcmFceEM1XHg5RnRceEM0XHhCMXJtYSBFbnN0aXRceEMzXHhCQ3NceEMzXHhCQyAtIFVFS0FFLCBPVT1LYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSwgQ049VFx4QzNceDlDQlx4QzRceEIwVEFLIFVFS0FFIEtceEMzXHhCNmsgU2VydGlmaWthIEhpem1ldCBTYVx4QzRceDlGbGF5XHhDNFx4QjFjXHhDNFx4QjFzXHhDNFx4QjEgLSBTXHhDM1x4QkNyXHhDM1x4QkNtIDMKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOjhhOjZkOjRiOmZmOjEwOjg4OjNhOmMzOmY2OjdlOjk0OmU4OmVhOjIwOgorICAgICAgICAgICAgICAgICAgICA2NDo3MDphZToyMTo4MTpiZTozYTo3YjozYzpkYjpmMToxZDo1Mjo3Zjo1OToKKyAgICAgICAgICAgICAgICAgICAgZmE6ZjM6MjI6NGM6OTU6YTA6OTA6YmM6NDg6NGU6MTE6YWI6ZmI6Yjc6YjU6CisgICAgICAgICAgICAgICAgICAgIDhkOjdhOjgzOjI4OjhjOjI2OjQ2OmQ4OjRlOjk1OjQwOjg3OjYxOjlmOmM1OgorICAgICAgICAgICAgICAgICAgICA5ZTo2ZDo4MTo4Nzo1Nzo2Yzo4YTozYjpiNDo2NjplYTpjYzo0MDpmYzplMzoKKyAgICAgICAgICAgICAgICAgICAgYWE6NmM6YjI6Y2I6MDE6ZGI6MzI6YmY6ZDI6ZWI6ODU6Y2Y6YTE6MGQ6NTU6CisgICAgICAgICAgICAgICAgICAgIGMzOjViOjM4OjU3OjcwOmI4Ojc1OmM2Ojc5OmQxOjE0OjMwOmVkOjFiOjU4OgorICAgICAgICAgICAgICAgICAgICA1Yjo2YjplZjozNTpmMjphMToyMTo0ZTpjNTpjZTo3Yzo5OTo1Zjo2YzpiOToKKyAgICAgICAgICAgICAgICAgICAgYjg6MjI6OTM6NTA6YTc6Y2Q6NGM6NzA6NmE6YmU6NmE6MDU6N2Y6MTM6OWM6CisgICAgICAgICAgICAgICAgICAgIDJiOjFlOmVhOmZlOjQ3OmNlOjA0OmE1OjZmOmFjOjkzOjJlOjdjOjJiOjlmOgorICAgICAgICAgICAgICAgICAgICA5ZTo3OToxMzo5MTplODplYTo5ZTpjYTozODo3NTo4ZTo2MjpiMDo5NTo5MzoKKyAgICAgICAgICAgICAgICAgICAgMmE6ZTU6ZGY6ZTk6NWU6OTc6NmU6MjA6NWY6NWY6ODQ6N2E6NDQ6Mzk6MTk6CisgICAgICAgICAgICAgICAgICAgIDQwOjFjOmJhOjU1OjJiOmZiOjMwOmIyOjgxOmVmOjg0OmUzOmRjOmVjOjk4OgorICAgICAgICAgICAgICAgICAgICAzODozOTowMzo4NTowODphOTo1NDowMzowNToyOTpmMDpjOTo4Zjo4YjplYToKKyAgICAgICAgICAgICAgICAgICAgMGI6ODY6NjU6MTk6MTE6ZDM6ZTk6MDk6MjM6ZGU6Njg6OTM6MDM6Yzk6MzY6CisgICAgICAgICAgICAgICAgICAgIDFjOjIxOjZlOmNlOjhjOjY2OmYxOjk5OjMwOmQ4OmQ3OmIzOmMzOjFkOmY4OgorICAgICAgICAgICAgICAgICAgICA4MToyZTphODpiZDo4MjowYjo2NjpmZTo4MjpjYjplMTplMDoxYTo4MjpjMzoKKyAgICAgICAgICAgICAgICAgICAgNDA6ODEKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEJEOjg4Ojg3OkM5OjhGOkY2OkE0OjBBOjBCOkFBOkVCOkM1OkZFOjkxOjIzOjlEOkFCOjRBOjhBOjMyCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAxZDo3YzpmYTo0OTo4ZjozNDplOTpiNzoyNjo5MjoxNjo5YTowNTo3NDplNzo0YjpkMDo2ZDoKKyAgICAgICAgMzk6NmM6YzM6MjY6ZjY6Y2U6Yjg6MzE6YmM6YzQ6ZGY6YmM6MmE6Zjg6Mzc6OTE6MTg6ZGM6CisgICAgICAgIDA0OmM4OjY0Ojk5OjJiOjE4OjZkOjgwOjAzOjU5OmM5OmFlOmY4OjU4OmQwOjNlOmVkOmMzOgorICAgICAgICAyMzo5Zjo2OTozYzo4NjozODoxYzo5ZTplZjpkYToyNzo3ODpkMTo4NDozNzo3MTo4YTozYzoKKyAgICAgICAgNGI6Mzk6Y2Y6N2U6NDU6MDY6ZDY6MmQ6ZDg6OGE6NGQ6Nzg6MTI6ZDY6YWQ6YzI6ZDM6Y2I6CisgICAgICAgIGQyOmQwOjQxOmYzOjI2OjM2OjRhOjliOjk1OjZjOjBjOmVlOmU1OmQxOjQzOjI3OjY2OmMxOgorICAgICAgICA4ODpmNzo3YTpiMzoyMDo2YzplYTpiMDo2OToyYjpjNzoyMDplODowYzowMzpjNDo0MTowNToKKyAgICAgICAgOTk6ZTI6M2Y6ZTQ6NmI6Zjg6YTA6ODY6ODE6Yzc6ODQ6YzY6MWY6ZDU6NGI6ODE6MTI6YjI6CisgICAgICAgIDE2OjIxOjJjOjEzOmExOjgwOmIyOjVlOjBjOjRhOjEzOjllOjIwOmQ4OjYyOjQwOmFiOjkwOgorICAgICAgICBlYTo2NDo0YToyZjphYzowZDowMToxMjo3OTo0NTphODoyZjo4NzoxOTo2ODpjODplMjo4NToKKyAgICAgICAgYzc6MzA6YjI6NzU6Zjk6Mzg6M2Y6YjI6YzA6OTM6YjQ6NmI6ZTI6MDM6NDQ6Y2U6Njc6YTA6CisgICAgICAgIGRmOjg5OmQ2OmFkOjhjOjc2OmEzOjEzOmMzOjk0OjYxOjJiOjZiOmQ5OjZjOmMxOjA3OjBhOgorICAgICAgICAyMjowNzo4NTo2Yzo4NToyNDo0NjphOTpiZTozZjo4Yjo3ODo4NDo4Mjo3ZToyNDowYzo5ZDoKKyAgICAgICAgZmQ6ODE6Mzc6ZTM6MjU6YTg6ZWQ6MzY6NGU6OTU6MmM6Yzk6OWM6OTA6ZGE6ZWM6YTk6NDI6CisgICAgICAgIDNjOmFkOmI2OjAyCitTSEExIEZpbmdlcnByaW50PTFCOjRCOjM5OjYxOjI2OjI3OjZCOjY0OjkxOkEyOjY4OjZEOkQ3OjAyOjQzOjIxOjJEOjFGOjFEOjk2CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNDU1ZjFiNTIuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy80NTVmMWI1Mi4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVjZGUzMmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNDU1ZjFiNTIuMApAQCAtMCwwICsxLDgyIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUVQakNDQXlhZ0F3SUJBZ0lFU2xPTUtEQU5CZ2txaGtpRzl3MEJBUXNGQURDQnZqRUxNQWtHQTFVRUJoTUMKK1ZWTXhGakFVQmdOVkJBb1REVVZ1ZEhKMWMzUXNJRWx1WXk0eEtEQW1CZ05WQkFzVEgxTmxaU0IzZDNjdVpXNTAKK2NuVnpkQzV1WlhRdmJHVm5ZV3d0ZEdWeWJYTXhPVEEzQmdOVkJBc1RNQ2hqS1NBeU1EQTVJRVZ1ZEhKMWMzUXMKK0lFbHVZeTRnTFNCbWIzSWdZWFYwYUc5eWFYcGxaQ0IxYzJVZ2IyNXNlVEV5TURBR0ExVUVBeE1wUlc1MGNuVnoKK2RDQlNiMjkwSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVJQzBnUnpJd0hoY05NRGt3TnpBM01UY3kKK05UVTBXaGNOTXpBeE1qQTNNVGMxTlRVMFdqQ0J2akVMTUFrR0ExVUVCaE1DVlZNeEZqQVVCZ05WQkFvVERVVnUKK2RISjFjM1FzSUVsdVl5NHhLREFtQmdOVkJBc1RIMU5sWlNCM2QzY3VaVzUwY25WemRDNXVaWFF2YkdWbllXd3QKK2RHVnliWE14T1RBM0JnTlZCQXNUTUNoaktTQXlNREE1SUVWdWRISjFjM1FzSUVsdVl5NGdMU0JtYjNJZ1lYVjAKK2FHOXlhWHBsWkNCMWMyVWdiMjVzZVRFeU1EQUdBMVVFQXhNcFJXNTBjblZ6ZENCU2IyOTBJRU5sY25ScFptbGoKK1lYUnBiMjRnUVhWMGFHOXlhWFI1SUMwZ1J6SXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUsKK0FvSUJBUUM2aExaeTI1NE1hK0taNlRBQnAzYnFNcmlWUVJySjJtRk9XSExQL3ZhQ2ViOXpZUVlLcFNmWXMxL1QKK1JVNGNjdFpPTXZKeWlnLzNneG5RYW9DQUFFVWVzTWZubXI4U1Z5Y2NvMmd2Q29lOWFtc09YbVh6SEhmVjFJV04KK2NDRzBzekxuaTZMVmhqa0NzYmpTUjg3a3lVbkVPNmZlKzFSOVY3N3c2RzdDZWJJNkMxWGlVSmdXTWhOY0wzaFcKK3djS1VzL0phNUNlYW55VFh4dXpRbXlXQzQ4ekN4RVhGakpkNkJtc3FFWitwQ201SU8yL2IxQkVaUXZlUEI3LzEKK1UxK2NQdlFYTE9acHJFNHlUR0ozNnJmbzViczB2Qm1McnB4UjU3ZCt0Vk94TXlMbGJjOXdQQnI2NHB0bnRvUDAKK2phV3ZZa3hONEZpc1pEUVNBL2kyalpSakpLUnhBZ01CQUFHalFqQkFNQTRHQTFVZER3RUIvd1FFQXdJQkJqQVAKK0JnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJScWNpWjYwQjd2ZmVjN2FWSFViSTJma0JKbXF6QU4KK0Jna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWVaOGRsc2EyZVQ4aWpZZlRod01FWUdwcm1pNVppWE1SckVQUjlSUC8KK2pUa3J3UEs5VDNDTXFTL3FGOFFMVko3VUc1YVlNenlvcldLaUFIYXJXV2x1QmgxK3hMbEVqWml2RXRSaDJ3b1oKK1JrZno2L2Rqd1VBRlFLWFN0L1MxbWphL3FZaDJpQVJWQkN1Y2gzOGFOengrTGFVYTJOU0pYc3E5ckQxczJHMnYKKzFmTjJEODA3aURnaW5XeVRtc1E5djRJYlpUK21EMTJxL09XeUZjcTFyY2E4UGRDRTZPb0djckJOT1RKNHZ6NFIKK25BdWtuWm9oOC9DYkN6QjQyOEhjaDBQK3ZHT2F5c1hDSE1uSGpmODdFbGdJNXJZOTdIb3NUdnVEbHM0TVBHbUgKK1ZIT2tjOEtULzFFUXJCVlVBZGo4QmJHSm9YOTBnNXBKMTl4T2U0cEliNHRGOWc9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAxMjQ2OTg5MzUyICgweDRhNTM4YzI4KQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9VVMsIE89RW50cnVzdCwgSW5jLiwgT1U9U2VlIHd3dy5lbnRydXN0Lm5ldC9sZWdhbC10ZXJtcywgT1U9KGMpIDIwMDkgRW50cnVzdCwgSW5jLiAtIGZvciBhdXRob3JpemVkIHVzZSBvbmx5LCBDTj1FbnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMgorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogSnVsICA3IDE3OjI1OjU0IDIwMDkgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBEZWMgIDcgMTc6NTU6NTQgMjAzMCBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgTz1FbnRydXN0LCBJbmMuLCBPVT1TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zLCBPVT0oYykgMjAwOSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHksIENOPUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpiYTo4NDpiNjo3MjpkYjo5ZTowYzo2YjplMjo5OTplOTozMDowMTphNzoKKyAgICAgICAgICAgICAgICAgICAgNzY6ZWE6MzI6Yjg6OTU6NDE6MWE6Yzk6ZGE6NjE6NGU6NTg6NzI6Y2Y6ZmU6CisgICAgICAgICAgICAgICAgICAgIGY2OjgyOjc5OmJmOjczOjYxOjA2OjBhOmE1OjI3OmQ4OmIzOjVmOmQzOjQ1OgorICAgICAgICAgICAgICAgICAgICA0ZToxYzo3MjpkNjo0ZTozMjpmMjo3Mjo4YTowZjpmNzo4MzoxOTpkMDo2YToKKyAgICAgICAgICAgICAgICAgICAgODA6ODA6MDA6NDU6MWU6YjA6Yzc6ZTc6OWE6YmY6MTI6NTc6Mjc6MWM6YTM6CisgICAgICAgICAgICAgICAgICAgIDY4OjJmOjBhOjg3OmJkOjZhOjZiOjBlOjVlOjY1OmYzOjFjOjc3OmQ1OmQ0OgorICAgICAgICAgICAgICAgICAgICA4NTo4ZDo3MDoyMTpiNDpiMzozMjplNzo4YjphMjpkNTo4NjozOTowMjpiMToKKyAgICAgICAgICAgICAgICAgICAgYjg6ZDI6NDc6Y2U6ZTQ6Yzk6NDk6YzQ6M2I6YTc6ZGU6ZmI6NTQ6N2Q6NTc6CisgICAgICAgICAgICAgICAgICAgIGJlOmYwOmU4OjZlOmMyOjc5OmIyOjNhOjBiOjU1OmUyOjUwOjk4OjE2OjMyOgorICAgICAgICAgICAgICAgICAgICAxMzo1YzoyZjo3ODo1NjpjMTpjMjo5NDpiMzpmMjo1YTplNDoyNzo5YTo5ZjoKKyAgICAgICAgICAgICAgICAgICAgMjQ6ZDc6YzY6ZWM6ZDA6OWI6MjU6ODI6ZTM6Y2M6YzI6YzQ6NDU6YzU6OGM6CisgICAgICAgICAgICAgICAgICAgIDk3OjdhOjA2OjZiOjJhOjExOjlmOmE5OjBhOjZlOjQ4OjNiOjZmOmRiOmQ0OgorICAgICAgICAgICAgICAgICAgICAxMToxOTo0MjpmNzo4ZjowNzpiZjpmNTo1Mzo1Zjo5YzozZTpmNDoxNzoyYzoKKyAgICAgICAgICAgICAgICAgICAgZTY6Njk6YWM6NGU6MzI6NGM6NjI6Nzc6ZWE6Yjc6ZTg6ZTU6YmI6MzQ6YmM6CisgICAgICAgICAgICAgICAgICAgIDE5OjhiOmFlOjljOjUxOmU3OmI3OjdlOmI1OjUzOmIxOjMzOjIyOmU1OjZkOgorICAgICAgICAgICAgICAgICAgICBjZjo3MDozYzoxYTpmYTplMjo5Yjo2NzpiNjo4MzpmNDo4ZDphNTphZjo2MjoKKyAgICAgICAgICAgICAgICAgICAgNGM6NGQ6ZTA6NTg6YWM6NjQ6MzQ6MTI6MDM6Zjg6YjY6OGQ6OTQ6NjM6MjQ6CisgICAgICAgICAgICAgICAgICAgIGE0OjcxCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgNkE6NzI6MjY6N0E6RDA6MUU6RUY6N0Q6RTc6M0I6Njk6NTE6RDQ6NkM6OEQ6OUY6OTA6MTI6NjY6QUIKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA3OTo5ZjoxZDo5NjpjNjpiNjo3OTozZjoyMjo4ZDo4NzpkMzo4NzowMzowNDo2MDo2YTo2YjoKKyAgICAgICAgOWE6MmU6NTk6ODk6NzM6MTE6YWM6NDM6ZDE6ZjU6MTM6ZmY6OGQ6Mzk6MmI6YzA6ZjI6YmQ6CisgICAgICAgIDRmOjcwOjhjOmE5OjJmOmVhOjE3OmM0OjBiOjU0OjllOmQ0OjFiOjk2Ojk4OjMzOjNjOmE4OgorICAgICAgICBhZDo2MjphMjowMDo3NjphYjo1OTo2OTo2ZTowNjoxZDo3ZTpjNDpiOTo0NDo4ZDo5ODphZjoKKyAgICAgICAgMTI6ZDQ6NjE6ZGI6MGE6MTk6NDY6NDc6ZjM6ZWI6Zjc6NjM6YzE6NDA6MDU6NDA6YTU6ZDI6CisgICAgICAgIGI3OmY0OmI1OjlhOjM2OmJmOmE5Ojg4Ojc2Ojg4OjA0OjU1OjA0OjJiOjljOjg3OjdmOjFhOgorICAgICAgICAzNzozYzo3ZToyZDphNToxYTpkODpkNDo4OTo1ZTpjYTpiZDphYzozZDo2YzpkODo2ZDphZjoKKyAgICAgICAgZDU6ZjM6NzY6MGY6Y2Q6M2I6ODg6Mzg6MjI6OWQ6NmM6OTM6OWE6YzQ6M2Q6YmY6ODI6MWI6CisgICAgICAgIDY1OjNmOmE2OjBmOjVkOmFhOmZjOmU1OmIyOjE1OmNhOmI1OmFkOmM2OmJjOjNkOmQwOjg0OgorICAgICAgICBlODplYTowNjo3MjpiMDo0ZDozOTozMjo3ODpiZjozZToxMTo5YzowYjphNDo5ZDo5YToyMToKKyAgICAgICAgZjM6ZjA6OWI6MGI6MzA6Nzg6ZGI6YzE6ZGM6ODc6NDM6ZmU6YmM6NjM6OWE6Y2E6YzU6YzI6CisgICAgICAgIDFjOmM5OmM3OjhkOmZmOjNiOjEyOjU4OjA4OmU2OmI2OjNkOmVjOjdhOjJjOjRlOmZiOjgzOgorICAgICAgICA5NjpjZTowYzozYzo2OTo4Nzo1NDo3MzphNDo3MzpjMjo5MzpmZjo1MToxMDphYzoxNTo1NDoKKyAgICAgICAgMDE6ZDg6ZmM6MDU6YjE6ODk6YTE6N2Y6NzQ6ODM6OWE6NDk6ZDc6ZGM6NGU6N2I6OGE6NDg6CisgICAgICAgIDZmOjhiOjQ1OmY2CitTSEExIEZpbmdlcnByaW50PThDOkY0OjI3OkZEOjc5OjBDOjNBOkQxOjY2OjA2OjhEOkU4OjFFOjU3OkVGOkJCOjkzOjIyOjcyOkQ0CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNDZiMmZkM2IuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy80NmIyZmQzYi4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFkOTRmMGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNDZiMmZkM2IuMApAQCAtMCwwICsxLDEyOSBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlGd1RDQ0E2bWdBd0lCQWdJSVRySUFad3dEWFU4d0RRWUpLb1pJaHZjTkFRRUZCUUF3U1RFTE1Ba0dBMVVFCitCaE1DUTBneEZUQVRCZ05WQkFvVERGTjNhWE56VTJsbmJpQkJSekVqTUNFR0ExVUVBeE1hVTNkcGMzTlRhV2R1CitJRkJzWVhScGJuVnRJRU5CSUMwZ1J6SXdIaGNOTURZeE1ESTFNRGd6TmpBd1doY05Nell4TURJMU1EZ3pOakF3CitXakJKTVFzd0NRWURWUVFHRXdKRFNERVZNQk1HQTFVRUNoTU1VM2RwYzNOVGFXZHVJRUZITVNNd0lRWURWUVFECitFeHBUZDJsemMxTnBaMjRnVUd4aGRHbHVkVzBnUTBFZ0xTQkhNakNDQWlJd0RRWUpLb1pJaHZjTkFRRUJCUUFECitnZ0lQQURDQ0Fnb0NnZ0lCQU1yZm9nTGkydmo4QnhheDNtQ3EzcFpjWkIvSEwzN1BaL3BFUXRaMlk1V3U2Njl5CitJSXBGUjRaaWVJYldJRGttOUs2ai9TUG5wWnkxSWlFWnR6ZVRJc0JRbklKNzFOVUVSRnpMdE1LZmtyNGsySHRuCitJdUpwWCtVRmVOU0gyWEZ3TXlWVHRJYzdLWkFvTnBwVlJEQm9wSU9YZncwZW5IYi9GWjFnbHdDTmlvVUQ3SUMrCis2aXh1RUZHU3pIN1ZvelBZMWtuZVdDcXY5aGJyUzN1UU1wZTV1cDFZOGZoWFNRUWVvbDBHY04xeDIvbmRpNW9iCitqTTg5bzAzT3kzejJ1NXlnK2duT0kyS3k2UTBmNG5Jb2o1K3NhQ0I5Ynp1b2hURUpmd3ZINkdYcDQzZ09DV2N3CitpelNDKzEzZ3pKMkJiV0x1Q0I0RUxFNmI3UDZwVDEvOWFYanZDUitodEwvNjgrK1FIa3dGaXg3cWVwRjZ3OWZsCisrekM4YkJzUVdKajNHbC9RS1RJREUwWk5ZV3FGVEZKMEx3WWZleEhpaEpmR21mTnRmOWRuZzM0VGFOaHhLRnJZCit6dDNvRUJTYS9tMGpoMjZPV25BODFZMEpBS2VxdkxBeE4yM0loQlFlVzcxRll5QnJTM1NNdmRzNkRzSFBXaGFQCitwWmp5ZG9teUV4STdDM2Qzckx2bFBDbEtrbkxLWVJvclhremlnM1IzK2pWSWVvVk5qWnBUeE45NHlwZVJTQ3RGCitLd0gzSEJxaTdSaTZDcjJEK20rOGpWZVRPOVRVcHM0ZThhQ3h6cXY5S3lpYVR4dlh3M0xicE1TL1hVejEzWHVXCithZTVvZ09ibm1MbzJ0LzV1N1N1OUlQaGxHZHBWQ1g0bDNQNWhZbkw1ZmhnQzcyTzAwUHV2NVR0ampHZVBBZ01CCitBQUdqZ2F3d2dha3dEZ1lEVlIwUEFRSC9CQVFEQWdFR01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPCitCQllFRkZDdnpBZUhGVWR2T01XMFpkSGVsYXJwMzV6TU1COEdBMVVkSXdRWU1CYUFGRkN2ekFlSEZVZHZPTVcwCitaZEhlbGFycDM1ek1NRVlHQTFVZElBUS9NRDB3T3dZSllJVjBBVmtCQVFFQk1DNHdMQVlJS3dZQkJRVUhBZ0VXCitJR2gwZEhBNkx5OXlaWEJ2YzJsMGIzSjVMbk4zYVhOemMybG5iaTVqYjIwdk1BMEdDU3FHU0liM0RRRUJCUVVBCitBNElDQVFBSWhhYjFGZ3o4UkJyQlkrRDVWVVlJL0hBY1FpaVdqcmZGd1VGMVRnbHhlZVZ0bHNwTHBZaGcwREIwCit1TW9JM0xRd25rQUhGbXRsbFhjQnJxUzNOUXVCMm5FVnFYUVhPSHRZeXZrdis4QmxkbzFiQWJsOTNvSTlaTGkrCitGSFNqQ2xUVExKVVlGelgxVVdzL2o2S1dZVGw0YTB2bHBxRDRVOTlSRUpOaTU0QXY0dEhndkk0MlJuY3o3TGo3CitqcG9zaVUweEVROG1uZ1M3dHdTTkMvSzUvRnFkT3hhM0w4aVlxLzZLVUZrdW96djhLVjJMd1V2SjRvb1RIYkcvCit1MElkVXQxTzJCUmVFTVl4Qis5eEovY2JPUW5jZ3VxTHM1V0dYdjMxMmwweHB1QXh0cFRtUkVsMHhSYmw5eDhECitZU2pGeU1zU29FSkwrV3VJQ0kyME1oanpkWi9FZndCUEJaV2NveGNDdzdOVG02b2dPU2tyWnZxZHIxNnprdEsxCitwdUVhK1MxQmFZRVV0TFMxN1lrOXp2dXBuVFZDUkxFY0ZIT0J6eW9CTlpveDFTMlBiWVRmZ0UxWDR6L0ZoSFhhCitpY1l3dSt1UHl5SUlvSzZxOFFOc09rdE5DYVVPY3NaV2F5RkNUaU1sRkdpdWRncDhEQWR3WlBtYUwvWUZPU2JHCitESThaZjBOZWJ2UmJGUy9iWVYzbVp5OC9DSlQ1WUxTWU1kcDA4WVNUY1UxZisyQlkwZnZFd1cySm9yc2dINTF4CitrY3N5bXhNOVBuMlNValdza3BTaTB4akNmTWZxcjNZRkZ0MW5KOEorSEFjaUlmTkFDaHMwQjBRVHdvUnFqdDhaCitXcjkvNngzaUdqalJYSzlIa211QXRUQ2x5WTNZcXpHQkg5L0NaamZUazZtRmhubGwwZz09CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICA0ZTpiMjowMDo2NzowYzowMzo1ZDo0ZgorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPUNILCBPPVN3aXNzU2lnbiBBRywgQ049U3dpc3NTaWduIFBsYXRpbnVtIENBIC0gRzIKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IE9jdCAyNSAwODozNjowMCAyMDA2IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogT2N0IDI1IDA4OjM2OjAwIDIwMzYgR01UCisgICAgICAgIFN1YmplY3Q6IEM9Q0gsIE89U3dpc3NTaWduIEFHLCBDTj1Td2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMgorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDQwOTYgYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDQwOTYgYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6Y2E6ZGY6YTI6MDI6ZTI6ZGE6Zjg6ZmM6MDc6MTY6YjE6ZGU6NjA6YWE6CisgICAgICAgICAgICAgICAgICAgIGRlOjk2OjVjOjY0OjFmOmM3OjJmOjdlOmNmOjY3OmZhOjQ0OjQyOmQ2Ojc2OgorICAgICAgICAgICAgICAgICAgICA2Mzo5NTphZTplYjphZjo3MjoyMDo4YTo0NTo0Nzo4Njo2Mjo3ODo4NjpkNjoKKyAgICAgICAgICAgICAgICAgICAgMjA6Mzk6MjY6ZjQ6YWU6YTM6ZmQ6MjM6ZTc6YTU6OWM6YjU6MjI6MjE6MTk6CisgICAgICAgICAgICAgICAgICAgIGI3OjM3OjkzOjIyOmMwOjUwOjljOjgyOjdiOmQ0OmQ1OjA0OjQ0OjVjOmNiOgorICAgICAgICAgICAgICAgICAgICBiNDpjMjo5Zjo5MjpiZToyNDpkODo3Yjo2NzoyMjplMjo2OTo1ZjplNTowNToKKyAgICAgICAgICAgICAgICAgICAgNzg6ZDQ6ODc6ZDk6NzE6NzA6MzM6MjU6NTM6YjQ6ODc6M2I6Mjk6OTA6Mjg6CisgICAgICAgICAgICAgICAgICAgIDM2OjlhOjU1OjQ0OjMwOjY4OmE0OjgzOjk3OjdmOjBkOjFlOjljOjc2OmZmOgorICAgICAgICAgICAgICAgICAgICAxNTo5ZDo2MDo5NzowMDo4ZDo4YTo4NTowMzplYzo4MDpiZTplYToyYzo2ZToKKyAgICAgICAgICAgICAgICAgICAgMTA6NTE6OTI6Y2M6N2U6ZDU6YTM6MzM6ZDg6ZDY6NDk6ZGU6NTg6MmE6YWY6CisgICAgICAgICAgICAgICAgICAgIGY2OjE2OmViOjRiOjdiOjkwOjMyOjk3OmI5OmJhOjlkOjU4OmYxOmY4OjU3OgorICAgICAgICAgICAgICAgICAgICA0OTowNDoxZTphMjo1ZDowNjo3MDpkZDo3MTpkYjpmOTpkZDo4Yjo5YToxYjoKKyAgICAgICAgICAgICAgICAgICAgOGM6Y2Y6M2Q6YTM6NGQ6Y2U6Y2I6N2M6ZjY6YmI6OWM6YTA6ZmE6MDk6Y2U6CisgICAgICAgICAgICAgICAgICAgIDIzOjYyOmIyOmU5OjBkOjFmOmUyOjcyOjI4OjhmOjlmOmFjOjY4OjIwOjdkOgorICAgICAgICAgICAgICAgICAgICA2ZjozYjphODo4NTozMTowOTo3ZjowYjpjNzplODo2NTplOTplMzo3ODowZToKKyAgICAgICAgICAgICAgICAgICAgMDk6Njc6MzA6OGI6MzQ6ODI6ZmI6NWQ6ZTA6Y2M6OWQ6ODE6NmQ6NjI6ZWU6CisgICAgICAgICAgICAgICAgICAgIDA4OjFlOjA0OjJjOjRlOjliOmVjOmZlOmE5OjRmOjVmOmZkOjY5Ojc4OmVmOgorICAgICAgICAgICAgICAgICAgICAwOToxZjphMTpiNDpiZjpmYTpmMzplZjo5MDoxZTo0YzowNTo4YjoxZTplYToKKyAgICAgICAgICAgICAgICAgICAgN2E6OTE6N2E6YzM6ZDc6ZTU6ZmI6MzA6YmM6NmM6MWI6MTA6NTg6OTg6Zjc6CisgICAgICAgICAgICAgICAgICAgIDFhOjVmOmQwOjI5OjMyOjAzOjEzOjQ2OjRkOjYxOjZhOjg1OjRjOjUyOjc0OgorICAgICAgICAgICAgICAgICAgICAyZjowNjoxZjo3YjoxMTplMjo4NDo5NzpjNjo5OTpmMzo2ZDo3ZjpkNzo2NzoKKyAgICAgICAgICAgICAgICAgICAgODM6N2U6MTM6Njg6ZDg6NzE6Mjg6NWE6ZDg6Y2U6ZGQ6ZTg6MTA6MTQ6OWE6CisgICAgICAgICAgICAgICAgICAgIGZlOjZkOjIzOjg3OjZlOjhlOjVhOjcwOjNjOmQ1OjhkOjA5OjAwOmE3OmFhOgorICAgICAgICAgICAgICAgICAgICBiYzpiMDozMTozNzo2ZDpjODo4NDoxNDoxZTo1YjpiZDo0NTo2MzoyMDo2YjoKKyAgICAgICAgICAgICAgICAgICAgNGI6NzQ6OGM6YmQ6ZGI6M2E6MGU6YzE6Y2Y6NWE6MTY6OGY6YTU6OTg6ZjI6CisgICAgICAgICAgICAgICAgICAgIDc2Ojg5OmIyOjEzOjEyOjNiOjBiOjc3Ojc3OmFjOmJiOmU1OjNjOjI5OjRhOgorICAgICAgICAgICAgICAgICAgICA5Mjo3MjpjYTo2MToxYToyYjo1ZTo0YzplMjo4Mzo3NDo3NzpmYTozNTo0ODoKKyAgICAgICAgICAgICAgICAgICAgN2E6ODU6NGQ6OGQ6OWE6NTM6YzQ6ZGY6Nzg6Y2E6OTc6OTE6NDg6MmI6NDU6CisgICAgICAgICAgICAgICAgICAgIDJiOjAxOmY3OjFjOjFhOmEyOmVkOjE4OmJhOjBhOmJkOjgzOmZhOjZmOmJjOgorICAgICAgICAgICAgICAgICAgICA4ZDo1Nzo5MzozYjpkNDpkNDphNjpjZToxZTpmMTphMDpiMTpjZTphYjpmZDoKKyAgICAgICAgICAgICAgICAgICAgMmI6Mjg6OWE6NGY6MWI6ZDc6YzM6NzI6ZGI6YTQ6YzQ6YmY6NWQ6NGM6ZjU6CisgICAgICAgICAgICAgICAgICAgIGRkOjdiOjk2OjY5OmVlOjY4OjgwOmU2OmU3Ojk4OmJhOjM2OmI3OmZlOjZlOgorICAgICAgICAgICAgICAgICAgICBlZDoyYjpiZDoyMDpmODo2NToxOTpkYTo1NTowOTo3ZToyNTpkYzpmZTo2MToKKyAgICAgICAgICAgICAgICAgICAgNjI6NzI6Zjk6N2U6MTg6MDI6ZWY6NjM6YjQ6ZDA6ZmI6YWY6ZTU6M2I6NjM6CisgICAgICAgICAgICAgICAgICAgIDhjOjY3OjhmCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgNTA6QUY6Q0M6MDc6ODc6MTU6NDc6NkY6Mzg6QzU6QjQ6NjU6RDE6REU6OTU6QUE6RTk6REY6OUM6Q0MKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOjUwOkFGOkNDOjA3Ojg3OjE1OjQ3OjZGOjM4OkM1OkI0OjY1OkQxOkRFOjk1OkFBOkU5OkRGOjlDOkNDCisKKyAgICAgICAgICAgIFg1MDl2MyBDZXJ0aWZpY2F0ZSBQb2xpY2llczogCisgICAgICAgICAgICAgICAgUG9saWN5OiAyLjE2Ljc1Ni4xLjg5LjEuMS4xLjEKKyAgICAgICAgICAgICAgICAgIENQUzogaHR0cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8KKworICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAwODo4NTphNjpmNToxNjowYzpmYzo0NDoxYTpjMTo2MzplMDpmOTo1NTo0NjowODpmYzo3MDoKKyAgICAgICAgMWM6NDI6Mjg6OTY6OGU6Yjc6YzU6YzE6NDE6NzU6NGU6MDk6NzE6Nzk6ZTU6NmQ6OTY6Y2E6CisgICAgICAgIDRiOmE1Ojg4OjYwOmQwOjMwOjc0OmI4OmNhOjA4OmRjOmI0OjMwOjllOjQwOjA3OjE2OjZiOgorICAgICAgICA2NTo5NTo3NzowMTphZTphNDpiNzozNTowYjo4MTpkYTo3MToxNTphOTo3NDoxNzozODo3YjoKKyAgICAgICAgNTg6Y2E6Zjk6MmY6ZmI6YzA6NjU6NzY6OGQ6NWI6MDE6Yjk6N2Q6ZGU6ODI6M2Q6NjQ6Yjg6CisgICAgICAgIGJlOjE0Ojc0OmEzOjBhOjU0OmQzOjJjOjk1OjE4OjE3OjM1OmY1OjUxOjZiOjNmOjhmOmEyOgorICAgICAgICA5Njo2MTozOTo3ODo2Yjo0YjplNTphNjphMDpmODo1MzpkZjo1MToxMDo5Mzo2MjplNzo4MDoKKyAgICAgICAgMmY6ZTI6ZDE6ZTA6YmM6OGU6MzY6NDY6Nzc6MzM6ZWM6Yjg6ZmI6OGU6OWE6MmM6ODk6NGQ6CisgICAgICAgIDMxOjExOjBmOjI2OjllOjA0OmJiOmI3OjA0OjhkOjBiOmYyOmI5OmZjOjVhOjlkOjNiOjE2OgorICAgICAgICBiNzoyZjpjODo5ODphYjpmZTo4YTo1MDo1OToyZTphMzozYjpmYzoyOTo1ZDo4YjpjMTo0YjoKKyAgICAgICAgYzk6ZTI6OGE6MTM6MWQ6YjE6YmY6YmI6NDI6MWQ6NTI6ZGQ6NGU6ZDg6MTQ6NWU6MTA6YzY6CisgICAgICAgIDMxOjA3OmVmOjcxOjI3OmY3OjFiOjM5OjA5OmRjOjgyOmVhOjhiOmIzOjk1Ojg2OjVlOmZkOgorICAgICAgICBmNTpkYTo1ZDozMTphNjplMDozMTpiNjo5NDplNjo0NDo0OTo3NDpjNToxNjplNTpmNzoxZjoKKyAgICAgICAgMDM6NjE6Mjg6YzU6Yzg6Y2I6MTI6YTA6NDI6NGI6Zjk6NmI6ODg6MDg6OGQ6YjQ6MzI6MTg6CisgICAgICAgIGYzOjc1OjlmOmM0OjdmOjAwOjRmOjA1Ojk1OjljOmEzOjE3OjAyOmMzOmIzOjUzOjliOmFhOgorICAgICAgICAyMDozOToyOToyYjo2NjpmYTo5ZDphZjo1ZTpiMzo5MjpkMjpiNTphNjplMToxYTpmOToyZDoKKyAgICAgICAgNDE6Njk6ODE6MTQ6YjQ6YjQ6YjU6ZWQ6ODk6M2Q6Y2U6ZmI6YTk6OWQ6MzU6NDI6NDQ6YjE6CisgICAgICAgIDFjOjE0OjczOjgxOmNmOjJhOjAxOjM1OjlhOjMxOmQ1OjJkOjhmOjZkOjg0OmRmOjgwOjRkOgorICAgICAgICA1NzplMzozZjpjNTo4NDo3NTpkYTo4OTpjNjozMDpiYjplYjo4ZjpjYjoyMjowODphMDphZToKKyAgICAgICAgYWE6ZjE6MDM6NmM6M2E6NGI6NGQ6MDk6YTU6MGU6NzI6YzY6NTY6NmI6MjE6NDI6NGU6MjM6CisgICAgICAgIDI1OjE0OjY4OmFlOjc2OjBhOjdjOjBjOjA3OjcwOjY0OmY5OjlhOjJmOmY2OjA1OjM5OjI2OgorICAgICAgICBjNjowYzo4ZjoxOTo3Zjo0Mzo1ZTo2ZTpmNDo1YjoxNToyZjpkYjo2MTo1ZDplNjo2NzoyZjoKKyAgICAgICAgM2Y6MDg6OTQ6Zjk6NjA6YjQ6OTg6MzE6ZGE6NzQ6ZjE6ODQ6OTM6NzE6NGQ6NWY6ZmI6NjA6CisgICAgICAgIDU4OmQxOmZiOmM0OmMxOjZkOjg5OmEyOmJiOjIwOjFmOjlkOjcxOjkxOmNiOjMyOjliOjEzOgorICAgICAgICAzZDozZTo3ZDo5Mjo1MjozNTphYzo5Mjo5NDphMjpkMzoxODpjMjo3YzpjNzplYTphZjo3NjoKKyAgICAgICAgMDU6MTY6ZGQ6Njc6Mjc6YzI6N2U6MWM6MDc6MjI6MjE6ZjM6NDA6MGE6MWI6MzQ6MDc6NDQ6CisgICAgICAgIDEzOmMyOjg0OjZhOjhlOmRmOjE5OjVhOmJmOjdmOmViOjFkOmUyOjFhOjM4OmQxOjVjOmFmOgorICAgICAgICA0Nzo5Mjo2Yjo4MDpiNTozMDphNTpjOTo4ZDpkODphYjozMTo4MToxZjpkZjpjMjo2NjozNzoKKyAgICAgICAgZDM6OTM6YTk6ODU6ODY6Nzk6NjU6ZDIKK1NIQTEgRmluZ2VycHJpbnQ9NTY6RTA6RkE6QzA6M0I6OEY6MTg6MjM6NTU6MTg6RTU6RDM6MTE6Q0E6RTg6QzI6NDM6MzE6QUI6NjYKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy80ODQ3ODczNC4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzQ4NDc4NzM0LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzkzMTFlZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy80ODQ3ODczNC4wCkBAIC0wLDAgKzEsNzYgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRGN6Q0NBbHVnQXdJQkFnSUJCREFOQmdrcWhraUc5dzBCQVFVRkFEQmtNUXN3Q1FZRFZRUUdFd0pMVWpFTgorTUFzR0ExVUVDZ3dFUzBsVFFURXVNQ3dHQTFVRUN3d2xTMjl5WldFZ1EyVnlkR2xtYVdOaGRHbHZiaUJCZFhSbworYjNKcGRIa2dRMlZ1ZEhKaGJERVdNQlFHQTFVRUF3d05TMGxUUVNCU2IyOTBRMEVnTVRBZUZ3MHdOVEE0TWpRdworT0RBMU5EWmFGdzB5TlRBNE1qUXdPREExTkRaYU1HUXhDekFKQmdOVkJBWVRBa3RTTVEwd0N3WURWUVFLREFSTAorU1ZOQk1TNHdMQVlEVlFRTERDVkxiM0psWVNCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlU0JEWlc1MAorY21Gc01SWXdGQVlEVlFRRERBMUxTVk5CSUZKdmIzUkRRU0F4TUlJQklEQU5CZ2txaGtpRzl3MEJBUUVGQUFPQworQVEwQU1JSUJDQUtDQVFFQXZBVGsraE01OERTV0lHdHNhTHY2MjNmL0ovZXM3Qy9uL2ZCL2JXK01LczBsQ1ZzaworOUtGby9DanN5U1hpck8zZXlET0U5YkNsQ1RxbnNVZEl4Y3hQakhtYytRWlhmZDN1T1BiUEZMS2M2dFBBWFhkaQorOEVjTnVScEFVMXhrY0s4SVdzRDN6M1g1Ykkxa0tCNGcvcmNiR2ROYVpvTnk0ckNidmRNbEZRMHliMlEzbElWRworeUhLK2Q5VnVIeWd2eDJudDU0T0pNMWpUM3FDL1FPaERVTzdjVFd1OHBlcW15R0dPOWNOa3J3WVYzQ21MUDNXTQordkhGRTIveXR0UmNkYlltRHo4WXp2YjlGb3Y0S242TVJYdys1SDV3YXdrYk1uQ2htbjNBbVBDN2Zxb0Qrak1VRQorQ1NWUHpaTkhQRGZxQW1lUy92d2lKRnlzMGl6Z1hBRXppc0VaMndJQkE2TXlNREF3SFFZRFZSME9CQllFRkwrMgorSjlnRFduWmxUR0VCUVZZeDVZdDdPdG5NTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFRgorQlFBRGdnRUJBQk92VVF2ZWltcGI1cG9LeUxHUVNrNmhBcDNNaU5LclpyMDk3THV4UXBWcXNseGEvNkZqWkphcAorYUJWL0pWNksrS1J6d1lDS2hRb09VdWd5NTBYNFRtV0FrWmwwUStWRm5Va3E4SlNWM2VuaE1OSVRic2xPc1hmbAorQk0rdFdoNlVDVnJYUEFnY3JucnBGRExCUmEzU0praHlyS2hCMnZBaGh6bGUzL3hrLzJGMEtwelptNHRmd2plVAorMktNM0x6dVRhN0liQjZkL0NWRHYwenErSVd1S2tEc25TbEZPYTU2Y2g1MzRlSkF4N1JFbnhxaFp2dndZQy91TworZmk1QzRlM25DU0c5dVJQRlZtZjBKcVpDUTVCRVZMUnhtM2JrR2hLc0dpZ0EzNXZCMWZqYlhLUDRrckc5dE5UNQorVU5rQUFrL2JnOUFSVDZSQ1ZtRTZmaE15MDRRZnlibz0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogNCAoMHg0KQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPUtSLCBPPUtJU0EsIE9VPUtvcmVhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IENlbnRyYWwsIENOPUtJU0EgUm9vdENBIDEKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEF1ZyAyNCAwODowNTo0NiAyMDA1IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogQXVnIDI0IDA4OjA1OjQ2IDIwMjUgR01UCisgICAgICAgIFN1YmplY3Q6IEM9S1IsIE89S0lTQSwgT1U9S29yZWEgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgQ2VudHJhbCwgQ049S0lTQSBSb290Q0EgMQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YmM6MDQ6ZTQ6ZmE6MTM6Mzk6ZjA6MzQ6OTY6MjA6NmI6NmM6Njg6YmI6CisgICAgICAgICAgICAgICAgICAgIGZhOmRiOjc3OmZmOjI3OmY3OmFjOmVjOjJmOmU3OmZkOmYwOjdmOjZkOjZmOgorICAgICAgICAgICAgICAgICAgICA4YzoyYTpjZDoyNTowOTo1YjoyNDpmNDphMTo2ODpmYzoyODplYzpjOToyNToKKyAgICAgICAgICAgICAgICAgICAgZTI6YWM6ZWQ6ZGU6Yzg6MzM6ODQ6ZjU6YjA6YTU6MDk6M2E6YTc6YjE6NDc6CisgICAgICAgICAgICAgICAgICAgIDQ4OmM1OmNjOjRmOjhjOjc5OjljOmY5OjA2OjU3OjdkOmRkOmVlOjM4OmY2OgorICAgICAgICAgICAgICAgICAgICBjZjoxNDpiMjo5YzplYTpkMzpjMDo1ZDo3Nzo2MjpmMDo0NzowZDpiOToxYToKKyAgICAgICAgICAgICAgICAgICAgNDA6NTM6NWM6NjQ6NzA6YWY6MDg6NWE6YzA6Zjc6Y2Y6NzU6Zjk6NmM6OGQ6CisgICAgICAgICAgICAgICAgICAgIDY0OjI4OjFlOjIwOmZlOmI3OjFiOjE5OmQzOjVhOjY2OjgzOjcyOmUyOmIwOgorICAgICAgICAgICAgICAgICAgICA5YjpiZDpkMzoyNToxNTowZDozMjo2Zjo2NDozNzo5NDo4NTo0NjpjODo3MjoKKyAgICAgICAgICAgICAgICAgICAgYmU6Nzc6ZDU6NmU6MWY6Mjg6MmY6Yzc6Njk6ZWQ6ZTc6ODM6ODk6MzM6NTg6CisgICAgICAgICAgICAgICAgICAgIGQzOmRlOmEwOmJmOjQwOmU4OjQzOjUwOmVlOmRjOjRkOjZiOmJjOmE1OmVhOgorICAgICAgICAgICAgICAgICAgICBhNjpjODo2MTo4ZTpmNTpjMzo2NDphZjowNjoxNTpkYzoyOTo4YjozZjo3NToKKyAgICAgICAgICAgICAgICAgICAgOGM6YmM6NzE6NDQ6ZGI6ZmM6YWQ6YjU6MTc6MWQ6NmQ6ODk6ODM6Y2Y6YzY6CisgICAgICAgICAgICAgICAgICAgIDMzOmJkOmJmOjQ1OmEyOmZlOjBhOjlmOmEzOjExOjVmOjBmOmI5OjFmOjljOgorICAgICAgICAgICAgICAgICAgICAxYTpjMjo0NjpjYzo5YzoyODo2Njo5Zjo3MDoyNjozYzoyZTpkZjphYTo4MDoKKyAgICAgICAgICAgICAgICAgICAgZmU6OGM6YzU6MDQ6MDk6MjU6NGY6Y2Q6OTM6NDc6M2M6Mzc6ZWE6MDI6Njc6CisgICAgICAgICAgICAgICAgICAgIDkyOmZlOmZjOjIyOjI0OjVjOmFjOmQyOjJjOmUwOjVjOjAxOjMzOjhhOmMxOgorICAgICAgICAgICAgICAgICAgICAxOTpkYgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiAzICgweDMpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEJGOkI2OjI3OkQ4OjAzOjVBOjc2OjY1OjRDOjYxOjAxOjQxOjU2OjMxOkU1OjhCOjdCOjNBOkQ5OkNDCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAxMzphZjo1MTowYjpkZTo4YTo2YTo1YjplNjo5YTowYTpjODpiMTo5MDo0YTo0ZTphMTowMjoKKyAgICAgICAgOWQ6Y2M6ODg6ZDI6YWI6NjY6YmQ6M2Q6ZWM6YmI6YjE6NDI6OTU6NmE6YjI6NWM6NWE6ZmY6CisgICAgICAgIGExOjYzOjY0Ojk2OmE5OjY4OjE1OjdmOjI1OjVlOjhhOmY4OmE0OjczOmMxOjgwOjhhOjg1OgorICAgICAgICAwYTowZTo1MjplODozMjplNzo0NTpmODo0ZTo2NTo4MDo5MTo5OTo3NDo0MzplNTo0NTo5ZDoKKyAgICAgICAgNDk6MmE6ZjA6OTQ6OTU6ZGQ6ZTk6ZTE6MzA6ZDI6MTM6NmU6Yzk6NGU6YjE6Nzc6ZTU6MDQ6CisgICAgICAgIGNmOmFkOjVhOjFlOjk0OjA5OjVhOmQ3OjNjOjA4OjFjOmFlOjdhOmU5OjE0OjMyOmMxOjQ1OgorICAgICAgICBhZDpkMjoyNjo0ODo3MjphYzphODo0MTpkYTpmMDoyMTo4NzozOTo1ZTpkZjpmYzo2NDpmZjoKKyAgICAgICAgNjE6NzQ6MmE6OWM6ZDk6OWI6OGI6NWY6YzI6Mzc6OTM6ZDg6YTM6Mzc6MmY6M2I6OTM6NmI6CisgICAgICAgIGIyOjFiOjA3OmE3OjdmOjA5OjUwOmVmOmQzOjNhOmJlOjIxOjZiOjhhOjkwOjNiOjI3OjRhOgorICAgICAgICA1MTo0ZTo2Yjo5ZTo5Yzo4Nzo5ZDpmODo3ODo5MDozMTplZDoxMToyNzpjNjphODo1OTpiZToKKyAgICAgICAgZmM6MTg6MGI6ZmI6OGU6N2U6MmU6NDI6ZTE6ZWQ6ZTc6MDk6MjE6YmQ6Yjk6MTM6YzU6NTY6CisgICAgICAgIDY3OmY0OjI2OmE2OjQyOjQzOjkwOjQ0OjU0OmI0OjcxOjliOjc2OmU0OjFhOjEyOmFjOjFhOgorICAgICAgICAyODowMDpkZjo5YjpjMTpkNTpmODpkYjo1YzphMzpmODo5MjpiMTpiZDpiNDpkNDpmOTo1MDoKKyAgICAgICAgZDk6MDA6MDI6NGY6ZGI6ODM6ZDA6MTE6NGY6YTQ6NDI6NTY6NjE6M2E6N2U6MTM6MzI6ZDM6CisgICAgICAgIDg0OjFmOmM5OmJhCitTSEExIEZpbmdlcnByaW50PTAyOjcyOjY4OjI5OjNFOjVGOjVEOjE3OkFBOkE0OkIzOkMzOkU2OjM2OjFFOjFGOjkyOjU3OjVFOkFBCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNGQ2NTRkMWQuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy80ZDY1NGQxZC4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiMjFiZWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNGQ2NTRkMWQuMApAQCAtMCwwICsxLDQ5IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUNXakNDQWNNQ0FnR2xNQTBHQ1NxR1NJYjNEUUVCQkFVQU1IVXhDekFKQmdOVkJBWVRBbFZUTVJnd0ZnWUQKK1ZRUUtFdzlIVkVVZ1EyOXljRzl5WVhScGIyNHhKekFsQmdOVkJBc1RIa2RVUlNCRGVXSmxjbFJ5ZFhOMElGTnYKK2JIVjBhVzl1Y3l3Z1NXNWpMakVqTUNFR0ExVUVBeE1hUjFSRklFTjVZbVZ5VkhKMWMzUWdSMnh2WW1Gc0lGSnYKK2IzUXdIaGNOT1Rnd09ERXpNREF5T1RBd1doY05NVGd3T0RFek1qTTFPVEF3V2pCMU1Rc3dDUVlEVlFRR0V3SlYKK1V6RVlNQllHQTFVRUNoTVBSMVJGSUVOdmNuQnZjbUYwYVc5dU1TY3dKUVlEVlFRTEV4NUhWRVVnUTNsaVpYSlUKK2NuVnpkQ0JUYjJ4MWRHbHZibk1zSUVsdVl5NHhJekFoQmdOVkJBTVRHa2RVUlNCRGVXSmxjbFJ5ZFhOMElFZHMKK2IySmhiQ0JTYjI5ME1JR2ZNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCaVFLQmdRQ1ZENkMyOEZDYzZIckgKK2lNM2RGdzR1c0pUUUd6ME85cFRBaXBUSEJzaVFsOGk0WkJwNmZtdzhVK0UzS0hOZ2Y3S1hVd2VmVS9sdFdKVFMKK3I0MXRpR2VBNXUyeWxjOXlNY3FsSEhLNlhBTG5aRUxuK2FrczFqb05ySTFDcWlRQk9lYWNQd0dGVncxWWgwWDQKKzA0V3FrMmttaFhCSWdEOFNGY2Q1dEI4Rkx6dGltUUlEQVFBQk1BMEdDU3FHU0liM0RRRUJCQVVBQTRHQkFHM3IKK0d3bnBYdGxSMjJjaVlhUXFQRWgzNDZCOHB0NXpvaFFEaFQzN3F3NHd4WU1XTTRFVENKNTdORTdmUU1oMDE3bDkKKzNQUjJWWDJiWTFRWTZmRHE4MXl4Mll0Q0hybkFsVTY2K3RYaWZQVm9ZYitPN0FXWFgxdXcxNk9GTk1Ra3B3MFAKK2xaUHZ5NVRZbmgrZFhJVnR4NnF1VHg4aXRjMlZyYnFuelBtckMzcC8KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDEgKDB4MCkKKyAgICAgICAgU2VyaWFsIE51bWJlcjogNDIxICgweDFhNSkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogbWQ1V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPUdURSBDb3Jwb3JhdGlvbiwgT1U9R1RFIEN5YmVyVHJ1c3QgU29sdXRpb25zLCBJbmMuLCBDTj1HVEUgQ3liZXJUcnVzdCBHbG9iYWwgUm9vdAorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogQXVnIDEzIDAwOjI5OjAwIDE5OTggR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBBdWcgMTMgMjM6NTk6MDAgMjAxOCBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgTz1HVEUgQ29ycG9yYXRpb24sIE9VPUdURSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLiwgQ049R1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJvb3QKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgxMDI0IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgxMDI0IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOjk1OjBmOmEwOmI2OmYwOjUwOjljOmU4OjdhOmM3Ojg4OmNkOmRkOjE3OgorICAgICAgICAgICAgICAgICAgICAwZToyZTpiMDo5NDpkMDoxYjozZDowZTpmNjo5NDpjMDo4YTo5NDpjNzowNjoKKyAgICAgICAgICAgICAgICAgICAgYzg6OTA6OTc6Yzg6Yjg6NjQ6MWE6N2E6N2U6NmM6M2M6NTM6ZTE6Mzc6Mjg6CisgICAgICAgICAgICAgICAgICAgIDczOjYwOjdmOmIyOjk3OjUzOjA3OjlmOjUzOmY5OjZkOjU4Ojk0OmQyOmFmOgorICAgICAgICAgICAgICAgICAgICA4ZDo2ZDo4ODo2Nzo4MDplNjplZDpiMjo5NTpjZjo3MjozMTpjYTphNToxYzoKKyAgICAgICAgICAgICAgICAgICAgNzI6YmE6NWM6MDI6ZTc6NjQ6NDI6ZTc6Zjk6YTk6MmM6ZDY6M2E6MGQ6YWM6CisgICAgICAgICAgICAgICAgICAgIDhkOjQyOmFhOjI0OjAxOjM5OmU2OjljOjNmOjAxOjg1OjU3OjBkOjU4Ojg3OgorICAgICAgICAgICAgICAgICAgICA0NTpmODpkMzo4NTphYTo5Mzo2OToyNjo4NTo3MDo0ODo4MDozZjoxMjoxNToKKyAgICAgICAgICAgICAgICAgICAgYzc6Nzk6YjQ6MWY6MDU6MmY6M2I6NjI6OTkKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogbWQ1V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgNmQ6ZWI6MWI6MDk6ZTk6NWU6ZDk6NTE6ZGI6Njc6MjI6NjE6YTQ6MmE6M2M6NDg6Nzc6ZTM6CisgICAgICAgIGEwOjdjOmE2OmRlOjczOmEyOjE0OjAzOjg1OjNkOmZiOmFiOjBlOjMwOmM1OjgzOjE2OjMzOgorICAgICAgICA4MToxMzowODo5ZTo3YjozNDo0ZTpkZjo0MDpjODo3NDpkNzpiOTo3ZDpkYzpmNDo3Njo1NToKKyAgICAgICAgN2Q6OWI6NjM6NTQ6MTg6ZTk6ZjA6ZWE6ZjM6NWM6YjE6ZDk6OGI6NDI6MWU6Yjk6YzA6OTU6CisgICAgICAgIDRlOmJhOmZhOmQ1OmUyOjdjOmY1OjY4OjYxOmJmOjhlOmVjOjA1Ojk3OjVmOjViOmIwOmQ3OgorICAgICAgICBhMzo4NTozNDpjNDoyNDphNzowZDowZjo5NTo5MzplZjpjYjo5NDpkODo5ZToxZjo5ZDo1YzoKKyAgICAgICAgODU6NmQ6Yzc6YWE6YWU6NGY6MWY6MjI6YjU6Y2Q6OTU6YWQ6YmE6YTc6Y2M6Zjk6YWI6MGI6CisgICAgICAgIDdhOjdmCitTSEExIEZpbmdlcnByaW50PTk3OjgxOjc5OjUwOkQ4OjFDOjk2OjcwOkNDOjM0OkQ4OjA5OkNGOjc5OjQ0OjMxOjM2OjdFOkY0Ojc0CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNGUxOGMxNDguMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy80ZTE4YzE0OC4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBiNDU4ODMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNGUxOGMxNDguMApAQCAtMCwwICsxLDc5IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSURuekNDQW9lZ0F3SUJBZ0lCSmpBTkJna3Foa2lHOXcwQkFRVUZBREJ4TVFzd0NRWURWUVFHRXdKRVJURWMKK01Cb0dBMVVFQ2hNVFJHVjFkSE5qYUdVZ1ZHVnNaV3R2YlNCQlJ6RWZNQjBHQTFVRUN4TVdWQzFVWld4bFUyVmoKK0lGUnlkWE4wSUVObGJuUmxjakVqTUNFR0ExVUVBeE1hUkdWMWRITmphR1VnVkdWc1pXdHZiU0JTYjI5MElFTkIKK0lESXdIaGNOT1Rrd056QTVNVEl4TVRBd1doY05NVGt3TnpBNU1qTTFPVEF3V2pCeE1Rc3dDUVlEVlFRR0V3SkUKK1JURWNNQm9HQTFVRUNoTVRSR1YxZEhOamFHVWdWR1ZzWld0dmJTQkJSekVmTUIwR0ExVUVDeE1XVkMxVVpXeGwKK1UyVmpJRlJ5ZFhOMElFTmxiblJsY2pFak1DRUdBMVVFQXhNYVJHVjFkSE5qYUdVZ1ZHVnNaV3R2YlNCU2IyOTAKK0lFTkJJREl3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3JDNk0xNElzcEZMRVUKK2hhODhFT1E1YnpWZFNxN2Q2bUdObFVuMGIyU2pHbUJtcEtsQUlvVFoxS1hsZUpNT2FBR3R1VTFjT3M3VHVLaEMKK1FOL1BvN3FDV1dxU0c2d2NtdG9JS3lVbitXa2pSL0hnNnl4Nm0vVVRBdEIrTkh6Q25qd0FXYXYxMmd6MU1qd3IKK3JGRGExc1BlZzVUS3FBeVpNZzRJU0ZaYmF2dmE0VmhZQVVsZmNrRThGUVlCamwydHFyaVR0TTJlNjZmb2FpMVMKK05OczY3MXgxVWRyYjh6SDU3bkdZTXNSVUZVUU0rWnRWN2EzZkdBaWdvNGFLU2U1VEJZOFpUTlhlV0htYjBtb2MKK1FxdkYxYWZQYUErVzVPRmhtSFpoeUpGODFqNEE0cEZRaCtHZEN1YXRsOUlkeGpwOXk3emFBelRWamxzQjlXb0gKK3R4YTJia3AvQWdNQkFBR2pRakJBTUIwR0ExVWREZ1FXQkJReHcza2J1dlZUMXhmZ2lYb3RGMndLc3l1ZE16QVAKK0JnTlZIUk1FQ0RBR0FRSC9BZ0VGTUE0R0ExVWREd0VCL3dRRUF3SUJCakFOQmdrcWhraUc5dzBCQVFVRkFBT0MKK0FRRUFsR1JaclRsazV5bnJFLzVhdzRzVFY4Z0VKUEIwZDhCZzQyZjc2WW1tZzcrV2dueHUxTU05NzU2QWJyc3AKK3RKaDZzVHRVNnprWFIzNGFqZ3Y4SHpGWk1RU3l6aGZ6TE1kaU5sWGlJdGlKVmJTWVNLcGsrdFljTnRoRWVGcGEKK0l6cFhsL1Y2TUUrdW4ycE1TeXVPb0FQalB1Q3AxTko3MHJPbzRuSThyWjcvZ0Zua20wVzA5anV3elRrWm1ETGwKKzZpRmhrT1F4SVk0MHNmY3ZOVXFGRU5ybmlqY2h2bGxqNFBLRmlERlQxRlFVaFhCNTlDNEdkeWQxTHgrNGl2bisKK3hicllOdVNEN09kbHQ3OWpXdk5HcjRHVU45UkJqTllqMWg3UDlXZ2JSR09pV3Jxbk5WbWg1WEFGbXc0alY1bVUKK0NtMjZPV01vaHBMekdJVFkrOUhQQlZaa1Z3PT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMzggKDB4MjYpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9REUsIE89RGV1dHNjaGUgVGVsZWtvbSBBRywgT1U9VC1UZWxlU2VjIFRydXN0IENlbnRlciwgQ049RGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEp1bCAgOSAxMjoxMTowMCAxOTk5IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogSnVsICA5IDIzOjU5OjAwIDIwMTkgR01UCisgICAgICAgIFN1YmplY3Q6IEM9REUsIE89RGV1dHNjaGUgVGVsZWtvbSBBRywgT1U9VC1UZWxlU2VjIFRydXN0IENlbnRlciwgQ049RGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmFiOjBiOmEzOjM1OmUwOjhiOjI5OjE0OmIxOjE0Ojg1OmFmOjNjOjEwOgorICAgICAgICAgICAgICAgICAgICBlNDozOTo2ZjozNTo1ZDo0YTphZTpkZDplYTo2MTo4ZDo5NTo0OTpmNDo2ZjoKKyAgICAgICAgICAgICAgICAgICAgNjQ6YTM6MWE6NjA6NjY6YTQ6YTk6NDA6MjI6ODQ6ZDk6ZDQ6YTU6ZTU6Nzg6CisgICAgICAgICAgICAgICAgICAgIDkzOjBlOjY4OjAxOmFkOmI5OjRkOjVjOjNhOmNlOmQzOmI4OmE4OjQyOjQwOgorICAgICAgICAgICAgICAgICAgICBkZjpjZjphMzpiYTo4Mjo1OTo2YTo5MjoxYjphYzoxYzo5YTpkYTowODoyYjoKKyAgICAgICAgICAgICAgICAgICAgMjU6Mjc6Zjk6Njk6MjM6NDc6ZjE6ZTA6ZWI6MmM6N2E6OWI6ZjU6MTM6MDI6CisgICAgICAgICAgICAgICAgICAgIGQwOjdlOjM0OjdjOmMyOjllOjNjOjAwOjU5OmFiOmY1OmRhOjBjOmY1OjMyOgorICAgICAgICAgICAgICAgICAgICAzYzoyYjphYzo1MDpkYTpkNjpjMzpkZTo4Mzo5NDpjYTphODowYzo5OTozMjoKKyAgICAgICAgICAgICAgICAgICAgMGU6MDg6NDg6NTY6NWI6NmE6ZmI6ZGE6ZTE6NTg6NTg6MDE6NDk6NWY6NzI6CisgICAgICAgICAgICAgICAgICAgIDQxOjNjOjE1OjA2OjAxOjhlOjVkOmFkOmFhOmI4OjkzOmI0OmNkOjllOmViOgorICAgICAgICAgICAgICAgICAgICBhNzplODo2YToyZDo1MjozNDpkYjozYTplZjo1Yzo3NTo1MTpkYTpkYjpmMzoKKyAgICAgICAgICAgICAgICAgICAgMzE6Zjk6ZWU6NzE6OTg6MzI6YzQ6NTQ6MTU6NDQ6MGM6Zjk6OWI6NTU6ZWQ6CisgICAgICAgICAgICAgICAgICAgIGFkOmRmOjE4OjA4OmEwOmEzOjg2OjhhOjQ5OmVlOjUzOjA1OjhmOjE5OjRjOgorICAgICAgICAgICAgICAgICAgICBkNTpkZTo1ODo3OTo5YjpkMjo2YToxYzo0MjphYjpjNTpkNTphNzpjZjo2ODoKKyAgICAgICAgICAgICAgICAgICAgMGY6OTY6ZTQ6ZTE6NjE6OTg6NzY6NjE6Yzg6OTE6N2M6ZDY6M2U6MDA6ZTI6CisgICAgICAgICAgICAgICAgICAgIDkxOjUwOjg3OmUxOjlkOjBhOmU2OmFkOjk3OmQyOjFkOmM2OjNhOjdkOmNiOgorICAgICAgICAgICAgICAgICAgICBiYzpkYTowMzozNDpkNTo4ZTo1YjowMTpmNTo2YTowNzpiNzoxNjpiNjo2ZToKKyAgICAgICAgICAgICAgICAgICAgNGE6N2YKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDMxOkMzOjc5OjFCOkJBOkY1OjUzOkQ3OjE3OkUwOjg5OjdBOjJEOjE3OjZDOjBBOkIzOjJCOjlEOjMzCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IAorICAgICAgICAgICAgICAgIENBOlRSVUUsIHBhdGhsZW46NQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA5NDo2NDo1OTphZDozOTo2NDplNzoyOTplYjoxMzpmZTo1YTpjMzo4YjoxMzo1NzpjODowNDoKKyAgICAgICAgMjQ6ZjA6NzQ6Nzc6YzA6NjA6ZTM6Njc6ZmI6ZTk6ODk6YTY6ODM6YmY6OTY6ODI6N2M6NmU6CisgICAgICAgIGQ0OmMzOjNkOmVmOjllOjgwOjZlOmJiOjI5OmI0Ojk4OjdhOmIxOjNiOjU0OmViOjM5OjE3OgorICAgICAgICA0Nzo3ZToxYTo4ZTowYjpmYzoxZjozMTo1OTozMTowNDpiMjpjZToxNzpmMzoyYzpjNzo2MjoKKyAgICAgICAgMzY6NTU6ZTI6MjI6ZDg6ODk6NTU6YjQ6OTg6NDg6YWE6NjQ6ZmE6ZDY6MWM6MzY6ZDg6NDQ6CisgICAgICAgIDc4OjVhOjVhOjIzOjNhOjU3Ojk3OmY1OjdhOjMwOjRmOmFlOjlmOjZhOjRjOjRiOjJiOjhlOgorICAgICAgICBhMDowMzplMzozZTplMDphOTpkNDpkMjo3YjpkMjpiMzphODplMjo3MjozYzphZDo5ZTpmZjoKKyAgICAgICAgODA6NTk6ZTQ6OWI6NDU6YjQ6ZjY6M2I6YjA6Y2Q6Mzk6MTk6OTg6MzI6ZTU6ZWE6MjE6NjE6CisgICAgICAgIDkwOmU0OjMxOjIxOjhlOjM0OmIxOmY3OjJmOjM1OjRhOjg1OjEwOmRhOmU3OjhhOjM3OjIxOgorICAgICAgICBiZTo1OTo2MzplMDpmMjo4NTo4ODozMTo1MzpkNDo1NDoxNDo4NTo3MDo3OTpmNDoyZTowNjoKKyAgICAgICAgNzc6Mjc6NzU6MmY6MWY6Yjg6OGE6Zjk6ZmU6YzU6YmE6ZDg6MzY6ZTQ6ODM6ZWM6ZTc6NjU6CisgICAgICAgIGI3OmJmOjYzOjVhOmYzOjQ2OmFmOjgxOjk0OjM3OmQ0OjQxOjhjOmQ2OjIzOmQ2OjFlOmNmOgorICAgICAgICBmNTo2ODoxYjo0NDo2MzphMjo1YTpiYTphNzozNTo1OTphMTplNTo3MDowNTo5YjowZToyMzoKKyAgICAgICAgNTc6OTk6OTQ6MGE6NmQ6YmE6Mzk6NjM6Mjg6ODY6OTI6ZjM6MTg6ODQ6ZDg6ZmI6ZDE6Y2Y6CisgICAgICAgIDA1OjU2OjY0OjU3CitTSEExIEZpbmdlcnByaW50PTg1OkE0OjA4OkMwOjlDOjE5OjNFOjVEOjUxOjU4OjdEOkNEOkQ2OjEzOjMwOkZEOjhDOkRFOjM3OkJGCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNGZiZDZiZmEuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy80ZmJkNmJmYS4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxMmY2MTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNGZiZDZiZmEuMApAQCAtMCwwICsxLDg5IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUVYakNDQTBhZ0F3SUJBZ0lRUkw0TWkxQUFJYlFSMHlwb0JxbXRhVEFOQmdrcWhraUc5dzBCQVFVRkFEQ0IKK2t6RUxNQWtHQTFVRUJoTUNWVk14Q3pBSkJnTlZCQWdUQWxWVU1SY3dGUVlEVlFRSEV3NVRZV3gwSUV4aGEyVWcKK1EybDBlVEVlTUJ3R0ExVUVDaE1WVkdobElGVlRSVkpVVWxWVFZDQk9aWFIzYjNKck1TRXdId1lEVlFRTEV4aG8KK2RIUndPaTh2ZDNkM0xuVnpaWEowY25WemRDNWpiMjB4R3pBWkJnTlZCQU1URWxWVVRpQXRJRVJCVkVGRGIzSncKK0lGTkhRekFlRncwNU9UQTJNalF4T0RVM01qRmFGdzB4T1RBMk1qUXhPVEEyTXpCYU1JR1RNUXN3Q1FZRFZRUUcKK0V3SlZVekVMTUFrR0ExVUVDQk1DVlZReEZ6QVZCZ05WQkFjVERsTmhiSFFnVEdGclpTQkRhWFI1TVI0d0hBWUQKK1ZRUUtFeFZVYUdVZ1ZWTkZVbFJTVlZOVUlFNWxkSGR2Y21zeElUQWZCZ05WQkFzVEdHaDBkSEE2THk5M2QzY3UKK2RYTmxjblJ5ZFhOMExtTnZiVEViTUJrR0ExVUVBeE1TVlZST0lDMGdSRUZVUVVOdmNuQWdVMGRETUlJQklqQU4KK0Jna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTMrNVlFS0lyYmxYRWpyOHVSZ25uNEFnUExpdDYKK0U1UWJ2ZmEyZ0k1bEJaTUFIcnl2NGcrT0dRMFNSK3lzcmFQNkxuRDQzbTc3VmtJVm5pNWM3eVBlSWJrRmRpY1oKK0QwL1d3NXkwdnBRWlkvS21FUXJyVTBpY3Z2SXBPeGJvR3FCTXBzbjBHRmxvd0hEeVV3REFYbENDcFZadk52bEsKKzRFU0dvRTFPMWtkdVNVckxaOWVteEFXNWpoNzAvUC9ONXpiZ25BVnNzak1pRmRDMDRNd1h3TExBOVA0eVB5a3EKK2xYdlk4cWRPRDFSOG9RMkFzd2tEd2Y5YzNWNmFQcnl1dkVlS2FxNXh5aCt4S3JoZlFnVUw3RVl3MFhJTHl1bFcKK2JmWHYzM2krWWJxeXBhNEVUTHlvckdrVmw3M3Y2N1NNdnpYNDFNUFJLQTVjT3A5d0dETWdkOFNpcndJREFRQUIKK280R3JNSUdvTUFzR0ExVWREd1FFQXdJQnhqQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01CMEdBMVVkRGdRV0JCUlQKK010R3p6My82NFBHZ1hZVk9rdEtlUlIyMFR6QTlCZ05WSFI4RU5qQTBNREtnTUtBdWhpeG9kSFJ3T2k4dlkzSnMKK0xuVnpaWEowY25WemRDNWpiMjB2VlZST0xVUkJWRUZEYjNKd1UwZERMbU55YkRBcUJnTlZIU1VFSXpBaEJnZ3IKK0JnRUZCUWNEQVFZS0t3WUJCQUdDTndvREF3WUpZSVpJQVliNFFnUUJNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUIKK0FRQW5OWmNBaW9zb3ZjWXpNQjRwL09MMzFaalVRTHRneXIrckZ5d0pObjlRK2tIY3JwWTZDaU0raVZuSm93ZnQKK0d6ZXQvSHkrVVVsYTNqb0tWQWdXUmNLWnNZZk5qR2pnYVFQcHhFNllzanVNRnJNT29BeVlVSnVUcVhBSnlDeWoKK2o5OEM1T0J4T3ZHMEkzS2dxZ0hmMzVnK0ZGQ2dNU2E5S09sYU1DWjErWHRnSEkzenpWQW1iUVFubXQvVkRVVkgKK0tXc3M1bmJacVNsOU10M0pOank5cmpYeEVaNGR1NUEvRWtkT2p0ZCtEMkp6SFZJbU9Cd1lTZjB3ZEpyRTVTSXYKKzJNQ043WkY2VEFDUGNuOWQydDBiaTBWcjU5MXBsNmpGVmt3UERQYWZlcEUzOXBlQzROMXhhZjkyUDJCTlBNLzMKK21mbkdWL1RKVlRsNHVpeDV5YWFJSy9RSQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgNDQ6YmU6MGM6OGI6NTA6MDA6MjE6YjQ6MTE6ZDM6MmE6Njg6MDY6YTk6YWQ6NjkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgU1Q9VVQsIEw9U2FsdCBMYWtlIENpdHksIE89VGhlIFVTRVJUUlVTVCBOZXR3b3JrLCBPVT1odHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20sIENOPVVUTiAtIERBVEFDb3JwIFNHQworICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogSnVuIDI0IDE4OjU3OjIxIDE5OTkgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBKdW4gMjQgMTk6MDY6MzAgMjAxOSBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgU1Q9VVQsIEw9U2FsdCBMYWtlIENpdHksIE89VGhlIFVTRVJUUlVTVCBOZXR3b3JrLCBPVT1odHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20sIENOPVVUTiAtIERBVEFDb3JwIFNHQworICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6ZGY6ZWU6NTg6MTA6YTI6MmI6NmU6NTU6YzQ6OGU6YmY6MmU6NDY6MDk6CisgICAgICAgICAgICAgICAgICAgIGU3OmUwOjA4OjBmOjJlOjJiOjdhOjEzOjk0OjFiOmJkOmY2OmI2OjgwOjhlOgorICAgICAgICAgICAgICAgICAgICA2NTowNTo5MzowMDoxZTpiYzphZjplMjowZjo4ZToxOTowZDoxMjo0NzplYzoKKyAgICAgICAgICAgICAgICAgICAgYWM6YWQ6YTM6ZmE6MmU6NzA6Zjg6ZGU6NmU6ZmI6NTY6NDI6MTU6OWU6MmU6CisgICAgICAgICAgICAgICAgICAgIDVjOmVmOjIzOmRlOjIxOmI5OjA1Ojc2OjI3OjE5OjBmOjRmOmQ2OmMzOjljOgorICAgICAgICAgICAgICAgICAgICBiNDpiZTo5NDoxOTo2MzpmMjphNjoxMTowYTplYjo1Mzo0ODo5YzpiZTpmMjoKKyAgICAgICAgICAgICAgICAgICAgMjk6M2I6MTY6ZTg6MWE6YTA6NGM6YTY6Yzk6ZjQ6MTg6NTk6Njg6YzA6NzA6CisgICAgICAgICAgICAgICAgICAgIGYyOjUzOjAwOmMwOjVlOjUwOjgyOmE1OjU2OjZmOjM2OmY5OjRhOmUwOjQ0OgorICAgICAgICAgICAgICAgICAgICA4NjphMDo0ZDo0ZTpkNjo0Nzo2ZTo0OTo0YTpjYjo2NzpkNzphNjpjNDowNToKKyAgICAgICAgICAgICAgICAgICAgYjk6OGU6MWU6ZjQ6ZmM6ZmY6Y2Q6ZTc6MzY6ZTA6OWM6MDU6NmM6YjI6MzM6CisgICAgICAgICAgICAgICAgICAgIDIyOjE1OmQwOmI0OmUwOmNjOjE3OmMwOmIyOmMwOmY0OmZlOjMyOjNmOjI5OgorICAgICAgICAgICAgICAgICAgICAyYTo5NTo3YjpkODpmMjphNzo0ZTowZjo1NDo3YzphMTowZDo4MDpiMzowOToKKyAgICAgICAgICAgICAgICAgICAgMDM6YzE6ZmY6NWM6ZGQ6NWU6OWE6M2U6YmM6YWU6YmM6NDc6OGE6NmE6YWU6CisgICAgICAgICAgICAgICAgICAgIDcxOmNhOjFmOmIxOjJhOmI4OjVmOjQyOjA1OjBiOmVjOjQ2OjMwOmQxOjcyOgorICAgICAgICAgICAgICAgICAgICAwYjpjYTplOTo1Njo2ZDpmNTplZjpkZjo3ODpiZTo2MTpiYTpiMjphNTphZToKKyAgICAgICAgICAgICAgICAgICAgMDQ6NGM6YmM6YTg6YWM6Njk6MTU6OTc6YmQ6ZWY6ZWI6YjQ6OGM6YmY6MzU6CisgICAgICAgICAgICAgICAgICAgIGY4OmQ0OmMzOmQxOjI4OjBlOjVjOjNhOjlmOjcwOjE4OjMzOjIwOjc3OmM0OgorICAgICAgICAgICAgICAgICAgICBhMjphZgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiAKKyAgICAgICAgICAgICAgICBEaWdpdGFsIFNpZ25hdHVyZSwgTm9uIFJlcHVkaWF0aW9uLCBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICA1MzozMjpEMTpCMzpDRjo3RjpGQTpFMDpGMTpBMDo1RDo4NTo0RTo5MjpEMjo5RTo0NToxRDpCNDo0RgorICAgICAgICAgICAgWDUwOXYzIENSTCBEaXN0cmlidXRpb24gUG9pbnRzOiAKKyAgICAgICAgICAgICAgICBVUkk6aHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1EQVRBQ29ycFNHQy5jcmwKKworICAgICAgICAgICAgWDUwOXYzIEV4dGVuZGVkIEtleSBVc2FnZTogCisgICAgICAgICAgICAgICAgVExTIFdlYiBTZXJ2ZXIgQXV0aGVudGljYXRpb24sIE1pY3Jvc29mdCBTZXJ2ZXIgR2F0ZWQgQ3J5cHRvLCBOZXRzY2FwZSBTZXJ2ZXIgR2F0ZWQgQ3J5cHRvCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDI3OjM1Ojk3OjAwOjhhOjhiOjI4OmJkOmM2OjMzOjMwOjFlOjI5OmZjOmUyOmY3OmQ1Ojk4OgorICAgICAgICBkNDo0MDpiYjo2MDpjYTpiZjphYjoxNzoyYzowOTozNjo3Zjo1MDpmYTo0MTpkYzphZTo5NjoKKyAgICAgICAgM2E6MGE6MjM6M2U6ODk6NTk6Yzk6YTM6MDc6ZWQ6MWI6Mzc6YWQ6ZmM6N2M6YmU6NTE6NDk6CisgICAgICAgIDVhOmRlOjNhOjBhOjU0OjA4OjE2OjQ1OmMyOjk5OmIxOjg3OmNkOjhjOjY4OmUwOjY5OjAzOgorICAgICAgICBlOTpjNDo0ZTo5ODpiMjozYjo4YzoxNjpiMzowZTphMDowYzo5ODo1MDo5Yjo5MzphOTo3MDoKKyAgICAgICAgMDk6Yzg6MmM6YTM6OGY6ZGY6MDI6ZTQ6ZTA6NzE6M2E6ZjE6YjQ6MjM6NzI6YTA6YWE6MDE6CisgICAgICAgIGRmOmRmOjk4OjNlOjE0OjUwOmEwOjMxOjI2OmJkOjI4OmU5OjVhOjMwOjI2Ojc1OmY5OjdiOgorICAgICAgICA2MDoxYzo4ZDpmMzpjZDo1MDoyNjo2ZDowNDoyNzo5YTpkZjpkNTowZDo0NTo0NzoyOTo2YjoKKyAgICAgICAgMmM6ZTY6NzY6ZDk6YTk6Mjk6N2Q6MzI6ZGQ6Yzk6MzY6M2M6YmQ6YWU6MzU6ZjE6MTE6OWU6CisgICAgICAgIDFkOmJiOjkwOjNmOjEyOjQ3OjRlOjhlOmQ3OjdlOjBmOjYyOjczOjFkOjUyOjI2OjM4OjFjOgorICAgICAgICAxODo0OTpmZDozMDo3NDo5YTpjNDplNToyMjoyZjpkODpjMDo4ZDplZDo5MTo3YTo0YzowMDoKKyAgICAgICAgOGY6NzI6N2Y6NWQ6ZGE6ZGQ6MWI6OGI6NDU6NmI6ZTc6ZGQ6Njk6OTc6YTg6YzU6NTY6NGM6CisgICAgICAgIDBmOjBjOmY2OjlmOjdhOjkxOjM3OmY2Ojk3OjgyOmUwOmRkOjcxOjY5OmZmOjc2OjNmOjYwOgorICAgICAgICA0ZDozYzpjZjpmNzo5OTpmOTpjNjo1NzpmNDpjOTo1NTozOTo3ODpiYToyYzo3OTpjOTphNjoKKyAgICAgICAgODg6MmI6ZjQ6MDgKK1NIQTEgRmluZ2VycHJpbnQ9NTg6MTE6OUY6MEU6MTI6ODI6ODc6RUE6NTA6RkQ6RDk6ODc6NDU6NkY6NEY6Nzg6REM6RkE6RDY6RDQKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy81MDIxYTBhMi4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzUwMjFhMGEyLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzY1YzAyMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy81MDIxYTBhMi4wCkBAIC0wLDAgKzEsODQgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRDNUQ0NBc1dnQXdJQkFnSU9IYUlBQVFBQzdMZGdnSGlOdGdZd0RRWUpLb1pJaHZjTkFRRUZCUUF3ZVRFTAorTUFrR0ExVUVCaE1DUkVVeEhEQWFCZ05WQkFvVEUxUkRJRlJ5ZFhOMFEyVnVkR1Z5SUVkdFlrZ3hKREFpQmdOVgorQkFzVEcxUkRJRlJ5ZFhOMFEyVnVkR1Z5SUZWdWFYWmxjbk5oYkNCRFFURW1NQ1FHQTFVRUF4TWRWRU1nVkhKMQorYzNSRFpXNTBaWElnVlc1cGRtVnljMkZzSUVOQklFa3dIaGNOTURZd016SXlNVFUxTkRJNFdoY05NalV4TWpNeAorTWpJMU9UVTVXakI1TVFzd0NRWURWUVFHRXdKRVJURWNNQm9HQTFVRUNoTVRWRU1nVkhKMWMzUkRaVzUwWlhJZworUjIxaVNERWtNQ0lHQTFVRUN4TWJWRU1nVkhKMWMzUkRaVzUwWlhJZ1ZXNXBkbVZ5YzJGc0lFTkJNU1l3SkFZRAorVlFRREV4MVVReUJVY25WemRFTmxiblJsY2lCVmJtbDJaWEp6WVd3Z1EwRWdTVENDQVNJd0RRWUpLb1pJaHZjTgorQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUtSM0k1WkVyNUQwTWFjUTlDYUhuUE00MlE5ZTNzOUI2REd0eG5TUgorSkpaNEhnbWdtNXFWU2tyMVlud0NxTXFzKzFvRWRqbmVYL0g1czcvekExaFYwcXEzNHdRaTBmaVUyaUlJQUkzVAorZkNaZHpIZDU1eXg0T2FnbWN3NmlYU1ZwaFU5VkRwcnZ4cmxFNFZjOTN4OVVJdVZ2WmFvemhEcnp6bnErVlpldQoralJJUEZEUGlVSEREU1ljVHZGSGUxNWdTV3U4Nmd6T1NCbldMa253U2FIdHdhZysxbTdaM1cwaFpuZVR2V3Ezegord1o3VTEwVk95bFkwSWJ3K0YxdHZkd3hJQVVNcHNOMC9sbTdtbGFvTXdDQzIvVDQySjV6alhNOU9nZHdadTVHUQorZmV6bWx3UWVrOHdpU2RlWGhyWVRDanhESTNkKzhOem16U1FmTzRPYk5EcUROT01DQXdFQUFhTmpNR0V3SHdZRAorVlIwakJCZ3dGb0FVa3FSMUxLU2V2b0ZFNjNuOGlzV1ZwZXNRZFhNd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBTworQmdOVkhROEJBZjhFQkFNQ0FZWXdIUVlEVlIwT0JCWUVGSktrZFN5a25yNkJST3Q1L0lyRmxhWHJFSFZ6TUEwRworQ1NxR1NJYjNEUUVCQlFVQUE0SUJBUUFvMHVDRzFlYjRlL0NYM0NKck81VVVWZzhSTUtXYVR6cXdPdUFHeTJYMQorN2NhWEovNGw4bGZtWHBXTVBtUmdGVnAvTHcwQnhiRmcvVVUxei9DeXZ3Ylo3MXErczJJaHROZXJOWHhUUHFZbgorOGFFdDJob2puY3pkN0R3dG5pYzBYUS9DTm5tOHlVcGlMZTFyMlgxQlEzeTJxc3J0WWJFM2doVUpHb29XTU5qcworeWRaSGNuaExFRVlVamw4T3IrekhMNnNRMTdieGJ1eUdzc0xvRFpKejNLTDBEenEvWVNNUWlaeElRRzV3QUxQVAordWpkRVdCRjZBbXFJOERjMDhCbnByTlJsYy9acGpHU1VPbm1GS2JBV0t3eUNQd2FjeC8wUUs1NFBMTGFlNHhXLworMlRZY3VpVWFVajBhN0NJTUhPQ2tvajN3NkRuUGdjQjc3VjBmYjhYUUM5ZVkKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDFkOmEyOjAwOjAxOjAwOjAyOmVjOmI3OjYwOjgwOjc4OjhkOmI2OjA2CisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9REUsIE89VEMgVHJ1c3RDZW50ZXIgR21iSCwgT1U9VEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBLCBDTj1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTWFyIDIyIDE1OjU0OjI4IDIwMDYgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBEZWMgMzEgMjI6NTk6NTkgMjAyNSBHTVQKKyAgICAgICAgU3ViamVjdDogQz1ERSwgTz1UQyBUcnVzdENlbnRlciBHbWJILCBPVT1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EsIENOPVRDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDphNDo3NzoyMzo5Njo0NDphZjo5MDpmNDozMTphNzoxMDpmNDoyNjo4NzoKKyAgICAgICAgICAgICAgICAgICAgOWM6ZjM6Mzg6ZDk6MGY6NWU6ZGU6Y2Y6NDE6ZTg6MzE6YWQ6YzY6NzQ6OTE6CisgICAgICAgICAgICAgICAgICAgIDI0Ojk2Ojc4OjFlOjA5OmEwOjliOjlhOjk1OjRhOjRhOmY1OjYyOjdjOjAyOgorICAgICAgICAgICAgICAgICAgICBhODpjYTphYzpmYjo1YTowNDo3NjozOTpkZTo1ZjpmMTpmOTpiMzpiZjpmMzoKKyAgICAgICAgICAgICAgICAgICAgMDM6NTg6NTU6ZDI6YWE6Yjc6ZTM6MDQ6MjI6ZDE6Zjg6OTQ6ZGE6MjI6MDg6CisgICAgICAgICAgICAgICAgICAgIDAwOjhkOmQzOjdjOjI2OjVkOmNjOjc3Ojc5OmU3OjJjOjc4OjM5OmE4OjI2OgorICAgICAgICAgICAgICAgICAgICA3MzowZTphMjo1ZDoyNTo2OTo4NTo0Zjo1NTowZTo5YTplZjpjNjpiOTo0NDoKKyAgICAgICAgICAgICAgICAgICAgZTE6NTc6M2Q6ZGY6MWY6NTQ6MjI6ZTU6NmY6NjU6YWE6MzM6ODQ6M2E6ZjM6CisgICAgICAgICAgICAgICAgICAgIGNlOjdhOmJlOjU1Ojk3OmFlOjhkOjEyOjBmOjE0OjMzOmUyOjUwOjcwOmMzOgorICAgICAgICAgICAgICAgICAgICA0OTo4NzoxMzpiYzo1MTpkZTpkNzo5ODoxMjo1YTplZjozYTo4MzozMzo5MjoKKyAgICAgICAgICAgICAgICAgICAgMDY6NzU6OGI6OTI6N2M6MTI6Njg6N2I6NzA6NmE6MGY6YjU6OWI6YjY6Nzc6CisgICAgICAgICAgICAgICAgICAgIDViOjQ4OjU5OjlkOmU0OmVmOjVhOmFkOmYzOmMxOjllOmQ0OmQ3OjQ1OjRlOgorICAgICAgICAgICAgICAgICAgICBjYTo1NjozNDoyMTpiYzozZToxNzo1Yjo2Zjo3NzowYzo0ODowMTo0MzoyOToKKyAgICAgICAgICAgICAgICAgICAgYjA6ZGQ6M2Y6OTY6NmU6ZTY6OTU6YWE6MGM6YzA6MjA6YjY6ZmQ6M2U6MzY6CisgICAgICAgICAgICAgICAgICAgIDI3OjljOmUzOjVjOmNmOjRlOjgxOmRjOjE5OmJiOjkxOjkwOjdkOmVjOmU2OgorICAgICAgICAgICAgICAgICAgICA5NzowNDoxZTo5MzpjYzoyMjo0OTpkNzo5Nzo4NjpiNjoxMzowYTozYzo0MzoKKyAgICAgICAgICAgICAgICAgICAgMjM6Nzc6N2U6ZjA6ZGM6ZTY6Y2Q6MjQ6MWY6M2I6ODM6OWI6MzQ6M2E6ODM6CisgICAgICAgICAgICAgICAgICAgIDM0OmUzCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOjkyOkE0Ojc1OjJDOkE0OjlFOkJFOjgxOjQ0OkVCOjc5OkZDOjhBOkM1Ojk1OkE1OkVCOjEwOjc1OjczCisKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIERpZ2l0YWwgU2lnbmF0dXJlLCBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDkyOkE0Ojc1OjJDOkE0OjlFOkJFOjgxOjQ0OkVCOjc5OkZDOjhBOkM1Ojk1OkE1OkVCOjEwOjc1OjczCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDI4OmQyOmUwOjg2OmQ1OmU2OmY4OjdiOmYwOjk3OmRjOjIyOjZiOjNiOjk1OjE0OjU2OjBmOgorICAgICAgICAxMTozMDphNTo5YTo0ZjozYTpiMDozYTplMDowNjpjYjo2NTpmNTplZDpjNjo5NzoyNzpmZToKKyAgICAgICAgMjU6ZjI6NTc6ZTY6NWU6OTU6OGM6M2U6NjQ6NjA6MTU6NWE6N2Y6MmY6MGQ6MDE6YzU6YjE6CisgICAgICAgIDYwOmZkOjQ1OjM1OmNmOmYwOmIyOmJmOjA2OmQ5OmVmOjVhOmJlOmIzOjYyOjIxOmI0OmQ3OgorICAgICAgICBhYjozNTo3Yzo1MzozZTphNjoyNzpmMTphMToyZDpkYToxYToyMzo5ZDpjYzpkZDplYzozYzoKKyAgICAgICAgMmQ6OWU6Mjc6MzQ6NWQ6MGY6YzI6MzY6Nzk6YmM6Yzk6NGE6NjI6MmQ6ZWQ6NmI6ZDk6N2Q6CisgICAgICAgIDQxOjQzOjdjOmI2OmFhOmNhOmVkOjYxOmIxOjM3OjgyOjE1OjA5OjFhOjhhOjE2OjMwOmQ4OgorICAgICAgICBlYzpjOTpkNjo0Nzo3Mjo3ODo0YjoxMDo0NjoxNDo4ZTo1ZjowZTphZjplYzpjNzoyZjphYjoKKyAgICAgICAgMTA6ZDc6YjY6ZjE6NmU6ZWM6ODY6YjI6YzI6ZTg6MGQ6OTI6NzM6ZGM6YTI6ZjQ6MGY6M2E6CisgICAgICAgIGJmOjYxOjIzOjEwOjg5OjljOjQ4OjQwOjZlOjcwOjAwOmIzOmQzOmJhOjM3OjQ0OjU4OjExOgorICAgICAgICA3YTowMjo2YTo4ODpmMDozNzozNDpmMDoxOTplOTphYzpkNDo2NTo3MzpmNjo2OTo4Yzo2NDoKKyAgICAgICAgOTQ6M2E6Nzk6ODU6Mjk6YjA6MTY6MmI6MGM6ODI6M2Y6MDY6OWM6Yzc6ZmQ6MTA6MmI6OWU6CisgICAgICAgIDBmOjJjOmI2OjllOmUzOjE1OmJmOmQ5OjM2OjFjOmJhOjI1OjFhOjUyOjNkOjFhOmVjOjIyOgorICAgICAgICAwYzoxYzplMDphNDphMjozZDpmMDplODozOTpjZjo4MTpjMDo3YjplZDo1ZDoxZjo2ZjpjNToKKyAgICAgICAgZDA6MGI6ZDc6OTgKK1NIQTEgRmluZ2VycHJpbnQ9NkI6MkY6MzQ6QUQ6ODk6NTg6QkU6NjI6RkQ6QjA6NkI6NUM6Q0U6QkI6OUQ6RDk6NEY6NEU6Mzk6RjMKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy81MDQ2YzM1NS4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzUwNDZjMzU1LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDMxOTNiOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy81MDQ2YzM1NS4wCkBAIC0wLDAgKzEsMTI5IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUZ2VENDQTZXZ0F3SUJBZ0lJVHh2VUwxUzdMMHN3RFFZSktvWklodmNOQVFFRkJRQXdSekVMTUFrR0ExVUUKK0JoTUNRMGd4RlRBVEJnTlZCQW9UREZOM2FYTnpVMmxuYmlCQlJ6RWhNQjhHQTFVRUF4TVlVM2RwYzNOVGFXZHUKK0lGTnBiSFpsY2lCRFFTQXRJRWN5TUI0WERUQTJNVEF5TlRBNE16STBObG9YRFRNMk1UQXlOVEE0TXpJME5sb3cKK1J6RUxNQWtHQTFVRUJoTUNRMGd4RlRBVEJnTlZCQW9UREZOM2FYTnpVMmxuYmlCQlJ6RWhNQjhHQTFVRUF4TVkKK1UzZHBjM05UYVdkdUlGTnBiSFpsY2lCRFFTQXRJRWN5TUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEEKK01JSUNDZ0tDQWdFQXhQR0hmOU40TWZjNHlmakRtVU84eC9lOE4rZE9jYnBMajZWekhWeHVtSzREVjY0NE4wTXYKK0Z6MGZ5TTVvRU1GNHJoa0RLeEQ2TEhtRDl1aTVhTGxWOGdSRXB6bjUvQVNMSHZHaVRTZjVZWHU2dCtXaUU3YnIKK1lUN1FiTkhtKy9wZTdSMjBucUExVzZHU3kvQkprdjZGQ2dVKzV0a0w0ays3M0pVMy9KSHBNalVpMFI4NlRpZUYKK25iQVZsRExhWVExSFRXQkNycEpINklOYVVGanBpb3U1WGFIYzNabEtIelpudTBqa2c3WTM2MGc2cnc5bmp4Y0gKKzZBVEs3Mm94aDlUQXR2bVVjWHRuWkxpMmtVcENlMlV1TUdvTTlaRHVsZWJ5ellMczJhRks3UGF5UytWRmhlWnQKK2VKTUVMcHlDYlRhcHhERmtINGFEQ3lyME5RcDR5VlhQUWJCSDZUQ2ZtYjVocUFhRXVTaDZYempaRzZrNHNJTi8KK2M4SERPMGdxZ2c4aG03ak1xRFhEaEJ1RHN6NitwSlZwQVRxSkFIZ0UyY24wbVJtclZuNWJpNFk1RlpHa0VDd0oKK01vQmdzNVBBS3JZWUM1MStqVW55RUVwLytkVkdMeG1TbzVtbkpxeTdqRHptRHJ4SEI5eHpVZkZ3WkM4SStiUkgKK0hUQnNST29wTjRXU2FHYThnemorZXprdTAxRHdIL3RlWUxhcHB2b25RZkdiR0hMeTlZUjBTc2xueEZTdVNHVGYKK2pORnVzQjNoQjQ4SUhwbWNjZWxNMktYM1J4SWZkTkZSbm9iendxSWpRQXR6MjB1bTUzTUdqTUdnNmNGWnJFYjYKKzVpLzR6M0djUm0yNXhCV05PSGtEUlVqdnhGM1hDTzZIT1NLR3NnMFBXRVAzY2FsSUx2M3ExaDhDQXdFQUFhT0IKK3JEQ0JxVEFPQmdOVkhROEJBZjhFQkFNQ0FRWXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVUKK0Y2RE53ZVJCdGpwYk84dEZuYjBjd3BqNmhsZ3dId1lEVlIwakJCZ3dGb0FVRjZETndlUkJ0anBiTzh0Rm5iMGMKK3dwajZobGd3UmdZRFZSMGdCRDh3UFRBN0JnbGdoWFFCV1FFREFRRXdMakFzQmdnckJnRUZCUWNDQVJZZ2FIUjAKK2NEb3ZMM0psY0c5emFYUnZjbmt1YzNkcGMzTnphV2R1TG1OdmJTOHdEUVlKS29aSWh2Y05BUUVGQlFBRGdnSUIKK0FIUEdnZUFuMGkwUDRKVXc0cHBCZjFBc1gxOWlZYW1HYW1rWURIUkoxbDJFNmtGU0dHOVlyVkJXSUdyR3ZTaHAKK1dKSGNrUkUxcVRvZHZCcWxZSjdZSDM5RmtXblpmcnQ0Y3NFR0R5ck9qNFZ3WWF5Z3pRdTRPU2xXaERKT2hyczkKK3hDcloxeDl5N3Y1Um9TSkJzWEVDWXhxQ3NHS3JYbGNTSDkvTDNYV2d3RjE1a0l3YjRGRG0zakgrbUh0d1g2V1EKKzJLMzRBclp2MDJEZFFFc2l4VDJ0T25xZkdocEhrWGt6dW9MY01ta0RsbTRmUy9CeC91Tm5jcUN4djF5TDVQcVoKK0lzZUV1UnVOSTVjLzdTWGd6Mlc3OVdFRTc5MGVzbHBCSWxxaG4xMHM2RnZKYmFrTURIaXFZTVpXandGYURHaTgKK2FSbDV4QjkrbHdXL3hla2tVVjdVMVV0VDdka2pXallEWmFQQkE2MUJNUE5HRzRXUXIyVzExYkhrRmx0NGRSMlgKK2VtMVpxU3FQZTk3RGg0a1FtVWx6ZU1nOXZWRTFkQ3JWOFg1cEd5cTdPNzBsdUpwYVBYSmhrR2FIN2d6V1RkUVIKK2RBdHEvZ3NEL0tOVlY0bitTc3V1V3hjRnlQS05JekZUT05JdGFqK0N1WTBJYXZkZVFYUnV3eEYrQjZ3cFlKRS8KK09NcFhFQTI5TUMvSHBlWkJvTnF1QlllYW9LUmxiRXdKREltNnVOTzV3Sk9LTVBxTjVacHJGUUZPWjZyYVlsWSsKK2hBaG0wc1EyZmFjK0VQeUk0TlNBNVFDOXF2Tk9CcU42YXZsaWN1TUpUK3ViRGdFajhaKzdmTnpjYkJHWEpiTHkKK3RHTVUwZ1lxWjR5RDljN3FCOWlhYWg3czVBcTdLa3pyQ1dBNXpzcGkyQzV1CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICA0ZjoxYjpkNDoyZjo1NDpiYjoyZjo0YgorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPUNILCBPPVN3aXNzU2lnbiBBRywgQ049U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBPY3QgMjUgMDg6MzI6NDYgMjAwNiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IE9jdCAyNSAwODozMjo0NiAyMDM2IEdNVAorICAgICAgICBTdWJqZWN0OiBDPUNILCBPPVN3aXNzU2lnbiBBRywgQ049U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoNDA5NiBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoNDA5NiBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpjNDpmMTo4Nzo3ZjpkMzo3ODozMTpmNzozODpjOTpmODpjMzo5OTo0MzoKKyAgICAgICAgICAgICAgICAgICAgYmM6Yzc6Zjc6YmM6Mzc6ZTc6NGU6NzE6YmE6NGI6OGY6YTU6NzM6MWQ6NWM6CisgICAgICAgICAgICAgICAgICAgIDZlOjk4OmFlOjAzOjU3OmFlOjM4OjM3OjQzOjJmOjE3OjNkOjFmOmM4OmNlOgorICAgICAgICAgICAgICAgICAgICA2ODoxMDpjMTo3ODphZToxOTowMzoyYjoxMDpmYToyYzo3OTo4MzpmNjplODoKKyAgICAgICAgICAgICAgICAgICAgYjk6Njg6Yjk6NTU6ZjI6MDQ6NDQ6YTc6Mzk6Zjk6ZmM6MDQ6OGI6MWU6ZjE6CisgICAgICAgICAgICAgICAgICAgIGEyOjRkOjI3OmY5OjYxOjdiOmJhOmI3OmU1OmEyOjEzOmI2OmViOjYxOjNlOgorICAgICAgICAgICAgICAgICAgICBkMDo2YzpkMTplNjpmYjpmYTo1ZTplZDoxZDpiNDo5ZTphMDozNTo1YjphMToKKyAgICAgICAgICAgICAgICAgICAgOTI6Y2I6ZjA6NDk6OTI6ZmU6ODU6MGE6MDU6M2U6ZTY6ZDk6MGI6ZTI6NGY6CisgICAgICAgICAgICAgICAgICAgIGJiOmRjOjk1OjM3OmZjOjkxOmU5OjMyOjM1OjIyOmQxOjFmOjNhOjRlOjI3OgorICAgICAgICAgICAgICAgICAgICA4NTo5ZDpiMDoxNTo5NDozMjpkYTo2MTowZDo0Nzo0ZDo2MDo0MjphZTo5MjoKKyAgICAgICAgICAgICAgICAgICAgNDc6ZTg6ODM6NWE6NTA6NTg6ZTk6OGE6OGI6Yjk6NWQ6YTE6ZGM6ZGQ6OTk6CisgICAgICAgICAgICAgICAgICAgIDRhOjFmOjM2OjY3OmJiOjQ4OmU0OjgzOmI2OjM3OmViOjQ4OjNhOmFmOjBmOgorICAgICAgICAgICAgICAgICAgICA2Nzo4ZjoxNzowNzplODowNDpjYTplZjo2YTozMTo4NzpkNDpjMDpiNjpmOToKKyAgICAgICAgICAgICAgICAgICAgOTQ6NzE6N2I6Njc6NjQ6Yjg6YjY6OTE6NGE6NDI6N2I6NjU6MmU6MzA6NmE6CisgICAgICAgICAgICAgICAgICAgIDBjOmY1OjkwOmVlOjk1OmU2OmYyOmNkOjgyOmVjOmQ5OmExOjRhOmVjOmY2OgorICAgICAgICAgICAgICAgICAgICBiMjo0YjplNTo0NTo4NTplNjo2ZDo3ODo5MzowNDoyZTo5Yzo4Mjo2ZDozNjoKKyAgICAgICAgICAgICAgICAgICAgYTk6YzQ6MzE6NjQ6MWY6ODY6ODM6MGI6MmE6ZjQ6MzU6MGE6Nzg6Yzk6NTU6CisgICAgICAgICAgICAgICAgICAgIGNmOjQxOmIwOjQ3OmU5OjMwOjlmOjk5OmJlOjYxOmE4OjA2Ojg0OmI5OjI4OgorICAgICAgICAgICAgICAgICAgICA3YTo1ZjozODpkOToxYjphOTozODpiMDo4Mzo3Zjo3MzpjMTpjMzozYjo0ODoKKyAgICAgICAgICAgICAgICAgICAgMmE6ODI6MGY6MjE6OWI6Yjg6Y2M6YTg6MzU6YzM6ODQ6MWI6ODM6YjM6M2U6CisgICAgICAgICAgICAgICAgICAgIGJlOmE0Ojk1OjY5OjAxOjNhOjg5OjAwOjc4OjA0OmQ5OmM5OmY0Ojk5OjE5OgorICAgICAgICAgICAgICAgICAgICBhYjo1Njo3ZTo1Yjo4Yjo4NjozOToxNTo5MTphNDoxMDoyYzowOTozMjo4MDoKKyAgICAgICAgICAgICAgICAgICAgNjA6YjM6OTM6YzA6MmE6YjY6MTg6MGI6OWQ6N2U6OGQ6NDk6ZjI6MTA6NGE6CisgICAgICAgICAgICAgICAgICAgIDdmOmY5OmQ1OjQ2OjJmOjE5OjkyOmEzOjk5OmE3OjI2OmFjOmJiOjhjOjNjOgorICAgICAgICAgICAgICAgICAgICBlNjowZTpiYzo0NzowNzpkYzo3Mzo1MTpmMTo3MDo2NDoyZjowODpmOTpiNDoKKyAgICAgICAgICAgICAgICAgICAgNDc6MWQ6MzA6NmM6NDQ6ZWE6Mjk6Mzc6ODU6OTI6Njg6NjY6YmM6ODM6Mzg6CisgICAgICAgICAgICAgICAgICAgIGZlOjdiOjM5OjJlOmQzOjUwOmYwOjFmOmZiOjVlOjYwOmI2OmE5OmE2OmZhOgorICAgICAgICAgICAgICAgICAgICAyNzo0MTpmMTo5YjoxODo3MjpmMjpmNTo4NDo3NDo0YTpjOTo2NzpjNDo1NDoKKyAgICAgICAgICAgICAgICAgICAgYWU6NDg6NjQ6ZGY6OGM6ZDE6NmU6YjA6MWQ6ZTE6MDc6OGY6MDg6MWU6OTk6CisgICAgICAgICAgICAgICAgICAgIDljOjcxOmU5OjRjOmQ4OmE1OmY3OjQ3OjEyOjFmOjc0OmQxOjUxOjllOjg2OgorICAgICAgICAgICAgICAgICAgICBmMzpjMjphMjoyMzo0MDowYjo3MzpkYjo0YjphNjplNzo3MzowNjo4YzpjMToKKyAgICAgICAgICAgICAgICAgICAgYTA6ZTk6YzE6NTk6YWM6NDY6ZmE6ZTY6MmY6Zjg6Y2Y6NzE6OWM6NDY6NmQ6CisgICAgICAgICAgICAgICAgICAgIGI5OmM0OjE1OjhkOjM4Ojc5OjAzOjQ1OjQ4OmVmOmM0OjVkOmQ3OjA4OmVlOgorICAgICAgICAgICAgICAgICAgICA4NzozOToyMjo4NjpiMjowZDowZjo1ODo0MzpmNzo3MTphOTo0ODoyZTpmZDoKKyAgICAgICAgICAgICAgICAgICAgZWE6ZDY6MWYKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICAxNzpBMDpDRDpDMTpFNDo0MTpCNjozQTo1QjozQjpDQjo0NTo5RDpCRDoxQzpDMjo5ODpGQTo4Njo1OAorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6MTc6QTA6Q0Q6QzE6RTQ6NDE6QjY6M0E6NUI6M0I6Q0I6NDU6OUQ6QkQ6MUM6QzI6OTg6RkE6ODY6NTgKKworICAgICAgICAgICAgWDUwOXYzIENlcnRpZmljYXRlIFBvbGljaWVzOiAKKyAgICAgICAgICAgICAgICBQb2xpY3k6IDIuMTYuNzU2LjEuODkuMS4zLjEuMQorICAgICAgICAgICAgICAgICAgQ1BTOiBodHRwOi8vcmVwb3NpdG9yeS5zd2lzc3NpZ24uY29tLworCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDczOmM2OjgxOmUwOjI3OmQyOjJkOjBmOmUwOjk1OjMwOmUyOjlhOjQxOjdmOjUwOjJjOjVmOgorICAgICAgICA1Zjo2Mjo2MTphOTo4Njo2YTo2OToxODowYzo3NDo0OTpkNjo1ZDo4NDplYTo0MTo1MjoxODoKKyAgICAgICAgNmY6NTg6YWQ6NTA6NTY6MjA6NmE6YzY6YmQ6Mjg6Njk6NTg6OTE6ZGM6OTE6MTE6MzU6YTk6CisgICAgICAgIDNhOjFkOmJjOjFhOmE1OjYwOjllOmQ4OjFmOjdmOjQ1OjkxOjY5OmQ5OjdlOmJiOjc4OjcyOgorICAgICAgICBjMTowNjowZjoyYTpjZTo4Zjo4NTo3MDo2MTphYzphMDpjZDowYjpiODozOToyOTo1Njo4NDoKKyAgICAgICAgMzI6NGU6ODY6YmI6M2Q6YzQ6MmE6ZDk6ZDc6MWY6NzI6ZWU6ZmU6NTE6YTE6MjI6NDE6YjE6CisgICAgICAgIDcxOjAyOjYzOjFhOjgyOmIwOjYyOmFiOjVlOjU3OjEyOjFmOmRmOmNiOmRkOjc1OmEwOmMwOgorICAgICAgICA1ZDo3OTo5MDo4YzoxYjplMDo1MDplNjpkZTozMTpmZTo5ODo3Yjo3MDo1ZjphNTo5MDpkODoKKyAgICAgICAgYWQ6Zjg6MDI6YjY6NmY6ZDM6NjA6ZGQ6NDA6NGI6MjI6YzU6M2Q6YWQ6M2E6N2E6OWY6MWE6CisgICAgICAgIDFhOjQ3OjkxOjc5OjMzOmJhOjgyOmRjOjMyOjY5OjAzOjk2OjZlOjFmOjRiOmYwOjcxOmZlOgorICAgICAgICBlMzo2Nzo3MjphMDpiMTpiZjo1Yzo4YjplNDpmYTo5OToyMjpjNzo4NDpiOToxYjo4ZDoyMzoKKyAgICAgICAgOTc6M2Y6ZWQ6MjU6ZTA6Y2Y6NjU6YmI6ZjU6NjE6MDQ6ZWY6ZGQ6MWU6YjI6NWE6NDE6MjI6CisgICAgICAgIDVhOmExOjlmOjVkOjJjOmU4OjViOmM5OjZkOmE5OjBjOjBjOjc4OmFhOjYwOmM2OjU2OjhmOgorICAgICAgICAwMTo1YTowYzo2ODpiYzo2OToxOTo3OTpjNDoxZjo3ZTo5NzowNTpiZjpjNTplOToyNDo1MToKKyAgICAgICAgNWU6ZDQ6ZDU6NGI6NTM6ZWQ6ZDk6MjM6NWE6MzY6MDM6NjU6YTM6YzE6MDM6YWQ6NDE6MzA6CisgICAgICAgIGYzOjQ2OjFiOjg1OjkwOmFmOjY1OmI1OmQ1OmIxOmU0OjE2OjViOjc4Ojc1OjFkOjk3OjdhOgorICAgICAgICA2ZDo1OTphOToyYTo4Zjo3YjpkZTpjMzo4Nzo4OToxMDo5OTo0OTo3Mzo3ODpjODozZDpiZDoKKyAgICAgICAgNTE6MzU6NzQ6MmE6ZDU6ZjE6N2U6Njk6MWI6MmE6YmI6M2I6YmQ6MjU6Yjg6OWE6NWE6M2Q6CisgICAgICAgIDcyOjYxOjkwOjY2Ojg3OmVlOjBjOmQ2OjRkOmQ0OjExOjc0OjBiOjZhOmZlOjBiOjAzOmZjOgorICAgICAgICBhMzo1NTo1Nzo4OTpmZTo0YTpjYjphZTo1YjoxNzowNTpjODpmMjo4ZDoyMzozMTo1MzozODoKKyAgICAgICAgZDI6MmQ6NmE6M2Y6ODI6Yjk6OGQ6MDg6NmE6Zjc6NWU6NDE6NzQ6NmU6YzM6MTE6N2U6MDc6CisgICAgICAgIGFjOjI5OjYwOjkxOjNmOjM4OmNhOjU3OjEwOjBkOmJkOjMwOjJmOmM3OmE1OmU2OjQxOmEwOgorICAgICAgICBkYTphZTowNTo4Nzo5YTphMDphNDo2NTo2Yzo0YzowOTowYzo4OTpiYTpiODpkMzpiOTpjMDoKKyAgICAgICAgOTM6OGE6MzA6ZmE6OGQ6ZTU6OWE6NmI6MTU6MDE6NGU6Njc6YWE6ZGE6NjI6NTY6M2U6ODQ6CisgICAgICAgIDA4OjY2OmQyOmM0OjM2OjdkOmE3OjNlOjEwOmZjOjg4OmUwOmQ0OjgwOmU1OjAwOmJkOmFhOgorICAgICAgICBmMzo0ZTowNjphMzo3YTo2YTpmOTo2Mjo3MjplMzowOTo0ZjplYjo5YjowZTowMToyMzpmMToKKyAgICAgICAgOWY6YmI6N2M6ZGM6ZGM6NmM6MTE6OTc6MjU6YjI6ZjI6YjQ6NjM6MTQ6ZDI6MDY6MmE6Njc6CisgICAgICAgIDhjOjgzOmY1OmNlOmVhOjA3OmQ4OjlhOjZhOjFlOmVjOmU0OjBhOmJiOjJhOjRjOmViOjA5OgorICAgICAgICA2MDozOTpjZTpjYTo2MjpkODoyZTo2ZQorU0hBMSBGaW5nZXJwcmludD05QjpBQTpFNTo5Rjo1NjpFRToyMTpDQjo0Mzo1QTpCRToyNTo5MzpERjpBNzpGMDo0MDpEMToxRDpDQgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzUyNGQ5YjQzLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNTI0ZDliNDMuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZDAzNTdjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzUyNGQ5YjQzLjAKQEAgLTAsMCArMSw4OCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFdVRDQ0E2R2dBd0lCQWdJUVFCckVaQ0d6RXlFRERydmtFaHJGSFRBTkJna3Foa2lHOXcwQkFRc0ZBRENCCit2VEVMTUFrR0ExVUVCaE1DVlZNeEZ6QVZCZ05WQkFvVERsWmxjbWxUYVdkdUxDQkpibU11TVI4d0hRWURWUVFMCitFeFpXWlhKcFUybG5iaUJVY25WemRDQk9aWFIzYjNKck1Ub3dPQVlEVlFRTEV6RW9ZeWtnTWpBd09DQldaWEpwCitVMmxuYml3Z1NXNWpMaUF0SUVadmNpQmhkWFJvYjNKcGVtVmtJSFZ6WlNCdmJteDVNVGd3TmdZRFZRUURFeTlXCitaWEpwVTJsbmJpQlZibWwyWlhKellXd2dVbTl2ZENCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVEFlCitGdzB3T0RBME1ESXdNREF3TURCYUZ3MHpOekV5TURFeU16VTVOVGxhTUlHOU1Rc3dDUVlEVlFRR0V3SlZVekVYCitNQlVHQTFVRUNoTU9WbVZ5YVZOcFoyNHNJRWx1WXk0eEh6QWRCZ05WQkFzVEZsWmxjbWxUYVdkdUlGUnlkWE4wCitJRTVsZEhkdmNtc3hPakE0QmdOVkJBc1RNU2hqS1NBeU1EQTRJRlpsY21sVGFXZHVMQ0JKYm1NdUlDMGdSbTl5CitJR0YxZEdodmNtbDZaV1FnZFhObElHOXViSGt4T0RBMkJnTlZCQU1UTDFabGNtbFRhV2R1SUZWdWFYWmxjbk5oCitiQ0JTYjI5MElFTmxjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGCitBQU9DQVE4QU1JSUJDZ0tDQVFFQXgyRTNYckVCTk50aTF4V2IvMWhhakNNajFtQ09rZGVRbUlONjVsZ1pPSXpGCis5dVZraGJTaWNmdnR2Ym5helUwQXRNZ3RjNlhIYVhHVkh6azhza1FIbk9nTytrMUt4Q0hmS1dHUE1pSmhnc1dICitIMjZNZkY4V0lGRkUwWEJQVityakhPUE1lZTVZMkE3Q3MwV1R3Q3pubWhjcmV3QTNla0V6ZU9FejR2TVFHbitICitMTDcyOWZkQzR1Vy9oMktKWHdCTDM4WGQ1SFZFTWtFNkhuRnVhY3NMZFVZSTBjclNLNVhRei91NVFHdGtqRmROCisvQk1SZVlUdFhsVDJOSjhJQWZNUUpRWVhTdHJ4SFhwbWE1aGdacVRaNzlJdWd2SHc3d25xUk1rVmF1SURialBUCitySjlWQU1mMkNHcVV1Vi9jNERQeGhHRDVXeWNSdFB3VzhydFdhb0FsalFJREFRQUJvNEd5TUlHdk1BOEdBMVVkCitFd0VCL3dRRk1BTUJBZjh3RGdZRFZSMFBBUUgvQkFRREFnRUdNRzBHQ0NzR0FRVUZCd0VNQkdFd1g2RmRvRnN3CitXVEJYTUZVV0NXbHRZV2RsTDJkcFpqQWhNQjh3QndZRkt3NERBaG9FRkkvbDB4cUdySTJPYThQUGdHclVTQmdzCitleGt1TUNVV0kyaDBkSEE2THk5c2IyZHZMblpsY21semFXZHVMbU52YlM5MmMyeHZaMjh1WjJsbU1CMEdBMVVkCitEZ1FXQkJTMmQvcHBTRWVmVXhMVnd1b0hNbllIMFpjSEdUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFTdmo0CitzQVBtTEdkNzVKUjNZOHh1VFBsOURnM2N5TGsxdVhCUFkvb2srbXlEakVlZE8yUHptdmwyTXBXUnNYZThySnErCitzZVF4SWNhQmxWWmFEckhDMUxHbVdhenhZOHU0VEIxWmtFcnZrQllvSDFxdUVQdUJVRGdNYk16eFBjUDFZK096Cis0eUhKSkRucC9SVm1SdlFiRWRCTmM2TjlSdms5N2FoZll0VHhQL2pnZEZjckdKMkJ0TVFvMnBTWHBYRHJyQjIrCitCeEh3MWR2ZDVZencxVEt3ZytaWDRvKy92cUdxdnowZHRkUTQ2dGV3WERwUGFqK1B3R1pzWTZycDJhUVc5SUhSCitsUlFPZmMyVk5OblNqM0J6Z1h1Y2ZyMllZZGhGaDVpUXhldUdNTVkxdi9EL3cxV0lnMHZ2QlpJR2NmSzRtSk8zCis3TTJDWWZFNDVrK1htQ3BhalE9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgNDA6MWE6YzQ6NjQ6MjE6YjM6MTM6MjE6MDM6MGU6YmI6ZTQ6MTI6MWE6YzU6MWQKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPVZlcmlTaWduLCBJbmMuLCBPVT1WZXJpU2lnbiBUcnVzdCBOZXR3b3JrLCBPVT0oYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5LCBDTj1WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogQXByICAyIDAwOjAwOjAwIDIwMDggR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBEZWMgIDEgMjM6NTk6NTkgMjAzNyBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgTz1WZXJpU2lnbiwgSW5jLiwgT1U9VmVyaVNpZ24gVHJ1c3QgTmV0d29yaywgT1U9KGMpIDIwMDggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seSwgQ049VmVyaVNpZ24gVW5pdmVyc2FsIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmM3OjYxOjM3OjVlOmIxOjAxOjM0OmRiOjYyOmQ3OjE1OjliOmZmOjU4OgorICAgICAgICAgICAgICAgICAgICA1YTo4YzoyMzoyMzpkNjo2MDo4ZTo5MTpkNzo5MDo5ODo4Mzo3YTplNjo1ODoKKyAgICAgICAgICAgICAgICAgICAgMTk6Mzg6OGM6YzU6ZjY6ZTU6NjQ6ODU6YjQ6YTI6NzE6ZmI6ZWQ6YmQ6Yjk6CisgICAgICAgICAgICAgICAgICAgIGRhOmNkOjRkOjAwOmI0OmM4OjJkOjczOmE1OmM3OjY5OjcxOjk1OjFmOjM5OgorICAgICAgICAgICAgICAgICAgICAzYzpiMjo0NDowNzo5YzplODowZTpmYTo0ZDo0YTpjNDoyMTpkZjoyOTo2MToKKyAgICAgICAgICAgICAgICAgICAgOGY6MzI6MjI6NjE6ODI6YzU6ODc6MWY6NmU6OGM6N2M6NWY6MTY6MjA6NTE6CisgICAgICAgICAgICAgICAgICAgIDQ0OmQxOjcwOjRmOjU3OmVhOmUzOjFjOmUzOmNjOjc5OmVlOjU4OmQ4OjBlOgorICAgICAgICAgICAgICAgICAgICBjMjpiMzo0NTo5MzpjMDoyYzplNzo5YToxNzoyYjo3YjowMDozNzo3YTo0MToKKyAgICAgICAgICAgICAgICAgICAgMzM6Nzg6ZTE6MzM6ZTI6ZjM6MTA6MWE6N2Y6ODc6MmM6YmU6ZjY6ZjU6Zjc6CisgICAgICAgICAgICAgICAgICAgIDQyOmUyOmU1OmJmOjg3OjYyOjg5OjVmOjAwOjRiOmRmOmM1OmRkOmU0Ojc1OgorICAgICAgICAgICAgICAgICAgICA0NDozMjo0MTozYToxZTo3MTo2ZTo2OTpjYjowYjo3NTo0NjowODpkMTpjYToKKyAgICAgICAgICAgICAgICAgICAgZDI6MmI6OTU6ZDA6Y2Y6ZmI6Yjk6NDA6NmI6NjQ6OGM6NTc6NGQ6ZmM6MTM6CisgICAgICAgICAgICAgICAgICAgIDExOjc5Ojg0OmVkOjVlOjU0OmY2OjM0OjlmOjA4OjAxOmYzOjEwOjI1OjA2OgorICAgICAgICAgICAgICAgICAgICAxNzo0YTpkYTpmMToxZDo3YTo2Njo2Yjo5ODo2MDo2NjphNDpkOTplZjpkMjoKKyAgICAgICAgICAgICAgICAgICAgMmU6ODI6ZjE6ZjA6ZWY6MDk6ZWE6NDQ6Yzk6MTU6NmE6ZTI6MDM6NmU6MzM6CisgICAgICAgICAgICAgICAgICAgIGQzOmFjOjlmOjU1OjAwOmM3OmY2OjA4OjZhOjk0OmI5OjVmOmRjOmUwOjMzOgorICAgICAgICAgICAgICAgICAgICBmMTo4NDo2MDpmOTo1YjoyNzoxMTpiNDpmYzoxNjpmMjpiYjo1Njo2YTo4MDoKKyAgICAgICAgICAgICAgICAgICAgMjU6OGQKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIDEuMy42LjEuNS41LjcuMS4xMjogCisgICAgICAgICAgICAgICAgMF8uXS5bMFkwVzBVLi5pbWFnZS9naWYwITAuMC4uLisuLi4uLi4uLi4uLi4uLmsuLi5qLkguLHsuLjAlLiNodHRwOi8vbG9nby52ZXJpc2lnbi5jb20vdnNsb2dvLmdpZgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEI2Ojc3OkZBOjY5OjQ4OjQ3OjlGOjUzOjEyOkQ1OkMyOkVBOjA3OjMyOjc2OjA3OkQxOjk3OjA3OjE5CisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgNGE6Zjg6Zjg6YjA6MDM6ZTY6MmM6Njc6N2I6ZTQ6OTQ6Nzc6NjM6Y2M6NmU6NGM6Zjk6N2Q6CisgICAgICAgIDBlOjBkOmRjOmM4OmI5OjM1OmI5OjcwOjRmOjYzOmZhOjI0OmZhOjZjOjgzOjhjOjQ3OjlkOgorICAgICAgICAzYjo2MzpmMzo5YTpmOTo3NjozMjo5NTo5MTpiMTo3NzpiYzphYzo5YTpiZTpiMTplNDozMToKKyAgICAgICAgMjE6YzY6ODE6OTU6NTY6NWE6MGU6YjE6YzI6ZDQ6YjE6YTY6NTk6YWM6ZjE6NjM6Y2I6Yjg6CisgICAgICAgIDRjOjFkOjU5OjkwOjRhOmVmOjkwOjE2OjI4OjFmOjVhOmFlOjEwOmZiOjgxOjUwOjM4OjBjOgorICAgICAgICA2YzpjYzpmMTozZDpjMzpmNTo2MzplMzpiMzplMzoyMTpjOToyNDozOTplOTpmZDoxNTo2NjoKKyAgICAgICAgNDY6ZjQ6MWI6MTE6ZDA6NGQ6NzM6YTM6N2Q6NDY6Zjk6M2Q6ZWQ6YTg6NWY6NjI6ZDQ6ZjE6CisgICAgICAgIDNmOmY4OmUwOjc0OjU3OjJiOjE4OjlkOjgxOmI0OmM0OjI4OmRhOjk0Ojk3OmE1OjcwOmViOgorICAgICAgICBhYzoxZDpiZTowNzoxMTpmMDpkNTpkYjpkZDplNTo4YzpmMDpkNTozMjpiMDo4MzplNjo1NzoKKyAgICAgICAgZTI6OGY6YmY6YmU6YTE6YWE6YmY6M2Q6MWQ6YjU6ZDQ6Mzg6ZWE6ZDc6YjA6NWM6M2E6NGY6CisgICAgICAgIDZhOjNmOjhmOmMwOjY2OjZjOjYzOmFhOmU5OmQ5OmE0OjE2OmY0OjgxOmQxOjk1OjE0OjBlOgorICAgICAgICA3ZDpjZDo5NTozNDpkOTpkMjo4Zjo3MDo3Mzo4MTo3Yjo5Yzo3ZTpiZDo5ODo2MTpkODo0NToKKyAgICAgICAgODc6OTg6OTA6YzU6ZWI6ODY6MzA6YzY6MzU6YmY6ZjA6ZmY6YzM6NTU6ODg6ODM6NGI6ZWY6CisgICAgICAgIDA1OjkyOjA2OjcxOmYyOmI4Ojk4OjkzOmI3OmVjOmNkOjgyOjYxOmYxOjM4OmU2OjRmOjk3OgorICAgICAgICA5ODoyYTo1YTo4ZAorU0hBMSBGaW5nZXJwcmludD0zNjo3OTpDQTozNTo2Njo4Nzo3MjozMDo0RDozMDpBNTpGQjo4NzozQjowRjpBNzo3QjpCNzowRDo1NApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzU2YjhhMGI2LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNTZiOGEwYjYuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNWUwYTAzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzU2YjhhMGI2LjAKQEAgLTAsMCArMSw4MiBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFUERDQ0F5U2dBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUVVGQURDQnZqRS9NRDBHQTFVRUF3dzJWTU9jCitVa3RVVWxWVFZDQkZiR1ZyZEhKdmJtbHJJRk5sY25ScFptbHJZU0JJYVhwdFpYUWdVMkhFbjJ4aGVjU3hZOFN4CitjOFN4TVFzd0NRWURWUVFHRXdKVVVqRVBNQTBHQTFVRUJ3d0dRVzVyWVhKaE1WMHdXd1lEVlFRS0RGUlV3NXhTCitTMVJTVlZOVUlFSnBiR2RwSU1Td2JHVjBhY1dmYVcwZ2RtVWdRbWxzYWNXZmFXMGdSOE84ZG1WdWJHbkVuMmtnCitTR2w2YldWMGJHVnlhU0JCTHNXZUxpQW9ZeWtnUzJGenhMRnRJREl3TURVd0hoY05NRFV4TVRBM01UQXdOelUzCitXaGNOTVRVd09URTJNVEF3TnpVM1dqQ0J2akUvTUQwR0ExVUVBd3cyVk1PY1VrdFVVbFZUVkNCRmJHVnJkSEp2CitibWxySUZObGNuUnBabWxyWVNCSWFYcHRaWFFnVTJIRW4yeGhlY1N4WThTeGM4U3hNUXN3Q1FZRFZRUUdFd0pVCitVakVQTUEwR0ExVUVCd3dHUVc1cllYSmhNVjB3V3dZRFZRUUtERlJVdzV4U1MxUlNWVk5VSUVKcGJHZHBJTVN3CitiR1YwYWNXZmFXMGdkbVVnUW1sc2FjV2ZhVzBnUjhPOGRtVnViR25FbjJrZ1NHbDZiV1YwYkdWeWFTQkJMc1dlCitMaUFvWXlrZ1MyRnp4TEZ0SURJd01EVXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCCitBUUNwTm43RGtVTk13eG1ZQ01qSFdIdFBGb3lsemtrQkgzTU9ySFVUcHZxZUxDRGUySkFPQ3RGcDBpZjdxbmVmCitKMUlsNHN0ZDJOaURVQmQ5aXJXQ1B3U090Tlh3U2Fka3R4NHVYeUNjVUhWUHIrRzFRUlQwbUpLSXgrWGxaRWRoCitSM245d0ZIeHdabm4zTTVxKzYrMUFURGNSaHp2aXV5Vjc5ei9yeEFjNjUzWXNLcHFoUmdORjhrK3YvR2IwQW1KCitRdjJnUXJTZGlWRlZLYzhiY0x5RVZLM0JFeCtZOUM1MllJdGRQNXF0eWd5L3AxWmJqM2U0MVo1NVNaSS80UEdYCitKSHBzbXhjUGJlOVRtSkVyNUErK1dYa0hlTHVYbGZTZmFkUllod3FwNDh5MldCbWZKaUd4eEZtTnNrRjF3SzFwCit6cHdBQ1BJMi96N3dvUThhckJUOXBtQVBBZ01CQUFHalF6QkJNQjBHQTFVZERnUVdCQlRaTjdOT0JmM1p6NThTCitGcTYyaVMvckpUcUlIREFQQmdOVkhROEJBZjhFQlFNREJ3WUFNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKCitLb1pJaHZjTkFRRUZCUUFEZ2dFQkFISmdscmZKM05ncFhpT0ZYN0t6TFhiN2lOY1gvbnR0UmJqMmhXeWZJdndxCitFQ0xzcXJrdzlxdFkxamtRTVprcEFMMkpaa0g3ZE42UndSZ0xuN1ZoeTUwNnZ2V29sS01pVlc0WFNmL1NLZkU0CitKbDN2cGFvNitYRjc1dHBZSGROMHdnSDZQbWxZWDYzTGFMNFVMcHRzd0xiY29DYjZkeHJpSk5vYU4rQm5yZEZ6CitndzJsR2gxdUVwSitoR0lBRjcyOEpSaFg4dGVwYjFtSXZEUzNMb1Y0blpiY0ZNTXNpbEtibG94U1pqMkdGb3RICit1RkVKak9wOXpZaHlzMkF6c2ZBS1JPOFA5UWszaUNRT0xHc2dPcUw2RWZKQU5aeEVhR003ckROdlk3d3N1L0xTCit5M1o5ZllqWUhjZ0ZIVzY4bEtsbWpIZHh4L3FSK2k5Um51azVVcmJuQkVJPQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAxICgweDEpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IENOPVRceEMzXHg5Q1JLVFJVU1QgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhXHhDNFx4OUZsYXlceEM0XHhCMWNceEM0XHhCMXNceEM0XHhCMSwgQz1UUiwgTD1BbmthcmEsIE89VFx4QzNceDlDUktUUlVTVCBCaWxnaSBceEM0XHhCMGxldGlceEM1XHg5RmltIHZlIEJpbGlceEM1XHg5RmltIEdceEMzXHhCQ3ZlbmxpXHhDNFx4OUZpIEhpem1ldGxlcmkgQS5ceEM1XHg5RS4gKGMpIEthc1x4QzRceEIxbSAyMDA1CisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBOb3YgIDcgMTA6MDc6NTcgMjAwNSBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IFNlcCAxNiAxMDowNzo1NyAyMDE1IEdNVAorICAgICAgICBTdWJqZWN0OiBDTj1UXHhDM1x4OUNSS1RSVVNUIEVsZWt0cm9uaWsgU2VydGlmaWthIEhpem1ldCBTYVx4QzRceDlGbGF5XHhDNFx4QjFjXHhDNFx4QjFzXHhDNFx4QjEsIEM9VFIsIEw9QW5rYXJhLCBPPVRceEMzXHg5Q1JLVFJVU1QgQmlsZ2kgXHhDNFx4QjBsZXRpXHhDNVx4OUZpbSB2ZSBCaWxpXHhDNVx4OUZpbSBHXHhDM1x4QkN2ZW5saVx4QzRceDlGaSBIaXptZXRsZXJpIEEuXHhDNVx4OUUuIChjKSBLYXNceEM0XHhCMW0gMjAwNQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YTk6MzY6N2U6YzM6OTE6NDM6NGM6YzM6MTk6OTg6MDg6Yzg6Yzc6NTg6CisgICAgICAgICAgICAgICAgICAgIDdiOjRmOjE2OjhjOmE1OmNlOjQ5OjAxOjFmOjczOjBlOmFjOjc1OjEzOmE2OgorICAgICAgICAgICAgICAgICAgICBmYTo5ZToyYzoyMDpkZTpkODo5MDowZTowYTpkMTo2OTpkMjoyNzpmYjphYToKKyAgICAgICAgICAgICAgICAgICAgNzc6OWY6Mjc6NTI6MjU6ZTI6Y2I6NWQ6ZDg6ZDg6ODM6NTA6MTc6N2Q6OGE6CisgICAgICAgICAgICAgICAgICAgIGI1OjgyOjNmOjA0OjhlOmI0OmQ1OmYwOjQ5OmE3OjY0OmI3OjFlOjJlOjVmOgorICAgICAgICAgICAgICAgICAgICAyMDo5Yzo1MDo3NTo0ZjphZjplMTpiNTo0MToxNDpmNDo5ODo5Mjo4ODpjNzoKKyAgICAgICAgICAgICAgICAgICAgZTU6ZTU6NjQ6NDc6NjE6NDc6Nzk6ZmQ6YzA6NTE6ZjE6YzE6OTk6ZTc6ZGM6CisgICAgICAgICAgICAgICAgICAgIGNlOjZhOmZiOmFmOmI1OjAxOjMwOmRjOjQ2OjFjOmVmOjhhOmVjOjk1OmVmOgorICAgICAgICAgICAgICAgICAgICBkYzpmZjphZjoxMDoxYzplYjo5ZDpkODpiMDphYTo2YTo4NToxODowZDoxNzoKKyAgICAgICAgICAgICAgICAgICAgYzk6M2U6YmY6ZjE6OWI6ZDA6MDk6ODk6NDI6ZmQ6YTA6NDI6YjQ6OWQ6ODk6CisgICAgICAgICAgICAgICAgICAgIDUxOjU1OjI5OmNmOjFiOjcwOmJjOjg0OjU0OmFkOmMxOjEzOjFmOjk4OmY0OgorICAgICAgICAgICAgICAgICAgICAyZTo3Njo2MDo4Yjo1ZDozZjo5YTphZDpjYTowYzpiZjphNzo1Njo1Yjo4ZjoKKyAgICAgICAgICAgICAgICAgICAgNzc6Yjg6ZDU6OWU6Nzk6NDk6OTI6M2Y6ZTA6ZjE6OTc6MjQ6N2E6NmM6OWI6CisgICAgICAgICAgICAgICAgICAgIDE3OjBmOjZkOmVmOjUzOjk4OjkxOjJiOmU0OjBmOmJlOjU5Ojc5OjA3Ojc4OgorICAgICAgICAgICAgICAgICAgICBiYjo5Nzo5NTpmNDo5Zjo2OTpkNDo1ODo4NzowYTphOTplMzpjYzpiNjo1ODoKKyAgICAgICAgICAgICAgICAgICAgMTk6OWY6MjY6MjE6YjE6YzQ6NTk6OGQ6YjI6NDE6NzU6YzA6YWQ6Njk6Y2U6CisgICAgICAgICAgICAgICAgICAgIDljOjAwOjA4OmYyOjM2OmZmOjNlOmYwOmExOjBmOjFhOmFjOjE0OmZkOmE2OgorICAgICAgICAgICAgICAgICAgICA2MDowZgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgRDk6Mzc6QjM6NEU6MDU6RkQ6RDk6Q0Y6OUY6MTI6MTY6QUU6QjY6ODk6MkY6RUI6MjU6M0E6ODg6MUMKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDcyOjYwOjk2OmI3OmM5OmRjOmQ4OjI5OjVlOjIzOjg1OjVmOmIyOmIzOjJkOjc2OmZiOjg4OgorICAgICAgICBkNzoxNzpmZTo3Yjo2ZDo0NTpiODpmNjo4NTo2Yzo5ZjoyMjpmYzoyYToxMDoyMjplYzphYToKKyAgICAgICAgYjk6MzA6ZjY6YWI6NTg6ZDY6Mzk6MTA6MzE6OTk6Mjk6MDA6YmQ6ODk6NjY6NDE6ZmI6NzQ6CisgICAgICAgIGRlOjkxOmMxOjE4OjBiOjlmOmI1OjYxOmNiOjlkOjNhOmJlOmY1OmE4Ojk0OmEzOjIyOjU1OgorICAgICAgICA2ZToxNzo0OTpmZjpkMjoyOTpmMTozODoyNjo1ZDplZjphNTphYTozYTpmOTo3MTo3YjplNjoKKyAgICAgICAgZGE6NTg6MWQ6ZDM6NzQ6YzI6MDE6ZmE6M2U6Njk6NTg6NWY6YWQ6Y2I6Njg6YmU6MTQ6MmU6CisgICAgICAgIDliOjZjOmMwOmI2OmRjOmEwOjI2OmZhOjc3OjFhOmUyOjI0OmRhOjFhOjM3OmUwOjY3OmFkOgorICAgICAgICBkMTo3Mzo4MzowZDphNToxYToxZDo2ZToxMjo5Mjo3ZTo4NDo2MjowMDoxNzpiZDpiYzoyNToKKyAgICAgICAgMTg6NTc6ZjI6ZDc6YTk6NmY6NTk6ODg6YmM6MzQ6Yjc6MmU6ODU6Nzg6OWQ6OTY6ZGM6MTQ6CisgICAgICAgIGMzOjJjOjhhOjUyOjliOjk2OjhjOjUyOjY2OjNkOjg2OjE2OjhiOjQ3OmI4OjUxOjA5OjhjOgorICAgICAgICBlYTo3ZDpjZDo4ODo3MjpiMzo2MDozMzpiMTpmMDowYTo0NDplZjowZjpmNTowOTozNzo4ODoKKyAgICAgICAgMjQ6MGU6MmM6NmI6MjA6M2E6YTI6ZmE6MTE6ZjI6NDA6MzU6OWM6NDQ6Njg6NjM6M2I6YWM6CisgICAgICAgIDMzOjZmOjYzOmJjOjJjOmJiOmYyOmQyOmNiOjc2OjdkOjdkOjg4OmQ4OjFkOmM4OjA1OjFkOgorICAgICAgICA2ZTpiYzo5NDphOTo2Njo4Yzo3Nzo3MTpjNzpmYTo5MTpmYToyZjo1MTo5ZTplOTozOTo1MjoKKyAgICAgICAgYjY6ZTc6MDQ6NDIKK1NIQTEgRmluZ2VycHJpbnQ9QjQ6MzU6RDQ6RTE6MTE6OUQ6MUM6NjY6OTA6QTc6NDk6RUI6QjM6OTQ6QkQ6NjM6N0I6QTc6ODI6QjcKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy81NzY5MjM3My4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzU3NjkyMzczLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDgzOTY4OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy81NzY5MjM3My4wCkBAIC0wLDAgKzEsODEgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRFpqQ0NBazZnQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFVRkFEQkVNUXN3Q1FZRFZRUUdFd0pWVXpFVworTUJRR0ExVUVDaE1OUjJWdlZISjFjM1FnU1c1akxqRWRNQnNHQTFVRUF4TVVSMlZ2VkhKMWMzUWdSMnh2WW1GcworSUVOQklESXdIaGNOTURRd016QTBNRFV3TURBd1doY05NVGt3TXpBME1EVXdNREF3V2pCRU1Rc3dDUVlEVlFRRworRXdKVlV6RVdNQlFHQTFVRUNoTU5SMlZ2VkhKMWMzUWdTVzVqTGpFZE1Cc0dBMVVFQXhNVVIyVnZWSEoxYzNRZworUjJ4dlltRnNJRU5CSURJd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUR2UEUxQQorUFJEZk8xTUE0V2YrbEdBVlBvV0k4WWtOa01nb0k1a0Y2Q3NnbmNiellFYll3YkxWakRIWjNDQjVKSUcvTlRMOAorWTJuYnNTcHI3aUZZOGdqcGVNdHZ5L3dXVXNpUnhQODljOTZ4UHFmQ2ZXYkI5WDVTSkJyaTFXZVIwSUlRMTNoTAorVHl0Q09iMWtMVUNnc0JEVE9FaEdpS0VNdXpvekttS1krd0NkRTFsL2J6dHlxdTZtRDRiNUJXSHFaMzhNTjVhTAorNW1rV1J4SENKMWtEczZaZ3dpRkFWdnFneDMwNkUrUHNWOGV6MXE2ZGlZRDNBZWNzOXBZckV3MTVMTm5BNUlaNworUzR3TWNvS0sreGZOQUd3NkV6eXdoSWRMRm5vcHNrL2JIZFFMODJZM3ZkajJWN3RlSkhxNFBJdTUrcElhR29TZQorMkhTUHFodC9YdlQrUlNJaEFnTUJBQUdqWXpCaE1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRQorRkhFNE52SUNNVk5ISzI2NlpVYXBFQlZZSUFVSk1COEdBMVVkSXdRWU1CYUFGSEU0TnZJQ01WTkhLMjY2WlVhcAorRUJWWUlBVUpNQTRHQTFVZER3RUIvd1FFQXdJQmhqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFBL2UxSzZ0ZAorRVB4N3NySmVySnNPZmxONFdUNUNCUDUxbzYyc2dVN1hBb3RleEMzSVVuYkhMQi84Z1RLWTBVdkdrcE16TlRFdgorL05nZFJOM2dnWCtkNll2aFpKRmlDemtJakt4MG5WblplbGxTbHhHNUZudHZSZE9XMlRGOUFqWVBuRHR1enl3TgorQTBaRjY2RDBmMGhFeGdoQXpONGJjTFVwcmJxTE96UmxkUnR4SVIwc0ZBcXdscFc0MXVyeVpmc3B1ay9xa1pOMAorYWJieS8rRWEwQXpSZG9YTGlpVzlsMTRzYnhXWkp1ZTJLZjhpN01rQ3gxWUF6VW01czJ4N1V3UWE0cWpKcWhJRgorSThMTzU3c0VBc3pBUjZMa3hDa3ZXMFZYaVZIdVBPdFNDUDhITlI2Zk5XcEhTbGFZMFZxRkg0ejFJcityem9QegorNGlJcHJuMkRRS2k2YkE9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAxICgweDEpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9VVMsIE89R2VvVHJ1c3QgSW5jLiwgQ049R2VvVHJ1c3QgR2xvYmFsIENBIDIKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IE1hciAgNCAwNTowMDowMCAyMDA0IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogTWFyICA0IDA1OjAwOjAwIDIwMTkgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89R2VvVHJ1c3QgSW5jLiwgQ049R2VvVHJ1c3QgR2xvYmFsIENBIDIKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmVmOjNjOjRkOjQwOjNkOjEwOmRmOjNiOjUzOjAwOmUxOjY3OmZlOjk0OgorICAgICAgICAgICAgICAgICAgICA2MDoxNTozZTo4NTo4ODpmMTo4OTowZDo5MDpjODoyODoyMzo5OTowNTplODoKKyAgICAgICAgICAgICAgICAgICAgMmI6MjA6OWQ6YzY6ZjM6NjA6NDY6ZDg6YzE6YjI6ZDU6OGM6MzE6ZDk6ZGM6CisgICAgICAgICAgICAgICAgICAgIDIwOjc5OjI0OjgxOmJmOjM1OjMyOmZjOjYzOjY5OmRiOmIxOjJhOjZiOmVlOgorICAgICAgICAgICAgICAgICAgICAyMTo1ODpmMjowODplOTo3ODpjYjo2ZjpjYjpmYzoxNjo1MjpjODo5MTpjNDoKKyAgICAgICAgICAgICAgICAgICAgZmY6M2Q6NzM6ZGU6YjE6M2U6YTc6YzI6N2Q6NjY6YzE6ZjU6N2U6NTI6MjQ6CisgICAgICAgICAgICAgICAgICAgIDFhOmUyOmQ1OjY3OjkxOmQwOjgyOjEwOmQ3Ojc4OjRiOjRmOjJiOjQyOjM5OgorICAgICAgICAgICAgICAgICAgICBiZDo2NDoyZDo0MDphMDpiMDoxMDpkMzozODo0ODo0Njo4ODphMTowYzpiYjoKKyAgICAgICAgICAgICAgICAgICAgM2E6MzM6MmE6NjI6OTg6ZmI6MDA6OWQ6MTM6NTk6N2Y6NmY6M2I6NzI6YWE6CisgICAgICAgICAgICAgICAgICAgIGVlOmE2OjBmOjg2OmY5OjA1OjYxOmVhOjY3OjdmOjBjOjM3Ojk2OjhiOmU2OgorICAgICAgICAgICAgICAgICAgICA2OToxNjo0NzoxMTpjMjoyNzo1OTowMzpiMzphNjo2MDpjMjoyMTo0MDo1NjoKKyAgICAgICAgICAgICAgICAgICAgZmE6YTA6Yzc6N2Q6M2E6MTM6ZTM6ZWM6NTc6Yzc6YjM6ZDY6YWU6OWQ6ODk6CisgICAgICAgICAgICAgICAgICAgIDgwOmY3OjAxOmU3OjJjOmY2Ojk2OjJiOjEzOjBkOjc5OjJjOmQ5OmMwOmU0OgorICAgICAgICAgICAgICAgICAgICA4Njo3Yjo0Yjo4YzowYzo3Mjo4Mjo4YTpmYjoxNzpjZDowMDo2YzozYToxMzoKKyAgICAgICAgICAgICAgICAgICAgM2M6YjA6ODQ6ODc6NGI6MTY6N2E6Mjk6YjI6NGY6ZGI6MWQ6ZDQ6MGI6ZjM6CisgICAgICAgICAgICAgICAgICAgIDY2OjM3OmJkOmQ4OmY2OjU3OmJiOjVlOjI0OjdhOmI4OjNjOjhiOmI5OmZhOgorICAgICAgICAgICAgICAgICAgICA5MjoxYToxYTo4NDo5ZTpkODo3NDo4ZjphYToxYjo3Zjo1ZTpmNDpmZTo0NToKKyAgICAgICAgICAgICAgICAgICAgMjI6MjEKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICA3MTozODozNjpGMjowMjozMTo1Mzo0NzoyQjo2RTpCQTo2NTo0NjpBOToxMDoxNTo1ODoyMDowNTowOQorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6NzE6Mzg6MzY6RjI6MDI6MzE6NTM6NDc6MkI6NkU6QkE6NjU6NDY6QTk6MTA6MTU6NTg6MjA6MDU6MDkKKworICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBEaWdpdGFsIFNpZ25hdHVyZSwgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMDM6Zjc6YjU6MmI6YWI6NWQ6MTA6ZmM6N2I6YjI6YjI6NWU6YWM6OWI6MGU6N2U6NTM6Nzg6CisgICAgICAgIDU5OjNlOjQyOjA0OmZlOjc1OmEzOmFkOmFjOjgxOjRlOmQ3OjAyOjhiOjVlOmM0OjJkOmM4OgorICAgICAgICA1Mjo3NjpjNzoyYzoxZjpmYzo4MTozMjo5ODpkMTo0YjpjNjo5Mjo5MzozMzozNTozMToyZjoKKyAgICAgICAgZmM6ZDg6MWQ6NDQ6ZGQ6ZTA6ODE6N2Y6OWQ6ZTk6OGI6ZTE6NjQ6OTE6NjI6MGI6Mzk6MDg6CisgICAgICAgIDhjOmFjOjc0OjlkOjU5OmQ5OjdhOjU5OjUyOjk3OjExOmI5OjE2OjdiOjZmOjQ1OmQzOjk2OgorICAgICAgICBkOTozMTo3ZDowMjozNjowZjo5YzozYjo2ZTpjZjoyYzowZDowMzo0Njo0NTplYjphMDpmNDoKKyAgICAgICAgN2Y6NDg6NDQ6YzY6MDg6NDA6Y2M6ZGU6MWI6NzA6YjU6Mjk6YWQ6YmE6OGI6M2I6MzQ6NjU6CisgICAgICAgIDc1OjFiOjcxOjIxOjFkOjJjOjE0OjBhOmIwOjk2Ojk1OmI4OmQ2OmVhOmYyOjY1OmZiOjI5OgorICAgICAgICBiYTo0ZjplYTo5MTo5Mzo3NDo2OTpiNjpmMjpmZjplMToxYTpkMDowYzpkMTo3Njo4NTpjYjoKKyAgICAgICAgOGE6MjU6YmQ6OTc6NWU6MmM6NmY6MTU6OTk6MjY6ZTc6YjY6Mjk6ZmY6MjI6ZWM6Yzk6MDI6CisgICAgICAgIGM3OjU2OjAwOmNkOjQ5OmI5OmIzOjZjOjdiOjUzOjA0OjFhOmUyOmE4OmM5OmFhOjEyOjA1OgorICAgICAgICAyMzpjMjpjZTplNzpiYjowNDowMjpjYzpjMDo0NzphMjplNDpjNDoyOToyZjo1Yjo0NTo1NzoKKyAgICAgICAgODk6NTE6ZWU6M2M6ZWI6NTI6MDg6ZmY6MDc6MzU6MWU6OWY6MzU6NmE6NDc6NGE6NTY6OTg6CisgICAgICAgIGQxOjVhOjg1OjFmOjhjOmY1OjIyOmJmOmFiOmNlOjgzOmYzOmUyOjIyOjI5OmFlOjdkOjgzOgorICAgICAgICA0MDphODpiYTo2YworU0hBMSBGaW5nZXJwcmludD1BOTpFOTo3ODowODoxNDozNzo1ODo4ODpGMjowNToxOTpCMDo2RDoyQjowRDoyQjo2MDoxNjo5MDo3RApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzU4YTQ0YWYxLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNThhNDRhZjEuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43Yzc5YTM2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzU4YTQ0YWYxLjAKQEAgLTAsMCArMSw4OCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFQWpDQ0F1cWdBd0lCQWdJRk9SRkZFSlF3RFFZSktvWklodmNOQVFFRkJRQXdnWVV4Q3pBSkJnTlZCQVlUCitBa1pTTVE4d0RRWURWUVFJRXdaR2NtRnVZMlV4RGpBTUJnTlZCQWNUQlZCaGNtbHpNUkF3RGdZRFZRUUtFd2RRCitUUzlUUjBST01RNHdEQVlEVlFRTEV3VkVRMU5UU1RFT01Bd0dBMVVFQXhNRlNVZERMMEV4SXpBaEJna3Foa2lHCis5dzBCQ1FFV0ZHbG5ZMkZBYzJka2JpNXdiUzVuYjNWMkxtWnlNQjRYRFRBeU1USXhNekUwTWpreU0xb1hEVEl3CitNVEF4TnpFME1qa3lNbG93Z1lVeEN6QUpCZ05WQkFZVEFrWlNNUTh3RFFZRFZRUUlFd1pHY21GdVkyVXhEakFNCitCZ05WQkFjVEJWQmhjbWx6TVJBd0RnWURWUVFLRXdkUVRTOVRSMFJPTVE0d0RBWURWUVFMRXdWRVExTlRTVEVPCitNQXdHQTFVRUF4TUZTVWRETDBFeEl6QWhCZ2txaGtpRzl3MEJDUUVXRkdsblkyRkFjMmRrYmk1d2JTNW5iM1YyCitMbVp5TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFzaC9SMEdMRk16dkFCSWFJCitzOXo0aVBmOTMwUGZlbzJhU1Z6MlRxck1ITG1oNnllSjhrYnBPMHB4MVIyT0xjL21yYXRqVU1kVUMyNFN5WkEyCit4dGd2MnBHcWFNVnkvaGNLc2hkK2ViVXlpSERLY01DV1NvN2tWYzBkSjVTL3puSXE3Rno1Y3lEK3ZmY3VpV2U0Cit1MGR6RXZmUk5XazY4Z3E1cnY5R1FrYWl2NkdGR3ZtLzVQOUpoZmVqY0lZeUhGMmZZUGVwcmFYL3o5RTArWDFiCitGOGJjMWc0b2E4TGQ4ZlV6YUoxTy9JZDhOaExXbzREb1F3MVZZWlRxWkRkSDZuZkswTEpZQmNOZGZyR29ScEF4CitWczV3S3BheU1MaDM1bm5BdlNrNy9aUjNUTDBnelVFbDRDN0hHN3Z1cEFSQjBsMnRFbXFLbTBmN3lkMUdRT0dkCitQRFBRdFFJREFRQUJvM2N3ZFRBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUFzR0ExVWREd1FFQXdJQlJqQVZCZ05WCitIU0FFRGpBTU1Bb0dDQ3FCZWdGNUFRRUJNQjBHQTFVZERnUVdCQlNqQlM4WVlGRENpUXJkS3lGUC80NU9xREF4CitOakFmQmdOVkhTTUVHREFXZ0JTakJTOFlZRkRDaVFyZEt5RlAvNDVPcURBeE5qQU5CZ2txaGtpRzl3MEJBUVVGCitBQU9DQVFFQUJkd20yUHAzRlVSby9DOW1PblRnWGVRcC93WUhFNFJLcTg5dG9COVJsUGhKeTNRMkZMd1YzZHVKCitMOTJQb0YxODlSTHJuNTQ0cEVmTXM1Ylp2cHdscXdOK013K1ZnUTM5RnVDSXZqZndiRjNRTVpzeUsxMFhaWk9ZCitZTHh1ajdHb1BCN1pIUE9wSmtMNVpCM0M1NUwyOUI1YXFobFNYYS9vb3ZkZ29QYU44SW4xYnVBS0JRR1Z5WXNnCitDcnBhL0pvc1BMM0R0OGxkZUNVRlAxWVVtd3phK3pwSS9wZHBYc29RaHZkT2xnUUlUZXl3dmwzY080NVB3ZjJhCitOalNhVEZSK0Z3TklsUWdSSEFkdmhRaCtYVTNFbmR2N3JzNnkwYk80ZzJ3ZHNyTjU4ZGh3bVg3d0V3TE9YdDFSCiswOTgyZ2FFYmVDOXhzL0ZaVEVZWUtLdUYwbUJXV2c9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgMzk6MTE6NDU6MTA6OTQKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1GUiwgU1Q9RnJhbmNlLCBMPVBhcmlzLCBPPVBNL1NHRE4sIE9VPURDU1NJLCBDTj1JR0MvQS9lbWFpbEFkZHJlc3M9aWdjYUBzZ2RuLnBtLmdvdXYuZnIKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IERlYyAxMyAxNDoyOToyMyAyMDAyIEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogT2N0IDE3IDE0OjI5OjIyIDIwMjAgR01UCisgICAgICAgIFN1YmplY3Q6IEM9RlIsIFNUPUZyYW5jZSwgTD1QYXJpcywgTz1QTS9TR0ROLCBPVT1EQ1NTSSwgQ049SUdDL0EvZW1haWxBZGRyZXNzPWlnY2FAc2dkbi5wbS5nb3V2LmZyCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpiMjoxZjpkMTpkMDo2MjpjNTozMzozYjpjMDowNDo4Njo4ODpiMzpkYzoKKyAgICAgICAgICAgICAgICAgICAgZjg6ODg6Zjc6ZmQ6ZGY6NDM6ZGY6N2E6OGQ6OWE6NDk6NWM6ZjY6NGU6YWE6CisgICAgICAgICAgICAgICAgICAgIGNjOjFjOmI5OmExOmViOjI3Ojg5OmYyOjQ2OmU5OjNiOjRhOjcxOmQ1OjFkOgorICAgICAgICAgICAgICAgICAgICA4ZToyZDpjZjplNjphZDphYjo2Mzo1MDpjNzo1NDowYjo2ZToxMjpjOTo5MDoKKyAgICAgICAgICAgICAgICAgICAgMzY6YzY6ZDg6MmY6ZGE6OTE6YWE6Njg6YzU6NzI6ZmU6MTc6MGE6YjI6MTc6CisgICAgICAgICAgICAgICAgICAgIDdlOjc5OmI1OjMyOjg4OjcwOmNhOjcwOmMwOjk2OjRhOjhlOmU0OjU1OmNkOgorICAgICAgICAgICAgICAgICAgICAxZDoyNzo5NDpiZjpjZTo3MjoyYTplYzo1YzpmOTo3MzoyMDpmZTpiZDpmNzoKKyAgICAgICAgICAgICAgICAgICAgMmU6ODk6Njc6Yjg6YmI6NDc6NzM6MTI6Zjc6ZDE6MzU6Njk6M2E6ZjI6MGE6CisgICAgICAgICAgICAgICAgICAgIGI5OmFlOmZmOjQ2OjQyOjQ2OmEyOmJmOmExOjg1OjFhOmY5OmJmOmU0OmZmOgorICAgICAgICAgICAgICAgICAgICA0OTo4NTpmNzphMzo3MDo4NjozMjoxYzo1ZDo5Zjo2MDpmNzphOTphZDphNToKKyAgICAgICAgICAgICAgICAgICAgZmY6Y2Y6ZDE6MzQ6Zjk6N2Q6NWI6MTc6YzY6ZGM6ZDY6MGU6Mjg6NmI6YzI6CisgICAgICAgICAgICAgICAgICAgIGRkOmYxOmY1OjMzOjY4OjlkOjRlOmZjOjg3OjdjOjM2OjEyOmQ2OmEzOjgwOgorICAgICAgICAgICAgICAgICAgICBlODo0MzowZDo1NTo2MTo5NDplYTo2NDozNzo0NzplYTo3NzpjYTpkMDpiMjoKKyAgICAgICAgICAgICAgICAgICAgNTg6MDU6YzM6NWQ6N2U6YjE6YTg6NDY6OTA6MzE6NTY6Y2U6NzA6MmE6OTY6CisgICAgICAgICAgICAgICAgICAgIGIyOjMwOmI4Ojc3OmU2Ojc5OmMwOmJkOjI5OjNiOmZkOjk0Ojc3OjRjOmJkOgorICAgICAgICAgICAgICAgICAgICAyMDpjZDo0MToyNTplMDoyZTpjNzoxYjpiYjplZTphNDowNDo0MTpkMjo1ZDoKKyAgICAgICAgICAgICAgICAgICAgYWQ6MTI6NmE6OGE6OWI6NDc6ZmI6Yzk6ZGQ6NDY6NDA6ZTE6OWQ6M2M6MzM6CisgICAgICAgICAgICAgICAgICAgIGQwOmI1CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiAKKyAgICAgICAgICAgICAgICBOb24gUmVwdWRpYXRpb24sIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQ2VydGlmaWNhdGUgUG9saWNpZXM6IAorICAgICAgICAgICAgICAgIFBvbGljeTogMS4yLjI1MC4xLjEyMS4xLjEuMQorCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgQTM6MDU6MkY6MTg6NjA6NTA6QzI6ODk6MEE6REQ6MkI6MjE6NEY6RkY6OEU6NEU6QTg6MzA6MzE6MzYKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOkEzOjA1OjJGOjE4OjYwOjUwOkMyOjg5OjBBOkREOjJCOjIxOjRGOkZGOjhFOjRFOkE4OjMwOjMxOjM2CisKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMDU6ZGM6MjY6ZDg6ZmE6Nzc6MTU6NDQ6Njg6ZmM6MmY6NjY6M2E6NzQ6ZTA6NWQ6ZTQ6Mjk6CisgICAgICAgIGZmOjA2OjA3OjEzOjg0OjRhOmFiOmNmOjZkOmEwOjFmOjUxOjk0OmY4OjQ5OmNiOjc0OjM2OgorICAgICAgICAxNDpiYzoxNTpkZDpkYjo4OToyZjpkZDo4ZjphMDo1ZDo3YzpmNToxMjplYjo5Zjo5ZTozODoKKyAgICAgICAgYTQ6NDc6Y2M6YjM6OTY6ZDk6YmU6OWM6MjU6YWI6MDM6N2U6MzM6MGY6OTU6ODE6MGQ6ZmQ6CisgICAgICAgIDE2OmUwOjg4OmJlOjM3OmYwOjZjOjVkOmQwOjMxOjliOjMyOjJiOjVkOjE3OjY1OjkzOjk4OgorICAgICAgICA2MDpiYzo2ZTo4ZjpiMTphODozYzoxZTpkOToxYzpmMzphOToyNjo0MjpmOTo2NDoxZDpjMjoKKyAgICAgICAgZTc6OTI6ZjY6ZjQ6MWU6NWE6YWE6MTk6NTI6NWQ6YWY6ZTg6YTI6Zjc6NjA6YTA6ZjY6OGQ6CisgICAgICAgIGYwOjg5OmY1OjZlOmUwOjBhOjA1OjAxOjk1OmM5OjhiOjIwOjBhOmJhOjVhOmZjOjlhOjJjOgorICAgICAgICAzYzpiZDpjMzpiNzpjOTo1ZDo3ODoyNTowNTozZjo1NjoxNDo5YjowYzpkYTpmYjozYTo0ODoKKyAgICAgICAgZmU6OTc6Njk6NWU6Y2E6MTA6ODY6Zjc6NGU6OTY6MDQ6MDg6NGQ6ZWM6YjA6YmU6NWQ6ZGM6CisgICAgICAgIDNiOjhlOjRmOmMxOmZkOjlhOjM2OjM0OjlhOjRjOjU0OjdlOjE3OjAzOjQ4Ojk1OjA4OjExOgorICAgICAgICAxYzowNzo2Zjo4NTowODo3ZTo1ZDo0ZDpjNDo5ZDpkYjpmYjphZTpjZTpiMjpkMTpiMzpiODoKKyAgICAgICAgODM6NmM6MWQ6YjI6YjM6Nzk6ZjE6ZDg6NzA6OTk6N2U6ZjA6MTM6MDI6Y2U6NWU6ZGQ6NTE6CisgICAgICAgIGQzOmRmOjM2OjgxOmExOjFiOjc4OjJmOjcxOmIzOmYxOjU5OjRjOjQ2OjE4OjI4OmFiOjg1OgorICAgICAgICBkMjo2MDo1Njo1YQorU0hBMSBGaW5nZXJwcmludD02MDpENjo4OTo3NDpCNTpDMjo2NTo5RTo4QTowRjpDMTo4ODo3Qzo4ODpEMjo0Njo2OToxQjoxODoyQwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzU5NGYxNzc1LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNTk0ZjE3NzUuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNjMyYzhhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzU5NGYxNzc1LjAKQEAgLTAsMCArMSw3MCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlESURDQ0FvbWdBd0lCQWdJRU5kNzB6ekFOQmdrcWhraUc5dzBCQVFVRkFEQk9NUXN3Q1FZRFZRUUdFd0pWCitVekVRTUE0R0ExVUVDaE1IUlhGMWFXWmhlREV0TUNzR0ExVUVDeE1rUlhGMWFXWmhlQ0JUWldOMWNtVWdRMlZ5CitkR2xtYVdOaGRHVWdRWFYwYUc5eWFYUjVNQjRYRFRrNE1EZ3lNakUyTkRFMU1Wb1hEVEU0TURneU1qRTJOREUxCitNVm93VGpFTE1Ba0dBMVVFQmhNQ1ZWTXhFREFPQmdOVkJBb1RCMFZ4ZFdsbVlYZ3hMVEFyQmdOVkJBc1RKRVZ4CitkV2xtWVhnZ1UyVmpkWEpsSUVObGNuUnBabWxqWVhSbElFRjFkR2h2Y21sMGVUQ0JuekFOQmdrcWhraUc5dzBCCitBUUVGQUFPQmpRQXdnWWtDZ1lFQXdWMnhXR2NJWXU2Z21pMGZDRzJSRkdpWUNoNysyZ1J2RTRSaUljUFJmTTZmCitCZUM0QWZCT05PemlpcFVFWkt6eGExTmZCYlBMWjRDL1FnS08vdDBCQ2V6aEFCUlAvUHZ3RE4xRHVsc3I0UitBCitjSmtWVjVNVzhRK1hhcmZDYUNNY3pFMVpNS3hSSGp1dks5YnVZMFY3eGRsZlVOTGpVQTg2aU9lL0ZQM2d4N2tDCitBd0VBQWFPQ0FRa3dnZ0VGTUhBR0ExVWRId1JwTUdjd1phQmpvR0drWHpCZE1Rc3dDUVlEVlFRR0V3SlZVekVRCitNQTRHQTFVRUNoTUhSWEYxYVdaaGVERXRNQ3NHQTFVRUN4TWtSWEYxYVdaaGVDQlRaV04xY21VZ1EyVnlkR2xtCithV05oZEdVZ1FYVjBhRzl5YVhSNU1RMHdDd1lEVlFRREV3UkRVa3d4TUJvR0ExVWRFQVFUTUJHQkR6SXdNVGd3CitPREl5TVRZME1UVXhXakFMQmdOVkhROEVCQU1DQVFZd0h3WURWUjBqQkJnd0ZvQVVTT1pvK1N2U3NwWFhSOWdqCitJQkJQTTVpUW45UXdIUVlEVlIwT0JCWUVGRWptYVBrcjByS1YxMGZZSXlBUVR6T1lrSi9VTUF3R0ExVWRFd1FGCitNQU1CQWY4d0dnWUpLb1pJaHZaOUIwRUFCQTB3Q3hzRlZqTXVNR01EQWdiQU1BMEdDU3FHU0liM0RRRUJCUVVBCitBNEdCQUZqT0tlcjg5OTYxemdLNUY3V0YwYm5qNEpYTUpURU5BS2FTYm4rMmttT2VVSlhSbW0va0VkNWpoVzZZCis3cWovV3NqVFZiSm1jVmZld0NIclBTcW5JMGtCQklaQ2UvenVmNklXVXJWblo5TkEyenNtV0xJb2R6MnVGSGRoCisxdm9xWmllZ0RmcW5jMXpxY1BHVUlXVkVYL3I4N3lsb3FhS0hlZTk1NzArc0IzYzQKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogOTAzODA0MTExICgweDM1ZGVmNGNmKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPUVxdWlmYXgsIE9VPUVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogQXVnIDIyIDE2OjQxOjUxIDE5OTggR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBBdWcgMjIgMTY6NDE6NTEgMjAxOCBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgTz1FcXVpZmF4LCBPVT1FcXVpZmF4IFNlY3VyZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgxMDI0IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgxMDI0IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmMxOjVkOmIxOjU4OjY3OjA4OjYyOmVlOmEwOjlhOjJkOjFmOjA4OjZkOgorICAgICAgICAgICAgICAgICAgICA5MToxNDo2ODo5ODowYToxZTpmZTpkYTowNDo2ZjoxMzo4NDo2MjoyMTpjMzoKKyAgICAgICAgICAgICAgICAgICAgZDE6N2M6Y2U6OWY6MDU6ZTA6Yjg6MDE6ZjA6NGU6MzQ6ZWM6ZTI6OGE6OTU6CisgICAgICAgICAgICAgICAgICAgIDA0OjY0OmFjOmYxOjZiOjUzOjVmOjA1OmIzOmNiOjY3OjgwOmJmOjQyOjAyOgorICAgICAgICAgICAgICAgICAgICA4ZTpmZTpkZDowMTowOTplYzplMTowMDoxNDo0ZjpmYzpmYjpmMDowYzpkZDoKKyAgICAgICAgICAgICAgICAgICAgNDM6YmE6NWI6MmI6ZTE6MWY6ODA6NzA6OTk6MTU6NTc6OTM6MTY6ZjE6MGY6CisgICAgICAgICAgICAgICAgICAgIDk3OjZhOmI3OmMyOjY4OjIzOjFjOmNjOjRkOjU5OjMwOmFjOjUxOjFlOjNiOgorICAgICAgICAgICAgICAgICAgICBhZjoyYjpkNjplZTo2Mzo0NTo3YjpjNTpkOTo1Zjo1MDpkMjplMzo1MDowZjoKKyAgICAgICAgICAgICAgICAgICAgM2E6ODg6ZTc6YmY6MTQ6ZmQ6ZTA6Yzc6YjkKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIENSTCBEaXN0cmlidXRpb24gUG9pbnRzOiAKKyAgICAgICAgICAgICAgICBEaXJOYW1lOi9DPVVTL089RXF1aWZheC9PVT1FcXVpZmF4IFNlY3VyZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkvQ049Q1JMMQorCisgICAgICAgICAgICBYNTA5djMgUHJpdmF0ZSBLZXkgVXNhZ2UgUGVyaW9kOiAKKyAgICAgICAgICAgICAgICBOb3QgQWZ0ZXI6IEF1ZyAyMiAxNjo0MTo1MSAyMDE4IEdNVAorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOjQ4OkU2OjY4OkY5OjJCOkQyOkIyOjk1OkQ3OjQ3OkQ4OjIzOjIwOjEwOjRGOjMzOjk4OjkwOjlGOkQ0CisKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICA0ODpFNjo2ODpGOToyQjpEMjpCMjo5NTpENzo0NzpEODoyMzoyMDoxMDo0RjozMzo5ODo5MDo5RjpENAorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiAKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICAxLjIuODQwLjExMzUzMy43LjY1LjA6IAorICAgICAgICAgICAgICAgIDAuLi5WMy4wYy4uLi4KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgNTg6Y2U6Mjk6ZWE6ZmM6Zjc6ZGU6YjU6Y2U6MDI6Yjk6MTc6YjU6ODU6ZDE6Yjk6ZTM6ZTA6CisgICAgICAgIDk1OmNjOjI1OjMxOjBkOjAwOmE2OjkyOjZlOjdmOmI2OjkyOjYzOjllOjUwOjk1OmQxOjlhOgorICAgICAgICA2ZjplNDoxMTpkZTo2Mzo4NTo2ZTo5ODplZTphODpmZjo1YTpjODpkMzo1NTpiMjo2Njo3MToKKyAgICAgICAgNTc6ZGU6YzA6MjE6ZWI6M2Q6MmE6YTc6MjM6NDk6MDE6MDQ6ODY6NDI6N2I6ZmM6ZWU6N2Y6CisgICAgICAgIGEyOjE2OjUyOmI1OjY3OjY3OmQzOjQwOmRiOjNiOjI2OjU4OmIyOjI4Ojc3OjNkOmFlOjE0OgorICAgICAgICA3Nzo2MTpkNjpmYToyYTo2NjoyNzphMDowZDpmYTphNzo3Mzo1YzplYTo3MDpmMTo5NDoyMToKKyAgICAgICAgNjU6NDQ6NWY6ZmE6ZmM6ZWY6Mjk6Njg6YTk6YTI6ODc6Nzk6ZWY6Nzk6ZWY6NGY6YWM6MDc6CisgICAgICAgIDc3OjM4CitTSEExIEZpbmdlcnByaW50PUQyOjMyOjA5OkFEOjIzOkQzOjE0OjIzOjIxOjc0OkU0OjBEOjdGOjlEOjYyOjEzOjk3Ojg2OjYzOjNBCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNWEzZjBmZjguMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy81YTNmMGZmOC4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVjOWU2NWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNWEzZjBmZjguMApAQCAtMCwwICsxLDg2IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUVIVENDQXdXZ0F3SUJBZ0lRVG9FdGlvSmw0QXNDN2o0MUFrYmxQVEFOQmdrcWhraUc5dzBCQVFVRkFEQ0IKK2dURUxNQWtHQTFVRUJoTUNSMEl4R3pBWkJnTlZCQWdURWtkeVpXRjBaWElnVFdGdVkyaGxjM1JsY2pFUU1BNEcKK0ExVUVCeE1IVTJGc1ptOXlaREVhTUJnR0ExVUVDaE1SUTA5TlQwUlBJRU5CSUV4cGJXbDBaV1F4SnpBbEJnTlYKK0JBTVRIa05QVFU5RVR5QkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVRBZUZ3MHdOakV5TURFd01EQXcKK01EQmFGdzB5T1RFeU16RXlNelU1TlRsYU1JR0JNUXN3Q1FZRFZRUUdFd0pIUWpFYk1Ca0dBMVVFQ0JNU1IzSmwKK1lYUmxjaUJOWVc1amFHVnpkR1Z5TVJBd0RnWURWUVFIRXdkVFlXeG1iM0prTVJvd0dBWURWUVFLRXhGRFQwMVAKK1JFOGdRMEVnVEdsdGFYUmxaREVuTUNVR0ExVUVBeE1lUTA5TlQwUlBJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjAKK2FHOXlhWFI1TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUEwRUNMaTNMamtSdjMKK1VjRWJWQVNZMDZtL3dlYUtYVHVIKzd1SXpnM2pMejhHbHZDaUtWQ1pydHM3b1Zld2RGRnh6ZTFDa1UxQi9xbkkKKzJHcUdkMFM3V1dhWFVGNjAxQ3h3Uk0vYU41VkNhVHd3eEhHelV2QWhUYUhZdWpsOEhKNmpKSjN5Z3hhWXFoWjgKK1E1c1ZXN2V1TkpIKzFHSW1HRWFhUCt2QitmR1FWK3VzZWcyTDIzSXdhbWJWNEVhamNOeG8yZjhFU0lsMzNyWHAKKysyZHRRZW04T2IweTJXSUM4YkdvUFc0M25PSXY0dE9pSm92R3VGVkRpT0VqUHFYU0pEbHFSNnNBMUtHenFTWCsKK0RUK25IYnJUVWNFTHBOcXNPTzlWVUNRRlpVYVRORTh0amEzRzFDRVowbzdLQldGeEIzTkg1WW9aRXIwRVRjNU8KK25LVklyTHNtOXdJREFRQUJvNEdPTUlHTE1CMEdBMVVkRGdRV0JCUUxXT1dMeGt3Vk42UkFxVENwSWI1SE5scFcKKy96QU9CZ05WSFE4QkFmOEVCQU1DQVFZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pCSkJnTlZIUjhFUWpCQU1ENmcKK1BLQTZoamhvZEhSd09pOHZZM0pzTG1OdmJXOWtiMk5oTG1OdmJTOURUMDFQUkU5RFpYSjBhV1pwWTJGMGFXOXUKK1FYVjBhRzl5YVhSNUxtTnliREFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBUHBpZW0vWWI2ZGM1dDNpdUhYSVkKK1NkT0g1RU9DNnovSnF2V290ZTlWZkNGU1pmblZEZUZzOUQ2TWszT1JMZ0xFVGdkeGI4Q1BPR0VJcUI2QkNzQXYKK0lDOUJpNUhjU0VXODhjYmV1blpyTThnQUxURkdUTzNubmMrSWxQOHp3RmJvSklZbXVOZzRPTjhxYTkwU3pNYy8KK1J4ZE1vc0lHbGduVzIvNC9QRVpCMzFqaVZnODhPOEVja3pYWk9GS3M3c2pzTGpCT2xEVzBKQjlMZUduYThnSTQKK3pKVlNrL0J3SlZtY0lHZkU3dm1MVjJIMGtuWjlQNFNOVmJmbzVhelY4ZlVaVnFaYSs1QWNyNVByNVJ6VVo1ZGQKK0JBNitDNE9tRjRPNU1CS2d4VE1WQmJrTis4Y0ZkdVBZU28zOE5CZWp4aUVvdmpCRk1SN0hlTDVZWVRpc08rSUIKK1pRPT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDRlOjgxOjJkOjhhOjgyOjY1OmUwOjBiOjAyOmVlOjNlOjM1OjAyOjQ2OmU1OjNkCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9R0IsIFNUPUdyZWF0ZXIgTWFuY2hlc3RlciwgTD1TYWxmb3JkLCBPPUNPTU9ETyBDQSBMaW1pdGVkLCBDTj1DT01PRE8gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IERlYyAgMSAwMDowMDowMCAyMDA2IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogRGVjIDMxIDIzOjU5OjU5IDIwMjkgR01UCisgICAgICAgIFN1YmplY3Q6IEM9R0IsIFNUPUdyZWF0ZXIgTWFuY2hlc3RlciwgTD1TYWxmb3JkLCBPPUNPTU9ETyBDQSBMaW1pdGVkLCBDTj1DT01PRE8gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmQwOjQwOjhiOjhiOjcyOmUzOjkxOjFiOmY3OjUxOmMxOjFiOjU0OjA0OgorICAgICAgICAgICAgICAgICAgICA5ODpkMzphOTpiZjpjMTplNjo4YTo1ZDozYjo4NzpmYjpiYjo4ODpjZTowZDoKKyAgICAgICAgICAgICAgICAgICAgZTM6MmY6M2Y6MDY6OTY6ZjA6YTI6Mjk6NTA6OTk6YWU6ZGI6M2I6YTE6NTc6CisgICAgICAgICAgICAgICAgICAgIGIwOjc0OjUxOjcxOmNkOmVkOjQyOjkxOjRkOjQxOmZlOmE5OmM4OmQ4OjZhOgorICAgICAgICAgICAgICAgICAgICA4Njo3Nzo0NDpiYjo1OTo2Njo5Nzo1MDo1ZTpiNDpkNDoyYzo3MDo0NDpjZjoKKyAgICAgICAgICAgICAgICAgICAgZGE6Mzc6OTU6NDI6Njk6M2M6MzA6YzQ6NzE6YjM6NTI6ZjA6MjE6NGQ6YTE6CisgICAgICAgICAgICAgICAgICAgIGQ4OmJhOjM5OjdjOjFjOjllOmEzOjI0OjlkOmYyOjgzOjE2Ojk4OmFhOjE2OgorICAgICAgICAgICAgICAgICAgICA3Yzo0Mzo5YjoxNTo1YjpiNzphZTozNDo5MTpmZTpkNDo2MjoyNjoxODo0NjoKKyAgICAgICAgICAgICAgICAgICAgOWE6M2Y6ZWI6YzE6Zjk6ZjE6OTA6NTc6ZWI6YWM6N2E6MGQ6OGI6ZGI6NzI6CisgICAgICAgICAgICAgICAgICAgIDMwOjZhOjY2OmQ1OmUwOjQ2OmEzOjcwOmRjOjY4OmQ5OmZmOjA0OjQ4Ojg5OgorICAgICAgICAgICAgICAgICAgICA3NzpkZTpiNTplOTpmYjo2Nzo2ZDo0MTplOTpiYzozOTpiZDozMjpkOTo2MjoKKyAgICAgICAgICAgICAgICAgICAgMDI6ZjE6YjE6YTg6M2Q6NmU6Mzc6OWM6ZTI6MmY6ZTI6ZDM6YTI6MjY6OGI6CisgICAgICAgICAgICAgICAgICAgIGM2OmI4OjU1OjQzOjg4OmUxOjIzOjNlOmE1OmQyOjI0OjM5OjZhOjQ3OmFiOgorICAgICAgICAgICAgICAgICAgICAwMDpkNDphMTpiMzphOToyNTpmZTowZDozZjphNzoxZDpiYTpkMzo1MTpjMToKKyAgICAgICAgICAgICAgICAgICAgMGI6YTQ6ZGE6YWM6Mzg6ZWY6NTU6NTA6MjQ6MDU6NjU6NDY6OTM6MzQ6NGY6CisgICAgICAgICAgICAgICAgICAgIDJkOjhkOmFkOmM2OmQ0OjIxOjE5OmQyOjhlOmNhOjA1OjYxOjcxOjA3OjczOgorICAgICAgICAgICAgICAgICAgICA0NzplNTo4YToxOToxMjpiZDowNDo0ZDpjZTo0ZTo5YzphNTo0ODphYzpiYjoKKyAgICAgICAgICAgICAgICAgICAgMjY6ZjcKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDBCOjU4OkU1OjhCOkM2OjRDOjE1OjM3OkE0OjQwOkE5OjMwOkE5OjIxOkJFOjQ3OjM2OjVBOjU2OkZGCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIENSTCBEaXN0cmlidXRpb24gUG9pbnRzOiAKKyAgICAgICAgICAgICAgICBVUkk6aHR0cDovL2NybC5jb21vZG9jYS5jb20vQ09NT0RPQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmwKKworICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAzZTo5ODo5ZTo5YjpmNjoxYjplOTpkNzozOTpiNzo3ODphZToxZDo3MjoxODo0OTpkMzo4NzoKKyAgICAgICAgZTQ6NDM6ODI6ZWI6M2Y6Yzk6YWE6ZjU6YTg6YjU6ZWY6NTU6N2M6MjE6NTI6NjU6Zjk6ZDU6CisgICAgICAgIDBkOmUxOjZjOmY0OjNlOjhjOjkzOjczOjkxOjJlOjAyOmM0OjRlOjA3OjcxOjZmOmMwOjhmOgorICAgICAgICAzODo2MTowODphODoxZTo4MTowYTpjMDoyZjoyMDoyZjo0MTo4Yjo5MTpkYzo0ODo0NTpiYzoKKyAgICAgICAgZjE6YzY6ZGU6YmE6NzY6NmI6MzM6Yzg6MDA6MmQ6MzE6NDY6NGM6ZWQ6ZTc6OWQ6Y2Y6ODg6CisgICAgICAgIDk0OmZmOjMzOmMwOjU2OmU4OjI0Ojg2OjI2OmI4OmQ4OjM4OjM4OmRmOjJhOjZiOmRkOjEyOgorICAgICAgICBjYzpjNzozZjo0NzoxNzo0YzphMjpjMjowNjo5NjowOTpkNjpkYjpmZTozZjozYzo0Njo0MToKKyAgICAgICAgZGY6NTg6ZTI6NTY6MGY6M2M6M2I6YzE6MWM6OTM6MzU6ZDk6Mzg6NTI6YWM6ZWU6Yzg6ZWM6CisgICAgICAgIDJlOjMwOjRlOjk0OjM1OmI0OjI0OjFmOjRiOjc4OjY5OmRhOmYyOjAyOjM4OmNjOjk1OjUyOgorICAgICAgICA5MzpmMDo3MDoyNTo1OTo5YzoyMDo2NzpjNDplZTpmOTo4Yjo1Nzo2MTpmNDo5Mjo3Njo3ZDoKKyAgICAgICAgM2Y6ODQ6OGQ6NTU6Yjc6ZTg6ZTU6YWM6ZDU6ZjE6ZjU6MTk6NTY6YTY6NWE6ZmI6OTA6MWM6CisgICAgICAgIGFmOjkzOmViOmU1OjFjOmQ0OjY3Ojk3OjVkOjA0OjBlOmJlOjBiOjgzOmE2OjE3OjgzOmI5OgorICAgICAgICAzMDoxMjphMDpjNTozMzoxNTowNTpiOTowZDpmYjpjNzowNTo3NjplMzpkODo0YTo4ZDpmYzoKKyAgICAgICAgMzQ6MTc6YTM6YzY6MjE6Mjg6YmU6MzA6NDU6MzE6MWU6Yzc6Nzg6YmU6NTg6NjE6Mzg6YWM6CisgICAgICAgIDNiOmUyOjAxOjY1CitTSEExIEZpbmdlcnByaW50PTY2OjMxOkJGOjlFOkY3OjRGOjlFOkI2OkM5OkQ1OkE2OjBDOkJBOjZBOkJFOkQxOkY3OkJEOkVGOjdCCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNWE1MzcyZmMuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy81YTUzNzJmYy4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZiNGY3MGMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNWE1MzcyZmMuMApAQCAtMCwwICsxLDc0IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUZTekNDQkxTZ0F3SUJBZ0lCYVRBTkJna3Foa2lHOXcwQkFRUUZBRENCbVRFTE1Ba0dBMVVFQmhNQ1NGVXgKK0VUQVBCZ05WQkFjVENFSjFaR0Z3WlhOME1TY3dKUVlEVlFRS0V4NU9aWFJNYjJOcklFaGhiRzk2WVhSaWFYcDAKK2IyNXpZV2RwSUV0bWRDNHhHakFZQmdOVkJBc1RFVlJoYm5WemFYUjJZVzU1YTJsaFpHOXJNVEl3TUFZRFZRUUQKK0V5bE9aWFJNYjJOcklGVjZiR1YwYVNBb1EyeGhjM01nUWlrZ1ZHRnVkWE5wZEhaaGJubHJhV0ZrYnpBZUZ3MDUKK09UQXlNalV4TkRFd01qSmFGdzB4T1RBeU1qQXhOREV3TWpKYU1JR1pNUXN3Q1FZRFZRUUdFd0pJVlRFUk1BOEcKK0ExVUVCeE1JUW5Wa1lYQmxjM1F4SnpBbEJnTlZCQW9USGs1bGRFeHZZMnNnU0dGc2IzcGhkR0pwZW5SdmJuTmgKK1oya2dTMlowTGpFYU1CZ0dBMVVFQ3hNUlZHRnVkWE5wZEhaaGJubHJhV0ZrYjJzeE1qQXdCZ05WQkFNVEtVNWwKK2RFeHZZMnNnVlhwc1pYUnBJQ2hEYkdGemN5QkNLU0JVWVc1MWMybDBkbUZ1ZVd0cFlXUnZNSUdmTUEwR0NTcUcKK1NJYjNEUUVCQVFVQUE0R05BRENCaVFLQmdRQ3g2Z1RzSUtBandvODRZTS9IUnJQVkcvNzd1Wm1lQk53Y2Y0eEsKK2daanVwTlRLaWhlNUluK0RDblZNbThCcDJHUTVvKzJTby8xYlhIUWF3RWZLT21sMm1ycmlSQmY4VEtQVi9yaVgKK2lLK0lBNGtmcFBJRVBzZ0hDK2I1c3k5NlloUUpSaFRLWlBXTGdMVmlxTmhyMW5HVExiTy9DVlJZN1FicnFIdmMKK1E3R2hhUUlEQVFBQm80SUNuekNDQXBzd0VnWURWUjBUQVFIL0JBZ3dCZ0VCL3dJQkJEQU9CZ05WSFE4QkFmOEUKK0JBTUNBQVl3RVFZSllJWklBWWI0UWdFQkJBUURBZ0FITUlJQ1lBWUpZSVpJQVliNFFnRU5CSUlDVVJhQ0FrMUcKK1NVZFpSVXhGVFNFZ1JYcGxiaUIwWVc1MWMybDBkbUZ1ZVNCaElFNWxkRXh2WTJzZ1MyWjBMaUJCYkhSaGJHRnUKK2IzTWdVM3B2YkdkaGJIUmhkR0Z6YVNCR1pXeDBaWFJsYkdWcFltVnVJR3hsYVhKMElHVnNhbUZ5WVhOdmF5QmgKK2JHRndhbUZ1SUd0bGMzcDFiSFF1SUVFZ2FHbDBaV3hsYzJsMFpYTWdabTlzZVdGdFlYUmhkQ0JoSUU1bGRFeHYKK1kyc2dTMlowTGlCMFpYSnRaV3RtWld4bGJHOXpjMlZuTFdKcGVuUnZjMmwwWVhOaElIWmxaR2t1SUVFZ1pHbG4KK2FYUmhiR2x6SUdGc1lXbHlZWE1nWld4bWIyZGhaR0Z6WVc1aGF5Qm1aV3gwWlhSbGJHVWdZWG9nWld4dmFYSjAKK0lHVnNiR1Z1YjNKNlpYTnBJR1ZzYW1GeVlYTWdiV1ZuZEdWMFpXeGxMaUJCZWlCbGJHcGhjbUZ6SUd4bGFYSmgKK2MyRWdiV1ZuZEdGc1lXeG9ZWFJ2SUdFZ1RtVjBURzlqYXlCTFpuUXVJRWx1ZEdWeWJtVjBJR2h2Ym14aGNHcGgKK2JpQmhJR2gwZEhCek9pOHZkM2QzTG01bGRHeHZZMnN1Ym1WMEwyUnZZM01nWTJsdFpXNGdkbUZuZVNCclpYSm8KK1pYUnZJR0Y2SUdWc2JHVnViM0o2WlhOQWJtVjBiRzlqYXk1dVpYUWdaUzF0WVdsc0lHTnBiV1Z1TGlCSlRWQlAKK1VsUkJUbFFoSUZSb1pTQnBjM04xWVc1alpTQmhibVFnZEdobElIVnpaU0J2WmlCMGFHbHpJR05sY25ScFptbGoKK1lYUmxJR2x6SUhOMVltcGxZM1FnZEc4Z2RHaGxJRTVsZEV4dlkyc2dRMUJUSUdGMllXbHNZV0pzWlNCaGRDQm8KK2RIUndjem92TDNkM2R5NXVaWFJzYjJOckxtNWxkQzlrYjJOeklHOXlJR0o1SUdVdGJXRnBiQ0JoZENCamNITkEKK2JtVjBiRzlqYXk1dVpYUXVNQTBHQ1NxR1NJYjNEUUVCQkFVQUE0R0JBQVRicm93WHIvZ09rREZPelQ0SndHMDYKK3NQZ3pURWRNNDNXSUVKZXNzRGdWa2NZcGxzd2h3RzA4cFhUUDJJS2xPY05sNDBKd3V5S1E0MzNiTlhiaG9MWGEKK24zQnVreG93T1IwdzJ5N2pmTEtSc3RFM0tmcTUxaGRjUjAvakhUanJuOVY3bGFnb25oVkswZEhRS3dDWG9PS1MKK05pdGpyRmdCYXpNcFVJYUQ4UUZJCistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDEwNSAoMHg2OSkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogbWQ1V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPUhVLCBMPUJ1ZGFwZXN0LCBPPU5ldExvY2sgSGFsb3phdGJpenRvbnNhZ2kgS2Z0LiwgT1U9VGFudXNpdHZhbnlraWFkb2ssIENOPU5ldExvY2sgVXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBGZWIgMjUgMTQ6MTA6MjIgMTk5OSBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEZlYiAyMCAxNDoxMDoyMiAyMDE5IEdNVAorICAgICAgICBTdWJqZWN0OiBDPUhVLCBMPUJ1ZGFwZXN0LCBPPU5ldExvY2sgSGFsb3phdGJpenRvbnNhZ2kgS2Z0LiwgT1U9VGFudXNpdHZhbnlraWFkb2ssIENOPU5ldExvY2sgVXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMTAyNCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMTAyNCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpiMTplYTowNDplYzoyMDphMDoyMzpjMjo4ZjozODo2MDpjZjpjNzo0NjoKKyAgICAgICAgICAgICAgICAgICAgYjM6ZDU6MWI6ZmU6ZmI6Yjk6OTk6OWU6MDQ6ZGM6MWM6N2Y6OGM6NGE6ODE6CisgICAgICAgICAgICAgICAgICAgIDk4OmVlOmE0OmQ0OmNhOjhhOjE3OmI5OjIyOjdmOjgzOjBhOjc1OjRjOjliOgorICAgICAgICAgICAgICAgICAgICBjMDo2OTpkODo2NDozOTphMzplZDo5MjphMzpmZDo1Yjo1Yzo3NDoxYTpjMDoKKyAgICAgICAgICAgICAgICAgICAgNDc6Y2E6M2E6Njk6NzY6OWE6YmE6ZTI6NDQ6MTc6ZmM6NGM6YTM6ZDU6ZmU6CisgICAgICAgICAgICAgICAgICAgIGI4Ojk3Ojg4OmFmOjg4OjAzOjg5OjFmOmE0OmYyOjA0OjNlOmM4OjA3OjBiOgorICAgICAgICAgICAgICAgICAgICBlNjpmOTpiMzoyZjo3YTo2MjoxNDowOTo0NjoxNDpjYTo2NDpmNTo4Yjo4MDoKKyAgICAgICAgICAgICAgICAgICAgYjU6NjI6YTg6ZDg6NmI6ZDY6NzE6OTM6MmQ6YjM6YmY6MDk6NTQ6NTg6ZWQ6CisgICAgICAgICAgICAgICAgICAgIDA2OmViOmE4OjdiOmRjOjQzOmIxOmExOjY5CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFLCBwYXRobGVuOjQKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIE5ldHNjYXBlIENlcnQgVHlwZTogCisgICAgICAgICAgICAgICAgU1NMIENBLCBTL01JTUUgQ0EsIE9iamVjdCBTaWduaW5nIENBCisgICAgICAgICAgICBOZXRzY2FwZSBDb21tZW50OiAKKyAgICAgICAgICAgICAgICBGSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQuIEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNAbmV0bG9jay5uZXQuCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogbWQ1V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMDQ6ZGI6YWU6OGM6MTc6YWY6Zjg6MGU6OTA6MzE6NGU6Y2Q6M2U6MDk6YzA6NmQ6M2E6YjA6CisgICAgICAgIGY4OjMzOjRjOjQ3OjRjOmUzOjc1Ojg4OjEwOjk3OmFjOmIwOjM4OjE1OjkxOmM2OjI5Ojk2OgorICAgICAgICBjYzoyMTpjMDo2ZDozYzphNTo3NDpjZjpkODo4MjphNTozOTpjMzo2NTplMzo0Mjo3MDpiYjoKKyAgICAgICAgMjI6OTA6ZTM6N2Q6ZGI6MzU6NzY6ZTE6YTA6YjU6ZGE6OWY6NzA6NmU6OTM6MWE6MzA6Mzk6CisgICAgICAgIDFkOjMwOmRiOjJlOmUzOjdjOmIyOjkxOmIyOmQxOjM3OjI5OmZhOmI5OmQ2OjE3OjVjOjQ3OgorICAgICAgICA0ZjplMzoxZDozODplYjo5ZjpkNTo3Yjo5NTphODoyODo5ZToxNTo0YTpkMTpkMTpkMDoyYjoKKyAgICAgICAgMDA6OTc6YTA6ZTI6OTI6MzY6MmI6NjM6YWM6NTg6MDE6NmI6MzM6Mjk6NTA6ODY6ODM6ZjE6CisgICAgICAgIDAxOjQ4CitTSEExIEZpbmdlcnByaW50PTg3OjlGOjRCOkVFOjA1OkRGOjk4OjU4OjNCOkUzOjYwOkQ2OjMzOkU3OjBEOjNGOkZFOjk4OjcxOkFGCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNWNmOWQ1MzYuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy81Y2Y5ZDUzNi4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4MmQ3YWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNWNmOWQ1MzYuMApAQCAtMCwwICsxLDEwNSBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlGMERDQ0JMaWdBd0lCQWdJRU9yWlFpekFOQmdrcWhraUc5dzBCQVFVRkFEQi9NUXN3Q1FZRFZRUUdFd0pDCitUVEVaTUJjR0ExVUVDaE1RVVhWdlZtRmthWE1nVEdsdGFYUmxaREVsTUNNR0ExVUVDeE1jVW05dmRDQkRaWEowCithV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVEV1TUN3R0ExVUVBeE1sVVhWdlZtRmthWE1nVW05dmRDQkRaWEowCithV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVEFlRncwd01UQXpNVGt4T0RNek16TmFGdzB5TVRBek1UY3hPRE16CitNek5hTUg4eEN6QUpCZ05WQkFZVEFrSk5NUmt3RndZRFZRUUtFeEJSZFc5V1lXUnBjeUJNYVcxcGRHVmtNU1V3CitJd1lEVlFRTEV4eFNiMjkwSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNUzR3TEFZRFZRUURFeVZSCitkVzlXWVdScGN5QlNiMjkwSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNSUlCSWpBTkJna3Foa2lHCis5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBdjJHMWxWTzZWL3o2OG1jTE9ocmZFWUJrbGJUUnZNMTZ6L1lwCitsaTRrVkVBa09QY2FoZHhZVE11a0owS1gwSitEaXNQa0JnTmJBS1ZSSG5BRWRPTEIxRHFyMTYwN0J4Z0ZqdjJECityT3BtMlJnYmFJcjFWeHFZdXZYdGRqMTgyZDZVYWp0TEY4SFZqNzFsT0RxVjBEMVZOazdmZVZjeEtoN1lXV1ZKCitXQ0NZZnF0ZmZwL3AxazNzZzNTcHgyelk3aWxLaFNvR0ZQbFU1dFBhWlFlTFl6Y1MxOURzdzNzZ1FVU2o3Y3VnCitGK0Z4WmM0ZFpqSDNkZ0VaeUgwRFdMYVZTUjJtRWlib3hneDI0T05teStwZHBpYnU1Y3hmdldlbkFTY09vc3BVCit4YkY2bFIxeEhrb3BpZ1BjYWtYQnBCbGViemJOdzZLd3QvNWNPT0pTdlBoRVErYVF1d0lEQVFBQm80SUNVakNDCitBazR3UFFZSUt3WUJCUVVIQVFFRU1UQXZNQzBHQ0NzR0FRVUZCekFCaGlGb2RIUndjem92TDI5amMzQXVjWFZ2CitkbUZrYVhOdlptWnphRzl5WlM1amIyMHdEd1lEVlIwVEFRSC9CQVV3QXdFQi96Q0NBUm9HQTFVZElBU0NBUkV3CitnZ0VOTUlJQkNRWUpLd1lCQkFHK1dBQUJNSUg3TUlIVUJnZ3JCZ0VGQlFjQ0FqQ0J4eHFCeEZKbGJHbGhibU5sCitJRzl1SUhSb1pTQlJkVzlXWVdScGN5QlNiMjkwSUVObGNuUnBabWxqWVhSbElHSjVJR0Z1ZVNCd1lYSjBlU0JoCitjM04xYldWeklHRmpZMlZ3ZEdGdVkyVWdiMllnZEdobElIUm9aVzRnWVhCd2JHbGpZV0pzWlNCemRHRnVaR0Z5CitaQ0IwWlhKdGN5QmhibVFnWTI5dVpHbDBhVzl1Y3lCdlppQjFjMlVzSUdObGNuUnBabWxqWVhScGIyNGdjSEpoCitZM1JwWTJWekxDQmhibVFnZEdobElGRjFiMVpoWkdseklFTmxjblJwWm1sallYUmxJRkJ2YkdsamVTNHdJZ1lJCitLd1lCQlFVSEFnRVdGbWgwZEhBNkx5OTNkM2N1Y1hWdmRtRmthWE11WW0wd0hRWURWUjBPQkJZRUZJdExiZTNUCitLYmtHR2V3NU9hbndsNFJxeSsvZk1JR3VCZ05WSFNNRWdhWXdnYU9BRkl0TGJlM1RLYmtHR2V3NU9hbndsNFJxCit5Ky9mb1lHRXBJR0JNSDh4Q3pBSkJnTlZCQVlUQWtKTk1Sa3dGd1lEVlFRS0V4QlJkVzlXWVdScGN5Qk1hVzFwCitkR1ZrTVNVd0l3WURWUVFMRXh4U2IyOTBJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1TNHdMQVlECitWUVFERXlWUmRXOVdZV1JwY3lCU2IyOTBJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNWdnUTZ0bENMCitNQTRHQTFVZER3RUIvd1FFQXdJQkJqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFpdFFVdGY3MG1wS25HZFNrCitmbklZajlsb2ZGSWszV2R2T1hyRXFsNDk0bGl3VFhDWWhHSG9HK05wR0E3TyswZFFvRTcvOENRZnZiTE85U2Y4Cis3QzlUcW5ON0F6MTBidVlXbnV1bExzUy9WaWRRSzJLNnZrc2NQRlZjUVIwa3ZvSWdSMTNWUkg1NkZtamZmVTFSCitjSGhYSFRNZS9RS1puQXpOQ2dWUHg3dU9wSFg2U20yeGdJNEpWcm1jR21EK1hjSFhldHdSZU5EV1hjRzMxYTB5CittUU02aXN4VUpUa3hnWHNUSWxHNlJteWh1NTc2Qkd4SkpuU1AwblByekRDaTV1cFpJb2Y0bC9VTy9lck1rcVFXCit4RklZNmlIT3NmSG1oSUhsdXFtR0tQSkRXbDBTbmF3ZTJhamxDbXFuZjZDSEtjL3lpVTNVN01YaTVuclFOaU9LCitTblEyK1E9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiA5ODUwMjY2OTkgKDB4M2FiNjUwOGIpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9Qk0sIE89UXVvVmFkaXMgTGltaXRlZCwgT1U9Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSwgQ049UXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTWFyIDE5IDE4OjMzOjMzIDIwMDEgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBNYXIgMTcgMTg6MzM6MzMgMjAyMSBHTVQKKyAgICAgICAgU3ViamVjdDogQz1CTSwgTz1RdW9WYWRpcyBMaW1pdGVkLCBPVT1Sb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5LCBDTj1RdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5CisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpiZjo2MTpiNTo5NTo1MzpiYTo1NzpmYzpmYTpmMjo2NzowYjozYToxYToKKyAgICAgICAgICAgICAgICAgICAgZGY6MTE6ODA6NjQ6OTU6YjQ6ZDE6YmM6Y2Q6N2E6Y2Y6ZjY6Mjk6OTY6MmU6CisgICAgICAgICAgICAgICAgICAgIDI0OjU0OjQwOjI0OjM4OmY3OjFhOjg1OmRjOjU4OjRjOmNiOmE0OjI3OjQyOgorICAgICAgICAgICAgICAgICAgICA5NzpkMDo5Zjo4Mzo4YTpjMzplNDowNjowMzo1YjowMDphNTo1MToxZTo3MDoKKyAgICAgICAgICAgICAgICAgICAgMDQ6NzQ6ZTI6YzE6ZDQ6M2E6YWI6ZDc6YWQ6M2I6MDc6MTg6MDU6OGU6ZmQ6CisgICAgICAgICAgICAgICAgICAgIDgzOmFjOmVhOjY2OmQ5OjE4OjFiOjY4OjhhOmY1OjU3OjFhOjk4OmJhOmY1OgorICAgICAgICAgICAgICAgICAgICBlZDo3NjozZDo3YzpkOTpkZTo5NDo2YTozYjo0YjoxNzpjMTpkNTo4ZjpiZDoKKyAgICAgICAgICAgICAgICAgICAgNjU6Mzg6M2E6OTU6ZDA6M2Q6NTU6MzY6NGU6ZGY6Nzk6NTc6MzE6MmE6MWU6CisgICAgICAgICAgICAgICAgICAgIGQ4OjU5OjY1OjQ5OjU4OjIwOjk4OjdlOmFiOjVmOjdlOjlmOmU5OmQ2OjRkOgorICAgICAgICAgICAgICAgICAgICBlYzo4Mzo3NDphOTpjNzo2YzpkODplZToyOTo0YTo4NToyYTowNjoxNDpmOToKKyAgICAgICAgICAgICAgICAgICAgNTQ6ZTY6ZDM6ZGE6NjU6MDc6OGI6NjM6Mzc6MTI6ZDc6ZDA6ZWM6YzM6N2I6CisgICAgICAgICAgICAgICAgICAgIDIwOjQxOjQ0OmEzOmVkOmNiOmEwOjE3OmUxOjcxOjY1OmNlOjFkOjY2OjMxOgorICAgICAgICAgICAgICAgICAgICBmNzo3NjowMToxOTpjODo3ZDowMzo1ODpiNjo5NTo0OToxZDphNjoxMjoyNjoKKyAgICAgICAgICAgICAgICAgICAgZTg6YzY6MGM6NzY6ZTA6ZTM6NjY6Y2I6ZWE6NWQ6YTY6MjY6ZWU6ZTU6Y2M6CisgICAgICAgICAgICAgICAgICAgIDVmOmJkOjY3OmE3OjAxOjI3OjBlOmEyOmNhOjU0OmM1OmIxOjdhOjk1OjFkOgorICAgICAgICAgICAgICAgICAgICA3MToxZTo0YToyOTo4YTowMzpkYzo2YTo0NTpjMTphNDoxOTo1ZTo2ZjozNjoKKyAgICAgICAgICAgICAgICAgICAgY2Q6YzM6YTI6YjA6Yjc6ZmU6NWM6Mzg6ZTI6NTI6YmM6Zjg6NDQ6NDM6ZTY6CisgICAgICAgICAgICAgICAgICAgIDkwOmJiCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIEF1dGhvcml0eSBJbmZvcm1hdGlvbiBBY2Nlc3M6IAorICAgICAgICAgICAgICAgIE9DU1AgLSBVUkk6aHR0cHM6Ly9vY3NwLnF1b3ZhZGlzb2Zmc2hvcmUuY29tCisKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgQ2VydGlmaWNhdGUgUG9saWNpZXM6IAorICAgICAgICAgICAgICAgIFBvbGljeTogMS4zLjYuMS40LjEuODAyNC4wLjEKKyAgICAgICAgICAgICAgICAgIFVzZXIgTm90aWNlOgorICAgICAgICAgICAgICAgICAgICBFeHBsaWNpdCBUZXh0OiBSZWxpYW5jZSBvbiB0aGUgUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2NlcHRhbmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0aW9uIHByYWN0aWNlcywgYW5kIHRoZSBRdW9WYWRpcyBDZXJ0aWZpY2F0ZSBQb2xpY3kuCisgICAgICAgICAgICAgICAgICBDUFM6IGh0dHA6Ly93d3cucXVvdmFkaXMuYm0KKworICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDhCOjRCOjZEOkVEOkQzOjI5OkI5OjA2OjE5OkVDOjM5OjM5OkE5OkYwOjk3Ojg0OjZBOkNCOkVGOkRGCisgICAgICAgICAgICBYNTA5djMgQXV0aG9yaXR5IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBrZXlpZDo4Qjo0Qjo2RDpFRDpEMzoyOTpCOTowNjoxOTpFQzozOTozOTpBOTpGMDo5Nzo4NDo2QTpDQjpFRjpERgorICAgICAgICAgICAgICAgIERpck5hbWU6L0M9Qk0vTz1RdW9WYWRpcyBMaW1pdGVkL09VPVJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkvQ049UXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQorICAgICAgICAgICAgICAgIHNlcmlhbDozQTpCNjo1MDo4QgorCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDhhOmQ0OjE0OmI1OmZlOmY0OjlhOjkyOmE3OjE5OmQ0OmE0OjdlOjcyOjE4OjhmOmQ5OjY4OgorICAgICAgICA3Yzo1MjoyNDpkZDo2Nzo2ZjozOTo3YTpjNDphYTo1ZTozZDplMjo1ODpiMDo0ZDo3MDo5ODoKKyAgICAgICAgODQ6NjE6ZTg6MWI6ZTM6Njk6MTg6MGU6Y2U6ZmI6NDc6NTA6YTA6NGU6ZmY6ZjA6MjQ6MWY6CisgICAgICAgIGJkOmIyOmNlOmY1OjI3OmZjOmVjOjJmOjUzOmFhOjczOjdiOjAzOjNkOjc0OjZlOmU2OjE2OgorICAgICAgICA5ZTplYjphNToyZTpjNDpiZjo1NjoyNzo1MDoyYjo2MjpiYTpiZTo0YjoxYzozYzo1NTo1YzoKKyAgICAgICAgNDE6MWQ6MjQ6YmU6ODI6MjA6NDc6NWQ6ZDU6NDQ6N2U6N2E6MTY6Njg6ZGY6N2Q6NGQ6NTE6CisgICAgICAgIDcwOjc4OjU3OjFkOjMzOjFlOmZkOjAyOjk5OjljOjBjOmNkOjBhOjA1OjRmOmM3OmJiOjhlOgorICAgICAgICBhNDo3NTpmYTo0YTo2ZDpiMTo4MDo4ZTowOTo1NjpiOTo5YzoxYTo2MDpmZTo1ZDpjMTpkNzoKKyAgICAgICAgN2E6ZGM6MTE6Nzg6ZDA6ZDY6NWQ6YzE6Yjc6ZDU6YWQ6MzI6OTk6MDM6M2E6OGE6Y2M6NTQ6CisgICAgICAgIDI1OjM5OjMxOjgxOjdiOjEzOjIyOjUxOmJhOjQ2OjZjOmExOmJiOjllOmZhOjA0OjZjOjQ5OgorICAgICAgICAyNjo3NDo4ZjpkMjo3MzplYjpjYzozMDphMjplNjplYTo1OToyMjo4NzpmODo5NzpmNTowZToKKyAgICAgICAgZmQ6ZWE6Y2M6OTI6YTQ6MTY6YzQ6NTI6MTg6ZWE6MjE6Y2U6YjE6ZjE6ZTY6ODQ6ODE6ZTU6CisgICAgICAgIGJhOmE5Ojg2OjI4OmYyOjQzOjVhOjVkOjEyOjlkOmFjOjFlOmQ5OmE4OmU1OjBhOjZhOmE3OgorICAgICAgICA3ZjphMDo4NzoyOTpjZjpmMjo4OTo0ZDpkNDplYzpjNTplMjplNjo3YTpkMDozNjoyMzo4YToKKyAgICAgICAgNGE6NzQ6MzY6ZjkKK1NIQTEgRmluZ2VycHJpbnQ9REU6M0Y6NDA6QkQ6NTA6OTM6RDM6OUI6NkM6NjA6RjY6REE6QkM6MDc6NjI6MDE6MDA6ODk6NzY6QzkKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy81ZTRlNjllNy4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzVlNGU2OWU3LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzRlMjA0NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy81ZTRlNjllNy4wCkBAIC0wLDAgKzEsNjEgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRGhEQ0NBd3FnQXdJQkFnSVFMNEQrSTR3T0lnOUlaeElva1llc3N6QUtCZ2dxaGtqT1BRUURBekNCeWpFTAorTUFrR0ExVUVCaE1DVlZNeEZ6QVZCZ05WQkFvVERsWmxjbWxUYVdkdUxDQkpibU11TVI4d0hRWURWUVFMRXhaVworWlhKcFUybG5iaUJVY25WemRDQk9aWFIzYjNKck1Ub3dPQVlEVlFRTEV6RW9ZeWtnTWpBd055QldaWEpwVTJsbgorYml3Z1NXNWpMaUF0SUVadmNpQmhkWFJvYjNKcGVtVmtJSFZ6WlNCdmJteDVNVVV3UXdZRFZRUURFenhXWlhKcAorVTJsbmJpQkRiR0Z6Y3lBeklGQjFZbXhwWXlCUWNtbHRZWEo1SUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eQorYVhSNUlDMGdSelF3SGhjTk1EY3hNVEExTURBd01EQXdXaGNOTXpnd01URTRNak0xT1RVNVdqQ0J5akVMTUFrRworQTFVRUJoTUNWVk14RnpBVkJnTlZCQW9URGxabGNtbFRhV2R1TENCSmJtTXVNUjh3SFFZRFZRUUxFeFpXWlhKcAorVTJsbmJpQlVjblZ6ZENCT1pYUjNiM0pyTVRvd09BWURWUVFMRXpFb1l5a2dNakF3TnlCV1pYSnBVMmxuYml3ZworU1c1akxpQXRJRVp2Y2lCaGRYUm9iM0pwZW1Wa0lIVnpaU0J2Ym14NU1VVXdRd1lEVlFRREV6eFdaWEpwVTJsbgorYmlCRGJHRnpjeUF6SUZCMVlteHBZeUJRY21sdFlYSjVJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNQorSUMwZ1J6UXdkakFRQmdjcWhrak9QUUlCQmdVcmdRUUFJZ05pQUFTblZucDhVdHBrbXc0dFhOaGVySkk5L2dIbQorR1VvOUZBTkwrbUFuSU5tRGlXbjZWTWFhR0Y1VkttVGVCdmFOU2p1dEVEeGxQWkNJQkluZ01HR3pybDBCcDN2ZQorZkxLK3ltVmhBSWF1Mm85NzBJbXRUUjFabWtHeHZFZUEzSjVpdy9tamdiSXdnYTh3RHdZRFZSMFRBUUgvQkFVdworQXdFQi96QU9CZ05WSFE4QkFmOEVCQU1DQVFZd2JRWUlLd1lCQlFVSEFRd0VZVEJmb1YyZ1d6QlpNRmN3VlJZSgorYVcxaFoyVXZaMmxtTUNFd0h6QUhCZ1VyRGdNQ0dnUVVqK1hUR29hc2pZNXJ3OCtBYXRSSUdDeDdHUzR3SlJZagorYUhSMGNEb3ZMMnh2WjI4dWRtVnlhWE5wWjI0dVkyOXRMM1p6Ykc5bmJ5NW5hV1l3SFFZRFZSME9CQllFRkxNVwora2YzdXBtN2t0UzVKajRkNGdZRHM1YkcxTUFvR0NDcUdTTTQ5QkFNREEyZ0FNR1VDTUdZaERCZ21ZRm80ZTFaQworNEtmOE5vUlJrU0FzZGsxRFBjUWRoQ1BRck5aOE5RYk96V205a0EzYmJFaENIUTZxUWdJeEFKdzlTRGtqT1ZnYQorRlJKWmFwN3YxVm15SFZJc21YSE54eW5mR3lwaGUzSFIzdlBBNVEwNlNxb3RwOWlHS3QwdUVBPT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDJmOjgwOmZlOjIzOjhjOjBlOjIyOjBmOjQ4OjY3OjEyOjI4OjkxOjg3OmFjOmIzCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IGVjZHNhLXdpdGgtU0hBMzg0CisgICAgICAgIElzc3VlcjogQz1VUywgTz1WZXJpU2lnbiwgSW5jLiwgT1U9VmVyaVNpZ24gVHJ1c3QgTmV0d29yaywgT1U9KGMpIDIwMDcgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seSwgQ049VmVyaVNpZ24gQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0CisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBOb3YgIDUgMDA6MDA6MDAgMjAwNyBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEphbiAxOCAyMzo1OTo1OSAyMDM4IEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPVZlcmlTaWduLCBJbmMuLCBPVT1WZXJpU2lnbiBUcnVzdCBOZXR3b3JrLCBPVT0oYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5LCBDTj1WZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogaWQtZWNQdWJsaWNLZXkKKyAgICAgICAgICAgIEVDIFB1YmxpYyBLZXk6CisgICAgICAgICAgICAgICAgcHViOiAKKyAgICAgICAgICAgICAgICAgICAgMDQ6YTc6NTY6N2E6N2M6NTI6ZGE6NjQ6OWI6MGU6MmQ6NWM6ZDg6NWU6YWM6CisgICAgICAgICAgICAgICAgICAgIDkyOjNkOmZlOjAxOmU2OjE5OjRhOjNkOjE0OjAzOjRiOmZhOjYwOjI3OjIwOgorICAgICAgICAgICAgICAgICAgICBkOTo4Mzo4OTo2OTpmYTo1NDpjNjo5YToxODo1ZTo1NToyYTo2NDpkZTowNjoKKyAgICAgICAgICAgICAgICAgICAgZjY6OGQ6NGE6M2I6YWQ6MTA6M2M6NjU6M2Q6OTA6ODg6MDQ6ODk6ZTA6MzA6CisgICAgICAgICAgICAgICAgICAgIDYxOmIzOmFlOjVkOjAxOmE3OjdiOmRlOjdjOmIyOmJlOmNhOjY1OjYxOjAwOgorICAgICAgICAgICAgICAgICAgICA4NjphZTpkYTo4Zjo3YjpkMDo4OTphZDo0ZDoxZDo1OTo5YTo0MTpiMTpiYzoKKyAgICAgICAgICAgICAgICAgICAgNDc6ODA6ZGM6OWU6NjI6YzM6ZjkKKyAgICAgICAgICAgICAgICBBU04xIE9JRDogc2VjcDM4NHIxCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIDEuMy42LjEuNS41LjcuMS4xMjogCisgICAgICAgICAgICAgICAgMF8uXS5bMFkwVzBVLi5pbWFnZS9naWYwITAuMC4uLisuLi4uLi4uLi4uLi4uLmsuLi5qLkguLHsuLjAlLiNodHRwOi8vbG9nby52ZXJpc2lnbi5jb20vdnNsb2dvLmdpZgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEIzOjE2OjkxOkZEOkVFOkE2OjZFOkU0OkI1OjJFOjQ5OjhGOjg3Ojc4OjgxOjgwOkVDOkU1OkIxOkI1CisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogZWNkc2Etd2l0aC1TSEEzODQKKyAgICAgICAgMzA6NjU6MDI6MzA6NjY6MjE6MGM6MTg6MjY6NjA6NWE6Mzg6N2I6NTY6NDI6ZTA6YTc6ZmM6CisgICAgICAgIDM2Ojg0OjUxOjkxOjIwOjJjOjc2OjRkOjQzOjNkOmM0OjFkOjg0OjIzOmQwOmFjOmQ2OjdjOgorICAgICAgICAzNTowNjpjZTpjZDo2OTpiZDo5MDowZDpkYjo2Yzo0ODo0MjoxZDowZTphYTo0MjowMjozMToKKyAgICAgICAgMDA6OWM6M2Q6NDg6Mzk6MjM6Mzk6NTg6MWE6MTU6MTI6NTk6NmE6OWU6ZWY6ZDU6NTk6YjI6CisgICAgICAgIDFkOjUyOjJjOjk5OjcxOmNkOmM3OjI5OmRmOjFiOjJhOjYxOjdiOjcxOmQxOmRlOmYzOmMwOgorICAgICAgICBlNTowZDozYTo0YTphYToyZDphNzpkODo4NjoyYTpkZDoyZToxMAorU0hBMSBGaW5nZXJwcmludD0yMjpENTpEODpERjo4RjowMjozMTpEMTo4RDpGNzo5RDpCNzpDRjo4QToyRDo2NDpDOTozRjo2QzozQQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzYwYWZlODEyLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNjBhZmU4MTIuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYzUzZWIzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzYwYWZlODEyLjAKQEAgLTAsMCArMSw4MiBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFRlRDQ0F2MmdBd0lCQWdJR1NVRXM1QUFRTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUduTVFzd0NRWURWUVFHCitFd0pJVlRFUk1BOEdBMVVFQnd3SVFuVmtZWEJsYzNReEZUQVRCZ05WQkFvTURFNWxkRXh2WTJzZ1MyWjBMakUzCitNRFVHQTFVRUN3d3VWR0Z1dzdwenc2MTBkc09oYm5scmFXRmt3N05ySUNoRFpYSjBhV1pwWTJGMGFXOXVJRk5sCitjblpwWTJWektURTFNRE1HQTFVRUF3d3NUbVYwVEc5amF5QkJjbUZ1ZVNBb1EyeGhjM01nUjI5c1pDa2dSc1dSCitkR0Z1dzdwenc2MTBkc09oYm5rd0hoY05NRGd4TWpFeE1UVXdPREl4V2hjTk1qZ3hNakEyTVRVd09ESXhXakNCCitwekVMTUFrR0ExVUVCaE1DU0ZVeEVUQVBCZ05WQkFjTUNFSjFaR0Z3WlhOME1SVXdFd1lEVlFRS0RBeE9aWFJNCitiMk5ySUV0bWRDNHhOekExQmdOVkJBc01MbFJoYnNPNmM4T3RkSGJEb1c1NWEybGhaTU96YXlBb1EyVnlkR2xtCithV05oZEdsdmJpQlRaWEoyYVdObGN5a3hOVEF6QmdOVkJBTU1MRTVsZEV4dlkyc2dRWEpoYm5rZ0tFTnNZWE56CitJRWR2YkdRcElFYkZrWFJoYnNPNmM4T3RkSGJEb1c1NU1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCitNSUlCQ2dLQ0FRRUF4Q1JlYzc1TGJSVERvZlRqbDVCdTBqQkZIanp1WjlsazRCcUtmOG93eW9QaklNSGo5RHJUCitsRjhhZkZ0dHZ6QlBoQ2Yybng5SnZNYVpDcER5RC9WL1E0UTNZMUdMZXFWdy9IcFl6WTZiN2NOR2JJUndYZHJ6CitBWkFqL0U0d3FYN2hKMlBuN1dROG9MakpNMlArRnBEL3NMajkxNmpBd0pSREM3YlZXYWFlVnRBa0gzQjVyOXM1CitWQTFsZGRrVlFaUUJyMTdzOW8zeC82MWsvaUNhMTF6ci9xWWZDR1NqaTNaVnJSNDdLR0F1aHlYb3FxOGZ4bVJHCitJTGR3Znp6ZVNOdVdVN2M1ZCtRYTRzY1doSGFYV3krN0dSV0YrR21GOVptbnFmSTBwNm0ycGdQOGI0WTlWSHgyCitCSnRyK1VCZEFEVEhMcGwxbmVXSUE2cE4rQVBTUW5iQUd3SURBS2lMbzBVd1F6QVNCZ05WSFJNQkFmOEVDREFHCitBUUgvQWdFRU1BNEdBMVVkRHdFQi93UUVBd0lCQmpBZEJnTlZIUTRFRmdRVXpQcG5rL0MydU5DbHdCN3pVLzJNCitVOStEMTVZd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFLdC83aHdXcVp3OFVRQ2d3QkVJQmFlWjVtOEJpRlJoCitidkc1R0sxS3JmNkJRQ09VTC90MWZDOG9TMklrZ1lJTDlXSHhIRzY0WVRqcmdmcGlvVHRhWXRPVVpjVGg1bTJDCisrQzhsY0xJaEpzRnlVUitNTE1PRWtNTmFqN3JQOUtkbHBldVkwZnNGc2taMUZTTnFiNFZqTUlEdzFaNGZLUnpDCitiTEJRV1YyUVd6dW9EVERQdjMxL3p2R2RnNzNKUm00Z3B2bGhVYm9oTDN1K3BSVmpvZFNWaC9HZXVmT0o4ejJGCit1TGpidnJXNUtmbmFOd1VBU1pRRGhFVG52ME14ejNXTEpkSDBwbVQxa3ZhckJlczk2YVVMTm1MYXpBWmZOb3UyCitYakc0S3Z0ZTluSGZSQ2FleE9ZTmtiUXVkWldBVVdwTE1LYXdZcUdUOFp2WXpzUmpkVDlaUjdFPQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgNDk6NDE6MmM6ZTQ6MDA6MTAKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPUhVLCBMPUJ1ZGFwZXN0LCBPPU5ldExvY2sgS2Z0LiwgT1U9VGFuXHhDM1x4QkFzXHhDM1x4QUR0dlx4QzNceEExbnlraWFkXHhDM1x4QjNrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKSwgQ049TmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRlx4QzVceDkxdGFuXHhDM1x4QkFzXHhDM1x4QUR0dlx4QzNceEExbnkKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IERlYyAxMSAxNTowODoyMSAyMDA4IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogRGVjICA2IDE1OjA4OjIxIDIwMjggR01UCisgICAgICAgIFN1YmplY3Q6IEM9SFUsIEw9QnVkYXBlc3QsIE89TmV0TG9jayBLZnQuLCBPVT1UYW5ceEMzXHhCQXNceEMzXHhBRHR2XHhDM1x4QTFueWtpYWRceEMzXHhCM2sgKENlcnRpZmljYXRpb24gU2VydmljZXMpLCBDTj1OZXRMb2NrIEFyYW55IChDbGFzcyBHb2xkKSBGXHhDNVx4OTF0YW5ceEMzXHhCQXNceEMzXHhBRHR2XHhDM1x4QTFueQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YzQ6MjQ6NWU6NzM6YmU6NGI6NmQ6MTQ6YzM6YTE6ZjQ6ZTM6OTc6OTA6CisgICAgICAgICAgICAgICAgICAgIDZlOmQyOjMwOjQ1OjFlOjNjOmVlOjY3OmQ5OjY0OmUwOjFhOjhhOjdmOmNhOgorICAgICAgICAgICAgICAgICAgICAzMDpjYTo4MzplMzoyMDpjMTplMzpmNDozYTpkMzo5NDo1ZjoxYTo3Yzo1YjoKKyAgICAgICAgICAgICAgICAgICAgNmQ6YmY6MzA6NGY6ODQ6Mjc6ZjY6OWY6MWY6NDk6YmM6YzY6OTk6MGE6OTA6CisgICAgICAgICAgICAgICAgICAgIGYyOjBmOmY1OjdmOjQzOjg0OjM3OjYzOjUxOjhiOjdhOmE1OjcwOmZjOjdhOgorICAgICAgICAgICAgICAgICAgICA1ODpjZDo4ZTo5YjplZDpjMzo0Njo2Yzo4NDo3MDo1ZDpkYTpmMzowMTo5MDoKKyAgICAgICAgICAgICAgICAgICAgMjM6ZmM6NGU6MzA6YTk6N2U6ZTE6Mjc6NjM6ZTc6ZWQ6NjQ6M2M6YTA6Yjg6CisgICAgICAgICAgICAgICAgICAgIGM5OjMzOjYzOmZlOjE2OjkwOmZmOmIwOmI4OmZkOmQ3OmE4OmMwOmMwOjk0OgorICAgICAgICAgICAgICAgICAgICA0MzowYjpiNjpkNTo1OTphNjo5ZTo1NjpkMDoyNDoxZjo3MDo3OTphZjpkYjoKKyAgICAgICAgICAgICAgICAgICAgMzk6NTQ6MGQ6NjU6NzU6ZDk6MTU6NDE6OTQ6MDE6YWY6NWU6ZWM6ZjY6OGQ6CisgICAgICAgICAgICAgICAgICAgIGYxOmZmOmFkOjY0OmZlOjIwOjlhOmQ3OjVjOmViOmZlOmE2OjFmOjA4OjY0OgorICAgICAgICAgICAgICAgICAgICBhMzo4Yjo3Njo1NTphZDoxZTozYjoyODo2MDoyZTo4NzoyNTplODphYTphZjoKKyAgICAgICAgICAgICAgICAgICAgMWY6YzY6NjQ6NDY6MjA6Yjc6NzA6N2Y6M2M6ZGU6NDg6ZGI6OTY6NTM6Yjc6CisgICAgICAgICAgICAgICAgICAgIDM5Ojc3OmU0OjFhOmUyOmM3OjE2Ojg0Ojc2Ojk3OjViOjJmOmJiOjE5OjE1OgorICAgICAgICAgICAgICAgICAgICA4NTpmODo2OTo4NTpmNTo5OTphNzphOTpmMjozNDphNzphOTpiNjphNjowMzoKKyAgICAgICAgICAgICAgICAgICAgZmM6NmY6ODY6M2Q6NTQ6N2M6NzY6MDQ6OWI6NmI6Zjk6NDA6NWQ6MDA6MzQ6CisgICAgICAgICAgICAgICAgICAgIGM3OjJlOjk5Ojc1OjlkOmU1Ojg4OjAzOmFhOjRkOmY4OjAzOmQyOjQyOjc2OgorICAgICAgICAgICAgICAgICAgICBjMDoxYgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA0MzE0NyAoMHhhODhiKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFLCBwYXRobGVuOjQKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBDQzpGQTo2Nzo5MzpGMDpCNjpCODpEMDpBNTpDMDoxRTpGMzo1MzpGRDo4Qzo1MzpERjo4MzpENzo5NgorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTI1NldpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIGFiOjdmOmVlOjFjOjE2OmE5OjljOjNjOjUxOjAwOmEwOmMwOjExOjA4OjA1OmE3Ojk5OmU2OgorICAgICAgICA2ZjowMTo4ODo1NDo2MTo2ZTpmMTpiOToxODphZDo0YTphZDpmZTo4MTo0MDoyMzo5NDoyZjoKKyAgICAgICAgZmI6NzU6N2M6MmY6Mjg6NGI6NjI6MjQ6ODE6ODI6MGI6ZjU6NjE6ZjE6MWM6NmU6Yjg6NjE6CisgICAgICAgIDM4OmViOjgxOmZhOjYyOmExOjNiOjVhOjYyOmQzOjk0OjY1OmM0OmUxOmU2OjZkOjgyOmY4OgorICAgICAgICAyZjoyNTo3MDpiMjoyMToyNjpjMTo3Mjo1MToxZjo4YzoyYzpjMzo4NDo5MDpjMzo1YTo4ZjoKKyAgICAgICAgYmE6Y2Y6ZjQ6YTc6NjU6YTU6ZWI6OTg6ZDE6ZmI6MDU6YjI6NDY6NzU6MTU6MjM6NmE6NmY6CisgICAgICAgIDg1OjYzOjMwOjgwOmYwOmQ1OjllOjFmOjI5OjFjOmMyOjZjOmIwOjUwOjU5OjVkOjkwOjViOgorICAgICAgICAzYjphODowZDozMDpjZjpiZjo3ZDo3ZjpjZTpmMTo5ZDo4MzpiZDpjOTo0Njo2ZToyMDphNjoKKyAgICAgICAgZjk6NjE6NTE6YmE6MjE6MmY6N2I6YmU6YTU6MTU6NjM6YTE6ZDQ6OTU6ODc6ZjE6OWU6Yjk6CisgICAgICAgIGYzOjg5OmYzOjNkOjg1OmI4OmI4OmRiOmJlOmI1OmI5OjI5OmY5OmRhOjM3OjA1OjAwOjQ5OgorICAgICAgICA5NDowMzo4NDo0NDplNzpiZjo0MzozMTpjZjo3NTo4YjoyNTpkMTpmNDphNjo2NDpmNTo5MjoKKyAgICAgICAgZjY6YWI6MDU6ZWI6M2Q6ZTk6YTU6MGI6MzY6NjI6ZGE6Y2M6MDY6NWY6MzY6OGI6YjY6NWU6CisgICAgICAgIDMxOmI4OjJhOmZiOjVlOmY2OjcxOmRmOjQ0OjI2OjllOmM0OmU2OjBkOjkxOmI0OjJlOjc1OgorICAgICAgICA5NTo4MDo1MTo2YTo0YjozMDphNjpiMDo2MjphMTo5MzpmMTo5YjpkODpjZTpjNDo2Mzo3NToKKyAgICAgICAgM2Y6NTk6NDc6YjEKK1NIQTEgRmluZ2VycHJpbnQ9MDY6MDg6M0Y6NTk6M0Y6MTU6QTE6MDQ6QTA6Njk6QTQ6NkI6QTk6MDM6RDA6MDY6Qjc6OTc6MDk6OTEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy82MzVjY2ZkNS4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzYzNWNjZmQ1LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjU3OWRkZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy82MzVjY2ZkNS4wCkBAIC0wLDAgKzEsNzQgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRlR6Q0NCTGlnQXdJQkFnSUJhREFOQmdrcWhraUc5dzBCQVFRRkFEQ0JtekVMTUFrR0ExVUVCaE1DU0ZVeAorRVRBUEJnTlZCQWNUQ0VKMVpHRndaWE4wTVNjd0pRWURWUVFLRXg1T1pYUk1iMk5ySUVoaGJHOTZZWFJpYVhwMAorYjI1ellXZHBJRXRtZEM0eEdqQVlCZ05WQkFzVEVWUmhiblZ6YVhSMllXNTVhMmxoWkc5ck1UUXdNZ1lEVlFRRAorRXl0T1pYUk1iMk5ySUVWNGNISmxjM042SUNoRGJHRnpjeUJES1NCVVlXNTFjMmwwZG1GdWVXdHBZV1J2TUI0WAorRFRrNU1ESXlOVEUwTURneE1Wb1hEVEU1TURJeU1ERTBNRGd4TVZvd2dac3hDekFKQmdOVkJBWVRBa2hWTVJFdworRHdZRFZRUUhFd2hDZFdSaGNHVnpkREVuTUNVR0ExVUVDaE1lVG1WMFRHOWpheUJJWVd4dmVtRjBZbWw2ZEc5dQorYzJGbmFTQkxablF1TVJvd0dBWURWUVFMRXhGVVlXNTFjMmwwZG1GdWVXdHBZV1J2YXpFME1ESUdBMVVFQXhNcgorVG1WMFRHOWpheUJGZUhCeVpYTnplaUFvUTJ4aGMzTWdReWtnVkdGdWRYTnBkSFpoYm5scmFXRmtiekNCbnpBTgorQmdrcWhraUc5dzBCQVFFRkFBT0JqUUF3Z1lrQ2dZRUE2K3l3YkdHS0l5V3ZZQ0RqMlovOGt3dmJYWTJ3b2JOQQorT29MTy9YWGdlRElEaGxxR2xaSHRVL3FkUVB6bTZOM1pXM29EdlYzek93ekRVWG1iclZXZzZkQURFSzhLdWhSQworMlZJbUVTTEgwaURNZ3FTYXFmNjRnWGFkYXJmU05uVStzWVlKOW01dGZrNjNldXl1Y1lUMkJETUlKVExyZEt3VworUk1ia1FKTWRmNjBDQXdFQUFhT0NBcDh3Z2dLYk1CSUdBMVVkRXdFQi93UUlNQVlCQWY4Q0FRUXdEZ1lEVlIwUAorQVFIL0JBUURBZ0FHTUJFR0NXQ0dTQUdHK0VJQkFRUUVBd0lBQnpDQ0FtQUdDV0NHU0FHRytFSUJEUVNDQWxFVworZ2dKTlJrbEhXVVZNUlUwaElFVjZaVzRnZEdGdWRYTnBkSFpoYm5rZ1lTQk9aWFJNYjJOcklFdG1kQzRnUVd4MAorWVd4aGJtOXpJRk42YjJ4bllXeDBZWFJoYzJrZ1JtVnNkR1YwWld4bGFXSmxiaUJzWldseWRDQmxiR3BoY21GegorYjJzZ1lXeGhjR3BoYmlCclpYTjZkV3gwTGlCQklHaHBkR1ZzWlhOcGRHVnpJR1p2YkhsaGJXRjBZWFFnWVNCTworWlhSTWIyTnJJRXRtZEM0Z2RHVnliV1ZyWm1Wc1pXeHZjM05sWnkxaWFYcDBiM05wZEdGellTQjJaV1JwTGlCQgorSUdScFoybDBZV3hwY3lCaGJHRnBjbUZ6SUdWc1ptOW5ZV1JoYzJGdVlXc2dabVZzZEdWMFpXeGxJR0Y2SUdWcworYjJseWRDQmxiR3hsYm05eWVtVnphU0JsYkdwaGNtRnpJRzFsWjNSbGRHVnNaUzRnUVhvZ1pXeHFZWEpoY3lCcworWldseVlYTmhJRzFsWjNSaGJHRnNhR0YwYnlCaElFNWxkRXh2WTJzZ1MyWjBMaUJKYm5SbGNtNWxkQ0JvYjI1cworWVhCcVlXNGdZU0JvZEhSd2N6b3ZMM2QzZHk1dVpYUnNiMk5yTG01bGRDOWtiMk56SUdOcGJXVnVJSFpoWjNrZworYTJWeWFHVjBieUJoZWlCbGJHeGxibTl5ZW1WelFHNWxkR3h2WTJzdWJtVjBJR1V0YldGcGJDQmphVzFsYmk0ZworU1UxUVQxSlVRVTVVSVNCVWFHVWdhWE56ZFdGdVkyVWdZVzVrSUhSb1pTQjFjMlVnYjJZZ2RHaHBjeUJqWlhKMAorYVdacFkyRjBaU0JwY3lCemRXSnFaV04wSUhSdklIUm9aU0JPWlhSTWIyTnJJRU5RVXlCaGRtRnBiR0ZpYkdVZworWVhRZ2FIUjBjSE02THk5M2QzY3VibVYwYkc5amF5NXVaWFF2Wkc5amN5QnZjaUJpZVNCbExXMWhhV3dnWVhRZworWTNCelFHNWxkR3h2WTJzdWJtVjBMakFOQmdrcWhraUc5dzBCQVFRRkFBT0JnUUFRclgvWERES0FDdGlHOFhtWQordGEzVXpiTTJ4SlpJd1Z6Tm10a0ZMcCsrVU92MEpoUVFMZFJtRi9pZXdTZjk4ZTNrZTB1Z2JMV3JtbGR3cHUyZworcE8wdTlmMzh2ZjVOTndnTXZPT1dneUwxU1J0L1N5dTBWTUdBZkpsT0hkQ003dENzNVpMNmRWYitaS0FUajdpNAorRnAxaEJXZUF5TkRZcFFjQ05KZ0VqVE1FMUE9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAxMDQgKDB4NjgpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IG1kNVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1IVSwgTD1CdWRhcGVzdCwgTz1OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4sIE9VPVRhbnVzaXR2YW55a2lhZG9rLCBDTj1OZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBDKSBUYW51c2l0dmFueWtpYWRvCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBGZWIgMjUgMTQ6MDg6MTEgMTk5OSBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEZlYiAyMCAxNDowODoxMSAyMDE5IEdNVAorICAgICAgICBTdWJqZWN0OiBDPUhVLCBMPUJ1ZGFwZXN0LCBPPU5ldExvY2sgSGFsb3phdGJpenRvbnNhZ2kgS2Z0LiwgT1U9VGFudXNpdHZhbnlraWFkb2ssIENOPU5ldExvY2sgRXhwcmVzc3ogKENsYXNzIEMpIFRhbnVzaXR2YW55a2lhZG8KKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgxMDI0IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgxMDI0IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmViOmVjOmIwOjZjOjYxOjhhOjIzOjI1OmFmOjYwOjIwOmUzOmQ5OjlmOgorICAgICAgICAgICAgICAgICAgICBmYzo5MzowYjpkYjo1ZDo4ZDpiMDphMTpiMzo0MDozYTo4MjpjZTpmZDo3NToKKyAgICAgICAgICAgICAgICAgICAgZTA6Nzg6MzI6MDM6ODY6NWE6ODY6OTU6OTE6ZWQ6NTM6ZmE6OWQ6NDA6ZmM6CisgICAgICAgICAgICAgICAgICAgIGU2OmU4OmRkOmQ5OjViOjdhOjAzOmJkOjVkOmYzOjNiOjBjOmMzOjUxOjc5OgorICAgICAgICAgICAgICAgICAgICA5YjphZDo1NTphMDplOTpkMDowMzoxMDphZjowYTpiYToxNDo0MjpkOTo1MjoKKyAgICAgICAgICAgICAgICAgICAgMjY6MTE6MjI6Yzc6ZDI6MjA6Y2M6ODI6YTQ6OWE6YTk6ZmU6Yjg6ODE6NzY6CisgICAgICAgICAgICAgICAgICAgIDlkOjZhOmI3OmQyOjM2Ojc1OjNlOmIxOjg2OjA5OmY2OjZlOjZkOjdlOjRlOgorICAgICAgICAgICAgICAgICAgICBiNzo3YTplYzphZTo3MTo4NDpmNjowNDozMzowODoyNTozMjplYjo3NDphYzoKKyAgICAgICAgICAgICAgICAgICAgMTY6NDQ6YzY6ZTQ6NDA6OTM6MWQ6N2Y6YWQKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUsIHBhdGhsZW46NAorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgTmV0c2NhcGUgQ2VydCBUeXBlOiAKKyAgICAgICAgICAgICAgICBTU0wgQ0EsIFMvTUlNRSBDQSwgT2JqZWN0IFNpZ25pbmcgQ0EKKyAgICAgICAgICAgIE5ldHNjYXBlIENvbW1lbnQ6IAorICAgICAgICAgICAgICAgIEZJR1lFTEVNISBFemVuIHRhbnVzaXR2YW55IGEgTmV0TG9jayBLZnQuIEFsdGFsYW5vcyBTem9sZ2FsdGF0YXNpIEZlbHRldGVsZWliZW4gbGVpcnQgZWxqYXJhc29rIGFsYXBqYW4ga2VzenVsdC4gQSBoaXRlbGVzaXRlcyBmb2x5YW1hdGF0IGEgTmV0TG9jayBLZnQuIHRlcm1la2ZlbGVsb3NzZWctYml6dG9zaXRhc2EgdmVkaS4gQSBkaWdpdGFsaXMgYWxhaXJhcyBlbGZvZ2FkYXNhbmFrIGZlbHRldGVsZSBheiBlbG9pcnQgZWxsZW5vcnplc2kgZWxqYXJhcyBtZWd0ZXRlbGUuIEF6IGVsamFyYXMgbGVpcmFzYSBtZWd0YWxhbGhhdG8gYSBOZXRMb2NrIEtmdC4gSW50ZXJuZXQgaG9ubGFwamFuIGEgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBjaW1lbiB2YWd5IGtlcmhldG8gYXogZWxsZW5vcnplc0BuZXRsb2NrLm5ldCBlLW1haWwgY2ltZW4uIElNUE9SVEFOVCEgVGhlIGlzc3VhbmNlIGFuZCB0aGUgdXNlIG9mIHRoaXMgY2VydGlmaWNhdGUgaXMgc3ViamVjdCB0byB0aGUgTmV0TG9jayBDUFMgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3Mgb3IgYnkgZS1tYWlsIGF0IGNwc0BuZXRsb2NrLm5ldC4KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBtZDVXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAxMDphZDo3ZjpkNzowYzozMjo4MDowYTpkODo4NjpmMTo3OTo5ODpiNTphZDpkNDpjZDpiMzoKKyAgICAgICAgMzY6YzQ6OTY6NDg6YzE6NWM6Y2Q6OWE6ZDk6MDU6MmU6OWY6YmU6NTA6ZWI6ZjQ6MjY6MTQ6CisgICAgICAgIDEwOjJkOmQ0OjY2OjE3OmY4OjllOmMxOjI3OmZkOmYxOmVkOmU0OjdiOjRiOmEwOjZjOmI1OgorICAgICAgICBhYjo5YTo1Nzo3MDphNjplZDphMDphNDplZDoyZTpmNTpmZDpmYzpiZDpmZTo0ZDozNzowODoKKyAgICAgICAgMGM6YmM6ZTM6OTY6ODM6MjI6ZjU6NDk6MWI6N2Y6NGI6MmI6YjQ6NTQ6YzE6ODA6N2M6OTk6CisgICAgICAgIDRlOjFkOmQwOjhjOmVlOmQwOmFjOmU1OjkyOmZhOjc1OjU2OmZlOjY0OmEwOjEzOjhmOmI4OgorICAgICAgICBiODoxNjo5ZDo2MTowNTo2Nzo4MDpjODpkMDpkODphNTowNzowMjozNDo5ODowNDo4ZDozMzoKKyAgICAgICAgMDQ6ZDQKK1NIQTEgRmluZ2VycHJpbnQ9RTM6OTI6NTE6MkY6MEE6Q0Y6RjU6MDU6REY6RjY6REU6MDY6N0Y6NzU6Mzc6RTE6NjU6RUE6NTc6NEIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy82NzQ5NTQzNi4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzY3NDk1NDM2LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzk0N2UxNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy82NzQ5NTQzNi4wCkBAIC0wLDAgKzEsODMgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRUtqQ0NBeEtnQXdJQkFnSVFZQUdYdDBhbjZyUzBtdFpMTC9lUSt6QU5CZ2txaGtpRzl3MEJBUXNGQURDQgorcmpFTE1Ba0dBMVVFQmhNQ1ZWTXhGVEFUQmdOVkJBb1RESFJvWVhkMFpTd2dTVzVqTGpFb01DWUdBMVVFQ3hNZgorUTJWeWRHbG1hV05oZEdsdmJpQlRaWEoyYVdObGN5QkVhWFpwYzJsdmJqRTRNRFlHQTFVRUN4TXZLR01wSURJdworTURnZ2RHaGhkM1JsTENCSmJtTXVJQzBnUm05eUlHRjFkR2h2Y21sNlpXUWdkWE5sSUc5dWJIa3hKREFpQmdOVgorQkFNVEczUm9ZWGQwWlNCUWNtbHRZWEo1SUZKdmIzUWdRMEVnTFNCSE16QWVGdzB3T0RBME1ESXdNREF3TURCYQorRncwek56RXlNREV5TXpVNU5UbGFNSUd1TVFzd0NRWURWUVFHRXdKVlV6RVZNQk1HQTFVRUNoTU1kR2hoZDNSbAorTENCSmJtTXVNU2d3SmdZRFZRUUxFeDlEWlhKMGFXWnBZMkYwYVc5dUlGTmxjblpwWTJWeklFUnBkbWx6YVc5dQorTVRnd05nWURWUVFMRXk4b1l5a2dNakF3T0NCMGFHRjNkR1VzSUVsdVl5NGdMU0JHYjNJZ1lYVjBhRzl5YVhwbAorWkNCMWMyVWdiMjVzZVRFa01DSUdBMVVFQXhNYmRHaGhkM1JsSUZCeWFXMWhjbmtnVW05dmRDQkRRU0F0SUVjegorTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFzcjhuTFB2YjJGdmRlSHNibm5kbQorZ2NzK3ZIeXU4NllubWpTamFERnhPRE5pNVBOeFpubXhxV1dqcFl2VmoyQXRQMExNcW1zeXdDUExMRUhkNU4vOAorWVp6aWM3SWlsUkZER0YvRXRoOVhiQW9GV0NMSU5rdzZmS1hSejRhdmlLZEVBaE4wY1hNS1Fsa0MrQnNVYTBMZgorYjErNmE0S2luVnZuU3IwZUFYTGJTM1RvTzM5L2ZSOEV0Q2FiNExSYXJFYzlWYmpYc0NaU0tBRXhRR2JZMlNTOQorOWlyWTdDRkpYSnYyZXVsL1ZUVitsbXVOazVNbnk1Szc2cXhBd0ovQytJRFBYZlJhM001MGhxWStiQXRUeXIyUworemhrR2N1WU1YRGhweHdUV3ZHek9XL2IzYUp6Y0pSVklpS0hwcWZpWW5PRHoxVEVvWVJGc1o1YU5PWm5Md2tVaworT1FJREFRQUJvMEl3UURBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUE0R0ExVWREd0VCL3dRRUF3SUJCakFkQmdOVgorSFE0RUZnUVVyV3lxbEdDYzdlVC8rajRLZEN0akEvZTJXYjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUJwQQorMkpWbHJBbVNpY1k1OUJEbHFRNW1VMTE0M3Zva2tidm5SRkhmeGhZMEN1OXFSRkhxS3dlS0EzckQ2ejhLTEZJVworb0N0RHVTV1FQM0NwTXlWdFJSb29PeWZQcXNNcFFodmZPMHpBTXpSYlFZaS9heXRscnlqdnN2WERxbWJPZTFidQordDhqTFo4SEpuQm9ZdU1URFNRUHhZQTVRelViRjgzZDU5N1lWNERqYnh5OG9vQXcvZHlaMDJTVVMyakhhR2g3YworS1VHUklqeHBwN3NDOHJaY0p3T0o5QWJxbStSeWd1T2hDY0hwQUJuVFB0UndhN3B4cHFwWXJ2Uzc2V3kyNzRmTQorbTd2L09lWldZZE1LcDhSY1RHQjdCWGNtZXIvWUIxSXNZdmR3WTlrNXZHOGN3bm5jZGltdnpzVXNaQVJlaURadQorTWRSQUdtSTBOajgxQWE2c1k2QT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDYwOjAxOjk3OmI3OjQ2OmE3OmVhOmI0OmI0OjlhOmQ2OjRiOjJmOmY3OjkwOmZiCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTI1NldpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgTz10aGF3dGUsIEluYy4sIE9VPUNlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24sIE9VPShjKSAyMDA4IHRoYXd0ZSwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5LCBDTj10aGF3dGUgUHJpbWFyeSBSb290IENBIC0gRzMKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEFwciAgMiAwMDowMDowMCAyMDA4IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogRGVjICAxIDIzOjU5OjU5IDIwMzcgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89dGhhd3RlLCBJbmMuLCBPVT1DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uLCBPVT0oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seSwgQ049dGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpiMjpiZjoyNzoyYzpmYjpkYjpkODo1YjpkZDo3ODo3YjoxYjo5ZTo3NzoKKyAgICAgICAgICAgICAgICAgICAgNjY6ODE6Y2I6M2U6YmM6N2M6YWU6ZjM6YTY6Mjc6OWE6MzQ6YTM6Njg6MzE6CisgICAgICAgICAgICAgICAgICAgIDcxOjM4OjMzOjYyOmU0OmYzOjcxOjY2Ojc5OmIxOmE5OjY1OmEzOmE1OjhiOgorICAgICAgICAgICAgICAgICAgICBkNTo4Zjo2MDoyZDozZjo0MjpjYzphYTo2YjozMjpjMDoyMzpjYjoyYzo0MToKKyAgICAgICAgICAgICAgICAgICAgZGQ6ZTQ6ZGY6ZmM6NjE6OWM6ZTI6NzM6YjI6MjI6OTU6MTE6NDM6MTg6NWY6CisgICAgICAgICAgICAgICAgICAgIGM0OmI2OjFmOjU3OjZjOjBhOjA1OjU4OjIyOmM4OjM2OjRjOjNhOjdjOmE1OgorICAgICAgICAgICAgICAgICAgICBkMTpjZjo4NjphZjo4ODphNzo0NDowMjoxMzo3NDo3MTo3MzowYTo0Mjo1OToKKyAgICAgICAgICAgICAgICAgICAgMDI6Zjg6MWI6MTQ6NmI6NDI6ZGY6NmY6NWY6YmE6NmI6ODI6YTI6OWQ6NWI6CisgICAgICAgICAgICAgICAgICAgIGU3OjRhOmJkOjFlOjAxOjcyOmRiOjRiOjc0OmU4OjNiOjdmOjdmOjdkOjFmOgorICAgICAgICAgICAgICAgICAgICAwNDpiNDoyNjo5YjplMDpiNDo1YTphYzo0NzozZDo1NTpiODpkNzpiMDoyNjoKKyAgICAgICAgICAgICAgICAgICAgNTI6Mjg6MDE6MzE6NDA6NjY6ZDg6ZDk6MjQ6YmQ6ZjY6MmE6ZDg6ZWM6MjE6CisgICAgICAgICAgICAgICAgICAgIDQ5OjVjOjliOmY2OjdhOmU5OjdmOjU1OjM1OjdlOjk2OjZiOjhkOjkzOjkzOgorICAgICAgICAgICAgICAgICAgICAyNzpjYjo5MjpiYjplYTphYzo0MDpjMDo5ZjpjMjpmODo4MDpjZjo1ZDpmNDoKKyAgICAgICAgICAgICAgICAgICAgNWE6ZGM6Y2U6NzQ6ODY6YTY6M2U6NmM6MGI6NTM6Y2E6YmQ6OTI6Y2U6MTk6CisgICAgICAgICAgICAgICAgICAgIDA2OjcyOmU2OjBjOjVjOjM4OjY5OmM3OjA0OmQ2OmJjOjZjOmNlOjViOmY2OgorICAgICAgICAgICAgICAgICAgICBmNzo2ODo5YzpkYzoyNToxNTo0ODo4ODphMTplOTphOTpmODo5ODo5YzplMDoKKyAgICAgICAgICAgICAgICAgICAgZjM6ZDU6MzE6Mjg6NjE6MTE6NmM6Njc6OTY6OGQ6Mzk6OTk6Y2I6YzI6NDU6CisgICAgICAgICAgICAgICAgICAgIDI0OjM5CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgQUQ6NkM6QUE6OTQ6NjA6OUM6RUQ6RTQ6RkY6RkE6M0U6MEE6NzQ6MkI6NjM6MDM6Rjc6QjY6NTk6QkYKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAxYTo0MDpkODo5NTo2NTphYzowOTo5Mjo4OTpjNjozOTpmNDoxMDplNTphOTowZTo2Njo1MzoKKyAgICAgICAgNWQ6Nzg6ZGU6ZmE6MjQ6OTE6YmI6ZTc6NDQ6NTE6ZGY6YzY6MTY6MzQ6MGE6ZWY6NmE6NDQ6CisgICAgICAgIDUxOmVhOjJiOjA3OjhhOjAzOjdhOmMzOmViOjNmOjBhOjJjOjUyOjE2OmEwOjJiOjQzOmI5OgorICAgICAgICAyNTo5MDozZjo3MDphOTozMzoyNTo2ZDo0NToxYToyODozYjoyNzpjZjphYTpjMzoyOTo0MjoKKyAgICAgICAgMWI6ZGY6M2I6NGM6YzA6MzM6MzQ6NWI6NDE6ODg6YmY6NmI6MmI6NjU6YWY6Mjg6ZWY6YjI6CisgICAgICAgIGY1OmMzOmFhOjY2OmNlOjdiOjU2OmVlOmI3OmM4OmNiOjY3OmMxOmM5OjljOjFhOjE4OmI4OgorICAgICAgICBjNDpjMzo0OTowMzpmMTo2MDowZTo1MDpjZDo0NjpjNTpmMzo3Nzo3OTpmNzpiNjoxNTplMDoKKyAgICAgICAgMzg6ZGI6Yzc6MmY6Mjg6YTA6MGM6M2Y6Nzc6MjY6NzQ6ZDk6MjU6MTI6ZGE6MzE6ZGE6MWE6CisgICAgICAgIDFlOmRjOjI5OjQxOjkxOjIyOjNjOjY5OmE3OmJiOjAyOmYyOmI2OjVjOjI3OjAzOjg5OmY0OgorICAgICAgICAwNjplYTo5YjplNDo3Mjo4MjplMzphMTowOTpjMTplOTowMDoxOTpkMzozZTpkNDo3MDo2YjoKKyAgICAgICAgYmE6NzE6YTY6YWE6NTg6YWU6ZjQ6YmI6ZTk6NmM6YjY6ZWY6ODc6Y2M6OWI6YmI6ZmY6Mzk6CisgICAgICAgIGU2OjU2OjYxOmQzOjBhOmE3OmM0OjVjOjRjOjYwOjdiOjA1Ojc3OjI2OjdhOmJmOmQ4OjA3OgorICAgICAgICA1MjoyYzo2MjpmNzo3MDo2MzpkOTozOTpiYzo2ZjoxYzpjMjo3OTpkYzo3NjoyOTphZjpjZToKKyAgICAgICAgYzU6MmM6NjQ6MDQ6NWU6ODg6MzY6NmU6MzE6ZDQ6NDA6MWE6NjI6MzQ6MzY6M2Y6MzU6MDE6CisgICAgICAgIGFlOmFjOjYzOmEwCitTSEExIEZpbmdlcnByaW50PUYxOjhCOjUzOjhEOjFCOkU5OjAzOkI2OkE2OkYwOjU2OjQzOjVCOjE3OjE1Ojg5OkNBOkYzOjZCOkYyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNjkxMDVmNGYuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy82OTEwNWY0Zi4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2ZjQzMDUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNjkxMDVmNGYuMApAQCAtMCwwICsxLDgzIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUR0ekNDQXArZ0F3SUJBZ0lRRE9mZzVSZllSdjZQNVdEOEcvQXdPVEFOQmdrcWhraUc5dzBCQVFVRkFEQmwKK01Rc3dDUVlEVlFRR0V3SlZVekVWTUJNR0ExVUVDaE1NUkdsbmFVTmxjblFnU1c1ak1Sa3dGd1lEVlFRTEV4QjMKK2QzY3VaR2xuYVdObGNuUXVZMjl0TVNRd0lnWURWUVFERXh0RWFXZHBRMlZ5ZENCQmMzTjFjbVZrSUVsRUlGSnYKK2IzUWdRMEV3SGhjTk1EWXhNVEV3TURBd01EQXdXaGNOTXpFeE1URXdNREF3TURBd1dqQmxNUXN3Q1FZRFZRUUcKK0V3SlZVekVWTUJNR0ExVUVDaE1NUkdsbmFVTmxjblFnU1c1ak1Sa3dGd1lEVlFRTEV4QjNkM2N1WkdsbmFXTmwKK2NuUXVZMjl0TVNRd0lnWURWUVFERXh0RWFXZHBRMlZ5ZENCQmMzTjFjbVZrSUVsRUlGSnZiM1FnUTBFd2dnRWkKK01BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3REaFhPNUVPQVhMR0g4N2RnK1hFU3BhN2MKK0pwU0lxdlRPOVNBNUtGaGdEUGlBMnFrVmxUSmhQTFd4S0lTS2l0eWZDZ3lERjNxUGtLeUs1M2xUWERHRUt2WVAKK21ESTJkc3plM1R5b291OXEreUh5VW1IZm55RFhIK0t4MmY0WVpOSVNXMS81V0JnMXZFZk5vVGI1YTMvVXNEZysKK3dSdkRqRFBaMkM4WS9pZ1BzNmVEMXNOdVJNQmhOWllXL2xtY2kzWnQxL0dpU3cwci93dHkycDVnMEk2UU5jWjQKK1ZZY2dvYy9sYlFySVNYd3htRE5zSXVtSDBESmFvcm9UZ2hIdE9SZWRtVHB5b2ViNnBOblZGekYxcm9WOUlxNC8KK0FVYUc5aWg1eUxIYTVGY1h4SDRjRHJDMGtxWldzNzJ5bCsycXAvQzN4YWcvbFJiUS82R1c2d2hmR0hkUEFnTUIKK0FBR2pZekJoTUE0R0ExVWREd0VCL3dRRUF3SUJoakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVcKK0JCUkY2Nkt2OUpMTGdqRXRVWXVucHlHZDgyM0lEekFmQmdOVkhTTUVHREFXZ0JSRjY2S3Y5SkxMZ2pFdFVZdW4KK3B5R2Q4MjNJRHpBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQW9nNjgzK0x0OE9OeWMzcGtsTC8zY21iWU11UkMKK2RXS3VoK3Z5MWRuZVZyT2Z6TTRVS0xrTmwyQmNFa3hZNU5NOWcwbEZXSmMxYVJxb1IrcFd4bm1yRXRobmdZVGYKK2Z3azhsT2E0Sml3Z3ZUMnpLSW4zWC84aTRwZUVIK2xsNzRmZzM4Rm5TYk5kNjdJSkt1c203WGkrZlQ4cjg3Y20KK05XMWZpUUcyU1Z1ZkFRV2JxejBsd2N5MmY4THhiNGJHK21SbzY0RXRsT3RDdC9xTUh0MWk4YjVRWjdkc3ZmUHgKK0gyc01OZ2NXZnpkOHFWdHRldkVTUm1DRDF5Y0V2a3ZPbDc3RFp5cG9FZCtBNXd3elpyOFREUlJ1ODM4Zll4QWUKKytvMGJKVzFzajZXM1lRR3gwcU1tb1JCeG5hM2l3L25EbVZHM0t3Y0l6aTdtVUxLbitncEZMNkx3OGc9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgMGM6ZTc6ZTA6ZTU6MTc6ZDg6NDY6ZmU6OGY6ZTU6NjA6ZmM6MWI6ZjA6MzA6MzkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgTz1EaWdpQ2VydCBJbmMsIE9VPXd3dy5kaWdpY2VydC5jb20sIENOPURpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTm92IDEwIDAwOjAwOjAwIDIwMDYgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBOb3YgMTAgMDA6MDA6MDAgMjAzMSBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgTz1EaWdpQ2VydCBJbmMsIE9VPXd3dy5kaWdpY2VydC5jb20sIENOPURpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YWQ6MGU6MTU6Y2U6ZTQ6NDM6ODA6NWM6YjE6ODc6ZjM6Yjc6NjA6Zjk6CisgICAgICAgICAgICAgICAgICAgIDcxOjEyOmE1OmFlOmRjOjI2Ojk0Ojg4OmFhOmY0OmNlOmY1OjIwOjM5OjI4OgorICAgICAgICAgICAgICAgICAgICA1ODo2MDowYzpmODo4MDpkYTphOToxNTo5NTozMjo2MTozYzpiNTpiMToyODoKKyAgICAgICAgICAgICAgICAgICAgODQ6OGE6OGE6ZGM6OWY6MGE6MGM6ODM6MTc6N2E6OGY6OTA6YWM6OGE6ZTc6CisgICAgICAgICAgICAgICAgICAgIDc5OjUzOjVjOjMxOjg0OjJhOmY2OjBmOjk4OjMyOjM2Ojc2OmNjOmRlOmRkOgorICAgICAgICAgICAgICAgICAgICAzYzphODphMjplZjo2YTpmYjoyMTpmMjo1Mjo2MTpkZjo5ZjoyMDpkNzoxZjoKKyAgICAgICAgICAgICAgICAgICAgZTI6YjE6ZDk6ZmU6MTg6NjQ6ZDI6MTI6NWI6NWY6Zjk6NTg6MTg6MzU6YmM6CisgICAgICAgICAgICAgICAgICAgIDQ3OmNkOmExOjM2OmY5OjZiOjdmOmQ0OmIwOjM4OjNlOmMxOjFiOmMzOjhjOgorICAgICAgICAgICAgICAgICAgICAzMzpkOTpkODoyZjoxODpmZToyODowZjpiMzphNzo4MzpkNjpjMzo2ZTo0NDoKKyAgICAgICAgICAgICAgICAgICAgYzA6NjE6MzU6OTY6MTY6ZmU6NTk6OWM6OGI6NzY6NmQ6ZDc6ZjE6YTI6NGI6CisgICAgICAgICAgICAgICAgICAgIDBkOjJiOmZmOjBiOjcyOmRhOjllOjYwOmQwOjhlOjkwOjM1OmM2Ojc4OjU1OgorICAgICAgICAgICAgICAgICAgICA4NzoyMDphMTpjZjplNTo2ZDowYTpjODo0OTo3YzozMTo5ODozMzo2YzoyMjoKKyAgICAgICAgICAgICAgICAgICAgZTk6ODc6ZDA6MzI6NWE6YTI6YmE6MTM6ODI6MTE6ZWQ6Mzk6MTc6OWQ6OTk6CisgICAgICAgICAgICAgICAgICAgIDNhOjcyOmExOmU2OmZhOmE0OmQ5OmQ1OjE3OjMxOjc1OmFlOjg1OjdkOjIyOgorICAgICAgICAgICAgICAgICAgICBhZTozZjowMTo0Njo4NjpmNjoyODo3OTpjODpiMTpkYTplNDo1NzoxNzpjNDoKKyAgICAgICAgICAgICAgICAgICAgN2U6MWM6MGU6YjA6YjQ6OTI6YTY6NTY6YjM6YmQ6YjI6OTc6ZWQ6YWE6YTc6CisgICAgICAgICAgICAgICAgICAgIGYwOmI3OmM1OmE4OjNmOjk1OjE2OmQwOmZmOmExOjk2OmViOjA4OjVmOjE4OgorICAgICAgICAgICAgICAgICAgICA3Nzo0ZgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIERpZ2l0YWwgU2lnbmF0dXJlLCBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICA0NTpFQjpBMjpBRjpGNDo5MjpDQjo4MjozMToyRDo1MTo4QjpBNzpBNzoyMTo5RDpGMzo2RDpDODowRgorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6NDU6RUI6QTI6QUY6RjQ6OTI6Q0I6ODI6MzE6MkQ6NTE6OEI6QTc6QTc6MjE6OUQ6RjM6NkQ6Qzg6MEYKKworICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBhMjowZTpiYzpkZjplMjplZDpmMDplMzo3Mjo3Mzo3YTo2NDo5NDpiZjpmNzo3Mjo2NjpkODoKKyAgICAgICAgMzI6ZTQ6NDI6NzU6NjI6YWU6ODc6ZWI6ZjI6ZDU6ZDk6ZGU6NTY6YjM6OWY6Y2M6Y2U6MTQ6CisgICAgICAgIDI4OmI5OjBkOjk3OjYwOjVjOjEyOjRjOjU4OmU0OmQzOjNkOjgzOjQ5OjQ1OjU4Ojk3OjM1OgorICAgICAgICA2OToxYTphODo0NzplYTo1NjpjNjo3OTphYjoxMjpkODo2Nzo4MTo4NDpkZjo3ZjowOTozYzoKKyAgICAgICAgOTQ6ZTY6Yjg6MjY6MmM6MjA6YmQ6M2Q6YjM6Mjg6ODk6Zjc6NWY6ZmY6MjI6ZTI6OTc6ODQ6CisgICAgICAgIDFmOmU5OjY1OmVmOjg3OmUwOmRmOmMxOjY3OjQ5OmIzOjVkOmViOmIyOjA5OjJhOmViOjI2OgorICAgICAgICBlZDo3ODpiZTo3ZDozZjoyYjpmMzpiNzoyNjozNTo2ZDo1Zjo4OTowMTpiNjo0OTo1Yjo5ZjoKKyAgICAgICAgMDE6MDU6OWI6YWI6M2Q6MjU6YzE6Y2M6YjY6N2Y6YzI6ZjE6NmY6ODY6YzY6ZmE6NjQ6Njg6CisgICAgICAgIGViOjgxOjJkOjk0OmViOjQyOmI3OmZhOjhjOjFlOmRkOjYyOmYxOmJlOjUwOjY3OmI3OjZjOgorICAgICAgICBiZDpmMzpmMToxZjo2YjowYzozNjowNzoxNjo3ZjozNzo3YzphOTo1Yjo2ZDo3YTpmMToxMjoKKyAgICAgICAgNDY6NjA6ODM6ZDc6Mjc6MDQ6YmU6NGI6Y2U6OTc6YmU6YzM6Njc6MmE6Njg6MTE6ZGY6ODA6CisgICAgICAgIGU3OjBjOjMzOjY2OmJmOjEzOjBkOjE0OjZlOmYzOjdmOjFmOjYzOjEwOjFlOmZhOjhkOjFiOgorICAgICAgICAyNTo2ZDo2Yzo4ZjphNTpiNzo2MTowMTpiMTpkMjphMzoyNjphMToxMDo3MTo5ZDphZDplMjoKKyAgICAgICAgYzM6Zjk6YzM6OTk6NTE6Yjc6MmI6MDc6MDg6Y2U6MmU6ZTY6NTA6YjI6YTc6ZmE6MGE6NDU6CisgICAgICAgIDJmOmEyOmYwOmYyCitTSEExIEZpbmdlcnByaW50PTA1OjYzOkI4OjYzOjBEOjYyOkQ3OjVBOkJCOkM4OkFCOjFFOjRCOkRGOkI1OkE4Ojk5OkIyOjREOjQzCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNmFkZjA3OTkuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy82YWRmMDc5OS4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU5MTcwZTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNmFkZjA3OTkuMApAQCAtMCwwICsxLDgwIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUQ1VENDQXMyZ0F3SUJBZ0lFT2VTWG5qQU5CZ2txaGtpRzl3MEJBUVVGQURDQmdqRUxNQWtHQTFVRUJoTUMKK1ZWTXhGREFTQmdOVkJBb1RDMWRsYkd4eklFWmhjbWR2TVN3d0tnWURWUVFMRXlOWFpXeHNjeUJHWVhKbmJ5QkQKK1pYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVEV2TUMwR0ExVUVBeE1tVjJWc2JITWdSbUZ5WjI4Z1VtOXYKK2RDQkRaWEowYVdacFkyRjBaU0JCZFhSb2IzSnBkSGt3SGhjTk1EQXhNREV4TVRZME1USTRXaGNOTWpFd01URTAKK01UWTBNVEk0V2pDQmdqRUxNQWtHQTFVRUJoTUNWVk14RkRBU0JnTlZCQW9UQzFkbGJHeHpJRVpoY21kdk1Td3cKK0tnWURWUVFMRXlOWFpXeHNjeUJHWVhKbmJ5QkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVRFdk1DMEcKK0ExVUVBeE1tVjJWc2JITWdSbUZ5WjI4Z1VtOXZkQ0JEWlhKMGFXWnBZMkYwWlNCQmRYUm9iM0pwZEhrd2dnRWkKK01BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRFZxRE03SnZrMC84MmJmdVVFUjg0QTRuMTMKKzV6SENMaWVsVFdpNU1icU5RMW1YeDNPcWZ6MWNRSjRGNWFIaWlkbE11RCtiK1F5MHlHSVpMRVd1a1I1emNVSEUKK1N4UDljTUlsckNMMWRRdTNVK1NsSzkzT3ZSdzZlc1AzRTQ4bVZKd1dhMnV2KzlpV3NXQ2FTT0FsSWlSNU5NNE8KK0pnQUxUcXY5aTg2QzF5OEljR2pCcUFyNWRFOEhxNlQ1NG9OK0ozTjBQcmo1T0VMOHBhaGJTQ096NitNbHNvQ3UKK2x0UUtuTUo0bXNab0dLNDNZamRlVVhXb1dHUEFVZTVBZUg2b3J4cWc0YkI0blZDTWUrZXovSTRqc050bEFIQ0UKK0FRZ0FGRzVVaHBxNnpQazNFUGJnM29RdG5hU0ZOOU9INHhYUXdSZVFmaGtoYWhLcGR2MFNBdWxQSVY0WEFnTUIKK0FBR2pZVEJmTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3VEFZRFZSMGdCRVV3UXpCQkJndGdoa2dCaHZ0N2h3Y0IKK0N6QXlNREFHQ0NzR0FRVUZCd0lCRmlSb2RIUndPaTh2ZDNkM0xuZGxiR3h6Wm1GeVoyOHVZMjl0TDJObGNuUncKK2IyeHBZM2t3RFFZSktvWklodmNOQVFFRkJRQURnZ0VCQU5JbjNad0tkeXU3SXZJQ3RVcEtrZm5STGI3a3V4cG8KKzd3NmtBT251NSsvdTl2bmxkS1RDMkZKWXhIVDd6bXUxT3lsNUdGcnZtKzBmYXpidVNDVWxGTFpXb2hEbzdxZC8KKzBEK2owTU5kSnU0SHpNUEJKQ0dISHQ4cUVsTnZRUmJuN2E2VStveHkraE5IOER4K3JuMFJPaFBzN2ZwdmNtUjcKK25YMS9KdjE2K3lXdDZqNHBmMHpqQUZjeXNMUHA3Vk1YMll1eUZBNHc2T1hWRThaa3I4UUExZGhZSlB6MWorengKK3gzMmwydzhuMGNieVFJam1IL1pocVBSQ3lMazMwNm0rTEZaNHduS2JXVjAxUUlyb1RtTWF0dWtnYWxIaXpxU1EKKzMzWndtVnh3UTAyM3RxY1paRTZTdDhXUlBIOUlGbVY3RnYzTC9QdloxZFpQSVdVN1NuOUhvL3M9CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDk3MTI4MjMzNCAoMHgzOWU0OTc5ZSkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgTz1XZWxscyBGYXJnbywgT1U9V2VsbHMgRmFyZ28gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHksIENOPVdlbGxzIEZhcmdvIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5CisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBPY3QgMTEgMTY6NDE6MjggMjAwMCBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEphbiAxNCAxNjo0MToyOCAyMDIxIEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPVdlbGxzIEZhcmdvLCBPVT1XZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSwgQ049V2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmQ1OmE4OjMzOjNiOjI2OmY5OjM0OmZmOmNkOjliOjdlOmU1OjA0OjQ3OgorICAgICAgICAgICAgICAgICAgICBjZTowMDplMjo3ZDo3NzplNzozMTpjMjoyZToyNzphNTo0ZDo2ODpiOTozMToKKyAgICAgICAgICAgICAgICAgICAgYmE6OGQ6NDM6NTk6OTc6Yzc6NzM6YWE6N2Y6M2Q6NWM6NDA6OWU6MDU6ZTU6CisgICAgICAgICAgICAgICAgICAgIGExOmUyOjg5OmQ5OjRjOmI4OjNmOjliOmY5OjBjOmI0OmM4OjYyOjE5OjJjOgorICAgICAgICAgICAgICAgICAgICA0NTphZTo5MToxZTo3Mzo3MTo0MTpjNDo0YjoxMzpmZDo3MDpjMjoyNTphYzoKKyAgICAgICAgICAgICAgICAgICAgMjI6ZjU6NzU6MGI6Yjc6NTM6ZTQ6YTU6MmI6ZGQ6Y2U6YmQ6MWM6M2E6N2E6CisgICAgICAgICAgICAgICAgICAgIGMzOmY3OjEzOjhmOjI2OjU0OjljOjE2OjZiOjZiOmFmOmZiOmQ4Ojk2OmIxOgorICAgICAgICAgICAgICAgICAgICA2MDo5YTo0ODplMDoyNToyMjoyNDo3OTozNDpjZTowZToyNjowMDowYjo0ZToKKyAgICAgICAgICAgICAgICAgICAgYWI6ZmQ6OGI6Y2U6ODI6ZDc6MmY6MDg6NzA6Njg6YzE6YTg6MGE6Zjk6NzQ6CisgICAgICAgICAgICAgICAgICAgIDRmOjA3OmFiOmE0OmY5OmUyOjgzOjdlOjI3OjczOjc0OjNlOmI4OmY5OjM4OgorICAgICAgICAgICAgICAgICAgICA0MjpmYzphNTphODo1Yjo0ODoyMzpiMzplYjplMzoyNTpiMjo4MDphZTo5NjoKKyAgICAgICAgICAgICAgICAgICAgZDQ6MGE6OWM6YzI6Nzg6OWE6YzY6Njg6MTg6YWU6Mzc6NjI6Mzc6NWU6NTE6CisgICAgICAgICAgICAgICAgICAgIDc1OmE4OjU4OjYzOmMwOjUxOmVlOjQwOjc4OjdlOmE4OmFmOjFhOmEwOmUxOgorICAgICAgICAgICAgICAgICAgICBiMDo3ODo5ZDo1MDo4Yzo3YjplNzpiMzpmYzo4ZToyMzpiMDpkYjo2NTowMDoKKyAgICAgICAgICAgICAgICAgICAgNzA6ODQ6MDE6MDg6MDA6MTQ6NmU6NTQ6ODY6OWE6YmE6Y2M6Zjk6Mzc6MTA6CisgICAgICAgICAgICAgICAgICAgIGY2OmUwOmRlOjg0OjJkOjlkOmE0Ojg1OjM3OmQzOjg3OmUzOjE1OmQwOmMxOgorICAgICAgICAgICAgICAgICAgICAxNzo5MDo3ZToxOToyMTo2YToxMjphOTo3NjpmZDoxMjowMjplOTo0ZjoyMToKKyAgICAgICAgICAgICAgICAgICAgNWU6MTcKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBDZXJ0aWZpY2F0ZSBQb2xpY2llczogCisgICAgICAgICAgICAgICAgUG9saWN5OiAyLjE2Ljg0MC4xLjExNDE3MS45MDMuMS4xMQorICAgICAgICAgICAgICAgICAgQ1BTOiBodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRwb2xpY3kKKworICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBkMjoyNzpkZDo5YzowYTo3NzoyYjpiYjoyMjpmMjowMjpiNTo0YTo0YTo5MTpmOTpkMToyZDoKKyAgICAgICAgYmU6ZTQ6YmI6MWE6Njg6ZWY6MGU6YTQ6MDA6ZTk6ZWU6ZTc6ZWY6ZWU6ZjY6Zjk6ZTU6NzQ6CisgICAgICAgIGE0OmMyOmQ4OjUyOjU4OmM0Ojc0OmZiOmNlOjZiOmI1OjNiOjI5Ojc5OjE4OjVhOmVmOjliOgorICAgICAgICBlZDoxZjo2YjozNjplZTo0ODoyNToyNToxNDpiNjo1NjphMjoxMDplODplZTphNzo3ZjpkMDoKKyAgICAgICAgM2Y6YTM6ZDA6YzM6NWQ6MjY6ZWU6MDc6Y2M6YzM6YzE6MjQ6MjE6ODc6MWU6ZGY6MmE6MTI6CisgICAgICAgIDUzOjZmOjQxOjE2OmU3OmVkOmFlOjk0OmZhOjhjOjcyOmZhOjEzOjQ3OmYwOjNjOjdlOmFlOgorICAgICAgICA3ZDoxMTozYToxMzplYzplZDpmYTo2Zjo3Mjo2NDo3Yjo5ZDo3ZDo3ZjoyNjpmZDo3YTpmYjoKKyAgICAgICAgMjU6YWQ6ZWE6M2U6Mjk6N2Y6NGM6ZTM6MDA6NTc6MzI6YjA6YjM6ZTk6ZWQ6NTM6MTc6ZDk6CisgICAgICAgIDhiOmIyOjE0OjBlOjMwOmU4OmU1OmQ1OjEzOmM2OjY0OmFmOmM0OjAwOmQ1OmQ4OjU4OjI0OgorICAgICAgICBmYzpmNTo4ZjplYzpmMTpjNzo3ZDphNTpkYjowZjoyNzpkMTpjNjpmMjo0MDo4ODplNjoxZjoKKyAgICAgICAgZjY6NjE6YTg6ZjQ6NDI6Yzg6Yjk6Mzc6ZDM6YTk6YmU6MmM6NTY6Nzg6YzI6NzI6OWI6NTk6CisgICAgICAgIDVkOjM1OjQwOjhhOmU4OjRlOjYzOjFhOmI2OmU5OjIwOjZhOjUxOmUyOmNlOmE0OjkwOmRmOgorICAgICAgICA3Njo3MDo5OTo1Yzo3MDo0Mzo0ZDpiNzpiNjphNzoxOTo2NDo0ZTo5MjpiNzpjNTo5MTozYzoKKyAgICAgICAgN2Y6NDg6MTY6NjU6N2I6MTY6ZmQ6Y2I6ZmM6ZmI6ZDk6ZDU6ZDY6NGY6MjE6NjU6M2I6NGE6CisgICAgICAgIDdmOjQ3OmEzOmZiCitTSEExIEZpbmdlcnByaW50PTkzOkU2OkFCOjIyOjAzOjAzOkI1OjIzOjI4OkRDOkRBOjU2OjlFOkJBOkU0OkQxOkQxOkNDOkZCOjY1CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNmU4YmY5OTYuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy82ZThiZjk5Ni4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVlNDI2ODQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNmU4YmY5OTYuMApAQCAtMCwwICsxLDcyIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSURERENDQWZTZ0F3SUJBZ0lEQVFBZ01BMEdDU3FHU0liM0RRRUJCUVVBTUQ0eEN6QUpCZ05WQkFZVEFsQk0KK01Sc3dHUVlEVlFRS0V4SlZibWw2WlhSdklGTndMaUI2SUc4dWJ5NHhFakFRQmdOVkJBTVRDVU5sY25SMWJTQkQKK1FUQWVGdzB3TWpBMk1URXhNRFEyTXpsYUZ3MHlOekEyTVRFeE1EUTJNemxhTUQ0eEN6QUpCZ05WQkFZVEFsQk0KK01Sc3dHUVlEVlFRS0V4SlZibWw2WlhSdklGTndMaUI2SUc4dWJ5NHhFakFRQmdOVkJBTVRDVU5sY25SMWJTQkQKK1FUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU02eHdTN1RUM3pOSmM0WVBrL0UKK2pHK0FhblBJVzFING05TGN1d0Jjc2FEOGRRUHVnZkNJN2lOUzZlWVZNNDJzTFFuRmR2a3JPWUNKNUpkTGtLV28KK2VQaHpRM3VrWWJEWVdNemhiR1orblBNSlhsVmpoTldvNy9PeExqQm9zOFE4Mkt4dWpabGFrRTQwM0RhYWo0R0kKK1VMZHRsa0lKODllVmd3MUJTN0JxYS9qOEQzNWluMmZFN1NaZkVDWVBDRS93cEZjb3pvKzQ3VVgyYnU0bFhhcHUKK09iN2treS9aUjZCeTYvcW1XNi9LVXovaURzYVdWaEZ1OStsbXFTYllmNVZUN1FxRmlMcFBLYVZDakY2Mi9JVWcKK0FLcG9DNkVhaFFHY3hFWmpnb2kySXJIdS9xcEdXWDdQTlN6VnR0cGQ5MGd6RkZTMjY5bHZ6czJJMXFzYjJwWTcKK0hWa0NBd0VBQWFNVE1CRXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUEKK3VJM083K2NVdXMvdXNFU1NiTFE1UHFLRWJxMjRJWGZTMUhlQ2grWWdRWUh1NHZnUnQyUFJGemUrR1hZa0hBUWEKK1RPczlxbWR2TGRUTi9tVXhjTVVicGdJS3VtQjdiVmpDbWtuK1l6SUxhK002d0t5ck83RG8wd2xSakJDRHhqVGcKK3hTdmdHclpnRkNkc01uZU12TEp5bU0vTnpEKzV5Q1JDRk5aWC9PWW1RNmtkNVlDUXpnTlVLRDczUDlQNFRlMXEKK0NqcVRFNXM3RkNNVFk1dy8wWWNuZWVWTVVlTUJyWVZkR2p1eDFYTVFwTlB5dkc1azlWcFdrS2pIRGt4MER5NXgKK08vZklSL1JwYnhYeUVWNkRIcHg4VXE3OUF0b1NxRmxuR051OGNOMmJzV250Z002SlFFaHFEalhLS1dZVklaUXMKKzZHQXFtNFZLUVBOcmlpVHNCaFlzY3c9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiA2NTU2OCAoMHgxMDAyMCkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1QTCwgTz1Vbml6ZXRvIFNwLiB6IG8uby4sIENOPUNlcnR1bSBDQQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogSnVuIDExIDEwOjQ2OjM5IDIwMDIgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBKdW4gMTEgMTA6NDY6MzkgMjAyNyBHTVQKKyAgICAgICAgU3ViamVjdDogQz1QTCwgTz1Vbml6ZXRvIFNwLiB6IG8uby4sIENOPUNlcnR1bSBDQQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6Y2U6YjE6YzE6MmU6ZDM6NGY6N2M6Y2Q6MjU6Y2U6MTg6M2U6NGY6YzQ6CisgICAgICAgICAgICAgICAgICAgIDhjOjZmOjgwOjZhOjczOmM4OjViOjUxOmY4OjliOmQyOmRjOmJiOjAwOjVjOgorICAgICAgICAgICAgICAgICAgICBiMTphMDpmYzo3NTowMzplZTo4MTpmMDo4ODplZToyMzo1MjplOTplNjoxNToKKyAgICAgICAgICAgICAgICAgICAgMzM6OGQ6YWM6MmQ6MDk6YzU6NzY6Zjk6MmI6Mzk6ODA6ODk6ZTQ6OTc6NGI6CisgICAgICAgICAgICAgICAgICAgIDkwOmE1OmE4Ojc4OmY4OjczOjQzOjdiOmE0OjYxOmIwOmQ4OjU4OmNjOmUxOgorICAgICAgICAgICAgICAgICAgICA2Yzo2Njo3ZTo5YzpmMzowOTo1ZTo1NTo2Mzo4NDpkNTphODplZjpmMzpiMToKKyAgICAgICAgICAgICAgICAgICAgMmU6MzA6Njg6YjM6YzQ6M2M6ZDg6YWM6NmU6OGQ6OTk6NWE6OTA6NGU6MzQ6CisgICAgICAgICAgICAgICAgICAgIGRjOjM2OjlhOjhmOjgxOjg4OjUwOmI3OjZkOjk2OjQyOjA5OmYzOmQ3Ojk1OgorICAgICAgICAgICAgICAgICAgICA4MzowZDo0MTo0YjpiMDo2YTo2YjpmODpmYzowZjo3ZTo2Mjo5Zjo2NzpjNDoKKyAgICAgICAgICAgICAgICAgICAgZWQ6MjY6NWY6MTA6MjY6MGY6MDg6NGY6ZjA6YTQ6NTc6Mjg6Y2U6OGY6Yjg6CisgICAgICAgICAgICAgICAgICAgIGVkOjQ1OmY2OjZlOmVlOjI1OjVkOmFhOjZlOjM5OmJlOmU0OjkzOjJmOmQ5OgorICAgICAgICAgICAgICAgICAgICA0NzphMDo3MjplYjpmYTphNjo1YjphZjpjYTo1MzozZjplMjowZTpjNjo5NjoKKyAgICAgICAgICAgICAgICAgICAgNTY6MTE6NmU6Zjc6ZTk6NjY6YTk6MjY6ZDg6N2Y6OTU6NTM6ZWQ6MGE6ODU6CisgICAgICAgICAgICAgICAgICAgIDg4OmJhOjRmOjI5OmE1OjQyOjhjOjVlOmI2OmZjOjg1OjIwOjAwOmFhOjY4OgorICAgICAgICAgICAgICAgICAgICAwYjphMToxYTo4NTowMTo5YzpjNDo0Njo2Mzo4Mjo4ODpiNjoyMjpiMTplZToKKyAgICAgICAgICAgICAgICAgICAgZmU6YWE6NDY6NTk6N2U6Y2Y6MzU6MmM6ZDU6YjY6ZGE6NWQ6Zjc6NDg6MzM6CisgICAgICAgICAgICAgICAgICAgIDE0OjU0OmI2OmViOmQ5OjZmOmNlOmNkOjg4OmQ2OmFiOjFiOmRhOjk2OjNiOgorICAgICAgICAgICAgICAgICAgICAxZDo1OQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBiODo4ZDpjZTplZjplNzoxNDpiYTpjZjplZTpiMDo0NDo5Mjo2YzpiNDozOTozZTphMjo4NDoKKyAgICAgICAgNmU6YWQ6Yjg6MjE6Nzc6ZDI6ZDQ6Nzc6ODI6ODc6ZTY6MjA6NDE6ODE6ZWU6ZTI6Zjg6MTE6CisgICAgICAgIGI3OjYzOmQxOjE3OjM3OmJlOjE5Ojc2OjI0OjFjOjA0OjFhOjRjOmViOjNkOmFhOjY3OjZmOgorICAgICAgICAyZDpkNDpjZDpmZTo2NTozMTo3MDpjNToxYjphNjowMjowYTpiYTo2MDo3Yjo2ZDo1ODpjMjoKKyAgICAgICAgOWE6NDk6ZmU6NjM6MzI6MGI6NmI6ZTM6M2E6YzA6YWM6YWI6M2I6YjA6ZTg6ZDM6MDk6NTE6CisgICAgICAgIDhjOjEwOjgzOmM2OjM0OmUwOmM1OjJiOmUwOjFhOmI2OjYwOjE0OjI3OjZjOjMyOjc3OjhjOgorICAgICAgICBiYzpiMjo3Mjo5ODpjZjpjZDpjYzozZjpiOTpjODoyNDo0MjoxNDpkNjo1NzpmYzplNjoyNjoKKyAgICAgICAgNDM6YTk6MWQ6ZTU6ODA6OTA6Y2U6MDM6NTQ6Mjg6M2U6Zjc6M2Y6ZDM6Zjg6NGQ6ZWQ6NmE6CisgICAgICAgIDBhOjNhOjkzOjEzOjliOjNiOjE0OjIzOjEzOjYzOjljOjNmOmQxOjg3OjI3Ojc5OmU1OjRjOgorICAgICAgICA1MTplMzowMTphZDo4NTo1ZDoxYTozYjpiMTpkNTo3MzoxMDphNDpkMzpmMjpiYzo2ZTo2NDoKKyAgICAgICAgZjU6NWE6NTY6OTA6YTg6Yzc6MGU6NGM6NzQ6MGY6MmU6NzE6M2I6Zjc6Yzg6NDc6ZjQ6Njk6CisgICAgICAgIDZmOjE1OmYyOjExOjVlOjgzOjFlOjljOjdjOjUyOmFlOmZkOjAyOmRhOjEyOmE4OjU5OjY3OgorICAgICAgICAxODpkYjpiYzo3MDpkZDo5YjpiMTo2OTplZDo4MDpjZTo4OTo0MDo0ODo2YTowZTozNTpjYToKKyAgICAgICAgMjk6NjY6MTU6MjE6OTQ6MmM6ZTg6NjA6MmE6OWI6ODU6NGE6NDA6ZjM6NmI6OGE6MjQ6ZWM6CisgICAgICAgIDA2OjE2OjJjOjczCitTSEExIEZpbmdlcnByaW50PTYyOjUyOkRDOjQwOkY3OjExOjQzOkEyOjJGOkRFOjlFOkY3OjM0OjhFOjA2OjQyOjUxOkIxOjgxOjE4CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNmZjYzEyNWQuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy82ZmNjMTI1ZC4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVjOGU1ZTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNmZjYzEyNWQuMApAQCAtMCwwICsxLDgwIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSURvakNDQW9xZ0F3SUJBZ0lRRTRZMVRSMC9CdkxCK1dVRjFaQWNZakFOQmdrcWhraUc5dzBCQVFVRkFEQnIKK01Rc3dDUVlEVlFRR0V3SlZVekVOTUFzR0ExVUVDaE1FVmtsVFFURXZNQzBHQTFVRUN4TW1WbWx6WVNCSmJuUmwKK2NtNWhkR2x2Ym1Gc0lGTmxjblpwWTJVZ1FYTnpiMk5wWVhScGIyNHhIREFhQmdOVkJBTVRFMVpwYzJFZ1pVTnYKK2JXMWxjbU5sSUZKdmIzUXdIaGNOTURJd05qSTJNREl4T0RNMldoY05Nakl3TmpJME1EQXhOakV5V2pCck1Rc3cKK0NRWURWUVFHRXdKVlV6RU5NQXNHQTFVRUNoTUVWa2xUUVRFdk1DMEdBMVVFQ3hNbVZtbHpZU0JKYm5SbGNtNWgKK2RHbHZibUZzSUZObGNuWnBZMlVnUVhOemIyTnBZWFJwYjI0eEhEQWFCZ05WQkFNVEUxWnBjMkVnWlVOdmJXMWwKK2NtTmxJRkp2YjNRd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUN2Vjk1V0htNmgKKzJtQ3hsQ2ZMRjlzSFA0Q0ZUOGljdHREMGIwL1BtZGpoMjhKSVhEcXNPVFBISDJxTEpqMHJOZlZJc1pIQkFrNEUKK2xwRjdzRFB3c1JST0VXKzFRSzhiUmFWSzczNjJyUEtnSDFnL0VrWmdQSTJoNEgzUFZ6NHpIdnRIOGFvVmx3ZFYKK1pxVzFMUzdZZ0ZteXB3MjNSdXdoWS84MXE2VUN6eXIwVFA1NzlaUmRoRTJvOG1DUDJ3NGxQSjl6Y2MrVTMwcnEKKzI5OXlPSXp6bHIzeEY3elN1anRGV3NhbjlzWVhpd0dkL0Jtb0tvTVd1RHBJL2s0K29Lc0dHZWxUODRBVEIrMHQKK3Z6OEtQRlVnT1N3c0FHbDBsVXE4SUxLcGVlVVlpWkdvM0J4Tjc3dCtOd3RkL2ptbGlGS01BR3pzR0h4QnZmYUwKK2RYZTZZSjJFNS80dEFnTUJBQUdqUWpCQU1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RnWURWUjBQQVFIL0JBUUQKK0FnRUdNQjBHQTFVZERnUVdCQlFWT0lNUFB5dy9jRE1lelViK0I0d2c0TmZEdHpBTkJna3Foa2lHOXcwQkFRVUYKK0FBT0NBUUVBWC9GQmZYeGNDTGtyNE5XU1IvcG5YS1VUd3dNaG15dE1pVWJQV1UzSi9xVkF0bVBOM1hFb2xXY1IKK3pDU3MwMFJzY2E0QklHc0RvbzhZdHlrNmZlVVdZRk40UE1DdkZZUDNqMUl6Skwxa2s1ZnVpL2ZiR0todGNiUDMKK0xCZlFkQ1ZwOS81clBKUytUVXRCakU3aWM5RGprQ0p6UTgzejcrcHp6a1dLc0taSi8weDluWEdJeEhZZGtGc2QKKzd2M005Kzc5WUtXeGVoWngwUmJRZkJJOGJHbVgyNjVmT1pwd0x3VThHVVlFbVNBMjBHQnVZUWE3RmtLTWNQY3cKKysrRGJacU1BQWIzbUxOcVJYNkJHaTAxcW5EMDkzUVZHL25hL29Bbzg1QURtSjdmL2hDM2V1aUlubGhCeDZ5THQKKzM5OHpuTS9qcmE2TzFJN21UMUd2RnBMZ1hQWUhEdz09CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICAxMzo4NjozNTo0ZDoxZDozZjowNjpmMjpjMTpmOTo2NTowNTpkNTo5MDoxYzo2MgorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPVZJU0EsIE9VPVZpc2EgSW50ZXJuYXRpb25hbCBTZXJ2aWNlIEFzc29jaWF0aW9uLCBDTj1WaXNhIGVDb21tZXJjZSBSb290CisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBKdW4gMjYgMDI6MTg6MzYgMjAwMiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEp1biAyNCAwMDoxNjoxMiAyMDIyIEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPVZJU0EsIE9VPVZpc2EgSW50ZXJuYXRpb25hbCBTZXJ2aWNlIEFzc29jaWF0aW9uLCBDTj1WaXNhIGVDb21tZXJjZSBSb290CisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDphZjo1NzpkZTo1NjoxZTo2ZTphMTpkYTo2MDpiMTo5NDoyNzpjYjoxNzoKKyAgICAgICAgICAgICAgICAgICAgZGI6MDc6M2Y6ODA6ODU6NGY6Yzg6OWM6YjY6ZDA6ZjQ6NmY6NGY6Y2Y6OTk6CisgICAgICAgICAgICAgICAgICAgIGQ4OmUxOmRiOmMyOjQ4OjVjOjNhOmFjOjM5OjMzOmM3OjFmOjZhOjhiOjI2OgorICAgICAgICAgICAgICAgICAgICAzZDoyYjozNTpmNTo0ODpiMTo5MTpjMTowMjo0ZTowNDo5Njo5MTo3YjpiMDoKKyAgICAgICAgICAgICAgICAgICAgMzM6ZjA6YjE6MTQ6NGU6MTE6NmY6YjU6NDA6YWY6MWI6NDU6YTU6NGE6ZWY6CisgICAgICAgICAgICAgICAgICAgIDdlOmI2OmFjOmYyOmEwOjFmOjU4OjNmOjEyOjQ2OjYwOjNjOjhkOmExOmUwOgorICAgICAgICAgICAgICAgICAgICA3ZDpjZjo1NzozZTozMzoxZTpmYjo0NzpmMTphYToxNTo5NzowNzo1NTo2NjoKKyAgICAgICAgICAgICAgICAgICAgYTU6YjU6MmQ6MmU6ZDg6ODA6NTk6YjI6YTc6MGQ6Yjc6NDY6ZWM6MjE6NjM6CisgICAgICAgICAgICAgICAgICAgIGZmOjM1OmFiOmE1OjAyOmNmOjJhOmY0OjRjOmZlOjdiOmY1Ojk0OjVkOjg0OgorICAgICAgICAgICAgICAgICAgICA0ZDphODpmMjo2MDo4ZjpkYjowZToyNTozYzo5Zjo3Mzo3MTpjZjo5NDpkZjoKKyAgICAgICAgICAgICAgICAgICAgNGE6ZWE6ZGI6ZGY6NzI6Mzg6OGM6ZjM6OTY6YmQ6ZjE6MTc6YmM6ZDI6YmE6CisgICAgICAgICAgICAgICAgICAgIDNiOjQ1OjVhOmM2OmE3OmY2OmM2OjE3OjhiOjAxOjlkOmZjOjE5OmE4OjJhOgorICAgICAgICAgICAgICAgICAgICA4MzoxNjpiODozYTo0ODpmZTo0ZTozZTphMDphYjowNjoxOTplOTo1MzpmMzoKKyAgICAgICAgICAgICAgICAgICAgODA6MTM6MDc6ZWQ6MmQ6YmY6M2Y6MGE6M2M6NTU6MjA6Mzk6MmM6MmM6MDA6CisgICAgICAgICAgICAgICAgICAgIDY5Ojc0Ojk1OjRhOmJjOjIwOmIyOmE5Ojc5OmU1OjE4Ojg5OjkxOmE4OmRjOgorICAgICAgICAgICAgICAgICAgICAxYzo0ZDplZjpiYjo3ZTozNzowYjo1ZDpmZTozOTphNTo4ODo1Mjo4YzowMDoKKyAgICAgICAgICAgICAgICAgICAgNmM6ZWM6MTg6N2M6NDE6YmQ6ZjY6OGI6NzU6Nzc6YmE6NjA6OWQ6ODQ6ZTc6CisgICAgICAgICAgICAgICAgICAgIGZlOjJkCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgMTU6Mzg6ODM6MEY6M0Y6MkM6M0Y6NzA6MzM6MUU6Q0Q6NDY6RkU6MDc6OEM6MjA6RTA6RDc6QzM6QjcKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgNWY6ZjE6NDE6N2Q6N2M6NWM6MDg6Yjk6MmI6ZTA6ZDU6OTI6NDc6ZmE6Njc6NWM6YTU6MTM6CisgICAgICAgIGMzOjAzOjIxOjliOjJiOjRjOjg5OjQ2OmNmOjU5OjRkOmM5OmZlOmE1OjQwOmI2OjYzOmNkOgorICAgICAgICBkZDo3MToyODo5NTo2NzoxMTpjYzoyNDphYzpkMzo0NDo2Yzo3MTphZTowMToyMDo2YjowMzoKKyAgICAgICAgYTI6OGY6MTg6Yjc6Mjk6M2E6N2Q6ZTU6MTY6NjA6NTM6Nzg6M2M6YzA6YWY6MTU6ODM6Zjc6CisgICAgICAgIDhmOjUyOjMzOjI0OmJkOjY0OjkzOjk3OmVlOjhiOmY3OmRiOjE4OmE4OjZkOjcxOmIzOmY3OgorICAgICAgICAyYzoxNzpkMDo3NDoyNTo2OTpmNzpmZTo2YjozYzo5NDpiZTo0ZDo0Yjo0MTo4Yzo0ZTplMjoKKyAgICAgICAgNzM6ZDA6ZTM6OTA6MjI6NzM6NDM6Y2Q6ZjM6ZWY6ZWE6NzM6Y2U6NDU6OGE6YjA6YTY6NDk6CisgICAgICAgIGZmOjRjOjdkOjlkOjcxOjg4OmM0Ojc2OjFkOjkwOjViOjFkOmVlOmZkOmNjOmY3OmVlOmZkOgorICAgICAgICA2MDphNTpiMTo3YToxNjo3MTpkMToxNjpkMDo3YzoxMjozYzo2Yzo2OTo5NzpkYjphZTo1ZjoKKyAgICAgICAgMzk6OWE6NzA6MmY6MDU6M2M6MTk6NDY6MDQ6OTk6MjA6MzY6ZDA6NjA6NmU6NjE6MDY6YmI6CisgICAgICAgIDE2OjQyOjhjOjcwOmY3OjMwOmZiOmUwOmRiOjY2OmEzOjAwOjAxOmJkOmU2OjJjOmRhOjkxOgorICAgICAgICA1ZjphMDo0Njo4Yjo0ZDo2YTo5YzozZDozZDpkZDowNTo0NjpmZTo3NjpiZjphMDowYTozYzoKKyAgICAgICAgZTQ6MDA6ZTY6Mjc6Yjc6ZmY6ODQ6MmQ6ZGU6YmE6MjI6Mjc6OTY6MTA6NzE6ZWI6MjI6ZWQ6CisgICAgICAgIGRmOmRmOjMzOjljOmNmOmUzOmFkOmFlOjhlOmQ0OjhlOmU2OjRmOjUxOmFmOjE2OjkyOmUwOgorICAgICAgICA1YzpmNjowNzowZgorU0hBMSBGaW5nZXJwcmludD03MDoxNzo5Qjo4Njo4QzowMDpBNDpGQTo2MDo5MTo1MjoyMjozRjo5RjozRTozMjpCRDpFMDowNTo2MgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzcyZjM2OWFmLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNzJmMzY5YWYuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMmIzZWUwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzcyZjM2OWFmLjAKQEAgLTAsMCArMSw3NyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEVXpDQ0FqdWdBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUVVGQURCTE1Rc3dDUVlEVlFRR0V3Sk9UekVkCitNQnNHQTFVRUNnd1VRblY1Y0dGemN5QkJVeTA1T0RNeE5qTXpNamN4SFRBYkJnTlZCQU1NRkVKMWVYQmhjM01nCitRMnhoYzNNZ01pQkRRU0F4TUI0WERUQTJNVEF4TXpFd01qVXdPVm9YRFRFMk1UQXhNekV3TWpVd09Wb3dTekVMCitNQWtHQTFVRUJoTUNUazh4SFRBYkJnTlZCQW9NRkVKMWVYQmhjM01nUVZNdE9UZ3pNVFl6TXpJM01SMHdHd1lECitWUVFEREJSQ2RYbHdZWE56SUVOc1lYTnpJRElnUTBFZ01UQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQCitBRENDQVFvQ2dnRUJBSXM4QjBYWTl0L214OHE2alVQRlI0MndXc0U0MjVLRUhLOFQxQTl2TmtZZ3hDN01jWEEwCitvalRUTnk3WTNUcDNMOERyS2VoYzByV3BrVFNISWxuK3pOdm5tYStXd2FqSFFOMmxGWXh1eUh5WEE4dm1JUExYCitsMTh4b1M4MzByN3V2cW10cUV5ZUlXWkRPNmk4OHdtak9OVlpKTUhDUjNheGlGeUNPN3NycGdUWGpBZVB6ZFZCCitIZkN1dUNrc2xGSmdOSlE3MnVBNDBaMHpQaFgwa3pMRkFOcTFLV1lPT25nUElWSmZBdVdTZXlYVGtoNHZGWjJCCis1SjJPNk8rSnpoUk1WQjBjZ1JKTmNLaStFQVVYZmgvUnVGZFY3YzI3VXNLd0huakNUVFpveTFZbXdWTEJ2WGIzCitXTlZ5Zmg5RWRyc0FpUjBXblZFMTcwM0NWdTlyNEl3N0Rla0NBd0VBQWFOQ01FQXdEd1lEVlIwVEFRSC9CQVV3CitBd0VCL3pBZEJnTlZIUTRFRmdRVVA0MmFXWXY4ZTN1Y282ODRzRG50a0hHQTFzZ3dEZ1lEVlIwUEFRSC9CQVFECitBZ0VHTUEwR0NTcUdTSWIzRFFFQkJRVUFBNElCQVFBVkduNFRpcm5vQjZOTEp6S3lRSkh5SWRGa2hiNWphdExQCitnY0lWMVhwK0RDbXNOeDRjZkhaU2xkcTFmeU9oS1hkbHlUS2RxQzVXcTJCMnpoYTBqWDk0d05XWlVZTi9YdG0rCitES2hRN1NMSHJRVk1kdnZ0N2g1SFpQYjNKMzFjS0E5RnhWeGlYcWFha1pHM1V4Y3UzSzFnblpaa09iMW5hTEt1CitCY3RONTE4ZlY0YlZJSndvKzI4VE9QWDJFWkwyZlpsZUh3em9xMFFrS1hKQVBUWlNyNHhZa0hQQjdHRXNlYUhzCitoN1UvMmszWklRQXczcERhRHRNYVNLaytoUXNVaTR5OFFaNXE5dzV3d0RYM09hSmRadEI3V1orb1J4S2FKeU9rCitMWTRuZzVJZ29kY1ZmL0V1R083MFNIOHZmL0doR0xXaEM1U2dZaUF5bkIzMjFPKy9USWhvCistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDEgKDB4MSkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1OTywgTz1CdXlwYXNzIEFTLTk4MzE2MzMyNywgQ049QnV5cGFzcyBDbGFzcyAyIENBIDEKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IE9jdCAxMyAxMDoyNTowOSAyMDA2IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogT2N0IDEzIDEwOjI1OjA5IDIwMTYgR01UCisgICAgICAgIFN1YmplY3Q6IEM9Tk8sIE89QnV5cGFzcyBBUy05ODMxNjMzMjcsIENOPUJ1eXBhc3MgQ2xhc3MgMiBDQSAxCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDo4YjozYzowNzo0NTpkODpmNjpkZjplNjpjNzpjYTpiYTo4ZDo0MzpjNToKKyAgICAgICAgICAgICAgICAgICAgNDc6OGQ6YjA6NWE6YzE6Mzg6ZGI6OTI6ODQ6MWM6YWY6MTM6ZDQ6MGY6NmY6CisgICAgICAgICAgICAgICAgICAgIDM2OjQ2OjIwOmM0OjJlOmNjOjcxOjcwOjM0OmEyOjM0OmQzOjM3OjJlOmQ4OgorICAgICAgICAgICAgICAgICAgICBkZDozYTo3NzoyZjpjMDplYjoyOTplODo1YzpkMjpiNTphOTo5MTozNDo4NzoKKyAgICAgICAgICAgICAgICAgICAgMjI6NTk6ZmU6Y2M6ZGI6ZTc6OTk6YWY6OTY6YzE6YTg6Yzc6NDA6ZGQ6YTU6CisgICAgICAgICAgICAgICAgICAgIDE1OjhjOjZlOmM4OjdjOjk3OjAzOmNiOmU2OjIwOmYyOmQ3Ojk3OjVmOjMxOgorICAgICAgICAgICAgICAgICAgICBhMToyZjozNzpkMjpiZTplZTpiZTphOTphZDphODo0Yzo5ZToyMTo2Njo0MzoKKyAgICAgICAgICAgICAgICAgICAgM2I6YTg6YmM6ZjM6MDk6YTM6Mzg6ZDU6NTk6MjQ6YzE6YzI6NDc6NzY6YjE6CisgICAgICAgICAgICAgICAgICAgIDg4OjVjOjgyOjNiOmJiOjJiOmE2OjA0OmQ3OjhjOjA3OjhmOmNkOmQ1OjQxOgorICAgICAgICAgICAgICAgICAgICAxZDpmMDphZTpiODoyOToyYzo5NDo1Mjo2MDozNDo5NDozYjpkYTplMDozODoKKyAgICAgICAgICAgICAgICAgICAgZDE6OWQ6MzM6M2U6MTU6ZjQ6OTM6MzI6YzU6MDA6ZGE6YjU6Mjk6NjY6MGU6CisgICAgICAgICAgICAgICAgICAgIDNhOjc4OjBmOjIxOjUyOjVmOjAyOmU1OjkyOjdiOjI1OmQzOjkyOjFlOjJmOgorICAgICAgICAgICAgICAgICAgICAxNTo5ZDo4MTplNDo5ZDo4ZTplODplZjo4OTpjZToxNDo0Yzo1NDoxZDoxYzoKKyAgICAgICAgICAgICAgICAgICAgODE6MTI6NGQ6NzA6YTg6YmU6MTA6MDU6MTc6N2U6MWY6ZDE6Yjg6NTc6NTU6CisgICAgICAgICAgICAgICAgICAgIGVkOmNkOmJiOjUyOmMyOmIwOjFlOjc4OmMyOjRkOjM2OjY4OmNiOjU2OjI2OgorICAgICAgICAgICAgICAgICAgICBjMTo1MjpjMTpiZDo3NjpmNzo1ODpkNTo3Mjo3ZToxZjo0NDo3NjpiYjowMDoKKyAgICAgICAgICAgICAgICAgICAgODk6MWQ6MTY6OWQ6NTE6MzU6ZWY6NGQ6YzI6NTY6ZWY6NmI6ZTA6OGM6M2I6CisgICAgICAgICAgICAgICAgICAgIDBkOmU5CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgM0Y6OEQ6OUE6NTk6OEI6RkM6N0I6N0I6OUM6QTM6QUY6Mzg6QjA6Mzk6RUQ6OTA6NzE6ODA6RDY6QzgKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMTU6MWE6N2U6MTM6OGE6Yjk6ZTg6MDc6YTM6NGI6Mjc6MzI6YjI6NDA6OTE6ZjI6MjE6ZDE6CisgICAgICAgIDY0Ojg1OmJlOjYzOjZhOmQyOmNmOjgxOmMyOjE1OmQ1OjdhOjdlOjBjOjI5OmFjOjM3OjFlOgorICAgICAgICAxYzo3Yzo3Njo1Mjo5NTpkYTpiNTo3ZjoyMzphMToyOTo3Nzo2NTpjOTozMjo5ZDphODoyZToKKyAgICAgICAgNTY6YWI6NjA6NzY6Y2U6MTY6YjQ6OGQ6N2Y6Nzg6YzA6ZDU6OTk6NTE6ODM6N2Y6NWU6ZDk6CisgICAgICAgIGJlOjBjOmE4OjUwOmVkOjIyOmM3OmFkOjA1OjRjOjc2OmZiOmVkOmVlOjFlOjQ3OjY0OmY2OgorICAgICAgICBmNzoyNzo3ZDo1YzoyODowZjo0NTpjNTo1Yzo2Mjo1ZTphNjo5YTo5MTo5MTpiNzo1MzoxNzoKKyAgICAgICAgMmU6ZGM6YWQ6NjA6OWQ6OTY6NjQ6Mzk6YmQ6Njc6Njg6YjI6YWU6MDU6Y2I6NGQ6ZTc6NWY6CisgICAgICAgIDFmOjU3Ojg2OmQ1OjIwOjljOjI4OmZiOjZmOjEzOjM4OmY1OmY2OjExOjkyOmY2OjdkOjk5OgorICAgICAgICA1ZToxZjowYzplODphYjo0NDoyNDoyOTo3Mjo0MDozZDozNjo1MjphZjo4Yzo1ODo5MDo3MzoKKyAgICAgICAgYzE6ZWM6NjE6MmM6Nzk6YTE6ZWM6ODc6YjU6M2Y6ZGE6NGQ6ZDk6MjE6MDA6MzA6ZGU6OTA6CisgICAgICAgIGRhOjBlOmQzOjFhOjQ4OmE5OjNlOjg1OjBiOjE0OjhiOjhjOmJjOjQxOjllOjZhOmY3OjBlOgorICAgICAgICA3MDpjMDozNTpmNzozOTphMjo1ZDo2NjpkMDo3Yjo1OTo5ZjphODo0NzoxMjo5YToyNzoyMzoKKyAgICAgICAgYTQ6MmQ6OGU6Mjc6ODM6OTI6MjA6YTE6ZDc6MTU6N2Y6ZjE6MmU6MTg6ZWU6ZjQ6NDg6N2Y6CisgICAgICAgIDJmOjdmOmYxOmExOjE4OmI1OmExOjBiOjk0OmEwOjYyOjIwOjMyOjljOjFkOmY2OmQ0OmVmOgorICAgICAgICBiZjo0Yzo4ODo2OAorU0hBMSBGaW5nZXJwcmludD1BMDpBMTpBQjo5MDpDOTpGQzo4NDo3QjozQjoxMjo2MTpFODo5Nzo3RDo1RjpEMzoyMjo2MTpEMzpDQwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzcyZmE3MzcxLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNzJmYTczNzEuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MGE4MWQ5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzcyZmE3MzcxLjAKQEAgLTAsMCArMSw1NCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEQWpDQ0Ftc0NFSDNaL2dmUHFCNjNFSGxuKzZlSk5NWXdEUVlKS29aSWh2Y05BUUVGQlFBd2djRXhDekFKCitCZ05WQkFZVEFsVlRNUmN3RlFZRFZRUUtFdzVXWlhKcFUybG5iaXdnU1c1akxqRThNRG9HQTFVRUN4TXpRMnhoCitjM01nTXlCUWRXSnNhV01nVUhKcGJXRnllU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVTQXRJRWN5CitNVG93T0FZRFZRUUxFekVvWXlrZ01UazVPQ0JXWlhKcFUybG5iaXdnU1c1akxpQXRJRVp2Y2lCaGRYUm9iM0pwCitlbVZrSUhWelpTQnZibXg1TVI4d0hRWURWUVFMRXhaV1pYSnBVMmxuYmlCVWNuVnpkQ0JPWlhSM2IzSnJNQjRYCitEVGs0TURVeE9EQXdNREF3TUZvWERUSTRNRGd3TVRJek5UazFPVm93Z2NFeEN6QUpCZ05WQkFZVEFsVlRNUmN3CitGUVlEVlFRS0V3NVdaWEpwVTJsbmJpd2dTVzVqTGpFOE1Eb0dBMVVFQ3hNelEyeGhjM01nTXlCUWRXSnNhV01nCitVSEpwYldGeWVTQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVNBdElFY3lNVG93T0FZRFZRUUxFekVvCitZeWtnTVRrNU9DQldaWEpwVTJsbmJpd2dTVzVqTGlBdElFWnZjaUJoZFhSb2IzSnBlbVZrSUhWelpTQnZibXg1CitNUjh3SFFZRFZRUUxFeFpXWlhKcFUybG5iaUJVY25WemRDQk9aWFIzYjNKck1JR2ZNQTBHQ1NxR1NJYjNEUUVCCitBUVVBQTRHTkFEQ0JpUUtCZ1FETVh0RVJYVnhwMEt2VHVXcE1tUjlabURDT0ZvVWdSbTFIUDlTRklJVGhiYlA0CitwTzBNOFJjUE8vbW4rU1hYd2MrRVkvSjhZOCtpUi9MR1d6T09aRUFFYU1HQXVXUWNSWGZIMkc3MWxTazhVT2cwCisxM2dmcUxwdFE1R1ZqMFZYWG43Ris4cWtCT3ZxbHpkVU1HKzdBVWN5TTgzY1Y1dGthV0g0bXgwY2lVOWNad0lECitBUUFCTUEwR0NTcUdTSWIzRFFFQkJRVUFBNEdCQUZGTnpiNWN5NWdabkJXeUFUbDRMazBQWjNCd21jWVFXcFNrCitVMDFVYlN1dkRWMUFpMlRUMSs3ZVZtR1NYNmJFSFJCaE50TXNKenpvS1FtNUVXUjB6TFZ6bnh4SXFieGhBZTdpCitGNllNNDBBSU93N242MFJ6S3ByeGFaTHZjUlRET2F4eHA1RUpiK1J4QnJPNldWY21lUUQyK0EyaU16QW8xS3BZCitvSjJkYVpIOQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMSAoMHgwKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgN2Q6ZDk6ZmU6MDc6Y2Y6YTg6MWU6Yjc6MTA6Nzk6Njc6ZmI6YTc6ODk6MzQ6YzYKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgTz1WZXJpU2lnbiwgSW5jLiwgT1U9Q2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyLCBPVT0oYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5LCBPVT1WZXJpU2lnbiBUcnVzdCBOZXR3b3JrCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBNYXkgMTggMDA6MDA6MDAgMTk5OCBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEF1ZyAgMSAyMzo1OTo1OSAyMDI4IEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPVZlcmlTaWduLCBJbmMuLCBPVT1DbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIsIE9VPShjKSAxOTk4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHksIE9VPVZlcmlTaWduIFRydXN0IE5ldHdvcmsKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgxMDI0IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgxMDI0IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmNjOjVlOmQxOjExOjVkOjVjOjY5OmQwOmFiOmQzOmI5OjZhOjRjOjk5OgorICAgICAgICAgICAgICAgICAgICAxZjo1OTo5ODozMDo4ZToxNjo4NToyMDo0Njo2ZDo0NzozZjpkNDo4NToyMDoKKyAgICAgICAgICAgICAgICAgICAgODQ6ZTE6NmQ6YjM6Zjg6YTQ6ZWQ6MGM6ZjE6MTc6MGY6M2I6Zjk6YTc6Zjk6CisgICAgICAgICAgICAgICAgICAgIDI1OmQ3OmMxOmNmOjg0OjYzOmYyOjdjOjYzOmNmOmEyOjQ3OmYyOmM2OjViOgorICAgICAgICAgICAgICAgICAgICAzMzo4ZTo2NDo0MDowNDo2ODpjMTo4MDpiOTo2NDoxYzo0NTo3NzpjNzpkODoKKyAgICAgICAgICAgICAgICAgICAgNmU6ZjU6OTU6Mjk6M2M6NTA6ZTg6MzQ6ZDc6Nzg6MWY6YTg6YmE6NmQ6NDM6CisgICAgICAgICAgICAgICAgICAgIDkxOjk1OjhmOjQ1OjU3OjVlOjdlOmM1OmZiOmNhOmE0OjA0OmViOmVhOjk3OgorICAgICAgICAgICAgICAgICAgICAzNzo1NDozMDo2ZjpiYjowMTo0NzozMjozMzpjZDpkYzo1Nzo5Yjo2NDo2OToKKyAgICAgICAgICAgICAgICAgICAgNjE6Zjg6OWI6MWQ6MWM6ODk6NGY6NWM6NjcKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDUxOjRkOmNkOmJlOjVjOmNiOjk4OjE5OjljOjE1OmIyOjAxOjM5Ojc4OjJlOjRkOjBmOjY3OgorICAgICAgICA3MDo3MDo5OTpjNjoxMDo1YTo5NDphNDo1Mzo0ZDo1NDo2ZDoyYjphZjowZDo1ZDo0MDo4YjoKKyAgICAgICAgNjQ6ZDM6ZDc6ZWU6ZGU6NTY6NjE6OTI6NWY6YTY6YzQ6MWQ6MTA6NjE6MzY6ZDM6MmM6Mjc6CisgICAgICAgIDNjOmU4OjI5OjA5OmI5OjExOjY0Ojc0OmNjOmI1OjczOjlmOjFjOjQ4OmE5OmJjOjYxOjAxOgorICAgICAgICBlZTplMjoxNzphNjowYzplMzo0MDowODozYjowZTplNzplYjo0NDo3MzoyYTo5YTpmMTo2OToKKyAgICAgICAgOTI6ZWY6NzE6MTQ6YzM6Mzk6YWM6NzE6YTc6OTE6MDk6NmY6ZTQ6NzE6MDY6YjM6YmE6NTk6CisgICAgICAgIDU3OjI2Ojc5OjAwOmY2OmY4OjBkOmEyOjMzOjMwOjI4OmQ0OmFhOjU4OmEwOjlkOjlkOjY5OgorICAgICAgICA5MTpmZAorU0hBMSBGaW5nZXJwcmludD04NTozNzoxQzpBNjpFNTo1MDoxNDozRDpDRToyODowMzo0NzoxQjpERTozQTowOTpFODpGODo3NzowRgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzc0YzI2YmQwLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNzRjMjZiZDAuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NDM3MWEyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzc0YzI2YmQwLjAKQEAgLTAsMCArMSw2MCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlDa0RDQ0FmbWdBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUVFGQURCYU1Rc3dDUVlEVlFRR0V3SlZVekVjCitNQm9HQTFVRUNoTVRSWEYxYVdaaGVDQlRaV04xY21VZ1NXNWpMakV0TUNzR0ExVUVBeE1rUlhGMWFXWmhlQ0JUCitaV04xY21VZ1IyeHZZbUZzSUdWQ2RYTnBibVZ6Y3lCRFFTMHhNQjRYRFRrNU1EWXlNVEEwTURBd01Gb1hEVEl3CitNRFl5TVRBME1EQXdNRm93V2pFTE1Ba0dBMVVFQmhNQ1ZWTXhIREFhQmdOVkJBb1RFMFZ4ZFdsbVlYZ2dVMlZqCitkWEpsSUVsdVl5NHhMVEFyQmdOVkJBTVRKRVZ4ZFdsbVlYZ2dVMlZqZFhKbElFZHNiMkpoYkNCbFFuVnphVzVsCitjM01nUTBFdE1UQ0JuekFOQmdrcWhraUc5dzBCQVFFRkFBT0JqUUF3Z1lrQ2dZRUF1dWNYa0FKbHNUUlZQRW5DCitVZFhmcDlFM2o5SG5nWE5CVW1DYm5hRVhKbml0eDdIb0pwUXl0ZDR6alRvdjIvS2FlbHB6bUtOYzZmdUtjeHRjCis1OE8vZ0d6TnFmVFdLOEQzK1ptcVk2S3hSd0lQMU9SUk9oSThiSXBhVklSdzI4SEZrTTl5UmN1b1djRE5NNTAvCitvNWJyaFRNaEhENGVQbUJ1ZHB4bmhjWEl3MkVDQXdFQUFhTm1NR1F3RVFZSllJWklBWWI0UWdFQkJBUURBZ0FICitNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdId1lEVlIwakJCZ3dGb0FVdnFpZ2RISlFhMFMzeVNQWSs2ai9zMWRyCithR3d3SFFZRFZSME9CQllFRkw2b29IUnlVR3RFdDhrajJQdW8vN05YYTJoc01BMEdDU3FHU0liM0RRRUJCQVVBCitBNEdCQUREaUFWR3F4K3BmMnJuUVpROHcxajdhRFJSSmJwR1RKeFF4NzhUM0xVWDQ3TWUvb2tFTkk3U1MrUmtBCitaNzBCcjgzZ2NmeGF6MlRFNEphWTBLTkE0Z0dLN3ljSDhXVUJpa1F0Qm1WMVVzQ0dFQ0FoWDJ4ckQyeXVDUnl2Cis4cUlZTk1SMXBITWM4WTNjNzYzNXMzYTBrci9jbFJBZXZzdklPMXFFWUJsV2xLbFYKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMSAoMHgxKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBtZDVXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9VVMsIE89RXF1aWZheCBTZWN1cmUgSW5jLiwgQ049RXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBKdW4gMjEgMDQ6MDA6MDAgMTk5OSBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEp1biAyMSAwNDowMDowMCAyMDIwIEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPUVxdWlmYXggU2VjdXJlIEluYy4sIENOPUVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5lc3MgQ0EtMQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDEwMjQgYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDEwMjQgYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YmE6ZTc6MTc6OTA6MDI6NjU6YjE6MzQ6NTU6M2M6NDk6YzI6NTE6ZDU6CisgICAgICAgICAgICAgICAgICAgIGRmOmE3OmQxOjM3OjhmOmQxOmU3OjgxOjczOjQxOjUyOjYwOjliOjlkOmExOgorICAgICAgICAgICAgICAgICAgICAxNzoyNjo3ODphZDpjNzpiMTplODoyNjo5NDozMjpiNTpkZTozMzo4ZDozYToKKyAgICAgICAgICAgICAgICAgICAgMmY6ZGI6ZjI6OWE6N2E6NWE6NzM6OTg6YTM6NWM6ZTk6ZmI6OGE6NzM6MWI6CisgICAgICAgICAgICAgICAgICAgIDVjOmU3OmMzOmJmOjgwOjZjOmNkOmE5OmY0OmQ2OjJiOmMwOmY3OmY5Ojk5OgorICAgICAgICAgICAgICAgICAgICBhYTo2MzphMjpiMTo0NzowMjowZjpkNDplNDo1MTozYToxMjozYzo2Yzo4YToKKyAgICAgICAgICAgICAgICAgICAgNWE6NTQ6ODQ6NzA6ZGI6YzE6YzU6OTA6Y2Y6NzI6NDU6Y2I6YTg6NTk6YzA6CisgICAgICAgICAgICAgICAgICAgIGNkOjMzOjlkOjNmOmEzOjk2OmViOjg1OjMzOjIxOjFjOjNlOjFlOjNlOjYwOgorICAgICAgICAgICAgICAgICAgICA2ZTo3Njo5Yzo2Nzo4NTpjNTpjODpjMzo2MQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBOZXRzY2FwZSBDZXJ0IFR5cGU6IAorICAgICAgICAgICAgICAgIFNTTCBDQSwgUy9NSU1FIENBLCBPYmplY3QgU2lnbmluZyBDQQorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOkJFOkE4OkEwOjc0OjcyOjUwOjZCOjQ0OkI3OkM5OjIzOkQ4OkZCOkE4OkZGOkIzOjU3OjZCOjY4OjZDCisKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBCRTpBODpBMDo3NDo3Mjo1MDo2Qjo0NDpCNzpDOToyMzpEODpGQjpBODpGRjpCMzo1Nzo2Qjo2ODo2QworICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IG1kNVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDMwOmUyOjAxOjUxOmFhOmM3OmVhOjVmOmRhOmI5OmQwOjY1OjBmOjMwOmQ2OjNlOmRhOjBkOgorICAgICAgICAxNDo0OTo2ZTo5MTo5MzoyNzoxNDozMTplZjpjNDpmNzoyZDo0NTpmODplYzpjNzpiZjphMjoKKyAgICAgICAgNDE6MGQ6MjM6YjQ6OTI6Zjk6MTk6MDA6Njc6YmQ6MDE6YWY6Y2Q6ZTA6NzE6ZmM6NWE6Y2Y6CisgICAgICAgIDY0OmM0OmUwOjk2Ojk4OmQwOmEzOjQwOmUyOjAxOjhhOmVmOjI3OjA3OmYxOjY1OjAxOjhhOgorICAgICAgICA0NDoyZDowNjo2NTo3NTo1MjpjMDo4NjoxMDoyMDoyMTo1Zjo2Yzo2YjowZjo2YzphZTowOToKKyAgICAgICAgMWM6YWY6ZjI6YTI6MTg6MzQ6YzQ6NzU6YTQ6NzM6MWM6ZjE6OGQ6ZGM6ZWY6YWQ6Zjk6YjM6CisgICAgICAgIDc2OmI0OjkyOmJmOmRjOjk1OjEwOjFlOmJlOmNiOmM4OjNiOjVhOjg0OjYwOjE5OjU2Ojk0OgorICAgICAgICBhOTo1NQorU0hBMSBGaW5nZXJwcmludD03RTo3ODo0QToxMDoxQzo4Mjo2NTpDQzoyRDpFMTpGMTo2RDo0NzpCNDo0MDpDQTpEOTowQToxOTo0NQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzc1NjgwZDJlLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNzU2ODBkMmUuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMDdiNDIzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzc1NjgwZDJlLjAKQEAgLTAsMCArMSw4NiBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFTWpDQ0F4cWdBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUVVGQURCN01Rc3dDUVlEVlFRR0V3SkhRakViCitNQmtHQTFVRUNBd1NSM0psWVhSbGNpQk5ZVzVqYUdWemRHVnlNUkF3RGdZRFZRUUhEQWRUWVd4bWIzSmtNUm93CitHQVlEVlFRS0RCRkRiMjF2Wkc4Z1EwRWdUR2x0YVhSbFpERWhNQjhHQTFVRUF3d1lRVUZCSUVObGNuUnBabWxqCitZWFJsSUZObGNuWnBZMlZ6TUI0WERUQTBNREV3TVRBd01EQXdNRm9YRFRJNE1USXpNVEl6TlRrMU9Wb3dlekVMCitNQWtHQTFVRUJoTUNSMEl4R3pBWkJnTlZCQWdNRWtkeVpXRjBaWElnVFdGdVkyaGxjM1JsY2pFUU1BNEdBMVVFCitCd3dIVTJGc1ptOXlaREVhTUJnR0ExVUVDZ3dSUTI5dGIyUnZJRU5CSUV4cGJXbDBaV1F4SVRBZkJnTlZCQU1NCitHRUZCUVNCRFpYSjBhV1pwWTJGMFpTQlRaWEoyYVdObGN6Q0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQCitBRENDQVFvQ2dnRUJBTDVBbmZSdTRlcDJoeHhOUlVTT3ZrYklnd2Fkd1NyK0dCK081QUw2ODZ0ZFVJb1dNUXVhCitCdERGY0NMTlNTMVVZOHkyYm1oR0MxUHF5MHdrd0x4eVR1cnhGYTcwVkpvU0NzTjZzak5nNHRxSlZmTWlXUFBlCiszTS92ZzRhaWpKUlBuMmp5bUpCR2hDZkhkci9qekRVc2kxNEhaR1dDd0Vpd3FKSDVZWjkySUZDb2tjZG10ZXQ0CitZZ05XOElvYUUrb3hveDZnbWYwNDl2WW5NbGh2Qi9WcnVQc1VLNiszcXN6V1kxOXpqTm9GbWFnNHFNc1hlRFpSCityT21lOUhnNmpjOFAyVUxpbUF5ckw1OE9BZDd2bjVsSjhTM2ZySFJORzVpMVI4WGxLZEg1a0JqSFlweStnOGNtCitlejZLSmNmQTNaM21OV2dRSUoyUDJON1N3NFNjRFY3b0w4a0NBd0VBQWFPQndEQ0J2VEFkQmdOVkhRNEVGZ1FVCitvQkVLSXo2VzhRZnM0cThwNzRLbGY5QXdwTFF3RGdZRFZSMFBBUUgvQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGCitNQU1CQWY4d2V3WURWUjBmQkhRd2NqQTRvRGFnTklZeWFIUjBjRG92TDJOeWJDNWpiMjF2Wkc5allTNWpiMjB2CitRVUZCUTJWeWRHbG1hV05oZEdWVFpYSjJhV05sY3k1amNtd3dOcUEwb0RLR01HaDBkSEE2THk5amNtd3VZMjl0CitiMlJ2TG01bGRDOUJRVUZEWlhKMGFXWnBZMkYwWlZObGNuWnBZMlZ6TG1OeWJEQU5CZ2txaGtpRzl3MEJBUVVGCitBQU9DQVFFQUNGYjhBdkNiNlArayt0Wjd4a1NBemsvRXhmWUFXTXltdHJ3VVNXZ0VkdWptN2wzc0FnOWcxbzFRCitHRThtVGdIajVyQ2w3cis4ZEZSQnYvMzhFcmpIVDFyMGlXQUZmMkMzQlVyejl2SEN2OFM1ZElhMkxYMXJ6Tkx6CitSdDB2eHVCcXc4TTBBeXg5bHQxYXdnNm5DcG5CQll1ckRDL3pYRHJQYkRkVkNZZmVVMEJzV08vOHRxdGxiZ1QyCitHOXc4NEZvVnhwN1o4VmxJTUNGbEEyenM2U0Z6N0pzRG9lQTNyYUFWR0kvNnVnTE9weXlwRUJNczFPVUlKcXNpCitsMkQ0a0Y1MDFLS2FVNzN5cVdqZ29tN0MxMnl4b3crZXYrdG81MWJ5cnZMakt6ZzZDWUcxYTRYWHZpM3RQeHEzCitzbVBpOVdJc2d0UnFBRUZROFRtRG41WHBOcGFZYmc9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAxICgweDEpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9R0IsIFNUPUdyZWF0ZXIgTWFuY2hlc3RlciwgTD1TYWxmb3JkLCBPPUNvbW9kbyBDQSBMaW1pdGVkLCBDTj1BQUEgQ2VydGlmaWNhdGUgU2VydmljZXMKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEphbiAgMSAwMDowMDowMCAyMDA0IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogRGVjIDMxIDIzOjU5OjU5IDIwMjggR01UCisgICAgICAgIFN1YmplY3Q6IEM9R0IsIFNUPUdyZWF0ZXIgTWFuY2hlc3RlciwgTD1TYWxmb3JkLCBPPUNvbW9kbyBDQSBMaW1pdGVkLCBDTj1BQUEgQ2VydGlmaWNhdGUgU2VydmljZXMKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmJlOjQwOjlkOmY0OjZlOmUxOmVhOjc2Ojg3OjFjOjRkOjQ1OjQ0OjhlOgorICAgICAgICAgICAgICAgICAgICBiZTo0NjpjODo4MzowNjo5ZDpjMToyYTpmZToxODoxZjo4ZTplNDowMjpmYToKKyAgICAgICAgICAgICAgICAgICAgZjM6YWI6NWQ6NTA6OGE6MTY6MzE6MGI6OWE6MDY6ZDA6YzU6NzA6MjI6Y2Q6CisgICAgICAgICAgICAgICAgICAgIDQ5OjJkOjU0OjYzOmNjOmI2OjZlOjY4OjQ2OjBiOjUzOmVhOmNiOjRjOjI0OgorICAgICAgICAgICAgICAgICAgICBjMDpiYzo3Mjo0ZTplYTpmMToxNTphZTpmNDo1NDo5YToxMjowYTpjMzo3YToKKyAgICAgICAgICAgICAgICAgICAgYjI6MzM6NjA6ZTI6ZGE6ODk6NTU6ZjM6MjI6NTg6ZjM6ZGU6ZGM6Y2Y6ZWY6CisgICAgICAgICAgICAgICAgICAgIDgzOjg2OmEyOjhjOjk0OjRmOjlmOjY4OmYyOjk4OjkwOjQ2Ojg0OjI3OmM3OgorICAgICAgICAgICAgICAgICAgICA3NjpiZjplMzpjYzozNToyYzo4Yjo1ZTowNzo2NDo2NTo4MjpjMDo0ODpiMDoKKyAgICAgICAgICAgICAgICAgICAgYTg6OTE6Zjk6NjE6OWY6NzY6MjA6NTA6YTg6OTE6Yzc6NjY6YjU6ZWI6Nzg6CisgICAgICAgICAgICAgICAgICAgIDYyOjAzOjU2OmYwOjhhOjFhOjEzOmVhOjMxOmEzOjFlOmEwOjk5OmZkOjM4OgorICAgICAgICAgICAgICAgICAgICBmNjpmNjoyNzozMjo1ODo2ZjowNzpmNTo2YjpiODpmYjoxNDoyYjphZjpiNzoKKyAgICAgICAgICAgICAgICAgICAgYWE6Y2M6ZDY6NjM6NWY6NzM6OGM6ZGE6MDU6OTk6YTg6Mzg6YTg6Y2I6MTc6CisgICAgICAgICAgICAgICAgICAgIDc4OjM2OjUxOmFjOmU5OjllOmY0Ojc4OjNhOjhkOmNmOjBmOmQ5OjQyOmUyOgorICAgICAgICAgICAgICAgICAgICA5ODowYzphYjoyZjo5ZjowZTowMTpkZTplZjo5Zjo5OTo0OTpmMToyZDpkZjoKKyAgICAgICAgICAgICAgICAgICAgYWM6NzQ6NGQ6MWI6OTg6YjU6NDc6YzU6ZTU6Mjk6ZDE6Zjk6OTA6MTg6Yzc6CisgICAgICAgICAgICAgICAgICAgIDYyOjljOmJlOjgzOmM3OjI2OjdiOjNlOjhhOjI1OmM3OmMwOmRkOjlkOmU2OgorICAgICAgICAgICAgICAgICAgICAzNTo2ODoxMDoyMDo5ZDo4ZjpkODpkZTpkMjpjMzo4NDo5YzowZDo1ZTplODoKKyAgICAgICAgICAgICAgICAgICAgMmY6YzkKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEEwOjExOjBBOjIzOjNFOjk2OkYxOjA3OkVDOkUyOkFGOjI5OkVGOjgyOkE1OjdGOkQwOjMwOkE0OkI0CisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIENSTCBEaXN0cmlidXRpb24gUG9pbnRzOiAKKyAgICAgICAgICAgICAgICBVUkk6aHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwKKyAgICAgICAgICAgICAgICBVUkk6aHR0cDovL2NybC5jb21vZG8ubmV0L0FBQUNlcnRpZmljYXRlU2VydmljZXMuY3JsCisKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMDg6NTY6ZmM6MDI6ZjA6OWI6ZTg6ZmY6YTQ6ZmE6ZDY6N2I6YzY6NDQ6ODA6Y2U6NGY6YzQ6CisgICAgICAgIGM1OmY2OjAwOjU4OmNjOmE2OmI2OmJjOjE0OjQ5OjY4OjA0Ojc2OmU4OmU2OmVlOjVkOmVjOgorICAgICAgICAwMjowZjo2MDpkNjo4ZDo1MDoxODo0ZjoyNjo0ZTowMTplMzplNjpiMDphNTplZTpiZjpiYzoKKyAgICAgICAgNzQ6NTQ6NDE6YmY6ZmQ6ZmM6MTI6Yjg6Yzc6NGY6NWE6ZjQ6ODk6NjA6MDU6N2Y6NjA6Yjc6CisgICAgICAgIDA1OjRhOmYzOmY2OmYxOmMyOmJmOmM0OmI5Ojc0Ojg2OmI2OjJkOjdkOjZiOmNjOmQyOmYzOgorICAgICAgICA0NjpkZDoyZjpjNjplMDo2YTpjMzpjMzozNDowMzoyYzo3ZDo5NjpkZDo1YTpjMjowZTphNzoKKyAgICAgICAgMGE6OTk6YzE6MDU6OGI6YWI6MGM6MmY6ZjM6NWM6M2E6Y2Y6NmM6Mzc6NTU6MDk6ODc6ZGU6CisgICAgICAgIDUzOjQwOjZjOjU4OmVmOmZjOmI2OmFiOjY1OjZlOjA0OmY2OjFiOmRjOjNjOmUwOjVhOjE1OgorICAgICAgICBjNjo5ZTpkOTpmMTo1OTo0ODozMDoyMTo2NTowMzo2YzplYzplOToyMTo3MzplYzo5YjowMzoKKyAgICAgICAgYTE6ZTA6Mzc6YWQ6YTA6MTU6MTg6OGY6ZmE6YmE6MDI6Y2U6YTc6MmM6YTk6MTA6MTM6MmM6CisgICAgICAgIGQ0OmU1OjA4OjI2OmFiOjIyOjk3OjYwOmY4OjkwOjVlOjc0OmQ0OmEyOjlhOjUzOmJkOmYyOgorICAgICAgICBhOTo2ODplMDphMjo2ZTpjMjpkNzo2YzpiMTphMzowZjo5ZTpiZjplYjo2ODplNzo1NjpmMjoKKyAgICAgICAgYWU6ZjI6ZTM6MmI6Mzg6M2E6MDk6ODE6YjU6NmI6ODU6ZDc6YmU6MmQ6ZWQ6M2Y6MWE6Yjc6CisgICAgICAgIGIyOjYzOmUyOmY1OjYyOjJjOjgyOmQ0OjZhOjAwOjQxOjUwOmYxOjM5OjgzOjlmOjk1OmU5OgorICAgICAgICAzNjo5Njo5ODo2ZQorU0hBMSBGaW5nZXJwcmludD1EMTpFQjoyMzpBNDo2RDoxNzpENjo4RjpEOToyNTo2NDpDMjpGMTpGMTo2MDoxNzo2NDpEODpFMzo0OQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzc2NTFiMzI3LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNzY1MWIzMjcuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YTI5ZjM2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzc2NTFiMzI3LjAKQEAgLTAsMCArMSw0OSBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlDUERDQ0FhVUNFRHlSTWNzZjl0QWJEcHE0MEVTL0VyNHdEUVlKS29aSWh2Y05BUUVGQlFBd1h6RUxNQWtHCitBMVVFQmhNQ1ZWTXhGekFWQmdOVkJBb1REbFpsY21sVGFXZHVMQ0JKYm1NdU1UY3dOUVlEVlFRTEV5NURiR0Z6CitjeUF6SUZCMVlteHBZeUJRY21sdFlYSjVJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1CNFhEVGsyCitNREV5T1RBd01EQXdNRm9YRFRJNE1EZ3dNakl6TlRrMU9Wb3dYekVMTUFrR0ExVUVCaE1DVlZNeEZ6QVZCZ05WCitCQW9URGxabGNtbFRhV2R1TENCSmJtTXVNVGN3TlFZRFZRUUxFeTVEYkdGemN5QXpJRkIxWW14cFl5QlFjbWx0CitZWEo1SUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdOCitBRENCaVFLQmdRREpYRm1lOGh1S0FSUzBFTjhFUU52alY2OXFSVUNQaEF3TDBUUFoyUkhQN2dKWUh5WDNLcWhFCitCYXJzQXg5NGY1NlR1Wm9BcWlOOTFxeUZvbU5GeDNJbnpQUk14blZ4MGpudlQwTHdkZDhLa01hT0lHK1lEL2lzCitJMTl3S1Rha3lZYm5zWm9neTFPbGhlYzl2bjJhL2lSRk05eDJGZTBQb25Ga1RHVXVnV2hGcHdJREFRQUJNQTBHCitDU3FHU0liM0RRRUJCUVVBQTRHQkFCQnlVcWtGRkJreUNFSHd4V3NLekg0UElSbk41R2ZjWDZrYjVzcm9jNTBpCisySmh1Y3dOaGtjVjhzRVZBYmtTZGpiQ3hsblJoTFEycFJkS2traXJXbW5XWGJqOVQvVVdaWUIyb0swejVYcWNKCisySFV3MTlKbFlEMW4xa2hWZFdrL2tmVklDMGRwSW1tQ2xyN0p5RGlHU25vc2N4bElhVTVyZkdXL0QveHd6b2lRCistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAxICgweDApCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICAzYzo5MTozMTpjYjoxZjpmNjpkMDoxYjowZTo5YTpiODpkMDo0NDpiZjoxMjpiZQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPVZlcmlTaWduLCBJbmMuLCBPVT1DbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5CisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBKYW4gMjkgMDA6MDA6MDAgMTk5NiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEF1ZyAgMiAyMzo1OTo1OSAyMDI4IEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPVZlcmlTaWduLCBJbmMuLCBPVT1DbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5CisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMTAyNCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMTAyNCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpjOTo1Yzo1OTo5ZTpmMjoxYjo4YTowMToxNDpiNDoxMDpkZjowNDo0MDoKKyAgICAgICAgICAgICAgICAgICAgZGI6ZTM6NTc6YWY6NmE6NDU6NDA6OGY6ODQ6MGM6MGI6ZDE6MzM6ZDk6ZDk6CisgICAgICAgICAgICAgICAgICAgIDExOmNmOmVlOjAyOjU4OjFmOjI1OmY3OjJhOmE4OjQ0OjA1OmFhOmVjOjAzOgorICAgICAgICAgICAgICAgICAgICAxZjo3ODo3Zjo5ZTo5MzpiOTo5YTowMDphYToyMzo3ZDpkNjphYzo4NTphMjoKKyAgICAgICAgICAgICAgICAgICAgNjM6NDU6Yzc6NzI6Mjc6Y2M6ZjQ6NGM6YzY6NzU6NzE6ZDI6Mzk6ZWY6NGY6CisgICAgICAgICAgICAgICAgICAgIDQyOmYwOjc1OmRmOjBhOjkwOmM2OjhlOjIwOjZmOjk4OjBmOmY4OmFjOjIzOgorICAgICAgICAgICAgICAgICAgICA1Zjo3MDoyOTozNjphNDpjOTo4NjplNzpiMTo5YToyMDpjYjo1MzphNTo4NToKKyAgICAgICAgICAgICAgICAgICAgZTc6M2Q6YmU6N2Q6OWE6ZmU6MjQ6NDU6MzM6ZGM6NzY6MTU6ZWQ6MGY6YTI6CisgICAgICAgICAgICAgICAgICAgIDcxOjY0OjRjOjY1OjJlOjgxOjY4OjQ1OmE3CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAxMDo3Mjo1MjphOTowNToxNDoxOTozMjowODo0MTpmMDpjNTo2YjowYTpjYzo3ZTowZjoyMToKKyAgICAgICAgMTk6Y2Q6ZTQ6Njc6ZGM6NWY6YTk6MWI6ZTY6Y2E6ZTg6NzM6OWQ6MjI6ZDg6OTg6NmU6NzM6CisgICAgICAgIDAzOjYxOjkxOmM1OjdjOmIwOjQ1OjQwOjZlOjQ0OjlkOjhkOmIwOmIxOjk2Ojc0OjYxOjJkOgorICAgICAgICAwZDphOTo0NTpkMjphNDo5MjoyYTpkNjo5YTo3NTo5Nzo2ZTozZjo1MzpmZDo0NTo5OTo2MDoKKyAgICAgICAgMWQ6YTg6MmI6NGM6Zjk6NWU6YTc6MDk6ZDg6NzU6MzA6ZDc6ZDI6NjU6NjA6M2Q6Njc6ZDY6CisgICAgICAgIDQ4OjU1Ojc1OjY5OjNmOjkxOmY1OjQ4OjBiOjQ3OjY5OjIyOjY5OjgyOjk2OmJlOmM5OmM4OgorICAgICAgICAzODo4Njo0YTo3YToyYzo3MzoxOTo0ODo2OTo0ZTo2Yjo3Yzo2NTpiZjowZjpmYzo3MDpjZToKKyAgICAgICAgODg6OTAKK1NIQTEgRmluZ2VycHJpbnQ9QTE6REI6NjM6OTM6OTE6NkY6MTc6RTQ6MTg6NTU6MDk6NDA6MDQ6MTU6Qzc6MDI6NDA6QjA6QUU6NkIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy83NjU3OTE3NC4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzc2NTc5MTc0LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTg5ODNhYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy83NjU3OTE3NC4wCkBAIC0wLDAgKzEsOTAgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRU1EQ0NBeGlnQXdJQkFnSVFVSlJzN0JqcTFaeE4xWmZ2ZFkrZ3JUQU5CZ2txaGtpRzl3MEJBUVVGQURDQgorZ2pFTE1Ba0dBMVVFQmhNQ1ZWTXhIakFjQmdOVkJBc1RGWGQzZHk1NGNtRnRjSE5sWTNWeWFYUjVMbU52YlRFaworTUNJR0ExVUVDaE1iV0ZKaGJYQWdVMlZqZFhKcGRIa2dVMlZ5ZG1salpYTWdTVzVqTVMwd0t3WURWUVFERXlSWQorVW1GdGNDQkhiRzlpWVd3Z1EyVnlkR2xtYVdOaGRHbHZiaUJCZFhSb2IzSnBkSGt3SGhjTk1EUXhNVEF4TVRjeAorTkRBMFdoY05NelV3TVRBeE1EVXpOekU1V2pDQmdqRUxNQWtHQTFVRUJoTUNWVk14SGpBY0JnTlZCQXNURlhkMworZHk1NGNtRnRjSE5sWTNWeWFYUjVMbU52YlRFa01DSUdBMVVFQ2hNYldGSmhiWEFnVTJWamRYSnBkSGtnVTJWeQorZG1salpYTWdTVzVqTVMwd0t3WURWUVFERXlSWVVtRnRjQ0JIYkc5aVlXd2dRMlZ5ZEdsbWFXTmhkR2x2YmlCQgorZFhSb2IzSnBkSGt3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ1lKQjY5RmJTNgorMzhlTXBTZTJPQXRwODdaT3FDd3VJUjFjUk44aFhYNGpkUDVlZnJSS3Q2YXRINjdnQmhiaW0xdlpaM1JyWFlDUAorS1oyR0c5bWNEWmh0ZGhBb1dPUmxzSDlLbUhtZjRNTXhmb0FydFl6QVFEc1JodERMb29ZMllLVFZNSUp0Mlc3UQorRHhJRU01ZGZUMkZhOE9UNWthdm5IVHU4Nk0vMGF5MDBmT0pJWVJ5TzgyRkV6RytnU3FtVXNFM2E1NmswZW5JNAorcUVITVBKUVJmZXZJcG95M2hzdktNenZaUFRlTCszbytoaXpuYzljS1Y2eGtteG5yOUE4RUNJcXNBeGNaWlBSYQorSlNLTk5DeXk5bWdkRW0zVGloNFUyc1NQcHVJamhkVjZEYjFxNE9uczdCZTdRaHRucWlYdFJZTWgvTUhKZk5WaQorUHZyeXhTM1QvZFJsQWdNQkFBR2pnWjh3Z1p3d0V3WUpLd1lCQkFHQ054UUNCQVllQkFCREFFRXdDd1lEVlIwUAorQkFRREFnR0dNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdIUVlEVlIwT0JCWUVGTVpQb2owR1k0UUpuTTVpNUFTcworalZ5MTZiWWJNRFlHQTFVZEh3UXZNQzB3SzZBcG9DZUdKV2gwZEhBNkx5OWpjbXd1ZUhKaGJYQnpaV04xY21sMAorZVM1amIyMHZXRWREUVM1amNtd3dFQVlKS3dZQkJBR0NOeFVCQkFNQ0FRRXdEUVlKS29aSWh2Y05BUUVGQlFBRAorZ2dFQkFKRVZPUU1CRzJmN1NoejVDbUJib2RwTmwyTDVKRk1uMTRKa1RwQXV3MGtiSzVyYy9LaDRaelh4SGZBUgordmJkSTR4RDJEZDgvMHNtMnFsV2tTTG9DMjk1WkxoVmJPNTBXZlVmWE4rcGZUWFlTTnJzZjE2R0JCRVlnb3l4dAorcVo0QmZqOHB6Z0NUMy8zSmtuT0ppV1NlNXl2a0hKRXMwcm5PZmM1dk1ablQ1cjdTSHBEd0NSUjVYQ09yVGRMYQorSVI5Tm1YbWQ0YzhubnhDYkhJZ05zSXBrUVRHNERteVFKS1NiWEhHUHVydCtIQnZiYW9BUElienAyNmEzUVBTeQoraTZteDVPK2FHdEE5YVpudXFDaWo0VHl6OExJUm5NOThRT2JkNTBOOW90ZzZ0YW1OOGpTWnhOUVE0UWI5Q1lRUQorTys3RVRQVHNKM3hDd25SOGdvb0p5YlFESmJ3PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgNTA6OTQ6NmM6ZWM6MTg6ZWE6ZDU6OWM6NGQ6ZDU6OTc6ZWY6NzU6OGY6YTA6YWQKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgT1U9d3d3LnhyYW1wc2VjdXJpdHkuY29tLCBPPVhSYW1wIFNlY3VyaXR5IFNlcnZpY2VzIEluYywgQ049WFJhbXAgR2xvYmFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5CisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBOb3YgIDEgMTc6MTQ6MDQgMjAwNCBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEphbiAgMSAwNTozNzoxOSAyMDM1IEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPVT13d3cueHJhbXBzZWN1cml0eS5jb20sIE89WFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jLCBDTj1YUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOjk4OjI0OjFlOmJkOjE1OmI0OmJhOmRmOmM3OjhjOmE1OjI3OmI2OjM4OgorICAgICAgICAgICAgICAgICAgICAwYjo2OTpmMzpiNjo0ZTphODoyYzoyZToyMToxZDo1Yzo0NDpkZjoyMTo1ZDoKKyAgICAgICAgICAgICAgICAgICAgN2U6MjM6NzQ6ZmU6NWU6N2U6YjQ6NGE6Yjc6YTY6YWQ6MWY6YWU6ZTA6MDY6CisgICAgICAgICAgICAgICAgICAgIDE2OmUyOjliOjViOmQ5OjY3Ojc0OjZiOjVkOjgwOjhmOjI5OjlkOjg2OjFiOgorICAgICAgICAgICAgICAgICAgICBkOTo5YzowZDo5ODo2ZDo3NjoxMDoyODo1ODplNDo2NTpiMDo3Zjo0YTo5ODoKKyAgICAgICAgICAgICAgICAgICAgNzk6OWY6ZTA6YzM6MzE6N2U6ODA6MmI6YjU6OGM6YzA6NDA6M2I6MTE6ODY6CisgICAgICAgICAgICAgICAgICAgIGQwOmNiOmEyOjg2OjM2OjYwOmE0OmQ1OjMwOjgyOjZkOmQ5OjZlOmQwOjBmOgorICAgICAgICAgICAgICAgICAgICAxMjowNDozMzo5Nzo1Zjo0Zjo2MTo1YTpmMDplNDpmOTo5MTphYjplNzoxZDoKKyAgICAgICAgICAgICAgICAgICAgM2I6YmM6ZTg6Y2Y6ZjQ6NmI6MmQ6MzQ6N2M6ZTI6NDg6NjE6MWM6OGU6ZjM6CisgICAgICAgICAgICAgICAgICAgIDYxOjQ0OmNjOjZmOmEwOjRhOmE5Ojk0OmIwOjRkOmRhOmU3OmE5OjM0OjdhOgorICAgICAgICAgICAgICAgICAgICA3MjozODphODo0MTpjYzozYzo5NDoxMTo3ZDplYjpjODphNjo4YzpiNzo4NjoKKyAgICAgICAgICAgICAgICAgICAgY2I6Y2E6MzM6M2I6ZDk6M2Q6Mzc6OGI6ZmI6N2E6M2U6ODY6MmM6ZTc6NzM6CisgICAgICAgICAgICAgICAgICAgIGQ3OjBhOjU3OmFjOjY0OjliOjE5OmViOmY0OjBmOjA0OjA4OjhhOmFjOjAzOgorICAgICAgICAgICAgICAgICAgICAxNzoxOTo2NDpmNDo1YToyNToyMjo4ZDozNDoyYzpiMjpmNjo2ODoxZDoxMjoKKyAgICAgICAgICAgICAgICAgICAgNmQ6ZDM6OGE6MWU6MTQ6ZGE6YzQ6OGY6YTY6ZTI6MjM6ODU6ZDU6N2E6MGQ6CisgICAgICAgICAgICAgICAgICAgIGJkOjZhOmUwOmU5OmVjOmVjOjE3OmJiOjQyOjFiOjY3OmFhOjI1OmVkOjQ1OgorICAgICAgICAgICAgICAgICAgICA4MzoyMTpmYzpjMTpjOTo3YzpkNTo2MjozZTpmYTpmMjpjNToyZDpkMzpmZDoKKyAgICAgICAgICAgICAgICAgICAgZDQ6NjUKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgMS4zLjYuMS40LjEuMzExLjIwLjI6IAorICAgICAgICAgICAgICAgIC4uLkMuQQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogCisgICAgICAgICAgICAgICAgRGlnaXRhbCBTaWduYXR1cmUsIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEM2OjRGOkEyOjNEOjA2OjYzOjg0OjA5OjlDOkNFOjYyOkU0OjA0OkFDOjhEOjVDOkI1OkU5OkI2OjFCCisgICAgICAgICAgICBYNTA5djMgQ1JMIERpc3RyaWJ1dGlvbiBQb2ludHM6IAorICAgICAgICAgICAgICAgIFVSSTpodHRwOi8vY3JsLnhyYW1wc2VjdXJpdHkuY29tL1hHQ0EuY3JsCisKKyAgICAgICAgICAgIDEuMy42LjEuNC4xLjMxMS4yMS4xOiAKKyAgICAgICAgICAgICAgICAuLi4KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgOTE6MTU6Mzk6MDM6MDE6MWI6Njc6ZmI6NGE6MWM6Zjk6MGE6NjA6NWI6YTE6ZGE6NGQ6OTc6CisgICAgICAgIDYyOmY5OjI0OjUzOjI3OmQ3OjgyOjY0OjRlOjkwOjJlOmMzOjQ5OjFiOjJiOjlhOmRjOmZjOgorICAgICAgICBhODo3ODo2NzozNTpmMToxZDpmMDoxMTpiZDpiNzo0ODplMzoxMDpmNjowZDpkZjozZjpkMjoKKyAgICAgICAgYzk6YjY6YWE6NTU6YTQ6NDg6YmE6MDI6ZGI6ZGU6NTk6MmU6MTU6NWI6M2I6OWQ6MTY6N2Q6CisgICAgICAgIDQ3OmQ3OjM3OmVhOjVmOjRkOjc2OjEyOjM2OmJiOjFmOmQ3OmExOjgxOjA0OjQ2OjIwOmEzOgorICAgICAgICAyYzo2ZDphOTo5ZTowMTo3ZTozZjoyOTpjZTowMDo5MzpkZjpmZDpjOTo5Mjo3Mzo4OTo4OToKKyAgICAgICAgNjQ6OWU6ZTc6MmI6ZTQ6MWM6OTE6MmM6ZDI6Yjk6Y2U6N2Q6Y2U6NmY6MzE6OTk6ZDM6ZTY6CisgICAgICAgIGJlOmQyOjFlOjkwOmYwOjA5OjE0Ojc5OjVjOjIzOmFiOjRkOmQyOmRhOjIxOjFmOjRkOjk5OgorICAgICAgICA3OTo5ZDplMTpjZjoyNzo5ZjoxMDo5YjoxYzo4ODowZDpiMDo4YTo2NDo0MTozMTpiODowZToKKyAgICAgICAgNmM6OTA6MjQ6YTQ6OWI6NWM6NzE6OGY6YmE6YmI6N2U6MWM6MWI6ZGI6NmE6ODA6MGY6MjE6CisgICAgICAgIGJjOmU5OmRiOmE2OmI3OjQwOmY0OmIyOjhiOmE5OmIxOmU0OmVmOjlhOjFhOmQwOjNkOjY5OgorICAgICAgICA5OTplZTphODoyODphMzplMTozYzpiMzpmMDpiMjoxMTo5YzpjZjo3Yzo0MDplNjpkZDplNzoKKyAgICAgICAgNDM6N2Q6YTI6ZDg6M2E6YjU6YTk6OGQ6ZjI6MzQ6OTk6YzQ6ZDQ6MTA6ZTE6MDY6ZmQ6MDk6CisgICAgICAgIDg0OjEwOjNiOmVlOmM0OjRjOmY0OmVjOjI3OjdjOjQyOmMyOjc0OjdjOjgyOjhhOjA5OmM5OgorICAgICAgICBiNDowMzoyNTpiYworU0hBMSBGaW5nZXJwcmludD1CODowMTo4NjpEMTpFQjo5Qzo4NjpBNTo0MTowNDpDRjozMDo1NDpGMzo0Qzo1MjpCNzpFNTo1ODpDNgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzc5OTliZTBkLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvNzk5OWJlMGQuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMDIxYTZlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzc5OTliZTBkLjAKQEAgLTAsMCArMSw3OCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEVkRDQ0FqeWdBd0lCQWdJREFqUldNQTBHQ1NxR1NJYjNEUUVCQlFVQU1FSXhDekFKQmdOVkJBWVRBbFZUCitNUll3RkFZRFZRUUtFdzFIWlc5VWNuVnpkQ0JKYm1NdU1Sc3dHUVlEVlFRREV4SkhaVzlVY25WemRDQkhiRzlpCitZV3dnUTBFd0hoY05NREl3TlRJeE1EUXdNREF3V2hjTk1qSXdOVEl4TURRd01EQXdXakJDTVFzd0NRWURWUVFHCitFd0pWVXpFV01CUUdBMVVFQ2hNTlIyVnZWSEoxYzNRZ1NXNWpMakViTUJrR0ExVUVBeE1TUjJWdlZISjFjM1FnCitSMnh2WW1Gc0lFTkJNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTJzd1lZekQ5Cis5QmNqR2xaK1c5ODhiRGprY2JkNGtkUzhvZGhNK0toRHRnUHBUU0VIQ0lqYVdDOW1PU205QlhpTG5Uam9CYmRxCitmbkdrNXNSZ3ByRHZnT1NKS0ErZUpkYnRnL090cHBISG1NbENHRFVVbmEyWVJwSXVUOHJ4aDBQQkZwVlhMVkR2CitpUzJBZWxldDh1NWZhOUlBamJrVStCUVZOZG5BUnFON2NzaVJ2OGxWSzgzUWx6NmNKbVRNMzg2REdYSEtUdWJVCisxWHVwR2MxVjNzanMwbDQ0VStWY1Q0d3QvbEFqTnZ4bTVzdU9wRGtaQUxlVkFqbVJDdzcrT0M3UkhRV2E5azArCitidzhISGE4c0hvOWdPZUw2TmxNVE9kUmVKaXZiUGFnVXZUTHJHQU1vVWdSeDVhc3pQZUU0dXdjMmhHS2NlZW9XCitNUFJmd0N2b2NXdmsrUUlEQVFBQm8xTXdVVEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlRBCitlcGhvalluN3F3VmtEQkY5cW4xbHVNck1UakFmQmdOVkhTTUVHREFXZ0JUQWVwaG9qWW43cXdWa0RCRjlxbjFsCit1TXJNVGpBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQU5lTXBhdVV2WFZTT0tWQ1VuNWthRk9TUGVDcGlsS0luCitaNTdRenhwZVIrbkJzcVRQM1VFYUJVNmJTKzVLYjFWU3N5U2hOd3JyWkhZcUxpenovVHQxa0wvNmNkakhQVGZTCit0UVdWWXJtbTNvazlObnM0ZDBpWHJLWWdqeTZteVF6Q3NwbEZBTWZPRVZFaUl1Q2w2cllWU0FsazZsNVBkUGNGCitQc2VLVWd6YkZiUzliWnZseHJGVWFLbmphWkMybXFVUHVMay9JSDJ1U3JXNG5PUWR0cXZtbEtYQng0T3QyL1VuCitodzRFYk5YLzNhQmQ3WWRTdHlzVkFxNDVwbXAwNmRyRTU3eE5OQjZwWEUwelg1SUpMNGhtWFhlWHh4MTJFNm5WCis1ZkVXQ1JFMTFhemJKSEZ3TEpoV0M5a1h0TkhqVVN0ZWRlalYwTnhQTk8zQ0JXYUFvY3ZtTXc9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAxNDQ0NzAgKDB4MjM0NTYpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9VVMsIE89R2VvVHJ1c3QgSW5jLiwgQ049R2VvVHJ1c3QgR2xvYmFsIENBCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBNYXkgMjEgMDQ6MDA6MDAgMjAwMiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IE1heSAyMSAwNDowMDowMCAyMDIyIEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPUdlb1RydXN0IEluYy4sIENOPUdlb1RydXN0IEdsb2JhbCBDQQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6ZGE6Y2M6MTg6NjM6MzA6ZmQ6ZjQ6MTc6MjM6MWE6NTY6N2U6NWI6ZGY6CisgICAgICAgICAgICAgICAgICAgIDNjOjZjOjM4OmU0OjcxOmI3Ojc4OjkxOmQ0OmJjOmExOmQ4OjRjOmY4OmE4OgorICAgICAgICAgICAgICAgICAgICA0MzpiNjowMzplOTo0ZDoyMTowNzowODo4ODpkYTo1ODoyZjo2NjozOToyOToKKyAgICAgICAgICAgICAgICAgICAgYmQ6MDU6Nzg6OGI6OWQ6Mzg6ZTg6MDU6Yjc6NmE6N2U6NzE6YTQ6ZTY6YzQ6CisgICAgICAgICAgICAgICAgICAgIDYwOmE2OmIwOmVmOjgwOmU0Ojg5OjI4OjBmOjllOjI1OmQ2OmVkOjgzOmYzOgorICAgICAgICAgICAgICAgICAgICBhZDphNjo5MTpjNzo5ODpjOTo0MjoxODozNToxNDo5ZDphZDo5ODo0Njo5MjoKKyAgICAgICAgICAgICAgICAgICAgMmU6NGY6Y2E6ZjE6ODc6NDM6YzE6MTY6OTU6NTc6MmQ6NTA6ZWY6ODk6MmQ6CisgICAgICAgICAgICAgICAgICAgIDgwOjdhOjU3OmFkOmYyOmVlOjVmOjZiOmQyOjAwOjhkOmI5OjE0OmY4OjE0OgorICAgICAgICAgICAgICAgICAgICAxNTozNTpkOTpjMDo0NjphMzo3Yjo3MjpjODo5MTpiZjpjOTo1NToyYjpjZDoKKyAgICAgICAgICAgICAgICAgICAgZDA6OTc6M2U6OWM6MjY6NjQ6Y2M6ZGY6Y2U6ODM6MTk6NzE6Y2E6NGU6ZTY6CisgICAgICAgICAgICAgICAgICAgIGQ0OmQ1OjdiOmE5OjE5OmNkOjU1OmRlOmM4OmVjOmQyOjVlOjM4OjUzOmU1OgorICAgICAgICAgICAgICAgICAgICA1Yzo0Zjo4YzoyZDpmZTo1MDoyMzozNjpmYzo2NjplNjpjYjo4ZTphNDozOToKKyAgICAgICAgICAgICAgICAgICAgMTk6MDA6Yjc6OTU6MDI6Mzk6OTE6MGI6MGU6ZmU6Mzg6MmU6ZDE6MWQ6MDU6CisgICAgICAgICAgICAgICAgICAgIDlhOmY2OjRkOjNlOjZmOjBmOjA3OjFkOmFmOjJjOjFlOjhmOjYwOjM5OmUyOgorICAgICAgICAgICAgICAgICAgICBmYTozNjo1MzoxMzozOTpkNDo1ZToyNjoyYjpkYjozZDphODoxNDpiZDozMjoKKyAgICAgICAgICAgICAgICAgICAgZWI6MTg6MDM6Mjg6NTI6MDQ6NzE6ZTU6YWI6MzM6M2Q6ZTE6Mzg6YmI6MDc6CisgICAgICAgICAgICAgICAgICAgIDM2Ojg0OjYyOjljOjc5OmVhOjE2OjMwOmY0OjVmOmMwOjJiOmU4OjcxOjZiOgorICAgICAgICAgICAgICAgICAgICBlNDpmOQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEMwOjdBOjk4OjY4OjhEOjg5OkZCOkFCOjA1OjY0OjBDOjExOjdEOkFBOjdEOjY1OkI4OkNBOkNDOjRFCisgICAgICAgICAgICBYNTA5djMgQXV0aG9yaXR5IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBrZXlpZDpDMDo3QTo5ODo2ODo4RDo4OTpGQjpBQjowNTo2NDowQzoxMTo3RDpBQTo3RDo2NTpCODpDQTpDQzo0RQorCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDM1OmUzOjI5OjZhOmU1OjJmOjVkOjU0OjhlOjI5OjUwOjk0OjlmOjk5OjFhOjE0OmU0OjhmOgorICAgICAgICA3ODoyYTo2Mjo5NDphMjoyNzo2Nzo5ZTpkMDpjZjoxYTo1ZTo0NzplOTpjMTpiMjphNDpjZjoKKyAgICAgICAgZGQ6NDE6MWE6MDU6NGU6OWI6NGI6ZWU6NGE6NmY6NTU6NTI6YjM6MjQ6YTE6Mzc6MGE6ZWI6CisgICAgICAgIDY0Ojc2OjJhOjJlOjJjOmYzOmZkOjNiOjc1OjkwOmJmOmZhOjcxOmQ4OmM3OjNkOjM3OmQyOgorICAgICAgICBiNTowNTo5NTo2MjpiOTphNjpkZTo4OTozZDozNjo3YjozODo3Nzo0ODo5NzphYzphNjoyMDoKKyAgICAgICAgOGY6MmU6YTY6Yzk6MGM6YzI6YjI6OTk6NDU6MDA6Yzc6Y2U6MTE6NTE6MjI6MjI6ZTA6YTU6CisgICAgICAgIGVhOmI2OjE1OjQ4OjA5OjY0OmVhOjVlOjRmOjc0OmY3OjA1OjNlOmM3OjhhOjUyOjBjOmRiOgorICAgICAgICAxNTpiNDpiZDo2ZDo5YjplNTpjNjpiMTo1NDo2ODphOTplMzo2OTo5MDpiNjo5YTphNTowZjoKKyAgICAgICAgYjg6Yjk6M2Y6MjA6N2Q6YWU6NGE6YjU6Yjg6OWM6ZTQ6MWQ6YjY6YWI6ZTY6OTQ6YTU6YzE6CisgICAgICAgIGM3OjgzOmFkOmRiOmY1OjI3Ojg3OjBlOjA0OjZjOmQ1OmZmOmRkOmEwOjVkOmVkOjg3OjUyOgorICAgICAgICBiNzoyYjoxNTowMjphZTozOTphNjo2YTo3NDplOTpkYTpjNDplNzpiYzo0ZDozNDoxZTphOToKKyAgICAgICAgNWM6NGQ6MzM6NWY6OTI6MDk6MmY6ODg6NjY6NWQ6Nzc6OTc6Yzc6MWQ6NzY6MTM6YTk6ZDU6CisgICAgICAgIGU1OmYxOjE2OjA5OjExOjM1OmQ1OmFjOmRiOjI0OjcxOjcwOjJjOjk4OjU2OjBiOmQ5OjE3OgorICAgICAgICBiNDpkMTplMzo1MToyYjo1ZTo3NTplODpkNTpkMDpkYzo0ZjozNDplZDpjMjowNTo2Njo4MDoKKyAgICAgICAgYTE6Y2I6ZTY6MzMKK1NIQTEgRmluZ2VycHJpbnQ9REU6Mjg6RjQ6QTQ6RkY6RTU6Qjk6MkY6QTM6QzU6MDM6RDE6QTM6NDk6QTc6Rjk6OTY6MkE6ODI6MTIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy83YTQ4MWU2Ni4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzdhNDgxZTY2LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTRkMzNjMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy83YTQ4MWU2Ni4wCkBAIC0wLDAgKzEsODkgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRXFqQ0NBNUtnQXdJQkFnSU9Ta2NBQVFBQzVhQmQxajhBVWI4d0RRWUpLb1pJaHZjTkFRRUZCUUF3ZGpFTAorTUFrR0ExVUVCaE1DUkVVeEhEQWFCZ05WQkFvVEUxUkRJRlJ5ZFhOMFEyVnVkR1Z5SUVkdFlrZ3hJakFnQmdOVgorQkFzVEdWUkRJRlJ5ZFhOMFEyVnVkR1Z5SUVOc1lYTnpJRE1nUTBFeEpUQWpCZ05WQkFNVEhGUkRJRlJ5ZFhOMAorUTJWdWRHVnlJRU5zWVhOeklETWdRMEVnU1Vrd0hoY05NRFl3TVRFeU1UUTBNVFUzV2hjTk1qVXhNak14TWpJMQorT1RVNVdqQjJNUXN3Q1FZRFZRUUdFd0pFUlRFY01Cb0dBMVVFQ2hNVFZFTWdWSEoxYzNSRFpXNTBaWElnUjIxaQorU0RFaU1DQUdBMVVFQ3hNWlZFTWdWSEoxYzNSRFpXNTBaWElnUTJ4aGMzTWdNeUJEUVRFbE1DTUdBMVVFQXhNYworVkVNZ1ZISjFjM1JEWlc1MFpYSWdRMnhoYzNNZ015QkRRU0JKU1RDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRAorZ2dFUEFEQ0NBUW9DZ2dFQkFMVGd1MUc3T1Z5TEJNVk1lUndqaGpFUVkwTlZKei9HUmNla1Bld0pEUm9lSU1KVworSHQ0Yk53Y3dJaTl2OFFieHE2M1d5S3Rob3k5RHhMQ3lMZnpEbG1sN2Zvcmt6TUE1RXBCQ1lNbk1OV2p1MmwrUQorVmwvTkhFMWJXRW5yRGdGUFpQb3NQSWxZMkM4dTRyQm82U0k3ZFluV1JCcGw4aHVYSmgwb2Jhem92VmtkS3lUMgorMW9RRFpvZ2tBSGhnOGZpci9nS3lhL3NpK3pYbUZ0R3Q5aTRTNVBvMWF1VVp1VjNiT3g0YSs5UC9GUlFJMkFscQordWtXZEZIbGdmYTlBaWdkenM1T1cwM1EwalRvM0tkNWM3UFh1TGpIQ0lOeSs4VTkvSTFMWlcrSmsyWnlxQndpMQorUmIzUjBESEJxMVNmcWRMRFltQUQ4YnM1U3BKS1BRcTVuY1dnL2pjQ0F3RUFBYU9DQVRRd2dnRXdNQThHQTFVZAorRXdFQi93UUZNQU1CQWY4d0RnWURWUjBQQVFIL0JBUURBZ0VHTUIwR0ExVWREZ1FXQkJUVW92eWZzOFBZQTlOWAorWEFlazBDU253UElBMURDQjdRWURWUjBmQklIbE1JSGlNSUhmb0lIY29JSFpoalZvZEhSd09pOHZkM2QzTG5SeQorZFhOMFkyVnVkR1Z5TG1SbEwyTnliQzkyTWk5MFkxOWpiR0Z6YzE4elgyTmhYMGxKTG1OeWJJYUJuMnhrWVhBNgorTHk5M2QzY3VkSEoxYzNSalpXNTBaWEl1WkdVdlEwNDlWRU1sTWpCVWNuVnpkRU5sYm5SbGNpVXlNRU5zWVhOegorSlRJd015VXlNRU5CSlRJd1NVa3NUejFVUXlVeU1GUnlkWE4wUTJWdWRHVnlKVEl3UjIxaVNDeFBWVDF5YjI5MAorWTJWeWRITXNSRU05ZEhKMWMzUmpaVzUwWlhJc1JFTTlaR1UvWTJWeWRHbG1hV05oZEdWU1pYWnZZMkYwYVc5dQorVEdsemREOWlZWE5sUHpBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQU5tRGtjUGNHSUVQWkl4cEM4dmlqc3JsTgoraXJUendwcFZNWHpFTzJlYXROOU5Eb3FUU2hlTEc0M0tpZUhQT2g2c0hmR2NNclNPV1hhaVFZVWxONkFUMFBWOAorVHRYcWx1SnVjc0c3S3Y1c2J2aVJtRWI4eVJ0WFcrcklHanMvc0ZHWVBBZmFMRmtCMm90RTZPRjAvYWRvM1ZTNgorZzBic3lFYTErSytYd0RzSkhJL09jcFk5TTFad3ZKYkwyTlY5SUpxRG54cmNPZkhGY3FNUkEvMDdRbElwMitnQgorOTV0ZWpOYU5oazRaK3J3Y3ZzVWhwWWVlZUM0MjJ3bHhvM0kwK0d6akJnbnlYbGFsMDkyWSt0VG1CdlR3dGlCagorUytvcHZhcUNaaDc3Z2Fxbk42MFRHT2FTdzRIQk03dUlIcUhuNHJTOU1Xd09VVDF2KzVaV2dPSTJGOUhjNUE9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgNGE6NDc6MDA6MDE6MDA6MDI6ZTU6YTA6NWQ6ZDY6M2Y6MDA6NTE6YmYKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1ERSwgTz1UQyBUcnVzdENlbnRlciBHbWJILCBPVT1UQyBUcnVzdENlbnRlciBDbGFzcyAzIENBLCBDTj1UQyBUcnVzdENlbnRlciBDbGFzcyAzIENBIElJCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBKYW4gMTIgMTQ6NDE6NTcgMjAwNiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IERlYyAzMSAyMjo1OTo1OSAyMDI1IEdNVAorICAgICAgICBTdWJqZWN0OiBDPURFLCBPPVRDIFRydXN0Q2VudGVyIEdtYkgsIE9VPVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EsIENOPVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmI0OmUwOmJiOjUxOmJiOjM5OjVjOjhiOjA0OmM1OjRjOjc5OjFjOjIzOgorICAgICAgICAgICAgICAgICAgICA4NjozMToxMDo2Mzo0Mzo1NToyNzozZjpjNjo0NTpjNzphNDozZDplYzowOToKKyAgICAgICAgICAgICAgICAgICAgMGQ6MWE6MWU6MjA6YzI6NTY6MWU6ZGU6MWI6Mzc6MDc6MzA6MjI6MmY6NmY6CisgICAgICAgICAgICAgICAgICAgIGYxOjA2OmYxOmFiOmFkOmQ2OmM4OmFiOjYxOmEzOjJmOjQzOmM0OmIwOmIyOgorICAgICAgICAgICAgICAgICAgICAyZDpmYzpjMzo5Njo2OTo3Yjo3ZTo4YTplNDpjYzpjMDozOToxMjo5MDo0MjoKKyAgICAgICAgICAgICAgICAgICAgNjA6Yzk6Y2M6MzU6Njg6ZWU6ZGE6NWY6OTA6NTY6NWY6Y2Q6MWM6NGQ6NWI6CisgICAgICAgICAgICAgICAgICAgIDU4OjQ5OmViOjBlOjAxOjRmOjY0OmZhOjJjOjNjOjg5OjU4OmQ4OjJmOjJlOgorICAgICAgICAgICAgICAgICAgICBlMjpiMDo2ODplOToyMjozYjo3NTo4OTpkNjo0NDoxYTo2NTpmMjoxYjo5NzoKKyAgICAgICAgICAgICAgICAgICAgMjY6MWQ6Mjg6NmQ6YWM6ZTg6YmQ6NTk6MWQ6MmI6MjQ6ZjY6ZDY6ODQ6MDM6CisgICAgICAgICAgICAgICAgICAgIDY2Ojg4OjI0OjAwOjc4OjYwOmYxOmY4OmFiOmZlOjAyOmIyOjZiOmZiOjIyOgorICAgICAgICAgICAgICAgICAgICBmYjozNTplNjoxNjpkMTphZDpmNjoyZToxMjplNDpmYTozNTo2YTplNToxOToKKyAgICAgICAgICAgICAgICAgICAgYjk6NWQ6ZGI6M2I6MWU6MWE6ZmI6ZDM6ZmY6MTU6MTQ6MDg6ZDg6MDk6NmE6CisgICAgICAgICAgICAgICAgICAgIGJhOjQ1OjlkOjE0Ojc5OjYwOjdkOmFmOjQwOjhhOjA3OjczOmIzOjkzOjk2OgorICAgICAgICAgICAgICAgICAgICBkMzo3NDozNDo4ZDozYTozNzoyOTpkZTo1YzplYzpmNTplZToyZTozMTpjMjoKKyAgICAgICAgICAgICAgICAgICAgMjA6ZGM6YmU6ZjE6NGY6N2Y6MjM6NTI6ZDk6NWI6ZTI6NjQ6ZDk6OWM6YWE6CisgICAgICAgICAgICAgICAgICAgIDA3OjA4OmI1OjQ1OmJkOmQxOmQwOjMxOmMxOmFiOjU0OjlmOmE5OmQyOmMzOgorICAgICAgICAgICAgICAgICAgICA2Mjo2MDowMzpmMTpiYjozOTo0YTo5Mjo0YTozZDowYTpiOTo5ZDpjNTphMDoKKyAgICAgICAgICAgICAgICAgICAgZmU6MzcKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBENDpBMjpGQzo5RjpCMzpDMzpEODowMzpEMzo1Nzo1QzowNzpBNDpEMDoyNDpBNzpDMDpGMjowMDpENAorICAgICAgICAgICAgWDUwOXYzIENSTCBEaXN0cmlidXRpb24gUG9pbnRzOiAKKyAgICAgICAgICAgICAgICBVUkk6aHR0cDovL3d3dy50cnVzdGNlbnRlci5kZS9jcmwvdjIvdGNfY2xhc3NfM19jYV9JSS5jcmwKKyAgICAgICAgICAgICAgICBVUkk6bGRhcDovL3d3dy50cnVzdGNlbnRlci5kZS9DTj1UQyUyMFRydXN0Q2VudGVyJTIwQ2xhc3MlMjAzJTIwQ0ElMjBJSSxPPVRDJTIwVHJ1c3RDZW50ZXIlMjBHbWJILE9VPXJvb3RjZXJ0cyxEQz10cnVzdGNlbnRlcixEQz1kZT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/CisKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMzY6NjA6ZTQ6NzA6Zjc6MDY6MjA6NDM6ZDk6MjM6MWE6NDI6ZjI6Zjg6YTM6YjI6Yjk6NGQ6CisgICAgICAgIDhhOmI0OmYzOmMyOjlhOjU1OjMxOjdjOmM0OjNiOjY3OjlhOmI0OmRmOjRkOjBlOjhhOjkzOgorICAgICAgICA0YToxNzo4YjoxYjo4ZDpjYTo4OTplMTpjZjozYToxZTphYzoxZDpmMTo5YzozMjpiNDo4ZToKKyAgICAgICAgNTk6NzY6YTI6NDE6ODU6MjU6Mzc6YTA6MTM6ZDA6ZjU6N2M6NGU6ZDU6ZWE6OTY6ZTI6NmU6CisgICAgICAgIDcyOmMxOmJiOjJhOmZlOjZjOjZlOmY4OjkxOjk4OjQ2OmZjOmM5OjFiOjU3OjViOmVhOmM4OgorICAgICAgICAxYTozYjozZjpiMDo1MTo5ODozYzowNzpkYToyYzo1OTowMTpkYTo4Yjo0NDplODplMTo3NDoKKyAgICAgICAgZmQ6YTc6Njg6ZGQ6NTQ6YmE6ODM6NDY6ZWM6Yzg6NDY6YjU6Zjg6YWY6OTc6YzA6M2I6MDk6CisgICAgICAgIDFjOjhmOmNlOjcyOjk2OjNkOjMzOjU2OjcwOmJjOjk2OmNiOmQ4OmQ1OjdkOjIwOjlhOjgzOgorICAgICAgICA5ZjoxYTpkYzozOTpmMTpjNTo3MjphMzoxMTowMzpmZDozYjo0Mjo1MjoyOTpkYjplODowMToKKyAgICAgICAgZjc6OWI6NWU6OGM6ZDY6OGQ6ODY6NGU6MTk6ZmE6YmM6MWM6YmU6YzU6MjE6YTU6ODc6OWU6CisgICAgICAgIDc4OjJlOjM2OmRiOjA5OjcxOmEzOjcyOjM0OmY4OjZjOmUzOjA2OjA5OmYyOjVlOjU2OmE1OgorICAgICAgICBkMzpkZDo5ODpmYTpkNDplNjowNjpmNDpmMDpiNjoyMDo2Mzo0YjplYToyOTpiZDphYTo4MjoKKyAgICAgICAgNjY6MWU6ZmI6ODE6YWE6YTc6Mzc6YWQ6MTM6MTg6ZTY6OTI6YzM6ODE6YzE6MzM6YmI6ODg6CisgICAgICAgIDFlOmExOmU3OmUyOmI0OmJkOjMxOjZjOjBlOjUxOjNkOjZmOmZiOjk2OjU2OjgwOmUyOjM2OgorICAgICAgICAxNzpkMTpkYzplNAorU0hBMSBGaW5nZXJwcmludD04MDoyNTpFRjpGNDo2RTo3MDpDODpENDo3MjoyNDo2NTo4NDpGRTo0MDozQjo4QTo4RDo2QTpEQjpGNQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzdhODE5ZWYyLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvN2E4MTllZjIuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xY2MwNDMyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzdhODE5ZWYyLjAKQEAgLTAsMCArMSwxMjYgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRnR6Q0NBNStnQXdJQkFnSUNCUWt3RFFZSktvWklodmNOQVFFRkJRQXdSVEVMTUFrR0ExVUVCaE1DUWsweAorR1RBWEJnTlZCQW9URUZGMWIxWmhaR2x6SUV4cGJXbDBaV1F4R3pBWkJnTlZCQU1URWxGMWIxWmhaR2x6SUZKdgorYjNRZ1EwRWdNakFlRncwd05qRXhNalF4T0RJM01EQmFGdzB6TVRFeE1qUXhPREl6TXpOYU1FVXhDekFKQmdOVgorQkFZVEFrSk5NUmt3RndZRFZRUUtFeEJSZFc5V1lXUnBjeUJNYVcxcGRHVmtNUnN3R1FZRFZRUURFeEpSZFc5VworWVdScGN5QlNiMjkwSUVOQklESXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFDYQorR01wTGxBMEFMYThES1lyd0Q0SElya3daaFIwSW42c3BSSVh6TDRHdE1oNlFScitqaGlZYUh2NStIQmc2WEp4ZworRnlvNmRJTXpNSDFoVkJITDdhdmc1dEtpZnZWcmJ4aTNDZ3N0L2VrKzd3ckdzeERwM01KR0YvaGQvYVRhLzU1SgorV3B6bU0rWWtsdmMvdWxzckhIbzF3dFpuL3F0bVVJdHRLR0FyNzlkZ3c4ZVR2STAya2ZOLytOc1JFOFNjZDNiQgorcnJjQ2FvRjZxVVdENGdYbXVWYkJsRGVQU0hGakl1d1haUWVWaWt2Zmo4WmFDdVd3NDE5ZWF4R3JEUG1GNjBUcAorK0FSejh1bitYSmlNOVhPdmE3Uit6ZFJjQWl0TU9lR3lsWlV0UW9mWDFiT1FRN2RzRS9IZTNmYkUrSWsvMFhYMQora3NPUjFZcUkwSkRzM0czZWljSmxjWmFMRFFQOW5MOWJGcXlTMityK2VYeXQ2Ni8zRnN2YnpTVXI1Ui83bXAvaQorVWN3NlV3eEk1ZzY5eWJSMkJsTG1FUk9GY21NREJPQUVOaXNnR1FMb2RLY2Z0c2xXWnZCMUpkeG53UTVoWUlpegorUHRHby9LUGFIYkRSc1NOVTMwUjJiZTFCMk1HeUlyWlRITjgxSGR5aGR5b3g1QzMxNWVYYnlPRC81WURYQzJPZworL3pPaEQ3b3NGUlhxbDdQU29yVys4b3lXSGhxUEhXeWtZVGU1aG5NejE1ZVduaU45Z3FSTWdlS2gwYnBuWDVVSAorb3ljUjdoWVFlN3hGU2t5eUJOS3I3OVg5REZIT1VHb0lNZm1SMmd5UFpGd0R3enFMSUQ5dWpXYzlPdGIrZlZ1SQoreVY3N3pHSGNpek4zMDBReU5RbGlCSklXRU5pZUowZjdPeUhqK09zZFd3SURBUUFCbzRHd01JR3RNQThHQTFVZAorRXdFQi93UUZNQU1CQWY4d0N3WURWUjBQQkFRREFnRUdNQjBHQTFVZERnUVdCQlFhaEdLOFNFd3pKUVRVN3REMgorQThRWlJ0R1VhekJ1QmdOVkhTTUVaekJsZ0JRYWhHSzhTRXd6SlFUVTd0RDJBOFFaUnRHVWE2RkpwRWN3UlRFTAorTUFrR0ExVUVCaE1DUWsweEdUQVhCZ05WQkFvVEVGRjFiMVpoWkdseklFeHBiV2wwWldReEd6QVpCZ05WQkFNVAorRWxGMWIxWmhaR2x6SUZKdmIzUWdRMEVnTW9JQ0JRa3dEUVlKS29aSWh2Y05BUUVGQlFBRGdnSUJBRDRLRmsyZgorQmx1b3JuRmRMd1V2WitZVFJZUEVOdmJ6d0NZTURiVkhaRjM0dEhMSlJxVURHQ2RWaVhoOWR1cVdOSUFYSU56bgorZy9pTi9BZTQybDlOTG1leWhQM1pSUHgzVUlIbWZMVEpEUXR5VS9oMkJ3ZEJSNVlNKytDQ0pwTlZqUDRpSDJCbAorZkYvbkpyUDNNcENZVU5RM2NWWDJraUY0OTVWNSt2Z3RKb2RtVmpCM3BqZDRNMUlRV0s0L1lZN3lhckh2R0g1SworV1dQS2phSlcxYWN2dkZZZnp6bkI0dnNLcUJVc2ZVMTZZOFpzbDBRODBtL0RTaGNLK0pEU1Y2SVpVYVV0bDBIYQorQjArcFVOcVFqWlJHNFQ3d2xQMFFBRGoxTytoQTRiUnVWaG9nekc5WWplMHVSWS9XNlpNLzU3RXMzenJXSW96YworaExzaWI5RDQ1TVk1NlFTSVBNTzY2MVY2YllDWkpQVnNBZnY0bDdDVVcrdjkwbS94ZDJnTk5XUWpyTGhWb1FQUgorVFVJWjNQaDFXVmFqK2FoSmVmaXZEcmtSb0h5M2F1MDAwTFltWWpnYWh3ejQ2UDB1MDVCL0I1RXFIZForWElXRAorbWJBNENEL3BYdmsxQitUSlltNVhmNmRRbGZlNnlKdm1qcUlCeGRabXYzbGg4endjNGJtQ1hGMmd3K25ZU0wwWgorb2hFVUdXNnloaHRvUGtnM0dvaTNYWlplbk1mdkoySUk0cEVaWE5MeElkMjZGMEtDbDNHQlV6R3BuL1o5WXI5eQorNGFPVEhjeUtKbG9KT05ETzF3MkFGclI0cFRxSFRJMktwZFZHbC9Jc0VMbThWQ0xBQVZCcFE1NzBzdTl0K096YQorOGVPeDc5K1JqMVFxQ3lYQkpobkVVaEFGWmRXQ0VPckNNYzB1CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDEyODkgKDB4NTA5KQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPUJNLCBPPVF1b1ZhZGlzIExpbWl0ZWQsIENOPVF1b1ZhZGlzIFJvb3QgQ0EgMgorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTm92IDI0IDE4OjI3OjAwIDIwMDYgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBOb3YgMjQgMTg6MjM6MzMgMjAzMSBHTVQKKyAgICAgICAgU3ViamVjdDogQz1CTSwgTz1RdW9WYWRpcyBMaW1pdGVkLCBDTj1RdW9WYWRpcyBSb290IENBIDIKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICg0MDk2IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICg0MDk2IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOjlhOjE4OmNhOjRiOjk0OjBkOjAwOjJkOmFmOjAzOjI5OjhhOmYwOjBmOgorICAgICAgICAgICAgICAgICAgICA4MTpjODphZTo0YzoxOTo4NToxZDowODo5ZjphYjoyOTo0NDo4NTpmMzoyZjoKKyAgICAgICAgICAgICAgICAgICAgODE6YWQ6MzI6MWU6OTA6NDY6YmY6YTM6ODY6MjY6MWE6MWU6ZmU6N2U6MWM6CisgICAgICAgICAgICAgICAgICAgIDE4OjNhOjVjOjljOjYwOjE3OjJhOjNhOjc0OjgzOjMzOjMwOjdkOjYxOjU0OgorICAgICAgICAgICAgICAgICAgICAxMTpjYjplZDphYjplMDplNjpkMjphMjo3ZTpmNTo2Yjo2ZjoxODpiNzowYToKKyAgICAgICAgICAgICAgICAgICAgMGI6MmQ6ZmQ6ZTk6M2U6ZWY6MGE6YzY6YjM6MTA6ZTk6ZGM6YzI6NDY6MTc6CisgICAgICAgICAgICAgICAgICAgIGY4OjVkOmZkOmE0OmRhOmZmOjllOjQ5OjVhOjljOmU2OjMzOmU2OjI0Ojk2OgorICAgICAgICAgICAgICAgICAgICBmNzozZjpiYTo1YjoyYjoxYzo3YTozNTpjMjpkNjo2NzpmZTphYjo2Njo1MDoKKyAgICAgICAgICAgICAgICAgICAgOGI6NmQ6Mjg6NjA6MmI6ZWY6ZDc6NjA6YzM6Yzc6OTM6YmM6OGQ6MzY6OTE6CisgICAgICAgICAgICAgICAgICAgIGYzOjdmOmY4OmRiOjExOjEzOmM0OjljOjc3Ojc2OmMxOmFlOmI3OjAyOjZhOgorICAgICAgICAgICAgICAgICAgICA4MTo3YTphOTo0NTo4MzplMjowNTplNjpiOTo1NjpjMTo5NDozNzo4Zjo0ODoKKyAgICAgICAgICAgICAgICAgICAgNzE6NjM6MjI6ZWM6MTc6NjU6MDc6OTU6OGE6NGI6ZGY6OGY6YzY6NWE6MGE6CisgICAgICAgICAgICAgICAgICAgIGU1OmIwOmUzOjVmOjVlOjZiOjExOmFiOjBjOmY5Ojg1OmViOjQ0OmU5OmY4OgorICAgICAgICAgICAgICAgICAgICAwNDo3MzpmMjplOTpmZTo1Yzo5ODo4YzpmNTo3MzphZjo2YjpiNDo3ZTpjZDoKKyAgICAgICAgICAgICAgICAgICAgZDQ6NWM6MDI6MmI6NGM6Mzk6ZTE6YjI6OTU6OTU6MmQ6NDI6ODc6ZDc6ZDU6CisgICAgICAgICAgICAgICAgICAgIGIzOjkwOjQzOmI3OjZjOjEzOmYxOmRlOmRkOmY2OmM0OmY4Ojg5OjNmOmQxOgorICAgICAgICAgICAgICAgICAgICA3NTpmNTo5MjpjMzo5MTpkNTo4YTo4ODpkMDo5MDplYzpkYzo2ZDpkZTo4OToKKyAgICAgICAgICAgICAgICAgICAgYzI6NjU6NzE6OTY6OGI6MGQ6MDM6ZmQ6OWM6YmY6NWI6MTY6YWM6OTI6ZGI6CisgICAgICAgICAgICAgICAgICAgIGVhOmZlOjc5OjdjOmFkOmViOmFmOmY3OjE2OmNiOmRiOmNkOjI1OjJiOmU1OgorICAgICAgICAgICAgICAgICAgICAxZjpmYjo5YTo5ZjplMjo1MTpjYzozYTo1MzowYzo0ODplNjowZTpiZDpjOToKKyAgICAgICAgICAgICAgICAgICAgYjQ6NzY6MDY6NTI6ZTY6MTE6MTM6ODU6NzI6NjM6MDM6MDQ6ZTA6MDQ6MzY6CisgICAgICAgICAgICAgICAgICAgIDJiOjIwOjE5OjAyOmU4Ojc0OmE3OjFmOmI2OmM5OjU2OjY2OmYwOjc1OjI1OgorICAgICAgICAgICAgICAgICAgICBkYzo2NzpjMTowZTo2MTo2MDo4ODpiMzozZTpkMTphODpmYzphMzpkYToxZDoKKyAgICAgICAgICAgICAgICAgICAgYjA6ZDE6YjE6MjM6NTQ6ZGY6NDQ6NzY6NmQ6ZWQ6NDE6ZDg6YzE6YjI6MjI6CisgICAgICAgICAgICAgICAgICAgIGI2OjUzOjFjOmRmOjM1OjFkOmRjOmExOjc3OjJhOjMxOmU0OjJkOmY1OmU1OgorICAgICAgICAgICAgICAgICAgICBlNTpkYjpjODplMDpmZjplNTo4MDpkNzowYjo2MzphMDpmZjozMzphMTowZjoKKyAgICAgICAgICAgICAgICAgICAgYmE6MmM6MTU6MTU6ZWE6OTc6YjM6ZDI6YTI6YjU6YmU6ZjI6OGM6OTY6MWU6CisgICAgICAgICAgICAgICAgICAgIDFhOjhmOjFkOjZjOmE0OjYxOjM3OmI5Ojg2OjczOjMzOmQ3Ojk3Ojk2OjllOgorICAgICAgICAgICAgICAgICAgICAyMzo3ZDo4MjphNDo0Yzo4MTplMjphMTpkMTpiYTo2Nzo1Zjo5NTowNzphMzoKKyAgICAgICAgICAgICAgICAgICAgMjc6MTE6ZWU6MTY6MTA6N2I6YmM6NDU6NGE6NGM6YjI6MDQ6ZDI6YWI6ZWY6CisgICAgICAgICAgICAgICAgICAgIGQ1OmZkOjBjOjUxOmNlOjUwOjZhOjA4OjMxOmY5OjkxOmRhOjBjOjhmOjY0OgorICAgICAgICAgICAgICAgICAgICA1YzowMzpjMzozYTo4YjoyMDozZjo2ZTo4ZDo2NzozZDozYTpkNjpmZTo3ZDoKKyAgICAgICAgICAgICAgICAgICAgNWI6ODg6Yzk6NWU6ZmI6Y2M6NjE6ZGM6OGI6MzM6Nzc6ZDM6NDQ6MzI6MzU6CisgICAgICAgICAgICAgICAgICAgIDA5OjYyOjA0OjkyOjE2OjEwOmQ4OjllOjI3OjQ3OmZiOjNiOjIxOmUzOmY4OgorICAgICAgICAgICAgICAgICAgICBlYjoxZDo1YgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICAxQTo4NDo2MjpCQzo0ODo0QzozMzoyNTowNDpENDpFRTpEMDpGNjowMzpDNDoxOTo0NjpEMTo5NDo2QgorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6MUE6ODQ6NjI6QkM6NDg6NEM6MzM6MjU6MDQ6RDQ6RUU6RDA6RjY6MDM6QzQ6MTk6NDY6RDE6OTQ6NkIKKyAgICAgICAgICAgICAgICBEaXJOYW1lOi9DPUJNL089UXVvVmFkaXMgTGltaXRlZC9DTj1RdW9WYWRpcyBSb290IENBIDIKKyAgICAgICAgICAgICAgICBzZXJpYWw6MDU6MDkKKworICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAzZTowYToxNjo0ZDo5ZjowNjo1YjphODphZTo3MTo1ZDoyZjowNToyZjo2NzplNjoxMzo0NToKKyAgICAgICAgODM6YzQ6MzY6ZjY6ZjM6YzA6MjY6MGM6MGQ6YjU6NDc6NjQ6NWQ6Zjg6YjQ6NzI6Yzk6NDY6CisgICAgICAgIGE1OjAzOjE4OjI3OjU1Ojg5Ojc4OjdkOjc2OmVhOjk2OjM0OjgwOjE3OjIwOmRjOmU3OjgzOgorICAgICAgICBmODo4ZDpmYzowNzpiODpkYTo1Zjo0ZDoyZTo2NzpiMjo4NDpmZDpkOTo0NDpmYzo3Nzo1MDoKKyAgICAgICAgODE6ZTY6N2M6YjQ6Yzk6MGQ6MGI6NzI6NTM6Zjg6NzY6MDc6MDc6NDE6NDc6OTY6MGM6ZmI6CisgICAgICAgIGUwOjgyOjI2OjkzOjU1OjhjOmZlOjIyOjFmOjYwOjY1OjdjOjVmOmU3OjI2OmIzOmY3OjMyOgorICAgICAgICA5MDo5ODo1MDpkNDozNzo3MTo1NTpmNjo5MjoyMTo3ODpmNzo5NTo3OTpmYTpmODoyZDoyNjoKKyAgICAgICAgODc6NjY6NTY6MzA6Nzc6YTY6Mzc6Nzg6MzM6NTI6MTA6NTg6YWU6M2Y6NjE6OGU6ZjI6NmE6CisgICAgICAgIGIxOmVmOjE4OjdlOjRhOjU5OjYzOmNhOjhkOmEyOjU2OmQ1OmE3OjJmOmJjOjU2OjFmOmNmOgorICAgICAgICAzOTpjMTplMjpmYjowYTphODoxNToyYzo3ZDo0ZDo3YTo2MzpjNjo2Yzo5Nzo0NDozYzpkMjoKKyAgICAgICAgNmY6YzM6NGE6MTc6MGE6Zjg6OTA6ZDI6NTc6YTI6MTk6NTE6YTU6MmQ6OTc6NDE6ZGE6MDc6CisgICAgICAgIDRmOmE5OjUwOmRhOjkwOjhkOjk0OjQ2OmUxOjNlOmYwOjk0OmZkOjEwOjAwOjM4OmY1OjNiOgorICAgICAgICBlODo0MDplMTpiNDo2ZTo1NjoxYToyMDpjYzo2Zjo1ODo4ZDplZDoyZTo0NTo4ZjpkNjplOToKKyAgICAgICAgOTM6M2Y6ZTc6YjE6MmM6ZGY6M2E6ZDY6MjI6OGM6ZGM6ODQ6YmI6MjI6NmY6ZDA6Zjg6ZTQ6CisgICAgICAgIGM2OjM5OmU5OjA0Ojg4OjNjOmMzOmJhOmViOjU1OjdhOjZkOjgwOjk5OjI0OmY1OjZjOjAxOgorICAgICAgICBmYjpmODo5NzpiMDo5NDo1YjplYjpmZDpkMjo2ZjpmMTo3Nzo2ODowZDozNTo2NDoyMzphYzoKKyAgICAgICAgYjg6NTU6YTE6MDM6ZDE6NGQ6NDI6MTk6ZGM6Zjg6NzU6NTk6NTY6YTM6Zjk6YTg6NDk6Nzk6CisgICAgICAgIGY4OmFmOjBlOmI5OjExOmEwOjdjOmI3OjZhOmVkOjM0OmQwOmI2OjI2OjYyOjM4OjFhOjg3OgorICAgICAgICAwYzpmODplODpmZDoyZTpkMzo5MDo3ZjowNzo5MToyYToxZDpkNjo3ZTo1Yzo4NTo4Mzo5OToKKyAgICAgICAgYjA6Mzg6MDg6M2Y6ZTk6NWU6Zjk6MzU6MDc6ZTQ6Yzk6NjI6NmU6NTc6N2Y6YTc6NTA6OTU6CisgICAgICAgIGY3OmJhOmM4OjliOmU2OjhlOmEyOjAxOmM1OmQ2OjY2OmJmOjc5OjYxOmYzOjNjOjFjOmUxOgorICAgICAgICBiOTo4Mjo1Yzo1ZDphMDpjMzplOTpkODo0ODpiZDoxOTphMjoxMToxNDoxOTo2ZTpiMjo4NjoKKyAgICAgICAgMWI6Njg6M2U6NDg6Mzc6MWE6ODg6Yjc6NWQ6OTY6NWU6OWM6Yzc6ZWY6Mjc6NjI6MDg6ZTI6CisgICAgICAgIDkxOjE5OjVjOmQyOmYxOjIxOmRkOmJhOjE3OjQyOjgyOjk3OjcxOjgxOjUzOjMxOmE5OjlmOgorICAgICAgICBmNjo3ZDo2MjpiZjo3MjplMTphMzo5MzoxZDpjYzo4YToyNjo1YTowOTozODpkMDpjZTpkNzoKKyAgICAgICAgMGQ6ODA6MTY6YjQ6Nzg6YTU6M2E6ODc6NGM6OGQ6OGE6YTU6ZDU6NDY6OTc6ZjI6MmM6MTA6CisgICAgICAgIGI5OmJjOjU0OjIyOmMwOjAxOjUwOjY5OjQzOjllOmY0OmIyOmVmOjZkOmY4OmVjOmRhOmYxOgorICAgICAgICBlMzpiMTplZjpkZjo5MTo4Zjo1NDoyYTowYjoyNTpjMToyNjoxOTpjNDo1MjoxMDowNTo2NToKKyAgICAgICAgZDU6ODI6MTA6ZWE6YzI6MzE6Y2Q6MmUKK1NIQTEgRmluZ2VycHJpbnQ9Q0E6M0E6RkI6Q0Y6MTI6NDA6MzY6NEI6NDQ6QjI6MTY6MjA6ODg6ODA6NDg6Mzk6MTk6OTM6N0M6RjcKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy83ZDNjZDgyNi4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzdkM2NkODI2LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODBjYTk0MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy83ZDNjZDgyNi4wCkBAIC0wLDAgKzEsNTIgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJQzV6Q0NBbEFDQVFFd0RRWUpLb1pJaHZjTkFRRUZCUUF3Z2JzeEpEQWlCZ05WQkFjVEcxWmhiR2xEWlhKMAorSUZaaGJHbGtZWFJwYjI0Z1RtVjBkMjl5YXpFWE1CVUdBMVVFQ2hNT1ZtRnNhVU5sY25Rc0lFbHVZeTR4TlRBegorQmdOVkJBc1RMRlpoYkdsRFpYSjBJRU5zWVhOeklETWdVRzlzYVdONUlGWmhiR2xrWVhScGIyNGdRWFYwYUc5eQorYVhSNU1TRXdId1lEVlFRREV4aG9kSFJ3T2k4dmQzZDNMblpoYkdsalpYSjBMbU52YlM4eElEQWVCZ2txaGtpRworOXcwQkNRRVdFV2x1Wm05QWRtRnNhV05sY25RdVkyOXRNQjRYRFRrNU1EWXlOakF3TWpJek0xb1hEVEU1TURZeQorTmpBd01qSXpNMW93Z2JzeEpEQWlCZ05WQkFjVEcxWmhiR2xEWlhKMElGWmhiR2xrWVhScGIyNGdUbVYwZDI5eQorYXpFWE1CVUdBMVVFQ2hNT1ZtRnNhVU5sY25Rc0lFbHVZeTR4TlRBekJnTlZCQXNUTEZaaGJHbERaWEowSUVOcworWVhOeklETWdVRzlzYVdONUlGWmhiR2xrWVhScGIyNGdRWFYwYUc5eWFYUjVNU0V3SHdZRFZRUURFeGhvZEhSdworT2k4dmQzZDNMblpoYkdsalpYSjBMbU52YlM4eElEQWVCZ2txaGtpRzl3MEJDUUVXRVdsdVptOUFkbUZzYVdObAorY25RdVkyOXRNSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdOQURDQmlRS0JnUURqbUZHV0hPalZzUWFCYWxmRAorY25XVHE4K2Vwdnp6RmxMV0xVMmZOVVNvTGdSTkIwbUtPQ24xZHpmbnQ2dGQzelp4RkptUDNNS1M4ZWRna3BmcworMkVqY3Y4RUNJTVlrcENoTU1GcDJiYkZjODkzZW5oQnhvWWpIVzV0QmJjcXd1STRWN3Eweks4OUhCRngxY1FxWQorSkpncHAwbFpwZDM0dDBOaVlmUFQ0dEJWUHdJREFRQUJNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0R0JBRmE3QWxpRQorWndnczN4L2JlMGt6OWRObm5mUzBDaEN6eWNVczRwSnFjWGduOG5DRFF0TSt6NmxVOVBIWWtoYU0wUVRMUzZ2SgorbjBXdVBJcXBzSEV6WGNqRlY5K3ZxRFd6ZjRtSDZlZ2xrcmgvaFhxdTFyd2VOMWdxWjhtUnp5cUJQdTNHT2QvQQorUGhtY0djd1RUWUpCdFl6ZTREMWdDQ0FQUlg1cm9uK2pqQlh1CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAxICgweDApCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDEgKDB4MSkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogTD1WYWxpQ2VydCBWYWxpZGF0aW9uIE5ldHdvcmssIE89VmFsaUNlcnQsIEluYy4sIE9VPVZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5LCBDTj1odHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8vZW1haWxBZGRyZXNzPWluZm9AdmFsaWNlcnQuY29tCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBKdW4gMjYgMDA6MjI6MzMgMTk5OSBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEp1biAyNiAwMDoyMjozMyAyMDE5IEdNVAorICAgICAgICBTdWJqZWN0OiBMPVZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yaywgTz1WYWxpQ2VydCwgSW5jLiwgT1U9VmFsaUNlcnQgQ2xhc3MgMyBQb2xpY3kgVmFsaWRhdGlvbiBBdXRob3JpdHksIENOPWh0dHA6Ly93d3cudmFsaWNlcnQuY29tLy9lbWFpbEFkZHJlc3M9aW5mb0B2YWxpY2VydC5jb20KKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgxMDI0IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgxMDI0IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmUzOjk4OjUxOjk2OjFjOmU4OmQ1OmIxOjA2OjgxOjZhOjU3OmMzOjcyOgorICAgICAgICAgICAgICAgICAgICA3NTo5MzphYjpjZjo5ZTphNjpmYzpmMzoxNjo1MjpkNjoyZDo0ZDo5ZjozNToKKyAgICAgICAgICAgICAgICAgICAgNDQ6YTg6MmU6MDQ6NGQ6MDc6NDk6OGE6Mzg6Mjk6ZjU6Nzc6Mzc6ZTc6Yjc6CisgICAgICAgICAgICAgICAgICAgIGFiOjVkOmRmOjM2OjcxOjE0Ojk5OjhmOmRjOmMyOjkyOmYxOmU3OjYwOjkyOgorICAgICAgICAgICAgICAgICAgICA5NzplYzpkODo0ODpkYzpiZjpjMTowMjoyMDpjNjoyNDphNDoyODo0YzozMDoKKyAgICAgICAgICAgICAgICAgICAgNWE6NzY6NmQ6YjE6NWM6ZjM6ZGQ6ZGU6OWU6MTA6NzE6YTE6ODg6Yzc6NWI6CisgICAgICAgICAgICAgICAgICAgIDliOjQxOjZkOmNhOmIwOmI4OjhlOjE1OmVlOmFkOjMzOjJiOmNmOjQ3OjA0OgorICAgICAgICAgICAgICAgICAgICA1Yzo3NTo3MTowYTo5ODoyNDo5ODoyOTphNzo0OTo1OTphNTpkZDpmODpiNzoKKyAgICAgICAgICAgICAgICAgICAgNDM6NjI6NjE6ZjM6ZDM6ZTI6ZDA6NTU6M2YKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDU2OmJiOjAyOjU4Ojg0OjY3OjA4OjJjOmRmOjFmOmRiOjdiOjQ5OjMzOmY1OmQzOjY3OjlkOgorICAgICAgICBmNDpiNDowYToxMDpiMzpjOTpjNToyYzplMjo5Mjo2YTo3MTo3ODoyNzpmMjo3MDo4Mzo0MjoKKyAgICAgICAgZDM6M2U6Y2Y6YTk6NTQ6ZjQ6ZjE6ZDg6OTI6MTY6OGM6ZDE6MDQ6Y2I6NGI6YWI6Yzk6OWY6CisgICAgICAgIDQ1OmFlOjNjOjhhOmE5OmIwOjcxOjMzOjVkOmM4OmM1OjU3OmRmOmFmOmE4OjM1OmIzOjdmOgorICAgICAgICA4OTo4NzplOTplODoyNTo5MjpiODo3Zjo4NTo3YTphZTpkNjpiYzoxZTozNzo1ODoyYTo2NzoKKyAgICAgICAgYzk6OTE6Y2Y6MmE6ODE6M2U6ZWQ6YzY6Mzk6ZGY6YzA6M2U6MTk6OWM6MTk6Y2M6MTM6NGQ6CisgICAgICAgIDgyOjQxOmI1OjhjOmRlOmUwOjNkOjYwOjA4OjIwOjBmOjQ1OjdlOjZiOmEyOjdmOmEzOjhjOgorICAgICAgICAxNTplZQorU0hBMSBGaW5nZXJwcmludD02OTpCRDo4QzpGNDo5QzpEMzowMDpGQjo1OToyRToxNzo5MzpDQTo1NTo2QTpGMzpFQzpBQTozNTpGQgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzdkNDUzZDhmLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvN2Q0NTNkOGYuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMDA1NTViCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzdkNDUzZDhmLjAKQEAgLTAsMCArMSw3NSBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFR2pDQ0F3SUNFUUNiZmdaSm96NWl1ZFh1a0VoeEtlOVhNQTBHQ1NxR1NJYjNEUUVCQlFVQU1JSEtNUXN3CitDUVlEVlFRR0V3SlZVekVYTUJVR0ExVUVDaE1PVm1WeWFWTnBaMjRzSUVsdVl5NHhIekFkQmdOVkJBc1RGbFpsCitjbWxUYVdkdUlGUnlkWE4wSUU1bGRIZHZjbXN4T2pBNEJnTlZCQXNUTVNoaktTQXhPVGs1SUZabGNtbFRhV2R1CitMQ0JKYm1NdUlDMGdSbTl5SUdGMWRHaHZjbWw2WldRZ2RYTmxJRzl1YkhreFJUQkRCZ05WQkFNVFBGWmxjbWxUCithV2R1SUVOc1lYTnpJRE1nVUhWaWJHbGpJRkJ5YVcxaGNua2dRMlZ5ZEdsbWFXTmhkR2x2YmlCQmRYUm9iM0pwCitkSGtnTFNCSE16QWVGdzA1T1RFd01ERXdNREF3TURCYUZ3MHpOakEzTVRZeU16VTVOVGxhTUlIS01Rc3dDUVlECitWUVFHRXdKVlV6RVhNQlVHQTFVRUNoTU9WbVZ5YVZOcFoyNHNJRWx1WXk0eEh6QWRCZ05WQkFzVEZsWmxjbWxUCithV2R1SUZSeWRYTjBJRTVsZEhkdmNtc3hPakE0QmdOVkJBc1RNU2hqS1NBeE9UazVJRlpsY21sVGFXZHVMQ0JKCitibU11SUMwZ1JtOXlJR0YxZEdodmNtbDZaV1FnZFhObElHOXViSGt4UlRCREJnTlZCQU1UUEZabGNtbFRhV2R1CitJRU5zWVhOeklETWdVSFZpYkdsaklGQnlhVzFoY25rZ1EyVnlkR2xtYVdOaGRHbHZiaUJCZFhSb2IzSnBkSGtnCitMU0JITXpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTXU2bkZMOGVCOGFIbThiCitOM085K01scmxCSXdUL0EyUi9YUWtRcjFGOGlsWWNFV1FFMzdpbUdRNVhZZ3dSRUdmYXNzYnFiMUVVR08raTJ0CitLbUZacEdjbVRORG92RkpiY0NBRVdORjZ5YVJwdklNWFpLMEZpN3pRV002TmpQWHI4RUpKQzUyWEoyY3lidUd1CitreFVjY0x3Z1RTOFkzcEtJNkd5RlZ4RWE2WDdqSmhGVW9rV1dWWVBLTUlubzNOaWo3U3FBUDM5NVpWYytGU0JtCitDQytWazcrcVJ5K29ScGZ3RXVMK3dnb3JVZVoyNXJkR3QrSU5wc3lvdzB4WlZZbm02Rk5jSE9xZDhHSVdDNmZKCitYd3p3M3NKMnpxLzNhdkw2UWFhaU14VEo1WHBqMDU1aU45V0ZaWjRPNWxNa2RCdGVIUkpUVzhjczU0TkpPeFd1CitpbWk1VjVjQ0F3RUFBVEFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBRVJTV3dhdVNDUGMvTDhteS91UmFuMlRlCisyeUZQaHBrMGRqWlgzZEFWTDhXdGZ4VWZOMkp6UHRUblg4NFhBOXMxK2l2YnJtQUpYeDVmajI2N0N6M3FXaE1lCitER0J2dGNDMUl5SXVCd3ZMcVhUTFI3c2R3ZGVsYTh3djBrTDlTZDJuaWM5VHV0b0FXaWkvZ3QvNHVoTWRVSWFDCisvWTR3anlsR3NCNDlOZG80WWhZWVNxM210bEZzM3E5aTZ3SFFIaVQrZW84U0doSm91UHRtbVJRVVJWeXU1NjVwCitGNEVyV2pmSlhpcjB4dUtoWEZTYnBsUUF6L0R4d2NlWU1CbzdOaGJibzI3cS9hMnl3dHJ2QWtjVGlzRHhzekd0CitUeHpoVDV5dkR3eWQ5M2dOMlBRMVZvRGF0MjBYajUwZWdXVGgvc1ZGdXExcnVRcDZUazlMaE81TDhYM2RFUT09CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAxICgweDApCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICA5Yjo3ZTowNjo0OTphMzozZTo2MjpiOTpkNTplZTo5MDo0ODo3MToyOTplZjo1NworICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPVZlcmlTaWduLCBJbmMuLCBPVT1WZXJpU2lnbiBUcnVzdCBOZXR3b3JrLCBPVT0oYykgMTk5OSBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5LCBDTj1WZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzMKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IE9jdCAgMSAwMDowMDowMCAxOTk5IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogSnVsIDE2IDIzOjU5OjU5IDIwMzYgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89VmVyaVNpZ24sIEluYy4sIE9VPVZlcmlTaWduIFRydXN0IE5ldHdvcmssIE9VPShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHksIENOPVZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMworICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6Y2I6YmE6OWM6NTI6ZmM6Nzg6MWY6MWE6MWU6NmY6MWI6Mzc6NzM6YmQ6CisgICAgICAgICAgICAgICAgICAgIGY4OmM5OjZiOjk0OjEyOjMwOjRmOmYwOjM2OjQ3OmY1OmQwOjkxOjBhOmY1OgorICAgICAgICAgICAgICAgICAgICAxNzpjODphNTo2MTpjMToxNjo0MDo0ZDpmYjo4YTo2MTo5MDplNTo3NjoyMDoKKyAgICAgICAgICAgICAgICAgICAgYzE6MTE6MDY6N2Q6YWI6MmM6NmU6YTY6ZjU6MTE6NDE6OGU6ZmE6MmQ6YWQ6CisgICAgICAgICAgICAgICAgICAgIDJhOjYxOjU5OmE0OjY3OjI2OjRjOmQwOmU4OmJjOjUyOjViOjcwOjIwOjA0OgorICAgICAgICAgICAgICAgICAgICA1ODpkMTo3YTpjOTphNDo2OTpiYzo4MzoxNzo2NDphZDowNTo4YjpiYzpkMDoKKyAgICAgICAgICAgICAgICAgICAgNTg6Y2U6OGQ6OGM6ZjU6ZWI6ZjA6NDI6NDk6MGI6OWQ6OTc6Mjc6Njc6MzI6CisgICAgICAgICAgICAgICAgICAgIDZlOmUxOmFlOjkzOjE1OjFjOjcwOmJjOjIwOjRkOjJmOjE4OmRlOjkyOjg4OgorICAgICAgICAgICAgICAgICAgICBlODo2Yzo4NTo1NzoxMToxYTplOTo3ZTplMzoyNjoxMTo1NDphMjo0NTo5NjoKKyAgICAgICAgICAgICAgICAgICAgNTU6ODM6Y2E6MzA6ODk6ZTg6ZGM6ZDg6YTM6ZWQ6MmE6ODA6M2Y6N2Y6Nzk6CisgICAgICAgICAgICAgICAgICAgIDY1OjU3OjNlOjE1OjIwOjY2OjA4OjJmOjk1OjkzOmJmOmFhOjQ3OjJmOmE4OgorICAgICAgICAgICAgICAgICAgICA0Njo5NzpmMDoxMjplMjpmZTpjMjowYToyYjo1MTplNjo3NjplNjpiNzo0NjoKKyAgICAgICAgICAgICAgICAgICAgYjc6ZTI6MGQ6YTY6Y2M6YTg6YzM6NGM6NTk6NTU6ODk6ZTY6ZTg6NTM6NWM6CisgICAgICAgICAgICAgICAgICAgIDFjOmVhOjlkOmYwOjYyOjE2OjBiOmE3OmM5OjVmOjBjOmYwOmRlOmMyOjc2OgorICAgICAgICAgICAgICAgICAgICBjZTphZjpmNzo2YTpmMjpmYTo0MTphNjphMjozMzoxNDpjOTplNTo3YTo2MzoKKyAgICAgICAgICAgICAgICAgICAgZDM6OWU6NjI6Mzc6ZDU6ODU6NjU6OWU6MGU6ZTY6NTM6MjQ6NzQ6MWI6NWU6CisgICAgICAgICAgICAgICAgICAgIDFkOjEyOjUzOjViOmM3OjJjOmU3OjgzOjQ5OjNiOjE1OmFlOjhhOjY4OmI5OgorICAgICAgICAgICAgICAgICAgICA1Nzo5NworICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMTE6MTQ6OTY6YzE6YWI6OTI6MDg6Zjc6M2Y6MmY6Yzk6YjI6ZmU6ZTQ6NWE6OWY6NjQ6ZGU6CisgICAgICAgIGRiOjIxOjRmOjg2Ojk5OjM0Ojc2OjM2OjU3OmRkOmQwOjE1OjJmOmM1OmFkOjdmOjE1OjFmOgorICAgICAgICAzNzo2Mjo3MzozZTpkNDplNzo1ZjpjZToxNzowMzpkYjozNTpmYToyYjpkYjphZTo2MDowOToKKyAgICAgICAgNWY6MWU6NWY6OGY6NmU6YmI6MGI6M2Q6ZWE6NWE6MTM6MWU6MGM6NjA6NmY6YjU6YzA6YjU6CisgICAgICAgIDIzOjIyOjJlOjA3OjBiOmNiOmE5Ojc0OmNiOjQ3OmJiOjFkOmMxOmQ3OmE1OjZiOmNjOjJmOgorICAgICAgICBkMjo0MjpmZDo0OTpkZDphNzo4OTpjZjo1MzpiYTpkYTowMDo1YToyODpiZjo4MjpkZjpmODoKKyAgICAgICAgYmE6MTM6MWQ6NTA6ODY6ODI6ZmQ6OGU6MzA6OGY6Mjk6NDY6YjA6MWU6M2Q6MzU6ZGE6Mzg6CisgICAgICAgIDYyOjE2OjE4OjRhOmFkOmU2OmI2OjUxOjZjOmRlOmFmOjYyOmViOjAxOmQwOjFlOjI0OmZlOgorICAgICAgICA3YTo4ZjoxMjoxYToxMjo2ODpiODpmYjo2Njo5OToxNDoxNDo0NTo1YzphZTplNzphZTo2OToKKyAgICAgICAgMTc6ODE6MmI6NWE6Mzc6Yzk6NWU6MmE6ZjQ6YzY6ZTI6YTE6NWM6NTQ6OWI6YTY6NTQ6MDA6CisgICAgICAgIGNmOmYwOmYxOmMxOmM3Ojk4OjMwOjFhOjNiOjM2OjE2OmRiOmEzOjZlOmVhOmZkOmFkOmIyOgorICAgICAgICBjMjpkYTplZjowMjo0NzoxMzo4YTpjMDpmMTpiMzozMTphZDo0ZjoxYzplMTo0Zjo5YzphZjoKKyAgICAgICAgMGY6MGM6OWQ6Zjc6Nzg6MGQ6ZDg6ZjQ6MzU6NTY6ODA6ZGE6Yjc6NmQ6MTc6OGY6OWQ6MWU6CisgICAgICAgIDgxOjY0OmUxOmZlOmM1OjQ1OmJhOmFkOjZiOmI5OjBhOjdhOjRlOjRmOjRiOjg0OmVlOjRiOgorICAgICAgICBmMTo3ZDpkZDoxMQorU0hBMSBGaW5nZXJwcmludD0xMzoyRDowRDo0NTo1Mzo0Qjo2OTo5NzpDRDpCMjpENTpDMzozOTpFMjo1NTo3Njo2MDo5Qjo1QzpDNgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzgxYjk3NjhmLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvODFiOTc2OGYuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YzdhYzU0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzgxYjk3NjhmLjAKQEAgLTAsMCArMSw4NCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEeFRDQ0FxMmdBd0lCQWdJUUFxeGNKbW9MUUp1UEMzbnlya1lsZHpBTkJna3Foa2lHOXcwQkFRVUZBREJzCitNUXN3Q1FZRFZRUUdFd0pWVXpFVk1CTUdBMVVFQ2hNTVJHbG5hVU5sY25RZ1NXNWpNUmt3RndZRFZRUUxFeEIzCitkM2N1WkdsbmFXTmxjblF1WTI5dE1Tc3dLUVlEVlFRREV5SkVhV2RwUTJWeWRDQklhV2RvSUVGemMzVnlZVzVqCitaU0JGVmlCU2IyOTBJRU5CTUI0WERUQTJNVEV4TURBd01EQXdNRm9YRFRNeE1URXhNREF3TURBd01Gb3diREVMCitNQWtHQTFVRUJoTUNWVk14RlRBVEJnTlZCQW9UREVScFoybERaWEowSUVsdVl6RVpNQmNHQTFVRUN4TVFkM2QzCitMbVJwWjJsalpYSjBMbU52YlRFck1Da0dBMVVFQXhNaVJHbG5hVU5sY25RZ1NHbG5hQ0JCYzNOMWNtRnVZMlVnCitSVllnVW05dmRDQkRRVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFNYk01WFBtCisrOVM3NVMwdE1xYmY1WUUveWMwbFNiWnhLc1BWbERSbm9nb2NzRjlwcGtDeHhMZXlqOUNZcEtsQldUclQzSlRXCitQTnQwT0tSS3pFMGxndmRLcFZNU09PN3pTVzF4a1g1anRxdW1YOE9raFBoUFlsRysrTVhzMnppUzR3YmxDSkVNCit4Q2hCVmZ2TFdva1ZmbkhvTmI5TmNnazl2am80VUZ0M01SdU5zOGNrUlpxbnJHMEFGRm9FdDdvVDYxRUttRUZCCitJazVsWVllQlFWQ21lVnlKM2hsS1Y5VXU1bDBjVXl4K21NMGFCaGFrYUhQUU5BUVRYS0Z4MDFwOFZkdGVaT0UzCitoekJXQk9VUnRDbUFFdkY1T1lpaUFoRjhKMmEzaUxkNDhzb0txRGlyQ21UQ3YyWmRsWVRCb1NVZWgxMGFVQXNnCitFc3hCdTI0TFVUaTRTOHNDQXdFQUFhTmpNR0V3RGdZRFZSMFBBUUgvQkFRREFnR0dNQThHQTFVZEV3RUIvd1FGCitNQU1CQWY4d0hRWURWUjBPQkJZRUZMRSt3MmtEK0w5SEFkU1lKaG9JQXU5alpDdkRNQjhHQTFVZEl3UVlNQmFBCitGTEUrdzJrRCtMOUhBZFNZSmhvSUF1OWpaQ3ZETUEwR0NTcUdTSWIzRFFFQkJRVUFBNElCQVFBY0dnYVgzTmVjCituenlJWmdZSVZ5SGJJVWY0S21lcXZ4Z3lka0FRVjhHSzgzclpFV1dPTmZxZS9FVzFudGxNTVV1NGtlaERMSTZ6CitlTTdiNDFONWNkYmxJWlFCMmxXSG1pUms5b3Btek42Y044Mm9OTEZwbXlQSW5uZ2lLM0JENDFWSE1XRVo3MWpGCitoUzlPTVBhZ01SWWp5T2ZpWlJZenk3OGFHNkE5K01wZWl6R0xZQWlKTFF3R1hGSzN4UGtLbU5FVlg1OFN2bncyCitZemk5UktSLzVDWXJDc1NYYVEzcGpPTEFFRmU0eUhZU2tWWHlTR25ZdkNvQ1d3OUUxQ0F4Mi9TNmNDWmRrR0NlCit2RXNYQ1MrMHl4NURhTWtISjhIU1hQZnFJYmxvRXB3OG5MK2UvSUJjbTJQTjdFZXFKU2Rub0RmekFJSjlWTmVwCisrT2t1RTZOMzZCOUsKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDAyOmFjOjVjOjI2OjZhOjBiOjQwOjliOjhmOjBiOjc5OmYyOmFlOjQ2OjI1Ojc3CisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9VVMsIE89RGlnaUNlcnQgSW5jLCBPVT13d3cuZGlnaWNlcnQuY29tLCBDTj1EaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBOb3YgMTAgMDA6MDA6MDAgMjAwNiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IE5vdiAxMCAwMDowMDowMCAyMDMxIEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPURpZ2lDZXJ0IEluYywgT1U9d3d3LmRpZ2ljZXJ0LmNvbSwgQ049RGlnaUNlcnQgSGlnaCBBc3N1cmFuY2UgRVYgUm9vdCBDQQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YzY6Y2M6ZTU6NzM6ZTY6ZmI6ZDQ6YmI6ZTU6MmQ6MmQ6MzI6YTY6ZGY6CisgICAgICAgICAgICAgICAgICAgIGU1OjgxOjNmOmM5OmNkOjI1OjQ5OmI2OjcxOjJhOmMzOmQ1Ojk0OjM0OjY3OgorICAgICAgICAgICAgICAgICAgICBhMjowYToxYzpiMDo1Zjo2OTphNjo0MDpiMTpjNDpiNzpiMjo4ZjpkMDo5ODoKKyAgICAgICAgICAgICAgICAgICAgYTQ6YTk6NDE6NTk6M2E6ZDM6ZGM6OTQ6ZDY6M2M6ZGI6NzQ6Mzg6YTQ6NGE6CisgICAgICAgICAgICAgICAgICAgIGNjOjRkOjI1OjgyOmY3OjRhOmE1OjUzOjEyOjM4OmVlOmYzOjQ5OjZkOjcxOgorICAgICAgICAgICAgICAgICAgICA5MTo3ZTo2MzpiNjphYjphNjo1ZjpjMzphNDo4NDpmODo0Zjo2Mjo1MTpiZToKKyAgICAgICAgICAgICAgICAgICAgZjg6YzU6ZWM6ZGI6Mzg6OTI6ZTM6MDY6ZTU6MDg6OTE6MGM6YzQ6Mjg6NDE6CisgICAgICAgICAgICAgICAgICAgIDU1OmZiOmNiOjVhOjg5OjE1OjdlOjcxOmU4OjM1OmJmOjRkOjcyOjA5OjNkOgorICAgICAgICAgICAgICAgICAgICBiZTozYTozODo1MDo1Yjo3NzozMToxYjo4ZDpiMzpjNzoyNDo0NTo5YTphNzoKKyAgICAgICAgICAgICAgICAgICAgYWM6NmQ6MDA6MTQ6NWE6MDQ6Yjc6YmE6MTM6ZWI6NTE6MGE6OTg6NDE6NDE6CisgICAgICAgICAgICAgICAgICAgIDIyOjRlOjY1OjYxOjg3OjgxOjQxOjUwOmE2Ojc5OjVjOjg5OmRlOjE5OjRhOgorICAgICAgICAgICAgICAgICAgICA1NzpkNToyZTplNjo1ZDoxYzo1MzoyYzo3ZTo5ODpjZDoxYTowNjoxNjphNDoKKyAgICAgICAgICAgICAgICAgICAgNjg6NzM6ZDA6MzQ6MDQ6MTM6NWM6YTE6NzE6ZDM6NWE6N2M6NTU6ZGI6NWU6CisgICAgICAgICAgICAgICAgICAgIDY0OmUxOjM3Ojg3OjMwOjU2OjA0OmU1OjExOmI0OjI5OjgwOjEyOmYxOjc5OgorICAgICAgICAgICAgICAgICAgICAzOTo4ODphMjowMjoxMTo3YzoyNzo2NjpiNzo4ODpiNzo3ODpmMjpjYTowYToKKyAgICAgICAgICAgICAgICAgICAgYTg6Mzg6YWI6MGE6NjQ6YzI6YmY6NjY6NWQ6OTU6ODQ6YzE6YTE6MjU6MWU6CisgICAgICAgICAgICAgICAgICAgIDg3OjVkOjFhOjUwOjBiOjIwOjEyOmNjOjQxOmJiOjZlOjBiOjUxOjM4OmI4OgorICAgICAgICAgICAgICAgICAgICA0YjpjYgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIERpZ2l0YWwgU2lnbmF0dXJlLCBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBCMTozRTpDMzo2OTowMzpGODpCRjo0NzowMTpENDo5ODoyNjoxQTowODowMjpFRjo2Mzo2NDoyQjpDMworICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6QjE6M0U6QzM6Njk6MDM6Rjg6QkY6NDc6MDE6RDQ6OTg6MjY6MUE6MDg6MDI6RUY6NjM6NjQ6MkI6QzMKKworICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAxYzoxYTowNjo5NzpkYzpkNzo5Yzo5ZjozYzo4ODo2NjowNjowODo1NzoyMTpkYjoyMTo0NzoKKyAgICAgICAgZjg6MmE6Njc6YWE6YmY6MTg6MzI6NzY6NDA6MTA6NTc6YzE6OGE6ZjM6N2E6ZDk6MTE6NjU6CisgICAgICAgIDhlOjM1OmZhOjllOmZjOjQ1OmI1OjllOmQ5OjRjOjMxOjRiOmI4OjkxOmU4OjQzOjJjOjhlOgorICAgICAgICBiMzo3ODpjZTpkYjplMzo1Mzo3OTo3MTpkNjplNToyMTo5NDowMTpkYTo1NTo4Nzo5YToyNDoKKyAgICAgICAgNjQ6ZjY6OGE6NjY6Y2M6ZGU6OWM6Mzc6Y2Q6YTg6MzQ6YjE6Njk6OWI6MjM6Yzg6OWU6Nzg6CisgICAgICAgIDIyOjJiOjcwOjQzOmUzOjU1OjQ3OjMxOjYxOjE5OmVmOjU4OmM1Ojg1OjJmOjRlOjMwOmY2OgorICAgICAgICBhMDozMToxNjoyMzpjODplNzplMjo2NToxNjozMzpjYjpiZjoxYToxYjphMDozZDpmODpjYToKKyAgICAgICAgNWU6OGI6MzE6OGI6NjA6MDg6ODk6MmQ6MGM6MDY6NWM6NTI6Yjc6YzQ6Zjk6MGE6OTg6ZDE6CisgICAgICAgIDE1OjVmOjlmOjEyOmJlOjdjOjM2OjYzOjM4OmJkOjQ0OmE0OjdmOmU0OjI2OjJiOjBhOmM0OgorICAgICAgICA5Nzo2OTowZDplOTo4YzplMjpjMDoxMDo1NzpiODpjODo3NjoxMjo5MTo1NTpmMjo0ODo2OToKKyAgICAgICAgZDg6YmM6MmE6MDI6NWI6MGY6NDQ6ZDQ6MjA6MzE6ZGI6ZjQ6YmE6NzA6MjY6NWQ6OTA6NjA6CisgICAgICAgIDllOmJjOjRiOjE3OjA5OjJmOmI0OmNiOjFlOjQzOjY4OmM5OjA3OjI3OmMxOmQyOjVjOmY3OgorICAgICAgICBlYToyMTpiOTo2ODoxMjo5YzozYzo5YzpiZjo5ZTpmYzo4MDo1Yzo5Yjo2MzpjZDplYzo0NzoKKyAgICAgICAgYWE6MjU6Mjc6Njc6YTA6Mzc6ZjM6MDA6ODI6N2Q6NTQ6ZDc6YTk6Zjg6ZTk6MmU6MTM6YTM6CisgICAgICAgIDc3OmU4OjFmOjRhCitTSEExIEZpbmdlcnByaW50PTVGOkI3OkVFOjA2OjMzOkUyOjU5OkRCOkFEOjBDOjRDOjlBOkU2OkQzOjhGOjFBOjYxOkM3OkRDOjI1CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvODQ3MDcxOWQuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy84NDcwNzE5ZC4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQzYjM1MzIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvODQ3MDcxOWQuMApAQCAtMCwwICsxLDgyIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSURZVENDQWttZ0F3SUJBZ0lRQ2dFQkFRQUFBbndBQUFBS0FBQUFBakFOQmdrcWhraUc5dzBCQVFVRkFEQTYKK01Sa3dGd1lEVlFRS0V4QlNVMEVnVTJWamRYSnBkSGtnU1c1ak1SMHdHd1lEVlFRTEV4UlNVMEVnVTJWamRYSnAKK2RIa2dNakEwT0NCV016QWVGdzB3TVRBeU1qSXlNRE01TWpOYUZ3MHlOakF5TWpJeU1ETTVNak5hTURveEdUQVgKK0JnTlZCQW9URUZKVFFTQlRaV04xY21sMGVTQkpibU14SFRBYkJnTlZCQXNURkZKVFFTQlRaV04xY21sMGVTQXkKK01EUTRJRll6TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF0NDlWY2RLQTNYdHAKK2VhZndHRkF5UEdKbjlncVZCOTNtRy9PZTJkSkJWR3V0bjN5K0djMzdScXRCYUI0WTZsWElMNUY0aVNqN0p5bGcKKy85K1BqRHZKU1p1MXBKVE9BZW8rdFdON2Z5YjlHZDNBSWIyRTBTMVBSc05PM05nM09Uc29yOHVkR3VvcnJ5R2wKK3dTTWl1TGdiV2hPSFY0UFI4Q0RuNkU4alFyQUFwWDJKNmVsaGM1U1ljU2E4TFdyZzkwM3c4YllxT0RHQkRTbmgKK0FNRlJEMHhTK0FSYXFuMXkwN2lIS3J0akVBTXFzNkZQRFZwZVJyYzlEdlYwN0ptZitUMGtnWWltM1dCVTZKVTIKK1BjWUprNXFqRW9BQVZaa1pSNzNRcFh6RHV2c2Y5L1VQK0t5NXRmUTNtQk1ZM29WYnR3eUNPNGR2bFRsWU1OcHUKK0FXZ1hJc3pBQ3dJREFRQUJvMk13WVRBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUE0R0ExVWREd0VCL3dRRUF3SUIKK0JqQWZCZ05WSFNNRUdEQVdnQlFIdzFFd3BLcnBSYTQxSlByL0pDd3owTEdkakRBZEJnTlZIUTRFRmdRVUI4TlIKK01LU3E2VVd1TlNUNi95UXNNOUN4bll3d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFGOCtoblp1dURVOFRqWWMKK0hubVl2LzNWRWhGNVVnN3VNWW04M1gvNTBjWVZJZWlLQVZRTk92dFV1ZFpqMUxHcWxrMmlRazNVVXgrTEVONS8KK1piNWdFeWR4aUtSejQ0UmowYVJWNFZDVDVoc09lZEJudkViSXZ6OFhEWlhteHBCcDN1ZTBMOTZWZmRBU1B6MCsKK2YwMC9GR2oxRVZEVndmU1FwUWdkTVdEL1lJd2pWQXF2L3FGdXhkRjZLbWg0eng2Q0NpQzBINjNsaGJKcWFIVk8KK3JTVTNsSVcrdmFIVTZyY01TenlkNkJJQThGK3NEZUdzY0dOejkzOTVueklsUW5RRmdDaS92Y0VrbGxnVnNSY2gKKzZZbEwyd2VJWi9RVnJYQStMMDJGTzhLMzIvNllhQ09KNFhRUDN2VEZoR01wRzh6TEI4a0FwS25Yd2lKUFo5ZDMKKzdDQUZZZDQ9CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICAwYTowMTowMTowMTowMDowMDowMjo3YzowMDowMDowMDowYTowMDowMDowMDowMgorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBPPVJTQSBTZWN1cml0eSBJbmMsIE9VPVJTQSBTZWN1cml0eSAyMDQ4IFYzCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBGZWIgMjIgMjA6Mzk6MjMgMjAwMSBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEZlYiAyMiAyMDozOToyMyAyMDI2IEdNVAorICAgICAgICBTdWJqZWN0OiBPPVJTQSBTZWN1cml0eSBJbmMsIE9VPVJTQSBTZWN1cml0eSAyMDQ4IFYzCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpiNzo4Zjo1NTo3MTpkMjo4MDpkZDo3Yjo2OTo3OTphNzpmMDoxODo1MDoKKyAgICAgICAgICAgICAgICAgICAgMzI6M2M6NjI6Njc6ZjY6MGE6OTU6MDc6ZGQ6ZTY6MWI6ZjM6OWU6ZDk6ZDI6CisgICAgICAgICAgICAgICAgICAgIDQxOjU0OjZiOmFkOjlmOjdjOmJlOjE5OmNkOmZiOjQ2OmFiOjQxOjY4OjFlOgorICAgICAgICAgICAgICAgICAgICAxODplYTo1NTpjODoyZjo5MTo3ODo4OToyODpmYjoyNzoyOTo2MDpmZjpkZjoKKyAgICAgICAgICAgICAgICAgICAgOGY6OGM6M2I6Yzk6NDk6OWI6YjU6YTQ6OTQ6Y2U6MDE6ZWE6M2U6YjU6NjM6CisgICAgICAgICAgICAgICAgICAgIDdiOjdmOjI2OmZkOjE5OmRkOmMwOjIxOmJkOjg0OmQxOjJkOjRmOjQ2OmMzOgorICAgICAgICAgICAgICAgICAgICA0ZTpkYzpkODozNzozOTozYjoyODphZjpjYjo5ZDoxYTplYToyYjphZjoyMToKKyAgICAgICAgICAgICAgICAgICAgYTU6YzE6MjM6MjI6Yjg6Yjg6MWI6NWE6MTM6ODc6NTc6ODM6ZDE6ZjA6MjA6CisgICAgICAgICAgICAgICAgICAgIGU3OmU4OjRmOjIzOjQyOmIwOjAwOmE1OjdkOjg5OmU5OmU5OjYxOjczOjk0OgorICAgICAgICAgICAgICAgICAgICA5ODo3MToyNjpiYzoyZDo2YTplMDpmNzo0ZDpmMDpmMTpiNjoyYTozODozMToKKyAgICAgICAgICAgICAgICAgICAgODE6MGQ6Mjk6ZTE6MDA6YzE6NTE6MGY6NGM6NTI6Zjg6MDQ6NWE6YWE6N2Q6CisgICAgICAgICAgICAgICAgICAgIDcyOmQzOmI4Ojg3OjJhOmJiOjYzOjEwOjAzOjJhOmIzOmExOjRmOjBkOjVhOgorICAgICAgICAgICAgICAgICAgICA1ZTo0NjpiNzozZDowZTpmNTo3NDplYzo5OTo5ZjpmOTozZDoyNDo4MTo4ODoKKyAgICAgICAgICAgICAgICAgICAgYTY6ZGQ6NjA6NTQ6ZTg6OTU6MzY6M2Q6YzY6MDk6OTM6OWE6YTM6MTI6ODA6CisgICAgICAgICAgICAgICAgICAgIDAwOjU1Ojk5OjE5OjQ3OmJkOmQwOmE1OjdjOmMzOmJhOmZiOjFmOmY3OmY1OgorICAgICAgICAgICAgICAgICAgICAwZjpmODphYzpiOTpiNTpmNDozNzo5ODoxMzoxODpkZTo4NTo1YjpiNzowYzoKKyAgICAgICAgICAgICAgICAgICAgODI6M2I6ODc6NmY6OTU6Mzk6NTg6MzA6ZGE6NmU6MDE6Njg6MTc6MjI6Y2M6CisgICAgICAgICAgICAgICAgICAgIGMwOjBiCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQXV0aG9yaXR5IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBrZXlpZDowNzpDMzo1MTozMDpBNDpBQTpFOTo0NTpBRTozNToyNDpGQTpGRjoyNDoyQzozMzpEMDpCMTo5RDo4QworCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgMDc6QzM6NTE6MzA6QTQ6QUE6RTk6NDU6QUU6MzU6MjQ6RkE6RkY6MjQ6MkM6MzM6RDA6QjE6OUQ6OEMKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgNWY6M2U6ODY6NzY6NmU6Yjg6MzU6M2M6NGU6MzY6MWM6MWU6Nzk6OTg6YmY6ZmQ6ZDU6MTI6CisgICAgICAgIDExOjc5OjUyOjBlOmVlOjMxOjg5OmJjOmRkOjdmOmY5OmQxOmM2OjE1OjIxOmU4OjhhOjAxOgorICAgICAgICA1NDowZDozYTpmYjo1NDpiOTpkNjo2MzpkNDpiMTphYTo5Njo0ZDphMjo0Mjo0ZDpkNDo1MzoKKyAgICAgICAgMWY6OGI6MTA6ZGU6N2Y6NjU6YmU6NjA6MTM6Mjc6NzE6ODg6YTQ6NzM6ZTM6ODQ6NjM6ZDE6CisgICAgICAgIGE0OjU1OmUxOjUwOjkzOmU2OjFiOjBlOjc5OmQwOjY3OmJjOjQ2OmM4OmJmOjNmOjE3OjBkOgorICAgICAgICA5NTplNjpjNjo5MDo2OTpkZTplNzpiNDoyZjpkZTo5NTo3ZDpkMDoxMjozZjozZDozZTo3ZjoKKyAgICAgICAgNGQ6M2Y6MTQ6Njg6ZjU6MTE6NTA6ZDU6YzE6ZjQ6OTA6YTU6MDg6MWQ6MzE6NjA6ZmY6NjA6CisgICAgICAgIDhjOjIzOjU0OjBhOmFmOmZlOmExOjZlOmM1OmQxOjdhOjJhOjY4Ojc4OmNmOjFlOjgyOjBhOgorICAgICAgICAyMDpiNDoxZjphZDplNTo4NTpiMjo2YTo2ODo3NTo0ZTphZDoyNTozNzo5NDo4NTpiZTpiZDoKKyAgICAgICAgYTE6ZDQ6ZWE6Yjc6MGM6NGI6M2M6OWQ6ZTg6MTI6MDA6ZjA6NWY6YWM6MGQ6ZTE6YWM6NzA6CisgICAgICAgIDYzOjczOmY3OjdmOjc5OjlmOjMyOjI1OjQyOjc0OjA1OjgwOjI4OmJmOmJkOmMxOjI0Ojk2OgorICAgICAgICA1ODoxNTpiMToxNzoyMTplOTo4OTo0YjpkYjowNzo4ODo2NzpmNDoxNTphZDo3MDozZToyZjoKKyAgICAgICAgNGQ6ODU6M2I6YzI6Yjc6ZGI6ZmU6OTg6Njg6MjM6ODk6ZTE6NzQ6MGY6ZGU6ZjQ6YzU6ODQ6CisgICAgICAgIDYzOjI5OjFiOmNjOmNiOjA3OmM5OjAwOmE0OmE5OmQ3OmMyOjIyOjRmOjY3OmQ3Ojc3OmVjOgorICAgICAgICAyMDowNTo2MTpkZQorU0hBMSBGaW5nZXJwcmludD0yNTowMTo5MDoxOTpDRjpGQjpEOTo5OToxQzpCNzo2ODoyNTo3NDo4RDo5NDo1RjozMDo5Mzo5NTo0MgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzg0Y2JhODJmLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvODRjYmE4MmYuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNzgwZGVkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzg0Y2JhODJmLjAKQEAgLTAsMCArMSw3NyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEK3pDQ0F1T2dBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUVVGQURDQnR6RS9NRDBHQTFVRUF3dzJWTU9jCitVa3RVVWxWVFZDQkZiR1ZyZEhKdmJtbHJJRk5sY25ScFptbHJZU0JJYVhwdFpYUWdVMkhFbjJ4aGVjU3hZOFN4CitjOFN4TVFzd0NRWURWUVFHREFKVVVqRVBNQTBHQTFVRUJ3d0dRVTVMUVZKQk1WWXdWQVlEVlFRS0RFMG9ZeWtnCitNakF3TlNCVXc1eFNTMVJTVlZOVUlFSnBiR2RwSU1Td2JHVjBhY1dmYVcwZ2RtVWdRbWxzYWNXZmFXMGdSOE84CitkbVZ1YkduRW4ya2dTR2w2YldWMGJHVnlhU0JCTHNXZUxqQWVGdzB3TlRBMU1UTXhNREkzTVRkYUZ3MHhOVEF6CitNakl4TURJM01UZGFNSUczTVQ4d1BRWURWUVFERERaVXc1eFNTMVJTVlZOVUlFVnNaV3QwY205dWFXc2dVMlZ5CitkR2xtYVd0aElFaHBlbTFsZENCVFljU2ZiR0Y1eExGanhMRnp4TEV4Q3pBSkJnTlZCQVlNQWxSU01ROHdEUVlECitWUVFIREFaQlRrdEJVa0V4VmpCVUJnTlZCQW9NVFNoaktTQXlNREExSUZURG5GSkxWRkpWVTFRZ1FtbHNaMmtnCit4TEJzWlhScHhaOXBiU0IyWlNCQ2FXeHB4WjlwYlNCSHc3eDJaVzVzYWNTZmFTQklhWHB0WlhSc1pYSnBJRUV1Cit4WjR1TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF5bElGMW1NRDJCeGYzZEo3CitYZklNWUdGYmF6dDBLM2dOZlVXOUluVG9qQVBCeGhFcVBaVzhxWlN3dTVHWHlHbDhoTVcwa1d4c0UycWtWYTJrCitoZWlWZnJNQXJ3RENCUmoxY0owMmk2N0w1QnVCZjVPSSsycFZ1MzJGa3M2NldKL2JNc1c5WGU4aVNpOUJCMzVKCitZYk9HN0U2bVFXNkV2QVBzOVRzY3lCL0M3cWp1NmhKS2pSVFA4d3JnVURuNUNEWDRFVm10NXlMcVM4b1VCdDVDCit1cktaOHkxVWlCQUc2dUVhUGoxbkgvdk8rM3lDNkJGZFNzRzVGT3BVMldhYmZJbDlCSnBpeWVsU1BKNmM3OUwxCitKdVRtNVJoOGkyN2ZiTXg0VzA5eXNzdGNQNHdGamRGTWpLMlN4K0Y0ZjJWc1NRWlFMSjR5d3RkS3huV0tXVTUxCitiMGRld1FJREFRQUJveEF3RGpBTUJnTlZIUk1FQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUJBUUFWCis5VlgvTjVhQVdTR2svS0VWVENEMjFGL2FBeVQ4ejVBYTlDRUttdTQ2c1dydjcvaGcwVXcyWmtVZDgyWUNkQVI3CitrakNvM2dwMkQrK1ZicjNKTitZYURheUpTRnZNZ3piQzlVWmNXWUpXdE5YK0k3VFlWQnhFcThTbjVSVE9QRUZoCitmRVBtemNTQkNZc2srMVFsMWhhb2xneG5CMit6VUVmakhDUW8zU3FZcEdIKzIrb1NON3dCR2pTRnZXNVA1NUZ5CitCMFNGSGxqS1ZFVGQ5Nnk1eTRraGN0dVB3R2twbHlxanJoZ2pseHhCS290OEtzRjhrT2lwS01EVGtjYXRLSWRBCithTFgvN0tmUzB6Z1luTk45YVYzd3hxVWVKQnVqUi94cEIyam41SnEwN1EraGg0Y0N6b2ZTU0U3aHZQL0w4WEtTCitSR1FESmVyZVcyNmZ5ZkpPck4zSAorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAxICgweDEpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IENOPVRceEMzXHg5Q1JLVFJVU1QgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhXHhDNFx4OUZsYXlceEM0XHhCMWNceEM0XHhCMXNceEM0XHhCMSwgQz1UUiwgTD1BTktBUkEsIE89KGMpIDIwMDUgVFx4QzNceDlDUktUUlVTVCBCaWxnaSBceEM0XHhCMGxldGlceEM1XHg5RmltIHZlIEJpbGlceEM1XHg5RmltIEdceEMzXHhCQ3ZlbmxpXHhDNFx4OUZpIEhpem1ldGxlcmkgQS5ceEM1XHg5RS4KKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IE1heSAxMyAxMDoyNzoxNyAyMDA1IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogTWFyIDIyIDEwOjI3OjE3IDIwMTUgR01UCisgICAgICAgIFN1YmplY3Q6IENOPVRceEMzXHg5Q1JLVFJVU1QgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhXHhDNFx4OUZsYXlceEM0XHhCMWNceEM0XHhCMXNceEM0XHhCMSwgQz1UUiwgTD1BTktBUkEsIE89KGMpIDIwMDUgVFx4QzNceDlDUktUUlVTVCBCaWxnaSBceEM0XHhCMGxldGlceEM1XHg5RmltIHZlIEJpbGlceEM1XHg5RmltIEdceEMzXHhCQ3ZlbmxpXHhDNFx4OUZpIEhpem1ldGxlcmkgQS5ceEM1XHg5RS4KKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmNhOjUyOjA1OmQ2OjYzOjAzOmQ4OjFjOjVmOmRkOmQyOjdiOjVkOmYyOgorICAgICAgICAgICAgICAgICAgICAwYzo2MDo2MTo1Yjo2YjozYjo3NDoyYjo3ODowZDo3ZDo0NTpiZDoyMjo3NDoKKyAgICAgICAgICAgICAgICAgICAgZTg6OGM6MDM6YzE6YzY6MTE6MmE6M2Q6OTU6YmM6YTk6OTQ6YjA6YmI6OTE6CisgICAgICAgICAgICAgICAgICAgIDk3OmM4OjY5OjdjOjg0OmM1OmI0OjkxOjZjOjZjOjEzOjZhOmE0OjU1OmFkOgorICAgICAgICAgICAgICAgICAgICBhNDo4NTplODo5NTo3ZTpiMzowMDphZjowMDpjMjowNToxODpmNTo3MDo5ZDoKKyAgICAgICAgICAgICAgICAgICAgMzY6OGI6YWU6Y2I6ZTQ6MWI6ODE6N2Y6OTM6ODg6ZmI6NmE6NTU6YmI6N2Q6CisgICAgICAgICAgICAgICAgICAgIDg1OjkyOmNlOmJhOjU4OjlmOmRiOjMyOmM1OmJkOjVkOmVmOjIyOjRhOjJmOgorICAgICAgICAgICAgICAgICAgICA0MTowNzo3ZTo0OTo2MTpiMzo4NjplYzo0ZTphNjo0MTo2ZTo4NDpiYzowMzoKKyAgICAgICAgICAgICAgICAgICAgZWM6ZjU6M2I6MWM6Yzg6MWY6YzI6ZWU6YTg6ZWU6ZWE6MTI6NGE6OGQ6MTQ6CisgICAgICAgICAgICAgICAgICAgIGNmOmYzOjBhOmUwOjUwOjM5OmY5OjA4OjM1OmY4OjExOjU5OmFkOmU3OjIyOgorICAgICAgICAgICAgICAgICAgICBlYTo0YjpjYToxNDowNjpkZTo0MjpiYTpiMjo5OTpmMzoyZDo1NDo4ODoxMDoKKyAgICAgICAgICAgICAgICAgICAgMDY6ZWE6ZTE6MWE6M2U6M2Q6Njc6MWY6ZmI6Y2U6ZmI6N2M6ODI6ZTg6MTE6CisgICAgICAgICAgICAgICAgICAgIDVkOjRhOmMxOmI5OjE0OmVhOjU0OmQ5OjY2OjliOjdjOjg5OjdkOjA0OjlhOgorICAgICAgICAgICAgICAgICAgICA2MjpjOTplOTo1MjozYzo5ZTo5YzplZjpkMjpmNToyNjplNDplNjplNToxODoKKyAgICAgICAgICAgICAgICAgICAgN2M6OGI6NmU6ZGY6NmM6Y2M6Nzg6NWI6NGY6NzI6YjI6Y2I6NWM6M2Y6OGM6CisgICAgICAgICAgICAgICAgICAgIDA1OjhkOmQxOjRjOjhjOmFkOjkyOmM3OmUxOjc4OjdmOjY1OjZjOjQ5OjA2OgorICAgICAgICAgICAgICAgICAgICA1MDoyYzo5ZTozMjpjMjpkNzo0YTpjNjo3NTo4YTo1OTo0ZTo3NTo2Zjo0NzoKKyAgICAgICAgICAgICAgICAgICAgNWU6YzEKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiAKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDE1OmY1OjU1OmZmOjM3Ojk2OjgwOjU5OjIxOmE0OmZjOmExOjE1OjRjOjIwOmY2OmQ0OjVmOgorICAgICAgICBkYTowMzoyNDpmYzpjZjo5MDoxYTpmNDoyMTowYTo5YTplZTozYTpiMTo2YTplZjplZjpmODoKKyAgICAgICAgNjA6ZDE6NGM6MzY6NjY6NDU6MWQ6ZjM6NjY6MDI6NzQ6MDQ6N2I6OTI6MzA6YTg6ZGU6MGE6CisgICAgICAgIDc2OjBmOmVmOjk1OjZlOmJkOmM5OjM3OmU2OjFhOjBkOmFjOjg5OjQ4OjViOmNjOjgzOjM2OgorICAgICAgICBjMjpmNTo0Njo1Yzo1OTo4Mjo1NjpiNDpkNTpmZToyMzpiNDpkODo1NDoxYzo0NDphYjpjNDoKKyAgICAgICAgYTc6ZTU6MTQ6Y2U6M2M6NDE6NjE6N2M6NDM6ZTY6Y2Q6YzQ6ODE6MDk6OGI6MjQ6ZmI6NTQ6CisgICAgICAgIDI1OmQ2OjE2OmE4Ojk2OjBjOjY3OjA3OjZmOmIzOjUwOjQ3OmUzOjFjOjI0OjI4OmRkOjJhOgorICAgICAgICA5ODphNDo2MTpmZTpkYjplYToxMjozNzpiYzowMToxYTozNDo4NTpiZDo2ZTo0ZjplNzo5MToKKyAgICAgICAgNzI6MDc6NDQ6ODU6MWU6NTg6Y2E6NTQ6NDQ6ZGQ6Zjc6YWM6Yjk6Y2I6ODk6MjE6NzI6ZGI6CisgICAgICAgIDhmOmMwOjY5OjI5Ojk3OjJhOmEzOmFlOjE4OjIzOjk3OjFjOjQxOjJhOjhiOjdjOjJhOmMxOgorICAgICAgICA3Yzo5MDplODphOToyODpjMDpkMzo5MTpjNjphZDoyODo4Nzo0MDo2ODpiNTpmZjplYzphNzoKKyAgICAgICAgZDI6ZDM6Mzg6MTg6OWM6ZDM6N2Q6Njk6NWQ6ZjA6YzY6YTU6MWU6MjQ6MWI6YTM6NDc6ZmM6CisgICAgICAgIDY5OjA3OjY4OmU3OmU0OjlhOmI0OmVkOjBmOmExOjg3Ojg3OjAyOmNlOjg3OmQyOjQ4OjRlOgorICAgICAgICBlMTpiYzpmZjpjYjpmMTo3Mjo5Mjo0NDo2NDowMzoyNTplYTpkZTo1Yjo2ZTo5ZjpjOTpmMjoKKyAgICAgICAgNGU6YWM6ZGQ6YzcKK1NIQTEgRmluZ2VycHJpbnQ9Nzk6OTg6QTM6MDg6RTE6NEQ6NjU6ODU6RTY6QzI6MUU6MTU6M0E6NzE6OUY6QkE6NUE6RDM6NEE6RDkKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy84NWNkZTI1NC4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzg1Y2RlMjU0LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWU5NzBkZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy84NWNkZTI1NC4wCkBAIC0wLDAgKzEsODAgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRDNUQ0NBc1dnQXdJQkFnSUJBREFOQmdrcWhraUc5dzBCQVFzRkFEQ0JqekVMTUFrR0ExVUVCaE1DVlZNeAorRURBT0JnTlZCQWdUQjBGeWFYcHZibUV4RXpBUkJnTlZCQWNUQ2xOamIzUjBjMlJoYkdVeEpUQWpCZ05WQkFvVAorSEZOMFlYSm1hV1ZzWkNCVVpXTm9ibTlzYjJkcFpYTXNJRWx1WXk0eE1qQXdCZ05WQkFNVEtWTjBZWEptYVdWcworWkNCU2IyOTBJRU5sY25ScFptbGpZWFJsSUVGMWRHaHZjbWwwZVNBdElFY3lNQjRYRFRBNU1Ea3dNVEF3TURBdworTUZvWERUTTNNVEl6TVRJek5UazFPVm93Z1k4eEN6QUpCZ05WQkFZVEFsVlRNUkF3RGdZRFZRUUlFd2RCY21sNgorYjI1aE1STXdFUVlEVlFRSEV3cFRZMjkwZEhOa1lXeGxNU1V3SXdZRFZRUUtFeHhUZEdGeVptbGxiR1FnVkdWagorYUc1dmJHOW5hV1Z6TENCSmJtTXVNVEl3TUFZRFZRUURFeWxUZEdGeVptbGxiR1FnVW05dmRDQkRaWEowYVdacAorWTJGMFpTQkJkWFJvYjNKcGRIa2dMU0JITWpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQworZ2dFQkFMM3R3UVA4OW8vOEFyRnZXNTlJMloxNTRxSzNBMkZXR01OSHR0ZktQVFV1aVVQM29XbWIzb29hL1JNZworbkxSSmR6SXBWdjI1N0l6ZEl2cHkzQ2RobCs3MldvVHNiaG01aVN6Y2hGdlZkUHRyWDhXSnBSQlNpVVpWOUxoMQorSE9aLzVGU3VTL2hWY2xjQ0dmZ1hjVm5ySGlnSGRNV2RTTDVzdFBTa3NQTmtOM21Td094R1huL2hiVk5NWXEvTgorSHd0anV6cWQrL3g1QUpoaGRNOG1na0JqODdKeWFoa05tY3JVRG5YTU4vdUxpY0ZaOFdKL1g3TmZaVEQ0cDdkTgorZGxvZWRsNDB3T2lXVnBtS3MvQi9wTTI5M0RJeGZKSFA0RjhSK0d1cVNWelJtWlRSb3VOald3bDJ0VlppNFV0MAorSFpiVUp0UUlCRm5RbUE0TzV0Nzh3K3dma1BFQ0F3RUFBYU5DTUVBd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBTworQmdOVkhROEJBZjhFQkFNQ0FRWXdIUVlEVlIwT0JCWUVGSHdNTWgrbjJUQi94SDFvbzJLb29jNnJCMXNuTUEwRworQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUFSV2ZvbFR3TnZsSms3bWgrQ2hUblVkZ1dVWHVFb2syMWlYUW5Db0tqVQorc0hVNDhUUnFuZVNmaW9ZbVVlWXMwY1l0YnBVZ1NwSUI3TGlLWjNzeDRtY3VqSlVESmk1RG5Vb3g5ZzYxREx1MworNGpkL0lyb0FvdzU3VXZ0cnV6dkUwM2xSVHMyUTlHY0hHY2c4Um5vTkFYM0ZXT2R0NW9Vd0Y1b2t4QkRnQlBmZworOG4vVXFnci9RaDAzN1pUbFpGa1NJSGM0MHpJK09JRjFsblA2YUkreHk4NGZ4ZXo2bkg3UGZySHhCeTIyL0wvSworcEwvUWx3Vkt2T29ZS0FLUXZWUjRDU0Z4MDlGOUhka1dzS2xoUGRBS0FDTDh4M3ZMQ1dSRkN6dEFnZmQ5ZkRMMQorbU1wWWpuMHE3cEJaYzJUNU5uUmVKYUgxWmdVdWZ6a1ZxU3I3VUl1T2hXbjAKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMCAoMHgwKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9VVMsIFNUPUFyaXpvbmEsIEw9U2NvdHRzZGFsZSwgTz1TdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuLCBDTj1TdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMgorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogU2VwICAxIDAwOjAwOjAwIDIwMDkgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBEZWMgMzEgMjM6NTk6NTkgMjAzNyBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgU1Q9QXJpem9uYSwgTD1TY290dHNkYWxlLCBPPVN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4sIENOPVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpiZDplZDpjMTowMzpmYzpmNjo4ZjpmYzowMjpiMTo2Zjo1Yjo5Zjo0ODoKKyAgICAgICAgICAgICAgICAgICAgZDk6OWQ6Nzk6ZTI6YTI6Yjc6MDM6NjE6NTY6MTg6YzM6NDc6YjY6ZDc6Y2E6CisgICAgICAgICAgICAgICAgICAgIDNkOjM1OjJlOjg5OjQzOmY3OmExOjY5OjliOmRlOjhhOjFhOmZkOjEzOjIwOgorICAgICAgICAgICAgICAgICAgICA5YzpiNDo0OTo3NzozMjoyOTo1NjpmZDpiOTplYzo4YzpkZDoyMjpmYTo3MjoKKyAgICAgICAgICAgICAgICAgICAgZGM6Mjc6NjE6OTc6ZWU6ZjY6NWE6ODQ6ZWM6NmU6MTk6Yjk6ODk6MmM6ZGM6CisgICAgICAgICAgICAgICAgICAgIDg0OjViOmQ1Ojc0OmZiOjZiOjVmOmM1Ojg5OmE1OjEwOjUyOjg5OjQ2OjU1OgorICAgICAgICAgICAgICAgICAgICBmNDpiODo3NToxYzplNjo3ZjplNDo1NDphZTo0YjpmODo1NTo3Mjo1NzowMjoKKyAgICAgICAgICAgICAgICAgICAgMTk6Zjg6MTc6NzE6NTk6ZWI6MWU6Mjg6MDc6NzQ6YzU6OWQ6NDg6YmU6NmM6CisgICAgICAgICAgICAgICAgICAgIGI0OmY0OmE0OmIwOmYzOjY0OjM3Ojc5OjkyOmMwOmVjOjQ2OjVlOjdmOmUxOgorICAgICAgICAgICAgICAgICAgICA2ZDo1Mzo0Yzo2MjphZjpjZDoxZjowYjo2MzpiYjozYTo5ZDpmYjpmYzo3OToKKyAgICAgICAgICAgICAgICAgICAgMDA6OTg6NjE6NzQ6Y2Y6MjY6ODI6NDA6NjM6ZjM6YjI6NzI6NmE6MTk6MGQ6CisgICAgICAgICAgICAgICAgICAgIDk5OmNhOmQ0OjBlOjc1OmNjOjM3OmZiOjhiOjg5OmMxOjU5OmYxOjYyOjdmOgorICAgICAgICAgICAgICAgICAgICA1ZjpiMzo1Zjo2NTozMDpmODphNzpiNzo0ZDo3Njo1YToxZTo3Njo1ZTozNDoKKyAgICAgICAgICAgICAgICAgICAgYzA6ZTg6OTY6NTY6OTk6OGE6YjM6ZjA6N2Y6YTQ6Y2Q6YmQ6ZGM6MzI6MzE6CisgICAgICAgICAgICAgICAgICAgIDdjOjkxOmNmOmUwOjVmOjExOmY4OjZiOmFhOjQ5OjVjOmQxOjk5Ojk0OmQxOgorICAgICAgICAgICAgICAgICAgICBhMjplMzo2Mzo1YjowOTo3NjpiNTo1Njo2MjplMTo0Yjo3NDoxZDo5NjpkNDoKKyAgICAgICAgICAgICAgICAgICAgMjY6ZDQ6MDg6MDQ6NTk6ZDA6OTg6MGU6MGU6ZTY6ZGU6ZmM6YzM6ZWM6MWY6CisgICAgICAgICAgICAgICAgICAgIDkwOmYxCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgN0M6MEM6MzI6MUY6QTc6RDk6MzA6N0Y6QzQ6N0Q6Njg6QTM6NjI6QTg6QTE6Q0U6QUI6MDc6NUI6MjcKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAxMTo1OTpmYToyNTo0ZjowMzo2Zjo5NDo5OTozYjo5YToxZjo4Mjo4NTozOTpkNDo3NjowNToKKyAgICAgICAgOTQ6NWU6ZTE6Mjg6OTM6NmQ6NjI6NWQ6MDk6YzI6YTA6YTg6ZDQ6YjA6NzU6Mzg6ZjE6MzQ6CisgICAgICAgIDZhOjlkOmU0OjlmOjhhOjg2OjI2OjUxOmU2OjJjOmQxOmM2OjJkOjZlOjk1OjIwOjRhOjkyOgorICAgICAgICAwMTplYzpiODo4YTo2Nzo3YjozMTplMjo2NzoyZTo4Yzo5NTowMzoyNjoyZTo0Mzo5ZDo0YToKKyAgICAgICAgMzE6ZjY6MGU6YjU6MGM6YmI6Yjc6ZTI6Mzc6N2Y6MjI6YmE6MDA6YTM6MGU6N2I6NTI6ZmI6CisgICAgICAgIDZiOmJiOjNiOmM0OmQzOjc5OjUxOjRlOmNkOjkwOmY0OjY3OjA3OjE5OmM4OjNjOjQ2OjdhOgorICAgICAgICAwZDowMTo3ZDpjNTo1ODplNzo2ZDplNjo4NTozMDoxNzo5YToyNDpjNDoxMDplMDowNDpmNzoKKyAgICAgICAgZTA6ZjI6N2Y6ZDQ6YWE6MGE6ZmY6NDI6MWQ6Mzc6ZWQ6OTQ6ZTU6NjQ6NTk6MTI6MjA6Nzc6CisgICAgICAgIDM4OmQzOjMyOjNlOjM4OjgxOjc1Ojk2OjczOmZhOjY4OjhmOmIxOmNiOmNlOjFmOmM1OmVjOgorICAgICAgICBmYTo5Yzo3ZTpjZjo3ZTpiMTpmMTowNzoyZDpiNjpmYzpiZjpjYTphNDpiZjpkMDo5NzowNToKKyAgICAgICAgNGE6YmM6ZWE6MTg6Mjg6MDI6OTA6YmQ6NTQ6Nzg6MDk6MjE6NzE6ZDM6ZDE6N2Q6MWQ6ZDk6CisgICAgICAgIDE2OmIwOmE5OjYxOjNkOmQwOjBhOjAwOjIyOmZjOmM3OjdiOmNiOjA5OjY0OjQ1OjBiOjNiOgorICAgICAgICA0MDo4MTpmNzo3ZDo3YzozMjpmNTo5ODpjYTo1ODo4ZTo3ZDoyYTplZTo5MDo1OTo3Mzo2NDoKKyAgICAgICAgZjk6MzY6NzQ6NWU6MjU6YTE6ZjU6NjY6MDU6MmU6N2Y6Mzk6MTU6YTk6MmE6ZmI6NTA6OGI6CisgICAgICAgIDhlOjg1OjY5OmY0CitTSEExIEZpbmdlcnByaW50PUI1OjFDOjA2OjdDOkVFOjJCOjBDOjNEOkY4OjU1OkFCOjJEOjkyOkY0OkZFOjM5OkQ0OkU3OjBGOjBFCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvODYyMTJiMTkuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy84NjIxMmIxOS4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU4YTllNTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvODYyMTJiMTkuMApAQCAtMCwwICsxLDc4IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSURURENDQWpTZ0F3SUJBZ0lJZkU4RU9SelVtUzB3RFFZSktvWklodmNOQVFFRkJRQXdSREVMTUFrR0ExVUUKK0JoTUNWVk14RkRBU0JnTlZCQW9NQzBGbVptbHliVlJ5ZFhOME1SOHdIUVlEVlFRRERCWkJabVpwY20xVWNuVnoKK2RDQk9aWFIzYjNKcmFXNW5NQjRYRFRFd01ERXlPVEUwTURneU5Gb1hEVE13TVRJek1URTBNRGd5TkZvd1JERUwKK01Ba0dBMVVFQmhNQ1ZWTXhGREFTQmdOVkJBb01DMEZtWm1seWJWUnlkWE4wTVI4d0hRWURWUVFEREJaQlptWnAKK2NtMVVjblZ6ZENCT1pYUjNiM0pyYVc1bk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0MKK0FRRUF0SVRNTXhjdWE1UnNhMkZTb091anozbVVUT1dVZ0puTFZXUkVaWTluWk9JRzQxdzNTZll2bTRTRUhpM3kKK1lKMHdUc3lFaGVJc3p4NmUvamFyTTNjMVJOZzFsaG85TnVoNkR0alZSNkZxYVl2Wi9MczZybmxhMWZUV2NidWEKK2tDTnJtcmVJZEljTUhsKzVuaTM2cTFNcjNMdDJQcE5NQ0FpTUhxSWpITlJxclNLNm1RRXViV1hMdmlSbVZTUkwKK1FFU3hHOWZod29YQTNoQS9QZTI0L1BIeEkxUGN2MldYYjluNVFIR05mYjJWMU02K29GNG5JOTc5cHRBbURnQXAKKzZ6eEc4RDFndno5UTB0d21RVkdlRkRkQ0JLTndWNmdiaCswdCtudnVqQXJqcVdhSkdjdEIrZDFFTm1IUDRuZEcKK3lIMzI5SktCTnYzYk5QRnlmdk1NRnIyMEZRSURBUUFCbzBJd1FEQWRCZ05WSFE0RUZnUVVCeC9TNTV6YXdtNmkKK1FMU3dlbEFRVUhURXlMMHdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QU9CZ05WSFE4QkFmOEVCQU1DQVFZd0RRWUoKK0tvWklodmNOQVFFRkJRQURnZ0VCQUlsWHNoWjZxTUw5MXRtYm16VENuTFF5RkUybnBOL3N2cWUrK0VQYmtUZk8KK3RESXVVRlVhTlU1MlEzRWc3NU4zVGhWd0xvZkR3UjF0M011MUo5UXNWdEZTVXpwRTBuUEl4QnNGWlZwaWtwenUKK1FZMHgyK2MwNmxraDFRRjYxMlM0WkRuTnllMnY3VXNEU0tlZ21RR0EzR1dqTnE1bFdVaFBna3ZJWmZGWEhlVloKK0xnby9iTmpSOWVVSnRHeFVBQXJnRlUySGRXMjNXSlphM1czU0FLRDBtMGkrd3pla3VqYmdmSWVGbHhvVm90NHUKK29sdTlyeGo1a0ZETmNGbjRKMmRIeThlZ0J6cDkwU3hkYkJrNlpyVjkvWkZ2Z3JHK0NKUGJGRWZ4b2pmSFJaNDgKK3gzZXZaS2lUMy9acGc0Smc4a2xDTk8xYUFGU0ZIQlkya2d4YytxYXR2OXM9CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICA3Yzo0ZjowNDozOToxYzpkNDo5OToyZAorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPUFmZmlybVRydXN0LCBDTj1BZmZpcm1UcnVzdCBOZXR3b3JraW5nCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBKYW4gMjkgMTQ6MDg6MjQgMjAxMCBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IERlYyAzMSAxNDowODoyNCAyMDMwIEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPUFmZmlybVRydXN0LCBDTj1BZmZpcm1UcnVzdCBOZXR3b3JraW5nCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpiNDo4NDpjYzozMzoxNzoyZTo2Yjo5NDo2Yzo2Yjo2MTo1MjphMDplYjoKKyAgICAgICAgICAgICAgICAgICAgYTM6Y2Y6Nzk6OTQ6NGM6ZTU6OTQ6ODA6OTk6Y2I6NTU6NjQ6NDQ6NjU6OGY6CisgICAgICAgICAgICAgICAgICAgIDY3OjY0OmUyOjA2OmUzOjVjOjM3OjQ5OmY2OjJmOjliOjg0Ojg0OjFlOjJkOgorICAgICAgICAgICAgICAgICAgICBmMjo2MDo5ZDozMDo0ZTpjYzo4NDo4NTplMjoyYzpjZjoxZTo5ZTpmZTozNjoKKyAgICAgICAgICAgICAgICAgICAgYWI6MzM6Nzc6MzU6NDQ6ZDg6MzU6OTY6MWE6M2Q6MzY6ZTg6N2E6MGU6ZDg6CisgICAgICAgICAgICAgICAgICAgIGQ1OjQ3OmExOjZhOjY5OjhiOmQ5OmZjOmJiOjNhOmFlOjc5OjVhOmQ1OmY0OgorICAgICAgICAgICAgICAgICAgICBkNjo3MTpiYjo5YTo5MDoyMzo2Yjo5YTpiNzo4ODo3NDo4NzowYzoxZTo1ZjoKKyAgICAgICAgICAgICAgICAgICAgYjk6OWU6MmQ6ZmE6YWI6NTM6MmI6ZGM6YmI6NzY6M2U6OTM6NGM6MDg6MDg6CisgICAgICAgICAgICAgICAgICAgIDhjOjFlOmEyOjIzOjFjOmQ0OjZhOmFkOjIyOmJhOjk5OjAxOjJlOjZkOjY1OgorICAgICAgICAgICAgICAgICAgICBjYjpiZToyNDo2Njo1NToyNDo0Yjo0MDo0NDpiMToxYjpkNzplMTpjMjo4NToKKyAgICAgICAgICAgICAgICAgICAgYzA6ZGU6MTA6M2Y6M2Q6ZWQ6Yjg6ZmM6ZjE6ZjE6MjM6NTM6ZGM6YmY6NjU6CisgICAgICAgICAgICAgICAgICAgIDk3OjZmOmQ5OmY5OjQwOjcxOjhkOjdkOmJkOjk1OmQ0OmNlOmJlOmEwOjVlOgorICAgICAgICAgICAgICAgICAgICAyNzoyMzpkZTpmZDphNjpkMDoyNjowZTowMDoyOTplYjozYzo0NjpmMDozZDoKKyAgICAgICAgICAgICAgICAgICAgNjA6YmY6M2Y6NTA6ZDI6ZGM6MjY6NDE6NTE6OWU6MTQ6Mzc6NDI6MDQ6YTM6CisgICAgICAgICAgICAgICAgICAgIDcwOjU3OmE4OjFiOjg3OmVkOjJkOmZhOjdiOmVlOjhjOjBhOmUzOmE5OjY2OgorICAgICAgICAgICAgICAgICAgICA4OToxOTpjYjo0MTpmOTpkZDo0NDozNjo2MTpjZjplMjo3Nzo0NjpjODo3ZDoKKyAgICAgICAgICAgICAgICAgICAgZjY6ZjQ6OTI6ODE6MzY6ZmQ6ZGI6MzQ6ZjE6NzI6N2U6ZjM6MGM6MTY6YmQ6CisgICAgICAgICAgICAgICAgICAgIGI0OjE1CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICAwNzoxRjpEMjpFNzo5QzpEQTpDMjo2RTpBMjo0MDpCNDpCMDo3QTo1MDoxMDo1MDo3NDpDNDpDODpCRAorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgODk6NTc6YjI6MTY6N2E6YTg6YzI6ZmQ6ZDY6ZDk6OWI6OWI6MzQ6YzI6OWM6YjQ6MzI6MTQ6CisgICAgICAgIDRkOmE3OmE0OmRmOmVjOmJlOmE3OmJlOmY4OjQzOmRiOjkxOjM3OmNlOmI0OjMyOjJlOjUwOgorICAgICAgICA1NToxYTozNTo0ZTo3Njo0Mzo3MToyMDplZjo5Mzo3Nzo0ZToxNTo3MDoyZTo4NzpjMzpjMToKKyAgICAgICAgMWQ6NmQ6ZGM6Y2I6YjU6Mjc6ZDQ6MmM6NTY6ZDE6NTI6NTM6M2E6NDQ6ZDI6NzM6Yzg6YzQ6CisgICAgICAgIDFiOjA1OjY1OjVhOjYyOjkyOjljOmVlOjQxOjhkOjMxOmRiOmU3OjM0OmVhOjU5OjIxOmQ1OgorICAgICAgICAwMTo3YTpkNzo2NDpiODo2NDozOTpjZDpjOTplZDphZjplZDo0YjowMzo0ODphNzphMDo5OToKKyAgICAgICAgMDE6ODA6ZGM6NjU6YTM6MzY6YWU6NjU6NTk6NDg6NGY6ODI6NGI6Yzg6NjU6ZjE6NTc6MWQ6CisgICAgICAgIGU1OjU5OjJlOjBhOjNmOjZjOmQ4OmQxOmY1OmU1OjA5OmI0OjZjOjU0OjAwOjBhOmUwOjE1OgorICAgICAgICA0ZDo4Nzo3NTo2ZDpiNzo1ODo5Njo1YTpkZDo2ZDpkMjowMDphMDpmNDo5Yjo0ODpiZTpjMzoKKyAgICAgICAgMzc6YTQ6YmE6MzY6ZTA6N2M6ODc6ODU6OTc6MWE6MTU6YTI6ZGU6MmU6YTI6NWI6YmQ6YWY6CisgICAgICAgIDE4OmY5OjkwOjUwOmNkOjcwOjU5OmY4OjI3OjY3OjQ3OmNiOmM3OmEwOjA3OjNhOjdkOmQxOgorICAgICAgICAyYzo1ZDo2YzoxOTozYTo2NjpiNTo3ZDpmZDo5MTo2Zjo4MjpiMTpiZTowODo5MzpkYjoxNDoKKyAgICAgICAgNDc6ZjE6YTI6Mzc6Yzc6NDU6OWU6M2M6Yzc6Nzc6YWY6NjQ6YTg6OTM6ZGY6ZjY6Njk6ODM6CisgICAgICAgIDgyOjYwOmYyOjQ5OjQyOjM0OmVkOjVhOjAwOjU0Ojg1OjFjOjE2OjM2OjkyOjBjOjVjOmZhOgorICAgICAgICBhNjphZDpiZjpkYgorU0hBMSBGaW5nZXJwcmludD0yOTozNjoyMTowMjo4QjoyMDpFRDowMjpGNTo2NjpDNTozMjpEMTpENjpFRDo5MDo5Rjo0NTowMDoyRgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzg3NzUzYjBkLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvODc3NTNiMGQuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYjAwNzI2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzg3NzUzYjBkLjAKQEAgLTAsMCArMSwxMjIgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRmJEQ0NBMVNnQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFVRkFEQkhNUXN3Q1FZRFZRUUdFd0pWVXpFVworTUJRR0ExVUVDaE1OUjJWdlZISjFjM1FnU1c1akxqRWdNQjRHQTFVRUF4TVhSMlZ2VkhKMWMzUWdWVzVwZG1WeQorYzJGc0lFTkJJREl3SGhjTk1EUXdNekEwTURVd01EQXdXaGNOTWprd016QTBNRFV3TURBd1dqQkhNUXN3Q1FZRAorVlFRR0V3SlZVekVXTUJRR0ExVUVDaE1OUjJWdlZISjFjM1FnU1c1akxqRWdNQjRHQTFVRUF4TVhSMlZ2VkhKMQorYzNRZ1ZXNXBkbVZ5YzJGc0lFTkJJREl3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQworQVFDelZGTEJ5VDd5MmR5eFV4cFpLZWV4dzBVbzVkZlI3Y1hGUzZHcWRIdFhyMG9tL05qMVhxZHVHZHQwREU4MQorV3pJTEFlUGI2M3AzTmVxcVd1RFc2S0ZYbFBDUW8zUldsRVF3QXg1Y1RpdUZKblNDZWd4Mm9HOU56a0V0b0JVRworRkYrM1FzMTdqMWhoTk53cUNQa3V3d0dtSWtRY1RBZUM1bHZPMEVwOEJOTVpjeWZ3cXBoL0xxOU82NGNlSkhkcQorWGJib1cwVzYzTU9oQlc5V2pvOFFKcVZKd3k3WFFZY2k0RStHeW1DMTZxRmp3QUdYRUhtOUFEd1NiU3NWc2F4TAorc2U0WXVVNlczTngyL3p1K3oxOER3UHc3Nkw1R0cvL2FRTUpTOS83ak92ZHFkelhRMm8zclhoaHFNY2NldWp3YgorS05aclZNYXFXOWVpTEJzWnpLSUM5cHRadlRkcmhyVnRncnJZNnNsV3ZLazJXUDArR2ZQdERDYXBremo0VDhGZAorSWdiUWwrcmhyY1pWNElFcktJTTYrdlI3SVZFQXZsSTR6czFtZWFqMGdWYmkwSU1KUjFGYlVHclAyMGdhWFQ3MworeS9abDkyenhsZmdDT3pKV2dqbDZXNzB2aVJ1L29iVG8vMytOak44RDhXQk9XQkZNNjZNL0VDdURtZ0Z6MlpSdAoraEFBblpxendjRUFKUXBLdFQ1TU5ZUWxSSk5pUzFRdVVZYktIc3UzL21qWC9oVlRLN1VSRHJCczhGbXRJU2dvYworUUlnZmtzSUxBQVgvOHNnQ1NxU3FxY3labHB3dldPQjk0YjY3Qjl4ZkJISmNNVFREN0Y4dDREMWtrQ0xtMGV5NAorTHQxWnJ0bWhONzlVTmR4ek1rK01CQjR6c3NsRzhkaGN5RlZReVdpOXFMbzJDUUlEQVFBQm8yTXdZVEFQQmdOVgorSFJNQkFmOEVCVEFEQVFIL01CMEdBMVVkRGdRV0JCUjI4MVhoK3FRMisvQ2ZYR0p4N1R6MFJ6Z1FLekFmQmdOVgorSFNNRUdEQVdnQlIyODFYaCtxUTIrL0NmWEdKeDdUejBSemdRS3pBT0JnTlZIUThCQWY4RUJBTUNBWVl3RFFZSgorS29aSWh2Y05BUUVGQlFBRGdnSUJBR2JCeGlQejJlQXVibC9vejY2d3NDVk5LL2c3V0p0QUpEZGF5NnNXU2YregorZFhrem9TOXRjQmMwa2Y1bmZvL3NtK1ZlZ3FsVkh5L2MxRkVIRXY2c0ZqNHNOY1pqL053UTZ3MmpxdEI4ek5IUQorTDFFdXhCUmEzdWdaNFQ3R3pLUXA1eTZFcWdZd2VIWlVjeWlZV1RqZ0FBMWkwMEo5SVordVBUcU0xZnAzRFJncgorRmc1Zk51SDhLclV3Sk0vZ1l3eDdXQnIrbWJwQ0VyR1I5SHhvNHNqb3J5enF5WDZ1dXlvOURSWGNOSlcyR0hTbworYWcvSHRQUVR4T1JiN1FyU3BKZE1LdTB2YkJLSlBmRW5jS3BxQTFJaG4wQ29aMUR5ODFvZjM5OGo5dHg0VHVhWQorVDFVNlUrUHY4dlNmeDN6WVdLOHBJcGU0NEwyUkxyQjI3RmNSeis4cFJQUHBoWHBnWStSZE00a1gyVEdxMnRiegorR0RWeXo0Y3JMMk1qaEYyRWpEOVhvSWo4bVpFb0ptbVoxSStYUkw2TzFVaXhwQ2dwOFJXMDRlV2UzZmlQcG04bQorMXdrOE9od1JEcVpzTi9ldFJJY3NLTWZZZElLejBHOUtWN3MxS1NlZ2krZ2hwNGRrTmwzTTJCYXN4N0luUUpKVgorT0NpTlVXN2RGR2RUYkhGY0pvUk5kVnEyZm1CV3FVMnQrNXNlbC9NTjJkS1hWSGZhUFJLMzRCN3ZDQWFzK1lXSAorNmFMY3IzNFlFb1A5VmhkQkx0VXBnbjJaOURIMmNhblBMQUVucFFXNXFySklUaXJ2bjVOU1VaVThVbk9PVmt3WAorUU1BSktPU0xha2hUMit6TlZWWHh4dmpwb2l4TXB0RW1YMzZ2V2t6YUg2YnlIQ3grcmdJVzBsYlFMMWRUUitpUworLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAxICgweDEpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9VVMsIE89R2VvVHJ1c3QgSW5jLiwgQ049R2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IE1hciAgNCAwNTowMDowMCAyMDA0IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogTWFyICA0IDA1OjAwOjAwIDIwMjkgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89R2VvVHJ1c3QgSW5jLiwgQ049R2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICg0MDk2IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICg0MDk2IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmIzOjU0OjUyOmMxOmM5OjNlOmYyOmQ5OmRjOmIxOjUzOjFhOjU5OjI5OgorICAgICAgICAgICAgICAgICAgICBlNzpiMTpjMzo0NToyODplNTpkNzpkMTplZDpjNTpjNTo0YjphMTphYTo3NDoKKyAgICAgICAgICAgICAgICAgICAgN2I6NTc6YWY6NGE6MjY6ZmM6ZDg6ZjU6NWU6YTc6NmU6MTk6ZGI6NzQ6MGM6CisgICAgICAgICAgICAgICAgICAgIDRmOjM1OjViOjMyOjBiOjAxOmUzOmRiOmViOjdhOjc3OjM1OmVhOmFhOjVhOgorICAgICAgICAgICAgICAgICAgICBlMDpkNjplODphMTo1Nzo5NDpmMDo5MDphMzo3NDo1Njo5NDo0NDozMDowMzoKKyAgICAgICAgICAgICAgICAgICAgMWU6NWM6NGU6MmI6ODU6MjY6NzQ6ODI6N2E6MGM6NzY6YTA6NmY6NGQ6Y2U6CisgICAgICAgICAgICAgICAgICAgIDQxOjJkOmEwOjE1OjA2OjE0OjVmOmI3OjQyOmNkOjdiOjhmOjU4OjYxOjM0OgorICAgICAgICAgICAgICAgICAgICBkYzoyYTowODpmOToyZTpjMzowMTphNjoyMjo0NDoxYzo0YzowNzo4MjplNjoKKyAgICAgICAgICAgICAgICAgICAgNWI6Y2U6ZDA6NGE6N2M6MDQ6ZDM6MTk6NzM6Mjc6ZjA6YWE6OTg6N2Y6MmU6CisgICAgICAgICAgICAgICAgICAgIGFmOjRlOmViOjg3OjFlOjI0Ojc3OjZhOjVkOmI2OmU4OjViOjQ1OmJhOmRjOgorICAgICAgICAgICAgICAgICAgICBjMzphMTowNTo2Zjo1Njo4ZTo4ZjoxMDoyNjphNTo0OTpjMzoyZTpkNzo0MToKKyAgICAgICAgICAgICAgICAgICAgODc6MjI6ZTA6NGY6ODY6Y2E6NjA6YjU6ZWE6YTE6NjM6YzA6MDE6OTc6MTA6CisgICAgICAgICAgICAgICAgICAgIDc5OmJkOjAwOjNjOjEyOjZkOjJiOjE1OmIxOmFjOjRiOmIxOmVlOjE4OmI5OgorICAgICAgICAgICAgICAgICAgICA0ZTo5NjpkYzpkYzo3NjpmZjozYjpiZTpjZjo1ZjowMzpjMDpmYzozYjplODoKKyAgICAgICAgICAgICAgICAgICAgYmU6NDY6MWI6ZmY6ZGE6NDA6YzI6NTI6Zjc6ZmU6ZTM6M2E6Zjc6NmE6Nzc6CisgICAgICAgICAgICAgICAgICAgIDM1OmQwOmRhOjhkOmViOjVlOjE4OjZhOjMxOmM3OjFlOmJhOjNjOjFiOjI4OgorICAgICAgICAgICAgICAgICAgICBkNjo2Yjo1NDpjNjphYTo1YjpkNzphMjoyYzoxYjoxOTpjYzphMjowMjpmNjoKKyAgICAgICAgICAgICAgICAgICAgOWI6NTk6YmQ6Mzc6NmI6ODY6YjU6NmQ6ODI6YmE6ZDg6ZWE6Yzk6NTY6YmM6CisgICAgICAgICAgICAgICAgICAgIGE5OjM2OjU4OmZkOjNlOjE5OmYzOmVkOjBjOjI2OmE5OjkzOjM4OmY4OjRmOgorICAgICAgICAgICAgICAgICAgICBjMTo1ZDoyMjowNjpkMDo5NzplYTplMTphZDpjNjo1NTplMDo4MToyYjoyODoKKyAgICAgICAgICAgICAgICAgICAgODM6M2E6ZmE6ZjQ6N2I6MjE6NTE6MDA6YmU6NTI6Mzg6Y2U6Y2Q6NjY6Nzk6CisgICAgICAgICAgICAgICAgICAgIGE4OmY0OjgxOjU2OmUyOmQwOjgzOjA5OjQ3OjUxOjViOjUwOjZhOmNmOmRiOgorICAgICAgICAgICAgICAgICAgICA0ODoxYTo1ZDozZTpmNzpjYjpmNjo2NTpmNzo2YzpmMTo5NTpmODowMjozYjoKKyAgICAgICAgICAgICAgICAgICAgMzI6NTY6ODI6Mzk6N2E6NWI6YmQ6MmY6ODk6MWI6YmY6YTE6YjQ6ZTg6ZmY6CisgICAgICAgICAgICAgICAgICAgIDdmOjhkOjhjOmRmOjAzOmYxOjYwOjRlOjU4OjExOjRjOmViOmEzOjNmOjEwOgorICAgICAgICAgICAgICAgICAgICAyYjo4Mzo5YTowMTo3MzpkOTo5NDo2ZDo4NDowMDoyNzo2NjphYzpmMDo3MDoKKyAgICAgICAgICAgICAgICAgICAgNDA6MDk6NDI6OTI6YWQ6NGY6OTM6MGQ6NjE6MDk6NTE6MjQ6ZDg6OTI6ZDU6CisgICAgICAgICAgICAgICAgICAgIDBiOjk0OjYxOmIyOjg3OmIyOmVkOmZmOjlhOjM1OmZmOjg1OjU0OmNhOmVkOgorICAgICAgICAgICAgICAgICAgICA0NDo0MzphYzoxYjozYzoxNjo2Yjo0ODo0YTowYToxYzo0MDo4ODoxZjo5MjoKKyAgICAgICAgICAgICAgICAgICAgYzI6MGI6MDA6MDU6ZmY6ZjI6Yzg6MDI6NGE6YTQ6YWE6YTk6Y2M6OTk6OTY6CisgICAgICAgICAgICAgICAgICAgIDljOjJmOjU4OmUwOjdkOmUxOmJlOmJiOjA3OmRjOjVmOjA0OjcyOjVjOjMxOgorICAgICAgICAgICAgICAgICAgICAzNDpjMzplYzo1ZjoyZDplMDozZDo2NDo5MDoyMjplNjpkMTplYzpiODoyZToKKyAgICAgICAgICAgICAgICAgICAgZGQ6NTk6YWU6ZDk6YTE6Mzc6YmY6NTQ6MzU6ZGM6NzM6MzI6NGY6OGM6MDQ6CisgICAgICAgICAgICAgICAgICAgIDFlOjMzOmIyOmM5OjQ2OmYxOmQ4OjVjOmM4OjU1OjUwOmM5OjY4OmJkOmE4OgorICAgICAgICAgICAgICAgICAgICBiYTozNjowOQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDc2OkYzOjU1OkUxOkZBOkE0OjM2OkZCOkYwOjlGOjVDOjYyOjcxOkVEOjNDOkY0OjQ3OjM4OjEwOjJCCisgICAgICAgICAgICBYNTA5djMgQXV0aG9yaXR5IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBrZXlpZDo3NjpGMzo1NTpFMTpGQTpBNDozNjpGQjpGMDo5Rjo1Qzo2Mjo3MTpFRDozQzpGNDo0NzozODoxMDoyQgorCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIERpZ2l0YWwgU2lnbmF0dXJlLCBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA2NjpjMTpjNjoyMzpmMzpkOTplMDoyZTo2ZTo1ZjplODpjZjphZTpiMDpiMDoyNTo0ZDoyYjoKKyAgICAgICAgZjg6M2I6NTg6OWI6NDA6MjQ6Mzc6NWE6Y2I6YWI6MTY6NDk6ZmY6YjM6NzU6Nzk6MzM6YTE6CisgICAgICAgIDJmOjZkOjcwOjE3OjM0OjkxOmZlOjY3OjdlOjhmOmVjOjliOmU1OjVlOjgyOmE5OjU1OjFmOgorICAgICAgICAyZjpkYzpkNDo1MTowNzoxMjpmZTphYzoxNjozZToyYzozNTpjNjo2MzpmYzpkYzoxMDplYjoKKyAgICAgICAgMGQ6YTM6YWE6ZDA6N2M6Y2M6ZDE6ZDA6MmY6NTE6MmU6YzQ6MTQ6NWE6ZGU6ZTg6MTk6ZTE6CisgICAgICAgIDNlOmM2OmNjOmE0OjI5OmU3OjJlOjg0OmFhOjA2OjMwOjc4Ojc2OjU0OjczOjI4Ojk4OjU5OgorICAgICAgICAzODplMDowMDowZDo2MjpkMzo0Mjo3ZDoyMTo5ZjphZTozZDozYTo4YzpkNTpmYTo3NzowZDoKKyAgICAgICAgMTg6MmI6MTY6MGU6NWY6MzY6ZTE6ZmM6MmE6YjU6MzA6MjQ6Y2Y6ZTA6NjM6MGM6N2I6NTg6CisgICAgICAgIDFhOmZlOjk5OmJhOjQyOjEyOmIxOjkxOmY0OjdjOjY4OmUyOmM4OmU4OmFmOjJjOmVhOmM5OgorICAgICAgICA3ZTphZTpiYjoyYTozZDowZDoxNTpkYzozNDo5NTpiNjoxODo3NDphODo2YTowZjpjNzpiNDoKKyAgICAgICAgZjQ6MTM6YzQ6ZTQ6NWI6ZWQ6MGE6ZDI6YTQ6OTc6NGM6MmE6ZWQ6MmY6NmM6MTI6ODk6M2Q6CisgICAgICAgIGYxOjI3OjcwOmFhOjZhOjAzOjUyOjIxOjlmOjQwOmE4OjY3OjUwOmYyOmYzOjVhOjFmOmRmOgorICAgICAgICBkZjoyMzpmNjpkYzo3ODo0ZTplNjo5ODo0Zjo1NTozYTo1MzplMzplZjpmMjpmNDo5ZjpjNzoKKyAgICAgICAgN2M6ZDg6NTg6YWY6Mjk6MjI6OTc6Yjg6ZTA6YmQ6OTE6MmU6YjA6NzY6ZWM6NTc6MTE6Y2Y6CisgICAgICAgIGVmOjI5OjQ0OmYzOmU5Ojg1OjdhOjYwOjYzOmU0OjVkOjMzOjg5OjE3OmQ5OjMxOmFhOmRhOgorICAgICAgICBkNjpmMzoxODozNTo3MjpjZjo4NzoyYjoyZjo2MzoyMzo4NDo1ZDo4NDo4YzozZjo1NzphMDoKKyAgICAgICAgODg6ZmM6OTk6OTE6Mjg6MjY6Njk6OTk6ZDQ6OGY6OTc6NDQ6YmU6OGU6ZDU6NDg6YjE6YTQ6CisgICAgICAgIDI4OjI5OmYxOjE1OmI0OmUxOmU1OjllOmRkOmY4OjhmOmE2OjZmOjI2OmQ3OjA5OjNjOjNhOgorICAgICAgICAxYzoxMTowZTphNjo2YzozNzpmNzphZDo0NDo4NzoyYzoyODpjNzpkODo3NDo4MjpiMzpkMDoKKyAgICAgICAgNmY6NGE6NTc6YmI6MzU6Mjk6Mjc6YTA6OGI6ZTg6MjE6YTc6ODc6NjQ6MzY6NWQ6Y2M6ZDg6CisgICAgICAgIDE2OmFjOmM3OmIyOjI3OjQwOjkyOjU1OjM4OjI4OjhkOjUxOjZlOmRkOjE0OjY3OjUzOjZjOgorICAgICAgICA3MTo1YzoyNjo4NDo0ZDo3NTo1YTpiNjo3ZTo2MDo1NjphOTo0ZDphZDpmYjo5YjoxZTo5NzoKKyAgICAgICAgZjM6MGQ6ZDk6ZDI6OTc6NTQ6Nzc6ZGE6M2Q6MTI6Yjc6ZTA6MWU6ZWY6MDg6MDY6YWM6Zjk6CisgICAgICAgIDg1Ojg3OmU5OmEyOmRjOmFmOjdlOjE4OjEyOjgzOmZkOjU2OjE3OjQxOjJlOmQ1OjI5OjgyOgorICAgICAgICA3ZDo5OTpmNDozMTpmNjo3MTphOTpjZjoyYzowMToyNzphNTowNTpiOTphYTpiMjo0ODo0ZToKKyAgICAgICAgMmE6ZWY6OWY6OTM6NTI6NTE6OTU6M2M6NTI6NzM6OGU6NTY6NGM6MTc6NDA6YzA6MDk6Mjg6CisgICAgICAgIGU0OjhiOjZhOjQ4OjUzOmRiOmVjOmNkOjU1OjU1OmYxOmM2OmY4OmU5OmEyOjJjOjRjOmE2OgorICAgICAgICBkMToyNjo1Zjo3ZTphZjo1YTo0YzpkYToxZjphNjpmMjoxYzoyYzo3ZTphZTowMjoxNjpkMjoKKyAgICAgICAgNTY6ZDA6MmY6NTc6NTM6NDc6ZTg6OTIKK1NIQTEgRmluZ2VycHJpbnQ9Mzc6OUE6MTk6N0I6NDE6ODU6NDU6MzU6MEM6QTY6MDM6Njk6RjM6M0M6MkU6QUY6NDc6NEY6MjA6NzkKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy84ODJkZTA2MS4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzg4MmRlMDYxLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTBlMTE1MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy84ODJkZTA2MS4wCkBAIC0wLDAgKzEsNzggQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRE9EQ0NBaUNnQXdJQkFnSUdJQVlGRm5BQ01BMEdDU3FHU0liM0RRRUJCUVVBTURzeEN6QUpCZ05WQkFZVAorQWxKUE1SRXdEd1lEVlFRS0V3aGpaWEowVTBsSFRqRVpNQmNHQTFVRUN4TVFZMlZ5ZEZOSlIwNGdVazlQVkNCRAorUVRBZUZ3MHdOakEzTURReE56SXdNRFJhRncwek1UQTNNRFF4TnpJd01EUmFNRHN4Q3pBSkJnTlZCQVlUQWxKUAorTVJFd0R3WURWUVFLRXdoalpYSjBVMGxIVGpFWk1CY0dBMVVFQ3hNUVkyVnlkRk5KUjA0Z1VrOVBWQ0JEUVRDQworQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFMY3p1WDdJSlVxT3RkdTBLQnVxVjVEbworMFNMVFpMclRrK2pVcklaaFFHcGdWMmhVaEUyOGFsUUNCZi9mbTVvcXJsMEhqMHJES0gvdit5djZlZkhIcmZBUQorVXlTUWkyYkpxSWlycjFxakFPbSt1a2J1VzNON0xCZUNnVjVpTEtFQ1piTzl4U3NBZnNUOEF6TlhEZTNpK3M1ZAorUmRZNHpUVzJzc0hRbklGS3F1U3lBVndkajErWnhMR3QyNGdoNjVBSWdvRHpNS05ENXBDQ3JsVW9TZTFiMTZrUQorT0E3K2oweGJtMGJxUWZXd0NIVEQwSWd6dG56WGROL2NoTkZERG5VNW9TVkFLT3A0eXc0c0xqbWRqSXR1Rmh3dgorSm9JUTR1TmxsQW9Fd0Y3M1hWdjRFT0xRdW5wTCs5NDNBQUFhV3lqajBweHpQaktIbUtISlVTL1gzcXd6czA4QworQXdFQUFhTkNNRUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFQkFNQ0FjWXdIUVlEVlIwTworQkJZRUZPQ01tOXNsU2JQeGZJYldza0tIQzlCcm9ObmtNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUJBUUErMGh5SgorTGpYOCtIWGQ1bjlsaVBSeVRNa3MxekpPODkwWmVVZTlqanRia3c5UVNTUVRheFFHY3U4SjA2R2g0MENFeWVjWQorTW5ROFNHNFBuMHZVOXg3VGs0WmtWSmRqY2xEVlZjLzZJSk1Db3B2REk1Tk9GbFYyb0hCNWJjMGhIODh2TGJ3WgorNDRneCtGa2FnUW5JbDZaMHgyREVXOHhYanJKMS9Sc0NDZHRaYjNLVGFmY3hRZGFJT0wrSHNyMFdlZm1xNUw2SQorSmQxaEp5TWN0VEVIQkRhMEdwQzlvSFJ4VUlsdHZCVGpENGF1OGFzK3g2QUp6S05JMGVEYlpPZVN0Yyt2Y2tOdworaS9uRGhEd1RxbjZTbTFkVGsvcHd3cEVPTWZtYloxM3BsamhlWDdOelRvZ1ZaOTZlZGhCaUlMNVZhWlZEQURsTgorOXU2d1drNUpSRlJZWDBLRAorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgMjA6MDY6MDU6MTY6NzA6MDIKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1STywgTz1jZXJ0U0lHTiwgT1U9Y2VydFNJR04gUk9PVCBDQQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogSnVsICA0IDE3OjIwOjA0IDIwMDYgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBKdWwgIDQgMTc6MjA6MDQgMjAzMSBHTVQKKyAgICAgICAgU3ViamVjdDogQz1STywgTz1jZXJ0U0lHTiwgT1U9Y2VydFNJR04gUk9PVCBDQQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6Yjc6MzM6Yjk6N2U6Yzg6MjU6NGE6OGU6YjU6ZGI6YjQ6Mjg6MWI6YWE6CisgICAgICAgICAgICAgICAgICAgIDU3OjkwOmU4OmQxOjIyOmQzOjY0OmJhOmQzOjkzOmU4OmQ0OmFjOjg2OjYxOgorICAgICAgICAgICAgICAgICAgICA0MDo2YTo2MDo1Nzo2ODo1NDo4NDo0ZDpiYzo2YTo1NDowMjowNTpmZjpkZjoKKyAgICAgICAgICAgICAgICAgICAgOWI6OWE6MmE6YWU6NWQ6MDc6OGY6NGE6YzM6Mjg6N2Y6ZWY6ZmI6MmI6ZmE6CisgICAgICAgICAgICAgICAgICAgIDc5OmYxOmM3OmFkOmYwOjEwOjUzOjI0OjkwOjhiOjY2OmM5OmE4Ojg4OmFiOgorICAgICAgICAgICAgICAgICAgICBhZjo1YTphMzowMDplOTpiZTpiYTo0NjplZTo1Yjo3Mzo3YjoyYzoxNzo4MjoKKyAgICAgICAgICAgICAgICAgICAgODE6NWU6NjI6MmM6YTE6MDI6NjU6YjM6YmQ6YzU6MmI6MDA6N2U6YzQ6ZmM6CisgICAgICAgICAgICAgICAgICAgIDAzOjMzOjU3OjBkOmVkOmUyOmZhOmNlOjVkOjQ1OmQ2OjM4OmNkOjM1OmI2OgorICAgICAgICAgICAgICAgICAgICBiMjpjMTpkMDo5Yzo4MTo0YTphYTplNDpiMjowMTo1YzoxZDo4Zjo1Zjo5OToKKyAgICAgICAgICAgICAgICAgICAgYzQ6YjE6YWQ6ZGI6ODg6MjE6ZWI6OTA6MDg6ODI6ODA6ZjM6MzA6YTM6NDM6CisgICAgICAgICAgICAgICAgICAgIGU2OjkwOjgyOmFlOjU1OjI4OjQ5OmVkOjViOmQ3OmE5OjEwOjM4OjBlOmZlOgorICAgICAgICAgICAgICAgICAgICA4Zjo0Yzo1Yjo5Yjo0NjplYTo0MTpmNTpiMDowODo3NDpjMzpkMDo4ODozMzoKKyAgICAgICAgICAgICAgICAgICAgYjY6N2M6ZDc6NzQ6ZGY6ZGM6ODQ6ZDE6NDM6MGU6NzU6Mzk6YTE6MjU6NDA6CisgICAgICAgICAgICAgICAgICAgIDI4OmVhOjc4OmNiOjBlOjJjOjJlOjM5OjlkOjhjOjhiOjZlOjE2OjFjOjJmOgorICAgICAgICAgICAgICAgICAgICAyNjo4MjoxMDplMjplMzo2NTo5NDowYTowNDpjMDo1ZTpmNzo1ZDo1YjpmODoKKyAgICAgICAgICAgICAgICAgICAgMTA6ZTI6ZDA6YmE6N2E6NGI6ZmI6ZGU6Mzc6MDA6MDA6MWE6NWI6Mjg6ZTM6CisgICAgICAgICAgICAgICAgICAgIGQyOjljOjczOjNlOjMyOjg3Ojk4OmExOmM5OjUxOjJmOmQ3OmRlOmFjOjMzOgorICAgICAgICAgICAgICAgICAgICBiMzo0ZgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBEaWdpdGFsIFNpZ25hdHVyZSwgTm9uIFJlcHVkaWF0aW9uLCBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEUwOjhDOjlCOkRCOjI1OjQ5OkIzOkYxOjdDOjg2OkQ2OkIyOjQyOjg3OjBCOkQwOjZCOkEwOkQ5OkU0CisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDNlOmQyOjFjOjg5OjJlOjM1OmZjOmY4Ojc1OmRkOmU2OjdmOjY1Ojg4OmY0OjcyOjRjOmM5OgorICAgICAgICAyYzpkNzozMjo0ZTpmMzpkZDoxOTo3OTo0NzpiZDo4ZTozYjo1Yjo5MzowZjo1MDo0OToyNDoKKyAgICAgICAgMTM6NmI6MTQ6MDY6NzI6ZWY6MDk6ZDM6YTE6YTE6ZTM6NDA6ODQ6Yzk6ZTc6MTg6MzI6NzQ6CisgICAgICAgIDNjOjQ4OjZlOjBmOjlmOjRiOmQ0OmY3OjFlOmQzOjkzOjg2OjY0OjU0Ojk3OjYzOjcyOjUwOgorICAgICAgICBkNTo1NTpjZjpmYToyMDo5MzowMjphMjo5YjpjMzoyMzo5Mzo0ZToxNjo1NTo3NjphMDo3MDoKKyAgICAgICAgNzk6NmQ6Y2Q6MjE6MWY6Y2Y6MmY6MmQ6YmM6MTk6ZTM6ODg6MzE6Zjg6NTk6MWE6ODE6MDk6CisgICAgICAgIGM4Ojk3OmE2Ojc0OmM3OjYwOmM0OjViOmNjOjU3OjhlOmIyOjc1OmZkOjFiOjAyOjA5OmRiOgorICAgICAgICA1OTo2Zjo3Mjo5Mzo2OTpmNzozMTo0MTpkNjo4ODozODpiZjo4NzpiMjpiZDoxNjo3OTpmOToKKyAgICAgICAgYWE6ZTQ6YmU6ODg6MjU6ZGQ6NjE6Mjc6MjM6MWM6YjU6MzE6MDc6MDQ6MzY6YjQ6MWE6OTA6CisgICAgICAgIGJkOmEwOjc0OjcxOjUwOjg5OjZkOmJjOjE0OmUzOjBmOjg2OmFlOmYxOmFiOjNlOmM3OmEwOgorICAgICAgICAwOTpjYzphMzo0ODpkMTplMDpkYjo2NDplNzo5MjpiNTpjZjphZjo3Mjo0Mzo3MDo4YjpmOToKKyAgICAgICAgYzM6ODQ6M2M6MTM6YWE6N2U6OTI6OWI6NTc6NTM6OTM6ZmE6NzA6YzI6OTE6MGU6MzE6Zjk6CisgICAgICAgIDliOjY3OjVkOmU5Ojk2OjM4OjVlOjVmOmIzOjczOjRlOjg4OjE1OjY3OmRlOjllOjc2OjEwOgorICAgICAgICA2MjoyMDpiZTo1NTo2OTo5NTo0MzowMDozOTo0ZDpmNjplZTpiMDo1YTo0ZTo0OTo0NDo1NDoKKyAgICAgICAgNTg6NWY6NDI6ODMKK1NIQTEgRmluZ2VycHJpbnQ9RkE6Qjc6RUU6MzY6OTc6MjY6NjI6RkI6MkQ6QjA6MkE6RjY6QkY6MDM6RkQ6RTg6N0M6NEI6MkY6OUIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy84OTVjYWQxYS4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzg5NWNhZDFhLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDhiM2E0MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy84OTVjYWQxYS4wCkBAIC0wLDAgKzEsODIgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRFZUQ0NBajJnQXdJQkFnSUVTVE1BQVRBTkJna3Foa2lHOXcwQkFRVUZBREF5TVFzd0NRWURWUVFHRXdKRAorVGpFT01Bd0dBMVVFQ2hNRlEwNU9TVU14RXpBUkJnTlZCQU1UQ2tOT1RrbERJRkpQVDFRd0hoY05NRGN3TkRFMgorTURjd09URTBXaGNOTWpjd05ERTJNRGN3T1RFMFdqQXlNUXN3Q1FZRFZRUUdFd0pEVGpFT01Bd0dBMVVFQ2hNRgorUTA1T1NVTXhFekFSQmdOVkJBTVRDa05PVGtsRElGSlBUMVF3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQgorRHdBd2dnRUtBb0lCQVFEVE5mYy9jM2V0NkZ0ekY4TFJiKzFWdkc3cTZLUjVzbXpEbysvaG43RTdTSVgxbWx3aAorSWhBc3hZTE8ydU9hYmpmaGh5emN1UXhhdW9oVjMvMnEyeDh4NmdIeDN6a0J3UlA5U0ZJaHhGWGYydGl6VkhhNgorZExHM2ZkZkE2UFpaeFUzSXZhMGZGTnJmV0VRbE1oa3F4MzUranE0NHNEQjdSM0lKTWZBdzI4TWJkaW03YVhaTworVi9rYlpLS1RWcmR2bVc3YkNnU2NFZU9BSDh0amxCQUtxZUZrZ2pINWpDZnRwcGtBOW5DVEdQaWhOSWFqM1hyQworR0huMmVtVTF6NURydlRPVG4xT3JjenZtbXpRZ0x4M3ZxUjFqR3FDQTJ3TXYrU1lhaHRLTnU2bStVanFIWjBnTgordjdTZzJDYStJMTl6TjM4bTVwSUVvMy9QSUtlMzh6ckt5NW5MQWdNQkFBR2pjekJ4TUJFR0NXQ0dTQUdHK0VJQgorQVFRRUF3SUFCekFmQmdOVkhTTUVHREFXZ0JSbDhqR3RLdmYzM1ZLV0NzY0N3UTd2cHRVN0VUQVBCZ05WSFJNQgorQWY4RUJUQURBUUgvTUFzR0ExVWREd1FFQXdJQi9qQWRCZ05WSFE0RUZnUVVaZkl4clNyMzk5MVNsZ3JIQXNFTworNzZiVk94RXdEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBRXMxN3N6a3JyL0RicTJmbFR0TFAxc2UzMWNwb2xuSworT09LNUd2K2U1bTR5M1I2dTZqVzM5Wk9SVHRwQzRjTVhZRkR5MFZ3bXVZSzM2bTNrbklUbkEza1hyNWc5bE52SAordWdEbnVMOEJWOEYzUlRJTU8vRzBIQWl3L1ZHZ29kMmFIUk0ybW0yM3h6eTU0Y1haRi9xRDFUMFZvRHk3SGd2aQoreUpBL3FJWU0vUG1MWG9YTFQxdExZaEZIeFVWOEJTOUJzWjRRYVJ1Wmx1QlZlZnRPaHBtNGxOcUdPR3FUbytmTAorYnVYZjZpRlZpWng5ZlgrWTlRQ0o3dU9Fd0Z5V3RjVkc2a2JnaFZXMkc4a1Mxc0hOellEekFnRTh5R25MUlVoagorMkpUUTdJVU9PMDRSWmZTQ2pLWTlyaTRpbEFuSVhPbzhnVjBXS2dPWEZsVUoyNHBCZ3A1bW14RT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMTIyODA3OTEwNSAoMHg0OTMzMDAwMSkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1DTiwgTz1DTk5JQywgQ049Q05OSUMgUk9PVAorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogQXByIDE2IDA3OjA5OjE0IDIwMDcgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBBcHIgMTYgMDc6MDk6MTQgMjAyNyBHTVQKKyAgICAgICAgU3ViamVjdDogQz1DTiwgTz1DTk5JQywgQ049Q05OSUMgUk9PVAorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6ZDM6MzU6Zjc6M2Y6NzM6Nzc6YWQ6ZTg6NWI6NzM6MTc6YzI6ZDE6NmY6CisgICAgICAgICAgICAgICAgICAgIGVkOjU1OmJjOjZlOmVhOmU4OmE0Ojc5OmIyOjZjOmMzOmEzOmVmOmUxOjlmOgorICAgICAgICAgICAgICAgICAgICBiMTozYjo0ODo4NTpmNTo5YTo1YzoyMToyMjoxMDoyYzpjNTo4MjpjZTpkYToKKyAgICAgICAgICAgICAgICAgICAgZTM6OWE6NmU6Mzc6ZTE6ODc6MmM6ZGM6Yjk6MGM6NWE6YmE6ODg6NTU6ZGY6CisgICAgICAgICAgICAgICAgICAgIGZkOmFhOmRiOjFmOjMxOmVhOjAxOmYxOmRmOjM5OjAxOmMxOjEzOmZkOjQ4OgorICAgICAgICAgICAgICAgICAgICA1MjoyMTpjNDo1NTpkZjpkYTpkODpiMzo1NDo3NjpiYTo3NDpiMTpiNzo3ZDoKKyAgICAgICAgICAgICAgICAgICAgZDc6YzA6ZTg6ZjY6NTk6YzU6NGQ6Yzg6YmQ6YWQ6MWY6MTQ6ZGE6ZGY6NTg6CisgICAgICAgICAgICAgICAgICAgIDQ0OjI1OjMyOjE5OjJhOmM3OjdlOjdlOjhlOmFlOjM4OmIwOjMwOjdiOjQ3OgorICAgICAgICAgICAgICAgICAgICA3MjowOTozMTpmMDozMDpkYjpjMzoxYjo3NjoyOTpiYjo2OTo3Njo0ZTo1NzoKKyAgICAgICAgICAgICAgICAgICAgZjk6MWI6NjQ6YTI6OTM6NTY6Yjc6NmY6OTk6NmU6ZGI6MGE6MDQ6OWM6MTE6CisgICAgICAgICAgICAgICAgICAgIGUzOjgwOjFmOmNiOjYzOjk0OjEwOjBhOmE5OmUxOjY0OjgyOjMxOmY5OjhjOgorICAgICAgICAgICAgICAgICAgICAyNzplZDphNjo5OTowMDpmNjo3MDo5MzoxODpmODphMTozNDo4NjphMzpkZDoKKyAgICAgICAgICAgICAgICAgICAgN2E6YzI6MTg6Nzk6ZjY6N2E6NjU6MzU6Y2Y6OTA6ZWI6YmQ6MzM6OTM6OWY6CisgICAgICAgICAgICAgICAgICAgIDUzOmFiOjczOjNiOmU2OjliOjM0OjIwOjJmOjFkOmVmOmE5OjFkOjYzOjFhOgorICAgICAgICAgICAgICAgICAgICBhMDo4MDpkYjowMzoyZjpmOToyNjoxYTo4NjpkMjo4ZDpiYjphOTpiZTo1MjoKKyAgICAgICAgICAgICAgICAgICAgM2E6ODc6Njc6NDg6MGQ6YmY6YjQ6YTA6ZDg6MjY6YmU6MjM6NWY6NzM6Mzc6CisgICAgICAgICAgICAgICAgICAgIDdmOjI2OmU2OjkyOjA0OmEzOjdmOmNmOjIwOmE3OmI3OmYzOjNhOmNhOmNiOgorICAgICAgICAgICAgICAgICAgICA5OTpjYgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBOZXRzY2FwZSBDZXJ0IFR5cGU6IAorICAgICAgICAgICAgICAgIFNTTCBDQSwgUy9NSU1FIENBLCBPYmplY3QgU2lnbmluZyBDQQorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6NjU6RjI6MzE6QUQ6MkE6Rjc6Rjc6REQ6NTI6OTY6MEE6Qzc6MDI6QzE6MEU6RUY6QTY6RDU6M0I6MTEKKworICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IAorICAgICAgICAgICAgICAgIERpZ2l0YWwgU2lnbmF0dXJlLCBOb24gUmVwdWRpYXRpb24sIEtleSBFbmNpcGhlcm1lbnQsIERhdGEgRW5jaXBoZXJtZW50LCBLZXkgQWdyZWVtZW50LCBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDY1OkYyOjMxOkFEOjJBOkY3OkY3OkREOjUyOjk2OjBBOkM3OjAyOkMxOjBFOkVGOkE2OkQ1OjNCOjExCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDRiOjM1OmVlOmNjOmU0OmFlOmJmOmMzOjZlOmFkOjlmOjk1OjNiOjRiOjNmOjViOjFlOmRmOgorICAgICAgICA1NzoyOTphMjo1OTpjYTozODplMjpiOToxYTpmZjo5ZTplNjo2ZTozMjpkZDoxZTphZTplYToKKyAgICAgICAgMzU6Yjc6ZjU6OTM6OTE6NGU6ZGE6NDI6ZTE6YzM6MTc6NjA6NTA6ZjI6ZDE6NWM6MjY6Yjk6CisgICAgICAgIDgyOmI3OmVhOjZkOmU0OjljOjg0OmU3OjAzOjc5OjE3OmFmOjk4OjNkOjk0OmRiOmM3OmJhOgorICAgICAgICAwMDplNzpiODpiZjowMTo1NzpjMTo3Nzo0NTozMjowYzozYjpmMTpiNDoxYzowODpiMDpmZDoKKyAgICAgICAgNTE6YTA6YTE6ZGQ6OWE6MWQ6MTM6MzY6OWE6NmQ6Yjc6Yzc6M2M6Yjk6ZTE6YzU6ZDk6MTc6CisgICAgICAgIGZhOjgzOmQ1OjNkOjE1OmEwOjNjOmJiOjFlOjBiOmUyOmM4OjkwOjNmOmE4Ojg2OjBjOmZjOgorICAgICAgICBmOTo4Yjo1ZTo4NTpjYjo0Zjo1Yjo0Yjo2MjoxMTo0NzpjNTo0NTo3YzowNToyZjo0MTpiMToKKyAgICAgICAgOWU6MTA6Njk6MWI6OTk6OTY6ZTA6NTU6Nzk6ZmI6NGU6ODY6OTk6Yjg6OTQ6ZGE6ODY6Mzg6CisgICAgICAgIDZhOjkzOmEzOmU3OmNiOjZlOmU1OmRmOmVhOjIxOjU1Ojg5OjljOjdkOjdkOjdmOjk4OmY1OgorICAgICAgICAwMDo4OTplZTplMzo4NDpjMDo1Yzo5NjpiNTpjNTo0NjplYTo0NjplMDo4NTo1NTpiNjoxYjoKKyAgICAgICAgYzk6MTI6ZDY6YzE6Y2Q6Y2Q6ODA6ZjM6MDI6MDE6M2M6Yzg6Njk6Y2I6NDU6NDg6NjM6ZDg6CisgICAgICAgIDk0OmQwOmVjOjg1OjBlOjNiOjRlOjExOjY1OmY0OjgyOjhjOmE2OjNkOmFlOjJlOjIyOjk0OgorICAgICAgICAwOTpjODo1YzplYTozYzo4MTo1ZDoxNjoyYTowMzo5NzoxNjo1NTowOTpkYjo4YTo0MTo4MjoKKyAgICAgICAgOWU6NjY6OWI6MTEKK1NIQTEgRmluZ2VycHJpbnQ9OEI6QUY6NEM6OUI6MUQ6RjA6MkE6OTI6Rjc6REE6MTI6OEU6Qjk6MUI6QUM6RjQ6OTg6NjA6NEI6NkYKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy84OWMwMmE0NS4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzg5YzAyYTQ1LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzEyMjA0ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy84OWMwMmE0NS4wCkBAIC0wLDAgKzEsNTQgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJQ2lUQ0NBZytnQXdJQkFnSVFIMGV2cW1JQWNGQlVUQUdlbTJPWktqQUtCZ2dxaGtqT1BRUURBekNCaFRFTAorTUFrR0ExVUVCaE1DUjBJeEd6QVpCZ05WQkFnVEVrZHlaV0YwWlhJZ1RXRnVZMmhsYzNSbGNqRVFNQTRHQTFVRQorQnhNSFUyRnNabTl5WkRFYU1CZ0dBMVVFQ2hNUlEwOU5UMFJQSUVOQklFeHBiV2wwWldReEt6QXBCZ05WQkFNVAorSWtOUFRVOUVUeUJGUTBNZ1EyVnlkR2xtYVdOaGRHbHZiaUJCZFhSb2IzSnBkSGt3SGhjTk1EZ3dNekEyTURBdworTURBd1doY05Nemd3TVRFNE1qTTFPVFU1V2pDQmhURUxNQWtHQTFVRUJoTUNSMEl4R3pBWkJnTlZCQWdURWtkeQorWldGMFpYSWdUV0Z1WTJobGMzUmxjakVRTUE0R0ExVUVCeE1IVTJGc1ptOXlaREVhTUJnR0ExVUVDaE1SUTA5TgorVDBSUElFTkJJRXhwYldsMFpXUXhLekFwQmdOVkJBTVRJa05QVFU5RVR5QkZRME1nUTJWeWRHbG1hV05oZEdsdgorYmlCQmRYUm9iM0pwZEhrd2RqQVFCZ2NxaGtqT1BRSUJCZ1VyZ1FRQUlnTmlBQVFEUjNzdmRjbUNGWVg3ZGVTUgorRnRTcllwbjFQbElMQnM1QkFIK1g0UW9rUEIwQkJPNDkwbzBKbHd6Z2RlVDYrM2VLS3ZVRFlFczJpeFlqRnEwSgorY2ZSSzlDaFF0UDZJSEc0L2JDOHZDVmxicFZzTE01bml3ejJKK1dvczc3TFRCdW1qUWpCQU1CMEdBMVVkRGdRVworQkJSMWNhY1pTQm04blozcVFVZmZsTVJJZDVuVGVUQU9CZ05WSFE4QkFmOEVCQU1DQVFZd0R3WURWUjBUQVFILworQkFVd0F3RUIvekFLQmdncWhrak9QUVFEQXdOb0FEQmxBakVBN3dOYmVxeTNlQXB5dDRqZi83VkdGQWtLK3FEbQorZlFqR0dvZTlHS2h6dlNiS1lBeWR6cG1mejF3UE1PRytGREhxQWpBVTlKTThTYWN6ZXBCR1I3TmpmUk9iVHJkdgorR0RlQVUvN2RJT0ExbWpiUnh3RzU1dHpkOC84ZExEb1dWOW1TT2RZPQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgMWY6NDc6YWY6YWE6NjI6MDA6NzA6NTA6NTQ6NGM6MDE6OWU6OWI6NjM6OTk6MmEKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogZWNkc2Etd2l0aC1TSEEzODQKKyAgICAgICAgSXNzdWVyOiBDPUdCLCBTVD1HcmVhdGVyIE1hbmNoZXN0ZXIsIEw9U2FsZm9yZCwgTz1DT01PRE8gQ0EgTGltaXRlZCwgQ049Q09NT0RPIEVDQyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTWFyICA2IDAwOjAwOjAwIDIwMDggR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBKYW4gMTggMjM6NTk6NTkgMjAzOCBHTVQKKyAgICAgICAgU3ViamVjdDogQz1HQiwgU1Q9R3JlYXRlciBNYW5jaGVzdGVyLCBMPVNhbGZvcmQsIE89Q09NT0RPIENBIExpbWl0ZWQsIENOPUNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogaWQtZWNQdWJsaWNLZXkKKyAgICAgICAgICAgIEVDIFB1YmxpYyBLZXk6CisgICAgICAgICAgICAgICAgcHViOiAKKyAgICAgICAgICAgICAgICAgICAgMDQ6MDM6NDc6N2I6MmY6NzU6Yzk6ODI6MTU6ODU6ZmI6NzU6ZTQ6OTE6MTY6CisgICAgICAgICAgICAgICAgICAgIGQ0OmFiOjYyOjk5OmY1OjNlOjUyOjBiOjA2OmNlOjQxOjAwOjdmOjk3OmUxOgorICAgICAgICAgICAgICAgICAgICAwYToyNDozYzoxZDowMTowNDplZTozZDpkMjo4ZDowOTo5NzowYzplMDo3NToKKyAgICAgICAgICAgICAgICAgICAgZTQ6ZmE6ZmI6Nzc6OGE6MmE6ZjU6MDM6NjA6NGI6MzY6OGI6MTY6MjM6MTY6CisgICAgICAgICAgICAgICAgICAgIGFkOjA5OjcxOmY0OjRhOmY0OjI4OjUwOmI0OmZlOjg4OjFjOjZlOjNmOjZjOgorICAgICAgICAgICAgICAgICAgICAyZjoyZjowOTo1OTo1YjphNTo1YjowYjozMzo5OTplMjpjMzozZDo4OTpmOToKKyAgICAgICAgICAgICAgICAgICAgNmE6MmM6ZWY6YjI6ZDM6MDY6ZTkKKyAgICAgICAgICAgICAgICBBU04xIE9JRDogc2VjcDM4NHIxCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDc1OjcxOkE3OjE5OjQ4OjE5OkJDOjlEOjlEOkVBOjQxOjQ3OkRGOjk0OkM0OjQ4Ojc3Ojk5OkQzOjc5CisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IGVjZHNhLXdpdGgtU0hBMzg0CisgICAgICAgIDMwOjY1OjAyOjMxOjAwOmVmOjAzOjViOjdhOmFjOmI3Ojc4OjBhOjcyOmI3Ojg4OmRmOmZmOgorICAgICAgICBiNTo0NjoxNDowOTowYTpmYTphMDplNjo3ZDowODpjNjoxYTo4NzpiZDoxODphODo3MzpiZDoKKyAgICAgICAgMjY6Y2E6NjA6MGM6OWQ6Y2U6OTk6OWY6Y2Y6NWM6MGY6MzA6ZTE6YmU6MTQ6MzE6ZWE6MDI6CisgICAgICAgIDMwOjE0OmY0OjkzOjNjOjQ5OmE3OjMzOjdhOjkwOjQ2OjQ3OmIzOjYzOjdkOjEzOjliOjRlOgorICAgICAgICBiNzo2ZjoxODozNzo4MDo1MzpmZTpkZDoyMDplMDozNTo5YTozNjpkMTpjNzowMTpiOTplNjoKKyAgICAgICAgZGM6ZGQ6ZjM6ZmY6MWQ6MmM6M2E6MTY6NTc6ZDk6OTI6Mzk6ZDYKK1NIQTEgRmluZ2VycHJpbnQ9OUY6NzQ6NEU6OUY6MkI6NEQ6QkE6RUM6MEY6MzE6MkM6NTA6QjY6NTY6M0I6OEU6MkQ6OTM6QzM6MTEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy84ZjdiOTZjNC4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzhmN2I5NmM0LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODFhMmM3NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy84ZjdiOTZjNC4wCkBAIC0wLDAgKzEsNzAgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRElEQ0NBb21nQXdJQkFnSUVOM0RQdFRBTkJna3Foa2lHOXcwQkFRVUZBREJPTVFzd0NRWURWUVFHRXdKVgorVXpFWE1CVUdBMVVFQ2hNT1JYRjFhV1poZUNCVFpXTjFjbVV4SmpBa0JnTlZCQXNUSFVWeGRXbG1ZWGdnVTJWagorZFhKbElHVkNkWE5wYm1WemN5QkRRUzB5TUI0WERUazVNRFl5TXpFeU1UUTBOVm9YRFRFNU1EWXlNekV5TVRRMAorTlZvd1RqRUxNQWtHQTFVRUJoTUNWVk14RnpBVkJnTlZCQW9URGtWeGRXbG1ZWGdnVTJWamRYSmxNU1l3SkFZRAorVlFRTEV4MUZjWFZwWm1GNElGTmxZM1Z5WlNCbFFuVnphVzVsYzNNZ1EwRXRNakNCbnpBTkJna3Foa2lHOXcwQgorQVFFRkFBT0JqUUF3Z1lrQ2dZRUE1RGs1a3g1U0Joc29Odml5b3luRjdZNnlFYjMrNitlMGRNS1Avd1huMlowRwordnhMSVB3N3kxdEVrc2hIZTBYTUppdFN4TEpnSkRSNVFScktEcGtXTlltaTdoUnNnY0RLcVFNMm1sbC9FY1RjLworQlBPM1FTUTVCeG9lTG1GWW9CSUw1YVhmeGF2cU4zSE1ITWczT3JtWFVxZXN4V29rbEU2Y2U4L0FhdGJmSWIwQworQXdFQUFhT0NBUWt3Z2dFRk1IQUdBMVVkSHdScE1HY3daYUJqb0dHa1h6QmRNUXN3Q1FZRFZRUUdFd0pWVXpFWAorTUJVR0ExVUVDaE1PUlhGMWFXWmhlQ0JUWldOMWNtVXhKakFrQmdOVkJBc1RIVVZ4ZFdsbVlYZ2dVMlZqZFhKbAorSUdWQ2RYTnBibVZ6Y3lCRFFTMHlNUTB3Q3dZRFZRUURFd1JEVWt3eE1Cb0dBMVVkRUFRVE1CR0JEekl3TVRrdworTmpJek1USXhORFExV2pBTEJnTlZIUThFQkFNQ0FRWXdId1lEVlIwakJCZ3dGb0FVVUo0TDZxOWV1U0JJcGxCcQoreS8zWUlIcW5nbll3SFFZRFZSME9CQllFRkZDZUMrcXZYcmtnU0taUWFzdjkyQ0I2cDRKMk1Bd0dBMVVkRXdRRgorTUFNQkFmOHdHZ1lKS29aSWh2WjlCMEVBQkEwd0N4c0ZWak11TUdNREFnYkFNQTBHQ1NxR1NJYjNEUUVCQlFVQQorQTRHQkFBeUdncTNvVGhyMWpva240alZZUFNtMEI0ODJVSlcvYnNHZTY4U1Fzb1dvdTdkQzRBOEhPZC83bnBDeQorMGNFK1U1OERSTEIrUy9SdjVId2Y1K0t4NUxpYTc4Tzl6dDRMTWpUWjNpanRNMnZFMU5jOUVsaXJmUWt0eTNEMQorRTRxVW9TZWsxbkRGYlpTMXlYMmRvTkxHQ0VuWlpwdW0wL1FMM01VbVYrR1JNT3JOCistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDkzMDE0MDA4NSAoMHgzNzcwY2ZiNSkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgTz1FcXVpZmF4IFNlY3VyZSwgT1U9RXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTIKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEp1biAyMyAxMjoxNDo0NSAxOTk5IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogSnVuIDIzIDEyOjE0OjQ1IDIwMTkgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89RXF1aWZheCBTZWN1cmUsIE9VPUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0yCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMTAyNCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMTAyNCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDplNDozOTozOTo5MzoxZTo1MjowNjoxYjoyODozNjpmODpiMjphMzoyOToKKyAgICAgICAgICAgICAgICAgICAgYzU6ZWQ6OGU6YjI6MTE6YmQ6ZmU6ZWI6ZTc6YjQ6NzQ6YzI6OGY6ZmY6MDU6CisgICAgICAgICAgICAgICAgICAgIGU3OmQ5OjlkOjA2OmJmOjEyOmM4OjNmOjBlOmYyOmQ2OmQxOjI0OmIyOjExOgorICAgICAgICAgICAgICAgICAgICBkZTpkMTo3MzowOTo4YTpkNDpiMToyYzo5ODowOTowZDoxZTo1MDo0NjpiMjoKKyAgICAgICAgICAgICAgICAgICAgODM6YTY6NDU6OGQ6NjI6Njg6YmI6ODU6MWI6MjA6NzA6MzI6YWE6NDA6Y2Q6CisgICAgICAgICAgICAgICAgICAgIGE2Ojk2OjVmOmM0OjcxOjM3OjNmOjA0OmYzOmI3OjQxOjI0OjM5OjA3OjFhOgorICAgICAgICAgICAgICAgICAgICAxZToyZTo2MTo1ODphMDoxMjowYjplNTphNTpkZjpjNTphYjplYTozNzo3MToKKyAgICAgICAgICAgICAgICAgICAgY2M6MWM6Yzg6Mzc6M2E6Yjk6OTc6NTI6YTc6YWM6YzU6NmE6MjQ6OTQ6NGU6CisgICAgICAgICAgICAgICAgICAgIDljOjdiOmNmOmMwOjZhOmQ2OmRmOjIxOmJkCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBDUkwgRGlzdHJpYnV0aW9uIFBvaW50czogCisgICAgICAgICAgICAgICAgRGlyTmFtZTovQz1VUy9PPUVxdWlmYXggU2VjdXJlL09VPUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0yL0NOPUNSTDEKKworICAgICAgICAgICAgWDUwOXYzIFByaXZhdGUgS2V5IFVzYWdlIFBlcmlvZDogCisgICAgICAgICAgICAgICAgTm90IEFmdGVyOiBKdW4gMjMgMTI6MTQ6NDUgMjAxOSBHTVQKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQXV0aG9yaXR5IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBrZXlpZDo1MDo5RTowQjpFQTpBRjo1RTpCOToyMDo0ODpBNjo1MDo2QTpDQjpGRDpEODoyMDo3QTpBNzo4Mjo3NgorCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgNTA6OUU6MEI6RUE6QUY6NUU6Qjk6MjA6NDg6QTY6NTA6NkE6Q0I6RkQ6RDg6MjA6N0E6QTc6ODI6NzYKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgMS4yLjg0MC4xMTM1MzMuNy42NS4wOiAKKyAgICAgICAgICAgICAgICAwLi4uVjMuMGMuLi4uCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDBjOjg2OjgyOmFkOmU4OjRlOjFhOmY1OjhlOjg5OjI3OmUyOjM1OjU4OjNkOjI5OmI0OjA3OgorICAgICAgICA4ZjozNjo1MDo5NTpiZjo2ZTpjMTo5ZTplYjpjNDo5MDpiMjo4NTphODpiYjpiNzo0MjplMDoKKyAgICAgICAgMGY6MDc6Mzk6ZGY6ZmI6OWU6OTA6YjI6ZDE6YzE6M2U6NTM6OWY6MDM6NDQ6YjA6N2U6NGI6CisgICAgICAgIGY0OjZmOmU0OjdjOjFmOmU3OmUyOmIxOmU0OmI4OjlhOmVmOmMzOmJkOmNlOmRlOjBiOjMyOgorICAgICAgICAzNDpkOTpkZToyODplZDozMzo2YjpjNDpkNDpkNzozZDoxMjo1ODphYjo3ZDowOToyZDpjYjoKKyAgICAgICAgNzA6ZjU6MTM6OGE6OTQ6YTE6Mjc6YTQ6ZDY6NzA6YzU6NmQ6OTQ6YjU6Yzk6N2Q6OWQ6YTA6CisgICAgICAgIGQyOmM2OjA4OjQ5OmQ5OjY2OjliOmE2OmQzOmY0OjBiOmRjOmM1OjI2OjU3OmUxOjkxOjMwOgorICAgICAgICBlYTpjZAorU0hBMSBGaW5nZXJwcmludD0zOTo0RjpGNjo4NTowQjowNjpCRTo1MjpFNToxODo1NjpDQzoxMDpFMTo4MDpFODo4MjpCMzo4NTpDQwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzkzMzk1MTJhLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvOTMzOTUxMmEuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNDdkY2JkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzkzMzk1MTJhLjAKQEAgLTAsMCArMSwxMzcgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJR25UQ0NCSVdnQXdJQkFnSUNCY1l3RFFZSktvWklodmNOQVFFRkJRQXdSVEVMTUFrR0ExVUVCaE1DUWsweAorR1RBWEJnTlZCQW9URUZGMWIxWmhaR2x6SUV4cGJXbDBaV1F4R3pBWkJnTlZCQU1URWxGMWIxWmhaR2x6SUZKdgorYjNRZ1EwRWdNekFlRncwd05qRXhNalF4T1RFeE1qTmFGdzB6TVRFeE1qUXhPVEEyTkRSYU1FVXhDekFKQmdOVgorQkFZVEFrSk5NUmt3RndZRFZRUUtFeEJSZFc5V1lXUnBjeUJNYVcxcGRHVmtNUnN3R1FZRFZRUURFeEpSZFc5VworWVdScGN5QlNiMjkwSUVOQklETXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFETQorVjBJV1ZKem1tTlBUVGU3KzdjZWZRemxLWmJQb0ZvZzAydzFaa1hUUGtyZ0VRSzBDU3pHcnZJMlJhTmdnRGhvQgorNGhwN1RoZGQ0b3EzUDVrYXpldGhxOEpscGgrM3Q3MjNqL3o5Y0k4TG9HZStBYUpaejNIbUR5bDIvN0ZXZVVVcgorSDU1NlZPaWpLVFZvcEFGUEQ2UXVOKzhiditPUEVLaHlxMWhYNTFTR3lNbnpXOW9zMmwyT2JqeWpQdHI3Z3VYZAorOGx5eUJUTnZpamJPMEJOTy83OUtERFJNcHNNaHZWQUVWZXV4dTUzN1JSNWtGZDVWQVl3Q2RyWExvVDlDYWJ3dgordldoREZsYUpLamRoa2YybXJrN0F5eFJsbERkTGtnYnZCTkRJbklqYkMzdUJyN0U5S3NSbE9uaTI3dHlBc2RMVAorbVp3NjdtdGFhN09OdDlYT25NSytwVXN2RnJHZWFEc0diNjU5bi9qZTdNd3BwNWlqSlVNdjcvRmZKdUdJVGZoZQorYnRmWkZHNFpNMm1uTzRTSms4UlRWUk9oVVhoQStMakpvdTU3dWxKQ2c1NFU3UVZTV2xsV3A1ZjhuVDhLS2RqYworVDVFT0U3emVsYVRmaTVtK3JKc3ppTysxZ2E4YnhpSlR5UGJIN3BjVXNNVjhlRkxJOE01dWQyQ0VwdWtxZGlEdAorV0FFWE1KUHBHb3ZnYzJQWmFwS1VTVTYwclVxRnhLTWlNUHdKN1dnaWM2YUlERlVoV01YaE9wOHEzY3Joa09EWgorYzZ0c2dMam9DMlNUb0p5TUdmK3owZ3pza1NhSGlyT2k0WENQTEFybHpXMW9VZXZhUHdWL2l6TG1FMXhyL2w5QQorNGlMSXRMUmtUOWE2ZlVnK3FHa00xN3VHY2NsenVEODduU1ZMMnY5QTZ3SURBUUFCbzRJQmxUQ0NBWkV3RHdZRAorVlIwVEFRSC9CQVV3QXdFQi96Q0I0UVlEVlIwZ0JJSFpNSUhXTUlIVEJna3JCZ0VFQWI1WUFBTXdnY1V3Z1pNRworQ0NzR0FRVUZCd0lDTUlHR0dvR0RRVzU1SUhWelpTQnZaaUIwYUdseklFTmxjblJwWm1sallYUmxJR052Ym5OMAorYVhSMWRHVnpJR0ZqWTJWd2RHRnVZMlVnYjJZZ2RHaGxJRkYxYjFaaFpHbHpJRkp2YjNRZ1EwRWdNeUJEWlhKMAorYVdacFkyRjBaU0JRYjJ4cFkza2dMeUJEWlhKMGFXWnBZMkYwYVc5dUlGQnlZV04wYVdObElGTjBZWFJsYldWdQorZEM0d0xRWUlLd1lCQlFVSEFnRVdJV2gwZEhBNkx5OTNkM2N1Y1hWdmRtRmthWE5uYkc5aVlXd3VZMjl0TDJOdworY3pBTEJnTlZIUThFQkFNQ0FRWXdIUVlEVlIwT0JCWUVGUExBRStDQ1F6Nzc3aTluTXBZMVhOdTR5d0xRTUc0RworQTFVZEl3Um5NR1dBRlBMQUUrQ0NRejc3N2k5bk1wWTFYTnU0eXdMUW9VbWtSekJGTVFzd0NRWURWUVFHRXdKQworVFRFWk1CY0dBMVVFQ2hNUVVYVnZWbUZrYVhNZ1RHbHRhWFJsWkRFYk1Ca0dBMVVFQXhNU1VYVnZWbUZrYVhNZworVW05dmRDQkRRU0F6Z2dJRnhqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FnRUFUNjJnTEV6NndQSnY5MlpWcXlNMAorN3VjcDJzTmJ0ckNEMmREUTRpSDc4MkNuTzExZ1V5ZWltL1lJSWlybnY2Qnk1WndrYWpHeGtIb24yNFFSaVNlbQorZDFvNDE3K3Nodnp1WFlPOEJzYlJkMnNQYlNRdlMzcHNwd2VXeXVPRW42MklpeDJyRm8xYlpoZlpGdlNMZ05MZAorK0xKMncvdzRFNm9NM2tKcEsyN3pQT3VBSjl2MXBrUU5uMXBWV1F2VkRWSkl4YTZmOGkrQXhlb3lVRFVTbHk3QgorNGYveEk0aFJPSi95WmxaMjV3OVJsNlZTREUxSlVaVTJQYitpU3d3UUhZYVpUS3J6Y2hHVDVPcjJtOXFvWGFkTgordDU0Q3JuTUF5Tm9qQStqNTZobDBZZ0NVeXlJZ3ZwU25XYldDYXI2WmVYcXA4a29rVXZkMC9icE81cWdkQW02eAorRFlCRXdhN1RJemRmdTRWOEs1SXU2SDZsaTkyWjRiOG5ieTFkcW51SC9ncmRTL3lPOVNia2JuQkNialBzTVo1NworazhIa3lXa2FQY0JyVGlKdDdxdFlUY2JRUWNFcjZrOFNoMTdyUmRoczlaZ0MwNkRZVllvR21SbWlvSGZSTUo2cworekhYdWcvV3dZam5QYkZmaVROS1JDdzUxS0J1YXYvMGFRL0hLZC9zN2oyRzRhU2dXUWdSZWNDb2NJZGlQNGIwagorV3kxMFFKTFpZeGtOYzkxcHZHSkh2T0IwSzdMcmZiNUJHN1hBUnNXaElzdGZUc0Vva3Q0WXV0VXFLTHNSaXhlVAorbUpsZ2xGd2p6MW9ubDE0TEJRYVROeDQ3YVRicnFaNWhIWTh5Mm80TTFuUStld2trMmdGM1I4UTd6VFNNbWZYSworNFNWaE03SlpHK0p1MXpkWHRnMnBFdG89CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDE0NzggKDB4NWM2KQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPUJNLCBPPVF1b1ZhZGlzIExpbWl0ZWQsIENOPVF1b1ZhZGlzIFJvb3QgQ0EgMworICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTm92IDI0IDE5OjExOjIzIDIwMDYgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBOb3YgMjQgMTk6MDY6NDQgMjAzMSBHTVQKKyAgICAgICAgU3ViamVjdDogQz1CTSwgTz1RdW9WYWRpcyBMaW1pdGVkLCBDTj1RdW9WYWRpcyBSb290IENBIDMKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICg0MDk2IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICg0MDk2IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmNjOjU3OjQyOjE2OjU0OjljOmU2Ojk4OmQzOmQzOjRkOmVlOmZlOmVkOgorICAgICAgICAgICAgICAgICAgICBjNzo5Zjo0MzozOTo0YTo2NTpiMzplODoxNjo4ODozNDpkYjowZDo1OTo5MToKKyAgICAgICAgICAgICAgICAgICAgNzQ6Y2Y6OTI6Yjg6MDQ6NDA6YWQ6MDI6NGI6MzE6YWI6YmM6OGQ6OTE6Njg6CisgICAgICAgICAgICAgICAgICAgIGQ4OjIwOjBlOjFhOjAxOmUyOjFhOjdiOjRlOjE3OjVkOmUyOjhhOmI3OjNmOgorICAgICAgICAgICAgICAgICAgICA5OToxYTpjZDplYjo2MTphYjpjMjo2NTphNjoxZjpiNzpiNzpiZDpiNzo4ZjoKKyAgICAgICAgICAgICAgICAgICAgZmM6ZmQ6NzA6OGY6MGI6YTA6Njc6YmU6MDE6YTI6NTk6Y2Y6NzE6ZTY6MGY6CisgICAgICAgICAgICAgICAgICAgIDI5Ojc2OmZmOmIxOjU2Ojc5OjQ1OjJiOjFmOjllOjdhOjU0OmU4OmEzOjI5OgorICAgICAgICAgICAgICAgICAgICAzNTo2ODphNDowMTo0ZjowZjphNDoyZTozNzplZjoxYjpiZjplMzo4ZjoxMDoKKyAgICAgICAgICAgICAgICAgICAgYTg6NzI6YWI6NTg6NTc6ZTc6NTQ6ODY6Yzg6Yzk6ZjM6NWI6ZGE6MmM6ZGE6CisgICAgICAgICAgICAgICAgICAgIDVkOjhlOjZlOjNjOmEzOjNlOmRhOmZiOjgyOmU1OmRkOmYyOjVjOmIyOjA1OgorICAgICAgICAgICAgICAgICAgICAzMzo2Zjo4YTozNjpjZTpkMDoxMzo0ZTpmZjpiZjo0YTowYzozNDo0YzphNjoKKyAgICAgICAgICAgICAgICAgICAgYzM6MjE6YmQ6NTA6MDQ6NTU6ZWI6YjE6YmI6OWQ6ZmI6NDU6MWU6NjQ6MTU6CisgICAgICAgICAgICAgICAgICAgIGRlOjU1OjAxOjhjOjAyOjc2OmI1OmNiOmExOjNmOjQyOjY5OmJjOjJmOmJkOgorICAgICAgICAgICAgICAgICAgICA2ODo0MzoxNjo1Njo4OToyYTozNzo2MTo5MTpmZDphNjphZTo0ZTpjMDpjYjoKKyAgICAgICAgICAgICAgICAgICAgMTQ6NjU6OTQ6Mzc6NGI6OTI6MDY6ZWY6MDQ6ZDA6Yzg6OWM6ODg6ZGI6MGI6CisgICAgICAgICAgICAgICAgICAgIDdiOjgxOmFmOmIxOjNkOjJhOmM0OjY1OjNhOjc4OmI2OmVlOmRjOjgwOmIxOgorICAgICAgICAgICAgICAgICAgICBkMjpkMzo5OTo5YzozYTplZTo2Yjo1YTo2YjpiMzo4ZDpiNzpkNTpjZTo5YzoKKyAgICAgICAgICAgICAgICAgICAgYzI6YmU6YTU6NGI6MmY6MTY6YjE6OWU6Njg6M2I6MDY6NmY6YWU6N2Q6OWY6CisgICAgICAgICAgICAgICAgICAgIGY4OmRlOmVjOmNjOjI5OmE3Ojk4OmEzOjI1OjQzOjJmOmVmOmYxOjVmOjI2OgorICAgICAgICAgICAgICAgICAgICBlMTo4ODo0ZDpmODo1ZTo2ZTpkNzpkOToxNDo2ZToxOTozMzo2OTphNzozYjoKKyAgICAgICAgICAgICAgICAgICAgODQ6ODk6OTM6YzQ6NTM6NTU6MTM6YTE6NTE6Nzg6NDA6Zjg6Yjg6Yzk6YTI6CisgICAgICAgICAgICAgICAgICAgIGVlOjdiOmJhOjUyOjQyOjgzOjllOjE0OmVkOjA1OjUyOjVhOjU5OjU2OmE3OgorICAgICAgICAgICAgICAgICAgICA5NzpmYzo5ZDozZjowYToyOTpkODpkYzo0Zjo5MTowZToxMzpiYzpkZTo5NToKKyAgICAgICAgICAgICAgICAgICAgYTQ6ZGY6OGI6OTk6YmU6YWM6OWI6MzM6ODg6ZWY6YjU6ODE6YWY6MWI6YzY6CisgICAgICAgICAgICAgICAgICAgIDIyOjUzOmM4OmY2OmM3OmVlOjk3OjE0OmIwOmM1OjdjOjc4OjUyOmM4OmYwOgorICAgICAgICAgICAgICAgICAgICBjZTo2ZTo3Nzo2MDo4NDphNjplOToyYTo3NjoyMDplZDo1ODowMToxNzozMDoKKyAgICAgICAgICAgICAgICAgICAgOTM6ZTk6MWE6OGI6ZTA6NzM6NjM6ZDk6NmE6OTI6OTQ6NDk6NGU6YjQ6YWQ6CisgICAgICAgICAgICAgICAgICAgIDRhOjg1OmM0OmEzOjIyOjMwOmZjOjA5OmVkOjY4OjIyOjczOmE2Ojg4OjBjOgorICAgICAgICAgICAgICAgICAgICA1NToyMTo1ODpjNTplMTozYTo5ZjoyYTpkZDpjYTplMTo5MDplMDpkOTo3MzoKKyAgICAgICAgICAgICAgICAgICAgYWI6NmM6ODA6Yjg6ZTg6MGI6NjQ6OTM6YTA6OWM6OGM6MTk6ZmY6YjM6ZDI6CisgICAgICAgICAgICAgICAgICAgIDBjOmVjOjkxOjI2Ojg3OjhhOmIzOmEyOmUxOjcwOjhmOjJjOjBhOmU1OmNkOgorICAgICAgICAgICAgICAgICAgICA2ZDo2ODo1MTplYjpkYTozZjowNTo3Zjo4YjozMjplNjoxMzo1Yzo2YjpmZToKKyAgICAgICAgICAgICAgICAgICAgNWY6NDA6ZTI6MjI6Yzg6YjQ6YjQ6NjQ6NGY6ZDY6YmE6N2Q6NDg6M2U6YTg6CisgICAgICAgICAgICAgICAgICAgIDY5OjBjOmQ3OmJiOjg2OjcxOmM5OjczOmI4OjNmOjNiOjlkOjI1OjRiOmRhOgorICAgICAgICAgICAgICAgICAgICBmZjo0MDplYgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIENlcnRpZmljYXRlIFBvbGljaWVzOiAKKyAgICAgICAgICAgICAgICBQb2xpY3k6IDEuMy42LjEuNC4xLjgwMjQuMC4zCisgICAgICAgICAgICAgICAgICBVc2VyIE5vdGljZToKKyAgICAgICAgICAgICAgICAgICAgRXhwbGljaXQgVGV4dDogQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4KKyAgICAgICAgICAgICAgICAgIENQUzogaHR0cDovL3d3dy5xdW92YWRpc2dsb2JhbC5jb20vY3BzCisKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgRjI6QzA6MTM6RTA6ODI6NDM6M0U6RkI6RUU6MkY6Njc6MzI6OTY6MzU6NUM6REI6Qjg6Q0I6MDI6RDAKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOkYyOkMwOjEzOkUwOjgyOjQzOjNFOkZCOkVFOjJGOjY3OjMyOjk2OjM1OjVDOkRCOkI4OkNCOjAyOkQwCisgICAgICAgICAgICAgICAgRGlyTmFtZTovQz1CTS9PPVF1b1ZhZGlzIExpbWl0ZWQvQ049UXVvVmFkaXMgUm9vdCBDQSAzCisgICAgICAgICAgICAgICAgc2VyaWFsOjA1OkM2CisKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgNGY6YWQ6YTA6MmM6NGM6ZmE6YzA6ZjI6NmY6Zjc6NjY6NTU6YWI6MjM6MzQ6ZWU6ZTc6Mjk6CisgICAgICAgIGRhOmMzOjViOmI2OmIwOjgzOmQ5OmQwOmQwOmUyOjIxOmZiOmYzOjYwOmE3OjNiOjVkOjYwOgorICAgICAgICA1MzoyNzphMjo5YjpmNjowODoyMjoyYTplNzpiZjphMDo3MjplNTo5YzoyNDo2YTozMTpiMToKKyAgICAgICAgOTA6N2E6Mjc6ZGI6ODQ6MTE6ODk6Mjc6YTY6Nzc6NWE6Mzg6ZDc6YmY6YWM6ODY6ZmM6ZWU6CisgICAgICAgIDVkOjgzOmJjOjA2OmM2OmQxOjc3OjZiOjBmOjZkOjI0OjJmOjRiOjdhOjZjOmE3OjA3Ojk2OgorICAgICAgICBjYTplMzo4NDo5ZjphZDo4ODo4YjoxZDphYjoxNjo4ZDo1Yjo2NjoxNzpkOToxNjpmNDo4YjoKKyAgICAgICAgODA6ZDI6ZGQ6Zjg6YjI6NzY6YzM6ZmM6Mzg6MTM6YWE6MGM6ZGU6NDI6Njk6MmI6NmU6ZjM6CisgICAgICAgIDNjOmViOjgwOjI3OmRiOmY1OmE2OjQ0OjBkOjlmOjVhOjU1OjU5OjBiOmQ1OjBkOjUyOjQ4OgorICAgICAgICBjNTphZTo5ZjpmMjoyZjo4MDpjNTplYTozMjo1MDozNToxMjo5NzoyZTpjMTplMTpmZjpmMToKKyAgICAgICAgMjM6ODg6NTE6Mzg6OWY6ZjI6NjY6NTY6NzY6ZTc6MGY6NTE6OTc6YTU6NTI6MGM6NGQ6NDk6CisgICAgICAgIDUxOjk1OjM2OjNkOmJmOmEyOjRiOjBjOjEwOjFkOjg2Ojk5OjRjOmFhOmYzOjcyOjExOjkzOgorICAgICAgICBlNDplYTpmNjo5YjpkYTphODo1ZDphNzo0ZDpiNzo5ZTowMjphZTo3MzowMDpjODpkYToyMzoKKyAgICAgICAgMDM6ZTg6Zjk6ZWE6MTk6NzQ6NjI6MDA6OTQ6Y2I6MjI6MjA6YmU6OTQ6YTc6NTk6YjU6ODI6CisgICAgICAgIDZhOmJlOjk5Ojc5OjdhOmE5OmYyOjRhOjI0OjUyOmY3Ojc0OmZkOmJhOjRlOmU2OmE4OjFkOgorICAgICAgICAwMjo2ZTpiMTowZDo4MDo0NDpjMTphZTpkMzoyMzozNzo1ZjpiYjo4NTo3YzoyYjo5MjoyZToKKyAgICAgICAgZTg6N2U6YTU6OGI6ZGQ6OTk6ZTE6YmY6Mjc6NmY6MmQ6NWQ6YWE6N2I6ODc6ZmU6MGE6ZGQ6CisgICAgICAgIDRiOmZjOjhlOmY1OjI2OmU0OjZlOjcwOjQyOjZlOjMzOmVjOjMxOjllOjdiOjkzOmMxOmU0OgorICAgICAgICBjOTo2OToxYTozZDpjMDo2Yjo0ZToyMjo2ZDplZTphYjo1ODo0ZDpjNjpkMDo0MTpjMToyYjoKKyAgICAgICAgZWE6NGY6MTI6ODc6NWU6ZWI6NDU6ZDg6NmM6ZjU6OTg6MDI6ZDM6YTA6ZDg6NTU6OGE6MDY6CisgICAgICAgIDk5OjE5OmEyOmEwOjc3OmQxOjMwOjllOmFjOmNjOjc1OmVlOjgzOmY1OmIwOjYyOjM5OmNmOgorICAgICAgICA2Yzo1NzplMjo0YzpkMjo5MTowYjowZTo3NToyODoxYjo5YTpiZjpmZDoxYTo0MzpmMTpjYToKKyAgICAgICAgNzc6ZmI6M2I6OGY6NjE6Yjg6Njk6Mjg6MTY6NDI6MDQ6NWU6NzA6MmE6MWM6MjE6ZDg6OGY6CisgICAgICAgIGUxOmJkOjIzOjViOjJkOjc0OjQwOjkyOmQ5OjYzOjE5OjBkOjczOmRkOjY5OmJjOjYyOjQ3OgorICAgICAgICBiYzplMDo3NDoyYjpiMjplYjo3ZDpiZTo0MToxYjpiNTpjMDo0NjpjNTphMToyMjpjYjo1ZjoKKyAgICAgICAgNGU6YzE6Mjg6OTI6ZGU6MTg6YmE6ZDU6MmE6Mjg6YmI6MTE6OGI6MTc6OTM6OTg6OTk6NjA6CisgICAgICAgIDk0OjVjOjIzOmNmOjVhOjI3Ojk3OjVlOjBiOjA1OjA2OjkzOjM3OjFlOjNiOjY5OjM2OmViOgorICAgICAgICBhOTo5ZTo2MToxZDo4ZjozMjpkYTo4ZTowYzpkNjo3NDozZTo3YjowOToyNDpkYTowMTo3NzoKKyAgICAgICAgNDc6YzQ6M2I6Y2Q6MzQ6OGM6OTk6ZjU6Y2E6ZTE6MjU6NjE6MzM6YjI6NTk6MWI6ZTI6NmU6CisgICAgICAgIGQ3OjM3OjU3OmI2OjBkOmE5OjEyOmRhCitTSEExIEZpbmdlcnByaW50PTFGOjQ5OjE0OkY3OkQ4Ojc0Ojk1OjFEOkREOkFFOjAyOkMwOkJFOkZEOjNBOjJEOjgyOjc1OjUxOjg1CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvOTVhZmY5ZTMuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy85NWFmZjllMy4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4ZGUzYWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvOTVhZmY5ZTMuMApAQCAtMCwwICsxLDc5IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUR1ekNDQXFPZ0F3SUJBZ0lEQkVUQU1BMEdDU3FHU0liM0RRRUJCUVVBTUg0eEN6QUpCZ05WQkFZVEFsQk0KK01TSXdJQVlEVlFRS0V4bFZibWw2WlhSdklGUmxZMmh1YjJ4dloybGxjeUJUTGtFdU1TY3dKUVlEVlFRTEV4NUQKK1pYSjBkVzBnUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa3hJakFnQmdOVkJBTVRHVU5sY25SMWJTQlUKK2NuVnpkR1ZrSUU1bGRIZHZjbXNnUTBFd0hoY05NRGd4TURJeU1USXdOek0zV2hjTk1qa3hNak14TVRJd056TTMKK1dqQitNUXN3Q1FZRFZRUUdFd0pRVERFaU1DQUdBMVVFQ2hNWlZXNXBlbVYwYnlCVVpXTm9ibTlzYjJkcFpYTWcKK1V5NUJMakVuTUNVR0ExVUVDeE1lUTJWeWRIVnRJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1TSXcKK0lBWURWUVFERXhsRFpYSjBkVzBnVkhKMWMzUmxaQ0JPWlhSM2IzSnJJRU5CTUlJQklqQU5CZ2txaGtpRzl3MEIKK0FRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTQvdDlvM0s2d3ZESkZJZjFhd0ZPNFc1QUI3cHRKMTEvOTFzdHMxckgKK1VWK3JwREttWVllMmJnK0cwakFDbC9qWGFWZWhHRGxkYW1SNXhnRlpyRHd4U2poODBnVFNTeWpvSUY4N0I2TE0KK1RYUGI4NjVQeDFiVldxZVdpZnJ6cTJqVUk0WlpKODhKSjd5c2JuS0RIREJ5MytDaTZkTGhkSFVadlNxZWV4VlUKK0JCdlhRem10VlNqRjRocTc5TURrcmpoSk04eDJoWjg1UmRLa252SVNqRkg0Zk9RdGYvV3NYK3NXbjdFdDBick0KK2tVSjNUQ1hKa0RodjIvRE0rNDRlbDFrKzFXQk81Z1VvN1VsNUUwdTZTTnN2K1hMVE9jcitIOWcwY3ZXMFFNOHgKK0FjUHMzaEV0RjEwZnVGRFJYaG1uYWQ0SE15aktVSlg1cDFUTFZJWlFSYW41U1FJREFRQUJvMEl3UURBUEJnTlYKK0hSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlFJZHMzTEIvOGs5c1hON2J1UXZPS0VOMFoxOXpBT0JnTlYKK0hROEJBZjhFQkFNQ0FRWXdEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBS2FvclNMT0FUMm1vLzlpMEVpZGkxNXkKK3NIaEU0OXdjcnduOUkwajZ2U3JFdVZVRXRSQ2pqU2ZlQzRKajBPN2VERGQ1UVZzaXNyQ2FRVnltY09EVTBIZkwKK0k5TUE0R3hXTCtGcERRM1pxcjhoZ1ZEWkJxV28vNVUzMEtyKzRyUDFtUzFGaElybFFnblhkQUl2OTRuWW1lbTgKK0o5UkhqYm9OUmh4M3p4U2tITG1rTWNTY0tIUUROUDh6R1NhbDZRMTB0ejZYeG5ib0o1YWpadDNocnZKQlc4cVkKK1ZvTnpjT1NHR3RJeFFib3Z2aTBUV25adlR1aE9nUTQvV3dNaW9CSytabGdSU3NzRHhMUXFLaTJXRitBNVZMeEkKKzAzWW5uWm90QnFiSjdEblNxOXVmbWdzbkFqVXBzVUNWNS9ub25GV0lHVWJXdHpUMWZzNDVtdGs0OFZIM1R5dz0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMjc5NzQ0ICgweDQ0NGMwKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVBMLCBPPVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4sIE9VPUNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSwgQ049Q2VydHVtIFRydXN0ZWQgTmV0d29yayBDQQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogT2N0IDIyIDEyOjA3OjM3IDIwMDggR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBEZWMgMzEgMTI6MDc6MzcgMjAyOSBHTVQKKyAgICAgICAgU3ViamVjdDogQz1QTCwgTz1Vbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuLCBPVT1DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHksIENOPUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmUzOmZiOjdkOmEzOjcyOmJhOmMyOmYwOmM5OjE0Ojg3OmY1OjZiOjAxOgorICAgICAgICAgICAgICAgICAgICA0ZTplMTo2ZTo0MDowNzpiYTo2ZDoyNzo1ZDo3ZjpmNzo1YjoyZDpiMzo1YToKKyAgICAgICAgICAgICAgICAgICAgYzc6NTE6NWY6YWI6YTQ6MzI6YTY6NjE6ODc6YjY6NmU6MGY6ODY6ZDI6MzA6CisgICAgICAgICAgICAgICAgICAgIDAyOjk3OmY4OmQ3OjY5OjU3OmExOjE4OjM5OjVkOjZhOjY0Ojc5OmM2OjAxOgorICAgICAgICAgICAgICAgICAgICA1OTphYzozYzozMTo0YTozODo3YzpkMjowNDpkMjo0YjoyODplODoyMDo1ZjoKKyAgICAgICAgICAgICAgICAgICAgM2I6MDc6YTI6Y2M6NGQ6NzM6ZGI6ZjM6YWU6NGY6Yzc6NTY6ZDU6NWE6YTc6CisgICAgICAgICAgICAgICAgICAgIDk2Ojg5OmZhOmYzOmFiOjY4OmQ0OjIzOjg2OjU5OjI3OmNmOjA5OjI3OmJjOgorICAgICAgICAgICAgICAgICAgICBhYzo2ZTo3Mjo4MzoxYzozMDo3MjpkZjplMDphMjplOTpkMjplMTo3NDo3NToKKyAgICAgICAgICAgICAgICAgICAgMTk6YmQ6MmE6OWU6N2I6MTU6NTQ6MDQ6MWI6ZDc6NDM6Mzk6YWQ6NTU6Mjg6CisgICAgICAgICAgICAgICAgICAgIGM1OmUyOjFhOmJiOmY0OmMwOmU0OmFlOjM4OjQ5OjMzOmNjOjc2Ojg1OjlmOgorICAgICAgICAgICAgICAgICAgICAzOTo0NTpkMjphNDo5ZTpmMjoxMjo4Yzo1MTpmODo3YzplNDoyZDo3ZjpmNToKKyAgICAgICAgICAgICAgICAgICAgYWM6NWY6ZWI6MTY6OWY6YjE6MmQ6ZDE6YmE6Y2M6OTE6NDI6Nzc6NGM6MjU6CisgICAgICAgICAgICAgICAgICAgIGM5OjkwOjM4OjZmOmRiOmYwOmNjOmZiOjhlOjFlOjk3OjU5OjNlOmQ1OjYwOgorICAgICAgICAgICAgICAgICAgICA0ZTplNjowNToyODplZDo0OTo3OToxMzo0YjpiYTo0ODpkYjoyZjpmOTo3MjoKKyAgICAgICAgICAgICAgICAgICAgZDM6Mzk6Y2E6ZmU6MWY6ZDg6MzQ6NzI6ZjU6YjQ6NDA6Y2Y6MzE6MDE6YzM6CisgICAgICAgICAgICAgICAgICAgIGVjOmRlOjExOjJkOjE3OjVkOjFmOmI4OjUwOmQxOjVlOjE5OmE3OjY5OmRlOgorICAgICAgICAgICAgICAgICAgICAwNzozMzoyODpjYTo1MDo5NTpmOTphNzo1NDpjYjo1NDo4Njo1MDo0NTphOToKKyAgICAgICAgICAgICAgICAgICAgZjk6NDkKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICAwODo3NjpDRDpDQjowNzpGRjoyNDpGNjpDNTpDRDpFRDpCQjo5MDpCQzpFMjo4NDozNzo0Njo3NTpGNworICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBhNjphODphZDoyMjpjZTowMTozZDphNjphMzpmZjo2MjpkMDo0ODo5ZDo4Yjo1ZTo3MjpiMDoKKyAgICAgICAgNzg6NDQ6ZTM6ZGM6MWM6YWY6MDk6ZmQ6MjM6NDg6ZmE6YmQ6MmE6YzQ6Yjk6NTU6MDQ6YjU6CisgICAgICAgIDEwOmEzOjhkOjI3OmRlOjBiOjgyOjYzOmQwOmVlOmRlOjBjOjM3Ojc5OjQxOjViOjIyOmIyOgorICAgICAgICBiMDo5YTo0MTo1YzphNjo3MDplMDpkNDpkMDo3NzpjYjoyMzpkMzowMDplMDo2Yzo1NjoyZjoKKyAgICAgICAgZTE6Njk6MGQ6MGQ6ZDk6YWE6YmY6MjE6ODE6NTA6ZDk6MDY6YTU6YTg6ZmY6OTU6Mzc6ZDA6CisgICAgICAgIGFhOmZlOmUyOmIzOmY1Ojk5OjJkOjQ1Ojg0OjhhOmU1OjQyOjA5OmQ3Ojc0OjAyOjJmOmY3OgorICAgICAgICA4OTpkODo5OTplOTpiYzoyNzpkNDo0Nzo4ZDpiYTowZDo0NjoxYzo3NzpjZjoxNDphNDoxYzoKKyAgICAgICAgYjk6YTQ6MzE6YzQ6OWM6Mjg6NzQ6MDM6MzQ6ZmY6MzM6MTk6MjY6YTU6ZTk6MGQ6NzQ6Yjc6CisgICAgICAgIDNlOjk3OmM2Ojc2OmU4OjI3Ojk2OmEzOjY2OmRkOmUxOmFlOmYyOjQxOjViOmNhOjk4OjU2OgorICAgICAgICA4Mzo3Mzo3MDplNDo4NjoxYTpkMjozMTo0MTpiYToyZjpiZToyZDoxMzo1YTo3Njo2Zjo0ZToKKyAgICAgICAgZTg6NGU6ODE6MGU6M2Y6NWI6MDM6MjI6YTA6MTI6YmU6NjY6NTg6MTE6NGE6Y2I6MDM6YzQ6CisgICAgICAgIGI0OjJhOjJhOjJkOjk2OjE3OmUwOjM5OjU0OmJjOjQ4OmQzOjc2OjI3OjlkOjlhOjJkOjA2OgorICAgICAgICBhNjpjOTplYzozOTpkMjphYjpkYjo5Zjo5YTowYjoyNzowMjozNToyOTpiMTo0MDo5NTplNzoKKyAgICAgICAgZjk6ZTg6OWM6NTU6ODg6MTk6NDY6ZDY6Yjc6MzQ6ZjU6N2U6Y2U6Mzk6OWE6ZDk6Mzg6ZjE6CisgICAgICAgIDUxOmY3OjRmOjJjCitTSEExIEZpbmdlcnByaW50PTA3OkUwOjMyOkUwOjIwOkI3OjJDOjNGOjE5OjJGOjA2OjI4OkEyOjU5OjNBOjE5OkE3OjBGOjA2OjlFCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvOTY4NWE0OTMuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy85Njg1YTQ5My4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE3YmNlNDUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvOTY4NWE0OTMuMApAQCAtMCwwICsxLDc1IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSURNRENDQWhpZ0F3SUJBZ0lDQStnd0RRWUpLb1pJaHZjTkFRRUZCUUF3UnpFTE1Ba0dBMVVFQmhNQ1NFc3gKK0ZqQVVCZ05WQkFvVERVaHZibWRyYjI1bklGQnZjM1F4SURBZUJnTlZCQU1URjBodmJtZHJiMjVuSUZCdmMzUWcKK1VtOXZkQ0JEUVNBeE1CNFhEVEF6TURVeE5UQTFNVE14TkZvWERUSXpNRFV4TlRBME5USXlPVm93UnpFTE1Ba0cKK0ExVUVCaE1DU0VzeEZqQVVCZ05WQkFvVERVaHZibWRyYjI1bklGQnZjM1F4SURBZUJnTlZCQU1URjBodmJtZHIKK2IyNW5JRkJ2YzNRZ1VtOXZkQ0JEUVNBeE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0MKK0FRRUFyUDg0dHVsbUFrbmpvclRoa1BsQWozbjU0cjE1L2dLOTdpU1NIU0wyMm9WeWFmN1hQd25VM1pHMUFwelEKK2pWcmhWY05RaHJrcEpzTGoyYUR4YVFNb0lJQkZJaTFXcHp0VWxWWWlXUjhvM3g4Z1BXMmlOcjRqb0xGdXRiRW4KK1B6bFRDZXFyYXVoMHNzSmxYSTYvZk1ONGhNMmVGdnoxTGs4Z0tnaWZkL1BGSHNTYVVtWWVTRjdqRUFhUElwamgKK1pZNGJYU05tTzdpbE1sSElocXFocVo1L2RwVENwbXkzUWZEVnlBWTQ1dFFNNHZNN1RHMVFqTVNESjhFVGhGazkKK25uVjB0dGdDWGpxUWVzQkNObkxzYWszYzc4UUEzeE1ZVjE4bWVNaldDbmwzdi9ldnQzYTVwUXVFRjEwUTZtL2gKK3E1VVJYMjA4bzF4TmcxdnlzeG1LZ0lzTGh3SURBUUFCb3lZd0pEQVNCZ05WSFJNQkFmOEVDREFHQVFIL0FnRUQKK01BNEdBMVVkRHdFQi93UUVBd0lCeGpBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQURrYlZQSzdpaDlsZWdZc0MKK21FRUlqRXk4MnR2dUp4dUM1MnBGN0JhTFQ0V2c4N0p3dlZxV3VzcHViZTVHaTI3bktpNldzeGt6NjdTZnFMSTMKKzdwaW9sN1l1dG1jbjFLWkovUnlUWlhhZVFpL2NJbXlhVC9KYUZUbXhjZGNyVWVodEhKakEyU3Iwb1lKNzFjbEIKK29pTUJkRGhWaXcrNUxtZWlJQVEzMnB3TDB4Y2g0SStYZVRSdmhFZ0NJRE1iNWpSRW41Rnc5SUJlaEVQQ0tkSnMKK0VoVGtZWTJzRUpDZWhGQzc4Slp2UlorSzg4cHNUL29ST2hVVlJzUE5INE5iTFVFUzdWQm5RUk05SWF1VWlxcE8KK2ZNR3grNmZXdFNjdmw2dHU0QjNpMFJ3c0gwVGkvTDZSb1p6NzFpbFRjNGFmVTloRERsM1dZNEp4SFlCMHl2YmkKK0FtdlpXZz09CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDEwMDAgKDB4M2U4KQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPUhLLCBPPUhvbmdrb25nIFBvc3QsIENOPUhvbmdrb25nIFBvc3QgUm9vdCBDQSAxCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBNYXkgMTUgMDU6MTM6MTQgMjAwMyBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IE1heSAxNSAwNDo1MjoyOSAyMDIzIEdNVAorICAgICAgICBTdWJqZWN0OiBDPUhLLCBPPUhvbmdrb25nIFBvc3QsIENOPUhvbmdrb25nIFBvc3QgUm9vdCBDQSAxCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDphYzpmZjozODpiNjplOTo2NjowMjo0OTplMzphMjpiNDplMTo5MDpmOToKKyAgICAgICAgICAgICAgICAgICAgNDA6OGY6Nzk6Zjk6ZTI6YmQ6Nzk6ZmU6MDI6YmQ6ZWU6MjQ6OTI6MWQ6MjI6CisgICAgICAgICAgICAgICAgICAgIGY2OmRhOjg1OjcyOjY5OmZlOmQ3OjNmOjA5OmQ0OmRkOjkxOmI1OjAyOjljOgorICAgICAgICAgICAgICAgICAgICBkMDo4ZDo1YTplMTo1NTpjMzo1MDo4NjpiOToyOToyNjpjMjplMzpkOTphMDoKKyAgICAgICAgICAgICAgICAgICAgZjE6Njk6MDM6Mjg6MjA6ODA6NDU6MjI6MmQ6NTY6YTc6M2I6NTQ6OTU6NTY6CisgICAgICAgICAgICAgICAgICAgIDIyOjU5OjFmOjI4OmRmOjFmOjIwOjNkOjZkOmEyOjM2OmJlOjIzOmEwOmIxOgorICAgICAgICAgICAgICAgICAgICA2ZTpiNTpiMToyNzozZjozOTo1MzowOTplYTphYjo2YTplODo3NDpiMjpjMjoKKyAgICAgICAgICAgICAgICAgICAgNjU6NWM6OGU6YmY6N2M6YzM6Nzg6ODQ6Y2Q6OWU6MTY6ZmM6ZjU6MmU6NGY6CisgICAgICAgICAgICAgICAgICAgIDIwOjJhOjA4OjlmOjc3OmYzOmM1OjFlOmM0OjlhOjUyOjY2OjFlOjQ4OjVlOgorICAgICAgICAgICAgICAgICAgICBlMzoxMDowNjo4ZjoyMjo5ODplMTo2NTo4ZToxYjo1ZDoyMzo2NjozYjpiODoKKyAgICAgICAgICAgICAgICAgICAgYTU6MzI6NTE6Yzg6ODY6YWE6YTE6YTk6OWU6N2Y6NzY6OTQ6YzI6YTY6NmM6CisgICAgICAgICAgICAgICAgICAgIGI3OjQxOmYwOmQ1OmM4OjA2OjM4OmU2OmQ0OjBjOmUyOmYzOjNiOjRjOjZkOgorICAgICAgICAgICAgICAgICAgICA1MDo4YzpjNDo4MzoyNzpjMToxMzo4NDo1OTozZDo5ZTo3NTo3NDpiNjpkODoKKyAgICAgICAgICAgICAgICAgICAgMDI6NWU6M2E6OTA6N2E6YzA6NDI6MzY6NzI6ZWM6NmE6NGQ6ZGM6ZWY6YzQ6CisgICAgICAgICAgICAgICAgICAgIDAwOmRmOjEzOjE4OjU3OjVmOjI2Ojc4OmM4OmQ2OjBhOjc5Ojc3OmJmOmY3OgorICAgICAgICAgICAgICAgICAgICBhZjpiNzo3NjpiOTphNTowYjo4NDoxNzo1ZDoxMDplYTo2ZjplMTphYjo5NToKKyAgICAgICAgICAgICAgICAgICAgMTE6NWY6NmQ6M2M6YTM6NWM6NGQ6ODM6NWI6ZjI6YjM6MTk6OGE6ODA6OGI6CisgICAgICAgICAgICAgICAgICAgIDBiOjg3CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFLCBwYXRobGVuOjMKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgRGlnaXRhbCBTaWduYXR1cmUsIE5vbiBSZXB1ZGlhdGlvbiwgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMGU6NDY6ZDU6M2M6YWU6ZTI6ODc6ZDk6NWU6ODE6OGI6MDI6OTg6NDE6MDg6OGM6NGM6YmM6CisgICAgICAgIGRhOmRiOmVlOjI3OjFiOjgyOmU3OjZhOjQ1OmVjOjE2OjhiOjRmOjg1OmEwOmYzOmIyOjcwOgorICAgICAgICBiZDo1YTo5NjpiYTpjYTo2ZTo2ZDplZTo0Njo4Yjo2ZTplNzoyYToyZTo5NjpiMzoxOTozMzoKKyAgICAgICAgZWI6YjQ6OWY6YTg6YjI6Mzc6ZWU6OTg6YTg6OTc6YjY6MmU6YjY6Njc6Mjc6ZDQ6YTY6NDk6CisgICAgICAgIGZkOjFjOjkzOjY1Ojc2OjllOjQyOjJmOmRjOjIyOjZjOjlhOjRmOmYyOjVhOjE1OjM5OmIxOgorICAgICAgICA3MTpkNzoyYjo1MTplODo2ZDoxYzo5ODpjMDpkOToyYTpmNDphMTo4Mjo3YjpkNTpjOTo0MToKKyAgICAgICAgYTI6MjM6MDE6NzQ6Mzg6NTU6OGI6MGY6Yjk6MmU6Njc6YTI6MjA6MDQ6Mzc6ZGE6OWM6MGI6CisgICAgICAgIGQzOjE3OjIxOmUwOjhmOjk3Ojc5OjM0OjZmOjg0OjQ4OjAyOjIwOjMzOjFiOmU2OjM0OjQ0OgorICAgICAgICA5Zjo5MTo3MDpmNDo4MDo1ZTo4NDo0MzpjMjoyOTpkMjo2YzoxMjoxNDplNDo2MTo4ZDphYzoKKyAgICAgICAgMTA6OTA6OWU6ODQ6NTA6YmI6ZjA6OTY6NmY6NDU6OWY6OGE6ZjM6Y2E6NmM6NGY6ZmE6MTE6CisgICAgICAgIDNhOjE1OjE1OjQ2OmMzOmNkOjFmOjgzOjViOjJkOjQxOjEyOmVkOjUwOjY3OjQxOjEzOjNkOgorICAgICAgICAyMTphYjo5NDo4YTphYTo0ZTo3YzpjMTpiMTpmYjphNzpkNjpiNToyNzoyZjo5NzphYjo2ZToKKyAgICAgICAgZTA6MWQ6ZTI6ZDE6MWM6MmM6MWY6NDQ6ZTI6ZmM6YmU6OTE6YTE6OWM6ZmI6ZDY6Mjk6NTM6CisgICAgICAgIDczOjg2OjlmOjUzOmQ4OjQzOjBlOjVkOmQ2OjYzOjgyOjcxOjFkOjgwOjc0OmNhOmY2OmUyOgorICAgICAgICAwMjo2YjpkOTo1YQorU0hBMSBGaW5nZXJwcmludD1ENjpEQTpBODoyMDo4RDowOTpEMjoxNTo0RDoyNDpCNToyRjpDQjozNDo2RTpCMjo1ODpCMjo4QTo1OApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzk3NzJjYTMyLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvOTc3MmNhMzIuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYTJjNjViCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzk3NzJjYTMyLjAKQEAgLTAsMCArMSw3OSBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEZkRDQ0FtU2dBd0lCQWdJUUdLeTFhdjFwdGhVNlkyeXYydnJFb1RBTkJna3Foa2lHOXcwQkFRVUZBREJZCitNUXN3Q1FZRFZRUUdFd0pWVXpFV01CUUdBMVVFQ2hNTlIyVnZWSEoxYzNRZ1NXNWpMakV4TUM4R0ExVUVBeE1vCitSMlZ2VkhKMWMzUWdVSEpwYldGeWVTQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVRBZUZ3MHdOakV4CitNamN3TURBd01EQmFGdzB6TmpBM01UWXlNelU1TlRsYU1GZ3hDekFKQmdOVkJBWVRBbFZUTVJZd0ZBWURWUVFLCitFdzFIWlc5VWNuVnpkQ0JKYm1NdU1URXdMd1lEVlFRREV5aEhaVzlVY25WemRDQlFjbWx0WVhKNUlFTmxjblJwCitabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDCitBUUVBdnJnVmUvL1VmSDFucllOa2U4aENVeTNmOW9RSUlHSFdBVmxxbkVRUnIrOTIvWlYrem1Fd3UzcURYd0s5CitBV2JLN2hXTmI2RXduTDJoaFo2VU92TldpQUF4ejlqdWFwWUMyZTBEalB0MWJlZnF1RlVXQlJhYTlPQmVzWWpBCitaSVZjRlUySXg3ZTY0SFhwclFVOW5jZUpTT0M3S01nRDRUQ1RaRjVTd0Zsd0lqVlhpSXJ4bFFxRDE3d3hjd0UwCis3ZTlHY2VCckFxZzFjbXVYbTJiZ3l4eDVYOWdhQkdnZVJ3TG1uV0RpTnBjQjM4NDFrdCsrWjhkdGQxazdqNTNXCitrQldVdkVJMEVNRTUrYkVuUG43V2luWEZzcStXMDZMZW0rU1l2bjNoNllHdHRtLzgxdzdhNERTd0RScDM1K01JCittTzlZK3B5RXR6YXZ3dCtzMHZRUUJuQnhOUUlEQVFBQm8wSXdRREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTRHCitBMVVkRHdFQi93UUVBd0lCQmpBZEJnTlZIUTRFRmdRVUxOVlFRWmNWaS9DUE5tRmJTdnRyMlpuSk01SXdEUVlKCitLb1pJaHZjTkFRRUZCUUFEZ2dFQkFGcHdmeXpkdHpSUDlZWlJxU2ErUzdpcThYRU4zR0hIb09vMEhucDNEd1ExCis2Q2VQYkpDL2tSWWtSajVLVHM0ckZ0VUxVaDM4SDJlaUFrVXhUODd6K2dPbmVaMVRhdG5hWXpyNGdOZlRtZUdsCis0YjdVVlhHWU5UcStrK3F1clVLeWtHL2cvQ0ZOTldNemlVbldtMDdLeCtkT0NRRDMyc2Z2bVdLWmQ3YVZJbDZLCitvS3YwdUhpWXlqZ1ptY2x5bm5qTlM2eXZHYUJ6RWkzOHdrRzZnWkhhRmxveHQvbTBjWUFTU0pseWMxcFpVOEZqCitValB0cDhuU09RSncrdUN4UW1ZcHFwdFI3VEJVSWhSZjJhc2R3ZVNVOFBqMUsvZnF5bmhHMXJpUi9hWU5LeG9VCitBVDZBOEVLZ2xRZGViYzNNUzZSRmphc1M2TFBlV3VXZ2ZPZ1BJaDFhNlZrPQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgMTg6YWM6YjU6NmE6ZmQ6Njk6YjY6MTU6M2E6NjM6NmM6YWY6ZGE6ZmE6YzQ6YTEKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgTz1HZW9UcnVzdCBJbmMuLCBDTj1HZW9UcnVzdCBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5CisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBOb3YgMjcgMDA6MDA6MDAgMjAwNiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEp1bCAxNiAyMzo1OTo1OSAyMDM2IEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPUdlb1RydXN0IEluYy4sIENOPUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmJlOmI4OjE1OjdiOmZmOmQ0OjdjOjdkOjY3OmFkOjgzOjY0OjdiOmM4OgorICAgICAgICAgICAgICAgICAgICA0Mjo1MzoyZDpkZjpmNjo4NDowODoyMDo2MTpkNjowMTo1OTo2YTo5Yzo0NDoKKyAgICAgICAgICAgICAgICAgICAgMTE6YWY6ZWY6NzY6ZmQ6OTU6N2U6Y2U6NjE6MzA6YmI6N2E6ODM6NWY6MDI6CisgICAgICAgICAgICAgICAgICAgIGJkOjAxOjY2OmNhOmVlOjE1OjhkOjZmOmExOjMwOjljOmJkOmExOjg1OjllOgorICAgICAgICAgICAgICAgICAgICA5NDozYTpmMzo1Njo4ODowMDozMTpjZjpkODplZTo2YTo5NjowMjpkOTplZDoKKyAgICAgICAgICAgICAgICAgICAgMDM6OGM6ZmI6NzU6NmQ6ZTc6ZWE6Yjg6NTU6MTY6MDU6MTY6OWE6ZjQ6ZTA6CisgICAgICAgICAgICAgICAgICAgIDVlOmIxOjg4OmMwOjY0Ojg1OjVjOjE1OjRkOjg4OmM3OmI3OmJhOmUwOjc1OgorICAgICAgICAgICAgICAgICAgICBlOTphZDowNTozZDo5ZDpjNzo4OTo0ODplMDpiYjoyODpjODowMzplMTozMDoKKyAgICAgICAgICAgICAgICAgICAgOTM6NjQ6NWU6NTI6YzA6NTk6NzA6MjI6MzU6NTc6ODg6OGE6ZjE6OTU6MGE6CisgICAgICAgICAgICAgICAgICAgIDgzOmQ3OmJjOjMxOjczOjAxOjM0OmVkOmVmOjQ2OjcxOmUwOjZiOjAyOmE4OgorICAgICAgICAgICAgICAgICAgICAzNTo3Mjo2Yjo5Nzo5Yjo2NjplMDpjYjoxYzo3OTo1ZjpkODoxYTowNDo2ODoKKyAgICAgICAgICAgICAgICAgICAgMWU6NDc6MDI6ZTY6OWQ6NjA6ZTI6MzY6OTc6MDE6ZGY6Y2U6MzU6OTI6ZGY6CisgICAgICAgICAgICAgICAgICAgIGJlOjY3OmM3OjZkOjc3OjU5OjNiOjhmOjlkOmQ2OjkwOjE1Ojk0OmJjOjQyOgorICAgICAgICAgICAgICAgICAgICAzNDoxMDpjMTozOTpmOTpiMToyNzozZTo3ZTpkNjo4YTo3NTpjNTpiMjphZjoKKyAgICAgICAgICAgICAgICAgICAgOTY6ZDM6YTI6ZGU6OWI6ZTQ6OTg6YmU6N2Q6ZTE6ZTk6ODE6YWQ6YjY6NmY6CisgICAgICAgICAgICAgICAgICAgIGZjOmQ3OjBlOmRhOmUwOjM0OmIwOjBkOjFhOjc3OmU3OmUzOjA4Ojk4OmVmOgorICAgICAgICAgICAgICAgICAgICA1ODpmYTo5Yzo4NDpiNzozNjphZjpjMjpkZjphYzpkMjpmNDoxMDowNjo3MDoKKyAgICAgICAgICAgICAgICAgICAgNzE6MzUKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICAyQzpENTo1MDo0MTo5NzoxNTo4QjpGMDo4RjozNjo2MTo1Qjo0QTpGQjo2QjpEOTo5OTpDOTozMzo5MgorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA1YTo3MDo3ZjoyYzpkZDpiNzozNDo0ZjpmNTo4Njo1MTphOToyNjpiZTo0YjpiODphYTpmMToKKyAgICAgICAgNzE6MGQ6ZGM6NjE6Yzc6YTA6ZWE6MzQ6MWU6N2E6Nzc6MGY6MDQ6MzU6ZTg6Mjc6OGY6NmM6CisgICAgICAgIDkwOmJmOjkxOjE2OjI0OjQ2OjNlOjRhOjRlOmNlOjJiOjE2OmQ1OjBiOjUyOjFkOmZjOjFmOgorICAgICAgICA2NzphMjowMjo0NTozMTo0ZjpjZTpmMzpmYTowMzphNzo3OTo5ZDo1Mzo2YTpkOTpkYTo2MzoKKyAgICAgICAgM2E6Zjg6ODA6ZDc6ZDM6OTk6ZTE6YTU6ZTE6YmU6ZDQ6NTU6NzE6OTg6MzU6M2E6YmU6OTM6CisgICAgICAgIGVhOmFlOmFkOjQyOmIyOjkwOjZmOmUwOmZjOjIxOjRkOjM1OjYzOjMzOjg5OjQ5OmQ2OjliOgorICAgICAgICA0ZTpjYTpjNzplNzo0ZTowOTowMDpmNzpkYTpjNzplZjo5OTo2Mjo5OTo3NzpiNjo5NToyMjoKKyAgICAgICAgNWU6OGE6YTA6YWI6ZjQ6Yjg6Nzg6OTg6Y2E6Mzg6MTk6OTk6Yzk6NzI6OWU6Nzg6Y2Q6NGI6CisgICAgICAgIGFjOmFmOjE5OmEwOjczOjEyOjJkOmZjOmMyOjQxOmJhOjgxOjkxOmRhOjE2OjVhOjMxOmI3OgorICAgICAgICBmOTpiNDo3MTo4MDoxMjo0ODo5OTo3Mjo3Mzo1YTo1OTo1MzpjMTo2Mzo1MjozMzplZDphNzoKKyAgICAgICAgYzk6ZDI6Mzk6MDI6NzA6ZmE6ZTA6YjE6NDI6NjY6Mjk6YWE6OWI6NTE6ZWQ6MzA6NTQ6MjI6CisgICAgICAgIDE0OjVmOmQ5OmFiOjFkOmMxOmU0Ojk0OmYwOmY4OmY1OjJiOmY3OmVhOmNhOjc4OjQ2OmQ2OgorICAgICAgICBiODo5MTpmZDphNjowZDoyYjoxYToxNDowMTozZTo4MDpmMDo0MjphMDo5NTowNzo1ZTo2ZDoKKyAgICAgICAgY2Q6Y2M6NGI6YTQ6NDU6OGQ6YWI6MTI6ZTg6YjM6ZGU6NWE6ZTU6YTA6N2M6ZTg6MGY6MjI6CisgICAgICAgIDFkOjVhOmU5OjU5CitTSEExIEZpbmdlcnByaW50PTMyOjNDOjExOjhFOjFCOkY3OkI4OkI2OjUyOjU0OkUyOkUyOjEwOjBEOkQ2OjAyOjkwOjM3OkYwOjk2CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvOWQ2NTIzY2UuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy85ZDY1MjNjZS4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA5NzQ0N2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvOWQ2NTIzY2UuMApAQCAtMCwwICsxLDEyMyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlGc0RDQ0E1aWdBd0lCQWdJUUZjaTlaVWRjcjdpWEFGN2tCdEs4blRBTkJna3Foa2lHOXcwQkFRVUZBREJlCitNUXN3Q1FZRFZRUUdFd0pVVnpFak1DRUdBMVVFQ2d3YVEyaDFibWRvZDJFZ1ZHVnNaV052YlNCRGJ5NHNJRXgwCitaQzR4S2pBb0JnTlZCQXNNSVdWUVMwa2dVbTl2ZENCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVEFlCitGdzB3TkRFeU1qQXdNak14TWpkYUZ3MHpOREV5TWpBd01qTXhNamRhTUY0eEN6QUpCZ05WQkFZVEFsUlhNU013CitJUVlEVlFRS0RCcERhSFZ1WjJoM1lTQlVaV3hsWTI5dElFTnZMaXdnVEhSa0xqRXFNQ2dHQTFVRUN3d2haVkJMCitTU0JTYjI5MElFTmxjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1TUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGCitBQU9DQWc4QU1JSUNDZ0tDQWdFQTRTVVA3bzNiaUROMVo4MnRIMzA2VG0yZDB5OFU4Mk4weXdFaGFqZnFoRkFICitTeVpiQ1VOc0laNXF5TlVEOVdCcGo4endJdVFmNS9kcUlqRzNMQlh5NFA0QWFrUC9oMlhHdFJyQnAweHRJbkFoCitpakh5bDNTSkNSSW1ISjdLMlJLaWxUemE2V2UvQ0tCazQ5WkN0MFh2bC9UMjlkZTFTaFVDV0gyWVdFdGd2TTNYCitEWm9UTTFQUllmbDYxZGQ0czVvejl3Q0d6aDFObERpdnFPeDRVWENLWEJDRFVTSDNFVDAwaGw3bFNNMlhnWUkxCitUQm5zWmZacnhRV2g3a2NUMXJNaEo1UVFDdGtrTzdxK1JCTkdNRCtYUE5qWDEycnVPempqSzlTWERya2I1d2RKCitmemNxK1hkNHoxVHRXMGFkbzRBT2tVUEIxbHRmRkxxZnBvMGtSMEJadjNJNHNqWnNOLytaMFYwT1dRcXJhZmZBCitzZ1JGZWxRQXJyNVQ5clhuNGZnOG96SFNxZjRoVW1URnBtZndkUWNHbEJTQlZjWW41QUdQRjhGcWNkZStTL3VVCitXSDErRVRPeFF2ZGliQmpXendsb1BuOXM5aDZQWXEybFk5c0pweDhpUWtFZWI1bUtQdGY1UDBCNmViQ2xBWkxTCituVDBJRmFVUUFTMnpNbmFvbFEyemVwcjdCeEI0RVcvaGo4ZTZEeVVhZENybEhKaEJtZDhoaCtpVkJtb0tzMnBICitkbVgyT3MrUFloY1pld29velJyU2d4NGh4eXkvdnY5aGFMZG5HN3Q0VFkzT1orWGt3WTYzSTJiaW5aQjFOSmlwCitOaXVLbXBTNW5lek1pckg0SllsY1dyWXZqQjl0ZVNTblVtakRoRFhpWm8xakRpVk4xUm15NW5rM3B5S2RWREVDCitBd0VBQWFOcU1HZ3dIUVlEVlIwT0JCWUVGQjRNOTdabjh1R1NKZ2xGd0ZVNUxuYy9Ra3FpTUF3R0ExVWRFd1FGCitNQU1CQWY4d09RWUVaeW9IQUFReE1DOHdMUUlCQURBSkJnVXJEZ01DR2dVQU1BY0dCV2NxQXdBQUJCUkZzTUxICitDbFo4N2x0NERKWDVHRlBCcGh6WUVEQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FnRUFDYk9EVTFrQlBwVkp1ZkdCCit1dmwySUNPMUoyQjAxR3FaTkY1c0FGUFpuL0ttc1NRSFJHb3F4cVdPZUJMb1I5bFlHeE1xWG5tYm53b3FaNllsCitQd1pwVm5QRGltWkkreW1CVjNRR3lwenFLT2c0WnlZcjhkVzFQMldUK0RaZGpvMk5RQ0NIR2Vydko4QTl0RGtQCitKWHRvVUhSVm5BeFpmVm85UVpRbFVnamdSeXdWTVJuVnZ3ZFZ4cnNTdFpmMFg0T0Z1bkhCMld5QkVYWUtDckMvCitncGYzNmozNit1d3RxU2lVTzFiZDBsRXVyc0M5Q0JXTWQxSTBsdGFick5NZGptRVBOWHVicmpscEMySmdRQ0EyCitqNi83TnU0dENFb2R1TCtiWFBqcXBSdWdjNmJZK0c3Z013UmZhS29uaCszWndaQ2M3YjNqYWpXdlk5K3JHTm02Cis1dWxLNmxDS0QyR1RIdUl0R2VJd2xEV1NYUTYyQjY4WmdJOUhrRkZMTGszZGhlTFNDbElLRjVyOEdyQlFBdVVCCitvMk0zSVV4RXhKdFJtUkVPYzV3R2oxUXVweWhlUkRtSFZpMDN2WVZFbE9FTVN5eWN3NUtGTkdITEQ3aWJTa05TCisvalE2ZmJqcEtkeDJxY2d3K0JSeGdNWWVOa2gwSWtGY2g0TG9HSEdMUVlsRTUzNVlXNmk0alJQcHAyekRSKzJ6CitHcDFpcm8yQzZwU2UzVmtRdzYzZDRrM2pNZFhIN09qeXNQNlNIaFlLR3Z6WjgvZ250c20rSGJSc1pKQi85T1RFCitXOWMzcmtJTzNhUWFiM3lJVk1VV2J1RjZhQzc0T3I4TnBEeUpPM2luVG1PREJDRUlaNDN5Z2tuUVcvMnh6UStECitoTlErSUlYM1NqMHJuUDBxQ2dsTjZvSDRFWnc9CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICAxNTpjODpiZDo2NTo0Nzo1YzphZjpiODo5NzowMDo1ZTplNDowNjpkMjpiYzo5ZAorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVRXLCBPPUNodW5naHdhIFRlbGVjb20gQ28uLCBMdGQuLCBPVT1lUEtJIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IERlYyAyMCAwMjozMToyNyAyMDA0IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogRGVjIDIwIDAyOjMxOjI3IDIwMzQgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VFcsIE89Q2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4sIE9VPWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDQwOTYgYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDQwOTYgYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6ZTE6MjU6MGY6ZWU6OGQ6ZGI6ODg6MzM6NzU6Njc6Y2Q6YWQ6MWY6N2Q6CisgICAgICAgICAgICAgICAgICAgIDNhOjRlOjZkOjlkOmQzOjJmOjE0OmYzOjYzOjc0OmNiOjAxOjIxOjZhOjM3OgorICAgICAgICAgICAgICAgICAgICBlYTo4NDo1MDowNzo0YjoyNjo1YjowOTo0Mzo2YzoyMTo5ZTo2YTpjODpkNToKKyAgICAgICAgICAgICAgICAgICAgMDM6ZjU6NjA6Njk6OGY6Y2M6ZjA6MjI6ZTQ6MWY6ZTc6Zjc6NmE6MjI6MzE6CisgICAgICAgICAgICAgICAgICAgIGI3OjJjOjE1OmYyOmUwOmZlOjAwOjZhOjQzOmZmOjg3OjY1OmM2OmI1OjFhOgorICAgICAgICAgICAgICAgICAgICBjMTphNzo0Yzo2ZDoyMjo3MDoyMTo4YTozMTpmMjo5Nzo3NDo4OTowOToxMjoKKyAgICAgICAgICAgICAgICAgICAgMjY6MWM6OWU6Y2E6ZDk6MTI6YTI6OTU6M2M6ZGE6ZTk6Njc6YmY6MDg6YTA6CisgICAgICAgICAgICAgICAgICAgIDY0OmUzOmQ2OjQyOmI3OjQ1OmVmOjk3OmY0OmY2OmY1OmQ3OmI1OjRhOjE1OgorICAgICAgICAgICAgICAgICAgICAwMjo1ODo3ZDo5ODo1ODo0Yjo2MDpiYzpjZDpkNzowZDo5YToxMzozMzo1MzoKKyAgICAgICAgICAgICAgICAgICAgZDE6NjE6Zjk6N2E6ZDU6ZDc6Nzg6YjM6OWE6MzM6Zjc6MDA6ODY6Y2U6MWQ6CisgICAgICAgICAgICAgICAgICAgIDRkOjk0OjM4OmFmOmE4OmVjOjc4OjUxOjcwOjhhOjVjOjEwOjgzOjUxOjIxOgorICAgICAgICAgICAgICAgICAgICBmNzoxMTozZDozNDo4Njo1ZTplNTo0ODpjZDo5Nzo4MTo4MjozNTo0YzoxOToKKyAgICAgICAgICAgICAgICAgICAgZWM6NjU6ZjY6NmI6YzU6MDU6YTE6ZWU6NDc6MTM6ZDY6YjM6MjE6Mjc6OTQ6CisgICAgICAgICAgICAgICAgICAgIDEwOjBhOmQ5OjI0OjNiOmJhOmJlOjQ0OjEzOjQ2OjMwOjNmOjk3OjNjOmQ4OgorICAgICAgICAgICAgICAgICAgICBkNzpkNzo2YTplZTozYjozODplMzoyYjpkNDo5NzowZTpiOToxYjplNzowNzoKKyAgICAgICAgICAgICAgICAgICAgNDk6N2Y6Mzc6MmE6Zjk6Nzc6Nzg6Y2Y6NTQ6ZWQ6NWI6NDY6OWQ6YTM6ODA6CisgICAgICAgICAgICAgICAgICAgIDBlOjkxOjQzOmMxOmQ2OjViOjVmOjE0OmJhOjlmOmE2OjhkOjI0OjQ3OjQwOgorICAgICAgICAgICAgICAgICAgICA1OTpiZjo3MjozODpiMjozNjo2YzozNzpmZjo5OTpkMTo1ZDowZTo1OTowYToKKyAgICAgICAgICAgICAgICAgICAgYWI6Njk6Zjc6YzA6YjI6MDQ6NDU6N2E6NTQ6MDA6YWU6YmU6NTM6ZjY6YjU6CisgICAgICAgICAgICAgICAgICAgIGU3OmUxOmY4OjNjOmEzOjMxOmQyOmE5OmZlOjIxOjUyOjY0OmM1OmE2OjY3OgorICAgICAgICAgICAgICAgICAgICBmMDo3NTowNzowNjo5NDoxNDo4MTo1NTpjNjoyNzplNDowMTo4ZjoxNzpjMToKKyAgICAgICAgICAgICAgICAgICAgNmE6NzE6ZDc6YmU6NGI6ZmI6OTQ6NTg6N2Q6N2U6MTE6MzM6YjE6NDI6Zjc6CisgICAgICAgICAgICAgICAgICAgIDYyOjZjOjE4OmQ2OmNmOjA5OjY4OjNlOjdmOjZjOmY2OjFlOjhmOjYyOmFkOgorICAgICAgICAgICAgICAgICAgICBhNTo2MzpkYjowOTphNzoxZjoyMjo0Mjo0MToxZTo2Zjo5OTo4YTozZTpkNzoKKyAgICAgICAgICAgICAgICAgICAgZjk6M2Y6NDA6N2E6Nzk6YjA6YTU6MDE6OTI6ZDI6OWQ6M2Q6MDg6MTU6YTU6CisgICAgICAgICAgICAgICAgICAgIDEwOjAxOjJkOmIzOjMyOjc2OmE4Ojk1OjBkOmIzOjdhOjlhOmZiOjA3OjEwOgorICAgICAgICAgICAgICAgICAgICA3ODoxMTo2ZjplMTo4ZjpjNzpiYTowZjoyNToxYTo3NDoyYTplNToxYzo5ODoKKyAgICAgICAgICAgICAgICAgICAgNDE6OTk6ZGY6MjE6ODc6ZTg6OTU6MDY6NmE6MGE6YjM6NmE6NDc6NzY6NjU6CisgICAgICAgICAgICAgICAgICAgIGY2OjNhOmNmOjhmOjYyOjE3OjE5OjdiOjBhOjI4OmNkOjFhOmQyOjgzOjFlOgorICAgICAgICAgICAgICAgICAgICAyMTpjNzoyYzpiZjpiZTpmZjo2MTo2ODpiNzo2NzoxYjpiYjo3ODo0ZDo4ZDoKKyAgICAgICAgICAgICAgICAgICAgY2U6Njc6ZTU6ZTQ6YzE6OGU6Yjc6MjM6NjY6ZTI6OWQ6OTA6NzU6MzQ6OTg6CisgICAgICAgICAgICAgICAgICAgIGE5OjM2OjJiOjhhOjlhOjk0OmI5OjlkOmVjOmNjOjhhOmIxOmY4OjI1Ojg5OgorICAgICAgICAgICAgICAgICAgICA1Yzo1YTpiNjoyZjo4YzoxZjo2ZDo3OToyNDphNzo1Mjo2ODpjMzo4NDozNToKKyAgICAgICAgICAgICAgICAgICAgZTI6NjY6OGQ6NjM6MGU6MjU6NGQ6ZDU6MTk6YjI6ZTY6Nzk6Mzc6YTc6MjI6CisgICAgICAgICAgICAgICAgICAgIDlkOjU0OjMxCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICAxRTowQzpGNzpCNjo2NzpGMjpFMTo5MjoyNjowOTo0NTpDMDo1NTozOToyRTo3NzozRjo0Mjo0QTpBMgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiAKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBzZXRDZXh0LWhhc2hlZFJvb3Q6IAorICAgICAgICAgICAgICAgIDAvMC0uLi4wLi4uKy4uLi4uLjAuLi5nKi4uLi4uRS4uLgorVnwuW3guLi4uUy4uLi4uCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDA5OmIzOjgzOjUzOjU5OjAxOjNlOjk1OjQ5OmI5OmYxOjgxOmJhOmY5Ojc2OjIwOjIzOmI1OgorICAgICAgICAyNzo2MDo3NDpkNDo2YTo5OTozNDo1ZTo2YzowMDo1MzpkOTo5ZjpmMjphNjpiMToyNDowNzoKKyAgICAgICAgNDQ6NmE6MmE6YzY6YTU6OGU6Nzg6MTI6ZTg6NDc6ZDk6NTg6MWI6MTM6MmE6NWU6Nzk6OWI6CisgICAgICAgIDlmOjBhOjJhOjY3OmE2OjI1OjNmOjA2OjY5OjU2OjczOmMzOjhhOjY2OjQ4OmZiOjI5OjgxOgorICAgICAgICA1Nzo3NDowNjpjYTo5YzplYToyODplODozODo2NzoyNjoyYjpmMTpkNTpiNTozZjo2NTo5MzoKKyAgICAgICAgZjg6MzY6NWQ6OGU6OGQ6OGQ6NDA6MjA6ODc6MTk6ZWE6ZWY6Mjc6YzA6M2Q6YjQ6Mzk6MGY6CisgICAgICAgIDI1OjdiOjY4OjUwOjc0OjU1OjljOjBjOjU5OjdkOjVhOjNkOjQxOjk0OjI1OjUyOjA4OmUwOgorICAgICAgICA0NzoyYzoxNTozMToxOTpkNTpiZjowNzo1NTpjNjpiYjoxMjpiNTo5NzpmNDo1Zjo4Mzo4NToKKyAgICAgICAgYmE6NzE6YzE6ZDk6NmM6ODE6MTE6NzY6MGE6MGE6YjA6YmY6ODI6OTc6Zjc6ZWE6M2Q6ZmE6CisgICAgICAgIGZhOmVjOjJkOmE5OjI4Ojk0OjNiOjU2OmRkOmQyOjUxOjJlOmFlOmMwOmJkOjA4OjE1OjhjOgorICAgICAgICA3Nzo1MjozNDo5NjpkNjo5YjphYzpkMzoxZDo4ZTo2MTowZjozNTo3Yjo5YjphZTozOTo2OToKKyAgICAgICAgMGI6NjI6NjA6NDA6MjA6MzY6OGY6YWY6ZmI6MzY6ZWU6MmQ6MDg6NGE6MWQ6Yjg6YmY6OWI6CisgICAgICAgIDVjOmY4OmVhOmE1OjFiOmEwOjczOmE2OmQ4OmY4OjZlOmUwOjMzOjA0OjVmOjY4OmFhOjI3OgorICAgICAgICA4NzplZDpkOTpjMTo5MDo5YzplZDpiZDplMzo2YTozNTphZjo2MzpkZjphYjoxODpkOTpiYToKKyAgICAgICAgZTY6ZTk6NGE6ZWE6NTA6OGE6MGY6NjE6OTM6MWU6ZTI6MmQ6MTk6ZTI6MzA6OTQ6MzU6OTI6CisgICAgICAgIDVkOjBlOmI2OjA3OmFmOjE5OjgwOjhmOjQ3OjkwOjUxOjRiOjJlOjRkOmRkOjg1OmUyOmQyOgorICAgICAgICAwYTo1MjowYToxNzo5YTpmYzoxYTpiMDo1MDowMjplNTowMTphMzo2MzozNzoyMTo0Yzo0NDoKKyAgICAgICAgYzQ6OWI6NTE6OTk6MTE6MGU6NzM6OWM6MDY6OGY6NTQ6MmU6YTc6Mjg6NWU6NDQ6Mzk6ODc6CisgICAgICAgIDU2OjJkOjM3OmJkOjg1OjQ0Ojk0OmUxOjBjOjRiOjJjOjljOmMzOjkyOjg1OjM0OjYxOmNiOgorICAgICAgICAwZjpiODo5Yjo0YTo0Mzo1MjpmZTozNDozYTo3ZDpiODplOToyOTpkYzo3NjphOTpjODozMDoKKyAgICAgICAgZjg6MTQ6NzE6ODA6YzY6MWU6MzY6NDg6NzQ6MjI6NDE6NWM6ODc6ODI6ZTg6MTg6NzE6OGI6CisgICAgICAgIDQxOjg5OjQ0OmU3OjdlOjU4OjViOmE4OmI4OjhkOjEzOmU5OmE3OjZjOmMzOjQ3OmVkOmIzOgorICAgICAgICAxYTo5ZDo2MjphZTo4ZDo4MjplYTo5NDo5ZTpkZDo1OToxMDpjMzphZDpkZDplMjo0ZDplMzoKKyAgICAgICAgMzE6ZDU6Yzc6ZWM6ZTg6ZjI6YjA6ZmU6OTI6MWU6MTY6MGE6MWE6ZmM6ZDk6ZjM6Zjg6Mjc6CisgICAgICAgIGI2OmM5OmJlOjFkOmI0OjZjOjY0OjkwOjdmOmY0OmU0OmM0OjViOmQ3OjM3OmFlOjQyOjBlOgorICAgICAgICBkZDphNDoxYTo2Zjo3Yzo4ODo1NDpjNToxNjo2ZTplMTo3YTo2ODoyZTpmODozYTpiZjowZDoKKyAgICAgICAgYTQ6M2M6ODk6M2I6Nzg6YTc6NGU6NjM6ODM6MDQ6MjE6MDg6Njc6OGQ6ZjI6ODI6NDk6ZDA6CisgICAgICAgIDViOmZkOmIxOmNkOjBmOjgzOjg0OmQ0OjNlOjIwOjg1OmY3OjRhOjNkOjJiOjljOmZkOjJhOgorICAgICAgICAwYTowOTo0ZDplYTo4MTpmODoxMTo5YworU0hBMSBGaW5nZXJwcmludD02Nzo2NTowRDpGMTo3RTo4RTo3RTo1Qjo4Mjo0MDpBNDpGNDo1Njo0QjpDRjpFMjozRDo2OTpDNjpGMApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzlkYmVmZTdiLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvOWRiZWZlN2IuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jODVkNGE4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzlkYmVmZTdiLjAKQEAgLTAsMCArMSw3OCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEZlRDQ0FtV2dBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUVVGQURCZ01Rc3dDUVlEVlFRR0V3SktVREVsCitNQ01HQTFVRUNoTWNVMFZEVDAwZ1ZISjFjM1FnVTNsemRHVnRjeUJEVHk0c1RGUkVMakVxTUNnR0ExVUVDeE1oCitVMlZqZFhKcGRIa2dRMjl0YlhWdWFXTmhkR2x2YmlCRlZpQlNiMjkwUTBFeE1CNFhEVEEzTURZd05qQXlNVEl6CitNbG9YRFRNM01EWXdOakF5TVRJek1sb3dZREVMTUFrR0ExVUVCaE1DU2xBeEpUQWpCZ05WQkFvVEhGTkZRMDlOCitJRlJ5ZFhOMElGTjVjM1JsYlhNZ1EwOHVMRXhVUkM0eEtqQW9CZ05WQkFzVElWTmxZM1Z5YVhSNUlFTnZiVzExCitibWxqWVhScGIyNGdSVllnVW05dmRFTkJNVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DCitnZ0VCQUx4LzdGZWJKT0QrbkxwQ2VhbUlpdnFBNFBVSEtVUHFqZ28wTm8wYytxZTFPWGovbDNYM0wrU3Fhd1NFCitSTXFtNG1pTy9WVlFZZytrY1E3T0J6Z3RRb1ZRclR5V2I0dlZvZzdQM2ttSlBkWmtMampsSG15MVY0cWU3MGdPCit6WHBwRm9kRXRaRGtCcDJ1b1FTWFdIbnZJRXFDYTR3aXYrd2ZEK21FY2UzeER1UzRHQlBNVmpaZDBab2VVV3M1CitibUIyaURRTDg3UFJzSjNLWWVKa0hjRkdCN2hqM1I0elpiT09DVlZTUGJXOS93ZnJyV0ZWR0N5cGFaaEtxa0RGCitNeFJsZEFENWtkNnZBMGpGUUZUY0Q0U1FhQ0RGa3BiY0x1VUNSYXJBWDFUNGJlcEp6MTFzUzYvdm1zSldYTVkxCitWa0pxTUYvQ3EvYmlQVCt6eVJHUE1VelhuMGtDQXdFQUFhTkNNRUF3SFFZRFZSME9CQllFRkRWSzlVMnZQOWVDCitPS3lyY1dVWGRZeWRWWlBtTUE0R0ExVWREd0VCL3dRRUF3SUJCakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHCitDU3FHU0liM0RRRUJCUVVBQTRJQkFRQ29oK25zK0VCblhjUEJac2RBUzVmOGh4T1FXc1R2b01wZmk3ZW50L0hXCit0V1MzaXJPNEc4emErNnhtaUVITzZQemsyeDZJcHUwblVCc0NNQ1JHZWY0RWgzQ1hRSFBSd01GWEdacHBwU2VaCitxNTFpaFBaUndTekpJeFhZS0xlckpSTzFSdUdHQXY4bWpNU0lraDFXL2hsbjhsWGtnS05ybkt0MzRWRnhEU0RiCitFSnJidlhaNUIzZVpLSzJhWHRxeFQwUXNOWTZsbHNmOWcvQll4bm5XbUh5b2pmNkdQZ2NXa3VGNzV4M3NNM1orCitRaTVLaGZtUmlXaUVBNEdsbTVxKzR6ZkZWS3RXT3hndFFhUU0rRUxibWFEZ2NtKzdYZUVXVDFNS1pQbE85TDlPCitWTDE0YklqcXY1d1RKTUp3YWFKL0Q4ZzhyUWpKc0poQW95cm5pSVB0ZDQ5MAorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAwICgweDApCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9SlAsIE89U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELiwgT1U9U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBKdW4gIDYgMDI6MTI6MzIgMjAwNyBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEp1biAgNiAwMjoxMjozMiAyMDM3IEdNVAorICAgICAgICBTdWJqZWN0OiBDPUpQLCBPPVNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4sIE9VPVNlY3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YmM6N2Y6ZWM6NTc6OWI6MjQ6ZTA6ZmU6OWM6YmE6NDI6Nzk6YTk6ODg6CisgICAgICAgICAgICAgICAgICAgIDhhOmZhOjgwOmUwOmY1OjA3OjI5OjQzOmVhOjhlOjBhOjM0OjM2OjhkOjFjOgorICAgICAgICAgICAgICAgICAgICBmYTphNzpiNTozOTo3ODpmZjo5Nzo3NTpmNzoyZjplNDphYTo2YjowNDo4NDoKKyAgICAgICAgICAgICAgICAgICAgNDQ6Y2E6YTY6ZTI6Njg6OGU6ZmQ6NTU6NTA6NjI6MGY6YTQ6NzE6MGU6Y2U6CisgICAgICAgICAgICAgICAgICAgIDA3OjM4OjJkOjQyOjg1OjUwOmFkOjNjOjk2OjZmOjhiOmQ1OmEyOjBlOmNmOgorICAgICAgICAgICAgICAgICAgICBkZTo0OTo4OTozZDpkNjo2NDoyZTozODplNToxZTo2YzpiNTo1Nzo4YTo5ZToKKyAgICAgICAgICAgICAgICAgICAgZWY6NDg6MGU6Y2Q6N2E6Njk6MTY6ODc6NDQ6YjU6OTA6ZTQ6MDY6OWQ6YWU6CisgICAgICAgICAgICAgICAgICAgIGExOjA0Ojk3OjU4Ojc5OmVmOjIwOjRhOjgyOjZiOjhjOjIyOmJmOmVjOjFmOgorICAgICAgICAgICAgICAgICAgICAwZjplOTo4NDo3MTplZDpmMTowZTplNDpiODoxODoxMzpjYzo1NjozNjo1ZDoKKyAgICAgICAgICAgICAgICAgICAgZDE6OWE6MWU6NTE6NmI6Mzk6NmU6NjA6NzY6ODg6MzQ6MGI6ZjM6YjM6ZDE6CisgICAgICAgICAgICAgICAgICAgIGIwOjlkOmNhOjYxOmUyOjY0OjFkOmMxOjQ2OjA3OmI4OjYzOmRkOjFlOjMzOgorICAgICAgICAgICAgICAgICAgICA2NTpiMzo4ZTowOTo1NTo1MjozZDpiNTpiZDpmZjowNzplYjphZDo2MTo1NToKKyAgICAgICAgICAgICAgICAgICAgMTg6MmM6YTk6Njk6OTg6NGE6YWE6NDA6YzU6MzM6MTQ6NjU6NzQ6MDA6Zjk6CisgICAgICAgICAgICAgICAgICAgIDkxOmRlOmFmOjAzOjQ4OmM1OjQwOjU0OmRjOjBmOjg0OjkwOjY4OjIwOmM1OgorICAgICAgICAgICAgICAgICAgICA5Mjo5NjpkYzoyZTplNTowMjo0NTphYTpjMDo1Zjo1NDpmODo2ZDplYTo0OToKKyAgICAgICAgICAgICAgICAgICAgY2Y6NWQ6NmM6NGI6YWY6ZWY6OWE6YzI6NTY6NWM6YzY6MzU6NTY6NDI6NmE6CisgICAgICAgICAgICAgICAgICAgIDMwOjVmOmMyOmFiOmY2OmUyOjNkOjNmOmIzOmM5OjExOjhmOjMxOjRjOmQ3OgorICAgICAgICAgICAgICAgICAgICA5Zjo0OQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgMzU6NEE6RjU6NEQ6QUY6M0Y6RDc6ODI6Mzg6QUM6QUI6NzE6NjU6MTc6NzU6OEM6OUQ6NTU6OTM6RTYKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIGE4Ojg3OmU5OmVjOmY4OjQwOjY3OjVkOmMzOmMxOjY2OmM3OjQwOjRiOjk3OmZjOjg3OjEzOgorICAgICAgICA5MDo1YTpjNDplZjphMDpjYTo1Zjo4YjpiNzphNzpiNzpmMTpkNjpiNTo2NDpiNzo4YTpiMzoKKyAgICAgICAgYjg6MWI6Y2M6ZGE6ZmI6YWM6NjY6ODg6NDE6Y2U6ZTg6ZmM6ZTQ6ZGI6MWU6ODg6YTY6ZWQ6CisgICAgICAgIDI3OjUwOjFiOjAyOjMwOjI0OjQ2Ojc5OmZlOjA0Ojg3OjcwOjk3OjQwOjczOmQxOmMwOmMxOgorICAgICAgICA1NzoxOTo5YTo2OTphNToyNzo5OTphYjo5ZDo2Mjo4NDpmNjo1MTpjMToyYzpjOToyMzoxNToKKyAgICAgICAgZDg6Mjg6Yjc6YWI6MjU6MTM6YjU6NDY6ZTE6ODY6MDI6ZmY6MjY6OGM6YzQ6ODg6OTI6MWQ6CisgICAgICAgIDU2OmZlOjE5OjY3OmYyOjU1OmU0OjgwOmEzOjZiOjljOmFiOjc3OmUxOjUxOjcxOjBkOjIwOgorICAgICAgICBkYjoxMDo5YTpkYjpiZDo3Njo3OTowNzo3Nzo5OToyODphZDo5YTo1ZTpkYTpiMTo0Zjo0NDoKKyAgICAgICAgMmM6MzU6OGU6YTU6OTY6Yzc6ZmQ6ODM6ZjA6NTg6YzY6Nzk6ZDY6OTg6N2M6YTg6OGQ6ZmU6CisgICAgICAgIDg2OjNlOjA3OjE2OjkyOmUxOjdiOmU3OjFkOmVjOjMzOjc2OjdlOjQyOjJlOjRhOjg1OmY5OgorICAgICAgICA5MTo4OTo2ODo4NDowMzo4MTphNTo5Yjo5YTpiZTplMzozNzpjNTo1NDphYjo1NjozYjoxODoKKyAgICAgICAgMmQ6NDE6YTQ6MGM6Zjg6NDI6ZGI6OTk6YTA6ZTA6NzI6NmY6YmI6NWQ6ZTE6MTY6NGY6NTM6CisgICAgICAgIDBhOjY0OmY5OjRlOmY0OmJmOjRlOjU0OmJkOjc4OjZjOjg4OmVhOmJmOjljOjEzOjI0OmMyOgorICAgICAgICA3MDo2OTphMjo3ZjowZjpjODozYzphZDowODpjOTpiMDo5ODo0MDphMzoyYTplNzo4ODo4MzoKKyAgICAgICAgZWQ6Nzc6OGY6NzQKK1NIQTEgRmluZ2VycHJpbnQ9RkU6Qjg6QzQ6MzI6REM6Rjk6NzY6OUE6Q0U6QUU6M0Q6RDg6OTA6OEY6RkQ6Mjg6ODY6NjU6NjQ6N0QKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy85ZjUzMzUxOC4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzLzlmNTMzNTE4LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTdiYjM2YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy85ZjUzMzUxOC4wCkBAIC0wLDAgKzEsMTM5IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUhTVENDQlRHZ0F3SUJBZ0lKQU1uTjArblZmU1BPTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUdzTVFzd0NRWUQKK1ZRUUdFd0pGVlRGRE1FRUdBMVVFQnhNNlRXRmtjbWxrSUNoelpXVWdZM1Z5Y21WdWRDQmhaR1J5WlhOeklHRjAKK0lIZDNkeTVqWVcxbGNtWnBjbTFoTG1OdmJTOWhaR1J5WlhOektURVNNQkFHQTFVRUJSTUpRVGd5TnpRek1qZzMKK01Sc3dHUVlEVlFRS0V4SkJReUJEWVcxbGNtWnBjbTFoSUZNdVFTNHhKekFsQmdOVkJBTVRIa2RzYjJKaGJDQkQKK2FHRnRZbVZ5YzJsbmJpQlNiMjkwSUMwZ01qQXdPREFlRncwd09EQTRNREV4TWpNeE5EQmFGdzB6T0RBM016RXgKK01qTXhOREJhTUlHc01Rc3dDUVlEVlFRR0V3SkZWVEZETUVFR0ExVUVCeE02VFdGa2NtbGtJQ2h6WldVZ1kzVnkKK2NtVnVkQ0JoWkdSeVpYTnpJR0YwSUhkM2R5NWpZVzFsY21acGNtMWhMbU52YlM5aFpHUnlaWE56S1RFU01CQUcKK0ExVUVCUk1KUVRneU56UXpNamczTVJzd0dRWURWUVFLRXhKQlF5QkRZVzFsY21acGNtMWhJRk11UVM0eEp6QWwKK0JnTlZCQU1USGtkc2IySmhiQ0JEYUdGdFltVnljMmxuYmlCU2IyOTBJQzBnTWpBd09EQ0NBaUl3RFFZSktvWkkKK2h2Y05BUUVCQlFBRGdnSVBBRENDQWdvQ2dnSUJBTURmVnRQa09wdDJSYlFUMi8vQnRobUxOMEVZbFZKSDZ4ZWQKK0tZaU9OV3dHTWk1SFl2TkpCTDk5UkRheGNjeTlXZ2x6MWRtRlJQK1JWeVhmWGphT2NORmNjVU1kMmRydlhOTDcKK0c3MDZ0Y3V0bzh4RXB3MnVJUlUvdVhwYmtuWFlwQkk0aVJtS3Q0RFM0akp2VnB5UjFvZ1FDN04wWkpKMFlQUDIKK3p4aFBZTElqME1jN3ptRkxtWS9DRE5CQXNwamNEYWhPbzdrS3JtQ2dyVVZTWTdwbXZXamcrYjRhcUlHN0hrRjQKK2RkUEIvZ0JWc0lkVTZDZVFOUjFNTTYyWC9KY3VtSVMvTE1tanY5R1lFUlR0WS9qS21JaFlGNW50UlFPWGZqeUcKK0hvaU12dktSaEk5bE5OZ0FUSDIzTVJkYUtYb0tHQ1F3b3plMWVxa0JmU2JXK1E2T1dmSDlHek8xS1RzWE8wRzIKK0lkM1V3RDJsbjU4ZlExREp1N3hzZXBlWTdzMk1IL3VjVWE2TGNMMG5uM0hBYTZ4OWtHYm8xMTA2RGJEVndvM1YKK3lKMmR3VzNRMEw5UjVPUDR3emcycnRhbmRlYXZoRU5kazVJTWFnZmVPeDJZSXRhc3dUWGJvNkFsLzNLMWRoM2UKK2Jla3NaaXhTaE5CRmtzNGM1ZVV6SGR3SFUxU2pxb0k3bWpjdjNOMmdaT25tM2IydS9HU0ZIVHlueVFiZWhQOXIKKzZHc2FQTVdpczBMN2l3aytYd2hTeDJMRTFBVnh2OFJrNVBpaGcrZytFcHVvSHRRMlRTOXg5bzBvOW9PcEU5SmgKK3daRzdTTUEwajBHTVMwemJhUkwvVUpTY0lJTlpjKzE4b2ZMeC9kMzNTZE5EV0tCV1k4bzlQZVUxVmxucERzb2cKK3pDdExreWtQQWdNQkFBR2pnZ0ZxTUlJQlpqQVNCZ05WSFJNQkFmOEVDREFHQVFIL0FnRU1NQjBHQTFVZERnUVcKK0JCUzVDY3FjSHR2VGJEcHJydTFVOFZ1VEJqVXVYakNCNFFZRFZSMGpCSUhaTUlIV2dCUzVDY3FjSHR2VGJEcHIKK3J1MVU4VnVUQmpVdVhxR0JzcVNCcnpDQnJERUxNQWtHQTFVRUJoTUNSVlV4UXpCQkJnTlZCQWNUT2sxaFpISnAKK1pDQW9jMlZsSUdOMWNuSmxiblFnWVdSa2NtVnpjeUJoZENCM2QzY3VZMkZ0WlhKbWFYSnRZUzVqYjIwdllXUmsKK2NtVnpjeWt4RWpBUUJnTlZCQVVUQ1VFNE1qYzBNekk0TnpFYk1Ca0dBMVVFQ2hNU1FVTWdRMkZ0WlhKbWFYSnQKK1lTQlRMa0V1TVNjd0pRWURWUVFERXg1SGJHOWlZV3dnUTJoaGJXSmxjbk5wWjI0Z1VtOXZkQ0F0SURJd01EaUMKK0NRREp6ZFBwMVgwanpqQU9CZ05WSFE4QkFmOEVCQU1DQVFZd1BRWURWUjBnQkRZd05EQXlCZ1JWSFNBQU1Db3cKK0tBWUlLd1lCQlFVSEFnRVdIR2gwZEhBNkx5OXdiMnhwWTNrdVkyRnRaWEptYVhKdFlTNWpiMjB3RFFZSktvWkkKK2h2Y05BUUVGQlFBRGdnSUJBSUNJZjNEZWtpalpCWlJHLzVCWHFmRXYzeG9OYS9wOERoeEpKSGtuMkVhcWJ5bFoKK1VvaHdFdXJkUGZXYlUxUnY0V0NpcUFtNTdPdFpmTVkxOGR3WTZmRm41YSs2UmVBSjNzcEVEOElYRG5lUlJYb3oKK1gxK1dMR2lMd1VlUG1Kczl3T3pMOWRXQ2tvUTEwYjQyT0ZaeU1WdEhMYW9YcEdOUjZ3b0JyWC9zZFo3TG9SL3gKK2Z4S3h1ZVJrZjJmV0l5cjB1RGxkbU9naHArRzlQVUlhZEpwd3IyaHNVRjFKei8vN0RsM21MRWZYZ1RwWkFMVnoKK2EyTWc5akZGQ0RrTzlIQitRSEJhUDlCclFxbDBQU2d2QW0xMWNwVUpqVWhqeHNZalY1S1RYalhCamZrSzl5eWQKK1loejJyWHpkcGpFZXRySEhmb1VtK3FScXRkcGpNTkh2a3pleVppOTlCZmZudDB1WWxEWEEyVG9wd1oyeVVETWQKK1NxbGFwc2tENyszMDU2aHVpclJYaE91a1A5RHVxcXFIVzJQb2srSnJxTlM0Y25ockcrMDU1RjNMbTZxSDFVOU8KK0FQN1phcDg4TVE4b0FnRjltT2luc0tKa25ubjRTUElWcWN6bXlFVHJQM2laOG50eFBqenhtS2ZGR0JJLzVyc28KK00wTHBSUXA4YmZLR2VTL0ZnaGw5Q1lsOHNsUjJpSzdld2ZQTTRXN2JNZGFUcnBtZzd5VnFjNWlKV3pvdUU0Z2UKK3Y4Q1NsRFFiNHllM2l4NXZRdi9uNlRlYlVCMHRvdmtDN3N0WVdEcHh2R2pqcXNHdkhDZ2ZvdHdqWlQrQjZxNloKKzA5Z3d6eE1OVHhYSmhMeW5TQzM0TUNOMzJFWkxlVzMyak8wNmYyQVJlUFRwbTY3VlZNQjBnTkVMUXAvQgorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgYzk6Y2Q6ZDM6ZTk6ZDU6N2Q6MjM6Y2UKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1FVSwgTD1NYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpL3NlcmlhbE51bWJlcj1BODI3NDMyODcsIE89QUMgQ2FtZXJmaXJtYSBTLkEuLCBDTj1HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDgKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEF1ZyAgMSAxMjozMTo0MCAyMDA4IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogSnVsIDMxIDEyOjMxOjQwIDIwMzggR01UCisgICAgICAgIFN1YmplY3Q6IEM9RVUsIEw9TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKS9zZXJpYWxOdW1iZXI9QTgyNzQzMjg3LCBPPUFDIENhbWVyZmlybWEgUy5BLiwgQ049R2xvYmFsIENoYW1iZXJzaWduIFJvb3QgLSAyMDA4CisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoNDA5NiBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoNDA5NiBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpjMDpkZjo1NjpkMzplNDozYTo5Yjo3Njo0NTpiNDoxMzpkYjpmZjpjMToKKyAgICAgICAgICAgICAgICAgICAgYjY6MTk6OGI6Mzc6NDE6MTg6OTU6NTI6NDc6ZWI6MTc6OWQ6Mjk6ODg6OGU6CisgICAgICAgICAgICAgICAgICAgIDM1OjZjOjA2OjMyOjJlOjQ3OjYyOmYzOjQ5OjA0OmJmOjdkOjQ0OjM2OmIxOgorICAgICAgICAgICAgICAgICAgICA3MTpjYzpiZDo1YTowOTo3MzpkNTpkOTo4NTo0NDpmZjo5MTo1NzoyNTpkZjoKKyAgICAgICAgICAgICAgICAgICAgNWU6MzY6OGU6NzA6ZDE6NWM6NzE6NDM6MWQ6ZDk6ZGE6ZWY6NWM6ZDI6ZmI6CisgICAgICAgICAgICAgICAgICAgIDFiOmJkOjNhOmI1OmNiOmFkOmEzOmNjOjQ0OmE3OjBkOmFlOjIxOjE1OjNmOgorICAgICAgICAgICAgICAgICAgICBiOTo3YTo1Yjo5Mjo3NTpkODphNDoxMjozODo4OToxOTo4YTpiNzo4MDpkMjoKKyAgICAgICAgICAgICAgICAgICAgZTI6MzI6NmY6NTY6OWM6OTE6ZDY6ODg6MTA6MGI6YjM6NzQ6NjQ6OTI6NzQ6CisgICAgICAgICAgICAgICAgICAgIDYwOmYzOmY2OmNmOjE4OjRmOjYwOmIyOjIzOmQwOmM3OjNiOmNlOjYxOjRiOgorICAgICAgICAgICAgICAgICAgICA5OTo4ZjpjMjowYzpkMDo0MDpiMjo5ODpkYzowZDphODo0ZTphMzpiOTowYToKKyAgICAgICAgICAgICAgICAgICAgYWU6NjA6YTA6YWQ6NDU6NTI6NjM6YmE6NjY6YmQ6Njg6ZTA6Zjk6YmU6MWE6CisgICAgICAgICAgICAgICAgICAgIGE4OjgxOmJiOjFlOjQxOjc4Ojc1OmQzOmMxOmZlOjAwOjU1OmIwOjg3OjU0OgorICAgICAgICAgICAgICAgICAgICBlODoyNzo5MDozNToxZDo0YzozMzphZDo5NzpmYzo5NzoyZTo5ODo4NDpiZjoKKyAgICAgICAgICAgICAgICAgICAgMmM6Yzk6YTM6YmY6ZDE6OTg6MTE6MTQ6ZWQ6NjM6Zjg6Y2E6OTg6ODg6NTg6CisgICAgICAgICAgICAgICAgICAgIDE3Ojk5OmVkOjQ1OjAzOjk3OjdlOjNjOjg2OjFlOjg4OjhjOmJlOmYyOjkxOgorICAgICAgICAgICAgICAgICAgICA4NDo4Zjo2NTozNDpkODowMDo0Yzo3ZDpiNzozMToxNzo1YToyOTo3YTowYToKKyAgICAgICAgICAgICAgICAgICAgMTg6MjQ6MzA6YTM6Mzc6YjU6N2E6YTk6MDE6N2Q6MjY6ZDY6Zjk6MGU6OGU6CisgICAgICAgICAgICAgICAgICAgIDU5OmYxOmZkOjFiOjMzOmI1OjI5OjNiOjE3OjNiOjQxOmI2OjIxOmRkOmQ0OgorICAgICAgICAgICAgICAgICAgICBjMDozZDphNTo5Zjo5ZjoxZjo0Mzo1MDpjOTpiYjpiYzo2Yzo3YTo5Nzo5ODoKKyAgICAgICAgICAgICAgICAgICAgZWU6Y2Q6OGM6MWY6ZmI6OWM6NTE6YWU6OGI6NzA6YmQ6Mjc6OWY6NzE6YzA6CisgICAgICAgICAgICAgICAgICAgIDZiOmFjOjdkOjkwOjY2OmU4OmQ3OjVkOjNhOjBkOmIwOmQ1OmMyOjhkOmQ1OgorICAgICAgICAgICAgICAgICAgICBjODo5ZDo5ZDpjMTo2ZDpkMDpkMDpiZjo1MTplNDplMzpmODpjMzozODozNjoKKyAgICAgICAgICAgICAgICAgICAgYWU6ZDY6YTc6NzU6ZTY6YWY6ODQ6NDM6NWQ6OTM6OTI6MGM6NmE6MDc6ZGU6CisgICAgICAgICAgICAgICAgICAgIDNiOjFkOjk4OjIyOmQ2OmFjOmMxOjM1OmRiOmEzOmEwOjI1OmZmOjcyOmI1OgorICAgICAgICAgICAgICAgICAgICA3NjoxZDpkZTo2ZDplOToyYzo2NjoyYzo1Mjo4NDpkMDo0NTo5MjpjZToxYzoKKyAgICAgICAgICAgICAgICAgICAgZTU6ZTU6MzM6MWQ6ZGM6MDc6NTM6NTQ6YTM6YWE6ODI6M2I6OWE6Mzc6MmY6CisgICAgICAgICAgICAgICAgICAgIGRjOmRkOmEwOjY0OmU5OmU2OmRkOmJkOmFlOmZjOjY0Ojg1OjFkOjNjOmE3OgorICAgICAgICAgICAgICAgICAgICBjOTowNjpkZTo4NDpmZjo2YjplODo2YjoxYTozYzpjNTphMjpiMzo0MjpmYjoKKyAgICAgICAgICAgICAgICAgICAgOGI6MDk6M2U6NWY6MDg6NTI6Yzc6NjI6YzQ6ZDQ6MDU6NzE6YmY6YzQ6NjQ6CisgICAgICAgICAgICAgICAgICAgIGU0OmY4OmExOjgzOmU4OjNlOjEyOjliOmE4OjFlOmQ0OjM2OjRkOjJmOjcxOgorICAgICAgICAgICAgICAgICAgICBmNjo4ZDoyODpmNjo4MzphOToxMzpkMjo2MTpjMTo5MTpiYjo0ODpjMDozNDoKKyAgICAgICAgICAgICAgICAgICAgOGY6NDE6OGM6NGI6NGM6ZGI6Njk6MTI6ZmY6NTA6OTQ6OWM6MjA6ODM6NTk6CisgICAgICAgICAgICAgICAgICAgIDczOmVkOjdjOmExOmYyOmYxOmZkOmRkOmY3OjQ5OmQzOjQzOjU4OmEwOjU2OgorICAgICAgICAgICAgICAgICAgICA2MzpjYTozZDozZDplNTozNTo1Njo1OTplOTowZTpjYToyMDpjYzoyYjo0YjoKKyAgICAgICAgICAgICAgICAgICAgOTM6Mjk6MGYKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUsIHBhdGhsZW46MTIKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBCOTowOTpDQTo5QzoxRTpEQjpEMzo2QzozQTo2QjpBRTpFRDo1NDpGMTo1Qjo5MzowNjozNToyRTo1RQorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6Qjk6MDk6Q0E6OUM6MUU6REI6RDM6NkM6M0E6NkI6QUU6RUQ6NTQ6RjE6NUI6OTM6MDY6MzU6MkU6NUUKKyAgICAgICAgICAgICAgICBEaXJOYW1lOi9DPUVVL0w9TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKS9zZXJpYWxOdW1iZXI9QTgyNzQzMjg3L089QUMgQ2FtZXJmaXJtYSBTLkEuL0NOPUdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwOAorICAgICAgICAgICAgICAgIHNlcmlhbDpDOTpDRDpEMzpFOTpENTo3RDoyMzpDRQorCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQ2VydGlmaWNhdGUgUG9saWNpZXM6IAorICAgICAgICAgICAgICAgIFBvbGljeTogWDUwOXYzIEFueSBQb2xpY3kKKyAgICAgICAgICAgICAgICAgIENQUzogaHR0cDovL3BvbGljeS5jYW1lcmZpcm1hLmNvbQorCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDgwOjg4OjdmOjcwOmRlOjkyOjI4OmQ5OjA1Ojk0OjQ2OmZmOjkwOjU3OmE5OmYxOjJmOmRmOgorICAgICAgICAxYTowZDo2YjpmYTo3YzowZToxYzo0OToyNDo3OToyNzpkODo0NjphYTo2ZjoyOTo1OTo1MjoKKyAgICAgICAgODg6NzA6MTI6ZWE6ZGQ6M2Q6ZjU6OWI6NTM6NTQ6NmY6ZTE6NjA6YTI6YTg6MDk6Yjk6ZWM6CisgICAgICAgIGViOjU5OjdjOmM2OjM1OmYxOmRjOjE4OmU5OmYxOjY3OmU1OmFmOmJhOjQ1OmUwOjA5OmRlOgorICAgICAgICBjYTo0NDowZjpjMjoxNzowZTo3Nzo5MTo0NTo3YTozMzo1Zjo1Zjo5NjoyYzo2ODo4YjpjMToKKyAgICAgICAgNDc6OGY6OTg6OWI6M2Q6YzA6ZWM6Y2I6ZjU6ZDU6ODI6OTI6ODQ6MzU6ZDE6YmU6MzY6Mzg6CisgICAgICAgIDU2OjcyOjMxOjViOjQ3OjJkOmFhOjE3OmE0OjYzOjUxOmViOjBhOjAxOmFkOjdmOmVjOjc1OgorICAgICAgICA5ZTpjYjphMToxZjpmMTo3ZjoxMjpiMTpiOTplNDo2NDo3Zjo2NzpkNjoyMzoyYTpmNDpiODoKKyAgICAgICAgMzk6NWQ6OTg6ZTg6MjE6YTc6ZTE6YmQ6M2Q6NDI6MWE6NzQ6OWE6NzA6YWY6Njg6NmM6NTA6CisgICAgICAgIDVkOjQ5OmNmOmZmOmZiOjBlOjVkOmU2OjJjOjQ3OmQ3OjgxOjNhOjU5OjAwOmI1OjczOjZiOgorICAgICAgICA2MzoyMDpmNjozMTo0NTowODozOTowZTpmNDo3MDo3ZTo0MDo3MDo1YTozZjpkMDo2Yjo0MjoKKyAgICAgICAgYTk6NzQ6M2Q6Mjg6MmY6MDI6NmQ6NzU6NzI6OTU6MDk6OGQ6NDg6NjM6YzY6YzY6MjM6NTc6CisgICAgICAgIDkyOjkzOjVlOjM1OmMxOjhkOmY5OjBhOmY3OjJjOjlkOjYyOjFjOmY2OmFkOjdjOmRkOmE2OgorICAgICAgICAzMToxZTpiNjpiMTpjNzo3ZTo4NToyNjpmYTphNDo2YTpiNTpkYTo2MzozMDpkMTplZjo5MzoKKyAgICAgICAgMzc6YjI6NjY6MmY6N2Q6MDU6Zjc6ZTc6Yjc6NGI6OTg6OTQ6MzU6YzA6ZDk6M2E6Mjk6YzE6CisgICAgICAgIDlkOmIyOjUwOjMzOjFkOjRhOmE5OjVhOmE2OmM5OjAzOmVmOmVkOmY0OmU3OmE4OjZlOjhhOgorICAgICAgICBiNDo1Nzo4NDplYjphNDozZjpkMDplZTphYTphYTo4Nzo1Yjo2MzplODo5MzplMjo2YjphODoKKyAgICAgICAgZDQ6Yjg6NzI6Nzg6NmI6MWI6ZWQ6Mzk6ZTQ6NWQ6Y2I6OWI6YWE6ODc6ZDU6NGY6NGU6MDA6CisgICAgICAgIGZlOmQ5OjZhOjlmOjNjOjMxOjBmOjI4OjAyOjAxOjdkOjk4OmU4OmE3OmIwOmEyOjY0OjllOgorICAgICAgICA3OTpmODo0ODpmMjoxNTphOTpjYzplNjpjODo0NDplYjozZjo3ODo5OTpmMjo3Yjo3MTozZToKKyAgICAgICAgM2M6ZjE6OTg6YTc6YzU6MTg6MTI6M2Y6ZTY6YmI6Mjg6MzM6NDI6ZTk6NDU6MGE6N2M6NmQ6CisgICAgICAgIGYyOjg2Ojc5OjJmOmM1OjgyOjE5OjdkOjA5Ojg5OjdjOmIyOjU0Ojc2Ojg4OmFlOmRlOmMxOgorICAgICAgICBmMzpjYzplMTo2ZTpkYjozMTpkNjo5MzphZTo5OTphMDplZjoyNTo2YTo3Mzo5ODo4OTo1YjoKKyAgICAgICAgM2E6MmU6MTM6ODg6MWU6YmY6YzA6OTI6OTQ6MzQ6MWI6ZTM6Mjc6Yjc6OGI6MWU6NmY6NDI6CisgICAgICAgIGZmOmU3OmU5OjM3OjliOjUwOjFkOjJkOmEyOmY5OjAyOmVlOmNiOjU4OjU4OjNhOjcxOmJjOgorICAgICAgICA2ODplMzphYTpjMTphZjoxYzoyODoxZjphMjpkYzoyMzo2NTozZjo4MTplYTphZTo5OTpkMzoKKyAgICAgICAgZDg6MzA6Y2Y6MTM6MGQ6NGY6MTU6Yzk6ODQ6YmM6YTc6NDg6MmQ6Zjg6MzA6MjM6Nzc6ZDg6CisgICAgICAgIDQ2OjRiOjc5OjZkOmY2OjhjOmVkOjNhOjdmOjYwOjExOjc4OmY0OmU5OjliOmFlOmQ1OjU0OgorICAgICAgICBjMDo3NDo4MDpkMTowYjo0Mjo5ZjpjMQorU0hBMSBGaW5nZXJwcmludD00QTpCRDpFRTpFQzo5NTowRDozNTo5Qzo4OTpBRTpDNzo1MjpBMToyQzo1QjoyOTpGNjpENjpBQTowQwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2EwYmM2ZmJiLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYTBiYzZmYmIuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NmFjYzFjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2EwYmM2ZmJiLjAKQEAgLTAsMCArMSw5OCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFeFRDQ0E2MmdBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUVVGQURCOU1Rc3dDUVlEVlFRR0V3SkZWVEVuCitNQ1VHQTFVRUNoTWVRVU1nUTJGdFpYSm1hWEp0WVNCVFFTQkRTVVlnUVRneU56UXpNamczTVNNd0lRWURWUVFMCitFeHBvZEhSd09pOHZkM2QzTG1Ob1lXMWlaWEp6YVdkdUxtOXlaekVnTUI0R0ExVUVBeE1YUjJ4dlltRnNJRU5vCitZVzFpWlhKemFXZHVJRkp2YjNRd0hoY05NRE13T1RNd01UWXhOREU0V2hjTk16Y3dPVE13TVRZeE5ERTRXakI5CitNUXN3Q1FZRFZRUUdFd0pGVlRFbk1DVUdBMVVFQ2hNZVFVTWdRMkZ0WlhKbWFYSnRZU0JUUVNCRFNVWWdRVGd5CitOelF6TWpnM01TTXdJUVlEVlFRTEV4cG9kSFJ3T2k4dmQzZDNMbU5vWVcxaVpYSnphV2R1TG05eVp6RWdNQjRHCitBMVVFQXhNWFIyeHZZbUZzSUVOb1lXMWlaWEp6YVdkdUlGSnZiM1F3Z2dFZ01BMEdDU3FHU0liM0RRRUJBUVVBCitBNElCRFFBd2dnRUlBb0lCQVFDaWNLTFFuMEt1V3hmSDJIM1BGSVA4VDhtaHR4T3ZpdGVlUGdRS2tvdGdWdnEwCitNaStJVGFGZ0NQUzNDVTZnU1M5SjF0UGZuWmRhbjVRRWNPdy9XZG0zekdhTG1GSW9DUUxmeFMrRWpYcVhkNy9zCitRSjBsY3F1MVB6S1krN2UzL0hLRTVUV0grVlg2b3g4T2J5NG8zV21nMlVJUXh2aTFSTUxRUTMvYnZPU2lQR3BWCitlQXAzcWRqcUdUSzNMLzVjUHh2dXNaanN5cTE2YVVYamxnOVY5dWJ0ZGVwbDZESldrMGFKcUNXS1pRYnVhNzk1CitCOUR4dDYvdExFMlN1OENvWDZkbmZRVHlGUWh3ckpMV2ZRVFNNL3RNdGdzTCt4ckp4STBEcVg1YzhsQ3JFcVdoCit6MGhRcGUvU3lCb1QrckIvc1lJY2Qyb1BYOXdMbFkvdlEzN21SUWtsQWdFRG80SUJVRENDQVV3d0VnWURWUjBUCitBUUgvQkFnd0JnRUIvd0lCRERBL0JnTlZIUjhFT0RBMk1EU2dNcUF3aGk1b2RIUndPaTh2WTNKc0xtTm9ZVzFpCitaWEp6YVdkdUxtOXlaeTlqYUdGdFltVnljMmxuYm5KdmIzUXVZM0pzTUIwR0ExVWREZ1FXQkJSRG5EYWZzSjR3CitUY2JPWDYwUXErVURwZnFwRkRBT0JnTlZIUThCQWY4RUJBTUNBUVl3RVFZSllJWklBWWI0UWdFQkJBUURBZ0FICitNQ29HQTFVZEVRUWpNQ0dCSDJOb1lXMWlaWEp6YVdkdWNtOXZkRUJqYUdGdFltVnljMmxuYmk1dmNtY3dLZ1lECitWUjBTQkNNd0lZRWZZMmhoYldKbGNuTnBaMjV5YjI5MFFHTm9ZVzFpWlhKemFXZHVMbTl5WnpCYkJnTlZIU0FFCitWREJTTUZBR0N5c0dBUVFCZ1ljdUNnRUJNRUV3UHdZSUt3WUJCUVVIQWdFV00yaDBkSEE2THk5amNITXVZMmhoCitiV0psY25OcFoyNHViM0puTDJOd2N5OWphR0Z0WW1WeWMybG5ibkp2YjNRdWFIUnRiREFOQmdrcWhraUc5dzBCCitBUVVGQUFPQ0FRRUFQRHR3a2ZrRVZDZVI0ZTN0L21oL1lWM2xRV1ZQTXZFWUJaUnFITjRmY05zK2V6SUNOTFVNCitiS0dLZktYMGovL1UySzBYMVMwRTBUOVlnT0tCV1lpK3dPTkdreVQra0wwbW9qQXQ2SmNtVnpXSmRKWVk5aFhpCityeVFaVmdJQ3Nyb1BGT3JHaW1iQmhrVlZpNzZTdnB5a0JNZEpQSjdvS1hxSjEvNnYvMmoxcFJlUXZheVp6S1dHCitWd2xuUnR2V0ZzSkc4ZVNwVVBXUDBaSVYwMTgreGdCSk9tNVlzdEhSSncwbHlETDRJQkhOZlRJelNKUlVUTjNjCitlY1F3bit1T3VGVzExNGhjeFdva1BiTFRCUU5SeGdmdnpCUnlkRDF1Y3M0WUtJeEtvSGZsQ1N0RlJFZXN0MmQvCitBWW9GV3BPK29jSC8rT2NPWjZSSFNYWmRkWkFhOVNhUDhBPT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMCAoMHgwKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPUVVLCBPPUFDIENhbWVyZmlybWEgU0EgQ0lGIEE4Mjc0MzI4NywgT1U9aHR0cDovL3d3dy5jaGFtYmVyc2lnbi5vcmcsIENOPUdsb2JhbCBDaGFtYmVyc2lnbiBSb290CisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBTZXAgMzAgMTY6MTQ6MTggMjAwMyBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IFNlcCAzMCAxNjoxNDoxOCAyMDM3IEdNVAorICAgICAgICBTdWJqZWN0OiBDPUVVLCBPPUFDIENhbWVyZmlybWEgU0EgQ0lGIEE4Mjc0MzI4NywgT1U9aHR0cDovL3d3dy5jaGFtYmVyc2lnbi5vcmcsIENOPUdsb2JhbCBDaGFtYmVyc2lnbiBSb290CisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDphMjo3MDphMjpkMDo5Zjo0MjphZTo1YjoxNzpjNzpkODo3ZDpjZjoxNDoKKyAgICAgICAgICAgICAgICAgICAgODM6ZmM6NGY6Yzk6YTE6Yjc6MTM6YWY6OGE6ZDc6OWU6M2U6MDQ6MGE6OTI6CisgICAgICAgICAgICAgICAgICAgIDhiOjYwOjU2OmZhOmI0OjMyOjJmOjg4OjRkOmExOjYwOjA4OmY0OmI3OjA5OgorICAgICAgICAgICAgICAgICAgICA0ZTphMDo0OToyZjo0OTpkNjpkMzpkZjo5ZDo5Nzo1YTo5Zjo5NDowNDo3MDoKKyAgICAgICAgICAgICAgICAgICAgZWM6M2Y6NTk6ZDk6Yjc6Y2M6NjY6OGI6OTg6NTI6Mjg6MDk6MDI6ZGY6YzU6CisgICAgICAgICAgICAgICAgICAgIDJmOjg0OjhkOjdhOjk3Ojc3OmJmOmVjOjQwOjlkOjI1OjcyOmFiOmI1OjNmOgorICAgICAgICAgICAgICAgICAgICAzMjo5ODpmYjpiNzpiNzpmYzo3Mjo4NDplNTozNTo4NzpmOTo1NTpmYTphMzoKKyAgICAgICAgICAgICAgICAgICAgMWY6MGU6NmY6MmU6Mjg6ZGQ6Njk6YTA6ZDk6NDI6MTA6YzY6Zjg6YjU6NDQ6CisgICAgICAgICAgICAgICAgICAgIGMyOmQwOjQzOjdmOmRiOmJjOmU0OmEyOjNjOjZhOjU1Ojc4OjBhOjc3OmE5OgorICAgICAgICAgICAgICAgICAgICBkODplYToxOTozMjpiNzoyZjpmZTo1YzozZjoxYjplZTpiMTo5ODplYzpjYToKKyAgICAgICAgICAgICAgICAgICAgYWQ6N2E6Njk6NDU6ZTM6OTY6MGY6NTU6ZjY6ZTY6ZWQ6NzU6ZWE6NjU6ZTg6CisgICAgICAgICAgICAgICAgICAgIDMyOjU2OjkzOjQ2Ojg5OmE4OjI1OjhhOjY1OjA2OmVlOjZiOmJmOjc5OjA3OgorICAgICAgICAgICAgICAgICAgICBkMDpmMTpiNzphZjplZDoyYzo0ZDo5MjpiYjpjMDphODo1ZjphNzo2Nzo3ZDoKKyAgICAgICAgICAgICAgICAgICAgMDQ6ZjI6MTU6MDg6NzA6YWM6OTI6ZDY6N2Q6MDQ6ZDI6MzM6ZmI6NGM6YjY6CisgICAgICAgICAgICAgICAgICAgIDBiOjBiOmZiOjFhOmM5OmM0OjhkOjAzOmE5OjdlOjVjOmYyOjUwOmFiOjEyOgorICAgICAgICAgICAgICAgICAgICBhNTphMTpjZjo0ODo1MDphNTplZjpkMjpjODoxYToxMzpmYTpiMDo3ZjpiMToKKyAgICAgICAgICAgICAgICAgICAgODI6MWM6Nzc6NmE6MGY6NWY6ZGM6MGI6OTU6OGY6ZWY6NDM6N2U6ZTY6NDU6CisgICAgICAgICAgICAgICAgICAgIDA5OjI1CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDMgKDB4MykKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRSwgcGF0aGxlbjoxMgorICAgICAgICAgICAgWDUwOXYzIENSTCBEaXN0cmlidXRpb24gUG9pbnRzOiAKKyAgICAgICAgICAgICAgICBVUkk6aHR0cDovL2NybC5jaGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNpZ25yb290LmNybAorCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgNDM6OUM6MzY6OUY6QjA6OUU6MzA6NEQ6QzY6Q0U6NUY6QUQ6MTA6QUI6RTU6MDM6QTU6RkE6QTk6MTQKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIE5ldHNjYXBlIENlcnQgVHlwZTogCisgICAgICAgICAgICAgICAgU1NMIENBLCBTL01JTUUgQ0EsIE9iamVjdCBTaWduaW5nIENBCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBBbHRlcm5hdGl2ZSBOYW1lOiAKKyAgICAgICAgICAgICAgICBlbWFpbDpjaGFtYmVyc2lnbnJvb3RAY2hhbWJlcnNpZ24ub3JnCisgICAgICAgICAgICBYNTA5djMgSXNzdWVyIEFsdGVybmF0aXZlIE5hbWU6IAorICAgICAgICAgICAgICAgIGVtYWlsOmNoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcKKyAgICAgICAgICAgIFg1MDl2MyBDZXJ0aWZpY2F0ZSBQb2xpY2llczogCisgICAgICAgICAgICAgICAgUG9saWN5OiAxLjMuNi4xLjQuMS4xNzMyNi4xMC4xLjEKKyAgICAgICAgICAgICAgICAgIENQUzogaHR0cDovL2Nwcy5jaGFtYmVyc2lnbi5vcmcvY3BzL2NoYW1iZXJzaWducm9vdC5odG1sCisKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgM2M6M2I6NzA6OTE6Zjk6MDQ6NTQ6Mjc6OTE6ZTE6ZWQ6ZWQ6ZmU6Njg6N2Y6NjE6NWQ6ZTU6CisgICAgICAgIDQxOjY1OjRmOjMyOmYxOjE4OjA1Ojk0OjZhOjFjOmRlOjFmOjcwOmRiOjNlOjdiOjMyOjAyOgorICAgICAgICAzNDpiNTowYzo2YzphMTo4YTo3YzphNTpmNDo4ZjpmZjpkNDpkODphZDoxNzpkNToyZDowNDoKKyAgICAgICAgZDE6M2Y6NTg6ODA6ZTI6ODE6NTk6ODg6YmU6YzA6ZTM6NDY6OTM6MjQ6ZmU6OTA6YmQ6MjY6CisgICAgICAgIGEyOjMwOjJkOmU4Ojk3OjI2OjU3OjM1Ojg5Ojc0Ojk2OjE4OmY2OjE1OmUyOmFmOjI0OjE5OgorICAgICAgICA1NjowMjowMjpiMjpiYTowZjoxNDplYTpjNjo4YTo2NjpjMTo4Njo0NTo1NTo4YjpiZTo5MjoKKyAgICAgICAgYmU6OWM6YTQ6MDQ6Yzc6NDk6M2M6OWU6ZTg6Mjk6N2E6ODk6ZDc6ZmU6YWY6ZmY6Njg6ZjU6CisgICAgICAgIGE1OjE3OjkwOmJkOmFjOjk5OmNjOmE1Ojg2OjU3OjA5OjY3OjQ2OmRiOmQ2OjE2OmMyOjQ2OgorICAgICAgICBmMTplNDphOTo1MDpmNTo4ZjpkMTo5MjoxNTpkMzo1ZjozZTpjNjowMDo0OTozYTo2ZTo1ODoKKyAgICAgICAgYjI6ZDE6ZDE6Mjc6MGQ6MjU6Yzg6MzI6Zjg6MjA6MTE6Y2Q6N2Q6MzI6MzM6NDg6OTQ6NTQ6CisgICAgICAgIDRjOmRkOmRjOjc5OmM0OjMwOjlmOmViOjhlOmI4OjU1OmI1OmQ3Ojg4OjVjOmM1OjZhOjI0OgorICAgICAgICAzZDpiMjpkMzowNTowMzo1MTpjNjowNzplZjpjYzoxNDo3Mjo3NDozZDo2ZTo3MjpjZToxODoKKyAgICAgICAgMjg6OGM6NGE6YTA6Nzc6ZTU6MDk6MmI6NDU6NDQ6NDc6YWM6Yjc6Njc6N2Y6MDE6OGE6MDU6CisgICAgICAgIDVhOjkzOmJlOmExOmMxOmZmOmY4OmU3OjBlOjY3OmE0OjQ3OjQ5Ojc2OjVkOjc1OjkwOjFhOgorICAgICAgICBmNToyNjo4ZjpmMAorU0hBMSBGaW5nZXJwcmludD0zMzo5Qjo2QjoxNDo1MDoyNDo5Qjo1NTo3QTowMTo4Nzo3Mjo4NDpEOTpFMDoyRjpDMzpEMjpEODpFOQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2ExNWIzYjZiLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYTE1YjNiNmIuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZmVhYzcyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2ExNWIzYjZiLjAKQEAgLTAsMCArMSw3MyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlES1RDQ0FwS2dBd0lCQWdJRU5tN1R6akFOQmdrcWhraUc5dzBCQVFVRkFEQkdNUXN3Q1FZRFZRUUdFd0pWCitVekVrTUNJR0ExVUVDaE1iUkdsbmFYUmhiQ0JUYVdkdVlYUjFjbVVnVkhKMWMzUWdRMjh1TVJFd0R3WURWUVFMCitFd2hFVTFSRFFTQkZNakFlRncwNU9ERXlNRGt4T1RFM01qWmFGdzB4T0RFeU1Ea3hPVFEzTWpaYU1FWXhDekFKCitCZ05WQkFZVEFsVlRNU1F3SWdZRFZRUUtFeHRFYVdkcGRHRnNJRk5wWjI1aGRIVnlaU0JVY25WemRDQkRieTR4CitFVEFQQmdOVkJBc1RDRVJUVkVOQklFVXlNSUdkTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdMQURDQmh3S0JnUUMvCitrNDhYa3U4ekV4anJFSDlPRnIvL0JvOHFoYnhlK1NTbUpJaTJBN2ZCdzE4RFc5RnZybjVDNm1ZanVHT0RWdnNvCitMZUU0aTdUdXFBSGh6aHkyaUNvaVJvWDduNmR3cVVjVVA4N2VaZkNvY2ZkUEpteU12TWExNzk1SkovOUlLbjNvCitUUVBNeDdKU3hoY3hFenUxVGR2SXhQYkREeVFxMmd5ZDU1RmJnTTJVblFJQkE2T0NBU1F3Z2dFZ01CRUdDV0NHCitTQUdHK0VJQkFRUUVBd0lBQnpCb0JnTlZIUjhFWVRCZk1GMmdXNkJacEZjd1ZURUxNQWtHQTFVRUJoTUNWVk14CitKREFpQmdOVkJBb1RHMFJwWjJsMFlXd2dVMmxuYm1GMGRYSmxJRlJ5ZFhOMElFTnZMakVSTUE4R0ExVUVDeE1JCitSRk5VUTBFZ1JUSXhEVEFMQmdOVkJBTVRCRU5TVERFd0t3WURWUjBRQkNRd0lvQVBNVGs1T0RFeU1Ea3hPVEUzCitNalphZ1E4eU1ERTRNVEl3T1RFNU1UY3lObG93Q3dZRFZSMFBCQVFEQWdFR01COEdBMVVkSXdRWU1CYUFGQjZDCitUU2hsZ0R6SlFXNnNOUzVheTk3dStEbGJNQjBHQTFVZERnUVdCQlFlZ2swb1pZQTh5VUZ1ckRVdVdzdmU3dmc1CitXekFNQmdOVkhSTUVCVEFEQVFIL01Ca0dDU3FHU0liMmZRZEJBQVFNTUFvYkJGWTBMakFEQWdTUU1BMEdDU3FHCitTSWIzRFFFQkJRVUFBNEdCQUVlTmc2MWk4dHV3bmtVaUJibWkxZ01PT0hMbm52eDc1cE8ybXFXaWxNZzBIWkhSCit4ZGYwQ2lVUFBYaUJuZyt4WjhTUVRHUGRYcWZpdXAvMTkwMmxNWHVjS1MxTS9tUSs3TFpUL3VxYjdZTGJkSFZMCitCM2x1SHRnWmczUGU5VDdRdGQ3blMyaDlReTRxSU9GK29IaEVuZ2oxbVBuSGZ4c2IxZ1lnQWxpaHc2SUQKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogOTEzMjMyODQ2ICgweDM2NmVkM2NlKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPURpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLiwgT1U9RFNUQ0EgRTIKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IERlYyAgOSAxOToxNzoyNiAxOTk4IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogRGVjICA5IDE5OjQ3OjI2IDIwMTggR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89RGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uLCBPVT1EU1RDQSBFMgorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDEwMjQgYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDEwMjQgYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YmY6OTM6OGY6MTc6OTI6ZWY6MzM6MTM6MTg6ZWI6MTA6N2Y6NGU6MTY6CisgICAgICAgICAgICAgICAgICAgIGJmOmZmOjA2OjhmOjJhOjg1OmJjOjVlOmY5OjI0OmE2OjI0Ojg4OmI2OjAzOgorICAgICAgICAgICAgICAgICAgICBiNzpjMTpjMzo1ZjowMzo1YjpkMTo2ZjphZTo3ZTo0MjplYTo2NjoyMzpiODoKKyAgICAgICAgICAgICAgICAgICAgNjM6ODM6NTY6ZmI6Mjg6MmQ6ZTE6Mzg6OGI6YjQ6ZWU6YTg6MDE6ZTE6Y2U6CisgICAgICAgICAgICAgICAgICAgIDFjOmI2Ojg4OjJhOjIyOjQ2Ojg1OmZiOjlmOmE3OjcwOmE5OjQ3OjE0OjNmOgorICAgICAgICAgICAgICAgICAgICBjZTpkZTo2NTpmMDphODo3MTpmNzo0ZjoyNjo2Yzo4YzpiYzpjNjpiNTplZjoKKyAgICAgICAgICAgICAgICAgICAgZGU6NDk6Mjc6ZmY6NDg6MmE6N2Q6ZTg6NGQ6MDM6Y2M6Yzc6YjI6NTI6YzY6CisgICAgICAgICAgICAgICAgICAgIDE3OjMxOjEzOjNiOmI1OjRkOmRiOmM4OmM0OmY2OmMzOjBmOjI0OjJhOmRhOgorICAgICAgICAgICAgICAgICAgICAwYzo5ZDplNzo5MTo1Yjo4MDpjZDo5NDo5ZAorICAgICAgICAgICAgICAgIEV4cG9uZW50OiAzICgweDMpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgTmV0c2NhcGUgQ2VydCBUeXBlOiAKKyAgICAgICAgICAgICAgICBTU0wgQ0EsIFMvTUlNRSBDQSwgT2JqZWN0IFNpZ25pbmcgQ0EKKyAgICAgICAgICAgIFg1MDl2MyBDUkwgRGlzdHJpYnV0aW9uIFBvaW50czogCisgICAgICAgICAgICAgICAgRGlyTmFtZTovQz1VUy9PPURpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLi9PVT1EU1RDQSBFMi9DTj1DUkwxCisKKyAgICAgICAgICAgIFg1MDl2MyBQcml2YXRlIEtleSBVc2FnZSBQZXJpb2Q6IAorICAgICAgICAgICAgICAgIE5vdCBCZWZvcmU6IERlYyAgOSAxOToxNzoyNiAxOTk4IEdNVCwgTm90IEFmdGVyOiBEZWMgIDkgMTk6MTc6MjYgMjAxOCBHTVQKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQXV0aG9yaXR5IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBrZXlpZDoxRTo4Mjo0RDoyODo2NTo4MDozQzpDOTo0MTo2RTpBQzozNToyRTo1QTpDQjpERTpFRTpGODozOTo1QgorCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgMUU6ODI6NEQ6Mjg6NjU6ODA6M0M6Qzk6NDE6NkU6QUM6MzU6MkU6NUE6Q0I6REU6RUU6Rjg6Mzk6NUIKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgMS4yLjg0MC4xMTM1MzMuNy42NS4wOiAKKyAgICAgICAgICAgICAgICAwCisuLlY0LjAuLi4uCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDQ3OjhkOjgzOmFkOjYyOmYyOmRiOmIwOjllOjQ1OjIyOjA1OmI5OmEyOmQ2OjAzOjBlOjM4OgorICAgICAgICA3MjplNzo5ZTpmYzo3YjplNjo5MzpiNjo5YTphNTphMjo5NDpjODozNDoxZDo5MTpkMTpjNToKKyAgICAgICAgZDc6ZjQ6MGE6MjU6MGY6M2Q6Nzg6ODE6OWU6MGY6YjE6Njc6YzQ6OTA6NGM6NjM6ZGQ6NWU6CisgICAgICAgIGE3OmUyOmJhOjlmOmY1OmY3OjRkOmE1OjMxOjdiOjljOjI5OjJkOjRjOmZlOjY0OjNlOmVjOgorICAgICAgICBiNjo1MzpmZTplYTo5YjplZDo4MjpkYjo3NDo3NTo0YjowNzo3OTo2ZToxZTpkODoxOTo4MzoKKyAgICAgICAgNzM6ZGU6ZjU6M2U6ZDA6YjU6ZGU6ZTc6NGI6Njg6N2Q6NDM6MmU6MmE6MjA6ZTE6N2U6YTA6CisgICAgICAgIDc4OjQ0OjllOjA4OmY1Ojk4OmY5OmM3OjdmOjFiOjFiOmQ2OjA2OjIwOjAyOjU4OmExOmMzOgorICAgICAgICBhMjowMworU0hBMSBGaW5nZXJwcmludD1BQjo0ODpGMzozMzpEQjowNDpBQjpCOTpDMDo3MjpEQTo1QjowQzpDMTpEMDo1NzpGMDozNjo5Qjo0NgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2EzODk2YjQ0LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYTM4OTZiNDQuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MDgxYzRiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2EzODk2YjQ0LjAKQEAgLTAsMCArMSw3NyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEV2pDQ0FrS2dBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUVVGQURCUU1Rc3dDUVlEVlFRR0V3SktVREVZCitNQllHQTFVRUNoTVBVMFZEVDAwZ1ZISjFjM1F1Ym1WME1TY3dKUVlEVlFRTEV4NVRaV04xY21sMGVTQkRiMjF0CitkVzVwWTJGMGFXOXVJRkp2YjNSRFFURXdIaGNOTURNd09UTXdNRFF5TURRNVdoY05Nak13T1RNd01EUXlNRFE1CitXakJRTVFzd0NRWURWUVFHRXdKS1VERVlNQllHQTFVRUNoTVBVMFZEVDAwZ1ZISjFjM1F1Ym1WME1TY3dKUVlECitWUVFMRXg1VFpXTjFjbWwwZVNCRGIyMXRkVzVwWTJGMGFXOXVJRkp2YjNSRFFURXdnZ0VpTUEwR0NTcUdTSWIzCitEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUN6cy81LzAyMng3eFo4VjZVTWJYYUtMMHUvWlB0TTdvcnc4eWw4Cis5Zi91S3VEcDZicGJaQ0thbW04c09pWnBVUVdaSnR6VkhHcHh4cHA5SHAzZGZHekdqR2RuU2o3NGNiQVpKNmtKCitES2FWdjB1TURQcFZtRHZZNkNLaFMzRTRlYXlYa21temlYN3FJV2dHbUJTV2g5SmhOcnh0SjFhZVYrN0F3RmI5CitNcytrMlk3Q0k5ZU5xUFBZSmF5WDVIQTQ5TFk2dEowN2x5WkRvNkc4U1ZseVRDTXdod0ZZOWs2K0hHaFdacS9OCitRVjNJczAwcVZVYXJIOW9lNGtBOTI4MTl1WktBbkRmZERKWmtuZHdpOTJTTDMySGVGWlJTRmFCOVVzbExxQ0hKCit4ckh0eThPVllORVA4S3R3K04vTFRYN3MxdnFyMmIxL1ZQS2w2WG42MmRaMkpDaHpBZ01CQUFHalB6QTlNQjBHCitBMVVkRGdRV0JCU2djMG1aYU55RlcyWGpteWd2VjUrOU03d0hTREFMQmdOVkhROEVCQU1DQVFZd0R3WURWUjBUCitBUUgvQkFVd0F3RUIvekFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBYUVDcHFMdmtUMTE1c3dXMUY3TmdFK3ZHCitrbDNnMGROcS92dSttMjIveHdWdFdTREVIUEMzMm9SWUFtUDZTQmJ2VDZVTDkwcVk4aitlRzYxSGEyUE9DRWZyCitVajk0bks5TnJ2alZUOCthbUNvUVFUbFN4TjNabXc3dmt3R3VzaTdLYUVJa1FteXdzem8remVuYVNNUVZ5K241CitCdytTVUVtSzNUR1hYOG5wTjZvN1dXV1hsRExKczU4K09tSll4VW10WWc1eHBUS3FMOGFKZGtOQUV4Tm5QYUpVCitKUkRMOFRyeTJmcmJTVmE3cHY2blFUWEQ0SWhoeVlqSDN6WVFJcGhaNnJCSysxWVdjMjZzVGZjaW9VK3RIWG90CitSU2ZsTU1GZTh0b1R5eVZDVVpWSEE0eHNJY3gwUXUxVC96T0xqdzlYQVJZdno2YnV5WEFpRkwzOXZtd0xBdz09CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDAgKDB4MCkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1KUCwgTz1TRUNPTSBUcnVzdC5uZXQsIE9VPVNlY3VyaXR5IENvbW11bmljYXRpb24gUm9vdENBMQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogU2VwIDMwIDA0OjIwOjQ5IDIwMDMgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBTZXAgMzAgMDQ6MjA6NDkgMjAyMyBHTVQKKyAgICAgICAgU3ViamVjdDogQz1KUCwgTz1TRUNPTSBUcnVzdC5uZXQsIE9VPVNlY3VyaXR5IENvbW11bmljYXRpb24gUm9vdENBMQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YjM6YjM6ZmU6N2Y6ZDM6NmQ6YjE6ZWY6MTY6N2M6NTc6YTU6MGM6NmQ6CisgICAgICAgICAgICAgICAgICAgIDc2OjhhOjJmOjRiOmJmOjY0OmZiOjRjOmVlOjhhOmYwOmYzOjI5OjdjOmY1OgorICAgICAgICAgICAgICAgICAgICBmZjplZToyYTplMDplOTplOTpiYTo1Yjo2NDoyMjo5YTo5YTo2ZjoyYzozYToKKyAgICAgICAgICAgICAgICAgICAgMjY6Njk6NTE6MDU6OTk6MjY6ZGM6ZDU6MWM6NmE6NzE6YzY6OWE6N2Q6MWU6CisgICAgICAgICAgICAgICAgICAgIDlkOmRkOjdjOjZjOmM2OjhjOjY3OjY3OjRhOjNlOmY4OjcxOmIwOjE5OjI3OgorICAgICAgICAgICAgICAgICAgICBhOTowOTowYzphNjo5NTpiZjo0Yjo4YzowYzpmYTo1NTo5ODozYjpkODplODoKKyAgICAgICAgICAgICAgICAgICAgMjI6YTE6NGI6NzE6Mzg6Nzk6YWM6OTc6OTI6Njk6YjM6ODk6N2U6ZWE6MjE6CisgICAgICAgICAgICAgICAgICAgIDY4OjA2Ojk4OjE0Ojk2Ojg3OmQyOjYxOjM2OmJjOjZkOjI3OjU2OjllOjU3OgorICAgICAgICAgICAgICAgICAgICBlZTpjMDpjMDo1NjpmZDozMjpjZjphNDpkOTo4ZTpjMjoyMzpkNzo4ZDphODoKKyAgICAgICAgICAgICAgICAgICAgZjM6ZDg6MjU6YWM6OTc6ZTQ6NzA6Mzg6ZjQ6YjY6M2E6YjQ6OWQ6M2I6OTc6CisgICAgICAgICAgICAgICAgICAgIDI2OjQzOmEzOmExOmJjOjQ5OjU5OjcyOjRjOjIzOjMwOjg3OjAxOjU4OmY2OgorICAgICAgICAgICAgICAgICAgICA0ZTpiZToxYzo2ODo1Njo2NjphZjpjZDo0MTo1ZDpjODpiMzo0ZDoyYTo1NToKKyAgICAgICAgICAgICAgICAgICAgNDY6YWI6MWY6ZGE6MWU6ZTI6NDA6M2Q6ZGI6Y2Q6N2Q6Yjk6OTI6ODA6OWM6CisgICAgICAgICAgICAgICAgICAgIDM3OmRkOjBjOjk2OjY0OjlkOmRjOjIyOmY3OjY0OjhiOmRmOjYxOmRlOjE1OgorICAgICAgICAgICAgICAgICAgICA5NDo1MjoxNTphMDo3ZDo1MjpjOTo0YjphODoyMTpjOTpjNjpiMTplZDpjYjoKKyAgICAgICAgICAgICAgICAgICAgYzM6OTU6NjA6ZDE6MGY6ZjA6YWI6NzA6Zjg6ZGY6Y2I6NGQ6N2U6ZWM6ZDY6CisgICAgICAgICAgICAgICAgICAgIGZhOmFiOmQ5OmJkOjdmOjU0OmYyOmE1OmU5Ojc5OmZhOmQ5OmQ2Ojc2OjI0OgorICAgICAgICAgICAgICAgICAgICAyODo3MworICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgQTA6NzM6NDk6OTk6Njg6REM6ODU6NUI6NjU6RTM6OUI6Mjg6MkY6NTc6OUY6QkQ6MzM6QkM6MDc6NDgKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA2ODo0MDphOTphODpiYjplNDo0Zjo1ZDo3OTpiMzowNTpiNToxNzpiMzo2MDoxMzplYjpjNjoKKyAgICAgICAgOTI6NWQ6ZTA6ZDE6ZDM6NmE6ZmU6ZmI6YmU6OWI6NmQ6YmY6Yzc6MDU6NmQ6NTk6MjA6YzQ6CisgICAgICAgIDFjOmYwOmI3OmRhOjg0OjU4OjAyOjYzOmZhOjQ4OjE2OmVmOjRmOmE1OjBiOmY3OjRhOjk4OgorICAgICAgICBmMjozZjo5ZToxYjphZDo0Nzo2Yjo2MzpjZTowODo0NzplYjo1MjozZjo3ODo5YzphZjo0ZDoKKyAgICAgICAgYWU6Zjg6ZDU6NGY6Y2Y6OWE6OTg6MmE6MTA6NDE6Mzk6NTI6YzQ6ZGQ6ZDk6OWI6MGU6ZWY6CisgICAgICAgIDkzOjAxOmFlOmIyOjJlOmNhOjY4OjQyOjI0OjQyOjZjOmIwOmIzOjNhOjNlOmNkOmU5OmRhOgorICAgICAgICA0ODpjNDoxNTpjYjplOTpmOTowNzowZjo5Mjo1MDo0OTo4YTpkZDozMTo5Nzo1ZjpjOTplOToKKyAgICAgICAgMzc6YWE6M2I6NTk6NjU6OTc6OTQ6MzI6Yzk6YjM6OWY6M2U6M2E6NjI6NTg6YzU6NDk6YWQ6CisgICAgICAgIDYyOjBlOjcxOmE1OjMyOmFhOjJmOmM2Ojg5Ojc2OjQzOjQwOjEzOjEzOjY3OjNkOmEyOjU0OgorICAgICAgICAyNToxMDpjYjpmMTozYTpmMjpkOTpmYTpkYjo0OTo1NjpiYjphNjpmZTphNzo0MTozNTpjMzoKKyAgICAgICAgZTA6ODg6NjE6Yzk6ODg6Yzc6ZGY6MzY6MTA6MjI6OTg6NTk6ZWE6YjA6NGE6ZmI6NTY6MTY6CisgICAgICAgIDczOjZlOmFjOjRkOmY3OjIyOmExOjRmOmFkOjFkOjdhOjJkOjQ1OjI3OmU1OjMwOmMxOjVlOgorICAgICAgICBmMjpkYToxMzpjYjoyNTo0Mjo1MTo5NTo0NzowMzo4Yzo2YzoyMTpjYzo3NDo0MjplZDo1MzoKKyAgICAgICAgZmY6MzM6OGI6OGY6MGY6NTc6MDE6MTY6MmY6Y2Y6YTY6ZWU6Yzk6NzA6MjI6MTQ6YmQ6ZmQ6CisgICAgICAgIGJlOjZjOjBiOjAzCitTSEExIEZpbmdlcnByaW50PTM2OkIxOjJCOjQ5OkY5OjgxOjlFOkQ3OjRDOjlFOkJDOjM4OjBGOkM2OjU2OjhGOjVEOkFDOkIyOkY3CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYTc2MDUzNjIuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9hNzYwNTM2Mi4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEzNGY0NWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYTc2MDUzNjIuMApAQCAtMCwwICsxLDc2IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSURJRENDQWdpZ0F3SUJBZ0lCSFRBTkJna3Foa2lHOXcwQkFRVUZBREE1TVFzd0NRWURWUVFHRXdKR1NURVAKK01BMEdBMVVFQ2hNR1UyOXVaWEpoTVJrd0Z3WURWUVFERXhCVGIyNWxjbUVnUTJ4aGMzTXlJRU5CTUI0WERUQXgKK01EUXdOakEzTWprME1Gb1hEVEl4TURRd05qQTNNamswTUZvd09URUxNQWtHQTFVRUJoTUNSa2t4RHpBTkJnTlYKK0JBb1RCbE52Ym1WeVlURVpNQmNHQTFVRUF4TVFVMjl1WlhKaElFTnNZWE56TWlCRFFUQ0NBU0l3RFFZSktvWkkKK2h2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSkFYU2pXZHl2QU5sc2RFK2hZMy9FaTl2WCtBTFRVNzRXK28KK1o2bS9BeHhOakc4eVI5VkJhS1FUQk1FMURKcUVRL3hjSGYrSnMrZ1hHTTJSWC91SjQrcS9UbDE4R3liVGRYbnQKKzVvVGpWK1d0S2NUME9pam5wWHVFTm1tei9WNTJ2YU10bWRPUVRpTW9mUmhqOFZRN0pwMTJXNWRDc3YrdThFN3MKKzNUbVZUb01HZitkSlFNakZBYkpVV21ZZFBmejU2VHdLbm9HNGNQQUJpK1FqVkh6SXJ2aVFIZ0NXY3RSVXoyRWoKK3ZPcjduUUtWMGJhNWNUcHBDRDhQdE9GQ3g0ajFQNWlvcDdvYzRIRng3MWhYZ1ZCNlhHdDBSZzZEQTVqRGpxaHUKKzhuWXliaWVEd25QejNCam90SlBxZFVSckJHQWdjVmVIbmZPK29KQWpQWW9rNGRvaDI4TUNBd0VBQWFNek1ERXcKK0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBUkJnTlZIUTRFQ2dRSVNxQ3FXSVRUWGp3d0N3WURWUjBQQkFRREFnRUcKK01BMEdDU3FHU0liM0RRRUJCUVVBQTRJQkFRQmF6b2Y1Rm5JVlYwc2QyWnZub2lZdzdKTm4zOVl0MGpTdjl6aWwKK3pxc1d1YXN2ZkRYTHJOQVB0RXdyL0lEdmE0eVJYeloyOTl1ekd4bnE5TElSL1dGeFJMOG9zem9kdjdORDZKKy8KKzNERUljYkNkamRZMFJ6S1F4bVVrOTZCS2ZBUnpqemx2RjR4eXRiMUx5SHI0ZTRQREtFNmNDZXBuUDdKbkJCdkQKK0ZOcjQ1MGtra2RBZGF2cGhPZTlyNXlGMUJnZllFclFoSUhCQ2NZSGFQSm8ydnFaYkRXcHNtaCtSZS9uNTcwSzYKK1RrNmV6QXlObE56WlJaeGU3RUpRWTY3MFhjU3hFdHpLTzZndW5SUmFCWFczN05kajRybzF0Z1FJa2VqYW5aejIKK1pyVVlyQXFtVkNZME05SWJ3ZFIvR2pxT0M2b3lidHY4VHlXZjJUTEhsbHB3ck45TQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAyOSAoMHgxZCkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1GSSwgTz1Tb25lcmEsIENOPVNvbmVyYSBDbGFzczIgQ0EKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEFwciAgNiAwNzoyOTo0MCAyMDAxIEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogQXByICA2IDA3OjI5OjQwIDIwMjEgR01UCisgICAgICAgIFN1YmplY3Q6IEM9RkksIE89U29uZXJhLCBDTj1Tb25lcmEgQ2xhc3MyIENBCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDo5MDoxNzo0YTozNTo5ZDpjYTpmMDowZDo5NjpjNzo0NDpmYToxNjozNzoKKyAgICAgICAgICAgICAgICAgICAgZmM6NDg6YmQ6YmQ6N2Y6ODA6MmQ6MzU6M2I6ZTE6NmY6YTg6Njc6YTk6YmY6CisgICAgICAgICAgICAgICAgICAgIDAzOjFjOjRkOjhjOjZmOjMyOjQ3OmQ1OjQxOjY4OmE0OjEzOjA0OmMxOjM1OgorICAgICAgICAgICAgICAgICAgICAwYzo5YTo4NDo0MzpmYzo1YzoxZDpmZjo4OTpiMzplODoxNzoxODpjZDo5MToKKyAgICAgICAgICAgICAgICAgICAgNWY6ZmI6ODk6ZTM6ZWE6YmY6NGU6NWQ6N2M6MWI6MjY6ZDM6NzU6Nzk6ZWQ6CisgICAgICAgICAgICAgICAgICAgIGU2Ojg0OmUzOjU3OmU1OmFkOjI5OmM0OmY0OjNhOjI4OmU3OmE1OjdiOjg0OgorICAgICAgICAgICAgICAgICAgICAzNjo2OTpiMzpmZDo1ZTo3NjpiZDphMzoyZDo5OTpkMzo5MDo0ZToyMzoyODoKKyAgICAgICAgICAgICAgICAgICAgN2Q6MTg6NjM6ZjE6NTQ6M2I6MjY6OWQ6NzY6NWI6OTc6NDI6YjI6ZmY6YWU6CisgICAgICAgICAgICAgICAgICAgIGYwOjRlOmVjOmRkOjM5Ojk1OjRlOjgzOjA2OjdmOmU3OjQ5OjQwOmM4OmM1OgorICAgICAgICAgICAgICAgICAgICAwMTpiMjo1NDo1YTo2NjoxZDozZDpmYzpmOTplOTozYzowYTo5ZTo4MTpiODoKKyAgICAgICAgICAgICAgICAgICAgNzA6ZjA6MDE6OGI6ZTQ6MjM6NTQ6N2M6Yzg6YWU6Zjg6OTA6MWU6MDA6OTY6CisgICAgICAgICAgICAgICAgICAgIDcyOmQ0OjU0OmNmOjYxOjIzOmJjOmVhOmZiOjlkOjAyOjk1OmQxOmI2OmI5OgorICAgICAgICAgICAgICAgICAgICA3MTozYTo2OTowODozZjowZjpiNDplMTo0MjpjNzo4ODpmNTozZjo5ODphODoKKyAgICAgICAgICAgICAgICAgICAgYTc6YmE6MWM6ZTA6NzE6NzE6ZWY6NTg6NTc6ODE6NTA6N2E6NWM6NmI6NzQ6CisgICAgICAgICAgICAgICAgICAgIDQ2OjBlOjgzOjAzOjk4OmMzOjhlOmE4OjZlOmYyOjc2OjMyOjZlOjI3OjgzOgorICAgICAgICAgICAgICAgICAgICBjMjo3MzpmMzpkYzoxODplODpiNDo5MzplYTo3NTo0NDo2YjowNDo2MDoyMDoKKyAgICAgICAgICAgICAgICAgICAgNzE6NTc6ODc6OWQ6ZjM6YmU6YTA6OTA6MjM6M2Q6OGE6MjQ6ZTE6ZGE6MjE6CisgICAgICAgICAgICAgICAgICAgIGRiOmMzCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgNEE6QTA6QUE6NTg6ODQ6RDM6NUU6M0MKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDVhOmNlOjg3OmY5OjE2OjcyOjE1OjU3OjRiOjFkOmQ5OjliOmU3OmEyOjI2OjMwOmVjOjkzOgorICAgICAgICA2NzpkZjpkNjoyZDpkMjozNDphZjpmNzozODphNTpjZTphYjoxNjpiOTphYjoyZjo3YzozNToKKyAgICAgICAgY2I6YWM6ZDA6MGY6YjQ6NGM6MmI6ZmM6ODA6ZWY6NmI6OGM6OTE6NWY6MzY6NzY6Zjc6ZGI6CisgICAgICAgIGIzOjFiOjE5OmVhOmY0OmIyOjExOmZkOjYxOjcxOjQ0OmJmOjI4OmIzOjNhOjFkOmJmOmIzOgorICAgICAgICA0MzplODo5ZjpiZjpkYzozMTowODo3MTpiMDo5ZDo4ZDpkNjozNDo0NzozMjo5MDpjNjo2NToKKyAgICAgICAgMjQ6Zjc6YTA6NGE6N2M6MDQ6NzM6OGY6Mzk6NmY6MTc6OGM6NzI6YjU6YmQ6NGI6Yzg6N2E6CisgICAgICAgIGY4OjdiOjgzOmMzOjI4OjRlOjljOjA5OmVhOjY3OjNmOmIyOjY3OjA0OjFiOmMzOjE0OmRhOgorICAgICAgICBmODplNzo0OToyNDo5MTpkMDoxZDo2YTpmYTo2MTozOTplZjo2YjplNzoyMTo3NTowNjowNzoKKyAgICAgICAgZDg6MTI6YjQ6MjE6MjA6NzA6NDI6NzE6ODE6ZGE6M2M6OWE6MzY6YmU6YTY6NWI6MGQ6NmE6CisgICAgICAgIDZjOjlhOjFmOjkxOjdiOmY5OmY5OmVmOjQyOmJhOjRlOjRlOjllOmNjOjBjOjhkOjk0OmRjOgorICAgICAgICBkOTo0NTo5Yzo1ZTplYzo0Mjo1MDo2MzphZTpmNDo1ZDpjNDpiMToxMjpkYzpjYTozYjphODoKKyAgICAgICAgMmU6OWQ6MTQ6NWE6MDU6NzU6Yjc6ZWM6ZDc6NjM6ZTI6YmE6MzU6YjY6MDQ6MDg6OTE6ZTg6CisgICAgICAgIGRhOjlkOjljOmY2OjY2OmI1OjE4OmFjOjBhOmE2OjU0OjI2OjM0OjMzOmQyOjFiOmMxOmQ0OgorICAgICAgICA3ZjoxYTozYTo4ZTowYjphYTozMjo2ZTpkYjpmYzo0ZjoyNTo5ZjpkOTozMjpjNzo5Njo1YToKKyAgICAgICAgNzA6YWM6ZGY6NGMKK1NIQTEgRmluZ2VycHJpbnQ9Mzc6Rjc6NkQ6RTY6MDc6N0M6OTA6QzU6QjE6M0U6OTM6MUE6Qjc6NDE6MTA6QjQ6RjI6RTQ6OUE6MjcKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9hN2QyY2Y2NC4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2E3ZDJjZjY0LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGU3OTdkNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9hN2QyY2Y2NC4wCkBAIC0wLDAgKzEsNTQgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJQ2lEQ0NBZzJnQXdJQkFnSVFOZndtWE5tRVQ4azlKajFYbTY3WFZqQUtCZ2dxaGtqT1BRUURBekNCaERFTAorTUFrR0ExVUVCaE1DVlZNeEZUQVRCZ05WQkFvVERIUm9ZWGQwWlN3Z1NXNWpMakU0TURZR0ExVUVDeE12S0dNcAorSURJd01EY2dkR2hoZDNSbExDQkpibU11SUMwZ1JtOXlJR0YxZEdodmNtbDZaV1FnZFhObElHOXViSGt4SkRBaQorQmdOVkJBTVRHM1JvWVhkMFpTQlFjbWx0WVhKNUlGSnZiM1FnUTBFZ0xTQkhNakFlRncwd056RXhNRFV3TURBdworTURCYUZ3MHpPREF4TVRneU16VTVOVGxhTUlHRU1Rc3dDUVlEVlFRR0V3SlZVekVWTUJNR0ExVUVDaE1NZEdoaAorZDNSbExDQkpibU11TVRnd05nWURWUVFMRXk4b1l5a2dNakF3TnlCMGFHRjNkR1VzSUVsdVl5NGdMU0JHYjNJZworWVhWMGFHOXlhWHBsWkNCMWMyVWdiMjVzZVRFa01DSUdBMVVFQXhNYmRHaGhkM1JsSUZCeWFXMWhjbmtnVW05dgorZENCRFFTQXRJRWN5TUhZd0VBWUhLb1pJemowQ0FRWUZLNEVFQUNJRFlnQUVvdFdjZ251Vm5mRlNlSWYraWhhLworQmViZm93SlBEUWZHQUZHNkRBSlNMU0trUWpuRS9vL3F5Y0crMUUzL24zcWU0ckY4bXEybmhnbHpoOUhubXVONgorcGFwdSs3cXpjTUJuaUtJMTFLT2FzZjJ0d3U4eCtxaTU4L3NJeHBIUit5bVZvMEl3UURBUEJnTlZIUk1CQWY4RQorQlRBREFRSC9NQTRHQTFVZER3RUIvd1FFQXdJQkJqQWRCZ05WSFE0RUZnUVVtdGdBTUFEbmEzK0ZHTzZMdHM2SworRFBnUjRic3dDZ1lJS29aSXpqMEVBd01EYVFBd1pnSXhBTjM0NEZkSFc2Zm1Dc085OVlDS2x6VU5HNGs4VklaMworS01xaDlIbmV0ZVk0c1BCbGNJeC9BbFRDdi8vWW9UN1p6d0l4QU1TTmxQemNVOUxjblhnV0h4VXpJMU5TNDFveAorWFozS3JyMFRLVVFOSjF1bzUyaWNFdmRZUHk1eUFsZWpqNkVVTGc9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgMzU6ZmM6MjY6NWM6ZDk6ODQ6NGY6Yzk6M2Q6MjY6M2Q6NTc6OWI6YWU6ZDc6NTYKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogZWNkc2Etd2l0aC1TSEEzODQKKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPXRoYXd0ZSwgSW5jLiwgT1U9KGMpIDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHksIENOPXRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMgorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTm92ICA1IDAwOjAwOjAwIDIwMDcgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBKYW4gMTggMjM6NTk6NTkgMjAzOCBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgTz10aGF3dGUsIEluYy4sIE9VPShjKSAyMDA3IHRoYXd0ZSwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5LCBDTj10aGF3dGUgUHJpbWFyeSBSb290IENBIC0gRzIKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogaWQtZWNQdWJsaWNLZXkKKyAgICAgICAgICAgIEVDIFB1YmxpYyBLZXk6CisgICAgICAgICAgICAgICAgcHViOiAKKyAgICAgICAgICAgICAgICAgICAgMDQ6YTI6ZDU6OWM6ODI6N2I6OTU6OWQ6ZjE6NTI6Nzg6ODc6ZmU6OGE6MTY6CisgICAgICAgICAgICAgICAgICAgIGJmOjA1OmU2OmRmOmEzOjAyOjRmOjBkOjA3OmM2OjAwOjUxOmJhOjBjOjAyOgorICAgICAgICAgICAgICAgICAgICA1MjoyZDoyMjphNDo0MjozOTpjNDpmZTo4ZjplYTpjOTpjMTpiZTpkNDo0ZDoKKyAgICAgICAgICAgICAgICAgICAgZmY6OWY6N2E6OWU6ZTI6YjE6N2M6OWE6YWQ6YTc6ODY6MDk6NzM6ODc6ZDE6CisgICAgICAgICAgICAgICAgICAgIGU3OjlhOmUzOjdhOmE1OmFhOjZlOmZiOmJhOmIzOjcwOmMwOjY3Ojg4OmEyOgorICAgICAgICAgICAgICAgICAgICAzNTpkNDphMzo5YTpiMTpmZDphZDpjMjplZjozMTpmYTphODpiOTpmMzpmYjoKKyAgICAgICAgICAgICAgICAgICAgMDg6YzY6OTE6ZDE6ZmI6Mjk6OTUKKyAgICAgICAgICAgICAgICBBU04xIE9JRDogc2VjcDM4NHIxCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICA5QTpEODowMDozMDowMDpFNzo2Qjo3Rjo4NToxODpFRTo4QjpCNjpDRTo4QTowQzpGODoxMTpFMTpCQgorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IGVjZHNhLXdpdGgtU0hBMzg0CisgICAgICAgIDMwOjY2OjAyOjMxOjAwOmRkOmY4OmUwOjU3OjQ3OjViOmE3OmU2OjBhOmMzOmJkOmY1OjgwOgorICAgICAgICA4YTo5NzozNTowZDoxYjo4OTozYzo1NDo4Njo3NzoyODpjYTphMTpmNDo3OTpkZTpiNTplNjoKKyAgICAgICAgMzg6YjA6ZjA6NjU6NzA6OGM6N2Y6MDI6NTQ6YzI6YmY6ZmY6ZDg6YTE6M2U6ZDk6Y2Y6MDI6CisgICAgICAgIDMxOjAwOmM0OjhkOjk0OmZjOmRjOjUzOmQyOmRjOjlkOjc4OjE2OjFmOjE1OjMzOjIzOjUzOgorICAgICAgICA1MjplMzo1YTozMTo1ZDo5ZDpjYTphZTpiZDoxMzoyOTo0NDowZDoyNzo1YjphODplNzo2ODoKKyAgICAgICAgOWM6MTI6Zjc6NTg6M2Y6MmU6NzI6MDI6NTc6YTM6OGY6YTE6MTQ6MmUKK1NIQTEgRmluZ2VycHJpbnQ9QUE6REI6QkM6MjI6MjM6OEY6QzQ6MDE6QTE6Mjc6QkI6Mzg6REQ6RjQ6MUQ6REI6MDg6OUU6RjA6MTIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9hYjUzNDZmNC4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2FiNTM0NmY0LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDEwMzdkNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9hYjUzNDZmNC4wCkBAIC0wLDAgKzEsNzggQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRGJUQ0NBbFdnQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFVRkFEQllNUXN3Q1FZRFZRUUdFd0pLVURFcgorTUNrR0ExVUVDaE1pU21Gd1lXNGdRMlZ5ZEdsbWFXTmhkR2x2YmlCVFpYSjJhV05sY3l3Z1NXNWpMakVjTUJvRworQTFVRUF4TVRVMlZqZFhKbFUybG5iaUJTYjI5MFEwRXhNVEFlRncwd09UQTBNRGd3TkRVMk5EZGFGdzB5T1RBMAorTURnd05EVTJORGRhTUZneEN6QUpCZ05WQkFZVEFrcFFNU3N3S1FZRFZRUUtFeUpLWVhCaGJpQkRaWEowYVdacAorWTJGMGFXOXVJRk5sY25acFkyVnpMQ0JKYm1NdU1Sd3dHZ1lEVlFRREV4TlRaV04xY21WVGFXZHVJRkp2YjNSRAorUVRFeE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBL1hlcXBSeVFCVHZMVEpzegoraTFvVVJhVG5rQmJSMzFmU0lSQ2tGLzNmck5ZZnArVGJmUGZzMzdnRDJwUlkvVjF5Zkl3L1h3Rm5kQldXNHdJOAoraDl1dXl3R093dk5teG9WRjlBTEdPclZpc3EvNm5MK2s1dFNBTUpqekRiYVRqNm5VMkRieXNQeUt5aXloRlRPVgorTWRyQUcvTHVZcG1HWXorLzNaTXFnNmgydVJNZnQ4NU9Rb1dQSXVjdUd2S1ZDYklGdFVST2Q2RWd2YW55VGdwOQorVUszMUJRMUZUMFp4L1NnK1Uvc0UyQzNYWlIxS0cvclBPN0F4bWpWdXlJc0cwd0NSOHBRSVpVeXhOQVlBZW9uaQorOE1jRFdjL1YxdWluTXJQbW1FQ0d4YzBuRW92TWU4NjNFVHhpWUFjalBpdEFicFNBQ1cyMnMyOTNielVJVVBzQworaDhVK2lRSURBUUFCbzBJd1FEQWRCZ05WSFE0RUZnUVVXL2hOVDdLbGh0UTYwdkZqbXFDK0NmWlh0OTR3RGdZRAorVlIwUEFRSC9CQVFEQWdFR01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQgorQUtDaE9CWm1McWRXSHlHY0J2b2Q3YmtpeFRnbTJFNVA3S04vZWQ1R0lhR0hkNDhIQ0pxeXBNV3ZEektZQzN4bQorS2JhYmZTVlNTVU9yVEM0cmJucHdyeFlPNHdKcyswTG1HSjFGMkZYSTZEdmQ1K0gwTGdzY05GeHNXRXI3akloUQorWDVVY3YrMnJJclZsczRXNm5nKzRyZVY2RzRwUU9oMjlEYng3VkZBTHVVS3ZWYUFZZ2ExbG1lKys1SnkveElXcgorUWJKVWI5d2x6ZTE0NG80TWpRbEozV043V21tV0FpR292VkpaNlgwMXk4aFN5bitCL3RscjAvY1I3U1hmK09mNQorcFBweWw0UlREYVhRTWhoUmRsa1ViQS9yN0YrQWpIVkRnOE9GbVA5TW5pME41SGVEazA2MWxnZUxLQk9iakJtTgorUVNkSlFPN2U1aU5FT2R5aEl0YTZBL0k9CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDEgKDB4MSkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1KUCwgTz1KYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuLCBDTj1TZWN1cmVTaWduIFJvb3RDQTExCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBBcHIgIDggMDQ6NTY6NDcgMjAwOSBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEFwciAgOCAwNDo1Njo0NyAyMDI5IEdNVAorICAgICAgICBTdWJqZWN0OiBDPUpQLCBPPUphcGFuIENlcnRpZmljYXRpb24gU2VydmljZXMsIEluYy4sIENOPVNlY3VyZVNpZ24gUm9vdENBMTEKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmZkOjc3OmFhOmE1OjFjOjkwOjA1OjNiOmNiOjRjOjliOjMzOjhiOjVhOgorICAgICAgICAgICAgICAgICAgICAxNDo0NTphNDplNzo5MDoxNjpkMTpkZjo1NzpkMjoyMToxMDphNDoxNzpmZDoKKyAgICAgICAgICAgICAgICAgICAgZGY6YWM6ZDY6MWY6YTc6ZTQ6ZGI6N2M6Zjc6ZWM6ZGY6Yjg6MDM6ZGE6OTQ6CisgICAgICAgICAgICAgICAgICAgIDU4OmZkOjVkOjcyOjdjOjhjOjNmOjVmOjAxOjY3Ojc0OjE1Ojk2OmUzOjAyOgorICAgICAgICAgICAgICAgICAgICAzYzo4NzpkYjphZTpjYjowMTo4ZTpjMjpmMzo2NjpjNjo4NTo0NTpmNDowMjoKKyAgICAgICAgICAgICAgICAgICAgYzY6M2E6YjU6NjI6YjI6YWY6ZmE6OWM6YmY6YTQ6ZTY6ZDQ6ODA6MzA6OTg6CisgICAgICAgICAgICAgICAgICAgIGYzOjBkOmI2OjkzOjhmOmE5OmQ0OmQ4OjM2OmYyOmIwOmZjOjhhOmNhOjJjOgorICAgICAgICAgICAgICAgICAgICBhMToxNTozMzo5NTozMTpkYTpjMDoxYjpmMjplZTo2Mjo5OTo4Njo2MzozZjoKKyAgICAgICAgICAgICAgICAgICAgYmY6ZGQ6OTM6MmE6ODM6YTg6NzY6Yjk6MTM6MWY6Yjc6Y2U6NGU6NDI6ODU6CisgICAgICAgICAgICAgICAgICAgIDhmOjIyOmU3OjJlOjFhOmYyOjk1OjA5OmIyOjA1OmI1OjQ0OjRlOjc3OmExOgorICAgICAgICAgICAgICAgICAgICAyMDpiZDphOTpmMjo0ZTowYTo3ZDo1MDphZDpmNTowNTowZDo0NTo0Zjo0NjoKKyAgICAgICAgICAgICAgICAgICAgNzE6ZmQ6Mjg6M2U6NTM6ZmI6MDQ6ZDg6MmQ6ZDc6NjU6MWQ6NGE6MWI6ZmE6CisgICAgICAgICAgICAgICAgICAgIGNmOjNiOmIwOjMxOjlhOjM1OjZlOmM4OjhiOjA2OmQzOjAwOjkxOmYyOjk0OgorICAgICAgICAgICAgICAgICAgICAwODo2NTo0YzpiMTozNDowNjowMDo3YTo4OTplMjpmMDpjNzowMzo1OTpjZjoKKyAgICAgICAgICAgICAgICAgICAgZDU6ZDY6ZTg6YTc6MzI6YjM6ZTY6OTg6NDA6ODY6YzU6Y2Q6Mjc6MTI6OGI6CisgICAgICAgICAgICAgICAgICAgIGNjOjdiOmNlOmI3OjExOjNjOjYyOjYwOjA3OjIzOjNlOjJiOjQwOjZlOjk0OgorICAgICAgICAgICAgICAgICAgICA4MDowOTo2ZDpiNjpiMzo2Zjo3Nzo2ZjozNTowODo1MDpmYjowMjo4NzpjNToKKyAgICAgICAgICAgICAgICAgICAgM2U6ODkKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDVCOkY4OjREOjRGOkIyOkE1Ojg2OkQ0OjNBOkQyOkYxOjYzOjlBOkEwOkJFOjA5OkY2OjU3OkI3OkRFCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBhMDphMTozODoxNjo2NjoyZTphNzo1NjoxZjoyMTo5YzowNjpmYToxZDplZDpiOToyMjpjNToKKyAgICAgICAgMzg6MjY6ZDg6NGU6NGY6ZWM6YTM6N2Y6Nzk6ZGU6NDY6MjE6YTE6ODc6Nzc6OGY6MDc6MDg6CisgICAgICAgIDlhOmIyOmE0OmM1OmFmOjBmOjMyOjk4OjBiOjdjOjY2OjI5OmI2OjliOjdkOjI1OjUyOjQ5OgorICAgICAgICA0MzphYjo0YzoyZToyYjo2ZTo3YTo3MDphZjoxNjowZTplMzowMjo2YzpmYjo0MjplNjoxODoKKyAgICAgICAgOWQ6NDU6ZDg6NTU6Yzg6ZTg6M2I6ZGQ6ZTc6ZTE6ZjQ6MmU6MGI6MWM6MzQ6NWM6NmM6NTg6CisgICAgICAgIDRhOmZiOjhjOjg4OjUwOjVmOjk1OjFjOmJmOmVkOmFiOjIyOmI1OjY1OmIzOjg1OmJhOjllOgorICAgICAgICAwZjpiODphZDplNTo3YToxYjo4YTo1MDozYToxZDpiZDowZDpiYzo3Yjo1NDo1MDowYjpiOToKKyAgICAgICAgNDI6YWY6NTU6YTA6MTg6ODE6YWQ6NjU6OTk6ZWY6YmU6ZTQ6OWM6YmY6YzQ6ODU6YWI6NDE6CisgICAgICAgIGIyOjU0OjZmOmRjOjI1OmNkOmVkOjc4OmUyOjhlOjBjOjhkOjA5OjQ5OmRkOjYzOjdiOjVhOgorICAgICAgICA2OTo5NjowMjoyMTphODpiZDo1Mjo1OTplOTo3ZDozNTpjYjpjODo1MjpjYTo3Zjo4MTpmZToKKyAgICAgICAgZDk6NmI6ZDM6Zjc6MTE6ZWQ6MjU6ZGY6Zjg6ZTc6Zjk6YTQ6ZmE6NzI6OTc6ODQ6NTM6MGQ6CisgICAgICAgIGE1OmQwOjMyOjE4OjUxOjc2OjU5OjE0OjZjOjBmOmViOmVjOjVmOjgwOjhjOjc1OjQzOjgzOgorICAgICAgICBjMzo4NTo5ODpmZjo0Yzo5ZToyZDowZDplNDo3Nzo4Mzo5Mzo0ZTpiNTo5NjowNzo4YjoyODoKKyAgICAgICAgMTM6OWI6OGM6MTk6OGQ6NDE6Mjc6NDk6NDA6ZWU6ZGU6ZTY6MjM6NDQ6Mzk6ZGM6YTE6MjI6CisgICAgICAgIGQ2OmJhOjAzOmYyCitTSEExIEZpbmdlcnByaW50PTNCOkM0OjlGOjQ4OkY4OkYzOjczOkEwOjlDOjFFOkJEOkY4OjVCOkIxOkMzOjY1OkM3OkQ4OjExOkIzCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYWRkNjczNDUuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9hZGQ2NzM0NS4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgxMzZhNjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYWRkNjczNDUuMApAQCAtMCwwICsxLDk2IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUdmVENDQldXZ0F3SUJBZ0lDQVFNd0RRWUpLb1pJaHZjTkFRRUVCUUF3Z2E4eEN6QUpCZ05WQkFZVEFraFYKK01SQXdEZ1lEVlFRSUV3ZElkVzVuWVhKNU1SRXdEd1lEVlFRSEV3aENkV1JoY0dWemRERW5NQ1VHQTFVRUNoTWUKK1RtVjBURzlqYXlCSVlXeHZlbUYwWW1sNmRHOXVjMkZuYVNCTFpuUXVNUm93R0FZRFZRUUxFeEZVWVc1MWMybDAKK2RtRnVlV3RwWVdSdmF6RTJNRFFHQTFVRUF4TXRUbVYwVEc5amF5QkxiM3BxWldkNWVtOXBJQ2hEYkdGemN5QkIKK0tTQlVZVzUxYzJsMGRtRnVlV3RwWVdSdk1CNFhEVGs1TURJeU5ESXpNVFEwTjFvWERURTVNREl4T1RJek1UUTAKK04xb3dnYTh4Q3pBSkJnTlZCQVlUQWtoVk1SQXdEZ1lEVlFRSUV3ZElkVzVuWVhKNU1SRXdEd1lEVlFRSEV3aEMKK2RXUmhjR1Z6ZERFbk1DVUdBMVVFQ2hNZVRtVjBURzlqYXlCSVlXeHZlbUYwWW1sNmRHOXVjMkZuYVNCTFpuUXUKK01Sb3dHQVlEVlFRTEV4RlVZVzUxYzJsMGRtRnVlV3RwWVdSdmF6RTJNRFFHQTFVRUF4TXRUbVYwVEc5amF5QkwKK2IzcHFaV2Q1ZW05cElDaERiR0Z6Y3lCQktTQlVZVzUxYzJsMGRtRnVlV3RwWVdSdk1JSUJJakFOQmdrcWhraUcKKzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF2SFNNRDd0TTlEY2VxUVdDMk9iaGJIRHFlTFZ1MFRoRURhaUQKK3psM1MxdFdCeGRSTDUxdVVjQ2JiTzUxcVRHTDNjZk5rMW1FN1BldHpvemZaeitxTWtqdk45d2ZjWm5TWDlFVWkKKzNmUmM0TDl0ODc1bE0rUVZPci9ibUpCVk9NVHRwbFZqQzdCNEJQVGpic0UvanZ4UmVCK1Nub1BDL3Rtd3FjbTgKK1dnRC9xYWlZZFB2MkxENFZPUTIyQkZXb0RwZ2dRck94SmExK21tOWRVN0dyRFB6cjRQTjZzNml6LzBiMlk2TFkKK09waDd0cXlGLzdBbFQzUmo1eE1IcFFxUEJmZkFaRzkrcHllQWx0N1VMb1pneDJzclhuTjdGK2VSUDJRTTJFc2kKK05DdWJNdkpJSDUraENvUjY0c0t0bHoyTzFjSDVWcU5RNmNhMCtwaWk3cFhtS2dPTTN3SURBUUFCbzRJQ256Q0MKK0Fwc3dEZ1lEVlIwUEFRSC9CQVFEQWdBR01CSUdBMVVkRXdFQi93UUlNQVlCQWY4Q0FRUXdFUVlKWUlaSUFZYjQKK1FnRUJCQVFEQWdBSE1JSUNZQVlKWUlaSUFZYjRRZ0VOQklJQ1VSYUNBazFHU1VkWlJVeEZUU0VnUlhwbGJpQjAKK1lXNTFjMmwwZG1GdWVTQmhJRTVsZEV4dlkyc2dTMlowTGlCQmJIUmhiR0Z1YjNNZ1UzcHZiR2RoYkhSaGRHRnoKK2FTQkdaV3gwWlhSbGJHVnBZbVZ1SUd4bGFYSjBJR1ZzYW1GeVlYTnZheUJoYkdGd2FtRnVJR3RsYzNwMWJIUXUKK0lFRWdhR2wwWld4bGMybDBaWE1nWm05c2VXRnRZWFJoZENCaElFNWxkRXh2WTJzZ1MyWjBMaUIwWlhKdFpXdG0KK1pXeGxiRzl6YzJWbkxXSnBlblJ2YzJsMFlYTmhJSFpsWkdrdUlFRWdaR2xuYVhSaGJHbHpJR0ZzWVdseVlYTWcKK1pXeG1iMmRoWkdGellXNWhheUJtWld4MFpYUmxiR1VnWVhvZ1pXeHZhWEowSUdWc2JHVnViM0o2WlhOcElHVnMKK2FtRnlZWE1nYldWbmRHVjBaV3hsTGlCQmVpQmxiR3BoY21GeklHeGxhWEpoYzJFZ2JXVm5kR0ZzWVd4b1lYUnYKK0lHRWdUbVYwVEc5amF5QkxablF1SUVsdWRHVnlibVYwSUdodmJteGhjR3BoYmlCaElHaDBkSEJ6T2k4dmQzZDMKK0xtNWxkR3h2WTJzdWJtVjBMMlJ2WTNNZ1kybHRaVzRnZG1GbmVTQnJaWEpvWlhSdklHRjZJR1ZzYkdWdWIzSjYKK1pYTkFibVYwYkc5amF5NXVaWFFnWlMxdFlXbHNJR05wYldWdUxpQkpUVkJQVWxSQlRsUWhJRlJvWlNCcGMzTjEKK1lXNWpaU0JoYm1RZ2RHaGxJSFZ6WlNCdlppQjBhR2x6SUdObGNuUnBabWxqWVhSbElHbHpJSE4xWW1wbFkzUWcKK2RHOGdkR2hsSUU1bGRFeHZZMnNnUTFCVElHRjJZV2xzWVdKc1pTQmhkQ0JvZEhSd2N6b3ZMM2QzZHk1dVpYUnMKK2IyTnJMbTVsZEM5a2IyTnpJRzl5SUdKNUlHVXRiV0ZwYkNCaGRDQmpjSE5BYm1WMGJHOWpheTV1WlhRdU1BMEcKK0NTcUdTSWIzRFFFQkJBVUFBNElCQVFCSUpFYjN1bFp2K3Nnb0EwQk81VEU1YXlaclUzL2IzOS96Y1QwbXdCUU8KK3htZDdJNmdNYzkwQnU4YktiamM1VmRYSGpGWWdEaWdLRHRJcXBMQkpVc1k0Qi82K0NnbU0wWmpQeXRvVU1hRlAKKzBqbjhEeEVzUThQZHE1UEhWVDVIZkJnYUFOenplOWp5ZjFKc0lQUUxYMmxTOU83NHNpbGc2K05KTVNFTjFyVVEKK1FlSkJDV3ppR3BwV1MzY0M5cUNibWllSDZGVXBjY0tRbjBWNEd1RVZaRDNRRHRpZ2RwK3V4ZEF1NnRZUFZ1eGsKK2YxcWJGRmdCSjM0VFVNZHJLdVpvUEw5Y29Bb2I0UTU2NmVLQXcrbnA5djFzRVo3UTVTZ25LMVF5UWhTQ2RlWksKKzhDdG1kV09Nb3ZzRVBvTU9temJ3R09RbUlNT004Q2dIclR3WFpvaTEvYmFJCistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDI1OSAoMHgxMDMpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IG1kNVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1IVSwgU1Q9SHVuZ2FyeSwgTD1CdWRhcGVzdCwgTz1OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4sIE9VPVRhbnVzaXR2YW55a2lhZG9rLCBDTj1OZXRMb2NrIEtvemplZ3l6b2kgKENsYXNzIEEpIFRhbnVzaXR2YW55a2lhZG8KKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEZlYiAyNCAyMzoxNDo0NyAxOTk5IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogRmViIDE5IDIzOjE0OjQ3IDIwMTkgR01UCisgICAgICAgIFN1YmplY3Q6IEM9SFUsIFNUPUh1bmdhcnksIEw9QnVkYXBlc3QsIE89TmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuLCBPVT1UYW51c2l0dmFueWtpYWRvaywgQ049TmV0TG9jayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpiYzo3NDo4YzowZjpiYjo0YzpmNDozNzoxZTphOTowNTo4MjpkODplNjoKKyAgICAgICAgICAgICAgICAgICAgZTE6NmM6NzA6ZWE6Nzg6YjU6NmU6ZDE6Mzg6NDQ6MGQ6YTg6ODM6Y2U6NWQ6CisgICAgICAgICAgICAgICAgICAgIGQyOmQ2OmQ1OjgxOmM1OmQ0OjRiOmU3OjViOjk0OjcwOjI2OmRiOjNiOjlkOgorICAgICAgICAgICAgICAgICAgICA2YTo0Yzo2MjpmNzo3MTpmMzo2NDpkNjo2MTozYjozZDplYjo3MzphMzozNzoKKyAgICAgICAgICAgICAgICAgICAgZDk6Y2Y6ZWE6OGM6OTI6M2I6Y2Q6Zjc6MDc6ZGM6NjY6NzQ6OTc6ZjQ6NDU6CisgICAgICAgICAgICAgICAgICAgIDIyOmRkOmY0OjVjOmUwOmJmOjZkOmYzOmJlOjY1OjMzOmU0OjE1OjNhOmJmOgorICAgICAgICAgICAgICAgICAgICBkYjo5ODo5MDo1NTozODpjNDplZDphNjo1NTo2MzowYjpiMDo3ODowNDpmNDoKKyAgICAgICAgICAgICAgICAgICAgZTM6NmU6YzE6M2Y6OGU6ZmM6NTE6Nzg6MWY6OTI6OWU6ODM6YzI6ZmU6ZDk6CisgICAgICAgICAgICAgICAgICAgIGIwOmE5OmM5OmJjOjVhOjAwOmZmOmE5OmE4Ojk4Ojc0OmZiOmY2OjJjOjNlOgorICAgICAgICAgICAgICAgICAgICAxNTozOTowZDpiNjowNDo1NTphODowZTo5ODoyMDo0MjpiMzpiMToyNTphZDoKKyAgICAgICAgICAgICAgICAgICAgN2U6OWE6NmY6NWQ6NTM6YjE6YWI6MGM6ZmM6ZWI6ZTA6ZjM6N2E6YjM6YTg6CisgICAgICAgICAgICAgICAgICAgIGIzOmZmOjQ2OmY2OjYzOmEyOmQ4OjNhOjk4OjdiOmI2OmFjOjg1OmZmOmIwOgorICAgICAgICAgICAgICAgICAgICAyNTo0Zjo3NDo2MzplNzoxMzowNzphNTowYTo4ZjowNTpmNzpjMDo2NDo2ZjoKKyAgICAgICAgICAgICAgICAgICAgN2U6YTc6Mjc6ODA6OTY6ZGU6ZDQ6MmU6ODY6NjA6Yzc6NmI6MmI6NWU6NzM6CisgICAgICAgICAgICAgICAgICAgIDdiOjE3OmU3OjkxOjNmOjY0OjBjOmQ4OjRiOjIyOjM0OjJiOjliOjMyOmYyOgorICAgICAgICAgICAgICAgICAgICA0ODoxZjo5ZjphMTowYTo4NDo3YTplMjpjMjphZDo5NzozZDo4ZTpkNTpjMToKKyAgICAgICAgICAgICAgICAgICAgZjk6NTY6YTM6NTA6ZTk6YzY6YjQ6ZmE6OTg6YTI6ZWU6OTU6ZTY6MmE6MDM6CisgICAgICAgICAgICAgICAgICAgIDhjOmRmCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFLCBwYXRobGVuOjQKKyAgICAgICAgICAgIE5ldHNjYXBlIENlcnQgVHlwZTogCisgICAgICAgICAgICAgICAgU1NMIENBLCBTL01JTUUgQ0EsIE9iamVjdCBTaWduaW5nIENBCisgICAgICAgICAgICBOZXRzY2FwZSBDb21tZW50OiAKKyAgICAgICAgICAgICAgICBGSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQuIEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNAbmV0bG9jay5uZXQuCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogbWQ1V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgNDg6MjQ6NDY6Zjc6YmE6NTY6NmY6ZmE6Yzg6Mjg6MDM6NDA6NGU6ZTU6MzE6Mzk6NmI6MjY6CisgICAgICAgIDZiOjUzOjdmOmRiOmRmOmRmOmYzOjcxOjNkOjI2OmMwOjE0OjBlOmM2OjY3OjdiOjIzOmE4OgorICAgICAgICAwYzo3MzpkZDowMTpiYjpjNjpjYTo2ZTozNzozOTo1NTpkNTpjNzo4Yzo1NjoyMDowZToyODoKKyAgICAgICAgMGE6MGU6ZDI6MmE6YTQ6YjA6NDk6NTI6YzY6Mzg6MDc6ZmU6YmU6MGE6MDk6OGM6ZDE6OTg6CisgICAgICAgIGNmOmNhOmRhOjE0OjMxOmExOjRmOmQyOjM5OmZjOjBmOjExOjJjOjQzOmMzOmRkOmFiOjkzOgorICAgICAgICBjNzo1NTozZTo0Nzo3YzoxODoxYTowMDpkYzpmMzo3YjpkODpmMjo3Zjo1Mjo2YzoyMDpmNDoKKyAgICAgICAgMGI6NWY6Njk6NTI6ZjQ6ZWU6Zjg6YjI6Mjk6NjA6ZWI6ZTM6NDk6MzE6MjE6MGQ6ZDY6YjU6CisgICAgICAgIDEwOjQxOmUyOjQxOjA5OjZjOmUyOjFhOjlhOjU2OjRiOjc3OjAyOmY2OmEwOjliOjlhOjI3OgorICAgICAgICA4NzplODo1NToyOTo3MTpjMjo5MDo5Zjo0NTo3ODoxYTplMToxNTo2NDozZDpkMDowZTpkODoKKyAgICAgICAgYTA6NzY6OWY6YWU6YzU6ZDA6MmU6ZWE6ZDY6MGY6NTY6ZWM6NjQ6N2Y6NWE6OWI6MTQ6NTg6CisgICAgICAgIDAxOjI3OjdlOjEzOjUwOmM3OjZiOjJhOmU2OjY4OjNjOmJmOjVjOmEwOjBhOjFiOmUxOjBlOgorICAgICAgICA3YTplOTplMjo4MDpjMzplOTplOTpmNjpmZDo2YzoxMTo5ZTpkMDplNToyODoyNzoyYjo1NDoKKyAgICAgICAgMzI6NDI6MTQ6ODI6NzU6ZTY6NGE6ZjA6MmI6NjY6NzU6NjM6OGM6YTI6ZmI6MDQ6M2U6ODM6CisgICAgICAgIDBlOjliOjM2OmYwOjE4OmU0OjI2OjIwOmMzOjhjOmYwOjI4OjA3OmFkOjNjOjE3OjY2Ojg4OgorICAgICAgICBiNTpmZDpiNjo4OAorU0hBMSBGaW5nZXJwcmludD1BQzpFRDo1Rjo2NTo1MzpGRDoyNTpDRTowMTo1RjoxRjo3QTo0ODozQjo2QTo3NDo5Rjo2MTo3ODpDNgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2IwZjNlNzZlLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYjBmM2U3NmUuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNTQ0MTY4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2IwZjNlNzZlLjAKQEAgLTAsMCArMSw3OSBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEZFRDQ0FsMmdBd0lCQWdJTEJBQUFBQUFCRlV0YXc1UXdEUVlKS29aSWh2Y05BUUVGQlFBd1Z6RUxNQWtHCitBMVVFQmhNQ1FrVXhHVEFYQmdOVkJBb1RFRWRzYjJKaGJGTnBaMjRnYm5ZdGMyRXhFREFPQmdOVkJBc1RCMUp2CitiM1FnUTBFeEd6QVpCZ05WQkFNVEVrZHNiMkpoYkZOcFoyNGdVbTl2ZENCRFFUQWVGdzA1T0RBNU1ERXhNakF3CitNREJhRncweU9EQXhNamd4TWpBd01EQmFNRmN4Q3pBSkJnTlZCQVlUQWtKRk1Sa3dGd1lEVlFRS0V4QkhiRzlpCitZV3hUYVdkdUlHNTJMWE5oTVJBd0RnWURWUVFMRXdkU2IyOTBJRU5CTVJzd0dRWURWUVFERXhKSGJHOWlZV3hUCithV2R1SUZKdmIzUWdRMEV3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRGFEdWFaCitqYzZqNDArS2Z2dnhpNE1sYStwSUgvRXFzTG1WRVFTOThHUFI0bWRtenh6ZHp4dElLKzZOaVk2YXJ5bUFaYXZwCit4eTBTeTZzY1RIQUhvVDBLTU0wVmpVLzQzZFNNVUJVYzcxRHV4QzczL09sUzhwRjk0RzNWTlRDT1hrTno4a0hwCisxV3Jqc29rNlZqazRid1k4aUdsYktrM0ZwMVM0YkluTW0vazh5dVg5aWZVU1BKSjRsdGJjZEc2VFJHSFJqY2RHCitzblVPaHVnWml0VnRiTlY0RnBXaTZjZ0tPT3Z5SkJOUGMxU1RFNFU2Rzd3ZU5MV0xCWXk1ZDR1eDJ4OGdrYXNKCitVMjZRem5zM2RMbHdSNUVpVVdNV2VhNnhya0VtQ01nWks5Rkdxa2pXWkNyWGd6VC9MQ3JCYkJsRFNnZUY1OU44Cis5aUZvNytyeVVwOS9rNURQQWdNQkFBR2pRakJBTUE0R0ExVWREd0VCL3dRRUF3SUJCakFQQmdOVkhSTUJBZjhFCitCVEFEQVFIL01CMEdBMVVkRGdRV0JCUmdlMllhUlEyWHlvbFFMMzBFelRTby8vejlTekFOQmdrcWhraUc5dzBCCitBUVVGQUFPQ0FRRUExblBuZkU5MjBJMi83THFpdmpURktESzFmUHhzbkN3cnZRbWVVNzlyWHFvUlNMYmxDS096Cit5ajFoVGROR0NiTSt3NkRqWTFVYjhycnZyVG5oUTdrNG8rWXZpaVk3NzZCUVZ2bkdDdjA0emNRTGNGR1VsNWdFCiszOE5mbE5VVnlSUkJuTVJkZFdRVkRmOVZNT3lHai84Tjd5eTVZMGIycXZ6ZnZHbjlMaEpJWkpyZ2xmQ203eW1QCitBYkVWdFF3ZHBmNXBMR2trZUI2enB4eHhZdTdLeUplc0YxMkt3dmhIaG00cXhGWXhsZEJuaVlVcitXeW1YVWFkCitES3FDNUpsUjNYQzMyMVk5WWVScTRWelc5djQ5M2tITUI2NWpVcjlUVS9RcjZjZjl0dmVDWDRYU1FSamJnYk1FCitITVVmcElCdkZTREozZ3lJQ2gzV1psWGkvRWpKS1NacDRBPT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDA0OjAwOjAwOjAwOjAwOjAxOjE1OjRiOjVhOmMzOjk0CisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9QkUsIE89R2xvYmFsU2lnbiBudi1zYSwgT1U9Um9vdCBDQSwgQ049R2xvYmFsU2lnbiBSb290IENBCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBTZXAgIDEgMTI6MDA6MDAgMTk5OCBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEphbiAyOCAxMjowMDowMCAyMDI4IEdNVAorICAgICAgICBTdWJqZWN0OiBDPUJFLCBPPUdsb2JhbFNpZ24gbnYtc2EsIE9VPVJvb3QgQ0EsIENOPUdsb2JhbFNpZ24gUm9vdCBDQQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6ZGE6MGU6ZTY6OTk6OGQ6Y2U6YTM6ZTM6NGY6OGE6N2U6ZmI6ZjE6OGI6CisgICAgICAgICAgICAgICAgICAgIDgzOjI1OjZiOmVhOjQ4OjFmOmYxOjJhOmIwOmI5Ojk1OjExOjA0OmJkOmYwOgorICAgICAgICAgICAgICAgICAgICA2MzpkMTplMjo2Nzo2NjpjZjoxYzpkZDpjZjoxYjo0ODoyYjplZTo4ZDo4OToKKyAgICAgICAgICAgICAgICAgICAgOGU6OWE6YWY6Mjk6ODA6NjU6YWI6ZTk6Yzc6MmQ6MTI6Y2I6YWI6MWM6NGM6CisgICAgICAgICAgICAgICAgICAgIDcwOjA3OmExOjNkOjBhOjMwOmNkOjE1OjhkOjRmOmY4OmRkOmQ0OjhjOjUwOgorICAgICAgICAgICAgICAgICAgICAxNToxYzplZjo1MDplZTpjNDoyZTpmNzpmYzplOTo1MjpmMjo5MTo3ZDplMDoKKyAgICAgICAgICAgICAgICAgICAgNmQ6ZDU6MzU6MzA6OGU6NWU6NDM6NzM6ZjI6NDE6ZTk6ZDU6NmE6ZTM6YjI6CisgICAgICAgICAgICAgICAgICAgIDg5OjNhOjU2OjM5OjM4OjZmOjA2OjNjOjg4OjY5OjViOjJhOjRkOmM1OmE3OgorICAgICAgICAgICAgICAgICAgICA1NDpiODo2Yzo4OTpjYzo5YjpmOTozYzpjYTplNTpmZDo4OTpmNToxMjozYzoKKyAgICAgICAgICAgICAgICAgICAgOTI6Nzg6OTY6ZDY6ZGM6NzQ6NmU6OTM6NDQ6NjE6ZDE6OGQ6Yzc6NDY6YjI6CisgICAgICAgICAgICAgICAgICAgIDc1OjBlOjg2OmU4OjE5OjhhOmQ1OjZkOjZjOmQ1Ojc4OjE2Ojk1OmEyOmU5OgorICAgICAgICAgICAgICAgICAgICBjODowYTozODplYjpmMjoyNDoxMzo0Zjo3Mzo1NDo5MzoxMzo4NTozYToxYjoKKyAgICAgICAgICAgICAgICAgICAgYmM6MWU6MzQ6YjU6OGI6MDU6OGM6Yjk6Nzc6OGI6YjE6ZGI6MWY6MjA6OTE6CisgICAgICAgICAgICAgICAgICAgIGFiOjA5OjUzOjZlOjkwOmNlOjdiOjM3Ojc0OmI5OjcwOjQ3OjkxOjIyOjUxOgorICAgICAgICAgICAgICAgICAgICA2MzoxNjo3OTphZTpiMTphZTo0MToyNjowODpjODoxOToyYjpkMTo0NjphYToKKyAgICAgICAgICAgICAgICAgICAgNDg6ZDY6NjQ6MmE6ZDc6ODM6MzQ6ZmY6MmM6MmE6YzE6NmM6MTk6NDM6NGE6CisgICAgICAgICAgICAgICAgICAgIDA3Ojg1OmU3OmQzOjdjOmY2OjIxOjY4OmVmOmVhOmYyOjUyOjlmOjdmOjkzOgorICAgICAgICAgICAgICAgICAgICA5MDpjZgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDYwOjdCOjY2OjFBOjQ1OjBEOjk3OkNBOjg5OjUwOjJGOjdEOjA0OkNEOjM0OkE4OkZGOkZDOkZEOjRCCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIGQ2OjczOmU3OjdjOjRmOjc2OmQwOjhkOmJmOmVjOmJhOmEyOmJlOjM0OmM1OjI4OjMyOmI1OgorICAgICAgICA3YzpmYzo2Yzo5YzoyYzoyYjpiZDowOTo5ZTo1MzpiZjo2Yjo1ZTphYToxMTo0ODpiNjplNToKKyAgICAgICAgMDg6YTM6YjM6Y2E6M2Q6NjE6NGQ6ZDM6NDY6MDk6YjM6M2U6YzM6YTA6ZTM6NjM6NTU6MWI6CisgICAgICAgIGYyOmJhOmVmOmFkOjM5OmUxOjQzOmI5OjM4OmEzOmU2OjJmOjhhOjI2OjNiOmVmOmEwOjUwOgorICAgICAgICA1NjpmOTpjNjowYTpmZDozODpjZDpjNDowYjo3MDo1MTo5NDo5Nzo5ODowNDpkZjpjMzo1ZjoKKyAgICAgICAgOTQ6ZDU6MTU6Yzk6MTQ6NDE6OWM6YzQ6NWQ6NzU6NjQ6MTU6MGQ6ZmY6NTU6MzA6ZWM6ODY6CisgICAgICAgIDhmOmZmOjBkOmVmOjJjOmI5OjYzOjQ2OmY2OmFhOmZjOmRmOmJjOjY5OmZkOjJlOjEyOjQ4OgorICAgICAgICA2NDo5YTplMDo5NTpmMDphNjplZjoyOTo4ZjowMTpiMToxNTpiNTowYzoxZDphNTpmZTo2OToKKyAgICAgICAgMmM6Njk6MjQ6Nzg6MWU6YjM6YTc6MWM6NzE6NjI6ZWU6Y2E6Yzg6OTc6YWM6MTc6NWQ6OGE6CisgICAgICAgIGMyOmY4OjQ3Ojg2OjZlOjJhOmM0OjU2OjMxOjk1OmQwOjY3Ojg5Ojg1OjJiOmY5OjZjOmE2OgorICAgICAgICA1ZDo0Njo5ZDowYzphYTo4MjplNDo5OTo1MTpkZDo3MDpiNzpkYjo1NjozZDo2MTplNDo2YToKKyAgICAgICAgZTE6NWM6ZDY6ZjY6ZmU6M2Q6ZGU6NDE6Y2M6MDc6YWU6NjM6NTI6YmY6NTM6NTM6ZjQ6MmI6CisgICAgICAgIGU5OmM3OmZkOmI2OmY3OjgyOjVmOjg1OmQyOjQxOjE4OmRiOjgxOmIzOjA0OjFjOmM1OjFmOgorICAgICAgICBhNDo4MDo2ZjoxNToyMDpjOTpkZTowYzo4ODowYToxZDpkNjo2Njo1NTplMjpmYzo0ODpjOToKKyAgICAgICAgMjk6MjY6Njk6ZTAKK1NIQTEgRmluZ2VycHJpbnQ9QjE6QkM6OTY6OEI6RDQ6RjQ6OUQ6NjI6MkE6QTg6OUE6ODE6RjI6MTU6MDE6NTI6QTQ6MUQ6ODI6OUMKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9iN2RiMTg5MC4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2I3ZGIxODkwLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTYyNTY0MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9iN2RiMTg5MC4wCkBAIC0wLDAgKzEsNzggQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRGV6Q0NBbU9nQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFVRkFEQmZNUXN3Q1FZRFZRUUdFd0pVVnpFUworTUJBR0ExVUVDZ3dKVkVGSlYwRk9MVU5CTVJBd0RnWURWUVFMREFkU2IyOTBJRU5CTVNvd0tBWURWUVFERENGVQorVjBOQklGSnZiM1FnUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa3dIaGNOTURnd09ESTRNRGN5TkRNegorV2hjTk16QXhNak14TVRVMU9UVTVXakJmTVFzd0NRWURWUVFHRXdKVVZ6RVNNQkFHQTFVRUNnd0pWRUZKVjBGTworTFVOQk1SQXdEZ1lEVlFRTERBZFNiMjkwSUVOQk1Tb3dLQVlEVlFRRERDRlVWME5CSUZKdmIzUWdRMlZ5ZEdsbQorYVdOaGRHbHZiaUJCZFhSb2IzSnBkSGt3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQgorQVFDd2ZuSzRwQU9VNXFmZUNUaVJTaEZBaDZkOFdXUVVlN1VSRU4zK3Y5WEF1MWJpaFNYME5YSVArRlBRUWVGRQorQWNLMEhNTXhRaFpIaFRNaWRySUtidy9sSlZCUGhZYSt2NWd1RUdjZXZoRUZoZ1dReEZuUWZIZ1FzSUJjdCtISAorSzNYTGZKK3V0ZEdkSXpkanA5eENvaTJTQkJ0UXdYdTRQaHZKVmdTTEwxS2JyYWxXNmNIL3JhbFloekMyZ2ZlWAorUmZ3WlZ6c3JiK1JIOUpsRi9oM3grSmVqaUIwM0hGeVA0SFlsbWxENG9GVC9SSkIySTlJeXhzT3JCci84KzcvegorclgyU1lnSmJLZE0xbzVPYVEyUmdYYkw2TXY4N0JLOU5RR3I1eCtQdkkvMXJ5K1VQaXpnTjdncjgvZytZbnpBeAorM1d4U1pmbUxnYjRpNFJ4WUE3cVJHNGtIQWdNQkFBR2pRakJBTUE0R0ExVWREd0VCL3dRRUF3SUJCakFQQmdOVgorSFJNQkFmOEVCVEFEQVFIL01CMEdBMVVkRGdRV0JCUnFPRnNtamQ2TFd2SlBlbFNER1JqakNEV211akFOQmdrcQoraGtpRzl3MEJBUVVGQUFPQ0FRRUFQTlYzUGRyZmlicUhEQWhVYWlCUWtyNndRVDI1Sm1TRENpL29RTUNYS0NlQworTUVySmsvOXE1NllBZjRsQ210WVI1VlBPTDh6eTJnWEUvdUpReERxR2ZjemFmaEFKTzVJMUtsT3kvdXNyQmRscworWGViUTc5TnFacDRWS0lWNjZJSUFyQjZuQ1dsV1F0Tm9VUmkrVkpxL1JFRzZTYjRndW1sYzdyaDN6YzVzSDYyRAorbGhoOURyVVVPWVR4S09rdG81NTdIbnB5V29PemVXL3Z0UHpRQ3FWWVQwYmYrMjE1V2ZLRUlsS3VEOHo3ZkR2bgorYXNwSFljTjYrTk9TQkIrNElJVGhObFFXeDBEZU80cHozTi9HQ1V6ZjdOci8xRk5Db2NueVloMGlnenlYeGZrWgorWWllc1pTTFgwenpHNVk2eVU4eEp6cnd3L25zT001RDc3ZElVa1I4SHJ3PT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMSAoMHgxKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVRXLCBPPVRBSVdBTi1DQSwgT1U9Um9vdCBDQSwgQ049VFdDQSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5CisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBBdWcgMjggMDc6MjQ6MzMgMjAwOCBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IERlYyAzMSAxNTo1OTo1OSAyMDMwIEdNVAorICAgICAgICBTdWJqZWN0OiBDPVRXLCBPPVRBSVdBTi1DQSwgT1U9Um9vdCBDQSwgQ049VFdDQSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5CisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpiMDo3ZTo3MjpiODphNDowMzo5NDplNjphNzpkZTowOTozODo5MTo0YToKKyAgICAgICAgICAgICAgICAgICAgMTE6NDA6ODc6YTc6N2M6NTk6NjQ6MTQ6N2I6YjU6MTE6MTA6ZGQ6ZmU6YmY6CisgICAgICAgICAgICAgICAgICAgIGQ1OmMwOmJiOjU2OmUyOjg1OjI1OmY0OjM1OjcyOjBmOmY4OjUzOmQwOjQxOgorICAgICAgICAgICAgICAgICAgICBlMTo0NDowMTpjMjpiNDoxYzpjMzozMTo0MjoxNjo0Nzo4NTozMzoyMjo3NjoKKyAgICAgICAgICAgICAgICAgICAgYjI6MGE6NmY6MGY6ZTU6MjU6NTA6NGY6ODU6ODY6YmU6YmY6OTg6MmU6MTA6CisgICAgICAgICAgICAgICAgICAgIDY3OjFlOmJlOjExOjA1Ojg2OjA1OjkwOmM0OjU5OmQwOjdjOjc4OjEwOmIwOgorICAgICAgICAgICAgICAgICAgICA4MDo1YzpiNzplMTpjNzoyYjo3NTpjYjo3Yzo5ZjphZTpiNTpkMTo5ZDoyMzoKKyAgICAgICAgICAgICAgICAgICAgMzc6NjM6YTc6ZGM6NDI6YTI6MmQ6OTI6MDQ6MWI6NTA6YzE6N2I6Yjg6M2U6CisgICAgICAgICAgICAgICAgICAgIDFiOmM5OjU2OjA0OjhiOjJmOjUyOjliOmFkOmE5OjU2OmU5OmMxOmZmOmFkOgorICAgICAgICAgICAgICAgICAgICBhOTo1ODo4NzozMDpiNjo4MTpmNzo5Nzo0NTpmYzoxOTo1NzozYjoyYjo2ZjoKKyAgICAgICAgICAgICAgICAgICAgZTQ6NDc6ZjQ6OTk6NDU6ZmU6MWQ6ZjE6Zjg6OTc6YTM6ODg6MWQ6Mzc6MWM6CisgICAgICAgICAgICAgICAgICAgIDVjOjhmOmUwOjc2OjI1OjlhOjUwOmY4OmEwOjU0OmZmOjQ0OjkwOjc2OjIzOgorICAgICAgICAgICAgICAgICAgICBkMjozMjpjNjpjMzphYjowNjpiZjpmYzpmYjpiZjpmMzphZDo3ZDo5Mjo2MjoKKyAgICAgICAgICAgICAgICAgICAgMDI6NWI6Mjk6ZDM6MzU6YTM6OTM6OWE6NDM6NjQ6NjA6NWQ6YjI6ZmE6MzI6CisgICAgICAgICAgICAgICAgICAgIGZmOjNiOjA0OmFmOjRkOjQwOjZhOmY5OmM3OmUzOmVmOjIzOmZkOjZiOmNiOgorICAgICAgICAgICAgICAgICAgICBlNTowZjo4YjozODowZDplZTowYTpmYzpmZTowZjo5ODo5ZjozMDozMTpkZDoKKyAgICAgICAgICAgICAgICAgICAgNmM6NTI6NjU6Zjk6OGI6ODE6YmU6MjI6ZTE6MWM6NTg6MDM6YmE6OTE6MWI6CisgICAgICAgICAgICAgICAgICAgIDg5OjA3CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgNkE6Mzg6NUI6MjY6OEQ6REU6OEI6NUE6RjI6NEY6N0E6NTQ6ODM6MTk6MTg6RTM6MDg6MzU6QTY6QkEKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgM2M6ZDU6Nzc6M2Q6ZGE6ZGY6ODk6YmE6ODc6MGM6MDg6NTQ6NmE6MjA6NTA6OTI6YmU6YjA6CisgICAgICAgIDQxOjNkOmI5OjI2OjY0OjgzOjBhOjJmOmU4OjQwOmMwOjk3OjI4OjI3OjgyOjMwOjRhOmM5OgorICAgICAgICA5MzpmZjo2YTplNzphNjowMDo3Zjo4OTo0Mjo5YTpkNjoxMTplNTo1MzpjZToyZjpjYzpmMjoKKyAgICAgICAgZGE6MDU6YzQ6ZmU6ZTI6NTA6YzQ6M2E6ODY6N2Q6Y2M6ZGE6N2U6MTA6MDk6M2I6OTI6MzU6CisgICAgICAgIDJhOjUzOmIyOmZlOmViOjJiOjA1OmQ5OjZjOjVkOmU2OmQwOmVmOmQzOjZhOjY2OjllOjE1OgorICAgICAgICAyODo4NTo3YTplODo4MjowMDphYzoxZTphNzowOTo2OTo1Njo0MjpkMzo2ODo1MToxODpiZToKKyAgICAgICAgNTQ6OWE6YmY6NDQ6NDE6YmE6NDk6YmU6MjA6YmE6Njk6NWM6ZWU6Yjg6Nzc6Y2Q6Y2U6NmM6CisgICAgICAgIDFmOmFkOjgzOjk2OjE4OjdkOjBlOmI1OjE0OjM5Ojg0OmYxOjI4OmU5OjJkOmEzOjllOjdiOgorICAgICAgICAxZTo3YTo3Mjo1YTo4MzpiMzo3OTo2ZjplZjpiNDpmYzpkMDowYTphNTo1ODo0Zjo0NjpkZjoKKyAgICAgICAgZmI6NmQ6Nzk6NTk6ZjI6ODQ6MjI6NTI6YWU6MGY6Y2M6ZmI6N2M6M2I6ZTc6NmE6Y2E6NDc6CisgICAgICAgIDYxOmMzOjdhOmY4OmQzOjkyOjA0OjFmOmI4OjIwOjg0OmUxOjM2OjU0OjE2OmM3OjQwOmRlOgorICAgICAgICAzYjo4YTo3MzpkYzpkZjpjNjowOTo0YzpkZjplYzpkYTpmZjpkNDo1Mzo0MjphMTpjOTpmMjoKKyAgICAgICAgNjI6MWQ6MjI6ODM6M2M6OTc6YzU6Zjk6MTk6NjI6Mjc6YWM6NjU6MjI6ZDc6ZDM6M2M6YzY6CisgICAgICAgIGU1OjhlOmIyOjUzOmNjOjQ5OmNlOmJjOjMwOmZlOjdiOjBlOjMzOjkwOmZiOmVkOmQyOjE0OgorICAgICAgICA5MToxZjowNzphZgorU0hBMSBGaW5nZXJwcmludD1DRjo5RTo4Nzo2RDpEMzpFQjpGQzo0MjoyNjo5NzpBMzpCNTpBMzo3QTpBMDo3NjpBOTowNjoyMzo0OApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2JjM2YyNTcwLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYmMzZjI1NzAuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NWVlMThiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2JjM2YyNTcwLjAKQEAgLTAsMCArMSw4MCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEeFRDQ0FxMmdBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUXNGQURDQmd6RUxNQWtHQTFVRUJoTUNWVk14CitFREFPQmdOVkJBZ1RCMEZ5YVhwdmJtRXhFekFSQmdOVkJBY1RDbE5qYjNSMGMyUmhiR1V4R2pBWUJnTlZCQW9UCitFVWR2UkdGa1pIa3VZMjl0TENCSmJtTXVNVEV3THdZRFZRUURFeWhIYnlCRVlXUmtlU0JTYjI5MElFTmxjblJwCitabWxqWVhSbElFRjFkR2h2Y21sMGVTQXRJRWN5TUI0WERUQTVNRGt3TVRBd01EQXdNRm9YRFRNM01USXpNVEl6CitOVGsxT1Zvd2dZTXhDekFKQmdOVkJBWVRBbFZUTVJBd0RnWURWUVFJRXdkQmNtbDZiMjVoTVJNd0VRWURWUVFICitFd3BUWTI5MGRITmtZV3hsTVJvd0dBWURWUVFLRXhGSGIwUmhaR1I1TG1OdmJTd2dTVzVqTGpFeE1DOEdBMVVFCitBeE1vUjI4Z1JHRmtaSGtnVW05dmRDQkRaWEowYVdacFkyRjBaU0JCZFhSb2IzSnBkSGtnTFNCSE1qQ0NBU0l3CitEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTDl4WWdqeCtsazA5eHZKR0tQM2dFbFk2U0tECitFNmJGSUVNQk80VHg1b1ZKbnlmcTlvUWJUcUMwMjNDWXh6SUJzUVUrQjA3dTlQcFBMMWt3SXVlckdWWnI0b0FICisvUE1XZFlBNVVYdmwrVFcyZEU2cGpZSVQ1TFkvcVFPRCtxSytpaFZxZjk0THc3WVpGQVhLNnNPb0JKUTdSbnd5CitEZk1BWmlMSWpXbHROb3dSR0xmVHNoeGd0RGo2QW96TzA5MUdCOTRLUHV0ZGZNaDgrN0FyVTZTU1ltbFJKUVZoCitHa1NCakN5cFE1WWozNnc2Z1pvT0tjVWNxZWxkSHJhZW5qQUtPYzd4aUlEN1MxM01NdXlGWWtNbE5BSldKd0dSCit0RHR3S2o5dXNlaWNpQUY5bjlUNTIxTnRZSjIvTE9kWXE3aGZSdnpPeEJzRFBBbnJTVEZjYVVhejRFY0NBd0VBCitBYU5DTUVBd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBT0JnTlZIUThCQWY4RUJBTUNBUVl3SFFZRFZSME9CQllFCitGRHFhaFFjUVp5aTI3L2E5QlVGdUlNR1UyZy9lTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFDWjIxMTUxZm1YCitXV2NEWWZGK093WXhkUzJoSUk1UFpZZTA5NmFjdk5qcEw5RGJXdTdQZEl4enREaEMyZ1Y3K0FKMXVQMmxzZGV1Cis5dGZlRTh0VEVINktSdEdYK3JjdUt4R3JrTEFuZ1Bub24xcnBONStyNU45c3M0VVhuVDNaSkU5NWtUWFdYd1RyCitnSU9ybWdJdHRSRDAySkRIQkhOQTdYSWxvS21mN0o2cmFCS1pWOGFQRWpvSnBMMUUvUVlWTjhHYjVES2o3VGpvCisyR1R6TEg0VS9BTHFuODMvQjJnWDJ5S1FPQzE2amRGVThXbmpYelBLZWoxN0N1UEtmMTg1NWVKMXVzVjJHRFBPCitMUEF2VEszM3NlZk9UNmpFbTBwVUJzVi9mZFVJRCtJYy9uNFh1S3hlOXRRV3NrTUpERTMycDJ1MG1ZUmx5bnFJCis0dUpFdmx6MzZoejEKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMCAoMHgwKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9VVMsIFNUPUFyaXpvbmEsIEw9U2NvdHRzZGFsZSwgTz1Hb0RhZGR5LmNvbSwgSW5jLiwgQ049R28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMgorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogU2VwICAxIDAwOjAwOjAwIDIwMDkgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBEZWMgMzEgMjM6NTk6NTkgMjAzNyBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgU1Q9QXJpem9uYSwgTD1TY290dHNkYWxlLCBPPUdvRGFkZHkuY29tLCBJbmMuLCBDTj1HbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpiZjo3MTo2MjowODpmMTpmYTo1OTozNDpmNzoxYjpjOToxODphMzpmNzoKKyAgICAgICAgICAgICAgICAgICAgODA6NDk6NTg6ZTk6MjI6ODM6MTM6YTY6YzU6MjA6NDM6MDE6M2I6ODQ6ZjE6CisgICAgICAgICAgICAgICAgICAgIGU2Ojg1OjQ5OjlmOjI3OmVhOmY2Ojg0OjFiOjRlOmEwOmI0OmRiOjcwOjk4OgorICAgICAgICAgICAgICAgICAgICBjNzozMjowMTpiMTowNTozZTowNzo0ZTplZTpmNDpmYTo0ZjoyZjo1OTozMDoKKyAgICAgICAgICAgICAgICAgICAgMjI6ZTc6YWI6MTk6NTY6NmI6ZTI6ODA6MDc6ZmM6ZjM6MTY6NzU6ODA6Mzk6CisgICAgICAgICAgICAgICAgICAgIDUxOjdiOmU1OmY5OjM1OmI2Ojc0OjRlOmE5OjhkOjgyOjEzOmU0OmI2OjNmOgorICAgICAgICAgICAgICAgICAgICBhOTowMzo4MzpmYTphMjpiZTo4YToxNTo2YTo3ZjpkZTowYjpjMzpiNjoxOToKKyAgICAgICAgICAgICAgICAgICAgMTQ6MDU6Y2E6ZWE6YzM6YTg6MDQ6OTQ6M2I6NDY6N2M6MzI6MGQ6ZjM6MDA6CisgICAgICAgICAgICAgICAgICAgIDY2OjIyOmM4OjhkOjY5OjZkOjM2OjhjOjExOjE4OmI3OmQzOmIyOjFjOjYwOgorICAgICAgICAgICAgICAgICAgICBiNDozODpmYTowMjo4YzpjZTpkMzpkZDo0NjowNzpkZTowYTozZTplYjo1ZDoKKyAgICAgICAgICAgICAgICAgICAgN2M6Yzg6N2M6ZmI6YjA6MmI6NTM6YTQ6OTI6NjI6Njk6NTE6MjU6MDU6NjE6CisgICAgICAgICAgICAgICAgICAgIDFhOjQ0OjgxOjhjOjJjOmE5OjQzOjk2OjIzOmRmOmFjOjNhOjgxOjlhOjBlOgorICAgICAgICAgICAgICAgICAgICAyOTpjNToxYzphOTplOTo1ZDoxZTpiNjo5ZTo5ZTozMDowYTozOTpjZTpmMToKKyAgICAgICAgICAgICAgICAgICAgODg6ODA6ZmI6NGI6NWQ6Y2M6MzI6ZWM6ODU6NjI6NDM6MjU6MzQ6MDI6NTY6CisgICAgICAgICAgICAgICAgICAgIDI3OjAxOjkxOmI0OjNiOjcwOjJhOjNmOjZlOmIxOmU4OjljOjg4OjAxOjdkOgorICAgICAgICAgICAgICAgICAgICA5ZjpkNDpmOTpkYjo1Mzo2ZDo2MDo5ZDpiZjoyYzplNzo1ODphYjpiODo1ZjoKKyAgICAgICAgICAgICAgICAgICAgNDY6ZmM6Y2U6YzQ6MWI6MDM6M2M6MDk6ZWI6NDk6MzE6NWM6Njk6NDY6YjM6CisgICAgICAgICAgICAgICAgICAgIGUwOjQ3CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgM0E6OUE6ODU6MDc6MTA6Njc6Mjg6QjY6RUY6RjY6QkQ6MDU6NDE6NkU6MjA6QzE6OTQ6REE6MEY6REUKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA5OTpkYjo1ZDo3OTpkNTpmOTo5Nzo1OTo2NzowMzo2MTpmMTo3ZTozYjowNjozMTo3NToyZDoKKyAgICAgICAgYTE6MjA6OGU6NGY6NjU6ODc6YjQ6Zjc6YTY6OWM6YmM6ZDg6ZTk6MmY6ZDA6ZGI6NWE6ZWU6CisgICAgICAgIGNmOjc0OjhjOjczOmI0OjM4OjQyOmRhOjA1OjdiOmY4OjAyOjc1OmI4OmZkOmE1OmIxOmQ3OgorICAgICAgICBhZTpmNjpkNzpkZToxMzpjYjo1MzoxMDo3ZTo4YTo0NjpkMTo5NzpmYTpiNzoyZToyYjoxMToKKyAgICAgICAgYWI6OTA6YjA6Mjc6ODA6Zjk6ZTg6OWY6NWE6ZTk6Mzc6OWY6YWI6ZTQ6ZGY6NmM6YjM6ODU6CisgICAgICAgIDE3OjlkOjNkOmQ5OjI0OjRmOjc5OjkxOjM1OmQ2OjVmOjA0OmViOjgwOjgzOmFiOjlhOjAyOgorICAgICAgICAyZDpiNToxMDpmNDpkODo5MDpjNzowNDo3Mzo0MDplZDo3MjoyNTphMDphOTo5ZjplYzo5ZToKKyAgICAgICAgYWI6Njg6MTI6OTk6NTc6YzY6OGY6MTI6M2E6MDk6YTQ6YmQ6NDQ6ZmQ6MDY6MTU6Mzc6YzE6CisgICAgICAgIDliOmU0OjMyOmEzOmVkOjM4OmU4OmQ4OjY0OmYzOjJjOjdlOjE0OmZjOjAyOmVhOjlmOmNkOgorICAgICAgICBmZjowNzo2ODoxNzpkYjoyMjo5MDozODoyZDo3YTo4ZDpkMTo1NDpmMTo2OTplMzo1ZjozMzoKKyAgICAgICAgY2E6N2E6M2Q6N2I6MGE6ZTM6Y2E6N2Y6NWY6Mzk6ZTU6ZTI6NzU6YmE6YzU6NzY6MTg6MzM6CisgICAgICAgIGNlOjJjOmYwOjJmOjRjOmFkOmY3OmIxOmU3OmNlOjRmOmE4OmM0OjliOjRhOjU0OjA2OmM1OgorICAgICAgICA3Zjo3ZDpkNTowODowZjplMjoxYzpmZTo3ZToxNzpiODphYzo1ZTpmNjpkNDoxNjpiMjo0MzoKKyAgICAgICAgMDk6MGM6NGQ6ZjY6YTc6NmI6YjQ6OTk6ODQ6NjU6Y2E6N2E6ODg6ZTI6ZTI6NDQ6YmU6NWM6CisgICAgICAgIGY3OmVhOjFjOmY1CitTSEExIEZpbmdlcnByaW50PTQ3OkJFOkFCOkM5OjIyOkVBOkU4OjBFOjc4Ojc4OjM0OjYyOkE3OjlGOjQ1OkMyOjU0OkZEOkU2OjhCCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYmNkZDU5NTkuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9iY2RkNTk1OS4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5OGU1MWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYmNkZDU5NTkuMApAQCAtMCwwICsxLDUyIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUM1ekNDQWxBQ0FRRXdEUVlKS29aSWh2Y05BUUVGQlFBd2dic3hKREFpQmdOVkJBY1RHMVpoYkdsRFpYSjAKK0lGWmhiR2xrWVhScGIyNGdUbVYwZDI5eWF6RVhNQlVHQTFVRUNoTU9WbUZzYVVObGNuUXNJRWx1WXk0eE5UQXoKK0JnTlZCQXNUTEZaaGJHbERaWEowSUVOc1lYTnpJRElnVUc5c2FXTjVJRlpoYkdsa1lYUnBiMjRnUVhWMGFHOXkKK2FYUjVNU0V3SHdZRFZRUURFeGhvZEhSd09pOHZkM2QzTG5aaGJHbGpaWEowTG1OdmJTOHhJREFlQmdrcWhraUcKKzl3MEJDUUVXRVdsdVptOUFkbUZzYVdObGNuUXVZMjl0TUI0WERUazVNRFl5TmpBd01UazFORm9YRFRFNU1EWXkKK05qQXdNVGsxTkZvd2dic3hKREFpQmdOVkJBY1RHMVpoYkdsRFpYSjBJRlpoYkdsa1lYUnBiMjRnVG1WMGQyOXkKK2F6RVhNQlVHQTFVRUNoTU9WbUZzYVVObGNuUXNJRWx1WXk0eE5UQXpCZ05WQkFzVExGWmhiR2xEWlhKMElFTnMKK1lYTnpJRElnVUc5c2FXTjVJRlpoYkdsa1lYUnBiMjRnUVhWMGFHOXlhWFI1TVNFd0h3WURWUVFERXhob2RIUncKK09pOHZkM2QzTG5aaGJHbGpaWEowTG1OdmJTOHhJREFlQmdrcWhraUc5dzBCQ1FFV0VXbHVabTlBZG1Gc2FXTmwKK2NuUXVZMjl0TUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FET09uSEs1YXZJV1pKVjE2dlkKK2RBNzU3dG4yVlVkWlpVY09CVlhjNjVnMlBGeFRYZE13enpqc3ZVR0o3U1ZDQ1NSckNsNnpmTjFTTFV6bTFOWjkKK1dsbXBaZFJKRXkwa1RSeFFiN1hCaFZRNy9uSGswMXhDK1lEZ2tSb0tXemsyWi9NL1ZYd2JQN1JmWkhNMDQ3UVMKK3Y0ZGsrTm9TL3pjbndiTkR1Kzk3Ymk1cDl3SURBUUFCTUEwR0NTcUdTSWIzRFFFQkJRVUFBNEdCQUR0L1VHOXYKK1VKU1pTV0k0T0I5TCtLWElQcWVDZ2ZZcngrakZ6dWc2RUlMTEdBQ09UYjJvV0graGVRQzF1K21OcjBIWkR6VHUKK0lZRVpvREpKS1BURWpsYlZValA5VU5WK21Xd0Q1TWxNL010c3EyYXpTaUdNNWJVTU1qNFFzc3hzb2R5YW1Fd0MKK1cvUE91WjZsY2c1S3R6ODg1aFpvK0w3dGRFeThXOVZpSDBQZAorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMSAoMHgwKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAxICgweDEpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEw9VmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrLCBPPVZhbGlDZXJ0LCBJbmMuLCBPVT1WYWxpQ2VydCBDbGFzcyAyIFBvbGljeSBWYWxpZGF0aW9uIEF1dGhvcml0eSwgQ049aHR0cDovL3d3dy52YWxpY2VydC5jb20vL2VtYWlsQWRkcmVzcz1pbmZvQHZhbGljZXJ0LmNvbQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogSnVuIDI2IDAwOjE5OjU0IDE5OTkgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBKdW4gMjYgMDA6MTk6NTQgMjAxOSBHTVQKKyAgICAgICAgU3ViamVjdDogTD1WYWxpQ2VydCBWYWxpZGF0aW9uIE5ldHdvcmssIE89VmFsaUNlcnQsIEluYy4sIE9VPVZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5LCBDTj1odHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8vZW1haWxBZGRyZXNzPWluZm9AdmFsaWNlcnQuY29tCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMTAyNCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMTAyNCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpjZTozYTo3MTpjYTplNTphYjpjODo1OTo5Mjo1NTpkNzphYjpkODo3NDoKKyAgICAgICAgICAgICAgICAgICAgMGU6Zjk6ZWU6ZDk6ZjY6NTU6NDc6NTk6NjU6NDc6MGU6MDU6NTU6ZGM6ZWI6CisgICAgICAgICAgICAgICAgICAgIDk4OjM2OjNjOjVjOjUzOjVkOmQzOjMwOmNmOjM4OmVjOmJkOjQxOjg5OmVkOgorICAgICAgICAgICAgICAgICAgICAyNTo0MjowOToyNDo2YjowYTo1ZTpiMzo3YzpkZDo1MjoyZDo0YzplNjpkNDoKKyAgICAgICAgICAgICAgICAgICAgZDY6N2Q6NWE6NTk6YTk6NjU6ZDQ6NDk6MTM6MmQ6MjQ6NGQ6MWM6NTA6NmY6CisgICAgICAgICAgICAgICAgICAgIGI1OmMxOjg1OjU0OjNiOmZlOjcxOmU0OmQzOjVjOjQyOmY5OjgwOmUwOjkxOgorICAgICAgICAgICAgICAgICAgICAxYTowYTo1YjozOTozNjo2NzpmMzozZjo1NTo3YzoxYjozZjpiNDo1Zjo2NDoKKyAgICAgICAgICAgICAgICAgICAgNzM6MzQ6ZTM6YjQ6MTI6YmY6ODc6NjQ6Zjg6ZGE6MTI6ZmY6Mzc6Mjc6YzE6CisgICAgICAgICAgICAgICAgICAgIGIzOjQzOmJiOmVmOjdiOjZlOjJlOjY5OmY3CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAzYjo3Zjo1MDo2Zjo2Zjo1MDo5NDo5OTo0OTo2MjozODozODoxZjo0YjpmODphNTpjODozZToKKyAgICAgICAgYTc6ODI6ODE6ZjY6MmI6Yzc6ZTg6YzU6Y2U6ZTg6M2E6MTA6ODI6Y2I6MTg6MDA6OGU6NGQ6CisgICAgICAgIGJkOmE4OjU4OjdmOmExOjc5OjAwOmI1OmJiOmU5OjhkOmFmOjQxOmQ5OjBmOjM0OmVlOjIxOgorICAgICAgICA4MToxOTphMDozMjo0OToyODpmNDpjNDo4ZTo1NjpkNTo1MjozMzpmZDo1MDpkNTo3ZTo5OToKKyAgICAgICAgNmM6MDM6ZTQ6Yzk6NGM6ZmM6Y2I6NmM6YWI6NjY6YjM6NGE6MjE6OGM6ZTU6YjU6MGM6MzI6CisgICAgICAgIDNlOjEwOmIyOmNjOjZjOmExOmRjOjlhOjk4OjRjOjAyOjViOmYzOmNlOmI5OjllOmE1OjcyOgorICAgICAgICAwZTo0YTpiNzozZjozYzplNjoxNjo2ODpmODpiZTplZDo3NDo0YzpiYzo1YjpkNTo2MjoxZjoKKyAgICAgICAgNDM6ZGQKK1NIQTEgRmluZ2VycHJpbnQ9MzE6N0E6MkE6RDA6N0Y6MkI6MzM6NUU6RjU6QTE6QzM6NEU6NEI6NTc6RTg6Qjc6RDg6RjE6RkM6QTYKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9iZGE0Y2M4NC4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2JkYTRjYzg0LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjI0NTA4OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9iZGE0Y2M4NC4wCkBAIC0wLDAgKzEsODIgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRHBEQ0NBb3lnQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFVRkFEQmpNUXN3Q1FZRFZRUUdFd0pWVXpFYworTUJvR0ExVUVDaE1UUVcxbGNtbGpZU0JQYm14cGJtVWdTVzVqTGpFMk1EUUdBMVVFQXhNdFFXMWxjbWxqWVNCUAorYm14cGJtVWdVbTl2ZENCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlU0F4TUI0WERUQXlNRFV5T0RBMgorTURBd01Gb1hEVE0zTVRFeE9USXdORE13TUZvd1l6RUxNQWtHQTFVRUJoTUNWVk14SERBYUJnTlZCQW9URTBGdAorWlhKcFkyRWdUMjVzYVc1bElFbHVZeTR4TmpBMEJnTlZCQU1UTFVGdFpYSnBZMkVnVDI1c2FXNWxJRkp2YjNRZworUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa2dNVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUAorQURDQ0FRb0NnZ0VCQUtndjZLUnBCZ05IdytrcW1QOFpvbkNheGxDeWZxWGZhRTBiZkErMmwyaDlMYWFMbCtsaworaHNtajc2Q0d2MkJsbkV0VWlNSkl4VW81dnhUaldWWGxHYlIweUxRRk9Wd1dwZUtWQmVBU3JsbUxvak5vV0J5bQorMUJXMzJKL1gzSEdyZnBxL200NHpEeUw5SHk3bkJ6YnZZam5GM2N1NkpSUWozZ3pHUFR6T2dnam1aajdhVVRzVworT3FNRmY2RGNoOVdjL0hLcG9IMTQ1TGN4VlI1bHU5UmhzQ0ZnN1JBeWNzV1NKUjc0a0VvWWVFZmZmakEzUGxBYgorMnh6VGE1cUdVd2V3NzZ3R2VQaUVtZjRoalV5QXRneUM5bVp3ZVJyVFQ2UFA4YzlHc0VzUFB0MklZcmlNcVFrbworTzNySGwrRWU1ZlNmd01DdUpLRElvZGtQMW5zbWdta3lQYWNDQXdFQUFhTmpNR0V3RHdZRFZSMFRBUUgvQkFVdworQXdFQi96QWRCZ05WSFE0RUZnUVVBSzNaby9aNTltNTBxWDh6UFlFWDEwelBNOTR3SHdZRFZSMGpCQmd3Rm9BVQorQUszWm8vWjU5bTUwcVg4elBZRVgxMHpQTTk0d0RnWURWUjBQQVFIL0JBUURBZ0dHTUEwR0NTcUdTSWIzRFFFQgorQlFVQUE0SUJBUUI4aXRFZkdEZUM0TGl3bysxV2xjaGlZWndGb3MzQ1lpWmh6UkFXMTh5MFpUVFFFWXF0cUtrRgorWnU5MDgyMWZuWm12OW92NzYxS3lCWmlpYnlyRlZMMGx2Vit1eUlicVJpekJzNzNCNlVsd0dCYVhDQk9NSU9BYgorTGpwSHl4N2tBRENWVy9SRm84QWFzQUZPcTczQUkyNWpQNEJLeFFmdDNPSnZ4OEZpOGVOeTFnVElkR2NMK29pcgorb1FISWIvQVVyOUtaelZHVGZ1MHVPTWU5emtaUVBYTGplU1dkbTRnckVDRGRwYmd5bjQzZ0tkOGhkSWFDMnkrQworTU1iSE5ZYXorWlpmUnRzTVJmM3pVTU52eHNOSXJVYW00U2RIQ2gwT203YkNkMzlqOHVCOUdyNzg0Ti9YeDZkcworc1BtdXVqejlkTFFSNkZnTmdMelRxSUE2bWUxMXpFWjcKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMSAoMHgxKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPUFtZXJpY2EgT25saW5lIEluYy4sIENOPUFtZXJpY2EgT25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTWF5IDI4IDA2OjAwOjAwIDIwMDIgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBOb3YgMTkgMjA6NDM6MDAgMjAzNyBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgTz1BbWVyaWNhIE9ubGluZSBJbmMuLCBDTj1BbWVyaWNhIE9ubGluZSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IDEKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmE4OjJmOmU4OmE0OjY5OjA2OjAzOjQ3OmMzOmU5OjJhOjk4OmZmOjE5OgorICAgICAgICAgICAgICAgICAgICBhMjo3MDo5YTpjNjo1MDpiMjo3ZTphNTpkZjo2ODo0ZDoxYjo3YzowZjpiNjoKKyAgICAgICAgICAgICAgICAgICAgOTc6Njg6N2Q6MmQ6YTY6OGI6OTc6ZTk6NjQ6ODY6Yzk6YTM6ZWY6YTA6ODY6CisgICAgICAgICAgICAgICAgICAgIGJmOjYwOjY1OjljOjRiOjU0Ojg4OmMyOjQ4OmM1OjRhOjM5OmJmOjE0OmUzOgorICAgICAgICAgICAgICAgICAgICA1OTo1NTplNToxOTpiNDo3NDpjODpiNDowNTozOTo1YzoxNjphNTplMjo5NToKKyAgICAgICAgICAgICAgICAgICAgMDU6ZTA6MTI6YWU6NTk6OGI6YTI6MzM6Njg6NTg6MWM6YTY6ZDQ6MTU6Yjc6CisgICAgICAgICAgICAgICAgICAgIGQ4OjlmOmQ3OmRjOjcxOmFiOjdlOjlhOmJmOjliOjhlOjMzOjBmOjIyOmZkOgorICAgICAgICAgICAgICAgICAgICAxZjoyZTplNzowNzozNjplZjo2MjozOTpjNTpkZDpjYjpiYToyNToxNDoyMzoKKyAgICAgICAgICAgICAgICAgICAgZGU6MGM6YzY6M2Q6M2M6Y2U6ODI6MDg6ZTY6NjY6M2U6ZGE6NTE6M2I6MTY6CisgICAgICAgICAgICAgICAgICAgIDNhOmEzOjA1OjdmOmEwOmRjOjg3OmQ1OjljOmZjOjcyOmE5OmEwOjdkOjc4OgorICAgICAgICAgICAgICAgICAgICBlNDpiNzozMTo1NToxZTo2NTpiYjpkNDo2MTpiMDoyMTo2MDplZDoxMDozMjoKKyAgICAgICAgICAgICAgICAgICAgNzI6YzU6OTI6MjU6MWU6Zjg6OTA6NGE6MTg6Nzg6NDc6ZGY6N2U6MzA6Mzc6CisgICAgICAgICAgICAgICAgICAgIDNlOjUwOjFiOmRiOjFjOmQzOjZiOjlhOjg2OjUzOjA3OmIwOmVmOmFjOjA2OgorICAgICAgICAgICAgICAgICAgICA3ODpmODo4NDo5OTpmZToyMTo4ZDo0Yzo4MDpiNjowYzo4MjpmNjo2Njo3MDoKKyAgICAgICAgICAgICAgICAgICAgNzk6MWE6ZDM6NGY6YTM6Y2Y6ZjE6Y2Y6NDY6YjA6NGI6MGY6M2U6ZGQ6ODg6CisgICAgICAgICAgICAgICAgICAgIDYyOmI4OjhjOmE5OjA5OjI4OjNiOjdhOmM3Ojk3OmUxOjFlOmU1OmY0OjlmOgorICAgICAgICAgICAgICAgICAgICBjMDpjMDphZToyNDphMDpjODphMTpkOTowZjpkNjo3YjoyNjo4Mjo2OTozMjoKKyAgICAgICAgICAgICAgICAgICAgM2Q6YTcKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICAwMDpBRDpEOTpBMzpGNjo3OTpGNjo2RTo3NDpBOTo3RjozMzozRDo4MToxNzpENzo0QzpDRjozMzpERQorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6MDA6QUQ6RDk6QTM6RjY6Nzk6RjY6NkU6NzQ6QTk6N0Y6MzM6M0Q6ODE6MTc6RDc6NEM6Q0Y6MzM6REUKKworICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBEaWdpdGFsIFNpZ25hdHVyZSwgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgN2M6OGE6ZDE6MWY6MTg6Mzc6ODI6ZTA6Yjg6YjA6YTM6ZWQ6NTY6OTU6Yzg6NjI6NjE6OWM6CisgICAgICAgIDA1OmEyOmNkOmMyOjYyOjI2OjYxOmNkOjEwOjE2OmQ3OmNjOmI0OjY1OjM0OmQwOjExOjhhOgorICAgICAgICBhZDphODphOTowNTo2NjplZjo3NDpmMzo2ZDo1Zjo5ZDo5OTphZjpmNjo4YjpmYjplYjo1MjoKKyAgICAgICAgYjI6MDU6OTg6YTI6NmY6MmE6YzU6NTQ6YmQ6MjU6YmQ6NWY6YWU6Yzg6ODY6ZWE6NDY6MmM6CisgICAgICAgIGMxOmIzOmJkOmMxOmU5OjQ5OjcwOjE4OjE2Ojk3OjA4OjEzOjhjOjIwOmUwOjFiOjJlOjNhOgorICAgICAgICA0NzpjYjoxZTplNDowMDozMDo5NTo1YjpmNDo0NTphMzpjMDoxYTpiMDowMTo0ZTphYjpiZDoKKyAgICAgICAgYzA6MjM6NmU6NjM6M2Y6ODA6NGE6YzU6MDc6ZWQ6ZGM6ZTI6NmY6Yzc6YzE6NjI6ZjE6ZTM6CisgICAgICAgIDcyOmQ2OjA0OmM4Ojc0OjY3OjBiOmZhOjg4OmFiOmExOjAxOmM4OjZmOmYwOjE0OmFmOmQyOgorICAgICAgICA5OTpjZDo1MTo5Mzo3ZTplZDoyZTozODpjNzpiZDpjZTo0Njo1MDozZDo3MjplMzo3OToyNToKKyAgICAgICAgOWQ6OWI6ODg6MmI6MTA6MjA6ZGQ6YTU6Yjg6MzI6OWY6OGQ6ZTA6Mjk6ZGY6MjE6NzQ6ODY6CisgICAgICAgIDgyOmRiOjJmOjgyOjMwOmM2OmM3OjM1Ojg2OmIzOmY5Ojk2OjVmOjQ2OmRiOjBjOjQ1OmZkOgorICAgICAgICBmMzo1MDpjMzo2ZjpjNjpjMzo0ODphZDo0NjphNjplMToyNzo0NzowYToxZDowZTo5YjpiNjoKKyAgICAgICAgYzI6Nzc6N2Y6NjM6ZjI6ZTA6N2Q6MWE6YmU6ZmM6ZTA6ZGY6ZDc6Yzc6YTc6NmM6YjA6Zjk6CisgICAgICAgIGFlOmJhOjNjOmZkOjc0OmI0OjExOmU4OjU4OjBkOjgwOmJjOmQzOmE4OjgwOjNhOjk5OmVkOgorICAgICAgICA3NTpjYzo0Njo3YgorU0hBMSBGaW5nZXJwcmludD0zOToyMTpDMToxNTpDMTo1RDowRTpDQTo1QzpDQjo1QjpDNDpGMDo3RDoyMTpEODowNTowQjo1Njo2QQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2JkYWNjYTZmLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYmRhY2NhNmYuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZmJjZjI0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2JkYWNjYTZmLjAKQEAgLTAsMCArMSw4NyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEdkRDQ0FxU2dBd0lCQWdJUUIxWWlwT2pVaW9sTjlCUEk4UGpxcFRBTkJna3Foa2lHOXcwQkFRVUZBREJLCitNUXN3Q1FZRFZRUUdFd0pWVXpFZ01CNEdBMVVFQ2hNWFUyVmpkWEpsVkhKMWMzUWdRMjl5Y0c5eVlYUnBiMjR4CitHVEFYQmdOVkJBTVRFRk5sWTNWeVpTQkhiRzlpWVd3Z1EwRXdIaGNOTURZeE1UQTNNVGswTWpJNFdoY05Namt4CitNak14TVRrMU1qQTJXakJLTVFzd0NRWURWUVFHRXdKVlV6RWdNQjRHQTFVRUNoTVhVMlZqZFhKbFZISjFjM1FnCitRMjl5Y0c5eVlYUnBiMjR4R1RBWEJnTlZCQU1URUZObFkzVnlaU0JIYkc5aVlXd2dRMEV3Z2dFaU1BMEdDU3FHCitTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDdk5TN1lyR3hWYVFaeDVSTm9KTE5QMk13aFIvanhZRGlKCitpUVBwdmVwZVJsTUozRnoxV3VqM1JTb0M2ekZoMXlrelRNN0hmQW8zZmcrNk1wamhIWmV2ajhmY3lUaVc4OXNhCisvRkh0YU1iUWJxUjhKTkd1UXNpV1VHTXU0UDUxL3Bpblgwa3VsZU01TTJTT0hxUmZrTkpuUExMWi9rRzVWYWNKCitqbklGSG92ZFJJV0NRdEJKd0IxZzhORVhMSlhyOXFYQmtxUEZ3cWNJWUExZ0JCQ1dlWjRXTk9hcHR2b2xSVG5JCitIbVg1ay9XcThWTGNtWmc5cFlZYUREVXora3VsQkFZVkhER0E3Nm9ZYThKNzE5ck8rVE1nMWZXOWFqTXRnUVQ3CitzRnpVbktQaVhCM2pxVUoxWG52VWQrODVWTHJKQ2hnYkVwbEpMNGhML1ZCaTBYUG5qM3BEQWdNQkFBR2pnWjB3CitnWm93RXdZSkt3WUJCQUdDTnhRQ0JBWWVCQUJEQUVFd0N3WURWUjBQQkFRREFnR0dNQThHQTFVZEV3RUIvd1FGCitNQU1CQWY4d0hRWURWUjBPQkJZRUZLOUVCTUpCZmtpRDIwNDVBdXpzaEhybXpzbWtNRFFHQTFVZEh3UXRNQ3N3CitLYUFub0NXR0kyaDBkSEE2THk5amNtd3VjMlZqZFhKbGRISjFjM1F1WTI5dEwxTkhRMEV1WTNKc01CQUdDU3NHCitBUVFCZ2pjVkFRUURBZ0VBTUEwR0NTcUdTSWIzRFFFQkJRVUFBNElCQVFCakdnaEFmYVJlVXcxMzJIcXVIdzBMCitVUllEN3hoOHlPT3ZhbGlURkdDUnNvVGNpRTYrT1lvNjgrYUNpVjBCTjdPckpLUVZEcEkxV2twRVhrNVgrblhPCitIMGpPWnZROFFDYVNtR3diN2lSR0RCZXpVcVhicFpHUnp6ZlRiK2NuQ0RwT0dSODZwMWhjRjg5NVA0dmtwOU1tCitJNTBtRDFocC9FZCtzdENOaTVPL0tVOURhWFIyWjB2UEI0em1BdmUxNGJSRHRVc3RGSi81M0NZTnY2WkhkQWJZCitpTkU2S1RDRXp0STVnR0licU1kWFNieHFWVkZuRlVxK05RZmsxWFdZTjNrd0ZOc3BuV3pGYWN4SFZhSXc5OHhjCitmOExEbUJ4clRoYUE2M3A0WlVXaUFCcXZEQTFWWkRSSXVKSzU4YlJRS2ZKUEl4L2FiS3dmUk9IZEkzaFJXOGNXCistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICAwNzo1NjoyMjphNDplODpkNDo4YTo4OTo0ZDpmNDoxMzpjODpmMDpmODplYTphNQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPVNlY3VyZVRydXN0IENvcnBvcmF0aW9uLCBDTj1TZWN1cmUgR2xvYmFsIENBCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBOb3YgIDcgMTk6NDI6MjggMjAwNiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IERlYyAzMSAxOTo1MjowNiAyMDI5IEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPVNlY3VyZVRydXN0IENvcnBvcmF0aW9uLCBDTj1TZWN1cmUgR2xvYmFsIENBCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDphZjozNToyZTpkODphYzo2Yzo1NTo2OTowNjo3MTplNToxMzo2ODoyNDoKKyAgICAgICAgICAgICAgICAgICAgYjM6NGY6ZDg6Y2M6MjE6NDc6Zjg6ZjE6NjA6Mzg6ODk6ODk6MDM6ZTk6YmQ6CisgICAgICAgICAgICAgICAgICAgIGVhOjVlOjQ2OjUzOjA5OmRjOjVjOmY1OjVhOmU4OmY3OjQ1OjJhOjAyOmViOgorICAgICAgICAgICAgICAgICAgICAzMTo2MTpkNzoyOTozMzo0YzpjZTpjNzo3YzowYTozNzo3ZTowZjpiYTozMjoKKyAgICAgICAgICAgICAgICAgICAgOTg6ZTE6MWQ6OTc6YWY6OGY6Yzc6ZGM6Yzk6Mzg6OTY6ZjM6ZGI6MWE6ZmM6CisgICAgICAgICAgICAgICAgICAgIDUxOmVkOjY4OmM2OmQwOjZlOmE0OjdjOjI0OmQxOmFlOjQyOmM4Ojk2OjUwOgorICAgICAgICAgICAgICAgICAgICA2MzoyZTplMDpmZTo3NTpmZTo5ODphNzo1Zjo0OToyZTo5NTplMzozOTozMzoKKyAgICAgICAgICAgICAgICAgICAgNjQ6OGU6MWU6YTQ6NWY6OTA6ZDI6Njc6M2M6YjI6ZDk6ZmU6NDE6Yjk6NTU6CisgICAgICAgICAgICAgICAgICAgIGE3OjA5OjhlOjcyOjA1OjFlOjhiOmRkOjQ0Ojg1OjgyOjQyOmQwOjQ5OmMwOgorICAgICAgICAgICAgICAgICAgICAxZDo2MDpmMDpkMToxNzoyYzo5NTplYjpmNjphNTpjMTo5MjphMzpjNTpjMjoKKyAgICAgICAgICAgICAgICAgICAgYTc6MDg6NjA6MGQ6NjA6MDQ6MTA6OTY6Nzk6OWU6MTY6MzQ6ZTY6YTk6YjY6CisgICAgICAgICAgICAgICAgICAgIGZhOjI1OjQ1OjM5OmM4OjFlOjY1OmY5OjkzOmY1OmFhOmYxOjUyOmRjOjk5OgorICAgICAgICAgICAgICAgICAgICA5ODozZDphNTo4NjoxYTowYzozNTozMzpmYTo0YjphNTowNDowNjoxNToxYzoKKyAgICAgICAgICAgICAgICAgICAgMzE6ODA6ZWY6YWE6MTg6NmI6YzI6N2I6ZDc6ZGE6Y2U6Zjk6MzM6MjA6ZDU6CisgICAgICAgICAgICAgICAgICAgIGY1OmJkOjZhOjMzOjJkOjgxOjA0OmZiOmIwOjVjOmQ0OjljOmEzOmUyOjVjOgorICAgICAgICAgICAgICAgICAgICAxZDplMzphOTo0Mjo3NTo1ZTo3YjpkNDo3NzplZjozOTo1NDpiYTpjOTowYToKKyAgICAgICAgICAgICAgICAgICAgMTg6MWI6MTI6OTk6NDk6MmY6ODg6NGI6ZmQ6NTA6NjI6ZDE6NzM6ZTc6OGY6CisgICAgICAgICAgICAgICAgICAgIDdhOjQzCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIDEuMy42LjEuNC4xLjMxMS4yMC4yOiAKKyAgICAgICAgICAgICAgICAuLi5DLkEKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IAorICAgICAgICAgICAgICAgIERpZ2l0YWwgU2lnbmF0dXJlLCBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBBRjo0NDowNDpDMjo0MTo3RTo0ODo4MzpEQjo0RTozOTowMjpFQzpFQzo4NDo3QTpFNjpDRTpDOTpBNAorICAgICAgICAgICAgWDUwOXYzIENSTCBEaXN0cmlidXRpb24gUG9pbnRzOiAKKyAgICAgICAgICAgICAgICBVUkk6aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU0dDQS5jcmwKKworICAgICAgICAgICAgMS4zLjYuMS40LjEuMzExLjIxLjE6IAorICAgICAgICAgICAgICAgIC4uLgorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA2MzoxYTowODo0MDo3ZDphNDo1ZTo1MzowZDo3NzpkODo3YTphZToxZjowZDowYjo1MToxNjoKKyAgICAgICAgMDM6ZWY6MTg6N2M6Yzg6ZTM6YWY6NmE6NTg6OTM6MTQ6NjA6OTE6YjI6ODQ6ZGM6ODg6NGU6CisgICAgICAgIGJlOjM5OjhhOjNhOmYzOmU2OjgyOjg5OjVkOjAxOjM3OmIzOmFiOjI0OmE0OjE1OjBlOjkyOgorICAgICAgICAzNTo1YTo0YTo0NDo1ZTo0ZTo1NzpmYTo3NTpjZToxZjo0ODpjZTo2NjpmNDozYzo0MDoyNjoKKyAgICAgICAgOTI6OTg6NmM6MWI6ZWU6MjQ6NDY6MGM6MTc6YjM6NTI6YTU6ZGI6YTU6OTE6OTE6Y2Y6Mzc6CisgICAgICAgIGQzOjZmOmU3OjI3OjA4OjNhOjRlOjE5OjFmOjNhOmE3OjU4OjVjOjE3OmNmOjc5OjNmOjhiOgorICAgICAgICBlNDphNzpkMzoyNjoyMzo5ZDoyNjowZjo1ODo2OTpmYzo0Nzo3ZTpiMjpkMDo4ZDo4Yjo5MzoKKyAgICAgICAgYmY6Mjk6NGY6NDM6Njk6NzQ6NzY6Njc6NGI6Y2Y6MDc6OGM6ZTY6MDI6Zjc6YjU6ZTE6YjQ6CisgICAgICAgIDQzOmI1OjRiOjJkOjE0OjlmOmY5OmRjOjI2OjBkOmJmOmE2OjQ3Ojc0OjA2OmQ4Ojg4OmQxOgorICAgICAgICAzYToyOTozMDo4NDpjZTpkMjozOTo4MDo2MjoxYjphODpjNzo1Nzo0OTpiYzo2YTo1NTo1MToKKyAgICAgICAgNjc6MTU6NGE6YmU6MzU6MDc6ZTQ6ZDU6NzU6OTg6Mzc6Nzk6MzA6MTQ6ZGI6Mjk6OWQ6NmM6CisgICAgICAgIGM1OjY5OmNjOjQ3OjU1OmEyOjMwOmY3OmNjOjVjOjdmOmMyOmMzOjk4OjFjOjZiOjRlOjE2OgorICAgICAgICA4MDplYjo3YTo3ODo2NTo0NTphMjowMDoxYTphZjowYzowZDo1NTo2NDozNDo0ODpiODo5MjoKKyAgICAgICAgYjk6ZjE6YjQ6NTA6Mjk6ZjI6NGY6MjM6MWY6ZGE6NmM6YWM6MWY6NDQ6ZTE6ZGQ6MjM6Nzg6CisgICAgICAgIDUxOjViOmM3OjE2CitTSEExIEZpbmdlcnByaW50PTNBOjQ0OjczOjVBOkU1OjgxOjkwOjFGOjI0Ojg2OjYxOjQ2OjFFOjNCOjlDOkM0OjVGOkY1OjNBOjFCCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYmY2NGYzNWIuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9iZjY0ZjM1Yi4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAwOTk2NDkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYmY2NGYzNWIuMApAQCAtMCwwICsxLDkxIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUVrVENDQTNtZ0F3SUJBZ0lFUld0UVZEQU5CZ2txaGtpRzl3MEJBUVVGQURDQnNERUxNQWtHQTFVRUJoTUMKK1ZWTXhGakFVQmdOVkJBb1REVVZ1ZEhKMWMzUXNJRWx1WXk0eE9UQTNCZ05WQkFzVE1IZDNkeTVsYm5SeWRYTjAKK0xtNWxkQzlEVUZNZ2FYTWdhVzVqYjNKd2IzSmhkR1ZrSUdKNUlISmxabVZ5Wlc1alpURWZNQjBHQTFVRUN4TVcKK0tHTXBJREl3TURZZ1JXNTBjblZ6ZEN3Z1NXNWpMakV0TUNzR0ExVUVBeE1rUlc1MGNuVnpkQ0JTYjI5MElFTmwKK2NuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNQjRYRFRBMk1URXlOekl3TWpNME1sb1hEVEkyTVRFeU56SXcKK05UTTBNbG93Z2JBeEN6QUpCZ05WQkFZVEFsVlRNUll3RkFZRFZRUUtFdzFGYm5SeWRYTjBMQ0JKYm1NdU1Ua3cKK053WURWUVFMRXpCM2QzY3VaVzUwY25WemRDNXVaWFF2UTFCVElHbHpJR2x1WTI5eWNHOXlZWFJsWkNCaWVTQnkKK1pXWmxjbVZ1WTJVeEh6QWRCZ05WQkFzVEZpaGpLU0F5TURBMklFVnVkSEoxYzNRc0lFbHVZeTR4TFRBckJnTlYKK0JBTVRKRVZ1ZEhKMWMzUWdVbTl2ZENCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVENDQVNJd0RRWUoKK0tvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUxhVnRrTkMrc1p0S205STM1Uk1PVmNGN3NONUVVRm8KK051M3MvcG9CajZFNEtQejNFRVptTGswZUdyRWFUc2JSd0pXSXNNbi9NWXN6QTl1M2czcytJSVJlN2JKV0tLZjQKKzRMbEFjVGZGeTBjT2x5cG93Q0tWWWhYYlI5bjEwQ3YvZ2t2SnJUN2VUTnVRZ0ZBL0NZcUVBT3d3Q2owWXpmdjkKK0tsbWFJNVVYTEVXZUgyNURlVzBNWEpqK1NLZkZJMGRjWHYxdTV4NjA5bWhGMFlhRFc2S0tqYkhqS1lEK0pYR0kKK3JiNjhqNnhTbGt1cVVZM2tFekVaNkU1Tm45dXNzMnJWdkRsVWNjcDZlbitRM1gwZGdObUJ1MWttd2hIKzVwUGkKKzk0RGtaZnMwTnc0cGdIQk5yemlHTHA1L1Y2K2VGNjdySE1zb0lWKzJITmpub2dRaStkUGEyTXNDQXdFQUFhT0IKK3NEQ0JyVEFPQmdOVkhROEJBZjhFQkFNQ0FRWXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXJCZ05WSFJBRUpEQWkKK2dBOHlNREEyTVRFeU56SXdNak0wTWxxQkR6SXdNall4TVRJM01qQTFNelF5V2pBZkJnTlZIU01FR0RBV2dCUm8KK2tPUm5wS1pUZ01lR1pxVHg5MHREKzRTOWJUQWRCZ05WSFE0RUZnUVVhSkRrWjZTbVU0REhobWFrOGZkTFEvdUUKK3ZXMHdIUVlKS29aSWh2WjlCMEVBQkJBd0Roc0lWamN1TVRvMExqQURBZ1NRTUEwR0NTcUdTSWIzRFFFQkJRVUEKK0E0SUJBUUNUMURDdzF3TWdLdEQ1WStpUkRBVWdxVjhaeW50eVR0U3gyOUNXKzFSYUdTd01DUGV5dklXb25YOXQKK08xS3pLdHZuMUlTTVkvWVB5eVlCa1ZCczlGOFU0cE4wd0JPZU1EcFE0N1JneFJ6d0lrU05jVWVzeUJySjZadWEKK0FHQVQvM0IrWHhGTlNSdXpGVko3eVZUYXY1MlZyMnVhMko3cDhlUkRqZUlSUkRxL3I3MkRRbk5TaTZxN3B5blAKKzlXUWNDazNSdktxc255clEvMzkvMm4zcXNlMHdKY0dFMmpUU1czaURWdXljTnNNbTRoSDJaMGtka3F1TSsrdi8KK2V1NkZTcWRRZ1BDblhFcVVMbDhGbVR4U1FlRE50R1BQQVVPNm5JUGNqMkE3ODFxMHRIdXUyZ3VRT0hYdmdSMW0KKzB2ZFhjRGF6di93b3IzRWxoVnNUL2g1L1dyUTgKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMTE2NDY2MDgyMCAoMHg0NTZiNTA1NCkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgTz1FbnRydXN0LCBJbmMuLCBPVT13d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVuY2UsIE9VPShjKSAyMDA2IEVudHJ1c3QsIEluYy4sIENOPUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTm92IDI3IDIwOjIzOjQyIDIwMDYgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBOb3YgMjcgMjA6NTM6NDIgMjAyNiBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgTz1FbnRydXN0LCBJbmMuLCBPVT13d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVuY2UsIE9VPShjKSAyMDA2IEVudHJ1c3QsIEluYy4sIENOPUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YjY6OTU6YjY6NDM6NDI6ZmE6YzY6NmQ6MmE6NmY6NDg6ZGY6OTQ6NGM6CisgICAgICAgICAgICAgICAgICAgIDM5OjU3OjA1OmVlOmMzOjc5OjExOjQxOjY4OjM2OmVkOmVjOmZlOjlhOjAxOgorICAgICAgICAgICAgICAgICAgICA4ZjphMTozODoyODpmYzpmNzoxMDo0Njo2NjoyZTo0ZDoxZToxYTpiMToxYToKKyAgICAgICAgICAgICAgICAgICAgNGU6YzY6ZDE6YzA6OTU6ODg6YjA6Yzk6ZmY6MzE6OGI6MzM6MDM6ZGI6Yjc6CisgICAgICAgICAgICAgICAgICAgIDgzOjdiOjNlOjIwOjg0OjVlOmVkOmIyOjU2OjI4OmE3OmY4OmUwOmI5OjQwOgorICAgICAgICAgICAgICAgICAgICA3MTozNzpjNTpjYjo0NzowZTo5NzoyYTo2ODpjMDoyMjo5NTo2MjoxNTpkYjoKKyAgICAgICAgICAgICAgICAgICAgNDc6ZDk6ZjU6ZDA6MmI6ZmY6ODI6NGI6Yzk6YWQ6M2U6ZGU6NGM6ZGI6OTA6CisgICAgICAgICAgICAgICAgICAgIDgwOjUwOjNmOjA5OjhhOjg0OjAwOmVjOjMwOjBhOjNkOjE4OmNkOmZiOmZkOgorICAgICAgICAgICAgICAgICAgICAyYTo1OTo5YToyMzo5NToxNzoyYzo0NTo5ZToxZjo2ZTo0Mzo3OTo2ZDowYzoKKyAgICAgICAgICAgICAgICAgICAgNWM6OTg6ZmU6NDg6YTc6YzU6MjM6NDc6NWM6NWU6ZmQ6NmU6ZTc6MWU6YjQ6CisgICAgICAgICAgICAgICAgICAgIGY2OjY4OjQ1OmQxOjg2OjgzOjViOmEyOjhhOjhkOmIxOmUzOjI5OjgwOmZlOgorICAgICAgICAgICAgICAgICAgICAyNTo3MTo4ODphZDpiZTpiYzo4ZjphYzo1Mjo5Njo0YjphYTo1MTo4ZDplNDoKKyAgICAgICAgICAgICAgICAgICAgMTM6MzE6MTk6ZTg6NGU6NGQ6OWY6ZGI6YWM6YjM6NmE6ZDU6YmM6Mzk6NTQ6CisgICAgICAgICAgICAgICAgICAgIDcxOmNhOjdhOjdhOjdmOjkwOmRkOjdkOjFkOjgwOmQ5OjgxOmJiOjU5OjI2OgorICAgICAgICAgICAgICAgICAgICBjMjoxMTpmZTplNjo5MzplMjpmNzo4MDplNDo2NTpmYjozNDozNzowZToyOToKKyAgICAgICAgICAgICAgICAgICAgODA6NzA6NGQ6YWY6Mzg6ODY6MmU6OWU6N2Y6NTc6YWY6OWU6MTc6YWU6ZWI6CisgICAgICAgICAgICAgICAgICAgIDFjOmNiOjI4OjIxOjVmOmI2OjFjOmQ4OmU3OmEyOjA0OjIyOmY5OmQzOmRhOgorICAgICAgICAgICAgICAgICAgICBkODpjYgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIFByaXZhdGUgS2V5IFVzYWdlIFBlcmlvZDogCisgICAgICAgICAgICAgICAgTm90IEJlZm9yZTogTm92IDI3IDIwOjIzOjQyIDIwMDYgR01ULCBOb3QgQWZ0ZXI6IE5vdiAyNyAyMDo1Mzo0MiAyMDI2IEdNVAorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6Njg6OTA6RTQ6Njc6QTQ6QTY6NTM6ODA6Qzc6ODY6NjY6QTQ6RjE6Rjc6NEI6NDM6RkI6ODQ6QkQ6NkQKKworICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDY4OjkwOkU0OjY3OkE0OkE2OjUzOjgwOkM3Ojg2OjY2OkE0OkYxOkY3OjRCOjQzOkZCOjg0OkJEOjZECisgICAgICAgICAgICAxLjIuODQwLjExMzUzMy43LjY1LjA6IAorICAgICAgICAgICAgICAgIDAuLi5WNy4xOjQuMC4uLi4KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgOTM6ZDQ6MzA6YjA6ZDc6MDM6MjA6MmE6ZDA6Zjk6NjM6ZTg6OTE6MGM6MDU6MjA6YTk6NWY6CisgICAgICAgIDE5OmNhOjdiOjcyOjRlOmQ0OmIxOmRiOmQwOjk2OmZiOjU0OjVhOjE5OjJjOjBjOjA4OmY3OgorICAgICAgICBiMjpiYzo4NTphODo5ZDo3Zjo2ZDozYjo1MjpiMzoyYTpkYjplNzpkNDo4NDo4Yzo2MzpmNjoKKyAgICAgICAgMGY6Y2I6MjY6MDE6OTE6NTA6NmM6ZjQ6NWY6MTQ6ZTI6OTM6NzQ6YzA6MTM6OWU6MzA6M2E6CisgICAgICAgIDUwOmUzOmI0OjYwOmM1OjFjOmYwOjIyOjQ0OjhkOjcxOjQ3OmFjOmM4OjFhOmM5OmU5OjliOgorICAgICAgICA5YTowMDo2MDoxMzpmZjo3MDo3ZTo1ZjoxMTo0ZDo0OToxYjpiMzoxNTo1Mjo3YjpjOTo1NDoKKyAgICAgICAgZGE6YmY6OWQ6OTU6YWY6NmI6OWE6ZDg6OWU6ZTk6ZjE6ZTQ6NDM6OGQ6ZTI6MTE6NDQ6M2E6CisgICAgICAgIGJmOmFmOmJkOjgzOjQyOjczOjUyOjhiOmFhOmJiOmE3OjI5OmNmOmY1OjY0OjFjOjBhOjRkOgorICAgICAgICBkMTpiYzphYTphYzo5ZjoyYTpkMDpmZjo3Zjo3ZjpkYTo3ZDplYTpiMTplZDozMDoyNTpjMToKKyAgICAgICAgODQ6ZGE6MzQ6ZDI6NWI6Nzg6ODM6NTY6ZWM6OWM6MzY6YzM6MjY6ZTI6MTE6ZjY6Njc6NDk6CisgICAgICAgIDFkOjkyOmFiOjhjOmZiOmViOmZmOjdhOmVlOjg1OjRhOmE3OjUwOjgwOmYwOmE3OjVjOjRhOgorICAgICAgICA5NDoyZTo1ZjowNTo5OTozYzo1Mjo0MTplMDpjZDpiNDo2MzpjZjowMTo0MzpiYTo5Yzo4MzoKKyAgICAgICAgZGM6OGY6NjA6M2I6ZjM6NWE6YjQ6YjQ6N2I6YWU6ZGE6MGI6OTA6Mzg6NzU6ZWY6ODE6MWQ6CisgICAgICAgIDY2OmQyOmY3OjU3OjcwOjM2OmIzOmJmOmZjOjI4OmFmOjcxOjI1Ojg1OjViOjEzOmZlOjFlOgorICAgICAgICA3Zjo1YTpiNDozYworU0hBMSBGaW5nZXJwcmludD1CMzoxRTpCMTpCNzo0MDpFMzo2Qzo4NDowMjpEQTpEQzozNzpENDo0RDpGNTpENDo2Nzo0OTo1MjpGOQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2MyMTViYzY5LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYzIxNWJjNjkuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOGFiNDhmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2MyMTViYzY5LjAKQEAgLTAsMCArMSw3MyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlES1RDQ0FwS2dBd0lCQWdJRU5uQVZsakFOQmdrcWhraUc5dzBCQVFVRkFEQkdNUXN3Q1FZRFZRUUdFd0pWCitVekVrTUNJR0ExVUVDaE1iUkdsbmFYUmhiQ0JUYVdkdVlYUjFjbVVnVkhKMWMzUWdRMjh1TVJFd0R3WURWUVFMCitFd2hFVTFSRFFTQkZNVEFlRncwNU9ERXlNVEF4T0RFd01qTmFGdzB4T0RFeU1UQXhPRFF3TWpOYU1FWXhDekFKCitCZ05WQkFZVEFsVlRNU1F3SWdZRFZRUUtFeHRFYVdkcGRHRnNJRk5wWjI1aGRIVnlaU0JVY25WemRDQkRieTR4CitFVEFQQmdOVkJBc1RDRVJUVkVOQklFVXhNSUdkTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdMQURDQmh3S0JnUUNnCitiSUdwenpRZUpOMytoaWpNM29NditWN1VRdExvZEdCbUU1Z0dIS2xSRW1sdk1WVzVTWElBQ0g3VHBXSkVOeVNaCitqOW1EU0krWmJaVVR1ME03TGtsT2lEZkJ1MWgvL3VHOStMdGh6Zk5Id0ptbThmT1I2SGg4QU10aHlVUW5jV2xWCitTbjVKVGUyaW83NENUQURLQXFqdUFRSXhaQTlTTFJOMGRqYTFlclF0Y1FJQkE2T0NBU1F3Z2dFZ01CRUdDV0NHCitTQUdHK0VJQkFRUUVBd0lBQnpCb0JnTlZIUjhFWVRCZk1GMmdXNkJacEZjd1ZURUxNQWtHQTFVRUJoTUNWVk14CitKREFpQmdOVkJBb1RHMFJwWjJsMFlXd2dVMmxuYm1GMGRYSmxJRlJ5ZFhOMElFTnZMakVSTUE4R0ExVUVDeE1JCitSRk5VUTBFZ1JURXhEVEFMQmdOVkJBTVRCRU5TVERFd0t3WURWUjBRQkNRd0lvQVBNVGs1T0RFeU1UQXhPREV3CitNak5hZ1E4eU1ERTRNVEl4TURFNE1UQXlNMW93Q3dZRFZSMFBCQVFEQWdFR01COEdBMVVkSXdRWU1CYUFGR3A1CitmcEZwUmhnVENnSjNwVmxiWUpnbERxTDRNQjBHQTFVZERnUVdCQlJxZVg2UmFVWVlFd29DZDZWWlcyQ1lKUTZpCisrREFNQmdOVkhSTUVCVEFEQVFIL01Ca0dDU3FHU0liMmZRZEJBQVFNTUFvYkJGWTBMakFEQWdTUU1BMEdDU3FHCitTSWIzRFFFQkJRVUFBNEdCQUNJUzJIb2QzSUVHdGdsbHNvZklIMTYwTCtuRUh2STh3YnNFa0JGS2cwNStrN2xOCitRc2VTSnFCY05KbzRjdmo5YXhZK0lPNkNpekVxa3phRkk0aUtQQU5vMDhrSkQwMzhiS1RhS0hLVERvbUFzSDMrCitnRzlsYlJnemw0dkNhNG51WUQzSW0rOS9LekppYzVQTFBPTjc0blo0UmJ5aGt3UzdocDg2VzBONnc0cGwKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogOTEzMzE1MjIyICgweDM2NzAxNTk2KQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPURpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLiwgT1U9RFNUQ0EgRTEKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IERlYyAxMCAxODoxMDoyMyAxOTk4IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogRGVjIDEwIDE4OjQwOjIzIDIwMTggR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89RGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uLCBPVT1EU1RDQSBFMQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDEwMjQgYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDEwMjQgYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YTA6NmM6ODE6YTk6Y2Y6MzQ6MWU6MjQ6ZGQ6ZmU6ODY6Mjg6Y2M6ZGU6CisgICAgICAgICAgICAgICAgICAgIDgzOjJmOmY5OjVlOmQ0OjQyOmQyOmU4Ojc0OjYwOjY2OjEzOjk4OjA2OjFjOgorICAgICAgICAgICAgICAgICAgICBhOTo1MToxMjo2OTo2ZjozMTo1NTpiOTo0OTo3MjowMDowODo3ZTpkMzphNToKKyAgICAgICAgICAgICAgICAgICAgNjI6NDQ6Mzc6MjQ6OTk6OGY6ZDk6ODM6NDg6OGY6OTk6NmQ6OTU6MTM6YmI6CisgICAgICAgICAgICAgICAgICAgIDQzOjNiOjJlOjQ5OjRlOjg4OjM3OmMxOmJiOjU4OjdmOmZlOmUxOmJkOmY4OgorICAgICAgICAgICAgICAgICAgICBiYjo2MTpjZDpmMzo0NzpjMDo5OTphNjpmMTpmMzo5MTplODo3ODo3YzowMDoKKyAgICAgICAgICAgICAgICAgICAgY2I6NjE6Yzk6NDQ6Mjc6NzE6Njk6NTU6NGE6N2U6NDk6NGQ6ZWQ6YTI6YTM6CisgICAgICAgICAgICAgICAgICAgIGJlOjAyOjRjOjAwOmNhOjAyOmE4OmVlOjAxOjAyOjMxOjY0OjBmOjUyOjJkOgorICAgICAgICAgICAgICAgICAgICAxMzo3NDo3NjozNjpiNTo3YTpiNDoyZDo3MQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiAzICgweDMpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgTmV0c2NhcGUgQ2VydCBUeXBlOiAKKyAgICAgICAgICAgICAgICBTU0wgQ0EsIFMvTUlNRSBDQSwgT2JqZWN0IFNpZ25pbmcgQ0EKKyAgICAgICAgICAgIFg1MDl2MyBDUkwgRGlzdHJpYnV0aW9uIFBvaW50czogCisgICAgICAgICAgICAgICAgRGlyTmFtZTovQz1VUy9PPURpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLi9PVT1EU1RDQSBFMS9DTj1DUkwxCisKKyAgICAgICAgICAgIFg1MDl2MyBQcml2YXRlIEtleSBVc2FnZSBQZXJpb2Q6IAorICAgICAgICAgICAgICAgIE5vdCBCZWZvcmU6IERlYyAxMCAxODoxMDoyMyAxOTk4IEdNVCwgTm90IEFmdGVyOiBEZWMgMTAgMTg6MTA6MjMgMjAxOCBHTVQKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQXV0aG9yaXR5IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBrZXlpZDo2QTo3OTo3RTo5MTo2OTo0NjoxODoxMzowQTowMjo3NzpBNTo1OTo1Qjo2MDo5ODoyNTowRTpBMjpGOAorCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgNkE6Nzk6N0U6OTE6Njk6NDY6MTg6MTM6MEE6MDI6Nzc6QTU6NTk6NUI6NjA6OTg6MjU6MEU6QTI6RjgKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgMS4yLjg0MC4xMTM1MzMuNy42NS4wOiAKKyAgICAgICAgICAgICAgICAwCisuLlY0LjAuLi4uCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDIyOjEyOmQ4OjdhOjFkOmRjOjgxOjA2OmI2OjA5OjY1OmIyOjg3OmM4OjFmOjVlOmI0OjJmOgorICAgICAgICBlOTpjNDoxZTpmMjozYzpjMTpiYjowNDo5MDoxMTo0YTo4Mzo0ZTo3ZTo5MzpiOTo0ZDo0MjoKKyAgICAgICAgYzc6OTI6MjY6YTA6NWM6MzQ6OWE6Mzg6NzI6Zjg6ZmQ6NmI6MTY6M2U6MjA6ZWU6ODI6OGI6CisgICAgICAgIDMxOjJhOjkzOjM2Ojg1OjIzOjg4OjhhOjNjOjAzOjY4OmQzOmM5OjA5OjBmOjRkOmZjOjZjOgorICAgICAgICBhNDpkYToyODo3Mjo5MzowZTo4OTo4MDpiMDo3ZDpmZTo4MDo2Zjo2NTo2ZDoxODozMzo5NzoKKyAgICAgICAgOGI6YzI6NmI6ODk6ZWU6NjA6M2Q6Yzg6OWI6ZWY6N2Y6MmI6MzI6NjI6NzM6OTM6Y2I6M2M6CisgICAgICAgIGUzOjdiOmUyOjc2Ojc4OjQ1OmJjOmExOjkzOjA0OmJiOjg2OjlmOjNhOjViOjQzOjdhOmMzOgorICAgICAgICA4YTo2NQorU0hBMSBGaW5nZXJwcmludD04MTo5Njo4QjozQTpFRjoxQzpEQzo3MDpGNTpGQTozMjo2OTpDMjo5MjpBMzo2Mzo1QjpEMToyMzpEMwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2MzM2E4MGQ0LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYzMzYTgwZDQuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNzZiNjAxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2MzM2E4MGQ0LjAKQEAgLTAsMCArMSw1NiBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlESnpDQ0FwQ2dBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUVFGQURDQnpqRUxNQWtHQTFVRUJoTUNXa0V4CitGVEFUQmdOVkJBZ1RERmRsYzNSbGNtNGdRMkZ3WlRFU01CQUdBMVVFQnhNSlEyRndaU0JVYjNkdU1SMHdHd1lECitWUVFLRXhSVWFHRjNkR1VnUTI5dWMzVnNkR2x1WnlCall6RW9NQ1lHQTFVRUN4TWZRMlZ5ZEdsbWFXTmhkR2x2CitiaUJUWlhKMmFXTmxjeUJFYVhacGMybHZiakVoTUI4R0ExVUVBeE1ZVkdoaGQzUmxJRkJ5WlcxcGRXMGdVMlZ5CitkbVZ5SUVOQk1TZ3dKZ1lKS29aSWh2Y05BUWtCRmhsd2NtVnRhWFZ0TFhObGNuWmxja0IwYUdGM2RHVXVZMjl0CitNQjRYRFRrMk1EZ3dNVEF3TURBd01Gb1hEVEl3TVRJek1USXpOVGsxT1Zvd2djNHhDekFKQmdOVkJBWVRBbHBCCitNUlV3RXdZRFZRUUlFd3hYWlhOMFpYSnVJRU5oY0dVeEVqQVFCZ05WQkFjVENVTmhjR1VnVkc5M2JqRWRNQnNHCitBMVVFQ2hNVVZHaGhkM1JsSUVOdmJuTjFiSFJwYm1jZ1kyTXhLREFtQmdOVkJBc1RIME5sY25ScFptbGpZWFJwCitiMjRnVTJWeWRtbGpaWE1nUkdsMmFYTnBiMjR4SVRBZkJnTlZCQU1UR0ZSb1lYZDBaU0JRY21WdGFYVnRJRk5sCitjblpsY2lCRFFURW9NQ1lHQ1NxR1NJYjNEUUVKQVJZWmNISmxiV2wxYlMxelpYSjJaWEpBZEdoaGQzUmxMbU52CitiVENCbnpBTkJna3Foa2lHOXcwQkFRRUZBQU9CalFBd2dZa0NnWUVBMGpZMmFvdlh3bHVlMm9GQllvODQ3a2tFCitWZGJRN3h3YmxSWkg3eGhJTlRwUzlDdHFCbzg3TCtwVzQ2K0dqWjRYOTU2MFpYVUNUZS9MQ2FJaFVkaWIwR2ZRCit1ZzJTQmhSejFKUExseW9BbkZ4T0RMejZGVkw4OGtSdTJoRktiZ2lmTHkzaithbzZobk8yUmxOWXlJa0Z2WU1SCit1SE0vcWdlTjlFSk41MENkSERjQ0F3RUFBYU1UTUJFd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBTkJna3Foa2lHCis5dzBCQVFRRkFBT0JnUUFtU0N3V3dsajY2QlowREtxcVgxUS84dGZKZUdCZVhtNDNZeUozTm42eUY4UTB1ZlVJCitoZnpKQVRqL1RiN3lGa0pENTd0YVJ2dkJ4aEVmOFVxd0tFYkp3OFJDZmJ6NnExbHUxYmRSaUJIanBJVVphNEpNCitwQXdTcmVta3JqL3h3MGxsbW96RnlENGx0NVNadTVJeWNRZndobDd0VUNlbURhWWorYnZMcGdjVVFnPT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMSAoMHgxKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBtZDVXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9WkEsIFNUPVdlc3Rlcm4gQ2FwZSwgTD1DYXBlIFRvd24sIE89VGhhd3RlIENvbnN1bHRpbmcgY2MsIE9VPUNlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24sIENOPVRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQS9lbWFpbEFkZHJlc3M9cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogQXVnICAxIDAwOjAwOjAwIDE5OTYgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBEZWMgMzEgMjM6NTk6NTkgMjAyMCBHTVQKKyAgICAgICAgU3ViamVjdDogQz1aQSwgU1Q9V2VzdGVybiBDYXBlLCBMPUNhcGUgVG93biwgTz1UaGF3dGUgQ29uc3VsdGluZyBjYywgT1U9Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbiwgQ049VGhhd3RlIFByZW1pdW0gU2VydmVyIENBL2VtYWlsQWRkcmVzcz1wcmVtaXVtLXNlcnZlckB0aGF3dGUuY29tCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMTAyNCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMTAyNCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpkMjozNjozNjo2YTo4YjpkNzpjMjo1Yjo5ZTpkYTo4MTo0MTo2Mjo4ZjoKKyAgICAgICAgICAgICAgICAgICAgMzg6ZWU6NDk6MDQ6NTU6ZDY6ZDA6ZWY6MWM6MWI6OTU6MTY6NDc6ZWY6MTg6CisgICAgICAgICAgICAgICAgICAgIDQ4OjM1OjNhOjUyOmY0OjJiOjZhOjA2OjhmOjNiOjJmOmVhOjU2OmUzOmFmOgorICAgICAgICAgICAgICAgICAgICA4Njo4ZDo5ZToxNzpmNzo5ZTpiNDo2NTo3NTowMjo0ZDplZjpjYjowOTphMjoKKyAgICAgICAgICAgICAgICAgICAgMjE6NTE6ZDg6OWI6ZDA6Njc6ZDA6YmE6MGQ6OTI6MDY6MTQ6NzM6ZDQ6OTM6CisgICAgICAgICAgICAgICAgICAgIGNiOjk3OjJhOjAwOjljOjVjOjRlOjBjOmJjOmZhOjE1OjUyOmZjOmYyOjQ0OgorICAgICAgICAgICAgICAgICAgICA2ZTpkYToxMTo0YTo2ZTowODo5ZjoyZjoyZDplMzpmOTphYTozYTo4Njo3MzoKKyAgICAgICAgICAgICAgICAgICAgYjY6NDY6NTM6NTg6Yzg6ODk6MDU6YmQ6ODM6MTE6Yjg6NzM6M2Y6YWE6MDc6CisgICAgICAgICAgICAgICAgICAgIDhkOmY0OjQyOjRkOmU3OjQwOjlkOjFjOjM3CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogbWQ1V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMjY6NDg6MmM6MTY6YzI6NTg6ZmE6ZTg6MTY6NzQ6MGM6YWE6YWE6NWY6NTQ6M2Y6ZjI6ZDc6CisgICAgICAgIGM5Ojc4OjYwOjVlOjVlOjZlOjM3OjYzOjIyOjc3OjM2OjdlOmIyOjE3OmM0OjM0OmI5OmY1OgorICAgICAgICAwODo4NTpmYzpjOTowMTozODpmZjo0ZDpiZTpmMjoxNjo0Mjo0MzplNzpiYjo1YTo0NjpmYjoKKyAgICAgICAgYzE6YzY6MTE6MWY6ZjE6NGE6YjA6Mjg6NDY6Yzk6YzM6YzQ6NDI6N2Q6YmM6ZmE6YWI6NTk6CisgICAgICAgIDZlOmQ1OmI3OjUxOjg4OjExOmUzOmE0Ojg1OjE5OjZiOjgyOjRjOmE0OjBjOjEyOmFkOmU5OgorICAgICAgICBhNDphZTozZjpmMTpjMzo0OTo2NTo5YTo4YzpjNTpjODozZToyNTpiNzo5NDo5OTpiYjo5MjoKKyAgICAgICAgMzI6NzE6MDc6ZjA6ODY6NWU6ZWQ6NTA6Mjc6YTY6MGQ6YTY6MjM6Zjk6YmI6Y2I6YTY6MDc6CisgICAgICAgIDE0OjQyCitTSEExIEZpbmdlcnByaW50PTYyOjdGOjhEOjc4OjI3OjY1OjYzOjk5OkQyOjdEOjdGOjkwOjQ0OkM5OkZFOkIzOkYzOjNFOkZBOjlBCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYzUyN2U0YWIuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9jNTI3ZTRhYi4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM3NDZhYzgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYzUyN2U0YWIuMApAQCAtMCwwICsxLDc1IEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUVHakNDQXdJQ0VRRHNvS2VMYm5WcUFjL0VmTXd2bEY3WE1BMEdDU3FHU0liM0RRRUJCUVVBTUlIS01Rc3cKK0NRWURWUVFHRXdKVlV6RVhNQlVHQTFVRUNoTU9WbVZ5YVZOcFoyNHNJRWx1WXk0eEh6QWRCZ05WQkFzVEZsWmwKK2NtbFRhV2R1SUZSeWRYTjBJRTVsZEhkdmNtc3hPakE0QmdOVkJBc1RNU2hqS1NBeE9UazVJRlpsY21sVGFXZHUKK0xDQkpibU11SUMwZ1JtOXlJR0YxZEdodmNtbDZaV1FnZFhObElHOXViSGt4UlRCREJnTlZCQU1UUEZabGNtbFQKK2FXZHVJRU5zWVhOeklEUWdVSFZpYkdsaklGQnlhVzFoY25rZ1EyVnlkR2xtYVdOaGRHbHZiaUJCZFhSb2IzSnAKK2RIa2dMU0JITXpBZUZ3MDVPVEV3TURFd01EQXdNREJhRncwek5qQTNNVFl5TXpVNU5UbGFNSUhLTVFzd0NRWUQKK1ZRUUdFd0pWVXpFWE1CVUdBMVVFQ2hNT1ZtVnlhVk5wWjI0c0lFbHVZeTR4SHpBZEJnTlZCQXNURmxabGNtbFQKK2FXZHVJRlJ5ZFhOMElFNWxkSGR2Y21zeE9qQTRCZ05WQkFzVE1TaGpLU0F4T1RrNUlGWmxjbWxUYVdkdUxDQkoKK2JtTXVJQzBnUm05eUlHRjFkR2h2Y21sNlpXUWdkWE5sSUc5dWJIa3hSVEJEQmdOVkJBTVRQRlpsY21sVGFXZHUKK0lFTnNZWE56SURRZ1VIVmliR2xqSUZCeWFXMWhjbmtnUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa2cKK0xTQkhNekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFLM0xwUkZweGxtcjhZKzEKK0dROVd6c3kxSHlEa25pWWxTK0J6WllsWjN0Q0Q1UFVQdGJ1dDhYem9JZnprNkF6dWZFVWlHWGFTdEJPM0lGc0oKKyttR3VxUEtsallYQ0t0YmVaamJTbXdMMHFKSmdmSnhwdEk4a0h0Q0dVdll5bkVGWUhpSzl6VVZpbFFodTBHYmQKK1U2TE04QkRjVkhPTEJLRkdNek5jRjBDNW5rM1Q4NzVWZytpeGlZNWFmSnFXSXBBN2lDWHkwbE9JQWd3TGVQTG0KK054ZExNRVlINUlCdHB0aVdMdWdzK0JHek9BMW1wcHZxeVNOYjI0N2k4eE9PR2xrdHFnTHc3S1NIWnR6QlAvWFkKK3VmVHNnc2JTUFpVZDVjQlBoTW5abzBRb0JtclhSYXp3YTJydlRsLzRFWUllT0dNMFpsRFVQcE56K2pERFpxMy8KK2t5Mlg3d01DQXdFQUFUQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFqL29sYTA5YjVLUk9KMVdySWhWWlBNcTEKK0N0UksyNnZkb1Y5VHhhQlhPY0xPUnl1K09zaFd2OExaSnhBNnNRVTh3SGN4dXpyVEJYdHRtaHd3aklETGs1TXEKK2c2c0ZVWUlDQUJGbmEvT0lZVWRmQTVQVld3M2c4ZFNoTWpXRnNqcmJzSUtyMGNzS3ZFK01XOFZMQURzZktvS20KK2ZqYUYzSDQ4WndDMTVEdFM0S2pyWFJYNXhtM3dyUjBPaGJlcG1uTVVXbHVQUVNqQTFlZ3RUYVJlemFyWjdjN2MKKzJOVThRaDBYd1JKZFJUakRPUFA4aFM2RFJraXkxeUJma2phUDUza1BtRjZaNlBEUXBMdjFVNzBxemxtd3IyNS8KK2JMdlNIZ0N3SWUzNFFXS0N1ZGl5eEx0R1VQTXh4WThCcUhUcjlYZ24ydWYzWmtQem5vTStJS3JETldDUnpnPT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDEgKDB4MCkKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIGVjOmEwOmE3OjhiOjZlOjc1OjZhOjAxOmNmOmM0OjdjOmNjOjJmOjk0OjVlOmQ3CisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9VVMsIE89VmVyaVNpZ24sIEluYy4sIE9VPVZlcmlTaWduIFRydXN0IE5ldHdvcmssIE9VPShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHksIENOPVZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMworICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogT2N0ICAxIDAwOjAwOjAwIDE5OTkgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBKdWwgMTYgMjM6NTk6NTkgMjAzNiBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgTz1WZXJpU2lnbiwgSW5jLiwgT1U9VmVyaVNpZ24gVHJ1c3QgTmV0d29yaywgT1U9KGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seSwgQ049VmVyaVNpZ24gQ2xhc3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDphZDpjYjphNToxMTo2OTpjNjo1OTphYjpmMTo4ZjpiNToxOTowZjo1NjoKKyAgICAgICAgICAgICAgICAgICAgY2U6Y2M6YjU6MWY6MjA6ZTQ6OWU6MjY6MjU6NGI6ZTA6NzM6NjU6ODk6NTk6CisgICAgICAgICAgICAgICAgICAgIGRlOmQwOjgzOmU0OmY1OjBmOmI1OmJiOmFkOmYxOjdjOmU4OjIxOmZjOmU0OgorICAgICAgICAgICAgICAgICAgICBlODowYzplZTo3Yzo0NToyMjoxOTo3Njo5MjpiNDoxMzpiNzoyMDo1YjowOToKKyAgICAgICAgICAgICAgICAgICAgZmE6NjE6YWU6YTg6ZjI6YTU6OGQ6ODU6YzI6MmE6ZDY6ZGU6NjY6MzY6ZDI6CisgICAgICAgICAgICAgICAgICAgIDliOjAyOmY0OmE4OjkyOjYwOjdjOjljOjY5OmI0OjhmOjI0OjFlOmQwOjg2OgorICAgICAgICAgICAgICAgICAgICA1MjpmNjozMjo5Yzo0MTo1ODoxZToyMjpiZDpjZDo0NTo2Mjo5NTowODo2ZToKKyAgICAgICAgICAgICAgICAgICAgZDA6NjY6ZGQ6NTM6YTI6Y2M6ZjA6MTA6ZGM6NTQ6NzM6OGI6MDQ6YTE6NDY6CisgICAgICAgICAgICAgICAgICAgIDMzOjMzOjVjOjE3OjQwOmI5OjllOjRkOmQzOmYzOmJlOjU1OjgzOmU4OmIxOgorICAgICAgICAgICAgICAgICAgICA4OTo4ZTo1YTo3Yzo5YTo5NjoyMjo5MDozYjo4ODoyNTpmMjpkMjo1Mzo4ODoKKyAgICAgICAgICAgICAgICAgICAgMDI6MGM6MGI6Nzg6ZjI6ZTY6Mzc6MTc6NGI6MzA6NDY6MDc6ZTQ6ODA6NmQ6CisgICAgICAgICAgICAgICAgICAgIGE2OmQ4Ojk2OjJlOmU4OjJjOmY4OjExOmIzOjM4OjBkOjY2OmE2OjliOmVhOgorICAgICAgICAgICAgICAgICAgICBjOToyMzo1YjpkYjo4ZTplMjpmMzoxMzo4ZToxYTo1OToyZDphYTowMjpmMDoKKyAgICAgICAgICAgICAgICAgICAgZWM6YTQ6ODc6NjY6ZGM6YzE6M2Y6ZjU6ZDg6Yjk6ZjQ6ZWM6ODI6YzY6ZDI6CisgICAgICAgICAgICAgICAgICAgIDNkOjk1OjFkOmU1OmMwOjRmOjg0OmM5OmQ5OmEzOjQ0OjI4OjA2OjZhOmQ3OgorICAgICAgICAgICAgICAgICAgICA0NTphYzpmMDo2Yjo2YTplZjo0ZTo1ZjpmODoxMTo4MjoxZTozODo2MzozNDoKKyAgICAgICAgICAgICAgICAgICAgNjY6NTA6ZDQ6M2U6OTM6NzM6ZmE6MzA6YzM6NjY6YWQ6ZmY6OTM6MmQ6OTc6CisgICAgICAgICAgICAgICAgICAgIGVmOjAzCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA4ZjpmYToyNTo2Yjo0Zjo1YjplNDphNDo0ZToyNzo1NTphYjoyMjoxNTo1OTozYzpjYTpiNToKKyAgICAgICAgMGE6ZDQ6NGE6ZGI6YWI6ZGQ6YTE6NWY6NTM6YzU6YTA6NTc6Mzk6YzI6Y2U6NDc6MmI6YmU6CisgICAgICAgIDNhOmM4OjU2OmJmOmMyOmQ5OjI3OjEwOjNhOmIxOjA1OjNjOmMwOjc3OjMxOmJiOjNhOmQzOgorICAgICAgICAwNTo3Yjo2ZDo5YToxYzozMDo4Yzo4MDpjYjo5Mzo5MzoyYTo4MzphYjowNTo1MTo4MjowMjoKKyAgICAgICAgMDA6MTE6Njc6NmI6ZjM6ODg6NjE6NDc6NWY6MDM6OTM6ZDU6NWI6MGQ6ZTA6ZjE6ZDQ6YTE6CisgICAgICAgIDMyOjM1Ojg1OmIyOjNhOmRiOmIwOjgyOmFiOmQxOmNiOjBhOmJjOjRmOjhjOjViOmM1OjRiOgorICAgICAgICAwMDozYjoxZjoyYTo4MjphNjo3ZTozNjo4NTpkYzo3ZTozYzo2NzowMDpiNTplNDozYjo1MjoKKyAgICAgICAgZTA6YTg6ZWI6NWQ6MTU6Zjk6YzY6NmQ6ZjA6YWQ6MWQ6MGU6ODU6Yjc6YTk6OWE6NzM6MTQ6CisgICAgICAgIDVhOjViOjhmOjQxOjI4OmMwOmQ1OmU4OjJkOjRkOmE0OjVlOmNkOmFhOmQ5OmVkOmNlOmRjOgorICAgICAgICBkODpkNTozYzo0MjoxZDoxNzpjMToxMjo1ZDo0NTozODpjMzozODpmMzpmYzo4NToyZTo4MzoKKyAgICAgICAgNDY6NDg6YjI6ZDc6MjA6NWY6OTI6MzY6OGY6ZTc6Nzk6MGY6OTg6NWU6OTk6ZTg6ZjA6ZDA6CisgICAgICAgIGE0OmJiOmY1OjUzOmJkOjJhOmNlOjU5OmIwOmFmOjZlOjdmOjZjOmJiOmQyOjFlOjAwOmIwOgorICAgICAgICAyMTplZDpmODo0MTo2Mjo4MjpiOTpkODpiMjpjNDpiYjo0Njo1MDpmMzozMTpjNTo4ZjowMToKKyAgICAgICAgYTg6NzQ6ZWI6ZjU6Nzg6Mjc6ZGE6ZTc6Zjc6NjY6NDM6ZjM6OWU6ODM6M2U6MjA6YWE6YzM6CisgICAgICAgIDM1OjYwOjkxOmNlCitTSEExIEZpbmdlcnByaW50PUM4OkVDOjhDOjg3OjkyOjY5OkNCOjRCOkFCOjM5OkU5OjhEOjdFOjU3OjY3OkYzOjE0Ojk1OjczOjlECmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYzdlMmE2MzguMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9jN2UyYTYzOC4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc5OWUyZTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYzdlMmE2MzguMApAQCAtMCwwICsxLDgyIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUQvakNDQXVhZ0F3SUJBZ0lRRmF4dWxCbXllVXRCOWllcHd4Z1BIekFOQmdrcWhraUc5dzBCQVFzRkFEQ0IKK21ERUxNQWtHQTFVRUJoTUNWVk14RmpBVUJnTlZCQW9URFVkbGIxUnlkWE4wSUVsdVl5NHhPVEEzQmdOVkJBc1QKK01DaGpLU0F5TURBNElFZGxiMVJ5ZFhOMElFbHVZeTRnTFNCR2IzSWdZWFYwYUc5eWFYcGxaQ0IxYzJVZ2IyNXMKK2VURTJNRFFHQTFVRUF4TXRSMlZ2VkhKMWMzUWdVSEpwYldGeWVTQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHYKK2NtbDBlU0F0SUVjek1CNFhEVEE0TURRd01qQXdNREF3TUZvWERUTTNNVEl3TVRJek5UazFPVm93Z1pneEN6QUoKK0JnTlZCQVlUQWxWVE1SWXdGQVlEVlFRS0V3MUhaVzlVY25WemRDQkpibU11TVRrd053WURWUVFMRXpBb1l5a2cKK01qQXdPQ0JIWlc5VWNuVnpkQ0JKYm1NdUlDMGdSbTl5SUdGMWRHaHZjbWw2WldRZ2RYTmxJRzl1YkhreE5qQTAKK0JnTlZCQU1UTFVkbGIxUnlkWE4wSUZCeWFXMWhjbmtnUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa2cKK0xTQkhNekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFOemlYbUpZSFROWE9USXoKKyt1dkxoNHluMUVyZEJvanFaSTR4bUtVNGtCNll6eTVqSy9CR3ZFU3lpYUhBS0F4SmNDR1ZuMlRBcHBNU0FtVW0KK2hzYWxpZkQ2MTRTZ2NLOVBHcGMvQmtUVnlldHlFSDNrTVNqN0hHSG1LQWRFYzVJaWFhY0RpR3lkWThoUzJwZ24KKzV3aE1jRDYweVJMQnhXZURYVFB6QXhIc2F0QlQ0dEc2Tm1DVWdMdGhZMnhiRjM3ZlFKUWVxdzNDSVNod2lQL1cKK0pteHNZQVFsVGxWK2ZlKy9sRWpldHgzZGNJMEZYNGlsbS9MQzd1clJRRUZ0WWpnZFZnYkZBMGRSSUJuOGV4QUwKK0RtS3VkbFcvWDNlK1Bra0JVejJZSlFOMkpGb2R0TnVKNm5ubHRyTTdQN3BNS0VGL0JxeHFqc0hROWdVZGZlWkMKK2h1T2wxVWNDQXdFQUFhTkNNRUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFQkFNQ0FRWXcKK0hRWURWUjBPQkJZRUZNUjV5bzZoVGdNZEhOeHIyekZibEQ0L01IOHRNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUIKK0FRQXR4UlBQVm9CN2VuaTluNjRzbWVmdjJ0K1VYZ2xwcCtkdWFJeTljcjVIcVE2WEVyaEs4V1RUT2Q4bE5OVEIKK3pVNkI4QThFeENTek5KYkdwcW93MzJoaGM5ZjVqb1dKN3c1ZWxTaEtLaWVQRUk0dWZJYkVBcDdhREhkbERrUU4KK2t2MzlzeFkyK2hFTkhZd09CNGxxS1ZiM2N2VGRGWngzTldaWHF4TlQySTdCUU1YWEV4WmFjc2UzYVFIRWVyR0QKK0FXaDlqVUdobEJqQkpWejg4UDZEQW9kOERRM1BMZ2hjU2tBTlB1eUJZZVlrMjhyZ0RpMEhzajVXM0kzMVFZVUgKK1NKc01DOHRKUDMzc3QvM0xqV2VKR3F2dHV4NmpBQWdJRnlxQ1hERmRSb290RDRhYmRObEYrOVJBc1hxcWFDMkcKK3Nwa2k0Y0VyeDV6NDgxK29naExyR1JFdAorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgMTU6YWM6NmU6OTQ6MTk6YjI6Nzk6NGI6NDE6ZjY6Mjc6YTk6YzM6MTg6MGY6MWYKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPUdlb1RydXN0IEluYy4sIE9VPShjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seSwgQ049R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBBcHIgIDIgMDA6MDA6MDAgMjAwOCBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IERlYyAgMSAyMzo1OTo1OSAyMDM3IEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPUdlb1RydXN0IEluYy4sIE9VPShjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seSwgQ049R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpkYzplMjo1ZTo2Mjo1ODoxZDozMzo1NzozOTozMjozMzpmYTplYjpjYjoKKyAgICAgICAgICAgICAgICAgICAgODc6OGM6YTc6ZDQ6NGE6ZGQ6MDY6ODg6ZWE6NjQ6OGU6MzE6OTg6YTU6Mzg6CisgICAgICAgICAgICAgICAgICAgIDkwOjFlOjk4OmNmOjJlOjYzOjJiOmYwOjQ2OmJjOjQ0OmIyOjg5OmExOmMwOgorICAgICAgICAgICAgICAgICAgICAyODowYzo0OTo3MDoyMTo5NTo5Zjo2NDpjMDphNjo5MzoxMjowMjo2NToyNjoKKyAgICAgICAgICAgICAgICAgICAgODY6YzY6YTU6ODk6ZjA6ZmE6ZDc6ODQ6YTA6NzA6YWY6NGY6MWE6OTc6M2Y6CisgICAgICAgICAgICAgICAgICAgIDA2OjQ0OmQ1OmM5OmViOjcyOjEwOjdkOmU0OjMxOjI4OmZiOjFjOjYxOmU2OgorICAgICAgICAgICAgICAgICAgICAyODowNzo0NDo3Mzo5MjoyMjo2OTphNzowMzo4ODo2Yzo5ZDo2MzpjODo1MjoKKyAgICAgICAgICAgICAgICAgICAgZGE6OTg6Mjc6ZTc6MDg6NGM6NzA6M2U6YjQ6Yzk6MTI6YzE6YzU6Njc6ODM6CisgICAgICAgICAgICAgICAgICAgIDVkOjMzOmYzOjAzOjExOmVjOjZhOmQwOjUzOmUyOmQxOmJhOjM2OjYwOjk0OgorICAgICAgICAgICAgICAgICAgICA4MDpiYjo2MTo2Mzo2Yzo1YjoxNzo3ZTpkZjo0MDo5NDoxZTphYjowZDpjMjoKKyAgICAgICAgICAgICAgICAgICAgMjE6Mjg6NzA6ODg6ZmY6ZDY6MjY6NmM6NmM6NjA6MDQ6MjU6NGU6NTU6N2U6CisgICAgICAgICAgICAgICAgICAgIDdkOmVmOmJmOjk0OjQ4OmRlOmI3OjFkOmRkOjcwOjhkOjA1OjVmOjg4OmE1OgorICAgICAgICAgICAgICAgICAgICA5YjpmMjpjMjplZTplYTpkMTo0MDo0MTo2ZDo2MjozODoxZDo1NjowNjpjNToKKyAgICAgICAgICAgICAgICAgICAgMDM6NDc6NTE6MjA6MTk6ZmM6N2I6MTA6MGI6MGU6NjI6YWU6NzY6NTU6YmY6CisgICAgICAgICAgICAgICAgICAgIDVmOjc3OmJlOjNlOjQ5OjAxOjUzOjNkOjk4OjI1OjAzOjc2OjI0OjVhOjFkOgorICAgICAgICAgICAgICAgICAgICBiNDpkYjo4OTplYTo3OTplNTpiNjpiMzozYjozZjpiYTo0YzoyODo0MTo3ZjoKKyAgICAgICAgICAgICAgICAgICAgMDY6YWM6NmE6OGU6YzE6ZDA6ZjY6MDU6MWQ6N2Q6ZTY6NDI6ODY6ZTM6YTU6CisgICAgICAgICAgICAgICAgICAgIGQ1OjQ3CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgQzQ6Nzk6Q0E6OEU6QTE6NEU6MDM6MUQ6MUM6REM6NkI6REI6MzE6NUI6OTQ6M0U6M0Y6MzA6N0Y6MkQKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAyZDpjNToxMzpjZjo1Njo4MDo3Yjo3YTo3ODpiZDo5ZjphZToyYzo5OTplNzplZjpkYTpkZjoKKyAgICAgICAgOTQ6NWU6MDk6Njk6YTc6ZTc6NmU6Njg6OGM6YmQ6NzI6YmU6NDc6YTk6MGU6OTc6MTI6Yjg6CisgICAgICAgIDRhOmYxOjY0OmQzOjM5OmRmOjI1OjM0OmQ0OmMxOmNkOjRlOjgxOmYwOjBmOjA0OmM0OjI0OgorICAgICAgICBiMzozNDo5NjpjNjphNjphYTozMDpkZjo2ODo2MTo3MzpkNzpmOTo4ZTo4NTo4OTplZjowZToKKyAgICAgICAgNWU6OTU6Mjg6NGE6MmE6Mjc6OGY6MTA6OGU6MmU6N2M6ODY6YzQ6MDI6OWU6ZGE6MGM6Nzc6CisgICAgICAgIDY1OjBlOjQ0OjBkOjkyOmZkOmZkOmIzOjE2OjM2OmZhOjExOjBkOjFkOjhjOjBlOjA3Ojg5OgorICAgICAgICA2YToyOTo1NjpmNzo3MjpmNDpkZDoxNTo5Yzo3NzozNTo2Njo1NzphYjoxMzo1MzpkODo4ZToKKyAgICAgICAgYzE6NDA6YzU6ZDc6MTM6MTY6NWE6NzI6Yzc6Yjc6Njk6MDE6YzQ6N2E6YjE6ODM6MDE6Njg6CisgICAgICAgIDdkOjhkOjQxOmExOjk0OjE4OmMxOjI1OjVjOmZjOmYwOmZlOjgzOjAyOjg3OjdjOjBkOjBkOgorICAgICAgICBjZjoyZTowODo1Yzo0YTo0MDowZDozZTplYzo4MTo2MTplNjoyNDpkYjpjYTplMDowZToyZDoKKyAgICAgICAgMDc6YjI6M2U6NTY6ZGM6OGQ6ZjU6NDE6ODU6MDc6NDg6OWI6MGM6MGI6Y2I6NDk6M2Y6N2Q6CisgICAgICAgIGVjOmI3OmZkOmNiOjhkOjY3Ojg5OjFhOmFiOmVkOmJiOjFlOmEzOjAwOjA4OjA4OjE3OjJhOgorICAgICAgICA4Mjo1YzozMTo1ZDo0Njo4YToyZDowZjo4Njo5Yjo3NDpkOTo0NTpmYjpkNDo0MDpiMTo3YToKKyAgICAgICAgYWE6Njg6MmQ6ODY6YjI6OTk6MjI6ZTE6YzE6MmI6Yzc6OWM6Zjg6ZjM6NWY6YTg6ODI6MTI6CisgICAgICAgIGViOjE5OjExOjJkCitTSEExIEZpbmdlcnByaW50PTAzOjlFOkVEOkI4OjBCOkU3OkEwOjNDOjY5OjUzOjg5OjNCOjIwOkQyOkQ5OjMyOjNBOjRDOjJBOkZECmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYzg3NjM1OTMuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9jODc2MzU5My4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE0OGUxNjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvYzg3NjM1OTMuMApAQCAtMCwwICsxLDEzMiBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlHWmpDQ0JFNmdBd0lCQWdJUEIzNVNrM3ZnRmVOWDhHbU15K3dNTUEwR0NTcUdTSWIzRFFFQkJRVUFNSHN4CitDekFKQmdOVkJBWVRBa05QTVVjd1JRWURWUVFLREQ1VGIyTnBaV1JoWkNCRFlXMWxjbUZzSUdSbElFTmxjblJwCitabWxqWVdOcHc3TnVJRVJwWjJsMFlXd2dMU0JEWlhKMGFXUERvVzFoY21FZ1V5NUJMakVqTUNFR0ExVUVBd3dhCitRVU1nVW1IRHJYb2dRMlZ5ZEdsanc2RnRZWEpoSUZNdVFTNHdIaGNOTURZeE1USTNNakEwTmpJNVdoY05NekF3CitOREF5TWpFME1qQXlXakI3TVFzd0NRWURWUVFHRXdKRFR6RkhNRVVHQTFVRUNndytVMjlqYVdWa1lXUWdRMkZ0CitaWEpoYkNCa1pTQkRaWEowYVdacFkyRmphY096YmlCRWFXZHBkR0ZzSUMwZ1EyVnlkR2xqdzZGdFlYSmhJRk11CitRUzR4SXpBaEJnTlZCQU1NR2tGRElGSmh3NjE2SUVObGNuUnBZOE9oYldGeVlTQlRMa0V1TUlJQ0lqQU5CZ2txCitoa2lHOXcwQkFRRUZBQU9DQWc4QU1JSUNDZ0tDQWdFQXEydUpvMVBNU0NNSSs4UFBVWllJTHJnSWVtMDhrQmVHCitxZW50TGhNMFI3TFFjTnpKUE5DTnl1NUxGNnZRaGJDbkl3VExxS0w4NVhYYlFNcGlpWTlRbmdFOUpsc1loQnpMCitmRGUzZmV6VGYzTVpzR3F5MklpS0xVVjBxUGV6dU1EVTJzMGlpWFJOV2hVNWN4aDBUN1hybWFmQkhvaTB3cE9RCitZNWZ6cDZjU3Nna2lCelBaa2MwT25COE9JTWZ1dXpPTmo4TFNXS2RmL1dVMzRvakMySStHZFY3NUxhZUhNL0o0CitOeStMdkIyR056bXhsUExZdkVxY2d4aGFCdnp6MU5TNmpCVUpKZkQ1dG8wRWZoY1NNMnRYU0V4UDJ5WWU2OHlRCis1NHY1YUh4d0Q2TXEwRG80M3plWDRsdmVnR0hUZ05pUmcwSmFUQVNKYUJFOHJGOW9nRUhNWUVMT0RWb3FEQStiCitNTUNtOEliYnEwblhsMjFJaS9rRHdGSm5teEwzd3ZJdW1HVkMyZGFhNDlBWk1ReXRoOVZYQW5vdzZJWW0rNDhqCitpbFNINUw4ODd1dkRkVWhmSGpsdmdXSnN4UzNFRjFRWnR6ZU5uRGVSeVBZTDFlcGpiNE9zT01MelA5NmErK0VqCitZZkRJSnNzMnlLSHpNSStrbzZLaDNWT3ozdkNhTWgrRGtYa3d3YWtmVTV0VG9oVlRQOTJkc3hBN1NIMkpEL3p0CitBL1g3SldSMURoY1pEWThBRm1kNWVrRDhMVmtIMlpENm1xMDkzSUNLNWx3MW9tZE1FV3V4K0lCa0FDMXZJbUhGCityRXNtNVZvUWdwdWtnM3MwOTU2SmtTQ1hqcmRDeDJiRDBPbWsxdlVnamNURGxheEVDcDFiY3p3bVBTOUt2cWZKCitweEFlKzU5UWFmTUNBd0VBQWFPQjVqQ0I0ekFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTRHQTFVZER3RUIvd1FFCitBd0lCQmpBZEJnTlZIUTRFRmdRVTBRblE2ZGZPZVhSVStUb3dzL1J0TEFNREcyZ3dnYUFHQTFVZElBU0JtRENCCitsVENCa2dZRVZSMGdBRENCaVRBckJnZ3JCZ0VGQlFjQ0FSWWZhSFIwY0RvdkwzZDNkeTVqWlhKMGFXTmhiV0Z5CitZUzVqYjIwdlpIQmpMekJhQmdnckJnRUZCUWNDQWpCT0dreE1hVzFwZEdGamFXOXVaWE1nWkdVZ1oyRnlZVzUwCis3V0Z6SUdSbElHVnpkR1VnWTJWeWRHbG1hV05oWkc4Z2MyVWdjSFZsWkdWdUlHVnVZMjl1ZEhKaGNpQmxiaUJzCitZU0JFVUVNdU1BMEdDU3FHU0liM0RRRUJCUVVBQTRJQ0FRQmNsTFc0UlpGTmptRWZBeWdQVTN6bXBGbXBzNHA2Cit4YkQvQ0h3c28zRWNJUk5ub1pVU1FEV0RnNDkwMnpOYzhFbDJDb0ZTM1VuVW1qSXo3NXVueTNYbGVzdVhFcEJjCit1bnZGbTkrN09TUEkvNWpPQ2swaUFVZ0hmb3JBMVNCQ2xFVHZ2M2VpaVdkSUcwQURCYUdKN005aTR6MGxkbWEvCitKcmU3SXI1di96bFhkTHA2eVFHVndaVlI2S3NzK0xHR0lPay95elZiMGhmcEt2NkRFeGRBN29oaVpWdlZPMkRwCitlenk0eWRWL05nSWxxbWpDTVJXM01HWHJmeDFJZWJIUE9lSkNnQmJUOVpNai9FeVh5Vm8zYkh3aTJFck4wbzQyCitnem1Sa0JESThjazFmais0MDRIR0lHUWF0bERDSWFSNDNOQXZPMlNUZFBDV2tQSHYrd2xhTkVDVzhEWVN3YU4wCitqSk4rUWQ1M2kreUcyZElQUHkzUnpFQ2lpV1pJSGlDem5DTlpjNmxFYzd3a2VaQldON1BHS1g2akQvRXBPZTkrCitYQ2d5Y0RXczJyaklkV2I4bTB3NVI0NGJiNXROQWxRaU0rOWh1cDRwaE85T1N6TkhkcGRxeTM1Zi9SV21ua0pECitXMlphaW9nTjl4YTVQMUZsSzJacWk5RTRVcUxXUmhINi9Kb2NkSjZQbHdzQ1QyVEc5V2pUU3kzL3BEY2VpeisvCitSTDVoUnFHRVBRZ25USUVnZDRrSTZtZEFYbXdJVVY4MFdveVdhTTNYOTRuQ0hOTXlBSzlTeTlOZ1d5bzZSMzVyCitNRE9oWWlsL1NybmhMZWNVSXc0T0dFZmhlZndWVmRDeC9DVnhZM1V6SENNcnIxelo3VWQzWUE0N0R4N1N3TnhrCitCWW44ZU5aY0xDWkRxUT09CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICAwNzo3ZTo1Mjo5Mzo3YjplMDoxNTplMzo1NzpmMDo2OTo4YzpjYjplYzowYworICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPUNPLCBPPVNvY2llZGFkIENhbWVyYWwgZGUgQ2VydGlmaWNhY2lceEMzXHhCM24gRGlnaXRhbCAtIENlcnRpY1x4QzNceEExbWFyYSBTLkEuLCBDTj1BQyBSYVx4QzNceEFEeiBDZXJ0aWNceEMzXHhBMW1hcmEgUy5BLgorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTm92IDI3IDIwOjQ2OjI5IDIwMDYgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBBcHIgIDIgMjE6NDI6MDIgMjAzMCBHTVQKKyAgICAgICAgU3ViamVjdDogQz1DTywgTz1Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRpZmljYWNpXHhDM1x4QjNuIERpZ2l0YWwgLSBDZXJ0aWNceEMzXHhBMW1hcmEgUy5BLiwgQ049QUMgUmFceEMzXHhBRHogQ2VydGljXHhDM1x4QTFtYXJhIFMuQS4KKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICg0MDk2IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICg0MDk2IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmFiOjZiOjg5OmEzOjUzOmNjOjQ4OjIzOjA4OmZiOmMzOmNmOjUxOjk2OgorICAgICAgICAgICAgICAgICAgICAwODoyZTpiODowODo3YTo2ZDozYzo5MDoxNzo4NjphOTplOTplZDoyZToxMzoKKyAgICAgICAgICAgICAgICAgICAgMzQ6NDc6YjI6ZDA6NzA6ZGM6Yzk6M2M6ZDA6OGQ6Y2E6ZWU6NGI6MTc6YWI6CisgICAgICAgICAgICAgICAgICAgIGQwOjg1OmIwOmE3OjIzOjA0OmNiOmE4OmEyOmZjOmU1Ojc1OmRiOjQwOmNhOgorICAgICAgICAgICAgICAgICAgICA2Mjo4OTo4Zjo1MDo5ZTowMTozZDoyNjo1YjoxODo4NDoxYzpjYjo3YzozNzoKKyAgICAgICAgICAgICAgICAgICAgYjc6N2Q6ZWM6ZDM6N2Y6NzM6MTk6YjA6NmE6YjI6ZDg6ODg6OGE6MmQ6NDU6CisgICAgICAgICAgICAgICAgICAgIDc0OmE4OmY3OmIzOmI4OmMwOmQ0OmRhOmNkOjIyOjg5Ojc0OjRkOjVhOjE1OgorICAgICAgICAgICAgICAgICAgICAzOTo3MzoxODo3NDo0ZjpiNTplYjo5OTphNzpjMToxZTo4ODpiNDpjMjo5MzoKKyAgICAgICAgICAgICAgICAgICAgOTA6NjM6OTc6ZjM6YTc6YTc6MTI6YjI6MDk6MjI6MDc6MzM6ZDk6OTE6Y2Q6CisgICAgICAgICAgICAgICAgICAgIDBlOjljOjFmOjBlOjIwOmM3OmVlOmJiOjMzOjhkOjhmOmMyOmQyOjU4OmE3OgorICAgICAgICAgICAgICAgICAgICA1ZjpmZDo2NTozNzplMjo4ODpjMjpkODo4Zjo4Njo3NTo1ZTpmOToyZDphNzoKKyAgICAgICAgICAgICAgICAgICAgODc6MzM6ZjI6Nzg6Mzc6MmY6OGI6YmM6MWQ6ODY6Mzc6Mzk6YjE6OTQ6ZjI6CisgICAgICAgICAgICAgICAgICAgIGQ4OmJjOjRhOjljOjgzOjE4OjVhOjA2OmZjOmYzOmQ0OmQ0OmJhOjhjOjE1OgorICAgICAgICAgICAgICAgICAgICAwOToyNTpmMDpmOTpiNjo4ZDowNDo3ZToxNzoxMjozMzo2Yjo1Nzo0ODo0YzoKKyAgICAgICAgICAgICAgICAgICAgNGY6ZGI6MjY6MWU6ZWI6Y2M6OTA6ZTc6OGI6Zjk6Njg6N2M6NzA6MGY6YTM6CisgICAgICAgICAgICAgICAgICAgIDJhOmQwOjNhOjM4OmRmOjM3Ojk3OmUyOjViOmRlOjgwOjYxOmQzOjgwOmQ4OgorICAgICAgICAgICAgICAgICAgICA5MTo4Mzo0Mjo1YTo0YzowNDo4OTo2ODoxMTozYzphYzo1Zjo2ODo4MDo0MToKKyAgICAgICAgICAgICAgICAgICAgY2M6NjA6NDI6Y2U6MGQ6NWE6MmE6MGM6MGY6OWI6MzA6YzA6YTY6ZjA6ODY6CisgICAgICAgICAgICAgICAgICAgIGRiOmFiOjQ5OmQ3Ojk3OjZkOjQ4OjhiOmY5OjAzOmMwOjUyOjY3OjliOjEyOgorICAgICAgICAgICAgICAgICAgICBmNzpjMjpmMjoyZTo5ODo2NTo0MjpkOTpkNjo5YTplMzpkMDoxOTozMTowYzoKKyAgICAgICAgICAgICAgICAgICAgYWQ6ODc6ZDU6NTc6MDI6N2E6MzA6ZTg6ODY6MjY6ZmI6OGY6MjM6OGE6NTQ6CisgICAgICAgICAgICAgICAgICAgIDg3OmU0OmJmOjNjOmVlOmViOmMzOjc1OjQ4OjVmOjFlOjM5OjZmOjgxOjYyOgorICAgICAgICAgICAgICAgICAgICA2YzpjNToyZDpjNDoxNzo1NDoxOTpiNzozNzo4ZDo5YzozNzo5MTpjODpmNjoKKyAgICAgICAgICAgICAgICAgICAgMGI6ZDU6ZWE6NjM6NmY6ODM6YWM6Mzg6YzI6ZjM6M2Y6ZGU6OWE6ZmI6ZTE6CisgICAgICAgICAgICAgICAgICAgIDIzOjYxOmYwOmM4OjI2OmNiOjM2OmM4OmExOmYzOjMwOjhmOmE0OmEzOmEyOgorICAgICAgICAgICAgICAgICAgICBhMTpkZDo1MzpiMzpkZTpmMDo5YTozMjoxZjo4Mzo5MTo3OTozMDpjMTphOToKKyAgICAgICAgICAgICAgICAgICAgMWY6NTM6OWI6NTM6YTI6MTU6NTM6M2Y6ZGQ6OWQ6YjM6MTA6M2I6NDg6N2Q6CisgICAgICAgICAgICAgICAgICAgIDg5OjBmOmZjOmVkOjAzOmY1OmZiOjI1OjY0Ojc1OjBlOjE3OjE5OjBkOjhmOgorICAgICAgICAgICAgICAgICAgICAwMDoxNjo2Nzo3OTo3YTo0MDpmYzoyZDo1OTowNzpkOTo5MDpmYTo5YTphZDoKKyAgICAgICAgICAgICAgICAgICAgM2Q6ZGM6ODA6OGE6ZTY6NWM6MzU6YTI6Njc6NGM6MTE6NmI6YjE6Zjg6ODA6CisgICAgICAgICAgICAgICAgICAgIDY0OjAwOjJkOjZmOjIyOjYxOmM1OmFjOjRiOjI2OmU1OjVhOjEwOjgyOjliOgorICAgICAgICAgICAgICAgICAgICBhNDo4Mzo3YjozNDpmNzo5ZTo4OTo5MToyMDo5Nzo4ZTpiNzo0MjpjNzo2NjoKKyAgICAgICAgICAgICAgICAgICAgYzM6ZDA6ZTk6YTQ6ZDY6ZjU6MjA6OGQ6YzQ6YzM6OTU6YWM6NDQ6MGE6OWQ6CisgICAgICAgICAgICAgICAgICAgIDViOjczOjNjOjI2OjNkOjJmOjRhOmJlOmE3OmM5OmE3OjEwOjFlOmZiOjlmOgorICAgICAgICAgICAgICAgICAgICA1MDo2OTpmMworICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEQxOjA5OkQwOkU5OkQ3OkNFOjc5Ojc0OjU0OkY5OjNBOjMwOkIzOkY0OjZEOjJDOjAzOjAzOjFCOjY4CisgICAgICAgICAgICBYNTA5djMgQ2VydGlmaWNhdGUgUG9saWNpZXM6IAorICAgICAgICAgICAgICAgIFBvbGljeTogWDUwOXYzIEFueSBQb2xpY3kKKyAgICAgICAgICAgICAgICAgIENQUzogaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vZHBjLworICAgICAgICAgICAgICAgICAgVXNlciBOb3RpY2U6CisgICAgICAgICAgICAgICAgICAgIEV4cGxpY2l0IFRleHQ6IExpbWl0YWNpb25lcyBkZSBnYXJhbnTtYXMgZGUgZXN0ZSBjZXJ0aWZpY2FkbyBzZSBwdWVkZW4gZW5jb250cmFyIGVuIGxhIERQQy4KKworICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA1Yzo5NDpiNTpiODo0NTo5MTo0ZDo4ZTo2MToxZjowMzoyODowZjo1Mzo3YzplNjphNDo1OToKKyAgICAgICAgYTk6YjM6OGE6N2E6YzU6YjA6ZmY6MDg6N2M6MmM6YTM6NzE6MWM6MjE6MTM6Njc6YTE6OTU6CisgICAgICAgIDEyOjQwOjM1OjgzOjgzOjhmOjc0OmRiOjMzOjVjOmYwOjQ5Ojc2OjBhOjgxOjUyOmRkOjQ5OgorICAgICAgICBkNDo5YTozMjozMzplZjo5YjphNzpjYjo3NTplNTo3YTpjYjo5NzoxMjo5MDo1YzpiYTo3YjoKKyAgICAgICAgYzU6OWI6ZGY6YmI6Mzk6MjM6Yzg6ZmY6OTg6Y2U6MGE6NGQ6MjI6MDE6NDg6MDc6N2U6OGE6CisgICAgICAgIGMwOmQ1OjIwOjQyOjk0OjQ0OmVmOmJmOjc3OmEyOjg5OjY3OjQ4OjFiOjQwOjAzOjA1OmExOgorICAgICAgICA4OTplYzpjZjo2MjplMzozZDoyNTo3Njo2NjpiZjoyNjpiNzpiYjoyMjpiZTo2ZjpmZjozOToKKyAgICAgICAgNTc6NzQ6YmE6N2E6Yzk6MDE6OTU6YzE6OTU6NTE6ZTg6YWI6MmM6Zjg6YjE6ODY6MjA6ZTk6CisgICAgICAgIDNmOmNiOjM1OjViOmQyOjE3OmU5OjJhOmZlOjgzOjEzOjE3OjQwOmVlOjg4OjYyOjY1OjViOgorICAgICAgICBkNTozYjo2MDplOTo3YjozYzpiODpjOTpkNTo3ZjozNjowMjoyNTphYTo2ODpjMjozMToxNToKKyAgICAgICAgYjc6MzA6NjU6ZWI6N2Y6MWQ6NDg6Nzk6YjE6Y2Y6Mzk6ZTI6NDI6ODA6MTY6ZDM6ZjU6OTM6CisgICAgICAgIDIzOmZjOjRjOjk3OmM5OjVhOjM3OjZjOjdjOjIyOmQ4OjRhOmNkOmQyOjhlOjM2OjgzOjM5OgorICAgICAgICA5MTo5MDoxMDpjODpmMTpjOTozNTo3ZTozZjpiODpkMzo4MTpjNjoyMDo2NDoxYTpiNjo1MDoKKyAgICAgICAgYzI6MjE6YTQ6Nzg6ZGM6ZDA6MmY6M2I6NjQ6OTM6NzQ6ZjA6OTY6OTA6ZjE6ZWY6ZmI6MDk6CisgICAgICAgIDVhOjM0OjQwOjk2OmYwOjM2OjEyOmMxOmEzOjc0OjhjOjkzOjdlOjQxOmRlOjc3OjhiOmVjOgorICAgICAgICA4NjpkOTpkMjowZjozZjoyZDpkMTpjYzo0MDphMjo4OTo2Njo0ODoxZToyMDpiMzo5YzoyMzoKKyAgICAgICAgNTk6NzM6YTk6NDQ6NzM6YmM6MjQ6Nzk6OTA6NTY6Mzc6YjM6YzY6Mjk6N2U6YTM6MGY6ZjE6CisgICAgICAgIDI5OjM5OmVmOjdlOjVjOjI4OjMyOjcwOjM1OmFjOmRhOmI4OmM4Ojc1OjY2OmZjOjliOjRjOgorICAgICAgICAzOTo0Nzo4ZToxYjo2Zjo5Yjo0ZDowMjo1NDoyMjozMzplZjo2MTpiYTo5ZToyOTo4NDplZjoKKyAgICAgICAgNGU6NGI6MzM6NDc6NzY6OTc6NmE6Y2I6N2U6NWY6ZmQ6MTU6YTY6OWU6NDI6NDM6NWI6NjY6CisgICAgICAgIDVhOjhhOjg4OjBkOmY3OjE2OmI5OjNmOjUxOjY1OjJiOjY2OjZhOjhiOmQxOjM4OjUyOmEyOgorICAgICAgICBkNjo0NjoxMTpmYTpmYzo5YToxYzo3NDo5ZTo4Zjo5NzowYjowMjo0Zjo2NDpjNjpmNTo2ODoKKyAgICAgICAgZDM6NGI6MmQ6ZmY6YTQ6Mzc6MWU6OGI6M2Y6YmY6NDQ6YmU6NjE6NDY6YTE6ODQ6M2Q6MDg6CisgICAgICAgIDI3OjRjOjgxOjIwOjc3Ojg5OjA4OmVhOjY3OjQwOjVlOjZjOjA4OjUxOjVmOjM0OjVhOjhjOgorICAgICAgICA5Njo2ODpjZDpkNzpmNzo4OTpjMjoxYzpkMzozMjowMDphZjo1MjpjYjpkMzo2MDo1YjoyYToKKyAgICAgICAgM2E6NDc6N2U6NmI6MzA6MzM6YTE6NjI6Mjk6N2Y6NGE6Yjk6ZTE6MmQ6ZTc6MTQ6MjM6MGU6CisgICAgICAgIDBlOjE4OjQ3OmUxOjc5OmZjOjE1OjU1OmQwOmIxOmZjOjI1OjcxOjYzOjc1OjMzOjFjOjIzOgorICAgICAgICAyYjphZjo1YzpkOTplZDo0Nzo3Nzo2MDowZTozYjowZjoxZTpkMjpjMDpkYzo2NDowNTo4OToKKyAgICAgICAgZmM6Nzg6ZDY6NWM6MmM6MjY6NDM6YTkKK1NIQTEgRmluZ2VycHJpbnQ9Q0I6QTE6QzU6Rjg6QjA6RTM6NUU6Qjg6Qjk6NDU6MTI6RDM6Rjk6MzQ6QTI6RTk6MDY6MTA6RDM6MzYKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9jY2M1MmY0OS4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2NjYzUyZjQ5LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjE5M2Y2MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9jY2M1MmY0OS4wCkBAIC0wLDAgKzEsNTEgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJQi9qQ0NBWVdnQXdJQkFnSUlkSmNsaXNjL2VsUXdDZ1lJS29aSXpqMEVBd013UlRFTE1Ba0dBMVVFQmhNQworVlZNeEZEQVNCZ05WQkFvTUMwRm1abWx5YlZSeWRYTjBNU0F3SGdZRFZRUUREQmRCWm1acGNtMVVjblZ6ZENCUQorY21WdGFYVnRJRVZEUXpBZUZ3MHhNREF4TWpreE5ESXdNalJhRncwME1ERXlNekV4TkRJd01qUmFNRVV4Q3pBSgorQmdOVkJBWVRBbFZUTVJRd0VnWURWUVFLREF0QlptWnBjbTFVY25WemRERWdNQjRHQTFVRUF3d1hRV1ptYVhKdAorVkhKMWMzUWdVSEpsYldsMWJTQkZRME13ZGpBUUJnY3Foa2pPUFFJQkJnVXJnUVFBSWdOaUFBUU5NRjRiRlowRAorMEtGNU5iYzZQSko2eWhVY3pXTHpuQ1pjQnozbFZQcWoxc3dTNnZRVVgraU9HYXN2TGtqbXJCaERlS3pRTjhPOQorc3MwczVrZmlHdVpqdUQwdUwzakVUOXYwRDZSb1RGVnlhNVVkVGhoQ2xYak1OenlSNHB0bEt5bWpRakJBTUIwRworQTFVZERnUVdCQlNhcnlsNndCRTFOU1pSTUFERGF2NUExYTdXUERBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUE0RworQTFVZER3RUIvd1FFQXdJQkJqQUtCZ2dxaGtqT1BRUURBd05uQURCa0FqQVhDZk9IaUZCYXI4akFRcjlIWC9WcworYW9iZ3hDZDA1RGhUMXdWL0d6VGp4aSt6eWdrOE41M1g1N2hHOGYyaDRuRUNNRUpaaDBQVVVkKzYwd2t5V3M2SQorZmxjOW5GOUNhL1VITGJYd2dwUDVXVyt1WlBwWTVZc2U0Mk8rdFlITmJ3S01lUT09CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICA3NDo5NzoyNTo4YTpjNzozZjo3YTo1NAorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBlY2RzYS13aXRoLVNIQTM4NAorICAgICAgICBJc3N1ZXI6IEM9VVMsIE89QWZmaXJtVHJ1c3QsIENOPUFmZmlybVRydXN0IFByZW1pdW0gRUNDCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBKYW4gMjkgMTQ6MjA6MjQgMjAxMCBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IERlYyAzMSAxNDoyMDoyNCAyMDQwIEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPUFmZmlybVRydXN0LCBDTj1BZmZpcm1UcnVzdCBQcmVtaXVtIEVDQworICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiBpZC1lY1B1YmxpY0tleQorICAgICAgICAgICAgRUMgUHVibGljIEtleToKKyAgICAgICAgICAgICAgICBwdWI6IAorICAgICAgICAgICAgICAgICAgICAwNDowZDozMDo1ZToxYjoxNTo5ZDowMzpkMDphMTo3OTozNTpiNzozYTozYzoKKyAgICAgICAgICAgICAgICAgICAgOTI6N2E6Y2E6MTU6MWM6Y2Q6NjI6ZjM6OWM6MjY6NWM6MDc6M2Q6ZTU6NTQ6CisgICAgICAgICAgICAgICAgICAgIGZhOmEzOmQ2OmNjOjEyOmVhOmY0OjE0OjVmOmU4OjhlOjE5OmFiOjJmOjJlOgorICAgICAgICAgICAgICAgICAgICA0ODplNjphYzoxODo0Mzo3ODphYzpkMDozNzpjMzpiZDpiMjpjZDoyYzplNjoKKyAgICAgICAgICAgICAgICAgICAgNDc6ZTI6MWE6ZTY6NjM6Yjg6M2Q6MmU6MmY6Nzg6YzQ6NGY6ZGI6ZjQ6MGY6CisgICAgICAgICAgICAgICAgICAgIGE0OjY4OjRjOjU1OjcyOjZiOjk1OjFkOjRlOjE4OjQyOjk1Ojc4OmNjOjM3OgorICAgICAgICAgICAgICAgICAgICAzYzo5MTplMjo5Yjo2NToyYjoyOQorICAgICAgICAgICAgICAgIEFTTjEgT0lEOiBzZWNwMzg0cjEKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgOUE6QUY6Mjk6N0E6QzA6MTE6MzU6MzU6MjY6NTE6MzA6MDA6QzM6NkE6RkU6NDA6RDU6QUU6RDY6M0MKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogZWNkc2Etd2l0aC1TSEEzODQKKyAgICAgICAgMzA6NjQ6MDI6MzA6MTc6MDk6ZjM6ODc6ODg6NTA6NWE6YWY6Yzg6YzA6NDI6YmY6NDc6NWY6CisgICAgICAgIGY1OjZjOjZhOjg2OmUwOmM0OjI3Ojc0OmU0OjM4OjUzOmQ3OjA1OjdmOjFiOjM0OmUzOmM2OgorICAgICAgICAyZjpiMzpjYTowOTozYzozNzo5ZDpkNzplNzpiODo0NjpmMTpmZDphMTplMjo3MTowMjozMDoKKyAgICAgICAgNDI6NTk6ODc6NDM6ZDQ6NTE6ZGY6YmE6ZDM6MDk6MzI6NWE6Y2U6ODg6N2U6NTc6M2Q6OWM6CisgICAgICAgIDVmOjQyOjZiOmY1OjA3OjJkOmI1OmYwOjgyOjkzOmY5OjU5OjZmOmFlOjY0OmZhOjU4OmU1OgorICAgICAgICA4YjoxZTplMzo2MzpiZTpiNTo4MTpjZDo2ZjowMjo4Yzo3OQorU0hBMSBGaW5nZXJwcmludD1CODoyMzo2QjowMDoyRjoxRDoxNjo4Njo1MzowMTo1NTo2QzoxMTpBNDozNzpDQTpFQjpGRjpDMzpCQgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2NkYWViYjcyLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvY2RhZWJiNzIuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMzhiZGVjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2NkYWViYjcyLjAKQEAgLTAsMCArMSw4MyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEdWpDQ0FxS2dBd0lCQWdJRUFKaVdpakFOQmdrcWhraUc5dzBCQVFVRkFEQlZNUXN3Q1FZRFZRUUdFd0pPCitUREVlTUJ3R0ExVUVDaE1WVTNSaFlYUWdaR1Z5SUU1bFpHVnliR0Z1WkdWdU1TWXdKQVlEVlFRREV4MVRkR0ZoCitkQ0JrWlhJZ1RtVmtaWEpzWVc1a1pXNGdVbTl2ZENCRFFUQWVGdzB3TWpFeU1UY3dPVEl6TkRsYUZ3MHhOVEV5CitNVFl3T1RFMU16aGFNRlV4Q3pBSkJnTlZCQVlUQWs1TU1SNHdIQVlEVlFRS0V4VlRkR0ZoZENCa1pYSWdUbVZrCitaWEpzWVc1a1pXNHhKakFrQmdOVkJBTVRIVk4wWVdGMElHUmxjaUJPWldSbGNteGhibVJsYmlCU2IyOTBJRU5CCitNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQW1OSzFVUkY2Z2FZVW1IRnR2c3puCitFeHZXSnc1NnMyb1lITFpoV3RWaENiL2VrQlBIWis3ZDg5ckZEQktlTlZVK0xDZUlRR3YzM04waVlmWEN4dzcxCis5dFYyVTAyUGpMd1lkamVGbmVqS1NjZlNUNWdUQ2FJK0lvaWNmOWJ5RUdXMDdsOFkxUmZqK01YOTRwMmk3MU1PCitoWGVpRCtFd1IrNEE1ek45UkdjYUMxSG9pNkNlVUpob05GSWZMbTBCOG1CRjhqSHJxVEZvS2J0NlFaN0dHWCtVCit0RkU1QTMreTNxY3ltN1JIam0rMFNxN2xyN0hjc0J0aHZKbHkzdVNKdDNvbVhkb3pTVnRTbkE3MWlxM0R1RDNvCitCbXJDMVNvTGJIdUV2VllGeTRabGt1eEVLN0NPdWR4d0MwYmFyYnhqaURuNjIycitJL3E4NUVqMFp5dHFFUkFoCitTUUlEQVFBQm80R1JNSUdPTUF3R0ExVWRFd1FGTUFNQkFmOHdUd1lEVlIwZ0JFZ3dSakJFQmdSVkhTQUFNRHd3CitPZ1lJS3dZQkJRVUhBZ0VXTG1oMGRIQTZMeTkzZDNjdWNHdHBiM1psY21obGFXUXVibXd2Y0c5c2FXTnBaWE12CitjbTl2ZEMxd2IyeHBZM2t3RGdZRFZSMFBBUUgvQkFRREFnRUdNQjBHQTFVZERnUVdCQlNvZmV1OFk2UjBFM1FBCis3SmJnMHpUQkxMOXMrREFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBQllTSFZYUTJZY0c3MGRUR0ZhZ1R0SitrCisvcnZ1RmJRdkJnd3A4cWlTcEdFTi9LdGNDRnRSRXl0TndpcGh5UGdKV1B3dEFySTVmWmxtZ2I5dVhKVkZJR3ptCitlYWZSMkJ3cC9NSWdKMUhJOFh4ZE5HZHBoUkV3eGdEUzEvUFRmTGJ3TVZjb0VvSno2VE12cGxXMEM1R1VSNXo2Cit1M3BDTXVpdWZpM0l2S3dVdjlrUDJWdjh3Zmw2bGVGOWZwYjhjYkRDVE1qZlJUVEp6ZzN5bkdRSTBEdkRLY1d5Cis3WkFFd2JFcGtjVXdiOEdwY2pQTS9sMFdGeXdSYWVkKy9zV0RDTis4M0NJNkxpQnBJemxXWUdlUWl5NTJPZnNSCitpSmYyZkwxTHVDQVdad1dONGp2QmNqK1VsVGZIWGJtZTJKT2hGNC8vREdZVndTUjhNbndESFR1aFdFVXlrdz09CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDEwMDAwMDEwICgweDk4OTY4YSkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1OTCwgTz1TdGFhdCBkZXIgTmVkZXJsYW5kZW4sIENOPVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENBCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBEZWMgMTcgMDk6MjM6NDkgMjAwMiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IERlYyAxNiAwOToxNTozOCAyMDE1IEdNVAorICAgICAgICBTdWJqZWN0OiBDPU5MLCBPPVN0YWF0IGRlciBOZWRlcmxhbmRlbiwgQ049U3RhYXQgZGVyIE5lZGVybGFuZGVuIFJvb3QgQ0EKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOjk4OmQyOmI1OjUxOjExOjdhOjgxOmE2OjE0Ojk4OjcxOjZkOmJlOmNjOgorICAgICAgICAgICAgICAgICAgICBlNzoxMzoxYjpkNjoyNzowZTo3YTpiMzo2YToxODoxYzpiNjo2MTo1YTpkNToKKyAgICAgICAgICAgICAgICAgICAgNjE6MDk6YmY6ZGU6OTA6MTM6Yzc6Njc6ZWU6ZGQ6ZjM6ZGE6YzU6MGM6MTI6CisgICAgICAgICAgICAgICAgICAgIDllOjM1OjU1OjNlOjJjOjI3Ojg4OjQwOjZiOmY3OmRjOmRkOjIyOjYxOmY1OgorICAgICAgICAgICAgICAgICAgICBjMjpjNzowZTpmNTpmNjpkNTo3Njo1Mzo0ZDo4Zjo4YzpiYzoxODo3NjozNzoKKyAgICAgICAgICAgICAgICAgICAgODU6OWQ6ZTg6Y2E6NDk6Yzc6ZDI6NGY6OTg6MTM6MDk6YTI6M2U6MjI6ODg6CisgICAgICAgICAgICAgICAgICAgIDljOjdmOmQ2OmYyOjEwOjY1OmI0OmVlOjVmOjE4OmQ1OjE3OmUzOmY4OmM1OgorICAgICAgICAgICAgICAgICAgICBmZDplMjo5ZDphMjplZjo1MzowZTo4NTo3NzphMjowZjplMTozMDo0NzplZToKKyAgICAgICAgICAgICAgICAgICAgMDA6ZTc6MzM6N2Q6NDQ6Njc6MWE6MGI6NTE6ZTg6OGI6YTA6OWU6NTA6OTg6CisgICAgICAgICAgICAgICAgICAgIDY4OjM0OjUyOjFmOjJlOjZkOjAxOmYyOjYwOjQ1OmYyOjMxOmViOmE5OjMxOgorICAgICAgICAgICAgICAgICAgICA2ODoyOTpiYjo3YTo0MTo5ZTpjNjoxOTo3Zjo5NDpiNDo1MTozOTowMzo3ZjoKKyAgICAgICAgICAgICAgICAgICAgYjI6ZGU6YTc6MzI6OWI6YjQ6NDc6OGU6NmY6YjQ6NGE6YWU6ZTU6YWY6YjE6CisgICAgICAgICAgICAgICAgICAgIGRjOmIwOjFiOjYxOmJjOjk5OjcyOmRlOmU0Ojg5OmI3OjdhOjI2OjVkOmRhOgorICAgICAgICAgICAgICAgICAgICAzMzo0OTo1Yjo1Mjo5YzowZTpmNTo4YTphZDpjMzpiODozZDplODowNjo2YToKKyAgICAgICAgICAgICAgICAgICAgYzI6ZDU6MmE6MGI6NmM6N2I6ODQ6YmQ6NTY6MDU6Y2I6ODY6NjU6OTI6ZWM6CisgICAgICAgICAgICAgICAgICAgIDQ0OjJiOmIwOjhlOmI5OmRjOjcwOjBiOjQ2OmRhOmFkOmJjOjYzOjg4OjM5OgorICAgICAgICAgICAgICAgICAgICBmYTpkYjo2YTpmZToyMzpmYTpiYzplNDo0ODpmNDo2NzoyYjo2YToxMToxMDoKKyAgICAgICAgICAgICAgICAgICAgMjE6NDkKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiAKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgQ2VydGlmaWNhdGUgUG9saWNpZXM6IAorICAgICAgICAgICAgICAgIFBvbGljeTogWDUwOXYzIEFueSBQb2xpY3kKKyAgICAgICAgICAgICAgICAgIENQUzogaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeQorCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgQTg6N0Q6RUI6QkM6NjM6QTQ6NzQ6MTM6NzQ6MDA6RUM6OTY6RTA6RDM6MzQ6QzE6MkM6QkY6NkM6RjgKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMDU6ODQ6ODc6NTU6NzQ6MzY6NjE6YzE6YmI6ZDE6ZDQ6YzY6MTU6YTg6MTM6YjQ6OWY6YTQ6CisgICAgICAgIGZlOmJiOmVlOjE1OmI0OjJmOjA2OjBjOjI5OmYyOmE4OjkyOmE0OjYxOjBkOmZjOmFiOjVjOgorICAgICAgICAwODo1Yjo1MToxMzoyYjo0ZDpjMjoyYTo2MTpjODpmODowOTo1ODpmYzoyZDowMjpiMjozOToKKyAgICAgICAgN2Q6OTk6NjY6ODE6YmY6NmU6NWM6OTU6NDU6MjA6NmM6ZTY6Nzk6YTc6ZDE6ZDg6MWM6Mjk6CisgICAgICAgIGZjOmMyOjIwOjI3OjUxOmM4OmYxOjdjOjVkOjM0OjY3OjY5Ojg1OjExOjMwOmM2OjAwOmQyOgorICAgICAgICBkNzpmMzpkMzo3YzpiNjpmMDozMTo1NzoyODoxMjo4Mjo3MzplOTozMzoyZjphNjo1NTpiNDoKKyAgICAgICAgMGI6OTE6OTQ6NDc6OWM6ZmE6YmI6N2E6NDI6MzI6ZTg6YWU6N2U6MmQ6Yzg6YmM6YWM6MTQ6CisgICAgICAgIGJmOmQ5OjBmOmQ5OjViOmZjOmMxOmY5OjdhOjk1OmUxOjdkOjdlOjk2OmZjOjcxOmIwOmMyOgorICAgICAgICA0YzpjODpkZjo0NTozNDpjOTpjZTowZDpmMjo5Yzo2NDowODpkMDozYjpjMzoyOTpjNTpiMjoKKyAgICAgICAgZWQ6OTA6MDQ6YzE6YjE6Mjk6OTE6YzU6MzA6NmY6YzE6YTk6NzI6MzM6Y2M6ZmU6NWQ6MTY6CisgICAgICAgIDE3OjJjOjExOjY5OmU3OjdlOmZlOmM1OjgzOjA4OmRmOmJjOmRjOjIyOjNhOjJlOjIwOjY5OgorICAgICAgICAyMzozOTo1Njo2MDo2Nzo5MDo4YjoyZTo3NjozOTpmYjoxMTo4ODo5NzpmNjo3YzpiZDo0YjoKKyAgICAgICAgYjg6MjA6MTY6Njc6MDU6OGQ6ZTI6M2I6YzE6NzI6M2Y6OTQ6OTU6Mzc6Yzc6NWQ6Yjk6OWU6CisgICAgICAgIGQ4OjkzOmExOjE3OjhmOmZmOjBjOjY2OjE1OmMxOjI0OjdjOjMyOjdjOjAzOjFkOjNiOmExOgorICAgICAgICA1ODo0NTozMjo5MworU0hBMSBGaW5nZXJwcmludD0xMDoxRDpGQTozRjpENTowQjpDQjpCQjo5QjpCNTo2MDowQzoxOTo1NTpBNDoxQTpGNDo3MzozQTowNApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2NmNzAxZWViLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvY2Y3MDFlZWIuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMmM4OWU5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2NmNzAxZWViLjAKQEAgLTAsMCArMSw4NyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEdURDQ0FxQ2dBd0lCQWdJUURQQ09YQWdXcGExQ2YvRHJKeGhaMERBTkJna3Foa2lHOXcwQkFRVUZBREJJCitNUXN3Q1FZRFZRUUdFd0pWVXpFZ01CNEdBMVVFQ2hNWFUyVmpkWEpsVkhKMWMzUWdRMjl5Y0c5eVlYUnBiMjR4CitGekFWQmdOVkJBTVREbE5sWTNWeVpWUnlkWE4wSUVOQk1CNFhEVEEyTVRFd056RTVNekV4T0ZvWERUSTVNVEl6CitNVEU1TkRBMU5Wb3dTREVMTUFrR0ExVUVCaE1DVlZNeElEQWVCZ05WQkFvVEYxTmxZM1Z5WlZSeWRYTjBJRU52CitjbkJ2Y21GMGFXOXVNUmN3RlFZRFZRUURFdzVUWldOMWNtVlVjblZ6ZENCRFFUQ0NBU0l3RFFZSktvWklodmNOCitBUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBS3VrZ2VXVnpmWDJGSTdDVDhyVTRuaVZXSnhCNFEyWlFDUVhPWkV6CitadW0rNFlPdllseUowZndrVzJHejRCRVJRUndkYnZDNHUvamVwNEc2cGtqR254Mjl2bzZwUVQ2NGxPMHBHdFNPCiswZ01kQSs5dERXY2NWOWNHcmNySTlmNE9yMllsU0FTV0MxMmp1aGJEQ0UvUlJ2Z1VYUExJWGdHWmJmMkl6SWFvCit3Vzh4UW14U1Btakw4eGswMzd1SEdGYUFKc1RRM01CdjM5Nmd3cEVXb0dRUlMwUzhIdmJuK21QZVpxeDJwSEdqCis3RGFVYUhwM3BMSG5EaStCZXVLMWNvYnZvbXVMOEEvYjAxay91bks4UkNTYzQzT3o5NjlYTDBJbW5hbDB1Z0JTCis4a3ZOVTN4SEN6YUZEbWFwQ0pjV05GZkJadmVBNCsxd1ZNZVQ0QzRvRlZtSHVyc0NBd0VBQWFPQm5UQ0JtakFUCitCZ2tyQmdFRUFZSTNGQUlFQmg0RUFFTUFRVEFMQmdOVkhROEVCQU1DQVlZd0R3WURWUjBUQVFIL0JBVXdBd0VCCisvekFkQmdOVkhRNEVGZ1FVUWpLMkZ2b0UvZjVkUzNyRC9mZE1RQjFhUTY4d05BWURWUjBmQkMwd0t6QXBvQ2VnCitKWVlqYUhSMGNEb3ZMMk55YkM1elpXTjFjbVYwY25WemRDNWpiMjB2VTFSRFFTNWpjbXd3RUFZSkt3WUJCQUdDCitOeFVCQkFNQ0FRQXdEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBRER0VDByaFdEcFNjbHUxcHFObEdLYTdVVHQzCis2WjNxMDU5YzRFVmxldzNLVytKd1VMS1VCUlN1U2NlTlFRY1NjNVIrRENNaC9id1FmMkFRV25MMW1BNnM3TGwvCiszWHB2WGRNYzlQK0lCV2xDcVFWeHlMZXNKdWd1dEl4cS8zSGN1TEhmbWJ4OElWUXI1RmlpdTFjcHJwNnBveGttCitENWt1Q0xEdi9XblBtUm9KamVPbm55dkpOalI3SkxONFRKVVhwQVltSHJaa1VqWmZZR2Zabk1VRmRBdm5aeVBTCitDUHlJNmE2TGYrRXc5RGQrL2NZeTJpMmVSREF3Yk80SDN0STAvTkwvUVBaTDlHWkdCbFNtOGpJS1l5WXdhNXZSCiszSXRIdXVHNTFXTFFvcUQwWndWNEtXTWFid1RXK01aTW81cXhON1NONVNoTEhaNHN3cmhvdk8wQzdqRT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDBjOmYwOjhlOjVjOjA4OjE2OmE1OmFkOjQyOjdmOmYwOmViOjI3OjE4OjU5OmQwCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9VVMsIE89U2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24sIENOPVNlY3VyZVRydXN0IENBCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBOb3YgIDcgMTk6MzE6MTggMjAwNiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IERlYyAzMSAxOTo0MDo1NSAyMDI5IEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPVNlY3VyZVRydXN0IENvcnBvcmF0aW9uLCBDTj1TZWN1cmVUcnVzdCBDQQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YWI6YTQ6ODE6ZTU6OTU6Y2Q6ZjU6ZjY6MTQ6OGU6YzI6NGY6Y2E6ZDQ6CisgICAgICAgICAgICAgICAgICAgIGUyOjc4Ojk1OjU4OjljOjQxOmUxOjBkOjk5OjQwOjI0OjE3OjM5OjkxOjMzOgorICAgICAgICAgICAgICAgICAgICA2NjplOTpiZTplMTo4MzphZjo2Mjo1Yzo4OTpkMTpmYzoyNDo1Yjo2MTpiMzoKKyAgICAgICAgICAgICAgICAgICAgZTA6MTE6MTE6NDE6MWM6MWQ6NmU6ZjA6Yjg6YmI6Zjg6ZGU6YTc6ODE6YmE6CisgICAgICAgICAgICAgICAgICAgIGE2OjQ4OmM2OjlmOjFkOmJkOmJlOjhlOmE5OjQxOjNlOmI4Ojk0OmVkOjI5OgorICAgICAgICAgICAgICAgICAgICAxYTpkNDo4ZTpkMjowMzoxZDowMzplZjo2ZDowZDo2NzoxYzo1NzpkNzowNjoKKyAgICAgICAgICAgICAgICAgICAgYWQ6Y2E6Yzg6ZjU6ZmU6MGU6YWY6NjY6MjU6NDg6MDQ6OTY6MGI6NWQ6YTM6CisgICAgICAgICAgICAgICAgICAgIGJhOjE2OmMzOjA4OjRmOmQxOjQ2OmY4OjE0OjVjOmYyOmM4OjVlOjAxOjk5OgorICAgICAgICAgICAgICAgICAgICA2ZDpmZDo4ODpjYzo4NjphODpjMTo2ZjozMTo0Mjo2Yzo1MjozZTo2ODpjYjoKKyAgICAgICAgICAgICAgICAgICAgZjM6MTk6MzQ6ZGY6YmI6ODc6MTg6NTY6ODA6MjY6YzQ6ZDA6ZGM6YzA6NmY6CisgICAgICAgICAgICAgICAgICAgIGRmOmRlOmEwOmMyOjkxOjE2OmEwOjY0OjExOjRiOjQ0OmJjOjFlOmY2OmU3OgorICAgICAgICAgICAgICAgICAgICBmYTo2MzpkZTo2NjphYzo3NjphNDo3MTphMzplYzozNjo5NDo2ODo3YTo3NzoKKyAgICAgICAgICAgICAgICAgICAgYTQ6YjE6ZTc6MGU6MmY6ODE6N2E6ZTI6YjU6NzI6ODY6ZWY6YTI6NmI6OGI6CisgICAgICAgICAgICAgICAgICAgIGYwOjBmOmRiOmQzOjU5OjNmOmJhOjcyOmJjOjQ0OjI0OjljOmUzOjczOmIzOgorICAgICAgICAgICAgICAgICAgICBmNzphZjo1NzoyZjo0MjoyNjo5ZDphOTo3NDpiYTowMDo1MjpmMjo0YjpjZDoKKyAgICAgICAgICAgICAgICAgICAgNTM6N2M6NDc6MGI6MzY6ODU6MGU6NjY6YTk6MDg6OTc6MTY6MzQ6NTc6YzE6CisgICAgICAgICAgICAgICAgICAgIDY2OmY3OjgwOmUzOmVkOjcwOjU0OmM3OjkzOmUwOjJlOjI4OjE1OjU5Ojg3OgorICAgICAgICAgICAgICAgICAgICBiYTpiYgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICAxLjMuNi4xLjQuMS4zMTEuMjAuMjogCisgICAgICAgICAgICAgICAgLi4uQy5BCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiAKKyAgICAgICAgICAgICAgICBEaWdpdGFsIFNpZ25hdHVyZSwgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgNDI6MzI6QjY6MTY6RkE6MDQ6RkQ6RkU6NUQ6NEI6N0E6QzM6RkQ6Rjc6NEM6NDA6MUQ6NUE6NDM6QUYKKyAgICAgICAgICAgIFg1MDl2MyBDUkwgRGlzdHJpYnV0aW9uIFBvaW50czogCisgICAgICAgICAgICAgICAgVVJJOmh0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NUQ0EuY3JsCisKKyAgICAgICAgICAgIDEuMy42LjEuNC4xLjMxMS4yMS4xOiAKKyAgICAgICAgICAgICAgICAuLi4KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMzA6ZWQ6NGY6NGE6ZTE6NTg6M2E6NTI6NzI6NWI6YjU6YTY6YTM6NjU6MTg6YTY6YmI6NTE6CisgICAgICAgIDNiOjc3OmU5OjlkOmVhOmQzOjlmOjVjOmUwOjQ1OjY1OjdiOjBkOmNhOjViOmUyOjcwOjUwOgorICAgICAgICBiMjo5NDowNToxNDphZTo0OTpjNzo4ZDo0MTowNzoxMjo3Mzo5NDo3ZTowYzoyMzoyMTpmZDoKKyAgICAgICAgYmM6MTA6N2Y6NjA6MTA6NWE6NzI6ZjU6OTg6MGU6YWM6ZWM6Yjk6N2Y6ZGQ6N2E6NmY6NWQ6CisgICAgICAgIGQzOjFjOmY0OmZmOjg4OjA1OjY5OjQyOmE5OjA1OjcxOmM4OmI3OmFjOjI2OmU4OjJlOmI0OgorICAgICAgICA4Yzo2YTpmZjo3MTpkYzpiODpiMTpkZjo5OTpiYzo3YzoyMTo1NDoyYjplNDo1ODphMjpiYjoKKyAgICAgICAgNTc6Mjk6YWU6OWU6YTk6YTM6MTk6MjY6MGY6OTk6MmU6MDg6YjA6ZWY6ZmQ6Njk6Y2Y6OTk6CisgICAgICAgIDFhOjA5OjhkOmUzOmE3OjlmOjJiOmM5OjM2OjM0OjdiOjI0OmIzOjc4OjRjOjk1OjE3OmE0OgorICAgICAgICAwNjoyNjoxZTpiNjo2NDo1MjozNjo1Zjo2MDo2NzpkOTo5YzpjNTowNTo3NDowYjplNzo2NzoKKyAgICAgICAgMjM6ZDI6MDg6ZmM6ODg6ZTk6YWU6OGI6N2Y6ZTE6MzA6ZjQ6Mzc6N2U6ZmQ6YzY6MzI6ZGE6CisgICAgICAgIDJkOjllOjQ0OjMwOjMwOjZjOmVlOjA3OmRlOmQyOjM0OmZjOmQyOmZmOjQwOmY2OjRiOmY0OgorICAgICAgICA2Njo0NjowNjo1NDphNjpmMjozMjowYTo2MzoyNjozMDo2Yjo5YjpkMTpkYzo4Yjo0NzpiYToKKyAgICAgICAgZTE6Yjk6ZDU6NjI6ZDA6YTI6YTA6ZjQ6Njc6MDU6Nzg6Mjk6NjM6MWE6NmY6MDQ6ZDY6Zjg6CisgICAgICAgIGM2OjRjOmEzOjlhOmIxOjM3OmI0OjhkOmU1OjI4OjRiOjFkOjllOjJjOmMyOmI4OjY4OmJjOgorICAgICAgICBlZDowMjplZTozMQorU0hBMSBGaW5nZXJwcmludD04Nzo4MjpDNjpDMzowNDozNTozQjpDRjpEMjo5Njo5MjpEMjo1OTozRTo3RDo0NDpEOTozNDpGRjoxMQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2QxNmE1ODY1LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZDE2YTU4NjUuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYzMwNGE1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2QxNmE1ODY1LjAKQEAgLTAsMCArMSwxMzAgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJR0ZEQ0NBL3lnQXdJQkFnSUlVK3c3N3Z1eVNGOHdEUVlKS29aSWh2Y05BUUVGQlFBd1VURUxNQWtHQTFVRQorQmhNQ1JWTXhRakJBQmdOVkJBTU1PVUYxZEc5eWFXUmhaQ0JrWlNCRFpYSjBhV1pwWTJGamFXOXVJRVpwY20xaAorY0hKdlptVnphVzl1WVd3Z1EwbEdJRUUyTWpZek5EQTJPREFlRncwd09UQTFNakF3T0RNNE1UVmFGdzB6TURFeQorTXpFd09ETTRNVFZhTUZFeEN6QUpCZ05WQkFZVEFrVlRNVUl3UUFZRFZRUURERGxCZFhSdmNtbGtZV1FnWkdVZworUTJWeWRHbG1hV05oWTJsdmJpQkdhWEp0WVhCeWIyWmxjMmx2Ym1Gc0lFTkpSaUJCTmpJMk16UXdOamd3Z2dJaQorTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFES2xtdU82dmo3OGFJMTRIOU0ydUREVXRkOQordGhESUFsNnpReXJFVDJxeXloeGRLSnA0RVJwcFdWZXZ0U0JDNUlzUDV0OWJwZ09TTC9VUjVHTFhNbkU0MlFRTQorY2FzOVVYNFBCOTlqQlZ6cHY1UnZ3U21Dd0xUYVViREJQTHV0TjBwY3l2RkxOZzRrcTcvRGhIZjlxRkQwc2VmRworTDlJdFdZMTZDazZXYVZJQ3FqYVk3UHo2RklNTU54L0pramQvMTRFdDVjUzU0RDQwL21mMFBtYlIwL1JBejE1aQorTkE5d0JqNGdHRnJPOTNJYkpXeVRkQlNUbzNPeERxcUhFQ05aWHlBRkdVZnRhSTZTRXNwZC9OWXJzcEk4SU0vaAorWDY4Z3ZxQjJmM2JsN0JxR1lUTSs1M3UwUDZBUGpxSzVhbSs1aHladlFXeUlwbEQ5YW1NTDlaTVdHeG1Qc3UyYgorbThtUTlRRU0zeGs5RHo0NEk4a3Zqd3pSQXY0YlZkWk8wSTA4cjArazgvNnZLdE1GblhrSW9jdFhNYlNjeUpDeQorWi9RWUZwTTYvRWZZMFhpV01SKzZLd3hmWFptdFk0bGFKQ0IyMk4vOXEwNm1JcXFkWHVZbmluMW9LYVBuaXJqYQorRWJzWExabWRFeVJHOThYaTJKK09mOGVQZEcxYXN1aHk5YXp1SkJDdEx4VGEveTJhUm5GSHZrTGZ1d0hiOUgvVAorS0k4eFdWdlR5UUttdEZMS2JwZjdROFVJSm0rSzlMdjlueWlxRGRWRjh4TTZIZGpBZUk5Qlp6d2VsR1N1ZXd2RgorNk5rQmlEa2FsNFprUWRVN2h3eHUrZy9HdlVnVXZ6bE4xSjVCdG8rV0hXT1drOW1WQm5neGFKNDNCanVBaVVWaAorT1NQSEcwU2pGZVVjK0pJd3V3SURBUUFCbzRIdk1JSHNNQklHQTFVZEV3RUIvd1FJTUFZQkFmOENBUUV3RGdZRAorVlIwUEFRSC9CQVFEQWdFR01CMEdBMVVkRGdRV0JCUmx6ZXVyTlI0QVBuN1ZkTUFjdEhOSERocGtMekNCcGdZRAorVlIwZ0JJR2VNSUdiTUlHWUJnUlZIU0FBTUlHUE1DOEdDQ3NHQVFVRkJ3SUJGaU5vZEhSd09pOHZkM2QzTG1acAorY20xaGNISnZabVZ6YVc5dVlXd3VZMjl0TDJOd2N6QmNCZ2dyQmdFRkJRY0NBakJRSGs0QVVBQmhBSE1BWlFCdgorQUNBQVpBQmxBQ0FBYkFCaEFDQUFRZ0J2QUc0QVlRQnVBRzhBZGdCaEFDQUFOQUEzQUNBQVFnQmhBSElBWXdCbAorQUd3QWJ3QnVBR0VBSUFBd0FEZ0FNQUF4QURjd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dJQkFCZDlvUG0wM2NYRgorNjYxTEpMV2hBcXZkcFloS3NnOVZTeXRYakR2bE1kMyt4REx4NTF0a2xqWXlHT3lsTW5mWDQwUzJ3QkVxZ0xrOQorYW01OG05T3QvTVBXbytaa0tYelI0VGdlZ2l2L0oyV3YreFlWeEM1eGhPVzEvL3FrUjcxa01ydjJKWVNpSjBMMQorSUxEQ0V4QVJ6UkFWdWtLUUt0SkU0WlltNnpGSUV2MHEyc2tHejNRZXFVdlZoeWo1ZVRTU1BpNUU2UGFQVDQ4MQorUHlXek9keGpLcEJySUYvRVVoSk9seXdxckoyWDNranlvMmJid3RLRGxhWm1wNTRsRCtrTE01RmxDbHJEMlZRUworM2EvRFRnNGZKbDROM0xPTjdOV0JjTjdTVHlRRjgyeE85VXhKWm8zUi85SUxKVUZJL2xHRXhrS3ZnQVRQMEg1aworU2VUeTM2THNzVXpBS2gzbnRMRmxvc1M4OFpqMHFuQUhZN1M0Mmp0TStrQWlNRnNScHZBRkRzWUNBMGlyaHB1RgorM2R2ZDZxSjJnSE45OVp3RXhFV041N2tjaTU3cTEzWFJjckhlZFVUblFuM2lWMnQ5M0ptOFBZTW82b0NUamNWTQorWmNGd2diZzQvRU14c3ZZRE5FZXlyUHNpQnNzZTNSZEhIRjltdWRNYW90b1JzYVM4SThua3ZvZi91WlMyK0YwZworU3RSZjU3MW9lMlh5RlI3U09xa3Q2ZGhySkt5WFdFUkhyVmtZOFNGbGNON09OR0NvUVBIelBLVERLQ09NL2ljegorUTBDZ0Z6enI2anV3Y3FhanVVcExYaFpJOUxLOHlJeVN4WjJmckhJMnZEU0FOR3VwaTVMQXVCZnQ3SFpUOVNRQgorakxNaTZFdDhWY2FkK3FNVXUyV0ZibTVQRW40S1BKMlYKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDUzOmVjOjNiOmVlOmZiOmIyOjQ4OjVmCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9RVMsIENOPUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2OAorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTWF5IDIwIDA4OjM4OjE1IDIwMDkgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBEZWMgMzEgMDg6Mzg6MTUgMjAzMCBHTVQKKyAgICAgICAgU3ViamVjdDogQz1FUywgQ049QXV0b3JpZGFkIGRlIENlcnRpZmljYWNpb24gRmlybWFwcm9mZXNpb25hbCBDSUYgQTYyNjM0MDY4CisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoNDA5NiBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoNDA5NiBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpjYTo5Njo2Yjo4ZTplYTpmODpmYjpmMTphMjozNTplMDo3Zjo0YzpkYToKKyAgICAgICAgICAgICAgICAgICAgZTA6YzM6NTI6ZDc6N2Q6YjY6MTA6Yzg6MDI6NWU6YjM6NDM6MmE6YzQ6NGY6CisgICAgICAgICAgICAgICAgICAgIDZhOmIyOmNhOjFjOjVkOjI4OjlhOjc4OjExOjFhOjY5OjU5OjU3OmFmOmI1OgorICAgICAgICAgICAgICAgICAgICAyMDo0MjplNDo4YjowZjplNjpkZjo1YjphNjowMzo5MjoyZjpmNToxMTplNDoKKyAgICAgICAgICAgICAgICAgICAgNjI6ZDc6MzI6NzE6Mzg6ZDk6MDQ6MGM6NzE6YWI6M2Q6NTE6N2U6MGY6MDc6CisgICAgICAgICAgICAgICAgICAgIGRmOjYzOjA1OjVjOmU5OmJmOjk0OjZmOmMxOjI5OjgyOmMwOmI0OmRhOjUxOgorICAgICAgICAgICAgICAgICAgICBiMDpjMTozYzpiYjphZDozNzo0YTo1YzpjYTpmMTo0YjozNjowZToyNDphYjoKKyAgICAgICAgICAgICAgICAgICAgYmY6YzM6ODQ6Nzc6ZmQ6YTg6NTA6ZjQ6YjE6ZTc6YzY6MmY6ZDI6MmQ6NTk6CisgICAgICAgICAgICAgICAgICAgIDhkOjdhOjBhOjRlOjk2OjY5OjUyOjAyOmFhOjM2Ojk4OmVjOmZjOmZhOjE0OgorICAgICAgICAgICAgICAgICAgICA4MzowYzozNzoxZjpjOTo5MjozNzo3ZjpkNzo4MToyZDplNTpjNDpiOTplMDoKKyAgICAgICAgICAgICAgICAgICAgM2U6MzQ6ZmU6Njc6ZjQ6M2U6NjY6ZDE6ZDM6ZjQ6NDA6Y2Y6NWU6NjI6MzQ6CisgICAgICAgICAgICAgICAgICAgIDBmOjcwOjA2OjNlOjIwOjE4OjVhOmNlOmY3OjcyOjFiOjI1OjZjOjkzOjc0OgorICAgICAgICAgICAgICAgICAgICAxNDo5MzphMzo3MzpiMTowZTphYTo4NzoxMDoyMzo1OTo1ZjoyMDowNToxOToKKyAgICAgICAgICAgICAgICAgICAgNDc6ZWQ6Njg6OGU6OTI6MTI6Y2E6NWQ6ZmM6ZDY6MmI6YjI6OTI6M2M6MjA6CisgICAgICAgICAgICAgICAgICAgIGNmOmUxOjVmOmFmOjIwOmJlOmEwOjc2OjdmOjc2OmU1OmVjOjFhOjg2OjYxOgorICAgICAgICAgICAgICAgICAgICAzMzozZTplNzo3YjpiNDozZjphMDowZjo4ZTphMjpiOTo2YTo2ZjpiOTo4NzoKKyAgICAgICAgICAgICAgICAgICAgMjY6NmY6NDE6NmM6ODg6YTY6NTA6ZmQ6NmE6NjM6MGI6ZjU6OTM6MTY6MWI6CisgICAgICAgICAgICAgICAgICAgIDE5OjhmOmIyOmVkOjliOjliOmM5OjkwOmY1OjAxOjBjOmRmOjE5OjNkOjBmOgorICAgICAgICAgICAgICAgICAgICAzZTozODoyMzpjOToyZjo4ZjowYzpkMTowMjpmZToxYjo1NTpkNjo0ZTpkMDoKKyAgICAgICAgICAgICAgICAgICAgOGQ6M2M6YWY6NGY6YTQ6ZjM6ZmU6YWY6MmE6ZDM6MDU6OWQ6Nzk6MDg6YTE6CisgICAgICAgICAgICAgICAgICAgIGNiOjU3OjMxOmI0OjljOmM4OjkwOmIyOjY3OmY0OjE4OjE2OjkzOjNhOmZjOgorICAgICAgICAgICAgICAgICAgICA0NzpkODpkMTo3ODo5NjozMToxZjpiYToyYjowYzo1Zjo1ZDo5OTphZDo2MzoKKyAgICAgICAgICAgICAgICAgICAgODk6NWE6MjQ6MjA6NzY6ZDg6ZGY6ZmQ6YWI6NGU6YTY6MjI6YWE6OWQ6NWU6CisgICAgICAgICAgICAgICAgICAgIGU2OjI3OjhhOjdkOjY4OjI5OmEzOmU3OjhhOmI4OmRhOjExOmJiOjE3OjJkOgorICAgICAgICAgICAgICAgICAgICA5OTo5ZDoxMzoyNDo0NjpmNzpjNTplMjpkODo5Zjo4ZTo3ZjpjNzo4Zjo3NDoKKyAgICAgICAgICAgICAgICAgICAgNmQ6NWE6YjI6ZTg6NzI6ZjU6YWM6ZWU6MjQ6MTA6YWQ6MmY6MTQ6ZGE6ZmY6CisgICAgICAgICAgICAgICAgICAgIDJkOjlhOjQ2OjcxOjQ3OmJlOjQyOmRmOmJiOjAxOmRiOmY0OjdmOmQzOjI4OgorICAgICAgICAgICAgICAgICAgICA4ZjozMTo1OTo1YjpkMzpjOTowMjphNjpiNDo1MjpjYTo2ZTo5NzpmYjo0MzoKKyAgICAgICAgICAgICAgICAgICAgYzU6MDg6MjY6NmY6OGE6ZjQ6YmI6ZmQ6OWY6Mjg6YWE6MGQ6ZDU6NDU6ZjM6CisgICAgICAgICAgICAgICAgICAgIDEzOjNhOjFkOmQ4OmMwOjc4OjhmOjQxOjY3OjNjOjFlOjk0OjY0OmFlOjdiOgorICAgICAgICAgICAgICAgICAgICAwYjpjNTplODpkOTowMTo4ODozOToxYTo5Nzo4Njo2NDo0MTpkNTozYjo4NzoKKyAgICAgICAgICAgICAgICAgICAgMGM6NmU6ZmE6MGY6YzY6YmQ6NDg6MTQ6YmY6Mzk6NGQ6ZDQ6OWU6NDE6YjY6CisgICAgICAgICAgICAgICAgICAgIDhmOjk2OjFkOjYzOjk2OjkzOmQ5Ojk1OjA2Ojc4OjMxOjY4OjllOjM3OjA2OgorICAgICAgICAgICAgICAgICAgICAzYjo4MDo4OTo0NTo2MTozOToyMzpjNzoxYjo0NDphMzoxNTplNToxYzpmODoKKyAgICAgICAgICAgICAgICAgICAgOTI6MzA6YmIKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUsIHBhdGhsZW46MQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDY1OkNEOkVCOkFCOjM1OjFFOjAwOjNFOjdFOkQ1Ojc0OkMwOjFDOkI0OjczOjQ3OjBFOjFBOjY0OjJGCisgICAgICAgICAgICBYNTA5djMgQ2VydGlmaWNhdGUgUG9saWNpZXM6IAorICAgICAgICAgICAgICAgIFBvbGljeTogWDUwOXYzIEFueSBQb2xpY3kKKyAgICAgICAgICAgICAgICAgIENQUzogaHR0cDovL3d3dy5maXJtYXByb2Zlc2lvbmFsLmNvbS9jcHMKKyAgICAgICAgICAgICAgICAgIFVzZXIgTm90aWNlOgorICAgICAgICAgICAgICAgICAgICBFeHBsaWNpdCBUZXh0OiAKKworICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAxNzo3ZDphMDpmOTpiNDpkZDpjNTpjNTplYjphZDo0YjoyNDpiNTphMTowMjphYjpkZDphNToKKyAgICAgICAgODg6NGE6YjI6MGY6NTU6NGI6MmI6NTc6OGM6M2I6ZTU6MzE6ZGQ6ZmU6YzQ6MzI6ZjE6ZTc6CisgICAgICAgIDViOjY0Ojk2OjM2OjMyOjE4OmVjOmE1OjMyOjc3OmQ3OmUzOjQ0OmI2OmMwOjExOjJhOjgwOgorICAgICAgICBiOTozZDo2YTo2ZTo3Yzo5YjpkMzphZDpmYzpjMzpkNjphMzplNjo2NDoyOTo3YzpkMTplMToKKyAgICAgICAgMzg6MWU6ODI6MmI6ZmY6Mjc6NjU6YWY6ZmI6MTY6MTU6YzQ6MmU6NzE6ODQ6ZTU6YjU6ZmY6CisgICAgICAgIGZhOmE0OjQ3OmJkOjY0OjMyOmJiOmY2OjI1Ojg0OmEyOjI3OjQyOmY1OjIwOmIwOmMyOjEzOgorICAgICAgICAxMDoxMTpjZDoxMDoxNTpiYTo0Mjo5MDoyYTpkMjo0NDplMTo5NjoyNjplYjozMTo0ODoxMjoKKyAgICAgICAgZmQ6MmE6ZGE6Yzk6MDY6Y2Y6NzQ6MWU6YTk6NGI6ZDU6ODc6Mjg6Zjk6Nzk6MzQ6OTI6M2U6CisgICAgICAgIDJlOjQ0OmU4OmY2OjhmOjRmOjhmOjM1OjNmOjI1OmIzOjM5OmRjOjYzOjJhOjkwOjZiOjIwOgorICAgICAgICA1ZjpjNDo1MjoxMjo0ZTo5NzoyYzoyYTphYzo5ZDo5NzpkZTo0ODpmMjphMzo2NjpkYjpjMjoKKyAgICAgICAgZDI6ODM6OTU6YTY6NjY6YTc6OWU6MjU6MGY6ZTk6MGI6MzM6OTE6NjU6MGE6NWE6YzM6ZDk6CisgICAgICAgIDU0OjEyOmRkOmFmOmMzOjRlOjBlOjFmOjI2OjVlOjBkOmRjOmIzOjhkOmVjOmQ1OjgxOjcwOgorICAgICAgICBkZTpkMjo0ZjoyNDowNTpmMzo2Yzo0ZTpmNTo0Yzo0OTo2Njo4ZDpkMTpmZjpkMjowYjoyNToKKyAgICAgICAgNDE6NDg6ZmU6NTE6ODQ6YzY6NDI6YWY6ODA6MDQ6Y2Y6ZDA6N2U6NjQ6NDk6ZTQ6ZjI6ZGY6CisgICAgICAgIGEyOmVjOmIxOjRjOmMwOjJhOjFkOmU3OmI0OmIxOjY1OmEyOmM0OmJjOmYxOjk4OmY0OmFhOgorICAgICAgICA3MDowNzo2MzpiNDpiODpkYTozYjo0YzpmYTo0MDoyMjozMDo1YjoxMTphNjpmMDowNTowZToKKyAgICAgICAgYzY6MDI6MDM6NDg6YWI6ODY6OWI6ODU6ZGQ6ZGI6ZGQ6ZWE6YTI6NzY6ODA6NzM6N2Q6ZjU6CisgICAgICAgIDljOjA0OmM0OjQ1OjhkOmU3OmI5OjFjOjhiOjllOmVhOmQ3Ojc1OmQxOjcyOmIxOmRlOjc1OgorICAgICAgICA0NDplNzo0Mjo3ZDplMjo1Nzo2Yjo3ZDpkYzo5OTpiYzozZDo4MzoyODplYTo4MDo5Mzo4ZDoKKyAgICAgICAgYzU6NGM6NjU6YzE6NzA6ODE6Yjg6Mzg6ZmM6NDM6MzE6YjI6ZjY6MDM6MzQ6NDc6YjI6YWM6CisgICAgICAgIGZiOjIyOjA2OmNiOjFlOmRkOjE3OjQ3OjFjOjVmOjY2OmI5OmQzOjFhOmEyOmRhOjExOmIxOgorICAgICAgICBhNDpiYzoyMzpjOTplNDpiZTo4NzpmZjpiOTo5NDpiNjpmODo1ZDoyMDo0YTpkNDo1ZjplNzoKKyAgICAgICAgYmQ6Njg6N2I6NjU6ZjI6MTU6MWU6ZDI6M2E6YTk6MmQ6ZTk6ZDg6NmI6MjQ6YWM6OTc6NTg6CisgICAgICAgIDQ0OjQ3OmFkOjU5OjE4OmYxOjIxOjY1OjcwOmRlOmNlOjM0OjYwOmE4OjQwOmYxOmYzOjNjOgorICAgICAgICBhNDpjMzoyODoyMzo4YzpmZToyNzozMzo0Mzo0MDphMDoxNzozYzplYjplYTozYjpiMDo3MjoKKyAgICAgICAgYTY6YTM6Yjk6NGE6NGI6NWU6MTY6NDg6ZjQ6YjI6YmM6Yzg6OGM6OTI6YzU6OWQ6OWY6YWM6CisgICAgICAgIDcyOjM2OmJjOjM0OjgwOjM0OjZiOmE5OjhiOjkyOmMwOmI4OjE3OmVkOmVjOjc2OjUzOmY1OgorICAgICAgICAyNDowMTo4YzpiMzoyMjplODo0Yjo3Yzo1NTpjNjo5ZDpmYTphMzoxNDpiYjo2NTo4NTo2ZToKKyAgICAgICAgNmU6NGY6MTI6N2U6MGE6M2M6OWQ6OTUKK1NIQTEgRmluZ2VycHJpbnQ9QUU6QzU6RkI6M0Y6Qzg6RTE6QkY6QzQ6RTU6NEY6MDM6MDc6NUE6OUE6RTg6MDA6Qjc6Rjc6QjY6RkEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9kNTM3ZmJhNi4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2Q1MzdmYmE2LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzVmNjIyNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9kNTM3ZmJhNi4wCkBAIC0wLDAgKzEsOTQgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRUt6Q0NBeE9nQXdJQkFnSUVPc3lsVERBTkJna3Foa2lHOXcwQkFRVUZBREJETVFzd0NRWURWUVFHRXdKRQorU3pFVk1CTUdBMVVFQ2hNTVZFUkRJRWx1ZEdWeWJtVjBNUjB3R3dZRFZRUUxFeFJVUkVNZ1NXNTBaWEp1WlhRZworVW05dmRDQkRRVEFlRncwd01UQTBNRFV4TmpNek1UZGFGdzB5TVRBME1EVXhOekF6TVRkYU1FTXhDekFKQmdOVgorQkFZVEFrUkxNUlV3RXdZRFZRUUtFd3hVUkVNZ1NXNTBaWEp1WlhReEhUQWJCZ05WQkFzVEZGUkVReUJKYm5SbAorY201bGRDQlNiMjkwSUVOQk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBeExoQQordkpIVll4L1htYUNMREVBZWRMZEluVWFNQXJMZ0pGL3dHUk9uTjROclhjZU8rWVF3emhvNyt2dk9pMjBqeHNOdQorWnArSnBkL2dRbEJuK2g5c0h2VFFCZGEveXRaTzVHaGdiRWFxSEYxajRRZUdEbVVBcHk2bWNjYTh1WUdvT24wYQorMHZuUnJFdkx6bld2M0h2NmdYUFUvTHE5UVlqVWRMUDVYamc2UEVPbzBwVk9kMjBUREoyUGVBRzNXaUFmQXpjMQorNGl6YlN5c3NlTGxKMjhUUXg1eWM1SW9nQ1NFV1ZtYi9CZXhiNC9EUHF5UWtYc04vY0hvU3hOSzFFS0MySWVHTgorZUdsVlJHbjF5cFljTklVWEpYZmk5aThubUhqOWVRWTZvdFphUThILzdBUTc3aFB2MDFoYS81THI3SzdhOGpjRAorUjBHMmw4a3RDa0VpdTd2bXB3SURBUUFCbzRJQkpUQ0NBU0V3RVFZSllJWklBWWI0UWdFQkJBUURBZ0FITUdVRworQTFVZEh3UmVNRnd3V3FCWW9GYWtWREJTTVFzd0NRWURWUVFHRXdKRVN6RVZNQk1HQTFVRUNoTU1WRVJESUVsdQorZEdWeWJtVjBNUjB3R3dZRFZRUUxFeFJVUkVNZ1NXNTBaWEp1WlhRZ1VtOXZkQ0JEUVRFTk1Bc0dBMVVFQXhNRQorUTFKTU1UQXJCZ05WSFJBRUpEQWlnQTh5TURBeE1EUXdOVEUyTXpNeE4xcUJEekl3TWpFd05EQTFNVGN3TXpFMworV2pBTEJnTlZIUThFQkFNQ0FRWXdId1lEVlIwakJCZ3dGb0FVYkdRQngvMkZiYXpJMnA1UUNJVUl0VHhXcUZBdworSFFZRFZSME9CQllFRkd4a0FjZjloVzJzeU5xZVVBaUZDTFU4VnFoUU1Bd0dBMVVkRXdRRk1BTUJBZjh3SFFZSgorS29aSWh2WjlCMEVBQkJBd0Roc0lWalV1TURvMExqQURBZ1NRTUEwR0NTcUdTSWIzRFFFQkJRVUFBNElCQVFCTworUTh6UjNSMFFHd1ovdDZUNjA5bE4reU9mSTFSYjVvc3ZCQ2lMdFNkdGlhSHNtR25jNTQwbWd3VjVkT3kwdWFPWAord1RVQS9SWGFPWUU2bFRHUTNwZnBocWlaZHd6bFdxQ0UveElXckc2NGpjTjdrc0tzTHRCOUtPeTI4MkE0YVc4KworMkFSVlBwN01WZEs2L3J0SEJOY0syUllLTkNuMVdCUFZUOCtQVmt1ekh1N1RtSG5hQ0I0TWI3ajRGaWZ2d204OQorOXFOTFBnN2tiV3piTzBFU203ME5SeU4vUEVyUXI4Q3Y5dThidFJYRTY0UEVDVjkwaTlrUis4SldzVHo0Y01vMAoralVOQUU0ejltUU5VZWNZdTZvYWg5anJVQ2J6MHZHYk1QVmpRVjBrSzdpWGlRZTRUK1pzNE5ORUE5WDdubEIzOAorYVFOaXVKa0ZCVDFyZUJLOXNHOWwKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogOTg2NDkwMTg4ICgweDNhY2NhNTRjKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPURLLCBPPVREQyBJbnRlcm5ldCwgT1U9VERDIEludGVybmV0IFJvb3QgQ0EKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEFwciAgNSAxNjozMzoxNyAyMDAxIEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogQXByICA1IDE3OjAzOjE3IDIwMjEgR01UCisgICAgICAgIFN1YmplY3Q6IEM9REssIE89VERDIEludGVybmV0LCBPVT1UREMgSW50ZXJuZXQgUm9vdCBDQQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YzQ6Yjg6NDA6YmM6OTE6ZDU6NjM6MWY6ZDc6OTk6YTA6OGI6MGM6NDA6CisgICAgICAgICAgICAgICAgICAgIDFlOjc0OmI3OjQ4OjlkOjQ2OjhjOjAyOmIyOmUwOjI0OjVmOmYwOjE5OjEzOgorICAgICAgICAgICAgICAgICAgICBhNzozNzo4Mzo2Yjo1ZDpjNzo4ZTpmOTo4NDozMDpjZToxYTozYjpmYTpmYjoKKyAgICAgICAgICAgICAgICAgICAgY2U6OGI6NmQ6MjM6YzY6YzM6NmU6NjY6OWY6ODk6YTU6ZGY6ZTA6NDI6NTA6CisgICAgICAgICAgICAgICAgICAgIDY3OmZhOjFmOjZjOjFlOmY0OmQwOjA1OmQ2OmJmOmNhOmQ2OjRlOmU0OjY4OgorICAgICAgICAgICAgICAgICAgICA2MDo2Yzo0NjphYToxYzo1ZDo2MzplMTowNzo4NjowZTo2NTowMDphNzoyZToKKyAgICAgICAgICAgICAgICAgICAgYTY6NzE6YzY6YmM6Yjk6ODE6YTg6M2E6N2Q6MWE6ZDI6Zjk6ZDE6YWM6NGI6CisgICAgICAgICAgICAgICAgICAgIGNiOmNlOjc1OmFmOmRjOjdiOmZhOjgxOjczOmQ0OmZjOmJhOmJkOjQxOjg4OgorICAgICAgICAgICAgICAgICAgICBkNDo3NDpiMzpmOTo1ZTozODozYTozYzo0MzphODpkMjo5NTo0ZTo3Nzo2ZDoKKyAgICAgICAgICAgICAgICAgICAgMTM6MGM6OWQ6OGY6Nzg6MDE6Yjc6NWE6MjA6MWY6MDM6Mzc6MzU6ZTI6MmM6CisgICAgICAgICAgICAgICAgICAgIGRiOjRiOjJiOjJjOjc4OmI5OjQ5OmRiOmM0OmQwOmM3OjljOjljOmU0OjhhOgorICAgICAgICAgICAgICAgICAgICAyMDowOToyMToxNjo1Njo2NjpmZjowNTplYzo1YjplMzpmMDpjZjphYjoyNDoKKyAgICAgICAgICAgICAgICAgICAgMjQ6NWU6YzM6N2Y6NzA6N2E6MTI6YzQ6ZDI6YjU6MTA6YTA6YjY6MjE6ZTE6CisgICAgICAgICAgICAgICAgICAgIDhkOjc4OjY5OjU1OjQ0OjY5OmY1OmNhOjk2OjFjOjM0Ojg1OjE3OjI1Ojc3OgorICAgICAgICAgICAgICAgICAgICBlMjpmNjoyZjoyNzo5ODo3ODpmZDo3OTowNjozYTphMjpkNjo1YTo0MzpjMToKKyAgICAgICAgICAgICAgICAgICAgZmY6ZWM6MDQ6M2I6ZWU6MTM6ZWY6ZDM6NTg6NWE6ZmY6OTI6ZWI6ZWM6YWU6CisgICAgICAgICAgICAgICAgICAgIGRhOmYyOjM3OjAzOjQ3OjQxOmI2Ojk3OmM5OjJkOjBhOjQxOjIyOmJiOmJiOgorICAgICAgICAgICAgICAgICAgICBlNjphNworICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBOZXRzY2FwZSBDZXJ0IFR5cGU6IAorICAgICAgICAgICAgICAgIFNTTCBDQSwgUy9NSU1FIENBLCBPYmplY3QgU2lnbmluZyBDQQorICAgICAgICAgICAgWDUwOXYzIENSTCBEaXN0cmlidXRpb24gUG9pbnRzOiAKKyAgICAgICAgICAgICAgICBEaXJOYW1lOi9DPURLL089VERDIEludGVybmV0L09VPVREQyBJbnRlcm5ldCBSb290IENBL0NOPUNSTDEKKworICAgICAgICAgICAgWDUwOXYzIFByaXZhdGUgS2V5IFVzYWdlIFBlcmlvZDogCisgICAgICAgICAgICAgICAgTm90IEJlZm9yZTogQXByICA1IDE2OjMzOjE3IDIwMDEgR01ULCBOb3QgQWZ0ZXI6IEFwciAgNSAxNzowMzoxNyAyMDIxIEdNVAorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOjZDOjY0OjAxOkM3OkZEOjg1OjZEOkFDOkM4OkRBOjlFOjUwOjA4Ojg1OjA4OkI1OjNDOjU2OkE4OjUwCisKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICA2Qzo2NDowMTpDNzpGRDo4NTo2RDpBQzpDODpEQTo5RTo1MDowODo4NTowODpCNTozQzo1NjpBODo1MAorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiAKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICAxLjIuODQwLjExMzUzMy43LjY1LjA6IAorICAgICAgICAgICAgICAgIDAuLi5WNS4wOjQuMC4uLi4KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgNGU6NDM6Y2M6ZDE6ZGQ6MWQ6MTA6MWI6MDY6N2Y6Yjc6YTQ6ZmE6ZDM6ZDk6NGQ6ZmI6MjM6CisgICAgICAgIDlmOjIzOjU0OjViOmU2OjhiOjJmOjA0OjI4OjhiOmI1OjI3OjZkOjg5OmExOmVjOjk4OjY5OgorICAgICAgICBkYzplNzo4ZDoyNjo4MzowNTo3OTo3NDplYzpiNDpiOTphMzo5NzpjMTozNTowMDpmZDoxNToKKyAgICAgICAgZGE6Mzk6ODE6M2E6OTU6MzE6OTA6ZGU6OTc6ZTk6ODY6YTg6OTk6Nzc6MGM6ZTU6NWE6YTA6CisgICAgICAgIDg0OmZmOjEyOjE2OmFjOjZlOmI4OjhkOmMzOjdiOjkyOmMyOmFjOjJlOmQwOjdkOjI4OmVjOgorICAgICAgICBiNjpmMzo2MDozODo2OTo2ZjozZTpkODowNDo1NTozZTo5ZTpjYzo1NTpkMjpiYTpmZTpiYjoKKyAgICAgICAgNDc6MDQ6ZDc6MGE6ZDk6MTY6MGE6MzQ6Mjk6ZjU6NTg6MTM6ZDU6NGY6Y2Y6OGY6NTY6NGI6CisgICAgICAgIGIzOjFlOmVlOmQzOjk4Ojc5OmRhOjA4OjFlOjBjOjZmOmI4OmY4OjE2OjI3OmVmOmMyOjZmOgorICAgICAgICAzZDpmNjphMzo0YjozZTowZTplNDo2ZDo2YzpkYjozYjo0MToxMjo5YjpiZDowZDo0NzoyMzoKKyAgICAgICAgN2Y6M2M6NGE6ZDA6YWY6YzA6YWY6ZjY6ZWY6MWI6YjU6MTU6YzQ6ZWI6ODM6YzQ6MDk6NWY6CisgICAgICAgIDc0OjhiOmQ5OjExOmZiOmMyOjU2OmIxOjNjOmY4OjcwOmNhOjM0OjhkOjQzOjQwOjEzOjhjOgorICAgICAgICBmZDo5OTowMzo1NDo3OTpjNjoyZTplYTo4NjphMTpmNjozYTpkNDowOTpiYzpmNDpiYzo2NjoKKyAgICAgICAgY2M6M2Q6NTg6ZDA6NTc6NDk6MGE6ZWU6MjU6ZTI6NDE6ZWU6MTM6Zjk6OWI6Mzg6MzQ6ZDE6CisgICAgICAgIDAwOmY1OjdlOmU3Ojk0OjFkOmZjOjY5OjAzOjYyOmI4Ojk5OjA1OjA1OjNkOjZiOjc4OjEyOgorICAgICAgICBiZDpiMDo2Zjo2NQorU0hBMSBGaW5nZXJwcmludD0yMTpGQzpCRDo4RTo3Rjo2QzpBRjowNToxQjpEMTpCMzo0MzpFQzpBODpFNzo2MTo0NzpGMjowRjo4QQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2Q2NGYwNmYzLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZDY0ZjA2ZjMuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZmQ0OWU3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2Q2NGYwNmYzLjAKQEAgLTAsMCArMSw5MCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFRHpDQ0F2ZWdBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUVVGQURCS01Rc3dDUVlEVlFRR0V3SlRTekVUCitNQkVHQTFVRUJ4TUtRbkpoZEdsemJHRjJZVEVUTUJFR0ExVUVDaE1LUkdsemFXY2dZUzV6TGpFUk1BOEdBMVVFCitBeE1JUTBFZ1JHbHphV2N3SGhjTk1EWXdNekl5TURFek9UTTBXaGNOTVRZd016SXlNREV6T1RNMFdqQktNUXN3CitDUVlEVlFRR0V3SlRTekVUTUJFR0ExVUVCeE1LUW5KaGRHbHpiR0YyWVRFVE1CRUdBMVVFQ2hNS1JHbHphV2NnCitZUzV6TGpFUk1BOEdBMVVFQXhNSVEwRWdSR2x6YVdjd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3CitnZ0VLQW9JQkFRQ1M5akhCZllqOW1RR3AySHZ5Y1hYeE1jYnpkV2I2VVNoR2hKZDROTHhzL0x4RldZZ21HRXJFCitOeCtoU2tTOTQzRUU5VVFYNGovOFNGaHZYSjU2Q2JwUk55SWpaa01oc0R4a292aHFGUTQvNjFIaFZLbmRCcG5YCittanhVaXprRFB3L0Z6c2JyZzNJQ3FCOXg4eTM0ZFFqYllrem8rczc1NTJvZnRtczFncnJpanhhU2ZRVU1iRVlECitYY0R0YWI4NndZcWc2STdadVVVb2h3anN0TW9Wdm9MZHRVU0xMYTJHREdoaWJZVlc4cXdVWXpyRzBabXNOSGhXCitTOCsyclQrTWl0Y0U1ZU40VFBXR3F2V1ArajFzY2FNdHltZnJhSHR1TTZrTWdpaW9UR29oUUJVZ0RDWmJnOEtwCitGaFhBSklKZEt4YXR5bVAyZEFDdzMwUEVFR0JXWjJORkFnTUJBQUdqZ2Y4d2dmd3dEd1lEVlIwVEFRSC9CQVV3CitBd0VCL3pBZEJnTlZIUTRFRmdRVWpiSkphSjF5Q0NXNXdDZjFVSk5XU0VaeCtZOHdEZ1lEVlIwUEFRSC9CQVFECitBZ0VHTURZR0ExVWRFUVF2TUMyQkUyTmhiM0JsY21GMGIzSkFaR2x6YVdjdWMydUdGbWgwZEhBNkx5OTNkM2N1CitaR2x6YVdjdWMyc3ZZMkV3WmdZRFZSMGZCRjh3WFRBdG9DdWdLWVluYUhSMGNEb3ZMM2QzZHk1a2FYTnBaeTV6CitheTlqWVM5amNtd3ZZMkZmWkdsemFXY3VZM0pzTUN5Z0txQW9oaVpvZEhSd09pOHZZMkV1WkdsemFXY3VjMnN2CitZMkV2WTNKc0wyTmhYMlJwYzJsbkxtTnliREFhQmdOVkhTQUVFekFSTUE4R0RTdUJIcEdUNWdvQUFBQUJBUUV3CitEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBRjAwZEdGTXJ6dlkvNTl0V0RZY1BRdUJEUklyUmhDQS9lYzhKOUI2Cit5S20yZm5Rd002TTZpbnQwd0hsNVFwTnQvN0VwRklLcklZd3ZGL2svSmkvMVdjYnZnQWEzbWtrcDdNNStjVHhxCitFRUhBOXRPYXNueGFrWnpBckZ2SVRWNzM0VlAvUTNmOG5rdG5iTmZ6ZzlHZzRIOGwzN2lZQzVveU9Hd3dvUFAvCitDQlV6OTFCS2V6NmpQaUNwM0M5V2dBcnRRVkN3eWZUc3N1TW1SQUFPYjU0R3ZDS1dVM0JseEZBS1JtdWtMeWVCCitFaWNUWHhDaGRzNktlemZxd3psaEE1V1lPdWRzaUNVSS9IbG9EWWQ5WXZpMFgvdkYyRXk5V0x3L1ExdlVIZ0ZOCitQR08rSSsrTXpWcFF1R2hVK1FxWk14RUE0WjdDUm5lQzlWa0dqQ0ZNaHduTjVhZz0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMSAoMHgxKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVNLLCBMPUJyYXRpc2xhdmEsIE89RGlzaWcgYS5zLiwgQ049Q0EgRGlzaWcKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IE1hciAyMiAwMTozOTozNCAyMDA2IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogTWFyIDIyIDAxOjM5OjM0IDIwMTYgR01UCisgICAgICAgIFN1YmplY3Q6IEM9U0ssIEw9QnJhdGlzbGF2YSwgTz1EaXNpZyBhLnMuLCBDTj1DQSBEaXNpZworICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6OTI6ZjY6MzE6YzE6N2Q6ODg6ZmQ6OTk6MDE6YTk6ZDg6N2I6ZjI6NzE6CisgICAgICAgICAgICAgICAgICAgIDc1OmYxOjMxOmM2OmYzOjc1OjY2OmZhOjUxOjI4OjQ2Ojg0Ojk3Ojc4OjM0OgorICAgICAgICAgICAgICAgICAgICBiYzo2YzpmYzpiYzo0NTo1OTo4ODoyNjoxODo0YTpjNDozNzoxZjphMTo0YToKKyAgICAgICAgICAgICAgICAgICAgNDQ6YmQ6ZTM6NzE6MDQ6ZjU6NDQ6MTc6ZTI6M2Y6ZmM6NDg6NTg6NmY6NWM6CisgICAgICAgICAgICAgICAgICAgIDllOjdhOjA5OmJhOjUxOjM3OjIyOjIzOjY2OjQzOjIxOmIwOjNjOjY0OmEyOgorICAgICAgICAgICAgICAgICAgICBmODo2YToxNTowZTozZjplYjo1MTplMTo1NDphOTpkZDowNjo5OTpkNzo5YToKKyAgICAgICAgICAgICAgICAgICAgM2M6NTQ6OGI6Mzk6MDM6M2Y6MGY6YzU6Y2U6YzY6ZWI6ODM6NzI6MDI6YTg6CisgICAgICAgICAgICAgICAgICAgIDFmOjcxOmYzOjJkOmY4Ojc1OjA4OmRiOjYyOjRjOmU4OmZhOmNlOmY5OmU3OgorICAgICAgICAgICAgICAgICAgICA2YToxZjpiNjo2YjozNTo4MjpiYTplMjo4ZjoxNjo5Mjo3ZDowNTowYzo2YzoKKyAgICAgICAgICAgICAgICAgICAgNDY6MDM6NWQ6YzA6ZWQ6Njk6YmY6M2E6YzE6OGE6YTA6ZTg6OGU6ZDk6Yjk6CisgICAgICAgICAgICAgICAgICAgIDQ1OjI4Ojg3OjA4OmVjOmI0OmNhOjE1OmJlOjgyOmRkOmI1OjQ0OjhiOjJkOgorICAgICAgICAgICAgICAgICAgICBhZDo4NjowYzo2ODo2Mjo2ZDo4NTo1NjpmMjphYzoxNDo2MzozYTpjNjpkMToKKyAgICAgICAgICAgICAgICAgICAgOTk6YWM6MzQ6Nzg6NTY6NGI6Y2Y6YjY6YWQ6M2Y6OGM6OGE6ZDc6MDQ6ZTU6CisgICAgICAgICAgICAgICAgICAgIGUzOjc4OjRjOmY1Ojg2OmFhOmY1OjhmOmZhOjNkOjZjOjcxOmEzOjJkOmNhOgorICAgICAgICAgICAgICAgICAgICA2NzplYjo2ODo3Yjo2ZTozMzphOTowYzo4MjoyODphODo0Yzo2YToyMTo0MDoKKyAgICAgICAgICAgICAgICAgICAgMTU6MjA6MGM6MjY6NWI6ODM6YzI6YTk6MTY6MTU6YzA6MjQ6ODI6NWQ6MmI6CisgICAgICAgICAgICAgICAgICAgIDE2OmFkOmNhOjYzOmY2Ojc0OjAwOmIwOmRmOjQzOmM0OjEwOjYwOjU2OjY3OgorICAgICAgICAgICAgICAgICAgICA2Mzo0NQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDhEOkIyOjQ5OjY4OjlEOjcyOjA4OjI1OkI5OkMwOjI3OkY1OjUwOjkzOjU2OjQ4OjQ2OjcxOkY5OjhGCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBBbHRlcm5hdGl2ZSBOYW1lOiAKKyAgICAgICAgICAgICAgICBlbWFpbDpjYW9wZXJhdG9yQGRpc2lnLnNrLCBVUkk6aHR0cDovL3d3dy5kaXNpZy5zay9jYQorICAgICAgICAgICAgWDUwOXYzIENSTCBEaXN0cmlidXRpb24gUG9pbnRzOiAKKyAgICAgICAgICAgICAgICBVUkk6aHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2FfZGlzaWcuY3JsCisgICAgICAgICAgICAgICAgVVJJOmh0dHA6Ly9jYS5kaXNpZy5zay9jYS9jcmwvY2FfZGlzaWcuY3JsCisKKyAgICAgICAgICAgIFg1MDl2MyBDZXJ0aWZpY2F0ZSBQb2xpY2llczogCisgICAgICAgICAgICAgICAgUG9saWN5OiAxLjMuMTU4LjM1OTc1OTQ2LjAuMC4wLjEuMS4xCisKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgNWQ6MzQ6NzQ6NjE6NGM6YWY6M2I6ZDg6ZmY6OWY6NmQ6NTg6MzY6MWM6M2Q6MGI6ODE6MGQ6CisgICAgICAgIDEyOjJiOjQ2OjEwOjgwOmZkOmU3OjNjOjI3OmQwOjdhOmM4OmE5OmI2OjdlOjc0OjMwOjMzOgorICAgICAgICBhMzozYTo4YTo3Yjo3NDpjMDo3OTo3OTo0Mjo5Mzo2ZDpmZjpiMToyOToxNDo4MjphYjoyMToKKyAgICAgICAgOGM6MmY6MTc6Zjk6M2Y6MjY6MmY6ZjU6NTk6YzY6ZWY6ODA6MDY6Yjc6OWE6NDk6Mjk6ZWM6CisgICAgICAgIGNlOjdlOjcxOjNjOjZhOjEwOjQxOmMwOmY2OmQzOjlhOmIyOjdjOjVhOjkxOjljOmMwOmFjOgorICAgICAgICA1YjpjODo0ZDo1ZTpmNzplMTo1MzpmZjo0Mzo3NzpmYzo5ZTo0Yjo2Nzo2YzpkNzpmMzo4MzoKKyAgICAgICAgZDE6YTA6ZTA6N2Y6MjU6ZGY6Yjg6OTg6MGI6OWE6MzI6Mzg6NmM6MzA6YTA6ZjM6ZmY6MDg6CisgICAgICAgIDE1OjMzOmY3OjUwOjRhOjdiOjNlOmEzOjNlOjIwOmE5OmRjOjJmOjU2OjgwOjBhOmVkOjQxOgorICAgICAgICA1MDpiMDpjOTpmNDplYzpiMjplMzoyNjo0NDowMDowZTo2Zjo5ZTowNjpiYzoyMjo5Njo1MzoKKyAgICAgICAgNzA6NjU6YzQ6NTA6MGE6NDY6NmI6YTQ6MmY6Mjc6ODE6MTI6Mjc6MTM6NWY6MTA6YTE6NzY6CisgICAgICAgIGNlOjhhOjdiOjM3OmVhOmMzOjM5OjYxOjAzOjk1Ojk4OjNhOmU3OjZjOjg4OjI1OjA4OmZjOgorICAgICAgICA3OTo2ODowZDo4Nzo3ZDo2MjpmODpiNDo1ZjpmYjpjNTpkODo0YzpiZDo1ODpiYzozZjo0MzoKKyAgICAgICAgNWI6ZDQ6MWU6MDE6NGQ6M2M6NjM6YmU6MjM6ZWY6OGM6Y2Q6NWE6NTA6Yjg6Njg6NTQ6Zjk6CisgICAgICAgIDBhOjk5OjMzOjExOjAwOmUxOjllOmMyOjQ2Ojc3OjgyOmY1OjU5OjA2OjhjOjIxOjRjOjg3OgorICAgICAgICAwOTpjZDplNTphOAorU0hBMSBGaW5nZXJwcmludD0yQTpDODpENTo4Qjo1NzpDRTpCRjoyRjo0OTpBRjpGMjpGQzo3Njo4Rjo1MToxNDo2Mjo5MDo3QTo0MQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2Q3NzczNDJkLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZDc3NzM0MmQuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZDYyZWJjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2Q3NzczNDJkLjAKQEAgLTAsMCArMSw3MCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlES1RDQ0FoRUNDRjlnV0Y4QUFBQUFNQTBHQ1NxR1NJYjNEUUVCQlFVQU1GY3hDekFKQmdOVkJBWVRBa3BRCitNU3N3S1FZRFZRUUtFeUpLWVhCaGJpQkRaWEowYVdacFkyRjBhVzl1SUZObGNuWnBZMlZ6TENCSmJtTXVNUnN3CitHUVlEVlFRREV4SlRaV04xY21WVGFXZHVJRkp2YjNSRFFURXdIaGNOT1Rrd09URTFNVFV3TURBeFdoY05NakF3CitPVEUxTVRRMU9UVTVXakJYTVFzd0NRWURWUVFHRXdKS1VERXJNQ2tHQTFVRUNoTWlTbUZ3WVc0Z1EyVnlkR2xtCithV05oZEdsdmJpQlRaWEoyYVdObGN5d2dTVzVqTGpFYk1Ca0dBMVVFQXhNU1UyVmpkWEpsVTJsbmJpQlNiMjkwCitRMEV4TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFsSkFNUzNFcEhOcjJhSGw2CitwTHJuMHN5TnIraEhrSmtmeGlycWwyUG9IODRYVjhZYXM2akhmSWZ0TlRXQXVycHViYjRYL3N3dEcyenZpZ0JKCitGdUh1Qmw1S0IxMnJQZEZRdUpGRzFOVGFGZGlVWEE3SzE5cS9vUGRKUE1pN3p1b21nUW9VTFp3Tk4wVnJRY3BYCitpemp3Smg4eC9NODBqbzkzd1QvanExUThKN1RPTWt4VkUyTDgvam9XSmM4YmE2SWp0K0RxQW1tNzl5SnhiWHdMCitHWk9obDV6amtXa2ZhT1F2ZlJCdGoyZXV3UkNpc0Y1alNwZjM1bmlwclNhN1ZNbmZ0TzdGbnRNbDNSTm9VL21QCis2T3psM29IV2VEN3VVRUMwQVR5c0ZjR0NPeTUvOFZJbmkzTGc1OXY1aXluRHcwb3JNNG1yWENvSC9Id2pIaXRQCitDQ0wrd1FJREFRQUJNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUJBUUJWN1c5N2srVkZNVTVvMVZXQm9nZ2ZiTjBKCit4WGdhY0ZmSTN3aUJybVozeG5VUDVPOUppd05jYlA4Y2tLUnlzdE1XRXJJRytFYUdycituRmR1RlRmckNMVTJ6Cit0YkJENzN4K0I5dGZzMWRHVVhZSGhrVDlCK3J4eTB0RlRXYW5NeWJFK1VPcWpSS3oxSTFvdHZjQ2ViUXRXdGNECittQVFzYVptdjlHWTdaS3l5d0N2SWFWU2VURTVJR0kzT1Y3VTdVZVViMS9vNVlOdFdSUk8rNTJiVkkvWjhTQUN3CitUTzgwalNLc3NpN1JURGpOK2xnREJ1NDZjNGNLQlRySzVLL1V3ZTRjaFg4bEZzOG5BUitFaW5jSTBOTkc2Q0RzCituNlNNOGJ6TnhCSTJnQjdIQ1NpdjZBaSt3Tk95UHRjdVp6Mmp6cnMwK3VLRnphek9WUjFGVzNpRjA0VjYKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDEgKDB4MCkKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDVmOjYwOjU4OjVmOjAwOjAwOjAwOjAwCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9SlAsIE89SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLiwgQ049U2VjdXJlU2lnbiBSb290Q0ExCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBTZXAgMTUgMTU6MDA6MDEgMTk5OSBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IFNlcCAxNSAxNDo1OTo1OSAyMDIwIEdNVAorICAgICAgICBTdWJqZWN0OiBDPUpQLCBPPUphcGFuIENlcnRpZmljYXRpb24gU2VydmljZXMsIEluYy4sIENOPVNlY3VyZVNpZ24gUm9vdENBMQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6OTQ6OTA6MGM6NGI6NzE6Mjk6MWM6ZGE6ZjY6Njg6Nzk6N2E6YTQ6YmE6CisgICAgICAgICAgICAgICAgICAgIGU3OmQyOmNjOjhkOmFmOmU4OjQ3OjkwOjk5OjFmOmM2OjJhOmVhOjk3OjYzOgorICAgICAgICAgICAgICAgICAgICBlODoxZjpjZToxNzo1NzpjNjoxYTpiMzphODpjNzo3Yzo4NzplZDozNTozNToKKyAgICAgICAgICAgICAgICAgICAgODA6YmE6YmE6NmU6NmQ6YmU6MTc6ZmU6Y2M6MmQ6MWI6NmM6ZWY6OGE6MDA6CisgICAgICAgICAgICAgICAgICAgIDQ5OjE2OmUxOmVlOjA2OjVlOjRhOjA3OjVkOmFiOjNkOmQxOjUwOmI4OjkxOgorICAgICAgICAgICAgICAgICAgICA0NjpkNDpkNDpkYToxNTpkODo5NDo1YzowZTpjYTpkNzpkYTpiZjphMDpmNzoKKyAgICAgICAgICAgICAgICAgICAgNDk6M2M6Yzg6YmI6Y2U6ZWE6MjY6ODE6MGE6MTQ6MmQ6OWM6MGQ6Mzc6NDU6CisgICAgICAgICAgICAgICAgICAgIDZiOjQxOmNhOjU3OjhiOjM4OmYwOjI2OjFmOjMxOmZjOmNmOjM0OjhlOjhmOgorICAgICAgICAgICAgICAgICAgICA3NzpjMTozZjplMzphYjo1NDozYzoyNzpiNDpjZTozMjo0Yzo1NToxMzo2MjoKKyAgICAgICAgICAgICAgICAgICAgZmM6ZmU6M2E6MTY6MjU6Y2Y6MWI6NmI6YTI6MjM6Yjc6ZTA6ZWE6MDI6Njk6CisgICAgICAgICAgICAgICAgICAgIGJiOmY3OjIyOjcxOjZkOjdjOjBiOjE5OjkzOmExOjk3OjljOmUzOjkxOjY5OgorICAgICAgICAgICAgICAgICAgICAxZjo2ODplNDoyZjo3ZDoxMDo2ZDo4Zjo2NzphZTpjMToxMDphMjpiMDo1ZToKKyAgICAgICAgICAgICAgICAgICAgNjM6NGE6OTc6Zjc6ZTY6Nzg6YTk6YWQ6MjY6YmI6NTQ6Yzk6ZGY6YjQ6ZWU6CisgICAgICAgICAgICAgICAgICAgIGM1OjllOmQzOjI1OmRkOjEzOjY4OjUzOmY5OjhmOmU4OmVjOmU1OmRlOjgxOgorICAgICAgICAgICAgICAgICAgICBkNjo3ODozZTplZTo1MDo0MDpiNDowMTozYzphYzoxNTpjMTo4MjozYjoyZToKKyAgICAgICAgICAgICAgICAgICAgN2Y6ZjE6NTI6Mjc6OGI6NzI6ZTA6ZTc6ZGI6Zjk6OGI6Mjk6YzM6YzM6NGE6CisgICAgICAgICAgICAgICAgICAgIDJiOjMzOjg5OmFiOjVjOjJhOjA3OmZjOjdjOjIzOjFlOjJiOjRmOjA4OjIyOgorICAgICAgICAgICAgICAgICAgICBmZTpjMQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgNTU6ZWQ6NmY6N2I6OTM6ZTU6NDU6MzE6NGU6Njg6ZDU6NTU6ODE6YTI6MDg6MWY6NmM6ZGQ6CisgICAgICAgIDA5OmM1Ojc4OjFhOjcwOjU3OmM4OmRmOjA4OjgxOmFlOjY2Ojc3OmM2Ojc1OjBmOmU0OmVmOgorICAgICAgICA0OTo4YjowMzo1Yzo2YzpmZjoxYzo5MDphNDo3MjpiMjpkMzoxNjoxMjpiMjowNjpmODo0NjoKKyAgICAgICAgODY6YWU6YmY6YTc6MTU6ZGI6ODU6NGQ6ZmE6YzI6MmQ6NGQ6YjM6YjU6YjA6NDM6ZWY6N2M6CisgICAgICAgIDdlOjA3OmRiOjVmOmIzOjU3OjQ2OjUxOjc2OjA3Ojg2OjQ0OmZkOjA3OmVhOmYxOmNiOjRiOgorICAgICAgICA0NTo0ZDo2NjphNzozMzoyNjpjNDpmOTo0MzphYTo4ZDoxMjpiMzpkNDo4ZDo2ODpiNjpmNzoKKyAgICAgICAgMDI6Nzk6YjQ6MmQ6NWE6ZDc6MDM6OTg6MDQ6MmM6Njk6OTk6YWY6ZjQ6NjY6M2I6NjQ6YWM6CisgICAgICAgIGIyOmMwOjJiOmM4OjY5OjU0OjllOjRjOjRlOjQ4OjE4OjhkOmNlOjU3OmI1OjNiOjUxOmU1OgorICAgICAgICAxYjpkNzpmYTozOTo2MDpkYjo1Njo0NToxMzpiZTplNzo2NjpkNToyMzpmNjo3Yzo0ODowMDoKKyAgICAgICAgYjA6NGM6ZWY6MzQ6OGQ6MjI6YWM6YjI6MmU6ZDE6NGM6Mzg6Y2Q6ZmE6NTg6MDM6MDY6ZWU6CisgICAgICAgIDNhOjczOjg3OjBhOjA1OjNhOmNhOmU0OmFmOmQ0OmMxOmVlOjFjOjg1OjdmOjI1OjE2OmNmOgorICAgICAgICAyNzowMToxZjo4NDo4YTo3NzowODpkMDpkMzo0NjplODoyMDplYzo5ZjphNDo4YzpmMTpiYzoKKyAgICAgICAgY2Q6YzQ6MTI6MzY6ODA6MWU6Yzc6MDk6Mjg6YWY6ZTg6MDg6YmU6YzA6ZDM6YjI6M2U6ZDc6CisgICAgICAgIDJlOjY3OjNkOmEzOmNlOmJiOjM0OmZhOmUyOjg1OmNkOmFjOmNlOjU1OjFkOjQ1OjViOjc4OgorICAgICAgICA4NTpkMzo4NTo3YQorU0hBMSBGaW5nZXJwcmludD1DQTpCQjo1MTo2NzoyNDowMDo1ODo4RTo2NDoxOTpGMTpENDowODo3ODpEMDo0MDozQTpBMjowMjo2NApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2Q4Mjc0ZTI0LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZDgyNzRlMjQuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZGM1YTVjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2Q4Mjc0ZTI0LjAKQEAgLTAsMCArMSw4NyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFWkRDQ0EweWdBd0lCQWdJUVJMNE1pMUFBSkxRUjB6WXdTOEF6ZHpBTkJna3Foa2lHOXcwQkFRVUZBRENCCitvekVMTUFrR0ExVUVCaE1DVlZNeEN6QUpCZ05WQkFnVEFsVlVNUmN3RlFZRFZRUUhFdzVUWVd4MElFeGhhMlVnCitRMmwwZVRFZU1Cd0dBMVVFQ2hNVlZHaGxJRlZUUlZKVVVsVlRWQ0JPWlhSM2IzSnJNU0V3SHdZRFZRUUxFeGhvCitkSFJ3T2k4dmQzZDNMblZ6WlhKMGNuVnpkQzVqYjIweEt6QXBCZ05WQkFNVElsVlVUaTFWVTBWU1JtbHljM1F0CitUbVYwZDI5eWF5QkJjSEJzYVdOaGRHbHZibk13SGhjTk9Ua3dOekE1TVRnME9ETTVXaGNOTVRrd056QTVNVGcxCitOelE1V2pDQm96RUxNQWtHQTFVRUJoTUNWVk14Q3pBSkJnTlZCQWdUQWxWVU1SY3dGUVlEVlFRSEV3NVRZV3gwCitJRXhoYTJVZ1EybDBlVEVlTUJ3R0ExVUVDaE1WVkdobElGVlRSVkpVVWxWVFZDQk9aWFIzYjNKck1TRXdId1lECitWUVFMRXhob2RIUndPaTh2ZDNkM0xuVnpaWEowY25WemRDNWpiMjB4S3pBcEJnTlZCQU1USWxWVVRpMVZVMFZTCitSbWx5YzNRdFRtVjBkMjl5YXlCQmNIQnNhV05oZEdsdmJuTXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCitEd0F3Z2dFS0FvSUJBUUN6KzVHaDVEWlZoYXdHTkZ1Z21saXkrTFVQQlhlRHJqS3hkcEpvN0NOS3lYWS80NXkyCitOM2tEdWF0cGpRY2x0aGxuNUxBYkdITmhTdWgremRNdlpPT21mQXo2RjRDakRVZUpUMUZ4TCs3OFAvbTRGb0NICitpWk1sSUpwRGdta2tkaWhaTmFFZHdIK0RCbVFXSUN6VFNhU0Z0TUJoZjFFSStHZ1ZrWURMcGRYdU96cjBoQVJlCitZRm1uakRSeTdyaDR4ZEU3RWtwdmZtVW51YVJWeGJsdlE2VEZIU3lad0ZLa2VFd1ZzMENZQ0d0RHhnR3dlbnYxCitheHdpUDh2di82alFPa3QyRlo3UzBjWXU0OXRYR3pLaXVHL29ocVkvY0t2bGNKS3JSQjVBVVB1Y28yTGtiRzZnCit5TjdpZ0VMNjZTL296aklFajN5TnR4eWpOVHdWM1o3RHJwZWxBZ01CQUFHamdaRXdnWTR3Q3dZRFZSMFBCQVFECitBZ0hHTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRlBxR3lkdmd1dWw0OVV1bzFoWGY4TlBoCithaFE4TUU4R0ExVWRId1JJTUVZd1JLQkNvRUNHUG1oMGRIQTZMeTlqY213dWRYTmxjblJ5ZFhOMExtTnZiUzlWCitWRTR0VlZORlVrWnBjbk4wTFU1bGRIZHZjbXRCY0hCc2FXTmhkR2x2Ym5NdVkzSnNNQTBHQ1NxR1NJYjNEUUVCCitCUVVBQTRJQkFRQ2s4eVhNMGRTUmd5TFF6REtybTVaT05KRlVJQ1UwWVY4cUFoWGhpNnIvZldSUnp3ci92SDNZCitJV3A0eXk5UmIvaENIVE85NjdWN2xNUERxYUF0MzlFcEh4Mytqeis3cUVVcWY5RnVWU1RpdXdMN01UKys2THpzCitRQ3Y0QWRSV09PVEtSSUsxWVNBaFoyWDI4QXZuTlBpbHdweWpYRUFmaFpPVkJ0NVAxQ2VwdHFYOEZzMXpNVCs0CitaU2ZQMUZNYThLeHVuMDhGREFPQnA0UXB4RnE5WkZkeXJUdlBOeGltbU1hdEJyVGNDS01FMVNta2xwb1NaMHFNCitZRVdkOFNPYXNBQ2NhTFdZVU5QdmppNlNaYkZJUGlHK0ZUQXFEYlVNbzJzL3JuOVg5UitXZk45djNZSXdMR1ViCitRRXJOYUxseTdIRjI3RlNPSDRVTUFXcjZwamlzSDhTRQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgNDQ6YmU6MGM6OGI6NTA6MDA6MjQ6YjQ6MTE6ZDM6MzY6MzA6NGI6YzA6MzM6NzcKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgU1Q9VVQsIEw9U2FsdCBMYWtlIENpdHksIE89VGhlIFVTRVJUUlVTVCBOZXR3b3JrLCBPVT1odHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20sIENOPVVUTi1VU0VSRmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEp1bCAgOSAxODo0ODozOSAxOTk5IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogSnVsICA5IDE4OjU3OjQ5IDIwMTkgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIFNUPVVULCBMPVNhbHQgTGFrZSBDaXR5LCBPPVRoZSBVU0VSVFJVU1QgTmV0d29yaywgT1U9aHR0cDovL3d3dy51c2VydHJ1c3QuY29tLCBDTj1VVE4tVVNFUkZpcnN0LU5ldHdvcmsgQXBwbGljYXRpb25zCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpiMzpmYjo5MTphMTplNDozNjo1NTo4NTphYzowNjozNDo1YjphMDo5YToKKyAgICAgICAgICAgICAgICAgICAgNTg6YjI6Zjg6YjU6MGY6MDU6Nzc6ODM6YWU6MzI6YjE6NzY6OTI6Njg6ZWM6CisgICAgICAgICAgICAgICAgICAgIDIzOjRhOmM5Ojc2OjNmOmUzOjljOmI2OjM3Ojc5OjAzOmI5OmFiOjY5OjhkOgorICAgICAgICAgICAgICAgICAgICAwNzoyNTpiNjoxOTo2NzplNDpiMDoxYjoxODo3Mzo2MTo0YTplODo3ZTpjZDoKKyAgICAgICAgICAgICAgICAgICAgZDM6MmY6NjQ6ZTM6YTY6N2M6MGM6ZmE6MTc6ODA6YTM6MGQ6NDc6ODk6NGY6CisgICAgICAgICAgICAgICAgICAgIDUxOjcxOjJmOmVlOmZjOjNmOmY5OmI4OjE2OjgwOjg3Ojg5OjkzOjI1OjIwOgorICAgICAgICAgICAgICAgICAgICA5YTo0Mzo4Mjo2OToyNDo3NjoyODo1OTozNTphMToxZDpjMDo3Zjo4MzowNjoKKyAgICAgICAgICAgICAgICAgICAgNjQ6MTY6MjA6MmM6ZDM6NDk6YTQ6ODU6YjQ6YzA6NjE6N2Y6NTE6MDg6Zjg6CisgICAgICAgICAgICAgICAgICAgIDY4OjE1OjkxOjgwOmNiOmE1OmQ1OmVlOjNiOjNhOmY0Ojg0OjA0OjVlOjYwOgorICAgICAgICAgICAgICAgICAgICA1OTphNzo4YzozNDo3MjplZTpiODo3ODpjNTpkMTozYjoxMjo0YTo2Zjo3ZToKKyAgICAgICAgICAgICAgICAgICAgNjU6Mjc6Yjk6YTQ6NTU6YzU6Yjk6NmY6NDM6YTQ6YzU6MWQ6MmM6OTk6YzA6CisgICAgICAgICAgICAgICAgICAgIDUyOmE0Ojc4OjRjOjE1OmIzOjQwOjk4OjA4OjZiOjQzOmM2OjAxOmIwOjdhOgorICAgICAgICAgICAgICAgICAgICA3YjpmNTo2YjoxYzoyMjozZjpjYjplZjpmZjphODpkMDozYTo0Yjo3NjoxNToKKyAgICAgICAgICAgICAgICAgICAgOWU6ZDI6ZDE6YzY6MmU6ZTM6ZGI6NTc6MWI6MzI6YTI6Yjg6NmY6ZTg6ODY6CisgICAgICAgICAgICAgICAgICAgIGE2OjNmOjcwOmFiOmU1OjcwOjkyOmFiOjQ0OjFlOjQwOjUwOmZiOjljOmEzOgorICAgICAgICAgICAgICAgICAgICA2MjplNDo2Yzo2ZTphMDpjODpkZTplMjo4MDo0MjpmYTplOToyZjplODpjZToKKyAgICAgICAgICAgICAgICAgICAgMzI6MDQ6OGY6N2M6OGQ6Yjc6MWM6YTM6MzU6M2M6MTU6ZGQ6OWU6YzM6YWU6CisgICAgICAgICAgICAgICAgICAgIDk3OmE1CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IAorICAgICAgICAgICAgICAgIERpZ2l0YWwgU2lnbmF0dXJlLCBOb24gUmVwdWRpYXRpb24sIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEZBOjg2OkM5OkRCOkUwOkJBOkU5Ojc4OkY1OjRCOkE4OkQ2OjE1OkRGOkYwOkQzOkUxOjZBOjE0OjNDCisgICAgICAgICAgICBYNTA5djMgQ1JMIERpc3RyaWJ1dGlvbiBQb2ludHM6IAorICAgICAgICAgICAgICAgIFVSSTpodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1OZXR3b3JrQXBwbGljYXRpb25zLmNybAorCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIGE0OmYzOjI1OmNjOmQxOmQ0OjkxOjgzOjIyOmQwOmNjOjMyOmFiOjliOjk2OjRlOjM0OjkxOgorICAgICAgICA1NDoyMDoyNTozNDo2MTo1ZjoyYTowMjoxNTplMTo4YjphYTpmZjo3ZDo2NDo1MTpjZjowYToKKyAgICAgICAgZmY6YmM6N2Q6ZDg6MjE6NmE6Nzg6Y2I6MmY6NTE6NmY6Zjg6NDI6MWQ6MzM6YmQ6ZWI6YjU6CisgICAgICAgIDdiOjk0OmMzOmMzOmE5OmEwOjJkOmRmOmQxOjI5OjFmOjFkOmZlOjhmOjNmOmJiOmE4OjQ1OgorICAgICAgICAyYTo3ZjpkMTo2ZTo1NToyNDplMjpiYjowMjpmYjozMTozZjpiZTplODpiYzplYzo0MDoyYjoKKyAgICAgICAgZjg6MDE6ZDQ6NTY6Mzg6ZTQ6Y2E6NDQ6ODI6YjU6NjE6MjA6MjE6Njc6NjU6ZjY6ZjA6MGI6CisgICAgICAgIGU3OjM0OmY4OmE1OmMyOjljOmEzOjVjOjQwOjFmOjg1OjkzOjk1OjA2OmRlOjRmOmQ0OjI3OgorICAgICAgICBhOTpiNjphNTpmYzoxNjpjZDo3MzozMTozZjpiODo2NToyNzpjZjpkNDo1MzoxYTpmMDphYzoKKyAgICAgICAgNmU6OWY6NGY6MDU6MGM6MDM6ODE6YTc6ODQ6Mjk6YzQ6NWE6YmQ6NjQ6NTc6NzI6YWQ6M2I6CisgICAgICAgIGNmOjM3OjE4OmE2Ojk4OmM2OmFkOjA2OmI0OmRjOjA4OmEzOjA0OmQ1OjI5OmE0Ojk2OjlhOgorICAgICAgICAxMjo2Nzo0YTo4Yzo2MDo0NTo5ZDpmMToyMzo5YTpiMDowMDo5Yzo2ODpiNTo5ODo1MDpkMzoKKyAgICAgICAgZWY6OGU6MmU6OTI6NjU6YjE6NDg6M2U6MjE6YmU6MTU6MzA6MmE6MGQ6YjU6MGM6YTM6NmI6CisgICAgICAgIDNmOmFlOjdmOjU3OmY1OjFmOjk2OjdjOmRmOjZmOmRkOjgyOjMwOjJjOjY1OjFiOjQwOjRhOgorICAgICAgICBjZDo2ODpiOTo3MjplYzo3MTo3NjplYzo1NDo4ZToxZjo4NTowYzowMTo2YTpmYTphNjozODoKKyAgICAgICAgYWM6MWY6YzQ6ODQKK1NIQTEgRmluZ2VycHJpbnQ9NUQ6OTg6OUM6REI6MTU6OTY6MTE6MzY6NTE6NjU6NjQ6MUI6NTY6MEY6REI6RUE6MkE6QzI6M0U6RjEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9kYmM1NGNhYi4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2RiYzU0Y2FiLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTA1MDNkMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9kYmM1NGNhYi4wCkBAIC0wLDAgKzEsMTIwIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUZSakNDQXk2Z0F3SUJBZ0lJYll3VVJyR21DdTR3RFFZSktvWklodmNOQVFFTUJRQXdRVEVMTUFrR0ExVUUKK0JoTUNWVk14RkRBU0JnTlZCQW9NQzBGbVptbHliVlJ5ZFhOME1Sd3dHZ1lEVlFRRERCTkJabVpwY20xVWNuVnoKK2RDQlFjbVZ0YVhWdE1CNFhEVEV3TURFeU9URTBNVEF6TmxvWERUUXdNVEl6TVRFME1UQXpObG93UVRFTE1Ba0cKK0ExVUVCaE1DVlZNeEZEQVNCZ05WQkFvTUMwRm1abWx5YlZSeWRYTjBNUnd3R2dZRFZRUUREQk5CWm1acGNtMVUKK2NuVnpkQ0JRY21WdGFYVnRNSUlDSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQWc4QU1JSUNDZ0tDQWdFQXhCTGYKK3FWLytRZDNkOVorSzQvYXM0VHg0bXJ6WThIOTZvRE1xM0kwZ1c2NHRiK2VUMlRad2FtalBqbEdqaFZ0bkJLQVEKK0pHOWRLSUxCbDFmWVNDa1R0dUcra1UzZmhReFRHSm9lSktKUGovQ2loUXZMOUNsLzBxUlk3aVpOeWFxb2U1cloKKytqamVSRmNWNWZpTXlObEk0ZzBXSngwZXlJT0ZKYmU2cWxWQnpBTWlTeTJSall2bWlhOW14K24vSytrOHJOclMKK3M4UGhhSnlKK0hvQVZ0NzBWWlZzKzdwazNXS0wzd3QzTXV0aXpDYWFtN3VxWW9OTXRBWjZNTWdwdiswR1RaZTUKK0hNUXhLOVZmdkZNU0Y1eVpWeWxtZDJFaE1RY3VKVW1kR1BMdTh5dHhqTFc2T1FkSmQvenZMcEtRQlkwdEwzZDcKKzcwTy9OYnVhMlBsenB5enkwRmZ1S0U0bVg0K1FhQWt2dVBqY0J1a3VtajVScDlFaXhBcW5PRWhzcy9uL2ZhdUcKK1YrTzYxb1Y0ZDdwRDZraC85dGkrSTIwZXY5RTJiRmhjOGU2a0dWUWE5UVBTZHViaGpMMDhzOU5JUytMSStIK1MKK3FIWkduRUpsUHFRZXdRY0RXa1l0dUpmenQ5V3lWU0h2dXR4TUFKZjdGSlVuTTcvb1EwZEcwZ2laRm1BN21uN1MKKzV1MDQ2dXdCSGp4SVZra0p4MHczQUo2SURzQno0VzltNlhKSE1ENFE1UXNEeVpwQ0FHekZsSDVoeElyZmY0SWEKK0MxbkVXVEozczd4Z2FWWTUvYlFHZXl6V1pEYlp2VWp0aEI5K3BTS1BLcmhDOUlLMzFGT1FlRTR0R3YyQmIwVFgKK093RjBsa0xnQU9JdWErckY3bktzdTcvKzZxcW8rTnoyc25tS3RtY0NBd0VBQWFOQ01FQXdIUVlEVlIwT0JCWUUKK0ZKM0FaNllNSXRrbTlVV3JwbVZTRVNmWVJheGpNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEZ1lEVlIwUEFRSC8KK0JBUURBZ0VHTUEwR0NTcUdTSWIzRFFFQkRBVUFBNElDQVFDelYwMFFZazQ2NUt6cXVCeXZNaVBJczBsYVVaeDIKK0tJMTVxbGRHRjlYMVV2YTNST2dJUkw4WWhOSUxnTTNGRXYwQVZRVmhoMEhjdFNTZVBNVFl5UHR3bmk5NGxvTWcKK050NThEMmtUaUtWMU5wZ0lwc2Jmck03aldOYTNQdDY2OCtzMFFOaWlnZlY0UHkvVnBmelpvdFJlQkE0WHJmNUIKKzhPV3ljdnBFZ2pOQzZDMVk5MWFNWWorNlFyQ2NERngrTG1VbVhGTlBBTEo0ZnFFTm1TMk51QjJPb3NTdy9XRFEKK01LU095QVJpcWNUdE5kNTZsKzBPT0Y2U0w1TndwYW1jYjZkOUV4MSt4Z2hJc1Y1bjYxRUlKZW5tSld0U0taR2MKKzBqbHpDRmZlbVFhMFc1MFFCdUhDQUtpNEhFb0NDaFRRd1VISys0dzFJWDJDT1BLcFZKRVpOWk9VYldvNnhiTFEKK3U0bUdrK2lieVE4NnAzcTRvZkI0UnZyOE55L2xpb1R6My80RTJhRm9vQzhrNGdtVkJ0V1Z5dUVrbHV0ODlwTUYKK3UrMXo2UzNSZFRuWDV5VGIyRTVmUTQrZTBCUTV2MVZ3U0psWE1iU2M3a3FZQTVZd0gyQUc3aHNqL29GZ0l4cEgKK1lvV2x6QmswZ0crenJCcmpuL0I3U0szVkFkbG50cWx5aytvdFpyV3l1T1E5UExMdlRJenE2d2UvcXpXYVZZYTgKK0dLYTFxRjYwZzJ4cmFVRFRuOXp4dzJscnVlRnRDZlR4cWxCMkNucDllaGVoVlpaQ21URUozV0FSalFVd2Z1YU8KK1J0R2RGTnJIRitRRmxvekVKTFVienhRSHNrRDRvNTVCaHJ3RTBHdVd5Q3FBTlAyLzd3YWozVmpGaFQwK2ovNmUKK0tlQzJ1QWxvR1J3WVF3PT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDZkOjhjOjE0OjQ2OmIxOmE2OjBhOmVlCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTM4NFdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgTz1BZmZpcm1UcnVzdCwgQ049QWZmaXJtVHJ1c3QgUHJlbWl1bQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogSmFuIDI5IDE0OjEwOjM2IDIwMTAgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBEZWMgMzEgMTQ6MTA6MzYgMjA0MCBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgTz1BZmZpcm1UcnVzdCwgQ049QWZmaXJtVHJ1c3QgUHJlbWl1bQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDQwOTYgYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDQwOTYgYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YzQ6MTI6ZGY6YTk6NWY6ZmU6NDE6ZGQ6ZGQ6ZjU6OWY6OGE6ZTM6ZjY6CisgICAgICAgICAgICAgICAgICAgIGFjOmUxOjNjOjc4OjlhOmJjOmQ4OmYwOjdmOjdhOmEwOjMzOjJhOmRjOjhkOgorICAgICAgICAgICAgICAgICAgICAyMDo1YjphZToyZDo2ZjplNzo5MzpkOTozNjo3MDo2YTo2ODpjZjo4ZTo1MToKKyAgICAgICAgICAgICAgICAgICAgYTM6ODU6NWI6Njc6MDQ6YTA6MTA6MjQ6NmY6NWQ6Mjg6ODI6YzE6OTc6NTc6CisgICAgICAgICAgICAgICAgICAgIGQ4OjQ4OjI5OjEzOmI2OmUxOmJlOjkxOjRkOmRmOjg1OjBjOjUzOjE4OjlhOgorICAgICAgICAgICAgICAgICAgICAxZToyNDphMjo0Zjo4ZjpmMDphMjo4NTowYjpjYjpmNDoyOTo3ZjpkMjphNDoKKyAgICAgICAgICAgICAgICAgICAgNTg6ZWU6MjY6NGQ6Yzk6YWE6YTg6N2I6OWE6ZDk6ZmE6Mzg6ZGU6NDQ6NTc6CisgICAgICAgICAgICAgICAgICAgIDE1OmU1OmY4OjhjOmM4OmQ5OjQ4OmUyOjBkOjE2OjI3OjFkOjFlOmM4OjgzOgorICAgICAgICAgICAgICAgICAgICA4NToyNTpiNzpiYTphYTo1NTo0MTpjYzowMzoyMjo0YjoyZDo5MTo4ZDo4YjoKKyAgICAgICAgICAgICAgICAgICAgZTY6ODk6YWY6NjY6Yzc6ZTk6ZmY6MmI6ZTk6M2M6YWM6ZGE6ZDI6YjM6YzM6CisgICAgICAgICAgICAgICAgICAgIGUxOjY4OjljOjg5OmY4OjdhOjAwOjU2OmRlOmY0OjU1Ojk1OjZjOmZiOmJhOgorICAgICAgICAgICAgICAgICAgICA2NDpkZDo2Mjo4YjpkZjowYjo3NzozMjplYjo2MjpjYzoyNjo5YTo5YjpiYjoKKyAgICAgICAgICAgICAgICAgICAgYWE6NjI6ODM6NGM6YjQ6MDY6N2E6MzA6Yzg6Mjk6YmY6ZWQ6MDY6NGQ6OTc6CisgICAgICAgICAgICAgICAgICAgIGI5OjFjOmM0OjMxOjJiOmQ1OjVmOmJjOjUzOjEyOjE3OjljOjk5OjU3OjI5OgorICAgICAgICAgICAgICAgICAgICA2Njo3Nzo2MToyMTozMTowNzoyZToyNTo0OTo5ZDoxODpmMjplZTpmMzoyYjoKKyAgICAgICAgICAgICAgICAgICAgNzE6OGM6YjU6YmE6Mzk6MDc6NDk6Nzc6ZmM6ZWY6MmU6OTI6OTA6MDU6OGQ6CisgICAgICAgICAgICAgICAgICAgIDJkOjJmOjc3OjdiOmVmOjQzOmJmOjM1OmJiOjlhOmQ4OmY5OjczOmE3OjJjOgorICAgICAgICAgICAgICAgICAgICBmMjpkMDo1NzplZToyODo0ZToyNjo1Zjo4Zjo5MDo2ODowOToyZjpiODpmODoKKyAgICAgICAgICAgICAgICAgICAgZGM6MDY6ZTk6MmU6OWE6M2U6NTE6YTc6ZDE6MjI6YzQ6MGE6YTc6Mzg6NDg6CisgICAgICAgICAgICAgICAgICAgIDZjOmIzOmY5OmZmOjdkOmFiOjg2OjU3OmUzOmJhOmQ2Ojg1Ojc4Ojc3OmJhOgorICAgICAgICAgICAgICAgICAgICA0MzplYTo0ODo3ZjpmNjpkODpiZToyMzo2ZDoxZTpiZjpkMTozNjo2Yzo1ODoKKyAgICAgICAgICAgICAgICAgICAgNWM6ZjE6ZWU6YTQ6MTk6NTQ6MWE6ZjU6MDM6ZDI6NzY6ZTY6ZTE6OGM6YmQ6CisgICAgICAgICAgICAgICAgICAgIDNjOmIzOmQzOjQ4OjRiOmUyOmM4OmY4OjdmOjkyOmE4Ojc2OjQ2OjljOjQyOgorICAgICAgICAgICAgICAgICAgICA2NTozZTphNDoxZTpjMTowNzowMzo1YTo0NjoyZDpiODo5NzpmMzpiNzpkNToKKyAgICAgICAgICAgICAgICAgICAgYjI6NTU6MjE6ZWY6YmE6ZGM6NGM6MDA6OTc6ZmI6MTQ6OTU6Mjc6MzM6YmY6CisgICAgICAgICAgICAgICAgICAgIGU4OjQzOjQ3OjQ2OmQyOjA4Ojk5OjE2OjYwOjNiOjlhOjdlOmQyOmU2OmVkOgorICAgICAgICAgICAgICAgICAgICAzODplYTplYzowMToxZTozYzo0ODo1Njo0OTowOTpjNzo0YzozNzowMDo5ZToKKyAgICAgICAgICAgICAgICAgICAgODg6MGU6YzA6NzM6ZTE6NmY6NjY6ZTk6NzI6NDc6MzA6M2U6MTA6ZTU6MGI6CisgICAgICAgICAgICAgICAgICAgIDAzOmM5OjlhOjQyOjAwOjZjOmM1Ojk0OjdlOjYxOmM0OjhhOmRmOjdmOjgyOgorICAgICAgICAgICAgICAgICAgICAxYTowYjo1OTpjNDo1OTozMjo3NzpiMzpiYzo2MDo2OTo1NjozOTpmZDpiNDoKKyAgICAgICAgICAgICAgICAgICAgMDY6N2I6MmM6ZDY6NjQ6MzY6ZDk6YmQ6NDg6ZWQ6ODQ6MWY6N2U6YTU6MjI6CisgICAgICAgICAgICAgICAgICAgIDhmOjJhOmI4OjQyOmY0OjgyOmI3OmQ0OjUzOjkwOjc4OjRlOjJkOjFhOmZkOgorICAgICAgICAgICAgICAgICAgICA4MTo2Zjo0NDpkNzozYjowMTo3NDo5Njo0MjplMDowMDplMjoyZTo2YjplYToKKyAgICAgICAgICAgICAgICAgICAgYzU6ZWU6NzI6YWM6YmI6YmY6ZmU6ZWE6YWE6YTg6Zjg6ZGM6ZjY6YjI6Nzk6CisgICAgICAgICAgICAgICAgICAgIDhhOmI2OjY3CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICA5RDpDMDo2NzpBNjowQzoyMjpEOToyNjpGNTo0NTpBQjpBNjo2NTo1MjoxMToyNzpEODo0NTpBQzo2MworICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGEzODRXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBiMzo1Nzo0ZDoxMDo2Mjo0ZTozYTplNDphYzplYTpiODoxYzphZjozMjoyMzpjODpiMzo0OToKKyAgICAgICAgNWE6NTE6OWM6NzY6Mjg6OGQ6Nzk6YWE6NTc6NDY6MTc6ZDU6ZjU6NTI6ZjY6Yjc6NDQ6ZTg6CisgICAgICAgIDA4OjQ0OmJmOjE4Ojg0OmQyOjBiOjgwOmNkOmM1OjEyOmZkOjAwOjU1OjA1OjYxOjg3OjQxOgorICAgICAgICBkYzpiNToyNDo5ZTozYzpjNDpkODpjODpmYjo3MDo5ZToyZjo3ODo5Njo4MzoyMDozNjpkZToKKyAgICAgICAgN2M6MGY6Njk6MTM6ODg6YTU6NzU6MzY6OTg6MDg6YTY6YzY6ZGY6YWM6Y2U6ZTM6NTg6ZDY6CisgICAgICAgIGI3OjNlOmRlOmJhOmYzOmViOjM0OjQwOmQ4OmEyOjgxOmY1Ojc4OjNmOjJmOmQ1OmE1OmZjOgorICAgICAgICBkOTphMjpkNDo1ZTowNDowZToxNzphZDpmZTo0MTpmMDplNTpiMjo3MjpmYTo0NDo4MjozMzoKKyAgICAgICAgNDI6ZTg6MmQ6NTg6Zjc6NTY6OGM6NjI6M2Y6YmE6NDI6YjA6OWM6MGM6NWM6N2U6MmU6NjU6CisgICAgICAgIDI2OjVjOjUzOjRmOjAwOmIyOjc4OjdlOmExOjBkOjk5OjJkOjhkOmI4OjFkOjhlOmEyOmM0OgorICAgICAgICBiMDpmZDo2MDpkMDozMDphNDo4ZTpjODowNDo2MjphOTpjNDplZDozNTpkZTo3YTo5NzplZDoKKyAgICAgICAgMGU6Mzg6NWU6OTI6MmY6OTM6NzA6YTU6YTk6OWM6NmY6YTc6N2Q6MTM6MWQ6N2U6YzY6MDg6CisgICAgICAgIDQ4OmIxOjVlOjY3OmViOjUxOjA4OjI1OmU5OmU2OjI1OjZiOjUyOjI5OjkxOjljOmQyOjM5OgorICAgICAgICA3MzowODo1NzpkZTo5OTowNjpiNDo1Yjo5ZDoxMDowNjplMTpjMjowMDphODpiODoxYzo0YToKKyAgICAgICAgMDI6MGE6MTQ6ZDA6YzE6NDE6Y2E6ZmI6OGM6MzU6MjE6N2Q6ODI6Mzg6ZjI6YTk6NTQ6OTE6CisgICAgICAgIDE5OjM1OjkzOjk0OjZkOjZhOjNhOmM1OmIyOmQwOmJiOjg5Ojg2OjkzOmU4OjliOmM5OjBmOgorICAgICAgICAzYTphNzo3YTpiODphMTpmMDo3ODo0NjpmYTpmYzozNzoyZjplNTo4YTo4NDpmMzpkZjpmZToKKyAgICAgICAgMDQ6ZDk6YTE6Njg6YTA6MmY6MjQ6ZTI6MDk6OTU6MDY6ZDU6OTU6Y2E6ZTE6MjQ6OTY6ZWI6CisgICAgICAgIDdjOmY2OjkzOjA1OmJiOmVkOjczOmU5OjJkOmQxOjc1OjM5OmQ3OmU3OjI0OmRiOmQ4OjRlOgorICAgICAgICA1Zjo0Mzo4Zjo5ZTpkMDoxNDozOTpiZjo1NTo3MDo0ODo5OTo1NzozMTpiNDo5YzplZTo0YToKKyAgICAgICAgOTg6MDM6OTY6MzA6MWY6NjA6MDY6ZWU6MWI6MjM6ZmU6ODE6NjA6MjM6MWE6NDc6NjI6ODU6CisgICAgICAgIGE1OmNjOjE5OjM0OjgwOjZmOmIzOmFjOjFhOmUzOjlmOmYwOjdiOjQ4OmFkOmQ1OjAxOmQ5OgorICAgICAgICA2NzpiNjphOTo3Mjo5MzplYToyZDo2NjpiNTpiMjpiODplNDozZDozYzpiMjplZjo0Yzo4YzoKKyAgICAgICAgZWE6ZWI6MDc6YmY6YWI6MzU6OWE6NTU6ODY6YmM6MTg6YTY6YjU6YTg6NWU6YjQ6ODM6NmM6CisgICAgICAgIDZiOjY5OjQwOmQzOjlmOmRjOmYxOmMzOjY5OjZiOmI5OmUxOjZkOjA5OmY0OmYxOmFhOjUwOgorICAgICAgICA3NjowYTo3YTo3ZDo3YToxNzphMTo1NTo5Njo0Mjo5OTozMTowOTpkZDo2MDoxMTo4ZDowNToKKyAgICAgICAgMzA6N2U6ZTY6OGU6NDY6ZDE6OWQ6MTQ6ZGE6Yzc6MTc6ZTQ6MDU6OTY6OGM6YzQ6MjQ6YjU6CisgICAgICAgIDFiOmNmOjE0OjA3OmIyOjQwOmY4OmEzOjllOjQxOjg2OmJjOjA0OmQwOjZiOjk2OmM4OjJhOgorICAgICAgICA4MDozNDpmZDpiZjplZjowNjphMzpkZDo1ODpjNTo4NTozZDozZTo4ZjpmZTo5ZToyOTplMDoKKyAgICAgICAgYjY6Yjg6MDk6Njg6MTk6MWM6MTg6NDMKK1NIQTEgRmluZ2VycHJpbnQ9RDg6QTY6MzM6MkM6RTA6MDM6NkY6QjE6ODU6RjY6NjM6NEY6N0Q6NkE6MDY6NjU6MjY6MzI6Mjg6MjcKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9kZGMzMjhmZi4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2RkYzMyOGZmLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGNkOTg5NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9kZGMzMjhmZi4wCkBAIC0wLDAgKzEsNTYgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJREV6Q0NBbnlnQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFRRkFEQ0J4REVMTUFrR0ExVUVCaE1DV2tFeAorRlRBVEJnTlZCQWdUREZkbGMzUmxjbTRnUTJGd1pURVNNQkFHQTFVRUJ4TUpRMkZ3WlNCVWIzZHVNUjB3R3dZRAorVlFRS0V4UlVhR0YzZEdVZ1EyOXVjM1ZzZEdsdVp5QmpZekVvTUNZR0ExVUVDeE1mUTJWeWRHbG1hV05oZEdsdgorYmlCVFpYSjJhV05sY3lCRWFYWnBjMmx2YmpFWk1CY0dBMVVFQXhNUVZHaGhkM1JsSUZObGNuWmxjaUJEUVRFbQorTUNRR0NTcUdTSWIzRFFFSkFSWVhjMlZ5ZG1WeUxXTmxjblJ6UUhSb1lYZDBaUzVqYjIwd0hoY05PVFl3T0RBeAorTURBd01EQXdXaGNOTWpBeE1qTXhNak0xT1RVNVdqQ0J4REVMTUFrR0ExVUVCaE1DV2tFeEZUQVRCZ05WQkFnVAorREZkbGMzUmxjbTRnUTJGd1pURVNNQkFHQTFVRUJ4TUpRMkZ3WlNCVWIzZHVNUjB3R3dZRFZRUUtFeFJVYUdGMworZEdVZ1EyOXVjM1ZzZEdsdVp5QmpZekVvTUNZR0ExVUVDeE1mUTJWeWRHbG1hV05oZEdsdmJpQlRaWEoyYVdObAorY3lCRWFYWnBjMmx2YmpFWk1CY0dBMVVFQXhNUVZHaGhkM1JsSUZObGNuWmxjaUJEUVRFbU1DUUdDU3FHU0liMworRFFFSkFSWVhjMlZ5ZG1WeUxXTmxjblJ6UUhSb1lYZDBaUzVqYjIwd2daOHdEUVlKS29aSWh2Y05BUUVCQlFBRAorZ1kwQU1JR0pBb0dCQU5Pa1VHN0kvMVpyNXM5ZHR1b01hSFZIb3FyQzJvUWwvS2owUjFIYWhiVWdkSlNHSGc5MQoreWVrSVlmVUdiVEJ1RlJrQzZWTEFZdHRObVo3aWFneEVPTTMrdnVOa0NYREYvckZyS2JZdlNjZzcxQ2NFSlJDWAorTCtlUWJjQW9RcG5YVEVQZXcvVWhiVlNmWGNOWTRjRGsyVnV3dU55MGU5ODJPc0sxWmlJUzFvY05BZ01CQUFHagorRXpBUk1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUVCUUFEZ1lFQUIvcE1hVno3bGN4RworN29XRFRTRXdqc3JacUc5Skd1YmFVZU5nY0d5RVlSR2hHc2hJUGxsRGZVK1ZQYUdMdHd0aW1IcDFpdDJJVGs2ZQorUU51b3pESjB1VzhOeHVPelJBdlppbSthS1p1WkdDZzcwZU5BS0pwYVBOVzE1eUFiaThxa3E0M3BVZG5pVEN4WgorcWRxNXNuVWI5a0x5NzhmeUdQbUp2S1AvaWlNdWNFYz0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogMSAoMHgxKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBtZDVXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9WkEsIFNUPVdlc3Rlcm4gQ2FwZSwgTD1DYXBlIFRvd24sIE89VGhhd3RlIENvbnN1bHRpbmcgY2MsIE9VPUNlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24sIENOPVRoYXd0ZSBTZXJ2ZXIgQ0EvZW1haWxBZGRyZXNzPXNlcnZlci1jZXJ0c0B0aGF3dGUuY29tCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBBdWcgIDEgMDA6MDA6MDAgMTk5NiBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IERlYyAzMSAyMzo1OTo1OSAyMDIwIEdNVAorICAgICAgICBTdWJqZWN0OiBDPVpBLCBTVD1XZXN0ZXJuIENhcGUsIEw9Q2FwZSBUb3duLCBPPVRoYXd0ZSBDb25zdWx0aW5nIGNjLCBPVT1DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uLCBDTj1UaGF3dGUgU2VydmVyIENBL2VtYWlsQWRkcmVzcz1zZXJ2ZXItY2VydHNAdGhhd3RlLmNvbQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDEwMjQgYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDEwMjQgYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6ZDM6YTQ6NTA6NmU6Yzg6ZmY6NTY6NmI6ZTY6Y2Y6NWQ6YjY6ZWE6MGM6CisgICAgICAgICAgICAgICAgICAgIDY4Ojc1OjQ3OmEyOmFhOmMyOmRhOjg0OjI1OmZjOmE4OmY0OjQ3OjUxOmRhOgorICAgICAgICAgICAgICAgICAgICA4NTpiNToyMDo3NDo5NDo4NjoxZTowZjo3NTpjOTplOTowODo2MTpmNTowNjoKKyAgICAgICAgICAgICAgICAgICAgNmQ6MzA6NmU6MTU6MTk6MDI6ZTk6NTI6YzA6NjI6ZGI6NGQ6OTk6OWU6ZTI6CisgICAgICAgICAgICAgICAgICAgIDZhOjBjOjQ0OjM4OmNkOmZlOmJlOmUzOjY0OjA5OjcwOmM1OmZlOmIxOjZiOgorICAgICAgICAgICAgICAgICAgICAyOTpiNjoyZjo0OTpjODozYjpkNDoyNzowNDoyNToxMDo5NzoyZjplNzo5MDoKKyAgICAgICAgICAgICAgICAgICAgNmQ6YzA6Mjg6NDI6OTk6ZDc6NGM6NDM6ZGU6YzM6ZjU6MjE6NmQ6NTQ6OWY6CisgICAgICAgICAgICAgICAgICAgIDVkOmMzOjU4OmUxOmMwOmU0OmQ5OjViOmIwOmI4OmRjOmI0OjdiOmRmOjM2OgorICAgICAgICAgICAgICAgICAgICAzYTpjMjpiNTo2NjoyMjoxMjpkNjo4NzowZAorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IG1kNVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDA3OmZhOjRjOjY5OjVjOmZiOjk1OmNjOjQ2OmVlOjg1OjgzOjRkOjIxOjMwOjhlOmNhOmQ5OgorICAgICAgICBhODo2Zjo0OToxYTplNjpkYTo1MTplMzo2MDo3MDo2Yzo4NDo2MToxMTphMToxYTpjODo0ODoKKyAgICAgICAgM2U6NTk6NDM6N2Q6NGY6OTU6M2Q6YTE6OGI6Yjc6MGI6NjI6OTg6N2E6NzU6OGE6ZGQ6ODg6CisgICAgICAgIDRlOjRlOjllOjQwOmRiOmE4OmNjOjMyOjc0OmI5OjZmOjBkOmM2OmUzOmIzOjQ0OjBiOmQ5OgorICAgICAgICA4YTo2Zjo5YToyOTo5Yjo5OToxODoyODozYjpkMTplMzo0MDoyODo5YTo1YTozYzpkNTpiNToKKyAgICAgICAgZTc6MjA6MWI6OGI6Y2E6YTQ6YWI6OGQ6ZTk6NTE6ZDk6ZTI6NGM6MmM6NTk6YTk6ZGE6Yjk6CisgICAgICAgIGIyOjc1OjFiOmY2OjQyOmYyOmVmOmM3OmYyOjE4OmY5Ojg5OmJjOmEzOmZmOjhhOjIzOjJlOgorICAgICAgICA3MDo0NworU0hBMSBGaW5nZXJwcmludD0yMzpFNTo5NDo5NDo1MTo5NTpGMjo0MTo0ODowMzpCNDpENTo2NDpEMjpBMzpBMzpGNTpEODo4Qjo4QwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2U0ODE5M2NmLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZTQ4MTkzY2YuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMzVjYTNiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2U0ODE5M2NmLjAKQEAgLTAsMCArMSw3OCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEVERDQ0FqU2dBd0lCQWdJSWQzY0dKeWFwc1h3d0RRWUpLb1pJaHZjTkFRRUxCUUF3UkRFTE1Ba0dBMVVFCitCaE1DVlZNeEZEQVNCZ05WQkFvTUMwRm1abWx5YlZSeWRYTjBNUjh3SFFZRFZRUUREQlpCWm1acGNtMVVjblZ6CitkQ0JEYjIxdFpYSmphV0ZzTUI0WERURXdNREV5T1RFME1EWXdObG9YRFRNd01USXpNVEUwTURZd05sb3dSREVMCitNQWtHQTFVRUJoTUNWVk14RkRBU0JnTlZCQW9NQzBGbVptbHliVlJ5ZFhOME1SOHdIUVlEVlFRRERCWkJabVpwCitjbTFVY25WemRDQkRiMjF0WlhKamFXRnNNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDCitBUUVBOWh0UFp3Y3JvUlgxQmlMTEh3R3k0M05GQmtSSkxMdEpKUlRXenNPM3F5eFB4a0V5bEZmNkVxZGJEdUtQCitIeDZHR2FlcXRTMjVYdzJLd3ErRk5Ya3lMYnNjWWpmeXNWdEtQY3JOY1YvcFFyNlU2TWplK1NKSVpNYmxxOFlyCitiYTBGOFByVkM4K2E1ZkJRcElzN1I2VWpXM3A2K0RNL3VPK1psK01nd2RZb2ljK1UrN2xGN2VOQUZ4SFVkUEFMCitNZUlySm1xYlRGZXVyQ0ErdWtWNkJmTzltMmtWcm4xT0lHUEVOWFk2QndMSk4vM0hSKzdvOFhZZGN4WHlsNlMxCit5SHA1MlVLcUszOWMvczRtVDZObWdUV3ZSTHBVSGh3d01tV2Q1anlUWGxCT2V1TTYxRzdNR3Z2NTBqZXVKQ3FyCitWd01pS0ExSmRYKzNLTnAxdjQ3ajNBNTVNUUlEQVFBQm8wSXdRREFkQmdOVkhRNEVGZ1FVblpQR1U0dGV5cTgvCitueDRQNVptVnZDVDJsSTh3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFQkFNQ0FRWXdEUVlKCitLb1pJaHZjTkFRRUxCUUFEZ2dFQkFGaXM5QVFPemNBTi93cjkxTG9XWHltOWUyaVpXRW5TdEIwM1RYOG5mVVlHCitYVVBHaGk0K2M3SW1mVStUcWJiRUtwcXJJWmNVc2Q2TTA2dUpGZGhySk5UeEZxN1lwRnpVZjFHTzdSZ0JzWk5qCit2Yno0WVlDYW5ySE9RbkRpcVgwR0pYMG5vZjV2N0xNZUpOcmpTMVVhQURzMXREdloxMTB3L1lFVGlmTENCaXZ0CitaOFNPeVVPeVhHc1ZpUUs4WXZ4TzhyVXpxckp2MHdxaVVPUDJPK2d1Uk1MYlpqaXBNMVpJOFcwYk00ME5qRDlnCitONTNUeW0xK05INE5uM0oyaXh1ZmN2MVNOVUZGQXBZdkhMS2FjMGtoc1VsSFJVZTA3Mm8wRWNsTm1zeFp0OVlDCitubHBPWmJXVXJodmZLYkFXOGI4QW5nYzZGMlMxQkxVaklaa0tsVHVYZk84PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgNzc6Nzc6MDY6Mjc6MjY6YTk6YjE6N2MKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPUFmZmlybVRydXN0LCBDTj1BZmZpcm1UcnVzdCBDb21tZXJjaWFsCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBKYW4gMjkgMTQ6MDY6MDYgMjAxMCBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IERlYyAzMSAxNDowNjowNiAyMDMwIEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPUFmZmlybVRydXN0LCBDTj1BZmZpcm1UcnVzdCBDb21tZXJjaWFsCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpmNjoxYjo0Zjo2NzowNzoyYjphMToxNTpmNTowNjoyMjpjYjoxZjowMToKKyAgICAgICAgICAgICAgICAgICAgYjI6ZTM6NzM6NDU6MDY6NDQ6NDk6MmM6YmI6NDk6MjU6MTQ6ZDY6Y2U6YzM6CisgICAgICAgICAgICAgICAgICAgIGI3OmFiOjJjOjRmOmM2OjQxOjMyOjk0OjU3OmZhOjEyOmE3OjViOjBlOmUyOgorICAgICAgICAgICAgICAgICAgICA4ZjoxZjoxZTo4NjoxOTphNzphYTpiNToyZDpiOTo1ZjowZDo4YTpjMjphZjoKKyAgICAgICAgICAgICAgICAgICAgODU6MzU6Nzk6MzI6MmQ6YmI6MWM6NjI6Mzc6ZjI6YjE6NWI6NGE6M2Q6Y2E6CisgICAgICAgICAgICAgICAgICAgIGNkOjcxOjVmOmU5OjQyOmJlOjk0OmU4OmM4OmRlOmY5OjIyOjQ4OjY0OmM2OgorICAgICAgICAgICAgICAgICAgICBlNTphYjpjNjoyYjo2ZDphZDowNTpmMDpmYTpkNTowYjpjZjo5YTplNTpmMDoKKyAgICAgICAgICAgICAgICAgICAgNTA6YTQ6OGI6M2I6NDc6YTU6MjM6NWI6N2E6N2E6Zjg6MzM6M2Y6Yjg6ZWY6CisgICAgICAgICAgICAgICAgICAgIDk5Ojk3OmUzOjIwOmMxOmQ2OjI4Ojg5OmNmOjk0OmZiOmI5OjQ1OmVkOmUzOgorICAgICAgICAgICAgICAgICAgICA0MDoxNzoxMTpkNDo3NDpmMDowYjozMTplMjoyYjoyNjo2YTo5Yjo0Yzo1NzoKKyAgICAgICAgICAgICAgICAgICAgYWU6YWM6MjA6M2U6YmE6NDU6N2E6MDU6ZjM6YmQ6OWI6Njk6MTU6YWU6N2Q6CisgICAgICAgICAgICAgICAgICAgIDRlOjIwOjYzOmM0OjM1Ojc2OjNhOjA3OjAyOmM5OjM3OmZkOmM3OjQ3OmVlOgorICAgICAgICAgICAgICAgICAgICBlODpmMTo3NjoxZDo3MzoxNTpmMjo5NzphNDpiNTpjODo3YTo3OTpkOTo0MjoKKyAgICAgICAgICAgICAgICAgICAgYWE6MmI6N2Y6NWM6ZmU6Y2U6MjY6NGY6YTM6NjY6ODE6MzU6YWY6NDQ6YmE6CisgICAgICAgICAgICAgICAgICAgIDU0OjFlOjFjOjMwOjMyOjY1OjlkOmU2OjNjOjkzOjVlOjUwOjRlOjdhOmUzOgorICAgICAgICAgICAgICAgICAgICAzYTpkNDo2ZTpjYzoxYTpmYjpmOTpkMjozNzphZToyNDoyYTphYjo1NzowMzoKKyAgICAgICAgICAgICAgICAgICAgMjI6Mjg6MGQ6NDk6NzU6N2Y6Yjc6Mjg6ZGE6NzU6YmY6OGU6ZTM6ZGM6MGU6CisgICAgICAgICAgICAgICAgICAgIDc5OjMxCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICA5RDo5MzpDNjo1Mzo4Qjo1RTpDQTpBRjozRjo5RjoxRTowRjpFNTo5OTo5NTpCQzoyNDpGNjo5NDo4RgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA1ODphYzpmNDowNDowZTpjZDpjMDowZDpmZjowYTpmZDpkNDpiYToxNjo1ZjoyOTpiZDo3YjoKKyAgICAgICAgNjg6OTk6NTg6NDk6ZDI6YjQ6MWQ6Mzc6NGQ6N2Y6Mjc6N2Q6NDY6MDY6NWQ6NDM6YzY6ODY6CisgICAgICAgIDJlOjNlOjczOmIyOjI2OjdkOjRmOjkzOmE5OmI2OmM0OjJhOjlhOmFiOjIxOjk3OjE0OmIxOgorICAgICAgICBkZTo4YzpkMzphYjo4OToxNTpkODo2YjoyNDpkNDpmMToxNjphZTpkODphNDo1YzpkNDo3ZjoKKyAgICAgICAgNTE6OGU6ZWQ6MTg6MDE6YjE6OTM6NjM6YmQ6YmM6Zjg6NjE6ODA6OWE6OWU6YjE6Y2U6NDI6CisgICAgICAgIDcwOmUyOmE5OjdkOjA2OjI1OjdkOjI3OmExOmZlOjZmOmVjOmIzOjFlOjI0OmRhOmUzOjRiOgorICAgICAgICA1NToxYTowMDozYjozNTpiNDozYjpkOTpkNzo1ZDozMDpmZDo4MToxMzo4OTpmMjpjMjowNjoKKyAgICAgICAgMmI6ZWQ6Njc6YzQ6OGU6Yzk6NDM6YjI6NWM6NmI6MTU6ODk6MDI6YmM6NjI6ZmM6NGU6ZjI6CisgICAgICAgIGI1OjMzOmFhOmIyOjZmOmQzOjBhOmEyOjUwOmUzOmY2OjNiOmU4OjJlOjQ0OmMyOmRiOjY2OgorICAgICAgICAzODphOTozMzo1Njo0ODpmMTo2ZDoxYjozMzo4ZDowZDo4YzozZjo2MDozNzo5ZDpkMzpjYToKKyAgICAgICAgNmQ6N2U6MzQ6N2U6MGQ6OWY6NzI6NzY6OGI6MWI6OWY6NzI6ZmQ6NTI6MzU6NDE6NDU6MDI6CisgICAgICAgIDk2OjJmOjFjOmIyOjlhOjczOjQ5OjIxOmIxOjQ5OjQ3OjQ1OjQ3OmI0OmVmOjZhOjM0OjExOgorICAgICAgICBjOTo0ZDo5YTpjYzo1OTpiNzpkNjowMjo5ZTo1YTo0ZTo2NTpiNTo5NDphZToxYjpkZjoyOToKKyAgICAgICAgYjA6MTY6ZjE6YmY6MDA6OWU6MDc6M2E6MTc6NjQ6YjU6MDQ6YjU6MjM6MjE6OTk6MGE6OTU6CisgICAgICAgIDNiOjk3OjdjOmVmCitTSEExIEZpbmdlcnByaW50PUY5OkI1OkI2OjMyOjQ1OjVGOjlDOkJFOkVDOjU3OjVGOjgwOkRDOkU5OjZFOjJDOkM3OkIyOjc4OkI3CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZTYwYmYwYzAuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9lNjBiZjBjMC4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5MzQzOTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZTYwYmYwYzAuMApAQCAtMCwwICsxLDEyOCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlGMlRDQ0E4R2dBd0lCQWdJUVhBdUZYQXZuV1VIZlY4dy9mNTJvTmpBTkJna3Foa2lHOXcwQkFRVUZBREJrCitNUXN3Q1FZRFZRUUdFd0pqYURFUk1BOEdBMVVFQ2hNSVUzZHBjM05qYjIweEpUQWpCZ05WQkFzVEhFUnBaMmwwCitZV3dnUTJWeWRHbG1hV05oZEdVZ1UyVnlkbWxqWlhNeEd6QVpCZ05WQkFNVEVsTjNhWE56WTI5dElGSnZiM1FnCitRMEVnTVRBZUZ3MHdOVEE0TVRneE1qQTJNakJhRncweU5UQTRNVGd5TWpBMk1qQmFNR1F4Q3pBSkJnTlZCQVlUCitBbU5vTVJFd0R3WURWUVFLRXdoVGQybHpjMk52YlRFbE1DTUdBMVVFQ3hNY1JHbG5hWFJoYkNCRFpYSjBhV1pwCitZMkYwWlNCVFpYSjJhV05sY3pFYk1Ca0dBMVVFQXhNU1UzZHBjM05qYjIwZ1VtOXZkQ0JEUVNBeE1JSUNJakFOCitCZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUEwTG13cUF6WnV6OGgrQnZWTTVPQUZtVWdkYkk5CittMkJ0UnNpTU1XOFh3L3FhYkZidFBNV1JWOFBOcTVaSmtDb1pTeDZqYlZmZDhTdGlLSFZGWHFyV1cvb0xKZGloCitGdmtjeEM3bWxTcG56TkFwYmp5Rk5EaGhTYkVBbjlZNmNWOU5iYzVmdWFua2lYOXFVdnJLbS9MY3FmbWRtVWMvCitUaWxmdEthTlhYc0xtUkVEQS83bjI5dWoveDJselpBZUFSODFzSDhBMjVCdnhuNTcwZTU2ZXFlcURGZHZwRzNGCitFenV3cGRudE1oeTBYbWVMVk54emgrWFRGM3htVUhKZDFCcFl3ZG5QMklrQ2I2ZEp0RFpkMEtUZUJ5eTJkYmNvCitrZGFYdmlqMW1CN3FXeWJKdmJDWGM5cXVrU2JyYU1INU9SWFdaMHNLYlUvTHo3RGtRbkdNVTNubjd1SGJIYUJ1CitIWXdhZHpWY0ZoNHJVeDgwaTlGcy9QSm5CM3IxcmUzV21xdWhzVXZoekRkZi9YL05UYTY0SDV4RCtTcFlWVU5GCit2SmJOY0E3OHllTm11azZOTzRITEZXUjd1WlRvWFROU2hYRXVUNDZpQmhGUnllUExvVzR4Q0dRTXd0STg5VGJvCisxOUFPZUNNZ2tja2tLbVVwV3lMM0ljNkRYcVR6M2t2VGFJOUdkVnlEQ1c0cGE4UndqUFdkMXlBdi8wYlNLempDCitMM1VjUFg3YXBlOGVZSVZwUXRQTStHUCtIa001aGFhMlkwRVFzM01ldk5QNnluMFdSK0tuMWRDamlnb0lsbUpXCitialRiMlFLNU1IWGpCTkxuajhLd0VVQUtyTlZ4QW1LTE1iN2R4aU5ZTVVKRExYVDV4cDZtaWcvcC9yK0Q1a05YCitKTHJ2UmpTcTF4SUJPTzBDQXdFQUFhT0JoakNCZ3pBT0JnTlZIUThCQWY4RUJBTUNBWVl3SFFZRFZSMGhCQll3CitGREFTQmdkZ2hYUUJVd0FCQmdkZ2hYUUJVd0FCTUJJR0ExVWRFd0VCL3dRSU1BWUJBZjhDQVFjd0h3WURWUjBqCitCQmd3Rm9BVUF5VXYzbStDQVRwY0xOd3JvV20xWjlTTTAvMHdIUVlEVlIwT0JCWUVGQU1sTDk1dmdnRTZYQ3pjCitLNkZwdFdmVWpOUDlNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUNBUUExRU12c3BnUU5EUS9Od051cnFQS0lsd3pmCitreTlOZkVCV01YcnJwQTlnelhyenZzTW5qZ00rcE4wUzczNGVkQVk4UHpIeUhIdVJNU0cwOE5Cc2w5VHBsN0lrCitWaDVXd3pXOWlBVVBXeEFhWk9ISGdqRDVNcTJlVUN6bmVBWFFNYkZhbUlwMVRwQmNhaFFxNEZKSGdtRG1IdHFCCitzZnNVQzFyeG45S1Z1ajdRRzlZVkhhTytodFhiRDhCSlpMc3VVQmxMMGlUNDNSNEhWdEE0b0pWd0lIYU0xOTBlCiszcDl4eENQdmd4TmNveVFWVFNsQVBHckVxZGkzcGtTbERmVGduWGNlUUhBbS9OclpOdVI1NUxVL3ZKdGx2cnNSCitscy9ieGlnNU9nak9SMXRUV3NXWi9sMnAzZTlNMU1hbHJRTG1qQWNTSG04RDBXK2dvL01wdlJMSFVLS3dmNGlwCittWGVhc2NDbE9TNWNmR25pTExEcU4ycWs0VnJoOVZEbGcrK2x1eXFJNTR6Yi9XMWVseG1vZm1aMWEzSHF2N0hICitiNkQwanFUc05GRmJqQ1lEY0tGMzFRRVNWd0ExMnlQZURvb29tZjJ4RUc5TC96Z3RZRTRzbk90bnRhMUo3a3NmCitySy83RFpCYVptQndYYXJOZU5RazdzaEJvSk1Ca3B4cW52eTVKTVd6RllKK3ZxNlZLK3V4d05yakFXQUxYbW1zCitoRlpodm5FWC9oMFRELzdHaDBYcC9qS2dHZzBUcEpSVmNhVVdpN3JLaWJDeXgveVAyRlMxazJLZHpzOVorejBZCit6aXJMTlJXQ1hmOVVJbHR4VXZ1M3lmNWdtd0JCWlBDcUt1eTJRa1BPaVdhQnlJdWZPVlFESmRNV05ZNkUwRi82CitNQnIxbW16MERsUDVPbHZSSEE9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgNWM6MGI6ODU6NWM6MGI6ZTc6NTk6NDE6ZGY6NTc6Y2M6M2Y6N2Y6OWQ6YTg6MzYKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1jaCwgTz1Td2lzc2NvbSwgT1U9RGlnaXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlcywgQ049U3dpc3Njb20gUm9vdCBDQSAxCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBBdWcgMTggMTI6MDY6MjAgMjAwNSBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEF1ZyAxOCAyMjowNjoyMCAyMDI1IEdNVAorICAgICAgICBTdWJqZWN0OiBDPWNoLCBPPVN3aXNzY29tLCBPVT1EaWdpdGFsIENlcnRpZmljYXRlIFNlcnZpY2VzLCBDTj1Td2lzc2NvbSBSb290IENBIDEKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICg0MDk2IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICg0MDk2IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmQwOmI5OmIwOmE4OjBjOmQ5OmJiOjNmOjIxOmY4OjFiOmQ1OjMzOjkzOgorICAgICAgICAgICAgICAgICAgICA4MDoxNjo2NToyMDo3NTpiMjozZDo5Yjo2MDo2ZDo0NjpjODo4YzozMTo2ZjoKKyAgICAgICAgICAgICAgICAgICAgMTc6YzM6ZmE6OWE6NmM6NTY6ZWQ6M2M6YzU6OTE6NTc6YzM6Y2Q6YWI6OTY6CisgICAgICAgICAgICAgICAgICAgIDQ5OjkwOjJhOjE5OjRiOjFlOmEzOjZkOjU3OmRkOmYxOjJiOjYyOjI4Ojc1OgorICAgICAgICAgICAgICAgICAgICA0NTo1ZTphYTpkNjo1YjpmYTowYjoyNTpkODphMToxNjpmOToxYzpjNDoyZToKKyAgICAgICAgICAgICAgICAgICAgZTY6OTU6MmE6Njc6Y2M6ZDA6Mjk6NmU6M2M6ODU6MzQ6Mzg6NjE6NDk6YjE6CisgICAgICAgICAgICAgICAgICAgIDAwOjlmOmQ2OjNhOjcxOjVmOjRkOjZkOmNlOjVmOmI5OmE5OmU0Ojg5OjdmOgorICAgICAgICAgICAgICAgICAgICA2YTo1MjpmYTpjYTo5YjpmMjpkYzphOTpmOTo5ZDo5OTo0NzozZjo0ZToyOToKKyAgICAgICAgICAgICAgICAgICAgNWY6YjQ6YTY6OGQ6NWQ6N2I6MGI6OTk6MTE6MDM6MDM6ZmU6ZTc6ZGI6ZGI6CisgICAgICAgICAgICAgICAgICAgIGEzOmZmOjFkOmE1OmNkOjkwOjFlOjAxOjFmOjM1OmIwOjdmOjAwOmRiOjkwOgorICAgICAgICAgICAgICAgICAgICA2ZjpjNjo3ZTo3YjpkMTplZTo3YTo3YTphNzphYTowYzo1Nzo2ZjphNDo2ZDoKKyAgICAgICAgICAgICAgICAgICAgYzU6MTM6M2I6YjA6YTU6ZDk6ZWQ6MzI6MWM6YjQ6NWU6Njc6OGI6NTQ6ZGM6CisgICAgICAgICAgICAgICAgICAgIDczOjg3OmU1OmQzOjE3OjdjOjY2OjUwOjcyOjVkOmQ0OjFhOjU4OmMxOmQ5OgorICAgICAgICAgICAgICAgICAgICBjZjpkODo4OTowMjo2ZjphNzo0OTpiNDozNjo1ZDpkMDphNDpkZTowNzoyYzoKKyAgICAgICAgICAgICAgICAgICAgYjY6NzU6Yjc6Mjg6OTE6ZDY6OTc6YmU6Mjg6ZjU6OTg6MWU6ZWE6NWI6MjY6CisgICAgICAgICAgICAgICAgICAgIGM5OmJkOmIwOjk3OjczOmRhOmFlOjkxOjI2OmViOjY4OmMxOmY5OjM5OjE1OgorICAgICAgICAgICAgICAgICAgICBkNjo2Nzo0YjowYTo2ZDo0ZjpjYjpjZjpiMDplNDo0Mjo3MTo4Yzo1Mzo3OToKKyAgICAgICAgICAgICAgICAgICAgZTc6ZWU6ZTE6ZGI6MWQ6YTA6NmU6MWQ6OGM6MWE6Nzc6MzU6NWM6MTY6MWU6CisgICAgICAgICAgICAgICAgICAgIDJiOjUzOjFmOjM0OjhiOmQxOjZjOmZjOmYyOjY3OjA3OjdhOmY1OmFkOmVkOgorICAgICAgICAgICAgICAgICAgICBkNjo5YTphYjphMTpiMTo0YjplMTpjYzozNzo1ZjpmZDo3ZjpjZDo0ZDphZToKKyAgICAgICAgICAgICAgICAgICAgYjg6MWY6OWM6NDM6Zjk6MmE6NTg6NTU6NDM6NDU6YmM6OTY6Y2Q6NzA6MGU6CisgICAgICAgICAgICAgICAgICAgIGZjOmM5OmUzOjY2OmJhOjRlOjhkOjNiOjgxOmNiOjE1OjY0OjdiOmI5Ojk0OgorICAgICAgICAgICAgICAgICAgICBlODo1ZDozMzo1Mjo4NTo3MToyZTo0Zjo4ZTphMjowNjoxMTo1MTpjOTplMzoKKyAgICAgICAgICAgICAgICAgICAgY2I6YTE6NmU6MzE6MDg6NjQ6MGM6YzI6ZDI6M2M6ZjU6MzY6ZTg6ZDc6ZDA6CisgICAgICAgICAgICAgICAgICAgIDBlOjc4OjIzOjIwOjkxOmM5OjI0OjJhOjY1OjI5OjViOjIyOmY3OjIxOmNlOgorICAgICAgICAgICAgICAgICAgICA4Mzo1ZTphNDpmMzpkZTo0YjpkMzo2ODo4Zjo0Njo3NTo1Yzo4MzowOTo2ZToKKyAgICAgICAgICAgICAgICAgICAgMjk6NmI6YzQ6NzA6OGM6ZjU6OWQ6ZDc6MjA6MmY6ZmY6NDY6ZDI6MmI6Mzg6CisgICAgICAgICAgICAgICAgICAgIGMyOjJmOjc1OjFjOjNkOjdlOmRhOmE1OmVmOjFlOjYwOjg1OjY5OjQyOmQzOgorICAgICAgICAgICAgICAgICAgICBjYzpmODo2MzpmZToxZTo0MzozOTo4NTphNjpiNjo2Mzo0MToxMDpiMzo3MzoKKyAgICAgICAgICAgICAgICAgICAgMWU6YmM6ZDM6ZmE6Y2E6N2Q6MTY6NDc6ZTI6YTc6ZDU6ZDA6YTM6OGE6MGE6CisgICAgICAgICAgICAgICAgICAgIDA4Ojk2OjYyOjU2OjZlOjM0OmRiOmQ5OjAyOmI5OjMwOjc1OmUzOjA0OmQyOgorICAgICAgICAgICAgICAgICAgICBlNzo4ZjpjMjpiMDoxMTo0MDowYTphYzpkNTo3MTowMjo2Mjo4YjozMTpiZToKKyAgICAgICAgICAgICAgICAgICAgZGQ6YzY6MjM6NTg6MzE6NDI6NDM6MmQ6NzQ6Zjk6YzY6OWU6YTY6OGE6MGY6CisgICAgICAgICAgICAgICAgICAgIGU5OmZlOmJmOjgzOmU2OjQzOjU3OjI0OmJhOmVmOjQ2OjM0OmFhOmQ3OjEyOgorICAgICAgICAgICAgICAgICAgICAwMTozODplZAorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIERpZ2l0YWwgU2lnbmF0dXJlLCBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIFBvbGljeSBNYXBwaW5nczogCisgICAgICAgICAgICAgICAgMi4xNi43NTYuMS44My4wLjE6Mi4xNi43NTYuMS44My4wLjEKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFLCBwYXRobGVuOjcKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOjAzOjI1OjJGOkRFOjZGOjgyOjAxOjNBOjVDOjJDOkRDOjJCOkExOjY5OkI1OjY3OkQ0OjhDOkQzOkZECisKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICAwMzoyNToyRjpERTo2Rjo4MjowMTozQTo1QzoyQzpEQzoyQjpBMTo2OTpCNTo2NzpENDo4QzpEMzpGRAorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAzNToxMDpjYjplYzphNjowNDowZDowZDowZjpjZDpjMDpkYjphYjphODpmMjo4ODo5NzowYzoKKyAgICAgICAgZGY6OTM6MmY6NGQ6N2M6NDA6NTY6MzE6N2E6ZWI6YTQ6MGY6NjA6Y2Q6N2E6ZjM6YmU6YzM6CisgICAgICAgIDI3OjhlOjAzOjNlOmE0OmRkOjEyOmVmOjdlOjFlOjc0OjA2OjNjOjNmOjMxOmYyOjFjOjdiOgorICAgICAgICA5MTozMToyMTpiNDpmMDpkMDo2Yzo5NzpkNDplOTo5NzpiMjoyNDo1NjoxZTo1NjpjMzozNToKKyAgICAgICAgYmQ6ODg6MDU6MGY6NWI6MTA6MWE6NjQ6ZTE6Yzc6ODI6MzA6Zjk6MzI6YWQ6OWU6NTA6MmM6CisgICAgICAgIGU3Ojc4OjA1OmQwOjMxOmIxOjVhOjk4OjhhOjc1OjRlOjkwOjVjOjZhOjE0OjJhOmUwOjUyOgorICAgICAgICA0Nzo4Mjo2MDplNjoxZTpkYTo4MTpiMTpmYjoxNDowYjo1YTpmMTo5ZjpkMjo5NTpiYTozZToKKyAgICAgICAgZDA6MWI6ZDY6MTU6MWQ6YTM6YmU6ODY6ZDU6ZGI6MGY6YzA6NDk6NjQ6YmI6MmU6NTA6MTk6CisgICAgICAgIDRiOmQyOjI0OmY4OmRkOjFlOjA3OjU2OmQwOjM4OmEwOjk1OjcwOjIwOjc2OjhjOmQ3OmRkOgorICAgICAgICAxZTpkZTo5Zjo3MTpjNDoyMzplZjo4MzoxMzo1YzphMzoyNDoxNTo0ZDoyOTo0MDozYzo2YToKKyAgICAgICAgYzQ6YTk6ZDg6Yjc6YTY6NDQ6YTU6MGQ6ZjQ6ZTA6OWQ6Nzc6MWU6NDA6NzA6MjY6ZmM6ZGE6CisgICAgICAgIGQ5OjM2OmU0Ojc5OmU0OmI1OjNmOmJjOjliOjY1OmJlOmJiOjExOjk2OmNmOmRiOmM2OjI4OgorICAgICAgICAzOTozYTowODpjZTo0Nzo1Yjo1Mzo1YTpjNTo5OTpmZTo1ZDphOTpkZDplZjo0YzpkNDpjNjoKKyAgICAgICAgYTU6YWQ6MDI6ZTY6OGM6MDc6MTI6MWU6NmY6MDM6ZDE6NmY6YTA6YTM6ZjM6Mjk6YmQ6MTI6CisgICAgICAgIGM3OjUwOmEyOmIwOjdmOjg4OmE5Ojk5Ojc3OjlhOmIxOmMwOmE1OjM5OjJlOjVjOjdjOjY5OgorICAgICAgICBlMjoyYzpiMDplYTozNzo2YTphNDplMTo1YTplMTpmNTo1MDplNTo4MzplZjphNTpiYjoyYToKKyAgICAgICAgODg6ZTc6OGM6ZGI6ZmQ6NmQ6NWU6OTc6MTk6YTg6N2U6NjY6NzU6NmI6NzE6ZWE6YmY6YjE6CisgICAgICAgIGM3OjZmOmEwOmY0OjhlOmE0OmVjOjM0OjUxOjViOjhjOjI2OjAzOjcwOmExOjc3OmQ1OjAxOgorICAgICAgICAxMjo1NzowMDozNTpkYjoyMzpkZTowZTo4YToyODo5OTpmZDpiMToxMDo2Zjo0YjpmZjozODoKKyAgICAgICAgMmQ6NjA6NGU6MmM6OWM6ZWI6Njc6YjU6YWQ6NDk6ZWU6NGI6MWY6YWM6YWY6ZmI6MGQ6OTA6CisgICAgICAgIDVhOjY2OjYwOjcwOjVkOmFhOmNkOjc4OmQ0OjI0OmVlOmM4OjQxOmEwOjkzOjAxOjkyOjljOgorICAgICAgICA2YTo5ZTpmYzpiOToyNDpjNTpiMzoxNTo4Mjo3ZTpiZTphZTo5NToyYjplYjpiMTpjMDpkYToKKyAgICAgICAgZTM6MDE6NjA6MGI6NWU6Njk6YWM6ODQ6NTY6NjE6YmU6NzE6MTc6ZmU6MWQ6MTM6MGY6ZmU6CisgICAgICAgIGM2Ojg3OjQ1OmU5OmZlOjMyOmEwOjFhOjBkOjEzOmE0Ojk0OjU1OjcxOmE1OjE2OjhiOmJhOgorICAgICAgICBjYTo4OTpiMDpiMjpjNzpmYzo4ZjpkODo1NDpiNTo5Mzo2Mjo5ZDpjZTpjZjo1OTpmYjozZDoKKyAgICAgICAgMTg6Y2U6MmE6Y2I6MzU6MTU6ODI6NWQ6ZmY6NTQ6MjI6NWI6NzE6NTI6ZmI6Yjc6Yzk6ZmU6CisgICAgICAgIDYwOjliOjAwOjQxOjY0OmYwOmFhOjJhOmVjOmI2OjQyOjQzOmNlOjg5OjY2OjgxOmM4OjhiOgorICAgICAgICA5ZjozOTo1NDowMzoyNTpkMzoxNjozNTo4ZTo4NDpkMDo1ZjpmYTozMDoxYTpmNTo5YTo2YzoKKyAgICAgICAgZjQ6MGU6NTM6Zjk6M2E6NWI6ZDE6MWMKK1NIQTEgRmluZ2VycHJpbnQ9NUY6M0E6RkM6MEE6OEI6NjQ6RjY6ODY6Njc6MzQ6NzQ6REY6N0U6QTk6QTI6RkU6Rjk6RkE6N0E6NTEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9lNzc1ZWQyZC4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2U3NzVlZDJkLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjJmZmU1YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9lNzc1ZWQyZC4wCkBAIC0wLDAgKzEsMTIyIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUZhRENDQTFDZ0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRVUZBREJGTVFzd0NRWURWUVFHRXdKVlV6RVcKK01CUUdBMVVFQ2hNTlIyVnZWSEoxYzNRZ1NXNWpMakVlTUJ3R0ExVUVBeE1WUjJWdlZISjFjM1FnVlc1cGRtVnkKK2MyRnNJRU5CTUI0WERUQTBNRE13TkRBMU1EQXdNRm9YRFRJNU1ETXdOREExTURBd01Gb3dSVEVMTUFrR0ExVUUKK0JoTUNWVk14RmpBVUJnTlZCQW9URFVkbGIxUnlkWE4wSUVsdVl5NHhIakFjQmdOVkJBTVRGVWRsYjFSeWRYTjAKK0lGVnVhWFpsY25OaGJDQkRRVENDQWlJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFLWVYKK1ZhQ2p4dUFmakowaFVOZkJ2aXRidGFTZW9kbHlXTDBBRzB5L1lja1VIVVdDcThZZGdOWTk2eENjT3E5dEpQaTgKK2NRR2VCdlY4WHg3QkRsWEtnNXBaTUs0Wnl6QklsZTBpTjQzMFNwcHlaajZ0bGNEZ0ZnRGdFQjhyTVE3WGxGVFQKK1FqT2dOQjBlUlhiZFQ4b1lOK3lGRlhvWkNQelZ4NXp3OHFrdUVLbVM1ajFZUGFrV2FEd3ZkU0VZZnloM3BlRmgKK0Y3ZW02ZmdlbWR0emJ2UUtvaUZzN3RxcWhaSm1yL1o2YTRMYXVpSUlOUS9QUXZFMSttcnVmaXNsekRvUjVHMnYKK2M3SjJIYTNRc25obkdxUTVIRkVMWjFhRC9UaGREYzdkOExzcmxoL2VlekpTL1IyN3RRYWhzaUZlcGRhVmFIL3cKK21aN2NSUWcrNTlJSkRUV1UzWUJPVTVmWHRRbEVJR1FXRndNQ1RGTU5hTjdWcW5KTmsyMkNEdHVjdmMrMDgxeGQKK1ZIcHBDWmJXMnhIQmpYV290TTg1eU00OHZDUjg1bUxLNGIxOXA3MVhaUXZrL2lYdHRta1EzQ2dhUnIwQkhkQ1gKK3RlR1lPOEEzWk5ZOWxPNEw0ZlVvcmd0V3YzR0xJeWxCam9iRlMxSjcySEdySDRvVnBqdURXdGRZQVZIR1RFSFoKK2Y5aEJaM0tpS045Z2c2bWV5SHY4VTNOeVdmV1RlaGQyRHM3MzVWelpDMVUwb3FwYnRXcFU1eFBLVit5WGJmUmUKK0JpOUZpMWpVSXhhUzVCWnVLR05aTU45UUFaeGppUnFmMnhlVWduQTN3eVNlbWtmV1dzcE9xR21KY2grUmJOdCsKK25odXR4eDl6M1N4UEdXWDlmNU5BRUM3UzhPMDhuaTRvUG1rbU04VjdBZ01CQUFHall6QmhNQThHQTFVZEV3RUIKKy93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZOcTdMcXF3RExpSUpsRjBYRzBEMDhEWWozcldNQjhHQTFVZEl3UVkKK01CYUFGTnE3THFxd0RMaUlKbEYwWEcwRDA4RFlqM3JXTUE0R0ExVWREd0VCL3dRRUF3SUJoakFOQmdrcWhraUcKKzl3MEJBUVVGQUFPQ0FnRUFNWGpteDdYZnVKUkF5WEhFcURYc1JoM0NoZk1vV0lhd0MveU9zam1QUkZXclpJUmMKK2FhblFtamc4K3VVZk5lVkU0NEI1bEdpa3U4U2ZQZUUwelRCR2kxUXJsYVh2OXorWmhQMDE1czh4eHR4cXY2ZlgKK0l3amhtRjdEV2doMnFhYXZkeSszWUwxRVJtcnZsLzl6bGNHTzZKUDcvVEczN0ZjUkVVV2JNUEVhaURuQlR6eW4KK0FOWEgvS3R0Z0NKd3BRemdYUVFwQXZ2TG9KSFJmTmJEZmxEVm5WaStRVGpydVhVOEZkbWJ5VXFEV2NEYVUvMHoKK3V6WVltNFVQRmQzdUxheDJrN25aQVkxSUVLajc5VGlHOGRzS3hyMkVveU5CM3RaM2I0WFVoUnhRNEs1UmlycU4KK1BuYml1Y29uOGwrZjcyNVpEUWJZS3hlazBueHJ1MThVR2tpUEdrem5zMGNjamt4Rkt5RHVTTi9uM1FtT0dLamEKK1FJMlNKaEZUWVhOZDY3M254RTBwTjJIcnJEa3RaeTRXMXZVQWc0V2h6SDkyeEgza3QwdG03d05GWUdtMkRGS1cKK2tvUmVwcU8xcEQ0cjJjellHMGVxOGtUYVQva0Q2UEFVeXovemc5N1F3VlRqdCtnS04wMkxJRmtETUJtaExNaTkKK0VSL2Zyc2xLeGZNblptYUdyR2lSLzlubVV4d1BpMXhwWlFvbXlCNDB3MTFSZTllcG5BYWhOdDNWaVpTODJlUXQKK0RGNEpiQWlYZktNOWZKUC9QNkVVcDgrMVhldmIyeHpFZHQrSXViMUZCWlVicnZ4R2FreXZTT1BPcmcvU2Z1dm0KK2JKeFBnV3A2Wkt5N1B0WG55M1l1eGFkSXdWeVFEOHZJUC9ybU11R05HMitrNW83WStTbElpczV6L2l3PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAxICgweDEpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9VVMsIE89R2VvVHJ1c3QgSW5jLiwgQ049R2VvVHJ1c3QgVW5pdmVyc2FsIENBCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBNYXIgIDQgMDU6MDA6MDAgMjAwNCBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IE1hciAgNCAwNTowMDowMCAyMDI5IEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPUdlb1RydXN0IEluYy4sIENOPUdlb1RydXN0IFVuaXZlcnNhbCBDQQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDQwOTYgYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDQwOTYgYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YTY6MTU6NTU6YTA6YTM6YzY6ZTA6MWY6OGM6OWQ6MjE6NTA6ZDc6YzE6CisgICAgICAgICAgICAgICAgICAgIGJlOjJiOjViOmI1OmE0OjllOmExOmQ5OjcyOjU4OmJkOjAwOjFiOjRjOmJmOgorICAgICAgICAgICAgICAgICAgICA2MTpjOToxNDoxZDo0NTo4MjphYjpjNjoxZDo4MDpkNjozZDplYjoxMDo5YzoKKyAgICAgICAgICAgICAgICAgICAgM2E6YWY6NmQ6MjQ6Zjg6YmM6NzE6MDE6OWU6MDY6ZjU6N2M6NWY6MWU6YzE6CisgICAgICAgICAgICAgICAgICAgIDBlOjU1OmNhOjgzOjlhOjU5OjMwOmFlOjE5OmNiOjMwOjQ4Ojk1OmVkOjIyOgorICAgICAgICAgICAgICAgICAgICAzNzo4ZDpmNDo0YTo5YTo3Mjo2NjozZTphZDo5NTpjMDplMDoxNjowMDplMDoKKyAgICAgICAgICAgICAgICAgICAgMTA6MWY6MmI6MzE6MGU6ZDc6OTQ6NTQ6ZDM6NDI6MzM6YTA6MzQ6MWQ6MWU6CisgICAgICAgICAgICAgICAgICAgIDQ1Ojc2OmRkOjRmOmNhOjE4OjM3OmVjOjg1OjE1OjdhOjE5OjA4OmZjOmQ1OgorICAgICAgICAgICAgICAgICAgICBjNzo5YzpmMDpmMjphOToyZToxMDphOTo5MjplNjozZDo1ODozZDphOToxNjoKKyAgICAgICAgICAgICAgICAgICAgNjg6M2M6MmY6NzU6MjE6MTg6N2Y6Mjg6Nzc6YTU6ZTE6NjE6MTc6Yjc6YTY6CisgICAgICAgICAgICAgICAgICAgIGU5OmY4OjFlOjk5OmRiOjczOjZlOmY0OjBhOmEyOjIxOjZjOmVlOmRhOmFhOgorICAgICAgICAgICAgICAgICAgICA4NTo5Mjo2NjphZjpmNjo3YTo2Yjo4MjpkYTpiYToyMjowODozNTowZjpjZjoKKyAgICAgICAgICAgICAgICAgICAgNDI6ZjE6MzU6ZmE6NmE6ZWU6N2U6MmI6MjU6Y2M6M2E6MTE6ZTQ6NmQ6YWY6CisgICAgICAgICAgICAgICAgICAgIDczOmIyOjc2OjFkOmFkOmQwOmIyOjc4OjY3OjFhOmE0OjM5OjFjOjUxOjBiOgorICAgICAgICAgICAgICAgICAgICA2Nzo1Njo4MzpmZDozODo1ZDowZDpjZTpkZDpmMDpiYjoyYjo5NjoxZjpkZToKKyAgICAgICAgICAgICAgICAgICAgN2I6MzI6NTI6ZmQ6MWQ6YmI6YjU6MDY6YTE6YjI6MjE6NWU6YTU6ZDY6OTU6CisgICAgICAgICAgICAgICAgICAgIDY4OjdmOmYwOjk5OjllOmRjOjQ1OjA4OjNlOmU3OmQyOjA5OjBkOjM1Ojk0OgorICAgICAgICAgICAgICAgICAgICBkZDo4MDo0ZTo1Mzo5NzpkNzpiNTowOTo0NDoyMDo2NDoxNjoxNzowMzowMjoKKyAgICAgICAgICAgICAgICAgICAgNGM6NTM6MGQ6Njg6ZGU6ZDU6YWE6NzI6NGQ6OTM6NmQ6ODI6MGU6ZGI6OWM6CisgICAgICAgICAgICAgICAgICAgIGJkOmNmOmI0OmYzOjVjOjVkOjU0OjdhOjY5OjA5Ojk2OmQ2OmRiOjExOmMxOgorICAgICAgICAgICAgICAgICAgICA4ZDo3NTphODpiNDpjZjozOTpjODpjZTozYzpiYzoyNDo3YzplNjo2MjpjYToKKyAgICAgICAgICAgICAgICAgICAgZTE6YmQ6N2Q6YTc6YmQ6NTc6NjU6MGI6ZTQ6ZmU6MjU6ZWQ6YjY6Njk6MTA6CisgICAgICAgICAgICAgICAgICAgIGRjOjI4OjFhOjQ2OmJkOjAxOjFkOmQwOjk3OmI1OmUxOjk4OjNiOmMwOjM3OgorICAgICAgICAgICAgICAgICAgICA2NDpkNjozZDo5NDplZTowYjplMTpmNToyODphZTowYjo1NjpiZjo3MTo4YjoKKyAgICAgICAgICAgICAgICAgICAgMjM6Mjk6NDE6OGU6ODY6YzU6NGI6NTI6N2I6ZDg6NzE6YWI6MWY6OGE6MTU6CisgICAgICAgICAgICAgICAgICAgIGE2OjNiOjgzOjVhOmQ3OjU4OjAxOjUxOmM2OjRjOjQxOmQ5OjdmOmQ4OjQxOgorICAgICAgICAgICAgICAgICAgICA2Nzo3MjphMjoyODpkZjo2MDo4MzphOTo5ZTpjODo3YjpmYzo1Mzo3Mzo3MjoKKyAgICAgICAgICAgICAgICAgICAgNTk6ZjU6OTM6N2E6MTc6NzY6MGU6Y2U6Zjc6ZTU6NWM6ZDk6MGI6NTU6MzQ6CisgICAgICAgICAgICAgICAgICAgIGEyOmFhOjViOmI1OjZhOjU0OmU3OjEzOmNhOjU3OmVjOjk3OjZkOmY0OjVlOgorICAgICAgICAgICAgICAgICAgICAwNjoyZjo0NTo4Yjo1ODpkNDoyMzoxNjo5MjplNDoxNjo2ZToyODo2Mzo1OToKKyAgICAgICAgICAgICAgICAgICAgMzA6ZGY6NTA6MDE6OWM6NjM6ODk6MWE6OWY6ZGI6MTc6OTQ6ODI6NzA6Mzc6CisgICAgICAgICAgICAgICAgICAgIGMzOjI0OjllOjlhOjQ3OmQ2OjVhOmNhOjRlOmE4OjY5Ojg5OjcyOjFmOjkxOgorICAgICAgICAgICAgICAgICAgICA2YzpkYjo3ZTo5ZToxYjphZDpjNzoxZjo3MzpkZDoyYzo0ZjoxOTo2NTpmZDoKKyAgICAgICAgICAgICAgICAgICAgN2Y6OTM6NDA6MTA6MmU6ZDI6ZjA6ZWQ6M2M6OWU6MmU6Mjg6M2U6Njk6MjY6CisgICAgICAgICAgICAgICAgICAgIDMzOmM1OjdiCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgREE6QkI6MkU6QUE6QjA6MEM6Qjg6ODg6MjY6NTE6NzQ6NUM6NkQ6MDM6RDM6QzA6RDg6OEY6N0E6RDYKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOkRBOkJCOjJFOkFBOkIwOjBDOkI4Ojg4OjI2OjUxOjc0OjVDOjZEOjAzOkQzOkMwOkQ4OjhGOjdBOkQ2CisKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgRGlnaXRhbCBTaWduYXR1cmUsIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDMxOjc4OmU2OmM3OmI1OmRmOmI4Ojk0OjQwOmM5OjcxOmM0OmE4OjM1OmVjOjQ2OjFkOmMyOgorICAgICAgICA4NTpmMzoyODo1ODo4NjpiMDowYjpmYzo4ZTpiMjozOTo4Zjo0NDo1NTphYjo2NDo4NDo1YzoKKyAgICAgICAgNjk6YTk6ZDA6OWE6Mzg6M2M6ZmE6ZTU6MWY6MzU6ZTU6NDQ6ZTM6ODA6Nzk6OTQ6Njg6YTQ6CisgICAgICAgIGJiOmM0OjlmOjNkOmUxOjM0OmNkOjMwOjQ2OjhiOjU0OjJiOjk1OmE1OmVmOmY3OjNmOjk5OgorICAgICAgICA4NDpmZDozNTplNjpjZjozMTpjNjpkYzo2YTpiZjphNzpkNzoyMzowODplMTo5ODo1ZTpjMzoKKyAgICAgICAgNWE6MDg6NzY6YTk6YTY6YWY6Nzc6MmY6Yjc6NjA6YmQ6NDQ6NDY6NmE6ZWY6OTc6ZmY6NzM6CisgICAgICAgIDk1OmMxOjhlOmU4OjkzOmZiOmZkOjMxOmI3OmVjOjU3OjExOjExOjQ1OjliOjMwOmYxOjFhOgorICAgICAgICA4ODozOTpjMTo0ZjozYzphNzowMDpkNTpjNzpmYzphYjo2ZDo4MDoyMjo3MDphNTowYzplMDoKKyAgICAgICAgNWQ6MDQ6Mjk6MDI6ZmI6Y2I6YTA6OTE6ZDE6N2M6ZDY6YzM6N2U6NTA6ZDU6OWQ6NTg6YmU6CisgICAgICAgIDQxOjM4OmViOmI5Ojc1OjNjOjE1OmQ5OjliOmM5OjRhOjgzOjU5OmMwOmRhOjUzOmZkOjMzOgorICAgICAgICBiYjozNjoxODo5Yjo4NTowZjoxNTpkZDplZToyZDphYzo3Njo5MzpiOTpkOTowMTo4ZDo0ODoKKyAgICAgICAgMTA6YTg6ZmI6ZjU6Mzg6ODY6ZjE6ZGI6MGE6YzY6YmQ6ODQ6YTM6MjM6NDE6ZGU6ZDY6Nzc6CisgICAgICAgIDZmOjg1OmQ0Ojg1OjFjOjUwOmUwOmFlOjUxOjhhOmJhOjhkOjNlOjc2OmUyOmI5OmNhOjI3OgorICAgICAgICBmMjo1Zjo5ZjplZjo2ZTo1OTowZDowNjpkODoyYjoxNzphNDpkMjo3Yzo2YjpiYjo1ZjoxNDoKKyAgICAgICAgMWE6NDg6OGY6MWE6NGM6ZTc6YjM6NDc6MWM6OGU6NGM6NDU6MmI6MjA6ZWU6NDg6ZGY6ZTc6CisgICAgICAgIGRkOjA5OjhlOjE4OmE4OmRhOjQwOjhkOjkyOjI2OjExOjUzOjYxOjczOjVkOmViOmJkOmU3OgorICAgICAgICBjNDo0ZDoyOTozNzo2MTplYjphYzozOToyZDo2NzoyZToxNjpkNjpmNTowMDo4Mzo4NTphMToKKyAgICAgICAgY2M6N2Y6NzY6YzQ6N2Q6ZTQ6Yjc6NGI6NjY6ZWY6MDM6NDU6NjA6Njk6YjY6MGM6NTI6OTY6CisgICAgICAgIDkyOjg0OjVlOmE2OmEzOmI1OmE0OjNlOjJiOmQ5OmNjOmQ4OjFiOjQ3OmFhOmYyOjQ0OmRhOgorICAgICAgICA0ZjpmOTowMzplODpmMDoxNDpjYjozZjpmMzo4MzpkZTpkMDpjMTo1NDplMzpiNzplODowYToKKyAgICAgICAgMzc6NGQ6OGI6MjA6NTk6MDM6MzA6MTk6YTE6MmM6Yzg6YmQ6MTE6MWY6ZGY6YWU6Yzk6NGE6CisgICAgICAgIGM1OmYzOjI3OjY2OjY2Ojg2OmFjOjY4OjkxOmZmOmQ5OmU2OjUzOjFjOjBmOjhiOjVjOjY5OgorICAgICAgICA2NTowYToyNjpjODoxZTozNDpjMzo1ZDo1MTo3YjpkNzphOTo5YzowNjphMTozNjpkZDpkNToKKyAgICAgICAgODk6OTQ6YmM6ZDk6ZTQ6MmQ6MGM6NWU6MDk6NmM6MDg6OTc6N2M6YTM6M2Q6N2M6OTM6ZmY6CisgICAgICAgIDNmOmExOjE0OmE3OmNmOmI1OjVkOmViOmRiOmRiOjFjOmM0Ojc2OmRmOjg4OmI5OmJkOjQ1OgorICAgICAgICAwNTo5NToxYjphZTpmYzo0Njo2YTo0YzphZjo0ODplMzpjZTphZTowZjpkMjo3ZTplYjplNjoKKyAgICAgICAgNmM6OWM6NGY6ODE6NmE6N2E6NjQ6YWM6YmI6M2U6ZDU6ZTc6Y2I6NzY6MmU6YzU6YTc6NDg6CisgICAgICAgIGMxOjVjOjkwOjBmOmNiOmM4OjNmOmZhOmU2OjMyOmUxOjhkOjFiOjZmOmE0OmU2OjhlOmQ4OgorICAgICAgICBmOToyOTo0ODo4YTpjZTo3MzpmZToyYworU0hBMSBGaW5nZXJwcmludD1FNjoyMTpGMzozNTo0Mzo3OTowNTo5QTo0Qjo2ODozMDo5RDo4QToyRjo3NDoyMjoxNTo4NzpFQzo3OQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2U3YjhkNjU2LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZTdiOGQ2NTYuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMDc0NDdlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2U3YjhkNjU2LjAKQEAgLTAsMCArMSw2MCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlDZ2pDQ0FldWdBd0lCQWdJQkJEQU5CZ2txaGtpRzl3MEJBUVFGQURCVE1Rc3dDUVlEVlFRR0V3SlZVekVjCitNQm9HQTFVRUNoTVRSWEYxYVdaaGVDQlRaV04xY21VZ1NXNWpMakVtTUNRR0ExVUVBeE1kUlhGMWFXWmhlQ0JUCitaV04xY21VZ1pVSjFjMmx1WlhOeklFTkJMVEV3SGhjTk9Ua3dOakl4TURRd01EQXdXaGNOTWpBd05qSXhNRFF3CitNREF3V2pCVE1Rc3dDUVlEVlFRR0V3SlZVekVjTUJvR0ExVUVDaE1UUlhGMWFXWmhlQ0JUWldOMWNtVWdTVzVqCitMakVtTUNRR0ExVUVBeE1kUlhGMWFXWmhlQ0JUWldOMWNtVWdaVUoxYzJsdVpYTnpJRU5CTFRFd2daOHdEUVlKCitLb1pJaHZjTkFRRUJCUUFEZ1kwQU1JR0pBb0dCQU00dkdid1h0M2ZlazZsZldnMFhUelFhREpqMEl0bFoxTVJvCitSdkMwTmNXRkF5REdyMFdsSVZGRlFlc1dXRFl5YitKUVltVDUvVkdjcWlUWjlKMkRLb2NLSWRNU09EUnNqUUJ1CitXcURaUXU0YUlaWDVVa3hWV3NVUE9FOUcrbTM0TGpYV0hYenI0dkN3ZFlESXFST3N2b2p2T202clh5bzRZZ0t3CitFbnYrajZZREFnTUJBQUdqWmpCa01CRUdDV0NHU0FHRytFSUJBUVFFQXdJQUJ6QVBCZ05WSFJNQkFmOEVCVEFECitBUUgvTUI4R0ExVWRJd1FZTUJhQUZFcDRNbElSMjFrV05sN2Z3UlEyUUdwSGZFeWhNQjBHQTFVZERnUVdCQlJLCitlREpTRWR0WkZqWmUzOEVVTmtCcVIzeE1vVEFOQmdrcWhraUc5dzBCQVFRRkFBT0JnUUIxVzZpYkF4SG02VlpNCit6Zm1wVE1BTm12UE1aV25tSlhiTVdiZldWTU1kelptc0dkMjBoZFhnUGZ4aUlLZUVTMWhsOGVMNWxTRS85ZFIrCitXQjVIaDFRK1dLRzF0ZmdxNzNIbnZNUDJzVWxHNHRlZ2ErVldlcG9ubUh4R1loVG55Znh1QXhKNWdEZ2RTSUtOCisvQmYrS3BZcnRXS21wajI5ZjVKWnpWb3FnckkzZVE9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiA0ICgweDQpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IG1kNVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgTz1FcXVpZmF4IFNlY3VyZSBJbmMuLCBDTj1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogSnVuIDIxIDA0OjAwOjAwIDE5OTkgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBKdW4gMjEgMDQ6MDA6MDAgMjAyMCBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgTz1FcXVpZmF4IFNlY3VyZSBJbmMuLCBDTj1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDEwMjQgYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDEwMjQgYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6Y2U6MmY6MTk6YmM6MTc6Yjc6Nzc6ZGU6OTM6YTk6NWY6NWE6MGQ6MTc6CisgICAgICAgICAgICAgICAgICAgIDRmOjM0OjFhOjBjOjk4OmY0OjIyOmQ5OjU5OmQ0OmM0OjY4OjQ2OmYwOmI0OgorICAgICAgICAgICAgICAgICAgICAzNTpjNTo4NTowMzoyMDpjNjphZjo0NTphNToyMTo1MTo0NTo0MTplYjoxNjoKKyAgICAgICAgICAgICAgICAgICAgNTg6MzY6MzI6NmY6ZTI6NTA6NjI6NjQ6Zjk6ZmQ6NTE6OWM6YWE6MjQ6ZDk6CisgICAgICAgICAgICAgICAgICAgIGY0OjlkOjgzOjJhOjg3OjBhOjIxOmQzOjEyOjM4OjM0OjZjOjhkOjAwOjZlOgorICAgICAgICAgICAgICAgICAgICA1YTphMDpkOTo0MjplZToxYToyMTo5NTpmOTo1Mjo0Yzo1NTo1YTpjNTowZjoKKyAgICAgICAgICAgICAgICAgICAgMzg6NGY6NDY6ZmE6NmQ6Zjg6MmU6MzU6ZDY6MWQ6N2M6ZWI6ZTI6ZjA6YjA6CisgICAgICAgICAgICAgICAgICAgIDc1OjgwOmM4OmE5OjEzOmFjOmJlOjg4OmVmOjNhOjZlOmFiOjVmOjJhOjM4OgorICAgICAgICAgICAgICAgICAgICA2MjowMjpiMDoxMjo3YjpmZTo4ZjphNjowMworICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBOZXRzY2FwZSBDZXJ0IFR5cGU6IAorICAgICAgICAgICAgICAgIFNTTCBDQSwgUy9NSU1FIENBLCBPYmplY3QgU2lnbmluZyBDQQorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOjRBOjc4OjMyOjUyOjExOkRCOjU5OjE2OjM2OjVFOkRGOkMxOjE0OjM2OjQwOjZBOjQ3OjdDOjRDOkExCisKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICA0QTo3ODozMjo1MjoxMTpEQjo1OToxNjozNjo1RTpERjpDMToxNDozNjo0MDo2QTo0Nzo3Qzo0QzpBMQorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IG1kNVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDc1OjViOmE4OjliOjAzOjExOmU2OmU5OjU2OjRjOmNkOmY5OmE5OjRjOmMwOjBkOjlhOmYzOgorICAgICAgICBjYzo2NTo2OTplNjoyNTo3NjpjYzo1OTpiNzpkNjo1NDpjMzoxZDpjZDo5OTphYzoxOTpkZDoKKyAgICAgICAgYjQ6ODU6ZDU6ZTA6M2Q6ZmM6NjI6MjA6YTc6ODQ6NGI6NTg6NjU6ZjE6ZTI6Zjk6OTU6MjE6CisgICAgICAgIDNmOmY1OmQ0OjdlOjU4OjFlOjQ3Ojg3OjU0OjNlOjU4OmExOmI1OmI1OmY4OjJhOmVmOjcxOgorICAgICAgICBlNzpiYzpjMzpmNjpiMTo0OTo0NjplMjpkNzphMDo2YjplNTo1Njo3YTo5YToyNzo5ODo3YzoKKyAgICAgICAgNDY6NjI6MTQ6ZTc6Yzk6ZmM6NmU6MDM6MTI6Nzk6ODA6Mzg6MWQ6NDg6ODI6OGQ6ZmM6MTc6CisgICAgICAgIGZlOjJhOjk2OjJiOmI1OjYyOmE2OmE2OjNkOmJkOjdmOjkyOjU5OmNkOjVhOjJhOjgyOmIyOgorICAgICAgICAzNzo3OQorU0hBMSBGaW5nZXJwcmludD1EQTo0MDoxODo4Qjo5MTo4OTpBMzpFRDpFRTpBRTpEQTo5NzpGRToyRjo5RDpGNTpCNzpEMTo4QTo0MQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2U4NjUxMDgzLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZTg2NTEwODMuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MjM2ZDVlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2U4NjUxMDgzLjAKQEAgLTAsMCArMSw4NyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFQ2pDQ0F2S2dBd0lCQWdJSkFNSitRd1JPUno4Wk1BMEdDU3FHU0liM0RRRUJDd1VBTUlHQ01Rc3dDUVlECitWUVFHRXdKSVZURVJNQThHQTFVRUJ3d0lRblZrWVhCbGMzUXhGakFVQmdOVkJBb01EVTFwWTNKdmMyVmpJRXgwCitaQzR4SnpBbEJnTlZCQU1NSGsxcFkzSnZjMlZqSUdVdFUzcHBaMjV2SUZKdmIzUWdRMEVnTWpBd09URWZNQjBHCitDU3FHU0liM0RRRUpBUllRYVc1bWIwQmxMWE42YVdkdWJ5NW9kVEFlRncwd09UQTJNVFl4TVRNd01UaGFGdzB5CitPVEV5TXpBeE1UTXdNVGhhTUlHQ01Rc3dDUVlEVlFRR0V3SklWVEVSTUE4R0ExVUVCd3dJUW5Wa1lYQmxjM1F4CitGakFVQmdOVkJBb01EVTFwWTNKdmMyVmpJRXgwWkM0eEp6QWxCZ05WQkFNTUhrMXBZM0p2YzJWaklHVXRVM3BwCitaMjV2SUZKdmIzUWdRMEVnTWpBd09URWZNQjBHQ1NxR1NJYjNEUUVKQVJZUWFXNW1iMEJsTFhONmFXZHVieTVvCitkVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFPbjRqL05qcmRxRzJLZmdRdnZQCitrZDZtSnZpWnBXTndyWnV1eWpOQWZXMldicUVPUk83aEU1MlVRbEthdlhXRmRDeW9EaDJUdGhpM2pDeW96L3RjCitjYm5hN1A3b2ZvL2tMeDJ5cUhXSDJMZWg1VHZQbVVwRzBJTVpmY0NoRWh5VmJVcjAyTWVsVFRNdWhUbEFkWDRVCitmSUFTbUZESFFXZTRvSUJoVktac1RoL2duUTRINmNtNk0rZit3RlVvTEFLQXB4bjFudHhWVXdPWGV3ZEkvNW43CitONG9reEZuTVVCQmpqcXFwR3JDRUdvYjVYN3V4VUc2azBRck0xWEYrSDZjYmZQVlRiaUpmeXl2bTFIeGRydGJDCit4a3psQlFIWjdWZjh3U041L1BySUpJT1Y4N1ZxVVFIUWQ5YnBFcUg1R29QN2dodTVzSmYwZGdZelEwbWcvd3UxCisrclVDQXdFQUFhT0JnREIrTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RGdZRFZSMFBBUUgvQkFRREFnRUdNQjBHCitBMVVkRGdRV0JCVExEOGJmUWtQTVBjdTFTQ09oR25xbUtyczBhREFmQmdOVkhTTUVHREFXZ0JUTEQ4YmZRa1BNCitQY3UxU0NPaEducW1LcnMwYURBYkJnTlZIUkVFRkRBU2dSQnBibVp2UUdVdGMzcHBaMjV2TG1oMU1BMEdDU3FHCitTSWIzRFFFQkN3VUFBNElCQVFESjBRNWVMdFhNczN3K3kvdzkvdzBvbFpNRXlML2F6WG00UTVEd3BMN3Y4dThoCittTHpVMUYwRzl1NUM3REJzb0txcHl2R3Zpdm8vQzNOcVB1b3VRSDRmcmxSaGVlc3VDRGZYSS9PTW43NGRzZUdrCitkZHVnNGxRVXNib2NLYVFZOWhLNm9oUVU0ekUxeUVEL3QrQUZkbGZCSEZueStML2s3U1ZpWElUd2ZuNGZzNzc1Cit0eUVSekFNQlZuQ25FSkllR3pTQkhxMmNHc01FUE8wQ1lkWWVCdk5mT29meUsvRkZoK1U5ck5ISFY0UzlhNjdjCisyUG0yRzJKd0N6MDJ5VUx5TXRkNlllYlMyejNQeUtuSm05emJXRVRYYnppdmYzalRvNjBhZGJvY3dUWjhqeDV0CitITU4xUnE0MUJhYjJYRDBoN2xid3lZSWlMWHBVcTNERGZTSmxnbkNXCistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICBjMjo3ZTo0MzowNDo0ZTo0NzozZjoxOQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9SFUsIEw9QnVkYXBlc3QsIE89TWljcm9zZWMgTHRkLiwgQ049TWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQSAyMDA5L2VtYWlsQWRkcmVzcz1pbmZvQGUtc3ppZ25vLmh1CisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBKdW4gMTYgMTE6MzA6MTggMjAwOSBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IERlYyAzMCAxMTozMDoxOCAyMDI5IEdNVAorICAgICAgICBTdWJqZWN0OiBDPUhVLCBMPUJ1ZGFwZXN0LCBPPU1pY3Jvc2VjIEx0ZC4sIENOPU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOS9lbWFpbEFkZHJlc3M9aW5mb0BlLXN6aWduby5odQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6ZTk6Zjg6OGY6ZjM6NjM6YWQ6ZGE6ODY6ZDg6YTc6ZTA6NDI6ZmI6Y2Y6CisgICAgICAgICAgICAgICAgICAgIDkxOmRlOmE2OjI2OmY4Ojk5OmE1OjYzOjcwOmFkOjliOmFlOmNhOjMzOjQwOgorICAgICAgICAgICAgICAgICAgICA3ZDo2ZDo5Njo2ZTphMTowZTo0NDplZTplMToxMzo5ZDo5NDo0Mjo1Mjo5YToKKyAgICAgICAgICAgICAgICAgICAgYmQ6NzU6ODU6NzQ6MmM6YTg6MGU6MWQ6OTM6YjY6MTg6Yjc6OGM6MmM6YTg6CisgICAgICAgICAgICAgICAgICAgIGNmOmZiOjVjOjcxOmI5OmRhOmVjOmZlOmU4OjdlOjhmOmU0OjJmOjFkOmIyOgorICAgICAgICAgICAgICAgICAgICBhODo3NTo4NzpkODpiNzphMTplNTozYjpjZjo5OTo0YTo0NjpkMDo4MzoxOToKKyAgICAgICAgICAgICAgICAgICAgN2Q6YzA6YTE6MTI6MWM6OTU6NmQ6NGE6ZjQ6ZDg6Yzc6YTU6NGQ6MzM6MmU6CisgICAgICAgICAgICAgICAgICAgIDg1OjM5OjQwOjc1OjdlOjE0OjdjOjgwOjEyOjk4OjUwOmM3OjQxOjY3OmI4OgorICAgICAgICAgICAgICAgICAgICBhMDo4MDo2MTo1NDphNjo2Yzo0ZToxZjplMDo5ZDowZTowNzplOTpjOTpiYToKKyAgICAgICAgICAgICAgICAgICAgMzM6ZTc6ZmU6YzA6NTU6Mjg6MmM6MDI6ODA6YTc6MTk6ZjU6OWU6ZGM6NTU6CisgICAgICAgICAgICAgICAgICAgIDUzOjAzOjk3OjdiOjA3OjQ4OmZmOjk5OmZiOjM3OjhhOjI0OmM0OjU5OmNjOgorICAgICAgICAgICAgICAgICAgICA1MDoxMDo2Mzo4ZTphYTphOToxYTpiMDo4NDoxYTo4NjpmOTo1ZjpiYjpiMToKKyAgICAgICAgICAgICAgICAgICAgNTA6NmU6YTQ6ZDE6MGE6Y2M6ZDU6NzE6N2U6MWY6YTc6MWI6N2M6ZjU6NTM6CisgICAgICAgICAgICAgICAgICAgIDZlOjIyOjVmOmNiOjJiOmU2OmQ0OjdjOjVkOmFlOmQ2OmMyOmM2OjRjOmU1OgorICAgICAgICAgICAgICAgICAgICAwNTowMTpkOTplZDo1NzpmYzpjMToyMzo3OTpmYzpmYTpjODoyNDo4Mzo5NToKKyAgICAgICAgICAgICAgICAgICAgZjM6YjU6NmE6NTE6MDE6ZDA6Nzc6ZDY6ZTk6MTI6YTE6Zjk6MWE6ODM6ZmI6CisgICAgICAgICAgICAgICAgICAgIDgyOjFiOmI5OmIwOjk3OmY0Ojc2OjA2OjMzOjQzOjQ5OmEwOmZmOjBiOmI1OgorICAgICAgICAgICAgICAgICAgICBmYTpiNQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIENCOjBGOkM2OkRGOjQyOjQzOkNDOjNEOkNCOkI1OjQ4OjIzOkExOjFBOjdBOkE2OjJBOkJCOjM0OjY4CisgICAgICAgICAgICBYNTA5djMgQXV0aG9yaXR5IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBrZXlpZDpDQjowRjpDNjpERjo0Mjo0MzpDQzozRDpDQjpCNTo0ODoyMzpBMToxQTo3QTpBNjoyQTpCQjozNDo2OAorCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBBbHRlcm5hdGl2ZSBOYW1lOiAKKyAgICAgICAgICAgICAgICBlbWFpbDppbmZvQGUtc3ppZ25vLmh1CisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgYzk6ZDE6MGU6NWU6MmU6ZDU6Y2M6YjM6N2M6M2U6Y2I6ZmM6M2Q6ZmY6MGQ6Mjg6OTU6OTM6CisgICAgICAgIDA0OmM4OmJmOmRhOmNkOjc5OmI4OjQzOjkwOmYwOmE0OmJlOmVmOmYyOmVmOjIxOjk4OmJjOgorICAgICAgICBkNDpkNDo1ZDowNjpmNjplZTo0MjplYzozMDo2YzphMDphYTphOTpjYTpmMTphZjo4YTpmYToKKyAgICAgICAgM2Y6MGI6NzM6NmE6M2U6ZWE6MmU6NDA6N2U6MWY6YWU6NTQ6NjE6Nzk6ZWI6MmU6MDg6Mzc6CisgICAgICAgIGQ3OjIzOmYzOjhjOjlmOmJlOjFkOmIxOmUxOmE0Ojc1OmRiOmEwOmUyOjU0OjE0OmIxOmJhOgorICAgICAgICAxYzoyOTphNDoxODpmNjoxMjpiYTphMjoxNDoxNDplMzozMTozNTpjODo0MDpmZjpiNzplMDoKKyAgICAgICAgMDU6NzY6NTc6YzE6MWM6NTk6ZjI6Zjg6YmY6ZTQ6ZWQ6MjU6NjI6NWM6ODQ6ZjA6N2U6N2U6CisgICAgICAgIDFmOmIzOmJlOmY5OmI3OjIxOjExOmNjOjAzOjAxOjU2OjcwOmE3OjEwOjkyOjFlOjFiOjM0OgorICAgICAgICA4MToxZTphZDo5YzoxYTpjMzowNDozYzplZDowMjo2MTpkNjoxZTowNjpmMzo1ZjozYTo4NzoKKyAgICAgICAgZjI6MmI6ZjE6NDU6ODc6ZTU6M2Q6YWM6ZDE6Yzc6NTc6ODQ6YmQ6NmI6YWU6ZGM6ZDg6Zjk6CisgICAgICAgIGI2OjFiOjYyOjcwOjBiOjNkOjM2OmM5OjQyOmYyOjMyOmQ3OjdhOjYxOmU2OmQyOmRiOjNkOgorICAgICAgICBjZjpjODphOTpjOTo5YjpkYzpkYjo1ODo0NDpkNzo2ZjozODphZjo3Zjo3ODpkMzphMzphZDoKKyAgICAgICAgMWE6NzU6YmE6MWM6YzE6MzY6N2M6OGY6MWU6NmQ6MWM6YzM6NzU6NDY6YWU6MzU6MDU6YTY6CisgICAgICAgIGY2OjVjOjNkOjIxOmVlOjU2OmYwOmM5OjgyOjIyOjJkOjdhOjU0OmFiOjcwOmMzOjdkOjIyOgorICAgICAgICA2NTo4Mjo3MDo5NgorU0hBMSBGaW5nZXJwcmludD04OTpERjo3NDpGRTo1QzpGNDowRjo0QTo4MDpGOTpFMzozNzo3RDo1NDpEQTo5MTpFMTowMTozMTo4RQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2VhMTY5NjE3LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZWExNjk2MTcuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MWViNmU3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2VhMTY5NjE3LjAKQEAgLTAsMCArMSwxMjkgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRnRUQ0NBNTJnQXdJQkFnSUlZWTNIaGpzQmdnVXdEUVlKS29aSWh2Y05BUUVGQlFBd1JERVdNQlFHQTFVRQorQXd3TlFVTkZSRWxEVDAwZ1VtOXZkREVNTUFvR0ExVUVDd3dEVUV0Sk1ROHdEUVlEVlFRS0RBWkZSRWxEVDAweAorQ3pBSkJnTlZCQVlUQWtWVE1CNFhEVEE0TURReE9ERTJNalF5TWxvWERUSTRNRFF4TXpFMk1qUXlNbG93UkRFVworTUJRR0ExVUVBd3dOUVVORlJFbERUMDBnVW05dmRERU1NQW9HQTFVRUN3d0RVRXRKTVE4d0RRWURWUVFLREFaRgorUkVsRFQwMHhDekFKQmdOVkJBWVRBa1ZUTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQworQWdFQS81S1Y0V2dHZHJRc3lGaEl5djJBVkNsVll5VC9rR1diRUhWN3cycmJZZ0lCOGhpR3RYeGFPTEhrV0xuNworMDlndG43MHlONzhzRlcyK3RmUWgwaE9SMlFldEFRWFc4NzEzemw5Q2dRcjVhdU9EQUtnckxsVVRZNEhLUnh4NworWEJaWGVodURZQVE2UG1YRHpRSGUzcVRXRExxTzN0a0U3aGRXSXB1UFkvMU5GZ3UzZTNlTStTVzEwVzJaRWk1UAorR3JqbTZnU1NyajBSdVZGQ1BZZXdNWVd2ZVZxYy91ZE9YcEpQUS95ck9xMmxFaVptdWVJTTE1ak8xRmlsbFVBSwordDBTZEUzUXJ3cVhySWhXWUVOaUx4UVNmSFk5ZzVRWWJtOCs1ZWFBOW9pTS9RajlyK2h3RGV6Q056bXpBditZYgorWDc5bnVJUVoxUlh2ZTh1UU5qRml5YndDcTBaZm0vNGFhSlEwUFpDT3JmYmtIUWwvU29nNFA3NW4vVFNXOVIyOAorTUhUTE9PN1ZiS3ZVL1BRQXR3QmJoVElXZGpQcDJLT1puUVVBcWhibTg0RjliMzJxaG0ydEZYVFR4S0p4cXZRVQorZmVjeXVCKzgxZkZPdlc4WEFqblhEcFZDT3NjQVB1a21ZeEhxQzlGSy94aWRzdGQ3THpyWmx2dm9IcEt1RTFYSQorMlNmMjNFZ2JzQ1RCaGVOM25acWs4d3dSSFEzSXRCVHV0WUpYQ2I4Z1dIOHZJaVBZY010NWJNbEw4cWtxeVB5SAorSzljYVVQZ242QzlENHpxOTJGZHgvYzZtVWx2NTNVM3Q1Zlp2aWUyN2s1eDJJWFh3a2t3cDl5K2NBUzcrVUVhZQorWkF3VXN3ZGJ4Y0p6YlBFSFhFVWtGRFd1Zy9GcVRZbDYrclBZTFdid05vZjFLMU1DQXdFQUFhT0JxakNCcHpBUAorQmdOVkhSTUJBZjhFQlRBREFRSC9NQjhHQTFVZEl3UVlNQmFBRkthejRTc3JTYmJYYzZHcWxQVUI1M05sVEt4UQorTUE0R0ExVWREd0VCL3dRRUF3SUJoakFkQmdOVkhRNEVGZ1FVcHJQaEt5dEp0dGR6b2FxVTlRSG5jMlZNckZBdworUkFZRFZSMGdCRDB3T3pBNUJnUlZIU0FBTURFd0x3WUlLd1lCQlFVSEFnRVdJMmgwZEhBNkx5OWhZMlZrYVdOdgorYlM1bFpHbGpiMjFuY205MWNDNWpiMjB2Wkc5ak1BMEdDU3FHU0liM0RRRUJCUVVBQTRJQ0FRRE9MQXRTVVdJbQorZlF3bmc0L0Y5dHFnYUh0UGtsN3FwSE15RVZORXNrVExuZXdQZVVLekVLYkhEWjNMdHZvL09uenF2NGhUR3p6MworZ3ZvRk5UUGhOYWhYd09mOWpVOC9rekpQZUdZRGR3ZFk2WlhJZmo3UWVRQ004aHRSTTV1OGxPazZlMjVTTFRLZQorSTZSRis3WXVFN0NMR0xIZHp0VWRwMEovVmI3N1c3dEgxUHdrelFTdWxnVVYxcXpPTVBQS0M4VzY0aUxncHEwaQorNUFMdWRCRi9UUDk0SFRYYTVnSTA2eGdTWVhjR0NSWmo2aGl0b29jZjhzZUFDUWwxVGhDb2p6Mkd1SFVSd0NSaQoraXBaN1NrWHA3Rm5Gdm11RDV1SG9yTFV3SHY0RkI0RDU0U01OVUk4Rm1QOHNYK2c3dHEzUGdiVWhoOG9JS2lNbgorTUNBcnorMlVXNnl5ZXRMSEtLR0tDNXROU2l4dGhUOEpjanhuNHRuY0I3cnJaWHRhQVdQV2tGdFBGMlk5ZndzWgorbzVOakVGSXFueFFXV09MY3BmU2hGb3NPa1l1QnlwdFordGhya1FkbFZWOVNINjg2KzVEZGFhVmJuRzBPTExiNgorenF5bGZESktaMERjTURRajNkY0VJMmJ3L0ZXQXAvdG1HWUkxWjJKd09WNXZ4K3FRUUVRSUhyaXkxdHZ1V2FjTgorR0hrMHZGUVlYbFBLTkZIdFJRcm1qc2VDTmo2bk9HT3BNQ3dYRUdDU24xV0hFbGtRd2c5bmFSSE1UaDUrU3BxdAorcjBDb2RheFdrSFM0b0p5bGVXL2M2UnJJYVFYcHV2b0RzM3prNEU3Q3pwM290a1lOYm41WE9tZVV3c3NmbkhkSworWjA1cGhrT1RPUHUyMjArRGtkUmdma3MrS3pnSFZaaGVwQT09CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICA2MTo4ZDpjNzo4NjozYjowMTo4MjowNQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDTj1BQ0VESUNPTSBSb290LCBPVT1QS0ksIE89RURJQ09NLCBDPUVTCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBBcHIgMTggMTY6MjQ6MjIgMjAwOCBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEFwciAxMyAxNjoyNDoyMiAyMDI4IEdNVAorICAgICAgICBTdWJqZWN0OiBDTj1BQ0VESUNPTSBSb290LCBPVT1QS0ksIE89RURJQ09NLCBDPUVTCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoNDA5NiBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoNDA5NiBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpmZjo5Mjo5NTplMTo2ODowNjo3NjpiNDoyYzpjODo1ODo0ODpjYTpmZDoKKyAgICAgICAgICAgICAgICAgICAgODA6NTQ6Mjk6NTU6NjM6MjQ6ZmY6OTA6NjU6OWI6MTA6NzU6N2I6YzM6NmE6CisgICAgICAgICAgICAgICAgICAgIGRiOjYyOjAyOjAxOmYyOjE4Ojg2OmI1OjdjOjVhOjM4OmIxOmU0OjU4OmI5OgorICAgICAgICAgICAgICAgICAgICBmYjpkMzpkODoyZDo5ZjpiZDozMjozNzpiZjoyYzoxNTo2ZDpiZTpiNTpmNDoKKyAgICAgICAgICAgICAgICAgICAgMjE6ZDI6MTM6OTE6ZDk6MDc6YWQ6MDE6MDU6ZDY6ZjM6YmQ6Nzc6Y2U6NWY6CisgICAgICAgICAgICAgICAgICAgIDQyOjgxOjBhOmY5OjZhOmUzOjgzOjAwOmE4OjJiOjJlOjU1OjEzOjYzOjgxOgorICAgICAgICAgICAgICAgICAgICBjYTo0NzoxYzo3Yjo1YzoxNjo1Nzo3YToxYjo4Mzo2MDowNDozYTozZTo2NToKKyAgICAgICAgICAgICAgICAgICAgYzM6Y2Q6MDE6ZGU6ZGU6YTQ6ZDY6MGM6YmE6OGU6ZGU6ZDk6MDQ6ZWU6MTc6CisgICAgICAgICAgICAgICAgICAgIDU2OjIyOjliOjhmOjYzOmZkOjRkOjE2OjBiOmI3OjdiOjc3OjhjOmY5OjI1OgorICAgICAgICAgICAgICAgICAgICBiNTpkMTo2ZDo5OToxMjoyZTo0ZjoxYTpiODplNjplYTowNDo5MjphZTozZDoKKyAgICAgICAgICAgICAgICAgICAgMTE6Yjk6NTE6NDI6M2Q6ODc6YjA6MzE6ODU6YWY6Nzk6NWE6OWM6ZmU6ZTc6CisgICAgICAgICAgICAgICAgICAgIDRlOjVlOjkyOjRmOjQzOmZjOmFiOjNhOmFkOmE1OjEyOjI2OjY2OmI5OmUyOgorICAgICAgICAgICAgICAgICAgICAwYzpkNzo5ODpjZTpkNDo1ODphNTo5NTo0MDowYTpiNzo0NDo5ZDoxMzo3NDoKKyAgICAgICAgICAgICAgICAgICAgMmI6YzI6YTU6ZWI6MjI6MTU6OTg6MTA6ZDg6OGI6YzU6MDQ6OWY6MWQ6OGY6CisgICAgICAgICAgICAgICAgICAgIDYwOmU1OjA2OjFiOjliOmNmOmI5Ojc5OmEwOjNkOmEyOjIzOjNmOjQyOjNmOgorICAgICAgICAgICAgICAgICAgICA2YjpmYToxYzowMzo3YjozMDo4ZDpjZTo2YzpjMDpiZjplNjoxYjo1ZjpiZjoKKyAgICAgICAgICAgICAgICAgICAgNjc6Yjg6ODQ6MTk6ZDU6MTU6ZWY6N2I6Y2I6OTA6MzY6MzE6NjI6Yzk6YmM6CisgICAgICAgICAgICAgICAgICAgIDAyOmFiOjQ2OjVmOjliOmZlOjFhOjY4Ojk0OjM0OjNkOjkwOjhlOmFkOmY2OgorICAgICAgICAgICAgICAgICAgICBlNDoxZDowOTo3Zjo0YTo4ODozODozZjpiZTo2NzpmZDozNDo5NjpmNToxZDoKKyAgICAgICAgICAgICAgICAgICAgYmM6MzA6NzQ6Y2I6Mzg6ZWU6ZDU6NmM6YWI6ZDQ6ZmM6ZjQ6MDA6Yjc6MDA6CisgICAgICAgICAgICAgICAgICAgIDViOjg1OjMyOjE2Ojc2OjMzOmU5OmQ4OmEzOjk5OjlkOjA1OjAwOmFhOjE2OgorICAgICAgICAgICAgICAgICAgICBlNjpmMzo4MTo3ZDo2Zjo3ZDphYTo4Njo2ZDphZDoxNTo3NDpkMzpjNDphMjoKKyAgICAgICAgICAgICAgICAgICAgNzE6YWE6ZjQ6MTQ6N2Q6ZTc6MzI6Yjg6MWY6YmM6ZDU6ZjE6NGU6YmQ6NmY6CisgICAgICAgICAgICAgICAgICAgIDE3OjAyOjM5OmQ3OjBlOjk1OjQyOjNhOmM3OjAwOjNlOmU5OjI2OjYzOjExOgorICAgICAgICAgICAgICAgICAgICBlYTowYjpkMTo0YTpmZjoxODo5ZDpiMjpkNzo3YjoyZjozYTpkOTo5NjpmYjoKKyAgICAgICAgICAgICAgICAgICAgZTg6MWU6OTI6YWU6MTM6NTU6Yzg6ZDk6Mjc6ZjY6ZGM6NDg6MWI6YjA6MjQ6CisgICAgICAgICAgICAgICAgICAgIGMxOjg1OmUzOjc3OjlkOjlhOmE0OmYzOjBjOjExOjFkOjBkOmM4OmI0OjE0OgorICAgICAgICAgICAgICAgICAgICBlZTpiNTo4Mjo1NzowOTpiZjoyMDo1ODo3ZjoyZjoyMjoyMzpkODo3MDpjYjoKKyAgICAgICAgICAgICAgICAgICAgNzk6NmM6Yzk6NGI6ZjI6YTk6MmE6Yzg6ZmM6ODc6MmI6ZDc6MWE6NTA6Zjg6CisgICAgICAgICAgICAgICAgICAgIDI3OmU4OjJmOjQzOmUzOjNhOmJkOmQ4OjU3OjcxOmZkOmNlOmE2OjUyOjViOgorICAgICAgICAgICAgICAgICAgICBmOTpkZDo0ZDplZDplNTpmNjo2Zjo4OTplZDpiYjo5Mzo5Yzo3NjoyMTo3NToKKyAgICAgICAgICAgICAgICAgICAgZjA6OTI6NGM6Mjk6Zjc6MmY6OWM6MDE6MmU6ZmU6NTA6NDY6OWU6NjQ6MGM6CisgICAgICAgICAgICAgICAgICAgIDE0OmIzOjA3OjViOmM1OmMyOjczOjZjOmYxOjA3OjVjOjQ1OjI0OjE0OjM1OgorICAgICAgICAgICAgICAgICAgICBhZTo4MzpmMTo2YTo0ZDo4OTo3YTpmYTpiMzpkODoyZDo2NjpmMDozNjo4NzoKKyAgICAgICAgICAgICAgICAgICAgZjU6MmI6NTMKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOkE2OkIzOkUxOjJCOjJCOjQ5OkI2OkQ3OjczOkExOkFBOjk0OkY1OjAxOkU3OjczOjY1OjRDOkFDOjUwCisKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgRGlnaXRhbCBTaWduYXR1cmUsIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgQTY6QjM6RTE6MkI6MkI6NDk6QjY6RDc6NzM6QTE6QUE6OTQ6RjU6MDE6RTc6NzM6NjU6NEM6QUM6NTAKKyAgICAgICAgICAgIFg1MDl2MyBDZXJ0aWZpY2F0ZSBQb2xpY2llczogCisgICAgICAgICAgICAgICAgUG9saWN5OiBYNTA5djMgQW55IFBvbGljeQorICAgICAgICAgICAgICAgICAgQ1BTOiBodHRwOi8vYWNlZGljb20uZWRpY29tZ3JvdXAuY29tL2RvYworCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIGNlOjJjOjBiOjUyOjUxOjYyOjI2OjdkOjBjOjI3OjgzOjhmOmM1OmY2OmRhOmEwOjY4OjdiOgorICAgICAgICA0Zjo5Mjo1ZTplYTphNDo3MzozMjoxMTo1Mzo0NDpiMjo0NDpjYjo5ZDplYzowZjo3OTo0MjoKKyAgICAgICAgYjM6MTA6YTY6Yzc6MGQ6OWQ6Y2I6YjY6ZmE6M2Y6M2E6N2M6ZWE6YmY6ODg6NTM6MWI6M2M6CisgICAgICAgIGY3OjgyOmZhOjA1OjM1OjMzOmUxOjM1OmE4OjU3OmMwOmU3OmZkOjhkOjRmOjNmOjkzOjMyOgorICAgICAgICA0Zjo3ODo2NjowMzo3NzowNzo1ODplOTo5NTpjODo3ZTozZTpkMDo3OTowMDo4YzpmMjoxYjoKKyAgICAgICAgNTE6MzM6OWI6YmM6OTQ6ZTk6M2E6N2I6NmU6NTI6MmQ6MzI6OWU6MjM6YTQ6NDU6ZmI6YjY6CisgICAgICAgIDJlOjEzOmIwOjhiOjE4OmIxOmRkOmNlOmQ1OjFkOmE3OjQyOjdmOjU1OmJlOmZiOjViOmJiOgorICAgICAgICA0NzpkNDpmYzoyNDpjZDowNDphZTo5NjowNToxNTpkNjphYzpjZTozMDpmMzpjYTowYjpjNToKKyAgICAgICAgYmE6ZTI6MjI6ZTA6YTY6YWQ6MjI6ZTQ6MDI6ZWU6NzQ6MTE6N2Y6NGM6ZmY6Nzg6MWQ6MzU6CisgICAgICAgIGRhOmU2OjAyOjM0OmViOjE4OjEyOjYxOjc3OjA2OjA5OjE2OjYzOmVhOjE4OmFkOmEyOjg3OgorICAgICAgICAxZjpmMjpjNzo4MDowOTowOTo3NTo0ZToxMDphODo4ZjozZDo4NjpiODo3NToxMTpjMDoyNDoKKyAgICAgICAgNjI6OGE6OTY6N2I6NGE6NDU6ZTk6ZWM6NTk6YzU6YmU6NmI6ODM6ZTY6ZTE6ZTg6YWM6YjU6CisgICAgICAgIDMwOjFlOmZlOjA1OjA3OjgwOmY5OmUxOjIzOjBkOjUwOjhmOjA1Ojk4OmZmOjJjOjVmOmU4OgorICAgICAgICAzYjpiNjphZDpjZjo4MTpiNToyMTo4NzpjYTowODoyYToyMzoyNzozMDoyMDoyYjpjZjplZDoKKyAgICAgICAgOTQ6NWI6YWM6YjI6N2E6ZDI6Yzc6Mjg6YTE6OGE6MGI6OWI6NGQ6NGE6MmM6NmQ6ODU6M2Y6CisgICAgICAgIDA5OjcyOjNjOjY3OmUyOmQ5OmRjOjA3OmJhOmViOjY1OjdiOjVhOjAxOjYzOmQ2OjkwOjViOgorICAgICAgICA0ZjoxNzo2NjozZDo3ZjowYjoxOTphMzo5Mzo2MzoxMDo1MjoyYTo5ZjoxNDoxNjo1ODplMjoKKyAgICAgICAgZGM6YTU6ZjQ6YTE6MTY6OGI6MGU6OTE6OGI6ODE6Y2E6OWI6NTk6ZmE6ZDg6NmI6OTE6MDc6CisgICAgICAgIDY1OjU1OjVmOjUyOjFmOmFmOjNhOmZiOjkwOmRkOjY5OmE1OjViOjljOjZkOjBlOjJjOmI2OgorICAgICAgICBmYTpjZTphYzphNTo3YzozMjo0YTo2Nzo0MDpkYzozMDozNDoyMzpkZDpkNzowNDoyMzo2NjoKKyAgICAgICAgZjA6ZmM6NTU6ODA6YTc6ZmI6NjY6MTk6ODI6MzU6Njc6NjI6NzA6Mzk6NWU6NmY6Yzc6ZWE6CisgICAgICAgIDkwOjQwOjQ0OjA4OjFlOmI4OmIyOmQ2OmRiOmVlOjU5OmE3OjBkOjE4Ojc5OjM0OmJjOjU0OgorICAgICAgICAxODo1ZTo1MzpjYTozNDo1MTplZDo0NTowYTplNjo4ZTpjNzo4MjozNjozZTphNzozODo2MzoKKyAgICAgICAgYTk6MzA6MmM6MTc6MTA6NjA6OTI6OWY6NTU6ODc6MTI6NTk6MTA6YzI6MGY6Njc6Njk6MTE6CisgICAgICAgIGNjOjRlOjFlOjdlOjRhOjlhOmFkOmFmOjQwOmE4Ojc1OmFjOjU2OjkwOjc0OmI4OmEwOjljOgorICAgICAgICBhNTo3OTo2ZjpkYzplOToxYTpjODo2OTowNTplOTpiYTpmYTowMzpiMzo3YzplNDplMDo0ZToKKyAgICAgICAgYzI6Y2U6OWQ6ZTg6YjY6NDY6MGQ6NmU6N2U6NTc6M2E6Njc6OTQ6YzI6Y2I6MWY6OWM6Nzc6CisgICAgICAgIDRhOjY3OjRlOjY5Ojg2OjQzOjkzOjM4OmZiOmI2OmRiOjRmOjgzOjkxOmQ0OjYwOjdlOjRiOgorICAgICAgICAzZToyYjozODowNzo1NTo5ODo1ZTphNAorU0hBMSBGaW5nZXJwcmludD1FMDpCNDozMjoyRTpCMjpGNjpBNTo2ODpCNjo1NDo1Mzo4NDo0ODoxODo0QTo1MDozNjo4Nzo0Mzo4NApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2ViMzc1YzNlLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZWIzNzVjM2UuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMDE5ZTY4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2ViMzc1YzNlLjAKQEAgLTAsMCArMSw3NyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEVXpDQ0FqdWdBd0lCQWdJQkFqQU5CZ2txaGtpRzl3MEJBUVVGQURCTE1Rc3dDUVlEVlFRR0V3Sk9UekVkCitNQnNHQTFVRUNnd1VRblY1Y0dGemN5QkJVeTA1T0RNeE5qTXpNamN4SFRBYkJnTlZCQU1NRkVKMWVYQmhjM01nCitRMnhoYzNNZ015QkRRU0F4TUI0WERUQTFNRFV3T1RFME1UTXdNMW9YRFRFMU1EVXdPVEUwTVRNd00xb3dTekVMCitNQWtHQTFVRUJoTUNUazh4SFRBYkJnTlZCQW9NRkVKMWVYQmhjM01nUVZNdE9UZ3pNVFl6TXpJM01SMHdHd1lECitWUVFEREJSQ2RYbHdZWE56SUVOc1lYTnpJRE1nUTBFZ01UQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQCitBRENDQVFvQ2dnRUJBS1NPMTNUWktXVGVYeCtIZ0pIcVRqbm1HY1pFQzREVkM2OVRCNHNTdmVabjhBS3hpZlpnCitpc1Jic0VMUndDR295K0diNzJSUnRxZlBGZlYwZ0dnRWtLQllvdVowcGxOVFZVaGpQNUpXM1NST2p2aTZLLy96CitOSXFlS05jMG42d3YxZy94cEMrOVVySkpoVzA1TmZCRU1KTkdKUE8yNTFQN3ZHR3ZxYU1VKzhJWEY0UnM0SHlJCisrTWtjVnl6d1BYNlV2Q1dUaE9pYUFKcEZCVUpYZ1BST3p0bXVPZmJJVXhBTVpUcEhlMkRDMXZxUnljWnhiTDJSCitoenlSaGttcjh3K2diQ1oyWGh5c20zSGxqYnliSVI2YzFqaCtKSUFWTVlLV3NVblRZamRiaUF3S1lqVCtwMGgrCittYkV3aTVBM2xSeW9INlVzamZSVnlOdmRXUXJDclhpZzlJc0NBd0VBQWFOQ01FQXdEd1lEVlIwVEFRSC9CQVV3CitBd0VCL3pBZEJnTlZIUTRFRmdRVU9CVG15UENwcEFQMFRqNGlvMXZ5MXVDdFFIUXdEZ1lEVlIwUEFRSC9CQVFECitBZ0VHTUEwR0NTcUdTSWIzRFFFQkJRVUFBNElCQVFBQlo2T015U1U5RTJOZEZtL3NvVDRKWEpFVktpclpnQ0ZQCitCZHk3cFltckV6TXFuamkzakc4Q2NtUEhjM2NlQ1FhNk95aDdwRWZKWVdzSUNDRDhpZ1dLSDd5NnhzTCt6MjdzCitFek54Wnk1cCtxa3NQMmJBRWxsTkMxUUNrb1M3MnhMdmczQndlTWhUK3QvR3h2L2NpQzhId0VtZE1sZGcwL0wyCittU2xmNTZvQnpLd3pxQndLdTVIRUE2QnZ0alQ1aHRPemRsU1k5RXFCczFPZFRVRHM1WGNUUmE5YnFoL1lMMHlDCitlLzRxeEZpN1QveWUvUU5sR2lvT3c2VWdGcFJyZWFhaUVyUzdHcVFqZWwvd3JvUWs1UE1yKzRva295ZVlaZG93CitkWGI4R1pIbzIrdWJQeksvUUpjSEpyck04NVNGU25vbms4K1FRdFM0V3hhbTU4dEFBOTE1CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDIgKDB4MikKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1OTywgTz1CdXlwYXNzIEFTLTk4MzE2MzMyNywgQ049QnV5cGFzcyBDbGFzcyAzIENBIDEKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IE1heSAgOSAxNDoxMzowMyAyMDA1IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogTWF5ICA5IDE0OjEzOjAzIDIwMTUgR01UCisgICAgICAgIFN1YmplY3Q6IEM9Tk8sIE89QnV5cGFzcyBBUy05ODMxNjMzMjcsIENOPUJ1eXBhc3MgQ2xhc3MgMyBDQSAxCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDphNDo4ZTpkNzo3NDpkOToyOTo2NDpkZTo1ZjoxZjo4Nzo4MDo5MTplYToKKyAgICAgICAgICAgICAgICAgICAgNGU6Mzk6ZTY6MTk6YzY6NDQ6MGI6ODA6ZDU6MGI6YWY6NTM6MDc6OGI6MTI6CisgICAgICAgICAgICAgICAgICAgIGJkOmU2OjY3OmYwOjAyOmIxOjg5OmY2OjYwOjhhOmM0OjViOmIwOjQyOmQxOgorICAgICAgICAgICAgICAgICAgICBjMDoyMTphODpjYjplMTo5YjplZjo2NDo1MTpiNjphNzpjZjoxNTpmNTo3NDoKKyAgICAgICAgICAgICAgICAgICAgODA6Njg6MDQ6OTA6YTA6NTg6YTI6ZTY6NzQ6YTY6NTM6NTM6NTU6NDg6NjM6CisgICAgICAgICAgICAgICAgICAgIDNmOjkyOjU2OmRkOjI0OjRlOjhlOmY4OmJhOjJiOmZmOmYzOjM0OjhhOjllOgorICAgICAgICAgICAgICAgICAgICAyODpkNzozNDo5ZjphYzoyZjpkNjowZjpmMTphNDoyZjpiZDo1MjpiMjo0OToKKyAgICAgICAgICAgICAgICAgICAgODU6NmQ6Mzk6MzU6ZjA6NDQ6MzA6OTM6NDY6MjQ6ZjM6YjY6ZTc6NTM6ZmI6CisgICAgICAgICAgICAgICAgICAgIGJjOjYxOmFmOmE5OmEzOjE0OmZiOmMyOjE3OjE3Ojg0OjZjOmUwOjdjOjg4OgorICAgICAgICAgICAgICAgICAgICBmODpjOToxYzo1NzoyYzpmMDozZDo3ZTo5NDpiYzoyNTo5Mzo4NDplODo5YToKKyAgICAgICAgICAgICAgICAgICAgMDA6OWE6NDU6MDU6NDI6NTc6ODA6ZjQ6NGU6Y2U6ZDk6YWU6Mzk6ZjY6Yzg6CisgICAgICAgICAgICAgICAgICAgIDUzOjEwOjBjOjY1OjNhOjQ3OjdiOjYwOmMyOmQ2OmZhOjkxOmM5OmM2OjcxOgorICAgICAgICAgICAgICAgICAgICA2YzpiZDo5MTo4NzozYzo5MTo4Njo0OTphYjpmMzowZjphMDo2YzoyNjo3NjoKKyAgICAgICAgICAgICAgICAgICAgNWU6MWM6YWM6OWI6NzE6ZTU6OGQ6YmM6OWI6MjE6MWU6OWM6ZDY6Mzg6N2U6CisgICAgICAgICAgICAgICAgICAgIDI0OjgwOjE1OjMxOjgyOjk2OmIxOjQ5OmQzOjYyOjM3OjViOjg4OjBjOjBhOgorICAgICAgICAgICAgICAgICAgICA2MjozNDpmZTphNzo0ODo3ZTo5OTpiMTozMDo4Yjo5MDozNzo5NToxYzphODoKKyAgICAgICAgICAgICAgICAgICAgMWY6YTU6MmM6OGQ6ZjQ6NTU6Yzg6ZGI6ZGQ6NTk6MGE6YzI6YWQ6Nzg6YTA6CisgICAgICAgICAgICAgICAgICAgIGY0OjhiCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgMzg6MTQ6RTY6Qzg6RjA6QTk6QTQ6MDM6RjQ6NEU6M0U6MjI6QTM6NUI6RjI6RDY6RTA6QUQ6NDA6NzQKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMDE6Njc6YTM6OGM6Yzk6MjU6M2Q6MTM6NjM6NWQ6MTY6NmY6ZWM6YTE6M2U6MDk6NWM6OTE6CisgICAgICAgIDE1OjJhOjJhOmQ5OjgwOjIxOjRmOjA1OmRjOmJiOmE1Ojg5OmFiOjEzOjMzOjJhOjllOjM4OgorICAgICAgICBiNzo4Yzo2ZjowMjo3Mjo2MzpjNzo3Mzo3NzoxZTowOTowNjpiYTozYjoyODo3YjphNDo0NzoKKyAgICAgICAgYzk6NjE6NmI6MDg6MDg6MjA6ZmM6OGE6MDU6OGE6MWY6YmM6YmE6YzY6YzI6ZmU6Y2Y6NmU6CisgICAgICAgIGVjOjEzOjMzOjcxOjY3OjJlOjY5OmZhOmE5OjJjOjNmOjY2OmMwOjEyOjU5OjRkOjBiOjU0OgorICAgICAgICAwMjo5Mjo4NDpiYjpkYjoxMjplZjo4Mzo3MDo3MDo3ODpjODo1MzpmYTpkZjpjNjpjNjpmZjoKKyAgICAgICAgZGM6ODg6MmY6MDc6YzA6NDk6OWQ6MzI6NTc6NjA6ZDM6ZjI6ZjY6OTk6Mjk6NWY6ZTc6YWE6CisgICAgICAgIDAxOmNjOmFjOjMzOmE4OjFjOjBhOmJiOjkxOmM0OjAzOmEwOjZmOmI2OjM0OmY5Ojg2OmQzOgorICAgICAgICBiMzo3Njo1NDo5ODpmNDo0YTo4MTpiMzo1Mzo5ZDo0ZDo0MDplYzplNTo3NzoxMzo0NTphZjoKKyAgICAgICAgNWI6YWE6MWY6ZDg6MmY6NGM6ODI6N2I6ZmU6MmE6YzQ6NTg6YmI6NGY6ZmM6OWU6ZmQ6MDM6CisgICAgICAgIDY1OjFhOjJhOjBlOmMzOmE1OjIwOjE2Ojk0OjZiOjc5OmE2OmEyOjEyOmI0OmJiOjFhOmE0OgorICAgICAgICAyMzo3YTo1ZjpmMDphZTo4NDoyNDplNDpmMzoyYjpmYjo4YToyNDphMzoyNzo5ODo2NTpkYToKKyAgICAgICAgMzA6NzU6NzY6ZmM6MTk6OTE6ZTg6ZGI6ZWI6OWI6M2Y6MzI6YmY6NDA6OTc6MDc6MjY6YmE6CisgICAgICAgIGNjOmYzOjk0Ojg1OjRhOjdhOjI3OjkzOmNmOjkwOjQyOmQ0OmI4OjViOjE2OmE2OmU3OmNiOgorICAgICAgICA0MDowMzpkZDo3OQorU0hBMSBGaW5nZXJwcmludD02MTo1NzozQToxMTpERjowRTpEODo3RTpENTo5Mjo2NToyMjpFQTpEMDo1NjpENzo0NDpCMzoyMzo3MQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2VkMDQ5ODM1LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZWQwNDk4MzUuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZjdlZTdkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2VkMDQ5ODM1LjAKQEAgLTAsMCArMSw1NCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEQWpDQ0Ftc0NFREtJanByUzllc1RSL2gveENBM0pmZ3dEUVlKS29aSWh2Y05BUUVGQlFBd2djRXhDekFKCitCZ05WQkFZVEFsVlRNUmN3RlFZRFZRUUtFdzVXWlhKcFUybG5iaXdnU1c1akxqRThNRG9HQTFVRUN4TXpRMnhoCitjM01nTkNCUWRXSnNhV01nVUhKcGJXRnllU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVTQXRJRWN5CitNVG93T0FZRFZRUUxFekVvWXlrZ01UazVPQ0JXWlhKcFUybG5iaXdnU1c1akxpQXRJRVp2Y2lCaGRYUm9iM0pwCitlbVZrSUhWelpTQnZibXg1TVI4d0hRWURWUVFMRXhaV1pYSnBVMmxuYmlCVWNuVnpkQ0JPWlhSM2IzSnJNQjRYCitEVGs0TURVeE9EQXdNREF3TUZvWERUSTRNRGd3TVRJek5UazFPVm93Z2NFeEN6QUpCZ05WQkFZVEFsVlRNUmN3CitGUVlEVlFRS0V3NVdaWEpwVTJsbmJpd2dTVzVqTGpFOE1Eb0dBMVVFQ3hNelEyeGhjM01nTkNCUWRXSnNhV01nCitVSEpwYldGeWVTQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVNBdElFY3lNVG93T0FZRFZRUUxFekVvCitZeWtnTVRrNU9DQldaWEpwVTJsbmJpd2dTVzVqTGlBdElFWnZjaUJoZFhSb2IzSnBlbVZrSUhWelpTQnZibXg1CitNUjh3SFFZRFZRUUxFeFpXWlhKcFUybG5iaUJVY25WemRDQk9aWFIzYjNKck1JR2ZNQTBHQ1NxR1NJYjNEUUVCCitBUVVBQTRHTkFEQ0JpUUtCZ1FDNjhPVFArY1N1aFZTNUIxZjVqOFYvYUJINHhCZXdSTnpqTUhQVkttSXF1TkRNCitITzBvVzM2OWF0eXprU1RLUVdJOC9BSUJ2eHdXTVpRRmwzWnVvcTI5WVJkc1RqQ0c4RkUzS2xESHFHS0IzRnRLCitxc0dndEc3ckwrVlh4YkVyUUhEYldrMmhqaCs5QXgvWUE5U1BUSmx4dk9LQ3pGam9tRHFHMDRZNDh3QXBId0lECitBUUFCTUEwR0NTcUdTSWIzRFFFQkJRVUFBNEdCQUlXTUVzR251VkFWZXNzK3JMaERpdHlxM1JTNmlZRitBVHdqCitjU0dJTDRMY1kvb0NSYXhGV2RjcVdFUmJ0NStCTzVKb1BlSTNKUFY3Ykk5Mk5aWUpxRm1kdWM0anEzVFdnLzB5CitjeWZZYVQ1RGRQYXV4WW1hNTFOODZYdjJTL1BCWllQZWpZcWNQSWlOT1ZuOHFqOGlqYUhCWmxDQmNrenRJbVJQCitUOHFBa2JZcAorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMSAoMHgwKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgMzI6ODg6OGU6OWE6ZDI6ZjU6ZWI6MTM6NDc6Zjg6N2Y6YzQ6MjA6Mzc6MjU6ZjgKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgTz1WZXJpU2lnbiwgSW5jLiwgT1U9Q2xhc3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyLCBPVT0oYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5LCBPVT1WZXJpU2lnbiBUcnVzdCBOZXR3b3JrCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBNYXkgMTggMDA6MDA6MDAgMTk5OCBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IEF1ZyAgMSAyMzo1OTo1OSAyMDI4IEdNVAorICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPVZlcmlTaWduLCBJbmMuLCBPVT1DbGFzcyA0IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIsIE9VPShjKSAxOTk4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHksIE9VPVZlcmlTaWduIFRydXN0IE5ldHdvcmsKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgxMDI0IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgxMDI0IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmJhOmYwOmU0OmNmOmY5OmM0OmFlOjg1OjU0OmI5OjA3OjU3OmY5OjhmOgorICAgICAgICAgICAgICAgICAgICBjNTo3Zjo2ODoxMTpmODpjNDoxNzpiMDo0NDpkYzplMzozMDo3MzpkNToyYToKKyAgICAgICAgICAgICAgICAgICAgNjI6MmE6Yjg6ZDA6Y2M6MWM6ZWQ6Mjg6NWI6N2U6YmQ6NmE6ZGM6YjM6OTE6CisgICAgICAgICAgICAgICAgICAgIDI0OmNhOjQxOjYyOjNjOmZjOjAyOjAxOmJmOjFjOjE2OjMxOjk0OjA1Ojk3OgorICAgICAgICAgICAgICAgICAgICA3Njo2ZTphMjphZDpiZDo2MToxNzo2Yzo0ZTozMDo4NjpmMDo1MTozNzoyYToKKyAgICAgICAgICAgICAgICAgICAgNTA6Yzc6YTg6NjI6ODE6ZGM6NWI6NGE6YWE6YzE6YTA6YjQ6NmU6ZWI6MmY6CisgICAgICAgICAgICAgICAgICAgIGU1OjU3OmM1OmIxOjJiOjQwOjcwOmRiOjVhOjRkOmExOjhlOjFmOmJkOjAzOgorICAgICAgICAgICAgICAgICAgICAxZjpkODowMzpkNDo4Zjo0Yzo5OTo3MTpiYzplMjo4MjpjYzo1ODplODo5ODoKKyAgICAgICAgICAgICAgICAgICAgM2E6ODY6ZDM6ODY6Mzg6ZjM6MDA6Mjk6MWYKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDg1OjhjOjEyOmMxOmE3OmI5OjUwOjE1OjdhOmNiOjNlOmFjOmI4OjQzOjhhOmRjOmFhOmRkOgorICAgICAgICAxNDpiYTo4OTo4MTo3ZTowMTozYzoyMzo3MToyMTo4ODoyZjo4MjpkYzo2MzpmYTowMjo0NToKKyAgICAgICAgYWM6NDU6NTk6ZDc6MmE6NTg6NDQ6NWI6Yjc6OWY6ODE6M2I6OTI6Njg6M2Q6ZTI6Mzc6MjQ6CisgICAgICAgIGY1OjdiOjZjOjhmOjc2OjM1Ojk2OjA5OmE4OjU5OjlkOmI5OmNlOjIzOmFiOjc0OmQ2OjgzOgorICAgICAgICBmZDozMjo3MzoyNzpkODo2OTozZTo0Mzo3NDpmNjphZTpjNTo4OTo5YTplNzo1Mzo3YzplOToKKyAgICAgICAgN2I6ZjY6NGI6ZjM6YzE6NjU6ODM6ZGU6OGQ6OGE6OWM6M2M6ODg6OGQ6Mzk6NTk6ZmM6YWE6CisgICAgICAgIDNmOjIyOjhkOmExOmMxOjY2OjUwOjgxOjcyOjRjOmVkOjIyOjY0OjRmOjRmOmNhOjgwOjkxOgorICAgICAgICBiNjoyOQorU0hBMSBGaW5nZXJwcmludD0wQjo3NzpCRTpCQjpDQjo3QTpBMjo0NzowNTpERTpDQzowRjpCRDo2QTowMjpGQzo3QTpCRDo5Qjo1MgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2VkNTI0Y2Y1LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZWQ1MjRjZjUuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NmU3N2Q2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2VkNTI0Y2Y1LjAKQEAgLTAsMCArMSw4MyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFMkRDQ0JFR2dBd0lCQWdJRU4wclNRekFOQmdrcWhraUc5dzBCQVFVRkFEQ0J3ekVMTUFrR0ExVUVCaE1DCitWVk14RkRBU0JnTlZCQW9UQzBWdWRISjFjM1F1Ym1WME1Uc3dPUVlEVlFRTEV6SjNkM2N1Wlc1MGNuVnpkQzV1CitaWFF2UTFCVElHbHVZMjl5Y0M0Z1lua2djbVZtTGlBb2JHbHRhWFJ6SUd4cFlXSXVLVEVsTUNNR0ExVUVDeE1jCitLR01wSURFNU9Ua2dSVzUwY25WemRDNXVaWFFnVEdsdGFYUmxaREU2TURnR0ExVUVBeE14Ulc1MGNuVnpkQzV1CitaWFFnVTJWamRYSmxJRk5sY25abGNpQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVRBZUZ3MDVPVEExCitNalV4TmpBNU5EQmFGdzB4T1RBMU1qVXhOak01TkRCYU1JSERNUXN3Q1FZRFZRUUdFd0pWVXpFVU1CSUdBMVVFCitDaE1MUlc1MGNuVnpkQzV1WlhReE96QTVCZ05WQkFzVE1uZDNkeTVsYm5SeWRYTjBMbTVsZEM5RFVGTWdhVzVqCitiM0p3TGlCaWVTQnlaV1l1SUNoc2FXMXBkSE1nYkdsaFlpNHBNU1V3SXdZRFZRUUxFeHdvWXlrZ01UazVPU0JGCitiblJ5ZFhOMExtNWxkQ0JNYVcxcGRHVmtNVG93T0FZRFZRUURFekZGYm5SeWRYTjBMbTVsZENCVFpXTjFjbVVnCitVMlZ5ZG1WeUlFTmxjblJwWm1sallYUnBiMjRnUVhWMGFHOXlhWFI1TUlHZE1BMEdDU3FHU0liM0RRRUJBUVVBCitBNEdMQURDQmh3S0JnUUROS0lNMFZCdUo4dyt2TjVFeC82OHhZTW1vNkxJUWFPMmY1NU0yOFFwa3UwZjFCQmMvCitJMGROeFNjWmdTWU1WSElOaUMzWkg1b1NuN3l6Y2RPQUdUOUhabnVNTlNqU3VRcmZKTnFjMWxCNWdYcGEwemYzCit3a3JZS1pJbVpOSGttR3c2QUlyMU5KdGwrTzNqRVAvOXVFbFkzS0RlZ2pscmdiRVdHV0c1VkxibVF3SUJBNk9DCitBZGN3Z2dIVE1CRUdDV0NHU0FHRytFSUJBUVFFQXdJQUJ6Q0NBUmtHQTFVZEh3U0NBUkF3Z2dFTU1JSGVvSUhiCitvSUhZcElIVk1JSFNNUXN3Q1FZRFZRUUdFd0pWVXpFVU1CSUdBMVVFQ2hNTFJXNTBjblZ6ZEM1dVpYUXhPekE1CitCZ05WQkFzVE1uZDNkeTVsYm5SeWRYTjBMbTVsZEM5RFVGTWdhVzVqYjNKd0xpQmllU0J5WldZdUlDaHNhVzFwCitkSE1nYkdsaFlpNHBNU1V3SXdZRFZRUUxFeHdvWXlrZ01UazVPU0JGYm5SeWRYTjBMbTVsZENCTWFXMXBkR1ZrCitNVG93T0FZRFZRUURFekZGYm5SeWRYTjBMbTVsZENCVFpXTjFjbVVnVTJWeWRtVnlJRU5sY25ScFptbGpZWFJwCitiMjRnUVhWMGFHOXlhWFI1TVEwd0N3WURWUVFERXdSRFVrd3hNQ21nSjZBbGhpTm9kSFJ3T2k4dmQzZDNMbVZ1CitkSEoxYzNRdWJtVjBMME5TVEM5dVpYUXhMbU55YkRBckJnTlZIUkFFSkRBaWdBOHhPVGs1TURVeU5URTJNRGswCitNRnFCRHpJd01Ua3dOVEkxTVRZd09UUXdXakFMQmdOVkhROEVCQU1DQVFZd0h3WURWUjBqQkJnd0ZvQVU4QmRpCitFMVU5cy84S0FHdjdVSVNYOCsxaTBCb3dIUVlEVlIwT0JCWUVGUEFYWWhOVlBiUC9DZ0JyKzFDRWwvUHRZdEFhCitNQXdHQTFVZEV3UUZNQU1CQWY4d0dRWUpLb1pJaHZaOUIwRUFCQXd3Q2hzRVZqUXVNQU1DQkpBd0RRWUpLb1pJCitodmNOQVFFRkJRQURnWUVBa053d0F2cGtkTUtuQ3FWOElZMDBGNmo3Unc3L0pYeU5Fd3I3NUppMTc0ejR4UkFOCis5NUsrOGNQVjFaVnFCTHNzemlZMlpjZ3h4dWZ1UCtOWGRZUjZFZTlHVHhqMDA1aTdxSWN5dW5MMlBPSTluOWNkCisyY05nUTR4WURpS1dMMktqTEIrNnJRWHZxeko0aDZCVWN4bTFYQVg1VWo1dExVVUw5d3FUNnUwRytiST0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogOTI3NjUwMzcxICgweDM3NGFkMjQzKQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPUVudHJ1c3QubmV0LCBPVT13d3cuZW50cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKSwgT1U9KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZCwgQ049RW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogTWF5IDI1IDE2OjA5OjQwIDE5OTkgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBNYXkgMjUgMTY6Mzk6NDAgMjAxOSBHTVQKKyAgICAgICAgU3ViamVjdDogQz1VUywgTz1FbnRydXN0Lm5ldCwgT1U9d3d3LmVudHJ1c3QubmV0L0NQUyBpbmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLiksIE9VPShjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQsIENOPUVudHJ1c3QubmV0IFNlY3VyZSBTZXJ2ZXIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgxMDI0IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgxMDI0IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmNkOjI4OjgzOjM0OjU0OjFiOjg5OmYzOjBmOmFmOjM3OjkxOjMxOmZmOgorICAgICAgICAgICAgICAgICAgICBhZjozMTo2MDpjOTphODplODpiMjoxMDo2ODplZDo5ZjplNzo5MzozNjpmMToKKyAgICAgICAgICAgICAgICAgICAgMGE6NjQ6YmI6NDc6ZjU6MDQ6MTc6M2Y6MjM6NDc6NGQ6YzU6Mjc6MTk6ODE6CisgICAgICAgICAgICAgICAgICAgIDI2OjBjOjU0OjcyOjBkOjg4OjJkOmQ5OjFmOjlhOjEyOjlmOmJjOmIzOjcxOgorICAgICAgICAgICAgICAgICAgICBkMzo4MDoxOTozZjo0Nzo2Njo3Yjo4YzozNToyODpkMjpiOTowYTpkZjoyNDoKKyAgICAgICAgICAgICAgICAgICAgZGE6OWM6ZDY6NTA6Nzk6ODE6N2E6NWE6ZDM6Mzc6Zjc6YzI6NGE6ZDg6Mjk6CisgICAgICAgICAgICAgICAgICAgIDkyOjI2OjY0OmQxOmU0Ojk4OjZjOjNhOjAwOjhhOmY1OjM0OjliOjY1OmY4OgorICAgICAgICAgICAgICAgICAgICBlZDplMzoxMDpmZjpmZDpiODo0OTo1ODpkYzphMDpkZTo4MjozOTo2Yjo4MToKKyAgICAgICAgICAgICAgICAgICAgYjE6MTY6MTk6NjE6Yjk6NTQ6YjY6ZTY6NDMKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogMyAoMHgzKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIE5ldHNjYXBlIENlcnQgVHlwZTogCisgICAgICAgICAgICAgICAgU1NMIENBLCBTL01JTUUgQ0EsIE9iamVjdCBTaWduaW5nIENBCisgICAgICAgICAgICBYNTA5djMgQ1JMIERpc3RyaWJ1dGlvbiBQb2ludHM6IAorICAgICAgICAgICAgICAgIERpck5hbWU6L0M9VVMvTz1FbnRydXN0Lm5ldC9PVT13d3cuZW50cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKS9PVT0oYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVkL0NOPUVudHJ1c3QubmV0IFNlY3VyZSBTZXJ2ZXIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkvQ049Q1JMMQorICAgICAgICAgICAgICAgIFVSSTpodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9uZXQxLmNybAorCisgICAgICAgICAgICBYNTA5djMgUHJpdmF0ZSBLZXkgVXNhZ2UgUGVyaW9kOiAKKyAgICAgICAgICAgICAgICBOb3QgQmVmb3JlOiBNYXkgMjUgMTY6MDk6NDAgMTk5OSBHTVQsIE5vdCBBZnRlcjogTWF5IDI1IDE2OjA5OjQwIDIwMTkgR01UCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiAKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6RjA6MTc6NjI6MTM6NTU6M0Q6QjM6RkY6MEE6MDA6NkI6RkI6NTA6ODQ6OTc6RjM6RUQ6NjI6RDA6MUEKKworICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEYwOjE3OjYyOjEzOjU1OjNEOkIzOkZGOjBBOjAwOjZCOkZCOjUwOjg0Ojk3OkYzOkVEOjYyOkQwOjFBCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIDEuMi44NDAuMTEzNTMzLjcuNjUuMDogCisgICAgICAgICAgICAgICAgMAorLi5WNC4wLi4uLgorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA5MDpkYzozMDowMjpmYTo2NDo3NDpjMjphNzowYTphNTo3YzoyMTo4ZDozNDoxNzphODpmYjoKKyAgICAgICAgNDc6MGU6ZmY6MjU6N2M6OGQ6MTM6MGE6ZmI6ZTQ6OTg6YjU6ZWY6OGM6Zjg6YzU6MTA6MGQ6CisgICAgICAgIGY3OjkyOmJlOmYxOmMzOmQ1OmQ1Ojk1OjZhOjA0OmJiOjJjOmNlOjI2OjM2OjY1OmM4OjMxOgorICAgICAgICBjNjplNzplZTozZjplMzo1Nzo3NTo4NDo3YToxMTplZjo0Njo0ZjoxODpmNDpkMzo5ODpiYjoKKyAgICAgICAgYTg6ODc6MzI6YmE6NzI6ZjY6M2M6ZTI6M2Q6OWY6ZDc6MWQ6ZDk6YzM6NjA6NDM6OGM6NTg6CisgICAgICAgIDBlOjIyOjk2OjJmOjYyOmEzOjJjOjFmOmJhOmFkOjA1OmVmOmFiOjMyOjc4Ojg3OmEwOjU0OgorICAgICAgICA3MzoxOTpiNTo1YzowNTpmOTo1MjozZTo2ZDoyZDo0NTowYjpmNzowYTo5MzplYTplZDowNjoKKyAgICAgICAgZjk6YjIKK1NIQTEgRmluZ2VycHJpbnQ9OTk6QTY6OUI6RTY6MUE6RkU6ODg6NkI6NEQ6MkI6ODI6MDA6N0M6Qjg6NTQ6RkM6MzE6N0U6MTU6MzkKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9lZTdjZDZmYi4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2VlN2NkNmZiLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2RmZmQwMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9lZTdjZDZmYi4wCkBAIC0wLDAgKzEsOTggQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRXZUQ0NBNldnQXdJQkFnSUJBREFOQmdrcWhraUc5dzBCQVFVRkFEQi9NUXN3Q1FZRFZRUUdFd0pGVlRFbgorTUNVR0ExVUVDaE1lUVVNZ1EyRnRaWEptYVhKdFlTQlRRU0JEU1VZZ1FUZ3lOelF6TWpnM01TTXdJUVlEVlFRTAorRXhwb2RIUndPaTh2ZDNkM0xtTm9ZVzFpWlhKemFXZHVMbTl5WnpFaU1DQUdBMVVFQXhNWlEyaGhiV0psY25NZworYjJZZ1EyOXRiV1Z5WTJVZ1VtOXZkREFlRncwd016QTVNekF4TmpFek5ETmFGdzB6TnpBNU16QXhOakV6TkRSYQorTUg4eEN6QUpCZ05WQkFZVEFrVlZNU2N3SlFZRFZRUUtFeDVCUXlCRFlXMWxjbVpwY20xaElGTkJJRU5KUmlCQgorT0RJM05ETXlPRGN4SXpBaEJnTlZCQXNUR21oMGRIQTZMeTkzZDNjdVkyaGhiV0psY25OcFoyNHViM0puTVNJdworSUFZRFZRUURFeGxEYUdGdFltVnljeUJ2WmlCRGIyMXRaWEpqWlNCU2IyOTBNSUlCSURBTkJna3Foa2lHOXcwQgorQVFFRkFBT0NBUTBBTUlJQkNBS0NBUUVBdHpaVjVhVmRHRERnMm9sVWtmekl4MUw0TDFEWjc3RjFjMlZIZlJ0YgordW5YRi9LR0lKUG92N2NvSVNqbFV4RkY2dGRwZzZqZzhnYkxMOGJ2WmtTTS9TQUZ3ZGFrRktxMGZjZlBKVkQwZAorQm1wQVByTU1oZTVjRzNuQ1lzUzRObzQxWFFFTUl3UkhOYXFiWUU2Z1pqM0xKZ3FjUUtIMFhaaS9jYXVsQUdncQorN1lONkQ2SVV0ZFFpczRDd1BBeGFVV2t0V0JpUDdabWU4YTdpbGViMlI2aldEQSt3V0ZqYncyWTNucHVSVkRNMworMHBRY2Frakp5ZktsMnFVTUkvY2pEcHd5VlY1eG5JUUZVWm90L2VaT0tqUmEzc3BBTjJjTVZDRlZkOW9LRE15WAorcm9EY2xEWks5RDdPTmhNZVUrU3NUam9GN051dWNwdzRpOUE1TzRrS1BuZitkUUlCQTZPQ0FVUXdnZ0ZBTUJJRworQTFVZEV3RUIvd1FJTUFZQkFmOENBUXd3UEFZRFZSMGZCRFV3TXpBeG9DK2dMWVlyYUhSMGNEb3ZMMk55YkM1agorYUdGdFltVnljMmxuYmk1dmNtY3ZZMmhoYldKbGNuTnliMjkwTG1OeWJEQWRCZ05WSFE0RUZnUVU0NVQxc1UzcAorMjZFcFcxZUxUWFlHZHVIUm9vb3dEZ1lEVlIwUEFRSC9CQVFEQWdFR01CRUdDV0NHU0FHRytFSUJBUVFFQXdJQQorQnpBbkJnTlZIUkVFSURBZWdSeGphR0Z0WW1WeWMzSnZiM1JBWTJoaGJXSmxjbk5wWjI0dWIzSm5NQ2NHQTFVZAorRWdRZ01CNkJIR05vWVcxaVpYSnpjbTl2ZEVCamFHRnRZbVZ5YzJsbmJpNXZjbWN3V0FZRFZSMGdCRkV3VHpCTgorQmdzckJnRUVBWUdITGdvREFUQStNRHdHQ0NzR0FRVUZCd0lCRmpCb2RIUndPaTh2WTNCekxtTm9ZVzFpWlhKegorYVdkdUxtOXlaeTlqY0hNdlkyaGhiV0psY25OeWIyOTBMbWgwYld3d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQgorQUF4Qmw4SWFoc0FpZkovN2tQTWEwUU94N3hQNUlWOEVuTnJKcFkwbmJKYUhrYjVCa0FGeWsrY2VmVi8yaWNaZAorcDBBSlBheEpSVVhjTG8wd2FMSUp1dnZETDh5NkM5OC9kM3RHZlRvU0pJNldqendGQ20vU2xDZ2RiUXpBTG9naQorMWRqUEhSUEg4RWpYMXdXbno4ZEhuanM4Tk1pQVQ5UVV1L3dOVVBmNnMreENYNm5kYmNqMGRjOTd3WEltc1FFYworWEN6OWVrNjBBY1VGVjdublBLb0YyWWpwQjBaQnp1OUJnYTVZMzRPaXJzclhkeC9uQUR5ZGI0N2tNZ2tkVFhnMAorZURROGxKc203VTl4eGhsNnZTQWlTRnIrUzMwRHQrZFl2c1l5VG5RZWFOMm9hRnV6UHU1aWZkbUE2QXAxZXJmdQordEdXYUlaRGdxdENZdkRpMWN6eUwrTnc9CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6IDAgKDB4MCkKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1FVSwgTz1BQyBDYW1lcmZpcm1hIFNBIENJRiBBODI3NDMyODcsIE9VPWh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnLCBDTj1DaGFtYmVycyBvZiBDb21tZXJjZSBSb290CisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBTZXAgMzAgMTY6MTM6NDMgMjAwMyBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IFNlcCAzMCAxNjoxMzo0NCAyMDM3IEdNVAorICAgICAgICBTdWJqZWN0OiBDPUVVLCBPPUFDIENhbWVyZmlybWEgU0EgQ0lGIEE4Mjc0MzI4NywgT1U9aHR0cDovL3d3dy5jaGFtYmVyc2lnbi5vcmcsIENOPUNoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmI3OjM2OjU1OmU1OmE1OjVkOjE4OjMwOmUwOmRhOjg5OjU0OjkxOmZjOgorICAgICAgICAgICAgICAgICAgICBjODpjNzo1MjpmODoyZjo1MDpkOTplZjpiMTo3NTo3Mzo2NTo0Nzo3ZDoxYjoKKyAgICAgICAgICAgICAgICAgICAgNWI6YmE6NzU6YzU6ZmM6YTE6ODg6MjQ6ZmE6MmY6ZWQ6Y2E6MDg6NGE6Mzk6CisgICAgICAgICAgICAgICAgICAgIDU0OmM0OjUxOjdhOmI1OmRhOjYwOmVhOjM4OjNjOjgxOmIyOmNiOmYxOmJiOgorICAgICAgICAgICAgICAgICAgICBkOTo5MToyMzozZjo0ODowMTo3MDo3NTphOTowNToyYTphZDoxZjo3MTpmMzoKKyAgICAgICAgICAgICAgICAgICAgYzk6NTQ6M2Q6MWQ6MDY6NmE6NDA6M2U6YjM6MGM6ODU6ZWU6NWM6MWI6Nzk6CisgICAgICAgICAgICAgICAgICAgIGMyOjYyOmM0OmI4OjM2OjhlOjM1OjVkOjAxOjBjOjIzOjA0OjQ3OjM1OmFhOgorICAgICAgICAgICAgICAgICAgICA5Yjo2MDo0ZTphMDo2NjozZDpjYjoyNjowYTo5Yzo0MDphMTpmNDo1ZDo5ODoKKyAgICAgICAgICAgICAgICAgICAgYmY6NzE6YWI6YTU6MDA6Njg6MmE6ZWQ6ODM6N2E6MGY6YTI6MTQ6YjU6ZDQ6CisgICAgICAgICAgICAgICAgICAgIDIyOmIzOjgwOmIwOjNjOjBjOjVhOjUxOjY5OjJkOjU4OjE4OjhmOmVkOjk5OgorICAgICAgICAgICAgICAgICAgICA5ZTpmMTphZTplMjo5NTplNjpmNjo0NzphODpkNjowYzowZjpiMDo1ODo1ODoKKyAgICAgICAgICAgICAgICAgICAgZGI6YzM6NjY6Mzc6OWU6OWI6OTE6NTQ6MzM6Mzc6ZDI6OTQ6MWM6NmE6NDg6CisgICAgICAgICAgICAgICAgICAgIGM5OmM5OmYyOmE1OmRhOmE1OjBjOjIzOmY3OjIzOjBlOjljOjMyOjU1OjVlOgorICAgICAgICAgICAgICAgICAgICA3MTo5Yzo4NDowNTo1MTo5YToyZDpmZDplNjo0ZToyYTozNDo1YTpkZTpjYToKKyAgICAgICAgICAgICAgICAgICAgNDA6Mzc6Njc6MGM6NTQ6MjE6NTU6Nzc6ZGE6MGE6MGM6Y2M6OTc6YWU6ODA6CisgICAgICAgICAgICAgICAgICAgIGRjOjk0OjM2OjRhOmY0OjNlOmNlOjM2OjEzOjFlOjUzOmU0OmFjOjRlOjNhOgorICAgICAgICAgICAgICAgICAgICAwNTplYzpkYjphZTo3Mjo5YzozODo4YjpkMDozOTozYjo4OTowYTozZTo3NzoKKyAgICAgICAgICAgICAgICAgICAgZmU6NzUKKyAgICAgICAgICAgICAgICBFeHBvbmVudDogMyAoMHgzKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFLCBwYXRobGVuOjEyCisgICAgICAgICAgICBYNTA5djMgQ1JMIERpc3RyaWJ1dGlvbiBQb2ludHM6IAorICAgICAgICAgICAgICAgIFVSSTpodHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9jaGFtYmVyc3Jvb3QuY3JsCisKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBFMzo5NDpGNTpCMTo0RDpFOTpEQjpBMToyOTo1Qjo1Nzo4Qjo0RDo3NjowNjo3NjpFMTpEMTpBMjo4QQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgTmV0c2NhcGUgQ2VydCBUeXBlOiAKKyAgICAgICAgICAgICAgICBTU0wgQ0EsIFMvTUlNRSBDQSwgT2JqZWN0IFNpZ25pbmcgQ0EKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEFsdGVybmF0aXZlIE5hbWU6IAorICAgICAgICAgICAgICAgIGVtYWlsOmNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcKKyAgICAgICAgICAgIFg1MDl2MyBJc3N1ZXIgQWx0ZXJuYXRpdmUgTmFtZTogCisgICAgICAgICAgICAgICAgZW1haWw6Y2hhbWJlcnNyb290QGNoYW1iZXJzaWduLm9yZworICAgICAgICAgICAgWDUwOXYzIENlcnRpZmljYXRlIFBvbGljaWVzOiAKKyAgICAgICAgICAgICAgICBQb2xpY3k6IDEuMy42LjEuNC4xLjE3MzI2LjEwLjMuMQorICAgICAgICAgICAgICAgICAgQ1BTOiBodHRwOi8vY3BzLmNoYW1iZXJzaWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwKKworICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAwYzo0MTo5NzpjMjoxYTo4NjpjMDoyMjo3Yzo5ZjpmYjo5MDpmMzoxYTpkMTowMzpiMTplZjoKKyAgICAgICAgMTM6Zjk6MjE6NWY6MDQ6OWM6ZGE6Yzk6YTU6OGQ6Mjc6NmM6OTY6ODc6OTE6YmU6NDE6OTA6CisgICAgICAgIDAxOjcyOjkzOmU3OjFlOjdkOjVmOmY2Ojg5OmM2OjVkOmE3OjQwOjA5OjNkOmFjOjQ5OjQ1OgorICAgICAgICA0NTpkYzoyZTo4ZDozMDo2ODpiMjowOTpiYTpmYjpjMzoyZjpjYzpiYTowYjpkZjozZjo3NzoKKyAgICAgICAgN2I6NDY6N2Q6M2E6MTI6MjQ6OGU6OTY6OGY6M2M6MDU6MGE6NmY6ZDI6OTQ6Mjg6MWQ6NmQ6CisgICAgICAgIDBjOmMwOjJlOjg4OjIyOmQ1OmQ4OmNmOjFkOjEzOmM3OmYwOjQ4OmQ3OmQ3OjA1OmE3OmNmOgorICAgICAgICBjNzo0Nzo5ZTozYjozYzozNDpjODo4MDo0ZjpkNDoxNDpiYjpmYzowZDo1MDpmNzpmYTpiMzoKKyAgICAgICAgZWM6NDI6NWY6YTk6ZGQ6NmQ6Yzg6ZjQ6NzU6Y2Y6N2I6YzE6NzI6MjY6YjE6MDE6MWM6NWM6CisgICAgICAgIDJjOmZkOjdhOjRlOmI0OjAxOmM1OjA1OjU3OmI5OmU3OjNjOmFhOjA1OmQ5Ojg4OmU5OjA3OgorICAgICAgICA0Njo0MTpjZTplZjo0MTo4MTphZTo1ODpkZjo4MzphMjphZTpjYTpkNzo3NzoxZjplNzowMDoKKyAgICAgICAgM2M6OWQ6NmY6OGU6ZTQ6MzI6MDk6MWQ6NGQ6Nzg6MzQ6Nzg6MzQ6M2M6OTQ6OWI6MjY6ZWQ6CisgICAgICAgIDRmOjcxOmM2OjE5OjdhOmJkOjIwOjIyOjQ4OjVhOmZlOjRiOjdkOjAzOmI3OmU3OjU4OmJlOgorICAgICAgICBjNjozMjo0ZTo3NDoxZTo2ODpkZDphODo2ODo1YjpiMzozZTplZTo2Mjo3ZDpkOTo4MDplODoKKyAgICAgICAgMGE6NzU6N2E6Yjc6ZWU6YjQ6NjU6OWE6MjE6OTA6ZTA6YWE6ZDA6OTg6YmM6Mzg6YjU6NzM6CisgICAgICAgIDNjOjhiOmY4OmRjCitTSEExIEZpbmdlcnByaW50PTZFOjNBOjU1OkE0OjE5OjBDOjE5OjVDOjkzOjg0OjNDOkMwOkRCOjcyOjJFOjMxOjMwOjYxOkYwOkIxCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZjQ5OTZlODIuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9mNDk5NmU4Mi4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVhMTBiMWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZjQ5OTZlODIuMApAQCAtMCwwICsxLDUyIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUM1ekNDQWxBQ0FRRXdEUVlKS29aSWh2Y05BUUVGQlFBd2dic3hKREFpQmdOVkJBY1RHMVpoYkdsRFpYSjAKK0lGWmhiR2xrWVhScGIyNGdUbVYwZDI5eWF6RVhNQlVHQTFVRUNoTU9WbUZzYVVObGNuUXNJRWx1WXk0eE5UQXoKK0JnTlZCQXNUTEZaaGJHbERaWEowSUVOc1lYTnpJREVnVUc5c2FXTjVJRlpoYkdsa1lYUnBiMjRnUVhWMGFHOXkKK2FYUjVNU0V3SHdZRFZRUURFeGhvZEhSd09pOHZkM2QzTG5aaGJHbGpaWEowTG1OdmJTOHhJREFlQmdrcWhraUcKKzl3MEJDUUVXRVdsdVptOUFkbUZzYVdObGNuUXVZMjl0TUI0WERUazVNRFl5TlRJeU1qTTBPRm9YRFRFNU1EWXkKK05USXlNak0wT0Zvd2dic3hKREFpQmdOVkJBY1RHMVpoYkdsRFpYSjBJRlpoYkdsa1lYUnBiMjRnVG1WMGQyOXkKK2F6RVhNQlVHQTFVRUNoTU9WbUZzYVVObGNuUXNJRWx1WXk0eE5UQXpCZ05WQkFzVExGWmhiR2xEWlhKMElFTnMKK1lYTnpJREVnVUc5c2FXTjVJRlpoYkdsa1lYUnBiMjRnUVhWMGFHOXlhWFI1TVNFd0h3WURWUVFERXhob2RIUncKK09pOHZkM2QzTG5aaGJHbGpaWEowTG1OdmJTOHhJREFlQmdrcWhraUc5dzBCQ1FFV0VXbHVabTlBZG1Gc2FXTmwKK2NuUXVZMjl0TUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FEWVdZSjZpYmlXdXFZdmFHOVkKK0xxZFVIQVp1OU9xTlNMd3hsQmZ3ODA2OHNyZzFrbmF3MEtXbEFkY0FBeElpR1FqNC94RWptODRIOWI5cEdpYisKK1R1blJmNTBzUUIxWmFHNm0rRml3blJxUDB6L3gzQmtHZ2FnTzREcmR5Rk5GQ1FibUQzREQra0NtRHVKV0JROFkKK1Rmd2dndEZ6VlhTTmRuS2dIWjBkd04wL2NRSURBUUFCTUEwR0NTcUdTSWIzRFFFQkJRVUFBNEdCQUZCb1BVbjAKK0xCd0dsTitWWUgrV2V4ZitUM0d0Wk1qZGQ5THZXVlhvUCtpT0JTb2g4Z2ZTdGFkUy9weXh0dUpiZHhkQTZuTFcKK0k4c29nVExEQUhrWTdGa1hpY25HYWg1eHlmMjNkS1VsUlduRlNLc1o0VVdLSldzWjd1VzdFdlYvOTZhTlVjUHcKK25YUzNxVDZncGYrMlNRTVQyaUxNN1hHQ0s1blBPcmYxTFhMSQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMSAoMHgwKQorICAgICAgICBTZXJpYWwgTnVtYmVyOiAxICgweDEpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEw9VmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrLCBPPVZhbGlDZXJ0LCBJbmMuLCBPVT1WYWxpQ2VydCBDbGFzcyAxIFBvbGljeSBWYWxpZGF0aW9uIEF1dGhvcml0eSwgQ049aHR0cDovL3d3dy52YWxpY2VydC5jb20vL2VtYWlsQWRkcmVzcz1pbmZvQHZhbGljZXJ0LmNvbQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogSnVuIDI1IDIyOjIzOjQ4IDE5OTkgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBKdW4gMjUgMjI6MjM6NDggMjAxOSBHTVQKKyAgICAgICAgU3ViamVjdDogTD1WYWxpQ2VydCBWYWxpZGF0aW9uIE5ldHdvcmssIE89VmFsaUNlcnQsIEluYy4sIE9VPVZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5LCBDTj1odHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8vZW1haWxBZGRyZXNzPWluZm9AdmFsaWNlcnQuY29tCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMTAyNCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMTAyNCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpkODo1OTo4Mjo3YTo4OTpiODo5NjpiYTphNjoyZjo2ODo2Zjo1ODoyZToKKyAgICAgICAgICAgICAgICAgICAgYTc6NTQ6MWM6MDY6NmU6ZjQ6ZWE6OGQ6NDg6YmM6MzE6OTQ6MTc6ZjA6ZjM6CisgICAgICAgICAgICAgICAgICAgIDRlOmJjOmIyOmI4OjM1OjkyOjc2OmIwOmQwOmE1OmE1OjAxOmQ3OjAwOjAzOgorICAgICAgICAgICAgICAgICAgICAxMjoyMjoxOTowODpmODpmZjoxMToyMzo5YjpjZTowNzpmNTpiZjo2OToxYToKKyAgICAgICAgICAgICAgICAgICAgMjY6ZmU6NGU6ZTk6ZDE6N2Y6OWQ6MmM6NDA6MWQ6NTk6Njg6NmU6YTY6Zjg6CisgICAgICAgICAgICAgICAgICAgIDU4OmIwOjlkOjFhOjhmOmQzOjNmOmYxOmRjOjE5OjA2OjgxOmE4OjBlOmUwOgorICAgICAgICAgICAgICAgICAgICAzYTpkZDpjODo1Mzo0NTowOTowNjplNjowZjo3MDpjMzpmYTo0MDphNjowZToKKyAgICAgICAgICAgICAgICAgICAgZTI6NTY6MDU6MGY6MTg6NGQ6ZmM6MjA6ODI6ZDE6NzM6NTU6NzQ6OGQ6NzY6CisgICAgICAgICAgICAgICAgICAgIDcyOmEwOjFkOjlkOjFkOmMwOmRkOjNmOjcxCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA1MDo2ODozZDo0OTpmNDoyYzoxYzowNjo5NDpkZjo5NTo2MDo3Zjo5Njo3YjoxNzpmZTo0ZjoKKyAgICAgICAgNzE6YWQ6NjQ6Yzg6ZGQ6Nzc6ZDI6ZWY6NTk6NTU6ZTg6M2Y6ZTg6OGU6MDU6MmE6MjE6ZjI6CisgICAgICAgIDA3OmQyOmI1OmE3OjUyOmZlOjljOmIxOmI2OmUyOjViOjc3OjE3OjQwOmVhOjcyOmQ2OjIzOgorICAgICAgICBjYjoyODo4MTozMjpjMzowMDo3OToxODplYzo1OToxNzo4OTpjOTpjNjo2YToxZTo3MTpjOToKKyAgICAgICAgZmQ6Yjc6NzQ6YTU6MjU6NDU6Njk6YzU6NDg6YWI6MTk6ZTE6NDU6OGE6MjU6NmI6MTk6ZWU6CisgICAgICAgIGU1OmJiOjEyOmY1OjdmOmY3OmE2OjhkOjUxOmMzOmYwOjlkOjc0OmI3OmE5OjNlOmEwOmE1OgorICAgICAgICBmZjpiNjo0OTowMzoxMzpkYToyMjpjYzplZDo3MTo4MjoyYjo5OTpjZjozYTpiNzpmNToyZDoKKyAgICAgICAgNzI6YzgKK1NIQTEgRmluZ2VycHJpbnQ9RTU6REY6NzQ6M0M6QjY6MDE6QzQ6OUI6OTg6NDM6REM6QUI6OEM6RTg6NkE6ODE6MTA6OUY6RTQ6OEUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9mNThhNjBmZS4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2Y1OGE2MGZlLjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTlmN2RhYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9mNThhNjBmZS4wCkBAIC0wLDAgKzEsODYgQEAKKy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorTUlJRHF6Q0NBcE9nQXdJQkFnSVJBTWNvUndtenVHeEZqQjM2SlBVMlR1a3dEUVlKS29aSWh2Y05BUUVGQlFBdworUERFYk1Ca0dBMVVFQXhNU1EyOXRVMmxuYmlCVFpXTjFjbVZrSUVOQk1SQXdEZ1lEVlFRS0V3ZERiMjFUYVdkdQorTVFzd0NRWURWUVFHRXdKSlREQWVGdzB3TkRBek1qUXhNVE0zTWpCYUZ3MHlPVEF6TVRZeE5UQTBOVFphTUR3eAorR3pBWkJnTlZCQU1URWtOdmJWTnBaMjRnVTJWamRYSmxaQ0JEUVRFUU1BNEdBMVVFQ2hNSFEyOXRVMmxuYmpFTAorTUFrR0ExVUVCaE1DU1V3d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURHdFdoZgorSFpRVnc2UUlWUzNqb0ZkNjcrbDBLcnU1ZkZkSkdoRmVUeW1IREVqV2F1ZVAxSDVYSkxrR2llUWNQT3FzNDlvaAorZ0hNaEN1OTVtR3dmQ1AraFVIM3ltQnZKVkc4K3BTanNJUVFQUmJzSFBhSEEraXFZSFU0R2svdjFpRHVyWDhzVworditiem5rcUg3Um5xd3A5RDVQR0JwWDhRVHo3UlNtS3RVeHZMZy84SFphV1NMV2FwVzdoYTlCMjBJWkZLRjN1ZQorTXY1V0pEbXlWSVJEOVlUQzJMeEJrTXlkMW1qYTZZSlFxVHRvejdWZEFwUmdGckZEMlVOZDNWMkhidXE3czhscgorOWdPVUNYRGVGaEY2SytoMmowa1FtSGU1WTF5TE01ZDE5Z3VNc3F0YjNuUWdKVC9qOHhINWgyaUdOWEhESFl3dAorNitVYXJBOXoxWUpaUUlEVEFnTUJBQUdqZ2Fjd2dhUXdEQVlEVlIwVEJBVXdBd0VCL3pCRUJnTlZIUjhFUFRBNworTURtZ042QTFoak5vZEhSd09pOHZabVZrYVhJdVkyOXRjMmxuYmk1amJ5NXBiQzlqY213dlEyOXRVMmxuYmxObAorWTNWeVpXUkRRUzVqY213d0RnWURWUjBQQVFIL0JBUURBZ0dHTUI4R0ExVWRJd1FZTUJhQUZNRkw3WEMyOXo1OAorQURzQWo4YytEa1dmSGwzc01CMEdBMVVkRGdRV0JCVEJTKzF3dHZjK2ZBQTdBSS9IUGc1Rm54NWQ3REFOQmdrcQoraGtpRzl3MEJBUVVGQUFPQ0FRRUFGcy91a2hOUXEzc1Vuak8yUWlCcTFCVzlDYXY4Y3VqdlIzcVFyRkhCWkU3cAoraUwxRFJZSGpaaU0vRW9aTkdlUUZzT1kzd28zYUJpakpENG1rVTZsMVA3Q1crNnRNTTFYNWVDWkdieHMybVB0QworZHNHQ3VZN2UrMFg1WXh0aU96a0d5bmQ2cUR3SnoydzJQUThLUlV0cEZocEZmVE1EWmZsU2NaQW1sYXhNRFBXTAora3ovTWRYU0ZtTHIvWW5wTkg0bitycjJVQUptL0VhWGM0SG5GRmd0OUFtRWQ2b1g1QWhWUDUxcUpUaFJ2NHpkTAoraGZYQlBHSGcvUVZCc3BKL3d4MmcwSzVTWkdCckdNWW1uTmoxWk9RMkdtS2ZpZzgrLzIxT0dWWk9JSkZzbnpRegorT2pSWFVEcHZnVjRHeHZVK2ZFNk9LODVsQmk1ZDBpcFRkRjdUYmllZWp3PT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIGM3OjI4OjQ3OjA5OmIzOmI4OjZjOjQ1OjhjOjFkOmZhOjI0OmY1OjM2OjRlOmU5CisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IENOPUNvbVNpZ24gU2VjdXJlZCBDQSwgTz1Db21TaWduLCBDPUlMCisgICAgICAgIFZhbGlkaXR5CisgICAgICAgICAgICBOb3QgQmVmb3JlOiBNYXIgMjQgMTE6Mzc6MjAgMjAwNCBHTVQKKyAgICAgICAgICAgIE5vdCBBZnRlciA6IE1hciAxNiAxNTowNDo1NiAyMDI5IEdNVAorICAgICAgICBTdWJqZWN0OiBDTj1Db21TaWduIFNlY3VyZWQgQ0EsIE89Q29tU2lnbiwgQz1JTAorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YzY6YjU6Njg6NWY6MWQ6OTQ6MTU6YzM6YTQ6MDg6NTU6MmQ6ZTM6YTA6CisgICAgICAgICAgICAgICAgICAgIDU3OjdhOmVmOmU5Ojc0OjJhOmJiOmI5OjdjOjU3OjQ5OjFhOjExOjVlOjRmOgorICAgICAgICAgICAgICAgICAgICAyOTo4NzowYzo0ODpkNjo2YTplNzo4ZjpkNDo3ZTo1NzoyNDpiOTowNjo4OToKKyAgICAgICAgICAgICAgICAgICAgZTQ6MWM6M2M6ZWE6YWM6ZTM6ZGE6MjE6ODA6NzM6MjE6MGE6ZWY6Nzk6OTg6CisgICAgICAgICAgICAgICAgICAgIDZjOjFmOjA4OmZmOmExOjUwOjdkOmYyOjk4OjFiOmM5OjU0OjZmOjNlOmE1OgorICAgICAgICAgICAgICAgICAgICAyODplYzoyMTowNDowZjo0NTpiYjowNzozZDphMTpjMDpmYToyYTo5ODoxZDoKKyAgICAgICAgICAgICAgICAgICAgNGU6MDY6OTM6ZmI6ZjU6ODg6M2I6YWI6NWY6Y2I6MTY6YmY6ZTY6ZjM6OWU6CisgICAgICAgICAgICAgICAgICAgIDRhOjg3OmVkOjE5OmVhOmMyOjlmOjQzOmU0OmYxOjgxOmE1OjdmOjEwOjRmOgorICAgICAgICAgICAgICAgICAgICAzZTpkMTo0YTo2MjphZDo1MzoxYjpjYjo4MzpmZjowNzo2NTphNTo5MjoyZDoKKyAgICAgICAgICAgICAgICAgICAgNjY6YTk6NWI6Yjg6NWE6ZjQ6MWQ6YjQ6MjE6OTE6NGE6MTc6N2I6OWU6MzI6CisgICAgICAgICAgICAgICAgICAgIGZlOjU2OjI0OjM5OmIyOjU0Ojg0OjQzOmY1Ojg0OmMyOmQ4OmJjOjQxOjkwOgorICAgICAgICAgICAgICAgICAgICBjYzo5ZDpkNjo2ODpkYTplOTo4Mjo1MDphOTozYjo2ODpjZjpiNTo1ZDowMjoKKyAgICAgICAgICAgICAgICAgICAgOTQ6NjA6MTY6YjE6NDM6ZDk6NDM6NWQ6ZGQ6NWQ6ODc6NmU6ZWE6YmI6YjM6CisgICAgICAgICAgICAgICAgICAgIGM5OjZiOmY2OjAzOjk0OjA5OjcwOmRlOjE2OjExOjdhOjJiOmU4Ojc2OjhmOgorICAgICAgICAgICAgICAgICAgICA0OToxMDo5ODo3NzpiOTo2Mzo1Yzo4YjozMzo5Nzo3NTpmNjowYjo4YzpiMjoKKyAgICAgICAgICAgICAgICAgICAgYWI6NWI6ZGU6NzQ6MjA6MjU6M2Y6ZTM6ZjM6MTE6Zjk6ODc6Njg6ODY6MzU6CisgICAgICAgICAgICAgICAgICAgIDcxOmMzOjFkOjhjOjJkOmViOmU1OjFhOmFjOjBmOjczOmQ1OjgyOjU5OjQwOgorICAgICAgICAgICAgICAgICAgICA4MDpkMworICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgIFg1MDl2MyBDUkwgRGlzdHJpYnV0aW9uIFBvaW50czogCisgICAgICAgICAgICAgICAgVVJJOmh0dHA6Ly9mZWRpci5jb21zaWduLmNvLmlsL2NybC9Db21TaWduU2VjdXJlZENBLmNybAorCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIERpZ2l0YWwgU2lnbmF0dXJlLCBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAga2V5aWQ6QzE6NEI6RUQ6NzA6QjY6Rjc6M0U6N0M6MDA6M0I6MDA6OEY6Qzc6M0U6MEU6NDU6OUY6MUU6NUQ6RUMKKworICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEMxOjRCOkVEOjcwOkI2OkY3OjNFOjdDOjAwOjNCOjAwOjhGOkM3OjNFOjBFOjQ1OjlGOjFFOjVEOkVDCisgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIDE2OmNmOmVlOjkyOjEzOjUwOmFiOjdiOjE0OjllOjMzOmI2OjQyOjIwOjZhOmQ0OjE1OmJkOgorICAgICAgICAwOTphYjpmYzo3MjplODplZjo0Nzo3YTo5MDphYzo1MTpjMTo2NDo0ZTplOTo4ODpiZDo0MzoKKyAgICAgICAgNDU6ODE6ZTM6NjY6MjM6M2Y6MTI6ODY6NGQ6MTk6ZTQ6MDU6YjA6ZTY6Mzc6YzI6OGQ6ZGE6CisgICAgICAgIDA2OjI4OmM5OjBmOjg5OmE0OjUzOmE5Ojc1OjNmOmIwOjk2OmZiOmFiOjRjOjMzOjU1OmY5OgorICAgICAgICA3ODoyNjo0Njo2ZjoxYjozNjo5ODpmYjo0Mjo3NjpjMTo4MjpiOTo4ZTpkZTpmYjo0NTpmOToKKyAgICAgICAgNjM6MWI6NjI6M2I6Mzk6MDY6Y2E6Nzc6N2E6YTg6M2M6MDk6Y2Y6NmM6MzY6M2Q6MGY6MGE6CisgICAgICAgIDQ1OjRiOjY5OjE2OjFhOjQ1OjdkOjMzOjAzOjY1OmY5OjUyOjcxOjkwOjI2Ojk1OmFjOjRjOgorICAgICAgICAwYzpmNTo4Yjo5MzozZjpjYzo3NTo3NDo4NTo5ODpiYTpmZjo2Mjo3YTo0ZDoxZjo4OTpmZToKKyAgICAgICAgYWU6YmQ6OTQ6MDA6OTk6YmY6MTE6YTU6ZGM6ZTA6Nzk6YzU6MTY6MGI6N2Q6MDI6NjE6MWQ6CisgICAgICAgIGVhOjg1OmY5OjAyOjE1OjRmOmU3OjVhOjg5OjRlOjE0OjZmOmUzOjM3OjRiOjg1OmY1OmMxOgorICAgICAgICAzYzo2MTplMDpmZDowNTo0MTpiMjo5Mjo3ZjpjMzoxZDphMDpkMDphZTo1Mjo2NDo2MDo2YjoKKyAgICAgICAgMTg6YzY6MjY6OWM6ZDg6ZjU6NjQ6ZTQ6MzY6MWE6NjI6OWY6OGE6MGY6M2U6ZmY6NmQ6NGU6CisgICAgICAgIDE5OjU2OjRlOjIwOjkxOjZjOjlmOjM0OjMzOjNhOjM0OjU3OjUwOjNhOjZmOjgxOjVlOjA2OgorICAgICAgICBjNjpmNTozZTo3Yzo0ZTo4ZToyYjpjZTo2NTowNjoyZTo1ZDpkMjoyYTo1Mzo3NDo1ZTpkMzoKKyAgICAgICAgNmU6Mjc6OWU6OGYKK1NIQTEgRmluZ2VycHJpbnQ9Rjk6Q0Q6MEU6MkM6REE6NzY6MjQ6QzE6OEY6QkQ6RjA6RjA6QUI6QjY6NDU6Qjg6Rjc6RkU6RDU6N0EKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9mNjFiZmY0NS4wIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2Y2MWJmZjQ1LjAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzYxNDNjOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9mNjFiZmY0NS4wCkBAIC0wLDAgKzEsMTIyIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSUhxRENDQnBDZ0F3SUJBZ0lSQU15NDU3OU9LUnI5b3R4bXBSd3NEeEV3RFFZSktvWklodmNOQVFFRkJRQXcKK2NqRUxNQWtHQTFVRUJoTUNTRlV4RVRBUEJnTlZCQWNUQ0VKMVpHRndaWE4wTVJZd0ZBWURWUVFLRXcxTmFXTnkKK2IzTmxZeUJNZEdRdU1SUXdFZ1lEVlFRTEV3dGxMVk42YVdkdWJ5QkRRVEVpTUNBR0ExVUVBeE1aVFdsamNtOXoKK1pXTWdaUzFUZW1sbmJtOGdVbTl2ZENCRFFUQWVGdzB3TlRBME1EWXhNakk0TkRSYUZ3MHhOekEwTURZeE1qSTQKK05EUmFNSEl4Q3pBSkJnTlZCQVlUQWtoVk1SRXdEd1lEVlFRSEV3aENkV1JoY0dWemRERVdNQlFHQTFVRUNoTU4KK1RXbGpjbTl6WldNZ1RIUmtMakVVTUJJR0ExVUVDeE1MWlMxVGVtbG5ibThnUTBFeElqQWdCZ05WQkFNVEdVMXAKK1kzSnZjMlZqSUdVdFUzcHBaMjV2SUZKdmIzUWdRMEV3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXcKK2dnRUtBb0lCQVFEdHlBRFZnWHZOT0FCSHpOdUV3U0ZwTEhTUURDSFpVNGZ0UGtORVU2K3IrSUNiUEhpTjFJMnUKK3VPL1RFZHlCNXM4N2xveldieFhHZDM2aEwrQmZrclluMTNhYUhVTTg2dG5zTCs0NTgycG5TNHVDenlMNFpWWCsKK0xNc3ZmVWg2UFhYNXFxQW51M2pDQnNwUnduNW1TNi9Ob3FkTkFvSS9ncXlGeHVFUGtFZVpsQXB4Y3BNcXlhYkEKK3ZqeFdUSE9TSi9GcnRmWDkvREFGWUpMRzY1WitBWkhDYWJFZUhYdFRSYmpjUVIvSmkzSFdWQlRqaTFSNFA3NzAKK1lqdGI5YVBzMVpKMDRuUXc3d0hiNGRTcm1ac3FhL2k5cGh5R0kwSmY3RW5lbW90YjlISTZRTVZKUHFXK2pxcHgKKzYyejY5UnJrYXYxN2ZWVkE3MWh1NXRuVnZDU3J3ZSszQWdNQkFBR2pnZ1EzTUlJRU16Qm5CZ2dyQmdFRkJRY0IKK0FRUmJNRmt3S0FZSUt3WUJCUVVITUFHR0hHaDBkSEJ6T2k4dmNtTmhMbVV0YzNwcFoyNXZMbWgxTDI5amMzQXcKK0xRWUlLd1lCQlFVSE1BS0dJV2gwZEhBNkx5OTNkM2N1WlMxemVtbG5ibTh1YUhVdlVtOXZkRU5CTG1OeWREQVAKK0JnTlZIUk1CQWY4RUJUQURBUUgvTUlJQmN3WURWUjBnQklJQmFqQ0NBV1l3Z2dGaUJnd3JCZ0VFQVlHb0dBSUIKK0FRRXdnZ0ZRTUNnR0NDc0dBUVVGQndJQkZoeG9kSFJ3T2k4dmQzZDNMbVV0YzNwcFoyNXZMbWgxTDFOYVUxb3YKK01JSUJJZ1lJS3dZQkJRVUhBZ0l3Z2dFVUhvSUJFQUJCQUNBQWRBQmhBRzRBK2dCekFPMEFkQUIyQU9FQWJnQjUKK0FDQUE2UUJ5QUhRQVpRQnNBRzBBWlFCNkFPa0Fjd0RwQUdnQVpRQjZBQ0FBNlFCekFDQUFaUUJzQUdZQWJ3Qm4KK0FHRUFaQURoQUhNQTRRQm9BRzhBZWdBZ0FHRUFJQUJUQUhvQWJ3QnNBR2NBNFFCc0FIUUFZUUIwQVBNQUlBQlQKK0FIb0Fid0JzQUdjQTRRQnNBSFFBWVFCMEFPRUFjd0JwQUNBQVV3QjZBR0VBWWdEaEFHd0FlUUI2QUdFQWRBQmgKK0FDQUFjd0I2QUdVQWNnQnBBRzRBZEFBZ0FHc0FaUUJzQUd3QUlBQmxBR3dBYWdEaEFISUFiZ0JwQURvQUlBQm8KK0FIUUFkQUJ3QURvQUx3QXZBSGNBZHdCM0FDNEFaUUF0QUhNQWVnQnBBR2NBYmdCdkFDNEFhQUIxQUM4QVV3QmEKK0FGTUFXZ0F2TUlISUJnTlZIUjhFZ2NBd2diMHdnYnFnZ2JlZ2diU0dJV2gwZEhBNkx5OTNkM2N1WlMxemVtbG4KK2JtOHVhSFV2VW05dmRFTkJMbU55YklhQmpteGtZWEE2THk5c1pHRndMbVV0YzNwcFoyNXZMbWgxTDBOT1BVMXAKK1kzSnZjMlZqSlRJd1pTMVRlbWxuYm04bE1qQlNiMjkwSlRJd1EwRXNUMVU5WlMxVGVtbG5ibThsTWpCRFFTeFAKK1BVMXBZM0p2YzJWakpUSXdUSFJrTGl4TVBVSjFaR0Z3WlhOMExFTTlTRlUvWTJWeWRHbG1hV05oZEdWU1pYWnYKK1kyRjBhVzl1VEdsemREdGlhVzVoY25rd0RnWURWUjBQQVFIL0JBUURBZ0VHTUlHV0JnTlZIUkVFZ1k0d2dZdUIKK0VHbHVabTlBWlMxemVtbG5ibTh1YUhXa2R6QjFNU013SVFZRFZRUUREQnBOYVdOeWIzTmxZeUJsTFZONmFXZHUKK3c3TWdVbTl2ZENCRFFURVdNQlFHQTFVRUN3d05aUzFUZW1sbmJzT3pJRWhUV2pFV01CUUdBMVVFQ2hNTlRXbGoKK2NtOXpaV01nUzJaMExqRVJNQThHQTFVRUJ4TUlRblZrWVhCbGMzUXhDekFKQmdOVkJBWVRBa2hWTUlHc0JnTlYKK0hTTUVnYVF3Z2FHQUZNZWdTWFVXWVlUYk1VdUUwdkUzUUpEdlR0ejNvWGFrZERCeU1Rc3dDUVlEVlFRR0V3SkkKK1ZURVJNQThHQTFVRUJ4TUlRblZrWVhCbGMzUXhGakFVQmdOVkJBb1REVTFwWTNKdmMyVmpJRXgwWkM0eEZEQVMKK0JnTlZCQXNUQzJVdFUzcHBaMjV2SUVOQk1TSXdJQVlEVlFRREV4bE5hV055YjNObFl5QmxMVk42YVdkdWJ5QlMKK2IyOTBJRU5CZ2hFQXpMam52MDRwR3YyaTNHYWxIQ3dQRVRBZEJnTlZIUTRFRmdRVXg2QkpkUlpoaE5zeFM0VFMKKzhUZEFrTzlPM1Bjd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFOTVRuR1pqV1M3S1hIQU0vSU84VmJIMGpnZHMKK1ppZk93VHNncVJ5N1JsUnc3bHJNb0hmcWFFUW42L0lwM1hlcDFmdmoxS2NFeEpXNEMrRkVhR0FIUXpBeFFtSGwKKzd0bmxKTlViMytGS0c2cWZ4MS80ZWhIcUU1TUF5b3BZc2U3dERrMjAxNmcySm56Z09zSFZWNEx4ZGJiOWlWL2EKKzg2ZzRuelVHQ000aWxiN04xZnkrVzk1NWE5eDZxV1ZtdnJFbFdsL3RmdE9zUm0xTTlES0h0Q0FFNEd4NHNIZlIKK2hVWkxwaEszZGVoS3lWWnMxNUtybmZWSk9OSlBVK05Wa0JIYm1KYkdTZkkrOUo4YjRQZUkzQ1ZpbVVUWWM3OC8KK01QTU1OejdVd2lpQWM3RUJ0NTFhbGhRQlM2a1JuU2xxTHRCZGdjRFBzaUJEeHdQZ04wNWRDdHhaSUNVPQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgY2M6Yjg6ZTc6YmY6NGU6Mjk6MWE6ZmQ6YTI6ZGM6NjY6YTU6MWM6MmM6MGY6MTEKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1IVSwgTD1CdWRhcGVzdCwgTz1NaWNyb3NlYyBMdGQuLCBPVT1lLVN6aWdubyBDQSwgQ049TWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogQXByICA2IDEyOjI4OjQ0IDIwMDUgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBBcHIgIDYgMTI6Mjg6NDQgMjAxNyBHTVQKKyAgICAgICAgU3ViamVjdDogQz1IVSwgTD1CdWRhcGVzdCwgTz1NaWNyb3NlYyBMdGQuLCBPVT1lLVN6aWdubyBDQSwgQ049TWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6ZWQ6Yzg6MDA6ZDU6ODE6N2I6Y2Q6Mzg6MDA6NDc6Y2M6ZGI6ODQ6YzE6CisgICAgICAgICAgICAgICAgICAgIDIxOjY5OjJjOjc0OjkwOjBjOjIxOmQ5OjUzOjg3OmVkOjNlOjQzOjQ0OjUzOgorICAgICAgICAgICAgICAgICAgICBhZjphYjpmODo4MDo5YjozYzo3ODo4ZDpkNDo4ZDphZTpiODplZjpkMzoxMToKKyAgICAgICAgICAgICAgICAgICAgZGM6ODE6ZTY6Y2Y6M2I6OTY6OGM6ZDY6NmY6MTU6YzY6Nzc6N2U6YTE6MmY6CisgICAgICAgICAgICAgICAgICAgIGUwOjVmOjkyOmI2OjI3OmQ3Ojc2OjlhOjFkOjQzOjNjOmVhOmQ5OmVjOjJmOgorICAgICAgICAgICAgICAgICAgICBlZTozOTpmMzo2YTo2Nzo0Yjo4Yjo4MjpjZjoyMjpmODo2NTo1NTpmZToyYzoKKyAgICAgICAgICAgICAgICAgICAgY2I6MmY6N2Q6NDg6N2E6M2Q6NzU6Zjk6YWE6YTA6Mjc6YmI6Nzg6YzI6MDY6CisgICAgICAgICAgICAgICAgICAgIGNhOjUxOmMyOjdlOjY2OjRiOmFmOmNkOmEyOmE3OjRkOjAyOjgyOjNmOjgyOgorICAgICAgICAgICAgICAgICAgICBhYzo4NTpjNjplMTowZjo5MDo0Nzo5OTo5NDowYTo3MTo3Mjo5MzoyYTpjOToKKyAgICAgICAgICAgICAgICAgICAgYTY6YzA6YmU6M2M6NTY6NGM6NzM6OTI6Mjc6ZjE6NmI6YjU6ZjU6ZmQ6ZmM6CisgICAgICAgICAgICAgICAgICAgIDMwOjA1OjYwOjkyOmM2OmViOjk2OjdlOjAxOjkxOmMyOjY5OmIxOjFlOjFkOgorICAgICAgICAgICAgICAgICAgICA3Yjo1Mzo0NTpiODpkYzo0MToxZjpjOTo4Yjo3MTpkNjo1NDoxNDplMzo4YjoKKyAgICAgICAgICAgICAgICAgICAgNTQ6Nzg6M2Y6YmU6ZjQ6NjI6M2I6NWI6ZjU6YTM6ZWM6ZDU6OTI6NzQ6ZTI6CisgICAgICAgICAgICAgICAgICAgIDc0OjMwOmVmOjAxOmRiOmUxOmQ0OmFiOjk5OjliOjJhOjZiOmY4OmJkOmE2OgorICAgICAgICAgICAgICAgICAgICAxYzo4NjoyMzo0Mjo1ZjplYzo0OTpkZTo5YTo4Yjo1YjpmNDo3MjozYTo0MDoKKyAgICAgICAgICAgICAgICAgICAgYzU6NDk6M2U6YTU6YmU6OGU6YWE6NzE6ZWI6NmM6ZmE6ZjU6MWE6ZTQ6NmE6CisgICAgICAgICAgICAgICAgICAgIGZkOjdiOjdkOjU1OjQwOmVmOjU4OjZlOmU2OmQ5OmQ1OmJjOjI0OmFiOmMxOgorICAgICAgICAgICAgICAgICAgICBlZjpiNworICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBBdXRob3JpdHkgSW5mb3JtYXRpb24gQWNjZXNzOiAKKyAgICAgICAgICAgICAgICBPQ1NQIC0gVVJJOmh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AKKyAgICAgICAgICAgICAgICBDQSBJc3N1ZXJzIC0gVVJJOmh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydAorCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIENlcnRpZmljYXRlIFBvbGljaWVzOiAKKyAgICAgICAgICAgICAgICBQb2xpY3k6IDEuMy42LjEuNC4xLjIxNTI4LjIuMS4xLjEKKyAgICAgICAgICAgICAgICAgIENQUzogaHR0cDovL3d3dy5lLXN6aWduby5odS9TWlNaLworICAgICAgICAgICAgICAgICAgVXNlciBOb3RpY2U6CisgICAgICAgICAgICAgICAgICAgIEV4cGxpY2l0IFRleHQ6IAorCisgICAgICAgICAgICBYNTA5djMgQ1JMIERpc3RyaWJ1dGlvbiBQb2ludHM6IAorICAgICAgICAgICAgICAgIFVSSTpodHRwOi8vd3d3LmUtc3ppZ25vLmh1L1Jvb3RDQS5jcmwKKyAgICAgICAgICAgICAgICBVUkk6bGRhcDovL2xkYXAuZS1zemlnbm8uaHUvQ049TWljcm9zZWMlMjBlLVN6aWdubyUyMFJvb3QlMjBDQSxPVT1lLVN6aWdubyUyMENBLE89TWljcm9zZWMlMjBMdGQuLEw9QnVkYXBlc3QsQz1IVT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0O2JpbmFyeQorCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBBbHRlcm5hdGl2ZSBOYW1lOiAKKyAgICAgICAgICAgICAgICBlbWFpbDppbmZvQGUtc3ppZ25vLmh1LCBEaXJOYW1lOi9DTj1NaWNyb3NlYyBlLVN6aWduXHhDM1x4QjMgUm9vdCBDQS9PVT1lLVN6aWduXHhDM1x4QjMgSFNaL089TWljcm9zZWMgS2Z0Li9MPUJ1ZGFwZXN0L0M9SFUKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOkM3OkEwOjQ5Ojc1OjE2OjYxOjg0OkRCOjMxOjRCOjg0OkQyOkYxOjM3OjQwOjkwOkVGOjRFOkRDOkY3CisgICAgICAgICAgICAgICAgRGlyTmFtZTovQz1IVS9MPUJ1ZGFwZXN0L089TWljcm9zZWMgTHRkLi9PVT1lLVN6aWdubyBDQS9DTj1NaWNyb3NlYyBlLVN6aWdubyBSb290IENBCisgICAgICAgICAgICAgICAgc2VyaWFsOkNDOkI4OkU3OkJGOjRFOjI5OjFBOkZEOkEyOkRDOjY2OkE1OjFDOjJDOjBGOjExCisKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBDNzpBMDo0OTo3NToxNjo2MTo4NDpEQjozMTo0Qjo4NDpEMjpGMTozNzo0MDo5MDpFRjo0RTpEQzpGNworICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBkMzoxMzo5Yzo2Njo2Mzo1OToyZTpjYTo1Yzo3MDowYzpmYzo4MzpiYzo1NTpiMTpmNDo4ZToKKyAgICAgICAgMDc6NmM6NjY6Mjc6Y2U6YzE6M2I6MjA6YTk6MWM6YmI6NDY6NTQ6NzA6ZWU6NWE6Y2M6YTA6CisgICAgICAgIDc3OmVhOjY4OjQ0OjI3OmViOmYyOjI5OmRkOjc3OmE5OmQ1OmZiOmUzOmQ0OmE3OjA0OmM0OgorICAgICAgICA5NTpiODowYjplMTo0NDo2ODo2MDowNzo0MzozMDozMTo0Mjo2MTplNTplZTpkOTplNToyNDoKKyAgICAgICAgZDU6MWI6ZGY6ZTE6NGE6MWI6YWE6OWY6Yzc6NWY6Zjg6N2E6MTE6ZWE6MTM6OTM6MDA6Y2E6CisgICAgICAgIDhhOjU4OmIxOmVlOmVkOjBlOjRkOmI0OmQ3OmE4OjM2OjI2OjdjOmUwOjNhOmMxOmQ1OjU3OgorICAgICAgICA4MjpmMTo3NTpiNjpmZDo4OTo1ZjpkYTpmMzphODozODo5ZjozNTowNjowODpjZToyMjo5NToKKyAgICAgICAgYmU6Y2Q6ZDU6ZmM6YmU6NWI6ZGU6Nzk6NmI6ZGM6N2E6YTk6NjU6NjY6YmU6YjE6MjU6NWE6CisgICAgICAgIDVmOmVkOjdlOmQzOmFjOjQ2OjZkOjRjOmY0OjMyOjg3OmI0OjIwOjA0OmUwOjZjOjc4OmIwOgorICAgICAgICA3NzpkMTo4NTo0Njo0YjphNjoxMjpiNzo3NTplODo0YTpjOTo1Njo2YzpkNzo5MjphYjo5ZDoKKyAgICAgICAgZjU6NDk6Mzg6ZDI6NGY6NTM6ZTM6NTU6OTA6MTE6ZGI6OTg6OTY6YzY6NDk6ZjI6M2U6ZjQ6CisgICAgICAgIDlmOjFiOmUwOmY3Ojg4OmRjOjI1OjYyOjk5OjQ0OmQ4OjczOmJmOjNmOjMwOmYzOjBjOjM3OgorICAgICAgICAzZTpkNDpjMjoyODo4MDo3MzpiMTowMTpiNzo5ZDo1YTo5NjoxNDowMTo0YjphOToxMTo5ZDoKKyAgICAgICAgMjk6NmE6MmU6ZDA6NWQ6ODE6YzA6Y2Y6YjI6MjA6NDM6Yzc6MDM6ZTA6Mzc6NGU6NWQ6MGE6CisgICAgICAgIGRjOjU5OjIwOjI1CitTSEExIEZpbmdlcnByaW50PTIzOjg4OkM5OkQzOjcxOkNDOjlFOjk2OjNEOkZGOjdEOjNDOkE3OkNFOkZDOkQ2OjI1OkVDOjE5OjBECmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZjgwY2M3ZjYuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9mODBjYzdmNi4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQzZWNmMDIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZjgwY2M3ZjYuMApAQCAtMCwwICsxLDEyNiBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlGNXpDQ0E4K2dBd0lCQWdJSVRLOXpRaHlPZEFJd0RRWUpLb1pJaHZjTkFRRUZCUUF3Z1lBeE9EQTJCZ05WCitCQU1NTDBWQ1J5QkZiR1ZyZEhKdmJtbHJJRk5sY25ScFptbHJZU0JJYVhwdFpYUWdVMkhFbjJ4aGVjU3hZOFN4CitjOFN4TVRjd05RWURWUVFLREM1RlFrY2dRbWxzYWNXZmFXMGdWR1ZyYm05c2IycHBiR1Z5YVNCMlpTQklhWHB0CitaWFJzWlhKcElFRXV4WjR1TVFzd0NRWURWUVFHRXdKVVVqQWVGdzB3TmpBNE1UY3dNREl4TURsYUZ3MHhOakE0CitNVFF3TURNeE1EbGFNSUdBTVRnd05nWURWUVFEREM5RlFrY2dSV3hsYTNSeWIyNXBheUJUWlhKMGFXWnBhMkVnCitTR2w2YldWMElGTmh4SjlzWVhuRXNXUEVzWFBFc1RFM01EVUdBMVVFQ2d3dVJVSkhJRUpwYkduRm4ybHRJRlJsCithMjV2Ykc5cWFXeGxjbWtnZG1VZ1NHbDZiV1YwYkdWeWFTQkJMc1dlTGpFTE1Ba0dBMVVFQmhNQ1ZGSXdnZ0lpCitNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUNEd0F3Z2dJS0FvSUNBUUR1b0lSaDBEcHFaaEF5MkRFNGY2ZW41ZjJoCis0ZnVYZDdoeGx1Z1Rsa2FEVDdieVgzSldiaE5ncFFHUjRsdkZ6VmNmZDJOUi95ODkyN2svcXFrMTUzblE5ZEFrCit0aUhxNnlPVS9pbS8rNG1SREdTYUJVb3J6QXp1OFQyYmdtbWtUUGlhYitjaTJoQzZYNUw4R0NjS3FLcEUraTRzCit0UHRHbWdnRGczS3JpT1JxY3NubFpSOXVLZytkcytnNzVBeHVldHBYL2RmcmVZdGVJQWJUZGd0c0FwV2psdVRMCitkbEhSS0oyaEd2eEVvazNNZW5hb0RUMi9GMDhpaUZEOXJyYnNrRkJLVzUrVlFhcktEN0pLL29DWlRxTkdGYXY0CitjMEpxd21aMnNRb21GZDJUa3V6YnFWOVVJbEtSY0YwVDZranNiZ05zMmQxcy9Pc05BLyttZ3hLYjhhbVREOFVtCitUREd5WTVsaGN1Y3FaSm5TdU9sMTRueXBxWm9hcXNOVzJ4Q2FQSU5TdG51V3Q2eUhkNmk1OG1jTGxFT3pyejV6Cisra0kyc1NYRkNqRW1OMVpudXFNTGZkYjNpYzFub2JjNkhtWlA5cUJWRkNWTUxETU5wa0dNdlFReGFoQnlDcDBPCitMbmE5WHZOUmlZdW9QMVZ6djlzNnhpUUZscEpJcWt1TktnUGxWNUVROUdvb0ZXNUhkNFJjVVhTZkdlbm1IbU1XCitPZU1SRmVOWUdrUzl5OFJzWnRlRUJ0OHc5RGVpUXlKNTBoQnMzN3ZtRXhIOG5ZUUtFM3Z3TzlEOG93clhpZXFXCitmbzFJaFI1a1g5dFVvcXpWZWdKNWE5S0s4R2ZhWlhJTkZIRGs2WTU0anpKMGZGZnkxdGIwTm9rYitDbHNpN24yCitsOUdrTHFxK0N4bkNSZWx3WFFJREFKM1pvMk13WVRBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUE0R0ExVWREd0VCCisvd1FFQXdJQkJqQWRCZ05WSFE0RUZnUVU1ODdHVC93V1o1YjZTcU1Id1FTbnkycmUya2N3SHdZRFZSMGpCQmd3CitGb0FVNTg3R1Qvd1daNWI2U3FNSHdRU255MnJlMmtjd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dJQkFKdVltbDIrCis4eWdqZHNaczkzL21RSjdBTnR5VkRSMnRGY1UyMk5VNTcvSWVJbDZ6Z3JSZHUwd2F5cElOMzBja0hyTWsycEdJCis2WU53M1pQWDZicXozeFphUHQ3Z3lQdlQvV3dwK0JWR29HZ216Sk5Tcm9JQms1REtkOHBOU2UvaVd0a3F2VERPCitUTEtCdGpET1dVL2FXUjFxZXFSRnNJSW1nWVoyOWZVUUFManVzd25vVDRjQ0I2NGtYUEJmckFvd3pJcEFvSE1FCit3ZnVKSlBhYUhGeTNQQXBuTmdVSU1iT3YyQUZvS3VCNGozVGV1Rkdrakd3Z1BhTDdzOVFKL1h2Q2dLcVRiQ21ZCitJYWk3RnZPcEVsOTB0WWVZOHBVbTN6VHZpbE9SaUYwYWxLTS9mQ0w0MTRpNnBveVdxRDFTTkdLZkFCNVVWVUpuCit4azFHajdzVVJUMEtsaGFPRUtHWG1kWFRNSVhNM3JSeXQ3eUtQQmdwYVAzY2NRZnVKRGxxK3UybHJEZ3YrUjRRCitEZ1p4R2hCTS9uVisveDVYT1VMSzErRVZvVlpWV1J2Um82OFIyRTdEcFN2dmtML0E3SUlUVzQzV2NpeVRUbzlxCitLZCtGUE5NTjRLSVlFc3hWTDBlM3A1c0Mva0gyaUV4dDJxa0JSNE5rSjJJUWd0WVNlMTRESHpTcHlaSCtyMTF0CitoaWUzSTZwMUdNb2c1N0FQMTRrT3BtY2lZL1NEUVNzR1M3dFkxZEhYdDdrUVk5aUpTclNxM1JaajlXNitZS0g0Cis3ZWpXa0U4YXhzV2dLZE9uSWFqMVdqejN4MG1pSVpwS2xWSWdsbkthWnN2MzBvWkRmQ0srbHZtOUFhaEgzZVU3CitRUGwxSzVzclJtU0dqUjcwai9zSGQ5RHFTYUljalZJVXBncVQKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgICAgICAgIDRjOmFmOjczOjQyOjFjOjhlOjc0OjAyCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IENOPUVCRyBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2FceEM0XHg5RmxheVx4QzRceEIxY1x4QzRceEIxc1x4QzRceEIxLCBPPUVCRyBCaWxpXHhDNVx4OUZpbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS5ceEM1XHg5RS4sIEM9VFIKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEF1ZyAxNyAwMDoyMTowOSAyMDA2IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogQXVnIDE0IDAwOjMxOjA5IDIwMTYgR01UCisgICAgICAgIFN1YmplY3Q6IENOPUVCRyBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2FceEM0XHg5RmxheVx4QzRceEIxY1x4QzRceEIxc1x4QzRceEIxLCBPPUVCRyBCaWxpXHhDNVx4OUZpbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS5ceEM1XHg5RS4sIEM9VFIKKyAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICg0MDk2IGJpdCkKKyAgICAgICAgICAgICAgICBNb2R1bHVzICg0MDk2IGJpdCk6CisgICAgICAgICAgICAgICAgICAgIDAwOmVlOmEwOjg0OjYxOmQwOjNhOjZhOjY2OjEwOjMyOmQ4OjMxOjM4OjdmOgorICAgICAgICAgICAgICAgICAgICBhNzphNzplNTpmZDphMTplMTpmYjo5Nzo3NzpiODo3MTo5NjplODoxMzo5NjoKKyAgICAgICAgICAgICAgICAgICAgNDY6ODM6NGY6YjY6ZjI6NWY6NzI6NTY6NmU6MTM6NjA6YTU6MDE6OTE6ZTI6CisgICAgICAgICAgICAgICAgICAgIDViOmM1OmNkOjU3OjFmOjc3OjYzOjUxOmZmOjJmOjNkOmRiOmI5OjNmOmFhOgorICAgICAgICAgICAgICAgICAgICBhOTozNTplNzo3OTpkMDpmNTpkMDoyNDpiNjoyMTplYTplYjoyMzo5NDpmZToKKyAgICAgICAgICAgICAgICAgICAgMjk6YmY6ZmI6ODk6OTE6MGM6NjQ6OWE6MDU6NGE6MmI6Y2M6MGM6ZWU6ZjE6CisgICAgICAgICAgICAgICAgICAgIDNkOjliOjgyOjY5OmE0OjRjOmY4OjlhOjZmOmU3OjIyOmRhOjEwOmJhOjVmOgorICAgICAgICAgICAgICAgICAgICA5MjpmYzoxODoyNzowYTphODphYTo0NDpmYToyZToyYzpiNDpmYjo0Njo5YToKKyAgICAgICAgICAgICAgICAgICAgMDg6MDM6ODM6NzI6YWI6ODg6ZTQ6NmE6NzI6Yzk6ZTU6NjU6MWY6NmU6MmE6CisgICAgICAgICAgICAgICAgICAgIDBmOjlkOmIzOmU4OjNiOmU0OjBjOjZlOjdhOmRhOjU3OmZkOmQ3OmViOjc5OgorICAgICAgICAgICAgICAgICAgICA4Yjo1ZToyMDowNjpkMzo3NjowYjo2YzowMjo5NTphMzo5NjplNDpjYjo3NjoKKyAgICAgICAgICAgICAgICAgICAgNTE6ZDE6Mjg6OWQ6YTE6MWE6ZmM6NDQ6YTI6NGQ6Y2M6N2E6NzY6YTg6MGQ6CisgICAgICAgICAgICAgICAgICAgIDNkOmJmOjE3OjRmOjIyOjg4OjUwOmZkOmFlOmI2OmVjOjkwOjUwOjRhOjViOgorICAgICAgICAgICAgICAgICAgICA5Zjo5NTo0MTphYTpjYTowZjpiMjo0YTpmZTo4MDo5OTo0ZTphMzo0NjoxNToKKyAgICAgICAgICAgICAgICAgICAgYWI6Zjg6NzM6NDI6NmE6YzI6NjY6NzY6YjE6MGE6MjY6MTU6ZGQ6OTM6OTI6CisgICAgICAgICAgICAgICAgICAgIGVjOmRiOmE5OjVmOjU0OjIyOjUyOjkxOjcwOjVkOjEzOmVhOjQ4OmVjOjZlOgorICAgICAgICAgICAgICAgICAgICAwMzo2YzpkOTpkZDo2YzpmYzplYjowZDowMzpmZjphNjo4MzoxMjo5YjpmMToKKyAgICAgICAgICAgICAgICAgICAgYTk6OTM6MGY6YzU6MjY6NGM6MzE6YjI6NjM6OTk6NjE6NzI6ZTc6MmE6NjQ6CisgICAgICAgICAgICAgICAgICAgIDk5OmQyOmI4OmU5Ojc1OmUyOjdjOmE5OmE5OjlhOjFhOmFhOmMzOjU2OmRiOgorICAgICAgICAgICAgICAgICAgICAxMDo5YTozYzo4Mzo1MjpiNjo3Yjo5NjpiNzphYzo4Nzo3NzphODpiOTpmMjoKKyAgICAgICAgICAgICAgICAgICAgNjc6MGI6OTQ6NDM6YjM6YWY6M2U6NzM6ZmE6NDI6MzY6YjE6MjU6YzU6MGE6CisgICAgICAgICAgICAgICAgICAgIDMxOjI2OjM3OjU2OjY3OmJhOmEzOjBiOjdkOmQ2OmY3Ojg5OmNkOjY3OmExOgorICAgICAgICAgICAgICAgICAgICBiNzozYToxZTo2Njo0ZjpmNjphMDo1NToxNDoyNTo0YzoyYzozMzowZDphNjoKKyAgICAgICAgICAgICAgICAgICAgNDE6OGM6YmQ6MDQ6MzE6NmE6MTA6NzI6MGE6OWQ6MGU6MmU6NzY6YmQ6NWU6CisgICAgICAgICAgICAgICAgICAgIGYzOjUxOjg5OjhiOmE4OjNmOjU1OjczOmJmOmRiOjNhOmM2OjI0OjA1Ojk2OgorICAgICAgICAgICAgICAgICAgICA5Mjo0ODphYTo0Yjo4ZDoyYTowMzplNTo1Nzo5MToxMDpmNDo2YToyODoxNToKKyAgICAgICAgICAgICAgICAgICAgNmU6NDc6Nzc6ODQ6NWM6NTE6NzQ6OWY6MTk6ZTk6ZTY6MWU6NjM6MTY6Mzk6CisgICAgICAgICAgICAgICAgICAgIGUzOjExOjE1OmUzOjU4OjFhOjQ0OmJkOmNiOmM0OjZjOjY2OmQ3Ojg0OjA2OgorICAgICAgICAgICAgICAgICAgICBkZjozMDpmNDozNzphMjo0MzoyMjo3OTpkMjoxMDo2YzpkZjpiYjplNjoxMzoKKyAgICAgICAgICAgICAgICAgICAgMTE6ZmM6OWQ6ODQ6MGE6MTM6N2I6ZjA6M2I6ZDA6ZmM6YTM6MGE6ZDc6ODk6CisgICAgICAgICAgICAgICAgICAgIGVhOjk2OjdlOjhkOjQ4Ojg1OjFlOjY0OjVmOmRiOjU0OmEyOmFjOmQ1OjdhOgorICAgICAgICAgICAgICAgICAgICAwMjo3OTo2YjpkMjo4YTpmMDo2NzpkYTo2NTo3MjowZDoxNDo3MDplNDplOToKKyAgICAgICAgICAgICAgICAgICAgOGU6Nzg6OGY6MzI6NzQ6N2M6NTc6ZjI6ZDY6ZDY6ZjQ6MzY6ODk6MWI6Zjg6CisgICAgICAgICAgICAgICAgICAgIDI5OjZjOjhiOmI5OmY2Ojk3OmQxOmE0OjJlOmFhOmJlOjBiOjE5OmMyOjQ1OgorICAgICAgICAgICAgICAgICAgICBlOTo3MDo1ZAorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA0MDQwOSAoMHg5ZGQ5KQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgRTc6Q0U6QzY6NEY6RkM6MTY6Njc6OTY6RkE6NEE6QTM6MDc6QzE6MDQ6QTc6Q0I6NkE6REU6REE6NDcKKyAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIGtleWlkOkU3OkNFOkM2OjRGOkZDOjE2OjY3Ojk2OkZBOjRBOkEzOjA3OkMxOjA0OkE3OkNCOjZBOkRFOkRBOjQ3CisKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgOWI6OTg6OWE6NWQ6YmU6ZjM6Mjg6MjM6NzY6YzY6NmM6Zjc6N2Y6ZTY6NDA6OWU6YzA6MzY6CisgICAgICAgIGRjOjk1OjBkOjFkOmFkOjE1OmM1OjM2OmQ4OmQ1OjM5OmVmOmYyOjFlOjIyOjVlOmIzOjgyOgorICAgICAgICBiNDo1ZDpiYjo0YzoxYTpjYTo5MjowZDpkZjo0NzoyNDoxZTpiMzoyNDpkYTo5MTo4ODplOToKKyAgICAgICAgODM6NzA6ZGQ6OTM6ZDc6ZTk6YmE6YjM6ZGY6MTY6NWE6M2U6ZGU6ZTA6Yzg6ZmI6ZDM6ZmQ6CisgICAgICAgIDZjOjI5OmY4OjE1OjQ2OmEwOjY4OjI2OmNjOjkzOjUyOmFlOjgyOjAxOjkzOjkwOmNhOjc3OgorICAgICAgICBjYTo0ZDo0OTplZjplMjo1YTpkOToyYTpiZDozMDpjZTo0YzpiMjo4MTpiNjozMDpjZTo1OToKKyAgICAgICAgNGY6ZGE6NTk6MWQ6NmE6N2E6YTQ6NDU6YjA6ODI6MjY6ODE6ODY6NzY6ZjU6ZjU6MTA6MDA6CisgICAgICAgIGI4OmVlOmIzOjA5OmU4OjRmOjg3OjAyOjA3OmFlOjI0OjVjOmYwOjVmOmFjOjBhOjMwOmNjOgorICAgICAgICA4YTo0MDphMDo3MzowNDpjMTpmYjo4OToyNDpmNjo5YToxYzo1YzpiNzozYzowYTo2NzozNjoKKyAgICAgICAgMDU6MDg6MzE6YjM6YWY6ZDg6MDE6Njg6MmE6ZTA6Nzg6OGY6NzQ6ZGU6Yjg6NTE6YTQ6OGM6CisgICAgICAgIDZjOjIwOjNkOmEyOmZiOmIzOmQ0OjA5OmZkOjdiOmMyOjgwOmFhOjkzOjZjOjI5Ojk4OjIxOgorICAgICAgICBhODpiYjoxNjpmMzphOToxMjo1Zjo3NDpiNTo4Nzo5ODpmMjo5NToyNjpkZjozNDplZjo4YToKKyAgICAgICAgNTM6OTE6ODg6NWQ6MWE6OTQ6YTM6M2Y6N2M6MjI6Zjg6ZDc6ODg6YmE6YTY6OGM6OTY6YTg6CisgICAgICAgIDNkOjUyOjM0OjYyOjlmOjAwOjFlOjU0OjU1OjQyOjY3OmM2OjRkOjQ2OjhmOmJiOjE0OjQ1OgorICAgICAgICAzZDowYTo5NjoxNjo4ZToxMDphMTo5Nzo5OTpkNTpkMzozMDo4NTpjYzpkZTpiNDo3MjpiNzoKKyAgICAgICAgYmM6OGE6M2M6MTg6Mjk6Njg6ZmQ6ZGM6NzE6MDc6ZWU6MjQ6Mzk6NmE6ZmE6ZWQ6YTU6YWM6CisgICAgICAgIDM4OjJmOmY5OjFlOjEwOjBlOjA2OjcxOjFhOjEwOjRjOmZlOjc1OjdlOmZmOjFlOjU3OjM5OgorICAgICAgICA0MjpjYTpkNzplMToxNTphMTo1Njo1NTo1OToxYjpkMTphMzphZjoxMTpkODo0ZTpjMzphNToKKyAgICAgICAgMmI6ZWY6OTA6YmY6YzA6ZWM6ODI6MTM6NWI6OGQ6ZDY6NzI6MmM6OTM6NGU6OGY6NmE6Mjk6CisgICAgICAgIGRmOjg1OjNjOmQzOjBkOmUwOmEyOjE4OjEyOmNjOjU1OjJmOjQ3OmI3OmE3OjliOjAyOmZlOgorICAgICAgICA0MTpmNjo4ODo0Yzo2ZDpkYTphOTowMTo0Nzo4Mzo2NDoyNzo2MjoxMDo4MjpkNjoxMjo3YjoKKyAgICAgICAgNWU6MDM6MWY6MzQ6YTk6Yzk6OTE6ZmU6YWY6NWQ6NmQ6ODY6Mjc6Yjc6MjM6YWE6NzU6MTg6CisgICAgICAgIGNhOjIwOmU3OmIwOjBmOmQ3Ojg5OjBlOmE2OjY3OjIyOjYzOmY0OjgzOjQxOjJiOjA2OjRiOgorICAgICAgICBiYjo1ODpkNTpkMTpkNzpiNzpiOToxMDo2MzpkODo4OTo0YTpiNDphYTpkZDoxNjo2MzpmNToKKyAgICAgICAgNmU6YmU6NjA6YTE6Zjg6ZWQ6ZTg6ZDY6OTA6NGY6MWE6YzY6YzU6YTA6Mjk6ZDM6YTc6MjE6CisgICAgICAgIGE4OmY1OjVhOjNjOmY3OmM3OjQ5OmEyOjIxOjlhOjRhOjk1OjUyOjIwOjk2OjcyOjlhOjY2OgorICAgICAgICBjYjpmNzpkMjo4Njo0Mzo3YzoyMjpiZTo5NjpmOTpiZDowMTphODo0NzpkZDplNTozYjo0MDoKKyAgICAgICAgZjk6NzU6MmI6OWI6MmI6NDY6NjQ6ODY6OGQ6MWU6ZjQ6OGY6ZmI6MDc6Nzc6ZDA6ZWE6NDk6CisgICAgICAgIGEyOjFjOjhkOjUyOjE0OmE2OjBhOjkzCitTSEExIEZpbmdlcnByaW50PThDOjk2OkJBOkVCOkREOjJCOjA3OjA3OjQ4OkVFOjMwOjMyOjY2OkEwOkYzOjk4OjZFOjdDOkFFOjU4CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZmFjMDg0ZDcuMCBiL2x1bmkvc3JjL21haW4vZmlsZXMvY2FjZXJ0cy9mYWMwODRkNy4wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcwMzNkNTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZmFjMDg0ZDcuMApAQCAtMCwwICsxLDgxIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KK01JSURvRENDQW9pZ0F3SUJBZ0lCTVRBTkJna3Foa2lHOXcwQkFRVUZBREJETVFzd0NRWURWUVFHRXdKS1VERWMKK01Cb0dBMVVFQ2hNVFNtRndZVzVsYzJVZ1IyOTJaWEp1YldWdWRERVdNQlFHQTFVRUN4TU5RWEJ3YkdsallYUnAKK2IyNURRVEFlRncwd056RXlNVEl4TlRBd01EQmFGdzB4TnpFeU1USXhOVEF3TURCYU1FTXhDekFKQmdOVkJBWVQKK0FrcFFNUnd3R2dZRFZRUUtFeE5LWVhCaGJtVnpaU0JIYjNabGNtNXRaVzUwTVJZd0ZBWURWUVFMRXcxQmNIQnMKK2FXTmhkR2x2YmtOQk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBcDIzZ2RFNkgKK2o2VUczbWlpMjRhWlMyUU5jZkFLQlp1T3F1SE1MdEpxTzhGNnRKZGhqWXEreHBxY0JyU0dVZVEzRG5SNGZsK0sKK2Y1U2sxMGNJL1ZCYVZ1Um9yQ2h6b0h2cGZ4aVNRRTh0bmZXdVJFaHpOZ2FlWkN3N05DUGJYQ2JrY1htUDFHNTUKK0lybVR3Y3JOd1ZidGlHclhvRGtoQkZjc292VzhSMEZQWGpRaWxiVWZLVzFlU3ZOTmNyNUJWaUNIL09sUVI5Y3cKK0ZPNWNqRlc2V1kySC9DUGVrOUFFalAzdmJiM1Flc21sT21weU04WktEUVVYS2kxN3NhZlkxdkMrOUQvcURpaHQKK1FXRWpkbmpEdUdXazgxcXV6TUtxMmVkWTNyWituWVZ1bnlvS2I1OERLVENYS0IyOHQ4OVVLVTVSTWZrbnRpZ20KKy9xSmo1a0VXOERPWVJ3SURBUUFCbzRHZU1JR2JNQjBHQTFVZERnUVdCQlJVV3NzbVAzSE1sRVlObGxQcWEwalEKK2svNUNkVEFPQmdOVkhROEJBZjhFQkFNQ0FRWXdXUVlEVlIwUkJGSXdVS1JPTUV3eEN6QUpCZ05WQkFZVEFrcFEKK01SZ3dGZ1lEVlFRS0RBL21sNlhtbkt6bG03M21sTC9sdXB3eEl6QWhCZ05WQkFzTUd1T0NvdU9EbCtPRHF1T0MKK3NlT0R2T09DdCtPRHArT0RzME5CTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFRkJRQUQKK2dnRUJBRGxxUkhaM09EcnNvMmRHRC9tTEJxajdhcEF4em43czJ0R0pmSHJyTGd5OW1UTG5zQ1RXdy8vMXNvZ0oKK2h5empWT0dqcHJJSUM4Q0ZxTWpTbkhIMkhaOWcvRGd6RStHZTNBdGYyaFpRS1hzdmNKRVBtYm8wTkkyVmRNVisKK2VLbG1YYjNLSVhkQ0VLeG1KajNla2F2OUZmQnY3V3hmRVBqekZ2WURpbytuRWhFTXkvMC9lY0djL1dMdW84OVUKK0RORXJYeGMrNHo2L3dDcytDWnYraUtaK3RKSVgvQ09VZ2IxdXA4V013dXNSUmR2NFFjbVdkdXB3WDNrU2ErU2oKK0Ixb0Y3eWRKenlHZmlrd0pjR2FwSnNFckVVNHowZzc4MW16U0RqSmthUCt0QlhoZkF4Mm80NUNzSk9BUFFLZEwKK3Jvc290NExLR0FmbXQxdDA2U0FaZjdJYmlWUT0KKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KK0NlcnRpZmljYXRlOgorICAgIERhdGE6CisgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgICAgU2VyaWFsIE51bWJlcjogNDkgKDB4MzEpCisgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICBJc3N1ZXI6IEM9SlAsIE89SmFwYW5lc2UgR292ZXJubWVudCwgT1U9QXBwbGljYXRpb25DQQorICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgTm90IEJlZm9yZTogRGVjIDEyIDE1OjAwOjAwIDIwMDcgR01UCisgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBEZWMgMTIgMTU6MDA6MDAgMjAxNyBHTVQKKyAgICAgICAgU3ViamVjdDogQz1KUCwgTz1KYXBhbmVzZSBHb3Zlcm5tZW50LCBPVT1BcHBsaWNhdGlvbkNBCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDphNzo2ZDplMDo3NDo0ZTo4Nzo4ZjphNTowNjpkZTo2ODphMjpkYjo4NjoKKyAgICAgICAgICAgICAgICAgICAgOTk6NGI6NjQ6MGQ6NzE6ZjA6MGE6MDU6OWI6OGU6YWE6ZTE6Y2M6MmU6ZDI6CisgICAgICAgICAgICAgICAgICAgIDZhOjNiOmMxOjdhOmI0Ojk3OjYxOjhkOjhhOmJlOmM2OjlhOjljOjA2OmI0OgorICAgICAgICAgICAgICAgICAgICA4Njo1MTplNDozNzowZTo3NDo3ODo3ZTo1Zjo4YTo3Zjo5NDphNDpkNzo0NzoKKyAgICAgICAgICAgICAgICAgICAgMDg6ZmQ6NTA6NWE6NTY6ZTQ6Njg6YWM6Mjg6NzM6YTA6N2I6ZTk6N2Y6MTg6CisgICAgICAgICAgICAgICAgICAgIDkyOjQwOjRmOjJkOjlkOmY1OmFlOjQ0OjQ4OjczOjM2OjA2OjllOjY0OjJjOgorICAgICAgICAgICAgICAgICAgICAzYjozNDoyMzpkYjo1YzoyNjplNDo3MTo3OTo4ZjpkNDo2ZTo3OToyMjpiOToKKyAgICAgICAgICAgICAgICAgICAgOTM6YzE6Y2E6Y2Q6YzE6NTY6ZWQ6ODg6NmE6ZDc6YTA6Mzk6MjE6MDQ6NTc6CisgICAgICAgICAgICAgICAgICAgIDJjOmEyOmY1OmJjOjQ3OjQxOjRmOjVlOjM0OjIyOjk1OmI1OjFmOjI5OjZkOgorICAgICAgICAgICAgICAgICAgICA1ZTo0YTpmMzo0ZDo3MjpiZTo0MTo1NjoyMDo4NzpmYzplOTo1MDo0NzpkNzoKKyAgICAgICAgICAgICAgICAgICAgMzA6MTQ6ZWU6NWM6OGM6NTU6YmE6NTk6OGQ6ODc6ZmM6MjM6ZGU6OTM6ZDA6CisgICAgICAgICAgICAgICAgICAgIDA0OjhjOmZkOmVmOjZkOmJkOmQwOjdhOmM5OmE1OjNhOjZhOjcyOjMzOmM2OgorICAgICAgICAgICAgICAgICAgICA0YTowZDowNToxNzoyYToyZDo3YjpiMTphNzpkODpkNjpmMDpiZTpmNDozZjoKKyAgICAgICAgICAgICAgICAgICAgZWE6MGU6Mjg6NmQ6NDE6NjE6MjM6NzY6Nzg6YzM6Yjg6NjU6YTQ6ZjM6NWE6CisgICAgICAgICAgICAgICAgICAgIGFlOmNjOmMyOmFhOmQ5OmU3OjU4OmRlOmI2OjdlOjlkOjg1OjZlOjlmOjJhOgorICAgICAgICAgICAgICAgICAgICAwYTo2Zjo5ZjowMzoyOTozMDo5NzoyODoxZDpiYzpiNzpjZjo1NDoyOTo0ZToKKyAgICAgICAgICAgICAgICAgICAgNTE6MzE6Zjk6Mjc6YjY6Mjg6MjY6ZmU6YTI6NjM6ZTY6NDE6MTY6ZjA6MzM6CisgICAgICAgICAgICAgICAgICAgIDk4OjQ3CisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICA1NDo1QTpDQjoyNjozRjo3MTpDQzo5NDo0NjowRDo5Njo1MzpFQTo2Qjo0ODpEMDo5MzpGRTo0Mjo3NQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgQWx0ZXJuYXRpdmUgTmFtZTogCisgICAgICAgICAgICAgICAgRGlyTmFtZTovQz1KUC9PPVx4RTZceDk3XHhBNVx4RTZceDlDXHhBQ1x4RTVceDlCXHhCRFx4RTZceDk0XHhCRlx4RTVceEJBXHg5Qy9PVT1ceEUzXHg4Mlx4QTJceEUzXHg4M1x4OTdceEUzXHg4M1x4QUFceEUzXHg4Mlx4QjFceEUzXHg4M1x4QkNceEUzXHg4Mlx4QjdceEUzXHg4M1x4QTdceEUzXHg4M1x4QjNDQQorICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgMzk6NmE6NDQ6NzY6Nzc6Mzg6M2E6ZWM6YTM6Njc6NDY6MGY6Zjk6OGI6MDY6YTg6ZmI6NmE6CisgICAgICAgIDkwOjMxOmNlOjdlOmVjOmRhOmQxOjg5OjdjOjdhOmViOjJlOjBjOmJkOjk5OjMyOmU3OmIwOgorICAgICAgICAyNDpkNjpjMzpmZjpmNTpiMjo4ODowOTo4NzoyYzplMzo1NDplMTphMzphNjpiMjowODowYjoKKyAgICAgICAgYzA6ODU6YTg6Yzg6ZDI6OWM6NzE6ZjY6MWQ6OWY6NjA6ZmM6Mzg6MzM6MTM6ZTE6OWU6ZGM6CisgICAgICAgIDBiOjVmOmRhOjE2OjUwOjI5OjdiOjJmOjcwOjkxOjBmOjk5OmJhOjM0OjM0OjhkOjk1Ojc0OgorICAgICAgICBjNTo3ZTo3ODphOTo2Njo1ZDpiZDpjYToyMTo3Nzo0MjoxMDphYzo2NjoyNjozZDpkZTo5MToKKyAgICAgICAgYWI6ZmQ6MTU6ZjA6NmY6ZWQ6NmM6NWY6MTA6Zjg6ZjM6MTY6ZjY6MDM6OGE6OGY6YTc6MTI6CisgICAgICAgIDExOjBjOmNiOmZkOjNmOjc5OmMxOjljOmZkOjYyOmVlOmEzOmNmOjU0OjBjOmQxOjJiOjVmOgorICAgICAgICAxNzozZTplMzozZTpiZjpjMDoyYjozZTowOTo5YjpmZTo4ODphNjo3ZTpiNDo5MjoxNzpmYzoKKyAgICAgICAgMjM6OTQ6ODE6YmQ6NmU6YTc6YzU6OGM6YzI6ZWI6MTE6NDU6ZGI6Zjg6NDE6Yzk6OTY6NzY6CisgICAgICAgIGVhOjcwOjVmOjc5OjEyOjZiOmU0OmEzOjA3OjVhOjA1OmVmOjI3OjQ5OmNmOjIxOjlmOjhhOgorICAgICAgICA0YzowOTo3MDo2NjphOToyNjpjMToyYjoxMTo0ZTozMzpkMjowZTpmYzpkNjo2YzpkMjowZToKKyAgICAgICAgMzI6NjQ6Njg6ZmY6YWQ6MDU6Nzg6NWY6MDM6MWQ6YTg6ZTM6OTA6YWM6MjQ6ZTA6MGY6NDA6CisgICAgICAgIGE3OjRiOmFlOjhiOjI4OmI3OjgyOmNhOjE4OjA3OmU2OmI3OjViOjc0OmU5OjIwOjE5OjdmOgorICAgICAgICBiMjoxYjo4OTo1NAorU0hBMSBGaW5nZXJwcmludD03Rjo4QTpCMDpDRjpEMDo1MTo4Nzo2QTo2NjpGMzozNjowRjo0NzpDODo4RDo4QzpEMzozNTpGQzo3NApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2ZhY2FjYmM2LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZmFjYWNiYzYuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMGI0ZWZhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2ZhY2FjYmM2LjAKQEAgLTAsMCArMSw4OCBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFMHpDQ0E3dWdBd0lCQWdJUUdOclJuaVo5Nkx0S0lWak56R3M3U2pBTkJna3Foa2lHOXcwQkFRVUZBRENCCit5akVMTUFrR0ExVUVCaE1DVlZNeEZ6QVZCZ05WQkFvVERsWmxjbWxUYVdkdUxDQkpibU11TVI4d0hRWURWUVFMCitFeFpXWlhKcFUybG5iaUJVY25WemRDQk9aWFIzYjNKck1Ub3dPQVlEVlFRTEV6RW9ZeWtnTWpBd05pQldaWEpwCitVMmxuYml3Z1NXNWpMaUF0SUVadmNpQmhkWFJvYjNKcGVtVmtJSFZ6WlNCdmJteDVNVVV3UXdZRFZRUURFenhXCitaWEpwVTJsbmJpQkRiR0Z6Y3lBeklGQjFZbXhwWXlCUWNtbHRZWEo1SUVObGNuUnBabWxqWVhScGIyNGdRWFYwCithRzl5YVhSNUlDMGdSelV3SGhjTk1EWXhNVEE0TURBd01EQXdXaGNOTXpZd056RTJNak0xT1RVNVdqQ0J5akVMCitNQWtHQTFVRUJoTUNWVk14RnpBVkJnTlZCQW9URGxabGNtbFRhV2R1TENCSmJtTXVNUjh3SFFZRFZRUUxFeFpXCitaWEpwVTJsbmJpQlVjblZ6ZENCT1pYUjNiM0pyTVRvd09BWURWUVFMRXpFb1l5a2dNakF3TmlCV1pYSnBVMmxuCitiaXdnU1c1akxpQXRJRVp2Y2lCaGRYUm9iM0pwZW1Wa0lIVnpaU0J2Ym14NU1VVXdRd1lEVlFRREV6eFdaWEpwCitVMmxuYmlCRGJHRnpjeUF6SUZCMVlteHBZeUJRY21sdFlYSjVJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5CithWFI1SUMwZ1J6VXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDdkpBZ0lLWG8xCitubUFNcXVkTE8wN2NmTHc4UlJ5N0srRCtLUUw1VndpalpJVVZKL1h4cmNneGlWMGk2Q3FxcGtLemovaTVWYmV4Cit0MHV6L285K0IxZnM3MFBiWm1JVlljOWdEYVRZM3ZqZ3cySUlQVlFUNjBuS1dWU0ZKdVVyanh1ZjYvV2hrY0l6CitTZGhEWTJwU1M5S1A2SEJSVGRHSmFYdkhjUGF6M0JKMDIzdGRTMWJUbHI4VmQ2R3c5S0lsOHE4Y2ttY1k1ZlFHCitCTytRdWVRQTVOMDZ0Um4vQXJyMFBPN2dpK3MzaSt6MDE2enk5dkE5cjkxMWtUTVpIUnhBeTNRa0dTR1QyUlQrCityQ3BTeDQvVkJFbmtqV05IaUR4cGc4ditSNzByZmsvRmxhNE9uZFRSUThCbmMrTVVDSDdsUDU5enVETUt6MTAvCitOSWVXaXU1VDZDVVZBZ01CQUFHamdiSXdnYTh3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFCitCQU1DQVFZd2JRWUlLd1lCQlFVSEFRd0VZVEJmb1YyZ1d6QlpNRmN3VlJZSmFXMWhaMlV2WjJsbU1DRXdIekFICitCZ1VyRGdNQ0dnUVVqK1hUR29hc2pZNXJ3OCtBYXRSSUdDeDdHUzR3SlJZamFIUjBjRG92TDJ4dloyOHVkbVZ5CithWE5wWjI0dVkyOXRMM1p6Ykc5bmJ5NW5hV1l3SFFZRFZSME9CQllFRkgvVFphZkMzZXk3OERBSjgwTTUrZ0t2CitNekV6TUEwR0NTcUdTSWIzRFFFQkJRVUFBNElCQVFDVEpFb3dYMkxQMkJxWUx6M3EzSmt0dlhmMnBYa2lPT3pFCitwNkI0RXExaURrVndaTVhubDJZdG1BbCtYNi9XekNobDhnR3FDQnBIM3ZuNWZKSmFDR2tnRGRrK2JXNDhEVzdZCis1Z2FSUUJpNStNSHQzOXRCcXVDV0lNbk5aQlU0Z2NtVTdxS0VLUXNUYjQ3YkROMGxBdHVraXhsRTBrRjZCV2xLCitXRTlneW42Q2Fnc0NxaVVYT2JYYmYrZUVaU3FWaXIyRzNsNkJGb010RU16ZS9haUNLbTBvSHcwTHhPWG5HaVlaCis0ZlFSYnhDMWxmem5RZ1V5Mjg2ZFVWNG90cDZGMDF2dnBYMUZRSEtPdHc1ckRnYjdNelZJY2JpZEo0dkVaVjhOCitobmFjUkhyMmxWejJYVElJTTZSVXRoZy9hRnp5UWtxRk9GU0RYOUhvTFBLc0VkYW83V05xCistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICAxODpkYTpkMTo5ZToyNjo3ZDplODpiYjo0YToyMTo1ODpjZDpjYzo2YjozYjo0YQorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPVVTLCBPPVZlcmlTaWduLCBJbmMuLCBPVT1WZXJpU2lnbiBUcnVzdCBOZXR3b3JrLCBPVT0oYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5LCBDTj1WZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IE5vdiAgOCAwMDowMDowMCAyMDA2IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogSnVsIDE2IDIzOjU5OjU5IDIwMzYgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89VmVyaVNpZ24sIEluYy4sIE9VPVZlcmlTaWduIFRydXN0IE5ldHdvcmssIE9VPShjKSAyMDA2IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHksIENOPVZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHNQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6YWY6MjQ6MDg6MDg6Mjk6N2E6MzU6OWU6NjA6MGM6YWE6ZTc6NGI6M2I6CisgICAgICAgICAgICAgICAgICAgIDRlOmRjOjdjOmJjOjNjOjQ1OjFjOmJiOjJiOmUwOmZlOjI5OjAyOmY5OjU3OgorICAgICAgICAgICAgICAgICAgICAwODphMzo2NDo4NToxNToyNzpmNTpmMTphZDpjODozMTo4OTo1ZDoyMjplODoKKyAgICAgICAgICAgICAgICAgICAgMmE6YWE6YTY6NDI6YjM6OGY6Zjg6Yjk6NTU6Yjc6YjE6Yjc6NGI6YjM6ZmU6CisgICAgICAgICAgICAgICAgICAgIDhmOjdlOjA3OjU3OmVjOmVmOjQzOmRiOjY2OjYyOjE1OjYxOmNmOjYwOjBkOgorICAgICAgICAgICAgICAgICAgICBhNDpkODpkZTpmODplMDpjMzo2MjowODozZDo1NDoxMzplYjo0OTpjYTo1OToKKyAgICAgICAgICAgICAgICAgICAgNTQ6ODU6MjY6ZTU6MmI6OGY6MWI6OWY6ZWI6ZjU6YTE6OTE6YzI6MzM6NDk6CisgICAgICAgICAgICAgICAgICAgIGQ4OjQzOjYzOjZhOjUyOjRiOmQyOjhmOmU4OjcwOjUxOjRkOmQxOjg5OjY5OgorICAgICAgICAgICAgICAgICAgICA3YjpjNzo3MDpmNjpiMzpkYzoxMjo3NDpkYjo3Yjo1ZDo0Yjo1NjpkMzo5NjoKKyAgICAgICAgICAgICAgICAgICAgYmY6MTU6Nzc6YTE6YjA6ZjQ6YTI6MjU6ZjI6YWY6MWM6OTI6Njc6MTg6ZTU6CisgICAgICAgICAgICAgICAgICAgIGY0OjA2OjA0OmVmOjkwOmI5OmU0OjAwOmU0OmRkOjNhOmI1OjE5OmZmOjAyOgorICAgICAgICAgICAgICAgICAgICBiYTpmNDozYzplZTplMDo4YjplYjozNzo4YjplYzpmNDpkNzphYzpmMjpmNjoKKyAgICAgICAgICAgICAgICAgICAgZjA6M2Q6YWY6ZGQ6NzU6OTE6MzM6MTk6MWQ6MWM6NDA6Y2I6NzQ6MjQ6MTk6CisgICAgICAgICAgICAgICAgICAgIDIxOjkzOmQ5OjE0OmZlOmFjOjJhOjUyOmM3OjhmOmQ1OjA0OjQ5OmU0OjhkOgorICAgICAgICAgICAgICAgICAgICA2Mzo0Nzo4ODozYzo2OTo4MzpjYjpmZTo0NzpiZDoyYjo3ZTo0ZjpjNTo5NToKKyAgICAgICAgICAgICAgICAgICAgYWU6MGU6OWQ6ZDQ6ZDE6NDM6YzA6Njc6NzM6ZTM6MTQ6MDg6N2U6ZTU6M2Y6CisgICAgICAgICAgICAgICAgICAgIDlmOjczOmI4OjMzOjBhOmNmOjVkOjNmOjM0Ojg3Ojk2OjhhOmVlOjUzOmU4OgorICAgICAgICAgICAgICAgICAgICAyNToxNQorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgMS4zLjYuMS41LjUuNy4xLjEyOiAKKyAgICAgICAgICAgICAgICAwXy5dLlswWTBXMFUuLmltYWdlL2dpZjAhMC4wLi4uKy4uLi4uLi4uLi4uLi4uay4uLmouSC4sey4uMCUuI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmCisgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjogCisgICAgICAgICAgICAgICAgN0Y6RDM6NjU6QTc6QzI6REQ6RUM6QkI6RjA6MzA6MDk6RjM6NDM6Mzk6RkE6MDI6QUY6MzM6MzE6MzMKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgOTM6MjQ6NGE6MzA6NWY6NjI6Y2Y6ZDg6MWE6OTg6MmY6M2Q6ZWE6ZGM6OTk6MmQ6YmQ6Nzc6CisgICAgICAgIGY2OmE1Ojc5OjIyOjM4OmVjOmM0OmE3OmEwOjc4OjEyOmFkOjYyOjBlOjQ1OjcwOjY0OmM1OgorICAgICAgICBlNzo5Nzo2NjoyZDo5ODowOTo3ZTo1ZjphZjpkNjpjYzoyODo2NTpmMjowMTphYTowODoxYToKKyAgICAgICAgNDc6ZGU6Zjk6Zjk6N2M6OTI6NWE6MDg6Njk6MjA6MGQ6ZDk6M2U6NmQ6NmU6M2M6MGQ6NmU6CisgICAgICAgIGQ4OmU2OjA2OjkxOjQwOjE4OmI5OmY4OmMxOmVkOmRmOmRiOjQxOmFhOmUwOjk2OjIwOmM5OgorICAgICAgICBjZDo2NDoxNTozODo4MTpjOTo5NDplZTphMjo4NDoyOTowYjoxMzo2Zjo4ZTpkYjowYzpkZDoKKyAgICAgICAgMjU6MDI6ZGI6YTQ6OGI6MTk6NDQ6ZDI6NDE6N2E6MDU6Njk6NGE6NTg6NGY6NjA6Y2E6N2U6CisgICAgICAgIDgyOjZhOjBiOjAyOmFhOjI1OjE3OjM5OmI1OmRiOjdmOmU3Ojg0OjY1OjJhOjk1OjhhOmJkOgorICAgICAgICA4NjpkZTo1ZTo4MToxNjo4MzoyZDoxMDpjYzpkZTpmZDphODo4MjoyYTo2ZDoyODoxZjowZDoKKyAgICAgICAgMGI6YzQ6ZTU6ZTc6MWE6MjY6MTk6ZTE6ZjQ6MTE6NmY6MTA6YjU6OTU6ZmM6ZTc6NDI6MDU6CisgICAgICAgIDMyOmRiOmNlOjlkOjUxOjVlOjI4OmI2OjllOjg1OmQzOjViOmVmOmE1OjdkOjQ1OjQwOjcyOgorICAgICAgICA4ZTpiNzowZTo2YjowZTowNjpmYjozMzozNTo0ODo3MTpiODo5ZDoyNzo4YjpjNDo2NTo1ZjoKKyAgICAgICAgMGQ6ODY6NzY6OWM6NDQ6N2E6ZjY6OTU6NWM6ZjY6NWQ6MzI6MDg6MzM6YTQ6NTQ6YjY6MTg6CisgICAgICAgIDNmOjY4OjVjOmYyOjQyOjRhOjg1OjM4OjU0OjgzOjVmOmQxOmU4OjJjOmYyOmFjOjExOmQ2OgorICAgICAgICBhODplZDo2Mzo2YQorU0hBMSBGaW5nZXJwcmludD00RTpCNjpENTo3ODo0OTo5QjoxQzpDRjo1Rjo1ODoxRTpBRDo1NjpCRTozRDo5Qjo2Nzo0NDpBNTpFNQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2ZkZTg0ODk3LjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZmRlODQ4OTcuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZWE4NGY4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2ZkZTg0ODk3LjAKQEAgLTAsMCArMSw4NyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlEcURDQ0FwQ2dBd0lCQWdJSkFQN2M0d0VQeVVqL01BMEdDU3FHU0liM0RRRUJCUVVBTURReEN6QUpCZ05WCitCQVlUQWtaU01SSXdFQVlEVlFRS0RBbEVhR2x0ZVc5MGFYTXhFVEFQQmdOVkJBTU1DRU5sY25ScFoyNWhNQjRYCitEVEEzTURZeU9URTFNVE13TlZvWERUSTNNRFl5T1RFMU1UTXdOVm93TkRFTE1Ba0dBMVVFQmhNQ1JsSXhFakFRCitCZ05WQkFvTUNVUm9hVzE1YjNScGN6RVJNQThHQTFVRUF3d0lRMlZ5ZEdsbmJtRXdnZ0VpTUEwR0NTcUdTSWIzCitEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURJYVBISjF0YXpOSFVtZ2g3c3RMN3FYT0VtN1JGSFllR2lmQlo0CitRQ0hrWUo1YXlHUGh4TEdXa3Y4WWJXa2o0U3RpOTkzaU5pK1JCN2xJenc3c2ViWXM1elJMY0FnbG96eUhHeG55CitnUWNQT0pBWjB4SCtoclR5MFY0ZUhwYk5nR3pPT3pHVHR2S2cwS21WRW4ybG1zeHJ5SVJXaWpPcDV5SVZVeGJ3Cit6QmZzVjEvcG9ncVlDZDdqWDV4djNFampoUXNWV3FhNm42eEk0d215OS9ReTNsNDB2aHg0WFVKYnpnNGlqMDJRCisxMzB5R0xNTExHcS9qajhVRVlrZ0RuY1V0VDJVQ0lmM0pSN1ZzbUFBN0c4cUtDVnVLajRZWXhjbFB6NUVJQmIyCitKc2dscmdWS3RPZGpMUE9NRmxOK1hQc1JHZ2pCUm1LZklyanh3bzFwM1BvNldBYmZBZ01CQUFHamdid3dnYmt3CitEd1lEVlIwVEFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVVHdTMrUVRtUXRDUlp2Z0h5VXRWRjlsbzUzQkV3CitaQVlEVlIwakJGMHdXNEFVR3UzK1FUbVF0Q1JadmdIeVV0VkY5bG81M0JHaE9LUTJNRFF4Q3pBSkJnTlZCQVlUCitBa1pTTVJJd0VBWURWUVFLREFsRWFHbHRlVzkwYVhNeEVUQVBCZ05WQkFNTUNFTmxjblJwWjI1aGdna0EvdHpqCitBUS9KU1A4d0RnWURWUjBQQVFIL0JBUURBZ0VHTUJFR0NXQ0dTQUdHK0VJQkFRUUVBd0lBQnpBTkJna3Foa2lHCis5dzBCQVFVRkFBT0NBUUVBaFFNZWtuSDJRcS9obzJHZTYvUEFEL0tsMU5xVjV0YSthRFk5Zm00ZlRJcnYwUThoCitiVjZsVW1QT0V2anZLdHB2NnpmK0V3TEh5enMrSW12YVlTNS8xSEk5M1REaEhreEFHWXdQMTV6Umd6QjdtRm5jCitmY2E1RENsTW9UT2k2MmM2WllUVGx1THRka1Z3ajdVcjN2a2oxa2x1UEJTMXhwODFIbERRd1k5cWNFUUNZc3V1CitIV2hCcDZwWDZGT3FCOUlHOXRVVUJndVJBM1VzYkhLMVlaV2FEWXU1RGVmMTMxVE4zdWJZMWdrSWwyUGx3UzZ3Cit0MFFtd0NiQXIxVXduanZWTmlvWkJQUmNIdi9QTExmLzBQMkhRQkhWRVNPN1NNQWhxYVFvTGYwVitMQk9LL1F3CitXeUg4RVpFMHZrSHZlNTJYZGYrWGxjQ1dXQy9xdTBiWHUrVFpMZz09CistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCitDZXJ0aWZpY2F0ZToKKyAgICBEYXRhOgorICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICAgICAgICBmZTpkYzplMzowMTowZjpjOTo0ODpmZgorICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgSXNzdWVyOiBDPUZSLCBPPURoaW15b3RpcywgQ049Q2VydGlnbmEKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEp1biAyOSAxNToxMzowNSAyMDA3IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogSnVuIDI5IDE1OjEzOjA1IDIwMjcgR01UCisgICAgICAgIFN1YmplY3Q6IEM9RlIsIE89RGhpbXlvdGlzLCBDTj1DZXJ0aWduYQorICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgICAgICAgICAgICAgICAgMDA6Yzg6Njg6ZjE6Yzk6ZDY6ZDY6YjM6MzQ6NzU6MjY6ODI6MWU6ZWM6YjQ6CisgICAgICAgICAgICAgICAgICAgIGJlOmVhOjVjOmUxOjI2OmVkOjExOjQ3OjYxOmUxOmEyOjdjOjE2Ojc4OjQwOgorICAgICAgICAgICAgICAgICAgICAyMTplNDo2MDo5ZTo1YTpjODo2MzplMTpjNDpiMTo5Njo5MjpmZjoxODo2ZDoKKyAgICAgICAgICAgICAgICAgICAgNjk6MjM6ZTE6MmI6NjI6Zjc6ZGQ6ZTI6MzY6MmY6OTE6MDc6Yjk6NDg6Y2Y6CisgICAgICAgICAgICAgICAgICAgIDBlOmVjOjc5OmI2OjJjOmU3OjM0OjRiOjcwOjA4OjI1OmEzOjNjOjg3OjFiOgorICAgICAgICAgICAgICAgICAgICAxOTpmMjo4MTowNzowZjozODo5MDoxOTpkMzoxMTpmZTo4NjpiNDpmMjpkMToKKyAgICAgICAgICAgICAgICAgICAgNWU6MWU6MWU6OTY6Y2Q6ODA6NmM6Y2U6M2I6MzE6OTM6YjY6ZjI6YTA6ZDA6CisgICAgICAgICAgICAgICAgICAgIGE5Ojk1OjEyOjdkOmE1OjlhOmNjOjZiOmM4Ojg0OjU2OjhhOjMzOmE5OmU3OgorICAgICAgICAgICAgICAgICAgICAyMjoxNTo1MzoxNjpmMDpjYzoxNzplYzo1Nzo1ZjplOTphMjowYTo5ODowOToKKyAgICAgICAgICAgICAgICAgICAgZGU6ZTM6NWY6OWM6NmY6ZGM6NDg6ZTM6ODU6MGI6MTU6NWE6YTY6YmE6OWY6CisgICAgICAgICAgICAgICAgICAgIGFjOjQ4OmUzOjA5OmIyOmY3OmY0OjMyOmRlOjVlOjM0OmJlOjFjOjc4OjVkOgorICAgICAgICAgICAgICAgICAgICA0Mjo1YjpjZTowZToyMjo4Zjo0ZDo5MDpkNzo3ZDozMjoxODpiMzowYjoyYzoKKyAgICAgICAgICAgICAgICAgICAgNmE6YmY6OGU6M2Y6MTQ6MTE6ODk6MjA6MGU6Nzc6MTQ6YjU6M2Q6OTQ6MDg6CisgICAgICAgICAgICAgICAgICAgIDg3OmY3OjI1OjFlOmQ1OmIyOjYwOjAwOmVjOjZmOjJhOjI4OjI1OjZlOjJhOgorICAgICAgICAgICAgICAgICAgICAzZToxODo2MzoxNzoyNTozZjozZTo0NDoyMDoxNjpmNjoyNjpjODoyNTphZToKKyAgICAgICAgICAgICAgICAgICAgMDU6NGE6YjQ6ZTc6NjM6MmM6ZjM6OGM6MTY6NTM6N2U6NWM6ZmI6MTE6MWE6CisgICAgICAgICAgICAgICAgICAgIDA4OmMxOjQ2OjYyOjlmOjIyOmI4OmYxOmMyOjhkOjY5OmRjOmZhOjNhOjU4OgorICAgICAgICAgICAgICAgICAgICAwNjpkZgorICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIDFBOkVEOkZFOjQxOjM5OjkwOkI0OjI0OjU5OkJFOjAxOkYyOjUyOkQ1OjQ1OkY2OjVBOjM5OkRDOjExCisgICAgICAgICAgICBYNTA5djMgQXV0aG9yaXR5IEtleSBJZGVudGlmaWVyOiAKKyAgICAgICAgICAgICAgICBrZXlpZDoxQTpFRDpGRTo0MTozOTo5MDpCNDoyNDo1OTpCRTowMTpGMjo1MjpENTo0NTpGNjo1QTozOTpEQzoxMQorICAgICAgICAgICAgICAgIERpck5hbWU6L0M9RlIvTz1EaGlteW90aXMvQ049Q2VydGlnbmEKKyAgICAgICAgICAgICAgICBzZXJpYWw6RkU6REM6RTM6MDE6MEY6Qzk6NDg6RkYKKworICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAgICAgICAgTmV0c2NhcGUgQ2VydCBUeXBlOiAKKyAgICAgICAgICAgICAgICBTU0wgQ0EsIFMvTUlNRSBDQSwgT2JqZWN0IFNpZ25pbmcgQ0EKKyAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgODU6MDM6MWU6OTI6NzE6ZjY6NDI6YWY6ZTE6YTM6NjE6OWU6ZWI6ZjM6YzA6MGY6ZjI6YTU6CisgICAgICAgIGQ0OmRhOjk1OmU2OmQ2OmJlOjY4OjM2OjNkOjdlOjZlOjFmOjRjOjhhOmVmOmQxOjBmOjIxOgorICAgICAgICA2ZDo1ZTphNTo1Mjo2MzpjZToxMjpmODplZjoyYTpkYTo2ZjplYjozNzpmZToxMzowMjpjNzoKKyAgICAgICAgY2I6M2I6M2U6MjI6NmI6ZGE6NjE6MmU6N2Y6ZDQ6NzI6M2Q6ZGQ6MzA6ZTE6MWU6NGM6NDA6CisgICAgICAgIDE5OjhjOjBmOmQ3OjljOmQxOjgzOjMwOjdiOjk4OjU5OmRjOjdkOmM2OmI5OjBjOjI5OjRjOgorICAgICAgICBhMTozMzphMjplYjo2NzozYTo2NTo4NDpkMzo5NjplMjplZDo3Njo0NTo3MDo4ZjpiNToyYjoKKyAgICAgICAgZGU6Zjk6MjM6ZDY6NDk6NmU6M2M6MTQ6YjU6YzY6OWY6MzU6MWU6NTA6ZDA6YzE6OGY6NmE6CisgICAgICAgIDcwOjQ0OjAyOjYyOmNiOmFlOjFkOjY4OjQxOmE3OmFhOjU3OmU4OjUzOmFhOjA3OmQyOjA2OgorICAgICAgICBmNjpkNToxNDowNjowYjo5MTowMzo3NToyYzo2Yzo3MjpiNTo2MTo5NTo5YTowZDo4YjpiOToKKyAgICAgICAgMGQ6ZTc6ZjU6ZGY6NTQ6Y2Q6ZGU6ZTY6ZDg6ZDY6MDk6MDg6OTc6NjM6ZTU6YzE6MmU6YjA6CisgICAgICAgIGI3OjQ0OjI2OmMwOjI2OmMwOmFmOjU1OjMwOjllOjNiOmQ1OjM2OjJhOjE5OjA0OmY0OjVjOgorICAgICAgICAxZTpmZjpjZjoyYzpiNzpmZjpkMDpmZDo4Nzo0MDoxMTpkNToxMToyMzpiYjo0ODpjMDoyMToKKyAgICAgICAgYTk6YTQ6Mjg6MmQ6ZmQ6MTU6Zjg6YjA6NGU6MmI6ZjQ6MzA6NWI6MjE6ZmM6MTE6OTE6MzQ6CisgICAgICAgIGJlOjQxOmVmOjdiOjlkOjk3Ojc1OmZmOjk3Ojk1OmMwOjk2OjU4OjJmOmVhOmJiOjQ2OmQ3OgorICAgICAgICBiYjplNDpkOToyZQorU0hBMSBGaW5nZXJwcmludD1CMToyRToxMzo2Mzo0NTo4NjpBNDo2RjoxQTpCMjo2MDo2ODozNzo1ODoyRDpDNDpBQzpGRDo5NDo5NwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2ZmNzgzNjkwLjAgYi9sdW5pL3NyYy9tYWluL2ZpbGVzL2NhY2VydHMvZmY3ODM2OTAuMApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNzNhOTFiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9maWxlcy9jYWNlcnRzL2ZmNzgzNjkwLjAKQEAgLTAsMCArMSw4OSBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlFZERDQ0ExeWdBd0lCQWdJUVJMNE1pMUFBSkxRUjB6WXEvbVVLL1RBTkJna3Foa2lHOXcwQkFRVUZBRENCCitsekVMTUFrR0ExVUVCaE1DVlZNeEN6QUpCZ05WQkFnVEFsVlVNUmN3RlFZRFZRUUhFdzVUWVd4MElFeGhhMlVnCitRMmwwZVRFZU1Cd0dBMVVFQ2hNVlZHaGxJRlZUUlZKVVVsVlRWQ0JPWlhSM2IzSnJNU0V3SHdZRFZRUUxFeGhvCitkSFJ3T2k4dmQzZDNMblZ6WlhKMGNuVnpkQzVqYjIweEh6QWRCZ05WQkFNVEZsVlVUaTFWVTBWU1JtbHljM1F0CitTR0Z5WkhkaGNtVXdIaGNOT1Rrd056QTVNVGd4TURReVdoY05NVGt3TnpBNU1UZ3hPVEl5V2pDQmx6RUxNQWtHCitBMVVFQmhNQ1ZWTXhDekFKQmdOVkJBZ1RBbFZVTVJjd0ZRWURWUVFIRXc1VFlXeDBJRXhoYTJVZ1EybDBlVEVlCitNQndHQTFVRUNoTVZWR2hsSUZWVFJWSlVVbFZUVkNCT1pYUjNiM0pyTVNFd0h3WURWUVFMRXhob2RIUndPaTh2CitkM2QzTG5WelpYSjBjblZ6ZEM1amIyMHhIekFkQmdOVkJBTVRGbFZVVGkxVlUwVlNSbWx5YzNRdFNHRnlaSGRoCitjbVV3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3g5OE00UDdTb2Y4ODVnbEZuCiswRzJmMHY5WTgrZWZLK3dOaVZTWnVUaVpGdmZnSVhsSXdydGhkQktXSFR4cWN0VThFR2M2T2UwckU4MW02NVVKCitNNlJzbDdIb3h1ekJkWG1jUmw2TnE5QnEvYmtxVlJjUVZMTVo4SnIyOGJGZHRxZHQrK0J4RjJ1aWlQc0EzLzRhCitNWGNNbWdGNnNUTGpLd0VIT0c3RHBWNGp2RVdiZTFEQnlUQ1AyK1VyZXROYit6TkFIcURWbUJlOGk0ZkRpZE5kCitvSTZ5cXFyMmptbUlCc1g2aVNIekNKMXBMZ2t6bXlrTlJnK016RWswc0dsUnZma0d6V2l0Wmt5OFBxeGh2UXFJCitEc2pmUGU1OEJFeWRDbDVya2RidXgrMG9qYXROaDRsejBHNmswQjRXaXhUaGRrUURmMk9zNU0xSm5NV1M5S3N5CitvVWhiQWdNQkFBR2pnYmt3Z2JZd0N3WURWUjBQQkFRREFnSEdNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdIUVlECitWUjBPQkJZRUZLRnlYeVliS0poRGxWMEhOOVdGbHAxTDBzTkZNRVFHQTFVZEh3UTlNRHN3T2FBM29EV0dNMmgwCitkSEE2THk5amNtd3VkWE5sY25SeWRYTjBMbU52YlM5VlZFNHRWVk5GVWtacGNuTjBMVWhoY21SM1lYSmxMbU55CitiREF4QmdOVkhTVUVLakFvQmdnckJnRUZCUWNEQVFZSUt3WUJCUVVIQXdVR0NDc0dBUVVGQndNR0JnZ3JCZ0VGCitCUWNEQnpBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQVJ4a1AzblRHbVpldi9LMG9YbldPNnkxbjdrNTdLOWNNCisvL2JleTFXaUN1Rk1WR1dUWUd1ZkVweXRYb01zNjFxdXdPUXQ5QUJqSGJqQWJQTFBTYnROazI4R3Bnb2lza2xpCitDRTcveU1nVXNvZ1dYZWNCNUJLVjVVVTBzNHRwdmMrMGhZOTFVWjU5T2pnNkZFZ1N4dnVuT3hxTkRZSkFCK2dFCitDSkNoaWNzWlVOL0tIQUc4SFFRWmV4QjJsenZ1a0pES3hBNGZGbTUxN3pQNDAyOWJIcGJqNEhSM2RIdUtvbTR0CiszWGJXT1RDQzhLdWNVdklxeDY5SlhuN0hhT1dDZ2NocUova25pQ3JWV0ZDVkgvQTdIRmU3ZlJRNVlpdWF5WlNTCitLcU1pRFArSkpuMWZJeXRIMXhVZHFXcWVVUTBxVVo2QitkUTdYbkFTZnhBeW5CNjduZmhtcUE9PQorLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorQ2VydGlmaWNhdGU6CisgICAgRGF0YToKKyAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAgICAgICAgNDQ6YmU6MGM6OGI6NTA6MDA6MjQ6YjQ6MTE6ZDM6MzY6MmE6ZmU6NjU6MGE6ZmQKKyAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgIElzc3VlcjogQz1VUywgU1Q9VVQsIEw9U2FsdCBMYWtlIENpdHksIE89VGhlIFVTRVJUUlVTVCBOZXR3b3JrLCBPVT1odHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20sIENOPVVUTi1VU0VSRmlyc3QtSGFyZHdhcmUKKyAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgIE5vdCBCZWZvcmU6IEp1bCAgOSAxODoxMDo0MiAxOTk5IEdNVAorICAgICAgICAgICAgTm90IEFmdGVyIDogSnVsICA5IDE4OjE5OjIyIDIwMTkgR01UCisgICAgICAgIFN1YmplY3Q6IEM9VVMsIFNUPVVULCBMPVNhbHQgTGFrZSBDaXR5LCBPPVRoZSBVU0VSVFJVU1QgTmV0d29yaywgT1U9aHR0cDovL3d3dy51c2VydHJ1c3QuY29tLCBDTj1VVE4tVVNFUkZpcnN0LUhhcmR3YXJlCisgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAwMDpiMTpmNzpjMzozODozZjpiNDphODo3ZjpjZjozOTo4Mjo1MTo2NzpkMDoKKyAgICAgICAgICAgICAgICAgICAgNmQ6OWY6ZDI6ZmY6NTg6ZjM6ZTc6OWY6MmI6ZWM6MGQ6ODk6NTQ6OTk6Yjk6CisgICAgICAgICAgICAgICAgICAgIDM4Ojk5OjE2OmY3OmUwOjIxOjc5OjQ4OmMyOmJiOjYxOjc0OjEyOjk2OjFkOgorICAgICAgICAgICAgICAgICAgICAzYzo2YTo3MjpkNTozYzoxMDo2NzozYTozOTplZDoyYjoxMzpjZDo2NjplYjoKKyAgICAgICAgICAgICAgICAgICAgOTU6MDk6MzM6YTQ6NmM6OTc6YjE6ZTg6YzY6ZWM6YzE6NzU6Nzk6OWM6NDY6CisgICAgICAgICAgICAgICAgICAgIDVlOjhkOmFiOmQwOjZhOmZkOmI5OjJhOjU1OjE3OjEwOjU0OmIzOjE5OmYwOgorICAgICAgICAgICAgICAgICAgICA5YTpmNjpmMTpiMTo1ZDpiNjphNzo2ZDpmYjplMDo3MToxNzo2YjphMjo4ODoKKyAgICAgICAgICAgICAgICAgICAgZmI6MDA6ZGY6ZmU6MWE6MzE6Nzc6MGM6OWE6MDE6N2E6YjE6MzI6ZTM6MmI6CisgICAgICAgICAgICAgICAgICAgIDAxOjA3OjM4OjZlOmMzOmE1OjVlOjIzOmJjOjQ1OjliOjdiOjUwOmMxOmM5OgorICAgICAgICAgICAgICAgICAgICAzMDo4ZjpkYjplNToyYjo3YTpkMzo1YjpmYjozMzo0MDoxZTphMDpkNTo5ODoKKyAgICAgICAgICAgICAgICAgICAgMTc6YmM6OGI6ODc6YzM6ODk6ZDM6NWQ6YTA6OGU6YjI6YWE6YWE6ZjY6OGU6CisgICAgICAgICAgICAgICAgICAgIDY5Ojg4OjA2OmM1OmZhOjg5OjIxOmYzOjA4OjlkOjY5OjJlOjA5OjMzOjliOgorICAgICAgICAgICAgICAgICAgICAyOTowZDo0NjowZjo4YzpjYzo0OTozNDpiMDo2OTo1MTpiZDpmOTowNjpjZDoKKyAgICAgICAgICAgICAgICAgICAgNjg6YWQ6NjY6NGM6YmM6M2U6YWM6NjE6YmQ6MGE6ODg6MGU6Yzg6ZGY6M2Q6CisgICAgICAgICAgICAgICAgICAgIGVlOjdjOjA0OjRjOjlkOjBhOjVlOjZiOjkxOmQ2OmVlOmM3OmVkOjI4OjhkOgorICAgICAgICAgICAgICAgICAgICBhYjo0ZDo4Nzo4OTo3MzpkMDo2ZTphNDpkMDoxZToxNjo4YjoxNDplMTo3NjoKKyAgICAgICAgICAgICAgICAgICAgNDQ6MDM6N2Y6NjM6YWM6ZTQ6Y2Q6NDk6OWM6YzU6OTI6ZjQ6YWI6MzI6YTE6CisgICAgICAgICAgICAgICAgICAgIDQ4OjViCisgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IAorICAgICAgICAgICAgICAgIERpZ2l0YWwgU2lnbmF0dXJlLCBOb24gUmVwdWRpYXRpb24sIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAorICAgICAgICAgICAgICAgIEExOjcyOjVGOjI2OjFCOjI4Ojk4OjQzOjk1OjVEOjA3OjM3OkQ1Ojg1Ojk2OjlEOjRCOkQyOkMzOjQ1CisgICAgICAgICAgICBYNTA5djMgQ1JMIERpc3RyaWJ1dGlvbiBQb2ludHM6IAorICAgICAgICAgICAgICAgIFVSSTpodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1IYXJkd2FyZS5jcmwKKworICAgICAgICAgICAgWDUwOXYzIEV4dGVuZGVkIEtleSBVc2FnZTogCisgICAgICAgICAgICAgICAgVExTIFdlYiBTZXJ2ZXIgQXV0aGVudGljYXRpb24sIElQU2VjIEVuZCBTeXN0ZW0sIElQU2VjIFR1bm5lbCwgSVBTZWMgVXNlcgorICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICA0NzoxOTowZjpkZTo3NDpjNjo5OTo5NzphZjpmYzphZDoyODo1ZTo3NTo4ZTplYjoyZDo2NzoKKyAgICAgICAgZWU6NGU6N2I6MmI6ZDc6MGM6ZmY6ZjY6ZGU6Y2I6NTU6YTI6MGE6ZTE6NGM6NTQ6NjU6OTM6CisgICAgICAgIDYwOjZiOjlmOjEyOjljOmFkOjVlOjgzOjJjOmViOjVhOmFlOmMwOmU0OjJkOmY0OjAwOjYzOgorICAgICAgICAxZDpiODpjMDo2YzpmMjpjZjo0OTpiYjo0ZDo5Mzo2ZjowNjphNjowYToyMjpiMjo0OTo2MjoKKyAgICAgICAgMDg6NGU6ZmY6Yzg6Yzg6MTQ6YjI6ODg6MTY6NWQ6ZTc6MDE6ZTQ6MTI6OTU6ZTU6NDU6MzQ6CisgICAgICAgIGIzOjhiOjY5OmJkOmNmOmI0Ojg1OjhmOjc1OjUxOjllOjdkOjNhOjM4OjNhOjE0OjQ4OjEyOgorICAgICAgICBjNjpmYjphNzozYjoxYTo4ZDowZDo4Mjo0MDowNzplODowNDowODo5MDphMTo4OTpjYjoxOToKKyAgICAgICAgNTA6ZGY6Y2E6MWM6MDE6YmM6MWQ6MDQ6MTk6N2I6MTA6NzY6OTc6M2I6ZWU6OTA6OTA6Y2E6CisgICAgICAgIGM0OjBlOjFmOjE2OjZlOjc1OmVmOjMzOmY4OmQzOjZmOjViOjFlOjk2OmUzOmUwOjc0Ojc3OgorICAgICAgICA3NDo3Yjo4YTphMjo2ZToyZDpkZDo3NjpkNjozOTozMDo4MjpmMDphYjo5Yzo1MjpmMjoyYToKKyAgICAgICAgYzc6YWY6NDk6NWU6N2U6Yzc6Njg6ZTU6ODI6ODE6Yzg6NmE6Mjc6Zjk6Mjc6ODg6MmE6ZDU6CisgICAgICAgIDU4OjUwOjk1OjFmOmYwOjNiOjFjOjU3OmJiOjdkOjE0OjM5OjYyOjJiOjlhOmM5Ojk0OjkyOgorICAgICAgICAyYTphMzoyMjowYzpmZjo4OToyNjo3ZDo1ZjoyMzoyYjo0NzpkNzoxNToxZDphOTo2YTo5ZToKKyAgICAgICAgNTE6MGQ6MmE6NTE6OWU6ODE6Zjk6ZDQ6M2I6NWU6NzA6MTI6N2Y6MTA6MzI6OWM6MWU6YmI6CisgICAgICAgIDlkOmY4OjY2OmE4CitTSEExIEZpbmdlcnByaW50PTA0OjgzOkVEOjMzOjk5OkFDOjM2OjA4OjA1Ojg3OjIyOkVEOkJDOjVFOjQ2OjAwOkUzOkJFOkY5OkQ3CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9hd3QvZm9udC9OdW1lcmljU2hhcGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9hd3QvZm9udC9OdW1lcmljU2hhcGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODVhNWY0OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2F3dC9mb250L051bWVyaWNTaGFwZXIuamF2YQpAQCAtMCwwICsxLDg0MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBJbHlhIFMuIE9rb21pbgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitwYWNrYWdlIGphdmEuYXd0LmZvbnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCisvKioKKyAqIFRoZSBDbGFzcyBOdW1lcmljU2hhcGVyIHByb3ZpZGVzIG1ldGhvZHMgdG8gY29udmVydCBsYXRpbiBjaGFyYWN0ZXIgY29kZXMKKyAqIHRvIHVuaWNvZGUgY2hhcmFjdGVyIGNvZGVzLgorICogRm9yIHRhYmxlcyBvZiB0aGUgY2hhcmFjdGVyIGNvZGVzIHVzZWQsCisgKiBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy51bmljb2RlLm9yZy9QdWJsaWMvVU5JREFUQS8iPnVuaWNvZGUub3JnPC9hPi4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE51bWVyaWNTaGFwZXIgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgLyoqIFRoZSBDb25zdGFudCBzZXJpYWxWZXJzaW9uVUlELiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04MDIyNzY0NzA1OTIzNzMwMzA4TDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBFVVJPUEVBTiBpbmRpY2F0ZXMgdGhlIGxhdGluIGFuZCBleHRlbmRlZCByYW5nZSwKKyAgICAgKiBhbmQgbGF0aW4gZGVjaW1hbCBiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVVUk9QRUFOID0gMTsKKworICAgIC8qKiBUaGUgQ29uc3RhbnQgQVJBQklDIGluZGljYXRlcyB0aGUgQVJBQklDIHJhbmdlIGFuZCBkZWNpbWFsIGJhc2UuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVJBQklDID0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBFQVNURVJOX0FSQUJJQyBpbmRpY2F0ZXMgdGhlIEFSQUJJQyByYW5nZSBhbmQKKyAgICAgKiBBUkFCSUNfRVhURU5ERUQgZGVjaW1hbCBiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVBU1RFUk5fQVJBQklDID0gNDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBERVZBTkFHQVJJIGluZGljYXRlcyB0aGUgREVWQU5BR0FSSSByYW5nZSBhbmQKKyAgICAgKiBkZWNpbWFsIGJhc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVWQU5BR0FSSSA9IDg7CisKKyAgICAvKiogVGhlIENvbnN0YW50IEJFTkdBTEkgaW5kaWNhdGVzIHRoZSBCRU5HQUxJIHJhbmdlIGFuZCBkZWNpbWFsIGJhc2UuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkVOR0FMSSA9IDE2OworCisgICAgLyoqIFRoZSBDb25zdGFudCBHVVJNVUtISSBpbmRpY2F0ZXMgdGhlIEdVUk1VS0hJIHJhbmdlIGFuZCBkZWNpbWFsIGJhc2UuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgR1VSTVVLSEkgPSAzMjsKKworICAgIC8qKiBUaGUgQ29uc3RhbnQgR1VKQVJBVEkgaW5kaWNhdGVzIHRoZSBHVUpBUkFUSSByYW5nZSBhbmQgZGVjaW1hbCBiYXNlLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEdVSkFSQVRJID0gNjQ7CisKKyAgICAvKiogVGhlIENvbnN0YW50IE9SSVlBIGluZGljYXRlcyB0aGUgT1JJWUEgcmFuZ2UgYW5kIGRlY2ltYWwgYmFzZS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUklZQSA9IDEyODsKKworICAgIC8qKiBUaGUgQ29uc3RhbnQgVEFNSUwgaW5kaWNhdGVzIHRoZSBUQU1JTCByYW5nZSBhbmQgZGVjaW1hbCBiYXNlLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBTUlMID0gMjU2OworCisgICAgLyoqIFRoZSBDb25zdGFudCBURUxVR1UgaW5kaWNhdGVzIHRoZSBURUxVR1UgcmFuZ2UgYW5kIGRlY2ltYWwgYmFzZS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBURUxVR1UgPSA1MTI7CisKKyAgICAvKiogVGhlIENvbnN0YW50IEtBTk5BREEgaW5kaWNhdGVzIHRoZSBLQU5OQURBIHJhbmdlIGFuZCBkZWNpbWFsIGJhc2UuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgS0FOTkFEQSA9IDEwMjQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgTUFMQVlBTEFNIGluZGljYXRlcyB0aGUgTUFMQVlBTEFNIHJhbmdlIGFuZCBkZWNpbWFsIGJhc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFMQVlBTEFNID0gMjA0ODsKKworICAgIC8qKiBUaGUgQ29uc3RhbnQgVEhBSSBpbmRpY2F0ZXMgdGhlIFRIQUkgcmFuZ2UgYW5kIGRlY2ltYWwgYmFzZS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUSEFJID0gNDA5NjsKKworICAgIC8qKiBUaGUgQ29uc3RhbnQgTEFPIGluZGljYXRlcyB0aGUgTEFPIHJhbmdlIGFuZCBkZWNpbWFsIGJhc2UuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTEFPID0gODE5MjsKKworICAgIC8qKiBUaGUgQ29uc3RhbnQgVElCRVRBTiBpbmRpY2F0ZXMgdGhlIFRJQkVUQU4gcmFuZ2UgYW5kIGRlY2ltYWwgYmFzZS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUSUJFVEFOID0gMTYzODQ7CisKKyAgICAvKiogVGhlIENvbnN0YW50IE1ZQU5NQVIgaW5kaWNhdGVzIHRoZSBNWUFOTUFSIHJhbmdlIGFuZCBkZWNpbWFsIGJhc2UuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTVlBTk1BUiA9IDMyNzY4OworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IEVUSElPUElDIGluZGljYXRlcyB0aGUgRVRISU9QSUMgcmFuZ2UgYW5kIGRlY2ltYWwgYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFVEhJT1BJQyA9IDY1NTM2OworCisgICAgLyoqIFRoZSBDb25zdGFudCBLSE1FUiBpbmRpY2F0ZXMgdGhlIEtITUVSIHJhbmdlIGFuZCBkZWNpbWFsIGJhc2UuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgS0hNRVIgPSAxMzEwNzI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgTU9OR09MSUFOIGluZGljYXRlcyB0aGUgTU9OR09MSUFOIHJhbmdlIGFuZAorICAgICAqIGRlY2ltYWwgYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNT05HT0xJQU4gPSAyNjIxNDQ7CisKKyAgICAvKiogVGhlIENvbnN0YW50IEFMTF9SQU5HRVMgaW5kaWNhdGVzIGFsbCByYW5nZXMuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUxMX1JBTkdFUyA9IDUyNDI4NzsKKworICAgIC8qIEZ1cnRoZXIgb25lIGNhbiBmaW5kIHRoZSBzZXQgb2Ygc2NyaXB0IGluZGljZXMuCisgICAgICogSW5kZXggaXMgdGhlIHBvd2VyIHlvdSBuZWVkIHRoZSAyIHRvIHJhaXNlIHRvIHRvIGdldCBjb3JyZXNwb25kaW5nCisgICAgICogcmFuZ2UgY29uc3RhbnQgdmFsdWUuIEFsc28gc2NyaXB0IHJhbmdlcywgY29udGV4dCBuYW1lcyBhbmQgZGlnaXRzIGxvdworICAgICAqIHJhbmdlcyBhcmUgaW5kZXhlZCB3aXRoIHRoZXNlIGluZGljZXMuCisgICAgICovCisKKyAgICAvLyBJbmRleCBvZiB0aGUgRVVST1BFQU4gcmFuZ2UKKyAgICAvKiogVGhlIENvbnN0YW50IElOREVYX0VVUk9QRUFOLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTkRFWF9FVVJPUEVBTiA9IDA7CisKKyAgICAvLyBJbmRleCBvZiB0aGUgQVJBQklDIHJhbmdlCisgICAgLyoqIFRoZSBDb25zdGFudCBJTkRFWF9BUkFCSUMuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOREVYX0FSQUJJQyA9IDE7CisKKyAgICAvLyBJbmRleCBvZiB0aGUgRUFTVEVSTl9BUkFCSUMgcmFuZ2UKKyAgICAvKiogVGhlIENvbnN0YW50IElOREVYX0VBU1RFUk5fQVJBQklDLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTkRFWF9FQVNURVJOX0FSQUJJQyA9IDI7CisKKyAgICAvLyBJbmRleCBvZiB0aGUgREVWQU5BR0FSSSByYW5nZQorICAgIC8qKiBUaGUgQ29uc3RhbnQgSU5ERVhfREVWQU5BR0FSSS4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5ERVhfREVWQU5BR0FSSSA9IDM7CisKKyAgICAvLyBJbmRleCBvZiB0aGUgQkVOR0FMSSByYW5nZQorICAgIC8qKiBUaGUgQ29uc3RhbnQgSU5ERVhfQkVOR0FMSS4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5ERVhfQkVOR0FMSSA9IDQ7CisKKyAgICAvLyBJbmRleCBvZiB0aGUgR1VSTVVLSEkgcmFuZ2UKKyAgICAvKiogVGhlIENvbnN0YW50IElOREVYX0dVUk1VS0hJLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTkRFWF9HVVJNVUtISSA9IDU7CisKKyAgICAvLyBJbmRleCBvZiB0aGUgR1VKQVJUSSByYW5nZQorICAgIC8qKiBUaGUgQ29uc3RhbnQgSU5ERVhfR1VKQVJBVEkuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOREVYX0dVSkFSQVRJID0gNjsKKworICAgIC8vIEluZGV4IG9mIHRoZSBPUklZQSByYW5nZQorICAgIC8qKiBUaGUgQ29uc3RhbnQgSU5ERVhfT1JJWUEuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOREVYX09SSVlBID0gNzsKKworICAgIC8vIEluZGV4IG9mIHRoZSBUQU1JTCByYW5nZQorICAgIC8qKiBUaGUgQ29uc3RhbnQgSU5ERVhfVEFNSUwuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOREVYX1RBTUlMID0gODsKKworICAgIC8vIEluZGV4IG9mIHRoZSBURUxVR1UgcmFuZ2UKKyAgICAvKiogVGhlIENvbnN0YW50IElOREVYX1RFTFVHVS4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5ERVhfVEVMVUdVID0gOTsKKworICAgIC8vIEluZGV4IG9mIHRoZSBLQU5OQURBIHJhbmdlCisgICAgLyoqIFRoZSBDb25zdGFudCBJTkRFWF9LQU5OQURBLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTkRFWF9LQU5OQURBID0gMTA7CisKKyAgICAvLyBJbmRleCBvZiB0aGUgTUFMQVlBTEFNIHJhbmdlCisgICAgLyoqIFRoZSBDb25zdGFudCBJTkRFWF9NQUxBWUFMQU0uICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOREVYX01BTEFZQUxBTSA9IDExOworCisgICAgLy8gSW5kZXggb2YgdGhlIFRIQUkgcmFuZ2UKKyAgICAvKiogVGhlIENvbnN0YW50IElOREVYX1RIQUkuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOREVYX1RIQUkgPSAxMjsKKworICAgIC8vIEluZGV4IG9mIHRoZSBMQU8gcmFuZ2UKKyAgICAvKiogVGhlIENvbnN0YW50IElOREVYX0xBTy4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5ERVhfTEFPID0gMTM7CisKKyAgICAvLyBJbmRleCBvZiB0aGUgVElCRVRBTiByYW5nZQorICAgIC8qKiBUaGUgQ29uc3RhbnQgSU5ERVhfVElCRVRBTi4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5ERVhfVElCRVRBTiA9IDE0OworCisgICAgLy8gSW5kZXggb2YgdGhlIE1ZQU5NQVIgcmFuZ2UKKyAgICAvKiogVGhlIENvbnN0YW50IElOREVYX01ZQU5NQVIuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOREVYX01ZQU5NQVIgPSAxNTsKKworICAgIC8vIEluZGV4IG9mIHRoZSBFVEhJT1BJQyByYW5nZQorICAgIC8qKiBUaGUgQ29uc3RhbnQgSU5ERVhfRVRISU9QSUMuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOREVYX0VUSElPUElDID0gMTY7CisKKyAgICAvLyBJbmRleCBvZiB0aGUgS0hNRVIgcmFuZ2UKKyAgICAvKiogVGhlIENvbnN0YW50IElOREVYX0tITUVSLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTkRFWF9LSE1FUiA9IDE3OworCisgICAgLy8gSW5kZXggb2YgdGhlIE1PTkdPTElBTiByYW5nZQorICAgIC8qKiBUaGUgQ29uc3RhbnQgSU5ERVhfTU9OR09MSUFOLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTkRFWF9NT05HT0xJQU4gPSAxODsKKworICAgIC8vIE1heGltdW0gaW5kZXggdGhhdCByYW5nZSBjYW4ndCBleGNlZWQKKyAgICAvKiogVGhlIENvbnN0YW50IE1BWF9JTkRFWC4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0lOREVYID0gMTk7CisKKyAgICAvKgorICAgICAqIFNjcmlwdHMgcmFuZ2VzIGFycmF5LiBBcnJheSByZXByZXNlbnRzIHJhbmdlcyBhcyBwYWlycyBvZgorICAgICAqIGxvd2VzdCBhbmQgaGlnaGVzdCByYW5nZSBib3VuZHMuCisgICAgICogRGF0YSBpcyB0YWtlbiBmcm9tIHRoZSBVbmljb2RlRGF0YS50eHQgZmlsZSBmcm9tCisgICAgICogaHR0cDovL3d3dy51bmljb2RlLm9yZy9QdWJsaWMvVU5JREFUQS8KKyAgICAgKi8KKyAgICAvKiogVGhlIHNjcmlwdHMgcmFuZ2VzLiAqLworICAgIHByaXZhdGUgZmluYWwgaW50W10gc2NyaXB0c1JhbmdlcyA9IHsKKyAgICAgICAgICAgIDB4MDAwMCwgMHgwMjRGLCAgICAgLy8gRVVST1BFQU4gKGJhc2ljIGxhdGluICsgbGF0aW4tMSArIGV4dGVuZGVkKQorICAgICAgICAgICAgMHgwNjAwLCAweDA2RkYsICAgICAvLyBBUkFCSUMKKyAgICAgICAgICAgIDB4MDYwMCwgMHgwNkZGLCAgICAgLy8gRUFTVEVSTl9BUkFCSUMgKFhYWDogZGlmZiB3aXRoIEFSQUJJQyA/ICkKKyAgICAgICAgICAgIDB4MDkwMCwgMHgwOTdGLCAgICAgLy8gREVWQU5BR0FSSQorICAgICAgICAgICAgMHgwOTgwLCAweDA5RkYsICAgICAvLyBCRU5HQUxJCisgICAgICAgICAgICAweDBBMDAsIDB4MEE3RiwgICAgIC8vIEdVUk1VS0hJCisgICAgICAgICAgICAweDBBODAsIDB4MEFGRiwgICAgIC8vIEdVSkFSQVRJCisgICAgICAgICAgICAweDBCMDAsIDB4MEI3RiwgICAgIC8vIE9SSVlBCisgICAgICAgICAgICAweDBCODAsIDB4MEJGRiwgICAgIC8vIFRBTUlMCisgICAgICAgICAgICAweDBDMDAsIDB4MEM3RiwgICAgIC8vIFRFTFVHVQorICAgICAgICAgICAgMHgwQzgwLCAweDBDRkYsICAgICAvLyBLQU5OQURBCisgICAgICAgICAgICAweDBEMDAsIDB4MEQ3RiwgICAgIC8vIE1BTEFZQUxBTQorICAgICAgICAgICAgMHgwRTAwLCAweDBFN0YsICAgICAvLyBUSEFJCisgICAgICAgICAgICAweDBFODAsIDB4MEVGRiwgICAgIC8vIExBTworICAgICAgICAgICAgMHgwRjAwLCAweDBGRkYsICAgICAvLyBUSUJFVEFOCisgICAgICAgICAgICAweDEwMDAsIDB4MTA5RiwgICAgIC8vIE1ZQU5NQVIKKyAgICAgICAgICAgIDB4MTIwMCwgMHgxMzdGLCAgICAgLy8gRVRISU9QSUMKKyAgICAgICAgICAgIDB4MTc4MCwgMHgxN0ZGLCAgICAgLy8gS0hNRVIKKyAgICAgICAgICAgIDB4MTgwMCwgMHgxOEFGICAgICAgLy8gTU9OR09MSUFOCisgICAgfTsKKworICAgIC8qCisgICAgICogRGlnaXQgbG93IHJhbmdlcyB2YWx1ZXMgZGVjcmVhc2VkIGJ5IDB4MDAzMC4gRWFjaCBsb3cgcmFuZ2UKKyAgICAgKiB2YWx1ZSBkZWNyZWFzZWQgYnkgMHgwMDMwIGZvciBlYXN5IG9idGFpbmcgdW5pY29kZSB2YWx1ZSBvZiB0aGUKKyAgICAgKiBjb250ZXh0IGRlcGVuZGVudCBkaWdpdC4gRXVyb3BlYW4gZGlnaXRzIHN0YXJ0cyBmcm9tIDB4MDAzMCBoZW5jZQorICAgICAqIGNvbnRleHQgZGVwZW5kZW50IHVuaWNvZGUgZGlnaXQgdmFsdWUgZXF1YWxzIHRvCisgICAgICogICAgICBkaWdpdHNMb3dSYW5nZXNbc2NyaXB0IGluZGV4XSArIGV1cm9wZWFuIGRpZ2l0IGNoYXIgdW5pY29kZSB2YWx1ZS4KKyAgICAgKiAhISB0aGUgb25seSBleGNlcHRpb24gaXMgRVRISU9QSUMgc2NyaXB0IHdoZXJlIHRoZXJlIGlzIG5vICcwJyBkaWdpdAorICAgICAqIERhdGEgaXMgdGFrZW4gZnJvbSB0aGUgVW5pY29kZURhdGEudHh0IGZpbGUgZnJvbQorICAgICAqIGh0dHA6Ly93d3cudW5pY29kZS5vcmcvUHVibGljL1VOSURBVEEvCisgICAgICovCisgICAgLyoqIFRoZSBkaWdpdHMgbG93IHJhbmdlcy4gKi8KKyAgICBwcml2YXRlIGZpbmFsIGludFtdIGRpZ2l0c0xvd1JhbmdlcyA9IHsKKyAgICAgICAgICAgIDB4MDAwMCwgICAgICAgICAgICAgLy8gRVVST1BFQU4KKyAgICAgICAgICAgIDB4MDYzMCwgICAgICAgICAgICAgLy8gQVJBQklDCisgICAgICAgICAgICAweDA2MzAsICAgICAgICAgICAgIC8vIEVBU1RFUk5fQVJBQklDCisgICAgICAgICAgICAweDA5MzYsICAgICAgICAgICAgIC8vIERFVkFOQUdBUkkKKyAgICAgICAgICAgIDB4MDlCNiwgICAgICAgICAgICAgLy8gQkVOR0FMSQorICAgICAgICAgICAgMHgwQTM2LCAgICAgICAgICAgICAvLyBHVVJNVUtISQorICAgICAgICAgICAgMHgwQUI2LCAgICAgICAgICAgICAvLyBHVUpBUkFUSQorICAgICAgICAgICAgMHgwQjM2LCAgICAgICAgICAgICAvLyBPUklZQQorICAgICAgICAgICAgMHgwQkI2LCAgICAgICAgICAgICAvLyBUQU1JTAorICAgICAgICAgICAgMHgwQzM2LCAgICAgICAgICAgICAvLyBURUxVR1UKKyAgICAgICAgICAgIDB4MENCNiwgICAgICAgICAgICAgLy8gS0FOTkFEQQorICAgICAgICAgICAgMHgwRDM2LCAgICAgICAgICAgICAvLyBNQUxBWUFMQU0KKyAgICAgICAgICAgIDB4MEUyMCwgICAgICAgICAgICAgLy8gVEhBSQorICAgICAgICAgICAgMHgwRUEwLCAgICAgICAgICAgICAvLyBMQU8KKyAgICAgICAgICAgIDB4MEVGMCwgICAgICAgICAgICAgLy8gVElCRVRBTgorICAgICAgICAgICAgMHgxMDEwLCAgICAgICAgICAgICAvLyBNWUFOTUFSCisgICAgICAgICAgICAweDEzMzgsICAgICAgICAgICAgIC8vIEVUSElPUElDIC0gKGxvdyByYW5nZS0xKSBubyBFVEhJT1BJQyAnMCcgRElHSVQhCisgICAgICAgICAgICAweDE3QjAsICAgICAgICAgICAgIC8vIEtITUVSCisgICAgICAgICAgICAweDE3RTAgICAgICAgICAgICAgIC8vIE1PTkdPTElBTgorICAgIH07CisKKyAgICAvLyBTZXQgb2YgY29udGV4dCBuYW1lcyB1c2VkIGluIHRvU3RyaW5nIG1ldGhvZAorICAgIC8qKiBUaGUgY29udGV4dHMuICovCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmdbXSBjb250ZXh0cyA9IHsKKyAgICAgICAgICAgICJFVVJPUEVBTiIsCisgICAgICAgICAgICAiQVJBQklDIiwKKyAgICAgICAgICAgICJFQVNURVJOX0FSQUJJQyIsCisgICAgICAgICAgICAiREVWQU5BR0FSSSIsCisgICAgICAgICAgICAiQkVOR0FMSSIsCisgICAgICAgICAgICAiR1VSTVVLSEkiLAorICAgICAgICAgICAgIkdVSkFSQVRJIiwKKyAgICAgICAgICAgICJPUklZQSIsCisgICAgICAgICAgICAiVEFNSUwiLAorICAgICAgICAgICAgIlRFTFVHVSIsCisgICAgICAgICAgICAiS0FOTkFEQSIsCisgICAgICAgICAgICAiTUFMQVlBTEFNIiwKKyAgICAgICAgICAgICJUSEFJIiwKKyAgICAgICAgICAgICJMQU8iLAorICAgICAgICAgICAgIlRJQkVUQU4iLAorICAgICAgICAgICAgIk1ZQU5NQVIiLAorICAgICAgICAgICAgIkVUSElPUElDIiwKKyAgICAgICAgICAgICJLSE1FUiIsCisgICAgICAgICAgICAiTU9OR09MSUFOIgorICAgIH07CisKKyAgICAvKgorICAgICAqIFN0cm9uZyBjaGFyYWN0ZXJzIGZsYWdzIGFycmF5IGlzIHRvIGRldGVybWluZSBpZiB0aGUKKyAgICAgKiB1bmljb2RlIGJpZGlyZWN0aW9uYWwgY2F0ZWdvcnkgb2YgdGhlIGNoYXJhY3RlciBpcyBzdHJvbmcsCisgICAgICogYWNjb3JkaW5nIHRvIFVuaWNvZGUgc3BlY2lmaWNhdGlvbi4gSWYgdGhlIGJpdCB3aXRoIGluZGV4IGVxdWFscyB0bworICAgICAqIGNoYXJhY3RlcidzIHVuaWNvZGUgdmFsdWUgaXMgMSAtIHRoZSBjaGFyYWN0ZXIgaXMgc3Ryb25nLgorICAgICAqIFRoaXMgYXJyYXkgd2FzIGdlbmVyYXRlZCB1c2luZyBVbmljb2RlRGF0YS50eHQgZmlsZSBmcm9tCisgICAgICogaHR0cDovL3d3dy51bmljb2RlLm9yZy9QdWJsaWMvVU5JREFUQS8KKyAgICAgKi8KKworICAgIC8qKiBUaGUgQ29uc3RhbnQgU1RST05HX1RFWFRfRkxBR1MuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gU1RST05HX1RFWFRfRkxBR1MgPSB7IDAsIDAsIDEzNDIxNzcyNiwgMTM0MjE3NzI2LAorICAgICAgICAgICAgMCwgNjkyMDcwNDAsIC04Mzg4NjA5LCAtODM4ODYwOSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLAorICAgICAgICAgICAgLTEsIC0xLCAtNjU1MzMsIC0xLCAtMSwgLTEwMDY2MzI5NywgMTk2NjExLCAxNjQxNSwgMCwgMCwgMCwKKyAgICAgICAgICAgIDY3MTA4ODY0LCAtMTA0MzIsIC01LCAtMzI3NjksIC00MTk0MzA1LCAtMSwgLTEsIC0xLCAtMSwgLTEwMTcsIC0xLAorICAgICAgICAgICAgLTMyNzY5LCA2NzEwODg2MywgNjU1MzUsIC0xMzEwNzIsIC0yNTE2NTgyNSwgLTIsIDc2NywgMTA3Mzc0MTgyNCwKKyAgICAgICAgICAgIC02NTQ2MywgMjAzMzY2MywgLTkzOTUxMzg0MSwgMTM0MjE3NzI2LCAyMDQ3LCAtNzM3MjgsIC0xLCAtMSwKKyAgICAgICAgICAgIDU0MTA2NTIxNSwgLTY3MDU5NjE2LCAtMTgwMjI1LCA2NTUzNSwgLTgxOTIsIDE2MzgzLCAtMSwgMTMxMTM1LCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgLTgsIC00Njk3NjIwNDksIC0xNjcwMzk5OSwgNTM3MDAxOTcxLAorICAgICAgICAgICAgLTQxNzgxMiwgLTQ3MzU2MzY0OSwgLTEzMzM3NjU3NTksIDEzMzQzMTIzNSwgLTQyMzk2MCwgLTEwMTYyMDE3MjksCisgICAgICAgICAgICAxNTc3MDU4MzA1LCAxOTAwNDgwLCAtMjc4NTUyLCAtNDcwOTQyMjA5LCA3MjE5MywgNjU0NzUsIC00MTc4MTIsCisgICAgICAgICAgICAxNjc2NTQxNDM5LCAtMTMzMzc4MjE0MywgMjYyMDgzLCAtNzAwNTk0MjAwLCAtMTAwNjY0NzUyOCwgODM5NjIzMCwKKyAgICAgICAgICAgIDUyNDIyNCwgLTEzOTI4MiwgNjYwNTk3NzUsIDMwLCA2NTQ3NSwgLTEzOTI4NCwgLTQ3MDgxMTEzNywKKyAgICAgICAgICAgIDEwODAwMzY4MzEsIDY1NDc1LCAtMTM5Mjg0LCAtMTAwNjYzMzQ3MywgODM5NjIyNSwgNjU0NzUsIC01ODcyMDI3NiwKKyAgICAgICAgICAgIDgwNTA0NDIyMywgLTE2NTQ3NzEzLCAxODM1MDA4LCAtMiwgOTE3NTAzLCAyNjg0MDI4MTUsIDAsIC0xNzgxNjE3MCwKKyAgICAgICAgICAgIDUzNzc4MzQ3MCwgODcyMzQ5NzkxLCAwLCAtNTAzMzE2NDksIC0xMDUwNjczMTUzLCAtMjU3LCAtMjE0NzQ4MTYwMSwKKyAgICAgICAgICAgIDM4NzIsIC0xMDczNzQxODI0LCAyMzc1MDMsIDAsIC0xLCAxNjkxNDE3MSwgMTY3NzcyMTUsIDAsIDAsIC0xLAorICAgICAgICAgICAgLTY1NDczLCA1MzY4NzA5MTEsIC0xLCAtMSwgLTIwODAzNzQ3ODUsIC0xLCAtMSwgLTI0OSwgLTEsIDY3MTA4ODYzLAorICAgICAgICAgICAgLTEsIC0xLCAxMDMxNzQ5MTE5LCAtMSwgLTQ5NjY1LCAyMTM0NzY5NjYzLCAtODM4ODgwMywgLTEsCisgICAgICAgICAgICAtMTI3MTM5ODUsIC0xLCAxMzQyMTc3MjcsIDUzNjg3MDkxMSwgNjU1MzUsIC0xLCAtMSwgMjA5NzE1MSwgLTIsCisgICAgICAgICAgICAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsCisgICAgICAgICAgICAtMSwgODM4ODYwNywgMTM0MjE3NzI2LCAtMSwgLTEsIDEzMTA3MSwgMjUzOTUxLCA2NTUzNTk5LCAyNjIxNDMsCisgICAgICAgICAgICAxMjI4NzksIC0xLCAtMTA2NTM1MzIxNywgNDAxNjA1MDU1LCAxMDIzLCA2NzA0MzMyOCwgLTEsIC0xLAorICAgICAgICAgICAgMTY3NzcyMTUsIC0xLCA1MTEsIDAsIDAsIDUzNjg3MDkxMSwgMzMyMjY4NzIsIC02NCwgMjA0Nzk5OSwgLTEsCisgICAgICAgICAgICAtNjQ1MTMsIDY3MDQ0MzUxLCAwLCAtODMwNDcyMTkzLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgMCwgMCwKKyAgICAgICAgICAgIC0xLCAtMSwgLTEsIC0xLCAyNjg0MzU0NTUsIC0xLCAtMSwgNjcxMDg4NjMsIDEwNjExNTg5MTEsIC0xLAorICAgICAgICAgICAgLTE0MjYxMTI3MDUsIDEwNzM3NDE4MjMsIC0xLCAxNjA4NTE1NTgzLCAyNjUyMzIzNDgsIDUzNDUxOTgwNywKKyAgICAgICAgICAgIDQ5MTUyLCAyNzY0OCwgMCwgLTIxNDczNTI1NzYsIDIwMzE2MTYsIDAsIDAsIDAsIDEwNDMzMzIyMjgsCisgICAgICAgICAgICAtMjAxNjA1ODA4LCA5OTIsIC0xLCAxNSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIC00MTk0MzA0LCAtMSwgMTM0MjE3NzI3LCAyMDk3MTUyLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAtMjY4NDM1NDU2LAorICAgICAgICAgICAgLTEsIC0xLCAxMDIzLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCA0MDk2LCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgLTEsCisgICAgICAgICAgICAtMzI3NjksIDIxNDc0ODM2NDcsIDAsIC0xLCAtMSwgLTEsIDMxLCAtMSwgLTY1NDczLCAtMSwgMzI4MzEsCisgICAgICAgICAgICA4Mzg4NjA3LCAyMTM5MDYyMTQzLCAyMTM5MDYyMTQzLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMjI0LCA1MjQxNTc5NTAsIC0yLCAtMSwgLTUyODQ4MjMwNSwgLTIsIC0xLAorICAgICAgICAgICAgLTEzNDIxNzcyOSwgLTMyLCAtMTIyODgxLCAtMSwgLTEsIC0zMjc2OSwgMTY3NzcyMTUsIDAsIC02NTUzNiwKKyAgICAgICAgICAgIDUzNjg3MDkxMSwgLTEsIDE1LCAtMTg3OTA0ODE5MywgLTEsIDEzMTA3MSwgLTYxNDQxLCAyMTQ3NDgzNjQ3LCAtMSwKKyAgICAgICAgICAgIC0xLCAtMSwgLTEyNTgyOTEyMSwgLTEsIC0xLCAxMDczNzQxODIzLCAyMTQ3NDgzNjQ3LCAxLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMjA5NzE1MiwgMCwgMCwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMTM0MjE3NzI4LCAwLCAwLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLAorICAgICAgICAgICAgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLAorICAgICAgICAgICAgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIDgxOTEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAtMjExNywgMTU5LCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCA4LCAwLCAwLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgLTIxNDc0ODM2NDgsIDEsIDAsIDAsIC0yMTQ3NDgzNjQ4LAorICAgICAgICAgICAgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIC0yMTQ3NDgzNjQ4LCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAtMjE0NzQ4MzY0OCwgLTEsIC0xLCAtMSwKKyAgICAgICAgICAgIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC00OTE1MywgLTEsIC02MzQ4OSwgLTEsIC0xLCA2NzEwODg2MywgMCwKKyAgICAgICAgICAgIC0xNTk0MzU5NjgxLCAxNjAyMjIzNjE1LCAtMzcsIC0xLCAtMSwgMjYyMTQzLCAtNTI0Mjg4LCAtMSwgLTEsIC0xLAorICAgICAgICAgICAgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIDEwNzM3NDE4MjMsIC02NTUzNiwgLTEsIC0xOTY2MDksIC0xLAorICAgICAgICAgICAgMjU1LCA1MzY4MDUzNzYsIDAsIDAsIDAsIC0yMTYyNjg4LCAtMSwgLTEsIC0xLCA1MzY4NzA5MTEsIDAsCisgICAgICAgICAgICAxMzQyMTc3MjYsIDEzNDIxNzcyNiwgLTY0LCAtMSwgMjE0NzQ4MzY0NywgNDg2MzQxODg0LCAwCisKKyAgICB9OworCisgICAgLy8gaW5kZXggb2YgY29udGV4dCByYW5nZSAoU2VyaWFsaXphdGlvbiBzdXBwb3J0KQorICAgIC8qKiBUaGUga2V5LiAqLworICAgIHByaXZhdGUgaW50IGtleTsKKworICAgIC8vIGZsYWcsIHRydWUgaWYgc2hhcGluZyBjb250ZXh0dWFsIChTZXJpYWxpemF0aW9uIHN1cHBvcnQpCisgICAgLyoqIFRoZSBtYXNrLiAqLworICAgIHByaXZhdGUgaW50IG1hc2s7CisKKyAgICAvLyByYW5nZXMgdG8gYmUgc2hhcGVkCisgICAgLyoqIFRoZSByYW5nZXMuICovCisgICAgcHJpdmF0ZSBpbnQgZlJhbmdlczsKKworICAgIC8vIGluZGV4IG9mIHRoZSBkZWZhdWx0IGNvbnRleHQKKyAgICAvKiogVGhlIGRlZmF1bHQgY29udGV4dCBpbmRleC4gKi8KKyAgICBwcml2YXRlIGludCBmRGVmYXVsdENvbnRleHRJbmRleDsKKworICAgIC8vIGZsYWcgaWYgTnVtZXJpY1NoYXBlciBzaGFwZXMgY29udGV4dHVhbGx5CisgICAgLyoqIFRoZSBjb250ZXh0dWFsLiAqLworICAgIHByaXZhdGUgYm9vbGVhbiBmQ29udGV4dHVhbDsKKworICAgIC8vIHVzZXMgZm9yIG5vbi1jb250ZXh0IGRlcGVuZGVudCBjYXNlIG9ubHkKKyAgICAvKiogVGhlIHNpbmdsZSByYW5nZSBpbmRleC4gKi8KKyAgICBwcml2YXRlIGludCBmU2luZ2xlUmFuZ2VJbmRleDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgTnVtZXJpY1NoYXBlciB3aXRoIHNwZWNpZmllZCBwYXJhbWV0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIHJhbmdlcyBzcGVjaWZpZWQgcmFuZ2VzIHRvIGJlIHNoYXBlZAorICAgICAqIEBwYXJhbSBkZWZhdWx0Q29udGV4dCBkZWZhdWx0IGNvbnRleHQgcmFuZ2UKKyAgICAgKiBAcGFyYW0gaXNDb250ZXh0dWFsIHNwZWNpZmllcyBpZiB0aGUgaW5zdGFuY2UgaXMgY29udGV4dHVhbAorICAgICAqLworICAgIHByaXZhdGUgTnVtZXJpY1NoYXBlcihpbnQgcmFuZ2VzLCBpbnQgZGVmYXVsdENvbnRleHQsIGJvb2xlYW4gaXNDb250ZXh0dWFsKXsKKyAgICAgICAgdGhpcy5mUmFuZ2VzID0gcmFuZ2VzOworICAgICAgICB0aGlzLmZEZWZhdWx0Q29udGV4dEluZGV4ID0gZ2V0SW5kZXhGcm9tUmFuZ2UoZGVmYXVsdENvbnRleHQpOworICAgICAgICB0aGlzLmZDb250ZXh0dWFsID0gaXNDb250ZXh0dWFsOworCisgICAgICAgIGlmICghZkNvbnRleHR1YWwpeworICAgICAgICAgICAgZlNpbmdsZVJhbmdlSW5kZXggPSBnZXRJbmRleEZyb21SYW5nZShyYW5nZXMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBzY3JpcHQgaW5kZXggb2YgdGhlIHNwZWNpZmllZCBjb250ZXh0IHJhbmdlLgorICAgICAqCisgICAgICogQHBhcmFtIHJhbmdlIHNwZWNpZmllZCByYW5nZQorICAgICAqCisgICAgICogQHJldHVybiBvbmUgb2YgdGhlIHNjcmlwdCBpbmRpY2VzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIHJhbmdlLgorICAgICAqLworICAgIHByaXZhdGUgaW50IGdldEluZGV4RnJvbVJhbmdlKGludCByYW5nZSl7CisgICAgICAgIGlmIChyYW5nZSA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyByYW5nZUV4Y2VwdGlvbihyYW5nZSk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgaW5kZXggPSAwOworICAgICAgICB3aGlsZSAoaW5kZXggPCBNQVhfSU5ERVgpeworICAgICAgICAgICAgaWYgKHJhbmdlID09ICgxIDw8IGluZGV4KSl7CisgICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4OworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW5kZXgrKzsKKyAgICAgICAgfQorCisgICAgICAgIHRocm93IHJhbmdlRXhjZXB0aW9uKHJhbmdlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHJhbmdlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHNwZWNpZmllZCBzY3JpcHQgaW5kZXguCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXggc3BlY2lmaWVkIHNjcmlwdCBpbmRleAorICAgICAqCisgICAgICogQHJldHVybiBvbmUgb2YgdGhlIHJhbmdlIGNvbnN0YW50cyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCBzY3JpcHQgaW5kZXguCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgZ2V0UmFuZ2VGcm9tSW5kZXgoaW50IGluZGV4KXsKKyAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBNQVhfSU5ERVgpeworICAgICAgICAgICAgdGhyb3cgcmFuZ2VFeGNlcHRpb24oaW5kZXgpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIDEgPDwgaW5kZXg7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHJhbmdlRXhjZXB0aW9uKGludCB2YWx1ZSkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbGxlZ2FsIHJhbmdlIGFyZ3VtZW50IHZhbHVlOiAiICsgdmFsdWUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGludCByZXN1bHQgPSAxNzsKKyAgICAgICAgcmVzdWx0ID0gMzEgKiByZXN1bHQgKyBmUmFuZ2VzOworICAgICAgICByZXN1bHQgPSAzMSAqIHJlc3VsdCArIGZEZWZhdWx0Q29udGV4dEluZGV4OworICAgICAgICByZXN1bHQgPSAzMSAqIHJlc3VsdCArIChmQ29udGV4dHVhbCA/IDEgOiAwKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChvYmogPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTnVtZXJpY1NoYXBlciBucyA9IChOdW1lcmljU2hhcGVyKW9iajsKKyAgICAgICAgICAgIHJldHVybiAoZlJhbmdlcyA9PSBucy5mUmFuZ2VzICYmCisgICAgICAgICAgICAgICAgICAgIGZEZWZhdWx0Q29udGV4dEluZGV4ID09IG5zLmZEZWZhdWx0Q29udGV4dEluZGV4ICYmCisgICAgICAgICAgICAgICAgICAgIGZDb250ZXh0dWFsID09IG5zLmZDb250ZXh0dWFsKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpeworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIC8qICEhIFRoZXJlIGlzIG5vIGRlc2NyaXB0aW9uIGluIHRoZSBkb2N1bWVudGF0aW9uIHdoYXQgdGhpcyBtZXRob2QgbXVzdAorICAgICAgICAgKiByZXR1cm4uIFRodXMgZm9ybWF0IG9mIHRvU3RyaW5nIG1ldGhvZCBpcyBiYXNlZCBvbiAxLjUgcmVsZWFzZQorICAgICAgICAgKiBiZWhhdmlvciBhbmQgY2FuIGJlIG9idGFpbmVkIHVzaW5nIG5leHQgdGVzdCBzYW1wbGU6CisgICAgICAgICAqCisgICAgICAgICAqIC8vIFNpbXBsZSBzaGFwZXJzIHRvU3RyaW5nIGZvcm1hdAorICAgICAgICAgKiBTeXN0ZW0ub3V0LnByaW50bG4oTnVtZXJpY1NoYXBlci5nZXRTaGFwZXIoTnVtZXJpY1NoYXBlci5FQVNURVJOX0FSQUJJQykpOworICAgICAgICAgKgorICAgICAgICAgKiAvLyBDb250ZXh0IHNoYXBlcnMgd2l0aCBkZWZhdWx0IGNvbnRleHQgdG9TdHJpbmcgZm9ybWF0CisgICAgICAgICAqIFN5c3RlbS5vdXQucHJpbnRsbihOdW1lcmljU2hhcGVyLmdldENvbnRleHR1YWxTaGFwZXIoCisgICAgICAgICAqICAgICAgTnVtZXJpY1NoYXBlci5BUkFCSUMgfCBOdW1lcmljU2hhcGVyLlRBTUlMKSk7CisgICAgICAgICAqCisgICAgICAgICAqIC8vIENvbnRleHQgc2hhcGVycyB3aXRoIGNvbnRleHQKKyAgICAgICAgICogU3lzdGVtLm91dC5wcmludGxuKE51bWVyaWNTaGFwZXIuZ2V0Q29udGV4dHVhbFNoYXBlcigKKyAgICAgICAgICogICAgICBOdW1lcmljU2hhcGVyLkFSQUJJQyB8IE51bWVyaWNTaGFwZXIuVEFNSUwsCisgICAgICAgICAqICAgICAgTnVtZXJpY1NoYXBlci5FQVNURVJOX0FSQUJJQykpOworICAgICAgICAgKi8KKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKHN1cGVyLnRvU3RyaW5nKCkpOworCisgICAgICAgIHNiLmFwcGVuZCgiW2NvbnRleHR1YWw6Iik7CisgICAgICAgIHNiLmFwcGVuZChmQ29udGV4dHVhbCk7CisKKyAgICAgICAgaWYgKGZDb250ZXh0dWFsKXsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiLCBjb250ZXh0OiIpOworICAgICAgICAgICAgc2IuYXBwZW5kKGNvbnRleHRzW2ZEZWZhdWx0Q29udGV4dEluZGV4XSk7CisgICAgICAgIH0KKworICAgICAgICBzYi5hcHBlbmQoIiwgcmFuZ2Uocyk6ICIpOworICAgICAgICBpZiAoZkNvbnRleHR1YWwpIHsKKyAgICAgICAgICAgIGludCBpbmRleCA9IDA7CisgICAgICAgICAgICBib29sZWFuIGlzRmlyc3QgPSB0cnVlOworICAgICAgICAgICAgd2hpbGUgKGluZGV4IDwgTUFYX0lOREVYKXsKKyAgICAgICAgICAgICAgICBpZiAoKGZSYW5nZXMgJiAoMSA8PCBpbmRleCkpICE9IDApeworICAgICAgICAgICAgICAgICAgICBpZiAoaXNGaXJzdCl7CisgICAgICAgICAgICAgICAgICAgICAgICBpc0ZpcnN0ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIiwgIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKGNvbnRleHRzW2luZGV4XSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGluZGV4Kys7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoY29udGV4dHNbZlNpbmdsZVJhbmdlSW5kZXhdKTsKKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQoIl0iKTsKKworICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBOdW1lcmljU2hhcGVyIGZvciB0aGUgc3BlY2lmaWVkIHVuaWNvZGUgcmFuZ2VzCisgICAgICogYW5kIGRlZmF1bHQgdW5pY29kZSByYW5nZS4gVGhlIGRlZmF1bHRDb250ZXh0IHBhcmFtZXRlcgorICAgICAqIGlzIHVzZWQgYXMgdGhlIHN0YXJ0aW5nIGNvbnRleHQgKHdoaWNoIGluZGljYXRlcyB0aGUKKyAgICAgKiBsYW5ndWFnZS9zY3JpcHQgYmVpbmcgdXNlZCkuIFRoZSBPUiBsb2dpY2FsIG9wZXJhdGlvbgorICAgICAqIHNob3VsZCBiZSB1c2VkIGZvciBtdWx0aXBsZSByYW5nZXM6CisgICAgICogTnVtZXJpY1NoYXBlci5ERVZBTkFHQVJJIHwgTnVtZXJpY1NoYXBlci5CRU5HQUxJLgorICAgICAqIFRoZSBOdW1lcmljU2hhcGVyIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIGlzIGNvbnRleHR1YWwKKyAgICAgKiBpbiB0aGF0IGl0IHN1cHBvcnRzIG11bHRpcGxlIGNoYXJhY3RlciByYW5nZXMsIGRlcGVuZGluZworICAgICAqIG9uIHRoZSBjb250ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIHJhbmdlcyB0aGUgdW5pY29kZSByYW5nZXMuCisgICAgICogQHBhcmFtIGRlZmF1bHRDb250ZXh0IHRoZSBkZWZhdWx0LCBzdGFydGluZyBjb250ZXh0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgTnVtZXJpY1NoYXBlciBmb3IgdGhlIHNwZWNpZmllZCByYW5nZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBOdW1lcmljU2hhcGVyIGdldENvbnRleHR1YWxTaGFwZXIoaW50IHJhbmdlcywKKyAgICAgICAgICAgIGludCBkZWZhdWx0Q29udGV4dCkgeworICAgICAgICByYW5nZXMgJj0gQUxMX1JBTkdFUzsKKyAgICAgICAgZGVmYXVsdENvbnRleHQgJj0gQUxMX1JBTkdFUzsKKyAgICAgICAgcmV0dXJuIG5ldyBOdW1lcmljU2hhcGVyKHJhbmdlcywgZGVmYXVsdENvbnRleHQsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIE51bWVyaWNTaGFwZXIgZm9yIHRoZSBzcGVjaWZpZWQgdW5pY29kZSByYW5nZXMuCisgICAgICogVGhlIE9SIGxvZ2ljYWwgb3BlcmF0aW9uIHNob3VsZCBiZSB1c2VkIGZvciBtdWx0aXBsZSByYW5nZXM6CisgICAgICogTnVtZXJpY1NoYXBlci5ERVZBTkFHQVJJIHwgTnVtZXJpY1NoYXBlci5CRU5HQUxJLgorICAgICAqIFRoZSBOdW1lcmljU2hhcGVyIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIGlzIGNvbnRleHR1YWwKKyAgICAgKiBpbiB0aGF0IGl0IHN1cHBvcnRzIG11bHRpcGxlIGNoYXJhY3RlciByYW5nZXMsIGRlcGVuZGluZworICAgICAqIG9uIHRoZSBjb250ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIHJhbmdlcyB0aGUgdW5pY29kZSByYW5nZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBOdW1lcmljU2hhcGVyIGZvciB0aGUgc3BlY2lmaWVkIHJhbmdlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIE51bWVyaWNTaGFwZXIgZ2V0Q29udGV4dHVhbFNoYXBlcihpbnQgcmFuZ2VzKSB7CisgICAgICAgIHJhbmdlcyAmPSBBTExfUkFOR0VTOworICAgICAgICByZXR1cm4gbmV3IE51bWVyaWNTaGFwZXIocmFuZ2VzLCBFVVJPUEVBTiwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWFza3MgZm9yIGFsbCBvZiB0aGUgcmFuZ2VzIHN1cHBvcnRlZCBieSB0aGlzIE51bWVyaWNTaGFwZXIsCisgICAgICogcGFja2VkIGludG8gYW4gaW50IHZhbHVlIHVzaW5nIHRoZSBsb2dpY2FsIE9SIGxvZ2ljYWwgb3BlcmF0aW9uCisgICAgICogZm9yIG11bHRpcGxlIHJhbmdlczoKKyAgICAgKiBOdW1lcmljU2hhcGVyLkRFVkFOQUdBUkkgfCBOdW1lcmljU2hhcGVyLkJFTkdBTEkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFsbCByYW5nZXMgb2YgdGhpcyBOdW1lcmljU2hhcGVyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UmFuZ2VzKCkgeworICAgICAgICByZXR1cm4gZlJhbmdlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgTnVtZXJpY1NoYXBlciBmb3IgdGhlIHNwZWNpZmllZCB1bmljb2RlIHJhbmdlLgorICAgICAqIFRoZSBOdW1lcmljU2hhcGVyIHN1cHBvcnRzIG9ubHkgYSBzaW5nbGUgcmFuZ2UgYW5kCisgICAgICogaGVuY2UgaXMgbm90IGNvbnRleHR1YWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2luZ2xlUmFuZ2UgdGhlIHNwZWNpZmllZCB1bmljb2RlIHNpbmdsZSByYW5nZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIE51bWVyaWNTaGFwZXIgZm9yIHRoZSBzcGVjaWZpZWQgdW5pY29kZSByYW5nZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIE51bWVyaWNTaGFwZXIgZ2V0U2hhcGVyKGludCBzaW5nbGVSYW5nZSkgeworICAgICAgICBzaW5nbGVSYW5nZSAmPSBBTExfUkFOR0VTOworICAgICAgICByZXR1cm4gbmV3IE51bWVyaWNTaGFwZXIoc2luZ2xlUmFuZ2UsIEVVUk9QRUFOLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoaXMgTnVtZXJpY1NoYXBlciBpcyBjb250ZXh0dWFsIChzdXBwb3J0aW5nCisgICAgICogbXVsdGlwbGUgc2NyaXB0IHJhbmdlcykgb3Igbm90LgorICAgICAqCisgICAgICogQHJldHVybiB0cnVlLCBpZiB0aGlzIE51bWVyaWNTaGFwZXIgaXMgY29udGV4dHVhbCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQ29udGV4dHVhbCgpIHsKKyAgICAgICAgcmV0dXJuIGZDb250ZXh0dWFsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyYW5zZm9ybXMgdGhlIGVuY29kaW5nIG9mIHRoZSB0ZXh0LCBzdGFydGluZyBmcm9tIHRoZSBjaGFyYWN0ZXIKKyAgICAgKiBhdCBpbmRleCBzdGFydCBhbmQgdHJhbnNmb3JtaW5nIGNvdW50IGNoYXJhY3RlcnMsCisgICAgICogdXNpbmcgdGhlIHNwZWNpZmllZCBjb250ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIHRleHQgdGhlIHRleHQgdG8gYmUgc2hhcGVkLgorICAgICAqIEBwYXJhbSBzdGFydCB0aGUgc3RhcnQgb2Zmc2V0IG9mIHRoZSB0ZXh0LgorICAgICAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gYmUgc2hhcGVkLgorICAgICAqIEBwYXJhbSBjb250ZXh0IHRoZSBjb250ZXh0IHRvIGJlIHVzZWQgZm9yIHNoYXBpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2hhcGUoY2hhcltdIHRleHQsIGludCBzdGFydCwgaW50IGNvdW50LCBpbnQgY29udGV4dCkgeworICAgICAgICBpZiAoaXNDb250ZXh0dWFsKCkpeworICAgICAgICAgICAgY29udGV4dHVhbFNoYXBlKHRleHQsIHN0YXJ0LCBjb3VudCwgZ2V0SW5kZXhGcm9tUmFuZ2UoY29udGV4dCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbm9uQ29udGV4dHVhbFNoYXBlKHRleHQsIHN0YXJ0LCBjb3VudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmFuc2Zvcm1zIHRoZSBlbmNvZGluZyBvZiB0aGUgdGV4dCwgc3RhcnRpbmcgZnJvbSB0aGUgY2hhcmFjdGVyCisgICAgICogYXQgaW5kZXggc3RhcnQgYW5kIHRyYW5zZm9ybWluZyBjb3VudCBjaGFyYWN0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIHRleHQgdGhlIHRleHQgdG8gYmUgc2hhcGVkLgorICAgICAqIEBwYXJhbSBzdGFydCB0aGUgc3RhcnQgb2Zmc2V0IG9mIHRoZSB0ZXh0LgorICAgICAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gYmUgc2hhcGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNoYXBlKGNoYXJbXSB0ZXh0LCBpbnQgc3RhcnQsIGludCBjb3VudCkgeworICAgICAgICBpZiAoaXNDb250ZXh0dWFsKCkpeworICAgICAgICAgICAgY29udGV4dHVhbFNoYXBlKHRleHQsIHN0YXJ0LCBjb3VudCwgZkRlZmF1bHRDb250ZXh0SW5kZXgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbm9uQ29udGV4dHVhbFNoYXBlKHRleHQsIHN0YXJ0LCBjb3VudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyBjb3VudCBvZiBkaWdpdHMgb2YgdGhlIGdpdmVuIGFycmF5IG9mIGNoYXJhY3RlcnMgZnJvbSB0aGUgc3RhcnQKKyAgICAgKiBpbmRleCB1c2luZyBzcGVjaWZpZWQgY29udGV4dC4gVGhpcyBtZXRob2QgaXMgYXBwbGllZCBmb3IgdGhlIGNvbnRleHR1YWwKKyAgICAgKiBzaGFwaW5nLCBpZiB0aGUgc2hhcGVyIGluc3RhbmNlIGlzIG5vdCBjb250ZXh0dWFsIHVzZSBub25Db250ZXh0dWFsU2hhcGUKKyAgICAgKiBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGV4dCBhbiBhcnJheSBvZiBjaGFycworICAgICAqIEBwYXJhbSBzdGFydCBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIHRvIGNvbnZlcnQKKyAgICAgKiBAcGFyYW0gY291bnQgYSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBjb252ZXJ0CisgICAgICogQHBhcmFtIGNvbnRleHRJbmRleCBpbmRleCBvZiB0aGUgc2NyaXB0IGluZGV4IHRvIHVzZSBpbiBzaGFwZXIKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY29udGV4dHVhbFNoYXBlKGNoYXJbXSB0ZXh0LCBpbnQgc3RhcnQsIGludCBjb3VudCwKKyAgICAgICAgICAgIGludCBjb250ZXh0SW5kZXgpeworICAgICAgICBjaGFyIG1heERpZ2l0ID0gKGNoYXIpMHgwMDM5OworICAgICAgICBjaGFyIG1pbkRpZ2l0ID0gKGNoYXIpMHgwMDMwOworCisgICAgICAgIGludCBjdXJySW5kZXg7CisgICAgICAgIGlmICgoKDEgPDwgY29udGV4dEluZGV4KSAmIGZSYW5nZXMpID09IDAgKXsKKyAgICAgICAgICAgIGN1cnJJbmRleCA9IElOREVYX0VVUk9QRUFOOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY3VyckluZGV4ID0gY29udGV4dEluZGV4OworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaW5kID0gc3RhcnQ7IGluZCA8IHN0YXJ0ICsgY291bnQ7IGluZCsrKXsKKyAgICAgICAgICAgIGlmIChtaW5EaWdpdCA8PSB0ZXh0W2luZF0gJiYgdGV4dFtpbmRdIDw9IG1heERpZ2l0KXsKKyAgICAgICAgICAgICAgICBpZiAoY3VyckluZGV4ICE9IElOREVYX0VUSElPUElDIHx8IHRleHRbaW5kXSAhPSAnMCcpeworICAgICAgICAgICAgICAgICAgICB0ZXh0W2luZF0gPSAoY2hhcikoZGlnaXRzTG93UmFuZ2VzW2N1cnJJbmRleF0gKyB0ZXh0W2luZF0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYoaXNDaGFyU3Ryb25nKHRleHRbaW5kXSkpeworICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSBnZXRDaGFySW5kZXgodGV4dFtpbmRdKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJJbmRleCAhPSBpbmRleCl7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKCgxIDw8IGluZGV4KSAmIGZSYW5nZXMpICE9IDApeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJJbmRleCA9IGluZGV4OworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJySW5kZXggPSBJTkRFWF9FVVJPUEVBTjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgY291bnQgb2YgZGlnaXRzIG9mIHRoZSBnaXZlbiBhcnJheSBvZiBjaGFyYWN0ZXJzIGZyb20gdGhlIHN0YXJ0CisgICAgICogaW5kZXguIE1ldGhvZCBpcyBhcHBsaWVkIGZvciBub24tY29udGV4dHVhbCBzaGFwZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGV4dCBhbiBhcnJheSBvZiBjaGFycworICAgICAqIEBwYXJhbSBzdGFydCBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIHRvIGNvbnZlcnQKKyAgICAgKiBAcGFyYW0gY291bnQgYSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBjb252ZXJ0CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIG5vbkNvbnRleHR1YWxTaGFwZShjaGFyW10gdGV4dCwgaW50IHN0YXJ0LCBpbnQgY291bnQpeworICAgICAgICBjaGFyIG1heERpZ2l0ID0gKGNoYXIpMHgwMDM5OworICAgICAgICBjaGFyIG1pbkRpZ2l0ID0gKGNoYXIpKChmUmFuZ2VzID09IEVUSElPUElDKSA/IDB4MDAzMSA6IDB4MDAzMCk7CisgICAgICAgIGZvciAoaW50IGluZCA9IHN0YXJ0OyBpbmQgPCBzdGFydCArIGNvdW50OyBpbmQrKyl7CisgICAgICAgICAgICBpZiAobWluRGlnaXQgPD0gdGV4dFtpbmRdICYmIHRleHRbaW5kXSA8PSBtYXhEaWdpdCl7CisgICAgICAgICAgICAgICAgICAgIHRleHRbaW5kXSA9IChjaGFyKShkaWdpdHNMb3dSYW5nZXNbZlNpbmdsZVJhbmdlSW5kZXhdICsgdGV4dFtpbmRdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIHNjcmlwdCBvZiB0aGUgc3BlY2lmaWVkIGNoYXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2ggc3BlY2lmaWVkIHVuaWNvZGUgY2hhcmFjdGVyCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHNjcmlwdCBpbmRleCBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbiBjaGFyCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgZ2V0Q2hhckluZGV4KGNoYXIgY2gpeworICAgICAgICBpbnQgaW5kZXggPSBJTkRFWF9FVVJPUEVBTjsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpIDwgTUFYX0lOREVYOyBpKyspeworICAgICAgICAgICAgaW50IGogPSBpICogMjsKKyAgICAgICAgICAgIGlmIChzY3JpcHRzUmFuZ2VzW2pdIDw9IGNoICYmIGNoIDw9IHNjcmlwdHNSYW5nZXNbaisxXSl7CisgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gaW5kZXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBiaWRpcmVjdGlvbmFsIGNhdGVnb3J5IG9mIHRoZSBjaGFyYWN0ZXIKKyAgICAgKiBpcyBzdHJvbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hyIHRoZSBjaHIKKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIGNoYXJhY3RlciBpcyBzdHJvbmcsIGZhbHNlIG90aGVyd2lzZQorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpc0NoYXJTdHJvbmcoaW50IGNocikgeworICAgICAgICByZXR1cm4gKFNUUk9OR19URVhUX0ZMQUdTW2NociA+PiA1XSAmICgxIDw8IChjaHIgJSAzMikpKSAhPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYWxsIHByaXZhdGUgc2VyaWFsaXplZCBmaWVsZHMgZm9yIG9iamVjdCB0byBiZSBjb3JyZWN0bHkgc2VyaWFsaXplZAorICAgICAqIGFjY29yZGluZyB0byB0aGUgc2VyaWFsaXplZCBmb3JtIG9mIHRoaXMgY2xhc3MgbWVudGlvbmVkIGluIHRoZQorICAgICAqIGRvY3VtZW50YXRpb24uCisgICAgICovCisgICAgIHByaXZhdGUgdm9pZCB1cGRhdGVSYW5nZXNGaWVsZHMoKXsKKyAgICAgICAgZlJhbmdlcyA9IChtYXNrICYgfigxIDw8IDMxKSk7CisgICAgICAgIGZDb250ZXh0dWFsID0gKChtYXNrICYoMSA8PCAzMSkpICE9IDApOworICAgICAgICBpZiAoZkNvbnRleHR1YWwpeworICAgICAgICAgICAgZlJhbmdlcyA9IChtYXNrICYgfigxIDw8IDMxKSk7CisgICAgICAgICAgICBmRGVmYXVsdENvbnRleHRJbmRleCA9IGtleTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZSYW5nZXMgPSBtYXNrOworICAgICAgICAgICAgZlNpbmdsZVJhbmdlSW5kZXggPSBrZXk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHByaXZhdGUgZmllbGRzIGZvciBvYmplY3QgYWZ0ZXIgZGVzZXJpYWxpemF0aW9uCisgICAgICogYWNjb3JkaW5nIHRvIHRoZSBzZXJpYWxpemVkIGZvcm0gb2YgdGhpcyBjbGFzcyBtZW50aW9uZWQgaW4gdGhlCisgICAgICogZG9jdW1lbnRhdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgdXBkYXRlS2V5TWFza0ZpZWxkcygpeworICAgICAgICBtYXNrID0gZlJhbmdlczsKKyAgICAgICAgaWYgKGZDb250ZXh0dWFsKXsKKyAgICAgICAgICAgIG1hc2sgfD0gKDEgPDwgMzEpOworICAgICAgICAgICAga2V5ID0gZkRlZmF1bHRDb250ZXh0SW5kZXg7CisgICAgICAgIH0gZWxzZXsKKyAgICAgICAgICAgIGtleSA9IGZTaW5nbGVSYW5nZUluZGV4OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGUgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIG91dCB0aGUgb3V0CisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIFNpZ25hbHMgdGhhdCBhbiBJL08gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW0gb3V0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb257CisgICAgICAgIHVwZGF0ZUtleU1hc2tGaWVsZHMoKTsKKyAgICAgICAgb3V0LmRlZmF1bHRXcml0ZU9iamVjdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIGluIHRoZSBpbgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBTaWduYWxzIHRoYXQgYW4gSS9PIGV4Y2VwdGlvbiBoYXMgb2NjdXJyZWQuCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHRoZSBjbGFzcyBub3QgZm91bmQgZXhjZXB0aW9uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSBpbikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9ueworICAgICAgICBpbi5kZWZhdWx0UmVhZE9iamVjdCgpOworICAgICAgICB1cGRhdGVSYW5nZXNGaWVsZHMoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2F3dC9mb250L1RleHRBdHRyaWJ1dGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2F3dC9mb250L1RleHRBdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOTI5ZmRiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvYXd0L2ZvbnQvVGV4dEF0dHJpYnV0ZS5qYXZhCkBAIC0wLDAgKzEsMzAzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIElseWEgUy4gT2tvbWluCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KK3BhY2thZ2UgamF2YS5hd3QuZm9udDsKKworaW1wb3J0IGphdmEudGV4dC5BdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlOworCisvKioKKyAqIFRoZSBUZXh0QXR0cmlidXRlIGNsYXNzIGRlZmluZXMgYXR0cmlidXRlIGtleXMgYW5kIGF0dHJpYnV0ZSB2YWx1ZXMKKyAqIGZvciB0ZXh0IHJlbmRlcmluZy4gRWFjaCBUZXh0QXR0cmlidXRlcyBzaG91bGQgaGF2ZSB0aGUgZm9sbG93aW5nCisgKiBpbmZvcm1hdGlvbjoKKyAqIDx1bD4KKyAqIDxsaT5rZXkgbmFtZTs8L2xpPgorICogPGxpPnZhbGlkIHZhbHVlczs8L2xpPgorICogPGxpPnJlbGV2YW50IGNvbnN0YW50czs8L2xpPgorICogPGxpPmRlZmF1bHQgYWN0aW9uIGlmIHRoZSBhdHRyaWJ1dGUgaXMgYWJzZW50OzwvbGk+CisgKiA8bGk+ZGVmYXVsdCBhY3Rpb24ncyBkZXNjcmlwdGlvbi48L2xpPgorICogPC91bD4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFRleHRBdHRyaWJ1dGUgZXh0ZW5kcyBBdHRyaWJ1dGUgeworCisgICAgLyoqIFRoZSBDb25zdGFudCBzZXJpYWxWZXJzaW9uVUlELiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDc3NDQxMTI3ODQxMTc4NjE3MDJMOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGVzIGEgbmV3IFRleHRBdHRyaWJ1dGUgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiBUZXh0QXR0cmlidXRlLgorICAgICAqLworICAgIHByb3RlY3RlZCBUZXh0QXR0cmlidXRlKFN0cmluZyBuYW1lKSB7CisgICAgICAgIHN1cGVyKG5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBCQUNLR1JPVU5EIHRleHQgYXR0cmlidXRlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVGV4dEF0dHJpYnV0ZSBCQUNLR1JPVU5EID0gbmV3IFRleHRBdHRyaWJ1dGUoImJhY2tncm91bmQiKTsKKworICAgIC8qKiBUaGUgQklESV9FTUJFRERJTkcgdGV4dCBhdHRyaWJ1dGUga2V5LiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVGV4dEF0dHJpYnV0ZSBCSURJX0VNQkVERElORyA9IG5ldyBUZXh0QXR0cmlidXRlKCJiaWRpX2VtYmVkZGluZyIpOworCisgICAgLyoqIFRoZSBDSEFSX1JFUExBQ0VNRU5UIHRleHQgYXR0cmlidXRlIGtleS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRleHRBdHRyaWJ1dGUgQ0hBUl9SRVBMQUNFTUVOVCA9IG5ldyBUZXh0QXR0cmlidXRlKCJjaGFyX3JlcGxhY2VtZW50Iik7CisKKyAgICAvKiogVGhlIEZBTUlMWSB0ZXh0IGF0dHJpYnV0ZSBrZXkuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBUZXh0QXR0cmlidXRlIEZBTUlMWSA9IG5ldyBUZXh0QXR0cmlidXRlKCJmYW1pbHkiKTsKKworICAgIC8qKiBUaGUgRk9OVCB0ZXh0IGF0dHJpYnV0ZSBrZXkuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBUZXh0QXR0cmlidXRlIEZPTlQgPSBuZXcgVGV4dEF0dHJpYnV0ZSgiZm9udCIpOworCisgICAgLyoqIFRoZSBGT1JFR1JPVU5EIHRleHQgYXR0cmlidXRlIGtleS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRleHRBdHRyaWJ1dGUgRk9SRUdST1VORCA9IG5ldyBUZXh0QXR0cmlidXRlKCJmb3JlZ3JvdW5kIik7CisKKyAgICAvKiogVGhlIElOUFVUX01FVEhPRF9ISUdITElHSFQgdGV4dCBhdHRyaWJ1dGUga2V5LiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVGV4dEF0dHJpYnV0ZSBJTlBVVF9NRVRIT0RfSElHSExJR0hUID0gbmV3IFRleHRBdHRyaWJ1dGUoCisgICAgICAgICAgICAiaW5wdXQgbWV0aG9kIGhpZ2hsaWdodCIpOworCisgICAgLyoqIFRoZSBJTlBVVF9NRVRIT0RfVU5ERVJMSU5FIHRleHQgYXR0cmlidXRlIGtleS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRleHRBdHRyaWJ1dGUgSU5QVVRfTUVUSE9EX1VOREVSTElORSA9IG5ldyBUZXh0QXR0cmlidXRlKAorICAgICAgICAgICAgImlucHV0IG1ldGhvZCB1bmRlcmxpbmUiKTsKKworICAgIC8qKiBUaGUgSlVTVElGSUNBVElPTiB0ZXh0IGF0dHJpYnV0ZSBrZXkuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBUZXh0QXR0cmlidXRlIEpVU1RJRklDQVRJT04gPSBuZXcgVGV4dEF0dHJpYnV0ZSgianVzdGlmaWNhdGlvbiIpOworCisgICAgLyoqIFRoZSBDb25zdGFudCBKVVNUSUZJQ0FUSU9OX2luZGljYXRlcyB0aGUgZnVsbCByZXF1ZXN0ZWQgd2lkdGguICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGbG9hdCBKVVNUSUZJQ0FUSU9OX0ZVTEwgPSBuZXcgRmxvYXQoMS4wZik7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgSlVTVElGSUNBVElPTl9OT05FIGluZGljYXRlcyB0aGF0IGxpbmUgaXMgbm90CisgICAgICogYWxsb3dlZCBmb3IganVzdGlmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZsb2F0IEpVU1RJRklDQVRJT05fTk9ORSA9IG5ldyBGbG9hdCgwLjBmKTsKKworICAgIC8qKgorICAgICAqIFRoZSBLRVJOSU5HIHRleHQgYXR0cmlidXRlIGtleS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRleHRBdHRyaWJ1dGUgS0VSTklORyA9IG5ldyBUZXh0QXR0cmlidXRlKCJrZXJuaW5nIik7CisKKyAgICAvKiogQHNpbmNlIDEuNiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW50ZWdlciBLRVJOSU5HX09OID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBMSUdBVFVSRVMgdGV4dCBhdHRyaWJ1dGUga2V5LgorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVGV4dEF0dHJpYnV0ZSBMSUdBVFVSRVMgPSBuZXcgVGV4dEF0dHJpYnV0ZSgibGlnYXR1cmVzIik7CisKKyAgICAvKiogQHNpbmNlIDEuNiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW50ZWdlciBMSUdBVFVSRVNfT04gPSAxOworCisgICAgLyoqIFRoZSBOVU1FUklDX1NIQVBJTkcgdGV4dCBhdHRyaWJ1dGUuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBUZXh0QXR0cmlidXRlIE5VTUVSSUNfU0hBUElORyA9IG5ldyBUZXh0QXR0cmlidXRlKCJudW1lcmljX3NoYXBpbmciKTsKKworICAgIC8qKiBUaGUgUE9TVFVSRSB0ZXh0IGF0dHJpYnV0ZS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRleHRBdHRyaWJ1dGUgUE9TVFVSRSA9IG5ldyBUZXh0QXR0cmlidXRlKCJwb3N0dXJlIik7CisKKyAgICAvKiogVGhlIENvbnN0YW50IFBPU1RVUkVfUkVHVUxBUiBpbmRpY2F0ZXMgcmVndWxhciBwb3N0dXJlLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmxvYXQgUE9TVFVSRV9SRUdVTEFSID0gbmV3IEZsb2F0KDAuMGYpOworCisgICAgLyoqIFRoZSBDb25zdGFudCBQT1NUVVJFX09CTElRVUUgaW5kaWNhdGVzIGl0YWxpYyBwb3N0dXJlLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmxvYXQgUE9TVFVSRV9PQkxJUVVFID0gbmV3IEZsb2F0KDAuMjBmKTsKKworICAgIC8qKiBUaGUgUlVOX0RJUkVDVElPTiB0ZXh0IGF0dHJpYnV0ZS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRleHRBdHRyaWJ1dGUgUlVOX0RJUkVDVElPTiA9IG5ldyBUZXh0QXR0cmlidXRlKCJydW5fZGlyZWN0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgUlVOX0RJUkVDVElPTl9MVFIgaW5kaWNhdGVzIGxlZnQtdG8tcmlnaHQgcnVuCisgICAgICogZGlyZWN0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQm9vbGVhbiBSVU5fRElSRUNUSU9OX0xUUiA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFJVTl9ESVJFQ1RJT05fUlRMIGluZGljYXRlcyByaWdodC10by1sZWZ0IHJ1bgorICAgICAqIGRpcmVjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEJvb2xlYW4gUlVOX0RJUkVDVElPTl9SVEwgPSB0cnVlOworCisgICAgLyoqIFRoZSBTSVpFIHRleHQgYXR0cmlidXRlLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVGV4dEF0dHJpYnV0ZSBTSVpFID0gbmV3IFRleHRBdHRyaWJ1dGUoInNpemUiKTsKKworICAgIC8qKiBUaGUgU1RSSUtFVEhST1VHSCB0ZXh0IGF0dHJpYnV0ZS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRleHRBdHRyaWJ1dGUgU1RSSUtFVEhST1VHSCA9IG5ldyBUZXh0QXR0cmlidXRlKCJzdHJpa2V0aHJvdWdoIik7CisKKyAgICAvKiogVGhlIENvbnN0YW50IFNUUklLRVRIUk9VR0hfT04gaW5kaWNhdGVzIGEgc2luZ2xlIHN0cmlrZXRocm91Z2guICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBCb29sZWFuIFNUUklLRVRIUk9VR0hfT04gPSB0cnVlOworCisgICAgLyoqIFRoZSBTVVBFUlNDUklQVCB0ZXh0IGF0dHJpYnV0ZS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRleHRBdHRyaWJ1dGUgU1VQRVJTQ1JJUFQgPSBuZXcgVGV4dEF0dHJpYnV0ZSgic3VwZXJzY3JpcHQiKTsKKworICAgIC8qKiBUaGUgQ29uc3RhbnQgU1VQRVJTQ1JJUFRfU1VCIGluZGljYXRlcyBhIHN0YW5kYXJkIHN1YnNjcmlwdC4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEludGVnZXIgU1VQRVJTQ1JJUFRfU1VCID0gLTE7CisKKyAgICAvKiogVGhlIENvbnN0YW50IFNVUEVSU0NSSVBUX1NVUEVSIGluZGljYXRlcyBhIHN0YW5kYXJkIHN1cGVyc2NyaXB0LiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW50ZWdlciBTVVBFUlNDUklQVF9TVVBFUiA9IDE7CisKKyAgICAvKiogVGhlIFNXQVBfQ09MT1JTIHRleHQgYXR0cmlidXRlLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVGV4dEF0dHJpYnV0ZSBTV0FQX0NPTE9SUyA9IG5ldyBUZXh0QXR0cmlidXRlKCJzd2FwX2NvbG9ycyIpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFNXQVBfQ09MT1JTX09OIGluZGljYXRlcyBhIHN3YXAgb2YgZm9yZWdyb3VuZAorICAgICAqIGFuZCBiYWNrZ3JvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQm9vbGVhbiBTV0FQX0NPTE9SU19PTiA9IHRydWU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgVFJBQ0tJTkcgdGV4dCBhdHRyaWJ1dGUga2V5LgorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVGV4dEF0dHJpYnV0ZSBUUkFDS0lORyA9IG5ldyBUZXh0QXR0cmlidXRlKCJ0cmFja2luZyIpOworCisgICAgLyoqIEBzaW5jZSAxLjYgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZsb2F0IFRSQUNLSU5HX0xPT1NFID0gMC4wNGY7CisgICAgLyoqIEBzaW5jZSAxLjYgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZsb2F0IFRSQUNLSU5HX1RJR0hUID0gLTAuMDRmOworCisgICAgLyoqIFRoZSBUUkFOU0ZPUk0gdGV4dCBhdHRyaWJ1dGUuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBUZXh0QXR0cmlidXRlIFRSQU5TRk9STSA9IG5ldyBUZXh0QXR0cmlidXRlKCJ0cmFuc2Zvcm0iKTsKKworICAgIC8qKiBUaGUgQ29uc3RhbnQgVU5ERVJMSU5FIHRleHQgYXR0cmlidXRlLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVGV4dEF0dHJpYnV0ZSBVTkRFUkxJTkUgPSBuZXcgVGV4dEF0dHJpYnV0ZSgidW5kZXJsaW5lIik7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVU5ERVJMSU5FX09OIGluZGljYXRlcyBhIHN0YW5kYXJkIHVuZGVybGluZQorICAgICAqIGF0IHRoZSByb21hbiBiYXNlbGluZSBmb3Igcm9tYW4gdGV4dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEludGVnZXIgVU5ERVJMSU5FX09OID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBVTkRFUkxJTkVfTE9XX09ORV9QSVhFTCBpbmRpY2F0ZXMgYSBzaW5nbGUKKyAgICAgKiBwaXhlbCBzb2xpZCBsb3cgdW5kZXJsaW5lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW50ZWdlciBVTkRFUkxJTkVfTE9XX09ORV9QSVhFTCA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVU5ERVJMSU5FX0xPV19UV09fUElYRUwgaW5kaWNhdGVzIGEgZG91YmxlCisgICAgICogcGl4ZWwgc29saWQgbG93IHVuZGVybGluZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEludGVnZXIgVU5ERVJMSU5FX0xPV19UV09fUElYRUwgPSAyOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFVOREVSTElORV9MT1dfRE9UVEVEIGluZGljYXRlcyBhCisgICAgICogc2luZ2xlIHBpeGVsIGRvdHRlZCBsb3cgdW5kZXJsaW5lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW50ZWdlciBVTkRFUkxJTkVfTE9XX0RPVFRFRCA9IDM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVU5ERVJMSU5FX0xPV19HUkFZIGluZGljYXRlcyBkb3VibGUgcGl4ZWwKKyAgICAgKiBncmF5IGxvdyB1bmRlcmxpbmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBJbnRlZ2VyIFVOREVSTElORV9MT1dfR1JBWSA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgVU5ERVJMSU5FX0xPV19EQVNIRUQgaW5kaWNhdGVzIHNpbmdsZSBwaXhlbCBkYXNoZWQKKyAgICAgKiBsb3cgdW5kZXJsaW5lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW50ZWdlciBVTkRFUkxJTkVfTE9XX0RBU0hFRCA9IDU7CisKKyAgICAvKiogVGhlIFdFSUdIVCB0ZXh0IGF0dHJpYnV0ZS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRleHRBdHRyaWJ1dGUgV0VJR0hUID0gbmV3IFRleHRBdHRyaWJ1dGUoIndlaWdodCIpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFdFSUdIVF9FWFRSQV9MSUdIVCBpbmRpY2F0ZXMgdGhlIGxpZ2h0ZXN0CisgICAgICogcHJlZGVmaW5lZCB3ZWlnaHQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGbG9hdCBXRUlHSFRfRVhUUkFfTElHSFQgPSBuZXcgRmxvYXQoMC41Zik7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgV0VJR0hUX0xJR0hUIGluZGljYXRlcyB0aGUgc3RhbmRhcmQgbGlnaHQgd2VpZ2h0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmxvYXQgV0VJR0hUX0xJR0hUID0gbmV3IEZsb2F0KDAuNzVmKTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBXRUlHSFRfREVNSUxJR0hUIGluZGljYXRlcyBhbiBpbnRlcm1lZGlhdGUgd2VpZ2h0CisgICAgICogYmV0d2VlbiBMSUdIVCBhbmQgU1RBTkRBUkQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGbG9hdCBXRUlHSFRfREVNSUxJR0hUID0gbmV3IEZsb2F0KDAuODc1Zik7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgV0VJR0hUX1JFR1VMQVIgaW5kaWNhdGVzIHRoZSBzdGFuZGFydCB3ZWlnaHQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGbG9hdCBXRUlHSFRfUkVHVUxBUiA9IG5ldyBGbG9hdCgxLjBmKTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBXRUlHSFRfU0VNSUJPTEQgaW5kaWNhdGVzIGEgc2VtaSB3ZWlnaHQKKyAgICAgKiBvZiBSRUdVTEFSLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmxvYXQgV0VJR0hUX1NFTUlCT0xEID0gbmV3IEZsb2F0KDEuMjVmKTsKKworICAgIC8qKiBUaGUgQ29uc3RhbnQgV0VJR0hUX01FRElVTSBpbmRpY2F0ZXMgYXZlcmFnZSB3ZWlnaHQKKyAgICAgKiBiZXR3ZWVuIHRoZSBSRUdVTEFSIGFuZCBCT0xELiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmxvYXQgV0VJR0hUX01FRElVTSA9IG5ldyBGbG9hdCgxLjVmKTsKKworICAgIC8qKiBUaGUgQ29uc3RhbnQgV0VJR0hUX0RFTUlCT0xEIGluZGljYXRlcworICAgICAqIGEgbGlnaHRlciB3ZWlnaHQgdGhhbiBCT0xELiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmxvYXQgV0VJR0hUX0RFTUlCT0xEID0gbmV3IEZsb2F0KDEuNzVmKTsKKworICAgIC8qKiBUaGUgQ29uc3RhbnQgV0VJR0hUX0JPTEQgaW5kaWNhdGVzIHRoZSBzdGFuZGFyZCBib2xkIHdlaWdodC4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZsb2F0IFdFSUdIVF9CT0xEID0gbmV3IEZsb2F0KDIuMGYpOworCisgICAgLyoqIFRoZSBDb25zdGFudCBXRUlHSFRfSEVBVlkgaW5kaWNhdGVzIGEgaGVhdmllciB3ZWlnaHQgdGhhbiBCT0xELiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmxvYXQgV0VJR0hUX0hFQVZZID0gbmV3IEZsb2F0KDIuMjVmKTsKKworICAgIC8qKiBUaGUgQ29uc3RhbnQgV0VJR0hUX0VYVFJBQk9MRCBpbmRpY2F0ZXMgYW4gZXh0cmEgaGVhdnkgd2VpZ2h0LiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmxvYXQgV0VJR0hUX0VYVFJBQk9MRCA9IG5ldyBGbG9hdCgyLjVmKTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBXRUlHSFRfVUxUUkFCT0xEIGluZGljYXRlcyB0aGUgaGVhdmllc3QgcHJlZGVmaW5lZAorICAgICAqIHdlaWdodC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZsb2F0IFdFSUdIVF9VTFRSQUJPTEQgPSBuZXcgRmxvYXQoMi43NWYpOworCisgICAgLyoqIFRoZSBXSURUSCB0ZXh0IGF0dHJpYnV0ZS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRleHRBdHRyaWJ1dGUgV0lEVEggPSBuZXcgVGV4dEF0dHJpYnV0ZSgid2lkdGgiKTsKKworICAgIC8qKgorICAgICAqIFRoZSBDb25zdGFudCBXSURUSF9DT05ERU5TRUQgaW5kaWNhdGVzIHRoZSBtb3N0IGNvbmRlbnNlZAorICAgICAqIHByZWRlZmluZWQgd2lkdGguCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGbG9hdCBXSURUSF9DT05ERU5TRUQgPSBuZXcgRmxvYXQoMC43NWYpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFdJRFRIX1NFTUlfQ09OREVOU0VEIGluZGljYXRlcworICAgICAqIGEgc2VtaSBjb25kZW5zZWQgd2lkdGguCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGbG9hdCBXSURUSF9TRU1JX0NPTkRFTlNFRCA9IG5ldyBGbG9hdCgwLjg3NWYpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFdJRFRIX1JFR1VMQVIgaW5kaWNhdGVzIHRoZSBzdGFuZGFyZCB3aWR0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZsb2F0IFdJRFRIX1JFR1VMQVIgPSBuZXcgRmxvYXQoMS4wZik7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQ29uc3RhbnQgV0lEVEhfU0VNSV9FWFRFTkRFRCBpbmRpY2F0ZXMgc2VtaSBleHRlbmRlZCB3aWR0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZsb2F0IFdJRFRIX1NFTUlfRVhURU5ERUQgPSBuZXcgRmxvYXQoMS4yNWYpOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0YW50IFdJRFRIX0VYVEVOREVEIGluZGljYXRlcyBleHRlbmRlZCB3aWR0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZsb2F0IFdJRFRIX0VYVEVOREVEID0gbmV3IEZsb2F0KDEuNWYpOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9iZWFucy9JbmRleGVkUHJvcGVydHlDaGFuZ2VFdmVudC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvYmVhbnMvSW5kZXhlZFByb3BlcnR5Q2hhbmdlRXZlbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZDM0MGQ0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvYmVhbnMvSW5kZXhlZFByb3BlcnR5Q2hhbmdlRXZlbnQuamF2YQpAQCAtMCwwICsxLDYyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUCisgKiBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUKKyAqIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCisgKiB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuYmVhbnM7CisKKy8qKgorICogQSB0eXBlIG9mIHtAbGluayBQcm9wZXJ0eUNoYW5nZUV2ZW50fSB0aGF0IGluZGljYXRlcyB0aGF0IGFuIGluZGV4ZWQgcHJvcGVydHkKKyAqIGhhcyBjaGFuZ2VkLgorICovCitwdWJsaWMgY2xhc3MgSW5kZXhlZFByb3BlcnR5Q2hhbmdlRXZlbnQgZXh0ZW5kcyBQcm9wZXJ0eUNoYW5nZUV2ZW50IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0zMjAyMjc0NDg0OTU4MDY4NzBMOworCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgaW5kZXg7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHByb3BlcnR5IGNoYW5nZWQgZXZlbnQgd2l0aCBhbiBpbmRpY2F0aW9uIG9mIHRoZSBwcm9wZXJ0eQorICAgICAqIGluZGV4LgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIGNoYW5nZWQgYmVhbi4KKyAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lCisgICAgICogICAgICAgICAgICB0aGUgY2hhbmdlZCBwcm9wZXJ0eSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gdG8gaW5kaWNhdGUgYW4KKyAgICAgKiAgICAgICAgICAgIHVuc3BlY2lmaWVkIHNldCBvZiB0aGUgcHJvcGVydGllcyBoYXMgY2hhbmdlZC4KKyAgICAgKiBAcGFyYW0gb2xkVmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmV2aW91cyB2YWx1ZSBvZiB0aGUgcHJvcGVydHksIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmCisgICAgICogICAgICAgICAgICB0aGUgPGNvZGU+cHJvcGVydHlOYW1lPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiBvciB0aGUKKyAgICAgKiAgICAgICAgICAgIHByZXZpb3VzIHZhbHVlIGlzIHVua25vd24uCisgICAgICogQHBhcmFtIG5ld1ZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlCisgICAgICogICAgICAgICAgICA8Y29kZT5wcm9wZXJ0eU5hbWU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+IG9yIHRoZSBuZXcKKyAgICAgKiAgICAgICAgICAgIHZhbHVlIGlzIHVua25vd24uLgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBwcm9wZXJ0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5kZXhlZFByb3BlcnR5Q2hhbmdlRXZlbnQoT2JqZWN0IHNvdXJjZSwgU3RyaW5nIHByb3BlcnR5TmFtZSwKKyAgICAgICAgICAgIE9iamVjdCBvbGRWYWx1ZSwgT2JqZWN0IG5ld1ZhbHVlLCBpbnQgaW5kZXgpIHsKKyAgICAgICAgc3VwZXIoc291cmNlLCBwcm9wZXJ0eU5hbWUsIG9sZFZhbHVlLCBuZXdWYWx1ZSk7CisgICAgICAgIHRoaXMuaW5kZXggPSBpbmRleDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgcHJvcGVydHkgdGhhdCB3YXMgY2hhbmdlZCBpbiB0aGlzIGV2ZW50LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXgoKSB7CisgICAgICAgIHJldHVybiBpbmRleDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9iZWFucy9Qcm9wZXJ0eUNoYW5nZUV2ZW50LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9iZWFucy9Qcm9wZXJ0eUNoYW5nZUV2ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmUwNDU1ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2JlYW5zL1Byb3BlcnR5Q2hhbmdlRXZlbnQuamF2YQpAQCAtMCwwICsxLDExNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmJlYW5zOworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50T2JqZWN0OworCisvKioKKyAqIEFuIGV2ZW50IHRoYXQgaW5kaWNhdGVzIHRoYXQgYSBjb25zdHJhaW50IG9yIGEgYm91bmRhcnkgb2YgYSBwcm9wZXJ0eSBoYXMKKyAqIGNoYW5nZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBQcm9wZXJ0eUNoYW5nZUV2ZW50IGV4dGVuZHMgRXZlbnRPYmplY3QgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzA0MjY5MzY4ODkzOTY0ODEyM0w7CisKKyAgICBTdHJpbmcgcHJvcGVydHlOYW1lOworCisgICAgT2JqZWN0IG9sZFZhbHVlOworCisgICAgT2JqZWN0IG5ld1ZhbHVlOworCisgICAgT2JqZWN0IHByb3BhZ2F0aW9uSWQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29uc3RydWN0b3IgdXNlZCB0byBjcmVhdGUgYSBuZXcge0Bjb2RlIFByb3BlcnR5Q2hhbmdlRXZlbnR9LgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIGNoYW5nZWQgYmVhbi4KKyAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lCisgICAgICogICAgICAgICAgICB0aGUgY2hhbmdlZCBwcm9wZXJ0eSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gdG8gaW5kaWNhdGUgYW4KKyAgICAgKiAgICAgICAgICAgIHVuc3BlY2lmaWVkIHNldCBvZiB0aGUgcHJvcGVydGllcyBoYXMgY2hhbmdlZC4KKyAgICAgKiBAcGFyYW0gb2xkVmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmV2aW91cyB2YWx1ZSBvZiB0aGUgcHJvcGVydHksIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmCisgICAgICogICAgICAgICAgICB0aGUgPGNvZGU+cHJvcGVydHlOYW1lPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiBvciB0aGUKKyAgICAgKiAgICAgICAgICAgIHByZXZpb3VzIHZhbHVlIGlzIHVua25vd24uCisgICAgICogQHBhcmFtIG5ld1ZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlCisgICAgICogICAgICAgICAgICA8Y29kZT5wcm9wZXJ0eU5hbWU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+IG9yIHRoZSBuZXcKKyAgICAgKiAgICAgICAgICAgIHZhbHVlIGlzIHVua25vd24uCisgICAgICovCisgICAgcHVibGljIFByb3BlcnR5Q2hhbmdlRXZlbnQoT2JqZWN0IHNvdXJjZSwgU3RyaW5nIHByb3BlcnR5TmFtZSwKKyAgICAgICAgICAgIE9iamVjdCBvbGRWYWx1ZSwgT2JqZWN0IG5ld1ZhbHVlKSB7CisgICAgICAgIHN1cGVyKHNvdXJjZSk7CisKKyAgICAgICAgdGhpcy5wcm9wZXJ0eU5hbWUgPSBwcm9wZXJ0eU5hbWU7CisgICAgICAgIHRoaXMub2xkVmFsdWUgPSBvbGRWYWx1ZTsKKyAgICAgICAgdGhpcy5uZXdWYWx1ZSA9IG5ld1ZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRoYXQgaGFzIGNoYW5nZWQuIElmIGFuIHVuc3BlY2lmaWVkIHNldAorICAgICAqIG9mIHByb3BlcnRpZXMgaGFzIGNoYW5nZWQgaXQgcmV0dXJucyBudWxsLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgdGhhdCBoYXMgY2hhbmdlZCwgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFByb3BlcnR5TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIHByb3BlcnR5TmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwcm9wYWdhdGlvbklkIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBzZWUgI2dldFByb3BhZ2F0aW9uSWQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFByb3BhZ2F0aW9uSWQoT2JqZWN0IHByb3BhZ2F0aW9uSWQpIHsKKyAgICAgICAgdGhpcy5wcm9wYWdhdGlvbklkID0gcHJvcGFnYXRpb25JZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcm9wYWdhdGlvbklkIG9iamVjdC4gVGhpcyBpcyByZXNlcnZlZCBmb3IgZnV0dXJlIHVzZS4gQmVhbnMKKyAgICAgKiAxLjAgZGVtYW5kcyB0aGF0IGEgbGlzdGVuZXIgcmVjZWl2aW5nIHRoaXMgcHJvcGVydHkgYW5kIHRoZW4gc2VuZGluZyBpdHMKKyAgICAgKiBvd24gUHJvcGVydHlDaGFuZ2VFdmVudCBzZXRzIHRoZSByZWNlaXZlZCBwcm9wYWdhdGlvbklkIG9uIHRoZSBuZXcKKyAgICAgKiBQcm9wZXJ0eUNoYW5nZUV2ZW50J3MgcHJvcGFnYXRpb25JZCBmaWVsZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByb3BhZ2F0aW9uSWQgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGFnYXRpb25JZCgpIHsKKyAgICAgICAgcmV0dXJuIHByb3BhZ2F0aW9uSWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgb2xkIHZhbHVlIHRoYXQgdGhlIHByb3BlcnR5IGhhZC4gSWYgdGhlIG9sZCB2YWx1ZSBpcyB1bmtub3duCisgICAgICogdGhpcyBtZXRob2QgcmV0dXJucyBudWxsLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgb2xkIHByb3BlcnR5IHZhbHVlIG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRPbGRWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIG9sZFZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5ldyB2YWx1ZSB0aGF0IHRoZSBwcm9wZXJ0eSBub3cgaGFzLiBJZiB0aGUgbmV3IHZhbHVlIGlzCisgICAgICogdW5rbm93biB0aGlzIG1ldGhvZCByZXR1cm5zIG51bGwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBvbGQgcHJvcGVydHkgdmFsdWUgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldE5ld1ZhbHVlKCkgeworICAgICAgICByZXR1cm4gbmV3VmFsdWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvYmVhbnMvUHJvcGVydHlDaGFuZ2VMaXN0ZW5lci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvYmVhbnMvUHJvcGVydHlDaGFuZ2VMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYwOGEwMDYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9iZWFucy9Qcm9wZXJ0eUNoYW5nZUxpc3RlbmVyLmphdmEKQEAgLTAsMCArMSwzNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmJlYW5zOworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CisKKy8qKgorICogQSBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIGNhbiBzdWJzY3JpYmUgd2l0aCBhIGV2ZW50IHNvdXJjZS4gV2hlbmV2ZXIgdGhhdAorICogc291cmNlIHJhaXNlcyBhIFByb3BlcnR5Q2hhbmdlRXZlbnQgdGhpcyBsaXN0ZW5lciB3aWxsIGdldCBub3RpZmllZC4KKyAqLworcHVibGljIGludGVyZmFjZSBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIGV4dGVuZHMgRXZlbnRMaXN0ZW5lciB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc291cmNlIGJlYW4gY2FsbHMgdGhpcyBtZXRob2Qgd2hlbiBhbiBldmVudCBpcyByYWlzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXZlbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGxpbmsgUHJvcGVydHlDaGFuZ2VFdmVudH0gb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHRoZSBuYW1lCisgICAgICogICAgICAgICAgICBhbmQgdGhlIG9sZCBhbmQgbmV3IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSB0aGF0IGhhcyBjaGFuZ2VkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByb3BlcnR5Q2hhbmdlKFByb3BlcnR5Q2hhbmdlRXZlbnQgZXZlbnQpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvYmVhbnMvUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9iZWFucy9Qcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZGIyOWUyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvYmVhbnMvUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5LmphdmEKQEAgLTAsMCArMSw1OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmJlYW5zOworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXJQcm94eTsKKworLyoqCisgKiBUaGUgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBsaXN0ZW5lciBwcm94eSBqdXN0IGRlbGVnYXRlcyB0aGUgcmVjZWl2ZWQgZXZlbnRzCisgKiB0byBpdHMgbGlzdGVuZXIuCisgKi8KK3B1YmxpYyBjbGFzcyBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkgZXh0ZW5kcyBFdmVudExpc3RlbmVyUHJveHkgaW1wbGVtZW50cworICAgICAgICBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIHsKKworICAgIFN0cmluZyBwcm9wZXJ0eU5hbWU7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGxpc3RlbmVyIHByb3h5IHRoYXQgYXNzb2NpYXRlcyBhIGxpc3RlbmVyIHdpdGggYSBwcm9wZXJ0eQorICAgICAqIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgYXNzb2NpYXRlZCBwcm9wZXJ0eS4KKyAgICAgKiBAcGFyYW0gbGlzdGVuZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0ZW5lciB0byBkZWxlZ2F0ZSBpbmNvbWluZyBldmVudHMgdG8uCisgICAgICovCisgICAgcHVibGljIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eShTdHJpbmcgcHJvcGVydHlOYW1lLAorICAgICAgICAgICAgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lcikgeworICAgICAgICBzdXBlcihsaXN0ZW5lcik7CisgICAgICAgIHRoaXMucHJvcGVydHlOYW1lID0gcHJvcGVydHlOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGxpc3RlbmVyIHByb3h5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgYXNzb2NpYXRlZCBwcm9wZXJ0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFByb3BlcnR5TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIHByb3BlcnR5TmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBwcm9wZXJ0eUNoYW5nZShQcm9wZXJ0eUNoYW5nZUV2ZW50IGV2ZW50KSB7CisgICAgICAgIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIgPSAoUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcikgZ2V0TGlzdGVuZXIoKTsKKyAgICAgICAgbGlzdGVuZXIucHJvcGVydHlDaGFuZ2UoZXZlbnQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2JlYW5zL1Byb3BlcnR5Q2hhbmdlU3VwcG9ydC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvYmVhbnMvUHJvcGVydHlDaGFuZ2VTdXBwb3J0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDRmODE1NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2JlYW5zL1Byb3BlcnR5Q2hhbmdlU3VwcG9ydC5qYXZhCkBAIC0wLDAgKzEsMzk5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuYmVhbnM7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1GaWVsZDsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyOworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db3B5T25Xcml0ZUFycmF5TGlzdDsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuT2JqZWN0czsKKworLyoqCisgKiBNYW5hZ2VzIGEgbGlzdCBvZiBsaXN0ZW5lcnMgdG8gYmUgbm90aWZpZWQgd2hlbiBhIHByb3BlcnR5IGNoYW5nZXMuIExpc3RlbmVycworICogc3Vic2NyaWJlIHRvIGJlIG5vdGlmaWVkIG9mIGFsbCBwcm9wZXJ0eSBjaGFuZ2VzLCBvciBvZiBjaGFuZ2VzIHRvIGEgc2luZ2xlCisgKiBuYW1lZCBwcm9wZXJ0eS4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGlzIHRocmVhZCBzYWZlLiBObyBsb2NraW5nIGlzIG5lY2Vzc2FyeSB3aGVuIHN1YnNjcmliaW5nIG9yCisgKiB1bnN1YnNjcmliaW5nIGxpc3RlbmVycywgb3Igd2hlbiBwdWJsaXNoaW5nIGV2ZW50cy4gQ2FsbGVycyBzaG91bGQgYmUgY2FyZWZ1bAorICogd2hlbiBwdWJsaXNoaW5nIGV2ZW50cyBiZWNhdXNlIGxpc3RlbmVycyBtYXkgbm90IGJlIHRocmVhZCBzYWZlLgorICovCitwdWJsaWMgY2xhc3MgUHJvcGVydHlDaGFuZ2VTdXBwb3J0IGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDY0MDEyNTM3NzM3Nzk5NTE4MDNsOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFN0cmVhbUZpZWxkW10gc2VyaWFsUGVyc2lzdGVudEZpZWxkcyA9IHsKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJzb3VyY2UiLCBPYmplY3QuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImNoaWxkcmVuIiwgT2JqZWN0LmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJwcm9wZXJ0eUNoYW5nZVN1cHBvcnRTZXJpYWxpemVkRGF0YVZlcnNpb24iLCBpbnQuY2xhc3MpLAorICAgIH07CisKKyAgICBwcml2YXRlIHRyYW5zaWVudCBPYmplY3Qgc291cmNlQmVhbjsKKworICAgIC8qKgorICAgICAqIEFsbCBsaXN0ZW5lcnMsIGluY2x1ZGluZyBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkgbGlzdGVuZXJzIHRoYXQgYXJlCisgICAgICogb25seSBiZSBub3RpZmllZCB3aGVuIHRoZSBhc3NpZ25lZCBwcm9wZXJ0eSBpcyBjaGFuZ2VkLiBUaGlzIGxpc3QgbWF5IGJlCisgICAgICogbW9kaWZpZWQgY29uY3VycmVudGx5IQorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IExpc3Q8UHJvcGVydHlDaGFuZ2VMaXN0ZW5lcj4gbGlzdGVuZXJzCisgICAgICAgICAgICA9IG5ldyBDb3B5T25Xcml0ZUFycmF5TGlzdDxQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyPigpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSB0aGF0IHVzZXMgdGhlIHNvdXJjZSBiZWFuIGFzIHNvdXJjZSBmb3IgYW55IGV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZUJlYW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBiZWFuIHVzZWQgYXMgc291cmNlIGZvciBhbGwgZXZlbnRzLgorICAgICAqLworICAgIHB1YmxpYyBQcm9wZXJ0eUNoYW5nZVN1cHBvcnQoT2JqZWN0IHNvdXJjZUJlYW4pIHsKKyAgICAgICAgaWYgKHNvdXJjZUJlYW4gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zb3VyY2VCZWFuID0gc291cmNlQmVhbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaXJlcyBhIHtAbGluayBQcm9wZXJ0eUNoYW5nZUV2ZW50fSB3aXRoIHRoZSBnaXZlbiBuYW1lLCBvbGQgdmFsdWUgYW5kCisgICAgICogbmV3IHZhbHVlLiBBcyBzb3VyY2UgdGhlIGJlYW4gdXNlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaXMgdXNlZC4KKyAgICAgKiBJZiB0aGUgb2xkIHZhbHVlIGFuZCB0aGUgbmV3IHZhbHVlIGFyZSBub3QgbnVsbCBhbmQgZXF1YWwgdGhlIGV2ZW50IHdpbGwKKyAgICAgKiBub3QgYmUgZmlyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcHJvcGVydHkKKyAgICAgKiBAcGFyYW0gb2xkVmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBvbGQgdmFsdWUgb2YgdGhlIHByb3BlcnR5CisgICAgICogQHBhcmFtIG5ld1ZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZpcmVQcm9wZXJ0eUNoYW5nZShTdHJpbmcgcHJvcGVydHlOYW1lLCBPYmplY3Qgb2xkVmFsdWUsIE9iamVjdCBuZXdWYWx1ZSkgeworICAgICAgICBmaXJlUHJvcGVydHlDaGFuZ2UobmV3IFByb3BlcnR5Q2hhbmdlRXZlbnQoc291cmNlQmVhbiwgcHJvcGVydHlOYW1lLCBvbGRWYWx1ZSwgbmV3VmFsdWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaXJlcyBhbiB7QGxpbmsgSW5kZXhlZFByb3BlcnR5Q2hhbmdlRXZlbnR9IHdpdGggdGhlIGdpdmVuIG5hbWUsIG9sZAorICAgICAqIHZhbHVlLCBuZXcgdmFsdWUgYW5kIGluZGV4LiBBcyBzb3VyY2UgdGhlIGJlYW4gdXNlZCB0byBpbml0aWFsaXplIHRoaXMKKyAgICAgKiBpbnN0YW5jZSBpcyB1c2VkLiBJZiB0aGUgb2xkIHZhbHVlIGFuZCB0aGUgbmV3IHZhbHVlIGFyZSBub3QgbnVsbCBhbmQKKyAgICAgKiBlcXVhbCB0aGUgZXZlbnQgd2lsbCBub3QgYmUgZmlyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcHJvcGVydHkKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleAorICAgICAqIEBwYXJhbSBvbGRWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG9sZCB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgb2YgdGhlIHByb3BlcnR5CisgICAgICovCisgICAgcHVibGljIHZvaWQgZmlyZUluZGV4ZWRQcm9wZXJ0eUNoYW5nZShTdHJpbmcgcHJvcGVydHlOYW1lLCBpbnQgaW5kZXgsCisgICAgICAgICAgICBPYmplY3Qgb2xkVmFsdWUsIE9iamVjdCBuZXdWYWx1ZSkgeworICAgICAgICBmaXJlUHJvcGVydHlDaGFuZ2UobmV3IEluZGV4ZWRQcm9wZXJ0eUNoYW5nZUV2ZW50KHNvdXJjZUJlYW4sCisgICAgICAgICAgICAgICAgcHJvcGVydHlOYW1lLCBvbGRWYWx1ZSwgbmV3VmFsdWUsIGluZGV4KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVW5zdWJzY3JpYmVzIHtAY29kZSBsaXN0ZW5lcn0gZnJvbSBjaGFuZ2Ugbm90aWZpY2F0aW9ucyBmb3IgdGhlIHByb3BlcnR5CisgICAgICogbmFtZWQge0Bjb2RlIHByb3BlcnR5TmFtZX0uIElmIG11bHRpcGxlIHN1YnNjcmlwdGlvbnMgZXhpc3QgZm9yIHtAY29kZQorICAgICAqIGxpc3RlbmVyfSwgaXQgd2lsbCByZWNlaXZlIG9uZSBmZXdlciBub3RpZmljYXRpb25zIHdoZW4gdGhlIHByb3BlcnR5CisgICAgICogY2hhbmdlcy4gSWYgdGhlIHByb3BlcnR5IG5hbWUgb3IgbGlzdGVuZXIgaXMgbnVsbCBvciBub3Qgc3Vic2NyaWJlZCwgdGhpcworICAgICAqIG1ldGhvZCBzaWxlbnRseSBkb2VzIG5vdGhpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihTdHJpbmcgcHJvcGVydHlOYW1lLCBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyKSB7CisgICAgICAgIGZvciAoUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBwIDogbGlzdGVuZXJzKSB7CisgICAgICAgICAgICBpZiAoZXF1YWxzKHByb3BlcnR5TmFtZSwgbGlzdGVuZXIsIHApKSB7CisgICAgICAgICAgICAgICAgbGlzdGVuZXJzLnJlbW92ZShwKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdHdvIGNoYWlucyBvZiBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveGllcyBoYXZlIHRoZSBzYW1lCisgICAgICogbmFtZXMgaW4gdGhlIHNhbWUgb3JkZXIgYW5kIGJvdHRvbSBvdXQgaW4gdGhlIHNhbWUgZXZlbnQgbGlzdGVuZXIuIFRoaXMKKyAgICAgKiBtZXRob2QncyBzaWduYXR1cmUgaXMgYXN5bW1ldHJpYyB0byBhdm9pZCBhbGxvY2F0aW5nIGEgcHJveHk6IGlmCisgICAgICogbm9uLW51bGwsIHtAY29kZSBhTmFtZX0gcmVwcmVzZW50cyB0aGUgZmlyc3QgcHJvcGVydHkgbmFtZSBhbmQge0Bjb2RlIGF9CisgICAgICogaXMgaXRzIGxpc3RlbmVyLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBlcXVhbHMoU3RyaW5nIGFOYW1lLCBFdmVudExpc3RlbmVyIGEsIEV2ZW50TGlzdGVuZXIgYikgeworICAgICAgICAvKgorICAgICAgICAgKiBFYWNoIGl0ZXJhdGlvbiBvZiB0aGUgbG9vcCBhdHRlbXB0cyB0byBtYXRjaCBhIHBhaXIgb2YgcHJvcGVydHkgbmFtZXMKKyAgICAgICAgICogZnJvbSBhIGFuZCBiLiBJZiB0aGV5IGRvbid0IG1hdGNoLCB0aGUgY2hhaW5zIG11c3Qgbm90IGJlIGVxdWFsIQorICAgICAgICAgKi8KKyAgICAgICAgd2hpbGUgKGIgaW5zdGFuY2VvZiBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkpIHsKKyAgICAgICAgICAgIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSBiUHJveHkgPSAoUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5KSBiOyAvLyB1bndyYXAgYgorICAgICAgICAgICAgU3RyaW5nIGJOYW1lID0gYlByb3h5LmdldFByb3BlcnR5TmFtZSgpOworICAgICAgICAgICAgYiA9IGJQcm94eS5nZXRMaXN0ZW5lcigpOworICAgICAgICAgICAgaWYgKGFOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZiAoIShhIGluc3RhbmNlb2YgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5KSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSBhUHJveHkgPSAoUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5KSBhOyAvLyB1bndyYXAgYQorICAgICAgICAgICAgICAgIGFOYW1lID0gYVByb3h5LmdldFByb3BlcnR5TmFtZSgpOworICAgICAgICAgICAgICAgIGEgPSBhUHJveHkuZ2V0TGlzdGVuZXIoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghT2JqZWN0cy5lcXVhbChhTmFtZSwgYk5hbWUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBub3QgZXF1YWw7IGEgYW5kIGIgc3Vic2NyaWJlIHRvIGRpZmZlcmVudCBwcm9wZXJ0aWVzCisgICAgICAgICAgICB9CisgICAgICAgICAgICBhTmFtZSA9IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGFOYW1lID09IG51bGwgJiYgT2JqZWN0cy5lcXVhbChhLCBiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdWJzY3JpYmVzIHtAY29kZSBsaXN0ZW5lcn0gdG8gY2hhbmdlIG5vdGlmaWNhdGlvbnMgZm9yIHRoZSBwcm9wZXJ0eQorICAgICAqIG5hbWVkIHtAY29kZSBwcm9wZXJ0eU5hbWV9LiBJZiB0aGUgbGlzdGVuZXIgaXMgYWxyZWFkeSBzdWJzY3JpYmVkLCBpdAorICAgICAqIHdpbGwgcmVjZWl2ZSBhbiBhZGRpdGlvbmFsIG5vdGlmaWNhdGlvbiB3aGVuIHRoZSBwcm9wZXJ0eSBjaGFuZ2VzLiBJZiB0aGUKKyAgICAgKiBwcm9wZXJ0eSBuYW1lIG9yIGxpc3RlbmVyIGlzIG51bGwsIHRoaXMgbWV0aG9kIHNpbGVudGx5IGRvZXMgbm90aGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKFN0cmluZyBwcm9wZXJ0eU5hbWUsIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIpIHsKKyAgICAgICAgaWYgKGxpc3RlbmVyICE9IG51bGwgJiYgcHJvcGVydHlOYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxpc3RlbmVycy5hZGQobmV3IFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eShwcm9wZXJ0eU5hbWUsIGxpc3RlbmVyKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdWJzY3JpYmVycyB0byBiZSBub3RpZmllZCB3aGVuIHtAY29kZSBwcm9wZXJ0eU5hbWV9IGNoYW5nZXMuCisgICAgICogVGhpcyBpbmNsdWRlcyBib3RoIGxpc3RlbmVycyBzdWJzY3JpYmVkIHRvIGFsbCBwcm9wZXJ0eSBjaGFuZ2VzIGFuZAorICAgICAqIGxpc3RlbmVycyBzdWJzY3JpYmVkIHRvIHRoZSBuYW1lZCBwcm9wZXJ0eSBvbmx5LgorICAgICAqLworICAgIHB1YmxpYyBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyW10gZ2V0UHJvcGVydHlDaGFuZ2VMaXN0ZW5lcnMoU3RyaW5nIHByb3BlcnR5TmFtZSkgeworICAgICAgICBMaXN0PFByb3BlcnR5Q2hhbmdlTGlzdGVuZXI+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8UHJvcGVydHlDaGFuZ2VMaXN0ZW5lcj4oKTsKKyAgICAgICAgZm9yIChQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIHAgOiBsaXN0ZW5lcnMpIHsKKyAgICAgICAgICAgIGlmIChwIGluc3RhbmNlb2YgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5ICYmIE9iamVjdHMuZXF1YWwoCisgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5TmFtZSwgKChQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkpIHApLmdldFByb3BlcnR5TmFtZSgpKSkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQocCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdC50b0FycmF5KG5ldyBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyW3Jlc3VsdC5zaXplKCldKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaXJlcyBhIHByb3BlcnR5IGNoYW5nZSBvZiBhIGJvb2xlYW4gcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4gSWYgdGhlCisgICAgICogb2xkIHZhbHVlIGFuZCB0aGUgbmV3IHZhbHVlIGFyZSBub3QgbnVsbCBhbmQgZXF1YWwgdGhlIGV2ZW50IHdpbGwgbm90IGJlCisgICAgICogZmlyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcHJvcGVydHkgbmFtZQorICAgICAqIEBwYXJhbSBvbGRWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG9sZCB2YWx1ZQorICAgICAqIEBwYXJhbSBuZXdWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZpcmVQcm9wZXJ0eUNoYW5nZShTdHJpbmcgcHJvcGVydHlOYW1lLCBib29sZWFuIG9sZFZhbHVlLCBib29sZWFuIG5ld1ZhbHVlKSB7CisgICAgICAgIGZpcmVQcm9wZXJ0eUNoYW5nZShwcm9wZXJ0eU5hbWUsIEJvb2xlYW4udmFsdWVPZihvbGRWYWx1ZSksIEJvb2xlYW4udmFsdWVPZihuZXdWYWx1ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpcmVzIGEgcHJvcGVydHkgY2hhbmdlIG9mIGEgYm9vbGVhbiBwcm9wZXJ0eSB3aXRoIHRoZSBnaXZlbiBuYW1lLiBJZiB0aGUKKyAgICAgKiBvbGQgdmFsdWUgYW5kIHRoZSBuZXcgdmFsdWUgYXJlIG5vdCBudWxsIGFuZCBlcXVhbCB0aGUgZXZlbnQgd2lsbCBub3QgYmUKKyAgICAgKiBmaXJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm9wZXJ0eSBuYW1lCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNoYW5nZWQgcHJvcGVydHkKKyAgICAgKiBAcGFyYW0gb2xkVmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBvbGQgdmFsdWUKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBmaXJlSW5kZXhlZFByb3BlcnR5Q2hhbmdlKFN0cmluZyBwcm9wZXJ0eU5hbWUsIGludCBpbmRleCwKKyAgICAgICAgICAgIGJvb2xlYW4gb2xkVmFsdWUsIGJvb2xlYW4gbmV3VmFsdWUpIHsKKyAgICAgICAgaWYgKG9sZFZhbHVlICE9IG5ld1ZhbHVlKSB7CisgICAgICAgICAgICBmaXJlSW5kZXhlZFByb3BlcnR5Q2hhbmdlKHByb3BlcnR5TmFtZSwgaW5kZXgsCisgICAgICAgICAgICAgICAgICAgIEJvb2xlYW4udmFsdWVPZihvbGRWYWx1ZSksIEJvb2xlYW4udmFsdWVPZihuZXdWYWx1ZSkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlyZXMgYSBwcm9wZXJ0eSBjaGFuZ2Ugb2YgYW4gaW50ZWdlciBwcm9wZXJ0eSB3aXRoIHRoZSBnaXZlbiBuYW1lLiBJZgorICAgICAqIHRoZSBvbGQgdmFsdWUgYW5kIHRoZSBuZXcgdmFsdWUgYXJlIG5vdCBudWxsIGFuZCBlcXVhbCB0aGUgZXZlbnQgd2lsbCBub3QKKyAgICAgKiBiZSBmaXJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm9wZXJ0eSBuYW1lCisgICAgICogQHBhcmFtIG9sZFZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgb2xkIHZhbHVlCisgICAgICogQHBhcmFtIG5ld1ZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlCisgICAgICovCisgICAgcHVibGljIHZvaWQgZmlyZVByb3BlcnR5Q2hhbmdlKFN0cmluZyBwcm9wZXJ0eU5hbWUsIGludCBvbGRWYWx1ZSwgaW50IG5ld1ZhbHVlKSB7CisgICAgICAgIGZpcmVQcm9wZXJ0eUNoYW5nZShwcm9wZXJ0eU5hbWUsIEludGVnZXIudmFsdWVPZihvbGRWYWx1ZSksIEludGVnZXIudmFsdWVPZihuZXdWYWx1ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpcmVzIGEgcHJvcGVydHkgY2hhbmdlIG9mIGFuIGludGVnZXIgcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4gSWYKKyAgICAgKiB0aGUgb2xkIHZhbHVlIGFuZCB0aGUgbmV3IHZhbHVlIGFyZSBub3QgbnVsbCBhbmQgZXF1YWwgdGhlIGV2ZW50IHdpbGwgbm90CisgICAgICogYmUgZmlyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcHJvcGVydHkgbmFtZQorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjaGFuZ2VkIHByb3BlcnR5CisgICAgICogQHBhcmFtIG9sZFZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgb2xkIHZhbHVlCisgICAgICogQHBhcmFtIG5ld1ZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlCisgICAgICovCisgICAgcHVibGljIHZvaWQgZmlyZUluZGV4ZWRQcm9wZXJ0eUNoYW5nZShTdHJpbmcgcHJvcGVydHlOYW1lLCBpbnQgaW5kZXgsCisgICAgICAgICAgICBpbnQgb2xkVmFsdWUsIGludCBuZXdWYWx1ZSkgeworICAgICAgICBpZiAob2xkVmFsdWUgIT0gbmV3VmFsdWUpIHsKKyAgICAgICAgICAgIGZpcmVJbmRleGVkUHJvcGVydHlDaGFuZ2UocHJvcGVydHlOYW1lLCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgSW50ZWdlci52YWx1ZU9mKG9sZFZhbHVlKSwgSW50ZWdlci52YWx1ZU9mKG5ld1ZhbHVlKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlcmUgYXJlIGxpc3RlbmVycyByZWdpc3RlcmVkIHRvIHRoZSBwcm9wZXJ0eSB3aXRoIHRoZQorICAgICAqIGdpdmVuIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcHJvcGVydHkKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlcmUgYXJlIGxpc3RlbmVycyByZWdpc3RlcmVkIHRvIHRoYXQgcHJvcGVydHksIGZhbHNlCisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzTGlzdGVuZXJzKFN0cmluZyBwcm9wZXJ0eU5hbWUpIHsKKyAgICAgICAgZm9yIChQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIHAgOiBsaXN0ZW5lcnMpIHsKKyAgICAgICAgICAgIGlmICghKHAgaW5zdGFuY2VvZiBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkpIHx8IE9iamVjdHMuZXF1YWwoCisgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5TmFtZSwgKChQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkpIHApLmdldFByb3BlcnR5TmFtZSgpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVbnN1YnNjcmliZXMge0Bjb2RlIGxpc3RlbmVyfSBmcm9tIGNoYW5nZSBub3RpZmljYXRpb25zIGZvciBhbGwKKyAgICAgKiBwcm9wZXJ0aWVzLiBJZiB0aGUgbGlzdGVuZXIgaGFzIG11bHRpcGxlIHN1YnNjcmlwdGlvbnMsIGl0IHdpbGwgcmVjZWl2ZQorICAgICAqIG9uZSBmZXdlciBub3RpZmljYXRpb24gd2hlbiBwcm9wZXJ0aWVzIGNoYW5nZS4gSWYgdGhlIHByb3BlcnR5IG5hbWUgb3IKKyAgICAgKiBsaXN0ZW5lciBpcyBudWxsIG9yIG5vdCBzdWJzY3JpYmVkLCB0aGlzIG1ldGhvZCBzaWxlbnRseSBkb2VzIG5vdGhpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyKSB7CisgICAgICAgIGZvciAoUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBwIDogbGlzdGVuZXJzKSB7CisgICAgICAgICAgICBpZiAoZXF1YWxzKG51bGwsIGxpc3RlbmVyLCBwKSkgeworICAgICAgICAgICAgICAgIGxpc3RlbmVycy5yZW1vdmUocCk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU3Vic2NyaWJlcyB7QGNvZGUgbGlzdGVuZXJ9IHRvIGNoYW5nZSBub3RpZmljYXRpb25zIGZvciBhbGwgcHJvcGVydGllcy4KKyAgICAgKiBJZiB0aGUgbGlzdGVuZXIgaXMgYWxyZWFkeSBzdWJzY3JpYmVkLCBpdCB3aWxsIHJlY2VpdmUgYW4gYWRkaXRpb25hbAorICAgICAqIG5vdGlmaWNhdGlvbi4gSWYgdGhlIGxpc3RlbmVyIGlzIG51bGwsIHRoaXMgbWV0aG9kIHNpbGVudGx5IGRvZXMgbm90aGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIpIHsKKyAgICAgICAgaWYgKGxpc3RlbmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxpc3RlbmVycy5hZGQobGlzdGVuZXIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbGwgc3Vic2NyaWJlcnMuIFRoaXMgaW5jbHVkZXMgYm90aCBsaXN0ZW5lcnMgc3Vic2NyaWJlZCB0byBhbGwKKyAgICAgKiBwcm9wZXJ0eSBjaGFuZ2VzIGFuZCBsaXN0ZW5lcnMgc3Vic2NyaWJlZCB0byBhIHNpbmdsZSBwcm9wZXJ0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcltdIGdldFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJzKCkgeworICAgICAgICByZXR1cm4gbGlzdGVuZXJzLnRvQXJyYXkobmV3IFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJbMF0pOyAvLyAwIHRvIGF2b2lkIHN5bmNocm9uaXphdGlvbgorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvKgorICAgICAgICAgKiBUaGUgc2VyaWFsaXplZCBmb3JtIG9mIHRoaXMgY2xhc3MgdXNlcyBQcm9wZXJ0eUNoYW5nZVN1cHBvcnQgdG8gZ3JvdXAKKyAgICAgICAgICogUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcnMgc3Vic2NyaWJlZCB0byB0aGUgc2FtZSBwcm9wZXJ0eSBuYW1lLgorICAgICAgICAgKi8KKyAgICAgICAgTWFwPFN0cmluZywgUHJvcGVydHlDaGFuZ2VTdXBwb3J0PiBtYXAgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgUHJvcGVydHlDaGFuZ2VTdXBwb3J0PigpOworICAgICAgICBmb3IgKFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgcCA6IGxpc3RlbmVycykgeworICAgICAgICAgICAgaWYgKHAgaW5zdGFuY2VvZiBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkgJiYgIShwIGluc3RhbmNlb2YgU2VyaWFsaXphYmxlKSkgeworICAgICAgICAgICAgICAgIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSBwcm94eSA9IChQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkpIHA7CisgICAgICAgICAgICAgICAgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lciA9IChQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKSBwcm94eS5nZXRMaXN0ZW5lcigpOworICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lciBpbnN0YW5jZW9mIFNlcmlhbGl6YWJsZSkgeworICAgICAgICAgICAgICAgICAgICBQcm9wZXJ0eUNoYW5nZVN1cHBvcnQgbGlzdCA9IG1hcC5nZXQocHJveHkuZ2V0UHJvcGVydHlOYW1lKCkpOworICAgICAgICAgICAgICAgICAgICBpZiAobGlzdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ID0gbmV3IFByb3BlcnR5Q2hhbmdlU3VwcG9ydChzb3VyY2VCZWFuKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1hcC5wdXQocHJveHkuZ2V0UHJvcGVydHlOYW1lKCksIGxpc3QpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGxpc3QubGlzdGVuZXJzLmFkZChsaXN0ZW5lcik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtLlB1dEZpZWxkIHB1dEZpZWxkcyA9IG91dC5wdXRGaWVsZHMoKTsKKyAgICAgICAgcHV0RmllbGRzLnB1dCgic291cmNlIiwgc291cmNlQmVhbik7CisgICAgICAgIHB1dEZpZWxkcy5wdXQoImNoaWxkcmVuIiwgbWFwKTsKKyAgICAgICAgb3V0LndyaXRlRmllbGRzKCk7CisKKyAgICAgICAgZm9yIChQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIHAgOiBsaXN0ZW5lcnMpIHsKKyAgICAgICAgICAgIGlmIChwIGluc3RhbmNlb2YgU2VyaWFsaXphYmxlKSB7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlT2JqZWN0KHApOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIG91dC53cml0ZU9iamVjdChudWxsKTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0uR2V0RmllbGQgcmVhZEZpZWxkcyA9IGluLnJlYWRGaWVsZHMoKTsKKyAgICAgICAgc291cmNlQmVhbiA9IHJlYWRGaWVsZHMuZ2V0KCJzb3VyY2UiLCBudWxsKTsKKyAgICAgICAgbGlzdGVuZXJzID0gbmV3IENvcHlPbldyaXRlQXJyYXlMaXN0PFByb3BlcnR5Q2hhbmdlTGlzdGVuZXI+KCk7CisKKyAgICAgICAgTWFwPFN0cmluZywgUHJvcGVydHlDaGFuZ2VTdXBwb3J0PiBjaGlsZHJlbgorICAgICAgICAgICAgICAgID0gKE1hcDxTdHJpbmcsIFByb3BlcnR5Q2hhbmdlU3VwcG9ydD4pIHJlYWRGaWVsZHMuZ2V0KCJjaGlsZHJlbiIsIG51bGwpOworICAgICAgICBpZiAoY2hpbGRyZW4gIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBQcm9wZXJ0eUNoYW5nZVN1cHBvcnQ+IGVudHJ5IDogY2hpbGRyZW4uZW50cnlTZXQoKSkgeworICAgICAgICAgICAgICAgIGZvciAoUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBwIDogZW50cnkuZ2V0VmFsdWUoKS5saXN0ZW5lcnMpIHsKKyAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzLmFkZChuZXcgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5KGVudHJ5LmdldEtleSgpLCBwKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lcjsKKyAgICAgICAgd2hpbGUgKChsaXN0ZW5lciA9IChQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKSBpbi5yZWFkT2JqZWN0KCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxpc3RlbmVycy5hZGQobGlzdGVuZXIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHVibGlzaGVzIGEgcHJvcGVydHkgY2hhbmdlIGV2ZW50IHRvIGFsbCBsaXN0ZW5lcnMgb2YgdGhhdCBwcm9wZXJ0eS4gSWYKKyAgICAgKiB0aGUgZXZlbnQncyBvbGQgYW5kIG5ldyB2YWx1ZXMgYXJlIGVxdWFsIChidXQgbm9uLW51bGwpLCBubyBldmVudCB3aWxsIGJlCisgICAgICogcHVibGlzaGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZpcmVQcm9wZXJ0eUNoYW5nZShQcm9wZXJ0eUNoYW5nZUV2ZW50IGV2ZW50KSB7CisgICAgICAgIFN0cmluZyBwcm9wZXJ0eU5hbWUgPSBldmVudC5nZXRQcm9wZXJ0eU5hbWUoKTsKKyAgICAgICAgT2JqZWN0IG9sZFZhbHVlID0gZXZlbnQuZ2V0T2xkVmFsdWUoKTsKKyAgICAgICAgT2JqZWN0IG5ld1ZhbHVlID0gZXZlbnQuZ2V0TmV3VmFsdWUoKTsKKyAgICAgICAgaWYgKG5ld1ZhbHVlICE9IG51bGwgJiYgb2xkVmFsdWUgIT0gbnVsbCAmJiBuZXdWYWx1ZS5lcXVhbHMob2xkVmFsdWUpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBub3RpZnlFYWNoTGlzdGVuZXI6CisgICAgICAgIGZvciAoUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBwIDogbGlzdGVuZXJzKSB7CisgICAgICAgICAgICAvLyB1bndyYXAgbGlzdGVuZXIgcHJveGllcyB1bnRpbCB3ZSBnZXQgYSBtaXNtYXRjaGVkIG5hbWUgb3IgdGhlIHJlYWwgbGlzdGVuZXIKKyAgICAgICAgICAgIHdoaWxlIChwIGluc3RhbmNlb2YgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5KSB7CisgICAgICAgICAgICAgICAgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5IHByb3h5ID0gKFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSkgcDsKKyAgICAgICAgICAgICAgICBpZiAoIU9iamVjdHMuZXF1YWwocHJveHkuZ2V0UHJvcGVydHlOYW1lKCksIHByb3BlcnR5TmFtZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWUgbm90aWZ5RWFjaExpc3RlbmVyOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBwID0gKFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIpIHByb3h5LmdldExpc3RlbmVyKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwLnByb3BlcnR5Q2hhbmdlKGV2ZW50KTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0J1ZmZlcmVkSW5wdXRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0J1ZmZlcmVkSW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNDU1OTViCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vQnVmZmVyZWRJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNDA3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIFdyYXBzIGFuIGV4aXN0aW5nIHtAbGluayBJbnB1dFN0cmVhbX0gYW5kIDxlbT5idWZmZXJzPC9lbT4gdGhlIGlucHV0LgorICogRXhwZW5zaXZlIGludGVyYWN0aW9uIHdpdGggdGhlIHVuZGVybHlpbmcgaW5wdXQgc3RyZWFtIGlzIG1pbmltaXplZCwgc2luY2UKKyAqIG1vc3QgKHNtYWxsZXIpIHJlcXVlc3RzIGNhbiBiZSBzYXRpc2ZpZWQgYnkgYWNjZXNzaW5nIHRoZSBidWZmZXIgYWxvbmUuIFRoZQorICogZHJhd2JhY2sgaXMgdGhhdCBzb21lIGV4dHJhIHNwYWNlIGlzIHJlcXVpcmVkIHRvIGhvbGQgdGhlIGJ1ZmZlciBhbmQgdGhhdAorICogY29weWluZyB0YWtlcyBwbGFjZSB3aGVuIGZpbGxpbmcgdGhhdCBidWZmZXIsIGJ1dCB0aGlzIGlzIHVzdWFsbHkgb3V0d2VpZ2hlZAorICogYnkgdGhlIHBlcmZvcm1hbmNlIGJlbmVmaXRzLgorICoKKyAqIDxwLz5BIHR5cGljYWwgYXBwbGljYXRpb24gcGF0dGVybiBmb3IgdGhlIGNsYXNzIGxvb2tzIGxpa2UgdGhpczo8cC8+CisgKgorICogPHByZT4KKyAqIEJ1ZmZlcmVkSW5wdXRTdHJlYW0gYnVmID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbSgmcXVvdDtmaWxlLmphdmEmcXVvdDspKTsKKyAqIDwvcHJlPgorICoKKyAqIEBzZWUgQnVmZmVyZWRPdXRwdXRTdHJlYW0KKyAqLworcHVibGljIGNsYXNzIEJ1ZmZlcmVkSW5wdXRTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJJbnB1dFN0cmVhbSB7CisgICAgLyoqCisgICAgICogVGhlIGJ1ZmZlciBjb250YWluaW5nIHRoZSBjdXJyZW50IGJ5dGVzIHJlYWQgZnJvbSB0aGUgdGFyZ2V0IElucHV0U3RyZWFtLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2xhdGlsZSBieXRlW10gYnVmOworCisgICAgLyoqCisgICAgICogVGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyBpbnNpZGUgdGhlIGJ5dGUgYXJyYXkge0Bjb2RlIGJ1Zn0uCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBjb3VudDsKKworICAgIC8qKgorICAgICAqIFRoZSBjdXJyZW50IGxpbWl0LCB3aGljaCB3aGVuIHBhc3NlZCwgaW52YWxpZGF0ZXMgdGhlIGN1cnJlbnQgbWFyay4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IG1hcmtsaW1pdDsKKworICAgIC8qKgorICAgICAqIFRoZSBjdXJyZW50bHkgbWFya2VkIHBvc2l0aW9uLiAtMSBpbmRpY2F0ZXMgbm8gbWFyayBoYXMgYmVlbiBzZXQgb3IgdGhlCisgICAgICogbWFyayBoYXMgYmVlbiBpbnZhbGlkYXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IG1hcmtwb3MgPSAtMTsKKworICAgIC8qKgorICAgICAqIFRoZSBjdXJyZW50IHBvc2l0aW9uIHdpdGhpbiB0aGUgYnl0ZSBhcnJheSB7QGNvZGUgYnVmfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHBvczsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJ1ZmZlcmVkSW5wdXRTdHJlYW19LCBwcm92aWRpbmcge0Bjb2RlIGlufSB3aXRoIGEgYnVmZmVyCisgICAgICogb2YgODE5MiBieXRlcy4KKyAgICAgKgorICAgICAqIDxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gcGFzc2luZyBhIG51bGwgc291cmNlIGNyZWF0ZXMgYSBjbG9zZWQKKyAgICAgKiB7QGNvZGUgQnVmZmVyZWRJbnB1dFN0cmVhbX0uIEFsbCByZWFkIG9wZXJhdGlvbnMgb24gc3VjaCBhIHN0cmVhbSB3aWxsCisgICAgICogZmFpbCB3aXRoIGFuIElPRXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGluIHRoZSB7QGNvZGUgSW5wdXRTdHJlYW19IHRoZSBidWZmZXIgcmVhZHMgZnJvbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVmZmVyZWRJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbikgeworICAgICAgICB0aGlzKGluLCA4MTkyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBCdWZmZXJlZElucHV0U3RyZWFtfSwgcHJvdmlkaW5nIHtAY29kZSBpbn0gd2l0aCB7QGNvZGUgc2l6ZX0gYnl0ZXMKKyAgICAgKiBvZiBidWZmZXIuCisgICAgICoKKyAgICAgKiA8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IHBhc3NpbmcgYSBudWxsIHNvdXJjZSBjcmVhdGVzIGEgY2xvc2VkCisgICAgICoge0Bjb2RlIEJ1ZmZlcmVkSW5wdXRTdHJlYW19LiBBbGwgcmVhZCBvcGVyYXRpb25zIG9uIHN1Y2ggYSBzdHJlYW0gd2lsbAorICAgICAqIGZhaWwgd2l0aCBhbiBJT0V4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbiB0aGUge0Bjb2RlIElucHV0U3RyZWFtfSB0aGUgYnVmZmVyIHJlYWRzIGZyb20uCisgICAgICogQHBhcmFtIHNpemUgdGhlIHNpemUgb2YgYnVmZmVyIGluIGJ5dGVzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBzaXplIDw9IDB9LgorICAgICAqLworICAgIHB1YmxpYyBCdWZmZXJlZElucHV0U3RyZWFtKElucHV0U3RyZWFtIGluLCBpbnQgc2l6ZSkgeworICAgICAgICBzdXBlcihpbik7CisgICAgICAgIGlmIChzaXplIDw9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInNpemUgPD0gMCIpOworICAgICAgICB9CisgICAgICAgIGJ1ZiA9IG5ldyBieXRlW3NpemVdOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gZXN0aW1hdGVkIG51bWJlciBvZiBieXRlcyB0aGF0IGNhbiBiZSByZWFkIG9yIHNraXBwZWQgd2l0aG91dCBibG9ja2luZyBmb3IgbW9yZQorICAgICAqIGlucHV0LiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgYXZhaWxhYmxlIGluIHRoZSBidWZmZXIKKyAgICAgKiBwbHVzIHRob3NlIGF2YWlsYWJsZSBpbiB0aGUgc291cmNlIHN0cmVhbSwgYnV0IHNlZSB7QGxpbmsgSW5wdXRTdHJlYW0jYXZhaWxhYmxlfSBmb3IKKyAgICAgKiBpbXBvcnRhbnQgY2F2ZWF0cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVzdGltYXRlZCBudW1iZXIgb2YgYnl0ZXMgYXZhaWxhYmxlCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGlzIHN0cmVhbSBpcyBjbG9zZWQgb3IgYW4gZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gbG9jYWxJbiA9IGluOyAvLyAnaW4nIGNvdWxkIGJlIGludmFsaWRhdGVkIGJ5IGNsb3NlKCkKKyAgICAgICAgaWYgKGJ1ZiA9PSBudWxsIHx8IGxvY2FsSW4gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgc3RyZWFtQ2xvc2VkKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvdW50IC0gcG9zICsgbG9jYWxJbi5hdmFpbGFibGUoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIElPRXhjZXB0aW9uIHN0cmVhbUNsb3NlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQnVmZmVyZWRJbnB1dFN0cmVhbSBpcyBjbG9zZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhpcyBzdHJlYW0uIFRoZSBzb3VyY2Ugc3RyZWFtIGlzIGNsb3NlZCBhbmQgYW55IHJlc291cmNlcworICAgICAqIGFzc29jaWF0ZWQgd2l0aCBpdCBhcmUgcmVsZWFzZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNsb3NpbmcgdGhpcyBzdHJlYW0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBidWYgPSBudWxsOworICAgICAgICBJbnB1dFN0cmVhbSBsb2NhbEluID0gaW47CisgICAgICAgIGluID0gbnVsbDsKKyAgICAgICAgaWYgKGxvY2FsSW4gIT0gbnVsbCkgeworICAgICAgICAgICAgbG9jYWxJbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgZmlsbGJ1ZihJbnB1dFN0cmVhbSBsb2NhbEluLCBieXRlW10gbG9jYWxCdWYpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAobWFya3BvcyA9PSAtMSB8fCAocG9zIC0gbWFya3BvcyA+PSBtYXJrbGltaXQpKSB7CisgICAgICAgICAgICAvKiBNYXJrIHBvc2l0aW9uIG5vdCBzZXQgb3IgZXhjZWVkZWQgcmVhZGxpbWl0ICovCisgICAgICAgICAgICBpbnQgcmVzdWx0ID0gbG9jYWxJbi5yZWFkKGxvY2FsQnVmKTsKKyAgICAgICAgICAgIGlmIChyZXN1bHQgPiAwKSB7CisgICAgICAgICAgICAgICAgbWFya3BvcyA9IC0xOworICAgICAgICAgICAgICAgIHBvcyA9IDA7CisgICAgICAgICAgICAgICAgY291bnQgPSByZXN1bHQgPT0gLTEgPyAwIDogcmVzdWx0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgICAgICBpZiAobWFya3BvcyA9PSAwICYmIG1hcmtsaW1pdCA+IGxvY2FsQnVmLmxlbmd0aCkgeworICAgICAgICAgICAgLyogSW5jcmVhc2UgYnVmZmVyIHNpemUgdG8gYWNjb21tb2RhdGUgdGhlIHJlYWRsaW1pdCAqLworICAgICAgICAgICAgaW50IG5ld0xlbmd0aCA9IGxvY2FsQnVmLmxlbmd0aCAqIDI7CisgICAgICAgICAgICBpZiAobmV3TGVuZ3RoID4gbWFya2xpbWl0KSB7CisgICAgICAgICAgICAgICAgbmV3TGVuZ3RoID0gbWFya2xpbWl0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnl0ZVtdIG5ld2J1ZiA9IG5ldyBieXRlW25ld0xlbmd0aF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGxvY2FsQnVmLCAwLCBuZXdidWYsIDAsIGxvY2FsQnVmLmxlbmd0aCk7CisgICAgICAgICAgICAvLyBSZWFzc2lnbiBidWYsIHdoaWNoIHdpbGwgaW52YWxpZGF0ZSBhbnkgbG9jYWwgcmVmZXJlbmNlcworICAgICAgICAgICAgLy8gRklYTUU6IHdoYXQgaWYgYnVmIHdhcyBudWxsPworICAgICAgICAgICAgbG9jYWxCdWYgPSBidWYgPSBuZXdidWY7CisgICAgICAgIH0gZWxzZSBpZiAobWFya3BvcyA+IDApIHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobG9jYWxCdWYsIG1hcmtwb3MsIGxvY2FsQnVmLCAwLCBsb2NhbEJ1Zi5sZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgLSBtYXJrcG9zKTsKKyAgICAgICAgfQorICAgICAgICAvKiBTZXQgdGhlIG5ldyBwb3NpdGlvbiBhbmQgbWFyayBwb3NpdGlvbiAqLworICAgICAgICBwb3MgLT0gbWFya3BvczsKKyAgICAgICAgY291bnQgPSBtYXJrcG9zID0gMDsKKyAgICAgICAgaW50IGJ5dGVzcmVhZCA9IGxvY2FsSW4ucmVhZChsb2NhbEJ1ZiwgcG9zLCBsb2NhbEJ1Zi5sZW5ndGggLSBwb3MpOworICAgICAgICBjb3VudCA9IGJ5dGVzcmVhZCA8PSAwID8gcG9zIDogcG9zICsgYnl0ZXNyZWFkOworICAgICAgICByZXR1cm4gYnl0ZXNyZWFkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgYSBtYXJrIHBvc2l0aW9uIGluIHRoaXMgc3RyZWFtLiBUaGUgcGFyYW1ldGVyIHtAY29kZSByZWFkbGltaXR9CisgICAgICogaW5kaWNhdGVzIGhvdyBtYW55IGJ5dGVzIGNhbiBiZSByZWFkIGJlZm9yZSBhIG1hcmsgaXMgaW52YWxpZGF0ZWQuCisgICAgICogQ2FsbGluZyB7QGNvZGUgcmVzZXQoKX0gd2lsbCByZXBvc2l0aW9uIHRoZSBzdHJlYW0gYmFjayB0byB0aGUgbWFya2VkCisgICAgICogcG9zaXRpb24gaWYge0Bjb2RlIHJlYWRsaW1pdH0gaGFzIG5vdCBiZWVuIHN1cnBhc3NlZC4gVGhlIHVuZGVybHlpbmcKKyAgICAgKiBidWZmZXIgbWF5IGJlIGluY3JlYXNlZCBpbiBzaXplIHRvIGFsbG93IHtAY29kZSByZWFkbGltaXR9IG51bWJlciBvZgorICAgICAqIGJ5dGVzIHRvIGJlIHN1cHBvcnRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFkbGltaXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBjYW4gYmUgcmVhZCBiZWZvcmUgdGhlIG1hcmsgaXMKKyAgICAgKiAgICAgICAgICAgIGludmFsaWRhdGVkLgorICAgICAqIEBzZWUgI3Jlc2V0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgbWFyayhpbnQgcmVhZGxpbWl0KSB7CisgICAgICAgIG1hcmtsaW1pdCA9IHJlYWRsaW1pdDsKKyAgICAgICAgbWFya3BvcyA9IHBvczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB7QGNvZGUgQnVmZmVyZWRJbnB1dFN0cmVhbX0gc3VwcG9ydHMgdGhlIHtAY29kZSBtYXJrKCl9CisgICAgICogYW5kIHtAY29kZSByZXNldCgpfSBtZXRob2RzLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gZm9yIEJ1ZmZlcmVkSW5wdXRTdHJlYW1zLgorICAgICAqIEBzZWUgI21hcmsoaW50KQorICAgICAqIEBzZWUgI3Jlc2V0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXJrU3VwcG9ydGVkKCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHNpbmdsZSBieXRlIGZyb20gdGhpcyBzdHJlYW0gYW5kIHJldHVybnMgaXQgYXMgYW4gaW50ZWdlciBpbiB0aGUKKyAgICAgKiByYW5nZSBmcm9tIDAgdG8gMjU1LiBSZXR1cm5zIC0xIGlmIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSBzdHJpbmcgaGFzIGJlZW4KKyAgICAgKiByZWFjaGVkLiBJZiB0aGUgaW50ZXJuYWwgYnVmZmVyIGRvZXMgbm90IGNvbnRhaW4gYW55IGF2YWlsYWJsZSBieXRlcyB0aGVuCisgICAgICogaXQgaXMgZmlsbGVkIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0gYW5kIHRoZSBmaXJzdCBieXRlIGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYnl0ZSByZWFkIG9yIC0xIGlmIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSBzdHJlYW0gaGFzIGJlZW4KKyAgICAgKiAgICAgICAgIHJlYWNoZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgc3RyZWFtIGlzIGNsb3NlZCBvciBhbm90aGVyIElPRXhjZXB0aW9uIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVXNlIGxvY2FsIHJlZnMgc2luY2UgYnVmIGFuZCBpbiBtYXkgYmUgaW52YWxpZGF0ZWQgYnkgYW4KKyAgICAgICAgLy8gdW5zeW5jaHJvbml6ZWQgY2xvc2UoKQorICAgICAgICBieXRlW10gbG9jYWxCdWYgPSBidWY7CisgICAgICAgIElucHV0U3RyZWFtIGxvY2FsSW4gPSBpbjsKKyAgICAgICAgaWYgKGxvY2FsQnVmID09IG51bGwgfHwgbG9jYWxJbiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBzdHJlYW1DbG9zZWQoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qIEFyZSB0aGVyZSBidWZmZXJlZCBieXRlcyBhdmFpbGFibGU/ICovCisgICAgICAgIGlmIChwb3MgPj0gY291bnQgJiYgZmlsbGJ1Zihsb2NhbEluLCBsb2NhbEJ1ZikgPT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsgLyogbm8sIGZpbGwgYnVmZmVyICovCisgICAgICAgIH0KKyAgICAgICAgLy8gbG9jYWxCdWYgbWF5IGhhdmUgYmVlbiBpbnZhbGlkYXRlZCBieSBmaWxsYnVmCisgICAgICAgIGlmIChsb2NhbEJ1ZiAhPSBidWYpIHsKKyAgICAgICAgICAgIGxvY2FsQnVmID0gYnVmOworICAgICAgICAgICAgaWYgKGxvY2FsQnVmID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBzdHJlYW1DbG9zZWQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qIERpZCBmaWxsaW5nIHRoZSBidWZmZXIgZmFpbCB3aXRoIC0xIChFT0YpPyAqLworICAgICAgICBpZiAoY291bnQgLSBwb3MgPiAwKSB7CisgICAgICAgICAgICByZXR1cm4gbG9jYWxCdWZbcG9zKytdICYgMHhGRjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYXQgbW9zdCB7QGNvZGUgYnl0ZUNvdW50fSBieXRlcyBmcm9tIHRoaXMgc3RyZWFtIGFuZCBzdG9yZXMgdGhlbSBpbgorICAgICAqIGJ5dGUgYXJyYXkge0Bjb2RlIGJ1ZmZlcn0gc3RhcnRpbmcgYXQgb2Zmc2V0IHtAY29kZSBvZmZzZXR9LiBSZXR1cm5zIHRoZQorICAgICAqIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSByZWFkIG9yIC0xIGlmIG5vIGJ5dGVzIHdlcmUgcmVhZCBhbmQgdGhlIGVuZCBvZgorICAgICAqIHRoZSBzdHJlYW0gd2FzIGVuY291bnRlcmVkLiBJZiBhbGwgdGhlIGJ1ZmZlcmVkIGJ5dGVzIGhhdmUgYmVlbiB1c2VkLCBhCisgICAgICogbWFyayBoYXMgbm90IGJlZW4gc2V0IGFuZCB0aGUgcmVxdWVzdGVkIG51bWJlciBvZiBieXRlcyBpcyBsYXJnZXIgdGhhbgorICAgICAqIHRoZSByZWNlaXZlcidzIGJ1ZmZlciBzaXplLCB0aGlzIGltcGxlbWVudGF0aW9uIGJ5cGFzc2VzIHRoZSBidWZmZXIgYW5kCisgICAgICogc2ltcGx5IHBsYWNlcyB0aGUgcmVzdWx0cyBkaXJlY3RseSBpbnRvIHtAY29kZSBidWZmZXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYXJyYXkgaW4gd2hpY2ggdG8gc3RvcmUgdGhlIGJ5dGVzIHJlYWQuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHJlYWQgb3IgLTEgaWYgZW5kIG9mIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGJ5dGVDb3VudCA8IDB9LCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBieXRlQ291bnR9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgc2l6ZSBvZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBidWZmZXJ9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3RyZWFtIGlzIGFscmVhZHkgY2xvc2VkIG9yIGFub3RoZXIgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBvY2N1cnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgcmVhZChieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBVc2UgbG9jYWwgcmVmIHNpbmNlIGJ1ZiBtYXkgYmUgaW52YWxpZGF0ZWQgYnkgYW4gdW5zeW5jaHJvbml6ZWQKKyAgICAgICAgLy8gY2xvc2UoKQorICAgICAgICBieXRlW10gbG9jYWxCdWYgPSBidWY7CisgICAgICAgIGlmIChsb2NhbEJ1ZiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBzdHJlYW1DbG9zZWQoKTsKKyAgICAgICAgfQorICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXIubGVuZ3RoLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIGlmIChieXRlQ291bnQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgSW5wdXRTdHJlYW0gbG9jYWxJbiA9IGluOworICAgICAgICBpZiAobG9jYWxJbiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBzdHJlYW1DbG9zZWQoKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCByZXF1aXJlZDsKKyAgICAgICAgaWYgKHBvcyA8IGNvdW50KSB7CisgICAgICAgICAgICAvKiBUaGVyZSBhcmUgYnl0ZXMgYXZhaWxhYmxlIGluIHRoZSBidWZmZXIuICovCisgICAgICAgICAgICBpbnQgY29weWxlbmd0aCA9IGNvdW50IC0gcG9zID49IGJ5dGVDb3VudCA/IGJ5dGVDb3VudCA6IGNvdW50IC0gcG9zOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShsb2NhbEJ1ZiwgcG9zLCBidWZmZXIsIG9mZnNldCwgY29weWxlbmd0aCk7CisgICAgICAgICAgICBwb3MgKz0gY29weWxlbmd0aDsKKyAgICAgICAgICAgIGlmIChjb3B5bGVuZ3RoID09IGJ5dGVDb3VudCB8fCBsb2NhbEluLmF2YWlsYWJsZSgpID09IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY29weWxlbmd0aDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG9mZnNldCArPSBjb3B5bGVuZ3RoOworICAgICAgICAgICAgcmVxdWlyZWQgPSBieXRlQ291bnQgLSBjb3B5bGVuZ3RoOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmVxdWlyZWQgPSBieXRlQ291bnQ7CisgICAgICAgIH0KKworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgaW50IHJlYWQ7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogSWYgd2UncmUgbm90IG1hcmtlZCBhbmQgdGhlIHJlcXVpcmVkIHNpemUgaXMgZ3JlYXRlciB0aGFuIHRoZQorICAgICAgICAgICAgICogYnVmZmVyLCBzaW1wbHkgcmVhZCB0aGUgYnl0ZXMgZGlyZWN0bHkgYnlwYXNzaW5nIHRoZSBidWZmZXIuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGlmIChtYXJrcG9zID09IC0xICYmIHJlcXVpcmVkID49IGxvY2FsQnVmLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIHJlYWQgPSBsb2NhbEluLnJlYWQoYnVmZmVyLCBvZmZzZXQsIHJlcXVpcmVkKTsKKyAgICAgICAgICAgICAgICBpZiAocmVhZCA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVxdWlyZWQgPT0gYnl0ZUNvdW50ID8gLTEgOiBieXRlQ291bnQgLSByZXF1aXJlZDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmIChmaWxsYnVmKGxvY2FsSW4sIGxvY2FsQnVmKSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVxdWlyZWQgPT0gYnl0ZUNvdW50ID8gLTEgOiBieXRlQ291bnQgLSByZXF1aXJlZDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gbG9jYWxCdWYgbWF5IGhhdmUgYmVlbiBpbnZhbGlkYXRlZCBieSBmaWxsYnVmCisgICAgICAgICAgICAgICAgaWYgKGxvY2FsQnVmICE9IGJ1ZikgeworICAgICAgICAgICAgICAgICAgICBsb2NhbEJ1ZiA9IGJ1ZjsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGxvY2FsQnVmID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IHN0cmVhbUNsb3NlZCgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcmVhZCA9IGNvdW50IC0gcG9zID49IHJlcXVpcmVkID8gcmVxdWlyZWQgOiBjb3VudCAtIHBvczsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGxvY2FsQnVmLCBwb3MsIGJ1ZmZlciwgb2Zmc2V0LCByZWFkKTsKKyAgICAgICAgICAgICAgICBwb3MgKz0gcmVhZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlcXVpcmVkIC09IHJlYWQ7CisgICAgICAgICAgICBpZiAocmVxdWlyZWQgPT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBieXRlQ291bnQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobG9jYWxJbi5hdmFpbGFibGUoKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGJ5dGVDb3VudCAtIHJlcXVpcmVkOworICAgICAgICAgICAgfQorICAgICAgICAgICAgb2Zmc2V0ICs9IHJlYWQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhpcyBzdHJlYW0gdG8gdGhlIGxhc3QgbWFya2VkIGxvY2F0aW9uLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgc3RyZWFtIGlzIGNsb3NlZCwgbm8gbWFyayBoYXMgYmVlbiBzZXQgb3IgdGhlIG1hcmsgaXMKKyAgICAgKiAgICAgICAgICAgICBubyBsb25nZXIgdmFsaWQgYmVjYXVzZSBtb3JlIHRoYW4ge0Bjb2RlIHJlYWRsaW1pdH0gYnl0ZXMKKyAgICAgKiAgICAgICAgICAgICBoYXZlIGJlZW4gcmVhZCBzaW5jZSBzZXR0aW5nIHRoZSBtYXJrLgorICAgICAqIEBzZWUgI21hcmsoaW50KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZXNldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChidWYgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJTdHJlYW0gaXMgY2xvc2VkIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKC0xID09IG1hcmtwb3MpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiTWFyayBoYXMgYmVlbiBpbnZhbGlkYXRlZC4iKTsKKyAgICAgICAgfQorICAgICAgICBwb3MgPSBtYXJrcG9zOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNraXBzIHtAY29kZSBieXRlQ291bnR9IGJ5dGVzIGluIHRoaXMgc3RyZWFtLiBTdWJzZXF1ZW50IGNhbGxzIHRvCisgICAgICoge0Bjb2RlIHJlYWR9IHdpbGwgbm90IHJldHVybiB0aGVzZSBieXRlcyB1bmxlc3Mge0Bjb2RlIHJlc2V0fSBpcworICAgICAqIHVzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnl0ZUNvdW50CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHNraXAuIHtAY29kZSBza2lwfSBkb2VzIG5vdGhpbmcgYW5kCisgICAgICogICAgICAgICAgICByZXR1cm5zIDAgaWYge0Bjb2RlIGJ5dGVDb3VudH0gaXMgbGVzcyB0aGFuIHplcm8uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHNraXBwZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgc3RyZWFtIGlzIGNsb3NlZCBvciBhbm90aGVyIElPRXhjZXB0aW9uIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGxvbmcgc2tpcChsb25nIGJ5dGVDb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVXNlIGxvY2FsIHJlZnMgc2luY2UgYnVmIGFuZCBpbiBtYXkgYmUgaW52YWxpZGF0ZWQgYnkgYW4KKyAgICAgICAgLy8gdW5zeW5jaHJvbml6ZWQgY2xvc2UoKQorICAgICAgICBieXRlW10gbG9jYWxCdWYgPSBidWY7CisgICAgICAgIElucHV0U3RyZWFtIGxvY2FsSW4gPSBpbjsKKyAgICAgICAgaWYgKGxvY2FsQnVmID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IHN0cmVhbUNsb3NlZCgpOworICAgICAgICB9CisgICAgICAgIGlmIChieXRlQ291bnQgPCAxKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICBpZiAobG9jYWxJbiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBzdHJlYW1DbG9zZWQoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjb3VudCAtIHBvcyA+PSBieXRlQ291bnQpIHsKKyAgICAgICAgICAgIHBvcyArPSBieXRlQ291bnQ7CisgICAgICAgICAgICByZXR1cm4gYnl0ZUNvdW50OworICAgICAgICB9CisgICAgICAgIGxvbmcgcmVhZCA9IGNvdW50IC0gcG9zOworICAgICAgICBwb3MgPSBjb3VudDsKKworICAgICAgICBpZiAobWFya3BvcyAhPSAtMSkgeworICAgICAgICAgICAgaWYgKGJ5dGVDb3VudCA8PSBtYXJrbGltaXQpIHsKKyAgICAgICAgICAgICAgICBpZiAoZmlsbGJ1Zihsb2NhbEluLCBsb2NhbEJ1ZikgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChjb3VudCAtIHBvcyA+PSBieXRlQ291bnQgLSByZWFkKSB7CisgICAgICAgICAgICAgICAgICAgIHBvcyArPSBieXRlQ291bnQgLSByZWFkOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gYnl0ZUNvdW50OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBDb3VsZG4ndCBnZXQgYWxsIHRoZSBieXRlcywgc2tpcCB3aGF0IHdlIHJlYWQKKyAgICAgICAgICAgICAgICByZWFkICs9IChjb3VudCAtIHBvcyk7CisgICAgICAgICAgICAgICAgcG9zID0gY291bnQ7CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlYWQgKyBsb2NhbEluLnNraXAoYnl0ZUNvdW50IC0gcmVhZCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vQnVmZmVyZWRPdXRwdXRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0J1ZmZlcmVkT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmJiZjU5NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0J1ZmZlcmVkT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxODkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogV3JhcHMgYW4gZXhpc3Rpbmcge0BsaW5rIE91dHB1dFN0cmVhbX0gYW5kIDxlbT5idWZmZXJzPC9lbT4gdGhlIG91dHB1dC4KKyAqIEV4cGVuc2l2ZSBpbnRlcmFjdGlvbiB3aXRoIHRoZSB1bmRlcmx5aW5nIGlucHV0IHN0cmVhbSBpcyBtaW5pbWl6ZWQsIHNpbmNlCisgKiBtb3N0IChzbWFsbGVyKSByZXF1ZXN0cyBjYW4gYmUgc2F0aXNmaWVkIGJ5IGFjY2Vzc2luZyB0aGUgYnVmZmVyIGFsb25lLiBUaGUKKyAqIGRyYXdiYWNrIGlzIHRoYXQgc29tZSBleHRyYSBzcGFjZSBpcyByZXF1aXJlZCB0byBob2xkIHRoZSBidWZmZXIgYW5kIHRoYXQKKyAqIGNvcHlpbmcgdGFrZXMgcGxhY2Ugd2hlbiBmbHVzaGluZyB0aGF0IGJ1ZmZlciwgYnV0IHRoaXMgaXMgdXN1YWxseSBvdXR3ZWlnaGVkCisgKiBieSB0aGUgcGVyZm9ybWFuY2UgYmVuZWZpdHMuCisgKgorICogPHAvPkEgdHlwaWNhbCBhcHBsaWNhdGlvbiBwYXR0ZXJuIGZvciB0aGUgY2xhc3MgbG9va3MgbGlrZSB0aGlzOjxwLz4KKyAqCisgKiA8cHJlPgorICogQnVmZmVyZWRPdXRwdXRTdHJlYW0gYnVmID0gbmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKCZxdW90O2ZpbGUuamF2YSZxdW90OykpOworICogPC9wcmU+CisgKgorICogQHNlZSBCdWZmZXJlZElucHV0U3RyZWFtCisgKi8KK3B1YmxpYyBjbGFzcyBCdWZmZXJlZE91dHB1dFN0cmVhbSBleHRlbmRzIEZpbHRlck91dHB1dFN0cmVhbSB7CisgICAgLyoqCisgICAgICogVGhlIGJ1ZmZlciBjb250YWluaW5nIHRoZSBieXRlcyB0byBiZSB3cml0dGVuIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqLworICAgIHByb3RlY3RlZCBieXRlW10gYnVmOworCisgICAgLyoqCisgICAgICogVGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyBpbnNpZGUgdGhlIGJ5dGUgYXJyYXkge0Bjb2RlIGJ1Zn0uCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBjb3VudDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJ1ZmZlcmVkT3V0cHV0U3RyZWFtfSwgcHJvdmlkaW5nIHtAY29kZSBvdXR9IHdpdGggYSBidWZmZXIKKyAgICAgKiBvZiA4MTkyIGJ5dGVzLgorICAgICAqCisgICAgICogQHBhcmFtIG91dCB0aGUge0Bjb2RlIE91dHB1dFN0cmVhbX0gdGhlIGJ1ZmZlciB3cml0ZXMgdG8uCisgICAgICovCisgICAgcHVibGljIEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgdGhpcyhvdXQsIDgxOTIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJ1ZmZlcmVkT3V0cHV0U3RyZWFtfSwgcHJvdmlkaW5nIHtAY29kZSBvdXR9IHdpdGgge0Bjb2RlIHNpemV9IGJ5dGVzCisgICAgICogb2YgYnVmZmVyLgorICAgICAqCisgICAgICogQHBhcmFtIG91dCB0aGUge0Bjb2RlIE91dHB1dFN0cmVhbX0gdGhlIGJ1ZmZlciB3cml0ZXMgdG8uCisgICAgICogQHBhcmFtIHNpemUgdGhlIHNpemUgb2YgYnVmZmVyIGluIGJ5dGVzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBzaXplIDw9IDB9LgorICAgICAqLworICAgIHB1YmxpYyBCdWZmZXJlZE91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3V0LCBpbnQgc2l6ZSkgeworICAgICAgICBzdXBlcihvdXQpOworICAgICAgICBpZiAoc2l6ZSA8PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzaXplIDw9IDAiKTsKKyAgICAgICAgfQorICAgICAgICBidWYgPSBuZXcgYnl0ZVtzaXplXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIHRoaXMgc3RyZWFtIHRvIGVuc3VyZSBhbGwgcGVuZGluZyBkYXRhIGlzIHdyaXR0ZW4gb3V0IHRvIHRoZQorICAgICAqIHRhcmdldCBzdHJlYW0uIEluIGFkZGl0aW9uLCB0aGUgdGFyZ2V0IHN0cmVhbSBpcyBmbHVzaGVkLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhdHRlbXB0aW5nIHRvIGZsdXNoIHRoaXMgc3RyZWFtLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgIGZsdXNoSW50ZXJuYWwoKTsKKyAgICAgICAgb3V0LmZsdXNoKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrTm90Q2xvc2VkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGJ1ZiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkJ1ZmZlcmVkT3V0cHV0U3RyZWFtIGlzIGNsb3NlZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHtAY29kZSBjb3VudH0gYnl0ZXMgZnJvbSB0aGUgYnl0ZSBhcnJheSB7QGNvZGUgYnVmZmVyfSBzdGFydGluZyBhdAorICAgICAqIHtAY29kZSBvZmZzZXR9IHRvIHRoaXMgc3RyZWFtLiBJZiB0aGVyZSBpcyByb29tIGluIHRoZSBidWZmZXIgdG8gaG9sZCB0aGUKKyAgICAgKiBieXRlcywgdGhleSBhcmUgY29waWVkIGluLiBJZiBub3QsIHRoZSBidWZmZXJlZCBieXRlcyBwbHVzIHRoZSBieXRlcyBpbgorICAgICAqIHtAY29kZSBidWZmZXJ9IGFyZSB3cml0dGVuIHRvIHRoZSB0YXJnZXQgc3RyZWFtLCB0aGUgdGFyZ2V0IGlzIGZsdXNoZWQsCisgICAgICogYW5kIHRoZSBidWZmZXIgaXMgY2xlYXJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXIgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgcG9zaXRpb24gaW4ge0Bjb2RlIGJ1ZmZlcn0gZnJvbSB3aGVyZSB0byBnZXQgYnl0ZXMuCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyBmcm9tIHtAY29kZSBidWZmZXJ9IHRvIHdyaXRlIHRvIHRoaXMKKyAgICAgKiAgICAgICAgICAgIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGxlbmd0aCA8IDB9LCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBsZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgc2l6ZSBvZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBidWZmZXJ9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYXR0ZW1wdGluZyB0byB3cml0ZSB0byB0aGlzIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGJ1ZmZlcn0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgb2Zmc2V0IG9yIGNvdW50IGlzIG91dHNpZGUgb2YgYm91bmRzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCB3cml0ZShieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja05vdENsb3NlZCgpOworCisgICAgICAgIGlmIChidWZmZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJidWZmZXIgPT0gbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZVtdIGludGVybmFsQnVmZmVyID0gYnVmOworICAgICAgICBpZiAobGVuZ3RoID49IGludGVybmFsQnVmZmVyLmxlbmd0aCkgeworICAgICAgICAgICAgZmx1c2hJbnRlcm5hbCgpOworICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZmZlciwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBsZW5ndGgpOworCisgICAgICAgIC8vIGZsdXNoIHRoZSBpbnRlcm5hbCBidWZmZXIgZmlyc3QgaWYgd2UgaGF2ZSBub3QgZW5vdWdoIHNwYWNlIGxlZnQKKyAgICAgICAgaWYgKGxlbmd0aCA+IChpbnRlcm5hbEJ1ZmZlci5sZW5ndGggLSBjb3VudCkpIHsKKyAgICAgICAgICAgIGZsdXNoSW50ZXJuYWwoKTsKKyAgICAgICAgfQorCisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCBvZmZzZXQsIGludGVybmFsQnVmZmVyLCBjb3VudCwgbGVuZ3RoKTsKKyAgICAgICAgY291bnQgKz0gbGVuZ3RoOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoYnVmID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdXBlci5jbG9zZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgYnVmID0gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBvbmUgYnl0ZSB0byB0aGlzIHN0cmVhbS4gT25seSB0aGUgbG93IG9yZGVyIGJ5dGUgb2YgdGhlIGludGVnZXIKKyAgICAgKiB7QGNvZGUgb25lQnl0ZX0gaXMgd3JpdHRlbi4gSWYgdGhlcmUgaXMgcm9vbSBpbiB0aGUgYnVmZmVyLCB0aGUgYnl0ZSBpcworICAgICAqIGNvcGllZCBpbnRvIHRoZSBidWZmZXIgYW5kIHRoZSBjb3VudCBpbmNyZW1lbnRlZC4gT3RoZXJ3aXNlLCB0aGUgYnVmZmVyCisgICAgICogcGx1cyB7QGNvZGUgb25lQnl0ZX0gYXJlIHdyaXR0ZW4gdG8gdGhlIHRhcmdldCBzdHJlYW0sIHRoZSB0YXJnZXQgaXMKKyAgICAgKiBmbHVzaGVkLCBhbmQgdGhlIGJ1ZmZlciBpcyByZXNldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvbmVCeXRlCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSB0byBiZSB3cml0dGVuLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYXR0ZW1wdGluZyB0byB3cml0ZSB0byB0aGlzIHN0cmVhbS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgd3JpdGUoaW50IG9uZUJ5dGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgIGlmIChjb3VudCA9PSBidWYubGVuZ3RoKSB7CisgICAgICAgICAgICBvdXQud3JpdGUoYnVmLCAwLCBjb3VudCk7CisgICAgICAgICAgICBjb3VudCA9IDA7CisgICAgICAgIH0KKyAgICAgICAgYnVmW2NvdW50KytdID0gKGJ5dGUpIG9uZUJ5dGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmx1c2hlcyBvbmx5IGludGVybmFsIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZmx1c2hJbnRlcm5hbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjb3VudCA+IDApIHsKKyAgICAgICAgICAgIG91dC53cml0ZShidWYsIDAsIGNvdW50KTsKKyAgICAgICAgICAgIGNvdW50ID0gMDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0J1ZmZlcmVkUmVhZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9CdWZmZXJlZFJlYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAzZWNmOWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9CdWZmZXJlZFJlYWRlci5qYXZhCkBAIC0wLDAgKzEsNTE2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIFdyYXBzIGFuIGV4aXN0aW5nIHtAbGluayBSZWFkZXJ9IGFuZCA8ZW0+YnVmZmVyczwvZW0+IHRoZSBpbnB1dC4gRXhwZW5zaXZlCisgKiBpbnRlcmFjdGlvbiB3aXRoIHRoZSB1bmRlcmx5aW5nIHJlYWRlciBpcyBtaW5pbWl6ZWQsIHNpbmNlIG1vc3QgKHNtYWxsZXIpCisgKiByZXF1ZXN0cyBjYW4gYmUgc2F0aXNmaWVkIGJ5IGFjY2Vzc2luZyB0aGUgYnVmZmVyIGFsb25lLiBUaGUgZHJhd2JhY2sgaXMgdGhhdAorICogc29tZSBleHRyYSBzcGFjZSBpcyByZXF1aXJlZCB0byBob2xkIHRoZSBidWZmZXIgYW5kIHRoYXQgY29weWluZyB0YWtlcyBwbGFjZQorICogd2hlbiBmaWxsaW5nIHRoYXQgYnVmZmVyLCBidXQgdGhpcyBpcyB1c3VhbGx5IG91dHdlaWdoZWQgYnkgdGhlIHBlcmZvcm1hbmNlCisgKiBiZW5lZml0cy4KKyAqCisgKiA8cC8+QSB0eXBpY2FsIGFwcGxpY2F0aW9uIHBhdHRlcm4gZm9yIHRoZSBjbGFzcyBsb29rcyBsaWtlIHRoaXM6PHAvPgorICoKKyAqIDxwcmU+CisgKiBCdWZmZXJlZFJlYWRlciBidWYgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IEZpbGVSZWFkZXIoJnF1b3Q7ZmlsZS5qYXZhJnF1b3Q7KSk7CisgKiA8L3ByZT4KKyAqCisgKiBAc2VlIEJ1ZmZlcmVkV3JpdGVyCisgKiBAc2luY2UgMS4xCisgKi8KK3B1YmxpYyBjbGFzcyBCdWZmZXJlZFJlYWRlciBleHRlbmRzIFJlYWRlciB7CisKKyAgICBwcml2YXRlIFJlYWRlciBpbjsKKworICAgIC8qKgorICAgICAqIFRoZSBjaGFyYWN0ZXJzIHRoYXQgY2FuIGJlIHJlYWQgYW5kIHJlZmlsbGVkIGluIGJ1bGsuIFdlIG1haW50YWluIHRocmVlCisgICAgICogaW5kaWNlcyBpbnRvIHRoaXMgYnVmZmVyOjxwcmU+CisgICAgICogICAgIHsgWCBYIFggWCBYIFggWCBYIFggWCBYIFggLSAtIH0KKyAgICAgKiAgICAgICAgICAgXiAgICAgXiAgICAgICAgICAgICBeCisgICAgICogICAgICAgICAgIHwgICAgIHwgICAgICAgICAgICAgfAorICAgICAqICAgICAgICAgbWFyayAgIHBvcyAgICAgICAgICAgZW5kPC9wcmU+CisgICAgICogUG9zIHBvaW50cyB0byB0aGUgbmV4dCByZWFkYWJsZSBjaGFyYWN0ZXIuIEVuZCBpcyBvbmUgZ3JlYXRlciB0aGFuIHRoZQorICAgICAqIGxhc3QgcmVhZGFibGUgY2hhcmFjdGVyLiBXaGVuIHtAY29kZSBwb3MgPT0gZW5kfSwgdGhlIGJ1ZmZlciBpcyBlbXB0eSBhbmQKKyAgICAgKiBtdXN0IGJlIHtAbGluayAjZmlsbEJ1ZigpIGZpbGxlZH0gYmVmb3JlIGNoYXJhY3RlcnMgY2FuIGJlIHJlYWQuCisgICAgICoKKyAgICAgKiA8cD5NYXJrIGlzIHRoZSB2YWx1ZSBwb3Mgd2lsbCBiZSBzZXQgdG8gb24gY2FsbHMgdG8ge0BsaW5rICNyZXNldH0uIEl0cworICAgICAqIHZhbHVlIGlzIGluIHRoZSByYW5nZSB7QGNvZGUgWzAuLi5wb3NdfS4gSWYgdGhlIG1hcmsgaXMge0Bjb2RlIC0xfSwgdGhlCisgICAgICogYnVmZmVyIGNhbm5vdCBiZSByZXNldC4KKyAgICAgKgorICAgICAqIDxwPk1hcmtMaW1pdCBsaW1pdHMgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIG1hcmsgYW5kIHRoZSBwb3MuIFdoZW4gdGhpcworICAgICAqIGxpbWl0IGlzIGV4Y2VlZGVkLCB7QGxpbmsgI3Jlc2V0fSBpcyBwZXJtaXR0ZWQgKGJ1dCBub3QgcmVxdWlyZWQpIHRvCisgICAgICogdGhyb3cgYW4gZXhjZXB0aW9uLiBGb3Igc2hvcnRlciBkaXN0YW5jZXMsIHtAbGluayAjcmVzZXR9IHNoYWxsIG5vdCB0aHJvdworICAgICAqICh1bmxlc3MgdGhlIHJlYWRlciBpcyBjbG9zZWQpLgorICAgICAqLworICAgIHByaXZhdGUgY2hhcltdIGJ1ZjsKKworICAgIHByaXZhdGUgaW50IHBvczsKKworICAgIHByaXZhdGUgaW50IGVuZDsKKworICAgIHByaXZhdGUgaW50IG1hcmsgPSAtMTsKKworICAgIHByaXZhdGUgaW50IG1hcmtMaW1pdCA9IC0xOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQnVmZmVyZWRSZWFkZXJ9LCBwcm92aWRpbmcge0Bjb2RlIGlufSB3aXRoIGEgYnVmZmVyCisgICAgICogb2YgODE5MiBjaGFyYWN0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGluIHRoZSB7QGNvZGUgUmVhZGVyfSB0aGUgYnVmZmVyIHJlYWRzIGZyb20uCisgICAgICovCisgICAgcHVibGljIEJ1ZmZlcmVkUmVhZGVyKFJlYWRlciBpbikgeworICAgICAgICB0aGlzKGluLCA4MTkyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBCdWZmZXJlZFJlYWRlcn0sIHByb3ZpZGluZyB7QGNvZGUgaW59IHdpdGgge0Bjb2RlIHNpemV9IGNoYXJhY3RlcnMKKyAgICAgKiBvZiBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4gdGhlIHtAY29kZSBJbnB1dFN0cmVhbX0gdGhlIGJ1ZmZlciByZWFkcyBmcm9tLgorICAgICAqIEBwYXJhbSBzaXplIHRoZSBzaXplIG9mIGJ1ZmZlciBpbiBjaGFyYWN0ZXJzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBzaXplIDw9IDB9LgorICAgICAqLworICAgIHB1YmxpYyBCdWZmZXJlZFJlYWRlcihSZWFkZXIgaW4sIGludCBzaXplKSB7CisgICAgICAgIHN1cGVyKGluKTsKKyAgICAgICAgaWYgKHNpemUgPD0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigic2l6ZSA8PSAwIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5pbiA9IGluOworICAgICAgICBidWYgPSBuZXcgY2hhcltzaXplXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhpcyByZWFkZXIuIFRoaXMgaW1wbGVtZW50YXRpb24gY2xvc2VzIHRoZSBidWZmZXJlZCBzb3VyY2UgcmVhZGVyCisgICAgICogYW5kIHJlbGVhc2VzIHRoZSBidWZmZXIuIE5vdGhpbmcgaXMgZG9uZSBpZiB0aGlzIHJlYWRlciBoYXMgYWxyZWFkeSBiZWVuCisgICAgICogY2xvc2VkLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjbG9zaW5nIHRoaXMgcmVhZGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBpZiAoIWlzQ2xvc2VkKCkpIHsKKyAgICAgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICAgICAgICAgIGJ1ZiA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQb3B1bGF0ZXMgdGhlIGJ1ZmZlciB3aXRoIGRhdGEuIEl0IGlzIGFuIGVycm9yIHRvIGNhbGwgdGhpcyBtZXRob2Qgd2hlbgorICAgICAqIHRoZSBidWZmZXIgc3RpbGwgY29udGFpbnMgZGF0YTsgaWUuIGlmIHtAY29kZSBwb3MgPCBlbmR9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgaW50byB0aGUgYnVmZmVyLCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZQorICAgICAqICAgICAgc291cmNlIHN0cmVhbSBoYXMgYmVlbiByZWFjaGVkLgorICAgICAqLworICAgIHByaXZhdGUgaW50IGZpbGxCdWYoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBhc3NlcnQocG9zID09IGVuZCk7CisKKyAgICAgICAgaWYgKG1hcmsgPT0gLTEgfHwgKHBvcyAtIG1hcmsgPj0gbWFya0xpbWl0KSkgeworICAgICAgICAgICAgLyogbWFyayBpc24ndCBzZXQgb3IgaGFzIGV4Y2VlZGVkIGl0cyBsaW1pdC4gdXNlIHRoZSB3aG9sZSBidWZmZXIgKi8KKyAgICAgICAgICAgIGludCByZXN1bHQgPSBpbi5yZWFkKGJ1ZiwgMCwgYnVmLmxlbmd0aCk7CisgICAgICAgICAgICBpZiAocmVzdWx0ID4gMCkgeworICAgICAgICAgICAgICAgIG1hcmsgPSAtMTsKKyAgICAgICAgICAgICAgICBwb3MgPSAwOworICAgICAgICAgICAgICAgIGVuZCA9IHJlc3VsdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKworICAgICAgICBpZiAobWFyayA9PSAwICYmIG1hcmtMaW1pdCA+IGJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgIC8qIHRoZSBvbmx5IHdheSB0byBtYWtlIHJvb20gd2hlbiBtYXJrPTAgaXMgYnkgZ3Jvd2luZyB0aGUgYnVmZmVyICovCisgICAgICAgICAgICBpbnQgbmV3TGVuZ3RoID0gYnVmLmxlbmd0aCAqIDI7CisgICAgICAgICAgICBpZiAobmV3TGVuZ3RoID4gbWFya0xpbWl0KSB7CisgICAgICAgICAgICAgICAgbmV3TGVuZ3RoID0gbWFya0xpbWl0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2hhcltdIG5ld2J1ZiA9IG5ldyBjaGFyW25ld0xlbmd0aF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZiwgMCwgbmV3YnVmLCAwLCBidWYubGVuZ3RoKTsKKyAgICAgICAgICAgIGJ1ZiA9IG5ld2J1ZjsKKyAgICAgICAgfSBlbHNlIGlmIChtYXJrID4gMCkgeworICAgICAgICAgICAgLyogbWFrZSByb29tIGJ5IHNoaWZ0aW5nIHRoZSBidWZmZXJlZCBkYXRhIHRvIGxlZnQgbWFyayBwb3NpdGlvbnMgKi8KKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCBtYXJrLCBidWYsIDAsIGJ1Zi5sZW5ndGggLSBtYXJrKTsKKyAgICAgICAgICAgIHBvcyAtPSBtYXJrOworICAgICAgICAgICAgZW5kIC09IG1hcms7CisgICAgICAgICAgICBtYXJrID0gMDsKKyAgICAgICAgfQorCisgICAgICAgIC8qIFNldCB0aGUgbmV3IHBvc2l0aW9uIGFuZCBtYXJrIHBvc2l0aW9uICovCisgICAgICAgIGludCBjb3VudCA9IGluLnJlYWQoYnVmLCBwb3MsIGJ1Zi5sZW5ndGggLSBwb3MpOworICAgICAgICBpZiAoY291bnQgIT0gLTEpIHsKKyAgICAgICAgICAgIGVuZCArPSBjb3VudDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY291bnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoaXMgcmVhZGVyIGlzIGNsb3NlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgcmVhZGVyIGlzIGNsb3NlZCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpc0Nsb3NlZCgpIHsKKyAgICAgICAgcmV0dXJuIGJ1ZiA9PSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgYSBtYXJrIHBvc2l0aW9uIGluIHRoaXMgcmVhZGVyLiBUaGUgcGFyYW1ldGVyIHtAY29kZSBtYXJrTGltaXR9CisgICAgICogaW5kaWNhdGVzIGhvdyBtYW55IGNoYXJhY3RlcnMgY2FuIGJlIHJlYWQgYmVmb3JlIHRoZSBtYXJrIGlzIGludmFsaWRhdGVkLgorICAgICAqIENhbGxpbmcge0Bjb2RlIHJlc2V0KCl9IHdpbGwgcmVwb3NpdGlvbiB0aGUgcmVhZGVyIGJhY2sgdG8gdGhlIG1hcmtlZAorICAgICAqIHBvc2l0aW9uIGlmIHtAY29kZSBtYXJrTGltaXR9IGhhcyBub3QgYmVlbiBzdXJwYXNzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWFya0xpbWl0CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdGhhdCBjYW4gYmUgcmVhZCBiZWZvcmUgdGhlIG1hcmsgaXMKKyAgICAgKiAgICAgICAgICAgIGludmFsaWRhdGVkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG1hcmtMaW1pdCA8IDB9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgc2V0dGluZyBhIG1hcmsgaW4gdGhpcyByZWFkZXIuCisgICAgICogQHNlZSAjbWFya1N1cHBvcnRlZCgpCisgICAgICogQHNlZSAjcmVzZXQoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIG1hcmsoaW50IG1hcmtMaW1pdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG1hcmtMaW1pdCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgICAgICB0aGlzLm1hcmtMaW1pdCA9IG1hcmtMaW1pdDsKKyAgICAgICAgICAgIG1hcmsgPSBwb3M7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tOb3RDbG9zZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaXNDbG9zZWQoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJCdWZmZXJlZFJlYWRlciBpcyBjbG9zZWQiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgcmVhZGVyIHN1cHBvcnRzIHRoZSB7QGNvZGUgbWFyaygpfSBhbmQKKyAgICAgKiB7QGNvZGUgcmVzZXQoKX0gbWV0aG9kcy4gVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHtAY29kZSB0cnVlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGZvciB7QGNvZGUgQnVmZmVyZWRSZWFkZXJ9LgorICAgICAqIEBzZWUgI21hcmsoaW50KQorICAgICAqIEBzZWUgI3Jlc2V0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXJrU3VwcG9ydGVkKCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHNpbmdsZSBjaGFyYWN0ZXIgZnJvbSB0aGlzIHJlYWRlciBhbmQgcmV0dXJucyBpdCB3aXRoIHRoZSB0d28KKyAgICAgKiBoaWdoZXItb3JkZXIgYnl0ZXMgc2V0IHRvIDAuIElmIHBvc3NpYmxlLCBCdWZmZXJlZFJlYWRlciByZXR1cm5zIGEKKyAgICAgKiBjaGFyYWN0ZXIgZnJvbSB0aGUgYnVmZmVyLiBJZiB0aGVyZSBhcmUgbm8gY2hhcmFjdGVycyBhdmFpbGFibGUgaW4gdGhlCisgICAgICogYnVmZmVyLCBpdCBmaWxscyB0aGUgYnVmZmVyIGFuZCB0aGVuIHJldHVybnMgYSBjaGFyYWN0ZXIuIEl0IHJldHVybnMgLTEKKyAgICAgKiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBjaGFyYWN0ZXJzIGluIHRoZSBzb3VyY2UgcmVhZGVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2hhcmFjdGVyIHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgc291cmNlIHJlYWRlciBoYXMgYmVlbgorICAgICAqICAgICAgICAgcmVhY2hlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyByZWFkZXIgaXMgY2xvc2VkIG9yIHNvbWUgb3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgICAgICAvKiBBcmUgdGhlcmUgYnVmZmVyZWQgY2hhcmFjdGVycyBhdmFpbGFibGU/ICovCisgICAgICAgICAgICBpZiAocG9zIDwgZW5kIHx8IGZpbGxCdWYoKSAhPSAtMSkgeworICAgICAgICAgICAgICAgIHJldHVybiBidWZbcG9zKytdOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYXQgbW9zdCB7QGNvZGUgbGVuZ3RofSBjaGFyYWN0ZXJzIGZyb20gdGhpcyByZWFkZXIgYW5kIHN0b3JlcyB0aGVtCisgICAgICogYXQge0Bjb2RlIG9mZnNldH0gaW4gdGhlIGNoYXJhY3RlciBhcnJheSB7QGNvZGUgYnVmZmVyfS4gUmV0dXJucyB0aGUKKyAgICAgKiBudW1iZXIgb2YgY2hhcmFjdGVycyBhY3R1YWxseSByZWFkIG9yIC0xIGlmIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSByZWFkZXIKKyAgICAgKiBoYXMgYmVlbiByZWFjaGVkLiBJZiBhbGwgdGhlIGJ1ZmZlcmVkIGNoYXJhY3RlcnMgaGF2ZSBiZWVuIHVzZWQsIGEgbWFyaworICAgICAqIGhhcyBub3QgYmVlbiBzZXQgYW5kIHRoZSByZXF1ZXN0ZWQgbnVtYmVyIG9mIGNoYXJhY3RlcnMgaXMgbGFyZ2VyIHRoYW4KKyAgICAgKiB0aGlzIHJlYWRlcnMgYnVmZmVyIHNpemUsIEJ1ZmZlcmVkUmVhZGVyIGJ5cGFzc2VzIHRoZSBidWZmZXIgYW5kIHNpbXBseQorICAgICAqIHBsYWNlcyB0aGUgcmVzdWx0cyBkaXJlY3RseSBpbnRvIHtAY29kZSBidWZmZXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciBhcnJheSB0byBzdG9yZSB0aGUgY2hhcmFjdGVycyByZWFkLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIHBvc2l0aW9uIGluIHtAY29kZSBidWZmZXJ9IHRvIHN0b3JlIHRoZSBieXRlcyByZWFkCisgICAgICogICAgICAgICAgICBmcm9tIHRoaXMgcmVhZGVyLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQsIG11c3QgYmUKKyAgICAgKiAgICAgICAgICAgIG5vbi1uZWdhdGl2ZS4KKyAgICAgKiBAcmV0dXJuIG51bWJlciBvZiBjaGFyYWN0ZXJzIHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgc291cmNlIHJlYWRlcgorICAgICAqICAgICAgICAgaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGxlbmd0aCA8IDB9LCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBsZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgc2l6ZSBvZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBidWZmZXJ9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQgb3Igc29tZSBvdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChjaGFyW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXIubGVuZ3RoLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgICAgICBpbnQgb3V0c3RhbmRpbmcgPSBsZW5ndGg7CisgICAgICAgICAgICB3aGlsZSAob3V0c3RhbmRpbmcgPiAwKSB7CisKKyAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAqIElmIHRoZXJlIGFyZSBieXRlcyBpbiB0aGUgYnVmZmVyLCBncmFiIHRob3NlIGZpcnN0LgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIGludCBhdmFpbGFibGUgPSBlbmQgLSBwb3M7CisgICAgICAgICAgICAgICAgaWYgKGF2YWlsYWJsZSA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ID0gYXZhaWxhYmxlID49IG91dHN0YW5kaW5nID8gb3V0c3RhbmRpbmcgOiBhdmFpbGFibGU7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCBwb3MsIGJ1ZmZlciwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgICAgICAgICAgICAgIHBvcyArPSBjb3VudDsKKyAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IGNvdW50OworICAgICAgICAgICAgICAgICAgICBvdXRzdGFuZGluZyAtPSBjb3VudDsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAqIEJlZm9yZSBhdHRlbXB0aW5nIHRvIHJlYWQgZnJvbSB0aGUgdW5kZXJseWluZyBzdHJlYW0sIG1ha2UKKyAgICAgICAgICAgICAgICAgKiBzdXJlIHdlIHJlYWxseSwgcmVhbGx5IHdhbnQgdG8uIFdlIHdvbid0IGJvdGhlciBpZiB3ZSdyZQorICAgICAgICAgICAgICAgICAqIGRvbmUsIG9yIGlmIHdlJ3ZlIGFscmVhZHkgZ290IHNvbWUgYnl0ZXMgYW5kIHJlYWRpbmcgZnJvbSB0aGUKKyAgICAgICAgICAgICAgICAgKiB1bmRlcmx5aW5nIHN0cmVhbSB3b3VsZCBibG9jay4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBpZiAob3V0c3RhbmRpbmcgPT0gMCB8fCAob3V0c3RhbmRpbmcgPCBsZW5ndGggJiYgIWluLnJlYWR5KCkpKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIGFzc2VydChwb3MgPT0gZW5kKTsKKworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogSWYgd2UncmUgdW5tYXJrZWQgYW5kIHRoZSByZXF1ZXN0ZWQgc2l6ZSBpcyBncmVhdGVyIHRoYW4gb3VyCisgICAgICAgICAgICAgICAgICogYnVmZmVyLCByZWFkIHRoZSBieXRlcyBkaXJlY3RseSBpbnRvIHRoZSBjYWxsZXIncyBidWZmZXIuIFdlCisgICAgICAgICAgICAgICAgICogZG9uJ3QgcmVhZCBpbnRvIHNtYWxsZXIgYnVmZmVycyBiZWNhdXNlIHRoYXQgY291bGQgcmVzdWx0IGluCisgICAgICAgICAgICAgICAgICogYSBtYW55IHJlYWRzLgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIGlmICgobWFyayA9PSAtMSB8fCAocG9zIC0gbWFyayA+PSBtYXJrTGltaXQpKSAmJiBvdXRzdGFuZGluZyA+PSBidWYubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIGludCBjb3VudCA9IGluLnJlYWQoYnVmZmVyLCBvZmZzZXQsIG91dHN0YW5kaW5nKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50ID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgb3V0c3RhbmRpbmcgLT0gY291bnQ7CisgICAgICAgICAgICAgICAgICAgICAgICBtYXJrID0gLTE7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7IC8vIGFzc3VtZSB0aGUgc291cmNlIHN0cmVhbSBnYXZlIHVzIGFsbCB0aGF0IGl0IGNvdWxkCisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGZpbGxCdWYoKSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsgLy8gc291cmNlIGlzIGV4aGF1c3RlZAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IGNvdW50ID0gbGVuZ3RoIC0gb3V0c3RhbmRpbmc7CisgICAgICAgICAgICByZXR1cm4gKGNvdW50ID4gMCB8fCBjb3VudCA9PSBsZW5ndGgpID8gY291bnQgOiAtMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBlZWtzIGF0IHRoZSBuZXh0IGlucHV0IGNoYXJhY3RlciwgcmVmaWxsaW5nIHRoZSBidWZmZXIgaWYgbmVjZXNzYXJ5LiBJZgorICAgICAqIHRoaXMgY2hhcmFjdGVyIGlzIGEgbmV3bGluZSBjaGFyYWN0ZXIgKCJcbiIpLCBpdCBpcyBkaXNjYXJkZWQuCisgICAgICovCisgICAgZmluYWwgdm9pZCBjaG9tcE5ld2xpbmUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoKHBvcyAhPSBlbmQgfHwgZmlsbEJ1ZigpICE9IC0xKQorICAgICAgICAgICAgICAgICYmIGJ1Zltwb3NdID09ICdcbicpIHsKKyAgICAgICAgICAgIHBvcysrOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBsaW5lIG9mIHRleHQgYXZhaWxhYmxlIGZyb20gdGhpcyByZWFkZXIuIEEgbGluZSBpcworICAgICAqIHJlcHJlc2VudGVkIGJ5IHplcm8gb3IgbW9yZSBjaGFyYWN0ZXJzIGZvbGxvd2VkIGJ5IHtAY29kZSAnXG4nfSwKKyAgICAgKiB7QGNvZGUgJ1xyJ30sIHtAY29kZSAiXHJcbiJ9IG9yIHRoZSBlbmQgb2YgdGhlIHJlYWRlci4gVGhlIHN0cmluZyBkb2VzCisgICAgICogbm90IGluY2x1ZGUgdGhlIG5ld2xpbmUgc2VxdWVuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb250ZW50cyBvZiB0aGUgbGluZSBvciB7QGNvZGUgbnVsbH0gaWYgbm8gY2hhcmFjdGVycyB3ZXJlCisgICAgICogICAgICAgICByZWFkIGJlZm9yZSB0aGUgZW5kIG9mIHRoZSByZWFkZXIgaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyByZWFkZXIgaXMgY2xvc2VkIG9yIHNvbWUgb3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHJlYWRMaW5lKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBjaGVja05vdENsb3NlZCgpOworICAgICAgICAgICAgLyogaGFzIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBiZWVuIGV4aGF1c3RlZD8gKi8KKyAgICAgICAgICAgIGlmIChwb3MgPT0gZW5kICYmIGZpbGxCdWYoKSA9PSAtMSkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChpbnQgY2hhclBvcyA9IHBvczsgY2hhclBvcyA8IGVuZDsgY2hhclBvcysrKSB7CisgICAgICAgICAgICAgICAgY2hhciBjaCA9IGJ1ZltjaGFyUG9zXTsKKyAgICAgICAgICAgICAgICBpZiAoY2ggPiAnXHInKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJ1xuJykgeworICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcmVzID0gbmV3IFN0cmluZyhidWYsIHBvcywgY2hhclBvcyAtIHBvcyk7CisgICAgICAgICAgICAgICAgICAgIHBvcyA9IGNoYXJQb3MgKyAxOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gJ1xyJykgeworICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcmVzID0gbmV3IFN0cmluZyhidWYsIHBvcywgY2hhclBvcyAtIHBvcyk7CisgICAgICAgICAgICAgICAgICAgIHBvcyA9IGNoYXJQb3MgKyAxOworICAgICAgICAgICAgICAgICAgICBpZiAoKChwb3MgPCBlbmQpIHx8IChmaWxsQnVmKCkgIT0gLTEpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIChidWZbcG9zXSA9PSAnXG4nKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcG9zKys7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNoYXIgZW9sID0gJ1wwJzsKKyAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoODApOworICAgICAgICAgICAgLyogVHlwaWNhbCBMaW5lIExlbmd0aCAqLworCisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGJ1ZiwgcG9zLCBlbmQgLSBwb3MpOworICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICBwb3MgPSBlbmQ7CisKKyAgICAgICAgICAgICAgICAvKiBBcmUgdGhlcmUgYnVmZmVyZWQgY2hhcmFjdGVycyBhdmFpbGFibGU/ICovCisgICAgICAgICAgICAgICAgaWYgKGVvbCA9PSAnXG4nKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gYXR0ZW1wdCB0byBmaWxsIGJ1ZmZlcgorICAgICAgICAgICAgICAgIGlmIChmaWxsQnVmKCkgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gY2hhcmFjdGVycyBvciBudWxsLgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0Lmxlbmd0aCgpID4gMCB8fCBlb2wgIT0gJ1wwJworICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gcmVzdWx0LnRvU3RyaW5nKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZvciAoaW50IGNoYXJQb3MgPSBwb3M7IGNoYXJQb3MgPCBlbmQ7IGNoYXJQb3MrKykgeworICAgICAgICAgICAgICAgICAgICBjaGFyIGMgPSBidWZbY2hhclBvc107CisgICAgICAgICAgICAgICAgICAgIGlmIChlb2wgPT0gJ1wwJykgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChjID09ICdcbicgfHwgYyA9PSAnXHInKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVvbCA9IGM7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZW9sID09ICdccicgJiYgYyA9PSAnXG4nKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hhclBvcyA+IHBvcykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoYnVmLCBwb3MsIGNoYXJQb3MgLSBwb3MgLSAxKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHBvcyA9IGNoYXJQb3MgKyAxOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXJQb3MgPiBwb3MpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGJ1ZiwgcG9zLCBjaGFyUG9zIC0gcG9zIC0gMSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBwb3MgPSBjaGFyUG9zOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChlb2wgPT0gJ1wwJykgeworICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGJ1ZiwgcG9zLCBlbmQgLSBwb3MpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoYnVmLCBwb3MsIGVuZCAtIHBvcyAtIDEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyByZWFkZXIgaXMgcmVhZHkgdG8gYmUgcmVhZCB3aXRob3V0IGJsb2NraW5nLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyByZWFkZXIgd2lsbCBub3QgYmxvY2sgd2hlbiB7QGNvZGUgcmVhZH0gaXMKKyAgICAgKiAgICAgICAgIGNhbGxlZCwge0Bjb2RlIGZhbHNlfSBpZiB1bmtub3duIG9yIGJsb2NraW5nIHdpbGwgb2NjdXIuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgcmVhZGVyIGlzIGNsb3NlZCBvciBzb21lIG90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSAjcmVhZCgpCisgICAgICogQHNlZSAjcmVhZChjaGFyW10sIGludCwgaW50KQorICAgICAqIEBzZWUgI3JlYWRMaW5lKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiByZWFkeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgICAgIHJldHVybiAoKGVuZCAtIHBvcykgPiAwKSB8fCBpbi5yZWFkeSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzZXRzIHRoaXMgcmVhZGVyJ3MgcG9zaXRpb24gdG8gdGhlIGxhc3Qge0Bjb2RlIG1hcmsoKX0gbG9jYXRpb24uCisgICAgICogSW52b2NhdGlvbnMgb2Yge0Bjb2RlIHJlYWQoKX0gYW5kIHtAY29kZSBza2lwKCl9IHdpbGwgb2NjdXIgZnJvbSB0aGlzIG5ldworICAgICAqIGxvY2F0aW9uLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgcmVhZGVyIGlzIGNsb3NlZCBvciBubyBtYXJrIGhhcyBiZWVuIHNldC4KKyAgICAgKiBAc2VlICNtYXJrKGludCkKKyAgICAgKiBAc2VlICNtYXJrU3VwcG9ydGVkKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCByZXNldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgICAgIGlmIChtYXJrID09IC0xKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbnZhbGlkIG1hcmsiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBvcyA9IG1hcms7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTa2lwcyB7QGNvZGUgYnl0ZUNvdW50fSBieXRlcyBpbiB0aGlzIHN0cmVhbS4gU3Vic2VxdWVudCBjYWxscyB0bworICAgICAqIHtAY29kZSByZWFkfSB3aWxsIG5vdCByZXR1cm4gdGhlc2UgYnl0ZXMgdW5sZXNzIHtAY29kZSByZXNldH0gaXMKKyAgICAgKiB1c2VkLgorICAgICAqIFNraXBwaW5nIGNoYXJhY3RlcnMgbWF5IGludmFsaWRhdGUgYSBtYXJrIGlmIHtAY29kZSBtYXJrTGltaXR9CisgICAgICogaXMgc3VycGFzc2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGJ5dGVDb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gc2tpcC4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBhY3R1YWxseSBza2lwcGVkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGJ5dGVDb3VudCA8IDB9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQgb3Igc29tZSBvdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgI21hcmsoaW50KQorICAgICAqIEBzZWUgI21hcmtTdXBwb3J0ZWQoKQorICAgICAqIEBzZWUgI3Jlc2V0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBza2lwKGxvbmcgYnl0ZUNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoYnl0ZUNvdW50IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiYnl0ZUNvdW50IDwgMDogIiArIGJ5dGVDb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBjaGVja05vdENsb3NlZCgpOworICAgICAgICAgICAgaWYgKGJ5dGVDb3VudCA8IDEpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChlbmQgLSBwb3MgPj0gYnl0ZUNvdW50KSB7CisgICAgICAgICAgICAgICAgcG9zICs9IGJ5dGVDb3VudDsKKyAgICAgICAgICAgICAgICByZXR1cm4gYnl0ZUNvdW50OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBsb25nIHJlYWQgPSBlbmQgLSBwb3M7CisgICAgICAgICAgICBwb3MgPSBlbmQ7CisgICAgICAgICAgICB3aGlsZSAocmVhZCA8IGJ5dGVDb3VudCkgeworICAgICAgICAgICAgICAgIGlmIChmaWxsQnVmKCkgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChlbmQgLSBwb3MgPj0gYnl0ZUNvdW50IC0gcmVhZCkgeworICAgICAgICAgICAgICAgICAgICBwb3MgKz0gYnl0ZUNvdW50IC0gcmVhZDsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJ5dGVDb3VudDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gQ291bGRuJ3QgZ2V0IGFsbCB0aGUgY2hhcmFjdGVycywgc2tpcCB3aGF0IHdlIHJlYWQKKyAgICAgICAgICAgICAgICByZWFkICs9IChlbmQgLSBwb3MpOworICAgICAgICAgICAgICAgIHBvcyA9IGVuZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBieXRlQ291bnQ7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9CdWZmZXJlZFdyaXRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vQnVmZmVyZWRXcml0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNGNiZTdjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vQnVmZmVyZWRXcml0ZXIuamF2YQpAQCAtMCwwICsxLDMwNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuU25lYWt5VGhyb3c7CisKKy8qKgorICogV3JhcHMgYW4gZXhpc3Rpbmcge0BsaW5rIFdyaXRlcn0gYW5kIDxlbT5idWZmZXJzPC9lbT4gdGhlIG91dHB1dC4gRXhwZW5zaXZlCisgKiBpbnRlcmFjdGlvbiB3aXRoIHRoZSB1bmRlcmx5aW5nIHJlYWRlciBpcyBtaW5pbWl6ZWQsIHNpbmNlIG1vc3QgKHNtYWxsZXIpCisgKiByZXF1ZXN0cyBjYW4gYmUgc2F0aXNmaWVkIGJ5IGFjY2Vzc2luZyB0aGUgYnVmZmVyIGFsb25lLiBUaGUgZHJhd2JhY2sgaXMgdGhhdAorICogc29tZSBleHRyYSBzcGFjZSBpcyByZXF1aXJlZCB0byBob2xkIHRoZSBidWZmZXIgYW5kIHRoYXQgY29weWluZyB0YWtlcyBwbGFjZQorICogd2hlbiBmaWxsaW5nIHRoYXQgYnVmZmVyLCBidXQgdGhpcyBpcyB1c3VhbGx5IG91dHdlaWdoZWQgYnkgdGhlIHBlcmZvcm1hbmNlCisgKiBiZW5lZml0cy4KKyAqCisgKiA8cC8+QSB0eXBpY2FsIGFwcGxpY2F0aW9uIHBhdHRlcm4gZm9yIHRoZSBjbGFzcyBsb29rcyBsaWtlIHRoaXM6PHAvPgorICoKKyAqIDxwcmU+CisgKiBCdWZmZXJlZFdyaXRlciBidWYgPSBuZXcgQnVmZmVyZWRXcml0ZXIobmV3IEZpbGVXcml0ZXIoJnF1b3Q7ZmlsZS5qYXZhJnF1b3Q7KSk7CisgKiA8L3ByZT4KKyAqCisgKiBAc2VlIEJ1ZmZlcmVkUmVhZGVyCisgKi8KK3B1YmxpYyBjbGFzcyBCdWZmZXJlZFdyaXRlciBleHRlbmRzIFdyaXRlciB7CisKKyAgICBwcml2YXRlIFdyaXRlciBvdXQ7CisKKyAgICBwcml2YXRlIGNoYXJbXSBidWY7CisKKyAgICBwcml2YXRlIGludCBwb3M7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBCdWZmZXJlZFdyaXRlcn0sIHByb3ZpZGluZyB7QGNvZGUgb3V0fSB3aXRoIGEgYnVmZmVyCisgICAgICogb2YgODE5MiBieXRlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQgdGhlIHtAY29kZSBXcml0ZXJ9IHRoZSBidWZmZXIgd3JpdGVzIHRvLgorICAgICAqLworICAgIHB1YmxpYyBCdWZmZXJlZFdyaXRlcihXcml0ZXIgb3V0KSB7CisgICAgICAgIHRoaXMob3V0LCA4MTkyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBCdWZmZXJlZFdyaXRlcn0sIHByb3ZpZGluZyB7QGNvZGUgb3V0fSB3aXRoIHtAY29kZSBzaXplfSBieXRlcworICAgICAqIG9mIGJ1ZmZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQgdGhlIHtAY29kZSBPdXRwdXRTdHJlYW19IHRoZSBidWZmZXIgd3JpdGVzIHRvLgorICAgICAqIEBwYXJhbSBzaXplIHRoZSBzaXplIG9mIGJ1ZmZlciBpbiBieXRlcy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgc2l6ZSA8PSAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVmZmVyZWRXcml0ZXIoV3JpdGVyIG91dCwgaW50IHNpemUpIHsKKyAgICAgICAgc3VwZXIob3V0KTsKKyAgICAgICAgaWYgKHNpemUgPD0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigic2l6ZSA8PSAwIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5vdXQgPSBvdXQ7CisgICAgICAgIHRoaXMuYnVmID0gbmV3IGNoYXJbc2l6ZV07CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgd3JpdGVyLiBUaGUgY29udGVudHMgb2YgdGhlIGJ1ZmZlciBhcmUgZmx1c2hlZCwgdGhlIHRhcmdldAorICAgICAqIHdyaXRlciBpcyBjbG9zZWQsIGFuZCB0aGUgYnVmZmVyIGlzIHJlbGVhc2VkLiBPbmx5IHRoZSBmaXJzdCBpbnZvY2F0aW9uCisgICAgICogb2YgY2xvc2UgaGFzIGFueSBlZmZlY3QuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNsb3NpbmcgdGhpcyB3cml0ZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGlmIChpc0Nsb3NlZCgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBUaHJvd2FibGUgdGhyb3duID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZmx1c2hJbnRlcm5hbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvd24gPSBlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnVmID0gbnVsbDsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7CisgICAgICAgICAgICAgICAgaWYgKHRocm93biA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93biA9IGU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgb3V0ID0gbnVsbDsKKworICAgICAgICAgICAgaWYgKHRocm93biAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgU25lYWt5VGhyb3cuc25lYWt5VGhyb3codGhyb3duKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZsdXNoZXMgdGhpcyB3cml0ZXIuIFRoZSBjb250ZW50cyBvZiB0aGUgYnVmZmVyIGFyZSBjb21taXR0ZWQgdG8gdGhlCisgICAgICogdGFyZ2V0IHdyaXRlciBhbmQgaXQgaXMgdGhlbiBmbHVzaGVkLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBmbHVzaGluZyB0aGlzIHdyaXRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgICAgIGZsdXNoSW50ZXJuYWwoKTsKKyAgICAgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrTm90Q2xvc2VkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzQ2xvc2VkKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQnVmZmVyZWRXcml0ZXIgaXMgY2xvc2VkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIHRoZSBpbnRlcm5hbCBidWZmZXIuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGZsdXNoSW50ZXJuYWwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAocG9zID4gMCkgeworICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZiwgMCwgcG9zKTsKKyAgICAgICAgfQorICAgICAgICBwb3MgPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgd3JpdGVyIGlzIGNsb3NlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgd3JpdGVyIGlzIGNsb3NlZCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGlzQ2xvc2VkKCkgeworICAgICAgICByZXR1cm4gb3V0ID09IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgbmV3bGluZSB0byB0aGlzIHdyaXRlci4gT24gQW5kcm9pZCwgdGhpcyBpcyB7QGNvZGUgIlxuIn0uCisgICAgICogVGhlIHRhcmdldCB3cml0ZXIgbWF5IG9yIG1heSBub3QgYmUgZmx1c2hlZCB3aGVuIGEgbmV3bGluZSBpcyB3cml0dGVuLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhdHRlbXB0aW5nIHRvIHdyaXRlIHRvIHRoaXMgd3JpdGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG5ld0xpbmUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3cml0ZShTeXN0ZW0ubGluZVNlcGFyYXRvcigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMge0Bjb2RlIGNvdW50fSBjaGFyYWN0ZXJzIHN0YXJ0aW5nIGF0IHtAY29kZSBvZmZzZXR9IGluCisgICAgICoge0Bjb2RlIGNidWZ9IHRvIHRoaXMgd3JpdGVyLiBJZiB7QGNvZGUgY291bnR9IGlzIGdyZWF0ZXIgdGhhbiB0aGlzCisgICAgICogd3JpdGVyJ3MgYnVmZmVyLCB0aGVuIHRoZSBidWZmZXIgaXMgZmx1c2hlZCBhbmQgdGhlIGNoYXJhY3RlcnMgYXJlCisgICAgICogd3JpdHRlbiBkaXJlY3RseSB0byB0aGUgdGFyZ2V0IHdyaXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYnVmCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgY29udGFpbmluZyBjaGFyYWN0ZXJzIHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBwb3NpdGlvbiBpbiB7QGNvZGUgY2J1Zn0gZm9yIHJldHJpZXZpbmcgY2hhcmFjdGVycy4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwfSBvciB7QGNvZGUgY291bnQgPCAwfSwgb3IgaWYKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgb2Zmc2V0ICsgY291bnR9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgc2l6ZSBvZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBjYnVmfS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB3cml0ZXIgaXMgY2xvc2VkIG9yIGFub3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShjaGFyW10gY2J1ZiwgaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgICAgICBpZiAoY2J1ZiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJidWZmZXIgPT0gbnVsbCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoY2J1Zi5sZW5ndGgsIG9mZnNldCwgY291bnQpOworICAgICAgICAgICAgaWYgKHBvcyA9PSAwICYmIGNvdW50ID49IHRoaXMuYnVmLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIG91dC53cml0ZShjYnVmLCBvZmZzZXQsIGNvdW50KTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgYXZhaWxhYmxlID0gdGhpcy5idWYubGVuZ3RoIC0gcG9zOworICAgICAgICAgICAgaWYgKGNvdW50IDwgYXZhaWxhYmxlKSB7CisgICAgICAgICAgICAgICAgYXZhaWxhYmxlID0gY291bnQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYXZhaWxhYmxlID4gMCkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY2J1Ziwgb2Zmc2V0LCB0aGlzLmJ1ZiwgcG9zLCBhdmFpbGFibGUpOworICAgICAgICAgICAgICAgIHBvcyArPSBhdmFpbGFibGU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocG9zID09IHRoaXMuYnVmLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIG91dC53cml0ZSh0aGlzLmJ1ZiwgMCwgdGhpcy5idWYubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBwb3MgPSAwOworICAgICAgICAgICAgICAgIGlmIChjb3VudCA+IGF2YWlsYWJsZSkgeworICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gYXZhaWxhYmxlOworICAgICAgICAgICAgICAgICAgICBhdmFpbGFibGUgPSBjb3VudCAtIGF2YWlsYWJsZTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGF2YWlsYWJsZSA+PSB0aGlzLmJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dC53cml0ZShjYnVmLCBvZmZzZXQsIGF2YWlsYWJsZSk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNidWYsIG9mZnNldCwgdGhpcy5idWYsIHBvcywgYXZhaWxhYmxlKTsKKyAgICAgICAgICAgICAgICAgICAgcG9zICs9IGF2YWlsYWJsZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGNoYXJhY3RlciB7QGNvZGUgb25lQ2hhcn0gdG8gdGhpcyB3cml0ZXIuIElmIHRoZSBidWZmZXIKKyAgICAgKiBnZXRzIGZ1bGwgYnkgd3JpdGluZyB0aGlzIGNoYXJhY3RlciwgdGhpcyB3cml0ZXIgaXMgZmx1c2hlZC4gT25seSB0aGUKKyAgICAgKiBsb3dlciB0d28gYnl0ZXMgb2YgdGhlIGludGVnZXIge0Bjb2RlIG9uZUNoYXJ9IGFyZSB3cml0dGVuLgorICAgICAqCisgICAgICogQHBhcmFtIG9uZUNoYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgd3JpdGVyIGlzIGNsb3NlZCBvciBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IG9uZUNoYXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgICAgIGlmIChwb3MgPj0gYnVmLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIG91dC53cml0ZShidWYsIDAsIGJ1Zi5sZW5ndGgpOworICAgICAgICAgICAgICAgIHBvcyA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBidWZbcG9zKytdID0gKGNoYXIpIG9uZUNoYXI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMge0Bjb2RlIGNvdW50fSBjaGFyYWN0ZXJzIHN0YXJ0aW5nIGF0IHtAY29kZSBvZmZzZXR9IGluIHtAY29kZSBzdHJ9CisgICAgICogdG8gdGhpcyB3cml0ZXIuIElmIHtAY29kZSBjb3VudH0gaXMgZ3JlYXRlciB0aGFuIHRoaXMgd3JpdGVyJ3MgYnVmZmVyLAorICAgICAqIHRoZW4gdGhpcyB3cml0ZXIgaXMgZmx1c2hlZCBhbmQgdGhlIHJlbWFpbmluZyBjaGFyYWN0ZXJzIGFyZSB3cml0dGVuCisgICAgICogZGlyZWN0bHkgdG8gdGhlIHRhcmdldCB3cml0ZXIuIElmIGNvdW50IGlzIG5lZ2F0aXZlIG5vIGNoYXJhY3RlcnMgYXJlCisgICAgICogd3JpdHRlbiB0byB0aGUgYnVmZmVyLiBUaGlzIGRpZmZlcnMgZnJvbSB0aGUgYmVoYXZpb3Igb2YgdGhlIHN1cGVyY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgbm9uLW51bGwgU3RyaW5nIGNvbnRhaW5pbmcgY2hhcmFjdGVycyB0byB3cml0ZS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgcG9zaXRpb24gaW4ge0Bjb2RlIHN0cn0gZm9yIHJldHJpZXZpbmcgY2hhcmFjdGVycy4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgd3JpdGVyIGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkIG9yIGFub3RoZXIgSS9PIGVycm9yCisgICAgICogICAgICAgICAgICAgb2NjdXJzLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwfSBvciB7QGNvZGUgb2Zmc2V0ICsgY291bnR9IGlzIGdyZWF0ZXIKKyAgICAgKiAgICAgICAgICAgICB0aGFuIHRoZSBsZW5ndGggb2Yge0Bjb2RlIHN0cn0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoU3RyaW5nIHN0ciwgaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgICAgICBpZiAoY291bnQgPD0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCA+IHN0ci5sZW5ndGgoKSAtIGNvdW50KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oc3RyLCBvZmZzZXQsIGNvdW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChwb3MgPT0gMCAmJiBjb3VudCA+PSBidWYubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgY2hhcltdIGNoYXJzID0gbmV3IGNoYXJbY291bnRdOworICAgICAgICAgICAgICAgIHN0ci5nZXRDaGFycyhvZmZzZXQsIG9mZnNldCArIGNvdW50LCBjaGFycywgMCk7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlKGNoYXJzLCAwLCBjb3VudCk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IGF2YWlsYWJsZSA9IGJ1Zi5sZW5ndGggLSBwb3M7CisgICAgICAgICAgICBpZiAoY291bnQgPCBhdmFpbGFibGUpIHsKKyAgICAgICAgICAgICAgICBhdmFpbGFibGUgPSBjb3VudDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhdmFpbGFibGUgPiAwKSB7CisgICAgICAgICAgICAgICAgc3RyLmdldENoYXJzKG9mZnNldCwgb2Zmc2V0ICsgYXZhaWxhYmxlLCBidWYsIHBvcyk7CisgICAgICAgICAgICAgICAgcG9zICs9IGF2YWlsYWJsZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChwb3MgPT0gYnVmLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIG91dC53cml0ZSh0aGlzLmJ1ZiwgMCwgdGhpcy5idWYubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBwb3MgPSAwOworICAgICAgICAgICAgICAgIGlmIChjb3VudCA+IGF2YWlsYWJsZSkgeworICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gYXZhaWxhYmxlOworICAgICAgICAgICAgICAgICAgICBhdmFpbGFibGUgPSBjb3VudCAtIGF2YWlsYWJsZTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGF2YWlsYWJsZSA+PSBidWYubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjaGFyW10gY2hhcnMgPSBuZXcgY2hhcltjb3VudF07CisgICAgICAgICAgICAgICAgICAgICAgICBzdHIuZ2V0Q2hhcnMob2Zmc2V0LCBvZmZzZXQgKyBhdmFpbGFibGUsIGNoYXJzLCAwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dC53cml0ZShjaGFycywgMCwgYXZhaWxhYmxlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBzdHIuZ2V0Q2hhcnMob2Zmc2V0LCBvZmZzZXQgKyBhdmFpbGFibGUsIGJ1ZiwgcG9zKTsKKyAgICAgICAgICAgICAgICAgICAgcG9zICs9IGF2YWlsYWJsZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9CeXRlQXJyYXlJbnB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vQnl0ZUFycmF5SW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYThjNDUzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vQnl0ZUFycmF5SW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDIxMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBBIHNwZWNpYWxpemVkIHtAbGluayBJbnB1dFN0cmVhbSB9IGZvciByZWFkaW5nIHRoZSBjb250ZW50cyBvZiBhIGJ5dGUgYXJyYXkuCisgKgorICogQHNlZSBCeXRlQXJyYXlPdXRwdXRTdHJlYW0KKyAqLworcHVibGljIGNsYXNzIEJ5dGVBcnJheUlucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworICAgIC8qKgorICAgICAqIFRoZSB7QGNvZGUgYnl0ZX0gYXJyYXkgY29udGFpbmluZyB0aGUgYnl0ZXMgdG8gc3RyZWFtIG92ZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBidWY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY3VycmVudCBwb3NpdGlvbiB3aXRoaW4gdGhlIGJ5dGUgYXJyYXkuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBwb3M7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY3VycmVudCBtYXJrIHBvc2l0aW9uLiBJbml0aWFsbHkgc2V0IHRvIDAgb3IgdGhlIDxjb2RlPm9mZnNldDwvY29kZT4KKyAgICAgKiBwYXJhbWV0ZXIgd2l0aGluIHRoZSBjb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IG1hcms7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIGluaXRpYWxseSBhdmFpbGFibGUgaW4gdGhlIGJ5dGUgYXJyYXkKKyAgICAgKiB7QGNvZGUgYnVmfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGNvdW50OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQnl0ZUFycmF5SW5wdXRTdHJlYW19IG9uIHRoZSBieXRlIGFycmF5CisgICAgICoge0Bjb2RlIGJ1Zn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSBhcnJheSB0byBzdHJlYW0gb3Zlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZVtdIGJ1ZikgeworICAgICAgICB0aGlzLm1hcmsgPSAwOworICAgICAgICB0aGlzLmJ1ZiA9IGJ1ZjsKKyAgICAgICAgdGhpcy5jb3VudCA9IGJ1Zi5sZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQnl0ZUFycmF5SW5wdXRTdHJlYW19IG9uIHRoZSBieXRlIGFycmF5CisgICAgICoge0Bjb2RlIGJ1Zn0gd2l0aCB0aGUgaW5pdGlhbCBwb3NpdGlvbiBzZXQgdG8ge0Bjb2RlIG9mZnNldH0gYW5kIHRoZQorICAgICAqIG51bWJlciBvZiBieXRlcyBhdmFpbGFibGUgc2V0IHRvIHtAY29kZSBvZmZzZXR9ICsge0Bjb2RlIGxlbmd0aH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSBhcnJheSB0byBzdHJlYW0gb3Zlci4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBwb3NpdGlvbiBpbiB7QGNvZGUgYnVmfSB0byBzdGFydCBzdHJlYW1pbmcgZnJvbS4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIGF2YWlsYWJsZSBmb3Igc3RyZWFtaW5nLgorICAgICAqLworICAgIHB1YmxpYyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlW10gYnVmLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIHRoaXMuYnVmID0gYnVmOworICAgICAgICBwb3MgPSBvZmZzZXQ7CisgICAgICAgIG1hcmsgPSBvZmZzZXQ7CisgICAgICAgIGNvdW50ID0gb2Zmc2V0ICsgbGVuZ3RoID4gYnVmLmxlbmd0aCA/IGJ1Zi5sZW5ndGggOiBvZmZzZXQgKyBsZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHJlbWFpbmluZyBieXRlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIGNvdW50IC0gcG9zfQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGF2YWlsYWJsZSgpIHsKKyAgICAgICAgcmV0dXJuIGNvdW50IC0gcG9zOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGlzIHN0cmVhbSBhbmQgZnJlZXMgcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIGNsb3NpbmcgdGhpcyBzdHJlYW0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBEbyBub3RoaW5nIG9uIGNsb3NlLCB0aGlzIG1hdGNoZXMgSkRLIGJlaGF2aW9yLgorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgYSBtYXJrIHBvc2l0aW9uIGluIHRoaXMgQnl0ZUFycmF5SW5wdXRTdHJlYW0uIFRoZSBwYXJhbWV0ZXIKKyAgICAgKiB7QGNvZGUgcmVhZGxpbWl0fSBpcyBpZ25vcmVkLiBTZW5kaW5nIHtAY29kZSByZXNldCgpfSB3aWxsIHJlcG9zaXRpb24gdGhlCisgICAgICogc3RyZWFtIGJhY2sgdG8gdGhlIG1hcmtlZCBwb3NpdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFkbGltaXQKKyAgICAgKiAgICAgICAgICAgIGlnbm9yZWQuCisgICAgICogQHNlZSAjbWFya1N1cHBvcnRlZCgpCisgICAgICogQHNlZSAjcmVzZXQoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBtYXJrKGludCByZWFkbGltaXQpIHsKKyAgICAgICAgbWFyayA9IHBvczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIHN0cmVhbSBzdXBwb3J0cyB0aGUge0Bjb2RlIG1hcmsoKX0gYW5kCisgICAgICoge0Bjb2RlIHJlc2V0KCl9IG1ldGhvZHMuIFJldHVybnMge0Bjb2RlIHRydWV9IHNpbmNlIHRoaXMgY2xhc3Mgc3VwcG9ydHMKKyAgICAgKiB0aGVzZSBtZXRob2RzLgorICAgICAqCisgICAgICogQHJldHVybiBhbHdheXMge0Bjb2RlIHRydWV9LgorICAgICAqIEBzZWUgI21hcmsoaW50KQorICAgICAqIEBzZWUgI3Jlc2V0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXJrU3VwcG9ydGVkKCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHNpbmdsZSBieXRlIGZyb20gdGhlIHNvdXJjZSBieXRlIGFycmF5IGFuZCByZXR1cm5zIGl0IGFzIGFuCisgICAgICogaW50ZWdlciBpbiB0aGUgcmFuZ2UgZnJvbSAwIHRvIDI1NS4gUmV0dXJucyAtMSBpZiB0aGUgZW5kIG9mIHRoZSBzb3VyY2UKKyAgICAgKiBhcnJheSBoYXMgYmVlbiByZWFjaGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYnl0ZSByZWFkIG9yIC0xIGlmIHRoZSBlbmQgb2YgdGhpcyBzdHJlYW0gaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCByZWFkKCkgeworICAgICAgICByZXR1cm4gcG9zIDwgY291bnQgPyBidWZbcG9zKytdICYgMHhGRiA6IC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGF0IG1vc3Qge0Bjb2RlIGxlbn0gYnl0ZXMgZnJvbSB0aGlzIHN0cmVhbSBhbmQgc3RvcmVzCisgICAgICogdGhlbSBpbiBieXRlIGFycmF5IHtAY29kZSBifSBzdGFydGluZyBhdCB7QGNvZGUgb2Zmc2V0fS4gVGhpcworICAgICAqIGltcGxlbWVudGF0aW9uIHJlYWRzIGJ5dGVzIGZyb20gdGhlIHNvdXJjZSBieXRlIGFycmF5LgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYXJyYXkgaW4gd2hpY2ggdG8gc3RvcmUgdGhlIGJ5dGVzIHJlYWQuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgcG9zaXRpb24gaW4ge0Bjb2RlIGJ9IHRvIHN0b3JlIHRoZSBieXRlcyByZWFkIGZyb20KKyAgICAgKiAgICAgICAgICAgIHRoaXMgc3RyZWFtLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0byBzdG9yZSBpbiB7QGNvZGUgYn0uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHJlYWQgb3IgLTEgaWYgbm8gYnl0ZXMgd2VyZSByZWFkIGFuZAorICAgICAqICAgICAgICAgdGhlIGVuZCBvZiB0aGUgc3RyZWFtIHdhcyBlbmNvdW50ZXJlZC4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGxlbmd0aCA8IDB9LCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBsZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgc2l6ZSBvZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBifS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGJ9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCByZWFkKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBsZW5ndGgpOworCisgICAgICAgIC8vIEFyZSB0aGVyZSBhbnkgYnl0ZXMgYXZhaWxhYmxlPworICAgICAgICBpZiAodGhpcy5wb3MgPj0gdGhpcy5jb3VudCkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGlmIChsZW5ndGggPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBpbnQgY29weWxlbiA9IHRoaXMuY291bnQgLSBwb3MgPCBsZW5ndGggPyB0aGlzLmNvdW50IC0gcG9zIDogbGVuZ3RoOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRoaXMuYnVmLCBwb3MsIGJ1ZmZlciwgb2Zmc2V0LCBjb3B5bGVuKTsKKyAgICAgICAgcG9zICs9IGNvcHlsZW47CisgICAgICAgIHJldHVybiBjb3B5bGVuOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0cyB0aGlzIHN0cmVhbSB0byB0aGUgbGFzdCBtYXJrZWQgbG9jYXRpb24uIFRoaXMgaW1wbGVtZW50YXRpb24KKyAgICAgKiByZXNldHMgdGhlIHBvc2l0aW9uIHRvIGVpdGhlciB0aGUgbWFya2VkIHBvc2l0aW9uLCB0aGUgc3RhcnQgcG9zaXRpb24KKyAgICAgKiBzdXBwbGllZCBpbiB0aGUgY29uc3RydWN0b3Igb3IgMCBpZiBuZWl0aGVyIGhhcyBiZWVuIHByb3ZpZGVkLgorICAgICAqCisgICAgICogQHNlZSAjbWFyayhpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHJlc2V0KCkgeworICAgICAgICBwb3MgPSBtYXJrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNraXBzIHtAY29kZSBieXRlQ291bnR9IGJ5dGVzIGluIHRoaXMgSW5wdXRTdHJlYW0uIFN1YnNlcXVlbnQKKyAgICAgKiBjYWxscyB0byB7QGNvZGUgcmVhZH0gd2lsbCBub3QgcmV0dXJuIHRoZXNlIGJ5dGVzIHVubGVzcyB7QGNvZGUgcmVzZXR9IGlzCisgICAgICogdXNlZC4gVGhpcyBpbXBsZW1lbnRhdGlvbiBza2lwcyB7QGNvZGUgYnl0ZUNvdW50fSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhlCisgICAgICogdGFyZ2V0IHN0cmVhbS4gSXQgZG9lcyBub3RoaW5nIGFuZCByZXR1cm5zIDAgaWYge0Bjb2RlIGJ5dGVDb3VudH0gaXMgbmVnYXRpdmUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgc2tpcHBlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGxvbmcgc2tpcChsb25nIGJ5dGVDb3VudCkgeworICAgICAgICBpZiAoYnl0ZUNvdW50IDw9IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGludCB0ZW1wID0gcG9zOworICAgICAgICBwb3MgPSB0aGlzLmNvdW50IC0gcG9zIDwgYnl0ZUNvdW50ID8gdGhpcy5jb3VudCA6IChpbnQpIChwb3MgKyBieXRlQ291bnQpOworICAgICAgICByZXR1cm4gcG9zIC0gdGVtcDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9CeXRlQXJyYXlPdXRwdXRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0J5dGVBcnJheU91dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNhYjJjMjAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9CeXRlQXJyYXlPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDIzMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBBIHNwZWNpYWxpemVkIHtAbGluayBPdXRwdXRTdHJlYW19IGZvciBjbGFzcyBmb3Igd3JpdGluZyBjb250ZW50IHRvIGFuCisgKiAoaW50ZXJuYWwpIGJ5dGUgYXJyYXkuIEFzIGJ5dGVzIGFyZSB3cml0dGVuIHRvIHRoaXMgc3RyZWFtLCB0aGUgYnl0ZSBhcnJheQorICogbWF5IGJlIGV4cGFuZGVkIHRvIGhvbGQgbW9yZSBieXRlcy4gV2hlbiB0aGUgd3JpdGluZyBpcyBjb25zaWRlcmVkIHRvIGJlCisgKiBmaW5pc2hlZCwgYSBjb3B5IG9mIHRoZSBieXRlIGFycmF5IGNhbiBiZSByZXF1ZXN0ZWQgZnJvbSB0aGUgY2xhc3MuCisgKgorICogQHNlZSBCeXRlQXJyYXlJbnB1dFN0cmVhbQorICovCitwdWJsaWMgY2xhc3MgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKyAgICAvKioKKyAgICAgKiBUaGUgYnl0ZSBhcnJheSBjb250YWluaW5nIHRoZSBieXRlcyB3cml0dGVuLgorICAgICAqLworICAgIHByb3RlY3RlZCBieXRlW10gYnVmOworCisgICAgLyoqCisgICAgICogVGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgY291bnQ7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSB3aXRoIGEgZGVmYXVsdCBzaXplIG9mIDMyIGJ5dGVzLgorICAgICAqIElmIG1vcmUgdGhhbiAzMiBieXRlcyBhcmUgd3JpdHRlbiB0byB0aGlzIGluc3RhbmNlLCB0aGUgdW5kZXJseWluZyBieXRlCisgICAgICogYXJyYXkgd2lsbCBleHBhbmQuCisgICAgICovCisgICAgcHVibGljIEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpIHsKKyAgICAgICAgYnVmID0gbmV3IGJ5dGVbMzJdOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJ5dGVBcnJheU91dHB1dFN0cmVhbX0gd2l0aCBhIGRlZmF1bHQgc2l6ZSBvZgorICAgICAqIHtAY29kZSBzaXplfSBieXRlcy4gSWYgbW9yZSB0aGFuIHtAY29kZSBzaXplfSBieXRlcyBhcmUgd3JpdHRlbiB0byB0aGlzCisgICAgICogaW5zdGFuY2UsIHRoZSB1bmRlcmx5aW5nIGJ5dGUgYXJyYXkgd2lsbCBleHBhbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgaW5pdGlhbCBzaXplIGZvciB0aGUgdW5kZXJseWluZyBieXRlIGFycmF5LCBtdXN0IGJlCisgICAgICogICAgICAgICAgICBub24tbmVnYXRpdmUuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc2l6ZX0gPCAwLgorICAgICAqLworICAgIHB1YmxpYyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oaW50IHNpemUpIHsKKyAgICAgICAgaWYgKHNpemUgPj0gMCkgeworICAgICAgICAgICAgYnVmID0gbmV3IGJ5dGVbc2l6ZV07CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzaXplIDwgMCIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgc3RyZWFtLiBUaGlzIHJlbGVhc2VzIHN5c3RlbSByZXNvdXJjZXMgdXNlZCBmb3IgdGhpcyBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGF0dGVtcHRpbmcgdG8gY2xvc2UgdGhpcyBzdHJlYW0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvKioKKyAgICAgICAgICogQWx0aG91Z2ggdGhlIHNwZWMgY2xhaW1zICJBIGNsb3NlZCBzdHJlYW0gY2Fubm90IHBlcmZvcm0gb3V0cHV0CisgICAgICAgICAqIG9wZXJhdGlvbnMgYW5kIGNhbm5vdCBiZSByZW9wZW5lZC4iLCB0aGlzIGltcGxlbWVudGF0aW9uIG11c3QgZG8KKyAgICAgICAgICogbm90aGluZy4KKyAgICAgICAgICovCisgICAgICAgIHN1cGVyLmNsb3NlKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGV4cGFuZChpbnQgaSkgeworICAgICAgICAvKiBDYW4gdGhlIGJ1ZmZlciBoYW5kbGUgQGkgbW9yZSBieXRlcywgaWYgbm90IGV4cGFuZCBpdCAqLworICAgICAgICBpZiAoY291bnQgKyBpIDw9IGJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGVbXSBuZXdidWYgPSBuZXcgYnl0ZVsoY291bnQgKyBpKSAqIDJdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZiwgMCwgbmV3YnVmLCAwLCBjb3VudCk7CisgICAgICAgIGJ1ZiA9IG5ld2J1ZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhpcyBzdHJlYW0gdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgdW5kZXJseWluZyBieXRlIGFycmF5LiBBbGwKKyAgICAgKiBzdWJzZXF1ZW50IHdyaXRlcyB3aWxsIG92ZXJ3cml0ZSBhbnkgYnl0ZXMgcHJldmlvdXNseSBzdG9yZWQgaW4gdGhpcworICAgICAqIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVzZXQoKSB7CisgICAgICAgIGNvdW50ID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiB0byB0aGlzIHN0cmVhbSBzbyBmYXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiB0byB0aGlzIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgIHJldHVybiBjb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb250ZW50cyBvZiB0aGlzIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBhcyBhIGJ5dGUgYXJyYXkuIEFueQorICAgICAqIGNoYW5nZXMgbWFkZSB0byB0aGUgcmVjZWl2ZXIgYWZ0ZXIgcmV0dXJuaW5nIHdpbGwgbm90IGJlIHJlZmxlY3RlZCBpbiB0aGUKKyAgICAgKiBieXRlIGFycmF5IHJldHVybmVkIHRvIHRoZSBjYWxsZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgc3RyZWFtJ3MgY3VycmVudCBjb250ZW50cyBhcyBhIGJ5dGUgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBieXRlW10gdG9CeXRlQXJyYXkoKSB7CisgICAgICAgIGJ5dGVbXSBuZXdBcnJheSA9IG5ldyBieXRlW2NvdW50XTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWYsIDAsIG5ld0FycmF5LCAwLCBjb3VudCk7CisgICAgICAgIHJldHVybiBuZXdBcnJheTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb250ZW50cyBvZiB0aGlzIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBhcyBhIHN0cmluZy4gQW55CisgICAgICogY2hhbmdlcyBtYWRlIHRvIHRoZSByZWNlaXZlciBhZnRlciByZXR1cm5pbmcgd2lsbCBub3QgYmUgcmVmbGVjdGVkIGluIHRoZQorICAgICAqIHN0cmluZyByZXR1cm5lZCB0byB0aGUgY2FsbGVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIHN0cmVhbSdzIGN1cnJlbnQgY29udGVudHMgYXMgYSBzdHJpbmcuCisgICAgICovCisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhidWYsIDAsIGNvdW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb250ZW50cyBvZiB0aGlzIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBhcyBhIHN0cmluZy4gRWFjaCBieXRlCisgICAgICoge0Bjb2RlIGJ9IGluIHRoaXMgc3RyZWFtIGlzIGNvbnZlcnRlZCB0byBhIGNoYXJhY3RlciB7QGNvZGUgY30gdXNpbmcgdGhlCisgICAgICogZm9sbG93aW5nIGZ1bmN0aW9uOgorICAgICAqIHtAY29kZSBjID09IChjaGFyKSgoKGhpYnl0ZSAmIDB4ZmYpIDw8IDgpIHwgKGIgJiAweGZmKSl9LiBUaGlzIG1ldGhvZCBpcworICAgICAqIGRlcHJlY2F0ZWQgYW5kIGVpdGhlciB7QGxpbmsgI3RvU3RyaW5nKCl9IG9yIHtAbGluayAjdG9TdHJpbmcoU3RyaW5nKX0KKyAgICAgKiBzaG91bGQgYmUgdXNlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBoaWJ5dGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBoaWdoIGJ5dGUgb2YgZWFjaCByZXN1bHRpbmcgVW5pY29kZSBjaGFyYWN0ZXIuCisgICAgICogQHJldHVybiB0aGlzIHN0cmVhbSdzIGN1cnJlbnQgY29udGVudHMgYXMgYSBzdHJpbmcgd2l0aCB0aGUgaGlnaCBieXRlIHNldAorICAgICAqICAgICAgICAgdG8ge0Bjb2RlIGhpYnl0ZX0uCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjdG9TdHJpbmcoKX0uCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGludCBoaWJ5dGUpIHsKKyAgICAgICAgY2hhcltdIG5ld0J1ZiA9IG5ldyBjaGFyW3NpemUoKV07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmV3QnVmLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBuZXdCdWZbaV0gPSAoY2hhcikgKCgoaGlieXRlICYgMHhmZikgPDwgOCkgfCAoYnVmW2ldICYgMHhmZikpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKG5ld0J1Zik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29udGVudHMgb2YgdGhpcyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYXMgYSBzdHJpbmcgY29udmVydGVkCisgICAgICogYWNjb3JkaW5nIHRvIHRoZSBlbmNvZGluZyBkZWNsYXJlZCBpbiB7QGNvZGUgZW5jfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbmMKKyAgICAgKiAgICAgICAgICAgIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgZW5jb2RpbmcgdG8gdXNlIHdoZW4gdHJhbnNsYXRpbmcKKyAgICAgKiAgICAgICAgICAgIHRoaXMgc3RyZWFtIHRvIGEgc3RyaW5nLgorICAgICAqIEByZXR1cm4gdGhpcyBzdHJlYW0ncyBjdXJyZW50IGNvbnRlbnRzIGFzIGFuIGVuY29kZWQgc3RyaW5nLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwcm92aWRlZCBlbmNvZGluZyBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoU3RyaW5nIGVuYykgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhidWYsIDAsIGNvdW50LCBlbmMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB7QGNvZGUgY291bnR9IGJ5dGVzIGZyb20gdGhlIGJ5dGUgYXJyYXkge0Bjb2RlIGJ1ZmZlcn0gc3RhcnRpbmcgYXQKKyAgICAgKiBvZmZzZXQge0Bjb2RlIGluZGV4fSB0byB0aGlzIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXIgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBwb3NpdGlvbiBpbiB7QGNvZGUgYnVmZmVyfSB0byByZXRyaWV2ZSBieXRlcy4KKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIG9mIHtAY29kZSBidWZmZXJ9IHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYnVmZmVyfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBsZW4gPCAwfSwgb3IgaWYKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgb2Zmc2V0ICsgbGVufSBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBidWZmZXJ9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCB3cml0ZShieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgbGVuKSB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGJ1ZmZlci5sZW5ndGgsIG9mZnNldCwgbGVuKTsKKyAgICAgICAgaWYgKGxlbiA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZXhwYW5kKGxlbik7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCBvZmZzZXQsIGJ1ZiwgdGhpcy5jb3VudCwgbGVuKTsKKyAgICAgICAgdGhpcy5jb3VudCArPSBsZW47CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBzcGVjaWZpZWQgYnl0ZSB7QGNvZGUgb25lQnl0ZX0gdG8gdGhlIE91dHB1dFN0cmVhbS4gT25seSB0aGUKKyAgICAgKiBsb3cgb3JkZXIgYnl0ZSBvZiB7QGNvZGUgb25lQnl0ZX0gaXMgd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvbmVCeXRlCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSB0byBiZSB3cml0dGVuLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCB3cml0ZShpbnQgb25lQnl0ZSkgeworICAgICAgICBpZiAoY291bnQgPT0gYnVmLmxlbmd0aCkgeworICAgICAgICAgICAgZXhwYW5kKDEpOworICAgICAgICB9CisgICAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSBvbmVCeXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRha2VzIHRoZSBjb250ZW50cyBvZiB0aGlzIHN0cmVhbSBhbmQgd3JpdGVzIGl0IHRvIHRoZSBvdXRwdXQgc3RyZWFtCisgICAgICoge0Bjb2RlIG91dH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICogICAgICAgICAgICBhbiBPdXRwdXRTdHJlYW0gb24gd2hpY2ggdG8gd3JpdGUgdGhlIGNvbnRlbnRzIG9mIHRoaXMgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0byB7QGNvZGUgb3V0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgd3JpdGVUbyhPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXQud3JpdGUoYnVmLCAwLCBjb3VudCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vQ2hhckFycmF5UmVhZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9DaGFyQXJyYXlSZWFkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNjZlZmNmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vQ2hhckFycmF5UmVhZGVyLmphdmEKQEAgLTAsMCArMSwyODcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogQSBzcGVjaWFsaXplZCB7QGxpbmsgUmVhZGVyfSBmb3IgcmVhZGluZyB0aGUgY29udGVudHMgb2YgYSBjaGFyIGFycmF5LgorICoKKyAqIEBzZWUgQ2hhckFycmF5V3JpdGVyCisgKi8KK3B1YmxpYyBjbGFzcyBDaGFyQXJyYXlSZWFkZXIgZXh0ZW5kcyBSZWFkZXIgeworICAgIC8qKgorICAgICAqIFRoZSBidWZmZXIgZm9yIGNoYXJhY3RlcnMuCisgICAgICovCisgICAgcHJvdGVjdGVkIGNoYXJbXSBidWY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY3VycmVudCBidWZmZXIgcG9zaXRpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBwb3M7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY3VycmVudCBtYXJrIHBvc2l0aW9uLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgbWFya2VkUG9zID0gLTE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZW5kaW5nIGluZGV4IG9mIHRoZSBidWZmZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBjb3VudDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBDaGFyQXJyYXlSZWFkZXIgb24gdGhlIGNoYXIgYXJyYXkge0Bjb2RlIGJ1Zn0uIFRoZSBzaXplIG9mCisgICAgICogdGhlIHJlYWRlciBpcyBzZXQgdG8gdGhlIGxlbmd0aCBvZiB0aGUgYnVmZmVyIGFuZCB0aGUgb2JqZWN0IHRvIHRvIHJlYWQKKyAgICAgKiBmcm9tIGlzIHNldCB0byB7QGNvZGUgYnVmfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWYKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyIGFycmF5IGZyb20gd2hpY2ggdG8gcmVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2hhckFycmF5UmVhZGVyKGNoYXJbXSBidWYpIHsKKyAgICAgICAgdGhpcy5idWYgPSBidWY7CisgICAgICAgIHRoaXMuY291bnQgPSBidWYubGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBDaGFyQXJyYXlSZWFkZXIgb24gdGhlIGNoYXIgYXJyYXkge0Bjb2RlIGJ1Zn0uIFRoZSBzaXplIG9mCisgICAgICogdGhlIHJlYWRlciBpcyBzZXQgdG8ge0Bjb2RlIGxlbmd0aH0gYW5kIHRoZSBzdGFydCBwb3NpdGlvbiBmcm9tIHdoaWNoIHRvCisgICAgICogcmVhZCB0aGUgYnVmZmVyIGlzIHNldCB0byB7QGNvZGUgb2Zmc2V0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWYKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyIGFycmF5IGZyb20gd2hpY2ggdG8gcmVhZC4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB7QGNvZGUgYnVmfSB0byByZWFkLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0aGF0IGNhbiBiZSByZWFkIGZyb20ge0Bjb2RlIGJ1Zn0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGxlbmd0aCA8IDB9LCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXR9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgc2l6ZSBvZiB7QGNvZGUgYnVmfSAuCisgICAgICovCisgICAgcHVibGljIENoYXJBcnJheVJlYWRlcihjaGFyW10gYnVmLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFRoZSBzcGVjIG9mIHRoaXMgY29uc3RydWN0b3IgaXMgYnJva2VuLiBJbiBkZWZpbmluZyB0aGUgbGVnYWwgdmFsdWVzCisgICAgICAgICAqIG9mIG9mZnNldCBhbmQgbGVuZ3RoLCBpdCBkb2Vzbid0IGNvbnNpZGVyIGJ1ZmZlcidzIGxlbmd0aC4gQW5kIHRvIGJlCisgICAgICAgICAqIGNvbXBhdGlibGUgd2l0aCB0aGUgYnJva2VuIHNwZWMsIHdlIG11c3QgYWxzbyB0ZXN0IHdoZXRoZXIKKyAgICAgICAgICogKG9mZnNldCArIGxlbmd0aCkgb3ZlcmZsb3dzLgorICAgICAgICAgKi8KKyAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4gYnVmLmxlbmd0aCB8fCBsZW5ndGggPCAwIHx8IG9mZnNldCArIGxlbmd0aCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmJ1ZiA9IGJ1ZjsKKyAgICAgICAgdGhpcy5wb3MgPSBvZmZzZXQ7CisgICAgICAgIHRoaXMubWFya2VkUG9zID0gb2Zmc2V0OworCisgICAgICAgIC8qIFRoaXMgaXMgYWNjb3JkaW5nIHRvIHNwZWMgKi8KKyAgICAgICAgaW50IGJ1ZmZlckxlbmd0aCA9IGJ1Zi5sZW5ndGg7CisgICAgICAgIHRoaXMuY291bnQgPSBvZmZzZXQgKyBsZW5ndGggPCBidWZmZXJMZW5ndGggPyBsZW5ndGggOiBidWZmZXJMZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgY2xvc2VzIHRoaXMgQ2hhckFycmF5UmVhZGVyLiBPbmNlIGl0IGlzIGNsb3NlZCwgeW91IGNhbiBubworICAgICAqIGxvbmdlciByZWFkIGZyb20gaXQuIE9ubHkgdGhlIGZpcnN0IGludm9jYXRpb24gb2YgdGhpcyBtZXRob2QgaGFzIGFueQorICAgICAqIGVmZmVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBpZiAoaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICBidWYgPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyByZWFkZXIgaXMgb3Blbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSByZWFkZXIgaXMgb3Blbiwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGlzT3BlbigpIHsKKyAgICAgICAgcmV0dXJuIGJ1ZiAhPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgcmVhZGVyIGlzIGNsb3NlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSByZWFkZXIgaXMgY2xvc2VkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNDbG9zZWQoKSB7CisgICAgICAgIHJldHVybiBidWYgPT0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGEgbWFyayBwb3NpdGlvbiBpbiB0aGlzIHJlYWRlci4gVGhlIHBhcmFtZXRlciB7QGNvZGUgcmVhZExpbWl0fSBpcworICAgICAqIGlnbm9yZWQgZm9yIENoYXJBcnJheVJlYWRlcnMuIENhbGxpbmcge0Bjb2RlIHJlc2V0KCl9IHdpbGwgcmVwb3NpdGlvbiB0aGUKKyAgICAgKiByZWFkZXIgYmFjayB0byB0aGUgbWFya2VkIHBvc2l0aW9uIHByb3ZpZGVkIHRoZSBtYXJrIGhhcyBub3QgYmVlbgorICAgICAqIGludmFsaWRhdGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYWRMaW1pdAorICAgICAqICAgICAgICAgICAgaWdub3JlZCBmb3IgQ2hhckFycmF5UmVhZGVycy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyByZWFkZXIgaXMgY2xvc2VkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIG1hcmsoaW50IHJlYWRMaW1pdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBjaGVja05vdENsb3NlZCgpOworICAgICAgICAgICAgbWFya2VkUG9zID0gcG9zOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrTm90Q2xvc2VkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzQ2xvc2VkKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ2hhckFycmF5UmVhZGVyIGlzIGNsb3NlZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyByZWFkZXIgc3VwcG9ydHMgdGhlIHtAY29kZSBtYXJrKCl9IGFuZAorICAgICAqIHtAY29kZSByZXNldCgpfSBtZXRob2RzLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gZm9yIENoYXJBcnJheVJlYWRlci4KKyAgICAgKiBAc2VlICNtYXJrKGludCkKKyAgICAgKiBAc2VlICNyZXNldCgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gbWFya1N1cHBvcnRlZCgpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBzaW5nbGUgY2hhcmFjdGVyIGZyb20gdGhpcyByZWFkZXIgYW5kIHJldHVybnMgaXQgYXMgYW4gaW50ZWdlcgorICAgICAqIHdpdGggdGhlIHR3byBoaWdoZXItb3JkZXIgYnl0ZXMgc2V0IHRvIDAuIFJldHVybnMgLTEgaWYgbm8gbW9yZQorICAgICAqIGNoYXJhY3RlcnMgYXJlIGF2YWlsYWJsZSBmcm9tIHRoaXMgcmVhZGVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2hhcmFjdGVyIHJlYWQgYXMgYW4gaW50IG9yIC0xIGlmIHRoZSBlbmQgb2YgdGhlIHJlYWRlciBoYXMKKyAgICAgKiAgICAgICAgIGJlZW4gcmVhY2hlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyByZWFkZXIgaXMgY2xvc2VkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgICAgIGlmIChwb3MgPT0gY291bnQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gYnVmW3BvcysrXTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGF0IG1vc3Qge0Bjb2RlIGNvdW50fSBjaGFyYWN0ZXJzIGZyb20gdGhpcyBDaGFyQXJyYXlSZWFkZXIgYW5kCisgICAgICogc3RvcmVzIHRoZW0gYXQge0Bjb2RlIG9mZnNldH0gaW4gdGhlIGNoYXJhY3RlciBhcnJheSB7QGNvZGUgYnVmfS4KKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBhY3R1YWxseSByZWFkIG9yIC0xIGlmIHRoZSBlbmQgb2YgcmVhZGVyCisgICAgICogd2FzIGVuY291bnRlcmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciBhcnJheSB0byBzdG9yZSB0aGUgY2hhcmFjdGVycyByZWFkLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIHBvc2l0aW9uIGluIHtAY29kZSBidWZmZXJ9IHRvIHN0b3JlIHRoZSBjaGFyYWN0ZXJzCisgICAgICogICAgICAgICAgICByZWFkIGZyb20gdGhpcyByZWFkZXIuCisgICAgICogQHBhcmFtIGxlbgorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZC4KKyAgICAgKiBAcmV0dXJuIG51bWJlciBvZiBjaGFyYWN0ZXJzIHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgcmVhZGVyIGhhcyBiZWVuCisgICAgICogICAgICAgICByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwfSBvciB7QGNvZGUgbGVuIDwgMH0sIG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIG9mZnNldCArIGxlbn0gaXMgYmlnZ2VyIHRoYW4gdGhlIHNpemUgb2YKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgYnVmZmVyfS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyByZWFkZXIgaXMgY2xvc2VkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChjaGFyW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXIubGVuZ3RoLCBvZmZzZXQsIGxlbik7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgICAgIGlmIChwb3MgPCB0aGlzLmNvdW50KSB7CisgICAgICAgICAgICAgICAgaW50IGJ5dGVzUmVhZCA9IHBvcyArIGxlbiA+IHRoaXMuY291bnQgPyB0aGlzLmNvdW50IC0gcG9zIDogbGVuOworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodGhpcy5idWYsIHBvcywgYnVmZmVyLCBvZmZzZXQsIGJ5dGVzUmVhZCk7CisgICAgICAgICAgICAgICAgcG9zICs9IGJ5dGVzUmVhZDsKKyAgICAgICAgICAgICAgICByZXR1cm4gYnl0ZXNSZWFkOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyByZWFkZXIgaXMgcmVhZHkgdG8gYmUgcmVhZCB3aXRob3V0IGJsb2NraW5nLgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoZSBuZXh0IHtAY29kZSByZWFkfSB3aWxsIG5vdCBibG9jay4gUmV0dXJucworICAgICAqIHtAY29kZSBmYWxzZX0gaWYgdGhpcyByZWFkZXIgbWF5IG9yIG1heSBub3QgYmxvY2sgd2hlbiB7QGNvZGUgcmVhZH0gaXMKKyAgICAgKiBjYWxsZWQuIFRoZSBpbXBsZW1lbnRhdGlvbiBpbiBDaGFyQXJyYXlSZWFkZXIgYWx3YXlzIHJldHVybnMge0Bjb2RlIHRydWV9CisgICAgICogZXZlbiB3aGVuIGl0IGhhcyBiZWVuIGNsb3NlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgcmVhZGVyIHdpbGwgbm90IGJsb2NrIHdoZW4ge0Bjb2RlIHJlYWR9IGlzCisgICAgICogICAgICAgICBjYWxsZWQsIHtAY29kZSBmYWxzZX0gaWYgdW5rbm93biBvciBibG9ja2luZyB3aWxsIG9jY3VyLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gcmVhZHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgICAgICByZXR1cm4gcG9zICE9IGNvdW50OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzZXRzIHRoaXMgcmVhZGVyJ3MgcG9zaXRpb24gdG8gdGhlIGxhc3Qge0Bjb2RlIG1hcmsoKX0gbG9jYXRpb24uCisgICAgICogSW52b2NhdGlvbnMgb2Yge0Bjb2RlIHJlYWQoKX0gYW5kIHtAY29kZSBza2lwKCl9IHdpbGwgb2NjdXIgZnJvbSB0aGlzIG5ldworICAgICAqIGxvY2F0aW9uLiBJZiB0aGlzIHJlYWRlciBoYXMgbm90IGJlZW4gbWFya2VkLCBpdCBpcyByZXNldCB0byB0aGUKKyAgICAgKiBiZWdpbm5pbmcgb2YgdGhlIHN0cmluZy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgICAgICBwb3MgPSBtYXJrZWRQb3MgIT0gLTEgPyBtYXJrZWRQb3MgOiAwOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcHMge0Bjb2RlIGNoYXJDb3VudH0gY2hhcmFjdGVycyBpbiB0aGlzIHJlYWRlci4gU3Vic2VxdWVudCBjYWxscyB0bworICAgICAqIHtAY29kZSByZWFkfSB3aWxsIG5vdCByZXR1cm4gdGhlc2UgY2hhcmFjdGVycyB1bmxlc3Mge0Bjb2RlIHJlc2V0fQorICAgICAqIGlzIHVzZWQuIFRoaXMgbWV0aG9kIGRvZXMgbm90aGluZyBhbmQgcmV0dXJucyAwIGlmIHtAY29kZSBjaGFyQ291bnQgPD0gMH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBhY3R1YWxseSBza2lwcGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgc2tpcChsb25nIGNoYXJDb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBjaGVja05vdENsb3NlZCgpOworICAgICAgICAgICAgaWYgKGNoYXJDb3VudCA8PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsb25nIHNraXBwZWQgPSAwOworICAgICAgICAgICAgaWYgKGNoYXJDb3VudCA8IHRoaXMuY291bnQgLSBwb3MpIHsKKyAgICAgICAgICAgICAgICBwb3MgPSBwb3MgKyAoaW50KSBjaGFyQ291bnQ7CisgICAgICAgICAgICAgICAgc2tpcHBlZCA9IGNoYXJDb3VudDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc2tpcHBlZCA9IHRoaXMuY291bnQgLSBwb3M7CisgICAgICAgICAgICAgICAgcG9zID0gdGhpcy5jb3VudDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBza2lwcGVkOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vQ2hhckFycmF5V3JpdGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9DaGFyQXJyYXlXcml0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYzk4YTdjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vQ2hhckFycmF5V3JpdGVyLmphdmEKQEAgLTAsMCArMSwzMDAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogQSBzcGVjaWFsaXplZCB7QGxpbmsgV3JpdGVyfSBmb3IgY2xhc3MgZm9yIHdyaXRpbmcgY29udGVudCB0byBhbiAoaW50ZXJuYWwpCisgKiBjaGFyIGFycmF5LiBBcyBieXRlcyBhcmUgd3JpdHRlbiB0byB0aGlzIHdyaXRlciwgdGhlIGNoYXIgYXJyYXkgbWF5IGJlCisgKiBleHBhbmRlZCB0byBob2xkIG1vcmUgY2hhcmFjdGVycy4gV2hlbiB0aGUgd3JpdGluZyBpcyBjb25zaWRlcmVkIHRvIGJlCisgKiBmaW5pc2hlZCwgYSBjb3B5IG9mIHRoZSBjaGFyIGFycmF5IGNhbiBiZSByZXF1ZXN0ZWQgZnJvbSB0aGUgY2xhc3MuCisgKgorICogQHNlZSBDaGFyQXJyYXlSZWFkZXIKKyAqLworcHVibGljIGNsYXNzIENoYXJBcnJheVdyaXRlciBleHRlbmRzIFdyaXRlciB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYnVmZmVyIGZvciBjaGFyYWN0ZXJzLgorICAgICAqLworICAgIHByb3RlY3RlZCBjaGFyW10gYnVmOworCisgICAgLyoqCisgICAgICogVGhlIGVuZGluZyBpbmRleCBvZiB0aGUgYnVmZmVyLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgY291bnQ7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBDaGFyQXJyYXlXcml0ZXJ9IHdoaWNoIGhhcyBhIGJ1ZmZlciBhbGxvY2F0ZWQKKyAgICAgKiB3aXRoIHRoZSBkZWZhdWx0IHNpemUgb2YgMzIgY2hhcmFjdGVycy4gVGhpcyBidWZmZXIgaXMgYWxzbyB1c2VkIGFzIHRoZQorICAgICAqIHtAY29kZSBsb2NrfSB0byBzeW5jaHJvbml6ZSBhY2Nlc3MgdG8gdGhpcyB3cml0ZXIuCisgICAgICovCisgICAgcHVibGljIENoYXJBcnJheVdyaXRlcigpIHsKKyAgICAgICAgYnVmID0gbmV3IGNoYXJbMzJdOworICAgICAgICBsb2NrID0gYnVmOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIENoYXJBcnJheVdyaXRlcn0gd2hpY2ggaGFzIGEgYnVmZmVyIGFsbG9jYXRlZAorICAgICAqIHdpdGggdGhlIHNpemUgb2Yge0Bjb2RlIGluaXRpYWxTaXplfSBjaGFyYWN0ZXJzLiBUaGUgYnVmZmVyIGlzIGFsc28gdXNlZAorICAgICAqIGFzIHRoZSB7QGNvZGUgbG9ja30gdG8gc3luY2hyb25pemUgYWNjZXNzIHRvIHRoaXMgd3JpdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGluaXRpYWxTaXplCisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBzaXplIG9mIHRoaXMgQ2hhckFycmF5V3JpdGVycyBidWZmZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW5pdGlhbFNpemUgPCAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2hhckFycmF5V3JpdGVyKGludCBpbml0aWFsU2l6ZSkgeworICAgICAgICBpZiAoaW5pdGlhbFNpemUgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzaXplIDwgMCIpOworICAgICAgICB9CisgICAgICAgIGJ1ZiA9IG5ldyBjaGFyW2luaXRpYWxTaXplXTsKKyAgICAgICAgbG9jayA9IGJ1ZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhpcyB3cml0ZXIuIFRoZSBpbXBsZW1lbnRhdGlvbiBpbiB7QGNvZGUgQ2hhckFycmF5V3JpdGVyfSBkb2VzIG5vdGhpbmcuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgIC8qIGVtcHR5ICovCisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGV4cGFuZChpbnQgaSkgeworICAgICAgICAvKiBDYW4gdGhlIGJ1ZmZlciBoYW5kbGUgQGkgbW9yZSBjaGFycywgaWYgbm90IGV4cGFuZCBpdCAqLworICAgICAgICBpZiAoY291bnQgKyBpIDw9IGJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGludCBuZXdMZW4gPSBNYXRoLm1heCgyICogYnVmLmxlbmd0aCwgY291bnQgKyBpKTsKKyAgICAgICAgY2hhcltdIG5ld2J1ZiA9IG5ldyBjaGFyW25ld0xlbl07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCAwLCBuZXdidWYsIDAsIGNvdW50KTsKKyAgICAgICAgYnVmID0gbmV3YnVmOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZsdXNoZXMgdGhpcyB3cml0ZXIuIFRoZSBpbXBsZW1lbnRhdGlvbiBpbiB7QGNvZGUgQ2hhckFycmF5V3JpdGVyfSBkb2VzIG5vdGhpbmcuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB7CisgICAgICAgIC8qIGVtcHR5ICovCisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzZXRzIHRoaXMgd3JpdGVyLiBUaGUgY3VycmVudCB3cml0ZSBwb3NpdGlvbiBpcyByZXNldCB0byB0aGUgYmVnaW5uaW5nCisgICAgICogb2YgdGhlIGJ1ZmZlci4gQWxsIHdyaXR0ZW4gY2hhcmFjdGVycyBhcmUgbG9zdCBhbmQgdGhlIHNpemUgb2YgdGhpcworICAgICAqIHdyaXRlciBpcyBzZXQgdG8gMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBjb3VudCA9IDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzaXplIG9mIHRoaXMgd3JpdGVyLCB0aGF0IGlzIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpdAorICAgICAqIHN0b3Jlcy4gVGhpcyBudW1iZXIgY2hhbmdlcyBpZiB0aGlzIHdyaXRlciBpcyByZXNldCBvciB3aGVuIG1vcmUKKyAgICAgKiBjaGFyYWN0ZXJzIGFyZSB3cml0dGVuIHRvIGl0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIENoYXJBcnJheVdyaXRlcidzIGN1cnJlbnQgc2l6ZSBpbiBjaGFyYWN0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICByZXR1cm4gY291bnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb250ZW50cyBvZiB0aGUgcmVjZWl2ZXIgYXMgYSBjaGFyIGFycmF5LiBUaGUgYXJyYXkgcmV0dXJuZWQKKyAgICAgKiBpcyBhIGNvcHkgYW5kIGFueSBtb2RpZmljYXRpb25zIG1hZGUgdG8gdGhpcyB3cml0ZXIgYWZ0ZXIgY2FsbGluZyB0aGlzCisgICAgICogbWV0aG9kIGFyZSBub3QgcmVmbGVjdGVkIGluIHRoZSByZXN1bHQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgQ2hhckFycmF5V3JpdGVyJ3MgY29udGVudHMgYXMgYSBuZXcgY2hhciBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhcltdIHRvQ2hhckFycmF5KCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGNoYXJbXSByZXN1bHQgPSBuZXcgY2hhcltjb3VudF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZiwgMCwgcmVzdWx0LCAwLCBjb3VudCk7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29udGVudHMgb2YgdGhpcyB7QGNvZGUgQ2hhckFycmF5V3JpdGVyfSBhcyBhIHN0cmluZy4gVGhlCisgICAgICogc3RyaW5nIHJldHVybmVkIGlzIGEgY29weSBhbmQgYW55IG1vZGlmaWNhdGlvbnMgbWFkZSB0byB0aGlzIHdyaXRlciBhZnRlcgorICAgICAqIGNhbGxpbmcgdGhpcyBtZXRob2QgYXJlIG5vdCByZWZsZWN0ZWQgaW4gdGhlIHJlc3VsdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBDaGFyQXJyYXlXcml0ZXJzIGNvbnRlbnRzIGFzIGEgbmV3IHN0cmluZy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGJ1ZiwgMCwgY291bnQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHtAY29kZSBjb3VudH0gY2hhcmFjdGVycyBzdGFydGluZyBhdCB7QGNvZGUgb2Zmc2V0fSBpbiB7QGNvZGUgY30KKyAgICAgKiB0byB0aGlzIHdyaXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBub24tbnVsbCBhcnJheSBjb250YWluaW5nIGNoYXJhY3RlcnMgdG8gd3JpdGUuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4ge0Bjb2RlIGJ1Zn0gdG8gd3JpdGUuCisgICAgICogQHBhcmFtIGxlbgorICAgICAqICAgICAgICAgICAgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGxlbiA8IDB9LCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBsZW59IGlzIGJpZ2dlciB0aGFuIHRoZSBzaXplIG9mIHtAY29kZSBjfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShjaGFyW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgbGVuKSB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGJ1ZmZlci5sZW5ndGgsIG9mZnNldCwgbGVuKTsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBleHBhbmQobGVuKTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCBvZmZzZXQsIHRoaXMuYnVmLCB0aGlzLmNvdW50LCBsZW4pOworICAgICAgICAgICAgdGhpcy5jb3VudCArPSBsZW47CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIge0Bjb2RlIG9uZUNoYXJ9IHRvIHRoaXMgd3JpdGVyLgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gd3JpdGVzIHRoZSB0d28gbG93IG9yZGVyIGJ5dGVzIG9mIHRoZSBpbnRlZ2VyCisgICAgICoge0Bjb2RlIG9uZUNoYXJ9IHRvIHRoZSBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb25lQ2hhcgorICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byB3cml0ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgb25lQ2hhcikgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGV4cGFuZCgxKTsKKyAgICAgICAgICAgIGJ1Zltjb3VudCsrXSA9IChjaGFyKSBvbmVDaGFyOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHtAY29kZSBjb3VudH0gY2hhcmFjdGVycyBzdGFydGluZyBhdCB7QGNvZGUgb2Zmc2V0fSBmcm9tCisgICAgICogdGhlIHN0cmluZyB7QGNvZGUgc3RyfSB0byB0aGlzIENoYXJBcnJheVdyaXRlci4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBjb3VudCA8IDB9LCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBjb3VudH0gaXMgYmlnZ2VyIHRoYW4gdGhlIGxlbmd0aCBvZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBzdHJ9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKFN0cmluZyBzdHIsIGludCBvZmZzZXQsIGludCBjb3VudCkgeworICAgICAgICBpZiAoc3RyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigic3RyID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoKG9mZnNldCB8IGNvdW50KSA8IDAgfHwgb2Zmc2V0ID4gc3RyLmxlbmd0aCgpIC0gY291bnQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKHN0ciwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBleHBhbmQoY291bnQpOworICAgICAgICAgICAgc3RyLmdldENoYXJzKG9mZnNldCwgb2Zmc2V0ICsgY291bnQsIGJ1ZiwgdGhpcy5jb3VudCk7CisgICAgICAgICAgICB0aGlzLmNvdW50ICs9IGNvdW50OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBjb250ZW50cyBvZiB0aGlzIHtAY29kZSBDaGFyQXJyYXlXcml0ZXJ9IHRvIGFub3RoZXIge0Bjb2RlCisgICAgICogV3JpdGVyfS4gVGhlIG91dHB1dCBpcyBhbGwgdGhlIGNoYXJhY3RlcnMgdGhhdCBoYXZlIGJlZW4gd3JpdHRlbiB0byB0aGUKKyAgICAgKiByZWNlaXZlciBzaW5jZSB0aGUgbGFzdCByZXNldCBvciBzaW5jZSBpdCB3YXMgY3JlYXRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBub24tbnVsbCB7QGNvZGUgV3JpdGVyfSBvbiB3aGljaCB0byB3cml0ZSB0aGUgY29udGVudHMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvdXR9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGF0dGVtcHRpbmcgdG8gd3JpdGUgb3V0IHRoZSBjb250ZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKFdyaXRlciBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZiwgMCwgY291bnQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyBhIGNoYXIge0Bjb2RlIGN9IHRvIHRoZSB7QGNvZGUgQ2hhckFycmF5V3JpdGVyfS4gVGhlIG1ldGhvZCB3b3JrcworICAgICAqIHRoZSBzYW1lIHdheSBhcyB7QGNvZGUgd3JpdGUoYyl9LgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgYXBwZW5kZWQgdG8gdGhlIENoYXJBcnJheVdyaXRlci4KKyAgICAgKiBAcmV0dXJuIHRoaXMgQ2hhckFycmF5V3JpdGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDaGFyQXJyYXlXcml0ZXIgYXBwZW5kKGNoYXIgYykgeworICAgICAgICB3cml0ZShjKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyBhIHtAY29kZSBDaGFyU2VxdWVuY2V9IHRvIHRoZSB7QGNvZGUgQ2hhckFycmF5V3JpdGVyfS4gVGhlIG1ldGhvZAorICAgICAqIHdvcmtzIHRoZSBzYW1lIHdheSBhcyB7QGNvZGUgd3JpdGUoY3NxLnRvU3RyaW5nKCkpfS4gSWYge0Bjb2RlIGNzcX0gaXMKKyAgICAgKiB7QGNvZGUgbnVsbH0sIHRoZW4gaXQgd2lsbCBiZSBzdWJzdGl0dXRlZCB3aXRoIHRoZSBzdHJpbmcge0Bjb2RlICJudWxsIn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY3NxCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIENoYXJTZXF1ZW5jZX0gYXBwZW5kZWQgdG8gdGhlIHtAY29kZQorICAgICAqICAgICAgICAgICAgQ2hhckFycmF5V3JpdGVyfSwgbWF5IGJlIHtAY29kZSBudWxsfS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgQ2hhckFycmF5V3JpdGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDaGFyQXJyYXlXcml0ZXIgYXBwZW5kKENoYXJTZXF1ZW5jZSBjc3EpIHsKKyAgICAgICAgaWYgKGNzcSA9PSBudWxsKSB7CisgICAgICAgICAgICBjc3EgPSAibnVsbCI7CisgICAgICAgIH0KKyAgICAgICAgYXBwZW5kKGNzcSwgMCwgY3NxLmxlbmd0aCgpKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kIGEgc3Vic2VxdWVuY2Ugb2YgYSB7QGNvZGUgQ2hhclNlcXVlbmNlfSB0byB0aGUge0Bjb2RlCisgICAgICogQ2hhckFycmF5V3JpdGVyfS4gVGhlIGZpcnN0IGFuZCBsYXN0IGNoYXJhY3RlcnMgb2YgdGhlIHN1YnNlcXVlbmNlIGFyZQorICAgICAqIHNwZWNpZmllZCBieSB0aGUgcGFyYW1ldGVycyB7QGNvZGUgc3RhcnR9IGFuZCB7QGNvZGUgZW5kfS4gQSBjYWxsIHRvCisgICAgICoge0Bjb2RlIENoYXJBcnJheVdyaXRlci5hcHBlbmQoY3NxKX0gd29ya3MgdGhlIHNhbWUgd2F5IGFzIHtAY29kZQorICAgICAqIENoYXJBcnJheVdyaXRlci53cml0ZShjc3Euc3ViU2VxdWVuY2Uoc3RhcnQsIGVuZCkudG9TdHJpbmcpfS4gSWYge0Bjb2RlCisgICAgICogY3NxfSBpcyB7QGNvZGUgbnVsbH0sIHRoZW4gaXQgd2lsbCBiZSBzdWJzdGl0dXRlZCB3aXRoIHRoZSBzdHJpbmcge0Bjb2RlCisgICAgICogIm51bGwifS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjc3EKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2hhclNlcXVlbmNlfSBhcHBlbmRlZCB0byB0aGUge0Bjb2RlCisgICAgICogICAgICAgICAgICBDaGFyQXJyYXlXcml0ZXJ9LCBtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gdGhlIHtAY29kZSBDaGFyU2VxdWVuY2V9CisgICAgICogICAgICAgICAgICBhcHBlbmRlZCB0byB0aGUge0Bjb2RlIENoYXJBcnJheVdyaXRlcn0uCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIGxhc3Qgb25lIGluIHRoZSB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIENoYXJTZXF1ZW5jZX0gYXBwZW5kZWQgdG8gdGhlIHtAY29kZSBDaGFyQXJyYXlXcml0ZXJ9LgorICAgICAqIEByZXR1cm4gdGhpcyBDaGFyQXJyYXlXcml0ZXIuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0IDwgMH0sIHtAY29kZSBlbmQgPCAwfSwge0Bjb2RlIHN0YXJ0ID4gZW5kfSwKKyAgICAgKiAgICAgICAgICAgICBvciBpZiB7QGNvZGUgZW5kfSBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZiB7QGNvZGUgY3NxfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ2hhckFycmF5V3JpdGVyIGFwcGVuZChDaGFyU2VxdWVuY2UgY3NxLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgaWYgKGNzcSA9PSBudWxsKSB7CisgICAgICAgICAgICBjc3EgPSAibnVsbCI7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIG91dHB1dCA9IGNzcS5zdWJTZXF1ZW5jZShzdGFydCwgZW5kKS50b1N0cmluZygpOworICAgICAgICB3cml0ZShvdXRwdXQsIDAsIG91dHB1dC5sZW5ndGgoKSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0NoYXJDb252ZXJzaW9uRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9DaGFyQ29udmVyc2lvbkV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYzODIyYzQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9DaGFyQ29udmVyc2lvbkV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworLyoqCisgKiBUaGUgdG9wIGxldmVsIGNsYXNzIGZvciBjaGFyYWN0ZXIgY29udmVyc2lvbiBleGNlcHRpb25zLgorICovCitwdWJsaWMgY2xhc3MgQ2hhckNvbnZlcnNpb25FeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODY4MDAxNjM1MjAxODQyNzAzMUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBDaGFyQ29udmVyc2lvbkV4Y2VwdGlvbn0gd2l0aCBpdHMgc3RhY2sgdHJhY2UKKyAgICAgKiBmaWxsZWQgaW4uCisgICAgICovCisgICAgcHVibGljIENoYXJDb252ZXJzaW9uRXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIENoYXJDb252ZXJzaW9uRXhjZXB0aW9ufSB3aXRoIGl0cyBzdGFjayB0cmFjZSBhbmQKKyAgICAgKiBkZXRhaWwgbWVzc2FnZSBmaWxsZWQgaW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2hhckNvbnZlcnNpb25FeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vQ2xvc2VhYmxlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9DbG9zZWFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOTI5ZTdjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vQ2xvc2VhYmxlLmphdmEKQEAgLTAsMCArMSwzMyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCisvKioKKyAqIEFuIHtAY29kZSBBdXRvQ2xvc2VhYmxlfSB3aG9zZSBjbG9zZSBtZXRob2QgbWF5IHRocm93IGFuIHtAbGluayBJT0V4Y2VwdGlvbn0uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQ2xvc2VhYmxlIGV4dGVuZHMgQXV0b0Nsb3NlYWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhlIG9iamVjdCBhbmQgcmVsZWFzZSBhbnkgc3lzdGVtIHJlc291cmNlcyBpdCBob2xkcy4KKyAgICAgKgorICAgICAqIDxwPkFsdGhvdWdoIG9ubHkgdGhlIGZpcnN0IGNhbGwgaGFzIGFueSBlZmZlY3QsIGl0IGlzIHNhZmUgdG8gY2FsbCBjbG9zZQorICAgICAqIG11bHRpcGxlIHRpbWVzIG9uIHRoZSBzYW1lIG9iamVjdC4gVGhpcyBpcyBtb3JlIGxlbmllbnQgdGhhbiB0aGUKKyAgICAgKiBvdmVycmlkZGVuIHtAY29kZSBBdXRvQ2xvc2VhYmxlLmNsb3NlKCl9LCB3aGljaCBtYXkgYmUgY2FsbGVkIGF0IG1vc3QKKyAgICAgKiBvbmNlLgorICAgICAqLworICAgIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9Db25zb2xlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9Db25zb2xlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTFkMjA5NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0NvbnNvbGUuamF2YQpAQCAtMCwwICsxLDIwNyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEudXRpbC5Gb3JtYXR0ZXI7CitpbXBvcnQgbGliY29yZS5pby5FcnJub0V4Y2VwdGlvbjsKK2ltcG9ydCBsaWJjb3JlLmlvLkxpYmNvcmU7CitpbXBvcnQgc3RhdGljIGxpYmNvcmUuaW8uT3NDb25zdGFudHMuKjsKKworLyoqCisgKiBQcm92aWRlcyBhY2Nlc3MgdG8gdGhlIGNvbnNvbGUsIGlmIGF2YWlsYWJsZS4gVGhlIHN5c3RlbS13aWRlIGluc3RhbmNlIGNhbgorICogYmUgYWNjZXNzZWQgdmlhIHtAbGluayBqYXZhLmxhbmcuU3lzdGVtI2NvbnNvbGV9LgorICogQHNpbmNlIDEuNgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQ29uc29sZSBpbXBsZW1lbnRzIEZsdXNoYWJsZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0IENPTlNPTEVfTE9DSyA9IG5ldyBPYmplY3QoKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbnNvbGUgY29uc29sZSA9IG1ha2VDb25zb2xlKCk7CisKKyAgICBwcml2YXRlIGZpbmFsIENvbnNvbGVSZWFkZXIgcmVhZGVyOworICAgIHByaXZhdGUgZmluYWwgUHJpbnRXcml0ZXIgd3JpdGVyOworCisgICAgLyoqCisgICAgICogU2VjcmV0IGFjY2Vzc29yIGZvciB7QGNvZGUgU3lzdGVtLmNvbnNvbGV9LgorICAgICAqIEBoaWRlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDb25zb2xlIGdldENvbnNvbGUoKSB7CisgICAgICAgIHJldHVybiBjb25zb2xlOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIENvbnNvbGUgbWFrZUNvbnNvbGUoKSB7CisgICAgICAgIC8vIFdlIGRvbid0IGNhcmUgYWJvdXQgc3RkZXJyLCBiZWNhdXNlIHRoaXMgY2xhc3Mgb25seSB1c2VzIHN0ZGluIGFuZCBzdGRvdXQuCisgICAgICAgIGlmICghTGliY29yZS5vcy5pc2F0dHkoRmlsZURlc2NyaXB0b3IuaW4pIHx8ICFMaWJjb3JlLm9zLmlzYXR0eShGaWxlRGVzY3JpcHRvci5vdXQpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBDb25zb2xlKFN5c3RlbS5pbiwgU3lzdGVtLm91dCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBDb25zb2xlKElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLnJlYWRlciA9IG5ldyBDb25zb2xlUmVhZGVyKGluKTsKKyAgICAgICAgdGhpcy53cml0ZXIgPSBuZXcgQ29uc29sZVdyaXRlcihvdXQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgeworICAgICAgICB3cml0ZXIuZmx1c2goKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBmb3JtYXR0ZWQgc3RyaW5nIHRvIHRoZSBjb25zb2xlIHVzaW5nCisgICAgICogdGhlIHNwZWNpZmllZCBmb3JtYXQgc3RyaW5nIGFuZCBhcmd1bWVudHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9ybWF0IHRoZSBmb3JtYXQgc3RyaW5nIChzZWUge0BsaW5rIGphdmEudXRpbC5Gb3JtYXR0ZXIjZm9ybWF0fSkKKyAgICAgKiBAcGFyYW0gYXJncworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgZm9ybWF0dGVyLiBJZiB0aGVyZSBhcmUKKyAgICAgKiAgICAgICAgICAgIG1vcmUgYXJndW1lbnRzIHRoYW4gcmVxdWlyZWQgYnkge0Bjb2RlIGZvcm1hdH0sCisgICAgICogICAgICAgICAgICBhZGRpdGlvbmFsIGFyZ3VtZW50cyBhcmUgaWdub3JlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBjb25zb2xlIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBDb25zb2xlIGZvcm1hdChTdHJpbmcgZm9ybWF0LCBPYmplY3QuLi4gYXJncykgeworICAgICAgICBGb3JtYXR0ZXIgZiA9IG5ldyBGb3JtYXR0ZXIod3JpdGVyKTsKKyAgICAgICAgZi5mb3JtYXQoZm9ybWF0LCBhcmdzKTsKKyAgICAgICAgZi5mbHVzaCgpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVpdmFsZW50IHRvIHtAY29kZSBmb3JtYXQoZm9ybWF0LCBhcmdzKX0uCisgICAgICovCisgICAgcHVibGljIENvbnNvbGUgcHJpbnRmKFN0cmluZyBmb3JtYXQsIE9iamVjdC4uLiBhcmdzKSB7CisgICAgICAgIHJldHVybiBmb3JtYXQoZm9ybWF0LCBhcmdzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGxpbmsgUmVhZGVyfSBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb25zb2xlLgorICAgICAqLworICAgIHB1YmxpYyBSZWFkZXIgcmVhZGVyKCkgeworICAgICAgICByZXR1cm4gcmVhZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgbGluZSBmcm9tIHRoZSBjb25zb2xlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGluZSwgb3IgbnVsbCBhdCBFT0YuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyByZWFkTGluZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiByZWFkZXIucmVhZExpbmUoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGxpbmUgZnJvbSB0aGlzIGNvbnNvbGUsIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvbXB0LgorICAgICAqIFRoZSBwcm9tcHQgaXMgZ2l2ZW4gYXMgYSBmb3JtYXQgc3RyaW5nIGFuZCBvcHRpb25hbCBhcmd1bWVudHMuCisgICAgICogTm90ZSB0aGF0IHRoaXMgY2FuIGJlIGEgc291cmNlIG9mIGVycm9yczogaWYgaXQgaXMgcG9zc2libGUgdGhhdCB5b3VyCisgICAgICogcHJvbXB0IGNvbnRhaW5zIHtAY29kZSAlfSBjaGFyYWN0ZXJzLCB5b3UgbXVzdCB1c2UgdGhlIGZvcm1hdCBzdHJpbmcge0Bjb2RlICIlcyJ9CisgICAgICogYW5kIHBhc3MgdGhlIGFjdHVhbCBwcm9tcHQgYXMgYSBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9ybWF0IHRoZSBmb3JtYXQgc3RyaW5nIChzZWUge0BsaW5rIGphdmEudXRpbC5Gb3JtYXR0ZXIjZm9ybWF0fSkKKyAgICAgKiBAcGFyYW0gYXJncworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgZm9ybWF0dGVyLiBJZiB0aGVyZSBhcmUKKyAgICAgKiAgICAgICAgICAgIG1vcmUgYXJndW1lbnRzIHRoYW4gcmVxdWlyZWQgYnkge0Bjb2RlIGZvcm1hdH0sCisgICAgICogICAgICAgICAgICBhZGRpdGlvbmFsIGFyZ3VtZW50cyBhcmUgaWdub3JlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBsaW5lLCBvciBudWxsIGF0IEVPRi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHJlYWRMaW5lKFN0cmluZyBmb3JtYXQsIE9iamVjdC4uLiBhcmdzKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoQ09OU09MRV9MT0NLKSB7CisgICAgICAgICAgICBmb3JtYXQoZm9ybWF0LCBhcmdzKTsKKyAgICAgICAgICAgIHJldHVybiByZWFkTGluZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBwYXNzd29yZCBmcm9tIHRoZSBjb25zb2xlLiBUaGUgcGFzc3dvcmQgd2lsbCBub3QgYmUgZWNob2VkIHRvIHRoZSBkaXNwbGF5LgorICAgICAqCisgICAgICogQHJldHVybiBhIGNoYXJhY3RlciBhcnJheSBjb250YWluaW5nIHRoZSBwYXNzd29yZCwgb3IgbnVsbCBhdCBFT0YuCisgICAgICovCisgICAgcHVibGljIGNoYXJbXSByZWFkUGFzc3dvcmQoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoQ09OU09MRV9MT0NLKSB7CisgICAgICAgICAgICBpbnQgcHJldmlvdXNTdGF0ZSA9IHNldEVjaG8oZmFsc2UsIDApOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgcGFzc3dvcmQgPSByZWFkTGluZSgpOworICAgICAgICAgICAgICAgIHdyaXRlci5wcmludGxuKCk7IC8vIFdlIHdvbid0IGhhdmUgZWNob2VkIHRoZSB1c2VyJ3MgbmV3bGluZS4KKyAgICAgICAgICAgICAgICByZXR1cm4gKHBhc3N3b3JkID09IG51bGwpID8gbnVsbCA6IHBhc3N3b3JkLnRvQ2hhckFycmF5KCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHNldEVjaG8odHJ1ZSwgcHJldmlvdXNTdGF0ZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgc2V0RWNobyhib29sZWFuIG9uLCBpbnQgcHJldmlvdXNTdGF0ZSkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHNldEVjaG9JbXBsKG9uLCBwcmV2aW91c1N0YXRlKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0Vycm9yKGV4KTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IHNldEVjaG9JbXBsKGJvb2xlYW4gb24sIGludCBwcmV2aW91c1N0YXRlKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHBhc3N3b3JkIGZyb20gdGhlIGNvbnNvbGUuIFRoZSBwYXNzd29yZCB3aWxsIG5vdCBiZSBlY2hvZWQgdG8gdGhlIGRpc3BsYXkuCisgICAgICogQSBmb3JtYXR0ZWQgcHJvbXB0IGlzIGFsc28gZGlzcGxheWVkLgorICAgICAqCisgICAgICogQHBhcmFtIGZvcm1hdCB0aGUgZm9ybWF0IHN0cmluZyAoc2VlIHtAbGluayBqYXZhLnV0aWwuRm9ybWF0dGVyI2Zvcm1hdH0pCisgICAgICogQHBhcmFtIGFyZ3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IG9mIGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhlIGZvcm1hdHRlci4gSWYgdGhlcmUgYXJlCisgICAgICogICAgICAgICAgICBtb3JlIGFyZ3VtZW50cyB0aGFuIHJlcXVpcmVkIGJ5IHtAY29kZSBmb3JtYXR9LAorICAgICAqICAgICAgICAgICAgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIGlnbm9yZWQuCisgICAgICogQHJldHVybiBhIGNoYXJhY3RlciBhcnJheSBjb250YWluaW5nIHRoZSBwYXNzd29yZCwgb3IgbnVsbCBhdCBFT0YuCisgICAgICovCisgICAgcHVibGljIGNoYXJbXSByZWFkUGFzc3dvcmQoU3RyaW5nIGZvcm1hdCwgT2JqZWN0Li4uIGFyZ3MpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChDT05TT0xFX0xPQ0spIHsKKyAgICAgICAgICAgIGZvcm1hdChmb3JtYXQsIGFyZ3MpOworICAgICAgICAgICAgcmV0dXJuIHJlYWRQYXNzd29yZCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0BsaW5rIFdyaXRlcn0gYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29uc29sZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpbnRXcml0ZXIgd3JpdGVyKCkgeworICAgICAgICByZXR1cm4gd3JpdGVyOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIENvbnNvbGVSZWFkZXIgZXh0ZW5kcyBCdWZmZXJlZFJlYWRlciB7CisgICAgICAgIHB1YmxpYyBDb25zb2xlUmVhZGVyKElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKGluLCBTeXN0ZW0uZ2V0UHJvcGVydHkoImZpbGUuZW5jb2RpbmciKSksIDI1Nik7CisgICAgICAgICAgICBsb2NrID0gQ09OU09MRV9MT0NLOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgeworICAgICAgICAgICAgLy8gQ29uc29sZS5yZWFkZXIgY2Fubm90IGJlIGNsb3NlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIENvbnNvbGVXcml0ZXIgZXh0ZW5kcyBQcmludFdyaXRlciB7CisgICAgICAgIHB1YmxpYyBDb25zb2xlV3JpdGVyKE91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgICAgIHN1cGVyKG91dCwgdHJ1ZSk7CisgICAgICAgICAgICBsb2NrID0gQ09OU09MRV9MT0NLOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgeworICAgICAgICAgICAgLy8gQ29uc29sZS53cml0ZXIgY2Fubm90IGJlIGNsb3NlZC4KKyAgICAgICAgICAgIGZsdXNoKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9EYXRhSW5wdXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0RhdGFJbnB1dC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwMmQyN2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9EYXRhSW5wdXQuamF2YQpAQCAtMCwwICsxLDI0MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCisvKioKKyAqIERlZmluZXMgYW4gaW50ZXJmYWNlIGZvciBjbGFzc2VzIHRoYXQgYXJlIGFibGUgdG8gcmVhZCBiaWctZW5kaWFuIHR5cGVkIGRhdGEgZnJvbSBzb21lCisgKiBzb3VyY2UuIFR5cGljYWxseSwgdGhpcyBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gYnkgYSBjbGFzcyB3aGljaCBpbXBsZW1lbnRzCisgKiB7QGxpbmsgRGF0YU91dHB1dH0uIFR5cGVzIHRoYXQgY2FuIGJlIHJlYWQgaW5jbHVkZSBieXRlLCAxNi1iaXQgc2hvcnQsIDMyLWJpdAorICogaW50LCAzMi1iaXQgZmxvYXQsIDY0LWJpdCBsb25nLCA2NC1iaXQgZG91YmxlLCBieXRlIHN0cmluZ3MsIGFuZCBNVVRGLTgKKyAqIHN0cmluZ3MuCisgKgorICogPGgzPk1VVEYtOCAoTW9kaWZpZWQgVVRGLTgpIEVuY29kaW5nPC9oMz4KKyAqIDxwPgorICogV2hlbiBlbmNvZGluZyBzdHJpbmdzIGFzIFVURiwgaW1wbGVtZW50YXRpb25zIG9mIHtAY29kZSBEYXRhSW5wdXR9IGFuZAorICoge0Bjb2RlIERhdGFPdXRwdXR9IHVzZSBhIHNsaWdodGx5IG1vZGlmaWVkIGZvcm0gb2YgVVRGLTgsIGhlcmVhZnRlciByZWZlcnJlZAorICogdG8gYXMgTVVURi04LiBUaGlzIGZvcm0gaXMgaWRlbnRpY2FsIHRvIHN0YW5kYXJkIFVURi04LCBleGNlcHQ6CisgKiA8dWw+CisgKiA8bGk+T25seSB0aGUgb25lLSwgdHdvLSwgYW5kIHRocmVlLWJ5dGUgZW5jb2RpbmdzIGFyZSB1c2VkLjwvbGk+CisgKiA8bGk+Q29kZSBwb2ludHMgaW4gdGhlIHJhbmdlIDxjb2RlPlUrMTAwMDA8L2NvZGU+ICZoZWxsaXA7CisgKiA8Y29kZT5VKzEwZmZmZjwvY29kZT4gYXJlIGVuY29kZWQgYXMgYSBzdXJyb2dhdGUgcGFpciwgZWFjaCBvZiB3aGljaCBpcworICogcmVwcmVzZW50ZWQgYXMgYSB0aHJlZS1ieXRlIGVuY29kZWQgdmFsdWUuPC9saT4KKyAqIDxsaT5UaGUgY29kZSBwb2ludCA8Y29kZT5VKzAwMDA8L2NvZGU+IGlzIGVuY29kZWQgaW4gdHdvLWJ5dGUgZm9ybS48L2xpPgorICogPC91bD4KKyAqIDxwPgorICogUGxlYXNlIHJlZmVyIHRvIDxhIGhyZWY9Imh0dHA6Ly91bmljb2RlLm9yZyI+VGhlIFVuaWNvZGUgU3RhbmRhcmQ8L2E+IGZvcgorICogZnVydGhlciBpbmZvcm1hdGlvbiBhYm91dCBjaGFyYWN0ZXIgZW5jb2RpbmcuIE1VVEYtOCBpcyBhY3R1YWxseSBjbG9zZXIgdG8KKyAqIHRoZSAocmVsYXRpdmVseSBsZXNzIHdlbGwta25vd24pIGVuY29kaW5nIDxhCisgKiBocmVmPSJodHRwOi8vd3d3LnVuaWNvZGUub3JnL3JlcG9ydHMvdHIyNi8iPkNFU1UtODwvYT4gdGhhbiB0byBVVEYtOCBwZXIgc2UuCisgKgorICogQHNlZSBEYXRhSW5wdXRTdHJlYW0KKyAqIEBzZWUgUmFuZG9tQWNjZXNzRmlsZQorICovCitwdWJsaWMgaW50ZXJmYWNlIERhdGFJbnB1dCB7CisgICAgLyoqCisgICAgICogUmVhZHMgYSBib29sZWFuLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBib29sZWFuIHZhbHVlLgorICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIGlmIHRoZSBlbmQgb2YgdGhlIGlucHV0IGlzIHJlYWNoZWQgYmVmb3JlIHRoZSByZWFkCisgICAgICogICAgICAgICByZXF1ZXN0IGNhbiBiZSBzYXRpc2ZpZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZy4KKyAgICAgKiBAc2VlIERhdGFPdXRwdXQjd3JpdGVCb29sZWFuKGJvb2xlYW4pCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gcmVhZEJvb2xlYW4oKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhbiA4LWJpdCBieXRlIHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBieXRlIHZhbHVlLgorICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIGlmIHRoZSBlbmQgb2YgdGhlIGlucHV0IGlzIHJlYWNoZWQgYmVmb3JlIHRoZSByZWFkCisgICAgICogICAgICAgICByZXF1ZXN0IGNhbiBiZSBzYXRpc2ZpZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZy4KKyAgICAgKiBAc2VlIERhdGFPdXRwdXQjd3JpdGVCeXRlKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYnl0ZSByZWFkQnl0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgYmlnLWVuZGlhbiAxNi1iaXQgY2hhcmFjdGVyIHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBjaGFyIHZhbHVlLgorICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIGlmIHRoZSBlbmQgb2YgdGhlIGlucHV0IGlzIHJlYWNoZWQgYmVmb3JlIHRoZSByZWFkCisgICAgICogICAgICAgICByZXF1ZXN0IGNhbiBiZSBzYXRpc2ZpZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZy4KKyAgICAgKiBAc2VlIERhdGFPdXRwdXQjd3JpdGVDaGFyKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgY2hhciByZWFkQ2hhcigpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgYmlnLWVuZGlhbiA2NC1iaXQgZG91YmxlIHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBkb3VibGUgdmFsdWUuCisgICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gaWYgdGhlIGVuZCBvZiB0aGUgaW5wdXQgaXMgcmVhY2hlZCBiZWZvcmUgdGhlIHJlYWQKKyAgICAgKiAgICAgICAgIHJlcXVlc3QgY2FuIGJlIHNhdGlzZmllZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nLgorICAgICAqIEBzZWUgRGF0YU91dHB1dCN3cml0ZURvdWJsZShkb3VibGUpCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGRvdWJsZSByZWFkRG91YmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgYSBiaWctZW5kaWFuIDMyLWJpdCBmbG9hdCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgZmxvYXQgdmFsdWUuCisgICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gaWYgdGhlIGVuZCBvZiB0aGUgaW5wdXQgaXMgcmVhY2hlZCBiZWZvcmUgdGhlIHJlYWQKKyAgICAgKiAgICAgICAgIHJlcXVlc3QgY2FuIGJlIHNhdGlzZmllZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nLgorICAgICAqIEBzZWUgRGF0YU91dHB1dCN3cml0ZUZsb2F0KGZsb2F0KQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBmbG9hdCByZWFkRmxvYXQoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBFcXVpdmFsZW50IHRvIHtAY29kZSByZWFkRnVsbHkoZHN0LCAwLCBkc3QubGVuZ3RoKTt9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHJlYWRGdWxseShieXRlW10gZHN0KSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB7QGNvZGUgYnl0ZUNvdW50fSBieXRlcyBmcm9tIHRoaXMgc3RyZWFtIGFuZCBzdG9yZXMgdGhlbSBpbiB0aGUgYnl0ZQorICAgICAqIGFycmF5IHtAY29kZSBkc3R9IHN0YXJ0aW5nIGF0IHtAY29kZSBvZmZzZXR9LiBJZiB7QGNvZGUgYnl0ZUNvdW50fSBpcyB6ZXJvLCB0aGVuIHRoaXMKKyAgICAgKiBtZXRob2QgcmV0dXJucyB3aXRob3V0IHJlYWRpbmcgYW55IGJ5dGVzLiBPdGhlcndpc2UsIHRoaXMgbWV0aG9kIGJsb2NrcyB1bnRpbAorICAgICAqIHtAY29kZSBieXRlQ291bnR9IGJ5dGVzIGhhdmUgYmVlbiByZWFkLiBJZiBpbnN1ZmZpY2llbnQgYnl0ZXMgYXJlIGF2YWlsYWJsZSwKKyAgICAgKiB7QGNvZGUgRU9GRXhjZXB0aW9ufSBpcyB0aHJvd24uIElmIGFuIEkvTyBlcnJvciBvY2N1cnMsIHtAY29kZSBJT0V4Y2VwdGlvbn0gaXMKKyAgICAgKiB0aHJvd24uIFdoZW4gYW4gZXhjZXB0aW9uIGlzIHRocm93biwgc29tZSBieXRlcyBtYXkgaGF2ZSBiZWVuIGNvbnN1bWVkIGZyb20gdGhlIHN0cmVhbQorICAgICAqIGFuZCB3cml0dGVuIGludG8gdGhlIGFycmF5LgorICAgICAqCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYXJyYXkgaW50byB3aGljaCB0aGUgZGF0YSBpcyByZWFkLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4ge0Bjb2RlIGRzdH0gYXQgd2hpY2ggdG8gc3RvcmUgdGhlIGJ5dGVzLgorICAgICAqIEBwYXJhbSBieXRlQ291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZC4KKyAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSBzdHJlYW0gaXMgcmVhY2hlZCBiZWZvcmUgZW5vdWdoCisgICAgICogICAgICAgICAgICAgYnl0ZXMgaGF2ZSBiZWVuIHJlYWQuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBieXRlQ291bnQgPCAwfSwgb3IKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgb2Zmc2V0ICsgYnl0ZUNvdW50ID4gZHN0Lmxlbmd0aH0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnMgd2hpbGUgcmVhZGluZyBmcm9tIHRoaXMgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZHN0fSBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHJlYWRGdWxseShieXRlW10gZHN0LCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGJpZy1lbmRpYW4gMzItYml0IGludGVnZXIgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGludCB2YWx1ZS4KKyAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbiBpZiB0aGUgZW5kIG9mIHRoZSBpbnB1dCBpcyByZWFjaGVkIGJlZm9yZSB0aGUgcmVhZAorICAgICAqICAgICAgICAgcmVxdWVzdCBjYW4gYmUgc2F0aXNmaWVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcuCisgICAgICogQHNlZSBEYXRhT3V0cHV0I3dyaXRlSW50KGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IHJlYWRJbnQoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIG5leHQgbGluZSBvZiB0ZXh0IGF2YWlsYWJsZSBmcm9tIHRoaXMKKyAgICAgKiBzdHJlYW0uIEEgbGluZSBpcyBtYWRlIG9mIHplcm8gb3IgbW9yZSBjaGFyYWN0ZXJzIGZvbGxvd2VkIGJ5IHtAY29kZQorICAgICAqICdcbid9LCB7QGNvZGUgJ1xyJ30sIHtAY29kZSAiXHJcbiJ9IG9yIHRoZSBlbmQgb2YgdGhlIHN0cmVhbS4gVGhlIHN0cmluZworICAgICAqIGRvZXMgbm90IGluY2x1ZGUgdGhlIG5ld2xpbmUgc2VxdWVuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb250ZW50cyBvZiB0aGUgbGluZSBvciBudWxsIGlmIG5vIGNoYXJhY3RlcnMgaGF2ZSBiZWVuIHJlYWQKKyAgICAgKiAgICAgICAgIGJlZm9yZSB0aGUgZW5kIG9mIHRoZSBzdHJlYW0uCisgICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gaWYgdGhlIGVuZCBvZiB0aGUgaW5wdXQgaXMgcmVhY2hlZCBiZWZvcmUgdGhlIHJlYWQKKyAgICAgKiAgICAgICAgIHJlcXVlc3QgY2FuIGJlIHNhdGlzZmllZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgcmVhZExpbmUoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGJpZy1lbmRpYW4gNjQtYml0IGxvbmcgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGxvbmcgdmFsdWUuCisgICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gaWYgdGhlIGVuZCBvZiB0aGUgaW5wdXQgaXMgcmVhY2hlZCBiZWZvcmUgdGhlIHJlYWQKKyAgICAgKiAgICAgICAgIHJlcXVlc3QgY2FuIGJlIHNhdGlzZmllZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nLgorICAgICAqIEBzZWUgRGF0YU91dHB1dCN3cml0ZUxvbmcobG9uZykKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgbG9uZyByZWFkTG9uZygpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgYmlnLWVuZGlhbiAxNi1iaXQgc2hvcnQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IHNob3J0IHZhbHVlLgorICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIGlmIHRoZSBlbmQgb2YgdGhlIGlucHV0IGlzIHJlYWNoZWQgYmVmb3JlIHRoZSByZWFkCisgICAgICogICAgICAgICByZXF1ZXN0IGNhbiBiZSBzYXRpc2ZpZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZy4KKyAgICAgKiBAc2VlIERhdGFPdXRwdXQjd3JpdGVTaG9ydChpbnQpCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHNob3J0IHJlYWRTaG9ydCgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIGFuIHVuc2lnbmVkIDgtYml0IGJ5dGUgdmFsdWUgYW5kIHJldHVybnMgaXQgYXMgYW4gaW50LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCB1bnNpZ25lZCBieXRlIHZhbHVlLgorICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIGlmIHRoZSBlbmQgb2YgdGhlIGlucHV0IGlzIHJlYWNoZWQgYmVmb3JlIHRoZSByZWFkCisgICAgICogICAgICAgICByZXF1ZXN0IGNhbiBiZSBzYXRpc2ZpZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZy4KKyAgICAgKiBAc2VlIERhdGFPdXRwdXQjd3JpdGVCeXRlKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IHJlYWRVbnNpZ25lZEJ5dGUoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGJpZy1lbmRpYW4gMTYtYml0IHVuc2lnbmVkIHNob3J0IHZhbHVlIGFuZCByZXR1cm5zIGl0IGFzIGFuIGludC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgdW5zaWduZWQgc2hvcnQgdmFsdWUuCisgICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gaWYgdGhlIGVuZCBvZiB0aGUgaW5wdXQgaXMgcmVhY2hlZCBiZWZvcmUgdGhlIHJlYWQKKyAgICAgKiAgICAgICAgIHJlcXVlc3QgY2FuIGJlIHNhdGlzZmllZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nLgorICAgICAqIEBzZWUgRGF0YU91dHB1dCN3cml0ZVNob3J0KGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IHJlYWRVbnNpZ25lZFNob3J0KCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgYSBzdHJpbmcgZW5jb2RlZCB3aXRoIHtAbGluayBEYXRhSW5wdXQgbW9kaWZpZWQgVVRGLTh9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBzdHJpbmcgZW5jb2RlZCB3aXRoIHtAbGluayBEYXRhSW5wdXQgbW9kaWZpZWQgVVRGLTh9LgorICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIGlmIHRoZSBlbmQgb2YgdGhlIGlucHV0IGlzIHJlYWNoZWQgYmVmb3JlIHRoZSByZWFkCisgICAgICogICAgICAgICByZXF1ZXN0IGNhbiBiZSBzYXRpc2ZpZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZy4KKyAgICAgKiBAc2VlIERhdGFPdXRwdXQjd3JpdGVVVEYoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIHJlYWRVVEYoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTa2lwcyB7QGNvZGUgY291bnR9IG51bWJlciBvZiBieXRlcy4gVGhpcyBtZXRob2Qgd2lsbCBub3QgdGhyb3cgYW4KKyAgICAgKiB7QGxpbmsgRU9GRXhjZXB0aW9ufSBpZiB0aGUgZW5kIG9mIHRoZSBpbnB1dCBpcyByZWFjaGVkIGJlZm9yZQorICAgICAqIHtAY29kZSBjb3VudH0gYnl0ZXMgd2hlcmUgc2tpcHBlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyB0byBza2lwLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSBza2lwcGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHByb2JsZW0gb2NjdXJzIGR1cmluZyBza2lwcGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IHNraXBCeXRlcyhpbnQgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0RhdGFJbnB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRGF0YUlucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzgyNjg1MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0RhdGFJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMjI2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKK2ltcG9ydCBqYXZhLm5pby5CeXRlT3JkZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5Nb2RpZmllZFV0Zjg7CitpbXBvcnQgbGliY29yZS5pby5NZW1vcnk7CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworaW1wb3J0IGxpYmNvcmUuaW8uU2l6ZU9mOworCisvKioKKyAqIFdyYXBzIGFuIGV4aXN0aW5nIHtAbGluayBJbnB1dFN0cmVhbX0gYW5kIHJlYWRzIGJpZy1lbmRpYW4gdHlwZWQgZGF0YSBmcm9tIGl0LgorICogVHlwaWNhbGx5LCB0aGlzIHN0cmVhbSBoYXMgYmVlbiB3cml0dGVuIGJ5IGEgRGF0YU91dHB1dFN0cmVhbS4gVHlwZXMgdGhhdCBjYW4KKyAqIGJlIHJlYWQgaW5jbHVkZSBieXRlLCAxNi1iaXQgc2hvcnQsIDMyLWJpdCBpbnQsIDMyLWJpdCBmbG9hdCwgNjQtYml0IGxvbmcsCisgKiA2NC1iaXQgZG91YmxlLCBieXRlIHN0cmluZ3MsIGFuZCBzdHJpbmdzIGVuY29kZWQgaW4KKyAqIHtAbGluayBEYXRhSW5wdXQgbW9kaWZpZWQgVVRGLTh9LgorICoKKyAqIEBzZWUgRGF0YU91dHB1dFN0cmVhbQorICovCitwdWJsaWMgY2xhc3MgRGF0YUlucHV0U3RyZWFtIGV4dGVuZHMgRmlsdGVySW5wdXRTdHJlYW0gaW1wbGVtZW50cyBEYXRhSW5wdXQgeworCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gc2NyYXRjaCA9IG5ldyBieXRlWzhdOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBEYXRhSW5wdXRTdHJlYW0gb24gdGhlIElucHV0U3RyZWFtIHtAY29kZSBpbn0uIEFsbAorICAgICAqIHJlYWRzIGFyZSB0aGVuIGZpbHRlcmVkIHRocm91Z2ggdGhpcyBzdHJlYW0uIE5vdGUgdGhhdCBkYXRhIHJlYWQgYnkgdGhpcworICAgICAqIHN0cmVhbSBpcyBub3QgaW4gYSBodW1hbiByZWFkYWJsZSBmb3JtYXQgYW5kIHdhcyBtb3N0IGxpa2VseSBjcmVhdGVkIGJ5IGEKKyAgICAgKiBEYXRhT3V0cHV0U3RyZWFtLgorICAgICAqCisgICAgICogPHA+PHN0cm9uZz5XYXJuaW5nOjwvc3Ryb25nPiBwYXNzaW5nIGEgbnVsbCBzb3VyY2UgY3JlYXRlcyBhbiBpbnZhbGlkCisgICAgICoge0Bjb2RlIERhdGFJbnB1dFN0cmVhbX0uIEFsbCBvcGVyYXRpb25zIG9uIHN1Y2ggYSBzdHJlYW0gd2lsbCBmYWlsLgorICAgICAqCisgICAgICogQHBhcmFtIGluCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIElucHV0U3RyZWFtIHRoZSBmaWx0ZXIgcmVhZHMgZnJvbS4KKyAgICAgKiBAc2VlIERhdGFPdXRwdXRTdHJlYW0KKyAgICAgKiBAc2VlIFJhbmRvbUFjY2Vzc0ZpbGUKKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YUlucHV0U3RyZWFtKElucHV0U3RyZWFtIGluKSB7CisgICAgICAgIHN1cGVyKGluKTsKKyAgICB9CisKKyAgICAvLyBvdmVycmlkZGVuIHRvIGFkZCAnZmluYWwnCisgICAgQE92ZXJyaWRlIHB1YmxpYyBmaW5hbCBpbnQgcmVhZChieXRlW10gYnVmZmVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gc3VwZXIucmVhZChidWZmZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGF0IG1vc3Qge0Bjb2RlIGxlbmd0aH0gYnl0ZXMgZnJvbSB0aGlzIHN0cmVhbSBhbmQgc3RvcmVzIHRoZW0gaW4KKyAgICAgKiB0aGUgYnl0ZSBhcnJheSB7QGNvZGUgYnVmZmVyfSBzdGFydGluZyBhdCB7QGNvZGUgb2Zmc2V0fS4gUmV0dXJucyB0aGUKKyAgICAgKiBudW1iZXIgb2YgYnl0ZXMgdGhhdCBoYXZlIGJlZW4gcmVhZCBvciAtMSBpZiBubyBieXRlcyBoYXZlIGJlZW4gcmVhZCBhbmQKKyAgICAgKiB0aGUgZW5kIG9mIHRoZSBzdHJlYW0gaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGFycmF5IGluIHdoaWNoIHRvIHN0b3JlIHRoZSBieXRlcyByZWFkLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIHBvc2l0aW9uIGluIHtAY29kZSBidWZmZXJ9IHRvIHN0b3JlIHRoZSBieXRlcworICAgICAqICAgICAgICAgICAgcmVhZCBmcm9tIHRoaXMgc3RyZWFtLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0byBzdG9yZSBpbiB7QGNvZGUgYnVmZmVyfS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBoYXZlIGJlZW4gcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZQorICAgICAqICAgICAgICAgc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnMgd2hpbGUgcmVhZGluZyBmcm9tIHRoaXMgc3RyZWFtLgorICAgICAqIEBzZWUgRGF0YU91dHB1dCN3cml0ZShieXRlW10pCisgICAgICogQHNlZSBEYXRhT3V0cHV0I3dyaXRlKGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGludCByZWFkKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBpbi5yZWFkKGJ1ZmZlciwgb2Zmc2V0LCBsZW5ndGgpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIHJlYWRCb29sZWFuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHRlbXAgPSBpbi5yZWFkKCk7CisgICAgICAgIGlmICh0ZW1wIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0ZW1wICE9IDA7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIGJ5dGUgcmVhZEJ5dGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgdGVtcCA9IGluLnJlYWQoKTsKKyAgICAgICAgaWYgKHRlbXAgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChieXRlKSB0ZW1wOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBjaGFyIHJlYWRDaGFyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIChjaGFyKSByZWFkU2hvcnQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgZG91YmxlIHJlYWREb3VibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gRG91YmxlLmxvbmdCaXRzVG9Eb3VibGUocmVhZExvbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIGZsb2F0IHJlYWRGbG9hdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBGbG9hdC5pbnRCaXRzVG9GbG9hdChyZWFkSW50KCkpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHJlYWRGdWxseShieXRlW10gZHN0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZWFkRnVsbHkoZHN0LCAwLCBkc3QubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCByZWFkRnVsbHkoYnl0ZVtdIGRzdCwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyZWFtcy5yZWFkRnVsbHkoaW4sIGRzdCwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBpbnQgcmVhZEludCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmVhbXMucmVhZEZ1bGx5KGluLCBzY3JhdGNoLCAwLCBTaXplT2YuSU5UKTsKKyAgICAgICAgcmV0dXJuIE1lbW9yeS5wZWVrSW50KHNjcmF0Y2gsIDAsIEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICB9CisKKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgcmVhZExpbmUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmdCdWlsZGVyIGxpbmUgPSBuZXcgU3RyaW5nQnVpbGRlcig4MCk7IC8vIFR5cGljYWwgbGluZSBsZW5ndGgKKyAgICAgICAgYm9vbGVhbiBmb3VuZFRlcm1pbmF0b3IgPSBmYWxzZTsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIGludCBuZXh0Qnl0ZSA9IGluLnJlYWQoKTsKKyAgICAgICAgICAgIHN3aXRjaCAobmV4dEJ5dGUpIHsKKyAgICAgICAgICAgICAgICBjYXNlIC0xOgorICAgICAgICAgICAgICAgICAgICBpZiAobGluZS5sZW5ndGgoKSA9PSAwICYmICFmb3VuZFRlcm1pbmF0b3IpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBsaW5lLnRvU3RyaW5nKCk7CisgICAgICAgICAgICAgICAgY2FzZSAoYnl0ZSkgJ1xyJzoKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kVGVybWluYXRvcikgeworICAgICAgICAgICAgICAgICAgICAgICAgKChQdXNoYmFja0lucHV0U3RyZWFtKSBpbikudW5yZWFkKG5leHRCeXRlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBsaW5lLnRvU3RyaW5nKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZm91bmRUZXJtaW5hdG9yID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgLyogSGF2ZSB0byBiZSBhYmxlIHRvIHBlZWsgYWhlYWQgb25lIGJ5dGUgKi8KKyAgICAgICAgICAgICAgICAgICAgaWYgKCEoaW4uZ2V0Q2xhc3MoKSA9PSBQdXNoYmFja0lucHV0U3RyZWFtLmNsYXNzKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaW4gPSBuZXcgUHVzaGJhY2tJbnB1dFN0cmVhbShpbik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAoYnl0ZSkgJ1xuJzoKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxpbmUudG9TdHJpbmcoKTsKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICBpZiAoZm91bmRUZXJtaW5hdG9yKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAoKFB1c2hiYWNrSW5wdXRTdHJlYW0pIGluKS51bnJlYWQobmV4dEJ5dGUpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxpbmUudG9TdHJpbmcoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBsaW5lLmFwcGVuZCgoY2hhcikgbmV4dEJ5dGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIGxvbmcgcmVhZExvbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJlYW1zLnJlYWRGdWxseShpbiwgc2NyYXRjaCwgMCwgU2l6ZU9mLkxPTkcpOworICAgICAgICByZXR1cm4gTWVtb3J5LnBlZWtMb25nKHNjcmF0Y2gsIDAsIEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgc2hvcnQgcmVhZFNob3J0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyZWFtcy5yZWFkRnVsbHkoaW4sIHNjcmF0Y2gsIDAsIFNpemVPZi5TSE9SVCk7CisgICAgICAgIHJldHVybiBNZW1vcnkucGVla1Nob3J0KHNjcmF0Y2gsIDAsIEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgaW50IHJlYWRVbnNpZ25lZEJ5dGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgdGVtcCA9IGluLnJlYWQoKTsKKyAgICAgICAgaWYgKHRlbXAgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRlbXA7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIGludCByZWFkVW5zaWduZWRTaG9ydCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiAoKGludCkgcmVhZFNob3J0KCkpICYgMHhmZmZmOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgcmVhZFVURigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBkZWNvZGVVVEYocmVhZFVuc2lnbmVkU2hvcnQoKSk7CisgICAgfQorCisgICAgU3RyaW5nIGRlY29kZVVURihpbnQgdXRmU2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGRlY29kZVVURih1dGZTaXplLCB0aGlzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZGVjb2RlVVRGKGludCB1dGZTaXplLCBEYXRhSW5wdXQgaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVt1dGZTaXplXTsKKyAgICAgICAgaW4ucmVhZEZ1bGx5KGJ1ZiwgMCwgdXRmU2l6ZSk7CisgICAgICAgIHJldHVybiBNb2RpZmllZFV0ZjguZGVjb2RlKGJ1ZiwgbmV3IGNoYXJbdXRmU2l6ZV0sIDAsIHV0ZlNpemUpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIHJlYWRVVEYoRGF0YUlucHV0IGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZGVjb2RlVVRGKGluLnJlYWRVbnNpZ25lZFNob3J0KCksIGluKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTa2lwcyB7QGNvZGUgY291bnR9IG51bWJlciBvZiBieXRlcyBpbiB0aGlzIHN0cmVhbS4gU3Vic2VxdWVudCB7QGNvZGUKKyAgICAgKiByZWFkKCl9cyB3aWxsIG5vdCByZXR1cm4gdGhlc2UgYnl0ZXMgdW5sZXNzIHtAY29kZSByZXNldCgpfSBpcyB1c2VkLgorICAgICAqCisgICAgICogVGhpcyBtZXRob2Qgd2lsbCBub3QgdGhyb3cgYW4ge0BsaW5rIEVPRkV4Y2VwdGlvbn0gaWYgdGhlIGVuZCBvZiB0aGUKKyAgICAgKiBpbnB1dCBpcyByZWFjaGVkIGJlZm9yZSB7QGNvZGUgY291bnR9IGJ5dGVzIHdoZXJlIHNraXBwZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gc2tpcC4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgc2tpcHBlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycyBkdXJpbmcgc2tpcHBpbmcuCisgICAgICogQHNlZSAjbWFyayhpbnQpCisgICAgICogQHNlZSAjcmVzZXQoKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgc2tpcEJ5dGVzKGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHNraXBwZWQgPSAwOworICAgICAgICBsb25nIHNraXA7CisgICAgICAgIHdoaWxlIChza2lwcGVkIDwgY291bnQgJiYgKHNraXAgPSBpbi5za2lwKGNvdW50IC0gc2tpcHBlZCkpICE9IDApIHsKKyAgICAgICAgICAgIHNraXBwZWQgKz0gc2tpcDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2tpcHBlZDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9EYXRhT3V0cHV0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9EYXRhT3V0cHV0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjJhNWNkMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0RhdGFPdXRwdXQuamF2YQpAQCAtMCwwICsxLDE5NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCisvKioKKyAqIERlZmluZXMgYW4gaW50ZXJmYWNlIGZvciBjbGFzc2VzIHRoYXQgYXJlIGFibGUgdG8gd3JpdGUgYmlnLWVuZGlhbiB0eXBlZCBkYXRhIHRvIHNvbWUKKyAqIHRhcmdldC4gVHlwaWNhbGx5LCB0aGlzIGRhdGEgY2FuIGJlIHJlYWQgaW4gYnkgYSBjbGFzcyB3aGljaCBpbXBsZW1lbnRzCisgKiBEYXRhSW5wdXQuIFR5cGVzIHRoYXQgY2FuIGJlIHdyaXR0ZW4gaW5jbHVkZSBieXRlLCAxNi1iaXQgc2hvcnQsIDMyLWJpdCBpbnQsCisgKiAzMi1iaXQgZmxvYXQsIDY0LWJpdCBsb25nLCA2NC1iaXQgZG91YmxlLCBieXRlIHN0cmluZ3MsIGFuZCB7QGxpbmsgRGF0YUlucHV0CisgKiBNVVRGLTh9IGVuY29kZWQgc3RyaW5ncy4KKyAqCisgKiBAc2VlIERhdGFPdXRwdXRTdHJlYW0KKyAqIEBzZWUgUmFuZG9tQWNjZXNzRmlsZQorICovCitwdWJsaWMgaW50ZXJmYWNlIERhdGFPdXRwdXQgeworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBlbnRpcmUgY29udGVudHMgb2YgdGhlIGJ5dGUgYXJyYXkge0Bjb2RlIGJ1ZmZlcn0gdG8gdGhpcworICAgICAqIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXIgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB3cml0ZShieXRlW10gYnVmZmVyKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMge0Bjb2RlIGNvdW50fSBieXRlcyBmcm9tIHRoZSBieXRlIGFycmF5IHtAY29kZSBidWZmZXJ9IHN0YXJ0aW5nIGF0CisgICAgICogb2Zmc2V0IHtAY29kZSBpbmRleH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgYnl0ZSBpbiB7QGNvZGUgYnVmZmVyfSB0byB3cml0ZS4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgZnJvbSB0aGUge0Bjb2RlIGJ1ZmZlcn0gdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB3cml0ZShieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3BlY2lmaWVkIDgtYml0IGJ5dGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb25lQnl0ZQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZy4KKyAgICAgKiBAc2VlIERhdGFJbnB1dCNyZWFkQnl0ZSgpCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgd3JpdGUoaW50IG9uZUJ5dGUpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3BlY2lmaWVkIGJvb2xlYW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsCisgICAgICogICAgICAgICAgICB0aGUgYm9vbGVhbiB2YWx1ZSB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nLgorICAgICAqIEBzZWUgRGF0YUlucHV0I3JlYWRCb29sZWFuKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB3cml0ZUJvb2xlYW4oYm9vbGVhbiB2YWwpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3BlY2lmaWVkIDgtYml0IGJ5dGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSB2YWx1ZSB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nLgorICAgICAqIEBzZWUgRGF0YUlucHV0I3JlYWRCeXRlKCkKKyAgICAgKiBAc2VlIERhdGFJbnB1dCNyZWFkVW5zaWduZWRCeXRlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB3cml0ZUJ5dGUoaW50IHZhbCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBsb3cgb3JkZXIgOC1iaXQgYnl0ZXMgZnJvbSB0aGUgc3BlY2lmaWVkIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgY29udGFpbmluZyB0aGUgYnl0ZXMgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB3cml0ZUJ5dGVzKFN0cmluZyBzdHIpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3BlY2lmaWVkIDE2LWJpdCBjaGFyYWN0ZXIgaW4gYmlnLWVuZGlhbiBvcmRlci4gT25seSB0aGUgdHdvIGxlYXN0IHNpZ25pZmljYW50CisgICAgICogYnl0ZXMgb2YgdGhlIGludGVnZXIge0Bjb2RlIG9uZUJ5dGV9IGFyZSB3cml0dGVuLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nLgorICAgICAqIEBzZWUgRGF0YUlucHV0I3JlYWRDaGFyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB3cml0ZUNoYXIoaW50IHZhbCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSAxNi1iaXQgY2hhcmFjdGVycyBjb250YWluZWQgaW4ge0Bjb2RlIHN0cn0gaW4gYmlnLWVuZGlhbiBvcmRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdGhhdCBjb250YWlucyB0aGUgY2hhcmFjdGVycyB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nLgorICAgICAqIEBzZWUgRGF0YUlucHV0I3JlYWRDaGFyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB3cml0ZUNoYXJzKFN0cmluZyBzdHIpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3BlY2lmaWVkIDY0LWJpdCBkb3VibGUgaW4gYmlnLWVuZGlhbiBvcmRlci4gVGhlIHJlc3VsdGluZyBvdXRwdXQgaXMgdGhlIGVpZ2h0CisgICAgICogYnl0ZXMgcmV0dXJuZWQgYnkge0BsaW5rIERvdWJsZSNkb3VibGVUb0xvbmdCaXRzKGRvdWJsZSl9LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdGhlIGRvdWJsZSB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nLgorICAgICAqIEBzZWUgRGF0YUlucHV0I3JlYWREb3VibGUoKQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHdyaXRlRG91YmxlKGRvdWJsZSB2YWwpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3BlY2lmaWVkIDMyLWJpdCBmbG9hdCBpbiBiaWctZW5kaWFuIG9yZGVyLiBUaGUgcmVzdWx0aW5nIG91dHB1dCBpcyB0aGUgZm91ciBieXRlcworICAgICAqIHJldHVybmVkIGJ5IHtAbGluayBGbG9hdCNmbG9hdFRvSW50Qml0cyhmbG9hdCl9LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcuCisgICAgICogQHNlZSBEYXRhSW5wdXQjcmVhZEZsb2F0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB3cml0ZUZsb2F0KGZsb2F0IHZhbCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBzcGVjaWZpZWQgMzItYml0IGludCBpbiBiaWctZW5kaWFuIG9yZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdGhlIGludCB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nLgorICAgICAqIEBzZWUgRGF0YUlucHV0I3JlYWRJbnQoKQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHdyaXRlSW50KGludCB2YWwpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3BlY2lmaWVkIDY0LWJpdCBsb25nIGluIGJpZy1lbmRpYW4gb3JkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsCisgICAgICogICAgICAgICAgICB0aGUgbG9uZyB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nLgorICAgICAqIEBzZWUgRGF0YUlucHV0I3JlYWRMb25nKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB3cml0ZUxvbmcobG9uZyB2YWwpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3BlY2lmaWVkIDE2LWJpdCBzaG9ydCBpbiBiaWctZW5kaWFuIG9yZGVyLiBPbmx5IHRoZSBsb3dlciB0d28gYnl0ZXMgb2Yge0Bjb2RlCisgICAgICogdmFsfSBhcmUgd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaG9ydCB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nLgorICAgICAqIEBzZWUgRGF0YUlucHV0I3JlYWRTaG9ydCgpCisgICAgICogQHNlZSBEYXRhSW5wdXQjcmVhZFVuc2lnbmVkU2hvcnQoKQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHdyaXRlU2hvcnQoaW50IHZhbCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGVuY29kZWQgaW4ge0BsaW5rIERhdGFJbnB1dCBtb2RpZmllZCBVVEYtOH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHdyaXRlIGVuY29kZWQgaW4ge0BsaW5rIERhdGFJbnB1dCBtb2RpZmllZCBVVEYtOH0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZy4KKyAgICAgKiBAc2VlIERhdGFJbnB1dCNyZWFkVVRGKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB3cml0ZVVURihTdHJpbmcgc3RyKSB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9EYXRhT3V0cHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9EYXRhT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjcxZjE3NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0RhdGFPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDE5OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCitpbXBvcnQgamF2YS5uaW8uQnl0ZU9yZGVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuTW9kaWZpZWRVdGY4OworaW1wb3J0IGxpYmNvcmUuaW8uTWVtb3J5OworaW1wb3J0IGxpYmNvcmUuaW8uU2l6ZU9mOworCisvKioKKyAqIFdyYXBzIGFuIGV4aXN0aW5nIHtAbGluayBPdXRwdXRTdHJlYW19IGFuZCB3cml0ZXMgYmlnLWVuZGlhbiB0eXBlZCBkYXRhIHRvIGl0LgorICogVHlwaWNhbGx5LCB0aGlzIHN0cmVhbSBjYW4gYmUgcmVhZCBpbiBieSBEYXRhSW5wdXRTdHJlYW0uIFR5cGVzIHRoYXQgY2FuIGJlCisgKiB3cml0dGVuIGluY2x1ZGUgYnl0ZSwgMTYtYml0IHNob3J0LCAzMi1iaXQgaW50LCAzMi1iaXQgZmxvYXQsIDY0LWJpdCBsb25nLAorICogNjQtYml0IGRvdWJsZSwgYnl0ZSBzdHJpbmdzLCBhbmQge0BsaW5rIERhdGFJbnB1dCBNVVRGLTh9IGVuY29kZWQgc3RyaW5ncy4KKyAqCisgKiBAc2VlIERhdGFJbnB1dFN0cmVhbQorICovCitwdWJsaWMgY2xhc3MgRGF0YU91dHB1dFN0cmVhbSBleHRlbmRzIEZpbHRlck91dHB1dFN0cmVhbSBpbXBsZW1lbnRzIERhdGFPdXRwdXQgeworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIHNjcmF0Y2ggPSBuZXcgYnl0ZVs4XTsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiBvdXQgc28gZmFyLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgd3JpdHRlbjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIERhdGFPdXRwdXRTdHJlYW19IG9uIHRoZSB7QGNvZGUgT3V0cHV0U3RyZWFtfQorICAgICAqIHtAY29kZSBvdXR9LiBOb3RlIHRoYXQgZGF0YSB3cml0dGVuIGJ5IHRoaXMgc3RyZWFtIGlzIG5vdCBpbiBhIGh1bWFuCisgICAgICogcmVhZGFibGUgZm9ybSBidXQgY2FuIGJlIHJlY29uc3RydWN0ZWQgYnkgdXNpbmcgYSB7QGxpbmsgRGF0YUlucHV0U3RyZWFtfQorICAgICAqIG9uIHRoZSByZXN1bHRpbmcgb3V0cHV0LgorICAgICAqCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBzdHJlYW0gZm9yIHdyaXRpbmcuCisgICAgICovCisgICAgcHVibGljIERhdGFPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgICBzdXBlcihvdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZsdXNoZXMgdGhpcyBzdHJlYW0gdG8gZW5zdXJlIGFsbCBwZW5kaW5nIGRhdGEgaXMgc2VudCBvdXQgdG8gdGhlIHRhcmdldAorICAgICAqIHN0cmVhbS4gVGhpcyBpbXBsZW1lbnRhdGlvbiB0aGVuIGFsc28gZmx1c2hlcyB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYXR0ZW1wdGluZyB0byBmbHVzaCB0aGlzIHN0cmVhbS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLmZsdXNoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gdG8gdGhlIHRhcmdldCBzdHJlYW0gc28gZmFyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBzaXplKCkgeworICAgICAgICBpZiAod3JpdHRlbiA8IDApIHsKKyAgICAgICAgICAgIHdyaXR0ZW4gPSBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gd3JpdHRlbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMge0Bjb2RlIGNvdW50fSBieXRlcyBmcm9tIHRoZSBieXRlIGFycmF5IHtAY29kZSBidWZmZXJ9IHN0YXJ0aW5nIGF0CisgICAgICoge0Bjb2RlIG9mZnNldH0gdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHRvIHdyaXRlIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgYnl0ZSBpbiB7QGNvZGUgYnVmZmVyfSB0byB3cml0ZS4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgZnJvbSB0aGUge0Bjb2RlIGJ1ZmZlcn0gdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYnVmZmVyfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoYnVmZmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiYnVmZmVyID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBvdXQud3JpdGUoYnVmZmVyLCBvZmZzZXQsIGNvdW50KTsKKyAgICAgICAgd3JpdHRlbiArPSBjb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBieXRlIHRvIHRoZSB0YXJnZXQgc3RyZWFtLiBPbmx5IHRoZSBsZWFzdCBzaWduaWZpY2FudCBieXRlIG9mCisgICAgICogdGhlIGludGVnZXIge0Bjb2RlIG9uZUJ5dGV9IGlzIHdyaXR0ZW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb25lQnl0ZQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgdG8gd3JpdGUgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqIEBzZWUgRGF0YUlucHV0U3RyZWFtI3JlYWRCeXRlKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgb25lQnl0ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LndyaXRlKG9uZUJ5dGUpOworICAgICAgICB3cml0dGVuKys7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgYm9vbGVhbiB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBib29sZWFuIHZhbHVlIHRvIHdyaXRlIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKiBAc2VlIERhdGFJbnB1dFN0cmVhbSNyZWFkQm9vbGVhbigpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgd3JpdGVCb29sZWFuKGJvb2xlYW4gdmFsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXQud3JpdGUodmFsID8gMSA6IDApOworICAgICAgICB3cml0dGVuKys7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGFuIDgtYml0IGJ5dGUgdG8gdGhlIHRhcmdldCBzdHJlYW0uIE9ubHkgdGhlIGxlYXN0IHNpZ25pZmljYW50CisgICAgICogYnl0ZSBvZiB0aGUgaW50ZWdlciB7QGNvZGUgdmFsfSBpcyB3cml0dGVuLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgdmFsdWUgdG8gd3JpdGUgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqIEBzZWUgRGF0YUlucHV0U3RyZWFtI3JlYWRCeXRlKCkKKyAgICAgKiBAc2VlIERhdGFJbnB1dFN0cmVhbSNyZWFkVW5zaWduZWRCeXRlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB3cml0ZUJ5dGUoaW50IHZhbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LndyaXRlKHZhbCk7CisgICAgICAgIHdyaXR0ZW4rKzsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB3cml0ZUJ5dGVzKFN0cmluZyBzdHIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzdHIubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlW3N0ci5sZW5ndGgoKV07CisgICAgICAgIGZvciAoaW50IGluZGV4ID0gMDsgaW5kZXggPCBzdHIubGVuZ3RoKCk7IGluZGV4KyspIHsKKyAgICAgICAgICAgIGJ5dGVzW2luZGV4XSA9IChieXRlKSBzdHIuY2hhckF0KGluZGV4KTsKKyAgICAgICAgfQorICAgICAgICBvdXQud3JpdGUoYnl0ZXMpOworICAgICAgICB3cml0dGVuICs9IGJ5dGVzLmxlbmd0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB3cml0ZUNoYXIoaW50IHZhbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGVTaG9ydCh2YWwpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHdyaXRlQ2hhcnMoU3RyaW5nIHN0cikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0gc3RyLmdldEJ5dGVzKCJVVEYtMTZCRSIpOworICAgICAgICBvdXQud3JpdGUoYnl0ZXMpOworICAgICAgICB3cml0dGVuICs9IGJ5dGVzLmxlbmd0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB3cml0ZURvdWJsZShkb3VibGUgdmFsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3cml0ZUxvbmcoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHModmFsKSk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHZvaWQgd3JpdGVGbG9hdChmbG9hdCB2YWwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlSW50KEZsb2F0LmZsb2F0VG9JbnRCaXRzKHZhbCkpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHdyaXRlSW50KGludCB2YWwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIE1lbW9yeS5wb2tlSW50KHNjcmF0Y2gsIDAsIHZhbCwgQnl0ZU9yZGVyLkJJR19FTkRJQU4pOworICAgICAgICBvdXQud3JpdGUoc2NyYXRjaCwgMCwgU2l6ZU9mLklOVCk7CisgICAgICAgIHdyaXR0ZW4gKz0gU2l6ZU9mLklOVDsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB3cml0ZUxvbmcobG9uZyB2YWwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIE1lbW9yeS5wb2tlTG9uZyhzY3JhdGNoLCAwLCB2YWwsIEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICAgICAgb3V0LndyaXRlKHNjcmF0Y2gsIDAsIFNpemVPZi5MT05HKTsKKyAgICAgICAgd3JpdHRlbiArPSBTaXplT2YuTE9ORzsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB3cml0ZVNob3J0KGludCB2YWwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIE1lbW9yeS5wb2tlU2hvcnQoc2NyYXRjaCwgMCwgKHNob3J0KSB2YWwsIEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICAgICAgb3V0LndyaXRlKHNjcmF0Y2gsIDAsIFNpemVPZi5TSE9SVCk7CisgICAgICAgIHdyaXR0ZW4gKz0gU2l6ZU9mLlNIT1JUOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHdyaXRlVVRGKFN0cmluZyBzdHIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlKE1vZGlmaWVkVXRmOC5lbmNvZGUoc3RyKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRU9GRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9FT0ZFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNDk2ZDE0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRU9GRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCisvKioKKyAqIFRocm93biB3aGVuIGEgcHJvZ3JhbSBlbmNvdW50ZXJzIHRoZSBlbmQgb2YgYSBmaWxlIG9yIHN0cmVhbSBkdXJpbmcgYW4gaW5wdXQKKyAqIG9wZXJhdGlvbi4KKyAqLworcHVibGljIGNsYXNzIEVPRkV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDY0MzM4NTgyMjM3NzQ4ODY5NzdMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRU9GRXhjZXB0aW9ufSB3aXRoIGl0cyBzdGFjayB0cmFjZSBmaWxsZWQgaW4uCisgICAgICovCisgICAgcHVibGljIEVPRkV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBFT0ZFeGNlcHRpb259IHdpdGggaXRzIHN0YWNrIHRyYWNlIGFuZCBkZXRhaWwKKyAgICAgKiBtZXNzYWdlIGZpbGxlZCBpbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBFT0ZFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRW11bGF0ZWRGaWVsZHMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0VtdWxhdGVkRmllbGRzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjNlZmFlZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0VtdWxhdGVkRmllbGRzLmphdmEKQEAgLTAsMCArMSw1NDcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworLyoqCisgKiBBbiBFbXVsYXRlZEZpZWxkcyBpcyBhbiBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgc2V0IG9mIGVtdWxhdGVkIGZpZWxkcyBmb3IKKyAqIGFuIG9iamVjdCBiZWluZyBkdW1wZWQgb3IgbG9hZGVkLiBJdCBhbGxvd3Mgb2JqZWN0cyB0byBiZSBkdW1wZWQgd2l0aCBhIHNoYXBlCisgKiBkaWZmZXJlbnQgdGhhbiB0aGUgZmllbGRzIHRoZXkgd2VyZSBkZWNsYXJlZCB0byBoYXZlLgorICoKKyAqIEBzZWUgT2JqZWN0SW5wdXRTdHJlYW0uR2V0RmllbGQKKyAqIEBzZWUgT2JqZWN0T3V0cHV0U3RyZWFtLlB1dEZpZWxkCisgKiBAc2VlIEVtdWxhdGVkRmllbGRzRm9yTG9hZGluZworICogQHNlZSBFbXVsYXRlZEZpZWxkc0ZvckR1bXBpbmcKKyAqLworY2xhc3MgRW11bGF0ZWRGaWVsZHMgeworCisgICAgLy8gQSBzbG90IGlzIGEgZmllbGQgcGx1cyBpdHMgdmFsdWUKKyAgICBzdGF0aWMgY2xhc3MgT2JqZWN0U2xvdCB7CisKKyAgICAgICAgLy8gRmllbGQgZGVzY3JpcHRvcgorICAgICAgICBPYmplY3RTdHJlYW1GaWVsZCBmaWVsZDsKKworICAgICAgICAvLyBBY3R1YWwgdmFsdWUgdGhpcyBlbXVsYXRlZCBmaWVsZCBob2xkcworICAgICAgICBPYmplY3QgZmllbGRWYWx1ZTsKKworICAgICAgICAvLyBJZiB0aGlzIGZpZWxkIGhhcyBhIGRlZmF1bHQgdmFsdWUgKHRydWUpIG9yIHNvbWV0aGluZyBoYXMgYmVlbgorICAgICAgICAvLyBhc3NpZ25lZCAoZmFsc2UpCisgICAgICAgIGJvb2xlYW4gZGVmYXVsdGVkID0gdHJ1ZTsKKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgZGVzY3JpcHRvciBmb3IgdGhpcyBlbXVsYXRlZCBmaWVsZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUgZmllbGQgZGVzY3JpcHRvcgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIE9iamVjdFN0cmVhbUZpZWxkIGdldEZpZWxkKCkgeworICAgICAgICAgICAgcmV0dXJuIGZpZWxkOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIHZhbHVlIGhlbGQgYnkgdGhpcyBlbXVsYXRlZCBmaWVsZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUgZmllbGQgdmFsdWUKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBmaWVsZFZhbHVlOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gVGhlIGNvbGxlY3Rpb24gb2Ygc2xvdHMgdGhlIHJlY2VpdmVyIHJlcHJlc2VudHMKKyAgICBwcml2YXRlIE9iamVjdFNsb3RbXSBzbG90c1RvU2VyaWFsaXplOworCisgICAgcHJpdmF0ZSBPYmplY3RTdHJlYW1GaWVsZFtdIGRlY2xhcmVkRmllbGRzOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiBFbXVsYXRlZEZpZWxkcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZHMKKyAgICAgKiAgICAgICAgICAgIGFuIGFycmF5IG9mIE9iamVjdFN0cmVhbUZpZWxkcywgd2hpY2ggZGVzY3JpYmUgdGhlIGZpZWxkcyB0bworICAgICAqICAgICAgICAgICAgYmUgZW11bGF0ZWQgKG5hbWVzLCB0eXBlcywgZXRjKS4KKyAgICAgKiBAcGFyYW0gZGVjbGFyZWQKKyAgICAgKiAgICAgICAgICAgIGFuIGFycmF5IG9mIE9iamVjdFN0cmVhbUZpZWxkcywgd2hpY2ggZGVzY3JpYmUgdGhlIGRlY2xhcmVkCisgICAgICogICAgICAgICAgICBmaWVsZHMuCisgICAgICovCisgICAgcHVibGljIEVtdWxhdGVkRmllbGRzKE9iamVjdFN0cmVhbUZpZWxkW10gZmllbGRzLCBPYmplY3RTdHJlYW1GaWVsZFtdIGRlY2xhcmVkKSB7CisgICAgICAgIC8vIFdlIGFzc3VtZSB0aGUgc2xvdHMgYXJlIGFscmVhZHkgc29ydGVkIGluIHRoZSByaWdodCBzaGFwZSBmb3IgZHVtcGluZworICAgICAgICBidWlsZFNsb3RzKGZpZWxkcyk7CisgICAgICAgIGRlY2xhcmVkRmllbGRzID0gZGVjbGFyZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQnVpbGQgZW11bGF0ZWQgc2xvdHMgdGhhdCBjb3JyZXNwb25kIHRvIGVtdWxhdGVkIGZpZWxkcy4gQSBzbG90IGlzIGEKKyAgICAgKiBmaWVsZCBkZXNjcmlwdG9yIChPYmplY3RTdHJlYW1GaWVsZCkgcGx1cyB0aGUgYWN0dWFsIHZhbHVlIGl0IGhvbGRzLgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkcworICAgICAqICAgICAgICAgICAgYW4gYXJyYXkgb2YgT2JqZWN0U3RyZWFtRmllbGQsIHdoaWNoIGRlc2NyaWJlIHRoZSBmaWVsZHMgdG8gYmUKKyAgICAgKiAgICAgICAgICAgIGVtdWxhdGVkIChuYW1lcywgdHlwZXMsIGV0YykuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkU2xvdHMoT2JqZWN0U3RyZWFtRmllbGRbXSBmaWVsZHMpIHsKKyAgICAgICAgc2xvdHNUb1NlcmlhbGl6ZSA9IG5ldyBPYmplY3RTbG90W2ZpZWxkcy5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgT2JqZWN0U2xvdCBzID0gbmV3IE9iamVjdFNsb3QoKTsKKyAgICAgICAgICAgIHNsb3RzVG9TZXJpYWxpemVbaV0gPSBzOworICAgICAgICAgICAgcy5maWVsZCA9IGZpZWxkc1tpXTsKKyAgICAgICAgfQorICAgICAgICAvLyBXZSBhc3N1bWUgdGhlIHNsb3RzIGFyZSBhbHJlYWR5IHNvcnRlZCBpbiB0aGUgcmlnaHQgc2hhcGUgZm9yIGR1bXBpbmcKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpbmRpY2F0aW5nIHRoZSBmaWVsZCBjYWxsZWQge0Bjb2RlIG5hbWV9IGhhcyBub3QgaGFkCisgICAgICogYSB2YWx1ZSBleHBsaWNpdGx5IGFzc2lnbmVkIGFuZCB0aGF0IGl0IHN0aWxsIGhvbGRzIGEgZGVmYXVsdCB2YWx1ZSBmb3IKKyAgICAgKiBpdHMgdHlwZSwgb3Ige0Bjb2RlIGZhbHNlfSBpbmRpY2F0aW5nIHRoYXQgdGhlIGZpZWxkIG5hbWVkIGhhcyBiZWVuCisgICAgICogYXNzaWduZWQgYSB2YWx1ZSBleHBsaWNpdGx5LgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byB0ZXN0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBuYW1lfSBzdGlsbCBob2xkcyBpdHMgZGVmYXVsdCB2YWx1ZSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBuYW1lfSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBkZWZhdWx0ZWQoU3RyaW5nIG5hbWUpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBPYmplY3RTbG90IHNsb3QgPSBmaW5kU2xvdChuYW1lLCBudWxsKTsKKyAgICAgICAgaWYgKHNsb3QgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibm8gZmllbGQgJyIgKyBuYW1lICsgIiciKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2xvdC5kZWZhdWx0ZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgYW5kIHJldHVybnMgYW4gT2JqZWN0U2xvdCB0aGF0IGNvcnJlc3BvbmRzIHRvIGEgZmllbGQgbmFtZWQge0Bjb2RlCisgICAgICogZmllbGROYW1lfSBhbmQgdHlwZSB7QGNvZGUgZmllbGRUeXBlfS4gSWYgdGhlIGZpZWxkIHR5cGUge0Bjb2RlCisgICAgICogZmllbGRUeXBlfSBjb3JyZXNwb25kcyB0byBhIHByaW1pdGl2ZSB0eXBlLCB0aGUgZmllbGQgdHlwZSBoYXMgdG8gbWF0Y2gKKyAgICAgKiBleGFjdGx5IG9yIHtAY29kZSBudWxsfSBpcyByZXR1cm5lZC4gSWYgdGhlIGZpZWxkIHR5cGUge0Bjb2RlIGZpZWxkVHlwZX0KKyAgICAgKiBjb3JyZXNwb25kcyB0byBhbiBvYmplY3QgdHlwZSwgdGhlIGZpZWxkIHR5cGUgaGFzIHRvIGJlIGNvbXBhdGlibGUgaW4KKyAgICAgKiB0ZXJtcyBvZiBhc3NpZ25tZW50LCBvciBudWxsIGlzIHJldHVybmVkLiBJZiB7QGNvZGUgZmllbGRUeXBlfSBpcyB7QGNvZGUKKyAgICAgKiBudWxsfSwgbm8gc3VjaCBjb21wYXRpYmlsaXR5IGNoZWNraW5nIGlzIHBlcmZvcm1lZCBhbmQgdGhlIHNsb3QgaXMKKyAgICAgKiByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBmaW5kCisgICAgICogQHBhcmFtIGZpZWxkVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHR5cGUgb2YgdGhlIGZpZWxkLiBUaGlzIHdpbGwgYmUgdXNlZCB0byB0ZXN0CisgICAgICogICAgICAgICAgICBjb21wYXRpYmlsaXR5LiBJZiB7QGNvZGUgbnVsbH0sIG5vIHRlc3RpbmcgaXMgZG9uZSwgdGhlCisgICAgICogICAgICAgICAgICBjb3JyZXNwb25kaW5nIHNsb3QgaXMgcmV0dXJuZWQuCisgICAgICogQHJldHVybiB0aGUgb2JqZWN0IHNsb3QsIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSBpcyBubyBmaWVsZCB3aXRoIHRoYXQKKyAgICAgKiAgICAgICAgIG5hbWUsIG9yIG5vIGNvbXBhdGlibGUgZmllbGQgKHJlbGF0aXZlIHRvIHtAY29kZSBmaWVsZFR5cGV9KQorICAgICAqLworICAgIHByaXZhdGUgT2JqZWN0U2xvdCBmaW5kU2xvdChTdHJpbmcgZmllbGROYW1lLCBDbGFzczw/PiBmaWVsZFR5cGUpIHsKKyAgICAgICAgYm9vbGVhbiBpc1ByaW1pdGl2ZSA9IGZpZWxkVHlwZSAhPSBudWxsICYmIGZpZWxkVHlwZS5pc1ByaW1pdGl2ZSgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNsb3RzVG9TZXJpYWxpemUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIE9iamVjdFNsb3Qgc2xvdCA9IHNsb3RzVG9TZXJpYWxpemVbaV07CisgICAgICAgICAgICBpZiAoc2xvdC5maWVsZC5nZXROYW1lKCkuZXF1YWxzKGZpZWxkTmFtZSkpIHsKKyAgICAgICAgICAgICAgICBpZiAoaXNQcmltaXRpdmUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gTG9va2luZyBmb3IgYSBwcmltaXRpdmUgdHlwZSBmaWVsZC4gVHlwZXMgbXVzdCBtYXRjaAorICAgICAgICAgICAgICAgICAgICAvLyAqZXhhY3RseSoKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNsb3QuZmllbGQuZ2V0VHlwZSgpID09IGZpZWxkVHlwZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNsb3Q7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAvLyBMb29raW5nIGZvciBhIG5vbi1wcmltaXRpdmUgdHlwZSBmaWVsZC4KKyAgICAgICAgICAgICAgICAgICAgaWYgKGZpZWxkVHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2xvdDsgLy8gTnVsbCBtZWFucyB3ZSB0YWtlIGFueXRoaW5nCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgLy8gVHlwZXMgbXVzdCBiZSBjb21wYXRpYmxlIChhc3NpZ25tZW50KQorICAgICAgICAgICAgICAgICAgICBpZiAoc2xvdC5maWVsZC5nZXRUeXBlKCkuaXNBc3NpZ25hYmxlRnJvbShmaWVsZFR5cGUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2xvdDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChkZWNsYXJlZEZpZWxkcyAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlY2xhcmVkRmllbGRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgT2JqZWN0U3RyZWFtRmllbGQgZmllbGQgPSBkZWNsYXJlZEZpZWxkc1tpXTsKKyAgICAgICAgICAgICAgICBpZiAoZmllbGQuZ2V0TmFtZSgpLmVxdWFscyhmaWVsZE5hbWUpKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChpc1ByaW1pdGl2ZSA/IGZpZWxkVHlwZSA9PSBmaWVsZC5nZXRUeXBlKCkgOiBmaWVsZFR5cGUgPT0gbnVsbCB8fAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLmdldFR5cGUoKS5pc0Fzc2lnbmFibGVGcm9tKGZpZWxkVHlwZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFNsb3Qgc2xvdCA9IG5ldyBPYmplY3RTbG90KCk7CisgICAgICAgICAgICAgICAgICAgICAgICBzbG90LmZpZWxkID0gZmllbGQ7CisgICAgICAgICAgICAgICAgICAgICAgICBzbG90LmRlZmF1bHRlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2xvdDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwcml2YXRlIE9iamVjdFNsb3QgZmluZE1hbmRhdG9yeVNsb3QoU3RyaW5nIG5hbWUsIENsYXNzPD8+IHR5cGUpIHsKKyAgICAgICAgT2JqZWN0U2xvdCBzbG90ID0gZmluZFNsb3QobmFtZSwgdHlwZSk7CisgICAgICAgIGlmIChzbG90ID09IG51bGwgfHwgKHR5cGUgPT0gbnVsbCAmJiBzbG90LmZpZWxkLmdldFR5cGUoKS5pc1ByaW1pdGl2ZSgpKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibm8gZmllbGQgJyIgKyBuYW1lICsgIicgb2YgdHlwZSAiICsgdHlwZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNsb3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgYW5kIHJldHVybnMgdGhlIGJ5dGUgdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCB7QGNvZGUgbmFtZX0KKyAgICAgKiBpbiB0aGUgcmVjZWl2ZXIuIElmIHRoZSBmaWVsZCBoYXMgbm90IGJlZW4gYXNzaWduZWQgYW55IHZhbHVlIHlldCwgdGhlCisgICAgICogZGVmYXVsdCB2YWx1ZSB7QGNvZGUgZGVmYXVsdFZhbHVlfSBpcyByZXR1cm5lZCBpbnN0ZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBmaW5kLgorICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHJldHVybiB2YWx1ZSBpbiBjYXNlIHRoZSBmaWVsZCBoYXMgbm90IGJlZW4gYXNzaWduZWQgdG8geWV0LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBmaWVsZCBpZiBpdCBoYXMgYmVlbiBhc3NpZ25lZCwgdGhlIGRlZmF1bHQKKyAgICAgKiAgICAgICAgIHZhbHVlIG90aGVyd2lzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNvcnJlc3BvbmRpbmcgZmllbGQgY2FuIG5vdCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZSBnZXQoU3RyaW5nIG5hbWUsIGJ5dGUgZGVmYXVsdFZhbHVlKSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0U2xvdCBzbG90ID0gZmluZE1hbmRhdG9yeVNsb3QobmFtZSwgYnl0ZS5jbGFzcyk7CisgICAgICAgIHJldHVybiBzbG90LmRlZmF1bHRlZCA/IGRlZmF1bHRWYWx1ZSA6ICgoQnl0ZSkgc2xvdC5maWVsZFZhbHVlKS5ieXRlVmFsdWUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kcyBhbmQgcmV0dXJucyB0aGUgY2hhciB2YWx1ZSBvZiBhIGdpdmVuIGZpZWxkIG5hbWVkIHtAY29kZSBuYW1lfSBpbiB0aGUKKyAgICAgKiByZWNlaXZlci4gSWYgdGhlIGZpZWxkIGhhcyBub3QgYmVlbiBhc3NpZ25lZCBhbnkgdmFsdWUgeWV0LCB0aGUgZGVmYXVsdAorICAgICAqIHZhbHVlIHtAY29kZSBkZWZhdWx0VmFsdWV9IGlzIHJldHVybmVkIGluc3RlYWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGZpbmQuCisgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAqICAgICAgICAgICAgcmV0dXJuIHZhbHVlIGluIGNhc2UgdGhlIGZpZWxkIGhhcyBub3QgYmVlbiBhc3NpZ25lZCB0byB5ZXQuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuIGZpZWxkIGlmIGl0IGhhcyBiZWVuIGFzc2lnbmVkLCB0aGUgZGVmYXVsdAorICAgICAqICAgICAgICAgdmFsdWUgb3RoZXJ3aXNlLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY29ycmVzcG9uZGluZyBmaWVsZCBjYW4gbm90IGJlIGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBjaGFyIGdldChTdHJpbmcgbmFtZSwgY2hhciBkZWZhdWx0VmFsdWUpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBPYmplY3RTbG90IHNsb3QgPSBmaW5kTWFuZGF0b3J5U2xvdChuYW1lLCBjaGFyLmNsYXNzKTsKKyAgICAgICAgcmV0dXJuIHNsb3QuZGVmYXVsdGVkID8gZGVmYXVsdFZhbHVlIDogKChDaGFyYWN0ZXIpIHNsb3QuZmllbGRWYWx1ZSkuY2hhclZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgYW5kIHJldHVybnMgdGhlIGRvdWJsZSB2YWx1ZSBvZiBhIGdpdmVuIGZpZWxkIG5hbWVkIHtAY29kZSBuYW1lfQorICAgICAqIGluIHRoZSByZWNlaXZlci4gSWYgdGhlIGZpZWxkIGhhcyBub3QgYmVlbiBhc3NpZ25lZCBhbnkgdmFsdWUgeWV0LCB0aGUKKyAgICAgKiBkZWZhdWx0IHZhbHVlIHtAY29kZSBkZWZhdWx0VmFsdWV9IGlzIHJldHVybmVkIGluc3RlYWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGZpbmQuCisgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAqICAgICAgICAgICAgcmV0dXJuIHZhbHVlIGluIGNhc2UgdGhlIGZpZWxkIGhhcyBub3QgYmVlbiBhc3NpZ25lZCB0byB5ZXQuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuIGZpZWxkIGlmIGl0IGhhcyBiZWVuIGFzc2lnbmVkLCB0aGUgZGVmYXVsdAorICAgICAqICAgICAgICAgdmFsdWUgb3RoZXJ3aXNlLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY29ycmVzcG9uZGluZyBmaWVsZCBjYW4gbm90IGJlIGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgZ2V0KFN0cmluZyBuYW1lLCBkb3VibGUgZGVmYXVsdFZhbHVlKSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0U2xvdCBzbG90ID0gZmluZE1hbmRhdG9yeVNsb3QobmFtZSwgZG91YmxlLmNsYXNzKTsKKyAgICAgICAgcmV0dXJuIHNsb3QuZGVmYXVsdGVkID8gZGVmYXVsdFZhbHVlIDogKChEb3VibGUpIHNsb3QuZmllbGRWYWx1ZSkuZG91YmxlVmFsdWUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kcyBhbmQgcmV0dXJucyB0aGUgZmxvYXQgdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCB7QGNvZGUgbmFtZX0gaW4KKyAgICAgKiB0aGUgcmVjZWl2ZXIuIElmIHRoZSBmaWVsZCBoYXMgbm90IGJlZW4gYXNzaWduZWQgYW55IHZhbHVlIHlldCwgdGhlCisgICAgICogZGVmYXVsdCB2YWx1ZSB7QGNvZGUgZGVmYXVsdFZhbHVlfSBpcyByZXR1cm5lZCBpbnN0ZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBmaW5kLgorICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHJldHVybiB2YWx1ZSBpbiBjYXNlIHRoZSBmaWVsZCBoYXMgbm90IGJlZW4gYXNzaWduZWQgdG8geWV0LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBmaWVsZCBpZiBpdCBoYXMgYmVlbiBhc3NpZ25lZCwgdGhlIGRlZmF1bHQKKyAgICAgKiAgICAgICAgIHZhbHVlIG90aGVyd2lzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNvcnJlc3BvbmRpbmcgZmllbGQgY2FuIG5vdCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0KFN0cmluZyBuYW1lLCBmbG9hdCBkZWZhdWx0VmFsdWUpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBPYmplY3RTbG90IHNsb3QgPSBmaW5kTWFuZGF0b3J5U2xvdChuYW1lLCBmbG9hdC5jbGFzcyk7CisgICAgICAgIHJldHVybiBzbG90LmRlZmF1bHRlZCA/IGRlZmF1bHRWYWx1ZSA6ICgoRmxvYXQpIHNsb3QuZmllbGRWYWx1ZSkuZmxvYXRWYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIGFuZCByZXR1cm5zIHRoZSBpbnQgdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCB7QGNvZGUgbmFtZX0gaW4gdGhlCisgICAgICogcmVjZWl2ZXIuIElmIHRoZSBmaWVsZCBoYXMgbm90IGJlZW4gYXNzaWduZWQgYW55IHZhbHVlIHlldCwgdGhlIGRlZmF1bHQKKyAgICAgKiB2YWx1ZSB7QGNvZGUgZGVmYXVsdFZhbHVlfSBpcyByZXR1cm5lZCBpbnN0ZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBmaW5kLgorICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHJldHVybiB2YWx1ZSBpbiBjYXNlIHRoZSBmaWVsZCBoYXMgbm90IGJlZW4gYXNzaWduZWQgdG8geWV0LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBmaWVsZCBpZiBpdCBoYXMgYmVlbiBhc3NpZ25lZCwgdGhlIGRlZmF1bHQKKyAgICAgKiAgICAgICAgIHZhbHVlIG90aGVyd2lzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNvcnJlc3BvbmRpbmcgZmllbGQgY2FuIG5vdCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldChTdHJpbmcgbmFtZSwgaW50IGRlZmF1bHRWYWx1ZSkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdFNsb3Qgc2xvdCA9IGZpbmRNYW5kYXRvcnlTbG90KG5hbWUsIGludC5jbGFzcyk7CisgICAgICAgIHJldHVybiBzbG90LmRlZmF1bHRlZCA/IGRlZmF1bHRWYWx1ZSA6ICgoSW50ZWdlcikgc2xvdC5maWVsZFZhbHVlKS5pbnRWYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIGFuZCByZXR1cm5zIHRoZSBsb25nIHZhbHVlIG9mIGEgZ2l2ZW4gZmllbGQgbmFtZWQge0Bjb2RlIG5hbWV9IGluIHRoZQorICAgICAqIHJlY2VpdmVyLiBJZiB0aGUgZmllbGQgaGFzIG5vdCBiZWVuIGFzc2lnbmVkIGFueSB2YWx1ZSB5ZXQsIHRoZSBkZWZhdWx0CisgICAgICogdmFsdWUge0Bjb2RlIGRlZmF1bHRWYWx1ZX0gaXMgcmV0dXJuZWQgaW5zdGVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZmllbGQgdG8gZmluZC4KKyAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlCisgICAgICogICAgICAgICAgICByZXR1cm4gdmFsdWUgaW4gY2FzZSB0aGUgZmllbGQgaGFzIG5vdCBiZWVuIGFzc2lnbmVkIHRvIHlldC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZmllbGQgaWYgaXQgaGFzIGJlZW4gYXNzaWduZWQsIHRoZSBkZWZhdWx0CisgICAgICogICAgICAgICB2YWx1ZSBvdGhlcndpc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjb3JyZXNwb25kaW5nIGZpZWxkIGNhbiBub3QgYmUgZm91bmQuCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0KFN0cmluZyBuYW1lLCBsb25nIGRlZmF1bHRWYWx1ZSkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdFNsb3Qgc2xvdCA9IGZpbmRNYW5kYXRvcnlTbG90KG5hbWUsIGxvbmcuY2xhc3MpOworICAgICAgICByZXR1cm4gc2xvdC5kZWZhdWx0ZWQgPyBkZWZhdWx0VmFsdWUgOiAoKExvbmcpIHNsb3QuZmllbGRWYWx1ZSkubG9uZ1ZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgYW5kIHJldHVybnMgdGhlIE9iamVjdCB2YWx1ZSBvZiBhIGdpdmVuIGZpZWxkIG5hbWVkIHtAY29kZSBuYW1lfSBpbgorICAgICAqIHRoZSByZWNlaXZlci4gSWYgdGhlIGZpZWxkIGhhcyBub3QgYmVlbiBhc3NpZ25lZCBhbnkgdmFsdWUgeWV0LCB0aGUKKyAgICAgKiBkZWZhdWx0IHZhbHVlIHtAY29kZSBkZWZhdWx0VmFsdWV9IGlzIHJldHVybmVkIGluc3RlYWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGZpbmQuCisgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAqICAgICAgICAgICAgcmV0dXJuIHZhbHVlIGluIGNhc2UgdGhlIGZpZWxkIGhhcyBub3QgYmVlbiBhc3NpZ25lZCB0byB5ZXQuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuIGZpZWxkIGlmIGl0IGhhcyBiZWVuIGFzc2lnbmVkLCB0aGUgZGVmYXVsdAorICAgICAqICAgICAgICAgdmFsdWUgb3RoZXJ3aXNlLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY29ycmVzcG9uZGluZyBmaWVsZCBjYW4gbm90IGJlIGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0KFN0cmluZyBuYW1lLCBPYmplY3QgZGVmYXVsdFZhbHVlKSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0U2xvdCBzbG90ID0gZmluZE1hbmRhdG9yeVNsb3QobmFtZSwgbnVsbCk7CisgICAgICAgIHJldHVybiBzbG90LmRlZmF1bHRlZCA/IGRlZmF1bHRWYWx1ZSA6IHNsb3QuZmllbGRWYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kcyBhbmQgcmV0dXJucyB0aGUgc2hvcnQgdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCB7QGNvZGUgbmFtZX0gaW4KKyAgICAgKiB0aGUgcmVjZWl2ZXIuIElmIHRoZSBmaWVsZCBoYXMgbm90IGJlZW4gYXNzaWduZWQgYW55IHZhbHVlIHlldCwgdGhlCisgICAgICogZGVmYXVsdCB2YWx1ZSB7QGNvZGUgZGVmYXVsdFZhbHVlfSBpcyByZXR1cm5lZCBpbnN0ZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBmaW5kLgorICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHJldHVybiB2YWx1ZSBpbiBjYXNlIHRoZSBmaWVsZCBoYXMgbm90IGJlZW4gYXNzaWduZWQgdG8geWV0LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBmaWVsZCBpZiBpdCBoYXMgYmVlbiBhc3NpZ25lZCwgdGhlIGRlZmF1bHQKKyAgICAgKiAgICAgICAgIHZhbHVlIG90aGVyd2lzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNvcnJlc3BvbmRpbmcgZmllbGQgY2FuIG5vdCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2hvcnQgZ2V0KFN0cmluZyBuYW1lLCBzaG9ydCBkZWZhdWx0VmFsdWUpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBPYmplY3RTbG90IHNsb3QgPSBmaW5kTWFuZGF0b3J5U2xvdChuYW1lLCBzaG9ydC5jbGFzcyk7CisgICAgICAgIHJldHVybiBzbG90LmRlZmF1bHRlZCA/IGRlZmF1bHRWYWx1ZSA6ICgoU2hvcnQpIHNsb3QuZmllbGRWYWx1ZSkuc2hvcnRWYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIGFuZCByZXR1cm5zIHRoZSBib29sZWFuIHZhbHVlIG9mIGEgZ2l2ZW4gZmllbGQgbmFtZWQge0Bjb2RlIG5hbWV9IGluCisgICAgICogdGhlIHJlY2VpdmVyLiBJZiB0aGUgZmllbGQgaGFzIG5vdCBiZWVuIGFzc2lnbmVkIGFueSB2YWx1ZSB5ZXQsIHRoZQorICAgICAqIGRlZmF1bHQgdmFsdWUge0Bjb2RlIGRlZmF1bHRWYWx1ZX0gaXMgcmV0dXJuZWQgaW5zdGVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZmllbGQgdG8gZmluZC4KKyAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlCisgICAgICogICAgICAgICAgICByZXR1cm4gdmFsdWUgaW4gY2FzZSB0aGUgZmllbGQgaGFzIG5vdCBiZWVuIGFzc2lnbmVkIHRvIHlldC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZmllbGQgaWYgaXQgaGFzIGJlZW4gYXNzaWduZWQsIHRoZSBkZWZhdWx0CisgICAgICogICAgICAgICB2YWx1ZSBvdGhlcndpc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjb3JyZXNwb25kaW5nIGZpZWxkIGNhbiBub3QgYmUgZm91bmQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0KFN0cmluZyBuYW1lLCBib29sZWFuIGRlZmF1bHRWYWx1ZSkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdFNsb3Qgc2xvdCA9IGZpbmRNYW5kYXRvcnlTbG90KG5hbWUsIGJvb2xlYW4uY2xhc3MpOworICAgICAgICByZXR1cm4gc2xvdC5kZWZhdWx0ZWQgPyBkZWZhdWx0VmFsdWUgOiAoKEJvb2xlYW4pIHNsb3QuZmllbGRWYWx1ZSkuYm9vbGVhblZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZCBhbmQgc2V0IHRoZSBieXRlIHZhbHVlIG9mIGEgZ2l2ZW4gZmllbGQgbmFtZWQge0Bjb2RlIG5hbWV9IGluIHRoZQorICAgICAqIHJlY2VpdmVyLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBzZXQuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICBuZXcgdmFsdWUgZm9yIHRoZSBmaWVsZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNvcnJlc3BvbmRpbmcgZmllbGQgY2FuIG5vdCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXQoU3RyaW5nIG5hbWUsIGJ5dGUgdmFsdWUpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBPYmplY3RTbG90IHNsb3QgPSBmaW5kTWFuZGF0b3J5U2xvdChuYW1lLCBieXRlLmNsYXNzKTsKKyAgICAgICAgc2xvdC5maWVsZFZhbHVlID0gQnl0ZS52YWx1ZU9mKHZhbHVlKTsKKyAgICAgICAgc2xvdC5kZWZhdWx0ZWQgPSBmYWxzZTsgLy8gTm8gbG9uZ2VyIGRlZmF1bHQgdmFsdWUKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGFuZCBzZXQgdGhlIGNoYXIgdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCB7QGNvZGUgbmFtZX0gaW4gdGhlCisgICAgICogcmVjZWl2ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIHNldC4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIG5ldyB2YWx1ZSBmb3IgdGhlIGZpZWxkLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY29ycmVzcG9uZGluZyBmaWVsZCBjYW4gbm90IGJlIGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1dChTdHJpbmcgbmFtZSwgY2hhciB2YWx1ZSkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdFNsb3Qgc2xvdCA9IGZpbmRNYW5kYXRvcnlTbG90KG5hbWUsIGNoYXIuY2xhc3MpOworICAgICAgICBzbG90LmZpZWxkVmFsdWUgPSBDaGFyYWN0ZXIudmFsdWVPZih2YWx1ZSk7CisgICAgICAgIHNsb3QuZGVmYXVsdGVkID0gZmFsc2U7IC8vIE5vIGxvbmdlciBkZWZhdWx0IHZhbHVlCisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZCBhbmQgc2V0IHRoZSBkb3VibGUgdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCB7QGNvZGUgbmFtZX0gaW4gdGhlCisgICAgICogcmVjZWl2ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIHNldC4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIG5ldyB2YWx1ZSBmb3IgdGhlIGZpZWxkLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY29ycmVzcG9uZGluZyBmaWVsZCBjYW4gbm90IGJlIGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1dChTdHJpbmcgbmFtZSwgZG91YmxlIHZhbHVlKSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0U2xvdCBzbG90ID0gZmluZE1hbmRhdG9yeVNsb3QobmFtZSwgZG91YmxlLmNsYXNzKTsKKyAgICAgICAgc2xvdC5maWVsZFZhbHVlID0gRG91YmxlLnZhbHVlT2YodmFsdWUpOworICAgICAgICBzbG90LmRlZmF1bHRlZCA9IGZhbHNlOyAvLyBObyBsb25nZXIgZGVmYXVsdCB2YWx1ZQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmQgYW5kIHNldCB0aGUgZmxvYXQgdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCB7QGNvZGUgbmFtZX0gaW4gdGhlCisgICAgICogcmVjZWl2ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIHNldC4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIG5ldyB2YWx1ZSBmb3IgdGhlIGZpZWxkLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY29ycmVzcG9uZGluZyBmaWVsZCBjYW4gbm90IGJlIGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1dChTdHJpbmcgbmFtZSwgZmxvYXQgdmFsdWUpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBPYmplY3RTbG90IHNsb3QgPSBmaW5kTWFuZGF0b3J5U2xvdChuYW1lLCBmbG9hdC5jbGFzcyk7CisgICAgICAgIHNsb3QuZmllbGRWYWx1ZSA9IEZsb2F0LnZhbHVlT2YodmFsdWUpOworICAgICAgICBzbG90LmRlZmF1bHRlZCA9IGZhbHNlOyAvLyBObyBsb25nZXIgZGVmYXVsdCB2YWx1ZQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmQgYW5kIHNldCB0aGUgaW50IHZhbHVlIG9mIGEgZ2l2ZW4gZmllbGQgbmFtZWQge0Bjb2RlIG5hbWV9IGluIHRoZQorICAgICAqIHJlY2VpdmVyLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBzZXQuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICBuZXcgdmFsdWUgZm9yIHRoZSBmaWVsZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNvcnJlc3BvbmRpbmcgZmllbGQgY2FuIG5vdCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXQoU3RyaW5nIG5hbWUsIGludCB2YWx1ZSkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdFNsb3Qgc2xvdCA9IGZpbmRNYW5kYXRvcnlTbG90KG5hbWUsIGludC5jbGFzcyk7CisgICAgICAgIHNsb3QuZmllbGRWYWx1ZSA9IEludGVnZXIudmFsdWVPZih2YWx1ZSk7CisgICAgICAgIHNsb3QuZGVmYXVsdGVkID0gZmFsc2U7IC8vIE5vIGxvbmdlciBkZWZhdWx0IHZhbHVlCisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZCBhbmQgc2V0IHRoZSBsb25nIHZhbHVlIG9mIGEgZ2l2ZW4gZmllbGQgbmFtZWQge0Bjb2RlIG5hbWV9IGluIHRoZQorICAgICAqIHJlY2VpdmVyLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBzZXQuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICBuZXcgdmFsdWUgZm9yIHRoZSBmaWVsZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNvcnJlc3BvbmRpbmcgZmllbGQgY2FuIG5vdCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXQoU3RyaW5nIG5hbWUsIGxvbmcgdmFsdWUpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBPYmplY3RTbG90IHNsb3QgPSBmaW5kTWFuZGF0b3J5U2xvdChuYW1lLCBsb25nLmNsYXNzKTsKKyAgICAgICAgc2xvdC5maWVsZFZhbHVlID0gTG9uZy52YWx1ZU9mKHZhbHVlKTsKKyAgICAgICAgc2xvdC5kZWZhdWx0ZWQgPSBmYWxzZTsgLy8gTm8gbG9uZ2VyIGRlZmF1bHQgdmFsdWUKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGFuZCBzZXQgdGhlIE9iamVjdCB2YWx1ZSBvZiBhIGdpdmVuIGZpZWxkIG5hbWVkIHtAY29kZSBuYW1lfSBpbiB0aGUKKyAgICAgKiByZWNlaXZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZmllbGQgdG8gc2V0LgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgbmV3IHZhbHVlIGZvciB0aGUgZmllbGQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjb3JyZXNwb25kaW5nIGZpZWxkIGNhbiBub3QgYmUgZm91bmQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHV0KFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBDbGFzczw/PiB2YWx1ZUNsYXNzID0gbnVsbDsKKyAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgIHZhbHVlQ2xhc3MgPSB2YWx1ZS5nZXRDbGFzcygpOworICAgICAgICB9CisgICAgICAgIE9iamVjdFNsb3Qgc2xvdCA9IGZpbmRNYW5kYXRvcnlTbG90KG5hbWUsIHZhbHVlQ2xhc3MpOworICAgICAgICBzbG90LmZpZWxkVmFsdWUgPSB2YWx1ZTsKKyAgICAgICAgc2xvdC5kZWZhdWx0ZWQgPSBmYWxzZTsgLy8gTm8gbG9uZ2VyIGRlZmF1bHQgdmFsdWUKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGFuZCBzZXQgdGhlIHNob3J0IHZhbHVlIG9mIGEgZ2l2ZW4gZmllbGQgbmFtZWQge0Bjb2RlIG5hbWV9IGluIHRoZQorICAgICAqIHJlY2VpdmVyLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBzZXQuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICBuZXcgdmFsdWUgZm9yIHRoZSBmaWVsZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNvcnJlc3BvbmRpbmcgZmllbGQgY2FuIG5vdCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXQoU3RyaW5nIG5hbWUsIHNob3J0IHZhbHVlKSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0U2xvdCBzbG90ID0gZmluZE1hbmRhdG9yeVNsb3QobmFtZSwgc2hvcnQuY2xhc3MpOworICAgICAgICBzbG90LmZpZWxkVmFsdWUgPSBTaG9ydC52YWx1ZU9mKHZhbHVlKTsKKyAgICAgICAgc2xvdC5kZWZhdWx0ZWQgPSBmYWxzZTsgLy8gTm8gbG9uZ2VyIGRlZmF1bHQgdmFsdWUKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGFuZCBzZXQgdGhlIGJvb2xlYW4gdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCB7QGNvZGUgbmFtZX0gaW4gdGhlCisgICAgICogcmVjZWl2ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIHNldC4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIG5ldyB2YWx1ZSBmb3IgdGhlIGZpZWxkLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY29ycmVzcG9uZGluZyBmaWVsZCBjYW4gbm90IGJlIGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1dChTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdFNsb3Qgc2xvdCA9IGZpbmRNYW5kYXRvcnlTbG90KG5hbWUsIGJvb2xlYW4uY2xhc3MpOworICAgICAgICBzbG90LmZpZWxkVmFsdWUgPSBCb29sZWFuLnZhbHVlT2YodmFsdWUpOworICAgICAgICBzbG90LmRlZmF1bHRlZCA9IGZhbHNlOyAvLyBObyBsb25nZXIgZGVmYXVsdCB2YWx1ZQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgYXJyYXkgb2YgT2JqZWN0U2xvdCB0aGUgcmVjZWl2ZXIgcmVwcmVzZW50cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYXJyYXkgb2YgT2JqZWN0U2xvdCB0aGUgcmVjZWl2ZXIgcmVwcmVzZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0U2xvdFtdIHNsb3RzKCkgeworICAgICAgICByZXR1cm4gc2xvdHNUb1NlcmlhbGl6ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9FbXVsYXRlZEZpZWxkc0ZvckR1bXBpbmcuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0VtdWxhdGVkRmllbGRzRm9yRHVtcGluZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjljZjZlYWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9FbXVsYXRlZEZpZWxkc0ZvckR1bXBpbmcuamF2YQpAQCAtMCwwICsxLDIyNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCisvKioKKyAqIEFuIEVtdWxhdGVkRmllbGRzRm9yRHVtcGluZyBpcyBhbiBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgc2V0IG9mIGVtdWxhdGVkCisgKiBmaWVsZHMgZm9yIGFuIG9iamVjdCBiZWluZyBkdW1wZWQuIEl0IGlzIGEgY29uY3JldGUgaW1wbGVtZW50YXRpb24gZm9yCisgKiBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGQKKyAqCisgKgorICogQHNlZSBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGQKKyAqIEBzZWUgRW11bGF0ZWRGaWVsZHNGb3JMb2FkaW5nCisgKi8KK2NsYXNzIEVtdWxhdGVkRmllbGRzRm9yRHVtcGluZyBleHRlbmRzIE9iamVjdE91dHB1dFN0cmVhbS5QdXRGaWVsZCB7CisgICAgLy8gUmVjb3JkIHRoZSBPYmplY3RPdXRwdXRTdHJlYW0gdGhhdCBjcmVhdGVkIHRoaXMgUHV0RmllbGQgZm9yIGNoZWNraW5nIGluICd3cml0ZScuCisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3RPdXRwdXRTdHJlYW0gb29zOworCisgICAgLy8gVGhlIGFjdHVhbCByZXByZXNlbnRhdGlvbiwgd2l0aCBhIG1vcmUgcG93ZXJmdWwgQVBJIChzZXQmZ2V0KQorICAgIHByaXZhdGUgRW11bGF0ZWRGaWVsZHMgZW11bGF0ZWRGaWVsZHM7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIEVtdWxhdGVkRmllbGRzRm9yRHVtcGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJlYW1DbGFzcworICAgICAqICAgICAgICAgICAgYSBPYmplY3RTdHJlYW1DbGFzcywgd2hpY2ggZGVzY3JpYmUgdGhlIGZpZWxkcyB0byBiZSBlbXVsYXRlZAorICAgICAqICAgICAgICAgICAgKG5hbWVzLCB0eXBlcywgZXRjKS4KKyAgICAgKi8KKyAgICBFbXVsYXRlZEZpZWxkc0ZvckR1bXBpbmcoT2JqZWN0T3V0cHV0U3RyZWFtIG9vcywgT2JqZWN0U3RyZWFtQ2xhc3Mgc3RyZWFtQ2xhc3MpIHsKKyAgICAgICAgdGhpcy5vb3MgPSBvb3M7CisgICAgICAgIHRoaXMuZW11bGF0ZWRGaWVsZHMgPSBuZXcgRW11bGF0ZWRGaWVsZHMoc3RyZWFtQ2xhc3MuZmllbGRzKCksIChPYmplY3RTdHJlYW1GaWVsZFtdKSBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGFjdHVhbCBFbXVsYXRlZEZpZWxkcyBpbnN0YW5jZSB1c2VkIGJ5IHRoZSByZWNlaXZlci4gV2UgaGF2ZQorICAgICAqIHRoZSBhY3R1YWwgd29yayBpbiBhIHNlcGFyYXRlIGNsYXNzIHNvIHRoYXQgdGhlIGNvZGUgY2FuIGJlIHNoYXJlZC4gVGhlCisgICAgICogcmVjZWl2ZXIgaGFzIHRvIGJlIG9mIGEgc3ViY2xhc3Mgb2YgUHV0RmllbGQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFycmF5IG9mIE9iamVjdFNsb3QgdGhlIHJlY2VpdmVyIHJlcHJlc2VudHMuCisgICAgICovCisgICAgRW11bGF0ZWRGaWVsZHMgZW11bGF0ZWRGaWVsZHMoKSB7CisgICAgICAgIHJldHVybiBlbXVsYXRlZEZpZWxkczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGFuZCBzZXQgdGhlIGJ5dGUgdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCA8Y29kZT5uYW1lPC9jb2RlPiBpbgorICAgICAqIHRoZSByZWNlaXZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICBBIFN0cmluZywgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIHNldAorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgTmV3IHZhbHVlIGZvciB0aGUgZmllbGQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcHV0KFN0cmluZyBuYW1lLCBieXRlIHZhbHVlKSB7CisgICAgICAgIGVtdWxhdGVkRmllbGRzLnB1dChuYW1lLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZCBhbmQgc2V0IHRoZSBjaGFyIHZhbHVlIG9mIGEgZ2l2ZW4gZmllbGQgbmFtZWQgPGNvZGU+bmFtZTwvY29kZT4gaW4KKyAgICAgKiB0aGUgcmVjZWl2ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgQSBTdHJpbmcsIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBzZXQKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIE5ldyB2YWx1ZSBmb3IgdGhlIGZpZWxkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHB1dChTdHJpbmcgbmFtZSwgY2hhciB2YWx1ZSkgeworICAgICAgICBlbXVsYXRlZEZpZWxkcy5wdXQobmFtZSwgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmQgYW5kIHNldCB0aGUgZG91YmxlIHZhbHVlIG9mIGEgZ2l2ZW4gZmllbGQgbmFtZWQgPGNvZGU+bmFtZTwvY29kZT4KKyAgICAgKiBpbiB0aGUgcmVjZWl2ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgQSBTdHJpbmcsIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBzZXQKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIE5ldyB2YWx1ZSBmb3IgdGhlIGZpZWxkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHB1dChTdHJpbmcgbmFtZSwgZG91YmxlIHZhbHVlKSB7CisgICAgICAgIGVtdWxhdGVkRmllbGRzLnB1dChuYW1lLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZCBhbmQgc2V0IHRoZSBmbG9hdCB2YWx1ZSBvZiBhIGdpdmVuIGZpZWxkIG5hbWVkIDxjb2RlPm5hbWU8L2NvZGU+CisgICAgICogaW4gdGhlIHJlY2VpdmVyLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIEEgU3RyaW5nLCB0aGUgbmFtZSBvZiB0aGUgZmllbGQgdG8gc2V0CisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICBOZXcgdmFsdWUgZm9yIHRoZSBmaWVsZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBwdXQoU3RyaW5nIG5hbWUsIGZsb2F0IHZhbHVlKSB7CisgICAgICAgIGVtdWxhdGVkRmllbGRzLnB1dChuYW1lLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZCBhbmQgc2V0IHRoZSBpbnQgdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCA8Y29kZT5uYW1lPC9jb2RlPiBpbgorICAgICAqIHRoZSByZWNlaXZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICBBIFN0cmluZywgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIHNldAorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgTmV3IHZhbHVlIGZvciB0aGUgZmllbGQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcHV0KFN0cmluZyBuYW1lLCBpbnQgdmFsdWUpIHsKKyAgICAgICAgZW11bGF0ZWRGaWVsZHMucHV0KG5hbWUsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGFuZCBzZXQgdGhlIGxvbmcgdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCA8Y29kZT5uYW1lPC9jb2RlPiBpbgorICAgICAqIHRoZSByZWNlaXZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICBBIFN0cmluZywgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIHNldAorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgTmV3IHZhbHVlIGZvciB0aGUgZmllbGQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcHV0KFN0cmluZyBuYW1lLCBsb25nIHZhbHVlKSB7CisgICAgICAgIGVtdWxhdGVkRmllbGRzLnB1dChuYW1lLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZCBhbmQgc2V0IHRoZSBPYmplY3QgdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCA8Y29kZT5uYW1lPC9jb2RlPgorICAgICAqIGluIHRoZSByZWNlaXZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICBBIFN0cmluZywgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIHNldAorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgTmV3IHZhbHVlIGZvciB0aGUgZmllbGQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcHV0KFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgZW11bGF0ZWRGaWVsZHMucHV0KG5hbWUsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGFuZCBzZXQgdGhlIHNob3J0IHZhbHVlIG9mIGEgZ2l2ZW4gZmllbGQgbmFtZWQgPGNvZGU+bmFtZTwvY29kZT4KKyAgICAgKiBpbiB0aGUgcmVjZWl2ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgQSBTdHJpbmcsIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBzZXQKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIE5ldyB2YWx1ZSBmb3IgdGhlIGZpZWxkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHB1dChTdHJpbmcgbmFtZSwgc2hvcnQgdmFsdWUpIHsKKyAgICAgICAgZW11bGF0ZWRGaWVsZHMucHV0KG5hbWUsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGFuZCBzZXQgdGhlIGJvb2xlYW4gdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCA8Y29kZT5uYW1lPC9jb2RlPgorICAgICAqIGluIHRoZSByZWNlaXZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICBBIFN0cmluZywgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIHNldAorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgTmV3IHZhbHVlIGZvciB0aGUgZmllbGQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcHV0KFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKSB7CisgICAgICAgIGVtdWxhdGVkRmllbGRzLnB1dChuYW1lLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGUgdGhlIGZpZWxkIHZhbHVlcyB0byB0aGUgc3BlY2lmaWVkIE9iamVjdE91dHB1dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXRwdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBPYmplY3RPdXRwdXQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBleGNlcHRpb24gaGFwcGVuZWQgd2hlbiB3cml0aW5nIHRoZSBmaWVsZCB2YWx1ZXMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShPYmplY3RPdXRwdXQgb3V0cHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIW91dHB1dC5lcXVhbHMob29zKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQXR0ZW1wdGluZyB0byB3cml0ZSB0byBhIGRpZmZlcmVudCBzdHJlYW0gdGhhbiB0aGUgb25lIHRoYXQgY3JlYXRlZCB0aGlzIFB1dEZpZWxkIik7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChFbXVsYXRlZEZpZWxkcy5PYmplY3RTbG90IHNsb3QgOiBlbXVsYXRlZEZpZWxkcy5zbG90cygpKSB7CisgICAgICAgICAgICBPYmplY3QgZmllbGRWYWx1ZSA9IHNsb3QuZ2V0RmllbGRWYWx1ZSgpOworICAgICAgICAgICAgQ2xhc3M8Pz4gdHlwZSA9IHNsb3QuZ2V0RmllbGQoKS5nZXRUeXBlKCk7CisgICAgICAgICAgICBpZiAodHlwZSA9PSBpbnQuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVJbnQoZmllbGRWYWx1ZSAhPSBudWxsID8gKChJbnRlZ2VyKSBmaWVsZFZhbHVlKS5pbnRWYWx1ZSgpIDogMCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gYnl0ZS5jbGFzcykgeworICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUJ5dGUoZmllbGRWYWx1ZSAhPSBudWxsID8gKChCeXRlKSBmaWVsZFZhbHVlKS5ieXRlVmFsdWUoKSA6IDApOworICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGNoYXIuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVDaGFyKGZpZWxkVmFsdWUgIT0gbnVsbCA/ICgoQ2hhcmFjdGVyKSBmaWVsZFZhbHVlKS5jaGFyVmFsdWUoKSA6IDApOworICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IHNob3J0LmNsYXNzKSB7CisgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlU2hvcnQoZmllbGRWYWx1ZSAhPSBudWxsID8gKChTaG9ydCkgZmllbGRWYWx1ZSkuc2hvcnRWYWx1ZSgpIDogMCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gYm9vbGVhbi5jbGFzcykgeworICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUJvb2xlYW4oZmllbGRWYWx1ZSAhPSBudWxsID8gKChCb29sZWFuKSBmaWVsZFZhbHVlKS5ib29sZWFuVmFsdWUoKSA6IGZhbHNlKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBsb25nLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlTG9uZyhmaWVsZFZhbHVlICE9IG51bGwgPyAoKExvbmcpIGZpZWxkVmFsdWUpLmxvbmdWYWx1ZSgpIDogMCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gZmxvYXQuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVGbG9hdChmaWVsZFZhbHVlICE9IG51bGwgPyAoKEZsb2F0KSBmaWVsZFZhbHVlKS5mbG9hdFZhbHVlKCkgOiAwKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBkb3VibGUuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVEb3VibGUoZmllbGRWYWx1ZSAhPSBudWxsID8gKChEb3VibGUpIGZpZWxkVmFsdWUpLmRvdWJsZVZhbHVlKCkgOiAwKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gRWl0aGVyIGFycmF5IG9yIE9iamVjdAorICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZU9iamVjdChmaWVsZFZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0VtdWxhdGVkRmllbGRzRm9yTG9hZGluZy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRW11bGF0ZWRGaWVsZHNGb3JMb2FkaW5nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTA0NGM2MAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0VtdWxhdGVkRmllbGRzRm9yTG9hZGluZy5qYXZhCkBAIC0wLDAgKzEsMjk4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKKy8qKgorICogQW4gRW11bGF0ZWRGaWVsZHNGb3JMb2FkaW5nIGlzIGFuIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgYSBzZXQgb2YgZW11bGF0ZWQKKyAqIGZpZWxkcyBmb3IgYW4gb2JqZWN0IGJlaW5nIGxvYWRlZC4gSXQgaXMgYSBjb25jcmV0ZSBpbXBsZW1lbnRhdGlvbiBmb3IKKyAqIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkCisgKgorICogQHNlZSBPYmplY3RJbnB1dFN0cmVhbS5HZXRGaWVsZAorICogQHNlZSBFbXVsYXRlZEZpZWxkc0ZvckR1bXBpbmcKKyAqLworY2xhc3MgRW11bGF0ZWRGaWVsZHNGb3JMb2FkaW5nIGV4dGVuZHMgT2JqZWN0SW5wdXRTdHJlYW0uR2V0RmllbGQgeworCisgICAgLy8gVGhlIGNsYXNzIGRlc2NyaXB0b3Igd2l0aCB0aGUgZGVjbGFyZWQgZmllbGRzIHRoZSByZWNlaXZlciBlbXVsYXRlcworICAgIHByaXZhdGUgT2JqZWN0U3RyZWFtQ2xhc3Mgc3RyZWFtQ2xhc3M7CisKKyAgICAvLyBUaGUgYWN0dWFsIHJlcHJlc2VudGF0aW9uLCB3aXRoIGEgbW9yZSBwb3dlcmZ1bCBBUEkgKHNldCZnZXQpCisgICAgcHJpdmF0ZSBFbXVsYXRlZEZpZWxkcyBlbXVsYXRlZEZpZWxkczsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgRW11bGF0ZWRGaWVsZHNGb3JEdW1waW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmVhbUNsYXNzCisgICAgICogICAgICAgICAgICBhbiBPYmplY3RTdHJlYW1DbGFzcywgZGVmaW5pbmcgdGhlIGNsYXNzIGZvciB3aGljaCB0byBlbXVsYXRlCisgICAgICogICAgICAgICAgICBmaWVsZHMuCisgICAgICovCisgICAgRW11bGF0ZWRGaWVsZHNGb3JMb2FkaW5nKE9iamVjdFN0cmVhbUNsYXNzIHN0cmVhbUNsYXNzKSB7CisgICAgICAgIHRoaXMuc3RyZWFtQ2xhc3MgPSBzdHJlYW1DbGFzczsKKyAgICAgICAgZW11bGF0ZWRGaWVsZHMgPSBuZXcgRW11bGF0ZWRGaWVsZHMoc3RyZWFtQ2xhc3MuZ2V0TG9hZEZpZWxkcygpLCBzdHJlYW1DbGFzcy5maWVsZHMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGEgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIHRoZSBmaWVsZCBuYW1lZCA8Y29kZT5uYW1lPC9jb2RlPiBoYXMKKyAgICAgKiBiZWVuIGFzc2lnbmVkIGEgdmFsdWUgZXhwbGljaXRseSAoZmFsc2UpIG9yIGlmIGl0IHN0aWxsIGhvbGRzIGEgZGVmYXVsdAorICAgICAqIHZhbHVlIGZvciB0aGUgdHlwZSAodHJ1ZSkgYmVjYXVzZSBpdCBoYXNuJ3QgYmVlbiBhc3NpZ25lZCB0byB5ZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgQSBTdHJpbmcsIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byB0ZXN0CisgICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgZmllbGQgaG9sZHMgaXQgZGVmYXVsdCB2YWx1ZSwKKyAgICAgKiAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXJyb3Igb2NjdXJzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiB0aGUgY29ycmVzcG9uZGluZyBmaWVsZCBjYW4gbm90IGJlIGZvdW5kLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGRlZmF1bHRlZChTdHJpbmcgbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGVtdWxhdGVkRmllbGRzLmRlZmF1bHRlZChuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGFjdHVhbCBFbXVsYXRlZEZpZWxkcyBpbnN0YW5jZSB1c2VkIGJ5IHRoZSByZWNlaXZlci4gV2UgaGF2ZQorICAgICAqIHRoZSBhY3R1YWwgd29yayBpbiBhIHNlcGFyYXRlIGNsYXNzIHNvIHRoYXQgdGhlIGNvZGUgY2FuIGJlIHNoYXJlZC4gVGhlCisgICAgICogcmVjZWl2ZXIgaGFzIHRvIGJlIG9mIGEgc3ViY2xhc3Mgb2YgR2V0RmllbGQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFycmF5IG9mIE9iamVjdFNsb3QgdGhlIHJlY2VpdmVyIHJlcHJlc2VudHMuCisgICAgICovCisgICAgRW11bGF0ZWRGaWVsZHMgZW11bGF0ZWRGaWVsZHMoKSB7CisgICAgICAgIHJldHVybiBlbXVsYXRlZEZpZWxkczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGFuZCByZXR1cm4gdGhlIGJ5dGUgdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCA8Y29kZT5uYW1lPC9jb2RlPgorICAgICAqIGluIHRoZSByZWNlaXZlci4gSWYgdGhlIGZpZWxkIGhhcyBub3QgYmVlbiBhc3NpZ25lZCBhbnkgdmFsdWUgeWV0LCB0aGUKKyAgICAgKiBkZWZhdWx0IHZhbHVlIDxjb2RlPmRlZmF1bHRWYWx1ZTwvY29kZT4gaXMgcmV0dXJuZWQgaW5zdGVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICBBIFN0cmluZywgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGZpbmQKKyAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlCisgICAgICogICAgICAgICAgICBSZXR1cm4gdmFsdWUgaW4gY2FzZSB0aGUgZmllbGQgaGFzIG5vdCBiZWVuIGFzc2lnbmVkIHRvIHlldC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZmllbGQgaWYgaXQgaGFzIGJlZW4gYXNzaWduZWQsIG9yIHRoZQorICAgICAqICAgICAgICAgZGVmYXVsdCB2YWx1ZSBvdGhlcndpc2UKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBlcnJvciBvY2N1cnMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIHRoZSBjb3JyZXNwb25kaW5nIGZpZWxkIGNhbiBub3QgYmUgZm91bmQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGUgZ2V0KFN0cmluZyBuYW1lLCBieXRlIGRlZmF1bHRWYWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGVtdWxhdGVkRmllbGRzLmdldChuYW1lLCBkZWZhdWx0VmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmQgYW5kIHJldHVybiB0aGUgY2hhciB2YWx1ZSBvZiBhIGdpdmVuIGZpZWxkIG5hbWVkIDxjb2RlPm5hbWU8L2NvZGU+CisgICAgICogaW4gdGhlIHJlY2VpdmVyLiBJZiB0aGUgZmllbGQgaGFzIG5vdCBiZWVuIGFzc2lnbmVkIGFueSB2YWx1ZSB5ZXQsIHRoZQorICAgICAqIGRlZmF1bHQgdmFsdWUgPGNvZGU+ZGVmYXVsdFZhbHVlPC9jb2RlPiBpcyByZXR1cm5lZCBpbnN0ZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIEEgU3RyaW5nLCB0aGUgbmFtZSBvZiB0aGUgZmllbGQgdG8gZmluZAorICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUKKyAgICAgKiAgICAgICAgICAgIFJldHVybiB2YWx1ZSBpbiBjYXNlIHRoZSBmaWVsZCBoYXMgbm90IGJlZW4gYXNzaWduZWQgdG8geWV0LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBmaWVsZCBpZiBpdCBoYXMgYmVlbiBhc3NpZ25lZCwgb3IgdGhlCisgICAgICogICAgICAgICBkZWZhdWx0IHZhbHVlIG90aGVyd2lzZQorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFuIElPIGVycm9yIG9jY3VycworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgdGhlIGNvcnJlc3BvbmRpbmcgZmllbGQgY2FuIG5vdCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgY2hhciBnZXQoU3RyaW5nIG5hbWUsIGNoYXIgZGVmYXVsdFZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZW11bGF0ZWRGaWVsZHMuZ2V0KG5hbWUsIGRlZmF1bHRWYWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZCBhbmQgcmV0dXJuIHRoZSBkb3VibGUgdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCA8Y29kZT5uYW1lPC9jb2RlPgorICAgICAqIGluIHRoZSByZWNlaXZlci4gSWYgdGhlIGZpZWxkIGhhcyBub3QgYmVlbiBhc3NpZ25lZCBhbnkgdmFsdWUgeWV0LCB0aGUKKyAgICAgKiBkZWZhdWx0IHZhbHVlIDxjb2RlPmRlZmF1bHRWYWx1ZTwvY29kZT4gaXMgcmV0dXJuZWQgaW5zdGVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICBBIFN0cmluZywgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGZpbmQKKyAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlCisgICAgICogICAgICAgICAgICBSZXR1cm4gdmFsdWUgaW4gY2FzZSB0aGUgZmllbGQgaGFzIG5vdCBiZWVuIGFzc2lnbmVkIHRvIHlldC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZmllbGQgaWYgaXQgaGFzIGJlZW4gYXNzaWduZWQsIG9yIHRoZQorICAgICAqICAgICAgICAgZGVmYXVsdCB2YWx1ZSBvdGhlcndpc2UKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBlcnJvciBvY2N1cnMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIHRoZSBjb3JyZXNwb25kaW5nIGZpZWxkIGNhbiBub3QgYmUgZm91bmQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGRvdWJsZSBnZXQoU3RyaW5nIG5hbWUsIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBlbXVsYXRlZEZpZWxkcy5nZXQobmFtZSwgZGVmYXVsdFZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGFuZCByZXR1cm4gdGhlIGZsb2F0IHZhbHVlIG9mIGEgZ2l2ZW4gZmllbGQgbmFtZWQgPGNvZGU+bmFtZTwvY29kZT4KKyAgICAgKiBpbiB0aGUgcmVjZWl2ZXIuIElmIHRoZSBmaWVsZCBoYXMgbm90IGJlZW4gYXNzaWduZWQgYW55IHZhbHVlIHlldCwgdGhlCisgICAgICogZGVmYXVsdCB2YWx1ZSA8Y29kZT5kZWZhdWx0VmFsdWU8L2NvZGU+IGlzIHJldHVybmVkIGluc3RlYWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgQSBTdHJpbmcsIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBmaW5kCisgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAqICAgICAgICAgICAgUmV0dXJuIHZhbHVlIGluIGNhc2UgdGhlIGZpZWxkIGhhcyBub3QgYmVlbiBhc3NpZ25lZCB0byB5ZXQuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuIGZpZWxkIGlmIGl0IGhhcyBiZWVuIGFzc2lnbmVkLCBvciB0aGUKKyAgICAgKiAgICAgICAgIGRlZmF1bHQgdmFsdWUgb3RoZXJ3aXNlCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXJyb3Igb2NjdXJzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiB0aGUgY29ycmVzcG9uZGluZyBmaWVsZCBjYW4gbm90IGJlIGZvdW5kLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdCBnZXQoU3RyaW5nIG5hbWUsIGZsb2F0IGRlZmF1bHRWYWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGVtdWxhdGVkRmllbGRzLmdldChuYW1lLCBkZWZhdWx0VmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmQgYW5kIHJldHVybiB0aGUgaW50IHZhbHVlIG9mIGEgZ2l2ZW4gZmllbGQgbmFtZWQgPGNvZGU+bmFtZTwvY29kZT4KKyAgICAgKiBpbiB0aGUgcmVjZWl2ZXIuIElmIHRoZSBmaWVsZCBoYXMgbm90IGJlZW4gYXNzaWduZWQgYW55IHZhbHVlIHlldCwgdGhlCisgICAgICogZGVmYXVsdCB2YWx1ZSA8Y29kZT5kZWZhdWx0VmFsdWU8L2NvZGU+IGlzIHJldHVybmVkIGluc3RlYWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgQSBTdHJpbmcsIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBmaW5kCisgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAqICAgICAgICAgICAgUmV0dXJuIHZhbHVlIGluIGNhc2UgdGhlIGZpZWxkIGhhcyBub3QgYmVlbiBhc3NpZ25lZCB0byB5ZXQuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuIGZpZWxkIGlmIGl0IGhhcyBiZWVuIGFzc2lnbmVkLCBvciB0aGUKKyAgICAgKiAgICAgICAgIGRlZmF1bHQgdmFsdWUgb3RoZXJ3aXNlCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXJyb3Igb2NjdXJzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiB0aGUgY29ycmVzcG9uZGluZyBmaWVsZCBjYW4gbm90IGJlIGZvdW5kLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0KFN0cmluZyBuYW1lLCBpbnQgZGVmYXVsdFZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZW11bGF0ZWRGaWVsZHMuZ2V0KG5hbWUsIGRlZmF1bHRWYWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZCBhbmQgcmV0dXJuIHRoZSBsb25nIHZhbHVlIG9mIGEgZ2l2ZW4gZmllbGQgbmFtZWQgPGNvZGU+bmFtZTwvY29kZT4KKyAgICAgKiBpbiB0aGUgcmVjZWl2ZXIuIElmIHRoZSBmaWVsZCBoYXMgbm90IGJlZW4gYXNzaWduZWQgYW55IHZhbHVlIHlldCwgdGhlCisgICAgICogZGVmYXVsdCB2YWx1ZSA8Y29kZT5kZWZhdWx0VmFsdWU8L2NvZGU+IGlzIHJldHVybmVkIGluc3RlYWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgQSBTdHJpbmcsIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBmaW5kCisgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAqICAgICAgICAgICAgUmV0dXJuIHZhbHVlIGluIGNhc2UgdGhlIGZpZWxkIGhhcyBub3QgYmVlbiBhc3NpZ25lZCB0byB5ZXQuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuIGZpZWxkIGlmIGl0IGhhcyBiZWVuIGFzc2lnbmVkLCBvciB0aGUKKyAgICAgKiAgICAgICAgIGRlZmF1bHQgdmFsdWUgb3RoZXJ3aXNlCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXJyb3Igb2NjdXJzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiB0aGUgY29ycmVzcG9uZGluZyBmaWVsZCBjYW4gbm90IGJlIGZvdW5kLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIGdldChTdHJpbmcgbmFtZSwgbG9uZyBkZWZhdWx0VmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBlbXVsYXRlZEZpZWxkcy5nZXQobmFtZSwgZGVmYXVsdFZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIGFuZCByZXR1cm4gdGhlIE9iamVjdCB2YWx1ZSBvZiBhIGdpdmVuIGZpZWxkIG5hbWVkIDxjb2RlPm5hbWU8L2NvZGU+CisgICAgICogaW4gdGhlIHJlY2VpdmVyLiBJZiB0aGUgZmllbGQgaGFzIG5vdCBiZWVuIGFzc2lnbmVkIGFueSB2YWx1ZSB5ZXQsIHRoZQorICAgICAqIGRlZmF1bHQgdmFsdWUgPGNvZGU+ZGVmYXVsdFZhbHVlPC9jb2RlPiBpcyByZXR1cm5lZCBpbnN0ZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIEEgU3RyaW5nLCB0aGUgbmFtZSBvZiB0aGUgZmllbGQgdG8gZmluZAorICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUKKyAgICAgKiAgICAgICAgICAgIFJldHVybiB2YWx1ZSBpbiBjYXNlIHRoZSBmaWVsZCBoYXMgbm90IGJlZW4gYXNzaWduZWQgdG8geWV0LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBmaWVsZCBpZiBpdCBoYXMgYmVlbiBhc3NpZ25lZCwgb3IgdGhlCisgICAgICogICAgICAgICBkZWZhdWx0IHZhbHVlIG90aGVyd2lzZQorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFuIElPIGVycm9yIG9jY3VycworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgdGhlIGNvcnJlc3BvbmRpbmcgZmllbGQgY2FuIG5vdCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGdldChTdHJpbmcgbmFtZSwgT2JqZWN0IGRlZmF1bHRWYWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGVtdWxhdGVkRmllbGRzLmdldChuYW1lLCBkZWZhdWx0VmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmQgYW5kIHJldHVybiB0aGUgc2hvcnQgdmFsdWUgb2YgYSBnaXZlbiBmaWVsZCBuYW1lZCA8Y29kZT5uYW1lPC9jb2RlPgorICAgICAqIGluIHRoZSByZWNlaXZlci4gSWYgdGhlIGZpZWxkIGhhcyBub3QgYmVlbiBhc3NpZ25lZCBhbnkgdmFsdWUgeWV0LCB0aGUKKyAgICAgKiBkZWZhdWx0IHZhbHVlIDxjb2RlPmRlZmF1bHRWYWx1ZTwvY29kZT4gaXMgcmV0dXJuZWQgaW5zdGVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICBBIFN0cmluZywgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGZpbmQKKyAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlCisgICAgICogICAgICAgICAgICBSZXR1cm4gdmFsdWUgaW4gY2FzZSB0aGUgZmllbGQgaGFzIG5vdCBiZWVuIGFzc2lnbmVkIHRvIHlldC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZmllbGQgaWYgaXQgaGFzIGJlZW4gYXNzaWduZWQsIG9yIHRoZQorICAgICAqICAgICAgICAgZGVmYXVsdCB2YWx1ZSBvdGhlcndpc2UKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBlcnJvciBvY2N1cnMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIHRoZSBjb3JyZXNwb25kaW5nIGZpZWxkIGNhbiBub3QgYmUgZm91bmQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHNob3J0IGdldChTdHJpbmcgbmFtZSwgc2hvcnQgZGVmYXVsdFZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZW11bGF0ZWRGaWVsZHMuZ2V0KG5hbWUsIGRlZmF1bHRWYWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZCBhbmQgcmV0dXJuIHRoZSBib29sZWFuIHZhbHVlIG9mIGEgZ2l2ZW4gZmllbGQgbmFtZWQKKyAgICAgKiA8Y29kZT5uYW1lPC9jb2RlPiBpbiB0aGUgcmVjZWl2ZXIuIElmIHRoZSBmaWVsZCBoYXMgbm90IGJlZW4gYXNzaWduZWQKKyAgICAgKiBhbnkgdmFsdWUgeWV0LCB0aGUgZGVmYXVsdCB2YWx1ZSA8Y29kZT5kZWZhdWx0VmFsdWU8L2NvZGU+IGlzIHJldHVybmVkCisgICAgICogaW5zdGVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICBBIFN0cmluZywgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGZpbmQKKyAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlCisgICAgICogICAgICAgICAgICBSZXR1cm4gdmFsdWUgaW4gY2FzZSB0aGUgZmllbGQgaGFzIG5vdCBiZWVuIGFzc2lnbmVkIHRvIHlldC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZmllbGQgaWYgaXQgaGFzIGJlZW4gYXNzaWduZWQsIG9yIHRoZQorICAgICAqICAgICAgICAgZGVmYXVsdCB2YWx1ZSBvdGhlcndpc2UKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBlcnJvciBvY2N1cnMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIHRoZSBjb3JyZXNwb25kaW5nIGZpZWxkIGNhbiBub3QgYmUgZm91bmQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0KFN0cmluZyBuYW1lLCBib29sZWFuIGRlZmF1bHRWYWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGVtdWxhdGVkRmllbGRzLmdldChuYW1lLCBkZWZhdWx0VmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgY2xhc3MgZGVzY3JpcHRvciBmb3Igd2hpY2ggdGhlIGVtdWxhdGVkIGZpZWxkcyBhcmUgZGVmaW5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gT2JqZWN0U3RyZWFtQ2xhc3MgVGhlIGNsYXNzIGRlc2NyaXB0b3IgZm9yIHdoaWNoIHRoZSBlbXVsYXRlZAorICAgICAqICAgICAgICAgZmllbGRzIGFyZSBkZWZpbmVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3RTdHJlYW1DbGFzcyBnZXRPYmplY3RTdHJlYW1DbGFzcygpIHsKKyAgICAgICAgcmV0dXJuIHN0cmVhbUNsYXNzOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0V4dGVybmFsaXphYmxlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9FeHRlcm5hbGl6YWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE1OTdkZWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9FeHRlcm5hbGl6YWJsZS5qYXZhCkBAIC0wLDAgKzEsNDcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworLyoqCisgKiBEZWZpbmVzIGFuIGludGVyZmFjZSBmb3IgY2xhc3NlcyB0aGF0IHdhbnQgdG8gYmUgc2VyaWFsaXphYmxlLCBidXQgaGF2ZSB0aGVpcgorICogb3duIGJpbmFyeSByZXByZXNlbnRhdGlvbi4KKyAqLworcHVibGljIGludGVyZmFjZSBFeHRlcm5hbGl6YWJsZSBleHRlbmRzIFNlcmlhbGl6YWJsZSB7CisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIG5leHQgb2JqZWN0IGZyb20gdGhlIE9iamVjdElucHV0IDxjb2RlPmlucHV0PC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dAorICAgICAqICAgICAgICAgICAgdGhlIE9iamVjdElucHV0IGZyb20gd2hpY2ggdGhlIG5leHQgb2JqZWN0IGlzIHJlYWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhdHRlbXB0aW5nIHRvIHJlYWQgZnJvbSB7QGNvZGUgaW5wdXR9LgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjbGFzcyBvZiB0aGUgaW5zdGFuY2UgYmVpbmcgbG9hZGVkIGNhbm5vdCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZWFkRXh0ZXJuYWwoT2JqZWN0SW5wdXQgaW5wdXQpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIHJlY2VpdmVyIHRvIHRoZSBPYmplY3RPdXRwdXQgPGNvZGU+b3V0cHV0PC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXRwdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBPYmplY3RPdXRwdXQgdG8gd3JpdGUgdGhlIG9iamVjdCB0by4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGF0dGVtcHRpbmcgdG8gd3JpdGUgdG8ge0Bjb2RlIG91dHB1dH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVFeHRlcm5hbChPYmplY3RPdXRwdXQgb3V0cHV0KSB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWxlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTY4ZjAyMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0ZpbGUuamF2YQpAQCAtMCwwICsxLDExNzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEubmV0LlVSSTsKK2ltcG9ydCBqYXZhLm5ldC5VUklTeW50YXhFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKK2ltcG9ydCBsaWJjb3JlLmlvLkVycm5vRXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKK2ltcG9ydCBsaWJjb3JlLmlvLkxpYmNvcmU7CitpbXBvcnQgbGliY29yZS5pby5TdHJ1Y3RTdGF0OworaW1wb3J0IGxpYmNvcmUuaW8uU3RydWN0U3RhdEZzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnV0aWwuRGVsZXRlT25FeGl0OworaW1wb3J0IHN0YXRpYyBsaWJjb3JlLmlvLk9zQ29uc3RhbnRzLio7CisKKy8qKgorICogQW4gImFic3RyYWN0IiByZXByZXNlbnRhdGlvbiBvZiBhIGZpbGUgc3lzdGVtIGVudGl0eSBpZGVudGlmaWVkIGJ5IGEKKyAqIHBhdGhuYW1lLiBUaGUgcGF0aG5hbWUgbWF5IGJlIGFic29sdXRlIChyZWxhdGl2ZSB0byB0aGUgcm9vdCBkaXJlY3RvcnkKKyAqIG9mIHRoZSBmaWxlIHN5c3RlbSkgb3IgcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgZGlyZWN0b3J5IGluIHdoaWNoIHRoZSBwcm9ncmFtCisgKiBpcyBydW5uaW5nLgorICoKKyAqIDxwPlRoZSBhY3R1YWwgZmlsZSByZWZlcmVuY2VkIGJ5IGEge0Bjb2RlIEZpbGV9IG1heSBvciBtYXkgbm90IGV4aXN0LiBJdCBtYXkKKyAqIGFsc28sIGRlc3BpdGUgdGhlIG5hbWUge0Bjb2RlIEZpbGV9LCBiZSBhIGRpcmVjdG9yeSBvciBvdGhlciBub24tcmVndWxhcgorICogZmlsZS4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIHByb3ZpZGVzIGxpbWl0ZWQgZnVuY3Rpb25hbGl0eSBmb3IgZ2V0dGluZy9zZXR0aW5nIGZpbGUKKyAqIHBlcm1pc3Npb25zLCBmaWxlIHR5cGUsIGFuZCBsYXN0IG1vZGlmaWVkIHRpbWUuCisgKgorICogPHA+T24gQW5kcm9pZCBzdHJpbmdzIGFyZSBjb252ZXJ0ZWQgdG8gVVRGLTggYnl0ZSBzZXF1ZW5jZXMgd2hlbiBzZW5kaW5nIGZpbGVuYW1lcyB0bworICogdGhlIG9wZXJhdGluZyBzeXN0ZW0sIGFuZCBieXRlIHNlcXVlbmNlcyByZXR1cm5lZCBieSB0aGUgb3BlcmF0aW5nIHN5c3RlbSAoZnJvbSB0aGUKKyAqIHZhcmlvdXMge0Bjb2RlIGxpc3R9IG1ldGhvZHMpIGFyZSBjb252ZXJ0ZWQgdG8gc3RyaW5ncyBieSBkZWNvZGluZyB0aGVtIGFzIFVURi04CisgKiBieXRlIHNlcXVlbmNlcy4KKyAqCisgKiBAc2VlIGphdmEuaW8uU2VyaWFsaXphYmxlCisgKiBAc2VlIGphdmEubGFuZy5Db21wYXJhYmxlCisgKi8KK3B1YmxpYyBjbGFzcyBGaWxlIGltcGxlbWVudHMgU2VyaWFsaXphYmxlLCBDb21wYXJhYmxlPEZpbGU+IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDMwMTA3NzM2NjU5OTE4MTU2N0w7CisKKyAgICAvKioKKyAgICAgKiBSZXVzaW5nIGEgUmFuZG9tIG1ha2VzIHRlbXBvcmFyeSBmaWxlbmFtZXMgc2xpZ2h0bHkgaGFyZGVyIHRvIHByZWRpY3QuCisgICAgICogKFJhbmRvbSBpcyB0aHJlYWQtc2FmZS4pCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUmFuZG9tIHRlbXBGaWxlUmFuZG9tID0gbmV3IFJhbmRvbSgpOworCisgICAgLyoqCisgICAgICogVGhlIHN5c3RlbS1kZXBlbmRlbnQgY2hhcmFjdGVyIHVzZWQgdG8gc2VwYXJhdGUgY29tcG9uZW50cyBpbiBmaWxlbmFtZXMgKCcvJykuCisgICAgICogVXNlIG9mIHRoaXMgKHJhdGhlciB0aGFuIGhhcmQtY29kaW5nICcvJykgaGVscHMgcG9ydGFiaWxpdHkgdG8gb3RoZXIgb3BlcmF0aW5nIHN5c3RlbXMuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGZpZWxkIGlzIGluaXRpYWxpemVkIGZyb20gdGhlIHN5c3RlbSBwcm9wZXJ0eSAiZmlsZS5zZXBhcmF0b3IiLgorICAgICAqIExhdGVyIGNoYW5nZXMgdG8gdGhhdCBwcm9wZXJ0eSB3aWxsIGhhdmUgbm8gZWZmZWN0IG9uIHRoaXMgZmllbGQgb3IgdGhpcyBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNoYXIgc2VwYXJhdG9yQ2hhcjsKKworICAgIC8qKgorICAgICAqIFRoZSBzeXN0ZW0tZGVwZW5kZW50IHN0cmluZyB1c2VkIHRvIHNlcGFyYXRlIGNvbXBvbmVudHMgaW4gZmlsZW5hbWVzICgnLycpLgorICAgICAqIFNlZSB7QGxpbmsgI3NlcGFyYXRvckNoYXJ9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIHNlcGFyYXRvcjsKKworICAgIC8qKgorICAgICAqIFRoZSBzeXN0ZW0tZGVwZW5kZW50IGNoYXJhY3RlciB1c2VkIHRvIHNlcGFyYXRlIGNvbXBvbmVudHMgaW4gc2VhcmNoIHBhdGhzICgnOicpLgorICAgICAqIFRoaXMgaXMgdXNlZCB0byBzcGxpdCBzdWNoIHRoaW5ncyBhcyB0aGUgUEFUSCBlbnZpcm9ubWVudCB2YXJpYWJsZSBhbmQgY2xhc3NwYXRoCisgICAgICogc3lzdGVtIHByb3BlcnRpZXMgaW50byBsaXN0cyBvZiBkaXJlY3RvcmllcyB0byBiZSBzZWFyY2hlZC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgZmllbGQgaXMgaW5pdGlhbGl6ZWQgZnJvbSB0aGUgc3lzdGVtIHByb3BlcnR5ICJwYXRoLnNlcGFyYXRvciIuCisgICAgICogTGF0ZXIgY2hhbmdlcyB0byB0aGF0IHByb3BlcnR5IHdpbGwgaGF2ZSBubyBlZmZlY3Qgb24gdGhpcyBmaWVsZCBvciB0aGlzIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBwYXRoU2VwYXJhdG9yQ2hhcjsKKworICAgIC8qKgorICAgICAqIFRoZSBzeXN0ZW0tZGVwZW5kZW50IHN0cmluZyB1c2VkIHRvIHNlcGFyYXRlIGNvbXBvbmVudHMgaW4gc2VhcmNoIHBhdGhzICgiOiIpLgorICAgICAqIFNlZSB7QGxpbmsgI3BhdGhTZXBhcmF0b3JDaGFyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBwYXRoU2VwYXJhdG9yOworCisgICAgLyoqCisgICAgICogVGhlIHBhdGggd2UgcmV0dXJuIGZyb20gZ2V0UGF0aC4gVGhpcyBpcyBhbG1vc3QgdGhlIHBhdGggd2Ugd2VyZQorICAgICAqIGdpdmVuLCBidXQgd2l0aG91dCBkdXBsaWNhdGUgYWRqYWNlbnQgc2xhc2hlcyBhbmQgd2l0aG91dCB0cmFpbGluZworICAgICAqIHNsYXNoZXMgKGV4Y2VwdCBmb3IgdGhlIHNwZWNpYWwgY2FzZSBvZiB0aGUgcm9vdCBkaXJlY3RvcnkpLiBUaGlzCisgICAgICogcGF0aCBtYXkgYmUgdGhlIGVtcHR5IHN0cmluZy4KKyAgICAgKgorICAgICAqIFRoaXMgY2FuJ3QgYmUgZmluYWwgYmVjYXVzZSB3ZSBvdmVycmlkZSByZWFkT2JqZWN0LgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHBhdGg7CisKKyAgICBzdGF0aWMgeworICAgICAgICBzZXBhcmF0b3JDaGFyID0gU3lzdGVtLmdldFByb3BlcnR5KCJmaWxlLnNlcGFyYXRvciIsICIvIikuY2hhckF0KDApOworICAgICAgICBwYXRoU2VwYXJhdG9yQ2hhciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgicGF0aC5zZXBhcmF0b3IiLCAiOiIpLmNoYXJBdCgwKTsKKyAgICAgICAgc2VwYXJhdG9yID0gU3RyaW5nLnZhbHVlT2Yoc2VwYXJhdG9yQ2hhcik7CisgICAgICAgIHBhdGhTZXBhcmF0b3IgPSBTdHJpbmcudmFsdWVPZihwYXRoU2VwYXJhdG9yQ2hhcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBmaWxlIHVzaW5nIHRoZSBzcGVjaWZpZWQgZGlyZWN0b3J5IGFuZCBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIGRpcgorICAgICAqICAgICAgICAgICAgdGhlIGRpcmVjdG9yeSB3aGVyZSB0aGUgZmlsZSBpcyBzdG9yZWQuCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWxlJ3MgbmFtZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG5hbWV9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZShGaWxlIGRpciwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgdGhpcyhkaXIgPT0gbnVsbCA/IG51bGwgOiBkaXIuZ2V0UGF0aCgpLCBuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGZpbGUgdXNpbmcgdGhlIHNwZWNpZmllZCBwYXRoLgorICAgICAqCisgICAgICogQHBhcmFtIHBhdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXRoIHRvIGJlIHVzZWQgZm9yIHRoZSBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBGaWxlKFN0cmluZyBwYXRoKSB7CisgICAgICAgIHRoaXMucGF0aCA9IGZpeFNsYXNoZXMocGF0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBGaWxlIHVzaW5nIHRoZSBzcGVjaWZpZWQgZGlyZWN0b3J5IHBhdGggYW5kIGZpbGUgbmFtZSwKKyAgICAgKiBwbGFjaW5nIGEgcGF0aCBzZXBhcmF0b3IgYmV0d2VlbiB0aGUgdHdvLgorICAgICAqCisgICAgICogQHBhcmFtIGRpclBhdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXRoIHRvIHRoZSBkaXJlY3Rvcnkgd2hlcmUgdGhlIGZpbGUgaXMgc3RvcmVkLgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgZmlsZSdzIG5hbWUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBuYW1lID09IG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBGaWxlKFN0cmluZyBkaXJQYXRoLCBTdHJpbmcgbmFtZSkgeworICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZGlyUGF0aCA9PSBudWxsIHx8IGRpclBhdGguaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aGlzLnBhdGggPSBmaXhTbGFzaGVzKG5hbWUpOworICAgICAgICB9IGVsc2UgaWYgKG5hbWUuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aGlzLnBhdGggPSBmaXhTbGFzaGVzKGRpclBhdGgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhpcy5wYXRoID0gZml4U2xhc2hlcyhqb2luKGRpclBhdGgsIG5hbWUpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgRmlsZSB1c2luZyB0aGUgcGF0aCBvZiB0aGUgc3BlY2lmaWVkIFVSSS4ge0Bjb2RlIHVyaX0KKyAgICAgKiBuZWVkcyB0byBiZSBhbiBhYnNvbHV0ZSBhbmQgaGllcmFyY2hpY2FsIFVuaWZpZWQgUmVzb3VyY2UgSWRlbnRpZmllciB3aXRoCisgICAgICogZmlsZSBzY2hlbWUgYW5kIG5vbi1lbXB0eSBwYXRoIGNvbXBvbmVudCwgYnV0IHdpdGggdW5kZWZpbmVkIGF1dGhvcml0eSwKKyAgICAgKiBxdWVyeSBvciBmcmFnbWVudCBjb21wb25lbnRzLgorICAgICAqCisgICAgICogQHBhcmFtIHVyaQorICAgICAqICAgICAgICAgICAgdGhlIFVuaWZpZWQgUmVzb3VyY2UgSWRlbnRpZmllciB0aGF0IGlzIHVzZWQgdG8gY29uc3RydWN0IHRoaXMKKyAgICAgKiAgICAgICAgICAgIGZpbGUuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgdXJpfSBkb2VzIG5vdCBjb21wbHkgd2l0aCB0aGUgY29uZGl0aW9ucyBhYm92ZS4KKyAgICAgKiBAc2VlICN0b1VSSQorICAgICAqIEBzZWUgamF2YS5uZXQuVVJJCisgICAgICovCisgICAgcHVibGljIEZpbGUoVVJJIHVyaSkgeworICAgICAgICAvLyBjaGVjayBwcmUtY29uZGl0aW9ucworICAgICAgICBjaGVja1VSSSh1cmkpOworICAgICAgICB0aGlzLnBhdGggPSBmaXhTbGFzaGVzKHVyaS5nZXRQYXRoKCkpOworICAgIH0KKworICAgIC8vIFJlbW92ZXMgZHVwbGljYXRlIGFkamFjZW50IHNsYXNoZXMgYW5kIGFueSB0cmFpbGluZyBzbGFzaC4KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZml4U2xhc2hlcyhTdHJpbmcgb3JpZ1BhdGgpIHsKKyAgICAgICAgLy8gUmVtb3ZlIGR1cGxpY2F0ZSBhZGphY2VudCBzbGFzaGVzLgorICAgICAgICBib29sZWFuIGxhc3RXYXNTbGFzaCA9IGZhbHNlOworICAgICAgICBjaGFyW10gbmV3UGF0aCA9IG9yaWdQYXRoLnRvQ2hhckFycmF5KCk7CisgICAgICAgIGludCBsZW5ndGggPSBuZXdQYXRoLmxlbmd0aDsKKyAgICAgICAgaW50IG5ld0xlbmd0aCA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIGNoYXIgY2ggPSBuZXdQYXRoW2ldOworICAgICAgICAgICAgaWYgKGNoID09ICcvJykgeworICAgICAgICAgICAgICAgIGlmICghbGFzdFdhc1NsYXNoKSB7CisgICAgICAgICAgICAgICAgICAgIG5ld1BhdGhbbmV3TGVuZ3RoKytdID0gc2VwYXJhdG9yQ2hhcjsKKyAgICAgICAgICAgICAgICAgICAgbGFzdFdhc1NsYXNoID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG5ld1BhdGhbbmV3TGVuZ3RoKytdID0gY2g7CisgICAgICAgICAgICAgICAgbGFzdFdhc1NsYXNoID0gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gUmVtb3ZlIGFueSB0cmFpbGluZyBzbGFzaCAodW5sZXNzIHRoaXMgaXMgdGhlIHJvb3Qgb2YgdGhlIGZpbGUgc3lzdGVtKS4KKyAgICAgICAgaWYgKGxhc3RXYXNTbGFzaCAmJiBuZXdMZW5ndGggPiAxKSB7CisgICAgICAgICAgICBuZXdMZW5ndGgtLTsKKyAgICAgICAgfQorICAgICAgICAvLyBSZXVzZSB0aGUgb3JpZ2luYWwgc3RyaW5nIGlmIHBvc3NpYmxlLgorICAgICAgICByZXR1cm4gKG5ld0xlbmd0aCAhPSBsZW5ndGgpID8gbmV3IFN0cmluZyhuZXdQYXRoLCAwLCBuZXdMZW5ndGgpIDogb3JpZ1BhdGg7CisgICAgfQorCisgICAgLy8gSm9pbnMgdHdvIHBhdGggY29tcG9uZW50cywgYWRkaW5nIGEgc2VwYXJhdG9yIG9ubHkgaWYgbmVjZXNzYXJ5LgorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBqb2luKFN0cmluZyBwcmVmaXgsIFN0cmluZyBzdWZmaXgpIHsKKyAgICAgICAgaW50IHByZWZpeExlbmd0aCA9IHByZWZpeC5sZW5ndGgoKTsKKyAgICAgICAgYm9vbGVhbiBoYXZlU2xhc2ggPSAocHJlZml4TGVuZ3RoID4gMCAmJiBwcmVmaXguY2hhckF0KHByZWZpeExlbmd0aCAtIDEpID09IHNlcGFyYXRvckNoYXIpOworICAgICAgICBpZiAoIWhhdmVTbGFzaCkgeworICAgICAgICAgICAgaGF2ZVNsYXNoID0gKHN1ZmZpeC5sZW5ndGgoKSA+IDAgJiYgc3VmZml4LmNoYXJBdCgwKSA9PSBzZXBhcmF0b3JDaGFyKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGF2ZVNsYXNoID8gKHByZWZpeCArIHN1ZmZpeCkgOiAocHJlZml4ICsgc2VwYXJhdG9yQ2hhciArIHN1ZmZpeCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja1VSSShVUkkgdXJpKSB7CisgICAgICAgIGlmICghdXJpLmlzQWJzb2x1dGUoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVVJJIGlzIG5vdCBhYnNvbHV0ZTogIiArIHVyaSk7CisgICAgICAgIH0gZWxzZSBpZiAoIXVyaS5nZXRSYXdTY2hlbWVTcGVjaWZpY1BhcnQoKS5zdGFydHNXaXRoKCIvIikpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlVSSSBpcyBub3QgaGllcmFyY2hpY2FsOiAiICsgdXJpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoISJmaWxlIi5lcXVhbHModXJpLmdldFNjaGVtZSgpKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRXhwZWN0ZWQgZmlsZSBzY2hlbWUgaW4gVVJJOiAiICsgdXJpKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcmF3UGF0aCA9IHVyaS5nZXRSYXdQYXRoKCk7CisgICAgICAgIGlmIChyYXdQYXRoID09IG51bGwgfHwgcmF3UGF0aC5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkV4cGVjdGVkIG5vbi1lbXB0eSBwYXRoIGluIFVSSTogIiArIHVyaSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHVyaS5nZXRSYXdBdXRob3JpdHkoKSAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGb3VuZCBhdXRob3JpdHkgaW4gVVJJOiAiICsgdXJpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodXJpLmdldFJhd1F1ZXJ5KCkgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRm91bmQgcXVlcnkgaW4gVVJJOiAiICsgdXJpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodXJpLmdldFJhd0ZyYWdtZW50KCkgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRm91bmQgZnJhZ21lbnQgaW4gVVJJOiAiICsgdXJpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZpbGUgc3lzdGVtIHJvb3RzLiBPbiBBbmRyb2lkIGFuZCBvdGhlciBVbml4IHN5c3RlbXMsIHRoZXJlIGlzCisgICAgICogYSBzaW5nbGUgcm9vdCwge0Bjb2RlIC99LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgRmlsZVtdIGxpc3RSb290cygpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBGaWxlW10geyBuZXcgRmlsZSgiLyIpIH07CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgd2hldGhlciBvciBub3QgdGhpcyBwcm9jZXNzIGlzIGFsbG93ZWQgdG8gZXhlY3V0ZSB0aGlzIGZpbGUuCisgICAgICogTm90ZSB0aGF0IHRoaXMgaXMgYSBiZXN0LWVmZm9ydCByZXN1bHQ7IHRoZSBvbmx5IHdheSB0byBiZSBjZXJ0YWluIGlzCisgICAgICogdG8gYWN0dWFsbHkgYXR0ZW1wdCB0aGUgb3BlcmF0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBmaWxlIGNhbiBiZSBleGVjdXRlZCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNhbkV4ZWN1dGUoKSB7CisgICAgICAgIHJldHVybiBkb0FjY2VzcyhYX09LKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgY3VycmVudCBjb250ZXh0IGlzIGFsbG93ZWQgdG8gcmVhZCBmcm9tIHRoaXMgZmlsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgZmlsZSBjYW4gYmUgcmVhZCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY2FuUmVhZCgpIHsKKyAgICAgICAgcmV0dXJuIGRvQWNjZXNzKFJfT0spOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBjdXJyZW50IGNvbnRleHQgaXMgYWxsb3dlZCB0byB3cml0ZSB0byB0aGlzIGZpbGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGZpbGUgY2FuIGJlIHdyaXR0ZW4sIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjYW5Xcml0ZSgpIHsKKyAgICAgICAgcmV0dXJuIGRvQWNjZXNzKFdfT0spOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBkb0FjY2VzcyhpbnQgbW9kZSkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIExpYmNvcmUub3MuYWNjZXNzKHBhdGgsIG1vZGUpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmVsYXRpdmUgc29ydCBvcmRlcmluZyBvZiB0aGUgcGF0aHMgZm9yIHRoaXMgZmlsZSBhbmQgdGhlCisgICAgICogZmlsZSB7QGNvZGUgYW5vdGhlcn0uIFRoZSBvcmRlcmluZyBpcyBwbGF0Zm9ybSBkZXBlbmRlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYW5vdGhlcgorICAgICAqICAgICAgICAgICAgYSBmaWxlIHRvIGNvbXBhcmUgdGhpcyBmaWxlIHRvCisgICAgICogQHJldHVybiBhbiBpbnQgZGV0ZXJtaW5lZCBieSBjb21wYXJpbmcgdGhlIHR3byBwYXRocy4gUG9zc2libGUgdmFsdWVzIGFyZQorICAgICAqICAgICAgICAgZGVzY3JpYmVkIGluIHRoZSBDb21wYXJhYmxlIGludGVyZmFjZS4KKyAgICAgKiBAc2VlIENvbXBhcmFibGUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhGaWxlIGFub3RoZXIpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGF0aCgpLmNvbXBhcmVUbyhhbm90aGVyLmdldFBhdGgoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVsZXRlcyB0aGlzIGZpbGUuIERpcmVjdG9yaWVzIG11c3QgYmUgZW1wdHkgYmVmb3JlIHRoZXkgd2lsbCBiZSBkZWxldGVkLgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IHRoaXMgbWV0aG9kIGRvZXMgPGk+bm90PC9pPiB0aHJvdyB7QGNvZGUgSU9FeGNlcHRpb259IG9uIGZhaWx1cmUuCisgICAgICogQ2FsbGVycyBtdXN0IGNoZWNrIHRoZSByZXR1cm4gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGZpbGUgd2FzIGRlbGV0ZWQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGRlbGV0ZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIExpYmNvcmUub3MucmVtb3ZlKHBhdGgpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTY2hlZHVsZXMgdGhpcyBmaWxlIHRvIGJlIGF1dG9tYXRpY2FsbHkgZGVsZXRlZCB3aGVuIHRoZSBWTSB0ZXJtaW5hdGVzIG5vcm1hbGx5LgorICAgICAqCisgICAgICogPHA+PGk+Tm90ZSB0aGF0IG9uIEFuZHJvaWQsIHRoZSBhcHBsaWNhdGlvbiBsaWZlY3ljbGUgZG9lcyBub3QgaW5jbHVkZSBWTSB0ZXJtaW5hdGlvbiwKKyAgICAgKiBzbyBjYWxsaW5nIHRoaXMgbWV0aG9kIHdpbGwgbm90IGVuc3VyZSB0aGF0IGZpbGVzIGFyZSBkZWxldGVkPC9pPi4gSW5zdGVhZCwgeW91IHNob3VsZAorICAgICAqIHVzZSB0aGUgbW9zdCBhcHByb3ByaWF0ZSBvdXQgb2Y6CisgICAgICogPHVsPgorICAgICAqIDxsaT5Vc2UgYSB7QGNvZGUgZmluYWxseX0gY2xhdXNlIHRvIG1hbnVhbGx5IGludm9rZSB7QGxpbmsgI2RlbGV0ZX0uCisgICAgICogPGxpPk1haW50YWluIHlvdXIgb3duIHNldCBvZiBmaWxlcyB0byBkZWxldGUsIGFuZCBwcm9jZXNzIGl0IGF0IGFuIGFwcHJvcHJpYXRlIHBvaW50CisgICAgICogaW4geW91ciBhcHBsaWNhdGlvbidzIGxpZmVjeWNsZS4KKyAgICAgKiA8bGk+VXNlIHRoZSBVbml4IHRyaWNrIG9mIGRlbGV0aW5nIHRoZSBmaWxlIGFzIHNvb24gYXMgYWxsIHJlYWRlcnMgYW5kIHdyaXRlcnMgaGF2ZQorICAgICAqIG9wZW5lZCBpdC4gTm8gbmV3IHJlYWRlcnMvd3JpdGVycyB3aWxsIGJlIGFibGUgdG8gYWNjZXNzIHRoZSBmaWxlLCBidXQgYWxsIGV4aXN0aW5nCisgICAgICogb25lcyB3aWxsIHN0aWxsIGhhdmUgYWNjZXNzIHVudGlsIHRoZSBsYXN0IG9uZSBjbG9zZXMgdGhlIGZpbGUuCisgICAgICogPC91bD4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkZWxldGVPbkV4aXQoKSB7CisgICAgICAgIERlbGV0ZU9uRXhpdC5nZXRJbnN0YW5jZSgpLmFkZEZpbGUoZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHtAY29kZSBvYmp9IHRvIHRoaXMgZmlsZSBhbmQgcmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhleQorICAgICAqIHJlcHJlc2VudCB0aGUgPGVtPnNhbWU8L2VtPiBvYmplY3QgdXNpbmcgYSBwYXRoIHNwZWNpZmljIGNvbXBhcmlzb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyBmaWxlIHdpdGguCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIG9ian0gaXMgdGhlIHNhbWUgYXMgdGhpcyBvYmplY3QsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBGaWxlKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBwYXRoLmVxdWFscygoKEZpbGUpIG9iaikuZ2V0UGF0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyBmaWxlIGNhbiBiZSBmb3VuZCBvbiB0aGUKKyAgICAgKiB1bmRlcmx5aW5nIGZpbGUgc3lzdGVtLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBmaWxlIGV4aXN0cywge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXhpc3RzKCkgeworICAgICAgICByZXR1cm4gZG9BY2Nlc3MoRl9PSyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYWJzb2x1dGUgcGF0aCBvZiB0aGlzIGZpbGUuIEFuIGFic29sdXRlIHBhdGggaXMgYSBwYXRoIHRoYXQgc3RhcnRzIGF0IGEgcm9vdAorICAgICAqIG9mIHRoZSBmaWxlIHN5c3RlbS4gT24gQW5kcm9pZCwgdGhlcmUgaXMgb25seSBvbmUgcm9vdDoge0Bjb2RlIC99LgorICAgICAqCisgICAgICogPHA+QSBjb21tb24gdXNlIGZvciBhYnNvbHV0ZSBwYXRocyBpcyB3aGVuIHBhc3NpbmcgcGF0aHMgdG8gYSB7QGNvZGUgUHJvY2Vzc30gYXMKKyAgICAgKiBjb21tYW5kLWxpbmUgYXJndW1lbnRzLCB0byByZW1vdmUgdGhlIHJlcXVpcmVtZW50IGltcGxpZWQgYnkgcmVsYXRpdmUgcGF0aHMsIHRoYXQgdGhlCisgICAgICogY2hpbGQgbXVzdCBoYXZlIHRoZSBzYW1lIHdvcmtpbmcgZGlyZWN0b3J5IGFzIGl0cyBwYXJlbnQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRBYnNvbHV0ZVBhdGgoKSB7CisgICAgICAgIGlmIChpc0Fic29sdXRlKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBwYXRoOworICAgICAgICB9CisgICAgICAgIFN0cmluZyB1c2VyRGlyID0gU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLmRpciIpOworICAgICAgICByZXR1cm4gcGF0aC5pc0VtcHR5KCkgPyB1c2VyRGlyIDogam9pbih1c2VyRGlyLCBwYXRoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGZpbGUgY29uc3RydWN0ZWQgdXNpbmcgdGhlIGFic29sdXRlIHBhdGggb2YgdGhpcyBmaWxlLgorICAgICAqIEVxdWl2YWxlbnQgdG8ge0Bjb2RlIG5ldyBGaWxlKHRoaXMuZ2V0QWJzb2x1dGVQYXRoKCkpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZSBnZXRBYnNvbHV0ZUZpbGUoKSB7CisgICAgICAgIHJldHVybiBuZXcgRmlsZShnZXRBYnNvbHV0ZVBhdGgoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2Fub25pY2FsIHBhdGggb2YgdGhpcyBmaWxlLgorICAgICAqIEFuIDxpPmFic29sdXRlPC9pPiBwYXRoIGlzIG9uZSB0aGF0IGJlZ2lucyBhdCB0aGUgcm9vdCBvZiB0aGUgZmlsZSBzeXN0ZW0uCisgICAgICogQSA8aT5jYW5vbmljYWw8L2k+IHBhdGggaXMgYW4gYWJzb2x1dGUgcGF0aCB3aXRoIHN5bWJvbGljIGxpbmtzCisgICAgICogYW5kIHJlZmVyZW5jZXMgdG8gIi4iIG9yICIuLiIgcmVzb2x2ZWQuIElmIGEgcGF0aCBlbGVtZW50IGRvZXMgbm90IGV4aXN0IChvcgorICAgICAqIGlzIG5vdCBzZWFyY2hhYmxlKSwgdGhlcmUgaXMgYSBjb25mbGljdCBiZXR3ZWVuIGludGVycHJldGluZyBjYW5vbmljYWxpemF0aW9uCisgICAgICogYXMgYSB0ZXh0dWFsIG9wZXJhdGlvbiAod2hlcmUgImEvLi4vYiIgaXMgImIiIGV2ZW4gaWYgImEiIGRvZXMgbm90IGV4aXN0KSAuCisgICAgICoKKyAgICAgKiA8cD5Nb3N0IGNhbGxlcnMgc2hvdWxkIHVzZSB7QGxpbmsgI2dldEFic29sdXRlUGF0aH0gaW5zdGVhZC4gQSBjYW5vbmljYWwgcGF0aCBpcworICAgICAqIHNpZ25pZmljYW50bHkgbW9yZSBleHBlbnNpdmUgdG8gY29tcHV0ZSwgYW5kIG5vdCBnZW5lcmFsbHkgdXNlZnVsLiBUaGUgcHJpbWFyeQorICAgICAqIHVzZSBmb3IgY2Fub25pY2FsIHBhdGhzIGlzIGRldGVybWluaW5nIHdoZXRoZXIgdHdvIHBhdGhzIHBvaW50IHRvIHRoZSBzYW1lIGZpbGUgYnkKKyAgICAgKiBjb21wYXJpbmcgdGhlIGNhbm9uaWNhbGl6ZWQgcGF0aHMuCisgICAgICoKKyAgICAgKiA8cD5JdCBjYW4gYmUgYWN0aXZlbHkgaGFybWZ1bCB0byB1c2UgYSBjYW5vbmljYWwgcGF0aCwgc3BlY2lmaWNhbGx5IGJlY2F1c2UKKyAgICAgKiBjYW5vbmljYWxpemF0aW9uIHJlbW92ZXMgc3ltYm9saWMgbGlua3MuIEl0J3Mgd2lzZSB0byBhc3N1bWUgdGhhdCBhIHN5bWJvbGljIGxpbmsKKyAgICAgKiBpcyBwcmVzZW50IGZvciBhIHJlYXNvbiwgYW5kIHRoYXQgdGhhdCByZWFzb24gaXMgYmVjYXVzZSB0aGUgbGluayBtYXkgbmVlZCB0byBjaGFuZ2UuCisgICAgICogQ2Fub25pY2FsaXphdGlvbiByZW1vdmVzIHRoaXMgbGF5ZXIgb2YgaW5kaXJlY3Rpb24uIEdvb2QgY29kZSBzaG91bGQgZ2VuZXJhbGx5IGF2b2lkCisgICAgICogY2FjaGluZyBjYW5vbmljYWwgcGF0aHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjYW5vbmljYWwgcGF0aCBvZiB0aGlzIGZpbGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDYW5vbmljYWxQYXRoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHJlYWxwYXRoKGdldEFic29sdXRlUGF0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUT0RPOiBtb3ZlIHRoaXMgc3R1ZmYgdG8gbGliY29yZS5vcy4KKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBTdHJpbmcgcmVhbHBhdGgoU3RyaW5nIHBhdGgpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBTdHJpbmcgcmVhZGxpbmsoU3RyaW5nIHBhdGgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBmaWxlIGNyZWF0ZWQgdXNpbmcgdGhlIGNhbm9uaWNhbCBwYXRoIG9mIHRoaXMgZmlsZS4KKyAgICAgKiBFcXVpdmFsZW50IHRvIHtAY29kZSBuZXcgRmlsZSh0aGlzLmdldENhbm9uaWNhbFBhdGgoKSl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV3IGZpbGUgY29uc3RydWN0ZWQgZnJvbSB0aGlzIGZpbGUncyBjYW5vbmljYWwgcGF0aC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZSBnZXRDYW5vbmljYWxGaWxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBGaWxlKGdldENhbm9uaWNhbFBhdGgoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgZmlsZSBvciBkaXJlY3RvcnkgcmVwcmVzZW50ZWQgYnkgdGhpcyBmaWxlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIGZpbGUncyBuYW1lIG9yIGFuIGVtcHR5IHN0cmluZyBpZiB0aGVyZSBpcyBubyBuYW1lIHBhcnQgaW4KKyAgICAgKiAgICAgICAgIHRoZSBmaWxlJ3MgcGF0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIGludCBzZXBhcmF0b3JJbmRleCA9IHBhdGgubGFzdEluZGV4T2Yoc2VwYXJhdG9yKTsKKyAgICAgICAgcmV0dXJuIChzZXBhcmF0b3JJbmRleCA8IDApID8gcGF0aCA6IHBhdGguc3Vic3RyaW5nKHNlcGFyYXRvckluZGV4ICsgMSwgcGF0aC5sZW5ndGgoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGF0aG5hbWUgb2YgdGhlIHBhcmVudCBvZiB0aGlzIGZpbGUuIFRoaXMgaXMgdGhlIHBhdGggdXAgdG8KKyAgICAgKiBidXQgbm90IGluY2x1ZGluZyB0aGUgbGFzdCBuYW1lLiB7QGNvZGUgbnVsbH0gaXMgcmV0dXJuZWQgaWYgdGhlcmUgaXMgbm8KKyAgICAgKiBwYXJlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgZmlsZSdzIHBhcmVudCBwYXRobmFtZSBvciB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRQYXJlbnQoKSB7CisgICAgICAgIGludCBsZW5ndGggPSBwYXRoLmxlbmd0aCgpLCBmaXJzdEluUGF0aCA9IDA7CisgICAgICAgIGlmIChzZXBhcmF0b3JDaGFyID09ICdcXCcgJiYgbGVuZ3RoID4gMiAmJiBwYXRoLmNoYXJBdCgxKSA9PSAnOicpIHsKKyAgICAgICAgICAgIGZpcnN0SW5QYXRoID0gMjsKKyAgICAgICAgfQorICAgICAgICBpbnQgaW5kZXggPSBwYXRoLmxhc3RJbmRleE9mKHNlcGFyYXRvckNoYXIpOworICAgICAgICBpZiAoaW5kZXggPT0gLTEgJiYgZmlyc3RJblBhdGggPiAwKSB7CisgICAgICAgICAgICBpbmRleCA9IDI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGluZGV4ID09IC0xIHx8IHBhdGguY2hhckF0KGxlbmd0aCAtIDEpID09IHNlcGFyYXRvckNoYXIpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGlmIChwYXRoLmluZGV4T2Yoc2VwYXJhdG9yQ2hhcikgPT0gaW5kZXgKKyAgICAgICAgICAgICAgICAmJiBwYXRoLmNoYXJBdChmaXJzdEluUGF0aCkgPT0gc2VwYXJhdG9yQ2hhcikgeworICAgICAgICAgICAgcmV0dXJuIHBhdGguc3Vic3RyaW5nKDAsIGluZGV4ICsgMSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHBhdGguc3Vic3RyaW5nKDAsIGluZGV4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGZpbGUgbWFkZSBmcm9tIHRoZSBwYXRobmFtZSBvZiB0aGUgcGFyZW50IG9mIHRoaXMgZmlsZS4KKyAgICAgKiBUaGlzIGlzIHRoZSBwYXRoIHVwIHRvIGJ1dCBub3QgaW5jbHVkaW5nIHRoZSBsYXN0IG5hbWUuIHtAY29kZSBudWxsfSBpcworICAgICAqIHJldHVybmVkIHdoZW4gdGhlcmUgaXMgbm8gcGFyZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIG5ldyBmaWxlIHJlcHJlc2VudGluZyB0aGlzIGZpbGUncyBwYXJlbnQgb3Ige0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBGaWxlIGdldFBhcmVudEZpbGUoKSB7CisgICAgICAgIFN0cmluZyB0ZW1wUGFyZW50ID0gZ2V0UGFyZW50KCk7CisgICAgICAgIGlmICh0ZW1wUGFyZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgRmlsZSh0ZW1wUGFyZW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwYXRoIG9mIHRoaXMgZmlsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBmaWxlJ3MgcGF0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFBhdGgoKSB7CisgICAgICAgIHJldHVybiBwYXRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW50ZWdlciBoYXNoIGNvZGUgZm9yIHRoZSByZWNlaXZlci4gQW55IHR3byBvYmplY3RzIGZvciB3aGljaAorICAgICAqIHtAY29kZSBlcXVhbHN9IHJldHVybnMge0Bjb2RlIHRydWV9IG11c3QgcmV0dXJuIHRoZSBzYW1lIGhhc2ggY29kZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBmaWxlcydzIGhhc2ggdmFsdWUuCisgICAgICogQHNlZSAjZXF1YWxzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIGdldFBhdGgoKS5oYXNoQ29kZSgpIF4gMTIzNDMyMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgaWYgdGhpcyBmaWxlJ3MgcGF0aG5hbWUgaXMgYWJzb2x1dGUuIFdoZXRoZXIgYSBwYXRobmFtZSBpcworICAgICAqIGFic29sdXRlIGlzIHBsYXRmb3JtIHNwZWNpZmljLiBPbiBBbmRyb2lkLCBhYnNvbHV0ZSBwYXRocyBzdGFydCB3aXRoCisgICAgICogdGhlIGNoYXJhY3RlciAnLycuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGZpbGUncyBwYXRobmFtZSBpcyBhYnNvbHV0ZSwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgI2dldFBhdGgKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0Fic29sdXRlKCkgeworICAgICAgICByZXR1cm4gcGF0aC5sZW5ndGgoKSA+IDAgJiYgcGF0aC5jaGFyQXQoMCkgPT0gc2VwYXJhdG9yQ2hhcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgaWYgdGhpcyBmaWxlIHJlcHJlc2VudHMgYSA8ZW0+ZGlyZWN0b3J5PC9lbT4gb24gdGhlCisgICAgICogdW5kZXJseWluZyBmaWxlIHN5c3RlbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgZmlsZSBpcyBhIGRpcmVjdG9yeSwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRGlyZWN0b3J5KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIFNfSVNESVIoTGliY29yZS5vcy5zdGF0KHBhdGgpLnN0X21vZGUpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgLy8gVGhlIFJJIHJldHVybnMgZmFsc2Ugb24gZXJyb3IuIChFdmVuIGZvciBlcnJvcnMgbGlrZSBFQUNDRVMgb3IgRUxPT1AuKQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIGlmIHRoaXMgZmlsZSByZXByZXNlbnRzIGEgPGVtPmZpbGU8L2VtPiBvbiB0aGUgdW5kZXJseWluZworICAgICAqIGZpbGUgc3lzdGVtLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBmaWxlIGlzIGEgZmlsZSwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNGaWxlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIFNfSVNSRUcoTGliY29yZS5vcy5zdGF0KHBhdGgpLnN0X21vZGUpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgLy8gVGhlIFJJIHJldHVybnMgZmFsc2Ugb24gZXJyb3IuIChFdmVuIGZvciBlcnJvcnMgbGlrZSBFQUNDRVMgb3IgRUxPT1AuKQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGlzIGZpbGUgaXMgYSBoaWRkZW4gZmlsZSBhcyBkZWZpbmVkIGJ5IHRoZQorICAgICAqIG9wZXJhdGluZyBzeXN0ZW0uIFRoZSBub3Rpb24gb2YgImhpZGRlbiIgaXMgc3lzdGVtLWRlcGVuZGVudC4gRm9yIFVuaXgKKyAgICAgKiBzeXN0ZW1zIGEgZmlsZSBpcyBjb25zaWRlcmVkIGhpZGRlbiBpZiBpdHMgbmFtZSBzdGFydHMgd2l0aCBhICIuIi4gRm9yCisgICAgICogV2luZG93cyBzeXN0ZW1zIHRoZXJlIGlzIGFuIGV4cGxpY2l0IGZsYWcgaW4gdGhlIGZpbGUgc3lzdGVtIGZvciB0aGlzCisgICAgICogcHVycG9zZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBmaWxlIGlzIGhpZGRlbiwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNIaWRkZW4oKSB7CisgICAgICAgIGlmIChwYXRoLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXROYW1lKCkuc3RhcnRzV2l0aCgiLiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRpbWUgd2hlbiB0aGlzIGZpbGUgd2FzIGxhc3QgbW9kaWZpZWQsIG1lYXN1cmVkIGluCisgICAgICogbWlsbGlzZWNvbmRzIHNpbmNlIEphbnVhcnkgMXN0LCAxOTcwLCBtaWRuaWdodC4KKyAgICAgKiBSZXR1cm5zIDAgaWYgdGhlIGZpbGUgZG9lcyBub3QgZXhpc3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB0aW1lIHdoZW4gdGhpcyBmaWxlIHdhcyBsYXN0IG1vZGlmaWVkLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGxhc3RNb2RpZmllZCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBMaWJjb3JlLm9zLnN0YXQocGF0aCkuc3RfbXRpbWUgKiAxMDAwTDsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIC8vIFRoZSBSSSByZXR1cm5zIDAgb24gZXJyb3IuIChFdmVuIGZvciBlcnJvcnMgbGlrZSBFQUNDRVMgb3IgRUxPT1AuKQorICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB0aW1lIHRoaXMgZmlsZSB3YXMgbGFzdCBtb2RpZmllZCwgbWVhc3VyZWQgaW4gbWlsbGlzZWNvbmRzIHNpbmNlCisgICAgICogSmFudWFyeSAxc3QsIDE5NzAsIG1pZG5pZ2h0LgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IHRoaXMgbWV0aG9kIGRvZXMgPGk+bm90PC9pPiB0aHJvdyB7QGNvZGUgSU9FeGNlcHRpb259IG9uIGZhaWx1cmUuCisgICAgICogQ2FsbGVycyBtdXN0IGNoZWNrIHRoZSByZXR1cm4gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGltZQorICAgICAqICAgICAgICAgICAgdGhlIGxhc3QgbW9kaWZpY2F0aW9uIHRpbWUgZm9yIHRoaXMgZmlsZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgb3BlcmF0aW9uIGlzIHN1Y2Nlc3NmdWwsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSB0aW1lIDwgMH0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc2V0TGFzdE1vZGlmaWVkKGxvbmcgdGltZSkgeworICAgICAgICBpZiAodGltZSA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInRpbWUgPCAwIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNldExhc3RNb2RpZmllZEltcGwocGF0aCwgdGltZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gc2V0TGFzdE1vZGlmaWVkSW1wbChTdHJpbmcgcGF0aCwgbG9uZyB0aW1lKTsKKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8gc2V0V3JpdGFibGUoZmFsc2UsIGZhbHNlKS4KKyAgICAgKgorICAgICAqIEBzZWUgI3NldFdyaXRhYmxlKGJvb2xlYW4sIGJvb2xlYW4pCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc2V0UmVhZE9ubHkoKSB7CisgICAgICAgIHJldHVybiBzZXRXcml0YWJsZShmYWxzZSwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1hbmlwdWxhdGVzIHRoZSBleGVjdXRlIHBlcm1pc3Npb25zIGZvciB0aGUgYWJzdHJhY3QgcGF0aCBkZXNpZ25hdGVkIGJ5CisgICAgICogdGhpcyBmaWxlLgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IHRoaXMgbWV0aG9kIGRvZXMgPGk+bm90PC9pPiB0aHJvdyB7QGNvZGUgSU9FeGNlcHRpb259IG9uIGZhaWx1cmUuCisgICAgICogQ2FsbGVycyBtdXN0IGNoZWNrIHRoZSByZXR1cm4gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhlY3V0YWJsZQorICAgICAqICAgICAgICAgICAgVG8gYWxsb3cgZXhlY3V0ZSBwZXJtaXNzaW9uIGlmIHRydWUsIG90aGVyd2lzZSBkaXNhbGxvdworICAgICAqIEBwYXJhbSBvd25lck9ubHkKKyAgICAgKiAgICAgICAgICAgIFRvIG1hbmlwdWxhdGUgZXhlY3V0ZSBwZXJtaXNzaW9uIG9ubHkgZm9yIG93bmVyIGlmIHRydWUsCisgICAgICogICAgICAgICAgICBvdGhlcndpc2UgZm9yIGV2ZXJ5b25lLiBUaGUgbWFuaXB1bGF0aW9uIHdpbGwgYXBwbHkgdG8KKyAgICAgKiAgICAgICAgICAgIGV2ZXJ5b25lIHJlZ2FyZGxlc3Mgb2YgdGhpcyB2YWx1ZSBpZiB0aGUgdW5kZXJseWluZyBzeXN0ZW0KKyAgICAgKiAgICAgICAgICAgIGRvZXMgbm90IGRpc3Rpbmd1aXNoIG93bmVyIGFuZCBvdGhlciB1c2Vycy4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgYW5kIG9ubHkgaWYgdGhlIG9wZXJhdGlvbiBzdWNjZWVkZWQuIElmIHRoZSB1c2VyIGRvZXMgbm90CisgICAgICogICAgICAgICBoYXZlIHBlcm1pc3Npb24gdG8gY2hhbmdlIHRoZSBhY2Nlc3MgcGVybWlzc2lvbnMgb2YgdGhpcyBhYnN0cmFjdAorICAgICAqICAgICAgICAgcGF0aG5hbWUgdGhlIG9wZXJhdGlvbiB3aWxsIGZhaWwuIElmIHRoZSB1bmRlcmx5aW5nIGZpbGUgc3lzdGVtCisgICAgICogICAgICAgICBkb2VzIG5vdCBzdXBwb3J0IGV4ZWN1dGUgcGVybWlzc2lvbiBhbmQgdGhlIHZhbHVlIG9mIGV4ZWN1dGFibGUKKyAgICAgKiAgICAgICAgIGlzIGZhbHNlLCB0aGlzIG9wZXJhdGlvbiB3aWxsIGZhaWwuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHNldEV4ZWN1dGFibGUoYm9vbGVhbiBleGVjdXRhYmxlLCBib29sZWFuIG93bmVyT25seSkgeworICAgICAgICByZXR1cm4gZG9DaG1vZChvd25lck9ubHkgPyBTX0lYVVNSIDogKFNfSVhVU1IgfCBTX0lYR1JQIHwgU19JWE9USCksIGV4ZWN1dGFibGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8gc2V0RXhlY3V0YWJsZShleGVjdXRhYmxlLCB0cnVlKS4KKyAgICAgKiBAc2VlICNzZXRFeGVjdXRhYmxlKGJvb2xlYW4sIGJvb2xlYW4pCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHNldEV4ZWN1dGFibGUoYm9vbGVhbiBleGVjdXRhYmxlKSB7CisgICAgICAgIHJldHVybiBzZXRFeGVjdXRhYmxlKGV4ZWN1dGFibGUsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1hbmlwdWxhdGVzIHRoZSByZWFkIHBlcm1pc3Npb25zIGZvciB0aGUgYWJzdHJhY3QgcGF0aCBkZXNpZ25hdGVkIGJ5IHRoaXMKKyAgICAgKiBmaWxlLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYWRhYmxlCisgICAgICogICAgICAgICAgICBUbyBhbGxvdyByZWFkIHBlcm1pc3Npb24gaWYgdHJ1ZSwgb3RoZXJ3aXNlIGRpc2FsbG93CisgICAgICogQHBhcmFtIG93bmVyT25seQorICAgICAqICAgICAgICAgICAgVG8gbWFuaXB1bGF0ZSByZWFkIHBlcm1pc3Npb24gb25seSBmb3Igb3duZXIgaWYgdHJ1ZSwKKyAgICAgKiAgICAgICAgICAgIG90aGVyd2lzZSBmb3IgZXZlcnlvbmUuIFRoZSBtYW5pcHVsYXRpb24gd2lsbCBhcHBseSB0bworICAgICAqICAgICAgICAgICAgZXZlcnlvbmUgcmVnYXJkbGVzcyBvZiB0aGlzIHZhbHVlIGlmIHRoZSB1bmRlcmx5aW5nIHN5c3RlbQorICAgICAqICAgICAgICAgICAgZG9lcyBub3QgZGlzdGluZ3Vpc2ggb3duZXIgYW5kIG90aGVyIHVzZXJzLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBhbmQgb25seSBpZiB0aGUgb3BlcmF0aW9uIHN1Y2NlZWRlZC4gSWYgdGhlIHVzZXIgZG9lcyBub3QKKyAgICAgKiAgICAgICAgIGhhdmUgcGVybWlzc2lvbiB0byBjaGFuZ2UgdGhlIGFjY2VzcyBwZXJtaXNzaW9ucyBvZiB0aGlzIGFic3RyYWN0CisgICAgICogICAgICAgICBwYXRobmFtZSB0aGUgb3BlcmF0aW9uIHdpbGwgZmFpbC4gSWYgdGhlIHVuZGVybHlpbmcgZmlsZSBzeXN0ZW0KKyAgICAgKiAgICAgICAgIGRvZXMgbm90IHN1cHBvcnQgcmVhZCBwZXJtaXNzaW9uIGFuZCB0aGUgdmFsdWUgb2YgcmVhZGFibGUgaXMKKyAgICAgKiAgICAgICAgIGZhbHNlLCB0aGlzIG9wZXJhdGlvbiB3aWxsIGZhaWwuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHNldFJlYWRhYmxlKGJvb2xlYW4gcmVhZGFibGUsIGJvb2xlYW4gb3duZXJPbmx5KSB7CisgICAgICAgIHJldHVybiBkb0NobW9kKG93bmVyT25seSA/IFNfSVJVU1IgOiAoU19JUlVTUiB8IFNfSVJHUlAgfCBTX0lST1RIKSwgcmVhZGFibGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8gc2V0UmVhZGFibGUocmVhZGFibGUsIHRydWUpLgorICAgICAqIEBzZWUgI3NldFJlYWRhYmxlKGJvb2xlYW4sIGJvb2xlYW4pCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHNldFJlYWRhYmxlKGJvb2xlYW4gcmVhZGFibGUpIHsKKyAgICAgICAgcmV0dXJuIHNldFJlYWRhYmxlKHJlYWRhYmxlLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYW5pcHVsYXRlcyB0aGUgd3JpdGUgcGVybWlzc2lvbnMgZm9yIHRoZSBhYnN0cmFjdCBwYXRoIGRlc2lnbmF0ZWQgYnkgdGhpcworICAgICAqIGZpbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gd3JpdGFibGUKKyAgICAgKiAgICAgICAgICAgIFRvIGFsbG93IHdyaXRlIHBlcm1pc3Npb24gaWYgdHJ1ZSwgb3RoZXJ3aXNlIGRpc2FsbG93CisgICAgICogQHBhcmFtIG93bmVyT25seQorICAgICAqICAgICAgICAgICAgVG8gbWFuaXB1bGF0ZSB3cml0ZSBwZXJtaXNzaW9uIG9ubHkgZm9yIG93bmVyIGlmIHRydWUsCisgICAgICogICAgICAgICAgICBvdGhlcndpc2UgZm9yIGV2ZXJ5b25lLiBUaGUgbWFuaXB1bGF0aW9uIHdpbGwgYXBwbHkgdG8KKyAgICAgKiAgICAgICAgICAgIGV2ZXJ5b25lIHJlZ2FyZGxlc3Mgb2YgdGhpcyB2YWx1ZSBpZiB0aGUgdW5kZXJseWluZyBzeXN0ZW0KKyAgICAgKiAgICAgICAgICAgIGRvZXMgbm90IGRpc3Rpbmd1aXNoIG93bmVyIGFuZCBvdGhlciB1c2Vycy4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgYW5kIG9ubHkgaWYgdGhlIG9wZXJhdGlvbiBzdWNjZWVkZWQuIElmIHRoZSB1c2VyIGRvZXMgbm90CisgICAgICogICAgICAgICBoYXZlIHBlcm1pc3Npb24gdG8gY2hhbmdlIHRoZSBhY2Nlc3MgcGVybWlzc2lvbnMgb2YgdGhpcyBhYnN0cmFjdAorICAgICAqICAgICAgICAgcGF0aG5hbWUgdGhlIG9wZXJhdGlvbiB3aWxsIGZhaWwuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHNldFdyaXRhYmxlKGJvb2xlYW4gd3JpdGFibGUsIGJvb2xlYW4gb3duZXJPbmx5KSB7CisgICAgICAgIHJldHVybiBkb0NobW9kKG93bmVyT25seSA/IFNfSVdVU1IgOiAoU19JV1VTUiB8IFNfSVdHUlAgfCBTX0lXT1RIKSwgd3JpdGFibGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8gc2V0V3JpdGFibGUod3JpdGFibGUsIHRydWUpLgorICAgICAqIEBzZWUgI3NldFdyaXRhYmxlKGJvb2xlYW4sIGJvb2xlYW4pCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHNldFdyaXRhYmxlKGJvb2xlYW4gd3JpdGFibGUpIHsKKyAgICAgICAgcmV0dXJuIHNldFdyaXRhYmxlKHdyaXRhYmxlLCB0cnVlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gZG9DaG1vZChpbnQgbWFzaywgYm9vbGVhbiBzZXQpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cnVjdFN0YXQgc2IgPSBMaWJjb3JlLm9zLnN0YXQocGF0aCk7CisgICAgICAgICAgICBpbnQgbmV3TW9kZSA9IHNldCA/IChzYi5zdF9tb2RlIHwgbWFzaykgOiAoc2Iuc3RfbW9kZSAmIH5tYXNrKTsKKyAgICAgICAgICAgIExpYmNvcmUub3MuY2htb2QocGF0aCwgbmV3TW9kZSk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGlzIGZpbGUgaW4gYnl0ZXMuCisgICAgICogUmV0dXJucyAwIGlmIHRoZSBmaWxlIGRvZXMgbm90IGV4aXN0LgorICAgICAqIFRoZSByZXN1bHQgZm9yIGEgZGlyZWN0b3J5IGlzIG5vdCBkZWZpbmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGluIHRoaXMgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBsZW5ndGgoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gTGliY29yZS5vcy5zdGF0KHBhdGgpLnN0X3NpemU7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAvLyBUaGUgUkkgcmV0dXJucyAwIG9uIGVycm9yLiAoRXZlbiBmb3IgZXJyb3JzIGxpa2UgRUFDQ0VTIG9yIEVMT09QLikKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBzdHJpbmdzIHdpdGggdGhlIGZpbGUgbmFtZXMgaW4gdGhlIGRpcmVjdG9yeQorICAgICAqIHJlcHJlc2VudGVkIGJ5IHRoaXMgZmlsZS4gVGhlIHJlc3VsdCBpcyB7QGNvZGUgbnVsbH0gaWYgdGhpcyBmaWxlIGlzIG5vdAorICAgICAqIGEgZGlyZWN0b3J5LgorICAgICAqIDxwPgorICAgICAqIFRoZSBlbnRyaWVzIHtAY29kZSAufSBhbmQge0Bjb2RlIC4ufSByZXByZXNlbnRpbmcgdGhlIGN1cnJlbnQgYW5kIHBhcmVudAorICAgICAqIGRpcmVjdG9yeSBhcmUgbm90IHJldHVybmVkIGFzIHBhcnQgb2YgdGhlIGxpc3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIHN0cmluZ3Mgd2l0aCBmaWxlIG5hbWVzIG9yIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nW10gbGlzdCgpIHsKKyAgICAgICAgcmV0dXJuIGxpc3RJbXBsKHBhdGgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBTdHJpbmdbXSBsaXN0SW1wbChTdHJpbmcgcGF0aCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgbGlzdCBvZiB0aGUgZmlsZXMgaW4gdGhlIGRpcmVjdG9yeSByZXByZXNlbnRlZCBieSB0aGlzIGZpbGUuIFRoaXMKKyAgICAgKiBsaXN0IGlzIHRoZW4gZmlsdGVyZWQgdGhyb3VnaCBhIEZpbGVuYW1lRmlsdGVyIGFuZCB0aGUgbmFtZXMgb2YgZmlsZXMKKyAgICAgKiB3aXRoIG1hdGNoaW5nIG5hbWVzIGFyZSByZXR1cm5lZCBhcyBhbiBhcnJheSBvZiBzdHJpbmdzLiBSZXR1cm5zCisgICAgICoge0Bjb2RlIG51bGx9IGlmIHRoaXMgZmlsZSBpcyBub3QgYSBkaXJlY3RvcnkuIElmIHtAY29kZSBmaWx0ZXJ9IGlzCisgICAgICoge0Bjb2RlIG51bGx9IHRoZW4gYWxsIGZpbGVuYW1lcyBtYXRjaC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZW50cmllcyB7QGNvZGUgLn0gYW5kIHtAY29kZSAuLn0gcmVwcmVzZW50aW5nIHRoZSBjdXJyZW50IGFuZCBwYXJlbnQKKyAgICAgKiBkaXJlY3RvcmllcyBhcmUgbm90IHJldHVybmVkIGFzIHBhcnQgb2YgdGhlIGxpc3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsdGVyCisgICAgICogICAgICAgICAgICB0aGUgZmlsdGVyIHRvIG1hdGNoIG5hbWVzIGFnYWluc3QsIG1heSBiZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBmaWxlcyBvciB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIGxpc3QoRmlsZW5hbWVGaWx0ZXIgZmlsdGVyKSB7CisgICAgICAgIFN0cmluZ1tdIGZpbGVuYW1lcyA9IGxpc3QoKTsKKyAgICAgICAgaWYgKGZpbHRlciA9PSBudWxsIHx8IGZpbGVuYW1lcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZmlsZW5hbWVzOworICAgICAgICB9CisgICAgICAgIExpc3Q8U3RyaW5nPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oZmlsZW5hbWVzLmxlbmd0aCk7CisgICAgICAgIGZvciAoU3RyaW5nIGZpbGVuYW1lIDogZmlsZW5hbWVzKSB7CisgICAgICAgICAgICBpZiAoZmlsdGVyLmFjY2VwdCh0aGlzLCBmaWxlbmFtZSkpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYWRkKGZpbGVuYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0LnRvQXJyYXkobmV3IFN0cmluZ1tyZXN1bHQuc2l6ZSgpXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBmaWxlcyBjb250YWluZWQgaW4gdGhlIGRpcmVjdG9yeSByZXByZXNlbnRlZCBieSB0aGlzCisgICAgICogZmlsZS4gVGhlIHJlc3VsdCBpcyB7QGNvZGUgbnVsbH0gaWYgdGhpcyBmaWxlIGlzIG5vdCBhIGRpcmVjdG9yeS4gVGhlCisgICAgICogcGF0aHMgb2YgdGhlIGZpbGVzIGluIHRoZSBhcnJheSBhcmUgYWJzb2x1dGUgaWYgdGhlIHBhdGggb2YgdGhpcyBmaWxlIGlzCisgICAgICogYWJzb2x1dGUsIHRoZXkgYXJlIHJlbGF0aXZlIG90aGVyd2lzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgZmlsZXMgb3Ige0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBGaWxlW10gbGlzdEZpbGVzKCkgeworICAgICAgICByZXR1cm4gZmlsZW5hbWVzVG9GaWxlcyhsaXN0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBsaXN0IG9mIHRoZSBmaWxlcyBpbiB0aGUgZGlyZWN0b3J5IHJlcHJlc2VudGVkIGJ5IHRoaXMgZmlsZS4gVGhpcworICAgICAqIGxpc3QgaXMgdGhlbiBmaWx0ZXJlZCB0aHJvdWdoIGEgRmlsZW5hbWVGaWx0ZXIgYW5kIGZpbGVzIHdpdGggbWF0Y2hpbmcKKyAgICAgKiBuYW1lcyBhcmUgcmV0dXJuZWQgYXMgYW4gYXJyYXkgb2YgZmlsZXMuIFJldHVybnMge0Bjb2RlIG51bGx9IGlmIHRoaXMKKyAgICAgKiBmaWxlIGlzIG5vdCBhIGRpcmVjdG9yeS4gSWYge0Bjb2RlIGZpbHRlcn0gaXMge0Bjb2RlIG51bGx9IHRoZW4gYWxsCisgICAgICogZmlsZW5hbWVzIG1hdGNoLgorICAgICAqIDxwPgorICAgICAqIFRoZSBlbnRyaWVzIHtAY29kZSAufSBhbmQge0Bjb2RlIC4ufSByZXByZXNlbnRpbmcgdGhlIGN1cnJlbnQgYW5kIHBhcmVudAorICAgICAqIGRpcmVjdG9yaWVzIGFyZSBub3QgcmV0dXJuZWQgYXMgcGFydCBvZiB0aGUgbGlzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWx0ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWx0ZXIgdG8gbWF0Y2ggbmFtZXMgYWdhaW5zdCwgbWF5IGJlIHtAY29kZSBudWxsfS4KKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIGZpbGVzIG9yIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZVtdIGxpc3RGaWxlcyhGaWxlbmFtZUZpbHRlciBmaWx0ZXIpIHsKKyAgICAgICAgcmV0dXJuIGZpbGVuYW1lc1RvRmlsZXMobGlzdChmaWx0ZXIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgbGlzdCBvZiB0aGUgZmlsZXMgaW4gdGhlIGRpcmVjdG9yeSByZXByZXNlbnRlZCBieSB0aGlzIGZpbGUuIFRoaXMKKyAgICAgKiBsaXN0IGlzIHRoZW4gZmlsdGVyZWQgdGhyb3VnaCBhIEZpbGVGaWx0ZXIgYW5kIG1hdGNoaW5nIGZpbGVzIGFyZQorICAgICAqIHJldHVybmVkIGFzIGFuIGFycmF5IG9mIGZpbGVzLiBSZXR1cm5zIHtAY29kZSBudWxsfSBpZiB0aGlzIGZpbGUgaXMgbm90IGEKKyAgICAgKiBkaXJlY3RvcnkuIElmIHtAY29kZSBmaWx0ZXJ9IGlzIHtAY29kZSBudWxsfSB0aGVuIGFsbCBmaWxlcyBtYXRjaC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZW50cmllcyB7QGNvZGUgLn0gYW5kIHtAY29kZSAuLn0gcmVwcmVzZW50aW5nIHRoZSBjdXJyZW50IGFuZCBwYXJlbnQKKyAgICAgKiBkaXJlY3RvcmllcyBhcmUgbm90IHJldHVybmVkIGFzIHBhcnQgb2YgdGhlIGxpc3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsdGVyCisgICAgICogICAgICAgICAgICB0aGUgZmlsdGVyIHRvIG1hdGNoIG5hbWVzIGFnYWluc3QsIG1heSBiZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBmaWxlcyBvciB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIEZpbGVbXSBsaXN0RmlsZXMoRmlsZUZpbHRlciBmaWx0ZXIpIHsKKyAgICAgICAgRmlsZVtdIGZpbGVzID0gbGlzdEZpbGVzKCk7CisgICAgICAgIGlmIChmaWx0ZXIgPT0gbnVsbCB8fCBmaWxlcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZmlsZXM7CisgICAgICAgIH0KKyAgICAgICAgTGlzdDxGaWxlPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PEZpbGU+KGZpbGVzLmxlbmd0aCk7CisgICAgICAgIGZvciAoRmlsZSBmaWxlIDogZmlsZXMpIHsKKyAgICAgICAgICAgIGlmIChmaWx0ZXIuYWNjZXB0KGZpbGUpKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChmaWxlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0LnRvQXJyYXkobmV3IEZpbGVbcmVzdWx0LnNpemUoKV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIGEgU3RyaW5nW10gY29udGFpbmluZyBmaWxlbmFtZXMgdG8gYSBGaWxlW10uCisgICAgICogTm90ZSB0aGF0IHRoZSBmaWxlbmFtZXMgbXVzdCBub3QgY29udGFpbiBzbGFzaGVzLgorICAgICAqIFRoaXMgbWV0aG9kIGlzIHRvIHJlbW92ZSBkdXBsaWNhdGlvbiBpbiB0aGUgaW1wbGVtZW50YXRpb24KKyAgICAgKiBvZiBGaWxlLmxpc3QncyBvdmVybG9hZHMuCisgICAgICovCisgICAgcHJpdmF0ZSBGaWxlW10gZmlsZW5hbWVzVG9GaWxlcyhTdHJpbmdbXSBmaWxlbmFtZXMpIHsKKyAgICAgICAgaWYgKGZpbGVuYW1lcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpbnQgY291bnQgPSBmaWxlbmFtZXMubGVuZ3RoOworICAgICAgICBGaWxlW10gcmVzdWx0ID0gbmV3IEZpbGVbY291bnRdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyArK2kpIHsKKyAgICAgICAgICAgIHJlc3VsdFtpXSA9IG5ldyBGaWxlKHRoaXMsIGZpbGVuYW1lc1tpXSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBkaXJlY3RvcnkgbmFtZWQgYnkgdGhlIHRyYWlsaW5nIGZpbGVuYW1lIG9mIHRoaXMgZmlsZS4gRG9lcworICAgICAqIG5vdCBjcmVhdGUgdGhlIGNvbXBsZXRlIHBhdGggcmVxdWlyZWQgdG8gY3JlYXRlIHRoaXMgZGlyZWN0b3J5LgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IHRoaXMgbWV0aG9kIGRvZXMgPGk+bm90PC9pPiB0aHJvdyB7QGNvZGUgSU9FeGNlcHRpb259IG9uIGZhaWx1cmUuCisgICAgICogQ2FsbGVycyBtdXN0IGNoZWNrIHRoZSByZXR1cm4gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZGlyZWN0b3J5IGhhcyBiZWVuIGNyZWF0ZWQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNta2RpcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBta2RpcigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIE9uIEFuZHJvaWQsIHdlIGRvbid0IHdhbnQgZGVmYXVsdCBwZXJtaXNzaW9ucyB0byBhbGxvdyBnbG9iYWwgYWNjZXNzLgorICAgICAgICAgICAgTGliY29yZS5vcy5ta2RpcihwYXRoLCBTX0lSV1hVKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgZGlyZWN0b3J5IG5hbWVkIGJ5IHRoZSB0cmFpbGluZyBmaWxlbmFtZSBvZiB0aGlzIGZpbGUsCisgICAgICogaW5jbHVkaW5nIHRoZSBjb21wbGV0ZSBkaXJlY3RvcnkgcGF0aCByZXF1aXJlZCB0byBjcmVhdGUgdGhpcyBkaXJlY3RvcnkuCisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoYXQgdGhpcyBtZXRob2QgZG9lcyA8aT5ub3Q8L2k+IHRocm93IHtAY29kZSBJT0V4Y2VwdGlvbn0gb24gZmFpbHVyZS4KKyAgICAgKiBDYWxsZXJzIG11c3QgY2hlY2sgdGhlIHJldHVybiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBuZWNlc3NhcnkgZGlyZWN0b3JpZXMgaGF2ZSBiZWVuIGNyZWF0ZWQsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IGlmIHRoZSB0YXJnZXQgZGlyZWN0b3J5IGFscmVhZHkgZXhpc3RzIG9yIG9uZSBvZgorICAgICAqICAgICAgICAgdGhlIGRpcmVjdG9yaWVzIGNhbiBub3QgYmUgY3JlYXRlZC4KKyAgICAgKiBAc2VlICNta2RpcgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG1rZGlycygpIHsKKyAgICAgICAgLyogSWYgdGhlIHRlcm1pbmFsIGRpcmVjdG9yeSBhbHJlYWR5IGV4aXN0cywgYW5zd2VyIGZhbHNlICovCisgICAgICAgIGlmIChleGlzdHMoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLyogSWYgdGhlIHJlY2VpdmVyIGNhbiBiZSBjcmVhdGVkLCBhbnN3ZXIgdHJ1ZSAqLworICAgICAgICBpZiAobWtkaXIoKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgcGFyZW50RGlyID0gZ2V0UGFyZW50KCk7CisgICAgICAgIC8qIElmIHRoZXJlIGlzIG5vIHBhcmVudCBhbmQgd2Ugd2VyZSBub3QgY3JlYXRlZCwgYW5zd2VyIGZhbHNlICovCisgICAgICAgIGlmIChwYXJlbnREaXIgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLyogT3RoZXJ3aXNlLCB0cnkgdG8gY3JlYXRlIGEgcGFyZW50IGRpcmVjdG9yeSBhbmQgdGhlbiB0aGlzIGRpcmVjdG9yeSAqLworICAgICAgICByZXR1cm4gKG5ldyBGaWxlKHBhcmVudERpcikubWtkaXJzKCkgJiYgbWtkaXIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldywgZW1wdHkgZmlsZSBvbiB0aGUgZmlsZSBzeXN0ZW0gYWNjb3JkaW5nIHRvIHRoZSBwYXRoCisgICAgICogaW5mb3JtYXRpb24gc3RvcmVkIGluIHRoaXMgZmlsZS4gVGhpcyBtZXRob2QgcmV0dXJucyB0cnVlIGlmIGl0IGNyZWF0ZXMKKyAgICAgKiBhIGZpbGUsIGZhbHNlIGlmIHRoZSBmaWxlIGFscmVhZHkgZXhpc3RlZC4gTm90ZSB0aGF0IGl0IHJldHVybnMgZmFsc2UKKyAgICAgKiBldmVuIGlmIHRoZSBmaWxlIGlzIG5vdCBhIGZpbGUgKGJlY2F1c2UgaXQncyBhIGRpcmVjdG9yeSwgc2F5KS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIG5vdCBnZW5lcmFsbHkgdXNlZnVsLiBGb3IgY3JlYXRpbmcgdGVtcG9yYXJ5IGZpbGVzLAorICAgICAqIHVzZSB7QGxpbmsgI2NyZWF0ZVRlbXBGaWxlfSBpbnN0ZWFkLiBGb3IgcmVhZGluZy93cml0aW5nIGZpbGVzLCB1c2Uge0BsaW5rIEZpbGVJbnB1dFN0cmVhbX0sCisgICAgICoge0BsaW5rIEZpbGVPdXRwdXRTdHJlYW19LCBvciB7QGxpbmsgUmFuZG9tQWNjZXNzRmlsZX0sIGFsbCBvZiB3aGljaCBjYW4gY3JlYXRlIGZpbGVzLgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IHRoaXMgbWV0aG9kIGRvZXMgPGk+bm90PC9pPiB0aHJvdyB7QGNvZGUgSU9FeGNlcHRpb259IGlmIHRoZSBmaWxlCisgICAgICogYWxyZWFkeSBleGlzdHMsIGV2ZW4gaWYgaXQncyBub3QgYSByZWd1bGFyIGZpbGUuIENhbGxlcnMgc2hvdWxkIGFsd2F5cyBjaGVjayB0aGUKKyAgICAgKiByZXR1cm4gdmFsdWUsIGFuZCBtYXkgYWRkaXRpb25hbGx5IHdhbnQgdG8gY2FsbCB7QGxpbmsgI2lzRmlsZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGZpbGUgaGFzIGJlZW4gY3JlYXRlZCwgZmFsc2UgaWYgaXQKKyAgICAgKiAgICAgICAgIGFscmVhZHkgZXhpc3RzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgaXQncyBub3QgcG9zc2libGUgdG8gY3JlYXRlIHRoZSBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNyZWF0ZU5ld0ZpbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBGaWxlRGVzY3JpcHRvciBmZCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBPbiBBbmRyb2lkLCB3ZSBkb24ndCB3YW50IGRlZmF1bHQgcGVybWlzc2lvbnMgdG8gYWxsb3cgZ2xvYmFsIGFjY2Vzcy4KKyAgICAgICAgICAgIGZkID0gTGliY29yZS5vcy5vcGVuKHBhdGgsIE9fUkRXUiB8IE9fQ1JFQVQgfCBPX0VYQ0wsIDA2MDApOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICBpZiAoZXJybm9FeGNlcHRpb24uZXJybm8gPT0gRUVYSVNUKSB7CisgICAgICAgICAgICAgICAgLy8gVGhlIGZpbGUgYWxyZWFkeSBleGlzdHMuCisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzSU9FeGNlcHRpb24oKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIElvVXRpbHMuY2xvc2UoZmQpOyAvLyBUT0RPOiBzaG91bGQgd2Ugc3VwcHJlc3MgSU9FeGNlcHRpb25zIHRocm93biBoZXJlPworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBlbXB0eSB0ZW1wb3JhcnkgZmlsZSB1c2luZyB0aGUgZ2l2ZW4gcHJlZml4IGFuZCBzdWZmaXggYXMgcGFydAorICAgICAqIG9mIHRoZSBmaWxlIG5hbWUuIElmIHtAY29kZSBzdWZmaXh9IGlzIG51bGwsIHtAY29kZSAudG1wfSBpcyB1c2VkLiBUaGlzCisgICAgICogbWV0aG9kIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kIHRoYXQgY2FsbHMKKyAgICAgKiB7QGxpbmsgI2NyZWF0ZVRlbXBGaWxlKFN0cmluZywgU3RyaW5nLCBGaWxlKX0gd2l0aCB0aGUgdGhpcmQgYXJndW1lbnQKKyAgICAgKiBiZWluZyB7QGNvZGUgbnVsbH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJlZml4CisgICAgICogICAgICAgICAgICB0aGUgcHJlZml4IHRvIHRoZSB0ZW1wIGZpbGUgbmFtZS4KKyAgICAgKiBAcGFyYW0gc3VmZml4CisgICAgICogICAgICAgICAgICB0aGUgc3VmZml4IHRvIHRoZSB0ZW1wIGZpbGUgbmFtZS4KKyAgICAgKiBAcmV0dXJuIHRoZSB0ZW1wb3JhcnkgZmlsZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoZW4gd3JpdGluZyB0aGUgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEZpbGUgY3JlYXRlVGVtcEZpbGUoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHN1ZmZpeCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGNyZWF0ZVRlbXBGaWxlKHByZWZpeCwgc3VmZml4LCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGVtcHR5IHRlbXBvcmFyeSBmaWxlIGluIHRoZSBnaXZlbiBkaXJlY3RvcnkgdXNpbmcgdGhlIGdpdmVuCisgICAgICogcHJlZml4IGFuZCBzdWZmaXggYXMgcGFydCBvZiB0aGUgZmlsZSBuYW1lLiBJZiB7QGNvZGUgc3VmZml4fSBpcyBudWxsLCB7QGNvZGUgLnRtcH0gaXMgdXNlZC4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB0aGlzIG1ldGhvZCBkb2VzIDxpPm5vdDwvaT4gY2FsbCB7QGxpbmsgI2RlbGV0ZU9uRXhpdH0sIGJ1dCBzZWUgdGhlCisgICAgICogZG9jdW1lbnRhdGlvbiBmb3IgdGhhdCBtZXRob2QgYmVmb3JlIHlvdSBjYWxsIGl0IG1hbnVhbGx5LgorICAgICAqCisgICAgICogQHBhcmFtIHByZWZpeAorICAgICAqICAgICAgICAgICAgdGhlIHByZWZpeCB0byB0aGUgdGVtcCBmaWxlIG5hbWUuCisgICAgICogQHBhcmFtIHN1ZmZpeAorICAgICAqICAgICAgICAgICAgdGhlIHN1ZmZpeCB0byB0aGUgdGVtcCBmaWxlIG5hbWUuCisgICAgICogQHBhcmFtIGRpcmVjdG9yeQorICAgICAqICAgICAgICAgICAgdGhlIGxvY2F0aW9uIHRvIHdoaWNoIHRoZSB0ZW1wIGZpbGUgaXMgdG8gYmUgd3JpdHRlbiwgb3IKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBudWxsfSBmb3IgdGhlIGRlZmF1bHQgbG9jYXRpb24gZm9yIHRlbXBvcmFyeSBmaWxlcywKKyAgICAgKiAgICAgICAgICAgIHdoaWNoIGlzIHRha2VuIGZyb20gdGhlICJqYXZhLmlvLnRtcGRpciIgc3lzdGVtIHByb3BlcnR5LiBJdAorICAgICAqICAgICAgICAgICAgbWF5IGJlIG5lY2Vzc2FyeSB0byBzZXQgdGhpcyBwcm9wZXJ0eSB0byBhbiBleGlzdGluZywgd3JpdGFibGUKKyAgICAgKiAgICAgICAgICAgIGRpcmVjdG9yeSBmb3IgdGhpcyBtZXRob2QgdG8gd29yayBwcm9wZXJseS4KKyAgICAgKiBAcmV0dXJuIHRoZSB0ZW1wb3JhcnkgZmlsZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBsZW5ndGggb2Yge0Bjb2RlIHByZWZpeH0gaXMgbGVzcyB0aGFuIDMuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGVuIHdyaXRpbmcgdGhlIGZpbGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBGaWxlIGNyZWF0ZVRlbXBGaWxlKFN0cmluZyBwcmVmaXgsIFN0cmluZyBzdWZmaXgsIEZpbGUgZGlyZWN0b3J5KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gRm9yY2UgYSBwcmVmaXggbnVsbCBjaGVjayBmaXJzdAorICAgICAgICBpZiAocHJlZml4Lmxlbmd0aCgpIDwgMykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicHJlZml4IG11c3QgYmUgYXQgbGVhc3QgMyBjaGFyYWN0ZXJzIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHN1ZmZpeCA9PSBudWxsKSB7CisgICAgICAgICAgICBzdWZmaXggPSAiLnRtcCI7CisgICAgICAgIH0KKyAgICAgICAgRmlsZSB0bXBEaXJGaWxlID0gZGlyZWN0b3J5OworICAgICAgICBpZiAodG1wRGlyRmlsZSA9PSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG1wRGlyID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmlvLnRtcGRpciIsICIuIik7CisgICAgICAgICAgICB0bXBEaXJGaWxlID0gbmV3IEZpbGUodG1wRGlyKTsKKyAgICAgICAgfQorICAgICAgICBGaWxlIHJlc3VsdDsKKyAgICAgICAgZG8geworICAgICAgICAgICAgcmVzdWx0ID0gbmV3IEZpbGUodG1wRGlyRmlsZSwgcHJlZml4ICsgdGVtcEZpbGVSYW5kb20ubmV4dEludCgpICsgc3VmZml4KTsKKyAgICAgICAgfSB3aGlsZSAoIXJlc3VsdC5jcmVhdGVOZXdGaWxlKCkpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbmFtZXMgdGhpcyBmaWxlIHRvIHtAY29kZSBuZXdQYXRofS4gVGhpcyBvcGVyYXRpb24gaXMgc3VwcG9ydGVkIGZvciBib3RoCisgICAgICogZmlsZXMgYW5kIGRpcmVjdG9yaWVzLgorICAgICAqCisgICAgICogPHA+TWFueSBmYWlsdXJlcyBhcmUgcG9zc2libGUuIFNvbWUgb2YgdGhlIG1vcmUgbGlrZWx5IGZhaWx1cmVzIGluY2x1ZGU6CisgICAgICogPHVsPgorICAgICAqIDxsaT5Xcml0ZSBwZXJtaXNzaW9uIGlzIHJlcXVpcmVkIG9uIHRoZSBkaXJlY3RvcmllcyBjb250YWluaW5nIGJvdGggdGhlIHNvdXJjZSBhbmQKKyAgICAgKiBkZXN0aW5hdGlvbiBwYXRocy4KKyAgICAgKiA8bGk+U2VhcmNoIHBlcm1pc3Npb24gaXMgcmVxdWlyZWQgZm9yIGFsbCBwYXJlbnRzIG9mIGJvdGggcGF0aHMuCisgICAgICogPGxpPkJvdGggcGF0aHMgYmUgb24gdGhlIHNhbWUgbW91bnQgcG9pbnQuIE9uIEFuZHJvaWQsIGFwcGxpY2F0aW9ucyBhcmUgbW9zdCBsaWtlbHkgdG8gaGl0CisgICAgICogdGhpcyByZXN0cmljdGlvbiB3aGVuIGF0dGVtcHRpbmcgdG8gY29weSBiZXR3ZWVuIGludGVybmFsIHN0b3JhZ2UgYW5kIGFuIFNEIGNhcmQuCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB0aGlzIG1ldGhvZCBkb2VzIDxpPm5vdDwvaT4gdGhyb3cge0Bjb2RlIElPRXhjZXB0aW9ufSBvbiBmYWlsdXJlLgorICAgICAqIENhbGxlcnMgbXVzdCBjaGVjayB0aGUgcmV0dXJuIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIG5ld1BhdGggdGhlIG5ldyBwYXRoLgorICAgICAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlbmFtZVRvKEZpbGUgbmV3UGF0aCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgTGliY29yZS5vcy5yZW5hbWUocGF0aCwgbmV3UGF0aC5wYXRoKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhpcworICAgICAqIGZpbGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcHJpbnRhYmxlIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgZmlsZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gcGF0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgVW5pZm9ybSBSZXNvdXJjZSBJZGVudGlmaWVyIGZvciB0aGlzIGZpbGUuIFRoZSBVUkkgaXMgc3lzdGVtCisgICAgICogZGVwZW5kZW50IGFuZCBtYXkgbm90IGJlIHRyYW5zZmVyYWJsZSBiZXR3ZWVuIGRpZmZlcmVudCBvcGVyYXRpbmcgLyBmaWxlCisgICAgICogc3lzdGVtcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gVVJJIGZvciB0aGlzIGZpbGUuCisgICAgICovCisgICAgcHVibGljIFVSSSB0b1VSSSgpIHsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBnZXRBYnNvbHV0ZU5hbWUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICghbmFtZS5zdGFydHNXaXRoKCIvIikpIHsKKyAgICAgICAgICAgICAgICAvLyBzdGFydCB3aXRoIHNlcC4KKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVSSSgiZmlsZSIsIG51bGwsICIvIiArIG5hbWUsIG51bGwsIG51bGwpOworICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLnN0YXJ0c1dpdGgoIi8vIikpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVSSSgiZmlsZSIsICIiLCBuYW1lLCBudWxsKTsgLy8gVU5DIHBhdGgKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuZXcgVVJJKCJmaWxlIiwgbnVsbCwgbmFtZSwgbnVsbCwgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKFVSSVN5bnRheEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyB0aGlzIHNob3VsZCBuZXZlciBoYXBwZW4KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIFVuaWZvcm0gUmVzb3VyY2UgTG9jYXRvciBmb3IgdGhpcyBmaWxlLiBUaGUgVVJMIGlzIHN5c3RlbQorICAgICAqIGRlcGVuZGVudCBhbmQgbWF5IG5vdCBiZSB0cmFuc2ZlcmFibGUgYmV0d2VlbiBkaWZmZXJlbnQgb3BlcmF0aW5nIC8gZmlsZQorICAgICAqIHN5c3RlbXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgVVJMIGZvciB0aGlzIGZpbGUuCisgICAgICogQHRocm93cyBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGF0aCBjYW5ub3QgYmUgdHJhbnNmb3JtZWQgaW50byBhIFVSTC4KKyAgICAgKiBAZGVwcmVjYXRlZCB1c2Uge0BsaW5rICN0b1VSSX0gYW5kIHtAbGluayBqYXZhLm5ldC5VUkkjdG9VUkx9IHRvIGdldAorICAgICAqIGNvcnJlY3QgZXNjYXBpbmcgb2YgaWxsZWdhbCBjaGFyYWN0ZXJzLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIFVSTCB0b1VSTCgpIHRocm93cyBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbmFtZSA9IGdldEFic29sdXRlTmFtZSgpOworICAgICAgICBpZiAoIW5hbWUuc3RhcnRzV2l0aCgiLyIpKSB7CisgICAgICAgICAgICAvLyBzdGFydCB3aXRoIHNlcC4KKyAgICAgICAgICAgIHJldHVybiBuZXcgVVJMKCJmaWxlIiwgIiIsIC0xLCAiLyIgKyBuYW1lLCBudWxsKTsKKyAgICAgICAgfSBlbHNlIGlmIChuYW1lLnN0YXJ0c1dpdGgoIi8vIikpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVVJMKCJmaWxlOiIgKyBuYW1lKTsgLy8gVU5DIHBhdGgKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFVSTCgiZmlsZSIsICIiLCAtMSwgbmFtZSwgbnVsbCk7CisgICAgfQorCisgICAgLy8gVE9ETzogaXMgdGhpcyByZWFsbHkgbmVjZXNzYXJ5LCBvciBjYW4gaXQgYmUgcmVwbGFjZWQgd2l0aCBnZXRBYnNvbHV0ZVBhdGg/CisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0QWJzb2x1dGVOYW1lKCkgeworICAgICAgICBGaWxlIGYgPSBnZXRBYnNvbHV0ZUZpbGUoKTsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBmLmdldFBhdGgoKTsKKyAgICAgICAgaWYgKGYuaXNEaXJlY3RvcnkoKSAmJiBuYW1lLmNoYXJBdChuYW1lLmxlbmd0aCgpIC0gMSkgIT0gc2VwYXJhdG9yQ2hhcikgeworICAgICAgICAgICAgLy8gRGlyZWN0b3JpZXMgbXVzdCBlbmQgd2l0aCBhIHNsYXNoCisgICAgICAgICAgICBuYW1lID0gbmFtZSArICIvIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoc2VwYXJhdG9yQ2hhciAhPSAnLycpIHsgLy8gTXVzdCBjb252ZXJ0IHNsYXNoZXMuCisgICAgICAgICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKHNlcGFyYXRvckNoYXIsICcvJyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN0cmVhbS5kZWZhdWx0V3JpdGVPYmplY3QoKTsKKyAgICAgICAgc3RyZWFtLndyaXRlQ2hhcihzZXBhcmF0b3JDaGFyKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIHN0cmVhbS5kZWZhdWx0UmVhZE9iamVjdCgpOworICAgICAgICBjaGFyIGluU2VwYXJhdG9yID0gc3RyZWFtLnJlYWRDaGFyKCk7CisgICAgICAgIHRoaXMucGF0aCA9IGZpeFNsYXNoZXMocGF0aC5yZXBsYWNlKGluU2VwYXJhdG9yLCBzZXBhcmF0b3JDaGFyKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdG90YWwgc2l6ZSBpbiBieXRlcyBvZiB0aGUgcGFydGl0aW9uIGNvbnRhaW5pbmcgdGhpcyBwYXRoLgorICAgICAqIFJldHVybnMgMCBpZiB0aGlzIHBhdGggZG9lcyBub3QgZXhpc3QuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0VG90YWxTcGFjZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cnVjdFN0YXRGcyBzYiA9IExpYmNvcmUub3Muc3RhdGZzKHBhdGgpOworICAgICAgICAgICAgcmV0dXJuIHNiLmZfYmxvY2tzICogc2IuZl9ic2l6ZTsgLy8gdG90YWwgYmxvY2sgY291bnQgKiBibG9jayBzaXplIGluIGJ5dGVzLgorICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgdXNhYmxlIGZyZWUgYnl0ZXMgb24gdGhlIHBhcnRpdGlvbiBjb250YWluaW5nIHRoaXMgcGF0aC4KKyAgICAgKiBSZXR1cm5zIDAgaWYgdGhpcyBwYXRoIGRvZXMgbm90IGV4aXN0LgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IHRoaXMgaXMgbGlrZWx5IHRvIGJlIGFuIG9wdGltaXN0aWMgb3Zlci1lc3RpbWF0ZSBhbmQgc2hvdWxkIG5vdAorICAgICAqIGJlIHRha2VuIGFzIGEgZ3VhcmFudGVlIHlvdXIgYXBwbGljYXRpb24gY2FuIGFjdHVhbGx5IHdyaXRlIHRoaXMgbWFueSBieXRlcy4KKyAgICAgKiBPbiBBbmRyb2lkIChhbmQgb3RoZXIgVW5peC1iYXNlZCBzeXN0ZW1zKSwgdGhpcyBtZXRob2QgcmV0dXJucyB0aGUgbnVtYmVyIG9mIGZyZWUgYnl0ZXMKKyAgICAgKiBhdmFpbGFibGUgdG8gbm9uLXJvb3QgdXNlcnMsIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB5b3UncmUgYWN0dWFsbHkgcnVubmluZyBhcyByb290LAorICAgICAqIGFuZCByZWdhcmRsZXNzIG9mIGFueSBxdW90YSBvciBvdGhlciByZXN0cmljdGlvbnMgdGhhdCBtaWdodCBhcHBseSB0byB0aGUgdXNlci4KKyAgICAgKiAoVGhlIHtAY29kZSBnZXRGcmVlU3BhY2V9IG1ldGhvZCByZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgcG90ZW50aWFsbHkgYXZhaWxhYmxlIHRvIHJvb3QuKQorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFVzYWJsZVNwYWNlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RydWN0U3RhdEZzIHNiID0gTGliY29yZS5vcy5zdGF0ZnMocGF0aCk7CisgICAgICAgICAgICByZXR1cm4gc2IuZl9iYXZhaWwgKiBzYi5mX2JzaXplOyAvLyBub24tcm9vdCBmcmVlIGJsb2NrIGNvdW50ICogYmxvY2sgc2l6ZSBpbiBieXRlcy4KKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGZyZWUgYnl0ZXMgb24gdGhlIHBhcnRpdGlvbiBjb250YWluaW5nIHRoaXMgcGF0aC4KKyAgICAgKiBSZXR1cm5zIDAgaWYgdGhpcyBwYXRoIGRvZXMgbm90IGV4aXN0LgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IHRoaXMgaXMgbGlrZWx5IHRvIGJlIGFuIG9wdGltaXN0aWMgb3Zlci1lc3RpbWF0ZSBhbmQgc2hvdWxkIG5vdAorICAgICAqIGJlIHRha2VuIGFzIGEgZ3VhcmFudGVlIHlvdXIgYXBwbGljYXRpb24gY2FuIGFjdHVhbGx5IHdyaXRlIHRoaXMgbWFueSBieXRlcy4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRGcmVlU3BhY2UoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJ1Y3RTdGF0RnMgc2IgPSBMaWJjb3JlLm9zLnN0YXRmcyhwYXRoKTsKKyAgICAgICAgICAgIHJldHVybiBzYi5mX2JmcmVlICogc2IuZl9ic2l6ZTsgLy8gZnJlZSBibG9jayBjb3VudCAqIGJsb2NrIHNpemUgaW4gYnl0ZXMuCisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0ZpbGVEZXNjcmlwdG9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWxlRGVzY3JpcHRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYwNGFlMmMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWxlRGVzY3JpcHRvci5qYXZhCkBAIC0wLDAgKzEsMTA3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKK2ltcG9ydCBsaWJjb3JlLmlvLkVycm5vRXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUuaW8uTGliY29yZTsKK2ltcG9ydCBzdGF0aWMgbGliY29yZS5pby5Pc0NvbnN0YW50cy4qOworCisvKioKKyAqIFdyYXBzIGEgVW5peCBmaWxlIGRlc2NyaXB0b3IuIEl0J3MgcG9zc2libGUgdG8gZ2V0IHRoZSBmaWxlIGRlc2NyaXB0b3IgdXNlZCBieSBzb21lCisgKiBjbGFzc2VzIChzdWNoIGFzIHtAbGluayBGaWxlSW5wdXRTdHJlYW19LCB7QGxpbmsgRmlsZU91dHB1dFN0cmVhbX0sCisgKiBhbmQge0BsaW5rIFJhbmRvbUFjY2Vzc0ZpbGV9KSwgYW5kIHRoZW4gY3JlYXRlIG5ldyBzdHJlYW1zIHRoYXQgcG9pbnQgdG8gdGhlIHNhbWUKKyAqIGZpbGUgZGVzY3JpcHRvci4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEZpbGVEZXNjcmlwdG9yIHsKKworICAgIC8qKgorICAgICAqIENvcnJlc3BvbmRzIHRvIHtAY29kZSBzdGRpbn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWxlRGVzY3JpcHRvciBpbiA9IG5ldyBGaWxlRGVzY3JpcHRvcigpOworCisgICAgLyoqCisgICAgICogQ29ycmVzcG9uZHMgdG8ge0Bjb2RlIHN0ZG91dH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWxlRGVzY3JpcHRvciBvdXQgPSBuZXcgRmlsZURlc2NyaXB0b3IoKTsKKworICAgIC8qKgorICAgICAqIENvcnJlc3BvbmRzIHRvIHtAY29kZSBzdGRlcnJ9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmlsZURlc2NyaXB0b3IgZXJyID0gbmV3IEZpbGVEZXNjcmlwdG9yKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgVW5peCBmaWxlIGRlc2NyaXB0b3IgYmFja2luZyB0aGlzIEZpbGVEZXNjcmlwdG9yLgorICAgICAqIEEgdmFsdWUgb2YgLTEgaW5kaWNhdGVzIHRoYXQgdGhpcyBGaWxlRGVzY3JpcHRvciBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHByaXZhdGUgaW50IGRlc2NyaXB0b3IgPSAtMTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIGluLmRlc2NyaXB0b3IgPSBTVERJTl9GSUxFTk87CisgICAgICAgIG91dC5kZXNjcmlwdG9yID0gU1RET1VUX0ZJTEVOTzsKKyAgICAgICAgZXJyLmRlc2NyaXB0b3IgPSBTVERFUlJfRklMRU5POworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW52YWxpZCBGaWxlRGVzY3JpcHRvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3IoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5zdXJlcyB0aGF0IGRhdGEgd2hpY2ggaXMgYnVmZmVyZWQgd2l0aGluIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uCisgICAgICogaXMgd3JpdHRlbiBvdXQgdG8gdGhlIGFwcHJvcHJpYXRlIGRldmljZSBiZWZvcmUgcmV0dXJuaW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHN5bmMoKSB0aHJvd3MgU3luY0ZhaWxlZEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMaWJjb3JlLm9zLmZzeW5jKHRoaXMpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgU3luY0ZhaWxlZEV4Y2VwdGlvbiBzZmUgPSBuZXcgU3luY0ZhaWxlZEV4Y2VwdGlvbihlcnJub0V4Y2VwdGlvbi5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgc2ZlLmluaXRDYXVzZShlcnJub0V4Y2VwdGlvbik7CisgICAgICAgICAgICB0aHJvdyBzZmU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB3aGV0aGVyIHRoaXMge0Bjb2RlIEZpbGVEZXNjcmlwdG9yfSBpcyB2YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB2YWxpZCgpIHsKKyAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3IgIT0gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW50IGZkLiBJdCdzIGhpZ2hseSB1bmxpa2VseSB5b3Ugc2hvdWxkIGJlIGNhbGxpbmcgdGhpcy4gUGxlYXNlIGRpc2N1c3MKKyAgICAgKiB5b3VyIG5lZWRzIHdpdGggYSBsaWJjb3JlIG1haW50YWluZXIgYmVmb3JlIHVzaW5nIHRoaXMgbWV0aG9kLgorICAgICAqIEBoaWRlIGludGVybmFsIHVzZSBvbmx5CisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRJbnQkKCkgeworICAgICAgICByZXR1cm4gZGVzY3JpcHRvcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBpbnQgZmQuIEl0J3MgaGlnaGx5IHVubGlrZWx5IHlvdSBzaG91bGQgYmUgY2FsbGluZyB0aGlzLiBQbGVhc2UgZGlzY3VzcworICAgICAqIHlvdXIgbmVlZHMgd2l0aCBhIGxpYmNvcmUgbWFpbnRhaW5lciBiZWZvcmUgdXNpbmcgdGhpcyBtZXRob2QuCisgICAgICogQGhpZGUgaW50ZXJuYWwgdXNlIG9ubHkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRJbnQkKGludCBmZCkgeworICAgICAgICB0aGlzLmRlc2NyaXB0b3IgPSBmZDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuICJGaWxlRGVzY3JpcHRvclsiICsgZGVzY3JpcHRvciArICJdIjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWxlRmlsdGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWxlRmlsdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGEzNmZhOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0ZpbGVGaWx0ZXIuamF2YQpAQCAtMCwwICsxLDM3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKKy8qKgorICogQW4gaW50ZXJmYWNlIGZvciBmaWx0ZXJpbmcge0BsaW5rIEZpbGV9IG9iamVjdHMgYmFzZWQgb24gdGhlaXIgbmFtZXMKKyAqIG9yIG90aGVyIGluZm9ybWF0aW9uLgorICoKKyAqIEBzZWUgRmlsZSNsaXN0RmlsZXMoRmlsZUZpbHRlcikKKyAqLworcHVibGljIGludGVyZmFjZSBGaWxlRmlsdGVyIHsKKworICAgIC8qKgorICAgICAqIEluZGljYXRpbmcgd2hldGhlciBhIHNwZWNpZmljIGZpbGUgc2hvdWxkIGJlIGluY2x1ZGVkIGluIGEgcGF0aG5hbWUgbGlzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXRobmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGFic3RyYWN0IGZpbGUgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGZpbGUgc2hvdWxkIGJlIGluY2x1ZGVkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gYWNjZXB0KEZpbGUgcGF0aG5hbWUpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRmlsZUlucHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWxlSW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Mzc2MDdhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRmlsZUlucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwyMDAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGRhbHZpay5zeXN0ZW0uQ2xvc2VHdWFyZDsKKworaW1wb3J0IGphdmEubmlvLk5pb1V0aWxzOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkZpbGVDaGFubmVsOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgbGliY29yZS5pby5FcnJub0V4Y2VwdGlvbjsKK2ltcG9ydCBsaWJjb3JlLmlvLklvQnJpZGdlOworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKK2ltcG9ydCBsaWJjb3JlLmlvLkxpYmNvcmU7CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworaW1wb3J0IHN0YXRpYyBsaWJjb3JlLmlvLk9zQ29uc3RhbnRzLio7CisKKy8qKgorICogQW4gaW5wdXQgc3RyZWFtIHRoYXQgcmVhZHMgYnl0ZXMgZnJvbSBhIGZpbGUuCisgKiA8cHJlPiAgIHtAY29kZQorICogICBGaWxlIGZpbGUgPSAuLi4KKyAqICAgSW5wdXRTdHJlYW0gaW4gPSBudWxsOworICogICB0cnkgeworICogICAgIGluID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKSk7CisgKiAgICAgLi4uCisgKiAgIH0gZmluYWxseSB7CisgKiAgICAgaWYgKGluICE9IG51bGwpIHsKKyAqICAgICAgIGluLmNsb3NlKCk7CisgKiAgICAgfQorICogICB9CisgKiB9PC9wcmU+CisgKgorICogPHA+VGhpcyBzdHJlYW0gaXMgPHN0cm9uZz5ub3QgYnVmZmVyZWQ8L3N0cm9uZz4uIE1vc3QgY2FsbGVycyBzaG91bGQgd3JhcAorICogdGhpcyBzdHJlYW0gd2l0aCBhIHtAbGluayBCdWZmZXJlZElucHV0U3RyZWFtfS4KKyAqCisgKiA8cD5Vc2Uge0BsaW5rIEZpbGVSZWFkZXJ9IHRvIHJlYWQgY2hhcmFjdGVycywgYXMgb3Bwb3NlZCB0byBieXRlcywgZnJvbSBhCisgKiBmaWxlLgorICoKKyAqIEBzZWUgQnVmZmVyZWRJbnB1dFN0cmVhbQorICogQHNlZSBGaWxlT3V0cHV0U3RyZWFtCisgKi8KK3B1YmxpYyBjbGFzcyBGaWxlSW5wdXRTdHJlYW0gZXh0ZW5kcyBJbnB1dFN0cmVhbSBpbXBsZW1lbnRzIENsb3NlYWJsZSB7CisKKyAgICBwcml2YXRlIEZpbGVEZXNjcmlwdG9yIGZkOworICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBzaG91bGRDbG9zZTsKKworICAgIC8qKiBUaGUgdW5pcXVlIGZpbGUgY2hhbm5lbC4gTGF6aWx5IGluaXRpYWxpemVkIGJlY2F1c2UgaXQncyByYXJlbHkgbmVlZGVkLiAqLworICAgIHByaXZhdGUgRmlsZUNoYW5uZWwgY2hhbm5lbDsKKworICAgIHByaXZhdGUgZmluYWwgQ2xvc2VHdWFyZCBndWFyZCA9IENsb3NlR3VhcmQuZ2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBGaWxlSW5wdXRTdHJlYW19IHRoYXQgcmVhZHMgZnJvbSB7QGNvZGUgZmlsZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZQorICAgICAqICAgICAgICAgICAgdGhlIGZpbGUgZnJvbSB3aGljaCB0aGlzIHN0cmVhbSByZWFkcy4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBmaWxlfSBkb2VzIG5vdCBleGlzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZUlucHV0U3RyZWFtKEZpbGUgZmlsZSkgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChmaWxlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiZmlsZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5mZCA9IElvQnJpZGdlLm9wZW4oZmlsZS5nZXRBYnNvbHV0ZVBhdGgoKSwgT19SRE9OTFkpOworICAgICAgICB0aGlzLnNob3VsZENsb3NlID0gdHJ1ZTsKKyAgICAgICAgZ3VhcmQub3BlbigiY2xvc2UiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBGaWxlSW5wdXRTdHJlYW19IHRoYXQgcmVhZHMgZnJvbSB7QGNvZGUgZmR9LgorICAgICAqCisgICAgICogQHBhcmFtIGZkCisgICAgICogICAgICAgICAgICB0aGUgRmlsZURlc2NyaXB0b3IgZnJvbSB3aGljaCB0aGlzIHN0cmVhbSByZWFkcy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGZkfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIEZpbGVJbnB1dFN0cmVhbShGaWxlRGVzY3JpcHRvciBmZCkgeworICAgICAgICBpZiAoZmQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJmZCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5mZCA9IGZkOworICAgICAgICB0aGlzLnNob3VsZENsb3NlID0gZmFsc2U7CisgICAgICAgIC8vIE5vdGUgdGhhdCB3ZSBkbyBub3QgY2FsbCBndWFyZC5vcGVuIGhlcmUgYmVjYXVzZSB0aGUKKyAgICAgICAgLy8gRmlsZURlc2NyaXB0b3IgaXMgbm90IG93bmVkIGJ5IHRoZSBzdHJlYW0uCisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgbmV3IEZpbGVJbnB1dFN0cmVhbShuZXcgRmlsZShwYXRoKSl9LgorICAgICAqLworICAgIHB1YmxpYyBGaWxlSW5wdXRTdHJlYW0oU3RyaW5nIHBhdGgpIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICB0aGlzKG5ldyBGaWxlKHBhdGgpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBJb0JyaWRnZS5hdmFpbGFibGUoZmQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZ3VhcmQuY2xvc2UoKTsKKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICBpZiAoY2hhbm5lbCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgY2hhbm5lbC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHNob3VsZENsb3NlKSB7CisgICAgICAgICAgICAgICAgSW9VdGlscy5jbG9zZShmZCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIEFuIG93bmVkIGZkIGhhcyBiZWVuIGludmFsaWRhdGVkIGJ5IElvVXRpbHMuY2xvc2UsIGJ1dAorICAgICAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gZXhwbGljaXRseSBzdG9wIHVzaW5nIGFuIHVub3duZWQgZmQgKGh0dHA6Ly9iLzQzNjEwNzYpLgorICAgICAgICAgICAgICAgIGZkID0gbmV3IEZpbGVEZXNjcmlwdG9yKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbnN1cmVzIHRoYXQgYWxsIHJlc291cmNlcyBmb3IgdGhpcyBzdHJlYW0gYXJlIHJlbGVhc2VkIHdoZW4gaXQgaXMgYWJvdXQKKyAgICAgKiB0byBiZSBnYXJiYWdlIGNvbGxlY3RlZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYXR0ZW1wdGluZyB0byBmaW5hbGl6ZSB0aGlzIHN0cmVhbS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGd1YXJkICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBndWFyZC53YXJuSWZPcGVuKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjbG9zZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdXBlci5maW5hbGl6ZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICAvLyBmb3IgY29uc2lzdGVuY3kgd2l0aCB0aGUgUkksIHdlIG11c3Qgb3ZlcnJpZGUgT2JqZWN0LmZpbmFsaXplKCkgdG8KKyAgICAgICAgICAgICAgICAvLyByZW1vdmUgdGhlICd0aHJvd3MgVGhyb3dhYmxlJyBjbGF1c2UuCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHJlYWQtb25seSB7QGxpbmsgRmlsZUNoYW5uZWx9IHRoYXQgc2hhcmVzIGl0cyBwb3NpdGlvbiB3aXRoCisgICAgICogdGhpcyBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIEZpbGVDaGFubmVsIGdldENoYW5uZWwoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgaWYgKGNoYW5uZWwgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGNoYW5uZWwgPSBOaW9VdGlscy5uZXdGaWxlQ2hhbm5lbCh0aGlzLCBmZCwgT19SRE9OTFkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGNoYW5uZWw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB1bmRlcmx5aW5nIGZpbGUgZGVzY3JpcHRvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgRmlsZURlc2NyaXB0b3IgZ2V0RkQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZmQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBTdHJlYW1zLnJlYWRTaW5nbGVCeXRlKHRoaXMpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGJ1ZmZlciwgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBJb0JyaWRnZS5yZWFkKGZkLCBidWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgc2tpcChsb25nIGJ5dGVDb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGJ5dGVDb3VudCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiYnl0ZUNvdW50IDwgMDogIiArIGJ5dGVDb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFRyeSBsc2VlaygyKS4gVGhhdCByZXR1cm5zIHRoZSBuZXcgb2Zmc2V0LCBidXQgd2UnbGwgdGhyb3cgYW4KKyAgICAgICAgICAgIC8vIGV4Y2VwdGlvbiBpZiBpdCBjb3VsZG4ndCBwZXJmb3JtIGV4YWN0bHkgdGhlIHNlZWsgd2UgYXNrZWQgZm9yLgorICAgICAgICAgICAgTGliY29yZS5vcy5sc2VlayhmZCwgYnl0ZUNvdW50LCBTRUVLX0NVUik7CisgICAgICAgICAgICByZXR1cm4gYnl0ZUNvdW50OworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgaWYgKGVycm5vRXhjZXB0aW9uLmVycm5vID09IEVTUElQRSkgeworICAgICAgICAgICAgICAgIC8vIFlvdSBjYW4ndCBzZWVrIG9uIGEgcGlwZSwgc28gZmFsbCBiYWNrIHRvIHRoZSBzdXBlcmNsYXNzJyBpbXBsZW1lbnRhdGlvbi4KKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuc2tpcChieXRlQ291bnQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzSU9FeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0ZpbGVOb3RGb3VuZEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRmlsZU5vdEZvdW5kRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTcxYWY2ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0ZpbGVOb3RGb3VuZEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworLyoqCisgKiBUaHJvd24gd2hlbiBhIGZpbGUgc3BlY2lmaWVkIGJ5IGEgcHJvZ3JhbSBjYW5ub3QgYmUgZm91bmQuCisgKi8KK3B1YmxpYyBjbGFzcyBGaWxlTm90Rm91bmRFeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODk3ODU2OTczODIzNzEwNDkyTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbn0gd2l0aCBpdHMgc3RhY2sgdHJhY2UKKyAgICAgKiBmaWxsZWQgaW4uCisgICAgICovCisgICAgcHVibGljIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBGaWxlTm90Rm91bmRFeGNlcHRpb259IHdpdGggaXRzIHN0YWNrIHRyYWNlIGFuZAorICAgICAqIGRldGFpbCBtZXNzYWdlIGZpbGxlZCBpbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBGaWxlTm90Rm91bmRFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRmlsZU91dHB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRmlsZU91dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY3ODcxMTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWxlT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxOTQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGRhbHZpay5zeXN0ZW0uQ2xvc2VHdWFyZDsKK2ltcG9ydCBqYXZhLm5pby5OaW9VdGlsczsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5GaWxlQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGxpYmNvcmUuaW8uSW9CcmlkZ2U7CitpbXBvcnQgbGliY29yZS5pby5Jb1V0aWxzOworaW1wb3J0IHN0YXRpYyBsaWJjb3JlLmlvLk9zQ29uc3RhbnRzLio7CisKKy8qKgorICogQW4gb3V0cHV0IHN0cmVhbSB0aGF0IHdyaXRlcyBieXRlcyB0byBhIGZpbGUuIElmIHRoZSBvdXRwdXQgZmlsZSBleGlzdHMsIGl0CisgKiBjYW4gYmUgcmVwbGFjZWQgb3IgYXBwZW5kZWQgdG8uIElmIGl0IGRvZXMgbm90IGV4aXN0LCBhIG5ldyBmaWxlIHdpbGwgYmUKKyAqIGNyZWF0ZWQuCisgKiA8cHJlPiAgIHtAY29kZQorICogICBGaWxlIGZpbGUgPSAuLi4KKyAqICAgT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgKiAgIHRyeSB7CisgKiAgICAgb3V0ID0gbmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZpbGUpKTsKKyAqICAgICAuLi4KKyAqICAgfSBmaW5hbGx5IHsKKyAqICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAqICAgICAgIG91dC5jbG9zZSgpOworICogICAgIH0KKyAqICAgfQorICogfTwvcHJlPgorICoKKyAqIDxwPlRoaXMgc3RyZWFtIGlzIDxzdHJvbmc+bm90IGJ1ZmZlcmVkPC9zdHJvbmc+LiBNb3N0IGNhbGxlcnMgc2hvdWxkIHdyYXAKKyAqIHRoaXMgc3RyZWFtIHdpdGggYSB7QGxpbmsgQnVmZmVyZWRPdXRwdXRTdHJlYW19LgorICoKKyAqIDxwPlVzZSB7QGxpbmsgRmlsZVdyaXRlcn0gdG8gd3JpdGUgY2hhcmFjdGVycywgYXMgb3Bwb3NlZCB0byBieXRlcywgdG8gYSBmaWxlLgorICoKKyAqIEBzZWUgQnVmZmVyZWRPdXRwdXRTdHJlYW0KKyAqIEBzZWUgRmlsZUlucHV0U3RyZWFtCisgKi8KK3B1YmxpYyBjbGFzcyBGaWxlT3V0cHV0U3RyZWFtIGV4dGVuZHMgT3V0cHV0U3RyZWFtIGltcGxlbWVudHMgQ2xvc2VhYmxlIHsKKworICAgIHByaXZhdGUgRmlsZURlc2NyaXB0b3IgZmQ7CisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHNob3VsZENsb3NlOworCisgICAgLyoqIFRoZSB1bmlxdWUgZmlsZSBjaGFubmVsLiBMYXppbHkgaW5pdGlhbGl6ZWQgYmVjYXVzZSBpdCdzIHJhcmVseSBuZWVkZWQuICovCisgICAgcHJpdmF0ZSBGaWxlQ2hhbm5lbCBjaGFubmVsOworCisgICAgLyoqIEZpbGUgYWNjZXNzIG1vZGUgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBtb2RlOworCisgICAgcHJpdmF0ZSBmaW5hbCBDbG9zZUd1YXJkIGd1YXJkID0gQ2xvc2VHdWFyZC5nZXQoKTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEZpbGVPdXRwdXRTdHJlYW19IHRoYXQgd3JpdGVzIHRvIHtAY29kZSBmaWxlfS4gVGhlIGZpbGUgd2lsbCBiZQorICAgICAqIHRydW5jYXRlZCBpZiBpdCBleGlzdHMsIGFuZCBjcmVhdGVkIGlmIGl0IGRvZXNuJ3QgZXhpc3QuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBpZiBmaWxlIGNhbm5vdCBiZSBvcGVuZWQgZm9yIHdyaXRpbmcuCisgICAgICovCisgICAgcHVibGljIEZpbGVPdXRwdXRTdHJlYW0oRmlsZSBmaWxlKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhmaWxlLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRmlsZU91dHB1dFN0cmVhbX0gdGhhdCB3cml0ZXMgdG8ge0Bjb2RlIGZpbGV9LgorICAgICAqIElmIHtAY29kZSBhcHBlbmR9IGlzIHRydWUgYW5kIHRoZSBmaWxlIGFscmVhZHkgZXhpc3RzLCBpdCB3aWxsIGJlIGFwcGVuZGVkIHRvOyBvdGhlcndpc2UKKyAgICAgKiBpdCB3aWxsIGJlIHRydW5jYXRlZC4gVGhlIGZpbGUgd2lsbCBiZSBjcmVhdGVkIGlmIGl0IGRvZXMgbm90IGV4aXN0LgorICAgICAqCisgICAgICogQHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24gaWYgdGhlIGZpbGUgY2Fubm90IGJlIG9wZW5lZCBmb3Igd3JpdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZU91dHB1dFN0cmVhbShGaWxlIGZpbGUsIGJvb2xlYW4gYXBwZW5kKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGZpbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJmaWxlID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLm1vZGUgPSBPX1dST05MWSB8IE9fQ1JFQVQgfCAoYXBwZW5kID8gT19BUFBFTkQgOiBPX1RSVU5DKTsKKyAgICAgICAgdGhpcy5mZCA9IElvQnJpZGdlLm9wZW4oZmlsZS5nZXRBYnNvbHV0ZVBhdGgoKSwgbW9kZSk7CisgICAgICAgIHRoaXMuc2hvdWxkQ2xvc2UgPSB0cnVlOworICAgICAgICB0aGlzLmd1YXJkLm9wZW4oImNsb3NlIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRmlsZU91dHB1dFN0cmVhbX0gdGhhdCB3cml0ZXMgdG8ge0Bjb2RlIGZkfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIGZkfSBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBGaWxlT3V0cHV0U3RyZWFtKEZpbGVEZXNjcmlwdG9yIGZkKSB7CisgICAgICAgIGlmIChmZCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImZkID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmZkID0gZmQ7CisgICAgICAgIHRoaXMuc2hvdWxkQ2xvc2UgPSBmYWxzZTsKKyAgICAgICAgdGhpcy5tb2RlID0gT19XUk9OTFk7CisgICAgICAgIHRoaXMuY2hhbm5lbCA9IE5pb1V0aWxzLm5ld0ZpbGVDaGFubmVsKHRoaXMsIGZkLCBtb2RlKTsKKyAgICAgICAgLy8gTm90ZSB0aGF0IHdlIGRvIG5vdCBjYWxsIGd1YXJkLm9wZW4gaGVyZSBiZWNhdXNlIHRoZQorICAgICAgICAvLyBGaWxlRGVzY3JpcHRvciBpcyBub3Qgb3duZWQgYnkgdGhlIHN0cmVhbS4KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBGaWxlT3V0cHV0U3RyZWFtfSB0aGF0IHdyaXRlcyB0byB7QGNvZGUgcGF0aH0uIFRoZSBmaWxlIHdpbGwgYmUKKyAgICAgKiB0cnVuY2F0ZWQgaWYgaXQgZXhpc3RzLCBhbmQgY3JlYXRlZCBpZiBpdCBkb2Vzbid0IGV4aXN0LgorICAgICAqCisgICAgICogQHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24gaWYgZmlsZSBjYW5ub3QgYmUgb3BlbmVkIGZvciB3cml0aW5nLgorICAgICAqLworICAgIHB1YmxpYyBGaWxlT3V0cHV0U3RyZWFtKFN0cmluZyBwYXRoKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhwYXRoLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRmlsZU91dHB1dFN0cmVhbX0gdGhhdCB3cml0ZXMgdG8ge0Bjb2RlIHBhdGh9LgorICAgICAqIElmIHtAY29kZSBhcHBlbmR9IGlzIHRydWUgYW5kIHRoZSBmaWxlIGFscmVhZHkgZXhpc3RzLCBpdCB3aWxsIGJlIGFwcGVuZGVkIHRvOyBvdGhlcndpc2UKKyAgICAgKiBpdCB3aWxsIGJlIHRydW5jYXRlZC4gVGhlIGZpbGUgd2lsbCBiZSBjcmVhdGVkIGlmIGl0IGRvZXMgbm90IGV4aXN0LgorICAgICAqCisgICAgICogQHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24gaWYgdGhlIGZpbGUgY2Fubm90IGJlIG9wZW5lZCBmb3Igd3JpdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZU91dHB1dFN0cmVhbShTdHJpbmcgcGF0aCwgYm9vbGVhbiBhcHBlbmQpIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICB0aGlzKG5ldyBGaWxlKHBhdGgpLCBhcHBlbmQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZ3VhcmQuY2xvc2UoKTsKKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICBpZiAoY2hhbm5lbCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgY2hhbm5lbC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHNob3VsZENsb3NlKSB7CisgICAgICAgICAgICAgICAgSW9VdGlscy5jbG9zZShmZCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIEFuIG93bmVkIGZkIGhhcyBiZWVuIGludmFsaWRhdGVkIGJ5IElvVXRpbHMuY2xvc2UsIGJ1dAorICAgICAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gZXhwbGljaXRseSBzdG9wIHVzaW5nIGFuIHVub3duZWQgZmQgKGh0dHA6Ly9iLzQzNjEwNzYpLgorICAgICAgICAgICAgICAgIGZkID0gbmV3IEZpbGVEZXNjcmlwdG9yKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGd1YXJkICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBndWFyZC53YXJuSWZPcGVuKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjbG9zZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdXBlci5maW5hbGl6ZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICAvLyBmb3IgY29uc2lzdGVuY3kgd2l0aCB0aGUgUkksIHdlIG11c3Qgb3ZlcnJpZGUgT2JqZWN0LmZpbmFsaXplKCkgdG8KKyAgICAgICAgICAgICAgICAvLyByZW1vdmUgdGhlICd0aHJvd3MgVGhyb3dhYmxlJyBjbGF1c2UuCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHdyaXRlLW9ubHkge0BsaW5rIEZpbGVDaGFubmVsfSB0aGF0IHNoYXJlcyBpdHMgcG9zaXRpb24gd2l0aAorICAgICAqIHRoaXMgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyBGaWxlQ2hhbm5lbCBnZXRDaGFubmVsKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGlmIChjaGFubmVsID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjaGFubmVsID0gTmlvVXRpbHMubmV3RmlsZUNoYW5uZWwodGhpcywgZmQsIG1vZGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGNoYW5uZWw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB1bmRlcmx5aW5nIGZpbGUgZGVzY3JpcHRvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgRmlsZURlc2NyaXB0b3IgZ2V0RkQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZmQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGJ1ZmZlciwgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIElvQnJpZGdlLndyaXRlKGZkLCBidWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IG9uZUJ5dGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlKG5ldyBieXRlW10geyAoYnl0ZSkgb25lQnl0ZSB9LCAwLCAxKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWxlUGVybWlzc2lvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRmlsZVBlcm1pc3Npb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNDI5ZjUyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRmlsZVBlcm1pc3Npb24uamF2YQpAQCAtMCwwICsxLDMxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBGaWxlUGVybWlzc2lvbiBleHRlbmRzIFBlcm1pc3Npb24gaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworICAgIHB1YmxpYyBGaWxlUGVybWlzc2lvbihTdHJpbmcgcGF0aCwgU3RyaW5nIGFjdGlvbnMpIHsgc3VwZXIoIiIpOyB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyBnZXRBY3Rpb25zKCkgeyByZXR1cm4gbnVsbDsgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGltcGxpZXMoUGVybWlzc2lvbiBwZXJtaXNzaW9uKSB7IHJldHVybiB0cnVlOyB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWxlUmVhZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWxlUmVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmNiODJiNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0ZpbGVSZWFkZXIuamF2YQpAQCAtMCwwICsxLDY4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKKy8qKgorICogQSBzcGVjaWFsaXplZCB7QGxpbmsgUmVhZGVyfSB0aGF0IHJlYWRzIGZyb20gYSBmaWxlIGluIHRoZSBmaWxlIHN5c3RlbS4KKyAqIEFsbCByZWFkIHJlcXVlc3RzIG1hZGUgYnkgY2FsbGluZyBtZXRob2RzIGluIHRoaXMgY2xhc3MgYXJlIGRpcmVjdGx5CisgKiBmb3J3YXJkZWQgdG8gdGhlIGVxdWl2YWxlbnQgZnVuY3Rpb24gb2YgdGhlIHVuZGVybHlpbmcgb3BlcmF0aW5nIHN5c3RlbS4KKyAqIFNpbmNlIHRoaXMgbWF5IGluZHVjZSBzb21lIHBlcmZvcm1hbmNlIHBlbmFsdHksIGluIHBhcnRpY3VsYXIgaWYgbWFueSBzbWFsbAorICogcmVhZCByZXF1ZXN0cyBhcmUgbWFkZSwgYSBGaWxlUmVhZGVyIGlzIG9mdGVuIHdyYXBwZWQgYnkgYQorICogQnVmZmVyZWRSZWFkZXIuCisgKgorICogQHNlZSBCdWZmZXJlZFJlYWRlcgorICogQHNlZSBGaWxlV3JpdGVyCisgKi8KK3B1YmxpYyBjbGFzcyBGaWxlUmVhZGVyIGV4dGVuZHMgSW5wdXRTdHJlYW1SZWFkZXIgeworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBGaWxlUmVhZGVyIG9uIHRoZSBnaXZlbiB7QGNvZGUgZmlsZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZQorICAgICAqICAgICAgICAgICAgYSBGaWxlIHRvIGJlIG9wZW5lZCBmb3IgcmVhZGluZyBjaGFyYWN0ZXJzIGZyb20uCisgICAgICogQHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZmlsZX0gZG9lcyBub3QgZXhpc3QuCisgICAgICovCisgICAgcHVibGljIEZpbGVSZWFkZXIoRmlsZSBmaWxlKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIobmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgbmV3IEZpbGVSZWFkZXIgb24gdGhlIGdpdmVuIEZpbGVEZXNjcmlwdG9yIHtAY29kZSBmZH0uIFNpbmNlCisgICAgICogYSBwcmV2aW91c2x5IG9wZW5lZCBGaWxlRGVzY3JpcHRvciBpcyBwYXNzZWQgYXMgYW4gYXJndW1lbnQsIG5vCisgICAgICogRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGNhbiBiZSB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmV2aW91c2x5IG9wZW5lZCBmaWxlIGRlc2NyaXB0b3IuCisgICAgICovCisgICAgcHVibGljIEZpbGVSZWFkZXIoRmlsZURlc2NyaXB0b3IgZmQpIHsKKyAgICAgICAgc3VwZXIobmV3IEZpbGVJbnB1dFN0cmVhbShmZCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIG5ldyBGaWxlUmVhZGVyIG9uIHRoZSBnaXZlbiBmaWxlIG5hbWVkIHtAY29kZSBmaWxlbmFtZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZW5hbWUKKyAgICAgKiAgICAgICAgICAgIGFuIGFic29sdXRlIG9yIHJlbGF0aXZlIHBhdGggc3BlY2lmeWluZyB0aGUgZmlsZSB0byBvcGVuLgorICAgICAqIEB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgbm8gZmlsZSBuYW1lZCB7QGNvZGUgZmlsZW5hbWV9LgorICAgICAqLworICAgIHB1YmxpYyBGaWxlUmVhZGVyKFN0cmluZyBmaWxlbmFtZSkgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZW5hbWUpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWxlV3JpdGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWxlV3JpdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzIzMjMyOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0ZpbGVXcml0ZXIuamF2YQpAQCAtMCwwICsxLDk4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKKy8qKgorICogQSBzcGVjaWFsaXplZCB7QGxpbmsgV3JpdGVyfSB0aGF0IHdyaXRlcyB0byBhIGZpbGUgaW4gdGhlIGZpbGUgc3lzdGVtLgorICogQWxsIHdyaXRlIHJlcXVlc3RzIG1hZGUgYnkgY2FsbGluZyBtZXRob2RzIGluIHRoaXMgY2xhc3MgYXJlIGRpcmVjdGx5CisgKiBmb3J3YXJkZWQgdG8gdGhlIGVxdWl2YWxlbnQgZnVuY3Rpb24gb2YgdGhlIHVuZGVybHlpbmcgb3BlcmF0aW5nIHN5c3RlbS4KKyAqIFNpbmNlIHRoaXMgbWF5IGluZHVjZSBzb21lIHBlcmZvcm1hbmNlIHBlbmFsdHksIGluIHBhcnRpY3VsYXIgaWYgbWFueSBzbWFsbAorICogd3JpdGUgcmVxdWVzdHMgYXJlIG1hZGUsIGEgRmlsZVdyaXRlciBpcyBvZnRlbiB3cmFwcGVkIGJ5IGEKKyAqIEJ1ZmZlcmVkV3JpdGVyLgorICoKKyAqIEBzZWUgQnVmZmVyZWRXcml0ZXIKKyAqIEBzZWUgRmlsZVJlYWRlcgorICovCitwdWJsaWMgY2xhc3MgRmlsZVdyaXRlciBleHRlbmRzIE91dHB1dFN0cmVhbVdyaXRlciB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgRmlsZVdyaXRlciB1c2luZyB0aGUgRmlsZSB7QGNvZGUgZmlsZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZQorICAgICAqICAgICAgICAgICAgdGhlIG5vbi1udWxsIEZpbGUgdG8gd3JpdGUgYnl0ZXMgdG8uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBmaWxlfSBjYW5ub3QgYmUgb3BlbmVkIGZvciB3cml0aW5nLgorICAgICAqLworICAgIHB1YmxpYyBGaWxlV3JpdGVyKEZpbGUgZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIobmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBGaWxlV3JpdGVyIHVzaW5nIHRoZSBGaWxlIHtAY29kZSBmaWxlfS4gVGhlIHBhcmFtZXRlcgorICAgICAqIHtAY29kZSBhcHBlbmR9IGRldGVybWluZXMgd2hldGhlciBvciBub3QgdGhlIGZpbGUgaXMgb3BlbmVkIGFuZCBhcHBlbmRlZAorICAgICAqIHRvIG9yIGp1c3Qgb3BlbmVkIGFuZCBvdmVyd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlCisgICAgICogICAgICAgICAgICB0aGUgbm9uLW51bGwgRmlsZSB0byB3cml0ZSBieXRlcyB0by4KKyAgICAgKiBAcGFyYW0gYXBwZW5kCisgICAgICogICAgICAgICAgICBpbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdG8gYXBwZW5kIHRvIGFuIGV4aXN0aW5nIGZpbGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgZmlsZX0gY2Fubm90IGJlIG9wZW5lZCBmb3Igd3JpdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZVdyaXRlcihGaWxlIGZpbGUsIGJvb2xlYW4gYXBwZW5kKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlLCBhcHBlbmQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgRmlsZVdyaXRlciB1c2luZyB0aGUgZXhpc3RpbmcgRmlsZURlc2NyaXB0b3Ige0Bjb2RlIGZkfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmZAorICAgICAqICAgICAgICAgICAgdGhlIG5vbi1udWxsIEZpbGVEZXNjcmlwdG9yIHRvIHdyaXRlIGJ5dGVzIHRvLgorICAgICAqLworICAgIHB1YmxpYyBGaWxlV3JpdGVyKEZpbGVEZXNjcmlwdG9yIGZkKSB7CisgICAgICAgIHN1cGVyKG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZkKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIEZpbGVXcml0ZXIgdXNpbmcgdGhlIHBsYXRmb3JtIGRlcGVuZGVudCB7QGNvZGUgZmlsZW5hbWV9LgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGVuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbm9uLW51bGwgbmFtZSBvZiB0aGUgZmlsZSB0byB3cml0ZSBieXRlcyB0by4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGZpbGUgY2Fubm90IGJlIG9wZW5lZCBmb3Igd3JpdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZVdyaXRlcihTdHJpbmcgZmlsZW5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKG5ldyBGaWxlT3V0cHV0U3RyZWFtKG5ldyBGaWxlKGZpbGVuYW1lKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBGaWxlV3JpdGVyIHVzaW5nIHRoZSBwbGF0Zm9ybSBkZXBlbmRlbnQge0Bjb2RlIGZpbGVuYW1lfS4gVGhlCisgICAgICogcGFyYW1ldGVyIHtAY29kZSBhcHBlbmR9IGRldGVybWluZXMgd2hldGhlciBvciBub3QgdGhlIGZpbGUgaXMgb3BlbmVkIGFuZAorICAgICAqIGFwcGVuZGVkIHRvIG9yIGp1c3Qgb3BlbmVkIGFuZCBvdmVyd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5vbi1udWxsIG5hbWUgb2YgdGhlIGZpbGUgdG8gd3JpdGUgYnl0ZXMgdG8uCisgICAgICogQHBhcmFtIGFwcGVuZAorICAgICAqICAgICAgICAgICAgaW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRvIGFwcGVuZCB0byBhbiBleGlzdGluZyBmaWxlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGZpbGV9IGNhbm5vdCBiZSBvcGVuZWQgZm9yIHdyaXRpbmcuCisgICAgICovCisgICAgcHVibGljIEZpbGVXcml0ZXIoU3RyaW5nIGZpbGVuYW1lLCBib29sZWFuIGFwcGVuZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIobmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZW5hbWUsIGFwcGVuZCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0ZpbGVuYW1lRmlsdGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWxlbmFtZUZpbHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM1MzgxYjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWxlbmFtZUZpbHRlci5qYXZhCkBAIC0wLDAgKzEsNDEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworLyoqCisgKiBBbiBpbnRlcmZhY2UgZm9yIGZpbHRlcmluZyB7QGxpbmsgRmlsZX0gb2JqZWN0cyBiYXNlZCBvbiB0aGVpciBuYW1lcworICogb3IgdGhlIGRpcmVjdG9yeSB0aGV5IHJlc2lkZSBpbi4KKyAqCisgKiBAc2VlIEZpbGUKKyAqIEBzZWUgRmlsZSNsaXN0KEZpbGVuYW1lRmlsdGVyKQorICovCitwdWJsaWMgaW50ZXJmYWNlIEZpbGVuYW1lRmlsdGVyIHsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyBpZiBhIHNwZWNpZmljIGZpbGVuYW1lIG1hdGNoZXMgdGhpcyBmaWx0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGlyCisgICAgICogICAgICAgICAgICB0aGUgZGlyZWN0b3J5IGluIHdoaWNoIHRoZSB7QGNvZGUgZmlsZW5hbWV9IHdhcyBmb3VuZC4KKyAgICAgKiBAcGFyYW0gZmlsZW5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWxlIGluIHtAY29kZSBkaXJ9IHRvIHRlc3QuCisgICAgICogQHJldHVybiAge0Bjb2RlIHRydWV9IGlmIHRoZSBmaWxlbmFtZSBtYXRjaGVzIHRoZSBmaWx0ZXIKKyAgICAgKiAgICAgICAgICAgIGFuZCBjYW4gYmUgaW5jbHVkZWQgaW4gdGhlIGxpc3QsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBhY2NlcHQoRmlsZSBkaXIsIFN0cmluZyBmaWxlbmFtZSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWx0ZXJJbnB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRmlsdGVySW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYmYxM2UyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRmlsdGVySW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDE3MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCisvKioKKyAqIFdyYXBzIGFuIGV4aXN0aW5nIHtAbGluayBJbnB1dFN0cmVhbX0gYW5kIHBlcmZvcm1zIHNvbWUgdHJhbnNmb3JtYXRpb24gb24KKyAqIHRoZSBpbnB1dCBkYXRhIHdoaWxlIGl0IGlzIGJlaW5nIHJlYWQuIFRyYW5zZm9ybWF0aW9ucyBjYW4gYmUgYW55dGhpbmcgZnJvbSBhCisgKiBzaW1wbGUgYnl0ZS13aXNlIGZpbHRlcmluZyBpbnB1dCBkYXRhIHRvIGFuIG9uLXRoZS1mbHkgY29tcHJlc3Npb24gb3IKKyAqIGRlY29tcHJlc3Npb24gb2YgdGhlIHVuZGVybHlpbmcgc3RyZWFtLiBJbnB1dCBzdHJlYW1zIHRoYXQgd3JhcCBhbm90aGVyIGlucHV0CisgKiBzdHJlYW0gYW5kIHByb3ZpZGUgc29tZSBhZGRpdGlvbmFsIGZ1bmN0aW9uYWxpdHkgb24gdG9wIG9mIGl0IHVzdWFsbHkgaW5oZXJpdAorICogZnJvbSB0aGlzIGNsYXNzLgorICoKKyAqIEBzZWUgRmlsdGVyT3V0cHV0U3RyZWFtCisgKi8KK3B1YmxpYyBjbGFzcyBGaWx0ZXJJbnB1dFN0cmVhbSBleHRlbmRzIElucHV0U3RyZWFtIHsKKworICAgIC8qKgorICAgICAqIFRoZSBzb3VyY2UgaW5wdXQgc3RyZWFtIHRoYXQgaXMgZmlsdGVyZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvbGF0aWxlIElucHV0U3RyZWFtIGluOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRmlsdGVySW5wdXRTdHJlYW19IHdpdGggdGhlIHNwZWNpZmllZCBpbnB1dAorICAgICAqIHN0cmVhbSBhcyBzb3VyY2UuCisgICAgICoKKyAgICAgKiA8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IHBhc3NpbmcgYSBudWxsIHNvdXJjZSBjcmVhdGVzIGFuIGludmFsaWQKKyAgICAgKiB7QGNvZGUgRmlsdGVySW5wdXRTdHJlYW19LCB0aGF0IGZhaWxzIG9uIGV2ZXJ5IG1ldGhvZCB0aGF0IGlzIG5vdAorICAgICAqIG92ZXJyaWRkZW4uIFN1YmNsYXNzZXMgc2hvdWxkIGNoZWNrIGZvciBudWxsIGluIHRoZWlyIGNvbnN0cnVjdG9ycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbiB0aGUgaW5wdXQgc3RyZWFtIHRvIGZpbHRlciByZWFkcyBvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRmlsdGVySW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgdGhpcy5pbiA9IGluOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGluLmF2YWlsYWJsZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGlzIHN0cmVhbS4gVGhpcyBpbXBsZW1lbnRhdGlvbiBjbG9zZXMgdGhlIGZpbHRlcmVkIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY2xvc2luZyB0aGlzIHN0cmVhbS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGluLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBhIG1hcmsgcG9zaXRpb24gaW4gdGhpcyBzdHJlYW0uIFRoZSBwYXJhbWV0ZXIge0Bjb2RlIHJlYWRsaW1pdH0KKyAgICAgKiBpbmRpY2F0ZXMgaG93IG1hbnkgYnl0ZXMgY2FuIGJlIHJlYWQgYmVmb3JlIHRoZSBtYXJrIGlzIGludmFsaWRhdGVkLgorICAgICAqIFNlbmRpbmcge0Bjb2RlIHJlc2V0KCl9IHdpbGwgcmVwb3NpdGlvbiB0aGlzIHN0cmVhbSBiYWNrIHRvIHRoZSBtYXJrZWQKKyAgICAgKiBwb3NpdGlvbiwgcHJvdmlkZWQgdGhhdCB7QGNvZGUgcmVhZGxpbWl0fSBoYXMgbm90IGJlZW4gc3VycGFzc2VkLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gc2V0cyBhIG1hcmsgaW4gdGhlIGZpbHRlcmVkIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFkbGltaXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBjYW4gYmUgcmVhZCBmcm9tIHRoaXMgc3RyZWFtIGJlZm9yZQorICAgICAqICAgICAgICAgICAgdGhlIG1hcmsgaXMgaW52YWxpZGF0ZWQuCisgICAgICogQHNlZSAjbWFya1N1cHBvcnRlZCgpCisgICAgICogQHNlZSAjcmVzZXQoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBtYXJrKGludCByZWFkbGltaXQpIHsKKyAgICAgICAgaW4ubWFyayhyZWFkbGltaXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgc3RyZWFtIHN1cHBvcnRzIHtAY29kZSBtYXJrKCl9IGFuZCB7QGNvZGUgcmVzZXQoKX0uCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSBmaWx0ZXJlZCBzdHJlYW0gc3VwcG9ydHMKKyAgICAgKiBtYXJraW5nLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIG1hcmsoKX0gYW5kIHtAY29kZSByZXNldCgpfSBhcmUgc3VwcG9ydGVkLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNlZSAjbWFyayhpbnQpCisgICAgICogQHNlZSAjcmVzZXQoKQorICAgICAqIEBzZWUgI3NraXAobG9uZykKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXJrU3VwcG9ydGVkKCkgeworICAgICAgICByZXR1cm4gaW4ubWFya1N1cHBvcnRlZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgc2luZ2xlIGJ5dGUgZnJvbSB0aGUgZmlsdGVyZWQgc3RyZWFtIGFuZCByZXR1cm5zIGl0IGFzIGFuIGludGVnZXIKKyAgICAgKiBpbiB0aGUgcmFuZ2UgZnJvbSAwIHRvIDI1NS4gUmV0dXJucyAtMSBpZiB0aGUgZW5kIG9mIHRoaXMgc3RyZWFtIGhhcyBiZWVuCisgICAgICogcmVhY2hlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZSBmaWx0ZXJlZCBzdHJlYW0gaGFzIGJlZW4KKyAgICAgKiAgICAgICAgIHJlYWNoZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzdHJlYW0gaXMgY2xvc2VkIG9yIGFub3RoZXIgSU9FeGNlcHRpb24gb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBpbi5yZWFkKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYXQgbW9zdCB7QGNvZGUgY291bnR9IGJ5dGVzIGZyb20gdGhpcyBzdHJlYW0gYW5kIHN0b3JlcyB0aGVtIGluIHRoZQorICAgICAqIGJ5dGUgYXJyYXkge0Bjb2RlIGJ1ZmZlcn0gc3RhcnRpbmcgYXQge0Bjb2RlIG9mZnNldH0uIFJldHVybnMgdGhlIG51bWJlcgorICAgICAqIG9mIGJ5dGVzIGFjdHVhbGx5IHJlYWQgb3IgLTEgaWYgbm8gYnl0ZXMgaGF2ZSBiZWVuIHJlYWQgYW5kIHRoZSBlbmQgb2YKKyAgICAgKiB0aGlzIHN0cmVhbSBoYXMgYmVlbiByZWFjaGVkLiBUaGlzIGltcGxlbWVudGF0aW9uIHJlYWRzIGJ5dGVzIGZyb20gdGhlCisgICAgICogZmlsdGVyZWQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYXJyYXkgaW4gd2hpY2ggdG8gc3RvcmUgdGhlIGJ5dGVzIHJlYWQuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgcG9zaXRpb24gaW4ge0Bjb2RlIGJ1ZmZlcn0gdG8gc3RvcmUgdGhlIGJ5dGVzCisgICAgICogICAgICAgICAgICByZWFkIGZyb20gdGhpcyBzdHJlYW0uCisgICAgICogQHBhcmFtIGNvdW50CisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgdG8gc3RvcmUgaW4ge0Bjb2RlIGJ1ZmZlcn0uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUKKyAgICAgKiAgICAgICAgIGZpbHRlcmVkIHN0cmVhbSBoYXMgYmVlbiByZWFjaGVkIHdoaWxlIHJlYWRpbmcuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgc3RyZWFtIGlzIGNsb3NlZCBvciBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGluLnJlYWQoYnVmZmVyLCBvZmZzZXQsIGNvdW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhpcyBzdHJlYW0gdG8gdGhlIGxhc3QgbWFya2VkIGxvY2F0aW9uLiBUaGlzIGltcGxlbWVudGF0aW9uCisgICAgICogcmVzZXRzIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgc3RyZWFtIGlzIGFscmVhZHkgY2xvc2VkLCBubyBtYXJrIGhhcyBiZWVuIHNldCBvciB0aGUKKyAgICAgKiAgICAgICAgICAgICBtYXJrIGlzIG5vIGxvbmdlciB2YWxpZCBiZWNhdXNlIG1vcmUgdGhhbiB7QGNvZGUgcmVhZGxpbWl0fQorICAgICAqICAgICAgICAgICAgIGJ5dGVzIGhhdmUgYmVlbiByZWFkIHNpbmNlIHNldHRpbmcgdGhlIG1hcmsuCisgICAgICogQHNlZSAjbWFyayhpbnQpCisgICAgICogQHNlZSAjbWFya1N1cHBvcnRlZCgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHJlc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW4ucmVzZXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTa2lwcyB7QGNvZGUgYnl0ZUNvdW50fSBieXRlcyBpbiB0aGlzIHN0cmVhbS4gU3Vic2VxdWVudAorICAgICAqIGNhbGxzIHRvIHtAY29kZSByZWFkfSB3aWxsIG5vdCByZXR1cm4gdGhlc2UgYnl0ZXMgdW5sZXNzIHtAY29kZSByZXNldH0gaXMKKyAgICAgKiB1c2VkLiBUaGlzIGltcGxlbWVudGF0aW9uIHNraXBzIHtAY29kZSBieXRlQ291bnR9IGJ5dGVzIGluIHRoZQorICAgICAqIGZpbHRlcmVkIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSBza2lwcGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHN0cmVhbSBpcyBjbG9zZWQgb3IgYW5vdGhlciBJT0V4Y2VwdGlvbiBvY2N1cnMuCisgICAgICogQHNlZSAjbWFyayhpbnQpCisgICAgICogQHNlZSAjcmVzZXQoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIHNraXAobG9uZyBieXRlQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBpbi5za2lwKGJ5dGVDb3VudCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRmlsdGVyT3V0cHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9GaWx0ZXJPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNWU1ZTc2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRmlsdGVyT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxMzEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgbGliY29yZS51dGlsLlNuZWFreVRocm93OworCisvKioKKyAqIFdyYXBzIGFuIGV4aXN0aW5nIHtAbGluayBPdXRwdXRTdHJlYW19IGFuZCBwZXJmb3JtcyBzb21lIHRyYW5zZm9ybWF0aW9uIG9uCisgKiB0aGUgb3V0cHV0IGRhdGEgd2hpbGUgaXQgaXMgYmVpbmcgd3JpdHRlbi4gVHJhbnNmb3JtYXRpb25zIGNhbiBiZSBhbnl0aGluZworICogZnJvbSBhIHNpbXBsZSBieXRlLXdpc2UgZmlsdGVyaW5nIG91dHB1dCBkYXRhIHRvIGFuIG9uLXRoZS1mbHkgY29tcHJlc3Npb24gb3IKKyAqIGRlY29tcHJlc3Npb24gb2YgdGhlIHVuZGVybHlpbmcgc3RyZWFtLiBPdXRwdXQgc3RyZWFtcyB0aGF0IHdyYXAgYW5vdGhlcgorICogb3V0cHV0IHN0cmVhbSBhbmQgcHJvdmlkZSBzb21lIGFkZGl0aW9uYWwgZnVuY3Rpb25hbGl0eSBvbiB0b3Agb2YgaXQgdXN1YWxseQorICogaW5oZXJpdCBmcm9tIHRoaXMgY2xhc3MuCisgKgorICogQHNlZSBGaWx0ZXJPdXRwdXRTdHJlYW0KKyAqLworcHVibGljIGNsYXNzIEZpbHRlck91dHB1dFN0cmVhbSBleHRlbmRzIE91dHB1dFN0cmVhbSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdGFyZ2V0IG91dHB1dCBzdHJlYW0gZm9yIHRoaXMgZmlsdGVyIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgT3V0cHV0U3RyZWFtIG91dDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEZpbHRlck91dHB1dFN0cmVhbX0gd2l0aCB7QGNvZGUgb3V0fSBhcyBpdHMKKyAgICAgKiB0YXJnZXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBzdHJlYW0gdGhhdCB0aGlzIHN0cmVhbSB3cml0ZXMgdG8uCisgICAgICovCisgICAgcHVibGljIEZpbHRlck91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIHRoaXMub3V0ID0gb3V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGlzIHN0cmVhbS4gVGhpcyBpbXBsZW1lbnRhdGlvbiBjbG9zZXMgdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGF0dGVtcHRpbmcgdG8gY2xvc2UgdGhpcyBzdHJlYW0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBUaHJvd2FibGUgdGhyb3duID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZsdXNoKCk7CisgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7CisgICAgICAgICAgICB0aHJvd24gPSBlOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZSkgeworICAgICAgICAgICAgaWYgKHRocm93biA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3duID0gZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmICh0aHJvd24gIT0gbnVsbCkgeworICAgICAgICAgICAgU25lYWt5VGhyb3cuc25lYWt5VGhyb3codGhyb3duKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEVuc3VyZXMgdGhhdCBhbGwgcGVuZGluZyBkYXRhIGlzIHNlbnQgb3V0IHRvIHRoZSB0YXJnZXQgc3RyZWFtLiBUaGlzCisgICAgICogaW1wbGVtZW50YXRpb24gZmx1c2hlcyB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYXR0ZW1wdGluZyB0byBmbHVzaCB0aGlzIHN0cmVhbS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC5mbHVzaCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB7QGNvZGUgY291bnR9IGJ5dGVzIGZyb20gdGhlIGJ5dGUgYXJyYXkge0Bjb2RlIGJ1ZmZlcn0gc3RhcnRpbmcgYXQKKyAgICAgKiB7QGNvZGUgb2Zmc2V0fSB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXIgdG8gd3JpdGUuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBieXRlIGluIHtAY29kZSBidWZmZXJ9IHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4ge0Bjb2RlIGJ1ZmZlcn0gdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBjb3VudCA8IDB9LCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBjb3VudH0gaXMgYmlnZ2VyIHRoYW4gdGhlIGxlbmd0aCBvZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBidWZmZXJ9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhpcyBzdHJlYW0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAvLyBDYWxsIHdyaXRlKCkgaW5zdGVhZCBvZiBvdXQud3JpdGUoKSBzaW5jZSBzdWJjbGFzc2VzIGNvdWxkCisgICAgICAgICAgICAvLyBvdmVycmlkZSB0aGUgd3JpdGUoKSBtZXRob2QuCisgICAgICAgICAgICB3cml0ZShidWZmZXJbb2Zmc2V0ICsgaV0pOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIG9uZSBieXRlIHRvIHRoZSB0YXJnZXQgc3RyZWFtLiBPbmx5IHRoZSBsb3cgb3JkZXIgYnl0ZSBvZiB0aGUKKyAgICAgKiBpbnRlZ2VyIHtAY29kZSBvbmVCeXRlfSBpcyB3cml0dGVuLgorICAgICAqCisgICAgICogQHBhcmFtIG9uZUJ5dGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0byB0aGlzIHN0cmVhbS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgb25lQnl0ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LndyaXRlKG9uZUJ5dGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0ZpbHRlclJlYWRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRmlsdGVyUmVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDNiZWI4YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0ZpbHRlclJlYWRlci5qYXZhCkBAIC0wLDAgKzEsMjAwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKKy8qKgorICogV3JhcHMgYW4gZXhpc3Rpbmcge0BsaW5rIFJlYWRlcn0gYW5kIHBlcmZvcm1zIHNvbWUgdHJhbnNmb3JtYXRpb24gb24gdGhlCisgKiBpbnB1dCBkYXRhIHdoaWxlIGl0IGlzIGJlaW5nIHJlYWQuIFRyYW5zZm9ybWF0aW9ucyBjYW4gYmUgYW55dGhpbmcgZnJvbSBhCisgKiBzaW1wbGUgYnl0ZS13aXNlIGZpbHRlcmluZyBpbnB1dCBkYXRhIHRvIGFuIG9uLXRoZS1mbHkgY29tcHJlc3Npb24gb3IKKyAqIGRlY29tcHJlc3Npb24gb2YgdGhlIHVuZGVybHlpbmcgcmVhZGVyLiBSZWFkZXJzIHRoYXQgd3JhcCBhbm90aGVyIHJlYWRlciBhbmQKKyAqIHByb3ZpZGUgc29tZSBhZGRpdGlvbmFsIGZ1bmN0aW9uYWxpdHkgb24gdG9wIG9mIGl0IHVzdWFsbHkgaW5oZXJpdCBmcm9tIHRoaXMKKyAqIGNsYXNzLgorICoKKyAqIEBzZWUgRmlsdGVyV3JpdGVyCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBGaWx0ZXJSZWFkZXIgZXh0ZW5kcyBSZWFkZXIgeworCisgICAgLyoqCisgICAgICogVGhlIHRhcmdldCBSZWFkZXIgd2hpY2ggaXMgYmVpbmcgZmlsdGVyZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIFJlYWRlciBpbjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgRmlsdGVyUmVhZGVyIG9uIHRoZSBSZWFkZXIge0Bjb2RlIGlufS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbgorICAgICAqICAgICAgICAgICAgVGhlIG5vbi1udWxsIFJlYWRlciB0byBmaWx0ZXIgcmVhZHMgb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIEZpbHRlclJlYWRlcihSZWFkZXIgaW4pIHsKKyAgICAgICAgc3VwZXIoaW4pOworICAgICAgICB0aGlzLmluID0gaW47CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgcmVhZGVyLiBUaGlzIGltcGxlbWVudGF0aW9uIGNsb3NlcyB0aGUgZmlsdGVyZWQgcmVhZGVyLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjbG9zaW5nIHRoaXMgcmVhZGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBhIG1hcmsgcG9zaXRpb24gaW4gdGhpcyByZWFkZXIuIFRoZSBwYXJhbWV0ZXIge0Bjb2RlIHJlYWRsaW1pdH0KKyAgICAgKiBpbmRpY2F0ZXMgaG93IG1hbnkgYnl0ZXMgY2FuIGJlIHJlYWQgYmVmb3JlIHRoZSBtYXJrIGlzIGludmFsaWRhdGVkLgorICAgICAqIFNlbmRpbmcge0Bjb2RlIHJlc2V0KCl9IHdpbGwgcmVwb3NpdGlvbiB0aGlzIHJlYWRlciBiYWNrIHRvIHRoZSBtYXJrZWQKKyAgICAgKiBwb3NpdGlvbiwgcHJvdmlkZWQgdGhhdCB7QGNvZGUgcmVhZGxpbWl0fSBoYXMgbm90IGJlZW4gc3VycGFzc2VkLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gc2V0cyBhIG1hcmsgaW4gdGhlIGZpbHRlcmVkIHJlYWRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFkbGltaXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBjYW4gYmUgcmVhZCBmcm9tIHRoaXMgcmVhZGVyIGJlZm9yZQorICAgICAqICAgICAgICAgICAgdGhlIG1hcmsgaXMgaW52YWxpZGF0ZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBtYXJraW5nIHRoaXMgcmVhZGVyLgorICAgICAqIEBzZWUgI21hcmtTdXBwb3J0ZWQoKQorICAgICAqIEBzZWUgI3Jlc2V0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgbWFyayhpbnQgcmVhZGxpbWl0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGluLm1hcmsocmVhZGxpbWl0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgcmVhZGVyIHN1cHBvcnRzIHtAY29kZSBtYXJrKCl9IGFuZCB7QGNvZGUgcmVzZXQoKX0uCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHdoZXRoZXIgdGhlIGZpbHRlcmVkIHJlYWRlciBzdXBwb3J0cyBtYXJraW5nLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIG1hcmsoKX0gYW5kIHtAY29kZSByZXNldCgpfSBhcmUgc3VwcG9ydGVkCisgICAgICogICAgICAgICBieSB0aGUgZmlsdGVyZWQgcmVhZGVyLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNtYXJrKGludCkKKyAgICAgKiBAc2VlICNyZXNldCgpCisgICAgICogQHNlZSAjc2tpcChsb25nKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hcmtTdXBwb3J0ZWQoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgcmV0dXJuIGluLm1hcmtTdXBwb3J0ZWQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgc2luZ2xlIGNoYXJhY3RlciBmcm9tIHRoZSBmaWx0ZXJlZCByZWFkZXIgYW5kIHJldHVybnMgaXQgYXMgYW4KKyAgICAgKiBpbnRlZ2VyIHdpdGggdGhlIHR3byBoaWdoZXItb3JkZXIgYnl0ZXMgc2V0IHRvIDAuIFJldHVybnMgLTEgaWYgdGhlIGVuZAorICAgICAqIG9mIHRoZSBmaWx0ZXJlZCByZWFkZXIgaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIGNoYXJhY3RlciByZWFkIG9yIC0xIGlmIHRoZSBlbmQgb2YgdGhlIGZpbHRlcmVkIHJlYWRlciBoYXMKKyAgICAgKiAgICAgICAgIGJlZW4gcmVhY2hlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgZnJvbSB0aGlzIHJlYWRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIHJldHVybiBpbi5yZWFkKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhdCBtb3N0IHtAY29kZSBjb3VudH0gY2hhcmFjdGVycyBmcm9tIHRoZSBmaWx0ZXJlZCByZWFkZXIgYW5kIHN0b3JlcyB0aGVtCisgICAgICogaW4gdGhlIGJ5dGUgYXJyYXkge0Bjb2RlIGJ1ZmZlcn0gc3RhcnRpbmcgYXQge0Bjb2RlIG9mZnNldH0uIFJldHVybnMgdGhlCisgICAgICogbnVtYmVyIG9mIGNoYXJhY3RlcnMgYWN0dWFsbHkgcmVhZCBvciAtMSBpZiBubyBjaGFyYWN0ZXJzIHdlcmUgcmVhZCBhbmQKKyAgICAgKiB0aGUgZW5kIG9mIHRoZSBmaWx0ZXJlZCByZWFkZXIgd2FzIGVuY291bnRlcmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIGNoYXIgYXJyYXkgaW4gd2hpY2ggdG8gc3RvcmUgdGhlIGNoYXJhY3RlcnMgcmVhZC4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBwb3NpdGlvbiBpbiB7QGNvZGUgYnVmZmVyfSB0byBzdG9yZSB0aGUgY2hhcmFjdGVycworICAgICAqICAgICAgICAgICAgcmVhZCBmcm9tIHRoaXMgcmVhZGVyLgorICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gc3RvcmUgaW4ge0Bjb2RlIGJ1ZmZlcn0uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgYWN0dWFsbHkgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZQorICAgICAqICAgICAgICAgZmlsdGVyZWQgcmVhZGVyIGhhcyBiZWVuIHJlYWNoZWQgd2hpbGUgcmVhZGluZy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgZnJvbSB0aGlzIHJlYWRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoY2hhcltdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIHJldHVybiBpbi5yZWFkKGJ1ZmZlciwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIHJlYWRlciBpcyByZWFkeSB0byBiZSByZWFkIHdpdGhvdXQgYmxvY2tpbmcuIElmCisgICAgICogdGhlIHJlc3VsdCBpcyB7QGNvZGUgdHJ1ZX0sIHRoZSBuZXh0IHtAY29kZSByZWFkKCl9IHdpbGwgbm90IGJsb2NrLiBJZgorICAgICAqIHRoZSByZXN1bHQgaXMge0Bjb2RlIGZhbHNlfSwgdGhpcyByZWFkZXIgbWF5IG9yIG1heSBub3QgYmxvY2sgd2hlbgorICAgICAqIHtAY29kZSByZWFkKCl9IGlzIHNlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHJlYWRlciB3aWxsIG5vdCBibG9jayB3aGVuIHtAY29kZSByZWFkKCl9CisgICAgICogICAgICAgICBpcyBjYWxsZWQsIHtAY29kZSBmYWxzZX0gaWYgdW5rbm93biBvciBibG9ja2luZyB3aWxsIG9jY3VyLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcmVhZGVyIGlzIGNsb3NlZCBvciBzb21lIG90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gcmVhZHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIHJldHVybiBpbi5yZWFkeSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzZXRzIHRoaXMgcmVhZGVyJ3MgcG9zaXRpb24gdG8gdGhlIGxhc3QgbWFya2VkIGxvY2F0aW9uLiBJbnZvY2F0aW9ucyBvZgorICAgICAqIHtAY29kZSByZWFkKCl9IGFuZCB7QGNvZGUgc2tpcCgpfSB3aWxsIG9jY3VyIGZyb20gdGhpcyBuZXcgbG9jYXRpb24uIElmCisgICAgICogdGhpcyByZWFkZXIgd2FzIG5vdCBtYXJrZWQsIHRoZSBiZWhhdmlvciBkZXBlbmRzIG9uIHRoZSBpbXBsZW1lbnRhdGlvbiBvZgorICAgICAqIHtAY29kZSByZXNldCgpfSBpbiB0aGUgUmVhZGVyIHN1YmNsYXNzIHRoYXQgaXMgZmlsdGVyZWQgYnkgdGhpcyByZWFkZXIuCisgICAgICogVGhlIGRlZmF1bHQgYmVoYXZpb3IgZm9yIFJlYWRlciBpcyB0byB0aHJvdyBhbiB7QGNvZGUgSU9FeGNlcHRpb259LgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnJlZCBvciB0aGUgZmlsdGVyZWQgcmVhZGVyIGRvZXMgbm90IHN1cHBvcnQKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgbWFyaygpfSBhbmQge0Bjb2RlIHJlc2V0KCl9LgorICAgICAqIEBzZWUgI21hcmsoaW50KQorICAgICAqIEBzZWUgI21hcmtTdXBwb3J0ZWQoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBpbi5yZXNldCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcHMge0Bjb2RlIGNoYXJDb3VudH0gY2hhcmFjdGVycyBpbiB0aGlzIHJlYWRlci4gU3Vic2VxdWVudCBjYWxscyB0byB7QGNvZGUgcmVhZH0KKyAgICAgKiB3aWxsIG5vdCByZXR1cm4gdGhlc2UgY2hhcmFjdGVycyB1bmxlc3Mge0Bjb2RlIHJlc2V0fSBpcyB1c2VkLiBUaGUKKyAgICAgKiBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGlzIHRvIHNraXAgY2hhcmFjdGVycyBpbiB0aGUgZmlsdGVyZWQgcmVhZGVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgYWN0dWFsbHkgc2tpcHBlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGZpbHRlcmVkIHJlYWRlciBpcyBjbG9zZWQgb3Igc29tZSBvdGhlciBJL08gZXJyb3IKKyAgICAgKiAgICAgICAgICAgICBvY2N1cnMuCisgICAgICogQHNlZSAjbWFyayhpbnQpCisgICAgICogQHNlZSAjbWFya1N1cHBvcnRlZCgpCisgICAgICogQHNlZSAjcmVzZXQoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIHNraXAobG9uZyBjaGFyQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgcmV0dXJuIGluLnNraXAoY2hhckNvdW50KTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0ZpbHRlcldyaXRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRmlsdGVyV3JpdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODIwZmU0ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0ZpbHRlcldyaXRlci5qYXZhCkBAIC0wLDAgKzEsMTMyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKKy8qKgorICogV3JhcHMgYW4gZXhpc3Rpbmcge0BsaW5rIFdyaXRlcn0gYW5kIHBlcmZvcm1zIHNvbWUgdHJhbnNmb3JtYXRpb24gb24gdGhlCisgKiBvdXRwdXQgZGF0YSB3aGlsZSBpdCBpcyBiZWluZyB3cml0dGVuLiBUcmFuc2Zvcm1hdGlvbnMgY2FuIGJlIGFueXRoaW5nIGZyb20gYQorICogc2ltcGxlIGJ5dGUtd2lzZSBmaWx0ZXJpbmcgb3V0cHV0IGRhdGEgdG8gYW4gb24tdGhlLWZseSBjb21wcmVzc2lvbiBvcgorICogZGVjb21wcmVzc2lvbiBvZiB0aGUgdW5kZXJseWluZyB3cml0ZXIuIFdyaXRlcnMgdGhhdCB3cmFwIGFub3RoZXIgd3JpdGVyIGFuZAorICogcHJvdmlkZSBzb21lIGFkZGl0aW9uYWwgZnVuY3Rpb25hbGl0eSBvbiB0b3Agb2YgaXQgdXN1YWxseSBpbmhlcml0IGZyb20gdGhpcworICogY2xhc3MuCisgKgorICogQHNlZSBGaWx0ZXJSZWFkZXIKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEZpbHRlcldyaXRlciBleHRlbmRzIFdyaXRlciB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgV3JpdGVyIGJlaW5nIGZpbHRlcmVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBXcml0ZXIgb3V0OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBGaWx0ZXJXcml0ZXIgb24gdGhlIFdyaXRlciB7QGNvZGUgb3V0fS4gQWxsIHdyaXRlcyBhcmUKKyAgICAgKiBub3cgZmlsdGVyZWQgdGhyb3VnaCB0aGlzIHdyaXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgV3JpdGVyIHRvIGZpbHRlciB3cml0ZXMgb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIEZpbHRlcldyaXRlcihXcml0ZXIgb3V0KSB7CisgICAgICAgIHN1cGVyKG91dCk7CisgICAgICAgIHRoaXMub3V0ID0gb3V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGlzIHdyaXRlci4gVGhpcyBpbXBsZW1lbnRhdGlvbiBjbG9zZXMgdGhlIHRhcmdldCB3cml0ZXIuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGF0dGVtcHRpbmcgdG8gY2xvc2UgdGhpcyB3cml0ZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmx1c2hlcyB0aGlzIHdyaXRlciB0byBlbnN1cmUgYWxsIHBlbmRpbmcgZGF0YSBpcyBzZW50IG91dCB0byB0aGUgdGFyZ2V0CisgICAgICogd3JpdGVyLiBUaGlzIGltcGxlbWVudGF0aW9uIGZsdXNoZXMgdGhlIHRhcmdldCB3cml0ZXIuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGF0dGVtcHRpbmcgdG8gZmx1c2ggdGhpcyB3cml0ZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHtAY29kZSBjb3VudH0gY2hhcmFjdGVycyBmcm9tIHRoZSBjaGFyIGFycmF5IHtAY29kZSBidWZmZXJ9CisgICAgICogc3RhcnRpbmcgYXQgcG9zaXRpb24ge0Bjb2RlIG9mZnNldH0gdG8gdGhlIHRhcmdldCB3cml0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHtAY29kZSBidWZmZXJ9IHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIHtAY29kZSBidWZmZXJ9IHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0byB0aGlzIHdyaXRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShjaGFyW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZmZlciwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIge0Bjb2RlIG9uZUNoYXJ9IHRvIHRoZSB0YXJnZXQgd3JpdGVyLiBPbmx5IHRoZQorICAgICAqIHR3byBsZWFzdCBzaWduaWZpY2FudCBieXRlcyBvZiB0aGUgaW50ZWdlciB7QGNvZGUgb25lQ2hhcn0gYXJlIHdyaXR0ZW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb25lQ2hhcgorICAgICAqICAgICAgICAgICAgdGhlIGNoYXIgdG8gd3JpdGUgdG8gdGhlIHRhcmdldCB3cml0ZXIuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoaXMgd3JpdGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBvbmVDaGFyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIG91dC53cml0ZShvbmVDaGFyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB7QGNvZGUgY291bnR9IGNoYXJhY3RlcnMgZnJvbSB0aGUgc3RyaW5nIHtAY29kZSBzdHJ9IHN0YXJ0aW5nIGF0CisgICAgICogcG9zaXRpb24ge0Bjb2RlIGluZGV4fSB0byB0aGlzIHdyaXRlci4gVGhpcyBpbXBsZW1lbnRhdGlvbiB3cml0ZXMKKyAgICAgKiB7QGNvZGUgc3RyfSB0byB0aGUgdGFyZ2V0IHdyaXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB7QGNvZGUgc3RyfSB0byB3cml0ZS4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgY2hhcnMgaW4ge0Bjb2RlIHN0cn0gdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoaXMgd3JpdGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKFN0cmluZyBzdHIsIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBvdXQud3JpdGUoc3RyLCBvZmZzZXQsIGNvdW50KTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0ZsdXNoYWJsZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vRmx1c2hhYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWRmMmExMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0ZsdXNoYWJsZS5qYXZhCkBAIC0wLDAgKzEsMzMgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworLyoqCisgKiBEZWZpbmVzIGFuIGludGVyZmFjZSBmb3IgY2xhc3NlcyB0aGF0IGNhbiAob3IgbmVlZCB0bykgYmUgZmx1c2hlZCwgdHlwaWNhbGx5CisgKiBiZWZvcmUgc29tZSBvdXRwdXQgcHJvY2Vzc2luZyBpcyBjb25zaWRlcmVkIHRvIGJlIGZpbmlzaGVkIGFuZCB0aGUgb2JqZWN0CisgKiBnZXRzIGNsb3NlZC4KKyAqLworcHVibGljIGludGVyZmFjZSBGbHVzaGFibGUgeworICAgIC8qKgorICAgICAqIEZsdXNoZXMgdGhlIG9iamVjdCBieSB3cml0aW5nIG91dCBhbnkgYnVmZmVyZWQgZGF0YSB0byB0aGUgdW5kZXJseWluZworICAgICAqIG91dHB1dC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBhcmUgYW55IGlzc3VlcyB3cml0aW5nIHRoZSBkYXRhLgorICAgICAqLworICAgIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9IaXN0b3JpY2FsQ2hhcnNldE5hbWVzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9IaXN0b3JpY2FsQ2hhcnNldE5hbWVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjBkNTQ5OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0hpc3RvcmljYWxDaGFyc2V0TmFtZXMuamF2YQpAQCAtMCwwICsxLDE3NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKKworLyoqCisgKiBUaGlzIGNvdWxkIGhhdmUgYmVlbiBpbiBDaGFyc2V0IG9yIENoYXJzZXRzLCBidXQgYWxsIGNvZGUgdXNlcyB0aG9zZSBjbGFzc2VzIHdoZXJlYXMgbm8gY29kZQorICogc2hvdWxkIG5lZWQgdG8gdXNlIHRoaXMsIHNvIGxldCdzIG5vdCBtYWtlIGdvb2QgY29kZSBwYXkgdG8gaW5pdGlhbGl6ZSB0aGlzIG1hcC4KKyAqLworY2xhc3MgSGlzdG9yaWNhbENoYXJzZXROYW1lcyB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4gaGlzdG9yaWNhbE5hbWVzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgc3RhdGljIHsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiQmlnNS1IS1NDUyIsICJCaWc1X0hLU0NTIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIkVVQy1KUCIsICJFVUNfSlAiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiRVVDLUtSIiwgIkVVQ19LUiIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJHQjIzMTIiLCAiRVVDX0NOIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklCTS1UaGFpIiwgIkNwODM4Iik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklCTTAwODU4IiwgIkNwODU4Iik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklCTTAxMTQwIiwgIkNwMTE0MCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJQk0wMTE0MSIsICJDcDExNDEiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSUJNMDExNDIiLCAiQ3AxMTQyIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklCTTAxMTQzIiwgIkNwMTE0MyIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJQk0wMTE0NCIsICJDcDExNDQiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSUJNMDExNDUiLCAiQ3AxMTQ1Iik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklCTTAxMTQ2IiwgIkNwMTE0NiIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJQk0wMTE0NyIsICJDcDExNDciKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSUJNMDExNDgiLCAiQ3AxMTQ4Iik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklCTTAxMTQ5IiwgIkNwMTE0OSIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJQk0wMzciLCAiQ3AwMzciKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSUJNMTAyNiIsICJDcDEwMjYiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSUJNMTA0NyIsICJDcDEwNDciKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSUJNMjczIiwgIkNwMjczIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklCTTI3NyIsICJDcDI3NyIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJQk0yNzgiLCAiQ3AyNzgiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSUJNMjgwIiwgIkNwMjgwIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklCTTI4NCIsICJDcDI4NCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJQk0yODUiLCAiQ3AyODUiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSUJNMjk3IiwgIkNwMjk3Iik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklCTTQyMCIsICJDcDQyMCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJQk00MjQiLCAiQ3A0MjQiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSUJNNDM3IiwgIkNwNDM3Iik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklCTTUwMCIsICJDcDUwMCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJQk03NzUiLCAiQ3A3NzUiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSUJNODUwIiwgIkNwODUwIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklCTTg1MiIsICJDcDg1MiIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJQk04NTUiLCAiQ3A4NTUiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSUJNODU3IiwgIkNwODU3Iik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklCTTg2MCIsICJDcDg2MCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJQk04NjEiLCAiQ3A4NjEiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSUJNODYyIiwgIkNwODYyIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklCTTg2MyIsICJDcDg2MyIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJQk04NjQiLCAiQ3A4NjQiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSUJNODY1IiwgIkNwODY1Iik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklCTTg2NiIsICJDcDg2NiIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJQk04NjgiLCAiQ3A4NjgiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSUJNODY5IiwgIkNwODY5Iik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklCTTg3MCIsICJDcDg3MCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJQk04NzEiLCAiQ3A4NzEiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSUJNOTE4IiwgIkNwOTE4Iik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklTTy0yMDIyLUNOIiwgIklTTzIwMjJDTiIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJU08tMjAyMi1KUCIsICJJU08yMDIySlAiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSVNPLTIwMjItS1IiLCAiSVNPMjAyMktSIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklTTy04ODU5LTEiLCAiSVNPODg1OV8xIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIklTTy04ODU5LTEzIiwgIklTTzg4NTlfMTMiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiSVNPLTg4NTktMTUiLCAiSVNPODg1OV8xNSIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJU08tODg1OS0yIiwgIklTTzg4NTlfMiIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJU08tODg1OS0zIiwgIklTTzg4NTlfMyIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJU08tODg1OS00IiwgIklTTzg4NTlfNCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJU08tODg1OS01IiwgIklTTzg4NTlfNSIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJU08tODg1OS02IiwgIklTTzg4NTlfNiIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJU08tODg1OS03IiwgIklTTzg4NTlfNyIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJU08tODg1OS04IiwgIklTTzg4NTlfOCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJJU08tODg1OS05IiwgIklTTzg4NTlfOSIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJLT0k4LVIiLCAiS09JOF9SIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIlNoaWZ0X0pJUyIsICJTSklTIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIlRJUy02MjAiLCAiVElTNjIwIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIlVTLUFTQ0lJIiwgIkFTQ0lJIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIlVURi0xNkJFIiwgIlVuaWNvZGVCaWdVbm1hcmtlZCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJVVEYtMTZMRSIsICJVbmljb2RlTGl0dGxlVW5tYXJrZWQiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgiVVRGLTgiLCAiVVRGOCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ3aW5kb3dzLTEyNTAiLCAiQ3AxMjUwIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIndpbmRvd3MtMTI1MSIsICJDcDEyNTEiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgid2luZG93cy0xMjUyIiwgIkNwMTI1MiIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ3aW5kb3dzLTEyNTMiLCAiQ3AxMjUzIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIndpbmRvd3MtMTI1NCIsICJDcDEyNTQiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgid2luZG93cy0xMjU1IiwgIkNwMTI1NSIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ3aW5kb3dzLTEyNTYiLCAiQ3AxMjU2Iik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIndpbmRvd3MtMTI1NyIsICJDcDEyNTciKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgid2luZG93cy0xMjU4IiwgIkNwMTI1OCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ3aW5kb3dzLTMxaiIsICJNUzkzMiIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUJpZzUtU29sYXJpcyIsICJCaWc1X1NvbGFyaXMiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgieC1ldWMtanAtbGludXgiLCAiRVVDX0pQX0xJTlVYIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIngtRVVDLVRXIiwgIkVVQ19UVyIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LWV1Y0pQLU9wZW4iLCAiRVVDX0pQX1NvbGFyaXMiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgieC1JQk0xMDA2IiwgIkNwMTAwNiIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTEwMjUiLCAiQ3AxMDI1Iik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIngtSUJNMTA0NiIsICJDcDEwNDYiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgieC1JQk0xMDk3IiwgIkNwMTA5NyIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTEwOTgiLCAiQ3AxMDk4Iik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIngtSUJNMTExMiIsICJDcDExMTIiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgieC1JQk0xMTIyIiwgIkNwMTEyMiIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTExMjMiLCAiQ3AxMTIzIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIngtSUJNMTEyNCIsICJDcDExMjQiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgieC1JQk0xMzgxIiwgIkNwMTM4MSIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTEzODMiLCAiQ3AxMzgzIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIngtSUJNMzM3MjIiLCAiQ3AzMzcyMiIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTczNyIsICJDcDczNyIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTg1NiIsICJDcDg1NiIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTg3NCIsICJDcDg3NCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTg3NSIsICJDcDg3NSIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTkyMSIsICJDcDkyMSIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTkyMiIsICJDcDkyMiIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTkzMCIsICJDcDkzMCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTkzMyIsICJDcDkzMyIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTkzNSIsICJDcDkzNSIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTkzNyIsICJDcDkzNyIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTkzOSIsICJDcDkzOSIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTk0MiIsICJDcDk0MiIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTk0MkMiLCAiQ3A5NDJDIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIngtSUJNOTQzIiwgIkNwOTQzIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIngtSUJNOTQzQyIsICJDcDk0M0MiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgieC1JQk05NDgiLCAiQ3A5NDgiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgieC1JQk05NDkiLCAiQ3A5NDkiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgieC1JQk05NDlDIiwgIkNwOTQ5QyIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTk1MCIsICJDcDk1MCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTk2NCIsICJDcDk2NCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlCTTk3MCIsICJDcDk3MCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlTQ0lJOTEiLCAiSVNDSUk5MSIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LUlTTy0yMDIyLUNOLUNOUyIsICJJU08yMDIyQ04iKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgieC1JU08tMjAyMi1DTi1HQiIsICJJU08yMDIyQ04iKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgieC1KSVNBdXRvRGV0ZWN0IiwgIkpJU0F1dG9EZXRlY3QiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgieC1NYWNBcmFiaWMiLCAiTWFjQXJhYmljIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIngtTWFjQ2VudHJhbEV1cm9wZSIsICJNYWNDZW50cmFsRXVyb3BlIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIngtTWFjQ3JvYXRpYW4iLCAiTWFjQ3JvYXRpYW4iKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgieC1NYWNDeXJpbGxpYyIsICJNYWNDeXJpbGxpYyIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LU1hY0RpbmdiYXQiLCAiTWFjRGluZ2JhdCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LU1hY0dyZWVrIiwgIk1hY0dyZWVrIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIngtTWFjSGVicmV3IiwgIk1hY0hlYnJldyIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LU1hY0ljZWxhbmQiLCAiTWFjSWNlbGFuZCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LU1hY1JvbWFuIiwgIk1hY1JvbWFuIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIngtTWFjUm9tYW5pYSIsICJNYWNSb21hbmlhIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIngtTWFjU3ltYm9sIiwgIk1hY1N5bWJvbCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LU1hY1RoYWkiLCAiTWFjVGhhaSIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LU1hY1R1cmtpc2giLCAiTWFjVHVya2lzaCIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LU1hY1VrcmFpbmUiLCAiTWFjVWtyYWluZSIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LU1TOTUwLUhLU0NTIiwgIk1TOTUwX0hLU0NTIik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIngtbXN3aW4tOTM2IiwgIk1TOTM2Iik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIngtUENLIiwgIlBDSyIpOworICAgICAgICBoaXN0b3JpY2FsTmFtZXMucHV0KCJ4LXdpbmRvd3MtODc0IiwgIk1TODc0Iik7CisgICAgICAgIGhpc3RvcmljYWxOYW1lcy5wdXQoIngtd2luZG93cy05NDkiLCAiTVM5NDkiKTsKKyAgICAgICAgaGlzdG9yaWNhbE5hbWVzLnB1dCgieC13aW5kb3dzLTk1MCIsICJNUzk1MCIpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldChDaGFyc2V0IGNoYXJzZXQpIHsKKyAgICAgICAgU3RyaW5nIG1vZGVybk5hbWUgPSBjaGFyc2V0Lm5hbWUoKTsKKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGhpc3RvcmljYWxOYW1lcy5nZXQobW9kZXJuTmFtZSk7CisgICAgICAgIHJldHVybiAocmVzdWx0ICE9IG51bGwpID8gcmVzdWx0IDogbW9kZXJuTmFtZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9JT0Vycm9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9JT0Vycm9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTkwNzMxYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0lPRXJyb3IuamF2YQpAQCAtMCwwICsxLDM3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKKy8qKgorICogVGhpcyBlcnJvciBpcyB0aHJvd24gd2hlbiBhIHNldmVyZSBJL08gZXJyb3IgaGFzIGhhcHBlbmVkLgorICoKKyAqIEBzaW5jZSAxLjYKKyAqLworcHVibGljIGNsYXNzIElPRXJyb3IgZXh0ZW5kcyBFcnJvciB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjcxMDA5Mjc5OTE2ODA0MTNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSB3aXRoIGl0cyBjYXVzZSBmaWxsZWQgaW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIFRoZSBkZXRhaWwgY2F1c2UgZm9yIHRoZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgSU9FcnJvcihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0lPRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9JT0V4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNlYjRkNDkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9JT0V4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNzEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworLyoqCisgKiBTaWduYWxzIGEgZ2VuZXJhbCwgSS9PLXJlbGF0ZWQgZXJyb3IuIEVycm9yIGRldGFpbHMgbWF5IGJlIHNwZWNpZmllZCB3aGVuCisgKiBjYWxsaW5nIHRoZSBjb25zdHJ1Y3RvciwgYXMgdXN1YWwuIE5vdGUgdGhlcmUgYXJlIGFsc28gc2V2ZXJhbCBzdWJjbGFzc2VzIG9mCisgKiB0aGlzIGNsYXNzIGZvciBtb3JlIHNwZWNpZmljIGVycm9yIHNpdHVhdGlvbnMsIHN1Y2ggYXMKKyAqIHtAbGluayBGaWxlTm90Rm91bmRFeGNlcHRpb259IG9yIHtAbGluayBFT0ZFeGNlcHRpb259LgorICovCitwdWJsaWMgY2xhc3MgSU9FeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzgxODM3NTgyODE0NjA5MDE1NUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJT0V4Y2VwdGlvbn0gd2l0aCBpdHMgc3RhY2sgdHJhY2UgZmlsbGVkIGluLgorICAgICAqLworICAgIHB1YmxpYyBJT0V4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJT0V4Y2VwdGlvbn0gd2l0aCBpdHMgc3RhY2sgdHJhY2UgYW5kIGRldGFpbAorICAgICAqIG1lc3NhZ2UgZmlsbGVkIGluLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIElPRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyB3aXRoIGRldGFpbCBtZXNzYWdlIGFuZCBjYXVzZQorICAgICAqIGZpbGxlZCBpbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICBUaGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24uCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICBUaGUgZGV0YWlsIGNhdXNlIGZvciB0aGUgZXhjZXB0aW9uLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgSU9FeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIHdpdGggaXRzIGRldGFpbCBjYXVzZSBmaWxsZWQgaW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIFRoZSBkZXRhaWwgY2F1c2UgZm9yIHRoZSBleGNlcHRpb24uCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBJT0V4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UgPT0gbnVsbCA/IG51bGwgOiBjYXVzZS50b1N0cmluZygpLCBjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vSW5wdXRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0lucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTYxZTA1NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL0lucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwyMzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworCisvKioKKyAqIEEgcmVhZGFibGUgc291cmNlIG9mIGJ5dGVzLgorICoKKyAqIDxwPk1vc3QgY2xpZW50cyB3aWxsIHVzZSBpbnB1dCBzdHJlYW1zIHRoYXQgcmVhZCBkYXRhIGZyb20gdGhlIGZpbGUgc3lzdGVtCisgKiAoe0BsaW5rIEZpbGVJbnB1dFN0cmVhbX0pLCB0aGUgbmV0d29yayAoe0BsaW5rIGphdmEubmV0LlNvY2tldCNnZXRJbnB1dFN0cmVhbSgpfS97QGxpbmsKKyAqIGphdmEubmV0Lkh0dHBVUkxDb25uZWN0aW9uI2dldElucHV0U3RyZWFtKCl9KSwgb3IgZnJvbSBhbiBpbi1tZW1vcnkgYnl0ZQorICogYXJyYXkgKHtAbGluayBCeXRlQXJyYXlJbnB1dFN0cmVhbX0pLgorICoKKyAqIDxwPlVzZSB7QGxpbmsgSW5wdXRTdHJlYW1SZWFkZXJ9IHRvIGFkYXB0IGEgYnl0ZSBzdHJlYW0gbGlrZSB0aGlzIG9uZSBpbnRvIGEKKyAqIGNoYXJhY3RlciBzdHJlYW0uCisgKgorICogPHA+TW9zdCBjbGllbnRzIHNob3VsZCB3cmFwIHRoZWlyIGlucHV0IHN0cmVhbSB3aXRoIHtAbGluaworICogQnVmZmVyZWRJbnB1dFN0cmVhbX0uIENhbGxlcnMgdGhhdCBkbyBvbmx5IGJ1bGsgcmVhZHMgbWF5IG9taXQgYnVmZmVyaW5nLgorICoKKyAqIDxwPlNvbWUgaW1wbGVtZW50YXRpb25zIHN1cHBvcnQgbWFya2luZyBhIHBvc2l0aW9uIGluIHRoZSBpbnB1dCBzdHJlYW0gYW5kCisgKiByZXNldHRpbmcgYmFjayB0byB0aGlzIHBvc2l0aW9uIGxhdGVyLiBJbXBsZW1lbnRhdGlvbnMgdGhhdCBkb24ndCByZXR1cm4KKyAqIGZhbHNlIGZyb20ge0BsaW5rICNtYXJrU3VwcG9ydGVkKCl9IGFuZCB0aHJvdyBhbiB7QGxpbmsgSU9FeGNlcHRpb259IHdoZW4KKyAqIHtAbGluayAjcmVzZXQoKX0gaXMgY2FsbGVkLgorICoKKyAqIDxoMz5TdWJjbGFzc2luZyBJbnB1dFN0cmVhbTwvaDM+CisgKiBTdWJjbGFzc2VzIHRoYXQgZGVjb3JhdGUgYW5vdGhlciBpbnB1dCBzdHJlYW0gc2hvdWxkIGNvbnNpZGVyIHN1YmNsYXNzaW5nCisgKiB7QGxpbmsgRmlsdGVySW5wdXRTdHJlYW19LCB3aGljaCBkZWxlZ2F0ZXMgYWxsIGNhbGxzIHRvIHRoZSBzb3VyY2UgaW5wdXQKKyAqIHN0cmVhbS4KKyAqCisgKiA8cD5BbGwgaW5wdXQgc3RyZWFtIHN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlIDxzdHJvbmc+Ym90aDwvc3Ryb25nPiB7QGxpbmsKKyAqICNyZWFkKCkgcmVhZCgpfSBhbmQge0BsaW5rICNyZWFkKGJ5dGVbXSxpbnQsaW50KSByZWFkKGJ5dGVbXSxpbnQsaW50KX0uIFRoZQorICogdGhyZWUgYXJndW1lbnQgb3ZlcmxvYWQgaXMgbmVjZXNzYXJ5IGZvciBidWxrIGFjY2VzcyB0byB0aGUgZGF0YS4gVGhpcyBpcworICogbXVjaCBtb3JlIGVmZmljaWVudCB0aGFuIGJ5dGUtYnktYnl0ZSBhY2Nlc3MuCisgKgorICogQHNlZSBPdXRwdXRTdHJlYW0KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIElucHV0U3RyZWFtIGV4dGVuZHMgT2JqZWN0IGltcGxlbWVudHMgQ2xvc2VhYmxlIHsKKworICAgIC8qKgorICAgICAqIFRoaXMgY29uc3RydWN0b3IgZG9lcyBub3RoaW5nLiBJdCBpcyBwcm92aWRlZCBmb3Igc2lnbmF0dXJlCisgICAgICogY29tcGF0aWJpbGl0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0oKSB7CisgICAgICAgIC8qIGVtcHR5ICovCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBlc3RpbWF0ZWQgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgY2FuIGJlIHJlYWQgb3Igc2tpcHBlZCB3aXRob3V0IGJsb2NraW5nIGZvciBtb3JlCisgICAgICogaW5wdXQuCisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoYXQgdGhpcyBtZXRob2QgcHJvdmlkZXMgc3VjaCBhIHdlYWsgZ3VhcmFudGVlIHRoYXQgaXQgaXMgbm90IHZlcnkgdXNlZnVsIGluCisgICAgICogcHJhY3RpY2UuCisgICAgICoKKyAgICAgKiA8cD5GaXJzdGx5LCB0aGUgZ3VhcmFudGVlIGlzICJ3aXRob3V0IGJsb2NraW5nIGZvciBtb3JlIGlucHV0IiByYXRoZXIgdGhhbiAid2l0aG91dAorICAgICAqIGJsb2NraW5nIjogYSByZWFkIG1heSBzdGlsbCBibG9jayB3YWl0aW5nIGZvciBJL08gdG8gY29tcGxldGUmbmJzcDsmbWRhc2g7IHRoZSBndWFyYW50ZWUgaXMKKyAgICAgKiBtZXJlbHkgdGhhdCBpdCB3b24ndCBoYXZlIHRvIHdhaXQgaW5kZWZpbml0ZWx5IGZvciBkYXRhIHRvIGJlIHdyaXR0ZW4uIFRoZSByZXN1bHQgb2YgdGhpcworICAgICAqIG1ldGhvZCBzaG91bGQgbm90IGJlIHVzZWQgYXMgYSBsaWNlbnNlIHRvIGRvIEkvTyBvbiBhIHRocmVhZCB0aGF0IHNob3VsZG4ndCBiZSBibG9ja2VkLgorICAgICAqCisgICAgICogPHA+U2Vjb25kbHksIHRoZSByZXN1bHQgaXMgYQorICAgICAqIGNvbnNlcnZhdGl2ZSBlc3RpbWF0ZSBhbmQgbWF5IGJlIHNpZ25pZmljYW50bHkgc21hbGxlciB0aGFuIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzCisgICAgICogYXZhaWxhYmxlLiBJbiBwYXJ0aWN1bGFyLCBhbiBpbXBsZW1lbnRhdGlvbiB0aGF0IGFsd2F5cyByZXR1cm5zIDAgd291bGQgYmUgY29ycmVjdC4KKyAgICAgKiBJbiBnZW5lcmFsLCBjYWxsZXJzIHNob3VsZCBvbmx5IHVzZSB0aGlzIG1ldGhvZCBpZiB0aGV5J2QgYmUgc2F0aXNmaWVkIHdpdGgKKyAgICAgKiB0cmVhdGluZyB0aGUgcmVzdWx0IGFzIGEgYm9vbGVhbiB5ZXMgb3Igbm8gYW5zd2VyIHRvIHRoZSBxdWVzdGlvbiAiaXMgdGhlcmUgZGVmaW5pdGVseQorICAgICAqIGRhdGEgcmVhZHk/Ii4KKyAgICAgKgorICAgICAqIDxwPlRoaXJkbHksIHRoZSBmYWN0IHRoYXQgYSBnaXZlbiBudW1iZXIgb2YgYnl0ZXMgaXMgImF2YWlsYWJsZSIgZG9lcyBub3QgZ3VhcmFudGVlIHRoYXQgYQorICAgICAqIHJlYWQgb3Igc2tpcCB3aWxsIGFjdHVhbGx5IHJlYWQgb3Igc2tpcCB0aGF0IG1hbnkgYnl0ZXM6IHRoZXkgbWF5IHJlYWQgb3Igc2tpcCBmZXdlci4KKyAgICAgKgorICAgICAqIDxwPkl0IGlzIHBhcnRpY3VsYXJseSBpbXBvcnRhbnQgdG8gcmVhbGl6ZSB0aGF0IHlvdSA8aT5tdXN0IG5vdDwvaT4gdXNlIHRoaXMgbWV0aG9kIHRvCisgICAgICogc2l6ZSBhIGNvbnRhaW5lciBhbmQgYXNzdW1lIHRoYXQgeW91IGNhbiByZWFkIHRoZSBlbnRpcmV0eSBvZiB0aGUgc3RyZWFtIHdpdGhvdXQgbmVlZGluZworICAgICAqIHRvIHJlc2l6ZSB0aGUgY29udGFpbmVyLiBTdWNoIGNhbGxlcnMgc2hvdWxkIHByb2JhYmx5IHdyaXRlIGV2ZXJ5dGhpbmcgdGhleSByZWFkIHRvIGEKKyAgICAgKiB7QGxpbmsgQnl0ZUFycmF5T3V0cHV0U3RyZWFtfSBhbmQgY29udmVydCB0aGF0IHRvIGEgYnl0ZSBhcnJheS4gQWx0ZXJuYXRpdmVseSwgaWYgeW91J3JlCisgICAgICogcmVhZGluZyBmcm9tIGEgZmlsZSwge0BsaW5rIEZpbGUjbGVuZ3RofSByZXR1cm5zIHRoZSBjdXJyZW50IGxlbmd0aCBvZiB0aGUgZmlsZSAodGhvdWdoCisgICAgICogYXNzdW1pbmcgdGhlIGZpbGUncyBsZW5ndGggY2FuJ3QgY2hhbmdlIG1heSBiZSBpbmNvcnJlY3QsIHJlYWRpbmcgYSBmaWxlIGlzIGluaGVyZW50bHkKKyAgICAgKiByYWN5KS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kIGluIHtAY29kZSBJbnB1dFN0cmVhbX0gYWx3YXlzIHJldHVybnMgMC4KKyAgICAgKiBTdWJjbGFzc2VzIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZCBpZiB0aGV5IGFyZSBhYmxlIHRvIGluZGljYXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMKKyAgICAgKiBhdmFpbGFibGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBlc3RpbWF0ZWQgbnVtYmVyIG9mIGJ5dGVzIGF2YWlsYWJsZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgdGhpcyBzdHJlYW0gaXMgY2xvc2VkIG9yIGFuIGVycm9yIG9jY3VycworICAgICAqLworICAgIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgc3RyZWFtLiBDb25jcmV0ZSBpbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBjbGFzcyBzaG91bGQgZnJlZQorICAgICAqIGFueSByZXNvdXJjZXMgZHVyaW5nIGNsb3NlLiBUaGlzIGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY2xvc2luZyB0aGlzIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8qIGVtcHR5ICovCisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBhIG1hcmsgcG9zaXRpb24gaW4gdGhpcyBJbnB1dFN0cmVhbS4gVGhlIHBhcmFtZXRlciB7QGNvZGUgcmVhZGxpbWl0fQorICAgICAqIGluZGljYXRlcyBob3cgbWFueSBieXRlcyBjYW4gYmUgcmVhZCBiZWZvcmUgdGhlIG1hcmsgaXMgaW52YWxpZGF0ZWQuCisgICAgICogU2VuZGluZyB7QGNvZGUgcmVzZXQoKX0gd2lsbCByZXBvc2l0aW9uIHRoZSBzdHJlYW0gYmFjayB0byB0aGUgbWFya2VkCisgICAgICogcG9zaXRpb24gcHJvdmlkZWQge0Bjb2RlIHJlYWRMaW1pdH0gaGFzIG5vdCBiZWVuIHN1cnBhc3NlZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZG9lcyBub3RoaW5nIGFuZCBjb25jcmV0ZSBzdWJjbGFzc2VzIG11c3QKKyAgICAgKiBwcm92aWRlIHRoZWlyIG93biBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFkbGltaXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBjYW4gYmUgcmVhZCBmcm9tIHRoaXMgc3RyZWFtIGJlZm9yZQorICAgICAqICAgICAgICAgICAgdGhlIG1hcmsgaXMgaW52YWxpZGF0ZWQuCisgICAgICogQHNlZSAjbWFya1N1cHBvcnRlZCgpCisgICAgICogQHNlZSAjcmVzZXQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG1hcmsoaW50IHJlYWRsaW1pdCkgeworICAgICAgICAvKiBlbXB0eSAqLworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgc3RyZWFtIHN1cHBvcnRzIHRoZSB7QGNvZGUgbWFyaygpfSBhbmQKKyAgICAgKiB7QGNvZGUgcmVzZXQoKX0gbWV0aG9kcy4gVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcmV0dXJucyB7QGNvZGUgZmFsc2V9LgorICAgICAqCisgICAgICogQHJldHVybiBhbHdheXMge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAc2VlICNtYXJrKGludCkKKyAgICAgKiBAc2VlICNyZXNldCgpCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbWFya1N1cHBvcnRlZCgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgc2luZ2xlIGJ5dGUgZnJvbSB0aGlzIHN0cmVhbSBhbmQgcmV0dXJucyBpdCBhcyBhbiBpbnRlZ2VyIGluIHRoZQorICAgICAqIHJhbmdlIGZyb20gMCB0byAyNTUuIFJldHVybnMgLTEgaWYgdGhlIGVuZCBvZiB0aGUgc3RyZWFtIGhhcyBiZWVuCisgICAgICogcmVhY2hlZC4gQmxvY2tzIHVudGlsIG9uZSBieXRlIGhhcyBiZWVuIHJlYWQsIHRoZSBlbmQgb2YgdGhlIHNvdXJjZQorICAgICAqIHN0cmVhbSBpcyBkZXRlY3RlZCBvciBhbiBleGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYnl0ZSByZWFkIG9yIC0xIGlmIHRoZSBlbmQgb2Ygc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzdHJlYW0gaXMgY2xvc2VkIG9yIGFub3RoZXIgSU9FeGNlcHRpb24gb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8ge0Bjb2RlIHJlYWQoYnVmZmVyLCAwLCBidWZmZXIubGVuZ3RoKX0uCisgICAgICovCisgICAgcHVibGljIGludCByZWFkKGJ5dGVbXSBidWZmZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByZWFkKGJ1ZmZlciwgMCwgYnVmZmVyLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYXQgbW9zdCB7QGNvZGUgbGVuZ3RofSBieXRlcyBmcm9tIHRoaXMgc3RyZWFtIGFuZCBzdG9yZXMgdGhlbSBpbgorICAgICAqIHRoZSBieXRlIGFycmF5IHtAY29kZSBifSBzdGFydGluZyBhdCB7QGNvZGUgb2Zmc2V0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGFycmF5IGluIHdoaWNoIHRvIHN0b3JlIHRoZSBieXRlcyByZWFkLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIHBvc2l0aW9uIGluIHtAY29kZSBidWZmZXJ9IHRvIHN0b3JlIHRoZSBieXRlcyByZWFkCisgICAgICogICAgICAgICAgICBmcm9tIHRoaXMgc3RyZWFtLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0byBzdG9yZSBpbiB7QGNvZGUgYn0uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgc3RyZWFtCisgICAgICogICAgICAgICBoYXMgYmVlbiByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwfSBvciB7QGNvZGUgbGVuZ3RoIDwgMH0sIG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIG9mZnNldCArIGxlbmd0aH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgYn0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzdHJlYW0gaXMgY2xvc2VkIG9yIGFub3RoZXIgSU9FeGNlcHRpb24gb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXIubGVuZ3RoLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGludCBjOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAoKGMgPSByZWFkKCkpID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpID09IDAgPyAtMSA6IGk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGlmIChpICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBidWZmZXJbb2Zmc2V0ICsgaV0gPSAoYnl0ZSkgYzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0cyB0aGlzIHN0cmVhbSB0byB0aGUgbGFzdCBtYXJrZWQgbG9jYXRpb24uIFRocm93cyBhbgorICAgICAqIHtAY29kZSBJT0V4Y2VwdGlvbn0gaWYgdGhlIG51bWJlciBvZiBieXRlcyByZWFkIHNpbmNlIHRoZSBtYXJrIGhhcyBiZWVuCisgICAgICogc2V0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGltaXQgcHJvdmlkZWQgdG8ge0Bjb2RlIG1hcmt9LCBvciBpZiBubyBtYXJrCisgICAgICogaGFzIGJlZW4gc2V0LgorICAgICAqIDxwPgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gYWx3YXlzIHRocm93cyBhbiB7QGNvZGUgSU9FeGNlcHRpb259IGFuZCBjb25jcmV0ZQorICAgICAqIHN1YmNsYXNzZXMgc2hvdWxkIHByb3ZpZGUgdGhlIHByb3BlciBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHN0cmVhbSBpcyBjbG9zZWQgb3IgYW5vdGhlciBJT0V4Y2VwdGlvbiBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHJlc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcHMgYXQgbW9zdCB7QGNvZGUgbn0gYnl0ZXMgaW4gdGhpcyBzdHJlYW0uIFRoaXMgbWV0aG9kIGRvZXMgbm90aGluZyBhbmQgcmV0dXJucworICAgICAqIDAgaWYge0Bjb2RlIG59IGlzIG5lZ2F0aXZlLCBidXQgc29tZSBzdWJjbGFzc2VzIG1heSB0aHJvdy4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhlICJhdCBtb3N0IiBpbiB0aGUgZGVzY3JpcHRpb24gb2YgdGhpcyBtZXRob2Q6IHRoaXMgbWV0aG9kIG1heSBjaG9vc2UgdG8gc2tpcAorICAgICAqIGZld2VyIGJ5dGVzIHRoYW4gcmVxdWVzdGVkLiBDYWxsZXJzIHNob3VsZCA8aT5hbHdheXM8L2k+IGNoZWNrIHRoZSByZXR1cm4gdmFsdWUuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcmVhZHMgYnl0ZXMgaW50byBhIHRlbXBvcmFyeQorICAgICAqIGJ1ZmZlci4gQ29uY3JldGUgc3ViY2xhc3NlcyBzaG91bGQgcHJvdmlkZSB0aGVpciBvd24gaW1wbGVtZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnl0ZUNvdW50IHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gc2tpcC4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgc2tpcHBlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBzdHJlYW0gaXMgY2xvc2VkIG9yIGFub3RoZXIgSU9FeGNlcHRpb24gb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIHNraXAobG9uZyBieXRlQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBTdHJlYW1zLnNraXBCeVJlYWRpbmcodGhpcywgYnl0ZUNvdW50KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9JbnB1dFN0cmVhbVJlYWRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vSW5wdXRTdHJlYW1SZWFkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OWJlOWVkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vSW5wdXRTdHJlYW1SZWFkZXIuamF2YQpAQCAtMCwwICsxLDMxNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5DaGFyQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXREZWNvZGVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ29kZXJSZXN1bHQ7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5Db2RpbmdFcnJvckFjdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0Lk1hbGZvcm1lZElucHV0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuVW5tYXBwYWJsZUNoYXJhY3RlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIEEgY2xhc3MgZm9yIHR1cm5pbmcgYSBieXRlIHN0cmVhbSBpbnRvIGEgY2hhcmFjdGVyIHN0cmVhbS4gRGF0YSByZWFkIGZyb20gdGhlCisgKiBzb3VyY2UgaW5wdXQgc3RyZWFtIGlzIGNvbnZlcnRlZCBpbnRvIGNoYXJhY3RlcnMgYnkgZWl0aGVyIGEgZGVmYXVsdCBvciBhCisgKiBwcm92aWRlZCBjaGFyYWN0ZXIgY29udmVydGVyLiBUaGUgZGVmYXVsdCBlbmNvZGluZyBpcyB0YWtlbiBmcm9tIHRoZQorICogImZpbGUuZW5jb2RpbmciIHN5c3RlbSBwcm9wZXJ0eS4ge0Bjb2RlIElucHV0U3RyZWFtUmVhZGVyfSBjb250YWlucyBhIGJ1ZmZlcgorICogb2YgYnl0ZXMgcmVhZCBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtIGFuZCBjb252ZXJ0cyB0aGVzZSBpbnRvIGNoYXJhY3RlcnMgYXMKKyAqIG5lZWRlZC4gVGhlIGJ1ZmZlciBzaXplIGlzIDhLLgorICoKKyAqIEBzZWUgT3V0cHV0U3RyZWFtV3JpdGVyCisgKi8KK3B1YmxpYyBjbGFzcyBJbnB1dFN0cmVhbVJlYWRlciBleHRlbmRzIFJlYWRlciB7CisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBpbjsKKworICAgIHByaXZhdGUgYm9vbGVhbiBlbmRPZklucHV0ID0gZmFsc2U7CisKKyAgICBwcml2YXRlIENoYXJzZXREZWNvZGVyIGRlY29kZXI7CisKKyAgICBwcml2YXRlIGZpbmFsIEJ5dGVCdWZmZXIgYnl0ZXMgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDgxOTIpOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSW5wdXRTdHJlYW1SZWFkZXJ9IG9uIHRoZSB7QGxpbmsgSW5wdXRTdHJlYW19CisgICAgICoge0Bjb2RlIGlufS4gVGhpcyBjb25zdHJ1Y3RvciBzZXRzIHRoZSBjaGFyYWN0ZXIgY29udmVydGVyIHRvIHRoZSBlbmNvZGluZworICAgICAqIHNwZWNpZmllZCBpbiB0aGUgImZpbGUuZW5jb2RpbmciIHByb3BlcnR5IGFuZCBmYWxscyBiYWNrIHRvIElTTyA4ODU5XzEKKyAgICAgKiAoSVNPLUxhdGluLTEpIGlmIHRoZSBwcm9wZXJ0eSBkb2Vzbid0IGV4aXN0LgorICAgICAqCisgICAgICogQHBhcmFtIGluCisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgc3RyZWFtIGZyb20gd2hpY2ggdG8gcmVhZCBjaGFyYWN0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFN0cmVhbVJlYWRlcihJbnB1dFN0cmVhbSBpbikgeworICAgICAgICB0aGlzKGluLCBDaGFyc2V0LmRlZmF1bHRDaGFyc2V0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgSW5wdXRTdHJlYW1SZWFkZXIgb24gdGhlIElucHV0U3RyZWFtIHtAY29kZSBpbn0uIFRoZQorICAgICAqIGNoYXJhY3RlciBjb252ZXJ0ZXIgdGhhdCBpcyB1c2VkIHRvIGRlY29kZSBieXRlcyBpbnRvIGNoYXJhY3RlcnMgaXMKKyAgICAgKiBpZGVudGlmaWVkIGJ5IG5hbWUgYnkge0Bjb2RlIGVuY30uIElmIHRoZSBlbmNvZGluZyBjYW5ub3QgYmUgZm91bmQsIGFuCisgICAgICogVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlcnJvciBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBJbnB1dFN0cmVhbSBmcm9tIHdoaWNoIHRvIHJlYWQgY2hhcmFjdGVycy4KKyAgICAgKiBAcGFyYW0gZW5jCisgICAgICogICAgICAgICAgICBpZGVudGlmaWVzIHRoZSBjaGFyYWN0ZXIgY29udmVydGVyIHRvIHVzZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGVuY30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmNvZGluZyBzcGVjaWZpZWQgYnkge0Bjb2RlIGVuY30gY2Fubm90IGJlIGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFN0cmVhbVJlYWRlcihJbnB1dFN0cmVhbSBpbiwgZmluYWwgU3RyaW5nIGVuYykKKyAgICAgICAgICAgIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoaW4pOworICAgICAgICBpZiAoZW5jID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMuaW4gPSBpbjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRlY29kZXIgPSBDaGFyc2V0LmZvck5hbWUoZW5jKS5uZXdEZWNvZGVyKCkub25NYWxmb3JtZWRJbnB1dCgKKyAgICAgICAgICAgICAgICAgICAgQ29kaW5nRXJyb3JBY3Rpb24uUkVQTEFDRSkub25Vbm1hcHBhYmxlQ2hhcmFjdGVyKAorICAgICAgICAgICAgICAgICAgICBDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uKQorICAgICAgICAgICAgICAgICAgICBuZXcgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbihlbmMpLmluaXRDYXVzZShlKTsKKyAgICAgICAgfQorICAgICAgICBieXRlcy5saW1pdCgwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IElucHV0U3RyZWFtUmVhZGVyIG9uIHRoZSBJbnB1dFN0cmVhbSB7QGNvZGUgaW59IGFuZAorICAgICAqIENoYXJzZXREZWNvZGVyIHtAY29kZSBkZWN9LgorICAgICAqCisgICAgICogQHBhcmFtIGluCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIElucHV0U3RyZWFtIGZyb20gd2hpY2ggdG8gcmVhZCBjaGFyYWN0ZXJzLgorICAgICAqIEBwYXJhbSBkZWMKKyAgICAgKiAgICAgICAgICAgIHRoZSBDaGFyc2V0RGVjb2RlciB1c2VkIGJ5IHRoZSBjaGFyYWN0ZXIgY29udmVyc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTdHJlYW1SZWFkZXIoSW5wdXRTdHJlYW0gaW4sIENoYXJzZXREZWNvZGVyIGRlYykgeworICAgICAgICBzdXBlcihpbik7CisgICAgICAgIGRlYy5hdmVyYWdlQ2hhcnNQZXJCeXRlKCk7CisgICAgICAgIHRoaXMuaW4gPSBpbjsKKyAgICAgICAgZGVjb2RlciA9IGRlYzsKKyAgICAgICAgYnl0ZXMubGltaXQoMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBJbnB1dFN0cmVhbVJlYWRlciBvbiB0aGUgSW5wdXRTdHJlYW0ge0Bjb2RlIGlufSBhbmQKKyAgICAgKiBDaGFyc2V0IHtAY29kZSBjaGFyc2V0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbgorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBJbnB1dFN0cmVhbSBmcm9tIHdoaWNoIHRvIHJlYWQgY2hhcmFjdGVycy4KKyAgICAgKiBAcGFyYW0gY2hhcnNldAorICAgICAqICAgICAgICAgICAgdGhlIENoYXJzZXQgdGhhdCBkZWZpbmVzIHRoZSBjaGFyYWN0ZXIgY29udmVydGVyCisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtUmVhZGVyKElucHV0U3RyZWFtIGluLCBDaGFyc2V0IGNoYXJzZXQpIHsKKyAgICAgICAgc3VwZXIoaW4pOworICAgICAgICB0aGlzLmluID0gaW47CisgICAgICAgIGRlY29kZXIgPSBjaGFyc2V0Lm5ld0RlY29kZXIoKS5vbk1hbGZvcm1lZElucHV0KAorICAgICAgICAgICAgICAgIENvZGluZ0Vycm9yQWN0aW9uLlJFUExBQ0UpLm9uVW5tYXBwYWJsZUNoYXJhY3RlcigKKyAgICAgICAgICAgICAgICBDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFKTsKKyAgICAgICAgYnl0ZXMubGltaXQoMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgcmVhZGVyLiBUaGlzIGltcGxlbWVudGF0aW9uIGNsb3NlcyB0aGUgc291cmNlIElucHV0U3RyZWFtIGFuZAorICAgICAqIHJlbGVhc2VzIGFsbCBsb2NhbCBzdG9yYWdlLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhdHRlbXB0aW5nIHRvIGNsb3NlIHRoaXMgcmVhZGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBpZiAoZGVjb2RlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZGVjb2Rlci5yZXNldCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZGVjb2RlciA9IG51bGw7CisgICAgICAgICAgICBpZiAoaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgaW4gPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaGlzdG9yaWNhbCBuYW1lIG9mIHRoZSBlbmNvZGluZyB1c2VkIGJ5IHRoaXMgd3JpdGVyIHRvIGNvbnZlcnQgY2hhcmFjdGVycyB0bworICAgICAqIGJ5dGVzLCBvciBudWxsIGlmIHRoaXMgd3JpdGVyIGhhcyBiZWVuIGNsb3NlZC4gTW9zdCBjYWxsZXJzIHNob3VsZCBwcm9iYWJseSBrZWVwCisgICAgICogdHJhY2sgb2YgdGhlIFN0cmluZyBvciBDaGFyc2V0IHRoZXkgcGFzc2VkIGluOyB0aGlzIG1ldGhvZCBtYXkgbm90IHJldHVybiB0aGUgc2FtZQorICAgICAqIG5hbWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpIHsKKyAgICAgICAgaWYgKCFpc09wZW4oKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIEhpc3RvcmljYWxDaGFyc2V0TmFtZXMuZ2V0KGRlY29kZXIuY2hhcnNldCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHNpbmdsZSBjaGFyYWN0ZXIgZnJvbSB0aGlzIHJlYWRlciBhbmQgcmV0dXJucyBpdCBhcyBhbiBpbnRlZ2VyCisgICAgICogd2l0aCB0aGUgdHdvIGhpZ2hlci1vcmRlciBieXRlcyBzZXQgdG8gMC4gUmV0dXJucyAtMSBpZiB0aGUgZW5kIG9mIHRoZQorICAgICAqIHJlYWRlciBoYXMgYmVlbiByZWFjaGVkLiBUaGUgYnl0ZSB2YWx1ZSBpcyBlaXRoZXIgb2J0YWluZWQgZnJvbQorICAgICAqIGNvbnZlcnRpbmcgYnl0ZXMgaW4gdGhpcyByZWFkZXIncyBidWZmZXIgb3IgYnkgZmlyc3QgZmlsbGluZyB0aGUgYnVmZmVyCisgICAgICogZnJvbSB0aGUgc291cmNlIElucHV0U3RyZWFtIGFuZCB0aGVuIHJlYWRpbmcgZnJvbSB0aGUgYnVmZmVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2hhcmFjdGVyIHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgcmVhZGVyIGhhcyBiZWVuCisgICAgICogICAgICAgICByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQgb3Igc29tZSBvdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgaWYgKCFpc09wZW4oKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW5wdXRTdHJlYW1SZWFkZXIgaXMgY2xvc2VkIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjaGFyW10gYnVmID0gbmV3IGNoYXJbMV07CisgICAgICAgICAgICByZXR1cm4gcmVhZChidWYsIDAsIDEpICE9IC0xID8gYnVmWzBdIDogLTE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhdCBtb3N0IHtAY29kZSBsZW5ndGh9IGNoYXJhY3RlcnMgZnJvbSB0aGlzIHJlYWRlciBhbmQgc3RvcmVzIHRoZW0KKyAgICAgKiBhdCBwb3NpdGlvbiB7QGNvZGUgb2Zmc2V0fSBpbiB0aGUgY2hhcmFjdGVyIGFycmF5IHtAY29kZSBidWZ9LiBSZXR1cm5zCisgICAgICogdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGFjdHVhbGx5IHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgcmVhZGVyIGhhcworICAgICAqIGJlZW4gcmVhY2hlZC4gVGhlIGJ5dGVzIGFyZSBlaXRoZXIgb2J0YWluZWQgZnJvbSBjb252ZXJ0aW5nIGJ5dGVzIGluIHRoaXMKKyAgICAgKiByZWFkZXIncyBidWZmZXIgb3IgYnkgZmlyc3QgZmlsbGluZyB0aGUgYnVmZmVyIGZyb20gdGhlIHNvdXJjZQorICAgICAqIElucHV0U3RyZWFtIGFuZCB0aGVuIHJlYWRpbmcgZnJvbSB0aGUgYnVmZmVyLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IHRvIHN0b3JlIHRoZSBjaGFyYWN0ZXJzIHJlYWQuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgcG9zaXRpb24gaW4ge0Bjb2RlIGJ1Zn0gdG8gc3RvcmUgdGhlIGNoYXJhY3RlcnMKKyAgICAgKiAgICAgICAgICAgIHJlYWQgZnJvbSB0aGlzIHJlYWRlci4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgcmVhZGVyIGhhcworICAgICAqICAgICAgICAgYmVlbiByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwfSBvciB7QGNvZGUgbGVuZ3RoIDwgMH0sIG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIG9mZnNldCArIGxlbmd0aH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgYnVmfS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyByZWFkZXIgaXMgY2xvc2VkIG9yIHNvbWUgb3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoY2hhcltdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBpZiAoIWlzT3BlbigpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbnB1dFN0cmVhbVJlYWRlciBpcyBjbG9zZWQiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIENoYXJCdWZmZXIgb3V0ID0gQ2hhckJ1ZmZlci53cmFwKGJ1ZmZlciwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICAgICAgQ29kZXJSZXN1bHQgcmVzdWx0ID0gQ29kZXJSZXN1bHQuVU5ERVJGTE9XOworCisgICAgICAgICAgICAvLyBieXRlcy5yZW1haW5pbmcoKSBpbmRpY2F0ZXMgbnVtYmVyIG9mIGJ5dGVzIGluIGJ1ZmZlcgorICAgICAgICAgICAgLy8gd2hlbiAxLXN0IHRpbWUgZW50ZXJlZCwgaXQnbGwgYmUgZXF1YWwgdG8gemVybworICAgICAgICAgICAgYm9vbGVhbiBuZWVkSW5wdXQgPSAhYnl0ZXMuaGFzUmVtYWluaW5nKCk7CisKKyAgICAgICAgICAgIHdoaWxlIChvdXQuaGFzUmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgICAgICAvLyBmaWxsIHRoZSBidWZmZXIgaWYgbmVlZGVkCisgICAgICAgICAgICAgICAgaWYgKG5lZWRJbnB1dCkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluLmF2YWlsYWJsZSgpID09IDAgJiYgb3V0LnBvc2l0aW9uKCkgPiBvZmZzZXQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBjb3VsZCByZXR1cm4gdGhlIHJlc3VsdCB3aXRob3V0IGJsb2NraW5nIHJlYWQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXZhaWxhYmxlIGRpZG4ndCB3b3JrIHNvIGp1c3QgdHJ5IHRoZSByZWFkCisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBpbnQgZGVzaXJlZEJ5dGVDb3VudCA9IGJ5dGVzLmNhcGFjaXR5KCkgLSBieXRlcy5saW1pdCgpOworICAgICAgICAgICAgICAgICAgICBpbnQgb2ZmID0gYnl0ZXMuYXJyYXlPZmZzZXQoKSArIGJ5dGVzLmxpbWl0KCk7CisgICAgICAgICAgICAgICAgICAgIGludCBhY3R1YWxCeXRlQ291bnQgPSBpbi5yZWFkKGJ5dGVzLmFycmF5KCksIG9mZiwgZGVzaXJlZEJ5dGVDb3VudCk7CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKGFjdHVhbEJ5dGVDb3VudCA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZW5kT2ZJbnB1dCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhY3R1YWxCeXRlQ291bnQgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnl0ZXMubGltaXQoYnl0ZXMubGltaXQoKSArIGFjdHVhbEJ5dGVDb3VudCk7CisgICAgICAgICAgICAgICAgICAgIG5lZWRJbnB1dCA9IGZhbHNlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIGRlY29kZSBieXRlcworICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRlY29kZXIuZGVjb2RlKGJ5dGVzLCBvdXQsIGZhbHNlKTsKKworICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuaXNVbmRlcmZsb3coKSkgeworICAgICAgICAgICAgICAgICAgICAvLyBjb21wYWN0IHRoZSBidWZmZXIgaWYgbm8gc3BhY2UgbGVmdAorICAgICAgICAgICAgICAgICAgICBpZiAoYnl0ZXMubGltaXQoKSA9PSBieXRlcy5jYXBhY2l0eSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBieXRlcy5jb21wYWN0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICBieXRlcy5saW1pdChieXRlcy5wb3NpdGlvbigpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzLnBvc2l0aW9uKDApOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIG5lZWRJbnB1dCA9IHRydWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAocmVzdWx0ID09IENvZGVyUmVzdWx0LlVOREVSRkxPVyAmJiBlbmRPZklucHV0KSB7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gZGVjb2Rlci5kZWNvZGUoYnl0ZXMsIG91dCwgdHJ1ZSk7CisgICAgICAgICAgICAgICAgZGVjb2Rlci5mbHVzaChvdXQpOworICAgICAgICAgICAgICAgIGRlY29kZXIucmVzZXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChyZXN1bHQuaXNNYWxmb3JtZWQoKSB8fCByZXN1bHQuaXNVbm1hcHBhYmxlKCkpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQudGhyb3dFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIG91dC5wb3NpdGlvbigpIC0gb2Zmc2V0ID09IDAgPyAtMSA6IG91dC5wb3NpdGlvbigpIC0gb2Zmc2V0OworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGlzT3BlbigpIHsKKyAgICAgICAgcmV0dXJuIGluICE9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyByZWFkZXIgaXMgcmVhZHkgdG8gYmUgcmVhZCB3aXRob3V0IGJsb2NraW5nLiBJZgorICAgICAqIHRoZSByZXN1bHQgaXMge0Bjb2RlIHRydWV9LCB0aGUgbmV4dCB7QGNvZGUgcmVhZCgpfSB3aWxsIG5vdCBibG9jay4gSWYKKyAgICAgKiB0aGUgcmVzdWx0IGlzIHtAY29kZSBmYWxzZX0gdGhlbiB0aGlzIHJlYWRlciBtYXkgb3IgbWF5IG5vdCBibG9jayB3aGVuCisgICAgICoge0Bjb2RlIHJlYWQoKX0gaXMgY2FsbGVkLiBUaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMge0Bjb2RlIHRydWV9IGlmCisgICAgICogdGhlcmUgYXJlIGJ5dGVzIGF2YWlsYWJsZSBpbiB0aGUgYnVmZmVyIG9yIHRoZSBzb3VyY2Ugc3RyZWFtIGhhcyBieXRlcworICAgICAqIGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSByZWNlaXZlciB3aWxsIG5vdCBibG9jayB3aGVuIHtAY29kZSByZWFkKCl9CisgICAgICogICAgICAgICBpcyBjYWxsZWQsIHtAY29kZSBmYWxzZX0gaWYgdW5rbm93biBvciBibG9ja2luZyB3aWxsIG9jY3VyLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQgb3Igc29tZSBvdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIHJlYWR5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBpZiAoaW4gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW5wdXRTdHJlYW1SZWFkZXIgaXMgY2xvc2VkIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiBieXRlcy5oYXNSZW1haW5pbmcoKSB8fCBpbi5hdmFpbGFibGUoKSA+IDA7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFmMzA3YmQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9JbnRlcnJ1cHRlZElPRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCisvKioKKyAqIFNpZ25hbHMgdGhhdCBhIGJsb2NraW5nIEkvTyBvcGVyYXRpb24gaGFzIGJlZW4gaW50ZXJydXB0ZWQuIFRoZSBudW1iZXIgb2YKKyAqIGJ5dGVzIHRoYXQgd2VyZSB0cmFuc2ZlcnJlZCBzdWNjZXNzZnVsbHkgYmVmb3JlIHRoZSBpbnRlcnJ1cHRpb24gdG9vayBwbGFjZQorICogaXMgc3RvcmVkIGluIGEgZmllbGQgb2YgdGhlIGV4Y2VwdGlvbi4KKyAqLworcHVibGljIGNsYXNzIEludGVycnVwdGVkSU9FeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0MDIwNTY4NDYwNzI3NTAwNTY3TDsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgYnl0ZXMgdHJhbnNmZXJyZWQgYmVmb3JlIHRoZSBJL08gaW50ZXJydXB0IG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgYnl0ZXNUcmFuc2ZlcnJlZDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIEludGVycnVwdGVkSU9FeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSB3aXRoIHRoZSBnaXZlbiBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIHdpdGggZ2l2ZW4gZGV0YWlsIG1lc3NhZ2UgYW5kIGNhdXNlLgorICAgICAqIEBoaWRlIGludGVybmFsIHVzZSBvbmx5CisgICAgICovCisgICAgcHVibGljIEludGVycnVwdGVkSU9FeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlLCBjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vSW52YWxpZENsYXNzRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9JbnZhbGlkQ2xhc3NFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zODYzZjI0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vSW52YWxpZENsYXNzRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw4NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCisvKioKKyAqIFNpZ25hbHMgYSBwcm9ibGVtIGR1cmluZyB0aGUgc2VyaWFsaXphdGlvbiBvciBvciBkZXNlcmlhbGl6YXRpb24gb2YgYW4KKyAqIG9iamVjdC4gUG9zc2libGUgcmVhc29ucyBpbmNsdWRlOgorICogPHVsPgorICogPGxpPlRoZSBTVUlEcyBvZiB0aGUgY2xhc3MgbG9hZGVkIGJ5IHRoZSBWTSBhbmQgdGhlIHNlcmlhbGl6ZWQgY2xhc3MgaW5mbyBkbworICogbm90IG1hdGNoLjwvbGk+CisgKiA8bGk+QSBzZXJpYWxpemFibGUgb3IgZXh0ZXJuYWxpemFibGUgb2JqZWN0IGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQgKHdoZW4KKyAqIGRlc2VyaWFsaXppbmcpIGJlY2F1c2UgdGhlIG5vLWFyZyBjb25zdHJ1Y3RvciB0aGF0IG5lZWRzIHRvIGJlIHJ1biBpcyBub3QKKyAqIHZpc2libGUgb3IgZmFpbHMuPC9saT4KKyAqIDwvdWw+CisgKgorICogQHNlZSBPYmplY3RJbnB1dFN0cmVhbSAjcmVhZE9iamVjdCgpCisgKiBAc2VlIE9iamVjdElucHV0VmFsaWRhdGlvbiN2YWxpZGF0ZU9iamVjdCgpCisgKi8KK3B1YmxpYyBjbGFzcyBJbnZhbGlkQ2xhc3NFeGNlcHRpb24gZXh0ZW5kcyBPYmplY3RTdHJlYW1FeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQzMzMzMTYyOTYyNTEwNTQ0MTZMOworCisgICAgLyoqCisgICAgICogVGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBjbGFzcyB0aGF0IGNhdXNlZCB0aGUgcHJvYmxlbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGNsYXNzbmFtZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEludmFsaWRDbGFzc0V4Y2VwdGlvbn0gd2l0aCBpdHMgc3RhY2sgdHJhY2UgYW5kCisgICAgICogZGV0YWlsZWQgbWVzc2FnZSBmaWxsZWQgaW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW52YWxpZENsYXNzRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEludmFsaWRDbGFzc0V4Y2VwdGlvbn0gd2l0aCBpdHMgc3RhY2sgdHJhY2UsCisgICAgICogZGV0YWlsIG1lc3NhZ2UgYW5kIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgY2xhc3Mgd2hpY2ggY2F1c2VkIHRoZQorICAgICAqIGV4Y2VwdGlvbiBmaWxsZWQgaW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2xhc3NOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgdGhhdCBjYXVzZWQgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW52YWxpZENsYXNzRXhjZXB0aW9uKFN0cmluZyBjbGFzc05hbWUsIFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgICAgICB0aGlzLmNsYXNzbmFtZSA9IGNsYXNzTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZXRhaWwgbWVzc2FnZSB3aGljaCB3YXMgcHJvdmlkZWQgd2hlbiB0aGUgZXhjZXB0aW9uIHdhcworICAgICAqIGNyZWF0ZWQuIHtAY29kZSBudWxsfSBpcyByZXR1cm5lZCBpZiBubyBtZXNzYWdlIHdhcyBwcm92aWRlZCBhdCBjcmVhdGlvbgorICAgICAqIHRpbWUuIElmIGEgZGV0YWlsIG1lc3NhZ2UgYXMgd2VsbCBhcyBhIGNsYXNzIG5hbWUgYXJlIHByb3ZpZGVkLCB0aGVuIHRoZQorICAgICAqIHZhbHVlcyBhcmUgY29uY2F0ZW5hdGVkIGFuZCByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGRldGFpbCBtZXNzYWdlLCBwb3NzaWJseSBjb25jYXRlbmF0ZWQgd2l0aCB0aGUgbmFtZSBvZiB0aGUKKyAgICAgKiAgICAgICAgIGNsYXNzIHRoYXQgY2F1c2VkIHRoZSBwcm9ibGVtLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9IHN1cGVyLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgaWYgKGNsYXNzbmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICBtc2cgPSBjbGFzc25hbWUgKyAiOyAiICsgbXNnOworICAgICAgICB9CisgICAgICAgIHJldHVybiBtc2c7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vSW52YWxpZE9iamVjdEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vSW52YWxpZE9iamVjdEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQzMzE3NmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9JbnZhbGlkT2JqZWN0RXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCisvKioKKyAqIFNpZ25hbHMgdGhhdCwgZHVyaW5nIGRlc2VyaWFsaXphdGlvbiwgdGhlIHZhbGlkYXRpb24gb2YgYW4gb2JqZWN0IGhhcyBmYWlsZWQuCisgKgorICogQHNlZSBPYmplY3RJbnB1dFN0cmVhbSNyZWdpc3RlclZhbGlkYXRpb24oT2JqZWN0SW5wdXRWYWxpZGF0aW9uLCBpbnQpCisgKiBAc2VlIE9iamVjdElucHV0VmFsaWRhdGlvbiN2YWxpZGF0ZU9iamVjdCgpCisgKi8KK3B1YmxpYyBjbGFzcyBJbnZhbGlkT2JqZWN0RXhjZXB0aW9uIGV4dGVuZHMgT2JqZWN0U3RyZWFtRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDMyMzMxNzQzMTgyODE4Mzk1ODNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiB7QGNvZGUgSW52YWxpZE9iamVjdEV4Y2VwdGlvbn0gd2l0aCBpdHMgc3RhY2sgdHJhY2UgYW5kCisgICAgICogZGV0YWlsIG1lc3NhZ2UgZmlsbGVkIGluLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIEludmFsaWRPYmplY3RFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vTGluZU51bWJlcklucHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9MaW5lTnVtYmVySW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZDFjZjE0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vTGluZU51bWJlcklucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwyNDIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworCisvKioKKyAqIFdyYXBzIGFuIGV4aXN0aW5nIHtAbGluayBJbnB1dFN0cmVhbX0gYW5kIGNvdW50cyB0aGUgbGluZSB0ZXJtaW5hdG9ycworICogZW5jb3VudGVyZWQgd2hpbGUgcmVhZGluZyB0aGUgZGF0YS4gTGluZSBudW1iZXJpbmcgc3RhcnRzIGF0IDAuIFJlY29nbml6ZWQKKyAqIGxpbmUgdGVybWluYXRvciBzZXF1ZW5jZXMgYXJlIHtAY29kZSAnXHInfSwge0Bjb2RlICdcbid9IGFuZCB7QGNvZGUgIlxyXG4ifS4KKyAqIFdoZW4gdXNpbmcge0Bjb2RlIHJlYWR9LCBsaW5lIHRlcm1pbmF0b3Igc2VxdWVuY2VzIGFyZSBhbHdheXMgdHJhbnNsYXRlZCBpbnRvCisgKiB7QGNvZGUgJ1xuJ30uCisgKgorICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayBMaW5lTnVtYmVyUmVhZGVyfQorICovCitARGVwcmVjYXRlZAorcHVibGljIGNsYXNzIExpbmVOdW1iZXJJbnB1dFN0cmVhbSBleHRlbmRzIEZpbHRlcklucHV0U3RyZWFtIHsKKworICAgIHByaXZhdGUgaW50IGxpbmVOdW1iZXI7CisKKyAgICBwcml2YXRlIGludCBtYXJrZWRMaW5lTnVtYmVyID0gLTE7CisKKyAgICBwcml2YXRlIGludCBsYXN0Q2hhciA9IC0xOworCisgICAgcHJpdmF0ZSBpbnQgbWFya2VkTGFzdENoYXI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBMaW5lTnVtYmVySW5wdXRTdHJlYW19IG9uIHRoZSB7QGxpbmsgSW5wdXRTdHJlYW19CisgICAgICoge0Bjb2RlIGlufS4gTGluZSBudW1iZXJzIGFyZSBjb3VudGVkIGZvciBhbGwgZGF0YSByZWFkIGZyb20gdGhpcyBzdHJlYW0uCisgICAgICoKKyAgICAgKiA8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IHBhc3NpbmcgYSBudWxsIHNvdXJjZSBjcmVhdGVzIGFuIGludmFsaWQKKyAgICAgKiB7QGNvZGUgTGluZU51bWJlcklucHV0U3RyZWFtfS4gQWxsIG9wZXJhdGlvbnMgb24gc3VjaCBhIHN0cmVhbSB3aWxsIGZhaWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiAgICAgICAgICAgIFRoZSBub24tbnVsbCBpbnB1dCBzdHJlYW0gdG8gY291bnQgbGluZSBudW1iZXJzLgorICAgICAqLworICAgIHB1YmxpYyBMaW5lTnVtYmVySW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgc3VwZXIoaW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB0aGUgc291cmNlIHN0cmVhbSBtYXkganVzdCBiZSBhIHNlcXVlbmNlIG9mIHtAY29kZSAiXHJcbiJ9IGJ5dGVzCisgICAgICogd2hpY2ggYXJlIGNvbnZlcnRlZCBpbnRvIHtAY29kZSAnXG4nfSBieSB0aGlzIHN0cmVhbS4gVGhlcmVmb3JlLAorICAgICAqIHtAY29kZSBhdmFpbGFibGV9IHJldHVybnMgb25seSB7QGNvZGUgaW4uYXZhaWxhYmxlKCkgLyAyfSBieXRlcyBhcworICAgICAqIHJlc3VsdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBpbi5hdmFpbGFibGUoKSAvIDIgKyAobGFzdENoYXIgPT0gLTEgPyAwIDogMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3VycmVudCBsaW5lIG51bWJlciBmb3IgdGhpcyBzdHJlYW0uIE51bWJlcmluZyBzdGFydHMgYXQgMC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgbGluZSBudW1iZXIuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyKCkgeworICAgICAgICByZXR1cm4gbGluZU51bWJlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGEgbWFyayBwb3NpdGlvbiBpbiB0aGlzIHN0cmVhbS4gVGhlIHBhcmFtZXRlciB7QGNvZGUgcmVhZGxpbWl0fQorICAgICAqIGluZGljYXRlcyBob3cgbWFueSBieXRlcyBjYW4gYmUgcmVhZCBiZWZvcmUgdGhlIG1hcmsgaXMgaW52YWxpZGF0ZWQuCisgICAgICogU2VuZGluZyB7QGNvZGUgcmVzZXQoKX0gd2lsbCByZXBvc2l0aW9uIHRoaXMgc3RyZWFtIGJhY2sgdG8gdGhlIG1hcmtlZAorICAgICAqIHBvc2l0aW9uLCBwcm92aWRlZCB0aGF0IHtAY29kZSByZWFkbGltaXR9IGhhcyBub3QgYmVlbiBzdXJwYXNzZWQuCisgICAgICogVGhlIGxpbmUgbnVtYmVyIGNvdW50IHdpbGwgYWxzbyBiZSByZXNldCB0byB0aGUgbGFzdCBtYXJrZWQKKyAgICAgKiBsaW5lIG51bWJlciBjb3VudC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHNldHMgYSBtYXJrIGluIHRoZSBmaWx0ZXJlZCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhZGxpbWl0CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgY2FuIGJlIHJlYWQgZnJvbSB0aGlzIHN0cmVhbSBiZWZvcmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXJrIGlzIGludmFsaWRhdGVkLgorICAgICAqIEBzZWUgI21hcmtTdXBwb3J0ZWQoKQorICAgICAqIEBzZWUgI3Jlc2V0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBtYXJrKGludCByZWFkbGltaXQpIHsKKyAgICAgICAgaW4ubWFyayhyZWFkbGltaXQpOworICAgICAgICBtYXJrZWRMaW5lTnVtYmVyID0gbGluZU51bWJlcjsKKyAgICAgICAgbWFya2VkTGFzdENoYXIgPSBsYXN0Q2hhcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHNpbmdsZSBieXRlIGZyb20gdGhlIGZpbHRlcmVkIHN0cmVhbSBhbmQgcmV0dXJucyBpdCBhcyBhbiBpbnRlZ2VyCisgICAgICogaW4gdGhlIHJhbmdlIGZyb20gMCB0byAyNTUuIFJldHVybnMgLTEgaWYgdGhlIGVuZCBvZiB0aGlzIHN0cmVhbSBoYXMgYmVlbgorICAgICAqIHJlYWNoZWQuCisgICAgICogPHA+CisgICAgICogVGhlIGxpbmUgbnVtYmVyIGNvdW50IGlzIGluY3JlbWVudGVkIGlmIGEgbGluZSB0ZXJtaW5hdG9yIGlzIGVuY291bnRlcmVkLgorICAgICAqIFJlY29nbml6ZWQgbGluZSB0ZXJtaW5hdG9yIHNlcXVlbmNlcyBhcmUge0Bjb2RlICdccid9LCB7QGNvZGUgJ1xuJ30gYW5kCisgICAgICoge0Bjb2RlICJcclxuIn0uIExpbmUgdGVybWluYXRvciBzZXF1ZW5jZXMgYXJlIGFsd2F5cyB0cmFuc2xhdGVkIGludG8KKyAgICAgKiB7QGNvZGUgJ1xuJ30uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBieXRlIHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgZmlsdGVyZWQgc3RyZWFtIGhhcyBiZWVuCisgICAgICogICAgICAgICByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3RyZWFtIGlzIGNsb3NlZCBvciBhbm90aGVyIElPRXhjZXB0aW9uIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZmFsbHRocm91Z2giKQorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBjdXJyZW50Q2hhciA9IGxhc3RDaGFyOworICAgICAgICBpZiAoY3VycmVudENoYXIgPT0gLTEpIHsKKyAgICAgICAgICAgIGN1cnJlbnRDaGFyID0gaW4ucmVhZCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbGFzdENoYXIgPSAtMTsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGN1cnJlbnRDaGFyKSB7CisgICAgICAgICAgICBjYXNlICdccic6CisgICAgICAgICAgICAgICAgY3VycmVudENoYXIgPSAnXG4nOworICAgICAgICAgICAgICAgIGxhc3RDaGFyID0gaW4ucmVhZCgpOworICAgICAgICAgICAgICAgIGlmIChsYXN0Q2hhciA9PSAnXG4nKSB7CisgICAgICAgICAgICAgICAgICAgIGxhc3RDaGFyID0gLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIGZhbGwgdGhyb3VnaAorICAgICAgICAgICAgY2FzZSAnXG4nOgorICAgICAgICAgICAgICAgIGxpbmVOdW1iZXIrKzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY3VycmVudENoYXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYXQgbW9zdCB7QGNvZGUgbGVuZ3RofSBieXRlcyBmcm9tIHRoZSBmaWx0ZXJlZCBzdHJlYW0gYW5kIHN0b3JlcworICAgICAqIHRoZW0gaW4gdGhlIGJ5dGUgYXJyYXkge0Bjb2RlIGJ1ZmZlcn0gc3RhcnRpbmcgYXQge0Bjb2RlIG9mZnNldH0uCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHJlYWQgb3IgLTEgaWYgbm8gYnl0ZXMgaGF2ZSBiZWVuCisgICAgICogcmVhZCBhbmQgdGhlIGVuZCBvZiB0aGlzIHN0cmVhbSBoYXMgYmVlbiByZWFjaGVkLgorICAgICAqIDxwPgorICAgICAqIFRoZSBsaW5lIG51bWJlciBjb3VudCBpcyBpbmNyZW1lbnRlZCBpZiBhIGxpbmUgdGVybWluYXRvciBpcyBlbmNvdW50ZXJlZC4KKyAgICAgKiBSZWNvZ25pemVkIGxpbmUgdGVybWluYXRvciBzZXF1ZW5jZXMgYXJlIHtAY29kZSAnXHInfSwge0Bjb2RlICdcbid9IGFuZAorICAgICAqIHtAY29kZSAiXHJcbiJ9LiBMaW5lIHRlcm1pbmF0b3Igc2VxdWVuY2VzIGFyZSBhbHdheXMgdHJhbnNsYXRlZCBpbnRvCisgICAgICoge0Bjb2RlICdcbid9LgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IGluIHdoaWNoIHRvIHN0b3JlIHRoZSBieXRlcyByZWFkLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIHBvc2l0aW9uIGluIHtAY29kZSBidWZmZXJ9IHRvIHN0b3JlIHRoZSBieXRlcyByZWFkCisgICAgICogICAgICAgICAgICBmcm9tIHRoaXMgc3RyZWFtLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0byBzdG9yZSBpbiB7QGNvZGUgYnVmZmVyfS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZQorICAgICAqICAgICAgICAgZmlsdGVyZWQgc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWQgd2hpbGUgcmVhZGluZy4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGxlbmd0aCA8IDB9LCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBsZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGJ1ZmZlcn0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgc3RyZWFtIGlzIGNsb3NlZCBvciBhbm90aGVyIElPRXhjZXB0aW9uIG9jY3Vycy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGJ1ZmZlcn0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXIubGVuZ3RoLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGludCBjdXJyZW50Q2hhcjsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY3VycmVudENoYXIgPSByZWFkKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgaWYgKGkgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjdXJyZW50Q2hhciA9PSAtMSkgeworICAgICAgICAgICAgICAgIHJldHVybiBpID09IDAgPyAtMSA6IGk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBidWZmZXJbb2Zmc2V0ICsgaV0gPSAoYnl0ZSkgY3VycmVudENoYXI7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhpcyBzdHJlYW0gdG8gdGhlIGxhc3QgbWFya2VkIGxvY2F0aW9uLiBJdCBhbHNvIHJlc2V0cyB0aGUgbGluZQorICAgICAqIGNvdW50IHRvIHdoYXQgaXMgd2FzIHdoZW4gdGhpcyBzdHJlYW0gd2FzIG1hcmtlZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHN0cmVhbSBpcyBhbHJlYWR5IGNsb3NlZCwgbm8gbWFyayBoYXMgYmVlbiBzZXQgb3IgdGhlCisgICAgICogICAgICAgICAgICAgbWFyayBpcyBubyBsb25nZXIgdmFsaWQgYmVjYXVzZSBtb3JlIHRoYW4ge0Bjb2RlIHJlYWRsaW1pdH0KKyAgICAgKiAgICAgICAgICAgICBieXRlcyBoYXZlIGJlZW4gcmVhZCBzaW5jZSBzZXR0aW5nIHRoZSBtYXJrLgorICAgICAqIEBzZWUgI21hcmsoaW50KQorICAgICAqIEBzZWUgI21hcmtTdXBwb3J0ZWQoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW4ucmVzZXQoKTsKKyAgICAgICAgbGluZU51bWJlciA9IG1hcmtlZExpbmVOdW1iZXI7CisgICAgICAgIGxhc3RDaGFyID0gbWFya2VkTGFzdENoYXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbGluZSBudW1iZXIgb2YgdGhpcyBzdHJlYW0gdG8gdGhlIHNwZWNpZmllZAorICAgICAqIHtAY29kZSBsaW5lTnVtYmVyfS4gTm90ZSB0aGF0IHRoaXMgbWF5IGhhdmUgc2lkZSBlZmZlY3RzIG9uIHRoZQorICAgICAqIGxpbmUgbnVtYmVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgbGFzdCBtYXJrZWQgcG9zaXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGluZU51bWJlcgorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBsaW5lTnVtYmVyIHZhbHVlLgorICAgICAqIEBzZWUgI21hcmsoaW50KQorICAgICAqIEBzZWUgI3Jlc2V0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMaW5lTnVtYmVyKGludCBsaW5lTnVtYmVyKSB7CisgICAgICAgIHRoaXMubGluZU51bWJlciA9IGxpbmVOdW1iZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcHMge0Bjb2RlIGNvdW50fSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhpcyBzdHJlYW0uIFN1YnNlcXVlbnQKKyAgICAgKiBjYWxscyB0byB7QGNvZGUgcmVhZH0gd2lsbCBub3QgcmV0dXJuIHRoZXNlIGJ5dGVzIHVubGVzcyB7QGNvZGUgcmVzZXR9IGlzCisgICAgICogdXNlZC4gVGhpcyBpbXBsZW1lbnRhdGlvbiBza2lwcyB7QGNvZGUgYnl0ZUNvdW50fSBieXRlcyBpbiB0aGUKKyAgICAgKiBmaWx0ZXJlZCBzdHJlYW0gYW5kIGluY3JlbWVudHMgdGhlIGxpbmUgbnVtYmVyIGNvdW50IHdoZW5ldmVyIGxpbmUKKyAgICAgKiB0ZXJtaW5hdG9yIHNlcXVlbmNlcyBhcmUgc2tpcHBlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBieXRlQ291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gc2tpcC4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgc2tpcHBlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBzdHJlYW0gaXMgY2xvc2VkIG9yIGFub3RoZXIgSU9FeGNlcHRpb24gb2NjdXJzLgorICAgICAqIEBzZWUgI21hcmsoaW50KQorICAgICAqIEBzZWUgI3JlYWQoKQorICAgICAqIEBzZWUgI3Jlc2V0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBza2lwKGxvbmcgYnl0ZUNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gU3RyZWFtcy5za2lwQnlSZWFkaW5nKHRoaXMsIGJ5dGVDb3VudCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vTGluZU51bWJlclJlYWRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vTGluZU51bWJlclJlYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAzZDAyYTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9MaW5lTnVtYmVyUmVhZGVyLmphdmEKQEAgLTAsMCArMSwyNzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworLyoqCisgKiBXcmFwcyBhbiBleGlzdGluZyB7QGxpbmsgUmVhZGVyfSBhbmQgY291bnRzIHRoZSBsaW5lIHRlcm1pbmF0b3JzIGVuY291bnRlcmVkCisgKiB3aGlsZSByZWFkaW5nIHRoZSBkYXRhLiBUaGUgbGluZSBudW1iZXIgc3RhcnRzIGF0IDAgYW5kIGlzIGluY3JlbWVudGVkIGFueQorICogdGltZSB7QGNvZGUgJ1xyJ30sIHtAY29kZSAnXG4nfSBvciB7QGNvZGUgIlxyXG4ifSBpcyByZWFkLiBUaGUgY2xhc3MgaGFzIGFuCisgKiBpbnRlcm5hbCBidWZmZXIgZm9yIGl0cyBkYXRhLiBUaGUgc2l6ZSBvZiB0aGUgYnVmZmVyIGRlZmF1bHRzIHRvIDggS0IuCisgKi8KK3B1YmxpYyBjbGFzcyBMaW5lTnVtYmVyUmVhZGVyIGV4dGVuZHMgQnVmZmVyZWRSZWFkZXIgeworCisgICAgcHJpdmF0ZSBpbnQgbGluZU51bWJlcjsKKworICAgIHByaXZhdGUgaW50IG1hcmtlZExpbmVOdW1iZXIgPSAtMTsKKworICAgIHByaXZhdGUgYm9vbGVhbiBsYXN0V2FzQ1I7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gbWFya2VkTGFzdFdhc0NSOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBMaW5lTnVtYmVyUmVhZGVyIG9uIHRoZSBSZWFkZXIge0Bjb2RlIGlufS4gVGhlIGludGVybmFsCisgICAgICogYnVmZmVyIGdldHMgdGhlIGRlZmF1bHQgc2l6ZSAoOCBLQikuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBSZWFkZXIgdGhhdCBpcyBidWZmZXJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGluZU51bWJlclJlYWRlcihSZWFkZXIgaW4pIHsKKyAgICAgICAgc3VwZXIoaW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgTGluZU51bWJlclJlYWRlciBvbiB0aGUgUmVhZGVyIHtAY29kZSBpbn0uIFRoZSBzaXplIG9mCisgICAgICogdGhlIGludGVybmFsIGJ1ZmZlciBpcyBzcGVjaWZpZWQgYnkgdGhlIHBhcmFtZXRlciB7QGNvZGUgc2l6ZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBSZWFkZXIgdGhhdCBpcyBidWZmZXJlZC4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIHNpemUgb2YgdGhlIGJ1ZmZlciB0byBhbGxvY2F0ZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzaXplIDw9IDB9LgorICAgICAqLworICAgIHB1YmxpYyBMaW5lTnVtYmVyUmVhZGVyKFJlYWRlciBpbiwgaW50IHNpemUpIHsKKyAgICAgICAgc3VwZXIoaW4sIHNpemUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgbGluZSBudW1iZXIgZm9yIHRoaXMgcmVhZGVyLiBOdW1iZXJpbmcgc3RhcnRzIGF0IDAuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IGxpbmUgbnVtYmVyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICByZXR1cm4gbGluZU51bWJlcjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgYSBtYXJrIHBvc2l0aW9uIGluIHRoaXMgcmVhZGVyLiBUaGUgcGFyYW1ldGVyIHtAY29kZSByZWFkbGltaXR9CisgICAgICogaW5kaWNhdGVzIGhvdyBtYW55IGNoYXJhY3RlcnMgY2FuIGJlIHJlYWQgYmVmb3JlIHRoZSBtYXJrIGlzIGludmFsaWRhdGVkLgorICAgICAqIFNlbmRpbmcge0Bjb2RlIHJlc2V0KCl9IHdpbGwgcmVwb3NpdGlvbiB0aGlzIHJlYWRlciBiYWNrIHRvIHRoZSBtYXJrZWQKKyAgICAgKiBwb3NpdGlvbiwgcHJvdmlkZWQgdGhhdCB7QGNvZGUgcmVhZGxpbWl0fSBoYXMgbm90IGJlZW4gc3VycGFzc2VkLiBUaGUKKyAgICAgKiBsaW5lIG51bWJlciBhc3NvY2lhdGVkIHdpdGggdGhpcyBtYXJrZWQgcG9zaXRpb24gaXMgYWxzbyBzdG9yZWQgc28gdGhhdAorICAgICAqIGl0IGNhbiBiZSByZXN0b3JlZCB3aGVuIHtAY29kZSByZXNldCgpfSBpcyBjYWxsZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhZGxpbWl0CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdGhhdCBjYW4gYmUgcmVhZCBmcm9tIHRoaXMgc3RyZWFtCisgICAgICogICAgICAgICAgICBiZWZvcmUgdGhlIG1hcmsgaXMgaW52YWxpZGF0ZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBzZXR0aW5nIHRoZSBtYXJrIGluIHRoaXMgcmVhZGVyLgorICAgICAqIEBzZWUgI21hcmtTdXBwb3J0ZWQoKQorICAgICAqIEBzZWUgI3Jlc2V0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBtYXJrKGludCByZWFkbGltaXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgc3VwZXIubWFyayhyZWFkbGltaXQpOworICAgICAgICAgICAgbWFya2VkTGluZU51bWJlciA9IGxpbmVOdW1iZXI7CisgICAgICAgICAgICBtYXJrZWRMYXN0V2FzQ1IgPSBsYXN0V2FzQ1I7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHNpbmdsZSBjaGFyYWN0ZXIgZnJvbSB0aGUgc291cmNlIHJlYWRlciBhbmQgcmV0dXJucyBpdCBhcyBhbgorICAgICAqIGludGVnZXIgd2l0aCB0aGUgdHdvIGhpZ2hlci1vcmRlciBieXRlcyBzZXQgdG8gMC4gUmV0dXJucyAtMSBpZiB0aGUgZW5kCisgICAgICogb2YgdGhlIHNvdXJjZSByZWFkZXIgaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbGluZSBudW1iZXIgY291bnQgaXMgaW5jcmVtZW50ZWQgaWYgYSBsaW5lIHRlcm1pbmF0b3IgaXMgZW5jb3VudGVyZWQuCisgICAgICogUmVjb2duaXplZCBsaW5lIHRlcm1pbmF0b3Igc2VxdWVuY2VzIGFyZSB7QGNvZGUgJ1xyJ30sIHtAY29kZSAnXG4nfSBhbmQKKyAgICAgKiB7QGNvZGUgIlxyXG4ifS4gTGluZSB0ZXJtaW5hdG9yIHNlcXVlbmNlcyBhcmUgYWx3YXlzIHRyYW5zbGF0ZWQgaW50bworICAgICAqIHtAY29kZSAnXG4nfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNoYXJhY3RlciByZWFkIG9yIC0xIGlmIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSByZWFkZXIgaGFzIGJlZW4KKyAgICAgKiAgICAgICAgIHJlYWNoZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSByZWFkZXIgaXMgY2xvc2VkIG9yIGFub3RoZXIgSU9FeGNlcHRpb24gb2NjdXJzLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJmYWxsdGhyb3VnaCIpCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBpbnQgY2ggPSBzdXBlci5yZWFkKCk7CisgICAgICAgICAgICBpZiAoY2ggPT0gJ1xuJyAmJiBsYXN0V2FzQ1IpIHsKKyAgICAgICAgICAgICAgICBjaCA9IHN1cGVyLnJlYWQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGxhc3RXYXNDUiA9IGZhbHNlOworICAgICAgICAgICAgc3dpdGNoIChjaCkgeworICAgICAgICAgICAgICAgIGNhc2UgJ1xyJzoKKyAgICAgICAgICAgICAgICAgICAgY2ggPSAnXG4nOworICAgICAgICAgICAgICAgICAgICBsYXN0V2FzQ1IgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAvLyBmYWxsIHRocm91Z2gKKyAgICAgICAgICAgICAgICBjYXNlICdcbic6CisgICAgICAgICAgICAgICAgICAgIGxpbmVOdW1iZXIrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBjaDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGF0IG1vc3Qge0Bjb2RlIGNvdW50fSBjaGFyYWN0ZXJzIGZyb20gdGhlIHNvdXJjZSByZWFkZXIgYW5kIHN0b3JlcworICAgICAqIHRoZW0gaW4gdGhlIGNoYXJhY3RlciBhcnJheSB7QGNvZGUgYnVmZmVyfSBzdGFydGluZyBhdCB7QGNvZGUgb2Zmc2V0fS4KKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBhY3R1YWxseSByZWFkIG9yIC0xIGlmIG5vIGNoYXJhY3RlcnMKKyAgICAgKiBoYXZlIGJlZW4gcmVhZCBhbmQgdGhlIGVuZCBvZiB0aGlzIHJlYWRlciBoYXMgYmVlbiByZWFjaGVkLgorICAgICAqIDxwPgorICAgICAqIFRoZSBsaW5lIG51bWJlciBjb3VudCBpcyBpbmNyZW1lbnRlZCBpZiBhIGxpbmUgdGVybWluYXRvciBpcyBlbmNvdW50ZXJlZC4KKyAgICAgKiBSZWNvZ25pemVkIGxpbmUgdGVybWluYXRvciBzZXF1ZW5jZXMgYXJlIHtAY29kZSAnXHInfSwge0Bjb2RlICdcbid9IGFuZAorICAgICAqIHtAY29kZSAiXHJcbiJ9LgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IGluIHdoaWNoIHRvIHN0b3JlIHRoZSBjaGFyYWN0ZXJzIHJlYWQuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgcG9zaXRpb24gaW4ge0Bjb2RlIGJ1ZmZlcn0gdG8gc3RvcmUgdGhlIGNoYXJhY3RlcnMKKyAgICAgKiAgICAgICAgICAgIHJlYWQgZnJvbSB0aGlzIHJlYWRlci4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHN0b3JlIGluIHtAY29kZSBidWZmZXJ9LgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGFjdHVhbGx5IHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUKKyAgICAgKiAgICAgICAgIHNvdXJjZSByZWFkZXIgaGFzIGJlZW4gcmVhY2hlZCB3aGlsZSByZWFkaW5nLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQgb3IgYW5vdGhlciBJT0V4Y2VwdGlvbiBvY2N1cnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGNoYXJbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBpbnQgcmVhZCA9IHN1cGVyLnJlYWQoYnVmZmVyLCBvZmZzZXQsIGNvdW50KTsKKyAgICAgICAgICAgIGlmIChyZWFkID09IC0xKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWFkOyBpKyspIHsKKyAgICAgICAgICAgICAgICBjaGFyIGNoID0gYnVmZmVyW29mZnNldCArIGldOworICAgICAgICAgICAgICAgIGlmIChjaCA9PSAnXHInKSB7CisgICAgICAgICAgICAgICAgICAgIGxpbmVOdW1iZXIrKzsKKyAgICAgICAgICAgICAgICAgICAgbGFzdFdhc0NSID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09ICdcbicpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFsYXN0V2FzQ1IpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVOdW1iZXIrKzsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBsYXN0V2FzQ1IgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBsYXN0V2FzQ1IgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVhZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgbGluZSBvZiB0ZXh0IGF2YWlsYWJsZSBmcm9tIHRoaXMgcmVhZGVyLiBBIGxpbmUgaXMKKyAgICAgKiByZXByZXNlbnRlZCBieSAwIG9yIG1vcmUgY2hhcmFjdGVycyBmb2xsb3dlZCBieSB7QGNvZGUgJ1xyJ30sCisgICAgICoge0Bjb2RlICdcbid9LCB7QGNvZGUgIlxyXG4ifSBvciB0aGUgZW5kIG9mIHRoZSBzdHJlYW0uIFRoZSByZXR1cm5lZAorICAgICAqIHN0cmluZyBkb2VzIG5vdCBpbmNsdWRlIHRoZSBuZXdsaW5lIHNlcXVlbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29udGVudHMgb2YgdGhlIGxpbmUgb3Ige0Bjb2RlIG51bGx9IGlmIG5vIGNoYXJhY3RlcnMgaGF2ZQorICAgICAqICAgICAgICAgYmVlbiByZWFkIGJlZm9yZSB0aGUgZW5kIG9mIHRoZSBzdHJlYW0gaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyByZWFkZXIgaXMgY2xvc2VkIG9yIGFub3RoZXIgSU9FeGNlcHRpb24gb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgcmVhZExpbmUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGlmIChsYXN0V2FzQ1IpIHsKKyAgICAgICAgICAgICAgICBjaG9tcE5ld2xpbmUoKTsKKyAgICAgICAgICAgICAgICBsYXN0V2FzQ1IgPSBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSBzdXBlci5yZWFkTGluZSgpOworICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgbGluZU51bWJlcisrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0cyB0aGlzIHJlYWRlciB0byB0aGUgbGFzdCBtYXJrZWQgbG9jYXRpb24uIEl0IGFsc28gcmVzZXRzIHRoZSBsaW5lCisgICAgICogY291bnQgdG8gd2hhdCBpcyB3YXMgd2hlbiB0aGlzIHJlYWRlciB3YXMgbWFya2VkLiBUaGlzIGltcGxlbWVudGF0aW9uCisgICAgICogcmVzZXRzIHRoZSBzb3VyY2UgcmVhZGVyLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgcmVhZGVyIGlzIGFscmVhZHkgY2xvc2VkLCBubyBtYXJrIGhhcyBiZWVuIHNldCBvciB0aGUKKyAgICAgKiAgICAgICAgICAgICBtYXJrIGlzIG5vIGxvbmdlciB2YWxpZCBiZWNhdXNlIG1vcmUgdGhhbiB7QGNvZGUgcmVhZGxpbWl0fQorICAgICAqICAgICAgICAgICAgIGJ5dGVzIGhhdmUgYmVlbiByZWFkIHNpbmNlIHNldHRpbmcgdGhlIG1hcmsuCisgICAgICogQHNlZSAjbWFyayhpbnQpCisgICAgICogQHNlZSAjbWFya1N1cHBvcnRlZCgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIHN1cGVyLnJlc2V0KCk7CisgICAgICAgICAgICBsaW5lTnVtYmVyID0gbWFya2VkTGluZU51bWJlcjsKKyAgICAgICAgICAgIGxhc3RXYXNDUiA9IG1hcmtlZExhc3RXYXNDUjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGxpbmUgbnVtYmVyIG9mIHRoaXMgcmVhZGVyIHRvIHRoZSBzcGVjaWZpZWQge0Bjb2RlIGxpbmVOdW1iZXJ9LgorICAgICAqIE5vdGUgdGhhdCB0aGlzIG1heSBoYXZlIHNpZGUgZWZmZWN0cyBvbiB0aGUgbGluZSBudW1iZXIgYXNzb2NpYXRlZCB3aXRoCisgICAgICogdGhlIGxhc3QgbWFya2VkIHBvc2l0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGxpbmVOdW1iZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgbGluZSBudW1iZXIgdmFsdWUuCisgICAgICogQHNlZSAjbWFyayhpbnQpCisgICAgICogQHNlZSAjcmVzZXQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExpbmVOdW1iZXIoaW50IGxpbmVOdW1iZXIpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICB0aGlzLmxpbmVOdW1iZXIgPSBsaW5lTnVtYmVyOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcHMge0Bjb2RlIGNoYXJDb3VudH0gY2hhcmFjdGVycyBpbiB0aGlzIHJlYWRlci4gU3Vic2VxdWVudCBjYWxscyB0bworICAgICAqIHtAY29kZSByZWFkfSB3aWxsIG5vdCByZXR1cm4gdGhlc2UgY2hhcmFjdGVycyB1bmxlc3Mge0Bjb2RlIHJlc2V0fQorICAgICAqIGlzIHVzZWQuIFRoaXMgaW1wbGVtZW50YXRpb24gc2tpcHMge0Bjb2RlIGNoYXJDb3VudH0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4KKyAgICAgKiB0aGUgc291cmNlIHJlYWRlciBhbmQgaW5jcmVtZW50cyB0aGUgbGluZSBudW1iZXIgY291bnQgd2hlbmV2ZXIgbGluZQorICAgICAqIHRlcm1pbmF0b3Igc2VxdWVuY2VzIGFyZSBza2lwcGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgYWN0dWFsbHkgc2tpcHBlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBjaGFyQ291bnQgPCAwfS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyByZWFkZXIgaXMgY2xvc2VkIG9yIGFub3RoZXIgSU9FeGNlcHRpb24gb2NjdXJzLgorICAgICAqIEBzZWUgI21hcmsoaW50KQorICAgICAqIEBzZWUgI3JlYWQoKQorICAgICAqIEBzZWUgI3Jlc2V0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBza2lwKGxvbmcgY2hhckNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY2hhckNvdW50IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiY2hhckNvdW50IDwgMDogIiArIGNoYXJDb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoYXJDb3VudDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKHJlYWQoKSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gY2hhckNvdW50OworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vTm90QWN0aXZlRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9Ob3RBY3RpdmVFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZTY2MDBkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vTm90QWN0aXZlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCisvKioKKyAqIFNpZ25hbHMgdGhhdCBhIHNlcmlhbGl6YXRpb24tcmVsYXRlZCBtZXRob2QgaGFzIGJlZW4gaW52b2tlZCBpbiB0aGUgd3JvbmcKKyAqIHBsYWNlLiBTb21lIG1ldGhvZHMgaW4ge0Bjb2RlIE9iamVjdElucHV0U3RyZWFtfSBhbmQge0Bjb2RlCisgKiBPYmplY3RPdXRwdXRTdHJlYW19IGNhbiBvbmx5IGJlIGNhbGxlZCBmcm9tIGEgbmVzdGVkIGNhbGwgdG8gcmVhZE9iamVjdCgpIG9yCisgKiB3cml0ZU9iamVjdCgpLiBBbnkgYXR0ZW1wdCB0byBjYWxsIHRoZW0gZnJvbSBhbm90aGVyIGNvbnRleHQgd2lsbCBjYXVzZSBhCisgKiB7QGNvZGUgTm90QWN0aXZlRXhjZXB0aW9ufSB0byBiZSB0aHJvd24uIFRoZSBsaXN0IG9mIG1ldGhvZHMgdGhhdCBhcmUKKyAqIHByb3RlY3RlZCB0aGlzIHdheSBpczoKKyAqIDx1bD4KKyAqIDxsaT57QGxpbmsgT2JqZWN0SW5wdXRTdHJlYW0jZGVmYXVsdFJlYWRPYmplY3QoKX08L2xpPgorICogPGxpPntAbGluayBPYmplY3RJbnB1dFN0cmVhbSNyZWdpc3RlclZhbGlkYXRpb24oT2JqZWN0SW5wdXRWYWxpZGF0aW9uLCBpbnQpfTwvbGk+CisgKiA8bGk+e0BsaW5rIE9iamVjdE91dHB1dFN0cmVhbSNkZWZhdWx0V3JpdGVPYmplY3QoKX08L2xpPgorICogPC91bD4KKyAqLworcHVibGljIGNsYXNzIE5vdEFjdGl2ZUV4Y2VwdGlvbiBleHRlbmRzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzg5MzQ2NzI3MzA0OTgwODg5NUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBOb3RBY3RpdmVFeGNlcHRpb259IHdpdGggaXRzIHN0YWNrIHRyYWNlIGZpbGxlZAorICAgICAqIGluLgorICAgICAqLworICAgIHB1YmxpYyBOb3RBY3RpdmVFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTm90QWN0aXZlRXhjZXB0aW9ufSB3aXRoIGl0cyBzdGFjayB0cmFjZSBhbmQKKyAgICAgKiBkZXRhaWwgbWVzc2FnZSBmaWxsZWQgaW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm90QWN0aXZlRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL05vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDQyZDk4OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL05vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworLyoqCisgKiBTaWduYWxzIHRoYXQgYW4gb2JqZWN0IHRoYXQgaXMgbm90IHNlcmlhbGl6YWJsZSBoYXMgYmVlbiBwYXNzZWQgaW50byB0aGUKKyAqIHtAY29kZSBPYmplY3RPdXRwdXQud3JpdGVPYmplY3QoKX0gbWV0aG9kLiBUaGlzIGNhbiBoYXBwZW4gaWYgdGhlIG9iamVjdAorICogZG9lcyBub3QgaW1wbGVtZW50IHtAY29kZSBTZXJpYWxpemFibGV9IG9yIHtAY29kZSBFeHRlcm5hbGl6YWJsZX0sIG9yIGlmIGl0CisgKiBpcyBzZXJpYWxpemFibGUgYnV0IGl0IG92ZXJyaWRlcyB7QGNvZGUgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtKX0gYW5kCisgKiBleHBsaWNpdGx5IHByZXZlbnRzIHNlcmlhbGl6YXRpb24gYnkgdGhyb3dpbmcgdGhpcyB0eXBlIG9mIGV4Y2VwdGlvbi4KKyAqCisgKiBAc2VlIE9iamVjdE91dHB1dCN3cml0ZU9iamVjdChPYmplY3QpCisgKiBAc2VlIE9iamVjdE91dHB1dFN0cmVhbSN3cml0ZU9iamVjdChPYmplY3QpCisgKi8KK3B1YmxpYyBjbGFzcyBOb3RTZXJpYWxpemFibGVFeGNlcHRpb24gZXh0ZW5kcyBPYmplY3RTdHJlYW1FeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjkwNjY0MjU1NDc5Mzg5MTM4MUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBOb3RTZXJpYWxpemFibGVFeGNlcHRpb259IHdpdGggaXRzIHN0YWNrIHRyYWNlCisgICAgICogZmlsbGVkIGluLgorICAgICAqLworICAgIHB1YmxpYyBOb3RTZXJpYWxpemFibGVFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGxpbmsgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9ufSB3aXRoIGl0cyBzdGFjayB0cmFjZQorICAgICAqIGFuZCBkZXRhaWwgbWVzc2FnZSBmaWxsZWQgaW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL09iamVjdElucHV0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9PYmplY3RJbnB1dC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU4OTIwNzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9PYmplY3RJbnB1dC5qYXZhCkBAIC0wLDAgKzEsMTExIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKKy8qKgorICogRGVmaW5lcyBhbiBpbnRlcmZhY2UgZm9yIGNsYXNzZXMgdGhhdCBhbGxvdyByZWFkaW5nIHNlcmlhbGl6ZWQgb2JqZWN0cy4KKyAqCisgKiBAc2VlIE9iamVjdElucHV0U3RyZWFtCisgKiBAc2VlIE9iamVjdE91dHB1dAorICovCitwdWJsaWMgaW50ZXJmYWNlIE9iamVjdElucHV0IGV4dGVuZHMgRGF0YUlucHV0LCBBdXRvQ2xvc2VhYmxlIHsKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhlIG51bWJlciBvZiBieXRlcyBvZiBwcmltaXRpdmUgZGF0YSB0aGF0IGNhbiBiZSByZWFkIHdpdGhvdXQKKyAgICAgKiBibG9ja2luZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhpcyBzdHJlYW0uIEltcGxlbWVudGF0aW9ucyBvZiB0aGlzIG1ldGhvZCBzaG91bGQgZnJlZSBhbnkKKyAgICAgKiByZXNvdXJjZXMgdXNlZCBieSB0aGUgc3RyZWFtLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgY2xvc2luZyB0aGUgaW5wdXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgYSBzaW5nbGUgYnl0ZSBmcm9tIHRoaXMgc3RyZWFtIGFuZCByZXR1cm5zIGl0IGFzIGFuIGludGVnZXIgaW4gdGhlCisgICAgICogcmFuZ2UgZnJvbSAwIHRvIDI1NS4gUmV0dXJucyAtMSBpZiB0aGUgZW5kIG9mIHRoaXMgc3RyZWFtIGhhcyBiZWVuCisgICAgICogcmVhY2hlZC4gQmxvY2tzIGlmIG5vIGlucHV0IGlzIGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoaXMgc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgc3RyZWFtIGlzIGNsb3NlZCBvciBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgYnl0ZXMgZnJvbSB0aGlzIHN0cmVhbSBpbnRvIHRoZSBieXRlIGFycmF5IHtAY29kZSBidWZmZXJ9LiBCbG9ja3MKKyAgICAgKiB3aGlsZSB3YWl0aW5nIGZvciBpbnB1dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBpbiB3aGljaCB0byBzdG9yZSB0aGUgYnl0ZXMgcmVhZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoaXMgc3RyZWFtIGhhcyBiZWVuCisgICAgICogICAgICAgICByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHN0cmVhbSBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmZmVyKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhdCBtb3N0IHtAY29kZSBjb3VudH0gYnl0ZXMgZnJvbSB0aGlzIHN0cmVhbSBhbmQgc3RvcmVzIHRoZW0gaW4KKyAgICAgKiBieXRlIGFycmF5IHtAY29kZSBidWZmZXJ9IHN0YXJ0aW5nIGF0IG9mZnNldCB7QGNvZGUgY291bnR9LiBCbG9ja3Mgd2hpbGUKKyAgICAgKiB3YWl0aW5nIGZvciBpbnB1dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBpbiB3aGljaCB0byBzdG9yZSB0aGUgYnl0ZXMgcmVhZC4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBwb3NpdGlvbiBpbiB7QGNvZGUgYnVmZmVyfSB0byBzdG9yZSB0aGUgYnl0ZXMgcmVhZAorICAgICAqICAgICAgICAgICAgZnJvbSB0aGlzIHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0byBzdG9yZSBpbiB7QGNvZGUgYnVmZmVyfS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoaXMgc3RyZWFtIGhhcyBiZWVuCisgICAgICogICAgICAgICByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHN0cmVhbSBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSBuZXh0IG9iamVjdCBmcm9tIHRoaXMgc3RyZWFtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgb2JqZWN0IHJlYWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgb2JqZWN0J3MgY2xhc3MgY2Fubm90IGJlIGZvdW5kLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHN0cmVhbSBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgcmVhZE9iamVjdCgpIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNraXBzIHtAY29kZSBieXRlQ291bnR9IGJ5dGVzIG9uIHRoaXMgc3RyZWFtLiBMZXNzIHRoYW4ge0Bjb2RlIGJ5dGVDb3VudH0gYnl0ZSBhcmUKKyAgICAgKiBza2lwcGVkIGlmIHRoZSBlbmQgb2YgdGhpcyBzdHJlYW0gaXMgcmVhY2hlZCBiZWZvcmUgdGhlIG9wZXJhdGlvbgorICAgICAqIGNvbXBsZXRlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSBza2lwcGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHN0cmVhbSBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIHNraXAobG9uZyBieXRlQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL09iamVjdElucHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9PYmplY3RJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQzYWYyNzgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9PYmplY3RJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMjQxMCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCitpbXBvcnQgZGFsdmlrLnN5c3RlbS5WTVN0YWNrOworaW1wb3J0IGphdmEuaW8uRW11bGF0ZWRGaWVsZHMuT2JqZWN0U2xvdDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5BcnJheTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Qcm94eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGxpYmNvcmUudXRpbC5FbXB0eUFycmF5OworCisvKioKKyAqIEEgc3BlY2lhbGl6ZWQge0BsaW5rIElucHV0U3RyZWFtfSB0aGF0IGlzIGFibGUgdG8gcmVhZCAoZGVzZXJpYWxpemUpIEphdmEKKyAqIG9iamVjdHMgYXMgd2VsbCBhcyBwcmltaXRpdmUgZGF0YSB0eXBlcyAoaW50LCBieXRlLCBjaGFyIGV0Yy4pLiBUaGUgZGF0YSBoYXMKKyAqIHR5cGljYWxseSBiZWVuIHNhdmVkIHVzaW5nIGFuIE9iamVjdE91dHB1dFN0cmVhbS4KKyAqCisgKiBAc2VlIE9iamVjdE91dHB1dFN0cmVhbQorICogQHNlZSBPYmplY3RJbnB1dAorICogQHNlZSBTZXJpYWxpemFibGUKKyAqIEBzZWUgRXh0ZXJuYWxpemFibGUKKyAqLworcHVibGljIGNsYXNzIE9iamVjdElucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0gaW1wbGVtZW50cyBPYmplY3RJbnB1dCwgT2JqZWN0U3RyZWFtQ29uc3RhbnRzIHsKKworICAgIC8vIFRPRE86IHRoaXMgaXMgbm9uLXN0YXRpYyB0byBhdm9pZCBzeW5jIGNvbnRlbnRpb24uIFdvdWxkIHN0YXRpYyBiZSBmYXN0ZXI/CisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBlbXB0eVN0cmVhbSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShFbXB0eUFycmF5LkJZVEUpOworCisgICAgLy8gVG8gcHV0IGludG8gb2JqZWN0c1JlYWQgd2hlbiByZWFkaW5nIHVuc2hhcmVkT2JqZWN0CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0IFVOU0hBUkVEX09CSiA9IG5ldyBPYmplY3QoKTsgLy8gJE5PTi1MT0NLLTEkCisKKyAgICAvLyBJZiB0aGUgcmVjZWl2ZXIgaGFzIGFscmVhZHkgcmVhZCAmIG5vdCBjb25zdW1lZCBhIFRDIGNvZGUKKyAgICBwcml2YXRlIGJvb2xlYW4gaGFzUHVzaGJhY2tUQzsKKworICAgIC8vIFB1c2ggYmFjayBUQyBjb2RlIGlmIHRoZSB2YXJpYWJsZSBhYm92ZSBpcyB0cnVlCisgICAgcHJpdmF0ZSBieXRlIHB1c2hiYWNrVEM7CisKKyAgICAvLyBIb3cgbWFueSBuZXN0ZWQgbGV2ZWxzIHRvIHJlYWRPYmplY3QuIFdoZW4gd2UgcmVhY2ggMCB3ZSBoYXZlIHRvIHZhbGlkYXRlCisgICAgLy8gdGhlIGdyYXBoIHRoZW4gcmVzZXQgaXQKKyAgICBwcml2YXRlIGludCBuZXN0ZWRMZXZlbHM7CisKKyAgICAvLyBBbGwgb2JqZWN0cyBhcmUgYXNzaWduZWQgYW4gSUQgKGludGVnZXIgaGFuZGxlKQorICAgIHByaXZhdGUgaW50IG5leHRIYW5kbGU7CisKKyAgICAvLyBXaGVyZSB3ZSByZWFkIGZyb20KKyAgICBwcml2YXRlIERhdGFJbnB1dFN0cmVhbSBpbnB1dDsKKworICAgIC8vIFdoZXJlIHdlIHJlYWQgcHJpbWl0aXZlIHR5cGVzIGZyb20KKyAgICBwcml2YXRlIERhdGFJbnB1dFN0cmVhbSBwcmltaXRpdmVUeXBlczsKKworICAgIC8vIFdoZXJlIHdlIGtlZXAgcHJpbWl0aXZlIHR5cGUgZGF0YQorICAgIHByaXZhdGUgSW5wdXRTdHJlYW0gcHJpbWl0aXZlRGF0YSA9IGVtcHR5U3RyZWFtOworCisgICAgLy8gUmVzb2x2ZSBvYmplY3QgaXMgYSBtZWNoYW5pc20gZm9yIHJlcGxhY2VtZW50CisgICAgcHJpdmF0ZSBib29sZWFuIGVuYWJsZVJlc29sdmU7CisKKyAgICAvKioKKyAgICAgKiBBbGwgdGhlIG9iamVjdHMgd2UndmUgcmVhZCwgaW5kZXhlZCBieSB0aGVpciBzZXJpYWxpemF0aW9uIGhhbmRsZSAobWludXMgdGhlIGJhc2Ugb2Zmc2V0KS4KKyAgICAgKi8KKyAgICBwcml2YXRlIEFycmF5TGlzdDxPYmplY3Q+IG9iamVjdHNSZWFkOworCisgICAgLy8gVXNlZCBieSBkZWZhdWx0UmVhZE9iamVjdAorICAgIHByaXZhdGUgT2JqZWN0IGN1cnJlbnRPYmplY3Q7CisKKyAgICAvLyBVc2VkIGJ5IGRlZmF1bHRSZWFkT2JqZWN0CisgICAgcHJpdmF0ZSBPYmplY3RTdHJlYW1DbGFzcyBjdXJyZW50Q2xhc3M7CisKKyAgICAvLyBBbGwgdmFsaWRhdGlvbnMgdG8gYmUgZXhlY3V0ZWQgd2hlbiB0aGUgY29tcGxldGUgZ3JhcGggaXMgcmVhZC4gU2VlIGlubmVyCisgICAgLy8gdHlwZSBiZWxvdy4KKyAgICBwcml2YXRlIElucHV0VmFsaWRhdGlvbkRlc2NbXSB2YWxpZGF0aW9uczsKKworICAgIC8vIEFsbG93cyB0aGUgcmVjZWl2ZXIgdG8gZGVjaWRlIGlmIGl0IG5lZWRzIHRvIGNhbGwgcmVhZE9iamVjdE92ZXJyaWRlCisgICAgcHJpdmF0ZSBib29sZWFuIHN1YmNsYXNzT3ZlcnJpZGluZ0ltcGxlbWVudGF0aW9uOworCisgICAgLy8gT3JpZ2luYWwgY2FsbGVyJ3MgY2xhc3MgbG9hZGVyLCB1c2VkIHRvIHBlcmZvcm0gY2xhc3MgbG9va3VwcworICAgIHByaXZhdGUgQ2xhc3NMb2FkZXIgY2FsbGVyQ2xhc3NMb2FkZXI7CisKKyAgICAvLyBmYWxzZSB3aGVuIHJlYWRpbmcgbWlzc2luZyBmaWVsZHMKKyAgICBwcml2YXRlIGJvb2xlYW4gbXVzdFJlc29sdmUgPSB0cnVlOworCisgICAgLy8gSGFuZGxlIGZvciB0aGUgY3VycmVudCBjbGFzcyBkZXNjcmlwdG9yCisgICAgcHJpdmF0ZSBpbnQgZGVzY3JpcHRvckhhbmRsZSA9IC0xOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSGFzaE1hcDxTdHJpbmcsIENsYXNzPD8+PiBQUklNSVRJVkVfQ0xBU1NFUyA9IG5ldyBIYXNoTWFwPFN0cmluZywgQ2xhc3M8Pz4+KCk7CisgICAgc3RhdGljIHsKKyAgICAgICAgUFJJTUlUSVZFX0NMQVNTRVMucHV0KCJib29sZWFuIiwgYm9vbGVhbi5jbGFzcyk7CisgICAgICAgIFBSSU1JVElWRV9DTEFTU0VTLnB1dCgiYnl0ZSIsIGJ5dGUuY2xhc3MpOworICAgICAgICBQUklNSVRJVkVfQ0xBU1NFUy5wdXQoImNoYXIiLCBjaGFyLmNsYXNzKTsKKyAgICAgICAgUFJJTUlUSVZFX0NMQVNTRVMucHV0KCJkb3VibGUiLCBkb3VibGUuY2xhc3MpOworICAgICAgICBQUklNSVRJVkVfQ0xBU1NFUy5wdXQoImZsb2F0IiwgZmxvYXQuY2xhc3MpOworICAgICAgICBQUklNSVRJVkVfQ0xBU1NFUy5wdXQoImludCIsIGludC5jbGFzcyk7CisgICAgICAgIFBSSU1JVElWRV9DTEFTU0VTLnB1dCgibG9uZyIsIGxvbmcuY2xhc3MpOworICAgICAgICBQUklNSVRJVkVfQ0xBU1NFUy5wdXQoInNob3J0Iiwgc2hvcnQuY2xhc3MpOworICAgICAgICBQUklNSVRJVkVfQ0xBU1NFUy5wdXQoInZvaWQiLCB2b2lkLmNsYXNzKTsKKyAgICB9CisKKyAgICAvLyBJbnRlcm5hbCB0eXBlIHVzZWQgdG8ga2VlcCB0cmFjayBvZiB2YWxpZGF0b3JzICYgY29ycmVzcG9uZGluZyBwcmlvcml0eQorICAgIHN0YXRpYyBjbGFzcyBJbnB1dFZhbGlkYXRpb25EZXNjIHsKKyAgICAgICAgT2JqZWN0SW5wdXRWYWxpZGF0aW9uIHZhbGlkYXRvcjsKKworICAgICAgICBpbnQgcHJpb3JpdHk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0RmllbGQgaXMgYW4gaW5uZXIgY2xhc3MgdGhhdCBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlIHBlcnNpc3RlbnQgZmllbGRzCisgICAgICogcmVhZCBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBzdGF0aWMgY2xhc3MgR2V0RmllbGQgeworICAgICAgICAvKioKKyAgICAgICAgICogR2V0cyB0aGUgT2JqZWN0U3RyZWFtQ2xhc3MgdGhhdCBkZXNjcmliZXMgYSBmaWVsZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUgZGVzY3JpcHRvciBjbGFzcyBmb3IgYSBzZXJpYWxpemVkIGZpZWxkLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGFic3RyYWN0IE9iamVjdFN0cmVhbUNsYXNzIGdldE9iamVjdFN0cmVhbUNsYXNzKCk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluZGljYXRlcyBpZiB0aGUgZmllbGQgaWRlbnRpZmllZCBieSB7QGNvZGUgbmFtZX0gaXMgZGVmYXVsdGVkLiBUaGlzCisgICAgICAgICAqIG1lYW5zIHRoYXQgaXQgaGFzIG5vIHZhbHVlIGluIHRoaXMgc3RyZWFtLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gbmFtZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBjaGVjay4KKyAgICAgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGZpZWxkIGlzIGRlZmF1bHRlZCwge0Bjb2RlIGZhbHNlfQorICAgICAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG5hbWV9IGRvZXMgbm90IGlkZW50aWZ5IGEgc2VyaWFsaXphYmxlIGZpZWxkLgorICAgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhlIHNvdXJjZSBpbnB1dAorICAgICAgICAgKiAgICAgICAgICAgICBzdHJlYW0uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBkZWZhdWx0ZWQoU3RyaW5nIG5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBib29sZWFuIGZpZWxkIGlkZW50aWZpZWQgYnkge0Bjb2RlIG5hbWV9IGZyb20KKyAgICAgICAgICogdGhlIHBlcnNpc3RlbnQgZmllbGQuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBuYW1lCisgICAgICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGdldC4KKyAgICAgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBkZWZhdWx0IHZhbHVlIHRoYXQgaXMgdXNlZCBpZiB0aGUgZmllbGQgZG9lcyBub3QgaGF2ZQorICAgICAgICAgKiAgICAgICAgICAgIGEgdmFsdWUgd2hlbiByZWFkIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmaWVsZCBpZGVudGlmaWVkIGJ5IHtAY29kZSBuYW1lfS4KKyAgICAgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzb3VyY2UgaW5wdXQKKyAgICAgICAgICogICAgICAgICAgICAgc3RyZWFtLgorICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiB0aGUgdHlwZSBvZiB0aGUgZmllbGQgaWRlbnRpZmllZCBieSB7QGNvZGUgbmFtZX0gaXMKKyAgICAgICAgICogICAgICAgICAgICAgbm90IHtAY29kZSBib29sZWFufS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGdldChTdHJpbmcgbmFtZSwgYm9vbGVhbiBkZWZhdWx0VmFsdWUpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBjaGFyYWN0ZXIgZmllbGQgaWRlbnRpZmllZCBieSB7QGNvZGUgbmFtZX0gZnJvbQorICAgICAgICAgKiB0aGUgcGVyc2lzdGVudCBmaWVsZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG5hbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZmllbGQgdG8gZ2V0LgorICAgICAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgdmFsdWUgdGhhdCBpcyB1c2VkIGlmIHRoZSBmaWVsZCBkb2VzIG5vdCBoYXZlCisgICAgICAgICAqICAgICAgICAgICAgYSB2YWx1ZSB3aGVuIHJlYWQgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkIGlkZW50aWZpZWQgYnkge0Bjb2RlIG5hbWV9LgorICAgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhlIHNvdXJjZSBpbnB1dAorICAgICAgICAgKiAgICAgICAgICAgICBzdHJlYW0uCisgICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIHRoZSB0eXBlIG9mIHRoZSBmaWVsZCBpZGVudGlmaWVkIGJ5IHtAY29kZSBuYW1lfSBpcworICAgICAgICAgKiAgICAgICAgICAgICBub3Qge0Bjb2RlIGNoYXJ9LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGFic3RyYWN0IGNoYXIgZ2V0KFN0cmluZyBuYW1lLCBjaGFyIGRlZmF1bHRWYWx1ZSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjsKKworICAgICAgICAvKioKKyAgICAgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgdGhlIGJ5dGUgZmllbGQgaWRlbnRpZmllZCBieSB7QGNvZGUgbmFtZX0gZnJvbSB0aGUKKyAgICAgICAgICogcGVyc2lzdGVudCBmaWVsZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG5hbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZmllbGQgdG8gZ2V0LgorICAgICAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgdmFsdWUgdGhhdCBpcyB1c2VkIGlmIHRoZSBmaWVsZCBkb2VzIG5vdCBoYXZlCisgICAgICAgICAqICAgICAgICAgICAgYSB2YWx1ZSB3aGVuIHJlYWQgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkIGlkZW50aWZpZWQgYnkge0Bjb2RlIG5hbWV9LgorICAgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhlIHNvdXJjZSBpbnB1dAorICAgICAgICAgKiAgICAgICAgICAgICBzdHJlYW0uCisgICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIHRoZSB0eXBlIG9mIHRoZSBmaWVsZCBpZGVudGlmaWVkIGJ5IHtAY29kZSBuYW1lfSBpcworICAgICAgICAgKiAgICAgICAgICAgICBub3Qge0Bjb2RlIGJ5dGV9LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGFic3RyYWN0IGJ5dGUgZ2V0KFN0cmluZyBuYW1lLCBieXRlIGRlZmF1bHRWYWx1ZSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjsKKworICAgICAgICAvKioKKyAgICAgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNob3J0IGZpZWxkIGlkZW50aWZpZWQgYnkge0Bjb2RlIG5hbWV9IGZyb20gdGhlCisgICAgICAgICAqIHBlcnNpc3RlbnQgZmllbGQuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBuYW1lCisgICAgICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGdldC4KKyAgICAgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBkZWZhdWx0IHZhbHVlIHRoYXQgaXMgdXNlZCBpZiB0aGUgZmllbGQgZG9lcyBub3QgaGF2ZQorICAgICAgICAgKiAgICAgICAgICAgIGEgdmFsdWUgd2hlbiByZWFkIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmaWVsZCBpZGVudGlmaWVkIGJ5IHtAY29kZSBuYW1lfS4KKyAgICAgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzb3VyY2UgaW5wdXQKKyAgICAgICAgICogICAgICAgICAgICAgc3RyZWFtLgorICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiB0aGUgdHlwZSBvZiB0aGUgZmllbGQgaWRlbnRpZmllZCBieSB7QGNvZGUgbmFtZX0gaXMKKyAgICAgICAgICogICAgICAgICAgICAgbm90IHtAY29kZSBzaG9ydH0uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgc2hvcnQgZ2V0KFN0cmluZyBuYW1lLCBzaG9ydCBkZWZhdWx0VmFsdWUpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBpbnRlZ2VyIGZpZWxkIGlkZW50aWZpZWQgYnkge0Bjb2RlIG5hbWV9IGZyb20KKyAgICAgICAgICogdGhlIHBlcnNpc3RlbnQgZmllbGQuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBuYW1lCisgICAgICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGdldC4KKyAgICAgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBkZWZhdWx0IHZhbHVlIHRoYXQgaXMgdXNlZCBpZiB0aGUgZmllbGQgZG9lcyBub3QgaGF2ZQorICAgICAgICAgKiAgICAgICAgICAgIGEgdmFsdWUgd2hlbiByZWFkIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmaWVsZCBpZGVudGlmaWVkIGJ5IHtAY29kZSBuYW1lfS4KKyAgICAgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzb3VyY2UgaW5wdXQKKyAgICAgICAgICogICAgICAgICAgICAgc3RyZWFtLgorICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiB0aGUgdHlwZSBvZiB0aGUgZmllbGQgaWRlbnRpZmllZCBieSB7QGNvZGUgbmFtZX0gaXMKKyAgICAgICAgICogICAgICAgICAgICAgbm90IHtAY29kZSBpbnR9LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGFic3RyYWN0IGludCBnZXQoU3RyaW5nIG5hbWUsIGludCBkZWZhdWx0VmFsdWUpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBsb25nIGZpZWxkIGlkZW50aWZpZWQgYnkge0Bjb2RlIG5hbWV9IGZyb20gdGhlCisgICAgICAgICAqIHBlcnNpc3RlbnQgZmllbGQuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBuYW1lCisgICAgICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGdldC4KKyAgICAgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBkZWZhdWx0IHZhbHVlIHRoYXQgaXMgdXNlZCBpZiB0aGUgZmllbGQgZG9lcyBub3QgaGF2ZQorICAgICAgICAgKiAgICAgICAgICAgIGEgdmFsdWUgd2hlbiByZWFkIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmaWVsZCBpZGVudGlmaWVkIGJ5IHtAY29kZSBuYW1lfS4KKyAgICAgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzb3VyY2UgaW5wdXQKKyAgICAgICAgICogICAgICAgICAgICAgc3RyZWFtLgorICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiB0aGUgdHlwZSBvZiB0aGUgZmllbGQgaWRlbnRpZmllZCBieSB7QGNvZGUgbmFtZX0gaXMKKyAgICAgICAgICogICAgICAgICAgICAgbm90IHtAY29kZSBsb25nfS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBhYnN0cmFjdCBsb25nIGdldChTdHJpbmcgbmFtZSwgbG9uZyBkZWZhdWx0VmFsdWUpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBmbG9hdCBmaWVsZCBpZGVudGlmaWVkIGJ5IHtAY29kZSBuYW1lfSBmcm9tIHRoZQorICAgICAgICAgKiBwZXJzaXN0ZW50IGZpZWxkLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gbmFtZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBnZXQuCisgICAgICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZGVmYXVsdCB2YWx1ZSB0aGF0IGlzIHVzZWQgaWYgdGhlIGZpZWxkIGRvZXMgbm90IGhhdmUKKyAgICAgICAgICogICAgICAgICAgICBhIHZhbHVlIHdoZW4gcmVhZCBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQgaWRlbnRpZmllZCBieSB7QGNvZGUgbmFtZX0uCisgICAgICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgZnJvbSB0aGUgc291cmNlIGlucHV0CisgICAgICAgICAqICAgICAgICAgICAgIHN0cmVhbS4KKyAgICAgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYgdGhlIHR5cGUgb2YgdGhlIGZpZWxkIGlkZW50aWZpZWQgYnkge0Bjb2RlIGZsb2F0fSBpcworICAgICAgICAgKiAgICAgICAgICAgICBub3Qge0Bjb2RlIGNoYXJ9LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGFic3RyYWN0IGZsb2F0IGdldChTdHJpbmcgbmFtZSwgZmxvYXQgZGVmYXVsdFZhbHVlKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiB0aGUgZG91YmxlIGZpZWxkIGlkZW50aWZpZWQgYnkge0Bjb2RlIG5hbWV9IGZyb20KKyAgICAgICAgICogdGhlIHBlcnNpc3RlbnQgZmllbGQuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBuYW1lCisgICAgICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGdldC4KKyAgICAgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBkZWZhdWx0IHZhbHVlIHRoYXQgaXMgdXNlZCBpZiB0aGUgZmllbGQgZG9lcyBub3QgaGF2ZQorICAgICAgICAgKiAgICAgICAgICAgIGEgdmFsdWUgd2hlbiByZWFkIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmaWVsZCBpZGVudGlmaWVkIGJ5IHtAY29kZSBuYW1lfS4KKyAgICAgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzb3VyY2UgaW5wdXQKKyAgICAgICAgICogICAgICAgICAgICAgc3RyZWFtLgorICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiB0aGUgdHlwZSBvZiB0aGUgZmllbGQgaWRlbnRpZmllZCBieSB7QGNvZGUgbmFtZX0gaXMKKyAgICAgICAgICogICAgICAgICAgICAgbm90IHtAY29kZSBkb3VibGV9LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGFic3RyYWN0IGRvdWJsZSBnZXQoU3RyaW5nIG5hbWUsIGRvdWJsZSBkZWZhdWx0VmFsdWUpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBvYmplY3QgZmllbGQgaWRlbnRpZmllZCBieSB7QGNvZGUgbmFtZX0gZnJvbQorICAgICAgICAgKiB0aGUgcGVyc2lzdGVudCBmaWVsZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG5hbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZmllbGQgdG8gZ2V0LgorICAgICAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgdmFsdWUgdGhhdCBpcyB1c2VkIGlmIHRoZSBmaWVsZCBkb2VzIG5vdCBoYXZlCisgICAgICAgICAqICAgICAgICAgICAgYSB2YWx1ZSB3aGVuIHJlYWQgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkIGlkZW50aWZpZWQgYnkge0Bjb2RlIG5hbWV9LgorICAgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhlIHNvdXJjZSBpbnB1dAorICAgICAgICAgKiAgICAgICAgICAgICBzdHJlYW0uCisgICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIHRoZSB0eXBlIG9mIHRoZSBmaWVsZCBpZGVudGlmaWVkIGJ5IHtAY29kZSBuYW1lfSBpcworICAgICAgICAgKiAgICAgICAgICAgICBub3Qge0Bjb2RlIE9iamVjdH0uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgYWJzdHJhY3QgT2JqZWN0IGdldChTdHJpbmcgbmFtZSwgT2JqZWN0IGRlZmF1bHRWYWx1ZSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IE9iamVjdElucHV0U3RyZWFtLiBUaGlzIGRlZmF1bHQgY29uc3RydWN0b3IgY2FuIGJlIHVzZWQKKyAgICAgKiBieSBzdWJjbGFzc2VzIHRoYXQgZG8gbm90IHdhbnQgdG8gdXNlIHRoZSBwdWJsaWMgY29uc3RydWN0b3IgaWYgaXQKKyAgICAgKiBhbGxvY2F0ZXMgdW5uZWVkZWQgZGF0YS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hlbiBjcmVhdGluZyB0aGlzIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgT2JqZWN0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBXQVJOSU5HIC0gd2Ugc2hvdWxkIHRocm93IElPRXhjZXB0aW9uIGlmIG5vdCBjYWxsZWQgZnJvbSBhIHN1YmNsYXNzCisgICAgICAgIC8vIGFjY29yZGluZyB0byB0aGUgSmF2YURvYy4gQWRkIHRoZSB0ZXN0LgorICAgICAgICB0aGlzLnN1YmNsYXNzT3ZlcnJpZGluZ0ltcGxlbWVudGF0aW9uID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IE9iamVjdElucHV0U3RyZWFtIHRoYXQgcmVhZHMgZnJvbSB0aGUgSW5wdXRTdHJlYW0KKyAgICAgKiB7QGNvZGUgaW5wdXR9LgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgbm9uLW51bGwgc291cmNlIElucHV0U3RyZWFtIHRvIGZpbHRlciByZWFkcyBvbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgdGhlIHN0cmVhbSBoZWFkZXIuCisgICAgICogQHRocm93cyBTdHJlYW1Db3JydXB0ZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc291cmNlIHN0cmVhbSBkb2VzIG5vdCBjb250YWluIHNlcmlhbGl6ZWQgb2JqZWN0cyB0aGF0CisgICAgICogICAgICAgICAgICAgY2FuIGJlIHJlYWQuCisgICAgICovCisgICAgcHVibGljIE9iamVjdElucHV0U3RyZWFtKElucHV0U3RyZWFtIGlucHV0KSB0aHJvd3MgU3RyZWFtQ29ycnVwdGVkRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMuaW5wdXQgPSAoaW5wdXQgaW5zdGFuY2VvZiBEYXRhSW5wdXRTdHJlYW0pCisgICAgICAgICAgICAgICAgPyAoRGF0YUlucHV0U3RyZWFtKSBpbnB1dCA6IG5ldyBEYXRhSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgICBwcmltaXRpdmVUeXBlcyA9IG5ldyBEYXRhSW5wdXRTdHJlYW0odGhpcyk7CisgICAgICAgIGVuYWJsZVJlc29sdmUgPSBmYWxzZTsKKyAgICAgICAgdGhpcy5zdWJjbGFzc092ZXJyaWRpbmdJbXBsZW1lbnRhdGlvbiA9IGZhbHNlOworICAgICAgICByZXNldFN0YXRlKCk7CisgICAgICAgIG5lc3RlZExldmVscyA9IDA7CisgICAgICAgIC8vIFNvIHJlYWQuLi4oKSBtZXRob2RzIGNhbiBiZSB1c2VkIGJ5CisgICAgICAgIC8vIHN1YmNsYXNzZXMgZHVyaW5nIHJlYWRTdHJlYW1IZWFkZXIoKQorICAgICAgICBwcmltaXRpdmVEYXRhID0gdGhpcy5pbnB1dDsKKyAgICAgICAgLy8gSGFzIHRvIGJlIGRvbmUgaGVyZSBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24KKyAgICAgICAgcmVhZFN0cmVhbUhlYWRlcigpOworICAgICAgICBwcmltaXRpdmVEYXRhID0gZW1wdHlTdHJlYW07CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyByZXR1cm5zIDAgaWYgbmV4dCBkYXRhIGlzIGFuIG9iamVjdCwgb3IgTiBpZiByZWFkaW5nIHByaW1pdGl2ZSB0eXBlcworICAgICAgICBjaGVja1JlYWRQcmltaXRpdmVUeXBlcygpOworICAgICAgICByZXR1cm4gcHJpbWl0aXZlRGF0YS5hdmFpbGFibGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgdG8gaWYgaXQgaXMgb2sgdG8gcmVhZCBwcmltaXRpdmUgdHlwZXMgZnJvbSB0aGlzIHN0cmVhbSBhdAorICAgICAqIHRoaXMgcG9pbnQuIE9uZSBpcyBub3Qgc3VwcG9zZWQgdG8gcmVhZCBwcmltaXRpdmUgdHlwZXMgd2hlbiBhYm91dCB0bworICAgICAqIHJlYWQgYW4gb2JqZWN0LCBmb3IgZXhhbXBsZSwgc28gYW4gZXhjZXB0aW9uIGhhcyB0byBiZSB0aHJvd24uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW55IElPIHByb2JsZW0gb2NjdXJyZWQgd2hlbiB0cnlpbmcgdG8gcmVhZCBwcmltaXRpdmUgdHlwZQorICAgICAqICAgICAgICAgICAgIG9yIGlmIGl0IGlzIGlsbGVnYWwgdG8gcmVhZCBwcmltaXRpdmUgdHlwZXMKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY2hlY2tSZWFkUHJpbWl0aXZlVHlwZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBJZiB3ZSBzdGlsbCBoYXZlIHByaW1pdGl2ZSBkYXRhLCBpdCBpcyBvayB0byByZWFkIHByaW1pdGl2ZSBkYXRhCisgICAgICAgIGlmIChwcmltaXRpdmVEYXRhID09IGlucHV0IHx8IHByaW1pdGl2ZURhdGEuYXZhaWxhYmxlKCkgPiAwKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICAvLyBJZiB3ZSBnb3QgaGVyZSBlaXRoZXIgd2UgaGFkIG5vIFN0cmVhbSBwcmV2aW91c2x5IGNyZWF0ZWQgb3IKKyAgICAgICAgLy8gd2Ugbm8gbG9uZ2VyIGhhdmUgZGF0YSBpbiB0aGF0IG9uZSwgc28gZ2V0IG1vcmUgYnl0ZXMKKyAgICAgICAgZG8geworICAgICAgICAgICAgaW50IG5leHQgPSAwOworICAgICAgICAgICAgaWYgKGhhc1B1c2hiYWNrVEMpIHsKKyAgICAgICAgICAgICAgICBoYXNQdXNoYmFja1RDID0gZmFsc2U7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG5leHQgPSBpbnB1dC5yZWFkKCk7CisgICAgICAgICAgICAgICAgcHVzaGJhY2tUQyA9IChieXRlKSBuZXh0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3dpdGNoIChwdXNoYmFja1RDKSB7CisgICAgICAgICAgICAgICAgY2FzZSBUQ19CTE9DS0RBVEE6CisgICAgICAgICAgICAgICAgICAgIHByaW1pdGl2ZURhdGEgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0ocmVhZEJsb2NrRGF0YSgpKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIGNhc2UgVENfQkxPQ0tEQVRBTE9ORzoKKyAgICAgICAgICAgICAgICAgICAgcHJpbWl0aXZlRGF0YSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShyZWFkQmxvY2tEYXRhTG9uZygpKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIGNhc2UgVENfUkVTRVQ6CisgICAgICAgICAgICAgICAgICAgIHJlc2V0U3RhdGUoKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hiYWNrVEMoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBPbmx5IFRDX1JFU0VUIGZhbGxzIHRocm91Z2gKKyAgICAgICAgfSB3aGlsZSAodHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgc3RyZWFtLiBUaGlzIGltcGxlbWVudGF0aW9uIGNsb3NlcyB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY2xvc2luZyB0aGlzIHN0cmVhbS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlucHV0LmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVmYXVsdCBtZXRob2QgdG8gcmVhZCBvYmplY3RzIGZyb20gdGhpcyBzdHJlYW0uIFNlcmlhbGl6YWJsZSBmaWVsZHMKKyAgICAgKiBkZWZpbmVkIGluIHRoZSBvYmplY3QncyBjbGFzcyBhbmQgc3VwZXJjbGFzc2VzIGFyZSByZWFkIGZyb20gdGhlIHNvdXJjZQorICAgICAqIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QncyBjbGFzcyBjYW5ub3QgYmUgZm91bmQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyB0aGUgb2JqZWN0IGRhdGEuCisgICAgICogQHRocm93cyBOb3RBY3RpdmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGZyb20ge0Bjb2RlIHJlYWRPYmplY3QoKX0uCisgICAgICogQHNlZSBPYmplY3RPdXRwdXRTdHJlYW0jZGVmYXVsdFdyaXRlT2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgZGVmYXVsdFJlYWRPYmplY3QoKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24sCisgICAgICAgICAgICBOb3RBY3RpdmVFeGNlcHRpb24geworICAgICAgICBpZiAoY3VycmVudE9iamVjdCAhPSBudWxsIHx8ICFtdXN0UmVzb2x2ZSkgeworICAgICAgICAgICAgcmVhZEZpZWxkVmFsdWVzKGN1cnJlbnRPYmplY3QsIGN1cnJlbnRDbGFzcyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm90QWN0aXZlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmFibGVzIG9iamVjdCByZXBsYWNlbWVudCBmb3IgdGhpcyBzdHJlYW0uIEJ5IGRlZmF1bHQgdGhpcyBpcyBub3QKKyAgICAgKiBlbmFibGVkLiBPbmx5IHRydXN0ZWQgc3ViY2xhc3NlcyAobG9hZGVkIHdpdGggc3lzdGVtIGNsYXNzIGxvYWRlcikgYXJlCisgICAgICogYWxsb3dlZCB0byBjaGFuZ2UgdGhpcyBzdGF0dXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW5hYmxlCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gdG8gZW5hYmxlIG9iamVjdCByZXBsYWNlbWVudDsge0Bjb2RlIGZhbHNlfSB0bworICAgICAqICAgICAgICAgICAgZGlzYWJsZSBpdC4KKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyBzZXR0aW5nLgorICAgICAqIEBzZWUgI3Jlc29sdmVPYmplY3QKKyAgICAgKiBAc2VlIE9iamVjdE91dHB1dFN0cmVhbSNlbmFibGVSZXBsYWNlT2JqZWN0CisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gZW5hYmxlUmVzb2x2ZU9iamVjdChib29sZWFuIGVuYWJsZSkgeworICAgICAgICBib29sZWFuIG9yaWdpbmFsVmFsdWUgPSBlbmFibGVSZXNvbHZlOworICAgICAgICBlbmFibGVSZXNvbHZlID0gZW5hYmxlOworICAgICAgICByZXR1cm4gb3JpZ2luYWxWYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG5leHQge0Bjb2RlIGludH0gaGFuZGxlIHRvIGJlIHVzZWQgdG8gaW5kaWNhdGUgY3ljbGljCisgICAgICogcmVmZXJlbmNlcyBiZWluZyBsb2FkZWQgZnJvbSB0aGUgc3RyZWFtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBoYW5kbGUgdG8gcmVwcmVzZW50IHRoZSBuZXh0IGN5Y2xpYyByZWZlcmVuY2UKKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBuZXh0SGFuZGxlKCkgeworICAgICAgICByZXR1cm4gbmV4dEhhbmRsZSsrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbmV4dCB0b2tlbiBjb2RlIChUQykgZnJvbSB0aGUgcmVjZWl2ZXIsIHdoaWNoIGluZGljYXRlcyB3aGF0CisgICAgICoga2luZCBvZiBvYmplY3QgZm9sbG93cworICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBUQyBmcm9tIHRoZSByZWNlaXZlcgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFuIElPIGVycm9yIG9jY3VycworICAgICAqCisgICAgICogQHNlZSBPYmplY3RTdHJlYW1Db25zdGFudHMKKyAgICAgKi8KKyAgICBwcml2YXRlIGJ5dGUgbmV4dFRDKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGhhc1B1c2hiYWNrVEMpIHsKKyAgICAgICAgICAgIGhhc1B1c2hiYWNrVEMgPSBmYWxzZTsgLy8gV2UgYXJlIGNvbnN1bWluZyBpdAorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gSnVzdCBpbiBjYXNlIGEgbGF0ZXIgY2FsbCBkZWNpZGVzIHRvIHJlYWxseSBwdXNoIGl0IGJhY2ssCisgICAgICAgICAgICAvLyB3ZSBkb24ndCByZXF1aXJlIHRoZSBjYWxsZXIgdG8gcGFzcyBpdCBhcyBwYXJhbWV0ZXIKKyAgICAgICAgICAgIHB1c2hiYWNrVEMgPSBpbnB1dC5yZWFkQnl0ZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBwdXNoYmFja1RDOworICAgIH0KKworICAgIC8qKgorICAgICAqIFB1c2hlcyBiYWNrIHRoZSBsYXN0IFRDIGNvZGUgcmVhZAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwdXNoYmFja1RDKCkgeworICAgICAgICBoYXNQdXNoYmFja1RDID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHNpbmdsZSBieXRlIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0gYW5kIHJldHVybnMgaXQgYXMgYW4gaW50ZWdlcgorICAgICAqIGluIHRoZSByYW5nZSBmcm9tIDAgdG8gMjU1LiBSZXR1cm5zIC0xIGlmIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSBzdHJlYW0KKyAgICAgKiBoYXMgYmVlbiByZWFjaGVkLiBCbG9ja3MgaWYgbm8gaW5wdXQgaXMgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYnl0ZSByZWFkIG9yIC0xIGlmIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSBzdHJlYW0gaGFzIGJlZW4KKyAgICAgKiAgICAgICAgIHJlYWNoZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhpcyBzdHJlYW0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tSZWFkUHJpbWl0aXZlVHlwZXMoKTsKKyAgICAgICAgcmV0dXJuIHByaW1pdGl2ZURhdGEucmVhZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGF0IG1vc3Qge0Bjb2RlIGxlbmd0aH0gYnl0ZXMgZnJvbSB0aGUgc291cmNlIHN0cmVhbSBhbmQgc3RvcmVzIHRoZW0KKyAgICAgKiBpbiBieXRlIGFycmF5IHtAY29kZSBidWZmZXJ9IHN0YXJ0aW5nIGF0IG9mZnNldCB7QGNvZGUgY291bnR9LiBCbG9ja3MKKyAgICAgKiB1bnRpbCB7QGNvZGUgY291bnR9IGJ5dGVzIGhhdmUgYmVlbiByZWFkLCB0aGUgZW5kIG9mIHRoZSBzb3VyY2Ugc3RyZWFtIGlzCisgICAgICogZGV0ZWN0ZWQgb3IgYW4gZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBpbiB3aGljaCB0byBzdG9yZSB0aGUgYnl0ZXMgcmVhZC4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBwb3NpdGlvbiBpbiB7QGNvZGUgYnVmZmVyfSB0byBzdG9yZSB0aGUgYnl0ZXMKKyAgICAgKiAgICAgICAgICAgIHJlYWQgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgdG8gc3RvcmUgaW4ge0Bjb2RlIGJ1ZmZlcn0uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgc291cmNlIGlucHV0CisgICAgICogICAgICAgICBzdHJlYW0gaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGxlbmd0aCA8IDB9LCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBsZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGJ1ZmZlcn0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhpcyBzdHJlYW0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBidWZmZXJ9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICBpZiAobGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGNoZWNrUmVhZFByaW1pdGl2ZVR5cGVzKCk7CisgICAgICAgIHJldHVybiBwcmltaXRpdmVEYXRhLnJlYWQoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYW5kIHJldHVybnMgYW4gYXJyYXkgb2YgcmF3IGJ5dGVzIHdpdGggcHJpbWl0aXZlIGRhdGEuIFRoZSBhcnJheQorICAgICAqIHdpbGwgaGF2ZSB1cCB0byAyNTUgYnl0ZXMuIFRoZSBwcmltaXRpdmUgZGF0YSB3aWxsIGJlIGluIHRoZSBmb3JtYXQKKyAgICAgKiBkZXNjcmliZWQgYnkge0Bjb2RlIERhdGFPdXRwdXRTdHJlYW19LgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgcHJpbWl0aXZlIGRhdGEgcmVhZCwgYXMgcmF3IGJ5dGVzCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXhjZXB0aW9uIGhhcHBlbmVkIHdoZW4gcmVhZGluZyB0aGUgcHJpbWl0aXZlIGRhdGEuCisgICAgICovCisgICAgcHJpdmF0ZSBieXRlW10gcmVhZEJsb2NrRGF0YSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtpbnB1dC5yZWFkQnl0ZSgpICYgMHhmZl07CisgICAgICAgIGlucHV0LnJlYWRGdWxseShyZXN1bHQpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIHJhdyBieXRlcyB3aXRoIHByaW1pdGl2ZSBkYXRhLiBUaGUgYXJyYXkKKyAgICAgKiB3aWxsIGhhdmUgbW9yZSB0aGFuIDI1NSBieXRlcy4gVGhlIHByaW1pdGl2ZSBkYXRhIHdpbGwgYmUgaW4gdGhlIGZvcm1hdAorICAgICAqIGRlc2NyaWJlZCBieSB7QGNvZGUgRGF0YU91dHB1dFN0cmVhbX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBwcmltaXRpdmUgZGF0YSByZWFkLCBhcyByYXcgYnl0ZXMKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBleGNlcHRpb24gaGFwcGVuZWQgd2hlbiByZWFkaW5nIHRoZSBwcmltaXRpdmUgZGF0YS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSByZWFkQmxvY2tEYXRhTG9uZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtpbnB1dC5yZWFkSW50KCldOworICAgICAgICBpbnB1dC5yZWFkRnVsbHkocmVzdWx0KTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGJvb2xlYW4gZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJvb2xlYW4gdmFsdWUgcmVhZCBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGVuZCBvZiB0aGUgaW5wdXQgaXMgcmVhY2hlZCBiZWZvcmUgdGhlIHJlYWQKKyAgICAgKiAgICAgICAgICAgICByZXF1ZXN0IGNhbiBiZSBzYXRpc2ZpZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVhZEJvb2xlYW4oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcHJpbWl0aXZlVHlwZXMucmVhZEJvb2xlYW4oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGJ5dGUgKDggYml0KSBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYnl0ZSB2YWx1ZSByZWFkIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZW5kIG9mIHRoZSBpbnB1dCBpcyByZWFjaGVkIGJlZm9yZSB0aGUgcmVhZAorICAgICAqICAgICAgICAgICAgIHJlcXVlc3QgY2FuIGJlIHNhdGlzZmllZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZSByZWFkQnl0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBwcmltaXRpdmVUeXBlcy5yZWFkQnl0ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgY2hhcmFjdGVyICgxNiBiaXQpIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFyIHZhbHVlIHJlYWQgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmQgb2YgdGhlIGlucHV0IGlzIHJlYWNoZWQgYmVmb3JlIHRoZSByZWFkCisgICAgICogICAgICAgICAgICAgcmVxdWVzdCBjYW4gYmUgc2F0aXNmaWVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyBjaGFyIHJlYWRDaGFyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHByaW1pdGl2ZVR5cGVzLnJlYWRDaGFyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYW5kIGRpc2NhcmRzIGJsb2NrIGRhdGEgYW5kIG9iamVjdHMgdW50aWwgVENfRU5EQkxPQ0tEQVRBIGlzIGZvdW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFuIElPIGV4Y2VwdGlvbiBoYXBwZW5lZCB3aGVuIHJlYWRpbmcgdGhlIG9wdGlvbmFsIGNsYXNzCisgICAgICogICAgICAgICAgICAgYW5ub3RhdGlvbi4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiB0aGUgY2xhc3MgY29ycmVzcG9uZGluZyB0byB0aGUgY2xhc3MgZGVzY3JpcHRvciBjb3VsZCBub3QKKyAgICAgKiAgICAgICAgICAgICBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZGlzY2FyZERhdGEoKSB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBwcmltaXRpdmVEYXRhID0gZW1wdHlTdHJlYW07CisgICAgICAgIGJvb2xlYW4gcmVzb2x2ZSA9IG11c3RSZXNvbHZlOworICAgICAgICBtdXN0UmVzb2x2ZSA9IGZhbHNlOworICAgICAgICBkbyB7CisgICAgICAgICAgICBieXRlIHRjID0gbmV4dFRDKCk7CisgICAgICAgICAgICBpZiAodGMgPT0gVENfRU5EQkxPQ0tEQVRBKSB7CisgICAgICAgICAgICAgICAgbXVzdFJlc29sdmUgPSByZXNvbHZlOworICAgICAgICAgICAgICAgIHJldHVybjsgLy8gRW5kIG9mIGFubm90YXRpb24KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlYWRDb250ZW50KHRjKTsKKyAgICAgICAgfSB3aGlsZSAodHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBjbGFzcyBkZXNjcmlwdG9yIChhbiB7QGNvZGUgT2JqZWN0U3RyZWFtQ2xhc3N9KSBmcm9tIHRoZQorICAgICAqIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNsYXNzIGRlc2NyaXB0b3IgcmVhZCBmcm9tIHRoZSBzdHJlYW0KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBleGNlcHRpb24gaGFwcGVuZWQgd2hlbiByZWFkaW5nIHRoZSBjbGFzcworICAgICAqICAgICAgICAgICAgIGRlc2NyaXB0b3IuCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgdGhlIGNsYXNzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGNsYXNzIGRlc2NyaXB0b3IgY291bGQgbm90CisgICAgICogICAgICAgICAgICAgYmUgZm91bmQuCisgICAgICovCisgICAgcHJpdmF0ZSBPYmplY3RTdHJlYW1DbGFzcyByZWFkQ2xhc3NEZXNjKCkgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZSB0YyA9IG5leHRUQygpOworICAgICAgICBzd2l0Y2ggKHRjKSB7CisgICAgICAgICAgICBjYXNlIFRDX0NMQVNTREVTQzoKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVhZE5ld0NsYXNzRGVzYyhmYWxzZSk7CisgICAgICAgICAgICBjYXNlIFRDX1BST1hZQ0xBU1NERVNDOgorICAgICAgICAgICAgICAgIENsYXNzPD8+IHByb3h5Q2xhc3MgPSByZWFkTmV3UHJveHlDbGFzc0Rlc2MoKTsKKyAgICAgICAgICAgICAgICBPYmplY3RTdHJlYW1DbGFzcyBzdHJlYW1DbGFzcyA9IE9iamVjdFN0cmVhbUNsYXNzLmxvb2t1cChwcm94eUNsYXNzKTsKKyAgICAgICAgICAgICAgICBzdHJlYW1DbGFzcy5zZXRMb2FkRmllbGRzKE9iamVjdFN0cmVhbUNsYXNzLk5PX0ZJRUxEUyk7CisgICAgICAgICAgICAgICAgcmVnaXN0ZXJPYmplY3RSZWFkKHN0cmVhbUNsYXNzLCBuZXh0SGFuZGxlKCksIGZhbHNlKTsKKyAgICAgICAgICAgICAgICBjaGVja2VkU2V0U3VwZXJDbGFzc0Rlc2Moc3RyZWFtQ2xhc3MsIHJlYWRDbGFzc0Rlc2MoKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN0cmVhbUNsYXNzOworICAgICAgICAgICAgY2FzZSBUQ19SRUZFUkVOQ0U6CisgICAgICAgICAgICAgICAgcmV0dXJuIChPYmplY3RTdHJlYW1DbGFzcykgcmVhZEN5Y2xpY1JlZmVyZW5jZSgpOworICAgICAgICAgICAgY2FzZSBUQ19OVUxMOgorICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICB0aHJvdyBjb3JydXB0U3RyZWFtKHRjKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgU3RyZWFtQ29ycnVwdGVkRXhjZXB0aW9uIGNvcnJ1cHRTdHJlYW0oYnl0ZSB0YykgdGhyb3dzIFN0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBTdHJlYW1Db3JydXB0ZWRFeGNlcHRpb24oIldyb25nIGZvcm1hdDogIiArIEludGVnZXIudG9IZXhTdHJpbmcodGMgJiAweGZmKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIGNvbnRlbnQgb2YgdGhlIHJlY2VpdmVyIGJhc2VkIG9uIHRoZSBwcmV2aW91c2x5IHJlYWQgdG9rZW4KKyAgICAgKiB7QGNvZGUgdGN9LgorICAgICAqCisgICAgICogQHBhcmFtIHRjCisgICAgICogICAgICAgICAgICBUaGUgdG9rZW4gY29kZSBmb3IgdGhlIG5leHQgaXRlbSBpbiB0aGUgc3RyZWFtCisgICAgICogQHJldHVybiB0aGUgb2JqZWN0IHJlYWQgZnJvbSB0aGUgc3RyZWFtCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXhjZXB0aW9uIGhhcHBlbmVkIHdoZW4gcmVhZGluZyB0aGUgY2xhc3MKKyAgICAgKiAgICAgICAgICAgICBkZXNjcmlwdG9yLgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIHRoZSBjbGFzcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBvYmplY3QgYmVpbmcgcmVhZCBjb3VsZCBub3QKKyAgICAgKiAgICAgICAgICAgICBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIE9iamVjdCByZWFkQ29udGVudChieXRlIHRjKSB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwKKyAgICAgICAgICAgIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3dpdGNoICh0YykgeworICAgICAgICAgICAgY2FzZSBUQ19CTE9DS0RBVEE6CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWRCbG9ja0RhdGEoKTsKKyAgICAgICAgICAgIGNhc2UgVENfQkxPQ0tEQVRBTE9ORzoKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVhZEJsb2NrRGF0YUxvbmcoKTsKKyAgICAgICAgICAgIGNhc2UgVENfQ0xBU1M6CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWROZXdDbGFzcyhmYWxzZSk7CisgICAgICAgICAgICBjYXNlIFRDX0NMQVNTREVTQzoKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVhZE5ld0NsYXNzRGVzYyhmYWxzZSk7CisgICAgICAgICAgICBjYXNlIFRDX0FSUkFZOgorICAgICAgICAgICAgICAgIHJldHVybiByZWFkTmV3QXJyYXkoZmFsc2UpOworICAgICAgICAgICAgY2FzZSBUQ19PQkpFQ1Q6CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWROZXdPYmplY3QoZmFsc2UpOworICAgICAgICAgICAgY2FzZSBUQ19TVFJJTkc6CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWROZXdTdHJpbmcoZmFsc2UpOworICAgICAgICAgICAgY2FzZSBUQ19MT05HU1RSSU5HOgorICAgICAgICAgICAgICAgIHJldHVybiByZWFkTmV3TG9uZ1N0cmluZyhmYWxzZSk7CisgICAgICAgICAgICBjYXNlIFRDX1JFRkVSRU5DRToKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVhZEN5Y2xpY1JlZmVyZW5jZSgpOworICAgICAgICAgICAgY2FzZSBUQ19OVUxMOgorICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgY2FzZSBUQ19FWENFUFRJT046CisgICAgICAgICAgICAgICAgRXhjZXB0aW9uIGV4YyA9IHJlYWRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgV3JpdGVBYm9ydGVkRXhjZXB0aW9uKCJSZWFkIGFuIGV4Y2VwdGlvbiIsIGV4Yyk7CisgICAgICAgICAgICBjYXNlIFRDX1JFU0VUOgorICAgICAgICAgICAgICAgIHJlc2V0U3RhdGUoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgdGhyb3cgY29ycnVwdFN0cmVhbSh0Yyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB0aGUgY29udGVudCBvZiB0aGUgcmVjZWl2ZXIgYmFzZWQgb24gdGhlIHByZXZpb3VzbHkgcmVhZCB0b2tlbgorICAgICAqIHtAY29kZSB0Y30uIFByaW1pdGl2ZSBkYXRhIGNvbnRlbnQgaXMgY29uc2lkZXJlZCBhbiBlcnJvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1bnNoYXJlZAorICAgICAqICAgICAgICAgICAgcmVhZCB0aGUgb2JqZWN0IHVuc2hhcmVkCisgICAgICogQHJldHVybiB0aGUgb2JqZWN0IHJlYWQgZnJvbSB0aGUgc3RyZWFtCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXhjZXB0aW9uIGhhcHBlbmVkIHdoZW4gcmVhZGluZyB0aGUgY2xhc3MKKyAgICAgKiAgICAgICAgICAgICBkZXNjcmlwdG9yLgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIHRoZSBjbGFzcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBvYmplY3QgYmVpbmcgcmVhZCBjb3VsZCBub3QKKyAgICAgKiAgICAgICAgICAgICBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIE9iamVjdCByZWFkTm9uUHJpbWl0aXZlQ29udGVudChib29sZWFuIHVuc2hhcmVkKQorICAgICAgICAgICAgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tSZWFkUHJpbWl0aXZlVHlwZXMoKTsKKyAgICAgICAgaWYgKHByaW1pdGl2ZURhdGEuYXZhaWxhYmxlKCkgPiAwKSB7CisgICAgICAgICAgICBPcHRpb25hbERhdGFFeGNlcHRpb24gZSA9IG5ldyBPcHRpb25hbERhdGFFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGUubGVuZ3RoID0gcHJpbWl0aXZlRGF0YS5hdmFpbGFibGUoKTsKKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0KKworICAgICAgICBkbyB7CisgICAgICAgICAgICBieXRlIHRjID0gbmV4dFRDKCk7CisgICAgICAgICAgICBzd2l0Y2ggKHRjKSB7CisgICAgICAgICAgICAgICAgY2FzZSBUQ19DTEFTUzoKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWROZXdDbGFzcyh1bnNoYXJlZCk7CisgICAgICAgICAgICAgICAgY2FzZSBUQ19DTEFTU0RFU0M6CisgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWFkTmV3Q2xhc3NEZXNjKHVuc2hhcmVkKTsKKyAgICAgICAgICAgICAgICBjYXNlIFRDX0FSUkFZOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVhZE5ld0FycmF5KHVuc2hhcmVkKTsKKyAgICAgICAgICAgICAgICBjYXNlIFRDX09CSkVDVDoKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWROZXdPYmplY3QodW5zaGFyZWQpOworICAgICAgICAgICAgICAgIGNhc2UgVENfU1RSSU5HOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVhZE5ld1N0cmluZyh1bnNoYXJlZCk7CisgICAgICAgICAgICAgICAgY2FzZSBUQ19MT05HU1RSSU5HOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVhZE5ld0xvbmdTdHJpbmcodW5zaGFyZWQpOworICAgICAgICAgICAgICAgIGNhc2UgVENfRU5VTToKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWRFbnVtKHVuc2hhcmVkKTsKKyAgICAgICAgICAgICAgICBjYXNlIFRDX1JFRkVSRU5DRToKKyAgICAgICAgICAgICAgICAgICAgaWYgKHVuc2hhcmVkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZWFkTmV3SGFuZGxlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9iamVjdEV4Y2VwdGlvbigiVW5zaGFyZWQgcmVhZCBvZiBiYWNrIHJlZmVyZW5jZSIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWFkQ3ljbGljUmVmZXJlbmNlKCk7CisgICAgICAgICAgICAgICAgY2FzZSBUQ19OVUxMOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICBjYXNlIFRDX0VYQ0VQVElPTjoKKyAgICAgICAgICAgICAgICAgICAgRXhjZXB0aW9uIGV4YyA9IHJlYWRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFdyaXRlQWJvcnRlZEV4Y2VwdGlvbigiUmVhZCBhbiBleGNlcHRpb24iLCBleGMpOworICAgICAgICAgICAgICAgIGNhc2UgVENfUkVTRVQ6CisgICAgICAgICAgICAgICAgICAgIHJlc2V0U3RhdGUoKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBUQ19FTkRCTE9DS0RBVEE6IC8vIENhbiBvY2N1ciByZWFkaW5nIGNsYXNzIGFubm90YXRpb24KKyAgICAgICAgICAgICAgICAgICAgcHVzaGJhY2tUQygpOworICAgICAgICAgICAgICAgICAgICBPcHRpb25hbERhdGFFeGNlcHRpb24gZSA9IG5ldyBPcHRpb25hbERhdGFFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgZS5lb2YgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgIHRocm93IGNvcnJ1cHRTdHJlYW0odGMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gT25seSBUQ19SRVNFVCBmYWxscyB0aHJvdWdoCisgICAgICAgIH0gd2hpbGUgKHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSBuZXh0IGl0ZW0gZnJvbSB0aGUgc3RyZWFtIGFzc3VtaW5nIGl0IGlzIGEgY3ljbGljIHJlZmVyZW5jZSB0bworICAgICAqIGFuIG9iamVjdCBwcmV2aW91c2x5IHJlYWQuIFJldHVybiB0aGUgYWN0dWFsIG9iamVjdCBwcmV2aW91c2x5IHJlYWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBvYmplY3QgcHJldmlvdXNseSByZWFkIGZyb20gdGhlIHN0cmVhbQorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFuIElPIGV4Y2VwdGlvbiBoYXBwZW5lZCB3aGVuIHJlYWRpbmcgdGhlIGNsYXNzCisgICAgICogICAgICAgICAgICAgZGVzY3JpcHRvci4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRPYmplY3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiB0aGUgY3ljbGljIHJlZmVyZW5jZSBpcyBub3QgdmFsaWQuCisgICAgICovCisgICAgcHJpdmF0ZSBPYmplY3QgcmVhZEN5Y2xpY1JlZmVyZW5jZSgpIHRocm93cyBJbnZhbGlkT2JqZWN0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByZWdpc3RlcmVkT2JqZWN0UmVhZChyZWFkTmV3SGFuZGxlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgZG91YmxlICg2NCBiaXQpIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkb3VibGUgdmFsdWUgcmVhZCBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGVuZCBvZiB0aGUgaW5wdXQgaXMgcmVhY2hlZCBiZWZvcmUgdGhlIHJlYWQKKyAgICAgKiAgICAgICAgICAgICByZXF1ZXN0IGNhbiBiZSBzYXRpc2ZpZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSByZWFkRG91YmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHByaW1pdGl2ZVR5cGVzLnJlYWREb3VibGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIHRoZSBuZXh0IGl0ZW0gYXNzdW1pbmcgaXQgaXMgYW4gZXhjZXB0aW9uLiBUaGUgZXhjZXB0aW9uIGlzIG5vdCBhCisgICAgICogcmVndWxhciBpbnN0YW5jZSBpbiB0aGUgb2JqZWN0IGdyYXBoLCBidXQgdGhlIGV4Y2VwdGlvbiBpbnN0YW5jZSB0aGF0CisgICAgICogaGFwcGVuZWQgKGlmIGFueSkgd2hlbiBkdW1waW5nIHRoZSBvcmlnaW5hbCBvYmplY3QgZ3JhcGguIFRoZSBzZXQgb2Ygc2VlbgorICAgICAqIG9iamVjdHMgd2lsbCBiZSByZXNldCBqdXN0IGJlZm9yZSBhbmQganVzdCBhZnRlciBsb2FkaW5nIHRoaXMgZXhjZXB0aW9uCisgICAgICogb2JqZWN0LgorICAgICAqIDxwPgorICAgICAqIFdoZW4gZXhjZXB0aW9ucyBhcmUgZm91bmQgbm9ybWFsbHkgaW4gdGhlIG9iamVjdCBncmFwaCwgdGhleSBhcmUgbG9hZGVkCisgICAgICogYXMgYSByZWd1bGFyIG9iamVjdCwgYW5kIG5vdCBieSB0aGlzIG1ldGhvZC4gSW4gdGhhdCBjYXNlLCB0aGUgc2V0IG9mCisgICAgICogImtub3duIG9iamVjdHMiIGlzIG5vdCByZXNldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGV4Y2VwdGlvbiByZWFkCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXhjZXB0aW9uIGhhcHBlbmVkIHdoZW4gcmVhZGluZyB0aGUgZXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgb2JqZWN0LgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGEgY2xhc3MgY291bGQgbm90IGJlIGZvdW5kIHdoZW4gcmVhZGluZyB0aGUgb2JqZWN0IGdyYXBoCisgICAgICogICAgICAgICAgICAgZm9yIHRoZSBleGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIE9wdGlvbmFsRGF0YUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIG9wdGlvbmFsIGRhdGEgY291bGQgbm90IGJlIGZvdW5kIHdoZW4gcmVhZGluZyB0aGUKKyAgICAgKiAgICAgICAgICAgICBleGNlcHRpb24gZ3JhcGgKKyAgICAgKiBAdGhyb3dzIFdyaXRlQWJvcnRlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFub3RoZXIgZXhjZXB0aW9uIHdhcyBjYXVzZWQgd2hlbiBkdW1waW5nIHRoaXMgZXhjZXB0aW9uCisgICAgICovCisgICAgcHJpdmF0ZSBFeGNlcHRpb24gcmVhZEV4Y2VwdGlvbigpIHRocm93cyBXcml0ZUFib3J0ZWRFeGNlcHRpb24sCisgICAgICAgICAgICBPcHRpb25hbERhdGFFeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKworICAgICAgICByZXNldFNlZW5PYmplY3RzKCk7CisKKyAgICAgICAgLy8gTm93IHdlIHJlYWQgdGhlIFRocm93YWJsZSBvYmplY3QgdGhhdCB3YXMgc2F2ZWQKKyAgICAgICAgLy8gV0FSTklORyAtIHRoZSBncmFtbWFyIHNheXMgaXQgaXMgYSBUaHJvd2FibGUsIGJ1dCB0aGUKKyAgICAgICAgLy8gV3JpdGVBYm9ydGVkRXhjZXB0aW9uIGNvbnN0cnVjdG9yIHRha2VzIGFuIEV4Y2VwdGlvbi4gU28sIHdlIHJlYWQgYW4KKyAgICAgICAgLy8gRXhjZXB0aW9uIGZyb20gdGhlIHN0cmVhbQorICAgICAgICBFeGNlcHRpb24gZXhjID0gKEV4Y2VwdGlvbikgcmVhZE9iamVjdCgpOworCisgICAgICAgIC8vIFdlIHJlc2V0IHRoZSByZWNlaXZlcidzIHN0YXRlICh0aGUgZ3JhbW1hciBoYXMgInJlc2V0IiBpbiBub3JtYWwKKyAgICAgICAgLy8gZm9udCkKKyAgICAgICAgcmVzZXRTZWVuT2JqZWN0cygpOworICAgICAgICByZXR1cm4gZXhjOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgY29sbGVjdGlvbiBvZiBmaWVsZCBkZXNjcmlwdG9ycyAobmFtZSwgdHlwZSBuYW1lLCBldGMpIGZvciB0aGUKKyAgICAgKiBjbGFzcyBkZXNjcmlwdG9yIHtAY29kZSBjRGVzY30gKGFuIHtAY29kZSBPYmplY3RTdHJlYW1DbGFzc30pCisgICAgICoKKyAgICAgKiBAcGFyYW0gY0Rlc2MKKyAgICAgKiAgICAgICAgICAgIFRoZSBjbGFzcyBkZXNjcmlwdG9yIChhbiB7QGNvZGUgT2JqZWN0U3RyZWFtQ2xhc3N9KQorICAgICAqICAgICAgICAgICAgZm9yIHdoaWNoIHRvIHdyaXRlIGZpZWxkIGluZm9ybWF0aW9uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXhjZXB0aW9uIGhhcHBlbmVkIHdoZW4gcmVhZGluZyB0aGUgZmllbGQKKyAgICAgKiAgICAgICAgICAgICBkZXNjcmlwdG9ycy4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhIGNsYXNzIGZvciBvbmUgb2YgdGhlIGZpZWxkIHR5cGVzIGNvdWxkIG5vdCBiZSBmb3VuZAorICAgICAqCisgICAgICogQHNlZSAjcmVhZE9iamVjdCgpCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRGaWVsZERlc2NyaXB0b3JzKE9iamVjdFN0cmVhbUNsYXNzIGNEZXNjKQorICAgICAgICAgICAgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc2hvcnQgbnVtRmllbGRzID0gaW5wdXQucmVhZFNob3J0KCk7CisgICAgICAgIE9iamVjdFN0cmVhbUZpZWxkW10gZmllbGRzID0gbmV3IE9iamVjdFN0cmVhbUZpZWxkW251bUZpZWxkc107CisKKyAgICAgICAgLy8gV2Ugc2V0IGl0IG5vdywgYnV0IGVhY2ggZWxlbWVudCB3aWxsIGJlIGluc2VydGVkIGluIHRoZSBhcnJheSBmdXJ0aGVyCisgICAgICAgIC8vIGRvd24KKyAgICAgICAgY0Rlc2Muc2V0TG9hZEZpZWxkcyhmaWVsZHMpOworCisgICAgICAgIC8vIENoZWNrIE9iamVjdE91dHB1dFN0cmVhbS53cml0ZUZpZWxkRGVzY3JpcHRvcnMKKyAgICAgICAgZm9yIChzaG9ydCBpID0gMDsgaSA8IG51bUZpZWxkczsgaSsrKSB7CisgICAgICAgICAgICBjaGFyIHR5cGVjb2RlID0gKGNoYXIpIGlucHV0LnJlYWRCeXRlKCk7CisgICAgICAgICAgICBTdHJpbmcgZmllbGROYW1lID0gaW5wdXQucmVhZFVURigpOworICAgICAgICAgICAgYm9vbGVhbiBpc1ByaW1UeXBlID0gT2JqZWN0U3RyZWFtQ2xhc3MuaXNQcmltaXRpdmVUeXBlKHR5cGVjb2RlKTsKKyAgICAgICAgICAgIFN0cmluZyBjbGFzc1NpZzsKKyAgICAgICAgICAgIGlmIChpc1ByaW1UeXBlKSB7CisgICAgICAgICAgICAgICAgY2xhc3NTaWcgPSBTdHJpbmcudmFsdWVPZih0eXBlY29kZSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIFRoZSBzcGVjIHNheXMgaXQgaXMgYSBVVEYsIGJ1dCBleHBlcmllbmNlIHNob3dzIHRoZXkgZHVtcAorICAgICAgICAgICAgICAgIC8vIHRoaXMgU3RyaW5nIHVzaW5nIHdyaXRlT2JqZWN0ICh1bmxpa2UgdGhlIGZpZWxkIG5hbWUsIHdoaWNoCisgICAgICAgICAgICAgICAgLy8gaXMgc2F2ZWQgd2l0aCB3cml0ZVVURikuCisgICAgICAgICAgICAgICAgLy8gQW5kIGlmIHJlc29sdmVPYmplY3QgaXMgZW5hYmxlZCwgdGhlIGNsYXNzU2lnIG1heSBiZSBtb2RpZmllZAorICAgICAgICAgICAgICAgIC8vIHNvIHRoYXQgdGhlIG9yaWdpbmFsIGNsYXNzIGRlc2NyaXB0b3IgY2Fubm90IGJlIHJlYWQKKyAgICAgICAgICAgICAgICAvLyBwcm9wZXJseSwgc28gaXQgaXMgZGlzYWJsZWQuCisgICAgICAgICAgICAgICAgYm9vbGVhbiBvbGQgPSBlbmFibGVSZXNvbHZlOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGVuYWJsZVJlc29sdmUgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgY2xhc3NTaWcgPSAoU3RyaW5nKSByZWFkT2JqZWN0KCk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgZW5hYmxlUmVzb2x2ZSA9IG9sZDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNsYXNzU2lnID0gZm9ybWF0Q2xhc3NTaWcoY2xhc3NTaWcpOworICAgICAgICAgICAgT2JqZWN0U3RyZWFtRmllbGQgZiA9IG5ldyBPYmplY3RTdHJlYW1GaWVsZChjbGFzc1NpZywgZmllbGROYW1lKTsKKyAgICAgICAgICAgIGZpZWxkc1tpXSA9IGY7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIEZvcm1hdCB0aGUgY2xhc3Mgc2lnbmF0dXJlIGZvciBPYmplY3RTdHJlYW1GaWVsZCwgZm9yIGV4YW1wbGUsCisgICAgICogIltMW0xqYXZhLmxhbmcuU3RyaW5nOzsiIGlzIGNvbnZlcnRlZCB0byAiW0xqYXZhLmxhbmcuU3RyaW5nOyIKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZm9ybWF0Q2xhc3NTaWcoU3RyaW5nIGNsYXNzU2lnKSB7CisgICAgICAgIGludCBzdGFydCA9IDA7CisgICAgICAgIGludCBlbmQgPSBjbGFzc1NpZy5sZW5ndGgoKTsKKworICAgICAgICBpZiAoZW5kIDw9IDApIHsKKyAgICAgICAgICAgIHJldHVybiBjbGFzc1NpZzsKKyAgICAgICAgfQorCisgICAgICAgIHdoaWxlIChjbGFzc1NpZy5zdGFydHNXaXRoKCJbTCIsIHN0YXJ0KQorICAgICAgICAgICAgICAgICYmIGNsYXNzU2lnLmNoYXJBdChlbmQgLSAxKSA9PSAnOycpIHsKKyAgICAgICAgICAgIHN0YXJ0ICs9IDI7CisgICAgICAgICAgICBlbmQtLTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzdGFydCA+IDApIHsKKyAgICAgICAgICAgIHN0YXJ0IC09IDI7CisgICAgICAgICAgICBlbmQrKzsKKyAgICAgICAgICAgIHJldHVybiBjbGFzc1NpZy5zdWJzdHJpbmcoc3RhcnQsIGVuZCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNsYXNzU2lnOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSBwZXJzaXN0ZW50IGZpZWxkcyBvZiB0aGUgb2JqZWN0IHRoYXQgaXMgY3VycmVudGx5IGJlaW5nIHJlYWQKKyAgICAgKiBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLiBUaGUgdmFsdWVzIHJlYWQgYXJlIHN0b3JlZCBpbiBhIEdldEZpZWxkIG9iamVjdAorICAgICAqIHRoYXQgcHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBwZXJzaXN0ZW50IGZpZWxkcy4gVGhpcyBHZXRGaWVsZCBvYmplY3QgaXMKKyAgICAgKiB0aGVuIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgR2V0RmllbGQgb2JqZWN0IGZyb20gd2hpY2ggcGVyc2lzdGVudCBmaWVsZHMgY2FuIGJlIGFjY2Vzc2VkCisgICAgICogICAgICAgICBieSBuYW1lLgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjbGFzcyBvZiBhbiBvYmplY3QgYmVpbmcgZGVzZXJpYWxpemVkIGNhbiBub3QgYmUKKyAgICAgKiAgICAgICAgICAgICBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgZnJvbSB0aGlzIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIE5vdEFjdGl2ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgc3RyZWFtIGlzIGN1cnJlbnRseSBub3QgcmVhZGluZyBhbiBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIEdldEZpZWxkIHJlYWRGaWVsZHMoKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIE5vdEFjdGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjdXJyZW50T2JqZWN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb3RBY3RpdmVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBFbXVsYXRlZEZpZWxkc0ZvckxvYWRpbmcgcmVzdWx0ID0gbmV3IEVtdWxhdGVkRmllbGRzRm9yTG9hZGluZyhjdXJyZW50Q2xhc3MpOworICAgICAgICByZWFkRmllbGRWYWx1ZXMocmVzdWx0KTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGNvbGxlY3Rpb24gb2YgZmllbGQgdmFsdWVzIGZvciB0aGUgZW11bGF0ZWQgZmllbGRzCisgICAgICoge0Bjb2RlIGVtdWxhdGVkRmllbGRzfQorICAgICAqCisgICAgICogQHBhcmFtIGVtdWxhdGVkRmllbGRzCisgICAgICogICAgICAgICAgICBhbiB7QGNvZGUgRW11bGF0ZWRGaWVsZHNGb3JMb2FkaW5nfSwgY29uY3JldGUgc3ViY2xhc3MKKyAgICAgKiAgICAgICAgICAgIG9mIHtAY29kZSBHZXRGaWVsZH0KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBleGNlcHRpb24gaGFwcGVuZWQgd2hlbiByZWFkaW5nIHRoZSBmaWVsZCB2YWx1ZXMuCisgICAgICogQHRocm93cyBJbnZhbGlkQ2xhc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBpbmNvbXBhdGlibGUgdHlwZSBpcyBiZWluZyBhc3NpZ25lZCB0byBhbiBlbXVsYXRlZAorICAgICAqICAgICAgICAgICAgIGZpZWxkLgorICAgICAqIEB0aHJvd3MgT3B0aW9uYWxEYXRhRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgb3B0aW9uYWwgZGF0YSBjb3VsZCBub3QgYmUgZm91bmQgd2hlbiByZWFkaW5nIHRoZQorICAgICAqICAgICAgICAgICAgIGV4Y2VwdGlvbiBncmFwaAorICAgICAqCisgICAgICogQHNlZSAjcmVhZEZpZWxkcworICAgICAqIEBzZWUgI3JlYWRPYmplY3QoKQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkRmllbGRWYWx1ZXMoRW11bGF0ZWRGaWVsZHNGb3JMb2FkaW5nIGVtdWxhdGVkRmllbGRzKQorICAgICAgICAgICAgdGhyb3dzIE9wdGlvbmFsRGF0YUV4Y2VwdGlvbiwgSW52YWxpZENsYXNzRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEVtdWxhdGVkRmllbGRzLk9iamVjdFNsb3RbXSBzbG90cyA9IGVtdWxhdGVkRmllbGRzLmVtdWxhdGVkRmllbGRzKCkuc2xvdHMoKTsKKyAgICAgICAgZm9yIChPYmplY3RTbG90IGVsZW1lbnQgOiBzbG90cykgeworICAgICAgICAgICAgZWxlbWVudC5kZWZhdWx0ZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIENsYXNzPD8+IHR5cGUgPSBlbGVtZW50LmZpZWxkLmdldFR5cGUoKTsKKyAgICAgICAgICAgIGlmICh0eXBlID09IGludC5jbGFzcykgeworICAgICAgICAgICAgICAgIGVsZW1lbnQuZmllbGRWYWx1ZSA9IGlucHV0LnJlYWRJbnQoKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBieXRlLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgZWxlbWVudC5maWVsZFZhbHVlID0gaW5wdXQucmVhZEJ5dGUoKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBjaGFyLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgZWxlbWVudC5maWVsZFZhbHVlID0gaW5wdXQucmVhZENoYXIoKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBzaG9ydC5jbGFzcykgeworICAgICAgICAgICAgICAgIGVsZW1lbnQuZmllbGRWYWx1ZSA9IGlucHV0LnJlYWRTaG9ydCgpOworICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGJvb2xlYW4uY2xhc3MpIHsKKyAgICAgICAgICAgICAgICBlbGVtZW50LmZpZWxkVmFsdWUgPSBpbnB1dC5yZWFkQm9vbGVhbigpOworICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGxvbmcuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICBlbGVtZW50LmZpZWxkVmFsdWUgPSBpbnB1dC5yZWFkTG9uZygpOworICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGZsb2F0LmNsYXNzKSB7CisgICAgICAgICAgICAgICAgZWxlbWVudC5maWVsZFZhbHVlID0gaW5wdXQucmVhZEZsb2F0KCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gZG91YmxlLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgZWxlbWVudC5maWVsZFZhbHVlID0gaW5wdXQucmVhZERvdWJsZSgpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBFaXRoZXIgYXJyYXkgb3IgT2JqZWN0CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5maWVsZFZhbHVlID0gcmVhZE9iamVjdCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gY25mKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFdBUk5JTkctIE5vdCBzdXJlIHRoaXMgaXMgdGhlIHJpZ2h0IHRoaW5nIHRvIGRvLiBXcml0ZQorICAgICAgICAgICAgICAgICAgICAvLyB0ZXN0IGNhc2UuCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQ2xhc3NFeGNlcHRpb24oY25mLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgY29sbGVjdGlvbiBvZiBmaWVsZCB2YWx1ZXMgZm9yIHRoZSBjbGFzcyBkZXNjcmlwdG9yCisgICAgICoge0Bjb2RlIGNsYXNzRGVzY30gKGFuIHtAY29kZSBPYmplY3RTdHJlYW1DbGFzc30pLiBUaGUKKyAgICAgKiB2YWx1ZXMgd2lsbCBiZSB1c2VkIHRvIHNldCBpbnN0YW5jZSBmaWVsZHMgaW4gb2JqZWN0IHtAY29kZSBvYmp9LgorICAgICAqIFRoaXMgaXMgdGhlIGRlZmF1bHQgbWVjaGFuaXNtLCB3aGVuIGVtdWxhdGVkIGZpZWxkcyAoYW4KKyAgICAgKiB7QGNvZGUgR2V0RmllbGR9KSBhcmUgbm90IHVzZWQuIEFjdHVhbCB2YWx1ZXMgdG8gbG9hZCBhcmUgc3RvcmVkCisgICAgICogZGlyZWN0bHkgaW50byB0aGUgb2JqZWN0IHtAY29kZSBvYmp9LgorICAgICAqCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgSW5zdGFuY2UgaW4gd2hpY2ggdGhlIGZpZWxkcyB3aWxsIGJlIHNldC4KKyAgICAgKiBAcGFyYW0gY2xhc3NEZXNjCisgICAgICogICAgICAgICAgICBBIGNsYXNzIGRlc2NyaXB0b3IgKGFuIHtAY29kZSBPYmplY3RTdHJlYW1DbGFzc30pCisgICAgICogICAgICAgICAgICBkZWZpbmluZyB3aGljaCBmaWVsZHMgc2hvdWxkIGJlIGxvYWRlZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBleGNlcHRpb24gaGFwcGVuZWQgd2hlbiByZWFkaW5nIHRoZSBmaWVsZCB2YWx1ZXMuCisgICAgICogQHRocm93cyBJbnZhbGlkQ2xhc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBpbmNvbXBhdGlibGUgdHlwZSBpcyBiZWluZyBhc3NpZ25lZCB0byBhbiBlbXVsYXRlZAorICAgICAqICAgICAgICAgICAgIGZpZWxkLgorICAgICAqIEB0aHJvd3MgT3B0aW9uYWxEYXRhRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgb3B0aW9uYWwgZGF0YSBjb3VsZCBub3QgYmUgZm91bmQgd2hlbiByZWFkaW5nIHRoZQorICAgICAqICAgICAgICAgICAgIGV4Y2VwdGlvbiBncmFwaAorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGEgY2xhc3Mgb2YgYW4gb2JqZWN0IGJlaW5nIGRlLXNlcmlhbGl6ZWQgY2FuIG5vdCBiZSBmb3VuZAorICAgICAqCisgICAgICogQHNlZSAjcmVhZEZpZWxkcworICAgICAqIEBzZWUgI3JlYWRPYmplY3QoKQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkRmllbGRWYWx1ZXMoT2JqZWN0IG9iaiwgT2JqZWN0U3RyZWFtQ2xhc3MgY2xhc3NEZXNjKSB0aHJvd3MgT3B0aW9uYWxEYXRhRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIE5vdyB3ZSBtdXN0IHJlYWQgYWxsIGZpZWxkcyBhbmQgYXNzaWduIHRoZW0gdG8gdGhlIHJlY2VpdmVyCisgICAgICAgIE9iamVjdFN0cmVhbUZpZWxkW10gZmllbGRzID0gY2xhc3NEZXNjLmdldExvYWRGaWVsZHMoKTsKKyAgICAgICAgZmllbGRzID0gKGZpZWxkcyA9PSBudWxsKSA/IE9iamVjdFN0cmVhbUNsYXNzLk5PX0ZJRUxEUyA6IGZpZWxkczsKKyAgICAgICAgQ2xhc3M8Pz4gZGVjbGFyaW5nQ2xhc3MgPSBjbGFzc0Rlc2MuZm9yQ2xhc3MoKTsKKyAgICAgICAgaWYgKGRlY2xhcmluZ0NsYXNzID09IG51bGwgJiYgbXVzdFJlc29sdmUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uKGNsYXNzRGVzYy5nZXROYW1lKCkpOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChPYmplY3RTdHJlYW1GaWVsZCBmaWVsZERlc2MgOiBmaWVsZHMpIHsKKyAgICAgICAgICAgIEZpZWxkIGZpZWxkID0gY2xhc3NEZXNjLmdldFJlZmxlY3Rpb25GaWVsZChmaWVsZERlc2MpOworICAgICAgICAgICAgLy8gV2UgbWF5IG5vdCBoYXZlIGJlZW4gYWJsZSB0byBmaW5kIHRoZSBmaWVsZCwgYnV0IHdlIHN0aWxsIG5lZWQgdG8gcmVhZCB0aGUgdmFsdWUKKyAgICAgICAgICAgIC8vIGFuZCBkbyB0aGUgb3RoZXIgY2hlY2tpbmcsIHNvIHRoZXJlJ3Mgbm8gbnVsbCBjaGVjayBvbiAnZmllbGQnIGhlcmUuCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENsYXNzPD8+IHR5cGUgPSBmaWVsZERlc2MuZ2V0VHlwZUludGVybmFsKCk7CisgICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gYnl0ZS5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICBieXRlIGIgPSBpbnB1dC5yZWFkQnl0ZSgpOworICAgICAgICAgICAgICAgICAgICBpZiAoZmllbGQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQuc2V0Qnl0ZShvYmosIGIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGNoYXIuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgY2hhciBjID0gaW5wdXQucmVhZENoYXIoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZpZWxkICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLnNldENoYXIob2JqLCBjKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBkb3VibGUuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgZG91YmxlIGQgPSBpbnB1dC5yZWFkRG91YmxlKCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC5zZXREb3VibGUob2JqLCBkKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBmbG9hdC5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICBmbG9hdCBmID0gaW5wdXQucmVhZEZsb2F0KCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC5zZXRGbG9hdChvYmosIGYpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGludC5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICBpbnQgaSA9IGlucHV0LnJlYWRJbnQoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZpZWxkICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLnNldEludChvYmosIGkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGxvbmcuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgbG9uZyBqID0gaW5wdXQucmVhZExvbmcoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZpZWxkICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLnNldExvbmcob2JqLCBqKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBzaG9ydC5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICBzaG9ydCBzID0gaW5wdXQucmVhZFNob3J0KCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC5zZXRTaG9ydChvYmosIHMpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGJvb2xlYW4uY2xhc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiB6ID0gaW5wdXQucmVhZEJvb2xlYW4oKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZpZWxkICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLnNldEJvb2xlYW4ob2JqLCB6KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIE9iamVjdCB0b1NldCA9IGZpZWxkRGVzYy5pc1Vuc2hhcmVkKCkgPyByZWFkVW5zaGFyZWQoKSA6IHJlYWRPYmplY3QoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHRvU2V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgZmllbGQgdHlwZSBmcm9tIHRoZSBsb2NhbCBmaWVsZCByYXRoZXIgdGhhbgorICAgICAgICAgICAgICAgICAgICAgICAgLy8gZnJvbSB0aGUgc3RyZWFtJ3Mgc3VwcGxpZWQgZGF0YS4gVGhhdCdzIHRoZSBmaWVsZAorICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2UnbGwgYmUgc2V0dGluZywgc28gdGhhdCdzIHRoZSBvbmUgdGhhdCBuZWVkcyB0byBiZQorICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmFsaWRhdGVkLgorICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGZpZWxkTmFtZSA9IGZpZWxkRGVzYy5nZXROYW1lKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RTdHJlYW1GaWVsZCBsb2NhbEZpZWxkRGVzYyA9IGNsYXNzRGVzYy5nZXRGaWVsZChmaWVsZE5hbWUpOworICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3M8Pz4gZmllbGRUeXBlID0gbG9jYWxGaWVsZERlc2MuZ2V0VHlwZUludGVybmFsKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBDbGFzczw/PiB2YWx1ZVR5cGUgPSB0b1NldC5nZXRDbGFzcygpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmaWVsZFR5cGUuaXNBc3NpZ25hYmxlRnJvbSh2YWx1ZVR5cGUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzQ2FzdEV4Y2VwdGlvbihjbGFzc0Rlc2MuZ2V0TmFtZSgpICsgIi4iICsgZmllbGROYW1lICsgIiAtICIgKyBmaWVsZFR5cGUgKyAiIG5vdCBjb21wYXRpYmxlIHdpdGggIiArIHZhbHVlVHlwZSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmllbGQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLnNldChvYmosIHRvU2V0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAgICAgLy8gT2JqZWN0U3RyZWFtRmllbGQgc2hvdWxkIGhhdmUgY2FsbGVkIHNldEFjY2Vzc2libGUodHJ1ZSkuCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGlhZSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hGaWVsZEVycm9yIGlnbm9yZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgZmxvYXQgKDMyIGJpdCkgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGZsb2F0IHZhbHVlIHJlYWQgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmQgb2YgdGhlIGlucHV0IGlzIHJlYWNoZWQgYmVmb3JlIHRoZSByZWFkCisgICAgICogICAgICAgICAgICAgcmVxdWVzdCBjYW4gYmUgc2F0aXNmaWVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdCByZWFkRmxvYXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcHJpbWl0aXZlVHlwZXMucmVhZEZsb2F0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYnl0ZXMgZnJvbSB0aGUgc291cmNlIHN0cmVhbSBpbnRvIHRoZSBieXRlIGFycmF5IHtAY29kZSBkc3R9LgorICAgICAqIFRoaXMgbWV0aG9kIHdpbGwgYmxvY2sgdW50aWwge0Bjb2RlIGRzdC5sZW5ndGh9IGJ5dGVzIGhhdmUgYmVlbiByZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IGluIHdoaWNoIHRvIHN0b3JlIHRoZSBieXRlcyByZWFkLgorICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGVuZCBvZiB0aGUgaW5wdXQgaXMgcmVhY2hlZCBiZWZvcmUgdGhlIHJlYWQKKyAgICAgKiAgICAgICAgICAgICByZXF1ZXN0IGNhbiBiZSBzYXRpc2ZpZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVhZEZ1bGx5KGJ5dGVbXSBkc3QpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHByaW1pdGl2ZVR5cGVzLnJlYWRGdWxseShkc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHtAY29kZSBieXRlQ291bnR9IGJ5dGVzIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0gaW50byB0aGUgYnl0ZSBhcnJheSB7QGNvZGUgZHN0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGFycmF5IGluIHdoaWNoIHRvIHN0b3JlIHRoZSBieXRlcyByZWFkLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIHBvc2l0aW9uIGluIHtAY29kZSBkc3R9IHRvIHN0b3JlIHRoZSBieXRlcworICAgICAqICAgICAgICAgICAgcmVhZCBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqIEBwYXJhbSBieXRlQ291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZC4KKyAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmQgb2YgdGhlIGlucHV0IGlzIHJlYWNoZWQgYmVmb3JlIHRoZSByZWFkCisgICAgICogICAgICAgICAgICAgcmVxdWVzdCBjYW4gYmUgc2F0aXNmaWVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlYWRGdWxseShieXRlW10gZHN0LCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBwcmltaXRpdmVUeXBlcy5yZWFkRnVsbHkoZHN0LCBvZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2Fsa3MgdGhlIGhpZXJhcmNoeSBvZiBjbGFzc2VzIGRlc2NyaWJlZCBieSBjbGFzcyBkZXNjcmlwdG9yCisgICAgICoge0Bjb2RlIGNsYXNzRGVzY30gYW5kIHJlYWRzIHRoZSBmaWVsZCB2YWx1ZXMgY29ycmVzcG9uZGluZyB0bworICAgICAqIGZpZWxkcyBkZWNsYXJlZCBieSB0aGUgY29ycmVzcG9uZGluZyBjbGFzcyBkZXNjcmlwdG9yLiBUaGUgaW5zdGFuY2UgdG8KKyAgICAgKiBzdG9yZSBmaWVsZCB2YWx1ZXMgaW50byBpcyB7QGNvZGUgb2JqZWN0fS4gSWYgdGhlIGNsYXNzCisgICAgICogKGNvcnJlc3BvbmRpbmcgdG8gY2xhc3MgZGVzY3JpcHRvciB7QGNvZGUgY2xhc3NEZXNjfSkgZGVmaW5lcworICAgICAqIHByaXZhdGUgaW5zdGFuY2UgbWV0aG9kIHtAY29kZSByZWFkT2JqZWN0fSBpdCB3aWxsIGJlIHVzZWQgdG8gbG9hZAorICAgICAqIGZpZWxkIHZhbHVlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIEluc3RhbmNlIGludG8gd2hpY2ggc3RvcmVkIGZpZWxkIHZhbHVlcyBsb2FkZWQuCisgICAgICogQHBhcmFtIGNsYXNzRGVzYworICAgICAqICAgICAgICAgICAgQSBjbGFzcyBkZXNjcmlwdG9yIChhbiB7QGNvZGUgT2JqZWN0U3RyZWFtQ2xhc3N9KQorICAgICAqICAgICAgICAgICAgZGVmaW5pbmcgd2hpY2ggZmllbGRzIHNob3VsZCBiZSBsb2FkZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXhjZXB0aW9uIGhhcHBlbmVkIHdoZW4gcmVhZGluZyB0aGUgZmllbGQgdmFsdWVzIGluCisgICAgICogICAgICAgICAgICAgdGhlIGhpZXJhcmNoeS4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhIGNsYXNzIGZvciBvbmUgb2YgdGhlIGZpZWxkIHR5cGVzIGNvdWxkIG5vdCBiZSBmb3VuZAorICAgICAqIEB0aHJvd3MgTm90QWN0aXZlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYge0Bjb2RlIGRlZmF1bHRSZWFkT2JqZWN0fSBpcyBjYWxsZWQgZnJvbSB0aGUgd3JvbmcKKyAgICAgKiAgICAgICAgICAgICBjb250ZXh0LgorICAgICAqCisgICAgICogQHNlZSAjZGVmYXVsdFJlYWRPYmplY3QKKyAgICAgKiBAc2VlICNyZWFkT2JqZWN0KCkKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZEhpZXJhcmNoeShPYmplY3Qgb2JqZWN0LCBPYmplY3RTdHJlYW1DbGFzcyBjbGFzc0Rlc2MpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIE5vdEFjdGl2ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChvYmplY3QgPT0gbnVsbCAmJiBtdXN0UmVzb2x2ZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vdEFjdGl2ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgTGlzdDxPYmplY3RTdHJlYW1DbGFzcz4gc3RyZWFtQ2xhc3NMaXN0ID0gY2xhc3NEZXNjLmdldEhpZXJhcmNoeSgpOworICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoT2JqZWN0U3RyZWFtQ2xhc3Mgb2JqZWN0U3RyZWFtQ2xhc3MgOiBzdHJlYW1DbGFzc0xpc3QpIHsKKyAgICAgICAgICAgICAgICByZWFkT2JqZWN0Rm9yQ2xhc3MobnVsbCwgb2JqZWN0U3RyZWFtQ2xhc3MpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgTGlzdDxDbGFzczw/Pj4gc3VwZXJjbGFzc2VzID0gY2FjaGVkU3VwZXJjbGFzc2VzLmdldChvYmplY3QuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICBpZiAoc3VwZXJjbGFzc2VzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzdXBlcmNsYXNzZXMgPSBjYWNoZVN1cGVyY2xhc3Nlc0ZvcihvYmplY3QuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGludCBsYXN0SW5kZXggPSAwOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAsIGVuZCA9IHN1cGVyY2xhc3Nlcy5zaXplKCk7IGkgPCBlbmQ7ICsraSkgeworICAgICAgICAgICAgICAgIENsYXNzPD8+IHN1cGVyY2xhc3MgPSBzdXBlcmNsYXNzZXMuZ2V0KGkpOworICAgICAgICAgICAgICAgIGludCBpbmRleCA9IGZpbmRTdHJlYW1TdXBlcmNsYXNzKHN1cGVyY2xhc3MsIHN0cmVhbUNsYXNzTGlzdCwgbGFzdEluZGV4KTsKKyAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVhZE9iamVjdE5vRGF0YShvYmplY3QsIHN1cGVyY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0U3RyZWFtQ2xhc3MubG9va3VwU3RyZWFtQ2xhc3Moc3VwZXJjbGFzcykpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSBsYXN0SW5kZXg7IGogPD0gaW5kZXg7IGorKykgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVhZE9iamVjdEZvckNsYXNzKG9iamVjdCwgc3RyZWFtQ2xhc3NMaXN0LmdldChqKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgbGFzdEluZGV4ID0gaW5kZXggKyAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgSGFzaE1hcDxDbGFzczw/PiwgTGlzdDxDbGFzczw/Pj4+IGNhY2hlZFN1cGVyY2xhc3NlcyA9IG5ldyBIYXNoTWFwPENsYXNzPD8+LCBMaXN0PENsYXNzPD8+Pj4oKTsKKworICAgIHByaXZhdGUgTGlzdDxDbGFzczw/Pj4gY2FjaGVTdXBlcmNsYXNzZXNGb3IoQ2xhc3M8Pz4gYykgeworICAgICAgICBBcnJheUxpc3Q8Q2xhc3M8Pz4+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8Q2xhc3M8Pz4+KCk7CisgICAgICAgIENsYXNzPD8+IG5leHRDbGFzcyA9IGM7CisgICAgICAgIHdoaWxlIChuZXh0Q2xhc3MgIT0gbnVsbCkgeworICAgICAgICAgICAgQ2xhc3M8Pz4gdGVzdENsYXNzID0gbmV4dENsYXNzLmdldFN1cGVyY2xhc3MoKTsKKyAgICAgICAgICAgIGlmICh0ZXN0Q2xhc3MgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQoMCwgbmV4dENsYXNzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG5leHRDbGFzcyA9IHRlc3RDbGFzczsKKyAgICAgICAgfQorICAgICAgICBjYWNoZWRTdXBlcmNsYXNzZXMucHV0KGMsIHJlc3VsdCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgZmluZFN0cmVhbVN1cGVyY2xhc3MoQ2xhc3M8Pz4gY2wsIExpc3Q8T2JqZWN0U3RyZWFtQ2xhc3M+IGNsYXNzTGlzdCwgaW50IGxhc3RJbmRleCkgeworICAgICAgICBmb3IgKGludCBpID0gbGFzdEluZGV4LCBlbmQgPSBjbGFzc0xpc3Quc2l6ZSgpOyBpIDwgZW5kOyBpKyspIHsKKyAgICAgICAgICAgIE9iamVjdFN0cmVhbUNsYXNzIG9iakNsID0gY2xhc3NMaXN0LmdldChpKTsKKyAgICAgICAgICAgIFN0cmluZyBmb3JOYW1lID0gb2JqQ2wuZm9yQ2xhc3MoKS5nZXROYW1lKCk7CisKKyAgICAgICAgICAgIGlmIChvYmpDbC5nZXROYW1lKCkuZXF1YWxzKGZvck5hbWUpKSB7CisgICAgICAgICAgICAgICAgaWYgKGNsLmdldE5hbWUoKS5lcXVhbHMob2JqQ2wuZ2V0TmFtZSgpKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIHRoZXJlIHdhcyBhIGNsYXNzIHJlcGxhY2VtZW50CisgICAgICAgICAgICAgICAgaWYgKGNsLmdldE5hbWUoKS5lcXVhbHMoZm9yTmFtZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdE5vRGF0YShPYmplY3Qgb2JqZWN0LCBDbGFzczw/PiBjbCwgT2JqZWN0U3RyZWFtQ2xhc3MgY2xhc3NEZXNjKQorICAgICAgICAgICAgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghY2xhc3NEZXNjLmlzU2VyaWFsaXphYmxlKCkpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2xhc3NEZXNjLmhhc01ldGhvZFJlYWRPYmplY3ROb0RhdGEoKSl7CisgICAgICAgICAgICBmaW5hbCBNZXRob2QgcmVhZE1ldGhvZCA9IGNsYXNzRGVzYy5nZXRNZXRob2RSZWFkT2JqZWN0Tm9EYXRhKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJlYWRNZXRob2QuaW52b2tlKG9iamVjdCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBUaHJvd2FibGUgZXggPSBlLmdldFRhcmdldEV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIGlmIChleCBpbnN0YW5jZW9mIFJ1bnRpbWVFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pIGV4OworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXggaW5zdGFuY2VvZiBFcnJvcikgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyAoRXJyb3IpIGV4OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aHJvdyAoT2JqZWN0U3RyZWFtRXhjZXB0aW9uKSBleDsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0Rm9yQ2xhc3MoT2JqZWN0IG9iamVjdCwgT2JqZWN0U3RyZWFtQ2xhc3MgY2xhc3NEZXNjKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLCBOb3RBY3RpdmVFeGNlcHRpb24geworICAgICAgICAvLyBIYXZlIHRvIGRvIHRoaXMgYmVmb3JlIGNhbGxpbmcgZGVmYXVsdFJlYWRPYmplY3Qgb3IgYW55dGhpbmcgdGhhdAorICAgICAgICAvLyBjYWxscyBkZWZhdWx0UmVhZE9iamVjdAorICAgICAgICBjdXJyZW50T2JqZWN0ID0gb2JqZWN0OworICAgICAgICBjdXJyZW50Q2xhc3MgPSBjbGFzc0Rlc2M7CisKKyAgICAgICAgYm9vbGVhbiBoYWRXcml0ZU1ldGhvZCA9IChjbGFzc0Rlc2MuZ2V0RmxhZ3MoKSAmIFNDX1dSSVRFX01FVEhPRCkgIT0gMDsKKyAgICAgICAgQ2xhc3M8Pz4gdGFyZ2V0Q2xhc3MgPSBjbGFzc0Rlc2MuZm9yQ2xhc3MoKTsKKworICAgICAgICBmaW5hbCBNZXRob2QgcmVhZE1ldGhvZDsKKyAgICAgICAgaWYgKHRhcmdldENsYXNzID09IG51bGwgfHwgIW11c3RSZXNvbHZlKSB7CisgICAgICAgICAgICByZWFkTWV0aG9kID0gbnVsbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlYWRNZXRob2QgPSBjbGFzc0Rlc2MuZ2V0TWV0aG9kUmVhZE9iamVjdCgpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAocmVhZE1ldGhvZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgLy8gV2UgaGF2ZSB0byBiZSBhYmxlIHRvIGZldGNoIGl0cyB2YWx1ZSwgZXZlbiBpZiBpdCBpcyBwcml2YXRlCisgICAgICAgICAgICAgICAgcmVhZE1ldGhvZC5zZXRBY2Nlc3NpYmxlKHRydWUpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHJlYWRNZXRob2QuaW52b2tlKG9iamVjdCwgdGhpcyk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIFRocm93YWJsZSBleCA9IGUuZ2V0VGFyZ2V0RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChleCBpbnN0YW5jZW9mIENsYXNzTm90Rm91bmRFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IChDbGFzc05vdEZvdW5kRXhjZXB0aW9uKSBleDsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChleCBpbnN0YW5jZW9mIFJ1bnRpbWVFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IChSdW50aW1lRXhjZXB0aW9uKSBleDsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChleCBpbnN0YW5jZW9mIEVycm9yKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAoRXJyb3IpIGV4OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHRocm93IChJT0V4Y2VwdGlvbikgZXg7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkZWZhdWx0UmVhZE9iamVjdCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGhhZFdyaXRlTWV0aG9kKSB7CisgICAgICAgICAgICAgICAgZGlzY2FyZERhdGEoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIC8vIENsZWFudXAsIG5lZWRzIHRvIHJ1biBhbHdheXMgc28gdGhhdCB3ZSBjYW4gbGF0ZXIgZGV0ZWN0IGludmFsaWQKKyAgICAgICAgICAgIC8vIGNhbGxzIHRvIGRlZmF1bHRSZWFkT2JqZWN0CisgICAgICAgICAgICBjdXJyZW50T2JqZWN0ID0gbnVsbDsgLy8gV2UgZGlkIG5vdCBzZXQgdGhpcywgc28gd2UgZG8gbm90IG5lZWQgdG8KKyAgICAgICAgICAgIC8vIGNsZWFuIGl0CisgICAgICAgICAgICBjdXJyZW50Q2xhc3MgPSBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYW4gaW50ZWdlciAoMzIgYml0KSBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaW50ZWdlciB2YWx1ZSByZWFkIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZW5kIG9mIHRoZSBpbnB1dCBpcyByZWFjaGVkIGJlZm9yZSB0aGUgcmVhZAorICAgICAqICAgICAgICAgICAgIHJlcXVlc3QgY2FuIGJlIHNhdGlzZmllZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHJlYWRJbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcHJpbWl0aXZlVHlwZXMucmVhZEludCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSBuZXh0IGxpbmUgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4gTGluZXMgYXJlIHRlcm1pbmF0ZWQgYnkKKyAgICAgKiB7QGNvZGUgJ1xyJ30sIHtAY29kZSAnXG4nfSwge0Bjb2RlICJcclxuIn0gb3IgYW4ge0Bjb2RlIEVPRn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVhZCBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgQnVmZmVyZWRSZWFkZXJ9CisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgU3RyaW5nIHJlYWRMaW5lKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHByaW1pdGl2ZVR5cGVzLnJlYWRMaW5lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBsb25nICg2NCBiaXQpIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsb25nIHZhbHVlIHJlYWQgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmQgb2YgdGhlIGlucHV0IGlzIHJlYWNoZWQgYmVmb3JlIHRoZSByZWFkCisgICAgICogICAgICAgICAgICAgcmVxdWVzdCBjYW4gYmUgc2F0aXNmaWVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIHJlYWRMb25nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHByaW1pdGl2ZVR5cGVzLnJlYWRMb25nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCBhIG5ldyBhcnJheSBmcm9tIHRoZSByZWNlaXZlci4gSXQgaXMgYXNzdW1lZCB0aGUgYXJyYXkgaGFzIG5vdCBiZWVuCisgICAgICogcmVhZCB5ZXQgKG5vdCBhIGN5Y2xpYyByZWZlcmVuY2UpLiBSZXR1cm4gdGhlIGFycmF5IHJlYWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdW5zaGFyZWQKKyAgICAgKiAgICAgICAgICAgIHJlYWQgdGhlIG9iamVjdCB1bnNoYXJlZAorICAgICAqIEByZXR1cm4gdGhlIGFycmF5IHJlYWQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBleGNlcHRpb24gaGFwcGVuZWQgd2hlbiByZWFkaW5nIHRoZSBhcnJheS4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhIGNsYXNzIGZvciBvbmUgb2YgdGhlIG9iamVjdHMgY291bGQgbm90IGJlIGZvdW5kCisgICAgICogQHRocm93cyBPcHRpb25hbERhdGFFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBvcHRpb25hbCBkYXRhIGNvdWxkIG5vdCBiZSBmb3VuZCB3aGVuIHJlYWRpbmcgdGhlIGFycmF5LgorICAgICAqLworICAgIHByaXZhdGUgT2JqZWN0IHJlYWROZXdBcnJheShib29sZWFuIHVuc2hhcmVkKSB0aHJvd3MgT3B0aW9uYWxEYXRhRXhjZXB0aW9uLAorICAgICAgICAgICAgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBPYmplY3RTdHJlYW1DbGFzcyBjbGFzc0Rlc2MgPSByZWFkQ2xhc3NEZXNjKCk7CisKKyAgICAgICAgaWYgKGNsYXNzRGVzYyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBtaXNzaW5nQ2xhc3NEZXNjcmlwdG9yKCk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgbmV3SGFuZGxlID0gbmV4dEhhbmRsZSgpOworCisgICAgICAgIC8vIEFycmF5IHNpemUKKyAgICAgICAgaW50IHNpemUgPSBpbnB1dC5yZWFkSW50KCk7CisgICAgICAgIENsYXNzPD8+IGFycmF5Q2xhc3MgPSBjbGFzc0Rlc2MuZm9yQ2xhc3MoKTsKKyAgICAgICAgQ2xhc3M8Pz4gY29tcG9uZW50VHlwZSA9IGFycmF5Q2xhc3MuZ2V0Q29tcG9uZW50VHlwZSgpOworICAgICAgICBPYmplY3QgcmVzdWx0ID0gQXJyYXkubmV3SW5zdGFuY2UoY29tcG9uZW50VHlwZSwgc2l6ZSk7CisKKyAgICAgICAgcmVnaXN0ZXJPYmplY3RSZWFkKHJlc3VsdCwgbmV3SGFuZGxlLCB1bnNoYXJlZCk7CisKKyAgICAgICAgLy8gTm93IHdlIGhhdmUgY29kZSBkdXBsaWNhdGlvbiBqdXN0IGJlY2F1c2UgSmF2YSBpcyB0eXBlZC4gV2UgaGF2ZSB0bworICAgICAgICAvLyByZWFkIE4gZWxlbWVudHMgYW5kIGFzc2lnbiB0byBhcnJheSBwb3NpdGlvbnMsIGJ1dCB3ZSBtdXN0IHR5cGVjYXN0CisgICAgICAgIC8vIHRoZSBhcnJheSBmaXJzdCwgYW5kIGFsc28gY2FsbCBkaWZmZXJlbnQgbWV0aG9kcyBkZXBlbmRpbmcgb24gdGhlCisgICAgICAgIC8vIGVsZW1lbnRzLgorICAgICAgICBpZiAoY29tcG9uZW50VHlwZS5pc1ByaW1pdGl2ZSgpKSB7CisgICAgICAgICAgICBpZiAoY29tcG9uZW50VHlwZSA9PSBpbnQuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICBpbnRbXSBpbnRBcnJheSA9IChpbnRbXSkgcmVzdWx0OworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGludEFycmF5W2ldID0gaW5wdXQucmVhZEludCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY29tcG9uZW50VHlwZSA9PSBieXRlLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGJ5dGVBcnJheSA9IChieXRlW10pIHJlc3VsdDsKKyAgICAgICAgICAgICAgICBpbnB1dC5yZWFkRnVsbHkoYnl0ZUFycmF5LCAwLCBzaXplKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY29tcG9uZW50VHlwZSA9PSBjaGFyLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgY2hhcltdIGNoYXJBcnJheSA9IChjaGFyW10pIHJlc3VsdDsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBjaGFyQXJyYXlbaV0gPSBpbnB1dC5yZWFkQ2hhcigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY29tcG9uZW50VHlwZSA9PSBzaG9ydC5jbGFzcykgeworICAgICAgICAgICAgICAgIHNob3J0W10gc2hvcnRBcnJheSA9IChzaG9ydFtdKSByZXN1bHQ7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgc2hvcnRBcnJheVtpXSA9IGlucHV0LnJlYWRTaG9ydCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY29tcG9uZW50VHlwZSA9PSBib29sZWFuLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgYm9vbGVhbltdIGJvb2xlYW5BcnJheSA9IChib29sZWFuW10pIHJlc3VsdDsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBib29sZWFuQXJyYXlbaV0gPSBpbnB1dC5yZWFkQm9vbGVhbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY29tcG9uZW50VHlwZSA9PSBsb25nLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgbG9uZ1tdIGxvbmdBcnJheSA9IChsb25nW10pIHJlc3VsdDsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBsb25nQXJyYXlbaV0gPSBpbnB1dC5yZWFkTG9uZygpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY29tcG9uZW50VHlwZSA9PSBmbG9hdC5jbGFzcykgeworICAgICAgICAgICAgICAgIGZsb2F0W10gZmxvYXRBcnJheSA9IChmbG9hdFtdKSByZXN1bHQ7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZmxvYXRBcnJheVtpXSA9IGlucHV0LnJlYWRGbG9hdCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY29tcG9uZW50VHlwZSA9PSBkb3VibGUuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICBkb3VibGVbXSBkb3VibGVBcnJheSA9IChkb3VibGVbXSkgcmVzdWx0OworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGRvdWJsZUFycmF5W2ldID0gaW5wdXQucmVhZERvdWJsZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzTm90Rm91bmRFeGNlcHRpb24oIldyb25nIGJhc2UgdHlwZSBpbiAiICsgY2xhc3NEZXNjLmdldE5hbWUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBBcnJheSBvZiBPYmplY3RzCisgICAgICAgICAgICBPYmplY3RbXSBvYmplY3RBcnJheSA9IChPYmplY3RbXSkgcmVzdWx0OworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICAvLyBUT0RPOiBUaGlzIHBsYWNlIGlzIHRoZSBvcHBvcnR1bml0eSBmb3IgZW5oYW5jZW1lbnQKKyAgICAgICAgICAgICAgICAvLyAgICAgIFdlIGNhbiBpbXBsZW1lbnQgd3JpdGluZyBlbGVtZW50cyB0aHJvdWdoIGZhc3QtcGF0aCwKKyAgICAgICAgICAgICAgICAvLyAgICAgIHdpdGhvdXQgc2V0dGluZyB1cCB0aGUgY29udGV4dCAoc2VlIHJlYWRPYmplY3QoKSkgZm9yCisgICAgICAgICAgICAgICAgLy8gICAgICBlYWNoIGVsZW1lbnQgd2l0aCBwdWJsaWMgQVBJCisgICAgICAgICAgICAgICAgb2JqZWN0QXJyYXlbaV0gPSByZWFkT2JqZWN0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVuYWJsZVJlc29sdmUpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IHJlc29sdmVPYmplY3QocmVzdWx0KTsKKyAgICAgICAgICAgIHJlZ2lzdGVyT2JqZWN0UmVhZChyZXN1bHQsIG5ld0hhbmRsZSwgZmFsc2UpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBuZXcgY2xhc3MgZnJvbSB0aGUgcmVjZWl2ZXIuIEl0IGlzIGFzc3VtZWQgdGhlIGNsYXNzIGhhcyBub3QgYmVlbgorICAgICAqIHJlYWQgeWV0IChub3QgYSBjeWNsaWMgcmVmZXJlbmNlKS4gUmV0dXJuIHRoZSBjbGFzcyByZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIHVuc2hhcmVkCisgICAgICogICAgICAgICAgICByZWFkIHRoZSBvYmplY3QgdW5zaGFyZWQKKyAgICAgKiBAcmV0dXJuIFRoZSB7QGNvZGUgamF2YS5sYW5nLkNsYXNzfSByZWFkIGZyb20gdGhlIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBleGNlcHRpb24gaGFwcGVuZWQgd2hlbiByZWFkaW5nIHRoZSBjbGFzcy4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhIGNsYXNzIGZvciBvbmUgb2YgdGhlIG9iamVjdHMgY291bGQgbm90IGJlIGZvdW5kCisgICAgICovCisgICAgcHJpdmF0ZSBDbGFzczw/PiByZWFkTmV3Q2xhc3MoYm9vbGVhbiB1bnNoYXJlZCkgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0U3RyZWFtQ2xhc3MgY2xhc3NEZXNjID0gcmVhZENsYXNzRGVzYygpOworICAgICAgICBpZiAoY2xhc3NEZXNjID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG1pc3NpbmdDbGFzc0Rlc2NyaXB0b3IoKTsKKyAgICAgICAgfQorICAgICAgICBDbGFzczw/PiBsb2NhbENsYXNzID0gY2xhc3NEZXNjLmZvckNsYXNzKCk7CisgICAgICAgIGlmIChsb2NhbENsYXNzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlZ2lzdGVyT2JqZWN0UmVhZChsb2NhbENsYXNzLCBuZXh0SGFuZGxlKCksIHVuc2hhcmVkKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbG9jYWxDbGFzczsKKyAgICB9CisKKyAgICAvKgorICAgICAqIHJlYWQgY2xhc3MgdHlwZSBmb3IgRW51bSwgbm90ZSB0aGVyZSdzIGRpZmZlcmVuY2UgYmV0d2VlbiBlbnVtIGFuZCBub3JtYWwKKyAgICAgKiBjbGFzc2VzCisgICAgICovCisgICAgcHJpdmF0ZSBPYmplY3RTdHJlYW1DbGFzcyByZWFkRW51bURlc2MoKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgICAgICBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZSB0YyA9IG5leHRUQygpOworICAgICAgICBzd2l0Y2ggKHRjKSB7CisgICAgICAgICAgICBjYXNlIFRDX0NMQVNTREVTQzoKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVhZEVudW1EZXNjSW50ZXJuYWwoKTsKKyAgICAgICAgICAgIGNhc2UgVENfUkVGRVJFTkNFOgorICAgICAgICAgICAgICAgIHJldHVybiAoT2JqZWN0U3RyZWFtQ2xhc3MpIHJlYWRDeWNsaWNSZWZlcmVuY2UoKTsKKyAgICAgICAgICAgIGNhc2UgVENfTlVMTDoKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgdGhyb3cgY29ycnVwdFN0cmVhbSh0Yyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIE9iamVjdFN0cmVhbUNsYXNzIHJlYWRFbnVtRGVzY0ludGVybmFsKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0U3RyZWFtQ2xhc3MgY2xhc3NEZXNjOworICAgICAgICBwcmltaXRpdmVEYXRhID0gaW5wdXQ7CisgICAgICAgIGludCBvbGRIYW5kbGUgPSBkZXNjcmlwdG9ySGFuZGxlOworICAgICAgICBkZXNjcmlwdG9ySGFuZGxlID0gbmV4dEhhbmRsZSgpOworICAgICAgICBjbGFzc0Rlc2MgPSByZWFkQ2xhc3NEZXNjcmlwdG9yKCk7CisgICAgICAgIHJlZ2lzdGVyT2JqZWN0UmVhZChjbGFzc0Rlc2MsIGRlc2NyaXB0b3JIYW5kbGUsIGZhbHNlKTsKKyAgICAgICAgZGVzY3JpcHRvckhhbmRsZSA9IG9sZEhhbmRsZTsKKyAgICAgICAgcHJpbWl0aXZlRGF0YSA9IGVtcHR5U3RyZWFtOworICAgICAgICBjbGFzc0Rlc2Muc2V0Q2xhc3MocmVzb2x2ZUNsYXNzKGNsYXNzRGVzYykpOworICAgICAgICAvLyBDb25zdW1lIHVucmVhZCBjbGFzcyBhbm5vdGF0aW9uIGRhdGEgYW5kIFRDX0VOREJMT0NLREFUQQorICAgICAgICBkaXNjYXJkRGF0YSgpOworICAgICAgICBPYmplY3RTdHJlYW1DbGFzcyBzdXBlckNsYXNzID0gcmVhZENsYXNzRGVzYygpOworICAgICAgICBjaGVja2VkU2V0U3VwZXJDbGFzc0Rlc2MoY2xhc3NEZXNjLCBzdXBlckNsYXNzKTsKKyAgICAgICAgLy8gQ2hlY2sgU1VJRHMsIG5vdGUgYWxsIFNVSUQgZm9yIEVudW0gaXMgMEwKKyAgICAgICAgaWYgKDBMICE9IGNsYXNzRGVzYy5nZXRTZXJpYWxWZXJzaW9uVUlEKCkgfHwgMEwgIT0gc3VwZXJDbGFzcy5nZXRTZXJpYWxWZXJzaW9uVUlEKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQ2xhc3NFeGNlcHRpb24oc3VwZXJDbGFzcy5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICJJbmNvbXBhdGlibGUgY2xhc3MgKFNVSUQpOiAiICsgc3VwZXJDbGFzcyArICIgYnV0IGV4cGVjdGVkICIgKyBzdXBlckNsYXNzKTsKKyAgICAgICAgfQorICAgICAgICBieXRlIHRjID0gbmV4dFRDKCk7CisgICAgICAgIC8vIGRpc2NhcmQgVENfRU5EQkxPQ0tEQVRBIGFmdGVyIGNsYXNzRGVzYyBpZiBhbnkKKyAgICAgICAgaWYgKHRjID09IFRDX0VOREJMT0NLREFUQSkgeworICAgICAgICAgICAgLy8gcmVhZCBuZXh0IHBhcmVudCBjbGFzcy4gRm9yIGVudW0sIGl0IG1heSBiZSBudWxsCisgICAgICAgICAgICBzdXBlckNsYXNzLnNldFN1cGVyY2xhc3MocmVhZENsYXNzRGVzYygpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIG5vdCBUQ19FTkRCTE9DS0RBVEEsIHB1c2ggYmFjayBmb3IgbmV4dCByZWFkCisgICAgICAgICAgICBwdXNoYmFja1RDKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNsYXNzRGVzYzsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikvLyBGb3IgdGhlIEVudW0udmFsdWVPZiBjYWxsCisgICAgcHJpdmF0ZSBPYmplY3QgcmVhZEVudW0oYm9vbGVhbiB1bnNoYXJlZCkgdGhyb3dzIE9wdGlvbmFsRGF0YUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gcmVhZCBjbGFzc2Rlc2MgZm9yIEVudW0gZmlyc3QKKyAgICAgICAgT2JqZWN0U3RyZWFtQ2xhc3MgY2xhc3NEZXNjID0gcmVhZEVudW1EZXNjKCk7CisgICAgICAgIGludCBuZXdIYW5kbGUgPSBuZXh0SGFuZGxlKCk7CisgICAgICAgIC8vIHJlYWQgbmFtZSBhZnRlciBjbGFzcyBkZXNjCisgICAgICAgIFN0cmluZyBuYW1lOworICAgICAgICBieXRlIHRjID0gbmV4dFRDKCk7CisgICAgICAgIHN3aXRjaCAodGMpIHsKKyAgICAgICAgICAgIGNhc2UgVENfUkVGRVJFTkNFOgorICAgICAgICAgICAgICAgIGlmICh1bnNoYXJlZCkgeworICAgICAgICAgICAgICAgICAgICByZWFkTmV3SGFuZGxlKCk7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT2JqZWN0RXhjZXB0aW9uKCJVbnNoYXJlZCByZWFkIG9mIGJhY2sgcmVmZXJlbmNlIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG5hbWUgPSAoU3RyaW5nKSByZWFkQ3ljbGljUmVmZXJlbmNlKCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFRDX1NUUklORzoKKyAgICAgICAgICAgICAgICBuYW1lID0gKFN0cmluZykgcmVhZE5ld1N0cmluZyh1bnNoYXJlZCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIHRocm93IGNvcnJ1cHRTdHJlYW0odGMpOworICAgICAgICB9CisKKyAgICAgICAgRW51bTw/PiByZXN1bHQgPSBFbnVtLnZhbHVlT2YoKENsYXNzKSBjbGFzc0Rlc2MuZm9yQ2xhc3MoKSwgbmFtZSk7CisgICAgICAgIHJlZ2lzdGVyT2JqZWN0UmVhZChyZXN1bHQsIG5ld0hhbmRsZSwgdW5zaGFyZWQpOworCisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBuZXcgY2xhc3MgZGVzY3JpcHRvciBmcm9tIHRoZSByZWNlaXZlci4gSXQgaXMgYXNzdW1lZCB0aGUgY2xhc3MKKyAgICAgKiBkZXNjcmlwdG9yIGhhcyBub3QgYmVlbiByZWFkIHlldCAobm90IGEgY3ljbGljIHJlZmVyZW5jZSkuIFJldHVybiB0aGUKKyAgICAgKiBjbGFzcyBkZXNjcmlwdG9yIHJlYWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdW5zaGFyZWQKKyAgICAgKiAgICAgICAgICAgIHJlYWQgdGhlIG9iamVjdCB1bnNoYXJlZAorICAgICAqIEByZXR1cm4gVGhlIHtAY29kZSBPYmplY3RTdHJlYW1DbGFzc30gcmVhZCBmcm9tIHRoZSBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXhjZXB0aW9uIGhhcHBlbmVkIHdoZW4gcmVhZGluZyB0aGUgY2xhc3MKKyAgICAgKiAgICAgICAgICAgICBkZXNjcmlwdG9yLgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGEgY2xhc3MgZm9yIG9uZSBvZiB0aGUgb2JqZWN0cyBjb3VsZCBub3QgYmUgZm91bmQKKyAgICAgKi8KKyAgICBwcml2YXRlIE9iamVjdFN0cmVhbUNsYXNzIHJlYWROZXdDbGFzc0Rlc2MoYm9vbGVhbiB1bnNoYXJlZCkKKyAgICAgICAgICAgIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFNvIHJlYWQuLi4oKSBtZXRob2RzIGNhbiBiZSB1c2VkIGJ5CisgICAgICAgIC8vIHN1YmNsYXNzZXMgZHVyaW5nIHJlYWRDbGFzc0Rlc2NyaXB0b3IoKQorICAgICAgICBwcmltaXRpdmVEYXRhID0gaW5wdXQ7CisgICAgICAgIGludCBvbGRIYW5kbGUgPSBkZXNjcmlwdG9ySGFuZGxlOworICAgICAgICBkZXNjcmlwdG9ySGFuZGxlID0gbmV4dEhhbmRsZSgpOworICAgICAgICBPYmplY3RTdHJlYW1DbGFzcyBuZXdDbGFzc0Rlc2MgPSByZWFkQ2xhc3NEZXNjcmlwdG9yKCk7CisgICAgICAgIHJlZ2lzdGVyT2JqZWN0UmVhZChuZXdDbGFzc0Rlc2MsIGRlc2NyaXB0b3JIYW5kbGUsIHVuc2hhcmVkKTsKKyAgICAgICAgZGVzY3JpcHRvckhhbmRsZSA9IG9sZEhhbmRsZTsKKyAgICAgICAgcHJpbWl0aXZlRGF0YSA9IGVtcHR5U3RyZWFtOworCisgICAgICAgIC8vIFdlIG5lZWQgdG8gbWFwIGNsYXNzRGVzYyB0byBjbGFzcy4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ld0NsYXNzRGVzYy5zZXRDbGFzcyhyZXNvbHZlQ2xhc3MobmV3Q2xhc3NEZXNjKSk7CisgICAgICAgICAgICAvLyBDaGVjayBTVUlEcyAmIGJhc2UgbmFtZSBvZiB0aGUgY2xhc3MKKyAgICAgICAgICAgIHZlcmlmeUFuZEluaXQobmV3Q2xhc3NEZXNjKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAobXVzdFJlc29sdmUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgIC8vIEp1c3QgY29udGludWUsIHRoZSBjbGFzcyBtYXkgbm90IGJlIHJlcXVpcmVkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBSZXNvbHZlIHRoZSBmaWVsZCBzaWduYXR1cmVzIHVzaW5nIHRoZSBjbGFzcyBsb2FkZXIgb2YgdGhlCisgICAgICAgIC8vIHJlc29sdmVkIGNsYXNzCisgICAgICAgIE9iamVjdFN0cmVhbUZpZWxkW10gZmllbGRzID0gbmV3Q2xhc3NEZXNjLmdldExvYWRGaWVsZHMoKTsKKyAgICAgICAgZmllbGRzID0gKGZpZWxkcyA9PSBudWxsKSA/IE9iamVjdFN0cmVhbUNsYXNzLk5PX0ZJRUxEUyA6IGZpZWxkczsKKyAgICAgICAgQ2xhc3NMb2FkZXIgbG9hZGVyID0gbmV3Q2xhc3NEZXNjLmZvckNsYXNzKCkgPT0gbnVsbCA/IGNhbGxlckNsYXNzTG9hZGVyCisgICAgICAgICAgICAgICAgOiBuZXdDbGFzc0Rlc2MuZm9yQ2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpOworICAgICAgICBmb3IgKE9iamVjdFN0cmVhbUZpZWxkIGVsZW1lbnQgOiBmaWVsZHMpIHsKKyAgICAgICAgICAgIGVsZW1lbnQucmVzb2x2ZShsb2FkZXIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ29uc3VtZSB1bnJlYWQgY2xhc3MgYW5ub3RhdGlvbiBkYXRhIGFuZCBUQ19FTkRCTE9DS0RBVEEKKyAgICAgICAgZGlzY2FyZERhdGEoKTsKKyAgICAgICAgY2hlY2tlZFNldFN1cGVyQ2xhc3NEZXNjKG5ld0NsYXNzRGVzYywgcmVhZENsYXNzRGVzYygpKTsKKyAgICAgICAgcmV0dXJuIG5ld0NsYXNzRGVzYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIG5ldyBwcm94eSBjbGFzcyBkZXNjcmlwdG9yIGZyb20gdGhlIHJlY2VpdmVyLiBJdCBpcyBhc3N1bWVkIHRoZQorICAgICAqIHByb3h5IGNsYXNzIGRlc2NyaXB0b3IgaGFzIG5vdCBiZWVuIHJlYWQgeWV0IChub3QgYSBjeWNsaWMgcmVmZXJlbmNlKS4KKyAgICAgKiBSZXR1cm4gdGhlIHByb3h5IGNsYXNzIGRlc2NyaXB0b3IgcmVhZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIHtAY29kZSBDbGFzc30gcmVhZCBmcm9tIHRoZSBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXhjZXB0aW9uIGhhcHBlbmVkIHdoZW4gcmVhZGluZyB0aGUgY2xhc3MKKyAgICAgKiAgICAgICAgICAgICBkZXNjcmlwdG9yLgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGEgY2xhc3MgZm9yIG9uZSBvZiB0aGUgb2JqZWN0cyBjb3VsZCBub3QgYmUgZm91bmQKKyAgICAgKi8KKyAgICBwcml2YXRlIENsYXNzPD8+IHJlYWROZXdQcm94eUNsYXNzRGVzYygpIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLAorICAgICAgICAgICAgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgY291bnQgPSBpbnB1dC5yZWFkSW50KCk7CisgICAgICAgIFN0cmluZ1tdIGludGVyZmFjZU5hbWVzID0gbmV3IFN0cmluZ1tjb3VudF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgeworICAgICAgICAgICAgaW50ZXJmYWNlTmFtZXNbaV0gPSBpbnB1dC5yZWFkVVRGKCk7CisgICAgICAgIH0KKyAgICAgICAgQ2xhc3M8Pz4gcHJveHkgPSByZXNvbHZlUHJveHlDbGFzcyhpbnRlcmZhY2VOYW1lcyk7CisgICAgICAgIC8vIENvbnN1bWUgdW5yZWFkIGNsYXNzIGFubm90YXRpb24gZGF0YSBhbmQgVENfRU5EQkxPQ0tEQVRBCisgICAgICAgIGRpc2NhcmREYXRhKCk7CisgICAgICAgIHJldHVybiBwcm94eTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGNsYXNzIGRlc2NyaXB0b3IgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNsYXNzIGRlc2NyaXB0b3IgcmVhZCBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgY2xhc3MgZm9yIG9uZSBvZiB0aGUgb2JqZWN0cyBjYW5ub3QgYmUgZm91bmQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICovCisgICAgcHJvdGVjdGVkIE9iamVjdFN0cmVhbUNsYXNzIHJlYWRDbGFzc0Rlc2NyaXB0b3IoKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBPYmplY3RTdHJlYW1DbGFzcyBuZXdDbGFzc0Rlc2MgPSBuZXcgT2JqZWN0U3RyZWFtQ2xhc3MoKTsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBpbnB1dC5yZWFkVVRGKCk7CisgICAgICAgIGlmIChuYW1lLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVGhlIHN0cmVhbSBpcyBjb3JydXB0ZWQiKTsKKyAgICAgICAgfQorICAgICAgICBuZXdDbGFzc0Rlc2Muc2V0TmFtZShuYW1lKTsKKyAgICAgICAgbmV3Q2xhc3NEZXNjLnNldFNlcmlhbFZlcnNpb25VSUQoaW5wdXQucmVhZExvbmcoKSk7CisgICAgICAgIG5ld0NsYXNzRGVzYy5zZXRGbGFncyhpbnB1dC5yZWFkQnl0ZSgpKTsKKworICAgICAgICAvKgorICAgICAgICAgKiBXZSBtdXN0IHJlZ2lzdGVyIHRoZSBjbGFzcyBkZXNjcmlwdG9yIGJlZm9yZSByZWFkaW5nIGZpZWxkCisgICAgICAgICAqIGRlc2NyaXB0b3JzLiBJZiBjYWxsZWQgb3V0c2lkZSBvZiByZWFkT2JqZWN0LCB0aGUgZGVzY3JpcHRvckhhbmRsZQorICAgICAgICAgKiBtaWdodCBiZSB1bnNldC4KKyAgICAgICAgICovCisgICAgICAgIGlmIChkZXNjcmlwdG9ySGFuZGxlID09IC0xKSB7CisgICAgICAgICAgICBkZXNjcmlwdG9ySGFuZGxlID0gbmV4dEhhbmRsZSgpOworICAgICAgICB9CisgICAgICAgIHJlZ2lzdGVyT2JqZWN0UmVhZChuZXdDbGFzc0Rlc2MsIGRlc2NyaXB0b3JIYW5kbGUsIGZhbHNlKTsKKworICAgICAgICByZWFkRmllbGREZXNjcmlwdG9ycyhuZXdDbGFzc0Rlc2MpOworICAgICAgICByZXR1cm4gbmV3Q2xhc3NEZXNjOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIHByb3h5IGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGUgaW50ZXJmYWNlcyBzcGVjaWZpZWQgaW4KKyAgICAgKiB7QGNvZGUgaW50ZXJmYWNlTmFtZXN9LgorICAgICAqCisgICAgICogQHBhcmFtIGludGVyZmFjZU5hbWVzCisgICAgICogICAgICAgICAgICB0aGUgaW50ZXJmYWNlcyB1c2VkIHRvIGNyZWF0ZSB0aGUgcHJveHkgY2xhc3MuCisgICAgICogQHJldHVybiB0aGUgcHJveHkgY2xhc3MuCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHByb3h5IGNsYXNzIG9yIGFueSBvZiB0aGUgc3BlY2lmaWVkIGludGVyZmFjZXMgY2Fubm90CisgICAgICogICAgICAgICAgICAgYmUgY3JlYXRlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKiBAc2VlIE9iamVjdE91dHB1dFN0cmVhbSNhbm5vdGF0ZVByb3h5Q2xhc3MoQ2xhc3MpCisgICAgICovCisgICAgcHJvdGVjdGVkIENsYXNzPD8+IHJlc29sdmVQcm94eUNsYXNzKFN0cmluZ1tdIGludGVyZmFjZU5hbWVzKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVE9ETzogVGhpcyBtZXRob2QgaXMgb3Bwb3J0dW5pdHkgZm9yIHBlcmZvcm1hbmNlIGVuaGFuY2VtZW50CisgICAgICAgIC8vICAgICAgIFdlIGNhbiBjYWNoZSB0aGUgY2xhc3Nsb2FkZXIgYW5kIHJlY2VudGx5IHVzZWQgaW50ZXJmYWNlcy4KKyAgICAgICAgQ2xhc3NMb2FkZXIgbG9hZGVyID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKTsKKyAgICAgICAgQ2xhc3M8Pz5bXSBpbnRlcmZhY2VzID0gbmV3IENsYXNzPD8+W2ludGVyZmFjZU5hbWVzLmxlbmd0aF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW50ZXJmYWNlTmFtZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGludGVyZmFjZXNbaV0gPSBDbGFzcy5mb3JOYW1lKGludGVyZmFjZU5hbWVzW2ldLCBmYWxzZSwgbG9hZGVyKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIFByb3h5LmdldFByb3h5Q2xhc3MobG9hZGVyLCBpbnRlcmZhY2VzKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uKGUudG9TdHJpbmcoKSwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGludCByZWFkTmV3SGFuZGxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGlucHV0LnJlYWRJbnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGEgbmV3IG9iamVjdCBmcm9tIHRoZSBzdHJlYW0uIEl0IGlzIGFzc3VtZWQgdGhlIG9iamVjdCBoYXMgbm90IGJlZW4KKyAgICAgKiBsb2FkZWQgeWV0IChub3QgYSBjeWNsaWMgcmVmZXJlbmNlKS4gUmV0dXJuIHRoZSBvYmplY3QgcmVhZC4KKyAgICAgKgorICAgICAqIElmIHRoZSBvYmplY3QgaW1wbGVtZW50cyA8Y29kZT5FeHRlcm5hbGl6YWJsZTwvY29kZT4gaXRzCisgICAgICogPGNvZGU+cmVhZEV4dGVybmFsPC9jb2RlPiBpcyBjYWxsZWQuIE90aGVyd2lzZSwgYWxsIGZpZWxkcyBkZXNjcmliZWQgYnkKKyAgICAgKiB0aGUgY2xhc3MgaGllcmFyY2h5IGFyZSBsb2FkZWQuIEVhY2ggY2xhc3MgY2FuIGRlZmluZSBob3cgaXRzIGRlY2xhcmVkCisgICAgICogaW5zdGFuY2UgZmllbGRzIGFyZSBsb2FkZWQgYnkgZGVmaW5pbmcgYSBwcml2YXRlIG1ldGhvZAorICAgICAqIDxjb2RlPnJlYWRPYmplY3Q8L2NvZGU+CisgICAgICoKKyAgICAgKiBAcGFyYW0gdW5zaGFyZWQKKyAgICAgKiAgICAgICAgICAgIHJlYWQgdGhlIG9iamVjdCB1bnNoYXJlZAorICAgICAqIEByZXR1cm4gdGhlIG9iamVjdCByZWFkCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXhjZXB0aW9uIGhhcHBlbmVkIHdoZW4gcmVhZGluZyB0aGUgb2JqZWN0LgorICAgICAqIEB0aHJvd3MgT3B0aW9uYWxEYXRhRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgb3B0aW9uYWwgZGF0YSBjb3VsZCBub3QgYmUgZm91bmQgd2hlbiByZWFkaW5nIHRoZSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgICBncmFwaAorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGEgY2xhc3MgZm9yIG9uZSBvZiB0aGUgb2JqZWN0cyBjb3VsZCBub3QgYmUgZm91bmQKKyAgICAgKi8KKyAgICBwcml2YXRlIE9iamVjdCByZWFkTmV3T2JqZWN0KGJvb2xlYW4gdW5zaGFyZWQpCisgICAgICAgICAgICB0aHJvd3MgT3B0aW9uYWxEYXRhRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdFN0cmVhbUNsYXNzIGNsYXNzRGVzYyA9IHJlYWRDbGFzc0Rlc2MoKTsKKworICAgICAgICBpZiAoY2xhc3NEZXNjID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG1pc3NpbmdDbGFzc0Rlc2NyaXB0b3IoKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBuZXdIYW5kbGUgPSBuZXh0SGFuZGxlKCk7CisgICAgICAgIENsYXNzPD8+IG9iamVjdENsYXNzID0gY2xhc3NEZXNjLmZvckNsYXNzKCk7CisgICAgICAgIE9iamVjdCByZXN1bHQgPSBudWxsOworICAgICAgICBPYmplY3QgcmVnaXN0ZXJlZFJlc3VsdCA9IG51bGw7CisgICAgICAgIGlmIChvYmplY3RDbGFzcyAhPSBudWxsKSB7CisgICAgICAgICAgICAvLyBOb3cgd2Uga25vdyB3aGljaCBjbGFzcyB0byBpbnN0YW50aWF0ZSBhbmQgd2hpY2ggY29uc3RydWN0b3IgdG8KKyAgICAgICAgICAgIC8vIHJ1bi4gV2UgYXJlIGFsbG93ZWQgdG8gcnVuIHRoZSBjb25zdHJ1Y3Rvci4KKyAgICAgICAgICAgIHJlc3VsdCA9IGNsYXNzRGVzYy5uZXdJbnN0YW5jZShvYmplY3RDbGFzcyk7CisgICAgICAgICAgICByZWdpc3Rlck9iamVjdFJlYWQocmVzdWx0LCBuZXdIYW5kbGUsIHVuc2hhcmVkKTsKKyAgICAgICAgICAgIHJlZ2lzdGVyZWRSZXN1bHQgPSByZXN1bHQ7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXN1bHQgPSBudWxsOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFRoaXMgaXMgaG93IHdlIGtub3cgd2hhdCB0byBkbyBpbiBkZWZhdWx0UmVhZE9iamVjdC4gQW5kIGl0IGlzCisgICAgICAgICAgICAvLyBhbHNvIHVzZWQgYnkgZGVmYXVsdFJlYWRPYmplY3QgdG8gY2hlY2sgaWYgaXQgd2FzIGNhbGxlZCBmcm9tIGFuCisgICAgICAgICAgICAvLyBpbnZhbGlkIHBsYWNlLiBJdCBhbHNvIGFsbG93cyByZWFkRXh0ZXJuYWwgdG8gY2FsbAorICAgICAgICAgICAgLy8gZGVmYXVsdFJlYWRPYmplY3QgYW5kIGhhdmUgaXQgd29yay4KKyAgICAgICAgICAgIGN1cnJlbnRPYmplY3QgPSByZXN1bHQ7CisgICAgICAgICAgICBjdXJyZW50Q2xhc3MgPSBjbGFzc0Rlc2M7CisKKyAgICAgICAgICAgIC8vIElmIEV4dGVybmFsaXphYmxlLCBqdXN0IGxldCB0aGUgb2JqZWN0IHJlYWQgaXRzZWxmCisgICAgICAgICAgICAvLyBOb3RlIHRoYXQgdGhpcyB2YWx1ZSBjb21lcyBmcm9tIHRoZSBTdHJlYW0sIGFuZCBpbiBmYWN0IGl0IGNvdWxkIGJlCisgICAgICAgICAgICAvLyB0aGF0IHRoZSBjbGFzc2VzIGhhdmUgYmVlbiBjaGFuZ2VkIHNvIHRoYXQgdGhlIGluZm8gYmVsb3cgbm93CisgICAgICAgICAgICAvLyBjb25mbGljdHMgd2l0aCB0aGUgbmV3ZXIgY2xhc3MKKyAgICAgICAgICAgIGJvb2xlYW4gd2FzRXh0ZXJuYWxpemFibGUgPSAoY2xhc3NEZXNjLmdldEZsYWdzKCkgJiBTQ19FWFRFUk5BTElaQUJMRSkgIT0gMDsKKyAgICAgICAgICAgIGlmICh3YXNFeHRlcm5hbGl6YWJsZSkgeworICAgICAgICAgICAgICAgIGJvb2xlYW4gYmxvY2tEYXRhID0gKGNsYXNzRGVzYy5nZXRGbGFncygpICYgU0NfQkxPQ0tfREFUQSkgIT0gMDsKKyAgICAgICAgICAgICAgICBpZiAoIWJsb2NrRGF0YSkgeworICAgICAgICAgICAgICAgICAgICBwcmltaXRpdmVEYXRhID0gaW5wdXQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChtdXN0UmVzb2x2ZSkgeworICAgICAgICAgICAgICAgICAgICBFeHRlcm5hbGl6YWJsZSBleHRlcm4gPSAoRXh0ZXJuYWxpemFibGUpIHJlc3VsdDsKKyAgICAgICAgICAgICAgICAgICAgZXh0ZXJuLnJlYWRFeHRlcm5hbCh0aGlzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGJsb2NrRGF0YSkgeworICAgICAgICAgICAgICAgICAgICAvLyBTaW1pbGFyIHRvIHJlYWRIaWVyYXJjaHkuIEFueXRoaW5nIG5vdCByZWFkIGJ5CisgICAgICAgICAgICAgICAgICAgIC8vIHJlYWRFeHRlcm5hbCBoYXMgdG8gYmUgY29uc3VtZWQgaGVyZQorICAgICAgICAgICAgICAgICAgICBkaXNjYXJkRGF0YSgpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHByaW1pdGl2ZURhdGEgPSBlbXB0eVN0cmVhbTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIElmIHdlIGdvdCBoZXJlLCBpdCBpcyBTZXJpYWxpemFibGUgYnV0IG5vdCBFeHRlcm5hbGl6YWJsZS4KKyAgICAgICAgICAgICAgICAvLyBXYWxrIHRoZSBoaWVyYXJjaHkgcmVhZGluZyBlYWNoIGNsYXNzJyBzbG90cworICAgICAgICAgICAgICAgIHJlYWRIaWVyYXJjaHkocmVzdWx0LCBjbGFzc0Rlc2MpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgLy8gQ2xlYW51cCwgbmVlZHMgdG8gcnVuIGFsd2F5cyBzbyB0aGF0IHdlIGNhbiBsYXRlciBkZXRlY3QgaW52YWxpZAorICAgICAgICAgICAgLy8gY2FsbHMgdG8gZGVmYXVsdFJlYWRPYmplY3QKKyAgICAgICAgICAgIGN1cnJlbnRPYmplY3QgPSBudWxsOworICAgICAgICAgICAgY3VycmVudENsYXNzID0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChvYmplY3RDbGFzcyAhPSBudWxsKSB7CisKKyAgICAgICAgICAgIGlmIChjbGFzc0Rlc2MuaGFzTWV0aG9kUmVhZFJlc29sdmUoKSl7CisgICAgICAgICAgICAgICAgTWV0aG9kIG1ldGhvZFJlYWRSZXNvbHZlID0gY2xhc3NEZXNjLmdldE1ldGhvZFJlYWRSZXNvbHZlKCk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbWV0aG9kUmVhZFJlc29sdmUuaW52b2tlKHJlc3VsdCwgKE9iamVjdFtdKSBudWxsKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGl0ZSkgeworICAgICAgICAgICAgICAgICAgICBUaHJvd2FibGUgdGFyZ2V0ID0gaXRlLmdldFRhcmdldEV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0IGluc3RhbmNlb2YgT2JqZWN0U3RyZWFtRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAoT2JqZWN0U3RyZWFtRXhjZXB0aW9uKSB0YXJnZXQ7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0IGluc3RhbmNlb2YgRXJyb3IpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IChFcnJvcikgdGFyZ2V0OworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pIHRhcmdldDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIFdlIGdldCBoZXJlIGVpdGhlciBpZiBjbGFzcy1iYXNlZCByZXBsYWNlbWVudCB3YXMgbm90IG5lZWRlZCBvciBpZiBpdAorICAgICAgICAvLyB3YXMgbmVlZGVkIGJ1dCBwcm9kdWNlZCB0aGUgc2FtZSBvYmplY3Qgb3IgaWYgaXQgY291bGQgbm90IGJlCisgICAgICAgIC8vIGNvbXB1dGVkLgorCisgICAgICAgIC8vIFRoZSBvYmplY3QgdG8gcmV0dXJuIGlzIHRoZSBvbmUgd2UgaW5zdGFudGlhdGVkIG9yIGEgcmVwbGFjZW1lbnQgZm9yCisgICAgICAgIC8vIGl0CisgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCAmJiBlbmFibGVSZXNvbHZlKSB7CisgICAgICAgICAgICByZXN1bHQgPSByZXNvbHZlT2JqZWN0KHJlc3VsdCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJlZ2lzdGVyZWRSZXN1bHQgIT0gcmVzdWx0KSB7CisgICAgICAgICAgICByZWdpc3Rlck9iamVjdFJlYWQocmVzdWx0LCBuZXdIYW5kbGUsIHVuc2hhcmVkKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgSW52YWxpZENsYXNzRXhjZXB0aW9uIG1pc3NpbmdDbGFzc0Rlc2NyaXB0b3IoKSB0aHJvd3MgSW52YWxpZENsYXNzRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IEludmFsaWRDbGFzc0V4Y2VwdGlvbigiUmVhZCBudWxsIGF0dGVtcHRpbmcgdG8gcmVhZCBjbGFzcyBkZXNjcmlwdG9yIGZvciBvYmplY3QiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGEgc3RyaW5nIGVuY29kZWQgaW4ge0BsaW5rIERhdGFJbnB1dCBtb2RpZmllZCBVVEYtOH0gZnJvbSB0aGUKKyAgICAgKiByZWNlaXZlci4gUmV0dXJuIHRoZSBzdHJpbmcgcmVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1bnNoYXJlZAorICAgICAqICAgICAgICAgICAgcmVhZCB0aGUgb2JqZWN0IHVuc2hhcmVkCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIGp1c3QgcmVhZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXhjZXB0aW9uIGhhcHBlbmVkIHdoZW4gcmVhZGluZyB0aGUgU3RyaW5nLgorICAgICAqLworICAgIHByaXZhdGUgT2JqZWN0IHJlYWROZXdTdHJpbmcoYm9vbGVhbiB1bnNoYXJlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0IHJlc3VsdCA9IGlucHV0LnJlYWRVVEYoKTsKKyAgICAgICAgaWYgKGVuYWJsZVJlc29sdmUpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IHJlc29sdmVPYmplY3QocmVzdWx0KTsKKyAgICAgICAgfQorICAgICAgICByZWdpc3Rlck9iamVjdFJlYWQocmVzdWx0LCBuZXh0SGFuZGxlKCksIHVuc2hhcmVkKTsKKworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgYSBuZXcgU3RyaW5nIGluIFVURiBmb3JtYXQgZnJvbSB0aGUgcmVjZWl2ZXIuIFJldHVybiB0aGUgc3RyaW5nCisgICAgICogcmVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1bnNoYXJlZAorICAgICAqICAgICAgICAgICAgcmVhZCB0aGUgb2JqZWN0IHVuc2hhcmVkCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIGp1c3QgcmVhZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBleGNlcHRpb24gaGFwcGVuZWQgd2hlbiByZWFkaW5nIHRoZSBTdHJpbmcuCisgICAgICovCisgICAgcHJpdmF0ZSBPYmplY3QgcmVhZE5ld0xvbmdTdHJpbmcoYm9vbGVhbiB1bnNoYXJlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgbG9uZyBsZW5ndGggPSBpbnB1dC5yZWFkTG9uZygpOworICAgICAgICBPYmplY3QgcmVzdWx0ID0gaW5wdXQuZGVjb2RlVVRGKChpbnQpIGxlbmd0aCk7CisgICAgICAgIGlmIChlbmFibGVSZXNvbHZlKSB7CisgICAgICAgICAgICByZXN1bHQgPSByZXNvbHZlT2JqZWN0KHJlc3VsdCk7CisgICAgICAgIH0KKyAgICAgICAgcmVnaXN0ZXJPYmplY3RSZWFkKHJlc3VsdCwgbmV4dEhhbmRsZSgpLCB1bnNoYXJlZCk7CisKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB0aGUgbmV4dCBvYmplY3QgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG9iamVjdCByZWFkIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIG9uZSBvZiB0aGUgb2JqZWN0cyBpbiB0aGUgb2JqZWN0IGdyYXBoIGNhbm5vdAorICAgICAqICAgICAgICAgICAgIGJlIGZvdW5kLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqIEB0aHJvd3MgT3B0aW9uYWxEYXRhRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgcHJpbWl0aXZlIGRhdGEgdHlwZXMgd2VyZSBmb3VuZCBpbnN0ZWFkIG9mIGFuIG9iamVjdC4KKyAgICAgKiBAc2VlIE9iamVjdE91dHB1dFN0cmVhbSN3cml0ZU9iamVjdChPYmplY3QpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIE9iamVjdCByZWFkT2JqZWN0KCkgdGhyb3dzIE9wdGlvbmFsRGF0YUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHJlYWRPYmplY3QoZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSBuZXh0IHVuc2hhcmVkIG9iamVjdCBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV3IG9iamVjdCByZWFkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjbGFzcyBvZiBvbmUgb2YgdGhlIG9iamVjdHMgaW4gdGhlIG9iamVjdCBncmFwaCBjYW5ub3QKKyAgICAgKiAgICAgICAgICAgICBiZSBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKiBAc2VlIE9iamVjdE91dHB1dFN0cmVhbSN3cml0ZVVuc2hhcmVkCisgICAgICovCisgICAgcHVibGljIE9iamVjdCByZWFkVW5zaGFyZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gcmVhZE9iamVjdCh0cnVlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIE9iamVjdCByZWFkT2JqZWN0KGJvb2xlYW4gdW5zaGFyZWQpIHRocm93cyBPcHRpb25hbERhdGFFeGNlcHRpb24sCisgICAgICAgICAgICBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gcmVzdG9yZUlucHV0ID0gKHByaW1pdGl2ZURhdGEgPT0gaW5wdXQpOworICAgICAgICBpZiAocmVzdG9yZUlucHV0KSB7CisgICAgICAgICAgICBwcmltaXRpdmVEYXRhID0gZW1wdHlTdHJlYW07CisgICAgICAgIH0KKworICAgICAgICAvLyBUaGlzIGlzIHRoZSBzcGVjJ2VkIGJlaGF2aW9yIGluIEpESyAxLjIuIFZlcnkgYml6YXJyZSB3YXkgdG8gYWxsb3cKKyAgICAgICAgLy8gYmVoYXZpb3Igb3ZlcnJpZGluZy4KKyAgICAgICAgaWYgKHN1YmNsYXNzT3ZlcnJpZGluZ0ltcGxlbWVudGF0aW9uICYmICF1bnNoYXJlZCkgeworICAgICAgICAgICAgcmV0dXJuIHJlYWRPYmplY3RPdmVycmlkZSgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gSWYgd2Ugc3RpbGwgaGFkIHByaW1pdGl2ZSB0eXBlcyB0byByZWFkLCBzaG91bGQgd2UgZGlzY2FyZCB0aGVtCisgICAgICAgIC8vIChyZXNldCB0aGUgcHJpbWl0aXZlVHlwZXMgc3RyZWFtKSBvciBsZWF2ZSBhcyBpcywgc28gdGhhdCBhdHRlbXB0cyB0bworICAgICAgICAvLyByZWFkIHByaW1pdGl2ZSB0eXBlcyB3b24ndCByZWFkICdwYXN0IGRhdGEnID8/PworICAgICAgICBPYmplY3QgcmVzdWx0OworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gV2UgbmVlZCB0aGlzIHNvIHdlIGNhbiB0ZWxsIHdoZW4gd2UgYXJlIHJldHVybmluZyB0byB0aGUKKyAgICAgICAgICAgIC8vIG9yaWdpbmFsL291dHNpZGUgY2FsbGVyCisgICAgICAgICAgICBpZiAoKytuZXN0ZWRMZXZlbHMgPT0gMSkgeworICAgICAgICAgICAgICAgIC8vIFJlbWVtYmVyIHRoZSBjYWxsZXIncyBjbGFzcyBsb2FkZXIKKyAgICAgICAgICAgICAgICBjYWxsZXJDbGFzc0xvYWRlciA9IGdldENsb3Nlc3RVc2VyQ2xhc3NMb2FkZXIoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmVzdWx0ID0gcmVhZE5vblByaW1pdGl2ZUNvbnRlbnQodW5zaGFyZWQpOworICAgICAgICAgICAgaWYgKHJlc3RvcmVJbnB1dCkgeworICAgICAgICAgICAgICAgIHByaW1pdGl2ZURhdGEgPSBpbnB1dDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIC8vIFdlIG5lZWQgdGhpcyBzbyB3ZSBjYW4gdGVsbCB3aGVuIHdlIGFyZSByZXR1cm5pbmcgdG8gdGhlCisgICAgICAgICAgICAvLyBvcmlnaW5hbC9vdXRzaWRlIGNhbGxlcgorICAgICAgICAgICAgaWYgKC0tbmVzdGVkTGV2ZWxzID09IDApIHsKKyAgICAgICAgICAgICAgICAvLyBXZSBhcmUgZ29pbmcgdG8gcmV0dXJuIHRvIHRoZSBvcmlnaW5hbCBjYWxsZXIsIHBlcmZvcm0KKyAgICAgICAgICAgICAgICAvLyBjbGVhbnVwcy4KKyAgICAgICAgICAgICAgICAvLyBObyBtb3JlIG5lZWQgdG8gcmVtZW1iZXIgdGhlIGNhbGxlcidzIGNsYXNzIGxvYWRlcgorICAgICAgICAgICAgICAgIGNhbGxlckNsYXNzTG9hZGVyID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIERvbmUgcmVhZGluZyB0aGlzIG9iamVjdC4gSXMgaXQgdGltZSB0byByZXR1cm4gdG8gdGhlIG9yaWdpbmFsCisgICAgICAgIC8vIGNhbGxlcj8gSWYgc28gd2UgbmVlZCB0byBwZXJmb3JtIHZhbGlkYXRpb25zIGZpcnN0LgorICAgICAgICBpZiAobmVzdGVkTGV2ZWxzID09IDAgJiYgdmFsaWRhdGlvbnMgIT0gbnVsbCkgeworICAgICAgICAgICAgLy8gV2UgYXJlIGdvaW5nIHRvIHJldHVybiB0byB0aGUgb3JpZ2luYWwgY2FsbGVyLiBJZiB2YWxpZGF0aW9uIGlzCisgICAgICAgICAgICAvLyBlbmFibGVkIHdlIG5lZWQgdG8gcnVuIHRoZW0gbm93IGFuZCB0aGVuIGNsZWFudXAgdGhlIHZhbGlkYXRpb24KKyAgICAgICAgICAgIC8vIGNvbGxlY3Rpb24KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZm9yIChJbnB1dFZhbGlkYXRpb25EZXNjIGVsZW1lbnQgOiB2YWxpZGF0aW9ucykgeworICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnZhbGlkYXRvci52YWxpZGF0ZU9iamVjdCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgLy8gVmFsaWRhdGlvbnMgaGF2ZSB0byBiZSByZW5ld2VkLCBzaW5jZSB0aGV5IGFyZSBvbmx5IGNhbGxlZAorICAgICAgICAgICAgICAgIC8vIGZyb20gcmVhZE9iamVjdAorICAgICAgICAgICAgICAgIHZhbGlkYXRpb25zID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENsYXNzTG9hZGVyIGJvb3RzdHJhcExvYWRlciA9IE9iamVjdC5jbGFzcy5nZXRDbGFzc0xvYWRlcigpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENsYXNzTG9hZGVyIHN5c3RlbUxvYWRlciA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCk7CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyB1cCB0aGUgY2FsbCBzdGFjayB0byBmaW5kIHRoZSBjbG9zZXN0IHVzZXItZGVmaW5lZCBjbGFzcyBsb2FkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgdXNlci1kZWZpbmVkIGNsYXNzIGxvYWRlciBvciBudWxsIGlmIG9uZSBpc24ndCBmb3VuZAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIENsYXNzTG9hZGVyIGdldENsb3Nlc3RVc2VyQ2xhc3NMb2FkZXIoKSB7CisgICAgICAgIENsYXNzPD8+W10gc3RhY2tDbGFzc2VzID0gVk1TdGFjay5nZXRDbGFzc2VzKC0xKTsKKyAgICAgICAgZm9yIChDbGFzczw/PiBzdGFja0NsYXNzIDogc3RhY2tDbGFzc2VzKSB7CisgICAgICAgICAgICBDbGFzc0xvYWRlciBsb2FkZXIgPSBzdGFja0NsYXNzLmdldENsYXNzTG9hZGVyKCk7CisgICAgICAgICAgICBpZiAobG9hZGVyICE9IG51bGwgJiYgbG9hZGVyICE9IGJvb3RzdHJhcExvYWRlcgorICAgICAgICAgICAgICAgICAgICAmJiBsb2FkZXIgIT0gc3lzdGVtTG9hZGVyKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGxvYWRlcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNZXRob2QgdG8gYmUgb3ZlcnJpZGRlbiBieSBzdWJjbGFzc2VzIHRvIHJlYWQgdGhlIG5leHQgb2JqZWN0IGZyb20gdGhlCisgICAgICogc291cmNlIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG9iamVjdCByZWFkIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIG9uZSBvZiB0aGUgb2JqZWN0cyBpbiB0aGUgb2JqZWN0IGdyYXBoIGNhbm5vdAorICAgICAqICAgICAgICAgICAgIGJlIGZvdW5kLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqIEB0aHJvd3MgT3B0aW9uYWxEYXRhRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgcHJpbWl0aXZlIGRhdGEgdHlwZXMgd2VyZSBmb3VuZCBpbnN0ZWFkIG9mIGFuIG9iamVjdC4KKyAgICAgKiBAc2VlIE9iamVjdE91dHB1dFN0cmVhbSN3cml0ZU9iamVjdE92ZXJyaWRlCisgICAgICovCisgICAgcHJvdGVjdGVkIE9iamVjdCByZWFkT2JqZWN0T3ZlcnJpZGUoKSB0aHJvd3MgT3B0aW9uYWxEYXRhRXhjZXB0aW9uLAorICAgICAgICAgICAgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgLy8gU3ViY2xhc3NlcyBtdXN0IG92ZXJyaWRlLgorICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHNob3J0ICgxNiBiaXQpIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzaG9ydCB2YWx1ZSByZWFkIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHNob3J0IHJlYWRTaG9ydCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBwcmltaXRpdmVUeXBlcy5yZWFkU2hvcnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhbmQgdmFsaWRhdGVzIHRoZSBPYmplY3RJbnB1dFN0cmVhbSBoZWFkZXIgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqIEB0aHJvd3MgU3RyZWFtQ29ycnVwdGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNvdXJjZSBzdHJlYW0gZG9lcyBub3QgY29udGFpbiByZWFkYWJsZSBzZXJpYWxpemVkCisgICAgICogICAgICAgICAgICAgb2JqZWN0cy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCByZWFkU3RyZWFtSGVhZGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgU3RyZWFtQ29ycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlucHV0LnJlYWRTaG9ydCgpID09IFNUUkVBTV9NQUdJQworICAgICAgICAgICAgICAgICYmIGlucHV0LnJlYWRTaG9ydCgpID09IFNUUkVBTV9WRVJTSU9OKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IFN0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGFuIHVuc2lnbmVkIGJ5dGUgKDggYml0KSBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdW5zaWduZWQgYnl0ZSB2YWx1ZSByZWFkIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0gcGFja2FnZWQgaW4KKyAgICAgKiAgICAgICAgIGFuIGludGVnZXIuCisgICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZW5kIG9mIHRoZSBpbnB1dCBpcyByZWFjaGVkIGJlZm9yZSB0aGUgcmVhZAorICAgICAqICAgICAgICAgICAgIHJlcXVlc3QgY2FuIGJlIHNhdGlzZmllZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHJlYWRVbnNpZ25lZEJ5dGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcHJpbWl0aXZlVHlwZXMucmVhZFVuc2lnbmVkQnl0ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGFuIHVuc2lnbmVkIHNob3J0ICgxNiBiaXQpIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB1bnNpZ25lZCBzaG9ydCB2YWx1ZSByZWFkIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0gcGFja2FnZWQgaW4KKyAgICAgKiAgICAgICAgIGFuIGludGVnZXIuCisgICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZW5kIG9mIHRoZSBpbnB1dCBpcyByZWFjaGVkIGJlZm9yZSB0aGUgcmVhZAorICAgICAqICAgICAgICAgICAgIHJlcXVlc3QgY2FuIGJlIHNhdGlzZmllZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHJlYWRVbnNpZ25lZFNob3J0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHByaW1pdGl2ZVR5cGVzLnJlYWRVbnNpZ25lZFNob3J0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBzdHJpbmcgZW5jb2RlZCBpbiB7QGxpbmsgRGF0YUlucHV0IG1vZGlmaWVkIFVURi04fSBmcm9tIHRoZQorICAgICAqIHNvdXJjZSBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgZW5jb2RlZCBpbiB7QGxpbmsgRGF0YUlucHV0IG1vZGlmaWVkIFVURi04fSByZWFkIGZyb20KKyAgICAgKiAgICAgICAgIHRoZSBzb3VyY2Ugc3RyZWFtLgorICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGVuZCBvZiB0aGUgaW5wdXQgaXMgcmVhY2hlZCBiZWZvcmUgdGhlIHJlYWQKKyAgICAgKiAgICAgICAgICAgICByZXF1ZXN0IGNhbiBiZSBzYXRpc2ZpZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyByZWFkVVRGKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHByaW1pdGl2ZVR5cGVzLnJlYWRVVEYoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcmV2aW91c2x5LXJlYWQgb2JqZWN0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIHNlcmlhbGl6YXRpb24gaGFuZGxlLgorICAgICAqIEB0aHJvd3MgSW52YWxpZE9iamVjdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIHRoZXJlIGlzIG5vIHByZXZpb3VzbHktcmVhZCBvYmplY3Qgd2l0aCB0aGlzIGhhbmRsZQorICAgICAqLworICAgIHByaXZhdGUgT2JqZWN0IHJlZ2lzdGVyZWRPYmplY3RSZWFkKGludCBoYW5kbGUpIHRocm93cyBJbnZhbGlkT2JqZWN0RXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0IHJlcyA9IG9iamVjdHNSZWFkLmdldChoYW5kbGUgLSBPYmplY3RTdHJlYW1Db25zdGFudHMuYmFzZVdpcmVIYW5kbGUpOworICAgICAgICBpZiAocmVzID09IFVOU0hBUkVEX09CSikgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPYmplY3RFeGNlcHRpb24oIkNhbm5vdCByZWFkIGJhY2sgcmVmZXJlbmNlIHRvIHVuc2hhcmVkIG9iamVjdCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzb2NpYXRlcyBhIHJlYWQgb2JqZWN0IHdpdGggdGhlIGl0cyBzZXJpYWxpemF0aW9uIGhhbmRsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVnaXN0ZXJPYmplY3RSZWFkKE9iamVjdCBvYmosIGludCBoYW5kbGUsIGJvb2xlYW4gdW5zaGFyZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh1bnNoYXJlZCkgeworICAgICAgICAgICAgb2JqID0gVU5TSEFSRURfT0JKOworICAgICAgICB9CisgICAgICAgIGludCBpbmRleCA9IGhhbmRsZSAtIE9iamVjdFN0cmVhbUNvbnN0YW50cy5iYXNlV2lyZUhhbmRsZTsKKyAgICAgICAgaW50IHNpemUgPSBvYmplY3RzUmVhZC5zaXplKCk7CisgICAgICAgIC8vIE9iamVjdE91dHB1dFN0cmVhbSBzb21ldGltZXMgd2FzdGVzIGEgaGFuZGxlLiBJJ3ZlIGNvbXBhcmVkIGhleCBkdW1wcyBvZiB0aGUgUkkKKyAgICAgICAgLy8gYW5kIGl0IHNlZW1zIGxpa2UgdGhhdCdzIGEgJ2ZlYXR1cmUnLiBMb29rIGZvciBjYWxscyB0byBvYmplY3RzV3JpdHRlbi5wdXQgdGhhdAorICAgICAgICAvLyBhcmUgZ3VhcmRlZCBieSAhdW5zaGFyZWQgdGVzdHMuCisgICAgICAgIHdoaWxlIChpbmRleCA+IHNpemUpIHsKKyAgICAgICAgICAgIG9iamVjdHNSZWFkLmFkZChudWxsKTsKKyAgICAgICAgICAgICsrc2l6ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5kZXggPT0gc2l6ZSkgeworICAgICAgICAgICAgb2JqZWN0c1JlYWQuYWRkKG9iaik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBvYmplY3RzUmVhZC5zZXQoaW5kZXgsIG9iaik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWdpc3RlcnMgYSBjYWxsYmFjayBmb3IgcG9zdC1kZXNlcmlhbGl6YXRpb24gdmFsaWRhdGlvbiBvZiBvYmplY3RzLiBJdAorICAgICAqIGFsbG93cyB0byBwZXJmb3JtIGFkZGl0aW9uYWwgY29uc2lzdGVuY3kgY2hlY2tzIGJlZm9yZSB0aGUge0Bjb2RlCisgICAgICogcmVhZE9iamVjdCgpfSBtZXRob2Qgb2YgdGhpcyBjbGFzcyByZXR1cm5zIGl0cyByZXN1bHQgdG8gdGhlIGNhbGxlci4gVGhpcworICAgICAqIG1ldGhvZCBjYW4gb25seSBiZSBjYWxsZWQgZnJvbSB3aXRoaW4gdGhlIHtAY29kZSByZWFkT2JqZWN0KCl9IG1ldGhvZCBvZgorICAgICAqIGEgY2xhc3MgdGhhdCBpbXBsZW1lbnRzICJzcGVjaWFsIiBkZXNlcmlhbGl6YXRpb24gcnVsZXMuIEl0IGNhbiBiZSBjYWxsZWQKKyAgICAgKiBtdWx0aXBsZSB0aW1lcy4gVmFsaWRhdGlvbiBjYWxsYmFja3MgYXJlIHRoZW4gZG9uZSBpbiBvcmRlciBvZiBkZWNyZWFzaW5nCisgICAgICogcHJpb3JpdHksIGRlZmluZWQgYnkge0Bjb2RlIHByaW9yaXR5fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIGFuIG9iamVjdCB0aGF0IGNhbiB2YWxpZGF0ZSBpdHNlbGYgYnkgcmVjZWl2aW5nIGEgY2FsbGJhY2suCisgICAgICogQHBhcmFtIHByaW9yaXR5CisgICAgICogICAgICAgICAgICB0aGUgdmFsaWRhdG9yJ3MgcHJpb3JpdHkuCisgICAgICogQHRocm93cyBJbnZhbGlkT2JqZWN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9iamVjdH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgTm90QWN0aXZlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBzdHJlYW0gaXMgY3VycmVudGx5IG5vdCByZWFkaW5nIG9iamVjdHMuIEluIHRoYXQKKyAgICAgKiAgICAgICAgICAgICBjYXNlLCBjYWxsaW5nIHRoaXMgbWV0aG9kIGlzIG5vdCBhbGxvd2VkLgorICAgICAqIEBzZWUgT2JqZWN0SW5wdXRWYWxpZGF0aW9uI3ZhbGlkYXRlT2JqZWN0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVnaXN0ZXJWYWxpZGF0aW9uKE9iamVjdElucHV0VmFsaWRhdGlvbiBvYmplY3QsCisgICAgICAgICAgICBpbnQgcHJpb3JpdHkpIHRocm93cyBOb3RBY3RpdmVFeGNlcHRpb24sIEludmFsaWRPYmplY3RFeGNlcHRpb24geworICAgICAgICAvLyBWYWxpZGF0aW9uIGNhbiBvbmx5IGJlIHJlZ2lzdGVyZWQgd2hlbiBpbnNpZGUgcmVhZE9iamVjdCBjYWxscworICAgICAgICBPYmplY3QgaW5zdGFuY2VCZWluZ1JlYWQgPSB0aGlzLmN1cnJlbnRPYmplY3Q7CisKKyAgICAgICAgaWYgKGluc3RhbmNlQmVpbmdSZWFkID09IG51bGwgJiYgbmVzdGVkTGV2ZWxzID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb3RBY3RpdmVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT2JqZWN0RXhjZXB0aW9uKCJDYWxsYmFjayBvYmplY3QgY2Fubm90IGJlIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICAvLyBGcm9tIG5vdyBvbiBpdCBpcyBqdXN0IGluc2VydGlvbiBpbiBhIFNvcnRlZENvbGxlY3Rpb24uIFNpbmNlCisgICAgICAgIC8vIHRoZSBKYXZhIGNsYXNzIGxpYnJhcmllcyBkb24ndCBwcm92aWRlIHRoYXQsIHdlIGhhdmUgdG8KKyAgICAgICAgLy8gaW1wbGVtZW50IGl0IGZyb20gc2NyYXRjaCBoZXJlLgorICAgICAgICBJbnB1dFZhbGlkYXRpb25EZXNjIGRlc2MgPSBuZXcgSW5wdXRWYWxpZGF0aW9uRGVzYygpOworICAgICAgICBkZXNjLnZhbGlkYXRvciA9IG9iamVjdDsKKyAgICAgICAgZGVzYy5wcmlvcml0eSA9IHByaW9yaXR5OworICAgICAgICAvLyBObyBuZWVkIGZvciB0aGlzLCB2YWxpZGF0ZU9iamVjdCBkb2VzIG5vdCB0YWtlIGEgcGFyYW1ldGVyCisgICAgICAgIC8vIGRlc2MudG9WYWxpZGF0ZSA9IGluc3RhbmNlQmVpbmdSZWFkOworICAgICAgICBpZiAodmFsaWRhdGlvbnMgPT0gbnVsbCkgeworICAgICAgICAgICAgdmFsaWRhdGlvbnMgPSBuZXcgSW5wdXRWYWxpZGF0aW9uRGVzY1sxXTsKKyAgICAgICAgICAgIHZhbGlkYXRpb25zWzBdID0gZGVzYzsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgICAgIGZvciAoOyBpIDwgdmFsaWRhdGlvbnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBJbnB1dFZhbGlkYXRpb25EZXNjIHZhbGlkYXRpb24gPSB2YWxpZGF0aW9uc1tpXTsKKyAgICAgICAgICAgICAgICAvLyBTb3J0ZWQsIGhpZ2hlciBwcmlvcml0eSBmaXJzdC4KKyAgICAgICAgICAgICAgICBpZiAocHJpb3JpdHkgPj0gdmFsaWRhdGlvbi5wcmlvcml0eSkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsgLy8gRm91bmQgdGhlIGluZGV4IHdoZXJlIHRvIGluc2VydAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIElucHV0VmFsaWRhdGlvbkRlc2NbXSBvbGRWYWxpZGF0aW9ucyA9IHZhbGlkYXRpb25zOworICAgICAgICAgICAgaW50IGN1cnJlbnRTaXplID0gb2xkVmFsaWRhdGlvbnMubGVuZ3RoOworICAgICAgICAgICAgdmFsaWRhdGlvbnMgPSBuZXcgSW5wdXRWYWxpZGF0aW9uRGVzY1tjdXJyZW50U2l6ZSArIDFdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShvbGRWYWxpZGF0aW9ucywgMCwgdmFsaWRhdGlvbnMsIDAsIGkpOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShvbGRWYWxpZGF0aW9ucywgaSwgdmFsaWRhdGlvbnMsIGkgKyAxLCBjdXJyZW50U2l6ZQorICAgICAgICAgICAgICAgICAgICAtIGkpOworICAgICAgICAgICAgdmFsaWRhdGlvbnNbaV0gPSBkZXNjOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzZXQgdGhlIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cyBhbHJlYWR5IGxvYWRlZCBieSB0aGUgcmVjZWl2ZXIuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlc2V0U2Vlbk9iamVjdHMoKSB7CisgICAgICAgIG9iamVjdHNSZWFkID0gbmV3IEFycmF5TGlzdDxPYmplY3Q+KCk7CisgICAgICAgIG5leHRIYW5kbGUgPSBiYXNlV2lyZUhhbmRsZTsKKyAgICAgICAgcHJpbWl0aXZlRGF0YSA9IGVtcHR5U3RyZWFtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0IHRoZSByZWNlaXZlci4gVGhlIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cyBhbHJlYWR5IHJlYWQgYnkgdGhlCisgICAgICogcmVjZWl2ZXIgaXMgcmVzZXQsIGFuZCBpbnRlcm5hbCBzdHJ1Y3R1cmVzIGFyZSBhbHNvIHJlc2V0IHNvIHRoYXQgdGhlCisgICAgICogcmVjZWl2ZXIga25vd3MgaXQgaXMgaW4gYSBmcmVzaCBjbGVhbiBzdGF0ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVzZXRTdGF0ZSgpIHsKKyAgICAgICAgcmVzZXRTZWVuT2JqZWN0cygpOworICAgICAgICBoYXNQdXNoYmFja1RDID0gZmFsc2U7CisgICAgICAgIHB1c2hiYWNrVEMgPSAwOworICAgICAgICAvLyBuZXN0ZWRMZXZlbHMgPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvYWRzIHRoZSBKYXZhIGNsYXNzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGNsYXNzIGRlc2NyaXB0b3Ige0Bjb2RlCisgICAgICogb3NDbGFzc30gdGhhdCBoYXMganVzdCBiZWVuIHJlYWQgZnJvbSB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvc0NsYXNzCisgICAgICogICAgICAgICAgICBhbiBPYmplY3RTdHJlYW1DbGFzcyByZWFkIGZyb20gdGhlIHNvdXJjZSBzdHJlYW0uCisgICAgICogQHJldHVybiBhIENsYXNzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGRlc2NyaXB0b3Ige0Bjb2RlIG9zQ2xhc3N9LgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjbGFzcyBmb3IgYW4gb2JqZWN0IGNhbm5vdCBiZSBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSBjcmVhdGluZyB0aGUgY2xhc3MuCisgICAgICogQHNlZSBPYmplY3RPdXRwdXRTdHJlYW0jYW5ub3RhdGVDbGFzcyhDbGFzcykKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ2xhc3M8Pz4gcmVzb2x2ZUNsYXNzKE9iamVjdFN0cmVhbUNsYXNzIG9zQ2xhc3MpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICAvLyBmYXN0cGF0aDogb2J0YWluIGNhY2hlZCB2YWx1ZQorICAgICAgICBDbGFzczw/PiBjbHMgPSBvc0NsYXNzLmZvckNsYXNzKCk7CisgICAgICAgIGlmIChjbHMgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gc2xvd3BhdGg6IHJlc29sdmUgdGhlIGNsYXNzCisgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lID0gb3NDbGFzcy5nZXROYW1lKCk7CisKKyAgICAgICAgICAgIC8vIGlmIGl0IGlzIHByaW1pdGl2ZSBjbGFzcywgZm9yIGV4YW1wbGUsIGxvbmcuY2xhc3MKKyAgICAgICAgICAgIGNscyA9IFBSSU1JVElWRV9DTEFTU0VTLmdldChjbGFzc05hbWUpOworCisgICAgICAgICAgICBpZiAoY2xzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyBub3QgcHJpbWl0aXZlIGNsYXNzCisgICAgICAgICAgICAgICAgLy8gVXNlIHRoZSBmaXJzdCBub24tbnVsbCBDbGFzc0xvYWRlciBvbiB0aGUgc3RhY2suIElmIG51bGwsIHVzZQorICAgICAgICAgICAgICAgIC8vIHRoZSBzeXN0ZW0gY2xhc3MgbG9hZGVyCisgICAgICAgICAgICAgICAgY2xzID0gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUsIHRydWUsIGNhbGxlckNsYXNzTG9hZGVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2xzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFsbG93cyB0cnVzdGVkIHN1YmNsYXNzZXMgdG8gc3Vic3RpdHV0ZSB0aGUgc3BlY2lmaWVkIG9yaWdpbmFsIHtAY29kZQorICAgICAqIG9iamVjdH0gd2l0aCBhIG5ldyBvYmplY3QuIE9iamVjdCBzdWJzdGl0dXRpb24gaGFzIHRvIGJlIGFjdGl2YXRlZCBmaXJzdAorICAgICAqIHdpdGggY2FsbGluZyB7QGNvZGUgZW5hYmxlUmVzb2x2ZU9iamVjdCh0cnVlKX0uIFRoaXMgaW1wbGVtZW50YXRpb24ganVzdAorICAgICAqIHJldHVybnMge0Bjb2RlIG9iamVjdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb3JpZ2luYWwgb2JqZWN0IGZvciB3aGljaCBhIHJlcGxhY2VtZW50IG1heSBiZSBkZWZpbmVkLgorICAgICAqIEByZXR1cm4gdGhlIHJlcGxhY2VtZW50IG9iamVjdCBmb3Ige0Bjb2RlIG9iamVjdH0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIGNyZWF0aW5nIHRoZSByZXBsYWNlbWVudAorICAgICAqICAgICAgICAgICAgIG9iamVjdC4KKyAgICAgKiBAc2VlICNlbmFibGVSZXNvbHZlT2JqZWN0CisgICAgICogQHNlZSBPYmplY3RPdXRwdXRTdHJlYW0jZW5hYmxlUmVwbGFjZU9iamVjdAorICAgICAqIEBzZWUgT2JqZWN0T3V0cHV0U3RyZWFtI3JlcGxhY2VPYmplY3QKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgT2JqZWN0IHJlc29sdmVPYmplY3QoT2JqZWN0IG9iamVjdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQnkgZGVmYXVsdCBubyBvYmplY3QgcmVwbGFjZW1lbnQuIFN1YmNsYXNzZXMgY2FuIG92ZXJyaWRlCisgICAgICAgIHJldHVybiBvYmplY3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcHMge0Bjb2RlIGxlbmd0aH0gYnl0ZXMgb24gdGhlIHNvdXJjZSBzdHJlYW0uIFRoaXMgbWV0aG9kIHNob3VsZCBub3QKKyAgICAgKiBiZSB1c2VkIHRvIHNraXAgYnl0ZXMgYXQgYW55IGFyYml0cmFyeSBwb3NpdGlvbiwganVzdCB3aGVuIHJlYWRpbmcKKyAgICAgKiBwcmltaXRpdmUgZGF0YSB0eXBlcyAoaW50LCBjaGFyIGV0YykuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHNraXAuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHNraXBwZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBza2lwcGluZyBieXRlcyBvbiB0aGUgc291cmNlIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNvdXJjZSBzdHJlYW0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2tpcEJ5dGVzKGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRvIGJlIHVzZWQgd2l0aCBhdmFpbGFibGUuIE9rIHRvIGNhbGwgaWYgcmVhZGluZyBwcmltaXRpdmUgYnVmZmVyCisgICAgICAgIGlmIChpbnB1dCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBvZmZzZXQgPSAwOworICAgICAgICB3aGlsZSAob2Zmc2V0IDwgbGVuZ3RoKSB7CisgICAgICAgICAgICBjaGVja1JlYWRQcmltaXRpdmVUeXBlcygpOworICAgICAgICAgICAgbG9uZyBza2lwcGVkID0gcHJpbWl0aXZlRGF0YS5za2lwKGxlbmd0aCAtIG9mZnNldCk7CisgICAgICAgICAgICBpZiAoc2tpcHBlZCA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG9mZnNldDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG9mZnNldCArPSAoaW50KSBza2lwcGVkOworICAgICAgICB9CisgICAgICAgIHJldHVybiBsZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogVmVyaWZ5IGlmIHRoZSBTVUlEICYgdGhlIGJhc2UgbmFtZSBmb3IgZGVzY3JpcHRvcgorICAgICAqIDxjb2RlPmxvYWRlZFN0cmVhbUNsYXNzPC9jb2RlPm1hdGNoZXMKKyAgICAgKiB0aGUgU1VJRCAmIHRoZSBiYXNlIG5hbWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgbG9hZGVkIGNsYXNzIGFuZAorICAgICAqIGluaXQgcHJpdmF0ZSBmaWVsZHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9hZGVkU3RyZWFtQ2xhc3MKKyAgICAgKiAgICAgICAgICAgIEFuIE9iamVjdFN0cmVhbUNsYXNzIHRoYXQgd2FzIGxvYWRlZCBmcm9tIHRoZSBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEludmFsaWRDbGFzc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIHRoZSBTVUlEIG9mIHRoZSBzdHJlYW0gY2xhc3MgZG9lcyBub3QgbWF0Y2ggdGhlIFZNIGNsYXNzCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHZlcmlmeUFuZEluaXQoT2JqZWN0U3RyZWFtQ2xhc3MgbG9hZGVkU3RyZWFtQ2xhc3MpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZENsYXNzRXhjZXB0aW9uIHsKKworICAgICAgICBDbGFzczw/PiBsb2NhbENsYXNzID0gbG9hZGVkU3RyZWFtQ2xhc3MuZm9yQ2xhc3MoKTsKKyAgICAgICAgT2JqZWN0U3RyZWFtQ2xhc3MgbG9jYWxTdHJlYW1DbGFzcyA9IE9iamVjdFN0cmVhbUNsYXNzCisgICAgICAgICAgICAgICAgLmxvb2t1cFN0cmVhbUNsYXNzKGxvY2FsQ2xhc3MpOworCisgICAgICAgIGlmIChsb2FkZWRTdHJlYW1DbGFzcy5nZXRTZXJpYWxWZXJzaW9uVUlEKCkgIT0gbG9jYWxTdHJlYW1DbGFzcworICAgICAgICAgICAgICAgIC5nZXRTZXJpYWxWZXJzaW9uVUlEKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQ2xhc3NFeGNlcHRpb24obG9hZGVkU3RyZWFtQ2xhc3MuZ2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAiSW5jb21wYXRpYmxlIGNsYXNzIChTVUlEKTogIiArIGxvYWRlZFN0cmVhbUNsYXNzICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGJ1dCBleHBlY3RlZCAiICsgbG9jYWxTdHJlYW1DbGFzcyk7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgbG9hZGVkQ2xhc3NCYXNlTmFtZSA9IGdldEJhc2VOYW1lKGxvYWRlZFN0cmVhbUNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIFN0cmluZyBsb2NhbENsYXNzQmFzZU5hbWUgPSBnZXRCYXNlTmFtZShsb2NhbFN0cmVhbUNsYXNzLmdldE5hbWUoKSk7CisKKyAgICAgICAgaWYgKCFsb2FkZWRDbGFzc0Jhc2VOYW1lLmVxdWFscyhsb2NhbENsYXNzQmFzZU5hbWUpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZENsYXNzRXhjZXB0aW9uKGxvYWRlZFN0cmVhbUNsYXNzLmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nLmZvcm1hdCgiSW5jb21wYXRpYmxlIGNsYXNzIChiYXNlIG5hbWUpOiAlcyBidXQgZXhwZWN0ZWQgJXMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRlZENsYXNzQmFzZU5hbWUsIGxvY2FsQ2xhc3NCYXNlTmFtZSkpOworICAgICAgICB9CisKKyAgICAgICAgbG9hZGVkU3RyZWFtQ2xhc3MuaW5pdFByaXZhdGVGaWVsZHMobG9jYWxTdHJlYW1DbGFzcyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldEJhc2VOYW1lKFN0cmluZyBmdWxsTmFtZSkgeworICAgICAgICBpbnQgayA9IGZ1bGxOYW1lLmxhc3RJbmRleE9mKCcuJyk7CisKKyAgICAgICAgaWYgKGsgPT0gLTEgfHwgayA9PSAoZnVsbE5hbWUubGVuZ3RoKCkgLSAxKSkgeworICAgICAgICAgICAgcmV0dXJuIGZ1bGxOYW1lOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmdWxsTmFtZS5zdWJzdHJpbmcoayArIDEpOworICAgIH0KKworICAgIC8vIEF2b2lkIHJlY3Vyc2l2ZSBkZWZpbmluZy4KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNoZWNrZWRTZXRTdXBlckNsYXNzRGVzYyhPYmplY3RTdHJlYW1DbGFzcyBkZXNjLAorICAgICAgICAgICAgT2JqZWN0U3RyZWFtQ2xhc3Mgc3VwZXJEZXNjKSB0aHJvd3MgU3RyZWFtQ29ycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGRlc2MuZXF1YWxzKHN1cGVyRGVzYykpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTdHJlYW1Db3JydXB0ZWRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBkZXNjLnNldFN1cGVyY2xhc3Moc3VwZXJEZXNjKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9PYmplY3RJbnB1dFZhbGlkYXRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL09iamVjdElucHV0VmFsaWRhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkyNWRmZjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9PYmplY3RJbnB1dFZhbGlkYXRpb24uamF2YQpAQCAtMCwwICsxLDM1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKKy8qKgorICogQSBjYWxsYmFjayBpbnRlcmZhY2UgZm9yIHBvc3QtZGVzZXJpYWxpemF0aW9uIGNoZWNrcyBvbiBvYmplY3RzLiBBbGxvd3MsIGZvcgorICogZXhhbXBsZSwgdGhlIHZhbGlkYXRpb24gb2YgYSB3aG9sZSBncmFwaCBvZiBvYmplY3RzIGFmdGVyIGFsbCBvZiB0aGVtIGhhdmUKKyAqIGJlZW4gbG9hZGVkLgorICoKKyAqIEBzZWUgT2JqZWN0SW5wdXRTdHJlYW0jcmVnaXN0ZXJWYWxpZGF0aW9uKE9iamVjdElucHV0VmFsaWRhdGlvbiwgaW50KQorICovCitwdWJsaWMgaW50ZXJmYWNlIE9iamVjdElucHV0VmFsaWRhdGlvbiB7CisgICAgLyoqCisgICAgICogVmFsaWRhdGVzIHRoaXMgb2JqZWN0LgorICAgICAqCisgICAgICogQHRocm93cyBJbnZhbGlkT2JqZWN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBvYmplY3QgZmFpbHMgdG8gdmFsaWRhdGUgaXRzZWxmLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlT2JqZWN0KCkgdGhyb3dzIEludmFsaWRPYmplY3RFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9PYmplY3RPdXRwdXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL09iamVjdE91dHB1dC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlNDU0ZWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9PYmplY3RPdXRwdXQuamF2YQpAQCAtMCwwICsxLDk0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKKy8qKgorICogRGVmaW5lcyBhbiBpbnRlcmZhY2UgZm9yIGNsYXNzZXMgdGhhdCBhbGxvdyByZWFkaW5nIHNlcmlhbGl6ZWQgb2JqZWN0cy4KKyAqCisgKiBAc2VlIE9iamVjdE91dHB1dFN0cmVhbQorICogQHNlZSBPYmplY3RJbnB1dAorICovCitwdWJsaWMgaW50ZXJmYWNlIE9iamVjdE91dHB1dCBleHRlbmRzIERhdGFPdXRwdXQsIEF1dG9DbG9zZWFibGUgeworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGUgdGFyZ2V0IHN0cmVhbS4gSW1wbGVtZW50YXRpb25zIG9mIHRoaXMgbWV0aG9kIHNob3VsZCBmcmVlIGFueQorICAgICAqIHJlc291cmNlcyB1c2VkIGJ5IHRoZSBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNsb3NpbmcgdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIHRoZSB0YXJnZXQgc3RyZWFtLiBJbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBtZXRob2Qgc2hvdWxkIGVuc3VyZQorICAgICAqIHRoYXQgYW55IHBlbmRpbmcgd3JpdGVzIGFyZSB3cml0dGVuIG91dCB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgZmx1c2hpbmcgdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGVudGlyZSBjb250ZW50cyBvZiB0aGUgYnl0ZSBhcnJheSB7QGNvZGUgYnVmZmVyfSB0byB0aGUgb3V0cHV0CisgICAgICogc3RyZWFtLiBCbG9ja3MgdW50aWwgYWxsIGJ5dGVzIGFyZSB3cml0dGVuLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIGJ1ZmZlciB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGJ1ZmZlcikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHtAY29kZSBjb3VudH0gYnl0ZXMgZnJvbSB0aGUgYnl0ZSBhcnJheSB7QGNvZGUgYnVmZmVyfSBzdGFydGluZyBhdAorICAgICAqIHBvc2l0aW9uIHtAY29kZSBvZmZzZXR9IHRvIHRoZSB0YXJnZXQgc3RyZWFtLiBCbG9ja3MgdW50aWwgYWxsIGJ5dGVzIGFyZQorICAgICAqIHdyaXR0ZW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgYnl0ZSBpbiB7QGNvZGUgYnVmZmVyfSB0byB3cml0ZS4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgZnJvbSB7QGNvZGUgYnVmZmVyfSB0byB3cml0ZSB0byB0aGUgdGFyZ2V0CisgICAgICogICAgICAgICAgICBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgc2luZ2xlIGJ5dGUgdG8gdGhlIHRhcmdldCBzdHJlYW0uIE9ubHkgdGhlIGxlYXN0IHNpZ25pZmljYW50CisgICAgICogYnl0ZSBvZiB0aGUgaW50ZWdlciB7QGNvZGUgdmFsdWV9IGlzIHdyaXR0ZW4gdG8gdGhlIHN0cmVhbS4gQmxvY2tzIHVudGlsCisgICAgICogdGhlIGJ5dGUgaXMgYWN0dWFsbHkgd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHtAY29kZSBvYmp9IHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0IG9iaikgdGhyb3dzIElPRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vT2JqZWN0T3V0cHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9PYmplY3RPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YWIzNTQ3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vT2JqZWN0T3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxODMyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Qcm94eTsKK2ltcG9ydCBqYXZhLm5pby5CeXRlT3JkZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5Nb2RpZmllZFV0Zjg7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgbGliY29yZS5pby5NZW1vcnk7CitpbXBvcnQgbGliY29yZS5pby5TaXplT2Y7CisKKy8qKgorICogQSBzcGVjaWFsaXplZCB7QGxpbmsgT3V0cHV0U3RyZWFtfSB0aGF0IGlzIGFibGUgdG8gd3JpdGUgKHNlcmlhbGl6ZSkgSmF2YQorICogb2JqZWN0cyBhcyB3ZWxsIGFzIHByaW1pdGl2ZSBkYXRhIHR5cGVzIChpbnQsIGJ5dGUsIGNoYXIgZXRjLikuIFRoZSBkYXRhIGNhbgorICogbGF0ZXIgYmUgbG9hZGVkIHVzaW5nIGFuIE9iamVjdElucHV0U3RyZWFtLgorICoKKyAqIEBzZWUgT2JqZWN0SW5wdXRTdHJlYW0KKyAqIEBzZWUgT2JqZWN0T3V0cHV0CisgKiBAc2VlIFNlcmlhbGl6YWJsZQorICogQHNlZSBFeHRlcm5hbGl6YWJsZQorICovCitwdWJsaWMgY2xhc3MgT2JqZWN0T3V0cHV0U3RyZWFtIGV4dGVuZHMgT3V0cHV0U3RyZWFtIGltcGxlbWVudHMgT2JqZWN0T3V0cHV0LCBPYmplY3RTdHJlYW1Db25zdGFudHMgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ2xhc3M8Pz5bXSBXUklURV9VTlNIQVJFRF9QQVJBTV9UWVBFUyA9IG5ldyBDbGFzc1tdIHsgT2JqZWN0LmNsYXNzIH07CisKKyAgICAvKgorICAgICAqIE1hc2sgdG8gemVybyBTQ19CTE9DX0RBVEEgYml0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgTk9UX1NDX0JMT0NLX0RBVEEgPSAoYnl0ZSkgKFNDX0JMT0NLX0RBVEEgXiAweEZGKTsKKworICAgIC8qCisgICAgICogSG93IG1hbnkgbmVzdGVkIGxldmVscyB0byB3cml0ZU9iamVjdC4gV2UgbWF5IG5vdCBuZWVkIHRoaXMuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbmVzdGVkTGV2ZWxzOworCisgICAgLyoKKyAgICAgKiBXaGVyZSB3ZSB3cml0ZSB0bworICAgICAqLworICAgIHByaXZhdGUgRGF0YU91dHB1dFN0cmVhbSBvdXRwdXQ7CisKKyAgICAvKgorICAgICAqIElmIG9iamVjdCByZXBsYWNlbWVudCBpcyBlbmFibGVkIG9yIG5vdAorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBlbmFibGVSZXBsYWNlOworCisgICAgLyoKKyAgICAgKiBXaGVyZSB3ZSB3cml0ZSBwcmltaXRpdmUgdHlwZXMgdG8KKyAgICAgKi8KKyAgICBwcml2YXRlIERhdGFPdXRwdXRTdHJlYW0gcHJpbWl0aXZlVHlwZXM7CisKKyAgICAvKgorICAgICAqIFdoZXJlIHRoZSB3cml0ZSBwcmltaXRpdmUgdHlwZXMgYXJlIGFjdHVhbGx5IHdyaXR0ZW4gdG8KKyAgICAgKi8KKyAgICBwcml2YXRlIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBwcmltaXRpdmVUeXBlc0J1ZmZlcjsKKworICAgIC8qCisgICAgICogVGFibGUgbWFwcGluZyBPYmplY3QgLT4gSW50ZWdlciAoaGFuZGxlKQorICAgICAqLworICAgIHByaXZhdGUgU2VyaWFsaXphdGlvbkhhbmRsZU1hcCBvYmplY3RzV3JpdHRlbjsKKworICAgIC8qCisgICAgICogQWxsIG9iamVjdHMgYXJlIGFzc2lnbmVkIGFuIElEIChpbnRlZ2VyIGhhbmRsZSkKKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBjdXJyZW50SGFuZGxlOworCisgICAgLyoKKyAgICAgKiBVc2VkIGJ5IGRlZmF1bHRXcml0ZU9iamVjdAorICAgICAqLworICAgIHByaXZhdGUgT2JqZWN0IGN1cnJlbnRPYmplY3Q7CisKKyAgICAvKgorICAgICAqIFVzZWQgYnkgZGVmYXVsdFdyaXRlT2JqZWN0CisgICAgICovCisgICAgcHJpdmF0ZSBPYmplY3RTdHJlYW1DbGFzcyBjdXJyZW50Q2xhc3M7CisKKyAgICAvKgorICAgICAqIEVpdGhlciBPYmplY3RTdHJlYW1Db25zdGFudHMuUFJPVE9DT0xfVkVSU0lPTl8xIG9yCisgICAgICogT2JqZWN0U3RyZWFtQ29uc3RhbnRzLlBST1RPQ09MX1ZFUlNJT05fMgorICAgICAqLworICAgIHByaXZhdGUgaW50IHByb3RvY29sVmVyc2lvbjsKKworICAgIC8qCisgICAgICogVXNlZCB0byBkZXRlY3QgbmVzdGVkIGV4Y2VwdGlvbiB3aGVuIHNhdmluZyBhbiBleGNlcHRpb24gZHVlIHRvIGFuIGVycm9yCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJlYW1Db3JydXB0ZWRFeGNlcHRpb24gbmVzdGVkRXhjZXB0aW9uOworCisgICAgLyoKKyAgICAgKiBVc2VkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIFB1dEZpZWxkIG9iamVjdCBmb3IgdGhlIGNsYXNzL29iamVjdCBiZWluZworICAgICAqIHdyaXR0ZW4KKyAgICAgKi8KKyAgICBwcml2YXRlIEVtdWxhdGVkRmllbGRzRm9yRHVtcGluZyBjdXJyZW50UHV0RmllbGQ7CisKKyAgICAvKgorICAgICAqIEFsbG93cyB0aGUgcmVjZWl2ZXIgdG8gZGVjaWRlIGlmIGl0IG5lZWRzIHRvIGNhbGwgd3JpdGVPYmplY3RPdmVycmlkZQorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBzdWJjbGFzc092ZXJyaWRpbmdJbXBsZW1lbnRhdGlvbjsKKworICAgIC8qCisgICAgICogRGVzY3JpcHRvciBmb3IgamF2YS5sYW5nLnJlZmxlY3QuUHJveHkKKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIE9iamVjdFN0cmVhbUNsYXNzIHByb3h5Q2xhc3NEZXNjID0gT2JqZWN0U3RyZWFtQ2xhc3MubG9va3VwKFByb3h5LmNsYXNzKTsKKworICAgIC8qKgorICAgICAqIFB1dEZpZWxkIGlzIGFuIGlubmVyIGNsYXNzIHRvIHByb3ZpZGUgYWNjZXNzIHRvIHRoZSBwZXJzaXN0ZW50IGZpZWxkcworICAgICAqIHRoYXQgYXJlIHdyaXR0ZW4gdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBQdXRGaWVsZCB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBQdXRzIHRoZSB2YWx1ZSBvZiB0aGUgYm9vbGVhbiBmaWVsZCBpZGVudGlmaWVkIGJ5IHtAY29kZSBuYW1lfSB0byB0aGUKKyAgICAgICAgICogcGVyc2lzdGVudCBmaWVsZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG5hbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZmllbGQgdG8gc2VyaWFsaXplLgorICAgICAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdGhhdCBpcyBwdXQgdG8gdGhlIHBlcnNpc3RlbnQgZmllbGQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBwdXQoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBQdXRzIHRoZSB2YWx1ZSBvZiB0aGUgY2hhcmFjdGVyIGZpZWxkIGlkZW50aWZpZWQgYnkge0Bjb2RlIG5hbWV9IHRvCisgICAgICAgICAqIHRoZSBwZXJzaXN0ZW50IGZpZWxkLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gbmFtZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBzZXJpYWxpemUuCisgICAgICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0aGF0IGlzIHB1dCB0byB0aGUgcGVyc2lzdGVudCBmaWVsZC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHB1dChTdHJpbmcgbmFtZSwgY2hhciB2YWx1ZSk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFB1dHMgdGhlIHZhbHVlIG9mIHRoZSBieXRlIGZpZWxkIGlkZW50aWZpZWQgYnkge0Bjb2RlIG5hbWV9IHRvIHRoZQorICAgICAgICAgKiBwZXJzaXN0ZW50IGZpZWxkLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gbmFtZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBzZXJpYWxpemUuCisgICAgICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0aGF0IGlzIHB1dCB0byB0aGUgcGVyc2lzdGVudCBmaWVsZC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHB1dChTdHJpbmcgbmFtZSwgYnl0ZSB2YWx1ZSk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFB1dHMgdGhlIHZhbHVlIG9mIHRoZSBzaG9ydCBmaWVsZCBpZGVudGlmaWVkIGJ5IHtAY29kZSBuYW1lfSB0byB0aGUKKyAgICAgICAgICogcGVyc2lzdGVudCBmaWVsZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG5hbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZmllbGQgdG8gc2VyaWFsaXplLgorICAgICAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdGhhdCBpcyBwdXQgdG8gdGhlIHBlcnNpc3RlbnQgZmllbGQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBwdXQoU3RyaW5nIG5hbWUsIHNob3J0IHZhbHVlKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogUHV0cyB0aGUgdmFsdWUgb2YgdGhlIGludGVnZXIgZmllbGQgaWRlbnRpZmllZCBieSB7QGNvZGUgbmFtZX0gdG8gdGhlCisgICAgICAgICAqIHBlcnNpc3RlbnQgZmllbGQuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBuYW1lCisgICAgICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIHNlcmlhbGl6ZS4KKyAgICAgICAgICogQHBhcmFtIHZhbHVlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRoYXQgaXMgcHV0IHRvIHRoZSBwZXJzaXN0ZW50IGZpZWxkLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcHV0KFN0cmluZyBuYW1lLCBpbnQgdmFsdWUpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBQdXRzIHRoZSB2YWx1ZSBvZiB0aGUgbG9uZyBmaWVsZCBpZGVudGlmaWVkIGJ5IHtAY29kZSBuYW1lfSB0byB0aGUKKyAgICAgICAgICogcGVyc2lzdGVudCBmaWVsZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG5hbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZmllbGQgdG8gc2VyaWFsaXplLgorICAgICAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdGhhdCBpcyBwdXQgdG8gdGhlIHBlcnNpc3RlbnQgZmllbGQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBwdXQoU3RyaW5nIG5hbWUsIGxvbmcgdmFsdWUpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBQdXRzIHRoZSB2YWx1ZSBvZiB0aGUgZmxvYXQgZmllbGQgaWRlbnRpZmllZCBieSB7QGNvZGUgbmFtZX0gdG8gdGhlCisgICAgICAgICAqIHBlcnNpc3RlbnQgZmllbGQuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBuYW1lCisgICAgICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIHNlcmlhbGl6ZS4KKyAgICAgICAgICogQHBhcmFtIHZhbHVlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRoYXQgaXMgcHV0IHRvIHRoZSBwZXJzaXN0ZW50IGZpZWxkLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcHV0KFN0cmluZyBuYW1lLCBmbG9hdCB2YWx1ZSk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFB1dHMgdGhlIHZhbHVlIG9mIHRoZSBkb3VibGUgZmllbGQgaWRlbnRpZmllZCBieSB7QGNvZGUgbmFtZX0gdG8gdGhlCisgICAgICAgICAqIHBlcnNpc3RlbnQgZmllbGQuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBuYW1lCisgICAgICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIHNlcmlhbGl6ZS4KKyAgICAgICAgICogQHBhcmFtIHZhbHVlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRoYXQgaXMgcHV0IHRvIHRoZSBwZXJzaXN0ZW50IGZpZWxkLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcHV0KFN0cmluZyBuYW1lLCBkb3VibGUgdmFsdWUpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBQdXRzIHRoZSB2YWx1ZSBvZiB0aGUgT2JqZWN0IGZpZWxkIGlkZW50aWZpZWQgYnkge0Bjb2RlIG5hbWV9IHRvIHRoZQorICAgICAgICAgKiBwZXJzaXN0ZW50IGZpZWxkLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gbmFtZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBzZXJpYWxpemUuCisgICAgICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0aGF0IGlzIHB1dCB0byB0aGUgcGVyc2lzdGVudCBmaWVsZC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHB1dChTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogV3JpdGVzIHRoZSBmaWVsZHMgdG8gdGhlIHRhcmdldCBzdHJlYW0ge0Bjb2RlIG91dH0uCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBvdXQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IHN0cmVhbQorICAgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBpcyB1bnNhZmUgYW5kIG1heSBjb3JydXB0IHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAgICAgKiAgICAgICAgICAgICBVc2UgT2JqZWN0T3V0cHV0U3RyZWFtI3dyaXRlRmllbGRzKCkgaW5zdGVhZC4KKyAgICAgICAgICovCisgICAgICAgIEBEZXByZWNhdGVkCisgICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHdyaXRlKE9iamVjdE91dHB1dCBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBPYmplY3RPdXRwdXRTdHJlYW19LiBUaGlzIGRlZmF1bHQgY29uc3RydWN0b3IgY2FuCisgICAgICogYmUgdXNlZCBieSBzdWJjbGFzc2VzIHRoYXQgZG8gbm90IHdhbnQgdG8gdXNlIHRoZSBwdWJsaWMgY29uc3RydWN0b3IgaWYKKyAgICAgKiBpdCBhbGxvY2F0ZXMgdW5uZWVkZWQgZGF0YS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hlbiBjcmVhdGluZyB0aGlzIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgT2JqZWN0T3V0cHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogV0FSTklORyAtIHdlIHNob3VsZCB0aHJvdyBJT0V4Y2VwdGlvbiBpZiBub3QgY2FsbGVkIGZyb20gYSBzdWJjbGFzcworICAgICAgICAgKiBhY2NvcmRpbmcgdG8gdGhlIEphdmFEb2MuIEFkZCB0aGUgdGVzdC4KKyAgICAgICAgICovCisgICAgICAgIHRoaXMuc3ViY2xhc3NPdmVycmlkaW5nSW1wbGVtZW50YXRpb24gPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtIHRoYXQgd3JpdGVzIHRvIHRoZSBPdXRwdXRTdHJlYW0KKyAgICAgKiB7QGNvZGUgb3V0cHV0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXRwdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBub24tbnVsbCBPdXRwdXRTdHJlYW0gdG8gZmlsdGVyIHdyaXRlcyBvbi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0aGUgb2JqZWN0IHN0cmVhbQorICAgICAqICAgICAgICAgICAgIGhlYWRlcgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3RPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG91dHB1dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5vdXRwdXQgPSAob3V0cHV0IGluc3RhbmNlb2YgRGF0YU91dHB1dFN0cmVhbSkgPyAoRGF0YU91dHB1dFN0cmVhbSkgb3V0cHV0CisgICAgICAgICAgICAgICAgOiBuZXcgRGF0YU91dHB1dFN0cmVhbShvdXRwdXQpOworICAgICAgICB0aGlzLmVuYWJsZVJlcGxhY2UgPSBmYWxzZTsKKyAgICAgICAgdGhpcy5wcm90b2NvbFZlcnNpb24gPSBQUk9UT0NPTF9WRVJTSU9OXzI7CisgICAgICAgIHRoaXMuc3ViY2xhc3NPdmVycmlkaW5nSW1wbGVtZW50YXRpb24gPSBmYWxzZTsKKworICAgICAgICByZXNldFN0YXRlKCk7CisgICAgICAgIHRoaXMubmVzdGVkRXhjZXB0aW9uID0gbmV3IFN0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbigpOworICAgICAgICAvLyBTbyB3cml0ZS4uLigpIG1ldGhvZHMgY2FuIGJlIHVzZWQgYnkKKyAgICAgICAgLy8gc3ViY2xhc3NlcyBkdXJpbmcgd3JpdGVTdHJlYW1IZWFkZXIoKQorICAgICAgICBwcmltaXRpdmVUeXBlcyA9IHRoaXMub3V0cHV0OworICAgICAgICAvLyBIYXMgdG8gYmUgZG9uZSBoZXJlIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbgorICAgICAgICB3cml0ZVN0cmVhbUhlYWRlcigpOworICAgICAgICBwcmltaXRpdmVUeXBlcyA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIG9wdGlvbmFsIGluZm9ybWF0aW9uIGZvciBjbGFzcyB7QGNvZGUgYUNsYXNzfSB0byB0aGUgb3V0cHV0CisgICAgICogc3RyZWFtLiBUaGlzIG9wdGlvbmFsIGRhdGEgY2FuIGJlIHJlYWQgd2hlbiBkZXNlcmlhbGl6aW5nIHRoZSBjbGFzcworICAgICAqIGRlc2NyaXB0b3IgKE9iamVjdFN0cmVhbUNsYXNzKSBmb3IgdGhpcyBjbGFzcyBmcm9tIGFuIGlucHV0IHN0cmVhbS4gQnkKKyAgICAgKiBkZWZhdWx0LCBubyBleHRyYSBkYXRhIGlzIHNhdmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGFDbGFzcworICAgICAqICAgICAgICAgICAgdGhlIGNsYXNzIHRvIGFubm90YXRlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKiBAc2VlIE9iamVjdElucHV0U3RyZWFtI3Jlc29sdmVDbGFzcyhPYmplY3RTdHJlYW1DbGFzcykKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBhbm5vdGF0ZUNsYXNzKENsYXNzPD8+IGFDbGFzcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQnkgZGVmYXVsdCBubyBleHRyYSBpbmZvIGlzIHNhdmVkLiBTdWJjbGFzc2VzIGNhbiBvdmVycmlkZQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBvcHRpb25hbCBpbmZvcm1hdGlvbiBmb3IgYSBwcm94eSBjbGFzcyB0byB0aGUgdGFyZ2V0IHN0cmVhbS4gVGhpcworICAgICAqIG9wdGlvbmFsIGRhdGEgY2FuIGJlIHJlYWQgd2hlbiBkZXNlcmlhbGl6aW5nIHRoZSBwcm94eSBjbGFzcyBmcm9tIGFuCisgICAgICogaW5wdXQgc3RyZWFtLiBCeSBkZWZhdWx0LCBubyBleHRyYSBkYXRhIGlzIHNhdmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGFDbGFzcworICAgICAqICAgICAgICAgICAgdGhlIHByb3h5IGNsYXNzIHRvIGFubm90YXRlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKiBAc2VlIE9iamVjdElucHV0U3RyZWFtI3Jlc29sdmVQcm94eUNsYXNzKFN0cmluZ1tdKQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGFubm90YXRlUHJveHlDbGFzcyhDbGFzczw/PiBhQ2xhc3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIEJ5IGRlZmF1bHQgbm8gZXh0cmEgaW5mbyBpcyBzYXZlZC4gU3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEbyB0aGUgbmVjZXNzYXJ5IHdvcmsgdG8gc2VlIGlmIHRoZSByZWNlaXZlciBjYW4gYmUgdXNlZCB0byB3cml0ZQorICAgICAqIHByaW1pdGl2ZSB0eXBlcyBsaWtlIGludCwgY2hhciwgZXRjLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjaGVja1dyaXRlUHJpbWl0aXZlVHlwZXMoKSB7CisgICAgICAgIGlmIChwcmltaXRpdmVUeXBlcyA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBJZiB3ZSBnb3QgaGVyZSB3ZSBoYXZlIG5vIFN0cmVhbSBwcmV2aW91c2x5IGNyZWF0ZWQKKyAgICAgICAgICAgIC8vIFdBUk5JTkcgLSBpZiB0aGUgc3RyZWFtIGRvZXMgbm90IGdyb3csIHRoaXMgY29kZSBpcyB3cm9uZworICAgICAgICAgICAgcHJpbWl0aXZlVHlwZXNCdWZmZXIgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKDEyOCk7CisgICAgICAgICAgICBwcmltaXRpdmVUeXBlcyA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKHByaW1pdGl2ZVR5cGVzQnVmZmVyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGlzIHN0cmVhbS4gQW55IGJ1ZmZlcmVkIGRhdGEgaXMgZmx1c2hlZC4gVGhpcyBpbXBsZW1lbnRhdGlvbgorICAgICAqIGNsb3NlcyB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY2xvc2luZyB0aGlzIHN0cmVhbS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIEZpcnN0IGZsdXNoIHdoYXQgaXMgbmVlZGVkIChwcmltaXRpdmUgZGF0YSwgZXRjKQorICAgICAgICBmbHVzaCgpOworICAgICAgICBvdXRwdXQuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlcyB0aGUgY29sbGVjdGlvbiBvZiBlbXVsYXRlZCBmaWVsZHMgdGhhdCB1c2VycyBjYW4gbWFuaXB1bGF0ZSB0bworICAgICAqIHN0b3JlIGEgcmVwcmVzZW50YXRpb24gZGlmZmVyZW50IHRoYW4gdGhlIG9uZSBkZWNsYXJlZCBieSB0aGUgY2xhc3Mgb2YKKyAgICAgKiB0aGUgb2JqZWN0IGJlaW5nIGR1bXBlZC4KKyAgICAgKgorICAgICAqIEBzZWUgI3dyaXRlRmllbGRzCisgICAgICogQHNlZSAjd3JpdGVGaWVsZFZhbHVlcyhFbXVsYXRlZEZpZWxkc0ZvckR1bXBpbmcpCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNvbXB1dGVQdXRGaWVsZCgpIHsKKyAgICAgICAgY3VycmVudFB1dEZpZWxkID0gbmV3IEVtdWxhdGVkRmllbGRzRm9yRHVtcGluZyh0aGlzLCBjdXJyZW50Q2xhc3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlZmF1bHQgbWV0aG9kIHRvIHdyaXRlIG9iamVjdHMgdG8gdGhpcyBzdHJlYW0uIFNlcmlhbGl6YWJsZSBmaWVsZHMKKyAgICAgKiBkZWZpbmVkIGluIHRoZSBvYmplY3QncyBjbGFzcyBhbmQgc3VwZXJjbGFzc2VzIGFyZSB3cml0dGVuIHRvIHRoZSBvdXRwdXQKKyAgICAgKiBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHRocm93cyBOb3RBY3RpdmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGZyb20ge0Bjb2RlIHdyaXRlT2JqZWN0KCl9LgorICAgICAqIEBzZWUgT2JqZWN0SW5wdXRTdHJlYW0jZGVmYXVsdFJlYWRPYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkZWZhdWx0V3JpdGVPYmplY3QoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY3VycmVudE9iamVjdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm90QWN0aXZlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgd3JpdGVGaWVsZFZhbHVlcyhjdXJyZW50T2JqZWN0LCBjdXJyZW50Q2xhc3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBidWZmZXJlZCBkYXRhIHRvIHRoZSB0YXJnZXQgc3RyZWFtLiBUaGlzIGlzIHNpbWlsYXIgdG8ge0Bjb2RlCisgICAgICogZmx1c2h9IGJ1dCB0aGUgZmx1c2ggaXMgbm90IHByb3BhZ2F0ZWQgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgZHJhaW4oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAocHJpbWl0aXZlVHlwZXMgPT0gbnVsbCB8fCBwcmltaXRpdmVUeXBlc0J1ZmZlciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICAvLyBJZiB3ZSBnb3QgaGVyZSB3ZSBoYXZlIGEgU3RyZWFtIHByZXZpb3VzbHkgY3JlYXRlZAorICAgICAgICBpbnQgb2Zmc2V0ID0gMDsKKyAgICAgICAgYnl0ZVtdIHdyaXR0ZW4gPSBwcmltaXRpdmVUeXBlc0J1ZmZlci50b0J5dGVBcnJheSgpOworICAgICAgICAvLyBOb3JtYWxpemUgdGhlIHByaW1pdGl2ZSBkYXRhCisgICAgICAgIHdoaWxlIChvZmZzZXQgPCB3cml0dGVuLmxlbmd0aCkgeworICAgICAgICAgICAgaW50IHRvV3JpdGUgPSB3cml0dGVuLmxlbmd0aCAtIG9mZnNldCA+IDEwMjQgPyAxMDI0CisgICAgICAgICAgICAgICAgICAgIDogd3JpdHRlbi5sZW5ndGggLSBvZmZzZXQ7CisgICAgICAgICAgICBpZiAodG9Xcml0ZSA8IDI1NikgeworICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUJ5dGUoVENfQkxPQ0tEQVRBKTsKKyAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVCeXRlKChieXRlKSB0b1dyaXRlKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlQnl0ZShUQ19CTE9DS0RBVEFMT05HKTsKKyAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVJbnQodG9Xcml0ZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIHdyaXRlIHByaW1pdGl2ZSB0eXBlcyB3ZSBoYWQgYW5kIHRoZSBtYXJrZXIgb2YgZW5kLW9mLWJ1ZmZlcgorICAgICAgICAgICAgb3V0cHV0LndyaXRlKHdyaXR0ZW4sIG9mZnNldCwgdG9Xcml0ZSk7CisgICAgICAgICAgICBvZmZzZXQgKz0gdG9Xcml0ZTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGFuZCBub3cgd2UncmUgY2xlYW4gdG8gYSBzdGF0ZSB3aGVyZSB3ZSBjYW4gd3JpdGUgYW4gb2JqZWN0CisgICAgICAgIHByaW1pdGl2ZVR5cGVzID0gbnVsbDsKKyAgICAgICAgcHJpbWl0aXZlVHlwZXNCdWZmZXIgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIER1bXBzIHRoZSBwYXJhbWV0ZXIge0Bjb2RlIG9ian0gb25seSBpZiBpdCBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKiBvciBhbiBvYmplY3QgdGhhdCBoYXMgYWxyZWFkeSBiZWVuIGR1bXBlZCBwcmV2aW91c2x5LgorICAgICAqCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgT2JqZWN0IHRvIGNoZWNrIGlmIGFuIGluc3RhbmNlIHByZXZpb3VzbHkgZHVtcGVkIGJ5IHRoaXMKKyAgICAgKiAgICAgICAgICAgIHN0cmVhbS4KKyAgICAgKiBAcmV0dXJuIC0xIGlmIGl0IGlzIGFuIGluc3RhbmNlIHdoaWNoIGhhcyBub3QgYmVlbiBkdW1wZWQgeWV0IChhbmQgdGhpcworICAgICAqICAgICAgICAgbWV0aG9kIGRvZXMgbm90aGluZykuIFRoZSBoYW5kbGUgaWYge0Bjb2RlIG9ian0gaXMgYW4KKyAgICAgKiAgICAgICAgIGluc3RhbmNlIHdoaWNoIGhhcyBiZWVuIGR1bXBlZCBhbHJlYWR5LgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFuIGVycm9yIG9jY3VycyBhdHRlbXB0aW5nIHRvIHNhdmUge0Bjb2RlIG51bGx9IG9yCisgICAgICogICAgICAgICAgICAgYSBjeWNsaWMgcmVmZXJlbmNlLgorICAgICAqLworICAgIHByaXZhdGUgaW50IGR1bXBDeWNsZShPYmplY3Qgb2JqKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBJZiB0aGUgb2JqZWN0IGhhcyBiZWVuIHNhdmVkIGFscmVhZHksIHNhdmUgaXRzIGhhbmRsZSBvbmx5CisgICAgICAgIGludCBoYW5kbGUgPSBvYmplY3RzV3JpdHRlbi5nZXQob2JqKTsKKyAgICAgICAgaWYgKGhhbmRsZSAhPSAtMSkgeworICAgICAgICAgICAgd3JpdGVDeWNsaWNSZWZlcmVuY2UoaGFuZGxlKTsKKyAgICAgICAgICAgIHJldHVybiBoYW5kbGU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuYWJsZXMgb2JqZWN0IHJlcGxhY2VtZW50IGZvciB0aGlzIHN0cmVhbS4gQnkgZGVmYXVsdCB0aGlzIGlzIG5vdAorICAgICAqIGVuYWJsZWQuIE9ubHkgdHJ1c3RlZCBzdWJjbGFzc2VzIChsb2FkZWQgd2l0aCBzeXN0ZW0gY2xhc3MgbG9hZGVyKSBhcmUKKyAgICAgKiBhbGxvd2VkIHRvIGNoYW5nZSB0aGlzIHN0YXR1cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbmFibGUKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSB0cnVlfSB0byBlbmFibGUgb2JqZWN0IHJlcGxhY2VtZW50OyB7QGNvZGUgZmFsc2V9IHRvCisgICAgICogICAgICAgICAgICBkaXNhYmxlIGl0LgorICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIHNldHRpbmcuCisgICAgICogQHNlZSAjcmVwbGFjZU9iamVjdAorICAgICAqIEBzZWUgT2JqZWN0SW5wdXRTdHJlYW0jZW5hYmxlUmVzb2x2ZU9iamVjdAorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGVuYWJsZVJlcGxhY2VPYmplY3QoYm9vbGVhbiBlbmFibGUpIHsKKyAgICAgICAgYm9vbGVhbiBvcmlnaW5hbFZhbHVlID0gZW5hYmxlUmVwbGFjZTsKKyAgICAgICAgZW5hYmxlUmVwbGFjZSA9IGVuYWJsZTsKKyAgICAgICAgcmV0dXJuIG9yaWdpbmFsVmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGJ1ZmZlcmVkIGRhdGEgdG8gdGhlIHRhcmdldCBzdHJlYW0gYW5kIGNhbGxzIHRoZSB7QGNvZGUgZmx1c2h9CisgICAgICogbWV0aG9kIG9mIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIG9yIGZsdXNoaW5nIHRoZSBvdXRwdXQKKyAgICAgKiAgICAgICAgICAgICBzdHJlYW0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBkcmFpbigpOworICAgICAgICBvdXRwdXQuZmx1c2goKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFRoZXNlIG1ldGhvZHMgZ2V0IHRoZSB2YWx1ZSBvZiBhIGZpZWxkIG5hbWVkIGZpZWxkTmFtZSBvZiBvYmplY3QKKyAgICAgKiBpbnN0YW5jZS4gVGhlIGZpZWxkIGlzIGRlY2xhcmVkIGJ5IGRlY2xhcmluZ0NsYXNzLiBUaGUgZmllbGQgaXMgdGhlIHNhbWUKKyAgICAgKiB0eXBlIGFzIHRoZSBtZXRob2QgcmV0dXJuIHZhbHVlLgorICAgICAqCisgICAgICogdGhlc2UgbWV0aG9kcyBjb3VsZCBiZSBpbXBsZW1lbnRlZCBub24tbmF0aXZlbHkgb24gdG9wIG9mCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QgYXQgdGhlIGV4cGVuc2Ugb2YgZXh0cmEgb2JqZWN0IGNyZWF0aW9uCisgICAgICogKGphdmEubGFuZy5yZWZsZWN0LkZpZWxkKS4gT3RoZXJ3aXNlIFNlcmlhbGl6YXRpb24gY291bGQgbm90IGZldGNoCisgICAgICogcHJpdmF0ZSBmaWVsZHMsIGV4Y2VwdCBieSB0aGUgdXNlIG9mIGEgbmF0aXZlIG1ldGhvZCBsaWtlIHRoaXMgb25lLgorICAgICAqCisgICAgICogQHRocm93cyBOb1N1Y2hGaWVsZEVycm9yIElmIHRoZSBmaWVsZCBkb2VzIG5vdCBleGlzdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgT2JqZWN0IGdldEZpZWxkTChPYmplY3QgaW5zdGFuY2UsIENsYXNzPD8+IGRlY2xhcmluZ0NsYXNzLCBTdHJpbmcgZmllbGROYW1lLCBTdHJpbmcgZmllbGRUeXBlTmFtZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG5leHQgaGFuZGxlIHRvIGJlIHVzZWQgdG8gaW5kaWNhdGUgY3ljbGljCisgICAgICogcmVmZXJlbmNlcyBiZWluZyBzYXZlZCB0byB0aGUgc3RyZWFtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBoYW5kbGUgdG8gcmVwcmVzZW50IHRoZSBuZXh0IGN5Y2xpYyByZWZlcmVuY2UKKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBuZXh0SGFuZGxlKCkgeworICAgICAgICByZXR1cm4gY3VycmVudEhhbmRsZSsrOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhpcyBzdHJlYW0ncyB7QGNvZGUgUHV0RmllbGR9IG9iamVjdC4gVGhpcyBvYmplY3QgcHJvdmlkZXMgYWNjZXNzCisgICAgICogdG8gdGhlIHBlcnNpc3RlbnQgZmllbGRzIHRoYXQgYXJlIGV2ZW50dWFsbHkgd3JpdHRlbiB0byB0aGUgb3V0cHV0CisgICAgICogc3RyZWFtLiBJdCBpcyB1c2VkIHRvIHRyYW5zZmVyIHRoZSB2YWx1ZXMgZnJvbSB0aGUgZmllbGRzIG9mIHRoZSBvYmplY3QKKyAgICAgKiB0aGF0IGlzIGN1cnJlbnRseSBiZWluZyB3cml0dGVuIHRvIHRoZSBwZXJzaXN0ZW50IGZpZWxkcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIFB1dEZpZWxkIG9iamVjdCBmcm9tIHdoaWNoIHBlcnNpc3RlbnQgZmllbGRzIGNhbiBiZSBhY2Nlc3NlZAorICAgICAqICAgICAgICAgYnkgbmFtZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAdGhyb3dzIE5vdEFjdGl2ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbWV0aG9kIGlzIG5vdCBjYWxsZWQgZnJvbSB7QGNvZGUgd3JpdGVPYmplY3QoKX0uCisgICAgICogQHNlZSBPYmplY3RJbnB1dFN0cmVhbSNkZWZhdWx0UmVhZE9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBQdXRGaWVsZCBwdXRGaWVsZHMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY3VycmVudE9iamVjdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm90QWN0aXZlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGN1cnJlbnRQdXRGaWVsZCA9PSBudWxsKSB7CisgICAgICAgICAgICBjb21wdXRlUHV0RmllbGQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY3VycmVudFB1dEZpZWxkOworICAgIH0KKworICAgIHByaXZhdGUgaW50IHJlZ2lzdGVyT2JqZWN0V3JpdHRlbihPYmplY3Qgb2JqKSB7CisgICAgICAgIGludCBoYW5kbGUgPSBuZXh0SGFuZGxlKCk7CisgICAgICAgIG9iamVjdHNXcml0dGVuLnB1dChvYmosIGhhbmRsZSk7CisgICAgICAgIHJldHVybiBoYW5kbGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlIHRoZSB1bnNoYXJlZCBvYmplY3QgZnJvbSB0aGUgdGFibGUsIGFuZCByZXN0b3JlIGFueSBwcmV2aW91cworICAgICAqIGhhbmRsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIE5vbi1udWxsIG9iamVjdCBiZWluZyBkdW1wZWQuCisgICAgICogQHBhcmFtIHByZXZpb3VzSGFuZGxlCisgICAgICogICAgICAgICAgICBUaGUgaGFuZGxlIG9mIHRoZSBwcmV2aW91cyBpZGVudGljYWwgb2JqZWN0IGR1bXBlZAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZW1vdmVVbnNoYXJlZFJlZmVyZW5jZShPYmplY3Qgb2JqLCBpbnQgcHJldmlvdXNIYW5kbGUpIHsKKyAgICAgICAgaWYgKHByZXZpb3VzSGFuZGxlICE9IC0xKSB7CisgICAgICAgICAgICBvYmplY3RzV3JpdHRlbi5wdXQob2JqLCBwcmV2aW91c0hhbmRsZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBvYmplY3RzV3JpdHRlbi5yZW1vdmUob2JqKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFsbG93cyB0cnVzdGVkIHN1YmNsYXNzZXMgdG8gc3Vic3RpdHV0ZSB0aGUgc3BlY2lmaWVkIG9yaWdpbmFsIHtAY29kZQorICAgICAqIG9iamVjdH0gd2l0aCBhIG5ldyBvYmplY3QuIE9iamVjdCBzdWJzdGl0dXRpb24gaGFzIHRvIGJlIGFjdGl2YXRlZCBmaXJzdAorICAgICAqIHdpdGggY2FsbGluZyB7QGNvZGUgZW5hYmxlUmVwbGFjZU9iamVjdCh0cnVlKX0uIFRoaXMgaW1wbGVtZW50YXRpb24ganVzdAorICAgICAqIHJldHVybnMge0Bjb2RlIG9iamVjdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb3JpZ2luYWwgb2JqZWN0IGZvciB3aGljaCBhIHJlcGxhY2VtZW50IG1heSBiZSBkZWZpbmVkLgorICAgICAqIEByZXR1cm4gdGhlIHJlcGxhY2VtZW50IG9iamVjdCBmb3Ige0Bjb2RlIG9iamVjdH0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIGNyZWF0aW5nIHRoZSByZXBsYWNlbWVudAorICAgICAqICAgICAgICAgICAgIG9iamVjdC4KKyAgICAgKiBAc2VlICNlbmFibGVSZXBsYWNlT2JqZWN0CisgICAgICogQHNlZSBPYmplY3RJbnB1dFN0cmVhbSNlbmFibGVSZXNvbHZlT2JqZWN0CisgICAgICogQHNlZSBPYmplY3RJbnB1dFN0cmVhbSNyZXNvbHZlT2JqZWN0CisgICAgICovCisgICAgcHJvdGVjdGVkIE9iamVjdCByZXBsYWNlT2JqZWN0KE9iamVjdCBvYmplY3QpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIEJ5IGRlZmF1bHQgbm8gb2JqZWN0IHJlcGxhY2VtZW50LiBTdWJjbGFzc2VzIGNhbiBvdmVycmlkZQorICAgICAgICByZXR1cm4gb2JqZWN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0cyB0aGUgc3RhdGUgb2YgdGhpcyBzdHJlYW0uIEEgbWFya2VyIGlzIHdyaXR0ZW4gdG8gdGhlIHN0cmVhbSwgc28KKyAgICAgKiB0aGF0IHRoZSBjb3JyZXNwb25kaW5nIGlucHV0IHN0cmVhbSB3aWxsIGFsc28gcGVyZm9ybSBhIHJlc2V0IGF0IHRoZSBzYW1lCisgICAgICogcG9pbnQuIE9iamVjdHMgcHJldmlvdXNseSB3cml0dGVuIGFyZSBubyBsb25nZXIgcmVtZW1iZXJlZCwgc28gdGhleSB3aWxsCisgICAgICogYmUgd3JpdHRlbiBhZ2FpbiAoaW5zdGVhZCBvZiBhIGN5Y2xpY2FsIHJlZmVyZW5jZSkgaWYgZm91bmQgaW4gdGhlIG9iamVjdAorICAgICAqIGdyYXBoLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSByZXNldCgpfSBpcyBjYWxsZWQgZHVyaW5nIHRoZSBzZXJpYWxpemF0aW9uIG9mIGFuCisgICAgICogICAgICAgICAgICAgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gRmlyc3Qgd2UgZmx1c2ggd2hhdCB3ZSBoYXZlCisgICAgICAgIGRyYWluKCk7CisgICAgICAgIC8qCisgICAgICAgICAqIEFuZCBkdW1wIGEgcmVzZXQgbWFya2VyLCBzbyB0aGF0IHRoZSBPYmplY3RJbnB1dFN0cmVhbSBjYW4gcmVzZXQKKyAgICAgICAgICogaXRzZWxmIGF0IHRoZSBzYW1lIHBvaW50CisgICAgICAgICAqLworICAgICAgICBvdXRwdXQud3JpdGVCeXRlKFRDX1JFU0VUKTsKKyAgICAgICAgLy8gTm93IHdlIHJlc2V0IG91cnNlbHZlcworICAgICAgICByZXNldFN0YXRlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzZXQgdGhlIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cyBhbHJlYWR5IGR1bXBlZCBieSB0aGUgcmVjZWl2ZXIuIElmIHRoZQorICAgICAqIG9iamVjdHMgYXJlIGZvdW5kIGFnYWluIGluIHRoZSBvYmplY3QgZ3JhcGgsIHRoZSByZWNlaXZlciB3aWxsIGR1bXAgdGhlbQorICAgICAqIGFnYWluLCBpbnN0ZWFkIG9mIGEgaGFuZGxlIChjeWNsaWMgcmVmZXJlbmNlKS4KKyAgICAgKgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZXNldFNlZW5PYmplY3RzKCkgeworICAgICAgICBvYmplY3RzV3JpdHRlbiA9IG5ldyBTZXJpYWxpemF0aW9uSGFuZGxlTWFwKCk7CisgICAgICAgIGN1cnJlbnRIYW5kbGUgPSBiYXNlV2lyZUhhbmRsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldCB0aGUgcmVjZWl2ZXIuIFRoZSBjb2xsZWN0aW9uIG9mIG9iamVjdHMgYWxyZWFkeSBkdW1wZWQgYnkgdGhlCisgICAgICogcmVjZWl2ZXIgaXMgcmVzZXQsIGFuZCBpbnRlcm5hbCBzdHJ1Y3R1cmVzIGFyZSBhbHNvIHJlc2V0IHNvIHRoYXQgdGhlCisgICAgICogcmVjZWl2ZXIga25vd3MgaXQgaXMgaW4gYSBmcmVzaCBjbGVhbiBzdGF0ZS4KKyAgICAgKgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZXNldFN0YXRlKCkgeworICAgICAgICByZXNldFNlZW5PYmplY3RzKCk7CisgICAgICAgIG5lc3RlZExldmVscyA9IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc3BlY2lmaWVkIHByb3RvY29sIHZlcnNpb24gdG8gYmUgdXNlZCBieSB0aGlzIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2ZXJzaW9uCisgICAgICogICAgICAgICAgICB0aGUgcHJvdG9jb2wgdmVyc2lvbiB0byBiZSB1c2VkLiBVc2UgYSB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFBST1RPQ09MX1ZFUlNJT05feH0gY29uc3RhbnQgZnJvbSB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIGphdmEuaW8uT2JqZWN0U3RyZWFtQ29uc3RhbnRzfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGludmFsaWQge0Bjb2RlIHZlcnNpb259IGlzIHNwZWNpZmllZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlIE9iamVjdFN0cmVhbUNvbnN0YW50cyNQUk9UT0NPTF9WRVJTSU9OXzEKKyAgICAgKiBAc2VlIE9iamVjdFN0cmVhbUNvbnN0YW50cyNQUk9UT0NPTF9WRVJTSU9OXzIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1c2VQcm90b2NvbFZlcnNpb24oaW50IHZlcnNpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghb2JqZWN0c1dyaXR0ZW4uaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDYW5ub3Qgc2V0IHByb3RvY29sIHZlcnNpb24gd2hlbiBzdHJlYW0gaW4gdXNlIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHZlcnNpb24gIT0gT2JqZWN0U3RyZWFtQ29uc3RhbnRzLlBST1RPQ09MX1ZFUlNJT05fMQorICAgICAgICAgICAgICAgICYmIHZlcnNpb24gIT0gT2JqZWN0U3RyZWFtQ29uc3RhbnRzLlBST1RPQ09MX1ZFUlNJT05fMikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVW5rbm93biBwcm90b2NvbDogIiArIHZlcnNpb24pOworICAgICAgICB9CisgICAgICAgIHByb3RvY29sVmVyc2lvbiA9IHZlcnNpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHtAY29kZSBjb3VudH0gYnl0ZXMgZnJvbSB0aGUgYnl0ZSBhcnJheSB7QGNvZGUgYnVmZmVyfSBzdGFydGluZyBhdAorICAgICAqIG9mZnNldCB7QGNvZGUgaW5kZXh9IHRvIHRoZSB0YXJnZXQgc3RyZWFtLiBCbG9ja3MgdW50aWwgYWxsIGJ5dGVzIGFyZQorICAgICAqIHdyaXR0ZW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgYnl0ZSBpbiB7QGNvZGUgYnVmZmVyfSB0byB3cml0ZS4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIGZyb20ge0Bjb2RlIGJ1ZmZlcn0gdG8gd3JpdGUgdG8gdGhlIG91dHB1dAorICAgICAqICAgICAgICAgICAgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja1dyaXRlUHJpbWl0aXZlVHlwZXMoKTsKKyAgICAgICAgcHJpbWl0aXZlVHlwZXMud3JpdGUoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgc2luZ2xlIGJ5dGUgdG8gdGhlIHRhcmdldCBzdHJlYW0uIE9ubHkgdGhlIGxlYXN0IHNpZ25pZmljYW50CisgICAgICogYnl0ZSBvZiB0aGUgaW50ZWdlciB7QGNvZGUgdmFsdWV9IGlzIHdyaXR0ZW4gdG8gdGhlIHN0cmVhbS4gQmxvY2tzIHVudGlsCisgICAgICogdGhlIGJ5dGUgaXMgYWN0dWFsbHkgd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tXcml0ZVByaW1pdGl2ZVR5cGVzKCk7CisgICAgICAgIHByaW1pdGl2ZVR5cGVzLndyaXRlKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBib29sZWFuIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgYm9vbGVhbiB2YWx1ZSB0byB3cml0ZSB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVCb29sZWFuKGJvb2xlYW4gdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrV3JpdGVQcmltaXRpdmVUeXBlcygpOworICAgICAgICBwcmltaXRpdmVUeXBlcy53cml0ZUJvb2xlYW4odmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGJ5dGUgKDggYml0KSB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgdG8gd3JpdGUgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlQnl0ZShpbnQgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrV3JpdGVQcmltaXRpdmVUeXBlcygpOworICAgICAgICBwcmltaXRpdmVUeXBlcy53cml0ZUJ5dGUodmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3RyaW5nIHtAY29kZSB2YWx1ZX0gYXMgYSBzZXF1ZW5jZSBvZiBieXRlcyB0byB0aGUgdGFyZ2V0CisgICAgICogc3RyZWFtLiBPbmx5IHRoZSBsZWFzdCBzaWduaWZpY2FudCBieXRlIG9mIGVhY2ggY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcKKyAgICAgKiBpcyB3cml0dGVuLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHdyaXRlIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZUJ5dGVzKFN0cmluZyB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tXcml0ZVByaW1pdGl2ZVR5cGVzKCk7CisgICAgICAgIHByaW1pdGl2ZVR5cGVzLndyaXRlQnl0ZXModmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGNoYXJhY3RlciAoMTYgYml0KSB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byB3cml0ZSB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVDaGFyKGludCB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tXcml0ZVByaW1pdGl2ZVR5cGVzKCk7CisgICAgICAgIHByaW1pdGl2ZVR5cGVzLndyaXRlQ2hhcih2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBzdHJpbmcge0Bjb2RlIHZhbHVlfSBhcyBhIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgdG8gdGhlIHRhcmdldAorICAgICAqIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB3cml0ZSB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVDaGFycyhTdHJpbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrV3JpdGVQcmltaXRpdmVUeXBlcygpOworICAgICAgICBwcmltaXRpdmVUeXBlcy53cml0ZUNoYXJzKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhIGNsYXNzIGRlc2NyaXB0b3Ige0Bjb2RlIGNsYXNzRGVzY30gKGFuCisgICAgICoge0Bjb2RlIE9iamVjdFN0cmVhbUNsYXNzfSkgdG8gdGhlIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbGFzc0Rlc2MKKyAgICAgKiAgICAgICAgICAgIFRoZSBjbGFzcyBkZXNjcmlwdG9yIChhbiB7QGNvZGUgT2JqZWN0U3RyZWFtQ2xhc3N9KSB0bworICAgICAqICAgICAgICAgICAgYmUgZHVtcGVkCisgICAgICogQHBhcmFtIHVuc2hhcmVkCisgICAgICogICAgICAgICAgICBXcml0ZSB0aGUgb2JqZWN0IHVuc2hhcmVkCisgICAgICogQHJldHVybiB0aGUgaGFuZGxlIGFzc2lnbmVkIHRvIHRoZSBjbGFzcyBkZXNjcmlwdG9yCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXhjZXB0aW9uIGhhcHBlbmVkIHdoZW4gd3JpdGluZyB0aGUgY2xhc3MKKyAgICAgKiAgICAgICAgICAgICBkZXNjcmlwdG9yLgorICAgICAqLworICAgIHByaXZhdGUgaW50IHdyaXRlQ2xhc3NEZXNjKE9iamVjdFN0cmVhbUNsYXNzIGNsYXNzRGVzYywgYm9vbGVhbiB1bnNoYXJlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNsYXNzRGVzYyA9PSBudWxsKSB7CisgICAgICAgICAgICB3cml0ZU51bGwoKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBpbnQgaGFuZGxlID0gLTE7CisgICAgICAgIGlmICghdW5zaGFyZWQpIHsKKyAgICAgICAgICAgIGhhbmRsZSA9IGR1bXBDeWNsZShjbGFzc0Rlc2MpOworICAgICAgICB9CisgICAgICAgIGlmIChoYW5kbGUgPT0gLTEpIHsKKyAgICAgICAgICAgIENsYXNzPD8+IGNsYXNzVG9Xcml0ZSA9IGNsYXNzRGVzYy5mb3JDbGFzcygpOworICAgICAgICAgICAgaW50IHByZXZpb3VzSGFuZGxlID0gLTE7CisgICAgICAgICAgICBpZiAodW5zaGFyZWQpIHsKKyAgICAgICAgICAgICAgICBwcmV2aW91c0hhbmRsZSA9IG9iamVjdHNXcml0dGVuLmdldChjbGFzc0Rlc2MpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gSWYgd2UgZ290IGhlcmUsIGl0IGlzIGEgbmV3IChub24tbnVsbCkgY2xhc3NEZXNjIHRoYXQgd2lsbCBoYXZlCisgICAgICAgICAgICAvLyB0byBiZSByZWdpc3RlcmVkIGFzIHdlbGwKKyAgICAgICAgICAgIGhhbmRsZSA9IHJlZ2lzdGVyT2JqZWN0V3JpdHRlbihjbGFzc0Rlc2MpOworCisgICAgICAgICAgICBpZiAoY2xhc3NEZXNjLmlzUHJveHkoKSkgeworICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUJ5dGUoVENfUFJPWFlDTEFTU0RFU0MpOworICAgICAgICAgICAgICAgIENsYXNzPD8+W10gaW50ZXJmYWNlcyA9IGNsYXNzVG9Xcml0ZS5nZXRJbnRlcmZhY2VzKCk7CisgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlSW50KGludGVyZmFjZXMubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludGVyZmFjZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlVVRGKGludGVyZmFjZXNbaV0uZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYW5ub3RhdGVQcm94eUNsYXNzKGNsYXNzVG9Xcml0ZSk7CisgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlQnl0ZShUQ19FTkRCTE9DS0RBVEEpOworICAgICAgICAgICAgICAgIHdyaXRlQ2xhc3NEZXNjKHByb3h5Q2xhc3NEZXNjLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgaWYgKHVuc2hhcmVkKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSByZWZlcmVuY2UgdG8gdW5zaGFyZWQgb2JqZWN0CisgICAgICAgICAgICAgICAgICAgIHJlbW92ZVVuc2hhcmVkUmVmZXJlbmNlKGNsYXNzRGVzYywgcHJldmlvdXNIYW5kbGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBvdXRwdXQud3JpdGVCeXRlKFRDX0NMQVNTREVTQyk7CisgICAgICAgICAgICBpZiAocHJvdG9jb2xWZXJzaW9uID09IFBST1RPQ09MX1ZFUlNJT05fMSkgeworICAgICAgICAgICAgICAgIHdyaXRlTmV3Q2xhc3NEZXNjKGNsYXNzRGVzYyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIFNvIHdyaXRlLi4uKCkgbWV0aG9kcyBjYW4gYmUgdXNlZCBieQorICAgICAgICAgICAgICAgIC8vIHN1YmNsYXNzZXMgZHVyaW5nIHdyaXRlQ2xhc3NEZXNjcmlwdG9yKCkKKyAgICAgICAgICAgICAgICBwcmltaXRpdmVUeXBlcyA9IG91dHB1dDsKKyAgICAgICAgICAgICAgICB3cml0ZUNsYXNzRGVzY3JpcHRvcihjbGFzc0Rlc2MpOworICAgICAgICAgICAgICAgIHByaW1pdGl2ZVR5cGVzID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIEV4dHJhIGNsYXNzIGluZm8gKG9wdGlvbmFsKQorICAgICAgICAgICAgYW5ub3RhdGVDbGFzcyhjbGFzc1RvV3JpdGUpOworICAgICAgICAgICAgZHJhaW4oKTsgLy8gZmx1c2ggcHJpbWl0aXZlIHR5cGVzIGluIHRoZSBhbm5vdGF0aW9uCisgICAgICAgICAgICBvdXRwdXQud3JpdGVCeXRlKFRDX0VOREJMT0NLREFUQSk7CisgICAgICAgICAgICB3cml0ZUNsYXNzRGVzYyhjbGFzc0Rlc2MuZ2V0U3VwZXJjbGFzcygpLCB1bnNoYXJlZCk7CisgICAgICAgICAgICBpZiAodW5zaGFyZWQpIHsKKyAgICAgICAgICAgICAgICAvLyByZW1vdmUgcmVmZXJlbmNlIHRvIHVuc2hhcmVkIG9iamVjdAorICAgICAgICAgICAgICAgIHJlbW92ZVVuc2hhcmVkUmVmZXJlbmNlKGNsYXNzRGVzYywgcHJldmlvdXNIYW5kbGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBoYW5kbGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgaGFuZGxlIHJlcHJlc2VudGluZyBhIGN5Y2xpYyByZWZlcmVuY2UgKG9iamVjdCBwcmV2aW91c2x5CisgICAgICogZHVtcGVkKS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVDeWNsaWNSZWZlcmVuY2UoaW50IGhhbmRsZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0cHV0LndyaXRlQnl0ZShUQ19SRUZFUkVOQ0UpOworICAgICAgICBvdXRwdXQud3JpdGVJbnQoaGFuZGxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBkb3VibGUgKDY0IGJpdCkgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb3VibGUgdG8gd3JpdGUgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlRG91YmxlKGRvdWJsZSB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tXcml0ZVByaW1pdGl2ZVR5cGVzKCk7CisgICAgICAgIHByaW1pdGl2ZVR5cGVzLndyaXRlRG91YmxlKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBjb2xsZWN0aW9uIG9mIGZpZWxkIGRlc2NyaXB0b3JzIChuYW1lLCB0eXBlIG5hbWUsIGV0YykgZm9yIHRoZQorICAgICAqIGNsYXNzIGRlc2NyaXB0b3Ige0Bjb2RlIGNsYXNzRGVzY30gKGFuCisgICAgICoge0Bjb2RlIE9iamVjdFN0cmVhbUNsYXNzfSkKKyAgICAgKgorICAgICAqIEBwYXJhbSBjbGFzc0Rlc2MKKyAgICAgKiAgICAgICAgICAgIFRoZSBjbGFzcyBkZXNjcmlwdG9yIChhbiB7QGNvZGUgT2JqZWN0U3RyZWFtQ2xhc3N9KQorICAgICAqICAgICAgICAgICAgZm9yIHdoaWNoIHRvIHdyaXRlIGZpZWxkIGluZm9ybWF0aW9uCisgICAgICogQHBhcmFtIGV4dGVybmFsaXphYmxlCisgICAgICogICAgICAgICAgICB0cnVlIGlmIHRoZSBkZXNjcmlwdG9ycyBhcmUgZXh0ZXJuYWxpemFibGUKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBleGNlcHRpb24gaGFwcGVuZWQgd2hlbiB3cml0aW5nIHRoZSBmaWVsZAorICAgICAqICAgICAgICAgICAgIGRlc2NyaXB0b3JzLgorICAgICAqCisgICAgICogQHNlZSAjd3JpdGVPYmplY3QoT2JqZWN0KQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB3cml0ZUZpZWxkRGVzY3JpcHRvcnMoT2JqZWN0U3RyZWFtQ2xhc3MgY2xhc3NEZXNjLCBib29sZWFuIGV4dGVybmFsaXphYmxlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBDbGFzczw/PiBsb2FkZWRDbGFzcyA9IGNsYXNzRGVzYy5mb3JDbGFzcygpOworICAgICAgICBPYmplY3RTdHJlYW1GaWVsZFtdIGZpZWxkcyA9IG51bGw7CisgICAgICAgIGludCBmaWVsZENvdW50ID0gMDsKKworICAgICAgICAvLyBUaGUgZmllbGRzIG9mIFN0cmluZyBhcmUgbm90IG5lZWRlZCBzaW5jZSBTdHJpbmdzIGFyZSB0cmVhdGVkIGFzCisgICAgICAgIC8vIHByaW1pdGl2ZSB0eXBlcworICAgICAgICBpZiAoIWV4dGVybmFsaXphYmxlICYmIGxvYWRlZENsYXNzICE9IE9iamVjdFN0cmVhbUNsYXNzLlNUUklOR0NMQVNTKSB7CisgICAgICAgICAgICBmaWVsZHMgPSBjbGFzc0Rlc2MuZmllbGRzKCk7CisgICAgICAgICAgICBmaWVsZENvdW50ID0gZmllbGRzLmxlbmd0aDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEZpZWxkIGNvdW50CisgICAgICAgIG91dHB1dC53cml0ZVNob3J0KGZpZWxkQ291bnQpOworICAgICAgICAvLyBGaWVsZCBuYW1lcworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkQ291bnQ7IGkrKykgeworICAgICAgICAgICAgT2JqZWN0U3RyZWFtRmllbGQgZiA9IGZpZWxkc1tpXTsKKyAgICAgICAgICAgIGJvb2xlYW4gd2FzUHJpbWl0aXZlID0gZi53cml0ZUZpZWxkKG91dHB1dCk7CisgICAgICAgICAgICBpZiAoIXdhc1ByaW1pdGl2ZSkgeworICAgICAgICAgICAgICAgIHdyaXRlT2JqZWN0KGYuZ2V0VHlwZVN0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgZmllbGRzIG9mIHRoZSBvYmplY3QgY3VycmVudGx5IGJlaW5nIHdyaXR0ZW4gdG8gdGhlIHRhcmdldAorICAgICAqIHN0cmVhbS4gVGhlIGZpZWxkIHZhbHVlcyBhcmUgYnVmZmVyZWQgaW4gdGhlIGN1cnJlbnRseSBhY3RpdmUge0Bjb2RlCisgICAgICogUHV0RmllbGR9IG9iamVjdCwgd2hpY2ggY2FuIGJlIGFjY2Vzc2VkIGJ5IGNhbGxpbmcge0Bjb2RlIHB1dEZpZWxkcygpfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIE5vdEFjdGl2ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGFyZSBubyBmaWVsZHMgdG8gd3JpdGUgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHNlZSAjcHV0RmllbGRzCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVGaWVsZHMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBIYXMgdG8gaGF2ZSBmaWVsZHMgdG8gd3JpdGUKKyAgICAgICAgaWYgKGN1cnJlbnRQdXRGaWVsZCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm90QWN0aXZlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgd3JpdGVGaWVsZFZhbHVlcyhjdXJyZW50UHV0RmllbGQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGNvbGxlY3Rpb24gb2YgZmllbGQgdmFsdWVzIGZvciB0aGUgZW11bGF0ZWQgZmllbGRzCisgICAgICoge0Bjb2RlIGVtdWxhdGVkRmllbGRzfQorICAgICAqCisgICAgICogQHBhcmFtIGVtdWxhdGVkRmllbGRzCisgICAgICogICAgICAgICAgICBhbiB7QGNvZGUgRW11bGF0ZWRGaWVsZHNGb3JEdW1waW5nfSwgY29uY3JldGUgc3ViY2xhc3MKKyAgICAgKiAgICAgICAgICAgIG9mIHtAY29kZSBQdXRGaWVsZH0KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBleGNlcHRpb24gaGFwcGVuZWQgd2hlbiB3cml0aW5nIHRoZSBmaWVsZCB2YWx1ZXMuCisgICAgICoKKyAgICAgKiBAc2VlICN3cml0ZUZpZWxkcworICAgICAqIEBzZWUgI3dyaXRlT2JqZWN0KE9iamVjdCkKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVGaWVsZFZhbHVlcyhFbXVsYXRlZEZpZWxkc0ZvckR1bXBpbmcgZW11bGF0ZWRGaWVsZHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIEFjY2VzcyBpbnRlcm5hbCBmaWVsZHMgd2hpY2ggd2UgY2FuIHNldC9nZXQuIFVzZXJzIGNhbid0IGRvIHRoaXMuCisgICAgICAgIEVtdWxhdGVkRmllbGRzIGFjY2Vzc2libGVTaW11bGF0ZWRGaWVsZHMgPSBlbXVsYXRlZEZpZWxkcy5lbXVsYXRlZEZpZWxkcygpOworICAgICAgICBmb3IgKEVtdWxhdGVkRmllbGRzLk9iamVjdFNsb3Qgc2xvdCA6IGFjY2Vzc2libGVTaW11bGF0ZWRGaWVsZHMuc2xvdHMoKSkgeworICAgICAgICAgICAgT2JqZWN0IGZpZWxkVmFsdWUgPSBzbG90LmdldEZpZWxkVmFsdWUoKTsKKyAgICAgICAgICAgIENsYXNzPD8+IHR5cGUgPSBzbG90LmdldEZpZWxkKCkuZ2V0VHlwZSgpOworICAgICAgICAgICAgaWYgKHR5cGUgPT0gaW50LmNsYXNzKSB7CisgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlSW50KGZpZWxkVmFsdWUgIT0gbnVsbCA/ICgoSW50ZWdlcikgZmllbGRWYWx1ZSkuaW50VmFsdWUoKSA6IDApOworICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGJ5dGUuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVCeXRlKGZpZWxkVmFsdWUgIT0gbnVsbCA/ICgoQnl0ZSkgZmllbGRWYWx1ZSkuYnl0ZVZhbHVlKCkgOiAwKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBjaGFyLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlQ2hhcihmaWVsZFZhbHVlICE9IG51bGwgPyAoKENoYXJhY3RlcikgZmllbGRWYWx1ZSkuY2hhclZhbHVlKCkgOiAwKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBzaG9ydC5jbGFzcykgeworICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZVNob3J0KGZpZWxkVmFsdWUgIT0gbnVsbCA/ICgoU2hvcnQpIGZpZWxkVmFsdWUpLnNob3J0VmFsdWUoKSA6IDApOworICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGJvb2xlYW4uY2xhc3MpIHsKKyAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVCb29sZWFuKGZpZWxkVmFsdWUgIT0gbnVsbCA/ICgoQm9vbGVhbikgZmllbGRWYWx1ZSkuYm9vbGVhblZhbHVlKCkgOiBmYWxzZSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gbG9uZy5jbGFzcykgeworICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUxvbmcoZmllbGRWYWx1ZSAhPSBudWxsID8gKChMb25nKSBmaWVsZFZhbHVlKS5sb25nVmFsdWUoKSA6IDApOworICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGZsb2F0LmNsYXNzKSB7CisgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoZmllbGRWYWx1ZSAhPSBudWxsID8gKChGbG9hdCkgZmllbGRWYWx1ZSkuZmxvYXRWYWx1ZSgpIDogMCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gZG91YmxlLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlKGZpZWxkVmFsdWUgIT0gbnVsbCA/ICgoRG91YmxlKSBmaWVsZFZhbHVlKS5kb3VibGVWYWx1ZSgpIDogMCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIEVpdGhlciBhcnJheSBvciBPYmplY3QKKyAgICAgICAgICAgICAgICB3cml0ZU9iamVjdChmaWVsZFZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGNvbGxlY3Rpb24gb2YgZmllbGQgdmFsdWVzIGZvciB0aGUgZmllbGRzIGRlc2NyaWJlZCBieSBjbGFzcworICAgICAqIGRlc2NyaXB0b3Ige0Bjb2RlIGNsYXNzRGVzY30gKGFuIHtAY29kZSBPYmplY3RTdHJlYW1DbGFzc30pLgorICAgICAqIFRoaXMgaXMgdGhlIGRlZmF1bHQgbWVjaGFuaXNtLCB3aGVuIGVtdWxhdGVkIGZpZWxkcyAoYW4KKyAgICAgKiB7QGNvZGUgUHV0RmllbGR9KSBhcmUgbm90IHVzZWQuIEFjdHVhbCB2YWx1ZXMgdG8gZHVtcCBhcmUgZmV0Y2hlZAorICAgICAqIGRpcmVjdGx5IGZyb20gb2JqZWN0IHtAY29kZSBvYmp9LgorICAgICAqCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgSW5zdGFuY2UgZnJvbSB3aGljaCB0byBmZXRjaCBmaWVsZCB2YWx1ZXMgdG8gZHVtcC4KKyAgICAgKiBAcGFyYW0gY2xhc3NEZXNjCisgICAgICogICAgICAgICAgICBBIGNsYXNzIGRlc2NyaXB0b3IgKGFuIHtAY29kZSBPYmplY3RTdHJlYW1DbGFzc30pCisgICAgICogICAgICAgICAgICBkZWZpbmluZyB3aGljaCBmaWVsZHMgc2hvdWxkIGJlIGR1bXBlZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBleGNlcHRpb24gaGFwcGVuZWQgd2hlbiB3cml0aW5nIHRoZSBmaWVsZCB2YWx1ZXMuCisgICAgICoKKyAgICAgKiBAc2VlICN3cml0ZU9iamVjdChPYmplY3QpCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlRmllbGRWYWx1ZXMoT2JqZWN0IG9iaiwgT2JqZWN0U3RyZWFtQ2xhc3MgY2xhc3NEZXNjKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmb3IgKE9iamVjdFN0cmVhbUZpZWxkIGZpZWxkRGVzYyA6IGNsYXNzRGVzYy5maWVsZHMoKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDbGFzczw/PiB0eXBlID0gZmllbGREZXNjLmdldFR5cGVJbnRlcm5hbCgpOworICAgICAgICAgICAgICAgIEZpZWxkIGZpZWxkID0gY2xhc3NEZXNjLmdldFJlZmxlY3Rpb25GaWVsZChmaWVsZERlc2MpOworICAgICAgICAgICAgICAgIGlmIChmaWVsZCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQ2xhc3NFeGNlcHRpb24oY2xhc3NEZXNjLmdldE5hbWUoKSArICIgZG9lc24ndCBoYXZlIGEgZmllbGQgIiArIGZpZWxkRGVzYy5nZXROYW1lKCkgKyAiIG9mIHR5cGUgIiArIHR5cGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBieXRlLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUJ5dGUoZmllbGQuZ2V0Qnl0ZShvYmopKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gY2hhci5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVDaGFyKGZpZWxkLmdldENoYXIob2JqKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGRvdWJsZS5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVEb3VibGUoZmllbGQuZ2V0RG91YmxlKG9iaikpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBmbG9hdC5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVGbG9hdChmaWVsZC5nZXRGbG9hdChvYmopKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gaW50LmNsYXNzKSB7CisgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUludChmaWVsZC5nZXRJbnQob2JqKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGxvbmcuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlTG9uZyhmaWVsZC5nZXRMb25nKG9iaikpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBzaG9ydC5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVTaG9ydChmaWVsZC5nZXRTaG9ydChvYmopKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gYm9vbGVhbi5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVCb29sZWFuKGZpZWxkLmdldEJvb2xlYW4ob2JqKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gUmVmZXJlbmNlIHR5cGVzIChpbmNsdWRpbmcgYXJyYXlzKS4KKyAgICAgICAgICAgICAgICAgICAgT2JqZWN0IG9iakZpZWxkID0gZmllbGQuZ2V0KG9iaik7CisgICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZERlc2MuaXNVbnNoYXJlZCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZVVuc2hhcmVkKG9iakZpZWxkKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlT2JqZWN0KG9iakZpZWxkKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAgICAgLy8gT2JqZWN0U3RyZWFtRmllbGQgc2hvdWxkIGhhdmUgY2FsbGVkIHNldEFjY2Vzc2libGUodHJ1ZSkuCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGlhZSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hGaWVsZEVycm9yIG5zZikgeworICAgICAgICAgICAgICAgIC8vIFRoZSB1c2VyIGRlZmluZWQgc2VyaWFsUGVyc2lzdGVudEZpZWxkcyBidXQgZGlkIG5vdCBwcm92aWRlCisgICAgICAgICAgICAgICAgLy8gdGhlIGdsdWUgdG8gdHJhbnNmZXIgdmFsdWVzIGluIHdyaXRlT2JqZWN0LCBzbyB3ZSBlbmRlZCB1cCB1c2luZworICAgICAgICAgICAgICAgIC8vIHRoZSBkZWZhdWx0IG1lY2hhbmlzbSBidXQgZmFpbGVkIHRvIHNldCB0aGUgZW11bGF0ZWQgZmllbGQuCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRDbGFzc0V4Y2VwdGlvbihjbGFzc0Rlc2MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGZsb2F0ICgzMiBiaXQpIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgZmxvYXQgdG8gd3JpdGUgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlRmxvYXQoZmxvYXQgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrV3JpdGVQcmltaXRpdmVUeXBlcygpOworICAgICAgICBwcmltaXRpdmVUeXBlcy53cml0ZUZsb2F0KHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXYWxrcyB0aGUgaGllcmFyY2h5IG9mIGNsYXNzZXMgZGVzY3JpYmVkIGJ5IGNsYXNzIGRlc2NyaXB0b3IKKyAgICAgKiB7QGNvZGUgY2xhc3NEZXNjfSBhbmQgd3JpdGVzIHRoZSBmaWVsZCB2YWx1ZXMgY29ycmVzcG9uZGluZyB0bworICAgICAqIGZpZWxkcyBkZWNsYXJlZCBieSB0aGUgY29ycmVzcG9uZGluZyBjbGFzcyBkZXNjcmlwdG9yLiBUaGUgaW5zdGFuY2UgdG8KKyAgICAgKiBmZXRjaCBmaWVsZCB2YWx1ZXMgZnJvbSBpcyB7QGNvZGUgb2JqZWN0fS4gSWYgdGhlIGNsYXNzCisgICAgICogKGNvcnJlc3BvbmRpbmcgdG8gY2xhc3MgZGVzY3JpcHRvciB7QGNvZGUgY2xhc3NEZXNjfSkgZGVmaW5lcworICAgICAqIHByaXZhdGUgaW5zdGFuY2UgbWV0aG9kIHtAY29kZSB3cml0ZU9iamVjdH0gaXQgd2lsbCBiZSB1c2VkIHRvCisgICAgICogZHVtcCBmaWVsZCB2YWx1ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICBJbnN0YW5jZSBmcm9tIHdoaWNoIHRvIGZldGNoIGZpZWxkIHZhbHVlcyB0byBkdW1wLgorICAgICAqIEBwYXJhbSBjbGFzc0Rlc2MKKyAgICAgKiAgICAgICAgICAgIEEgY2xhc3MgZGVzY3JpcHRvciAoYW4ge0Bjb2RlIE9iamVjdFN0cmVhbUNsYXNzfSkKKyAgICAgKiAgICAgICAgICAgIGRlZmluaW5nIHdoaWNoIGZpZWxkcyBzaG91bGQgYmUgZHVtcGVkLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFuIElPIGV4Y2VwdGlvbiBoYXBwZW5lZCB3aGVuIHdyaXRpbmcgdGhlIGZpZWxkIHZhbHVlcyBpbgorICAgICAqICAgICAgICAgICAgIHRoZSBoaWVyYXJjaHkuCisgICAgICogQHRocm93cyBOb3RBY3RpdmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiB0aGUgZ2l2ZW4gb2JqZWN0IGlzIG5vdCBhY3RpdmUKKyAgICAgKgorICAgICAqIEBzZWUgI2RlZmF1bHRXcml0ZU9iamVjdAorICAgICAqIEBzZWUgI3dyaXRlT2JqZWN0KE9iamVjdCkKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVIaWVyYXJjaHkoT2JqZWN0IG9iamVjdCwgT2JqZWN0U3RyZWFtQ2xhc3MgY2xhc3NEZXNjKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBOb3RBY3RpdmVFeGNlcHRpb24geworICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb3RBY3RpdmVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEZpZWxkcyBhcmUgd3JpdHRlbiBmcm9tIGNsYXNzIGNsb3Nlc3QgdG8gT2JqZWN0IHRvIGxlYWYgY2xhc3MKKyAgICAgICAgLy8gKGRvd24gdGhlIGNoYWluKQorICAgICAgICBMaXN0PE9iamVjdFN0cmVhbUNsYXNzPiBoaWVyYXJjaHkgPSBjbGFzc0Rlc2MuZ2V0SGllcmFyY2h5KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwLCBlbmQgPSBoaWVyYXJjaHkuc2l6ZSgpOyBpIDwgZW5kOyArK2kpIHsKKyAgICAgICAgICAgIE9iamVjdFN0cmVhbUNsYXNzIG9zYyA9IGhpZXJhcmNoeS5nZXQoaSk7CisgICAgICAgICAgICAvLyBIYXZlIHRvIGRvIHRoaXMgYmVmb3JlIGNhbGxpbmcgZGVmYXVsdFdyaXRlT2JqZWN0IG9yIGFueXRoaW5nCisgICAgICAgICAgICAvLyB0aGF0IGNhbGxzIGRlZmF1bHRXcml0ZU9iamVjdAorICAgICAgICAgICAgY3VycmVudE9iamVjdCA9IG9iamVjdDsKKyAgICAgICAgICAgIGN1cnJlbnRDbGFzcyA9IG9zYzsKKworICAgICAgICAgICAgLy8gU2VlIGlmIHRoZSBvYmplY3QgaGFzIGEgd3JpdGVPYmplY3QgbWV0aG9kLiBJZiBzbywgcnVuIGl0CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGJvb2xlYW4gZXhlY3V0ZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBpZiAob3NjLmhhc01ldGhvZFdyaXRlT2JqZWN0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgTWV0aG9kIG1ldGhvZCA9IG9zYy5nZXRNZXRob2RXcml0ZU9iamVjdCgpOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kLmludm9rZShvYmplY3QsIG5ldyBPYmplY3RbXSB7IHRoaXMgfSk7CisgICAgICAgICAgICAgICAgICAgICAgICBleGVjdXRlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgVGhyb3dhYmxlIGV4ID0gZS5nZXRUYXJnZXRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChleCBpbnN0YW5jZW9mIFJ1bnRpbWVFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikgZXg7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGV4IGluc3RhbmNlb2YgRXJyb3IpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAoRXJyb3IpIGV4OworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgKElPRXhjZXB0aW9uKSBleDsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGV4ZWN1dGVkKSB7CisgICAgICAgICAgICAgICAgICAgIGRyYWluKCk7CisgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUJ5dGUoVENfRU5EQkxPQ0tEQVRBKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgb2JqZWN0IGRpZCBub3QgaGF2ZSBhIHdyaXRlTWV0aG9kLCBjYWxsCisgICAgICAgICAgICAgICAgICAgIC8vIGRlZmF1bHRXcml0ZU9iamVjdAorICAgICAgICAgICAgICAgICAgICBkZWZhdWx0V3JpdGVPYmplY3QoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIC8vIENsZWFudXAsIG5lZWRzIHRvIHJ1biBhbHdheXMgc28gdGhhdCB3ZSBjYW4gbGF0ZXIgZGV0ZWN0CisgICAgICAgICAgICAgICAgLy8gaW52YWxpZCBjYWxscyB0byBkZWZhdWx0V3JpdGVPYmplY3QKKyAgICAgICAgICAgICAgICBjdXJyZW50T2JqZWN0ID0gbnVsbDsKKyAgICAgICAgICAgICAgICBjdXJyZW50Q2xhc3MgPSBudWxsOworICAgICAgICAgICAgICAgIGN1cnJlbnRQdXRGaWVsZCA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYW4gaW50ZWdlciAoMzIgYml0KSB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdG8gd3JpdGUgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlSW50KGludCB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tXcml0ZVByaW1pdGl2ZVR5cGVzKCk7CisgICAgICAgIHByaW1pdGl2ZVR5cGVzLndyaXRlSW50KHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBsb25nICg2NCBiaXQpIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbG9uZyB0byB3cml0ZSB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVMb25nKGxvbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrV3JpdGVQcmltaXRpdmVUeXBlcygpOworICAgICAgICBwcmltaXRpdmVUeXBlcy53cml0ZUxvbmcodmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIGFycmF5IHtAY29kZSBhcnJheX0gb2YgY2xhc3Mge0Bjb2RlIGFycmF5Q2xhc3N9IHdpdGgKKyAgICAgKiBjb21wb25lbnQgdHlwZSB7QGNvZGUgY29tcG9uZW50VHlwZX0gaW50byB0aGUgcmVjZWl2ZXIuIEl0IGlzCisgICAgICogYXNzdW1lZCB0aGUgYXJyYXkgaGFzIG5vdCBiZWVuIGR1bXBlZCB5ZXQuIFJldHVybnMKKyAgICAgKiB0aGUgaGFuZGxlIGZvciB0aGlzIG9iamVjdCAoYXJyYXkpIHdoaWNoIGlzIGR1bXBlZCBoZXJlLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICBUaGUgYXJyYXkgb2JqZWN0IHRvIGR1bXAKKyAgICAgKiBAcGFyYW0gYXJyYXlDbGFzcworICAgICAqICAgICAgICAgICAgQSB7QGNvZGUgamF2YS5sYW5nLkNsYXNzfSByZXByZXNlbnRpbmcgdGhlIGNsYXNzIG9mIHRoZQorICAgICAqICAgICAgICAgICAgYXJyYXkKKyAgICAgKiBAcGFyYW0gY29tcG9uZW50VHlwZQorICAgICAqICAgICAgICAgICAgQSB7QGNvZGUgamF2YS5sYW5nLkNsYXNzfSByZXByZXNlbnRpbmcgdGhlIGFycmF5CisgICAgICogICAgICAgICAgICBjb21wb25lbnQgdHlwZQorICAgICAqIEByZXR1cm4gdGhlIGhhbmRsZSBhc3NpZ25lZCB0byB0aGUgYXJyYXkKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBleGNlcHRpb24gaGFwcGVuZWQgd2hlbiB3cml0aW5nIHRoZSBhcnJheS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCB3cml0ZU5ld0FycmF5KE9iamVjdCBhcnJheSwgQ2xhc3M8Pz4gYXJyYXlDbGFzcywgT2JqZWN0U3RyZWFtQ2xhc3MgYXJyYXlDbERlc2MsCisgICAgICAgICAgICBDbGFzczw/PiBjb21wb25lbnRUeXBlLCBib29sZWFuIHVuc2hhcmVkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXRwdXQud3JpdGVCeXRlKFRDX0FSUkFZKTsKKyAgICAgICAgd3JpdGVDbGFzc0Rlc2MoYXJyYXlDbERlc2MsIGZhbHNlKTsKKworICAgICAgICBpbnQgaGFuZGxlID0gbmV4dEhhbmRsZSgpOworICAgICAgICBpZiAoIXVuc2hhcmVkKSB7CisgICAgICAgICAgICBvYmplY3RzV3JpdHRlbi5wdXQoYXJyYXksIGhhbmRsZSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBOb3cgd2UgaGF2ZSBjb2RlIGR1cGxpY2F0aW9uIGp1c3QgYmVjYXVzZSBKYXZhIGlzIHR5cGVkLiBXZSBoYXZlIHRvCisgICAgICAgIC8vIHdyaXRlIE4gZWxlbWVudHMgYW5kIGFzc2lnbiB0byBhcnJheSBwb3NpdGlvbnMsIGJ1dCB3ZSBtdXN0IHR5cGVjYXN0CisgICAgICAgIC8vIHRoZSBhcnJheSBmaXJzdCwgYW5kIGFsc28gY2FsbCBkaWZmZXJlbnQgbWV0aG9kcyBkZXBlbmRpbmcgb24gdGhlCisgICAgICAgIC8vIGVsZW1lbnRzLgorCisgICAgICAgIGlmIChjb21wb25lbnRUeXBlLmlzUHJpbWl0aXZlKCkpIHsKKyAgICAgICAgICAgIGlmIChjb21wb25lbnRUeXBlID09IGludC5jbGFzcykgeworICAgICAgICAgICAgICAgIGludFtdIGludEFycmF5ID0gKGludFtdKSBhcnJheTsKKyAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVJbnQoaW50QXJyYXkubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludEFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUludChpbnRBcnJheVtpXSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmIChjb21wb25lbnRUeXBlID09IGJ5dGUuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICBieXRlW10gYnl0ZUFycmF5ID0gKGJ5dGVbXSkgYXJyYXk7CisgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlSW50KGJ5dGVBcnJheS5sZW5ndGgpOworICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZShieXRlQXJyYXksIDAsIGJ5dGVBcnJheS5sZW5ndGgpOworICAgICAgICAgICAgfSBlbHNlIGlmIChjb21wb25lbnRUeXBlID09IGNoYXIuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICBjaGFyW10gY2hhckFycmF5ID0gKGNoYXJbXSkgYXJyYXk7CisgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlSW50KGNoYXJBcnJheS5sZW5ndGgpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2hhckFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUNoYXIoY2hhckFycmF5W2ldKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbXBvbmVudFR5cGUgPT0gc2hvcnQuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICBzaG9ydFtdIHNob3J0QXJyYXkgPSAoc2hvcnRbXSkgYXJyYXk7CisgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlSW50KHNob3J0QXJyYXkubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNob3J0QXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlU2hvcnQoc2hvcnRBcnJheVtpXSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmIChjb21wb25lbnRUeXBlID09IGJvb2xlYW4uY2xhc3MpIHsKKyAgICAgICAgICAgICAgICBib29sZWFuW10gYm9vbGVhbkFycmF5ID0gKGJvb2xlYW5bXSkgYXJyYXk7CisgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlSW50KGJvb2xlYW5BcnJheS5sZW5ndGgpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYm9vbGVhbkFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUJvb2xlYW4oYm9vbGVhbkFycmF5W2ldKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbXBvbmVudFR5cGUgPT0gbG9uZy5jbGFzcykgeworICAgICAgICAgICAgICAgIGxvbmdbXSBsb25nQXJyYXkgPSAobG9uZ1tdKSBhcnJheTsKKyAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVJbnQobG9uZ0FycmF5Lmxlbmd0aCk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsb25nQXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlTG9uZyhsb25nQXJyYXlbaV0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY29tcG9uZW50VHlwZSA9PSBmbG9hdC5jbGFzcykgeworICAgICAgICAgICAgICAgIGZsb2F0W10gZmxvYXRBcnJheSA9IChmbG9hdFtdKSBhcnJheTsKKyAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVJbnQoZmxvYXRBcnJheS5sZW5ndGgpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmxvYXRBcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVGbG9hdChmbG9hdEFycmF5W2ldKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbXBvbmVudFR5cGUgPT0gZG91YmxlLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgZG91YmxlW10gZG91YmxlQXJyYXkgPSAoZG91YmxlW10pIGFycmF5OworICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUludChkb3VibGVBcnJheS5sZW5ndGgpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZG91YmxlQXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlKGRvdWJsZUFycmF5W2ldKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQ2xhc3NFeGNlcHRpb24oIldyb25nIGJhc2UgdHlwZSBpbiAiICsgYXJyYXlDbGFzcy5nZXROYW1lKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gQXJyYXkgb2YgT2JqZWN0cworICAgICAgICAgICAgT2JqZWN0W10gb2JqZWN0QXJyYXkgPSAoT2JqZWN0W10pIGFycmF5OworICAgICAgICAgICAgb3V0cHV0LndyaXRlSW50KG9iamVjdEFycmF5Lmxlbmd0aCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iamVjdEFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgLy8gVE9ETzogVGhpcyBwbGFjZSBpcyB0aGUgb3Bwb3J0dW5pdHkgZm9yIGVuaGFuY2VtZW50CisgICAgICAgICAgICAgICAgLy8gICAgICBXZSBjYW4gaW1wbGVtZW50IHdyaXRpbmcgZWxlbWVudHMgdGhyb3VnaCBmYXN0LXBhdGgsCisgICAgICAgICAgICAgICAgLy8gICAgICB3aXRob3V0IHNldHRpbmcgdXAgdGhlIGNvbnRleHQgKHNlZSB3cml0ZU9iamVjdCgpKSBmb3IKKyAgICAgICAgICAgICAgICAvLyAgICAgIGVhY2ggZWxlbWVudCB3aXRoIHB1YmxpYyBBUEkKKyAgICAgICAgICAgICAgICB3cml0ZU9iamVjdChvYmplY3RBcnJheVtpXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGhhbmRsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBjbGFzcyB7QGNvZGUgb2JqZWN0fSBpbnRvIHRoZSByZWNlaXZlci4gSXQgaXMgYXNzdW1lZCB0aGUKKyAgICAgKiBjbGFzcyBoYXMgbm90IGJlZW4gZHVtcGVkIHlldC4gQ2xhc3NlcyBhcmUgbm90IHJlYWxseSBkdW1wZWQsIGJ1dCBhIGNsYXNzCisgICAgICogZGVzY3JpcHRvciAoe0Bjb2RlIE9iamVjdFN0cmVhbUNsYXNzfSkgdGhhdCBjb3JyZXNwb25kcyB0byB0aGVtLgorICAgICAqIFJldHVybnMgdGhlIGhhbmRsZSBmb3IgdGhpcyBvYmplY3QgKGNsYXNzKSB3aGljaCBpcyBkdW1wZWQgaGVyZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIFRoZSB7QGNvZGUgamF2YS5sYW5nLkNsYXNzfSBvYmplY3QgdG8gZHVtcAorICAgICAqIEByZXR1cm4gdGhlIGhhbmRsZSBhc3NpZ25lZCB0byB0aGUgY2xhc3MgYmVpbmcgZHVtcGVkCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXhjZXB0aW9uIGhhcHBlbmVkIHdoZW4gd3JpdGluZyB0aGUgY2xhc3MuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgd3JpdGVOZXdDbGFzcyhDbGFzczw/PiBvYmplY3QsIGJvb2xlYW4gdW5zaGFyZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dHB1dC53cml0ZUJ5dGUoVENfQ0xBU1MpOworCisgICAgICAgIC8vIEluc3RhbmNlcyBvZiBqYXZhLmxhbmcuQ2xhc3MgYXJlIGFsd2F5cyBTZXJpYWxpemFibGUsIGV2ZW4gaWYgdGhlaXIKKyAgICAgICAgLy8gaW5zdGFuY2VzIGFyZW4ndCAoZS5nLiBqYXZhLmxhbmcuT2JqZWN0LmNsYXNzKS4KKyAgICAgICAgLy8gV2UgY2Fubm90IGNhbGwgbG9va3VwIGJlY2F1c2UgaXQgcmV0dXJucyBudWxsIGlmIHRoZSBwYXJhbWV0ZXIKKyAgICAgICAgLy8gcmVwcmVzZW50cyBpbnN0YW5jZXMgdGhhdCBjYW5ub3QgYmUgc2VyaWFsaXplZCwgYW5kIHRoYXQgaXMgbm90IHdoYXQKKyAgICAgICAgLy8gd2Ugd2FudC4KKyAgICAgICAgT2JqZWN0U3RyZWFtQ2xhc3MgY2xEZXNjID0gT2JqZWN0U3RyZWFtQ2xhc3MubG9va3VwU3RyZWFtQ2xhc3Mob2JqZWN0KTsKKworICAgICAgICAvLyBUaGUgaGFuZGxlIGZvciB0aGUgY2xhc3NEZXNjIGlzIE5PVCB0aGUgaGFuZGxlIGZvciB0aGUgY2xhc3Mgb2JqZWN0CisgICAgICAgIC8vIGJlaW5nIGR1bXBlZC4gV2UgbXVzdCBhbGxvY2F0ZSBhIG5ldyBoYW5kbGUgYW5kIHJldHVybiBpdC4KKyAgICAgICAgaWYgKGNsRGVzYy5pc0VudW0oKSkgeworICAgICAgICAgICAgd3JpdGVFbnVtRGVzYyhvYmplY3QsIGNsRGVzYywgdW5zaGFyZWQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgd3JpdGVDbGFzc0Rlc2MoY2xEZXNjLCB1bnNoYXJlZCk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgaGFuZGxlID0gbmV4dEhhbmRsZSgpOworICAgICAgICBpZiAoIXVuc2hhcmVkKSB7CisgICAgICAgICAgICBvYmplY3RzV3JpdHRlbi5wdXQob2JqZWN0LCBoYW5kbGUpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGhhbmRsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBjbGFzcyBkZXNjcmlwdG9yIHtAY29kZSBjbGFzc0Rlc2N9IGludG8gdGhlIHJlY2VpdmVyLiBJdCBpcworICAgICAqIGFzc3VtZWQgdGhlIGNsYXNzIGRlc2NyaXB0b3IgaGFzIG5vdCBiZWVuIGR1bXBlZCB5ZXQuIFRoZSBjbGFzcworICAgICAqIGRlc2NyaXB0b3JzIGZvciB0aGUgc3VwZXJjbGFzcyBjaGFpbiB3aWxsIGJlIGR1bXBlZCBhcyB3ZWxsLiBSZXR1cm5zCisgICAgICogdGhlIGhhbmRsZSBmb3IgdGhpcyBvYmplY3QgKGNsYXNzIGRlc2NyaXB0b3IpIHdoaWNoIGlzIGR1bXBlZCBoZXJlLgorICAgICAqCisgICAgICogQHBhcmFtIGNsYXNzRGVzYworICAgICAqICAgICAgICAgICAgVGhlIHtAY29kZSBPYmplY3RTdHJlYW1DbGFzc30gb2JqZWN0IHRvIGR1bXAKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBleGNlcHRpb24gaGFwcGVuZWQgd2hlbiB3cml0aW5nIHRoZSBjbGFzcworICAgICAqICAgICAgICAgICAgIGRlc2NyaXB0b3IuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlTmV3Q2xhc3NEZXNjKE9iamVjdFN0cmVhbUNsYXNzIGNsYXNzRGVzYykKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dHB1dC53cml0ZVVURihjbGFzc0Rlc2MuZ2V0TmFtZSgpKTsKKyAgICAgICAgb3V0cHV0LndyaXRlTG9uZyhjbGFzc0Rlc2MuZ2V0U2VyaWFsVmVyc2lvblVJRCgpKTsKKyAgICAgICAgYnl0ZSBmbGFncyA9IGNsYXNzRGVzYy5nZXRGbGFncygpOworCisgICAgICAgIGJvb2xlYW4gZXh0ZXJuYWxpemFibGUgPSBjbGFzc0Rlc2MuaXNFeHRlcm5hbGl6YWJsZSgpOworCisgICAgICAgIGlmIChleHRlcm5hbGl6YWJsZSkgeworICAgICAgICAgICAgaWYgKHByb3RvY29sVmVyc2lvbiA9PSBQUk9UT0NPTF9WRVJTSU9OXzEpIHsKKyAgICAgICAgICAgICAgICBmbGFncyAmPSBOT1RfU0NfQkxPQ0tfREFUQTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gQ2hhbmdlIGZvciAxLjIuIE9iamVjdHMgY2FuIGJlIHNhdmVkIGluIG9sZCBmb3JtYXQKKyAgICAgICAgICAgICAgICAvLyAoUFJPVE9DT0xfVkVSU0lPTl8xKSBvciBpbiB0aGUgMS4yIGZvcm1hdCAoUFJPVE9DT0xfVkVSU0lPTl8yKS4KKyAgICAgICAgICAgICAgICBmbGFncyB8PSBTQ19CTE9DS19EQVRBOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIG91dHB1dC53cml0ZUJ5dGUoZmxhZ3MpOworICAgICAgICBpZiAoKFNDX0VOVU0gfCBTQ19TRVJJQUxJWkFCTEUpICE9IGNsYXNzRGVzYy5nZXRGbGFncygpKSB7CisgICAgICAgICAgICB3cml0ZUZpZWxkRGVzY3JpcHRvcnMoY2xhc3NEZXNjLCBleHRlcm5hbGl6YWJsZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBlbnVtIHdyaXRlIG5vIGZpZWxkcworICAgICAgICAgICAgb3V0cHV0LndyaXRlU2hvcnQoMCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBjbGFzcyBkZXNjcmlwdG9yIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIGNsYXNzRGVzYworICAgICAqICAgICAgICAgICAgdGhlIGNsYXNzIGRlc2NyaXB0b3IgdG8gd3JpdGUgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHdyaXRlQ2xhc3NEZXNjcmlwdG9yKE9iamVjdFN0cmVhbUNsYXNzIGNsYXNzRGVzYykKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlTmV3Q2xhc3NEZXNjKGNsYXNzRGVzYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGUgZXhjZXB0aW9uIHtAY29kZSBleH0gaW50byB0aGUgcmVjZWl2ZXIuIEl0IGlzIGFzc3VtZWQgdGhlCisgICAgICogZXhjZXB0aW9uIGhhcyBub3QgYmVlbiBkdW1wZWQgeWV0LiBSZXR1cm5zCisgICAgICogdGhlIGhhbmRsZSBmb3IgdGhpcyBvYmplY3QgKGV4Y2VwdGlvbikgd2hpY2ggaXMgZHVtcGVkIGhlcmUuCisgICAgICogVGhpcyBpcyB1c2VkIHRvIGR1bXAgdGhlIGV4Y2VwdGlvbiBpbnN0YW5jZSB0aGF0IGhhcHBlbmVkIChpZiBhbnkpIHdoZW4KKyAgICAgKiBkdW1waW5nIHRoZSBvcmlnaW5hbCBvYmplY3QgZ3JhcGguIFRoZSBzZXQgb2Ygc2VlbiBvYmplY3RzIHdpbGwgYmUgcmVzZXQKKyAgICAgKiBqdXN0IGJlZm9yZSBhbmQganVzdCBhZnRlciBkdW1waW5nIHRoaXMgZXhjZXB0aW9uIG9iamVjdC4KKyAgICAgKgorICAgICAqIFdoZW4gZXhjZXB0aW9ucyBhcmUgZm91bmQgbm9ybWFsbHkgaW4gdGhlIG9iamVjdCBncmFwaCwgdGhleSBhcmUgZHVtcGVkCisgICAgICogYXMgYSByZWd1bGFyIG9iamVjdCwgYW5kIG5vdCBieSB0aGlzIG1ldGhvZC4gSW4gdGhhdCBjYXNlLCB0aGUgc2V0IG9mCisgICAgICogImtub3duIG9iamVjdHMiIGlzIG5vdCByZXNldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleAorICAgICAqICAgICAgICAgICAgRXhjZXB0aW9uIG9iamVjdCB0byBkdW1wCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXhjZXB0aW9uIGhhcHBlbmVkIHdoZW4gd3JpdGluZyB0aGUgZXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgb2JqZWN0LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB3cml0ZU5ld0V4Y2VwdGlvbihFeGNlcHRpb24gZXgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dHB1dC53cml0ZUJ5dGUoVENfRVhDRVBUSU9OKTsKKyAgICAgICAgcmVzZXRTZWVuT2JqZWN0cygpOworICAgICAgICB3cml0ZU9iamVjdEludGVybmFsKGV4LCBmYWxzZSwgZmFsc2UsIGZhbHNlKTsgLy8gTm8gcmVwbGFjZW1lbnRzCisgICAgICAgIHJlc2V0U2Vlbk9iamVjdHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBvYmplY3Qge0Bjb2RlIG9iamVjdH0gb2YgY2xhc3Mge0Bjb2RlIHRoZUNsYXNzfSBpbnRvCisgICAgICogdGhlIHJlY2VpdmVyLiBJdCBpcyBhc3N1bWVkIHRoZSBvYmplY3QgaGFzIG5vdCBiZWVuIGR1bXBlZCB5ZXQuCisgICAgICogUmV0dXJuIHRoZSBoYW5kbGUgZm9yIHRoaXMgb2JqZWN0IHdoaWNoCisgICAgICogaXMgZHVtcGVkIGhlcmUuCisgICAgICoKKyAgICAgKiBJZiB0aGUgb2JqZWN0IGltcGxlbWVudHMge0Bjb2RlIEV4dGVybmFsaXphYmxlfSBpdHMKKyAgICAgKiB7QGNvZGUgd3JpdGVFeHRlcm5hbH0gaXMgY2FsbGVkLiBPdGhlcndpc2UsIGFsbCBmaWVsZHMgZGVzY3JpYmVkCisgICAgICogYnkgdGhlIGNsYXNzIGhpZXJhcmNoeSBpcyBkdW1wZWQuIEVhY2ggY2xhc3MgY2FuIGRlZmluZSBob3cgaXRzIGRlY2xhcmVkCisgICAgICogaW5zdGFuY2UgZmllbGRzIGFyZSBkdW1wZWQgYnkgZGVmaW5pbmcgYSBwcml2YXRlIG1ldGhvZAorICAgICAqIHtAY29kZSB3cml0ZU9iamVjdH0KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIFRoZSBvYmplY3QgdG8gZHVtcAorICAgICAqIEBwYXJhbSB0aGVDbGFzcworICAgICAqICAgICAgICAgICAgQSB7QGNvZGUgamF2YS5sYW5nLkNsYXNzfSByZXByZXNlbnRpbmcgdGhlIGNsYXNzIG9mIHRoZQorICAgICAqICAgICAgICAgICAgb2JqZWN0CisgICAgICogQHBhcmFtIHVuc2hhcmVkCisgICAgICogICAgICAgICAgICBXcml0ZSB0aGUgb2JqZWN0IHVuc2hhcmVkCisgICAgICogQHJldHVybiB0aGUgaGFuZGxlIGFzc2lnbmVkIHRvIHRoZSBvYmplY3QKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBJTyBleGNlcHRpb24gaGFwcGVuZWQgd2hlbiB3cml0aW5nIHRoZSBvYmplY3QuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgd3JpdGVOZXdPYmplY3QoT2JqZWN0IG9iamVjdCwgQ2xhc3M8Pz4gdGhlQ2xhc3MsIE9iamVjdFN0cmVhbUNsYXNzIGNsRGVzYywKKyAgICAgICAgICAgIGJvb2xlYW4gdW5zaGFyZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIE5vdCBTdHJpbmcsIG5vdCBudWxsLCBub3QgYXJyYXksIG5vdCBjeWNsaWMgcmVmZXJlbmNlCisKKyAgICAgICAgRW11bGF0ZWRGaWVsZHNGb3JEdW1waW5nIG9yaWdpbmFsQ3VycmVudFB1dEZpZWxkID0gY3VycmVudFB1dEZpZWxkOyAvLyBzYXZlCisgICAgICAgIGN1cnJlbnRQdXRGaWVsZCA9IG51bGw7IC8vIG51bGwgaXQsIHRvIG1ha2Ugc3VyZSBvbmUgd2lsbCBiZSBjb21wdXRlZCBpZgorICAgICAgICAvLyBuZWVkZWQKKworICAgICAgICBib29sZWFuIGV4dGVybmFsaXphYmxlID0gY2xEZXNjLmlzRXh0ZXJuYWxpemFibGUoKTsKKyAgICAgICAgYm9vbGVhbiBzZXJpYWxpemFibGUgPSBjbERlc2MuaXNTZXJpYWxpemFibGUoKTsKKyAgICAgICAgaWYgKCFleHRlcm5hbGl6YWJsZSAmJiAhc2VyaWFsaXphYmxlKSB7CisgICAgICAgICAgICAvLyBPYmplY3QgaXMgbmVpdGhlciBleHRlcm5hbGl6YWJsZSBub3Igc2VyaWFsaXphYmxlLiBFcnJvcgorICAgICAgICAgICAgdGhyb3cgbmV3IE5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbih0aGVDbGFzcy5nZXROYW1lKCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gRWl0aGVyIHNlcmlhbGl6YWJsZSBvciBleHRlcm5hbGl6YWJsZSwgbm93IHdlIGNhbiBzYXZlIGluZm8KKyAgICAgICAgb3V0cHV0LndyaXRlQnl0ZShUQ19PQkpFQ1QpOworICAgICAgICB3cml0ZUNsYXNzRGVzYyhjbERlc2MsIGZhbHNlKTsKKyAgICAgICAgaW50IHByZXZpb3VzSGFuZGxlID0gLTE7CisgICAgICAgIGlmICh1bnNoYXJlZCkgeworICAgICAgICAgICAgcHJldmlvdXNIYW5kbGUgPSBvYmplY3RzV3JpdHRlbi5nZXQob2JqZWN0KTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBoYW5kbGUgPSByZWdpc3Rlck9iamVjdFdyaXR0ZW4ob2JqZWN0KTsKKworICAgICAgICAvLyBUaGlzIGlzIGhvdyB3ZSBrbm93IHdoYXQgdG8gZG8gaW4gZGVmYXVsdFdyaXRlT2JqZWN0LiBBbmQgaXQgaXMgYWxzbworICAgICAgICAvLyB1c2VkIGJ5IGRlZmF1bHRXcml0ZU9iamVjdCB0byBjaGVjayBpZiBpdCB3YXMgY2FsbGVkIGZyb20gYW4gaW52YWxpZAorICAgICAgICAvLyBwbGFjZS4KKyAgICAgICAgLy8gSXQgYWxsb3dzIHdyaXRlRXh0ZXJuYWwgdG8gY2FsbCBkZWZhdWx0V3JpdGVPYmplY3QgYW5kIGhhdmUgaXQgd29yay4KKyAgICAgICAgY3VycmVudE9iamVjdCA9IG9iamVjdDsKKyAgICAgICAgY3VycmVudENsYXNzID0gY2xEZXNjOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGV4dGVybmFsaXphYmxlKSB7CisgICAgICAgICAgICAgICAgYm9vbGVhbiBub0Jsb2NrRGF0YSA9IHByb3RvY29sVmVyc2lvbiA9PSBQUk9UT0NPTF9WRVJTSU9OXzE7CisgICAgICAgICAgICAgICAgaWYgKG5vQmxvY2tEYXRhKSB7CisgICAgICAgICAgICAgICAgICAgIHByaW1pdGl2ZVR5cGVzID0gb3V0cHV0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBPYmplY3QgaXMgZXh0ZXJuYWxpemFibGUsIGp1c3QgY2FsbCBpdHMgb3duIG1ldGhvZAorICAgICAgICAgICAgICAgICgoRXh0ZXJuYWxpemFibGUpIG9iamVjdCkud3JpdGVFeHRlcm5hbCh0aGlzKTsKKyAgICAgICAgICAgICAgICBpZiAobm9CbG9ja0RhdGEpIHsKKyAgICAgICAgICAgICAgICAgICAgcHJpbWl0aXZlVHlwZXMgPSBudWxsOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFNpbWlsYXIgdG8gdGhlIGNvZGUgaW4gd3JpdGVIaWVyYXJjaHkgd2hlbiBvYmplY3QKKyAgICAgICAgICAgICAgICAgICAgLy8gaW1wbGVtZW50cyB3cml0ZU9iamVjdC4KKyAgICAgICAgICAgICAgICAgICAgLy8gQW55IHByaW1pdGl2ZSBkYXRhIGhhcyB0byBiZSBmbHVzaGVkIGFuZCBhIHRhZyBtdXN0IGJlCisgICAgICAgICAgICAgICAgICAgIC8vIHdyaXR0ZW4KKyAgICAgICAgICAgICAgICAgICAgZHJhaW4oKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlQnl0ZShUQ19FTkRCTE9DS0RBVEEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7IC8vIElmIGl0IGdvdCBoZXJlLCBpdCBoYXMgdG8gYmUgU2VyaWFsaXphYmxlCisgICAgICAgICAgICAgICAgLy8gT2JqZWN0IGlzIHNlcmlhbGl6YWJsZS4gV2FsayB0aGUgY2xhc3MgY2hhaW4gd3JpdGluZyB0aGUKKyAgICAgICAgICAgICAgICAvLyBmaWVsZHMKKyAgICAgICAgICAgICAgICB3cml0ZUhpZXJhcmNoeShvYmplY3QsIGN1cnJlbnRDbGFzcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAvLyBDbGVhbnVwLCBuZWVkcyB0byBydW4gYWx3YXlzIHNvIHRoYXQgd2UgY2FuIGxhdGVyIGRldGVjdCBpbnZhbGlkCisgICAgICAgICAgICAvLyBjYWxscyB0byBkZWZhdWx0V3JpdGVPYmplY3QKKyAgICAgICAgICAgIGlmICh1bnNoYXJlZCkgeworICAgICAgICAgICAgICAgIC8vIHJlbW92ZSByZWZlcmVuY2UgdG8gdW5zaGFyZWQgb2JqZWN0CisgICAgICAgICAgICAgICAgcmVtb3ZlVW5zaGFyZWRSZWZlcmVuY2Uob2JqZWN0LCBwcmV2aW91c0hhbmRsZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjdXJyZW50T2JqZWN0ID0gbnVsbDsKKyAgICAgICAgICAgIGN1cnJlbnRDbGFzcyA9IG51bGw7CisgICAgICAgICAgICBjdXJyZW50UHV0RmllbGQgPSBvcmlnaW5hbEN1cnJlbnRQdXRGaWVsZDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBoYW5kbGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGUgU3RyaW5nIHtAY29kZSBvYmplY3R9IGludG8gdGhlIHJlY2VpdmVyLiBJdCBpcyBhc3N1bWVkIHRoZQorICAgICAqIFN0cmluZyBoYXMgbm90IGJlZW4gZHVtcGVkIHlldC4gUmV0dXJucyB0aGUgaGFuZGxlIGZvciB0aGlzIG9iamVjdCAoU3RyaW5nKSB3aGljaCBpcyBkdW1wZWQgaGVyZS4KKyAgICAgKiBTdHJpbmdzIGFyZSBzYXZlZCBlbmNvZGVkIHdpdGgge0BsaW5rIERhdGFJbnB1dCBtb2RpZmllZCBVVEYtOH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIGR1bXAuCisgICAgICogQHJldHVybiB0aGUgaGFuZGxlIGFzc2lnbmVkIHRvIHRoZSBTdHJpbmcgYmVpbmcgZHVtcGVkCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gSU8gZXhjZXB0aW9uIGhhcHBlbmVkIHdoZW4gd3JpdGluZyB0aGUgU3RyaW5nLgorICAgICAqLworICAgIHByaXZhdGUgaW50IHdyaXRlTmV3U3RyaW5nKFN0cmluZyBvYmplY3QsIGJvb2xlYW4gdW5zaGFyZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgY291bnQgPSBNb2RpZmllZFV0ZjguY291bnRCeXRlcyhvYmplY3QsIGZhbHNlKTsKKyAgICAgICAgYnl0ZVtdIGJ1ZmZlcjsKKyAgICAgICAgaW50IG9mZnNldCA9IDA7CisgICAgICAgIGlmIChjb3VudCA8PSAweGZmZmYpIHsKKyAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBieXRlWzEgKyBTaXplT2YuU0hPUlQgKyAoaW50KSBjb3VudF07CisgICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gVENfU1RSSU5HOworICAgICAgICAgICAgTWVtb3J5LnBva2VTaG9ydChidWZmZXIsIG9mZnNldCwgKHNob3J0KSBjb3VudCwgQnl0ZU9yZGVyLkJJR19FTkRJQU4pOworICAgICAgICAgICAgb2Zmc2V0ICs9IFNpemVPZi5TSE9SVDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBieXRlWzEgKyBTaXplT2YuTE9ORyArIChpbnQpIGNvdW50XTsKKyAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBUQ19MT05HU1RSSU5HOworICAgICAgICAgICAgTWVtb3J5LnBva2VMb25nKGJ1ZmZlciwgb2Zmc2V0LCBjb3VudCwgQnl0ZU9yZGVyLkJJR19FTkRJQU4pOworICAgICAgICAgICAgb2Zmc2V0ICs9IFNpemVPZi5MT05HOworICAgICAgICB9CisgICAgICAgIE1vZGlmaWVkVXRmOC5lbmNvZGUoYnVmZmVyLCBvZmZzZXQsIG9iamVjdCk7CisgICAgICAgIG91dHB1dC53cml0ZShidWZmZXIsIDAsIGJ1ZmZlci5sZW5ndGgpOworCisgICAgICAgIGludCBoYW5kbGUgPSBuZXh0SGFuZGxlKCk7CisgICAgICAgIGlmICghdW5zaGFyZWQpIHsKKyAgICAgICAgICAgIG9iamVjdHNXcml0dGVuLnB1dChvYmplY3QsIGhhbmRsZSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gaGFuZGxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIGEgc3BlY2lhbCB0YWcgdGhhdCBpbmRpY2F0ZXMgdGhlIHZhbHVlIHtAY29kZSBudWxsfSBpbnRvIHRoZQorICAgICAqIHJlY2VpdmVyLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFuIElPIGV4Y2VwdGlvbiBoYXBwZW5lZCB3aGVuIHdyaXRpbmcgdGhlIHRhZyBmb3IKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlTnVsbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dHB1dC53cml0ZUJ5dGUoVENfTlVMTCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGFuIG9iamVjdCB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gd3JpdGUgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqIEBzZWUgT2JqZWN0SW5wdXRTdHJlYW0jcmVhZE9iamVjdCgpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0IG9iamVjdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGVPYmplY3Qob2JqZWN0LCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGFuIHVuc2hhcmVkIG9iamVjdCB0byB0aGUgdGFyZ2V0IHN0cmVhbS4gVGhpcyBtZXRob2QgaXMgaWRlbnRpY2FsCisgICAgICogdG8ge0Bjb2RlIHdyaXRlT2JqZWN0fSwgZXhjZXB0IHRoYXQgaXQgYWx3YXlzIHdyaXRlcyBhIG5ldyBvYmplY3QgdG8gdGhlCisgICAgICogc3RyZWFtIHZlcnN1cyB0aGUgdXNlIG9mIGJhY2stcmVmZXJlbmNpbmcgZm9yIGlkZW50aWNhbCBvYmplY3RzIGJ5CisgICAgICoge0Bjb2RlIHdyaXRlT2JqZWN0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gd3JpdGUgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqIEBzZWUgT2JqZWN0SW5wdXRTdHJlYW0jcmVhZFVuc2hhcmVkKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVVuc2hhcmVkKE9iamVjdCBvYmplY3QpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlT2JqZWN0KG9iamVjdCwgdHJ1ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdCBvYmplY3QsIGJvb2xlYW4gdW5zaGFyZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gc2V0T3V0cHV0ID0gKHByaW1pdGl2ZVR5cGVzID09IG91dHB1dCk7CisgICAgICAgIGlmIChzZXRPdXRwdXQpIHsKKyAgICAgICAgICAgIHByaW1pdGl2ZVR5cGVzID0gbnVsbDsKKyAgICAgICAgfQorICAgICAgICAvLyBUaGlzIGlzIHRoZSBzcGVjaWZpZWQgYmVoYXZpb3IgaW4gSkRLIDEuMi4gVmVyeSBiaXphcnJlIHdheSB0byBhbGxvdworICAgICAgICAvLyBiZWhhdmlvciBvdmVycmlkaW5nLgorICAgICAgICBpZiAoc3ViY2xhc3NPdmVycmlkaW5nSW1wbGVtZW50YXRpb24gJiYgIXVuc2hhcmVkKSB7CisgICAgICAgICAgICB3cml0ZU9iamVjdE92ZXJyaWRlKG9iamVjdCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gRmlyc3Qgd2UgbmVlZCB0byBmbHVzaCBwcmltaXRpdmUgdHlwZXMgaWYgdGhleSB3ZXJlIHdyaXR0ZW4KKyAgICAgICAgICAgIGRyYWluKCk7CisgICAgICAgICAgICAvLyBBY3R1YWwgd29yaywgYW5kIGNsYXNzLWJhc2VkIHJlcGxhY2VtZW50IHNob3VsZCBiZSBjb21wdXRlZAorICAgICAgICAgICAgLy8gaWYgbmVlZGVkLgorICAgICAgICAgICAgd3JpdGVPYmplY3RJbnRlcm5hbChvYmplY3QsIHVuc2hhcmVkLCB0cnVlLCB0cnVlKTsKKyAgICAgICAgICAgIGlmIChzZXRPdXRwdXQpIHsKKyAgICAgICAgICAgICAgICBwcmltaXRpdmVUeXBlcyA9IG91dHB1dDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9FeDEpIHsKKyAgICAgICAgICAgIC8vIFRoaXMgd2lsbCBtYWtlIGl0IHBhc3MgdGhyb3VnaCB1bnRpbCB0aGUgdG9wIGNhbGxlci4gSXQgYWxzbworICAgICAgICAgICAgLy8gbGV0cyBpdCBwYXNzIHRocm91Z2ggdGhlIG5lc3RlZCBleGNlcHRpb24uCisgICAgICAgICAgICBpZiAobmVzdGVkTGV2ZWxzID09IDAgJiYgaW9FeDEgIT0gbmVzdGVkRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgd3JpdGVOZXdFeGNlcHRpb24oaW9FeDEpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvRXgyKSB7CisgICAgICAgICAgICAgICAgICAgIG5lc3RlZEV4Y2VwdGlvbi5maWxsSW5TdGFja1RyYWNlKCk7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5lc3RlZEV4Y2VwdGlvbjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aHJvdyBpb0V4MTsgLy8gYW5kIHRoZW4gd2UgcHJvcGFnYXRlIHRoZSBvcmlnaW5hbCBleGNlcHRpb24KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIG9iamVjdCB7QGNvZGUgb2JqZWN0fSBpbnRvIHRoZSByZWNlaXZlcidzIHVuZGVybHlpbmcgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgVGhlIG9iamVjdCB0byB3cml0ZQorICAgICAqIEBwYXJhbSB1bnNoYXJlZAorICAgICAqICAgICAgICAgICAgV3JpdGUgdGhlIG9iamVjdCB1bnNoYXJlZAorICAgICAqIEBwYXJhbSBjb21wdXRlQ2xhc3NCYXNlZFJlcGxhY2VtZW50CisgICAgICogICAgICAgICAgICBBIGJvb2xlYW4gaW5kaWNhdGluZyBpZiBjbGFzcy1iYXNlZCByZXBsYWNlbWVudCBzaG91bGQgYmUKKyAgICAgKiAgICAgICAgICAgIGNvbXB1dGVkIChpZiBzdXBwb3J0ZWQpIGZvciB0aGUgb2JqZWN0LgorICAgICAqIEBwYXJhbSBjb21wdXRlU3RyZWFtUmVwbGFjZW1lbnQKKyAgICAgKiAgICAgICAgICAgIEEgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIHN0cmVhbS1iYXNlZCByZXBsYWNlbWVudCBzaG91bGQgYmUKKyAgICAgKiAgICAgICAgICAgIGNvbXB1dGVkIChpZiBzdXBwb3J0ZWQpIGZvciB0aGUgb2JqZWN0LgorICAgICAqIEByZXR1cm4gdGhlIGhhbmRsZSBhc3NpZ25lZCB0byB0aGUgZmluYWwgb2JqZWN0IGJlaW5nIGR1bXBlZAorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFuIElPIGV4Y2VwdGlvbiBoYXBwZW5lZCB3aGVuIHdyaXRpbmcgdGhlIG9iamVjdAorICAgICAqCisgICAgICogQHNlZSBPYmplY3RJbnB1dFN0cmVhbSNyZWFkT2JqZWN0KCkKKyAgICAgKi8KKyAgICBwcml2YXRlIGludCB3cml0ZU9iamVjdEludGVybmFsKE9iamVjdCBvYmplY3QsIGJvb2xlYW4gdW5zaGFyZWQsCisgICAgICAgICAgICBib29sZWFuIGNvbXB1dGVDbGFzc0Jhc2VkUmVwbGFjZW1lbnQsCisgICAgICAgICAgICBib29sZWFuIGNvbXB1dGVTdHJlYW1SZXBsYWNlbWVudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHdyaXRlTnVsbCgpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGludCBoYW5kbGUgPSAtMTsKKyAgICAgICAgaWYgKCF1bnNoYXJlZCkgeworICAgICAgICAgICAgaGFuZGxlID0gZHVtcEN5Y2xlKG9iamVjdCk7CisgICAgICAgICAgICBpZiAoaGFuZGxlICE9IC0xKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZTsgLy8gY3ljbGljIHJlZmVyZW5jZQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gTm9uLW51bGwgb2JqZWN0LCBmaXJzdCB0aW1lIHNlZW4uLi4KKyAgICAgICAgQ2xhc3M8Pz4gb2JqQ2xhc3MgPSBvYmplY3QuZ2V0Q2xhc3MoKTsKKyAgICAgICAgT2JqZWN0U3RyZWFtQ2xhc3MgY2xEZXNjID0gT2JqZWN0U3RyZWFtQ2xhc3MubG9va3VwU3RyZWFtQ2xhc3Mob2JqQ2xhc3MpOworCisgICAgICAgIG5lc3RlZExldmVscysrOworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBpZiAoIShlbmFibGVSZXBsYWNlICYmIGNvbXB1dGVTdHJlYW1SZXBsYWNlbWVudCkpIHsKKyAgICAgICAgICAgICAgICAvLyBJcyBpdCBhIENsYXNzID8KKyAgICAgICAgICAgICAgICBpZiAob2JqQ2xhc3MgPT0gT2JqZWN0U3RyZWFtQ2xhc3MuQ0xBU1NDTEFTUykgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gd3JpdGVOZXdDbGFzcygoQ2xhc3M8Pz4pIG9iamVjdCwgdW5zaGFyZWQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBJcyBpdCBhbiBPYmplY3RTdHJlYW1DbGFzcyA/CisgICAgICAgICAgICAgICAgaWYgKG9iakNsYXNzID09IE9iamVjdFN0cmVhbUNsYXNzLk9CSkVDVFNUUkVBTUNMQVNTQ0xBU1MpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdyaXRlQ2xhc3NEZXNjKChPYmplY3RTdHJlYW1DbGFzcykgb2JqZWN0LCB1bnNoYXJlZCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoY2xEZXNjLmlzU2VyaWFsaXphYmxlKCkgJiYgY29tcHV0ZUNsYXNzQmFzZWRSZXBsYWNlbWVudCkgeworICAgICAgICAgICAgICAgIGlmIChjbERlc2MuaGFzTWV0aG9kV3JpdGVSZXBsYWNlKCkpeworICAgICAgICAgICAgICAgICAgICBNZXRob2QgbWV0aG9kV3JpdGVSZXBsYWNlID0gY2xEZXNjLmdldE1ldGhvZFdyaXRlUmVwbGFjZSgpOworICAgICAgICAgICAgICAgICAgICBPYmplY3QgcmVwbE9iaiA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXBsT2JqID0gbWV0aG9kV3JpdGVSZXBsYWNlLmludm9rZShvYmplY3QsIChPYmplY3RbXSkgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXBsT2JqID0gb2JqZWN0OworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGl0ZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gV0FSTklORyAtIE5vdCBzdXJlIHRoaXMgaXMgdGhlIHJpZ2h0IHRoaW5nIHRvIGRvCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB3ZSBjYW4ndCBydW4gdGhlIG1ldGhvZAorICAgICAgICAgICAgICAgICAgICAgICAgVGhyb3dhYmxlIHRhcmdldCA9IGl0ZS5nZXRUYXJnZXRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQgaW5zdGFuY2VvZiBPYmplY3RTdHJlYW1FeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAoT2JqZWN0U3RyZWFtRXhjZXB0aW9uKSB0YXJnZXQ7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldCBpbnN0YW5jZW9mIEVycm9yKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKSB0YXJnZXQ7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IChSdW50aW1lRXhjZXB0aW9uKSB0YXJnZXQ7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKHJlcGxPYmogIT0gb2JqZWN0KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBBbGwgb3ZlciwgY2xhc3MtYmFzZWQgcmVwbGFjZW1lbnQgb2ZmIHRoaXMgdGltZS4KKyAgICAgICAgICAgICAgICAgICAgICAgIGludCByZXBsYWNlbWVudEhhbmRsZSA9IHdyaXRlT2JqZWN0SW50ZXJuYWwocmVwbE9iaiwgZmFsc2UsIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wdXRlU3RyZWFtUmVwbGFjZW1lbnQpOworICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFrZSB0aGUgb3JpZ2luYWwgb2JqZWN0IGFsc28gbWFwIHRvIHRoZSBzYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBoYW5kbGUuCisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwbGFjZW1lbnRIYW5kbGUgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3RzV3JpdHRlbi5wdXQob2JqZWN0LCByZXBsYWNlbWVudEhhbmRsZSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVwbGFjZW1lbnRIYW5kbGU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gV2UgZ2V0IGhlcmUgZWl0aGVyIGlmIGNsYXNzLWJhc2VkIHJlcGxhY2VtZW50IHdhcyBub3QgbmVlZGVkIG9yCisgICAgICAgICAgICAvLyBpZiBpdCB3YXMgbmVlZGVkIGJ1dCBwcm9kdWNlZCB0aGUgc2FtZSBvYmplY3Qgb3IgaWYgaXQgY291bGQgbm90CisgICAgICAgICAgICAvLyBiZSBjb21wdXRlZC4KKyAgICAgICAgICAgIGlmIChlbmFibGVSZXBsYWNlICYmIGNvbXB1dGVTdHJlYW1SZXBsYWNlbWVudCkgeworICAgICAgICAgICAgICAgIC8vIE5vdyB3ZSBjb21wdXRlIHRoZSBzdHJlYW0tZGVmaW5lZCByZXBsYWNlbWVudC4KKyAgICAgICAgICAgICAgICBPYmplY3Qgc3RyZWFtUmVwbGFjZW1lbnQgPSByZXBsYWNlT2JqZWN0KG9iamVjdCk7CisgICAgICAgICAgICAgICAgaWYgKHN0cmVhbVJlcGxhY2VtZW50ICE9IG9iamVjdCkgeworICAgICAgICAgICAgICAgICAgICAvLyBBbGwgb3ZlciwgY2xhc3MtYmFzZWQgcmVwbGFjZW1lbnQgb2ZmIHRoaXMgdGltZS4KKyAgICAgICAgICAgICAgICAgICAgaW50IHJlcGxhY2VtZW50SGFuZGxlID0gd3JpdGVPYmplY3RJbnRlcm5hbChzdHJlYW1SZXBsYWNlbWVudCwgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcHV0ZUNsYXNzQmFzZWRSZXBsYWNlbWVudCwgZmFsc2UpOworICAgICAgICAgICAgICAgICAgICAvLyBNYWtlIHRoZSBvcmlnaW5hbCBvYmplY3QgYWxzbyBtYXAgdG8gdGhlIHNhbWUgaGFuZGxlLgorICAgICAgICAgICAgICAgICAgICBpZiAocmVwbGFjZW1lbnRIYW5kbGUgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdHNXcml0dGVuLnB1dChvYmplY3QsIHJlcGxhY2VtZW50SGFuZGxlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVwbGFjZW1lbnRIYW5kbGU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBXZSBnZXQgaGVyZSBpZiBzdHJlYW0tYmFzZWQgcmVwbGFjZW1lbnQgcHJvZHVjZWQgdGhlIHNhbWUgb2JqZWN0CisKKyAgICAgICAgICAgIC8vIElzIGl0IGEgQ2xhc3MgPworICAgICAgICAgICAgaWYgKG9iakNsYXNzID09IE9iamVjdFN0cmVhbUNsYXNzLkNMQVNTQ0xBU1MpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gd3JpdGVOZXdDbGFzcygoQ2xhc3M8Pz4pIG9iamVjdCwgdW5zaGFyZWQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBJcyBpdCBhbiBPYmplY3RTdHJlYW1DbGFzcyA/CisgICAgICAgICAgICBpZiAob2JqQ2xhc3MgPT0gT2JqZWN0U3RyZWFtQ2xhc3MuT0JKRUNUU1RSRUFNQ0xBU1NDTEFTUykgeworICAgICAgICAgICAgICAgIHJldHVybiB3cml0ZUNsYXNzRGVzYygoT2JqZWN0U3RyZWFtQ2xhc3MpIG9iamVjdCwgdW5zaGFyZWQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBJcyBpdCBhIFN0cmluZyA/IChpbnN0YW5jZW9mLCBidXQgPT0gaXMgZmFzdGVyKQorICAgICAgICAgICAgaWYgKG9iakNsYXNzID09IE9iamVjdFN0cmVhbUNsYXNzLlNUUklOR0NMQVNTKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHdyaXRlTmV3U3RyaW5nKChTdHJpbmcpIG9iamVjdCwgdW5zaGFyZWQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBJcyBpdCBhbiBBcnJheSA/CisgICAgICAgICAgICBpZiAob2JqQ2xhc3MuaXNBcnJheSgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHdyaXRlTmV3QXJyYXkob2JqZWN0LCBvYmpDbGFzcywgY2xEZXNjLCBvYmpDbGFzcworICAgICAgICAgICAgICAgICAgICAgICAgLmdldENvbXBvbmVudFR5cGUoKSwgdW5zaGFyZWQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgRW51bSkgeworICAgICAgICAgICAgICAgIHJldHVybiB3cml0ZU5ld0VudW0ob2JqZWN0LCBvYmpDbGFzcywgdW5zaGFyZWQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBOb3QgYSBTdHJpbmcgb3IgQ2xhc3Mgb3IgQXJyYXkuIERlZmF1bHQgcHJvY2VkdXJlLgorICAgICAgICAgICAgcmV0dXJuIHdyaXRlTmV3T2JqZWN0KG9iamVjdCwgb2JqQ2xhc3MsIGNsRGVzYywgdW5zaGFyZWQpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbmVzdGVkTGV2ZWxzLS07CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyB3cml0ZSBmb3IgRW51bSBDbGFzcyBEZXNjIG9ubHksIHdoaWNoIGlzIGRpZmZlcmVudCBmcm9tIG90aGVyIGNsYXNzZXMKKyAgICBwcml2YXRlIE9iamVjdFN0cmVhbUNsYXNzIHdyaXRlRW51bURlc2MoQ2xhc3M8Pz4gdGhlQ2xhc3MsIE9iamVjdFN0cmVhbUNsYXNzIGNsYXNzRGVzYywgYm9vbGVhbiB1bnNoYXJlZCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIHdyaXRlIGNsYXNzRGVzYywgY2xhc3NEZXNjIGZvciBlbnVtIGlzIGRpZmZlcmVudAorCisgICAgICAgIC8vIHNldCBmbGFnIGZvciBlbnVtLCB0aGUgZmxhZyBpcyAoU0NfU0VSSUFMSVpBQkxFIHwgU0NfRU5VTSkKKyAgICAgICAgY2xhc3NEZXNjLnNldEZsYWdzKChieXRlKSAoU0NfU0VSSUFMSVpBQkxFIHwgU0NfRU5VTSkpOworICAgICAgICBpbnQgcHJldmlvdXNIYW5kbGUgPSAtMTsKKyAgICAgICAgaWYgKHVuc2hhcmVkKSB7CisgICAgICAgICAgICBwcmV2aW91c0hhbmRsZSA9IG9iamVjdHNXcml0dGVuLmdldChjbGFzc0Rlc2MpOworICAgICAgICB9CisgICAgICAgIGludCBoYW5kbGUgPSAtMTsKKyAgICAgICAgaWYgKCF1bnNoYXJlZCkgeworICAgICAgICAgICAgaGFuZGxlID0gZHVtcEN5Y2xlKGNsYXNzRGVzYyk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGhhbmRsZSA9PSAtMSkgeworICAgICAgICAgICAgQ2xhc3M8Pz4gY2xhc3NUb1dyaXRlID0gY2xhc3NEZXNjLmZvckNsYXNzKCk7CisgICAgICAgICAgICAvLyBJZiB3ZSBnb3QgaGVyZSwgaXQgaXMgYSBuZXcgKG5vbi1udWxsKSBjbGFzc0Rlc2MgdGhhdCB3aWxsIGhhdmUKKyAgICAgICAgICAgIC8vIHRvIGJlIHJlZ2lzdGVyZWQgYXMgd2VsbAorICAgICAgICAgICAgcmVnaXN0ZXJPYmplY3RXcml0dGVuKGNsYXNzRGVzYyk7CisKKyAgICAgICAgICAgIG91dHB1dC53cml0ZUJ5dGUoVENfQ0xBU1NERVNDKTsKKyAgICAgICAgICAgIGlmIChwcm90b2NvbFZlcnNpb24gPT0gUFJPVE9DT0xfVkVSU0lPTl8xKSB7CisgICAgICAgICAgICAgICAgd3JpdGVOZXdDbGFzc0Rlc2MoY2xhc3NEZXNjKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gU28gd3JpdGUuLi4oKSBtZXRob2RzIGNhbiBiZSB1c2VkIGJ5CisgICAgICAgICAgICAgICAgLy8gc3ViY2xhc3NlcyBkdXJpbmcgd3JpdGVDbGFzc0Rlc2NyaXB0b3IoKQorICAgICAgICAgICAgICAgIHByaW1pdGl2ZVR5cGVzID0gb3V0cHV0OworICAgICAgICAgICAgICAgIHdyaXRlQ2xhc3NEZXNjcmlwdG9yKGNsYXNzRGVzYyk7CisgICAgICAgICAgICAgICAgcHJpbWl0aXZlVHlwZXMgPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gRXh0cmEgY2xhc3MgaW5mbyAob3B0aW9uYWwpCisgICAgICAgICAgICBhbm5vdGF0ZUNsYXNzKGNsYXNzVG9Xcml0ZSk7CisgICAgICAgICAgICBkcmFpbigpOyAvLyBmbHVzaCBwcmltaXRpdmUgdHlwZXMgaW4gdGhlIGFubm90YXRpb24KKyAgICAgICAgICAgIG91dHB1dC53cml0ZUJ5dGUoVENfRU5EQkxPQ0tEQVRBKTsKKyAgICAgICAgICAgIC8vIHdyaXRlIHN1cGVyIGNsYXNzCisgICAgICAgICAgICBPYmplY3RTdHJlYW1DbGFzcyBzdXBlckNsYXNzRGVzYyA9IGNsYXNzRGVzYy5nZXRTdXBlcmNsYXNzKCk7CisgICAgICAgICAgICBpZiAoc3VwZXJDbGFzc0Rlc2MgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIHN1cGVyIGNsYXNzIGlzIGFsc28gZW51bQorICAgICAgICAgICAgICAgIHN1cGVyQ2xhc3NEZXNjLnNldEZsYWdzKChieXRlKSAoU0NfU0VSSUFMSVpBQkxFIHwgU0NfRU5VTSkpOworICAgICAgICAgICAgICAgIHdyaXRlRW51bURlc2Moc3VwZXJDbGFzc0Rlc2MuZm9yQ2xhc3MoKSwgc3VwZXJDbGFzc0Rlc2MsIHVuc2hhcmVkKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlQnl0ZShUQ19OVUxMKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh1bnNoYXJlZCkgeworICAgICAgICAgICAgICAgIC8vIHJlbW92ZSByZWZlcmVuY2UgdG8gdW5zaGFyZWQgb2JqZWN0CisgICAgICAgICAgICAgICAgcmVtb3ZlVW5zaGFyZWRSZWZlcmVuY2UoY2xhc3NEZXNjLCBwcmV2aW91c0hhbmRsZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNsYXNzRGVzYzsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCB3cml0ZU5ld0VudW0oT2JqZWN0IG9iamVjdCwgQ2xhc3M8Pz4gdGhlQ2xhc3MsIGJvb2xlYW4gdW5zaGFyZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIHdyaXRlIG5ldyBFbnVtCisgICAgICAgIEVtdWxhdGVkRmllbGRzRm9yRHVtcGluZyBvcmlnaW5hbEN1cnJlbnRQdXRGaWVsZCA9IGN1cnJlbnRQdXRGaWVsZDsgLy8gc2F2ZQorICAgICAgICAvLyBudWxsIGl0LCB0byBtYWtlIHN1cmUgb25lIHdpbGwgYmUgY29tcHV0ZWQgaWYgbmVlZGVkCisgICAgICAgIGN1cnJlbnRQdXRGaWVsZCA9IG51bGw7CisKKyAgICAgICAgb3V0cHV0LndyaXRlQnl0ZShUQ19FTlVNKTsKKyAgICAgICAgd2hpbGUgKHRoZUNsYXNzICE9IG51bGwgJiYgIXRoZUNsYXNzLmlzRW51bSgpKSB7CisgICAgICAgICAgICAvLyB3cml0ZSBlbnVtIG9ubHkKKyAgICAgICAgICAgIHRoZUNsYXNzID0gdGhlQ2xhc3MuZ2V0U3VwZXJjbGFzcygpOworICAgICAgICB9CisgICAgICAgIE9iamVjdFN0cmVhbUNsYXNzIGNsYXNzRGVzYyA9IE9iamVjdFN0cmVhbUNsYXNzLmxvb2t1cCh0aGVDbGFzcyk7CisgICAgICAgIHdyaXRlRW51bURlc2ModGhlQ2xhc3MsIGNsYXNzRGVzYywgdW5zaGFyZWQpOworCisgICAgICAgIGludCBwcmV2aW91c0hhbmRsZSA9IC0xOworICAgICAgICBpZiAodW5zaGFyZWQpIHsKKyAgICAgICAgICAgIHByZXZpb3VzSGFuZGxlID0gb2JqZWN0c1dyaXR0ZW4uZ2V0KG9iamVjdCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGhhbmRsZSA9IHJlZ2lzdGVyT2JqZWN0V3JpdHRlbihvYmplY3QpOworCisgICAgICAgIE9iamVjdFN0cmVhbUZpZWxkW10gZmllbGRzID0gY2xhc3NEZXNjLmdldFN1cGVyY2xhc3MoKS5maWVsZHMoKTsKKyAgICAgICAgLy8gT25seSB3cml0ZSBmaWVsZCAibmFtZSIgZm9yIGVudW0gY2xhc3MsIHdoaWNoIGlzIHRoZSBzZWNvbmQgZmllbGQgb2YKKyAgICAgICAgLy8gZW51bSwgdGhhdCBpcyBmaWVsZHNbMV0uIElnbm9yZSBhbGwgbm9uLWZpZWxkcyBhbmQgZmllbGRzLmxlbmd0aCA8IDIKKyAgICAgICAgaWYgKGZpZWxkcyAhPSBudWxsICYmIGZpZWxkcy5sZW5ndGggPiAxKSB7CisgICAgICAgICAgICBGaWVsZCBmaWVsZCA9IGNsYXNzRGVzYy5nZXRTdXBlcmNsYXNzKCkuZ2V0UmVmbGVjdGlvbkZpZWxkKGZpZWxkc1sxXSk7CisgICAgICAgICAgICBpZiAoZmllbGQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hGaWVsZEVycm9yKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFN0cmluZyBzdHIgPSAoU3RyaW5nKSBmaWVsZC5nZXQob2JqZWN0KTsKKyAgICAgICAgICAgICAgICBpbnQgc3RySGFuZGxlID0gLTE7CisgICAgICAgICAgICAgICAgaWYgKCF1bnNoYXJlZCkgeworICAgICAgICAgICAgICAgICAgICBzdHJIYW5kbGUgPSBkdW1wQ3ljbGUoc3RyKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHN0ckhhbmRsZSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICB3cml0ZU5ld1N0cmluZyhzdHIsIHVuc2hhcmVkKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihpYWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKHVuc2hhcmVkKSB7CisgICAgICAgICAgICAvLyByZW1vdmUgcmVmZXJlbmNlIHRvIHVuc2hhcmVkIG9iamVjdAorICAgICAgICAgICAgcmVtb3ZlVW5zaGFyZWRSZWZlcmVuY2Uob2JqZWN0LCBwcmV2aW91c0hhbmRsZSk7CisgICAgICAgIH0KKyAgICAgICAgY3VycmVudFB1dEZpZWxkID0gb3JpZ2luYWxDdXJyZW50UHV0RmllbGQ7CisgICAgICAgIHJldHVybiBoYW5kbGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWV0aG9kIHRvIGJlIG92ZXJyaWRkZW4gYnkgc3ViY2xhc3NlcyB0byB3cml0ZSB7QGNvZGUgb2JqZWN0fSB0byB0aGUKKyAgICAgKiB0YXJnZXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byB3cml0ZSB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgd3JpdGVPYmplY3RPdmVycmlkZShPYmplY3Qgb2JqZWN0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIXN1YmNsYXNzT3ZlcnJpZGluZ0ltcGxlbWVudGF0aW9uKSB7CisgICAgICAgICAgICAvLyBTdWJjbGFzc2VzIG11c3Qgb3ZlcnJpZGUuCisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIHNob3J0ICgxNiBiaXQpIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgc2hvcnQgdG8gd3JpdGUgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlU2hvcnQoaW50IHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja1dyaXRlUHJpbWl0aXZlVHlwZXMoKTsKKyAgICAgICAgcHJpbWl0aXZlVHlwZXMud3JpdGVTaG9ydCh2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSB7QGxpbmsgT2JqZWN0T3V0cHV0U3RyZWFtfSBoZWFkZXIgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgd3JpdGVTdHJlYW1IZWFkZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXRwdXQud3JpdGVTaG9ydChTVFJFQU1fTUFHSUMpOworICAgICAgICBvdXRwdXQud3JpdGVTaG9ydChTVFJFQU1fVkVSU0lPTik7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgc3RyaW5nIGVuY29kZWQgd2l0aCB7QGxpbmsgRGF0YUlucHV0IG1vZGlmaWVkIFVURi04fSB0byB0aGUKKyAgICAgKiB0YXJnZXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHdyaXRlIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVVURihTdHJpbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrV3JpdGVQcmltaXRpdmVUeXBlcygpOworICAgICAgICBwcmltaXRpdmVUeXBlcy53cml0ZVVURih2YWx1ZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vT2JqZWN0U3RyZWFtQ2xhc3MuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL09iamVjdFN0cmVhbUNsYXNzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTg3ZmNkNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL09iamVjdFN0cmVhbUNsYXNzLmphdmEKQEAgLTAsMCArMSwxMzAzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmLlNvZnRSZWZlcmVuY2U7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuRmllbGQ7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1vZGlmaWVyOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlByb3h5OworaW1wb3J0IGphdmEubmlvLkJ5dGVPcmRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db21wYXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5XZWFrSGFzaE1hcDsKK2ltcG9ydCBsaWJjb3JlLmlvLk1lbW9yeTsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuRW1wdHlBcnJheTsKKworLyoqCisgKiBSZXByZXNlbnRzIGEgZGVzY3JpcHRvciBmb3IgaWRlbnRpZnlpbmcgYSBjbGFzcyBkdXJpbmcgc2VyaWFsaXphdGlvbiBhbmQKKyAqIGRlc2VyaWFsaXphdGlvbi4gSW5mb3JtYXRpb24gY29udGFpbmVkIGluIHRoZSBkZXNjcmlwdG9yIGluY2x1ZGVzIHRoZSBuYW1lCisgKiBhbmQgU1VJRCBvZiB0aGUgY2xhc3MgYXMgd2VsbCBhcyBmaWVsZCBuYW1lcyBhbmQgdHlwZXMuIEluZm9ybWF0aW9uIGluaGVyaXRlZAorICogZnJvbSB0aGUgc3VwZXJjbGFzc2VzIGlzIGFsc28gdGFrZW4gaW50byBhY2NvdW50LgorICoKKyAqIEBzZWUgT2JqZWN0T3V0cHV0U3RyZWFtCisgKiBAc2VlIE9iamVjdElucHV0U3RyZWFtCisgKiBAc2VlIGphdmEubGFuZy5DbGFzcworICovCitwdWJsaWMgY2xhc3MgT2JqZWN0U3RyZWFtQ2xhc3MgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgLy8gTm8gbmVlZCB0byBjb21wdXRlIHRoZSBTVUlEIGZvciBPYmplY3RTdHJlYW1DbGFzcywganVzdCB1c2UgdGhlIHZhbHVlCisgICAgLy8gYmVsb3cKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjEyMDgzMjY4MjA4MDQzNzM2OEw7CisKKyAgICAvLyBOYW1lIG9mIHRoZSBmaWVsZCB0aGF0IGNvbnRhaW5zIHRoZSBTVUlEIHZhbHVlIChpZiBwcmVzZW50KQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBVSURfRklFTERfTkFNRSA9ICJzZXJpYWxWZXJzaW9uVUlEIjsKKworICAgIHN0YXRpYyBmaW5hbCBsb25nIENPTlNUUlVDVE9SX0lTX05PVF9SRVNPTFZFRCA9IC0xOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENMQVNTX01PRElGSUVSU19NQVNLID0gTW9kaWZpZXIuUFVCTElDIHwgTW9kaWZpZXIuRklOQUwgfAorICAgICAgICAgICAgTW9kaWZpZXIuSU5URVJGQUNFIHwgTW9kaWZpZXIuQUJTVFJBQ1Q7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTU9ESUZJRVJTX01BU0sgPSBNb2RpZmllci5QVUJMSUMgfCBNb2RpZmllci5QUklWQVRFIHwKKyAgICAgICAgICAgIE1vZGlmaWVyLlBST1RFQ1RFRCB8IE1vZGlmaWVyLlNUQVRJQyB8IE1vZGlmaWVyLkZJTkFMIHwgTW9kaWZpZXIuVk9MQVRJTEUgfAorICAgICAgICAgICAgTW9kaWZpZXIuVFJBTlNJRU5UOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1FVEhPRF9NT0RJRklFUlNfTUFTSyA9IE1vZGlmaWVyLlBVQkxJQyB8IE1vZGlmaWVyLlBSSVZBVEUgfAorICAgICAgICAgICAgTW9kaWZpZXIuUFJPVEVDVEVEIHwgTW9kaWZpZXIuU1RBVElDIHwgTW9kaWZpZXIuRklOQUwgfCBNb2RpZmllci5TWU5DSFJPTklaRUQgfAorICAgICAgICAgICAgTW9kaWZpZXIuTkFUSVZFIHwgTW9kaWZpZXIuQUJTVFJBQ1QgfCBNb2RpZmllci5TVFJJQ1Q7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDbGFzczw/PltdIFJFQURfUEFSQU1fVFlQRVMgPSBuZXcgQ2xhc3NbXSB7IE9iamVjdElucHV0U3RyZWFtLmNsYXNzIH07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ2xhc3M8Pz5bXSBXUklURV9QQVJBTV9UWVBFUyA9IG5ldyBDbGFzc1tdIHsgT2JqZWN0T3V0cHV0U3RyZWFtLmNsYXNzIH07CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCBpbmRpY2F0aW5nIHRoYXQgdGhlIGNsYXNzIGhhcyBubyBTZXJpYWxpemFibGUgZmllbGRzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgT2JqZWN0U3RyZWFtRmllbGRbXSBOT19GSUVMRFMgPSBuZXcgT2JqZWN0U3RyZWFtRmllbGRbMF07CisKKyAgICAvKgorICAgICAqIHVzZWQgdG8gZmV0Y2ggZmllbGQgc2VyaWFsUGVyc2lzdGVudEZpZWxkcyBhbmQgY2hlY2tpbmcgaXRzIHR5cGUKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgQ2xhc3M8Pz4gQVJSQVlfT0ZfRklFTERTOworCisgICAgc3RhdGljIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFSUkFZX09GX0ZJRUxEUyA9IENsYXNzLmZvck5hbWUoIltMamF2YS5pby5PYmplY3RTdHJlYW1GaWVsZDsiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBUaGlzIHNob3VsZCBub3QgaGFwcGVuCisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0xJTklUX05BTUUgPSAiPGNsaW5pdD4iOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENMSU5JVF9NT0RJRklFUlMgPSBNb2RpZmllci5TVEFUSUM7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0xJTklUX1NJR05BVFVSRSA9ICIoKVYiOworCisgICAgLy8gVXNlZCB0byBkZXRlcm1pbmUgaWYgYW4gb2JqZWN0IGlzIFNlcmlhbGl6YWJsZSBvciBFeHRlcm5hbGl6YWJsZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENsYXNzPFNlcmlhbGl6YWJsZT4gU0VSSUFMSVpBQkxFID0gU2VyaWFsaXphYmxlLmNsYXNzOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ2xhc3M8RXh0ZXJuYWxpemFibGU+IEVYVEVSTkFMSVpBQkxFID0gRXh0ZXJuYWxpemFibGUuY2xhc3M7CisKKyAgICAvLyBVc2VkIHRvIHRlc3QgaWYgdGhlIG9iamVjdCBpcyBhIFN0cmluZyBvciBhIGNsYXNzLgorICAgIHN0YXRpYyBmaW5hbCBDbGFzczxTdHJpbmc+IFNUUklOR0NMQVNTID0gU3RyaW5nLmNsYXNzOworCisgICAgc3RhdGljIGZpbmFsIENsYXNzPD8+IENMQVNTQ0xBU1MgPSBDbGFzcy5jbGFzczsKKworICAgIHN0YXRpYyBmaW5hbCBDbGFzczxPYmplY3RTdHJlYW1DbGFzcz4gT0JKRUNUU1RSRUFNQ0xBU1NDTEFTUyA9IE9iamVjdFN0cmVhbUNsYXNzLmNsYXNzOworCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgTWV0aG9kIG1ldGhvZFdyaXRlUmVwbGFjZTsKKworICAgIHByaXZhdGUgdHJhbnNpZW50IE1ldGhvZCBtZXRob2RSZWFkUmVzb2x2ZTsKKworICAgIHByaXZhdGUgdHJhbnNpZW50IE1ldGhvZCBtZXRob2RXcml0ZU9iamVjdDsKKworICAgIHByaXZhdGUgdHJhbnNpZW50IE1ldGhvZCBtZXRob2RSZWFkT2JqZWN0OworCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgTWV0aG9kIG1ldGhvZFJlYWRPYmplY3ROb0RhdGE7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgY2xhc3MgcHJvcGVydGllcyByZXNvbHZlZAorICAgICAqCisgICAgICogQHNlZSAjcmVzb2x2ZVByb3BlcnRpZXMoKQorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IGJvb2xlYW4gYXJlUHJvcGVydGllc1Jlc29sdmVkOworCisgICAgLyoqCisgICAgICogQ2FjaGVkIGNsYXNzIHByb3BlcnRpZXMKKyAgICAgKgorICAgICAqIEBzZWUgI3Jlc29sdmVQcm9wZXJ0aWVzKCkKKyAgICAgKiBAc2VlICNpc1NlcmlhbGl6YWJsZSgpCisgICAgICogQHNlZSAjaXNFeHRlcm5hbGl6YWJsZSgpCisgICAgICogQHNlZSAjaXNQcm94eSgpCisgICAgICogQHNlZSAjaXNFbnVtKCkKKyAgICAgKi8KKyAgICBwcml2YXRlIHRyYW5zaWVudCBib29sZWFuIGlzU2VyaWFsaXphYmxlOworICAgIHByaXZhdGUgdHJhbnNpZW50IGJvb2xlYW4gaXNFeHRlcm5hbGl6YWJsZTsKKyAgICBwcml2YXRlIHRyYW5zaWVudCBib29sZWFuIGlzUHJveHk7CisgICAgcHJpdmF0ZSB0cmFuc2llbnQgYm9vbGVhbiBpc0VudW07CisKKyAgICAvLyBDbGFzc0Rlc2MgLy8KKworICAgIC8vIE5hbWUgb2YgdGhlIGNsYXNzIHRoaXMgZGVzY3JpcHRvciByZXByZXNlbnRzCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgU3RyaW5nIGNsYXNzTmFtZTsKKworICAgIC8vIENvcnJlc3BvbmRpbmcgbG9hZGVkIGNsYXNzIHdpdGggdGhlIG5hbWUgYWJvdmUKKyAgICBwcml2YXRlIHRyYW5zaWVudCBDbGFzczw/PiByZXNvbHZlZENsYXNzOworCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgQ2xhc3M8Pz4gcmVzb2x2ZWRDb25zdHJ1Y3RvckNsYXNzOworICAgIHByaXZhdGUgdHJhbnNpZW50IGludCByZXNvbHZlZENvbnN0cnVjdG9yTWV0aG9kSWQ7CisKKyAgICAvLyBTZXJpYWwgdmVyc2lvbiBVSUQgb2YgdGhlIGNsYXNzIHRoZSBkZXNjcmlwdG9yIHJlcHJlc2VudHMKKyAgICBwcml2YXRlIHRyYW5zaWVudCBsb25nIHN2VUlEOworCisgICAgLy8gQ2xhc3NEZXNjSW5mbyAvLworCisgICAgLy8gQW55IGNvbWJpbmF0aW9uIG9mIFNDX1dSSVRFX01FVEhPRCwgU0NfU0VSSUFMSVpBQkxFIGFuZCBTQ19FWFRFUk5BTElaQUJMRQorICAgIC8vIChzZWUgT2JqZWN0U3RyZWFtQ29uc3RhbnRzKQorICAgIHByaXZhdGUgdHJhbnNpZW50IGJ5dGUgZmxhZ3M7CisKKyAgICAvLyBEZXNjcmlwdG9yIGZvciB0aGUgc3VwZXJjbGFzcyBvZiB0aGUgY2xhc3MgYXNzb2NpYXRlZCB3aXRoIHRoaXMKKyAgICAvLyBkZXNjcmlwdG9yCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgT2JqZWN0U3RyZWFtQ2xhc3Mgc3VwZXJjbGFzczsKKworICAgIC8vIEFycmF5IG9mIE9iamVjdFN0cmVhbUZpZWxkIChzZWUgYmVsb3cpIGRlc2NyaWJpbmcgdGhlIGZpZWxkcyBvZiB0aGlzCisgICAgLy8gY2xhc3MKKyAgICBwcml2YXRlIHRyYW5zaWVudCBPYmplY3RTdHJlYW1GaWVsZFtdIGZpZWxkczsKKworICAgIC8vIEFycmF5IG9mIE9iamVjdFN0cmVhbUZpZWxkIGRlc2NyaWJpbmcgdGhlIHNlcmlhbGl6ZWQgZmllbGRzIG9mIHRoaXMgY2xhc3MKKyAgICBwcml2YXRlIHRyYW5zaWVudCBPYmplY3RTdHJlYW1GaWVsZFtdIGxvYWRGaWVsZHM7CisKKyAgICAvLyBPYmplY3RTdHJlYW1GaWVsZCBkb2Vzbid0IG92ZXJyaWRlIGhhc2hDb2RlIG9yIGVxdWFscywgc28gdGhpcyBpcyBlcXVpdmFsZW50IHRvIGFuCisgICAgLy8gSWRlbnRpdHlIYXNoTWFwLCB3aGljaCBpcyBmaW5lIGZvciBvdXIgcHVycG9zZXMuCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgSGFzaE1hcDxPYmplY3RTdHJlYW1GaWVsZCwgRmllbGQ+IHJlZmxlY3Rpb25GaWVsZHMgPQorICAgICAgICAgICAgbmV3IEhhc2hNYXA8T2JqZWN0U3RyZWFtRmllbGQsIEZpZWxkPigpOworCisgICAgLy8gTWV0aG9kSUQgZm9yIGRlc2VyaWFsaXphdGlvbiBjb25zdHJ1Y3RvcgorICAgIHByaXZhdGUgdHJhbnNpZW50IGxvbmcgY29uc3RydWN0b3IgPSBDT05TVFJVQ1RPUl9JU19OT1RfUkVTT0xWRUQ7CisKKyAgICB2b2lkIHNldENvbnN0cnVjdG9yKGxvbmcgbmV3Q29uc3RydWN0b3IpIHsKKyAgICAgICAgY29uc3RydWN0b3IgPSBuZXdDb25zdHJ1Y3RvcjsKKyAgICB9CisKKyAgICBsb25nIGdldENvbnN0cnVjdG9yKCkgeworICAgICAgICByZXR1cm4gY29uc3RydWN0b3I7CisgICAgfQorCisgICAgRmllbGQgZ2V0UmVmbGVjdGlvbkZpZWxkKE9iamVjdFN0cmVhbUZpZWxkIG9zZikgeworICAgICAgICBzeW5jaHJvbml6ZWQgKHJlZmxlY3Rpb25GaWVsZHMpIHsKKyAgICAgICAgICAgIEZpZWxkIGZpZWxkID0gcmVmbGVjdGlvbkZpZWxkcy5nZXQob3NmKTsKKyAgICAgICAgICAgIGlmIChmaWVsZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZpZWxkOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENsYXNzPD8+IGRlY2xhcmluZ0NsYXNzID0gZm9yQ2xhc3MoKTsKKyAgICAgICAgICAgIEZpZWxkIGZpZWxkID0gZGVjbGFyaW5nQ2xhc3MuZ2V0RGVjbGFyZWRGaWVsZChvc2YuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGZpZWxkLnNldEFjY2Vzc2libGUodHJ1ZSk7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHJlZmxlY3Rpb25GaWVsZHMpIHsKKyAgICAgICAgICAgICAgICByZWZsZWN0aW9uRmllbGRzLnB1dChvc2YsIGZpZWxkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiByZWZsZWN0aW9uRmllbGRzLmdldChvc2YpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hGaWVsZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgLy8gVGhlIGNhbGxlciBtZXNzZWQgdXAuIFdlJ2xsIHJldHVybiBudWxsIGFuZCB3b24ndCB0cnkgdG8gcmVzb2x2ZSB0aGlzIGFnYWluLgorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIElmIGFuIE9iamVjdFN0cmVhbUNsYXNzIGRlc2NyaWJlcyBhbiBFeHRlcm5hbGl6YWJsZSBjbGFzcywgaXQgKHRoZQorICAgICAqIGRlc2NyaXB0b3IpIHNob3VsZCBub3QgaGF2ZSBmaWVsZCBkZXNjcmlwdG9ycyAoT2JqZWN0U3RyZWFtRmllbGQpIGF0IGFsbC4KKyAgICAgKiBUaGUgT2JqZWN0U3RyZWFtQ2xhc3MgdGhhdCBnZXRzIHNhdmVkIHNob3VsZCBzaW1wbHkgaGF2ZSBubyBmaWVsZCBpbmZvLgorICAgICAqIFRoaXMgaXMgYSBmb290bm90ZSBpbiBwYWdlIDE1MTEgKGNsYXNzIFNlcmlhbGl6YWJsZSkgb2YgIlRoZSBKYXZhIENsYXNzCisgICAgICogTGlicmFyaWVzLCBTZWNvbmQgRWRpdGlvbiwgVm9sLiBJIi4KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcy4KKyAgICAgKi8KKyAgICBPYmplY3RTdHJlYW1DbGFzcygpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlIGNsYXNzIGRlc2NyaXB0b3IgZm9yIGEgZ2l2ZW4gY2xhc3MgPGNvZGU+Y2w8L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtIGNsCisgICAgICogICAgICAgICAgICBhIGphdmEubGFuZ0NsYXNzIGZvciB3aGljaCB0byBjb21wdXRlIHRoZSBjb3JyZXNwb25kaW5nCisgICAgICogICAgICAgICAgICBkZXNjcmlwdG9yCisgICAgICogQHJldHVybiB0aGUgY29tcHV0ZXIgY2xhc3MgZGVzY3JpcHRvcgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIE9iamVjdFN0cmVhbUNsYXNzIGNyZWF0ZUNsYXNzRGVzYyhDbGFzczw/PiBjbCkgeworCisgICAgICAgIE9iamVjdFN0cmVhbUNsYXNzIHJlc3VsdCA9IG5ldyBPYmplY3RTdHJlYW1DbGFzcygpOworCisgICAgICAgIGJvb2xlYW4gaXNBcnJheSA9IGNsLmlzQXJyYXkoKTsKKyAgICAgICAgYm9vbGVhbiBzZXJpYWxpemFibGUgPSBpc1NlcmlhbGl6YWJsZShjbCk7CisgICAgICAgIGJvb2xlYW4gZXh0ZXJuYWxpemFibGUgPSBpc0V4dGVybmFsaXphYmxlKGNsKTsKKworICAgICAgICByZXN1bHQuaXNTZXJpYWxpemFibGUgPSBzZXJpYWxpemFibGU7CisgICAgICAgIHJlc3VsdC5pc0V4dGVybmFsaXphYmxlID0gZXh0ZXJuYWxpemFibGU7CisKKyAgICAgICAgLy8gTm93IHdlIGZpbGwgaW4gdGhlIHZhbHVlcworICAgICAgICByZXN1bHQuc2V0TmFtZShjbC5nZXROYW1lKCkpOworICAgICAgICByZXN1bHQuc2V0Q2xhc3MoY2wpOworICAgICAgICBDbGFzczw/PiBzdXBlcmNsYXNzID0gY2wuZ2V0U3VwZXJjbGFzcygpOworICAgICAgICBpZiAoc3VwZXJjbGFzcyAhPSBudWxsKSB7CisgICAgICAgICAgICByZXN1bHQuc2V0U3VwZXJjbGFzcyhsb29rdXAoc3VwZXJjbGFzcykpOworICAgICAgICB9CisKKyAgICAgICAgRmllbGRbXSBkZWNsYXJlZEZpZWxkcyA9IG51bGw7CisKKyAgICAgICAgLy8gQ29tcHV0ZSB0aGUgU1VJRAorICAgICAgICBpZiAoc2VyaWFsaXphYmxlIHx8IGV4dGVybmFsaXphYmxlKSB7CisgICAgICAgICAgICBpZiAocmVzdWx0LmlzRW51bSgpIHx8IHJlc3VsdC5pc1Byb3h5KCkpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuc2V0U2VyaWFsVmVyc2lvblVJRCgwTCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGRlY2xhcmVkRmllbGRzID0gY2wuZ2V0RGVjbGFyZWRGaWVsZHMoKTsKKyAgICAgICAgICAgICAgICByZXN1bHQuc2V0U2VyaWFsVmVyc2lvblVJRChjb21wdXRlU2VyaWFsVmVyc2lvblVJRChjbCwgZGVjbGFyZWRGaWVsZHMpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFNlcmlhbGl6YWJsZXMgbmVlZCBmaWVsZCBkZXNjcmlwdG9ycworICAgICAgICBpZiAoc2VyaWFsaXphYmxlICYmICFpc0FycmF5KSB7CisgICAgICAgICAgICBpZiAoZGVjbGFyZWRGaWVsZHMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGRlY2xhcmVkRmllbGRzID0gY2wuZ2V0RGVjbGFyZWRGaWVsZHMoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdC5idWlsZEZpZWxkRGVzY3JpcHRvcnMoZGVjbGFyZWRGaWVsZHMpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gRXh0ZXJuYWxpemFibGVzIG9yIGFycmF5cyBkbyBub3QgbmVlZCBGaWVsZERlc2MgaW5mbworICAgICAgICAgICAgcmVzdWx0LnNldEZpZWxkcyhOT19GSUVMRFMpOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ29weSBhbGwgZmllbGRzIHRvIGxvYWRGaWVsZHMgLSB0aGV5IHNob3VsZCBiZSByZWFkIGJ5IGRlZmF1bHQgaW4KKyAgICAgICAgLy8gT2JqZWN0SW5wdXRTdHJlYW0uZGVmYXVsdFJlYWRPYmplY3QoKSBtZXRob2QKKyAgICAgICAgT2JqZWN0U3RyZWFtRmllbGRbXSBmaWVsZHMgPSByZXN1bHQuZ2V0RmllbGRzKCk7CisKKyAgICAgICAgaWYgKGZpZWxkcyAhPSBudWxsKSB7CisgICAgICAgICAgICBPYmplY3RTdHJlYW1GaWVsZFtdIGxvYWRGaWVsZHMgPSBuZXcgT2JqZWN0U3RyZWFtRmllbGRbZmllbGRzLmxlbmd0aF07CisKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICAgICAgbG9hZEZpZWxkc1tpXSA9IG5ldyBPYmplY3RTdHJlYW1GaWVsZChmaWVsZHNbaV0uZ2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRzW2ldLmdldFR5cGUoKSwgZmllbGRzW2ldLmlzVW5zaGFyZWQoKSk7CisKKyAgICAgICAgICAgICAgICAvLyByZXNvbHZlIHR5cGUgc3RyaW5nIHRvIGluaXQgdHlwZVN0cmluZyBmaWVsZCBpbgorICAgICAgICAgICAgICAgIC8vIE9iamVjdFN0cmVhbUZpZWxkCisgICAgICAgICAgICAgICAgbG9hZEZpZWxkc1tpXS5nZXRUeXBlU3RyaW5nKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHQuc2V0TG9hZEZpZWxkcyhsb2FkRmllbGRzKTsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGUgZmxhZ3MgPSAwOworICAgICAgICBpZiAoZXh0ZXJuYWxpemFibGUpIHsKKyAgICAgICAgICAgIGZsYWdzIHw9IE9iamVjdFN0cmVhbUNvbnN0YW50cy5TQ19FWFRFUk5BTElaQUJMRTsKKyAgICAgICAgICAgIGZsYWdzIHw9IE9iamVjdFN0cmVhbUNvbnN0YW50cy5TQ19CTE9DS19EQVRBOyAvLyB1c2UgcHJvdG9jb2wgdmVyc2lvbiAyIGJ5IGRlZmF1bHQKKyAgICAgICAgfSBlbHNlIGlmIChzZXJpYWxpemFibGUpIHsKKyAgICAgICAgICAgIGZsYWdzIHw9IE9iamVjdFN0cmVhbUNvbnN0YW50cy5TQ19TRVJJQUxJWkFCTEU7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0Lm1ldGhvZFdyaXRlUmVwbGFjZSA9IGZpbmRNZXRob2QoY2wsICJ3cml0ZVJlcGxhY2UiKTsKKyAgICAgICAgcmVzdWx0Lm1ldGhvZFJlYWRSZXNvbHZlID0gZmluZE1ldGhvZChjbCwgInJlYWRSZXNvbHZlIik7CisgICAgICAgIHJlc3VsdC5tZXRob2RXcml0ZU9iamVjdCA9IGZpbmRQcml2YXRlTWV0aG9kKGNsLCAid3JpdGVPYmplY3QiLCBXUklURV9QQVJBTV9UWVBFUyk7CisgICAgICAgIHJlc3VsdC5tZXRob2RSZWFkT2JqZWN0ID0gZmluZFByaXZhdGVNZXRob2QoY2wsICJyZWFkT2JqZWN0IiwgUkVBRF9QQVJBTV9UWVBFUyk7CisgICAgICAgIHJlc3VsdC5tZXRob2RSZWFkT2JqZWN0Tm9EYXRhID0gZmluZFByaXZhdGVNZXRob2QoY2wsICJyZWFkT2JqZWN0Tm9EYXRhIiwgRW1wdHlBcnJheS5DTEFTUyk7CisgICAgICAgIGlmIChyZXN1bHQuaGFzTWV0aG9kV3JpdGVPYmplY3QoKSkgeworICAgICAgICAgICAgZmxhZ3MgfD0gT2JqZWN0U3RyZWFtQ29uc3RhbnRzLlNDX1dSSVRFX01FVEhPRDsKKyAgICAgICAgfQorICAgICAgICByZXN1bHQuc2V0RmxhZ3MoZmxhZ3MpOworCisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQnVpbGRzIHRoZSBjb2xsZWN0aW9uIG9mIGZpZWxkIGRlc2NyaXB0b3JzIGZvciB0aGUgcmVjZWl2ZXIKKyAgICAgKgorICAgICAqIEBwYXJhbSBkZWNsYXJlZEZpZWxkcworICAgICAqICAgICAgICAgICAgY29sbGVjdGlvbiBvZiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCBmb3Igd2hpY2ggdG8gY29tcHV0ZQorICAgICAqICAgICAgICAgICAgZmllbGQgZGVzY3JpcHRvcnMKKyAgICAgKi8KKyAgICB2b2lkIGJ1aWxkRmllbGREZXNjcmlwdG9ycyhGaWVsZFtdIGRlY2xhcmVkRmllbGRzKSB7CisgICAgICAgIC8vIFdlIGNvdWxkIGZpbmQgdGhlIGZpZWxkIG91cnNlbHZlcyBpbiB0aGUgY29sbGVjdGlvbiwgYnV0IGNhbGxpbmcKKyAgICAgICAgLy8gcmVmbGVjdCBpcyBlYXNpZXIuIE9wdGltaXplIGlmIG5lZWRlZC4KKyAgICAgICAgZmluYWwgRmllbGQgZiA9IE9iamVjdFN0cmVhbUNsYXNzLmZpZWxkU2VyaWFsUGVyc2lzdGVudEZpZWxkcyh0aGlzLmZvckNsYXNzKCkpOworICAgICAgICAvLyBJZiB3ZSBjb3VsZCBub3QgZmluZCB0aGUgZW11bGF0ZWQgZmllbGRzLCB3ZSdsbCBoYXZlIHRvIGNvbXB1dGUKKyAgICAgICAgLy8gZHVtcGFibGUgZmllbGRzIGZyb20gcmVmbGVjdCBmaWVsZHMKKyAgICAgICAgYm9vbGVhbiB1c2VSZWZsZWN0RmllbGRzID0gZiA9PSBudWxsOyAvLyBBc3N1bWUgd2Ugd2lsbCBjb21wdXRlIHRoZQorICAgICAgICAvLyBmaWVsZHMgdG8gZHVtcCBiYXNlZCBvbiB0aGUKKyAgICAgICAgLy8gcmVmbGVjdCBmaWVsZHMKKworICAgICAgICBPYmplY3RTdHJlYW1GaWVsZFtdIF9maWVsZHMgPSBudWxsOworICAgICAgICBpZiAoIXVzZVJlZmxlY3RGaWVsZHMpIHsKKyAgICAgICAgICAgIC8vIFRoZSB1c2VyIGRlY2xhcmVkIGEgY29sbGVjdGlvbiBvZiBlbXVsYXRlZCBmaWVsZHMuIFVzZSB0aGVtLgorICAgICAgICAgICAgLy8gV2UgaGF2ZSB0byBiZSBhYmxlIHRvIGZldGNoIGl0cyB2YWx1ZSwgZXZlbiBpZiBpdCBpcyBwcml2YXRlCisgICAgICAgICAgICBmLnNldEFjY2Vzc2libGUodHJ1ZSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIHN0YXRpYyBmaWVsZCwgcGFzcyBudWxsCisgICAgICAgICAgICAgICAgX2ZpZWxkcyA9IChPYmplY3RTdHJlYW1GaWVsZFtdKSBmLmdldChudWxsKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZXgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gQ29tcHV0ZSBjb2xsZWN0aW9uIG9mIGR1bXBhYmxlIGZpZWxkcyBiYXNlZCBvbiByZWZsZWN0IGZpZWxkcworICAgICAgICAgICAgTGlzdDxPYmplY3RTdHJlYW1GaWVsZD4gc2VyaWFsaXphYmxlRmllbGRzID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IEFycmF5TGlzdDxPYmplY3RTdHJlYW1GaWVsZD4oZGVjbGFyZWRGaWVsZHMubGVuZ3RoKTsKKyAgICAgICAgICAgIC8vIEZpbHRlciwgd2UgYXJlIG9ubHkgaW50ZXJlc3RlZCBpbiBmaWVsZHMgdGhhdCBhcmUgc2VyaWFsaXphYmxlCisgICAgICAgICAgICBmb3IgKEZpZWxkIGRlY2xhcmVkRmllbGQgOiBkZWNsYXJlZEZpZWxkcykgeworICAgICAgICAgICAgICAgIGludCBtb2RpZmllcnMgPSBkZWNsYXJlZEZpZWxkLmdldE1vZGlmaWVycygpOworICAgICAgICAgICAgICAgIGlmICghTW9kaWZpZXIuaXNTdGF0aWMobW9kaWZpZXJzKSAmJiAhTW9kaWZpZXIuaXNUcmFuc2llbnQobW9kaWZpZXJzKSkgeworICAgICAgICAgICAgICAgICAgICBPYmplY3RTdHJlYW1GaWVsZCBmaWVsZCA9IG5ldyBPYmplY3RTdHJlYW1GaWVsZChkZWNsYXJlZEZpZWxkLmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNsYXJlZEZpZWxkLmdldFR5cGUoKSk7CisgICAgICAgICAgICAgICAgICAgIHNlcmlhbGl6YWJsZUZpZWxkcy5hZGQoZmllbGQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHNlcmlhbGl6YWJsZUZpZWxkcy5zaXplKCkgPT0gMCkgeworICAgICAgICAgICAgICAgIF9maWVsZHMgPSBOT19GSUVMRFM7IC8vIElmIG5vIHNlcmlhbGl6YWJsZSBmaWVsZHMsIHNoYXJlIHRoZQorICAgICAgICAgICAgICAgIC8vIHNwZWNpYWwgdmFsdWUgc28gdGhhdCB1c2VycyBjYW4gdGVzdAorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBfZmllbGRzID0gc2VyaWFsaXphYmxlRmllbGRzLnRvQXJyYXkobmV3IE9iamVjdFN0cmVhbUZpZWxkW3NlcmlhbGl6YWJsZUZpZWxkcy5zaXplKCldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBBcnJheXMuc29ydChfZmllbGRzKTsKKyAgICAgICAgLy8gYXNzaWduIG9mZnNldHMKKyAgICAgICAgaW50IHByaW1PZmZzZXQgPSAwLCBvYmplY3RPZmZzZXQgPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF9maWVsZHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIENsYXNzPD8+IHR5cGUgPSBfZmllbGRzW2ldLmdldFR5cGUoKTsKKyAgICAgICAgICAgIGlmICh0eXBlLmlzUHJpbWl0aXZlKCkpIHsKKyAgICAgICAgICAgICAgICBfZmllbGRzW2ldLm9mZnNldCA9IHByaW1PZmZzZXQ7CisgICAgICAgICAgICAgICAgcHJpbU9mZnNldCArPSBwcmltaXRpdmVTaXplKHR5cGUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBfZmllbGRzW2ldLm9mZnNldCA9IG9iamVjdE9mZnNldCsrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZpZWxkcyA9IF9maWVsZHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZSBhbmQgcmV0dXJuIHRoZSBTZXJpYWwgVmVyc2lvbiBVSUQgb2YgdGhlIGNsYXNzIHtAY29kZSBjbH0uCisgICAgICogVGhlIHZhbHVlIGlzIGNvbXB1dGVkIGJhc2VkIG9uIHRoZSBjbGFzcyBuYW1lLCBzdXBlcmNsYXNzIGNoYWluLCBmaWVsZAorICAgICAqIG5hbWVzLCBtZXRob2QgbmFtZXMsIG1vZGlmaWVycywgZXRjLgorICAgICAqCisgICAgICogQHBhcmFtIGNsCisgICAgICogICAgICAgICAgICBhIGphdmEubGFuZy5DbGFzcyBmb3Igd2hpY2ggdG8gY29tcHV0ZSB0aGUgU1VJRAorICAgICAqIEBwYXJhbSBmaWVsZHMKKyAgICAgKiAgICAgICAgICAgIGNsLmdldERlY2xhcmVkRmllbGRzKCksIHByZS1jb21wdXRlZCBieSB0aGUgY2FsbGVyCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgU1VJRCBvZiB0aGlzIGNsYXNzCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgbG9uZyBjb21wdXRlU2VyaWFsVmVyc2lvblVJRChDbGFzczw/PiBjbCwgRmllbGRbXSBmaWVsZHMpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogRmlyc3Qgd2Ugc2hvdWxkIHRyeSB0byBmZXRjaCB0aGUgc3RhdGljIHNsb3QgJ3N0YXRpYyBmaW5hbCBsb25nCisgICAgICAgICAqIHNlcmlhbFZlcnNpb25VSUQnLiBJZiBpdCBpcyBkZWZpbmVkLCByZXR1cm4gaXQuIElmIG5vdCBkZWZpbmVkLCB3ZQorICAgICAgICAgKiByZWFsbHkgbmVlZCB0byBjb21wdXRlIFNVSUQgdXNpbmcgU0hBT3V0cHV0U3RyZWFtCisgICAgICAgICAqLworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZmluYWwgRmllbGQgZmllbGQgPSBmaWVsZHNbaV07CisgICAgICAgICAgICBpZiAoZmllbGQuZ2V0VHlwZSgpID09IGxvbmcuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICBpbnQgbW9kaWZpZXJzID0gZmllbGQuZ2V0TW9kaWZpZXJzKCk7CisgICAgICAgICAgICAgICAgaWYgKE1vZGlmaWVyLmlzU3RhdGljKG1vZGlmaWVycykgJiYgTW9kaWZpZXIuaXNGaW5hbChtb2RpZmllcnMpKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChVSURfRklFTERfTkFNRS5lcXVhbHMoZmllbGQuZ2V0TmFtZSgpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgICAgICAgICAqIFdlIG5lZWQgdG8gYmUgYWJsZSB0byBzZWUgaXQgZXZlbiBpZiB3ZSBoYXZlIG5vCisgICAgICAgICAgICAgICAgICAgICAgICAgKiB2aXNpYmlsaXR5LiBUaGF0IGlzIHdoeSB3ZSBzZXQgYWNjZXNzaWJsZSBmaXJzdCAobmV3CisgICAgICAgICAgICAgICAgICAgICAgICAgKiBBUEkgaW4gcmVmbGVjdCAxLjIpCisgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLnNldEFjY2Vzc2libGUodHJ1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN0YXRpYyBmaWVsZCwgcGFyYW1ldGVyIGlzIGlnbm9yZWQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmllbGQuZ2V0TG9uZyhudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkVycm9yIGZldGNoaW5nIFNVSUQ6ICIgKyBpYWUpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgTWVzc2FnZURpZ2VzdCBkaWdlc3Q7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkaWdlc3QgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJTSEEiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlKTsKKyAgICAgICAgfQorICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gc2hhID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgRGF0YU91dHB1dFN0cmVhbSBvdXRwdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShzaGEpOworICAgICAgICAgICAgb3V0cHV0LndyaXRlVVRGKGNsLmdldE5hbWUoKSk7CisgICAgICAgICAgICBpbnQgY2xhc3NNb2RpZmllcnMgPSBDTEFTU19NT0RJRklFUlNfTUFTSyAmIGNsLmdldE1vZGlmaWVycygpOworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFdvcmthcm91bmQgZm9yIDFGOUxPUU8uIEFycmF5cyBhcmUgQUJTVFJBQ1QgaW4gSkRLLCBidXQgdGhhdCBpcworICAgICAgICAgICAgICogbm90IGluIHRoZSBzcGVjaWZpY2F0aW9uLiBTaW5jZSB3ZSB3YW50IHRvIGJlIGNvbXBhdGlibGUgZm9yCisgICAgICAgICAgICAgKiBYLWxvYWRpbmcsIHdlIGhhdmUgdG8gcHJldGVuZCB3ZSBoYXZlIHRoZSBzYW1lIHNoYXBlCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGJvb2xlYW4gaXNBcnJheSA9IGNsLmlzQXJyYXkoKTsKKyAgICAgICAgICAgIGlmIChpc0FycmF5KSB7CisgICAgICAgICAgICAgICAgY2xhc3NNb2RpZmllcnMgfD0gTW9kaWZpZXIuQUJTVFJBQ1Q7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBSZXF1aXJlZCBmb3IgSkRLIFVJRCBjb21wYXRpYmlsaXR5CisgICAgICAgICAgICBpZiAoY2wuaXNJbnRlcmZhY2UoKSAmJiAhTW9kaWZpZXIuaXNQdWJsaWMoY2xhc3NNb2RpZmllcnMpKSB7CisgICAgICAgICAgICAgICAgY2xhc3NNb2RpZmllcnMgJj0gfk1vZGlmaWVyLkFCU1RSQUNUOworICAgICAgICAgICAgfQorICAgICAgICAgICAgb3V0cHV0LndyaXRlSW50KGNsYXNzTW9kaWZpZXJzKTsKKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIEluIEpESzEuMiBhcnJheXMgaW1wbGVtZW50IENsb25lYWJsZSBhbmQgU2VyaWFsaXphYmxlIGJ1dCBub3QgaW4KKyAgICAgICAgICAgICAqIEpESyAxLjEuNy4gU28sIEpESyAxLjIgInByZXRlbmRzIiBhcnJheXMgaGF2ZSBubyBpbnRlcmZhY2VzIHdoZW4KKyAgICAgICAgICAgICAqIGNvbXB1dGluZyBTSEEtMSB0byBiZSBjb21wYXRpYmxlLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAoIWlzQXJyYXkpIHsKKyAgICAgICAgICAgICAgICAvLyBJbnRlcmZhY2UgaW5mb3JtYXRpb24KKyAgICAgICAgICAgICAgICBDbGFzczw/PltdIGludGVyZmFjZXMgPSBjbC5nZXRJbnRlcmZhY2VzKCk7CisgICAgICAgICAgICAgICAgaWYgKGludGVyZmFjZXMubGVuZ3RoID4gMSkgeworICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGF0dGVtcHQgdG8gc29ydCBpZiByZWFsbHkgbmVlZGVkIChzYXZlcyBvYmplY3QKKyAgICAgICAgICAgICAgICAgICAgLy8gY3JlYXRpb24sIGV0YykKKyAgICAgICAgICAgICAgICAgICAgQ29tcGFyYXRvcjxDbGFzczw/Pj4gaW50ZXJmYWNlQ29tcGFyYXRvciA9IG5ldyBDb21wYXJhdG9yPENsYXNzPD8+PigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShDbGFzczw/PiBpdGYxLCBDbGFzczw/PiBpdGYyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZjEuZ2V0TmFtZSgpLmNvbXBhcmVUbyhpdGYyLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICAgICAgICAgIEFycmF5cy5zb3J0KGludGVyZmFjZXMsIGludGVyZmFjZUNvbXBhcmF0b3IpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIER1bXAgdGhlbQorICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW50ZXJmYWNlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVVVEYoaW50ZXJmYWNlc1tpXS5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gRmllbGQgaW5mb3JtYXRpb24KKyAgICAgICAgICAgIGlmIChmaWVsZHMubGVuZ3RoID4gMSkgeworICAgICAgICAgICAgICAgIC8vIE9ubHkgYXR0ZW1wdCB0byBzb3J0IGlmIHJlYWxseSBuZWVkZWQgKHNhdmVzIG9iamVjdCBjcmVhdGlvbiwKKyAgICAgICAgICAgICAgICAvLyBldGMpCisgICAgICAgICAgICAgICAgQ29tcGFyYXRvcjxGaWVsZD4gZmllbGRDb21wYXJhdG9yID0gbmV3IENvbXBhcmF0b3I8RmllbGQ+KCkgeworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoRmllbGQgZmllbGQxLCBGaWVsZCBmaWVsZDIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWVsZDEuZ2V0TmFtZSgpLmNvbXBhcmVUbyhmaWVsZDIuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICAgICAgQXJyYXlzLnNvcnQoZmllbGRzLCBmaWVsZENvbXBhcmF0b3IpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBEdW1wIHRoZW0KKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgRmllbGQgZmllbGQgPSBmaWVsZHNbaV07CisgICAgICAgICAgICAgICAgaW50IG1vZGlmaWVycyA9IGZpZWxkLmdldE1vZGlmaWVycygpICYgRklFTERfTU9ESUZJRVJTX01BU0s7CisKKyAgICAgICAgICAgICAgICBib29sZWFuIHNraXAgPSBNb2RpZmllci5pc1ByaXZhdGUobW9kaWZpZXJzKQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgKE1vZGlmaWVyLmlzVHJhbnNpZW50KG1vZGlmaWVycykgfHwgTW9kaWZpZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmlzU3RhdGljKG1vZGlmaWVycykpOworICAgICAgICAgICAgICAgIGlmICghc2tpcCkgeworICAgICAgICAgICAgICAgICAgICAvLyB3cml0ZSBuYW1lLCBtb2RpZmllciAmICJkZXNjcmlwdG9yIiBvZiBhbGwgYnV0IHByaXZhdGUKKyAgICAgICAgICAgICAgICAgICAgLy8gc3RhdGljIGFuZCBwcml2YXRlIHRyYW5zaWVudAorICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVVVEYoZmllbGQuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlSW50KG1vZGlmaWVycyk7CisgICAgICAgICAgICAgICAgICAgIG91dHB1dAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC53cml0ZVVURihkZXNjcmlwdG9yRm9yRmllbGRTaWduYXR1cmUoZ2V0RmllbGRTaWduYXR1cmUoZmllbGQpKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogTm9ybWFsbHkgY29uc3RydWN0b3JzIGNvbWUgYmVmb3JlIG1ldGhvZHMgKGJlY2F1c2UgPGluaXQ+IDwKKyAgICAgICAgICAgICAqIGFueU1ldGhvZE5hbWUpLiBIb3dldmVyLCA8Y2xpbml0PiBpcyBhbiBleGNlcHRpb24uIEJlc2lkZXMsCisgICAgICAgICAgICAgKiByZWZsZWN0IHdpbGwgbm90IGxldCB1cyBnZXQgdG8gaXQuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGlmIChoYXNDbGluaXQoY2wpKSB7CisgICAgICAgICAgICAgICAgLy8gd3JpdGUgbmFtZSwgbW9kaWZpZXIgJiAiZGVzY3JpcHRvciIKKyAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVVVEYoQ0xJTklUX05BTUUpOworICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZUludChDTElOSVRfTU9ESUZJRVJTKTsKKyAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVVVEYoQ0xJTklUX1NJR05BVFVSRSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIENvbnN0cnVjdG9yIGluZm9ybWF0aW9uCisgICAgICAgICAgICBDb25zdHJ1Y3Rvcjw/PltdIGNvbnN0cnVjdG9ycyA9IGNsLmdldERlY2xhcmVkQ29uc3RydWN0b3JzKCk7CisgICAgICAgICAgICBpZiAoY29uc3RydWN0b3JzLmxlbmd0aCA+IDEpIHsKKyAgICAgICAgICAgICAgICAvLyBPbmx5IGF0dGVtcHQgdG8gc29ydCBpZiByZWFsbHkgbmVlZGVkIChzYXZlcyBvYmplY3QgY3JlYXRpb24sCisgICAgICAgICAgICAgICAgLy8gZXRjKQorICAgICAgICAgICAgICAgIENvbXBhcmF0b3I8Q29uc3RydWN0b3I8Pz4+IGNvbnN0cnVjdG9yQ29tcGFyYXRvciA9IG5ldyBDb21wYXJhdG9yPENvbnN0cnVjdG9yPD8+PigpIHsKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIGludCBjb21wYXJlKENvbnN0cnVjdG9yPD8+IGN0cjEsIENvbnN0cnVjdG9yPD8+IGN0cjIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFsbCBjb25zdHJ1Y3RvcnMgaGF2ZSBzYW1lIG5hbWUsIHNvIHdlIHNvcnQgYmFzZWQgb24KKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpZ25hdHVyZQorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChnZXRDb25zdHJ1Y3RvclNpZ25hdHVyZShjdHIxKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29tcGFyZVRvKGdldENvbnN0cnVjdG9yU2lnbmF0dXJlKGN0cjIpKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9OworICAgICAgICAgICAgICAgIEFycmF5cy5zb3J0KGNvbnN0cnVjdG9ycywgY29uc3RydWN0b3JDb21wYXJhdG9yKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gRHVtcCB0aGVtCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbnN0cnVjdG9ycy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIENvbnN0cnVjdG9yPD8+IGNvbnN0cnVjdG9yID0gY29uc3RydWN0b3JzW2ldOworICAgICAgICAgICAgICAgIGludCBtb2RpZmllcnMgPSBjb25zdHJ1Y3Rvci5nZXRNb2RpZmllcnMoKQorICAgICAgICAgICAgICAgICAgICAgICAgJiBNRVRIT0RfTU9ESUZJRVJTX01BU0s7CisgICAgICAgICAgICAgICAgYm9vbGVhbiBpc1ByaXZhdGUgPSBNb2RpZmllci5pc1ByaXZhdGUobW9kaWZpZXJzKTsKKyAgICAgICAgICAgICAgICBpZiAoIWlzUHJpdmF0ZSkgeworICAgICAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAgICAgKiB3cml0ZSBuYW1lLCBtb2RpZmllciAmICJkZXNjcmlwdG9yIiBvZiBhbGwgYnV0IHByaXZhdGUKKyAgICAgICAgICAgICAgICAgICAgICogb25lcworICAgICAgICAgICAgICAgICAgICAgKgorICAgICAgICAgICAgICAgICAgICAgKiBjb25zdHJ1Y3Rvci5nZXROYW1lKCkgcmV0dXJucyB0aGUgY29uc3RydWN0b3IgbmFtZSBhcworICAgICAgICAgICAgICAgICAgICAgKiB0eXBlZCwgbm90IHRoZSBWTSBuYW1lCisgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVVVEYoIjxpbml0PiIpOworICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVJbnQobW9kaWZpZXJzKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlVVRGKGRlc2NyaXB0b3JGb3JTaWduYXR1cmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Q29uc3RydWN0b3JTaWduYXR1cmUoY29uc3RydWN0b3IpKS5yZXBsYWNlKCcvJywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLicpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIE1ldGhvZCBpbmZvcm1hdGlvbgorICAgICAgICAgICAgTWV0aG9kW10gbWV0aG9kcyA9IGNsLmdldERlY2xhcmVkTWV0aG9kcygpOworICAgICAgICAgICAgaWYgKG1ldGhvZHMubGVuZ3RoID4gMSkgeworICAgICAgICAgICAgICAgIENvbXBhcmF0b3I8TWV0aG9kPiBtZXRob2RDb21wYXJhdG9yID0gbmV3IENvbXBhcmF0b3I8TWV0aG9kPigpIHsKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIGludCBjb21wYXJlKE1ldGhvZCBtMSwgTWV0aG9kIG0yKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnQgcmVzdWx0ID0gbTEuZ2V0TmFtZSgpLmNvbXBhcmVUbyhtMi5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2FtZSBuYW1lLCBzaWduYXR1cmUgd2lsbCB0ZWxsIHdoaWNoIG9uZSBjb21lcworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpcnN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldE1ldGhvZFNpZ25hdHVyZShtMSkuY29tcGFyZVRvKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWV0aG9kU2lnbmF0dXJlKG0yKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfTsKKyAgICAgICAgICAgICAgICBBcnJheXMuc29ydChtZXRob2RzLCBtZXRob2RDb21wYXJhdG9yKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gRHVtcCB0aGVtCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1ldGhvZHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBNZXRob2QgbWV0aG9kID0gbWV0aG9kc1tpXTsKKyAgICAgICAgICAgICAgICBpbnQgbW9kaWZpZXJzID0gbWV0aG9kLmdldE1vZGlmaWVycygpICYgTUVUSE9EX01PRElGSUVSU19NQVNLOworICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNQcml2YXRlID0gTW9kaWZpZXIuaXNQcml2YXRlKG1vZGlmaWVycyk7CisgICAgICAgICAgICAgICAgaWYgKCFpc1ByaXZhdGUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gd3JpdGUgbmFtZSwgbW9kaWZpZXIgJiAiZGVzY3JpcHRvciIgb2YgYWxsIGJ1dCBwcml2YXRlCisgICAgICAgICAgICAgICAgICAgIC8vIG9uZXMKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlVVRGKG1ldGhvZC5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGVJbnQobW9kaWZpZXJzKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlVVRGKGRlc2NyaXB0b3JGb3JTaWduYXR1cmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TWV0aG9kU2lnbmF0dXJlKG1ldGhvZCkpLnJlcGxhY2UoJy8nLCAnLicpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUgKyAiIGNvbXB1dGluZyBTSEEtMS9TVUlEIik7CisgICAgICAgIH0KKworICAgICAgICAvLyBub3cgY29tcHV0ZSB0aGUgVUlEIGJhc2VkIG9uIHRoZSBTSEEKKyAgICAgICAgYnl0ZVtdIGhhc2ggPSBkaWdlc3QuZGlnZXN0KHNoYS50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgcmV0dXJuIE1lbW9yeS5wZWVrTG9uZyhoYXNoLCAwLCBCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGF0IHRoZSBzZXJpYWxpemF0aW9uIHNwZWNpZmljYXRpb24gY2FsbHMgImRlc2NyaXB0b3IiIGdpdmVuIGEKKyAgICAgKiBmaWVsZCBzaWduYXR1cmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2lnbmF0dXJlCisgICAgICogICAgICAgICAgICBhIGZpZWxkIHNpZ25hdHVyZQorICAgICAqIEByZXR1cm4gY29udGFpbmluZyB0aGUgZGVzY3JpcHRvcgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZXNjcmlwdG9yRm9yRmllbGRTaWduYXR1cmUoU3RyaW5nIHNpZ25hdHVyZSkgeworICAgICAgICByZXR1cm4gc2lnbmF0dXJlLnJlcGxhY2UoJy4nLCAnLycpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB3aGF0IHRoZSBzZXJpYWxpemF0aW9uIHNwZWNpZmljYXRpb24gY2FsbHMgImRlc2NyaXB0b3IiIGdpdmVuIGEKKyAgICAgKiBtZXRob2QvY29uc3RydWN0b3Igc2lnbmF0dXJlLgorICAgICAqCisgICAgICogQHBhcmFtIHNpZ25hdHVyZQorICAgICAqICAgICAgICAgICAgYSBtZXRob2Qgb3IgY29uc3RydWN0b3Igc2lnbmF0dXJlCisgICAgICogQHJldHVybiBjb250YWluaW5nIHRoZSBkZXNjcmlwdG9yCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGRlc2NyaXB0b3JGb3JTaWduYXR1cmUoU3RyaW5nIHNpZ25hdHVyZSkgeworICAgICAgICByZXR1cm4gc2lnbmF0dXJlLnN1YnN0cmluZyhzaWduYXR1cmUuaW5kZXhPZigiKCIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkIHtAY29kZSBzZXJpYWxQZXJzaXN0ZW50RmllbGRzfQorICAgICAqIGlmIGNsYXNzIHtAY29kZSBjbH0gaW1wbGVtZW50cyBpdC4gUmV0dXJuIG51bGwgb3RoZXJ3aXNlLgorICAgICAqCisgICAgICogQHBhcmFtIGNsCisgICAgICogICAgICAgICAgICBhIGphdmEubGFuZy5DbGFzcyB3aGljaCB0byB0ZXN0CisgICAgICogQHJldHVybiB7QGNvZGUgamF2YS5sYW5nLnJlZmxlY3QuRmllbGR9IGlmIHRoZSBjbGFzcyBoYXMKKyAgICAgKiAgICAgICAgIHNlcmlhbFBlcnNpc3RlbnRGaWVsZHMge0Bjb2RlIG51bGx9IGlmIHRoZSBjbGFzcyBkb2VzIG5vdAorICAgICAqICAgICAgICAgaGF2ZSBzZXJpYWxQZXJzaXN0ZW50RmllbGRzCisgICAgICovCisgICAgc3RhdGljIEZpZWxkIGZpZWxkU2VyaWFsUGVyc2lzdGVudEZpZWxkcyhDbGFzczw/PiBjbCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgRmllbGQgZiA9IGNsLmdldERlY2xhcmVkRmllbGQoInNlcmlhbFBlcnNpc3RlbnRGaWVsZHMiKTsKKyAgICAgICAgICAgIGludCBtb2RpZmllcnMgPSBmLmdldE1vZGlmaWVycygpOworICAgICAgICAgICAgaWYgKE1vZGlmaWVyLmlzU3RhdGljKG1vZGlmaWVycykgJiYgTW9kaWZpZXIuaXNQcml2YXRlKG1vZGlmaWVycykKKyAgICAgICAgICAgICAgICAgICAgJiYgTW9kaWZpZXIuaXNGaW5hbChtb2RpZmllcnMpKSB7CisgICAgICAgICAgICAgICAgaWYgKGYuZ2V0VHlwZSgpID09IEFSUkFZX09GX0ZJRUxEUykgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEZpZWxkRXhjZXB0aW9uIG5zbSkgeworICAgICAgICAgICAgLy8gSWdub3JlZAorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNsYXNzIChqYXZhLmxhbmcuQ2xhc3MpIGZvciB0aGlzIGRlc2NyaXB0b3IuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjbGFzcyBpbiB0aGUgbG9jYWwgVk0gdGhhdCB0aGlzIGRlc2NyaXB0b3IgcmVwcmVzZW50czsKKyAgICAgKiAgICAgICAgIHtAY29kZSBudWxsfSBpZiB0aGVyZSBpcyBubyBjb3JyZXNwb25kaW5nIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBDbGFzczw/PiBmb3JDbGFzcygpIHsKKyAgICAgICAgcmV0dXJuIHJlc29sdmVkQ2xhc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuZCByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2YgY2xhc3MgJ2luc3RhbnRpYXRpb25DbGFzcycKKyAgICAgKiB1c2luZyBKTkkgdG8gY2FsbCB0aGUgY29uc3RydWN0b3IgY2hvc2VuIGJ5IHJlc29sdmVDb25zdHJ1Y3RvckNsYXNzLgorICAgICAqCisgICAgICogVGhlIHJldHVybmVkIGluc3RhbmNlIG1heSBoYXZlIHVuaW5pdGlhbGl6ZWQgZmllbGRzLCBpbmNsdWRpbmcgZmluYWwgZmllbGRzLgorICAgICAqLworICAgIE9iamVjdCBuZXdJbnN0YW5jZShDbGFzczw/PiBpbnN0YW50aWF0aW9uQ2xhc3MpIHRocm93cyBJbnZhbGlkQ2xhc3NFeGNlcHRpb24geworICAgICAgICByZXNvbHZlQ29uc3RydWN0b3JDbGFzcyhpbnN0YW50aWF0aW9uQ2xhc3MpOworICAgICAgICByZXR1cm4gbmV3SW5zdGFuY2UoaW5zdGFudGlhdGlvbkNsYXNzLCByZXNvbHZlZENvbnN0cnVjdG9yTWV0aG9kSWQpOworICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgT2JqZWN0IG5ld0luc3RhbmNlKENsYXNzPD8+IGluc3RhbnRpYXRpb25DbGFzcywgaW50IG1ldGhvZElkKTsKKworICAgIHByaXZhdGUgQ2xhc3M8Pz4gcmVzb2x2ZUNvbnN0cnVjdG9yQ2xhc3MoQ2xhc3M8Pz4gb2JqZWN0Q2xhc3MpIHRocm93cyBJbnZhbGlkQ2xhc3NFeGNlcHRpb24geworICAgICAgICBpZiAocmVzb2x2ZWRDb25zdHJ1Y3RvckNsYXNzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiByZXNvbHZlZENvbnN0cnVjdG9yQ2xhc3M7CisgICAgICAgIH0KKworICAgICAgICAvLyBUaGUgY2xhc3Mgb2YgdGhlIGluc3RhbmNlIG1heSBub3QgYmUgdGhlIHNhbWUgYXMgdGhlIGNsYXNzIG9mIHRoZQorICAgICAgICAvLyBjb25zdHJ1Y3RvciB0byBydW4KKyAgICAgICAgLy8gVGhpcyBpcyB0aGUgY29uc3RydWN0b3IgdG8gcnVuIGlmIEV4dGVybmFsaXphYmxlCisgICAgICAgIENsYXNzPD8+IGNvbnN0cnVjdG9yQ2xhc3MgPSBvYmplY3RDbGFzczsKKworICAgICAgICAvLyBXQVJOSU5HIC0gV2hhdCBpZiB0aGUgb2JqZWN0IGlzIHNlcmlhbGl6YWJsZSBhbmQgZXh0ZXJuYWxpemFibGUgPworICAgICAgICAvLyBJcyB0aGF0IHBvc3NpYmxlID8KKyAgICAgICAgYm9vbGVhbiB3YXNTZXJpYWxpemFibGUgPSAoZmxhZ3MgJiBPYmplY3RTdHJlYW1Db25zdGFudHMuU0NfU0VSSUFMSVpBQkxFKSAhPSAwOworICAgICAgICBpZiAod2FzU2VyaWFsaXphYmxlKSB7CisgICAgICAgICAgICAvLyBOb3cgd2UgbXVzdCBydW4gdGhlIGNvbnN0cnVjdG9yIG9mIHRoZSBjbGFzcyBqdXN0IGFib3ZlIHRoZQorICAgICAgICAgICAgLy8gb25lIHRoYXQgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgc28gdGhhdCBzbG90cyB0aGF0IHdlcmUgbm90CisgICAgICAgICAgICAvLyBkdW1wZWQgY2FuIGJlIGluaXRpYWxpemVkIHByb3Blcmx5CisgICAgICAgICAgICB3aGlsZSAoY29uc3RydWN0b3JDbGFzcyAhPSBudWxsICYmIE9iamVjdFN0cmVhbUNsYXNzLmlzU2VyaWFsaXphYmxlKGNvbnN0cnVjdG9yQ2xhc3MpKSB7CisgICAgICAgICAgICAgICAgY29uc3RydWN0b3JDbGFzcyA9IGNvbnN0cnVjdG9yQ2xhc3MuZ2V0U3VwZXJjbGFzcygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gRmV0Y2ggdGhlIGVtcHR5IGNvbnN0cnVjdG9yLCBvciBudWxsIGlmIG5vbmUuCisgICAgICAgIENvbnN0cnVjdG9yPD8+IGNvbnN0cnVjdG9yID0gbnVsbDsKKyAgICAgICAgaWYgKGNvbnN0cnVjdG9yQ2xhc3MgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciA9IGNvbnN0cnVjdG9yQ2xhc3MuZ2V0RGVjbGFyZWRDb25zdHJ1Y3RvcihFbXB0eUFycmF5LkNMQVNTKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBIYXMgdG8gaGF2ZSBhbiBlbXB0eSBjb25zdHJ1Y3RvcgorICAgICAgICBpZiAoY29uc3RydWN0b3IgPT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9IGNvbnN0cnVjdG9yQ2xhc3MgIT0gbnVsbCA/IGNvbnN0cnVjdG9yQ2xhc3MuZ2V0TmFtZSgpIDogbnVsbDsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQ2xhc3NFeGNlcHRpb24oY2xhc3NOYW1lLCAiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgaW50IGNvbnN0cnVjdG9yTW9kaWZpZXJzID0gY29uc3RydWN0b3IuZ2V0TW9kaWZpZXJzKCk7CisgICAgICAgIGJvb2xlYW4gaXNQdWJsaWMgPSBNb2RpZmllci5pc1B1YmxpYyhjb25zdHJ1Y3Rvck1vZGlmaWVycyk7CisgICAgICAgIGJvb2xlYW4gaXNQcm90ZWN0ZWQgPSBNb2RpZmllci5pc1Byb3RlY3RlZChjb25zdHJ1Y3Rvck1vZGlmaWVycyk7CisgICAgICAgIGJvb2xlYW4gaXNQcml2YXRlID0gTW9kaWZpZXIuaXNQcml2YXRlKGNvbnN0cnVjdG9yTW9kaWZpZXJzKTsKKworICAgICAgICAvLyBOb3cgd2UgbXVzdCBjaGVjayBpZiB0aGUgZW1wdHkgY29uc3RydWN0b3IgaXMgdmlzaWJsZSB0byB0aGUKKyAgICAgICAgLy8gaW5zdGFudGlhdGlvbiBjbGFzcworICAgICAgICBib29sZWFuIHdhc0V4dGVybmFsaXphYmxlID0gKGZsYWdzICYgT2JqZWN0U3RyZWFtQ29uc3RhbnRzLlNDX0VYVEVSTkFMSVpBQkxFKSAhPSAwOworICAgICAgICBpZiAoaXNQcml2YXRlIHx8ICh3YXNFeHRlcm5hbGl6YWJsZSAmJiAhaXNQdWJsaWMpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZENsYXNzRXhjZXB0aW9uKGNvbnN0cnVjdG9yQ2xhc3MuZ2V0TmFtZSgpLCAiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gV2Uga25vdyB3ZSBhcmUgdGVzdGluZyBmcm9tIGEgc3ViY2xhc3MsIHNvIHRoZSBvbmx5IG90aGVyIGNhc2UKKyAgICAgICAgLy8gd2hlcmUgdGhlIHZpc2liaWxpdHkgaXMgbm90IGFsbG93ZWQgaXMgd2hlbiB0aGUgY29uc3RydWN0b3IgaGFzCisgICAgICAgIC8vIGRlZmF1bHQgdmlzaWJpbGl0eSBhbmQgdGhlIGluc3RhbnRpYXRpb24gY2xhc3MgaXMgaW4gYSBkaWZmZXJlbnQKKyAgICAgICAgLy8gcGFja2FnZSB0aGFuIHRoZSBjb25zdHJ1Y3RvciBjbGFzcworICAgICAgICBpZiAoIWlzUHVibGljICYmICFpc1Byb3RlY3RlZCkgeworICAgICAgICAgICAgLy8gTm90IHB1YmxpYywgbm90IHByaXZhdGUgYW5kIG5vdCBwcm90ZWN0ZWQuLi5tZWFucyBkZWZhdWx0CisgICAgICAgICAgICAvLyB2aXNpYmlsaXR5LiBDaGVjayBpZiBzYW1lIHBhY2thZ2UKKyAgICAgICAgICAgIGlmICghaW5TYW1lUGFja2FnZShjb25zdHJ1Y3RvckNsYXNzLCBvYmplY3RDbGFzcykpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZENsYXNzRXhjZXB0aW9uKGNvbnN0cnVjdG9yQ2xhc3MuZ2V0TmFtZSgpLCAiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmVzb2x2ZWRDb25zdHJ1Y3RvckNsYXNzID0gY29uc3RydWN0b3JDbGFzczsKKyAgICAgICAgcmVzb2x2ZWRDb25zdHJ1Y3Rvck1ldGhvZElkID0gZ2V0Q29uc3RydWN0b3JJZChyZXNvbHZlZENvbnN0cnVjdG9yQ2xhc3MpOworICAgICAgICByZXR1cm4gY29uc3RydWN0b3JDbGFzczsKKyAgICB9CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGludCBnZXRDb25zdHJ1Y3RvcklkKENsYXNzPD8+IGMpOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHR3byBjbGFzc2VzIGJlbG9uZyB0byB0aGUgc2FtZSBwYWNrYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGMxCisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIGNsYXNzZXMgdG8gdGVzdC4KKyAgICAgKiBAcGFyYW0gYzIKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdGhlciBjbGFzcyB0byB0ZXN0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSB0d28gY2xhc3NlcyBiZWxvbmcgdG8gdGhlIHNhbWUgcGFja2FnZSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpblNhbWVQYWNrYWdlKENsYXNzPD8+IGMxLCBDbGFzczw/PiBjMikgeworICAgICAgICBTdHJpbmcgbmFtZUMxID0gYzEuZ2V0TmFtZSgpOworICAgICAgICBTdHJpbmcgbmFtZUMyID0gYzIuZ2V0TmFtZSgpOworICAgICAgICBpbnQgaW5kZXhEb3RDMSA9IG5hbWVDMS5sYXN0SW5kZXhPZignLicpOworICAgICAgICBpbnQgaW5kZXhEb3RDMiA9IG5hbWVDMi5sYXN0SW5kZXhPZignLicpOworICAgICAgICBpZiAoaW5kZXhEb3RDMSAhPSBpbmRleERvdEMyKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIGNhbm5vdCBiZSBpbiB0aGUgc2FtZSBwYWNrYWdlIGlmIGluZGljZXMgYXJlIG5vdCB0aGUgc2FtZQorICAgICAgICB9CisgICAgICAgIGlmIChpbmRleERvdEMxID09IC0xKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gYm90aCBvZiB0aGVtIGFyZSBpbiBkZWZhdWx0IHBhY2thZ2UKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmFtZUMxLnJlZ2lvbk1hdGNoZXMoMCwgbmFtZUMyLCAwLCBpbmRleERvdEMxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBTdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBzaWduYXR1cmUgZm9yIGEgQ29uc3RydWN0b3Ige0Bjb2RlIGN9LgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIGEgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3IgZm9yIHdoaWNoIHRvIGNvbXB1dGUgdGhlCisgICAgICogICAgICAgICAgICBzaWduYXR1cmUKKyAgICAgKiBAcmV0dXJuIHRoZSBjb25zdHJ1Y3RvcidzIHNpZ25hdHVyZQorICAgICAqLworICAgIHN0YXRpYyBuYXRpdmUgU3RyaW5nIGdldENvbnN0cnVjdG9yU2lnbmF0dXJlKENvbnN0cnVjdG9yPD8+IGMpOworCisgICAgLyoqCisgICAgICogR2V0cyBhIGZpZWxkIGRlc2NyaXB0b3Igb2YgdGhlIGNsYXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMgY2xhc3MKKyAgICAgKiBkZXNjcmlwdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBkZXNpcmVkIGZpZWxkLgorICAgICAqIEByZXR1cm4gdGhlIGZpZWxkIGlkZW50aWZpZWQgYnkge0Bjb2RlIG5hbWV9IG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSBpcworICAgICAqICAgICAgICAgbm8gc3VjaCBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0U3RyZWFtRmllbGQgZ2V0RmllbGQoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgT2JqZWN0U3RyZWFtRmllbGRbXSBhbGxGaWVsZHMgPSBnZXRGaWVsZHMoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGxGaWVsZHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIE9iamVjdFN0cmVhbUZpZWxkIGYgPSBhbGxGaWVsZHNbaV07CisgICAgICAgICAgICBpZiAoZi5nZXROYW1lKCkuZXF1YWxzKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGY7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29sbGVjdGlvbiBvZiBmaWVsZCBkZXNjcmlwdG9ycyBmb3IgdGhlIGZpZWxkcyBvZiB0aGUKKyAgICAgKiBjb3JyZXNwb25kaW5nIGNsYXNzCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIGNvbGxlY3Rpb24gb2YgZGVjbGFyZWQgZmllbGRzIGZvciB0aGUgY2xhc3MgaXQKKyAgICAgKiAgICAgICAgIHJlcHJlc2VudHMKKyAgICAgKi8KKyAgICBPYmplY3RTdHJlYW1GaWVsZFtdIGZpZWxkcygpIHsKKyAgICAgICAgaWYgKGZpZWxkcyA9PSBudWxsKSB7CisgICAgICAgICAgICBDbGFzczw/PiBmb3JDbCA9IGZvckNsYXNzKCk7CisgICAgICAgICAgICBpZiAoZm9yQ2wgIT0gbnVsbCAmJiBpc1NlcmlhbGl6YWJsZSgpICYmICFmb3JDbC5pc0FycmF5KCkpIHsKKyAgICAgICAgICAgICAgICBidWlsZEZpZWxkRGVzY3JpcHRvcnMoZm9yQ2wuZ2V0RGVjbGFyZWRGaWVsZHMoKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIEV4dGVybmFsaXphYmxlcyBvciBhcnJheXMgZG8gbm90IG5lZWQgRmllbGREZXNjIGluZm8KKyAgICAgICAgICAgICAgICBzZXRGaWVsZHMoTk9fRklFTERTKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmllbGRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb2xsZWN0aW9uIG9mIGZpZWxkIGRlc2NyaXB0b3JzIGZvciB0aGUgc2VyaWFsaXplZCBmaWVsZHMgb2YKKyAgICAgKiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcyBjbGFzcyBkZXNjcmlwdG9yLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBmaWVsZCBkZXNjcmlwdG9ycyBvciBhbiBhcnJheSBvZiBsZW5ndGggemVybyBpZiB0aGVyZQorICAgICAqICAgICAgICAgYXJlIG5vIGZpZWxkcyBpbiB0aGlzIGRlc2NyaXB0b3IncyBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0U3RyZWFtRmllbGRbXSBnZXRGaWVsZHMoKSB7CisgICAgICAgIGNvcHlGaWVsZEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgcmV0dXJuIGxvYWRGaWVsZHMgPT0gbnVsbCA/IGZpZWxkcygpLmNsb25lKCkgOiBsb2FkRmllbGRzLmNsb25lKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgdm9sYXRpbGUgTGlzdDxPYmplY3RTdHJlYW1DbGFzcz4gY2FjaGVkSGllcmFyY2h5OworCisgICAgTGlzdDxPYmplY3RTdHJlYW1DbGFzcz4gZ2V0SGllcmFyY2h5KCkgeworICAgICAgICBMaXN0PE9iamVjdFN0cmVhbUNsYXNzPiByZXN1bHQgPSBjYWNoZWRIaWVyYXJjaHk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgY2FjaGVkSGllcmFyY2h5ID0gcmVzdWx0ID0gbWFrZUhpZXJhcmNoeSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBMaXN0PE9iamVjdFN0cmVhbUNsYXNzPiBtYWtlSGllcmFyY2h5KCkgeworICAgICAgICBBcnJheUxpc3Q8T2JqZWN0U3RyZWFtQ2xhc3M+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8T2JqZWN0U3RyZWFtQ2xhc3M+KCk7CisgICAgICAgIGZvciAoT2JqZWN0U3RyZWFtQ2xhc3Mgb3NjID0gdGhpczsgb3NjICE9IG51bGw7IG9zYyA9IG9zYy5nZXRTdXBlcmNsYXNzKCkpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hZGQoMCwgb3NjKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIElmIGEgQ2xhc3MgdXNlcyAic2VyaWFsUGVyc2lzdGVudEZpZWxkcyIgdG8gZGVmaW5lIHRoZSBzZXJpYWxpemVkIGZpZWxkcywKKyAgICAgKiB0aGlzLmxvYWRGaWVsZHMgY2Fubm90IGdldCB0aGUgInVuc2hhcmVkIiBpbmZvcm1hdGlvbiB3aGVuIGRlc2VyaWFsaXppbmcKKyAgICAgKiBmaWVsZHMgdXNpbmcgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBvZiBPYmplY3RJbnB1dFN0cmVhbS4gVGhpcyBtZXRob2QKKyAgICAgKiBwcm92aWRlcyBhIHdheSB0byBjb3B5IHRoZSAidW5zaGFyZWQiIGF0dHJpYnV0ZSBmcm9tIHRoaXMuZmllbGRzLgorICAgICAqCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNvcHlGaWVsZEF0dHJpYnV0ZXMoKSB7CisgICAgICAgIGlmICgobG9hZEZpZWxkcyA9PSBudWxsKSB8fCBmaWVsZHMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsb2FkRmllbGRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBPYmplY3RTdHJlYW1GaWVsZCBsb2FkRmllbGQgPSBsb2FkRmllbGRzW2ldOworICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBsb2FkRmllbGQuZ2V0TmFtZSgpOworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBmaWVsZHMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICBPYmplY3RTdHJlYW1GaWVsZCBmaWVsZCA9IGZpZWxkc1tqXTsKKyAgICAgICAgICAgICAgICBpZiAobmFtZS5lcXVhbHMoZmllbGQuZ2V0TmFtZSgpKSkgeworICAgICAgICAgICAgICAgICAgICBsb2FkRmllbGQuc2V0VW5zaGFyZWQoZmllbGQuaXNVbnNoYXJlZCgpKTsKKyAgICAgICAgICAgICAgICAgICAgbG9hZEZpZWxkLnNldE9mZnNldChmaWVsZC5nZXRPZmZzZXQoKSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNvbGxlY3Rpb24gb2YgZmllbGQgZGVzY3JpcHRvcnMgZm9yIHRoZSBpbnB1dCBmaWVsZHMgb2YgdGhlCisgICAgICogY29ycmVzcG9uZGluZyBjbGFzcworICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBjb2xsZWN0aW9uIG9mIGlucHV0IGZpZWxkcyBmb3IgdGhlIGNsYXNzIGl0CisgICAgICogICAgICAgICByZXByZXNlbnRzCisgICAgICovCisgICAgT2JqZWN0U3RyZWFtRmllbGRbXSBnZXRMb2FkRmllbGRzKCkgeworICAgICAgICByZXR1cm4gbG9hZEZpZWxkczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBTdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBzaWduYXR1cmUgZm9yIGEgZmllbGQge0Bjb2RlIGZ9LgorICAgICAqCisgICAgICogQHBhcmFtIGYKKyAgICAgKiAgICAgICAgICAgIGEgamF2YS5sYW5nLnJlZmxlY3QuRmllbGQgZm9yIHdoaWNoIHRvIGNvbXB1dGUgdGhlIHNpZ25hdHVyZQorICAgICAqIEByZXR1cm4gdGhlIGZpZWxkJ3Mgc2lnbmF0dXJlCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIFN0cmluZyBnZXRGaWVsZFNpZ25hdHVyZShGaWVsZCBmKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZsYWdzIGZvciB0aGlzIGRlc2NyaXB0b3IsIHdoZXJlIHBvc3NpYmxlIGNvbWJpbmVkIHZhbHVlcyBhcmUKKyAgICAgKgorICAgICAqIE9iamVjdFN0cmVhbUNvbnN0YW50cy5TQ19XUklURV9NRVRIT0QKKyAgICAgKiBPYmplY3RTdHJlYW1Db25zdGFudHMuU0NfU0VSSUFMSVpBQkxFCisgICAgICogT2JqZWN0U3RyZWFtQ29uc3RhbnRzLlNDX0VYVEVSTkFMSVpBQkxFCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGJ5dGUgdGhlIHJlY2VpdmVyJ3MgZmxhZ3MgZm9yIHRoZSBjbGFzcyBpdCByZXByZXNlbnRzCisgICAgICovCisgICAgYnl0ZSBnZXRGbGFncygpIHsKKyAgICAgICAgcmV0dXJuIGZsYWdzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIFN0cmluZyByZXByZXNlbnRpbmcgdGhlIHNpZ25hdHVyZSBmb3IgYSBtZXRob2Qge0Bjb2RlIG19LgorICAgICAqCisgICAgICogQHBhcmFtIG0KKyAgICAgKiAgICAgICAgICAgIGEgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIGZvciB3aGljaCB0byBjb21wdXRlIHRoZSBzaWduYXR1cmUKKyAgICAgKiBAcmV0dXJuIHRoZSBtZXRob2QncyBzaWduYXR1cmUKKyAgICAgKi8KKyAgICBzdGF0aWMgbmF0aXZlIFN0cmluZyBnZXRNZXRob2RTaWduYXR1cmUoTWV0aG9kIG0pOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcyBkZXNjcmlwdG9yLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGNsYXNzIHRoaXMgZGVzY3JpcHRvciByZXByZXNlbnRzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIGNsYXNzTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBTZXJpYWwgVmVyc2lvbiBVc2VyIElEIG9mIHRoZSBjbGFzcyByZXByZXNlbnRlZCBieSB0aGlzCisgICAgICogZGVzY3JpcHRvci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIFNVSUQgZm9yIHRoZSBjbGFzcyByZXByZXNlbnRlZCBieSB0aGlzIGRlc2NyaXB0b3IuCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0U2VyaWFsVmVyc2lvblVJRCgpIHsKKyAgICAgICAgcmV0dXJuIHN2VUlEOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRlc2NyaXB0b3IgKE9iamVjdFN0cmVhbUNsYXNzKSBvZiB0aGUgc3VwZXJjbGFzcyBvZiB0aGUgY2xhc3MKKyAgICAgKiByZXByZXNlbnRlZCBieSB0aGUgcmVjZWl2ZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIE9iamVjdFN0cmVhbUNsYXNzIHJlcHJlc2VudGluZyB0aGUgc3VwZXJjbGFzcyBvZiB0aGUgY2xhc3MKKyAgICAgKiAgICAgICAgIHJlcHJlc2VudGVkIGJ5IHRoZSByZWNlaXZlci4KKyAgICAgKi8KKyAgICBPYmplY3RTdHJlYW1DbGFzcyBnZXRTdXBlcmNsYXNzKCkgeworICAgICAgICByZXR1cm4gc3VwZXJjbGFzczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gY2xhc3Mge0Bjb2RlIGNsfSBoYXMgdGhlCisgICAgICogY29tcGlsZXItZ2VuZXJhdGVkIG1ldGhvZCB7QGNvZGUgY2xpbml0fS4gRXZlbiB0aG91Z2ggaXQgaXMKKyAgICAgKiBjb21waWxlci1nZW5lcmF0ZWQsIGl0IGlzIHVzZWQgYnkgdGhlIHNlcmlhbGl6YXRpb24gY29kZSB0byBjb21wdXRlIFNVSUQuCisgICAgICogVGhpcyBpcyB1bmZvcnR1bmF0ZSwgc2luY2UgaXQgbWF5IGRlcGVuZCBvbiBjb21waWxlciBvcHRpbWl6YXRpb25zIGluCisgICAgICogc29tZSBjYXNlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbAorICAgICAqICAgICAgICAgICAgYSBqYXZhLmxhbmcuQ2xhc3Mgd2hpY2ggdG8gdGVzdAorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBjbGFzcyBoYXMgPGNsaW5pdD4ge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgaWYgdGhlIGNsYXNzIGRvZXMgbm90IGhhdmUgPGNsaW5pdD4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBoYXNDbGluaXQoQ2xhc3M8Pz4gY2wpOworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRydWUgaWYgaW5zdGFuY2VzIG9mIGNsYXNzIHtAY29kZSBjbH0gYXJlIEV4dGVybmFsaXphYmxlLAorICAgICAqIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbAorICAgICAqICAgICAgICAgICAgYSBqYXZhLmxhbmcuQ2xhc3Mgd2hpY2ggdG8gdGVzdAorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGluc3RhbmNlcyBvZiB0aGUgY2xhc3MgYXJlIEV4dGVybmFsaXphYmxlCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IGlmIGluc3RhbmNlcyBvZiB0aGUgY2xhc3MgYXJlIG5vdAorICAgICAqICAgICAgICAgRXh0ZXJuYWxpemFibGUKKyAgICAgKgorICAgICAqIEBzZWUgT2JqZWN0I2hhc2hDb2RlCisgICAgICovCisgICAgc3RhdGljIGJvb2xlYW4gaXNFeHRlcm5hbGl6YWJsZShDbGFzczw/PiBjbCkgeworICAgICAgICByZXR1cm4gRVhURVJOQUxJWkFCTEUuaXNBc3NpZ25hYmxlRnJvbShjbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRydWUgaWYgdGhlIHR5cGUgY29kZQorICAgICAqIDxjb2RlPnR5cGVjb2RlPGNvZGU+IGRlc2NyaWJlcyBhIHByaW1pdGl2ZSB0eXBlCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZWNvZGUgYSBjaGFyIGRlc2NyaWJpbmcgdGhlIHR5cGVjb2RlCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHR5cGVjb2RlIHJlcHJlc2VudHMgYSBwcmltaXRpdmUgdHlwZQorICAgICAqIHtAY29kZSBmYWxzZX0gaWYgdGhlIHR5cGVjb2RlIHJlcHJlc2VudHMgYW4gT2JqZWN0IHR5cGUgKGluY2x1ZGluZyBhcnJheXMpCisgICAgICoKKyAgICAgKiBAc2VlIE9iamVjdCNoYXNoQ29kZQorICAgICAqLworICAgIHN0YXRpYyBib29sZWFuIGlzUHJpbWl0aXZlVHlwZShjaGFyIHR5cGVjb2RlKSB7CisgICAgICAgIHJldHVybiAhKHR5cGVjb2RlID09ICdbJyB8fCB0eXBlY29kZSA9PSAnTCcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0cnVlIGlmIGluc3RhbmNlcyBvZiBjbGFzcyB7QGNvZGUgY2x9IGFyZSBTZXJpYWxpemFibGUsCisgICAgICogZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqCisgICAgICogQHBhcmFtIGNsCisgICAgICogICAgICAgICAgICBhIGphdmEubGFuZy5DbGFzcyB3aGljaCB0byB0ZXN0CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgaW5zdGFuY2VzIG9mIHRoZSBjbGFzcyBhcmUgU2VyaWFsaXphYmxlCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IGlmIGluc3RhbmNlcyBvZiB0aGUgY2xhc3MgYXJlIG5vdAorICAgICAqICAgICAgICAgU2VyaWFsaXphYmxlCisgICAgICoKKyAgICAgKiBAc2VlIE9iamVjdCNoYXNoQ29kZQorICAgICAqLworICAgIHN0YXRpYyBib29sZWFuIGlzU2VyaWFsaXphYmxlKENsYXNzPD8+IGNsKSB7CisgICAgICAgIHJldHVybiBTRVJJQUxJWkFCTEUuaXNBc3NpZ25hYmxlRnJvbShjbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzb2x2ZXMgdGhlIGNsYXNzIHByb3BlcnRpZXMsIGlmIHRoZXkgd2VyZW4ndCBhbHJlYWR5CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlc29sdmVQcm9wZXJ0aWVzKCkgeworICAgICAgICBpZiAoYXJlUHJvcGVydGllc1Jlc29sdmVkKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBDbGFzczw/PiBjbCA9IGZvckNsYXNzKCk7CisgICAgICAgIGlzUHJveHkgPSBQcm94eS5pc1Byb3h5Q2xhc3MoY2wpOworICAgICAgICBpc0VudW0gPSBFbnVtLmNsYXNzLmlzQXNzaWduYWJsZUZyb20oY2wpOworICAgICAgICBpc1NlcmlhbGl6YWJsZSA9IGlzU2VyaWFsaXphYmxlKGNsKTsKKyAgICAgICAgaXNFeHRlcm5hbGl6YWJsZSA9IGlzRXh0ZXJuYWxpemFibGUoY2wpOworCisgICAgICAgIGFyZVByb3BlcnRpZXNSZXNvbHZlZCA9IHRydWU7CisgICAgfQorCisgICAgYm9vbGVhbiBpc1NlcmlhbGl6YWJsZSgpIHsKKyAgICAgICAgcmVzb2x2ZVByb3BlcnRpZXMoKTsKKyAgICAgICAgcmV0dXJuIGlzU2VyaWFsaXphYmxlOworICAgIH0KKworICAgIGJvb2xlYW4gaXNFeHRlcm5hbGl6YWJsZSgpIHsKKyAgICAgICAgcmVzb2x2ZVByb3BlcnRpZXMoKTsKKyAgICAgICAgcmV0dXJuIGlzRXh0ZXJuYWxpemFibGU7CisgICAgfQorCisgICAgYm9vbGVhbiBpc1Byb3h5KCkgeworICAgICAgICByZXNvbHZlUHJvcGVydGllcygpOworICAgICAgICByZXR1cm4gaXNQcm94eTsKKyAgICB9CisKKyAgICBib29sZWFuIGlzRW51bSgpIHsKKyAgICAgICAgcmVzb2x2ZVByb3BlcnRpZXMoKTsKKyAgICAgICAgcmV0dXJuIGlzRW51bTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZXNjcmlwdG9yIGZvciBhIHNlcmlhbGl6YWJsZSBjbGFzcy4KKyAgICAgKiBSZXR1cm5zIG51bGwgaWYgdGhlIGNsYXNzIGRvZXNuJ3QgaW1wbGVtZW50IHtAY29kZSBTZXJpYWxpemFibGV9IG9yIHtAY29kZSBFeHRlcm5hbGl6YWJsZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2wKKyAgICAgKiAgICAgICAgICAgIGEgamF2YS5sYW5nLkNsYXNzIGZvciB3aGljaCB0byBvYnRhaW4gdGhlIGNvcnJlc3BvbmRpbmcKKyAgICAgKiAgICAgICAgICAgIGRlc2NyaXB0b3IKKyAgICAgKiBAcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIGRlc2NyaXB0b3IgaWYgdGhlIGNsYXNzIGlzIHNlcmlhbGl6YWJsZSBvcgorICAgICAqICAgICAgICAgZXh0ZXJuYWxpemFibGU7IG51bGwgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgT2JqZWN0U3RyZWFtQ2xhc3MgbG9va3VwKENsYXNzPD8+IGNsKSB7CisgICAgICAgIE9iamVjdFN0cmVhbUNsYXNzIG9zYyA9IGxvb2t1cFN0cmVhbUNsYXNzKGNsKTsKKyAgICAgICAgcmV0dXJuIChvc2MuaXNTZXJpYWxpemFibGUoKSB8fCBvc2MuaXNFeHRlcm5hbGl6YWJsZSgpKSA/IG9zYyA6IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGVzY3JpcHRvciBmb3IgYW55IGNsYXNzLCB3aGV0aGVyIG9yIG5vdCB0aGUgY2xhc3MKKyAgICAgKiBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSBvciBFeHRlcm5hbGl6YWJsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbAorICAgICAqICAgICAgICAgICAgYSBqYXZhLmxhbmcuQ2xhc3MgZm9yIHdoaWNoIHRvIG9idGFpbiB0aGUgY29ycmVzcG9uZGluZworICAgICAqICAgICAgICAgICAgZGVzY3JpcHRvcgorICAgICAqIEByZXR1cm4gdGhlIGRlc2NyaXB0b3IKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBPYmplY3RTdHJlYW1DbGFzcyBsb29rdXBBbnkoQ2xhc3M8Pz4gY2wpIHsKKyAgICAgICAgcmV0dXJuIGxvb2t1cFN0cmVhbUNsYXNzKGNsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGRlc2NyaXB0b3IgKE9iamVjdFN0cmVhbUNsYXNzKSBjb3JyZXNwb25kaW5nIHRvIHRoZSBjbGFzcworICAgICAqIHtAY29kZSBjbH0uIFJldHVybnMgYW4gT2JqZWN0U3RyZWFtQ2xhc3MgZXZlbiBpZiBpbnN0YW5jZXMgb2YgdGhlCisgICAgICogY2xhc3MgY2Fubm90IGJlIHNlcmlhbGl6ZWQKKyAgICAgKgorICAgICAqIEBwYXJhbSBjbAorICAgICAqICAgICAgICAgICAgYSBqYXZhLmxhbmdDbGFzcyBmb3Igd2hpY2ggdG8gb2J0YWluIHRoZSBjb3JyZXNwb25kaW5nCisgICAgICogICAgICAgICAgICBkZXNjcmlwdG9yCisgICAgICogQHJldHVybiB0aGUgY29ycmVzcG9uZGluZyBkZXNjcmlwdG9yCisgICAgICovCisgICAgc3RhdGljIE9iamVjdFN0cmVhbUNsYXNzIGxvb2t1cFN0cmVhbUNsYXNzKENsYXNzPD8+IGNsKSB7CisgICAgICAgIFdlYWtIYXNoTWFwPENsYXNzPD8+LCBPYmplY3RTdHJlYW1DbGFzcz4gdGxjID0gZ2V0Q2FjaGUoKTsKKyAgICAgICAgT2JqZWN0U3RyZWFtQ2xhc3MgY2FjaGVkVmFsdWUgPSB0bGMuZ2V0KGNsKTsKKyAgICAgICAgaWYgKGNhY2hlZFZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgIGNhY2hlZFZhbHVlID0gY3JlYXRlQ2xhc3NEZXNjKGNsKTsKKyAgICAgICAgICAgIHRsYy5wdXQoY2wsIGNhY2hlZFZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2FjaGVkVmFsdWU7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBIFRocmVhZExvY2FsIGNhY2hlIGZvciBsb29rdXBTdHJlYW1DbGFzcywgd2l0aCB0aGUgcG9zc2liaWxpdHkgb2YgZGlzY2FyZGluZyB0aGUgdGhyZWFkCisgICAgICogbG9jYWwgc3RvcmFnZSBjb250ZW50IHdoZW4gdGhlIGhlYXAgaXMgZXhoYXVzdGVkLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFNvZnRSZWZlcmVuY2U8VGhyZWFkTG9jYWw8V2Vha0hhc2hNYXA8Q2xhc3M8Pz4sIE9iamVjdFN0cmVhbUNsYXNzPj4+IHN0b3JhZ2UgPQorICAgICAgICAgICAgbmV3IFNvZnRSZWZlcmVuY2U8VGhyZWFkTG9jYWw8V2Vha0hhc2hNYXA8Q2xhc3M8Pz4sIE9iamVjdFN0cmVhbUNsYXNzPj4+KG51bGwpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgV2Vha0hhc2hNYXA8Q2xhc3M8Pz4sIE9iamVjdFN0cmVhbUNsYXNzPiBnZXRDYWNoZSgpIHsKKyAgICAgICAgVGhyZWFkTG9jYWw8V2Vha0hhc2hNYXA8Q2xhc3M8Pz4sIE9iamVjdFN0cmVhbUNsYXNzPj4gdGxzID0gc3RvcmFnZS5nZXQoKTsKKyAgICAgICAgaWYgKHRscyA9PSBudWxsKSB7CisgICAgICAgICAgICB0bHMgPSBuZXcgVGhyZWFkTG9jYWw8V2Vha0hhc2hNYXA8Q2xhc3M8Pz4sIE9iamVjdFN0cmVhbUNsYXNzPj4oKSB7CisgICAgICAgICAgICAgICAgcHVibGljIFdlYWtIYXNoTWFwPENsYXNzPD8+LCBPYmplY3RTdHJlYW1DbGFzcz4gaW5pdGlhbFZhbHVlKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFdlYWtIYXNoTWFwPENsYXNzPD8+LCBPYmplY3RTdHJlYW1DbGFzcz4oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9OworICAgICAgICAgICAgc3RvcmFnZSA9IG5ldyBTb2Z0UmVmZXJlbmNlPFRocmVhZExvY2FsPFdlYWtIYXNoTWFwPENsYXNzPD8+LCBPYmplY3RTdHJlYW1DbGFzcz4+Pih0bHMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0bHMuZ2V0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QgaWYgY2xhc3MgPGNvZGU+Y2w8L2NvZGU+IGltcGxlbWVudHMKKyAgICAgKiA8Y29kZT5tZXRob2ROYW1lPC9jb2RlPiAuIFJldHVybiBudWxsIG90aGVyd2lzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbAorICAgICAqICAgICAgICAgICAgYSBqYXZhLmxhbmcuQ2xhc3Mgd2hpY2ggdG8gdGVzdAorICAgICAqIEByZXR1cm4gPGNvZGU+amF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kPC9jb2RlPiBpZiB0aGUgY2xhc3MgaW1wbGVtZW50cworICAgICAqICAgICAgICAgd3JpdGVSZXBsYWNlIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSBjbGFzcyBkb2VzIG5vdCBpbXBsZW1lbnQKKyAgICAgKiAgICAgICAgIHdyaXRlUmVwbGFjZQorICAgICAqLworICAgIHN0YXRpYyBNZXRob2QgZmluZE1ldGhvZChDbGFzczw/PiBjbCwgU3RyaW5nIG1ldGhvZE5hbWUpIHsKKyAgICAgICAgQ2xhc3M8Pz4gc2VhcmNoID0gY2w7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBudWxsOworICAgICAgICB3aGlsZSAoc2VhcmNoICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbWV0aG9kID0gc2VhcmNoLmdldERlY2xhcmVkTWV0aG9kKG1ldGhvZE5hbWUsIChDbGFzc1tdKSBudWxsKTsKKyAgICAgICAgICAgICAgICBpZiAoc2VhcmNoID09IGNsCisgICAgICAgICAgICAgICAgICAgICAgICB8fCAobWV0aG9kLmdldE1vZGlmaWVycygpICYgTW9kaWZpZXIuUFJJVkFURSkgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICBtZXRob2Quc2V0QWNjZXNzaWJsZSh0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1ldGhvZDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gbnNtKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzZWFyY2ggPSBzZWFyY2guZ2V0U3VwZXJjbGFzcygpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIGlmIGNsYXNzIDxjb2RlPmNsPC9jb2RlPiBpbXBsZW1lbnRzCisgICAgICogcHJpdmF0ZSA8Y29kZT5tZXRob2ROYW1lPC9jb2RlPiAuIFJldHVybiBudWxsIG90aGVyd2lzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbAorICAgICAqICAgICAgICAgICAgYSBqYXZhLmxhbmcuQ2xhc3Mgd2hpY2ggdG8gdGVzdAorICAgICAqIEByZXR1cm4ge0Bjb2RlIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZH0gaWYgdGhlIGNsYXNzIGltcGxlbWVudHMKKyAgICAgKiAgICAgICAgIHdyaXRlUmVwbGFjZSB7QGNvZGUgbnVsbH0gaWYgdGhlIGNsYXNzIGRvZXMgbm90IGltcGxlbWVudAorICAgICAqICAgICAgICAgd3JpdGVSZXBsYWNlCisgICAgICovCisgICAgc3RhdGljIE1ldGhvZCBmaW5kUHJpdmF0ZU1ldGhvZChDbGFzczw/PiBjbCwgU3RyaW5nIG1ldGhvZE5hbWUsCisgICAgICAgICAgICBDbGFzczw/PltdIHBhcmFtKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNZXRob2QgbWV0aG9kID0gY2wuZ2V0RGVjbGFyZWRNZXRob2QobWV0aG9kTmFtZSwgcGFyYW0pOworICAgICAgICAgICAgaWYgKE1vZGlmaWVyLmlzUHJpdmF0ZShtZXRob2QuZ2V0TW9kaWZpZXJzKCkpICYmIG1ldGhvZC5nZXRSZXR1cm5UeXBlKCkgPT0gdm9pZC5jbGFzcykgeworICAgICAgICAgICAgICAgIG1ldGhvZC5zZXRBY2Nlc3NpYmxlKHRydWUpOworICAgICAgICAgICAgICAgIHJldHVybiBtZXRob2Q7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBuc20pIHsKKyAgICAgICAgICAgIC8vIElnbm9yZWQKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBib29sZWFuIGhhc01ldGhvZFdyaXRlUmVwbGFjZSgpIHsKKyAgICAgICAgcmV0dXJuIChtZXRob2RXcml0ZVJlcGxhY2UgIT0gbnVsbCk7CisgICAgfQorCisgICAgTWV0aG9kIGdldE1ldGhvZFdyaXRlUmVwbGFjZSgpIHsKKyAgICAgICAgcmV0dXJuIG1ldGhvZFdyaXRlUmVwbGFjZTsKKyAgICB9CisKKyAgICBib29sZWFuIGhhc01ldGhvZFJlYWRSZXNvbHZlKCkgeworICAgICAgICByZXR1cm4gKG1ldGhvZFJlYWRSZXNvbHZlICE9IG51bGwpOworICAgIH0KKworICAgIE1ldGhvZCBnZXRNZXRob2RSZWFkUmVzb2x2ZSgpIHsKKyAgICAgICAgcmV0dXJuIG1ldGhvZFJlYWRSZXNvbHZlOworICAgIH0KKworICAgIGJvb2xlYW4gaGFzTWV0aG9kV3JpdGVPYmplY3QoKSB7CisgICAgICAgIHJldHVybiAobWV0aG9kV3JpdGVPYmplY3QgIT0gbnVsbCk7CisgICAgfQorCisgICAgTWV0aG9kIGdldE1ldGhvZFdyaXRlT2JqZWN0KCkgeworICAgICAgICByZXR1cm4gbWV0aG9kV3JpdGVPYmplY3Q7CisgICAgfQorCisgICAgYm9vbGVhbiBoYXNNZXRob2RSZWFkT2JqZWN0KCkgeworICAgICAgICByZXR1cm4gKG1ldGhvZFJlYWRPYmplY3QgIT0gbnVsbCk7CisgICAgfQorCisgICAgTWV0aG9kIGdldE1ldGhvZFJlYWRPYmplY3QoKSB7CisgICAgICAgIHJldHVybiBtZXRob2RSZWFkT2JqZWN0OworICAgIH0KKworICAgIGJvb2xlYW4gaGFzTWV0aG9kUmVhZE9iamVjdE5vRGF0YSgpIHsKKyAgICAgICAgcmV0dXJuIChtZXRob2RSZWFkT2JqZWN0Tm9EYXRhICE9IG51bGwpOworICAgIH0KKworICAgIE1ldGhvZCBnZXRNZXRob2RSZWFkT2JqZWN0Tm9EYXRhKCkgeworICAgICAgICByZXR1cm4gbWV0aG9kUmVhZE9iamVjdE5vRGF0YTsKKyAgICB9CisKKyAgICB2b2lkIGluaXRQcml2YXRlRmllbGRzKE9iamVjdFN0cmVhbUNsYXNzIGRlc2MpIHsKKyAgICAgICAgbWV0aG9kV3JpdGVSZXBsYWNlID0gZGVzYy5tZXRob2RXcml0ZVJlcGxhY2U7CisgICAgICAgIG1ldGhvZFJlYWRSZXNvbHZlID0gZGVzYy5tZXRob2RSZWFkUmVzb2x2ZTsKKyAgICAgICAgbWV0aG9kV3JpdGVPYmplY3QgPSBkZXNjLm1ldGhvZFdyaXRlT2JqZWN0OworICAgICAgICBtZXRob2RSZWFkT2JqZWN0ID0gZGVzYy5tZXRob2RSZWFkT2JqZWN0OworICAgICAgICBtZXRob2RSZWFkT2JqZWN0Tm9EYXRhID0gZGVzYy5tZXRob2RSZWFkT2JqZWN0Tm9EYXRhOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgY2xhc3MgKGphdmEubGFuZy5DbGFzcykgdGhhdCB0aGUgcmVjZWl2ZXIgcmVwcmVzZW50cworICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIGFDbGFzcywgdGhlIG5ldyBjbGFzcyB0aGF0IHRoZSByZWNlaXZlciBkZXNjcmliZXMKKyAgICAgKi8KKyAgICB2b2lkIHNldENsYXNzKENsYXNzPD8+IGMpIHsKKyAgICAgICAgcmVzb2x2ZWRDbGFzcyA9IGM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBjb2xsZWN0aW9uIG9mIGZpZWxkIGRlc2NyaXB0b3JzIGZvciB0aGUgZmllbGRzIG9mIHRoZQorICAgICAqIGNvcnJlc3BvbmRpbmcgY2xhc3MKKyAgICAgKgorICAgICAqIEBwYXJhbSBmCisgICAgICogICAgICAgICAgICBPYmplY3RTdHJlYW1GaWVsZFtdLCB0aGUgcmVjZWl2ZXIncyBuZXcgY29sbGVjdGlvbiBvZiBkZWNsYXJlZAorICAgICAqICAgICAgICAgICAgZmllbGRzIGZvciB0aGUgY2xhc3MgaXQgcmVwcmVzZW50cworICAgICAqLworICAgIHZvaWQgc2V0RmllbGRzKE9iamVjdFN0cmVhbUZpZWxkW10gZikgeworICAgICAgICBmaWVsZHMgPSBmOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgY29sbGVjdGlvbiBvZiBmaWVsZCBkZXNjcmlwdG9ycyBmb3IgdGhlIGlucHV0IGZpZWxkcyBvZiB0aGUKKyAgICAgKiBjb3JyZXNwb25kaW5nIGNsYXNzCisgICAgICoKKyAgICAgKiBAcGFyYW0gZgorICAgICAqICAgICAgICAgICAgT2JqZWN0U3RyZWFtRmllbGRbXSwgdGhlIHJlY2VpdmVyJ3MgbmV3IGNvbGxlY3Rpb24gb2YgaW5wdXQKKyAgICAgKiAgICAgICAgICAgIGZpZWxkcyBmb3IgdGhlIGNsYXNzIGl0IHJlcHJlc2VudHMKKyAgICAgKi8KKyAgICB2b2lkIHNldExvYWRGaWVsZHMoT2JqZWN0U3RyZWFtRmllbGRbXSBmKSB7CisgICAgICAgIGxvYWRGaWVsZHMgPSBmOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZmxhZ3MgZm9yIHRoaXMgZGVzY3JpcHRvciwgd2hlcmUgcG9zc2libGUgY29tYmluZWQgdmFsdWVzIGFyZQorICAgICAqCisgICAgICogT2JqZWN0U3RyZWFtQ29uc3RhbnRzLlNDX1dSSVRFX01FVEhPRAorICAgICAqIE9iamVjdFN0cmVhbUNvbnN0YW50cy5TQ19TRVJJQUxJWkFCTEUKKyAgICAgKiBPYmplY3RTdHJlYW1Db25zdGFudHMuU0NfRVhURVJOQUxJWkFCTEUKKyAgICAgKgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICBieXRlLCB0aGUgcmVjZWl2ZXIncyBuZXcgZmxhZ3MgZm9yIHRoZSBjbGFzcyBpdCByZXByZXNlbnRzCisgICAgICovCisgICAgdm9pZCBzZXRGbGFncyhieXRlIGIpIHsKKyAgICAgICAgZmxhZ3MgPSBiOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhlIHJlY2VpdmVyCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3TmFtZQorICAgICAqICAgICAgICAgICAgYSBTdHJpbmcsIHRoZSBuZXcgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGNsYXNzIHRoZQorICAgICAqICAgICAgICAgICAgcmVjZWl2ZXIgcmVwcmVzZW50cworICAgICAqLworICAgIHZvaWQgc2V0TmFtZShTdHJpbmcgbmV3TmFtZSkgeworICAgICAgICBjbGFzc05hbWUgPSBuZXdOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgU2VyaWFsIFZlcnNpb24gVXNlciBJRCBvZiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhlIHJlY2VpdmVyCisgICAgICoKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgYSBsb25nLCB0aGUgbmV3IFNVSUQgZm9yIHRoZSBjbGFzcyByZXByZXNlbnRlZCBieSB0aGUgcmVjZWl2ZXIKKyAgICAgKi8KKyAgICB2b2lkIHNldFNlcmlhbFZlcnNpb25VSUQobG9uZyBsKSB7CisgICAgICAgIHN2VUlEID0gbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGRlc2NyaXB0b3IgZm9yIHRoZSBzdXBlcmNsYXNzIG9mIHRoZSBjbGFzcyBkZXNjcmliZWQgYnkgdGhlCisgICAgICogcmVjZWl2ZXIKKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICBhbiBPYmplY3RTdHJlYW1DbGFzcywgdGhlIG5ldyBPYmplY3RTdHJlYW1DbGFzcyBmb3IgdGhlCisgICAgICogICAgICAgICAgICBzdXBlcmNsYXNzIG9mIHRoZSBjbGFzcyByZXByZXNlbnRlZCBieSB0aGUgcmVjZWl2ZXIKKyAgICAgKi8KKyAgICB2b2lkIHNldFN1cGVyY2xhc3MoT2JqZWN0U3RyZWFtQ2xhc3MgYykgeworICAgICAgICBzdXBlcmNsYXNzID0gYzsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBwcmltaXRpdmVTaXplKENsYXNzPD8+IHR5cGUpIHsKKyAgICAgICAgaWYgKHR5cGUgPT0gYnl0ZS5jbGFzcyB8fCB0eXBlID09IGJvb2xlYW4uY2xhc3MpIHsKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisgICAgICAgIGlmICh0eXBlID09IHNob3J0LmNsYXNzIHx8IHR5cGUgPT0gY2hhci5jbGFzcykgeworICAgICAgICAgICAgcmV0dXJuIDI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHR5cGUgPT0gaW50LmNsYXNzIHx8IHR5cGUgPT0gZmxvYXQuY2xhc3MpIHsKKyAgICAgICAgICAgIHJldHVybiA0OworICAgICAgICB9CisgICAgICAgIGlmICh0eXBlID09IGxvbmcuY2xhc3MgfHwgdHlwZSA9PSBkb3VibGUuY2xhc3MpIHsKKyAgICAgICAgICAgIHJldHVybiA4OworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIGNvbmNpc2UsIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIG9mIHRoaXMKKyAgICAgKiBkZXNjcmlwdG9yLgorICAgICAqCisgICAgICogQHJldHVybiBhIHByaW50YWJsZSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGRlc2NyaXB0b3IuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIGdldE5hbWUoKSArICI6IHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSIgKyBnZXRTZXJpYWxWZXJzaW9uVUlEKCkgKyAiTDsiOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL09iamVjdFN0cmVhbUNvbnN0YW50cy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vT2JqZWN0U3RyZWFtQ29uc3RhbnRzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODIyOGIzMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL09iamVjdFN0cmVhbUNvbnN0YW50cy5qYXZhCkBAIC0wLDAgKzEsMTg1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKKy8qKgorICogQSBoZWxwZXIgaW50ZXJmYWNlIHdpdGggY29uc3RhbnRzIHVzZWQgYnkgdGhlIHNlcmlhbGl6YXRpb24gaW1wbGVtZW50YXRpb24uCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBpbnRlcmZhY2UgT2JqZWN0U3RyZWFtQ29uc3RhbnRzIHsKKworICAgIC8qKgorICAgICAqIFRoZSBzdHJlYW0gaGVhZGVyJ3MgbWFnaWMgbnVtYmVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgU1RSRUFNX01BR0lDID0gKHNob3J0KSAweGFjZWQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3RyZWFtIGhlYWRlcidzIHZlcnNpb24gbnVtYmVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgU1RSRUFNX1ZFUlNJT04gPSA1OworCisgICAgLy8gVGhlc2UgYXJlIHRhZ3MgdG8gaW5kaWNhdGUgdGhlIHN0cmVhbSBjb250ZW50cworCisgICAgLyoqCisgICAgICogVGhlIG1pbmltdW0gdGFnIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBUQ19CQVNFID0gMHg3MDsKKworICAgIC8qKgorICAgICAqIFRhZyB0byBtYXJrIGEge0Bjb2RlIG51bGx9IG9iamVjdCByZWZlcmVuY2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFRDX05VTEwgPSAoYnl0ZSkgMHg3MDsKKworICAgIC8qKgorICAgICAqIFRhZyB0byBtYXJrIGEgcmVmZXJlbmNlIHRvIGFuIG9iamVjdCB0aGF0IGhhcyBhbHJlYWR5IGJlZW4gd3JpdHRlbiB0byB0aGUKKyAgICAgKiBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFRDX1JFRkVSRU5DRSA9IChieXRlKSAweDcxOworCisgICAgLyoqCisgICAgICogVGFnIHRvIG1hcmsgYSBuZXcgY2xhc3MgZGVzY3JpcHRvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgVENfQ0xBU1NERVNDID0gKGJ5dGUpIDB4NzI7CisKKyAgICAvKioKKyAgICAgKiBUYWcgdG8gbWFyayBhIG5ldyBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFRDX09CSkVDVCA9IChieXRlKSAweDczOworCisgICAgLyoqCisgICAgICogVGFnIHRvIG1hcmsgYSBuZXcgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBUQ19TVFJJTkcgPSAoYnl0ZSkgMHg3NDsKKworICAgIC8qKgorICAgICAqIFRhZyB0byBtYXJrIGEgbmV3IGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBUQ19BUlJBWSA9IChieXRlKSAweDc1OworCisgICAgLyoqCisgICAgICogVGFnIHRvIG1hcmsgYSByZWZlcmVuY2UgdG8gYSBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgVENfQ0xBU1MgPSAoYnl0ZSkgMHg3NjsKKworICAgIC8qKgorICAgICAqIFRhZyB0byBtYXJrIGEgYmxvY2sgb2Ygb3B0aW9uYWwgZGF0YS4gVGhlIGJ5dGUgZm9sbG93aW5nIHRoaXMgdGFnCisgICAgICogaW5kaWNhdGVzIHRoZSBzaXplIG9mIHRoZSBibG9jay4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgVENfQkxPQ0tEQVRBID0gKGJ5dGUpIDB4Nzc7CisKKyAgICAvKioKKyAgICAgKiBUYWcgdG8gbWFyayB0aGUgZW5kIG9mIGJsb2NrIGRhdGEgYmxvY2tzIGZvciBhbiBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFRDX0VOREJMT0NLREFUQSA9IChieXRlKSAweDc4OworCisgICAgLyoqCisgICAgICogVGFnIHRvIG1hcmsgYSBzdHJlYW0gcmVzZXQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFRDX1JFU0VUID0gKGJ5dGUpIDB4Nzk7CisKKyAgICAvKioKKyAgICAgKiBUYWcgdG8gbWFyayBhIGxvbmcgYmxvY2sgb2YgZGF0YS4gVGhlIGxvbmcgZm9sbG93aW5nIHRoaXMgdGFnCisgICAgICogaW5kaWNhdGVzIHRoZSBzaXplIG9mIHRoZSBibG9jay4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgVENfQkxPQ0tEQVRBTE9ORyA9IChieXRlKSAweDdBOworCisgICAgLyoqCisgICAgICogVGFnIHRvIG1hcmsgYW4gZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBUQ19FWENFUFRJT04gPSAoYnl0ZSkgMHg3QjsKKworICAgIC8qKgorICAgICAqIFRhZyB0byBtYXJrIGEgbG9uZyBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFRDX0xPTkdTVFJJTkcgPSAoYnl0ZSkgMHg3QzsKKworICAgIC8qKgorICAgICAqIFRhZyB0byBtYXJrIGEgbmV3IHByb3h5IGNsYXNzIGRlc2NyaXB0b3IuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFRDX1BST1hZQ0xBU1NERVNDID0gKGJ5dGUpIDB4N0Q7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF4aW11bSB0YWcgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFRDX01BWCA9IDB4N0U7CisKKyAgICAvKioKKyAgICAgKiBIYW5kbGUgZm9yIHRoZSBmaXJzdCBvYmplY3QgdGhhdCBnZXRzIHNlcmlhbGl6ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgYmFzZVdpcmVIYW5kbGUgPSAweDAwN2UwMDAwOworCisgICAgLyoqCisgICAgICogU3RyZWFtIHByb3RvY29sIHZlcnNpb24gMS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUk9UT0NPTF9WRVJTSU9OXzEgPSAxOworCisgICAgLyoqCisgICAgICogU3RyZWFtIHByb3RvY29sIHZlcnNpb24gMi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUk9UT0NPTF9WRVJTSU9OXzIgPSAyOworCisgICAgLyoqCisgICAgICogUGVybWlzc2lvbiBjb25zdGFudCB0byBlbmFibGUgc3ViY2xhc3Npbmcgb2YgT2JqZWN0SW5wdXRTdHJlYW0gYW5kCisgICAgICogT2JqZWN0T3V0cHV0U3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU2VyaWFsaXphYmxlUGVybWlzc2lvbiBTVUJDTEFTU19JTVBMRU1FTlRBVElPTl9QRVJNSVNTSU9OID0gbmV3IFNlcmlhbGl6YWJsZVBlcm1pc3Npb24oCisgICAgICAgICAgICAiZW5hYmxlU3ViY2xhc3NJbXBsZW1lbnRhdGlvbiIpOworCisgICAgLyoqCisgICAgICogUGVybWlzc2lvbiBjb25zdGFudCB0byBlbmFibGUgb2JqZWN0IHN1YnN0aXR1dGlvbiBkdXJpbmcgc2VyaWFsaXphdGlvbgorICAgICAqIGFuZCBkZXNlcmlhbGl6YXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTZXJpYWxpemFibGVQZXJtaXNzaW9uIFNVQlNUSVRVVElPTl9QRVJNSVNTSU9OID0gbmV3IFNlcmlhbGl6YWJsZVBlcm1pc3Npb24oCisgICAgICAgICAgICAiZW5hYmxlU3Vic3RpdHV0aW9uIik7CisKKyAgICAvLyBGbGFncyB0aGF0IGluZGljYXRlIGlmIHRoZSBvYmplY3Qgd2FzIHNlcmlhbGl6YWJsZSwgZXh0ZXJuYWxpemFibGUKKyAgICAvLyBhbmQgaGFkIGEgd3JpdGVPYmplY3QgbWV0aG9kIHdoZW4gZHVtcGVkLgorICAgIC8qKgorICAgICAqIEJpdCBtYXNrIGZvciB0aGUge0Bjb2RlIGZsYWd9IGZpZWxkIGluIE9iamVjdFN0cmVhbUNsYXNzLiBJbmRpY2F0ZXMKKyAgICAgKiB0aGF0IGEgc2VyaWFsaXphYmxlIGNsYXNzIGhhcyBpdHMgb3duIHtAY29kZSB3cml0ZU9iamVjdH0gbWV0aG9kLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBTQ19XUklURV9NRVRIT0QgPSAweDAxOyAvLyBJZiBTQ19TRVJJQUxJWkFCTEUKKworICAgIC8qKgorICAgICAqIEJpdCBtYXNrIGZvciB0aGUge0Bjb2RlIGZsYWd9IGZpZWxkIGluIE9iamVjdFN0cmVhbUNsYXNzLiBJbmRpY2F0ZXMKKyAgICAgKiB0aGF0IGEgY2xhc3MgaXMgc2VyaWFsaXphYmxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBTQ19TRVJJQUxJWkFCTEUgPSAweDAyOworCisgICAgLyoqCisgICAgICogQml0IG1hc2sgZm9yIHRoZSB7QGNvZGUgZmxhZ30gZmllbGQgaW4gT2JqZWN0U3RyZWFtQ2xhc3MuIEluZGljYXRlcworICAgICAqIHRoYXQgYSBjbGFzcyBpcyBleHRlcm5hbGl6YWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgU0NfRVhURVJOQUxJWkFCTEUgPSAweDA0OworCisgICAgLyoqCisgICAgICogQml0IG1hc2sgZm9yIHRoZSB7QGNvZGUgZmxhZ30gZmllbGQgaW4gT2JqZWN0U3RyZWFtQ2xhc3MuIEluZGljYXRlcworICAgICAqIHRoYXQgYW4gZXh0ZXJuYWxpemFibGUgY2xhc3MgaXMgd3JpdHRlbiBpbiBibG9jayBkYXRhIG1vZGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFNDX0JMT0NLX0RBVEEgPSAweDA4OyAvLyBJZiBTQ19FWFRFUk5BTElaQUJMRQorCisgICAgLyoqCisgICAgICogVGFnIHRvIG1hcmsgYSBuZXcgZW51bS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgVENfRU5VTSA9IDB4N0U7CisKKyAgICAvKioKKyAgICAgKiBCaXQgbWFzayBmb3IgdGhlIHtAY29kZSBmbGFnfSBmaWVsZCBpbiBPYmplY3RTdHJlYW1DbGFzcy4gSW5kaWNhdGVzCisgICAgICogdGhhdCBhIGNsYXNzIGlzIGFuIGVudW0gdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgU0NfRU5VTSA9IDB4MTA7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9PYmplY3RTdHJlYW1FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL09iamVjdFN0cmVhbUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1NGQzMDQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9PYmplY3RTdHJlYW1FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDUzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKKy8qKgorICogU2lnbmFscyBzb21lIHNvcnQgb2YgcHJvYmxlbSBkdXJpbmcgZWl0aGVyIHNlcmlhbGl6YXRpb24gb3IgZGVzZXJpYWxpemF0aW9uCisgKiBvZiBvYmplY3RzLiBUaGlzIGlzIGFjdHVhbGx5IHRoZSBzdXBlcmNsYXNzIG9mIHNldmVyYWwgb3RoZXIsIG1vcmUgc3BlY2lmaWMKKyAqIGV4Y2VwdGlvbiBjbGFzc2VzLgorICoKKyAqIEBzZWUgSW52YWxpZE9iamVjdEV4Y2VwdGlvbgorICogQHNlZSBOb3RBY3RpdmVFeGNlcHRpb24KKyAqIEBzZWUgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uCisgKiBAc2VlIE9wdGlvbmFsRGF0YUV4Y2VwdGlvbgorICogQHNlZSBTdHJlYW1Db3JydXB0ZWRFeGNlcHRpb24KKyAqIEBzZWUgV3JpdGVBYm9ydGVkRXhjZXB0aW9uCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBPYmplY3RTdHJlYW1FeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3MjYwODk4MTc0ODMzMzkyNjA3TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIE9iamVjdFN0cmVhbUV4Y2VwdGlvbn0gd2l0aCBpdHMgc3RhY2sgdHJhY2UKKyAgICAgKiBmaWxsZWQgaW4uCisgICAgICovCisgICAgcHJvdGVjdGVkIE9iamVjdFN0cmVhbUV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBPYmplY3RTdHJlYW1FeGNlcHRpb259IHdpdGggaXRzIHN0YWNrIHRyYWNlIGFuZAorICAgICAqIGRldGFpbCBtZXNzYWdlIGZpbGxlZCBpbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHByb3RlY3RlZCBPYmplY3RTdHJlYW1FeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vT2JqZWN0U3RyZWFtRmllbGQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL09iamVjdFN0cmVhbUZpZWxkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGI0NTBlMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL09iamVjdFN0cmVhbUZpZWxkLmphdmEKQEAgLTAsMCArMSwzNjIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEubGFuZy5yZWYuV2Vha1JlZmVyZW5jZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db21wYXJhdG9yOworCisvKioKKyAqIERlc2NyaWJlcyBhIGZpZWxkIGZvciB0aGUgcHVycG9zZSBvZiBzZXJpYWxpemF0aW9uLiBDbGFzc2VzIGNhbiBkZWZpbmUgdGhlCisgKiBjb2xsZWN0aW9uIG9mIGZpZWxkcyB0aGF0IGFyZSBzZXJpYWxpemVkLCB3aGljaCBtYXkgYmUgZGlmZmVyZW50IGZyb20gdGhlIHNldAorICogb2YgYWxsIGRlY2xhcmVkIGZpZWxkcy4KKyAqCisgKiBAc2VlIE9iamVjdE91dHB1dFN0cmVhbSN3cml0ZUZpZWxkcygpCisgKiBAc2VlIE9iamVjdElucHV0U3RyZWFtI3JlYWRGaWVsZHMoKQorICovCitwdWJsaWMgY2xhc3MgT2JqZWN0U3RyZWFtRmllbGQgaW1wbGVtZW50cyBDb21wYXJhYmxlPE9iamVjdD4geworCisgICAgLy8gRGVjbGFyZWQgbmFtZSBvZiB0aGUgZmllbGQKKyAgICBwcml2YXRlIFN0cmluZyBuYW1lOworCisgICAgLy8gRGVjbGFyZWQgdHlwZSBvZiB0aGUgZmllbGQKKyAgICBwcml2YXRlIE9iamVjdCB0eXBlOworCisgICAgLy8gb2Zmc2V0IG9mIHRoaXMgZmllbGQgaW4gdGhlIG9iamVjdAorICAgIGludCBvZmZzZXQ7CisKKyAgICAvLyBDYWNoZWQgdmVyc2lvbiBvZiBpbnRlcm4nZWQgdHlwZSBTdHJpbmcKKyAgICBwcml2YXRlIFN0cmluZyB0eXBlU3RyaW5nOworCisgICAgcHJpdmF0ZSBib29sZWFuIHVuc2hhcmVkOworCisgICAgcHJpdmF0ZSBib29sZWFuIGlzRGVzZXJpYWxpemVkOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBPYmplY3RTdHJlYW1GaWVsZCB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBhbmQgdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZmllbGQuCisgICAgICogQHBhcmFtIGNsCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgZmllbGQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBuYW1lfSBvciB7QGNvZGUgY2x9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0U3RyZWFtRmllbGQoU3RyaW5nIG5hbWUsIENsYXNzPD8+IGNsKSB7CisgICAgICAgIGlmIChuYW1lID09IG51bGwgfHwgY2wgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgICAgdGhpcy50eXBlID0gbmV3IFdlYWtSZWZlcmVuY2U8Q2xhc3M8Pz4+KGNsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIE9iamVjdFN0cmVhbUZpZWxkIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLCB0eXBlIGFuZCB0aGUKKyAgICAgKiBpbmRpY2F0aW9uIGlmIGl0IGlzIHVuc2hhcmVkLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBmaWVsZC4KKyAgICAgKiBAcGFyYW0gY2wKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSBmaWVsZC4KKyAgICAgKiBAcGFyYW0gdW5zaGFyZWQKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSB0cnVlfSBpZiB0aGUgZmllbGQgaXMgd3JpdHRlbiBhbmQgcmVhZCB1bnNoYXJlZDsKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbmFtZX0gb3Ige0Bjb2RlIGNsfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHNlZSBPYmplY3RPdXRwdXRTdHJlYW0jd3JpdGVVbnNoYXJlZChPYmplY3QpCisgICAgICovCisgICAgcHVibGljIE9iamVjdFN0cmVhbUZpZWxkKFN0cmluZyBuYW1lLCBDbGFzczw/PiBjbCwgYm9vbGVhbiB1bnNoYXJlZCkgeworICAgICAgICBpZiAobmFtZSA9PSBudWxsIHx8IGNsID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgIHRoaXMudHlwZSA9IChjbC5nZXRDbGFzc0xvYWRlcigpID09IG51bGwpID8gY2wgOiBuZXcgV2Vha1JlZmVyZW5jZTxDbGFzczw/Pj4oY2wpOworICAgICAgICB0aGlzLnVuc2hhcmVkID0gdW5zaGFyZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBPYmplY3RTdHJlYW1GaWVsZCB3aXRoIHRoZSBnaXZlbiBuYW1lIGFuZCB0aGUgZ2l2ZW4gdHlwZS4KKyAgICAgKiBUaGUgdHlwZSBtYXkgYmUgbnVsbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaWduYXR1cmUKKyAgICAgKiAgICAgICAgICAgIEEgU3RyaW5nIHJlcHJlc2VudGluZyB0aGUgdHlwZSBvZiB0aGUgZmllbGQKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgYSBTdHJpbmcsIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCwgb3IgbnVsbAorICAgICAqLworICAgIE9iamVjdFN0cmVhbUZpZWxkKFN0cmluZyBzaWduYXR1cmUsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgIHRoaXMudHlwZVN0cmluZyA9IHNpZ25hdHVyZS5yZXBsYWNlKCcuJywgJy8nKS5pbnRlcm4oKTsKKyAgICAgICAgZGVmYXVsdFJlc29sdmUoKTsKKyAgICAgICAgdGhpcy5pc0Rlc2VyaWFsaXplZCA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBmaWVsZCBkZXNjcmlwdG9yIHRvIHRoZSBzcGVjaWZpZWQgb25lLiBDaGVja3MgZmlyc3QgaWYgb25lCisgICAgICogb2YgdGhlIGNvbXBhcmVkIGZpZWxkcyBoYXMgYSBwcmltaXRpdmUgdHlwZSBhbmQgdGhlIG90aGVyIG9uZSBub3QuIElmIHNvLAorICAgICAqIHRoZSBmaWVsZCB3aXRoIHRoZSBwcmltaXRpdmUgdHlwZSBpcyBjb25zaWRlcmVkIHRvIGJlICJzbWFsbGVyIi4gSWYgYm90aAorICAgICAqIGZpZWxkcyBhcmUgZXF1YWwsIHRoZWlyIG5hbWVzIGFyZSBjb21wYXJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUgd2l0aC4KKyAgICAgKiBAcmV0dXJuIC0xIGlmIHRoaXMgZmllbGQgaXMgInNtYWxsZXIiIHRoYW4gZmllbGQge0Bjb2RlIG99LCAwIGlmIGJvdGgKKyAgICAgKiAgICAgICAgIGZpZWxkcyBhcmUgZXF1YWw7IDEgaWYgdGhpcyBmaWVsZCBpcyAiZ3JlYXRlciIgdGhhbiBmaWVsZCB7QGNvZGUKKyAgICAgKiAgICAgICAgIG99LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKE9iamVjdCBvKSB7CisgICAgICAgIE9iamVjdFN0cmVhbUZpZWxkIGYgPSAoT2JqZWN0U3RyZWFtRmllbGQpIG87CisgICAgICAgIGJvb2xlYW4gdGhpc1ByaW1pdGl2ZSA9IHRoaXMuaXNQcmltaXRpdmUoKTsKKyAgICAgICAgYm9vbGVhbiBmUHJpbWl0aXZlID0gZi5pc1ByaW1pdGl2ZSgpOworCisgICAgICAgIC8vIElmIG9uZSBpcyBwcmltaXRpdmUgYW5kIHRoZSBvdGhlciBpc24ndCwgd2UgaGF2ZSBlbm91Z2ggaW5mbyB0bworICAgICAgICAvLyBjb21wYXJlCisgICAgICAgIGlmICh0aGlzUHJpbWl0aXZlICE9IGZQcmltaXRpdmUpIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzUHJpbWl0aXZlID8gLTEgOiAxOworICAgICAgICB9CisKKyAgICAgICAgLy8gRWl0aGVyIGJvdGggcHJpbWl0aXZlcyBvciBib3RoIG5vdCBwcmltaXRpdmVzLiBDb21wYXJlIGJhc2VkIG9uIG5hbWUuCisgICAgICAgIHJldHVybiB0aGlzLmdldE5hbWUoKS5jb21wYXJlVG8oZi5nZXROYW1lKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWUgb2YgdGhpcyBmaWVsZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGZpZWxkJ3MgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG9mZnNldCBvZiB0aGlzIGZpZWxkIGluIHRoZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgZmllbGQncyBvZmZzZXQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBvZmZzZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSB0eXBlIG9mIHRoZSBmaWVsZCB0aGUgcmVjZWl2ZXIgcmVwcmVzZW50cywgdGhpcyBpcyBhbiBpbnRlcm5hbAorICAgICAqIG1ldGhvZAorICAgICAqCisgICAgICogQHJldHVybiBBIENsYXNzIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIHR5cGUgb2YgdGhlIGZpZWxkCisgICAgICovCisgICAgLy8gQ2hhbmdlZCBmcm9tIHByaXZhdGUgdG8gZGVmYXVsdCB2aXNpYmlsaXR5IGZvciB1c2FnZSBpbiBPYmplY3RTdHJlYW1DbGFzcworICAgIC8qIHBhY2thZ2UgKi8gQ2xhc3M8Pz4gZ2V0VHlwZUludGVybmFsKCkgeworICAgICAgICBpZiAodHlwZSBpbnN0YW5jZW9mIFdlYWtSZWZlcmVuY2UpIHsKKyAgICAgICAgICAgIHJldHVybiAoQ2xhc3M8Pz4pICgoV2Vha1JlZmVyZW5jZTw/PikgdHlwZSkuZ2V0KCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChDbGFzczw/PikgdHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0eXBlIG9mIHRoaXMgZmllbGQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIENsYXNzfSBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSB0eXBlIG9mIHRoZSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xhc3M8Pz4gZ2V0VHlwZSgpIHsKKyAgICAgICAgQ2xhc3M8Pz4gY2wgPSBnZXRUeXBlSW50ZXJuYWwoKTsKKyAgICAgICAgaWYgKGlzRGVzZXJpYWxpemVkICYmICFjbC5pc1ByaW1pdGl2ZSgpKSB7CisgICAgICAgICAgICByZXR1cm4gT2JqZWN0LmNsYXNzOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgY2hhcmFjdGVyIGNvZGUgZm9yIHRoZSB0eXBlIG9mIHRoaXMgZmllbGQuIFRoZSBmb2xsb3dpbmcgY29kZXMgYXJlCisgICAgICogdXNlZDoKKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogQiAgICAgYnl0ZQorICAgICAqIEMgICAgIGNoYXIKKyAgICAgKiBEICAgICBkb3VibGUKKyAgICAgKiBGICAgICBmbG9hdAorICAgICAqIEkgICAgIGludAorICAgICAqIEogICAgIGxvbmcKKyAgICAgKiBMICAgICBjbGFzcyBvciBpbnRlcmZhY2UKKyAgICAgKiBTICAgICBzaG9ydAorICAgICAqIFogICAgIGJvb2xlYW4KKyAgICAgKiBbICAgICBhcnJheQorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZmllbGQncyB0eXBlIGNvZGUuCisgICAgICovCisgICAgcHVibGljIGNoYXIgZ2V0VHlwZUNvZGUoKSB7CisgICAgICAgIHJldHVybiB0eXBlQ29kZU9mKGdldFR5cGVJbnRlcm5hbCgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGNoYXIgdHlwZUNvZGVPZihDbGFzczw/PiB0eXBlKSB7CisgICAgICAgIGlmICh0eXBlID09IGludC5jbGFzcykgeworICAgICAgICAgICAgcmV0dXJuICdJJzsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGJ5dGUuY2xhc3MpIHsKKyAgICAgICAgICAgIHJldHVybiAnQic7CisgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBjaGFyLmNsYXNzKSB7CisgICAgICAgICAgICByZXR1cm4gJ0MnOworICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gc2hvcnQuY2xhc3MpIHsKKyAgICAgICAgICAgIHJldHVybiAnUyc7CisgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBib29sZWFuLmNsYXNzKSB7CisgICAgICAgICAgICByZXR1cm4gJ1onOworICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gbG9uZy5jbGFzcykgeworICAgICAgICAgICAgcmV0dXJuICdKJzsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGZsb2F0LmNsYXNzKSB7CisgICAgICAgICAgICByZXR1cm4gJ0YnOworICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gZG91YmxlLmNsYXNzKSB7CisgICAgICAgICAgICByZXR1cm4gJ0QnOworICAgICAgICB9IGVsc2UgaWYgKHR5cGUuaXNBcnJheSgpKSB7CisgICAgICAgICAgICByZXR1cm4gJ1snOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuICdMJzsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHR5cGUgc2lnbmF0dXJlIHVzZWQgYnkgdGhlIFZNIHRvIHJlcHJlc2VudCB0aGUgdHlwZSBvZiB0aGlzCisgICAgICogZmllbGQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzaWduYXR1cmUgb2YgdGhpcyBmaWVsZCdzIGNsYXNzIG9yIHtAY29kZSBudWxsfSBpZiB0aGlzCisgICAgICogICAgICAgICBmaWVsZCdzIHR5cGUgaXMgcHJpbWl0aXZlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZVN0cmluZygpIHsKKyAgICAgICAgaWYgKGlzUHJpbWl0aXZlKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGlmICh0eXBlU3RyaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIENsYXNzPD8+IHQgPSBnZXRUeXBlSW50ZXJuYWwoKTsKKyAgICAgICAgICAgIFN0cmluZyB0eXBlTmFtZSA9IHQuZ2V0TmFtZSgpLnJlcGxhY2UoJy4nLCAnLycpOworICAgICAgICAgICAgU3RyaW5nIHN0ciA9ICh0LmlzQXJyYXkoKSkgPyB0eXBlTmFtZSA6ICgiTCIgKyB0eXBlTmFtZSArICc7Jyk7CisgICAgICAgICAgICB0eXBlU3RyaW5nID0gc3RyLmludGVybigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0eXBlU3RyaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgZmllbGQncyB0eXBlIGlzIGEgcHJpbWl0aXZlIHR5cGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGZpZWxkJ3MgdHlwZSBpcyBwcmltaXRpdmU7IHtAY29kZSBmYWxzZX0gaWYKKyAgICAgKiAgICAgICAgIHRoZSB0eXBlIG9mIHRoaXMgZmllbGQgaXMgYSByZWd1bGFyIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUHJpbWl0aXZlKCkgeworICAgICAgICBDbGFzczw/PiB0ID0gZ2V0VHlwZUludGVybmFsKCk7CisgICAgICAgIHJldHVybiB0ICE9IG51bGwgJiYgdC5pc1ByaW1pdGl2ZSgpOworICAgIH0KKworICAgIGJvb2xlYW4gd3JpdGVGaWVsZChEYXRhT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQ2xhc3M8Pz4gdCA9IGdldFR5cGVJbnRlcm5hbCgpOworICAgICAgICBvdXQud3JpdGVCeXRlKHR5cGVDb2RlT2YodCkpOworICAgICAgICBvdXQud3JpdGVVVEYobmFtZSk7CisgICAgICAgIHJldHVybiAodCAhPSBudWxsICYmIHQuaXNQcmltaXRpdmUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGlzIGZpZWxkJ3Mgb2Zmc2V0IGluIHRoZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWVsZCdzIG5ldyBvZmZzZXQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0T2Zmc2V0KGludCBuZXdWYWx1ZSkgeworICAgICAgICB0aGlzLm9mZnNldCA9IG5ld1ZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIGNvbmNpc2UsIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIG9mIHRoaXMKKyAgICAgKiBmaWVsZCBkZXNjcmlwdG9yLgorICAgICAqCisgICAgICogQHJldHVybiBhIHByaW50YWJsZSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGRlc2NyaXB0b3IuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAnKCcgKyBnZXROYW1lKCkgKyAnOicgKyBnZXRUeXBlSW50ZXJuYWwoKSArICcpJzsKKyAgICB9CisKKyAgICB2b2lkIHJlc29sdmUoQ2xhc3NMb2FkZXIgbG9hZGVyKSB7CisgICAgICAgIGlmICh0eXBlU3RyaW5nID09IG51bGwgJiYgaXNQcmltaXRpdmUoKSkgeworICAgICAgICAgICAgLy8gcHJpbWl0aXZlIHR5cGUgZGVjbGFyZWQgaW4gYSBzZXJpYWxpemFibGUgY2xhc3MKKyAgICAgICAgICAgIHR5cGVTdHJpbmcgPSBTdHJpbmcudmFsdWVPZihnZXRUeXBlQ29kZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh0eXBlU3RyaW5nLmxlbmd0aCgpID09IDEpIHsKKyAgICAgICAgICAgIGlmIChkZWZhdWx0UmVzb2x2ZSgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9IHR5cGVTdHJpbmcucmVwbGFjZSgnLycsICcuJyk7CisgICAgICAgIGlmIChjbGFzc05hbWUuY2hhckF0KDApID09ICdMJykgeworICAgICAgICAgICAgLy8gcmVtb3ZlIEwgYW5kIDsKKyAgICAgICAgICAgIGNsYXNzTmFtZSA9IGNsYXNzTmFtZS5zdWJzdHJpbmcoMSwgY2xhc3NOYW1lLmxlbmd0aCgpIC0gMSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENsYXNzPD8+IGNsID0gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUsIGZhbHNlLCBsb2FkZXIpOworICAgICAgICAgICAgdHlwZSA9IChjbC5nZXRDbGFzc0xvYWRlcigpID09IG51bGwpID8gY2wgOiBuZXcgV2Vha1JlZmVyZW5jZTxDbGFzczw/Pj4oY2wpOworICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIElnbm9yZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgZmllbGQgaXMgdW5zaGFyZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGZpZWxkIGlzIHVuc2hhcmVkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1Vuc2hhcmVkKCkgeworICAgICAgICByZXR1cm4gdW5zaGFyZWQ7CisgICAgfQorCisgICAgdm9pZCBzZXRVbnNoYXJlZChib29sZWFuIHVuc2hhcmVkKSB7CisgICAgICAgIHRoaXMudW5zaGFyZWQgPSB1bnNoYXJlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNvbHZlcyB0eXBlU3RyaW5nIGludG8gdHlwZS4gUmV0dXJucyB0cnVlIGlmIHRoZSB0eXBlIGlzIHByaW1pdGl2ZQorICAgICAqIGFuZCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGRlZmF1bHRSZXNvbHZlKCkgeworICAgICAgICBzd2l0Y2ggKHR5cGVTdHJpbmcuY2hhckF0KDApKSB7CisgICAgICAgIGNhc2UgJ0knOgorICAgICAgICAgICAgdHlwZSA9IGludC5jbGFzczsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlICdCJzoKKyAgICAgICAgICAgIHR5cGUgPSBieXRlLmNsYXNzOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ0MnOgorICAgICAgICAgICAgdHlwZSA9IGNoYXIuY2xhc3M7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSAnUyc6CisgICAgICAgICAgICB0eXBlID0gc2hvcnQuY2xhc3M7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSAnWic6CisgICAgICAgICAgICB0eXBlID0gYm9vbGVhbi5jbGFzczsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlICdKJzoKKyAgICAgICAgICAgIHR5cGUgPSBsb25nLmNsYXNzOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ0YnOgorICAgICAgICAgICAgdHlwZSA9IGZsb2F0LmNsYXNzOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ0QnOgorICAgICAgICAgICAgdHlwZSA9IGRvdWJsZS5jbGFzczsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgdHlwZSA9IE9iamVjdC5jbGFzczsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL09wdGlvbmFsRGF0YUV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vT3B0aW9uYWxEYXRhRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjkyZDBiZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL09wdGlvbmFsRGF0YUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworLyoqCisgKiBTaWduYWxzIHRoYXQgdGhlIHtAbGluayBPYmplY3RJbnB1dFN0cmVhbX0gY2xhc3MgZW5jb3VudGVyZWQgYSBwcmltaXRpdmUgdHlwZQorICogKHtAY29kZSBpbnR9LCB7QGNvZGUgY2hhcn0gZXRjLikgaW5zdGVhZCBvZiBhbiBvYmplY3QgaW5zdGFuY2UgaW4gdGhlIGlucHV0CisgKiBzdHJlYW0uCisgKgorICogQHNlZSBPYmplY3RJbnB1dFN0cmVhbSNhdmFpbGFibGUoKQorICogQHNlZSBPYmplY3RJbnB1dFN0cmVhbSNyZWFkT2JqZWN0KCkKKyAqIEBzZWUgT2JqZWN0SW5wdXRTdHJlYW0jc2tpcEJ5dGVzKGludCkKKyAqLworcHVibGljIGNsYXNzIE9wdGlvbmFsRGF0YUV4Y2VwdGlvbiBleHRlbmRzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODAxMTEyMTg2NTY4MTI1NzgyMEw7CisKKyAgICAvKioKKyAgICAgKiB7QGNvZGUgdHJ1ZX0gaW5kaWNhdGVzIHRoYXQgdGhlcmUgaXMgbm8gbW9yZSBwcmltaXRpdmUgZGF0YSBhdmFpbGFibGUuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZW9mOworCisgICAgLyoqCisgICAgICogVGhlIG51bWJlciBvZiBieXRlcyBvZiBwcmltaXRpdmUgZGF0YSAoaW50LCBjaGFyLCBsb25nIGV0Yy4pIHRoYXQgYXJlCisgICAgICogYXZhaWxhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgbGVuZ3RoOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgT3B0aW9uYWxEYXRhRXhjZXB0aW9ufSB3aXRoIGl0cyBzdGFjayB0cmFjZQorICAgICAqIGZpbGxlZCBpbi4KKyAgICAgKi8KKyAgICBPcHRpb25hbERhdGFFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgT3B0aW9uYWxEYXRhRXhjZXB0aW9ufSB3aXRoIGl0cyBzdGFjayB0cmFjZSBhbmQKKyAgICAgKiBkZXRhaWwgbWVzc2FnZSBmaWxsZWQgaW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBPcHRpb25hbERhdGFFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vT3V0cHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9PdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZWViMDY5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxMjggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogQSB3cml0YWJsZSBzaW5rIGZvciBieXRlcy4KKyAqCisgKiA8cD5Nb3N0IGNsaWVudHMgd2lsbCB1c2Ugb3V0cHV0IHN0cmVhbXMgdGhhdCB3cml0ZSBkYXRhIHRvIHRoZSBmaWxlIHN5c3RlbQorICogKHtAbGluayBGaWxlT3V0cHV0U3RyZWFtfSksIHRoZSBuZXR3b3JrICh7QGxpbmsgamF2YS5uZXQuU29ja2V0I2dldE91dHB1dFN0cmVhbSgpfS97QGxpbmsKKyAqIGphdmEubmV0Lkh0dHBVUkxDb25uZWN0aW9uI2dldE91dHB1dFN0cmVhbSgpfSksIG9yIHRvIGFuIGluLW1lbW9yeSBieXRlIGFycmF5CisgKiAoe0BsaW5rIEJ5dGVBcnJheU91dHB1dFN0cmVhbX0pLgorICoKKyAqIDxwPlVzZSB7QGxpbmsgT3V0cHV0U3RyZWFtV3JpdGVyfSB0byBhZGFwdCBhIGJ5dGUgc3RyZWFtIGxpa2UgdGhpcyBvbmUgaW50byBhCisgKiBjaGFyYWN0ZXIgc3RyZWFtLgorICoKKyAqIDxwPk1vc3QgY2xpZW50cyBzaG91bGQgd3JhcCB0aGVpciBvdXRwdXQgc3RyZWFtIHdpdGgge0BsaW5rCisgKiBCdWZmZXJlZE91dHB1dFN0cmVhbX0uIENhbGxlcnMgdGhhdCBkbyBvbmx5IGJ1bGsgd3JpdGVzIG1heSBvbWl0IGJ1ZmZlcmluZy4KKyAqCisgKiA8aDM+U3ViY2xhc3NpbmcgT3V0cHV0U3RyZWFtPC9oMz4KKyAqIFN1YmNsYXNzZXMgdGhhdCBkZWNvcmF0ZSBhbm90aGVyIG91dHB1dCBzdHJlYW0gc2hvdWxkIGNvbnNpZGVyIHN1YmNsYXNzaW5nCisgKiB7QGxpbmsgRmlsdGVyT3V0cHV0U3RyZWFtfSwgd2hpY2ggZGVsZWdhdGVzIGFsbCBjYWxscyB0byB0aGUgdGFyZ2V0IG91dHB1dAorICogc3RyZWFtLgorICoKKyAqIDxwPkFsbCBvdXRwdXQgc3RyZWFtIHN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlIDxzdHJvbmc+Ym90aDwvc3Ryb25nPiB7QGxpbmsKKyAqICN3cml0ZShpbnQpfSBhbmQge0BsaW5rICN3cml0ZShieXRlW10saW50LGludCkgd3JpdGUoYnl0ZVtdLGludCxpbnQpfS4gVGhlCisgKiB0aHJlZSBhcmd1bWVudCBvdmVybG9hZCBpcyBuZWNlc3NhcnkgZm9yIGJ1bGsgYWNjZXNzIHRvIHRoZSBkYXRhLiBUaGlzIGlzCisgKiBtdWNoIG1vcmUgZWZmaWNpZW50IHRoYW4gYnl0ZS1ieS1ieXRlIGFjY2Vzcy4KKyAqCisgKiBAc2VlIElucHV0U3RyZWFtCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBPdXRwdXRTdHJlYW0gaW1wbGVtZW50cyBDbG9zZWFibGUsIEZsdXNoYWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgc3RyZWFtLiBJbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBtZXRob2Qgc2hvdWxkIGZyZWUgYW55CisgICAgICogcmVzb3VyY2VzIHVzZWQgYnkgdGhlIHN0cmVhbS4gVGhpcyBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdGhpbmcuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNsb3NpbmcgdGhpcyBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvKiBlbXB0eSAqLworICAgIH0KKworICAgIC8qKgorICAgICAqIEZsdXNoZXMgdGhpcyBzdHJlYW0uIEltcGxlbWVudGF0aW9ucyBvZiB0aGlzIG1ldGhvZCBzaG91bGQgZW5zdXJlIHRoYXQKKyAgICAgKiBhbnkgYnVmZmVyZWQgZGF0YSBpcyB3cml0dGVuIG91dC4gVGhpcyBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdGhpbmcuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGZsdXNoaW5nIHRoaXMgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLyogZW1wdHkgKi8KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVpdmFsZW50IHRvIHtAY29kZSB3cml0ZShidWZmZXIsIDAsIGJ1ZmZlci5sZW5ndGgpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYnVmZmVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3cml0ZShidWZmZXIsIDAsIGJ1ZmZlci5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB7QGNvZGUgY291bnR9IGJ5dGVzIGZyb20gdGhlIGJ5dGUgYXJyYXkge0Bjb2RlIGJ1ZmZlcn0gc3RhcnRpbmcgYXQKKyAgICAgKiBwb3NpdGlvbiB7QGNvZGUgb2Zmc2V0fSB0byB0aGlzIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXIgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgcG9zaXRpb24gaW4ge0Bjb2RlIGJ1ZmZlcn0gZnJvbSB3aGVyZSB0byBnZXQgYnl0ZXMuCisgICAgICogQHBhcmFtIGNvdW50CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIGZyb20ge0Bjb2RlIGJ1ZmZlcn0gdG8gd3JpdGUgdG8gdGhpcworICAgICAqICAgICAgICAgICAgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0byB0aGlzIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGNvdW50IDwgMH0sIG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIG9mZnNldCArIGNvdW50fSBpcyBiaWdnZXIgdGhhbiB0aGUgbGVuZ3RoIG9mCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGJ1ZmZlcn0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXIubGVuZ3RoLCBvZmZzZXQsIGNvdW50KTsKKyAgICAgICAgZm9yIChpbnQgaSA9IG9mZnNldDsgaSA8IG9mZnNldCArIGNvdW50OyBpKyspIHsKKyAgICAgICAgICAgIHdyaXRlKGJ1ZmZlcltpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBzaW5nbGUgYnl0ZSB0byB0aGlzIHN0cmVhbS4gT25seSB0aGUgbGVhc3Qgc2lnbmlmaWNhbnQgYnl0ZSBvZgorICAgICAqIHRoZSBpbnRlZ2VyIHtAY29kZSBvbmVCeXRlfSBpcyB3cml0dGVuIHRvIHRoZSBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb25lQnl0ZQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhpcyBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgd3JpdGUoaW50IG9uZUJ5dGUpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHdyaXRlciBoYXMgZW5jb3VudGVyZWQgYW5kIHN1cHByZXNzZWQgYW4gZXJyb3IuIFVzZWQKKyAgICAgKiBieSBQcmludFN0cmVhbXMgYXMgYW4gYWx0ZXJuYXRpdmUgdG8gY2hlY2tlZCBleGNlcHRpb25zLgorICAgICAqLworICAgIGJvb2xlYW4gY2hlY2tFcnJvcigpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL091dHB1dFN0cmVhbVdyaXRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vT3V0cHV0U3RyZWFtV3JpdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODZiNjJmYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL091dHB1dFN0cmVhbVdyaXRlci5qYXZhCkBAIC0wLDAgKzEsMzMxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLkNoYXJCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldEVuY29kZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5Db2RlclJlc3VsdDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNvZGluZ0Vycm9yQWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogQSBjbGFzcyBmb3IgdHVybmluZyBhIGNoYXJhY3RlciBzdHJlYW0gaW50byBhIGJ5dGUgc3RyZWFtLiBEYXRhIHdyaXR0ZW4gdG8KKyAqIHRoZSB0YXJnZXQgaW5wdXQgc3RyZWFtIGlzIGNvbnZlcnRlZCBpbnRvIGJ5dGVzIGJ5IGVpdGhlciBhIGRlZmF1bHQgb3IgYQorICogcHJvdmlkZWQgY2hhcmFjdGVyIGNvbnZlcnRlci4gVGhlIGRlZmF1bHQgZW5jb2RpbmcgaXMgdGFrZW4gZnJvbSB0aGUKKyAqICJmaWxlLmVuY29kaW5nIiBzeXN0ZW0gcHJvcGVydHkuIHtAY29kZSBPdXRwdXRTdHJlYW1Xcml0ZXJ9IGNvbnRhaW5zIGEgYnVmZmVyCisgKiBvZiBieXRlcyB0byBiZSB3cml0dGVuIHRvIHRhcmdldCBzdHJlYW0gYW5kIGNvbnZlcnRzIHRoZXNlIGludG8gY2hhcmFjdGVycyBhcworICogbmVlZGVkLiBUaGUgYnVmZmVyIHNpemUgaXMgOEsuCisgKgorICogQHNlZSBJbnB1dFN0cmVhbVJlYWRlcgorICovCitwdWJsaWMgY2xhc3MgT3V0cHV0U3RyZWFtV3JpdGVyIGV4dGVuZHMgV3JpdGVyIHsKKworICAgIHByaXZhdGUgZmluYWwgT3V0cHV0U3RyZWFtIG91dDsKKworICAgIHByaXZhdGUgQ2hhcnNldEVuY29kZXIgZW5jb2RlcjsKKworICAgIHByaXZhdGUgQnl0ZUJ1ZmZlciBieXRlcyA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoODE5Mik7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IE91dHB1dFN0cmVhbVdyaXRlciB1c2luZyB7QGNvZGUgb3V0fSBhcyB0aGUgdGFyZ2V0CisgICAgICogc3RyZWFtIHRvIHdyaXRlIGNvbnZlcnRlZCBjaGFyYWN0ZXJzIHRvLiBUaGUgZGVmYXVsdCBjaGFyYWN0ZXIgZW5jb2RpbmcKKyAgICAgKiBpcyB1c2VkLgorICAgICAqCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgdGhlIG5vbi1udWxsIHRhcmdldCBzdHJlYW0gdG8gd3JpdGUgY29udmVydGVkIGJ5dGVzIHRvLgorICAgICAqLworICAgIHB1YmxpYyBPdXRwdXRTdHJlYW1Xcml0ZXIoT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgICB0aGlzKG91dCwgQ2hhcnNldC5kZWZhdWx0Q2hhcnNldCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IE91dHB1dFN0cmVhbVdyaXRlciB1c2luZyB7QGNvZGUgb3V0fSBhcyB0aGUgdGFyZ2V0CisgICAgICogc3RyZWFtIHRvIHdyaXRlIGNvbnZlcnRlZCBjaGFyYWN0ZXJzIHRvIGFuZCB7QGNvZGUgZW5jfSBhcyB0aGUgY2hhcmFjdGVyCisgICAgICogZW5jb2RpbmcuIElmIHRoZSBlbmNvZGluZyBjYW5ub3QgYmUgZm91bmQsIGFuCisgICAgICogVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlcnJvciBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IHN0cmVhbSB0byB3cml0ZSBjb252ZXJ0ZWQgYnl0ZXMgdG8uCisgICAgICogQHBhcmFtIGVuYworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyBkZXNjcmliaW5nIHRoZSBkZXNpcmVkIGNoYXJhY3RlciBlbmNvZGluZy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGVuY30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmNvZGluZyBzcGVjaWZpZWQgYnkge0Bjb2RlIGVuY30gY2Fubm90IGJlIGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBPdXRwdXRTdHJlYW1Xcml0ZXIoT3V0cHV0U3RyZWFtIG91dCwgZmluYWwgU3RyaW5nIGVuYykKKyAgICAgICAgICAgIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIob3V0KTsKKyAgICAgICAgaWYgKGVuYyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLm91dCA9IG91dDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVuY29kZXIgPSBDaGFyc2V0LmZvck5hbWUoZW5jKS5uZXdFbmNvZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbihlbmMpOworICAgICAgICB9CisgICAgICAgIGVuY29kZXIub25NYWxmb3JtZWRJbnB1dChDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFKTsKKyAgICAgICAgZW5jb2Rlci5vblVubWFwcGFibGVDaGFyYWN0ZXIoQ29kaW5nRXJyb3JBY3Rpb24uUkVQTEFDRSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIgdXNpbmcge0Bjb2RlIG91dH0gYXMgdGhlIHRhcmdldAorICAgICAqIHN0cmVhbSB0byB3cml0ZSBjb252ZXJ0ZWQgY2hhcmFjdGVycyB0byBhbmQge0Bjb2RlIGNzfSBhcyB0aGUgY2hhcmFjdGVyCisgICAgICogZW5jb2RpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IHN0cmVhbSB0byB3cml0ZSBjb252ZXJ0ZWQgYnl0ZXMgdG8uCisgICAgICogQHBhcmFtIGNzCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIENoYXJzZXR9IHRoYXQgc3BlY2lmaWVzIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcuCisgICAgICovCisgICAgcHVibGljIE91dHB1dFN0cmVhbVdyaXRlcihPdXRwdXRTdHJlYW0gb3V0LCBDaGFyc2V0IGNzKSB7CisgICAgICAgIHN1cGVyKG91dCk7CisgICAgICAgIHRoaXMub3V0ID0gb3V0OworICAgICAgICBlbmNvZGVyID0gY3MubmV3RW5jb2RlcigpOworICAgICAgICBlbmNvZGVyLm9uTWFsZm9ybWVkSW5wdXQoQ29kaW5nRXJyb3JBY3Rpb24uUkVQTEFDRSk7CisgICAgICAgIGVuY29kZXIub25Vbm1hcHBhYmxlQ2hhcmFjdGVyKENvZGluZ0Vycm9yQWN0aW9uLlJFUExBQ0UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyIHVzaW5nIHtAY29kZSBvdXR9IGFzIHRoZSB0YXJnZXQKKyAgICAgKiBzdHJlYW0gdG8gd3JpdGUgY29udmVydGVkIGNoYXJhY3RlcnMgdG8gYW5kIHtAY29kZSBlbmN9IGFzIHRoZSBjaGFyYWN0ZXIKKyAgICAgKiBlbmNvZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBzdHJlYW0gdG8gd3JpdGUgY29udmVydGVkIGJ5dGVzIHRvLgorICAgICAqIEBwYXJhbSBlbmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgZW5jb2RlciB1c2VkIGZvciBjaGFyYWN0ZXIgY29udmVyc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgT3V0cHV0U3RyZWFtV3JpdGVyKE91dHB1dFN0cmVhbSBvdXQsIENoYXJzZXRFbmNvZGVyIGVuYykgeworICAgICAgICBzdXBlcihvdXQpOworICAgICAgICBlbmMuY2hhcnNldCgpOworICAgICAgICB0aGlzLm91dCA9IG91dDsKKyAgICAgICAgZW5jb2RlciA9IGVuYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhpcyB3cml0ZXIuIFRoaXMgaW1wbGVtZW50YXRpb24gZmx1c2hlcyB0aGUgYnVmZmVyIGFzIHdlbGwgYXMgdGhlCisgICAgICogdGFyZ2V0IHN0cmVhbS4gVGhlIHRhcmdldCBzdHJlYW0gaXMgdGhlbiBjbG9zZWQgYW5kIHRoZSByZXNvdXJjZXMgZm9yIHRoZQorICAgICAqIGJ1ZmZlciBhbmQgY29udmVydGVyIGFyZSByZWxlYXNlZC4KKyAgICAgKgorICAgICAqIDxwPk9ubHkgdGhlIGZpcnN0IGludm9jYXRpb24gb2YgdGhpcyBtZXRob2QgaGFzIGFueSBlZmZlY3QuIFN1YnNlcXVlbnQgY2FsbHMKKyAgICAgKiBkbyBub3RoaW5nLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjbG9zaW5nIHRoaXMgd3JpdGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBpZiAoZW5jb2RlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZHJhaW5FbmNvZGVyKCk7CisgICAgICAgICAgICAgICAgZmx1c2hCeXRlcyhmYWxzZSk7CisgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgZW5jb2RlciA9IG51bGw7CisgICAgICAgICAgICAgICAgYnl0ZXMgPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmx1c2hlcyB0aGlzIHdyaXRlci4gVGhpcyBpbXBsZW1lbnRhdGlvbiBlbnN1cmVzIHRoYXQgYWxsIGJ1ZmZlcmVkIGJ5dGVzCisgICAgICogYXJlIHdyaXR0ZW4gdG8gdGhlIHRhcmdldCBzdHJlYW0uIEFmdGVyIHdyaXRpbmcgdGhlIGJ5dGVzLCB0aGUgdGFyZ2V0CisgICAgICogc3RyZWFtIGlzIGZsdXNoZWQgYXMgd2VsbC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgZmx1c2hpbmcgdGhpcyB3cml0ZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmbHVzaEJ5dGVzKHRydWUpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBmbHVzaEJ5dGVzKGJvb2xlYW4gZmx1c2hVbmRlcmx5aW5nU3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGNoZWNrU3RhdHVzKCk7CisgICAgICAgICAgICBpbnQgcG9zaXRpb24gPSBieXRlcy5wb3NpdGlvbigpOworICAgICAgICAgICAgaWYgKHBvc2l0aW9uID4gMCkgeworICAgICAgICAgICAgICAgIGJ5dGVzLmZsaXAoKTsKKyAgICAgICAgICAgICAgICBvdXQud3JpdGUoYnl0ZXMuYXJyYXkoKSwgYnl0ZXMuYXJyYXlPZmZzZXQoKSwgcG9zaXRpb24pOworICAgICAgICAgICAgICAgIGJ5dGVzLmNsZWFyKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZmx1c2hVbmRlcmx5aW5nU3RyZWFtKSB7CisgICAgICAgICAgICAgICAgb3V0LmZsdXNoKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY29udmVydChDaGFyQnVmZmVyIGNoYXJzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgQ29kZXJSZXN1bHQgcmVzdWx0ID0gZW5jb2Rlci5lbmNvZGUoY2hhcnMsIGJ5dGVzLCBmYWxzZSk7CisgICAgICAgICAgICBpZiAocmVzdWx0LmlzT3ZlcmZsb3coKSkgeworICAgICAgICAgICAgICAgIC8vIE1ha2Ugcm9vbSBhbmQgdHJ5IGFnYWluLgorICAgICAgICAgICAgICAgIGZsdXNoQnl0ZXMoZmFsc2UpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQuaXNFcnJvcigpKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LnRocm93RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBkcmFpbkVuY29kZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBTdHJpY3RseSBzcGVha2luZywgSSB0aGluayBpdCdzIHBhcnQgb2YgdGhlIENoYXJzZXRFbmNvZGVyIGNvbnRyYWN0IHRoYXQgeW91IGNhbGwKKyAgICAgICAgLy8gZW5jb2RlIHdpdGggZW5kT2ZJbnB1dCB0cnVlIGJlZm9yZSBmbHVzaGluZy4gT3VyIElDVS1iYXNlZCBpbXBsZW1lbnRhdGlvbnMgZG9uJ3QKKyAgICAgICAgLy8gYWN0dWFsbHkgbmVlZCB0aGlzLCBhbmQgeW91J2QgaG9wZSB0aGF0IGFueSByZWFzb25hYmxlIGltcGxlbWVudGF0aW9uIHdvdWxkbid0IGVpdGhlci4KKyAgICAgICAgLy8gQ2hhcnNldEVuY29kZXIuZW5jb2RlIGRvZXNuJ3QgYWN0dWFsbHkgcGFzcyB0aGUgYm9vbGVhbiB0aHJvdWdoIHRvIGVuY29kZUxvb3AgYW55d2F5IQorICAgICAgICBDaGFyQnVmZmVyIGNoYXJzID0gQ2hhckJ1ZmZlci5hbGxvY2F0ZSgwKTsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIENvZGVyUmVzdWx0IHJlc3VsdCA9IGVuY29kZXIuZW5jb2RlKGNoYXJzLCBieXRlcywgdHJ1ZSk7CisgICAgICAgICAgICBpZiAocmVzdWx0LmlzRXJyb3IoKSkgeworICAgICAgICAgICAgICAgIHJlc3VsdC50aHJvd0V4Y2VwdGlvbigpOworICAgICAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQuaXNPdmVyZmxvdygpKSB7CisgICAgICAgICAgICAgICAgZmx1c2hCeXRlcyhmYWxzZSk7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFNvbWUgZW5jb2RlcnMgKHN1Y2ggYXMgSVNPLTIwMjItSlApIGhhdmUgc3R1ZmYgdG8gd3JpdGUgb3V0IGFmdGVyIGFsbCB0aGUKKyAgICAgICAgLy8gY2hhcmFjdGVycyAoc3VjaCBhcyBzaGlmdGluZyBiYWNrIGludG8gYSBkZWZhdWx0IHN0YXRlKS4gSW4gb3VyIGltcGxlbWVudGF0aW9uLAorICAgICAgICAvLyB0aGlzIGlzIGFjdHVhbGx5IHRoZSBmaXJzdCB0aW1lIElDVSBpcyB0b2xkIHRoYXQgd2UndmUgcnVuIG91dCBvZiBpbnB1dC4KKyAgICAgICAgQ29kZXJSZXN1bHQgcmVzdWx0ID0gZW5jb2Rlci5mbHVzaChieXRlcyk7CisgICAgICAgIHdoaWxlICghcmVzdWx0LmlzVW5kZXJmbG93KCkpIHsKKyAgICAgICAgICAgIGlmIChyZXN1bHQuaXNPdmVyZmxvdygpKSB7CisgICAgICAgICAgICAgICAgZmx1c2hCeXRlcyhmYWxzZSk7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gZW5jb2Rlci5mbHVzaChieXRlcyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJlc3VsdC50aHJvd0V4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrU3RhdHVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGVuY29kZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJPdXRwdXRTdHJlYW1Xcml0ZXIgaXMgY2xvc2VkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBoaXN0b3JpY2FsIG5hbWUgb2YgdGhlIGVuY29kaW5nIHVzZWQgYnkgdGhpcyB3cml0ZXIgdG8gY29udmVydCBjaGFyYWN0ZXJzIHRvCisgICAgICogYnl0ZXMsIG9yIG51bGwgaWYgdGhpcyB3cml0ZXIgaGFzIGJlZW4gY2xvc2VkLiBNb3N0IGNhbGxlcnMgc2hvdWxkIHByb2JhYmx5IGtlZXAKKyAgICAgKiB0cmFjayBvZiB0aGUgU3RyaW5nIG9yIENoYXJzZXQgdGhleSBwYXNzZWQgaW47IHRoaXMgbWV0aG9kIG1heSBub3QgcmV0dXJuIHRoZSBzYW1lCisgICAgICogbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCkgeworICAgICAgICBpZiAoZW5jb2RlciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gSGlzdG9yaWNhbENoYXJzZXROYW1lcy5nZXQoZW5jb2Rlci5jaGFyc2V0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB7QGNvZGUgY291bnR9IGNoYXJhY3RlcnMgc3RhcnRpbmcgYXQge0Bjb2RlIG9mZnNldH0gaW4ge0Bjb2RlIGJ1Zn0KKyAgICAgKiB0byB0aGlzIHdyaXRlci4gVGhlIGNoYXJhY3RlcnMgYXJlIGltbWVkaWF0ZWx5IGNvbnZlcnRlZCB0byBieXRlcyBieSB0aGUKKyAgICAgKiBjaGFyYWN0ZXIgY29udmVydGVyIGFuZCBzdG9yZWQgaW4gYSBsb2NhbCBidWZmZXIuIElmIHRoZSBidWZmZXIgZ2V0cyBmdWxsCisgICAgICogYXMgYSByZXN1bHQgb2YgdGhlIGNvbnZlcnNpb24sIHRoaXMgd3JpdGVyIGlzIGZsdXNoZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgY29udGFpbmluZyBjaGFyYWN0ZXJzIHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHtAY29kZSBidWZ9IHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBjb3VudCA8IDB9LCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBjb3VudH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBzaXplIG9mCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGJ1Zn0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgd3JpdGVyIGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkIG9yIGFub3RoZXIgSS9PIGVycm9yCisgICAgICogICAgICAgICAgICAgb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGNoYXJbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBjaGVja1N0YXR1cygpOworICAgICAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgICAgICBDaGFyQnVmZmVyIGNoYXJzID0gQ2hhckJ1ZmZlci53cmFwKGJ1ZmZlciwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgICAgICBjb252ZXJ0KGNoYXJzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgY2hhcmFjdGVyIHtAY29kZSBvbmVDaGFyfSB0byB0aGlzIHdyaXRlci4gVGhlIGxvd2VzdCB0d28gYnl0ZXMKKyAgICAgKiBvZiB0aGUgaW50ZWdlciB7QGNvZGUgb25lQ2hhcn0gYXJlIGltbWVkaWF0ZWx5IGNvbnZlcnRlZCB0byBieXRlcyBieSB0aGUKKyAgICAgKiBjaGFyYWN0ZXIgY29udmVydGVyIGFuZCBzdG9yZWQgaW4gYSBsb2NhbCBidWZmZXIuIElmIHRoZSBidWZmZXIgZ2V0cyBmdWxsCisgICAgICogYnkgY29udmVydGluZyB0aGlzIGNoYXJhY3RlciwgdGhpcyB3cml0ZXIgaXMgZmx1c2hlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvbmVDaGFyCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHdyaXRlciBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBvbmVDaGFyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGNoZWNrU3RhdHVzKCk7CisgICAgICAgICAgICBDaGFyQnVmZmVyIGNoYXJzID0gQ2hhckJ1ZmZlci53cmFwKG5ldyBjaGFyW10geyAoY2hhcikgb25lQ2hhciB9KTsKKyAgICAgICAgICAgIGNvbnZlcnQoY2hhcnMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHtAY29kZSBjb3VudH0gY2hhcmFjdGVycyBzdGFydGluZyBhdCB7QGNvZGUgb2Zmc2V0fSBpbiB7QGNvZGUgc3RyfQorICAgICAqIHRvIHRoaXMgd3JpdGVyLiBUaGUgY2hhcmFjdGVycyBhcmUgaW1tZWRpYXRlbHkgY29udmVydGVkIHRvIGJ5dGVzIGJ5IHRoZQorICAgICAqIGNoYXJhY3RlciBjb252ZXJ0ZXIgYW5kIHN0b3JlZCBpbiBhIGxvY2FsIGJ1ZmZlci4gSWYgdGhlIGJ1ZmZlciBnZXRzIGZ1bGwKKyAgICAgKiBhcyBhIHJlc3VsdCBvZiB0aGUgY29udmVyc2lvbiwgdGhpcyB3cml0ZXIgaXMgZmx1c2hlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgY29udGFpbmluZyBjaGFyYWN0ZXJzIHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBwb3NpdGlvbiBpbiB7QGNvZGUgc3RyfSBmb3IgcmV0cmlldmluZyBjaGFyYWN0ZXJzLgorICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgd3JpdGVyIGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkIG9yIGFub3RoZXIgSS9PIGVycm9yCisgICAgICogICAgICAgICAgICAgb2NjdXJzLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwfSBvciB7QGNvZGUgY291bnQgPCAwfSwgb3IgaWYKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgb2Zmc2V0ICsgY291bnR9IGlzIGJpZ2dlciB0aGFuIHRoZSBsZW5ndGggb2YKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgc3RyfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShTdHJpbmcgc3RyLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgaWYgKGNvdW50IDwgMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKHN0ciwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc3RyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInN0ciA9PSBudWxsIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoKG9mZnNldCB8IGNvdW50KSA8IDAgfHwgb2Zmc2V0ID4gc3RyLmxlbmd0aCgpIC0gY291bnQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihzdHIsIG9mZnNldCwgY291bnQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2hlY2tTdGF0dXMoKTsKKyAgICAgICAgICAgIENoYXJCdWZmZXIgY2hhcnMgPSBDaGFyQnVmZmVyLndyYXAoc3RyLCBvZmZzZXQsIGNvdW50ICsgb2Zmc2V0KTsKKyAgICAgICAgICAgIGNvbnZlcnQoY2hhcnMpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIGJvb2xlYW4gY2hlY2tFcnJvcigpIHsKKyAgICAgICAgcmV0dXJuIG91dC5jaGVja0Vycm9yKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vUGlwZWRJbnB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vUGlwZWRJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFhNzdlNmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9QaXBlZElucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw0MTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogUmVjZWl2ZXMgaW5mb3JtYXRpb24gZnJvbSBhIGNvbW11bmljYXRpb25zIHBpcGUuIFdoZW4gdHdvIHRocmVhZHMgd2FudCB0bworICogcGFzcyBkYXRhIGJhY2sgYW5kIGZvcnRoLCBvbmUgY3JlYXRlcyBhIHBpcGVkIG91dHB1dCBzdHJlYW0gYW5kIHRoZSBvdGhlciBvbmUKKyAqIGNyZWF0ZXMgYSBwaXBlZCBpbnB1dCBzdHJlYW0uCisgKgorICogQHNlZSBQaXBlZE91dHB1dFN0cmVhbQorICovCitwdWJsaWMgY2xhc3MgUGlwZWRJbnB1dFN0cmVhbSBleHRlbmRzIElucHV0U3RyZWFtIHsKKworICAgIHByaXZhdGUgVGhyZWFkIGxhc3RSZWFkZXI7CisKKyAgICBwcml2YXRlIFRocmVhZCBsYXN0V3JpdGVyOworCisgICAgcHJpdmF0ZSBib29sZWFuIGlzQ2xvc2VkOworCisgICAgLyoqCisgICAgICogVGhlIGNpcmN1bGFyIGJ1ZmZlciB0aHJvdWdoIHdoaWNoIGRhdGEgaXMgcGFzc2VkLiBEYXRhIGlzIHJlYWQgZnJvbSB0aGUKKyAgICAgKiByYW5nZSB7QGNvZGUgW291dCwgaW4pfSBhbmQgd3JpdHRlbiB0byB0aGUgcmFuZ2Uge0Bjb2RlIFtpbiwgb3V0KX0uCisgICAgICogRGF0YSBpbiB0aGUgYnVmZmVyIGlzIGVpdGhlciBzZXF1ZW50aWFsOiA8cHJlPgorICAgICAqICAgICB7IC0gLSAtIFggWCBYIFggWCBYIFggLSAtIC0gLSAtIH0KKyAgICAgKiAgICAgICAgICAgICBeICAgICAgICAgICAgIF4KKyAgICAgKiAgICAgICAgICAgICB8ICAgICAgICAgICAgIHwKKyAgICAgKiAgICAgICAgICAgIG91dCAgICAgICAgICAgaW48L3ByZT4KKyAgICAgKiAuLi5vciB3cmFwcGVkIGFyb3VuZCB0aGUgYnVmZmVyJ3MgZW5kOiA8cHJlPgorICAgICAqICAgICB7IFggWCBYIFggLSAtIC0gLSAtIC0gLSAtIFggWCBYIH0KKyAgICAgKiAgICAgICAgICAgICAgIF4gICAgICAgICAgICAgICBeCisgICAgICogICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgfAorICAgICAqICAgICAgICAgICAgICBpbiAgICAgICAgICAgICAgb3V0PC9wcmU+CisgICAgICogV2hlbiB0aGUgYnVmZmVyIGlzIGVtcHR5LCB7QGNvZGUgaW4gPT0gLTF9LiBSZWFkaW5nIHdoZW4gdGhlIGJ1ZmZlciBpcworICAgICAqIGVtcHR5IHdpbGwgYmxvY2sgdW50aWwgZGF0YSBpcyBhdmFpbGFibGUuIFdoZW4gdGhlIGJ1ZmZlciBpcyBmdWxsLAorICAgICAqIHtAY29kZSBpbiA9PSBvdXR9LiBXcml0aW5nIHdoZW4gdGhlIGJ1ZmZlciBpcyBmdWxsIHdpbGwgYmxvY2sgdW50aWwgZnJlZQorICAgICAqIHNwYWNlIGlzIGF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIGJ1ZmZlcjsKKworICAgIC8qKgorICAgICAqIFRoZSBpbmRleCBpbiB7QGNvZGUgYnVmZmVyfSB3aGVyZSB0aGUgbmV4dCBieXRlIHdpbGwgYmUgd3JpdHRlbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGluID0gLTE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW5kZXggaW4ge0Bjb2RlIGJ1ZmZlcn0gd2hlcmUgdGhlIG5leHQgYnl0ZSB3aWxsIGJlIHJlYWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBvdXQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc2l6ZSBvZiB0aGUgZGVmYXVsdCBwaXBlIGluIGJ5dGVzLgorICAgICAqLworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFBJUEVfU0laRSA9IDEwMjQ7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgaWYgdGhpcyBwaXBlIGlzIGNvbm5lY3RlZC4KKyAgICAgKi8KKyAgICBib29sZWFuIGlzQ29ubmVjdGVkOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB1bmNvbm5lY3RlZCB7QGNvZGUgUGlwZWRJbnB1dFN0cmVhbX0uIFRoZSByZXN1bHRpbmcKKyAgICAgKiBzdHJlYW0gbXVzdCBiZSBjb25uZWN0ZWQgdG8gYSB7QGxpbmsgUGlwZWRPdXRwdXRTdHJlYW19IGJlZm9yZSBkYXRhIG1heQorICAgICAqIGJlIHJlYWQgZnJvbSBpdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGlwZWRJbnB1dFN0cmVhbSgpIHt9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBQaXBlZElucHV0U3RyZWFtfSBjb25uZWN0ZWQgdG8gdGhlCisgICAgICoge0BsaW5rIFBpcGVkT3V0cHV0U3RyZWFtfSB7QGNvZGUgb3V0fS4gQW55IGRhdGEgd3JpdHRlbiB0byB0aGUgb3V0cHV0CisgICAgICogc3RyZWFtIGNhbiBiZSByZWFkIGZyb20gdGhlIHRoaXMgaW5wdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgdGhlIHBpcGVkIG91dHB1dCBzdHJlYW0gdG8gY29ubmVjdCB0by4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBzdHJlYW0gb3Ige0Bjb2RlIG91dH0gYXJlIGFscmVhZHkgY29ubmVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyBQaXBlZElucHV0U3RyZWFtKFBpcGVkT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY29ubmVjdChvdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgdW5jb25uZWN0ZWQge0Bjb2RlIFBpcGVkSW5wdXRTdHJlYW19IHdpdGggdGhlIGdpdmVuCisgICAgICogYnVmZmVyIHNpemUuIFRoZSByZXN1bHRpbmcgc3RyZWFtIG11c3QgYmUgY29ubmVjdGVkIHRvIGEKKyAgICAgKiB7QGNvZGUgUGlwZWRPdXRwdXRTdHJlYW19IGJlZm9yZSBkYXRhIG1heSBiZSByZWFkIGZyb20gaXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGlwZVNpemUgdGhlIHNpemUgb2YgdGhlIGJ1ZmZlciBpbiBieXRlcy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBwaXBlU2l6ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gemVyby4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIFBpcGVkSW5wdXRTdHJlYW0oaW50IHBpcGVTaXplKSB7CisgICAgICAgIGlmIChwaXBlU2l6ZSA8PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJwaXBlIHNpemUgIiArIHBpcGVTaXplICsgIiB0b28gc21hbGwiKTsKKyAgICAgICAgfQorICAgICAgICBidWZmZXIgPSBuZXcgYnl0ZVtwaXBlU2l6ZV07CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUGlwZWRJbnB1dFN0cmVhbX0gY29ubmVjdGVkIHRvIHRoZSBnaXZlbiB7QGNvZGUgUGlwZWRPdXRwdXRTdHJlYW19LAorICAgICAqIHdpdGggdGhlIGdpdmVuIGJ1ZmZlciBzaXplLiBBbnkgZGF0YSB3cml0dGVuIHRvIHRoZSBvdXRwdXQgc3RyZWFtIGNhbiBiZSByZWFkIGZyb20gdGhpcworICAgICAqIGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQgdGhlIHtAY29kZSBQaXBlZE91dHB1dFN0cmVhbX0gdG8gY29ubmVjdCB0by4KKyAgICAgKiBAcGFyYW0gcGlwZVNpemUgdGhlIHNpemUgb2YgdGhlIGJ1ZmZlciBpbiBieXRlcy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgcGlwZVNpemUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8uCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBQaXBlZElucHV0U3RyZWFtKFBpcGVkT3V0cHV0U3RyZWFtIG91dCwgaW50IHBpcGVTaXplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKHBpcGVTaXplKTsKKyAgICAgICAgY29ubmVjdChvdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIDxwPlVubGlrZSBtb3N0IHN0cmVhbXMsIHtAY29kZSBQaXBlZElucHV0U3RyZWFtfSByZXR1cm5zIDAgcmF0aGVyIHRoYW4gdGhyb3dpbmcKKyAgICAgKiB7QGNvZGUgSU9FeGNlcHRpb259IGlmIHRoZSBzdHJlYW0gaGFzIGJlZW4gY2xvc2VkLiBVbmNvbm5lY3RlZCBhbmQgYnJva2VuIHBpcGVzIGFsc28KKyAgICAgKiByZXR1cm4gMC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3VycworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChidWZmZXIgPT0gbnVsbCB8fCBpbiA9PSAtMSkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGluIDw9IG91dCA/IGJ1ZmZlci5sZW5ndGggLSBvdXQgKyBpbiA6IGluIC0gb3V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGlzIHN0cmVhbS4gVGhpcyBpbXBsZW1lbnRhdGlvbiByZWxlYXNlcyB0aGUgYnVmZmVyIHVzZWQgZm9yIHRoZQorICAgICAqIHBpcGUgYW5kIG5vdGlmaWVzIGFsbCB0aHJlYWRzIHdhaXRpbmcgdG8gcmVhZCBvciB3cml0ZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY2xvc2luZyB0aGlzIHN0cmVhbS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBidWZmZXIgPSBudWxsOworICAgICAgICBub3RpZnlBbGwoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25uZWN0cyB0aGlzIHtAY29kZSBQaXBlZElucHV0U3RyZWFtfSB0byBhIHtAbGluayBQaXBlZE91dHB1dFN0cmVhbX0uCisgICAgICogQW55IGRhdGEgd3JpdHRlbiB0byB0aGUgb3V0cHV0IHN0cmVhbSBiZWNvbWVzIHJlYWRhYmxlIGluIHRoaXMgaW5wdXQKKyAgICAgKiBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIG91dHB1dCBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVpdGhlciBzdHJlYW0gaXMgYWxyZWFkeSBjb25uZWN0ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY29ubmVjdChQaXBlZE91dHB1dFN0cmVhbSBzcmMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHNyYy5jb25uZWN0KHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVzdGFibGlzaGVzIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBQaXBlZE91dHB1dFN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiB0aGlzIFJlYWRlciBpcyBhbHJlYWR5IGNvbm5lY3RlZC4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgdm9pZCBlc3RhYmxpc2hDb25uZWN0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzQ29ubmVjdGVkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlBpcGUgYWxyZWFkeSBjb25uZWN0ZWQiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYnVmZmVyID09IG51bGwpIHsgLy8gV2UgbWF5IGFscmVhZHkgaGF2ZSBhbGxvY2F0ZWQgdGhlIGJ1ZmZlci4KKyAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBieXRlW1BpcGVkSW5wdXRTdHJlYW0uUElQRV9TSVpFXTsKKyAgICAgICAgfQorICAgICAgICBpc0Nvbm5lY3RlZCA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBzaW5nbGUgYnl0ZSBmcm9tIHRoaXMgc3RyZWFtIGFuZCByZXR1cm5zIGl0IGFzIGFuIGludGVnZXIgaW4gdGhlCisgICAgICogcmFuZ2UgZnJvbSAwIHRvIDI1NS4gUmV0dXJucyAtMSBpZiB0aGUgZW5kIG9mIHRoaXMgc3RyZWFtIGhhcyBiZWVuCisgICAgICogcmVhY2hlZC4gSWYgdGhlcmUgaXMgbm8gZGF0YSBpbiB0aGUgcGlwZSwgdGhpcyBtZXRob2QgYmxvY2tzIHVudGlsIGRhdGEKKyAgICAgKiBpcyBhdmFpbGFibGUsIHRoZSBlbmQgb2YgdGhlIHN0cmVhbSBpcyBkZXRlY3RlZCBvciBhbiBleGNlcHRpb24gaXMKKyAgICAgKiB0aHJvd24uCisgICAgICogPHA+CisgICAgICogU2VwYXJhdGUgdGhyZWFkcyBzaG91bGQgYmUgdXNlZCB0byByZWFkIGZyb20gYSB7QGNvZGUgUGlwZWRJbnB1dFN0cmVhbX0KKyAgICAgKiBhbmQgdG8gd3JpdGUgdG8gdGhlIGNvbm5lY3RlZCB7QGxpbmsgUGlwZWRPdXRwdXRTdHJlYW19LiBJZiB0aGUgc2FtZQorICAgICAqIHRocmVhZCBpcyB1c2VkLCBhIGRlYWRsb2NrIG1heSBvY2N1ci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZSBzb3VyY2Ugc3RyZWFtIGhhcyBiZWVuCisgICAgICogICAgICAgICByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHN0cmVhbSBpcyBjbG9zZWQgb3Igbm90IGNvbm5lY3RlZCB0byBhbiBvdXRwdXQKKyAgICAgKiAgICAgICAgICAgICBzdHJlYW0sIG9yIGlmIHRoZSB0aHJlYWQgd3JpdGluZyB0byB0aGUgY29ubmVjdGVkIG91dHB1dAorICAgICAqICAgICAgICAgICAgIHN0cmVhbSBpcyBubyBsb25nZXIgYWxpdmUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaXNDb25uZWN0ZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiTm90IGNvbm5lY3RlZCIpOworICAgICAgICB9CisgICAgICAgIGlmIChidWZmZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbnB1dFN0cmVhbSBpcyBjbG9zZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTZXQgdGhlIGxhc3QgdGhyZWFkIHRvIGJlIHJlYWRpbmcgb24gdGhpcyBQaXBlZElucHV0U3RyZWFtLiBJZgorICAgICAgICAgKiBsYXN0UmVhZGVyIGRpZXMgd2hpbGUgc29tZW9uZSBpcyB3YWl0aW5nIHRvIHdyaXRlIGFuIElPRXhjZXB0aW9uIG9mCisgICAgICAgICAqICJQaXBlIGJyb2tlbiIgd2lsbCBiZSB0aHJvd24gaW4gcmVjZWl2ZSgpCisgICAgICAgICAqLworICAgICAgICBsYXN0UmVhZGVyID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBhdHRlbXB0cyA9IDM7CisgICAgICAgICAgICB3aGlsZSAoaW4gPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAvLyBBcmUgd2UgYXQgZW5kIG9mIHN0cmVhbT8KKyAgICAgICAgICAgICAgICBpZiAoaXNDbG9zZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoKGF0dGVtcHRzLS0gPD0gMCkgJiYgbGFzdFdyaXRlciAhPSBudWxsICYmICFsYXN0V3JpdGVyLmlzQWxpdmUoKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlBpcGUgYnJva2VuIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIE5vdGlmeSBjYWxsZXJzIG9mIHJlY2VpdmUoKQorICAgICAgICAgICAgICAgIG5vdGlmeUFsbCgpOworICAgICAgICAgICAgICAgIHdhaXQoMTAwMCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcnJ1cHRlZElPRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgcmVzdWx0ID0gYnVmZmVyW291dCsrXSAmIDB4ZmY7CisgICAgICAgIGlmIChvdXQgPT0gYnVmZmVyLmxlbmd0aCkgeworICAgICAgICAgICAgb3V0ID0gMDsKKyAgICAgICAgfQorICAgICAgICBpZiAob3V0ID09IGluKSB7CisgICAgICAgICAgICAvLyBlbXB0eSBidWZmZXIKKyAgICAgICAgICAgIGluID0gLTE7CisgICAgICAgICAgICBvdXQgPSAwOworICAgICAgICB9CisKKyAgICAgICAgLy8gbGV0IGJsb2NrZWQgd3JpdGVycyB3cml0ZSB0byB0aGUgbmV3bHkgYXZhaWxhYmxlIGJ1ZmZlciBzcGFjZQorICAgICAgICBub3RpZnlBbGwoKTsKKworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGF0IG1vc3Qge0Bjb2RlIGJ5dGVDb3VudH0gYnl0ZXMgZnJvbSB0aGlzIHN0cmVhbSBhbmQgc3RvcmVzIHRoZW0gaW4gdGhlCisgICAgICogYnl0ZSBhcnJheSB7QGNvZGUgYnl0ZXN9IHN0YXJ0aW5nIGF0IHtAY29kZSBvZmZzZXR9LiBCbG9ja3MgdW50aWwgYXQKKyAgICAgKiBsZWFzdCBvbmUgYnl0ZSBoYXMgYmVlbiByZWFkLCB0aGUgZW5kIG9mIHRoZSBzdHJlYW0gaXMgZGV0ZWN0ZWQgb3IgYW4KKyAgICAgKiBleGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIFNlcGFyYXRlIHRocmVhZHMgc2hvdWxkIGJlIHVzZWQgdG8gcmVhZCBmcm9tIGEge0Bjb2RlIFBpcGVkSW5wdXRTdHJlYW19CisgICAgICogYW5kIHRvIHdyaXRlIHRvIHRoZSBjb25uZWN0ZWQge0BsaW5rIFBpcGVkT3V0cHV0U3RyZWFtfS4gSWYgdGhlIHNhbWUKKyAgICAgKiB0aHJlYWQgaXMgdXNlZCwgYSBkZWFkbG9jayBtYXkgb2NjdXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZSBzdHJlYW0KKyAgICAgKiAgICAgICAgIGhhcyBiZWVuIHJlYWNoZWQuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBieXRlQ291bnQgPCAwfSwgb3IgaWYge0Bjb2RlCisgICAgICogICAgICAgICAgICAgb2Zmc2V0ICsgYnl0ZUNvdW50fSBpcyBncmVhdGVyIHRoYW4gdGhlIHNpemUgb2Yge0Bjb2RlIGJ5dGVzfS4KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgdGhyZWFkIHJlYWRpbmcgZnJvbSB0aGlzIHN0cmVhbSBpcyBpbnRlcnJ1cHRlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBzdHJlYW0gaXMgY2xvc2VkIG9yIG5vdCBjb25uZWN0ZWQgdG8gYW4gb3V0cHV0CisgICAgICogICAgICAgICAgICAgc3RyZWFtLCBvciBpZiB0aGUgdGhyZWFkIHdyaXRpbmcgdG8gdGhlIGNvbm5lY3RlZCBvdXRwdXQKKyAgICAgKiAgICAgICAgICAgICBzdHJlYW0gaXMgbm8gbG9uZ2VyIGFsaXZlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYnl0ZXN9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCByZWFkKGJ5dGVbXSBieXRlcywgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnl0ZXMubGVuZ3RoLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIGlmIChieXRlQ291bnQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWlzQ29ubmVjdGVkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIk5vdCBjb25uZWN0ZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChidWZmZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbnB1dFN0cmVhbSBpcyBjbG9zZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIFNldCB0aGUgbGFzdCB0aHJlYWQgdG8gYmUgcmVhZGluZyBvbiB0aGlzIFBpcGVkSW5wdXRTdHJlYW0uIElmCisgICAgICAgICAqIGxhc3RSZWFkZXIgZGllcyB3aGlsZSBzb21lb25lIGlzIHdhaXRpbmcgdG8gd3JpdGUgYW4gSU9FeGNlcHRpb24gb2YKKyAgICAgICAgICogIlBpcGUgYnJva2VuIiB3aWxsIGJlIHRocm93biBpbiByZWNlaXZlKCkKKyAgICAgICAgICovCisgICAgICAgIGxhc3RSZWFkZXIgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IGF0dGVtcHRzID0gMzsKKyAgICAgICAgICAgIHdoaWxlIChpbiA9PSAtMSkgeworICAgICAgICAgICAgICAgIC8vIEFyZSB3ZSBhdCBlbmQgb2Ygc3RyZWFtPworICAgICAgICAgICAgICAgIGlmIChpc0Nsb3NlZCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICgoYXR0ZW1wdHMtLSA8PSAwKSAmJiBsYXN0V3JpdGVyICE9IG51bGwgJiYgIWxhc3RXcml0ZXIuaXNBbGl2ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUGlwZSBicm9rZW4iKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gTm90aWZ5IGNhbGxlcnMgb2YgcmVjZWl2ZSgpCisgICAgICAgICAgICAgICAgbm90aWZ5QWxsKCk7CisgICAgICAgICAgICAgICAgd2FpdCgxMDAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkSU9FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCB0b3RhbENvcGllZCA9IDA7CisKKyAgICAgICAgLy8gY29weSBieXRlcyBmcm9tIG91dCB0aHJ1IHRoZSBlbmQgb2YgYnVmZmVyCisgICAgICAgIGlmIChvdXQgPj0gaW4pIHsKKyAgICAgICAgICAgIGludCBsZWZ0SW5CdWZmZXIgPSBidWZmZXIubGVuZ3RoIC0gb3V0OworICAgICAgICAgICAgaW50IGxlbmd0aCA9IGxlZnRJbkJ1ZmZlciA8IGJ5dGVDb3VudCA/IGxlZnRJbkJ1ZmZlciA6IGJ5dGVDb3VudDsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCBvdXQsIGJ5dGVzLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgICAgICBvdXQgKz0gbGVuZ3RoOworICAgICAgICAgICAgaWYgKG91dCA9PSBidWZmZXIubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgb3V0ID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChvdXQgPT0gaW4pIHsKKyAgICAgICAgICAgICAgICAvLyBlbXB0eSBidWZmZXIKKyAgICAgICAgICAgICAgICBpbiA9IC0xOworICAgICAgICAgICAgICAgIG91dCA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0b3RhbENvcGllZCArPSBsZW5ndGg7CisgICAgICAgIH0KKworICAgICAgICAvLyBjb3B5IGJ5dGVzIGZyb20gb3V0IHRocnUgaW4KKyAgICAgICAgaWYgKHRvdGFsQ29waWVkIDwgYnl0ZUNvdW50ICYmIGluICE9IC0xKSB7CisgICAgICAgICAgICBpbnQgbGVmdEluQnVmZmVyID0gaW4gLSBvdXQ7CisgICAgICAgICAgICBpbnQgbGVmdFRvQ29weSA9IGJ5dGVDb3VudCAtIHRvdGFsQ29waWVkOworICAgICAgICAgICAgaW50IGxlbmd0aCA9IGxlZnRUb0NvcHkgPCBsZWZ0SW5CdWZmZXIgPyBsZWZ0VG9Db3B5IDogbGVmdEluQnVmZmVyOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWZmZXIsIG91dCwgYnl0ZXMsIG9mZnNldCArIHRvdGFsQ29waWVkLCBsZW5ndGgpOworICAgICAgICAgICAgb3V0ICs9IGxlbmd0aDsKKyAgICAgICAgICAgIGlmIChvdXQgPT0gaW4pIHsKKyAgICAgICAgICAgICAgICAvLyBlbXB0eSBidWZmZXIKKyAgICAgICAgICAgICAgICBpbiA9IC0xOworICAgICAgICAgICAgICAgIG91dCA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0b3RhbENvcGllZCArPSBsZW5ndGg7CisgICAgICAgIH0KKworICAgICAgICAvLyBsZXQgYmxvY2tlZCB3cml0ZXJzIHdyaXRlIHRvIHRoZSBuZXdseSBhdmFpbGFibGUgYnVmZmVyIHNwYWNlCisgICAgICAgIG5vdGlmeUFsbCgpOworCisgICAgICAgIHJldHVybiB0b3RhbENvcGllZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlcyBhIGJ5dGUgYW5kIHN0b3JlcyBpdCBpbiB0aGlzIHN0cmVhbSdzIHtAY29kZSBidWZmZXJ9LiBUaGlzCisgICAgICogbWV0aG9kIGlzIGNhbGxlZCBieSB7QGxpbmsgUGlwZWRPdXRwdXRTdHJlYW0jd3JpdGUoaW50KX0uIFRoZSBsZWFzdAorICAgICAqIHNpZ25pZmljYW50IGJ5dGUgb2YgdGhlIGludGVnZXIge0Bjb2RlIG9uZUJ5dGV9IGlzIHN0b3JlZCBhdCBpbmRleAorICAgICAqIHtAY29kZSBpbn0gaW4gdGhlIHtAY29kZSBidWZmZXJ9LgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIGJsb2NrcyBhcyBsb25nIGFzIHtAY29kZSBidWZmZXJ9IGlzIGZ1bGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb25lQnl0ZQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgdG8gc3RvcmUgaW4gdGhpcyBwaXBlLgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgYnVmZmVyfSBpcyBmdWxsIGFuZCB0aGUgdGhyZWFkIHRoYXQgaGFzIGNhbGxlZAorICAgICAqICAgICAgICAgICAgIHRoaXMgbWV0aG9kIGlzIGludGVycnVwdGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHN0cmVhbSBpcyBjbG9zZWQgb3IgdGhlIHRocmVhZCB0aGF0IGhhcyBsYXN0IHJlYWQKKyAgICAgKiAgICAgICAgICAgICBmcm9tIHRoaXMgc3RyZWFtIGlzIG5vIGxvbmdlciBhbGl2ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgcmVjZWl2ZShpbnQgb25lQnl0ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGJ1ZmZlciA9PSBudWxsIHx8IGlzQ2xvc2VkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlBpcGUgaXMgY2xvc2VkIik7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBTZXQgdGhlIGxhc3QgdGhyZWFkIHRvIGJlIHdyaXRpbmcgb24gdGhpcyBQaXBlZElucHV0U3RyZWFtLiBJZgorICAgICAgICAgKiBsYXN0V3JpdGVyIGRpZXMgd2hpbGUgc29tZW9uZSBpcyB3YWl0aW5nIHRvIHJlYWQgYW4gSU9FeGNlcHRpb24gb2YKKyAgICAgICAgICogIlBpcGUgYnJva2VuIiB3aWxsIGJlIHRocm93biBpbiByZWFkKCkKKyAgICAgICAgICovCisgICAgICAgIGxhc3RXcml0ZXIgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgd2hpbGUgKGJ1ZmZlciAhPSBudWxsICYmIG91dCA9PSBpbikgeworICAgICAgICAgICAgICAgIGlmIChsYXN0UmVhZGVyICE9IG51bGwgJiYgIWxhc3RSZWFkZXIuaXNBbGl2ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUGlwZSBicm9rZW4iKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbm90aWZ5QWxsKCk7CisgICAgICAgICAgICAgICAgd2FpdCgxMDAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkSU9FeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYnVmZmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUGlwZSBpcyBjbG9zZWQiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW4gPT0gLTEpIHsKKyAgICAgICAgICAgIGluID0gMDsKKyAgICAgICAgfQorICAgICAgICBidWZmZXJbaW4rK10gPSAoYnl0ZSkgb25lQnl0ZTsKKyAgICAgICAgaWYgKGluID09IGJ1ZmZlci5sZW5ndGgpIHsKKyAgICAgICAgICAgIGluID0gMDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGxldCBibG9ja2VkIHJlYWRlcnMgcmVhZCB0aGUgbmV3bHkgYXZhaWxhYmxlIGRhdGEKKyAgICAgICAgbm90aWZ5QWxsKCk7CisgICAgfQorCisgICAgc3luY2hyb25pemVkIHZvaWQgZG9uZSgpIHsKKyAgICAgICAgaXNDbG9zZWQgPSB0cnVlOworICAgICAgICBub3RpZnlBbGwoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9QaXBlZE91dHB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vUGlwZWRPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNjc0YmIzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vUGlwZWRPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDE3OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCisvKioKKyAqIFBsYWNlcyBpbmZvcm1hdGlvbiBvbiBhIGNvbW11bmljYXRpb25zIHBpcGUuIFdoZW4gdHdvIHRocmVhZHMgd2FudCB0byBwYXNzCisgKiBkYXRhIGJhY2sgYW5kIGZvcnRoLCBvbmUgY3JlYXRlcyBhIHBpcGVkIG91dHB1dCBzdHJlYW0gYW5kIHRoZSBvdGhlciBvbmUKKyAqIGNyZWF0ZXMgYSBwaXBlZCBpbnB1dCBzdHJlYW0uCisgKgorICogQHNlZSBQaXBlZElucHV0U3RyZWFtCisgKi8KK3B1YmxpYyBjbGFzcyBQaXBlZE91dHB1dFN0cmVhbSBleHRlbmRzIE91dHB1dFN0cmVhbSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGVzdGluYXRpb24gUGlwZWRJbnB1dFN0cmVhbQorICAgICAqLworICAgIHByaXZhdGUgUGlwZWRJbnB1dFN0cmVhbSB0YXJnZXQ7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHVuY29ubmVjdGVkIHtAY29kZSBQaXBlZE91dHB1dFN0cmVhbX0uIFRoZSByZXN1bHRpbmcKKyAgICAgKiBzdHJlYW0gbXVzdCBiZSBjb25uZWN0ZWQgdG8gYSB7QGxpbmsgUGlwZWRJbnB1dFN0cmVhbX0gYmVmb3JlIGRhdGEgY2FuIGJlCisgICAgICogd3JpdHRlbiB0byBpdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGlwZWRPdXRwdXRTdHJlYW0oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUGlwZWRPdXRwdXRTdHJlYW19IGNvbm5lY3RlZCB0byB0aGUKKyAgICAgKiB7QGxpbmsgUGlwZWRJbnB1dFN0cmVhbX0ge0Bjb2RlIHRhcmdldH0uIEFueSBkYXRhIHdyaXR0ZW4gdG8gdGhpcyBzdHJlYW0KKyAgICAgKiBjYW4gYmUgcmVhZCBmcm9tIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHRhcmdldAorICAgICAqICAgICAgICAgICAgdGhlIHBpcGVkIGlucHV0IHN0cmVhbSB0byBjb25uZWN0IHRvLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHN0cmVhbSBvciB7QGNvZGUgdGFyZ2V0fSBhcmUgYWxyZWFkeSBjb25uZWN0ZWQuCisgICAgICovCisgICAgcHVibGljIFBpcGVkT3V0cHV0U3RyZWFtKFBpcGVkSW5wdXRTdHJlYW0gdGFyZ2V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjb25uZWN0KHRhcmdldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgc3RyZWFtLiBJZiB0aGlzIHN0cmVhbSBpcyBjb25uZWN0ZWQgdG8gYW4gaW5wdXQgc3RyZWFtLCB0aGUKKyAgICAgKiBpbnB1dCBzdHJlYW0gaXMgY2xvc2VkIGFuZCB0aGUgcGlwZSBpcyBkaXNjb25uZWN0ZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNsb3NpbmcgdGhpcyBzdHJlYW0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBJcyB0aGUgcGlwZSBjb25uZWN0ZWQ/CisgICAgICAgIFBpcGVkSW5wdXRTdHJlYW0gc3RyZWFtID0gdGFyZ2V0OworICAgICAgICBpZiAoc3RyZWFtICE9IG51bGwpIHsKKyAgICAgICAgICAgIHN0cmVhbS5kb25lKCk7CisgICAgICAgICAgICB0YXJnZXQgPSBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29ubmVjdHMgdGhpcyBzdHJlYW0gdG8gYSB7QGxpbmsgUGlwZWRJbnB1dFN0cmVhbX0uIEFueSBkYXRhIHdyaXR0ZW4gdG8KKyAgICAgKiB0aGlzIG91dHB1dCBzdHJlYW0gYmVjb21lcyByZWFkYWJsZSBpbiB0aGUgaW5wdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIHBpcGVkIGlucHV0IHN0cmVhbSB0byBjb25uZWN0IHRvLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBlaXRoZXIgc3RyZWFtIGlzIGFscmVhZHkgY29ubmVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNvbm5lY3QoUGlwZWRJbnB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzdHJlYW0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgc3luY2hyb25pemVkIChzdHJlYW0pIHsKKyAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJBbHJlYWR5IGNvbm5lY3RlZCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHN0cmVhbS5pc0Nvbm5lY3RlZCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUGlwZSBhbHJlYWR5IGNvbm5lY3RlZCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3RyZWFtLmVzdGFibGlzaENvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgIHRoaXMudGFyZ2V0ID0gc3RyZWFtOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTm90aWZpZXMgdGhlIHJlYWRlcnMgb2YgdGhpcyB7QGxpbmsgUGlwZWRJbnB1dFN0cmVhbX0gdGhhdCBieXRlcyBjYW4gYmUKKyAgICAgKiByZWFkLiBUaGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcgaWYgdGhpcyBzdHJlYW0gaXMgbm90IGNvbm5lY3RlZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIGZsdXNoaW5nIHRoaXMgc3RyZWFtLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUGlwZWRJbnB1dFN0cmVhbSBzdHJlYW0gPSB0YXJnZXQ7CisgICAgICAgIGlmIChzdHJlYW0gPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgc3luY2hyb25pemVkIChzdHJlYW0pIHsKKyAgICAgICAgICAgIHN0cmVhbS5ub3RpZnlBbGwoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB7QGNvZGUgY291bnR9IGJ5dGVzIGZyb20gdGhlIGJ5dGUgYXJyYXkge0Bjb2RlIGJ1ZmZlcn0gc3RhcnRpbmcgYXQKKyAgICAgKiB7QGNvZGUgb2Zmc2V0fSB0byB0aGlzIHN0cmVhbS4gVGhlIHdyaXR0ZW4gZGF0YSBjYW4gdGhlbiBiZSByZWFkIGZyb20gdGhlCisgICAgICogY29ubmVjdGVkIGlucHV0IHN0cmVhbS4KKyAgICAgKiA8cD4KKyAgICAgKiBTZXBhcmF0ZSB0aHJlYWRzIHNob3VsZCBiZSB1c2VkIHRvIHdyaXRlIHRvIGEge0Bjb2RlIFBpcGVkT3V0cHV0U3RyZWFtfQorICAgICAqIGFuZCB0byByZWFkIGZyb20gdGhlIGNvbm5lY3RlZCB7QGxpbmsgUGlwZWRJbnB1dFN0cmVhbX0uIElmIHRoZSBzYW1lCisgICAgICogdGhyZWFkIGlzIHVzZWQsIGEgZGVhZGxvY2sgbWF5IG9jY3VyLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIGJ1ZmZlciB0byB3cml0ZS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGJ5dGUgaW4ge0Bjb2RlIGJ1ZmZlcn0gdG8gd3JpdGUuCisgICAgICogQHBhcmFtIGNvdW50CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIGZyb20ge0Bjb2RlIGJ1ZmZlcn0gdG8gd3JpdGUgdG8gdGhpcworICAgICAqICAgICAgICAgICAgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwfSBvciB7QGNvZGUgY291bnQgPCAwfSwgb3IgaWYge0Bjb2RlCisgICAgICogICAgICAgICAgICAgb2Zmc2V0ICsgY291bnR9IGlzIGJpZ2dlciB0aGFuIHRoZSBsZW5ndGggb2Yge0Bjb2RlIGJ1ZmZlcn0uCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBpcGUgaXMgZnVsbCBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkCisgICAgICogICAgICAgICAgICAgd2FpdGluZyBmb3Igc3BhY2UgdG8gd3JpdGUgZGF0YS4gVGhpcyBjYXNlIGlzIG5vdCBjdXJyZW50bHkKKyAgICAgKiAgICAgICAgICAgICBoYW5kbGVkIGNvcnJlY3RseS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBzdHJlYW0gaXMgbm90IGNvbm5lY3RlZCwgaWYgdGhlIHRhcmdldCBzdHJlYW0gaXMKKyAgICAgKiAgICAgICAgICAgICBjbG9zZWQgb3IgaWYgdGhlIHRocmVhZCByZWFkaW5nIGZyb20gdGhlIHRhcmdldCBzdHJlYW0gaXMgbm8KKyAgICAgKiAgICAgICAgICAgICBsb25nZXIgYWxpdmUuIFRoaXMgY2FzZSBpcyBjdXJyZW50bHkgbm90IGhhbmRsZWQgY29ycmVjdGx5LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIud3JpdGUoYnVmZmVyLCBvZmZzZXQsIGNvdW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBzaW5nbGUgYnl0ZSB0byB0aGlzIHN0cmVhbS4gT25seSB0aGUgbGVhc3Qgc2lnbmlmaWNhbnQgYnl0ZSBvZgorICAgICAqIHRoZSBpbnRlZ2VyIHtAY29kZSBvbmVCeXRlfSBpcyB3cml0dGVuLiBUaGUgd3JpdHRlbiBieXRlIGNhbiB0aGVuIGJlIHJlYWQKKyAgICAgKiBmcm9tIHRoZSBjb25uZWN0ZWQgaW5wdXQgc3RyZWFtLgorICAgICAqIDxwPgorICAgICAqIFNlcGFyYXRlIHRocmVhZHMgc2hvdWxkIGJlIHVzZWQgdG8gd3JpdGUgdG8gYSB7QGNvZGUgUGlwZWRPdXRwdXRTdHJlYW19CisgICAgICogYW5kIHRvIHJlYWQgZnJvbSB0aGUgY29ubmVjdGVkIHtAbGluayBQaXBlZElucHV0U3RyZWFtfS4gSWYgdGhlIHNhbWUKKyAgICAgKiB0aHJlYWQgaXMgdXNlZCwgYSBkZWFkbG9jayBtYXkgb2NjdXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb25lQnl0ZQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBpcGUgaXMgZnVsbCBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkCisgICAgICogICAgICAgICAgICAgd2FpdGluZyBmb3Igc3BhY2UgdG8gd3JpdGUgZGF0YS4gVGhpcyBjYXNlIGlzIG5vdCBjdXJyZW50bHkKKyAgICAgKiAgICAgICAgICAgICBoYW5kbGVkIGNvcnJlY3RseS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBzdHJlYW0gaXMgbm90IGNvbm5lY3RlZCwgaWYgdGhlIHRhcmdldCBzdHJlYW0gaXMKKyAgICAgKiAgICAgICAgICAgICBjbG9zZWQgb3IgaWYgdGhlIHRocmVhZCByZWFkaW5nIGZyb20gdGhlIHRhcmdldCBzdHJlYW0gaXMgbm8KKyAgICAgKiAgICAgICAgICAgICBsb25nZXIgYWxpdmUuIFRoaXMgY2FzZSBpcyBjdXJyZW50bHkgbm90IGhhbmRsZWQgY29ycmVjdGx5LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBvbmVCeXRlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBQaXBlZElucHV0U3RyZWFtIHN0cmVhbSA9IHRhcmdldDsKKyAgICAgICAgaWYgKHN0cmVhbSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlBpcGUgbm90IGNvbm5lY3RlZCIpOworICAgICAgICB9CisgICAgICAgIHN0cmVhbS5yZWNlaXZlKG9uZUJ5dGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1BpcGVkUmVhZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9QaXBlZFJlYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYxOTBjODYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9QaXBlZFJlYWRlci5qYXZhCkBAIC0wLDAgKzEsNDUyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIFJlY2VpdmVzIGluZm9ybWF0aW9uIG9uIGEgY29tbXVuaWNhdGlvbnMgcGlwZS4gV2hlbiB0d28gdGhyZWFkcyB3YW50IHRvIHBhc3MKKyAqIGRhdGEgYmFjayBhbmQgZm9ydGgsIG9uZSBjcmVhdGVzIGEgcGlwZWQgd3JpdGVyIGFuZCB0aGUgb3RoZXIgY3JlYXRlcyBhIHBpcGVkCisgKiByZWFkZXIuCisgKgorICogQHNlZSBQaXBlZFdyaXRlcgorICovCitwdWJsaWMgY2xhc3MgUGlwZWRSZWFkZXIgZXh0ZW5kcyBSZWFkZXIgeworCisgICAgcHJpdmF0ZSBUaHJlYWQgbGFzdFJlYWRlcjsKKworICAgIHByaXZhdGUgVGhyZWFkIGxhc3RXcml0ZXI7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNDbG9zZWQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY2lyY3VsYXIgYnVmZmVyIHRocm91Z2ggd2hpY2ggZGF0YSBpcyBwYXNzZWQuIERhdGEgaXMgcmVhZCBmcm9tIHRoZQorICAgICAqIHJhbmdlIHtAY29kZSBbb3V0LCBpbil9IGFuZCB3cml0dGVuIHRvIHRoZSByYW5nZSB7QGNvZGUgW2luLCBvdXQpfS4KKyAgICAgKiBEYXRhIGluIHRoZSBidWZmZXIgaXMgZWl0aGVyIHNlcXVlbnRpYWw6IDxwcmU+CisgICAgICogICAgIHsgLSAtIC0gWCBYIFggWCBYIFggWCAtIC0gLSAtIC0gfQorICAgICAqICAgICAgICAgICAgIF4gICAgICAgICAgICAgXgorICAgICAqICAgICAgICAgICAgIHwgICAgICAgICAgICAgfAorICAgICAqICAgICAgICAgICAgb3V0ICAgICAgICAgICBpbjwvcHJlPgorICAgICAqIC4uLm9yIHdyYXBwZWQgYXJvdW5kIHRoZSBidWZmZXIncyBlbmQ6IDxwcmU+CisgICAgICogICAgIHsgWCBYIFggWCAtIC0gLSAtIC0gLSAtIC0gWCBYIFggfQorICAgICAqICAgICAgICAgICAgICAgXiAgICAgICAgICAgICAgIF4KKyAgICAgKiAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICB8CisgICAgICogICAgICAgICAgICAgIGluICAgICAgICAgICAgICBvdXQ8L3ByZT4KKyAgICAgKiBXaGVuIHRoZSBidWZmZXIgaXMgZW1wdHksIHtAY29kZSBpbiA9PSAtMX0uIFJlYWRpbmcgd2hlbiB0aGUgYnVmZmVyIGlzCisgICAgICogZW1wdHkgd2lsbCBibG9jayB1bnRpbCBkYXRhIGlzIGF2YWlsYWJsZS4gV2hlbiB0aGUgYnVmZmVyIGlzIGZ1bGwsCisgICAgICoge0Bjb2RlIGluID09IG91dH0uIFdyaXRpbmcgd2hlbiB0aGUgYnVmZmVyIGlzIGZ1bGwgd2lsbCBibG9jayB1bnRpbCBmcmVlCisgICAgICogc3BhY2UgaXMgYXZhaWxhYmxlLgorICAgICAqLworICAgIHByaXZhdGUgY2hhcltdIGJ1ZmZlcjsKKworICAgIC8qKgorICAgICAqIFRoZSBpbmRleCBpbiB7QGNvZGUgYnVmZmVyfSB3aGVyZSB0aGUgbmV4dCBjaGFyYWN0ZXIgd2lsbCBiZSB3cml0dGVuLgorICAgICAqLworICAgIHByaXZhdGUgaW50IGluID0gLTE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW5kZXggaW4ge0Bjb2RlIGJ1ZmZlcn0gd2hlcmUgdGhlIG5leHQgY2hhcmFjdGVyIHdpbGwgYmUgcmVhZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBvdXQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc2l6ZSBvZiB0aGUgZGVmYXVsdCBwaXBlIGluIGNoYXJhY3RlcnMKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUElQRV9TSVpFID0gMTAyNDsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyBpZiB0aGlzIHBpcGUgaXMgY29ubmVjdGVkCisgICAgICovCisgICAgYm9vbGVhbiBpc0Nvbm5lY3RlZDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgdW5jb25uZWN0ZWQge0Bjb2RlIFBpcGVkUmVhZGVyfS4gVGhlIHJlc3VsdGluZyByZWFkZXIKKyAgICAgKiBtdXN0IGJlIGNvbm5lY3RlZCB0byBhIHtAY29kZSBQaXBlZFdyaXRlcn0gYmVmb3JlIGRhdGEgbWF5IGJlIHJlYWQgZnJvbQorICAgICAqIGl0LgorICAgICAqLworICAgIHB1YmxpYyBQaXBlZFJlYWRlcigpIHt9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBQaXBlZFJlYWRlcn0gY29ubmVjdGVkIHRvIHRoZSB7QGxpbmsgUGlwZWRXcml0ZXJ9CisgICAgICoge0Bjb2RlIG91dH0uIEFueSBkYXRhIHdyaXR0ZW4gdG8gdGhlIHdyaXRlciBjYW4gYmUgcmVhZCBmcm9tIHRoZSB0aGlzCisgICAgICogcmVhZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBQaXBlZFdyaXRlcn0gdG8gY29ubmVjdCB0by4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG91dH0gaXMgYWxyZWFkeSBjb25uZWN0ZWQuCisgICAgICovCisgICAgcHVibGljIFBpcGVkUmVhZGVyKFBpcGVkV3JpdGVyIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY29ubmVjdChvdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgdW5jb25uZWN0ZWQge0Bjb2RlIFBpcGVkUmVhZGVyfSB3aXRoIHRoZSBnaXZlbiBidWZmZXIgc2l6ZS4KKyAgICAgKiBUaGUgcmVzdWx0aW5nIHJlYWRlciBtdXN0IGJlIGNvbm5lY3RlZCB0byBhIHtAY29kZSBQaXBlZFdyaXRlcn0gYmVmb3JlCisgICAgICogZGF0YSBtYXkgYmUgcmVhZCBmcm9tIGl0LgorICAgICAqCisgICAgICogQHBhcmFtIHBpcGVTaXplIHRoZSBzaXplIG9mIHRoZSBidWZmZXIgaW4gY2hhcnMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgcGlwZVNpemUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8uCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBQaXBlZFJlYWRlcihpbnQgcGlwZVNpemUpIHsKKyAgICAgICAgaWYgKHBpcGVTaXplIDw9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInBpcGUgc2l6ZSAiICsgcGlwZVNpemUgKyAiIHRvbyBzbWFsbCIpOworICAgICAgICB9CisgICAgICAgIGJ1ZmZlciA9IG5ldyBjaGFyW3BpcGVTaXplXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBQaXBlZFJlYWRlcn0gY29ubmVjdGVkIHRvIHRoZSBnaXZlbiB7QGNvZGUgUGlwZWRXcml0ZXJ9LAorICAgICAqIHdpdGggdGhlIGdpdmVuIGJ1ZmZlciBzaXplLiBBbnkgZGF0YSB3cml0dGVuIHRvIHRoZSB3cml0ZXIgY2FuIGJlIHJlYWQgZnJvbQorICAgICAqIHRoaXMgcmVhZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG91dCB0aGUge0Bjb2RlIFBpcGVkV3JpdGVyfSB0byBjb25uZWN0IHRvLgorICAgICAqIEBwYXJhbSBwaXBlU2l6ZSB0aGUgc2l6ZSBvZiB0aGUgYnVmZmVyIGluIGNoYXJzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3VycworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHBpcGVTaXplIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB6ZXJvLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgUGlwZWRSZWFkZXIoUGlwZWRXcml0ZXIgb3V0LCBpbnQgcGlwZVNpemUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMocGlwZVNpemUpOworICAgICAgICBjb25uZWN0KG91dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgcmVhZGVyLiBUaGlzIGltcGxlbWVudGF0aW9uIHJlbGVhc2VzIHRoZSBidWZmZXIgdXNlZCBmb3IKKyAgICAgKiB0aGUgcGlwZSBhbmQgbm90aWZpZXMgYWxsIHRocmVhZHMgd2FpdGluZyB0byByZWFkIG9yIHdyaXRlLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjbG9zaW5nIHRoaXMgcmVhZGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ1ZmZlciA9IG51bGw7CisgICAgICAgIGlzQ2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgbm90aWZ5QWxsKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29ubmVjdHMgdGhpcyB7QGNvZGUgUGlwZWRSZWFkZXJ9IHRvIGEge0BsaW5rIFBpcGVkV3JpdGVyfS4gQW55IGRhdGEKKyAgICAgKiB3cml0dGVuIHRvIHRoZSB3cml0ZXIgYmVjb21lcyByZWFkYWJsZSBpbiB0aGlzIHJlYWRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSB3cml0ZXIgdG8gY29ubmVjdCB0by4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyByZWFkZXIgaXMgY2xvc2VkIG9yIGFscmVhZHkgY29ubmVjdGVkLCBvciBpZiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBzcmN9IGlzIGFscmVhZHkgY29ubmVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNvbm5lY3QoUGlwZWRXcml0ZXIgc3JjKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzcmMuY29ubmVjdCh0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFc3RhYmxpc2hlcyB0aGUgY29ubmVjdGlvbiB0byB0aGUgUGlwZWRXcml0ZXIuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgdGhpcyBSZWFkZXIgaXMgYWxyZWFkeSBjb25uZWN0ZWQuCisgICAgICovCisgICAgc3luY2hyb25pemVkIHZvaWQgZXN0YWJsaXNoQ29ubmVjdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpc0Nvbm5lY3RlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJQaXBlIGFscmVhZHkgY29ubmVjdGVkIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlzQ2xvc2VkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlBpcGUgaXMgY2xvc2VkIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJ1ZmZlciA9PSBudWxsKSB7IC8vIFdlIG1heSBhbHJlYWR5IGhhdmUgYWxsb2NhdGVkIHRoZSBidWZmZXIuCisgICAgICAgICAgICBidWZmZXIgPSBuZXcgY2hhcltQSVBFX1NJWkVdOworICAgICAgICB9CisgICAgICAgIGlzQ29ubmVjdGVkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHNpbmdsZSBjaGFyYWN0ZXIgZnJvbSB0aGlzIHJlYWRlciBhbmQgcmV0dXJucyBpdCBhcyBhbiBpbnRlZ2VyCisgICAgICogd2l0aCB0aGUgdHdvIGhpZ2hlci1vcmRlciBieXRlcyBzZXQgdG8gMC4gUmV0dXJucyAtMSBpZiB0aGUgZW5kIG9mIHRoZQorICAgICAqIHJlYWRlciBoYXMgYmVlbiByZWFjaGVkLiBJZiB0aGVyZSBpcyBubyBkYXRhIGluIHRoZSBwaXBlLCB0aGlzIG1ldGhvZAorICAgICAqIGJsb2NrcyB1bnRpbCBkYXRhIGlzIGF2YWlsYWJsZSwgdGhlIGVuZCBvZiB0aGUgcmVhZGVyIGlzIGRldGVjdGVkIG9yIGFuCisgICAgICogZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKiA8cD4KKyAgICAgKiBTZXBhcmF0ZSB0aHJlYWRzIHNob3VsZCBiZSB1c2VkIHRvIHJlYWQgZnJvbSBhIHtAY29kZSBQaXBlZFJlYWRlcn0gYW5kIHRvCisgICAgICogd3JpdGUgdG8gdGhlIGNvbm5lY3RlZCB7QGxpbmsgUGlwZWRXcml0ZXJ9LiBJZiB0aGUgc2FtZSB0aHJlYWQgaXMgdXNlZCwKKyAgICAgKiBhIGRlYWRsb2NrIG1heSBvY2N1ci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNoYXJhY3RlciByZWFkIG9yIC0xIGlmIHRoZSBlbmQgb2YgdGhlIHJlYWRlciBoYXMgYmVlbgorICAgICAqICAgICAgICAgcmVhY2hlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyByZWFkZXIgaXMgY2xvc2VkIG9yIHNvbWUgb3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGFyW10gY2hhcnMgPSBuZXcgY2hhclsxXTsKKyAgICAgICAgaW50IHJlc3VsdCA9IHJlYWQoY2hhcnMsIDAsIDEpOworICAgICAgICByZXR1cm4gcmVzdWx0ICE9IC0xID8gY2hhcnNbMF0gOiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYXQgbW9zdCB7QGNvZGUgY291bnR9IGNoYXJhY3RlcnMgZnJvbSB0aGlzIHJlYWRlciBhbmQgc3RvcmVzIHRoZW0KKyAgICAgKiBpbiB0aGUgY2hhcmFjdGVyIGFycmF5IHtAY29kZSBidWZmZXJ9IHN0YXJ0aW5nIGF0IHtAY29kZSBvZmZzZXR9LiBJZgorICAgICAqIHRoZXJlIGlzIG5vIGRhdGEgaW4gdGhlIHBpcGUsIHRoaXMgbWV0aG9kIGJsb2NrcyB1bnRpbCBhdCBsZWFzdCBvbmUgYnl0ZQorICAgICAqIGhhcyBiZWVuIHJlYWQsIHRoZSBlbmQgb2YgdGhlIHJlYWRlciBpcyBkZXRlY3RlZCBvciBhbiBleGNlcHRpb24gaXMKKyAgICAgKiB0aHJvd24uCisgICAgICogPHA+CisgICAgICogU2VwYXJhdGUgdGhyZWFkcyBzaG91bGQgYmUgdXNlZCB0byByZWFkIGZyb20gYSB7QGNvZGUgUGlwZWRSZWFkZXJ9IGFuZCB0bworICAgICAqIHdyaXRlIHRvIHRoZSBjb25uZWN0ZWQge0BsaW5rIFBpcGVkV3JpdGVyfS4gSWYgdGhlIHNhbWUgdGhyZWFkIGlzIHVzZWQsIGEKKyAgICAgKiBkZWFkbG9jayBtYXkgb2NjdXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIGFycmF5IGluIHdoaWNoIHRvIHN0b3JlIHRoZSBjaGFyYWN0ZXJzIHJlYWQuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgcG9zaXRpb24gaW4ge0Bjb2RlIGJ5dGVzfSB0byBzdG9yZSB0aGUgY2hhcmFjdGVycworICAgICAqICAgICAgICAgICAgcmVhZCBmcm9tIHRoaXMgcmVhZGVyLgorICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gc3RvcmUgaW4ge0Bjb2RlIGJ1ZmZlcn0uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZSByZWFkZXIgaGFzCisgICAgICogICAgICAgICBiZWVuIHJlYWNoZWQuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBjb3VudCA8IDB9LCBvciBpZiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBvZmZzZXQgKyBjb3VudH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBzaXplIG9mIHtAY29kZSBidWZmZXJ9LgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB0aHJlYWQgcmVhZGluZyBmcm9tIHRoaXMgcmVhZGVyIGlzIGludGVycnVwdGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQgb3Igbm90IGNvbm5lY3RlZCB0byBhIHdyaXRlciwgb3IgaWYKKyAgICAgKiAgICAgICAgICAgICB0aGUgdGhyZWFkIHdyaXRpbmcgdG8gdGhlIGNvbm5lY3RlZCB3cml0ZXIgaXMgbm8gbG9uZ2VyCisgICAgICogICAgICAgICAgICAgYWxpdmUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgcmVhZChjaGFyW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaXNDb25uZWN0ZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUGlwZSBub3QgY29ubmVjdGVkIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRoaXMuYnVmZmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUGlwZSBpcyBjbG9zZWQiKTsKKyAgICAgICAgfQorICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXIubGVuZ3RoLCBvZmZzZXQsIGNvdW50KTsKKyAgICAgICAgaWYgKGNvdW50ID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIC8qKgorICAgICAgICAgKiBTZXQgdGhlIGxhc3QgdGhyZWFkIHRvIGJlIHJlYWRpbmcgb24gdGhpcyBQaXBlZFJlYWRlci4gSWYKKyAgICAgICAgICogbGFzdFJlYWRlciBkaWVzIHdoaWxlIHNvbWVvbmUgaXMgd2FpdGluZyB0byB3cml0ZSBhbiBJT0V4Y2VwdGlvbgorICAgICAgICAgKiBvZiAiUGlwZSBicm9rZW4iIHdpbGwgYmUgdGhyb3duIGluIHJlY2VpdmUoKQorICAgICAgICAgKi8KKyAgICAgICAgbGFzdFJlYWRlciA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKyAgICAgICAgICAgIHdoaWxlIChpbiA9PSAtMSkgeworICAgICAgICAgICAgICAgIC8vIEFyZSB3ZSBhdCBlbmQgb2Ygc3RyZWFtPworICAgICAgICAgICAgICAgIGlmIChpc0Nsb3NlZCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICghZmlyc3QgJiYgbGFzdFdyaXRlciAhPSBudWxsICYmICFsYXN0V3JpdGVyLmlzQWxpdmUoKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlBpcGUgYnJva2VuIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgLy8gTm90aWZ5IGNhbGxlcnMgb2YgcmVjZWl2ZSgpCisgICAgICAgICAgICAgICAgbm90aWZ5QWxsKCk7CisgICAgICAgICAgICAgICAgd2FpdCgxMDAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkSU9FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBjb3B5TGVuZ3RoID0gMDsKKyAgICAgICAgLyogQ29weSBjaGFycyBmcm9tIG91dCB0byBlbmQgb2YgYnVmZmVyIGZpcnN0ICovCisgICAgICAgIGlmIChvdXQgPj0gaW4pIHsKKyAgICAgICAgICAgIGNvcHlMZW5ndGggPSBjb3VudCA+IHRoaXMuYnVmZmVyLmxlbmd0aCAtIG91dCA/IHRoaXMuYnVmZmVyLmxlbmd0aCAtIG91dCA6IGNvdW50OworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0aGlzLmJ1ZmZlciwgb3V0LCBidWZmZXIsIG9mZnNldCwgY29weUxlbmd0aCk7CisgICAgICAgICAgICBvdXQgKz0gY29weUxlbmd0aDsKKyAgICAgICAgICAgIGlmIChvdXQgPT0gdGhpcy5idWZmZXIubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgb3V0ID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChvdXQgPT0gaW4pIHsKKyAgICAgICAgICAgICAgICAvLyBlbXB0eSBidWZmZXIKKyAgICAgICAgICAgICAgICBpbiA9IC0xOworICAgICAgICAgICAgICAgIG91dCA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBEaWQgdGhlIHJlYWQgZnVsbHkgc3VjY2VlZCBpbiB0aGUgcHJldmlvdXMgY29weSBvciBpcyB0aGUgYnVmZmVyCisgICAgICAgICAqIGVtcHR5PworICAgICAgICAgKi8KKyAgICAgICAgaWYgKGNvcHlMZW5ndGggPT0gY291bnQgfHwgaW4gPT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiBjb3B5TGVuZ3RoOworICAgICAgICB9CisKKyAgICAgICAgaW50IGNoYXJzQ29waWVkID0gY29weUxlbmd0aDsKKyAgICAgICAgLyogQ29weSBieXRlcyBmcm9tIDAgdG8gdGhlIG51bWJlciBvZiBhdmFpbGFibGUgYnl0ZXMgKi8KKyAgICAgICAgY29weUxlbmd0aCA9IGluIC0gb3V0ID4gY291bnQgLSBjb3B5TGVuZ3RoID8gY291bnQgLSBjb3B5TGVuZ3RoIDogaW4gLSBvdXQ7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodGhpcy5idWZmZXIsIG91dCwgYnVmZmVyLCBvZmZzZXQgKyBjaGFyc0NvcGllZCwgY29weUxlbmd0aCk7CisgICAgICAgIG91dCArPSBjb3B5TGVuZ3RoOworICAgICAgICBpZiAob3V0ID09IGluKSB7CisgICAgICAgICAgICAvLyBlbXB0eSBidWZmZXIKKyAgICAgICAgICAgIGluID0gLTE7CisgICAgICAgICAgICBvdXQgPSAwOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjaGFyc0NvcGllZCArIGNvcHlMZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyByZWFkZXIgaXMgcmVhZHkgdG8gYmUgcmVhZCB3aXRob3V0IGJsb2NraW5nLgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoaXMgcmVhZGVyIHdpbGwgbm90IGJsb2NrIHdoZW4ge0Bjb2RlIHJlYWR9IGlzCisgICAgICogY2FsbGVkLCB7QGNvZGUgZmFsc2V9IGlmIHVua25vd24gb3IgYmxvY2tpbmcgd2lsbCBvY2N1ci4gVGhpcworICAgICAqIGltcGxlbWVudGF0aW9uIHJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoZSBpbnRlcm5hbCBidWZmZXIgY29udGFpbnMKKyAgICAgKiBjaGFyYWN0ZXJzIHRoYXQgY2FuIGJlIHJlYWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFsd2F5cyB7QGNvZGUgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQgb3Igbm90IGNvbm5lY3RlZCwgb3IgaWYgc29tZSBvdGhlcgorICAgICAqICAgICAgICAgICAgIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSAjcmVhZCgpCisgICAgICogQHNlZSAjcmVhZChjaGFyW10sIGludCwgaW50KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiByZWFkeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaXNDb25uZWN0ZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUGlwZSBub3QgY29ubmVjdGVkIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJ1ZmZlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlBpcGUgaXMgY2xvc2VkIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGluICE9IC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlY2VpdmVzIGEgY2hhciBhbmQgc3RvcmVzIGl0IGludG8gdGhlIFBpcGVkUmVhZGVyLiBUaGlzIGNhbGxlZCBieQorICAgICAqIFBpcGVkV3JpdGVyLndyaXRlKCkgd2hlbiB3cml0ZXMgb2NjdXIuCisgICAgICogPFA+CisgICAgICogSWYgdGhlIGJ1ZmZlciBpcyBmdWxsIGFuZCB0aGUgdGhyZWFkIHNlbmRpbmcgI3JlY2VpdmUgaXMgaW50ZXJydXB0ZWQsIHRoZQorICAgICAqIEludGVycnVwdGVkSU9FeGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb25lQ2hhcgorICAgICAqICAgICAgICAgICAgdGhlIGNoYXIgdG8gc3RvcmUgaW50byB0aGUgcGlwZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiB0aGUgc3RyZWFtIGlzIGFscmVhZHkgY2xvc2VkIG9yIGFub3RoZXIgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBvY2N1cnMuCisgICAgICovCisgICAgc3luY2hyb25pemVkIHZvaWQgcmVjZWl2ZShjaGFyIG9uZUNoYXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChidWZmZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJQaXBlIGlzIGNsb3NlZCIpOworICAgICAgICB9CisgICAgICAgIGlmIChsYXN0UmVhZGVyICE9IG51bGwgJiYgIWxhc3RSZWFkZXIuaXNBbGl2ZSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlBpcGUgYnJva2VuIik7CisgICAgICAgIH0KKyAgICAgICAgLyoKKyAgICAgICAgKiBTZXQgdGhlIGxhc3QgdGhyZWFkIHRvIGJlIHdyaXRpbmcgb24gdGhpcyBQaXBlZFdyaXRlci4gSWYKKyAgICAgICAgKiBsYXN0V3JpdGVyIGRpZXMgd2hpbGUgc29tZW9uZSBpcyB3YWl0aW5nIHRvIHJlYWQgYW4gSU9FeGNlcHRpb24KKyAgICAgICAgKiBvZiAiUGlwZSBicm9rZW4iIHdpbGwgYmUgdGhyb3duIGluIHJlYWQoKQorICAgICAgICAqLworICAgICAgICBsYXN0V3JpdGVyID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdoaWxlIChidWZmZXIgIT0gbnVsbCAmJiBvdXQgPT0gaW4pIHsKKyAgICAgICAgICAgICAgICBub3RpZnlBbGwoKTsKKyAgICAgICAgICAgICAgICB3YWl0KDEwMDApOworICAgICAgICAgICAgICAgIGlmIChsYXN0UmVhZGVyICE9IG51bGwgJiYgIWxhc3RSZWFkZXIuaXNBbGl2ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUGlwZSBicm9rZW4iKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcnJ1cHRlZElPRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJ1ZmZlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlBpcGUgaXMgY2xvc2VkIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGluID09IC0xKSB7CisgICAgICAgICAgICBpbiA9IDA7CisgICAgICAgIH0KKyAgICAgICAgYnVmZmVyW2luKytdID0gb25lQ2hhcjsKKyAgICAgICAgaWYgKGluID09IGJ1ZmZlci5sZW5ndGgpIHsKKyAgICAgICAgICAgIGluID0gMDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlY2VpdmVzIGEgY2hhciBhcnJheSBhbmQgc3RvcmVzIGl0IGludG8gdGhlIFBpcGVkUmVhZGVyLiBUaGlzIGNhbGxlZCBieQorICAgICAqIFBpcGVkV3JpdGVyLndyaXRlKCkgd2hlbiB3cml0ZXMgb2NjdXIuCisgICAgICogPFA+CisgICAgICogSWYgdGhlIGJ1ZmZlciBpcyBmdWxsIGFuZCB0aGUgdGhyZWFkIHNlbmRpbmcgI3JlY2VpdmUgaXMgaW50ZXJydXB0ZWQsIHRoZQorICAgICAqIEludGVycnVwdGVkSU9FeGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgdGhlIHN0cmVhbSBpcyBhbHJlYWR5IGNsb3NlZCBvciBhbm90aGVyIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgb2NjdXJzLgorICAgICAqLworICAgIHN5bmNocm9uaXplZCB2b2lkIHJlY2VpdmUoY2hhcltdIGNoYXJzLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGNoYXJzLmxlbmd0aCwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgIGlmIChidWZmZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJQaXBlIGlzIGNsb3NlZCIpOworICAgICAgICB9CisgICAgICAgIGlmIChsYXN0UmVhZGVyICE9IG51bGwgJiYgIWxhc3RSZWFkZXIuaXNBbGl2ZSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlBpcGUgYnJva2VuIik7CisgICAgICAgIH0KKyAgICAgICAgLyoqCisgICAgICAgICAqIFNldCB0aGUgbGFzdCB0aHJlYWQgdG8gYmUgd3JpdGluZyBvbiB0aGlzIFBpcGVkV3JpdGVyLiBJZgorICAgICAgICAgKiBsYXN0V3JpdGVyIGRpZXMgd2hpbGUgc29tZW9uZSBpcyB3YWl0aW5nIHRvIHJlYWQgYW4gSU9FeGNlcHRpb24KKyAgICAgICAgICogb2YgIlBpcGUgYnJva2VuIiB3aWxsIGJlIHRocm93biBpbiByZWFkKCkKKyAgICAgICAgICovCisgICAgICAgIGxhc3RXcml0ZXIgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICB3aGlsZSAoY291bnQgPiAwKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHdoaWxlIChidWZmZXIgIT0gbnVsbCAmJiBvdXQgPT0gaW4pIHsKKyAgICAgICAgICAgICAgICAgICAgbm90aWZ5QWxsKCk7CisgICAgICAgICAgICAgICAgICAgIHdhaXQoMTAwMCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChsYXN0UmVhZGVyICE9IG51bGwgJiYgIWxhc3RSZWFkZXIuaXNBbGl2ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlBpcGUgYnJva2VuIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkSU9FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChidWZmZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUGlwZSBpcyBjbG9zZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpbiA9PSAtMSkgeworICAgICAgICAgICAgICAgIGluID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpbiA+PSBvdXQpIHsKKyAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gYnVmZmVyLmxlbmd0aCAtIGluOworICAgICAgICAgICAgICAgIGlmIChjb3VudCA8IGxlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSBjb3VudDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShjaGFycywgb2Zmc2V0LCBidWZmZXIsIGluLCBsZW5ndGgpOworICAgICAgICAgICAgICAgIG9mZnNldCArPSBsZW5ndGg7CisgICAgICAgICAgICAgICAgY291bnQgLT0gbGVuZ3RoOworICAgICAgICAgICAgICAgIGluICs9IGxlbmd0aDsKKyAgICAgICAgICAgICAgICBpZiAoaW4gPT0gYnVmZmVyLmxlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICBpbiA9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGNvdW50ID4gMCAmJiBpbiAhPSBvdXQpIHsKKyAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gb3V0IC0gaW47CisgICAgICAgICAgICAgICAgaWYgKGNvdW50IDwgbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IGNvdW50OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNoYXJzLCBvZmZzZXQsIGJ1ZmZlciwgaW4sIGxlbmd0aCk7CisgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IGxlbmd0aDsKKyAgICAgICAgICAgICAgICBjb3VudCAtPSBsZW5ndGg7CisgICAgICAgICAgICAgICAgaW4gKz0gbGVuZ3RoOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgc3luY2hyb25pemVkIHZvaWQgZG9uZSgpIHsKKyAgICAgICAgaXNDbG9zZWQgPSB0cnVlOworICAgICAgICBub3RpZnlBbGwoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9QaXBlZFdyaXRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vUGlwZWRXcml0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lY2U4OTlhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vUGlwZWRXcml0ZXIuamF2YQpAQCAtMCwwICsxLDE5MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBQbGFjZXMgaW5mb3JtYXRpb24gb24gYSBjb21tdW5pY2F0aW9ucyBwaXBlLiBXaGVuIHR3byB0aHJlYWRzIHdhbnQgdG8gcGFzcworICogZGF0YSBiYWNrIGFuZCBmb3J0aCwgb25lIGNyZWF0ZXMgYSBwaXBlZCB3cml0ZXIgYW5kIHRoZSBvdGhlciBjcmVhdGVzIGEgcGlwZWQKKyAqIHJlYWRlci4KKyAqCisgKiBAc2VlIFBpcGVkUmVhZGVyCisgKi8KK3B1YmxpYyBjbGFzcyBQaXBlZFdyaXRlciBleHRlbmRzIFdyaXRlciB7CisKKyAgICBwcml2YXRlIFBpcGVkUmVhZGVyIGRlc3RpbmF0aW9uOworICAgIHByaXZhdGUgYm9vbGVhbiBpc0Nsb3NlZDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgdW5jb25uZWN0ZWQge0Bjb2RlIFBpcGVkV3JpdGVyfS4gVGhlIHJlc3VsdGluZyB3cml0ZXIKKyAgICAgKiBtdXN0IGJlIGNvbm5lY3RlZCB0byBhIHtAY29kZSBQaXBlZFJlYWRlcn0gYmVmb3JlIGRhdGEgbWF5IGJlIHdyaXR0ZW4gdG8KKyAgICAgKiBpdC4KKyAgICAgKgorICAgICAqIEBzZWUgUGlwZWRSZWFkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgUGlwZWRXcml0ZXIoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUGlwZWRXcml0ZXJ9IGNvbm5lY3RlZCB0byB7QGNvZGUgZGVzdGluYXRpb259LgorICAgICAqIEFueSBkYXRhIHdyaXR0ZW4gdG8gdGhpcyB3cml0ZXIgY2FuIGJlIHJlYWQgZnJvbSB7QGNvZGUgZGVzdGluYXRpb259LgorICAgICAqCisgICAgICogQHBhcmFtIGRlc3RpbmF0aW9uCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIFBpcGVkUmVhZGVyfSB0byBjb25uZWN0IHRvLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGVzdGluYXRpb259IGlzIGFscmVhZHkgY29ubmVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyBQaXBlZFdyaXRlcihQaXBlZFJlYWRlciBkZXN0aW5hdGlvbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoZGVzdGluYXRpb24pOworICAgICAgICBjb25uZWN0KGRlc3RpbmF0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhpcyB3cml0ZXIuIElmIGEge0BsaW5rIFBpcGVkUmVhZGVyfSBpcyBjb25uZWN0ZWQgdG8gdGhpcyB3cml0ZXIsCisgICAgICogaXQgaXMgY2xvc2VkIGFzIHdlbGwgYW5kIHRoZSBwaXBlIGlzIGRpc2Nvbm5lY3RlZC4gQW55IGRhdGEgYnVmZmVyZWQgaW4KKyAgICAgKiB0aGUgcmVhZGVyIGNhbiBzdGlsbCBiZSByZWFkLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjbG9zaW5nIHRoaXMgd3JpdGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUGlwZWRSZWFkZXIgcmVhZGVyID0gZGVzdGluYXRpb247CisgICAgICAgIGlmIChyZWFkZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVhZGVyLmRvbmUoKTsKKyAgICAgICAgICAgIGlzQ2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgICAgIGRlc3RpbmF0aW9uID0gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbm5lY3RzIHRoaXMge0Bjb2RlIFBpcGVkV3JpdGVyfSB0byBhIHtAbGluayBQaXBlZFJlYWRlcn0uIEFueSBkYXRhCisgICAgICogd3JpdHRlbiB0byB0aGlzIHdyaXRlciBiZWNvbWVzIHJlYWRhYmxlIGluIHRoZSByZWFkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhZGVyCisgICAgICogICAgICAgICAgICB0aGUgcmVhZGVyIHRvIGNvbm5lY3QgdG8uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgd3JpdGVyIGlzIGNsb3NlZCBvciBhbHJlYWR5IGNvbm5lY3RlZCwgb3IgaWYge0Bjb2RlCisgICAgICogICAgICAgICAgICAgcmVhZGVyfSBpcyBhbHJlYWR5IGNvbm5lY3RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjb25uZWN0KFBpcGVkUmVhZGVyIHJlYWRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHJlYWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBzeW5jaHJvbml6ZWQgKHJlYWRlcikgeworICAgICAgICAgICAgaWYgKHRoaXMuZGVzdGluYXRpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUGlwZSBhbHJlYWR5IGNvbm5lY3RlZCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVhZGVyLmVzdGFibGlzaENvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgIHRoaXMubG9jayA9IHJlYWRlcjsKKyAgICAgICAgICAgIHRoaXMuZGVzdGluYXRpb24gPSByZWFkZXI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGUgcmVhZGVycyBvZiB0aGlzIHtAY29kZSBQaXBlZFJlYWRlcn0gdGhhdCBjaGFyYWN0ZXJzIGNhbiBiZSByZWFkLiBUaGlzCisgICAgICogbWV0aG9kIGRvZXMgbm90aGluZyBpZiB0aGlzIFdyaXRlciBpcyBub3QgY29ubmVjdGVkLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgZmx1c2hpbmcgdGhpcyB3cml0ZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBQaXBlZFJlYWRlciByZWFkZXIgPSBkZXN0aW5hdGlvbjsKKyAgICAgICAgaWYgKGlzQ2xvc2VkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlBpcGUgaXMgY2xvc2VkIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJlYWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBzeW5jaHJvbml6ZWQgKHJlYWRlcikgeworICAgICAgICAgICAgcmVhZGVyLm5vdGlmeUFsbCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHtAY29kZSBjb3VudH0gY2hhcmFjdGVycyBmcm9tIHRoZSBjaGFyYWN0ZXIgYXJyYXkge0Bjb2RlIGJ1ZmZlcn0KKyAgICAgKiBzdGFydGluZyBhdCBvZmZzZXQge0Bjb2RlIGluZGV4fSB0byB0aGlzIHdyaXRlci4gVGhlIHdyaXR0ZW4gZGF0YSBjYW4KKyAgICAgKiB0aGVuIGJlIHJlYWQgZnJvbSB0aGUgY29ubmVjdGVkIHtAbGluayBQaXBlZFJlYWRlcn0gaW5zdGFuY2UuCisgICAgICogPHA+CisgICAgICogU2VwYXJhdGUgdGhyZWFkcyBzaG91bGQgYmUgdXNlZCB0byB3cml0ZSB0byBhIHtAY29kZSBQaXBlZFdyaXRlcn0gYW5kIHRvCisgICAgICogcmVhZCBmcm9tIHRoZSBjb25uZWN0ZWQge0Bjb2RlIFBpcGVkUmVhZGVyfS4gSWYgdGhlIHNhbWUgdGhyZWFkIGlzIHVzZWQsCisgICAgICogYSBkZWFkbG9jayBtYXkgb2NjdXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHtAY29kZSBidWZmZXJ9IHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGZyb20ge0Bjb2RlIGJ1ZmZlcn0gdG8gd3JpdGUgdG8gdGhpcworICAgICAqICAgICAgICAgICAgd3JpdGVyLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwfSBvciB7QGNvZGUgY291bnQgPCAwfSwgb3IgaWYge0Bjb2RlCisgICAgICogICAgICAgICAgICAgb2Zmc2V0ICsgY291bnR9IGlzIGJpZ2dlciB0aGFuIHRoZSBsZW5ndGggb2Yge0Bjb2RlIGJ1ZmZlcn0uCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBpcGUgaXMgZnVsbCBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkCisgICAgICogICAgICAgICAgICAgd2FpdGluZyBmb3Igc3BhY2UgdG8gd3JpdGUgZGF0YS4gVGhpcyBjYXNlIGlzIG5vdCBjdXJyZW50bHkKKyAgICAgKiAgICAgICAgICAgICBoYW5kbGVkIGNvcnJlY3RseS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB3cml0ZXIgaXMgY2xvc2VkIG9yIG5vdCBjb25uZWN0ZWQsIGlmIHRoZSB0YXJnZXQKKyAgICAgKiAgICAgICAgICAgICByZWFkZXIgaXMgY2xvc2VkIG9yIGlmIHRoZSB0aHJlYWQgcmVhZGluZyBmcm9tIHRoZSB0YXJnZXQKKyAgICAgKiAgICAgICAgICAgICByZWFkZXIgaXMgbm8gbG9uZ2VyIGFsaXZlLiBUaGlzIGNhc2UgaXMgY3VycmVudGx5IG5vdCBoYW5kbGVkCisgICAgICogICAgICAgICAgICAgY29ycmVjdGx5LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYnVmZmVyfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoY2hhcltdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBQaXBlZFJlYWRlciByZWFkZXIgPSBkZXN0aW5hdGlvbjsKKyAgICAgICAgaWYgKHJlYWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlBpcGUgbm90IGNvbm5lY3RlZCIpOworICAgICAgICB9CisgICAgICAgIHJlYWRlci5yZWNlaXZlKGJ1ZmZlciwgb2Zmc2V0LCBjb3VudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgc2luZ2xlIGNoYXJhY3RlciB7QGNvZGUgY30gdG8gdGhpcyB3cml0ZXIuIFRoaXMgY2hhcmFjdGVyIGNhbgorICAgICAqIHRoZW4gYmUgcmVhZCBmcm9tIHRoZSBjb25uZWN0ZWQge0BsaW5rIFBpcGVkUmVhZGVyfSBpbnN0YW5jZS4KKyAgICAgKiA8cD4KKyAgICAgKiBTZXBhcmF0ZSB0aHJlYWRzIHNob3VsZCBiZSB1c2VkIHRvIHdyaXRlIHRvIGEge0Bjb2RlIFBpcGVkV3JpdGVyfSBhbmQgdG8KKyAgICAgKiByZWFkIGZyb20gdGhlIGNvbm5lY3RlZCB7QGNvZGUgUGlwZWRSZWFkZXJ9LiBJZiB0aGUgc2FtZSB0aHJlYWQgaXMgdXNlZCwKKyAgICAgKiBhIGRlYWRsb2NrIG1heSBvY2N1ci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwaXBlIGlzIGZ1bGwgYW5kIHRoZSBjdXJyZW50IHRocmVhZCBpcyBpbnRlcnJ1cHRlZAorICAgICAqICAgICAgICAgICAgIHdhaXRpbmcgZm9yIHNwYWNlIHRvIHdyaXRlIGRhdGEuIFRoaXMgY2FzZSBpcyBub3QgY3VycmVudGx5CisgICAgICogICAgICAgICAgICAgaGFuZGxlZCBjb3JyZWN0bHkuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgd3JpdGVyIGlzIGNsb3NlZCBvciBub3QgY29ubmVjdGVkLCBpZiB0aGUgdGFyZ2V0CisgICAgICogICAgICAgICAgICAgcmVhZGVyIGlzIGNsb3NlZCBvciBpZiB0aGUgdGhyZWFkIHJlYWRpbmcgZnJvbSB0aGUgdGFyZ2V0CisgICAgICogICAgICAgICAgICAgcmVhZGVyIGlzIG5vIGxvbmdlciBhbGl2ZS4gVGhpcyBjYXNlIGlzIGN1cnJlbnRseSBub3QgaGFuZGxlZAorICAgICAqICAgICAgICAgICAgIGNvcnJlY3RseS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgYykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUGlwZWRSZWFkZXIgcmVhZGVyID0gZGVzdGluYXRpb247CisgICAgICAgIGlmIChyZWFkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJQaXBlIG5vdCBjb25uZWN0ZWQiKTsKKyAgICAgICAgfQorICAgICAgICByZWFkZXIucmVjZWl2ZSgoY2hhcikgYyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vUHJpbnRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1ByaW50U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmE0OGIwNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1ByaW50U3RyZWFtLmphdmEKQEAgLTAsMCArMSw2NTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LklsbGVnYWxDaGFyc2V0TmFtZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Gb3JtYXR0ZXI7CitpbXBvcnQgamF2YS51dGlsLklsbGVnYWxGb3JtYXRFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworLyoqCisgKiBXcmFwcyBhbiBleGlzdGluZyB7QGxpbmsgT3V0cHV0U3RyZWFtfSBhbmQgcHJvdmlkZXMgY29udmVuaWVuY2UgbWV0aG9kcyBmb3IKKyAqIHdyaXRpbmcgY29tbW9uIGRhdGEgdHlwZXMgaW4gYSBodW1hbiByZWFkYWJsZSBmb3JtYXQuIFRoaXMgaXMgbm90IHRvIGJlCisgKiBjb25mdXNlZCB3aXRoIERhdGFPdXRwdXRTdHJlYW0gd2hpY2ggaXMgdXNlZCBmb3IgZW5jb2RpbmcgY29tbW9uIGRhdGEgdHlwZXMKKyAqIHNvIHRoYXQgdGhleSBjYW4gYmUgcmVhZCBiYWNrIGluLiBObyB7QGNvZGUgSU9FeGNlcHRpb259IGlzIHRocm93biBieSB0aGlzCisgKiBjbGFzcy4gSW5zdGVhZCwgY2FsbGVycyBzaG91bGQgdXNlIHtAbGluayAjY2hlY2tFcnJvcigpfSB0byBzZWUgaWYgYSBwcm9ibGVtCisgKiBoYXMgb2NjdXJyZWQgaW4gdGhpcyBzdHJlYW0uCisgKi8KK3B1YmxpYyBjbGFzcyBQcmludFN0cmVhbSBleHRlbmRzIEZpbHRlck91dHB1dFN0cmVhbSBpbXBsZW1lbnRzIEFwcGVuZGFibGUsIENsb3NlYWJsZSB7CisgICAgLyoqCisgICAgICogaW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoaXMgUHJpbnRTdHJlYW0gaGFzIGluY3VycmVkIGFuIGVycm9yLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpb0Vycm9yOworCisgICAgLyoqCisgICAgICogaW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoaXMgUHJpbnRTdHJlYW0gc2hvdWxkIGZsdXNoIGl0cyBjb250ZW50cyBhZnRlcgorICAgICAqIHByaW50aW5nIGEgbmV3IGxpbmUuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGF1dG9GbHVzaDsKKworICAgIHByaXZhdGUgU3RyaW5nIGVuY29kaW5nOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUHJpbnRTdHJlYW19IHdpdGgge0Bjb2RlIG91dH0gYXMgaXRzIHRhcmdldAorICAgICAqIHN0cmVhbS4gQnkgZGVmYXVsdCwgdGhlIG5ldyBwcmludCBzdHJlYW0gZG9lcyBub3QgYXV0b21hdGljYWxseSBmbHVzaCBpdHMKKyAgICAgKiBjb250ZW50cyB0byB0aGUgdGFyZ2V0IHN0cmVhbSB3aGVuIGEgbmV3bGluZSBpcyBlbmNvdW50ZXJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG91dH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBQcmludFN0cmVhbShPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIHN1cGVyKG91dCk7CisgICAgICAgIGlmIChvdXQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBQcmludFN0cmVhbX0gd2l0aCB7QGNvZGUgb3V0fSBhcyBpdHMgdGFyZ2V0CisgICAgICogc3RyZWFtLiBUaGUgcGFyYW1ldGVyIHtAY29kZSBhdXRvRmx1c2h9IGRldGVybWluZXMgaWYgdGhlIHByaW50IHN0cmVhbQorICAgICAqIGF1dG9tYXRpY2FsbHkgZmx1c2hlcyBpdHMgY29udGVudHMgdG8gdGhlIHRhcmdldCBzdHJlYW0gd2hlbiBhIG5ld2xpbmUgaXMKKyAgICAgKiBlbmNvdW50ZXJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gYXV0b0ZsdXNoCisgICAgICogICAgICAgICAgICBpbmRpY2F0ZXMgd2hldGhlciB0byBmbHVzaCBjb250ZW50cyB1cG9uIGVuY291bnRlcmluZyBhCisgICAgICogICAgICAgICAgICBuZXdsaW5lIHNlcXVlbmNlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb3V0fSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFByaW50U3RyZWFtKE91dHB1dFN0cmVhbSBvdXQsIGJvb2xlYW4gYXV0b0ZsdXNoKSB7CisgICAgICAgIHN1cGVyKG91dCk7CisgICAgICAgIGlmIChvdXQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5hdXRvRmx1c2ggPSBhdXRvRmx1c2g7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUHJpbnRTdHJlYW19IHdpdGgge0Bjb2RlIG91dH0gYXMgaXRzIHRhcmdldAorICAgICAqIHN0cmVhbSBhbmQgdXNpbmcgdGhlIGNoYXJhY3RlciBlbmNvZGluZyB7QGNvZGUgZW5jfSB3aGlsZSB3cml0aW5nLiBUaGUKKyAgICAgKiBwYXJhbWV0ZXIge0Bjb2RlIGF1dG9GbHVzaH0gZGV0ZXJtaW5lcyBpZiB0aGUgcHJpbnQgc3RyZWFtIGF1dG9tYXRpY2FsbHkKKyAgICAgKiBmbHVzaGVzIGl0cyBjb250ZW50cyB0byB0aGUgdGFyZ2V0IHN0cmVhbSB3aGVuIGEgbmV3bGluZSBpcyBlbmNvdW50ZXJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gYXV0b0ZsdXNoCisgICAgICogICAgICAgICAgICBpbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdG8gZmx1c2ggY29udGVudHMgdXBvbiBlbmNvdW50ZXJpbmcgYQorICAgICAqICAgICAgICAgICAgbmV3bGluZSBzZXF1ZW5jZS4KKyAgICAgKiBAcGFyYW0gZW5jCisgICAgICogICAgICAgICAgICB0aGUgbm9uLW51bGwgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIGRlc2lyZWQgY2hhcmFjdGVyIGVuY29kaW5nLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb3V0fSBvciB7QGNvZGUgZW5jfSBhcmUge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmNvZGluZyBzcGVjaWZpZWQgYnkge0Bjb2RlIGVuY30gaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpbnRTdHJlYW0oT3V0cHV0U3RyZWFtIG91dCwgYm9vbGVhbiBhdXRvRmx1c2gsIFN0cmluZyBlbmMpCisgICAgICAgICAgICB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKG91dCk7CisgICAgICAgIGlmIChvdXQgPT0gbnVsbCB8fCBlbmMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5hdXRvRmx1c2ggPSBhdXRvRmx1c2g7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoIUNoYXJzZXQuaXNTdXBwb3J0ZWQoZW5jKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uKGVuYyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxDaGFyc2V0TmFtZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbihlbmMpOworICAgICAgICB9CisgICAgICAgIGVuY29kaW5nID0gZW5jOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFByaW50U3RyZWFtfSB3aXRoIHtAY29kZSBmaWxlfSBhcyBpdHMgdGFyZ2V0LiBUaGUKKyAgICAgKiBWTSdzIGRlZmF1bHQgY2hhcmFjdGVyIHNldCBpcyB1c2VkIGZvciBjaGFyYWN0ZXIgZW5jb2RpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZQorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBmaWxlLiBJZiB0aGUgZmlsZSBhbHJlYWR5IGV4aXN0cywgaXRzIGNvbnRlbnRzIGFyZQorICAgICAqICAgICAgICAgICAgcmVtb3ZlZCwgb3RoZXJ3aXNlIGEgbmV3IGZpbGUgaXMgY3JlYXRlZC4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBvcGVuaW5nIG9yIGNyZWF0aW5nIHRoZSB0YXJnZXQgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpbnRTdHJlYW0oRmlsZSBmaWxlKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIobmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFByaW50U3RyZWFtfSB3aXRoIHtAY29kZSBmaWxlfSBhcyBpdHMgdGFyZ2V0LiBUaGUKKyAgICAgKiBjaGFyYWN0ZXIgc2V0IG5hbWVkIHtAY29kZSBjc259IGlzIHVzZWQgZm9yIGNoYXJhY3RlciBlbmNvZGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlCisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IGZpbGUuIElmIHRoZSBmaWxlIGFscmVhZHkgZXhpc3RzLCBpdHMgY29udGVudHMgYXJlCisgICAgICogICAgICAgICAgICByZW1vdmVkLCBvdGhlcndpc2UgYSBuZXcgZmlsZSBpcyBjcmVhdGVkLgorICAgICAqIEBwYXJhbSBjc24KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjaGFyYWN0ZXIgc2V0IHVzZWQgZm9yIGNoYXJhY3RlciBlbmNvZGluZy4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBvcGVuaW5nIG9yIGNyZWF0aW5nIHRoZSB0YXJnZXQgZmlsZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGNzbn0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmNvZGluZyBzcGVjaWZpZWQgYnkge0Bjb2RlIGNzbn0gaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpbnRTdHJlYW0oRmlsZSBmaWxlLCBTdHJpbmcgY3NuKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uLAorICAgICAgICAgICAgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZpbGUpKTsKKyAgICAgICAgaWYgKGNzbiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIUNoYXJzZXQuaXNTdXBwb3J0ZWQoY3NuKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24oY3NuKTsKKyAgICAgICAgfQorICAgICAgICBlbmNvZGluZyA9IGNzbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBQcmludFN0cmVhbX0gd2l0aCB0aGUgZmlsZSBpZGVudGlmaWVkIGJ5CisgICAgICoge0Bjb2RlIGZpbGVOYW1lfSBhcyBpdHMgdGFyZ2V0LiBUaGUgVk0ncyBkZWZhdWx0IGNoYXJhY3RlcgorICAgICAqIHNldCBpcyB1c2VkIGZvciBjaGFyYWN0ZXIgZW5jb2RpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgZmlsZSdzIG5hbWUuIElmIHRoZSBmaWxlIGFscmVhZHkgZXhpc3RzLCBpdHMKKyAgICAgKiAgICAgICAgICAgIGNvbnRlbnRzIGFyZSByZW1vdmVkLCBvdGhlcndpc2UgYSBuZXcgZmlsZSBpcyBjcmVhdGVkLgorICAgICAqIEB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIG9wZW5pbmcgb3IgY3JlYXRpbmcgdGhlIHRhcmdldCBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBQcmludFN0cmVhbShTdHJpbmcgZmlsZU5hbWUpIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICB0aGlzKG5ldyBGaWxlKGZpbGVOYW1lKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUHJpbnRTdHJlYW19IHdpdGggdGhlIGZpbGUgaWRlbnRpZmllZCBieQorICAgICAqIHtAY29kZSBmaWxlTmFtZX0gYXMgaXRzIHRhcmdldC4gVGhlIGNoYXJhY3RlciBzZXQgbmFtZWQge0Bjb2RlIGNzbn0gaXMKKyAgICAgKiB1c2VkIGZvciBjaGFyYWN0ZXIgZW5jb2RpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgZmlsZSdzIG5hbWUuIElmIHRoZSBmaWxlIGFscmVhZHkgZXhpc3RzLCBpdHMKKyAgICAgKiAgICAgICAgICAgIGNvbnRlbnRzIGFyZSByZW1vdmVkLCBvdGhlcndpc2UgYSBuZXcgZmlsZSBpcyBjcmVhdGVkLgorICAgICAqIEBwYXJhbSBjc24KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjaGFyYWN0ZXIgc2V0IHVzZWQgZm9yIGNoYXJhY3RlciBlbmNvZGluZy4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBvcGVuaW5nIG9yIGNyZWF0aW5nIHRoZSB0YXJnZXQgZmlsZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGNzbn0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmNvZGluZyBzcGVjaWZpZWQgYnkge0Bjb2RlIGNzbn0gaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpbnRTdHJlYW0oU3RyaW5nIGZpbGVOYW1lLCBTdHJpbmcgY3NuKQorICAgICAgICAgICAgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiwgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMobmV3IEZpbGUoZmlsZU5hbWUpLCBjc24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZsdXNoZXMgdGhpcyBzdHJlYW0gYW5kIHJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBlcnJvciBmbGFnLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgZWl0aGVyIGFuIHtAY29kZSBJT0V4Y2VwdGlvbn0gaGFzIGJlZW4gdGhyb3duCisgICAgICogICAgICAgICBwcmV2aW91c2x5IG9yIGlmIHtAY29kZSBzZXRFcnJvcigpfSBoYXMgYmVlbiBjYWxsZWQ7CisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNzZXRFcnJvcigpCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY2hlY2tFcnJvcigpIHsKKyAgICAgICAgT3V0cHV0U3RyZWFtIGRlbGVnYXRlID0gb3V0OworICAgICAgICBpZiAoZGVsZWdhdGUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGlvRXJyb3I7CisgICAgICAgIH0KKworICAgICAgICBmbHVzaCgpOworICAgICAgICByZXR1cm4gaW9FcnJvciB8fCBkZWxlZ2F0ZS5jaGVja0Vycm9yKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZXJyb3Igc3RhdGUgb2YgdGhlIHN0cmVhbSB0byBmYWxzZS4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgY2xlYXJFcnJvcigpIHsKKyAgICAgICAgaW9FcnJvciA9IGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGlzIHByaW50IHN0cmVhbS4gRmx1c2hlcyB0aGlzIHN0cmVhbSBhbmQgdGhlbiBjbG9zZXMgdGhlIHRhcmdldAorICAgICAqIHN0cmVhbS4gSWYgYW4gSS9PIGVycm9yIG9jY3VycywgdGhpcyBzdHJlYW0ncyBlcnJvciBzdGF0ZSBpcyBzZXQgdG8KKyAgICAgKiB7QGNvZGUgdHJ1ZX0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNsb3NlKCkgeworICAgICAgICBmbHVzaCgpOworICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgb3V0ID0gbnVsbDsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBzZXRFcnJvcigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5zdXJlcyB0aGF0IGFsbCBwZW5kaW5nIGRhdGEgaXMgc2VudCBvdXQgdG8gdGhlIHRhcmdldCBzdHJlYW0uIEl0IGFsc28KKyAgICAgKiBmbHVzaGVzIHRoZSB0YXJnZXQgc3RyZWFtLiBJZiBhbiBJL08gZXJyb3Igb2NjdXJzLCB0aGlzIHN0cmVhbSdzIGVycm9yCisgICAgICogc3RhdGUgaXMgc2V0IHRvIHtAY29kZSB0cnVlfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgZmx1c2goKSB7CisgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBvdXQuZmx1c2goKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gSWdub3JlZCwgZmFsbCB0aHJvdWdoIHRvIHNldEVycm9yCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgc2V0RXJyb3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGb3JtYXRzIHtAY29kZSBhcmdzfSBhY2NvcmRpbmcgdG8gdGhlIGZvcm1hdCBzdHJpbmcge0Bjb2RlIGZvcm1hdH0sIGFuZCB3cml0ZXMgdGhlIHJlc3VsdAorICAgICAqIHRvIHRoaXMgc3RyZWFtLiBUaGlzIG1ldGhvZCB1c2VzIHRoZSB1c2VyJ3MgZGVmYXVsdCBsb2NhbGUuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqCisgICAgICogQHBhcmFtIGZvcm1hdCB0aGUgZm9ybWF0IHN0cmluZyAoc2VlIHtAbGluayBqYXZhLnV0aWwuRm9ybWF0dGVyI2Zvcm1hdH0pCisgICAgICogQHBhcmFtIGFyZ3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IG9mIGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhlIGZvcm1hdHRlci4gSWYgdGhlcmUgYXJlCisgICAgICogICAgICAgICAgICBtb3JlIGFyZ3VtZW50cyB0aGFuIHJlcXVpcmVkIGJ5IHtAY29kZSBmb3JtYXR9LAorICAgICAqICAgICAgICAgICAgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIGlnbm9yZWQuCisgICAgICogQHJldHVybiB0aGlzIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZm9ybWF0IHN0cmluZyBpcyBpbGxlZ2FsIG9yIGluY29tcGF0aWJsZSB3aXRoIHRoZQorICAgICAqICAgICAgICAgICAgIGFyZ3VtZW50cywgaWYgdGhlcmUgYXJlIG5vdCBlbm91Z2ggYXJndW1lbnRzIG9yIGlmIGFueSBvdGhlcgorICAgICAqICAgICAgICAgICAgIGVycm9yIHJlZ2FyZGluZyB0aGUgZm9ybWF0IHN0cmluZyBvciBhcmd1bWVudHMgaXMgZGV0ZWN0ZWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgZm9ybWF0ID09IG51bGx9CisgICAgICovCisgICAgcHVibGljIFByaW50U3RyZWFtIGZvcm1hdChTdHJpbmcgZm9ybWF0LCBPYmplY3QuLi4gYXJncykgeworICAgICAgICByZXR1cm4gZm9ybWF0KExvY2FsZS5nZXREZWZhdWx0KCksIGZvcm1hdCwgYXJncyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgc3RyaW5nIGZvcm1hdHRlZCBieSBhbiBpbnRlcm1lZGlhdGUge0BsaW5rIEZvcm1hdHRlcn0gdG8gdGhpcworICAgICAqIHN0cmVhbSB1c2luZyB0aGUgc3BlY2lmaWVkIGxvY2FsZSwgZm9ybWF0IHN0cmluZyBhbmQgYXJndW1lbnRzLgorICAgICAqCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhbGUgdXNlZCBpbiB0aGUgbWV0aG9kLiBObyBsb2NhbGl6YXRpb24gd2lsbCBiZSBhcHBsaWVkCisgICAgICogICAgICAgICAgICBpZiB7QGNvZGUgbH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEBwYXJhbSBmb3JtYXQgdGhlIGZvcm1hdCBzdHJpbmcgKHNlZSB7QGxpbmsgamF2YS51dGlsLkZvcm1hdHRlciNmb3JtYXR9KQorICAgICAqIEBwYXJhbSBhcmdzCisgICAgICogICAgICAgICAgICB0aGUgbGlzdCBvZiBhcmd1bWVudHMgcGFzc2VkIHRvIHRoZSBmb3JtYXR0ZXIuIElmIHRoZXJlIGFyZQorICAgICAqICAgICAgICAgICAgbW9yZSBhcmd1bWVudHMgdGhhbiByZXF1aXJlZCBieSB7QGNvZGUgZm9ybWF0fSwKKyAgICAgKiAgICAgICAgICAgIGFkZGl0aW9uYWwgYXJndW1lbnRzIGFyZSBpZ25vcmVkLgorICAgICAqIEByZXR1cm4gdGhpcyBzdHJlYW0uCisgICAgICogQHRocm93cyBJbGxlZ2FsRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGZvcm1hdCBzdHJpbmcgaXMgaWxsZWdhbCBvciBpbmNvbXBhdGlibGUgd2l0aCB0aGUKKyAgICAgKiAgICAgICAgICAgICBhcmd1bWVudHMsIGlmIHRoZXJlIGFyZSBub3QgZW5vdWdoIGFyZ3VtZW50cyBvciBpZiBhbnkgb3RoZXIKKyAgICAgKiAgICAgICAgICAgICBlcnJvciByZWdhcmRpbmcgdGhlIGZvcm1hdCBzdHJpbmcgb3IgYXJndW1lbnRzIGlzIGRldGVjdGVkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIGZvcm1hdCA9PSBudWxsfQorICAgICAqLworICAgIHB1YmxpYyBQcmludFN0cmVhbSBmb3JtYXQoTG9jYWxlIGwsIFN0cmluZyBmb3JtYXQsIE9iamVjdC4uLiBhcmdzKSB7CisgICAgICAgIGlmIChmb3JtYXQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJmb3JtYXQgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIG5ldyBGb3JtYXR0ZXIodGhpcywgbCkuZm9ybWF0KGZvcm1hdCwgYXJncyk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50cyBhIGZvcm1hdHRlZCBzdHJpbmcuIFRoZSBiZWhhdmlvciBvZiB0aGlzIG1ldGhvZCBpcyB0aGUgc2FtZSBhcworICAgICAqIHRoaXMgc3RyZWFtJ3Mge0Bjb2RlICNmb3JtYXQoU3RyaW5nLCBPYmplY3QuLi4pfSBtZXRob2QuCisgICAgICoKKyAgICAgKiA8cD5UaGUge0Bjb2RlIExvY2FsZX0gdXNlZCBpcyB0aGUgdXNlcidzIGRlZmF1bHQgbG9jYWxlLgorICAgICAqIFNlZSAiPGEgaHJlZj0iLi4vdXRpbC9Mb2NhbGUuaHRtbCNkZWZhdWx0X2xvY2FsZSI+QmUgd2FyeSBvZiB0aGUgZGVmYXVsdCBsb2NhbGU8L2E+Ii4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmb3JtYXQgdGhlIGZvcm1hdCBzdHJpbmcgKHNlZSB7QGxpbmsgamF2YS51dGlsLkZvcm1hdHRlciNmb3JtYXR9KQorICAgICAqIEBwYXJhbSBhcmdzCisgICAgICogICAgICAgICAgICB0aGUgbGlzdCBvZiBhcmd1bWVudHMgcGFzc2VkIHRvIHRoZSBmb3JtYXR0ZXIuIElmIHRoZXJlIGFyZQorICAgICAqICAgICAgICAgICAgbW9yZSBhcmd1bWVudHMgdGhhbiByZXF1aXJlZCBieSB7QGNvZGUgZm9ybWF0fSwKKyAgICAgKiAgICAgICAgICAgIGFkZGl0aW9uYWwgYXJndW1lbnRzIGFyZSBpZ25vcmVkLgorICAgICAqIEByZXR1cm4gdGhpcyBzdHJlYW0uCisgICAgICogQHRocm93cyBJbGxlZ2FsRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGZvcm1hdCBzdHJpbmcgaXMgaWxsZWdhbCBvciBpbmNvbXBhdGlibGUgd2l0aCB0aGUKKyAgICAgKiAgICAgICAgICAgICBhcmd1bWVudHMsIGlmIHRoZXJlIGFyZSBub3QgZW5vdWdoIGFyZ3VtZW50cyBvciBpZiBhbnkgb3RoZXIKKyAgICAgKiAgICAgICAgICAgICBlcnJvciByZWdhcmRpbmcgdGhlIGZvcm1hdCBzdHJpbmcgb3IgYXJndW1lbnRzIGlzIGRldGVjdGVkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIGZvcm1hdCA9PSBudWxsfQorICAgICAqLworICAgIHB1YmxpYyBQcmludFN0cmVhbSBwcmludGYoU3RyaW5nIGZvcm1hdCwgT2JqZWN0Li4uIGFyZ3MpIHsKKyAgICAgICAgcmV0dXJuIGZvcm1hdChmb3JtYXQsIGFyZ3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50cyBhIGZvcm1hdHRlZCBzdHJpbmcuIFRoZSBiZWhhdmlvciBvZiB0aGlzIG1ldGhvZCBpcyB0aGUgc2FtZSBhcworICAgICAqIHRoaXMgc3RyZWFtJ3Mge0Bjb2RlICNmb3JtYXQoTG9jYWxlLCBTdHJpbmcsIE9iamVjdC4uLil9IG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUgbG9jYWxlIHVzZWQgaW4gdGhlIG1ldGhvZC4gTm8gbG9jYWxpemF0aW9uIHdpbGwgYmUgYXBwbGllZAorICAgICAqICAgICAgICAgICAgaWYge0Bjb2RlIGx9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAcGFyYW0gZm9ybWF0IHRoZSBmb3JtYXQgc3RyaW5nIChzZWUge0BsaW5rIGphdmEudXRpbC5Gb3JtYXR0ZXIjZm9ybWF0fSkKKyAgICAgKiBAcGFyYW0gYXJncworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgZm9ybWF0dGVyLiBJZiB0aGVyZSBhcmUKKyAgICAgKiAgICAgICAgICAgIG1vcmUgYXJndW1lbnRzIHRoYW4gcmVxdWlyZWQgYnkge0Bjb2RlIGZvcm1hdH0sCisgICAgICogICAgICAgICAgICBhZGRpdGlvbmFsIGFyZ3VtZW50cyBhcmUgaWdub3JlZC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBmb3JtYXQgc3RyaW5nIGlzIGlsbGVnYWwgb3IgaW5jb21wYXRpYmxlIHdpdGggdGhlCisgICAgICogICAgICAgICAgICAgYXJndW1lbnRzLCBpZiB0aGVyZSBhcmUgbm90IGVub3VnaCBhcmd1bWVudHMgb3IgaWYgYW55IG90aGVyCisgICAgICogICAgICAgICAgICAgZXJyb3IgcmVnYXJkaW5nIHRoZSBmb3JtYXQgc3RyaW5nIG9yIGFyZ3VtZW50cyBpcyBkZXRlY3RlZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBmb3JtYXQgPT0gbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFByaW50U3RyZWFtIHByaW50ZihMb2NhbGUgbCwgU3RyaW5nIGZvcm1hdCwgT2JqZWN0Li4uIGFyZ3MpIHsKKyAgICAgICAgcmV0dXJuIGZvcm1hdChsLCBmb3JtYXQsIGFyZ3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFB1dCB0aGUgbGluZSBzZXBhcmF0b3IgU3RyaW5nIG9udG8gdGhlIHByaW50IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgbmV3bGluZSgpIHsKKyAgICAgICAgcHJpbnQoU3lzdGVtLmxpbmVTZXBhcmF0b3IoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGNoYXJhY3RlciBhcnJheSB7QGNvZGUgY2hhcnN9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50KGNoYXJbXSBjaGFycykgeworICAgICAgICBwcmludChuZXcgU3RyaW5nKGNoYXJzLCAwLCBjaGFycy5sZW5ndGgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY2hhciB7QGNvZGUgY30uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJpbnQoY2hhciBjKSB7CisgICAgICAgIHByaW50KFN0cmluZy52YWx1ZU9mKGMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZG91YmxlIHtAY29kZSBkfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludChkb3VibGUgZCkgeworICAgICAgICBwcmludChTdHJpbmcudmFsdWVPZihkKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGZsb2F0IHtAY29kZSBmfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludChmbG9hdCBmKSB7CisgICAgICAgIHByaW50KFN0cmluZy52YWx1ZU9mKGYpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgaW50IHtAY29kZSBpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludChpbnQgaSkgeworICAgICAgICBwcmludChTdHJpbmcudmFsdWVPZihpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGxvbmcge0Bjb2RlIGx9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50KGxvbmcgbCkgeworICAgICAgICBwcmludChTdHJpbmcudmFsdWVPZihsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIE9iamVjdCB7QGNvZGUgb30sIG9yIHtAY29kZSAibnVsbCJ9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50KE9iamVjdCBvKSB7CisgICAgICAgIHByaW50KFN0cmluZy52YWx1ZU9mKG8pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgYSBzdHJpbmcgdG8gdGhlIHRhcmdldCBzdHJlYW0uIFRoZSBzdHJpbmcgaXMgY29udmVydGVkIHRvIGFuIGFycmF5CisgICAgICogb2YgYnl0ZXMgdXNpbmcgdGhlIGVuY29kaW5nIGNob3NlbiBkdXJpbmcgdGhlIGNvbnN0cnVjdGlvbiBvZiB0aGlzCisgICAgICogc3RyZWFtLiBUaGUgYnl0ZXMgYXJlIHRoZW4gd3JpdHRlbiB0byB0aGUgdGFyZ2V0IHN0cmVhbSB3aXRoCisgICAgICoge0Bjb2RlIHdyaXRlKGludCl9LgorICAgICAqCisgICAgICogPHA+SWYgYW4gSS9PIGVycm9yIG9jY3VycywgdGhpcyBzdHJlYW0ncyBlcnJvciBzdGF0ZSBpcyBzZXQgdG8ge0Bjb2RlIHRydWV9LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBwcmludCB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKiBAc2VlICN3cml0ZShpbnQpCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHByaW50KFN0cmluZyBzdHIpIHsKKyAgICAgICAgaWYgKG91dCA9PSBudWxsKSB7CisgICAgICAgICAgICBzZXRFcnJvcigpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGlmIChzdHIgPT0gbnVsbCkgeworICAgICAgICAgICAgcHJpbnQoIm51bGwiKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHdyaXRlKHN0ci5nZXRCeXRlcygpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgd3JpdGUoc3RyLmdldEJ5dGVzKGVuY29kaW5nKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHNldEVycm9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgYm9vbGVhbiB7QGNvZGUgYn0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJpbnQoYm9vbGVhbiBiKSB7CisgICAgICAgIHByaW50KFN0cmluZy52YWx1ZU9mKGIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgYSBuZXdsaW5lLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50bG4oKSB7CisgICAgICAgIG5ld2xpbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY2hhcmFjdGVyIGFycmF5IHtAY29kZSBjaGFyc30gZm9sbG93ZWQgYnkgYSBuZXdsaW5lLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50bG4oY2hhcltdIGNoYXJzKSB7CisgICAgICAgIHByaW50bG4obmV3IFN0cmluZyhjaGFycywgMCwgY2hhcnMubGVuZ3RoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGNoYXIge0Bjb2RlIGN9IGZvbGxvd2VkIGJ5IGEgbmV3bGluZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludGxuKGNoYXIgYykgeworICAgICAgICBwcmludGxuKFN0cmluZy52YWx1ZU9mKGMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZG91YmxlIHtAY29kZSBkfSBmb2xsb3dlZCBieSBhIG5ld2xpbmUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJpbnRsbihkb3VibGUgZCkgeworICAgICAgICBwcmludGxuKFN0cmluZy52YWx1ZU9mKGQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZmxvYXQge0Bjb2RlIGZ9IGZvbGxvd2VkIGJ5IGEgbmV3bGluZS4KKyAgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHByaW50bG4oZmxvYXQgZikgeworICAgICAgICBwcmludGxuKFN0cmluZy52YWx1ZU9mKGYpKTsKKyAgICB9CisKKyAgIC8qKgorICAgICAqIFByaW50cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBpbnQge0Bjb2RlIGl9IGZvbGxvd2VkIGJ5IGEgbmV3bGluZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludGxuKGludCBpKSB7CisgICAgICAgIHByaW50bG4oU3RyaW5nLnZhbHVlT2YoaSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBsb25nIHtAY29kZSBsfSBmb2xsb3dlZCBieSBhIG5ld2xpbmUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJpbnRsbihsb25nIGwpIHsKKyAgICAgICAgcHJpbnRsbihTdHJpbmcudmFsdWVPZihsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIE9iamVjdCB7QGNvZGUgb30sIG9yIHtAY29kZSAibnVsbCJ9LAorICAgICAqIGZvbGxvd2VkIGJ5IGEgbmV3bGluZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludGxuKE9iamVjdCBvKSB7CisgICAgICAgIHByaW50bG4oU3RyaW5nLnZhbHVlT2YobykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50cyBhIHN0cmluZyBmb2xsb3dlZCBieSBhIG5ld2xpbmUuIFRoZSBzdHJpbmcgaXMgY29udmVydGVkIHRvIGFuIGFycmF5IG9mIGJ5dGVzIHVzaW5nCisgICAgICogdGhlIGVuY29kaW5nIGNob3NlbiBkdXJpbmcgdGhlIGNvbnN0cnVjdGlvbiBvZiB0aGlzIHN0cmVhbS4gVGhlIGJ5dGVzIGFyZQorICAgICAqIHRoZW4gd3JpdHRlbiB0byB0aGUgdGFyZ2V0IHN0cmVhbSB3aXRoIHtAY29kZSB3cml0ZShpbnQpfS4KKyAgICAgKgorICAgICAqIDxwPklmIGFuIEkvTyBlcnJvciBvY2N1cnMsIHRoaXMgc3RyZWFtJ3MgZXJyb3Igc3RhdGUgaXMgc2V0IHRvIHtAY29kZSB0cnVlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gcHJpbnQgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHNlZSAjd3JpdGUoaW50KQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBwcmludGxuKFN0cmluZyBzdHIpIHsKKyAgICAgICAgcHJpbnQoc3RyKTsKKyAgICAgICAgbmV3bGluZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBib29sZWFuIHtAY29kZSBifSBmb2xsb3dlZCBieSBhIG5ld2xpbmUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJpbnRsbihib29sZWFuIGIpIHsKKyAgICAgICAgcHJpbnRsbihTdHJpbmcudmFsdWVPZihiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZXJyb3IgZmxhZyBvZiB0aGlzIHByaW50IHN0cmVhbSB0byB0cnVlLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldEVycm9yKCkgeworICAgICAgICBpb0Vycm9yID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMge0Bjb2RlIGNvdW50fSBieXRlcyBmcm9tIHtAY29kZSBidWZmZXJ9IHN0YXJ0aW5nIGF0IHtAY29kZSBvZmZzZXR9CisgICAgICogdG8gdGhlIHRhcmdldCBzdHJlYW0uIElmIGF1dG9GbHVzaCBpcyBzZXQsIHRoaXMgc3RyZWFtIGdldHMgZmx1c2hlZCBhZnRlcgorICAgICAqIHdyaXRpbmcgdGhlIGJ1ZmZlci4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgc3RyZWFtJ3MgZXJyb3IgZmxhZyBpcyBzZXQgdG8ge0Bjb2RlIHRydWV9IGlmIHRoaXMgc3RyZWFtIGlzIGNsb3NlZAorICAgICAqIG9yIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBieXRlIGluIHtAY29kZSBidWZmZXJ9IHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4ge0Bjb2RlIGJ1ZmZlcn0gdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBjb3VudCA8IDB9LCBvciBpZiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBvZmZzZXQgKyBjb3VudH0gaXMgYmlnZ2VyIHRoYW4gdGhlIGxlbmd0aCBvZiB7QGNvZGUgYnVmZmVyfS4KKyAgICAgKiBAc2VlICNmbHVzaCgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXIubGVuZ3RoLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgaWYgKG91dCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2V0RXJyb3IoKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG91dC53cml0ZShidWZmZXIsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBpZiAoYXV0b0ZsdXNoKSB7CisgICAgICAgICAgICAgICAgICAgIGZsdXNoKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHNldEVycm9yKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgb25lIGJ5dGUgdG8gdGhlIHRhcmdldCBzdHJlYW0uIE9ubHkgdGhlIGxlYXN0IHNpZ25pZmljYW50IGJ5dGUgb2YKKyAgICAgKiB0aGUgaW50ZWdlciB7QGNvZGUgb25lQnl0ZX0gaXMgd3JpdHRlbi4gVGhpcyBzdHJlYW0gaXMgZmx1c2hlZCBpZgorICAgICAqIHtAY29kZSBvbmVCeXRlfSBpcyBlcXVhbCB0byB0aGUgY2hhcmFjdGVyIHtAY29kZSAnXG4nfSBhbmQgdGhpcyBzdHJlYW0gaXMKKyAgICAgKiBzZXQgdG8gYXV0b0ZsdXNoLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgc3RyZWFtJ3MgZXJyb3IgZmxhZyBpcyBzZXQgdG8ge0Bjb2RlIHRydWV9IGlmIGl0IGlzIGNsb3NlZCBvciBhbiBJL08KKyAgICAgKiBlcnJvciBvY2N1cnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb25lQnl0ZQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgdG8gYmUgd3JpdHRlbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCB3cml0ZShpbnQgb25lQnl0ZSkgeworICAgICAgICBpZiAob3V0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHNldEVycm9yKCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG91dC53cml0ZShvbmVCeXRlKTsKKyAgICAgICAgICAgIGludCBiID0gb25lQnl0ZSAmIDB4RkY7CisgICAgICAgICAgICAvLyAweDBBIGlzIEFTQ0lJIG5ld2xpbmUsIDB4MTUgaXMgRUJDRElDIG5ld2xpbmUuCisgICAgICAgICAgICBib29sZWFuIGlzTmV3bGluZSA9IGIgPT0gMHgwQSB8fCBiID09IDB4MTU7CisgICAgICAgICAgICBpZiAoYXV0b0ZsdXNoICYmIGlzTmV3bGluZSkgeworICAgICAgICAgICAgICAgIGZsdXNoKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHNldEVycm9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHRoZSBjaGFyIHtAY29kZSBjfS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyBQcmludFN0cmVhbSBhcHBlbmQoY2hhciBjKSB7CisgICAgICAgIHByaW50KGMpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHRoZSBDaGFyU2VxdWVuY2Uge0Bjb2RlIGNoYXJTZXF1ZW5jZX0sIG9yIHtAY29kZSAibnVsbCJ9LgorICAgICAqIEByZXR1cm4gdGhpcyBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIFByaW50U3RyZWFtIGFwcGVuZChDaGFyU2VxdWVuY2UgY2hhclNlcXVlbmNlKSB7CisgICAgICAgIGlmIChjaGFyU2VxdWVuY2UgPT0gbnVsbCkgeworICAgICAgICAgICAgcHJpbnQoIm51bGwiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHByaW50KGNoYXJTZXF1ZW5jZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIGEgc3Vic2VxdWVuY2Ugb2YgQ2hhclNlcXVlbmNlIHtAY29kZSBjaGFyU2VxdWVuY2V9LCBvciB7QGNvZGUgIm51bGwifS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaGFyU2VxdWVuY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgYXBwZW5kZWQgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXIgaW4gdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSBhcHBlbmRlZAorICAgICAqICAgICAgICAgICAgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjaGFyYWN0ZXIgZm9sbG93aW5nIHRoZSBsYXN0IGNoYXJhY3RlciBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgIHN1YnNlcXVlbmNlIGFwcGVuZGVkIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAqIEByZXR1cm4gdGhpcyBzdHJlYW0uCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0ID4gZW5kfSwge0Bjb2RlIHN0YXJ0IDwgMH0sIHtAY29kZSBlbmQgPCAwfSBvcgorICAgICAqICAgICAgICAgICAgIGVpdGhlciB7QGNvZGUgc3RhcnR9IG9yIHtAY29kZSBlbmR9IGFyZSBncmVhdGVyIG9yIGVxdWFsIHRoYW4KKyAgICAgKiAgICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHtAY29kZSBjaGFyU2VxdWVuY2V9LgorICAgICAqLworICAgIHB1YmxpYyBQcmludFN0cmVhbSBhcHBlbmQoQ2hhclNlcXVlbmNlIGNoYXJTZXF1ZW5jZSwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIGlmIChjaGFyU2VxdWVuY2UgPT0gbnVsbCkgeworICAgICAgICAgICAgY2hhclNlcXVlbmNlID0gIm51bGwiOworICAgICAgICB9CisgICAgICAgIHByaW50KGNoYXJTZXF1ZW5jZS5zdWJTZXF1ZW5jZShzdGFydCwgZW5kKS50b1N0cmluZygpKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vUHJpbnRXcml0ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1ByaW50V3JpdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmE4OTBjOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1ByaW50V3JpdGVyLmphdmEKQEAgLTAsMCArMSw3MjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEudXRpbC5Gb3JtYXR0ZXI7CitpbXBvcnQgamF2YS51dGlsLklsbGVnYWxGb3JtYXRFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworLyoqCisgKiBXcmFwcyBlaXRoZXIgYW4gZXhpc3Rpbmcge0BsaW5rIE91dHB1dFN0cmVhbX0gb3IgYW4gZXhpc3Rpbmcge0BsaW5rIFdyaXRlcn0KKyAqIGFuZCBwcm92aWRlcyBjb252ZW5pZW5jZSBtZXRob2RzIGZvciBwcmludGluZyBjb21tb24gZGF0YSB0eXBlcyBpbiBhIGh1bWFuCisgKiByZWFkYWJsZSBmb3JtYXQuIE5vIHtAY29kZSBJT0V4Y2VwdGlvbn0gaXMgdGhyb3duIGJ5IHRoaXMgY2xhc3MuIEluc3RlYWQsCisgKiBjYWxsZXJzIHNob3VsZCB1c2Uge0BsaW5rICNjaGVja0Vycm9yKCl9IHRvIHNlZSBpZiBhIHByb2JsZW0gaGFzIG9jY3VycmVkIGluCisgKiB0aGlzIHdyaXRlci4KKyAqLworcHVibGljIGNsYXNzIFByaW50V3JpdGVyIGV4dGVuZHMgV3JpdGVyIHsKKyAgICAvKioKKyAgICAgKiBUaGUgd3JpdGVyIHRvIHByaW50IGRhdGEgdG8uCisgICAgICovCisgICAgcHJvdGVjdGVkIFdyaXRlciBvdXQ7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIFByaW50V3JpdGVyIGlzIGluIGFuIGVycm9yIHN0YXRlLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpb0Vycm9yOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoaXMgUHJpbnRXcml0ZXIgc2hvdWxkIGZsdXNoIGl0cyBjb250ZW50cyBhZnRlcgorICAgICAqIHByaW50aW5nIGEgbmV3IGxpbmUuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGF1dG9GbHVzaDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFByaW50V3JpdGVyfSB3aXRoIHtAY29kZSBvdXR9IGFzIGl0cyB0YXJnZXQKKyAgICAgKiBzdHJlYW0uIEJ5IGRlZmF1bHQsIHRoZSBuZXcgcHJpbnQgd3JpdGVyIGRvZXMgbm90IGF1dG9tYXRpY2FsbHkgZmx1c2ggaXRzCisgICAgICogY29udGVudHMgdG8gdGhlIHRhcmdldCBzdHJlYW0gd2hlbiBhIG5ld2xpbmUgaXMgZW5jb3VudGVyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IG91dHB1dCBzdHJlYW0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvdXR9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpbnRXcml0ZXIoT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgICB0aGlzKG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIob3V0KSwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFByaW50V3JpdGVyfSB3aXRoIHtAY29kZSBvdXR9IGFzIGl0cyB0YXJnZXQKKyAgICAgKiBzdHJlYW0uIFRoZSBwYXJhbWV0ZXIge0Bjb2RlIGF1dG9GbHVzaH0gZGV0ZXJtaW5lcyBpZiB0aGUgcHJpbnQgd3JpdGVyCisgICAgICogYXV0b21hdGljYWxseSBmbHVzaGVzIGl0cyBjb250ZW50cyB0byB0aGUgdGFyZ2V0IHN0cmVhbSB3aGVuIGEgbmV3bGluZSBpcworICAgICAqIGVuY291bnRlcmVkLgorICAgICAqCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBvdXRwdXQgc3RyZWFtLgorICAgICAqIEBwYXJhbSBhdXRvRmx1c2gKKyAgICAgKiAgICAgICAgICAgIGluZGljYXRlcyB3aGV0aGVyIGNvbnRlbnRzIGFyZSBmbHVzaGVkIHVwb24gZW5jb3VudGVyaW5nIGEKKyAgICAgKiAgICAgICAgICAgIG5ld2xpbmUgc2VxdWVuY2UuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvdXR9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpbnRXcml0ZXIoT3V0cHV0U3RyZWFtIG91dCwgYm9vbGVhbiBhdXRvRmx1c2gpIHsKKyAgICAgICAgdGhpcyhuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG91dCksIGF1dG9GbHVzaCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUHJpbnRXcml0ZXJ9IHdpdGgge0Bjb2RlIHdyfSBhcyBpdHMgdGFyZ2V0CisgICAgICogd3JpdGVyLiBCeSBkZWZhdWx0LCB0aGUgbmV3IHByaW50IHdyaXRlciBkb2VzIG5vdCBhdXRvbWF0aWNhbGx5IGZsdXNoIGl0cworICAgICAqIGNvbnRlbnRzIHRvIHRoZSB0YXJnZXQgd3JpdGVyIHdoZW4gYSBuZXdsaW5lIGlzIGVuY291bnRlcmVkLgorICAgICAqCisgICAgICogQHBhcmFtIHdyCisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IHdyaXRlci4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHdyfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFByaW50V3JpdGVyKFdyaXRlciB3cikgeworICAgICAgICB0aGlzKHdyLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUHJpbnRXcml0ZXJ9IHdpdGgge0Bjb2RlIG91dH0gYXMgaXRzIHRhcmdldAorICAgICAqIHdyaXRlci4gVGhlIHBhcmFtZXRlciB7QGNvZGUgYXV0b0ZsdXNofSBkZXRlcm1pbmVzIGlmIHRoZSBwcmludCB3cml0ZXIKKyAgICAgKiBhdXRvbWF0aWNhbGx5IGZsdXNoZXMgaXRzIGNvbnRlbnRzIHRvIHRoZSB0YXJnZXQgd3JpdGVyIHdoZW4gYSBuZXdsaW5lIGlzCisgICAgICogZW5jb3VudGVyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gd3IKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgd3JpdGVyLgorICAgICAqIEBwYXJhbSBhdXRvRmx1c2gKKyAgICAgKiAgICAgICAgICAgIGluZGljYXRlcyB3aGV0aGVyIHRvIGZsdXNoIGNvbnRlbnRzIHVwb24gZW5jb3VudGVyaW5nIGEKKyAgICAgKiAgICAgICAgICAgIG5ld2xpbmUgc2VxdWVuY2UuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvdXR9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpbnRXcml0ZXIoV3JpdGVyIHdyLCBib29sZWFuIGF1dG9GbHVzaCkgeworICAgICAgICBzdXBlcih3cik7CisgICAgICAgIHRoaXMuYXV0b0ZsdXNoID0gYXV0b0ZsdXNoOworICAgICAgICBvdXQgPSB3cjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBQcmludFdyaXRlcn0gd2l0aCB7QGNvZGUgZmlsZX0gYXMgaXRzIHRhcmdldC4gVGhlCisgICAgICogVk0ncyBkZWZhdWx0IGNoYXJhY3RlciBzZXQgaXMgdXNlZCBmb3IgY2hhcmFjdGVyIGVuY29kaW5nLgorICAgICAqIFRoZSBwcmludCB3cml0ZXIgZG9lcyBub3QgYXV0b21hdGljYWxseSBmbHVzaCBpdHMgY29udGVudHMgdG8gdGhlIHRhcmdldAorICAgICAqIGZpbGUgd2hlbiBhIG5ld2xpbmUgaXMgZW5jb3VudGVyZWQuIFRoZSBvdXRwdXQgdG8gdGhlIGZpbGUgaXMgYnVmZmVyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZQorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBmaWxlLiBJZiB0aGUgZmlsZSBhbHJlYWR5IGV4aXN0cywgaXRzIGNvbnRlbnRzIGFyZQorICAgICAqICAgICAgICAgICAgcmVtb3ZlZCwgb3RoZXJ3aXNlIGEgbmV3IGZpbGUgaXMgY3JlYXRlZC4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBvcGVuaW5nIG9yIGNyZWF0aW5nIHRoZSB0YXJnZXQgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpbnRXcml0ZXIoRmlsZSBmaWxlKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlKSkpLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUHJpbnRXcml0ZXJ9IHdpdGgge0Bjb2RlIGZpbGV9IGFzIGl0cyB0YXJnZXQuIFRoZQorICAgICAqIGNoYXJhY3RlciBzZXQgbmFtZWQge0Bjb2RlIGNzbn0gaXMgdXNlZCBmb3IgY2hhcmFjdGVyIGVuY29kaW5nLgorICAgICAqIFRoZSBwcmludCB3cml0ZXIgZG9lcyBub3QgYXV0b21hdGljYWxseSBmbHVzaCBpdHMgY29udGVudHMgdG8gdGhlIHRhcmdldAorICAgICAqIGZpbGUgd2hlbiBhIG5ld2xpbmUgaXMgZW5jb3VudGVyZWQuIFRoZSBvdXRwdXQgdG8gdGhlIGZpbGUgaXMgYnVmZmVyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZQorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBmaWxlLiBJZiB0aGUgZmlsZSBhbHJlYWR5IGV4aXN0cywgaXRzIGNvbnRlbnRzIGFyZQorICAgICAqICAgICAgICAgICAgcmVtb3ZlZCwgb3RoZXJ3aXNlIGEgbmV3IGZpbGUgaXMgY3JlYXRlZC4KKyAgICAgKiBAcGFyYW0gY3NuCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY2hhcmFjdGVyIHNldCB1c2VkIGZvciBjaGFyYWN0ZXIgZW5jb2RpbmcuCisgICAgICogQHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgb3BlbmluZyBvciBjcmVhdGluZyB0aGUgdGFyZ2V0IGZpbGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBjc259IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZW5jb2Rpbmcgc3BlY2lmaWVkIGJ5IHtAY29kZSBjc259IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIFByaW50V3JpdGVyKEZpbGUgZmlsZSwgU3RyaW5nIGNzbikgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiwKKyAgICAgICAgICAgIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgICAgICB0aGlzKG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIobmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZpbGUpKSwgY3NuKSwKKyAgICAgICAgICAgICAgICBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUHJpbnRXcml0ZXJ9IHdpdGggdGhlIGZpbGUgaWRlbnRpZmllZCBieSB7QGNvZGUKKyAgICAgKiBmaWxlTmFtZX0gYXMgaXRzIHRhcmdldC4gVGhlIFZNJ3MgZGVmYXVsdCBjaGFyYWN0ZXIgc2V0IGlzCisgICAgICogdXNlZCBmb3IgY2hhcmFjdGVyIGVuY29kaW5nLiBUaGUgcHJpbnQgd3JpdGVyIGRvZXMgbm90IGF1dG9tYXRpY2FsbHkKKyAgICAgKiBmbHVzaCBpdHMgY29udGVudHMgdG8gdGhlIHRhcmdldCBmaWxlIHdoZW4gYSBuZXdsaW5lIGlzIGVuY291bnRlcmVkLiBUaGUKKyAgICAgKiBvdXRwdXQgdG8gdGhlIGZpbGUgaXMgYnVmZmVyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgZmlsZSdzIG5hbWUuIElmIHRoZSBmaWxlIGFscmVhZHkgZXhpc3RzLCBpdHMKKyAgICAgKiAgICAgICAgICAgIGNvbnRlbnRzIGFyZSByZW1vdmVkLCBvdGhlcndpc2UgYSBuZXcgZmlsZSBpcyBjcmVhdGVkLgorICAgICAqIEB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIG9wZW5pbmcgb3IgY3JlYXRpbmcgdGhlIHRhcmdldCBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBQcmludFdyaXRlcihTdHJpbmcgZmlsZU5hbWUpIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICB0aGlzKG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIobmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZpbGVOYW1lKSkpLAorICAgICAgICAgICAgICAgIGZhbHNlKTsKKyAgICB9CisKKyAgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUHJpbnRXcml0ZXJ9IHdpdGggdGhlIGZpbGUgaWRlbnRpZmllZCBieSB7QGNvZGUKKyAgICAgKiBmaWxlTmFtZX0gYXMgaXRzIHRhcmdldC4gVGhlIGNoYXJhY3RlciBzZXQgbmFtZWQge0Bjb2RlIGNzbn0gaXMgdXNlZCBmb3IKKyAgICAgKiBjaGFyYWN0ZXIgZW5jb2RpbmcuIFRoZSBwcmludCB3cml0ZXIgZG9lcyBub3QgYXV0b21hdGljYWxseSBmbHVzaCBpdHMKKyAgICAgKiBjb250ZW50cyB0byB0aGUgdGFyZ2V0IGZpbGUgd2hlbiBhIG5ld2xpbmUgaXMgZW5jb3VudGVyZWQuIFRoZSBvdXRwdXQgdG8KKyAgICAgKiB0aGUgZmlsZSBpcyBidWZmZXJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBmaWxlJ3MgbmFtZS4gSWYgdGhlIGZpbGUgYWxyZWFkeSBleGlzdHMsIGl0cworICAgICAqICAgICAgICAgICAgY29udGVudHMgYXJlIHJlbW92ZWQsIG90aGVyd2lzZSBhIG5ldyBmaWxlIGlzIGNyZWF0ZWQuCisgICAgICogQHBhcmFtIGNzbgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNoYXJhY3RlciBzZXQgdXNlZCBmb3IgY2hhcmFjdGVyIGVuY29kaW5nLgorICAgICAqIEB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIG9wZW5pbmcgb3IgY3JlYXRpbmcgdGhlIHRhcmdldCBmaWxlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY3NufSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGVuY29kaW5nIHNwZWNpZmllZCBieSB7QGNvZGUgY3NufSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBQcmludFdyaXRlcihTdHJpbmcgZmlsZU5hbWUsIFN0cmluZyBjc24pCisgICAgICAgICAgICB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uLCBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlTmFtZSkpLCBjc24pLAorICAgICAgICAgICAgICAgIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIHRoaXMgd3JpdGVyIGFuZCByZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgZXJyb3IgZmxhZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGVpdGhlciBhbiB7QGNvZGUgSU9FeGNlcHRpb259IGhhcyBiZWVuIHRocm93bgorICAgICAqICAgICAgICAgcHJldmlvdXNseSBvciBpZiB7QGNvZGUgc2V0RXJyb3IoKX0gaGFzIGJlZW4gY2FsbGVkOworICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNlZSAjc2V0RXJyb3IoKQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNoZWNrRXJyb3IoKSB7CisgICAgICAgIFdyaXRlciBkZWxlZ2F0ZSA9IG91dDsKKyAgICAgICAgaWYgKGRlbGVnYXRlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBpb0Vycm9yOworICAgICAgICB9CisKKyAgICAgICAgZmx1c2goKTsKKyAgICAgICAgcmV0dXJuIGlvRXJyb3IgfHwgZGVsZWdhdGUuY2hlY2tFcnJvcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGVycm9yIHN0YXRlIG9mIHRoZSBzdHJlYW0gdG8gZmFsc2UuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGNsZWFyRXJyb3IoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgaW9FcnJvciA9IGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgcHJpbnQgd3JpdGVyLiBGbHVzaGVzIHRoaXMgd3JpdGVyIGFuZCB0aGVuIGNsb3NlcyB0aGUgdGFyZ2V0LgorICAgICAqIElmIGFuIEkvTyBlcnJvciBvY2N1cnMsIHRoaXMgd3JpdGVyJ3MgZXJyb3IgZmxhZyBpcyBzZXQgdG8ge0Bjb2RlIHRydWV9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgc2V0RXJyb3IoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgb3V0ID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEVuc3VyZXMgdGhhdCBhbGwgcGVuZGluZyBkYXRhIGlzIHNlbnQgb3V0IHRvIHRoZSB0YXJnZXQuIEl0IGFsc28KKyAgICAgKiBmbHVzaGVzIHRoZSB0YXJnZXQuIElmIGFuIEkvTyBlcnJvciBvY2N1cnMsIHRoaXMgd3JpdGVyJ3MgZXJyb3IKKyAgICAgKiBzdGF0ZSBpcyBzZXQgdG8ge0Bjb2RlIHRydWV9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgc2V0RXJyb3IoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHNldEVycm9yKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGb3JtYXRzIHtAY29kZSBhcmdzfSBhY2NvcmRpbmcgdG8gdGhlIGZvcm1hdCBzdHJpbmcge0Bjb2RlIGZvcm1hdH0sIGFuZCB3cml0ZXMgdGhlIHJlc3VsdAorICAgICAqIHRvIHRoaXMgc3RyZWFtLiBUaGlzIG1ldGhvZCB1c2VzIHRoZSB1c2VyJ3MgZGVmYXVsdCBsb2NhbGUuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqIElmIGF1dG9tYXRpYyBmbHVzaGluZyBpcyBlbmFibGVkIHRoZW4gdGhlIGJ1ZmZlciBpcyBmbHVzaGVkIGFzIHdlbGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9ybWF0IHRoZSBmb3JtYXQgc3RyaW5nIChzZWUge0BsaW5rIGphdmEudXRpbC5Gb3JtYXR0ZXIjZm9ybWF0fSkKKyAgICAgKiBAcGFyYW0gYXJncworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgZm9ybWF0dGVyLiBJZiB0aGVyZSBhcmUKKyAgICAgKiAgICAgICAgICAgIG1vcmUgYXJndW1lbnRzIHRoYW4gcmVxdWlyZWQgYnkge0Bjb2RlIGZvcm1hdH0sCisgICAgICogICAgICAgICAgICBhZGRpdGlvbmFsIGFyZ3VtZW50cyBhcmUgaWdub3JlZC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgd3JpdGVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBmb3JtYXQgc3RyaW5nIGlzIGlsbGVnYWwgb3IgaW5jb21wYXRpYmxlIHdpdGggdGhlCisgICAgICogICAgICAgICAgICAgYXJndW1lbnRzLCBpZiB0aGVyZSBhcmUgbm90IGVub3VnaCBhcmd1bWVudHMgb3IgaWYgYW55IG90aGVyCisgICAgICogICAgICAgICAgICAgZXJyb3IgcmVnYXJkaW5nIHRoZSBmb3JtYXQgc3RyaW5nIG9yIGFyZ3VtZW50cyBpcyBkZXRlY3RlZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBmb3JtYXQgPT0gbnVsbH0KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpbnRXcml0ZXIgZm9ybWF0KFN0cmluZyBmb3JtYXQsIE9iamVjdC4uLiBhcmdzKSB7CisgICAgICAgIHJldHVybiBmb3JtYXQoTG9jYWxlLmdldERlZmF1bHQoKSwgZm9ybWF0LCBhcmdzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBzdHJpbmcgZm9ybWF0dGVkIGJ5IGFuIGludGVybWVkaWF0ZSB7QGNvZGUgRm9ybWF0dGVyfSB0byB0aGUKKyAgICAgKiB0YXJnZXQgdXNpbmcgdGhlIHNwZWNpZmllZCBsb2NhbGUsIGZvcm1hdCBzdHJpbmcgYW5kIGFyZ3VtZW50cy4gSWYKKyAgICAgKiBhdXRvbWF0aWMgZmx1c2hpbmcgaXMgZW5hYmxlZCB0aGVuIHRoaXMgd3JpdGVyIGlzIGZsdXNoZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsZSB1c2VkIGluIHRoZSBtZXRob2QuIE5vIGxvY2FsaXphdGlvbiB3aWxsIGJlIGFwcGxpZWQKKyAgICAgKiAgICAgICAgICAgIGlmIHtAY29kZSBsfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHBhcmFtIGZvcm1hdCB0aGUgZm9ybWF0IHN0cmluZyAoc2VlIHtAbGluayBqYXZhLnV0aWwuRm9ybWF0dGVyI2Zvcm1hdH0pCisgICAgICogQHBhcmFtIGFyZ3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IG9mIGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhlIGZvcm1hdHRlci4gSWYgdGhlcmUgYXJlCisgICAgICogICAgICAgICAgICBtb3JlIGFyZ3VtZW50cyB0aGFuIHJlcXVpcmVkIGJ5IHtAY29kZSBmb3JtYXR9LAorICAgICAqICAgICAgICAgICAgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIGlnbm9yZWQuCisgICAgICogQHJldHVybiB0aGlzIHdyaXRlci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZm9ybWF0IHN0cmluZyBpcyBpbGxlZ2FsIG9yIGluY29tcGF0aWJsZSB3aXRoIHRoZQorICAgICAqICAgICAgICAgICAgIGFyZ3VtZW50cywgaWYgdGhlcmUgYXJlIG5vdCBlbm91Z2ggYXJndW1lbnRzIG9yIGlmIGFueSBvdGhlcgorICAgICAqICAgICAgICAgICAgIGVycm9yIHJlZ2FyZGluZyB0aGUgZm9ybWF0IHN0cmluZyBvciBhcmd1bWVudHMgaXMgZGV0ZWN0ZWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgZm9ybWF0ID09IG51bGx9CisgICAgICovCisgICAgcHVibGljIFByaW50V3JpdGVyIGZvcm1hdChMb2NhbGUgbCwgU3RyaW5nIGZvcm1hdCwgT2JqZWN0Li4uIGFyZ3MpIHsKKyAgICAgICAgaWYgKGZvcm1hdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImZvcm1hdCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgbmV3IEZvcm1hdHRlcih0aGlzLCBsKS5mb3JtYXQoZm9ybWF0LCBhcmdzKTsKKyAgICAgICAgaWYgKGF1dG9GbHVzaCkgeworICAgICAgICAgICAgZmx1c2goKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgYSBmb3JtYXR0ZWQgc3RyaW5nLiBUaGUgYmVoYXZpb3Igb2YgdGhpcyBtZXRob2QgaXMgdGhlIHNhbWUgYXMKKyAgICAgKiB0aGlzIHdyaXRlcidzIHtAY29kZSAjZm9ybWF0KFN0cmluZywgT2JqZWN0Li4uKX0gbWV0aG9kLgorICAgICAqCisgICAgICogPHA+VGhlIHtAY29kZSBMb2NhbGV9IHVzZWQgaXMgdGhlIHVzZXIncyBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKiBTZWUgIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9ybWF0IHRoZSBmb3JtYXQgc3RyaW5nIChzZWUge0BsaW5rIGphdmEudXRpbC5Gb3JtYXR0ZXIjZm9ybWF0fSkKKyAgICAgKiBAcGFyYW0gYXJncworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgZm9ybWF0dGVyLiBJZiB0aGVyZSBhcmUKKyAgICAgKiAgICAgICAgICAgIG1vcmUgYXJndW1lbnRzIHRoYW4gcmVxdWlyZWQgYnkge0Bjb2RlIGZvcm1hdH0sCisgICAgICogICAgICAgICAgICBhZGRpdGlvbmFsIGFyZ3VtZW50cyBhcmUgaWdub3JlZC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgd3JpdGVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBmb3JtYXQgc3RyaW5nIGlzIGlsbGVnYWwgb3IgaW5jb21wYXRpYmxlIHdpdGggdGhlCisgICAgICogICAgICAgICAgICAgYXJndW1lbnRzLCBpZiB0aGVyZSBhcmUgbm90IGVub3VnaCBhcmd1bWVudHMgb3IgaWYgYW55IG90aGVyCisgICAgICogICAgICAgICAgICAgZXJyb3IgcmVnYXJkaW5nIHRoZSBmb3JtYXQgc3RyaW5nIG9yIGFyZ3VtZW50cyBpcyBkZXRlY3RlZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBmb3JtYXQgPT0gbnVsbH0KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpbnRXcml0ZXIgcHJpbnRmKFN0cmluZyBmb3JtYXQsIE9iamVjdC4uLiBhcmdzKSB7CisgICAgICAgIHJldHVybiBmb3JtYXQoZm9ybWF0LCBhcmdzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgYSBmb3JtYXR0ZWQgc3RyaW5nLiBUaGUgYmVoYXZpb3Igb2YgdGhpcyBtZXRob2QgaXMgdGhlIHNhbWUgYXMKKyAgICAgKiB0aGlzIHdyaXRlcidzIHtAY29kZSAjZm9ybWF0KExvY2FsZSwgU3RyaW5nLCBPYmplY3QuLi4pfSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsZSB1c2VkIGluIHRoZSBtZXRob2QuIE5vIGxvY2FsaXphdGlvbiB3aWxsIGJlIGFwcGxpZWQKKyAgICAgKiAgICAgICAgICAgIGlmIHtAY29kZSBsfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHBhcmFtIGZvcm1hdCB0aGUgZm9ybWF0IHN0cmluZyAoc2VlIHtAbGluayBqYXZhLnV0aWwuRm9ybWF0dGVyI2Zvcm1hdH0pCisgICAgICogQHBhcmFtIGFyZ3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IG9mIGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhlIGZvcm1hdHRlci4gSWYgdGhlcmUgYXJlCisgICAgICogICAgICAgICAgICBtb3JlIGFyZ3VtZW50cyB0aGFuIHJlcXVpcmVkIGJ5IHtAY29kZSBmb3JtYXR9LAorICAgICAqICAgICAgICAgICAgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIGlnbm9yZWQuCisgICAgICogQHJldHVybiB0aGlzIHdyaXRlci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZm9ybWF0IHN0cmluZyBpcyBpbGxlZ2FsIG9yIGluY29tcGF0aWJsZSB3aXRoIHRoZQorICAgICAqICAgICAgICAgICAgIGFyZ3VtZW50cywgaWYgdGhlcmUgYXJlIG5vdCBlbm91Z2ggYXJndW1lbnRzIG9yIGlmIGFueSBvdGhlcgorICAgICAqICAgICAgICAgICAgIGVycm9yIHJlZ2FyZGluZyB0aGUgZm9ybWF0IHN0cmluZyBvciBhcmd1bWVudHMgaXMgZGV0ZWN0ZWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgZm9ybWF0ID09IG51bGx9CisgICAgICovCisgICAgcHVibGljIFByaW50V3JpdGVyIHByaW50ZihMb2NhbGUgbCwgU3RyaW5nIGZvcm1hdCwgT2JqZWN0Li4uIGFyZ3MpIHsKKyAgICAgICAgcmV0dXJuIGZvcm1hdChsLCBmb3JtYXQsIGFyZ3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGFycmF5CisgICAgICogdG8gdGhlIHRhcmdldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaGFyQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgYXJyYXkgdG8gcHJpbnQgdG8gdGhlIHRhcmdldC4KKyAgICAgKiBAc2VlICNwcmludChTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJpbnQoY2hhcltdIGNoYXJBcnJheSkgeworICAgICAgICBwcmludChuZXcgU3RyaW5nKGNoYXJBcnJheSwgMCwgY2hhckFycmF5Lmxlbmd0aCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIHRvIHRoZQorICAgICAqIHRhcmdldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaAorICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byBwcmludCB0byB0aGUgdGFyZ2V0LgorICAgICAqIEBzZWUgI3ByaW50KFN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludChjaGFyIGNoKSB7CisgICAgICAgIHByaW50KFN0cmluZy52YWx1ZU9mKGNoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCBkb3VibGUgdG8gdGhlIHRhcmdldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkbnVtCisgICAgICogICAgICAgICAgICB0aGUgZG91YmxlIHZhbHVlIHRvIHByaW50IHRvIHRoZSB0YXJnZXQuCisgICAgICogQHNlZSAjcHJpbnQoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50KGRvdWJsZSBkbnVtKSB7CisgICAgICAgIHByaW50KFN0cmluZy52YWx1ZU9mKGRudW0pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIGZsb2F0IHRvIHRoZSB0YXJnZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm51bQorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IHZhbHVlIHRvIHByaW50IHRvIHRoZSB0YXJnZXQuCisgICAgICogQHNlZSAjcHJpbnQoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50KGZsb2F0IGZudW0pIHsKKyAgICAgICAgcHJpbnQoU3RyaW5nLnZhbHVlT2YoZm51bSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQgaW50ZWdlciB0byB0aGUgdGFyZ2V0LgorICAgICAqCisgICAgICogQHBhcmFtIGludW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlZ2VyIHZhbHVlIHRvIHByaW50IHRvIHRoZSB0YXJnZXQuCisgICAgICogQHNlZSAjcHJpbnQoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50KGludCBpbnVtKSB7CisgICAgICAgIHByaW50KFN0cmluZy52YWx1ZU9mKGludW0pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIGxvbmcgdG8gdGhlIHRhcmdldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsbnVtCisgICAgICogICAgICAgICAgICB0aGUgbG9uZyB2YWx1ZSB0byBwcmludCB0byB0aGUgdGFyZ2V0LgorICAgICAqIEBzZWUgI3ByaW50KFN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludChsb25nIGxudW0pIHsKKyAgICAgICAgcHJpbnQoU3RyaW5nLnZhbHVlT2YobG51bSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHRvIHRoZSB0YXJnZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIHByaW50IHRvIHRoZSB0YXJnZXQuCisgICAgICogQHNlZSAjcHJpbnQoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50KE9iamVjdCBvYmopIHsKKyAgICAgICAgcHJpbnQoU3RyaW5nLnZhbHVlT2Yob2JqKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnRzIGEgc3RyaW5nIHRvIHRoZSB0YXJnZXQuIFRoZSBzdHJpbmcgaXMgY29udmVydGVkIHRvIGFuIGFycmF5IG9mCisgICAgICogYnl0ZXMgdXNpbmcgdGhlIGVuY29kaW5nIGNob3NlbiBkdXJpbmcgdGhlIGNvbnN0cnVjdGlvbiBvZiB0aGlzIHdyaXRlci4KKyAgICAgKiBUaGUgYnl0ZXMgYXJlIHRoZW4gd3JpdHRlbiB0byB0aGUgdGFyZ2V0IHdpdGgge0Bjb2RlIHdyaXRlKGludCl9LgorICAgICAqIDxwPgorICAgICAqIElmIGFuIEkvTyBlcnJvciBvY2N1cnMsIHRoaXMgd3JpdGVyJ3MgZXJyb3IgZmxhZyBpcyBzZXQgdG8ge0Bjb2RlIHRydWV9LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBwcmludCB0byB0aGUgdGFyZ2V0LgorICAgICAqIEBzZWUgI3dyaXRlKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludChTdHJpbmcgc3RyKSB7CisgICAgICAgIHdyaXRlKHN0ciAhPSBudWxsID8gc3RyIDogU3RyaW5nLnZhbHVlT2YoKE9iamVjdCkgbnVsbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQgYm9vbGVhbiB0byB0aGUgdGFyZ2V0LgorICAgICAqCisgICAgICogQHBhcmFtIGJvb2wKKyAgICAgKiAgICAgICAgICAgIHRoZSBib29sZWFuIHZhbHVlIHRvIHByaW50IHRoZSB0YXJnZXQuCisgICAgICogQHNlZSAjcHJpbnQoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50KGJvb2xlYW4gYm9vbCkgeworICAgICAgICBwcmludChTdHJpbmcudmFsdWVPZihib29sKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnRzIGEgbmV3bGluZS4gRmx1c2hlcyB0aGlzIHdyaXRlciBpZiB0aGUgYXV0b0ZsdXNoIGZsYWcgaXMgc2V0IHRvIHtAY29kZSB0cnVlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludGxuKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIHByaW50KFN5c3RlbS5saW5lU2VwYXJhdG9yKCkpOworICAgICAgICAgICAgaWYgKGF1dG9GbHVzaCkgeworICAgICAgICAgICAgICAgIGZsdXNoKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY2hhcmFjdGVyIGFycmF5IHtAY29kZSBjaGFyc30gZm9sbG93ZWQgYnkgYSBuZXdsaW5lLgorICAgICAqIEZsdXNoZXMgdGhpcyB3cml0ZXIgaWYgdGhlIGF1dG9GbHVzaCBmbGFnIGlzIHNldCB0byB7QGNvZGUgdHJ1ZX0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJpbnRsbihjaGFyW10gY2hhcnMpIHsKKyAgICAgICAgcHJpbnRsbihuZXcgU3RyaW5nKGNoYXJzLCAwLCBjaGFycy5sZW5ndGgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY2hhciB7QGNvZGUgY30gZm9sbG93ZWQgYnkgYSBuZXdsaW5lLgorICAgICAqIEZsdXNoZXMgdGhpcyB3cml0ZXIgaWYgdGhlIGF1dG9GbHVzaCBmbGFnIGlzIHNldCB0byB7QGNvZGUgdHJ1ZX0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJpbnRsbihjaGFyIGMpIHsKKyAgICAgICAgcHJpbnRsbihTdHJpbmcudmFsdWVPZihjKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGRvdWJsZSB7QGNvZGUgZH0gZm9sbG93ZWQgYnkgYSBuZXdsaW5lLgorICAgICAqIEZsdXNoZXMgdGhpcyB3cml0ZXIgaWYgdGhlIGF1dG9GbHVzaCBmbGFnIGlzIHNldCB0byB7QGNvZGUgdHJ1ZX0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJpbnRsbihkb3VibGUgZCkgeworICAgICAgICBwcmludGxuKFN0cmluZy52YWx1ZU9mKGQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZmxvYXQge0Bjb2RlIGZ9IGZvbGxvd2VkIGJ5IGEgbmV3bGluZS4KKyAgICAgKiBGbHVzaGVzIHRoaXMgd3JpdGVyIGlmIHRoZSBhdXRvRmx1c2ggZmxhZyBpcyBzZXQgdG8ge0Bjb2RlIHRydWV9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50bG4oZmxvYXQgZikgeworICAgICAgICBwcmludGxuKFN0cmluZy52YWx1ZU9mKGYpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgaW50IHtAY29kZSBpfSBmb2xsb3dlZCBieSBhIG5ld2xpbmUuCisgICAgICogRmx1c2hlcyB0aGlzIHdyaXRlciBpZiB0aGUgYXV0b0ZsdXNoIGZsYWcgaXMgc2V0IHRvIHtAY29kZSB0cnVlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludGxuKGludCBpKSB7CisgICAgICAgIHByaW50bG4oU3RyaW5nLnZhbHVlT2YoaSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBsb25nIHtAY29kZSBsfSBmb2xsb3dlZCBieSBhIG5ld2xpbmUuCisgICAgICogRmx1c2hlcyB0aGlzIHdyaXRlciBpZiB0aGUgYXV0b0ZsdXNoIGZsYWcgaXMgc2V0IHRvIHtAY29kZSB0cnVlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludGxuKGxvbmcgbCkgeworICAgICAgICBwcmludGxuKFN0cmluZy52YWx1ZU9mKGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgb2JqZWN0IHtAY29kZSBvfSwgb3Ige0Bjb2RlICJudWxsfSwKKyAgICAgKiBmb2xsb3dlZCBieSBhIG5ld2xpbmUuCisgICAgICogRmx1c2hlcyB0aGlzIHdyaXRlciBpZiB0aGUgYXV0b0ZsdXNoIGZsYWcgaXMgc2V0IHRvIHtAY29kZSB0cnVlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludGxuKE9iamVjdCBvYmopIHsKKyAgICAgICAgcHJpbnRsbihTdHJpbmcudmFsdWVPZihvYmopKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3RyaW5nIHtAY29kZSBzfSBmb2xsb3dlZCBieSBhIG5ld2xpbmUuCisgICAgICogRmx1c2hlcyB0aGlzIHdyaXRlciBpZiB0aGUgYXV0b0ZsdXNoIGZsYWcgaXMgc2V0IHRvIHtAY29kZSB0cnVlfS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBzdHJpbmcgaXMgY29udmVydGVkIHRvIGFuIGFycmF5IG9mIGJ5dGVzIHVzaW5nIHRoZQorICAgICAqIGVuY29kaW5nIGNob3NlbiBkdXJpbmcgdGhlIGNvbnN0cnVjdGlvbiBvZiB0aGlzIHdyaXRlci4gVGhlIGJ5dGVzIGFyZQorICAgICAqIHRoZW4gd3JpdHRlbiB0byB0aGUgdGFyZ2V0IHdpdGgge0Bjb2RlIHdyaXRlKGludCl9LiBGaW5hbGx5LCB0aGlzIHdyaXRlcgorICAgICAqIGlzIGZsdXNoZWQgaWYgdGhlIGF1dG9GbHVzaCBmbGFnIGlzIHNldCB0byB7QGNvZGUgdHJ1ZX0uCisgICAgICoKKyAgICAgKiA8cD5JZiBhbiBJL08gZXJyb3Igb2NjdXJzLCB0aGlzIHdyaXRlcidzIGVycm9yIGZsYWcgaXMgc2V0IHRvIHtAY29kZSB0cnVlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludGxuKFN0cmluZyBzdHIpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBwcmludChzdHIpOworICAgICAgICAgICAgcHJpbnRsbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGJvb2xlYW4ge0Bjb2RlIGJ9IGZvbGxvd2VkIGJ5IGEgbmV3bGluZS4KKyAgICAgKiBGbHVzaGVzIHRoaXMgd3JpdGVyIGlmIHRoZSBhdXRvRmx1c2ggZmxhZyBpcyBzZXQgdG8ge0Bjb2RlIHRydWV9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50bG4oYm9vbGVhbiBiKSB7CisgICAgICAgIHByaW50bG4oU3RyaW5nLnZhbHVlT2YoYikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGVycm9yIGZsYWcgb2YgdGhpcyB3cml0ZXIgdG8gdHJ1ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRFcnJvcigpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBpb0Vycm9yID0gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgY2hhcmFjdGVyIGJ1ZmZlciB7QGNvZGUgYnVmfSB0byB0aGUgdGFyZ2V0LgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZgorICAgICAqICAgICAgICAgICAgdGhlIG5vbi1udWxsIGFycmF5IGNvbnRhaW5pbmcgY2hhcmFjdGVycyB0byB3cml0ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShjaGFyW10gYnVmKSB7CisgICAgICAgIHdyaXRlKGJ1ZiwgMCwgYnVmLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHtAY29kZSBjb3VudH0gY2hhcmFjdGVycyBmcm9tIHtAY29kZSBidWZmZXJ9IHN0YXJ0aW5nIGF0IHtAY29kZQorICAgICAqIG9mZnNldH0gdG8gdGhlIHRhcmdldC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIHdyaXRlcidzIGVycm9yIGZsYWcgaXMgc2V0IHRvIHtAY29kZSB0cnVlfSBpZiB0aGlzIHdyaXRlciBpcyBjbG9zZWQKKyAgICAgKiBvciBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZgorICAgICAqICAgICAgICAgICAgdGhlIGJ1ZmZlciB0byB3cml0ZSB0byB0aGUgdGFyZ2V0LgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHtAY29kZSBidWZmZXJ9IHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIHtAY29kZSBidWZmZXJ9IHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwfSBvciB7QGNvZGUgY291bnQgPCAwfSwgb3IgaWYge0Bjb2RlCisgICAgICogICAgICAgICAgICAgb2Zmc2V0ICsgY291bnR9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHtAY29kZSBidWZ9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGNoYXJbXSBidWYsIGludCBvZmZzZXQsIGludCBjb3VudCkgeworICAgICAgICBkb1dyaXRlKGJ1Ziwgb2Zmc2V0LCBjb3VudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIG9uZSBjaGFyYWN0ZXIgdG8gdGhlIHRhcmdldC4gT25seSB0aGUgdHdvIGxlYXN0IHNpZ25pZmljYW50IGJ5dGVzCisgICAgICogb2YgdGhlIGludGVnZXIge0Bjb2RlIG9uZUNoYXJ9IGFyZSB3cml0dGVuLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgd3JpdGVyJ3MgZXJyb3IgZmxhZyBpcyBzZXQgdG8ge0Bjb2RlIHRydWV9IGlmIHRoaXMgd3JpdGVyIGlzIGNsb3NlZAorICAgICAqIG9yIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb25lQ2hhcgorICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byB3cml0ZSB0byB0aGUgdGFyZ2V0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBvbmVDaGFyKSB7CisgICAgICAgIGRvV3JpdGUobmV3IGNoYXJbXSB7IChjaGFyKSBvbmVDaGFyIH0sIDAsIDEpOworICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgdm9pZCBkb1dyaXRlKGNoYXJbXSBidWYsIGludCBvZmZzZXQsIGludCBjb3VudCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIG91dC53cml0ZShidWYsIG9mZnNldCwgY291bnQpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgc2V0RXJyb3IoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHNldEVycm9yKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgc3BlY2lmaWVkIHN0cmluZyB0byB0aGUgdGFyZ2V0LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIG5vbi1udWxsIHN0cmluZyBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXJzIHRvIHdyaXRlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKFN0cmluZyBzdHIpIHsKKyAgICAgICAgd3JpdGUoc3RyLnRvQ2hhckFycmF5KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB7QGNvZGUgY291bnR9IGNoYXJhY3RlcnMgZnJvbSB7QGNvZGUgc3RyfSBzdGFydGluZyBhdCB7QGNvZGUKKyAgICAgKiBvZmZzZXR9IHRvIHRoZSB0YXJnZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgbm9uLW51bGwgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGNoYXJhY3RlcnMgdG8gd3JpdGUuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4ge0Bjb2RlIHN0cn0gdG8gd3JpdGUuCisgICAgICogQHBhcmFtIGNvdW50CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgZnJvbSB7QGNvZGUgc3RyfSB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGNvdW50IDwgMH0sIG9yIGlmIHtAY29kZQorICAgICAqICAgICAgICAgICAgIG9mZnNldCArIGNvdW50fSBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZiB7QGNvZGUgc3RyfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShTdHJpbmcgc3RyLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHsKKyAgICAgICAgd3JpdGUoc3RyLnN1YnN0cmluZyhvZmZzZXQsIG9mZnNldCArIGNvdW50KS50b0NoYXJBcnJheSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHRoZSBjaGFyYWN0ZXIge0Bjb2RlIGN9IHRvIHRoZSB0YXJnZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byBhcHBlbmQgdG8gdGhlIHRhcmdldC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgd3JpdGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBQcmludFdyaXRlciBhcHBlbmQoY2hhciBjKSB7CisgICAgICAgIHdyaXRlKGMpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2Uge0Bjb2RlIGNzcX0gdG8gdGhlIHRhcmdldC4gVGhpcworICAgICAqIG1ldGhvZCB3b3JrcyB0aGUgc2FtZSB3YXkgYXMge0Bjb2RlIFByaW50V3JpdGVyLnByaW50KGNzcS50b1N0cmluZygpKX0uCisgICAgICogSWYge0Bjb2RlIGNzcX0gaXMge0Bjb2RlIG51bGx9LCB0aGVuIHRoZSBzdHJpbmcgIm51bGwiIGlzIHdyaXR0ZW4KKyAgICAgKiB0byB0aGUgdGFyZ2V0LgorICAgICAqCisgICAgICogQHBhcmFtIGNzcQorICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSBhcHBlbmRlZCB0byB0aGUgdGFyZ2V0LgorICAgICAqIEByZXR1cm4gdGhpcyB3cml0ZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFByaW50V3JpdGVyIGFwcGVuZChDaGFyU2VxdWVuY2UgY3NxKSB7CisgICAgICAgIGlmIChjc3EgPT0gbnVsbCkgeworICAgICAgICAgICAgY3NxID0gIm51bGwiOworICAgICAgICB9CisgICAgICAgIGFwcGVuZChjc3EsIDAsIGNzcS5sZW5ndGgoKSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgYSBzdWJzZXF1ZW5jZSBvZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHtAY29kZSBjc3F9IHRvIHRoZQorICAgICAqIHRhcmdldC4gVGhpcyBtZXRob2Qgd29ya3MgdGhlIHNhbWUgd2F5IGFzIHtAY29kZQorICAgICAqIFByaW50V3JpdGVyLnByaW50KGNzcS5zdWJzZXF1ZW5jZShzdGFydCwgZW5kKS50b1N0cmluZygpKX0uIElmIHtAY29kZQorICAgICAqIGNzcX0gaXMge0Bjb2RlIG51bGx9LCB0aGVuIHRoZSBzcGVjaWZpZWQgc3Vic2VxdWVuY2Ugb2YgdGhlIHN0cmluZyAibnVsbCIKKyAgICAgKiB3aWxsIGJlIHdyaXR0ZW4gdG8gdGhlIHRhcmdldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjc3EKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgYXBwZW5kZWQgdG8gdGhlIHRhcmdldC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhciBpbiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIGFwcGVuZGVkCisgICAgICogICAgICAgICAgICB0byB0aGUgdGFyZ2V0LgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgY2hhcmFjdGVyIGZvbGxvd2luZyB0aGUgbGFzdCBjaGFyYWN0ZXIgb2YgdGhlCisgICAgICogICAgICAgICAgICBzdWJzZXF1ZW5jZSBhcHBlbmRlZCB0byB0aGUgdGFyZ2V0LgorICAgICAqIEByZXR1cm4gdGhpcyB3cml0ZXIuCisgICAgICogQHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0ID4gZW5kfSwge0Bjb2RlIHN0YXJ0IDwgMH0sIHtAY29kZSBlbmQgPCAwfSBvcgorICAgICAqICAgICAgICAgICAgIGVpdGhlciB7QGNvZGUgc3RhcnR9IG9yIHtAY29kZSBlbmR9IGFyZSBncmVhdGVyIG9yIGVxdWFsIHRoYW4KKyAgICAgKiAgICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHtAY29kZSBjc3F9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBQcmludFdyaXRlciBhcHBlbmQoQ2hhclNlcXVlbmNlIGNzcSwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIGlmIChjc3EgPT0gbnVsbCkgeworICAgICAgICAgICAgY3NxID0gIm51bGwiOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBvdXRwdXQgPSBjc3Euc3ViU2VxdWVuY2Uoc3RhcnQsIGVuZCkudG9TdHJpbmcoKTsKKyAgICAgICAgd3JpdGUob3V0cHV0LCAwLCBvdXRwdXQubGVuZ3RoKCkpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9QdXNoYmFja0lucHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9QdXNoYmFja0lucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmEwZGY4NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1B1c2hiYWNrSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDM0NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBXcmFwcyBhbiBleGlzdGluZyB7QGxpbmsgSW5wdXRTdHJlYW19IGFuZCBhZGRzIGZ1bmN0aW9uYWxpdHkgdG8gInB1c2ggYmFjayIKKyAqIGJ5dGVzIHRoYXQgaGF2ZSBiZWVuIHJlYWQsIHNvIHRoYXQgdGhleSBjYW4gYmUgcmVhZCBhZ2Fpbi4gUGFyc2VycyBtYXkgZmluZAorICogdGhpcyB1c2VmdWwuIFRoZSBudW1iZXIgb2YgYnl0ZXMgd2hpY2ggbWF5IGJlIHB1c2hlZCBiYWNrIGNhbiBiZSBzcGVjaWZpZWQKKyAqIGR1cmluZyBjb25zdHJ1Y3Rpb24uIElmIHRoZSBidWZmZXIgb2YgcHVzaGVkIGJhY2sgYnl0ZXMgaXMgZW1wdHksIGJ5dGVzIGFyZQorICogcmVhZCBmcm9tIHRoZSB1bmRlcmx5aW5nIGlucHV0IHN0cmVhbS4KKyAqLworcHVibGljIGNsYXNzIFB1c2hiYWNrSW5wdXRTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJJbnB1dFN0cmVhbSB7CisgICAgLyoqCisgICAgICogVGhlIGJ1ZmZlciB0aGF0IGNvbnRhaW5zIHB1c2hlZC1iYWNrIGJ5dGVzLgorICAgICAqLworICAgIHByb3RlY3RlZCBieXRlW10gYnVmOworCisgICAgLyoqCisgICAgICogVGhlIGN1cnJlbnQgcG9zaXRpb24gd2l0aGluIHtAY29kZSBidWZ9LiBBIHZhbHVlIGVxdWFsIHRvCisgICAgICoge0Bjb2RlIGJ1Zi5sZW5ndGh9IGluZGljYXRlcyB0aGF0IG5vIGJ5dGVzIGFyZSBhdmFpbGFibGUuIEEgdmFsdWUgb2YgMAorICAgICAqIGluZGljYXRlcyB0aGF0IHRoZSBidWZmZXIgaXMgZnVsbC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHBvczsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFB1c2hiYWNrSW5wdXRTdHJlYW19IHdpdGggdGhlIHNwZWNpZmllZCBpbnB1dAorICAgICAqIHN0cmVhbSBhcyBzb3VyY2UuIFRoZSBzaXplIG9mIHRoZSBwdXNoYmFjayBidWZmZXIgaXMgc2V0IHRvIHRoZSBkZWZhdWx0CisgICAgICogdmFsdWUgb2YgMSBieXRlLgorICAgICAqCisgICAgICogPHA+PHN0cm9uZz5XYXJuaW5nOjwvc3Ryb25nPiBwYXNzaW5nIGEgbnVsbCBzb3VyY2UgY3JlYXRlcyBhbiBpbnZhbGlkCisgICAgICoge0Bjb2RlIFB1c2hiYWNrSW5wdXRTdHJlYW19LiBBbGwgcmVhZCBvcGVyYXRpb25zIG9uIHN1Y2ggYSBzdHJlYW0gd2lsbAorICAgICAqIGZhaWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgaW5wdXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyBQdXNoYmFja0lucHV0U3RyZWFtKElucHV0U3RyZWFtIGluKSB7CisgICAgICAgIHN1cGVyKGluKTsKKyAgICAgICAgYnVmID0gKGluID09IG51bGwpID8gbnVsbCA6IG5ldyBieXRlWzFdOworICAgICAgICBwb3MgPSAxOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFB1c2hiYWNrSW5wdXRTdHJlYW19IHdpdGgge0Bjb2RlIGlufSBhcyBzb3VyY2UKKyAgICAgKiBpbnB1dCBzdHJlYW0uIFRoZSBzaXplIG9mIHRoZSBwdXNoYmFjayBidWZmZXIgaXMgc2V0IHRvIHtAY29kZSBzaXplfS4KKyAgICAgKgorICAgICAqIDxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gcGFzc2luZyBhIG51bGwgc291cmNlIGNyZWF0ZXMgYW4gaW52YWxpZAorICAgICAqIHtAY29kZSBQdXNoYmFja0lucHV0U3RyZWFtfS4gQWxsIHJlYWQgb3BlcmF0aW9ucyBvbiBzdWNoIGEgc3RyZWFtIHdpbGwKKyAgICAgKiBmYWlsLgorICAgICAqCisgICAgICogQHBhcmFtIGluCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGlucHV0IHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIHNpemUgb2YgdGhlIHB1c2hiYWNrIGJ1ZmZlci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzaXplfSBpcyBuZWdhdGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHVzaGJhY2tJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbiwgaW50IHNpemUpIHsKKyAgICAgICAgc3VwZXIoaW4pOworICAgICAgICBpZiAoc2l6ZSA8PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzaXplIDw9IDAiKTsKKyAgICAgICAgfQorICAgICAgICBidWYgPSAoaW4gPT0gbnVsbCkgPyBudWxsIDogbmV3IGJ5dGVbc2l6ZV07CisgICAgICAgIHBvcyA9IHNpemU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoYnVmID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBidWYubGVuZ3RoIC0gcG9zICsgaW4uYXZhaWxhYmxlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgc3RyZWFtLiBUaGlzIGltcGxlbWVudGF0aW9uIGNsb3NlcyB0aGUgc291cmNlIHN0cmVhbQorICAgICAqIGFuZCByZWxlYXNlcyB0aGUgcHVzaGJhY2sgYnVmZmVyLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjbG9zaW5nIHRoaXMgc3RyZWFtLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluICE9IG51bGwpIHsKKyAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICBpbiA9IG51bGw7CisgICAgICAgICAgICBidWYgPSBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBzdHJlYW0gc3VwcG9ydHMgdGhlIHtAY29kZSBtYXJrKGludCl9IGFuZAorICAgICAqIHtAY29kZSByZXNldCgpfSBtZXRob2RzLiB7QGNvZGUgUHVzaGJhY2tJbnB1dFN0cmVhbX0gZG9lcyBub3Qgc3VwcG9ydAorICAgICAqIHRoZW0sIHNvIGl0IHJldHVybnMge0Bjb2RlIGZhbHNlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYWx3YXlzIHtAY29kZSBmYWxzZX0uCisgICAgICogQHNlZSAjbWFyayhpbnQpCisgICAgICogQHNlZSAjcmVzZXQoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hcmtTdXBwb3J0ZWQoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHNpbmdsZSBieXRlIGZyb20gdGhpcyBzdHJlYW0gYW5kIHJldHVybnMgaXQgYXMgYW4gaW50ZWdlciBpbiB0aGUKKyAgICAgKiByYW5nZSBmcm9tIDAgdG8gMjU1LiBJZiB0aGUgcHVzaGJhY2sgYnVmZmVyIGRvZXMgbm90IGNvbnRhaW4gYW55CisgICAgICogYXZhaWxhYmxlIGJ5dGVzIHRoZW4gYSBieXRlIGZyb20gdGhlIHNvdXJjZSBpbnB1dCBzdHJlYW0gaXMgcmV0dXJuZWQuCisgICAgICogQmxvY2tzIHVudGlsIG9uZSBieXRlIGhhcyBiZWVuIHJlYWQsIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSBzdHJlYW0gaXMKKyAgICAgKiBkZXRlY3RlZCBvciBhbiBleGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYnl0ZSByZWFkIG9yIC0xIGlmIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSBzdHJlYW0gaGFzIGJlZW4KKyAgICAgKiAgICAgICAgIHJlYWNoZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgc3RyZWFtIGlzIGNsb3NlZCBvciBhbiBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcKKyAgICAgKiAgICAgICAgICAgICBmcm9tIHRoaXMgc3RyZWFtLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChidWYgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgLy8gSXMgdGhlcmUgYSBwdXNoYmFjayBieXRlIGF2YWlsYWJsZT8KKyAgICAgICAgaWYgKHBvcyA8IGJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiAoYnVmW3BvcysrXSAmIDB4RkYpOworICAgICAgICB9CisgICAgICAgIC8vIEFzc3VtZSByZWFkKCkgaW4gdGhlIElucHV0U3RyZWFtIHdpbGwgcmV0dXJuIGxvdy1vcmRlciBieXRlIG9yIC0xCisgICAgICAgIC8vIGlmIGVuZCBvZiBzdHJlYW0uCisgICAgICAgIHJldHVybiBpbi5yZWFkKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYXQgbW9zdCB7QGNvZGUgbGVuZ3RofSBieXRlcyBmcm9tIHRoaXMgc3RyZWFtIGFuZCBzdG9yZXMgdGhlbSBpbgorICAgICAqIHRoZSBieXRlIGFycmF5IHtAY29kZSBidWZmZXJ9IHN0YXJ0aW5nIGF0IHtAY29kZSBvZmZzZXR9LiBCeXRlcyBhcmUgcmVhZAorICAgICAqIGZyb20gdGhlIHB1c2hiYWNrIGJ1ZmZlciBmaXJzdCwgdGhlbiBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtIGlmIG1vcmUgYnl0ZXMKKyAgICAgKiBhcmUgcmVxdWlyZWQuIEJsb2NrcyB1bnRpbCB7QGNvZGUgY291bnR9IGJ5dGVzIGhhdmUgYmVlbiByZWFkLCB0aGUgZW5kIG9mCisgICAgICogdGhlIHNvdXJjZSBzdHJlYW0gaXMgZGV0ZWN0ZWQgb3IgYW4gZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBpbiB3aGljaCB0byBzdG9yZSB0aGUgYnl0ZXMgcmVhZCBmcm9tIHRoaXMgc3RyZWFtLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIHBvc2l0aW9uIGluIHtAY29kZSBidWZmZXJ9IHRvIHN0b3JlIHRoZSBieXRlcyByZWFkCisgICAgICogICAgICAgICAgICBmcm9tIHRoaXMgc3RyZWFtLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0byBzdG9yZSBpbiB7QGNvZGUgYnVmZmVyfS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZSBzb3VyY2Ugc3RyZWFtCisgICAgICogICAgICAgICBoYXMgYmVlbiByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwfSBvciB7QGNvZGUgbGVuZ3RoIDwgMH0sIG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIG9mZnNldCArIGxlbmd0aH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgYnVmZmVyfS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBzdHJlYW0gaXMgY2xvc2VkIG9yIGFub3RoZXIgSS9PIGVycm9yIG9jY3VycyB3aGlsZQorICAgICAqICAgICAgICAgICAgIHJlYWRpbmcgZnJvbSB0aGlzIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGJ1ZmZlcn0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoYnVmID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IHN0cmVhbUNsb3NlZCgpOworICAgICAgICB9CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGJ1ZmZlci5sZW5ndGgsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgaW50IGNvcGllZEJ5dGVzID0gMCwgY29weUxlbmd0aCA9IDAsIG5ld09mZnNldCA9IG9mZnNldDsKKyAgICAgICAgLy8gQXJlIHRoZXJlIHB1c2hiYWNrIGJ5dGVzIGF2YWlsYWJsZT8KKyAgICAgICAgaWYgKHBvcyA8IGJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgIGNvcHlMZW5ndGggPSAoYnVmLmxlbmd0aCAtIHBvcyA+PSBsZW5ndGgpID8gbGVuZ3RoIDogYnVmLmxlbmd0aAorICAgICAgICAgICAgICAgICAgICAtIHBvczsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCBwb3MsIGJ1ZmZlciwgbmV3T2Zmc2V0LCBjb3B5TGVuZ3RoKTsKKyAgICAgICAgICAgIG5ld09mZnNldCArPSBjb3B5TGVuZ3RoOworICAgICAgICAgICAgY29waWVkQnl0ZXMgKz0gY29weUxlbmd0aDsKKyAgICAgICAgICAgIC8vIFVzZSB1cCB0aGUgYnl0ZXMgaW4gdGhlIGxvY2FsIGJ1ZmZlcgorICAgICAgICAgICAgcG9zICs9IGNvcHlMZW5ndGg7CisgICAgICAgIH0KKyAgICAgICAgLy8gSGF2ZSB3ZSBjb3BpZWQgZW5vdWdoPworICAgICAgICBpZiAoY29weUxlbmd0aCA9PSBsZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiBsZW5ndGg7CisgICAgICAgIH0KKyAgICAgICAgaW50IGluQ29waWVkID0gaW4ucmVhZChidWZmZXIsIG5ld09mZnNldCwgbGVuZ3RoIC0gY29waWVkQnl0ZXMpOworICAgICAgICBpZiAoaW5Db3BpZWQgPiAwKSB7CisgICAgICAgICAgICByZXR1cm4gaW5Db3BpZWQgKyBjb3BpZWRCeXRlczsKKyAgICAgICAgfQorICAgICAgICBpZiAoY29waWVkQnl0ZXMgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGluQ29waWVkOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb3BpZWRCeXRlczsKKyAgICB9CisKKyAgICBwcml2YXRlIElPRXhjZXB0aW9uIHN0cmVhbUNsb3NlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiAgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlB1c2hiYWNrSW5wdXRTdHJlYW0gaXMgY2xvc2VkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcHMge0Bjb2RlIGJ5dGVDb3VudH0gYnl0ZXMgaW4gdGhpcyBzdHJlYW0uIFRoaXMgaW1wbGVtZW50YXRpb24gc2tpcHMgYnl0ZXMKKyAgICAgKiBpbiB0aGUgcHVzaGJhY2sgYnVmZmVyIGZpcnN0IGFuZCB0aGVuIGluIHRoZSBzb3VyY2Ugc3RyZWFtIGlmIG5lY2Vzc2FyeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSBza2lwcGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHN0cmVhbSBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIHNraXAobG9uZyBieXRlQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpbiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBzdHJlYW1DbG9zZWQoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYnl0ZUNvdW50IDw9IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGludCBudW1Ta2lwcGVkID0gMDsKKyAgICAgICAgaWYgKHBvcyA8IGJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgIG51bVNraXBwZWQgKz0gKGJ5dGVDb3VudCA8IGJ1Zi5sZW5ndGggLSBwb3MpID8gYnl0ZUNvdW50IDogYnVmLmxlbmd0aCAtIHBvczsKKyAgICAgICAgICAgIHBvcyArPSBudW1Ta2lwcGVkOworICAgICAgICB9CisgICAgICAgIGlmIChudW1Ta2lwcGVkIDwgYnl0ZUNvdW50KSB7CisgICAgICAgICAgICBudW1Ta2lwcGVkICs9IGluLnNraXAoYnl0ZUNvdW50IC0gbnVtU2tpcHBlZCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bVNraXBwZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHVzaGVzIGFsbCB0aGUgYnl0ZXMgaW4ge0Bjb2RlIGJ1ZmZlcn0gYmFjayB0byB0aGlzIHN0cmVhbS4gVGhlIGJ5dGVzIGFyZQorICAgICAqIHB1c2hlZCBiYWNrIGluIHN1Y2ggYSB3YXkgdGhhdCB0aGUgbmV4dCBieXRlIHJlYWQgZnJvbSB0aGlzIHN0cmVhbSBpcworICAgICAqIGJ1ZmZlclswXSwgdGhlbiBidWZmZXJbMV0gYW5kIHNvIG9uLgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgc3RyZWFtJ3MgaW50ZXJuYWwgcHVzaGJhY2sgYnVmZmVyIGNhbm5vdCBzdG9yZSB0aGUgZW50aXJlCisgICAgICogY29udGVudHMgb2Yge0Bjb2RlIGJ1ZmZlcn0sIGFuIHtAY29kZSBJT0V4Y2VwdGlvbn0gaXMgdGhyb3duLiBQYXJ0cyBvZgorICAgICAqIHtAY29kZSBidWZmZXJ9IG1heSBoYXZlIGFscmVhZHkgYmVlbiBjb3BpZWQgdG8gdGhlIHB1c2hiYWNrIGJ1ZmZlciB3aGVuCisgICAgICogdGhlIGV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIGJ5dGVzIHRvIHB1c2ggYmFjayB0byB0aGlzIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGZyZWUgc3BhY2UgaW4gdGhlIGludGVybmFsIHB1c2hiYWNrIGJ1ZmZlciBpcyBub3QKKyAgICAgKiAgICAgICAgICAgICBzdWZmaWNpZW50IHRvIHN0b3JlIHRoZSBjb250ZW50cyBvZiB7QGNvZGUgYnVmZmVyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1bnJlYWQoYnl0ZVtdIGJ1ZmZlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdW5yZWFkKGJ1ZmZlciwgMCwgYnVmZmVyLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHVzaGVzIGEgc3Vic2V0IG9mIHRoZSBieXRlcyBpbiB7QGNvZGUgYnVmZmVyfSBiYWNrIHRvIHRoaXMgc3RyZWFtLiBUaGUKKyAgICAgKiBzdWJzZXQgaXMgZGVmaW5lZCBieSB0aGUgc3RhcnQgcG9zaXRpb24ge0Bjb2RlIG9mZnNldH0gd2l0aGluCisgICAgICoge0Bjb2RlIGJ1ZmZlcn0gYW5kIHRoZSBudW1iZXIgb2YgYnl0ZXMgc3BlY2lmaWVkIGJ5IHtAY29kZSBsZW5ndGh9LiBUaGUKKyAgICAgKiBieXRlcyBhcmUgcHVzaGVkIGJhY2sgaW4gc3VjaCBhIHdheSB0aGF0IHRoZSBuZXh0IGJ5dGUgcmVhZCBmcm9tIHRoaXMKKyAgICAgKiBzdHJlYW0gaXMge0Bjb2RlIGJ1ZmZlcltvZmZzZXRdfSwgdGhlbiB7QGNvZGUgYnVmZmVyWzFdfSBhbmQgc28gb24uCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBzdHJlYW0ncyBpbnRlcm5hbCBwdXNoYmFjayBidWZmZXIgY2Fubm90IHN0b3JlIHRoZSBzZWxlY3RlZAorICAgICAqIHN1YnNldCBvZiB7QGNvZGUgYnVmZmVyfSwgYW4ge0Bjb2RlIElPRXhjZXB0aW9ufSBpcyB0aHJvd24uIFBhcnRzIG9mCisgICAgICoge0Bjb2RlIGJ1ZmZlcn0gbWF5IGhhdmUgYWxyZWFkeSBiZWVuIGNvcGllZCB0byB0aGUgcHVzaGJhY2sgYnVmZmVyIHdoZW4KKyAgICAgKiB0aGUgZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXIgY29udGFpbmluZyB0aGUgYnl0ZXMgdG8gcHVzaCBiYWNrIHRvIHRoaXMgc3RyZWFtLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgYnl0ZSBpbiB7QGNvZGUgYnVmZmVyfSB0byBwdXNoIGJhY2suCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyB0byBwdXNoIGJhY2suCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBsZW5ndGggPCAwfSwgb3IgaWYKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgb2Zmc2V0ICsgbGVuZ3RofSBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBidWZmZXJ9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZnJlZSBzcGFjZSBpbiB0aGUgaW50ZXJuYWwgcHVzaGJhY2sgYnVmZmVyIGlzIG5vdAorICAgICAqICAgICAgICAgICAgIHN1ZmZpY2llbnQgdG8gc3RvcmUgdGhlIHNlbGVjdGVkIGNvbnRlbnRzIG9mIHtAY29kZSBidWZmZXJ9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVucmVhZChieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAobGVuZ3RoID4gcG9zKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlB1c2hiYWNrIGJ1ZmZlciBmdWxsIik7CisgICAgICAgIH0KKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICBpZiAoYnVmID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IHN0cmVhbUNsb3NlZCgpOworICAgICAgICB9CisKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWZmZXIsIG9mZnNldCwgYnVmLCBwb3MgLSBsZW5ndGgsIGxlbmd0aCk7CisgICAgICAgIHBvcyA9IHBvcyAtIGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQdXNoZXMgdGhlIHNwZWNpZmllZCBieXRlIHtAY29kZSBvbmVCeXRlfSBiYWNrIHRvIHRoaXMgc3RyZWFtLiBPbmx5IHRoZQorICAgICAqIGxlYXN0IHNpZ25pZmljYW50IGJ5dGUgb2YgdGhlIGludGVnZXIge0Bjb2RlIG9uZUJ5dGV9IGlzIHB1c2hlZCBiYWNrLgorICAgICAqIFRoaXMgaXMgZG9uZSBpbiBzdWNoIGEgd2F5IHRoYXQgdGhlIG5leHQgYnl0ZSByZWFkIGZyb20gdGhpcyBzdHJlYW0gaXMKKyAgICAgKiB7QGNvZGUgKGJ5dGUpIG9uZUJ5dGV9LgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgc3RyZWFtJ3MgaW50ZXJuYWwgcHVzaGJhY2sgYnVmZmVyIGNhbm5vdCBzdG9yZSB0aGUgYnl0ZSwgYW4KKyAgICAgKiB7QGNvZGUgSU9FeGNlcHRpb259IGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvbmVCeXRlCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSB0byBwdXNoIGJhY2sgdG8gdGhpcyBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgc3RyZWFtIGlzIGNsb3NlZCBvciB0aGUgaW50ZXJuYWwgcHVzaGJhY2sgYnVmZmVyIGlzCisgICAgICogICAgICAgICAgICAgZnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1bnJlYWQoaW50IG9uZUJ5dGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChidWYgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBvcyA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlB1c2hiYWNrIGJ1ZmZlciBmdWxsIik7CisgICAgICAgIH0KKyAgICAgICAgYnVmWy0tcG9zXSA9IChieXRlKSBvbmVCeXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1hcmtzIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoaXMgc3RyZWFtLiBTZXR0aW5nIGEgbWFyayBpcyBub3QKKyAgICAgKiBzdXBwb3J0ZWQgaW4gdGhpcyBjbGFzczsgdGhpcyBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdGhpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhZGxpbWl0CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgY2FuIGJlIHJlYWQgZnJvbSB0aGlzIHN0cmVhbSBiZWZvcmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXJrIGlzIGludmFsaWRhdGVkOyB0aGlzIHBhcmFtZXRlciBpcyBpZ25vcmVkLgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBtYXJrKGludCByZWFkbGltaXQpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhpcyBzdHJlYW0gdG8gdGhlIGxhc3QgbWFya2VkIHBvc2l0aW9uLiBSZXNldHRpbmcgdGhlIHN0cmVhbSBpcworICAgICAqIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBjbGFzczsgdGhpcyBpbXBsZW1lbnRhdGlvbiBhbHdheXMgdGhyb3dzIGFuCisgICAgICoge0Bjb2RlIElPRXhjZXB0aW9ufS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9QdXNoYmFja1JlYWRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vUHVzaGJhY2tSZWFkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZTNjZjgzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vUHVzaGJhY2tSZWFkZXIuamF2YQpAQCAtMCwwICsxLDM3NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBXcmFwcyBhbiBleGlzdGluZyB7QGxpbmsgUmVhZGVyfSBhbmQgYWRkcyBmdW5jdGlvbmFsaXR5IHRvICJwdXNoIGJhY2siCisgKiBjaGFyYWN0ZXJzIHRoYXQgaGF2ZSBiZWVuIHJlYWQsIHNvIHRoYXQgdGhleSBjYW4gYmUgcmVhZCBhZ2Fpbi4gUGFyc2VycyBtYXkKKyAqIGZpbmQgdGhpcyB1c2VmdWwuIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB3aGljaCBtYXkgYmUgcHVzaGVkIGJhY2sgY2FuIGJlCisgKiBzcGVjaWZpZWQgZHVyaW5nIGNvbnN0cnVjdGlvbi4gSWYgdGhlIGJ1ZmZlciBvZiBwdXNoZWQgYmFjayBieXRlcyBpcyBlbXB0eSwKKyAqIGNoYXJhY3RlcnMgYXJlIHJlYWQgZnJvbSB0aGUgdW5kZXJseWluZyByZWFkZXIuCisgKi8KK3B1YmxpYyBjbGFzcyBQdXNoYmFja1JlYWRlciBleHRlbmRzIEZpbHRlclJlYWRlciB7CisgICAgLyoqCisgICAgICogVGhlIHtAY29kZSBjaGFyfSBhcnJheSBjb250YWluaW5nIHRoZSBjaGFycyB0byByZWFkLgorICAgICAqLworICAgIGNoYXJbXSBidWY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY3VycmVudCBwb3NpdGlvbiB3aXRoaW4gdGhlIGNoYXIgYXJyYXkge0Bjb2RlIGJ1Zn0uIEEgdmFsdWUKKyAgICAgKiBlcXVhbCB0byBidWYubGVuZ3RoIGluZGljYXRlcyBubyBjaGFycyBhdmFpbGFibGUuIEEgdmFsdWUgb2YgMCBpbmRpY2F0ZXMKKyAgICAgKiB0aGUgYnVmZmVyIGlzIGZ1bGwuCisgICAgICovCisgICAgaW50IHBvczsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFB1c2hiYWNrUmVhZGVyfSB3aXRoIHRoZSBzcGVjaWZpZWQgcmVhZGVyIGFzCisgICAgICogc291cmNlLiBUaGUgc2l6ZSBvZiB0aGUgcHVzaGJhY2sgYnVmZmVyIGlzIHNldCB0byB0aGUgZGVmYXVsdCB2YWx1ZSBvZiAxCisgICAgICogY2hhcmFjdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGluCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIHJlYWRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHVzaGJhY2tSZWFkZXIoUmVhZGVyIGluKSB7CisgICAgICAgIHN1cGVyKGluKTsKKyAgICAgICAgYnVmID0gbmV3IGNoYXJbMV07CisgICAgICAgIHBvcyA9IDE7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUHVzaGJhY2tSZWFkZXJ9IHdpdGgge0Bjb2RlIGlufSBhcyBzb3VyY2UgcmVhZGVyLgorICAgICAqIFRoZSBzaXplIG9mIHRoZSBwdXNoYmFjayBidWZmZXIgaXMgc2V0IHRvIHtAY29kZSBzaXplfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbgorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSByZWFkZXIuCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaXplIG9mIHRoZSBwdXNoYmFjayBidWZmZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc2l6ZX0gaXMgbmVnYXRpdmUuCisgICAgICovCisgICAgcHVibGljIFB1c2hiYWNrUmVhZGVyKFJlYWRlciBpbiwgaW50IHNpemUpIHsKKyAgICAgICAgc3VwZXIoaW4pOworICAgICAgICBpZiAoc2l6ZSA8PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzaXplIDw9IDAiKTsKKyAgICAgICAgfQorICAgICAgICBidWYgPSBuZXcgY2hhcltzaXplXTsKKyAgICAgICAgcG9zID0gc2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhpcyByZWFkZXIuIFRoaXMgaW1wbGVtZW50YXRpb24gY2xvc2VzIHRoZSBzb3VyY2UgcmVhZGVyCisgICAgICogYW5kIHJlbGVhc2VzIHRoZSBwdXNoYmFjayBidWZmZXIuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNsb3NpbmcgdGhpcyByZWFkZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGJ1ZiA9IG51bGw7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFya3MgdGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhpcyBzdHJlYW0uIFNldHRpbmcgYSBtYXJrIGlzIG5vdAorICAgICAqIHN1cHBvcnRlZCBpbiB0aGlzIGNsYXNzOyB0aGlzIGltcGxlbWVudGF0aW9uIGFsd2F5cyB0aHJvd3MgYW4KKyAgICAgKiB7QGNvZGUgSU9FeGNlcHRpb259LgorICAgICAqCisgICAgICogQHBhcmFtIHJlYWRBaGVhZExpbWl0CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlciB0aGF0IGNhbiBiZSByZWFkIGZyb20gdGhpcyByZWFkZXIKKyAgICAgKiAgICAgICAgICAgIGJlZm9yZSB0aGUgbWFyayBpcyBpbnZhbGlkYXRlZDsgdGhpcyBwYXJhbWV0ZXIgaXMgaWdub3JlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIG1hcmsoaW50IHJlYWRBaGVhZExpbWl0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIm1hcmsvcmVzZXQgbm90IHN1cHBvcnRlZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgcmVhZGVyIHN1cHBvcnRzIHRoZSB7QGNvZGUgbWFyayhpbnQpfSBhbmQKKyAgICAgKiB7QGNvZGUgcmVzZXQoKX0gbWV0aG9kcy4ge0Bjb2RlIFB1c2hiYWNrUmVhZGVyfSBkb2VzIG5vdCBzdXBwb3J0IHRoZW0sIHNvCisgICAgICogaXQgcmV0dXJucyB7QGNvZGUgZmFsc2V9LgorICAgICAqCisgICAgICogQHJldHVybiBhbHdheXMge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAc2VlICNtYXJrKGludCkKKyAgICAgKiBAc2VlICNyZXNldCgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gbWFya1N1cHBvcnRlZCgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgc2luZ2xlIGNoYXJhY3RlciBmcm9tIHRoaXMgcmVhZGVyIGFuZCByZXR1cm5zIGl0IGFzIGFuIGludGVnZXIKKyAgICAgKiB3aXRoIHRoZSB0d28gaGlnaGVyLW9yZGVyIGJ5dGVzIHNldCB0byAwLiBSZXR1cm5zIC0xIGlmIHRoZSBlbmQgb2YgdGhlCisgICAgICogcmVhZGVyIGhhcyBiZWVuIHJlYWNoZWQuIElmIHRoZSBwdXNoYmFjayBidWZmZXIgZG9lcyBub3QgY29udGFpbiBhbnkKKyAgICAgKiBhdmFpbGFibGUgY2hhcmFjdGVycyB0aGVuIGEgY2hhcmFjdGVyIGZyb20gdGhlIHNvdXJjZSByZWFkZXIgaXMgcmV0dXJuZWQuCisgICAgICogQmxvY2tzIHVudGlsIG9uZSBjaGFyYWN0ZXIgaGFzIGJlZW4gcmVhZCwgdGhlIGVuZCBvZiB0aGUgc291cmNlIHJlYWRlciBpcworICAgICAqIGRldGVjdGVkIG9yIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFyYWN0ZXIgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZSBzb3VyY2UgcmVhZGVyIGhhcyBiZWVuCisgICAgICogICAgICAgICByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQgb3IgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nCisgICAgICogICAgICAgICAgICAgZnJvbSB0aGlzIHJlYWRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgICAgICAvKiBJcyB0aGVyZSBhIHB1c2hiYWNrIGNoYXJhY3RlciBhdmFpbGFibGU/ICovCisgICAgICAgICAgICBpZiAocG9zIDwgYnVmLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIHJldHVybiBidWZbcG9zKytdOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgKiBBc3N1bWUgcmVhZCgpIGluIHRoZSBJbnB1dFN0cmVhbSB3aWxsIHJldHVybiAyIGxvd2VzdC1vcmRlciBieXRlcworICAgICAgICAgICAgICogb3IgLTEgaWYgZW5kIG9mIHN0cmVhbS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgcmV0dXJuIGluLnJlYWQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja05vdENsb3NlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChidWYgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJQdXNoYmFja1JlYWRlciBpcyBjbG9zZWQiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGF0IG1vc3Qge0Bjb2RlIGxlbmd0aH0gYnl0ZXMgZnJvbSB0aGlzIHJlYWRlciBhbmQgc3RvcmVzIHRoZW0gaW4KKyAgICAgKiBieXRlIGFycmF5IHtAY29kZSBidWZmZXJ9IHN0YXJ0aW5nIGF0IHtAY29kZSBvZmZzZXR9LiBDaGFyYWN0ZXJzIGFyZQorICAgICAqIHJlYWQgZnJvbSB0aGUgcHVzaGJhY2sgYnVmZmVyIGZpcnN0LCB0aGVuIGZyb20gdGhlIHNvdXJjZSByZWFkZXIgaWYgbW9yZQorICAgICAqIGJ5dGVzIGFyZSByZXF1aXJlZC4gQmxvY2tzIHVudGlsIHtAY29kZSBjb3VudH0gY2hhcmFjdGVycyBoYXZlIGJlZW4gcmVhZCwKKyAgICAgKiB0aGUgZW5kIG9mIHRoZSBzb3VyY2UgcmVhZGVyIGlzIGRldGVjdGVkIG9yIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgaW4gd2hpY2ggdG8gc3RvcmUgdGhlIGNoYXJhY3RlcnMgcmVhZCBmcm9tIHRoaXMKKyAgICAgKiAgICAgICAgICAgIHJlYWRlci4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBwb3NpdGlvbiBpbiB7QGNvZGUgYnVmZmVyfSB0byBzdG9yZSB0aGUgY2hhcmFjdGVycworICAgICAqICAgICAgICAgICAgcmVhZCBmcm9tIHRoaXMgcmVhZGVyLgorICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHRvIHN0b3JlIGluIHtAY29kZSBidWZmZXJ9LgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyByZWFkIG9yIC0xIGlmIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSByZWFkZXIKKyAgICAgKiAgICAgICAgIGhhcyBiZWVuIHJlYWNoZWQuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBjb3VudCA8IDB9LCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBjb3VudH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgYnVmZmVyfS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyByZWFkZXIgaXMgY2xvc2VkIG9yIGFub3RoZXIgSS9PIGVycm9yIG9jY3VycyB3aGlsZQorICAgICAqICAgICAgICAgICAgIHJlYWRpbmcgZnJvbSB0aGlzIHJlYWRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoY2hhcltdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXIubGVuZ3RoLCBvZmZzZXQsIGNvdW50KTsKKworICAgICAgICAgICAgaW50IGNvcGllZENoYXJzID0gMDsKKyAgICAgICAgICAgIGludCBjb3B5TGVuZ3RoID0gMDsKKyAgICAgICAgICAgIGludCBuZXdPZmZzZXQgPSBvZmZzZXQ7CisgICAgICAgICAgICAvKiBBcmUgdGhlcmUgcHVzaGJhY2sgY2hhcnMgYXZhaWxhYmxlPyAqLworICAgICAgICAgICAgaWYgKHBvcyA8IGJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBjb3B5TGVuZ3RoID0gKGJ1Zi5sZW5ndGggLSBwb3MgPj0gY291bnQpID8gY291bnQgOiBidWYubGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICAtIHBvczsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZiwgcG9zLCBidWZmZXIsIG5ld09mZnNldCwgY29weUxlbmd0aCk7CisgICAgICAgICAgICAgICAgbmV3T2Zmc2V0ICs9IGNvcHlMZW5ndGg7CisgICAgICAgICAgICAgICAgY29waWVkQ2hhcnMgKz0gY29weUxlbmd0aDsKKyAgICAgICAgICAgICAgICAvKiBVc2UgdXAgdGhlIGNoYXJzIGluIHRoZSBsb2NhbCBidWZmZXIgKi8KKyAgICAgICAgICAgICAgICBwb3MgKz0gY29weUxlbmd0aDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8qIEhhdmUgd2UgY29waWVkIGVub3VnaD8gKi8KKyAgICAgICAgICAgIGlmIChjb3B5TGVuZ3RoID09IGNvdW50KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNvdW50OworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IGluQ29waWVkID0gaW4ucmVhZChidWZmZXIsIG5ld09mZnNldCwgY291bnQgLSBjb3BpZWRDaGFycyk7CisgICAgICAgICAgICBpZiAoaW5Db3BpZWQgPiAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGluQ29waWVkICsgY29waWVkQ2hhcnM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY29waWVkQ2hhcnMgPT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBpbkNvcGllZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBjb3BpZWRDaGFyczsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgcmVhZGVyIGlzIHJlYWR5IHRvIGJlIHJlYWQgd2l0aG91dCBibG9ja2luZy4KKyAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGlzIHJlYWRlciB3aWxsIG5vdCBibG9jayB3aGVuIHtAY29kZSByZWFkfSBpcworICAgICAqIGNhbGxlZCwge0Bjb2RlIGZhbHNlfSBpZiB1bmtub3duIG9yIGJsb2NraW5nIHdpbGwgb2NjdXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgcmVjZWl2ZXIgd2lsbCBub3QgYmxvY2sgd2hlbgorICAgICAqICAgICAgICAge0Bjb2RlIHJlYWQoKX0gaXMgY2FsbGVkLCB7QGNvZGUgZmFsc2V9IGlmIHVua25vd24KKyAgICAgKiAgICAgICAgIG9yIGJsb2NraW5nIHdpbGwgb2NjdXIuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgcmVhZGVyIGlzIGNsb3NlZCBvciBzb21lIG90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSAjcmVhZCgpCisgICAgICogQHNlZSAjcmVhZChjaGFyW10sIGludCwgaW50KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIHJlYWR5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBpZiAoYnVmID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlJlYWRlciBpcyBjbG9zZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAoYnVmLmxlbmd0aCAtIHBvcyA+IDAgfHwgaW4ucmVhZHkoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhpcyByZWFkZXIgdG8gdGhlIGxhc3QgbWFya2VkIHBvc2l0aW9uLiBSZXNldHRpbmcgdGhlIHJlYWRlciBpcworICAgICAqIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBjbGFzczsgdGhpcyBpbXBsZW1lbnRhdGlvbiBhbHdheXMgdGhyb3dzIGFuCisgICAgICoge0Bjb2RlIElPRXhjZXB0aW9ufS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIm1hcmsvcmVzZXQgbm90IHN1cHBvcnRlZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFB1c2hlcyBhbGwgdGhlIGNoYXJhY3RlcnMgaW4ge0Bjb2RlIGJ1ZmZlcn0gYmFjayB0byB0aGlzIHJlYWRlci4gVGhlCisgICAgICogY2hhcmFjdGVycyBhcmUgcHVzaGVkIGJhY2sgaW4gc3VjaCBhIHdheSB0aGF0IHRoZSBuZXh0IGNoYXJhY3RlciByZWFkCisgICAgICogZnJvbSB0aGlzIHJlYWRlciBpcyBidWZmZXJbMF0sIHRoZW4gYnVmZmVyWzFdIGFuZCBzbyBvbi4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIHJlYWRlcidzIGludGVybmFsIHB1c2hiYWNrIGJ1ZmZlciBjYW5ub3Qgc3RvcmUgdGhlIGVudGlyZQorICAgICAqIGNvbnRlbnRzIG9mIHtAY29kZSBidWZmZXJ9LCBhbiB7QGNvZGUgSU9FeGNlcHRpb259IGlzIHRocm93bi4gUGFydHMgb2YKKyAgICAgKiB7QGNvZGUgYnVmZmVyfSBtYXkgaGF2ZSBhbHJlYWR5IGJlZW4gY29waWVkIHRvIHRoZSBwdXNoYmFjayBidWZmZXIgd2hlbgorICAgICAqIHRoZSBleGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIGJ1ZmZlciBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXJzIHRvIHB1c2ggYmFjayB0byB0aGlzCisgICAgICogICAgICAgICAgICByZWFkZXIuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgcmVhZGVyIGlzIGNsb3NlZCBvciB0aGUgZnJlZSBzcGFjZSBpbiB0aGUgaW50ZXJuYWwKKyAgICAgKiAgICAgICAgICAgICBwdXNoYmFjayBidWZmZXIgaXMgbm90IHN1ZmZpY2llbnQgdG8gc3RvcmUgdGhlIGNvbnRlbnRzIG9mCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGJ1ZmZlcn0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdW5yZWFkKGNoYXJbXSBidWZmZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHVucmVhZChidWZmZXIsIDAsIGJ1ZmZlci5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFB1c2hlcyBhIHN1YnNldCBvZiB0aGUgY2hhcmFjdGVycyBpbiB7QGNvZGUgYnVmZmVyfSBiYWNrIHRvIHRoaXMgcmVhZGVyLgorICAgICAqIFRoZSBzdWJzZXQgaXMgZGVmaW5lZCBieSB0aGUgc3RhcnQgcG9zaXRpb24ge0Bjb2RlIG9mZnNldH0gd2l0aGluCisgICAgICoge0Bjb2RlIGJ1ZmZlcn0gYW5kIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBzcGVjaWZpZWQgYnkge0Bjb2RlIGxlbmd0aH0uCisgICAgICogVGhlIGJ5dGVzIGFyZSBwdXNoZWQgYmFjayBpbiBzdWNoIGEgd2F5IHRoYXQgdGhlIG5leHQgYnl0ZSByZWFkIGZyb20gdGhpcworICAgICAqIHN0cmVhbSBpcyB7QGNvZGUgYnVmZmVyW29mZnNldF19LCB0aGVuIHtAY29kZSBidWZmZXJbMV19IGFuZCBzbyBvbi4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIHN0cmVhbSdzIGludGVybmFsIHB1c2hiYWNrIGJ1ZmZlciBjYW5ub3Qgc3RvcmUgdGhlIHNlbGVjdGVkCisgICAgICogc3Vic2V0IG9mIHtAY29kZSBidWZmZXJ9LCBhbiB7QGNvZGUgSU9FeGNlcHRpb259IGlzIHRocm93bi4gUGFydHMgb2YKKyAgICAgKiB7QGNvZGUgYnVmZmVyfSBtYXkgaGF2ZSBhbHJlYWR5IGJlZW4gY29waWVkIHRvIHRoZSBwdXNoYmFjayBidWZmZXIgd2hlbgorICAgICAqIHRoZSBleGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIGJ1ZmZlciBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXJzIHRvIHB1c2ggYmFjayB0byB0aGlzCisgICAgICogICAgICAgICAgICByZWFkZXIuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBieXRlIGluIHtAY29kZSBidWZmZXJ9IHRvIHB1c2ggYmFjay4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHB1c2ggYmFjay4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGNvdW50IDwgMH0sIG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIG9mZnNldCArIGNvdW50fSBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBidWZmZXJ9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQgb3IgdGhlIGZyZWUgc3BhY2UgaW4gdGhlIGludGVybmFsCisgICAgICogICAgICAgICAgICAgcHVzaGJhY2sgYnVmZmVyIGlzIG5vdCBzdWZmaWNpZW50IHRvIHN0b3JlIHRoZSBzZWxlY3RlZAorICAgICAqICAgICAgICAgICAgIGNvbnRlbnRzIG9mIHtAY29kZSBidWZmZXJ9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYnVmZmVyfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdW5yZWFkKGNoYXJbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgICAgIGlmIChsZW5ndGggPiBwb3MpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlB1c2hiYWNrIGJ1ZmZlciBmdWxsIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXIubGVuZ3RoLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gb2Zmc2V0ICsgbGVuZ3RoIC0gMTsgaSA+PSBvZmZzZXQ7IGktLSkgeworICAgICAgICAgICAgICAgIHVucmVhZChidWZmZXJbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHVzaGVzIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIHtAY29kZSBvbmVDaGFyfSBiYWNrIHRvIHRoaXMgcmVhZGVyLiBUaGlzCisgICAgICogaXMgZG9uZSBpbiBzdWNoIGEgd2F5IHRoYXQgdGhlIG5leHQgY2hhcmFjdGVyIHJlYWQgZnJvbSB0aGlzIHJlYWRlciBpcworICAgICAqIHtAY29kZSAoY2hhcikgb25lQ2hhcn0uCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyByZWFkZXIncyBpbnRlcm5hbCBwdXNoYmFjayBidWZmZXIgY2Fubm90IHN0b3JlIHRoZSBjaGFyYWN0ZXIsIGFuCisgICAgICoge0Bjb2RlIElPRXhjZXB0aW9ufSBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb25lQ2hhcgorICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byBwdXNoIGJhY2sgdG8gdGhpcyBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgcmVhZGVyIGlzIGNsb3NlZCBvciB0aGUgaW50ZXJuYWwgcHVzaGJhY2sgYnVmZmVyIGlzCisgICAgICogICAgICAgICAgICAgZnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1bnJlYWQoaW50IG9uZUNoYXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgICAgIGlmIChwb3MgPT0gMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUHVzaGJhY2sgYnVmZmVyIGZ1bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ1ZlstLXBvc10gPSAoY2hhcikgb25lQ2hhcjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNraXBzIHtAY29kZSBjaGFyQ291bnR9IGNoYXJhY3RlcnMgaW4gdGhpcyByZWFkZXIuIFRoaXMgaW1wbGVtZW50YXRpb24gc2tpcHMKKyAgICAgKiBjaGFyYWN0ZXJzIGluIHRoZSBwdXNoYmFjayBidWZmZXIgZmlyc3QgYW5kIHRoZW4gaW4gdGhlIHNvdXJjZSByZWFkZXIgaWYKKyAgICAgKiBuZWNlc3NhcnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBhY3R1YWxseSBza2lwcGVkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBjaGFyQ291bnQgPCAwfS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyByZWFkZXIgaXMgY2xvc2VkIG9yIGFub3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBza2lwKGxvbmcgY2hhckNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY2hhckNvdW50IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiY2hhckNvdW50IDwgMDogIiArIGNoYXJDb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBjaGVja05vdENsb3NlZCgpOworICAgICAgICAgICAgaWYgKGNoYXJDb3VudCA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsb25nIGluU2tpcHBlZDsKKyAgICAgICAgICAgIGludCBhdmFpbGFibGVGcm9tQnVmZmVyID0gYnVmLmxlbmd0aCAtIHBvczsKKyAgICAgICAgICAgIGlmIChhdmFpbGFibGVGcm9tQnVmZmVyID4gMCkgeworICAgICAgICAgICAgICAgIGxvbmcgcmVxdWlyZWRGcm9tSW4gPSBjaGFyQ291bnQgLSBhdmFpbGFibGVGcm9tQnVmZmVyOworICAgICAgICAgICAgICAgIGlmIChyZXF1aXJlZEZyb21JbiA8PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHBvcyArPSBjaGFyQ291bnQ7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBjaGFyQ291bnQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHBvcyArPSBhdmFpbGFibGVGcm9tQnVmZmVyOworICAgICAgICAgICAgICAgIGluU2tpcHBlZCA9IGluLnNraXAocmVxdWlyZWRGcm9tSW4pOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpblNraXBwZWQgPSBpbi5za2lwKGNoYXJDb3VudCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gaW5Ta2lwcGVkICsgYXZhaWxhYmxlRnJvbUJ1ZmZlcjsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1JhbmRvbUFjY2Vzc0ZpbGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1JhbmRvbUFjY2Vzc0ZpbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZGU3NzllCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vUmFuZG9tQWNjZXNzRmlsZS5qYXZhCkBAIC0wLDAgKzEsODgyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKK2ltcG9ydCBkYWx2aWsuc3lzdGVtLkNsb3NlR3VhcmQ7CitpbXBvcnQgamF2YS5uaW8uQnl0ZU9yZGVyOworaW1wb3J0IGphdmEubmlvLk5pb1V0aWxzOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkZpbGVDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuTW9kaWZpZWRVdGY4OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgbGliY29yZS5pby5FcnJub0V4Y2VwdGlvbjsKK2ltcG9ydCBsaWJjb3JlLmlvLklvQnJpZGdlOworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKK2ltcG9ydCBsaWJjb3JlLmlvLkxpYmNvcmU7CitpbXBvcnQgbGliY29yZS5pby5NZW1vcnk7CitpbXBvcnQgbGliY29yZS5pby5TaXplT2Y7CitpbXBvcnQgc3RhdGljIGxpYmNvcmUuaW8uT3NDb25zdGFudHMuKjsKKworLyoqCisgKiBBbGxvd3MgcmVhZGluZyBmcm9tIGFuZCB3cml0aW5nIHRvIGEgZmlsZSBpbiBhIHJhbmRvbS1hY2Nlc3MgbWFubmVyLiBUaGlzIGlzCisgKiBkaWZmZXJlbnQgZnJvbSB0aGUgdW5pLWRpcmVjdGlvbmFsIHNlcXVlbnRpYWwgYWNjZXNzIHRoYXQgYQorICoge0BsaW5rIEZpbGVJbnB1dFN0cmVhbX0gb3Ige0BsaW5rIEZpbGVPdXRwdXRTdHJlYW19IHByb3ZpZGVzLiBJZiB0aGUgZmlsZSBpcworICogb3BlbmVkIGluIHJlYWQvd3JpdGUgbW9kZSwgd3JpdGUgb3BlcmF0aW9ucyBhcmUgYXZhaWxhYmxlIGFzIHdlbGwuIFRoZQorICogcG9zaXRpb24gb2YgdGhlIG5leHQgcmVhZCBvciB3cml0ZSBvcGVyYXRpb24gY2FuIGJlIG1vdmVkIGZvcndhcmRzIGFuZAorICogYmFja3dhcmRzIGFmdGVyIGV2ZXJ5IG9wZXJhdGlvbi4KKyAqLworcHVibGljIGNsYXNzIFJhbmRvbUFjY2Vzc0ZpbGUgaW1wbGVtZW50cyBEYXRhSW5wdXQsIERhdGFPdXRwdXQsIENsb3NlYWJsZSB7CisgICAgLyoqCisgICAgICogVGhlIEZpbGVEZXNjcmlwdG9yIHJlcHJlc2VudGluZyB0aGlzIFJhbmRvbUFjY2Vzc0ZpbGUuCisgICAgICovCisgICAgcHJpdmF0ZSBGaWxlRGVzY3JpcHRvciBmZDsKKworICAgIHByaXZhdGUgYm9vbGVhbiBzeW5jTWV0YWRhdGEgPSBmYWxzZTsKKworICAgIC8vIFRoZSB1bmlxdWUgZmlsZSBjaGFubmVsIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEZpbGVJbnB1dFN0cmVhbSAobGF6aWx5CisgICAgLy8gaW5pdGlhbGl6ZWQpLgorICAgIHByaXZhdGUgRmlsZUNoYW5uZWwgY2hhbm5lbDsKKworICAgIHByaXZhdGUgaW50IG1vZGU7CisKKyAgICBwcml2YXRlIGZpbmFsIENsb3NlR3VhcmQgZ3VhcmQgPSBDbG9zZUd1YXJkLmdldCgpOworCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gc2NyYXRjaCA9IG5ldyBieXRlWzhdOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUmFuZG9tQWNjZXNzRmlsZX0gYmFzZWQgb24ge0Bjb2RlIGZpbGV9IGFuZCBvcGVucworICAgICAqIGl0IGFjY29yZGluZyB0byB0aGUgYWNjZXNzIHN0cmluZyBpbiB7QGNvZGUgbW9kZX0uCisgICAgICogPHA+PGEgaWQ9ImFjY2Vzc21vZGUiLz4KKyAgICAgKiB7QGNvZGUgbW9kZX0gbWF5IGhhdmUgb25lIG9mIGZvbGxvd2luZyB2YWx1ZXM6CisgICAgICogPHRhYmxlIGJvcmRlcj0iMCI+CisgICAgICogPHRyPgorICAgICAqIDx0ZD57QGNvZGUgInIifTwvdGQ+CisgICAgICogPHRkPlRoZSBmaWxlIGlzIG9wZW5lZCBpbiByZWFkLW9ubHkgbW9kZS4gQW4ge0Bjb2RlIElPRXhjZXB0aW9ufSBpcworICAgICAqIHRocm93biBpZiBhbnkgb2YgdGhlIHtAY29kZSB3cml0ZX0gbWV0aG9kcyBpcyBjYWxsZWQuPC90ZD4KKyAgICAgKiA8L3RyPgorICAgICAqIDx0cj4KKyAgICAgKiA8dGQ+e0Bjb2RlICJydyJ9PC90ZD4KKyAgICAgKiA8dGQ+VGhlIGZpbGUgaXMgb3BlbmVkIGZvciByZWFkaW5nIGFuZCB3cml0aW5nLiBJZiB0aGUgZmlsZSBkb2VzIG5vdAorICAgICAqIGV4aXN0LCBpdCB3aWxsIGJlIGNyZWF0ZWQuPC90ZD4KKyAgICAgKiA8L3RyPgorICAgICAqIDx0cj4KKyAgICAgKiA8dGQ+e0Bjb2RlICJyd3MifTwvdGQ+CisgICAgICogPHRkPlRoZSBmaWxlIGlzIG9wZW5lZCBmb3IgcmVhZGluZyBhbmQgd3JpdGluZy4gRXZlcnkgY2hhbmdlIG9mIHRoZQorICAgICAqIGZpbGUncyBjb250ZW50IG9yIG1ldGFkYXRhIG11c3QgYmUgd3JpdHRlbiBzeW5jaHJvbm91c2x5IHRvIHRoZSB0YXJnZXQKKyAgICAgKiBkZXZpY2UuPC90ZD4KKyAgICAgKiA8L3RyPgorICAgICAqIDx0cj4KKyAgICAgKiA8dGQ+e0Bjb2RlICJyd2QifTwvdGQ+CisgICAgICogPHRkPlRoZSBmaWxlIGlzIG9wZW5lZCBmb3IgcmVhZGluZyBhbmQgd3JpdGluZy4gRXZlcnkgY2hhbmdlIG9mIHRoZQorICAgICAqIGZpbGUncyBjb250ZW50IG11c3QgYmUgd3JpdHRlbiBzeW5jaHJvbm91c2x5IHRvIHRoZSB0YXJnZXQgZGV2aWNlLjwvdGQ+CisgICAgICogPC90cj4KKyAgICAgKiA8L3RhYmxlPgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWxlIHRvIG9wZW4uCisgICAgICogQHBhcmFtIG1vZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWxlIGFjY2VzcyA8YSBocmVmPSIjYWNjZXNzbW9kZSI+bW9kZTwvYT4sIGVpdGhlciB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICJyIn0sIHtAY29kZSAicncifSwge0Bjb2RlICJyd3MifSBvciB7QGNvZGUgInJ3ZCJ9LgorICAgICAqIEB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGZpbGUgY2Fubm90IGJlIG9wZW5lZCBvciBjcmVhdGVkIGFjY29yZGluZyB0byB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBtb2RlfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBtb2RlfSBpcyBub3Qge0Bjb2RlICJyIn0sIHtAY29kZSAicncifSwge0Bjb2RlCisgICAgICogICAgICAgICAgICAgInJ3cyJ9IG9yIHtAY29kZSAicndkIn0uCisgICAgICovCisgICAgcHVibGljIFJhbmRvbUFjY2Vzc0ZpbGUoRmlsZSBmaWxlLCBTdHJpbmcgbW9kZSkgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBmbGFnczsKKyAgICAgICAgaWYgKG1vZGUuZXF1YWxzKCJyIikpIHsKKyAgICAgICAgICAgIGZsYWdzID0gT19SRE9OTFk7CisgICAgICAgIH0gZWxzZSBpZiAobW9kZS5lcXVhbHMoInJ3IikgfHwgbW9kZS5lcXVhbHMoInJ3cyIpIHx8IG1vZGUuZXF1YWxzKCJyd2QiKSkgeworICAgICAgICAgICAgZmxhZ3MgPSBPX1JEV1IgfCBPX0NSRUFUOworICAgICAgICAgICAgaWYgKG1vZGUuZXF1YWxzKCJyd3MiKSkgeworICAgICAgICAgICAgICAgIC8vIFN5bmMgZmlsZSBhbmQgbWV0YWRhdGEgd2l0aCBldmVyeSB3cml0ZQorICAgICAgICAgICAgICAgIHN5bmNNZXRhZGF0YSA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgaWYgKG1vZGUuZXF1YWxzKCJyd2QiKSkgeworICAgICAgICAgICAgICAgIC8vIFN5bmMgZmlsZSwgYnV0IG5vdCBuZWNlc3NhcmlseSBtZXRhZGF0YQorICAgICAgICAgICAgICAgIGZsYWdzIHw9IE9fU1lOQzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgbW9kZTogIiArIG1vZGUpOworICAgICAgICB9CisgICAgICAgIHRoaXMubW9kZSA9IGZsYWdzOworICAgICAgICB0aGlzLmZkID0gSW9CcmlkZ2Uub3BlbihmaWxlLmdldEFic29sdXRlUGF0aCgpLCBmbGFncyk7CisKKyAgICAgICAgLy8gaWYgd2UgYXJlIGluICJyd3MiIG1vZGUsIGF0dGVtcHQgdG8gc3luYyBmaWxlK21ldGFkYXRhCisgICAgICAgIGlmIChzeW5jTWV0YWRhdGEpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZmQuc3luYygpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIElnbm9yZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBndWFyZC5vcGVuKCJjbG9zZSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFJhbmRvbUFjY2Vzc0ZpbGV9IGJhc2VkIG9uIHRoZSBmaWxlIG5hbWVkIHtAY29kZQorICAgICAqIGZpbGVOYW1lfSBhbmQgb3BlbnMgaXQgYWNjb3JkaW5nIHRvIHRoZSBhY2Nlc3Mgc3RyaW5nIGluIHtAY29kZSBtb2RlfS4KKyAgICAgKiBUaGUgZmlsZSBwYXRoIG1heSBiZSBzcGVjaWZpZWQgYWJzb2x1dGVseSBvciByZWxhdGl2ZSB0byB0aGUgc3lzdGVtCisgICAgICogcHJvcGVydHkge0Bjb2RlICJ1c2VyLmRpciJ9LgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGVOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZmlsZSB0byBvcGVuLgorICAgICAqIEBwYXJhbSBtb2RlCisgICAgICogICAgICAgICAgICB0aGUgZmlsZSBhY2Nlc3MgPGEgaHJlZj0iI2FjY2Vzc21vZGUiPm1vZGU8L2E+LCBlaXRoZXIge0Bjb2RlCisgICAgICogICAgICAgICAgICAiciJ9LCB7QGNvZGUgInJ3In0sIHtAY29kZSAicndzIn0gb3Ige0Bjb2RlICJyd2QifS4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBmaWxlIGNhbm5vdCBiZSBvcGVuZWQgb3IgY3JlYXRlZCBhY2NvcmRpbmcgdG8ge0Bjb2RlCisgICAgICogICAgICAgICAgICAgbW9kZX0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbW9kZX0gaXMgbm90IHtAY29kZSAiciJ9LCB7QGNvZGUgInJ3In0sIHtAY29kZQorICAgICAqICAgICAgICAgICAgICJyd3MifSBvciB7QGNvZGUgInJ3ZCJ9LgorICAgICAqLworICAgIHB1YmxpYyBSYW5kb21BY2Nlc3NGaWxlKFN0cmluZyBmaWxlTmFtZSwgU3RyaW5nIG1vZGUpIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICB0aGlzKG5ldyBGaWxlKGZpbGVOYW1lKSwgbW9kZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgZmlsZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY2xvc2luZyB0aGlzIGZpbGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBndWFyZC5jbG9zZSgpOworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGlmIChjaGFubmVsICE9IG51bGwgJiYgY2hhbm5lbC5pc09wZW4oKSkgeworICAgICAgICAgICAgICAgIGNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBjaGFubmVsID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIElvVXRpbHMuY2xvc2UoZmQpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoZ3VhcmQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGd1YXJkLndhcm5JZk9wZW4oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNsb3NlKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzdXBlci5maW5hbGl6ZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGlzIGZpbGUncyB7QGxpbmsgRmlsZUNoYW5uZWx9IG9iamVjdC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZmlsZSBjaGFubmVsJ3Mge0BsaW5rIEZpbGVDaGFubmVsI3Bvc2l0aW9uKCkgcG9zaXRpb259IGlzIHRoZSBzYW1lCisgICAgICogYXMgdGhpcyBmaWxlJ3MgZmlsZSBwb2ludGVyIG9mZnNldCAoc2VlIHtAbGluayAjZ2V0RmlsZVBvaW50ZXIoKX0pLiBBbnkKKyAgICAgKiBjaGFuZ2VzIG1hZGUgdG8gdGhpcyBmaWxlJ3MgZmlsZSBwb2ludGVyIG9mZnNldCBhcmUgYWxzbyB2aXNpYmxlIGluIHRoZQorICAgICAqIGZpbGUgY2hhbm5lbCdzIHBvc2l0aW9uIGFuZCB2aWNlIHZlcnNhLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIGZpbGUncyBmaWxlIGNoYW5uZWwgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHN5bmNocm9uaXplZCBGaWxlQ2hhbm5lbCBnZXRDaGFubmVsKCkgeworICAgICAgICBpZihjaGFubmVsID09IG51bGwpIHsKKyAgICAgICAgICAgIGNoYW5uZWwgPSBOaW9VdGlscy5uZXdGaWxlQ2hhbm5lbCh0aGlzLCBmZCwgbW9kZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNoYW5uZWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGlzIGZpbGUncyB7QGxpbmsgRmlsZURlc2NyaXB0b3J9LiBUaGlzIHJlcHJlc2VudHMgdGhlIG9wZXJhdGluZworICAgICAqIHN5c3RlbSByZXNvdXJjZSBmb3IgdGhpcyByYW5kb20gYWNjZXNzIGZpbGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgZmlsZSdzIGZpbGUgZGVzY3JpcHRvciBvYmplY3QuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBnZXR0aW5nIHRoZSBmaWxlIGRlc2NyaXB0b3Igb2YgdGhpcworICAgICAqICAgICAgICAgICAgIGZpbGUuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEZpbGVEZXNjcmlwdG9yIGdldEZEKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGZkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGN1cnJlbnQgcG9zaXRpb24gd2l0aGluIHRoaXMgZmlsZS4gQWxsIHJlYWRzIGFuZAorICAgICAqIHdyaXRlcyB0YWtlIHBsYWNlIGF0IHRoZSBjdXJyZW50IGZpbGUgcG9pbnRlciBwb3NpdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgb2Zmc2V0IGluIGJ5dGVzIGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgZmlsZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgZ2V0dGluZyB0aGUgZmlsZSBwb2ludGVyIG9mIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldEZpbGVQb2ludGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBMaWJjb3JlLm9zLmxzZWVrKGZkLCAwTCwgU0VFS19DVVIpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzSU9FeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGlzIGZpbGUgaW4gYnl0ZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBmaWxlJ3MgbGVuZ3RoIGluIGJ5dGVzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpbGUgaXMgY2xvc2VkIG9yIHNvbWUgb3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBsZW5ndGgoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIExpYmNvcmUub3MuZnN0YXQoZmQpLnN0X3NpemU7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyBlcnJub0V4Y2VwdGlvbi5yZXRocm93QXNJT0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBzaW5nbGUgYnl0ZSBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoaXMgZmlsZSBhbmQgcmV0dXJucyBpdAorICAgICAqIGFzIGFuIGludGVnZXIgaW4gdGhlIHJhbmdlIGZyb20gMCB0byAyNTUuIFJldHVybnMgLTEgaWYgdGhlIGVuZCBvZiB0aGUKKyAgICAgKiBmaWxlIGhhcyBiZWVuIHJlYWNoZWQuIEJsb2NrcyB1bnRpbCBvbmUgYnl0ZSBoYXMgYmVlbiByZWFkLCB0aGUgZW5kIG9mCisgICAgICogdGhlIGZpbGUgaXMgZGV0ZWN0ZWQsIG9yIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBieXRlIHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgZmlsZSBoYXMgYmVlbiByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpbGUgaXMgY2xvc2VkIG9yIGFub3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gKHJlYWQoc2NyYXRjaCwgMCwgMSkgIT0gLTEpID8gc2NyYXRjaFswXSAmIDB4ZmYgOiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBieXRlcyBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoaXMgZmlsZSBhbmQgc3RvcmVzIHRoZW0gaW4gdGhlCisgICAgICogYnl0ZSBhcnJheSB7QGNvZGUgYnVmZmVyfS4gVGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHJlYWQgY29ycmVzcG9uZHMKKyAgICAgKiB0byB0aGUgc2l6ZSBvZiB7QGNvZGUgYnVmZmVyfS4gQmxvY2tzIHVudGlsIGF0IGxlYXN0IG9uZSBieXRlIGhhcyBiZWVuCisgICAgICogcmVhZCwgdGhlIGVuZCBvZiB0aGUgZmlsZSBpcyBkZXRlY3RlZCwgb3IgYW4gZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGFycmF5IGluIHdoaWNoIHRvIHN0b3JlIHRoZSBieXRlcyByZWFkLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSByZWFkIG9yIC0xIGlmIHRoZSBlbmQgb2YgdGhlIGZpbGUKKyAgICAgKiAgICAgICAgIGhhcyBiZWVuIHJlYWNoZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgZmlsZSBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmZmVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcmVhZChidWZmZXIsIDAsIGJ1ZmZlci5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGF0IG1vc3Qge0Bjb2RlIGJ5dGVDb3VudH0gYnl0ZXMgZnJvbSB0aGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGlzIGZpbGUKKyAgICAgKiBhbmQgc3RvcmVzIHRoZW0gaW4gdGhlIGJ5dGUgYXJyYXkge0Bjb2RlIGJ1ZmZlcn0gc3RhcnRpbmcgYXQge0Bjb2RlCisgICAgICogYnl0ZU9mZnNldH0uIEJsb2NrcyB1bnRpbCBhdCBsZWFzdCBvbmUgYnl0ZSBoYXMgYmVlbgorICAgICAqIHJlYWQsIHRoZSBlbmQgb2YgdGhlIGZpbGUgaXMgZGV0ZWN0ZWQsIG9yIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZSBzdHJlYW0KKyAgICAgKiAgICAgICAgIGhhcyBiZWVuIHJlYWNoZWQuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGJ5dGVPZmZzZXQgPCAwfSBvciB7QGNvZGUgYnl0ZUNvdW50IDwgMH0sIG9yIGlmIHtAY29kZQorICAgICAqICAgICAgICAgICAgIGJ5dGVPZmZzZXQgKyBieXRlQ291bnR9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgc2l6ZSBvZiB7QGNvZGUgYnVmZmVyfS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBmaWxlIGlzIGNsb3NlZCBvciBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGludCByZWFkKGJ5dGVbXSBidWZmZXIsIGludCBieXRlT2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gSW9CcmlkZ2UucmVhZChmZCwgYnVmZmVyLCBieXRlT2Zmc2V0LCBieXRlQ291bnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgYm9vbGVhbiBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoaXMgZmlsZS4gQmxvY2tzIHVudGlsIG9uZQorICAgICAqIGJ5dGUgaGFzIGJlZW4gcmVhZCwgdGhlIGVuZCBvZiB0aGUgZmlsZSBpcyByZWFjaGVkIG9yIGFuIGV4Y2VwdGlvbiBpcworICAgICAqIHRocm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgYm9vbGVhbiB2YWx1ZSBmcm9tIHRoaXMgZmlsZS4KKyAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmQgb2YgdGhpcyBmaWxlIGlzIGRldGVjdGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpbGUgaXMgY2xvc2VkIG9yIGFub3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlICN3cml0ZUJvb2xlYW4oYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiByZWFkQm9vbGVhbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCB0ZW1wID0gdGhpcy5yZWFkKCk7CisgICAgICAgIGlmICh0ZW1wIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0ZW1wICE9IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYW4gOC1iaXQgYnl0ZSBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoaXMgZmlsZS4gQmxvY2tzIHVudGlsCisgICAgICogb25lIGJ5dGUgaGFzIGJlZW4gcmVhZCwgdGhlIGVuZCBvZiB0aGUgZmlsZSBpcyByZWFjaGVkIG9yIGFuIGV4Y2VwdGlvbiBpcworICAgICAqIHRocm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgc2lnbmVkIDgtYml0IGJ5dGUgdmFsdWUgZnJvbSB0aGlzIGZpbGUuCisgICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZW5kIG9mIHRoaXMgZmlsZSBpcyBkZXRlY3RlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBmaWxlIGlzIGNsb3NlZCBvciBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSAjd3JpdGVCb29sZWFuKGJvb2xlYW4pCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJ5dGUgcmVhZEJ5dGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgdGVtcCA9IHRoaXMucmVhZCgpOworICAgICAgICBpZiAodGVtcCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKGJ5dGUpIHRlbXA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBiaWctZW5kaWFuIDE2LWJpdCBjaGFyYWN0ZXIgZnJvbSB0aGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGlzIGZpbGUuIEJsb2NrcyB1bnRpbAorICAgICAqIHR3byBieXRlcyBoYXZlIGJlZW4gcmVhZCwgdGhlIGVuZCBvZiB0aGUgZmlsZSBpcyByZWFjaGVkIG9yIGFuIGV4Y2VwdGlvbiBpcworICAgICAqIHRocm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgY2hhciB2YWx1ZSBmcm9tIHRoaXMgZmlsZS4KKyAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmQgb2YgdGhpcyBmaWxlIGlzIGRldGVjdGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpbGUgaXMgY2xvc2VkIG9yIGFub3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlICN3cml0ZUNoYXIoaW50KQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBjaGFyIHJlYWRDaGFyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIChjaGFyKSByZWFkU2hvcnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGJpZy1lbmRpYW4gNjQtYml0IGRvdWJsZSBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoaXMgZmlsZS4gQmxvY2tzCisgICAgICogdW50aWwgZWlnaHQgYnl0ZXMgaGF2ZSBiZWVuIHJlYWQsIHRoZSBlbmQgb2YgdGhlIGZpbGUgaXMgcmVhY2hlZCBvciBhbgorICAgICAqIGV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGRvdWJsZSB2YWx1ZSBmcm9tIHRoaXMgZmlsZS4KKyAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmQgb2YgdGhpcyBmaWxlIGlzIGRldGVjdGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpbGUgaXMgY2xvc2VkIG9yIGFub3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlICN3cml0ZURvdWJsZShkb3VibGUpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGRvdWJsZSByZWFkRG91YmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIERvdWJsZS5sb25nQml0c1RvRG91YmxlKHJlYWRMb25nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgYmlnLWVuZGlhbiAzMi1iaXQgZmxvYXQgZnJvbSB0aGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGlzIGZpbGUuIEJsb2NrcworICAgICAqIHVudGlsIGZvdXIgYnl0ZXMgaGF2ZSBiZWVuIHJlYWQsIHRoZSBlbmQgb2YgdGhlIGZpbGUgaXMgcmVhY2hlZCBvciBhbgorICAgICAqIGV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGZsb2F0IHZhbHVlIGZyb20gdGhpcyBmaWxlLgorICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGVuZCBvZiB0aGlzIGZpbGUgaXMgZGV0ZWN0ZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgZmlsZSBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgI3dyaXRlRmxvYXQoZmxvYXQpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGZsb2F0IHJlYWRGbG9hdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBGbG9hdC5pbnRCaXRzVG9GbG9hdChyZWFkSW50KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8ge0Bjb2RlIHJlYWRGdWxseShkc3QsIDAsIGRzdC5sZW5ndGgpO30uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgcmVhZEZ1bGx5KGJ5dGVbXSBkc3QpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJlYWRGdWxseShkc3QsIDAsIGRzdC5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHtAY29kZSBieXRlQ291bnR9IGJ5dGVzIGZyb20gdGhpcyBzdHJlYW0gYW5kIHN0b3JlcyB0aGVtIGluIHRoZSBieXRlCisgICAgICogYXJyYXkge0Bjb2RlIGRzdH0gc3RhcnRpbmcgYXQge0Bjb2RlIG9mZnNldH0uIElmIHtAY29kZSBieXRlQ291bnR9IGlzIHplcm8sIHRoZW4gdGhpcworICAgICAqIG1ldGhvZCByZXR1cm5zIHdpdGhvdXQgcmVhZGluZyBhbnkgYnl0ZXMuIE90aGVyd2lzZSwgdGhpcyBtZXRob2QgYmxvY2tzIHVudGlsCisgICAgICoge0Bjb2RlIGJ5dGVDb3VudH0gYnl0ZXMgaGF2ZSBiZWVuIHJlYWQuIElmIGluc3VmZmljaWVudCBieXRlcyBhcmUgYXZhaWxhYmxlLAorICAgICAqIHtAY29kZSBFT0ZFeGNlcHRpb259IGlzIHRocm93bi4gSWYgYW4gSS9PIGVycm9yIG9jY3Vycywge0Bjb2RlIElPRXhjZXB0aW9ufSBpcworICAgICAqIHRocm93bi4gV2hlbiBhbiBleGNlcHRpb24gaXMgdGhyb3duLCBzb21lIGJ5dGVzIG1heSBoYXZlIGJlZW4gY29uc3VtZWQgZnJvbSB0aGUgc3RyZWFtCisgICAgICogYW5kIHdyaXR0ZW4gaW50byB0aGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSBhcnJheSBpbnRvIHdoaWNoIHRoZSBkYXRhIGlzIHJlYWQuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB7QGNvZGUgZHN0fSBhdCB3aGljaCB0byBzdG9yZSB0aGUgYnl0ZXMuCisgICAgICogQHBhcmFtIGJ5dGVDb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyB0byByZWFkLgorICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGVuZCBvZiB0aGUgc291cmNlIHN0cmVhbSBpcyByZWFjaGVkIGJlZm9yZSBlbm91Z2gKKyAgICAgKiAgICAgICAgICAgICBieXRlcyBoYXZlIGJlZW4gcmVhZC4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGJ5dGVDb3VudCA8IDB9LCBvcgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBieXRlQ291bnQgPiBkc3QubGVuZ3RofS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhpcyBzdHJlYW0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkc3R9IGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgcmVhZEZ1bGx5KGJ5dGVbXSBkc3QsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGRzdC5sZW5ndGgsIG9mZnNldCwgYnl0ZUNvdW50KTsKKyAgICAgICAgd2hpbGUgKGJ5dGVDb3VudCA+IDApIHsKKyAgICAgICAgICAgIGludCByZXN1bHQgPSByZWFkKGRzdCwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICAgICAgaWYgKHJlc3VsdCA8IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBvZmZzZXQgKz0gcmVzdWx0OworICAgICAgICAgICAgYnl0ZUNvdW50IC09IHJlc3VsdDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgYmlnLWVuZGlhbiAzMi1iaXQgaW50ZWdlciBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoaXMgZmlsZS4gQmxvY2tzCisgICAgICogdW50aWwgZm91ciBieXRlcyBoYXZlIGJlZW4gcmVhZCwgdGhlIGVuZCBvZiB0aGUgZmlsZSBpcyByZWFjaGVkIG9yIGFuCisgICAgICogZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgaW50IHZhbHVlIGZyb20gdGhpcyBmaWxlLgorICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGVuZCBvZiB0aGlzIGZpbGUgaXMgZGV0ZWN0ZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgZmlsZSBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgI3dyaXRlSW50KGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IHJlYWRJbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZWFkRnVsbHkoc2NyYXRjaCwgMCwgU2l6ZU9mLklOVCk7CisgICAgICAgIHJldHVybiBNZW1vcnkucGVla0ludChzY3JhdGNoLCAwLCBCeXRlT3JkZXIuQklHX0VORElBTik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBsaW5lIG9mIHRleHQgZm9ybSB0aGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGlzIGZpbGUuIEEgbGluZSBpcworICAgICAqIHJlcHJlc2VudGVkIGJ5IHplcm8gb3IgbW9yZSBjaGFyYWN0ZXJzIGZvbGxvd2VkIGJ5IHtAY29kZSAnXG4nfSwge0Bjb2RlCisgICAgICogJ1xyJ30sIHtAY29kZSAiXHJcbiJ9IG9yIHRoZSBlbmQgb2YgZmlsZSBtYXJrZXIuIFRoZSBzdHJpbmcgZG9lcyBub3QKKyAgICAgKiBpbmNsdWRlIHRoZSBsaW5lIHRlcm1pbmF0aW5nIHNlcXVlbmNlLgorICAgICAqIDxwPgorICAgICAqIEJsb2NrcyB1bnRpbCBhIGxpbmUgdGVybWluYXRpbmcgc2VxdWVuY2UgaGFzIGJlZW4gcmVhZCwgdGhlIGVuZCBvZiB0aGUKKyAgICAgKiBmaWxlIGlzIHJlYWNoZWQgb3IgYW4gZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNvbnRlbnRzIG9mIHRoZSBsaW5lIG9yIHtAY29kZSBudWxsfSBpZiBubyBjaGFyYWN0ZXJzIGhhdmUKKyAgICAgKiAgICAgICAgIGJlZW4gcmVhZCBiZWZvcmUgdGhlIGVuZCBvZiB0aGUgZmlsZSBoYXMgYmVlbiByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpbGUgaXMgY2xvc2VkIG9yIGFub3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIHJlYWRMaW5lKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBsaW5lID0gbmV3IFN0cmluZ0J1aWxkZXIoODApOyAvLyBUeXBpY2FsIGxpbmUgbGVuZ3RoCisgICAgICAgIGJvb2xlYW4gZm91bmRUZXJtaW5hdG9yID0gZmFsc2U7CisgICAgICAgIGxvbmcgdW5yZWFkUG9zaXRpb24gPSAwOworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgaW50IG5leHRCeXRlID0gcmVhZCgpOworICAgICAgICAgICAgc3dpdGNoIChuZXh0Qnl0ZSkgeworICAgICAgICAgICAgICAgIGNhc2UgLTE6CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBsaW5lLmxlbmd0aCgpICE9IDAgPyBsaW5lLnRvU3RyaW5nKCkgOiBudWxsOworICAgICAgICAgICAgICAgIGNhc2UgKGJ5dGUpICdccic6CisgICAgICAgICAgICAgICAgICAgIGlmIChmb3VuZFRlcm1pbmF0b3IpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlZWsodW5yZWFkUG9zaXRpb24pOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxpbmUudG9TdHJpbmcoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBmb3VuZFRlcm1pbmF0b3IgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAvKiBIYXZlIHRvIGJlIGFibGUgdG8gcGVlayBhaGVhZCBvbmUgYnl0ZSAqLworICAgICAgICAgICAgICAgICAgICB1bnJlYWRQb3NpdGlvbiA9IGdldEZpbGVQb2ludGVyKCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgKGJ5dGUpICdcbic6CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBsaW5lLnRvU3RyaW5nKCk7CisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kVGVybWluYXRvcikgeworICAgICAgICAgICAgICAgICAgICAgICAgc2Vlayh1bnJlYWRQb3NpdGlvbik7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGluZS50b1N0cmluZygpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGxpbmUuYXBwZW5kKChjaGFyKSBuZXh0Qnl0ZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGJpZy1lbmRpYW4gNjQtYml0IGxvbmcgZnJvbSB0aGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGlzIGZpbGUuIEJsb2NrcyB1bnRpbAorICAgICAqIGVpZ2h0IGJ5dGVzIGhhdmUgYmVlbiByZWFkLCB0aGUgZW5kIG9mIHRoZSBmaWxlIGlzIHJlYWNoZWQgb3IgYW4KKyAgICAgKiBleGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBsb25nIHZhbHVlIGZyb20gdGhpcyBmaWxlLgorICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGVuZCBvZiB0aGlzIGZpbGUgaXMgZGV0ZWN0ZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgZmlsZSBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgI3dyaXRlTG9uZyhsb25nKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBsb25nIHJlYWRMb25nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmVhZEZ1bGx5KHNjcmF0Y2gsIDAsIFNpemVPZi5MT05HKTsKKyAgICAgICAgcmV0dXJuIE1lbW9yeS5wZWVrTG9uZyhzY3JhdGNoLCAwLCBCeXRlT3JkZXIuQklHX0VORElBTik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBiaWctZW5kaWFuIDE2LWJpdCBzaG9ydCBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoaXMgZmlsZS4gQmxvY2tzIHVudGlsCisgICAgICogdHdvIGJ5dGVzIGhhdmUgYmVlbiByZWFkLCB0aGUgZW5kIG9mIHRoZSBmaWxlIGlzIHJlYWNoZWQgb3IgYW4gZXhjZXB0aW9uCisgICAgICogaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBzaG9ydCB2YWx1ZSBmcm9tIHRoaXMgZmlsZS4KKyAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmQgb2YgdGhpcyBmaWxlIGlzIGRldGVjdGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpbGUgaXMgY2xvc2VkIG9yIGFub3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlICN3cml0ZVNob3J0KGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgc2hvcnQgcmVhZFNob3J0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmVhZEZ1bGx5KHNjcmF0Y2gsIDAsIFNpemVPZi5TSE9SVCk7CisgICAgICAgIHJldHVybiBNZW1vcnkucGVla1Nob3J0KHNjcmF0Y2gsIDAsIEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhbiB1bnNpZ25lZCA4LWJpdCBieXRlIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhpcyBmaWxlIGFuZAorICAgICAqIHJldHVybnMgaXQgYXMgYW4gaW50ZWdlci4gQmxvY2tzIHVudGlsIG9uZSBieXRlIGhhcyBiZWVuIHJlYWQsIHRoZSBlbmQgb2YKKyAgICAgKiB0aGUgZmlsZSBpcyByZWFjaGVkIG9yIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IHVuc2lnbmVkIGJ5dGUgdmFsdWUgZnJvbSB0aGlzIGZpbGUgYXMgYW4gaW50LgorICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGVuZCBvZiB0aGlzIGZpbGUgaXMgZGV0ZWN0ZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgZmlsZSBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgI3dyaXRlQnl0ZShpbnQpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCByZWFkVW5zaWduZWRCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHRlbXAgPSB0aGlzLnJlYWQoKTsKKyAgICAgICAgaWYgKHRlbXAgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRlbXA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYW4gdW5zaWduZWQgYmlnLWVuZGlhbiAxNi1iaXQgc2hvcnQgZnJvbSB0aGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGlzIGZpbGUgYW5kCisgICAgICogcmV0dXJucyBpdCBhcyBhbiBpbnRlZ2VyLiBCbG9ja3MgdW50aWwgdHdvIGJ5dGVzIGhhdmUgYmVlbiByZWFkLCB0aGUgZW5kIG9mCisgICAgICogdGhlIGZpbGUgaXMgcmVhY2hlZCBvciBhbiBleGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCB1bnNpZ25lZCBzaG9ydCB2YWx1ZSBmcm9tIHRoaXMgZmlsZSBhcyBhbiBpbnQuCisgICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZW5kIG9mIHRoaXMgZmlsZSBpcyBkZXRlY3RlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBmaWxlIGlzIGNsb3NlZCBvciBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSAjd3JpdGVTaG9ydChpbnQpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCByZWFkVW5zaWduZWRTaG9ydCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiAoKGludCkgcmVhZFNob3J0KCkpICYgMHhmZmZmOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgc3RyaW5nIHRoYXQgaXMgZW5jb2RlZCBpbiB7QGxpbmsgRGF0YUlucHV0IG1vZGlmaWVkIFVURi04fSBmcm9tCisgICAgICogdGhpcyBmaWxlLiBUaGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgbXVzdCBiZSByZWFkIGZvciB0aGUgY29tcGxldGUgc3RyaW5nCisgICAgICogaXMgZGV0ZXJtaW5lZCBieSB0aGUgZmlyc3QgdHdvIGJ5dGVzIHJlYWQgZnJvbSB0aGUgZmlsZS4gQmxvY2tzIHVudGlsIGFsbAorICAgICAqIHJlcXVpcmVkIGJ5dGVzIGhhdmUgYmVlbiByZWFkLCB0aGUgZW5kIG9mIHRoZSBmaWxlIGlzIHJlYWNoZWQgb3IgYW4KKyAgICAgKiBleGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBzdHJpbmcgZW5jb2RlZCBpbiB7QGxpbmsgRGF0YUlucHV0IG1vZGlmaWVkIFVURi04fSBmcm9tCisgICAgICogICAgICAgICB0aGlzIGZpbGUuCisgICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZW5kIG9mIHRoaXMgZmlsZSBpcyBkZXRlY3RlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBmaWxlIGlzIGNsb3NlZCBvciBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHRocm93cyBVVEZEYXRhRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGJ5dGVzIHJlYWQgY2Fubm90IGJlIGRlY29kZWQgaW50byBhIGNoYXJhY3RlciBzdHJpbmcuCisgICAgICogQHNlZSAjd3JpdGVVVEYoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgcmVhZFVURigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCB1dGZTaXplID0gcmVhZFVuc2lnbmVkU2hvcnQoKTsKKyAgICAgICAgaWYgKHV0ZlNpemUgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuICIiOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVt1dGZTaXplXTsKKyAgICAgICAgaWYgKHJlYWQoYnVmLCAwLCBidWYubGVuZ3RoKSAhPSBidWYubGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIE1vZGlmaWVkVXRmOC5kZWNvZGUoYnVmLCBuZXcgY2hhclt1dGZTaXplXSwgMCwgdXRmU2l6ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTW92ZXMgdGhpcyBmaWxlJ3MgZmlsZSBwb2ludGVyIHRvIGEgbmV3IHBvc2l0aW9uLCBmcm9tIHdoZXJlIGZvbGxvd2luZworICAgICAqIHtAY29kZSByZWFkfSwge0Bjb2RlIHdyaXRlfSBvciB7QGNvZGUgc2tpcH0gb3BlcmF0aW9ucyBhcmUgZG9uZS4gVGhlCisgICAgICogcG9zaXRpb24gbWF5IGJlIGdyZWF0ZXIgdGhhbiB0aGUgY3VycmVudCBsZW5ndGggb2YgdGhlIGZpbGUsIGJ1dCB0aGUKKyAgICAgKiBmaWxlJ3MgbGVuZ3RoIHdpbGwgb25seSBjaGFuZ2UgaWYgdGhlIG1vdmluZyBvZiB0aGUgcG9pbnRlciBpcyBmb2xsb3dlZAorICAgICAqIGJ5IGEge0Bjb2RlIHdyaXRlfSBvcGVyYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgbmV3IGZpbGUgcG9pbnRlciBwb3NpdGlvbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBmaWxlIGlzIGNsb3NlZCwge0Bjb2RlIHBvcyA8IDB9IG9yIGFub3RoZXIgSS9PIGVycm9yCisgICAgICogICAgICAgICAgICAgb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNlZWsobG9uZyBvZmZzZXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChvZmZzZXQgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIm9mZnNldCA8IDA6ICIgKyBvZmZzZXQpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMaWJjb3JlLm9zLmxzZWVrKGZkLCBvZmZzZXQsIFNFRUtfU0VUKTsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRocm93IGVycm5vRXhjZXB0aW9uLnJldGhyb3dBc0lPRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBsZW5ndGggb2YgdGhpcyBmaWxlIHRvIHtAY29kZSBuZXdMZW5ndGh9LiBJZiB0aGUgY3VycmVudCBmaWxlIGlzCisgICAgICogc21hbGxlciwgaXQgaXMgZXhwYW5kZWQgYnV0IHRoZSBjb250ZW50cyBmcm9tIHRoZSBwcmV2aW91cyBlbmQgb2YgdGhlCisgICAgICogZmlsZSB0byB0aGUgbmV3IGVuZCBhcmUgdW5kZWZpbmVkLiBUaGUgZmlsZSBpcyB0cnVuY2F0ZWQgaWYgaXRzIGN1cnJlbnQKKyAgICAgKiBzaXplIGlzIGJpZ2dlciB0aGFuIHtAY29kZSBuZXdMZW5ndGh9LiBJZiB0aGUgY3VycmVudCBmaWxlIHBvaW50ZXIKKyAgICAgKiBwb3NpdGlvbiBpcyBpbiB0aGUgdHJ1bmNhdGVkIHBhcnQsIGl0IGlzIHNldCB0byB0aGUgZW5kIG9mIHRoZSBmaWxlLgorICAgICAqCisgICAgICogQHBhcmFtIG5ld0xlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBmaWxlIGxlbmd0aCBpbiBieXRlcy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBuZXdMZW5ndGggPCAwfS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBmaWxlIGlzIGNsb3NlZCBvciBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TGVuZ3RoKGxvbmcgbmV3TGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAobmV3TGVuZ3RoIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibmV3TGVuZ3RoIDwgMCIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMaWJjb3JlLm9zLmZ0cnVuY2F0ZShmZCwgbmV3TGVuZ3RoKTsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRocm93IGVycm5vRXhjZXB0aW9uLnJldGhyb3dBc0lPRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBsb25nIGZpbGVQb2ludGVyID0gZ2V0RmlsZVBvaW50ZXIoKTsKKyAgICAgICAgaWYgKGZpbGVQb2ludGVyID4gbmV3TGVuZ3RoKSB7CisgICAgICAgICAgICBzZWVrKG5ld0xlbmd0aCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBpZiB3ZSBhcmUgaW4gInJ3cyIgbW9kZSwgYXR0ZW1wdCB0byBzeW5jIGZpbGUrbWV0YWRhdGEKKyAgICAgICAgaWYgKHN5bmNNZXRhZGF0YSkgeworICAgICAgICAgICAgZmQuc3luYygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcHMgb3ZlciB7QGNvZGUgY291bnR9IGJ5dGVzIGluIHRoaXMgZmlsZS4gTGVzcyB0aGFuIHtAY29kZSBjb3VudH0KKyAgICAgKiBieXRlcyBhcmUgc2tpcHBlZCBpZiB0aGUgZW5kIG9mIHRoZSBmaWxlIGlzIHJlYWNoZWQgb3IgYW4gZXhjZXB0aW9uIGlzCisgICAgICogdGhyb3duIGR1cmluZyB0aGUgb3BlcmF0aW9uLiBOb3RoaW5nIGlzIGRvbmUgaWYge0Bjb2RlIGNvdW50fSBpcworICAgICAqIG5lZ2F0aXZlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvdW50CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHNraXAuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHNraXBwZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgZmlsZSBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2tpcEJ5dGVzKGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNvdW50ID4gMCkgeworICAgICAgICAgICAgbG9uZyBjdXJyZW50UG9zID0gZ2V0RmlsZVBvaW50ZXIoKSwgZW9mID0gbGVuZ3RoKCk7CisgICAgICAgICAgICBpbnQgbmV3Q291bnQgPSAoaW50KSAoKGN1cnJlbnRQb3MgKyBjb3VudCA+IGVvZikgPyBlb2YgLSBjdXJyZW50UG9zIDogY291bnQpOworICAgICAgICAgICAgc2VlayhjdXJyZW50UG9zICsgbmV3Q291bnQpOworICAgICAgICAgICAgcmV0dXJuIG5ld0NvdW50OworICAgICAgICB9CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgZW50aXJlIGNvbnRlbnRzIG9mIHRoZSBieXRlIGFycmF5IHtAY29kZSBidWZmZXJ9IHRvIHRoaXMgZmlsZSwKKyAgICAgKiBzdGFydGluZyBhdCB0aGUgY3VycmVudCBmaWxlIHBvaW50ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhpcyBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBidWZmZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlKGJ1ZmZlciwgMCwgYnVmZmVyLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHtAY29kZSBieXRlQ291bnR9IGJ5dGVzIGZyb20gdGhlIGJ5dGUgYXJyYXkge0Bjb2RlIGJ1ZmZlcn0gdG8gdGhpcworICAgICAqIGZpbGUsIHN0YXJ0aW5nIGF0IHRoZSBjdXJyZW50IGZpbGUgcG9pbnRlciBhbmQgdXNpbmcge0Bjb2RlIGJ5dGVPZmZzZXR9IGFzCisgICAgICogdGhlIGZpcnN0IHBvc2l0aW9uIHdpdGhpbiB7QGNvZGUgYnVmZmVyfSB0byBnZXQgYnl0ZXMuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYnl0ZUNvdW50IDwgMH0sIHtAY29kZSBieXRlT2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGJ5dGVDb3VudCArCisgICAgICogICAgICAgICAgICAgYnl0ZU9mZnNldH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBzaXplIG9mIHtAY29kZSBidWZmZXJ9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhpcyBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBidWZmZXIsIGludCBieXRlT2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBJb0JyaWRnZS53cml0ZShmZCwgYnVmZmVyLCBieXRlT2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICAvLyBpZiB3ZSBhcmUgaW4gInJ3cyIgbW9kZSwgYXR0ZW1wdCB0byBzeW5jIGZpbGUrbWV0YWRhdGEKKyAgICAgICAgaWYgKHN5bmNNZXRhZGF0YSkgeworICAgICAgICAgICAgZmQuc3luYygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgYnl0ZSB0byB0aGlzIGZpbGUsIHN0YXJ0aW5nIGF0IHRoZSBjdXJyZW50IGZpbGUgcG9pbnRlci4gT25seQorICAgICAqIHRoZSBsZWFzdCBzaWduaWZpY2FudCBieXRlIG9mIHRoZSBpbnRlZ2VyIHtAY29kZSBvbmVCeXRlfSBpcyB3cml0dGVuLgorICAgICAqCisgICAgICogQHBhcmFtIG9uZUJ5dGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIHRvIHdyaXRlIHRvIHRoaXMgZmlsZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBmaWxlIGlzIGNsb3NlZCBvciBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSAjcmVhZCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IG9uZUJ5dGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHNjcmF0Y2hbMF0gPSAoYnl0ZSkgKG9uZUJ5dGUgJiAweGZmKTsKKyAgICAgICAgd3JpdGUoc2NyYXRjaCwgMCwgMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgYm9vbGVhbiB0byB0aGlzIGZpbGUgYXMgYSBzaW5nbGUgYnl0ZSAoMSBmb3IgdHJ1ZSwgMCBmb3IgZmFsc2UpLCBzdGFydGluZyBhdCB0aGUKKyAgICAgKiBjdXJyZW50IGZpbGUgcG9pbnRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBib29sZWFuIHRvIHdyaXRlIHRvIHRoaXMgZmlsZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBmaWxlIGlzIGNsb3NlZCBvciBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSAjcmVhZEJvb2xlYW4oKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHdyaXRlQm9vbGVhbihib29sZWFuIHZhbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGUodmFsID8gMSA6IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhbiA4LWJpdCBieXRlIHRvIHRoaXMgZmlsZSwgc3RhcnRpbmcgYXQgdGhlIGN1cnJlbnQgZmlsZSBwb2ludGVyLgorICAgICAqIE9ubHkgdGhlIGxlYXN0IHNpZ25pZmljYW50IGJ5dGUgb2YgdGhlIGludGVnZXIge0Bjb2RlIHZhbH0gaXMgd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIHRvIHdyaXRlIHRvIHRoaXMgZmlsZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBmaWxlIGlzIGNsb3NlZCBvciBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSAjcmVhZEJ5dGUoKQorICAgICAqIEBzZWUgI3JlYWRVbnNpZ25lZEJ5dGUoKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHdyaXRlQnl0ZShpbnQgdmFsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3cml0ZSh2YWwgJiAweEZGKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGxvdyBvcmRlciA4LWJpdCBieXRlcyBmcm9tIGEgc3RyaW5nIHRvIHRoaXMgZmlsZSwgc3RhcnRpbmcgYXQKKyAgICAgKiB0aGUgY3VycmVudCBmaWxlIHBvaW50ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGJ5dGVzIHRvIHdyaXRlIHRvIHRoaXMgZmlsZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhpcyBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHdyaXRlQnl0ZXMoU3RyaW5nIHN0cikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbc3RyLmxlbmd0aCgpXTsKKyAgICAgICAgZm9yIChpbnQgaW5kZXggPSAwOyBpbmRleCA8IHN0ci5sZW5ndGgoKTsgaW5kZXgrKykgeworICAgICAgICAgICAgYnl0ZXNbaW5kZXhdID0gKGJ5dGUpIChzdHIuY2hhckF0KGluZGV4KSAmIDB4RkYpOworICAgICAgICB9CisgICAgICAgIHdyaXRlKGJ5dGVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBiaWctZW5kaWFuIDE2LWJpdCBjaGFyYWN0ZXIgdG8gdGhpcyBmaWxlLCBzdGFydGluZyBhdCB0aGUgY3VycmVudCBmaWxlCisgICAgICogcG9pbnRlci4gT25seSB0aGUgdHdvIGxlYXN0IHNpZ25pZmljYW50IGJ5dGVzIG9mIHRoZSBpbnRlZ2VyIHtAY29kZSB2YWx9CisgICAgICogYXJlIHdyaXR0ZW4sIHdpdGggdGhlIGhpZ2ggYnl0ZSBmaXJzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyIHRvIHdyaXRlIHRvIHRoaXMgZmlsZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoaXMgZmlsZS4KKyAgICAgKiBAc2VlICNyZWFkQ2hhcigpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgd3JpdGVDaGFyKGludCB2YWwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlU2hvcnQodmFsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYmlnLWVuZGlhbiAxNi1iaXQgY2hhcmFjdGVycyBmcm9tIHtAY29kZSBzdHJ9IHRvIHRoaXMgZmlsZSwgc3RhcnRpbmcgYXQgdGhlCisgICAgICogY3VycmVudCBmaWxlIHBvaW50ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHdyaXRlIHRvIHRoaXMgZmlsZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoaXMgZmlsZS4KKyAgICAgKiBAc2VlICNyZWFkQ2hhcigpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgd3JpdGVDaGFycyhTdHJpbmcgc3RyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3cml0ZShzdHIuZ2V0Qnl0ZXMoIlVURi0xNkJFIikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGJpZy1lbmRpYW4gNjQtYml0IGRvdWJsZSB0byB0aGlzIGZpbGUsIHN0YXJ0aW5nIGF0IHRoZSBjdXJyZW50IGZpbGUKKyAgICAgKiBwb2ludGVyLiBUaGUgYnl0ZXMgYXJlIHRob3NlIHJldHVybmVkIGJ5CisgICAgICoge0BsaW5rIERvdWJsZSNkb3VibGVUb0xvbmdCaXRzKGRvdWJsZSl9LCBtZWFuaW5nIGEgY2Fub25pY2FsIE5hTiBpcyB1c2VkLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdGhlIGRvdWJsZSB0byB3cml0ZSB0byB0aGlzIGZpbGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0byB0aGlzIGZpbGUuCisgICAgICogQHNlZSAjcmVhZERvdWJsZSgpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgd3JpdGVEb3VibGUoZG91YmxlIHZhbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGVMb25nKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKHZhbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGJpZy1lbmRpYW4gMzItYml0IGZsb2F0IHRvIHRoaXMgZmlsZSwgc3RhcnRpbmcgYXQgdGhlIGN1cnJlbnQgZmlsZSBwb2ludGVyLgorICAgICAqIFRoZSBieXRlcyBhcmUgdGhvc2UgcmV0dXJuZWQgYnkge0BsaW5rIEZsb2F0I2Zsb2F0VG9JbnRCaXRzKGZsb2F0KX0sIG1lYW5pbmcgYSBjYW5vbmljYWwgTmFOCisgICAgICogaXMgdXNlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbG9hdCB0byB3cml0ZSB0byB0aGlzIGZpbGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0byB0aGlzIGZpbGUuCisgICAgICogQHNlZSAjcmVhZEZsb2F0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB3cml0ZUZsb2F0KGZsb2F0IHZhbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGVJbnQoRmxvYXQuZmxvYXRUb0ludEJpdHModmFsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgYmlnLWVuZGlhbiAzMi1iaXQgaW50ZWdlciB0byB0aGlzIGZpbGUsIHN0YXJ0aW5nIGF0IHRoZSBjdXJyZW50IGZpbGUKKyAgICAgKiBwb2ludGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdGhlIGludCB0byB3cml0ZSB0byB0aGlzIGZpbGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0byB0aGlzIGZpbGUuCisgICAgICogQHNlZSAjcmVhZEludCgpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgd3JpdGVJbnQoaW50IHZhbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgTWVtb3J5LnBva2VJbnQoc2NyYXRjaCwgMCwgdmFsLCBCeXRlT3JkZXIuQklHX0VORElBTik7CisgICAgICAgIHdyaXRlKHNjcmF0Y2gsIDAsIFNpemVPZi5JTlQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGJpZy1lbmRpYW4gNjQtYml0IGxvbmcgdG8gdGhpcyBmaWxlLCBzdGFydGluZyBhdCB0aGUgY3VycmVudCBmaWxlCisgICAgICogcG9pbnRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb25nIHRvIHdyaXRlIHRvIHRoaXMgZmlsZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nIHRvIHRoaXMgZmlsZS4KKyAgICAgKiBAc2VlICNyZWFkTG9uZygpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgd3JpdGVMb25nKGxvbmcgdmFsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBNZW1vcnkucG9rZUxvbmcoc2NyYXRjaCwgMCwgdmFsLCBCeXRlT3JkZXIuQklHX0VORElBTik7CisgICAgICAgIHdyaXRlKHNjcmF0Y2gsIDAsIFNpemVPZi5MT05HKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBiaWctZW5kaWFuIDE2LWJpdCBzaG9ydCB0byB0aGlzIGZpbGUsIHN0YXJ0aW5nIGF0IHRoZSBjdXJyZW50IGZpbGUKKyAgICAgKiBwb2ludGVyLiBPbmx5IHRoZSB0d28gbGVhc3Qgc2lnbmlmaWNhbnQgYnl0ZXMgb2YgdGhlIGludGVnZXIge0Bjb2RlIHZhbH0KKyAgICAgKiBhcmUgd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaG9ydCB0byB3cml0ZSB0byB0aGlzIGZpbGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyB0byB0aGlzIGZpbGUuCisgICAgICogQHNlZSAjcmVhZFNob3J0KCkKKyAgICAgKiBAc2VlIERhdGFJbnB1dCNyZWFkVW5zaWduZWRTaG9ydCgpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgd3JpdGVTaG9ydChpbnQgdmFsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBNZW1vcnkucG9rZVNob3J0KHNjcmF0Y2gsIDAsIChzaG9ydCkgdmFsLCBCeXRlT3JkZXIuQklHX0VORElBTik7CisgICAgICAgIHdyaXRlKHNjcmF0Y2gsIDAsIFNpemVPZi5TSE9SVCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgc3RyaW5nIGVuY29kZWQgd2l0aCB7QGxpbmsgRGF0YUlucHV0IG1vZGlmaWVkIFVURi04fSB0byB0aGlzCisgICAgICogZmlsZSwgc3RhcnRpbmcgYXQgdGhlIGN1cnJlbnQgZmlsZSBwb2ludGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB3cml0ZSBpbiB7QGxpbmsgRGF0YUlucHV0IG1vZGlmaWVkIFVURi04fQorICAgICAqICAgICAgICAgICAgZm9ybWF0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgdG8gdGhpcyBmaWxlLgorICAgICAqIEB0aHJvd3MgVVRGRGF0YUZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmNvZGVkIHN0cmluZyBpcyBsb25nZXIgdGhhbiA2NTUzNSBieXRlcy4KKyAgICAgKiBAc2VlICNyZWFkVVRGKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB3cml0ZVVURihTdHJpbmcgc3RyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3cml0ZShNb2RpZmllZFV0ZjguZW5jb2RlKHN0cikpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1JlYWRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vUmVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzEwYTU3YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1JlYWRlci5qYXZhCkBAIC0wLDAgKzEsMjY0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKK2ltcG9ydCBqYXZhLm5pby5DaGFyQnVmZmVyOworaW1wb3J0IGphdmEubmlvLlJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uOworCisvKioKKyAqIFRoZSBiYXNlIGNsYXNzIGZvciBhbGwgcmVhZGVycy4gQSByZWFkZXIgaXMgYSBtZWFucyBvZiByZWFkaW5nIGRhdGEgZnJvbSBhCisgKiBzb3VyY2UgaW4gYSBjaGFyYWN0ZXItd2lzZSBtYW5uZXIuIFNvbWUgcmVhZGVycyBhbHNvIHN1cHBvcnQgbWFya2luZyBhCisgKiBwb3NpdGlvbiBpbiB0aGUgaW5wdXQgYW5kIHJldHVybmluZyB0byB0aGlzIHBvc2l0aW9uIGxhdGVyLgorICogPHA+CisgKiBUaGlzIGFic3RyYWN0IGNsYXNzIGRvZXMgbm90IHByb3ZpZGUgYSBmdWxseSB3b3JraW5nIGltcGxlbWVudGF0aW9uLCBzbyBpdAorICogbmVlZHMgdG8gYmUgc3ViY2xhc3NlZCwgYW5kIGF0IGxlYXN0IHRoZSB7QGxpbmsgI3JlYWQoY2hhcltdLCBpbnQsIGludCl9IGFuZAorICoge0BsaW5rICNjbG9zZSgpfSBtZXRob2RzIG5lZWRzIHRvIGJlIG92ZXJyaWRkZW4uIE92ZXJyaWRpbmcgc29tZSBvZiB0aGUKKyAqIG5vbi1hYnN0cmFjdCBtZXRob2RzIGlzIGFsc28gb2Z0ZW4gYWR2aXNlZCwgc2luY2UgaXQgbWlnaHQgcmVzdWx0IGluIGhpZ2hlcgorICogZWZmaWNpZW5jeS4KKyAqIDxwPgorICogTWFueSBzcGVjaWFsaXplZCByZWFkZXJzIGZvciBwdXJwb3NlcyBsaWtlIHJlYWRpbmcgZnJvbSBhIGZpbGUgYWxyZWFkeSBleGlzdAorICogaW4gdGhpcyBwYWNrYWdlLgorICoKKyAqIEBzZWUgV3JpdGVyCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBSZWFkZXIgaW1wbGVtZW50cyBSZWFkYWJsZSwgQ2xvc2VhYmxlIHsKKyAgICAvKioKKyAgICAgKiBUaGUgb2JqZWN0IHVzZWQgdG8gc3luY2hyb25pemUgYWNjZXNzIHRvIHRoZSByZWFkZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIE9iamVjdCBsb2NrOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUmVhZGVyfSB3aXRoIHtAY29kZSB0aGlzfSBhcyB0aGUgb2JqZWN0IHVzZWQgdG8KKyAgICAgKiBzeW5jaHJvbml6ZSBjcml0aWNhbCBzZWN0aW9ucy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUmVhZGVyKCkgeworICAgICAgICBsb2NrID0gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBSZWFkZXJ9IHdpdGgge0Bjb2RlIGxvY2t9IHVzZWQgdG8gc3luY2hyb25pemUKKyAgICAgKiBjcml0aWNhbCBzZWN0aW9ucy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NrCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIE9iamVjdH0gdXNlZCB0byBzeW5jaHJvbml6ZSBjcml0aWNhbCBzZWN0aW9ucy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGxvY2t9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUmVhZGVyKE9iamVjdCBsb2NrKSB7CisgICAgICAgIGlmIChsb2NrID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMubG9jayA9IGxvY2s7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgcmVhZGVyLiBJbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBtZXRob2Qgc2hvdWxkIGZyZWUgYW55CisgICAgICogcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVhZGVyLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjbG9zaW5nIHRoaXMgcmVhZGVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyBhIG1hcmsgcG9zaXRpb24gaW4gdGhpcyByZWFkZXIuIFRoZSBwYXJhbWV0ZXIge0Bjb2RlIHJlYWRMaW1pdH0KKyAgICAgKiBpbmRpY2F0ZXMgaG93IG1hbnkgY2hhcmFjdGVycyBjYW4gYmUgcmVhZCBiZWZvcmUgdGhlIG1hcmsgaXMgaW52YWxpZGF0ZWQuCisgICAgICogQ2FsbGluZyB7QGNvZGUgcmVzZXQoKX0gd2lsbCByZXBvc2l0aW9uIHRoZSByZWFkZXIgYmFjayB0byB0aGUgbWFya2VkCisgICAgICogcG9zaXRpb24gaWYge0Bjb2RlIHJlYWRMaW1pdH0gaGFzIG5vdCBiZWVuIHN1cnBhc3NlZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gc2ltcGx5IHRocm93cyBhbiB7QGNvZGUgSU9FeGNlcHRpb259OworICAgICAqIHN1YmNsYXNzZXMgbXVzdCBwcm92aWRlIHRoZWlyIG93biBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFkTGltaXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0aGF0IGNhbiBiZSByZWFkIGJlZm9yZSB0aGUgbWFyayBpcworICAgICAqICAgICAgICAgICAgaW52YWxpZGF0ZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcmVhZExpbWl0IDwgMH0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBzZXR0aW5nIGEgbWFyayBpbiB0aGlzIHJlYWRlci4KKyAgICAgKiBAc2VlICNtYXJrU3VwcG9ydGVkKCkKKyAgICAgKiBAc2VlICNyZXNldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgbWFyayhpbnQgcmVhZExpbWl0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIHJlYWRlciBzdXBwb3J0cyB0aGUge0Bjb2RlIG1hcmsoKX0gYW5kCisgICAgICoge0Bjb2RlIHJlc2V0KCl9IG1ldGhvZHMuIFRoaXMgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5zCisgICAgICoge0Bjb2RlIGZhbHNlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYWx3YXlzIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbWFya1N1cHBvcnRlZCgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgc2luZ2xlIGNoYXJhY3RlciBmcm9tIHRoaXMgcmVhZGVyIGFuZCByZXR1cm5zIGl0IGFzIGFuIGludGVnZXIKKyAgICAgKiB3aXRoIHRoZSB0d28gaGlnaGVyLW9yZGVyIGJ5dGVzIHNldCB0byAwLiBSZXR1cm5zIC0xIGlmIHRoZSBlbmQgb2YgdGhlCisgICAgICogcmVhZGVyIGhhcyBiZWVuIHJlYWNoZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFyYWN0ZXIgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZSByZWFkZXIgaGFzIGJlZW4KKyAgICAgKiAgICAgICAgIHJlYWNoZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgcmVhZGVyIGlzIGNsb3NlZCBvciBzb21lIG90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBjaGFyW10gY2hhckFycmF5ID0gbmV3IGNoYXJbMV07CisgICAgICAgICAgICBpZiAocmVhZChjaGFyQXJyYXksIDAsIDEpICE9IC0xKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNoYXJBcnJheVswXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGNoYXJhY3RlcnMgZnJvbSB0aGlzIHJlYWRlciBhbmQgc3RvcmVzIHRoZW0gaW4gdGhlIGNoYXJhY3RlciBhcnJheQorICAgICAqIHtAY29kZSBidWZ9IHN0YXJ0aW5nIGF0IG9mZnNldCAwLiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycworICAgICAqIGFjdHVhbGx5IHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgcmVhZGVyIGhhcyBiZWVuIHJlYWNoZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmCisgICAgICogICAgICAgICAgICBjaGFyYWN0ZXIgYXJyYXkgdG8gc3RvcmUgdGhlIGNoYXJhY3RlcnMgcmVhZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyByZWFkIG9yIC0xIGlmIHRoZSBlbmQgb2YgdGhlIHJlYWRlciBoYXMKKyAgICAgKiAgICAgICAgIGJlZW4gcmVhY2hlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyByZWFkZXIgaXMgY2xvc2VkIG9yIHNvbWUgb3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHJlYWQoY2hhcltdIGJ1ZikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHJlYWQoYnVmLCAwLCBidWYubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhdCBtb3N0IHtAY29kZSBjb3VudH0gY2hhcmFjdGVycyBmcm9tIHRoaXMgcmVhZGVyIGFuZCBzdG9yZXMgdGhlbQorICAgICAqIGF0IHtAY29kZSBvZmZzZXR9IGluIHRoZSBjaGFyYWN0ZXIgYXJyYXkge0Bjb2RlIGJ1Zn0uIFJldHVybnMgdGhlIG51bWJlcgorICAgICAqIG9mIGNoYXJhY3RlcnMgYWN0dWFsbHkgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZSByZWFkZXIgaGFzIGJlZW4KKyAgICAgKiByZWFjaGVkLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZgorICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciBhcnJheSB0byBzdG9yZSB0aGUgY2hhcmFjdGVycyByZWFkLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIHBvc2l0aW9uIGluIHtAY29kZSBidWZmZXJ9IHRvIHN0b3JlIHRoZSBjaGFyYWN0ZXJzCisgICAgICogICAgICAgICAgICByZWFkIGZyb20gdGhpcyByZWFkZXIuCisgICAgICogQHBhcmFtIGNvdW50CisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgcmVhZGVyIGhhcworICAgICAqICAgICAgICAgYmVlbiByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQgb3Igc29tZSBvdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgcmVhZChjaGFyW10gYnVmLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgcmVhZGVyIGlzIHJlYWR5IHRvIGJlIHJlYWQgd2l0aG91dCBibG9ja2luZy4KKyAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGlzIHJlYWRlciB3aWxsIG5vdCBibG9jayB3aGVuIHtAY29kZSByZWFkfSBpcworICAgICAqIGNhbGxlZCwge0Bjb2RlIGZhbHNlfSBpZiB1bmtub3duIG9yIGJsb2NraW5nIHdpbGwgb2NjdXIuIFRoaXMgZGVmYXVsdAorICAgICAqIGltcGxlbWVudGF0aW9uIGFsd2F5cyByZXR1cm5zIHtAY29kZSBmYWxzZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFsd2F5cyB7QGNvZGUgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQgb3Igc29tZSBvdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgI3JlYWQoKQorICAgICAqIEBzZWUgI3JlYWQoY2hhcltdKQorICAgICAqIEBzZWUgI3JlYWQoY2hhcltdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiByZWFkeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhpcyByZWFkZXIncyBwb3NpdGlvbiB0byB0aGUgbGFzdCB7QGNvZGUgbWFyaygpfSBsb2NhdGlvbi4KKyAgICAgKiBJbnZvY2F0aW9ucyBvZiB7QGNvZGUgcmVhZCgpfSBhbmQge0Bjb2RlIHNraXAoKX0gd2lsbCBvY2N1ciBmcm9tIHRoaXMgbmV3CisgICAgICogbG9jYXRpb24uIElmIHRoaXMgcmVhZGVyIGhhcyBub3QgYmVlbiBtYXJrZWQsIHRoZSBiZWhhdmlvciBvZgorICAgICAqIHtAY29kZSByZXNldCgpfSBpcyBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYy4gVGhpcyBkZWZhdWx0CisgICAgICogaW1wbGVtZW50YXRpb24gdGhyb3dzIGFuIHtAY29kZSBJT0V4Y2VwdGlvbn0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYWx3YXlzIHRocm93biBpbiB0aGlzIGRlZmF1bHQgaW1wbGVtZW50YXRpb24uCisgICAgICogQHNlZSAjbWFyayhpbnQpCisgICAgICogQHNlZSAjbWFya1N1cHBvcnRlZCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTa2lwcyB7QGNvZGUgY2hhckNvdW50fSBjaGFyYWN0ZXJzIGluIHRoaXMgcmVhZGVyLiBTdWJzZXF1ZW50IGNhbGxzIG9mCisgICAgICoge0Bjb2RlIHJlYWR9IG1ldGhvZHMgd2lsbCBub3QgcmV0dXJuIHRoZXNlIGNoYXJhY3RlcnMgdW5sZXNzIHtAY29kZQorICAgICAqIHJlc2V0fSBpcyB1c2VkLiBUaGlzIG1ldGhvZCBtYXkgcGVyZm9ybSBtdWx0aXBsZSByZWFkcyB0byByZWFkIHtAY29kZQorICAgICAqIGNoYXJDb3VudH0gY2hhcmFjdGVycy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGFjdHVhbGx5IHNraXBwZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY2hhckNvdW50IDwgMH0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgcmVhZGVyIGlzIGNsb3NlZCBvciBzb21lIG90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSAjbWFyayhpbnQpCisgICAgICogQHNlZSAjbWFya1N1cHBvcnRlZCgpCisgICAgICogQHNlZSAjcmVzZXQoKQorICAgICAqLworICAgIHB1YmxpYyBsb25nIHNraXAobG9uZyBjaGFyQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjaGFyQ291bnQgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJjaGFyQ291bnQgPCAwOiAiICsgY2hhckNvdW50KTsKKyAgICAgICAgfQorICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGxvbmcgc2tpcHBlZCA9IDA7CisgICAgICAgICAgICBpbnQgdG9SZWFkID0gY2hhckNvdW50IDwgNTEyID8gKGludCkgY2hhckNvdW50IDogNTEyOworICAgICAgICAgICAgY2hhcltdIGNoYXJzU2tpcHBlZCA9IG5ldyBjaGFyW3RvUmVhZF07CisgICAgICAgICAgICB3aGlsZSAoc2tpcHBlZCA8IGNoYXJDb3VudCkgeworICAgICAgICAgICAgICAgIGludCByZWFkID0gcmVhZChjaGFyc1NraXBwZWQsIDAsIHRvUmVhZCk7CisgICAgICAgICAgICAgICAgaWYgKHJlYWQgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNraXBwZWQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHNraXBwZWQgKz0gcmVhZDsKKyAgICAgICAgICAgICAgICBpZiAocmVhZCA8IHRvUmVhZCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2tpcHBlZDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGNoYXJDb3VudCAtIHNraXBwZWQgPCB0b1JlYWQpIHsKKyAgICAgICAgICAgICAgICAgICAgdG9SZWFkID0gKGludCkgKGNoYXJDb3VudCAtIHNraXBwZWQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBza2lwcGVkOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgY2hhcmFjdGVycyBhbmQgcHV0cyB0aGVtIGludG8gdGhlIHtAY29kZSB0YXJnZXR9IGNoYXJhY3RlciBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGFyZ2V0CisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gY2hhcmFjdGVyIGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBwdXQgaW50byB7QGNvZGUgdGFyZ2V0fSBvciAtMSBpZiB0aGUgZW5kCisgICAgICogICAgICAgICBvZiB0aGlzIHJlYWRlciBoYXMgYmVlbiByZWFjaGVkIGJlZm9yZSBhIGNoYXJhY3RlciBoYXMgYmVlbiByZWFkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgSS9PIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhpcyByZWFkZXIuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSB0YXJnZXR9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHRhcmdldH0gaXMgcmVhZC1vbmx5LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgcmVhZChDaGFyQnVmZmVyIHRhcmdldCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGxlbmd0aCA9IHRhcmdldC5sZW5ndGgoKTsKKyAgICAgICAgY2hhcltdIGJ1ZiA9IG5ldyBjaGFyW2xlbmd0aF07CisgICAgICAgIGxlbmd0aCA9IE1hdGgubWluKGxlbmd0aCwgcmVhZChidWYpKTsKKyAgICAgICAgaWYgKGxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgIHRhcmdldC5wdXQoYnVmLCAwLCBsZW5ndGgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBsZW5ndGg7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vU2VxdWVuY2VJbnB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vU2VxdWVuY2VJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlhZTE5MDEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9TZXF1ZW5jZUlucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxOTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKKy8qKgorICogQ29uY2F0ZW5hdGVzIHR3byBvciBtb3JlIGV4aXN0aW5nIHtAbGluayBJbnB1dFN0cmVhbX1zLiBSZWFkcyBhcmUgdGFrZW4gZnJvbQorICogdGhlIGZpcnN0IHN0cmVhbSB1bnRpbCBpdCBlbmRzLCB0aGVuIHRoZSBuZXh0IHN0cmVhbSBpcyB1c2VkLCB1bnRpbCB0aGUgbGFzdAorICogc3RyZWFtIHJldHVybnMgZW5kIG9mIGZpbGUuCisgKi8KK3B1YmxpYyBjbGFzcyBTZXF1ZW5jZUlucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworICAgIC8qKgorICAgICAqIEFuIGVudW1lcmF0aW9uIHdoaWNoIHdpbGwgcmV0dXJuIHR5cGVzIG9mIElucHV0U3RyZWFtLgorICAgICAqLworICAgIHByaXZhdGUgRW51bWVyYXRpb248PyBleHRlbmRzIElucHV0U3RyZWFtPiBlOworCisgICAgLyoqCisgICAgICogVGhlIGN1cnJlbnQgaW5wdXQgc3RyZWFtLgorICAgICAqLworICAgIHByaXZhdGUgSW5wdXRTdHJlYW0gaW47CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBTZXF1ZW5jZUlucHV0U3RyZWFtfSB1c2luZyB0aGUgdHdvIHN0cmVhbXMKKyAgICAgKiB7QGNvZGUgczF9IGFuZCB7QGNvZGUgczJ9IGFzIHRoZSBzZXF1ZW5jZSBvZiBzdHJlYW1zIHRvIHJlYWQgZnJvbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzMQorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IHN0cmVhbSB0byBnZXQgYnl0ZXMgZnJvbS4KKyAgICAgKiBAcGFyYW0gczIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgc3RyZWFtIHRvIGdldCBieXRlcyBmcm9tLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgczF9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2VxdWVuY2VJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBzMSwgSW5wdXRTdHJlYW0gczIpIHsKKyAgICAgICAgaWYgKHMxID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIFZlY3RvcjxJbnB1dFN0cmVhbT4gaW5WZWN0b3IgPSBuZXcgVmVjdG9yPElucHV0U3RyZWFtPigxKTsKKyAgICAgICAgaW5WZWN0b3IuYWRkRWxlbWVudChzMik7CisgICAgICAgIGUgPSBpblZlY3Rvci5lbGVtZW50cygpOworICAgICAgICBpbiA9IHMxOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgU2VxdWVuY2VJbnB1dFN0cmVhbSB1c2luZyB0aGUgZWxlbWVudHMgcmV0dXJuZWQgZnJvbQorICAgICAqIEVudW1lcmF0aW9uIHtAY29kZSBlfSBhcyB0aGUgc3RyZWFtIHNlcXVlbmNlLiBUaGUgaW5zdGFuY2VzIHJldHVybmVkIGJ5CisgICAgICoge0Bjb2RlIGUubmV4dEVsZW1lbnQoKX0gbXVzdCBiZSBvZiB0eXBlIHtAbGluayBJbnB1dFN0cmVhbX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZQorICAgICAqICAgICAgICAgICAgdGhlIGVudW1lcmF0aW9uIG9mIHtAY29kZSBJbnB1dFN0cmVhbXN9IHRvIGdldCBieXRlcyBmcm9tLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgb2YgdGhlIGVsZW1lbnRzIGluIHtAY29kZSBlfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFNlcXVlbmNlSW5wdXRTdHJlYW0oRW51bWVyYXRpb248PyBleHRlbmRzIElucHV0U3RyZWFtPiBlKSB7CisgICAgICAgIHRoaXMuZSA9IGU7CisgICAgICAgIGlmIChlLmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICBpbiA9IGUubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGlmIChpbiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChlICE9IG51bGwgJiYgaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGluLmF2YWlsYWJsZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyBhbGwgc3RyZWFtcyBpbiB0aGlzIHNlcXVlbmNlIG9mIGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY2xvc2luZyBhbnkgb2YgdGhlIGlucHV0IHN0cmVhbXMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3aGlsZSAoaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgbmV4dFN0cmVhbSgpOworICAgICAgICB9CisgICAgICAgIGUgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdXAgdGhlIG5leHQgSW5wdXRTdHJlYW0gb3IgbGVhdmVzIGl0IGFsb25lIGlmIHRoZXJlIGFyZSBub25lIGxlZnQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIG5leHRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZS5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgaW4gPSBlLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICBpZiAoaW4gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW4gPSBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBzaW5nbGUgYnl0ZSBmcm9tIHRoaXMgc2VxdWVuY2Ugb2YgaW5wdXQgc3RyZWFtcyBhbmQgcmV0dXJucyBpdCBhcworICAgICAqIGFuIGludGVnZXIgaW4gdGhlIHJhbmdlIGZyb20gMCB0byAyNTUuIEl0IHRyaWVzIHRvIHJlYWQgZnJvbSB0aGUgY3VycmVudAorICAgICAqIHN0cmVhbSBmaXJzdDsgaWYgdGhlIGVuZCBvZiB0aGlzIHN0cmVhbSBoYXMgYmVlbiByZWFjaGVkLCBpdCByZWFkcyBmcm9tCisgICAgICogdGhlIG5leHQgb25lLiBCbG9ja3MgdW50aWwgb25lIGJ5dGUgaGFzIGJlZW4gcmVhZCwgdGhlIGVuZCBvZiB0aGUgbGFzdAorICAgICAqIGlucHV0IHN0cmVhbSBpbiB0aGUgc2VxdWVuY2UgaGFzIGJlZW4gcmVhY2hlZCwgb3IgYW4gZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgcmVhZCBvciAtMSBpZiBlaXRoZXIgdGhlIGVuZCBvZiB0aGUgbGFzdCBzdHJlYW0gaW4gdGhlCisgICAgICogICAgICAgICBzZXF1ZW5jZSBoYXMgYmVlbiByZWFjaGVkIG9yIHRoaXMgaW5wdXQgc3RyZWFtIHNlcXVlbmNlIGlzCisgICAgICogICAgICAgICBjbG9zZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIHRoZSBjdXJyZW50IHNvdXJjZSBpbnB1dAorICAgICAqICAgICAgICAgICAgIHN0cmVhbS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3aGlsZSAoaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgaW50IHJlc3VsdCA9IGluLnJlYWQoKTsKKyAgICAgICAgICAgIGlmIChyZXN1bHQgPj0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBuZXh0U3RyZWFtKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGF0IG1vc3Qge0Bjb2RlIGNvdW50fSBieXRlcyBmcm9tIHRoaXMgc2VxdWVuY2Ugb2YgaW5wdXQgc3RyZWFtcyBhbmQKKyAgICAgKiBzdG9yZXMgdGhlbSBpbiB0aGUgYnl0ZSBhcnJheSB7QGNvZGUgYnVmZmVyfSBzdGFydGluZyBhdCB7QGNvZGUgb2Zmc2V0fS4KKyAgICAgKiBCbG9ja3Mgb25seSB1bnRpbCBhdCBsZWFzdCAxIGJ5dGUgaGFzIGJlZW4gcmVhZCwgdGhlIGVuZCBvZiB0aGUgc3RyZWFtCisgICAgICogaGFzIGJlZW4gcmVhY2hlZCwgb3IgYW4gZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIFNlcXVlbmNlSW5wdXRTdHJlYW0gc2hvd3MgdGhlIHNhbWUgYmVoYXZpb3IgYXMgb3RoZXIgSW5wdXRTdHJlYW1zLgorICAgICAqIFRvIGRvIHRoaXMgaXQgd2lsbCByZWFkIG9ubHkgYXMgbWFueSBieXRlcyBhcyBhIGNhbGwgdG8gcmVhZCBvbiB0aGUKKyAgICAgKiBjdXJyZW50IHN1YnN0cmVhbSByZXR1cm5zLiBJZiB0aGF0IGNhbGwgZG9lcyBub3QgcmV0dXJuIGFzIG1hbnkgYnl0ZXMgYXMKKyAgICAgKiByZXF1ZXN0ZWQgYnkge0Bjb2RlIGNvdW50fSwgaXQgd2lsbCBub3QgcmV0cnkgdG8gcmVhZCBtb3JlIG9uIGl0cyBvd24KKyAgICAgKiBiZWNhdXNlIHN1YnNlcXVlbnQgcmVhZHMgbWlnaHQgYmxvY2suIFRoaXMgd291bGQgdmlvbGF0ZSB0aGUgcnVsZSB0aGF0CisgICAgICogaXQgd2lsbCBvbmx5IGJsb2NrIHVudGlsIGF0IGxlYXN0IG9uZSBieXRlIGhhcyBiZWVuIHJlYWQuCisgICAgICogPHA+CisgICAgICogSWYgYSBzdWJzdHJlYW0gaGFzIGFscmVhZHkgcmVhY2hlZCB0aGUgZW5kIHdoZW4gdGhpcyBjYWxsIGlzIG1hZGUsIGl0CisgICAgICogd2lsbCBjbG9zZSB0aGF0IHN1YnN0cmVhbSBhbmQgc3RhcnQgd2l0aCB0aGUgbmV4dCBvbmUuIElmIHRoZXJlIGFyZSBubworICAgICAqIG1vcmUgc3Vic3RyZWFtcyBpdCB3aWxsIHJldHVybiAtMS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBpbiB3aGljaCB0byBzdG9yZSB0aGUgYnl0ZXMgcmVhZC4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBwb3NpdGlvbiBpbiB7QGNvZGUgYnVmZmVyfSB0byBzdG9yZSB0aGUgYnl0ZXMgcmVhZAorICAgICAqICAgICAgICAgICAgZnJvbSB0aGlzIHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0byBzdG9yZSBpbiB7QGNvZGUgYnVmZmVyfS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgcmVhZDsgLTEgaWYgdGhpcyBzZXF1ZW5jZSBvZiBzdHJlYW1zCisgICAgICogICAgICAgICBpcyBjbG9zZWQgb3IgaWYgdGhlIGVuZCBvZiB0aGUgbGFzdCBzdHJlYW0gaW4gdGhlIHNlcXVlbmNlIGhhcworICAgICAqICAgICAgICAgYmVlbiByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwfSBvciB7QGNvZGUgY291bnQgPCAwfSwgb3IgaWYge0Bjb2RlCisgICAgICogICAgICAgICAgICAgb2Zmc2V0ICsgY291bnR9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgc2l6ZSBvZiB7QGNvZGUgYnVmZmVyfS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGJ1ZmZlcn0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpbiA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgIHdoaWxlIChpbiAhPSBudWxsKSB7CisgICAgICAgICAgICBpbnQgcmVzdWx0ID0gaW4ucmVhZChidWZmZXIsIG9mZnNldCwgY291bnQpOworICAgICAgICAgICAgaWYgKHJlc3VsdCA+PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG5leHRTdHJlYW0oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vU2VyaWFsaXphYmxlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9TZXJpYWxpemFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45Y2Q3ODE2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vU2VyaWFsaXphYmxlLmphdmEKQEAgLTAsMCArMSwzNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCisvKioKKyAqIEFuIGVtcHR5IG1hcmtlciBpbnRlcmZhY2UgZm9yIGNsYXNzZXMgdGhhdCB3YW50IHRvIHN1cHBvcnQgc2VyaWFsaXphdGlvbiBhbmQKKyAqIGRlc2VyaWFsaXphdGlvbiBiYXNlZCBvbiB0aGUge0Bjb2RlIE9iamVjdE91dHB1dFN0cmVhbX0gYW5kIHtAY29kZQorICogT2JqZWN0SW5wdXRTdHJlYW19IGNsYXNzZXMuIEltcGxlbWVudGluZyB0aGlzIGludGVyZmFjZSBpcyBlbm91Z2ggdG8gbWFrZQorICogbW9zdCBjbGFzc2VzIHNlcmlhbGl6YWJsZS4gSWYgYSBjbGFzcyBuZWVkcyBtb3JlIGZpbmUtZ3JhaW5lZCBjb250cm9sIG92ZXIKKyAqIHRoZSBzZXJpYWxpemF0aW9uIHByb2Nlc3MgKGZvciBleGFtcGxlIHRvIGltcGxlbWVudCBjb21wYXRpYmlsaXR5IHdpdGggb2xkZXIKKyAqIHZlcnNpb25zIG9mIHRoZSBjbGFzcyksIGl0IGNhbiBhY2hpZXZlIHRoaXMgYnkgcHJvdmlkaW5nIHRoZSBmb2xsb3dpbmcgdHdvCisgKiBtZXRob2RzIChzaWduYXR1cmVzIG11c3QgbWF0Y2ggZXhhY3RseSk6CisgKiA8cD4KKyAqIHtAY29kZSBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MKKyAqIElPRXhjZXB0aW9ufQorICogPHA+CisgKiB7QGNvZGUgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSBpbikgdGhyb3dzCisgKiBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbn0KKyAqLworcHVibGljIGludGVyZmFjZSBTZXJpYWxpemFibGUgeworICAgIC8qIGVtcHR5ICovCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9TZXJpYWxpemFibGVQZXJtaXNzaW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9TZXJpYWxpemFibGVQZXJtaXNzaW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmJlMTNmZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1NlcmlhbGl6YWJsZVBlcm1pc3Npb24uamF2YQpAQCAtMCwwICsxLDM0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkJhc2ljUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTZXJpYWxpemFibGVQZXJtaXNzaW9uIGV4dGVuZHMgQmFzaWNQZXJtaXNzaW9uIHsKKyAgICBwdWJsaWMgU2VyaWFsaXphYmxlUGVybWlzc2lvbihTdHJpbmcgcGVybWlzc2lvbk5hbWUpIHsgc3VwZXIoIiIpOyB9CisKKyAgICBwdWJsaWMgU2VyaWFsaXphYmxlUGVybWlzc2lvbihTdHJpbmcgbmFtZSwgU3RyaW5nIGFjdGlvbnMpIHsgc3VwZXIoIiIsICIiKTsgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgZ2V0QWN0aW9ucygpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpbXBsaWVzKFBlcm1pc3Npb24gcGVybWlzc2lvbikgeyByZXR1cm4gdHJ1ZTsgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vU2VyaWFsaXphdGlvbkhhbmRsZU1hcC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vU2VyaWFsaXphdGlvbkhhbmRsZU1hcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg2MzBiODIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9TZXJpYWxpemF0aW9uSGFuZGxlTWFwLmphdmEKQEAgLTAsMCArMSwxNzMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKKy8qKgorICogQSBzcGVjaWFsaXphdGlvbiBvZiBJZGVudGl0eUhhc2hNYXA8T2JqZWN0LCBpbnQ+IGZvciB1c2Ugd2hlbiBzZXJpYWxpemluZyBvYmplY3RzLgorICogV2UgbmVlZCB0byBhc3NpZ24gZWFjaCBvYmplY3Qgd2Ugd3JpdGUgYW4gaW50ICdoYW5kbGUnIChkZW5zZWx5IHBhY2tlZCBidXQgbm90IHN0YXJ0aW5nCisgKiBhdCB6ZXJvKSwgYW5kIHVzZSB0aGUgc2FtZSBoYW5kbGUgYW55IHRpbWUgd2Ugd3JpdGUgdGhlIHNhbWUgb2JqZWN0IGFnYWluLgorICovCitmaW5hbCBjbGFzcyBTZXJpYWxpemF0aW9uSGFuZGxlTWFwIHsKKyAgICAvKiBEZWZhdWx0IGxvYWQgZmFjdG9yIG9mIDAuNzU7ICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExPQURfRkFDVE9SID0gNzUwMDsKKworICAgIHByaXZhdGUgT2JqZWN0W10ga2V5czsKKyAgICBwcml2YXRlIGludFtdIHZhbHVlczsKKworICAgIC8qIEFjdHVhbCBudW1iZXIgb2Yga2V5LXZhbHVlIHBhaXJzLiAqLworICAgIHByaXZhdGUgaW50IHNpemU7CisKKyAgICAvKiBNYXhpbXVtIG51bWJlciBvZiBlbGVtZW50cyB0aGF0IGNhbiBiZSBwdXQgaW4gdGhpcyBtYXAgYmVmb3JlIGhhdmluZyB0byByZWhhc2guICovCisgICAgcHJpdmF0ZSBpbnQgdGhyZXNob2xkOworCisgICAgcHVibGljIFNlcmlhbGl6YXRpb25IYW5kbGVNYXAoKSB7CisgICAgICAgIHRoaXMuc2l6ZSA9IDA7CisgICAgICAgIHRoaXMudGhyZXNob2xkID0gMjE7IC8vIENvcGllZCBmcm9tIElkZW50aXR5SGFzaE1hcC4KKyAgICAgICAgaW50IGFycmF5U2l6ZSA9IChpbnQpICgoKGxvbmcpIHRocmVzaG9sZCAqIDEwMDAwKSAvIExPQURfRkFDVE9SKTsKKyAgICAgICAgcmVzaXplQXJyYXlzKGFycmF5U2l6ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlc2l6ZUFycmF5cyhpbnQgbmV3U2l6ZSkgeworICAgICAgICBPYmplY3RbXSBvbGRLZXlzID0ga2V5czsKKyAgICAgICAgaW50W10gb2xkVmFsdWVzID0gdmFsdWVzOworCisgICAgICAgIHRoaXMua2V5cyA9IG5ldyBPYmplY3RbbmV3U2l6ZV07CisgICAgICAgIHRoaXMudmFsdWVzID0gbmV3IGludFtuZXdTaXplXTsKKworICAgICAgICBpZiAob2xkS2V5cyAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9sZEtleXMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICBPYmplY3Qga2V5ID0gb2xkS2V5c1tpXTsKKyAgICAgICAgICAgICAgICBpbnQgdmFsdWUgPSBvbGRWYWx1ZXNbaV07CisgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gZmluZEluZGV4KGtleSwga2V5cyk7CisgICAgICAgICAgICAgICAga2V5c1tpbmRleF0gPSBrZXk7CisgICAgICAgICAgICAgICAgdmFsdWVzW2luZGV4XSA9IHZhbHVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGludCBnZXQoT2JqZWN0IGtleSkgeworICAgICAgICBpbnQgaW5kZXggPSBmaW5kSW5kZXgoa2V5LCBrZXlzKTsKKyAgICAgICAgaWYgKGtleXNbaW5kZXhdID09IGtleSkgeworICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1tpbmRleF07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGluZGV4IHdoZXJlIHRoZSBrZXkgaXMgZm91bmQgYXQsIG9yIHRoZSBpbmRleCBvZiB0aGUgbmV4dAorICAgICAqIGVtcHR5IHNwb3QgaWYgdGhlIGtleSBpcyBub3QgZm91bmQgaW4gdGhpcyB0YWJsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBmaW5kSW5kZXgoT2JqZWN0IGtleSwgT2JqZWN0W10gYXJyYXkpIHsKKyAgICAgICAgaW50IGxlbmd0aCA9IGFycmF5Lmxlbmd0aDsKKyAgICAgICAgaW50IGluZGV4ID0gZ2V0TW9kdWxvSGFzaChrZXksIGxlbmd0aCk7CisgICAgICAgIGludCBsYXN0ID0gKGluZGV4ICsgbGVuZ3RoIC0gMSkgJSBsZW5ndGg7CisgICAgICAgIHdoaWxlIChpbmRleCAhPSBsYXN0KSB7CisgICAgICAgICAgICBpZiAoYXJyYXlbaW5kZXhdID09IGtleSB8fCBhcnJheVtpbmRleF0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogRm91bmQgdGhlIGtleSwgb3IgdGhlIG5leHQgZW1wdHkgc3BvdCAod2hpY2ggbWVhbnMga2V5IGlzIG5vdAorICAgICAgICAgICAgICAgICAqIGluIHRoZSB0YWJsZSkKKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGluZGV4ID0gKGluZGV4ICsgMSkgJSBsZW5ndGg7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGluZGV4OworICAgIH0KKworICAgIHByaXZhdGUgaW50IGdldE1vZHVsb0hhc2goT2JqZWN0IGtleSwgaW50IGxlbmd0aCkgeworICAgICAgICByZXR1cm4gKFN5c3RlbS5pZGVudGl0eUhhc2hDb2RlKGtleSkgJiAweDdGRkZGRkZGKSAlIGxlbmd0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IHB1dChPYmplY3Qga2V5LCBpbnQgdmFsdWUpIHsKKyAgICAgICAgT2JqZWN0IF9rZXkgPSBrZXk7CisgICAgICAgIGludCBfdmFsdWUgPSB2YWx1ZTsKKworICAgICAgICBpbnQgaW5kZXggPSBmaW5kSW5kZXgoX2tleSwga2V5cyk7CisKKyAgICAgICAgLy8gaWYgdGhlIGtleSBkb2Vzbid0IGV4aXN0IGluIHRoZSB0YWJsZQorICAgICAgICBpZiAoa2V5c1tpbmRleF0gIT0gX2tleSkgeworICAgICAgICAgICAgaWYgKCsrc2l6ZSA+IHRocmVzaG9sZCkgeworICAgICAgICAgICAgICAgIHJlaGFzaCgpOworICAgICAgICAgICAgICAgIGluZGV4ID0gZmluZEluZGV4KF9rZXksIGtleXMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gaW5zZXJ0IHRoZSBrZXkgYW5kIGFzc2lnbiB0aGUgdmFsdWUgdG8gLTEgaW5pdGlhbGx5CisgICAgICAgICAgICBrZXlzW2luZGV4XSA9IF9rZXk7CisgICAgICAgICAgICB2YWx1ZXNbaW5kZXhdID0gLTE7CisgICAgICAgIH0KKworICAgICAgICAvLyBpbnNlcnQgdmFsdWUgdG8gd2hlcmUgaXQgbmVlZHMgdG8gZ28sIHJldHVybiB0aGUgb2xkIHZhbHVlCisgICAgICAgIGludCByZXN1bHQgPSB2YWx1ZXNbaW5kZXhdOworICAgICAgICB2YWx1ZXNbaW5kZXhdID0gX3ZhbHVlOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWhhc2goKSB7CisgICAgICAgIGludCBuZXdTaXplID0ga2V5cy5sZW5ndGggKiAyOworICAgICAgICByZXNpemVBcnJheXMobmV3U2l6ZSk7CisgICAgICAgIHRocmVzaG9sZCA9IChpbnQpICgobG9uZykgKGtleXMubGVuZ3RoKSAqIExPQURfRkFDVE9SIC8gMTAwMDApOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgcmVtb3ZlKE9iamVjdCBrZXkpIHsKKyAgICAgICAgYm9vbGVhbiBoYXNoZWRPazsKKyAgICAgICAgaW50IGluZGV4LCBuZXh0LCBoYXNoOworICAgICAgICBpbnQgcmVzdWx0OworICAgICAgICBPYmplY3Qgb2JqZWN0OworICAgICAgICBpbmRleCA9IG5leHQgPSBmaW5kSW5kZXgoa2V5LCBrZXlzKTsKKworICAgICAgICBpZiAoa2V5c1tpbmRleF0gIT0ga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKworICAgICAgICAvLyBzdG9yZSB0aGUgdmFsdWUgZm9yIHRoaXMga2V5CisgICAgICAgIHJlc3VsdCA9IHZhbHVlc1tpbmRleF07CisKKyAgICAgICAgLy8gc2hpZnQgdGhlIGZvbGxvd2luZyBlbGVtZW50cyB1cCBpZiBuZWVkZWQKKyAgICAgICAgLy8gdW50aWwgd2UgcmVhY2ggYW4gZW1wdHkgc3BvdAorICAgICAgICBpbnQgbGVuZ3RoID0ga2V5cy5sZW5ndGg7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBuZXh0ID0gKG5leHQgKyAyKSAlIGxlbmd0aDsKKyAgICAgICAgICAgIG9iamVjdCA9IGtleXNbbmV4dF07CisgICAgICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaGFzaCA9IGdldE1vZHVsb0hhc2gob2JqZWN0LCBsZW5ndGgpOworICAgICAgICAgICAgaGFzaGVkT2sgPSBoYXNoID4gaW5kZXg7CisgICAgICAgICAgICBpZiAobmV4dCA8IGluZGV4KSB7CisgICAgICAgICAgICAgICAgaGFzaGVkT2sgPSBoYXNoZWRPayB8fCAoaGFzaCA8PSBuZXh0KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaGFzaGVkT2sgPSBoYXNoZWRPayAmJiAoaGFzaCA8PSBuZXh0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghaGFzaGVkT2spIHsKKyAgICAgICAgICAgICAgICBrZXlzW2luZGV4XSA9IG9iamVjdDsKKyAgICAgICAgICAgICAgICB2YWx1ZXNbaW5kZXhdID0gdmFsdWVzW25leHRdOworICAgICAgICAgICAgICAgIGluZGV4ID0gbmV4dDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzaXplLS07CisKKyAgICAgICAgLy8gY2xlYXIgYm90aCB0aGUga2V5IGFuZCB0aGUgdmFsdWUKKyAgICAgICAga2V5c1tpbmRleF0gPSBudWxsOworICAgICAgICB2YWx1ZXNbaW5kZXhdID0gLTE7CisKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICByZXR1cm4gc2l6ZSA9PSAwOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1N0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vU3RyZWFtQ29ycnVwdGVkRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTc2OGE4OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1N0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworLyoqCisgKiBTaWduYWxzIHRoYXQgdGhlIHtAbGluayBPYmplY3RJbnB1dFN0cmVhbSNyZWFkT2JqZWN0KCl9IG1ldGhvZCBjb3VsZCBub3QKKyAqIHJlYWQgYW4gb2JqZWN0IGR1ZSB0byBtaXNzaW5nIGluZm9ybWF0aW9uIChmb3IgZXhhbXBsZSwgYSBjeWNsaWMgcmVmZXJlbmNlCisgKiB0aGF0IGRvZXNuJ3QgbWF0Y2ggYSBwcmV2aW91cyBpbnN0YW5jZSwgb3IgYSBtaXNzaW5nIGNsYXNzIGRlc2NyaXB0b3IgZm9yIHRoZQorICogb2JqZWN0IHRvIGJlIGxvYWRlZCkuCisgKgorICogQHNlZSBPYmplY3RJbnB1dFN0cmVhbQorICogQHNlZSBPcHRpb25hbERhdGFFeGNlcHRpb24KKyAqLworcHVibGljIGNsYXNzIFN0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbiBleHRlbmRzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA4OTgzNTU4MjAyMjE3NTkxNzQ2TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFN0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbn0gd2l0aCBpdHMgc3RhY2sgdHJhY2UKKyAgICAgKiBmaWxsZWQgaW4uCisgICAgICovCisgICAgcHVibGljIFN0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBTdHJlYW1Db3JydXB0ZWRFeGNlcHRpb259IHdpdGggaXRzIHN0YWNrIHRyYWNlCisgICAgICogYW5kIGRldGFpbCBtZXNzYWdlIGZpbGxlZCBpbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBTdHJlYW1Db3JydXB0ZWRFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vU3RyZWFtVG9rZW5pemVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9TdHJlYW1Ub2tlbml6ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNTIyYmU2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vU3RyZWFtVG9rZW5pemVyLmphdmEKQEAgLTAsMCArMSw2NzUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CisKKy8qKgorICogUGFyc2VzIGEgc3RyZWFtIGludG8gYSBzZXQgb2YgZGVmaW5lZCB0b2tlbnMsIG9uZSBhdCBhIHRpbWUuIFRoZSBkaWZmZXJlbnQKKyAqIHR5cGVzIG9mIHRva2VucyB0aGF0IGNhbiBiZSBmb3VuZCBhcmUgbnVtYmVycywgaWRlbnRpZmllcnMsIHF1b3RlZCBzdHJpbmdzLAorICogYW5kIGRpZmZlcmVudCBjb21tZW50IHN0eWxlcy4gVGhlIGNsYXNzIGNhbiBiZSB1c2VkIGZvciBsaW1pdGVkIHByb2Nlc3NpbmcKKyAqIG9mIHNvdXJjZSBjb2RlIG9mIHByb2dyYW1taW5nIGxhbmd1YWdlcyBsaWtlIEphdmEsIGFsdGhvdWdoIGl0IGlzIG5vd2hlcmUKKyAqIG5lYXIgYSBmdWxsIHBhcnNlci4KKyAqLworcHVibGljIGNsYXNzIFN0cmVhbVRva2VuaXplciB7CisgICAgLyoqCisgICAgICogQ29udGFpbnMgYSBudW1iZXIgaWYgdGhlIGN1cnJlbnQgdG9rZW4gaXMgYSBudW1iZXIgKHtAY29kZSB0dHlwZX0gPT0KKyAgICAgKiB7QGNvZGUgVFRfTlVNQkVSfSkuCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBudmFsOworCisgICAgLyoqCisgICAgICogQ29udGFpbnMgYSBzdHJpbmcgaWYgdGhlIGN1cnJlbnQgdG9rZW4gaXMgYSB3b3JkICh7QGNvZGUgdHR5cGV9ID09CisgICAgICoge0Bjb2RlIFRUX1dPUkR9KS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHN2YWw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29uc3RhbnQgcmVwcmVzZW50aW5nIHRoZSBlbmQgb2YgdGhlIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUVF9FT0YgPSAtMTsKKworICAgIC8qKgorICAgICAqIFRoZSBjb25zdGFudCByZXByZXNlbnRpbmcgdGhlIGVuZCBvZiB0aGUgbGluZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUVF9FT0wgPSAnXG4nOworCisgICAgLyoqCisgICAgICogVGhlIGNvbnN0YW50IHJlcHJlc2VudGluZyBhIG51bWJlciB0b2tlbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUVF9OVU1CRVIgPSAtMjsKKworICAgIC8qKgorICAgICAqIFRoZSBjb25zdGFudCByZXByZXNlbnRpbmcgYSB3b3JkIHRva2VuLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRUX1dPUkQgPSAtMzsKKworICAgIC8qKgorICAgICAqIEludGVybmFsIHJlcHJlc2VudGF0aW9uIG9mIHVua25vd24gc3RhdGUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRUX1VOS05PV04gPSAtNDsKKworICAgIC8qKgorICAgICAqIEFmdGVyIGNhbGxpbmcge0Bjb2RlIG5leHRUb2tlbigpfSwge0Bjb2RlIHR0eXBlfSBjb250YWlucyB0aGUgdHlwZSBvZgorICAgICAqIHRva2VuIHRoYXQgaGFzIGJlZW4gcmVhZC4gV2hlbiBhIHNpbmdsZSBjaGFyYWN0ZXIgaXMgcmVhZCwgaXRzIHZhbHVlCisgICAgICogY29udmVydGVkIHRvIGFuIGludGVnZXIgaXMgc3RvcmVkIGluIHtAY29kZSB0dHlwZX0uIEZvciBhIHF1b3RlZCBzdHJpbmcsCisgICAgICogdGhlIHZhbHVlIGlzIHRoZSBxdW90ZWQgY2hhcmFjdGVyLiBPdGhlcndpc2UsIGl0cyB2YWx1ZSBpcyBvbmUgb2YgdGhlCisgICAgICogZm9sbG93aW5nOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+IHtAY29kZSBUVF9XT1JEfSAtIHRoZSB0b2tlbiBpcyBhIHdvcmQuPC9saT4KKyAgICAgKiA8bGk+IHtAY29kZSBUVF9OVU1CRVJ9IC0gdGhlIHRva2VuIGlzIGEgbnVtYmVyLjwvbGk+CisgICAgICogPGxpPiB7QGNvZGUgVFRfRU9MfSAtIHRoZSBlbmQgb2YgbGluZSBoYXMgYmVlbiByZWFjaGVkLiBEZXBlbmRzIG9uCisgICAgICogd2hldGhlciB7QGNvZGUgZW9sSXNTaWduaWZpY2FudH0gaXMge0Bjb2RlIHRydWV9LjwvbGk+CisgICAgICogPGxpPiB7QGNvZGUgVFRfRU9GfSAtIHRoZSBlbmQgb2YgdGhlIHN0cmVhbSBoYXMgYmVlbiByZWFjaGVkLjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHR0eXBlID0gVFRfVU5LTk9XTjsKKworICAgIC8qKgorICAgICAqIEludGVybmFsIGNoYXJhY3RlciBtZWFuaW5ncywgMCBpbXBsaWVzIFRPS0VOX09SRElOQVJZCisgICAgICovCisgICAgcHJpdmF0ZSBieXRlW10gdG9rZW5UeXBlcyA9IG5ldyBieXRlWzI1Nl07CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFRPS0VOX0NPTU1FTlQgPSAxOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBUT0tFTl9RVU9URSA9IDI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFRPS0VOX1dISVRFID0gNDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgVE9LRU5fV09SRCA9IDg7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFRPS0VOX0RJR0lUID0gMTY7CisKKyAgICBwcml2YXRlIGludCBsaW5lTnVtYmVyID0gMTsKKworICAgIHByaXZhdGUgYm9vbGVhbiBmb3JjZUxvd2VyY2FzZTsKKworICAgIHByaXZhdGUgYm9vbGVhbiBpc0VPTFNpZ25pZmljYW50OworCisgICAgcHJpdmF0ZSBib29sZWFuIHNsYXNoU3RhckNvbW1lbnRzOworCisgICAgcHJpdmF0ZSBib29sZWFuIHNsYXNoU2xhc2hDb21tZW50czsKKworICAgIHByaXZhdGUgYm9vbGVhbiBwdXNoQmFja1Rva2VuOworCisgICAgcHJpdmF0ZSBib29sZWFuIGxhc3RDcjsKKworICAgIC8qIE9uZSBvZiB0aGVzZSB3aWxsIGhhdmUgdGhlIHN0cmVhbSAqLworICAgIHByaXZhdGUgSW5wdXRTdHJlYW0gaW5TdHJlYW07CisKKyAgICBwcml2YXRlIFJlYWRlciBpblJlYWRlcjsKKworICAgIHByaXZhdGUgaW50IHBlZWtDaGFyID0gLTI7CisKKyAgICAvKioKKyAgICAgKiBQcml2YXRlIGNvbnN0cnVjdG9yIHRvIGluaXRpYWxpemUgdGhlIGRlZmF1bHQgdmFsdWVzIGFjY29yZGluZyB0byB0aGUKKyAgICAgKiBzcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgU3RyZWFtVG9rZW5pemVyKCkgeworICAgICAgICAvKgorICAgICAgICAgKiBJbml0aWFsaXplIHRoZSBkZWZhdWx0IHN0YXRlIHBlciBzcGVjaWZpY2F0aW9uLiBBbGwgYnl0ZSB2YWx1ZXMgJ0EnCisgICAgICAgICAqIHRocm91Z2ggJ1onLCAnYScgdGhyb3VnaCAneicsIGFuZCAnXHUwMEEwJyB0aHJvdWdoICdcdTAwRkYnIGFyZQorICAgICAgICAgKiBjb25zaWRlcmVkIHRvIGJlIGFscGhhYmV0aWMuCisgICAgICAgICAqLworICAgICAgICB3b3JkQ2hhcnMoJ0EnLCAnWicpOworICAgICAgICB3b3JkQ2hhcnMoJ2EnLCAneicpOworICAgICAgICB3b3JkQ2hhcnMoMTYwLCAyNTUpOworICAgICAgICAvKioKKyAgICAgICAgICogQWxsIGJ5dGUgdmFsdWVzICdcdTAwMDAnIHRocm91Z2ggJ1x1MDAyMCcgYXJlIGNvbnNpZGVyZWQgdG8gYmUgd2hpdGUKKyAgICAgICAgICogc3BhY2UuCisgICAgICAgICAqLworICAgICAgICB3aGl0ZXNwYWNlQ2hhcnMoMCwgMzIpOworICAgICAgICAvKioKKyAgICAgICAgICogJy8nIGlzIGEgY29tbWVudCBjaGFyYWN0ZXIuIFNpbmdsZSBxdW90ZSAnXCcnIGFuZCBkb3VibGUgcXVvdGUgJyInCisgICAgICAgICAqIGFyZSBzdHJpbmcgcXVvdGUgY2hhcmFjdGVycy4KKyAgICAgICAgICovCisgICAgICAgIGNvbW1lbnRDaGFyKCcvJyk7CisgICAgICAgIHF1b3RlQ2hhcignIicpOworICAgICAgICBxdW90ZUNoYXIoJ1wnJyk7CisgICAgICAgIC8qKgorICAgICAgICAgKiBOdW1iZXJzIGFyZSBwYXJzZWQuCisgICAgICAgICAqLworICAgICAgICBwYXJzZU51bWJlcnMoKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIEVuZHMgb2YgbGluZXMgYXJlIHRyZWF0ZWQgYXMgd2hpdGUgc3BhY2UsIG5vdCBhcyBzZXBhcmF0ZSB0b2tlbnMuCisgICAgICAgICAqIEMtc3R5bGUgYW5kIEMrKy1zdHlsZSBjb21tZW50cyBhcmUgbm90IHJlY29nbml6ZWQuIFRoZXNlIGFyZSB0aGUKKyAgICAgICAgICogZGVmYXVsdHMgYW5kIGFyZSBub3QgbmVlZGVkIGluIGNvbnN0cnVjdG9yLgorICAgICAgICAgKi8KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBTdHJlYW1Ub2tlbml6ZXJ9IHdpdGgge0Bjb2RlIGlzfSBhcyBzb3VyY2UgaW5wdXQKKyAgICAgKiBzdHJlYW0uIFRoaXMgY29uc3RydWN0b3IgaXMgZGVwcmVjYXRlZDsgaW5zdGVhZCwgdGhlIGNvbnN0cnVjdG9yIHRoYXQKKyAgICAgKiB0YWtlcyBhIHtAY29kZSBSZWFkZXJ9IGFzIGFuIGFydWdtZW50IHNob3VsZCBiZSB1c2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGlzCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIHN0cmVhbSBmcm9tIHdoaWNoIHRvIHBhcnNlIHRva2Vucy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGlzfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjU3RyZWFtVG9rZW5pemVyKFJlYWRlcil9CisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgU3RyZWFtVG9rZW5pemVyKElucHV0U3RyZWFtIGlzKSB7CisgICAgICAgIHRoaXMoKTsKKyAgICAgICAgaWYgKGlzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGluU3RyZWFtID0gaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgU3RyZWFtVG9rZW5pemVyfSB3aXRoIHtAY29kZSByfSBhcyBzb3VyY2UgcmVhZGVyLgorICAgICAqIFRoZSB0b2tlbml6ZXIncyBpbml0aWFsIHN0YXRlIGlzIGFzIGZvbGxvd3M6CisgICAgICogPHVsPgorICAgICAqIDxsaT5BbGwgYnl0ZSB2YWx1ZXMgJ0EnIHRocm91Z2ggJ1onLCAnYScgdGhyb3VnaCAneicsIGFuZCAnJiM5Mjt1MDBBMCcKKyAgICAgKiB0aHJvdWdoICcmIzkyO3UwMEZGJyBhcmUgY29uc2lkZXJlZCB0byBiZSBhbHBoYWJldGljLjwvbGk+CisgICAgICogPGxpPkFsbCBieXRlIHZhbHVlcyAnJiM5Mjt1MDAwMCcgdGhyb3VnaCAnJiM5Mjt1MDAyMCcgYXJlIGNvbnNpZGVyZWQgdG8KKyAgICAgKiBiZSB3aGl0ZSBzcGFjZS4gJy8nIGlzIGEgY29tbWVudCBjaGFyYWN0ZXIuPC9saT4KKyAgICAgKiA8bGk+U2luZ2xlIHF1b3RlICdcJycgYW5kIGRvdWJsZSBxdW90ZSAnIicgYXJlIHN0cmluZyBxdW90ZSBjaGFyYWN0ZXJzLgorICAgICAqIDwvbGk+CisgICAgICogPGxpPk51bWJlcnMgYXJlIHBhcnNlZC48L2xpPgorICAgICAqIDxsaT5FbmQgb2YgbGluZXMgYXJlIGNvbnNpZGVyZWQgdG8gYmUgd2hpdGUgc3BhY2UgcmF0aGVyIHRoYW4gc2VwYXJhdGUKKyAgICAgKiB0b2tlbnMuPC9saT4KKyAgICAgKiA8bGk+Qy1zdHlsZSBhbmQgQysrLXN0eWxlIGNvbW1lbnRzIGFyZSBub3QgcmVjb2duaXplZC48L0xJPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSByZWFkZXIgZnJvbSB3aGljaCB0byBwYXJzZSB0b2tlbnMuCisgICAgICovCisgICAgcHVibGljIFN0cmVhbVRva2VuaXplcihSZWFkZXIgcikgeworICAgICAgICB0aGlzKCk7CisgICAgICAgIGlmIChyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGluUmVhZGVyID0gcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWZpZXMgdGhhdCB0aGUgY2hhcmFjdGVyIHtAY29kZSBjaH0gc2hhbGwgYmUgdHJlYXRlZCBhcyBhIGNvbW1lbnQKKyAgICAgKiBjaGFyYWN0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2gKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gYmUgY29uc2lkZXJlZCBhIGNvbW1lbnQgY2hhcmFjdGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNvbW1lbnRDaGFyKGludCBjaCkgeworICAgICAgICBpZiAoY2ggPj0gMCAmJiBjaCA8IHRva2VuVHlwZXMubGVuZ3RoKSB7CisgICAgICAgICAgICB0b2tlblR5cGVzW2NoXSA9IFRPS0VOX0NPTU1FTlQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWZpZXMgd2hldGhlciB0aGUgZW5kIG9mIGEgbGluZSBpcyBzaWduaWZpY2FudCBhbmQgc2hvdWxkIGJlIHJldHVybmVkCisgICAgICogYXMge0Bjb2RlIFRUX0VPRn0gaW4ge0Bjb2RlIHR0eXBlfSBieSB0aGlzIHRva2VuaXplci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmbGFnCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gaWYgRU9MIGlzIHNpZ25pZmljYW50LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlb2xJc1NpZ25pZmljYW50KGJvb2xlYW4gZmxhZykgeworICAgICAgICBpc0VPTFNpZ25pZmljYW50ID0gZmxhZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGxpbmUgbnVtYmVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIHRva2VuaXplcidzIGN1cnJlbnQgbGluZSBudW1iZXIuCisgICAgICovCisgICAgcHVibGljIGludCBsaW5lbm8oKSB7CisgICAgICAgIHJldHVybiBsaW5lTnVtYmVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNwZWNpZmllcyB3aGV0aGVyIHdvcmQgdG9rZW5zIHNob3VsZCBiZSBjb252ZXJ0ZWQgdG8gbG93ZXIgY2FzZSB3aGVuIHRoZXkKKyAgICAgKiBhcmUgc3RvcmVkIGluIHtAY29kZSBzdmFsfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmbGFnCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIHN2YWx9IHNob3VsZCBiZSBjb252ZXJ0ZWQgdG8gbG93ZXIKKyAgICAgKiAgICAgICAgICAgIGNhc2UsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvd2VyQ2FzZU1vZGUoYm9vbGVhbiBmbGFnKSB7CisgICAgICAgIGZvcmNlTG93ZXJjYXNlID0gZmxhZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgdGhlIG5leHQgdG9rZW4gZnJvbSB0aGlzIHRva2VuaXplcidzIHNvdXJjZSBzdHJlYW0gb3IgcmVhZGVyLiBUaGUKKyAgICAgKiB0eXBlIG9mIHRoZSB0b2tlbiBpcyBzdG9yZWQgaW4gdGhlIHtAY29kZSB0dHlwZX0gZmllbGQsIGFkZGl0aW9uYWwKKyAgICAgKiBpbmZvcm1hdGlvbiBtYXkgYmUgc3RvcmVkIGluIHRoZSB7QGNvZGUgbnZhbH0gb3Ige0Bjb2RlIHN2YWx9IGZpZWxkcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHtAY29kZSB0dHlwZX0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgcGFyc2luZyB0aGUgbmV4dCB0b2tlbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IG5leHRUb2tlbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwdXNoQmFja1Rva2VuKSB7CisgICAgICAgICAgICBwdXNoQmFja1Rva2VuID0gZmFsc2U7CisgICAgICAgICAgICBpZiAodHR5cGUgIT0gVFRfVU5LTk9XTikgeworICAgICAgICAgICAgICAgIHJldHVybiB0dHlwZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzdmFsID0gbnVsbDsgLy8gQWx3YXlzIHJlc2V0IHN2YWwgdG8gbnVsbAorICAgICAgICBpbnQgY3VycmVudENoYXIgPSBwZWVrQ2hhciA9PSAtMiA/IHJlYWQoKSA6IHBlZWtDaGFyOworCisgICAgICAgIGlmIChsYXN0Q3IgJiYgY3VycmVudENoYXIgPT0gJ1xuJykgeworICAgICAgICAgICAgbGFzdENyID0gZmFsc2U7CisgICAgICAgICAgICBjdXJyZW50Q2hhciA9IHJlYWQoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY3VycmVudENoYXIgPT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiAodHR5cGUgPSBUVF9FT0YpOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZSBjdXJyZW50VHlwZSA9IGN1cnJlbnRDaGFyID4gMjU1ID8gVE9LRU5fV09SRAorICAgICAgICAgICAgICAgIDogdG9rZW5UeXBlc1tjdXJyZW50Q2hhcl07CisgICAgICAgIHdoaWxlICgoY3VycmVudFR5cGUgJiBUT0tFTl9XSElURSkgIT0gMCkgeworICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgKiBTa2lwIG92ZXIgd2hpdGUgc3BhY2UgdW50aWwgd2UgaGl0IGEgbmV3IGxpbmUgb3IgYSByZWFsIHRva2VuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGlmIChjdXJyZW50Q2hhciA9PSAnXHInKSB7CisgICAgICAgICAgICAgICAgbGluZU51bWJlcisrOworICAgICAgICAgICAgICAgIGlmIChpc0VPTFNpZ25pZmljYW50KSB7CisgICAgICAgICAgICAgICAgICAgIGxhc3RDciA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIHBlZWtDaGFyID0gLTI7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAodHR5cGUgPSBUVF9FT0wpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoKGN1cnJlbnRDaGFyID0gcmVhZCgpKSA9PSAnXG4nKSB7CisgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRDaGFyID0gcmVhZCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudENoYXIgPT0gJ1xuJykgeworICAgICAgICAgICAgICAgIGxpbmVOdW1iZXIrKzsKKyAgICAgICAgICAgICAgICBpZiAoaXNFT0xTaWduaWZpY2FudCkgeworICAgICAgICAgICAgICAgICAgICBwZWVrQ2hhciA9IC0yOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHR0eXBlID0gVFRfRU9MKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY3VycmVudENoYXIgPSByZWFkKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIEFkdmFuY2Ugb3ZlciB0aGlzIHdoaXRlIHNwYWNlIGNoYXJhY3RlciBhbmQgdHJ5IGFnYWluLgorICAgICAgICAgICAgICAgIGN1cnJlbnRDaGFyID0gcmVhZCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGN1cnJlbnRDaGFyID09IC0xKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuICh0dHlwZSA9IFRUX0VPRik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjdXJyZW50VHlwZSA9IGN1cnJlbnRDaGFyID4gMjU1ID8gVE9LRU5fV09SRAorICAgICAgICAgICAgICAgICAgICA6IHRva2VuVHlwZXNbY3VycmVudENoYXJdOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENoZWNrIGZvciBkaWdpdHMgYmVmb3JlIGNoZWNraW5nIGZvciB3b3JkcyBzaW5jZSBkaWdpdHMgY2FuIGJlCisgICAgICAgICAqIGNvbnRhaW5lZCB3aXRoaW4gd29yZHMuCisgICAgICAgICAqLworICAgICAgICBpZiAoKGN1cnJlbnRUeXBlICYgVE9LRU5fRElHSVQpICE9IDApIHsKKyAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgZGlnaXRzID0gbmV3IFN0cmluZ0J1aWxkZXIoMjApOworICAgICAgICAgICAgYm9vbGVhbiBoYXZlRGVjaW1hbCA9IGZhbHNlLCBjaGVja0p1c3ROZWdhdGl2ZSA9IGN1cnJlbnRDaGFyID09ICctJzsKKyAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRDaGFyID09ICcuJykgeworICAgICAgICAgICAgICAgICAgICBoYXZlRGVjaW1hbCA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGRpZ2l0cy5hcHBlbmQoKGNoYXIpIGN1cnJlbnRDaGFyKTsKKyAgICAgICAgICAgICAgICBjdXJyZW50Q2hhciA9IHJlYWQoKTsKKyAgICAgICAgICAgICAgICBpZiAoKGN1cnJlbnRDaGFyIDwgJzAnIHx8IGN1cnJlbnRDaGFyID4gJzknKQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgKGhhdmVEZWNpbWFsIHx8IGN1cnJlbnRDaGFyICE9ICcuJykpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcGVla0NoYXIgPSBjdXJyZW50Q2hhcjsKKyAgICAgICAgICAgIGlmIChjaGVja0p1c3ROZWdhdGl2ZSAmJiBkaWdpdHMubGVuZ3RoKCkgPT0gMSkgeworICAgICAgICAgICAgICAgIC8vIERpZG4ndCBnZXQgYW55IG90aGVyIGRpZ2l0cyBvdGhlciB0aGFuICctJworICAgICAgICAgICAgICAgIHJldHVybiAodHR5cGUgPSAnLScpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBudmFsID0gRG91YmxlLnZhbHVlT2YoZGlnaXRzLnRvU3RyaW5nKCkpLmRvdWJsZVZhbHVlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIFVuc3VyZSB3aGF0IHRvIGRvLCB3aWxsIHdyaXRlIHRlc3QuCisgICAgICAgICAgICAgICAgbnZhbCA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gKHR0eXBlID0gVFRfTlVNQkVSKTsKKyAgICAgICAgfQorICAgICAgICAvLyBDaGVjayBmb3Igd29yZHMKKyAgICAgICAgaWYgKChjdXJyZW50VHlwZSAmIFRPS0VOX1dPUkQpICE9IDApIHsKKyAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgd29yZCA9IG5ldyBTdHJpbmdCdWlsZGVyKDIwKTsKKyAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgd29yZC5hcHBlbmQoKGNoYXIpIGN1cnJlbnRDaGFyKTsKKyAgICAgICAgICAgICAgICBjdXJyZW50Q2hhciA9IHJlYWQoKTsKKyAgICAgICAgICAgICAgICBpZiAoY3VycmVudENoYXIgPT0gLTEKKyAgICAgICAgICAgICAgICAgICAgICAgIHx8IChjdXJyZW50Q2hhciA8IDI1NiAmJiAodG9rZW5UeXBlc1tjdXJyZW50Q2hhcl0gJiAoVE9LRU5fV09SRCB8IFRPS0VOX0RJR0lUKSkgPT0gMCkpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcGVla0NoYXIgPSBjdXJyZW50Q2hhcjsKKyAgICAgICAgICAgIHN2YWwgPSB3b3JkLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBpZiAoZm9yY2VMb3dlcmNhc2UpIHsKKyAgICAgICAgICAgICAgICBzdmFsID0gc3ZhbC50b0xvd2VyQ2FzZShMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAodHR5cGUgPSBUVF9XT1JEKTsKKyAgICAgICAgfQorICAgICAgICAvLyBDaGVjayBmb3IgcXVvdGVkIGNoYXJhY3RlcgorICAgICAgICBpZiAoY3VycmVudFR5cGUgPT0gVE9LRU5fUVVPVEUpIHsKKyAgICAgICAgICAgIGludCBtYXRjaFF1b3RlID0gY3VycmVudENoYXI7CisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHF1b3RlU3RyaW5nID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgICAgIGludCBwZWVrT25lID0gcmVhZCgpOworICAgICAgICAgICAgd2hpbGUgKHBlZWtPbmUgPj0gMCAmJiBwZWVrT25lICE9IG1hdGNoUXVvdGUgJiYgcGVla09uZSAhPSAnXHInCisgICAgICAgICAgICAgICAgICAgICYmIHBlZWtPbmUgIT0gJ1xuJykgeworICAgICAgICAgICAgICAgIGJvb2xlYW4gcmVhZFBlZWsgPSB0cnVlOworICAgICAgICAgICAgICAgIGlmIChwZWVrT25lID09ICdcXCcpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGMxID0gcmVhZCgpOworICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3IgcXVvdGVkIG9jdGFsIElFOiBcMzc3CisgICAgICAgICAgICAgICAgICAgIGlmIChjMSA8PSAnNycgJiYgYzEgPj0gJzAnKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZGlnaXRWYWx1ZSA9IGMxIC0gJzAnOworICAgICAgICAgICAgICAgICAgICAgICAgYzEgPSByZWFkKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYzEgPiAnNycgfHwgYzEgPCAnMCcpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkUGVlayA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWdpdFZhbHVlID0gZGlnaXRWYWx1ZSAqIDggKyAoYzEgLSAnMCcpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMxID0gcmVhZCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxpbWl0IHRoZSBkaWdpdCB2YWx1ZSB0byBhIGJ5dGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGlnaXRWYWx1ZSA+IDAzNyB8fCBjMSA+ICc3JyB8fCBjMSA8ICcwJykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkUGVlayA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZ2l0VmFsdWUgPSBkaWdpdFZhbHVlICogOCArIChjMSAtICcwJyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFyZWFkUGVlaykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlJ3ZlIGNvbnN1bWVkIG9uZSB0byBtYW55CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVvdGVTdHJpbmcuYXBwZW5kKChjaGFyKSBkaWdpdFZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZWVrT25lID0gYzE7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlZWtPbmUgPSBkaWdpdFZhbHVlOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2EnOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZWVrT25lID0gMHg3OworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdiJzoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVla09uZSA9IDB4ODsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnZic6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlZWtPbmUgPSAweGM7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ24nOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZWVrT25lID0gMHhBOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdyJzoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVla09uZSA9IDB4RDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAndCc6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlZWtPbmUgPSAweDk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3YnOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZWVrT25lID0gMHhCOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZWVrT25lID0gYzE7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHJlYWRQZWVrKSB7CisgICAgICAgICAgICAgICAgICAgIHF1b3RlU3RyaW5nLmFwcGVuZCgoY2hhcikgcGVla09uZSk7CisgICAgICAgICAgICAgICAgICAgIHBlZWtPbmUgPSByZWFkKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHBlZWtPbmUgPT0gbWF0Y2hRdW90ZSkgeworICAgICAgICAgICAgICAgIHBlZWtPbmUgPSByZWFkKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwZWVrQ2hhciA9IHBlZWtPbmU7CisgICAgICAgICAgICB0dHlwZSA9IG1hdGNoUXVvdGU7CisgICAgICAgICAgICBzdmFsID0gcXVvdGVTdHJpbmcudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIHJldHVybiB0dHlwZTsKKyAgICAgICAgfQorICAgICAgICAvLyBEbyBjb21tZW50cywgYm90aCAiLy8iIGFuZCAiLypzdHVmZiovIgorICAgICAgICBpZiAoY3VycmVudENoYXIgPT0gJy8nICYmIChzbGFzaFNsYXNoQ29tbWVudHMgfHwgc2xhc2hTdGFyQ29tbWVudHMpKSB7CisgICAgICAgICAgICBpZiAoKGN1cnJlbnRDaGFyID0gcmVhZCgpKSA9PSAnKicgJiYgc2xhc2hTdGFyQ29tbWVudHMpIHsKKyAgICAgICAgICAgICAgICBpbnQgcGVla09uZSA9IHJlYWQoKTsKKyAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgICAgICBjdXJyZW50Q2hhciA9IHBlZWtPbmU7CisgICAgICAgICAgICAgICAgICAgIHBlZWtPbmUgPSByZWFkKCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50Q2hhciA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcGVla0NoYXIgPSAtMTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAodHR5cGUgPSBUVF9FT0YpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50Q2hhciA9PSAnXHInKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGVla09uZSA9PSAnXG4nKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVla09uZSA9IHJlYWQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVOdW1iZXIrKzsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50Q2hhciA9PSAnXG4nKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBsaW5lTnVtYmVyKys7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudENoYXIgPT0gJyonICYmIHBlZWtPbmUgPT0gJy8nKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwZWVrQ2hhciA9IHJlYWQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXh0VG9rZW4oKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudENoYXIgPT0gJy8nICYmIHNsYXNoU2xhc2hDb21tZW50cykgeworICAgICAgICAgICAgICAgIC8vIFNraXAgdG8gRU9GIG9yIG5ldyBsaW5lIHRoZW4gcmV0dXJuIHRoZSBuZXh0IHRva2VuCisgICAgICAgICAgICAgICAgd2hpbGUgKChjdXJyZW50Q2hhciA9IHJlYWQoKSkgPj0gMCAmJiBjdXJyZW50Q2hhciAhPSAnXHInCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBjdXJyZW50Q2hhciAhPSAnXG4nKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIEludGVudGlvbmFsbHkgZW1wdHkKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcGVla0NoYXIgPSBjdXJyZW50Q2hhcjsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV4dFRva2VuKCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnRUeXBlICE9IFRPS0VOX0NPTU1FTlQpIHsKKyAgICAgICAgICAgICAgICAvLyBXYXMganVzdCBhIHNsYXNoIGJ5IGl0c2VsZgorICAgICAgICAgICAgICAgIHBlZWtDaGFyID0gY3VycmVudENoYXI7CisgICAgICAgICAgICAgICAgcmV0dXJuICh0dHlwZSA9ICcvJyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gQ2hlY2sgZm9yIGNvbW1lbnQgY2hhcmFjdGVyCisgICAgICAgIGlmIChjdXJyZW50VHlwZSA9PSBUT0tFTl9DT01NRU5UKSB7CisgICAgICAgICAgICAvLyBTa2lwIHRvIEVPRiBvciBuZXcgbGluZSB0aGVuIHJldHVybiB0aGUgbmV4dCB0b2tlbgorICAgICAgICAgICAgd2hpbGUgKChjdXJyZW50Q2hhciA9IHJlYWQoKSkgPj0gMCAmJiBjdXJyZW50Q2hhciAhPSAnXHInCisgICAgICAgICAgICAgICAgICAgICYmIGN1cnJlbnRDaGFyICE9ICdcbicpIHsKKyAgICAgICAgICAgICAgICAvLyBJbnRlbnRpb25hbGx5IGVtcHR5CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwZWVrQ2hhciA9IGN1cnJlbnRDaGFyOworICAgICAgICAgICAgcmV0dXJuIG5leHRUb2tlbigpOworICAgICAgICB9CisKKyAgICAgICAgcGVla0NoYXIgPSByZWFkKCk7CisgICAgICAgIHJldHVybiAodHR5cGUgPSBjdXJyZW50Q2hhcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3BlY2lmaWVzIHRoYXQgdGhlIGNoYXJhY3RlciB7QGNvZGUgY2h9IHNoYWxsIGJlIHRyZWF0ZWQgYXMgYW4gb3JkaW5hcnkKKyAgICAgKiBjaGFyYWN0ZXIgYnkgdGhpcyB0b2tlbml6ZXIuIFRoYXQgaXMsIGl0IGhhcyBubyBzcGVjaWFsIG1lYW5pbmcgYXMgYQorICAgICAqIGNvbW1lbnQgY2hhcmFjdGVyLCB3b3JkIGNvbXBvbmVudCwgd2hpdGUgc3BhY2UsIHN0cmluZyBkZWxpbWl0ZXIgb3IKKyAgICAgKiBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2gKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gYmUgY29uc2lkZXJlZCBhbiBvcmRpbmFyeSBjaGFyYWN0ZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgb3JkaW5hcnlDaGFyKGludCBjaCkgeworICAgICAgICBpZiAoY2ggPj0gMCAmJiBjaCA8IHRva2VuVHlwZXMubGVuZ3RoKSB7CisgICAgICAgICAgICB0b2tlblR5cGVzW2NoXSA9IDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWZpZXMgdGhhdCB0aGUgY2hhcmFjdGVycyBpbiB0aGUgcmFuZ2UgZnJvbSB7QGNvZGUgbG93fSB0byB7QGNvZGUgaGl9CisgICAgICogc2hhbGwgYmUgdHJlYXRlZCBhcyBhbiBvcmRpbmFyeSBjaGFyYWN0ZXIgYnkgdGhpcyB0b2tlbml6ZXIuIFRoYXQgaXMsCisgICAgICogdGhleSBoYXZlIG5vIHNwZWNpYWwgbWVhbmluZyBhcyBhIGNvbW1lbnQgY2hhcmFjdGVyLCB3b3JkIGNvbXBvbmVudCwKKyAgICAgKiB3aGl0ZSBzcGFjZSwgc3RyaW5nIGRlbGltaXRlciBvciBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG93CisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSByYW5nZSBvZiBvcmRpbmFyeSBjaGFyYWN0ZXJzLgorICAgICAqIEBwYXJhbSBoaQorICAgICAqICAgICAgICAgICAgdGhlIGxhc3QgY2hhcmFjdGVyIGluIHRoZSByYW5nZSBvZiBvcmRpbmFyeSBjaGFyYWN0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG9yZGluYXJ5Q2hhcnMoaW50IGxvdywgaW50IGhpKSB7CisgICAgICAgIGlmIChsb3cgPCAwKSB7CisgICAgICAgICAgICBsb3cgPSAwOworICAgICAgICB9CisgICAgICAgIGlmIChoaSA+IHRva2VuVHlwZXMubGVuZ3RoKSB7CisgICAgICAgICAgICBoaSA9IHRva2VuVHlwZXMubGVuZ3RoIC0gMTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gbG93OyBpIDw9IGhpOyBpKyspIHsKKyAgICAgICAgICAgIHRva2VuVHlwZXNbaV0gPSAwOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU3BlY2lmaWVzIHRoYXQgdGhpcyB0b2tlbml6ZXIgc2hhbGwgcGFyc2UgbnVtYmVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwYXJzZU51bWJlcnMoKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAnMCc7IGkgPD0gJzknOyBpKyspIHsKKyAgICAgICAgICAgIHRva2VuVHlwZXNbaV0gfD0gVE9LRU5fRElHSVQ7CisgICAgICAgIH0KKyAgICAgICAgdG9rZW5UeXBlc1snLiddIHw9IFRPS0VOX0RJR0lUOworICAgICAgICB0b2tlblR5cGVzWyctJ10gfD0gVE9LRU5fRElHSVQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoYXQgdGhlIGN1cnJlbnQgdG9rZW4gc2hvdWxkIGJlIHB1c2hlZCBiYWNrIGFuZCByZXR1cm5lZCBhZ2FpbgorICAgICAqIHRoZSBuZXh0IHRpbWUge0Bjb2RlIG5leHRUb2tlbigpfSBpcyBjYWxsZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHVzaEJhY2soKSB7CisgICAgICAgIHB1c2hCYWNrVG9rZW4gPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNwZWNpZmllcyB0aGF0IHRoZSBjaGFyYWN0ZXIge0Bjb2RlIGNofSBzaGFsbCBiZSB0cmVhdGVkIGFzIGEgcXVvdGUKKyAgICAgKiBjaGFyYWN0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2gKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gYmUgY29uc2lkZXJlZCBhIHF1b3RlIGNoYXJhY3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBxdW90ZUNoYXIoaW50IGNoKSB7CisgICAgICAgIGlmIChjaCA+PSAwICYmIGNoIDwgdG9rZW5UeXBlcy5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRva2VuVHlwZXNbY2hdID0gVE9LRU5fUVVPVEU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQ2FsbCB0aGUgcmVhZCBmb3IgdGhlIGFwcHJvcHJpYXRlIHN0cmVhbQorICAgICAgICBpZiAoaW5TdHJlYW0gPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGluUmVhZGVyLnJlYWQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW5TdHJlYW0ucmVhZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNwZWNpZmllcyB0aGF0IGFsbCBjaGFyYWN0ZXJzIHNoYWxsIGJlIHRyZWF0ZWQgYXMgb3JkaW5hcnkgY2hhcmFjdGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZXNldFN5bnRheCgpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyNTY7IGkrKykgeworICAgICAgICAgICAgdG9rZW5UeXBlc1tpXSA9IDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWZpZXMgd2hldGhlciAic2xhc2gtc2xhc2giIChDKystc3R5bGUpIGNvbW1lbnRzIHNoYWxsIGJlIHJlY29nbml6ZWQuCisgICAgICogVGhpcyBraW5kIG9mIGNvbW1lbnQgZW5kcyBhdCB0aGUgZW5kIG9mIHRoZSBsaW5lLgorICAgICAqCisgICAgICogQHBhcmFtIGZsYWcKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgLy99IHNob3VsZCBiZSByZWNvZ25pemVkIGFzIHRoZSBzdGFydAorICAgICAqICAgICAgICAgICAgb2YgYSBjb21tZW50LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzbGFzaFNsYXNoQ29tbWVudHMoYm9vbGVhbiBmbGFnKSB7CisgICAgICAgIHNsYXNoU2xhc2hDb21tZW50cyA9IGZsYWc7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3BlY2lmaWVzIHdoZXRoZXIgInNsYXNoLXN0YXIiIChDLXN0eWxlKSBjb21tZW50cyBzaGFsbCBiZSByZWNvZ25pemVkLgorICAgICAqIFNsYXNoLXN0YXIgY29tbWVudHMgY2Fubm90IGJlIG5lc3RlZCBhbmQgZW5kIHdoZW4gYSBzdGFyLXNsYXNoCisgICAgICogY29tYmluYXRpb24gaXMgZm91bmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmxhZworICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGlmIHtAY29kZSAvKn0gc2hvdWxkIGJlIHJlY29nbml6ZWQgYXMgdGhlIHN0YXJ0CisgICAgICogICAgICAgICAgICBvZiBhIGNvbW1lbnQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNsYXNoU3RhckNvbW1lbnRzKGJvb2xlYW4gZmxhZykgeworICAgICAgICBzbGFzaFN0YXJDb21tZW50cyA9IGZsYWc7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RhdGUgb2YgdGhpcyB0b2tlbml6ZXIgaW4gYSByZWFkYWJsZSBmb3JtYXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoaXMgdG9rZW5pemVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIC8vIFZhbHVlcyBkZXRlcm1pbmVkIHRocm91Z2ggZXhwZXJpbWVudGF0aW9uCisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZCgiVG9rZW5bIik7CisgICAgICAgIHN3aXRjaCAodHR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgVFRfRU9GOgorICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIkVPRiIpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBUVF9FT0w6CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiRU9MIik7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFRUX05VTUJFUjoKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJuPSIpOworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQobnZhbCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFRUX1dPUkQ6CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChzdmFsKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgaWYgKHR0eXBlID09IFRUX1VOS05PV04gfHwgdG9rZW5UeXBlc1t0dHlwZV0gPT0gVE9LRU5fUVVPVEUpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChzdmFsKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCdcJycpOworICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKChjaGFyKSB0dHlwZSk7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJ1wnJyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJlc3VsdC5hcHBlbmQoIl0sIGxpbmUgIik7CisgICAgICAgIHJlc3VsdC5hcHBlbmQobGluZU51bWJlcik7CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWZpZXMgdGhhdCB0aGUgY2hhcmFjdGVycyBpbiB0aGUgcmFuZ2UgZnJvbSB7QGNvZGUgbG93fSB0byB7QGNvZGUgaGl9CisgICAgICogc2hhbGwgYmUgdHJlYXRlZCBhcyB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMgYnkgdGhpcyB0b2tlbml6ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG93CisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSByYW5nZSBvZiB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMuCisgICAgICogQHBhcmFtIGhpCisgICAgICogICAgICAgICAgICB0aGUgbGFzdCBjaGFyYWN0ZXIgaW4gdGhlIHJhbmdlIG9mIHdoaXRlc3BhY2UgY2hhcmFjdGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3aGl0ZXNwYWNlQ2hhcnMoaW50IGxvdywgaW50IGhpKSB7CisgICAgICAgIGlmIChsb3cgPCAwKSB7CisgICAgICAgICAgICBsb3cgPSAwOworICAgICAgICB9CisgICAgICAgIGlmIChoaSA+IHRva2VuVHlwZXMubGVuZ3RoKSB7CisgICAgICAgICAgICBoaSA9IHRva2VuVHlwZXMubGVuZ3RoIC0gMTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gbG93OyBpIDw9IGhpOyBpKyspIHsKKyAgICAgICAgICAgIHRva2VuVHlwZXNbaV0gPSBUT0tFTl9XSElURTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNwZWNpZmllcyB0aGF0IHRoZSBjaGFyYWN0ZXJzIGluIHRoZSByYW5nZSBmcm9tIHtAY29kZSBsb3d9IHRvIHtAY29kZSBoaX0KKyAgICAgKiBzaGFsbCBiZSB0cmVhdGVkIGFzIHdvcmQgY2hhcmFjdGVycyBieSB0aGlzIHRva2VuaXplci4gQSB3b3JkIGNvbnNpc3RzIG9mCisgICAgICogYSB3b3JkIGNoYXJhY3RlciBmb2xsb3dlZCBieSB6ZXJvIG9yIG1vcmUgd29yZCBvciBudW1iZXIgY2hhcmFjdGVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb3cKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gdGhlIHJhbmdlIG9mIHdvcmQgY2hhcmFjdGVycy4KKyAgICAgKiBAcGFyYW0gaGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBsYXN0IGNoYXJhY3RlciBpbiB0aGUgcmFuZ2Ugb2Ygd29yZCBjaGFyYWN0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdvcmRDaGFycyhpbnQgbG93LCBpbnQgaGkpIHsKKyAgICAgICAgaWYgKGxvdyA8IDApIHsKKyAgICAgICAgICAgIGxvdyA9IDA7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGhpID4gdG9rZW5UeXBlcy5sZW5ndGgpIHsKKyAgICAgICAgICAgIGhpID0gdG9rZW5UeXBlcy5sZW5ndGggLSAxOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSBsb3c7IGkgPD0gaGk7IGkrKykgeworICAgICAgICAgICAgdG9rZW5UeXBlc1tpXSB8PSBUT0tFTl9XT1JEOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vU3RyaW5nQnVmZmVySW5wdXRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1N0cmluZ0J1ZmZlcklucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWZhZGE1NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1N0cmluZ0J1ZmZlcklucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxNTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogQSBzcGVjaWFsaXplZCB7QGxpbmsgSW5wdXRTdHJlYW19IHRoYXQgcmVhZHMgYnl0ZXMgZnJvbSBhIHtAY29kZSBTdHJpbmd9IGluCisgKiBhIHNlcXVlbnRpYWwgbWFubmVyLgorICoKKyAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgU3RyaW5nUmVhZGVyfQorICovCitARGVwcmVjYXRlZAorcHVibGljIGNsYXNzIFN0cmluZ0J1ZmZlcklucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworICAgIC8qKgorICAgICAqIFRoZSBzb3VyY2Ugc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGRhdGEgdG8gcmVhZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIGJ1ZmZlcjsKKworICAgIC8qKgorICAgICAqIFRoZSB0b3RhbCBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgc291cmNlIHN0cmluZy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGNvdW50OworCisgICAgLyoqCisgICAgICogVGhlIGN1cnJlbnQgcG9zaXRpb24gd2l0aGluIHRoZSBzb3VyY2Ugc3RyaW5nLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgcG9zOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgbmV3IHtAY29kZSBTdHJpbmdCdWZmZXJJbnB1dFN0cmVhbX0gd2l0aCB7QGNvZGUgc3RyfSBhcworICAgICAqIHNvdXJjZS4gVGhlIHNpemUgb2YgdGhlIHN0cmVhbSBpcyBzZXQgdG8gdGhlIHtAY29kZSBsZW5ndGgoKX0gb2YgdGhlCisgICAgICogc3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBzdHJpbmcgZm9yIHRoaXMgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1ZmZlcklucHV0U3RyZWFtKFN0cmluZyBzdHIpIHsKKyAgICAgICAgaWYgKHN0ciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBidWZmZXIgPSBzdHI7CisgICAgICAgIGNvdW50ID0gc3RyLmxlbmd0aCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGF2YWlsYWJsZSgpIHsKKyAgICAgICAgcmV0dXJuIGNvdW50IC0gcG9zOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgc2luZ2xlIGJ5dGUgZnJvbSB0aGUgc291cmNlIHN0cmluZyBhbmQgcmV0dXJucyBpdCBhcyBhbiBpbnRlZ2VyCisgICAgICogaW4gdGhlIHJhbmdlIGZyb20gMCB0byAyNTUuIFJldHVybnMgLTEgaWYgdGhlIGVuZCBvZiB0aGUgc291cmNlIHN0cmluZworICAgICAqIGhhcyBiZWVuIHJlYWNoZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBieXRlIHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgc291cmNlIHN0cmluZyBoYXMgYmVlbgorICAgICAqICAgICAgICAgcmVhY2hlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCByZWFkKCkgeworICAgICAgICByZXR1cm4gcG9zIDwgY291bnQgPyBidWZmZXIuY2hhckF0KHBvcysrKSAmIDB4RkYgOiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhdCBtb3N0IHtAY29kZSBsZW5ndGh9IGJ5dGVzIGZyb20gdGhlIHNvdXJjZSBzdHJpbmcgYW5kIHN0b3JlcyB0aGVtCisgICAgICogaW4gdGhlIGJ5dGUgYXJyYXkge0Bjb2RlIGJ9IHN0YXJ0aW5nIGF0IHtAY29kZSBvZmZzZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYXJyYXkgaW4gd2hpY2ggdG8gc3RvcmUgdGhlIGJ5dGVzIHJlYWQuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgcG9zaXRpb24gaW4ge0Bjb2RlIGJ9IHRvIHN0b3JlIHRoZSBieXRlcyByZWFkIGZyb20KKyAgICAgKiAgICAgICAgICAgIHRoaXMgc3RyZWFtLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0byBzdG9yZSBpbiB7QGNvZGUgYn0uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgc291cmNlCisgICAgICogICAgICAgICBzdHJpbmcgaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGxlbmd0aCA8IDB9LCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBsZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGJ9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYn0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IHJlYWQoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgICAgICBpZiAoYnVmZmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiYnVmZmVyID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXIubGVuZ3RoLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIGlmIChsZW5ndGggPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBpbnQgY29weWxlbiA9IGNvdW50IC0gcG9zIDwgbGVuZ3RoID8gY291bnQgLSBwb3MgOiBsZW5ndGg7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY29weWxlbjsgaSsrKSB7CisgICAgICAgICAgICBidWZmZXJbb2Zmc2V0ICsgaV0gPSAoYnl0ZSkgdGhpcy5idWZmZXIuY2hhckF0KHBvcyArIGkpOworICAgICAgICB9CisgICAgICAgIHBvcyArPSBjb3B5bGVuOworICAgICAgICByZXR1cm4gY29weWxlbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhpcyBzdHJlYW0gdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgc291cmNlIHN0cmluZy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVzZXQoKSB7CisgICAgICAgIHBvcyA9IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcHMge0Bjb2RlIGNoYXJDb3VudH0gY2hhcmFjdGVycyBpbiB0aGUgc291cmNlIHN0cmluZy4gSXQgZG9lcyBub3RoaW5nIGFuZAorICAgICAqIHJldHVybnMgMCBpZiB7QGNvZGUgY2hhckNvdW50fSBpcyBuZWdhdGl2ZS4gTGVzcyB0aGFuIHtAY29kZSBjaGFyQ291bnR9IGNoYXJhY3RlcnMgYXJlCisgICAgICogc2tpcHBlZCBpZiB0aGUgZW5kIG9mIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIHJlYWNoZWQgYmVmb3JlIHRoZSBvcGVyYXRpb24KKyAgICAgKiBjb21wbGV0ZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBhY3R1YWxseSBza2lwcGVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgbG9uZyBza2lwKGxvbmcgY2hhckNvdW50KSB7CisgICAgICAgIGlmIChjaGFyQ291bnQgPD0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBpbnQgbnVtc2tpcHBlZDsKKyAgICAgICAgaWYgKHRoaXMuY291bnQgLSBwb3MgPCBjaGFyQ291bnQpIHsKKyAgICAgICAgICAgIG51bXNraXBwZWQgPSB0aGlzLmNvdW50IC0gcG9zOworICAgICAgICAgICAgcG9zID0gdGhpcy5jb3VudDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG51bXNraXBwZWQgPSAoaW50KSBjaGFyQ291bnQ7CisgICAgICAgICAgICBwb3MgKz0gY2hhckNvdW50OworICAgICAgICB9CisgICAgICAgIHJldHVybiBudW1za2lwcGVkOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1N0cmluZ1JlYWRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vU3RyaW5nUmVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWY4ZmYxMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1N0cmluZ1JlYWRlci5qYXZhCkBAIC0wLDAgKzEsMjQ4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuaW87CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIEEgc3BlY2lhbGl6ZWQge0BsaW5rIFJlYWRlcn0gdGhhdCByZWFkcyBjaGFyYWN0ZXJzIGZyb20gYSB7QGNvZGUgU3RyaW5nfSBpbgorICogYSBzZXF1ZW50aWFsIG1hbm5lci4KKyAqCisgKiBAc2VlIFN0cmluZ1dyaXRlcgorICovCitwdWJsaWMgY2xhc3MgU3RyaW5nUmVhZGVyIGV4dGVuZHMgUmVhZGVyIHsKKyAgICBwcml2YXRlIFN0cmluZyBzdHI7CisKKyAgICBwcml2YXRlIGludCBtYXJrcG9zID0gLTE7CisKKyAgICBwcml2YXRlIGludCBwb3M7CisKKyAgICBwcml2YXRlIGludCBjb3VudDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIG5ldyB7QGNvZGUgU3RyaW5nUmVhZGVyfSB3aXRoIHtAY29kZSBzdHJ9IGFzIHNvdXJjZS4gVGhlIHNpemUKKyAgICAgKiBvZiB0aGUgcmVhZGVyIGlzIHNldCB0byB0aGUge0Bjb2RlIGxlbmd0aCgpfSBvZiB0aGUgc3RyaW5nIGFuZCB0aGUgT2JqZWN0CisgICAgICogdG8gc3luY2hyb25pemUgYWNjZXNzIHRocm91Z2ggaXMgc2V0IHRvIHtAY29kZSBzdHJ9LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBzdHJpbmcgZm9yIHRoaXMgcmVhZGVyLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdSZWFkZXIoU3RyaW5nIHN0cikgeworICAgICAgICB0aGlzLnN0ciA9IHN0cjsKKyAgICAgICAgdGhpcy5jb3VudCA9IHN0ci5sZW5ndGgoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhpcyByZWFkZXIuIE9uY2UgaXQgaXMgY2xvc2VkLCByZWFkIG9wZXJhdGlvbnMgb24gdGhpcyByZWFkZXIKKyAgICAgKiB3aWxsIHRocm93IGFuIHtAY29kZSBJT0V4Y2VwdGlvbn0uIE9ubHkgdGhlIGZpcnN0IGludm9jYXRpb24gb2YgdGhpcworICAgICAqIG1ldGhvZCBoYXMgYW55IGVmZmVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICAgICAgc3RyID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyByZWFkZXIgaXMgY2xvc2VkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgY2xvc2VkLCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNDbG9zZWQoKSB7CisgICAgICAgIHJldHVybiBzdHIgPT0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGEgbWFyayBwb3NpdGlvbiBpbiB0aGlzIHJlYWRlci4gVGhlIHBhcmFtZXRlciB7QGNvZGUgcmVhZExpbWl0fSBpcworICAgICAqIGlnbm9yZWQgZm9yIHRoaXMgY2xhc3MuIENhbGxpbmcge0Bjb2RlIHJlc2V0KCl9IHdpbGwgcmVwb3NpdGlvbiB0aGUKKyAgICAgKiByZWFkZXIgYmFjayB0byB0aGUgbWFya2VkIHBvc2l0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYWRMaW1pdAorICAgICAqICAgICAgICAgICAgaWdub3JlZCBmb3Ige0Bjb2RlIFN0cmluZ1JlYWRlcn0gaW5zdGFuY2VzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHJlYWRMaW1pdCA8IDB9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQuCisgICAgICogQHNlZSAjbWFya1N1cHBvcnRlZCgpCisgICAgICogQHNlZSAjcmVzZXQoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIG1hcmsoaW50IHJlYWRMaW1pdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHJlYWRMaW1pdCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgICAgIG1hcmtwb3MgPSBwb3M7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tOb3RDbG9zZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaXNDbG9zZWQoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJTdHJpbmdSZWFkZXIgaXMgY2xvc2VkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIHJlYWRlciBzdXBwb3J0cyB0aGUge0Bjb2RlIG1hcmsoKX0gYW5kIHtAY29kZQorICAgICAqIHJlc2V0KCl9IG1ldGhvZHMuIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyB7QGNvZGUgdHJ1ZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFsd2F5cyB7QGNvZGUgdHJ1ZX0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gbWFya1N1cHBvcnRlZCgpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBzaW5nbGUgY2hhcmFjdGVyIGZyb20gdGhlIHNvdXJjZSBzdHJpbmcgYW5kIHJldHVybnMgaXQgYXMgYW4KKyAgICAgKiBpbnRlZ2VyIHdpdGggdGhlIHR3byBoaWdoZXItb3JkZXIgYnl0ZXMgc2V0IHRvIDAuIFJldHVybnMgLTEgaWYgdGhlIGVuZAorICAgICAqIG9mIHRoZSBzb3VyY2Ugc3RyaW5nIGhhcyBiZWVuIHJlYWNoZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFyYWN0ZXIgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZSBzb3VyY2Ugc3RyaW5nIGhhcyBiZWVuCisgICAgICogICAgICAgICByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBjaGVja05vdENsb3NlZCgpOworICAgICAgICAgICAgaWYgKHBvcyAhPSBjb3VudCkgeworICAgICAgICAgICAgICAgIHJldHVybiBzdHIuY2hhckF0KHBvcysrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGF0IG1vc3Qge0Bjb2RlIGxlbn0gY2hhcmFjdGVycyBmcm9tIHRoZSBzb3VyY2Ugc3RyaW5nIGFuZCBzdG9yZXMKKyAgICAgKiB0aGVtIGF0IHtAY29kZSBvZmZzZXR9IGluIHRoZSBjaGFyYWN0ZXIgYXJyYXkge0Bjb2RlIGJ1Zn0uIFJldHVybnMgdGhlCisgICAgICogbnVtYmVyIG9mIGNoYXJhY3RlcnMgYWN0dWFsbHkgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZSBzb3VyY2Ugc3RyaW5nCisgICAgICogaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWYKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgYXJyYXkgdG8gc3RvcmUgdGhlIGNoYXJhY3RlcnMgcmVhZC4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBwb3NpdGlvbiBpbiB7QGNvZGUgYnVmZmVyfSB0byBzdG9yZSB0aGUgY2hhcmFjdGVycworICAgICAqICAgICAgICAgICAgcmVhZCBmcm9tIHRoaXMgcmVhZGVyLgorICAgICAqIEBwYXJhbSBsZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgcmVhZCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZSByZWFkZXIgaGFzCisgICAgICogICAgICAgICBiZWVuIHJlYWNoZWQuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBsZW4gPCAwfSwgb3IgaWYKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgb2Zmc2V0ICsgbGVufSBpcyBncmVhdGVyIHRoYW4gdGhlIHNpemUgb2Yge0Bjb2RlIGJ1Zn0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgcmVhZGVyIGlzIGNsb3NlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoY2hhcltdIGJ1ZiwgaW50IG9mZnNldCwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBjaGVja05vdENsb3NlZCgpOworICAgICAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmLmxlbmd0aCwgb2Zmc2V0LCBsZW4pOworICAgICAgICAgICAgaWYgKGxlbiA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocG9zID09IHRoaXMuY291bnQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgZW5kID0gcG9zICsgbGVuID4gdGhpcy5jb3VudCA/IHRoaXMuY291bnQgOiBwb3MgKyBsZW47CisgICAgICAgICAgICBzdHIuZ2V0Q2hhcnMocG9zLCBlbmQsIGJ1Ziwgb2Zmc2V0KTsKKyAgICAgICAgICAgIGludCByZWFkID0gZW5kIC0gcG9zOworICAgICAgICAgICAgcG9zID0gZW5kOworICAgICAgICAgICAgcmV0dXJuIHJlYWQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIHJlYWRlciBpcyByZWFkeSB0byBiZSByZWFkIHdpdGhvdXQgYmxvY2tpbmcuIFRoaXMKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBhbHdheXMgcmV0dXJucyB7QGNvZGUgdHJ1ZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFsd2F5cyB7QGNvZGUgdHJ1ZX0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgcmVhZGVyIGlzIGNsb3NlZC4KKyAgICAgKiBAc2VlICNyZWFkKCkKKyAgICAgKiBAc2VlICNyZWFkKGNoYXJbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gcmVhZHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0cyB0aGlzIHJlYWRlcidzIHBvc2l0aW9uIHRvIHRoZSBsYXN0IHtAY29kZSBtYXJrKCl9IGxvY2F0aW9uLgorICAgICAqIEludm9jYXRpb25zIG9mIHtAY29kZSByZWFkKCl9IGFuZCB7QGNvZGUgc2tpcCgpfSB3aWxsIG9jY3VyIGZyb20gdGhpcyBuZXcKKyAgICAgKiBsb2NhdGlvbi4gSWYgdGhpcyByZWFkZXIgaGFzIG5vdCBiZWVuIG1hcmtlZCwgaXQgaXMgcmVzZXQgdG8gdGhlCisgICAgICogYmVnaW5uaW5nIG9mIHRoZSBzb3VyY2Ugc3RyaW5nLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgcmVhZGVyIGlzIGNsb3NlZC4KKyAgICAgKiBAc2VlICNtYXJrKGludCkKKyAgICAgKiBAc2VlICNtYXJrU3VwcG9ydGVkKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCByZXNldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgICAgIHBvcyA9IG1hcmtwb3MgIT0gLTEgPyBtYXJrcG9zIDogMDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIE1vdmVzIHtAY29kZSBjaGFyQ291bnR9IGNoYXJhY3RlcnMgaW4gdGhlIHNvdXJjZSBzdHJpbmcuIFVubGlrZSB0aGUge0BsaW5rCisgICAgICogUmVhZGVyI3NraXAobG9uZykgb3ZlcnJpZGRlbiBtZXRob2R9LCB0aGlzIG1ldGhvZCBtYXkgc2tpcCBuZWdhdGl2ZSBza2lwCisgICAgICogZGlzdGFuY2VzOiB0aGlzIHJld2luZHMgdGhlIGlucHV0IHNvIHRoYXQgY2hhcmFjdGVycyBtYXkgYmUgcmVhZCBhZ2Fpbi4KKyAgICAgKiBXaGVuIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSBzdHJpbmcgaGFzIGJlZW4gcmVhY2hlZCwgdGhlIGlucHV0IGNhbm5vdCBiZQorICAgICAqIHJld291bmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhckNvdW50CisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBza2lwLiBQb3NpdGl2ZSB2YWx1ZXMgc2tpcAorICAgICAqICAgICAgICAgICAgZm9yd2FyZDsgbmVnYXRpdmUgdmFsdWVzIHNraXAgYmFja3dhcmQuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgYWN0dWFsbHkgc2tpcHBlZC4gVGhpcyBpcyBib3VuZGVkIGJlbG93CisgICAgICogICAgICAgICAgICBieSB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgYWxyZWFkeSByZWFkIGFuZCBhYm92ZSBieSB0aGUKKyAgICAgKiAgICAgICAgICAgIG51bWJlciBvZiBjaGFyYWN0ZXJzIHJlbWFpbmluZzo8YnI+IHtAY29kZSAtKG51bSBjaGFycyBhbHJlYWR5CisgICAgICogICAgICAgICAgICByZWFkKSA8PSBkaXN0YW5jZSBza2lwcGVkIDw9IG51bSBjaGFycyByZW1haW5pbmd9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHJlYWRlciBpcyBjbG9zZWQuCisgICAgICogQHNlZSAjbWFyayhpbnQpCisgICAgICogQHNlZSAjbWFya1N1cHBvcnRlZCgpCisgICAgICogQHNlZSAjcmVzZXQoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIHNraXAobG9uZyBjaGFyQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKworICAgICAgICAgICAgaW50IG1pblNraXAgPSAtcG9zOworICAgICAgICAgICAgaW50IG1heFNraXAgPSBjb3VudCAtIHBvczsKKworICAgICAgICAgICAgaWYgKG1heFNraXAgPT0gMCB8fCBjaGFyQ291bnQgPiBtYXhTa2lwKSB7CisgICAgICAgICAgICAgICAgY2hhckNvdW50ID0gbWF4U2tpcDsgLy8gbm8gcmV3aW5kaW5nIGlmIHdlJ3JlIGF0IHRoZSBlbmQKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hhckNvdW50IDwgbWluU2tpcCkgeworICAgICAgICAgICAgICAgIGNoYXJDb3VudCA9IG1pblNraXA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHBvcyArPSBjaGFyQ291bnQ7CisgICAgICAgICAgICByZXR1cm4gY2hhckNvdW50OworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vU3RyaW5nV3JpdGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9TdHJpbmdXcml0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMGIxZDE4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vU3RyaW5nV3JpdGVyLmphdmEKQEAgLTAsMCArMSwyMzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogQSBzcGVjaWFsaXplZCB7QGxpbmsgV3JpdGVyfSB0aGF0IHdyaXRlcyBjaGFyYWN0ZXJzIHRvIGEge0Bjb2RlIFN0cmluZ0J1ZmZlcn0KKyAqIGluIGEgc2VxdWVudGlhbCBtYW5uZXIsIGFwcGVuZGluZyB0aGVtIGluIHRoZSBwcm9jZXNzLiBUaGUgcmVzdWx0IGNhbiBsYXRlcgorICogYmUgcXVlcmllZCB1c2luZyB0aGUge0BsaW5rICNTdHJpbmdXcml0ZXIoaW50KX0gb3Ige0BsaW5rICN0b1N0cmluZygpfQorICogbWV0aG9kcy4KKyAqCisgKiBAc2VlIFN0cmluZ1JlYWRlcgorICovCitwdWJsaWMgY2xhc3MgU3RyaW5nV3JpdGVyIGV4dGVuZHMgV3JpdGVyIHsKKworICAgIHByaXZhdGUgU3RyaW5nQnVmZmVyIGJ1ZjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFN0cmluZ1dyaXRlcn0gd2hpY2ggaGFzIGEge0BsaW5rIFN0cmluZ0J1ZmZlcn0KKyAgICAgKiBhbGxvY2F0ZWQgd2l0aCB0aGUgZGVmYXVsdCBzaXplIG9mIDE2IGNoYXJhY3RlcnMuIFRoZSB7QGNvZGUKKyAgICAgKiBTdHJpbmdCdWZmZXJ9IGlzIGFsc28gdGhlIHtAY29kZSBsb2NrfSB1c2VkIHRvIHN5bmNocm9uaXplIGFjY2VzcyB0byB0aGlzCisgICAgICogd3JpdGVyLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdXcml0ZXIoKSB7CisgICAgICAgIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoMTYpOworICAgICAgICBsb2NrID0gYnVmOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFN0cmluZ1dyaXRlcn0gd2hpY2ggaGFzIGEge0BsaW5rIFN0cmluZ0J1ZmZlcn0KKyAgICAgKiBhbGxvY2F0ZWQgd2l0aCBhIHNpemUgb2Yge0Bjb2RlIGluaXRpYWxTaXplfSBjaGFyYWN0ZXJzLiBUaGUge0Bjb2RlCisgICAgICogU3RyaW5nQnVmZmVyfSBpcyBhbHNvIHRoZSB7QGNvZGUgbG9ja30gdXNlZCB0byBzeW5jaHJvbml6ZSBhY2Nlc3MgdG8gdGhpcworICAgICAqIHdyaXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbml0aWFsU2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGludGlhbCBzaXplIG9mIHRoZSB0YXJnZXQgc3RyaW5nIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nV3JpdGVyKGludCBpbml0aWFsU2l6ZSkgeworICAgICAgICBpZiAoaW5pdGlhbFNpemUgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcihpbml0aWFsU2l6ZSk7CisgICAgICAgIGxvY2sgPSBidWY7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCBoYXMgbm8gZWZmZWN0LiBJbiBjb250cmFzdCB0byBtb3N0IHtAY29kZSBXcml0ZXJ9IHN1YmNsYXNzZXMsCisgICAgICogdGhlIG90aGVyIG1ldGhvZHMgaW4ge0Bjb2RlIFN0cmluZ1dyaXRlcn0gZG8gbm90IHRocm93IGFuIHtAY29kZSBJT0V4Y2VwdGlvbn0gaWYKKyAgICAgKiB7QGNvZGUgY2xvc2UoKX0gaGFzIGJlZW4gY2FsbGVkLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjbG9zaW5nIHRoaXMgd3JpdGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLyogZW1wdHkgKi8KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxsaW5nIHRoaXMgbWV0aG9kIGhhcyBubyBlZmZlY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB7CisgICAgICAgIC8qIGVtcHR5ICovCisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIHJlZmVyZW5jZSB0byB0aGlzIHdyaXRlcidzIGludGVybmFsIHtAbGluayBTdHJpbmdCdWZmZXJ9LiBBbnkKKyAgICAgKiBjaGFuZ2VzIG1hZGUgdG8gdGhlIHJldHVybmVkIGJ1ZmZlciBhcmUgcmVmbGVjdGVkIGluIHRoaXMgd3JpdGVyLgorICAgICAqCisgICAgICogQHJldHVybiBhIHJlZmVyZW5jZSB0byB0aGlzIHdyaXRlcidzIGludGVybmFsIHtAY29kZSBTdHJpbmdCdWZmZXJ9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgZ2V0QnVmZmVyKCkgeworICAgICAgICByZXR1cm4gYnVmOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGlzIHdyaXRlciBhcyBhIHN0cmluZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyB3cml0ZXIncyBjb250ZW50cyBhcyBhIHN0cmluZy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHtAY29kZSBjb3VudH0gY2hhcmFjdGVycyBzdGFydGluZyBhdCB7QGNvZGUgb2Zmc2V0fSBpbiB7QGNvZGUgYnVmfQorICAgICAqIHRvIHRoaXMgd3JpdGVyJ3Mge0Bjb2RlIFN0cmluZ0J1ZmZlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBub24tbnVsbCBjaGFyYWN0ZXIgYXJyYXkgdG8gd3JpdGUuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4ge0Bjb2RlIGNoYXJzfSB0byB3cml0ZS4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwfSBvciB7QGNvZGUgY291bnQgPCAwfSwgb3IgaWYge0Bjb2RlCisgICAgICogICAgICAgICAgICAgb2Zmc2V0ICsgY291bnR9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgc2l6ZSBvZiB7QGNvZGUgYnVmfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShjaGFyW10gY2hhcnMsIGludCBvZmZzZXQsIGludCBjb3VudCkgeworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChjaGFycy5sZW5ndGgsIG9mZnNldCwgY291bnQpOworICAgICAgICBpZiAoY291bnQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGJ1Zi5hcHBlbmQoY2hhcnMsIG9mZnNldCwgY291bnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBvbmUgY2hhcmFjdGVyIHRvIHRoaXMgd3JpdGVyJ3Mge0Bjb2RlIFN0cmluZ0J1ZmZlcn0uIE9ubHkgdGhlIHR3bworICAgICAqIGxlYXN0IHNpZ25pZmljYW50IGJ5dGVzIG9mIHRoZSBpbnRlZ2VyIHtAY29kZSBvbmVDaGFyfSBhcmUgd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvbmVDaGFyCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIHdyaXRlIHRvIHRoaXMgd3JpdGVyJ3Mge0Bjb2RlIFN0cmluZ0J1ZmZlcn0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IG9uZUNoYXIpIHsKKyAgICAgICAgYnVmLmFwcGVuZCgoY2hhcikgb25lQ2hhcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIHNwZWNpZmllZCBzdHJpbmcgdG8gdGhpcyB3cml0ZXIncyB7QGNvZGUKKyAgICAgKiBTdHJpbmdCdWZmZXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIG5vbi1udWxsIHN0cmluZyBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXJzIHRvIHdyaXRlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKFN0cmluZyBzdHIpIHsKKyAgICAgICAgYnVmLmFwcGVuZChzdHIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB7QGNvZGUgY291bnR9IGNoYXJhY3RlcnMgZnJvbSB7QGNvZGUgc3RyfSBzdGFydGluZyBhdCB7QGNvZGUKKyAgICAgKiBvZmZzZXR9IHRvIHRoaXMgd3JpdGVyJ3Mge0Bjb2RlIFN0cmluZ0J1ZmZlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgbm9uLW51bGwgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGNoYXJhY3RlcnMgdG8gd3JpdGUuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4ge0Bjb2RlIHN0cn0gdG8gd3JpdGUuCisgICAgICogQHBhcmFtIGNvdW50CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgZnJvbSB7QGNvZGUgc3RyfSB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGNvdW50IDwgMH0sIG9yIGlmIHtAY29kZQorICAgICAqICAgICAgICAgICAgIG9mZnNldCArIGNvdW50fSBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZiB7QGNvZGUgc3RyfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShTdHJpbmcgc3RyLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHsKKyAgICAgICAgU3RyaW5nIHN1YiA9IHN0ci5zdWJzdHJpbmcob2Zmc2V0LCBvZmZzZXQgKyBjb3VudCk7CisgICAgICAgIGJ1Zi5hcHBlbmQoc3ViKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHRoZSBjaGFyYWN0ZXIge0Bjb2RlIGN9IHRvIHRoaXMgd3JpdGVyJ3Mge0Bjb2RlIFN0cmluZ0J1ZmZlcn0uCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgdGhlIHNhbWUgd2F5IGFzIHtAbGluayAjd3JpdGUoaW50KX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byBhcHBlbmQgdG8gdGhlIHRhcmdldCBzdHJlYW0uCisgICAgICogQHJldHVybiB0aGlzIHdyaXRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nV3JpdGVyIGFwcGVuZChjaGFyIGMpIHsKKyAgICAgICAgd3JpdGUoYyk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSB7QGNvZGUgY3NxfSB0byB0aGlzIHdyaXRlcidzIHtAY29kZQorICAgICAqIFN0cmluZ0J1ZmZlcn0uIFRoaXMgbWV0aG9kIHdvcmtzIHRoZSBzYW1lIHdheSBhcyB7QGNvZGUKKyAgICAgKiBTdHJpbmdXcml0ZXIud3JpdGUoY3NxLnRvU3RyaW5nKCkpfS4gSWYge0Bjb2RlIGNzcX0gaXMge0Bjb2RlIG51bGx9LCB0aGVuCisgICAgICogdGhlIHN0cmluZyAibnVsbCIgaXMgd3JpdHRlbiB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjc3EKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgYXBwZW5kZWQgdG8gdGhlIHRhcmdldC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgd3JpdGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdXcml0ZXIgYXBwZW5kKENoYXJTZXF1ZW5jZSBjc3EpIHsKKyAgICAgICAgaWYgKGNzcSA9PSBudWxsKSB7CisgICAgICAgICAgICBjc3EgPSAibnVsbCI7CisgICAgICAgIH0KKyAgICAgICAgd3JpdGUoY3NxLnRvU3RyaW5nKCkpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIGEgc3Vic2VxdWVuY2Ugb2YgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSB7QGNvZGUgY3NxfSB0byB0aGlzCisgICAgICogd3JpdGVyJ3Mge0Bjb2RlIFN0cmluZ0J1ZmZlcn0uIFRoaXMgbWV0aG9kIHdvcmtzIHRoZSBzYW1lIHdheSBhcyB7QGNvZGUKKyAgICAgKiBTdHJpbmdXcml0ZXIud3JpdGVyKGNzcS5zdWJzZXF1ZW5jZShzdGFydCwgZW5kKS50b1N0cmluZygpKX0uIElmIHtAY29kZQorICAgICAqIGNzcX0gaXMge0Bjb2RlIG51bGx9LCB0aGVuIHRoZSBzcGVjaWZpZWQgc3Vic2VxdWVuY2Ugb2YgdGhlIHN0cmluZyAibnVsbCIKKyAgICAgKiB3aWxsIGJlIHdyaXR0ZW4gdG8gdGhlIHRhcmdldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjc3EKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgYXBwZW5kZWQgdG8gdGhlIHRhcmdldC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhciBpbiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIGFwcGVuZGVkCisgICAgICogICAgICAgICAgICB0byB0aGUgdGFyZ2V0LgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgY2hhcmFjdGVyIGZvbGxvd2luZyB0aGUgbGFzdCBjaGFyYWN0ZXIgb2YgdGhlCisgICAgICogICAgICAgICAgICBzdWJzZXF1ZW5jZSBhcHBlbmRlZCB0byB0aGUgdGFyZ2V0LgorICAgICAqIEByZXR1cm4gdGhpcyB3cml0ZXIuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0ID4gZW5kfSwge0Bjb2RlIHN0YXJ0IDwgMH0sIHtAY29kZSBlbmQgPCAwfSBvcgorICAgICAqICAgICAgICAgICAgIGVpdGhlciB7QGNvZGUgc3RhcnR9IG9yIHtAY29kZSBlbmR9IGFyZSBncmVhdGVyIG9yIGVxdWFsIHRoYW4KKyAgICAgKiAgICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHtAY29kZSBjc3F9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdXcml0ZXIgYXBwZW5kKENoYXJTZXF1ZW5jZSBjc3EsIGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBpZiAoY3NxID09IG51bGwpIHsKKyAgICAgICAgICAgIGNzcSA9ICJudWxsIjsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgb3V0cHV0ID0gY3NxLnN1YlNlcXVlbmNlKHN0YXJ0LCBlbmQpLnRvU3RyaW5nKCk7CisgICAgICAgIHdyaXRlKG91dHB1dCwgMCwgb3V0cHV0Lmxlbmd0aCgpKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vU3luY0ZhaWxlZEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vU3luY0ZhaWxlZEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI0MjI0MTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9TeW5jRmFpbGVkRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCisvKioKKyAqIFNpZ25hbHMgdGhhdCB0aGUge0BsaW5rIEZpbGVEZXNjcmlwdG9yI3N5bmMoKX0gbWV0aG9kIGhhcyBmYWlsZWQgdG8KKyAqIGNvbXBsZXRlLgorICovCitwdWJsaWMgY2xhc3MgU3luY0ZhaWxlZEV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yMzUzMzQyNjg0NDEyNDQzMzMwTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFN5bmNGYWlsZWRFeGNlcHRpb259IHdpdGggaXRzIHN0YWNrIHRyYWNlIGFuZAorICAgICAqIGRldGFpbCBtZXNzYWdlIGZpbGxlZCBpbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBTeW5jRmFpbGVkRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1VURkRhdGFGb3JtYXRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1VURkRhdGFGb3JtYXRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZjU2YWNkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vVVRGRGF0YUZvcm1hdEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworLyoqCisgKiBTaWduYWxzIHRoYXQgYW4gaW5jb3JyZWN0bHkgZW5jb2RlZCBVVEYtOCBzdHJpbmcgaGFzIGJlZW4gZW5jb3VudGVyZWQsIG1vc3QKKyAqIGxpa2VseSB3aGlsZSByZWFkaW5nIHNvbWUge0BsaW5rIERhdGFJbnB1dFN0cmVhbX0uCisgKgorICogQHNlZSBEYXRhSW5wdXRTdHJlYW0jcmVhZFVURigpCisgKi8KK3B1YmxpYyBjbGFzcyBVVEZEYXRhRm9ybWF0RXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNDIwNzQzNDQ5MjI4MjgwNjEyTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFVURkRhdGFGb3JtYXRFeGNlcHRpb259IHdpdGggaXRzIHN0YWNrIHRyYWNlCisgICAgICogZmlsbGVkIGluLgorICAgICAqLworICAgIHB1YmxpYyBVVEZEYXRhRm9ybWF0RXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFVURkRhdGFGb3JtYXRFeGNlcHRpb259IHdpdGggaXRzIHN0YWNrIHRyYWNlIGFuZAorICAgICAqIGRldGFpbCBtZXNzYWdlIGZpbGxlZCBpbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBVVEZEYXRhRm9ybWF0RXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1Vuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1Vuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMjQ4MjZiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5pbzsKKworLyoqCisgKiBUaHJvd24gd2hlbiBhIHByb2dyYW0gYXNrcyBmb3IgYSBwYXJ0aWN1bGFyIGNoYXJhY3RlciBjb252ZXJ0ZXIgdGhhdCBpcworICogdW5hdmFpbGFibGUuCisgKi8KK3B1YmxpYyBjbGFzcyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQyNzQyNzYyOTgzMjYxMzY2NzBMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbn0gd2l0aCBpdHMgc3RhY2sKKyAgICAgKiB0cmFjZSBmaWxsZWQgaW4uCisgICAgICovCisgICAgcHVibGljIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbn0gd2l0aCBpdHMgc3RhY2sKKyAgICAgKiB0cmFjZSBhbmQgZGV0YWlsIG1lc3NhZ2UgZmlsbGVkIGluLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vV3JpdGVBYm9ydGVkRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9Xcml0ZUFib3J0ZWRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZmUyMDJmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvaW8vV3JpdGVBYm9ydGVkRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw4MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCisvKioKKyAqIFNpZ25hbHMgdGhhdCB0aGUge0BsaW5rIE9iamVjdElucHV0U3RyZWFtI3JlYWRPYmplY3QoKX0gbWV0aG9kIGhhcyBkZXRlY3RlZAorICogYW4gZXhjZXB0aW9uIG1hcmtlciBpbiB0aGUgaW5wdXQgc3RyZWFtLiBUaGlzIG1hcmtlciBpbmRpY2F0ZXMgdGhhdCBleGNlcHRpb24KKyAqIG9jY3VycmVkIHdoZW4gdGhlIG9iamVjdCB3YXMgc2VyaWFsaXplZCwgYW5kIHRoaXMgbWFya2VyIHdhcyBpbnNlcnRlZCBpbnN0ZWFkCisgKiBvZiB0aGUgb3JpZ2luYWwgb2JqZWN0LiBJdCBpcyBhIHdheSB0byAicHJvcGFnYXRlIiBhbiBleGNlcHRpb24gZnJvbSB0aGUgY29kZQorICogdGhhdCBhdHRlbXB0ZWQgdG8gd3JpdGUgdGhlIG9iamVjdCB0byB0aGUgY29kZSB0aGF0IGlzIGF0dGVtcHRpbmcgdG8gcmVhZCB0aGUKKyAqIG9iamVjdC4KKyAqCisgKiBAc2VlIE9iamVjdElucHV0U3RyZWFtI3JlYWRPYmplY3QoKQorICovCitwdWJsaWMgY2xhc3MgV3JpdGVBYm9ydGVkRXhjZXB0aW9uIGV4dGVuZHMgT2JqZWN0U3RyZWFtRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0zMzI2NDI2NjI1NTk3MjgyNDQyTDsKKworICAgIC8qKgorICAgICAqIFRoZSBleGNlcHRpb24gdGhhdCBvY2N1cmVkIHdoZW4gd3JpdGVPYmplY3QoKSB3YXMgYXR0ZW1wdGluZyB0byBzZXJpYWxpemUKKyAgICAgKiB0aGUgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBFeGNlcHRpb24gZGV0YWlsOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgV3JpdGVBYm9ydGVkRXhjZXB0aW9ufSB3aXRoIGl0cyBzdGFjayB0cmFjZSwKKyAgICAgKiBkZXRhaWwgbWVzc2FnZSBhbmQgdGhlIGV4Y2VwdGlvbiB3aGljaCBjYXVzZWQgdGhlIHVuZGVybHlpbmcgcHJvYmxlbSB3aGVuCisgICAgICogc2VyaWFsaXppbmcgdGhlIG9iamVjdCBmaWxsZWQgaW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gcm9vdENhdXNlCisgICAgICogICAgICAgICAgICB0aGUgZXhjZXB0aW9uIHRoYXQgd2FzIHRocm93biB3aGVuIHNlcmlhbGl6aW5nIHRoZSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIFdyaXRlQWJvcnRlZEV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSwgRXhjZXB0aW9uIHJvb3RDYXVzZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICAgICAgZGV0YWlsID0gcm9vdENhdXNlOworICAgICAgICBpbml0Q2F1c2Uocm9vdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBleHRyYSBpbmZvcm1hdGlvbiBtZXNzYWdlIHdoaWNoIHdhcyBwcm92aWRlZCB3aGVuIHRoaXMgZXhjZXB0aW9uCisgICAgICogd2FzIGNyZWF0ZWQuIFJldHVybnMge0Bjb2RlIG51bGx9IGlmIG5vIG1lc3NhZ2Ugd2FzIHByb3ZpZGVkIGF0IGNyZWF0aW9uCisgICAgICogdGltZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGV4Y2VwdGlvbiBtZXNzYWdlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9IHN1cGVyLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgaWYgKGRldGFpbCAhPSBudWxsKSB7CisgICAgICAgICAgICBtc2cgPSBtc2cgKyAiOyAiICsgZGV0YWlsLnRvU3RyaW5nKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG1zZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjYXVzZSBvZiB0aGlzIGV4Y2VwdGlvbiBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgaXMgbm8gY2F1c2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBleGNlcHRpb24gY2F1c2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFRocm93YWJsZSBnZXRDYXVzZSgpIHsKKyAgICAgICAgcmV0dXJuIGRldGFpbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9Xcml0ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2lvL1dyaXRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlMjhiODAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9pby9Xcml0ZXIuamF2YQpAQCAtMCwwICsxLDI0NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmlvOworCisvKioKKyAqIFRoZSBiYXNlIGNsYXNzIGZvciBhbGwgd3JpdGVycy4gQSB3cml0ZXIgaXMgYSBtZWFucyBvZiB3cml0aW5nIGRhdGEgdG8gYQorICogdGFyZ2V0IGluIGEgY2hhcmFjdGVyLXdpc2UgbWFubmVyLiBNb3N0IG91dHB1dCBzdHJlYW1zIGV4cGVjdCB0aGUKKyAqIHtAbGluayAjZmx1c2goKX0gbWV0aG9kIHRvIGJlIGNhbGxlZCBiZWZvcmUgY2xvc2luZyB0aGUgc3RyZWFtLCB0byBlbnN1cmUgYWxsCisgKiBkYXRhIGlzIGFjdHVhbGx5IHdyaXR0ZW4gb3V0LgorICogPHA+CisgKiBUaGlzIGFic3RyYWN0IGNsYXNzIGRvZXMgbm90IHByb3ZpZGUgYSBmdWxseSB3b3JraW5nIGltcGxlbWVudGF0aW9uLCBzbyBpdAorICogbmVlZHMgdG8gYmUgc3ViY2xhc3NlZCwgYW5kIGF0IGxlYXN0IHRoZSB7QGxpbmsgI3dyaXRlKGNoYXJbXSwgaW50LCBpbnQpfSwKKyAqIHtAbGluayAjY2xvc2UoKX0gYW5kIHtAbGluayAjZmx1c2goKX0gbWV0aG9kcyBuZWVkcyB0byBiZSBvdmVycmlkZGVuLgorICogT3ZlcnJpZGluZyBzb21lIG9mIHRoZSBub24tYWJzdHJhY3QgbWV0aG9kcyBpcyBhbHNvIG9mdGVuIGFkdmlzZWQsIHNpbmNlIGl0CisgKiBtaWdodCByZXN1bHQgaW4gaGlnaGVyIGVmZmljaWVuY3kuCisgKiA8cD4KKyAqIE1hbnkgc3BlY2lhbGl6ZWQgcmVhZGVycyBmb3IgcHVycG9zZXMgbGlrZSByZWFkaW5nIGZyb20gYSBmaWxlIGFscmVhZHkgZXhpc3QKKyAqIGluIHRoaXMgcGFja2FnZS4KKyAqCisgKiBAc2VlIFJlYWRlcgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgV3JpdGVyIGltcGxlbWVudHMgQXBwZW5kYWJsZSwgQ2xvc2VhYmxlLCBGbHVzaGFibGUgeworICAgIC8qKgorICAgICAqIFRoZSBvYmplY3QgdXNlZCB0byBzeW5jaHJvbml6ZSBhY2Nlc3MgdG8gdGhlIHdyaXRlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgT2JqZWN0IGxvY2s7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBXcml0ZXJ9IHdpdGgge0Bjb2RlIHRoaXN9IGFzIHRoZSBvYmplY3QgdXNlZCB0bworICAgICAqIHN5bmNocm9uaXplIGNyaXRpY2FsIHNlY3Rpb25zLgorICAgICAqLworICAgIHByb3RlY3RlZCBXcml0ZXIoKSB7CisgICAgICAgIGxvY2sgPSB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFdyaXRlcn0gd2l0aCB7QGNvZGUgbG9ja30gdXNlZCB0byBzeW5jaHJvbml6ZQorICAgICAqIGNyaXRpY2FsIHNlY3Rpb25zLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2sKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT2JqZWN0fSB1c2VkIHRvIHN5bmNocm9uaXplIGNyaXRpY2FsIHNlY3Rpb25zLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbG9ja30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHByb3RlY3RlZCBXcml0ZXIoT2JqZWN0IGxvY2spIHsKKyAgICAgICAgaWYgKGxvY2sgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5sb2NrID0gbG9jazsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhpcyB3cml0ZXIuIEltcGxlbWVudGF0aW9ucyBvZiB0aGlzIG1ldGhvZCBzaG91bGQgZnJlZSBhbnkKKyAgICAgKiByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSB3cml0ZXIuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNsb3NpbmcgdGhpcyB3cml0ZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIHRoaXMgd3JpdGVyLiBJbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBtZXRob2Qgc2hvdWxkIGVuc3VyZSB0aGF0CisgICAgICogYWxsIGJ1ZmZlcmVkIGNoYXJhY3RlcnMgYXJlIHdyaXR0ZW4gdG8gdGhlIHRhcmdldC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgZmx1c2hpbmcgdGhpcyB3cml0ZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGVudGlyZSBjaGFyYWN0ZXIgYnVmZmVyIHtAY29kZSBidWZ9IHRvIHRoZSB0YXJnZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmCisgICAgICogICAgICAgICAgICB0aGUgbm9uLW51bGwgYXJyYXkgY29udGFpbmluZyBjaGFyYWN0ZXJzIHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHdyaXRlciBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGNoYXJbXSBidWYpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlKGJ1ZiwgMCwgYnVmLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHtAY29kZSBjb3VudH0gY2hhcmFjdGVycyBzdGFydGluZyBhdCB7QGNvZGUgb2Zmc2V0fSBpbiB7QGNvZGUgYnVmfQorICAgICAqIHRvIHRoZSB0YXJnZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmCisgICAgICogICAgICAgICAgICB0aGUgbm9uLW51bGwgY2hhcmFjdGVyIGFycmF5IHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHtAY29kZSBidWZ9IHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBjb3VudCA8IDB9LCBvciBpZiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBvZmZzZXQgKyBjb3VudH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBzaXplIG9mIHtAY29kZSBidWZ9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHdyaXRlciBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHdyaXRlKGNoYXJbXSBidWYsIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIG9uZSBjaGFyYWN0ZXIgdG8gdGhlIHRhcmdldC4gT25seSB0aGUgdHdvIGxlYXN0IHNpZ25pZmljYW50IGJ5dGVzCisgICAgICogb2YgdGhlIGludGVnZXIge0Bjb2RlIG9uZUNoYXJ9IGFyZSB3cml0dGVuLgorICAgICAqCisgICAgICogQHBhcmFtIG9uZUNoYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gd3JpdGUgdG8gdGhlIHRhcmdldC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB3cml0ZXIgaXMgY2xvc2VkIG9yIGFub3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgb25lQ2hhcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBjaGFyW10gb25lQ2hhckFycmF5ID0gbmV3IGNoYXJbMV07CisgICAgICAgICAgICBvbmVDaGFyQXJyYXlbMF0gPSAoY2hhcikgb25lQ2hhcjsKKyAgICAgICAgICAgIHdyaXRlKG9uZUNoYXJBcnJheSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgc3BlY2lmaWVkIHN0cmluZyB0byB0aGUgdGFyZ2V0LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIG5vbi1udWxsIHN0cmluZyBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXJzIHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHdyaXRlciBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFN0cmluZyBzdHIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlKHN0ciwgMCwgc3RyLmxlbmd0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMge0Bjb2RlIGNvdW50fSBjaGFyYWN0ZXJzIGZyb20ge0Bjb2RlIHN0cn0gc3RhcnRpbmcgYXQge0Bjb2RlCisgICAgICogb2Zmc2V0fSB0byB0aGUgdGFyZ2V0LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIG5vbi1udWxsIHN0cmluZyBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXJzIHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHtAY29kZSBzdHJ9IHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGZyb20ge0Bjb2RlIHN0cn0gdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgd3JpdGVyIGlzIGNsb3NlZCBvciBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBjb3VudCA8IDB9LCBvciBpZiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBvZmZzZXQgKyBjb3VudH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2Yge0Bjb2RlIHN0cn0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGUoU3RyaW5nIHN0ciwgaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoKG9mZnNldCB8IGNvdW50KSA8IDAgfHwgb2Zmc2V0ID4gc3RyLmxlbmd0aCgpIC0gY291bnQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKHN0ciwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgY2hhcltdIGJ1ZiA9IG5ldyBjaGFyW2NvdW50XTsKKyAgICAgICAgc3RyLmdldENoYXJzKG9mZnNldCwgb2Zmc2V0ICsgY291bnQsIGJ1ZiwgMCk7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgd3JpdGUoYnVmLCAwLCBidWYubGVuZ3RoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlIGNoYXJhY3RlciB7QGNvZGUgY30gdG8gdGhlIHRhcmdldC4gVGhpcyBtZXRob2Qgd29ya3MgdGhlIHNhbWUKKyAgICAgKiB3YXkgYXMge0BsaW5rICN3cml0ZShpbnQpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIGFwcGVuZCB0byB0aGUgdGFyZ2V0IHN0cmVhbS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgd3JpdGVyLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHdyaXRlciBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBXcml0ZXIgYXBwZW5kKGNoYXIgYykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGUoYyk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSB7QGNvZGUgY3NxfSB0byB0aGUgdGFyZ2V0LiBUaGlzIG1ldGhvZAorICAgICAqIHdvcmtzIHRoZSBzYW1lIHdheSBhcyB7QGNvZGUgV3JpdGVyLndyaXRlKGNzcS50b1N0cmluZygpKX0uIElmIHtAY29kZQorICAgICAqIGNzcX0gaXMge0Bjb2RlIG51bGx9LCB0aGVuIHRoZSBzdHJpbmcgIm51bGwiIGlzIHdyaXR0ZW4gdG8gdGhlIHRhcmdldAorICAgICAqIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjc3EKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgYXBwZW5kZWQgdG8gdGhlIHRhcmdldC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgd3JpdGVyLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHdyaXRlciBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBXcml0ZXIgYXBwZW5kKENoYXJTZXF1ZW5jZSBjc3EpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjc3EgPT0gbnVsbCkgeworICAgICAgICAgICAgY3NxID0gIm51bGwiOworICAgICAgICB9CisgICAgICAgIHdyaXRlKGNzcS50b1N0cmluZygpKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyBhIHN1YnNlcXVlbmNlIG9mIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2Uge0Bjb2RlIGNzcX0gdG8gdGhlCisgICAgICogdGFyZ2V0LiBUaGlzIG1ldGhvZCB3b3JrcyB0aGUgc2FtZSB3YXkgYXMge0Bjb2RlCisgICAgICogV3JpdGVyLndyaXRlcihjc3Euc3Vic2VxdWVuY2Uoc3RhcnQsIGVuZCkudG9TdHJpbmcoKSl9LiBJZiB7QGNvZGUKKyAgICAgKiBjc3F9IGlzIHtAY29kZSBudWxsfSwgdGhlbiB0aGUgc3BlY2lmaWVkIHN1YnNlcXVlbmNlIG9mIHRoZSBzdHJpbmcgIm51bGwiCisgICAgICogd2lsbCBiZSB3cml0dGVuIHRvIHRoZSB0YXJnZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY3NxCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIGFwcGVuZGVkIHRvIHRoZSB0YXJnZXQuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXIgaW4gdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSBhcHBlbmRlZAorICAgICAqICAgICAgICAgICAgdG8gdGhlIHRhcmdldC4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNoYXJhY3RlciBmb2xsb3dpbmcgdGhlIGxhc3QgY2hhcmFjdGVyIG9mIHRoZQorICAgICAqICAgICAgICAgICAgc3Vic2VxdWVuY2UgYXBwZW5kZWQgdG8gdGhlIHRhcmdldC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgd3JpdGVyLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHdyaXRlciBpcyBjbG9zZWQgb3IgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA+IGVuZH0sIHtAY29kZSBzdGFydCA8IDB9LCB7QGNvZGUgZW5kIDwgMH0gb3IKKyAgICAgKiAgICAgICAgICAgICBlaXRoZXIge0Bjb2RlIHN0YXJ0fSBvciB7QGNvZGUgZW5kfSBhcmUgZ3JlYXRlciBvciBlcXVhbCB0aGFuCisgICAgICogICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB7QGNvZGUgY3NxfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgV3JpdGVyIGFwcGVuZChDaGFyU2VxdWVuY2UgY3NxLCBpbnQgc3RhcnQsIGludCBlbmQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjc3EgPT0gbnVsbCkgeworICAgICAgICAgICAgY3NxID0gIm51bGwiOworICAgICAgICB9CisgICAgICAgIHdyaXRlKGNzcS5zdWJTZXF1ZW5jZShzdGFydCwgZW5kKS50b1N0cmluZygpKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgd3JpdGVyIGhhcyBlbmNvdW50ZXJlZCBhbmQgc3VwcHJlc3NlZCBhbiBlcnJvci4gVXNlZAorICAgICAqIGJ5IFByaW50V3JpdGVycyBhcyBhbiBhbHRlcm5hdGl2ZSB0byBjaGVja2VkIGV4Y2VwdGlvbnMuCisgICAgICovCisgICAgYm9vbGVhbiBjaGVja0Vycm9yKCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9BYnN0cmFjdE1ldGhvZEVycm9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0Fic3RyYWN0TWV0aG9kRXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMjEyNTA4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9BYnN0cmFjdE1ldGhvZEVycm9yLmphdmEKQEAgLTAsMCArMSw0NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyb3duIGJ5IHRoZSBWTSB3aGVuIGFuIGFic3RyYWN0IG1ldGhvZCBpcyBjYWxsZWQuCisgKiA8cD4KKyAqIE5vdGUgdGhhdCB0aGlzIGNhbiBvbmx5IG9jY3VyIHdoZW4gaW5jb25zaXN0ZW50IGNsYXNzIGZpbGVzIGhhdmUgYmVlbiBsb2FkZWQsCisgKiBzaW5jZSBpbnZva2luZyBhbiBhYnN0cmFjdCBtZXRob2QgaXMgYSBjb21waWxlIHRpbWUgZXJyb3IuCisgKi8KK3B1YmxpYyBjbGFzcyBBYnN0cmFjdE1ldGhvZEVycm9yIGV4dGVuZHMgSW5jb21wYXRpYmxlQ2xhc3NDaGFuZ2VFcnJvciB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTY1NDM5MTA4Mjk4OTAxODQ2Mkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBBYnN0cmFjdE1ldGhvZEVycm9yfSB0aGF0IGluY2x1ZGVzIHRoZSBjdXJyZW50CisgICAgICogc3RhY2sgdHJhY2UuCisgICAgICovCisgICAgcHVibGljIEFic3RyYWN0TWV0aG9kRXJyb3IoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQWJzdHJhY3RNZXRob2RFcnJvcn0gd2l0aCB0aGUgY3VycmVudCBzdGFjayB0cmFjZQorICAgICAqIGFuZCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgQWJzdHJhY3RNZXRob2RFcnJvcihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0Fic3RyYWN0U3RyaW5nQnVpbGRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9BYnN0cmFjdFN0cmluZ0J1aWxkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYWFiNDdkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9BYnN0cmFjdFN0cmluZ0J1aWxkZXIuamF2YQpAQCAtMCwwICsxLDkwMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKK2ltcG9ydCBqYXZhLmlvLkludmFsaWRPYmplY3RFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuRW1wdHlBcnJheTsKKworLyoqCisgKiBBIG1vZGlmaWFibGUge0BsaW5rIENoYXJTZXF1ZW5jZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzfSBmb3IgdXNlIGluIGNyZWF0aW5nCisgKiBhbmQgbW9kaWZ5aW5nIFN0cmluZ3MuIFRoaXMgY2xhc3MgaXMgaW50ZW5kZWQgYXMgYSBiYXNlIGNsYXNzIGZvcgorICoge0BsaW5rIFN0cmluZ0J1ZmZlcn0gYW5kIHtAbGluayBTdHJpbmdCdWlsZGVyfS4KKyAqCisgKiBAc2VlIFN0cmluZ0J1ZmZlcgorICogQHNlZSBTdHJpbmdCdWlsZGVyCisgKiBAc2luY2UgMS41CisgKi8KK2Fic3RyYWN0IGNsYXNzIEFic3RyYWN0U3RyaW5nQnVpbGRlciB7CisKKyAgICBzdGF0aWMgZmluYWwgaW50IElOSVRJQUxfQ0FQQUNJVFkgPSAxNjsKKworICAgIHByaXZhdGUgY2hhcltdIHZhbHVlOworCisgICAgcHJpdmF0ZSBpbnQgY291bnQ7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gc2hhcmVkOworCisgICAgLyoKKyAgICAgKiBSZXR1cm5zIHRoZSBjaGFyYWN0ZXIgYXJyYXkuCisgICAgICovCisgICAgZmluYWwgY2hhcltdIGdldFZhbHVlKCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBSZXR1cm5zIHRoZSB1bmRlcmx5aW5nIGJ1ZmZlciBhbmQgc2V0cyB0aGUgc2hhcmVkIGZsYWcuCisgICAgICovCisgICAgZmluYWwgY2hhcltdIHNoYXJlVmFsdWUoKSB7CisgICAgICAgIHNoYXJlZCA9IHRydWU7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFJlc3RvcmVzIGludGVybmFsIHN0YXRlIGFmdGVyIGRlc2VyaWFsaXphdGlvbi4KKyAgICAgKi8KKyAgICBmaW5hbCB2b2lkIHNldChjaGFyW10gdmFsLCBpbnQgbGVuKSB0aHJvd3MgSW52YWxpZE9iamVjdEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICh2YWwgPT0gbnVsbCkgeworICAgICAgICAgICAgdmFsID0gRW1wdHlBcnJheS5DSEFSOworICAgICAgICB9CisgICAgICAgIGlmICh2YWwubGVuZ3RoIDwgbGVuKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9iamVjdEV4Y2VwdGlvbigiY291bnQgb3V0IG9mIHJhbmdlIik7CisgICAgICAgIH0KKworICAgICAgICBzaGFyZWQgPSBmYWxzZTsKKyAgICAgICAgdmFsdWUgPSB2YWw7CisgICAgICAgIGNvdW50ID0gbGVuOworICAgIH0KKworICAgIEFic3RyYWN0U3RyaW5nQnVpbGRlcigpIHsKKyAgICAgICAgdmFsdWUgPSBuZXcgY2hhcltJTklUSUFMX0NBUEFDSVRZXTsKKyAgICB9CisKKyAgICBBYnN0cmFjdFN0cmluZ0J1aWxkZXIoaW50IGNhcGFjaXR5KSB7CisgICAgICAgIGlmIChjYXBhY2l0eSA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHZhbHVlID0gbmV3IGNoYXJbY2FwYWNpdHldOworICAgIH0KKworICAgIEFic3RyYWN0U3RyaW5nQnVpbGRlcihTdHJpbmcgc3RyaW5nKSB7CisgICAgICAgIGNvdW50ID0gc3RyaW5nLmxlbmd0aCgpOworICAgICAgICBzaGFyZWQgPSBmYWxzZTsKKyAgICAgICAgdmFsdWUgPSBuZXcgY2hhcltjb3VudCArIElOSVRJQUxfQ0FQQUNJVFldOworICAgICAgICBzdHJpbmcuX2dldENoYXJzKDAsIGNvdW50LCB2YWx1ZSwgMCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGVubGFyZ2VCdWZmZXIoaW50IG1pbikgeworICAgICAgICBpbnQgbmV3Q291bnQgPSAoKHZhbHVlLmxlbmd0aCA+PiAxKSArIHZhbHVlLmxlbmd0aCkgKyAyOworICAgICAgICBjaGFyW10gbmV3RGF0YSA9IG5ldyBjaGFyW21pbiA+IG5ld0NvdW50ID8gbWluIDogbmV3Q291bnRdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHZhbHVlLCAwLCBuZXdEYXRhLCAwLCBjb3VudCk7CisgICAgICAgIHZhbHVlID0gbmV3RGF0YTsKKyAgICAgICAgc2hhcmVkID0gZmFsc2U7CisgICAgfQorCisgICAgZmluYWwgdm9pZCBhcHBlbmROdWxsKCkgeworICAgICAgICBpbnQgbmV3Q291bnQgPSBjb3VudCArIDQ7CisgICAgICAgIGlmIChuZXdDb3VudCA+IHZhbHVlLmxlbmd0aCkgeworICAgICAgICAgICAgZW5sYXJnZUJ1ZmZlcihuZXdDb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgdmFsdWVbY291bnQrK10gPSAnbic7CisgICAgICAgIHZhbHVlW2NvdW50KytdID0gJ3UnOworICAgICAgICB2YWx1ZVtjb3VudCsrXSA9ICdsJzsKKyAgICAgICAgdmFsdWVbY291bnQrK10gPSAnbCc7CisgICAgfQorCisgICAgZmluYWwgdm9pZCBhcHBlbmQwKGNoYXJbXSBjaGFycykgeworICAgICAgICBpbnQgbmV3Q291bnQgPSBjb3VudCArIGNoYXJzLmxlbmd0aDsKKyAgICAgICAgaWYgKG5ld0NvdW50ID4gdmFsdWUubGVuZ3RoKSB7CisgICAgICAgICAgICBlbmxhcmdlQnVmZmVyKG5ld0NvdW50KTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNoYXJzLCAwLCB2YWx1ZSwgY291bnQsIGNoYXJzLmxlbmd0aCk7CisgICAgICAgIGNvdW50ID0gbmV3Q291bnQ7CisgICAgfQorCisgICAgZmluYWwgdm9pZCBhcHBlbmQwKGNoYXJbXSBjaGFycywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChjaGFycy5sZW5ndGgsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgaW50IG5ld0NvdW50ID0gY291bnQgKyBsZW5ndGg7CisgICAgICAgIGlmIChuZXdDb3VudCA+IHZhbHVlLmxlbmd0aCkgeworICAgICAgICAgICAgZW5sYXJnZUJ1ZmZlcihuZXdDb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShjaGFycywgb2Zmc2V0LCB2YWx1ZSwgY291bnQsIGxlbmd0aCk7CisgICAgICAgIGNvdW50ID0gbmV3Q291bnQ7CisgICAgfQorCisgICAgZmluYWwgdm9pZCBhcHBlbmQwKGNoYXIgY2gpIHsKKyAgICAgICAgaWYgKGNvdW50ID09IHZhbHVlLmxlbmd0aCkgeworICAgICAgICAgICAgZW5sYXJnZUJ1ZmZlcihjb3VudCArIDEpOworICAgICAgICB9CisgICAgICAgIHZhbHVlW2NvdW50KytdID0gY2g7CisgICAgfQorCisgICAgZmluYWwgdm9pZCBhcHBlbmQwKFN0cmluZyBzdHJpbmcpIHsKKyAgICAgICAgaWYgKHN0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBhcHBlbmROdWxsKCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaW50IGxlbmd0aCA9IHN0cmluZy5sZW5ndGgoKTsKKyAgICAgICAgaW50IG5ld0NvdW50ID0gY291bnQgKyBsZW5ndGg7CisgICAgICAgIGlmIChuZXdDb3VudCA+IHZhbHVlLmxlbmd0aCkgeworICAgICAgICAgICAgZW5sYXJnZUJ1ZmZlcihuZXdDb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgc3RyaW5nLl9nZXRDaGFycygwLCBsZW5ndGgsIHZhbHVlLCBjb3VudCk7CisgICAgICAgIGNvdW50ID0gbmV3Q291bnQ7CisgICAgfQorCisgICAgZmluYWwgdm9pZCBhcHBlbmQwKENoYXJTZXF1ZW5jZSBzLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgaWYgKHMgPT0gbnVsbCkgeworICAgICAgICAgICAgcyA9ICJudWxsIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoKHN0YXJ0IHwgZW5kKSA8IDAgfHwgc3RhcnQgPiBlbmQgfHwgZW5kID4gcy5sZW5ndGgoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBsZW5ndGggPSBlbmQgLSBzdGFydDsKKyAgICAgICAgaW50IG5ld0NvdW50ID0gY291bnQgKyBsZW5ndGg7CisgICAgICAgIGlmIChuZXdDb3VudCA+IHZhbHVlLmxlbmd0aCkgeworICAgICAgICAgICAgZW5sYXJnZUJ1ZmZlcihuZXdDb3VudCk7CisgICAgICAgIH0gZWxzZSBpZiAoc2hhcmVkKSB7CisgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmNsb25lKCk7CisgICAgICAgICAgICBzaGFyZWQgPSBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzIGluc3RhbmNlb2YgU3RyaW5nKSB7CisgICAgICAgICAgICAoKFN0cmluZykgcykuX2dldENoYXJzKHN0YXJ0LCBlbmQsIHZhbHVlLCBjb3VudCk7CisgICAgICAgIH0gZWxzZSBpZiAocyBpbnN0YW5jZW9mIEFic3RyYWN0U3RyaW5nQnVpbGRlcikgeworICAgICAgICAgICAgQWJzdHJhY3RTdHJpbmdCdWlsZGVyIG90aGVyID0gKEFic3RyYWN0U3RyaW5nQnVpbGRlcikgczsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob3RoZXIudmFsdWUsIHN0YXJ0LCB2YWx1ZSwgY291bnQsIGxlbmd0aCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpbnQgaiA9IGNvdW50OyAvLyBEZXN0aW5hdGlvbiBpbmRleC4KKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7CisgICAgICAgICAgICAgICAgdmFsdWVbaisrXSA9IHMuY2hhckF0KGkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5jb3VudCA9IG5ld0NvdW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRoYXQgY2FuIGJlIGhlbGQgd2l0aG91dCBncm93aW5nLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2FwYWNpdHkKKyAgICAgKiBAc2VlICNlbnN1cmVDYXBhY2l0eQorICAgICAqIEBzZWUgI2xlbmd0aAorICAgICAqLworICAgIHB1YmxpYyBpbnQgY2FwYWNpdHkoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZS5sZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIHtAY29kZSBpbmRleH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgY2hhcmFjdGVyIHRvIHJldHJpZXZlLgorICAgICAqIEByZXR1cm4gdGhlIGNoYXIgdmFsdWUuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4fSBpcyBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlCisgICAgICogICAgICAgICAgICAgY3VycmVudCB7QGxpbmsgI2xlbmd0aCgpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhciBjaGFyQXQoaW50IGluZGV4KSB7CisgICAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gY291bnQpIHsKKyAgICAgICAgICAgIHRocm93IGluZGV4QW5kTGVuZ3RoKGluZGV4KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdmFsdWVbaW5kZXhdOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpbmRleEFuZExlbmd0aChpbnQgaW5kZXgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oY291bnQsIGluZGV4KTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc3RhcnRFbmRBbmRMZW5ndGgoaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKGNvdW50LCBzdGFydCwgZW5kIC0gc3RhcnQpOworICAgIH0KKworICAgIGZpbmFsIHZvaWQgZGVsZXRlMChpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgaWYgKHN0YXJ0ID49IDApIHsKKyAgICAgICAgICAgIGlmIChlbmQgPiBjb3VudCkgeworICAgICAgICAgICAgICAgIGVuZCA9IGNvdW50OworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGVuZCA9PSBzdGFydCkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChlbmQgPiBzdGFydCkgeworICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBjb3VudCAtIGVuZDsKKyAgICAgICAgICAgICAgICBpZiAobGVuZ3RoID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFzaGFyZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsdWUsIGVuZCwgdmFsdWUsIHN0YXJ0LCBsZW5ndGgpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgY2hhcltdIG5ld0RhdGEgPSBuZXcgY2hhclt2YWx1ZS5sZW5ndGhdOworICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh2YWx1ZSwgMCwgbmV3RGF0YSwgMCwgc3RhcnQpOworICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh2YWx1ZSwgZW5kLCBuZXdEYXRhLCBzdGFydCwgbGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gbmV3RGF0YTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNoYXJlZCA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvdW50IC09IGVuZCAtIHN0YXJ0OworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0aHJvdyBzdGFydEVuZEFuZExlbmd0aChzdGFydCwgZW5kKTsKKyAgICB9CisKKyAgICBmaW5hbCB2b2lkIGRlbGV0ZUNoYXJBdDAoaW50IGluZGV4KSB7CisgICAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gY291bnQpIHsKKyAgICAgICAgICAgIHRocm93IGluZGV4QW5kTGVuZ3RoKGluZGV4KTsKKyAgICAgICAgfQorICAgICAgICBpbnQgbGVuZ3RoID0gY291bnQgLSBpbmRleCAtIDE7CisgICAgICAgIGlmIChsZW5ndGggPiAwKSB7CisgICAgICAgICAgICBpZiAoIXNoYXJlZCkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsdWUsIGluZGV4ICsgMSwgdmFsdWUsIGluZGV4LCBsZW5ndGgpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBjaGFyW10gbmV3RGF0YSA9IG5ldyBjaGFyW3ZhbHVlLmxlbmd0aF07CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh2YWx1ZSwgMCwgbmV3RGF0YSwgMCwgaW5kZXgpOworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsdWUsIGluZGV4ICsgMSwgbmV3RGF0YSwgaW5kZXgsIGxlbmd0aCk7CisgICAgICAgICAgICAgICAgdmFsdWUgPSBuZXdEYXRhOworICAgICAgICAgICAgICAgIHNoYXJlZCA9IGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGNvdW50LS07CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5zdXJlcyB0aGF0IHRoaXMgb2JqZWN0IGhhcyBhIG1pbmltdW0gY2FwYWNpdHkgYXZhaWxhYmxlIGJlZm9yZQorICAgICAqIHJlcXVpcmluZyB0aGUgaW50ZXJuYWwgYnVmZmVyIHRvIGJlIGVubGFyZ2VkLiBUaGUgZ2VuZXJhbCBwb2xpY3kgb2YgdGhpcworICAgICAqIG1ldGhvZCBpcyB0aGF0IGlmIHRoZSB7QGNvZGUgbWluaW11bUNhcGFjaXR5fSBpcyBsYXJnZXIgdGhhbiB0aGUgY3VycmVudAorICAgICAqIHtAbGluayAjY2FwYWNpdHkoKX0sIHRoZW4gdGhlIGNhcGFjaXR5IHdpbGwgYmUgaW5jcmVhc2VkIHRvIHRoZSBsYXJnZXN0CisgICAgICogdmFsdWUgb2YgZWl0aGVyIHRoZSB7QGNvZGUgbWluaW11bUNhcGFjaXR5fSBvciB0aGUgY3VycmVudCBjYXBhY2l0eQorICAgICAqIG11bHRpcGxpZWQgYnkgdHdvIHBsdXMgdHdvLiBBbHRob3VnaCB0aGlzIGlzIHRoZSBnZW5lcmFsIHBvbGljeSwgdGhlcmUgaXMKKyAgICAgKiBubyBndWFyYW50ZWUgdGhhdCB0aGUgY2FwYWNpdHkgd2lsbCBjaGFuZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWluCisgICAgICogICAgICAgICAgICB0aGUgbmV3IG1pbmltdW0gY2FwYWNpdHkgdG8gc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVuc3VyZUNhcGFjaXR5KGludCBtaW4pIHsKKyAgICAgICAgaWYgKG1pbiA+IHZhbHVlLmxlbmd0aCkgeworICAgICAgICAgICAgaW50IG91ck1pbiA9IHZhbHVlLmxlbmd0aCoyICsgMjsKKyAgICAgICAgICAgIGVubGFyZ2VCdWZmZXIoTWF0aC5tYXgob3VyTWluLCBtaW4pKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyB0aGUgcmVxdWVzdGVkIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgaW50byB7QGNvZGUgZHN0fSBwYXNzZWQKKyAgICAgKiBzdGFydGluZyBhdCB7QGNvZGUgZHN0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIGluY2x1c2l2ZSBzdGFydCBpbmRleCBvZiB0aGUgY2hhcmFjdGVycyB0byBjb3B5LgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNsdXNpdmUgZW5kIGluZGV4IG9mIHRoZSBjaGFyYWN0ZXJzIHRvIGNvcHkuCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBjaGFyW119IHRvIGNvcHkgdGhlIGNoYXJhY3RlcnMgdG8uCisgICAgICogQHBhcmFtIGRzdFN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgaW5jbHVzaXZlIHN0YXJ0IGluZGV4IG9mIHtAY29kZSBkc3R9IHRvIGJlZ2luIGNvcHlpbmcgdG8uCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBzdGFydH0gaXMgbmVnYXRpdmUsIHRoZSB7QGNvZGUgZHN0U3RhcnR9IGlzCisgICAgICogICAgICAgICAgICAgbmVnYXRpdmUsIHRoZSB7QGNvZGUgc3RhcnR9IGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgZW5kfSwgdGhlCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGVuZH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50IHtAbGluayAjbGVuZ3RoKCl9IG9yCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGRzdFN0YXJ0ICsgZW5kIC0gYmVnaW59IGlzIGdyZWF0ZXIgdGhhbgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBkc3QubGVuZ3RofS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBnZXRDaGFycyhpbnQgc3RhcnQsIGludCBlbmQsIGNoYXJbXSBkc3QsIGludCBkc3RTdGFydCkgeworICAgICAgICBpZiAoc3RhcnQgPiBjb3VudCB8fCBlbmQgPiBjb3VudCB8fCBzdGFydCA+IGVuZCkgeworICAgICAgICAgICAgdGhyb3cgc3RhcnRFbmRBbmRMZW5ndGgoc3RhcnQsIGVuZCk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weSh2YWx1ZSwgc3RhcnQsIGRzdCwgZHN0U3RhcnQsIGVuZCAtIHN0YXJ0KTsKKyAgICB9CisKKyAgICBmaW5hbCB2b2lkIGluc2VydDAoaW50IGluZGV4LCBjaGFyW10gY2hhcnMpIHsKKyAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+IGNvdW50KSB7CisgICAgICAgICAgICB0aHJvdyBpbmRleEFuZExlbmd0aChpbmRleCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNoYXJzLmxlbmd0aCAhPSAwKSB7CisgICAgICAgICAgICBtb3ZlKGNoYXJzLmxlbmd0aCwgaW5kZXgpOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShjaGFycywgMCwgdmFsdWUsIGluZGV4LCBjaGFycy5sZW5ndGgpOworICAgICAgICAgICAgY291bnQgKz0gY2hhcnMubGVuZ3RoOworICAgICAgICB9CisgICAgfQorCisgICAgZmluYWwgdm9pZCBpbnNlcnQwKGludCBpbmRleCwgY2hhcltdIGNoYXJzLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHsKKyAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPD0gY291bnQpIHsKKyAgICAgICAgICAgIC8vIHN0YXJ0ICsgbGVuZ3RoIGNvdWxkIG92ZXJmbG93LCBzdGFydC9sZW5ndGggbWF5YmUgTWF4SW50CisgICAgICAgICAgICBpZiAoc3RhcnQgPj0gMCAmJiBsZW5ndGggPj0gMCAmJiBsZW5ndGggPD0gY2hhcnMubGVuZ3RoIC0gc3RhcnQpIHsKKyAgICAgICAgICAgICAgICBpZiAobGVuZ3RoICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgbW92ZShsZW5ndGgsIGluZGV4KTsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShjaGFycywgc3RhcnQsIHZhbHVlLCBpbmRleCwgbGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gbGVuZ3RoOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oInRoaXMubGVuZ3RoPSIgKyBjb3VudAorICAgICAgICAgICAgICAgICsgIjsgaW5kZXg9IiArIGluZGV4ICsgIjsgY2hhcnMubGVuZ3RoPSIgKyBjaGFycy5sZW5ndGgKKyAgICAgICAgICAgICAgICArICI7IHN0YXJ0PSIgKyBzdGFydCArICI7IGxlbmd0aD0iICsgbGVuZ3RoKTsKKyAgICB9CisKKyAgICBmaW5hbCB2b2lkIGluc2VydDAoaW50IGluZGV4LCBjaGFyIGNoKSB7CisgICAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPiBjb3VudCkgeworICAgICAgICAgICAgLy8gUkkgY29tcGF0aWJsZSBleGNlcHRpb24gdHlwZQorICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihjb3VudCwgaW5kZXgpOworICAgICAgICB9CisgICAgICAgIG1vdmUoMSwgaW5kZXgpOworICAgICAgICB2YWx1ZVtpbmRleF0gPSBjaDsKKyAgICAgICAgY291bnQrKzsKKyAgICB9CisKKyAgICBmaW5hbCB2b2lkIGluc2VydDAoaW50IGluZGV4LCBTdHJpbmcgc3RyaW5nKSB7CisgICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDw9IGNvdW50KSB7CisgICAgICAgICAgICBpZiAoc3RyaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzdHJpbmcgPSAibnVsbCI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgbWluID0gc3RyaW5nLmxlbmd0aCgpOworICAgICAgICAgICAgaWYgKG1pbiAhPSAwKSB7CisgICAgICAgICAgICAgICAgbW92ZShtaW4sIGluZGV4KTsKKyAgICAgICAgICAgICAgICBzdHJpbmcuX2dldENoYXJzKDAsIG1pbiwgdmFsdWUsIGluZGV4KTsKKyAgICAgICAgICAgICAgICBjb3VudCArPSBtaW47CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBpbmRleEFuZExlbmd0aChpbmRleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBmaW5hbCB2b2lkIGluc2VydDAoaW50IGluZGV4LCBDaGFyU2VxdWVuY2UgcywgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIGlmIChzID09IG51bGwpIHsKKyAgICAgICAgICAgIHMgPSAibnVsbCI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChpbmRleCB8IHN0YXJ0IHwgZW5kKSA8IDAgfHwgaW5kZXggPiBjb3VudCB8fCBzdGFydCA+IGVuZCB8fCBlbmQgPiBzLmxlbmd0aCgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGluc2VydDAoaW5kZXgsIHMuc3ViU2VxdWVuY2Uoc3RhcnQsIGVuZCkudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGN1cnJlbnQgbGVuZ3RoLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgY29udGFpbmVkIGluIHRoaXMgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIGludCBsZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBjb3VudDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgbW92ZShpbnQgc2l6ZSwgaW50IGluZGV4KSB7CisgICAgICAgIGludCBuZXdDb3VudDsKKyAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCAtIGNvdW50ID49IHNpemUpIHsKKyAgICAgICAgICAgIGlmICghc2hhcmVkKSB7CisgICAgICAgICAgICAgICAgLy8gaW5kZXggPT0gY291bnQgY2FzZSBpcyBuby1vcAorICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsdWUsIGluZGV4LCB2YWx1ZSwgaW5kZXggKyBzaXplLCBjb3VudCAtIGluZGV4KTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICBuZXdDb3VudCA9IHZhbHVlLmxlbmd0aDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG5ld0NvdW50ID0gTWF0aC5tYXgoY291bnQgKyBzaXplLCB2YWx1ZS5sZW5ndGgqMiArIDIpOworICAgICAgICB9CisKKyAgICAgICAgY2hhcltdIG5ld0RhdGEgPSBuZXcgY2hhcltuZXdDb3VudF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsdWUsIDAsIG5ld0RhdGEsIDAsIGluZGV4KTsKKyAgICAgICAgLy8gaW5kZXggPT0gY291bnQgY2FzZSBpcyBuby1vcAorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHZhbHVlLCBpbmRleCwgbmV3RGF0YSwgaW5kZXggKyBzaXplLCBjb3VudCAtIGluZGV4KTsKKyAgICAgICAgdmFsdWUgPSBuZXdEYXRhOworICAgICAgICBzaGFyZWQgPSBmYWxzZTsKKyAgICB9CisKKyAgICBmaW5hbCB2b2lkIHJlcGxhY2UwKGludCBzdGFydCwgaW50IGVuZCwgU3RyaW5nIHN0cmluZykgeworICAgICAgICBpZiAoc3RhcnQgPj0gMCkgeworICAgICAgICAgICAgaWYgKGVuZCA+IGNvdW50KSB7CisgICAgICAgICAgICAgICAgZW5kID0gY291bnQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZW5kID4gc3RhcnQpIHsKKyAgICAgICAgICAgICAgICBpbnQgc3RyaW5nTGVuZ3RoID0gc3RyaW5nLmxlbmd0aCgpOworICAgICAgICAgICAgICAgIGludCBkaWZmID0gZW5kIC0gc3RhcnQgLSBzdHJpbmdMZW5ndGg7CisgICAgICAgICAgICAgICAgaWYgKGRpZmYgPiAwKSB7IC8vIHJlcGxhY2luZyB3aXRoIGZld2VyIGNoYXJhY3RlcnMKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFzaGFyZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluZGV4ID09IGNvdW50IGNhc2UgaXMgbm8tb3AKKyAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsdWUsIGVuZCwgdmFsdWUsIHN0YXJ0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgc3RyaW5nTGVuZ3RoLCBjb3VudCAtIGVuZCk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjaGFyW10gbmV3RGF0YSA9IG5ldyBjaGFyW3ZhbHVlLmxlbmd0aF07CisgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHZhbHVlLCAwLCBuZXdEYXRhLCAwLCBzdGFydCk7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmRleCA9PSBjb3VudCBjYXNlIGlzIG5vLW9wCisgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHZhbHVlLCBlbmQsIG5ld0RhdGEsIHN0YXJ0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgc3RyaW5nTGVuZ3RoLCBjb3VudCAtIGVuZCk7CisgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IG5ld0RhdGE7CisgICAgICAgICAgICAgICAgICAgICAgICBzaGFyZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGlmZiA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gcmVwbGFjaW5nIHdpdGggbW9yZSBjaGFyYWN0ZXJzLi4ubmVlZCBzb21lIHJvb20KKyAgICAgICAgICAgICAgICAgICAgbW92ZSgtZGlmZiwgZW5kKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNoYXJlZCkgeworICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmNsb25lKCk7CisgICAgICAgICAgICAgICAgICAgIHNoYXJlZCA9IGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzdHJpbmcuX2dldENoYXJzKDAsIHN0cmluZ0xlbmd0aCwgdmFsdWUsIHN0YXJ0KTsKKyAgICAgICAgICAgICAgICBjb3VudCAtPSBkaWZmOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzdGFydCA9PSBlbmQpIHsKKyAgICAgICAgICAgICAgICBpZiAoc3RyaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGluc2VydDAoc3RhcnQsIHN0cmluZyk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRocm93IHN0YXJ0RW5kQW5kTGVuZ3RoKHN0YXJ0LCBlbmQpOworICAgIH0KKworICAgIGZpbmFsIHZvaWQgcmV2ZXJzZTAoKSB7CisgICAgICAgIGlmIChjb3VudCA8IDIpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXNoYXJlZCkgeworICAgICAgICAgICAgaW50IGVuZCA9IGNvdW50IC0gMTsKKyAgICAgICAgICAgIGNoYXIgZnJvbnRIaWdoID0gdmFsdWVbMF07CisgICAgICAgICAgICBjaGFyIGVuZExvdyA9IHZhbHVlW2VuZF07CisgICAgICAgICAgICBib29sZWFuIGFsbG93RnJvbnRTdXIgPSB0cnVlLCBhbGxvd0VuZFN1ciA9IHRydWU7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgbWlkID0gY291bnQgLyAyOyBpIDwgbWlkOyBpKyssIC0tZW5kKSB7CisgICAgICAgICAgICAgICAgY2hhciBmcm9udExvdyA9IHZhbHVlW2kgKyAxXTsKKyAgICAgICAgICAgICAgICBjaGFyIGVuZEhpZ2ggPSB2YWx1ZVtlbmQgLSAxXTsKKyAgICAgICAgICAgICAgICBib29sZWFuIHN1ckF0RnJvbnQgPSBhbGxvd0Zyb250U3VyICYmIGZyb250TG93ID49IDB4ZGMwMAorICAgICAgICAgICAgICAgICAgICAgICAgJiYgZnJvbnRMb3cgPD0gMHhkZmZmICYmIGZyb250SGlnaCA+PSAweGQ4MDAKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIGZyb250SGlnaCA8PSAweGRiZmY7CisgICAgICAgICAgICAgICAgaWYgKHN1ckF0RnJvbnQgJiYgKGNvdW50IDwgMykpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBib29sZWFuIHN1ckF0RW5kID0gYWxsb3dFbmRTdXIgJiYgZW5kSGlnaCA+PSAweGQ4MDAKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIGVuZEhpZ2ggPD0gMHhkYmZmICYmIGVuZExvdyA+PSAweGRjMDAKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIGVuZExvdyA8PSAweGRmZmY7CisgICAgICAgICAgICAgICAgYWxsb3dGcm9udFN1ciA9IGFsbG93RW5kU3VyID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBpZiAoc3VyQXRGcm9udCA9PSBzdXJBdEVuZCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoc3VyQXRGcm9udCkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gYm90aCBzdXJyb2dhdGVzCisgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZVtlbmRdID0gZnJvbnRMb3c7CisgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZVtlbmQgLSAxXSA9IGZyb250SGlnaDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlW2ldID0gZW5kSGlnaDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlW2kgKyAxXSA9IGVuZExvdzsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZyb250SGlnaCA9IHZhbHVlW2kgKyAyXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGVuZExvdyA9IHZhbHVlW2VuZCAtIDJdOworICAgICAgICAgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgICAgICAgICAgICAgZW5kLS07CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBuZWl0aGVyIHN1cnJvZ2F0ZXMKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlW2VuZF0gPSBmcm9udEhpZ2g7CisgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZVtpXSA9IGVuZExvdzsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZyb250SGlnaCA9IGZyb250TG93OworICAgICAgICAgICAgICAgICAgICAgICAgZW5kTG93ID0gZW5kSGlnaDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChzdXJBdEZyb250KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBzdXJyb2dhdGUgb25seSBhdCB0aGUgZnJvbnQKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlW2VuZF0gPSBmcm9udExvdzsKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlW2ldID0gZW5kTG93OworICAgICAgICAgICAgICAgICAgICAgICAgZW5kTG93ID0gZW5kSGlnaDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93RnJvbnRTdXIgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN1cnJvZ2F0ZSBvbmx5IGF0IHRoZSBlbmQKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlW2VuZF0gPSBmcm9udEhpZ2g7CisgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZVtpXSA9IGVuZEhpZ2g7CisgICAgICAgICAgICAgICAgICAgICAgICBmcm9udEhpZ2ggPSBmcm9udExvdzsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93RW5kU3VyID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoKGNvdW50ICYgMSkgPT0gMSAmJiAoIWFsbG93RnJvbnRTdXIgfHwgIWFsbG93RW5kU3VyKSkgeworICAgICAgICAgICAgICAgIHZhbHVlW2VuZF0gPSBhbGxvd0Zyb250U3VyID8gZW5kTG93IDogZnJvbnRIaWdoOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY2hhcltdIG5ld0RhdGEgPSBuZXcgY2hhclt2YWx1ZS5sZW5ndGhdOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAsIGVuZCA9IGNvdW50OyBpIDwgY291bnQ7IGkrKykgeworICAgICAgICAgICAgICAgIGNoYXIgaGlnaCA9IHZhbHVlW2ldOworICAgICAgICAgICAgICAgIGlmICgoaSArIDEpIDwgY291bnQgJiYgaGlnaCA+PSAweGQ4MDAgJiYgaGlnaCA8PSAweGRiZmYpIHsKKyAgICAgICAgICAgICAgICAgICAgY2hhciBsb3cgPSB2YWx1ZVtpICsgMV07CisgICAgICAgICAgICAgICAgICAgIGlmIChsb3cgPj0gMHhkYzAwICYmIGxvdyA8PSAweGRmZmYpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ld0RhdGFbLS1lbmRdID0gbG93OworICAgICAgICAgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG5ld0RhdGFbLS1lbmRdID0gaGlnaDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHZhbHVlID0gbmV3RGF0YTsKKyAgICAgICAgICAgIHNoYXJlZCA9IGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY2hhcmFjdGVyIGF0IHRoZSB7QGNvZGUgaW5kZXh9LgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgemVyby1iYXNlZCBpbmRleCBvZiB0aGUgY2hhcmFjdGVyIHRvIHJlcGxhY2UuCisgICAgICogQHBhcmFtIGNoCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIHNldC4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW5kZXh9IGlzIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUKKyAgICAgKiAgICAgICAgICAgICBjdXJyZW50IHtAbGluayAjbGVuZ3RoKCl9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENoYXJBdChpbnQgaW5kZXgsIGNoYXIgY2gpIHsKKyAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBjb3VudCkgeworICAgICAgICAgICAgdGhyb3cgaW5kZXhBbmRMZW5ndGgoaW5kZXgpOworICAgICAgICB9CisgICAgICAgIGlmIChzaGFyZWQpIHsKKyAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuY2xvbmUoKTsKKyAgICAgICAgICAgIHNoYXJlZCA9IGZhbHNlOworICAgICAgICB9CisgICAgICAgIHZhbHVlW2luZGV4XSA9IGNoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGN1cnJlbnQgbGVuZ3RoIHRvIGEgbmV3IHZhbHVlLiBJZiB0aGUgbmV3IGxlbmd0aCBpcyBsYXJnZXIgdGhhbgorICAgICAqIHRoZSBjdXJyZW50IGxlbmd0aCwgdGhlbiB0aGUgbmV3IGNoYXJhY3RlcnMgYXQgdGhlIGVuZCBvZiB0aGlzIG9iamVjdAorICAgICAqIHdpbGwgY29udGFpbiB0aGUge0Bjb2RlIGNoYXJ9IHZhbHVlIG9mIHtAY29kZSBcdTAwMDB9LgorICAgICAqCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBsZW5ndGggb2YgdGhpcyBTdHJpbmdCdWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGxlbmd0aCA8IDB9LgorICAgICAqIEBzZWUgI2xlbmd0aAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExlbmd0aChpbnQgbGVuZ3RoKSB7CisgICAgICAgIGlmIChsZW5ndGggPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigibGVuZ3RoIDwgMDogIiArIGxlbmd0aCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxlbmd0aCA+IHZhbHVlLmxlbmd0aCkgeworICAgICAgICAgICAgZW5sYXJnZUJ1ZmZlcihsZW5ndGgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKHNoYXJlZCkgeworICAgICAgICAgICAgICAgIGNoYXJbXSBuZXdEYXRhID0gbmV3IGNoYXJbdmFsdWUubGVuZ3RoXTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHZhbHVlLCAwLCBuZXdEYXRhLCAwLCBjb3VudCk7CisgICAgICAgICAgICAgICAgdmFsdWUgPSBuZXdEYXRhOworICAgICAgICAgICAgICAgIHNoYXJlZCA9IGZhbHNlOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAoY291bnQgPCBsZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmZpbGwodmFsdWUsIGNvdW50LCBsZW5ndGgsIChjaGFyKSAwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY291bnQgPSBsZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgU3RyaW5nIHZhbHVlIG9mIHRoZSBzdWJzZXF1ZW5jZSBmcm9tIHRoZSB7QGNvZGUgc3RhcnR9IGluZGV4CisgICAgICogdG8gdGhlIGN1cnJlbnQgZW5kLgorICAgICAqCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgaW5jbHVzaXZlIHN0YXJ0IGluZGV4IHRvIGJlZ2luIHRoZSBzdWJzZXF1ZW5jZS4KKyAgICAgKiBAcmV0dXJuIGEgU3RyaW5nIGNvbnRhaW5pbmcgdGhlIHN1YnNlcXVlbmNlLgorICAgICAqIEB0aHJvd3MgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydH0gaXMgbmVnYXRpdmUgb3IgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50CisgICAgICogICAgICAgICAgICAge0BsaW5rICNsZW5ndGgoKX0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBzdWJzdHJpbmcoaW50IHN0YXJ0KSB7CisgICAgICAgIGlmIChzdGFydCA+PSAwICYmIHN0YXJ0IDw9IGNvdW50KSB7CisgICAgICAgICAgICBpZiAoc3RhcnQgPT0gY291bnQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gIiI7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIFJlbW92ZSBTdHJpbmcgc2hhcmluZyBmb3IgbW9yZSBwZXJmb3JtYW5jZQorICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcodmFsdWUsIHN0YXJ0LCBjb3VudCAtIHN0YXJ0KTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBpbmRleEFuZExlbmd0aChzdGFydCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgU3RyaW5nIHZhbHVlIG9mIHRoZSBzdWJzZXF1ZW5jZSBmcm9tIHRoZSB7QGNvZGUgc3RhcnR9IGluZGV4CisgICAgICogdG8gdGhlIHtAY29kZSBlbmR9IGluZGV4LgorICAgICAqCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgaW5jbHVzaXZlIHN0YXJ0IGluZGV4IHRvIGJlZ2luIHRoZSBzdWJzZXF1ZW5jZS4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgZXhjbHVzaXZlIGVuZCBpbmRleCB0byBlbmQgdGhlIHN1YnNlcXVlbmNlLgorICAgICAqIEByZXR1cm4gYSBTdHJpbmcgY29udGFpbmluZyB0aGUgc3Vic2VxdWVuY2UuCisgICAgICogQHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0fSBpcyBuZWdhdGl2ZSwgZ3JlYXRlciB0aGFuIHtAY29kZSBlbmR9IG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGVuZH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50IHtAbGluayAjbGVuZ3RoKCl9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgc3Vic3RyaW5nKGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBpZiAoc3RhcnQgPj0gMCAmJiBzdGFydCA8PSBlbmQgJiYgZW5kIDw9IGNvdW50KSB7CisgICAgICAgICAgICBpZiAoc3RhcnQgPT0gZW5kKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuICIiOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBSZW1vdmUgU3RyaW5nIHNoYXJpbmcgZm9yIG1vcmUgcGVyZm9ybWFuY2UKKyAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKHZhbHVlLCBzdGFydCwgZW5kIC0gc3RhcnQpOworICAgICAgICB9CisgICAgICAgIHRocm93IHN0YXJ0RW5kQW5kTGVuZ3RoKHN0YXJ0LCBlbmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgU3RyaW5nIHJlcHJlc2VudGF0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBhIFN0cmluZyBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXJzIGluIHRoaXMgaW5zdGFuY2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgaWYgKGNvdW50ID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorICAgICAgICAvLyBPcHRpbWl6ZSBTdHJpbmcgc2hhcmluZyBmb3IgbW9yZSBwZXJmb3JtYW5jZQorICAgICAgICBpbnQgd2FzdGVkID0gdmFsdWUubGVuZ3RoIC0gY291bnQ7CisgICAgICAgIGlmICh3YXN0ZWQgPj0gMjU2CisgICAgICAgICAgICAgICAgfHwgKHdhc3RlZCA+PSBJTklUSUFMX0NBUEFDSVRZICYmIHdhc3RlZCA+PSAoY291bnQgPj4gMSkpKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZyh2YWx1ZSwgMCwgY291bnQpOworICAgICAgICB9CisgICAgICAgIHNoYXJlZCA9IHRydWU7CisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKDAsIGNvdW50LCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBDaGFyU2VxdWVuY2V9IG9mIHRoZSBzdWJzZXF1ZW5jZSBmcm9tIHRoZSB7QGNvZGUgc3RhcnR9CisgICAgICogaW5kZXggdG8gdGhlIHtAY29kZSBlbmR9IGluZGV4LgorICAgICAqCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgaW5jbHVzaXZlIHN0YXJ0IGluZGV4IHRvIGJlZ2luIHRoZSBzdWJzZXF1ZW5jZS4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgZXhjbHVzaXZlIGVuZCBpbmRleCB0byBlbmQgdGhlIHN1YnNlcXVlbmNlLgorICAgICAqIEByZXR1cm4gYSBDaGFyU2VxdWVuY2UgY29udGFpbmluZyB0aGUgc3Vic2VxdWVuY2UuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0fSBpcyBuZWdhdGl2ZSwgZ3JlYXRlciB0aGFuIHtAY29kZSBlbmR9IG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGVuZH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50IHtAbGluayAjbGVuZ3RoKCl9LgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgQ2hhclNlcXVlbmNlIHN1YlNlcXVlbmNlKGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICByZXR1cm4gc3Vic3RyaW5nKHN0YXJ0LCBlbmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlYXJjaGVzIGZvciB0aGUgZmlyc3QgaW5kZXggb2YgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIuIFRoZSBzZWFyY2ggZm9yCisgICAgICogdGhlIGNoYXJhY3RlciBzdGFydHMgYXQgdGhlIGJlZ2lubmluZyBhbmQgbW92ZXMgdG93YXJkcyB0aGUgZW5kLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBmaW5kLgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyLCAtMSBpZiB0aGUgY2hhcmFjdGVyIGlzbid0CisgICAgICogICAgICAgICBmb3VuZC4KKyAgICAgKiBAc2VlICNsYXN0SW5kZXhPZihTdHJpbmcpCisgICAgICogQHNpbmNlIDEuNAorICAgICAqLworICAgIHB1YmxpYyBpbnQgaW5kZXhPZihTdHJpbmcgc3RyaW5nKSB7CisgICAgICAgIHJldHVybiBpbmRleE9mKHN0cmluZywgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VhcmNoZXMgZm9yIHRoZSBpbmRleCBvZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3Rlci4gVGhlIHNlYXJjaCBmb3IgdGhlCisgICAgICogY2hhcmFjdGVyIHN0YXJ0cyBhdCB0aGUgc3BlY2lmaWVkIG9mZnNldCBhbmQgbW92ZXMgdG93YXJkcyB0aGUgZW5kLgorICAgICAqCisgICAgICogQHBhcmFtIHN1YlN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBmaW5kLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIG9mZnNldC4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciwgLTEgaWYgdGhlIGNoYXJhY3RlciBpc24ndAorICAgICAqICAgICAgICAgZm91bmQKKyAgICAgKiBAc2VlICNsYXN0SW5kZXhPZihTdHJpbmcsaW50KQorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGluZGV4T2YoU3RyaW5nIHN1YlN0cmluZywgaW50IHN0YXJ0KSB7CisgICAgICAgIGlmIChzdGFydCA8IDApIHsKKyAgICAgICAgICAgIHN0YXJ0ID0gMDsKKyAgICAgICAgfQorICAgICAgICBpbnQgc3ViQ291bnQgPSBzdWJTdHJpbmcubGVuZ3RoKCk7CisgICAgICAgIGlmIChzdWJDb3VudCA+IDApIHsKKyAgICAgICAgICAgIGlmIChzdWJDb3VudCArIHN0YXJ0ID4gY291bnQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBUT0RPIG9wdGltaXplIGNoYXJBdCB0byBkaXJlY3QgYXJyYXkgYWNjZXNzCisgICAgICAgICAgICBjaGFyIGZpcnN0Q2hhciA9IHN1YlN0cmluZy5jaGFyQXQoMCk7CisgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgIGludCBpID0gc3RhcnQ7CisgICAgICAgICAgICAgICAgYm9vbGVhbiBmb3VuZCA9IGZhbHNlOworICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgY291bnQ7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWVbaV0gPT0gZmlyc3RDaGFyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoIWZvdW5kIHx8IHN1YkNvdW50ICsgaSA+IGNvdW50KSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsgLy8gaGFuZGxlcyBzdWJDb3VudCA+IGNvdW50IHx8IHN0YXJ0ID49IGNvdW50CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGludCBvMSA9IGksIG8yID0gMDsKKyAgICAgICAgICAgICAgICB3aGlsZSAoKytvMiA8IHN1YkNvdW50ICYmIHZhbHVlWysrbzFdID09IHN1YlN0cmluZy5jaGFyQXQobzIpKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIEludGVudGlvbmFsbHkgZW1wdHkKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKG8yID09IHN1YkNvdW50KSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzdGFydCA9IGkgKyAxOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiAoc3RhcnQgPCBjb3VudCB8fCBzdGFydCA9PSAwKSA/IHN0YXJ0IDogY291bnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VhcmNoZXMgZm9yIHRoZSBsYXN0IGluZGV4IG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyLiBUaGUgc2VhcmNoIGZvcgorICAgICAqIHRoZSBjaGFyYWN0ZXIgc3RhcnRzIGF0IHRoZSBlbmQgYW5kIG1vdmVzIHRvd2FyZHMgdGhlIGJlZ2lubmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gZmluZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciwgLTEgaWYgdGhlIGNoYXJhY3RlciBpc24ndAorICAgICAqICAgICAgICAgZm91bmQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdHJpbmd9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAc2VlIFN0cmluZyNsYXN0SW5kZXhPZihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGxhc3RJbmRleE9mKFN0cmluZyBzdHJpbmcpIHsKKyAgICAgICAgcmV0dXJuIGxhc3RJbmRleE9mKHN0cmluZywgY291bnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlYXJjaGVzIGZvciB0aGUgaW5kZXggb2YgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIuIFRoZSBzZWFyY2ggZm9yIHRoZQorICAgICAqIGNoYXJhY3RlciBzdGFydHMgYXQgdGhlIHNwZWNpZmllZCBvZmZzZXQgYW5kIG1vdmVzIHRvd2FyZHMgdGhlIGJlZ2lubmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdWJTdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gZmluZC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydGluZyBvZmZzZXQuCisgICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIsIC0xIGlmIHRoZSBjaGFyYWN0ZXIgaXNuJ3QKKyAgICAgKiAgICAgICAgIGZvdW5kLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3ViU3RyaW5nfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHNlZSBTdHJpbmcjbGFzdEluZGV4T2YoU3RyaW5nLGludCkKKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIGludCBsYXN0SW5kZXhPZihTdHJpbmcgc3ViU3RyaW5nLCBpbnQgc3RhcnQpIHsKKyAgICAgICAgaW50IHN1YkNvdW50ID0gc3ViU3RyaW5nLmxlbmd0aCgpOworICAgICAgICBpZiAoc3ViQ291bnQgPD0gY291bnQgJiYgc3RhcnQgPj0gMCkgeworICAgICAgICAgICAgaWYgKHN1YkNvdW50ID4gMCkgeworICAgICAgICAgICAgICAgIGlmIChzdGFydCA+IGNvdW50IC0gc3ViQ291bnQpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhcnQgPSBjb3VudCAtIHN1YkNvdW50OyAvLyBjb3VudCBhbmQgc3ViQ291bnQgYXJlIGJvdGgKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gPj0gMQorICAgICAgICAgICAgICAgIC8vIFRPRE8gb3B0aW1pemUgY2hhckF0IHRvIGRpcmVjdCBhcnJheSBhY2Nlc3MKKyAgICAgICAgICAgICAgICBjaGFyIGZpcnN0Q2hhciA9IHN1YlN0cmluZy5jaGFyQXQoMCk7CisgICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGkgPSBzdGFydDsKKyAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBmb3VuZCA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA+PSAwOyAtLWkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZVtpXSA9PSBmaXJzdENoYXIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKCFmb3VuZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGludCBvMSA9IGksIG8yID0gMDsKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCsrbzIgPCBzdWJDb3VudAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHZhbHVlWysrbzFdID09IHN1YlN0cmluZy5jaGFyQXQobzIpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbnRlbnRpb25hbGx5IGVtcHR5CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKG8yID09IHN1YkNvdW50KSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBzdGFydCA9IGkgLSAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBzdGFydCA8IGNvdW50ID8gc3RhcnQgOiBjb3VudDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJpbXMgb2ZmIGFueSBleHRyYSBjYXBhY2l0eSBiZXlvbmQgdGhlIGN1cnJlbnQgbGVuZ3RoLiBOb3RlLCB0aGlzIG1ldGhvZAorICAgICAqIGlzIE5PVCBndWFyYW50ZWVkIHRvIGNoYW5nZSB0aGUgY2FwYWNpdHkgb2YgdGhpcyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHZvaWQgdHJpbVRvU2l6ZSgpIHsKKyAgICAgICAgaWYgKGNvdW50IDwgdmFsdWUubGVuZ3RoKSB7CisgICAgICAgICAgICBjaGFyW10gbmV3VmFsdWUgPSBuZXcgY2hhcltjb3VudF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHZhbHVlLCAwLCBuZXdWYWx1ZSwgMCwgY291bnQpOworICAgICAgICAgICAgdmFsdWUgPSBuZXdWYWx1ZTsKKyAgICAgICAgICAgIHNoYXJlZCA9IGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIHRoZSBVbmljb2RlIGNvZGUgcG9pbnQgdmFsdWUgYXQgdGhlIHtAY29kZSBpbmRleH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCB0byB0aGUge0Bjb2RlIGNoYXJ9IGNvZGUgdW5pdC4KKyAgICAgKiBAcmV0dXJuIHRoZSBVbmljb2RlIGNvZGUgcG9pbnQgdmFsdWUuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4fSBpcyBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8KKyAgICAgKiAgICAgICAgICAgICB7QGxpbmsgI2xlbmd0aCgpfS4KKyAgICAgKiBAc2VlIENoYXJhY3RlcgorICAgICAqIEBzZWUgQ2hhcmFjdGVyI2NvZGVQb2ludEF0KGNoYXJbXSwgaW50LCBpbnQpCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29kZVBvaW50QXQoaW50IGluZGV4KSB7CisgICAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gY291bnQpIHsKKyAgICAgICAgICAgIHRocm93IGluZGV4QW5kTGVuZ3RoKGluZGV4KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gQ2hhcmFjdGVyLmNvZGVQb2ludEF0KHZhbHVlLCBpbmRleCwgY291bnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyB0aGUgVW5pY29kZSBjb2RlIHBvaW50IHZhbHVlIHRoYXQgcHJlY2VkZXMgdGhlIHtAY29kZSBpbmRleH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCB0byB0aGUge0Bjb2RlIGNoYXJ9IGNvZGUgdW5pdCB3aXRoaW4gdGhpcyBvYmplY3QuCisgICAgICogQHJldHVybiB0aGUgVW5pY29kZSBjb2RlIHBvaW50IHZhbHVlLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBpbmRleH0gaXMgbGVzcyB0aGFuIDEgb3IgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgICAgICAge0BsaW5rICNsZW5ndGgoKX0uCisgICAgICogQHNlZSBDaGFyYWN0ZXIKKyAgICAgKiBAc2VlIENoYXJhY3RlciNjb2RlUG9pbnRCZWZvcmUoY2hhcltdLCBpbnQsIGludCkKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIGludCBjb2RlUG9pbnRCZWZvcmUoaW50IGluZGV4KSB7CisgICAgICAgIGlmIChpbmRleCA8IDEgfHwgaW5kZXggPiBjb3VudCkgeworICAgICAgICAgICAgdGhyb3cgaW5kZXhBbmRMZW5ndGgoaW5kZXgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBDaGFyYWN0ZXIuY29kZVBvaW50QmVmb3JlKHZhbHVlLCBpbmRleCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIFVuaWNvZGUgY29kZSBwb2ludHMgYmV0d2VlbiB7QGNvZGUgc3RhcnR9CisgICAgICogYW5kIHtAY29kZSBlbmR9LgorICAgICAqCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgaW5jbHVzaXZlIGJlZ2lubmluZyBpbmRleCBvZiB0aGUgc3Vic2VxdWVuY2UuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGV4Y2x1c2l2ZSBlbmQgaW5kZXggb2YgdGhlIHN1YnNlcXVlbmNlLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBVbmljb2RlIGNvZGUgcG9pbnRzIGluIHRoZSBzdWJzZXF1ZW5jZS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnR9IGlzIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBlbmR9IG9yIHtAY29kZSBlbmR9IGlzIGdyZWF0ZXIgdGhhbgorICAgICAqICAgICAgICAgICAgIHtAbGluayAjbGVuZ3RoKCl9LgorICAgICAqIEBzZWUgQ2hhcmFjdGVyCisgICAgICogQHNlZSBDaGFyYWN0ZXIjY29kZVBvaW50Q291bnQoY2hhcltdLCBpbnQsIGludCkKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIGludCBjb2RlUG9pbnRDb3VudChpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgaWYgKHN0YXJ0IDwgMCB8fCBlbmQgPiBjb3VudCB8fCBzdGFydCA+IGVuZCkgeworICAgICAgICAgICAgdGhyb3cgc3RhcnRFbmRBbmRMZW5ndGgoc3RhcnQsIGVuZCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIENoYXJhY3Rlci5jb2RlUG9pbnRDb3VudCh2YWx1ZSwgc3RhcnQsIGVuZCAtIHN0YXJ0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCB0aGF0IGlzIG9mZnNldCB7QGNvZGUgY29kZVBvaW50T2Zmc2V0fSBjb2RlIHBvaW50cyBmcm9tCisgICAgICoge0Bjb2RlIGluZGV4fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHRvIGNhbGN1bGF0ZSB0aGUgb2Zmc2V0IGZyb20uCisgICAgICogQHBhcmFtIGNvZGVQb2ludE9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBjb2RlIHBvaW50cyB0byBjb3VudC4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCB0aGF0IGlzIHtAY29kZSBjb2RlUG9pbnRPZmZzZXR9IGNvZGUgcG9pbnRzIGF3YXkgZnJvbQorICAgICAqICAgICAgICAgaW5kZXguCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4fSBpcyBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4KKyAgICAgKiAgICAgICAgICAgICB7QGxpbmsgI2xlbmd0aCgpfSBvciBpZiB0aGVyZSBhcmVuJ3QgZW5vdWdoIGNvZGUgcG9pbnRzCisgICAgICogICAgICAgICAgICAgYmVmb3JlIG9yIGFmdGVyIHtAY29kZSBpbmRleH0gdG8gbWF0Y2gKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgY29kZVBvaW50T2Zmc2V0fS4KKyAgICAgKiBAc2VlIENoYXJhY3RlcgorICAgICAqIEBzZWUgQ2hhcmFjdGVyI29mZnNldEJ5Q29kZVBvaW50cyhjaGFyW10sIGludCwgaW50LCBpbnQsIGludCkKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIGludCBvZmZzZXRCeUNvZGVQb2ludHMoaW50IGluZGV4LCBpbnQgY29kZVBvaW50T2Zmc2V0KSB7CisgICAgICAgIHJldHVybiBDaGFyYWN0ZXIub2Zmc2V0QnlDb2RlUG9pbnRzKHZhbHVlLCAwLCBjb3VudCwgaW5kZXgsCisgICAgICAgICAgICAgICAgY29kZVBvaW50T2Zmc2V0KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0FwcGVuZGFibGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQXBwZW5kYWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc4MGY4YzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0FwcGVuZGFibGUuamF2YQpAQCAtMCwwICsxLDg3IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogRGVjbGFyZXMgbWV0aG9kcyB0byBhcHBlbmQgY2hhcmFjdGVycyBvciBjaGFyYWN0ZXIgc2VxdWVuY2VzLiBBbnkgY2xhc3MgdGhhdAorICogaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSBjYW4gcmVjZWl2ZSBkYXRhIGZvcm1hdHRlZCBieSBhCisgKiB7QGxpbmsgamF2YS51dGlsLkZvcm1hdHRlcn0uIFRoZSBhcHBlbmRlZCBjaGFyYWN0ZXIgb3IgY2hhcmFjdGVyIHNlcXVlbmNlCisgKiBzaG91bGQgYmUgdmFsaWQgYWNjb3JkaW5nIHRvIHRoZSBydWxlcyBkZXNjcmliZWQgaW4KKyAqIHtAbGluayBDaGFyYWN0ZXIgVW5pY29kZSBDaGFyYWN0ZXIgUmVwcmVzZW50YXRpb259LgorICogPHA+CisgKiB7QGNvZGUgQXBwZW5kYWJsZX0gaXRzZWxmIGRvZXMgbm90IGd1YXJhbnRlZSB0aHJlYWQgc2FmZXR5LiBUaGlzCisgKiByZXNwb25zaWJpbGl0eSBpcyB1cCB0byB0aGUgaW1wbGVtZW50aW5nIGNsYXNzLgorICogPHA+CisgKiBJbXBsZW1lbnRpbmcgY2xhc3NlcyBjYW4gY2hvb3NlIGRpZmZlcmVudCBleGNlcHRpb24gaGFuZGxpbmcgbWVjaGFuaXNtLiBUaGV5CisgKiBjYW4gY2hvb3NlIHRvIHRocm93IGV4Y2VwdGlvbnMgb3RoZXIgdGhhbiB7QGNvZGUgSU9FeGNlcHRpb259IG9yIHRoZXkgZG8gbm90CisgKiB0aHJvdyBhbnkgZXhjZXB0aW9ucyBhdCBhbGwgYW5kIHVzZSBlcnJvciBjb2RlcyBpbnN0ZWFkLgorICovCitwdWJsaWMgaW50ZXJmYWNlIEFwcGVuZGFibGUgeworCisgICAgLyoqCisgICAgICogQXBwZW5kcyB0aGUgc3BlY2lmaWVkIGNoYXJhY3Rlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIGFwcGVuZC4KKyAgICAgKiBAcmV0dXJuIHRoaXMge0Bjb2RlIEFwcGVuZGFibGV9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEFwcGVuZGFibGUgYXBwZW5kKGNoYXIgYykgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQXBwZW5kcyB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHtAY29kZSBjc3F9LiBJbXBsZW1lbnRhdGlvbiBjbGFzc2VzIG1heQorICAgICAqIG5vdCBhcHBlbmQgdGhlIHdob2xlIHNlcXVlbmNlLCBmb3IgZXhhbXBsZSBpZiB0aGUgdGFyZ2V0IGlzIGEgYnVmZmVyIHdpdGgKKyAgICAgKiBsaW1pdGVkIHNpemUuCisgICAgICogPHA+CisgICAgICogSWYge0Bjb2RlIGNzcX0gaXMge0Bjb2RlIG51bGx9LCB0aGUgY2hhcmFjdGVycyAibnVsbCIgYXJlIGFwcGVuZGVkLgorICAgICAqCisgICAgICogQHBhcmFtIGNzcQorICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSB0byBhcHBlbmQuCisgICAgICogQHJldHVybiB0aGlzIHtAY29kZSBBcHBlbmRhYmxlfS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBBcHBlbmRhYmxlIGFwcGVuZChDaGFyU2VxdWVuY2UgY3NxKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIGEgc3Vic2VxdWVuY2Ugb2Yge0Bjb2RlIGNzcX0uCisgICAgICogPHA+CisgICAgICogSWYge0Bjb2RlIGNzcX0gaXMgbm90IHtAY29kZSBudWxsfSB0aGVuIGNhbGxpbmcgdGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudAorICAgICAqIHRvIGNhbGxpbmcge0Bjb2RlIGFwcGVuZChjc3Euc3ViU2VxdWVuY2Uoc3RhcnQsIGVuZCkpfS4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB7QGNvZGUgY3NxfSBpcyB7QGNvZGUgbnVsbH0sIHRoZSBjaGFyYWN0ZXJzICJudWxsIiBhcmUgYXBwZW5kZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY3NxCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHRvIGFwcGVuZC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBpbmRleCBvZiB0aGUgc3Vic2VxdWVuY2Ugb2Yge0Bjb2RlIGNzcX0gdGhhdCBpcworICAgICAqICAgICAgICAgICAgYXBwZW5kZWQuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGxhc3QgaW5kZXggb2YgdGhlIHN1YnNlcXVlbmNlIG9mIHtAY29kZSBjc3F9IHRoYXQgaXMKKyAgICAgKiAgICAgICAgICAgIGFwcGVuZGVkLgorICAgICAqIEByZXR1cm4gdGhpcyB7QGNvZGUgQXBwZW5kYWJsZX0uCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0IDwgMH0sIHtAY29kZSBlbmQgPCAwfSwge0Bjb2RlIHN0YXJ0ID4gZW5kfQorICAgICAqICAgICAgICAgICAgIG9yIHtAY29kZSBlbmR9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHtAY29kZSBjc3F9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEFwcGVuZGFibGUgYXBwZW5kKENoYXJTZXF1ZW5jZSBjc3EsIGludCBzdGFydCwgaW50IGVuZCkgdGhyb3dzIElPRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Bcml0aG1ldGljRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0FyaXRobWV0aWNFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOWM3NDhhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Bcml0aG1ldGljRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyb3duIHdoZW4gdGhlIGFuIGludmFsaWQgYXJpdGhtZXRpYyBvcGVyYXRpb24gaXMgYXR0ZW1wdGVkLgorICovCitwdWJsaWMgY2xhc3MgQXJpdGhtZXRpY0V4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjI1NjQ3NzU1ODMxNDQ5NjAwN0w7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBBcml0aG1ldGljRXhjZXB0aW9ufSB0aGF0IGluY2x1ZGVzIHRoZSBjdXJyZW50CisgICAgICogc3RhY2sgdHJhY2UuCisgICAgICovCisgICAgcHVibGljIEFyaXRobWV0aWNFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQXJpdGhtZXRpY0V4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudCBzdGFjayB0cmFjZQorICAgICAqIGFuZCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIEFyaXRobWV0aWNFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODdhMTVlNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw3NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyb3duIHdoZW4gdGhlIGFuIGFycmF5IGlzIGluZGV4ZWQgd2l0aCBhIHZhbHVlIGxlc3MgdGhhbiB6ZXJvLCBvciBncmVhdGVyCisgKiB0aGFuIG9yIGVxdWFsIHRvIHRoZSBzaXplIG9mIHRoZSBhcnJheS4KKyAqLworcHVibGljIGNsYXNzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHRlbmRzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTUxMTYxMDExMjgxMTg5NTA4NDRMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9ufSB0aGF0IGluY2x1ZGVzIHRoZQorICAgICAqIGN1cnJlbnQgc3RhY2sgdHJhY2UuCisgICAgICovCisgICAgcHVibGljIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQKKyAgICAgKiBzdGFjayB0cmFjZSBhbmQgYSBkZXRhaWwgbWVzc2FnZSB0aGF0IGlzIGJhc2VkIG9uIHRoZSBzcGVjaWZpZWQgaW52YWxpZAorICAgICAqIHtAY29kZSBpbmRleH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnZhbGlkIGluZGV4LgorICAgICAqLworICAgIHB1YmxpYyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oaW50IGluZGV4KSB7CisgICAgICAgIHN1cGVyKCJpbmRleD0iICsgaW5kZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudAorICAgICAqIHN0YWNrIHRyYWNlIGFuZCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2VkIGludGVybmFsbHkgZm9yIGNvbnNpc3RlbnQgaGlnaC1xdWFsaXR5IGVycm9yIHJlcG9ydGluZy4KKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIHB1YmxpYyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oaW50IHNvdXJjZUxlbmd0aCwgaW50IGluZGV4KSB7CisgICAgICAgIHN1cGVyKCJsZW5ndGg9IiArIHNvdXJjZUxlbmd0aCArICI7IGluZGV4PSIgKyBpbmRleCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlZCBpbnRlcm5hbGx5IGZvciBjb25zaXN0ZW50IGhpZ2gtcXVhbGl0eSBlcnJvciByZXBvcnRpbmcuCisgICAgICogQGhpZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKGludCBzb3VyY2VMZW5ndGgsIGludCBvZmZzZXQsCisgICAgICAgICAgICBpbnQgY291bnQpIHsKKyAgICAgICAgc3VwZXIoImxlbmd0aD0iICsgc291cmNlTGVuZ3RoICsgIjsgcmVnaW9uU3RhcnQ9IiArIG9mZnNldAorICAgICAgICAgICAgICAgICsgIjsgcmVnaW9uTGVuZ3RoPSIgKyBjb3VudCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9BcnJheVN0b3JlRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0FycmF5U3RvcmVFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNTk3YTEwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9BcnJheVN0b3JlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyb3duIHdoZW4gYSBwcm9ncmFtIGF0dGVtcHRzIHRvIHN0b3JlIGFuIGVsZW1lbnQgb2YgYW4gaW5jb21wYXRpYmxlIHR5cGUgaW4KKyAqIGFuIGFycmF5LgorICovCitwdWJsaWMgY2xhc3MgQXJyYXlTdG9yZUV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQ1MjIxOTM4OTA0OTk4MzgyNDFMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQXJyYXlTdG9yZUV4Y2VwdGlvbn0gdGhhdCBpbmNsdWRlcyB0aGUgY3VycmVudAorICAgICAqIHN0YWNrIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBBcnJheVN0b3JlRXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEFycmF5U3RvcmVFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQgc3RhY2sgdHJhY2UKKyAgICAgKiBhbmQgdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBBcnJheVN0b3JlRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQXNzZXJ0aW9uRXJyb3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQXNzZXJ0aW9uRXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZDBkMmE0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Bc3NlcnRpb25FcnJvci5qYXZhCkBAIC0wLDAgKzEsMTI0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gd2hlbiBhbiBhc3NlcnRpb24gaGFzIGZhaWxlZC4KKyAqCisgKiBAc2luY2UgMS40CisgKi8KK3B1YmxpYyBjbGFzcyBBc3NlcnRpb25FcnJvciBleHRlbmRzIEVycm9yIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC01MDEzMjk5NDkzOTcwMjk3MzcwTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEFzc2VydGlvbkVycm9yfSB3aXRoIG5vIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIEFzc2VydGlvbkVycm9yKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEFzc2VydGlvbkVycm9yfSB3aXRoIHRoZSBnaXZlbiBkZXRhaWwgbWVzc2FnZSBhbmQgY2F1c2UuCisgICAgICogQHNpbmNlIDEuNworICAgICAqIEBoaWRlIDEuNworICAgICAqLworICAgIHB1YmxpYyBBc3NlcnRpb25FcnJvcihTdHJpbmcgZGV0YWlsTWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UsIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBBc3NlcnRpb25FcnJvcn0gd2l0aCBhIG1lc3NhZ2UgYmFzZWQgb24gY2FsbGluZworICAgICAqIHtAbGluayBTdHJpbmcjdmFsdWVPZihPYmplY3QpfSB3aXRoIHRoZSBzcGVjaWZpZWQgb2JqZWN0LiBJZiB0aGUgb2JqZWN0CisgICAgICogaXMgYW4gaW5zdGFuY2Ugb2Yge0BsaW5rIFRocm93YWJsZX0sIHRoZW4gaXQgYWxzbyBiZWNvbWVzIHRoZSBjYXVzZSBvZgorICAgICAqIHRoaXMgZXJyb3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBiZSBjb252ZXJ0ZWQgaW50byB0aGUgZGV0YWlsIG1lc3NhZ2UgYW5kCisgICAgICogICAgICAgICAgICBvcHRpb25hbGx5IHRoZSBjYXVzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXNzZXJ0aW9uRXJyb3IoT2JqZWN0IGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoU3RyaW5nLnZhbHVlT2YoZGV0YWlsTWVzc2FnZSksCisgICAgICAgICAgICAgICAgKGRldGFpbE1lc3NhZ2UgaW5zdGFuY2VvZiBUaHJvd2FibGUgPyAoVGhyb3dhYmxlKSBkZXRhaWxNZXNzYWdlIDogbnVsbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEFzc2VydGlvbkVycm9yfSB3aXRoIGEgbWVzc2FnZSBiYXNlZCBvbiBjYWxsaW5nCisgICAgICoge0BsaW5rIFN0cmluZyN2YWx1ZU9mKGJvb2xlYW4pfSB3aXRoIHRoZSBzcGVjaWZpZWQgYm9vbGVhbiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gYmUgY29udmVydGVkIGludG8gdGhlIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIEFzc2VydGlvbkVycm9yKGJvb2xlYW4gZGV0YWlsTWVzc2FnZSkgeworICAgICAgICB0aGlzKFN0cmluZy52YWx1ZU9mKGRldGFpbE1lc3NhZ2UpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBBc3NlcnRpb25FcnJvcn0gd2l0aCBhIG1lc3NhZ2UgYmFzZWQgb24gY2FsbGluZworICAgICAqIHtAbGluayBTdHJpbmcjdmFsdWVPZihjaGFyKX0gd2l0aCB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gYmUgY29udmVydGVkIGludG8gdGhlIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIEFzc2VydGlvbkVycm9yKGNoYXIgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICB0aGlzKFN0cmluZy52YWx1ZU9mKGRldGFpbE1lc3NhZ2UpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBBc3NlcnRpb25FcnJvcn0gd2l0aCBhIG1lc3NhZ2UgYmFzZWQgb24gY2FsbGluZworICAgICAqIHtAbGluayBTdHJpbmcjdmFsdWVPZihpbnQpfSB3aXRoIHRoZSBzcGVjaWZpZWQgaW50ZWdlciB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gYmUgY29udmVydGVkIGludG8gdGhlIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIEFzc2VydGlvbkVycm9yKGludCBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHRoaXMoSW50ZWdlci50b1N0cmluZyhkZXRhaWxNZXNzYWdlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQXNzZXJ0aW9uRXJyb3J9IHdpdGggYSBtZXNzYWdlIGJhc2VkIG9uIGNhbGxpbmcKKyAgICAgKiB7QGxpbmsgU3RyaW5nI3ZhbHVlT2YobG9uZyl9IHdpdGggdGhlIHNwZWNpZmllZCBsb25nIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0byBiZSBjb252ZXJ0ZWQgaW50byB0aGUgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXNzZXJ0aW9uRXJyb3IobG9uZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHRoaXMoTG9uZy50b1N0cmluZyhkZXRhaWxNZXNzYWdlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQXNzZXJ0aW9uRXJyb3J9IHdpdGggYSBtZXNzYWdlIGJhc2VkIG9uIGNhbGxpbmcKKyAgICAgKiB7QGxpbmsgU3RyaW5nI3ZhbHVlT2YoZmxvYXQpfSB3aXRoIHRoZSBzcGVjaWZpZWQgZmxvYXQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIGJlIGNvbnZlcnRlZCBpbnRvIHRoZSBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBBc3NlcnRpb25FcnJvcihmbG9hdCBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHRoaXMoRmxvYXQudG9TdHJpbmcoZGV0YWlsTWVzc2FnZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEFzc2VydGlvbkVycm9yfSB3aXRoIGEgbWVzc2FnZSBiYXNlZCBvbiBjYWxsaW5nCisgICAgICoge0BsaW5rIFN0cmluZyN2YWx1ZU9mKGRvdWJsZSl9IHdpdGggdGhlIHNwZWNpZmllZCBkb3VibGUgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIGJlIGNvbnZlcnRlZCBpbnRvIHRoZSBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBBc3NlcnRpb25FcnJvcihkb3VibGUgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICB0aGlzKERvdWJsZS50b1N0cmluZyhkZXRhaWxNZXNzYWdlKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9BdXRvQ2xvc2VhYmxlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0F1dG9DbG9zZWFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMzEzM2E5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9BdXRvQ2xvc2VhYmxlLmphdmEKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIERlZmluZXMgYW4gaW50ZXJmYWNlIGZvciBjbGFzc2VzIHRoYXQgY2FuIChvciBuZWVkIHRvKSBiZSBjbG9zZWQgb25jZSB0aGV5CisgKiBhcmUgbm90IHVzZWQgYW55IGxvbmdlci4gQ2FsbGluZyB0aGUge0Bjb2RlIGNsb3NlfSBtZXRob2QgcmVsZWFzZXMgcmVzb3VyY2VzCisgKiB0aGF0IHRoZSBvYmplY3QgaG9sZHMuCisgKgorICogPHA+QSBjb21tb24gcGF0dGVybiBmb3IgdXNpbmcgYW4ge0Bjb2RlIEF1dG9DbG9zZWFibGV9IHJlc291cmNlOiA8cHJlPiAgIHtAY29kZQorICogICBDbG9zYWJsZSBmb28gPSBuZXcgRm9vKCk7CisgKiAgIHRyeSB7CisgKiAgICAgIC4uLjsKKyAqICAgfSBmaW5hbGx5IHsKKyAqICAgICAgZm9vLmNsb3NlKCk7CisgKiAgIH0KKyAqIH08L3ByZT4KKyAqCisgKiBAc2luY2UgMS43CisgKiBAaGlkZSAxLjcKKyAqLworcHVibGljIGludGVyZmFjZSBBdXRvQ2xvc2VhYmxlIHsKKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGUgb2JqZWN0IGFuZCByZWxlYXNlIGFueSBzeXN0ZW0gcmVzb3VyY2VzIGl0IGhvbGRzLgorICAgICAqCisgICAgICogPHA+VW5sZXNzIHRoZSBpbXBsZW1lbnRpbmcgY2xhc3Mgc3BlY2lmaWVzIG90aGVyd2lzZSwgaXQgaXMgYW4gZXJyb3IgdG8KKyAgICAgKiBjYWxsIHtAbGluayAjY2xvc2V9IG1vcmUgdGhhbiBvbmNlLgorICAgICAqLworICAgIHZvaWQgY2xvc2UoKSB0aHJvd3MgRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Cb29sZWFuLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0Jvb2xlYW4uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYzhmZmM4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Cb29sZWFuLmphdmEKQEAgLTAsMCArMSwyMzIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKKy8qKgorICogVGhlIHdyYXBwZXIgZm9yIHRoZSBwcmltaXRpdmUgdHlwZSB7QGNvZGUgYm9vbGVhbn0uCisgKgorICogQHNpbmNlIDEuMAorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQm9vbGVhbiBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSwgQ29tcGFyYWJsZTxCb29sZWFuPiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzY2NTgwNDE5OTAxNDM2ODUzMEw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYm9vbGVhbiB2YWx1ZSBvZiB0aGUgcmVjZWl2ZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHZhbHVlOworCisgICAgLyoqCisgICAgICogVGhlIHtAbGluayBDbGFzc30gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcHJpbWl0aXZlIHR5cGUge0Bjb2RlCisgICAgICogYm9vbGVhbn0uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDbGFzczxCb29sZWFuPiBUWVBFCisgICAgICAgICAgICAgPSAoQ2xhc3M8Qm9vbGVhbj4pIGJvb2xlYW5bXS5jbGFzcy5nZXRDb21wb25lbnRUeXBlKCk7CisgICAgLy8gTm90ZTogQm9vbGVhbi5UWVBFIGNhbid0IGJlIHNldCB0byAiYm9vbGVhbi5jbGFzcyIsIHNpbmNlICp0aGF0KiBpcworICAgIC8vIGRlZmluZWQgdG8gYmUgImphdmEubGFuZy5Cb29sZWFuLlRZUEUiOworCisgICAgLyoqCisgICAgICogVGhlIHtAY29kZSBCb29sZWFufSBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBwcmltaXRpdmUgdmFsdWUKKyAgICAgKiB7QGNvZGUgdHJ1ZX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBCb29sZWFuIFRSVUUgPSBuZXcgQm9vbGVhbih0cnVlKTsKKworICAgIC8qKgorICAgICAqIFRoZSB7QGNvZGUgQm9vbGVhbn0gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcHJpbWl0aXZlIHZhbHVlCisgICAgICoge0Bjb2RlIGZhbHNlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEJvb2xlYW4gRkFMU0UgPSBuZXcgQm9vbGVhbihmYWxzZSk7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBCb29sZWFufSB3aXRoIGl0cyBib29sZWFuIHZhbHVlIHNwZWNpZmllZCBieQorICAgICAqIHtAY29kZSBzdHJpbmd9LiBJZiB7QGNvZGUgc3RyaW5nfSBpcyBub3Qge0Bjb2RlIG51bGx9IGFuZCBpcyBlcXVhbCB0bworICAgICAqICJ0cnVlIiB1c2luZyBhIG5vbi1jYXNlIHNlbnNpdGl2ZSBjb21wYXJpc29uLCB0aGUgcmVzdWx0IHdpbGwgYmUgYQorICAgICAqIEJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSBwcmltaXRpdmUgdmFsdWUge0Bjb2RlIHRydWV9LCBvdGhlcndpc2UgaXQgd2lsbAorICAgICAqIGJlIGEgQm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHByaW1pdGl2ZSB2YWx1ZSB7QGNvZGUgZmFsc2V9LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyByZXByZXNlbnRpbmcgYSBib29sZWFuIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBCb29sZWFuKFN0cmluZyBzdHJpbmcpIHsKKyAgICAgICAgdGhpcyhwYXJzZUJvb2xlYW4oc3RyaW5nKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQm9vbGVhbn0gd2l0aCB0aGUgc3BlY2lmaWVkIHByaW1pdGl2ZSBib29sZWFuCisgICAgICogdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmltaXRpdmUgYm9vbGVhbiB2YWx1ZSwge0Bjb2RlIHRydWV9IG9yIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgcHVibGljIEJvb2xlYW4oYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcHJpbWl0aXZlIHZhbHVlIG9mIHRoaXMgYm9vbGVhbiwgZWl0aGVyIHtAY29kZSB0cnVlfSBvcgorICAgICAqIHtAY29kZSBmYWxzZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgb2JqZWN0J3MgcHJpbWl0aXZlIHZhbHVlLCB7QGNvZGUgdHJ1ZX0gb3Ige0Bjb2RlIGZhbHNlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBib29sZWFuVmFsdWUoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBvYmplY3QgYW5kIGluZGljYXRlcyBpZiB0aGV5CisgICAgICogYXJlIGVxdWFsLiBJbiBvcmRlciB0byBiZSBlcXVhbCwge0Bjb2RlIG99IG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YKKyAgICAgKiB7QGNvZGUgQm9vbGVhbn0gYW5kIGhhdmUgdGhlIHNhbWUgYm9vbGVhbiB2YWx1ZSBhcyB0aGlzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyBib29sZWFuIHdpdGguCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgZXF1YWwgdG8gdGhpcworICAgICAqICAgICAgICAge0Bjb2RlIEJvb2xlYW59OyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBARmluZEJ1Z3NTdXBwcmVzc1dhcm5pbmdzKCJSQ19SRUZfQ09NUEFSSVNPTl9CQURfUFJBQ1RJQ0VfQk9PTEVBTiIpCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgIHJldHVybiAobyA9PSB0aGlzKSB8fCAoKG8gaW5zdGFuY2VvZiBCb29sZWFuKSAmJiAoKChCb29sZWFuKSBvKS52YWx1ZSA9PSB2YWx1ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoaXMgb2JqZWN0IHRvIHRoZSBzcGVjaWZpZWQgYm9vbGVhbiBvYmplY3QgdG8gZGV0ZXJtaW5lIHRoZWlyCisgICAgICogcmVsYXRpdmUgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhhdAorICAgICAqICAgICAgICAgICAgdGhlIGJvb2xlYW4gb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyBvYmplY3QgdG8uCisgICAgICogQHJldHVybiAwIGlmIHRoZSB2YWx1ZSBvZiB0aGlzIGJvb2xlYW4gYW5kIHRoZSB2YWx1ZSBvZiB7QGNvZGUgdGhhdH0gYXJlCisgICAgICogICAgICAgICBlcXVhbDsgYSBwb3NpdGl2ZSB2YWx1ZSBpZiB0aGUgdmFsdWUgb2YgdGhpcyBib29sZWFuIGlzCisgICAgICogICAgICAgICB7QGNvZGUgdHJ1ZX0gYW5kIHRoZSB2YWx1ZSBvZiB7QGNvZGUgdGhhdH0gaXMge0Bjb2RlIGZhbHNlfTsgYQorICAgICAqICAgICAgICAgbmVnYXRpdmUgdmFsdWUgaWYgdGhlIHZhbHVlIGlmIHRoaXMgYm9vbGVhbiBpcyB7QGNvZGUgZmFsc2V9IGFuZAorICAgICAqICAgICAgICAgdGhlIHZhbHVlIG9mIHtAY29kZSB0aGF0fSBpcyB7QGNvZGUgdHJ1ZX0uCisgICAgICogQHNlZSBqYXZhLmxhbmcuQ29tcGFyYWJsZQorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhCb29sZWFuIHRoYXQpIHsKKyAgICAgICAgcmV0dXJuIGNvbXBhcmUodmFsdWUsIHRoYXQudmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHR3byB7QGNvZGUgYm9vbGVhbn0gdmFsdWVzLgorICAgICAqIEByZXR1cm4gMCBpZiBsaHMgPSByaHMsIGxlc3MgdGhhbiAwIGlmIGxocyAmbHQ7IHJocywgYW5kIGdyZWF0ZXIgdGhhbiAwIGlmIGxocyAmZ3Q7IHJocy4KKyAgICAgKiAgICAgICAgIChXaGVyZSB0cnVlICZndDsgZmFsc2UuKQorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBjb21wYXJlKGJvb2xlYW4gbGhzLCBib29sZWFuIHJocykgeworICAgICAgICByZXR1cm4gbGhzID09IHJocyA/IDAgOiBsaHMgPyAxIDogLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnRlZ2VyIGhhc2ggY29kZSBmb3IgdGhpcyBib29sZWFuLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIGJvb2xlYW4ncyBoYXNoIGNvZGUsIHdoaWNoIGlzIHtAY29kZSAxMjMxfSBmb3Ige0Bjb2RlIHRydWV9CisgICAgICogICAgICAgICB2YWx1ZXMgYW5kIHtAY29kZSAxMjM3fSBmb3Ige0Bjb2RlIGZhbHNlfSB2YWx1ZXMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlID8gMTIzMSA6IDEyMzc7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhpcworICAgICAqIGJvb2xlYW4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuICJ0cnVlIiBpZiB0aGUgdmFsdWUgb2YgdGhpcyBib29sZWFuIGlzIHtAY29kZSB0cnVlfSwgImZhbHNlIgorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBTdHJpbmcudmFsdWVPZih2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIGJvb2xlYW59IHZhbHVlIG9mIHRoZSBzeXN0ZW0gcHJvcGVydHkgaWRlbnRpZmllZCBieQorICAgICAqIHtAY29kZSBzdHJpbmd9LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlcXVlc3RlZCBzeXN0ZW0gcHJvcGVydHkuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHN5c3RlbSBwcm9wZXJ0eSBuYW1lZCBieSB7QGNvZGUgc3RyaW5nfQorICAgICAqICAgICAgICAgZXhpc3RzIGFuZCBpdCBpcyBlcXVhbCB0byAidHJ1ZSIgdXNpbmcgY2FzZSBpbnNlbnNpdGl2ZQorICAgICAqICAgICAgICAgY29tcGFyaXNvbiwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNlZSBTeXN0ZW0jZ2V0UHJvcGVydHkoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBnZXRCb29sZWFuKFN0cmluZyBzdHJpbmcpIHsKKyAgICAgICAgaWYgKHN0cmluZyA9PSBudWxsIHx8IHN0cmluZy5sZW5ndGgoKSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChwYXJzZUJvb2xlYW4oU3lzdGVtLmdldFByb3BlcnR5KHN0cmluZykpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgdGhlIHNwZWNpZmllZCBzdHJpbmcgYXMgYSB7QGNvZGUgYm9vbGVhbn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIGJvb2xlYW4gdmFsdWUuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIHN9IGlzIG5vdCB7QGNvZGUgbnVsbH0gYW5kIGlzIGVxdWFsIHRvCisgICAgICogICAgICAgICB7QGNvZGUgInRydWUifSB1c2luZyBjYXNlIGluc2Vuc2l0aXZlIGNvbXBhcmlzb24sIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIHBhcnNlQm9vbGVhbihTdHJpbmcgcykgeworICAgICAgICByZXR1cm4gInRydWUiLmVxdWFsc0lnbm9yZUNhc2Uocyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhlIHNwZWNpZmllZCBib29sZWFuIHRvIGl0cyBzdHJpbmcgcmVwcmVzZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBib29sZWFuIHRvIGNvbnZlcnQuCisgICAgICogQHJldHVybiAidHJ1ZSIgaWYge0Bjb2RlIHZhbHVlfSBpcyB7QGNvZGUgdHJ1ZX0sICJmYWxzZSIgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIFN0cmluZy52YWx1ZU9mKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgdGhlIHNwZWNpZmllZCBzdHJpbmcgYXMgYSBib29sZWFuIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIGJvb2xlYW4gdmFsdWUuCisgICAgICogQHJldHVybiB7QGNvZGUgQm9vbGVhbi5UUlVFfSBpZiB7QGNvZGUgc3RyaW5nfSBpcyBlcXVhbCB0byAidHJ1ZSIgdXNpbmcKKyAgICAgKiAgICAgICAgIGNhc2UgaW5zZW5zaXRpdmUgY29tcGFyaXNvbiwge0Bjb2RlIEJvb2xlYW4uRkFMU0V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNwYXJzZUJvb2xlYW4oU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQm9vbGVhbiB2YWx1ZU9mKFN0cmluZyBzdHJpbmcpIHsKKyAgICAgICAgcmV0dXJuIHBhcnNlQm9vbGVhbihzdHJpbmcpID8gQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIEJvb2xlYW59IGluc3RhbmNlIGZvciB0aGUgc3BlY2lmaWVkIGJvb2xlYW4gdmFsdWUuCisgICAgICogPHA+CisgICAgICogSWYgaXQgaXMgbm90IG5lY2Vzc2FyeSB0byBnZXQgYSBuZXcge0Bjb2RlIEJvb2xlYW59IGluc3RhbmNlLCBpdCBpcworICAgICAqIHJlY29tbWVuZGVkIHRvIHVzZSB0aGlzIG1ldGhvZCBpbnN0ZWFkIG9mIHRoZSBjb25zdHJ1Y3Rvciwgc2luY2UgaXQKKyAgICAgKiByZXR1cm5zIGl0cyBzdGF0aWMgaW5zdGFuY2VzLCB3aGljaCByZXN1bHRzIGluIGJldHRlciBwZXJmb3JtYW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgYm9vbGVhbiB0byBjb252ZXJ0IHRvIGEge0Bjb2RlIEJvb2xlYW59LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIEJvb2xlYW4uVFJVRX0gaWYge0Bjb2RlIGJ9IGlzIGVxdWFsIHRvIHtAY29kZSB0cnVlfSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBCb29sZWFuLkZBTFNFfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCb29sZWFuIHZhbHVlT2YoYm9vbGVhbiBiKSB7CisgICAgICAgIHJldHVybiBiID8gQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0J5dGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQnl0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJkMWExZTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0J5dGUuamF2YQpAQCAtMCwwICsxLDMxMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhlIHdyYXBwZXIgZm9yIHRoZSBwcmltaXRpdmUgdHlwZSB7QGNvZGUgYnl0ZX0uCisgKgorICogQHNpbmNlIDEuMQorICovCitARmluZEJ1Z3NTdXBwcmVzc1dhcm5pbmdzKCJETV9OVU1CRVJfQ1RPUiIpCitwdWJsaWMgZmluYWwgY2xhc3MgQnl0ZSBleHRlbmRzIE51bWJlciBpbXBsZW1lbnRzIENvbXBhcmFibGU8Qnl0ZT4geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTcxODM2OTgyMzE1NTkxMjk4MjhMOworCisgICAgLyoqCisgICAgICogVGhlIHZhbHVlIHdoaWNoIHRoZSByZWNlaXZlciByZXByZXNlbnRzLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgYnl0ZSB2YWx1ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBtYXhpbXVtIHtAY29kZSBCeXRlfSB2YWx1ZSwgMjxzdXA+Nzwvc3VwPi0xLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBNQVhfVkFMVUUgPSAoYnl0ZSkgMHg3RjsKKworICAgIC8qKgorICAgICAqIFRoZSBtaW5pbXVtIHtAY29kZSBCeXRlfSB2YWx1ZSwgLTI8c3VwPjc8L3N1cD4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIE1JTl9WQUxVRSA9IChieXRlKSAweDgwOworCisgICAgLyoqCisgICAgICogVGhlIG51bWJlciBvZiBiaXRzIG5lZWRlZCB0byByZXByZXNlbnQgYSB7QGNvZGUgQnl0ZX0gdmFsdWUgaW4gdHdvJ3MKKyAgICAgKiBjb21wbGVtZW50IGZvcm0uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0laRSA9IDg7CisKKyAgICAvKioKKyAgICAgKiBUaGUge0BsaW5rIENsYXNzfSBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBwcmltaXRpdmUgdHlwZSB7QGNvZGUgYnl0ZX0uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDbGFzczxCeXRlPiBUWVBFCisgICAgICAgICAgICA9IChDbGFzczxCeXRlPikgYnl0ZVtdLmNsYXNzLmdldENvbXBvbmVudFR5cGUoKTsKKyAgICAvLyBOb3RlOiBCeXRlLlRZUEUgY2FuJ3QgYmUgc2V0IHRvICJieXRlLmNsYXNzIiwgc2luY2UgKnRoYXQqIGlzCisgICAgLy8gZGVmaW5lZCB0byBiZSAiamF2YS5sYW5nLkJ5dGUuVFlQRSI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBCeXRlfSB3aXRoIHRoZSBzcGVjaWZpZWQgcHJpbWl0aXZlIGJ5dGUgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmltaXRpdmUgYnl0ZSB2YWx1ZSB0byBzdG9yZSBpbiB0aGUgbmV3IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBCeXRlKGJ5dGUgdmFsdWUpIHsKKyAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJ5dGV9IGZyb20gdGhlIHNwZWNpZmllZCBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgc2luZ2xlIGJ5dGUgdmFsdWUuCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyaW5nfSBjYW5ub3QgYmUgcGFyc2VkIGFzIGEgYnl0ZSB2YWx1ZS4KKyAgICAgKiBAc2VlICNwYXJzZUJ5dGUoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBCeXRlKFN0cmluZyBzdHJpbmcpIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24geworICAgICAgICB0aGlzKHBhcnNlQnl0ZShzdHJpbmcpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBwcmltaXRpdmUgdmFsdWUgb2YgdGhpcyBieXRlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIG9iamVjdCdzIHByaW1pdGl2ZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZSBieXRlVmFsdWUoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIG9iamVjdCB0byB0aGUgc3BlY2lmaWVkIGJ5dGUgb2JqZWN0IHRvIGRldGVybWluZSB0aGVpcgorICAgICAqIHJlbGF0aXZlIG9yZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyBvYmplY3QgdG8uCisgICAgICogQHJldHVybiBhIG5lZ2F0aXZlIHZhbHVlIGlmIHRoZSB2YWx1ZSBvZiB0aGlzIGJ5dGUgaXMgbGVzcyB0aGFuIHRoZSB2YWx1ZQorICAgICAqICAgICAgICAgb2Yge0Bjb2RlIG9iamVjdH07IDAgaWYgdGhlIHZhbHVlIG9mIHRoaXMgYnl0ZSBhbmQgdGhlIHZhbHVlIG9mCisgICAgICogICAgICAgICB7QGNvZGUgb2JqZWN0fSBhcmUgZXF1YWw7IGEgcG9zaXRpdmUgdmFsdWUgaWYgdGhlIHZhbHVlIG9mIHRoaXMKKyAgICAgKiAgICAgICAgIGJ5dGUgaXMgZ3JlYXRlciB0aGFuIHRoZSB2YWx1ZSBvZiB7QGNvZGUgb2JqZWN0fS4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5Db21wYXJhYmxlCisgICAgICogQHNpbmNlIDEuMgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKEJ5dGUgb2JqZWN0KSB7CisgICAgICAgIHJldHVybiBjb21wYXJlKHZhbHVlLCBvYmplY3QudmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHR3byB7QGNvZGUgYnl0ZX0gdmFsdWVzLgorICAgICAqIEByZXR1cm4gMCBpZiBsaHMgPSByaHMsIGxlc3MgdGhhbiAwIGlmIGxocyAmbHQ7IHJocywgYW5kIGdyZWF0ZXIgdGhhbiAwIGlmIGxocyAmZ3Q7IHJocy4KKyAgICAgKiBAc2luY2UgMS43CisgICAgICogQGhpZGUgMS43CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgY29tcGFyZShieXRlIGxocywgYnl0ZSByaHMpIHsKKyAgICAgICAgcmV0dXJuIGxocyA+IHJocyA/IDEgOiAobGhzIDwgcmhzID8gLTEgOiAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgdGhlIHNwZWNpZmllZCBzdHJpbmcgYW5kIHJldHVybnMgYSB7QGNvZGUgQnl0ZX0gaW5zdGFuY2UgaWYgdGhlCisgICAgICogc3RyaW5nIGNhbiBiZSBkZWNvZGVkIGludG8gYSBzaW5nbGUgYnl0ZSB2YWx1ZS4gVGhlIHN0cmluZyBtYXkgYmUgYW4KKyAgICAgKiBvcHRpb25hbCBtaW51cyBzaWduICItIiBmb2xsb3dlZCBieSBhIGhleGFkZWNpbWFsICgiMHguLi4iIG9yICIjLi4uIiksCisgICAgICogb2N0YWwgKCIwLi4uIiksIG9yIGRlY2ltYWwgKCIuLi4iKSByZXByZXNlbnRhdGlvbiBvZiBhIGJ5dGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHNpbmdsZSBieXRlIHZhbHVlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgQnl0ZX0gY29udGFpbmluZyB0aGUgdmFsdWUgcmVwcmVzZW50ZWQgYnkge0Bjb2RlIHN0cmluZ30uCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyaW5nfSBjYW5ub3QgYmUgcGFyc2VkIGFzIGEgYnl0ZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEJ5dGUgZGVjb2RlKFN0cmluZyBzdHJpbmcpIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24geworICAgICAgICBpbnQgaW50VmFsdWUgPSBJbnRlZ2VyLmRlY29kZShzdHJpbmcpOworICAgICAgICBieXRlIHJlc3VsdCA9IChieXRlKSBpbnRWYWx1ZTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBpbnRWYWx1ZSkgeworICAgICAgICAgICAgcmV0dXJuIHZhbHVlT2YocmVzdWx0KTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJWYWx1ZSBvdXQgb2YgcmFuZ2UgZm9yIGJ5dGU6IFwiIiArIHN0cmluZyArICJcIiIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkb3VibGUgZG91YmxlVmFsdWUoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFuZCBpbmRpY2F0ZXMgaWYgdGhleSBhcmUKKyAgICAgKiBlcXVhbC4gSW4gb3JkZXIgdG8gYmUgZXF1YWwsIHtAY29kZSBvYmplY3R9IG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YKKyAgICAgKiB7QGNvZGUgQnl0ZX0gYW5kIGhhdmUgdGhlIHNhbWUgYnl0ZSB2YWx1ZSBhcyB0aGlzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB0aGlzIGJ5dGUgd2l0aC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBlcXVhbCB0byB0aGlzCisgICAgICogICAgICAgICB7QGNvZGUgQnl0ZX07IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIEBGaW5kQnVnc1N1cHByZXNzV2FybmluZ3MoIlJDX1JFRl9DT01QQVJJU09OIikKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICByZXR1cm4gKG9iamVjdCA9PSB0aGlzKSB8fCAoKG9iamVjdCBpbnN0YW5jZW9mIEJ5dGUpICYmICgoKEJ5dGUpIG9iamVjdCkudmFsdWUgPT0gdmFsdWUpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXQgZmxvYXRWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGludFZhbHVlKCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgbG9uZ1ZhbHVlKCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGFzIGEgc2lnbmVkIGRlY2ltYWwgYnl0ZSB2YWx1ZS4gVGhlIEFTQ0lJCisgICAgICogY2hhcmFjdGVyIFx1MDAyZCAoJy0nKSBpcyByZWNvZ25pemVkIGFzIHRoZSBtaW51cyBzaWduLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHNpbmdsZSBieXRlIHZhbHVlLgorICAgICAqIEByZXR1cm4gdGhlIHByaW1pdGl2ZSBieXRlIHZhbHVlIHJlcHJlc2VudGVkIGJ5IHtAY29kZSBzdHJpbmd9LgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0cmluZ30gY2FuIG5vdCBiZSBwYXJzZWQgYXMgYSBieXRlIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZSBwYXJzZUJ5dGUoU3RyaW5nIHN0cmluZykgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBwYXJzZUJ5dGUoc3RyaW5nLCAxMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGFzIGEgc2lnbmVkIGJ5dGUgdmFsdWUgdXNpbmcgdGhlIHNwZWNpZmllZAorICAgICAqIHJhZGl4LiBUaGUgQVNDSUkgY2hhcmFjdGVyIFx1MDAyZCAoJy0nKSBpcyByZWNvZ25pemVkIGFzIHRoZSBtaW51cyBzaWduLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHNpbmdsZSBieXRlIHZhbHVlLgorICAgICAqIEBwYXJhbSByYWRpeAorICAgICAqICAgICAgICAgICAgdGhlIHJhZGl4IHRvIHVzZSB3aGVuIHBhcnNpbmcuCisgICAgICogQHJldHVybiB0aGUgcHJpbWl0aXZlIGJ5dGUgdmFsdWUgcmVwcmVzZW50ZWQgYnkge0Bjb2RlIHN0cmluZ30gdXNpbmcKKyAgICAgKiAgICAgICAgIHtAY29kZSByYWRpeH0uCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyaW5nfSBjYW4gbm90IGJlIHBhcnNlZCBhcyBhIGJ5dGUgdmFsdWUsIG9yCisgICAgICogICAgICAgICAgICAge0Bjb2RlIHJhZGl4IDwgQ2hhcmFjdGVyLk1JTl9SQURJWCB8fAorICAgICAqICAgICAgICAgICAgIHJhZGl4ID4gQ2hhcmFjdGVyLk1BWF9SQURJWH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlIHBhcnNlQnl0ZShTdHJpbmcgc3RyaW5nLCBpbnQgcmFkaXgpIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24geworICAgICAgICBpbnQgaW50VmFsdWUgPSBJbnRlZ2VyLnBhcnNlSW50KHN0cmluZywgcmFkaXgpOworICAgICAgICBieXRlIHJlc3VsdCA9IChieXRlKSBpbnRWYWx1ZTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBpbnRWYWx1ZSkgeworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJWYWx1ZSBvdXQgb2YgcmFuZ2UgZm9yIGJ5dGU6IFwiIiArIHN0cmluZyArICJcIiIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzaG9ydCBzaG9ydFZhbHVlKCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIEludGVnZXIudG9TdHJpbmcodmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB0d28tZGlnaXQgaGV4IHN0cmluZy4gVGhhdCBpcywgLTEgYmVjb21lcyAiZmYiIG9yICJGRiIgYW5kIDIgYmVjb21lcyAiMDIiLgorICAgICAqIEBoaWRlIGludGVybmFsIHVzZSBvbmx5CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9IZXhTdHJpbmcoYnl0ZSBiLCBib29sZWFuIHVwcGVyQ2FzZSkgeworICAgICAgICByZXR1cm4gSW50ZWdyYWxUb1N0cmluZy5ieXRlVG9IZXhTdHJpbmcoYiwgdXBwZXJDYXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUKKyAgICAgKiBzcGVjaWZpZWQgYnl0ZSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgdG8gY29udmVydCB0byBhIHN0cmluZy4KKyAgICAgKiBAcmV0dXJuIGEgcHJpbnRhYmxlIHJlcHJlc2VudGF0aW9uIG9mIHtAY29kZSB2YWx1ZX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoYnl0ZSB2YWx1ZSkgeworICAgICAgICByZXR1cm4gSW50ZWdlci50b1N0cmluZyh2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGFzIGEgc2lnbmVkIGRlY2ltYWwgYnl0ZSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBzaW5nbGUgYnl0ZSB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIEJ5dGV9IGluc3RhbmNlIGNvbnRhaW5pbmcgdGhlIGJ5dGUgdmFsdWUgcmVwcmVzZW50ZWQgYnkKKyAgICAgKiAgICAgICAgIHtAY29kZSBzdHJpbmd9LgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0cmluZ30gY2FuIG5vdCBiZSBwYXJzZWQgYXMgYSBieXRlIHZhbHVlLgorICAgICAqIEBzZWUgI3BhcnNlQnl0ZShTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCeXRlIHZhbHVlT2YoU3RyaW5nIHN0cmluZykgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiB2YWx1ZU9mKHBhcnNlQnl0ZShzdHJpbmcpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgdGhlIHNwZWNpZmllZCBzdHJpbmcgYXMgYSBzaWduZWQgYnl0ZSB2YWx1ZSB1c2luZyB0aGUgc3BlY2lmaWVkCisgICAgICogcmFkaXguCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgc2luZ2xlIGJ5dGUgdmFsdWUuCisgICAgICogQHBhcmFtIHJhZGl4CisgICAgICogICAgICAgICAgICB0aGUgcmFkaXggdG8gdXNlIHdoZW4gcGFyc2luZy4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIEJ5dGV9IGluc3RhbmNlIGNvbnRhaW5pbmcgdGhlIGJ5dGUgdmFsdWUgcmVwcmVzZW50ZWQgYnkKKyAgICAgKiAgICAgICAgIHtAY29kZSBzdHJpbmd9IHVzaW5nIHtAY29kZSByYWRpeH0uCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyaW5nfSBjYW4gbm90IGJlIHBhcnNlZCBhcyBhIGJ5dGUgdmFsdWUsIG9yCisgICAgICogICAgICAgICAgICAge0Bjb2RlIHJhZGl4IDwgQ2hhcmFjdGVyLk1JTl9SQURJWCB8fAorICAgICAqICAgICAgICAgICAgIHJhZGl4ID4gQ2hhcmFjdGVyLk1BWF9SQURJWH0uCisgICAgICogQHNlZSAjcGFyc2VCeXRlKFN0cmluZywgaW50KQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQnl0ZSB2YWx1ZU9mKFN0cmluZyBzdHJpbmcsIGludCByYWRpeCkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiB2YWx1ZU9mKHBhcnNlQnl0ZShzdHJpbmcsIHJhZGl4KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBCeXRlfSBpbnN0YW5jZSBmb3IgdGhlIHNwZWNpZmllZCBieXRlIHZhbHVlLgorICAgICAqIDxwPgorICAgICAqIElmIGl0IGlzIG5vdCBuZWNlc3NhcnkgdG8gZ2V0IGEgbmV3IHtAY29kZSBCeXRlfSBpbnN0YW5jZSwgaXQgaXMKKyAgICAgKiByZWNvbW1lbmRlZCB0byB1c2UgdGhpcyBtZXRob2QgaW5zdGVhZCBvZiB0aGUgY29uc3RydWN0b3IsIHNpbmNlIGl0CisgICAgICogbWFpbnRhaW5zIGEgY2FjaGUgb2YgaW5zdGFuY2VzIHdoaWNoIG1heSByZXN1bHQgaW4gYmV0dGVyIHBlcmZvcm1hbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIHZhbHVlIHRvIHN0b3JlIGluIHRoZSBpbnN0YW5jZS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIEJ5dGV9IGluc3RhbmNlIGNvbnRhaW5pbmcge0Bjb2RlIGJ9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEJ5dGUgdmFsdWVPZihieXRlIGIpIHsKKyAgICAgICAgcmV0dXJuIFZBTFVFU1tiICsgMTI4XTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBIGNhY2hlIG9mIGluc3RhbmNlcyB1c2VkIGJ5IHtAbGluayBCeXRlI3ZhbHVlT2YoYnl0ZSl9IGFuZCBhdXRvLWJveGluZworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEJ5dGVbXSBWQUxVRVMgPSBuZXcgQnl0ZVsyNTZdOworCisgICAgc3RhdGljIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IC0xMjg7IGkgPCAxMjg7IGkrKykgeworICAgICAgICAgICAgVkFMVUVTW2kgKyAxMjhdID0gbmV3IEJ5dGUoKGJ5dGUpIGkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9DYXNlTWFwcGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0Nhc2VNYXBwZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZWM0MWY1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9DYXNlTWFwcGVyLmphdmEKQEAgLTAsMCArMSwyMDAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgbGliY29yZS5pY3UuSUNVOworCisvKioKKyAqIFBlcmZvcm1zIGNhc2Ugb3BlcmF0aW9ucyBhcyBkZXNjcmliZWQgYnkgaHR0cDovL3VuaWNvZGUub3JnL3JlcG9ydHMvdHIyMS90cjIxLTUuaHRtbC4KKyAqLworY2xhc3MgQ2FzZU1hcHBlciB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIHVwcGVyVmFsdWVzID0gIlNTXHUwMDAwXHUwMmJjTlx1MDAwMEpcdTAzMGNcdTAwMDBcdTAzOTlcdTAzMDhcdTAzMDFcdTAzYTVcdTAzMDhcdTAzMDFcdTA1MzVcdTA1NTJcdTAwMDBIXHUwMzMxXHUwMDAwVFx1MDMwOFx1MDAwMFdcdTAzMGFcdTAwMDBZXHUwMzBhXHUwMDAwQVx1MDJiZVx1MDAwMFx1MDNhNVx1MDMxM1x1MDAwMFx1MDNhNVx1MDMxM1x1MDMwMFx1MDNhNVx1MDMxM1x1MDMwMVx1MDNhNVx1MDMxM1x1MDM0Mlx1MWYwOFx1MDM5OVx1MDAwMFx1MWYwOVx1MDM5OVx1MDAwMFx1MWYwYVx1MDM5OVx1MDAwMFx1MWYwYlx1MDM5OVx1MDAwMFx1MWYwY1x1MDM5OVx1MDAwMFx1MWYwZFx1MDM5OVx1MDAwMFx1MWYwZVx1MDM5OVx1MDAwMFx1MWYwZlx1MDM5OVx1MDAwMFx1MWYwOFx1MDM5OVx1MDAwMFx1MWYwOVx1MDM5OVx1MDAwMFx1MWYwYVx1MDM5OVx1MDAwMFx1MWYwYlx1MDM5OVx1MDAwMFx1MWYwY1x1MDM5OVx1MDAwMFx1MWYwZFx1MDM5OVx1MDAwMFx1MWYwZVx1MDM5OVx1MDAwMFx1MWYwZlx1MDM5OVx1MDAwMFx1MWYyOFx1MDM5OVx1MDAwMFx1MWYyOVx1MDM5OVx1MDAwMFx1MWYyYVx1MDM5OVx1MDAwMFx1MWYyYlx1MDM5OVx1MDAwMFx1MWYyY1x1MDM5OVx1MDAwMFx1MWYyZFx1MDM5OVx1MDAwMFx1MWYyZVx1MDM5OVx1MDAwMFx1MWYyZlx1MDM5OVx1MDAwMFx1MWYyOFx1MDM5OVx1MDAwMFx1MWYyOVx1MDM5OVx1MDAwMFx1MWYyYVx1MDM5OVx1MDAwMFx1MWYyYlx1MDM5OVx1MDAwMFx1MWYyY1x1MDM5OVx1MDAwMFx1MWYyZFx1MDM5OVx1MDAwMFx1MWYyZVx1MDM5OVx1MDAwMFx1MWYyZlx1MDM5OVx1MDAwMFx1MWY2OFx1MDM5OVx1MDAwMFx1MWY2OVx1MDM5OVx1MDAwMFx1MWY2YVx1MDM5OVx1MDAwMFx1MWY2Ylx1MDM5OVx1MDAwMFx1MWY2Y1x1MDM5OVx1MDAwMFx1MWY2ZFx1MDM5OVx1MDAwMFx1MWY2ZVx1MDM5OVx1MDAwMFx1MWY2Zlx1MDM5OVx1MDAwMFx1MWY2OFx1MDM5OVx1MDAwMFx1MWY2OVx1MDM5OVx1MDAwMFx1MWY2YVx1MDM5OVx1MDAwMFx1MWY2Ylx1MDM5OVx1MDAwMFx1MWY2Y1x1MDM5OVx1MDAwMFx1MWY2ZFx1MDM5OVx1MDAwMFx1MWY2ZVx1MDM5OVx1MDAwMFx1MWY2Zlx1MDM5OVx1MDAwMFx1MWZiYVx1MDM5OVx1MDAwMFx1MDM5MVx1MDM5OVx1MDAwMFx1MDM4Nlx1MDM5OVx1MDAwMFx1MDM5MVx1MDM0Mlx1MDAwMFx1MDM5MVx1MDM0Mlx1MDM5OVx1MDM5MVx1MDM5OVx1MDAwMFx1MWZjYVx1MDM5OVx1MDAwMFx1MDM5N1x1MDM5OVx1MDAwMFx1MDM4OVx1MDM5OVx1MDAwMFx1MDM5N1x1MDM0Mlx1MDAwMFx1MDM5N1x1MDM0Mlx1MDM5OVx1MDM5N1x1MDM5OVx1MDAwMFx1MDM5OVx1MDMwOFx1MDMwMFx1MDM5OVx1MDMwOFx1MDMwMVx1MDM5OVx1MDM0Mlx1MDAwMFx1MDM5OVx1MDMwOFx1MDM0Mlx1MDNhNVx1MDMwOFx1MDMwMFx1MDNhNVx1MDMwOFx1MDMwMVx1MDNhMVx1MDMxM1x1MDAwMFx1MDNhNVx1MDM0Mlx1MDAwMFx1MDNhNVx1MDMwOFx1MDM0Mlx1MWZmYVx1MDM5OVx1MDAwMFx1MDNhOVx1MDM5OVx1MDAwMFx1MDM4Zlx1MDM5OVx1MDAwMFx1MDNhOVx1MDM0Mlx1MDAwMFx1MDNhOVx1MDM0Mlx1MDM5OVx1MDNhOVx1MDM5OVx1MDAwMEZGXHUwMDAwRklcdTAwMDBGTFx1MDAwMEZGSUZGTFNUXHUwMDAwU1RcdTAwMDBcdTA1NDRcdTA1NDZcdTAwMDBcdTA1NDRcdTA1MzVcdTAwMDBcdTA1NDRcdTA1M2JcdTAwMDBcdTA1NGVcdTA1NDZcdTAwMDBcdTA1NDRcdTA1M2RcdTAwMDAiLnRvQ2hhckFycmF5KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIHVwcGVyVmFsdWVzMiA9ICJcdTAwMGJcdTAwMDBcZlx1MDAwMFxyXHUwMDAwXHUwMDBlXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDBmXHUwMDEwXHUwMDExXHUwMDEyXHUwMDEzXHUwMDE0XHUwMDE1XHUwMDE2XHUwMDE3XHUwMDE4XHUwMDE5XHUwMDFhXHUwMDFiXHUwMDFjXHUwMDFkXHUwMDFlXHUwMDFmICFcIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT5cdTAwMDBcdTAwMDA/QEFcdTAwMDBCQ1x1MDAwMFx1MDAwMFx1MDAwMFx1MDAwMERcdTAwMDBcdTAwMDBcdTAwMDBcdTAwMDBcdTAwMDBFRkdcdTAwMDBISVx1MDAwMFx1MDAwMFx1MDAwMFx1MDAwMEpcdTAwMDBcdTAwMDBcdTAwMDBcdTAwMDBcdTAwMDBLTFx1MDAwMFx1MDAwME1OXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwT1BRXHUwMDAwUlNcdTAwMDBcdTAwMDBcdTAwMDBcdTAwMDBcdTAwMDBcdTAwMDBcdTAwMDBcdTAwMDBcdTAwMDBcdTAwMDBUVVZcdTAwMDBXWFx1MDAwMFx1MDAwMFx1MDAwMFx1MDAwMFkiLnRvQ2hhckFycmF5KCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIExBVElOX0NBUElUQUxfSV9XSVRIX0RPVCA9ICdcdTAxMzAnOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgR1JFRUtfQ0FQSVRBTF9TSUdNQSA9ICdcdTAzYTMnOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgR1JFRUtfU01BTExfRklOQUxfU0lHTUEgPSAnXHUwM2MyJzsKKworICAgIC8qKgorICAgICAqIE91ciBjdXJyZW50IEdDIG1ha2VzIHNob3J0LWxpdmVkIG9iamVjdHMgbW9yZSBleHBlbnNpdmUgdGhhbiB3ZSdkIGxpa2UuIFdoZW4gdGhhdCdzIGZpeGVkLAorICAgICAqIHRoaXMgY2xhc3Mgc2hvdWxkIGJlIGNoYW5nZWQgc28gdGhhdCB5b3UgaW5zdGFudGlhdGUgaXQgd2l0aCB0aGUgU3RyaW5nIGFuZCBpdHMgdmFsdWUsCisgICAgICogb2Zmc2V0LCBhbmQgY291bnQgZmllbGRzLgorICAgICAqLworICAgIHByaXZhdGUgQ2FzZU1hcHBlcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbXBsZW1lbnRzIFN0cmluZy50b0xvd2VyQ2FzZS4gV2UgbmVlZCAncycgc28gdGhhdCB3ZSBjYW4gcmV0dXJuIHRoZSBvcmlnaW5hbCBTdHJpbmcgaW5zdGFuY2UKKyAgICAgKiBpZiBub3RoaW5nIGNoYW5nZXMuIFdlIG5lZWQgJ3ZhbHVlJywgJ29mZnNldCcsIGFuZCAnY291bnQnIGJlY2F1c2UgdGhleSdyZSBub3Qgb3RoZXJ3aXNlCisgICAgICogYWNjZXNzaWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b0xvd2VyQ2FzZShMb2NhbGUgbG9jYWxlLCBTdHJpbmcgcywgY2hhcltdIHZhbHVlLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHsKKyAgICAgICAgLy8gUHVudCBoYXJkIGNhc2VzIHRvIElDVTRDLgorICAgICAgICBTdHJpbmcgbGFuZ3VhZ2VDb2RlID0gbG9jYWxlLmdldExhbmd1YWdlKCk7CisgICAgICAgIGlmIChsYW5ndWFnZUNvZGUuZXF1YWxzKCJ0ciIpIHx8IGxhbmd1YWdlQ29kZS5lcXVhbHMoImF6IikgfHwgbGFuZ3VhZ2VDb2RlLmVxdWFscygibHQiKSkgeworICAgICAgICAgICAgcmV0dXJuIElDVS50b0xvd2VyQ2FzZShzLCBsb2NhbGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICBjaGFyW10gbmV3VmFsdWUgPSBudWxsOworICAgICAgICBpbnQgbmV3Q291bnQgPSAwOworICAgICAgICBmb3IgKGludCBpID0gb2Zmc2V0LCBlbmQgPSBvZmZzZXQgKyBjb3VudDsgaSA8IGVuZDsgKytpKSB7CisgICAgICAgICAgICBjaGFyIGNoID0gdmFsdWVbaV07CisgICAgICAgICAgICBjaGFyIG5ld0NoOworICAgICAgICAgICAgaWYgKGNoID09IExBVElOX0NBUElUQUxfSV9XSVRIX0RPVCB8fCBDaGFyYWN0ZXIuaXNIaWdoU3Vycm9nYXRlKGNoKSkgeworICAgICAgICAgICAgICAgIC8vIFB1bnQgdGhlc2UgaGFyZCBjYXNlcy4KKyAgICAgICAgICAgICAgICByZXR1cm4gSUNVLnRvTG93ZXJDYXNlKHMsIGxvY2FsZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gR1JFRUtfQ0FQSVRBTF9TSUdNQSAmJiBpc0ZpbmFsU2lnbWEodmFsdWUsIG9mZnNldCwgY291bnQsIGkpKSB7CisgICAgICAgICAgICAgICAgbmV3Q2ggPSBHUkVFS19TTUFMTF9GSU5BTF9TSUdNQTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgbmV3Q2ggPSBDaGFyYWN0ZXIudG9Mb3dlckNhc2UoY2gpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG5ld1ZhbHVlID09IG51bGwgJiYgY2ggIT0gbmV3Q2gpIHsKKyAgICAgICAgICAgICAgICBuZXdWYWx1ZSA9IG5ldyBjaGFyW2NvdW50XTsgLy8gVGhlIHJlc3VsdCBjYW4ndCBiZSBsb25nZXIgdGhhbiB0aGUgaW5wdXQuCisgICAgICAgICAgICAgICAgbmV3Q291bnQgPSBpIC0gb2Zmc2V0OworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsdWUsIG9mZnNldCwgbmV3VmFsdWUsIDAsIG5ld0NvdW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChuZXdWYWx1ZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgbmV3VmFsdWVbbmV3Q291bnQrK10gPSBuZXdDaDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3VmFsdWUgIT0gbnVsbCA/IG5ldyBTdHJpbmcoMCwgbmV3Q291bnQsIG5ld1ZhbHVlKSA6IHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJ1ZSBpZiAnaW5kZXgnIGlzIHByZWNlZGVkIGJ5IGEgc2VxdWVuY2UgY29uc2lzdGluZyBvZiBhIGNhc2VkIGxldHRlciBhbmQgYSBjYXNlLWlnbm9yYWJsZQorICAgICAqIHNlcXVlbmNlLCBhbmQgJ2luZGV4JyBpcyBub3QgZm9sbG93ZWQgYnkgYSBzZXF1ZW5jZSBjb25zaXN0aW5nIG9mIGFuIGlnbm9yYWJsZSBzZXF1ZW5jZSBhbmQKKyAgICAgKiB0aGVuIGEgY2FzZWQgbGV0dGVyLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNGaW5hbFNpZ21hKGNoYXJbXSB2YWx1ZSwgaW50IG9mZnNldCwgaW50IGNvdW50LCBpbnQgaW5kZXgpIHsKKyAgICAgICAgLy8gVE9ETzogd2UgZG9uJ3Qgc2tpcCBjYXNlLWlnbm9yYWJsZSBzZXF1ZW5jZXMgbGlrZSB3ZSBzaG91bGQuCisgICAgICAgIC8vIFRPRE86IHdlIHNob3VsZCBhZGQgYSBtb3JlIGRpcmVjdCB3YXkgdG8gdGVzdCBmb3IgYSBjYXNlZCBsZXR0ZXIuCisgICAgICAgIGlmIChpbmRleCA8PSBvZmZzZXQpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBjaGFyIHByZXZpb3VzID0gdmFsdWVbaW5kZXggLSAxXTsKKyAgICAgICAgaWYgKCEoQ2hhcmFjdGVyLmlzTG93ZXJDYXNlKHByZXZpb3VzKSB8fCBDaGFyYWN0ZXIuaXNVcHBlckNhc2UocHJldmlvdXMpIHx8IENoYXJhY3Rlci5pc1RpdGxlQ2FzZShwcmV2aW91cykpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGluZGV4ICsgMSA+PSBvZmZzZXQgKyBjb3VudCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgY2hhciBuZXh0ID0gdmFsdWVbaW5kZXggKyAxXTsKKyAgICAgICAgaWYgKENoYXJhY3Rlci5pc0xvd2VyQ2FzZShuZXh0KSB8fCBDaGFyYWN0ZXIuaXNVcHBlckNhc2UobmV4dCkgfHwgQ2hhcmFjdGVyLmlzVGl0bGVDYXNlKG5leHQpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpbnRvIHRoZSB1cHBlclZhbHVlcyB0YWJsZS4KKyAgICAgKiBUaGUgdXBwZXJWYWx1ZXMgdGFibGUgY29udGFpbnMgdGhyZWUgZW50cmllcyBhdCBlYWNoIHBvc2l0aW9uLiBUaGVzZQorICAgICAqIHRocmVlIGNoYXJhY3RlcnMgYXJlIHRoZSB1cHBlciBjYXNlIGNvbnZlcnNpb24uIElmIG9ubHkgdHdvIGNoYXJhY3RlcnMKKyAgICAgKiBhcmUgdXNlZCwgdGhlIHRoaXJkIGNoYXJhY3RlciBpbiB0aGUgdGFibGUgaXMgXHUwMDAwLgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IGludG8gdGhlIHVwcGVyVmFsdWVzIHRhYmxlLCBvciAtMQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCB1cHBlckluZGV4KGludCBjaCkgeworICAgICAgICBpbnQgaW5kZXggPSAtMTsKKyAgICAgICAgaWYgKGNoID49IDB4ZGYpIHsKKyAgICAgICAgICAgIGlmIChjaCA8PSAweDU4NykgeworICAgICAgICAgICAgICAgIHN3aXRjaCAoY2gpIHsKKyAgICAgICAgICAgICAgICBjYXNlIDB4ZGY6IHJldHVybiAwOworICAgICAgICAgICAgICAgIGNhc2UgMHgxNDk6IHJldHVybiAxOworICAgICAgICAgICAgICAgIGNhc2UgMHgxZjA6IHJldHVybiAyOworICAgICAgICAgICAgICAgIGNhc2UgMHgzOTA6IHJldHVybiAzOworICAgICAgICAgICAgICAgIGNhc2UgMHgzYjA6IHJldHVybiA0OworICAgICAgICAgICAgICAgIGNhc2UgMHg1ODc6IHJldHVybiA1OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPj0gMHgxZTk2KSB7CisgICAgICAgICAgICAgICAgaWYgKGNoIDw9IDB4MWU5YSkgeworICAgICAgICAgICAgICAgICAgICBpbmRleCA9IDYgKyBjaCAtIDB4MWU5NjsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoID49IDB4MWY1MCAmJiBjaCA8PSAweDFmZmMpIHsKKyAgICAgICAgICAgICAgICAgICAgaW5kZXggPSB1cHBlclZhbHVlczJbY2ggLSAweDFmNTBdOworICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSAtMTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPj0gMHhmYjAwKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChjaCA8PSAweGZiMDYpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gOTAgKyBjaCAtIDB4ZmIwMDsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA+PSAweGZiMTMgJiYgY2ggPD0gMHhmYjE3KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IDk3ICsgY2ggLSAweGZiMTM7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGluZGV4OworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvVXBwZXJDYXNlKExvY2FsZSBsb2NhbGUsIFN0cmluZyBzLCBjaGFyW10gdmFsdWUsIGludCBvZmZzZXQsIGludCBjb3VudCkgeworICAgICAgICBTdHJpbmcgbGFuZ3VhZ2VDb2RlID0gbG9jYWxlLmdldExhbmd1YWdlKCk7CisgICAgICAgIGlmIChsYW5ndWFnZUNvZGUuZXF1YWxzKCJ0ciIpIHx8IGxhbmd1YWdlQ29kZS5lcXVhbHMoImF6IikgfHwgbGFuZ3VhZ2VDb2RlLmVxdWFscygibHQiKSkgeworICAgICAgICAgICAgcmV0dXJuIElDVS50b1VwcGVyQ2FzZShzLCBsb2NhbGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICBjaGFyW10gb3V0cHV0ID0gbnVsbDsKKyAgICAgICAgaW50IGkgPSAwOworICAgICAgICBmb3IgKGludCBvID0gb2Zmc2V0LCBlbmQgPSBvZmZzZXQgKyBjb3VudDsgbyA8IGVuZDsgbysrKSB7CisgICAgICAgICAgICBjaGFyIGNoID0gdmFsdWVbb107CisgICAgICAgICAgICBpZiAoQ2hhcmFjdGVyLmlzSGlnaFN1cnJvZ2F0ZShjaCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gSUNVLnRvVXBwZXJDYXNlKHMsIGxvY2FsZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBpbmRleCA9IHVwcGVySW5kZXgoY2gpOworICAgICAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7CisgICAgICAgICAgICAgICAgaWYgKG91dHB1dCAhPSBudWxsICYmIGkgPj0gb3V0cHV0Lmxlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICBjaGFyW10gbmV3b3V0cHV0ID0gbmV3IGNoYXJbb3V0cHV0Lmxlbmd0aCArIChjb3VudCAvIDYpICsgMl07CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob3V0cHV0LCAwLCBuZXdvdXRwdXQsIDAsIG91dHB1dC5sZW5ndGgpOworICAgICAgICAgICAgICAgICAgICBvdXRwdXQgPSBuZXdvdXRwdXQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNoYXIgdXBjaCA9IENoYXJhY3Rlci50b1VwcGVyQ2FzZShjaCk7CisgICAgICAgICAgICAgICAgaWYgKGNoICE9IHVwY2gpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG91dHB1dCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQgPSBuZXcgY2hhcltjb3VudF07CisgICAgICAgICAgICAgICAgICAgICAgICBpID0gbyAtIG9mZnNldDsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsdWUsIG9mZnNldCwgb3V0cHV0LCAwLCBpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBvdXRwdXRbaSsrXSA9IHVwY2g7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvdXRwdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBvdXRwdXRbaSsrXSA9IGNoOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaW50IHRhcmdldCA9IGluZGV4ICogMzsKKyAgICAgICAgICAgICAgICBjaGFyIHZhbDMgPSB1cHBlclZhbHVlc1t0YXJnZXQgKyAyXTsKKyAgICAgICAgICAgICAgICBpZiAob3V0cHV0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0ID0gbmV3IGNoYXJbY291bnQgKyAoY291bnQgLyA2KSArIDJdOworICAgICAgICAgICAgICAgICAgICBpID0gbyAtIG9mZnNldDsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh2YWx1ZSwgb2Zmc2V0LCBvdXRwdXQsIDAsIGkpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSArICh2YWwzID09IDAgPyAxIDogMikgPj0gb3V0cHV0Lmxlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICBjaGFyW10gbmV3b3V0cHV0ID0gbmV3IGNoYXJbb3V0cHV0Lmxlbmd0aCArIChjb3VudCAvIDYpICsgM107CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob3V0cHV0LCAwLCBuZXdvdXRwdXQsIDAsIG91dHB1dC5sZW5ndGgpOworICAgICAgICAgICAgICAgICAgICBvdXRwdXQgPSBuZXdvdXRwdXQ7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgY2hhciB2YWwgPSB1cHBlclZhbHVlc1t0YXJnZXRdOworICAgICAgICAgICAgICAgIG91dHB1dFtpKytdID0gdmFsOworICAgICAgICAgICAgICAgIHZhbCA9IHVwcGVyVmFsdWVzW3RhcmdldCArIDFdOworICAgICAgICAgICAgICAgIG91dHB1dFtpKytdID0gdmFsOworICAgICAgICAgICAgICAgIGlmICh2YWwzICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0W2krK10gPSB2YWwzOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAob3V0cHV0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBzOworICAgICAgICB9CisgICAgICAgIHJldHVybiBvdXRwdXQubGVuZ3RoID09IGkgfHwgb3V0cHV0Lmxlbmd0aCAtIGkgPCA4ID8gbmV3IFN0cmluZygwLCBpLCBvdXRwdXQpIDogbmV3IFN0cmluZyhvdXRwdXQsIDAsIGkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQ2hhclNlcXVlbmNlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0NoYXJTZXF1ZW5jZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZjMWVjZDMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0NoYXJTZXF1ZW5jZS5qYXZhCkBAIC0wLDAgKzEsNzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisKKy8qKgorICogVGhpcyBpbnRlcmZhY2UgcmVwcmVzZW50cyBhbiBvcmRlcmVkIHNldCBvZiBjaGFyYWN0ZXJzIGFuZCBkZWZpbmVzIHRoZQorICogbWV0aG9kcyB0byBwcm9iZSB0aGVtLgorICovCitwdWJsaWMgaW50ZXJmYWNlIENoYXJTZXF1ZW5jZSB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGlzIHNlcXVlbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMuCisgICAgICovCisgICAgcHVibGljIGludCBsZW5ndGgoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNoYXJhY3RlciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LCB3aXRoIHRoZSBmaXJzdCBjaGFyYWN0ZXIKKyAgICAgKiBoYXZpbmcgaW5kZXggemVyby4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjaGFyYWN0ZXIgdG8gcmV0dXJuLgorICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3RlZCBjaGFyYWN0ZXIuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4IDwgMH0gb3Ige0Bjb2RlIGluZGV4fSBpcyBncmVhdGVyIHRoYW4gdGhlCisgICAgICogICAgICAgICAgICAgbGVuZ3RoIG9mIHRoaXMgc2VxdWVuY2UuCisgICAgICovCisgICAgcHVibGljIGNoYXIgY2hhckF0KGludCBpbmRleCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIENoYXJTZXF1ZW5jZX0gZnJvbSB0aGUge0Bjb2RlIHN0YXJ0fSBpbmRleCAoaW5jbHVzaXZlKQorICAgICAqIHRvIHRoZSB7QGNvZGUgZW5kfSBpbmRleCAoZXhjbHVzaXZlKSBvZiB0aGlzIHNlcXVlbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgb2Zmc2V0IG9mIHRoZSBzdWItc2VxdWVuY2UuIEl0IGlzIGluY2x1c2l2ZSwgdGhhdAorICAgICAqICAgICAgICAgICAgaXMsIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIHRoYXQgaXMgaW5jbHVkZWQgaW4gdGhlCisgICAgICogICAgICAgICAgICBzdWItc2VxdWVuY2UuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGVuZCBvZmZzZXQgb2YgdGhlIHN1Yi1zZXF1ZW5jZS4gSXQgaXMgZXhjbHVzaXZlLCB0aGF0IGlzLAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgYWZ0ZXIgdGhvc2UgdGhhdCBhcmUgaW5jbHVkZWQKKyAgICAgKiAgICAgICAgICAgIGluIHRoZSBzdWItc2VxdWVuY2UKKyAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0ZWQgc3ViLXNlcXVlbmNlLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA8IDB9LCB7QGNvZGUgZW5kIDwgMH0sIHtAY29kZSBzdGFydCA+IGVuZH0sCisgICAgICogICAgICAgICAgICAgb3IgaWYge0Bjb2RlIHN0YXJ0fSBvciB7QGNvZGUgZW5kfSBhcmUgZ3JlYXRlciB0aGFuIHRoZQorICAgICAqICAgICAgICAgICAgIGxlbmd0aCBvZiB0aGlzIHNlcXVlbmNlLgorICAgICAqLworICAgIHB1YmxpYyBDaGFyU2VxdWVuY2Ugc3ViU2VxdWVuY2UoaW50IHN0YXJ0LCBpbnQgZW5kKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgd2l0aCB0aGUgc2FtZSBjaGFyYWN0ZXJzIGluIHRoZSBzYW1lIG9yZGVyIGFzIGluIHRoaXMKKyAgICAgKiBzZXF1ZW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgYmFzZWQgb24gdGhpcyBzZXF1ZW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0NoYXJhY3Rlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9DaGFyYWN0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYTQxZWMyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9DaGFyYWN0ZXIuamF2YQpAQCAtMCwwICsxLDMzMDcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBUaGUgd3JhcHBlciBmb3IgdGhlIHByaW1pdGl2ZSB0eXBlIHtAY29kZSBjaGFyfS4gVGhpcyBjbGFzcyBhbHNvIHByb3ZpZGVzIGEKKyAqIG51bWJlciBvZiB1dGlsaXR5IG1ldGhvZHMgZm9yIHdvcmtpbmcgd2l0aCBjaGFyYWN0ZXJzLgorICoKKyAqIDxwPkNoYXJhY3RlciBkYXRhIGlzIGtlcHQgdXAgdG8gZGF0ZSBhcyBVbmljb2RlIGV2b2x2ZXMuCisgKiBTZWUgdGhlIDxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjbG9jYWxlX2RhdGEiPkxvY2FsZSBkYXRhPC9hPiBzZWN0aW9uIG9mCisgKiB0aGUge0Bjb2RlIExvY2FsZX0gZG9jdW1lbnRhdGlvbiBmb3IgZGV0YWlscyBvZiB0aGUgVW5pY29kZSB2ZXJzaW9ucyBpbXBsZW1lbnRlZCBieSBjdXJyZW50CisgKiBhbmQgaGlzdG9yaWNhbCBBbmRyb2lkIHJlbGVhc2VzLgorICoKKyAqIDxwPlRoZSBVbmljb2RlIHNwZWNpZmljYXRpb24sIGNoYXJhY3RlciB0YWJsZXMsIGFuZCBvdGhlciBpbmZvcm1hdGlvbiBhcmUgYXZhaWxhYmxlIGF0CisgKiA8YSBocmVmPSJodHRwOi8vd3d3LnVuaWNvZGUub3JnLyI+aHR0cDovL3d3dy51bmljb2RlLm9yZy88L2E+LgorICoKKyAqIDxwPlVuaWNvZGUgY2hhcmFjdGVycyBhcmUgcmVmZXJyZWQgdG8gYXMgPGk+Y29kZSBwb2ludHM8L2k+LiBUaGUgcmFuZ2Ugb2YgdmFsaWQKKyAqIGNvZGUgcG9pbnRzIGlzIFUrMDAwMCB0byBVKzEwRkZGRi4gVGhlIDxpPkJhc2ljIE11bHRpbGluZ3VhbCBQbGFuZSAoQk1QKTwvaT4KKyAqIGlzIHRoZSBjb2RlIHBvaW50IHJhbmdlIFUrMDAwMCB0byBVK0ZGRkYuIENoYXJhY3RlcnMgYWJvdmUgdGhlIEJNUCBhcmUKKyAqIHJlZmVycmVkIHRvIGFzIDxpPlN1cHBsZW1lbnRhcnkgQ2hhcmFjdGVyczwvaT4uIE9uIHRoZSBKYXZhIHBsYXRmb3JtLCBVVEYtMTYKKyAqIGVuY29kaW5nIGFuZCB7QGNvZGUgY2hhcn0gcGFpcnMgYXJlIHVzZWQgdG8gcmVwcmVzZW50IGNvZGUgcG9pbnRzIGluIHRoZQorICogc3VwcGxlbWVudGFyeSByYW5nZS4gQSBwYWlyIG9mIHtAY29kZSBjaGFyfSB2YWx1ZXMgdGhhdCByZXByZXNlbnQgYQorICogc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIgYXJlIG1hZGUgdXAgb2YgYSA8aT5oaWdoIHN1cnJvZ2F0ZTwvaT4gd2l0aCBhIHZhbHVlCisgKiByYW5nZSBvZiAweEQ4MDAgdG8gMHhEQkZGIGFuZCBhIDxpPmxvdyBzdXJyb2dhdGU8L2k+IHdpdGggYSB2YWx1ZSByYW5nZSBvZgorICogMHhEQzAwIHRvIDB4REZGRi4KKyAqIDxwPgorICogT24gdGhlIEphdmEgcGxhdGZvcm0gYSB7QGNvZGUgY2hhcn0gdmFsdWUgcmVwcmVzZW50cyBlaXRoZXIgYSBzaW5nbGUgQk1QIGNvZGUKKyAqIHBvaW50IG9yIGEgVVRGLTE2IHVuaXQgdGhhdCdzIHBhcnQgb2YgYSBzdXJyb2dhdGUgcGFpci4gVGhlIHtAY29kZSBpbnR9IHR5cGUKKyAqIGlzIHVzZWQgdG8gcmVwcmVzZW50IGFsbCBVbmljb2RlIGNvZGUgcG9pbnRzLgorICoKKyAqIDxhIG5hbWU9InVuaWNvZGVfY2F0ZWdvcmllcyI+PGgzPlVuaWNvZGUgY2F0ZWdvcmllczwvaDM+PC9hPgorICogPHA+SGVyZSdzIGEgbGlzdCBvZiB0aGUgVW5pY29kZSBjaGFyYWN0ZXIgY2F0ZWdvcmllcyBhbmQgdGhlIGNvcnJlc3BvbmRpbmcgSmF2YSBjb25zdGFudCwKKyAqIGdyb3VwZWQgc2VtYW50aWNhbGx5IHRvIHByb3ZpZGUgYSBjb252ZW5pZW50IG92ZXJ2aWV3LiBUaGlzIHRhYmxlIGlzIGFsc28gdXNlZnVsIGluCisgKiBjb25qdW5jdGlvbiB3aXRoIHtAY29kZSBccH0gYW5kIHtAY29kZSBcUH0gaW4ge0BsaW5rIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIHJlZ3VsYXIgZXhwcmVzc2lvbnN9LgorICogPHNwYW4gY2xhc3M9ImRhdGF0YWJsZSI+CisgKiA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgorICogLmRhdGF0YWJsZSB0ZCB7IHBhZGRpbmctcmlnaHQ6IDIwcHg7IH0KKyAqIDwvc3R5bGU+CisgKiA8cD48dGFibGU+CisgKiA8dHI+IDx0ZD4gQ24gPC90ZD4gPHRkPiBVbmFzc2lnbmVkIDwvdGQ+ICA8dGQ+e0BsaW5rICNVTkFTU0lHTkVEfTwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gQ2MgPC90ZD4gPHRkPiBDb250cm9sIDwvdGQ+ICAgICA8dGQ+e0BsaW5rICNDT05UUk9MfTwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gQ2YgPC90ZD4gPHRkPiBGb3JtYXQgPC90ZD4gICAgICA8dGQ+e0BsaW5rICNGT1JNQVR9PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBDbyA8L3RkPiA8dGQ+IFByaXZhdGUgdXNlIDwvdGQ+IDx0ZD57QGxpbmsgI1BSSVZBVEVfVVNFfTwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gQ3MgPC90ZD4gPHRkPiBTdXJyb2dhdGUgPC90ZD4gICA8dGQ+e0BsaW5rICNTVVJST0dBVEV9PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPjxicj48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IEx1IDwvdGQ+IDx0ZD4gVXBwZXJjYXNlIGxldHRlciA8L3RkPiA8dGQ+e0BsaW5rICNVUFBFUkNBU0VfTEVUVEVSfTwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gTGwgPC90ZD4gPHRkPiBMb3dlcmNhc2UgbGV0dGVyIDwvdGQ+IDx0ZD57QGxpbmsgI0xPV0VSQ0FTRV9MRVRURVJ9PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBMdCA8L3RkPiA8dGQ+IFRpdGxlY2FzZSBsZXR0ZXIgPC90ZD4gPHRkPntAbGluayAjVElUTEVDQVNFX0xFVFRFUn08L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IExtIDwvdGQ+IDx0ZD4gTW9kaWZpZXIgbGV0dGVyIDwvdGQ+ICA8dGQ+e0BsaW5rICNNT0RJRklFUl9MRVRURVJ9PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBMbyA8L3RkPiA8dGQ+IE90aGVyIGxldHRlciA8L3RkPiAgICAgPHRkPntAbGluayAjT1RIRVJfTEVUVEVSfTwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD48YnI+PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBNbiA8L3RkPiA8dGQ+IE5vbi1zcGFjaW5nIG1hcmsgPC90ZD4gICAgICAgPHRkPntAbGluayAjTk9OX1NQQUNJTkdfTUFSS308L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IE1lIDwvdGQ+IDx0ZD4gRW5jbG9zaW5nIG1hcmsgPC90ZD4gICAgICAgICA8dGQ+e0BsaW5rICNFTkNMT1NJTkdfTUFSS308L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IE1jIDwvdGQ+IDx0ZD4gQ29tYmluaW5nIHNwYWNpbmcgbWFyayA8L3RkPiA8dGQ+e0BsaW5rICNDT01CSU5JTkdfU1BBQ0lOR19NQVJLfTwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD48YnI+PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBOZCA8L3RkPiA8dGQ+IERlY2ltYWwgZGlnaXQgbnVtYmVyIDwvdGQ+IDx0ZD57QGxpbmsgI0RFQ0lNQUxfRElHSVRfTlVNQkVSfTwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gTmwgPC90ZD4gPHRkPiBMZXR0ZXIgbnVtYmVyIDwvdGQ+ICAgICAgICA8dGQ+e0BsaW5rICNMRVRURVJfTlVNQkVSfTwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gTm8gPC90ZD4gPHRkPiBPdGhlciBudW1iZXIgPC90ZD4gICAgICAgICA8dGQ+e0BsaW5rICNPVEhFUl9OVU1CRVJ9PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPjxicj48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFBkIDwvdGQ+IDx0ZD4gRGFzaCBwdW5jdHVhdGlvbiA8L3RkPiAgICAgICAgICA8dGQ+e0BsaW5rICNEQVNIX1BVTkNUVUFUSU9OfTwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gUHMgPC90ZD4gPHRkPiBTdGFydCBwdW5jdHVhdGlvbiA8L3RkPiAgICAgICAgIDx0ZD57QGxpbmsgI1NUQVJUX1BVTkNUVUFUSU9OfTwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gUGUgPC90ZD4gPHRkPiBFbmQgcHVuY3R1YXRpb24gPC90ZD4gICAgICAgICAgIDx0ZD57QGxpbmsgI0VORF9QVU5DVFVBVElPTn08L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFBjIDwvdGQ+IDx0ZD4gQ29ubmVjdG9yIHB1bmN0dWF0aW9uIDwvdGQ+ICAgICA8dGQ+e0BsaW5rICNDT05ORUNUT1JfUFVOQ1RVQVRJT059PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBQaSA8L3RkPiA8dGQ+IEluaXRpYWwgcXVvdGUgcHVuY3R1YXRpb24gPC90ZD4gPHRkPntAbGluayAjSU5JVElBTF9RVU9URV9QVU5DVFVBVElPTn08L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFBmIDwvdGQ+IDx0ZD4gRmluYWwgcXVvdGUgcHVuY3R1YXRpb24gPC90ZD4gICA8dGQ+e0BsaW5rICNGSU5BTF9RVU9URV9QVU5DVFVBVElPTn08L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFBvIDwvdGQ+IDx0ZD4gT3RoZXIgcHVuY3R1YXRpb24gPC90ZD4gICAgICAgICA8dGQ+e0BsaW5rICNPVEhFUl9QVU5DVFVBVElPTn08L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+PGJyPjwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gU20gPC90ZD4gPHRkPiBNYXRoIHN5bWJvbCA8L3RkPiAgICAgPHRkPntAbGluayAjTUFUSF9TWU1CT0x9PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBTYyA8L3RkPiA8dGQ+IEN1cnJlbmN5IHN5bWJvbCA8L3RkPiA8dGQ+e0BsaW5rICNDVVJSRU5DWV9TWU1CT0x9PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBTayA8L3RkPiA8dGQ+IE1vZGlmaWVyIHN5bWJvbCA8L3RkPiA8dGQ+e0BsaW5rICNNT0RJRklFUl9TWU1CT0x9PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBTbyA8L3RkPiA8dGQ+IE90aGVyIHN5bWJvbCA8L3RkPiAgICA8dGQ+e0BsaW5rICNPVEhFUl9TWU1CT0x9PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPjxicj48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFpzIDwvdGQ+IDx0ZD4gU3BhY2Ugc2VwYXJhdG9yIDwvdGQ+ICAgICA8dGQ+e0BsaW5rICNTUEFDRV9TRVBBUkFUT1J9PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBabCA8L3RkPiA8dGQ+IExpbmUgc2VwYXJhdG9yIDwvdGQ+ICAgICAgPHRkPntAbGluayAjTElORV9TRVBBUkFUT1J9PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBacCA8L3RkPiA8dGQ+IFBhcmFncmFwaCBzZXBhcmF0b3IgPC90ZD4gPHRkPntAbGluayAjUEFSQUdSQVBIX1NFUEFSQVRPUn08L3RkPiA8L3RyPgorICogPC90YWJsZT4KKyAqIDwvc3Bhbj4KKyAqCisgKiBAc2luY2UgMS4wCisgKi8KK0BGaW5kQnVnc1N1cHByZXNzV2FybmluZ3MoIkRNX05VTUJFUl9DVE9SIikKK3B1YmxpYyBmaW5hbCBjbGFzcyBDaGFyYWN0ZXIgaW1wbGVtZW50cyBTZXJpYWxpemFibGUsIENvbXBhcmFibGU8Q2hhcmFjdGVyPiB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzc4NjE5ODkxMDg2NTM4NTA4MEw7CisKKyAgICBwcml2YXRlIGZpbmFsIGNoYXIgdmFsdWU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWluaW11bSB7QGNvZGUgQ2hhcmFjdGVyfSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNoYXIgTUlOX1ZBTFVFID0gJ1x1MDAwMCc7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF4aW11bSB7QGNvZGUgQ2hhcmFjdGVyfSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNoYXIgTUFYX1ZBTFVFID0gJ1x1ZmZmZic7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWluaW11bSByYWRpeCB1c2VkIGZvciBjb252ZXJzaW9ucyBiZXR3ZWVuIGNoYXJhY3RlcnMgYW5kIGludGVnZXJzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1JTl9SQURJWCA9IDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF4aW11bSByYWRpeCB1c2VkIGZvciBjb252ZXJzaW9ucyBiZXR3ZWVuIGNoYXJhY3RlcnMgYW5kIGludGVnZXJzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9SQURJWCA9IDM2OworCisgICAgLyoqCisgICAgICogVGhlIHtAbGluayBDbGFzc30gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcHJpbWl0aXZlIHR5cGUge0Bjb2RlIGNoYXJ9LgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3M8Q2hhcmFjdGVyPiBUWVBFCisgICAgICAgICAgICA9IChDbGFzczxDaGFyYWN0ZXI+KSBjaGFyW10uY2xhc3MuZ2V0Q29tcG9uZW50VHlwZSgpOworICAgIC8vIE5vdGU6IENoYXJhY3Rlci5UWVBFIGNhbid0IGJlIHNldCB0byAiY2hhci5jbGFzcyIsIHNpbmNlICp0aGF0KiBpcworICAgIC8vIGRlZmluZWQgdG8gYmUgImphdmEubGFuZy5DaGFyYWN0ZXIuVFlQRSI7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGNhdGVnb3J5IGNvbnN0YW50IENuLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBVTkFTU0lHTkVEID0gMDsKKworICAgIC8qKgorICAgICAqIFVuaWNvZGUgY2F0ZWdvcnkgY29uc3RhbnQgTHUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFVQUEVSQ0FTRV9MRVRURVIgPSAxOworCisgICAgLyoqCisgICAgICogVW5pY29kZSBjYXRlZ29yeSBjb25zdGFudCBMbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgTE9XRVJDQVNFX0xFVFRFUiA9IDI7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGNhdGVnb3J5IGNvbnN0YW50IEx0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBUSVRMRUNBU0VfTEVUVEVSID0gMzsKKworICAgIC8qKgorICAgICAqIFVuaWNvZGUgY2F0ZWdvcnkgY29uc3RhbnQgTG0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIE1PRElGSUVSX0xFVFRFUiA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGNhdGVnb3J5IGNvbnN0YW50IExvLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBPVEhFUl9MRVRURVIgPSA1OworCisgICAgLyoqCisgICAgICogVW5pY29kZSBjYXRlZ29yeSBjb25zdGFudCBNbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgTk9OX1NQQUNJTkdfTUFSSyA9IDY7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGNhdGVnb3J5IGNvbnN0YW50IE1lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBFTkNMT1NJTkdfTUFSSyA9IDc7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGNhdGVnb3J5IGNvbnN0YW50IE1jLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBDT01CSU5JTkdfU1BBQ0lOR19NQVJLID0gODsKKworICAgIC8qKgorICAgICAqIFVuaWNvZGUgY2F0ZWdvcnkgY29uc3RhbnQgTmQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIERFQ0lNQUxfRElHSVRfTlVNQkVSID0gOTsKKworICAgIC8qKgorICAgICAqIFVuaWNvZGUgY2F0ZWdvcnkgY29uc3RhbnQgTmwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIExFVFRFUl9OVU1CRVIgPSAxMDsKKworICAgIC8qKgorICAgICAqIFVuaWNvZGUgY2F0ZWdvcnkgY29uc3RhbnQgTm8uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIE9USEVSX05VTUJFUiA9IDExOworCisgICAgLyoqCisgICAgICogVW5pY29kZSBjYXRlZ29yeSBjb25zdGFudCBacy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgU1BBQ0VfU0VQQVJBVE9SID0gMTI7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGNhdGVnb3J5IGNvbnN0YW50IFpsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBMSU5FX1NFUEFSQVRPUiA9IDEzOworCisgICAgLyoqCisgICAgICogVW5pY29kZSBjYXRlZ29yeSBjb25zdGFudCBacC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgUEFSQUdSQVBIX1NFUEFSQVRPUiA9IDE0OworCisgICAgLyoqCisgICAgICogVW5pY29kZSBjYXRlZ29yeSBjb25zdGFudCBDYy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQ09OVFJPTCA9IDE1OworCisgICAgLyoqCisgICAgICogVW5pY29kZSBjYXRlZ29yeSBjb25zdGFudCBDZi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgRk9STUFUID0gMTY7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGNhdGVnb3J5IGNvbnN0YW50IENvLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBQUklWQVRFX1VTRSA9IDE4OworCisgICAgLyoqCisgICAgICogVW5pY29kZSBjYXRlZ29yeSBjb25zdGFudCBDcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgU1VSUk9HQVRFID0gMTk7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGNhdGVnb3J5IGNvbnN0YW50IFBkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBEQVNIX1BVTkNUVUFUSU9OID0gMjA7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGNhdGVnb3J5IGNvbnN0YW50IFBzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBTVEFSVF9QVU5DVFVBVElPTiA9IDIxOworCisgICAgLyoqCisgICAgICogVW5pY29kZSBjYXRlZ29yeSBjb25zdGFudCBQZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgRU5EX1BVTkNUVUFUSU9OID0gMjI7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGNhdGVnb3J5IGNvbnN0YW50IFBjLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBDT05ORUNUT1JfUFVOQ1RVQVRJT04gPSAyMzsKKworICAgIC8qKgorICAgICAqIFVuaWNvZGUgY2F0ZWdvcnkgY29uc3RhbnQgUG8uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIE9USEVSX1BVTkNUVUFUSU9OID0gMjQ7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGNhdGVnb3J5IGNvbnN0YW50IFNtLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBNQVRIX1NZTUJPTCA9IDI1OworCisgICAgLyoqCisgICAgICogVW5pY29kZSBjYXRlZ29yeSBjb25zdGFudCBTYy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQ1VSUkVOQ1lfU1lNQk9MID0gMjY7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGNhdGVnb3J5IGNvbnN0YW50IFNrLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBNT0RJRklFUl9TWU1CT0wgPSAyNzsKKworICAgIC8qKgorICAgICAqIFVuaWNvZGUgY2F0ZWdvcnkgY29uc3RhbnQgU28uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIE9USEVSX1NZTUJPTCA9IDI4OworCisgICAgLyoqCisgICAgICogVW5pY29kZSBjYXRlZ29yeSBjb25zdGFudCBQaS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgSU5JVElBTF9RVU9URV9QVU5DVFVBVElPTiA9IDI5OworCisgICAgLyoqCisgICAgICogVW5pY29kZSBjYXRlZ29yeSBjb25zdGFudCBQZi4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgRklOQUxfUVVPVEVfUFVOQ1RVQVRJT04gPSAzMDsKKworICAgIC8qKgorICAgICAqIFVuaWNvZGUgYmlkaXJlY3Rpb25hbCBjb25zdGFudC4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgRElSRUNUSU9OQUxJVFlfVU5ERUZJTkVEID0gLTE7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGJpZGlyZWN0aW9uYWwgY29uc3RhbnQgTC4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgRElSRUNUSU9OQUxJVFlfTEVGVF9UT19SSUdIVCA9IDA7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGJpZGlyZWN0aW9uYWwgY29uc3RhbnQgUi4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgRElSRUNUSU9OQUxJVFlfUklHSFRfVE9fTEVGVCA9IDE7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGJpZGlyZWN0aW9uYWwgY29uc3RhbnQgQUwuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIERJUkVDVElPTkFMSVRZX1JJR0hUX1RPX0xFRlRfQVJBQklDID0gMjsKKworICAgIC8qKgorICAgICAqIFVuaWNvZGUgYmlkaXJlY3Rpb25hbCBjb25zdGFudCBFTi4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgRElSRUNUSU9OQUxJVFlfRVVST1BFQU5fTlVNQkVSID0gMzsKKworICAgIC8qKgorICAgICAqIFVuaWNvZGUgYmlkaXJlY3Rpb25hbCBjb25zdGFudCBFUy4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgRElSRUNUSU9OQUxJVFlfRVVST1BFQU5fTlVNQkVSX1NFUEFSQVRPUiA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGJpZGlyZWN0aW9uYWwgY29uc3RhbnQgRVQuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIERJUkVDVElPTkFMSVRZX0VVUk9QRUFOX05VTUJFUl9URVJNSU5BVE9SID0gNTsKKworICAgIC8qKgorICAgICAqIFVuaWNvZGUgYmlkaXJlY3Rpb25hbCBjb25zdGFudCBBTi4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgRElSRUNUSU9OQUxJVFlfQVJBQklDX05VTUJFUiA9IDY7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGJpZGlyZWN0aW9uYWwgY29uc3RhbnQgQ1MuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIERJUkVDVElPTkFMSVRZX0NPTU1PTl9OVU1CRVJfU0VQQVJBVE9SID0gNzsKKworICAgIC8qKgorICAgICAqIFVuaWNvZGUgYmlkaXJlY3Rpb25hbCBjb25zdGFudCBOU00uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIERJUkVDVElPTkFMSVRZX05PTlNQQUNJTkdfTUFSSyA9IDg7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGJpZGlyZWN0aW9uYWwgY29uc3RhbnQgQk4uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIERJUkVDVElPTkFMSVRZX0JPVU5EQVJZX05FVVRSQUwgPSA5OworCisgICAgLyoqCisgICAgICogVW5pY29kZSBiaWRpcmVjdGlvbmFsIGNvbnN0YW50IEIuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIERJUkVDVElPTkFMSVRZX1BBUkFHUkFQSF9TRVBBUkFUT1IgPSAxMDsKKworICAgIC8qKgorICAgICAqIFVuaWNvZGUgYmlkaXJlY3Rpb25hbCBjb25zdGFudCBTLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBESVJFQ1RJT05BTElUWV9TRUdNRU5UX1NFUEFSQVRPUiA9IDExOworCisgICAgLyoqCisgICAgICogVW5pY29kZSBiaWRpcmVjdGlvbmFsIGNvbnN0YW50IFdTLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBESVJFQ1RJT05BTElUWV9XSElURVNQQUNFID0gMTI7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGJpZGlyZWN0aW9uYWwgY29uc3RhbnQgT04uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIERJUkVDVElPTkFMSVRZX09USEVSX05FVVRSQUxTID0gMTM7CisKKyAgICAvKioKKyAgICAgKiBVbmljb2RlIGJpZGlyZWN0aW9uYWwgY29uc3RhbnQgTFJFLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBESVJFQ1RJT05BTElUWV9MRUZUX1RPX1JJR0hUX0VNQkVERElORyA9IDE0OworCisgICAgLyoqCisgICAgICogVW5pY29kZSBiaWRpcmVjdGlvbmFsIGNvbnN0YW50IExSTy4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgRElSRUNUSU9OQUxJVFlfTEVGVF9UT19SSUdIVF9PVkVSUklERSA9IDE1OworCisgICAgLyoqCisgICAgICogVW5pY29kZSBiaWRpcmVjdGlvbmFsIGNvbnN0YW50IFJMRS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgRElSRUNUSU9OQUxJVFlfUklHSFRfVE9fTEVGVF9FTUJFRERJTkcgPSAxNjsKKworICAgIC8qKgorICAgICAqIFVuaWNvZGUgYmlkaXJlY3Rpb25hbCBjb25zdGFudCBSTE8uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIERJUkVDVElPTkFMSVRZX1JJR0hUX1RPX0xFRlRfT1ZFUlJJREUgPSAxNzsKKworICAgIC8qKgorICAgICAqIFVuaWNvZGUgYmlkaXJlY3Rpb25hbCBjb25zdGFudCBQREYuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIERJUkVDVElPTkFMSVRZX1BPUF9ESVJFQ1RJT05BTF9GT1JNQVQgPSAxODsKKworICAgIC8qKgorICAgICAqIFRoZSBtaW5pbXVtIHZhbHVlIG9mIGEgaGlnaCBzdXJyb2dhdGUgb3IgbGVhZGluZyBzdXJyb2dhdGUgdW5pdCBpbiBVVEYtMTYKKyAgICAgKiBlbmNvZGluZywge0Bjb2RlICdcdUQ4MDAnfS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNoYXIgTUlOX0hJR0hfU1VSUk9HQVRFID0gJ1x1RDgwMCc7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF4aW11bSB2YWx1ZSBvZiBhIGhpZ2ggc3Vycm9nYXRlIG9yIGxlYWRpbmcgc3Vycm9nYXRlIHVuaXQgaW4gVVRGLTE2CisgICAgICogZW5jb2RpbmcsIHtAY29kZSAnXHVEQkZGJ30uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjaGFyIE1BWF9ISUdIX1NVUlJPR0FURSA9ICdcdURCRkYnOworCisgICAgLyoqCisgICAgICogVGhlIG1pbmltdW0gdmFsdWUgb2YgYSBsb3cgc3Vycm9nYXRlIG9yIHRyYWlsaW5nIHN1cnJvZ2F0ZSB1bml0IGluIFVURi0xNgorICAgICAqIGVuY29kaW5nLCB7QGNvZGUgJ1x1REMwMCd9LgorICAgICAqCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBNSU5fTE9XX1NVUlJPR0FURSA9ICdcdURDMDAnOworCisgICAgLyoqCisgICAgICogVGhlIG1heGltdW0gdmFsdWUgb2YgYSBsb3cgc3Vycm9nYXRlIG9yIHRyYWlsaW5nIHN1cnJvZ2F0ZSB1bml0IGluIFVURi0xNgorICAgICAqIGVuY29kaW5nLCB7QGNvZGUgJ1x1REZGRid9LgorICAgICAqCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBNQVhfTE9XX1NVUlJPR0FURSA9ICdcdURGRkYnOworCisgICAgLyoqCisgICAgICogVGhlIG1pbmltdW0gdmFsdWUgb2YgYSBzdXJyb2dhdGUgdW5pdCBpbiBVVEYtMTYgZW5jb2RpbmcsIHtAY29kZSAnXHVEODAwJ30uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjaGFyIE1JTl9TVVJST0dBVEUgPSAnXHVEODAwJzsKKworICAgIC8qKgorICAgICAqIFRoZSBtYXhpbXVtIHZhbHVlIG9mIGEgc3Vycm9nYXRlIHVuaXQgaW4gVVRGLTE2IGVuY29kaW5nLCB7QGNvZGUgJ1x1REZGRid9LgorICAgICAqCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBNQVhfU1VSUk9HQVRFID0gJ1x1REZGRic7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWluaW11bSB2YWx1ZSBvZiBhIHN1cHBsZW1lbnRhcnkgY29kZSBwb2ludCwge0Bjb2RlIFUrMDEwMDAwfS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNSU5fU1VQUExFTUVOVEFSWV9DT0RFX1BPSU5UID0gMHgxMDAwMDsKKworICAgIC8qKgorICAgICAqIFRoZSBtaW5pbXVtIGNvZGUgcG9pbnQgdmFsdWUsIHtAY29kZSBVKzAwMDB9LgorICAgICAqCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1JTl9DT0RFX1BPSU5UID0gMHgwMDAwMDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF4aW11bSBjb2RlIHBvaW50IHZhbHVlLCB7QGNvZGUgVSsxMEZGRkZ9LgorICAgICAqCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9DT0RFX1BPSU5UID0gMHgxMEZGRkY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtYmVyIG9mIGJpdHMgcmVxdWlyZWQgdG8gcmVwcmVzZW50IGEge0Bjb2RlIENoYXJhY3Rlcn0gdmFsdWUKKyAgICAgKiB1bnNpZ25lZCBmb3JtLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJWkUgPSAxNjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBESVJFQ1RJT05BTElUWSA9IG5ldyBieXRlW10geworICAgICAgICAgICAgRElSRUNUSU9OQUxJVFlfTEVGVF9UT19SSUdIVCwgRElSRUNUSU9OQUxJVFlfUklHSFRfVE9fTEVGVCwKKyAgICAgICAgICAgIERJUkVDVElPTkFMSVRZX0VVUk9QRUFOX05VTUJFUiwKKyAgICAgICAgICAgIERJUkVDVElPTkFMSVRZX0VVUk9QRUFOX05VTUJFUl9TRVBBUkFUT1IsCisgICAgICAgICAgICBESVJFQ1RJT05BTElUWV9FVVJPUEVBTl9OVU1CRVJfVEVSTUlOQVRPUiwKKyAgICAgICAgICAgIERJUkVDVElPTkFMSVRZX0FSQUJJQ19OVU1CRVIsCisgICAgICAgICAgICBESVJFQ1RJT05BTElUWV9DT01NT05fTlVNQkVSX1NFUEFSQVRPUiwKKyAgICAgICAgICAgIERJUkVDVElPTkFMSVRZX1BBUkFHUkFQSF9TRVBBUkFUT1IsCisgICAgICAgICAgICBESVJFQ1RJT05BTElUWV9TRUdNRU5UX1NFUEFSQVRPUiwgRElSRUNUSU9OQUxJVFlfV0hJVEVTUEFDRSwKKyAgICAgICAgICAgIERJUkVDVElPTkFMSVRZX09USEVSX05FVVRSQUxTLAorICAgICAgICAgICAgRElSRUNUSU9OQUxJVFlfTEVGVF9UT19SSUdIVF9FTUJFRERJTkcsCisgICAgICAgICAgICBESVJFQ1RJT05BTElUWV9MRUZUX1RPX1JJR0hUX09WRVJSSURFLAorICAgICAgICAgICAgRElSRUNUSU9OQUxJVFlfUklHSFRfVE9fTEVGVF9BUkFCSUMsCisgICAgICAgICAgICBESVJFQ1RJT05BTElUWV9SSUdIVF9UT19MRUZUX0VNQkVERElORywKKyAgICAgICAgICAgIERJUkVDVElPTkFMSVRZX1JJR0hUX1RPX0xFRlRfT1ZFUlJJREUsCisgICAgICAgICAgICBESVJFQ1RJT05BTElUWV9QT1BfRElSRUNUSU9OQUxfRk9STUFULAorICAgICAgICAgICAgRElSRUNUSU9OQUxJVFlfTk9OU1BBQ0lOR19NQVJLLCBESVJFQ1RJT05BTElUWV9CT1VOREFSWV9ORVVUUkFMIH07CisKKyAgICAvKgorICAgICAqIFJlcHJlc2VudHMgYSBzdWJzZXQgb2YgdGhlIFVuaWNvZGUgY2hhcmFjdGVyIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFN1YnNldCB7CisgICAgICAgIFN0cmluZyBuYW1lOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBTdWJzZXR9LgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICAgICAqICAgICAgICAgICAgdGhpcyBzdWJzZXQncyBuYW1lLgorICAgICAgICAgKi8KKyAgICAgICAgcHJvdGVjdGVkIFN1YnNldChTdHJpbmcgc3RyaW5nKSB7CisgICAgICAgICAgICBpZiAoc3RyaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG5hbWUgPSBzdHJpbmc7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ29tcGFyZXMgdGhpcyBjaGFyYWN0ZXIgc3Vic2V0IHdpdGggdGhlIHNwZWNpZmllZCBvYmplY3QuIFVzZXMKKyAgICAgICAgICoge0BsaW5rIGphdmEubGFuZy5PYmplY3QjZXF1YWxzKE9iamVjdCl9IHRvIGRvIHRoZSBjb21wYXJpc29uLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHRoaXMgY2hhcmFjdGVyIHN1YnNldCB3aXRoLgorICAgICAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgb2JqZWN0fSBpcyB0aGlzIHN1YnNldCwgdGhhdCBpcywgaWYKKyAgICAgICAgICogICAgICAgICB7QGNvZGUgb2JqZWN0ID09IHRoaXN9OyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmplY3QpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIGludGVnZXIgaGFzaCBjb2RlIGZvciB0aGlzIGNoYXJhY3RlciBzdWJzZXQuCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gdGhpcyBzdWJzZXQncyBoYXNoIGNvZGUsIHdoaWNoIGlzIHRoZSBoYXNoIGNvZGUgY29tcHV0ZWQgYnkKKyAgICAgICAgICogICAgICAgICB7QGxpbmsgamF2YS5sYW5nLk9iamVjdCNoYXNoQ29kZSgpfS4KKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZmluYWwgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgc3Vic2V0LgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIHRoaXMgc3Vic2V0J3MgbmFtZS4KKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXByZXNlbnRzIGEgYmxvY2sgb2YgVW5pY29kZSBjaGFyYWN0ZXJzLCBhcyBkZWZpbmVkIGJ5IHRoZSBVbmljb2RlIDQuMC4xCisgICAgICogc3BlY2lmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFVuaWNvZGVCbG9jayBleHRlbmRzIFN1YnNldCB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7U3Vycm9nYXRlcyBBcmVhJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBkZXByZWNhdGVkIEFzIG9mIEphdmEgNSwgdGhpcyBibG9jayBoYXMgYmVlbiByZXBsYWNlZCBieQorICAgICAgICAgKiAgICAgICAgICAgICB7QGxpbmsgI0hJR0hfU1VSUk9HQVRFU30sCisgICAgICAgICAqICAgICAgICAgICAgIHtAbGluayAjSElHSF9QUklWQVRFX1VTRV9TVVJST0dBVEVTfSBhbmQKKyAgICAgICAgICogICAgICAgICAgICAge0BsaW5rICNMT1dfU1VSUk9HQVRFU30uCisgICAgICAgICAqLworICAgICAgICBARGVwcmVjYXRlZAorICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBTVVJST0dBVEVTX0FSRUEgPSBuZXcgVW5pY29kZUJsb2NrKCJTVVJST0dBVEVTX0FSRUEiLCAweDAsIDB4MCk7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7QmFzaWMgTGF0aW4mcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgQkFTSUNfTEFUSU4gPSBuZXcgVW5pY29kZUJsb2NrKCJCQVNJQ19MQVRJTiIsIDB4MCwgMHg3Zik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7TGF0aW4tMSBTdXBwbGVtZW50JnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIExBVElOXzFfU1VQUExFTUVOVCA9IG5ldyBVbmljb2RlQmxvY2soIkxBVElOXzFfU1VQUExFTUVOVCIsIDB4ODAsIDB4ZmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0xhdGluIEV4dGVuZGVkLUEmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgTEFUSU5fRVhURU5ERURfQSA9IG5ldyBVbmljb2RlQmxvY2soIkxBVElOX0VYVEVOREVEX0EiLCAweDEwMCwgMHgxN2YpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0xhdGluIEV4dGVuZGVkLUImcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgTEFUSU5fRVhURU5ERURfQiA9IG5ldyBVbmljb2RlQmxvY2soIkxBVElOX0VYVEVOREVEX0IiLCAweDE4MCwgMHgyNGYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0lQQSBFeHRlbnNpb25zJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIElQQV9FWFRFTlNJT05TID0gbmV3IFVuaWNvZGVCbG9jaygiSVBBX0VYVEVOU0lPTlMiLCAweDI1MCwgMHgyYWYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O1NwYWNpbmcgTW9kaWZpZXIgTGV0dGVycyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBTUEFDSU5HX01PRElGSUVSX0xFVFRFUlMgPSBuZXcgVW5pY29kZUJsb2NrKCJTUEFDSU5HX01PRElGSUVSX0xFVFRFUlMiLCAweDJiMCwgMHgyZmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0NvbWJpbmluZyBEaWFjcml0aWNhbCBNYXJrcyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBDT01CSU5JTkdfRElBQ1JJVElDQUxfTUFSS1MgPSBuZXcgVW5pY29kZUJsb2NrKCJDT01CSU5JTkdfRElBQ1JJVElDQUxfTUFSS1MiLCAweDMwMCwgMHgzNmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0dyZWVrIGFuZCBDb3B0aWMmcXVvdDsgVW5pY29kZSBCbG9jay4gUHJldmlvdXNseSByZWZlcnJlZAorICAgICAgICAgKiB0byBhcyAmcXVvdDtHcmVlayZxdW90Oy4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgR1JFRUsgPSBuZXcgVW5pY29kZUJsb2NrKCJHUkVFSyIsIDB4MzcwLCAweDNmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7Q3lyaWxsaWMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgQ1lSSUxMSUMgPSBuZXcgVW5pY29kZUJsb2NrKCJDWVJJTExJQyIsIDB4NDAwLCAweDRmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7Q3lyaWxsaWMgU3VwcGxlbWVudCZxdW90OyBVbmljb2RlIEJsb2NrLiBQcmV2aW91c2x5CisgICAgICAgICAqIHJlZmVycmVkIHRvIGFzICZxdW90O0N5cmlsbGljIFN1cHBsZW1lbnRhcnkmcXVvdDsuCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjUKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIENZUklMTElDX1NVUFBMRU1FTlRBUlkgPSBuZXcgVW5pY29kZUJsb2NrKCJDWVJJTExJQ19TVVBQTEVNRU5UQVJZIiwgMHg1MDAsIDB4NTJmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtBcm1lbmlhbiZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBBUk1FTklBTiA9IG5ldyBVbmljb2RlQmxvY2soIkFSTUVOSUFOIiwgMHg1MzAsIDB4NThmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtIZWJyZXcmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgSEVCUkVXID0gbmV3IFVuaWNvZGVCbG9jaygiSEVCUkVXIiwgMHg1OTAsIDB4NWZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtBcmFiaWMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgQVJBQklDID0gbmV3IFVuaWNvZGVCbG9jaygiQVJBQklDIiwgMHg2MDAsIDB4NmZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtTeXJpYWMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNAorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgU1lSSUFDID0gbmV3IFVuaWNvZGVCbG9jaygiU1lSSUFDIiwgMHg3MDAsIDB4NzRmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtUaGFhbmEmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNAorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgVEhBQU5BID0gbmV3IFVuaWNvZGVCbG9jaygiVEhBQU5BIiwgMHg3ODAsIDB4N2JmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtEZXZhbmFnYXJpJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIERFVkFOQUdBUkkgPSBuZXcgVW5pY29kZUJsb2NrKCJERVZBTkFHQVJJIiwgMHg5MDAsIDB4OTdmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtCZW5nYWxpJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIEJFTkdBTEkgPSBuZXcgVW5pY29kZUJsb2NrKCJCRU5HQUxJIiwgMHg5ODAsIDB4OWZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtHdXJtdWtoaSZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBHVVJNVUtISSA9IG5ldyBVbmljb2RlQmxvY2soIkdVUk1VS0hJIiwgMHhhMDAsIDB4YTdmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtHdWphcmF0aSZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBHVUpBUkFUSSA9IG5ldyBVbmljb2RlQmxvY2soIkdVSkFSQVRJIiwgMHhhODAsIDB4YWZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtPcml5YSZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBPUklZQSA9IG5ldyBVbmljb2RlQmxvY2soIk9SSVlBIiwgMHhiMDAsIDB4YjdmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtUYW1pbCZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBUQU1JTCA9IG5ldyBVbmljb2RlQmxvY2soIlRBTUlMIiwgMHhiODAsIDB4YmZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtUZWx1Z3UmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgVEVMVUdVID0gbmV3IFVuaWNvZGVCbG9jaygiVEVMVUdVIiwgMHhjMDAsIDB4YzdmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtLYW5uYWRhJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIEtBTk5BREEgPSBuZXcgVW5pY29kZUJsb2NrKCJLQU5OQURBIiwgMHhjODAsIDB4Y2ZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtNYWxheWFsYW0mcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgTUFMQVlBTEFNID0gbmV3IFVuaWNvZGVCbG9jaygiTUFMQVlBTEFNIiwgMHhkMDAsIDB4ZDdmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtTaW5oYWxhJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjQKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIFNJTkhBTEEgPSBuZXcgVW5pY29kZUJsb2NrKCJTSU5IQUxBIiwgMHhkODAsIDB4ZGZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtUaGFpJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIFRIQUkgPSBuZXcgVW5pY29kZUJsb2NrKCJUSEFJIiwgMHhlMDAsIDB4ZTdmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtMYW8mcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgTEFPID0gbmV3IFVuaWNvZGVCbG9jaygiTEFPIiwgMHhlODAsIDB4ZWZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtUaWJldGFuJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIFRJQkVUQU4gPSBuZXcgVW5pY29kZUJsb2NrKCJUSUJFVEFOIiwgMHhmMDAsIDB4ZmZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtNeWFubWFyJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjQKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIE1ZQU5NQVIgPSBuZXcgVW5pY29kZUJsb2NrKCJNWUFOTUFSIiwgMHgxMDAwLCAweDEwOWYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0dlb3JnaWFuJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIEdFT1JHSUFOID0gbmV3IFVuaWNvZGVCbG9jaygiR0VPUkdJQU4iLCAweDEwYTAsIDB4MTBmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7SGFuZ3VsIEphbW8mcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgSEFOR1VMX0pBTU8gPSBuZXcgVW5pY29kZUJsb2NrKCJIQU5HVUxfSkFNTyIsIDB4MTEwMCwgMHgxMWZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtFdGhpb3BpYyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS40CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBFVEhJT1BJQyA9IG5ldyBVbmljb2RlQmxvY2soIkVUSElPUElDIiwgMHgxMjAwLCAweDEzN2YpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0NoZXJva2VlJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjQKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIENIRVJPS0VFID0gbmV3IFVuaWNvZGVCbG9jaygiQ0hFUk9LRUUiLCAweDEzYTAsIDB4MTNmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7VW5pZmllZCBDYW5hZGlhbiBBYm9yaWdpbmFsIFN5bGxhYmljcyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS40CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBVTklGSUVEX0NBTkFESUFOX0FCT1JJR0lOQUxfU1lMTEFCSUNTID0gbmV3IFVuaWNvZGVCbG9jaygiVU5JRklFRF9DQU5BRElBTl9BQk9SSUdJTkFMX1NZTExBQklDUyIsIDB4MTQwMCwgMHgxNjdmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtPZ2hhbSZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS40CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBPR0hBTSA9IG5ldyBVbmljb2RlQmxvY2soIk9HSEFNIiwgMHgxNjgwLCAweDE2OWYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O1J1bmljJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjQKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIFJVTklDID0gbmV3IFVuaWNvZGVCbG9jaygiUlVOSUMiLCAweDE2YTAsIDB4MTZmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7VGFnYWxvZyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS41CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBUQUdBTE9HID0gbmV3IFVuaWNvZGVCbG9jaygiVEFHQUxPRyIsIDB4MTcwMCwgMHgxNzFmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtIYW51bm9vJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjUKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIEhBTlVOT08gPSBuZXcgVW5pY29kZUJsb2NrKCJIQU5VTk9PIiwgMHgxNzIwLCAweDE3M2YpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0J1aGlkJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjUKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIEJVSElEID0gbmV3IFVuaWNvZGVCbG9jaygiQlVISUQiLCAweDE3NDAsIDB4MTc1Zik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7VGFnYmFud2EmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgVEFHQkFOV0EgPSBuZXcgVW5pY29kZUJsb2NrKCJUQUdCQU5XQSIsIDB4MTc2MCwgMHgxNzdmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtLaG1lciZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS40CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBLSE1FUiA9IG5ldyBVbmljb2RlQmxvY2soIktITUVSIiwgMHgxNzgwLCAweDE3ZmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O01vbmdvbGlhbiZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS40CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBNT05HT0xJQU4gPSBuZXcgVW5pY29kZUJsb2NrKCJNT05HT0xJQU4iLCAweDE4MDAsIDB4MThhZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7TGltYnUmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgTElNQlUgPSBuZXcgVW5pY29kZUJsb2NrKCJMSU1CVSIsIDB4MTkwMCwgMHgxOTRmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtUYWkgTGUmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgVEFJX0xFID0gbmV3IFVuaWNvZGVCbG9jaygiVEFJX0xFIiwgMHgxOTUwLCAweDE5N2YpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0tobWVyIFN5bWJvbHMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgS0hNRVJfU1lNQk9MUyA9IG5ldyBVbmljb2RlQmxvY2soIktITUVSX1NZTUJPTFMiLCAweDE5ZTAsIDB4MTlmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7UGhvbmV0aWMgRXh0ZW5zaW9ucyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS41CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBQSE9ORVRJQ19FWFRFTlNJT05TID0gbmV3IFVuaWNvZGVCbG9jaygiUEhPTkVUSUNfRVhURU5TSU9OUyIsIDB4MWQwMCwgMHgxZDdmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtMYXRpbiBFeHRlbmRlZCBBZGRpdGlvbmFsJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIExBVElOX0VYVEVOREVEX0FERElUSU9OQUwgPSBuZXcgVW5pY29kZUJsb2NrKCJMQVRJTl9FWFRFTkRFRF9BRERJVElPTkFMIiwgMHgxZTAwLCAweDFlZmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0dyZWVrIEV4dGVuZGVkJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIEdSRUVLX0VYVEVOREVEID0gbmV3IFVuaWNvZGVCbG9jaygiR1JFRUtfRVhURU5ERUQiLCAweDFmMDAsIDB4MWZmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7R2VuZXJhbCBQdW5jdHVhdGlvbiZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBHRU5FUkFMX1BVTkNUVUFUSU9OID0gbmV3IFVuaWNvZGVCbG9jaygiR0VORVJBTF9QVU5DVFVBVElPTiIsIDB4MjAwMCwgMHgyMDZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtTdXBlcnNjcmlwdHMgYW5kIFN1YnNjcmlwdHMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgU1VQRVJTQ1JJUFRTX0FORF9TVUJTQ1JJUFRTID0gbmV3IFVuaWNvZGVCbG9jaygiU1VQRVJTQ1JJUFRTX0FORF9TVUJTQ1JJUFRTIiwgMHgyMDcwLCAweDIwOWYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0N1cnJlbmN5IFN5bWJvbHMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgQ1VSUkVOQ1lfU1lNQk9MUyA9IG5ldyBVbmljb2RlQmxvY2soIkNVUlJFTkNZX1NZTUJPTFMiLCAweDIwYTAsIDB4MjBjZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7Q29tYmluaW5nIERpYWNyaXRpY2FsIE1hcmtzIGZvciBTeW1ib2xzJnF1b3Q7IFVuaWNvZGUKKyAgICAgICAgICogQmxvY2suIFByZXZpb3VzbHkgcmVmZXJyZWQgdG8gYXMgJnF1b3Q7Q29tYmluaW5nIE1hcmtzIGZvcgorICAgICAgICAgKiBTeW1ib2xzJnF1b3Q7LgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBDT01CSU5JTkdfTUFSS1NfRk9SX1NZTUJPTFMgPSBuZXcgVW5pY29kZUJsb2NrKCJDT01CSU5JTkdfTUFSS1NfRk9SX1NZTUJPTFMiLCAweDIwZDAsIDB4MjBmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7TGV0dGVybGlrZSBTeW1ib2xzJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIExFVFRFUkxJS0VfU1lNQk9MUyA9IG5ldyBVbmljb2RlQmxvY2soIkxFVFRFUkxJS0VfU1lNQk9MUyIsIDB4MjEwMCwgMHgyMTRmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtOdW1iZXIgRm9ybXMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgTlVNQkVSX0ZPUk1TID0gbmV3IFVuaWNvZGVCbG9jaygiTlVNQkVSX0ZPUk1TIiwgMHgyMTUwLCAweDIxOGYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0Fycm93cyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBBUlJPV1MgPSBuZXcgVW5pY29kZUJsb2NrKCJBUlJPV1MiLCAweDIxOTAsIDB4MjFmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7TWF0aGVtYXRpY2FsIE9wZXJhdG9ycyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBNQVRIRU1BVElDQUxfT1BFUkFUT1JTID0gbmV3IFVuaWNvZGVCbG9jaygiTUFUSEVNQVRJQ0FMX09QRVJBVE9SUyIsIDB4MjIwMCwgMHgyMmZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtNaXNjZWxsYW5lb3VzIFRlY2huaWNhbCZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBNSVNDRUxMQU5FT1VTX1RFQ0hOSUNBTCA9IG5ldyBVbmljb2RlQmxvY2soIk1JU0NFTExBTkVPVVNfVEVDSE5JQ0FMIiwgMHgyMzAwLCAweDIzZmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0NvbnRyb2wgUGljdHVyZXMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgQ09OVFJPTF9QSUNUVVJFUyA9IG5ldyBVbmljb2RlQmxvY2soIkNPTlRST0xfUElDVFVSRVMiLCAweDI0MDAsIDB4MjQzZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7T3B0aWNhbCBDaGFyYWN0ZXIgUmVjb2duaXRpb24mcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgT1BUSUNBTF9DSEFSQUNURVJfUkVDT0dOSVRJT04gPSBuZXcgVW5pY29kZUJsb2NrKCJPUFRJQ0FMX0NIQVJBQ1RFUl9SRUNPR05JVElPTiIsIDB4MjQ0MCwgMHgyNDVmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtFbmNsb3NlZCBBbHBoYW51bWVyaWNzJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIEVOQ0xPU0VEX0FMUEhBTlVNRVJJQ1MgPSBuZXcgVW5pY29kZUJsb2NrKCJFTkNMT1NFRF9BTFBIQU5VTUVSSUNTIiwgMHgyNDYwLCAweDI0ZmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0JveCBEcmF3aW5nJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIEJPWF9EUkFXSU5HID0gbmV3IFVuaWNvZGVCbG9jaygiQk9YX0RSQVdJTkciLCAweDI1MDAsIDB4MjU3Zik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7QmxvY2sgRWxlbWVudHMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgQkxPQ0tfRUxFTUVOVFMgPSBuZXcgVW5pY29kZUJsb2NrKCJCTE9DS19FTEVNRU5UUyIsIDB4MjU4MCwgMHgyNTlmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtHZW9tZXRyaWMgU2hhcGVzJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIEdFT01FVFJJQ19TSEFQRVMgPSBuZXcgVW5pY29kZUJsb2NrKCJHRU9NRVRSSUNfU0hBUEVTIiwgMHgyNWEwLCAweDI1ZmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O01pc2NlbGxhbmVvdXMgU3ltYm9scyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBNSVNDRUxMQU5FT1VTX1NZTUJPTFMgPSBuZXcgVW5pY29kZUJsb2NrKCJNSVNDRUxMQU5FT1VTX1NZTUJPTFMiLCAweDI2MDAsIDB4MjZmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7RGluZ2JhdHMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgRElOR0JBVFMgPSBuZXcgVW5pY29kZUJsb2NrKCJESU5HQkFUUyIsIDB4MjcwMCwgMHgyN2JmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtNaXNjZWxsYW5lb3VzIE1hdGhlbWF0aWNhbCBTeW1ib2xzLUEmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgTUlTQ0VMTEFORU9VU19NQVRIRU1BVElDQUxfU1lNQk9MU19BID0gbmV3IFVuaWNvZGVCbG9jaygiTUlTQ0VMTEFORU9VU19NQVRIRU1BVElDQUxfU1lNQk9MU19BIiwgMHgyN2MwLCAweDI3ZWYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O1N1cHBsZW1lbnRhbCBBcnJvd3MtQSZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS41CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBTVVBQTEVNRU5UQUxfQVJST1dTX0EgPSBuZXcgVW5pY29kZUJsb2NrKCJTVVBQTEVNRU5UQUxfQVJST1dTX0EiLCAweDI3ZjAsIDB4MjdmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7QnJhaWxsZSBQYXR0ZXJucyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS40CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBCUkFJTExFX1BBVFRFUk5TID0gbmV3IFVuaWNvZGVCbG9jaygiQlJBSUxMRV9QQVRURVJOUyIsIDB4MjgwMCwgMHgyOGZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtTdXBwbGVtZW50YWwgQXJyb3dzLUImcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgU1VQUExFTUVOVEFMX0FSUk9XU19CID0gbmV3IFVuaWNvZGVCbG9jaygiU1VQUExFTUVOVEFMX0FSUk9XU19CIiwgMHgyOTAwLCAweDI5N2YpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O01pc2NlbGxhbmVvdXMgTWF0aGVtYXRpY2FsIFN5bWJvbHMtQiZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS41CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBNSVNDRUxMQU5FT1VTX01BVEhFTUFUSUNBTF9TWU1CT0xTX0IgPSBuZXcgVW5pY29kZUJsb2NrKCJNSVNDRUxMQU5FT1VTX01BVEhFTUFUSUNBTF9TWU1CT0xTX0IiLCAweDI5ODAsIDB4MjlmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7U3VwcGxlbWVudGFsIE1hdGhlbWF0aWNhbCBPcGVyYXRvcnMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgU1VQUExFTUVOVEFMX01BVEhFTUFUSUNBTF9PUEVSQVRPUlMgPSBuZXcgVW5pY29kZUJsb2NrKCJTVVBQTEVNRU5UQUxfTUFUSEVNQVRJQ0FMX09QRVJBVE9SUyIsIDB4MmEwMCwgMHgyYWZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtNaXNjZWxsYW5lb3VzIFN5bWJvbHMgYW5kIEFycm93cyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBNSVNDRUxMQU5FT1VTX1NZTUJPTFNfQU5EX0FSUk9XUyA9IG5ldyBVbmljb2RlQmxvY2soIk1JU0NFTExBTkVPVVNfU1lNQk9MU19BTkRfQVJST1dTIiwgMHgyYjAwLCAweDJiZmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0NKSyBSYWRpY2FscyBTdXBwbGVtZW50JnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjQKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIENKS19SQURJQ0FMU19TVVBQTEVNRU5UID0gbmV3IFVuaWNvZGVCbG9jaygiQ0pLX1JBRElDQUxTX1NVUFBMRU1FTlQiLCAweDJlODAsIDB4MmVmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7S2FuZ3hpIFJhZGljYWxzJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjQKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIEtBTkdYSV9SQURJQ0FMUyA9IG5ldyBVbmljb2RlQmxvY2soIktBTkdYSV9SQURJQ0FMUyIsIDB4MmYwMCwgMHgyZmRmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtJZGVvZ3JhcGhpYyBEZXNjcmlwdGlvbiBDaGFyYWN0ZXJzJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjQKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIElERU9HUkFQSElDX0RFU0NSSVBUSU9OX0NIQVJBQ1RFUlMgPSBuZXcgVW5pY29kZUJsb2NrKCJJREVPR1JBUEhJQ19ERVNDUklQVElPTl9DSEFSQUNURVJTIiwgMHgyZmYwLCAweDJmZmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0NKSyBTeW1ib2xzIGFuZCBQdW5jdHVhdGlvbiZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBDSktfU1lNQk9MU19BTkRfUFVOQ1RVQVRJT04gPSBuZXcgVW5pY29kZUJsb2NrKCJDSktfU1lNQk9MU19BTkRfUFVOQ1RVQVRJT04iLCAweDMwMDAsIDB4MzAzZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7SGlyYWdhbmEmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgSElSQUdBTkEgPSBuZXcgVW5pY29kZUJsb2NrKCJISVJBR0FOQSIsIDB4MzA0MCwgMHgzMDlmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtLYXRha2FuYSZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBLQVRBS0FOQSA9IG5ldyBVbmljb2RlQmxvY2soIktBVEFLQU5BIiwgMHgzMGEwLCAweDMwZmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0JvcG9tb2ZvJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIEJPUE9NT0ZPID0gbmV3IFVuaWNvZGVCbG9jaygiQk9QT01PRk8iLCAweDMxMDAsIDB4MzEyZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7SGFuZ3VsIENvbXBhdGliaWxpdHkgSmFtbyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBIQU5HVUxfQ09NUEFUSUJJTElUWV9KQU1PID0gbmV3IFVuaWNvZGVCbG9jaygiSEFOR1VMX0NPTVBBVElCSUxJVFlfSkFNTyIsIDB4MzEzMCwgMHgzMThmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtLYW5idW4mcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgS0FOQlVOID0gbmV3IFVuaWNvZGVCbG9jaygiS0FOQlVOIiwgMHgzMTkwLCAweDMxOWYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0JvcG9tb2ZvIEV4dGVuZGVkJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjQKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIEJPUE9NT0ZPX0VYVEVOREVEID0gbmV3IFVuaWNvZGVCbG9jaygiQk9QT01PRk9fRVhURU5ERUQiLCAweDMxYTAsIDB4MzFiZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7S2F0YWthbmEgUGhvbmV0aWMgRXh0ZW5zaW9ucyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS41CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBLQVRBS0FOQV9QSE9ORVRJQ19FWFRFTlNJT05TID0gbmV3IFVuaWNvZGVCbG9jaygiS0FUQUtBTkFfUEhPTkVUSUNfRVhURU5TSU9OUyIsIDB4MzFmMCwgMHgzMWZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtFbmNsb3NlZCBDSksgTGV0dGVycyBhbmQgTW9udGhzJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIEVOQ0xPU0VEX0NKS19MRVRURVJTX0FORF9NT05USFMgPSBuZXcgVW5pY29kZUJsb2NrKCJFTkNMT1NFRF9DSktfTEVUVEVSU19BTkRfTU9OVEhTIiwgMHgzMjAwLCAweDMyZmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0NKSyBDb21wYXRpYmlsaXR5JnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIENKS19DT01QQVRJQklMSVRZID0gbmV3IFVuaWNvZGVCbG9jaygiQ0pLX0NPTVBBVElCSUxJVFkiLCAweDMzMDAsIDB4MzNmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7Q0pLIFVuaWZpZWQgSWRlb2dyYXBocyBFeHRlbnNpb24gQSZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS40CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBDSktfVU5JRklFRF9JREVPR1JBUEhTX0VYVEVOU0lPTl9BID0gbmV3IFVuaWNvZGVCbG9jaygiQ0pLX1VOSUZJRURfSURFT0dSQVBIU19FWFRFTlNJT05fQSIsIDB4MzQwMCwgMHg0ZGJmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtZaWppbmcgSGV4YWdyYW0gU3ltYm9scyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS41CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBZSUpJTkdfSEVYQUdSQU1fU1lNQk9MUyA9IG5ldyBVbmljb2RlQmxvY2soIllJSklOR19IRVhBR1JBTV9TWU1CT0xTIiwgMHg0ZGMwLCAweDRkZmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0NKSyBVbmlmaWVkIElkZW9ncmFwaHMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgQ0pLX1VOSUZJRURfSURFT0dSQVBIUyA9IG5ldyBVbmljb2RlQmxvY2soIkNKS19VTklGSUVEX0lERU9HUkFQSFMiLCAweDRlMDAsIDB4OWZmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7WWkgU3lsbGFibGVzJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjQKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIFlJX1NZTExBQkxFUyA9IG5ldyBVbmljb2RlQmxvY2soIllJX1NZTExBQkxFUyIsIDB4YTAwMCwgMHhhNDhmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtZaSBSYWRpY2FscyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS40CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBZSV9SQURJQ0FMUyA9IG5ldyBVbmljb2RlQmxvY2soIllJX1JBRElDQUxTIiwgMHhhNDkwLCAweGE0Y2YpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0hhbmd1bCBTeWxsYWJsZXMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgSEFOR1VMX1NZTExBQkxFUyA9IG5ldyBVbmljb2RlQmxvY2soIkhBTkdVTF9TWUxMQUJMRVMiLCAweGFjMDAsIDB4ZDdhZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7SGlnaCBTdXJyb2dhdGVzJnF1b3Q7IFVuaWNvZGUgQmxvY2suIFRoaXMgYmxvY2sgcmVwcmVzZW50cworICAgICAgICAgKiBjb2RlIHBvaW50IHZhbHVlcyBpbiB0aGUgaGlnaCBzdXJyb2dhdGUgcmFuZ2UgMHhEODAwIHRvIDB4REI3RgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgSElHSF9TVVJST0dBVEVTID0gbmV3IFVuaWNvZGVCbG9jaygiSElHSF9TVVJST0dBVEVTIiwgMHhkODAwLCAweGRiN2YpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0hpZ2ggUHJpdmF0ZSBVc2UgU3Vycm9nYXRlcyZxdW90OyBVbmljb2RlIEJsb2NrLiBUaGlzIGJsb2NrCisgICAgICAgICAqIHJlcHJlc2VudHMgY29kZSBwb2ludCB2YWx1ZXMgaW4gdGhlIGhpZ2ggc3Vycm9nYXRlIHJhbmdlIDB4REI4MCB0bworICAgICAgICAgKiAweERCRkYKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIEhJR0hfUFJJVkFURV9VU0VfU1VSUk9HQVRFUyA9IG5ldyBVbmljb2RlQmxvY2soIkhJR0hfUFJJVkFURV9VU0VfU1VSUk9HQVRFUyIsIDB4ZGI4MCwgMHhkYmZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtMb3cgU3Vycm9nYXRlcyZxdW90OyBVbmljb2RlIEJsb2NrLiBUaGlzIGJsb2NrIHJlcHJlc2VudHMKKyAgICAgICAgICogY29kZSBwb2ludCB2YWx1ZXMgaW4gdGhlIGxvdyBzdXJyb2dhdGUgcmFuZ2UgMHhEQzAwIHRvIDB4REZGRgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgTE9XX1NVUlJPR0FURVMgPSBuZXcgVW5pY29kZUJsb2NrKCJMT1dfU1VSUk9HQVRFUyIsIDB4ZGMwMCwgMHhkZmZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtQcml2YXRlIFVzZSBBcmVhJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIFBSSVZBVEVfVVNFX0FSRUEgPSBuZXcgVW5pY29kZUJsb2NrKCJQUklWQVRFX1VTRV9BUkVBIiwgMHhlMDAwLCAweGY4ZmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0NKSyBDb21wYXRpYmlsaXR5IElkZW9ncmFwaHMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgQ0pLX0NPTVBBVElCSUxJVFlfSURFT0dSQVBIUyA9IG5ldyBVbmljb2RlQmxvY2soIkNKS19DT01QQVRJQklMSVRZX0lERU9HUkFQSFMiLCAweGY5MDAsIDB4ZmFmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7QWxwaGFiZXRpYyBQcmVzZW50YXRpb24gRm9ybXMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgQUxQSEFCRVRJQ19QUkVTRU5UQVRJT05fRk9STVMgPSBuZXcgVW5pY29kZUJsb2NrKCJBTFBIQUJFVElDX1BSRVNFTlRBVElPTl9GT1JNUyIsIDB4ZmIwMCwgMHhmYjRmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtBcmFiaWMgUHJlc2VudGF0aW9uIEZvcm1zLUEmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgQVJBQklDX1BSRVNFTlRBVElPTl9GT1JNU19BID0gbmV3IFVuaWNvZGVCbG9jaygiQVJBQklDX1BSRVNFTlRBVElPTl9GT1JNU19BIiwgMHhmYjUwLCAweGZkZmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O1ZhcmlhdGlvbiBTZWxlY3RvcnMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgVkFSSUFUSU9OX1NFTEVDVE9SUyA9IG5ldyBVbmljb2RlQmxvY2soIlZBUklBVElPTl9TRUxFQ1RPUlMiLCAweGZlMDAsIDB4ZmUwZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7Q29tYmluaW5nIEhhbGYgTWFya3MmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgQ09NQklOSU5HX0hBTEZfTUFSS1MgPSBuZXcgVW5pY29kZUJsb2NrKCJDT01CSU5JTkdfSEFMRl9NQVJLUyIsIDB4ZmUyMCwgMHhmZTJmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtDSksgQ29tcGF0aWJpbGl0eSBGb3JtcyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBDSktfQ09NUEFUSUJJTElUWV9GT1JNUyA9IG5ldyBVbmljb2RlQmxvY2soIkNKS19DT01QQVRJQklMSVRZX0ZPUk1TIiwgMHhmZTMwLCAweGZlNGYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O1NtYWxsIEZvcm0gVmFyaWFudHMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuMgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgU01BTExfRk9STV9WQVJJQU5UUyA9IG5ldyBVbmljb2RlQmxvY2soIlNNQUxMX0ZPUk1fVkFSSUFOVFMiLCAweGZlNTAsIDB4ZmU2Zik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7QXJhYmljIFByZXNlbnRhdGlvbiBGb3Jtcy1CJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIEFSQUJJQ19QUkVTRU5UQVRJT05fRk9STVNfQiA9IG5ldyBVbmljb2RlQmxvY2soIkFSQUJJQ19QUkVTRU5UQVRJT05fRk9STVNfQiIsIDB4ZmU3MCwgMHhmZWZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtIYWxmd2lkdGggYW5kIEZ1bGx3aWR0aCBGb3JtcyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS4yCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBIQUxGV0lEVEhfQU5EX0ZVTExXSURUSF9GT1JNUyA9IG5ldyBVbmljb2RlQmxvY2soIkhBTEZXSURUSF9BTkRfRlVMTFdJRFRIX0ZPUk1TIiwgMHhmZjAwLCAweGZmZWYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O1NwZWNpYWxzJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIFNQRUNJQUxTID0gbmV3IFVuaWNvZGVCbG9jaygiU1BFQ0lBTFMiLCAweGZmZjAsIDB4ZmZmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7TGluZWFyIEIgU3lsbGFiYXJ5JnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjIKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIExJTkVBUl9CX1NZTExBQkFSWSA9IG5ldyBVbmljb2RlQmxvY2soIkxJTkVBUl9CX1NZTExBQkFSWSIsIDB4MTAwMDAsIDB4MTAwN2YpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0xpbmVhciBCIElkZW9ncmFtcyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS41CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBMSU5FQVJfQl9JREVPR1JBTVMgPSBuZXcgVW5pY29kZUJsb2NrKCJMSU5FQVJfQl9JREVPR1JBTVMiLCAweDEwMDgwLCAweDEwMGZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtBZWdlYW4gTnVtYmVycyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS41CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBBRUdFQU5fTlVNQkVSUyA9IG5ldyBVbmljb2RlQmxvY2soIkFFR0VBTl9OVU1CRVJTIiwgMHgxMDEwMCwgMHgxMDEzZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7T2xkIEl0YWxpYyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS41CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBPTERfSVRBTElDID0gbmV3IFVuaWNvZGVCbG9jaygiT0xEX0lUQUxJQyIsIDB4MTAzMDAsIDB4MTAzMmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0dvdGhpYyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS41CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBHT1RISUMgPSBuZXcgVW5pY29kZUJsb2NrKCJHT1RISUMiLCAweDEwMzMwLCAweDEwMzRmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtVZ2FyaXRpYyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS41CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBVR0FSSVRJQyA9IG5ldyBVbmljb2RlQmxvY2soIlVHQVJJVElDIiwgMHgxMDM4MCwgMHgxMDM5Zik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7RGVzZXJldCZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS41CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBERVNFUkVUID0gbmV3IFVuaWNvZGVCbG9jaygiREVTRVJFVCIsIDB4MTA0MDAsIDB4MTA0NGYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O1NoYXZpYW4mcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgU0hBVklBTiA9IG5ldyBVbmljb2RlQmxvY2soIlNIQVZJQU4iLCAweDEwNDUwLCAweDEwNDdmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtPc21hbnlhJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjUKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIE9TTUFOWUEgPSBuZXcgVW5pY29kZUJsb2NrKCJPU01BTllBIiwgMHgxMDQ4MCwgMHgxMDRhZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7Q3lwcmlvdCBTeWxsYWJhcnkmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgQ1lQUklPVF9TWUxMQUJBUlkgPSBuZXcgVW5pY29kZUJsb2NrKCJDWVBSSU9UX1NZTExBQkFSWSIsIDB4MTA4MDAsIDB4MTA4M2YpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O0J5emFudGluZSBNdXNpY2FsIFN5bWJvbHMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgQllaQU5USU5FX01VU0lDQUxfU1lNQk9MUyA9IG5ldyBVbmljb2RlQmxvY2soIkJZWkFOVElORV9NVVNJQ0FMX1NZTUJPTFMiLCAweDFkMDAwLCAweDFkMGZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtNdXNpY2FsIFN5bWJvbHMmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgTVVTSUNBTF9TWU1CT0xTID0gbmV3IFVuaWNvZGVCbG9jaygiTVVTSUNBTF9TWU1CT0xTIiwgMHgxZDEwMCwgMHgxZDFmZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7VGFpIFh1YW4gSmluZyBTeW1ib2xzJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjUKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIFRBSV9YVUFOX0pJTkdfU1lNQk9MUyA9IG5ldyBVbmljb2RlQmxvY2soIlRBSV9YVUFOX0pJTkdfU1lNQk9MUyIsIDB4MWQzMDAsIDB4MWQzNWYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O01hdGhlbWF0aWNhbCBBbHBoYW51bWVyaWMgU3ltYm9scyZxdW90OyBVbmljb2RlIEJsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAc2luY2UgMS41CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFVuaWNvZGVCbG9jayBNQVRIRU1BVElDQUxfQUxQSEFOVU1FUklDX1NZTUJPTFMgPSBuZXcgVW5pY29kZUJsb2NrKCJNQVRIRU1BVElDQUxfQUxQSEFOVU1FUklDX1NZTUJPTFMiLCAweDFkNDAwLCAweDFkN2ZmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtDSksgVW5pZmllZCBJZGVvZ3JhcGhzIEV4dGVuc2lvbiBCJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjUKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIENKS19VTklGSUVEX0lERU9HUkFQSFNfRVhURU5TSU9OX0IgPSBuZXcgVW5pY29kZUJsb2NrKCJDSktfVU5JRklFRF9JREVPR1JBUEhTX0VYVEVOU0lPTl9CIiwgMHgyMDAwMCwgMHgyYTZkZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7Q0pLIENvbXBhdGliaWxpdHkgSWRlb2dyYXBocyBTdXBwbGVtZW50JnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjUKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIENKS19DT01QQVRJQklMSVRZX0lERU9HUkFQSFNfU1VQUExFTUVOVCA9IG5ldyBVbmljb2RlQmxvY2soIkNKS19DT01QQVRJQklMSVRZX0lERU9HUkFQSFNfU1VQUExFTUVOVCIsIDB4MmY4MDAsIDB4MmZhMWYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O1RhZ3MmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgVEFHUyA9IG5ldyBVbmljb2RlQmxvY2soIlRBR1MiLCAweGUwMDAwLCAweGUwMDdmKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSAmcXVvdDtWYXJpYXRpb24gU2VsZWN0b3JzIFN1cHBsZW1lbnQmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgVkFSSUFUSU9OX1NFTEVDVE9SU19TVVBQTEVNRU5UID0gbmV3IFVuaWNvZGVCbG9jaygiVkFSSUFUSU9OX1NFTEVDVE9SU19TVVBQTEVNRU5UIiwgMHhlMDEwMCwgMHhlMDFlZik7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgJnF1b3Q7U3VwcGxlbWVudGFyeSBQcml2YXRlIFVzZSBBcmVhLUEmcXVvdDsgVW5pY29kZSBCbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbmljb2RlQmxvY2sgU1VQUExFTUVOVEFSWV9QUklWQVRFX1VTRV9BUkVBX0EgPSBuZXcgVW5pY29kZUJsb2NrKCJTVVBQTEVNRU5UQVJZX1BSSVZBVEVfVVNFX0FSRUFfQSIsIDB4ZjAwMDAsIDB4ZmZmZmYpOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlICZxdW90O1N1cHBsZW1lbnRhcnkgUHJpdmF0ZSBVc2UgQXJlYS1CJnF1b3Q7IFVuaWNvZGUgQmxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEBzaW5jZSAxLjUKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVW5pY29kZUJsb2NrIFNVUFBMRU1FTlRBUllfUFJJVkFURV9VU0VfQVJFQV9CID0gbmV3IFVuaWNvZGVCbG9jaygiU1VQUExFTUVOVEFSWV9QUklWQVRFX1VTRV9BUkVBX0IiLCAweDEwMDAwMCwgMHgxMGZmZmYpOworCisgICAgICAgIC8qCisgICAgICAgICAqIEFsbCBvZiB0aGUgVW5pY29kZUJsb2NrcyB3aXRoIHZhbGlkIHJhbmdlcyBpbiBhc2NlbmRpbmcgb3JkZXIuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIHN0YXRpYyBVbmljb2RlQmxvY2tbXSBCTE9DS1MgPSBuZXcgVW5pY29kZUJsb2NrW10geworICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5CQVNJQ19MQVRJTiwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5MQVRJTl8xX1NVUFBMRU1FTlQsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suTEFUSU5fRVhURU5ERURfQSwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5MQVRJTl9FWFRFTkRFRF9CLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLklQQV9FWFRFTlNJT05TLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLlNQQUNJTkdfTU9ESUZJRVJfTEVUVEVSUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5DT01CSU5JTkdfRElBQ1JJVElDQUxfTUFSS1MsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suR1JFRUssCisgICAgICAgICAgICBVbmljb2RlQmxvY2suQ1lSSUxMSUMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suQVJNRU5JQU4sCisgICAgICAgICAgICBVbmljb2RlQmxvY2suSEVCUkVXLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLkFSQUJJQywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5TWVJJQUMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suVEhBQU5BLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLkRFVkFOQUdBUkksCisgICAgICAgICAgICBVbmljb2RlQmxvY2suQkVOR0FMSSwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5HVVJNVUtISSwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5HVUpBUkFUSSwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5PUklZQSwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5UQU1JTCwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5URUxVR1UsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suS0FOTkFEQSwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5NQUxBWUFMQU0sCisgICAgICAgICAgICBVbmljb2RlQmxvY2suU0lOSEFMQSwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5USEFJLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLkxBTywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5USUJFVEFOLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLk1ZQU5NQVIsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suR0VPUkdJQU4sCisgICAgICAgICAgICBVbmljb2RlQmxvY2suSEFOR1VMX0pBTU8sCisgICAgICAgICAgICBVbmljb2RlQmxvY2suRVRISU9QSUMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suQ0hFUk9LRUUsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suVU5JRklFRF9DQU5BRElBTl9BQk9SSUdJTkFMX1NZTExBQklDUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5PR0hBTSwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5SVU5JQywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5LSE1FUiwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5NT05HT0xJQU4sCisgICAgICAgICAgICBVbmljb2RlQmxvY2suTEFUSU5fRVhURU5ERURfQURESVRJT05BTCwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5HUkVFS19FWFRFTkRFRCwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5HRU5FUkFMX1BVTkNUVUFUSU9OLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLlNVUEVSU0NSSVBUU19BTkRfU1VCU0NSSVBUUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5DVVJSRU5DWV9TWU1CT0xTLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLkNPTUJJTklOR19NQVJLU19GT1JfU1lNQk9MUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5MRVRURVJMSUtFX1NZTUJPTFMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suTlVNQkVSX0ZPUk1TLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLkFSUk9XUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5NQVRIRU1BVElDQUxfT1BFUkFUT1JTLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLk1JU0NFTExBTkVPVVNfVEVDSE5JQ0FMLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLkNPTlRST0xfUElDVFVSRVMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suT1BUSUNBTF9DSEFSQUNURVJfUkVDT0dOSVRJT04sCisgICAgICAgICAgICBVbmljb2RlQmxvY2suRU5DTE9TRURfQUxQSEFOVU1FUklDUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5CT1hfRFJBV0lORywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5CTE9DS19FTEVNRU5UUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5HRU9NRVRSSUNfU0hBUEVTLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLk1JU0NFTExBTkVPVVNfU1lNQk9MUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5ESU5HQkFUUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5CUkFJTExFX1BBVFRFUk5TLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLkNKS19SQURJQ0FMU19TVVBQTEVNRU5ULAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLktBTkdYSV9SQURJQ0FMUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5JREVPR1JBUEhJQ19ERVNDUklQVElPTl9DSEFSQUNURVJTLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLkNKS19TWU1CT0xTX0FORF9QVU5DVFVBVElPTiwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5ISVJBR0FOQSwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5LQVRBS0FOQSwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5CT1BPTU9GTywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5IQU5HVUxfQ09NUEFUSUJJTElUWV9KQU1PLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLktBTkJVTiwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5CT1BPTU9GT19FWFRFTkRFRCwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5FTkNMT1NFRF9DSktfTEVUVEVSU19BTkRfTU9OVEhTLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLkNKS19DT01QQVRJQklMSVRZLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLkNKS19VTklGSUVEX0lERU9HUkFQSFNfRVhURU5TSU9OX0EsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suQ0pLX1VOSUZJRURfSURFT0dSQVBIUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5ZSV9TWUxMQUJMRVMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suWUlfUkFESUNBTFMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suSEFOR1VMX1NZTExBQkxFUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5ISUdIX1NVUlJPR0FURVMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suSElHSF9QUklWQVRFX1VTRV9TVVJST0dBVEVTLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLkxPV19TVVJST0dBVEVTLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLlBSSVZBVEVfVVNFX0FSRUEsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suQ0pLX0NPTVBBVElCSUxJVFlfSURFT0dSQVBIUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5BTFBIQUJFVElDX1BSRVNFTlRBVElPTl9GT1JNUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5BUkFCSUNfUFJFU0VOVEFUSU9OX0ZPUk1TX0EsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suQ09NQklOSU5HX0hBTEZfTUFSS1MsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suQ0pLX0NPTVBBVElCSUxJVFlfRk9STVMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suU01BTExfRk9STV9WQVJJQU5UUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5BUkFCSUNfUFJFU0VOVEFUSU9OX0ZPUk1TX0IsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suU1BFQ0lBTFMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suSEFMRldJRFRIX0FORF9GVUxMV0lEVEhfRk9STVMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suT0xEX0lUQUxJQywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5HT1RISUMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suREVTRVJFVCwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5CWVpBTlRJTkVfTVVTSUNBTF9TWU1CT0xTLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLk1VU0lDQUxfU1lNQk9MUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5NQVRIRU1BVElDQUxfQUxQSEFOVU1FUklDX1NZTUJPTFMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suQ0pLX1VOSUZJRURfSURFT0dSQVBIU19FWFRFTlNJT05fQiwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5DSktfQ09NUEFUSUJJTElUWV9JREVPR1JBUEhTX1NVUFBMRU1FTlQsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suVEFHUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5DWVJJTExJQ19TVVBQTEVNRU5UQVJZLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLlRBR0FMT0csCisgICAgICAgICAgICBVbmljb2RlQmxvY2suSEFOVU5PTywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5CVUhJRCwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5UQUdCQU5XQSwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5NSVNDRUxMQU5FT1VTX01BVEhFTUFUSUNBTF9TWU1CT0xTX0EsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suU1VQUExFTUVOVEFMX0FSUk9XU19BLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLlNVUFBMRU1FTlRBTF9BUlJPV1NfQiwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5NSVNDRUxMQU5FT1VTX01BVEhFTUFUSUNBTF9TWU1CT0xTX0IsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suU1VQUExFTUVOVEFMX01BVEhFTUFUSUNBTF9PUEVSQVRPUlMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suS0FUQUtBTkFfUEhPTkVUSUNfRVhURU5TSU9OUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5WQVJJQVRJT05fU0VMRUNUT1JTLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLlNVUFBMRU1FTlRBUllfUFJJVkFURV9VU0VfQVJFQV9BLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLlNVUFBMRU1FTlRBUllfUFJJVkFURV9VU0VfQVJFQV9CLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLkxJTUJVLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLlRBSV9MRSwKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5LSE1FUl9TWU1CT0xTLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLlBIT05FVElDX0VYVEVOU0lPTlMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suTUlTQ0VMTEFORU9VU19TWU1CT0xTX0FORF9BUlJPV1MsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suWUlKSU5HX0hFWEFHUkFNX1NZTUJPTFMsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suTElORUFSX0JfU1lMTEFCQVJZLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLkxJTkVBUl9CX0lERU9HUkFNUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5BRUdFQU5fTlVNQkVSUywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5VR0FSSVRJQywKKyAgICAgICAgICAgIFVuaWNvZGVCbG9jay5TSEFWSUFOLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLk9TTUFOWUEsCisgICAgICAgICAgICBVbmljb2RlQmxvY2suQ1lQUklPVF9TWUxMQUJBUlksCisgICAgICAgICAgICBVbmljb2RlQmxvY2suVEFJX1hVQU5fSklOR19TWU1CT0xTLAorICAgICAgICAgICAgVW5pY29kZUJsb2NrLlZBUklBVElPTl9TRUxFQ1RPUlNfU1VQUExFTUVOVAorICAgICAgICB9OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXRyaWV2ZXMgdGhlIGNvbnN0YW50IHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIHNwZWNpZmllZCBibG9jayBuYW1lLgorICAgICAgICAgKiBUaGUgYmxvY2sgbmFtZXMgYXJlIGRlZmluZWQgYnkgdGhlIFVuaWNvZGUgNC4wLjEgc3BlY2lmaWNhdGlvbiBpbiB0aGUKKyAgICAgICAgICoge0Bjb2RlIEJsb2Nrcy00LjAuMS50eHR9IGZpbGUuCisgICAgICAgICAqIDxwPgorICAgICAgICAgKiBCbG9jayBuYW1lcyBtYXkgYmUgb25lIG9mIHRoZSBmb2xsb3dpbmc6CisgICAgICAgICAqIDx1bD4KKyAgICAgICAgICogPGxpPkNhbm9uaWNhbCBibG9jayBuYW1lLCBhcyBkZWZpbmVkIGJ5IHRoZSBVbmljb2RlIHNwZWNpZmljYXRpb247CisgICAgICAgICAqIGNhc2UtaW5zZW5zaXRpdmUuPC9saT4KKyAgICAgICAgICogPGxpPkNhbm9uaWNhbCBibG9jayBuYW1lIHdpdGhvdXQgYW55IHNwYWNlcywgYXMgZGVmaW5lZCBieSB0aGUKKyAgICAgICAgICogVW5pY29kZSBzcGVjaWZpY2F0aW9uOyBjYXNlLWluc2Vuc2l0aXZlLjwvbGk+CisgICAgICAgICAqIDxsaT57QGNvZGUgVW5pY29kZUJsb2NrfSBjb25zdGFudCBpZGVudGlmaWVyLiBUaGlzIGlzIGRldGVybWluZWQgYnkKKyAgICAgICAgICogdXBwZXJjYXNpbmcgdGhlIGNhbm9uaWNhbCBuYW1lIGFuZCByZXBsYWNpbmcgYWxsIHNwYWNlcyBhbmQgaHlwaGVucworICAgICAgICAgKiB3aXRoIHVuZGVyc2NvcmVzLjwvbGk+CisgICAgICAgICAqIDwvdWw+CisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBibG9ja05hbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgYmxvY2sgdG8gcmV0cmlldmUuCisgICAgICAgICAqIEByZXR1cm4gdGhlIFVuaWNvZGVCbG9jayBjb25zdGFudCBjb3JyZXNwb25kaW5nIHRvIHtAY29kZSBibG9ja05hbWV9LgorICAgICAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBibG9ja05hbWV9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGJsb2NrTmFtZX0gaXMgbm90IGEgdmFsaWQgYmxvY2sgbmFtZS4KKyAgICAgICAgICogQHNpbmNlIDEuNQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBVbmljb2RlQmxvY2sgZm9yTmFtZShTdHJpbmcgYmxvY2tOYW1lKSB7CisgICAgICAgICAgICBpZiAoYmxvY2tOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBibG9jayA9IGZvck5hbWVJbXBsKGJsb2NrTmFtZSk7CisgICAgICAgICAgICBpZiAoYmxvY2sgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICBpZiAoYmxvY2tOYW1lLmVxdWFscygiU1VSUk9HQVRFU19BUkVBIikpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNVUlJPR0FURVNfQVJFQTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYoYmxvY2tOYW1lLmVxdWFsc0lnbm9yZUNhc2UoImdyZWVrIikpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEdSRUVLOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZihibG9ja05hbWUuZXF1YWxzKCJDT01CSU5JTkdfTUFSS1NfRk9SX1NZTUJPTFMiKSB8fAorICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tOYW1lLmVxdWFscygiQ29tYmluaW5nIE1hcmtzIGZvciBTeW1ib2xzIikgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrTmFtZS5lcXVhbHMoIkNvbWJpbmluZ01hcmtzZm9yU3ltYm9scyIpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBDT01CSU5JTkdfTUFSS1NfRk9SX1NZTUJPTFM7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkJhZCBibG9jayBuYW1lOiAiICsgYmxvY2tOYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBCTE9DS1NbYmxvY2tdOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdGhlIGNvbnN0YW50IGZvciB0aGUgVW5pY29kZSBibG9jayB0aGF0IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQKKyAgICAgICAgICogY2hhcmFjdGVyLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gYworICAgICAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgZm9yIHdoaWNoIHRvIGdldCB0aGUge0Bjb2RlIFVuaWNvZGVCbG9ja30KKyAgICAgICAgICogICAgICAgICAgICBjb25zdGFudC4KKyAgICAgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFVuaWNvZGVCbG9ja30gY29uc3RhbnQgZm9yIHRoZSBibG9jayB0aGF0IGNvbnRhaW5zCisgICAgICAgICAqICAgICAgICAge0Bjb2RlIGN9LCBvciB7QGNvZGUgbnVsbH0gaWYge0Bjb2RlIGN9IGRvZXMgbm90IGJlbG9uZyB0bworICAgICAgICAgKiAgICAgICAgIGFueSBkZWZpbmVkIGJsb2NrLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBVbmljb2RlQmxvY2sgb2YoY2hhciBjKSB7CisgICAgICAgICAgICByZXR1cm4gb2YoKGludCkgYyk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogR2V0cyB0aGUgY29uc3RhbnQgZm9yIHRoZSBVbmljb2RlIGJsb2NrIHRoYXQgY29udGFpbnMgdGhlIHNwZWNpZmllZAorICAgICAgICAgKiBVbmljb2RlIGNvZGUgcG9pbnQuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBjb2RlUG9pbnQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgVW5pY29kZSBjb2RlIHBvaW50IGZvciB3aGljaCB0byBnZXQgdGhlCisgICAgICAgICAqICAgICAgICAgICAge0Bjb2RlIFVuaWNvZGVCbG9ja30gY29uc3RhbnQuCisgICAgICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBVbmljb2RlQmxvY2t9IGNvbnN0YW50IGZvciB0aGUgYmxvY2sgdGhhdCBjb250YWlucworICAgICAgICAgKiAgICAgICAgIHtAY29kZSBjb2RlUG9pbnR9LCBvciB7QGNvZGUgbnVsbH0gaWYge0Bjb2RlIGNvZGVQb2ludH0gZG9lcworICAgICAgICAgKiAgICAgICAgIG5vdCBiZWxvbmcgdG8gYW55IGRlZmluZWQgYmxvY2suCisgICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBjb2RlUG9pbnR9IGlzIG5vdCBhIHZhbGlkIGNvZGUgcG9pbnQuCisgICAgICAgICAqIEBzaW5jZSAxLjUKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgVW5pY29kZUJsb2NrIG9mKGludCBjb2RlUG9pbnQpIHsKKyAgICAgICAgICAgIGNoZWNrVmFsaWRDb2RlUG9pbnQoY29kZVBvaW50KTsKKyAgICAgICAgICAgIGludCBibG9jayA9IG9mSW1wbChjb2RlUG9pbnQpOworICAgICAgICAgICAgaWYgKGJsb2NrID09IC0xIHx8IGJsb2NrID49IEJMT0NLUy5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBCTE9DS1NbYmxvY2tdOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBVbmljb2RlQmxvY2soU3RyaW5nIGJsb2NrTmFtZSwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgICAgICBzdXBlcihibG9ja05hbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGludCBmb3JOYW1lSW1wbChTdHJpbmcgYmxvY2tOYW1lKTsKKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgb2ZJbXBsKGludCBjb2RlUG9pbnQpOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQ2hhcmFjdGVyfSB3aXRoIHRoZSBzcGVjaWZpZWQgcHJpbWl0aXZlIGNoYXIKKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHByaW1pdGl2ZSBjaGFyIHZhbHVlIHRvIHN0b3JlIGluIHRoZSBuZXcgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIENoYXJhY3RlcihjaGFyIHZhbHVlKSB7CisgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBwcmltaXRpdmUgdmFsdWUgb2YgdGhpcyBjaGFyYWN0ZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgb2JqZWN0J3MgcHJpbWl0aXZlIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBjaGFyIGNoYXJWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY2hlY2tWYWxpZENvZGVQb2ludChpbnQgY29kZVBvaW50KSB7CisgICAgICAgIGlmICghaXNWYWxpZENvZGVQb2ludChjb2RlUG9pbnQpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIGNvZGUgcG9pbnQ6ICIgKyBjb2RlUG9pbnQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBvYmplY3QgdG8gdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgb2JqZWN0IHRvIGRldGVybWluZSB0aGVpcgorICAgICAqIHJlbGF0aXZlIG9yZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyBvYmplY3QgdG8uCisgICAgICogQHJldHVybiB7QGNvZGUgMH0gaWYgdGhlIHZhbHVlIG9mIHRoaXMgY2hhcmFjdGVyIGFuZCB0aGUgdmFsdWUgb2YKKyAgICAgKiAgICAgICAgIHtAY29kZSBjfSBhcmUgZXF1YWw7IGEgcG9zaXRpdmUgdmFsdWUgaWYgdGhlIHZhbHVlIG9mIHRoaXMKKyAgICAgKiAgICAgICAgIGNoYXJhY3RlciBpcyBncmVhdGVyIHRoYW4gdGhlIHZhbHVlIG9mIHtAY29kZSBjfTsgYSBuZWdhdGl2ZQorICAgICAqICAgICAgICAgdmFsdWUgaWYgdGhlIHZhbHVlIG9mIHRoaXMgY2hhcmFjdGVyIGlzIGxlc3MgdGhhbiB0aGUgdmFsdWUgb2YKKyAgICAgKiAgICAgICAgIHtAY29kZSBjfS4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5Db21wYXJhYmxlCisgICAgICogQHNpbmNlIDEuMgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKENoYXJhY3RlciBjKSB7CisgICAgICAgIHJldHVybiBjb21wYXJlKHZhbHVlLCBjLnZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0d28ge0Bjb2RlIGNoYXJ9IHZhbHVlcy4KKyAgICAgKiBAcmV0dXJuIDAgaWYgbGhzID0gcmhzLCBsZXNzIHRoYW4gMCBpZiBsaHMgJmx0OyByaHMsIGFuZCBncmVhdGVyIHRoYW4gMCBpZiBsaHMgJmd0OyByaHMuCisgICAgICogQHNpbmNlIDEuNworICAgICAqIEBoaWRlIDEuNworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXBhcmUoY2hhciBsaHMsIGNoYXIgcmhzKSB7CisgICAgICAgIHJldHVybiBsaHMgLSByaHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBDaGFyYWN0ZXJ9IGluc3RhbmNlIGZvciB0aGUge0Bjb2RlIGNoYXJ9IHZhbHVlIHBhc3NlZC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiBpdCBpcyBub3QgbmVjZXNzYXJ5IHRvIGdldCBhIG5ldyB7QGNvZGUgQ2hhcmFjdGVyfSBpbnN0YW5jZSwgaXQgaXMKKyAgICAgKiByZWNvbW1lbmRlZCB0byB1c2UgdGhpcyBtZXRob2QgaW5zdGVhZCBvZiB0aGUgY29uc3RydWN0b3IsIHNpbmNlIGl0CisgICAgICogbWFpbnRhaW5zIGEgY2FjaGUgb2YgaW5zdGFuY2VzIHdoaWNoIG1heSByZXN1bHQgaW4gYmV0dGVyIHBlcmZvcm1hbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyIHZhbHVlIGZvciB3aGljaCB0byBnZXQgYSB7QGNvZGUgQ2hhcmFjdGVyfSBpbnN0YW5jZS4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgQ2hhcmFjdGVyfSBpbnN0YW5jZSBmb3Ige0Bjb2RlIGN9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIENoYXJhY3RlciB2YWx1ZU9mKGNoYXIgYykgeworICAgICAgICByZXR1cm4gYyA8IDEyOCA/IFNNQUxMX1ZBTFVFU1tjXSA6IG5ldyBDaGFyYWN0ZXIoYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBjYWNoZSBvZiBpbnN0YW5jZXMgdXNlZCBieSB7QGxpbmsgI3ZhbHVlT2YoY2hhcil9IGFuZCBhdXRvLWJveGluZworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENoYXJhY3RlcltdIFNNQUxMX1ZBTFVFUyA9IG5ldyBDaGFyYWN0ZXJbMTI4XTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTI4OyBpKyspIHsKKyAgICAgICAgICAgIFNNQUxMX1ZBTFVFU1tpXSA9IG5ldyBDaGFyYWN0ZXIoKGNoYXIpIGkpOworICAgICAgICB9CisgICAgfQorICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHtAY29kZSBjb2RlUG9pbnR9IGlzIGEgdmFsaWQgVW5pY29kZSBjb2RlIHBvaW50LgorICAgICAqCisgICAgICogQHBhcmFtIGNvZGVQb2ludAorICAgICAqICAgICAgICAgICAgdGhlIGNvZGUgcG9pbnQgdG8gdGVzdC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgY29kZVBvaW50fSBpcyBhIHZhbGlkIFVuaWNvZGUgY29kZSBwb2ludDsKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNWYWxpZENvZGVQb2ludChpbnQgY29kZVBvaW50KSB7CisgICAgICAgIHJldHVybiAoTUlOX0NPREVfUE9JTlQgPD0gY29kZVBvaW50ICYmIE1BWF9DT0RFX1BPSU5UID49IGNvZGVQb2ludCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIge0Bjb2RlIGNvZGVQb2ludH0gaXMgd2l0aGluIHRoZSBzdXBwbGVtZW50YXJ5IGNvZGUKKyAgICAgKiBwb2ludCByYW5nZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2RlUG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2RlIHBvaW50IHRvIHRlc3QuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGNvZGVQb2ludH0gaXMgd2l0aGluIHRoZSBzdXBwbGVtZW50YXJ5CisgICAgICogICAgICAgICBjb2RlIHBvaW50IHJhbmdlOyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzU3VwcGxlbWVudGFyeUNvZGVQb2ludChpbnQgY29kZVBvaW50KSB7CisgICAgICAgIHJldHVybiAoTUlOX1NVUFBMRU1FTlRBUllfQ09ERV9QT0lOVCA8PSBjb2RlUG9pbnQgJiYgTUFYX0NPREVfUE9JTlQgPj0gY29kZVBvaW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB7QGNvZGUgY2h9IGlzIGEgaGlnaC0gKG9yIGxlYWRpbmctKSBzdXJyb2dhdGUgY29kZSB1bml0CisgICAgICogdGhhdCBpcyB1c2VkIGZvciByZXByZXNlbnRpbmcgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIGluIFVURi0xNgorICAgICAqIGVuY29kaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIGNoCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIHRlc3QuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGNofSBpcyBhIGhpZ2gtc3Vycm9nYXRlIGNvZGUgdW5pdDsKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgI2lzTG93U3Vycm9nYXRlKGNoYXIpCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0hpZ2hTdXJyb2dhdGUoY2hhciBjaCkgeworICAgICAgICByZXR1cm4gKE1JTl9ISUdIX1NVUlJPR0FURSA8PSBjaCAmJiBNQVhfSElHSF9TVVJST0dBVEUgPj0gY2gpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHtAY29kZSBjaH0gaXMgYSBsb3ctIChvciB0cmFpbGluZy0pIHN1cnJvZ2F0ZSBjb2RlIHVuaXQKKyAgICAgKiB0aGF0IGlzIHVzZWQgZm9yIHJlcHJlc2VudGluZyBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcnMgaW4gVVRGLTE2CisgICAgICogZW5jb2RpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2gKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gdGVzdC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgY2h9IGlzIGEgbG93LXN1cnJvZ2F0ZSBjb2RlIHVuaXQ7CisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNpc0hpZ2hTdXJyb2dhdGUoY2hhcikKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTG93U3Vycm9nYXRlKGNoYXIgY2gpIHsKKyAgICAgICAgcmV0dXJuIChNSU5fTE9XX1NVUlJPR0FURSA8PSBjaCAmJiBNQVhfTE9XX1NVUlJPR0FURSA+PSBjaCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgd2hldGhlciB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGlzIGEgaGlnaCBvciBsb3cgc3Vycm9nYXRlLgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNTdXJyb2dhdGUoY2hhciBjaCkgeworICAgICAgICByZXR1cm4gY2ggPj0gTUlOX1NVUlJPR0FURSAmJiBjaCA8PSBNQVhfU1VSUk9HQVRFOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIHBhaXIgaXMgYSB2YWxpZCBzdXJyb2dhdGUgcGFpci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBoaWdoCisgICAgICogICAgICAgICAgICB0aGUgaGlnaCBzdXJyb2dhdGUgdW5pdCB0byB0ZXN0LgorICAgICAqIEBwYXJhbSBsb3cKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb3cgc3Vycm9nYXRlIHVuaXQgdG8gdGVzdC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgaGlnaH0gaXMgYSBoaWdoLXN1cnJvZ2F0ZSBjb2RlIHVuaXQgYW5kCisgICAgICogICAgICAgICB7QGNvZGUgbG93fSBpcyBhIGxvdy1zdXJyb2dhdGUgY29kZSB1bml0OyB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHNlZSAjaXNIaWdoU3Vycm9nYXRlKGNoYXIpCisgICAgICogQHNlZSAjaXNMb3dTdXJyb2dhdGUoY2hhcikKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzU3Vycm9nYXRlUGFpcihjaGFyIGhpZ2gsIGNoYXIgbG93KSB7CisgICAgICAgIHJldHVybiAoaXNIaWdoU3Vycm9nYXRlKGhpZ2gpICYmIGlzTG93U3Vycm9nYXRlKGxvdykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGN1bGF0ZXMgdGhlIG51bWJlciBvZiB7QGNvZGUgY2hhcn0gdmFsdWVzIHJlcXVpcmVkIHRvIHJlcHJlc2VudCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgVW5pY29kZSBjb2RlIHBvaW50LiBUaGlzIG1ldGhvZCBjaGVja3MgaWYgdGhlIHtAY29kZSBjb2RlUG9pbnR9CisgICAgICogaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHtAY29kZSAweDEwMDAwfSwgaW4gd2hpY2ggY2FzZSB7QGNvZGUgMn0gaXMKKyAgICAgKiByZXR1cm5lZCwgb3RoZXJ3aXNlIHtAY29kZSAxfS4gVG8gdGVzdCBpZiB0aGUgY29kZSBwb2ludCBpcyB2YWxpZCwgdXNlCisgICAgICogdGhlIHtAbGluayAjaXNWYWxpZENvZGVQb2ludChpbnQpfSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29kZVBvaW50CisgICAgICogICAgICAgICAgICB0aGUgY29kZSBwb2ludCBmb3Igd2hpY2ggdG8gY2FsY3VsYXRlIHRoZSBudW1iZXIgb2YgcmVxdWlyZWQKKyAgICAgKiAgICAgICAgICAgIGNoYXJzLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIDJ9IGlmIHtAY29kZSBjb2RlUG9pbnQgPj0gMHgxMDAwMH07IHtAY29kZSAxfSBvdGhlcndpc2UuCisgICAgICogQHNlZSAjaXNWYWxpZENvZGVQb2ludChpbnQpCisgICAgICogQHNlZSAjaXNTdXBwbGVtZW50YXJ5Q29kZVBvaW50KGludCkKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgY2hhckNvdW50KGludCBjb2RlUG9pbnQpIHsKKyAgICAgICAgcmV0dXJuIChjb2RlUG9pbnQgPj0gMHgxMDAwMCA/IDIgOiAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyBhIHN1cnJvZ2F0ZSBwYWlyIGludG8gYSBVbmljb2RlIGNvZGUgcG9pbnQuIFRoaXMgbWV0aG9kIGFzc3VtZXMKKyAgICAgKiB0aGF0IHRoZSBwYWlyIGFyZSB2YWxpZCBzdXJyb2dhdGVzLiBJZiB0aGUgcGFpciBhcmUgPGk+bm90PC9pPiB2YWxpZAorICAgICAqIHN1cnJvZ2F0ZXMsIHRoZW4gdGhlIHJlc3VsdCBpcyBpbmRldGVybWluYXRlLiBUaGUKKyAgICAgKiB7QGxpbmsgI2lzU3Vycm9nYXRlUGFpcihjaGFyLCBjaGFyKX0gbWV0aG9kIHNob3VsZCBiZSB1c2VkIHByaW9yIHRvIHRoaXMKKyAgICAgKiBtZXRob2QgdG8gdmFsaWRhdGUgdGhlIHBhaXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaGlnaAorICAgICAqICAgICAgICAgICAgdGhlIGhpZ2ggc3Vycm9nYXRlIHVuaXQuCisgICAgICogQHBhcmFtIGxvdworICAgICAqICAgICAgICAgICAgdGhlIGxvdyBzdXJyb2dhdGUgdW5pdC4KKyAgICAgKiBAcmV0dXJuIHRoZSBVbmljb2RlIGNvZGUgcG9pbnQgY29ycmVzcG9uZGluZyB0byB0aGUgc3Vycm9nYXRlIHVuaXQgcGFpci4KKyAgICAgKiBAc2VlICNpc1N1cnJvZ2F0ZVBhaXIoY2hhciwgY2hhcikKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgdG9Db2RlUG9pbnQoY2hhciBoaWdoLCBjaGFyIGxvdykgeworICAgICAgICAvLyBTZWUgUkZDIDI3ODEsIFNlY3Rpb24gMi4yCisgICAgICAgIC8vIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzI3ODEudHh0CisgICAgICAgIGludCBoID0gKGhpZ2ggJiAweDNGRikgPDwgMTA7CisgICAgICAgIGludCBsID0gbG93ICYgMHgzRkY7CisgICAgICAgIHJldHVybiAoaCB8IGwpICsgMHgxMDAwMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb2RlIHBvaW50IGF0IHtAY29kZSBpbmRleH0gaW4gdGhlIHNwZWNpZmllZCBzZXF1ZW5jZSBvZgorICAgICAqIGNoYXJhY3RlciB1bml0cy4gSWYgdGhlIHVuaXQgYXQge0Bjb2RlIGluZGV4fSBpcyBhIGhpZ2gtc3Vycm9nYXRlIHVuaXQsCisgICAgICoge0Bjb2RlIGluZGV4ICsgMX0gaXMgbGVzcyB0aGFuIHRoZSBsZW5ndGggb2YgdGhlIHNlcXVlbmNlIGFuZCB0aGUgdW5pdCBhdAorICAgICAqIHtAY29kZSBpbmRleCArIDF9IGlzIGEgbG93LXN1cnJvZ2F0ZSB1bml0LCB0aGVuIHRoZSBzdXBwbGVtZW50YXJ5IGNvZGUKKyAgICAgKiBwb2ludCByZXByZXNlbnRlZCBieSB0aGUgcGFpciBpcyByZXR1cm5lZDsgb3RoZXJ3aXNlIHRoZSB7QGNvZGUgY2hhcn0KKyAgICAgKiB2YWx1ZSBhdCB7QGNvZGUgaW5kZXh9IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIHNlcQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBzZXF1ZW5jZSBvZiB7QGNvZGUgY2hhcn0gdW5pdHMuCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcG9zaXRpb24gaW4ge0Bjb2RlIHNlcX0gZnJvbSB3aGljaCB0byByZXRyaWV2ZSB0aGUgY29kZQorICAgICAqICAgICAgICAgICAgcG9pbnQuCisgICAgICogQHJldHVybiB0aGUgVW5pY29kZSBjb2RlIHBvaW50IG9yIHtAY29kZSBjaGFyfSB2YWx1ZSBhdCB7QGNvZGUgaW5kZXh9IGluCisgICAgICogICAgICAgICB7QGNvZGUgc2VxfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHNlcX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgaW5kZXh9IGlzIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0bworICAgICAqICAgICAgICAgICAgIHRoZSBsZW5ndGggb2Yge0Bjb2RlIHNlcX0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGNvZGVQb2ludEF0KENoYXJTZXF1ZW5jZSBzZXEsIGludCBpbmRleCkgeworICAgICAgICBpZiAoc2VxID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGludCBsZW4gPSBzZXEubGVuZ3RoKCk7CisgICAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gbGVuKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgY2hhciBoaWdoID0gc2VxLmNoYXJBdChpbmRleCsrKTsKKyAgICAgICAgaWYgKGluZGV4ID49IGxlbikgeworICAgICAgICAgICAgcmV0dXJuIGhpZ2g7CisgICAgICAgIH0KKyAgICAgICAgY2hhciBsb3cgPSBzZXEuY2hhckF0KGluZGV4KTsKKyAgICAgICAgaWYgKGlzU3Vycm9nYXRlUGFpcihoaWdoLCBsb3cpKSB7CisgICAgICAgICAgICByZXR1cm4gdG9Db2RlUG9pbnQoaGlnaCwgbG93KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGlnaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb2RlIHBvaW50IGF0IHtAY29kZSBpbmRleH0gaW4gdGhlIHNwZWNpZmllZCBhcnJheSBvZgorICAgICAqIGNoYXJhY3RlciB1bml0cy4gSWYgdGhlIHVuaXQgYXQge0Bjb2RlIGluZGV4fSBpcyBhIGhpZ2gtc3Vycm9nYXRlIHVuaXQsCisgICAgICoge0Bjb2RlIGluZGV4ICsgMX0gaXMgbGVzcyB0aGFuIHRoZSBsZW5ndGggb2YgdGhlIGFycmF5IGFuZCB0aGUgdW5pdCBhdAorICAgICAqIHtAY29kZSBpbmRleCArIDF9IGlzIGEgbG93LXN1cnJvZ2F0ZSB1bml0LCB0aGVuIHRoZSBzdXBwbGVtZW50YXJ5IGNvZGUKKyAgICAgKiBwb2ludCByZXByZXNlbnRlZCBieSB0aGUgcGFpciBpcyByZXR1cm5lZDsgb3RoZXJ3aXNlIHRoZSB7QGNvZGUgY2hhcn0KKyAgICAgKiB2YWx1ZSBhdCB7QGNvZGUgaW5kZXh9IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIHNlcQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBhcnJheSBvZiB7QGNvZGUgY2hhcn0gdW5pdHMuCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcG9zaXRpb24gaW4ge0Bjb2RlIHNlcX0gZnJvbSB3aGljaCB0byByZXRyaWV2ZSB0aGUgY29kZQorICAgICAqICAgICAgICAgICAgcG9pbnQuCisgICAgICogQHJldHVybiB0aGUgVW5pY29kZSBjb2RlIHBvaW50IG9yIHtAY29kZSBjaGFyfSB2YWx1ZSBhdCB7QGNvZGUgaW5kZXh9IGluCisgICAgICogICAgICAgICB7QGNvZGUgc2VxfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHNlcX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgaW5kZXh9IGlzIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0bworICAgICAqICAgICAgICAgICAgIHRoZSBsZW5ndGggb2Yge0Bjb2RlIHNlcX0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGNvZGVQb2ludEF0KGNoYXJbXSBzZXEsIGludCBpbmRleCkgeworICAgICAgICBpZiAoc2VxID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGludCBsZW4gPSBzZXEubGVuZ3RoOworICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGxlbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGNoYXIgaGlnaCA9IHNlcVtpbmRleCsrXTsKKyAgICAgICAgaWYgKGluZGV4ID49IGxlbikgeworICAgICAgICAgICAgcmV0dXJuIGhpZ2g7CisgICAgICAgIH0KKyAgICAgICAgY2hhciBsb3cgPSBzZXFbaW5kZXhdOworICAgICAgICBpZiAoaXNTdXJyb2dhdGVQYWlyKGhpZ2gsIGxvdykpIHsKKyAgICAgICAgICAgIHJldHVybiB0b0NvZGVQb2ludChoaWdoLCBsb3cpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBoaWdoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNvZGUgcG9pbnQgYXQge0Bjb2RlIGluZGV4fSBpbiB0aGUgc3BlY2lmaWVkIGFycmF5IG9mCisgICAgICogY2hhcmFjdGVyIHVuaXRzLCB3aGVyZSB7QGNvZGUgaW5kZXh9IGhhcyB0byBiZSBsZXNzIHRoYW4ge0Bjb2RlIGxpbWl0fS4KKyAgICAgKiBJZiB0aGUgdW5pdCBhdCB7QGNvZGUgaW5kZXh9IGlzIGEgaGlnaC1zdXJyb2dhdGUgdW5pdCwge0Bjb2RlIGluZGV4ICsgMX0KKyAgICAgKiBpcyBsZXNzIHRoYW4ge0Bjb2RlIGxpbWl0fSBhbmQgdGhlIHVuaXQgYXQge0Bjb2RlIGluZGV4ICsgMX0gaXMgYQorICAgICAqIGxvdy1zdXJyb2dhdGUgdW5pdCwgdGhlbiB0aGUgc3VwcGxlbWVudGFyeSBjb2RlIHBvaW50IHJlcHJlc2VudGVkIGJ5IHRoZQorICAgICAqIHBhaXIgaXMgcmV0dXJuZWQ7IG90aGVyd2lzZSB0aGUge0Bjb2RlIGNoYXJ9IHZhbHVlIGF0IHtAY29kZSBpbmRleH0gaXMKKyAgICAgKiByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzZXEKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgYXJyYXkgb2Yge0Bjb2RlIGNoYXJ9IHVuaXRzLgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBvc2l0aW9uIGluIHtAY29kZSBzZXF9IGZyb20gd2hpY2ggdG8gZ2V0IHRoZSBjb2RlIHBvaW50LgorICAgICAqIEBwYXJhbSBsaW1pdAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGFmdGVyIHRoZSBsYXN0IHVuaXQgaW4ge0Bjb2RlIHNlcX0gdGhhdCBjYW4gYmUgdXNlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBVbmljb2RlIGNvZGUgcG9pbnQgb3Ige0Bjb2RlIGNoYXJ9IHZhbHVlIGF0IHtAY29kZSBpbmRleH0gaW4KKyAgICAgKiAgICAgICAgIHtAY29kZSBzZXF9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc2VxfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4IDwgMH0sIHtAY29kZSBpbmRleCA+PSBsaW1pdH0sCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGxpbWl0IDwgMH0gb3IgaWYge0Bjb2RlIGxpbWl0fSBpcyBncmVhdGVyIHRoYW4gdGhlCisgICAgICogICAgICAgICAgICAgbGVuZ3RoIG9mIHtAY29kZSBzZXF9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBjb2RlUG9pbnRBdChjaGFyW10gc2VxLCBpbnQgaW5kZXgsIGludCBsaW1pdCkgeworICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGxpbWl0IHx8IGxpbWl0IDwgMCB8fCBsaW1pdCA+IHNlcS5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBjaGFyIGhpZ2ggPSBzZXFbaW5kZXgrK107CisgICAgICAgIGlmIChpbmRleCA+PSBsaW1pdCkgeworICAgICAgICAgICAgcmV0dXJuIGhpZ2g7CisgICAgICAgIH0KKyAgICAgICAgY2hhciBsb3cgPSBzZXFbaW5kZXhdOworICAgICAgICBpZiAoaXNTdXJyb2dhdGVQYWlyKGhpZ2gsIGxvdykpIHsKKyAgICAgICAgICAgIHJldHVybiB0b0NvZGVQb2ludChoaWdoLCBsb3cpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBoaWdoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNvZGUgcG9pbnQgdGhhdCBwcmVjZWRlcyB7QGNvZGUgaW5kZXh9IGluIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXIgdW5pdHMuIElmIHRoZSB1bml0IGF0IHtAY29kZSBpbmRleCAtIDF9IGlzIGEKKyAgICAgKiBsb3ctc3Vycm9nYXRlIHVuaXQsIHtAY29kZSBpbmRleCAtIDJ9IGlzIG5vdCBuZWdhdGl2ZSBhbmQgdGhlIHVuaXQgYXQKKyAgICAgKiB7QGNvZGUgaW5kZXggLSAyfSBpcyBhIGhpZ2gtc3Vycm9nYXRlIHVuaXQsIHRoZW4gdGhlIHN1cHBsZW1lbnRhcnkgY29kZQorICAgICAqIHBvaW50IHJlcHJlc2VudGVkIGJ5IHRoZSBwYWlyIGlzIHJldHVybmVkOyBvdGhlcndpc2UgdGhlIHtAY29kZSBjaGFyfQorICAgICAqIHZhbHVlIGF0IHtAY29kZSBpbmRleCAtIDF9IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIHNlcQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBzZXF1ZW5jZSBvZiB7QGNvZGUgY2hhcn0gdW5pdHMuCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcG9zaXRpb24gaW4ge0Bjb2RlIHNlcX0gZm9sbG93aW5nIHRoZSBjb2RlCisgICAgICogICAgICAgICAgICBwb2ludCB0aGF0IHNob3VsZCBiZSByZXR1cm5lZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBVbmljb2RlIGNvZGUgcG9pbnQgb3Ige0Bjb2RlIGNoYXJ9IHZhbHVlIGJlZm9yZSB7QGNvZGUgaW5kZXh9CisgICAgICogICAgICAgICBpbiB7QGNvZGUgc2VxfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHNlcX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgaW5kZXh9IGlzIGxlc3MgdGhhbiAxIG9yIGdyZWF0ZXIgdGhhbiB0aGUKKyAgICAgKiAgICAgICAgICAgICBsZW5ndGggb2Yge0Bjb2RlIHNlcX0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGNvZGVQb2ludEJlZm9yZShDaGFyU2VxdWVuY2Ugc2VxLCBpbnQgaW5kZXgpIHsKKyAgICAgICAgaWYgKHNlcSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgbGVuID0gc2VxLmxlbmd0aCgpOworICAgICAgICBpZiAoaW5kZXggPCAxIHx8IGluZGV4ID4gbGVuKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgY2hhciBsb3cgPSBzZXEuY2hhckF0KC0taW5kZXgpOworICAgICAgICBpZiAoLS1pbmRleCA8IDApIHsKKyAgICAgICAgICAgIHJldHVybiBsb3c7CisgICAgICAgIH0KKyAgICAgICAgY2hhciBoaWdoID0gc2VxLmNoYXJBdChpbmRleCk7CisgICAgICAgIGlmIChpc1N1cnJvZ2F0ZVBhaXIoaGlnaCwgbG93KSkgeworICAgICAgICAgICAgcmV0dXJuIHRvQ29kZVBvaW50KGhpZ2gsIGxvdyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGxvdzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb2RlIHBvaW50IHRoYXQgcHJlY2VkZXMge0Bjb2RlIGluZGV4fSBpbiB0aGUgc3BlY2lmaWVkCisgICAgICogYXJyYXkgb2YgY2hhcmFjdGVyIHVuaXRzLiBJZiB0aGUgdW5pdCBhdCB7QGNvZGUgaW5kZXggLSAxfSBpcyBhCisgICAgICogbG93LXN1cnJvZ2F0ZSB1bml0LCB7QGNvZGUgaW5kZXggLSAyfSBpcyBub3QgbmVnYXRpdmUgYW5kIHRoZSB1bml0IGF0CisgICAgICoge0Bjb2RlIGluZGV4IC0gMn0gaXMgYSBoaWdoLXN1cnJvZ2F0ZSB1bml0LCB0aGVuIHRoZSBzdXBwbGVtZW50YXJ5IGNvZGUKKyAgICAgKiBwb2ludCByZXByZXNlbnRlZCBieSB0aGUgcGFpciBpcyByZXR1cm5lZDsgb3RoZXJ3aXNlIHRoZSB7QGNvZGUgY2hhcn0KKyAgICAgKiB2YWx1ZSBhdCB7QGNvZGUgaW5kZXggLSAxfSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzZXEKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgYXJyYXkgb2Yge0Bjb2RlIGNoYXJ9IHVuaXRzLgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBvc2l0aW9uIGluIHtAY29kZSBzZXF9IGZvbGxvd2luZyB0aGUgY29kZQorICAgICAqICAgICAgICAgICAgcG9pbnQgdGhhdCBzaG91bGQgYmUgcmV0dXJuZWQuCisgICAgICogQHJldHVybiB0aGUgVW5pY29kZSBjb2RlIHBvaW50IG9yIHtAY29kZSBjaGFyfSB2YWx1ZSBiZWZvcmUge0Bjb2RlIGluZGV4fQorICAgICAqICAgICAgICAgaW4ge0Bjb2RlIHNlcX0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzZXF9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGluZGV4fSBpcyBsZXNzIHRoYW4gMSBvciBncmVhdGVyIHRoYW4gdGhlCisgICAgICogICAgICAgICAgICAgbGVuZ3RoIG9mIHtAY29kZSBzZXF9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBjb2RlUG9pbnRCZWZvcmUoY2hhcltdIHNlcSwgaW50IGluZGV4KSB7CisgICAgICAgIGlmIChzZXEgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGxlbiA9IHNlcS5sZW5ndGg7CisgICAgICAgIGlmIChpbmRleCA8IDEgfHwgaW5kZXggPiBsZW4pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBjaGFyIGxvdyA9IHNlcVstLWluZGV4XTsKKyAgICAgICAgaWYgKC0taW5kZXggPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gbG93OworICAgICAgICB9CisgICAgICAgIGNoYXIgaGlnaCA9IHNlcVtpbmRleF07CisgICAgICAgIGlmIChpc1N1cnJvZ2F0ZVBhaXIoaGlnaCwgbG93KSkgeworICAgICAgICAgICAgcmV0dXJuIHRvQ29kZVBvaW50KGhpZ2gsIGxvdyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGxvdzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb2RlIHBvaW50IHRoYXQgcHJlY2VkZXMgdGhlIHtAY29kZSBpbmRleH0gaW4gdGhlIHNwZWNpZmllZAorICAgICAqIGFycmF5IG9mIGNoYXJhY3RlciB1bml0cyBhbmQgaXMgbm90IGxlc3MgdGhhbiB7QGNvZGUgc3RhcnR9LiBJZiB0aGUgdW5pdAorICAgICAqIGF0IHtAY29kZSBpbmRleCAtIDF9IGlzIGEgbG93LXN1cnJvZ2F0ZSB1bml0LCB7QGNvZGUgaW5kZXggLSAyfSBpcyBub3QKKyAgICAgKiBsZXNzIHRoYW4ge0Bjb2RlIHN0YXJ0fSBhbmQgdGhlIHVuaXQgYXQge0Bjb2RlIGluZGV4IC0gMn0gaXMgYQorICAgICAqIGhpZ2gtc3Vycm9nYXRlIHVuaXQsIHRoZW4gdGhlIHN1cHBsZW1lbnRhcnkgY29kZSBwb2ludCByZXByZXNlbnRlZCBieSB0aGUKKyAgICAgKiBwYWlyIGlzIHJldHVybmVkOyBvdGhlcndpc2UgdGhlIHtAY29kZSBjaGFyfSB2YWx1ZSBhdCB7QGNvZGUgaW5kZXggLSAxfQorICAgICAqIGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIHNlcQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBhcnJheSBvZiB7QGNvZGUgY2hhcn0gdW5pdHMuCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcG9zaXRpb24gaW4ge0Bjb2RlIHNlcX0gZm9sbG93aW5nIHRoZSBjb2RlIHBvaW50IHRoYXQKKyAgICAgKiAgICAgICAgICAgIHNob3VsZCBiZSByZXR1cm5lZC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgZWxlbWVudCBpbiB7QGNvZGUgc2VxfS4KKyAgICAgKiBAcmV0dXJuIHRoZSBVbmljb2RlIGNvZGUgcG9pbnQgb3Ige0Bjb2RlIGNoYXJ9IHZhbHVlIGJlZm9yZSB7QGNvZGUgaW5kZXh9CisgICAgICogICAgICAgICBpbiB7QGNvZGUgc2VxfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHNlcX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgaW5kZXggPD0gc3RhcnR9LCB7QGNvZGUgc3RhcnQgPCAwfSwKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgaW5kZXh9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHtAY29kZSBzZXF9LCBvcgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydH0gaXMgZXF1YWwgb3IgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgc2VxfS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgY29kZVBvaW50QmVmb3JlKGNoYXJbXSBzZXEsIGludCBpbmRleCwgaW50IHN0YXJ0KSB7CisgICAgICAgIGlmIChzZXEgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGxlbiA9IHNlcS5sZW5ndGg7CisgICAgICAgIGlmIChpbmRleCA8PSBzdGFydCB8fCBpbmRleCA+IGxlbiB8fCBzdGFydCA8IDAgfHwgc3RhcnQgPj0gbGVuKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgY2hhciBsb3cgPSBzZXFbLS1pbmRleF07CisgICAgICAgIGlmICgtLWluZGV4IDwgc3RhcnQpIHsKKyAgICAgICAgICAgIHJldHVybiBsb3c7CisgICAgICAgIH0KKyAgICAgICAgY2hhciBoaWdoID0gc2VxW2luZGV4XTsKKyAgICAgICAgaWYgKGlzU3Vycm9nYXRlUGFpcihoaWdoLCBsb3cpKSB7CisgICAgICAgICAgICByZXR1cm4gdG9Db2RlUG9pbnQoaGlnaCwgbG93KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbG93OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIHRoZSBzcGVjaWZpZWQgVW5pY29kZSBjb2RlIHBvaW50IGludG8gYSBVVEYtMTYgZW5jb2RlZCBzZXF1ZW5jZQorICAgICAqIGFuZCBjb3BpZXMgdGhlIHZhbHVlKHMpIGludG8gdGhlIGNoYXIgYXJyYXkge0Bjb2RlIGRzdH0sIHN0YXJ0aW5nIGF0CisgICAgICogaW5kZXgge0Bjb2RlIGRzdEluZGV4fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2RlUG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBVbmljb2RlIGNvZGUgcG9pbnQgdG8gZW5jb2RlLgorICAgICAqIEBwYXJhbSBkc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXN0aW5hdGlvbiBhcnJheSB0byBjb3B5IHRoZSBlbmNvZGVkIHZhbHVlIGludG8uCisgICAgICogQHBhcmFtIGRzdEluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggaW4ge0Bjb2RlIGRzdH0gZnJvbSB3aGVyZSB0byBzdGFydCBjb3B5aW5nLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiB7QGNvZGUgY2hhcn0gdmFsdWUgdW5pdHMgY29waWVkIGludG8ge0Bjb2RlIGRzdH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGNvZGVQb2ludH0gaXMgbm90IGEgdmFsaWQgY29kZSBwb2ludC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGRzdH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkc3RJbmRleH0gaXMgbmVnYXRpdmUsIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0bworICAgICAqICAgICAgICAgICAgIHtAY29kZSBkc3QubGVuZ3RofSBvciBlcXVhbHMge0Bjb2RlIGRzdC5sZW5ndGggLSAxfSB3aGVuCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGNvZGVQb2ludH0gaXMgYQorICAgICAqICAgICAgICAgICAgIHtAbGluayAjaXNTdXBwbGVtZW50YXJ5Q29kZVBvaW50KGludCkgc3VwcGxlbWVudGFyeSBjb2RlIHBvaW50fS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgdG9DaGFycyhpbnQgY29kZVBvaW50LCBjaGFyW10gZHN0LCBpbnQgZHN0SW5kZXgpIHsKKyAgICAgICAgY2hlY2tWYWxpZENvZGVQb2ludChjb2RlUG9pbnQpOworICAgICAgICBpZiAoZHN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChkc3RJbmRleCA8IDAgfHwgZHN0SW5kZXggPj0gZHN0Lmxlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChpc1N1cHBsZW1lbnRhcnlDb2RlUG9pbnQoY29kZVBvaW50KSkgeworICAgICAgICAgICAgaWYgKGRzdEluZGV4ID09IGRzdC5sZW5ndGggLSAxKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIFNlZSBSRkMgMjc4MSwgU2VjdGlvbiAyLjEKKyAgICAgICAgICAgIC8vIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzI3ODEudHh0CisgICAgICAgICAgICBpbnQgY3BQcmltZSA9IGNvZGVQb2ludCAtIDB4MTAwMDA7CisgICAgICAgICAgICBpbnQgaGlnaCA9IDB4RDgwMCB8ICgoY3BQcmltZSA+PiAxMCkgJiAweDNGRik7CisgICAgICAgICAgICBpbnQgbG93ID0gMHhEQzAwIHwgKGNwUHJpbWUgJiAweDNGRik7CisgICAgICAgICAgICBkc3RbZHN0SW5kZXhdID0gKGNoYXIpIGhpZ2g7CisgICAgICAgICAgICBkc3RbZHN0SW5kZXggKyAxXSA9IChjaGFyKSBsb3c7CisgICAgICAgICAgICByZXR1cm4gMjsKKyAgICAgICAgfQorCisgICAgICAgIGRzdFtkc3RJbmRleF0gPSAoY2hhcikgY29kZVBvaW50OworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIFVuaWNvZGUgY29kZSBwb2ludCBpbnRvIGEgVVRGLTE2IGVuY29kZWQgc2VxdWVuY2UKKyAgICAgKiBhbmQgcmV0dXJucyBpdCBhcyBhIGNoYXIgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29kZVBvaW50CisgICAgICogICAgICAgICAgICB0aGUgVW5pY29kZSBjb2RlIHBvaW50IHRvIGVuY29kZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBVVEYtMTYgZW5jb2RlZCBjaGFyIHNlcXVlbmNlLiBJZiB7QGNvZGUgY29kZVBvaW50fSBpcyBhCisgICAgICogICAgICAgICB7QGxpbmsgI2lzU3VwcGxlbWVudGFyeUNvZGVQb2ludChpbnQpIHN1cHBsZW1lbnRhcnkgY29kZSBwb2ludH0sCisgICAgICogICAgICAgICB0aGVuIHRoZSByZXR1cm5lZCBhcnJheSBjb250YWlucyB0d28gY2hhcmFjdGVycywgb3RoZXJ3aXNlIGl0CisgICAgICogICAgICAgICBjb250YWlucyBqdXN0IG9uZSBjaGFyYWN0ZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGNvZGVQb2ludH0gaXMgbm90IGEgdmFsaWQgY29kZSBwb2ludC4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjaGFyW10gdG9DaGFycyhpbnQgY29kZVBvaW50KSB7CisgICAgICAgIGNoZWNrVmFsaWRDb2RlUG9pbnQoY29kZVBvaW50KTsKKyAgICAgICAgaWYgKGlzU3VwcGxlbWVudGFyeUNvZGVQb2ludChjb2RlUG9pbnQpKSB7CisgICAgICAgICAgICBpbnQgY3BQcmltZSA9IGNvZGVQb2ludCAtIDB4MTAwMDA7CisgICAgICAgICAgICBpbnQgaGlnaCA9IDB4RDgwMCB8ICgoY3BQcmltZSA+PiAxMCkgJiAweDNGRik7CisgICAgICAgICAgICBpbnQgbG93ID0gMHhEQzAwIHwgKGNwUHJpbWUgJiAweDNGRik7CisgICAgICAgICAgICByZXR1cm4gbmV3IGNoYXJbXSB7IChjaGFyKSBoaWdoLCAoY2hhcikgbG93IH07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBjaGFyW10geyAoY2hhcikgY29kZVBvaW50IH07CisgICAgfQorCisgICAgLyoqCisgICAgICogQ291bnRzIHRoZSBudW1iZXIgb2YgVW5pY29kZSBjb2RlIHBvaW50cyBpbiB0aGUgc3Vic2VxdWVuY2Ugb2YgdGhlCisgICAgICogc3BlY2lmaWVkIGNoYXJhY3RlciBzZXF1ZW5jZSwgYXMgZGVsaW5lYXRlZCBieSB7QGNvZGUgYmVnaW5JbmRleH0gYW5kCisgICAgICoge0Bjb2RlIGVuZEluZGV4fS4gQW55IHN1cnJvZ2F0ZSB2YWx1ZXMgd2l0aCBtaXNzaW5nIHBhaXIgdmFsdWVzIHdpbGwgYmUKKyAgICAgKiBjb3VudGVkIGFzIG9uZSBjb2RlIHBvaW50LgorICAgICAqCisgICAgICogQHBhcmFtIHNlcQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDaGFyU2VxdWVuY2V9IHRvIGxvb2sgdGhyb3VnaC4KKyAgICAgKiBAcGFyYW0gYmVnaW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluY2x1c2l2ZSBpbmRleCB0byBiZWdpbiBjb3VudGluZyBhdC4KKyAgICAgKiBAcGFyYW0gZW5kSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNsdXNpdmUgaW5kZXggdG8gc3RvcCBjb3VudGluZyBhdC4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgVW5pY29kZSBjb2RlIHBvaW50cy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHNlcX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBiZWdpbkluZGV4IDwgMH0sIHtAY29kZSBiZWdpbkluZGV4ID4gZW5kSW5kZXh9IG9yCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGVuZEluZGV4fSBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZiB7QGNvZGUgc2VxfS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgY29kZVBvaW50Q291bnQoQ2hhclNlcXVlbmNlIHNlcSwgaW50IGJlZ2luSW5kZXgsCisgICAgICAgICAgICBpbnQgZW5kSW5kZXgpIHsKKyAgICAgICAgaWYgKHNlcSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgbGVuID0gc2VxLmxlbmd0aCgpOworICAgICAgICBpZiAoYmVnaW5JbmRleCA8IDAgfHwgZW5kSW5kZXggPiBsZW4gfHwgYmVnaW5JbmRleCA+IGVuZEluZGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaW50IHJlc3VsdCA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSBiZWdpbkluZGV4OyBpIDwgZW5kSW5kZXg7IGkrKykgeworICAgICAgICAgICAgY2hhciBjID0gc2VxLmNoYXJBdChpKTsKKyAgICAgICAgICAgIGlmIChpc0hpZ2hTdXJyb2dhdGUoYykpIHsKKyAgICAgICAgICAgICAgICBpZiAoKytpIDwgZW5kSW5kZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgYyA9IHNlcS5jaGFyQXQoaSk7CisgICAgICAgICAgICAgICAgICAgIGlmICghaXNMb3dTdXJyb2dhdGUoYykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCsrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0Kys7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3VudHMgdGhlIG51bWJlciBvZiBVbmljb2RlIGNvZGUgcG9pbnRzIGluIHRoZSBzdWJzZXF1ZW5jZSBvZiB0aGUKKyAgICAgKiBzcGVjaWZpZWQgY2hhciBhcnJheSwgYXMgZGVsaW5lYXRlZCBieSB7QGNvZGUgb2Zmc2V0fSBhbmQge0Bjb2RlIGNvdW50fS4KKyAgICAgKiBBbnkgc3Vycm9nYXRlIHZhbHVlcyB3aXRoIG1pc3NpbmcgcGFpciB2YWx1ZXMgd2lsbCBiZSBjb3VudGVkIGFzIG9uZSBjb2RlCisgICAgICogcG9pbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2VxCisgICAgICogICAgICAgICAgICB0aGUgY2hhciBhcnJheSB0byBsb29rIHRocm91Z2gKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5jbHVzaXZlIGluZGV4IHRvIGJlZ2luIGNvdW50aW5nIGF0LgorICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiB7QGNvZGUgY2hhcn0gdmFsdWVzIHRvIGxvb2sgdGhyb3VnaCBpbgorICAgICAqICAgICAgICAgICAge0Bjb2RlIHNlcX0uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIFVuaWNvZGUgY29kZSBwb2ludHMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzZXF9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0sIHtAY29kZSBjb3VudCA8IDB9IG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIG9mZnNldCArIGNvdW50fSBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBzZXF9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBjb2RlUG9pbnRDb3VudChjaGFyW10gc2VxLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoc2VxLmxlbmd0aCwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgIGludCBlbmRJbmRleCA9IG9mZnNldCArIGNvdW50OworICAgICAgICBpbnQgcmVzdWx0ID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IG9mZnNldDsgaSA8IGVuZEluZGV4OyBpKyspIHsKKyAgICAgICAgICAgIGNoYXIgYyA9IHNlcVtpXTsKKyAgICAgICAgICAgIGlmIChpc0hpZ2hTdXJyb2dhdGUoYykpIHsKKyAgICAgICAgICAgICAgICBpZiAoKytpIDwgZW5kSW5kZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgYyA9IHNlcVtpXTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0xvd1N1cnJvZ2F0ZShjKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0Kys7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHQrKzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgdGhlIGluZGV4IGluIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIHNlcXVlbmNlIHRoYXQgaXMgb2Zmc2V0CisgICAgICoge0Bjb2RlIGNvZGVQb2ludE9mZnNldH0gY29kZSBwb2ludHMgZnJvbSB7QGNvZGUgaW5kZXh9LgorICAgICAqCisgICAgICogQHBhcmFtIHNlcQorICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSB0byBmaW5kIHRoZSBpbmRleCBpbi4KKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBpbmRleCBpbiB7QGNvZGUgc2VxfS4KKyAgICAgKiBAcGFyYW0gY29kZVBvaW50T2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNvZGUgcG9pbnRzIHRvIGxvb2sgYmFja3dhcmRzIG9yIGZvcndhcmRzOyBtYXkKKyAgICAgKiAgICAgICAgICAgIGJlIGEgbmVnYXRpdmUgb3IgcG9zaXRpdmUgdmFsdWUuCisgICAgICogQHJldHVybiB0aGUgaW5kZXggaW4ge0Bjb2RlIHNlcX0gdGhhdCBpcyB7QGNvZGUgY29kZVBvaW50T2Zmc2V0fSBjb2RlCisgICAgICogICAgICAgICBwb2ludHMgYXdheSBmcm9tIHtAY29kZSBpbmRleH0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzZXF9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW5kZXggPCAwfSwge0Bjb2RlIGluZGV4fSBpcyBncmVhdGVyIHRoYW4gdGhlCisgICAgICogICAgICAgICAgICAgbGVuZ3RoIG9mIHtAY29kZSBzZXF9LCBvciBpZiB0aGVyZSBhcmUgbm90IGVub3VnaCB2YWx1ZXMgaW4KKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgc2VxfSB0byBza2lwIHtAY29kZSBjb2RlUG9pbnRPZmZzZXR9IGNvZGUgcG9pbnRzCisgICAgICogICAgICAgICAgICAgZm9yd2FyZHMgb3IgYmFja3dhcmRzIChpZiB7QGNvZGUgY29kZVBvaW50T2Zmc2V0fSBpcworICAgICAqICAgICAgICAgICAgIG5lZ2F0aXZlKSBmcm9tIHtAY29kZSBpbmRleH0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IG9mZnNldEJ5Q29kZVBvaW50cyhDaGFyU2VxdWVuY2Ugc2VxLCBpbnQgaW5kZXgsIGludCBjb2RlUG9pbnRPZmZzZXQpIHsKKyAgICAgICAgaWYgKHNlcSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgbGVuID0gc2VxLmxlbmd0aCgpOworICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID4gbGVuKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGNvZGVQb2ludE9mZnNldCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gaW5kZXg7CisgICAgICAgIH0KKworICAgICAgICBpZiAoY29kZVBvaW50T2Zmc2V0ID4gMCkgeworICAgICAgICAgICAgaW50IGNvZGVQb2ludHMgPSBjb2RlUG9pbnRPZmZzZXQ7CisgICAgICAgICAgICBpbnQgaSA9IGluZGV4OworICAgICAgICAgICAgd2hpbGUgKGNvZGVQb2ludHMgPiAwKSB7CisgICAgICAgICAgICAgICAgY29kZVBvaW50cy0tOworICAgICAgICAgICAgICAgIGlmIChpID49IGxlbikgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoaXNIaWdoU3Vycm9nYXRlKHNlcS5jaGFyQXQoaSkpKSB7CisgICAgICAgICAgICAgICAgICAgIGludCBuZXh0ID0gaSArIDE7CisgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0IDwgbGVuICYmIGlzTG93U3Vycm9nYXRlKHNlcS5jaGFyQXQobmV4dCkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpKys7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgY29kZVBvaW50cyA9IC1jb2RlUG9pbnRPZmZzZXQ7CisgICAgICAgIGludCBpID0gaW5kZXg7CisgICAgICAgIHdoaWxlIChjb2RlUG9pbnRzID4gMCkgeworICAgICAgICAgICAgY29kZVBvaW50cy0tOworICAgICAgICAgICAgaS0tOworICAgICAgICAgICAgaWYgKGkgPCAwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpc0xvd1N1cnJvZ2F0ZShzZXEuY2hhckF0KGkpKSkgeworICAgICAgICAgICAgICAgIGludCBwcmV2ID0gaSAtIDE7CisgICAgICAgICAgICAgICAgaWYgKHByZXYgPj0gMCAmJiBpc0hpZ2hTdXJyb2dhdGUoc2VxLmNoYXJBdChwcmV2KSkpIHsKKyAgICAgICAgICAgICAgICAgICAgaS0tOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHRoZSBpbmRleCBpbiBhIHN1YnNlcXVlbmNlIG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGFycmF5CisgICAgICogdGhhdCBpcyBvZmZzZXQge0Bjb2RlIGNvZGVQb2ludE9mZnNldH0gY29kZSBwb2ludHMgZnJvbSB7QGNvZGUgaW5kZXh9LgorICAgICAqIFRoZSBzdWJzZXF1ZW5jZSBpcyBkZWxpbmVhdGVkIGJ5IHtAY29kZSBzdGFydH0gYW5kIHtAY29kZSBjb3VudH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2VxCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIGFycmF5IHRvIGZpbmQgdGhlIGluZGV4IGluLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIGluY2x1c2l2ZSBpbmRleCB0aGF0IG1hcmtzIHRoZSBiZWdpbm5pbmcgb2YgdGhlCisgICAgICogICAgICAgICAgICBzdWJzZXF1ZW5jZS4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2Yge0Bjb2RlIGNoYXJ9IHZhbHVlcyB0byBpbmNsdWRlIHdpdGhpbiB0aGUKKyAgICAgKiAgICAgICAgICAgIHN1YnNlcXVlbmNlLgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IGluZGV4IGluIHRoZSBzdWJzZXF1ZW5jZSBvZiB0aGUgY2hhciBhcnJheS4KKyAgICAgKiBAcGFyYW0gY29kZVBvaW50T2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNvZGUgcG9pbnRzIHRvIGxvb2sgYmFja3dhcmRzIG9yIGZvcndhcmRzOyBtYXkKKyAgICAgKiAgICAgICAgICAgIGJlIGEgbmVnYXRpdmUgb3IgcG9zaXRpdmUgdmFsdWUuCisgICAgICogQHJldHVybiB0aGUgaW5kZXggaW4ge0Bjb2RlIHNlcX0gdGhhdCBpcyB7QGNvZGUgY29kZVBvaW50T2Zmc2V0fSBjb2RlCisgICAgICogICAgICAgICBwb2ludHMgYXdheSBmcm9tIHtAY29kZSBpbmRleH0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzZXF9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwfSwge0Bjb2RlIGNvdW50IDwgMH0sCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGluZGV4IDwgc3RhcnR9LCB7QGNvZGUgaW5kZXggPiBzdGFydCArIGNvdW50fSwKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgc3RhcnQgKyBjb3VudH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgc2VxfSwgb3IgaWYgdGhlcmUgYXJlIG5vdCBlbm91Z2ggdmFsdWVzIGluCisgICAgICogICAgICAgICAgICAge0Bjb2RlIHNlcX0gdG8gc2tpcCB7QGNvZGUgY29kZVBvaW50T2Zmc2V0fSBjb2RlIHBvaW50cworICAgICAqICAgICAgICAgICAgIGZvcndhcmQgb3IgYmFja3dhcmQgKGlmIHtAY29kZSBjb2RlUG9pbnRPZmZzZXR9IGlzCisgICAgICogICAgICAgICAgICAgbmVnYXRpdmUpIGZyb20ge0Bjb2RlIGluZGV4fS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgb2Zmc2V0QnlDb2RlUG9pbnRzKGNoYXJbXSBzZXEsIGludCBzdGFydCwgaW50IGNvdW50LAorICAgICAgICAgICAgaW50IGluZGV4LCBpbnQgY29kZVBvaW50T2Zmc2V0KSB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KHNlcS5sZW5ndGgsIHN0YXJ0LCBjb3VudCk7CisgICAgICAgIGludCBlbmQgPSBzdGFydCArIGNvdW50OworICAgICAgICBpZiAoaW5kZXggPCBzdGFydCB8fCBpbmRleCA+IGVuZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjb2RlUG9pbnRPZmZzZXQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGluZGV4OworICAgICAgICB9CisKKyAgICAgICAgaWYgKGNvZGVQb2ludE9mZnNldCA+IDApIHsKKyAgICAgICAgICAgIGludCBjb2RlUG9pbnRzID0gY29kZVBvaW50T2Zmc2V0OworICAgICAgICAgICAgaW50IGkgPSBpbmRleDsKKyAgICAgICAgICAgIHdoaWxlIChjb2RlUG9pbnRzID4gMCkgeworICAgICAgICAgICAgICAgIGNvZGVQb2ludHMtLTsKKyAgICAgICAgICAgICAgICBpZiAoaSA+PSBlbmQpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGlzSGlnaFN1cnJvZ2F0ZShzZXFbaV0pKSB7CisgICAgICAgICAgICAgICAgICAgIGludCBuZXh0ID0gaSArIDE7CisgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0IDwgZW5kICYmIGlzTG93U3Vycm9nYXRlKHNlcVtuZXh0XSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBjb2RlUG9pbnRzID0gLWNvZGVQb2ludE9mZnNldDsKKyAgICAgICAgaW50IGkgPSBpbmRleDsKKyAgICAgICAgd2hpbGUgKGNvZGVQb2ludHMgPiAwKSB7CisgICAgICAgICAgICBjb2RlUG9pbnRzLS07CisgICAgICAgICAgICBpLS07CisgICAgICAgICAgICBpZiAoaSA8IHN0YXJ0KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpc0xvd1N1cnJvZ2F0ZShzZXFbaV0pKSB7CisgICAgICAgICAgICAgICAgaW50IHByZXYgPSBpIC0gMTsKKyAgICAgICAgICAgICAgICBpZiAocHJldiA+PSBzdGFydCAmJiBpc0hpZ2hTdXJyb2dhdGUoc2VxW3ByZXZdKSkgeworICAgICAgICAgICAgICAgICAgICBpLS07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCB0byBkZXRlcm1pbmUgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyCisgICAgICoge0Bjb2RlIGN9IGluIHRoZSBzdXBwbGllZCByYWRpeC4gVGhlIHZhbHVlIG9mIHtAY29kZSByYWRpeH0gbXVzdCBiZQorICAgICAqIGJldHdlZW4gTUlOX1JBRElYIGFuZCBNQVhfUkFESVguCisgICAgICoKKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byBkZXRlcm1pbmUgdGhlIHZhbHVlIG9mLgorICAgICAqIEBwYXJhbSByYWRpeAorICAgICAqICAgICAgICAgICAgdGhlIHJhZGl4LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHtAY29kZSBjfSBpbiB7QGNvZGUgcmFkaXh9IGlmIHtAY29kZSByYWRpeH0gbGllcworICAgICAqICAgICAgICAgYmV0d2VlbiB7QGxpbmsgI01JTl9SQURJWH0gYW5kIHtAbGluayAjTUFYX1JBRElYfTsgLTEgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGRpZ2l0KGNoYXIgYywgaW50IHJhZGl4KSB7CisgICAgICAgIHJldHVybiBkaWdpdCgoaW50KSBjLCByYWRpeCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVuaWVuY2UgbWV0aG9kIHRvIGRldGVybWluZSB0aGUgdmFsdWUgb2YgdGhlIGNoYXJhY3RlcgorICAgICAqIHtAY29kZSBjb2RlUG9pbnR9IGluIHRoZSBzdXBwbGllZCByYWRpeC4gVGhlIHZhbHVlIG9mIHtAY29kZSByYWRpeH0gbXVzdAorICAgICAqIGJlIGJldHdlZW4gTUlOX1JBRElYIGFuZCBNQVhfUkFESVguCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29kZVBvaW50CisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyLCBpbmNsdWRpbmcgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzLgorICAgICAqIEBwYXJhbSByYWRpeAorICAgICAqICAgICAgICAgICAgdGhlIHJhZGl4LgorICAgICAqIEByZXR1cm4gaWYge0Bjb2RlIHJhZGl4fSBsaWVzIGJldHdlZW4ge0BsaW5rICNNSU5fUkFESVh9IGFuZAorICAgICAqICAgICAgICAge0BsaW5rICNNQVhfUkFESVh9IHRoZW4gdGhlIHZhbHVlIG9mIHRoZSBjaGFyYWN0ZXIgaW4gdGhlIHJhZGl4OworICAgICAqICAgICAgICAgLTEgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGRpZ2l0KGludCBjb2RlUG9pbnQsIGludCByYWRpeCkgeworICAgICAgICBpZiAocmFkaXggPCBNSU5fUkFESVggfHwgcmFkaXggPiBNQVhfUkFESVgpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY29kZVBvaW50IDwgMTI4KSB7CisgICAgICAgICAgICAvLyBPcHRpbWl6ZWQgZm9yIEFTQ0lJCisgICAgICAgICAgICBpbnQgcmVzdWx0ID0gLTE7CisgICAgICAgICAgICBpZiAoJzAnIDw9IGNvZGVQb2ludCAmJiBjb2RlUG9pbnQgPD0gJzknKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gY29kZVBvaW50IC0gJzAnOworICAgICAgICAgICAgfSBlbHNlIGlmICgnYScgPD0gY29kZVBvaW50ICYmIGNvZGVQb2ludCA8PSAneicpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSAxMCArIChjb2RlUG9pbnQgLSAnYScpOworICAgICAgICAgICAgfSBlbHNlIGlmICgnQScgPD0gY29kZVBvaW50ICYmIGNvZGVQb2ludCA8PSAnWicpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSAxMCArIChjb2RlUG9pbnQgLSAnQScpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA8IHJhZGl4ID8gcmVzdWx0IDogLTE7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRpZ2l0SW1wbChjb2RlUG9pbnQsIHJhZGl4KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IGRpZ2l0SW1wbChpbnQgY29kZVBvaW50LCBpbnQgcmFkaXgpOworCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIG9iamVjdCBhbmQgaW5kaWNhdGVzIGlmIHRoZXkgYXJlCisgICAgICogZXF1YWwuIEluIG9yZGVyIHRvIGJlIGVxdWFsLCB7QGNvZGUgb2JqZWN0fSBtdXN0IGJlIGFuIGluc3RhbmNlIG9mCisgICAgICoge0Bjb2RlIENoYXJhY3Rlcn0gYW5kIGhhdmUgdGhlIHNhbWUgY2hhciB2YWx1ZSBhcyB0aGlzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB0aGlzIGRvdWJsZSB3aXRoLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBDaGFyYWN0ZXJ9OyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICByZXR1cm4gKG9iamVjdCBpbnN0YW5jZW9mIENoYXJhY3RlcikgJiYgKCgoQ2hhcmFjdGVyKSBvYmplY3QpLnZhbHVlID09IHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjaGFyYWN0ZXIgd2hpY2ggcmVwcmVzZW50cyB0aGUgc3BlY2lmaWVkIGRpZ2l0IGluIHRoZQorICAgICAqIHNwZWNpZmllZCByYWRpeC4gVGhlIHtAY29kZSByYWRpeH0gbXVzdCBiZSBiZXR3ZWVuIHtAY29kZSBNSU5fUkFESVh9IGFuZAorICAgICAqIHtAY29kZSBNQVhfUkFESVh9IGluY2x1c2l2ZTsge0Bjb2RlIGRpZ2l0fSBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBhbmQKKyAgICAgKiBzbWFsbGVyIHRoYW4ge0Bjb2RlIHJhZGl4fS4gSWYgYW55IG9mIHRoZXNlIGNvbmRpdGlvbnMgZG9lcyBub3QgaG9sZCwgMAorICAgICAqIGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGRpZ2l0CisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gcmFkaXgKKyAgICAgKiAgICAgICAgICAgIHRoZSByYWRpeC4KKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFyYWN0ZXIgd2hpY2ggcmVwcmVzZW50cyB0aGUge0Bjb2RlIGRpZ2l0fSBpbiB0aGUKKyAgICAgKiAgICAgICAgIHtAY29kZSByYWRpeH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjaGFyIGZvckRpZ2l0KGludCBkaWdpdCwgaW50IHJhZGl4KSB7CisgICAgICAgIGlmIChNSU5fUkFESVggPD0gcmFkaXggJiYgcmFkaXggPD0gTUFYX1JBRElYKSB7CisgICAgICAgICAgICBpZiAoZGlnaXQgPj0gMCAmJiBkaWdpdCA8IHJhZGl4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChjaGFyKSAoZGlnaXQgPCAxMCA/IGRpZ2l0ICsgJzAnIDogZGlnaXQgKyAnYScgLSAxMCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgZ2l2ZW4gY29kZSBwb2ludCwgb3IgbnVsbCBpZiB0aGUgY29kZSBwb2ludCBpcyB1bmFzc2lnbmVkLgorICAgICAqCisgICAgICogPHA+QXMgYSBmYWxsYmFjayBtZWNoYW5pc20gdGhpcyBtZXRob2QgcmV0dXJucyBzdHJpbmdzIGNvbnNpc3Rpbmcgb2YgdGhlIFVuaWNvZGUKKyAgICAgKiBibG9jayBuYW1lICh3aXRoIHVuZGVyc2NvcmVzIHJlcGxhY2VkIGJ5IHNwYWNlcyksIGEgc2luZ2xlIHNwYWNlLCBhbmQgdGhlIHVwcGVyY2FzZQorICAgICAqIGhleCB2YWx1ZSBvZiB0aGUgY29kZSBwb2ludCwgdXNpbmcgYXMgZmV3IGRpZ2l0cyBhcyBuZWNlc3NhcnkuCisgICAgICoKKyAgICAgKiA8cD5FeGFtcGxlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBDaGFyYWN0ZXIuZ2V0TmFtZSgwKX0gcmV0dXJucyAiTlVMTCIuCisgICAgICogPGxpPntAY29kZSBDaGFyYWN0ZXIuZ2V0TmFtZSgnZScpfSByZXR1cm5zICJMQVRJTiBTTUFMTCBMRVRURVIgRSIuCisgICAgICogPGxpPntAY29kZSBDaGFyYWN0ZXIuZ2V0TmFtZSgnXHUwNjY2Jyl9IHJldHVybnMgIkFSQUJJQy1JTkRJQyBESUdJVCBTSVgiLgorICAgICAqIDxsaT57QGNvZGUgQ2hhcmFjdGVyLmdldE5hbWUoMHhlMDAwKX0gcmV0dXJucyAiUFJJVkFURSBVU0UgQVJFQSBFMDAwIi4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGNvZGVQb2ludH0gaXMgbm90IGEgdmFsaWQgY29kZSBwb2ludC4KKyAgICAgKiBAc2luY2UgMS43CisgICAgICogQGhpZGUgMS43CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0TmFtZShpbnQgY29kZVBvaW50KSB7CisgICAgICAgIGNoZWNrVmFsaWRDb2RlUG9pbnQoY29kZVBvaW50KTsKKyAgICAgICAgaWYgKGdldFR5cGUoY29kZVBvaW50KSA9PSBDaGFyYWN0ZXIuVU5BU1NJR05FRCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGdldE5hbWVJbXBsKGNvZGVQb2ludCk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIGJsb2NrTmFtZSA9IENoYXJhY3Rlci5Vbmljb2RlQmxvY2sub2YoY29kZVBvaW50KS50b1N0cmluZygpLnJlcGxhY2UoJ18nLCAnICcpOworICAgICAgICAgICAgcmVzdWx0ID0gYmxvY2tOYW1lICsgIiAiICsgSW50ZWdyYWxUb1N0cmluZy5pbnRUb0hleFN0cmluZyhjb2RlUG9pbnQsIHRydWUsIDApOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIFN0cmluZyBnZXROYW1lSW1wbChpbnQgY29kZVBvaW50KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWVyaWMgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBVbmljb2RlIGNoYXJhY3Rlci4KKyAgICAgKiBTZWUge0BsaW5rICNnZXROdW1lcmljVmFsdWUoaW50KX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYyB0aGUgY2hhcmFjdGVyCisgICAgICogQHJldHVybiBhIG5vbi1uZWdhdGl2ZSBudW1lcmljIGludGVnZXIgdmFsdWUgaWYgYSBudW1lcmljIHZhbHVlIGZvcgorICAgICAqICAgICAgICAge0Bjb2RlIGN9IGV4aXN0cywgLTEgaWYgdGhlcmUgaXMgbm8gbnVtZXJpYyB2YWx1ZSBmb3Ige0Bjb2RlIGN9LAorICAgICAqICAgICAgICAgLTIgaWYgdGhlIG51bWVyaWMgdmFsdWUgY2FuIG5vdCBiZSByZXByZXNlbnRlZCBhcyBhbiBpbnRlZ2VyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldE51bWVyaWNWYWx1ZShjaGFyIGMpIHsKKyAgICAgICAgcmV0dXJuIGdldE51bWVyaWNWYWx1ZSgoaW50KSBjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBudW1lcmljIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgVW5pY29kZSBjb2RlIHBvaW50LiBGb3IgZXhhbXBsZSwKKyAgICAgKiB0aGUgY29kZSBwb2ludCAnXHUyMTZCJyBzdGFuZHMgZm9yIHRoZSBSb21hbiBudW1iZXIgWElJLCB3aGljaCBoYXMgdGhlCisgICAgICogbnVtZXJpYyB2YWx1ZSAxMi4KKyAgICAgKgorICAgICAqIDxwPlRoZXJlIGFyZSB0d28gcG9pbnRzIG9mIGRpdmVyZ2VuY2UgYmV0d2VlbiB0aGlzIG1ldGhvZCBhbmQgdGhlIFVuaWNvZGUKKyAgICAgKiBzcGVjaWZpY2F0aW9uLiBUaGlzIG1ldGhvZCB0cmVhdHMgdGhlIGxldHRlcnMgYS16IChpbiBib3RoIHVwcGVyIGFuZCBsb3dlcgorICAgICAqIGNhc2VzLCBhbmQgdGhlaXIgZnVsbC13aWR0aCB2YXJpYW50cykgYXMgbnVtYmVycyBmcm9tIDEwIHRvIDM1LiBUaGUKKyAgICAgKiBVbmljb2RlIHNwZWNpZmljYXRpb24gYWxzbyBzdXBwb3J0cyB0aGUgaWRlYSBvZiBjb2RlIHBvaW50cyB3aXRoIG5vbi1pbnRlZ2VyCisgICAgICogbnVtZXJpYyB2YWx1ZXM7IHRoaXMgbWV0aG9kIGRvZXMgbm90IChleGNlcHQgdG8gdGhlIGV4dGVudCBvZiByZXR1cm5pbmcgLTIKKyAgICAgKiBmb3Igc3VjaCBjb2RlIHBvaW50cykuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29kZVBvaW50IHRoZSBjb2RlIHBvaW50CisgICAgICogQHJldHVybiBhIG5vbi1uZWdhdGl2ZSBudW1lcmljIGludGVnZXIgdmFsdWUgaWYgYSBudW1lcmljIHZhbHVlIGZvcgorICAgICAqICAgICAgICAge0Bjb2RlIGNvZGVQb2ludH0gZXhpc3RzLCAtMSBpZiB0aGVyZSBpcyBubyBudW1lcmljIHZhbHVlIGZvcgorICAgICAqICAgICAgICAge0Bjb2RlIGNvZGVQb2ludH0sIC0yIGlmIHRoZSBudW1lcmljIHZhbHVlIGNhbiBub3QgYmUKKyAgICAgKiAgICAgICAgIHJlcHJlc2VudGVkIHdpdGggYW4gaW50ZWdlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBnZXROdW1lcmljVmFsdWUoaW50IGNvZGVQb2ludCkgeworICAgICAgICAvLyBUaGlzIGlzIGJvdGggYW4gb3B0aW1pemF0aW9uIGFuZCBwYXBlcnMgb3ZlciBkaWZmZXJlbmNlcyBiZXR3ZWVuIEphdmEgYW5kIElDVS4KKyAgICAgICAgaWYgKGNvZGVQb2ludCA8IDEyOCkgeworICAgICAgICAgICAgaWYgKGNvZGVQb2ludCA+PSAnMCcgJiYgY29kZVBvaW50IDw9ICc5JykgeworICAgICAgICAgICAgICAgIHJldHVybiBjb2RlUG9pbnQgLSAnMCc7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY29kZVBvaW50ID49ICdhJyAmJiBjb2RlUG9pbnQgPD0gJ3onKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNvZGVQb2ludCAtICgnYScgLSAxMCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY29kZVBvaW50ID49ICdBJyAmJiBjb2RlUG9pbnQgPD0gJ1onKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNvZGVQb2ludCAtICgnQScgLSAxMCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgLy8gRnVsbC13aWR0aCB1cHBlcmNhc2UgQS1aLgorICAgICAgICBpZiAoY29kZVBvaW50ID49IDB4ZmYyMSAmJiBjb2RlUG9pbnQgPD0gMHhmZjNhKSB7CisgICAgICAgICAgICByZXR1cm4gY29kZVBvaW50IC0gMHhmZjE3OworICAgICAgICB9CisgICAgICAgIC8vIEZ1bGwtd2lkdGggbG93ZXJjYXNlIGEtei4KKyAgICAgICAgaWYgKGNvZGVQb2ludCA+PSAweGZmNDEgJiYgY29kZVBvaW50IDw9IDB4ZmY1YSkgeworICAgICAgICAgICAgcmV0dXJuIGNvZGVQb2ludCAtIDB4ZmYzNzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0TnVtZXJpY1ZhbHVlSW1wbChjb2RlUG9pbnQpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgZ2V0TnVtZXJpY1ZhbHVlSW1wbChpbnQgY29kZVBvaW50KTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGdlbmVyYWwgVW5pY29kZSBjYXRlZ29yeSBvZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3Rlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIGdldCB0aGUgY2F0ZWdvcnkgb2YuCisgICAgICogQHJldHVybiB0aGUgVW5pY29kZSBjYXRlZ29yeSBvZiB7QGNvZGUgY30uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZ2V0VHlwZShjaGFyIGMpIHsKKyAgICAgICAgcmV0dXJuIGdldFR5cGUoKGludCkgYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZ2VuZXJhbCBVbmljb2RlIGNhdGVnb3J5IG9mIHRoZSBzcGVjaWZpZWQgY29kZSBwb2ludC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2RlUG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBVbmljb2RlIGNvZGUgcG9pbnQgdG8gZ2V0IHRoZSBjYXRlZ29yeSBvZi4KKyAgICAgKiBAcmV0dXJuIHRoZSBVbmljb2RlIGNhdGVnb3J5IG9mIHtAY29kZSBjb2RlUG9pbnR9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldFR5cGUoaW50IGNvZGVQb2ludCkgeworICAgICAgICBpbnQgdHlwZSA9IGdldFR5cGVJbXBsKGNvZGVQb2ludCk7CisgICAgICAgIC8vIFRoZSB0eXBlIHZhbHVlcyByZXR1cm5lZCBieSBJQ1UgYXJlIG5vdCBSSS1jb21wYXRpYmxlLiBUaGUgUkkgc2tpcHMgdGhlIHZhbHVlIDE3LgorICAgICAgICBpZiAodHlwZSA8PSBDaGFyYWN0ZXIuRk9STUFUKSB7CisgICAgICAgICAgICByZXR1cm4gdHlwZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKHR5cGUgKyAxKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IGdldFR5cGVJbXBsKGludCBjb2RlUG9pbnQpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgVW5pY29kZSBkaXJlY3Rpb25hbGl0eSBvZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3Rlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIGdldCB0aGUgZGlyZWN0aW9uYWxpdHkgb2YuCisgICAgICogQHJldHVybiB0aGUgVW5pY29kZSBkaXJlY3Rpb25hbGl0eSBvZiB7QGNvZGUgY30uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlIGdldERpcmVjdGlvbmFsaXR5KGNoYXIgYykgeworICAgICAgICByZXR1cm4gZ2V0RGlyZWN0aW9uYWxpdHkoKGludCljKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBVbmljb2RlIGRpcmVjdGlvbmFsaXR5IG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGNvZGVQb2ludAorICAgICAqICAgICAgICAgICAgdGhlIFVuaWNvZGUgY29kZSBwb2ludCB0byBnZXQgdGhlIGRpcmVjdGlvbmFsaXR5IG9mLgorICAgICAqIEByZXR1cm4gdGhlIFVuaWNvZGUgZGlyZWN0aW9uYWxpdHkgb2Yge0Bjb2RlIGNvZGVQb2ludH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlIGdldERpcmVjdGlvbmFsaXR5KGludCBjb2RlUG9pbnQpIHsKKyAgICAgICAgaWYgKGdldFR5cGUoY29kZVBvaW50KSA9PSBDaGFyYWN0ZXIuVU5BU1NJR05FRCkgeworICAgICAgICAgICAgcmV0dXJuIENoYXJhY3Rlci5ESVJFQ1RJT05BTElUWV9VTkRFRklORUQ7CisgICAgICAgIH0KKworICAgICAgICBieXRlIGRpcmVjdGlvbmFsaXR5ID0gZ2V0RGlyZWN0aW9uYWxpdHlJbXBsKGNvZGVQb2ludCk7CisgICAgICAgIGlmIChkaXJlY3Rpb25hbGl0eSA9PSAtMSkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIHJldHVybiBESVJFQ1RJT05BTElUWVtkaXJlY3Rpb25hbGl0eV07CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGJ5dGUgZ2V0RGlyZWN0aW9uYWxpdHlJbXBsKGludCBjb2RlUG9pbnQpOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgbWlycm9yZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgY30gaXMgbWlycm9yZWQ7IHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNNaXJyb3JlZChjaGFyIGMpIHsKKyAgICAgICAgcmV0dXJuIGlzTWlycm9yZWQoKGludCkgYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjb2RlIHBvaW50IGlzIG1pcnJvcmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGNvZGVQb2ludAorICAgICAqICAgICAgICAgICAgdGhlIGNvZGUgcG9pbnQgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGNvZGVQb2ludH0gaXMgbWlycm9yZWQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNNaXJyb3JlZChpbnQgY29kZVBvaW50KSB7CisgICAgICAgIHJldHVybiBpc01pcnJvcmVkSW1wbChjb2RlUG9pbnQpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBib29sZWFuIGlzTWlycm9yZWRJbXBsKGludCBjb2RlUG9pbnQpOworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhpZ2ggc3Vycm9nYXRlIGZvciB0aGUgZ2l2ZW4gY29kZSBwb2ludC4gVGhlIHJlc3VsdCBpcyBtZWFuaW5nbGVzcyBpZgorICAgICAqIHRoZSBnaXZlbiBjb2RlIHBvaW50IGlzIG5vdCBhIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyLgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNoYXIgaGlnaFN1cnJvZ2F0ZShpbnQgY29kZVBvaW50KSB7CisgICAgICAgIHJldHVybiAoY2hhcikgKChjb2RlUG9pbnQgPj4gMTApICsgMHhkN2MwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb3cgc3Vycm9nYXRlIGZvciB0aGUgZ2l2ZW4gY29kZSBwb2ludC4gVGhlIHJlc3VsdCBpcyBtZWFuaW5nbGVzcyBpZgorICAgICAqIHRoZSBnaXZlbiBjb2RlIHBvaW50IGlzIG5vdCBhIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyLgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNoYXIgbG93U3Vycm9nYXRlKGludCBjb2RlUG9pbnQpIHsKKyAgICAgICAgcmV0dXJuIChjaGFyKSAoKGNvZGVQb2ludCAmIDB4M2ZmKSB8IDB4ZGMwMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgd2hldGhlciB0aGUgZ2l2ZW4gY29kZSBwb2ludCBpcyBpbiB0aGUgQmFzaWMgTXVsdGlsaW5ndWFsIFBsYW5lIChCTVApLgorICAgICAqIFN1Y2ggY29kZSBwb2ludHMgY2FuIGJlIHJlcHJlc2VudGVkIGJ5IGEgc2luZ2xlIHtAY29kZSBjaGFyfS4KKyAgICAgKiBAc2luY2UgMS43CisgICAgICogQGhpZGUgMS43CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzQm1wQ29kZVBvaW50KGludCBjb2RlUG9pbnQpIHsKKyAgICAgICAgcmV0dXJuIGNvZGVQb2ludCA+PSAwICYmIGNvZGVQb2ludCA8PSAweGZmZmY7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgZGVmaW5lZCBpbiB0aGUgVW5pY29kZQorICAgICAqIHNwZWNpZmljYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZ2VuZXJhbCBVbmljb2RlIGNhdGVnb3J5IG9mIHRoZSBjaGFyYWN0ZXIgaXMKKyAgICAgKiAgICAgICAgIG5vdCB7QGNvZGUgVU5BU1NJR05FRH07IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0RlZmluZWQoY2hhciBjKSB7CisgICAgICAgIHJldHVybiBpc0RlZmluZWRJbXBsKGMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY29kZSBwb2ludCBpcyBkZWZpbmVkIGluIHRoZSBVbmljb2RlCisgICAgICogc3BlY2lmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2RlUG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2RlIHBvaW50IHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBnZW5lcmFsIFVuaWNvZGUgY2F0ZWdvcnkgb2YgdGhlIGNvZGUgcG9pbnQgaXMKKyAgICAgKiAgICAgICAgIG5vdCB7QGNvZGUgVU5BU1NJR05FRH07IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0RlZmluZWQoaW50IGNvZGVQb2ludCkgeworICAgICAgICByZXR1cm4gaXNEZWZpbmVkSW1wbChjb2RlUG9pbnQpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBib29sZWFuIGlzRGVmaW5lZEltcGwoaW50IGNvZGVQb2ludCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyBhIGRpZ2l0LgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGN9IGlzIGEgZGlnaXQ7IHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNEaWdpdChjaGFyIGMpIHsKKyAgICAgICAgcmV0dXJuIGlzRGlnaXQoKGludCkgYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjb2RlIHBvaW50IGlzIGEgZGlnaXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29kZVBvaW50CisgICAgICogICAgICAgICAgICB0aGUgY29kZSBwb2ludCB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgY29kZVBvaW50fSBpcyBhIGRpZ2l0OyB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzRGlnaXQoaW50IGNvZGVQb2ludCkgeworICAgICAgICAvLyBPcHRpbWl6ZWQgY2FzZSBmb3IgQVNDSUkKKyAgICAgICAgaWYgKCcwJyA8PSBjb2RlUG9pbnQgJiYgY29kZVBvaW50IDw9ICc5JykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvZGVQb2ludCA8IDE2MzIpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaXNEaWdpdEltcGwoY29kZVBvaW50KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBpc0RpZ2l0SW1wbChpbnQgY29kZVBvaW50KTsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGlnbm9yYWJsZSBpbiBhIEphdmEgb3IKKyAgICAgKiBVbmljb2RlIGlkZW50aWZpZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgY30gaXMgaWdub3JhYmxlOyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNJZGVudGlmaWVySWdub3JhYmxlKGNoYXIgYykgeworICAgICAgICByZXR1cm4gaXNJZGVudGlmaWVySWdub3JhYmxlKChpbnQpIGMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY29kZSBwb2ludCBpcyBpZ25vcmFibGUgaW4gYSBKYXZhIG9yCisgICAgICogVW5pY29kZSBpZGVudGlmaWVyLgorICAgICAqCisgICAgICogQHBhcmFtIGNvZGVQb2ludAorICAgICAqICAgICAgICAgICAgdGhlIGNvZGUgcG9pbnQgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGNvZGVQb2ludH0gaXMgaWdub3JhYmxlOyB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzSWRlbnRpZmllcklnbm9yYWJsZShpbnQgY29kZVBvaW50KSB7CisgICAgICAgIC8vIFRoaXMgaXMgYm90aCBhbiBvcHRpbWl6YXRpb24gYW5kIHBhcGVycyBvdmVyIGRpZmZlcmVuY2VzIGJldHdlZW4gSmF2YSBhbmQgSUNVLgorICAgICAgICBpZiAoY29kZVBvaW50IDwgMHg2MDApIHsKKyAgICAgICAgICAgIHJldHVybiAoY29kZVBvaW50ID49IDAgJiYgY29kZVBvaW50IDw9IDgpIHx8IChjb2RlUG9pbnQgPj0gMHhlICYmIGNvZGVQb2ludCA8PSAweDFiKSB8fAorICAgICAgICAgICAgICAgICAgICAoY29kZVBvaW50ID49IDB4N2YgJiYgY29kZVBvaW50IDw9IDB4OWYpIHx8IChjb2RlUG9pbnQgPT0gMHhhZCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlzSWRlbnRpZmllcklnbm9yYWJsZUltcGwoY29kZVBvaW50KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBpc0lkZW50aWZpZXJJZ25vcmFibGVJbXBsKGludCBjb2RlUG9pbnQpOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgYW4gSVNPIGNvbnRyb2wgY2hhcmFjdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGN9IGlzIGFuIElTTyBjb250cm9sIGNoYXJhY3RlcjsKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0lTT0NvbnRyb2woY2hhciBjKSB7CisgICAgICAgIHJldHVybiBpc0lTT0NvbnRyb2woKGludCkgYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjb2RlIHBvaW50IGlzIGFuIElTTyBjb250cm9sIGNoYXJhY3Rlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY29kZSBwb2ludCB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgY30gaXMgYW4gSVNPIGNvbnRyb2wgY2hhcmFjdGVyOworICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzSVNPQ29udHJvbChpbnQgYykgeworICAgICAgICByZXR1cm4gKGMgPj0gMCAmJiBjIDw9IDB4MWYpIHx8IChjID49IDB4N2YgJiYgYyA8PSAweDlmKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyBhIHZhbGlkIHBhcnQgb2YgYSBKYXZhCisgICAgICogaWRlbnRpZmllciBvdGhlciB0aGFuIHRoZSBmaXJzdCBjaGFyYWN0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgY30gaXMgdmFsaWQgYXMgcGFydCBvZiBhIEphdmEgaWRlbnRpZmllcjsKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0phdmFJZGVudGlmaWVyUGFydChjaGFyIGMpIHsKKyAgICAgICAgcmV0dXJuIGlzSmF2YUlkZW50aWZpZXJQYXJ0KChpbnQpIGMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY29kZSBwb2ludCBpcyBhIHZhbGlkIHBhcnQgb2YgYSBKYXZhCisgICAgICogaWRlbnRpZmllciBvdGhlciB0aGFuIHRoZSBmaXJzdCBjaGFyYWN0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29kZVBvaW50CisgICAgICogICAgICAgICAgICB0aGUgY29kZSBwb2ludCB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgY30gaXMgdmFsaWQgYXMgcGFydCBvZiBhIEphdmEgaWRlbnRpZmllcjsKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0phdmFJZGVudGlmaWVyUGFydChpbnQgY29kZVBvaW50KSB7CisgICAgICAgIC8vIFVzZSBwcmVjb21wdXRlZCBiaXRtYXNrcyB0byBvcHRpbWl6ZSB0aGUgQVNDSUkgcmFuZ2UuCisgICAgICAgIGlmIChjb2RlUG9pbnQgPCA2NCkgeworICAgICAgICAgICAgcmV0dXJuICgweDNmZjAwMTAwZmZmYzFmZkwgJiAoMUwgPDwgY29kZVBvaW50KSkgIT0gMDsKKyAgICAgICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAxMjgpIHsKKyAgICAgICAgICAgIHJldHVybiAoMHg4N2ZmZmZmZTg3ZmZmZmZlTCAmICgxTCA8PCAoY29kZVBvaW50IC0gNjQpKSkgIT0gMDsKKyAgICAgICAgfQorICAgICAgICBpbnQgdHlwZSA9IGdldFR5cGUoY29kZVBvaW50KTsKKyAgICAgICAgcmV0dXJuICh0eXBlID49IFVQUEVSQ0FTRV9MRVRURVIgJiYgdHlwZSA8PSBPVEhFUl9MRVRURVIpCisgICAgICAgICAgICAgICAgfHwgdHlwZSA9PSBDVVJSRU5DWV9TWU1CT0wgfHwgdHlwZSA9PSBDT05ORUNUT1JfUFVOQ1RVQVRJT04KKyAgICAgICAgICAgICAgICB8fCAodHlwZSA+PSBERUNJTUFMX0RJR0lUX05VTUJFUiAmJiB0eXBlIDw9IExFVFRFUl9OVU1CRVIpCisgICAgICAgICAgICAgICAgfHwgdHlwZSA9PSBDT01CSU5JTkdfU1BBQ0lOR19NQVJLIHx8IHR5cGUgPT0gTk9OX1NQQUNJTkdfTUFSSworICAgICAgICAgICAgICAgIHx8IChjb2RlUG9pbnQgPj0gMCAmJiBjb2RlUG9pbnQgPD0gOCkgfHwgKGNvZGVQb2ludCA+PSAweGUgJiYgY29kZVBvaW50IDw9IDB4MWIpCisgICAgICAgICAgICAgICAgfHwgKGNvZGVQb2ludCA+PSAweDdmICYmIGNvZGVQb2ludCA8PSAweDlmKSB8fCB0eXBlID09IEZPUk1BVDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyBhIHZhbGlkIGZpcnN0IGNoYXJhY3RlciBmb3IKKyAgICAgKiBhIEphdmEgaWRlbnRpZmllci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBjfSBpcyBhIHZhbGlkIGZpcnN0IGNoYXJhY3RlciBvZiBhIEphdmEKKyAgICAgKiAgICAgICAgIGlkZW50aWZpZXI7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0phdmFJZGVudGlmaWVyU3RhcnQoY2hhciBjKSB7CisgICAgICAgIHJldHVybiBpc0phdmFJZGVudGlmaWVyU3RhcnQoKGludCkgYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjb2RlIHBvaW50IGlzIGEgdmFsaWQgZmlyc3QgY2hhcmFjdGVyIGZvcgorICAgICAqIGEgSmF2YSBpZGVudGlmaWVyLgorICAgICAqCisgICAgICogQHBhcmFtIGNvZGVQb2ludAorICAgICAqICAgICAgICAgICAgdGhlIGNvZGUgcG9pbnQgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGNvZGVQb2ludH0gaXMgYSB2YWxpZCBzdGFydCBvZiBhIEphdmEKKyAgICAgKiAgICAgICAgIGlkZW50aWZpZXI7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0phdmFJZGVudGlmaWVyU3RhcnQoaW50IGNvZGVQb2ludCkgeworICAgICAgICAvLyBVc2UgcHJlY29tcHV0ZWQgYml0bWFza3MgdG8gb3B0aW1pemUgdGhlIEFTQ0lJIHJhbmdlLgorICAgICAgICBpZiAoY29kZVBvaW50IDwgNjQpIHsKKyAgICAgICAgICAgIHJldHVybiAoY29kZVBvaW50ID09ICckJyk7IC8vIFRoZXJlJ3Mgb25seSBvbmUgY2hhcmFjdGVyIGluIHRoaXMgcmFuZ2UuCisgICAgICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMTI4KSB7CisgICAgICAgICAgICByZXR1cm4gKDB4N2ZmZmZmZTg3ZmZmZmZlTCAmICgxTCA8PCAoY29kZVBvaW50IC0gNjQpKSkgIT0gMDsKKyAgICAgICAgfQorICAgICAgICBpbnQgdHlwZSA9IGdldFR5cGUoY29kZVBvaW50KTsKKyAgICAgICAgcmV0dXJuICh0eXBlID49IFVQUEVSQ0FTRV9MRVRURVIgJiYgdHlwZSA8PSBPVEhFUl9MRVRURVIpIHx8IHR5cGUgPT0gQ1VSUkVOQ1lfU1lNQk9MCisgICAgICAgICAgICAgICAgfHwgdHlwZSA9PSBDT05ORUNUT1JfUFVOQ1RVQVRJT04gfHwgdHlwZSA9PSBMRVRURVJfTlVNQkVSOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgSmF2YSBsZXR0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgY30gaXMgYSBKYXZhIGxldHRlcjsge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2lzSmF2YUlkZW50aWZpZXJTdGFydChjaGFyKX0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0phdmFMZXR0ZXIoY2hhciBjKSB7CisgICAgICAgIHJldHVybiBpc0phdmFJZGVudGlmaWVyU3RhcnQoYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgYSBKYXZhIGxldHRlciBvciBkaWdpdAorICAgICAqIGNoYXJhY3Rlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBjfSBpcyBhIEphdmEgbGV0dGVyIG9yIGRpZ2l0OworICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjaXNKYXZhSWRlbnRpZmllclBhcnQoY2hhcil9CisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNKYXZhTGV0dGVyT3JEaWdpdChjaGFyIGMpIHsKKyAgICAgICAgcmV0dXJuIGlzSmF2YUlkZW50aWZpZXJQYXJ0KGMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgbGV0dGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGN9IGlzIGEgbGV0dGVyOyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNMZXR0ZXIoY2hhciBjKSB7CisgICAgICAgIHJldHVybiBpc0xldHRlcigoaW50KSBjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGNvZGUgcG9pbnQgaXMgYSBsZXR0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29kZVBvaW50CisgICAgICogICAgICAgICAgICB0aGUgY29kZSBwb2ludCB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgY29kZVBvaW50fSBpcyBhIGxldHRlcjsge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0xldHRlcihpbnQgY29kZVBvaW50KSB7CisgICAgICAgIGlmICgoJ0EnIDw9IGNvZGVQb2ludCAmJiBjb2RlUG9pbnQgPD0gJ1onKSB8fCAoJ2EnIDw9IGNvZGVQb2ludCAmJiBjb2RlUG9pbnQgPD0gJ3onKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvZGVQb2ludCA8IDEyOCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpc0xldHRlckltcGwoY29kZVBvaW50KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBpc0xldHRlckltcGwoaW50IGNvZGVQb2ludCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyBhIGxldHRlciBvciBhIGRpZ2l0LgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGN9IGlzIGEgbGV0dGVyIG9yIGEgZGlnaXQ7IHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNMZXR0ZXJPckRpZ2l0KGNoYXIgYykgeworICAgICAgICByZXR1cm4gaXNMZXR0ZXJPckRpZ2l0KChpbnQpIGMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY29kZSBwb2ludCBpcyBhIGxldHRlciBvciBhIGRpZ2l0LgorICAgICAqCisgICAgICogQHBhcmFtIGNvZGVQb2ludAorICAgICAqICAgICAgICAgICAgdGhlIGNvZGUgcG9pbnQgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGNvZGVQb2ludH0gaXMgYSBsZXR0ZXIgb3IgYSBkaWdpdDsKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0xldHRlck9yRGlnaXQoaW50IGNvZGVQb2ludCkgeworICAgICAgICAvLyBPcHRpbWl6ZWQgY2FzZSBmb3IgQVNDSUkKKyAgICAgICAgaWYgKCgnQScgPD0gY29kZVBvaW50ICYmIGNvZGVQb2ludCA8PSAnWicpIHx8ICgnYScgPD0gY29kZVBvaW50ICYmIGNvZGVQb2ludCA8PSAneicpKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoJzAnIDw9IGNvZGVQb2ludCAmJiBjb2RlUG9pbnQgPD0gJzknKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY29kZVBvaW50IDwgMTI4KSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlzTGV0dGVyT3JEaWdpdEltcGwoY29kZVBvaW50KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBpc0xldHRlck9yRGlnaXRJbXBsKGludCBjb2RlUG9pbnQpOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgYSBsb3dlciBjYXNlIGxldHRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBjfSBpcyBhIGxvd2VyIGNhc2UgbGV0dGVyOyB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTG93ZXJDYXNlKGNoYXIgYykgeworICAgICAgICByZXR1cm4gaXNMb3dlckNhc2UoKGludCkgYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjb2RlIHBvaW50IGlzIGEgbG93ZXIgY2FzZSBsZXR0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29kZVBvaW50CisgICAgICogICAgICAgICAgICB0aGUgY29kZSBwb2ludCB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgY29kZVBvaW50fSBpcyBhIGxvd2VyIGNhc2UgbGV0dGVyOworICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTG93ZXJDYXNlKGludCBjb2RlUG9pbnQpIHsKKyAgICAgICAgLy8gT3B0aW1pemVkIGNhc2UgZm9yIEFTQ0lJCisgICAgICAgIGlmICgnYScgPD0gY29kZVBvaW50ICYmIGNvZGVQb2ludCA8PSAneicpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChjb2RlUG9pbnQgPCAxMjgpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaXNMb3dlckNhc2VJbXBsKGNvZGVQb2ludCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gaXNMb3dlckNhc2VJbXBsKGludCBjb2RlUG9pbnQpOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgYSBKYXZhIHNwYWNlLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGN9IGlzIGEgSmF2YSBzcGFjZTsge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2lzV2hpdGVzcGFjZShjaGFyKX0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1NwYWNlKGNoYXIgYykgeworICAgICAgICByZXR1cm4gYyA9PSAnXG4nIHx8IGMgPT0gJ1x0JyB8fCBjID09ICdcZicgfHwgYyA9PSAnXHInIHx8IGMgPT0gJyAnOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgVW5pY29kZSBzcGFjZSBjaGFyYWN0ZXIuCisgICAgICogVGhhdCBpcywgaWYgaXQgaXMgYSBtZW1iZXIgb2Ygb25lIG9mIHRoZSBVbmljb2RlIGNhdGVnb3JpZXMgU3BhY2UKKyAgICAgKiBTZXBhcmF0b3IsIExpbmUgU2VwYXJhdG9yLCBvciBQYXJhZ3JhcGggU2VwYXJhdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGN9IGlzIGEgVW5pY29kZSBzcGFjZSBjaGFyYWN0ZXIsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNTcGFjZUNoYXIoY2hhciBjKSB7CisgICAgICAgIHJldHVybiBpc1NwYWNlQ2hhcigoaW50KSBjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGNvZGUgcG9pbnQgaXMgYSBVbmljb2RlIHNwYWNlIGNoYXJhY3Rlci4KKyAgICAgKiBUaGF0IGlzLCBpZiBpdCBpcyBhIG1lbWJlciBvZiBvbmUgb2YgdGhlIFVuaWNvZGUgY2F0ZWdvcmllcyBTcGFjZQorICAgICAqIFNlcGFyYXRvciwgTGluZSBTZXBhcmF0b3IsIG9yIFBhcmFncmFwaCBTZXBhcmF0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29kZVBvaW50CisgICAgICogICAgICAgICAgICB0aGUgY29kZSBwb2ludCB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgY29kZVBvaW50fSBpcyBhIFVuaWNvZGUgc3BhY2UgY2hhcmFjdGVyLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzU3BhY2VDaGFyKGludCBjb2RlUG9pbnQpIHsKKyAgICAgICAgaWYgKGNvZGVQb2ludCA9PSAweDIwIHx8IGNvZGVQb2ludCA9PSAweGEwIHx8IGNvZGVQb2ludCA9PSAweDE2ODApIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChjb2RlUG9pbnQgPCAweDIwMDApIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY29kZVBvaW50IDw9IDB4ZmZmZikgeworICAgICAgICAgICAgcmV0dXJuIGNvZGVQb2ludCA8PSAweDIwMGIgfHwgY29kZVBvaW50ID09IDB4MjAyOCB8fCBjb2RlUG9pbnQgPT0gMHgyMDI5IHx8CisgICAgICAgICAgICAgICAgICAgIGNvZGVQb2ludCA9PSAweDIwMmYgfHwgY29kZVBvaW50ID09IDB4MzAwMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaXNTcGFjZUNoYXJJbXBsKGNvZGVQb2ludCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gaXNTcGFjZUNoYXJJbXBsKGludCBjb2RlUG9pbnQpOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgYSB0aXRsZWNhc2UgY2hhcmFjdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGN9IGlzIGEgdGl0bGVjYXNlIGNoYXJhY3Rlciwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1RpdGxlQ2FzZShjaGFyIGMpIHsKKyAgICAgICAgcmV0dXJuIGlzVGl0bGVDYXNlSW1wbChjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGNvZGUgcG9pbnQgaXMgYSB0aXRsZWNhc2UgY2hhcmFjdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGNvZGVQb2ludAorICAgICAqICAgICAgICAgICAgdGhlIGNvZGUgcG9pbnQgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGNvZGVQb2ludH0gaXMgYSB0aXRsZWNhc2UgY2hhcmFjdGVyLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzVGl0bGVDYXNlKGludCBjb2RlUG9pbnQpIHsKKyAgICAgICAgcmV0dXJuIGlzVGl0bGVDYXNlSW1wbChjb2RlUG9pbnQpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBib29sZWFuIGlzVGl0bGVDYXNlSW1wbChpbnQgY29kZVBvaW50KTsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIHZhbGlkIGFzIHBhcnQgb2YgYSBVbmljb2RlCisgICAgICogaWRlbnRpZmllciBvdGhlciB0aGFuIHRoZSBmaXJzdCBjaGFyYWN0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgY30gaXMgdmFsaWQgYXMgcGFydCBvZiBhIFVuaWNvZGUKKyAgICAgKiAgICAgICAgIGlkZW50aWZpZXI7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1VuaWNvZGVJZGVudGlmaWVyUGFydChjaGFyIGMpIHsKKyAgICAgICAgcmV0dXJuIGlzVW5pY29kZUlkZW50aWZpZXJQYXJ0SW1wbChjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGNvZGUgcG9pbnQgaXMgdmFsaWQgYXMgcGFydCBvZiBhIFVuaWNvZGUKKyAgICAgKiBpZGVudGlmaWVyIG90aGVyIHRoYW4gdGhlIGZpcnN0IGNoYXJhY3Rlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2RlUG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2RlIHBvaW50IHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBjb2RlUG9pbnR9IGlzIHZhbGlkIGFzIHBhcnQgb2YgYSBVbmljb2RlCisgICAgICogICAgICAgICBpZGVudGlmaWVyOyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNVbmljb2RlSWRlbnRpZmllclBhcnQoaW50IGNvZGVQb2ludCkgeworICAgICAgICByZXR1cm4gaXNVbmljb2RlSWRlbnRpZmllclBhcnRJbXBsKGNvZGVQb2ludCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gaXNVbmljb2RlSWRlbnRpZmllclBhcnRJbXBsKGludCBjb2RlUG9pbnQpOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgYSB2YWxpZCBpbml0aWFsIGNoYXJhY3RlcgorICAgICAqIGZvciBhIFVuaWNvZGUgaWRlbnRpZmllci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBjfSBpcyBhIHZhbGlkIGZpcnN0IGNoYXJhY3RlciBmb3IgYQorICAgICAqICAgICAgICAgVW5pY29kZSBpZGVudGlmaWVyOyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNVbmljb2RlSWRlbnRpZmllclN0YXJ0KGNoYXIgYykgeworICAgICAgICByZXR1cm4gaXNVbmljb2RlSWRlbnRpZmllclN0YXJ0SW1wbChjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGNvZGUgcG9pbnQgaXMgYSB2YWxpZCBpbml0aWFsIGNoYXJhY3RlcgorICAgICAqIGZvciBhIFVuaWNvZGUgaWRlbnRpZmllci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2RlUG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2RlIHBvaW50IHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBjb2RlUG9pbnR9IGlzIGEgdmFsaWQgZmlyc3QgY2hhcmFjdGVyIGZvcgorICAgICAqICAgICAgICAgYSBVbmljb2RlIGlkZW50aWZpZXI7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1VuaWNvZGVJZGVudGlmaWVyU3RhcnQoaW50IGNvZGVQb2ludCkgeworICAgICAgICByZXR1cm4gaXNVbmljb2RlSWRlbnRpZmllclN0YXJ0SW1wbChjb2RlUG9pbnQpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBib29sZWFuIGlzVW5pY29kZUlkZW50aWZpZXJTdGFydEltcGwoaW50IGNvZGVQb2ludCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyBhbiB1cHBlciBjYXNlIGxldHRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBjfSBpcyBhIHVwcGVyIGNhc2UgbGV0dGVyOyB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzVXBwZXJDYXNlKGNoYXIgYykgeworICAgICAgICByZXR1cm4gaXNVcHBlckNhc2UoKGludCkgYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjb2RlIHBvaW50IGlzIGFuIHVwcGVyIGNhc2UgbGV0dGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGNvZGVQb2ludAorICAgICAqICAgICAgICAgICAgdGhlIGNvZGUgcG9pbnQgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGNvZGVQb2ludH0gaXMgYSB1cHBlciBjYXNlIGxldHRlcjsKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1VwcGVyQ2FzZShpbnQgY29kZVBvaW50KSB7CisgICAgICAgIC8vIE9wdGltaXplZCBjYXNlIGZvciBBU0NJSQorICAgICAgICBpZiAoJ0EnIDw9IGNvZGVQb2ludCAmJiBjb2RlUG9pbnQgPD0gJ1onKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY29kZVBvaW50IDwgMTI4KSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlzVXBwZXJDYXNlSW1wbChjb2RlUG9pbnQpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBib29sZWFuIGlzVXBwZXJDYXNlSW1wbChpbnQgY29kZVBvaW50KTsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgd2hpdGVzcGFjZSBjaGFyYWN0ZXIgaW4KKyAgICAgKiBKYXZhLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHN1cHBsaWVkIHtAY29kZSBjfSBpcyBhIHdoaXRlc3BhY2UgY2hhcmFjdGVyCisgICAgICogICAgICAgICBpbiBKYXZhOyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNXaGl0ZXNwYWNlKGNoYXIgYykgeworICAgICAgICByZXR1cm4gaXNXaGl0ZXNwYWNlKChpbnQpIGMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY29kZSBwb2ludCBpcyBhIHdoaXRlc3BhY2UgY2hhcmFjdGVyIGluCisgICAgICogSmF2YS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2RlUG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2RlIHBvaW50IHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzdXBwbGllZCB7QGNvZGUgY30gaXMgYSB3aGl0ZXNwYWNlIGNoYXJhY3RlcgorICAgICAqICAgICAgICAgaW4gSmF2YTsge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzV2hpdGVzcGFjZShpbnQgY29kZVBvaW50KSB7CisgICAgICAgIC8vIFRoaXMgaXMgYm90aCBhbiBvcHRpbWl6YXRpb24gYW5kIHBhcGVycyBvdmVyIGRpZmZlcmVuY2VzIGJldHdlZW4gSmF2YSBhbmQgSUNVLgorICAgICAgICBpZiAoKGNvZGVQb2ludCA+PSAweDFjICYmIGNvZGVQb2ludCA8PSAweDIwKSB8fCAoY29kZVBvaW50ID49IDB4OSAmJiBjb2RlUG9pbnQgPD0gMHhkKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvZGVQb2ludCA9PSAweDE2ODApIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChjb2RlUG9pbnQgPCAweDIwMDAgfHwgY29kZVBvaW50ID09IDB4MjAwNykgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmIChjb2RlUG9pbnQgPD0gMHhmZmZmKSB7CisgICAgICAgICAgICByZXR1cm4gY29kZVBvaW50IDw9IDB4MjAwYiB8fCBjb2RlUG9pbnQgPT0gMHgyMDI4IHx8IGNvZGVQb2ludCA9PSAweDIwMjkgfHwKKyAgICAgICAgICAgICAgICAgICAgY29kZVBvaW50ID09IDB4MzAwMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaXNXaGl0ZXNwYWNlSW1wbChjb2RlUG9pbnQpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBib29sZWFuIGlzV2hpdGVzcGFjZUltcGwoaW50IGNvZGVQb2ludCk7CisKKyAgICAvKioKKyAgICAgKiBSZXZlcnNlcyB0aGUgb3JkZXIgb2YgdGhlIGZpcnN0IGFuZCBzZWNvbmQgYnl0ZSBpbiB0aGUgc3BlY2lmaWVkCisgICAgICogY2hhcmFjdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gcmV2ZXJzZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFyYWN0ZXIgd2l0aCByZW9yZGVyZWQgYnl0ZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjaGFyIHJldmVyc2VCeXRlcyhjaGFyIGMpIHsKKyAgICAgICAgcmV0dXJuIChjaGFyKSgoYzw8OCkgfCAoYz4+OCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxvd2VyIGNhc2UgZXF1aXZhbGVudCBmb3IgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaWYgdGhlCisgICAgICogY2hhcmFjdGVyIGlzIGFuIHVwcGVyIGNhc2UgbGV0dGVyLiBPdGhlcndpc2UsIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzCisgICAgICogcmV0dXJuZWQgdW5jaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIKKyAgICAgKiBAcmV0dXJuIGlmIHtAY29kZSBjfSBpcyBhbiB1cHBlciBjYXNlIGNoYXJhY3RlciB0aGVuIGl0cyBsb3dlciBjYXNlCisgICAgICogICAgICAgICBjb3VudGVycGFydCwgb3RoZXJ3aXNlIGp1c3Qge0Bjb2RlIGN9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2hhciB0b0xvd2VyQ2FzZShjaGFyIGMpIHsKKyAgICAgICAgcmV0dXJuIChjaGFyKSB0b0xvd2VyQ2FzZSgoaW50KSBjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb3dlciBjYXNlIGVxdWl2YWxlbnQgZm9yIHRoZSBzcGVjaWZpZWQgY29kZSBwb2ludCBpZiBpdCBpcworICAgICAqIGFuIHVwcGVyIGNhc2UgbGV0dGVyLiBPdGhlcndpc2UsIHRoZSBzcGVjaWZpZWQgY29kZSBwb2ludCBpcyByZXR1cm5lZAorICAgICAqIHVuY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2RlUG9pbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2RlIHBvaW50IHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4gaWYge0Bjb2RlIGNvZGVQb2ludH0gaXMgYW4gdXBwZXIgY2FzZSBjaGFyYWN0ZXIgdGhlbiBpdHMgbG93ZXIKKyAgICAgKiAgICAgICAgIGNhc2UgY291bnRlcnBhcnQsIG90aGVyd2lzZSBqdXN0IHtAY29kZSBjb2RlUG9pbnR9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHRvTG93ZXJDYXNlKGludCBjb2RlUG9pbnQpIHsKKyAgICAgICAgLy8gT3B0aW1pemVkIGNhc2UgZm9yIEFTQ0lJCisgICAgICAgIGlmICgnQScgPD0gY29kZVBvaW50ICYmIGNvZGVQb2ludCA8PSAnWicpIHsKKyAgICAgICAgICAgIHJldHVybiAoY2hhcikgKGNvZGVQb2ludCArICgnYScgLSAnQScpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY29kZVBvaW50IDwgMTkyKSB7CisgICAgICAgICAgICByZXR1cm4gY29kZVBvaW50OworICAgICAgICB9CisgICAgICAgIHJldHVybiB0b0xvd2VyQ2FzZUltcGwoY29kZVBvaW50KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IHRvTG93ZXJDYXNlSW1wbChpbnQgY29kZVBvaW50KTsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBTdHJpbmcudmFsdWVPZih2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgdG8gaXRzIHN0cmluZyByZXByZXNlbnRhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciB0byBjb252ZXJ0LgorICAgICAqIEByZXR1cm4gdGhlIGNoYXJhY3RlciBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoY2hhciB2YWx1ZSkgeworICAgICAgICByZXR1cm4gU3RyaW5nLnZhbHVlT2YodmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRpdGxlIGNhc2UgZXF1aXZhbGVudCBmb3IgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaWYgaXQKKyAgICAgKiBleGlzdHMuIE90aGVyd2lzZSwgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgcmV0dXJuZWQgdW5jaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gY29udmVydC4KKyAgICAgKiBAcmV0dXJuIHRoZSB0aXRsZSBjYXNlIGVxdWl2YWxlbnQgb2Yge0Bjb2RlIGN9IGlmIGl0IGV4aXN0cywgb3RoZXJ3aXNlCisgICAgICogICAgICAgICB7QGNvZGUgY30uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjaGFyIHRvVGl0bGVDYXNlKGNoYXIgYykgeworICAgICAgICByZXR1cm4gKGNoYXIpIHRvVGl0bGVDYXNlSW1wbChjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0aXRsZSBjYXNlIGVxdWl2YWxlbnQgZm9yIHRoZSBzcGVjaWZpZWQgY29kZSBwb2ludCBpZiBpdAorICAgICAqIGV4aXN0cy4gT3RoZXJ3aXNlLCB0aGUgc3BlY2lmaWVkIGNvZGUgcG9pbnQgaXMgcmV0dXJuZWQgdW5jaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGNvZGVQb2ludAorICAgICAqICAgICAgICAgICAgdGhlIGNvZGUgcG9pbnQgdG8gY29udmVydC4KKyAgICAgKiBAcmV0dXJuIHRoZSB0aXRsZSBjYXNlIGVxdWl2YWxlbnQgb2Yge0Bjb2RlIGNvZGVQb2ludH0gaWYgaXQgZXhpc3RzLAorICAgICAqICAgICAgICAgb3RoZXJ3aXNlIHtAY29kZSBjb2RlUG9pbnR9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHRvVGl0bGVDYXNlKGludCBjb2RlUG9pbnQpIHsKKyAgICAgICAgcmV0dXJuIHRvVGl0bGVDYXNlSW1wbChjb2RlUG9pbnQpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgdG9UaXRsZUNhc2VJbXBsKGludCBjb2RlUG9pbnQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdXBwZXIgY2FzZSBlcXVpdmFsZW50IGZvciB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpZiB0aGUKKyAgICAgKiBjaGFyYWN0ZXIgaXMgYSBsb3dlciBjYXNlIGxldHRlci4gT3RoZXJ3aXNlLCB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcworICAgICAqIHJldHVybmVkIHVuY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIGNvbnZlcnQuCisgICAgICogQHJldHVybiBpZiB7QGNvZGUgY30gaXMgYSBsb3dlciBjYXNlIGNoYXJhY3RlciB0aGVuIGl0cyB1cHBlciBjYXNlCisgICAgICogICAgICAgICBjb3VudGVycGFydCwgb3RoZXJ3aXNlIGp1c3Qge0Bjb2RlIGN9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2hhciB0b1VwcGVyQ2FzZShjaGFyIGMpIHsKKyAgICAgICAgcmV0dXJuIChjaGFyKSB0b1VwcGVyQ2FzZSgoaW50KSBjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB1cHBlciBjYXNlIGVxdWl2YWxlbnQgZm9yIHRoZSBzcGVjaWZpZWQgY29kZSBwb2ludCBpZiB0aGUKKyAgICAgKiBjb2RlIHBvaW50IGlzIGEgbG93ZXIgY2FzZSBsZXR0ZXIuIE90aGVyd2lzZSwgdGhlIHNwZWNpZmllZCBjb2RlIHBvaW50IGlzCisgICAgICogcmV0dXJuZWQgdW5jaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGNvZGVQb2ludAorICAgICAqICAgICAgICAgICAgdGhlIGNvZGUgcG9pbnQgdG8gY29udmVydC4KKyAgICAgKiBAcmV0dXJuIGlmIHtAY29kZSBjb2RlUG9pbnR9IGlzIGEgbG93ZXIgY2FzZSBjaGFyYWN0ZXIgdGhlbiBpdHMgdXBwZXIKKyAgICAgKiAgICAgICAgIGNhc2UgY291bnRlcnBhcnQsIG90aGVyd2lzZSBqdXN0IHtAY29kZSBjb2RlUG9pbnR9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHRvVXBwZXJDYXNlKGludCBjb2RlUG9pbnQpIHsKKyAgICAgICAgLy8gT3B0aW1pemVkIGNhc2UgZm9yIEFTQ0lJCisgICAgICAgIGlmICgnYScgPD0gY29kZVBvaW50ICYmIGNvZGVQb2ludCA8PSAneicpIHsKKyAgICAgICAgICAgIHJldHVybiAoY2hhcikgKGNvZGVQb2ludCAtICgnYScgLSAnQScpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY29kZVBvaW50IDwgMTgxKSB7CisgICAgICAgICAgICByZXR1cm4gY29kZVBvaW50OworICAgICAgICB9CisgICAgICAgIHJldHVybiB0b1VwcGVyQ2FzZUltcGwoY29kZVBvaW50KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IHRvVXBwZXJDYXNlSW1wbChpbnQgY29kZVBvaW50KTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQ2xhc3MuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQ2xhc3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNjE4M2E1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9DbGFzcy5qYXZhCkBAIC0wLDAgKzEsMTQxOSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKgorICogQ29weXJpZ2h0IChDKSAyMDA2LTIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworaW1wb3J0IGRhbHZpay5zeXN0ZW0uVk1TdGFjazsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uSW5oZXJpdGVkOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkFubm90YXRlZEVsZW1lbnQ7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuRmllbGQ7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuR2VuZXJpY0RlY2xhcmF0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1lbWJlcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXI7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5UeXBlVmFyaWFibGU7CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdGVjdGlvbkRvbWFpbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgbGliY29yZS51dGlsLkNvbGxlY3Rpb25VdGlsczsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuRW1wdHlBcnJheTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkua2VybmVsLnZtLlN0cmluZ1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLmxhbmcucmVmbGVjdC5HZW5lcmljU2lnbmF0dXJlUGFyc2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLmxhbmcucmVmbGVjdC5UeXBlczsKKworLyoqCisgKiBUaGUgaW4tbWVtb3J5IHJlcHJlc2VudGF0aW9uIG9mIGEgSmF2YSBjbGFzcy4gVGhpcyByZXByZXNlbnRhdGlvbiBzZXJ2ZXMgYXMKKyAqIHRoZSBzdGFydGluZyBwb2ludCBmb3IgcXVlcnlpbmcgY2xhc3MtcmVsYXRlZCBpbmZvcm1hdGlvbiwgYSBwcm9jZXNzIHVzdWFsbHkKKyAqIGNhbGxlZCAicmVmbGVjdGlvbiIuIFRoZXJlIGFyZSBiYXNpY2FsbHkgdGhyZWUgdHlwZXMgb2Yge0Bjb2RlIENsYXNzfQorICogaW5zdGFuY2VzOiB0aG9zZSByZXByZXNlbnRpbmcgcmVhbCBjbGFzc2VzIGFuZCBpbnRlcmZhY2VzLCB0aG9zZSByZXByZXNlbnRpbmcKKyAqIHByaW1pdGl2ZSB0eXBlcywgYW5kIHRob3NlIHJlcHJlc2VudGluZyBhcnJheSBjbGFzc2VzLgorICoKKyAqIDxoND5DbGFzcyBpbnN0YW5jZXMgcmVwcmVzZW50aW5nIG9iamVjdCB0eXBlcyAoY2xhc3NlcyBvciBpbnRlcmZhY2VzKTwvaDQ+CisgKiA8cD4KKyAqIFRoZXNlIHJlcHJlc2VudCBhbiBvcmRpbmFyeSBjbGFzcyBvciBpbnRlcmZhY2UgYXMgZm91bmQgaW4gdGhlIGNsYXNzCisgKiBoaWVyYXJjaHkuIFRoZSBuYW1lIGFzc29jaWF0ZWQgd2l0aCB0aGVzZSB7QGNvZGUgQ2xhc3N9IGluc3RhbmNlcyBpcyBzaW1wbHkKKyAqIHRoZSBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZSBvZiB0aGUgY2xhc3Mgb3IgaW50ZXJmYWNlIHRoYXQgaXQgcmVwcmVzZW50cy4KKyAqIEluIGFkZGl0aW9uIHRvIHRoaXMgaHVtYW4tcmVhZGFibGUgbmFtZSwgZWFjaCBjbGFzcyBpcyBhbHNvIGFzc29jaWF0ZWQgYnkgYQorICogc28tY2FsbGVkIDxlbT5zaWduYXR1cmU8L2VtPiwgd2hpY2ggaXMgdGhlIGxldHRlciAiTCIsIGZvbGxvd2VkIGJ5IHRoZQorICogY2xhc3MgbmFtZSBhbmQgYSBzZW1pY29sb24gKCI7IikuIFRoZSBzaWduYXR1cmUgaXMgd2hhdCB0aGUgcnVudGltZSBzeXN0ZW0KKyAqIHVzZXMgaW50ZXJuYWxseSBmb3IgaWRlbnRpZnlpbmcgdGhlIGNsYXNzIChmb3IgZXhhbXBsZSBpbiBhIERFWCBmaWxlKS4KKyAqIDwvcD4KKyAqIDxoND5DbGFzc2VzIHJlcHJlc2VudGluZyBwcmltaXRpdmUgdHlwZXM8L2g0PgorICogPHA+CisgKiBUaGVzZSByZXByZXNlbnQgdGhlIHN0YW5kYXJkIEphdmEgcHJpbWl0aXZlIHR5cGVzIGFuZCBoZW5jZSBzaGFyZSB0aGVpcgorICogbmFtZXMgKGZvciBleGFtcGxlICJpbnQiIGZvciB0aGUge0Bjb2RlIGludH0gcHJpbWl0aXZlIHR5cGUpLiBBbHRob3VnaCBpdCBpcworICogbm90IHBvc3NpYmxlIHRvIGNyZWF0ZSBuZXcgaW5zdGFuY2VzIGJhc2VkIG9uIHRoZXNlIHtAY29kZSBDbGFzc30gaW5zdGFuY2VzLAorICogdGhleSBhcmUgc3RpbGwgdXNlZnVsIGZvciBwcm92aWRpbmcgcmVmbGVjdGlvbiBpbmZvcm1hdGlvbiwgYW5kIGFzIHRoZQorICogY29tcG9uZW50IHR5cGUgb2YgYXJyYXkgY2xhc3Nlcy4gVGhlcmUgaXMgb25lIHtAY29kZSBDbGFzc30gaW5zdGFuY2UgZm9yIGVhY2gKKyAqIHByaW1pdGl2ZSB0eXBlLCBhbmQgdGhlaXIgc2lnbmF0dXJlcyBhcmU6CisgKiA8L3A+CisgKiA8dWw+CisgKiA8bGk+e0Bjb2RlIEJ9IHJlcHJlc2VudGluZyB0aGUge0Bjb2RlIGJ5dGV9IHByaW1pdGl2ZSB0eXBlPC9saT4KKyAqIDxsaT57QGNvZGUgU30gcmVwcmVzZW50aW5nIHRoZSB7QGNvZGUgc2hvcnR9IHByaW1pdGl2ZSB0eXBlPC9saT4KKyAqIDxsaT57QGNvZGUgSX0gcmVwcmVzZW50aW5nIHRoZSB7QGNvZGUgaW50fSBwcmltaXRpdmUgdHlwZTwvbGk+CisgKiA8bGk+e0Bjb2RlIEp9IHJlcHJlc2VudGluZyB0aGUge0Bjb2RlIGxvbmd9IHByaW1pdGl2ZSB0eXBlPC9saT4KKyAqIDxsaT57QGNvZGUgRn0gcmVwcmVzZW50aW5nIHRoZSB7QGNvZGUgZmxvYXR9IHByaW1pdGl2ZSB0eXBlPC9saT4KKyAqIDxsaT57QGNvZGUgRH0gcmVwcmVzZW50aW5nIHRoZSB7QGNvZGUgZG91YmxlfSBwcmltaXRpdmUgdHlwZTwvbGk+CisgKiA8bGk+e0Bjb2RlIEN9IHJlcHJlc2VudGluZyB0aGUge0Bjb2RlIGNoYXJ9IHByaW1pdGl2ZSB0eXBlPC9saT4KKyAqIDxsaT57QGNvZGUgWn0gcmVwcmVzZW50aW5nIHRoZSB7QGNvZGUgYm9vbGVhbn0gcHJpbWl0aXZlIHR5cGU8L2xpPgorICogPGxpPntAY29kZSBWfSByZXByZXNlbnRpbmcgdm9pZCBmdW5jdGlvbiByZXR1cm4gdmFsdWVzPC9saT4KKyAqIDwvdWw+CisgKiA8cD4KKyAqIDxoND5DbGFzc2VzIHJlcHJlc2VudGluZyBhcnJheSBjbGFzc2VzPC9oND4KKyAqIDxwPgorICogVGhlc2UgcmVwcmVzZW50IHRoZSBjbGFzc2VzIG9mIEphdmEgYXJyYXlzLiBUaGVyZSBpcyBvbmUgc3VjaCB7QGNvZGUgQ2xhc3N9CisgKiBpbnN0YW5jZSBwZXIgY29tYmluYXRpb24gb2YgYXJyYXkgbGVhZiBjb21wb25lbnQgdHlwZSBhbmQgYXJpdHkgKG51bWJlciBvZgorICogZGltZW5zaW9ucykuIEluIHRoaXMgY2FzZSwgdGhlIG5hbWUgYXNzb2NpYXRlZCB3aXRoIHRoZSB7QGNvZGUgQ2xhc3N9CisgKiBjb25zaXN0cyBvZiBvbmUgb3IgbW9yZSBsZWZ0IHNxdWFyZSBicmFja2V0cyAob25lIHBlciBkaW1lbnNpb24gaW4gdGhlIGFycmF5KQorICogZm9sbG93ZWQgYnkgdGhlIHNpZ25hdHVyZSBvZiB0aGUgY2xhc3MgcmVwcmVzZW50aW5nIHRoZSBsZWFmIGNvbXBvbmVudCB0eXBlLAorICogd2hpY2ggY2FuIGJlIGVpdGhlciBhbiBvYmplY3QgdHlwZSBvciBhIHByaW1pdGl2ZSB0eXBlLiBUaGUgc2lnbmF0dXJlIG9mIGEKKyAqIHtAY29kZSBDbGFzc30gcmVwcmVzZW50aW5nIGFuIGFycmF5IHR5cGUgaXMgdGhlIHNhbWUgYXMgaXRzIG5hbWUuIEV4YW1wbGVzCisgKiBvZiBhcnJheSBjbGFzcyBzaWduYXR1cmVzIGFyZToKKyAqIDwvcD4KKyAqIDx1bD4KKyAqIDxsaT57QGNvZGUgW0l9IHJlcHJlc2VudGluZyB0aGUge0Bjb2RlIGludFtdfSB0eXBlPC9saT4KKyAqIDxsaT57QGNvZGUgW0xqYXZhL2xhbmcvU3RyaW5nO30gcmVwcmVzZW50aW5nIHRoZSB7QGNvZGUgU3RyaW5nW119IHR5cGU8L2xpPgorICogPGxpPntAY29kZSBbW1tDfSByZXByZXNlbnRpbmcgdGhlIHtAY29kZSBjaGFyW11bXVtdfSB0eXBlICh0aHJlZSBkaW1lbnNpb25zISk8L2xpPgorICogPC91bD4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIENsYXNzPFQ+IGltcGxlbWVudHMgU2VyaWFsaXphYmxlLCBBbm5vdGF0ZWRFbGVtZW50LCBHZW5lcmljRGVjbGFyYXRpb24sIFR5cGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzIwNjA5MzQ1OTc2MDg0NjE2M0w7CisKKyAgICAvKioKKyAgICAgKiBMYXppbHkgY29tcHV0ZWQgbmFtZSBvZiB0aGlzIGNsYXNzOyBhbHdheXMgcHJlZmVyIGNhbGxpbmcgZ2V0TmFtZSgpLgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IFN0cmluZyBuYW1lOworCisgICAgcHJpdmF0ZSBDbGFzcygpIHsKKyAgICAgICAgLy8gUHJldmVudCB0aGlzIGNsYXNzIHRvIGJlIGluc3RhbnRpYXRlZCwgaW5zdGFuY2UKKyAgICAgICAgLy8gc2hvdWxkIGJlIGNyZWF0ZWQgYnkgSlZNIG9ubHkKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIFNpZ25hdHVyZSBhdHRyaWJ1dGUgZm9yIHRoaXMgY2xhc3MuICBSZXR1cm5zIG51bGwgaWYgbm90IGZvdW5kLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGdldFNpZ25hdHVyZUF0dHJpYnV0ZSgpIHsKKyAgICAgICAgT2JqZWN0W10gYW5ub3RhdGlvbiA9IGdldFNpZ25hdHVyZUFubm90YXRpb24oKTsKKworICAgICAgICBpZiAoYW5ub3RhdGlvbiA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBTdHJpbmdVdGlscy5jb21iaW5lU3RyaW5ncyhhbm5vdGF0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIFNpZ25hdHVyZSBhbm5vdGF0aW9uIGZvciB0aGlzIGNsYXNzLiAgUmV0dXJucyBudWxsIGlmIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICBuYXRpdmUgcHJpdmF0ZSBPYmplY3RbXSBnZXRTaWduYXR1cmVBbm5vdGF0aW9uKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIENsYXNzfSBvYmplY3Qgd2hpY2ggcmVwcmVzZW50cyB0aGUgY2xhc3Mgd2l0aCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgbmFtZS4gVGhlIG5hbWUgc2hvdWxkIGJlIHRoZSBuYW1lIG9mIGEgY2xhc3MgYXMgZGVzY3JpYmVkIGluCisgICAgICogdGhlIHtAbGluayBDbGFzcyBjbGFzcyBkZWZpbml0aW9ufTsgaG93ZXZlciwge0Bjb2RlIENsYXNzfWVzIHJlcHJlc2VudGluZworICAgICAqIHByaW1pdGl2ZSB0eXBlcyBjYW4gbm90IGJlIGZvdW5kIHVzaW5nIHRoaXMgbWV0aG9kLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBjbGFzcyBoYXMgbm90IGJlZW4gbG9hZGVkIHNvIGZhciwgaXQgaXMgYmVpbmcgbG9hZGVkIGFuZCBsaW5rZWQKKyAgICAgKiBmaXJzdC4gVGhpcyBpcyBkb25lIHRocm91Z2ggZWl0aGVyIHRoZSBjbGFzcyBsb2FkZXIgb2YgdGhlIGNhbGxpbmcgY2xhc3MKKyAgICAgKiBvciBvbmUgb2YgaXRzIHBhcmVudCBjbGFzcyBsb2FkZXJzLiBUaGUgY2xhc3MgaXMgYWxzbyBiZWluZyBpbml0aWFsaXplZCwKKyAgICAgKiB3aGljaCBtZWFucyB0aGF0IGEgcG9zc2libGUgc3RhdGljIGluaXRpYWxpemVyIGJsb2NrIGlzIGV4ZWN1dGVkLgorICAgICAqCisgICAgICogQHBhcmFtIGNsYXNzTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIG5vbi1wcmltaXRpdmUtdHlwZSBjbGFzcyB0byBmaW5kLgorICAgICAqIEByZXR1cm4gdGhlIG5hbWVkIHtAY29kZSBDbGFzc30gaW5zdGFuY2UuCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHJlcXVlc3RlZCBjbGFzcyBjYW4gbm90IGJlIGZvdW5kLgorICAgICAqIEB0aHJvd3MgTGlua2FnZUVycm9yCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyBsaW5rYWdlCisgICAgICogQHRocm93cyBFeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3IKKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBleGNlcHRpb24gb2NjdXJzIGR1cmluZyBzdGF0aWMgaW5pdGlhbGl6YXRpb24gb2YgYQorICAgICAqICAgICAgICAgICAgIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ2xhc3M8Pz4gZm9yTmFtZShTdHJpbmcgY2xhc3NOYW1lKSB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBmb3JOYW1lKGNsYXNzTmFtZSwgdHJ1ZSwgVk1TdGFjay5nZXRDYWxsaW5nQ2xhc3NMb2FkZXIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBDbGFzc30gb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIGNsYXNzIHdpdGggdGhlCisgICAgICogc3BlY2lmaWVkIG5hbWUuIFRoZSBuYW1lIHNob3VsZCBiZSB0aGUgbmFtZSBvZiBhIGNsYXNzIGFzIGRlc2NyaWJlZCBpbgorICAgICAqIHRoZSB7QGxpbmsgQ2xhc3MgY2xhc3MgZGVmaW5pdGlvbn0sIGhvd2V2ZXIge0Bjb2RlIENsYXNzfWVzIHJlcHJlc2VudGluZworICAgICAqIHByaW1pdGl2ZSB0eXBlcyBjYW4gbm90IGJlIGZvdW5kIHVzaW5nIHRoaXMgbWV0aG9kLiBTZWN1cml0eSBydWxlcyB3aWxsCisgICAgICogYmUgb2JleWVkLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBjbGFzcyBoYXMgbm90IGJlZW4gbG9hZGVkIHNvIGZhciwgaXQgaXMgYmVpbmcgbG9hZGVkIGFuZCBsaW5rZWQKKyAgICAgKiBmaXJzdC4gVGhpcyBpcyBkb25lIHRocm91Z2ggZWl0aGVyIHRoZSBzcGVjaWZpZWQgY2xhc3MgbG9hZGVyIG9yIG9uZSBvZgorICAgICAqIGl0cyBwYXJlbnQgY2xhc3MgbG9hZGVycy4gVGhlIGNhbGxlciBjYW4gYWxzbyByZXF1ZXN0IHRoZSBjbGFzcyB0byBiZQorICAgICAqIGluaXRpYWxpemVkLCB3aGljaCBtZWFucyB0aGF0IGEgcG9zc2libGUgc3RhdGljIGluaXRpYWxpemVyIGJsb2NrIGlzCisgICAgICogZXhlY3V0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2xhc3NOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgbm9uLXByaW1pdGl2ZS10eXBlIGNsYXNzIHRvIGZpbmQuCisgICAgICogQHBhcmFtIGluaXRpYWxpemVCb29sZWFuCisgICAgICogICAgICAgICAgICBpbmRpY2F0ZXMgd2hldGhlciB0aGUgY2xhc3Mgc2hvdWxkIGJlIGluaXRpYWxpemVkLgorICAgICAqIEBwYXJhbSBjbGFzc0xvYWRlcgorICAgICAqICAgICAgICAgICAgdGhlIGNsYXNzIGxvYWRlciB0byB1c2UgdG8gbG9hZCB0aGUgY2xhc3MuCisgICAgICogQHJldHVybiB0aGUgbmFtZWQge0Bjb2RlIENsYXNzfSBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcmVxdWVzdGVkIGNsYXNzIGNhbiBub3QgYmUgZm91bmQuCisgICAgICogQHRocm93cyBMaW5rYWdlRXJyb3IKKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIGxpbmthZ2UKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvcgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGV4Y2VwdGlvbiBvY2N1cnMgZHVyaW5nIHN0YXRpYyBpbml0aWFsaXphdGlvbiBvZiBhCisgICAgICogICAgICAgICAgICAgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDbGFzczw/PiBmb3JOYW1lKFN0cmluZyBjbGFzc05hbWUsIGJvb2xlYW4gaW5pdGlhbGl6ZUJvb2xlYW4sCisgICAgICAgICAgICBDbGFzc0xvYWRlciBjbGFzc0xvYWRlcikgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworCisgICAgICAgIGlmIChjbGFzc0xvYWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICBjbGFzc0xvYWRlciA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCk7CisgICAgICAgIH0KKyAgICAgICAgLy8gQ2F0Y2ggYW4gRXhjZXB0aW9uIHRocm93biBieSB0aGUgdW5kZXJseWluZyBuYXRpdmUgY29kZS4gSXQgd3JhcHMKKyAgICAgICAgLy8gdXAgZXZlcnl0aGluZyBpbnNpZGUgYSBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLCBldmVuIGlmIGUuZy4gYW4KKyAgICAgICAgLy8gRXJyb3Igb2NjdXJyZWQgZHVyaW5nIGluaXRpYWxpemF0aW9uLiBUaGlzIGFzIGEgd29ya2Fyb3VuZCBmb3IKKyAgICAgICAgLy8gYW4gRXhjZXB0aW9uSW5Jbml0aWxhaXplckVycm9yIHRoYXQncyBhbHNvIHdyYXBwZWQuIEl0IGlzIGFjdHVhbGx5CisgICAgICAgIC8vIGV4cGVjdGVkIHRvIGJlIHRocm93bi4gTWF5YmUgdGhlIHNhbWUgZ29lcyBmb3Igb3RoZXIgZXJyb3JzLgorICAgICAgICAvLyBOb3Qgd3JhcHBpbmcgdXAgYWxsIHRoZSBlcnJvcnMgd2lsbCBicmVhayBhbmRyb2lkIHRob3VnaC4KKyAgICAgICAgQ2xhc3M8Pz4gcmVzdWx0OworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzdWx0ID0gY2xhc3NGb3JOYW1lKGNsYXNzTmFtZSwgaW5pdGlhbGl6ZUJvb2xlYW4sCisgICAgICAgICAgICAgICAgICAgIGNsYXNzTG9hZGVyKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBUaHJvd2FibGUgY2F1c2UgPSBlLmdldENhdXNlKCk7CisgICAgICAgICAgICBpZiAoY2F1c2UgaW5zdGFuY2VvZiBFeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3IpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyAoRXhjZXB0aW9uSW5Jbml0aWFsaXplckVycm9yKSBjYXVzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFJldHVybnMgYSBjbGFzcyBieSBuYW1lIHdpdGhvdXQgYW55IHNlY3VyaXR5IGNoZWNrcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbGFzc05hbWUgVGhlIG5hbWUgb2YgdGhlIG5vbi1wcmltaXRpdmUgdHlwZSBjbGFzcyB0byBmaW5kCisgICAgICogQHBhcmFtIGluaXRpYWxpemVCb29sZWFuIEEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGNsYXNzIHNob3VsZCBiZQorICAgICAqICAgICAgICBpbml0aWFsaXplZAorICAgICAqIEBwYXJhbSBjbGFzc0xvYWRlciBUaGUgY2xhc3MgbG9hZGVyIHRvIHVzZSB0byBsb2FkIHRoZSBjbGFzcworICAgICAqIEByZXR1cm4gdGhlIG5hbWVkIGNsYXNzLgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBJZiB0aGUgY2xhc3MgY291bGQgbm90IGJlIGZvdW5kCisgICAgICovCisgICAgc3RhdGljIG5hdGl2ZSBDbGFzczw/PiBjbGFzc0Zvck5hbWUoU3RyaW5nIGNsYXNzTmFtZSwgYm9vbGVhbiBpbml0aWFsaXplQm9vbGVhbiwKKyAgICAgICAgICAgIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyKSB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyB7QGNvZGUgQ2xhc3N9IG9iamVjdHMgZm9yIGFsbCBwdWJsaWMgY2xhc3NlcworICAgICAqIGFuZCBpbnRlcmZhY2VzIHRoYXQgYXJlIG1lbWJlcnMgb2YgdGhpcyBjbGFzcy4gVGhpcyBpbmNsdWRlcyBwdWJsaWMKKyAgICAgKiBtZW1iZXJzIGluaGVyaXRlZCBmcm9tIHN1cGVyIGNsYXNzZXMgYW5kIGludGVyZmFjZXMuIElmIHRoZXJlIGFyZSBubyBzdWNoCisgICAgICogY2xhc3MgbWVtYmVycyBvciBpZiB0aGlzIG9iamVjdCByZXByZXNlbnRzIGEgcHJpbWl0aXZlIHR5cGUgdGhlbiBhbiBhcnJheQorICAgICAqIG9mIGxlbmd0aCAwIGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHVibGljIGNsYXNzIG1lbWJlcnMgb2YgdGhlIGNsYXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBDbGFzczw/PltdIGdldENsYXNzZXMoKSB7CisgICAgICAgIHJldHVybiBnZXRGdWxsTGlzdE9mQ2xhc3Nlcyh0cnVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIDxBIGV4dGVuZHMgQW5ub3RhdGlvbj4gQSBnZXRBbm5vdGF0aW9uKENsYXNzPEE+IGFubm90YXRpb25UeXBlKSB7CisgICAgICAgIGlmIChhbm5vdGF0aW9uVHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImFubm90YXRpb25UeXBlID09IG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIEEgYW5ub3RhdGlvbiA9IGdldERlY2xhcmVkQW5ub3RhdGlvbihhbm5vdGF0aW9uVHlwZSk7CisgICAgICAgIGlmIChhbm5vdGF0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBhbm5vdGF0aW9uOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGFubm90YXRpb25UeXBlLmlzQW5ub3RhdGlvblByZXNlbnQoSW5oZXJpdGVkLmNsYXNzKSkgeworICAgICAgICAgICAgZm9yIChDbGFzczw/PiBzdXAgPSBnZXRTdXBlcmNsYXNzKCk7IHN1cCAhPSBudWxsOyBzdXAgPSBzdXAuZ2V0U3VwZXJjbGFzcygpKSB7CisgICAgICAgICAgICAgICAgYW5ub3RhdGlvbiA9IHN1cC5nZXREZWNsYXJlZEFubm90YXRpb24oYW5ub3RhdGlvblR5cGUpOworICAgICAgICAgICAgICAgIGlmIChhbm5vdGF0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFubm90YXRpb247CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbGwgdGhlIGFubm90YXRpb25zIG9mIHRoaXMgY2xhc3MuIElmIHRoZXJlIGFyZSBubyBhbm5vdGF0aW9ucworICAgICAqIHRoZW4gYW4gZW1wdHkgYXJyYXkgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGUgYXJyYXkgY29udGFpbmluZyB0aGlzIGNsYXNzJyBhbm5vdGF0aW9ucy4KKyAgICAgKiBAc2VlICNnZXREZWNsYXJlZEFubm90YXRpb25zKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgQW5ub3RhdGlvbltdIGdldEFubm90YXRpb25zKCkgeworICAgICAgICAvKgorICAgICAgICAgKiBXZSBuZWVkIHRvIGdldCB0aGUgYW5ub3RhdGlvbnMgZGVjbGFyZWQgb24gdGhpcyBjbGFzcywgcGx1cyB0aGUKKyAgICAgICAgICogYW5ub3RhdGlvbnMgZnJvbSBzdXBlcmNsYXNzZXMgdGhhdCBoYXZlIHRoZSAiQEluaGVyaXRlZCIgYW5ub3RhdGlvbgorICAgICAgICAgKiBzZXQuICBXZSBjcmVhdGUgYSB0ZW1wb3JhcnkgbWFwIHRvIHVzZSB3aGlsZSB3ZSBhY2N1bXVsYXRlIHRoZQorICAgICAgICAgKiBhbm5vdGF0aW9ucyBhbmQgY29udmVydCBpdCB0byBhbiBhcnJheSBhdCB0aGUgZW5kLgorICAgICAgICAgKgorICAgICAgICAgKiBJdCdzIHBvc3NpYmxlIHRvIGhhdmUgZHVwbGljYXRlcyB3aGVuIGFubm90YXRpb25zIGFyZSBpbmhlcml0ZWQuCisgICAgICAgICAqIFdlIHVzZSBhIE1hcCB0byBmaWx0ZXIgdGhvc2Ugb3V0LgorICAgICAgICAgKgorICAgICAgICAgKiBIYXNoTWFwIG1pZ2h0IGJlIG92ZXJraWxsIGhlcmUuCisgICAgICAgICAqLworICAgICAgICBIYXNoTWFwPENsYXNzLCBBbm5vdGF0aW9uPiBtYXAgPSBuZXcgSGFzaE1hcDxDbGFzcywgQW5ub3RhdGlvbj4oKTsKKyAgICAgICAgQW5ub3RhdGlvbltdIGRlY2xhcmVkQW5ub3RhdGlvbnMgPSBnZXREZWNsYXJlZEFubm90YXRpb25zKCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IGRlY2xhcmVkQW5ub3RhdGlvbnMubGVuZ3RoLTE7IGkgPj0gMDsgLS1pKSB7CisgICAgICAgICAgICBtYXAucHV0KGRlY2xhcmVkQW5ub3RhdGlvbnNbaV0uYW5ub3RhdGlvblR5cGUoKSwgZGVjbGFyZWRBbm5vdGF0aW9uc1tpXSk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChDbGFzczw/PiBzdXAgPSBnZXRTdXBlcmNsYXNzKCk7IHN1cCAhPSBudWxsOyBzdXAgPSBzdXAuZ2V0U3VwZXJjbGFzcygpKSB7CisgICAgICAgICAgICBkZWNsYXJlZEFubm90YXRpb25zID0gc3VwLmdldERlY2xhcmVkQW5ub3RhdGlvbnMoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBkZWNsYXJlZEFubm90YXRpb25zLmxlbmd0aC0xOyBpID49IDA7IC0taSkgeworICAgICAgICAgICAgICAgIENsYXNzPD8+IGNsYXp6ID0gZGVjbGFyZWRBbm5vdGF0aW9uc1tpXS5hbm5vdGF0aW9uVHlwZSgpOworICAgICAgICAgICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGNsYXp6KSAmJiBjbGF6ei5pc0Fubm90YXRpb25QcmVzZW50KEluaGVyaXRlZC5jbGFzcykpIHsKKyAgICAgICAgICAgICAgICAgICAgbWFwLnB1dChjbGF6eiwgZGVjbGFyZWRBbm5vdGF0aW9uc1tpXSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyogY29udmVydCBhbm5vdGF0aW9uIHZhbHVlcyBmcm9tIEhhc2hNYXAgdG8gYXJyYXkgKi8KKyAgICAgICAgQ29sbGVjdGlvbjxBbm5vdGF0aW9uPiBjb2xsID0gbWFwLnZhbHVlcygpOworICAgICAgICByZXR1cm4gY29sbC50b0FycmF5KG5ldyBBbm5vdGF0aW9uW2NvbGwuc2l6ZSgpXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2Fub25pY2FsIG5hbWUgb2YgdGhpcyBjbGFzcy4gSWYgdGhpcyBjbGFzcyBkb2VzIG5vdCBoYXZlIGEKKyAgICAgKiBjYW5vbmljYWwgbmFtZSBhcyBkZWZpbmVkIGluIHRoZSBKYXZhIExhbmd1YWdlIFNwZWNpZmljYXRpb24sIHRoZW4gdGhlCisgICAgICogbWV0aG9kIHJldHVybnMge0Bjb2RlIG51bGx9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIGNsYXNzJyBjYW5vbmljYWwgbmFtZSwgb3Ige0Bjb2RlIG51bGx9IGlmIGl0IGRvZXMgbm90IGhhdmUgYQorICAgICAqICAgICAgICAgY2Fub25pY2FsIG5hbWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDYW5vbmljYWxOYW1lKCkgeworICAgICAgICBpZiAoaXNMb2NhbENsYXNzKCkgfHwgaXNBbm9ueW1vdXNDbGFzcygpKQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisKKyAgICAgICAgaWYgKGlzQXJyYXkoKSkgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFRoZSBjYW5vbmljYWwgbmFtZSBvZiBhbiBhcnJheSB0eXBlIGRlcGVuZHMgb24gdGhlIChleGlzdGVuY2Ugb2YpCisgICAgICAgICAgICAgKiB0aGUgY29tcG9uZW50IHR5cGUncyBjYW5vbmljYWwgbmFtZS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBnZXRDb21wb25lbnRUeXBlKCkuZ2V0Q2Fub25pY2FsTmFtZSgpOworICAgICAgICAgICAgaWYgKG5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuYW1lICsgIltdIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChpc01lbWJlckNsYXNzKCkpIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBUaGUgY2Fub25pY2FsIG5hbWUgb2YgYW4gaW5uZXIgY2xhc3MgZGVwZW5kcyBvbiB0aGUgKGV4aXN0ZW5jZQorICAgICAgICAgICAgICogb2YpIHRoZSBkZWNsYXJpbmcgY2xhc3MnIGNhbm9uaWNhbCBuYW1lLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGdldERlY2xhcmluZ0NsYXNzKCkuZ2V0Q2Fub25pY2FsTmFtZSgpOworICAgICAgICAgICAgaWYgKG5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuYW1lICsgIi4iICsgZ2V0U2ltcGxlTmFtZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFRoZSBjYW5vbmljYWwgbmFtZSBvZiBhIHRvcC1sZXZlbCBjbGFzcyBvciBwcmltaXRpdmUgdHlwZSBpcworICAgICAgICAgICAgICogZXF1YWwgdG8gdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICByZXR1cm4gZ2V0TmFtZSgpOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogT3RoZXIgY2xhc3NlcyBkb24ndCBoYXZlIGEgY2Fub25pY2FsIG5hbWUuCisgICAgICAgICAqLworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbGFzcyBsb2FkZXIgd2hpY2ggd2FzIHVzZWQgdG8gbG9hZCB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkKKyAgICAgKiB0aGlzIHtAY29kZSBDbGFzc30uIEltcGxlbWVudGF0aW9ucyBhcmUgZnJlZSB0byByZXR1cm4ge0Bjb2RlIG51bGx9IGZvcgorICAgICAqIGNsYXNzZXMgdGhhdCB3ZXJlIGxvYWRlZCBieSB0aGUgYm9vdHN0cmFwIGNsYXNzIGxvYWRlci4gVGhlIEFuZHJvaWQKKyAgICAgKiByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24sIHRob3VnaCwgcmV0dXJucyBhIHJlZmVyZW5jZSB0byBhbiBhY3R1YWwKKyAgICAgKiByZXByZXNlbnRhdGlvbiBvZiB0aGUgYm9vdHN0cmFwIGNsYXNzIGxvYWRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNsYXNzIGxvYWRlciBmb3IgdGhlIHJlcHJlc2VudGVkIGNsYXNzLgorICAgICAqIEBzZWUgQ2xhc3NMb2FkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xhc3NMb2FkZXIgZ2V0Q2xhc3NMb2FkZXIoKSB7CisgICAgICAgIGlmICh0aGlzLmlzUHJpbWl0aXZlKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQ2xhc3NMb2FkZXIgbG9hZGVyID0gZ2V0Q2xhc3NMb2FkZXJJbXBsKCk7CisgICAgICAgIGlmIChsb2FkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgbG9hZGVyID0gQm9vdENsYXNzTG9hZGVyLmdldEluc3RhbmNlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGxvYWRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG11c3QgYmUgcHJvdmlkZWQgYnkgdGhlIFZNIHZlbmRvciwgYXMgaXQgaXMgdXNlZCBieSBvdGhlciBwcm92aWRlZAorICAgICAqIGNsYXNzIGltcGxlbWVudGF0aW9ucyBpbiB0aGlzIHBhY2thZ2UuIE91dHNpZGUgb2YgdGhpcyBjbGFzcywgaXQgaXMgdXNlZAorICAgICAqIGJ5IFNlY3VyaXR5TWFuYWdlci5jbGFzc0xvYWRlckRlcHRoKCksCisgICAgICogY3VycmVudENsYXNzTG9hZGVyKCkgYW5kIGN1cnJlbnRMb2FkZWRDbGFzcygpLiBSZXR1cm4gdGhlIENsYXNzTG9hZGVyIGZvcgorICAgICAqIHRoaXMgQ2xhc3Mgd2l0aG91dCBkb2luZyBhbnkgc2VjdXJpdHkgY2hlY2tzLiBUaGUgYm9vdHN0cmFwIENsYXNzTG9hZGVyCisgICAgICogaXMgcmV0dXJuZWQsIHVubGlrZSBnZXRDbGFzc0xvYWRlcigpIHdoaWNoIHJldHVybnMgbnVsbCBpbiBwbGFjZSBvZiB0aGUKKyAgICAgKiBib290c3RyYXAgQ2xhc3NMb2FkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBDbGFzc0xvYWRlcgorICAgICAqLworICAgIENsYXNzTG9hZGVyIGdldENsYXNzTG9hZGVySW1wbCgpIHsKKyAgICAgICAgQ2xhc3NMb2FkZXIgbG9hZGVyID0gZ2V0Q2xhc3NMb2FkZXIodGhpcyk7CisgICAgICAgIHJldHVybiBsb2FkZXIgPT0gbnVsbCA/IEJvb3RDbGFzc0xvYWRlci5nZXRJbnN0YW5jZSgpIDogbG9hZGVyOworICAgIH0KKworICAgIC8qCisgICAgICogUmV0dXJucyB0aGUgZGVmaW5pbmcgY2xhc3MgbG9hZGVyIGZvciB0aGUgZ2l2ZW4gY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2xhenogdGhlIGNsYXNzIHRoZSBjbGFzcyBsb2FkZXIgb2Ygd2hpY2ggd2Ugd2FudAorICAgICAqIEByZXR1cm4gdGhlIGNsYXNzIGxvYWRlcgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBDbGFzc0xvYWRlciBnZXRDbGFzc0xvYWRlcihDbGFzczw/PiBjbGF6eik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIENsYXNzfSBvYmplY3Qgd2hpY2ggcmVwcmVzZW50cyB0aGUgY29tcG9uZW50IHR5cGUgaWYKKyAgICAgKiB0aGlzIGNsYXNzIHJlcHJlc2VudHMgYW4gYXJyYXkgdHlwZS4gUmV0dXJucyB7QGNvZGUgbnVsbH0gaWYgdGhpcyBjbGFzcworICAgICAqIGRvZXMgbm90IHJlcHJlc2VudCBhbiBhcnJheSB0eXBlLiBUaGUgY29tcG9uZW50IHR5cGUgb2YgYW4gYXJyYXkgdHlwZSBpcworICAgICAqIHRoZSB0eXBlIG9mIHRoZSBlbGVtZW50cyBvZiB0aGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb21wb25lbnQgdHlwZSBvZiB0aGlzIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBuYXRpdmUgQ2xhc3M8Pz4gZ2V0Q29tcG9uZW50VHlwZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBDb25zdHJ1Y3Rvcn0gb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIHB1YmxpYworICAgICAqIGNvbnN0cnVjdG9yIG1hdGNoaW5nIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIHR5cGVzLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlclR5cGVzCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIHR5cGVzIG9mIHRoZSByZXF1ZXN0ZWQgY29uc3RydWN0b3IuCisgICAgICogICAgICAgICAgICB7QGNvZGUgKENsYXNzW10pIG51bGx9IGlzIGVxdWl2YWxlbnQgdG8gdGhlIGVtcHR5IGFycmF5LgorICAgICAqIEByZXR1cm4gdGhlIGNvbnN0cnVjdG9yIGRlc2NyaWJlZCBieSB7QGNvZGUgcGFyYW1ldGVyVHlwZXN9LgorICAgICAqIEB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNvbnN0cnVjdG9yIGNhbiBub3QgYmUgZm91bmQuCisgICAgICogQHNlZSAjZ2V0RGVjbGFyZWRDb25zdHJ1Y3RvcihDbGFzc1tdKQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBDb25zdHJ1Y3RvcjxUPiBnZXRDb25zdHJ1Y3RvcihDbGFzczw/Pi4uLiBwYXJhbWV0ZXJUeXBlcykgdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiAoQ29uc3RydWN0b3IpIGdldENvbnN0cnVjdG9yT3JNZXRob2QoIjxpbml0PiIsIGZhbHNlLCB0cnVlLCBwYXJhbWV0ZXJUeXBlcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvbnN0cnVjdG9yIG9yIG1ldGhvZCB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIHRoZSBtZXRob2QgbmFtZSwgb3IgIjxpbml0PiIgdG8gcmV0dXJuIGEgY29uc3RydWN0b3IuCisgICAgICogQHBhcmFtIHJlY3Vyc2l2ZSB0cnVlIHRvIHNlYXJjaCBzdXBlcnR5cGVzLgorICAgICAqLworICAgIHByaXZhdGUgTWVtYmVyIGdldENvbnN0cnVjdG9yT3JNZXRob2QoU3RyaW5nIG5hbWUsIGJvb2xlYW4gcmVjdXJzaXZlLAorICAgICAgICAgICAgYm9vbGVhbiBwdWJsaWNPbmx5LCBDbGFzczw/PltdIHBhcmFtZXRlclR5cGVzKSB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHJlY3Vyc2l2ZSAmJiAhcHVibGljT25seSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7IC8vIGNhbid0IGxvb2t1cCBub24tcHVibGljIG1lbWJlcnMgcmVjdXJzaXZlbHkKKyAgICAgICAgfQorICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm5hbWUgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChwYXJhbWV0ZXJUeXBlcyA9PSBudWxsKSB7CisgICAgICAgICAgICBwYXJhbWV0ZXJUeXBlcyA9IEVtcHR5QXJyYXkuQ0xBU1M7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChDbGFzczw/PiBjIDogcGFyYW1ldGVyVHlwZXMpIHsKKyAgICAgICAgICAgIGlmIChjID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoTWV0aG9kRXhjZXB0aW9uKCJwYXJhbWV0ZXIgdHlwZSBpcyBudWxsIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgTWVtYmVyIHJlc3VsdCA9IHJlY3Vyc2l2ZQorICAgICAgICAgICAgICAgID8gZ2V0UHVibGljQ29uc3RydWN0b3JPck1ldGhvZFJlY3Vyc2l2ZShuYW1lLCBwYXJhbWV0ZXJUeXBlcykKKyAgICAgICAgICAgICAgICA6IENsYXNzLmdldERlY2xhcmVkQ29uc3RydWN0b3JPck1ldGhvZCh0aGlzLCBuYW1lLCBwYXJhbWV0ZXJUeXBlcyk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCB8fCBwdWJsaWNPbmx5ICYmIChyZXN1bHQuZ2V0TW9kaWZpZXJzKCkgJiBNb2RpZmllci5QVUJMSUMpID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hNZXRob2RFeGNlcHRpb24obmFtZSArICIgIiArIEFycmF5cy50b1N0cmluZyhwYXJhbWV0ZXJUeXBlcykpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBNZW1iZXIgZ2V0UHVibGljQ29uc3RydWN0b3JPck1ldGhvZFJlY3Vyc2l2ZShTdHJpbmcgbmFtZSwgQ2xhc3M8Pz5bXSBwYXJhbWV0ZXJUeXBlcykgeworICAgICAgICAvLyBzZWFyY2ggc3VwZXJjbGFzc2VzCisgICAgICAgIGZvciAoQ2xhc3M8Pz4gYyA9IHRoaXM7IGMgIT0gbnVsbDsgYyA9IGMuZ2V0U3VwZXJjbGFzcygpKSB7CisgICAgICAgICAgICBNZW1iZXIgcmVzdWx0ID0gQ2xhc3MuZ2V0RGVjbGFyZWRDb25zdHJ1Y3Rvck9yTWV0aG9kKGMsIG5hbWUsIHBhcmFtZXRlclR5cGVzKTsKKyAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCAmJiAocmVzdWx0LmdldE1vZGlmaWVycygpICYgTW9kaWZpZXIuUFVCTElDKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHNlYXJjaCBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzCisgICAgICAgIGZvciAoQ2xhc3M8Pz4gYyA9IHRoaXM7IGMgIT0gbnVsbDsgYyA9IGMuZ2V0U3VwZXJjbGFzcygpKSB7CisgICAgICAgICAgICBmb3IgKENsYXNzPD8+IGlmYyA6IGMuZ2V0SW50ZXJmYWNlcygpKSB7CisgICAgICAgICAgICAgICAgTWVtYmVyIHJlc3VsdCA9IGlmYy5nZXRQdWJsaWNDb25zdHJ1Y3Rvck9yTWV0aG9kUmVjdXJzaXZlKG5hbWUsIHBhcmFtZXRlclR5cGVzKTsKKyAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9IG51bGwgJiYgKHJlc3VsdC5nZXRNb2RpZmllcnMoKSAmIE1vZGlmaWVyLlBVQkxJQykgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyB7QGNvZGUgQ29uc3RydWN0b3J9IG9iamVjdHMgZm9yIGFsbCBwdWJsaWMKKyAgICAgKiBjb25zdHJ1Y3RvcnMgZm9yIHRoZSBjbGFzcyByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBDbGFzc30uIElmIHRoZXJlCisgICAgICogYXJlIG5vIHB1YmxpYyBjb25zdHJ1Y3RvcnMgb3IgaWYgdGhpcyB7QGNvZGUgQ2xhc3N9IHJlcHJlc2VudHMgYW4gYXJyYXkKKyAgICAgKiBjbGFzcywgYSBwcmltaXRpdmUgdHlwZSBvciB2b2lkIHRoZW4gYW4gZW1wdHkgYXJyYXkgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IHdpdGggdGhlIHB1YmxpYyBjb25zdHJ1Y3RvcnMgb2YgdGhlIGNsYXNzIHJlcHJlc2VudGVkIGJ5CisgICAgICogICAgICAgICB0aGlzIHtAY29kZSBDbGFzc30uCisgICAgICogQHNlZSAjZ2V0RGVjbGFyZWRDb25zdHJ1Y3RvcnMoKQorICAgICAqLworICAgIHB1YmxpYyBDb25zdHJ1Y3Rvcjw/PltdIGdldENvbnN0cnVjdG9ycygpIHsKKyAgICAgICAgcmV0dXJuIGdldERlY2xhcmVkQ29uc3RydWN0b3JzKHRoaXMsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFubm90YXRpb25zIHRoYXQgYXJlIGRpcmVjdGx5IGRlZmluZWQgb24gdGhlIGNsYXNzCisgICAgICogcmVwcmVzZW50ZWQgYnkgdGhpcyB7QGNvZGUgQ2xhc3N9LiBBbm5vdGF0aW9ucyB0aGF0IGFyZSBpbmhlcml0ZWQgYXJlIG5vdAorICAgICAqIGluY2x1ZGVkIGluIHRoZSByZXN1bHQuIElmIHRoZXJlIGFyZSBubyBhbm5vdGF0aW9ucyBhdCBhbGwsIGFuIGVtcHR5CisgICAgICogYXJyYXkgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGUgYXJyYXkgY29udGFpbmluZyB0aGUgYW5ub3RhdGlvbnMgZGVmaW5lZCBmb3IgdGhlCisgICAgICogICAgICAgICBjbGFzcyB0aGF0IHRoaXMge0Bjb2RlIENsYXNzfSByZXByZXNlbnRzLgorICAgICAqIEBzZWUgI2dldEFubm90YXRpb25zKCkKKyAgICAgKi8KKyAgICBuYXRpdmUgcHVibGljIEFubm90YXRpb25bXSBnZXREZWNsYXJlZEFubm90YXRpb25zKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhbm5vdGF0aW9uIGlmIGl0IGV4aXN0cy4KKyAgICAgKi8KKyAgICBuYXRpdmUgcHJpdmF0ZSA8QSBleHRlbmRzIEFubm90YXRpb24+IEEgZ2V0RGVjbGFyZWRBbm5vdGF0aW9uKENsYXNzPEE+IGFubm90YXRpb25DbGFzcyk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGFubm90YXRpb24gZXhpc3RzLgorICAgICAqLworICAgIG5hdGl2ZSBwcml2YXRlIGJvb2xlYW4gaXNEZWNsYXJlZEFubm90YXRpb25QcmVzZW50KENsYXNzPD8gZXh0ZW5kcyBBbm5vdGF0aW9uPiBhbm5vdGF0aW9uQ2xhc3MpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIHtAY29kZSBDbGFzc30gb2JqZWN0cyBmb3IgYWxsIGNsYXNzZXMgYW5kCisgICAgICogaW50ZXJmYWNlcyB0aGF0IGFyZSBkZWNsYXJlZCBhcyBtZW1iZXJzIG9mIHRoZSBjbGFzcyB3aGljaCB0aGlzIHtAY29kZQorICAgICAqIENsYXNzfSByZXByZXNlbnRzLiBJZiB0aGVyZSBhcmUgbm8gY2xhc3NlcyBvciBpbnRlcmZhY2VzIGRlY2xhcmVkIG9yIGlmCisgICAgICogdGhpcyBjbGFzcyByZXByZXNlbnRzIGFuIGFycmF5IGNsYXNzLCBhIHByaW1pdGl2ZSB0eXBlIG9yIHZvaWQsIHRoZW4gYW4KKyAgICAgKiBlbXB0eSBhcnJheSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgd2l0aCB7QGNvZGUgQ2xhc3N9IG9iamVjdHMgZm9yIGFsbCB0aGUgY2xhc3NlcyBhbmQKKyAgICAgKiAgICAgICAgIGludGVyZmFjZXMgdGhhdCBhcmUgdXNlZCBpbiBtZW1iZXIgZGVjbGFyYXRpb25zLgorICAgICAqLworICAgIHB1YmxpYyBDbGFzczw/PltdIGdldERlY2xhcmVkQ2xhc3NlcygpIHsKKyAgICAgICAgcmV0dXJuIGdldERlY2xhcmVkQ2xhc3Nlcyh0aGlzLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIG1lbWJlciBjbGFzc2VzIHdpdGhvdXQgcGVyZm9ybWluZyBhbnkgc2VjdXJpdHkgY2hlY2tzCisgICAgICogZmlyc3QuIFRoaXMgaW5jbHVkZXMgdGhlIG1lbWJlciBjbGFzc2VzIGluaGVyaXRlZCBmcm9tIHN1cGVyY2xhc3Nlcy4gSWYgbm8KKyAgICAgKiBtZW1iZXIgY2xhc3NlcyBleGlzdCBhdCBhbGwsIGFuIGVtcHR5IGFycmF5IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIHB1YmxpY09ubHkgcmVmbGVjdHMgd2hldGhlciB3ZSB3YW50IG9ubHkgcHVibGljIG1lbWJlcnMgb3IgYWxsIG9mIHRoZW0KKyAgICAgKiBAcmV0dXJuIHRoZSBsaXN0IG9mIGNsYXNzZXMKKyAgICAgKi8KKyAgICBwcml2YXRlIENsYXNzPD8+W10gZ2V0RnVsbExpc3RPZkNsYXNzZXMoYm9vbGVhbiBwdWJsaWNPbmx5KSB7CisgICAgICAgIENsYXNzPD8+W10gcmVzdWx0ID0gZ2V0RGVjbGFyZWRDbGFzc2VzKHRoaXMsIHB1YmxpY09ubHkpOworCisgICAgICAgIC8vIFRyYXZlcnNlIGFsbCBzdXBlcmNsYXNzZXMKKyAgICAgICAgQ2xhc3M8Pz4gY2xhenogPSB0aGlzLmdldFN1cGVyY2xhc3MoKTsKKyAgICAgICAgd2hpbGUgKGNsYXp6ICE9IG51bGwpIHsKKyAgICAgICAgICAgIENsYXNzPD8+W10gdGVtcCA9IGdldERlY2xhcmVkQ2xhc3NlcyhjbGF6eiwgcHVibGljT25seSk7CisgICAgICAgICAgICBpZiAodGVtcC5sZW5ndGggIT0gMCkgeworICAgICAgICAgICAgICAgIHJlc3VsdCA9IGFycmF5Y29weShuZXcgQ2xhc3NbcmVzdWx0Lmxlbmd0aCArIHRlbXAubGVuZ3RoXSwgcmVzdWx0LCB0ZW1wKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY2xhenogPSBjbGF6ei5nZXRTdXBlcmNsYXNzKCk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qCisgICAgICogUmV0dXJucyB0aGUgbGlzdCBvZiBtZW1iZXIgY2xhc3NlcyBvZiB0aGUgZ2l2ZW4gY2xhc3MuIE5vIHNlY3VyaXR5IGNoZWNrcworICAgICAqIGFyZSBwZXJmb3JtZWQuIElmIG5vIG1lbWJlcnMgZXhpc3QsIGFuIGVtcHR5IGFycmF5IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGNsYXp6IHRoZSBjbGFzcyB0aGUgbWVtYmVycyBvZiB3aGljaCB3ZSB3YW50CisgICAgICogQHBhcmFtIHB1YmxpY09ubHkgcmVmbGVjdHMgd2hldGhlciB3ZSB3YW50IG9ubHkgcHVibGljIG1lbWJlciBvciBhbGwgb2YgdGhlbQorICAgICAqIEByZXR1cm4gdGhlIGNsYXNzJyBjbGFzcyBtZW1iZXJzCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIENsYXNzPD8+W10gZ2V0RGVjbGFyZWRDbGFzc2VzKENsYXNzPD8+IGNsYXp6LCBib29sZWFuIHB1YmxpY09ubHkpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBDb25zdHJ1Y3Rvcn0gb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIGNvbnN0cnVjdG9yCisgICAgICogbWF0Y2hpbmcgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgdHlwZXMgdGhhdCBpcyBkZWNsYXJlZCBieSB0aGUgY2xhc3MKKyAgICAgKiByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBDbGFzc30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyVHlwZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgdHlwZXMgb2YgdGhlIHJlcXVlc3RlZCBjb25zdHJ1Y3Rvci4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSAoQ2xhc3NbXSkgbnVsbH0gaXMgZXF1aXZhbGVudCB0byB0aGUgZW1wdHkgYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgY29uc3RydWN0b3IgZGVzY3JpYmVkIGJ5IHtAY29kZSBwYXJhbWV0ZXJUeXBlc30uCisgICAgICogQHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcmVxdWVzdGVkIGNvbnN0cnVjdG9yIGNhbiBub3QgYmUgZm91bmQuCisgICAgICogQHNlZSAjZ2V0Q29uc3RydWN0b3IoQ2xhc3NbXSkKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgQ29uc3RydWN0b3I8VD4gZ2V0RGVjbGFyZWRDb25zdHJ1Y3RvcihDbGFzczw/Pi4uLiBwYXJhbWV0ZXJUeXBlcykKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24geworICAgICAgICByZXR1cm4gKENvbnN0cnVjdG9yKSBnZXRDb25zdHJ1Y3Rvck9yTWV0aG9kKCI8aW5pdD4iLCBmYWxzZSwgZmFsc2UsIHBhcmFtZXRlclR5cGVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcge0Bjb2RlIENvbnN0cnVjdG9yfSBvYmplY3RzIGZvciBhbGwKKyAgICAgKiBjb25zdHJ1Y3RvcnMgZGVjbGFyZWQgaW4gdGhlIGNsYXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIENsYXNzfS4gSWYKKyAgICAgKiB0aGVyZSBhcmUgbm8gY29uc3RydWN0b3JzIG9yIGlmIHRoaXMge0Bjb2RlIENsYXNzfSByZXByZXNlbnRzIGFuIGFycmF5CisgICAgICogY2xhc3MsIGEgcHJpbWl0aXZlIHR5cGUgb3Igdm9pZCB0aGVuIGFuIGVtcHR5IGFycmF5IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSB3aXRoIHRoZSBjb25zdHJ1Y3RvcnMgZGVjbGFyZWQgaW4gdGhlIGNsYXNzIHJlcHJlc2VudGVkCisgICAgICogICAgICAgICBieSB0aGlzIHtAY29kZSBDbGFzc30uCisgICAgICogQHNlZSAjZ2V0Q29uc3RydWN0b3JzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29uc3RydWN0b3I8Pz5bXSBnZXREZWNsYXJlZENvbnN0cnVjdG9ycygpIHsKKyAgICAgICAgcmV0dXJuIGdldERlY2xhcmVkQ29uc3RydWN0b3JzKHRoaXMsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFJldHVybnMgdGhlIGxpc3Qgb2YgY29uc3RydWN0b3JzIHdpdGhvdXQgcGVyZm9ybWluZyBhbnkgc2VjdXJpdHkgY2hlY2tzCisgICAgICogZmlyc3QuIElmIG5vIGNvbnN0cnVjdG9ycyBleGlzdCwgYW4gZW1wdHkgYXJyYXkgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2xhenogdGhlIGNsYXNzIG9mIGludGVyZXN0CisgICAgICogQHBhcmFtIHB1YmxpY09ubHkgcmVmbGVjdHMgd2hldGhlciB3ZSB3YW50IG9ubHkgcHVibGljIGNvbnN0cnVjdG9ycyBvciBhbGwgb2YgdGhlbQorICAgICAqIEByZXR1cm4gdGhlIGxpc3Qgb2YgY29uc3RydWN0b3JzCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIDxUPiBDb25zdHJ1Y3RvcjxUPltdIGdldERlY2xhcmVkQ29uc3RydWN0b3JzKAorICAgICAgICAgICAgQ2xhc3M8VD4gY2xhenosIGJvb2xlYW4gcHVibGljT25seSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIEZpZWxkfSBvYmplY3QgZm9yIHRoZSBmaWVsZCB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZQorICAgICAqIHdoaWNoIGlzIGRlY2xhcmVkIGluIHRoZSBjbGFzcyByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBDbGFzc30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgcmVxdWVzdGVkIGZpZWxkLgorICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3RlZCBmaWVsZCBpbiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcyBjbGFzcy4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEZpZWxkRXhjZXB0aW9uIGlmIHRoZSByZXF1ZXN0ZWQgZmllbGQgY2FuIG5vdCBiZSBmb3VuZC4KKyAgICAgKiBAc2VlICNnZXRGaWVsZChTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIEZpZWxkIGdldERlY2xhcmVkRmllbGQoU3RyaW5nIG5hbWUpIHRocm93cyBOb1N1Y2hGaWVsZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgRmllbGQgcmVzdWx0ID0gZ2V0RGVjbGFyZWRGaWVsZCh0aGlzLCBuYW1lKTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRmllbGRFeGNlcHRpb24obmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcge0Bjb2RlIEZpZWxkfSBvYmplY3RzIGZvciBhbGwgZmllbGRzIGRlY2xhcmVkCisgICAgICogaW4gdGhlIGNsYXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIENsYXNzfS4gSWYgdGhlcmUgYXJlIG5vIGZpZWxkcyBvcgorICAgICAqIGlmIHRoaXMge0Bjb2RlIENsYXNzfSByZXByZXNlbnRzIGFuIGFycmF5IGNsYXNzLCBhIHByaW1pdGl2ZSB0eXBlIG9yIHZvaWQKKyAgICAgKiB0aGVuIGFuIGVtcHR5IGFycmF5IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSB3aXRoIHRoZSBmaWVsZHMgZGVjbGFyZWQgaW4gdGhlIGNsYXNzIHJlcHJlc2VudGVkIGJ5CisgICAgICogICAgICAgICB0aGlzIGNsYXNzLgorICAgICAqIEBzZWUgI2dldEZpZWxkcygpCisgICAgICovCisgICAgcHVibGljIEZpZWxkW10gZ2V0RGVjbGFyZWRGaWVsZHMoKSB7CisgICAgICAgIHJldHVybiBnZXREZWNsYXJlZEZpZWxkcyh0aGlzLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIGZpZWxkcyB3aXRob3V0IHBlcmZvcm1pbmcgYW55IHNlY3VyaXR5IGNoZWNrcworICAgICAqIGZpcnN0LiBJZiBubyBmaWVsZHMgZXhpc3QgYXQgYWxsLCBhbiBlbXB0eSBhcnJheSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbGF6eiB0aGUgY2xhc3Mgb2YgaW50ZXJlc3QKKyAgICAgKiBAcGFyYW0gcHVibGljT25seSByZWZsZWN0cyB3aGV0aGVyIHdlIHdhbnQgb25seSBwdWJsaWMgZmllbGRzIG9yIGFsbCBvZiB0aGVtCisgICAgICogQHJldHVybiB0aGUgbGlzdCBvZiBmaWVsZHMKKyAgICAgKi8KKyAgICBzdGF0aWMgbmF0aXZlIEZpZWxkW10gZ2V0RGVjbGFyZWRGaWVsZHMoQ2xhc3M8Pz4gY2xhenosIGJvb2xlYW4gcHVibGljT25seSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBmaWVsZCBpZiBpdCBpcyBkZWZpbmVkIGJ5IHtAY29kZSBjbGF6en07IG51bGwgb3RoZXJ3aXNlLiBUaGlzCisgICAgICogbWF5IHJldHVybiBhIG5vbi1wdWJsaWMgbWVtYmVyLgorICAgICAqLworICAgIHN0YXRpYyBuYXRpdmUgRmllbGQgZ2V0RGVjbGFyZWRGaWVsZChDbGFzczw/PiBjbGF6eiwgU3RyaW5nIG5hbWUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBNZXRob2R9IG9iamVjdCB3aGljaCByZXByZXNlbnRzIHRoZSBtZXRob2QgbWF0Y2hpbmcgdGhlCisgICAgICogc3BlY2lmaWVkIG5hbWUgYW5kIHBhcmFtZXRlciB0eXBlcyB0aGF0IGlzIGRlY2xhcmVkIGJ5IHRoZSBjbGFzcworICAgICAqIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIENsYXNzfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgcmVxdWVzdGVkIG1ldGhvZCdzIG5hbWUuCisgICAgICogQHBhcmFtIHBhcmFtZXRlclR5cGVzCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIHR5cGVzIG9mIHRoZSByZXF1ZXN0ZWQgbWV0aG9kLgorICAgICAqICAgICAgICAgICAge0Bjb2RlIChDbGFzc1tdKSBudWxsfSBpcyBlcXVpdmFsZW50IHRvIHRoZSBlbXB0eSBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHRoZSBtZXRob2QgZGVzY3JpYmVkIGJ5IHtAY29kZSBuYW1lfSBhbmQge0Bjb2RlIHBhcmFtZXRlclR5cGVzfS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSByZXF1ZXN0ZWQgY29uc3RydWN0b3IgY2FuIG5vdCBiZSBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG5hbWV9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAc2VlICNnZXRNZXRob2QoU3RyaW5nLCBDbGFzc1tdKQorICAgICAqLworICAgIHB1YmxpYyBNZXRob2QgZ2V0RGVjbGFyZWRNZXRob2QoU3RyaW5nIG5hbWUsIENsYXNzPD8+Li4uIHBhcmFtZXRlclR5cGVzKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiB7CisgICAgICAgIE1lbWJlciBtZW1iZXIgPSBnZXRDb25zdHJ1Y3Rvck9yTWV0aG9kKG5hbWUsIGZhbHNlLCBmYWxzZSwgcGFyYW1ldGVyVHlwZXMpOworICAgICAgICBpZiAobWVtYmVyIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hNZXRob2RFeGNlcHRpb24obmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChNZXRob2QpIG1lbWJlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcge0Bjb2RlIE1ldGhvZH0gb2JqZWN0cyBmb3IgYWxsIG1ldGhvZHMKKyAgICAgKiBkZWNsYXJlZCBpbiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcyB7QGNvZGUgQ2xhc3N9LiBJZiB0aGVyZSBhcmUgbm8KKyAgICAgKiBtZXRob2RzIG9yIGlmIHRoaXMge0Bjb2RlIENsYXNzfSByZXByZXNlbnRzIGFuIGFycmF5IGNsYXNzLCBhIHByaW1pdGl2ZQorICAgICAqIHR5cGUgb3Igdm9pZCB0aGVuIGFuIGVtcHR5IGFycmF5IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSB3aXRoIHRoZSBtZXRob2RzIGRlY2xhcmVkIGluIHRoZSBjbGFzcyByZXByZXNlbnRlZCBieQorICAgICAqICAgICAgICAgdGhpcyB7QGNvZGUgQ2xhc3N9LgorICAgICAqIEBzZWUgI2dldE1ldGhvZHMoKQorICAgICAqLworICAgIHB1YmxpYyBNZXRob2RbXSBnZXREZWNsYXJlZE1ldGhvZHMoKSB7CisgICAgICAgIHJldHVybiBnZXREZWNsYXJlZE1ldGhvZHModGhpcywgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxpc3Qgb2YgbWV0aG9kcyB3aXRob3V0IHBlcmZvcm1pbmcgYW55IHNlY3VyaXR5IGNoZWNrcworICAgICAqIGZpcnN0LiBJZiBubyBtZXRob2RzIGV4aXN0LCBhbiBlbXB0eSBhcnJheSBpcyByZXR1cm5lZC4KKyAgICAgKi8KKyAgICBzdGF0aWMgbmF0aXZlIE1ldGhvZFtdIGdldERlY2xhcmVkTWV0aG9kcyhDbGFzczw/PiBjbGF6eiwgYm9vbGVhbiBwdWJsaWNPbmx5KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNvbnN0cnVjdG9yIG9yIG1ldGhvZCBpZiBpdCBpcyBkZWZpbmVkIGJ5IHtAY29kZSBjbGF6en07IG51bGwKKyAgICAgKiBvdGhlcndpc2UuIFRoaXMgbWF5IHJldHVybiBhIG5vbi1wdWJsaWMgbWVtYmVyLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgdGhlIG1ldGhvZCBuYW1lLCBvciAiPGluaXQ+IiB0byBnZXQgYSBjb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBzdGF0aWMgbmF0aXZlIE1lbWJlciBnZXREZWNsYXJlZENvbnN0cnVjdG9yT3JNZXRob2QoQ2xhc3MgY2xhenosIFN0cmluZyBuYW1lLCBDbGFzc1tdIGFyZ3MpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGVjbGFyaW5nIHtAY29kZSBDbGFzc30gb2YgdGhpcyB7QGNvZGUgQ2xhc3N9LiBSZXR1cm5zCisgICAgICoge0Bjb2RlIG51bGx9IGlmIHRoZSBjbGFzcyBpcyBub3QgYSBtZW1iZXIgb2YgYW5vdGhlciBjbGFzcyBvciBpZiB0aGlzCisgICAgICoge0Bjb2RlIENsYXNzfSByZXByZXNlbnRzIGFuIGFycmF5IGNsYXNzLCBhIHByaW1pdGl2ZSB0eXBlIG9yIHZvaWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkZWNsYXJpbmcge0Bjb2RlIENsYXNzfSBvciB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgbmF0aXZlIHB1YmxpYyBDbGFzczw/PiBnZXREZWNsYXJpbmdDbGFzcygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5jbG9zaW5nIHtAY29kZSBDbGFzc30gb2YgdGhpcyB7QGNvZGUgQ2xhc3N9LiBJZiB0aGVyZSBpcyBubworICAgICAqIGVuY2xvc2luZyBjbGFzcyB0aGUgbWV0aG9kIHJldHVybnMge0Bjb2RlIG51bGx9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZW5jbG9zaW5nIHtAY29kZSBDbGFzc30gb3Ige0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIG5hdGl2ZSBwdWJsaWMgQ2xhc3M8Pz4gZ2V0RW5jbG9zaW5nQ2xhc3MoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGVuY2xvc2luZyB7QGNvZGUgQ29uc3RydWN0b3J9IG9mIHRoaXMge0Bjb2RlIENsYXNzfSwgaWYgaXQgaXMgYW4KKyAgICAgKiBhbm9ueW1vdXMgb3IgbG9jYWwvYXV0b21hdGljIGNsYXNzOyBvdGhlcndpc2Uge0Bjb2RlIG51bGx9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZW5jbG9zaW5nIHtAY29kZSBDb25zdHJ1Y3Rvcn0gaW5zdGFuY2Ugb3Ige0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIG5hdGl2ZSBwdWJsaWMgQ29uc3RydWN0b3I8Pz4gZ2V0RW5jbG9zaW5nQ29uc3RydWN0b3IoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGVuY2xvc2luZyB7QGNvZGUgTWV0aG9kfSBvZiB0aGlzIHtAY29kZSBDbGFzc30sIGlmIGl0IGlzIGFuCisgICAgICogYW5vbnltb3VzIG9yIGxvY2FsL2F1dG9tYXRpYyBjbGFzczsgb3RoZXJ3aXNlIHtAY29kZSBudWxsfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVuY2xvc2luZyB7QGNvZGUgTWV0aG9kfSBpbnN0YW5jZSBvciB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgbmF0aXZlIHB1YmxpYyBNZXRob2QgZ2V0RW5jbG9zaW5nTWV0aG9kKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB7QGNvZGUgZW51bX0gY29uc3RhbnRzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHtAY29kZSBDbGFzc30uCisgICAgICogUmV0dXJucyB7QGNvZGUgbnVsbH0gaWYgdGhpcyB7QGNvZGUgQ2xhc3N9IGRvZXMgbm90IHJlcHJlc2VudCBhbiB7QGNvZGUKKyAgICAgKiBlbnVtfSB0eXBlLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSB3aXRoIHRoZSB7QGNvZGUgZW51bX0gY29uc3RhbnRzIG9yIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikgLy8gd2Ugb25seSBjYXN0IGFmdGVyIGNvbmZpcm1pbmcgdGhhdCB0aGlzIGNsYXNzIGlzIGFuIGVudW0KKyAgICBwdWJsaWMgVFtdIGdldEVudW1Db25zdGFudHMoKSB7CisgICAgICAgIGlmICghaXNFbnVtKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoVFtdKSBFbnVtLmdldFNoYXJlZENvbnN0YW50cygoQ2xhc3MpIHRoaXMpLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBGaWVsZH0gb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIHB1YmxpYyBmaWVsZCB3aXRoIHRoZQorICAgICAqIHNwZWNpZmllZCBuYW1lLiBUaGlzIG1ldGhvZCBmaXJzdCBzZWFyY2hlcyB0aGUgY2xhc3MgQyByZXByZXNlbnRlZCBieQorICAgICAqIHRoaXMge0Bjb2RlIENsYXNzfSwgdGhlbiB0aGUgaW50ZXJmYWNlcyBpbXBsZW1lbnRlZCBieSBDIGFuZCBmaW5hbGx5IHRoZQorICAgICAqIHN1cGVyY2xhc3NlcyBvZiBDLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXF1ZXN0ZWQgZmllbGQuCisgICAgICogQHJldHVybiB0aGUgcHVibGljIGZpZWxkIHNwZWNpZmllZCBieSB7QGNvZGUgbmFtZX0uCisgICAgICogQHRocm93cyBOb1N1Y2hGaWVsZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBmaWVsZCBjYW4gbm90IGJlIGZvdW5kLgorICAgICAqIEBzZWUgI2dldERlY2xhcmVkRmllbGQoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBGaWVsZCBnZXRGaWVsZChTdHJpbmcgbmFtZSkgdGhyb3dzIE5vU3VjaEZpZWxkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJuYW1lID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBGaWVsZCByZXN1bHQgPSBnZXRQdWJsaWNGaWVsZFJlY3Vyc2l2ZShuYW1lKTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRmllbGRFeGNlcHRpb24obmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIEZpZWxkIGdldFB1YmxpY0ZpZWxkUmVjdXJzaXZlKFN0cmluZyBuYW1lKSB7CisgICAgICAgIC8vIHNlYXJjaCBzdXBlcmNsYXNzZXMKKyAgICAgICAgZm9yIChDbGFzczw/PiBjID0gdGhpczsgYyAhPSBudWxsOyBjID0gYy5nZXRTdXBlcmNsYXNzKCkpIHsKKyAgICAgICAgICAgIEZpZWxkIHJlc3VsdCA9IENsYXNzLmdldERlY2xhcmVkRmllbGQoYywgbmFtZSk7CisgICAgICAgICAgICBpZiAocmVzdWx0ICE9IG51bGwgJiYgKHJlc3VsdC5nZXRNb2RpZmllcnMoKSAmIE1vZGlmaWVyLlBVQkxJQykgIT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBzZWFyY2ggaW1wbGVtZW50ZWQgaW50ZXJmYWNlcworICAgICAgICBmb3IgKENsYXNzPD8+IGMgPSB0aGlzOyBjICE9IG51bGw7IGMgPSBjLmdldFN1cGVyY2xhc3MoKSkgeworICAgICAgICAgICAgZm9yIChDbGFzczw/PiBpZmMgOiBjLmdldEludGVyZmFjZXMoKSkgeworICAgICAgICAgICAgICAgIEZpZWxkIHJlc3VsdCA9IGlmYy5nZXRQdWJsaWNGaWVsZFJlY3Vyc2l2ZShuYW1lKTsKKyAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9IG51bGwgJiYgKHJlc3VsdC5nZXRNb2RpZmllcnMoKSAmIE1vZGlmaWVyLlBVQkxJQykgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyB7QGNvZGUgRmllbGR9IG9iamVjdHMgZm9yIGFsbCBwdWJsaWMgZmllbGRzCisgICAgICogZm9yIHRoZSBjbGFzcyBDIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIENsYXNzfS4gRmllbGRzIG1heSBiZSBkZWNsYXJlZAorICAgICAqIGluIEMsIHRoZSBpbnRlcmZhY2VzIGl0IGltcGxlbWVudHMgb3IgaW4gdGhlIHN1cGVyY2xhc3NlcyBvZiBDLiBUaGUKKyAgICAgKiBlbGVtZW50cyBpbiB0aGUgcmV0dXJuZWQgYXJyYXkgYXJlIGluIG5vIHBhcnRpY3VsYXIgb3JkZXIuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGVyZSBhcmUgbm8gcHVibGljIGZpZWxkcyBvciBpZiB0aGlzIGNsYXNzIHJlcHJlc2VudHMgYW4gYXJyYXkgY2xhc3MsCisgICAgICogYSBwcmltaXRpdmUgdHlwZSBvciB7QGNvZGUgdm9pZH0gdGhlbiBhbiBlbXB0eSBhcnJheSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgd2l0aCB0aGUgcHVibGljIGZpZWxkcyBvZiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcworICAgICAqICAgICAgICAge0Bjb2RlIENsYXNzfS4KKyAgICAgKiBAc2VlICNnZXREZWNsYXJlZEZpZWxkcygpCisgICAgICovCisgICAgcHVibGljIEZpZWxkW10gZ2V0RmllbGRzKCkgeworICAgICAgICBMaXN0PEZpZWxkPiBmaWVsZHMgPSBuZXcgQXJyYXlMaXN0PEZpZWxkPigpOworICAgICAgICBnZXRQdWJsaWNGaWVsZHNSZWN1cnNpdmUoZmllbGRzKTsKKworICAgICAgICAvKgorICAgICAgICAgKiBUaGUgcmVzdWx0IG1heSBpbmNsdWRlIGR1cGxpY2F0ZXMgd2hlbiBjbGF6eiBpbXBsZW1lbnRzIGFuIGludGVyZmFjZQorICAgICAgICAgKiB0aHJvdWdoIG11bHRpcGxlIHBhdGhzLiBSZW1vdmUgdGhvc2UgZHVwbGljYXRlcy4KKyAgICAgICAgICovCisgICAgICAgIENvbGxlY3Rpb25VdGlscy5yZW1vdmVEdXBsaWNhdGVzKGZpZWxkcywgRmllbGQuT1JERVJfQllfTkFNRV9BTkRfREVDTEFSSU5HX0NMQVNTKTsKKyAgICAgICAgcmV0dXJuIGZpZWxkcy50b0FycmF5KG5ldyBGaWVsZFtmaWVsZHMuc2l6ZSgpXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUG9wdWxhdGVzIHtAY29kZSByZXN1bHR9IHdpdGggcHVibGljIGZpZWxkcyBkZWZpbmVkIGJ5IHRoaXMgY2xhc3MsIGl0cworICAgICAqIHN1cGVyY2xhc3NlcywgYW5kIGFsbCBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBnZXRQdWJsaWNGaWVsZHNSZWN1cnNpdmUoTGlzdDxGaWVsZD4gcmVzdWx0KSB7CisgICAgICAgIC8vIHNlYXJjaCBzdXBlcmNsYXNzZXMKKyAgICAgICAgZm9yIChDbGFzczw/PiBjID0gdGhpczsgYyAhPSBudWxsOyBjID0gYy5nZXRTdXBlcmNsYXNzKCkpIHsKKyAgICAgICAgICAgIGZvciAoRmllbGQgZmllbGQgOiBDbGFzcy5nZXREZWNsYXJlZEZpZWxkcyhjLCB0cnVlKSkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQoZmllbGQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gc2VhcmNoIGltcGxlbWVudGVkIGludGVyZmFjZXMKKyAgICAgICAgZm9yIChDbGFzczw/PiBjID0gdGhpczsgYyAhPSBudWxsOyBjID0gYy5nZXRTdXBlcmNsYXNzKCkpIHsKKyAgICAgICAgICAgIGZvciAoQ2xhc3M8Pz4gaWZjIDogYy5nZXRJbnRlcmZhY2VzKCkpIHsKKyAgICAgICAgICAgICAgICBpZmMuZ2V0UHVibGljRmllbGRzUmVjdXJzaXZlKHJlc3VsdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB7QGxpbmsgVHlwZX1zIG9mIHRoZSBpbnRlcmZhY2VzIHRoYXQgdGhpcyB7QGNvZGUgQ2xhc3N9IGRpcmVjdGx5CisgICAgICogaW1wbGVtZW50cy4gSWYgdGhlIHtAY29kZSBDbGFzc30gcmVwcmVzZW50cyBhIHByaW1pdGl2ZSB0eXBlIG9yIHtAY29kZQorICAgICAqIHZvaWR9IHRoZW4gYW4gZW1wdHkgYXJyYXkgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIHtAbGluayBUeXBlfSBpbnN0YW5jZXMgZGlyZWN0bHkgaW1wbGVtZW50ZWQgYnkgdGhlCisgICAgICogICAgICAgICBjbGFzcyByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBjbGFzc30uCisgICAgICovCisgICAgcHVibGljIFR5cGVbXSBnZXRHZW5lcmljSW50ZXJmYWNlcygpIHsKKyAgICAgICAgR2VuZXJpY1NpZ25hdHVyZVBhcnNlciBwYXJzZXIgPSBuZXcgR2VuZXJpY1NpZ25hdHVyZVBhcnNlcihnZXRDbGFzc0xvYWRlcigpKTsKKyAgICAgICAgcGFyc2VyLnBhcnNlRm9yQ2xhc3ModGhpcywgZ2V0U2lnbmF0dXJlQXR0cmlidXRlKCkpOworICAgICAgICByZXR1cm4gVHlwZXMuZ2V0Q2xvbmVkVHlwZUFycmF5KHBhcnNlci5pbnRlcmZhY2VUeXBlcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUge0Bjb2RlIFR5cGV9IHRoYXQgcmVwcmVzZW50cyB0aGUgc3VwZXJjbGFzcyBvZiB0aGlzIHtAY29kZQorICAgICAqIGNsYXNzfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIFR5cGV9IHJlcHJlc2VudGluZyB0aGUgc3VwZXJjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgVHlwZSBnZXRHZW5lcmljU3VwZXJjbGFzcygpIHsKKyAgICAgICAgR2VuZXJpY1NpZ25hdHVyZVBhcnNlciBwYXJzZXIgPSBuZXcgR2VuZXJpY1NpZ25hdHVyZVBhcnNlcihnZXRDbGFzc0xvYWRlcigpKTsKKyAgICAgICAgcGFyc2VyLnBhcnNlRm9yQ2xhc3ModGhpcywgZ2V0U2lnbmF0dXJlQXR0cmlidXRlKCkpOworICAgICAgICByZXR1cm4gVHlwZXMuZ2V0VHlwZShwYXJzZXIuc3VwZXJjbGFzc1R5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2Yge0Bjb2RlIENsYXNzfSBvYmplY3RzIHRoYXQgbWF0Y2ggdGhlIGludGVyZmFjZXMKKyAgICAgKiBzcGVjaWZpZWQgaW4gdGhlIHtAY29kZSBpbXBsZW1lbnRzfSBkZWNsYXJhdGlvbiBvZiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQKKyAgICAgKiBieSB0aGlzIHtAY29kZSBDbGFzc30uIFRoZSBvcmRlciBvZiB0aGUgZWxlbWVudHMgaW4gdGhlIGFycmF5IGlzCisgICAgICogaWRlbnRpY2FsIHRvIHRoZSBvcmRlciBpbiB0aGUgb3JpZ2luYWwgY2xhc3MgZGVjbGFyYXRpb24uIElmIHRoZSBjbGFzcworICAgICAqIGRvZXMgbm90IGltcGxlbWVudCBhbnkgaW50ZXJmYWNlcywgYW4gZW1wdHkgYXJyYXkgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IHdpdGggdGhlIGludGVyZmFjZXMgb2YgdGhlIGNsYXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMKKyAgICAgKiAgICAgICAgIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBuYXRpdmUgQ2xhc3M8Pz5bXSBnZXRJbnRlcmZhY2VzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIE1ldGhvZH0gb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIHB1YmxpYyBtZXRob2Qgd2l0aAorICAgICAqIHRoZSBzcGVjaWZpZWQgbmFtZSBhbmQgcGFyYW1ldGVyIHR5cGVzLiBUaGlzIG1ldGhvZCBmaXJzdCBzZWFyY2hlcyB0aGUKKyAgICAgKiBjbGFzcyBDIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIENsYXNzfSwgdGhlbiB0aGUgc3VwZXJjbGFzc2VzIG9mIEMgYW5kCisgICAgICogZmluYWxseSB0aGUgaW50ZXJmYWNlcyBpbXBsZW1lbnRlZCBieSBDIGFuZCBmaW5hbGx5IHRoZSBzdXBlcmNsYXNzZXMgb2YgQworICAgICAqIGZvciBhIG1ldGhvZCB3aXRoIG1hdGNoaW5nIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHJlcXVlc3RlZCBtZXRob2QncyBuYW1lLgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJUeXBlcworICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciB0eXBlcyBvZiB0aGUgcmVxdWVzdGVkIG1ldGhvZC4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSAoQ2xhc3NbXSkgbnVsbH0gaXMgZXF1aXZhbGVudCB0byB0aGUgZW1wdHkgYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgcHVibGljIGZpZWxkIHNwZWNpZmllZCBieSB7QGNvZGUgbmFtZX0uCisgICAgICogQHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbWV0aG9kIGNhbiBub3QgYmUgZm91bmQuCisgICAgICogQHNlZSAjZ2V0RGVjbGFyZWRNZXRob2QoU3RyaW5nLCBDbGFzc1tdKQorICAgICAqLworICAgIHB1YmxpYyBNZXRob2QgZ2V0TWV0aG9kKFN0cmluZyBuYW1lLCBDbGFzczw/Pi4uLiBwYXJhbWV0ZXJUeXBlcykgdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiB7CisgICAgICAgIE1lbWJlciBtZW1iZXIgPSBnZXRDb25zdHJ1Y3Rvck9yTWV0aG9kKG5hbWUsIHRydWUsIHRydWUsIHBhcmFtZXRlclR5cGVzKTsKKyAgICAgICAgaWYgKG1lbWJlciBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoTWV0aG9kRXhjZXB0aW9uKG5hbWUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoTWV0aG9kKSBtZW1iZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIHtAY29kZSBNZXRob2R9IG9iamVjdHMgZm9yIGFsbCBwdWJsaWMgbWV0aG9kcworICAgICAqIGZvciB0aGUgY2xhc3MgQyByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBDbGFzc30uIE1ldGhvZHMgbWF5IGJlCisgICAgICogZGVjbGFyZWQgaW4gQywgdGhlIGludGVyZmFjZXMgaXQgaW1wbGVtZW50cyBvciBpbiB0aGUgc3VwZXJjbGFzc2VzIG9mIEMuCisgICAgICogVGhlIGVsZW1lbnRzIGluIHRoZSByZXR1cm5lZCBhcnJheSBhcmUgaW4gbm8gcGFydGljdWxhciBvcmRlci4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGVyZSBhcmUgbm8gcHVibGljIG1ldGhvZHMgb3IgaWYgdGhpcyB7QGNvZGUgQ2xhc3N9IHJlcHJlc2VudHMgYQorICAgICAqIHByaW1pdGl2ZSB0eXBlIG9yIHtAY29kZSB2b2lkfSB0aGVuIGFuIGVtcHR5IGFycmF5IGlzIHJldHVybmVkLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgd2l0aCB0aGUgbWV0aG9kcyBvZiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcworICAgICAqICAgICAgICAge0Bjb2RlIENsYXNzfS4KKyAgICAgKiBAc2VlICNnZXREZWNsYXJlZE1ldGhvZHMoKQorICAgICAqLworICAgIHB1YmxpYyBNZXRob2RbXSBnZXRNZXRob2RzKCkgeworICAgICAgICBMaXN0PE1ldGhvZD4gbWV0aG9kcyA9IG5ldyBBcnJheUxpc3Q8TWV0aG9kPigpOworICAgICAgICBnZXRQdWJsaWNNZXRob2RzUmVjdXJzaXZlKG1ldGhvZHMpOworCisgICAgICAgIC8qCisgICAgICAgICAqIFJlbW92ZSBtZXRob2RzIGRlZmluZWQgYnkgbXVsdGlwbGUgdHlwZXMsIHByZWZlcnJpbmcgdG8ga2VlcCBtZXRob2RzCisgICAgICAgICAqIGRlY2xhcmVkIGJ5IGRlcml2ZWQgdHlwZXMuCisgICAgICAgICAqLworICAgICAgICBDb2xsZWN0aW9uVXRpbHMucmVtb3ZlRHVwbGljYXRlcyhtZXRob2RzLCBNZXRob2QuT1JERVJfQllfU0lHTkFUVVJFKTsKKyAgICAgICAgcmV0dXJuIG1ldGhvZHMudG9BcnJheShuZXcgTWV0aG9kW21ldGhvZHMuc2l6ZSgpXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUG9wdWxhdGVzIHtAY29kZSByZXN1bHR9IHdpdGggcHVibGljIG1ldGhvZHMgZGVmaW5lZCBieSB7QGNvZGUgY2xhenp9LCBpdHMKKyAgICAgKiBzdXBlcmNsYXNzZXMsIGFuZCBhbGwgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcywgaW5jbHVkaW5nIG92ZXJyaWRkZW4gbWV0aG9kcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZ2V0UHVibGljTWV0aG9kc1JlY3Vyc2l2ZShMaXN0PE1ldGhvZD4gcmVzdWx0KSB7CisgICAgICAgIC8vIHNlYXJjaCBzdXBlcmNsYXNzZXMKKyAgICAgICAgZm9yIChDbGFzczw/PiBjID0gdGhpczsgYyAhPSBudWxsOyBjID0gYy5nZXRTdXBlcmNsYXNzKCkpIHsKKyAgICAgICAgICAgIGZvciAoTWV0aG9kIG1ldGhvZCA6IENsYXNzLmdldERlY2xhcmVkTWV0aG9kcyhjLCB0cnVlKSkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQobWV0aG9kKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHNlYXJjaCBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzCisgICAgICAgIGZvciAoQ2xhc3M8Pz4gYyA9IHRoaXM7IGMgIT0gbnVsbDsgYyA9IGMuZ2V0U3VwZXJjbGFzcygpKSB7CisgICAgICAgICAgICBmb3IgKENsYXNzPD8+IGlmYyA6IGMuZ2V0SW50ZXJmYWNlcygpKSB7CisgICAgICAgICAgICAgICAgaWZjLmdldFB1YmxpY01ldGhvZHNSZWN1cnNpdmUocmVzdWx0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW50ZWdlciB0aGF0IHJlcHJlc2VudHMgdGhlIG1vZGlmaWVycyBvZiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQKKyAgICAgKiBieSB0aGlzIHtAY29kZSBDbGFzc30uIFRoZSByZXR1cm5lZCB2YWx1ZSBpcyBhIGNvbWJpbmF0aW9uIG9mIGJpdHMKKyAgICAgKiBkZWZpbmVkIGJ5IGNvbnN0YW50cyBpbiB0aGUge0BsaW5rIE1vZGlmaWVyfSBjbGFzcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1vZGlmaWVycyBvZiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcyB7QGNvZGUgQ2xhc3N9LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TW9kaWZpZXJzKCkgeworICAgICAgICByZXR1cm4gZ2V0TW9kaWZpZXJzKHRoaXMsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFJldHVybiB0aGUgbW9kaWZpZXJzIGZvciB0aGUgZ2l2ZW4gY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2xhenogdGhlIGNsYXNzIG9mIGludGVyZXN0CisgICAgICogQGlnbm9yZUlubmVyQ2xhc3Nlc0F0dHJpYiBkZXRlcm1pbmVzIHdoZXRoZXIgd2UgbG9vayBmb3IgYW5kIHVzZSB0aGUKKyAgICAgKiAgICAgZmxhZ3MgZnJvbSBhbiAiaW5uZXIgY2xhc3MiIGF0dHJpYnV0ZQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgZ2V0TW9kaWZpZXJzKENsYXNzPD8+IGNsYXp6LCBib29sZWFuIGlnbm9yZUlubmVyQ2xhc3Nlc0F0dHJpYik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBDbGFzc30uIEZvciBhCisgICAgICogZGVzY3JpcHRpb24gb2YgdGhlIGZvcm1hdCB3aGljaCBpcyB1c2VkLCBzZWUgdGhlIGNsYXNzIGRlZmluaXRpb24gb2YKKyAgICAgKiB7QGxpbmsgQ2xhc3N9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcyB7QGNvZGUgQ2xhc3N9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IG5hbWU7CisgICAgICAgIHJldHVybiAocmVzdWx0ID09IG51bGwpID8gKG5hbWUgPSBnZXROYW1lTmF0aXZlKCkpIDogcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgbmF0aXZlIFN0cmluZyBnZXROYW1lTmF0aXZlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzaW1wbGUgbmFtZSBvZiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcyB7QGNvZGUgQ2xhc3N9IGFzCisgICAgICogZGVmaW5lZCBpbiB0aGUgc291cmNlIGNvZGUuIElmIHRoZXJlIGlzIG5vIG5hbWUgKHRoYXQgaXMsIHRoZSBjbGFzcyBpcworICAgICAqIGFub255bW91cykgdGhlbiBhbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQuIElmIHRoZSByZWNlaXZlciBpcyBhbiBhcnJheQorICAgICAqIHRoZW4gdGhlIG5hbWUgb2YgdGhlIHVuZGVybHlpbmcgdHlwZSB3aXRoIHNxdWFyZSBicmFjZXMgYXBwZW5kZWQgKGZvcgorICAgICAqIGV4YW1wbGUge0Bjb2RlICJJbnRlZ2VyW10ifSkgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzaW1wbGUgbmFtZSBvZiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcyB7QGNvZGUgQ2xhc3N9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2ltcGxlTmFtZSgpIHsKKyAgICAgICAgaWYgKGlzQXJyYXkoKSkgeworICAgICAgICAgICAgcmV0dXJuIGdldENvbXBvbmVudFR5cGUoKS5nZXRTaW1wbGVOYW1lKCkgKyAiW10iOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBnZXROYW1lKCk7CisKKyAgICAgICAgaWYgKGlzQW5vbnltb3VzQ2xhc3MoKSkgeworICAgICAgICAgICAgcmV0dXJuICIiOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGlzTWVtYmVyQ2xhc3MoKSB8fCBpc0xvY2FsQ2xhc3MoKSkgeworICAgICAgICAgICAgcmV0dXJuIGdldElubmVyQ2xhc3NOYW1lKCk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgZG90ID0gbmFtZS5sYXN0SW5kZXhPZignLicpOworICAgICAgICBpZiAoZG90ICE9IC0xKSB7CisgICAgICAgICAgICByZXR1cm4gbmFtZS5zdWJzdHJpbmcoZG90ICsgMSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFJldHVybnMgdGhlIHNpbXBsZSBuYW1lIG9mIGEgbWVtYmVyIG9yIGxvY2FsIGNsYXNzLCBvciBudWxsIG90aGVyd2lzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIG5hbWUuCisgICAgICovCisgICAgcHJpdmF0ZSBuYXRpdmUgU3RyaW5nIGdldElubmVyQ2xhc3NOYW1lKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIG51bGwuCisgICAgICovCisgICAgcHVibGljIFByb3RlY3Rpb25Eb21haW4gZ2V0UHJvdGVjdGlvbkRvbWFpbigpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgVVJMIG9mIHRoZSByZXNvdXJjZSBzcGVjaWZpZWQgYnkge0Bjb2RlIHJlc05hbWV9LiBUaGUgbWFwcGluZworICAgICAqIGJldHdlZW4gdGhlIHJlc291cmNlIG5hbWUgYW5kIHRoZSBVUkwgaXMgbWFuYWdlZCBieSB0aGUgY2xhc3MnIGNsYXNzCisgICAgICogbG9hZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHJlc05hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZS4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0ZWQgcmVzb3VyY2UncyB7QGNvZGUgVVJMfSBvYmplY3Qgb3Ige0Bjb2RlIG51bGx9IGlmCisgICAgICogICAgICAgICB0aGUgcmVzb3VyY2UgY2FuIG5vdCBiZSBmb3VuZC4KKyAgICAgKiBAc2VlIENsYXNzTG9hZGVyCisgICAgICovCisgICAgcHVibGljIFVSTCBnZXRSZXNvdXJjZShTdHJpbmcgcmVzTmFtZSkgeworICAgICAgICAvLyBHZXQgYWJzb2x1dGUgcmVzb3VyY2UgbmFtZSwgYnV0IHdpdGhvdXQgdGhlIGxlYWRpbmcgc2xhc2gKKyAgICAgICAgaWYgKHJlc05hbWUuc3RhcnRzV2l0aCgiLyIpKSB7CisgICAgICAgICAgICByZXNOYW1lID0gcmVzTmFtZS5zdWJzdHJpbmcoMSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBTdHJpbmcgcGtnID0gZ2V0TmFtZSgpOworICAgICAgICAgICAgaW50IGRvdCA9IHBrZy5sYXN0SW5kZXhPZignLicpOworICAgICAgICAgICAgaWYgKGRvdCAhPSAtMSkgeworICAgICAgICAgICAgICAgIHBrZyA9IHBrZy5zdWJzdHJpbmcoMCwgZG90KS5yZXBsYWNlKCcuJywgJy8nKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcGtnID0gIiI7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJlc05hbWUgPSBwa2cgKyAiLyIgKyByZXNOYW1lOworICAgICAgICB9CisKKyAgICAgICAgLy8gRGVsZWdhdGUgdG8gcHJvcGVyIGNsYXNzIGxvYWRlcgorICAgICAgICBDbGFzc0xvYWRlciBsb2FkZXIgPSBnZXRDbGFzc0xvYWRlcigpOworICAgICAgICBpZiAobG9hZGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBsb2FkZXIuZ2V0UmVzb3VyY2UocmVzTmFtZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtUmVzb3VyY2UocmVzTmFtZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcmVhZC1vbmx5IHN0cmVhbSBmb3IgdGhlIGNvbnRlbnRzIG9mIHRoZSByZXNvdXJjZSBzcGVjaWZpZWQgYnkKKyAgICAgKiB7QGNvZGUgcmVzTmFtZX0uIFRoZSBtYXBwaW5nIGJldHdlZW4gdGhlIHJlc291cmNlIG5hbWUgYW5kIHRoZSBzdHJlYW0gaXMKKyAgICAgKiBtYW5hZ2VkIGJ5IHRoZSBjbGFzcycgY2xhc3MgbG9hZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHJlc05hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZS4KKyAgICAgKiBAcmV0dXJuIGEgc3RyZWFtIGZvciB0aGUgcmVxdWVzdGVkIHJlc291cmNlIG9yIHtAY29kZSBudWxsfSBpZiBubworICAgICAqICAgICAgICAgcmVzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgY2FuIGJlIGZvdW5kLgorICAgICAqIEBzZWUgQ2xhc3NMb2FkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0UmVzb3VyY2VBc1N0cmVhbShTdHJpbmcgcmVzTmFtZSkgeworICAgICAgICAvLyBHZXQgYWJzb2x1dGUgcmVzb3VyY2UgbmFtZSwgYnV0IHdpdGhvdXQgdGhlIGxlYWRpbmcgc2xhc2gKKyAgICAgICAgaWYgKHJlc05hbWUuc3RhcnRzV2l0aCgiLyIpKSB7CisgICAgICAgICAgICByZXNOYW1lID0gcmVzTmFtZS5zdWJzdHJpbmcoMSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBTdHJpbmcgcGtnID0gZ2V0TmFtZSgpOworICAgICAgICAgICAgaW50IGRvdCA9IHBrZy5sYXN0SW5kZXhPZignLicpOworICAgICAgICAgICAgaWYgKGRvdCAhPSAtMSkgeworICAgICAgICAgICAgICAgIHBrZyA9IHBrZy5zdWJzdHJpbmcoMCwgZG90KS5yZXBsYWNlKCcuJywgJy8nKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcGtnID0gIiI7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJlc05hbWUgPSBwa2cgKyAiLyIgKyByZXNOYW1lOworICAgICAgICB9CisKKyAgICAgICAgLy8gRGVsZWdhdGUgdG8gcHJvcGVyIGNsYXNzIGxvYWRlcgorICAgICAgICBDbGFzc0xvYWRlciBsb2FkZXIgPSBnZXRDbGFzc0xvYWRlcigpOworICAgICAgICBpZiAobG9hZGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBsb2FkZXIuZ2V0UmVzb3VyY2VBc1N0cmVhbShyZXNOYW1lKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBDbGFzc0xvYWRlci5nZXRTeXN0ZW1SZXNvdXJjZUFzU3RyZWFtKHJlc05hbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBudWxsLiAoT24gQW5kcm9pZCwgYSB7QGNvZGUgQ2xhc3NMb2FkZXJ9IGNhbiBsb2FkIGNsYXNzZXMgZnJvbSBtdWx0aXBsZSBkZXggZmlsZXMuCisgICAgICogQWxsIGNsYXNzZXMgZnJvbSBhbnkgZ2l2ZW4gZGV4IGZpbGUgd2lsbCBoYXZlIHRoZSBzYW1lIHNpZ25lcnMsIGJ1dCBkaWZmZXJlbnQgZGV4CisgICAgICogZmlsZXMgbWF5IGhhdmUgZGlmZmVyZW50IHNpZ25lcnMuIFRoaXMgZG9lcyBub3QgZml0IHdlbGwgd2l0aCB0aGUgb3JpZ2luYWwKKyAgICAgKiB7QGNvZGUgQ2xhc3NMb2FkZXJ9LWJhc2VkIG1vZGVsIG9mIHtAY29kZSBnZXRTaWduZXJzfS4pCisgICAgICoKKyAgICAgKiBAcmV0dXJuIG51bGwuCisgICAgICovCisgICAgcHVibGljIE9iamVjdFtdIGdldFNpZ25lcnMoKSB7CisgICAgICAgIC8vIFNlZSBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTE3NjYuCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBDbGFzc30gb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIHN1cGVyY2xhc3Mgb2YgdGhlCisgICAgICogY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcyB7QGNvZGUgQ2xhc3N9LiBJZiB0aGlzIHtAY29kZSBDbGFzc30gcmVwcmVzZW50cworICAgICAqIHRoZSB7QGNvZGUgT2JqZWN0fSBjbGFzcywgYSBwcmltaXRpdmUgdHlwZSwgYW4gaW50ZXJmYWNlIG9yIHZvaWQgdGhlbiB0aGUKKyAgICAgKiBtZXRob2QgcmV0dXJucyB7QGNvZGUgbnVsbH0uIElmIHRoaXMge0Bjb2RlIENsYXNzfSByZXByZXNlbnRzIGFuIGFycmF5CisgICAgICogY2xhc3MgdGhlbiB0aGUge0Bjb2RlIE9iamVjdH0gY2xhc3MgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdXBlcmNsYXNzIG9mIHRoZSBjbGFzcyByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBDbGFzc30uCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSBDbGFzczw/IHN1cGVyIFQ+IGdldFN1cGVyY2xhc3MoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyB7QGNvZGUgVHlwZVZhcmlhYmxlfSBvYmplY3RzIGZvciB0eXBlCisgICAgICogdmFyaWFibGVzIGRlY2xhcmVkIGJ5IHRoZSBnZW5lcmljIGNsYXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlCisgICAgICogQ2xhc3N9LiBSZXR1cm5zIGFuIGVtcHR5IGFycmF5IGlmIHRoZSBjbGFzcyBpcyBub3QgZ2VuZXJpYy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgd2l0aCB0aGUgdHlwZSB2YXJpYWJsZXMgb2YgdGhlIGNsYXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMKKyAgICAgKiAgICAgICAgIGNsYXNzLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgVHlwZVZhcmlhYmxlPENsYXNzPFQ+PltdIGdldFR5cGVQYXJhbWV0ZXJzKCkgeworICAgICAgICBHZW5lcmljU2lnbmF0dXJlUGFyc2VyIHBhcnNlciA9IG5ldyBHZW5lcmljU2lnbmF0dXJlUGFyc2VyKGdldENsYXNzTG9hZGVyKCkpOworICAgICAgICBwYXJzZXIucGFyc2VGb3JDbGFzcyh0aGlzLCBnZXRTaWduYXR1cmVBdHRyaWJ1dGUoKSk7CisgICAgICAgIHJldHVybiBwYXJzZXIuZm9ybWFsVHlwZVBhcmFtZXRlcnMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIHtAY29kZSBDbGFzc30gcmVwcmVzZW50cyBhbiBhbm5vdGF0aW9uIGNsYXNzLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgQ2xhc3N9IHJlcHJlc2VudHMgYW4gYW5ub3RhdGlvbgorICAgICAqICAgICAgICAgY2xhc3M7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQW5ub3RhdGlvbigpIHsKKyAgICAgICAgZmluYWwgaW50IEFDQ19BTk5PVEFUSU9OID0gMHgyMDAwOyAgLy8gbm90IHB1YmxpYyBpbiByZWZsZWN0Lk1vZGlmaWVycworICAgICAgICBpbnQgbW9kID0gZ2V0TW9kaWZpZXJzKHRoaXMsIHRydWUpOworICAgICAgICByZXR1cm4gKG1vZCAmIEFDQ19BTk5PVEFUSU9OKSAhPSAwOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc0Fubm90YXRpb25QcmVzZW50KENsYXNzPD8gZXh0ZW5kcyBBbm5vdGF0aW9uPiBhbm5vdGF0aW9uVHlwZSkgeworICAgICAgICBpZiAoYW5ub3RhdGlvblR5cGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJhbm5vdGF0aW9uVHlwZSA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoaXNEZWNsYXJlZEFubm90YXRpb25QcmVzZW50KGFubm90YXRpb25UeXBlKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBpZiAoYW5ub3RhdGlvblR5cGUuaXNEZWNsYXJlZEFubm90YXRpb25QcmVzZW50KEluaGVyaXRlZC5jbGFzcykpIHsKKyAgICAgICAgICAgIGZvciAoQ2xhc3M8Pz4gc3VwID0gZ2V0U3VwZXJjbGFzcygpOyBzdXAgIT0gbnVsbDsgc3VwID0gc3VwLmdldFN1cGVyY2xhc3MoKSkgeworICAgICAgICAgICAgICAgIGlmIChzdXAuaXNEZWNsYXJlZEFubm90YXRpb25QcmVzZW50KGFubm90YXRpb25UeXBlKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGNsYXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIENsYXNzfSBpcworICAgICAqIGFub255bW91c2x5IGRlY2xhcmVkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGNsYXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIENsYXNzfSBpcworICAgICAqICAgICAgICAgYW5vbnltb3VzOyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBuYXRpdmUgcHVibGljIGJvb2xlYW4gaXNBbm9ueW1vdXNDbGFzcygpOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGNsYXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIENsYXNzfSBpcyBhbiBhcnJheQorICAgICAqIGNsYXNzLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGNsYXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIENsYXNzfSBpcyBhbgorICAgICAqICAgICAgICAgYXJyYXkgY2xhc3M7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBnZXRDb21wb25lbnRUeXBlKCkgIT0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGNsYXNzIHR5cGUgY2FuIGJlIGNvbnZlcnRlZCB0byB0aGUgY2xhc3MKKyAgICAgKiByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBDbGFzc30uIENvbnZlcnNpb24gbWF5IGJlIGRvbmUgdmlhIGFuIGlkZW50aXR5CisgICAgICogY29udmVyc2lvbiBvciBhIHdpZGVuaW5nIHJlZmVyZW5jZSBjb252ZXJzaW9uIChpZiBlaXRoZXIgdGhlIHJlY2VpdmVyIG9yCisgICAgICogdGhlIGFyZ3VtZW50IHJlcHJlc2VudCBwcmltaXRpdmUgdHlwZXMsIG9ubHkgdGhlIGlkZW50aXR5IGNvbnZlcnNpb24KKyAgICAgKiBhcHBsaWVzKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjbGFzcyB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgY2xzfSBjYW4gYmUgY29udmVydGVkIHRvIHRoZSBjbGFzcworICAgICAqICAgICAgICAgcmVwcmVzZW50ZWQgYnkgdGhpcyB7QGNvZGUgQ2xhc3N9OyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGNsc30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBuYXRpdmUgYm9vbGVhbiBpc0Fzc2lnbmFibGVGcm9tKENsYXNzPD8+IGNscyk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcyB7QGNvZGUgQ2xhc3N9IGlzIGFuCisgICAgICoge0Bjb2RlIGVudW19LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGNsYXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIENsYXNzfSBpcyBhbgorICAgICAqICAgICAgICAge0Bjb2RlIGVudW19OyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VudW0oKSB7CisgICAgICAgIHJldHVybiAoKGdldE1vZGlmaWVycygpICYgMHg0MDAwKSAhPSAwKSAmJiAoZ2V0U3VwZXJjbGFzcygpID09IEVudW0uY2xhc3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGNhbiBiZSBjYXN0IHRvIHRoZSBjbGFzcworICAgICAqIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIENsYXNzfS4gVGhpcyBpcyB0aGUgcnVudGltZSB2ZXJzaW9uIG9mIHRoZQorICAgICAqIHtAY29kZSBpbnN0YW5jZW9mfSBvcGVyYXRvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIG9iamVjdH0gY2FuIGJlIGNhc3QgdG8gdGhlIHR5cGUKKyAgICAgKiAgICAgICAgIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIENsYXNzfTsge0Bjb2RlIGZhbHNlfSBpZiB7QGNvZGUKKyAgICAgKiAgICAgICAgIG9iamVjdH0gaXMge0Bjb2RlIG51bGx9IG9yIGNhbm5vdCBiZSBjYXN0LgorICAgICAqLworICAgIHB1YmxpYyBuYXRpdmUgYm9vbGVhbiBpc0luc3RhbmNlKE9iamVjdCBvYmplY3QpOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyB7QGNvZGUgQ2xhc3N9IHJlcHJlc2VudHMgYW4gaW50ZXJmYWNlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgQ2xhc3N9IHJlcHJlc2VudHMgYW4gaW50ZXJmYWNlOworICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSBib29sZWFuIGlzSW50ZXJmYWNlKCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcyB7QGNvZGUgQ2xhc3N9IGlzIGRlZmluZWQKKyAgICAgKiBsb2NhbGx5LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGNsYXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIENsYXNzfSBpcworICAgICAqICAgICAgICAgZGVmaW5lZCBsb2NhbGx5OyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0xvY2FsQ2xhc3MoKSB7CisgICAgICAgIGJvb2xlYW4gZW5jbG9zZWQgPSAoZ2V0RW5jbG9zaW5nTWV0aG9kKCkgIT0gbnVsbCB8fAorICAgICAgICAgICAgICAgICAgICAgICAgIGdldEVuY2xvc2luZ0NvbnN0cnVjdG9yKCkgIT0gbnVsbCk7CisgICAgICAgIHJldHVybiBlbmNsb3NlZCAmJiAhaXNBbm9ueW1vdXNDbGFzcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBjbGFzcyByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBDbGFzc30gaXMgYSBtZW1iZXIKKyAgICAgKiBjbGFzcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBjbGFzcyByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBDbGFzc30gaXMgYQorICAgICAqICAgICAgICAgbWVtYmVyIGNsYXNzOyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc01lbWJlckNsYXNzKCkgeworICAgICAgICByZXR1cm4gZ2V0RGVjbGFyaW5nQ2xhc3MoKSAhPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMge0Bjb2RlIENsYXNzfSByZXByZXNlbnRzIGEgcHJpbWl0aXZlIHR5cGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBDbGFzc30gcmVwcmVzZW50cyBhIHByaW1pdGl2ZSB0eXBlOworICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSBib29sZWFuIGlzUHJpbWl0aXZlKCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIHtAY29kZSBDbGFzc30gcmVwcmVzZW50cyBhIHN5bnRoZXRpYyB0eXBlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgQ2xhc3N9IHJlcHJlc2VudHMgYSBzeW50aGV0aWMgdHlwZTsKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzU3ludGhldGljKCkgeworICAgICAgICBmaW5hbCBpbnQgQUNDX1NZTlRIRVRJQyA9IDB4MTAwMDsgICAvLyBub3QgcHVibGljIGluIHJlZmxlY3QuTW9kaWZpZXJzCisgICAgICAgIGludCBtb2QgPSBnZXRNb2RpZmllcnModGhpcywgdHJ1ZSk7CisgICAgICAgIHJldHVybiAobW9kICYgQUNDX1NZTlRIRVRJQykgIT0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBjbGFzcyByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBDbGFzc30sCisgICAgICogY3JlYXRlZCBieSBpbnZva2luZyB0aGUgZGVmYXVsdCAodGhhdCBpcywgemVyby1hcmd1bWVudCkgY29uc3RydWN0b3IuIElmCisgICAgICogdGhlcmUgaXMgbm8gc3VjaCBjb25zdHJ1Y3Rvciwgb3IgaWYgdGhlIGNyZWF0aW9uIGZhaWxzIChlaXRoZXIgYmVjYXVzZSBvZgorICAgICAqIGEgbGFjayBvZiBhdmFpbGFibGUgbWVtb3J5IG9yIGJlY2F1c2UgYW4gZXhjZXB0aW9uIGlzIHRocm93biBieSB0aGUKKyAgICAgKiBjb25zdHJ1Y3RvciksIGFuIHtAY29kZSBJbnN0YW50aWF0aW9uRXhjZXB0aW9ufSBpcyB0aHJvd24uIElmIHRoZSBkZWZhdWx0CisgICAgICogY29uc3RydWN0b3IgZXhpc3RzIGJ1dCBpcyBub3QgYWNjZXNzaWJsZSBmcm9tIHRoZSBjb250ZXh0IHdoZXJlIHRoaXMKKyAgICAgKiBtZXRob2QgaXMgaW52b2tlZCwgYW4ge0Bjb2RlIElsbGVnYWxBY2Nlc3NFeGNlcHRpb259IGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGNsYXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIENsYXNzfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZGVmYXVsdCBjb25zdHJ1Y3RvciBpcyBub3QgdmlzaWJsZS4KKyAgICAgKiBAdGhyb3dzIEluc3RhbnRpYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaW5zdGFuY2UgY2FuIG5vdCBiZSBjcmVhdGVkLgorICAgICAqLworICAgIHB1YmxpYyBUIG5ld0luc3RhbmNlKCkgdGhyb3dzIEluc3RhbnRpYXRpb25FeGNlcHRpb24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3SW5zdGFuY2VJbXBsKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBuYXRpdmUgVCBuZXdJbnN0YW5jZUltcGwoKSB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwgSW5zdGFudGlhdGlvbkV4Y2VwdGlvbjsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIGlmIChpc1ByaW1pdGl2ZSgpKSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0U2ltcGxlTmFtZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIChpc0ludGVyZmFjZSgpID8gImludGVyZmFjZSAiIDogImNsYXNzICIpICsgZ2V0TmFtZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIFBhY2thZ2V9IG9mIHdoaWNoIHRoZSBjbGFzcyByZXByZXNlbnRlZCBieSB0aGlzCisgICAgICoge0Bjb2RlIENsYXNzfSBpcyBhIG1lbWJlci4gUmV0dXJucyB7QGNvZGUgbnVsbH0gaWYgbm8ge0Bjb2RlIFBhY2thZ2V9CisgICAgICogb2JqZWN0IHdhcyBjcmVhdGVkIGJ5IHRoZSBjbGFzcyBsb2FkZXIgb2YgdGhlIGNsYXNzLgorICAgICAqCisgICAgICogQHJldHVybiBQYWNrYWdlIHRoZSB7QGNvZGUgUGFja2FnZX0gb2Ygd2hpY2ggdGhpcyB7QGNvZGUgQ2xhc3N9IGlzIGEKKyAgICAgKiAgICAgICAgIG1lbWJlciBvciB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFBhY2thZ2UgZ2V0UGFja2FnZSgpIHsKKyAgICAgICAgLy8gVE9ETyBUaGlzIG1pZ2h0IGJlIGEgaGFjaywgYnV0IHRoZSBWTSBkb2Vzbid0IGhhdmUgdGhlIG5lY2Vzc2FyeSBpbmZvLgorICAgICAgICBDbGFzc0xvYWRlciBsb2FkZXIgPSBnZXRDbGFzc0xvYWRlcigpOworICAgICAgICBpZiAobG9hZGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN0cmluZyBuYW1lID0gZ2V0TmFtZSgpOworICAgICAgICAgICAgaW50IGRvdCA9IG5hbWUubGFzdEluZGV4T2YoJy4nKTsKKyAgICAgICAgICAgIHJldHVybiAoZG90ICE9IC0xID8gbG9hZGVyLmdldFBhY2thZ2UobmFtZS5zdWJzdHJpbmcoMCwgZG90KSkgOiBudWxsKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhc3NlcnRpb24gc3RhdHVzIGZvciB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcyB7QGNvZGUKKyAgICAgKiBDbGFzc30uIEFzc2VydGlvbiBpcyBlbmFibGVkIC8gZGlzYWJsZWQgYmFzZWQgb24gdGhlIGNsYXNzIGxvYWRlciwKKyAgICAgKiBwYWNrYWdlIG9yIGNsYXNzIGRlZmF1bHQgYXQgcnVudGltZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGFzc2VydGlvbiBzdGF0dXMgZm9yIHRoZSBjbGFzcyByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZQorICAgICAqICAgICAgICAgQ2xhc3N9LgorICAgICAqLworICAgIHB1YmxpYyBuYXRpdmUgYm9vbGVhbiBkZXNpcmVkQXNzZXJ0aW9uU3RhdHVzKCk7CisKKyAgICAvKioKKyAgICAgKiBDYXN0cyB0aGlzIHtAY29kZSBDbGFzc30gdG8gcmVwcmVzZW50IGEgc3ViY2xhc3Mgb2YgdGhlIHNwZWNpZmllZCBjbGFzcy4KKyAgICAgKiBJZiBzdWNjZXNzZnVsLCB0aGlzIHtAY29kZSBDbGFzc30gaXMgcmV0dXJuZWQ7IG90aGVyd2lzZSBhIHtAY29kZQorICAgICAqIENsYXNzQ2FzdEV4Y2VwdGlvbn0gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHBhcmFtIGNsYXp6CisgICAgICogICAgICAgICAgICB0aGUgcmVxdWlyZWQgdHlwZS4KKyAgICAgKiBAcmV0dXJuIHRoaXMge0Bjb2RlIENsYXNzfSBjYXN0IGFzIGEgc3ViY2xhc3Mgb2YgdGhlIGdpdmVuIHR5cGUuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBDbGFzc30gY2Fubm90IGJlIGNhc3QgdG8gdGhlIHNwZWNpZmllZCB0eXBlLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyA8VT4gQ2xhc3M8PyBleHRlbmRzIFU+IGFzU3ViY2xhc3MoQ2xhc3M8VT4gY2xhenopIHsKKyAgICAgICAgaWYgKGNsYXp6LmlzQXNzaWduYWJsZUZyb20odGhpcykpIHsKKyAgICAgICAgICAgIHJldHVybiAoQ2xhc3M8PyBleHRlbmRzIFU+KXRoaXM7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIGFjdHVhbENsYXNzTmFtZSA9IHRoaXMuZ2V0TmFtZSgpOworICAgICAgICBTdHJpbmcgZGVzaXJlZENsYXNzTmFtZSA9IGNsYXp6LmdldE5hbWUoKTsKKyAgICAgICAgdGhyb3cgbmV3IENsYXNzQ2FzdEV4Y2VwdGlvbihhY3R1YWxDbGFzc05hbWUgKyAiIGNhbm5vdCBiZSBjYXN0IHRvICIgKyBkZXNpcmVkQ2xhc3NOYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYXN0cyB0aGUgc3BlY2lmaWVkIG9iamVjdCB0byB0aGUgdHlwZSByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBDbGFzc30uCisgICAgICogSWYgdGhlIG9iamVjdCBpcyB7QGNvZGUgbnVsbH0gdGhlbiB0aGUgcmVzdWx0IGlzIGFsc28ge0Bjb2RlIG51bGx9LgorICAgICAqCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjYXN0LgorICAgICAqIEByZXR1cm4gdGhlIG9iamVjdCB0aGF0IGhhcyBiZWVuIGNhc3QuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgb2JqZWN0IGNhbm5vdCBiZSBjYXN0IHRvIHRoZSBzcGVjaWZpZWQgdHlwZS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgVCBjYXN0KE9iamVjdCBvYmopIHsKKyAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBlbHNlIGlmICh0aGlzLmlzSW5zdGFuY2Uob2JqKSkgeworICAgICAgICAgICAgcmV0dXJuIChUKW9iajsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgYWN0dWFsQ2xhc3NOYW1lID0gb2JqLmdldENsYXNzKCkuZ2V0TmFtZSgpOworICAgICAgICBTdHJpbmcgZGVzaXJlZENsYXNzTmFtZSA9IHRoaXMuZ2V0TmFtZSgpOworICAgICAgICB0aHJvdyBuZXcgQ2xhc3NDYXN0RXhjZXB0aW9uKGFjdHVhbENsYXNzTmFtZSArICIgY2Fubm90IGJlIGNhc3QgdG8gIiArIGRlc2lyZWRDbGFzc05hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyB0d28gYXJyYXlzIGludG8gb25lLiBBc3N1bWVzIHRoYXQgdGhlIGRlc3RpbmF0aW9uIGFycmF5IGlzIGxhcmdlCisgICAgICogZW5vdWdoLgorICAgICAqCisgICAgICogQHBhcmFtIHJlc3VsdCB0aGUgZGVzdGluYXRpb24gYXJyYXkKKyAgICAgKiBAcGFyYW0gaGVhZCB0aGUgZmlyc3Qgc291cmNlIGFycmF5CisgICAgICogQHBhcmFtIHRhaWwgdGhlIHNlY29uZCBzb3VyY2UgYXJyYXkKKyAgICAgKiBAcmV0dXJuIHRoZSBkZXN0aW5hdGlvbiBhcnJheSwgdGhhdCBpcywgcmVzdWx0CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgPFQgZXh0ZW5kcyBPYmplY3Q+IFRbXSBhcnJheWNvcHkoVFtdIHJlc3VsdCwgVFtdIGhlYWQsIFRbXSB0YWlsKSB7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoaGVhZCwgMCwgcmVzdWx0LCAwLCBoZWFkLmxlbmd0aCk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodGFpbCwgMCwgcmVzdWx0LCBoZWFkLmxlbmd0aCwgdGFpbC5sZW5ndGgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQ2xhc3NDYXN0RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0NsYXNzQ2FzdEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwMTZkNzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0NsYXNzQ2FzdEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIFRocm93biB3aGVuIGEgcHJvZ3JhbSBhdHRlbXB0cyB0byBjYXN0IGEgYW4gb2JqZWN0IHRvIGEgdHlwZSB3aXRoIHdoaWNoIGl0IGlzCisgKiBub3QgY29tcGF0aWJsZS4KKyAqLworcHVibGljIGNsYXNzIENsYXNzQ2FzdEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC05MjIzMzY1NjUxMDcwNDU4NTMyTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIENsYXNzQ2FzdEV4Y2VwdGlvbn0gdGhhdCBpbmNsdWRlcyB0aGUgY3VycmVudAorICAgICAqIHN0YWNrIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBDbGFzc0Nhc3RFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQ2xhc3NDYXN0RXhjZXB0aW9ufSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlCisgICAgICogYW5kIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xhc3NDYXN0RXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQ2xhc3NDaXJjdWxhcml0eUVycm9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0NsYXNzQ2lyY3VsYXJpdHlFcnJvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjViOWEzNDUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0NsYXNzQ2lyY3VsYXJpdHlFcnJvci5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyb3duIHdoZW4gdGhlIFZNIG5vdGljZXMgdGhhdCBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gbG9hZCBhCisgKiBjbGFzcyB3aGljaCB3b3VsZCBkaXJlY3RseSBvciBpbmRpcmVjdGx5IGluaGVyaXQgZnJvbSBvbmUgb2YgaXRzIHN1YmNsYXNzZXMuCisgKiA8cD4KKyAqIE5vdGUgdGhhdCB0aGlzIGVycm9yIGNhbiBvbmx5IG9jY3VyIHdoZW4gaW5jb25zaXN0ZW50IGNsYXNzIGZpbGVzIGFyZSBsb2FkZWQsCisgKiBzaW5jZSBpdCB3b3VsZCBub3JtYWxseSBiZSBkZXRlY3RlZCBhdCBjb21waWxlIHRpbWUuCisgKi8KK3B1YmxpYyBjbGFzcyBDbGFzc0NpcmN1bGFyaXR5RXJyb3IgZXh0ZW5kcyBMaW5rYWdlRXJyb3IgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTA1NDM2MjU0MjkxNDUzOTY4OUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBDbGFzc0NpcmN1bGFyaXR5RXJyb3J9IHRoYXQgaW5jbHVkZSB0aGUgY3VycmVudAorICAgICAqIHN0YWNrIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBDbGFzc0NpcmN1bGFyaXR5RXJyb3IoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQ2xhc3NDaXJjdWxhcml0eUVycm9yfSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrCisgICAgICogdHJhY2UgYW5kIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBDbGFzc0NpcmN1bGFyaXR5RXJyb3IoU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9DbGFzc0Zvcm1hdEVycm9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0NsYXNzRm9ybWF0RXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZDUzN2E4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9DbGFzc0Zvcm1hdEVycm9yLmphdmEKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyb3duIGJ5IGEgY2xhc3MgbG9hZGVyIHdoZW4gYSBjbGFzcyBmaWxlIGhhcyBhbiBpbGxlZ2FsIGZvcm1hdCBvciBpZiB0aGUKKyAqIGRhdGEgdGhhdCBpdCBjb250YWlucyBjYW4gbm90IGJlIGludGVycHJldGVkIGFzIGEgY2xhc3MuCisgKi8KK3B1YmxpYyBjbGFzcyBDbGFzc0Zvcm1hdEVycm9yIGV4dGVuZHMgTGlua2FnZUVycm9yIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04NDIwMTE0ODc5MDExOTQ5MTk1TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIENsYXNzRm9ybWF0RXJyb3J9IHRoYXQgaW5jbHVkZXMgdGhlIGN1cnJlbnQgc3RhY2sKKyAgICAgKiB0cmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xhc3NGb3JtYXRFcnJvcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBDbGFzc0Zvcm1hdEVycm9yfSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlCisgICAgICogYW5kIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBDbGFzc0Zvcm1hdEVycm9yKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQ2xhc3NMb2FkZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQ2xhc3NMb2FkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wY2RjNDQ4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9DbGFzc0xvYWRlci5qYXZhCkBAIC0wLDAgKzEsODQwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKK2ltcG9ydCBkYWx2aWsuc3lzdGVtLlBhdGhDbGFzc0xvYWRlcjsKK2ltcG9ydCBkYWx2aWsuc3lzdGVtLlZNU3RhY2s7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdGVjdGlvbkRvbWFpbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogTG9hZHMgY2xhc3NlcyBhbmQgcmVzb3VyY2VzIGZyb20gYSByZXBvc2l0b3J5LiBPbmUgb3IgbW9yZSBjbGFzcyBsb2FkZXJzIGFyZQorICogaW5zdGFsbGVkIGF0IHJ1bnRpbWUuIFRoZXNlIGFyZSBjb25zdWx0ZWQgd2hlbmV2ZXIgdGhlIHJ1bnRpbWUgc3lzdGVtIG5lZWRzIGEKKyAqIHNwZWNpZmljIGNsYXNzIHRoYXQgaXMgbm90IHlldCBhdmFpbGFibGUgaW4tbWVtb3J5LiBUeXBpY2FsbHksIGNsYXNzIGxvYWRlcnMKKyAqIGFyZSBncm91cGVkIGludG8gYSB0cmVlIHdoZXJlIGNoaWxkIGNsYXNzIGxvYWRlcnMgZGVsZWdhdGUgYWxsIHJlcXVlc3RzIHRvCisgKiBwYXJlbnQgY2xhc3MgbG9hZGVycy4gT25seSBpZiB0aGUgcGFyZW50IGNsYXNzIGxvYWRlciBjYW5ub3Qgc2F0aXNmeSB0aGUKKyAqIHJlcXVlc3QsIHRoZSBjaGlsZCBjbGFzcyBsb2FkZXIgaXRzZWxmIHRyaWVzIHRvIGhhbmRsZSBpdC4KKyAqIDxwPgorICoge0Bjb2RlIENsYXNzTG9hZGVyfSBpcyBhbiBhYnN0cmFjdCBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhlIGNvbW1vbgorICogaW5mcmFzdHJ1Y3R1cmUgcmVxdWlyZWQgYnkgYWxsIGNsYXNzIGxvYWRlcnMuIEFuZHJvaWQgcHJvdmlkZXMgc2V2ZXJhbAorICogY29uY3JldGUgaW1wbGVtZW50YXRpb25zIG9mIHRoZSBjbGFzcywgd2l0aAorICoge0BsaW5rIGRhbHZpay5zeXN0ZW0uUGF0aENsYXNzTG9hZGVyfSBiZWluZyB0aGUgb25lIHR5cGljYWxseSB1c2VkLiBPdGhlcgorICogYXBwbGljYXRpb25zIG1heSBpbXBsZW1lbnQgc3ViY2xhc3NlcyBvZiB7QGNvZGUgQ2xhc3NMb2FkZXJ9IHRvIHByb3ZpZGUKKyAqIHNwZWNpYWwgd2F5cyBmb3IgbG9hZGluZyBjbGFzc2VzLgorICogPC9wPgorICogQHNlZSBDbGFzcworICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ2xhc3NMb2FkZXIgeworCisgICAgLyoqCisgICAgICogVGhlICdTeXN0ZW0nIENsYXNzTG9hZGVyIC0gdGhlIG9uZSB0aGF0IGlzIHJlc3BvbnNpYmxlIGZvciBsb2FkaW5nCisgICAgICogY2xhc3NlcyBmcm9tIHRoZSBjbGFzc3BhdGguIEl0IGlzIG5vdCBlcXVhbCB0byB0aGUgYm9vdHN0cmFwIGNsYXNzIGxvYWRlciAtCisgICAgICogdGhhdCBvbmUgaGFuZGxlcyB0aGUgYnVpbHQtaW4gY2xhc3Nlcy4KKyAgICAgKgorICAgICAqIEJlY2F1c2Ugb2YgYSBwb3RlbnRpYWwgY2xhc3MgaW5pdGlhbGl6YXRpb24gcmFjZSBiZXR3ZWVuIENsYXNzTG9hZGVyIGFuZAorICAgICAqIGphdmEubGFuZy5TeXN0ZW0sIHJlcHJvZHVjaWJsZSB3aGVuIHVzaW5nIEpEV1Agd2l0aCAic3VzcGVuZD15Iiwgd2UgZGVmZXIKKyAgICAgKiBjcmVhdGlvbiBvZiB0aGUgc3lzdGVtIGNsYXNzIGxvYWRlciB1bnRpbCBmaXJzdCB1c2UuIFdlIHVzZSBhIHN0YXRpYworICAgICAqIGlubmVyIGNsYXNzIHRvIGdldCBzeW5jaHJvbml6YXRpb24gYXQgaW5pdCB0aW1lIHdpdGhvdXQgaGF2aW5nIHRvIHN5bmMgb24KKyAgICAgKiBldmVyeSBhY2Nlc3MuCisgICAgICoKKyAgICAgKiBAc2VlICNnZXRTeXN0ZW1DbGFzc0xvYWRlcigpCisgICAgICovCisgICAgc3RhdGljIHByaXZhdGUgY2xhc3MgU3lzdGVtQ2xhc3NMb2FkZXIgeworICAgICAgICBwdWJsaWMgc3RhdGljIENsYXNzTG9hZGVyIGxvYWRlciA9IENsYXNzTG9hZGVyLmNyZWF0ZVN5c3RlbUNsYXNzTG9hZGVyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIHBhcmVudCBDbGFzc0xvYWRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIENsYXNzTG9hZGVyIHBhcmVudDsKKworICAgIC8qKgorICAgICAqIFRoZSBwYWNrYWdlcyBrbm93biB0byB0aGUgY2xhc3MgbG9hZGVyLgorICAgICAqLworICAgIHByaXZhdGUgTWFwPFN0cmluZywgUGFja2FnZT4gcGFja2FnZXMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFBhY2thZ2U+KCk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgdGhlIHN5c3RlbSBjbGFzcyBsb2FkZXIuIE5vdGUgdGhpcyBpcyBOT1QgdGhlIGJvb3RzdHJhcCBjbGFzcworICAgICAqIGxvYWRlciAod2hpY2ggaXMgbWFuYWdlZCBieSB0aGUgVk0pLiBXZSB1c2UgYSBudWxsIHZhbHVlIGZvciB0aGUgcGFyZW50CisgICAgICogdG8gaW5kaWNhdGUgdGhhdCB0aGUgYm9vdHN0cmFwIGxvYWRlciBpcyBvdXIgcGFyZW50LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIENsYXNzTG9hZGVyIGNyZWF0ZVN5c3RlbUNsYXNzTG9hZGVyKCkgeworICAgICAgICBTdHJpbmcgY2xhc3NQYXRoID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmNsYXNzLnBhdGgiLCAiLiIpOworCisgICAgICAgIC8vIFN0cmluZ1tdIHBhdGhzID0gY2xhc3NQYXRoLnNwbGl0KCI6Iik7CisgICAgICAgIC8vIFVSTFtdIHVybHMgPSBuZXcgVVJMW3BhdGhzLmxlbmd0aF07CisgICAgICAgIC8vIGZvciAoaW50IGkgPSAwOyBpIDwgcGF0aHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgLy8gdHJ5IHsKKyAgICAgICAgLy8gdXJsc1tpXSA9IG5ldyBVUkwoImZpbGU6Ly8iICsgcGF0aHNbaV0pOworICAgICAgICAvLyB9CisgICAgICAgIC8vIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgLy8gZXgucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIC8vIH0KKyAgICAgICAgLy8gfQorICAgICAgICAvLworICAgICAgICAvLyByZXR1cm4gbmV3IGphdmEubmV0LlVSTENsYXNzTG9hZGVyKHVybHMsIG51bGwpOworCisgICAgICAgIC8vIFRPRE8gTWFrZSB0aGlzIGEgamF2YS5uZXQuVVJMQ2xhc3NMb2FkZXIgb25jZSB3ZSBoYXZlIHRob3NlPworICAgICAgICByZXR1cm4gbmV3IFBhdGhDbGFzc0xvYWRlcihjbGFzc1BhdGgsIEJvb3RDbGFzc0xvYWRlci5nZXRJbnN0YW5jZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzeXN0ZW0gY2xhc3MgbG9hZGVyLiBUaGlzIGlzIHRoZSBwYXJlbnQgZm9yIG5ldworICAgICAqIHtAY29kZSBDbGFzc0xvYWRlcn0gaW5zdGFuY2VzIGFuZCBpcyB0eXBpY2FsbHkgdGhlIGNsYXNzIGxvYWRlciB1c2VkIHRvCisgICAgICogc3RhcnQgdGhlIGFwcGxpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ2xhc3NMb2FkZXIgZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKSB7CisgICAgICAgIHJldHVybiBTeXN0ZW1DbGFzc0xvYWRlci5sb2FkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgdGhlIFVSTCBvZiB0aGUgcmVzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuIFRoZSBzeXN0ZW0gY2xhc3MKKyAgICAgKiBsb2FkZXIncyByZXNvdXJjZSBsb29rdXAgYWxnb3JpdGhtIGlzIHVzZWQgdG8gZmluZCB0aGUgcmVzb3VyY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgVVJMfSBvYmplY3QgZm9yIHRoZSByZXF1ZXN0ZWQgcmVzb3VyY2Ugb3Ige0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpZiB0aGUgcmVzb3VyY2UgY2FuIG5vdCBiZSBmb3VuZC4KKyAgICAgKiBAcGFyYW0gcmVzTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGZpbmQuCisgICAgICogQHNlZSBDbGFzcyNnZXRSZXNvdXJjZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVVJMIGdldFN5c3RlbVJlc291cmNlKFN0cmluZyByZXNOYW1lKSB7CisgICAgICAgIHJldHVybiBTeXN0ZW1DbGFzc0xvYWRlci5sb2FkZXIuZ2V0UmVzb3VyY2UocmVzTmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBlbnVtZXJhdGlvbiBvZiBVUkxzIGZvciB0aGUgcmVzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuCisgICAgICogVGhlIHN5c3RlbSBjbGFzcyBsb2FkZXIncyByZXNvdXJjZSBsb29rdXAgYWxnb3JpdGhtIGlzIHVzZWQgdG8gZmluZCB0aGUKKyAgICAgKiByZXNvdXJjZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gZW51bWVyYXRpb24gb2Yge0Bjb2RlIFVSTH0gb2JqZWN0cyBjb250YWluaW5nIHRoZSByZXF1ZXN0ZWQKKyAgICAgKiAgICAgICAgIHJlc291cmNlcy4KKyAgICAgKiBAcGFyYW0gcmVzTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGZpbmQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBFbnVtZXJhdGlvbjxVUkw+IGdldFN5c3RlbVJlc291cmNlcyhTdHJpbmcgcmVzTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIFN5c3RlbUNsYXNzTG9hZGVyLmxvYWRlci5nZXRSZXNvdXJjZXMocmVzTmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmVhbSBmb3IgdGhlIHJlc291cmNlIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLiBUaGUgc3lzdGVtCisgICAgICogY2xhc3MgbG9hZGVyJ3MgcmVzb3VyY2UgbG9va3VwIGFsZ29yaXRobSBpcyB1c2VkIHRvIGZpbmQgdGhlIHJlc291cmNlLgorICAgICAqIEJhc2ljYWxseSwgdGhlIGNvbnRlbnRzIG9mIHRoZSBqYXZhLmNsYXNzLnBhdGggYXJlIHNlYXJjaGVkIGluIG9yZGVyLAorICAgICAqIGxvb2tpbmcgZm9yIGEgcGF0aCB3aGljaCBtYXRjaGVzIHRoZSBzcGVjaWZpZWQgcmVzb3VyY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc3RyZWFtIGZvciB0aGUgcmVzb3VyY2Ugb3Ige0Bjb2RlIG51bGx9LgorICAgICAqIEBwYXJhbSByZXNOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gZmluZC4KKyAgICAgKiBAc2VlIENsYXNzI2dldFJlc291cmNlQXNTdHJlYW0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIElucHV0U3RyZWFtIGdldFN5c3RlbVJlc291cmNlQXNTdHJlYW0oU3RyaW5nIHJlc05hbWUpIHsKKyAgICAgICAgcmV0dXJuIFN5c3RlbUNsYXNzTG9hZGVyLmxvYWRlci5nZXRSZXNvdXJjZUFzU3RyZWFtKHJlc05hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyB3aXRoIHRoZSBzeXN0ZW0gY2xhc3MgbG9hZGVyIGFzCisgICAgICogaXRzIHBhcmVudC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ2xhc3NMb2FkZXIoKSB7CisgICAgICAgIHRoaXMoZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKSwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyB3aXRoIHRoZSBzcGVjaWZpZWQgY2xhc3MgbG9hZGVyCisgICAgICogYXMgaXRzIHBhcmVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJlbnRMb2FkZXIKKyAgICAgKiAgICAgICAgICAgIFRoZSB7QGNvZGUgQ2xhc3NMb2FkZXJ9IHRvIHVzZSBhcyB0aGUgbmV3IGNsYXNzIGxvYWRlcidzCisgICAgICogICAgICAgICAgICBwYXJlbnQuCisgICAgICovCisgICAgcHJvdGVjdGVkIENsYXNzTG9hZGVyKENsYXNzTG9hZGVyIHBhcmVudExvYWRlcikgeworICAgICAgICB0aGlzKHBhcmVudExvYWRlciwgZmFsc2UpOworICAgIH0KKworICAgIC8qCisgICAgICogY29uc3RydWN0b3IgZm9yIHRoZSBCb290Q2xhc3NMb2FkZXIgd2hpY2ggbmVlZHMgcGFyZW50IHRvIGJlIG51bGwuCisgICAgICovCisgICAgQ2xhc3NMb2FkZXIoQ2xhc3NMb2FkZXIgcGFyZW50TG9hZGVyLCBib29sZWFuIG51bGxBbGxvd2VkKSB7CisgICAgICAgIGlmIChwYXJlbnRMb2FkZXIgPT0gbnVsbCAmJiAhbnVsbEFsbG93ZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiUGFyZW50IENsYXNzTG9hZGVyIG1heSBub3QgYmUgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHBhcmVudCA9IHBhcmVudExvYWRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGNsYXNzIGZyb20gYW4gYXJyYXkgb2YgYnl0ZXMgY29udGFpbmluZyBhIGNsYXNzCisgICAgICogZGVmaW5pdGlvbiBpbiBjbGFzcyBmaWxlIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbGFzc1JlcAorICAgICAqICAgICAgICAgICAgdGhlIG1lbW9yeSBpbWFnZSBvZiBhIGNsYXNzIGZpbGUuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbnRvIHtAY29kZSBjbGFzc1JlcH0uCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgY2xhc3MgZmlsZS4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgQ2xhc3N9IG9iamVjdCBjcmVhdGVkIGZyb20gdGhlIHNwZWNpZmllZCBzdWJzZXQgb2YKKyAgICAgKiAgICAgICAgIGRhdGEgaW4ge0Bjb2RlIGNsYXNzUmVwfS4KKyAgICAgKiBAdGhyb3dzIENsYXNzRm9ybWF0RXJyb3IKKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY2xhc3NSZXB9IGRvZXMgbm90IGNvbnRhaW4gYSB2YWxpZCBjbGFzcy4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0sIHtAY29kZSBsZW5ndGggPCAwfSBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBsZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGNsYXNzUmVwfS4KKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNkZWZpbmVDbGFzcyhTdHJpbmcsIGJ5dGVbXSwgaW50LCBpbnQpfQorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHJvdGVjdGVkIGZpbmFsIENsYXNzPD8+IGRlZmluZUNsYXNzKGJ5dGVbXSBjbGFzc1JlcCwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgIHRocm93cyBDbGFzc0Zvcm1hdEVycm9yIHsKKworICAgICAgICByZXR1cm4gVk1DbGFzc0xvYWRlci5kZWZpbmVDbGFzcyh0aGlzLCBjbGFzc1JlcCwgb2Zmc2V0LCBsZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgY2xhc3MgZnJvbSBhbiBhcnJheSBvZiBieXRlcyBjb250YWluaW5nIGEgY2xhc3MKKyAgICAgKiBkZWZpbml0aW9uIGluIGNsYXNzIGZpbGUgZm9ybWF0LgorICAgICAqCisgICAgICogQHBhcmFtIGNsYXNzTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGV4cGVjdGVkIG5hbWUgb2YgdGhlIG5ldyBjbGFzcywgbWF5IGJlIHtAY29kZSBudWxsfSBpZiBub3QKKyAgICAgKiAgICAgICAgICAgIGtub3duLgorICAgICAqIEBwYXJhbSBjbGFzc1JlcAorICAgICAqICAgICAgICAgICAgdGhlIG1lbW9yeSBpbWFnZSBvZiBhIGNsYXNzIGZpbGUuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbnRvIHtAY29kZSBjbGFzc1JlcH0uCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgY2xhc3MgZmlsZS4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgQ2xhc3N9IG9iamVjdCBjcmVhdGVkIGZyb20gdGhlIHNwZWNpZmllZCBzdWJzZXQgb2YKKyAgICAgKiAgICAgICAgIGRhdGEgaW4ge0Bjb2RlIGNsYXNzUmVwfS4KKyAgICAgKiBAdGhyb3dzIENsYXNzRm9ybWF0RXJyb3IKKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY2xhc3NSZXB9IGRvZXMgbm90IGNvbnRhaW4gYSB2YWxpZCBjbGFzcy4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0sIHtAY29kZSBsZW5ndGggPCAwfSBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBsZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGNsYXNzUmVwfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgQ2xhc3M8Pz4gZGVmaW5lQ2xhc3MoU3RyaW5nIGNsYXNzTmFtZSwgYnl0ZVtdIGNsYXNzUmVwLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgdGhyb3dzIENsYXNzRm9ybWF0RXJyb3IgeworCisgICAgICAgIC8vIFRPRE8gRGVmaW5lIGEgZGVmYXVsdCBQcm90ZWN0aW9uRG9tYWluIG9uIGZpcnN0IHVzZQorICAgICAgICByZXR1cm4gZGVmaW5lQ2xhc3MoY2xhc3NOYW1lLCBjbGFzc1JlcCwgb2Zmc2V0LCBsZW5ndGgsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgY2xhc3MgZnJvbSBhbiBhcnJheSBvZiBieXRlcyBjb250YWluaW5nIGEgY2xhc3MKKyAgICAgKiBkZWZpbml0aW9uIGluIGNsYXNzIGZpbGUgZm9ybWF0IGFuZCBhc3NpZ25zIHRoZSBzcGVjaWZpZWQgcHJvdGVjdGlvbgorICAgICAqIGRvbWFpbiB0byB0aGUgbmV3IGNsYXNzLiBJZiB0aGUgcHJvdmlkZWQgcHJvdGVjdGlvbiBkb21haW4gaXMKKyAgICAgKiB7QGNvZGUgbnVsbH0gdGhlbiBhIGRlZmF1bHQgcHJvdGVjdGlvbiBkb21haW4gaXMgYXNzaWduZWQgdG8gdGhlIGNsYXNzLgorICAgICAqCisgICAgICogQHBhcmFtIGNsYXNzTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGV4cGVjdGVkIG5hbWUgb2YgdGhlIG5ldyBjbGFzcywgbWF5IGJlIHtAY29kZSBudWxsfSBpZiBub3QKKyAgICAgKiAgICAgICAgICAgIGtub3duLgorICAgICAqIEBwYXJhbSBjbGFzc1JlcAorICAgICAqICAgICAgICAgICAgdGhlIG1lbW9yeSBpbWFnZSBvZiBhIGNsYXNzIGZpbGUuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbnRvIHtAY29kZSBjbGFzc1JlcH0uCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgY2xhc3MgZmlsZS4KKyAgICAgKiBAcGFyYW0gcHJvdGVjdGlvbkRvbWFpbgorICAgICAqICAgICAgICAgICAgdGhlIHByb3RlY3Rpb24gZG9tYWluIHRvIGFzc2lnbiB0byB0aGUgbG9hZGVkIGNsYXNzLCBtYXkgYmUKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBudWxsfS4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgQ2xhc3N9IG9iamVjdCBjcmVhdGVkIGZyb20gdGhlIHNwZWNpZmllZCBzdWJzZXQgb2YKKyAgICAgKiAgICAgICAgIGRhdGEgaW4ge0Bjb2RlIGNsYXNzUmVwfS4KKyAgICAgKiBAdGhyb3dzIENsYXNzRm9ybWF0RXJyb3IKKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY2xhc3NSZXB9IGRvZXMgbm90IGNvbnRhaW4gYSB2YWxpZCBjbGFzcy4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0sIHtAY29kZSBsZW5ndGggPCAwfSBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBvZmZzZXQgKyBsZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGNsYXNzUmVwfS4KKyAgICAgKiBAdGhyb3dzIE5vQ2xhc3NEZWZGb3VuZEVycm9yCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGNsYXNzTmFtZX0gaXMgbm90IGVxdWFsIHRvIHRoZSBuYW1lIG9mIHRoZSBjbGFzcworICAgICAqICAgICAgICAgICAgIGNvbnRhaW5lZCBpbiB7QGNvZGUgY2xhc3NSZXB9LgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBDbGFzczw/PiBkZWZpbmVDbGFzcyhTdHJpbmcgY2xhc3NOYW1lLCBieXRlW10gY2xhc3NSZXAsIGludCBvZmZzZXQsIGludCBsZW5ndGgsCisgICAgICAgICAgICBQcm90ZWN0aW9uRG9tYWluIHByb3RlY3Rpb25Eb21haW4pIHRocm93cyBqYXZhLmxhbmcuQ2xhc3NGb3JtYXRFcnJvciB7CisKKyAgICAgICAgcmV0dXJuIFZNQ2xhc3NMb2FkZXIuZGVmaW5lQ2xhc3ModGhpcywgY2xhc3NOYW1lLCBjbGFzc1JlcCwgb2Zmc2V0LCBsZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlZmluZXMgYSBuZXcgY2xhc3Mgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUsIGJ5dGUgY29kZSBmcm9tIHRoZSBieXRlCisgICAgICogYnVmZmVyIGFuZCB0aGUgb3B0aW9uYWwgcHJvdGVjdGlvbiBkb21haW4uIElmIHRoZSBwcm92aWRlZCBwcm90ZWN0aW9uCisgICAgICogZG9tYWluIGlzIHtAY29kZSBudWxsfSB0aGVuIGEgZGVmYXVsdCBwcm90ZWN0aW9uIGRvbWFpbiBpcyBhc3NpZ25lZCB0bworICAgICAqIHRoZSBjbGFzcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgZXhwZWN0ZWQgbmFtZSBvZiB0aGUgbmV3IGNsYXNzLCBtYXkgYmUge0Bjb2RlIG51bGx9IGlmIG5vdAorICAgICAqICAgICAgICAgICAga25vd24uCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGJ1ZmZlciBjb250YWluaW5nIHRoZSBieXRlIGNvZGUgb2YgdGhlIG5ldyBjbGFzcy4KKyAgICAgKiBAcGFyYW0gcHJvdGVjdGlvbkRvbWFpbgorICAgICAqICAgICAgICAgICAgdGhlIHByb3RlY3Rpb24gZG9tYWluIHRvIGFzc2lnbiB0byB0aGUgbG9hZGVkIGNsYXNzLCBtYXkgYmUKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBudWxsfS4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgQ2xhc3N9IG9iamVjdCBjcmVhdGVkIGZyb20gdGhlIGRhdGEgaW4ge0Bjb2RlIGJ9LgorICAgICAqIEB0aHJvd3MgQ2xhc3NGb3JtYXRFcnJvcgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBifSBkb2VzIG5vdCBjb250YWluIGEgdmFsaWQgY2xhc3MuCisgICAgICogQHRocm93cyBOb0NsYXNzRGVmRm91bmRFcnJvcgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBjbGFzc05hbWV9IGlzIG5vdCBlcXVhbCB0byB0aGUgbmFtZSBvZiB0aGUgY2xhc3MKKyAgICAgKiAgICAgICAgICAgICBjb250YWluZWQgaW4ge0Bjb2RlIGJ9LgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBDbGFzczw/PiBkZWZpbmVDbGFzcyhTdHJpbmcgbmFtZSwgQnl0ZUJ1ZmZlciBiLAorICAgICAgICAgICAgUHJvdGVjdGlvbkRvbWFpbiBwcm90ZWN0aW9uRG9tYWluKSB0aHJvd3MgQ2xhc3NGb3JtYXRFcnJvciB7CisKKyAgICAgICAgYnl0ZVtdIHRlbXAgPSBuZXcgYnl0ZVtiLnJlbWFpbmluZygpXTsKKyAgICAgICAgYi5nZXQodGVtcCk7CisgICAgICAgIHJldHVybiBkZWZpbmVDbGFzcyhuYW1lLCB0ZW1wLCAwLCB0ZW1wLmxlbmd0aCwgcHJvdGVjdGlvbkRvbWFpbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3ZlcnJpZGRlbiBieSBzdWJjbGFzc2VzLCB0aHJvd3MgYSB7QGNvZGUgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbn0gYnkKKyAgICAgKiBkZWZhdWx0LiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkge0Bjb2RlIGxvYWRDbGFzc30gYWZ0ZXIgdGhlIHBhcmVudAorICAgICAqIHtAY29kZSBDbGFzc0xvYWRlcn0gaGFzIGZhaWxlZCB0byBmaW5kIGEgbG9hZGVkIGNsYXNzIG9mIHRoZSBzYW1lIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2xhc3NOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgdG8gbG9vayBmb3IuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIENsYXNzfSBvYmplY3QgdGhhdCBpcyBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2xhc3MgY2Fubm90IGJlIGZvdW5kLgorICAgICAqLworICAgIHByb3RlY3RlZCBDbGFzczw/PiBmaW5kQ2xhc3MoU3RyaW5nIGNsYXNzTmFtZSkgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbihjbGFzc05hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNsYXNzIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGlmIGl0IGhhcyBhbHJlYWR5IGJlZW4gbG9hZGVkCisgICAgICogYnkgdGhlIFZNIG9yIHtAY29kZSBudWxsfSBpZiBpdCBoYXMgbm90IHlldCBiZWVuIGxvYWRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbGFzc05hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyB0byBsb29rIGZvci4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgQ2xhc3N9IG9iamVjdCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIHJlcXVlc3RlZCBjbGFzcworICAgICAqICAgICAgICAgaGFzIG5vdCBiZWVuIGxvYWRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgQ2xhc3M8Pz4gZmluZExvYWRlZENsYXNzKFN0cmluZyBjbGFzc05hbWUpIHsKKyAgICAgICAgQ2xhc3NMb2FkZXIgbG9hZGVyOworICAgICAgICBpZiAodGhpcyA9PSBCb290Q2xhc3NMb2FkZXIuZ2V0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIGxvYWRlciA9IG51bGw7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGxvYWRlciA9IHRoaXM7CisgICAgICAgIHJldHVybiBWTUNsYXNzTG9hZGVyLmZpbmRMb2FkZWRDbGFzcyhsb2FkZXIsIGNsYXNzTmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgdGhlIGNsYXNzIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLCBsb2FkaW5nIGl0IHVzaW5nIHRoZSBzeXN0ZW0KKyAgICAgKiBjbGFzcyBsb2FkZXIgaWYgbmVjZXNzYXJ5LgorICAgICAqCisgICAgICogQHBhcmFtIGNsYXNzTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNsYXNzIHRvIGxvb2sgZm9yLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBDbGFzc30gb2JqZWN0IHdpdGggdGhlIHJlcXVlc3RlZCB7QGNvZGUgY2xhc3NOYW1lfS4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2xhc3MgY2FuIG5vdCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgQ2xhc3M8Pz4gZmluZFN5c3RlbUNsYXNzKFN0cmluZyBjbGFzc05hbWUpIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIENsYXNzLmZvck5hbWUoY2xhc3NOYW1lLCBmYWxzZSwgZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIGNsYXNzIGxvYWRlcidzIHBhcmVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBjbGFzcyBsb2FkZXIncyBwYXJlbnQgb3Ige0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBDbGFzc0xvYWRlciBnZXRQYXJlbnQoKSB7CisgICAgICAgIHJldHVybiBwYXJlbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgVVJMIG9mIHRoZSByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS4gVGhpcworICAgICAqIGltcGxlbWVudGF0aW9uIGZpcnN0IHRyaWVzIHRvIHVzZSB0aGUgcGFyZW50IGNsYXNzIGxvYWRlciB0byBmaW5kIHRoZQorICAgICAqIHJlc291cmNlOyBpZiB0aGlzIGZhaWxzIHRoZW4ge0BsaW5rICNmaW5kUmVzb3VyY2UoU3RyaW5nKX0gaXMgY2FsbGVkIHRvCisgICAgICogZmluZCB0aGUgcmVxdWVzdGVkIHJlc291cmNlLgorICAgICAqCisgICAgICogQHBhcmFtIHJlc05hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSB0byBmaW5kLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBVUkx9IG9iamVjdCBmb3IgdGhlIHJlcXVlc3RlZCByZXNvdXJjZSBvciB7QGNvZGUgbnVsbH0KKyAgICAgKiAgICAgICAgIGlmIHRoZSByZXNvdXJjZSBjYW4gbm90IGJlIGZvdW5kCisgICAgICogQHNlZSBDbGFzcyNnZXRSZXNvdXJjZQorICAgICAqLworICAgIHB1YmxpYyBVUkwgZ2V0UmVzb3VyY2UoU3RyaW5nIHJlc05hbWUpIHsKKyAgICAgICAgVVJMIHJlc291cmNlID0gcGFyZW50LmdldFJlc291cmNlKHJlc05hbWUpOworICAgICAgICBpZiAocmVzb3VyY2UgPT0gbnVsbCkgeworICAgICAgICAgICAgcmVzb3VyY2UgPSBmaW5kUmVzb3VyY2UocmVzTmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc291cmNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gZW51bWVyYXRpb24gb2YgVVJMcyBmb3IgdGhlIHJlc291cmNlIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gZmlyc3QgdXNlcyB0aGlzIGNsYXNzIGxvYWRlcidzIHBhcmVudCB0byBmaW5kIHRoZQorICAgICAqIHJlc291cmNlLCB0aGVuIGl0IGNhbGxzIHtAbGluayAjZmluZFJlc291cmNlcyhTdHJpbmcpfSB0byBnZXQgYWRkaXRpb25hbAorICAgICAqIFVSTHMuIFRoZSByZXR1cm5lZCBlbnVtZXJhdGlvbiBjb250YWlucyB0aGUge0Bjb2RlIFVSTH0gb2JqZWN0cyBvZiBib3RoCisgICAgICogZmluZCBvcGVyYXRpb25zLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBlbnVtZXJhdGlvbiBvZiB7QGNvZGUgVVJMfSBvYmplY3RzIGZvciB0aGUgcmVxdWVzdGVkIHJlc291cmNlLgorICAgICAqIEBwYXJhbSByZXNOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gZmluZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgRW51bWVyYXRpb248VVJMPiBnZXRSZXNvdXJjZXMoU3RyaW5nIHJlc05hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgRW51bWVyYXRpb24gZmlyc3QgPSBwYXJlbnQuZ2V0UmVzb3VyY2VzKHJlc05hbWUpOworICAgICAgICBFbnVtZXJhdGlvbiBzZWNvbmQgPSBmaW5kUmVzb3VyY2VzKHJlc05hbWUpOworCisgICAgICAgIHJldHVybiBuZXcgVHdvRW51bWVyYXRpb25zSW5PbmUoZmlyc3QsIHNlY29uZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmVhbSBmb3IgdGhlIHJlc291cmNlIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLiBTZWUKKyAgICAgKiB7QGxpbmsgI2dldFJlc291cmNlKFN0cmluZyl9IGZvciBhIGRlc2NyaXB0aW9uIG9mIHRoZSBsb29rdXAgYWxnb3JpdGhtCisgICAgICogdXNlZCB0byBmaW5kIHRoZSByZXNvdXJjZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJlYW0gZm9yIHRoZSByZXNvdXJjZSBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIHJlc291cmNlIGNhbiBub3QgYmUgZm91bmQKKyAgICAgKiBAcGFyYW0gcmVzTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGZpbmQuCisgICAgICogQHNlZSBDbGFzcyNnZXRSZXNvdXJjZUFzU3RyZWFtCisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldFJlc291cmNlQXNTdHJlYW0oU3RyaW5nIHJlc05hbWUpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFVSTCB1cmwgPSBnZXRSZXNvdXJjZShyZXNOYW1lKTsKKyAgICAgICAgICAgIGlmICh1cmwgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiB1cmwub3BlblN0cmVhbSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgLy8gRG9uJ3Qgd2FudCB0byBzZWUgdGhlIGV4Y2VwdGlvbi4KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvYWRzIHRoZSBjbGFzcyB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS4gSW52b2tpbmcgdGhpcyBtZXRob2QgaXMKKyAgICAgKiBlcXVpdmFsZW50IHRvIGNhbGxpbmcge0Bjb2RlIGxvYWRDbGFzcyhjbGFzc05hbWUsIGZhbHNlKX0uCisgICAgICogPHA+CisgICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBJbiB0aGUgQW5kcm9pZCByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24sIHRoZQorICAgICAqIHNlY29uZCBwYXJhbWV0ZXIgb2Yge0BsaW5rICNsb2FkQ2xhc3MoU3RyaW5nLCBib29sZWFuKX0gaXMgaWdub3JlZAorICAgICAqIGFueXdheS4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgQ2xhc3N9IG9iamVjdC4KKyAgICAgKiBAcGFyYW0gY2xhc3NOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgdG8gbG9vayBmb3IuCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNsYXNzIGNhbiBub3QgYmUgZm91bmQuCisgICAgICovCisgICAgcHVibGljIENsYXNzPD8+IGxvYWRDbGFzcyhTdHJpbmcgY2xhc3NOYW1lKSB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBsb2FkQ2xhc3MoY2xhc3NOYW1lLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9hZHMgdGhlIGNsYXNzIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLCBvcHRpb25hbGx5IGxpbmtpbmcgaXQgYWZ0ZXIKKyAgICAgKiBsb2FkaW5nLiBUaGUgZm9sbG93aW5nIHN0ZXBzIGFyZSBwZXJmb3JtZWQ6CisgICAgICogPG9sPgorICAgICAqIDxsaT4gQ2FsbCB7QGxpbmsgI2ZpbmRMb2FkZWRDbGFzcyhTdHJpbmcpfSB0byBkZXRlcm1pbmUgaWYgdGhlIHJlcXVlc3RlZAorICAgICAqIGNsYXNzIGhhcyBhbHJlYWR5IGJlZW4gbG9hZGVkLjwvbGk+CisgICAgICogPGxpPklmIHRoZSBjbGFzcyBoYXMgbm90IHlldCBiZWVuIGxvYWRlZDogSW52b2tlIHRoaXMgbWV0aG9kIG9uIHRoZQorICAgICAqIHBhcmVudCBjbGFzcyBsb2FkZXIuPC9saT4KKyAgICAgKiA8bGk+SWYgdGhlIGNsYXNzIGhhcyBzdGlsbCBub3QgYmVlbiBsb2FkZWQ6IENhbGwKKyAgICAgKiB7QGxpbmsgI2ZpbmRDbGFzcyhTdHJpbmcpfSB0byBmaW5kIHRoZSBjbGFzcy48L2xpPgorICAgICAqIDwvb2w+CisgICAgICogPHA+CisgICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBJbiB0aGUgQW5kcm9pZCByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24sIHRoZQorICAgICAqIHtAY29kZSByZXNvbHZlfSBwYXJhbWV0ZXIgaXMgaWdub3JlZDsgY2xhc3NlcyBhcmUgbmV2ZXIgbGlua2VkLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBDbGFzc30gb2JqZWN0LgorICAgICAqIEBwYXJhbSBjbGFzc05hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyB0byBsb29rIGZvci4KKyAgICAgKiBAcGFyYW0gcmVzb2x2ZQorICAgICAqICAgICAgICAgICAgSW5kaWNhdGVzIGlmIHRoZSBjbGFzcyBzaG91bGQgYmUgcmVzb2x2ZWQgYWZ0ZXIgbG9hZGluZy4gVGhpcworICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyIGlzIGlnbm9yZWQgb24gdGhlIEFuZHJvaWQgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uOworICAgICAqICAgICAgICAgICAgY2xhc3NlcyBhcmUgbm90IHJlc29sdmVkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjbGFzcyBjYW4gbm90IGJlIGZvdW5kLgorICAgICAqLworICAgIHByb3RlY3RlZCBDbGFzczw/PiBsb2FkQ2xhc3MoU3RyaW5nIGNsYXNzTmFtZSwgYm9vbGVhbiByZXNvbHZlKSB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIENsYXNzPD8+IGNsYXp6ID0gZmluZExvYWRlZENsYXNzKGNsYXNzTmFtZSk7CisKKyAgICAgICAgaWYgKGNsYXp6ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2xhenogPSBwYXJlbnQubG9hZENsYXNzKGNsYXNzTmFtZSwgZmFsc2UpOworICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gRG9uJ3Qgd2FudCB0byBzZWUgdGhpcy4KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGNsYXp6ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjbGF6eiA9IGZpbmRDbGFzcyhjbGFzc05hbWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGNsYXp6OworICAgIH0KKworICAgIC8qKgorICAgICAqIEZvcmNlcyBhIGNsYXNzIHRvIGJlIGxpbmtlZCAoaW5pdGlhbGl6ZWQpLiBJZiB0aGUgY2xhc3MgaGFzIGFscmVhZHkgYmVlbgorICAgICAqIGxpbmtlZCB0aGlzIG9wZXJhdGlvbiBoYXMgbm8gZWZmZWN0LgorICAgICAqIDxwPgorICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gSW4gdGhlIEFuZHJvaWQgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uLCB0aGlzCisgICAgICogbWV0aG9kIGhhcyBubyBlZmZlY3QuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGNsYXp6CisgICAgICogICAgICAgICAgICB0aGUgY2xhc3MgdG8gbGluay4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCByZXNvbHZlQ2xhc3MoQ2xhc3M8Pz4gY2xhenopIHsKKyAgICAgICAgLy8gbm8tb3AsIGRvZXNuJ3QgbWFrZSBzZW5zZSBvbiBhbmRyb2lkLgorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIHRoZSBVUkwgb2YgdGhlIHJlc291cmNlIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLiBUaGlzCisgICAgICogaW1wbGVtZW50YXRpb24ganVzdCByZXR1cm5zIHtAY29kZSBudWxsfTsgaXQgc2hvdWxkIGJlIG92ZXJyaWRkZW4gaW4KKyAgICAgKiBzdWJjbGFzc2VzLgorICAgICAqCisgICAgICogQHBhcmFtIHJlc05hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSB0byBmaW5kLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBVUkx9IG9iamVjdCBmb3IgdGhlIHJlcXVlc3RlZCByZXNvdXJjZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgVVJMIGZpbmRSZXNvdXJjZShTdHJpbmcgcmVzTmFtZSkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kcyBhbiBlbnVtZXJhdGlvbiBvZiBVUkxzIGZvciB0aGUgcmVzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBqdXN0IHJldHVybnMgYW4gZW1wdHkge0Bjb2RlIEVudW1lcmF0aW9ufTsgaXQgc2hvdWxkCisgICAgICogYmUgb3ZlcnJpZGRlbiBpbiBzdWJjbGFzc2VzLgorICAgICAqCisgICAgICogQHBhcmFtIHJlc05hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSB0byBmaW5kLgorICAgICAqIEByZXR1cm4gYW4gZW51bWVyYXRpb24gb2Yge0Bjb2RlIFVSTH0gb2JqZWN0cyBmb3IgdGhlIHJlcXVlc3RlZCByZXNvdXJjZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncyggeworICAgICAgICAgICAgInVuY2hlY2tlZCIsICJ1bnVzZWQiCisgICAgfSkKKyAgICBwcm90ZWN0ZWQgRW51bWVyYXRpb248VVJMPiBmaW5kUmVzb3VyY2VzKFN0cmluZyByZXNOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW1wdHlFbnVtZXJhdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFic29sdXRlIHBhdGggb2YgdGhlIG5hdGl2ZSBsaWJyYXJ5IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLAorICAgICAqIG9yIHtAY29kZSBudWxsfS4gSWYgdGhpcyBtZXRob2QgcmV0dXJucyB7QGNvZGUgbnVsbH0gdGhlbiB0aGUgdmlydHVhbAorICAgICAqIG1hY2hpbmUgc2VhcmNoZXMgdGhlIGRpcmVjdG9yaWVzIHNwZWNpZmllZCBieSB0aGUgc3lzdGVtIHByb3BlcnR5CisgICAgICogImphdmEubGlicmFyeS5wYXRoIi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIGFsd2F5cyByZXR1cm5zIHtAY29kZSBudWxsfS4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbGliTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGxpYnJhcnkgdG8gZmluZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhYnNvbHV0ZSBwYXRoIG9mIHRoZSBsaWJyYXJ5LgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgZmluZExpYnJhcnkoU3RyaW5nIGxpYk5hbWUpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGFja2FnZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS4gUGFja2FnZSBpbmZvcm1hdGlvbiBpcworICAgICAqIHNlYXJjaGVkIGluIHRoaXMgY2xhc3MgbG9hZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBwYWNrYWdlIHRvIGZpbmQuCisgICAgICogQHJldHVybiB0aGUgcGFja2FnZSB3aXRoIHRoZSByZXF1ZXN0ZWQgbmFtZTsge0Bjb2RlIG51bGx9IGlmIHRoZSBwYWNrYWdlCisgICAgICogICAgICAgICBjYW4gbm90IGJlIGZvdW5kLgorICAgICAqLworICAgIHByb3RlY3RlZCBQYWNrYWdlIGdldFBhY2thZ2UoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChwYWNrYWdlcykgeworICAgICAgICAgICAgcmV0dXJuIHBhY2thZ2VzLmdldChuYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYWxsIHRoZSBwYWNrYWdlcyBrbm93biB0byB0aGlzIGNsYXNzIGxvYWRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgd2l0aCBhbGwgcGFja2FnZXMga25vd24gdG8gdGhpcyBjbGFzcyBsb2FkZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIFBhY2thZ2VbXSBnZXRQYWNrYWdlcygpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChwYWNrYWdlcykgeworICAgICAgICAgICAgQ29sbGVjdGlvbjxQYWNrYWdlPiBjb2wgPSBwYWNrYWdlcy52YWx1ZXMoKTsKKyAgICAgICAgICAgIFBhY2thZ2VbXSByZXN1bHQgPSBuZXcgUGFja2FnZVtjb2wuc2l6ZSgpXTsKKyAgICAgICAgICAgIGNvbC50b0FycmF5KHJlc3VsdCk7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVmaW5lcyBhbmQgcmV0dXJucyBhIG5ldyB7QGNvZGUgUGFja2FnZX0gdXNpbmcgdGhlIHNwZWNpZmllZAorICAgICAqIGluZm9ybWF0aW9uLiBJZiB7QGNvZGUgc2VhbEJhc2V9IGlzIHtAY29kZSBudWxsfSwgdGhlIHBhY2thZ2UgaXMgbGVmdAorICAgICAqIHVuc2VhbGVkLiBPdGhlcndpc2UsIHRoZSBwYWNrYWdlIGlzIHNlYWxlZCB1c2luZyB0aGlzIFVSTC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcGFja2FnZS4KKyAgICAgKiBAcGFyYW0gc3BlY1RpdGxlCisgICAgICogICAgICAgICAgICB0aGUgdGl0bGUgb2YgdGhlIHNwZWNpZmljYXRpb24uCisgICAgICogQHBhcmFtIHNwZWNWZXJzaW9uCisgICAgICogICAgICAgICAgICB0aGUgdmVyc2lvbiBvZiB0aGUgc3BlY2lmaWNhdGlvbi4KKyAgICAgKiBAcGFyYW0gc3BlY1ZlbmRvcgorICAgICAqICAgICAgICAgICAgdGhlIHZlbmRvciBvZiB0aGUgc3BlY2lmaWNhdGlvbi4KKyAgICAgKiBAcGFyYW0gaW1wbFRpdGxlCisgICAgICogICAgICAgICAgICB0aGUgaW1wbGVtZW50YXRpb24gdGl0bGUuCisgICAgICogQHBhcmFtIGltcGxWZXJzaW9uCisgICAgICogICAgICAgICAgICB0aGUgaW1wbGVtZW50YXRpb24gdmVyc2lvbi4KKyAgICAgKiBAcGFyYW0gaW1wbFZlbmRvcgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmljYXRpb24gdmVuZG9yLgorICAgICAqIEBwYXJhbSBzZWFsQmFzZQorICAgICAqICAgICAgICAgICAgdGhlIFVSTCB1c2VkIHRvIHNlYWwgdGhpcyBwYWNrYWdlIG9yIHtAY29kZSBudWxsfSB0byBsZWF2ZSB0aGUKKyAgICAgKiAgICAgICAgICAgIHBhY2thZ2UgdW5zZWFsZWQuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFBhY2thZ2V9IG9iamVjdCB0aGF0IGhhcyBiZWVuIGNyZWF0ZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHBhY2thZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgYWxyZWFkeSBleGlzdHMuCisgICAgICovCisgICAgcHJvdGVjdGVkIFBhY2thZ2UgZGVmaW5lUGFja2FnZShTdHJpbmcgbmFtZSwgU3RyaW5nIHNwZWNUaXRsZSwgU3RyaW5nIHNwZWNWZXJzaW9uLAorICAgICAgICAgICAgU3RyaW5nIHNwZWNWZW5kb3IsIFN0cmluZyBpbXBsVGl0bGUsIFN0cmluZyBpbXBsVmVyc2lvbiwgU3RyaW5nIGltcGxWZW5kb3IsIFVSTCBzZWFsQmFzZSkKKyAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworCisgICAgICAgIHN5bmNocm9uaXplZCAocGFja2FnZXMpIHsKKyAgICAgICAgICAgIGlmIChwYWNrYWdlcy5jb250YWluc0tleShuYW1lKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlBhY2thZ2UgIiArIG5hbWUgKyAiIGFscmVhZHkgZGVmaW5lZCIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBQYWNrYWdlIG5ld1BhY2thZ2UgPSBuZXcgUGFja2FnZShuYW1lLCBzcGVjVGl0bGUsIHNwZWNWZXJzaW9uLCBzcGVjVmVuZG9yLCBpbXBsVGl0bGUsCisgICAgICAgICAgICAgICAgICAgIGltcGxWZXJzaW9uLCBpbXBsVmVuZG9yLCBzZWFsQmFzZSk7CisKKyAgICAgICAgICAgIHBhY2thZ2VzLnB1dChuYW1lLCBuZXdQYWNrYWdlKTsKKworICAgICAgICAgICAgcmV0dXJuIG5ld1BhY2thZ2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzaWduZXJzIG9mIHRoZSBzcGVjaWZpZWQgY2xhc3MuIFRoaXMgaW1wbGVtZW50YXRpb24gZG9lcworICAgICAqIG5vdGhpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDbGFzc30gb2JqZWN0IGZvciB3aGljaCB0byBzZXQgdGhlIHNpZ25lcnMuCisgICAgICogQHBhcmFtIHNpZ25lcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaWduZXJzIGZvciB7QGNvZGUgY30uCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0U2lnbmVycyhDbGFzczw/PiBjLCBPYmplY3RbXSBzaWduZXJzKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgYXNzZXJ0aW9uIHN0YXR1cyBvZiB0aGUgY2xhc3Mgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuCisgICAgICogPHA+CisgICAgICogPHN0cm9uZz5Ob3RlOiA8L3N0cm9uZz5UaGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcgaW4gdGhlIEFuZHJvaWQgcmVmZXJlbmNlCisgICAgICogaW1wbGVtZW50YXRpb24uCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGNuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgZm9yIHdoaWNoIHRvIHNldCB0aGUgYXNzZXJ0aW9uIHN0YXR1cy4KKyAgICAgKiBAcGFyYW0gZW5hYmxlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IGFzc2VydGlvbiBzdGF0dXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q2xhc3NBc3NlcnRpb25TdGF0dXMoU3RyaW5nIGNuYW1lLCBib29sZWFuIGVuYWJsZSkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGFzc2VydGlvbiBzdGF0dXMgb2YgdGhlIHBhY2thZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuCisgICAgICogPHA+CisgICAgICogPHN0cm9uZz5Ob3RlOiA8L3N0cm9uZz5UaGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcgaW4gdGhlIEFuZHJvaWQgcmVmZXJlbmNlCisgICAgICogaW1wbGVtZW50YXRpb24uCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcGFja2FnZSBmb3Igd2hpY2ggdG8gc2V0IHRoZSBhc3NlcnRpb24gc3RhdHVzLgorICAgICAqIEBwYXJhbSBlbmFibGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgYXNzZXJ0aW9uIHN0YXR1cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQYWNrYWdlQXNzZXJ0aW9uU3RhdHVzKFN0cmluZyBwbmFtZSwgYm9vbGVhbiBlbmFibGUpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkZWZhdWx0IGFzc2VydGlvbiBzdGF0dXMgZm9yIHRoaXMgY2xhc3MgbG9hZGVyLgorICAgICAqIDxwPgorICAgICAqIDxzdHJvbmc+Tm90ZTogPC9zdHJvbmc+VGhpcyBtZXRob2QgZG9lcyBub3RoaW5nIGluIHRoZSBBbmRyb2lkIHJlZmVyZW5jZQorICAgICAqIGltcGxlbWVudGF0aW9uLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbmFibGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgYXNzZXJ0aW9uIHN0YXR1cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREZWZhdWx0QXNzZXJ0aW9uU3RhdHVzKGJvb2xlYW4gZW5hYmxlKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGVmYXVsdCBhc3NlcnRpb24gc3RhdHVzIGZvciB0aGlzIGNsYXNzIGxvYWRlciB0byB7QGNvZGUgZmFsc2V9CisgICAgICogYW5kIHJlbW92ZXMgYW55IHBhY2thZ2UgZGVmYXVsdCBhbmQgY2xhc3MgYXNzZXJ0aW9uIHN0YXR1cyBzZXR0aW5ncy4KKyAgICAgKiA8cD4KKyAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGRvZXMgbm90aGluZyBpbiB0aGUgQW5kcm9pZCByZWZlcmVuY2UKKyAgICAgKiBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKiA8L3A+CisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXJBc3NlcnRpb25TdGF0dXMoKSB7CisgICAgfQorfQorCisvKgorICogUHJvdmlkZXMgYSBoZWxwZXIgY2xhc3MgdGhhdCBjb21iaW5lcyB0d28gZXhpc3RpbmcgVVJMIGVudW1lcmF0aW9ucyBpbnRvIG9uZS4KKyAqIEl0IGlzIHJlcXVpcmVkIGZvciB0aGUgZ2V0UmVzb3VyY2VzKCkgbWV0aG9kcy4gSXRlbXMgYXJlIGZldGNoZWQgZnJvbSB0aGUKKyAqIGZpcnN0IGVudW1lcmF0aW9uIHVudGlsIGl0J3MgZW1wdHksIHRoZW4gZnJvbSB0aGUgc2Vjb25kIG9uZS4KKyAqLworY2xhc3MgVHdvRW51bWVyYXRpb25zSW5PbmUgaW1wbGVtZW50cyBFbnVtZXJhdGlvbjxVUkw+IHsKKworICAgIHByaXZhdGUgRW51bWVyYXRpb248VVJMPiBmaXJzdDsKKworICAgIHByaXZhdGUgRW51bWVyYXRpb248VVJMPiBzZWNvbmQ7CisKKyAgICBwdWJsaWMgVHdvRW51bWVyYXRpb25zSW5PbmUoRW51bWVyYXRpb248VVJMPiBmaXJzdCwgRW51bWVyYXRpb248VVJMPiBzZWNvbmQpIHsKKyAgICAgICAgdGhpcy5maXJzdCA9IGZpcnN0OworICAgICAgICB0aGlzLnNlY29uZCA9IHNlY29uZDsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNNb3JlRWxlbWVudHMoKSB7CisgICAgICAgIHJldHVybiBmaXJzdC5oYXNNb3JlRWxlbWVudHMoKSB8fCBzZWNvbmQuaGFzTW9yZUVsZW1lbnRzKCk7CisgICAgfQorCisgICAgcHVibGljIFVSTCBuZXh0RWxlbWVudCgpIHsKKyAgICAgICAgaWYgKGZpcnN0Lmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICByZXR1cm4gZmlyc3QubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBzZWNvbmQubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgfQorICAgIH0KKworfQorCisvKioKKyAqIFByb3ZpZGVzIGFuIGV4cGxpY2l0IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBib290IGNsYXNzIGxvYWRlci4gSXQgc2l0cyBhdCB0aGUKKyAqIGhlYWQgb2YgdGhlIGNsYXNzIGxvYWRlciBjaGFpbiBhbmQgZGVsZWdhdGVzIHJlcXVlc3RzIHRvIHRoZSBWTSdzIGludGVybmFsCisgKiBjbGFzcyBsb2FkaW5nIG1lY2hhbmlzbS4KKyAqLworY2xhc3MgQm9vdENsYXNzTG9hZGVyIGV4dGVuZHMgQ2xhc3NMb2FkZXIgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgQm9vdENsYXNzTG9hZGVyIGluc3RhbmNlOworCisgICAgQEZpbmRCdWdzU3VwcHJlc3NXYXJuaW5ncygiRFBfQ1JFQVRFX0NMQVNTTE9BREVSX0lOU0lERV9ET19QUklWSUxFR0VEIikKKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBCb290Q2xhc3NMb2FkZXIgZ2V0SW5zdGFuY2UoKSB7CisgICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKSB7CisgICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBCb290Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBpbnN0YW5jZTsKKyAgICB9CisKKyAgICBwdWJsaWMgQm9vdENsYXNzTG9hZGVyKCkgeworICAgICAgICBzdXBlcihudWxsLCB0cnVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgQ2xhc3M8Pz4gZmluZENsYXNzKFN0cmluZyBuYW1lKSB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBWTUNsYXNzTG9hZGVyLmxvYWRDbGFzcyhuYW1lLCBmYWxzZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIFVSTCBmaW5kUmVzb3VyY2UoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIFZNQ2xhc3NMb2FkZXIuZ2V0UmVzb3VyY2UobmFtZSk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIEVudW1lcmF0aW9uPFVSTD4gZmluZFJlc291cmNlcyhTdHJpbmcgcmVzTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVudW1lcmF0aW9uKFZNQ2xhc3NMb2FkZXIuZ2V0UmVzb3VyY2VzKHJlc05hbWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHBhY2thZ2UgaW5mb3JtYXRpb24gZm9yIHRoZSBnaXZlbiBwYWNrYWdlLiBVbmZvcnR1bmF0ZWx5LCB0aGUKKyAgICAgKiBBbmRyb2lkIEJvb3RDbGFzc0xvYWRlciBkb2Vzbid0IHJlYWxseSBoYXZlIHRoaXMgaW5mb3JtYXRpb24sIGFuZCBhcyBhCisgICAgICogbm9uLXNlY3VyZSBDbGFzc0xvYWRlciwgaXQgaXNuJ3QgZXZlbiByZXF1aXJlZCB0bywgYWNjb3JkaW5nIHRvIHRoZSBzcGVjLgorICAgICAqIFlldCwgd2Ugd2FudCB0byBwcm92aWRlIGl0LCBpbiBvcmRlciB0byBtYWtlIGFsbCB0aG9zZSBob3BlZnVsIGNhbGxlcnMgb2YKKyAgICAgKiB7QGNvZGUgbXlDbGFzcy5nZXRQYWNrYWdlKCkuZ2V0TmFtZSgpfSBoYXBweS4gVGh1cyB3ZSBjb25zdHJ1Y3QgYSBQYWNrYWdlCisgICAgICogb2JqZWN0IHRoZSBmaXJzdCB0aW1lIGl0IGlzIGJlaW5nIHJlcXVlc3RlZCBhbmQgZmlsbCBtb3N0IG9mIHRoZSBmaWVsZHMKKyAgICAgKiB3aXRoIGR1bW15IHZhbHVlcy4gVGhlIFBhY2thZ2Ugb2JqZWN0IGlzIHRoZW4gcHV0IGludG8gdGhlIENsYXNzTG9hZGVyJ3MKKyAgICAgKiBQYWNrYWdlIGNhY2hlLCBzbyB3ZSBzZWUgdGhlIHNhbWUgb25lIG5leHQgdGltZS4gV2UgZG9uJ3QgY3JlYXRlIFBhY2thZ2UKKyAgICAgKiBvYmplY3RzIGZvciBudWxsIGFyZ3VtZW50cyBvciBmb3IgdGhlIGRlZmF1bHQgcGFja2FnZS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGVyZSBhIGxpbWl0ZWQgY2hhbmNlIHRoYXQgd2UgZW5kIHVwIHdpdGggbXVsdGlwbGUgUGFja2FnZSBvYmplY3RzCisgICAgICogcmVwcmVzZW50aW5nIHRoZSBzYW1lIHBhY2thZ2U6IEl0IGNhbiBoYXBwZW4gd2hlbiB3aGVuIGEgcGFja2FnZSBpcworICAgICAqIHNjYXR0ZXJlZCBhY3Jvc3MgZGlmZmVyZW50IEpBUiBmaWxlcyBiZWluZyBsb2FkZWQgYnkgZGlmZmVyZW50CisgICAgICogQ2xhc3NMb2FkZXJzLiBSYXRoZXIgdW5saWtlbHksIGFuZCBnaXZlbiB0aGF0IHRoaXMgd2hvbGUgdGhpbmcgaXMgbW9yZSBvcgorICAgICAqIGxlc3MgYSB3b3JrYXJvdW5kLCBwcm9iYWJseSBub3Qgd29ydGggdGhlIGVmZm9ydC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgUGFja2FnZSBnZXRQYWNrYWdlKFN0cmluZyBuYW1lKSB7CisgICAgICAgIGlmIChuYW1lICE9IG51bGwgJiYgIW5hbWUuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgICAgICBQYWNrYWdlIHBhY2sgPSBzdXBlci5nZXRQYWNrYWdlKG5hbWUpOworCisgICAgICAgICAgICAgICAgaWYgKHBhY2sgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBwYWNrID0gZGVmaW5lUGFja2FnZShuYW1lLCAiVW5rbm93biIsICIwLjAiLCAiVW5rbm93biIsICJVbmtub3duIiwgIjAuMCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVua25vd24iLCBudWxsKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICByZXR1cm4gcGFjazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBVUkwgZ2V0UmVzb3VyY2UoU3RyaW5nIHJlc05hbWUpIHsKKyAgICAgICAgcmV0dXJuIGZpbmRSZXNvdXJjZShyZXNOYW1lKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgQ2xhc3M8Pz4gbG9hZENsYXNzKFN0cmluZyBjbGFzc05hbWUsIGJvb2xlYW4gcmVzb2x2ZSkKKyAgICAgICAgICAgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBDbGFzczw/PiBjbGF6eiA9IGZpbmRMb2FkZWRDbGFzcyhjbGFzc05hbWUpOworCisgICAgICAgIGlmIChjbGF6eiA9PSBudWxsKSB7CisgICAgICAgICAgICBjbGF6eiA9IGZpbmRDbGFzcyhjbGFzc05hbWUpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGNsYXp6OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxVUkw+IGdldFJlc291cmNlcyhTdHJpbmcgcmVzTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGZpbmRSZXNvdXJjZXMocmVzTmFtZSk7CisgICAgfQorfQorCisvKioKKyAqIFRPRE8gT3BlbiBpc3N1ZXMgLSBNaXNzaW5nIC8gZW1wdHkgbWV0aG9kcyAtIFNpZ25lciBzdHVmZiAtIFByb3RlY3Rpb24KKyAqIGRvbWFpbnMgLSBBc3NlcnRpb25zCisgKi8KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmFjM2I0OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIFRocm93biB3aGVuIGEgY2xhc3MgbG9hZGVyIGlzIHVuYWJsZSB0byBmaW5kIGEgY2xhc3MuCisgKi8KK3B1YmxpYyBjbGFzcyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDkxNzY4NzMwMjk3NDUyNTQ1NDJMOworCisgICAgcHJpdmF0ZSBUaHJvd2FibGUgZXg7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBDbGFzc05vdEZvdW5kRXhjZXB0aW9ufSB0aGF0IGluY2x1ZGVzIHRoZSBjdXJyZW50CisgICAgICogc3RhY2sgdHJhY2UuCisgICAgICovCisgICAgcHVibGljIENsYXNzTm90Rm91bmRFeGNlcHRpb24oKSB7CisgICAgICAgIHN1cGVyKChUaHJvd2FibGUpIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIENsYXNzTm90Rm91bmRFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQgc3RhY2sKKyAgICAgKiB0cmFjZSBhbmQgdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIENsYXNzTm90Rm91bmRFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQgc3RhY2sKKyAgICAgKiB0cmFjZSwgdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZSBhbmQgdGhlIGV4Y2VwdGlvbiB0aGF0IG9jY3VycmVkIHdoZW4KKyAgICAgKiBsb2FkaW5nIHRoZSBjbGFzcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBleGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNlcHRpb24gd2hpY2ggb2NjdXJyZWQgd2hpbGUgbG9hZGluZyB0aGUgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIENsYXNzTm90Rm91bmRFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UsIFRocm93YWJsZSBleGNlcHRpb24pIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgICAgIGV4ID0gZXhjZXB0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGV4Y2VwdGlvbiB3aGljaCBvY2N1cnJlZCB3aGVuIGxvYWRpbmcgdGhlIGNsYXNzLgorICAgICAqCisgICAgICogQHJldHVybiBUaHJvd2FibGUgdGhlIGV4Y2VwdGlvbiB3aGljaCBvY2N1cnJlZCB3aGlsZSBsb2FkaW5nIHRoZSBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGhyb3dhYmxlIGdldEV4Y2VwdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIGV4OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNhdXNlIG9mIHRoaXMgVGhyb3dhYmxlLCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgaXMgbm8KKyAgICAgKiBjYXVzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhyb3dhYmxlIHRoZSByZWNlaXZlcidzIGNhdXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBUaHJvd2FibGUgZ2V0Q2F1c2UoKSB7CisgICAgICAgIHJldHVybiBleDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0Nsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0Nsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGE3OGI3YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQ3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gd2hlbiBhIHByb2dyYW0gYXR0ZW1wdHMgdG8gY2xvbmUgYW4gb2JqZWN0IHdoaWNoIGRvZXMgbm90IHN1cHBvcnQgdGhlCisgKiB7QGxpbmsgQ2xvbmVhYmxlfSBpbnRlcmZhY2UuCisgKgorICogQHNlZSBDbG9uZWFibGUKKyAqLworcHVibGljIGNsYXNzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDUxOTU1MTEyNTAwNzk2NTY0NDNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb259IHRoYXQgaW5jbHVkZXMgdGhlCisgICAgICogY3VycmVudCBzdGFjayB0cmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQKKyAgICAgKiBzdGFjayB0cmFjZSBhbmQgdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0Nsb25lYWJsZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9DbG9uZWFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMzgxN2FlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9DbG9uZWFibGUuamF2YQpAQCAtMCwwICsxLDMyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworCisvKioKKyAqIFRoaXMgKGVtcHR5KSBpbnRlcmZhY2UgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBhbGwgY2xhc3NlcyB0aGF0IHdpc2ggdG8KKyAqIHN1cHBvcnQgY2xvbmluZy4gVGhlIGltcGxlbWVudGF0aW9uIG9mIHtAY29kZSBjbG9uZSgpfSBpbiB7QGNvZGUgT2JqZWN0fQorICogY2hlY2tzIGlmIHRoZSBvYmplY3QgYmVpbmcgY2xvbmVkIGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UgYW5kIHRocm93cworICoge0Bjb2RlIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9ufSBpZiBpdCBkb2VzIG5vdC4KKyAqCisgKiBAc2VlIE9iamVjdCNjbG9uZQorICogQHNlZSBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgorICovCitwdWJsaWMgaW50ZXJmYWNlIENsb25lYWJsZSB7CisgICAgLy8gTWFya2VyIGludGVyZmFjZQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Db21wYXJhYmxlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0NvbXBhcmFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZjEwNDE2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Db21wYXJhYmxlLmphdmEKQEAgLTAsMCArMSw1MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhpcyBpbnRlcmZhY2Ugc2hvdWxkIGJlIGltcGxlbWVudGVkIGJ5IGFsbCBjbGFzc2VzIHRoYXQgd2lzaCB0byBkZWZpbmUgYQorICogPGVtPm5hdHVyYWwgb3JkZXI8L2VtPiBvZiB0aGVpciBpbnN0YW5jZXMuCisgKiB7QGxpbmsgamF2YS51dGlsLkNvbGxlY3Rpb25zI3NvcnR9IGFuZCB7QGNvZGUgamF2YS51dGlsLkFycmF5cyNzb3J0fSBjYW4gdGhlbgorICogYmUgdXNlZCB0byBhdXRvbWF0aWNhbGx5IHNvcnQgbGlzdHMgb2YgY2xhc3NlcyB0aGF0IGltcGxlbWVudCB0aGlzIGludGVyZmFjZS4KKyAqIDxwPgorICogVGhlIG9yZGVyIHJ1bGUgbXVzdCBiZSBib3RoIHRyYW5zaXRpdmUgKGlmIHtAY29kZSB4LmNvbXBhcmVUbyh5KSA8IDB9IGFuZAorICoge0Bjb2RlIHkuY29tcGFyZVRvKHopIDwgMH0sIHRoZW4ge0Bjb2RlIHguY29tcGFyZVRvKHopIDwgMH0gbXVzdCBob2xkKSBhbmQKKyAqIGludmVydGlibGUgKHRoZSBzaWduIG9mIHRoZSByZXN1bHQgb2YgeC5jb21wYXJlVG8oeSkgbXVzdCBiZSBlcXVhbCB0byB0aGUKKyAqIG5lZ2F0aW9uIG9mIHRoZSBzaWduIG9mIHRoZSByZXN1bHQgb2YgeS5jb21wYXJlVG8oeCkgZm9yIGFsbCBjb21iaW5hdGlvbnMgb2YKKyAqIHggYW5kIHkpLgorICogPHA+CisgKiBJbiBhZGRpdGlvbiwgaXQgaXMgcmVjb21tZW5kZWQgKGJ1dCBub3QgcmVxdWlyZWQpIHRoYXQgaWYgYW5kIG9ubHkgaWYgdGhlCisgKiByZXN1bHQgb2YgeC5jb21wYXJlVG8oeSkgaXMgemVybywgdGhlbiB0aGUgcmVzdWx0IG9mIHguZXF1YWxzKHkpIHNob3VsZCBiZQorICoge0Bjb2RlIHRydWV9LgorICovCitwdWJsaWMgaW50ZXJmYWNlIENvbXBhcmFibGU8VD4geworCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBvYmplY3QgdG8gdGhlIHNwZWNpZmllZCBvYmplY3QgdG8gZGV0ZXJtaW5lIHRoZWlyIHJlbGF0aXZlCisgICAgICogb3JkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYW5vdGhlcgorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHRvIHRoaXMgaW5zdGFuY2UuCisgICAgICogQHJldHVybiBhIG5lZ2F0aXZlIGludGVnZXIgaWYgdGhpcyBpbnN0YW5jZSBpcyBsZXNzIHRoYW4ge0Bjb2RlIGFub3RoZXJ9OworICAgICAqICAgICAgICAgYSBwb3NpdGl2ZSBpbnRlZ2VyIGlmIHRoaXMgaW5zdGFuY2UgaXMgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgICB7QGNvZGUgYW5vdGhlcn07IDAgaWYgdGhpcyBpbnN0YW5jZSBoYXMgdGhlIHNhbWUgb3JkZXIgYXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBhbm90aGVyfS4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhbm90aGVyfSBjYW5ub3QgYmUgY29udmVydGVkIGludG8gc29tZXRoaW5nCisgICAgICogICAgICAgICAgICAgY29tcGFyYWJsZSB0byB7QGNvZGUgdGhpc30gaW5zdGFuY2UuCisgICAgICovCisgICAgaW50IGNvbXBhcmVUbyhUIGFub3RoZXIpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Db21waWxlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Db21waWxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU5YjNkZWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0NvbXBpbGVyLmphdmEKQEAgLTAsMCArMSw4NiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIERvZXMgbm90aGluZyBvbiBBbmRyb2lkLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQ29tcGlsZXIgeworICAgIC8qKgorICAgICAqIFByZXZlbnQgdGhpcyBjbGFzcyBmcm9tIGJlaW5nIGluc3RhbnRpYXRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIENvbXBpbGVyKCkgeworICAgICAgICAvL2RvIG5vdGhpbmcKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeGVjdXRlcyBhbiBvcGVyYXRpb24gYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgY29tbWFuZCBvYmplY3QuIFRoaXMKKyAgICAgKiBtZXRob2QgaXMgdGhlIGxvdy1sZXZlbCBpbnRlcmZhY2UgdG8gdGhlIEpJVCBjb21waWxlci4gSXQgbWF5IHJldHVybiBhbnkKKyAgICAgKiBvYmplY3Qgb3Ige0Bjb2RlIG51bGx9IGlmIG5vIEpJVCBjb21waWxlciBpcyBhdmFpbGFibGUuIFJldHVybnMgbnVsbAorICAgICAqIG9uIEFuZHJvaWQsIHdoZXRoZXIgb3Igbm90IHRoZSBzeXN0ZW0gaGFzIGEgSklULgorICAgICAqCisgICAgICogQHBhcmFtIGNtZAorICAgICAqICAgICAgICAgICAgdGhlIGNvbW1hbmQgb2JqZWN0IGZvciB0aGUgSklUIGNvbXBpbGVyLgorICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBleGVjdXRpbmcgY29tbWFuZCBvciB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBPYmplY3QgY29tbWFuZChPYmplY3QgY21kKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBpbGVzIHRoZSBzcGVjaWZpZWQgY2xhc3MgdXNpbmcgdGhlIEpJVCBjb21waWxlciBhbmQgaW5kaWNhdGVzIGlmCisgICAgICogY29tcGlsYXRpb24gaGFzIGJlZW4gc3VjY2Vzc2Z1bC4gRG9lcyBub3RoaW5nIGFuZCByZXR1cm5zIGZhbHNlIG9uCisgICAgICogQW5kcm9pZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbGFzc1RvQ29tcGlsZQorICAgICAqICAgICAgICAgICAgamF2YS5sYW5nLkNsYXNzIHRoZSBjbGFzcyB0byBKSVQgY29tcGlsZQorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBjb21waWxhdGlvbiBoYXMgYmVlbiBzdWNjZXNzZnVsOworICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBpZiBpdCBoYXMgZmFpbGVkIG9yIGlmIHRoZXJlIGlzIG5vIEpJVCBjb21waWxlcgorICAgICAqICAgICAgICAgYXZhaWxhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBjb21waWxlQ2xhc3MoQ2xhc3M8Pz4gY2xhc3NUb0NvbXBpbGUpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBpbGVzIGFsbCBjbGFzc2VzIHdob3NlIG5hbWUgbWF0Y2hlcyB0aGUgc3BlY2lmaWVkIG5hbWUgdXNpbmcgdGhlIEpJVAorICAgICAqIGNvbXBpbGVyIGFuZCBpbmRpY2F0ZXMgaWYgY29tcGlsYXRpb24gaGFzIGJlZW4gc3VjY2Vzc2Z1bC4gRG9lcyBub3RoaW5nCisgICAgICogYW5kIHJldHVybnMgZmFsc2Ugb24gQW5kcm9pZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lUm9vdAorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBtYXRjaCBjbGFzcyBuYW1lcyB3aXRoLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBjb21waWxhdGlvbiBoYXMgYmVlbiBzdWNjZXNzZnVsOworICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBpZiBpdCBoYXMgZmFpbGVkIG9yIGlmIHRoZXJlIGlzIG5vIEpJVCBjb21waWxlcgorICAgICAqICAgICAgICAgYXZhaWxhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBjb21waWxlQ2xhc3NlcyhTdHJpbmcgbmFtZVJvb3QpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIERpc2FibGVzIHRoZSBKSVQgY29tcGlsZXIuIERvZXMgbm90aGluZyBvbiBBbmRyb2lkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBkaXNhYmxlKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuYWJsZXMgdGhlIEpJVCBjb21waWxlci4gRG9lcyBub3RoaW5nIG9uIEFuZHJvaWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGVuYWJsZSgpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0RhZW1vbnMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvRGFlbW9ucy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg4ZDRkOTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0RhZW1vbnMuamF2YQpAQCAtMCwwICsxLDIzNiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgZGFsdmlrLnN5c3RlbS5WTVJ1bnRpbWU7CitpbXBvcnQgamF2YS5sYW5nLnJlZi5GaW5hbGl6ZXJSZWZlcmVuY2U7CitpbXBvcnQgamF2YS5sYW5nLnJlZi5SZWZlcmVuY2U7CitpbXBvcnQgamF2YS5sYW5nLnJlZi5SZWZlcmVuY2VRdWV1ZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lb3V0RXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUudXRpbC5FbXB0eUFycmF5OworCisvKioKKyAqIENhbGxzIE9iamVjdC5maW5hbGl6ZSgpIG9uIG9iamVjdHMgaW4gdGhlIGZpbmFsaXplciByZWZlcmVuY2UgcXVldWUuIFRoZSBWTQorICogd2lsbCBhYm9ydCBpZiBhbnkgZmluYWxpemUoKSBjYWxsIHRha2VzIG1vcmUgdGhhbiB0aGUgbWF4aW11bSBmaW5hbGl6ZSB0aW1lCisgKiB0byBjb21wbGV0ZS4KKyAqCisgKiBAaGlkZQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRGFlbW9ucyB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5BTk9TX1BFUl9NSUxMSSA9IDEwMDAwMDA7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBNQVhfRklOQUxJWkVfTUlMTElTID0gMTBMICogMTAwMEw7IC8vIDEwIHNlY29uZHMKKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzdGFydCgpIHsKKyAgICAgICAgUmVmZXJlbmNlUXVldWVEYWVtb24uSU5TVEFOQ0Uuc3RhcnQoKTsKKyAgICAgICAgRmluYWxpemVyRGFlbW9uLklOU1RBTkNFLnN0YXJ0KCk7CisgICAgICAgIEZpbmFsaXplcldhdGNoZG9nRGFlbW9uLklOU1RBTkNFLnN0YXJ0KCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHN0b3AoKSB7CisgICAgICAgIFJlZmVyZW5jZVF1ZXVlRGFlbW9uLklOU1RBTkNFLnN0b3AoKTsKKyAgICAgICAgRmluYWxpemVyRGFlbW9uLklOU1RBTkNFLnN0b3AoKTsKKyAgICAgICAgRmluYWxpemVyV2F0Y2hkb2dEYWVtb24uSU5TVEFOQ0Uuc3RvcCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgYmFja2dyb3VuZCB0YXNrIHRoYXQgcHJvdmlkZXMgcnVudGltZSBzdXBwb3J0IHRvIHRoZSBhcHBsaWNhdGlvbi4KKyAgICAgKiBEYWVtb25zIGNhbiBiZSBzdG9wcGVkIGFuZCBzdGFydGVkLCBidXQgb25seSBzbyB0aGF0IHRoZSB6eWdvdGUgY2FuIGJlIGEKKyAgICAgKiBzaW5nbGUtdGhyZWFkZWQgcHJvY2VzcyB3aGVuIGl0IGZvcmtzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGFic3RyYWN0IGNsYXNzIERhZW1vbiBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBUaHJlYWQgdGhyZWFkOworCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzdGFydCgpIHsKKyAgICAgICAgICAgIGlmICh0aHJlYWQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oImFscmVhZHkgcnVubmluZyIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyZWFkID0gbmV3IFRocmVhZCh0aGlzLCBnZXRDbGFzcygpLmdldFNpbXBsZU5hbWUoKSk7CisgICAgICAgICAgICB0aHJlYWQuc2V0RGFlbW9uKHRydWUpOworICAgICAgICAgICAgdGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBydW4oKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0cnVlIHdoaWxlIHRoZSBjdXJyZW50IHRocmVhZCBzaG91bGQgY29udGludWUgdG8gcnVuOyBmYWxzZQorICAgICAgICAgKiB3aGVuIGl0IHNob3VsZCByZXR1cm4uCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIGJvb2xlYW4gaXNSdW5uaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuIHRocmVhZCAhPSBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGludGVycnVwdCgpIHsKKyAgICAgICAgICAgIGlmICh0aHJlYWQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIm5vdCBydW5uaW5nIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aHJlYWQuaW50ZXJydXB0KCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogV2FpdHMgZm9yIHRoZSBydW50aW1lIHRocmVhZCB0byBzdG9wLiBUaGlzIGludGVycnVwdHMgdGhlIHRocmVhZAorICAgICAgICAgKiBjdXJyZW50bHkgcnVubmluZyB0aGUgcnVubmFibGUgYW5kIHRoZW4gd2FpdHMgZm9yIGl0IHRvIGV4aXQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCBzdG9wKCkgeworICAgICAgICAgICAgVGhyZWFkIHRocmVhZFRvU3RvcDsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgICAgIHRocmVhZFRvU3RvcCA9IHRocmVhZDsKKyAgICAgICAgICAgICAgICB0aHJlYWQgPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHRocmVhZFRvU3RvcCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigibm90IHJ1bm5pbmciKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocmVhZFRvU3RvcC5pbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgdGhyZWFkVG9TdG9wLmpvaW4oKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgY3VycmVudCBzdGFjayB0cmFjZSBvZiB0aGUgdGhyZWFkLCBvciBhbiBlbXB0eSBzdGFjayB0cmFjZQorICAgICAgICAgKiBpZiB0aGUgdGhyZWFkIGlzIG5vdCBjdXJyZW50bHkgcnVubmluZy4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RhY2tUcmFjZUVsZW1lbnRbXSBnZXRTdGFja1RyYWNlKCkgeworICAgICAgICAgICAgcmV0dXJuIHRocmVhZCAhPSBudWxsID8gdGhyZWFkLmdldFN0YWNrVHJhY2UoKSA6IEVtcHR5QXJyYXkuU1RBQ0tfVFJBQ0VfRUxFTUVOVDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgaGVhcCBtYW5hZ2VtZW50IHRocmVhZCBtb3ZlcyBlbGVtZW50cyBmcm9tIHRoZSBnYXJiYWdlIGNvbGxlY3RvcidzCisgICAgICogcGVuZGluZyBsaXN0IHRvIHRoZSBtYW5hZ2VkIHJlZmVyZW5jZSBxdWV1ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBSZWZlcmVuY2VRdWV1ZURhZW1vbiBleHRlbmRzIERhZW1vbiB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFJlZmVyZW5jZVF1ZXVlRGFlbW9uIElOU1RBTkNFID0gbmV3IFJlZmVyZW5jZVF1ZXVlRGFlbW9uKCk7CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIHdoaWxlIChpc1J1bm5pbmcoKSkgeworICAgICAgICAgICAgICAgIFJlZmVyZW5jZTw/PiBsaXN0OworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoUmVmZXJlbmNlUXVldWUuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChSZWZlcmVuY2VRdWV1ZS51bmVucXVldWVkID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWZlcmVuY2VRdWV1ZS5jbGFzcy53YWl0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ID0gUmVmZXJlbmNlUXVldWUudW5lbnF1ZXVlZDsKKyAgICAgICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZVF1ZXVlLnVuZW5xdWV1ZWQgPSBudWxsOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZW5xdWV1ZShsaXN0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCBlbnF1ZXVlKFJlZmVyZW5jZTw/PiBsaXN0KSB7CisgICAgICAgICAgICB3aGlsZSAobGlzdCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgUmVmZXJlbmNlPD8+IHJlZmVyZW5jZTsKKyAgICAgICAgICAgICAgICAvLyBwZW5kaW5nTmV4dCBpcyBvd25lZCBieSB0aGUgR0Mgc28gbm8gc3luY2hyb25pemF0aW9uIGlzIHJlcXVpcmVkCisgICAgICAgICAgICAgICAgaWYgKGxpc3QgPT0gbGlzdC5wZW5kaW5nTmV4dCkgeworICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2UgPSBsaXN0OworICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2UucGVuZGluZ05leHQgPSBudWxsOworICAgICAgICAgICAgICAgICAgICBsaXN0ID0gbnVsbDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2UgPSBsaXN0LnBlbmRpbmdOZXh0OworICAgICAgICAgICAgICAgICAgICBsaXN0LnBlbmRpbmdOZXh0ID0gcmVmZXJlbmNlLnBlbmRpbmdOZXh0OworICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2UucGVuZGluZ05leHQgPSBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZWZlcmVuY2UuZW5xdWV1ZUludGVybmFsKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBGaW5hbGl6ZXJEYWVtb24gZXh0ZW5kcyBEYWVtb24geworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaW5hbGl6ZXJEYWVtb24gSU5TVEFOQ0UgPSBuZXcgRmluYWxpemVyRGFlbW9uKCk7CisgICAgICAgIHByaXZhdGUgZmluYWwgUmVmZXJlbmNlUXVldWU8T2JqZWN0PiBxdWV1ZSA9IEZpbmFsaXplclJlZmVyZW5jZS5xdWV1ZTsKKyAgICAgICAgcHJpdmF0ZSB2b2xhdGlsZSBPYmplY3QgZmluYWxpemluZ09iamVjdDsKKyAgICAgICAgcHJpdmF0ZSB2b2xhdGlsZSBsb25nIGZpbmFsaXppbmdTdGFydGVkTmFub3M7CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIHdoaWxlIChpc1J1bm5pbmcoKSkgeworICAgICAgICAgICAgICAgIC8vIFRha2UgYSByZWZlcmVuY2UsIGJsb2NraW5nIHVudGlsIG9uZSBpcyByZWFkeSBvciB0aGUgdGhyZWFkIHNob3VsZCBzdG9wCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZG9GaW5hbGl6ZSgoRmluYWxpemVyUmVmZXJlbmNlPD8+KSBxdWV1ZS5yZW1vdmUoKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBGaW5kQnVnc1N1cHByZXNzV2FybmluZ3MoIkZJX0VYUExJQ0lUX0lOVk9DQVRJT04iKQorICAgICAgICBwcml2YXRlIHZvaWQgZG9GaW5hbGl6ZShGaW5hbGl6ZXJSZWZlcmVuY2U8Pz4gcmVmZXJlbmNlKSB7CisgICAgICAgICAgICBGaW5hbGl6ZXJSZWZlcmVuY2UucmVtb3ZlKHJlZmVyZW5jZSk7CisgICAgICAgICAgICBPYmplY3Qgb2JqZWN0ID0gcmVmZXJlbmNlLmdldCgpOworICAgICAgICAgICAgcmVmZXJlbmNlLmNsZWFyKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZpbmFsaXppbmdTdGFydGVkTmFub3MgPSBTeXN0ZW0ubmFub1RpbWUoKTsKKyAgICAgICAgICAgICAgICBmaW5hbGl6aW5nT2JqZWN0ID0gb2JqZWN0OworICAgICAgICAgICAgICAgIG9iamVjdC5maW5hbGl6ZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGV4KSB7CisgICAgICAgICAgICAgICAgLy8gVGhlIFJJIHNpbGVudGx5IHN3YWxsb3dzIHRoZXNlLCBidXQgQW5kcm9pZCBoYXMgYWx3YXlzIGxvZ2dlZC4KKyAgICAgICAgICAgICAgICBTeXN0ZW0ubG9nRSgiVW5jYXVnaHQgZXhjZXB0aW9uIHRocm93biBieSBmaW5hbGl6ZXIiLCBleCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGZpbmFsaXppbmdPYmplY3QgPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIHdhdGNoZG9nIGV4aXRzIHRoZSBWTSBpZiB0aGUgZmluYWxpemVyIGV2ZXIgZ2V0cyBzdHVjay4gV2UgY29uc2lkZXIKKyAgICAgKiB0aGUgZmluYWxpemVyIHRvIGJlIHN0dWNrIGlmIGl0IHNwZW5kcyBtb3JlIHRoYW4gTUFYX0ZJTkFMSVpBVElPTl9NSUxMSVMKKyAgICAgKiBvbiBvbmUgaW5zdGFuY2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgRmluYWxpemVyV2F0Y2hkb2dEYWVtb24gZXh0ZW5kcyBEYWVtb24geworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaW5hbGl6ZXJXYXRjaGRvZ0RhZW1vbiBJTlNUQU5DRSA9IG5ldyBGaW5hbGl6ZXJXYXRjaGRvZ0RhZW1vbigpOworCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICB3aGlsZSAoaXNSdW5uaW5nKCkpIHsKKyAgICAgICAgICAgICAgICBPYmplY3Qgb2JqZWN0ID0gRmluYWxpemVyRGFlbW9uLklOU1RBTkNFLmZpbmFsaXppbmdPYmplY3Q7CisgICAgICAgICAgICAgICAgbG9uZyBzdGFydGVkTmFub3MgPSBGaW5hbGl6ZXJEYWVtb24uSU5TVEFOQ0UuZmluYWxpemluZ1N0YXJ0ZWROYW5vczsKKworICAgICAgICAgICAgICAgIGxvbmcgc2xlZXBNaWxsaXMgPSBNQVhfRklOQUxJWkVfTUlMTElTOworICAgICAgICAgICAgICAgIGlmIChvYmplY3QgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBsb25nIGVsYXBzZWRNaWxsaXMgPSAoU3lzdGVtLm5hbm9UaW1lKCkgLSBzdGFydGVkTmFub3MpIC8gTkFOT1NfUEVSX01JTExJOworICAgICAgICAgICAgICAgICAgICBzbGVlcE1pbGxpcyAtPSBlbGFwc2VkTWlsbGlzOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChzbGVlcE1pbGxpcyA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcChzbGVlcE1pbGxpcyk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKG9iamVjdCA9PSBudWxsCisgICAgICAgICAgICAgICAgICAgICAgICB8fCBvYmplY3QgIT0gRmluYWxpemVyRGFlbW9uLklOU1RBTkNFLmZpbmFsaXppbmdPYmplY3QKKyAgICAgICAgICAgICAgICAgICAgICAgIHx8IFZNUnVudGltZS5nZXRSdW50aW1lKCkuaXNEZWJ1Z2dlckFjdGl2ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIFRoZSBjdXJyZW50IG9iamVjdCBoYXMgZXhjZWVkZWQgdGhlIGZpbmFsaXphdGlvbiBkZWFkbGluZTsgYWJvcnQhCisgICAgICAgICAgICAgICAgbG9uZyBlbGFwc2VkTWlsbGlzID0gKFN5c3RlbS5uYW5vVGltZSgpIC0gc3RhcnRlZE5hbm9zKSAvIE5BTk9TX1BFUl9NSUxMSTsKKyAgICAgICAgICAgICAgICBFeGNlcHRpb24gc3ludGhldGljRXhjZXB0aW9uID0gbmV3IFRpbWVvdXRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICBzeW50aGV0aWNFeGNlcHRpb24uc2V0U3RhY2tUcmFjZShGaW5hbGl6ZXJEYWVtb24uSU5TVEFOQ0UuZ2V0U3RhY2tUcmFjZSgpKTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ubG9nRShvYmplY3QuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiLmZpbmFsaXplKCkgdGltZWQgb3V0IGFmdGVyICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgZWxhcHNlZE1pbGxpcyArICIgbXM7IGxpbWl0IGlzICIgKyBNQVhfRklOQUxJWkVfTUlMTElTICsgIiBtcyIsCisgICAgICAgICAgICAgICAgICAgICAgICBzeW50aGV0aWNFeGNlcHRpb24pOworICAgICAgICAgICAgICAgIFN5c3RlbS5leGl0KDIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9EZXByZWNhdGVkLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0RlcHJlY2F0ZWQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNDdhNmJlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9EZXByZWNhdGVkLmphdmEKQEAgLTAsMCArMSwzMyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5Eb2N1bWVudGVkOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3k7CisKKy8qKgorICogQW5ub3RhdGlvbiB0eXBlIHVzZWQgdG8gbWFyayBwcm9ncmFtIGVsZW1lbnRzIHRoYXQgc2hvdWxkIG5vIGxvbmdlciBiZSB1c2VkCisgKiBieSBwcm9ncmFtbWVycy4gQ29tcGlsZXJzIHByb2R1Y2UgYSB3YXJuaW5nIGlmIGEgZGVwcmVjYXRlZCBwcm9ncmFtIGVsZW1lbnQKKyAqIGlzIHVzZWQuCisgKgorICogQHNpbmNlIDEuNQorICovCitARG9jdW1lbnRlZAorQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKK3B1YmxpYyBAaW50ZXJmYWNlIERlcHJlY2F0ZWQgeworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Eb3VibGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvRG91YmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDU2NTI5YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvRG91YmxlLmphdmEKQEAgLTAsMCArMSw0ODQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIFRoZSB3cmFwcGVyIGZvciB0aGUgcHJpbWl0aXZlIHR5cGUge0Bjb2RlIGRvdWJsZX0uCisgKgorICogQHNlZSBqYXZhLmxhbmcuTnVtYmVyCisgKiBAc2luY2UgMS4wCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBEb3VibGUgZXh0ZW5kcyBOdW1iZXIgaW1wbGVtZW50cyBDb21wYXJhYmxlPERvdWJsZT4geworICAgIHN0YXRpYyBmaW5hbCBpbnQgRVhQT05FTlRfQklBUyA9IDEwMjM7CisKKyAgICBzdGF0aWMgZmluYWwgaW50IEVYUE9ORU5UX0JJVFMgPSAxMjsKKyAgICBzdGF0aWMgZmluYWwgaW50IE1BTlRJU1NBX0JJVFMgPSA1MjsKKyAgICBzdGF0aWMgZmluYWwgaW50IE5PTl9NQU5USVNTQV9CSVRTID0gMTI7CisKKyAgICBzdGF0aWMgZmluYWwgbG9uZyBTSUdOX01BU0sgICAgID0gMHg4MDAwMDAwMDAwMDAwMDAwTDsKKyAgICBzdGF0aWMgZmluYWwgbG9uZyBFWFBPTkVOVF9NQVNLID0gMHg3ZmYwMDAwMDAwMDAwMDAwTDsKKyAgICBzdGF0aWMgZmluYWwgbG9uZyBNQU5USVNTQV9NQVNLID0gMHgwMDBmZmZmZmZmZmZmZmZmTDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC05MTcyNzc0MzkyMjQ1MjU3NDY4TDsKKworICAgIC8qKgorICAgICAqIFRoZSB2YWx1ZSB3aGljaCB0aGUgcmVjZWl2ZXIgcmVwcmVzZW50cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGRvdWJsZSB2YWx1ZTsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IGZvciB0aGUgbWF4aW11bSB7QGNvZGUgZG91YmxlfSB2YWx1ZSwgKDIgLSAyPHN1cD4tNTI8L3N1cD4pICoKKyAgICAgKiAyPHN1cD4xMDIzPC9zdXA+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgZG91YmxlIE1BWF9WQUxVRSA9IDEuNzk3NjkzMTM0ODYyMzE1NzBlKzMwODsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IGZvciB0aGUgbWluaW11bSB7QGNvZGUgZG91YmxlfSB2YWx1ZSwgMjxzdXA+LTEwNzQ8L3N1cD4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBkb3VibGUgTUlOX1ZBTFVFID0gNWUtMzI0OworCisgICAgLyogNC45NDA2NTY0NTg0MTI0NjU0NGUtMzI0IGdldHMgcm91bmRlZCB0byA5Ljg4MTMxZS0zMjQgKi8KKworICAgIC8qKgorICAgICAqIENvbnN0YW50IGZvciB0aGUgTm90LWEtTnVtYmVyIChOYU4pIHZhbHVlIG9mIHRoZSB7QGNvZGUgZG91YmxlfSB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgZG91YmxlIE5hTiA9IDAuMCAvIDAuMDsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IGZvciB0aGUgcG9zaXRpdmUgaW5maW5pdHkgdmFsdWUgb2YgdGhlIHtAY29kZSBkb3VibGV9IHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBkb3VibGUgUE9TSVRJVkVfSU5GSU5JVFkgPSAxLjAgLyAwLjA7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCBmb3IgdGhlIG5lZ2F0aXZlIGluZmluaXR5IHZhbHVlIG9mIHRoZSB7QGNvZGUgZG91YmxlfSB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgZG91YmxlIE5FR0FUSVZFX0lORklOSVRZID0gLTEuMCAvIDAuMDsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IGZvciB0aGUgc21hbGxlc3QgcG9zaXRpdmUgbm9ybWFsIHZhbHVlIG9mIHRoZSB7QGNvZGUgZG91YmxlfSB0eXBlLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgZG91YmxlIE1JTl9OT1JNQUwgPSAyLjIyNTA3Mzg1ODUwNzIwMTRFLTMwODsKKworICAgIC8qKgorICAgICAqIE1heGltdW0gYmFzZS0yIGV4cG9uZW50IHRoYXQgYSBmaW5pdGUgdmFsdWUgb2YgdGhlIHtAY29kZSBkb3VibGV9IHR5cGUgbWF5IGhhdmUuCisgICAgICogRXF1YWwgdG8ge0Bjb2RlIE1hdGguZ2V0RXhwb25lbnQoRG91YmxlLk1BWF9WQUxVRSl9LgorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9FWFBPTkVOVCA9IDEwMjM7CisKKyAgICAvKioKKyAgICAgKiBNaW5pbXVtIGJhc2UtMiBleHBvbmVudCB0aGF0IGEgbm9ybWFsIHZhbHVlIG9mIHRoZSB7QGNvZGUgZG91YmxlfSB0eXBlIG1heSBoYXZlLgorICAgICAqIEVxdWFsIHRvIHtAY29kZSBNYXRoLmdldEV4cG9uZW50KERvdWJsZS5NSU5fTk9STUFMKX0uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUlOX0VYUE9ORU5UID0gLTEwMjI7CisKKyAgICAvKioKKyAgICAgKiBUaGUge0BsaW5rIENsYXNzfSBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBwcmltaXRpdmUgdHlwZSB7QGNvZGUKKyAgICAgKiBkb3VibGV9LgorICAgICAqCisgICAgICogQHNpbmNlIDEuMQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3M8RG91YmxlPiBUWVBFCisgICAgICAgICAgICA9IChDbGFzczxEb3VibGU+KSBkb3VibGVbXS5jbGFzcy5nZXRDb21wb25lbnRUeXBlKCk7CisgICAgLy8gTm90ZTogRG91YmxlLlRZUEUgY2FuJ3QgYmUgc2V0IHRvICJkb3VibGUuY2xhc3MiLCBzaW5jZSAqdGhhdCogaXMKKyAgICAvLyBkZWZpbmVkIHRvIGJlICJqYXZhLmxhbmcuRG91YmxlLlRZUEUiOworCisgICAgLyoqCisgICAgICogQ29uc3RhbnQgZm9yIHRoZSBudW1iZXIgb2YgYml0cyBuZWVkZWQgdG8gcmVwcmVzZW50IGEge0Bjb2RlIGRvdWJsZX0gaW4KKyAgICAgKiB0d28ncyBjb21wbGVtZW50IGZvcm0uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0laRSA9IDY0OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRG91YmxlfSB3aXRoIHRoZSBzcGVjaWZpZWQgcHJpbWl0aXZlIGRvdWJsZQorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgcHJpbWl0aXZlIGRvdWJsZSB2YWx1ZSB0byBzdG9yZSBpbiB0aGUgbmV3IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBEb3VibGUoZG91YmxlIHZhbHVlKSB7CisgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBEb3VibGV9IGZyb20gdGhlIHNwZWNpZmllZCBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgZG91YmxlIHZhbHVlLgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0cmluZ30gY2Fubm90IGJlIHBhcnNlZCBhcyBhIGRvdWJsZSB2YWx1ZS4KKyAgICAgKiBAc2VlICNwYXJzZURvdWJsZShTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIERvdWJsZShTdHJpbmcgc3RyaW5nKSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhwYXJzZURvdWJsZShzdHJpbmcpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIG9iamVjdCB0byB0aGUgc3BlY2lmaWVkIGRvdWJsZSBvYmplY3QgdG8gZGV0ZXJtaW5lIHRoZWlyCisgICAgICogcmVsYXRpdmUgb3JkZXIuIFRoZXJlIGFyZSB0d28gc3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBEb3VibGUuTmFOfSBpcyBlcXVhbCB0byB7QGNvZGUgRG91YmxlLk5hTn0gYW5kIGl0IGlzIGdyZWF0ZXIKKyAgICAgKiB0aGFuIGFueSBvdGhlciBkb3VibGUgdmFsdWUsIGluY2x1ZGluZyB7QGNvZGUgRG91YmxlLlBPU0lUSVZFX0lORklOSVRZfTs8L2xpPgorICAgICAqIDxsaT4rMC4wZCBpcyBncmVhdGVyIHRoYW4gLTAuMGQ8L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgZG91YmxlIG9iamVjdCB0byBjb21wYXJlIHRoaXMgb2JqZWN0IHRvLgorICAgICAqIEByZXR1cm4gYSBuZWdhdGl2ZSB2YWx1ZSBpZiB0aGUgdmFsdWUgb2YgdGhpcyBkb3VibGUgaXMgbGVzcyB0aGFuIHRoZQorICAgICAqICAgICAgICAgdmFsdWUgb2Yge0Bjb2RlIG9iamVjdH07IDAgaWYgdGhlIHZhbHVlIG9mIHRoaXMgZG91YmxlIGFuZCB0aGUKKyAgICAgKiAgICAgICAgIHZhbHVlIG9mIHtAY29kZSBvYmplY3R9IGFyZSBlcXVhbDsgYSBwb3NpdGl2ZSB2YWx1ZSBpZiB0aGUgdmFsdWUKKyAgICAgKiAgICAgICAgIG9mIHRoaXMgZG91YmxlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgdmFsdWUgb2Yge0Bjb2RlIG9iamVjdH0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvYmplY3R9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5Db21wYXJhYmxlCisgICAgICogQHNpbmNlIDEuMgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKERvdWJsZSBvYmplY3QpIHsKKyAgICAgICAgcmV0dXJuIGNvbXBhcmUodmFsdWUsIG9iamVjdC52YWx1ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGUgYnl0ZVZhbHVlKCkgeworICAgICAgICByZXR1cm4gKGJ5dGUpIHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW50ZWdlciBjb3JyZXNwb25kaW5nIHRvIHRoZSBiaXRzIG9mIHRoZSBnaXZlbgorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSUVFRV83NTQtMTk4NSI+SUVFRSA3NTQ8L2E+IGRvdWJsZSBwcmVjaXNpb24KKyAgICAgKiB7QGNvZGUgdmFsdWV9LiBBbGwgPGVtPk5vdC1hLU51bWJlciAoTmFOKTwvZW0+IHZhbHVlcyBhcmUgY29udmVydGVkIHRvIGEgc2luZ2xlIE5hTgorICAgICAqIHJlcHJlc2VudGF0aW9uICh7QGNvZGUgMHg3ZmY4MDAwMDAwMDAwMDAwTH0pIChjb21wYXJlIHRvIHtAbGluayAjZG91YmxlVG9SYXdMb25nQml0c30pLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGxvbmcgZG91YmxlVG9Mb25nQml0cyhkb3VibGUgdmFsdWUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnRlZ2VyIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGJpdHMgb2YgdGhlIGdpdmVuCisgICAgICogPGEgaHJlZj0iaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JRUVFXzc1NC0xOTg1Ij5JRUVFIDc1NDwvYT4gZG91YmxlIHByZWNpc2lvbgorICAgICAqIHtAY29kZSB2YWx1ZX0uIDxlbT5Ob3QtYS1OdW1iZXIgKE5hTik8L2VtPiB2YWx1ZXMgYXJlIHByZXNlcnZlZCAoY29tcGFyZQorICAgICAqIHRvIHtAbGluayAjZG91YmxlVG9Mb25nQml0c30pLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGxvbmcgZG91YmxlVG9SYXdMb25nQml0cyhkb3VibGUgdmFsdWUpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcHJpbWl0aXZlIHZhbHVlIG9mIHRoaXMgZG91YmxlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIG9iamVjdCdzIHByaW1pdGl2ZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZG91YmxlIGRvdWJsZVZhbHVlKCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgdGhpcyBkb3VibGUgZm9yIGVxdWFsaXR5IHdpdGgge0Bjb2RlIG9iamVjdH0uCisgICAgICogVG8gYmUgZXF1YWwsIHtAY29kZSBvYmplY3R9IG11c3QgYmUgYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIERvdWJsZX0gYW5kCisgICAgICoge0Bjb2RlIGRvdWJsZVRvTG9uZ0JpdHN9IG11c3QgZ2l2ZSB0aGUgc2FtZSB2YWx1ZSBmb3IgYm90aCBvYmplY3RzLgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0LCB1bmxpa2Uge0Bjb2RlID09fSwge0Bjb2RlIC0wLjB9IGFuZCB7QGNvZGUgKzAuMH0gY29tcGFyZQorICAgICAqIHVuZXF1YWwsIGFuZCB7QGNvZGUgTmFOfXMgY29tcGFyZSBlcXVhbCBieSB0aGlzIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB0aGlzIGRvdWJsZSB3aXRoLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBEb3VibGV9OyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICByZXR1cm4gKG9iamVjdCBpbnN0YW5jZW9mIERvdWJsZSkgJiYKKyAgICAgICAgICAgICAgICAoZG91YmxlVG9Mb25nQml0cyh0aGlzLnZhbHVlKSA9PSBkb3VibGVUb0xvbmdCaXRzKCgoRG91YmxlKSBvYmplY3QpLnZhbHVlKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZsb2F0IGZsb2F0VmFsdWUoKSB7CisgICAgICAgIHJldHVybiAoZmxvYXQpIHZhbHVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGxvbmcgdiA9IGRvdWJsZVRvTG9uZ0JpdHModmFsdWUpOworICAgICAgICByZXR1cm4gKGludCkgKHYgXiAodiA+Pj4gMzIpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGludFZhbHVlKCkgeworICAgICAgICByZXR1cm4gKGludCkgdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBvYmplY3QgcmVwcmVzZW50cyBhbiBpbmZpbml0ZSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSB2YWx1ZSBvZiB0aGlzIGRvdWJsZSBpcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZQorICAgICAqICAgICAgICAgaW5maW5pdHk7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzSW5maW5pdGUoKSB7CisgICAgICAgIHJldHVybiBpc0luZmluaXRlKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGRvdWJsZSByZXByZXNlbnRzIGFuIGluZmluaXRlIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb3VibGUgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHZhbHVlIG9mIHtAY29kZSBkfSBpcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZQorICAgICAqICAgICAgICAgaW5maW5pdHk7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0luZmluaXRlKGRvdWJsZSBkKSB7CisgICAgICAgIHJldHVybiAoZCA9PSBQT1NJVElWRV9JTkZJTklUWSkgfHwgKGQgPT0gTkVHQVRJVkVfSU5GSU5JVFkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgb2JqZWN0IGlzIGEgPGVtPk5vdC1hLU51bWJlciAoTmFOKTwvZW0+IHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBkb3VibGUgaXMgPGVtPk5vdC1hLU51bWJlcjwvZW0+OworICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBpZiBpdCBpcyBhIChwb3RlbnRpYWxseSBpbmZpbml0ZSkgZG91YmxlIG51bWJlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc05hTigpIHsKKyAgICAgICAgcmV0dXJuIGlzTmFOKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGRvdWJsZSBpcyBhIDxlbT5Ob3QtYS1OdW1iZXIgKE5hTik8L2VtPgorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb3VibGUgdmFsdWUgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGR9IGlzIDxlbT5Ob3QtYS1OdW1iZXI8L2VtPjsKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gaWYgaXQgaXMgYSAocG90ZW50aWFsbHkgaW5maW5pdGUpIGRvdWJsZSBudW1iZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTmFOKGRvdWJsZSBkKSB7CisgICAgICAgIHJldHVybiBkICE9IGQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgPGEgaHJlZj0iaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JRUVFXzc1NC0xOTg1Ij5JRUVFIDc1NDwvYT4KKyAgICAgKiBkb3VibGUgcHJlY2lzaW9uIGZsb2F0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIHtAY29kZSBiaXRzfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgbG9uZ0JpdHNUb0RvdWJsZShsb25nIGJpdHMpOworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgbG9uZ1ZhbHVlKCkgeworICAgICAgICByZXR1cm4gKGxvbmcpIHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgc3BlY2lmaWVkIHN0cmluZyBhcyBhIGRvdWJsZSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBkb3VibGUgdmFsdWUuCisgICAgICogQHJldHVybiB0aGUgcHJpbWl0aXZlIGRvdWJsZSB2YWx1ZSByZXByZXNlbnRlZCBieSB7QGNvZGUgc3RyaW5nfS4KKyAgICAgKiBAdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdHJpbmd9IGNhbm5vdCBiZSBwYXJzZWQgYXMgYSBkb3VibGUgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgcGFyc2VEb3VibGUoU3RyaW5nIHN0cmluZykgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBTdHJpbmdUb1JlYWwucGFyc2VEb3VibGUoc3RyaW5nKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc2hvcnQgc2hvcnRWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIChzaG9ydCkgdmFsdWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIERvdWJsZS50b1N0cmluZyh2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhlCisgICAgICogc3BlY2lmaWVkIGRvdWJsZSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICAgdGhlIGRvdWJsZSB0byBjb252ZXJ0IHRvIGEgc3RyaW5nLgorICAgICAqIEByZXR1cm4gYSBwcmludGFibGUgcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIGR9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKGRvdWJsZSBkKSB7CisgICAgICAgIHJldHVybiBSZWFsVG9TdHJpbmcuZ2V0SW5zdGFuY2UoKS5kb3VibGVUb1N0cmluZyhkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgdGhlIHNwZWNpZmllZCBzdHJpbmcgYXMgYSBkb3VibGUgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgZG91YmxlIHZhbHVlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgRG91YmxlfSBpbnN0YW5jZSBjb250YWluaW5nIHRoZSBkb3VibGUgdmFsdWUgcmVwcmVzZW50ZWQKKyAgICAgKiAgICAgICAgIGJ5IHtAY29kZSBzdHJpbmd9LgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0cmluZ30gY2Fubm90IGJlIHBhcnNlZCBhcyBhIGRvdWJsZSB2YWx1ZS4KKyAgICAgKiBAc2VlICNwYXJzZURvdWJsZShTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBEb3VibGUgdmFsdWVPZihTdHJpbmcgc3RyaW5nKSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHBhcnNlRG91YmxlKHN0cmluZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHR3byBzcGVjaWZpZWQgZG91YmxlIHZhbHVlcy4gVGhlcmUgYXJlIHR3byBzcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIERvdWJsZS5OYU59IGlzIGVxdWFsIHRvIHtAY29kZSBEb3VibGUuTmFOfSBhbmQgaXQgaXMgZ3JlYXRlcgorICAgICAqIHRoYW4gYW55IG90aGVyIGRvdWJsZSB2YWx1ZSwgaW5jbHVkaW5nIHtAY29kZSBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFl9OzwvbGk+CisgICAgICogPGxpPiswLjBkIGlzIGdyZWF0ZXIgdGhhbiAtMC4wZDwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkb3VibGUxCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgdmFsdWUgdG8gY29tcGFyZS4KKyAgICAgKiBAcGFyYW0gZG91YmxlMgorICAgICAqICAgICAgICAgICAgdGhlIHNlY29uZCB2YWx1ZSB0byBjb21wYXJlLgorICAgICAqIEByZXR1cm4gYSBuZWdhdGl2ZSB2YWx1ZSBpZiB7QGNvZGUgZG91YmxlMX0gaXMgbGVzcyB0aGFuIHtAY29kZSBkb3VibGUyfTsKKyAgICAgKiAgICAgICAgIDAgaWYge0Bjb2RlIGRvdWJsZTF9IGFuZCB7QGNvZGUgZG91YmxlMn0gYXJlIGVxdWFsOyBhIHBvc2l0aXZlCisgICAgICogICAgICAgICB2YWx1ZSBpZiB7QGNvZGUgZG91YmxlMX0gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSBkb3VibGUyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBjb21wYXJlKGRvdWJsZSBkb3VibGUxLCBkb3VibGUgZG91YmxlMikgeworICAgICAgICAvLyBOb24temVybywgbm9uLU5hTiBjaGVja2luZy4KKyAgICAgICAgaWYgKGRvdWJsZTEgPiBkb3VibGUyKSB7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZG91YmxlMiA+IGRvdWJsZTEpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZG91YmxlMSA9PSBkb3VibGUyICYmIDAuMGQgIT0gZG91YmxlMSkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICAvLyBOYU5zIGFyZSBlcXVhbCB0byBvdGhlciBOYU5zIGFuZCBsYXJnZXIgdGhhbiBhbnkgb3RoZXIgZG91YmxlCisgICAgICAgIGlmIChpc05hTihkb3VibGUxKSkgeworICAgICAgICAgICAgaWYgKGlzTmFOKGRvdWJsZTIpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfSBlbHNlIGlmIChpc05hTihkb3VibGUyKSkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisKKyAgICAgICAgLy8gRGVhbCB3aXRoICswLjAgYW5kIC0wLjAKKyAgICAgICAgbG9uZyBkMSA9IGRvdWJsZVRvUmF3TG9uZ0JpdHMoZG91YmxlMSk7CisgICAgICAgIGxvbmcgZDIgPSBkb3VibGVUb1Jhd0xvbmdCaXRzKGRvdWJsZTIpOworICAgICAgICAvLyBUaGUgYmVsb3cgZXhwcmVzc2lvbiBpcyBlcXVpdmFsZW50IHRvOgorICAgICAgICAvLyAoZDEgPT0gZDIpID8gMCA6IChkMSA8IGQyKSA/IC0xIDogMQorICAgICAgICByZXR1cm4gKGludCkgKChkMSA+PiA2MykgLSAoZDIgPj4gNjMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIERvdWJsZX0gaW5zdGFuY2UgZm9yIHRoZSBzcGVjaWZpZWQgZG91YmxlIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb3VibGUgdmFsdWUgdG8gc3RvcmUgaW4gdGhlIGluc3RhbmNlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgRG91YmxlfSBpbnN0YW5jZSBjb250YWluaW5nIHtAY29kZSBkfS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBEb3VibGUgdmFsdWVPZihkb3VibGUgZCkgeworICAgICAgICByZXR1cm4gbmV3IERvdWJsZShkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIGRvdWJsZSBpbnRvIGl0cyBoZXhhZGVjaW1hbCBzdHJpbmcgcmVwcmVzZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIGRvdWJsZSB0byBjb252ZXJ0LgorICAgICAqIEByZXR1cm4gdGhlIGhleGFkZWNpbWFsIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUgZH0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvSGV4U3RyaW5nKGRvdWJsZSBkKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFJlZmVyZW5jZTogaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JRUVFXzc1NC0xOTg1CisgICAgICAgICAqLworICAgICAgICBpZiAoZCAhPSBkKSB7CisgICAgICAgICAgICByZXR1cm4gIk5hTiI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGQgPT0gUE9TSVRJVkVfSU5GSU5JVFkpIHsKKyAgICAgICAgICAgIHJldHVybiAiSW5maW5pdHkiOworICAgICAgICB9CisgICAgICAgIGlmIChkID09IE5FR0FUSVZFX0lORklOSVRZKSB7CisgICAgICAgICAgICByZXR1cm4gIi1JbmZpbml0eSI7CisgICAgICAgIH0KKworICAgICAgICBsb25nIGJpdFZhbHVlID0gZG91YmxlVG9Mb25nQml0cyhkKTsKKworICAgICAgICBib29sZWFuIG5lZ2F0aXZlID0gKGJpdFZhbHVlICYgMHg4MDAwMDAwMDAwMDAwMDAwTCkgIT0gMDsKKyAgICAgICAgLy8gbWFzayBleHBvbmVudCBiaXRzIGFuZCBzaGlmdCBkb3duCisgICAgICAgIGxvbmcgZXhwb25lbnQgPSAoYml0VmFsdWUgJiAweDdGRjAwMDAwMDAwMDAwMDBMKSA+Pj4gNTI7CisgICAgICAgIC8vIG1hc2sgc2lnbmlmaWNhbmQgYml0cyBhbmQgc2hpZnQgdXAKKyAgICAgICAgbG9uZyBzaWduaWZpY2FuZCA9IGJpdFZhbHVlICYgMHgwMDBGRkZGRkZGRkZGRkZGTDsKKworICAgICAgICBpZiAoZXhwb25lbnQgPT0gMCAmJiBzaWduaWZpY2FuZCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gKG5lZ2F0aXZlID8gIi0weDAuMHAwIiA6ICIweDAuMHAwIik7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdCdWlsZGVyIGhleFN0cmluZyA9IG5ldyBTdHJpbmdCdWlsZGVyKDEwKTsKKyAgICAgICAgaWYgKG5lZ2F0aXZlKSB7CisgICAgICAgICAgICBoZXhTdHJpbmcuYXBwZW5kKCItMHgiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGhleFN0cmluZy5hcHBlbmQoIjB4Iik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZXhwb25lbnQgPT0gMCkgeyAvLyBkZW5vcm1hbCAoc3Vibm9ybWFsKSB2YWx1ZQorICAgICAgICAgICAgaGV4U3RyaW5nLmFwcGVuZCgiMC4iKTsKKyAgICAgICAgICAgIC8vIHNpZ25pZmljYW5kIGlzIDUyLWJpdHMsIHNvIHRoZXJlIGNhbiBiZSAxMyBoZXggZGlnaXRzCisgICAgICAgICAgICBpbnQgZnJhY3Rpb25EaWdpdHMgPSAxMzsKKyAgICAgICAgICAgIC8vIHJlbW92ZSB0cmFpbGluZyBoZXggemVyb3MsIHNvIEludGVnZXIudG9IZXhTdHJpbmcoKSB3b24ndCBwcmludAorICAgICAgICAgICAgLy8gdGhlbQorICAgICAgICAgICAgd2hpbGUgKChzaWduaWZpY2FuZCAhPSAwKSAmJiAoKHNpZ25pZmljYW5kICYgMHhGKSA9PSAwKSkgeworICAgICAgICAgICAgICAgIHNpZ25pZmljYW5kID4+Pj0gNDsKKyAgICAgICAgICAgICAgICBmcmFjdGlvbkRpZ2l0cy0tOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gdGhpcyBhc3N1bWVzIEludGVnZXIudG9IZXhTdHJpbmcoKSByZXR1cm5zIGxvd2VyY2FzZSBjaGFyYWN0ZXJzCisgICAgICAgICAgICBTdHJpbmcgaGV4U2lnbmlmaWNhbmQgPSBMb25nLnRvSGV4U3RyaW5nKHNpZ25pZmljYW5kKTsKKworICAgICAgICAgICAgLy8gaWYgdGhlcmUgYXJlIGRpZ2l0cyBsZWZ0LCB0aGVuIGluc2VydCBzb21lICcwJyBjaGFycyBmaXJzdAorICAgICAgICAgICAgaWYgKHNpZ25pZmljYW5kICE9IDAgJiYgZnJhY3Rpb25EaWdpdHMgPiBoZXhTaWduaWZpY2FuZC5sZW5ndGgoKSkgeworICAgICAgICAgICAgICAgIGludCBkaWdpdERpZmYgPSBmcmFjdGlvbkRpZ2l0cyAtIGhleFNpZ25pZmljYW5kLmxlbmd0aCgpOworICAgICAgICAgICAgICAgIHdoaWxlIChkaWdpdERpZmYtLSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGhleFN0cmluZy5hcHBlbmQoJzAnKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBoZXhTdHJpbmcuYXBwZW5kKGhleFNpZ25pZmljYW5kKTsKKyAgICAgICAgICAgIGhleFN0cmluZy5hcHBlbmQoInAtMTAyMiIpOworICAgICAgICB9IGVsc2UgeyAvLyBub3JtYWwgdmFsdWUKKyAgICAgICAgICAgIGhleFN0cmluZy5hcHBlbmQoIjEuIik7CisgICAgICAgICAgICAvLyBzaWduaWZpY2FuZCBpcyA1Mi1iaXRzLCBzbyB0aGVyZSBjYW4gYmUgMTMgaGV4IGRpZ2l0cworICAgICAgICAgICAgaW50IGZyYWN0aW9uRGlnaXRzID0gMTM7CisgICAgICAgICAgICAvLyByZW1vdmUgdHJhaWxpbmcgaGV4IHplcm9zLCBzbyBJbnRlZ2VyLnRvSGV4U3RyaW5nKCkgd29uJ3QgcHJpbnQKKyAgICAgICAgICAgIC8vIHRoZW0KKyAgICAgICAgICAgIHdoaWxlICgoc2lnbmlmaWNhbmQgIT0gMCkgJiYgKChzaWduaWZpY2FuZCAmIDB4RikgPT0gMCkpIHsKKyAgICAgICAgICAgICAgICBzaWduaWZpY2FuZCA+Pj49IDQ7CisgICAgICAgICAgICAgICAgZnJhY3Rpb25EaWdpdHMtLTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIHRoaXMgYXNzdW1lcyBJbnRlZ2VyLnRvSGV4U3RyaW5nKCkgcmV0dXJucyBsb3dlcmNhc2UgY2hhcmFjdGVycworICAgICAgICAgICAgU3RyaW5nIGhleFNpZ25pZmljYW5kID0gTG9uZy50b0hleFN0cmluZyhzaWduaWZpY2FuZCk7CisKKyAgICAgICAgICAgIC8vIGlmIHRoZXJlIGFyZSBkaWdpdHMgbGVmdCwgdGhlbiBpbnNlcnQgc29tZSAnMCcgY2hhcnMgZmlyc3QKKyAgICAgICAgICAgIGlmIChzaWduaWZpY2FuZCAhPSAwICYmIGZyYWN0aW9uRGlnaXRzID4gaGV4U2lnbmlmaWNhbmQubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgICAgICBpbnQgZGlnaXREaWZmID0gZnJhY3Rpb25EaWdpdHMgLSBoZXhTaWduaWZpY2FuZC5sZW5ndGgoKTsKKyAgICAgICAgICAgICAgICB3aGlsZSAoZGlnaXREaWZmLS0gIT0gMCkgeworICAgICAgICAgICAgICAgICAgICBoZXhTdHJpbmcuYXBwZW5kKCcwJyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBoZXhTdHJpbmcuYXBwZW5kKGhleFNpZ25pZmljYW5kKTsKKyAgICAgICAgICAgIGhleFN0cmluZy5hcHBlbmQoJ3AnKTsKKyAgICAgICAgICAgIC8vIHJlbW92ZSBleHBvbmVudCdzICdiaWFzJyBhbmQgY29udmVydCB0byBhIHN0cmluZworICAgICAgICAgICAgaGV4U3RyaW5nLmFwcGVuZChMb25nLnRvU3RyaW5nKGV4cG9uZW50IC0gMTAyMykpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBoZXhTdHJpbmcudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0VudW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvRW51bS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5MTY3MGMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0VudW0uamF2YQpAQCAtMCwwICsxLDIxNSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuQmFzaWNMcnVDYWNoZTsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuRW1wdHlBcnJheTsKKworLyoqCisgKiBUaGUgc3VwZXJjbGFzcyBvZiBhbGwgZW51bWVyYXRlZCB0eXBlcy4gQWN0dWFsIGVudW1lcmF0aW9uIHR5cGVzIGluaGVyaXQgZnJvbQorICogdGhpcyBjbGFzcywgYnV0IGV4dGVuZGluZyB0aGlzIGNsYXNzIGRvZXMgbm90IG1ha2UgYSBjbGFzcyBhbiBlbnVtZXJhdGlvbgorICogdHlwZSwgc2luY2UgdGhlIGNvbXBpbGVyIG5lZWRzIHRvIGdlbmVyYXRlIHNwZWNpYWwgaW5mb3JtYXRpb24gZm9yIGl0LgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRW51bTxFIGV4dGVuZHMgRW51bTxFPj4gaW1wbGVtZW50cyBTZXJpYWxpemFibGUsIENvbXBhcmFibGU8RT4geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQzMDA5MjY1NDY2MTkzOTQwMDVMOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQmFzaWNMcnVDYWNoZTxDbGFzczw/IGV4dGVuZHMgRW51bT4sIE9iamVjdFtdPiBzaGFyZWRDb25zdGFudHNDYWNoZQorICAgICAgICAgICAgPSBuZXcgQmFzaWNMcnVDYWNoZTxDbGFzczw/IGV4dGVuZHMgRW51bT4sIE9iamVjdFtdPig2NCkgeworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIE9iamVjdFtdIGNyZWF0ZShDbGFzczw/IGV4dGVuZHMgRW51bT4gZW51bVR5cGUpIHsKKyAgICAgICAgICAgIE1ldGhvZCBtZXRob2QgPSAoTWV0aG9kKSBDbGFzcy5nZXREZWNsYXJlZENvbnN0cnVjdG9yT3JNZXRob2QoCisgICAgICAgICAgICAgICAgICAgIGVudW1UeXBlLCAidmFsdWVzIiwgRW1wdHlBcnJheS5DTEFTUyk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiAoT2JqZWN0W10pIG1ldGhvZC5pbnZva2UoKE9iamVjdFtdKSBudWxsKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaW1wb3NzaWJsZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBpbXBvc3NpYmxlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9OworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbmFtZTsKKworICAgIHByaXZhdGUgZmluYWwgaW50IG9yZGluYWw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uc3RhbnRzIG9mIGVudW0gc3VidHlwZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGVudW0gY29uc3RhbnQncyBkZWNsYXJlZCBuYW1lLgorICAgICAqIEBwYXJhbSBvcmRpbmFsCisgICAgICogICAgICAgICAgICB0aGUgZW51bSBjb25zdGFudCdzIG9yZGluYWwsIHdoaWNoIGNvcnJlc3BvbmRzIHRvIGl0cyBwb3NpdGlvbgorICAgICAqICAgICAgICAgICAgaW4gdGhlIGVudW0gZGVjbGFyYXRpb24sIHN0YXJ0aW5nIGF0IHplcm8uCisgICAgICovCisgICAgcHJvdGVjdGVkIEVudW0oU3RyaW5nIG5hbWUsIGludCBvcmRpbmFsKSB7CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgIHRoaXMub3JkaW5hbCA9IG9yZGluYWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGlzIGVudW0gY29uc3RhbnQuIFRoZSBuYW1lIGlzIHRoZSBmaWVsZCBhcyBpdAorICAgICAqIGFwcGVhcnMgaW4gdGhlIHtAY29kZSBlbnVtfSBkZWNsYXJhdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhpcyBlbnVtIGNvbnN0YW50LgorICAgICAqIEBzZWUgI3RvU3RyaW5nKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIG5hbWUoKSB7CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHBvc2l0aW9uIG9mIHRoZSBlbnVtIGNvbnN0YW50IGluIHRoZSBkZWNsYXJhdGlvbi4gVGhlIGZpcnN0CisgICAgICogY29uc3RhbnQgaGFzIGFuIG9yZGluYWwgdmFsdWUgb2YgemVyby4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG9yZGluYWwgdmFsdWUgb2YgdGhpcyBlbnVtIGNvbnN0YW50LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgb3JkaW5hbCgpIHsKKyAgICAgICAgcmV0dXJuIG9yZGluYWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhpcworICAgICAqIG9iamVjdC4gSW4gdGhpcyBjYXNlLCB0aGUgZW51bSBjb25zdGFudCdzIG5hbWUgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcHJpbnRhYmxlIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoaXMgb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBvYmplY3QgYW5kIGluZGljYXRlcyBpZiB0aGV5IGFyZQorICAgICAqIGVxdWFsLiBJbiBvcmRlciB0byBiZSBlcXVhbCwge0Bjb2RlIG9iamVjdH0gbXVzdCBiZSBpZGVudGljYWwgdG8gdGhpcworICAgICAqIGVudW0gY29uc3RhbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3RoZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB0aGlzIGVudW0gY29uc3RhbnQgd2l0aC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBlcXVhbCB0byB0aGlzCisgICAgICogICAgICAgICB7QGNvZGUgRW51bX07IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMgPT0gb3RoZXI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIG9yZGluYWwgKyAobmFtZSA9PSBudWxsID8gMCA6IG5hbWUuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bjb2RlIEVudW19IG9iamVjdHMgYXJlIHNpbmdsZXRvbnMsIHRoZXkgbWF5IG5vdCBiZSBjbG9uZWQuIFRoaXMgbWV0aG9kCisgICAgICogYWx3YXlzIHRocm93cyBhIHtAY29kZSBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGRvZXMgbm90IHJldHVybi4KKyAgICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaXMgYWx3YXlzIHRocm93bi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgZmluYWwgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJFbnVtcyBtYXkgbm90IGJlIGNsb25lZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoaXMgb2JqZWN0IHRvIHRoZSBzcGVjaWZpZWQgZW51bSBvYmplY3QgdG8gZGV0ZXJtaW5lIHRoZWlyCisgICAgICogcmVsYXRpdmUgb3JkZXIuIFRoaXMgbWV0aG9kIGNvbXBhcmVzIHRoZSBvYmplY3QncyBvcmRpbmFsIHZhbHVlcywgdGhhdAorICAgICAqIGlzLCB0aGVpciBwb3NpdGlvbiBpbiB0aGUgZW51bSBkZWNsYXJhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvCisgICAgICogICAgICAgICAgICB0aGUgZW51bSBvYmplY3QgdG8gY29tcGFyZSB0aGlzIG9iamVjdCB0by4KKyAgICAgKiBAcmV0dXJuIGEgbmVnYXRpdmUgdmFsdWUgaWYgdGhlIG9yZGluYWwgdmFsdWUgb2YgdGhpcyBlbnVtIGNvbnN0YW50IGlzCisgICAgICogICAgICAgICBsZXNzIHRoYW4gdGhlIG9yZGluYWwgdmFsdWUgb2Yge0Bjb2RlIG99OyAwIGlmIHRoZSBvcmRpbmFsCisgICAgICogICAgICAgICB2YWx1ZXMgb2YgdGhpcyBlbnVtIGNvbnN0YW50IGFuZCB7QGNvZGUgb30gYXJlIGVxdWFsOyBhIHBvc2l0aXZlCisgICAgICogICAgICAgICB2YWx1ZSBpZiB0aGUgb3JkaW5hbCB2YWx1ZSBvZiB0aGlzIGVudW0gY29uc3RhbnQgaXMgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgICB0aGUgb3JkaW5hbCB2YWx1ZSBvZiB7QGNvZGUgb30uCisgICAgICogQHNlZSBqYXZhLmxhbmcuQ29tcGFyYWJsZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgY29tcGFyZVRvKEUgbykgeworICAgICAgICByZXR1cm4gb3JkaW5hbCAtIG8ub3JkaW5hbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBlbnVtIGNvbnN0YW50J3MgZGVjbGFyaW5nIGNsYXNzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2xhc3Mgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY29uc3RhbnQncyBlbnVtIHR5cGUuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIGZpbmFsIENsYXNzPEU+IGdldERlY2xhcmluZ0NsYXNzKCkgeworICAgICAgICBDbGFzczw/PiBteUNsYXNzID0gZ2V0Q2xhc3MoKTsKKyAgICAgICAgQ2xhc3M8Pz4gbXlTdXBlckNsYXNzID0gbXlDbGFzcy5nZXRTdXBlcmNsYXNzKCk7CisgICAgICAgIGlmIChFbnVtLmNsYXNzID09IG15U3VwZXJDbGFzcykgeworICAgICAgICAgICAgcmV0dXJuIChDbGFzczxFPilteUNsYXNzOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoQ2xhc3M8RT4pbXlTdXBlckNsYXNzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNvbnN0YW50IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIG9mIHRoZSBzcGVjaWZpZWQgZW51bSB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIGVudW1UeXBlCisgICAgICogICAgICAgICAgICB0aGUgY2xhc3Mgb2YgdGhlIGVudW1lcmF0ZWQgdHlwZSB0byBzZWFyY2ggZm9yIHRoZSBjb25zdGFudAorICAgICAqICAgICAgICAgICAgdmFsdWUuCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjb25zdGFudCB2YWx1ZSB0byBmaW5kLgorICAgICAqIEByZXR1cm4gdGhlIGVudW0gY29uc3RhbnQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVpdGhlciB7QGNvZGUgZW51bVR5cGV9IG9yIHtAY29kZSBuYW1lfSBhcmUge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGVudW1UeXBlfSBpcyBub3QgYW4gZW51bWVyYXRlZCB0eXBlIG9yIGRvZXMgbm90CisgICAgICogICAgICAgICAgICAgaGF2ZSBhIGNvbnN0YW50IHZhbHVlIGNhbGxlZCB7QGNvZGUgbmFtZX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8VCBleHRlbmRzIEVudW08VD4+IFQgdmFsdWVPZihDbGFzczxUPiBlbnVtVHlwZSwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgaWYgKGVudW1UeXBlID09IG51bGwgfHwgbmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImVudW1UeXBlID09IG51bGwgfHwgbmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFlbnVtVHlwZS5pc0VudW0oKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihlbnVtVHlwZSArICIgaXMgbm90IGFuIGVudW0gdHlwZSIpOworICAgICAgICB9CisgICAgICAgIGZvciAoVCB2YWx1ZSA6IGdldFNoYXJlZENvbnN0YW50cyhlbnVtVHlwZSkpIHsKKyAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyh2YWx1ZS5uYW1lKCkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24obmFtZSArICIgaXMgbm90IGEgY29uc3RhbnQgaW4gIiArIGVudW1UeXBlLmdldE5hbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNoYXJlZCwgbXV0YWJsZSBhcnJheSBjb250YWluaW5nIHRoZSBjb25zdGFudHMgb2YgdGhpcyBlbnVtLiBJdAorICAgICAqIGlzIGFuIGVycm9yIHRvIG1vZGlmeSB0aGUgcmV0dXJuZWQgYXJyYXkuCisgICAgICoKKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSAvLyB0aGUgY2FjaGUgYWx3YXlzIHJldHVybnMgdGhlIHR5cGUgbWF0Y2hpbmcgZW51bVR5cGUKKyAgICBwdWJsaWMgc3RhdGljIDxUIGV4dGVuZHMgRW51bTxUPj4gVFtdIGdldFNoYXJlZENvbnN0YW50cyhDbGFzczxUPiBlbnVtVHlwZSkgeworICAgICAgICByZXR1cm4gKFRbXSkgc2hhcmVkQ29uc3RhbnRzQ2FjaGUuZ2V0KGVudW1UeXBlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbnVtIHR5cGVzIG1heSBub3QgaGF2ZSBmaW5hbGl6ZXJzLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJGaW5hbGl6ZURvZXNudENhbGxTdXBlckZpbmFsaXplIikKKyAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBmaW5hbGl6ZSgpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0VudW1Db25zdGFudE5vdFByZXNlbnRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvRW51bUNvbnN0YW50Tm90UHJlc2VudEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNiZDMzMjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0VudW1Db25zdGFudE5vdFByZXNlbnRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDY5IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gaWYgYW4ge0Bjb2RlIGVudW19IGNvbnN0YW50IGRvZXMgbm90IGV4aXN0IGZvciBhIHBhcnRpY3VsYXIgbmFtZS4KKyAqCisgKiBAc2luY2UgMS41CisgKi8KK3B1YmxpYyBjbGFzcyBFbnVtQ29uc3RhbnROb3RQcmVzZW50RXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjA0Njk5ODUyMTk2MDUyMTEwOEw7CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIGZpbmFsIENsYXNzPD8gZXh0ZW5kcyBFbnVtPiBlbnVtVHlwZTsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGNvbnN0YW50TmFtZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEVudW1Db25zdGFudE5vdFByZXNlbnRFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQKKyAgICAgKiBzdGFjayB0cmFjZSBhbmQgYSBkZXRhaWwgbWVzc2FnZSBiYXNlZCBvbiB0aGUgc3BlY2lmaWVkIGVudW0gdHlwZSBhbmQKKyAgICAgKiBtaXNzaW5nIGNvbnN0YW50IG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW51bVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbnVtIHR5cGUuCisgICAgICogQHBhcmFtIGNvbnN0YW50TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG1pc3NpbmcgY29uc3RhbnQgbmFtZS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgRW51bUNvbnN0YW50Tm90UHJlc2VudEV4Y2VwdGlvbihDbGFzczw/IGV4dGVuZHMgRW51bT4gZW51bVR5cGUsIFN0cmluZyBjb25zdGFudE5hbWUpIHsKKyAgICAgICAgc3VwZXIoImVudW0gY29uc3RhbnQgIiArIGVudW1UeXBlLmdldE5hbWUoKSArICIuIiArIGNvbnN0YW50TmFtZSArICIgaXMgbWlzc2luZyIpOworICAgICAgICB0aGlzLmVudW1UeXBlID0gZW51bVR5cGU7CisgICAgICAgIHRoaXMuY29uc3RhbnROYW1lID0gY29uc3RhbnROYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGVudW0gdHlwZSBmb3Igd2hpY2ggdGhlIGNvbnN0YW50IG5hbWUgaXMgbWlzc2luZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVudW0gdHlwZSBmb3Igd2hpY2ggYSBjb25zdGFudCBuYW1lIGhhcyBub3QgYmVlbiBmb3VuZC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgQ2xhc3M8PyBleHRlbmRzIEVudW0+IGVudW1UeXBlKCkgeworICAgICAgICByZXR1cm4gZW51bVR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbmFtZSBvZiB0aGUgbWlzc2luZyBjb25zdGFudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGNvbnN0YW50IHRoYXQgaGFzIG5vdCBiZWVuIGZvdW5kIGluIHRoZSBlbnVtCisgICAgICogICAgICAgICB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgY29uc3RhbnROYW1lKCkgeworICAgICAgICByZXR1cm4gY29uc3RhbnROYW1lOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvRXJyb3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvRXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMDAxN2ZkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9FcnJvci5qYXZhCkBAIC0wLDAgKzEsNzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisKKy8qKgorICoge0Bjb2RlIEVycm9yfSBpcyB0aGUgc3VwZXJjbGFzcyBvZiBhbGwgY2xhc3NlcyB0aGF0IHJlcHJlc2VudCB1bnJlY292ZXJhYmxlCisgKiBlcnJvcnMuIFdoZW4gZXJyb3JzIGFyZSB0aHJvd24sIHRoZXkgc2hvdWxkIG5vdCBiZSBjYXVnaHQgYnkgYXBwbGljYXRpb24KKyAqIGNvZGUuCisgKgorICogQHNlZSBUaHJvd2FibGUKKyAqIEBzZWUgRXhjZXB0aW9uCisgKiBAc2VlIFJ1bnRpbWVFeGNlcHRpb24KKyAqLworcHVibGljIGNsYXNzIEVycm9yIGV4dGVuZHMgVGhyb3dhYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDQ5ODAxOTY1MDgyNzcyODAzNDJMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRXJyb3J9IHRoYXQgaW5jbHVkZXMgdGhlIGN1cnJlbnQgc3RhY2sgdHJhY2UuCisgICAgICovCisgICAgcHVibGljIEVycm9yKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEVycm9yfSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlIGFuZCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBFcnJvcihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBFcnJvcn0gd2l0aCB0aGUgY3VycmVudCBzdGFjayB0cmFjZSwgdGhlCisgICAgICogc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlIGFuZCB0aGUgc3BlY2lmaWVkIGNhdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBlcnJvci4KKyAgICAgKiBAcGFyYW0gdGhyb3dhYmxlCisgICAgICogICAgICAgICAgICB0aGUgY2F1c2Ugb2YgdGhpcyBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgRXJyb3IoU3RyaW5nIGRldGFpbE1lc3NhZ2UsIFRocm93YWJsZSB0aHJvd2FibGUpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSwgdGhyb3dhYmxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBFcnJvcn0gd2l0aCB0aGUgY3VycmVudCBzdGFjayB0cmFjZSBhbmQgdGhlCisgICAgICogc3BlY2lmaWVkIGNhdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIHRocm93YWJsZQorICAgICAqICAgICAgICAgICAgdGhlIGNhdXNlIG9mIHRoaXMgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIEVycm9yKFRocm93YWJsZSB0aHJvd2FibGUpIHsKKyAgICAgICAgc3VwZXIodGhyb3dhYmxlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0V4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9FeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOTAxODk1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDczIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworCisvKioKKyAqIHtAY29kZSBFeGNlcHRpb259IGlzIHRoZSBzdXBlcmNsYXNzIG9mIGFsbCBjbGFzc2VzIHRoYXQgcmVwcmVzZW50IHJlY292ZXJhYmxlCisgKiBleGNlcHRpb25zLiBXaGVuIGV4Y2VwdGlvbnMgYXJlIHRocm93biwgdGhleSBtYXkgYmUgY2F1Z2h0IGJ5IGFwcGxpY2F0aW9uCisgKiBjb2RlLgorICoKKyAqIEBzZWUgVGhyb3dhYmxlCisgKiBAc2VlIEVycm9yCisgKiBAc2VlIFJ1bnRpbWVFeGNlcHRpb24KKyAqLworcHVibGljIGNsYXNzIEV4Y2VwdGlvbiBleHRlbmRzIFRocm93YWJsZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTMzODc1MTY5OTMxMjQyMjk5NDhMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRXhjZXB0aW9ufSB0aGF0IGluY2x1ZGVzIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRXhjZXB0aW9ufSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlIGFuZCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEV4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudCBzdGFjayB0cmFjZSwgdGhlCisgICAgICogc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlIGFuZCB0aGUgc3BlY2lmaWVkIGNhdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICogQHBhcmFtIHRocm93YWJsZQorICAgICAqICAgICAgICAgICAgdGhlIGNhdXNlIG9mIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UsIFRocm93YWJsZSB0aHJvd2FibGUpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSwgdGhyb3dhYmxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQgc3RhY2sgdHJhY2UgYW5kIHRoZQorICAgICAqIHNwZWNpZmllZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYXVzZSBvZiB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgRXhjZXB0aW9uKFRocm93YWJsZSB0aHJvd2FibGUpIHsKKyAgICAgICAgc3VwZXIodGhyb3dhYmxlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0V4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9FeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMmViNzU3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9FeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3IuamF2YQpAQCAtMCwwICsxLDgwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gd2hlbiBhbiBleGNlcHRpb24gb2NjdXJzIGR1cmluZyBjbGFzcyBpbml0aWFsaXphdGlvbi4KKyAqLworcHVibGljIGNsYXNzIEV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvciBleHRlbmRzIExpbmthZ2VFcnJvciB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxNTIxNzExNzkyMjE3MjMyMjU2TDsKKworICAgIHByaXZhdGUgVGhyb3dhYmxlIGV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvcn0gdGhhdCBpbmNsdWRlcyB0aGUKKyAgICAgKiBjdXJyZW50IHN0YWNrIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBFeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3IoKSB7CisgICAgICAgIGluaXRDYXVzZShudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBFeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3J9IHdpdGggdGhlIGN1cnJlbnQKKyAgICAgKiBzdGFjayB0cmFjZSBhbmQgdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIEV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvcihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICAgICAgaW5pdENhdXNlKG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvcn0gd2l0aCB0aGUgY3VycmVudAorICAgICAqIHN0YWNrIHRyYWNlIGFuZCB0aGUgc3BlY2lmaWVkIGNhdXNlLiBUaGUgZXhjZXB0aW9uIHNob3VsZCBiZSB0aGUgb25lCisgICAgICogd2hpY2ggb3JpZ2luYWxseSBvY2N1cnJlZCBpbiB0aGUgY2xhc3MgaW5pdGlhbGl6YXRpb24gY29kZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNlcHRpb24gdGhhdCBjYXVzZWQgdGhpcyBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgRXhjZXB0aW9uSW5Jbml0aWFsaXplckVycm9yKFRocm93YWJsZSBleGNlcHRpb24pIHsKKyAgICAgICAgdGhpcy5leGNlcHRpb24gPSBleGNlcHRpb247CisgICAgICAgIGluaXRDYXVzZShleGNlcHRpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGV4Y2VwdGlvbiB0aGF0IGlzIHRoZSBjYXVzZSBvZiB0aGlzIGVycm9yLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZXhjZXB0aW9uIHRoYXQgY2F1c2VkIHRoaXMgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIFRocm93YWJsZSBnZXRFeGNlcHRpb24oKSB7CisgICAgICAgIHJldHVybiBleGNlcHRpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2F1c2Ugb2YgdGhpcyBlcnJvciwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIG5vIGNhdXNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZXhjZXB0aW9uIHRoYXQgY2F1c2VkIHRoaXMgZXJyb3IuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFRocm93YWJsZSBnZXRDYXVzZSgpIHsKKyAgICAgICAgcmV0dXJuIGV4Y2VwdGlvbjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0ZpbmRCdWdzU3VwcHJlc3NXYXJuaW5ncy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9GaW5kQnVnc1N1cHByZXNzV2FybmluZ3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYzc1M2JkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9GaW5kQnVnc1N1cHByZXNzV2FybmluZ3MuamF2YQpAQCAtMCwwICsxLDQ2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKK2ltcG9ydCBzdGF0aWMgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGUuQ09OU1RSVUNUT1I7CitpbXBvcnQgc3RhdGljIGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlLkZJRUxEOworaW1wb3J0IHN0YXRpYyBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZS5MT0NBTF9WQVJJQUJMRTsKK2ltcG9ydCBzdGF0aWMgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGUuTUVUSE9EOworaW1wb3J0IHN0YXRpYyBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZS5QQVJBTUVURVI7CitpbXBvcnQgc3RhdGljIGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlLlRZUEU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOworaW1wb3J0IHN0YXRpYyBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3kuQ0xBU1M7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OworCisvKioKKyAqIFN1cHByZXNzIEZpbmRCdWdzIHdhcm5pbmdzIG9uIHRoZSBhbm5vdGF0ZWQgZWxlbWVudC4gRmluZEJ1Z3Mgd2lsbCByZWNvZ25pemUKKyAqIGFueSBhbm5vdGF0aW9uIHRoYXQgaGFzIGNsYXNzIHJldGVudGlvbiBhbmQgd2hvc2UgbmFtZSBlbmRzIHdpdGgKKyAqICJTdXBwcmVzc1dhcm5pbmdzIi4KKyAqCisgKiBAaGlkZQorICovCitAVGFyZ2V0KHtUWVBFLCBGSUVMRCwgTUVUSE9ELCBQQVJBTUVURVIsIENPTlNUUlVDVE9SLCBMT0NBTF9WQVJJQUJMRX0pCitAUmV0ZW50aW9uKENMQVNTKQorcHVibGljIEBpbnRlcmZhY2UgRmluZEJ1Z3NTdXBwcmVzc1dhcm5pbmdzIHsKKworICAgIC8qKgorICAgICAqIFRoZSA8YSBocmVmPSJodHRwOi8vZmluZGJ1Z3Muc291cmNlZm9yZ2UubmV0L2J1Z0Rlc2NyaXB0aW9ucy5odG1sIj5GaW5kQnVncworICAgICAqIFBhdHRlcm5zPC9hPiB0byBzdXBwcmVzcywgc3VjaCBhcyB7QGNvZGUgU0VfVFJBTlNJRU5UX0ZJRUxEX05PVF9SRVNUT1JFRH0KKyAgICAgKiBvciB7QGNvZGUgU2V9LiBGdWxsLCB1cHBlciBjYXNlIG5hbWVzIGFyZSBwcmVmZXJyZWQuCisgICAgICovCisgICAgU3RyaW5nW10gdmFsdWUoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvRmxvYXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvRmxvYXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MDBiMmEwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9GbG9hdC5qYXZhCkBAIC0wLDAgKzEsNDkxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaGUgd3JhcHBlciBmb3IgdGhlIHByaW1pdGl2ZSB0eXBlIHtAY29kZSBmbG9hdH0uCisgKgorICogQHNlZSBqYXZhLmxhbmcuTnVtYmVyCisgKiBAc2luY2UgMS4wCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBGbG9hdCBleHRlbmRzIE51bWJlciBpbXBsZW1lbnRzIENvbXBhcmFibGU8RmxvYXQ+IHsKKyAgICBzdGF0aWMgZmluYWwgaW50IEVYUE9ORU5UX0JJQVMgPSAxMjc7CisKKyAgICBzdGF0aWMgZmluYWwgaW50IEVYUE9ORU5UX0JJVFMgPSA5OworICAgIHN0YXRpYyBmaW5hbCBpbnQgTUFOVElTU0FfQklUUyA9IDIzOworICAgIHN0YXRpYyBmaW5hbCBpbnQgTk9OX01BTlRJU1NBX0JJVFMgPSA5OworCisgICAgc3RhdGljIGZpbmFsIGludCBTSUdOX01BU0sgICAgID0gMHg4MDAwMDAwMDsKKyAgICBzdGF0aWMgZmluYWwgaW50IEVYUE9ORU5UX01BU0sgPSAweDdmODAwMDAwOworICAgIHN0YXRpYyBmaW5hbCBpbnQgTUFOVElTU0FfTUFTSyA9IDB4MDA3ZmZmZmY7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjY3MTI1NzMwMjY2MDc0NzAyOEw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdmFsdWUgd2hpY2ggdGhlIHJlY2VpdmVyIHJlcHJlc2VudHMuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBmbG9hdCB2YWx1ZTsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IGZvciB0aGUgbWF4aW11bSB7QGNvZGUgZmxvYXR9IHZhbHVlLCAoMiAtIDI8c3VwPi0yMzwvc3VwPikgKiAyPHN1cD4xMjc8L3N1cD4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBmbG9hdCBNQVhfVkFMVUUgPSAzLjQwMjgyMzQ2NjM4NTI4ODYwZSszOGY7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCBmb3IgdGhlIG1pbmltdW0ge0Bjb2RlIGZsb2F0fSB2YWx1ZSwgMjxzdXA+LTE0OTwvc3VwPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGZsb2F0IE1JTl9WQUxVRSA9IDEuNDAxMjk4NDY0MzI0ODE3MDdlLTQ1ZjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IGZvciB0aGUgTm90LWEtTnVtYmVyIChOYU4pIHZhbHVlIG9mIHRoZSB7QGNvZGUgZmxvYXR9IHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBmbG9hdCBOYU4gPSAwLjBmIC8gMC4wZjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IGZvciB0aGUgcG9zaXRpdmUgaW5maW5pdHkgdmFsdWUgb2YgdGhlIHtAY29kZSBmbG9hdH0gdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGZsb2F0IFBPU0lUSVZFX0lORklOSVRZID0gMS4wZiAvIDAuMGY7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCBmb3IgdGhlIG5lZ2F0aXZlIGluZmluaXR5IHZhbHVlIG9mIHRoZSB7QGNvZGUgZmxvYXR9IHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBmbG9hdCBORUdBVElWRV9JTkZJTklUWSA9IC0xLjBmIC8gMC4wZjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IGZvciB0aGUgc21hbGxlc3QgcG9zaXRpdmUgbm9ybWFsIHZhbHVlIG9mIHRoZSB7QGNvZGUgZmxvYXR9IHR5cGUuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBmbG9hdCBNSU5fTk9STUFMID0gMS4xNzU0OTQzNTA4MjIyODc1RS0zOGY7CisKKyAgICAvKioKKyAgICAgKiBNYXhpbXVtIGJhc2UtMiBleHBvbmVudCB0aGF0IGEgZmluaXRlIHZhbHVlIG9mIHRoZSB7QGNvZGUgZmxvYXR9IHR5cGUgbWF5IGhhdmUuCisgICAgICogRXF1YWwgdG8ge0Bjb2RlIE1hdGguZ2V0RXhwb25lbnQoRmxvYXQuTUFYX1ZBTFVFKX0uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0VYUE9ORU5UID0gMTI3OworCisgICAgLyoqCisgICAgICogTWluaW11bSBiYXNlLTIgZXhwb25lbnQgdGhhdCBhIG5vcm1hbCB2YWx1ZSBvZiB0aGUge0Bjb2RlIGZsb2F0fSB0eXBlIG1heSBoYXZlLgorICAgICAqIEVxdWFsIHRvIHtAY29kZSBNYXRoLmdldEV4cG9uZW50KEZsb2F0Lk1JTl9OT1JNQUwpfS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNSU5fRVhQT05FTlQgPSAtMTI2OworCisgICAgLyoqCisgICAgICogVGhlIHtAbGluayBDbGFzc30gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcHJpbWl0aXZlIHR5cGUge0Bjb2RlCisgICAgICogZmxvYXR9LgorICAgICAqCisgICAgICogQHNpbmNlIDEuMQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3M8RmxvYXQ+IFRZUEUKKyAgICAgICAgICAgID0gKENsYXNzPEZsb2F0PikgZmxvYXRbXS5jbGFzcy5nZXRDb21wb25lbnRUeXBlKCk7CisgICAgLy8gTm90ZTogRmxvYXQuVFlQRSBjYW4ndCBiZSBzZXQgdG8gImZsb2F0LmNsYXNzIiwgc2luY2UgKnRoYXQqIGlzCisgICAgLy8gZGVmaW5lZCB0byBiZSAiamF2YS5sYW5nLkZsb2F0LlRZUEUiOworCisgICAgLyoqCisgICAgICogQ29uc3RhbnQgZm9yIHRoZSBudW1iZXIgb2YgYml0cyBuZWVkZWQgdG8gcmVwcmVzZW50IGEge0Bjb2RlIGZsb2F0fSBpbgorICAgICAqIHR3bydzIGNvbXBsZW1lbnQgZm9ybS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSVpFID0gMzI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBGbG9hdH0gd2l0aCB0aGUgc3BlY2lmaWVkIHByaW1pdGl2ZSBmbG9hdCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHByaW1pdGl2ZSBmbG9hdCB2YWx1ZSB0byBzdG9yZSBpbiB0aGUgbmV3IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBGbG9hdChmbG9hdCB2YWx1ZSkgeworICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRmxvYXR9IHdpdGggdGhlIHNwZWNpZmllZCBwcmltaXRpdmUgZG91YmxlIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgcHJpbWl0aXZlIGRvdWJsZSB2YWx1ZSB0byBzdG9yZSBpbiB0aGUgbmV3IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBGbG9hdChkb3VibGUgdmFsdWUpIHsKKyAgICAgICAgdGhpcy52YWx1ZSA9IChmbG9hdCkgdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRmxvYXR9IGZyb20gdGhlIHNwZWNpZmllZCBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgZmxvYXQgdmFsdWUuCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyaW5nfSBjYW4gbm90IGJlIHBhcnNlZCBhcyBhIGZsb2F0IHZhbHVlLgorICAgICAqIEBzZWUgI3BhcnNlRmxvYXQoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBGbG9hdChTdHJpbmcgc3RyaW5nKSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhwYXJzZUZsb2F0KHN0cmluZykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoaXMgb2JqZWN0IHRvIHRoZSBzcGVjaWZpZWQgZmxvYXQgb2JqZWN0IHRvIGRldGVybWluZSB0aGVpcgorICAgICAqIHJlbGF0aXZlIG9yZGVyLiBUaGVyZSBhcmUgdHdvIHNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgRmxvYXQuTmFOfSBpcyBlcXVhbCB0byB7QGNvZGUgRmxvYXQuTmFOfSBhbmQgaXQgaXMgZ3JlYXRlcgorICAgICAqIHRoYW4gYW55IG90aGVyIGZsb2F0IHZhbHVlLCBpbmNsdWRpbmcge0Bjb2RlIEZsb2F0LlBPU0lUSVZFX0lORklOSVRZfTs8L2xpPgorICAgICAqIDxsaT4rMC4wZiBpcyBncmVhdGVyIHRoYW4gLTAuMGY8L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgZmxvYXQgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyBvYmplY3QgdG8uCisgICAgICogQHJldHVybiBhIG5lZ2F0aXZlIHZhbHVlIGlmIHRoZSB2YWx1ZSBvZiB0aGlzIGZsb2F0IGlzIGxlc3MgdGhhbiB0aGUKKyAgICAgKiAgICAgICAgIHZhbHVlIG9mIHtAY29kZSBvYmplY3R9OyAwIGlmIHRoZSB2YWx1ZSBvZiB0aGlzIGZsb2F0IGFuZCB0aGUKKyAgICAgKiAgICAgICAgIHZhbHVlIG9mIHtAY29kZSBvYmplY3R9IGFyZSBlcXVhbDsgYSBwb3NpdGl2ZSB2YWx1ZSBpZiB0aGUgdmFsdWUKKyAgICAgKiAgICAgICAgIG9mIHRoaXMgZmxvYXQgaXMgZ3JlYXRlciB0aGFuIHRoZSB2YWx1ZSBvZiB7QGNvZGUgb2JqZWN0fS4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5Db21wYXJhYmxlCisgICAgICogQHNpbmNlIDEuMgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKEZsb2F0IG9iamVjdCkgeworICAgICAgICByZXR1cm4gY29tcGFyZSh2YWx1ZSwgb2JqZWN0LnZhbHVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZSBieXRlVmFsdWUoKSB7CisgICAgICAgIHJldHVybiAoYnl0ZSkgdmFsdWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGRvdWJsZSBkb3VibGVWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHRoaXMgZG91YmxlIGZvciBlcXVhbGl0eSB3aXRoIHtAY29kZSBvYmplY3R9LgorICAgICAqIFRvIGJlIGVxdWFsLCB7QGNvZGUgb2JqZWN0fSBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIHtAY29kZSBGbG9hdH0gYW5kCisgICAgICoge0Bjb2RlIGZsb2F0VG9JbnRCaXRzfSBtdXN0IGdpdmUgdGhlIHNhbWUgdmFsdWUgZm9yIGJvdGggb2JqZWN0cy4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCwgdW5saWtlIHtAY29kZSA9PX0sIHtAY29kZSAtMC4wfSBhbmQge0Bjb2RlICswLjB9IGNvbXBhcmUKKyAgICAgKiB1bmVxdWFsLCBhbmQge0Bjb2RlIE5hTn1zIGNvbXBhcmUgZXF1YWwgYnkgdGhpcyBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyBmbG9hdCB3aXRoLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBGbG9hdH07IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIHJldHVybiAob2JqZWN0IGluc3RhbmNlb2YgRmxvYXQpICYmCisgICAgICAgICAgICAgICAgKGZsb2F0VG9JbnRCaXRzKHRoaXMudmFsdWUpID09IGZsb2F0VG9JbnRCaXRzKCgoRmxvYXQpIG9iamVjdCkudmFsdWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGludGVnZXIgY29ycmVzcG9uZGluZyB0byB0aGUgYml0cyBvZiB0aGUgZ2l2ZW4KKyAgICAgKiA8YSBocmVmPSJodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lFRUVfNzU0LTE5ODUiPklFRUUgNzU0PC9hPiBzaW5nbGUgcHJlY2lzaW9uCisgICAgICogZmxvYXQge0Bjb2RlIHZhbHVlfS4gQWxsIDxlbT5Ob3QtYS1OdW1iZXIgKE5hTik8L2VtPiB2YWx1ZXMgYXJlIGNvbnZlcnRlZCB0byBhIHNpbmdsZSBOYU4KKyAgICAgKiByZXByZXNlbnRhdGlvbiAoe0Bjb2RlIDB4N2ZjMDAwMDB9KSAoY29tcGFyZSB0byB7QGxpbmsgI2Zsb2F0VG9SYXdJbnRCaXRzfSkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IGZsb2F0VG9JbnRCaXRzKGZsb2F0IHZhbHVlKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW50ZWdlciBjb3JyZXNwb25kaW5nIHRvIHRoZSBiaXRzIG9mIHRoZSBnaXZlbgorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSUVFRV83NTQtMTk4NSI+SUVFRSA3NTQ8L2E+IHNpbmdsZSBwcmVjaXNpb24KKyAgICAgKiBmbG9hdCB7QGNvZGUgdmFsdWV9LiA8ZW0+Tm90LWEtTnVtYmVyIChOYU4pPC9lbT4gdmFsdWVzIGFyZSBwcmVzZXJ2ZWQgKGNvbXBhcmUKKyAgICAgKiB0byB7QGxpbmsgI2Zsb2F0VG9JbnRCaXRzfSkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IGZsb2F0VG9SYXdJbnRCaXRzKGZsb2F0IHZhbHVlKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHByaW1pdGl2ZSB2YWx1ZSBvZiB0aGlzIGZsb2F0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIG9iamVjdCdzIHByaW1pdGl2ZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXQgZmxvYXRWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiBmbG9hdFRvSW50Qml0cyh2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgPGEgaHJlZj0iaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JRUVFXzc1NC0xOTg1Ij5JRUVFIDc1NDwvYT4KKyAgICAgKiBzaW5nbGUgcHJlY2lzaW9uIGZsb2F0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIHtAY29kZSBiaXRzfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBmbG9hdCBpbnRCaXRzVG9GbG9hdChpbnQgYml0cyk7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGludFZhbHVlKCkgeworICAgICAgICByZXR1cm4gKGludCkgdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBvYmplY3QgcmVwcmVzZW50cyBhbiBpbmZpbml0ZSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSB2YWx1ZSBvZiB0aGlzIGZsb2F0IGlzIHBvc2l0aXZlIG9yIG5lZ2F0aXZlCisgICAgICogICAgICAgICBpbmZpbml0eTsge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNJbmZpbml0ZSgpIHsKKyAgICAgICAgcmV0dXJuIGlzSW5maW5pdGUodmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgZmxvYXQgcmVwcmVzZW50cyBhbiBpbmZpbml0ZSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmCisgICAgICogICAgICAgICAgICB0aGUgZmxvYXQgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHZhbHVlIG9mIHtAY29kZSBmfSBpcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZQorICAgICAqICAgICAgICAgaW5maW5pdHk7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0luZmluaXRlKGZsb2F0IGYpIHsKKyAgICAgICAgcmV0dXJuIChmID09IFBPU0lUSVZFX0lORklOSVRZKSB8fCAoZiA9PSBORUdBVElWRV9JTkZJTklUWSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBvYmplY3QgaXMgYSA8ZW0+Tm90LWEtTnVtYmVyIChOYU4pPC9lbT4gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGZsb2F0IGlzIDxlbT5Ob3QtYS1OdW1iZXI8L2VtPjsKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gaWYgaXQgaXMgYSAocG90ZW50aWFsbHkgaW5maW5pdGUpIGZsb2F0IG51bWJlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc05hTigpIHsKKyAgICAgICAgcmV0dXJuIGlzTmFOKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGZsb2F0IGlzIGEgPGVtPk5vdC1hLU51bWJlciAoTmFOKTwvZW0+CisgICAgICogdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZgorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IHZhbHVlIHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBmfSBpcyA8ZW0+Tm90LWEtTnVtYmVyPC9lbT47CisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IGlmIGl0IGlzIGEgKHBvdGVudGlhbGx5IGluZmluaXRlKSBmbG9hdCBudW1iZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTmFOKGZsb2F0IGYpIHsKKyAgICAgICAgcmV0dXJuIGYgIT0gZjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBsb25nVmFsdWUoKSB7CisgICAgICAgIHJldHVybiAobG9uZykgdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGFzIGEgZmxvYXQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgZmxvYXQgdmFsdWUuCisgICAgICogQHJldHVybiB0aGUgcHJpbWl0aXZlIGZsb2F0IHZhbHVlIHJlcHJlc2VudGVkIGJ5IHtAY29kZSBzdHJpbmd9LgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0cmluZ30gY2FuIG5vdCBiZSBwYXJzZWQgYXMgYSBmbG9hdCB2YWx1ZS4KKyAgICAgKiBAc2VlICN2YWx1ZU9mKFN0cmluZykKKyAgICAgKiBAc2luY2UgMS4yCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmbG9hdCBwYXJzZUZsb2F0KFN0cmluZyBzdHJpbmcpIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gU3RyaW5nVG9SZWFsLnBhcnNlRmxvYXQoc3RyaW5nKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc2hvcnQgc2hvcnRWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIChzaG9ydCkgdmFsdWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIEZsb2F0LnRvU3RyaW5nKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUKKyAgICAgKiBzcGVjaWZpZWQgZmxvYXQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZgorICAgICAqICAgICAgICAgICAgIHRoZSBmbG9hdCB0byBjb252ZXJ0IHRvIGEgc3RyaW5nLgorICAgICAqIEByZXR1cm4gYSBwcmludGFibGUgcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIGZ9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKGZsb2F0IGYpIHsKKyAgICAgICAgcmV0dXJuIFJlYWxUb1N0cmluZy5nZXRJbnN0YW5jZSgpLmZsb2F0VG9TdHJpbmcoZik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGFzIGEgZmxvYXQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgZmxvYXQgdmFsdWUuCisgICAgICogQHJldHVybiBhIHtAY29kZSBGbG9hdH0gaW5zdGFuY2UgY29udGFpbmluZyB0aGUgZmxvYXQgdmFsdWUgcmVwcmVzZW50ZWQKKyAgICAgKiAgICAgICAgIGJ5IHtAY29kZSBzdHJpbmd9LgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0cmluZ30gY2FuIG5vdCBiZSBwYXJzZWQgYXMgYSBmbG9hdCB2YWx1ZS4KKyAgICAgKiBAc2VlICNwYXJzZUZsb2F0KFN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEZsb2F0IHZhbHVlT2YoU3RyaW5nIHN0cmluZykgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBwYXJzZUZsb2F0KHN0cmluZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHR3byBzcGVjaWZpZWQgZmxvYXQgdmFsdWVzLiBUaGVyZSBhcmUgdHdvIHNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgRmxvYXQuTmFOfSBpcyBlcXVhbCB0byB7QGNvZGUgRmxvYXQuTmFOfSBhbmQgaXQgaXMgZ3JlYXRlcgorICAgICAqIHRoYW4gYW55IG90aGVyIGZsb2F0IHZhbHVlLCBpbmNsdWRpbmcge0Bjb2RlIEZsb2F0LlBPU0lUSVZFX0lORklOSVRZfTs8L2xpPgorICAgICAqIDxsaT4rMC4wZiBpcyBncmVhdGVyIHRoYW4gLTAuMGY8L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZmxvYXQxCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgdmFsdWUgdG8gY29tcGFyZS4KKyAgICAgKiBAcGFyYW0gZmxvYXQyCisgICAgICogICAgICAgICAgICB0aGUgc2Vjb25kIHZhbHVlIHRvIGNvbXBhcmUuCisgICAgICogQHJldHVybiBhIG5lZ2F0aXZlIHZhbHVlIGlmIHtAY29kZSBmbG9hdDF9IGlzIGxlc3MgdGhhbiB7QGNvZGUgZmxvYXQyfTsKKyAgICAgKiAgICAgICAgIDAgaWYge0Bjb2RlIGZsb2F0MX0gYW5kIHtAY29kZSBmbG9hdDJ9IGFyZSBlcXVhbDsgYSBwb3NpdGl2ZQorICAgICAqICAgICAgICAgdmFsdWUgaWYge0Bjb2RlIGZsb2F0MX0gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSBmbG9hdDJ9LgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBjb21wYXJlKGZsb2F0IGZsb2F0MSwgZmxvYXQgZmxvYXQyKSB7CisgICAgICAgIC8vIE5vbi16ZXJvLCBub24tTmFOIGNoZWNraW5nLgorICAgICAgICBpZiAoZmxvYXQxID4gZmxvYXQyKSB7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZmxvYXQyID4gZmxvYXQxKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZsb2F0MSA9PSBmbG9hdDIgJiYgMC4wZiAhPSBmbG9hdDEpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgLy8gTmFOcyBhcmUgZXF1YWwgdG8gb3RoZXIgTmFOcyBhbmQgbGFyZ2VyIHRoYW4gYW55IG90aGVyIGZsb2F0CisgICAgICAgIGlmIChpc05hTihmbG9hdDEpKSB7CisgICAgICAgICAgICBpZiAoaXNOYU4oZmxvYXQyKSkgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIH0gZWxzZSBpZiAoaXNOYU4oZmxvYXQyKSkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisKKyAgICAgICAgLy8gRGVhbCB3aXRoICswLjAgYW5kIC0wLjAKKyAgICAgICAgaW50IGYxID0gZmxvYXRUb1Jhd0ludEJpdHMoZmxvYXQxKTsKKyAgICAgICAgaW50IGYyID0gZmxvYXRUb1Jhd0ludEJpdHMoZmxvYXQyKTsKKyAgICAgICAgLy8gVGhlIGJlbG93IGV4cHJlc3Npb24gaXMgZXF1aXZhbGVudCB0bzoKKyAgICAgICAgLy8gKGYxID09IGYyKSA/IDAgOiAoZjEgPCBmMikgPyAtMSA6IDEKKyAgICAgICAgLy8gYmVjYXVzZSBmMSBhbmQgZjIgYXJlIGVpdGhlciAwIG9yIEludGVnZXIuTUlOX1ZBTFVFCisgICAgICAgIHJldHVybiAoZjEgPj4gMzEpIC0gKGYyID4+IDMxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIEZsb2F0fSBpbnN0YW5jZSBmb3IgdGhlIHNwZWNpZmllZCBmbG9hdCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmCisgICAgICogICAgICAgICAgICB0aGUgZmxvYXQgdmFsdWUgdG8gc3RvcmUgaW4gdGhlIGluc3RhbmNlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgRmxvYXR9IGluc3RhbmNlIGNvbnRhaW5pbmcge0Bjb2RlIGZ9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEZsb2F0IHZhbHVlT2YoZmxvYXQgZikgeworICAgICAgICByZXR1cm4gbmV3IEZsb2F0KGYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIHRoZSBzcGVjaWZpZWQgZmxvYXQgaW50byBpdHMgaGV4YWRlY2ltYWwgc3RyaW5nIHJlcHJlc2VudGF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGYKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbG9hdCB0byBjb252ZXJ0LgorICAgICAqIEByZXR1cm4gdGhlIGhleGFkZWNpbWFsIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUgZn0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvSGV4U3RyaW5nKGZsb2F0IGYpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogUmVmZXJlbmNlOiBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lFRUVfNzU0LTE5ODUKKyAgICAgICAgICovCisgICAgICAgIGlmIChmICE9IGYpIHsKKyAgICAgICAgICAgIHJldHVybiAiTmFOIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZiA9PSBQT1NJVElWRV9JTkZJTklUWSkgeworICAgICAgICAgICAgcmV0dXJuICJJbmZpbml0eSI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGYgPT0gTkVHQVRJVkVfSU5GSU5JVFkpIHsKKyAgICAgICAgICAgIHJldHVybiAiLUluZmluaXR5IjsKKyAgICAgICAgfQorCisgICAgICAgIGludCBiaXRWYWx1ZSA9IGZsb2F0VG9JbnRCaXRzKGYpOworCisgICAgICAgIGJvb2xlYW4gbmVnYXRpdmUgPSAoYml0VmFsdWUgJiAweDgwMDAwMDAwKSAhPSAwOworICAgICAgICAvLyBtYXNrIGV4cG9uZW50IGJpdHMgYW5kIHNoaWZ0IGRvd24KKyAgICAgICAgaW50IGV4cG9uZW50ID0gKGJpdFZhbHVlICYgMHg3ZjgwMDAwMCkgPj4+IDIzOworICAgICAgICAvLyBtYXNrIHNpZ25pZmljYW5kIGJpdHMgYW5kIHNoaWZ0IHVwCisgICAgICAgIC8vIHNpZ25pZmljYW5kIGlzIDIzLWJpdHMsIHNvIHdlIHNoaWZ0IHRvIHRyZWF0IGl0IGxpa2UgMjQtYml0cworICAgICAgICBpbnQgc2lnbmlmaWNhbmQgPSAoYml0VmFsdWUgJiAweDAwN0ZGRkZGKSA8PCAxOworCisgICAgICAgIGlmIChleHBvbmVudCA9PSAwICYmIHNpZ25pZmljYW5kID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAobmVnYXRpdmUgPyAiLTB4MC4wcDAiIDogIjB4MC4wcDAiKTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ0J1aWxkZXIgaGV4U3RyaW5nID0gbmV3IFN0cmluZ0J1aWxkZXIoMTApOworICAgICAgICBpZiAobmVnYXRpdmUpIHsKKyAgICAgICAgICAgIGhleFN0cmluZy5hcHBlbmQoIi0weCIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaGV4U3RyaW5nLmFwcGVuZCgiMHgiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChleHBvbmVudCA9PSAwKSB7IC8vIGRlbm9ybWFsIChzdWJub3JtYWwpIHZhbHVlCisgICAgICAgICAgICBoZXhTdHJpbmcuYXBwZW5kKCIwLiIpOworICAgICAgICAgICAgLy8gc2lnbmlmaWNhbmQgaXMgMjMtYml0cywgc28gdGhlcmUgY2FuIGJlIDYgaGV4IGRpZ2l0cworICAgICAgICAgICAgaW50IGZyYWN0aW9uRGlnaXRzID0gNjsKKyAgICAgICAgICAgIC8vIHJlbW92ZSB0cmFpbGluZyBoZXggemVyb3MsIHNvIEludGVnZXIudG9IZXhTdHJpbmcoKSB3b24ndCBwcmludAorICAgICAgICAgICAgLy8gdGhlbQorICAgICAgICAgICAgd2hpbGUgKChzaWduaWZpY2FuZCAhPSAwKSAmJiAoKHNpZ25pZmljYW5kICYgMHhGKSA9PSAwKSkgeworICAgICAgICAgICAgICAgIHNpZ25pZmljYW5kID4+Pj0gNDsKKyAgICAgICAgICAgICAgICBmcmFjdGlvbkRpZ2l0cy0tOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gdGhpcyBhc3N1bWVzIEludGVnZXIudG9IZXhTdHJpbmcoKSByZXR1cm5zIGxvd2VyY2FzZSBjaGFyYWN0ZXJzCisgICAgICAgICAgICBTdHJpbmcgaGV4U2lnbmlmaWNhbmQgPSBJbnRlZ2VyLnRvSGV4U3RyaW5nKHNpZ25pZmljYW5kKTsKKworICAgICAgICAgICAgLy8gaWYgdGhlcmUgYXJlIGRpZ2l0cyBsZWZ0LCB0aGVuIGluc2VydCBzb21lICcwJyBjaGFycyBmaXJzdAorICAgICAgICAgICAgaWYgKHNpZ25pZmljYW5kICE9IDAgJiYgZnJhY3Rpb25EaWdpdHMgPiBoZXhTaWduaWZpY2FuZC5sZW5ndGgoKSkgeworICAgICAgICAgICAgICAgIGludCBkaWdpdERpZmYgPSBmcmFjdGlvbkRpZ2l0cyAtIGhleFNpZ25pZmljYW5kLmxlbmd0aCgpOworICAgICAgICAgICAgICAgIHdoaWxlIChkaWdpdERpZmYtLSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGhleFN0cmluZy5hcHBlbmQoJzAnKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBoZXhTdHJpbmcuYXBwZW5kKGhleFNpZ25pZmljYW5kKTsKKyAgICAgICAgICAgIGhleFN0cmluZy5hcHBlbmQoInAtMTI2Iik7CisgICAgICAgIH0gZWxzZSB7IC8vIG5vcm1hbCB2YWx1ZQorICAgICAgICAgICAgaGV4U3RyaW5nLmFwcGVuZCgiMS4iKTsKKyAgICAgICAgICAgIC8vIHNpZ25pZmljYW5kIGlzIDIzLWJpdHMsIHNvIHRoZXJlIGNhbiBiZSA2IGhleCBkaWdpdHMKKyAgICAgICAgICAgIGludCBmcmFjdGlvbkRpZ2l0cyA9IDY7CisgICAgICAgICAgICAvLyByZW1vdmUgdHJhaWxpbmcgaGV4IHplcm9zLCBzbyBJbnRlZ2VyLnRvSGV4U3RyaW5nKCkgd29uJ3QgcHJpbnQKKyAgICAgICAgICAgIC8vIHRoZW0KKyAgICAgICAgICAgIHdoaWxlICgoc2lnbmlmaWNhbmQgIT0gMCkgJiYgKChzaWduaWZpY2FuZCAmIDB4RikgPT0gMCkpIHsKKyAgICAgICAgICAgICAgICBzaWduaWZpY2FuZCA+Pj49IDQ7CisgICAgICAgICAgICAgICAgZnJhY3Rpb25EaWdpdHMtLTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIHRoaXMgYXNzdW1lcyBJbnRlZ2VyLnRvSGV4U3RyaW5nKCkgcmV0dXJucyBsb3dlcmNhc2UgY2hhcmFjdGVycworICAgICAgICAgICAgU3RyaW5nIGhleFNpZ25pZmljYW5kID0gSW50ZWdlci50b0hleFN0cmluZyhzaWduaWZpY2FuZCk7CisKKyAgICAgICAgICAgIC8vIGlmIHRoZXJlIGFyZSBkaWdpdHMgbGVmdCwgdGhlbiBpbnNlcnQgc29tZSAnMCcgY2hhcnMgZmlyc3QKKyAgICAgICAgICAgIGlmIChzaWduaWZpY2FuZCAhPSAwICYmIGZyYWN0aW9uRGlnaXRzID4gaGV4U2lnbmlmaWNhbmQubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgICAgICBpbnQgZGlnaXREaWZmID0gZnJhY3Rpb25EaWdpdHMgLSBoZXhTaWduaWZpY2FuZC5sZW5ndGgoKTsKKyAgICAgICAgICAgICAgICB3aGlsZSAoZGlnaXREaWZmLS0gIT0gMCkgeworICAgICAgICAgICAgICAgICAgICBoZXhTdHJpbmcuYXBwZW5kKCcwJyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaGV4U3RyaW5nLmFwcGVuZChoZXhTaWduaWZpY2FuZCk7CisgICAgICAgICAgICBoZXhTdHJpbmcuYXBwZW5kKCdwJyk7CisgICAgICAgICAgICAvLyByZW1vdmUgZXhwb25lbnQncyAnYmlhcycgYW5kIGNvbnZlcnQgdG8gYSBzdHJpbmcKKyAgICAgICAgICAgIGhleFN0cmluZy5hcHBlbmQoZXhwb25lbnQgLSAxMjcpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBoZXhTdHJpbmcudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0hleFN0cmluZ1BhcnNlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9IZXhTdHJpbmdQYXJzZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NTkzYjk5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9IZXhTdHJpbmdQYXJzZXIuamF2YQpAQCAtMCwwICsxLDMxNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguTWF0Y2hlcjsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKKworLyoKKyAqIFBhcnNlcyBoZXggc3RyaW5nIHRvIGEgc2luZ2xlIG9yIGRvdWJsZSBwcmVjaXNpb24gZmxvYXRpbmcgcG9pbnQgbnVtYmVyLgorICoKKyAqIFRPRE86IHJld3JpdGUgdGhpcyEKKyAqCisgKiBAaGlkZQorICovCitmaW5hbCBjbGFzcyBIZXhTdHJpbmdQYXJzZXIgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERPVUJMRV9FWFBPTkVOVF9XSURUSCA9IDExOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERPVUJMRV9NQU5USVNTQV9XSURUSCA9IDUyOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEZMT0FUX0VYUE9ORU5UX1dJRFRIID0gODsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGTE9BVF9NQU5USVNTQV9XSURUSCA9IDIzOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEhFWF9SQURJWCA9IDE2OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9TSUdOSUZJQ0FOVF9MRU5HVEggPSAxNTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBIRVhfU0lHTklGSUNBTlQgPSAiMFt4WF0oXFxwe1hEaWdpdH0rXFwuP3xcXHB7WERpZ2l0fSpcXC5cXHB7WERpZ2l0fSspIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBCSU5BUllfRVhQT05FTlQgPSAiW3BQXShbKy1dP1xcZCspIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGTE9BVF9UWVBFX1NVRkZJWCA9ICJbZkZkRF0/IjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBIRVhfUEFUVEVSTiA9ICJbXFx4MDAtXFx4MjBdKihbKy1dPykiICsgSEVYX1NJR05JRklDQU5UCisgICAgICAgICAgICArIEJJTkFSWV9FWFBPTkVOVCArIEZMT0FUX1RZUEVfU1VGRklYICsgIltcXHgwMC1cXHgyMF0qIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gUEFUVEVSTiA9IFBhdHRlcm4uY29tcGlsZShIRVhfUEFUVEVSTik7CisKKyAgICBwcml2YXRlIGZpbmFsIGludCBFWFBPTkVOVF9XSURUSDsKKworICAgIHByaXZhdGUgZmluYWwgaW50IE1BTlRJU1NBX1dJRFRIOworCisgICAgcHJpdmF0ZSBmaW5hbCBsb25nIEVYUE9ORU5UX0JBU0U7CisKKyAgICBwcml2YXRlIGZpbmFsIGxvbmcgTUFYX0VYUE9ORU5UOworCisgICAgcHJpdmF0ZSBmaW5hbCBsb25nIE1JTl9FWFBPTkVOVDsKKworICAgIHByaXZhdGUgZmluYWwgbG9uZyBNQU5USVNTQV9NQVNLOworCisgICAgcHJpdmF0ZSBsb25nIHNpZ247CisKKyAgICBwcml2YXRlIGxvbmcgZXhwb25lbnQ7CisKKyAgICBwcml2YXRlIGxvbmcgbWFudGlzc2E7CisKKyAgICBwcml2YXRlIFN0cmluZyBhYmFuZG9uZWROdW1iZXI9IiI7CisKKyAgICBwdWJsaWMgSGV4U3RyaW5nUGFyc2VyKGludCBleHBvbmVudFdpZHRoLCBpbnQgbWFudGlzc2FXaWR0aCkgeworICAgICAgICB0aGlzLkVYUE9ORU5UX1dJRFRIID0gZXhwb25lbnRXaWR0aDsKKyAgICAgICAgdGhpcy5NQU5USVNTQV9XSURUSCA9IG1hbnRpc3NhV2lkdGg7CisKKyAgICAgICAgdGhpcy5FWFBPTkVOVF9CQVNFID0gfigtMUwgPDwgKGV4cG9uZW50V2lkdGggLSAxKSk7CisgICAgICAgIHRoaXMuTUFYX0VYUE9ORU5UID0gfigtMUwgPDwgZXhwb25lbnRXaWR0aCk7CisgICAgICAgIHRoaXMuTUlOX0VYUE9ORU5UID0gLShNQU5USVNTQV9XSURUSCArIDEpOworICAgICAgICB0aGlzLk1BTlRJU1NBX01BU0sgPSB+KC0xTCA8PCBtYW50aXNzYVdpZHRoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFBhcnNlcyB0aGUgaGV4IHN0cmluZyB0byBhIGRvdWJsZSBudW1iZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgcGFyc2VEb3VibGUoU3RyaW5nIGhleFN0cmluZykgeworICAgICAgICBIZXhTdHJpbmdQYXJzZXIgcGFyc2VyID0gbmV3IEhleFN0cmluZ1BhcnNlcihET1VCTEVfRVhQT05FTlRfV0lEVEgsIERPVUJMRV9NQU5USVNTQV9XSURUSCk7CisgICAgICAgIGxvbmcgcmVzdWx0ID0gcGFyc2VyLnBhcnNlKGhleFN0cmluZywgdHJ1ZSk7CisgICAgICAgIHJldHVybiBEb3VibGUubG9uZ0JpdHNUb0RvdWJsZShyZXN1bHQpOworICAgIH0KKworICAgIC8qCisgICAgICogUGFyc2VzIHRoZSBoZXggc3RyaW5nIHRvIGEgZmxvYXQgbnVtYmVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmxvYXQgcGFyc2VGbG9hdChTdHJpbmcgaGV4U3RyaW5nKSB7CisgICAgICAgIEhleFN0cmluZ1BhcnNlciBwYXJzZXIgPSBuZXcgSGV4U3RyaW5nUGFyc2VyKEZMT0FUX0VYUE9ORU5UX1dJRFRILCBGTE9BVF9NQU5USVNTQV9XSURUSCk7CisgICAgICAgIGludCByZXN1bHQgPSAoaW50KSBwYXJzZXIucGFyc2UoaGV4U3RyaW5nLCBmYWxzZSk7CisgICAgICAgIHJldHVybiBGbG9hdC5pbnRCaXRzVG9GbG9hdChyZXN1bHQpOworICAgIH0KKworICAgIHByaXZhdGUgbG9uZyBwYXJzZShTdHJpbmcgaGV4U3RyaW5nLCBib29sZWFuIGlzRG91YmxlKSB7CisgICAgICAgIE1hdGNoZXIgbWF0Y2hlciA9IFBBVFRFUk4ubWF0Y2hlcihoZXhTdHJpbmcpOworICAgICAgICBpZiAoIW1hdGNoZXIubWF0Y2hlcygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkIGhleCAiICsgKGlzRG91YmxlID8gImRvdWJsZSIgOiAiZmxvYXQiKSsgIjoiICsKKyAgICAgICAgICAgICAgICAgICAgaGV4U3RyaW5nKTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBzaWduU3RyID0gbWF0Y2hlci5ncm91cCgxKTsKKyAgICAgICAgU3RyaW5nIHNpZ25pZmljYW50U3RyID0gbWF0Y2hlci5ncm91cCgyKTsKKyAgICAgICAgU3RyaW5nIGV4cG9uZW50U3RyID0gbWF0Y2hlci5ncm91cCgzKTsKKworICAgICAgICBwYXJzZUhleFNpZ24oc2lnblN0cik7CisgICAgICAgIHBhcnNlRXhwb25lbnQoZXhwb25lbnRTdHIpOworICAgICAgICBwYXJzZU1hbnRpc3NhKHNpZ25pZmljYW50U3RyKTsKKworICAgICAgICBzaWduIDw8PSAoTUFOVElTU0FfV0lEVEggKyBFWFBPTkVOVF9XSURUSCk7CisgICAgICAgIGV4cG9uZW50IDw8PSBNQU5USVNTQV9XSURUSDsKKyAgICAgICAgcmV0dXJuIHNpZ24gfCBleHBvbmVudCB8IG1hbnRpc3NhOworICAgIH0KKworICAgIC8qCisgICAgICogUGFyc2VzIHRoZSBzaWduIGZpZWxkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwYXJzZUhleFNpZ24oU3RyaW5nIHNpZ25TdHIpIHsKKyAgICAgICAgdGhpcy5zaWduID0gc2lnblN0ci5lcXVhbHMoIi0iKSA/IDEgOiAwOworICAgIH0KKworICAgIC8qCisgICAgICogUGFyc2VzIHRoZSBleHBvbmVudCBmaWVsZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcGFyc2VFeHBvbmVudChTdHJpbmcgZXhwb25lbnRTdHIpIHsKKyAgICAgICAgY2hhciBsZWFkaW5nQ2hhciA9IGV4cG9uZW50U3RyLmNoYXJBdCgwKTsKKyAgICAgICAgaW50IGV4cFNpZ24gPSAobGVhZGluZ0NoYXIgPT0gJy0nID8gLTEgOiAxKTsKKyAgICAgICAgaWYgKCFDaGFyYWN0ZXIuaXNEaWdpdChsZWFkaW5nQ2hhcikpIHsKKyAgICAgICAgICAgIGV4cG9uZW50U3RyID0gZXhwb25lbnRTdHIuc3Vic3RyaW5nKDEpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGV4cG9uZW50ID0gZXhwU2lnbiAqIExvbmcucGFyc2VMb25nKGV4cG9uZW50U3RyKTsKKyAgICAgICAgICAgIGNoZWNrZWRBZGRFeHBvbmVudChFWFBPTkVOVF9CQVNFKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGV4cG9uZW50ID0gZXhwU2lnbiAqIExvbmcuTUFYX1ZBTFVFOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBQYXJzZXMgdGhlIG1hbnRpc3NhIGZpZWxkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwYXJzZU1hbnRpc3NhKFN0cmluZyBzaWduaWZpY2FudFN0cikgeworICAgICAgICBTdHJpbmdbXSBzdHJpbmdzID0gc2lnbmlmaWNhbnRTdHIuc3BsaXQoIlxcLiIpOworICAgICAgICBTdHJpbmcgc3RySW50ZWdlclBhcnQgPSBzdHJpbmdzWzBdOworICAgICAgICBTdHJpbmcgc3RyRGVjaW1hbFBhcnQgPSBzdHJpbmdzLmxlbmd0aCA+IDEgPyBzdHJpbmdzWzFdIDogIiI7CisKKyAgICAgICAgU3RyaW5nIHNpZ25pZmljYW5kID0gZ2V0Tm9ybWFsaXplZFNpZ25pZmljYW5kKHN0ckludGVnZXJQYXJ0LHN0ckRlY2ltYWxQYXJ0KTsKKyAgICAgICAgaWYgKHNpZ25pZmljYW5kLmVxdWFscygiMCIpKSB7CisgICAgICAgICAgICBzZXRaZXJvKCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpbnQgb2Zmc2V0ID0gZ2V0T2Zmc2V0KHN0ckludGVnZXJQYXJ0LCBzdHJEZWNpbWFsUGFydCk7CisgICAgICAgIGNoZWNrZWRBZGRFeHBvbmVudChvZmZzZXQpOworCisgICAgICAgIGlmIChleHBvbmVudCA+PSBNQVhfRVhQT05FTlQpIHsKKyAgICAgICAgICAgIHNldEluZmluaXRlKCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAoZXhwb25lbnQgPD0gTUlOX0VYUE9ORU5UKSB7CisgICAgICAgICAgICBzZXRaZXJvKCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAoc2lnbmlmaWNhbmQubGVuZ3RoKCkgPiBNQVhfU0lHTklGSUNBTlRfTEVOR1RIKSB7CisgICAgICAgICAgICBhYmFuZG9uZWROdW1iZXIgPSBzaWduaWZpY2FuZC5zdWJzdHJpbmcoTUFYX1NJR05JRklDQU5UX0xFTkdUSCk7CisgICAgICAgICAgICBzaWduaWZpY2FuZCA9IHNpZ25pZmljYW5kLnN1YnN0cmluZygwLCBNQVhfU0lHTklGSUNBTlRfTEVOR1RIKTsKKyAgICAgICAgfQorCisgICAgICAgIG1hbnRpc3NhID0gTG9uZy5wYXJzZUxvbmcoc2lnbmlmaWNhbmQsIEhFWF9SQURJWCk7CisKKyAgICAgICAgaWYgKGV4cG9uZW50ID49IDEpIHsKKyAgICAgICAgICAgIHByb2Nlc3NOb3JtYWxOdW1iZXIoKTsKKyAgICAgICAgfSBlbHNleworICAgICAgICAgICAgcHJvY2Vzc1N1Yk5vcm1hbE51bWJlcigpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc2V0SW5maW5pdGUoKSB7CisgICAgICAgIGV4cG9uZW50ID0gTUFYX0VYUE9ORU5UOworICAgICAgICBtYW50aXNzYSA9IDA7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNldFplcm8oKSB7CisgICAgICAgIGV4cG9uZW50ID0gMDsKKyAgICAgICAgbWFudGlzc2EgPSAwOworICAgIH0KKworICAgIC8qCisgICAgICogU2V0cyB0aGUgZXhwb25lbnQgdmFyaWFibGUgdG8gTG9uZy5NQVhfVkFMVUUgb3IgLUxvbmcuTUFYX1ZBTFVFIGlmCisgICAgICogb3ZlcmZsb3cgb3IgdW5kZXJmbG93IGhhcHBlbnMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrZWRBZGRFeHBvbmVudChsb25nIG9mZnNldCkgeworICAgICAgICBsb25nIHJlc3VsdCA9IGV4cG9uZW50ICsgb2Zmc2V0OworICAgICAgICBpbnQgZXhwU2lnbiA9IExvbmcuc2lnbnVtKGV4cG9uZW50KTsKKyAgICAgICAgaWYgKGV4cFNpZ24gKiBMb25nLnNpZ251bShvZmZzZXQpID4gMCAmJiBleHBTaWduICogTG9uZy5zaWdudW0ocmVzdWx0KSA8IDApIHsKKyAgICAgICAgICAgIGV4cG9uZW50ID0gZXhwU2lnbiAqIExvbmcuTUFYX1ZBTFVFOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZXhwb25lbnQgPSByZXN1bHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcHJvY2Vzc05vcm1hbE51bWJlcigpeworICAgICAgICBpbnQgZGVzaXJlZFdpZHRoID0gTUFOVElTU0FfV0lEVEggKyAyOworICAgICAgICBmaXRNYW50aXNzYUluRGVzaXJlZFdpZHRoKGRlc2lyZWRXaWR0aCk7CisgICAgICAgIHJvdW5kKCk7CisgICAgICAgIG1hbnRpc3NhID0gbWFudGlzc2EgJiBNQU5USVNTQV9NQVNLOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwcm9jZXNzU3ViTm9ybWFsTnVtYmVyKCl7CisgICAgICAgIGludCBkZXNpcmVkV2lkdGggPSBNQU5USVNTQV9XSURUSCArIDE7CisgICAgICAgIGRlc2lyZWRXaWR0aCArPSAoaW50KWV4cG9uZW50Oy8vbGVuZHMgYml0IGZyb20gbWFudGlzc2EgdG8gZXhwb25lbnQKKyAgICAgICAgZXhwb25lbnQgPSAwOworICAgICAgICBmaXRNYW50aXNzYUluRGVzaXJlZFdpZHRoKGRlc2lyZWRXaWR0aCk7CisgICAgICAgIHJvdW5kKCk7CisgICAgICAgIG1hbnRpc3NhID0gbWFudGlzc2EgJiBNQU5USVNTQV9NQVNLOworICAgIH0KKworICAgIC8qCisgICAgICogQWRqdXN0cyB0aGUgbWFudGlzc2EgdG8gZGVzaXJlZCB3aWR0aCBmb3IgZnVydGhlciBhbmFseXNpcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZml0TWFudGlzc2FJbkRlc2lyZWRXaWR0aChpbnQgZGVzaXJlZFdpZHRoKXsKKyAgICAgICAgaW50IGJpdExlbmd0aCA9IGNvdW50Qml0c0xlbmd0aChtYW50aXNzYSk7CisgICAgICAgIGlmIChiaXRMZW5ndGggPiBkZXNpcmVkV2lkdGgpIHsKKyAgICAgICAgICAgIGRpc2NhcmRUcmFpbGluZ0JpdHMoYml0TGVuZ3RoIC0gZGVzaXJlZFdpZHRoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG1hbnRpc3NhIDw8PSAoZGVzaXJlZFdpZHRoIC0gYml0TGVuZ3RoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogU3RvcmVzIHRoZSBkaXNjYXJkZWQgYml0cyB0byBhYmFuZG9uZWROdW1iZXIuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGRpc2NhcmRUcmFpbGluZ0JpdHMobG9uZyBudW0pIHsKKyAgICAgICAgbG9uZyBtYXNrID0gfigtMUwgPDwgbnVtKTsKKyAgICAgICAgYWJhbmRvbmVkTnVtYmVyICs9IChtYW50aXNzYSAmIG1hc2spOworICAgICAgICBtYW50aXNzYSA+Pj0gbnVtOworICAgIH0KKworICAgIC8qCisgICAgICogVGhlIHZhbHVlIGlzIHJvdW5kZWQgdXAgb3IgZG93biB0byB0aGUgbmVhcmVzdCBpbmZpbml0ZWx5IHByZWNpc2UgcmVzdWx0LgorICAgICAqIElmIHRoZSB2YWx1ZSBpcyBleGFjdGx5IGhhbGZ3YXkgYmV0d2VlbiB0d28gaW5maW5pdGVseSBwcmVjaXNlIHJlc3VsdHMsCisgICAgICogdGhlbiBpdCBzaG91bGQgYmUgcm91bmRlZCB1cCB0byB0aGUgbmVhcmVzdCBpbmZpbml0ZWx5IHByZWNpc2UgZXZlbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcm91bmQoKSB7CisgICAgICAgIFN0cmluZyByZXN1bHQgPSBhYmFuZG9uZWROdW1iZXIucmVwbGFjZUFsbCgiMCsiLCAiIik7CisgICAgICAgIGJvb2xlYW4gbW9yZVRoYW5aZXJvID0gKHJlc3VsdC5sZW5ndGgoKSA+IDAgPyB0cnVlIDogZmFsc2UpOworCisgICAgICAgIGludCBsYXN0RGlzY2FyZGVkQml0ID0gKGludCkgKG1hbnRpc3NhICYgMUwpOworICAgICAgICBtYW50aXNzYSA+Pj0gMTsKKyAgICAgICAgaW50IHRhaWxCaXRJbk1hbnRpc3NhID0gKGludCkgKG1hbnRpc3NhICYgMUwpOworCisgICAgICAgIGlmIChsYXN0RGlzY2FyZGVkQml0ID09IDEgJiYgKG1vcmVUaGFuWmVybyB8fCB0YWlsQml0SW5NYW50aXNzYSA9PSAxKSkgeworICAgICAgICAgICAgaW50IG9sZExlbmd0aCA9IGNvdW50Qml0c0xlbmd0aChtYW50aXNzYSk7CisgICAgICAgICAgICBtYW50aXNzYSArPSAxTDsKKyAgICAgICAgICAgIGludCBuZXdMZW5ndGggPSBjb3VudEJpdHNMZW5ndGgobWFudGlzc2EpOworCisgICAgICAgICAgICAvL1JvdW5kcyB1cCB0byBleHBvbmVudCB3aGVuIHdob2xlIGJpdHMgb2YgbWFudGlzc2EgYXJlIG9uZS1iaXRzLgorICAgICAgICAgICAgaWYgKG9sZExlbmd0aCA+PSBNQU5USVNTQV9XSURUSCAmJiBuZXdMZW5ndGggPiBvbGRMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBjaGVja2VkQWRkRXhwb25lbnQoMSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFJldHVybnMgdGhlIG5vcm1hbGl6ZWQgc2lnbmlmaWNhbmQgYWZ0ZXIgcmVtb3ZpbmcgdGhlIGxlYWRpbmcgemVyb3MuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0Tm9ybWFsaXplZFNpZ25pZmljYW5kKFN0cmluZyBzdHJJbnRlZ2VyUGFydCwgU3RyaW5nIHN0ckRlY2ltYWxQYXJ0KSB7CisgICAgICAgIFN0cmluZyBzaWduaWZpY2FuZCA9IHN0ckludGVnZXJQYXJ0ICsgc3RyRGVjaW1hbFBhcnQ7CisgICAgICAgIHNpZ25pZmljYW5kID0gc2lnbmlmaWNhbmQucmVwbGFjZUZpcnN0KCJeMCsiLCAiIik7CisgICAgICAgIGlmIChzaWduaWZpY2FuZC5sZW5ndGgoKSA9PSAwKSB7CisgICAgICAgICAgICBzaWduaWZpY2FuZCA9ICIwIjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2lnbmlmaWNhbmQ7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDYWxjdWxhdGVzIHRoZSBvZmZzZXQgYmV0d2VlbiB0aGUgbm9ybWFsaXplZCBudW1iZXIgYW5kIHVubm9ybWFsaXplZAorICAgICAqIG51bWJlci4gSW4gYSBub3JtYWxpemVkIHJlcHJlc2VudGF0aW9uLCBzaWduaWZpY2FuZCBpcyByZXByZXNlbnRlZCBieSB0aGUKKyAgICAgKiBjaGFyYWN0ZXJzICIweDEuIiBmb2xsb3dlZCBieSBhIGxvd2VyY2FzZSBoZXhhZGVjaW1hbCByZXByZXNlbnRhdGlvbiBvZgorICAgICAqIHRoZSByZXN0IG9mIHRoZSBzaWduaWZpY2FuZCBhcyBhIGZyYWN0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgaW50IGdldE9mZnNldChTdHJpbmcgc3RySW50ZWdlclBhcnQsIFN0cmluZyBzdHJEZWNpbWFsUGFydCkgeworICAgICAgICBzdHJJbnRlZ2VyUGFydCA9IHN0ckludGVnZXJQYXJ0LnJlcGxhY2VGaXJzdCgiXjArIiwgIiIpOworCisgICAgICAgIC8vSWYgdGhlIEludGVnZXIgcGFydCBpcyBhIG5vbnplcm8gbnVtYmVyLgorICAgICAgICBpZiAoc3RySW50ZWdlclBhcnQubGVuZ3RoKCkgIT0gMCkgeworICAgICAgICAgICAgU3RyaW5nIGxlYWRpbmdOdW1iZXIgPSBzdHJJbnRlZ2VyUGFydC5zdWJzdHJpbmcoMCwgMSk7CisgICAgICAgICAgICByZXR1cm4gKHN0ckludGVnZXJQYXJ0Lmxlbmd0aCgpIC0gMSkgKiA0ICsgY291bnRCaXRzTGVuZ3RoKExvbmcucGFyc2VMb25nKGxlYWRpbmdOdW1iZXIsSEVYX1JBRElYKSkgLSAxOworICAgICAgICB9CisKKyAgICAgICAgLy9JZiB0aGUgSW50ZWdlciBwYXJ0IGlzIGEgemVybyBudW1iZXIuCisgICAgICAgIGludCBpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc3RyRGVjaW1hbFBhcnQubGVuZ3RoKCkgJiYgc3RyRGVjaW1hbFBhcnQuY2hhckF0KGkpID09ICcwJzsgaSsrKTsKKyAgICAgICAgaWYgKGkgPT0gc3RyRGVjaW1hbFBhcnQubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBsZWFkaW5nTnVtYmVyPXN0ckRlY2ltYWxQYXJ0LnN1YnN0cmluZyhpLGkgKyAxKTsKKyAgICAgICAgcmV0dXJuICgtaSAtIDEpICogNCArIGNvdW50Qml0c0xlbmd0aChMb25nLnBhcnNlTG9uZyhsZWFkaW5nTnVtYmVyLCBIRVhfUkFESVgpKSAtIDE7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgY291bnRCaXRzTGVuZ3RoKGxvbmcgdmFsdWUpIHsKKyAgICAgICAgaW50IGxlYWRpbmdaZXJvcyA9IExvbmcubnVtYmVyT2ZMZWFkaW5nWmVyb3ModmFsdWUpOworICAgICAgICByZXR1cm4gTG9uZy5TSVpFIC0gbGVhZGluZ1plcm9zOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSWxsZWdhbEFjY2Vzc0Vycm9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFcnJvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNmN2NmODYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFcnJvci5qYXZhCkBAIC0wLDAgKzEsNDcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIFRocm93biB3aGVuIHRoZSBWTSBub3RpY2VzIHRoYXQgYSBwcm9ncmFtIHRyaWVzIGFjY2VzcyBhIGZpZWxkCisgKiB3aGljaCBpcyBub3QgYWNjZXNzaWJsZSBmcm9tIHdoZXJlIGl0IGlzIHJlZmVyZW5jZWQuCisgKiA8cD4KKyAqIE5vdGUgdGhhdCB0aGlzIGNhbiBvbmx5IG9jY3VyIHdoZW4gaW5jb25zaXN0ZW50IGNsYXNzIGZpbGVzIGhhdmUgYmVlbiBsb2FkZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBJbGxlZ2FsQWNjZXNzRXJyb3IgZXh0ZW5kcyBJbmNvbXBhdGlibGVDbGFzc0NoYW5nZUVycm9yIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04OTg4OTA0MDc0OTkyNDE3ODkxTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIElsbGVnYWxBY2Nlc3NFcnJvcn0gdGhhdCBpbmNsdWRlcyB0aGUgY3VycmVudAorICAgICAqIHN0YWNrIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBJbGxlZ2FsQWNjZXNzRXJyb3IoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSWxsZWdhbEFjY2Vzc0Vycm9yfSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlCisgICAgICogYW5kIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBJbGxlZ2FsQWNjZXNzRXJyb3IoU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NjI1Mzk1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyb3duIHdoZW4gYSBwcm9ncmFtIGF0dGVtcHRzIHRvIGFjY2VzcyBhIGZpZWxkIG9yIG1ldGhvZCB3aGljaCBpcyBub3QKKyAqIGFjY2Vzc2libGUgZnJvbSB0aGUgbG9jYXRpb24gd2hlcmUgdGhlIHJlZmVyZW5jZSBpcyBtYWRlLgorICovCitwdWJsaWMgY2xhc3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA2NjE2OTU4MjIyNDkwNzYyMDM0TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIElsbGVnYWxBY2Nlc3NFeGNlcHRpb259IHRoYXQgaW5jbHVkZXMgdGhlIGN1cnJlbnQKKyAgICAgKiBzdGFjayB0cmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9ufSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrCisgICAgICogdHJhY2UgYW5kIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY2NTQ4ZmMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNzEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIFRocm93biB3aGVuIGEgbWV0aG9kIGlzIGludm9rZWQgd2l0aCBhbiBhcmd1bWVudCB3aGljaCBpdCBjYW4gbm90IHJlYXNvbmFibHkKKyAqIGRlYWwgd2l0aC4KKyAqLworcHVibGljIGNsYXNzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTUzNjU2MzAxMjg4NTYwNjgxNjRMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufSB0aGF0IGluY2x1ZGVzIHRoZQorICAgICAqIGN1cnJlbnQgc3RhY2sgdHJhY2UuCisgICAgICovCisgICAgcHVibGljIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQgc3RhY2sKKyAgICAgKiB0cmFjZSBhbmQgdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrCisgICAgICogdHJhY2UsIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UgYW5kIHRoZSBzcGVjaWZpZWQgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYXVzZSBvZiB0aGlzIGV4Y2VwdGlvbiwgbWF5IGJlIHtAY29kZSBudWxsfS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UsIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQgc3RhY2sKKyAgICAgKiB0cmFjZSBhbmQgdGhlIHNwZWNpZmllZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGNhdXNlIG9mIHRoaXMgZXhjZXB0aW9uLCBtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcigoY2F1c2UgPT0gbnVsbCA/IG51bGwgOiBjYXVzZS50b1N0cmluZygpKSwgY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9JbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWI4Y2QzZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIFRocm93biB3aGVuIGEgbW9uaXRvciBvcGVyYXRpb24gaXMgYXR0ZW1wdGVkIHdoZW4gdGhlIG1vbml0b3IgaXMgbm90IGluIHRoZQorICogY29ycmVjdCBzdGF0ZSwgZm9yIGV4YW1wbGUgd2hlbiBhIHRocmVhZCBhdHRlbXB0cyB0byBleGl0IGEgbW9uaXRvciB3aGljaCBpdAorICogZG9lcyBub3Qgb3duLgorICovCitwdWJsaWMgY2xhc3MgSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzcxMzMwNjM2OTQ5ODg2OTA2OUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9ufSB0aGF0IGluY2x1ZGVzIHRoZQorICAgICAqIGN1cnJlbnQgc3RhY2sgdHJhY2UuCisgICAgICovCisgICAgcHVibGljIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrCisgICAgICogdHJhY2UgYW5kIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0lsbGVnYWxTdGF0ZUV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9JbGxlZ2FsU3RhdGVFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNDkzODQzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9JbGxlZ2FsU3RhdGVFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDcxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gd2hlbiBhbiBhY3Rpb24gaXMgYXR0ZW1wdGVkIGF0IGEgdGltZSB3aGVuIHRoZSBWTSBpcyBub3QKKyAqIGluIHRoZSBjb3JyZWN0IHN0YXRlLgorICovCitwdWJsaWMgY2xhc3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTg0ODkxNDY3MzA5MzExOTQxNkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJbGxlZ2FsU3RhdGVFeGNlcHRpb259IHRoYXQgaW5jbHVkZXMgdGhlIGN1cnJlbnQKKyAgICAgKiBzdGFjayB0cmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudCBzdGFjaworICAgICAqIHRyYWNlIGFuZCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJbGxlZ2FsU3RhdGVFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQgc3RhY2sKKyAgICAgKiB0cmFjZSwgdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZSBhbmQgdGhlIHNwZWNpZmllZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGNhdXNlIG9mIHRoaXMgZXhjZXB0aW9uLgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudCBzdGFjaworICAgICAqIHRyYWNlIGFuZCB0aGUgc3BlY2lmaWVkIGNhdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgY2F1c2Ugb2YgdGhpcyBleGNlcHRpb24sIG1heSBiZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKChjYXVzZSA9PSBudWxsID8gbnVsbCA6IGNhdXNlLnRvU3RyaW5nKCkpLCBjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9JbGxlZ2FsVGhyZWFkU3RhdGVFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2U2ODA3ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyb3duIHdoZW4gYW4gb3BlcmF0aW9uIGlzIGF0dGVtcHRlZCB3aGljaCBpcyBub3QgcG9zc2libGUgZ2l2ZW4gdGhlIHN0YXRlCisgKiB0aGF0IHRoZSBleGVjdXRpbmcgdGhyZWFkIGlzIGluLgorICovCitwdWJsaWMgY2xhc3MgSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uIGV4dGVuZHMgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03NjI2MjQ2MzYyMzk3NDYwMTc0TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIElsbGVnYWxUaHJlYWRTdGF0ZUV4Y2VwdGlvbn0gdGhhdCBpbmNsdWRlcyB0aGUKKyAgICAgKiBjdXJyZW50IHN0YWNrIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBJbGxlZ2FsVGhyZWFkU3RhdGVFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9ufSB3aXRoIHRoZSBjdXJyZW50CisgICAgICogc3RhY2sgdHJhY2UgYW5kIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSW5jb21wYXRpYmxlQ2xhc3NDaGFuZ2VFcnJvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9JbmNvbXBhdGlibGVDbGFzc0NoYW5nZUVycm9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGU0MzljZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSW5jb21wYXRpYmxlQ2xhc3NDaGFuZ2VFcnJvci5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisKKy8qKgorICoge0Bjb2RlIEluY29tcGF0aWJsZUNsYXNzQ2hhbmdlRXJyb3J9IGlzIHRoZSBzdXBlcmNsYXNzIG9mIGFsbCBjbGFzc2VzIHdoaWNoCisgKiByZXByZXNlbnQgZXJyb3JzIHRoYXQgb2NjdXIgd2hlbiBpbmNvbnNpc3RlbnQgY2xhc3MgZmlsZXMgYXJlIGxvYWRlZCBpbnRvCisgKiB0aGUgc2FtZSBydW5uaW5nIGltYWdlLgorICoKKyAqIEBzZWUgRXJyb3IKKyAqLworcHVibGljIGNsYXNzIEluY29tcGF0aWJsZUNsYXNzQ2hhbmdlRXJyb3IgZXh0ZW5kcyBMaW5rYWdlRXJyb3IgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQ5MTQ5NzU1MDM2NDI4MDIxMTlMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSW5jb21wYXRpYmxlQ2xhc3NDaGFuZ2VFcnJvcn0gdGhhdCBpbmNsdWRlcyB0aGUKKyAgICAgKiBjdXJyZW50IHN0YWNrIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBJbmNvbXBhdGlibGVDbGFzc0NoYW5nZUVycm9yKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEluY29tcGF0aWJsZUNsYXNzQ2hhbmdlRXJyb3J9IHdpdGggdGhlIGN1cnJlbnQKKyAgICAgKiBzdGFjayB0cmFjZSBhbmQgdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIEluY29tcGF0aWJsZUNsYXNzQ2hhbmdlRXJyb3IoU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9JbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZjQwMGFlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9JbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyb3duIHdoZW4gYSBwcm9ncmFtIGF0dGVtcHRzIHRvIGFjY2VzcyBhIHZhbHVlIGluIGFuIGluZGV4YWJsZSBjb2xsZWN0aW9uCisgKiB1c2luZyBhIHZhbHVlIHdoaWNoIGlzIG91dHNpZGUgb2YgdGhlIHJhbmdlIG9mIHZhbGlkIGluZGljZXMuCisgKi8KK3B1YmxpYyBjbGFzcyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAyMzQxMjI5OTYwMDYyNjc2ODdMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbn0gdGhhdCBpbmNsdWRlcyB0aGUKKyAgICAgKiBjdXJyZW50IHN0YWNrIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQgc3RhY2sKKyAgICAgKiB0cmFjZSBhbmQgdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSW5oZXJpdGFibGVUaHJlYWRMb2NhbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Jbmhlcml0YWJsZVRocmVhZExvY2FsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWI2YjU4OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSW5oZXJpdGFibGVUaHJlYWRMb2NhbC5qYXZhCkBAIC0wLDAgKzEsNjIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisKKy8qKgorICogQSB0aHJlYWQtbG9jYWwgdmFyaWFibGUgd2hvc2UgdmFsdWUgaXMgcGFzc2VkIGZyb20gcGFyZW50IHRvIGNoaWxkIHRocmVhZC4gQnkKKyAqIGRlZmF1bHQsIHRoZSB2YWx1ZSBvZiBhbiBpbmhlcml0YWJsZSB0aHJlYWQtbG9jYWwgdmFyaWFibGUgb2YgYSBjaGlsZCB0aHJlYWQKKyAqIGlzIGluaXRpYWxpemVkIHdpdGggdGhlIHZhbHVlIG9mIHRoZSBwYXJlbnQgdGhyZWFkJ3MgdmFyaWFibGUgYXQgdGhyZWFkCisgKiBjcmVhdGlvbiB0aW1lLiBIb3dldmVyLCBzdWJjbGFzc2VzIG1heSBvdmVycmlkZSB7Y29kZSAjY2hpbGRWYWx1ZShPYmplY3QpfQorICogdG8gcHJvdmlkZSBhbiBhcmJpdHJhcnkgZnVuY3Rpb24gZm9yIHBhc3NpbmcgdGhlIHZhbHVlIG9mIGEgcGFyZW50J3MKKyAqIHRocmVhZC1sb2NhbCB2YXJpYWJsZSB0byB0aGUgY2hpbGQncyB0aHJlYWQtbG9jYWwgdmFyaWFibGUuCisgKgorICogQHNlZSBqYXZhLmxhbmcuVGhyZWFkCisgKiBAc2VlIGphdmEubGFuZy5UaHJlYWRMb2NhbAorICovCitwdWJsaWMgY2xhc3MgSW5oZXJpdGFibGVUaHJlYWRMb2NhbDxUPiBleHRlbmRzIFRocmVhZExvY2FsPFQ+IHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgaW5oZXJpdGFibGUgdGhyZWFkLWxvY2FsIHZhcmlhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBJbmhlcml0YWJsZVRocmVhZExvY2FsKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGVzIHRoZSBpbml0aWFsIHZhbHVlIG9mIHRoaXMgdGhyZWFkLWxvY2FsIHZhcmlhYmxlIGZvciB0aGUgY2hpbGQKKyAgICAgKiB0aHJlYWQgZ2l2ZW4gdGhlIHBhcmVudCB0aHJlYWQncyB2YWx1ZS4gQ2FsbGVkIGZyb20gdGhlIHBhcmVudCB0aHJlYWQgd2hlbgorICAgICAqIGNyZWF0aW5nIGEgY2hpbGQgdGhyZWFkLiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHRoZSBwYXJlbnQKKyAgICAgKiB0aHJlYWQncyB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJlbnRWYWx1ZSB0aGUgdmFsdWUgb2YgdGhlIHZhcmlhYmxlIGluIHRoZSBwYXJlbnQgdGhyZWFkLgorICAgICAqIEByZXR1cm4gdGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIHZhcmlhYmxlIGZvciB0aGUgY2hpbGQgdGhyZWFkLgorICAgICAqLworICAgIHByb3RlY3RlZCBUIGNoaWxkVmFsdWUoVCBwYXJlbnRWYWx1ZSkgeworICAgICAgICByZXR1cm4gcGFyZW50VmFsdWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgVmFsdWVzIHZhbHVlcyhUaHJlYWQgY3VycmVudCkgeworICAgICAgICByZXR1cm4gY3VycmVudC5pbmhlcml0YWJsZVZhbHVlczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBWYWx1ZXMgaW5pdGlhbGl6ZVZhbHVlcyhUaHJlYWQgY3VycmVudCkgeworICAgICAgICByZXR1cm4gY3VycmVudC5pbmhlcml0YWJsZVZhbHVlcyA9IG5ldyBWYWx1ZXMoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0luc3RhbnRpYXRpb25FcnJvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9JbnN0YW50aWF0aW9uRXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYmM5MDY1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9JbnN0YW50aWF0aW9uRXJyb3IuamF2YQpAQCAtMCwwICsxLDU5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gd2hlbiB0aGUgVk0gbm90aWNlcyB0aGF0IGEgcHJvZ3JhbSB0cmllcyB0byBjcmVhdGUgYSBuZXcKKyAqIGluc3RhbmNlIG9mIGEgY2xhc3Mgd2hpY2ggaGFzIG5vIHZpc2libGUgY29uc3RydWN0b3JzIGZyb20gdGhlIGxvY2F0aW9uIHdoZXJlCisgKiB7QGNvZGUgbmV3fSBpcyBpbnZva2VkLgorICogPHA+CisgKiBOb3RlIHRoYXQgdGhpcyBjYW4gb25seSBvY2N1ciB3aGVuIGluY29uc2lzdGVudCBjbGFzcyBmaWxlcyBhcmUgYmVpbmcgbG9hZGVkLgorICovCitwdWJsaWMgY2xhc3MgSW5zdGFudGlhdGlvbkVycm9yIGV4dGVuZHMgSW5jb21wYXRpYmxlQ2xhc3NDaGFuZ2VFcnJvciB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQ4ODU4MTA2NTczNDk0MjEyMDRMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSW5zdGFudGlhdGlvbkVycm9yfSB0aGF0IGluY2x1ZGVzIHRoZSBjdXJyZW50CisgICAgICogc3RhY2sgdHJhY2UuCisgICAgICovCisgICAgcHVibGljIEluc3RhbnRpYXRpb25FcnJvcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJbnN0YW50aWF0aW9uRXJyb3J9IHdpdGggdGhlIGN1cnJlbnQgc3RhY2sgdHJhY2UKKyAgICAgKiBhbmQgdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIEluc3RhbnRpYXRpb25FcnJvcihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJbnN0YW50aWF0aW9uRXJyb3J9IHdpdGggdGhlIGN1cnJlbnQgc3RhY2sgdHJhY2UKKyAgICAgKiBhbmQgdGhlIGNsYXNzIHRoYXQgY2F1c2VkIHRoaXMgZXJyb3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2xhenoKKyAgICAgKiAgICAgICAgICAgIHRoZSBjbGFzcyB0aGF0IGNhbiBub3QgYmUgaW5zdGFudGlhdGVkLgorICAgICAqLworICAgIEluc3RhbnRpYXRpb25FcnJvcihDbGFzczw/PiBjbGF6eikgeworICAgICAgICBzdXBlcihjbGF6ei5nZXROYW1lKCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9JbnN0YW50aWF0aW9uRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0luc3RhbnRpYXRpb25FeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNWYyODhiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9JbnN0YW50aWF0aW9uRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyb3duIHdoZW4gYSBwcm9ncmFtIGF0dGVtcHRzIHRvIGFjY2VzcyBhIGNvbnN0cnVjdG9yIHdoaWNoIGlzIG5vdAorICogYWNjZXNzaWJsZSBmcm9tIHRoZSBsb2NhdGlvbiB3aGVyZSB0aGUgcmVmZXJlbmNlIGlzIG1hZGUuCisgKi8KK3B1YmxpYyBjbGFzcyBJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODQ0MTkyOTE2Mjk3NTUwOTExMEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJbnN0YW50aWF0aW9uRXhjZXB0aW9ufSB0aGF0IGluY2x1ZGVzIHRoZSBjdXJyZW50CisgICAgICogc3RhY2sgdHJhY2UuCisgICAgICovCisgICAgcHVibGljIEluc3RhbnRpYXRpb25FeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSW5zdGFudGlhdGlvbkV4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudCBzdGFjaworICAgICAqIHRyYWNlIGFuZCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIEluc3RhbnRpYXRpb25FeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSW5zdGFudGlhdGlvbkV4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudCBzdGFjaworICAgICAqIHRyYWNlIGFuZCB0aGUgY2xhc3MgdGhhdCBjYXVzZWQgdGhpcyBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2xhenoKKyAgICAgKiAgICAgICAgICAgIHRoZSBjbGFzcyB0aGF0IGNhbiBub3QgYmUgaW5zdGFudGlhdGVkLgorICAgICAqLworICAgIEluc3RhbnRpYXRpb25FeGNlcHRpb24oQ2xhc3M8Pz4gY2xhenopIHsKKyAgICAgICAgc3VwZXIoY2xhenouZ2V0TmFtZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0ludGVnZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSW50ZWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE1NTExYTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0ludGVnZXIuamF2YQpAQCAtMCwwICsxLDcyMCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhlIHdyYXBwZXIgZm9yIHRoZSBwcmltaXRpdmUgdHlwZSB7QGNvZGUgaW50fS4KKyAqIDxwPgorICogSW1wbGVtZW50YXRpb24gbm90ZTogVGhlICJiaXQgdHdpZGRsaW5nIiBtZXRob2RzIGluIHRoaXMgY2xhc3MgdXNlIHRlY2huaXF1ZXMKKyAqIGRlc2NyaWJlZCBpbiA8YSBocmVmPSJodHRwOi8vd3d3LmhhY2tlcnNkZWxpZ2h0Lm9yZy8iPkhlbnJ5IFMuIFdhcnJlbiwKKyAqIEpyLidzIEhhY2tlcidzIERlbGlnaHQsIChBZGRpc29uIFdlc2xleSwgMjAwMik8L2E+IGFuZCA8YSBocmVmPQorICogImh0dHA6Ly9ncmFwaGljcy5zdGFuZm9yZC5lZHUvfnNlYW5kZXIvYml0aGFja3MuaHRtbCI+U2VhbiBBbmRlcnNvbidzCisgKiBCaXQgVHdpZGRsaW5nIEhhY2tzLjwvYT4KKyAqCisgKiBAc2VlIGphdmEubGFuZy5Mb25nCisgKiBAc2luY2UgMS4wCisgKi8KK0BGaW5kQnVnc1N1cHByZXNzV2FybmluZ3MoIkRNX05VTUJFUl9DVE9SIikKK3B1YmxpYyBmaW5hbCBjbGFzcyBJbnRlZ2VyIGV4dGVuZHMgTnVtYmVyIGltcGxlbWVudHMgQ29tcGFyYWJsZTxJbnRlZ2VyPiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxMzYwODI2NjY3ODA2ODUyOTIwTDsKKworICAgIC8qKgorICAgICAqIFRoZSBpbnQgdmFsdWUgcmVwcmVzZW50ZWQgYnkgdGhpcyBJbnRlZ2VyCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCBmb3IgdGhlIG1heGltdW0ge0Bjb2RlIGludH0gdmFsdWUsIDI8c3VwPjMxPC9zdXA+LTEuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1ZBTFVFID0gMHg3RkZGRkZGRjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IGZvciB0aGUgbWluaW11bSB7QGNvZGUgaW50fSB2YWx1ZSwgLTI8c3VwPjMxPC9zdXA+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1JTl9WQUxVRSA9IDB4ODAwMDAwMDA7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCBmb3IgdGhlIG51bWJlciBvZiBiaXRzIG5lZWRlZCB0byByZXByZXNlbnQgYW4ge0Bjb2RlIGludH0gaW4KKyAgICAgKiB0d28ncyBjb21wbGVtZW50IGZvcm0uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0laRSA9IDMyOworCisgICAgLyoqCisgICAgICogVGFibGUgZm9yIFNlYWwncyBhbGdvcml0aG0gZm9yIE51bWJlciBvZiBUcmFpbGluZyBaZXJvcy4gSGFja2VyJ3MgRGVsaWdodAorICAgICAqIG9ubGluZSwgRmlndXJlIDUtMTggKGh0dHA6Ly93d3cuaGFja2Vyc2RlbGlnaHQub3JnL3JldmlzaW9ucy5wZGYpCisgICAgICogVGhlIGVudHJpZXMgd2hvc2UgdmFsdWUgaXMgLTEgYXJlIG5ldmVyIHJlZmVyZW5jZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIE5UWl9UQUJMRSA9IHsKKyAgICAgICAgMzIsICAwLCAgMSwgMTIsICAyLCAgNiwgLTEsIDEzLCAgIDMsIC0xLCAgNywgLTEsIC0xLCAtMSwgLTEsIDE0LAorICAgICAgICAxMCwgIDQsIC0xLCAtMSwgIDgsIC0xLCAtMSwgMjUsICAtMSwgLTEsIC0xLCAtMSwgLTEsIDIxLCAyNywgMTUsCisgICAgICAgIDMxLCAxMSwgIDUsIC0xLCAtMSwgLTEsIC0xLCAtMSwgICA5LCAtMSwgLTEsIDI0LCAtMSwgLTEsIDIwLCAyNiwKKyAgICAgICAgMzAsIC0xLCAtMSwgLTEsIC0xLCAyMywgLTEsIDE5LCAgMjksIC0xLCAyMiwgMTgsIDI4LCAxNywgMTYsIC0xCisgICAgfTsKKworICAgIC8qKgorICAgICAqIFRoZSB7QGxpbmsgQ2xhc3N9IG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHByaW1pdGl2ZSB0eXBlIHtAY29kZSBpbnR9LgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3M8SW50ZWdlcj4gVFlQRQorICAgICAgICAgICAgPSAoQ2xhc3M8SW50ZWdlcj4pIGludFtdLmNsYXNzLmdldENvbXBvbmVudFR5cGUoKTsKKyAgICAvLyBOb3RlOiBJbnRlZ2VyLlRZUEUgY2FuJ3QgYmUgc2V0IHRvICJpbnQuY2xhc3MiLCBzaW5jZSAqdGhhdCogaXMKKyAgICAvLyBkZWZpbmVkIHRvIGJlICJqYXZhLmxhbmcuSW50ZWdlci5UWVBFIjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEludGVnZXJ9IHdpdGggdGhlIHNwZWNpZmllZCBwcmltaXRpdmUgaW50ZWdlcgorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgcHJpbWl0aXZlIGludGVnZXIgdmFsdWUgdG8gc3RvcmUgaW4gdGhlIG5ldyBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW50ZWdlcihpbnQgdmFsdWUpIHsKKyAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEludGVnZXJ9IGZyb20gdGhlIHNwZWNpZmllZCBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGFuIGludGVnZXIgdmFsdWUuCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyaW5nfSBjYW5ub3QgYmUgcGFyc2VkIGFzIGFuIGludGVnZXIgdmFsdWUuCisgICAgICogQHNlZSAjcGFyc2VJbnQoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBJbnRlZ2VyKFN0cmluZyBzdHJpbmcpIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24geworICAgICAgICB0aGlzKHBhcnNlSW50KHN0cmluZykpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBieXRlIGJ5dGVWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIChieXRlKSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIG9iamVjdCB0byB0aGUgc3BlY2lmaWVkIGludGVnZXIgb2JqZWN0IHRvIGRldGVybWluZSB0aGVpcgorICAgICAqIHJlbGF0aXZlIG9yZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyBvYmplY3QgdG8uCisgICAgICogQHJldHVybiBhIG5lZ2F0aXZlIHZhbHVlIGlmIHRoZSB2YWx1ZSBvZiB0aGlzIGludGVnZXIgaXMgbGVzcyB0aGFuIHRoZQorICAgICAqICAgICAgICAgdmFsdWUgb2Yge0Bjb2RlIG9iamVjdH07IDAgaWYgdGhlIHZhbHVlIG9mIHRoaXMgaW50ZWdlciBhbmQgdGhlCisgICAgICogICAgICAgICB2YWx1ZSBvZiB7QGNvZGUgb2JqZWN0fSBhcmUgZXF1YWw7IGEgcG9zaXRpdmUgdmFsdWUgaWYgdGhlIHZhbHVlCisgICAgICogICAgICAgICBvZiB0aGlzIGludGVnZXIgaXMgZ3JlYXRlciB0aGFuIHRoZSB2YWx1ZSBvZiB7QGNvZGUgb2JqZWN0fS4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5Db21wYXJhYmxlCisgICAgICogQHNpbmNlIDEuMgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKEludGVnZXIgb2JqZWN0KSB7CisgICAgICAgIHJldHVybiBjb21wYXJlKHZhbHVlLCBvYmplY3QudmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHR3byB7QGNvZGUgaW50fSB2YWx1ZXMuCisgICAgICogQHJldHVybiAwIGlmIGxocyA9IHJocywgbGVzcyB0aGFuIDAgaWYgbGhzICZsdDsgcmhzLCBhbmQgZ3JlYXRlciB0aGFuIDAgaWYgbGhzICZndDsgcmhzLgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBjb21wYXJlKGludCBsaHMsIGludCByaHMpIHsKKyAgICAgICAgcmV0dXJuIGxocyA8IHJocyA/IC0xIDogKGxocyA9PSByaHMgPyAwIDogMSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGludmFsaWRJbnQoU3RyaW5nIHMpIHsKKyAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigiSW52YWxpZCBpbnQ6IFwiIiArIHMgKyAiXCIiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgdGhlIHNwZWNpZmllZCBzdHJpbmcgYW5kIHJldHVybnMgYSB7QGNvZGUgSW50ZWdlcn0gaW5zdGFuY2UgaWYgdGhlCisgICAgICogc3RyaW5nIGNhbiBiZSBkZWNvZGVkIGludG8gYW4gaW50ZWdlciB2YWx1ZS4gVGhlIHN0cmluZyBtYXkgYmUgYW4KKyAgICAgKiBvcHRpb25hbCBtaW51cyBzaWduICItIiBmb2xsb3dlZCBieSBhIGhleGFkZWNpbWFsICgiMHguLi4iIG9yICIjLi4uIiksCisgICAgICogb2N0YWwgKCIwLi4uIiksIG9yIGRlY2ltYWwgKCIuLi4iKSByZXByZXNlbnRhdGlvbiBvZiBhbiBpbnRlZ2VyLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYW4gaW50ZWdlciB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBJbnRlZ2VyfSBjb250YWluaW5nIHRoZSB2YWx1ZSByZXByZXNlbnRlZCBieQorICAgICAqICAgICAgICAge0Bjb2RlIHN0cmluZ30uCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyaW5nfSBjYW5ub3QgYmUgcGFyc2VkIGFzIGFuIGludGVnZXIgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJbnRlZ2VyIGRlY29kZShTdHJpbmcgc3RyaW5nKSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGxlbmd0aCA9IHN0cmluZy5sZW5ndGgoKSwgaSA9IDA7CisgICAgICAgIGlmIChsZW5ndGggPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgaW52YWxpZEludChzdHJpbmcpOworICAgICAgICB9CisgICAgICAgIGNoYXIgZmlyc3REaWdpdCA9IHN0cmluZy5jaGFyQXQoaSk7CisgICAgICAgIGJvb2xlYW4gbmVnYXRpdmUgPSBmaXJzdERpZ2l0ID09ICctJzsKKyAgICAgICAgaWYgKG5lZ2F0aXZlKSB7CisgICAgICAgICAgICBpZiAobGVuZ3RoID09IDEpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBpbnZhbGlkSW50KHN0cmluZyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmaXJzdERpZ2l0ID0gc3RyaW5nLmNoYXJBdCgrK2kpOworICAgICAgICB9CisKKyAgICAgICAgaW50IGJhc2UgPSAxMDsKKyAgICAgICAgaWYgKGZpcnN0RGlnaXQgPT0gJzAnKSB7CisgICAgICAgICAgICBpZiAoKytpID09IGxlbmd0aCkgeworICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZU9mKDApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKChmaXJzdERpZ2l0ID0gc3RyaW5nLmNoYXJBdChpKSkgPT0gJ3gnIHx8IGZpcnN0RGlnaXQgPT0gJ1gnKSB7CisgICAgICAgICAgICAgICAgaWYgKCsraSA9PSBsZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgaW52YWxpZEludChzdHJpbmcpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBiYXNlID0gMTY7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJhc2UgPSA4OworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKGZpcnN0RGlnaXQgPT0gJyMnKSB7CisgICAgICAgICAgICBpZiAoKytpID09IGxlbmd0aCkgeworICAgICAgICAgICAgICAgIHRocm93IGludmFsaWRJbnQoc3RyaW5nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJhc2UgPSAxNjsKKyAgICAgICAgfQorCisgICAgICAgIGludCByZXN1bHQgPSBwYXJzZShzdHJpbmcsIGksIGJhc2UsIG5lZ2F0aXZlKTsKKyAgICAgICAgcmV0dXJuIHZhbHVlT2YocmVzdWx0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZG91YmxlIGRvdWJsZVZhbHVlKCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFuZCBpbmRpY2F0ZXMgaWYgdGhleQorICAgICAqIGFyZSBlcXVhbC4gSW4gb3JkZXIgdG8gYmUgZXF1YWwsIHtAY29kZSBvfSBtdXN0IGJlIGFuIGluc3RhbmNlIG9mCisgICAgICoge0Bjb2RlIEludGVnZXJ9IGFuZCBoYXZlIHRoZSBzYW1lIGludGVnZXIgdmFsdWUgYXMgdGhpcyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbworICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHRoaXMgaW50ZWdlciB3aXRoLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBJbnRlZ2VyfTsge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgIHJldHVybiAobyBpbnN0YW5jZW9mIEludGVnZXIpICYmICgoKEludGVnZXIpIG8pLnZhbHVlID09IHZhbHVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXQgZmxvYXRWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBJbnRlZ2VyfSB2YWx1ZSBvZiB0aGUgc3lzdGVtIHByb3BlcnR5IGlkZW50aWZpZWQgYnkKKyAgICAgKiB7QGNvZGUgc3RyaW5nfS4gUmV0dXJucyB7QGNvZGUgbnVsbH0gaWYge0Bjb2RlIHN0cmluZ30gaXMge0Bjb2RlIG51bGx9CisgICAgICogb3IgZW1wdHksIGlmIHRoZSBwcm9wZXJ0eSBjYW4gbm90IGJlIGZvdW5kIG9yIGlmIGl0cyB2YWx1ZSBjYW4gbm90IGJlCisgICAgICogcGFyc2VkIGFzIGFuIGludGVnZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcmVxdWVzdGVkIHN5c3RlbSBwcm9wZXJ0eS4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0ZWQgcHJvcGVydHkncyB2YWx1ZSBhcyBhbiB7QGNvZGUgSW50ZWdlcn0gb3IKKyAgICAgKiAgICAgICAgIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEludGVnZXIgZ2V0SW50ZWdlcihTdHJpbmcgc3RyaW5nKSB7CisgICAgICAgIGlmIChzdHJpbmcgPT0gbnVsbCB8fCBzdHJpbmcubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHByb3AgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoc3RyaW5nKTsKKyAgICAgICAgaWYgKHByb3AgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBkZWNvZGUocHJvcCk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgSW50ZWdlcn0gdmFsdWUgb2YgdGhlIHN5c3RlbSBwcm9wZXJ0eSBpZGVudGlmaWVkIGJ5CisgICAgICoge0Bjb2RlIHN0cmluZ30uIFJldHVybnMgdGhlIHNwZWNpZmllZCBkZWZhdWx0IHZhbHVlIGlmIHtAY29kZSBzdHJpbmd9IGlzCisgICAgICoge0Bjb2RlIG51bGx9IG9yIGVtcHR5LCBpZiB0aGUgcHJvcGVydHkgY2FuIG5vdCBiZSBmb3VuZCBvciBpZiBpdHMgdmFsdWUKKyAgICAgKiBjYW4gbm90IGJlIHBhcnNlZCBhcyBhbiBpbnRlZ2VyLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlcXVlc3RlZCBzeXN0ZW0gcHJvcGVydHkuCisgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgdmFsdWUgdGhhdCBpcyByZXR1cm5lZCBpZiB0aGVyZSBpcyBubyBpbnRlZ2VyCisgICAgICogICAgICAgICAgICBzeXN0ZW0gcHJvcGVydHkgd2l0aCB0aGUgcmVxdWVzdGVkIG5hbWUuCisgICAgICogQHJldHVybiB0aGUgcmVxdWVzdGVkIHByb3BlcnR5J3MgdmFsdWUgYXMgYW4ge0Bjb2RlIEludGVnZXJ9IG9yIHRoZQorICAgICAqICAgICAgICAgZGVmYXVsdCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEludGVnZXIgZ2V0SW50ZWdlcihTdHJpbmcgc3RyaW5nLCBpbnQgZGVmYXVsdFZhbHVlKSB7CisgICAgICAgIGlmIChzdHJpbmcgPT0gbnVsbCB8fCBzdHJpbmcubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHZhbHVlT2YoZGVmYXVsdFZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcHJvcCA9IFN5c3RlbS5nZXRQcm9wZXJ0eShzdHJpbmcpOworICAgICAgICBpZiAocHJvcCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsdWVPZihkZWZhdWx0VmFsdWUpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gZGVjb2RlKHByb3ApOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHJldHVybiB2YWx1ZU9mKGRlZmF1bHRWYWx1ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgSW50ZWdlcn0gdmFsdWUgb2YgdGhlIHN5c3RlbSBwcm9wZXJ0eSBpZGVudGlmaWVkIGJ5CisgICAgICoge0Bjb2RlIHN0cmluZ30uIFJldHVybnMgdGhlIHNwZWNpZmllZCBkZWZhdWx0IHZhbHVlIGlmIHtAY29kZSBzdHJpbmd9IGlzCisgICAgICoge0Bjb2RlIG51bGx9IG9yIGVtcHR5LCBpZiB0aGUgcHJvcGVydHkgY2FuIG5vdCBiZSBmb3VuZCBvciBpZiBpdHMgdmFsdWUKKyAgICAgKiBjYW4gbm90IGJlIHBhcnNlZCBhcyBhbiBpbnRlZ2VyLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlcXVlc3RlZCBzeXN0ZW0gcHJvcGVydHkuCisgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgdmFsdWUgdGhhdCBpcyByZXR1cm5lZCBpZiB0aGVyZSBpcyBubyBpbnRlZ2VyCisgICAgICogICAgICAgICAgICBzeXN0ZW0gcHJvcGVydHkgd2l0aCB0aGUgcmVxdWVzdGVkIG5hbWUuCisgICAgICogQHJldHVybiB0aGUgcmVxdWVzdGVkIHByb3BlcnR5J3MgdmFsdWUgYXMgYW4ge0Bjb2RlIEludGVnZXJ9IG9yIHRoZQorICAgICAqICAgICAgICAgZGVmYXVsdCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEludGVnZXIgZ2V0SW50ZWdlcihTdHJpbmcgc3RyaW5nLCBJbnRlZ2VyIGRlZmF1bHRWYWx1ZSkgeworICAgICAgICBpZiAoc3RyaW5nID09IG51bGwgfHwgc3RyaW5nLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHByb3AgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoc3RyaW5nKTsKKyAgICAgICAgaWYgKHByb3AgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGRlY29kZShwcm9wKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHByaW1pdGl2ZSB2YWx1ZSBvZiB0aGlzIGludC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBvYmplY3QncyBwcmltaXRpdmUgdmFsdWUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBpbnRWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIGxvbmdWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgc3BlY2lmaWVkIHN0cmluZyBhcyBhIHNpZ25lZCBkZWNpbWFsIGludGVnZXIgdmFsdWUuIFRoZSBBU0NJSQorICAgICAqIGNoYXJhY3RlciBcdTAwMmQgKCctJykgaXMgcmVjb2duaXplZCBhcyB0aGUgbWludXMgc2lnbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYW4gaW50ZWdlciB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBwcmltaXRpdmUgaW50ZWdlciB2YWx1ZSByZXByZXNlbnRlZCBieSB7QGNvZGUgc3RyaW5nfS4KKyAgICAgKiBAdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdHJpbmd9IGNhbm5vdCBiZSBwYXJzZWQgYXMgYW4gaW50ZWdlciB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBwYXJzZUludChTdHJpbmcgc3RyaW5nKSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHBhcnNlSW50KHN0cmluZywgMTApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgc3BlY2lmaWVkIHN0cmluZyBhcyBhIHNpZ25lZCBpbnRlZ2VyIHZhbHVlIHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiByYWRpeC4gVGhlIEFTQ0lJIGNoYXJhY3RlciBcdTAwMmQgKCctJykgaXMgcmVjb2duaXplZCBhcyB0aGUgbWludXMgc2lnbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYW4gaW50ZWdlciB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gcmFkaXgKKyAgICAgKiAgICAgICAgICAgIHRoZSByYWRpeCB0byB1c2Ugd2hlbiBwYXJzaW5nLgorICAgICAqIEByZXR1cm4gdGhlIHByaW1pdGl2ZSBpbnRlZ2VyIHZhbHVlIHJlcHJlc2VudGVkIGJ5IHtAY29kZSBzdHJpbmd9IHVzaW5nCisgICAgICogICAgICAgICB7QGNvZGUgcmFkaXh9LgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0cmluZ30gY2Fubm90IGJlIHBhcnNlZCBhcyBhbiBpbnRlZ2VyIHZhbHVlLAorICAgICAqICAgICAgICAgICAgIG9yIHtAY29kZSByYWRpeCA8IENoYXJhY3Rlci5NSU5fUkFESVggfHwKKyAgICAgKiAgICAgICAgICAgICByYWRpeCA+IENoYXJhY3Rlci5NQVhfUkFESVh9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHBhcnNlSW50KFN0cmluZyBzdHJpbmcsIGludCByYWRpeCkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChyYWRpeCA8IENoYXJhY3Rlci5NSU5fUkFESVggfHwgcmFkaXggPiBDaGFyYWN0ZXIuTUFYX1JBRElYKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkIHJhZGl4OiAiICsgcmFkaXgpOworICAgICAgICB9CisgICAgICAgIGlmIChzdHJpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgaW52YWxpZEludChzdHJpbmcpOworICAgICAgICB9CisgICAgICAgIGludCBsZW5ndGggPSBzdHJpbmcubGVuZ3RoKCksIGkgPSAwOworICAgICAgICBpZiAobGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHRocm93IGludmFsaWRJbnQoc3RyaW5nKTsKKyAgICAgICAgfQorICAgICAgICBib29sZWFuIG5lZ2F0aXZlID0gc3RyaW5nLmNoYXJBdChpKSA9PSAnLSc7CisgICAgICAgIGlmIChuZWdhdGl2ZSAmJiArK2kgPT0gbGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBpbnZhbGlkSW50KHN0cmluZyk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcGFyc2Uoc3RyaW5nLCBpLCByYWRpeCwgbmVnYXRpdmUpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGludCBwYXJzZShTdHJpbmcgc3RyaW5nLCBpbnQgb2Zmc2V0LCBpbnQgcmFkaXgsIGJvb2xlYW4gbmVnYXRpdmUpIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24geworICAgICAgICBpbnQgbWF4ID0gSW50ZWdlci5NSU5fVkFMVUUgLyByYWRpeDsKKyAgICAgICAgaW50IHJlc3VsdCA9IDAsIGxlbmd0aCA9IHN0cmluZy5sZW5ndGgoKTsKKyAgICAgICAgd2hpbGUgKG9mZnNldCA8IGxlbmd0aCkgeworICAgICAgICAgICAgaW50IGRpZ2l0ID0gQ2hhcmFjdGVyLmRpZ2l0KHN0cmluZy5jaGFyQXQob2Zmc2V0KyspLCByYWRpeCk7CisgICAgICAgICAgICBpZiAoZGlnaXQgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBpbnZhbGlkSW50KHN0cmluZyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobWF4ID4gcmVzdWx0KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgaW52YWxpZEludChzdHJpbmcpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IG5leHQgPSByZXN1bHQgKiByYWRpeCAtIGRpZ2l0OworICAgICAgICAgICAgaWYgKG5leHQgPiByZXN1bHQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBpbnZhbGlkSW50KHN0cmluZyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHQgPSBuZXh0OworICAgICAgICB9CisgICAgICAgIGlmICghbmVnYXRpdmUpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IC1yZXN1bHQ7CisgICAgICAgICAgICBpZiAocmVzdWx0IDwgMCkgeworICAgICAgICAgICAgICAgIHRocm93IGludmFsaWRJbnQoc3RyaW5nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzaG9ydCBzaG9ydFZhbHVlKCkgeworICAgICAgICByZXR1cm4gKHNob3J0KSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIGludGVnZXIgaW50byBpdHMgYmluYXJ5IHN0cmluZyByZXByZXNlbnRhdGlvbi4gVGhlCisgICAgICogcmV0dXJuZWQgc3RyaW5nIGlzIGEgY29uY2F0ZW5hdGlvbiBvZiAnMCcgYW5kICcxJyBjaGFyYWN0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlZ2VyIHRvIGNvbnZlcnQuCisgICAgICogQHJldHVybiB0aGUgYmluYXJ5IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUgaX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9CaW5hcnlTdHJpbmcoaW50IGkpIHsKKyAgICAgICAgcmV0dXJuIEludGVncmFsVG9TdHJpbmcuaW50VG9CaW5hcnlTdHJpbmcoaSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhlIHNwZWNpZmllZCBpbnRlZ2VyIGludG8gaXRzIGhleGFkZWNpbWFsIHN0cmluZworICAgICAqIHJlcHJlc2VudGF0aW9uLiBUaGUgcmV0dXJuZWQgc3RyaW5nIGlzIGEgY29uY2F0ZW5hdGlvbiBvZiBjaGFyYWN0ZXJzIGZyb20KKyAgICAgKiAnMCcgdG8gJzknIGFuZCAnYScgdG8gJ2YnLgorICAgICAqCisgICAgICogQHBhcmFtIGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlZ2VyIHRvIGNvbnZlcnQuCisgICAgICogQHJldHVybiB0aGUgaGV4YWRlY2ltYWwgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHtAY29kZSBpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b0hleFN0cmluZyhpbnQgaSkgeworICAgICAgICByZXR1cm4gSW50ZWdyYWxUb1N0cmluZy5pbnRUb0hleFN0cmluZyhpLCBmYWxzZSwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhlIHNwZWNpZmllZCBpbnRlZ2VyIGludG8gaXRzIG9jdGFsIHN0cmluZyByZXByZXNlbnRhdGlvbi4gVGhlCisgICAgICogcmV0dXJuZWQgc3RyaW5nIGlzIGEgY29uY2F0ZW5hdGlvbiBvZiBjaGFyYWN0ZXJzIGZyb20gJzAnIHRvICc3Jy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB0byBjb252ZXJ0LgorICAgICAqIEByZXR1cm4gdGhlIG9jdGFsIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUgaX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9PY3RhbFN0cmluZyhpbnQgaSkgeworICAgICAgICByZXR1cm4gSW50ZWdyYWxUb1N0cmluZy5pbnRUb09jdGFsU3RyaW5nKGkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBJbnRlZ2VyLnRvU3RyaW5nKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIGludGVnZXIgaW50byBpdHMgZGVjaW1hbCBzdHJpbmcgcmVwcmVzZW50YXRpb24uCisgICAgICogVGhlIHJldHVybmVkIHN0cmluZyBpcyBhIGNvbmNhdGVuYXRpb24gb2YgYSBtaW51cyBzaWduIGlmIHRoZSBudW1iZXIgaXMKKyAgICAgKiBuZWdhdGl2ZSBhbmQgY2hhcmFjdGVycyBmcm9tICcwJyB0byAnOScuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdG8gY29udmVydC4KKyAgICAgKiBAcmV0dXJuIHRoZSBkZWNpbWFsIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUgaX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoaW50IGkpIHsKKyAgICAgICAgcmV0dXJuIEludGVncmFsVG9TdHJpbmcuaW50VG9TdHJpbmcoaSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhlIHNwZWNpZmllZCBzaWduZWQgaW50ZWdlciBpbnRvIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGJhc2VkIG9uIHRoZQorICAgICAqIHNwZWNpZmllZCByYWRpeC4gVGhlIHJldHVybmVkIHN0cmluZyBpcyBhIGNvbmNhdGVuYXRpb24gb2YgYSBtaW51cyBzaWduCisgICAgICogaWYgdGhlIG51bWJlciBpcyBuZWdhdGl2ZSBhbmQgY2hhcmFjdGVycyBmcm9tICcwJyB0byAnOScgYW5kICdhJyB0byAneicsCisgICAgICogZGVwZW5kaW5nIG9uIHRoZSByYWRpeC4gSWYge0Bjb2RlIHJhZGl4fSBpcyBub3QgaW4gdGhlIGludGVydmFsIGRlZmluZWQKKyAgICAgKiBieSB7QGNvZGUgQ2hhcmFjdGVyLk1JTl9SQURJWH0gYW5kIHtAY29kZSBDaGFyYWN0ZXIuTUFYX1JBRElYfSB0aGVuIDEwIGlzCisgICAgICogdXNlZCBhcyB0aGUgYmFzZSBmb3IgdGhlIGNvbnZlcnNpb24uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCB0cmVhdHMgaXRzIGFyZ3VtZW50IGFzIHNpZ25lZC4gSWYgeW91IHdhbnQgdG8gY29udmVydCBhbgorICAgICAqIHVuc2lnbmVkIHZhbHVlIHRvIG9uZSBvZiB0aGUgY29tbW9uIG5vbi1kZWNpbWFsIGJhc2VzLCB5b3UgbWF5IGZpbmQKKyAgICAgKiB7QGxpbmsgI3RvQmluYXJ5U3RyaW5nfSwge0Bjb2RlICN0b0hleFN0cmluZ30sIG9yIHtAbGluayAjdG9PY3RhbFN0cmluZ30KKyAgICAgKiBtb3JlIGNvbnZlbmllbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIHNpZ25lZCBpbnRlZ2VyIHRvIGNvbnZlcnQuCisgICAgICogQHBhcmFtIHJhZGl4CisgICAgICogICAgICAgICAgICB0aGUgYmFzZSB0byB1c2UgZm9yIHRoZSBjb252ZXJzaW9uLgorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUgaX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoaW50IGksIGludCByYWRpeCkgeworICAgICAgICByZXR1cm4gSW50ZWdyYWxUb1N0cmluZy5pbnRUb1N0cmluZyhpLCByYWRpeCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGFzIGEgc2lnbmVkIGRlY2ltYWwgaW50ZWdlciB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYW4gaW50ZWdlciB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBJbnRlZ2VyfSBpbnN0YW5jZSBjb250YWluaW5nIHRoZSBpbnRlZ2VyIHZhbHVlCisgICAgICogICAgICAgICByZXByZXNlbnRlZCBieSB7QGNvZGUgc3RyaW5nfS4KKyAgICAgKiBAdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdHJpbmd9IGNhbm5vdCBiZSBwYXJzZWQgYXMgYW4gaW50ZWdlciB2YWx1ZS4KKyAgICAgKiBAc2VlICNwYXJzZUludChTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJbnRlZ2VyIHZhbHVlT2YoU3RyaW5nIHN0cmluZykgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiB2YWx1ZU9mKHBhcnNlSW50KHN0cmluZykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgc3BlY2lmaWVkIHN0cmluZyBhcyBhIHNpZ25lZCBpbnRlZ2VyIHZhbHVlIHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiByYWRpeC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYW4gaW50ZWdlciB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gcmFkaXgKKyAgICAgKiAgICAgICAgICAgIHRoZSByYWRpeCB0byB1c2Ugd2hlbiBwYXJzaW5nLgorICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIEludGVnZXJ9IGluc3RhbmNlIGNvbnRhaW5pbmcgdGhlIGludGVnZXIgdmFsdWUKKyAgICAgKiAgICAgICAgIHJlcHJlc2VudGVkIGJ5IHtAY29kZSBzdHJpbmd9IHVzaW5nIHtAY29kZSByYWRpeH0uCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyaW5nfSBjYW5ub3QgYmUgcGFyc2VkIGFzIGFuIGludGVnZXIgdmFsdWUsIG9yCisgICAgICogICAgICAgICAgICAge0Bjb2RlIHJhZGl4IDwgQ2hhcmFjdGVyLk1JTl9SQURJWCB8fAorICAgICAqICAgICAgICAgICAgIHJhZGl4ID4gQ2hhcmFjdGVyLk1BWF9SQURJWH0uCisgICAgICogQHNlZSAjcGFyc2VJbnQoU3RyaW5nLCBpbnQpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJbnRlZ2VyIHZhbHVlT2YoU3RyaW5nIHN0cmluZywgaW50IHJhZGl4KSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlT2YocGFyc2VJbnQoc3RyaW5nLCByYWRpeCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgdGhlIGhpZ2hlc3QgKGxlZnRtb3N0KSBiaXQgb2YgdGhlIHNwZWNpZmllZCBpbnRlZ2VyIHRoYXQgaXMgMQorICAgICAqIGFuZCByZXR1cm5zIHRoZSBiaXQgbWFzayB2YWx1ZSBmb3IgdGhhdCBiaXQuIFRoaXMgaXMgYWxzbyByZWZlcnJlZCB0byBhcworICAgICAqIHRoZSBNb3N0IFNpZ25pZmljYW50IDEgQml0LiBSZXR1cm5zIHplcm8gaWYgdGhlIHNwZWNpZmllZCBpbnRlZ2VyIGlzCisgICAgICogemVyby4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB0byBleGFtaW5lLgorICAgICAqIEByZXR1cm4gdGhlIGJpdCBtYXNrIGluZGljYXRpbmcgdGhlIGhpZ2hlc3QgMSBiaXQgaW4ge0Bjb2RlIGl9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBoaWdoZXN0T25lQml0KGludCBpKSB7CisgICAgICAgIC8vIEhhY2tlcidzIERlbGlnaHQsIEZpZ3VyZSAzLTEKKyAgICAgICAgaSB8PSAoaSA+PiAxKTsKKyAgICAgICAgaSB8PSAoaSA+PiAyKTsKKyAgICAgICAgaSB8PSAoaSA+PiA0KTsKKyAgICAgICAgaSB8PSAoaSA+PiA4KTsKKyAgICAgICAgaSB8PSAoaSA+PiAxNik7CisgICAgICAgIHJldHVybiBpIC0gKGkgPj4+IDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgdGhlIGxvd2VzdCAocmlnaHRtb3N0KSBiaXQgb2YgdGhlIHNwZWNpZmllZCBpbnRlZ2VyIHRoYXQgaXMgMQorICAgICAqIGFuZCByZXR1cm5zIHRoZSBiaXQgbWFzayB2YWx1ZSBmb3IgdGhhdCBiaXQuIFRoaXMgaXMgYWxzbyByZWZlcnJlZAorICAgICAqIHRvIGFzIHRoZSBMZWFzdCBTaWduaWZpY2FudCAxIEJpdC4gUmV0dXJucyB6ZXJvIGlmIHRoZSBzcGVjaWZpZWQgaW50ZWdlcgorICAgICAqIGlzIHplcm8uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdG8gZXhhbWluZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBiaXQgbWFzayBpbmRpY2F0aW5nIHRoZSBsb3dlc3QgMSBiaXQgaW4ge0Bjb2RlIGl9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBsb3dlc3RPbmVCaXQoaW50IGkpIHsKKyAgICAgICAgcmV0dXJuIGkgJiAtaTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHRoZSBudW1iZXIgb2YgbGVhZGluZyB6ZXJvcyBpbiB0aGUgc3BlY2lmaWVkIGludGVnZXIgcHJpb3IgdG8KKyAgICAgKiB0aGUge0BsaW5rICNoaWdoZXN0T25lQml0KGludCkgaGlnaGVzdCBvbmUgYml0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB0byBleGFtaW5lLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBsZWFkaW5nIHplcm9zIGluIHtAY29kZSBpfS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgbnVtYmVyT2ZMZWFkaW5nWmVyb3MoaW50IGkpIHsKKyAgICAgICAgLy8gSGFja2VyJ3MgRGVsaWdodCwgRmlndXJlIDUtNgorICAgICAgICBpZiAoaSA8PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gKH5pID4+IDI2KSAmIDMyOworICAgICAgICB9CisgICAgICAgIGludCBuID0gMTsKKyAgICAgICAgaWYgKGkgPj4gMTYgPT0gMCkgeworICAgICAgICAgICAgbiArPSAgMTY7CisgICAgICAgICAgICBpIDw8PSAxNjsKKyAgICAgICAgfQorICAgICAgICBpZiAoaSA+PiAyNCA9PSAwKSB7CisgICAgICAgICAgICBuICs9ICA4OworICAgICAgICAgICAgaSA8PD0gODsKKyAgICAgICAgfQorICAgICAgICBpZiAoaSA+PiAyOCA9PSAwKSB7CisgICAgICAgICAgICBuICs9ICA0OworICAgICAgICAgICAgaSA8PD0gNDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaSA+PiAzMCA9PSAwKSB7CisgICAgICAgICAgICBuICs9ICAyOworICAgICAgICAgICAgaSA8PD0gMjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbiAtIChpID4+PiAzMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB0aGUgbnVtYmVyIG9mIHRyYWlsaW5nIHplcm9zIGluIHRoZSBzcGVjaWZpZWQgaW50ZWdlciBhZnRlcgorICAgICAqIHRoZSB7QGxpbmsgI2xvd2VzdE9uZUJpdChpbnQpIGxvd2VzdCBvbmUgYml0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB0byBleGFtaW5lLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiB0cmFpbGluZyB6ZXJvcyBpbiB7QGNvZGUgaX0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IG51bWJlck9mVHJhaWxpbmdaZXJvcyhpbnQgaSkgeworICAgICAgICByZXR1cm4gTlRaX1RBQkxFWygoaSAmIC1pKSAqIDB4MDQ1MEZCQUYpID4+PiAyNl07CisgICAgfQorCisgICAgLyoqCisgICAgICogQ291bnRzIHRoZSBudW1iZXIgb2YgMSBiaXRzIGluIHRoZSBzcGVjaWZpZWQgaW50ZWdlcjsgdGhpcyBpcyBhbHNvCisgICAgICogcmVmZXJyZWQgdG8gYXMgcG9wdWxhdGlvbiBjb3VudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB0byBleGFtaW5lLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiAxIGJpdHMgaW4ge0Bjb2RlIGl9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBiaXRDb3VudChpbnQgaSkgeworICAgICAgICAvLyBIYWNrZXIncyBEZWxpZ2h0LCBGaWd1cmUgNS0yCisgICAgICAgIGkgLT0gKGkgPj4gMSkgJiAweDU1NTU1NTU1OworICAgICAgICBpID0gKGkgJiAweDMzMzMzMzMzKSArICgoaSA+PiAyKSAmIDB4MzMzMzMzMzMpOworICAgICAgICBpID0gKChpID4+IDQpICsgaSkgJiAweDBGMEYwRjBGOworICAgICAgICBpICs9IGkgPj4gODsKKyAgICAgICAgaSArPSBpID4+IDE2OworICAgICAgICByZXR1cm4gaSAmIDB4MDAwMDAwM0Y7CisgICAgfQorCisgICAgLyoqCisgICAgICogUm90YXRlcyB0aGUgYml0cyBvZiB0aGUgc3BlY2lmaWVkIGludGVnZXIgdG8gdGhlIGxlZnQgYnkgdGhlIHNwZWNpZmllZAorICAgICAqIG51bWJlciBvZiBiaXRzLgorICAgICAqCisgICAgICogQHBhcmFtIGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlZ2VyIHZhbHVlIHRvIHJvdGF0ZSBsZWZ0LgorICAgICAqIEBwYXJhbSBkaXN0YW5jZQorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBiaXRzIHRvIHJvdGF0ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSByb3RhdGVkIHZhbHVlLgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCByb3RhdGVMZWZ0KGludCBpLCBpbnQgZGlzdGFuY2UpIHsKKyAgICAgICAgLy8gU2hpZnQgZGlzdGFuY2VzIGFyZSBtb2QgMzIgKEpMUzMgMTUuMTkpLCBzbyB3ZSBuZWVkbid0IG1hc2sgLWRpc3RhbmNlCisgICAgICAgIHJldHVybiAoaSA8PCBkaXN0YW5jZSkgfCAoaSA+Pj4gLWRpc3RhbmNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSb3RhdGVzIHRoZSBiaXRzIG9mIHRoZSBzcGVjaWZpZWQgaW50ZWdlciB0byB0aGUgcmlnaHQgYnkgdGhlIHNwZWNpZmllZAorICAgICAqIG51bWJlciBvZiBiaXRzLgorICAgICAqCisgICAgICogQHBhcmFtIGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlZ2VyIHZhbHVlIHRvIHJvdGF0ZSByaWdodC4KKyAgICAgKiBAcGFyYW0gZGlzdGFuY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYml0cyB0byByb3RhdGUuCisgICAgICogQHJldHVybiB0aGUgcm90YXRlZCB2YWx1ZS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgcm90YXRlUmlnaHQoaW50IGksIGludCBkaXN0YW5jZSkgeworICAgICAgICAvLyBTaGlmdCBkaXN0YW5jZXMgYXJlIG1vZCAzMiAoSkxTMyAxNS4xOSksIHNvIHdlIG5lZWRuJ3QgbWFzayAtZGlzdGFuY2UKKyAgICAgICAgcmV0dXJuIChpID4+PiBkaXN0YW5jZSkgfCAoaSA8PCAtZGlzdGFuY2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldmVyc2VzIHRoZSBvcmRlciBvZiB0aGUgYnl0ZXMgb2YgdGhlIHNwZWNpZmllZCBpbnRlZ2VyLgorICAgICAqCisgICAgICogQHBhcmFtIGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlZ2VyIHZhbHVlIGZvciB3aGljaCB0byByZXZlcnNlIHRoZSBieXRlIG9yZGVyLgorICAgICAqIEByZXR1cm4gdGhlIHJldmVyc2VkIHZhbHVlLgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCByZXZlcnNlQnl0ZXMoaW50IGkpIHsKKyAgICAgICAgLy8gSGFja2VyJ3MgRGVsaWdodCA3LTEsIHdpdGggbWlub3IgdHdlYWsgZnJvbSBWZWxkbWVpamVyCisgICAgICAgIC8vIGh0dHA6Ly9ncmFwaGljcy5zdGFuZm9yZC5lZHUvfnNlYW5kZXIvYml0aGFja3MuaHRtbAorICAgICAgICBpID0gICAgKChpID4+PiAgOCkgJiAweDAwRkYwMEZGKSB8ICgoaSAmIDB4MDBGRjAwRkYpIDw8ICA4KTsKKyAgICAgICAgcmV0dXJuICggaSA+Pj4gMTYgICAgICAgICAgICAgICkgfCAoIGkgICAgICAgICAgICAgICA8PCAxNik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV2ZXJzZXMgdGhlIG9yZGVyIG9mIHRoZSBiaXRzIG9mIHRoZSBzcGVjaWZpZWQgaW50ZWdlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB2YWx1ZSBmb3Igd2hpY2ggdG8gcmV2ZXJzZSB0aGUgYml0IG9yZGVyLgorICAgICAqIEByZXR1cm4gdGhlIHJldmVyc2VkIHZhbHVlLgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCByZXZlcnNlKGludCBpKSB7CisgICAgICAgIC8vIEhhY2tlcidzIERlbGlnaHQgNy0xLCB3aXRoIG1pbm9yIHR3ZWFrIGZyb20gVmVsZG1laWplcgorICAgICAgICAvLyBodHRwOi8vZ3JhcGhpY3Muc3RhbmZvcmQuZWR1L35zZWFuZGVyL2JpdGhhY2tzLmh0bWwKKyAgICAgICAgaSA9ICAgICgoaSA+Pj4gIDEpICYgMHg1NTU1NTU1NSkgfCAoKGkgJiAweDU1NTU1NTU1KSA8PCAgMSk7CisgICAgICAgIGkgPSAgICAoKGkgPj4+ICAyKSAmIDB4MzMzMzMzMzMpIHwgKChpICYgMHgzMzMzMzMzMykgPDwgIDIpOworICAgICAgICBpID0gICAgKChpID4+PiAgNCkgJiAweDBGMEYwRjBGKSB8ICgoaSAmIDB4MEYwRjBGMEYpIDw8ICA0KTsKKyAgICAgICAgaSA9ICAgICgoaSA+Pj4gIDgpICYgMHgwMEZGMDBGRikgfCAoKGkgJiAweDAwRkYwMEZGKSA8PCAgOCk7CisgICAgICAgIHJldHVybiAoKGkgPj4+IDE2KSAgICAgICAgICAgICApIHwgKChpICAgICAgICAgICAgICkgPDwgMTYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSB7QGNvZGUgc2lnbnVtfSBmdW5jdGlvbiBmb3IgdGhlIHNwZWNpZmllZAorICAgICAqIGludGVnZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgdG8gY2hlY2suCisgICAgICogQHJldHVybiAtMSBpZiB7QGNvZGUgaX0gaXMgbmVnYXRpdmUsIDEgaWYge0Bjb2RlIGl9IGlzIHBvc2l0aXZlLCAwIGlmCisgICAgICogICAgICAgICB7QGNvZGUgaX0gaXMgemVyby4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgc2lnbnVtKGludCBpKSB7CisgICAgICAgIHJldHVybiAoaSA+PiAzMSkgfCAoLWkgPj4+IDMxKTsgLy8gSGFja2VyJ3MgZGVsaWdodCAyLTcKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIEludGVnZXJ9IGluc3RhbmNlIGZvciB0aGUgc3BlY2lmaWVkIGludGVnZXIgdmFsdWUuCisgICAgICogPHA+CisgICAgICogSWYgaXQgaXMgbm90IG5lY2Vzc2FyeSB0byBnZXQgYSBuZXcge0Bjb2RlIEludGVnZXJ9IGluc3RhbmNlLCBpdCBpcworICAgICAqIHJlY29tbWVuZGVkIHRvIHVzZSB0aGlzIG1ldGhvZCBpbnN0ZWFkIG9mIHRoZSBjb25zdHJ1Y3Rvciwgc2luY2UgaXQKKyAgICAgKiBtYWludGFpbnMgYSBjYWNoZSBvZiBpbnN0YW5jZXMgd2hpY2ggbWF5IHJlc3VsdCBpbiBiZXR0ZXIgcGVyZm9ybWFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgdG8gc3RvcmUgaW4gdGhlIGluc3RhbmNlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgSW50ZWdlcn0gaW5zdGFuY2UgY29udGFpbmluZyB7QGNvZGUgaX0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgSW50ZWdlciB2YWx1ZU9mKGludCBpKSB7CisgICAgICAgIHJldHVybiAgaSA+PSAxMjggfHwgaSA8IC0xMjggPyBuZXcgSW50ZWdlcihpKSA6IFNNQUxMX1ZBTFVFU1tpICsgMTI4XTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBIGNhY2hlIG9mIGluc3RhbmNlcyB1c2VkIGJ5IHtAbGluayBJbnRlZ2VyI3ZhbHVlT2YoaW50KX0gYW5kIGF1dG8tYm94aW5nCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSW50ZWdlcltdIFNNQUxMX1ZBTFVFUyA9IG5ldyBJbnRlZ2VyWzI1Nl07CisKKyAgICBzdGF0aWMgeworICAgICAgICBmb3IgKGludCBpID0gLTEyODsgaSA8IDEyODsgaSsrKSB7CisgICAgICAgICAgICBTTUFMTF9WQUxVRVNbaSArIDEyOF0gPSBuZXcgSW50ZWdlcihpKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSW50ZWdyYWxUb1N0cmluZy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9JbnRlZ3JhbFRvU3RyaW5nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjYyMzRhMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSW50ZWdyYWxUb1N0cmluZy5qYXZhCkBAIC0wLDAgKzEsNTUwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogQ29udmVydHMgaW50ZWdyYWwgdHlwZXMgdG8gc3RyaW5ncy4gVGhpcyBjbGFzcyBpcyBwdWJsaWMgYnV0IGhpZGRlbiBzbyB0aGF0IGl0IGNhbiBhbHNvIGJlCisgKiB1c2VkIGJ5IGphdmEudXRpbC5Gb3JtYXR0ZXIgdG8gc3BlZWQgdXAgJWQuIFRoaXMgY2xhc3MgaXMgaW4gamF2YS5sYW5nIHNvIHRoYXQgaXQgY2FuIHRha2UKKyAqIGFkdmFudGFnZSBvZiB0aGUgcGFja2FnZS1wcml2YXRlIFN0cmluZyBjb25zdHJ1Y3Rvci4KKyAqCisgKiBUaGUgbW9zdCBpbXBvcnRhbnQgbWV0aG9kcyBhcmUgYXBwZW5kSW50L2FwcGVuZExvbmcgYW5kIGludFRvU3RyaW5nKGludCkvbG9uZ1RvU3RyaW5nKGludCkuCisgKiBUaGUgZm9ybWVyIGFyZSB1c2VkIGluIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBTdHJpbmdCdWlsZGVyLCBTdHJpbmdCdWZmZXIsIGFuZCBGb3JtYXR0ZXIsIHdoaWxlCisgKiB0aGUgbGF0dGVyIGFyZSB1c2VkIGJ5IEludGVnZXIudG9TdHJpbmcgYW5kIExvbmcudG9TdHJpbmcuCisgKgorICogVGhlIGFwcGVuZCBtZXRob2RzIHRha2UgQWJzdHJhY3RTdHJpbmdCdWlsZGVyIHJhdGhlciB0aGFuIEFwcGVuZGFibGUgYmVjYXVzZSB0aGUgbGF0dGVyIHJlcXVpcmVzCisgKiBDaGFyU2VxdWVuY2VzLCB3aGlsZSB3ZSBvbmx5IGhhdmUgcmF3IGNoYXJbXXMuIFNpbmNlIG11Y2ggb2YgdGhlIHNhdmluZ3MgY29tZSBmcm9tIG5vdCBjcmVhdGluZworICogYW55IGdhcmJhZ2UsIHdlIGNhbid0IGFmZm9yZCB0ZW1wb3JhcnkgQ2hhclNlcXVlbmNlIGluc3RhbmNlcy4KKyAqCisgKiBPbmUgZGF5IHRoZSBwZXJmb3JtYW5jZSBhZHZhbnRhZ2Ugb2YgdGhlIGJpbmFyeS9oZXgvb2N0YWwgc3BlY2lhbGl6YXRpb25zIHdpbGwgYmUgc21hbGwgZW5vdWdoCisgKiB0aGF0IHdlIGNhbiBsb3NlIHRoZSBkdXBsaWNhdGlvbiwgYnV0IHVudGlsIHRoZW4gdGhpcyBjbGFzcyBvZmZlcnMgdGhlIGZ1bGwgc2V0LgorICoKKyAqIEBoaWRlCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBJbnRlZ3JhbFRvU3RyaW5nIHsKKyAgICAvKioKKyAgICAgKiBXaGVuIGFwcGVuZGluZyB0byBhbiBBYnN0cmFjdFN0cmluZ0J1aWxkZXIsIHRoaXMgdGhyZWFkLWxvY2FsIGNoYXJbXSBsZXRzIHVzIGF2b2lkCisgICAgICogYWxsb2NhdGlvbiBvZiBhIHRlbXBvcmFyeSBhcnJheS4gKFdlIGNhbid0IHdyaXRlIHN0cmFpZ2h0IGludG8gdGhlIEFic3RyYWN0U3RyaW5nQnVpbGRlcgorICAgICAqIGJlY2F1c2UgaXQncyBhbG1vc3QgYXMgZXhwZW5zaXZlIHRvIHdvcmsgb3V0IHRoZSBleGFjdCBsZW5ndGggb2YgdGhlIHJlc3VsdCBhcyBpdCBpcyB0bworICAgICAqIGRvIHRoZSBmb3JtYXR0aW5nLiBXZSBjb3VsZCB0cnkgYmVpbmcgY29uc2VydmF0aXZlIGFuZCAiZGVsZXRlIi1pbmcgdGhlIHVudXNlZCBzcGFjZQorICAgICAqIGFmdGVyd2FyZHMsIGJ1dCB0aGVuIHdlJ2QgbmVlZCB0byBkdXBsaWNhdGUgY29udmVydEludCBhbmQgY29udmVydExvbmcgcmF0aGVyIHRoYW4gc2hhcmUKKyAgICAgKiB0aGUgY29kZS4pCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVGhyZWFkTG9jYWw8Y2hhcltdPiBCVUZGRVIgPSBuZXcgVGhyZWFkTG9jYWw8Y2hhcltdPigpIHsKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBjaGFyW10gaW5pdGlhbFZhbHVlKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBjaGFyWzIwXTsgLy8gTWF4aW11bSBsZW5ndGggb2YgYSBiYXNlLTEwIGxvbmcuCisgICAgICAgIH0KKyAgICB9OworCisgICAgLyoqCisgICAgICogVGhlc2UgdGFibGVzIGFyZSB1c2VkIHRvIHNwZWNpYWwtY2FzZSB0b1N0cmluZyBjb21wdXRhdGlvbiBmb3IKKyAgICAgKiBzbWFsbCB2YWx1ZXMuICBUaGlzIHNlcnZlcyB0aHJlZSBwdXJwb3NlczogaXQgcmVkdWNlcyBtZW1vcnkgdXNhZ2U7CisgICAgICogaXQgaW5jcmVhc2VzIHBlcmZvcm1hbmNlIGZvciBzbWFsbCB2YWx1ZXM7IGFuZCBpdCBkZWNyZWFzZXMgdGhlCisgICAgICogbnVtYmVyIG9mIGNvbXBhcmlzb25zIHJlcXVpcmVkIHRvIGRvIHRoZSBsZW5ndGggY29tcHV0YXRpb24uCisgICAgICogRWxlbWVudHMgb2YgdGhpcyB0YWJsZSBhcmUgbGF6aWx5IGluaXRpYWxpemVkIG9uIGZpcnN0IHVzZS4KKyAgICAgKiBObyBsb2NraW5nIGlzIG5lY2Vzc2FyeSwgaS5lLiwgd2UgdXNlIHRoZSBub24tdm9sYXRpbGUsIHJhY3kKKyAgICAgKiBzaW5nbGUtY2hlY2sgaWRpb20uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gU01BTExfTk9OTkVHQVRJVkVfVkFMVUVTID0gbmV3IFN0cmluZ1sxMDBdOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIFNNQUxMX05FR0FUSVZFX1ZBTFVFUyA9IG5ldyBTdHJpbmdbMTAwXTsKKworICAgIC8qKiBURU5TW2ldIGNvbnRhaW5zIHRoZSB0ZW5zIGRpZ2l0IG9mIHRoZSBudW1iZXIgaSwgMCA8PSBpIDw9IDk5LiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBURU5TID0geworICAgICAgICAnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcsCisgICAgICAgICcxJywgJzEnLCAnMScsICcxJywgJzEnLCAnMScsICcxJywgJzEnLCAnMScsICcxJywKKyAgICAgICAgJzInLCAnMicsICcyJywgJzInLCAnMicsICcyJywgJzInLCAnMicsICcyJywgJzInLAorICAgICAgICAnMycsICczJywgJzMnLCAnMycsICczJywgJzMnLCAnMycsICczJywgJzMnLCAnMycsCisgICAgICAgICc0JywgJzQnLCAnNCcsICc0JywgJzQnLCAnNCcsICc0JywgJzQnLCAnNCcsICc0JywKKyAgICAgICAgJzUnLCAnNScsICc1JywgJzUnLCAnNScsICc1JywgJzUnLCAnNScsICc1JywgJzUnLAorICAgICAgICAnNicsICc2JywgJzYnLCAnNicsICc2JywgJzYnLCAnNicsICc2JywgJzYnLCAnNicsCisgICAgICAgICc3JywgJzcnLCAnNycsICc3JywgJzcnLCAnNycsICc3JywgJzcnLCAnNycsICc3JywKKyAgICAgICAgJzgnLCAnOCcsICc4JywgJzgnLCAnOCcsICc4JywgJzgnLCAnOCcsICc4JywgJzgnLAorICAgICAgICAnOScsICc5JywgJzknLCAnOScsICc5JywgJzknLCAnOScsICc5JywgJzknLCAnOScKKyAgICB9OworCisgICAgLyoqIE9uZXMgW2ldIGNvbnRhaW5zIHRoZSB0ZW5zIGRpZ2l0IG9mIHRoZSBudW1iZXIgaSwgMCA8PSBpIDw9IDk5LiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBPTkVTID0geworICAgICAgICAnMCcsICcxJywgJzInLCAnMycsICc0JywgJzUnLCAnNicsICc3JywgJzgnLCAnOScsCisgICAgICAgICcwJywgJzEnLCAnMicsICczJywgJzQnLCAnNScsICc2JywgJzcnLCAnOCcsICc5JywKKyAgICAgICAgJzAnLCAnMScsICcyJywgJzMnLCAnNCcsICc1JywgJzYnLCAnNycsICc4JywgJzknLAorICAgICAgICAnMCcsICcxJywgJzInLCAnMycsICc0JywgJzUnLCAnNicsICc3JywgJzgnLCAnOScsCisgICAgICAgICcwJywgJzEnLCAnMicsICczJywgJzQnLCAnNScsICc2JywgJzcnLCAnOCcsICc5JywKKyAgICAgICAgJzAnLCAnMScsICcyJywgJzMnLCAnNCcsICc1JywgJzYnLCAnNycsICc4JywgJzknLAorICAgICAgICAnMCcsICcxJywgJzInLCAnMycsICc0JywgJzUnLCAnNicsICc3JywgJzgnLCAnOScsCisgICAgICAgICcwJywgJzEnLCAnMicsICczJywgJzQnLCAnNScsICc2JywgJzcnLCAnOCcsICc5JywKKyAgICAgICAgJzAnLCAnMScsICcyJywgJzMnLCAnNCcsICc1JywgJzYnLCAnNycsICc4JywgJzknLAorICAgICAgICAnMCcsICcxJywgJzInLCAnMycsICc0JywgJzUnLCAnNicsICc3JywgJzgnLCAnOScsCisgICAgfTsKKworICAgIC8qKgorICAgICAqIFRhYmxlIGZvciBNT0QgLyBESVYgMTAgY29tcHV0YXRpb24gZGVzY3JpYmVkIGluIFNlY3Rpb24gMTAtMjEKKyAgICAgKiBvZiBIYW5rIFdhcnJlbidzICJIYWNrZXIncyBEZWxpZ2h0IiBvbmxpbmUgYWRkZW5kdW0uCisgICAgICogaHR0cDovL3d3dy5oYWNrZXJzZGVsaWdodC5vcmcvZGl2Y01vcmUucGRmCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIE1PRF8xMF9UQUJMRSA9IHsKKyAgICAgICAgMCwgMSwgMiwgMiwgMywgMywgNCwgNSwgNSwgNiwgNywgNywgOCwgOCwgOSwgMAorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGlnaXRzIGZvciBldmVyeSBzdXBwb3J0ZWQgcmFkaXguCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIERJR0lUUyA9IHsKKyAgICAgICAgJzAnLCAnMScsICcyJywgJzMnLCAnNCcsICc1JywgJzYnLCAnNycsICc4JywgJzknLAorICAgICAgICAnYScsICdiJywgJ2MnLCAnZCcsICdlJywgJ2YnLCAnZycsICdoJywgJ2knLCAnaicsCisgICAgICAgICdrJywgJ2wnLCAnbScsICduJywgJ28nLCAncCcsICdxJywgJ3InLCAncycsICd0JywKKyAgICAgICAgJ3UnLCAndicsICd3JywgJ3gnLCAneScsICd6JworICAgIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gVVBQRVJfQ0FTRV9ESUdJVFMgPSB7CisgICAgICAgICcwJywgJzEnLCAnMicsICczJywgJzQnLCAnNScsICc2JywgJzcnLCAnOCcsICc5JywKKyAgICAgICAgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLCAnSCcsICdJJywgJ0onLAorICAgICAgICAnSycsICdMJywgJ00nLCAnTicsICdPJywgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsCisgICAgICAgICdVJywgJ1YnLCAnVycsICdYJywgJ1knLCAnWicKKyAgICB9OworCisgICAgcHJpdmF0ZSBJbnRlZ3JhbFRvU3RyaW5nKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8gSW50ZWdlci50b1N0cmluZyhpLCByYWRpeCkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgaW50VG9TdHJpbmcoaW50IGksIGludCByYWRpeCkgeworICAgICAgICBpZiAocmFkaXggPCBDaGFyYWN0ZXIuTUlOX1JBRElYIHx8IHJhZGl4ID4gQ2hhcmFjdGVyLk1BWF9SQURJWCkgeworICAgICAgICAgICAgcmFkaXggPSAxMDsKKyAgICAgICAgfQorICAgICAgICBpZiAocmFkaXggPT0gMTApIHsKKyAgICAgICAgICAgIHJldHVybiBpbnRUb1N0cmluZyhpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIElmIGkgaXMgcG9zaXRpdmUsIG5lZ2F0ZSBpdC4gVGhpcyBpcyB0aGUgb3Bwb3NpdGUgb2Ygd2hhdCBvbmUgbWlnaHQKKyAgICAgICAgICogZXhwZWN0LiBJdCBpcyBuZWNlc3NhcnkgYmVjYXVzZSB0aGUgcmFuZ2Ugb2YgdGhlIG5lZ2F0aXZlIHZhbHVlcyBpcworICAgICAgICAgKiBzdHJpY3RseSBsYXJnZXIgdGhhbiB0aGF0IG9mIHRoZSBwb3NpdGl2ZSB2YWx1ZXM6IHRoZXJlIGlzIG5vCisgICAgICAgICAqIHBvc2l0aXZlIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gSW50ZWdlci5NSU5fVkFMVUUuCisgICAgICAgICAqLworICAgICAgICBib29sZWFuIG5lZ2F0aXZlID0gZmFsc2U7CisgICAgICAgIGlmIChpIDwgMCkgeworICAgICAgICAgICAgbmVnYXRpdmUgPSB0cnVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaSA9IC1pOworICAgICAgICB9CisKKyAgICAgICAgaW50IGJ1ZkxlbiA9IHJhZGl4IDwgOCA/IDMzIDogMTI7ICAvLyBNYXggY2hhcnMgaW4gcmVzdWx0IChjb25zZXJ2YXRpdmUpCisgICAgICAgIGNoYXJbXSBidWYgPSBuZXcgY2hhcltidWZMZW5dOworICAgICAgICBpbnQgY3Vyc29yID0gYnVmTGVuOworCisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGludCBxID0gaSAvIHJhZGl4OworICAgICAgICAgICAgYnVmWy0tY3Vyc29yXSA9IERJR0lUU1tyYWRpeCAqIHEgLSBpXTsKKyAgICAgICAgICAgIGkgPSBxOworICAgICAgICB9IHdoaWxlIChpICE9IDApOworCisgICAgICAgIGlmIChuZWdhdGl2ZSkgeworICAgICAgICAgICAgYnVmWy0tY3Vyc29yXSA9ICctJzsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGN1cnNvciwgYnVmTGVuIC0gY3Vyc29yLCBidWYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8gSW50ZWdlci50b1N0cmluZyhpKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBpbnRUb1N0cmluZyhpbnQgaSkgeworICAgICAgICByZXR1cm4gY29udmVydEludChudWxsLCBpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVpdmFsZW50IHRvIHNiLmFwcGVuZChJbnRlZ2VyLnRvU3RyaW5nKGkpKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYXBwZW5kSW50KEFic3RyYWN0U3RyaW5nQnVpbGRlciBzYiwgaW50IGkpIHsKKyAgICAgICAgY29udmVydEludChzYiwgaSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGkgYW5kIGxlYXZlcyBzYiBhbG9uZSBpZiBzYiBpcyBudWxsLgorICAgICAqIFJldHVybnMgbnVsbCBhbmQgYXBwZW5kcyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGkgdG8gc2IgaWYgc2IgaXMgbm9uLW51bGwuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGNvbnZlcnRJbnQoQWJzdHJhY3RTdHJpbmdCdWlsZGVyIHNiLCBpbnQgaSkgeworICAgICAgICBib29sZWFuIG5lZ2F0aXZlID0gZmFsc2U7CisgICAgICAgIFN0cmluZyBxdWlja1Jlc3VsdCA9IG51bGw7CisgICAgICAgIGlmIChpIDwgMCkgeworICAgICAgICAgICAgbmVnYXRpdmUgPSB0cnVlOworICAgICAgICAgICAgaSA9IC1pOworICAgICAgICAgICAgaWYgKGkgPCAxMDApIHsKKyAgICAgICAgICAgICAgICBpZiAoaSA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gSWYgLW4gaXMgc3RpbGwgbmVnYXRpdmUsIG4gaXMgSW50ZWdlci5NSU5fVkFMVUUKKyAgICAgICAgICAgICAgICAgICAgcXVpY2tSZXN1bHQgPSAiLTIxNDc0ODM2NDgiOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHF1aWNrUmVzdWx0ID0gU01BTExfTkVHQVRJVkVfVkFMVUVTW2ldOworICAgICAgICAgICAgICAgICAgICBpZiAocXVpY2tSZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgU01BTExfTkVHQVRJVkVfVkFMVUVTW2ldID0gcXVpY2tSZXN1bHQgPQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpIDwgMTAgPyBzdHJpbmdPZignLScsIE9ORVNbaV0pIDogc3RyaW5nT2YoJy0nLCBURU5TW2ldLCBPTkVTW2ldKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChpIDwgMTAwKSB7CisgICAgICAgICAgICAgICAgcXVpY2tSZXN1bHQgPSBTTUFMTF9OT05ORUdBVElWRV9WQUxVRVNbaV07CisgICAgICAgICAgICAgICAgaWYgKHF1aWNrUmVzdWx0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgU01BTExfTk9OTkVHQVRJVkVfVkFMVUVTW2ldID0gcXVpY2tSZXN1bHQgPQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPCAxMCA/IHN0cmluZ09mKE9ORVNbaV0pIDogc3RyaW5nT2YoVEVOU1tpXSwgT05FU1tpXSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChxdWlja1Jlc3VsdCAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoc2IgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNiLmFwcGVuZDAocXVpY2tSZXN1bHQpOworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHF1aWNrUmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgaW50IGJ1ZkxlbiA9IDExOyAvLyBNYXggbnVtYmVyIG9mIGNoYXJzIGluIHJlc3VsdAorICAgICAgICBjaGFyW10gYnVmID0gKHNiICE9IG51bGwpID8gQlVGRkVSLmdldCgpIDogbmV3IGNoYXJbYnVmTGVuXTsKKyAgICAgICAgaW50IGN1cnNvciA9IGJ1ZkxlbjsKKworICAgICAgICAvLyBDYWxjdWxhdGUgZGlnaXRzIHR3by1hdC1hLXRpbWUgdGlsbCByZW1haW5pbmcgZGlnaXRzIGZpdCBpbiAxNiBiaXRzCisgICAgICAgIHdoaWxlIChpID49ICgxIDw8IDE2KSkgeworICAgICAgICAgICAgLy8gQ29tcHV0ZSBxID0gbi8xMDAgYW5kIHIgPSBuICUgMTAwIGFzIHBlciAiSGFja2VyJ3MgRGVsaWdodCIgMTAtOAorICAgICAgICAgICAgaW50IHEgPSAoaW50KSAoKDB4NTFFQjg1MUZMICogaSkgPj4+IDM3KTsKKyAgICAgICAgICAgIGludCByID0gaSAtIDEwMCpxOworICAgICAgICAgICAgYnVmWy0tY3Vyc29yXSA9IE9ORVNbcl07CisgICAgICAgICAgICBidWZbLS1jdXJzb3JdID0gVEVOU1tyXTsKKyAgICAgICAgICAgIGkgPSBxOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ2FsY3VsYXRlIHJlbWFpbmluZyBkaWdpdHMgb25lLWF0LWEtdGltZSBmb3IgcGVyZm9ybWFuY2UKKyAgICAgICAgd2hpbGUgKGkgIT0gMCkgeworICAgICAgICAgICAgLy8gQ29tcHV0ZSBxID0gbi8xMCBhbmQgciA9IG4gJSAxMCBhcyBwZXIgIkhhY2tlcidzIERlbGlnaHQiIDEwLTgKKyAgICAgICAgICAgIGludCBxID0gKDB4Q0NDRCAqIGkpID4+PiAxOTsKKyAgICAgICAgICAgIGludCByID0gaSAtIDEwKnE7CisgICAgICAgICAgICBidWZbLS1jdXJzb3JdID0gRElHSVRTW3JdOworICAgICAgICAgICAgaSA9IHE7CisgICAgICAgIH0KKworICAgICAgICBpZiAobmVnYXRpdmUpIHsKKyAgICAgICAgICAgIGJ1ZlstLWN1cnNvcl0gPSAnLSc7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc2IgIT0gbnVsbCkgeworICAgICAgICAgICAgc2IuYXBwZW5kMChidWYsIGN1cnNvciwgYnVmTGVuIC0gY3Vyc29yKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoY3Vyc29yLCBidWZMZW4gLSBjdXJzb3IsIGJ1Zik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVpdmFsZW50IHRvIExvbmcudG9TdHJpbmcodiwgcmFkaXgpLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGxvbmdUb1N0cmluZyhsb25nIHYsIGludCByYWRpeCkgeworICAgICAgICBpbnQgaSA9IChpbnQpIHY7CisgICAgICAgIGlmIChpID09IHYpIHsKKyAgICAgICAgICAgIHJldHVybiBpbnRUb1N0cmluZyhpLCByYWRpeCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAocmFkaXggPCBDaGFyYWN0ZXIuTUlOX1JBRElYIHx8IHJhZGl4ID4gQ2hhcmFjdGVyLk1BWF9SQURJWCkgeworICAgICAgICAgICAgcmFkaXggPSAxMDsKKyAgICAgICAgfQorICAgICAgICBpZiAocmFkaXggPT0gMTApIHsKKyAgICAgICAgICAgIHJldHVybiBsb25nVG9TdHJpbmcodik7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBJZiB2IGlzIHBvc2l0aXZlLCBuZWdhdGUgaXQuIFRoaXMgaXMgdGhlIG9wcG9zaXRlIG9mIHdoYXQgb25lIG1pZ2h0CisgICAgICAgICAqIGV4cGVjdC4gSXQgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdGhlIHJhbmdlIG9mIHRoZSBuZWdhdGl2ZSB2YWx1ZXMgaXMKKyAgICAgICAgICogc3RyaWN0bHkgbGFyZ2VyIHRoYW4gdGhhdCBvZiB0aGUgcG9zaXRpdmUgdmFsdWVzOiB0aGVyZSBpcyBubworICAgICAgICAgKiBwb3NpdGl2ZSB2YWx1ZSBjb3JyZXNwb25kaW5nIHRvIEludGVnZXIuTUlOX1ZBTFVFLgorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiBuZWdhdGl2ZSA9IGZhbHNlOworICAgICAgICBpZiAodiA8IDApIHsKKyAgICAgICAgICAgIG5lZ2F0aXZlID0gdHJ1ZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHYgPSAtdjsKKyAgICAgICAgfQorCisgICAgICAgIGludCBidWZMZW4gPSByYWRpeCA8IDggPyA2NSA6IDIzOyAgLy8gTWF4IGNoYXJzIGluIHJlc3VsdCAoY29uc2VydmF0aXZlKQorICAgICAgICBjaGFyW10gYnVmID0gbmV3IGNoYXJbYnVmTGVuXTsKKyAgICAgICAgaW50IGN1cnNvciA9IGJ1ZkxlbjsKKworICAgICAgICBkbyB7CisgICAgICAgICAgICBsb25nIHEgPSB2IC8gcmFkaXg7CisgICAgICAgICAgICBidWZbLS1jdXJzb3JdID0gRElHSVRTWyhpbnQpIChyYWRpeCAqIHEgLSB2KV07CisgICAgICAgICAgICB2ID0gcTsKKyAgICAgICAgfSB3aGlsZSAodiAhPSAwKTsKKworICAgICAgICBpZiAobmVnYXRpdmUpIHsKKyAgICAgICAgICAgIGJ1ZlstLWN1cnNvcl0gPSAnLSc7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhjdXJzb3IsIGJ1ZkxlbiAtIGN1cnNvciwgYnVmKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVpdmFsZW50IHRvIExvbmcudG9TdHJpbmcobCkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgbG9uZ1RvU3RyaW5nKGxvbmcgbCkgeworICAgICAgICByZXR1cm4gY29udmVydExvbmcobnVsbCwgbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byBzYi5hcHBlbmQoTG9uZy50b1N0cmluZyhsKSkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFwcGVuZExvbmcoQWJzdHJhY3RTdHJpbmdCdWlsZGVyIHNiLCBsb25nIGwpIHsKKyAgICAgICAgY29udmVydExvbmcoc2IsIGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBuIGFuZCBsZWF2ZXMgc2IgYWxvbmUgaWYgc2IgaXMgbnVsbC4KKyAgICAgKiBSZXR1cm5zIG51bGwgYW5kIGFwcGVuZHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBuIHRvIHNiIGlmIHNiIGlzIG5vbi1udWxsLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBjb252ZXJ0TG9uZyhBYnN0cmFjdFN0cmluZ0J1aWxkZXIgc2IsIGxvbmcgbikgeworICAgICAgICBpbnQgaSA9IChpbnQpIG47CisgICAgICAgIGlmIChpID09IG4pIHsKKyAgICAgICAgICAgIHJldHVybiBjb252ZXJ0SW50KHNiLCBpKTsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gbmVnYXRpdmUgPSAobiA8IDApOworICAgICAgICBpZiAobmVnYXRpdmUpIHsKKyAgICAgICAgICAgIG4gPSAtbjsKKyAgICAgICAgICAgIGlmIChuIDwgMCkgeworICAgICAgICAgICAgICAgIC8vIElmIC1uIGlzIHN0aWxsIG5lZ2F0aXZlLCBuIGlzIExvbmcuTUlOX1ZBTFVFCisgICAgICAgICAgICAgICAgU3RyaW5nIHF1aWNrUmVzdWx0ID0gIi05MjIzMzcyMDM2ODU0Nzc1ODA4IjsKKyAgICAgICAgICAgICAgICBpZiAoc2IgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQwKHF1aWNrUmVzdWx0KTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBxdWlja1Jlc3VsdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGludCBidWZMZW4gPSAyMDsgLy8gTWF4aW11bSBudW1iZXIgb2YgY2hhcnMgaW4gcmVzdWx0CisgICAgICAgIGNoYXJbXSBidWYgPSAoc2IgIT0gbnVsbCkgPyBCVUZGRVIuZ2V0KCkgOiBuZXcgY2hhcltidWZMZW5dOworCisgICAgICAgIGludCBsb3cgPSAoaW50KSAobiAlIDEwMDAwMDAwMDApOyAvLyBFeHRyYWN0IGxvdy1vcmRlciA5IGRpZ2l0cworICAgICAgICBpbnQgY3Vyc29yID0gaW50SW50b0NoYXJBcnJheShidWYsIGJ1ZkxlbiwgbG93KTsKKworICAgICAgICAvLyBaZXJvLXBhZCBMb3cgb3JkZXIgcGFydCB0byA5IGRpZ2l0cworICAgICAgICB3aGlsZSAoY3Vyc29yICE9IChidWZMZW4gLSA5KSkgeworICAgICAgICAgICAgYnVmWy0tY3Vyc29yXSA9ICcwJzsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIFRoZSByZW1haW5pbmcgZGlnaXRzIGFyZSAobiAtIGxvdykgLyAxLDAwMCwwMDAsMDAwLiAgVGhpcworICAgICAgICAgKiAiZXhhY3QgZGl2aXNpb24iIGlzIGRvbmUgYXMgcGVyIHRoZSBvbmxpbmUgYWRkZW5kdW0gdG8gSGFuayBXYXJyZW4ncworICAgICAgICAgKiAiSGFja2VyJ3MgRGVsaWdodCIgMTAtMjAsIGh0dHA6Ly93d3cuaGFja2Vyc2RlbGlnaHQub3JnL2RpdmNNb3JlLnBkZgorICAgICAgICAgKi8KKyAgICAgICAgbiA9ICgobiAtIGxvdykgPj4+IDkpICogMHg4RTQ3Q0U0MjNBMkU5QzZETDsKKworICAgICAgICAvKgorICAgICAgICAgKiBJZiB0aGUgcmVtYWluaW5nIGRpZ2l0cyBmaXQgaW4gYW4gaW50LCBlbWl0IHRoZW0gdXNpbmcgYQorICAgICAgICAgKiBzaW5nbGUgY2FsbCB0byBpbnRJbnRvQ2hhckFycmF5LiBPdGhlcndpc2UsIHN0cmlwIG9mZiB0aGUKKyAgICAgICAgICogbG93LW9yZGVyIGRpZ2l0LCBwdXQgaXQgaW4gYnVmLCBhbmQgdGhlbiBjYWxsIGludEludG9DaGFyQXJyYXkKKyAgICAgICAgICogb24gdGhlIHJlbWFpbmluZyBkaWdpdHMgKHdoaWNoIG5vdyBmaXQgaW4gYW4gaW50KS4KKyAgICAgICAgICovCisgICAgICAgIGlmICgobiAmICgtMUwgPDwgMzIpKSA9PSAwKSB7CisgICAgICAgICAgICBjdXJzb3IgPSBpbnRJbnRvQ2hhckFycmF5KGJ1ZiwgY3Vyc29yLCAoaW50KSBuKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBTZXQgbWlkRGlnaXQgdG8gbiAlIDEwCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGludCBsbzMyID0gKGludCkgbjsKKyAgICAgICAgICAgIGludCBoaTMyID0gKGludCkgKG4gPj4+IDMyKTsKKworICAgICAgICAgICAgLy8gbWlkRGlnaXQgPSAoKHVuc2lnbmVkKSBsb3czMikgJSAxMCwgcGVyICJIYWNrZXIncyBEZWxpZ2h0IiAxMC0yMQorICAgICAgICAgICAgaW50IG1pZERpZ2l0ID0gTU9EXzEwX1RBQkxFWygweDE5OTk5OTk5ICogbG8zMiArIChsbzMyID4+PiAxKSArIChsbzMyID4+PiAzKSkgPj4+IDI4XTsKKworICAgICAgICAgICAgLy8gQWRqdXN0IG1pZERpZ2l0IGZvciBoaTMyLiAoYXNzZXJ0IGhpMzIgPT0gMSB8fCBoaTMyID09IDIpCisgICAgICAgICAgICBtaWREaWdpdCAtPSBoaTMyIDw8IDI7ICAvLyAxTCA8PCAzMiA9PSAtNCBNT0QgMTAKKyAgICAgICAgICAgIGlmIChtaWREaWdpdCA8IDApIHsKKyAgICAgICAgICAgICAgICBtaWREaWdpdCArPSAxMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ1ZlstLWN1cnNvcl0gPSBESUdJVFNbbWlkRGlnaXRdOworCisgICAgICAgICAgICAvLyBFeGFjdCBkaXZpc2lvbiBhcyBwZXIgV2FycmVuIDEwLTIwCisgICAgICAgICAgICBpbnQgcmVzdCA9ICgoaW50KSAoKG4gLSBtaWREaWdpdCkgPj4+IDEpKSAqIDB4Q0NDQ0NDQ0Q7CisgICAgICAgICAgICBjdXJzb3IgPSBpbnRJbnRvQ2hhckFycmF5KGJ1ZiwgY3Vyc29yLCByZXN0KTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChuZWdhdGl2ZSkgeworICAgICAgICAgICAgYnVmWy0tY3Vyc29yXSA9ICctJzsKKyAgICAgICAgfQorICAgICAgICBpZiAoc2IgIT0gbnVsbCkgeworICAgICAgICAgICAgc2IuYXBwZW5kMChidWYsIGN1cnNvciwgYnVmTGVuIC0gY3Vyc29yKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoY3Vyc29yLCBidWZMZW4gLSBjdXJzb3IsIGJ1Zik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSB1bnNpZ25lZCBkZWNpbWFsIGludGVnZXIgcmVwcmVzZW50ZWQgYnkgbiBpbnRvIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjaGFyYWN0ZXIgYXJyYXkgc3RhcnRpbmcgYXQgcG9zaXRpb24gY3Vyc29yLiAgUmV0dXJucyB0aGUgaW5kZXggYWZ0ZXIKKyAgICAgKiB0aGUgbGFzdCBjaGFyYWN0ZXIgaW5zZXJ0ZWQgKGkuZS4sIHRoZSB2YWx1ZSB0byBwYXNzIGluIGFzIGN1cnNvciB0aGUKKyAgICAgKiBuZXh0IHRpbWUgdGhpcyBtZXRob2QgaXMgY2FsbGVkKS4gTm90ZSB0aGF0IG4gaXMgaW50ZXJwcmV0ZWQgYXMgYSBsYXJnZQorICAgICAqIHBvc2l0aXZlIGludGVnZXIgKG5vdCBhIG5lZ2F0aXZlIGludGVnZXIpIGlmIGl0cyBzaWduIGJpdCBpcyBzZXQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGludEludG9DaGFyQXJyYXkoY2hhcltdIGJ1ZiwgaW50IGN1cnNvciwgaW50IG4pIHsKKyAgICAgICAgLy8gQ2FsY3VsYXRlIGRpZ2l0cyB0d28tYXQtYS10aW1lIHRpbGwgcmVtYWluaW5nIGRpZ2l0cyBmaXQgaW4gMTYgYml0cworICAgICAgICB3aGlsZSAoKG4gJiAweGZmZmYwMDAwKSAhPSAwKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogQ29tcHV0ZSBxID0gbi8xMDAgYW5kIHIgPSBuICUgMTAwIGFzIHBlciAiSGFja2VyJ3MgRGVsaWdodCIgMTAtOC4KKyAgICAgICAgICAgICAqIFRoaXMgY29tcHV0YXRpb24gaXMgc2xpZ2h0bHkgZGlmZmVyZW50IGZyb20gdGhlIGNvcnJlc3BvbmRpbmcKKyAgICAgICAgICAgICAqIGNvbXB1dGF0aW9uIGluIGludFRvU3RyaW5nOiB0aGUgc2hpZnRzIGJlZm9yZSBhbmQgYWZ0ZXIKKyAgICAgICAgICAgICAqIG11bHRpcGx5IGNhbid0IGJlIGNvbWJpbmVkLCBhcyB0aGF0IHdvdWxkIHlpZWxkIHRoZSB3cm9uZyByZXN1bHQKKyAgICAgICAgICAgICAqIGlmIG4ncyBzaWduIGJpdCB3ZXJlIHNldC4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaW50IHEgPSAoaW50KSAoKDB4NTFFQjg1MUZMICogKG4gPj4+IDIpKSA+Pj4gMzUpOworICAgICAgICAgICAgaW50IHIgPSBuIC0gMTAwKnE7CisgICAgICAgICAgICBidWZbLS1jdXJzb3JdID0gT05FU1tyXTsKKyAgICAgICAgICAgIGJ1ZlstLWN1cnNvcl0gPSBURU5TW3JdOworICAgICAgICAgICAgbiA9IHE7CisgICAgICAgIH0KKworICAgICAgICAvLyBDYWxjdWxhdGUgcmVtYWluaW5nIGRpZ2l0cyBvbmUtYXQtYS10aW1lIGZvciBwZXJmb3JtYW5jZQorICAgICAgICB3aGlsZSAobiAhPSAwKSB7CisgICAgICAgICAgICAvLyBDb21wdXRlIHEgPSBuIC8gMTAgYW5kIHIgPSBuICUgMTAgYXMgcGVyICJIYWNrZXIncyBEZWxpZ2h0IiAxMC04CisgICAgICAgICAgICBpbnQgcSA9ICgweENDQ0QgKiBuKSA+Pj4gMTk7CisgICAgICAgICAgICBpbnQgciA9IG4gLSAxMCpxOworICAgICAgICAgICAgYnVmWy0tY3Vyc29yXSA9IERJR0lUU1tyXTsKKyAgICAgICAgICAgIG4gPSBxOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjdXJzb3I7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgaW50VG9CaW5hcnlTdHJpbmcoaW50IGkpIHsKKyAgICAgICAgaW50IGJ1ZkxlbiA9IDMyOyAgLy8gTWF4IG51bWJlciBvZiBiaW5hcnkgZGlnaXRzIGluIGFuIGludAorICAgICAgICBjaGFyW10gYnVmID0gbmV3IGNoYXJbYnVmTGVuXTsKKyAgICAgICAgaW50IGN1cnNvciA9IGJ1ZkxlbjsKKworICAgICAgICBkbyB7CisgICAgICAgICAgICBidWZbLS1jdXJzb3JdID0gRElHSVRTW2kgJiAxXTsKKyAgICAgICAgfSAgd2hpbGUgKChpID4+Pj0gMSkgIT0gMCk7CisKKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoY3Vyc29yLCBidWZMZW4gLSBjdXJzb3IsIGJ1Zik7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgbG9uZ1RvQmluYXJ5U3RyaW5nKGxvbmcgdikgeworICAgICAgICBpbnQgaSA9IChpbnQpIHY7CisgICAgICAgIGlmICh2ID49IDAgJiYgaSA9PSB2KSB7CisgICAgICAgICAgICByZXR1cm4gaW50VG9CaW5hcnlTdHJpbmcoaSk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgYnVmTGVuID0gNjQ7ICAvLyBNYXggbnVtYmVyIG9mIGJpbmFyeSBkaWdpdHMgaW4gYSBsb25nCisgICAgICAgIGNoYXJbXSBidWYgPSBuZXcgY2hhcltidWZMZW5dOworICAgICAgICBpbnQgY3Vyc29yID0gYnVmTGVuOworCisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGJ1ZlstLWN1cnNvcl0gPSBESUdJVFNbKChpbnQpIHYpICYgMV07CisgICAgICAgIH0gIHdoaWxlICgodiA+Pj49IDEpICE9IDApOworCisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGN1cnNvciwgYnVmTGVuIC0gY3Vyc29yLCBidWYpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nQnVpbGRlciBhcHBlbmRCeXRlQXNIZXgoU3RyaW5nQnVpbGRlciBzYiwgYnl0ZSBiLCBib29sZWFuIHVwcGVyQ2FzZSkgeworICAgICAgICBjaGFyW10gZGlnaXRzID0gdXBwZXJDYXNlID8gVVBQRVJfQ0FTRV9ESUdJVFMgOiBESUdJVFM7CisgICAgICAgIHNiLmFwcGVuZChkaWdpdHNbKGIgPj4gNCkgJiAweGZdKTsKKyAgICAgICAgc2IuYXBwZW5kKGRpZ2l0c1tiICYgMHhmXSk7CisgICAgICAgIHJldHVybiBzYjsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBieXRlVG9IZXhTdHJpbmcoYnl0ZSBiLCBib29sZWFuIHVwcGVyQ2FzZSkgeworICAgICAgICBjaGFyW10gZGlnaXRzID0gdXBwZXJDYXNlID8gVVBQRVJfQ0FTRV9ESUdJVFMgOiBESUdJVFM7CisgICAgICAgIGNoYXJbXSBidWYgPSBuZXcgY2hhclsyXTsgLy8gV2UgYWx3YXlzIHdhbnQgdHdvIGRpZ2l0cy4KKyAgICAgICAgYnVmWzBdID0gZGlnaXRzWyhiID4+IDQpICYgMHhmXTsKKyAgICAgICAgYnVmWzFdID0gZGlnaXRzW2IgJiAweGZdOworICAgICAgICByZXR1cm4gbmV3IFN0cmluZygwLCAyLCBidWYpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGJ5dGVzVG9IZXhTdHJpbmcoYnl0ZVtdIGJ5dGVzLCBib29sZWFuIHVwcGVyQ2FzZSkgeworICAgICAgICBjaGFyW10gZGlnaXRzID0gdXBwZXJDYXNlID8gVVBQRVJfQ0FTRV9ESUdJVFMgOiBESUdJVFM7CisgICAgICAgIGNoYXJbXSBidWYgPSBuZXcgY2hhcltieXRlcy5sZW5ndGggKiAyXTsKKyAgICAgICAgaW50IGMgPSAwOworICAgICAgICBmb3IgKGJ5dGUgYiA6IGJ5dGVzKSB7CisgICAgICAgICAgICBidWZbYysrXSA9IGRpZ2l0c1soYiA+PiA0KSAmIDB4Zl07CisgICAgICAgICAgICBidWZbYysrXSA9IGRpZ2l0c1tiICYgMHhmXTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhidWYpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGludFRvSGV4U3RyaW5nKGludCBpLCBib29sZWFuIHVwcGVyQ2FzZSwgaW50IG1pbldpZHRoKSB7CisgICAgICAgIGludCBidWZMZW4gPSA4OyAgLy8gTWF4IG51bWJlciBvZiBoZXggZGlnaXRzIGluIGFuIGludAorICAgICAgICBjaGFyW10gYnVmID0gbmV3IGNoYXJbYnVmTGVuXTsKKyAgICAgICAgaW50IGN1cnNvciA9IGJ1ZkxlbjsKKworICAgICAgICBjaGFyW10gZGlnaXRzID0gdXBwZXJDYXNlID8gVVBQRVJfQ0FTRV9ESUdJVFMgOiBESUdJVFM7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGJ1ZlstLWN1cnNvcl0gPSBkaWdpdHNbaSAmIDB4Zl07CisgICAgICAgIH0gd2hpbGUgKChpID4+Pj0gNCkgIT0gMCB8fCAoYnVmTGVuIC0gY3Vyc29yIDwgbWluV2lkdGgpKTsKKworICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhjdXJzb3IsIGJ1ZkxlbiAtIGN1cnNvciwgYnVmKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBsb25nVG9IZXhTdHJpbmcobG9uZyB2KSB7CisgICAgICAgIGludCBpID0gKGludCkgdjsKKyAgICAgICAgaWYgKHYgPj0gMCAmJiBpID09IHYpIHsKKyAgICAgICAgICAgIHJldHVybiBpbnRUb0hleFN0cmluZyhpLCBmYWxzZSwgMCk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgYnVmTGVuID0gMTY7ICAvLyBNYXggbnVtYmVyIG9mIGhleCBkaWdpdHMgaW4gYSBsb25nCisgICAgICAgIGNoYXJbXSBidWYgPSBuZXcgY2hhcltidWZMZW5dOworICAgICAgICBpbnQgY3Vyc29yID0gYnVmTGVuOworCisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGJ1ZlstLWN1cnNvcl0gPSBESUdJVFNbKChpbnQpIHYpICYgMHhGXTsKKyAgICAgICAgfSB3aGlsZSAoKHYgPj4+PSA0KSAhPSAwKTsKKworICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhjdXJzb3IsIGJ1ZkxlbiAtIGN1cnNvciwgYnVmKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBpbnRUb09jdGFsU3RyaW5nKGludCBpKSB7CisgICAgICAgIGludCBidWZMZW4gPSAxMTsgIC8vIE1heCBudW1iZXIgb2Ygb2N0YWwgZGlnaXRzIGluIGFuIGludAorICAgICAgICBjaGFyW10gYnVmID0gbmV3IGNoYXJbYnVmTGVuXTsKKyAgICAgICAgaW50IGN1cnNvciA9IGJ1ZkxlbjsKKworICAgICAgICBkbyB7CisgICAgICAgICAgICBidWZbLS1jdXJzb3JdID0gRElHSVRTW2kgJiA3XTsKKyAgICAgICAgfSB3aGlsZSAoKGkgPj4+PSAzKSAhPSAwKTsKKworICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhjdXJzb3IsIGJ1ZkxlbiAtIGN1cnNvciwgYnVmKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBsb25nVG9PY3RhbFN0cmluZyhsb25nIHYpIHsKKyAgICAgICAgaW50IGkgPSAoaW50KSB2OworICAgICAgICBpZiAodiA+PSAwICYmIGkgPT0gdikgeworICAgICAgICAgICAgcmV0dXJuIGludFRvT2N0YWxTdHJpbmcoaSk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGJ1ZkxlbiA9IDIyOyAgLy8gTWF4IG51bWJlciBvZiBvY3RhbCBkaWdpdHMgaW4gYSBsb25nCisgICAgICAgIGNoYXJbXSBidWYgPSBuZXcgY2hhcltidWZMZW5dOworICAgICAgICBpbnQgY3Vyc29yID0gYnVmTGVuOworCisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGJ1ZlstLWN1cnNvcl0gPSBESUdJVFNbKChpbnQpIHYpICYgN107CisgICAgICAgIH0gd2hpbGUgKCh2ID4+Pj0gMykgIT0gMCk7CisKKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoY3Vyc29yLCBidWZMZW4gLSBjdXJzb3IsIGJ1Zik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb21wb3NlZCBvZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlcnMuIE5vdGUgdGhhdCB0aGUKKyAgICAgKiBhdXRvYm94aW5nIGRvZXMgKm5vdCogcmVzdWx0IGluIGFuIGV4dHJhIGNvcHkgb2YgdGhlIGNoYXIgYXJyYXk6IHdlIGFyZQorICAgICAqIHVzaW5nIGEgcGFja2FnZS1wcml2YXRlIHN0cmluZyBjb25zdHJ1Y3RvciB0aGF0IGluY29ycG9yYXRlcyB0aGUKKyAgICAgKiAiYXV0b2JveGluZyBhcnJheSIgaW50byB0aGUgbmV3IHN0cmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgc3RyaW5nT2YoY2hhci4uLiBhcmdzKSB7CisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKDAsIGFyZ3MubGVuZ3RoLCBhcmdzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0ludGVybmFsRXJyb3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSW50ZXJuYWxFcnJvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZkMWUwNTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0ludGVybmFsRXJyb3IuamF2YQpAQCAtMCwwICsxLDQ0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gd2hlbiB0aGUgVk0gbm90aWNlcyB0aGF0IGl0IGhhcyBnb3R0ZW4gaW50byBhbiB1bmRlZmluZWQgc3RhdGUuCisgKi8KK3B1YmxpYyBjbGFzcyBJbnRlcm5hbEVycm9yIGV4dGVuZHMgVmlydHVhbE1hY2hpbmVFcnJvciB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtOTA2MjU5MzQxNjEyNTU2MjM2NUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJbnRlcm5hbEVycm9yfSB0aGF0IGluY2x1ZGVzIHRoZSBjdXJyZW50IHN0YWNrCisgICAgICogdHJhY2UuCisgICAgICovCisgICAgcHVibGljIEludGVybmFsRXJyb3IoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSW50ZXJuYWxFcnJvcn0gd2l0aCB0aGUgY3VycmVudCBzdGFjayB0cmFjZSBhbmQKKyAgICAgKiB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW50ZXJuYWxFcnJvcihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0ludGVycnVwdGVkRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0ludGVycnVwdGVkRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjg3ODkzOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSW50ZXJydXB0ZWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQ1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gd2hlbiBhIHdhaXRpbmcgdGhyZWFkIGlzIGFjdGl2YXRlZCBiZWZvcmUgdGhlIGNvbmRpdGlvbiBpdCB3YXMgd2FpdGluZworICogZm9yIGhhcyBiZWVuIHNhdGlzZmllZC4KKyAqLworcHVibGljIGNsYXNzIEludGVycnVwdGVkRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDY3MDA2OTczNzYxMDA2Mjg0NzNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSW50ZXJydXB0ZWRFeGNlcHRpb259IHRoYXQgaW5jbHVkZXMgdGhlIGN1cnJlbnQKKyAgICAgKiBzdGFjayB0cmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW50ZXJydXB0ZWRFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSW50ZXJydXB0ZWRFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQgc3RhY2sKKyAgICAgKiB0cmFjZSBhbmQgdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0l0ZXJhYmxlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0l0ZXJhYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjkzNmQyYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvSXRlcmFibGUuamF2YQpAQCAtMCwwICsxLDM1IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKKworLyoqCisgKiBJbnN0YW5jZXMgb2YgY2xhc3NlcyB0aGF0IGltcGxlbWVudCB0aGlzIGludGVyZmFjZSBjYW4gYmUgdXNlZCB3aXRoCisgKiB0aGUgZW5oYW5jZWQgZm9yIGxvb3AuCisgKgorICogQHNpbmNlIDEuNQorICovCitwdWJsaWMgaW50ZXJmYWNlIEl0ZXJhYmxlPFQ+IHsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4ge0BsaW5rIEl0ZXJhdG9yfSBmb3IgdGhlIGVsZW1lbnRzIGluIHRoaXMgb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybiBBbiB7QGNvZGUgSXRlcmF0b3J9IGluc3RhbmNlLgorICAgICAqLworICAgIEl0ZXJhdG9yPFQ+IGl0ZXJhdG9yKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0xpbmthZ2VFcnJvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9MaW5rYWdlRXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYmQwYTUzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9MaW5rYWdlRXJyb3IuamF2YQpAQCAtMCwwICsxLDU3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworCisvKioKKyAqIHtAY29kZSBMaW5rYWdlRXJyb3J9IGlzIHRoZSBzdXBlcmNsYXNzIG9mIGFsbCBlcnJvciBjbGFzc2VzIHRoYXQgb2NjdXIgd2hlbgorICogbG9hZGluZyBhbmQgbGlua2luZyBjbGFzcyBmaWxlcy4KKyAqCisgKiBAc2VlIEVycm9yCisgKi8KK3B1YmxpYyBjbGFzcyBMaW5rYWdlRXJyb3IgZXh0ZW5kcyBFcnJvciB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzNTc5NjAwMTA4MTU3MTYwMTIyTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIExpbmthZ2VFcnJvcn0gdGhhdCBpbmNsdWRlcyB0aGUgY3VycmVudCBzdGFjaworICAgICAqIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBMaW5rYWdlRXJyb3IoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTGlua2FnZUVycm9yfSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlIGFuZAorICAgICAqIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBMaW5rYWdlRXJyb3IoU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTGlua2FnZUVycm9yfSB3aXRoIHRoZSBnaXZlbiBkZXRhaWwgbWVzc2FnZSBhbmQgY2F1c2UuCisgICAgICogQHNpbmNlIDEuNworICAgICAqIEBoaWRlIDEuNworICAgICAqLworICAgIHB1YmxpYyBMaW5rYWdlRXJyb3IoU3RyaW5nIGRldGFpbE1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlLCBjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Mb25nLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL0xvbmcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YjU5MmUyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Mb25nLmphdmEKQEAgLTAsMCArMSw3NDEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIFRoZSB3cmFwcGVyIGZvciB0aGUgcHJpbWl0aXZlIHR5cGUge0Bjb2RlIGxvbmd9LgorICogPHA+CisgKiBJbXBsZW1lbnRhdGlvbiBub3RlOiBUaGUgImJpdCB0d2lkZGxpbmciIG1ldGhvZHMgaW4gdGhpcyBjbGFzcyB1c2UgdGVjaG5pcXVlcworICogZGVzY3JpYmVkIGluIDxhIGhyZWY9Imh0dHA6Ly93d3cuaGFja2Vyc2RlbGlnaHQub3JnLyI+SGVucnkgUy4gV2FycmVuLAorICogSnIuJ3MgSGFja2VyJ3MgRGVsaWdodCwgKEFkZGlzb24gV2VzbGV5LCAyMDAyKTwvYT4gYW5kIDxhIGhyZWY9CisgKiAiaHR0cDovL2dyYXBoaWNzLnN0YW5mb3JkLmVkdS9+c2VhbmRlci9iaXRoYWNrcy5odG1sIj5TZWFuIEFuZGVyc29uJ3MKKyAqIEJpdCBUd2lkZGxpbmcgSGFja3MuPC9hPgorICoKKyAqIEBzZWUgamF2YS5sYW5nLkludGVnZXIKKyAqIEBzaW5jZSAxLjAKKyAqLworQEZpbmRCdWdzU3VwcHJlc3NXYXJuaW5ncygiRE1fTlVNQkVSX0NUT1IiKQorcHVibGljIGZpbmFsIGNsYXNzIExvbmcgZXh0ZW5kcyBOdW1iZXIgaW1wbGVtZW50cyBDb21wYXJhYmxlPExvbmc+IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDQyOTA3NzQzODA1NTg4ODU4NTVMOworCisgICAgLyoqCisgICAgICogVGhlIHZhbHVlIHdoaWNoIHRoZSByZWNlaXZlciByZXByZXNlbnRzLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgbG9uZyB2YWx1ZTsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IGZvciB0aGUgbWF4aW11bSB7QGNvZGUgbG9uZ30gdmFsdWUsIDI8c3VwPjYzPC9zdXA+LTEuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIE1BWF9WQUxVRSA9IDB4N0ZGRkZGRkZGRkZGRkZGRkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCBmb3IgdGhlIG1pbmltdW0ge0Bjb2RlIGxvbmd9IHZhbHVlLCAtMjxzdXA+NjM8L3N1cD4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIE1JTl9WQUxVRSA9IDB4ODAwMDAwMDAwMDAwMDAwMEw7CisKKyAgICAvKioKKyAgICAgKiBUaGUge0BsaW5rIENsYXNzfSBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBwcmltaXRpdmUgdHlwZSB7QGNvZGUgbG9uZ30uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDbGFzczxMb25nPiBUWVBFCisgICAgICAgICAgICA9IChDbGFzczxMb25nPikgbG9uZ1tdLmNsYXNzLmdldENvbXBvbmVudFR5cGUoKTsKKyAgICAvLyBOb3RlOiBMb25nLlRZUEUgY2FuJ3QgYmUgc2V0IHRvICJsb25nLmNsYXNzIiwgc2luY2UgKnRoYXQqIGlzCisgICAgLy8gZGVmaW5lZCB0byBiZSAiamF2YS5sYW5nLkxvbmcuVFlQRSI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCBmb3IgdGhlIG51bWJlciBvZiBiaXRzIG5lZWRlZCB0byByZXByZXNlbnQgYSB7QGNvZGUgbG9uZ30gaW4KKyAgICAgKiB0d28ncyBjb21wbGVtZW50IGZvcm0uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0laRSA9IDY0OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTG9uZ30gd2l0aCB0aGUgc3BlY2lmaWVkIHByaW1pdGl2ZSBsb25nIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgcHJpbWl0aXZlIGxvbmcgdmFsdWUgdG8gc3RvcmUgaW4gdGhlIG5ldyBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTG9uZyhsb25nIHZhbHVlKSB7CisgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBMb25nfSBmcm9tIHRoZSBzcGVjaWZpZWQgc3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIGxvbmcgdmFsdWUuCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyaW5nfSBjYW5ub3QgYmUgcGFyc2VkIGFzIGEgbG9uZyB2YWx1ZS4KKyAgICAgKiBAc2VlICNwYXJzZUxvbmcoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBMb25nKFN0cmluZyBzdHJpbmcpIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24geworICAgICAgICB0aGlzKHBhcnNlTG9uZyhzdHJpbmcpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZSBieXRlVmFsdWUoKSB7CisgICAgICAgIHJldHVybiAoYnl0ZSkgdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBvYmplY3QgdG8gdGhlIHNwZWNpZmllZCBsb25nIG9iamVjdCB0byBkZXRlcm1pbmUgdGhlaXIKKyAgICAgKiByZWxhdGl2ZSBvcmRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb25nIG9iamVjdCB0byBjb21wYXJlIHRoaXMgb2JqZWN0IHRvLgorICAgICAqIEByZXR1cm4gYSBuZWdhdGl2ZSB2YWx1ZSBpZiB0aGUgdmFsdWUgb2YgdGhpcyBsb25nIGlzIGxlc3MgdGhhbiB0aGUgdmFsdWUKKyAgICAgKiAgICAgICAgIG9mIHtAY29kZSBvYmplY3R9OyAwIGlmIHRoZSB2YWx1ZSBvZiB0aGlzIGxvbmcgYW5kIHRoZSB2YWx1ZSBvZgorICAgICAqICAgICAgICAge0Bjb2RlIG9iamVjdH0gYXJlIGVxdWFsOyBhIHBvc2l0aXZlIHZhbHVlIGlmIHRoZSB2YWx1ZSBvZiB0aGlzCisgICAgICogICAgICAgICBsb25nIGlzIGdyZWF0ZXIgdGhhbiB0aGUgdmFsdWUgb2Yge0Bjb2RlIG9iamVjdH0uCisgICAgICogQHNlZSBqYXZhLmxhbmcuQ29tcGFyYWJsZQorICAgICAqIEBzaW5jZSAxLjIKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhMb25nIG9iamVjdCkgeworICAgICAgICByZXR1cm4gY29tcGFyZSh2YWx1ZSwgb2JqZWN0LnZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0d28ge0Bjb2RlIGxvbmd9IHZhbHVlcy4KKyAgICAgKiBAcmV0dXJuIDAgaWYgbGhzID0gcmhzLCBsZXNzIHRoYW4gMCBpZiBsaHMgJmx0OyByaHMsIGFuZCBncmVhdGVyIHRoYW4gMCBpZiBsaHMgJmd0OyByaHMuCisgICAgICogQHNpbmNlIDEuNworICAgICAqIEBoaWRlIDEuNworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXBhcmUobG9uZyBsaHMsIGxvbmcgcmhzKSB7CisgICAgICAgIHJldHVybiBsaHMgPCByaHMgPyAtMSA6IChsaHMgPT0gcmhzID8gMCA6IDEpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIE51bWJlckZvcm1hdEV4Y2VwdGlvbiBpbnZhbGlkTG9uZyhTdHJpbmcgcykgeworICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkIGxvbmc6IFwiIiArIHMgKyAiXCIiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgdGhlIHNwZWNpZmllZCBzdHJpbmcgYW5kIHJldHVybnMgYSB7QGNvZGUgTG9uZ30gaW5zdGFuY2UgaWYgdGhlCisgICAgICogc3RyaW5nIGNhbiBiZSBkZWNvZGVkIGludG8gYSBsb25nIHZhbHVlLiBUaGUgc3RyaW5nIG1heSBiZSBhbiBvcHRpb25hbAorICAgICAqIG1pbnVzIHNpZ24gIi0iIGZvbGxvd2VkIGJ5IGEgaGV4YWRlY2ltYWwgKCIweC4uLiIgb3IgIiMuLi4iKSwgb2N0YWwKKyAgICAgKiAoIjAuLi4iKSwgb3IgZGVjaW1hbCAoIi4uLiIpIHJlcHJlc2VudGF0aW9uIG9mIGEgbG9uZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgbG9uZyB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIExvbmd9IGNvbnRhaW5pbmcgdGhlIHZhbHVlIHJlcHJlc2VudGVkIGJ5IHtAY29kZSBzdHJpbmd9LgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0cmluZ30gY2Fubm90IGJlIHBhcnNlZCBhcyBhIGxvbmcgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBMb25nIGRlY29kZShTdHJpbmcgc3RyaW5nKSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGxlbmd0aCA9IHN0cmluZy5sZW5ndGgoKSwgaSA9IDA7CisgICAgICAgIGlmIChsZW5ndGggPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgaW52YWxpZExvbmcoc3RyaW5nKTsKKyAgICAgICAgfQorICAgICAgICBjaGFyIGZpcnN0RGlnaXQgPSBzdHJpbmcuY2hhckF0KGkpOworICAgICAgICBib29sZWFuIG5lZ2F0aXZlID0gZmlyc3REaWdpdCA9PSAnLSc7CisgICAgICAgIGlmIChuZWdhdGl2ZSkgeworICAgICAgICAgICAgaWYgKGxlbmd0aCA9PSAxKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgaW52YWxpZExvbmcoc3RyaW5nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpcnN0RGlnaXQgPSBzdHJpbmcuY2hhckF0KCsraSk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgYmFzZSA9IDEwOworICAgICAgICBpZiAoZmlyc3REaWdpdCA9PSAnMCcpIHsKKyAgICAgICAgICAgIGlmICgrK2kgPT0gbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlT2YoMEwpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKChmaXJzdERpZ2l0ID0gc3RyaW5nLmNoYXJBdChpKSkgPT0gJ3gnIHx8IGZpcnN0RGlnaXQgPT0gJ1gnKSB7CisgICAgICAgICAgICAgICAgaWYgKGkgPT0gbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IGludmFsaWRMb25nKHN0cmluZyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgICAgICBiYXNlID0gMTY7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJhc2UgPSA4OworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKGZpcnN0RGlnaXQgPT0gJyMnKSB7CisgICAgICAgICAgICBpZiAoaSA9PSBsZW5ndGgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBpbnZhbGlkTG9uZyhzdHJpbmcpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgYmFzZSA9IDE2OworICAgICAgICB9CisKKyAgICAgICAgbG9uZyByZXN1bHQgPSBwYXJzZShzdHJpbmcsIGksIGJhc2UsIG5lZ2F0aXZlKTsKKyAgICAgICAgcmV0dXJuIHZhbHVlT2YocmVzdWx0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZG91YmxlIGRvdWJsZVZhbHVlKCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFuZCBpbmRpY2F0ZXMgaWYgdGhleQorICAgICAqIGFyZSBlcXVhbC4gSW4gb3JkZXIgdG8gYmUgZXF1YWwsIHtAY29kZSBvfSBtdXN0IGJlIGFuIGluc3RhbmNlIG9mCisgICAgICoge0Bjb2RlIExvbmd9IGFuZCBoYXZlIHRoZSBzYW1lIGxvbmcgdmFsdWUgYXMgdGhpcyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbworICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHRoaXMgbG9uZyB3aXRoLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBMb25nfTsge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgIHJldHVybiAobyBpbnN0YW5jZW9mIExvbmcpICYmICgoKExvbmcpIG8pLnZhbHVlID09IHZhbHVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXQgZmxvYXRWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBMb25nfSB2YWx1ZSBvZiB0aGUgc3lzdGVtIHByb3BlcnR5IGlkZW50aWZpZWQgYnkKKyAgICAgKiB7QGNvZGUgc3RyaW5nfS4gUmV0dXJucyB7QGNvZGUgbnVsbH0gaWYge0Bjb2RlIHN0cmluZ30gaXMge0Bjb2RlIG51bGx9CisgICAgICogb3IgZW1wdHksIGlmIHRoZSBwcm9wZXJ0eSBjYW4gbm90IGJlIGZvdW5kIG9yIGlmIGl0cyB2YWx1ZSBjYW4gbm90IGJlCisgICAgICogcGFyc2VkIGFzIGEgbG9uZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXF1ZXN0ZWQgc3lzdGVtIHByb3BlcnR5LgorICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3RlZCBwcm9wZXJ0eSdzIHZhbHVlIGFzIGEge0Bjb2RlIExvbmd9IG9yIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIExvbmcgZ2V0TG9uZyhTdHJpbmcgc3RyaW5nKSB7CisgICAgICAgIGlmIChzdHJpbmcgPT0gbnVsbCB8fCBzdHJpbmcubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHByb3AgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoc3RyaW5nKTsKKyAgICAgICAgaWYgKHByb3AgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBkZWNvZGUocHJvcCk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgTG9uZ30gdmFsdWUgb2YgdGhlIHN5c3RlbSBwcm9wZXJ0eSBpZGVudGlmaWVkIGJ5CisgICAgICoge0Bjb2RlIHN0cmluZ30uIFJldHVybnMgdGhlIHNwZWNpZmllZCBkZWZhdWx0IHZhbHVlIGlmIHtAY29kZSBzdHJpbmd9IGlzCisgICAgICoge0Bjb2RlIG51bGx9IG9yIGVtcHR5LCBpZiB0aGUgcHJvcGVydHkgY2FuIG5vdCBiZSBmb3VuZCBvciBpZiBpdHMgdmFsdWUKKyAgICAgKiBjYW4gbm90IGJlIHBhcnNlZCBhcyBhIGxvbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcmVxdWVzdGVkIHN5c3RlbSBwcm9wZXJ0eS4KKyAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgZGVmYXVsdCB2YWx1ZSB0aGF0IGlzIHJldHVybmVkIGlmIHRoZXJlIGlzIG5vIGxvbmcgc3lzdGVtCisgICAgICogICAgICAgICAgICBwcm9wZXJ0eSB3aXRoIHRoZSByZXF1ZXN0ZWQgbmFtZS4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0ZWQgcHJvcGVydHkncyB2YWx1ZSBhcyBhIHtAY29kZSBMb25nfSBvciB0aGUgZGVmYXVsdAorICAgICAqICAgICAgICAgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBMb25nIGdldExvbmcoU3RyaW5nIHN0cmluZywgbG9uZyBkZWZhdWx0VmFsdWUpIHsKKyAgICAgICAgaWYgKHN0cmluZyA9PSBudWxsIHx8IHN0cmluZy5sZW5ndGgoKSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsdWVPZihkZWZhdWx0VmFsdWUpOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBwcm9wID0gU3lzdGVtLmdldFByb3BlcnR5KHN0cmluZyk7CisgICAgICAgIGlmIChwcm9wID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiB2YWx1ZU9mKGRlZmF1bHRWYWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBkZWNvZGUocHJvcCk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgcmV0dXJuIHZhbHVlT2YoZGVmYXVsdFZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBMb25nfSB2YWx1ZSBvZiB0aGUgc3lzdGVtIHByb3BlcnR5IGlkZW50aWZpZWQgYnkKKyAgICAgKiB7QGNvZGUgc3RyaW5nfS4gUmV0dXJucyB0aGUgc3BlY2lmaWVkIGRlZmF1bHQgdmFsdWUgaWYge0Bjb2RlIHN0cmluZ30gaXMKKyAgICAgKiB7QGNvZGUgbnVsbH0gb3IgZW1wdHksIGlmIHRoZSBwcm9wZXJ0eSBjYW4gbm90IGJlIGZvdW5kIG9yIGlmIGl0cyB2YWx1ZQorICAgICAqIGNhbiBub3QgYmUgcGFyc2VkIGFzIGEgbG9uZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXF1ZXN0ZWQgc3lzdGVtIHByb3BlcnR5LgorICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZWZhdWx0IHZhbHVlIHRoYXQgaXMgcmV0dXJuZWQgaWYgdGhlcmUgaXMgbm8gbG9uZyBzeXN0ZW0KKyAgICAgKiAgICAgICAgICAgIHByb3BlcnR5IHdpdGggdGhlIHJlcXVlc3RlZCBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3RlZCBwcm9wZXJ0eSdzIHZhbHVlIGFzIGEge0Bjb2RlIExvbmd9IG9yIHRoZSBkZWZhdWx0CisgICAgICogICAgICAgICB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIExvbmcgZ2V0TG9uZyhTdHJpbmcgc3RyaW5nLCBMb25nIGRlZmF1bHRWYWx1ZSkgeworICAgICAgICBpZiAoc3RyaW5nID09IG51bGwgfHwgc3RyaW5nLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHByb3AgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoc3RyaW5nKTsKKyAgICAgICAgaWYgKHByb3AgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGRlY29kZShwcm9wKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIChpbnQpICh2YWx1ZSBeICh2YWx1ZSA+Pj4gMzIpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGludFZhbHVlKCkgeworICAgICAgICByZXR1cm4gKGludCkgdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcHJpbWl0aXZlIHZhbHVlIG9mIHRoaXMgbG9uZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBvYmplY3QncyBwcmltaXRpdmUgdmFsdWUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgbG9uZ1ZhbHVlKCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGFzIGEgc2lnbmVkIGRlY2ltYWwgbG9uZyB2YWx1ZS4gVGhlIEFTQ0lJCisgICAgICogY2hhcmFjdGVyIFx1MDAyZCAoJy0nKSBpcyByZWNvZ25pemVkIGFzIHRoZSBtaW51cyBzaWduLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIGxvbmcgdmFsdWUuCisgICAgICogQHJldHVybiB0aGUgcHJpbWl0aXZlIGxvbmcgdmFsdWUgcmVwcmVzZW50ZWQgYnkge0Bjb2RlIHN0cmluZ30uCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyaW5nfSBjYW5ub3QgYmUgcGFyc2VkIGFzIGEgbG9uZyB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgcGFyc2VMb25nKFN0cmluZyBzdHJpbmcpIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gcGFyc2VMb25nKHN0cmluZywgMTApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgc3BlY2lmaWVkIHN0cmluZyBhcyBhIHNpZ25lZCBsb25nIHZhbHVlIHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiByYWRpeC4gVGhlIEFTQ0lJIGNoYXJhY3RlciBcdTAwMmQgKCctJykgaXMgcmVjb2duaXplZCBhcyB0aGUgbWludXMgc2lnbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBsb25nIHZhbHVlLgorICAgICAqIEBwYXJhbSByYWRpeAorICAgICAqICAgICAgICAgICAgdGhlIHJhZGl4IHRvIHVzZSB3aGVuIHBhcnNpbmcuCisgICAgICogQHJldHVybiB0aGUgcHJpbWl0aXZlIGxvbmcgdmFsdWUgcmVwcmVzZW50ZWQgYnkge0Bjb2RlIHN0cmluZ30gdXNpbmcKKyAgICAgKiAgICAgICAgIHtAY29kZSByYWRpeH0uCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyaW5nfSBjYW5ub3QgYmUgcGFyc2VkIGFzIGEgbG9uZyB2YWx1ZSwgb3IKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgcmFkaXggPCBDaGFyYWN0ZXIuTUlOX1JBRElYIHx8CisgICAgICogICAgICAgICAgICAgcmFkaXggPiBDaGFyYWN0ZXIuTUFYX1JBRElYfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgcGFyc2VMb25nKFN0cmluZyBzdHJpbmcsIGludCByYWRpeCkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChyYWRpeCA8IENoYXJhY3Rlci5NSU5fUkFESVggfHwgcmFkaXggPiBDaGFyYWN0ZXIuTUFYX1JBRElYKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkIHJhZGl4OiAiICsgcmFkaXgpOworICAgICAgICB9CisgICAgICAgIGlmIChzdHJpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgaW52YWxpZExvbmcoc3RyaW5nKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aCgpLCBpID0gMDsKKyAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBpbnZhbGlkTG9uZyhzdHJpbmcpOworICAgICAgICB9CisgICAgICAgIGJvb2xlYW4gbmVnYXRpdmUgPSBzdHJpbmcuY2hhckF0KGkpID09ICctJzsKKyAgICAgICAgaWYgKG5lZ2F0aXZlICYmICsraSA9PSBsZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IGludmFsaWRMb25nKHN0cmluZyk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcGFyc2Uoc3RyaW5nLCBpLCByYWRpeCwgbmVnYXRpdmUpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGxvbmcgcGFyc2UoU3RyaW5nIHN0cmluZywgaW50IG9mZnNldCwgaW50IHJhZGl4LCBib29sZWFuIG5lZ2F0aXZlKSB7CisgICAgICAgIGxvbmcgbWF4ID0gTG9uZy5NSU5fVkFMVUUgLyByYWRpeDsKKyAgICAgICAgbG9uZyByZXN1bHQgPSAwLCBsZW5ndGggPSBzdHJpbmcubGVuZ3RoKCk7CisgICAgICAgIHdoaWxlIChvZmZzZXQgPCBsZW5ndGgpIHsKKyAgICAgICAgICAgIGludCBkaWdpdCA9IENoYXJhY3Rlci5kaWdpdChzdHJpbmcuY2hhckF0KG9mZnNldCsrKSwgcmFkaXgpOworICAgICAgICAgICAgaWYgKGRpZ2l0ID09IC0xKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgaW52YWxpZExvbmcoc3RyaW5nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChtYXggPiByZXN1bHQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBpbnZhbGlkTG9uZyhzdHJpbmcpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbG9uZyBuZXh0ID0gcmVzdWx0ICogcmFkaXggLSBkaWdpdDsKKyAgICAgICAgICAgIGlmIChuZXh0ID4gcmVzdWx0KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgaW52YWxpZExvbmcoc3RyaW5nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdCA9IG5leHQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFuZWdhdGl2ZSkgeworICAgICAgICAgICAgcmVzdWx0ID0gLXJlc3VsdDsKKyAgICAgICAgICAgIGlmIChyZXN1bHQgPCAwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgaW52YWxpZExvbmcoc3RyaW5nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzaG9ydCBzaG9ydFZhbHVlKCkgeworICAgICAgICByZXR1cm4gKHNob3J0KSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIGxvbmcgdmFsdWUgaW50byBpdHMgYmluYXJ5IHN0cmluZyByZXByZXNlbnRhdGlvbi4KKyAgICAgKiBUaGUgcmV0dXJuZWQgc3RyaW5nIGlzIGEgY29uY2F0ZW5hdGlvbiBvZiAnMCcgYW5kICcxJyBjaGFyYWN0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIHYKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb25nIHZhbHVlIHRvIGNvbnZlcnQuCisgICAgICogQHJldHVybiB0aGUgYmluYXJ5IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUgdn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9CaW5hcnlTdHJpbmcobG9uZyB2KSB7CisgICAgICAgIHJldHVybiBJbnRlZ3JhbFRvU3RyaW5nLmxvbmdUb0JpbmFyeVN0cmluZyh2KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIGxvbmcgdmFsdWUgaW50byBpdHMgaGV4YWRlY2ltYWwgc3RyaW5nCisgICAgICogcmVwcmVzZW50YXRpb24uIFRoZSByZXR1cm5lZCBzdHJpbmcgaXMgYSBjb25jYXRlbmF0aW9uIG9mIGNoYXJhY3RlcnMgZnJvbQorICAgICAqICcwJyB0byAnOScgYW5kICdhJyB0byAnZicuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdgorICAgICAqICAgICAgICAgICAgdGhlIGxvbmcgdmFsdWUgdG8gY29udmVydC4KKyAgICAgKiBAcmV0dXJuIHRoZSBoZXhhZGVjaW1hbCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvSGV4U3RyaW5nKGxvbmcgdikgeworICAgICAgICByZXR1cm4gSW50ZWdyYWxUb1N0cmluZy5sb25nVG9IZXhTdHJpbmcodik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhlIHNwZWNpZmllZCBsb25nIHZhbHVlIGludG8gaXRzIG9jdGFsIHN0cmluZyByZXByZXNlbnRhdGlvbi4KKyAgICAgKiBUaGUgcmV0dXJuZWQgc3RyaW5nIGlzIGEgY29uY2F0ZW5hdGlvbiBvZiBjaGFyYWN0ZXJzIGZyb20gJzAnIHRvICc3Jy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2CisgICAgICogICAgICAgICAgICB0aGUgbG9uZyB2YWx1ZSB0byBjb252ZXJ0LgorICAgICAqIEByZXR1cm4gdGhlIG9jdGFsIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUgbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9PY3RhbFN0cmluZyhsb25nIHYpIHsKKyAgICAgICAgcmV0dXJuIEludGVncmFsVG9TdHJpbmcubG9uZ1RvT2N0YWxTdHJpbmcodik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIExvbmcudG9TdHJpbmcodmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIHRoZSBzcGVjaWZpZWQgbG9uZyB2YWx1ZSBpbnRvIGl0cyBkZWNpbWFsIHN0cmluZyByZXByZXNlbnRhdGlvbi4KKyAgICAgKiBUaGUgcmV0dXJuZWQgc3RyaW5nIGlzIGEgY29uY2F0ZW5hdGlvbiBvZiBhIG1pbnVzIHNpZ24gaWYgdGhlIG51bWJlciBpcworICAgICAqIG5lZ2F0aXZlIGFuZCBjaGFyYWN0ZXJzIGZyb20gJzAnIHRvICc5Jy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuCisgICAgICogICAgICAgICAgICB0aGUgbG9uZyB0byBjb252ZXJ0LgorICAgICAqIEByZXR1cm4gdGhlIGRlY2ltYWwgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHtAY29kZSBsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b1N0cmluZyhsb25nIG4pIHsKKyAgICAgICAgcmV0dXJuIEludGVncmFsVG9TdHJpbmcubG9uZ1RvU3RyaW5nKG4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIHRoZSBzcGVjaWZpZWQgc2lnbmVkIGxvbmcgdmFsdWUgaW50byBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBiYXNlZCBvbgorICAgICAqIHRoZSBzcGVjaWZpZWQgcmFkaXguIFRoZSByZXR1cm5lZCBzdHJpbmcgaXMgYSBjb25jYXRlbmF0aW9uIG9mIGEgbWludXMKKyAgICAgKiBzaWduIGlmIHRoZSBudW1iZXIgaXMgbmVnYXRpdmUgYW5kIGNoYXJhY3RlcnMgZnJvbSAnMCcgdG8gJzknIGFuZCAnYScgdG8KKyAgICAgKiAneicsIGRlcGVuZGluZyBvbiB0aGUgcmFkaXguIElmIHtAY29kZSByYWRpeH0gaXMgbm90IGluIHRoZSBpbnRlcnZhbAorICAgICAqIGRlZmluZWQgYnkge0Bjb2RlIENoYXJhY3Rlci5NSU5fUkFESVh9IGFuZCB7QGNvZGUgQ2hhcmFjdGVyLk1BWF9SQURJWH0KKyAgICAgKiB0aGVuIDEwIGlzIHVzZWQgYXMgdGhlIGJhc2UgZm9yIHRoZSBjb252ZXJzaW9uLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgdHJlYXRzIGl0cyBhcmd1bWVudCBhcyBzaWduZWQuIElmIHlvdSB3YW50IHRvIGNvbnZlcnQgYW4KKyAgICAgKiB1bnNpZ25lZCB2YWx1ZSB0byBvbmUgb2YgdGhlIGNvbW1vbiBub24tZGVjaW1hbCBiYXNlcywgeW91IG1heSBmaW5kCisgICAgICoge0BsaW5rICN0b0JpbmFyeVN0cmluZ30sIHtAY29kZSAjdG9IZXhTdHJpbmd9LCBvciB7QGxpbmsgI3RvT2N0YWxTdHJpbmd9CisgICAgICogbW9yZSBjb252ZW5pZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHYKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaWduZWQgbG9uZyB0byBjb252ZXJ0LgorICAgICAqIEBwYXJhbSByYWRpeAorICAgICAqICAgICAgICAgICAgdGhlIGJhc2UgdG8gdXNlIGZvciB0aGUgY29udmVyc2lvbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIHZ9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKGxvbmcgdiwgaW50IHJhZGl4KSB7CisgICAgICAgIHJldHVybiBJbnRlZ3JhbFRvU3RyaW5nLmxvbmdUb1N0cmluZyh2LCByYWRpeCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGFzIGEgc2lnbmVkIGRlY2ltYWwgbG9uZyB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBsb25nIHZhbHVlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgTG9uZ30gaW5zdGFuY2UgY29udGFpbmluZyB0aGUgbG9uZyB2YWx1ZSByZXByZXNlbnRlZCBieQorICAgICAqICAgICAgICAge0Bjb2RlIHN0cmluZ30uCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyaW5nfSBjYW5ub3QgYmUgcGFyc2VkIGFzIGEgbG9uZyB2YWx1ZS4KKyAgICAgKiBAc2VlICNwYXJzZUxvbmcoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTG9uZyB2YWx1ZU9mKFN0cmluZyBzdHJpbmcpIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gdmFsdWVPZihwYXJzZUxvbmcoc3RyaW5nKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGFzIGEgc2lnbmVkIGxvbmcgdmFsdWUgdXNpbmcgdGhlIHNwZWNpZmllZAorICAgICAqIHJhZGl4LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIGxvbmcgdmFsdWUuCisgICAgICogQHBhcmFtIHJhZGl4CisgICAgICogICAgICAgICAgICB0aGUgcmFkaXggdG8gdXNlIHdoZW4gcGFyc2luZy4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIExvbmd9IGluc3RhbmNlIGNvbnRhaW5pbmcgdGhlIGxvbmcgdmFsdWUgcmVwcmVzZW50ZWQgYnkKKyAgICAgKiAgICAgICAgIHtAY29kZSBzdHJpbmd9IHVzaW5nIHtAY29kZSByYWRpeH0uCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyaW5nfSBjYW5ub3QgYmUgcGFyc2VkIGFzIGEgbG9uZyB2YWx1ZSwgb3IKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgcmFkaXggPCBDaGFyYWN0ZXIuTUlOX1JBRElYIHx8CisgICAgICogICAgICAgICAgICAgcmFkaXggPiBDaGFyYWN0ZXIuTUFYX1JBRElYfS4KKyAgICAgKiBAc2VlICNwYXJzZUxvbmcoU3RyaW5nLCBpbnQpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBMb25nIHZhbHVlT2YoU3RyaW5nIHN0cmluZywgaW50IHJhZGl4KSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlT2YocGFyc2VMb25nKHN0cmluZywgcmFkaXgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHRoZSBoaWdoZXN0IChsZWZ0bW9zdCkgYml0IG9mIHRoZSBzcGVjaWZpZWQgbG9uZyB2YWx1ZSB0aGF0IGlzCisgICAgICogMSBhbmQgcmV0dXJucyB0aGUgYml0IG1hc2sgdmFsdWUgZm9yIHRoYXQgYml0LiBUaGlzIGlzIGFsc28gcmVmZXJyZWQgdG8KKyAgICAgKiBhcyB0aGUgTW9zdCBTaWduaWZpY2FudCAxIEJpdC4gUmV0dXJucyB6ZXJvIGlmIHRoZSBzcGVjaWZpZWQgbG9uZyBpcworICAgICAqIHplcm8uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdgorICAgICAqICAgICAgICAgICAgdGhlIGxvbmcgdG8gZXhhbWluZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBiaXQgbWFzayBpbmRpY2F0aW5nIHRoZSBoaWdoZXN0IDEgYml0IGluIHtAY29kZSB2fS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBsb25nIGhpZ2hlc3RPbmVCaXQobG9uZyB2KSB7CisgICAgICAgIC8vIEhhY2tlcidzIERlbGlnaHQsIEZpZ3VyZSAzLTEKKyAgICAgICAgdiB8PSAodiA+PiAxKTsKKyAgICAgICAgdiB8PSAodiA+PiAyKTsKKyAgICAgICAgdiB8PSAodiA+PiA0KTsKKyAgICAgICAgdiB8PSAodiA+PiA4KTsKKyAgICAgICAgdiB8PSAodiA+PiAxNik7CisgICAgICAgIHYgfD0gKHYgPj4gMzIpOworICAgICAgICByZXR1cm4gdiAtICh2ID4+PiAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHRoZSBsb3dlc3QgKHJpZ2h0bW9zdCkgYml0IG9mIHRoZSBzcGVjaWZpZWQgbG9uZyB2YWx1ZSB0aGF0IGlzCisgICAgICogMSBhbmQgcmV0dXJucyB0aGUgYml0IG1hc2sgdmFsdWUgZm9yIHRoYXQgYml0LiBUaGlzIGlzIGFsc28gcmVmZXJyZWQgdG8KKyAgICAgKiBhcyB0aGUgTGVhc3QgU2lnbmlmaWNhbnQgMSBCaXQuIFJldHVybnMgemVybyBpZiB0aGUgc3BlY2lmaWVkIGxvbmcgaXMKKyAgICAgKiB6ZXJvLgorICAgICAqCisgICAgICogQHBhcmFtIHYKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb25nIHRvIGV4YW1pbmUuCisgICAgICogQHJldHVybiB0aGUgYml0IG1hc2sgaW5kaWNhdGluZyB0aGUgbG93ZXN0IDEgYml0IGluIHtAY29kZSB2fS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBsb25nIGxvd2VzdE9uZUJpdChsb25nIHYpIHsKKyAgICAgICAgcmV0dXJuIHYgJiAtdjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHRoZSBudW1iZXIgb2YgbGVhZGluZyB6ZXJvcyBpbiB0aGUgc3BlY2lmaWVkIGxvbmcgdmFsdWUgcHJpb3IKKyAgICAgKiB0byB0aGUge0BsaW5rICNoaWdoZXN0T25lQml0KGxvbmcpIGhpZ2hlc3Qgb25lIGJpdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdgorICAgICAqICAgICAgICAgICAgdGhlIGxvbmcgdG8gZXhhbWluZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgbGVhZGluZyB6ZXJvcyBpbiB7QGNvZGUgdn0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IG51bWJlck9mTGVhZGluZ1plcm9zKGxvbmcgdikgeworICAgICAgICAvLyBBZnRlciBIYWNrZXIncyBEZWxpZ2h0LCBGaWd1cmUgNS02CisgICAgICAgIGlmICh2IDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHYgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDY0OworICAgICAgICB9CisgICAgICAgIC8vIE9uIGEgNjQtYml0IFZNLCB0aGUgdHdvIHByZXZpb3VzIHRlc3RzIHNob3VsZCBwcm9iYWJseSBiZSByZXBsYWNlZCBieQorICAgICAgICAvLyBpZiAodiA8PSAwKSByZXR1cm4gKChpbnQpICh+diA+PiA1NykpICYgNjQ7CisKKyAgICAgICAgaW50IG4gPSAxOworICAgICAgICBpbnQgaSA9IChpbnQpICh2ID4+PiAzMik7CisgICAgICAgIGlmIChpID09IDApIHsKKyAgICAgICAgICAgIG4gKz0gIDMyOworICAgICAgICAgICAgaSA9IChpbnQpIHY7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGkgPj4+IDE2ID09IDApIHsKKyAgICAgICAgICAgIG4gKz0gIDE2OworICAgICAgICAgICAgaSA8PD0gMTY7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGkgPj4+IDI0ID09IDApIHsKKyAgICAgICAgICAgIG4gKz0gIDg7CisgICAgICAgICAgICBpIDw8PSA4OworICAgICAgICB9CisgICAgICAgIGlmIChpID4+PiAyOCA9PSAwKSB7CisgICAgICAgICAgICBuICs9ICA0OworICAgICAgICAgICAgaSA8PD0gNDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaSA+Pj4gMzAgPT0gMCkgeworICAgICAgICAgICAgbiArPSAgMjsKKyAgICAgICAgICAgIGkgPDw9IDI7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG4gLSAoaSA+Pj4gMzEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgdGhlIG51bWJlciBvZiB0cmFpbGluZyB6ZXJvcyBpbiB0aGUgc3BlY2lmaWVkIGxvbmcgdmFsdWUgYWZ0ZXIKKyAgICAgKiB0aGUge0BsaW5rICNsb3dlc3RPbmVCaXQobG9uZykgbG93ZXN0IG9uZSBiaXR9LgorICAgICAqCisgICAgICogQHBhcmFtIHYKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb25nIHRvIGV4YW1pbmUuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHRyYWlsaW5nIHplcm9zIGluIHtAY29kZSB2fS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgbnVtYmVyT2ZUcmFpbGluZ1plcm9zKGxvbmcgdikgeworICAgICAgICBpbnQgbG93ID0gKGludCkgdjsKKyAgICAgICAgcmV0dXJuIGxvdyAhPTAgPyBJbnRlZ2VyLm51bWJlck9mVHJhaWxpbmdaZXJvcyhsb3cpCisgICAgICAgICAgICAgICAgICAgICAgIDogMzIgKyBJbnRlZ2VyLm51bWJlck9mVHJhaWxpbmdaZXJvcygoaW50KSAodiA+Pj4gMzIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3VudHMgdGhlIG51bWJlciBvZiAxIGJpdHMgaW4gdGhlIHNwZWNpZmllZCBsb25nIHZhbHVlOyB0aGlzIGlzIGFsc28KKyAgICAgKiByZWZlcnJlZCB0byBhcyBwb3B1bGF0aW9uIGNvdW50LgorICAgICAqCisgICAgICogQHBhcmFtIHYKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb25nIHRvIGV4YW1pbmUuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIDEgYml0cyBpbiB7QGNvZGUgdn0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGJpdENvdW50KGxvbmcgdikgeworICAgICAgICAvLyBDb21iaW5lcyB0ZWNobmlxdWVzIGZyb20gc2V2ZXJhbCBzb3VyY2VzCisgICAgICAgIHYgLT0gICh2ID4+PiAxKSAmIDB4NTU1NTU1NTU1NTU1NTU1NUw7CisgICAgICAgIHYgPSAodiAmIDB4MzMzMzMzMzMzMzMzMzMzM0wpICsgKCh2ID4+PiAyKSAmIDB4MzMzMzMzMzMzMzMzMzMzM0wpOworICAgICAgICBpbnQgaSA9ICAoKGludCkodiA+Pj4gMzIpKSArIChpbnQpIHY7CisgICAgICAgIGkgPSAoaSAmIDB4MEYwRjBGMEYpICsgKChpID4+PiA0KSAmIDB4MEYwRjBGMEYpOworICAgICAgICBpICs9IGkgPj4+IDg7CisgICAgICAgIGkgKz0gaSA+Pj4gMTY7CisgICAgICAgIHJldHVybiBpICAmIDB4MDAwMDAwN0Y7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBPbiBhIG1vZGVybiA2NC1iaXQgcHJvY2Vzc29yIHdpdGggYSBmYXN0IGhhcmR3YXJlIG11bHRpcGx5LCB0aGlzIGlzCisgICAgICogbXVjaCBmYXN0ZXIgKGFzc3VtaW5nIHlvdSdyZSBydW5uaW5nIGEgNjQtYml0IFZNKToKKyAgICAgKgorICAgICAqIC8vIGh0dHA6Ly9jaGVzc3Byb2dyYW1taW5nLndpa2lzcGFjZXMuY29tL1BvcHVsYXRpb24rQ291bnQKKyAgICAgKiBpbnQgYml0Q291bnQgKGxvbmcgeCkgeworICAgICAqICAgICB4IC09ICAoeCA+Pj4gMSkgJiAweDU1NTU1NTU1NTU1NTU1NTVMOworICAgICAqICAgICB4ID0gKHggJiAweDMzMzMzMzMzMzMzMzMzMzNMKSArICgoeCA+Pj4gMikgJiAweDMzMzMzMzMzMzMzMzMzMzNMKTsKKyAgICAgKiAgICAgeCA9ICh4ICsgKHggPj4+IDQpKSAmIDB4MGYwZjBmMGYwZjBmMGYwZkw7CisgICAgICogICAgIHggPSAoeCAqIDB4MDEwMTAxMDEwMTAxMDEwMUwpID4+PiA1NjsKKyAgICAgKiAgICAgcmV0dXJuIChpbnQpIHg7CisgICAgICogfQorICAgICAqCisgICAgICogUmVhbGx5IG1vZGVybiBwcm9jZXNzb3JzIChlLmcuLCBOZWhhbGVtLCBLLTEwKSBoYXZlIGhhcmR3YXJlIHBvcGNvdW50CisgICAgICogaW5zdHJ1Y3Rpb25zLgorICAgICAqLworCisgICAgLyoqCisgICAgICogUm90YXRlcyB0aGUgYml0cyBvZiB0aGUgc3BlY2lmaWVkIGxvbmcgdmFsdWUgdG8gdGhlIGxlZnQgYnkgdGhlIHNwZWNpZmllZAorICAgICAqIG51bWJlciBvZiBiaXRzLgorICAgICAqCisgICAgICogQHBhcmFtIHYKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb25nIHZhbHVlIHRvIHJvdGF0ZSBsZWZ0LgorICAgICAqIEBwYXJhbSBkaXN0YW5jZQorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBiaXRzIHRvIHJvdGF0ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSByb3RhdGVkIHZhbHVlLgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgcm90YXRlTGVmdChsb25nIHYsIGludCBkaXN0YW5jZSkgeworICAgICAgICAvLyBTaGlmdCBkaXN0YW5jZXMgYXJlIG1vZCA2NCAoSkxTMyAxNS4xOSksIHNvIHdlIG5lZWRuJ3QgbWFzayAtZGlzdGFuY2UKKyAgICAgICAgcmV0dXJuICh2IDw8IGRpc3RhbmNlKSB8ICh2ID4+PiAtZGlzdGFuY2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJvdGF0ZXMgdGhlIGJpdHMgb2YgdGhlIHNwZWNpZmllZCBsb25nIHZhbHVlIHRvIHRoZSByaWdodCBieSB0aGUKKyAgICAgKiBzcGVjaWZpZWQgbnVtYmVyIG9mIGJpdHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdgorICAgICAqICAgICAgICAgICAgdGhlIGxvbmcgdmFsdWUgdG8gcm90YXRlIHJpZ2h0LgorICAgICAqIEBwYXJhbSBkaXN0YW5jZQorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBiaXRzIHRvIHJvdGF0ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSByb3RhdGVkIHZhbHVlLgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgcm90YXRlUmlnaHQobG9uZyB2LCBpbnQgZGlzdGFuY2UpIHsKKyAgICAgICAgLy8gU2hpZnQgZGlzdGFuY2VzIGFyZSBtb2QgNjQgKEpMUzMgMTUuMTkpLCBzbyB3ZSBuZWVkbid0IG1hc2sgLWRpc3RhbmNlCisgICAgICAgIHJldHVybiAodiA+Pj4gZGlzdGFuY2UpIHwgKHYgPDwgLWRpc3RhbmNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXZlcnNlcyB0aGUgb3JkZXIgb2YgdGhlIGJ5dGVzIG9mIHRoZSBzcGVjaWZpZWQgbG9uZyB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2CisgICAgICogICAgICAgICAgICB0aGUgbG9uZyB2YWx1ZSBmb3Igd2hpY2ggdG8gcmV2ZXJzZSB0aGUgYnl0ZSBvcmRlci4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXZlcnNlZCB2YWx1ZS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBsb25nIHJldmVyc2VCeXRlcyhsb25nIHYpIHsKKyAgICAgICAgLy8gSGFja2VyJ3MgRGVsaWdodCA3LTEsIHdpdGggbWlub3IgdHdlYWsgZnJvbSBWZWxkbWVpamVyCisgICAgICAgIC8vIGh0dHA6Ly9ncmFwaGljcy5zdGFuZm9yZC5lZHUvfnNlYW5kZXIvYml0aGFja3MuaHRtbAorICAgICAgICB2ID0gKCh2ID4+PiA4KSAmIDB4MDBGRjAwRkYwMEZGMDBGRkwpIHwgKCh2ICYgMHgwMEZGMDBGRjAwRkYwMEZGTCkgPDwgOCk7CisgICAgICAgIHYgPSAoKHYgPj4+MTYpICYgMHgwMDAwRkZGRjAwMDBGRkZGTCkgfCAoKHYgJiAweDAwMDBGRkZGMDAwMEZGRkZMKSA8PDE2KTsKKyAgICAgICAgcmV0dXJuICgodiA+Pj4zMikgICAgICAgICAgICAgICAgICAgKSB8ICgodiAgICAgICAgICAgICAgICAgICAgICApIDw8MzIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldmVyc2VzIHRoZSBvcmRlciBvZiB0aGUgYml0cyBvZiB0aGUgc3BlY2lmaWVkIGxvbmcgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdgorICAgICAqICAgICAgICAgICAgdGhlIGxvbmcgdmFsdWUgZm9yIHdoaWNoIHRvIHJldmVyc2UgdGhlIGJpdCBvcmRlci4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXZlcnNlZCB2YWx1ZS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBsb25nIHJldmVyc2UobG9uZyB2KSB7CisgICAgICAgIC8vIEhhY2tlcidzIERlbGlnaHQgNy0xLCB3aXRoIG1pbm9yIHR3ZWFrIGZyb20gVmVsZG1laWplcgorICAgICAgICAvLyBodHRwOi8vZ3JhcGhpY3Muc3RhbmZvcmQuZWR1L35zZWFuZGVyL2JpdGhhY2tzLmh0bWwKKyAgICAgICAgdiA9ICgodiA+Pj4gMSkgJiAweDU1NTU1NTU1NTU1NTU1NTVMKSB8ICgodiAmIDB4NTU1NTU1NTU1NTU1NTU1NUwpIDw8IDEpOworICAgICAgICB2ID0gKCh2ID4+PiAyKSAmIDB4MzMzMzMzMzMzMzMzMzMzM0wpIHwgKCh2ICYgMHgzMzMzMzMzMzMzMzMzMzMzTCkgPDwgMik7CisgICAgICAgIHYgPSAoKHYgPj4+IDQpICYgMHgwRjBGMEYwRjBGMEYwRjBGTCkgfCAoKHYgJiAweDBGMEYwRjBGMEYwRjBGMEZMKSA8PCA0KTsKKyAgICAgICAgdiA9ICgodiA+Pj4gOCkgJiAweDAwRkYwMEZGMDBGRjAwRkZMKSB8ICgodiAmIDB4MDBGRjAwRkYwMEZGMDBGRkwpIDw8IDgpOworICAgICAgICB2ID0gKCh2ID4+PjE2KSAmIDB4MDAwMEZGRkYwMDAwRkZGRkwpIHwgKCh2ICYgMHgwMDAwRkZGRjAwMDBGRkZGTCkgPDwxNik7CisgICAgICAgIHJldHVybiAoKHYgPj4+MzIpICAgICAgICAgICAgICAgICAgICkgfCAoKHYgICAgICAgICAgICAgICAgICAgICAgKSA8PDMyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUge0Bjb2RlIHNpZ251bX0gZnVuY3Rpb24gZm9yIHRoZSBzcGVjaWZpZWQgbG9uZworICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHYKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb25nIHZhbHVlIHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4gLTEgaWYge0Bjb2RlIHZ9IGlzIG5lZ2F0aXZlLCAxIGlmIHtAY29kZSB2fSBpcyBwb3NpdGl2ZSwgMCBpZgorICAgICAqICAgICAgICAge0Bjb2RlIHZ9IGlzIHplcm8uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHNpZ251bShsb25nIHYpIHsKKyAgICAgICAgcmV0dXJuIHYgPCAwID8gLTEgOiAodiA9PSAwID8gMCA6IDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgTG9uZ30gaW5zdGFuY2UgZm9yIHRoZSBzcGVjaWZpZWQgbG9uZyB2YWx1ZS4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiBpdCBpcyBub3QgbmVjZXNzYXJ5IHRvIGdldCBhIG5ldyB7QGNvZGUgTG9uZ30gaW5zdGFuY2UsIGl0IGlzCisgICAgICogcmVjb21tZW5kZWQgdG8gdXNlIHRoaXMgbWV0aG9kIGluc3RlYWQgb2YgdGhlIGNvbnN0cnVjdG9yLCBzaW5jZSBpdAorICAgICAqIG1haW50YWlucyBhIGNhY2hlIG9mIGluc3RhbmNlcyB3aGljaCBtYXkgcmVzdWx0IGluIGJldHRlciBwZXJmb3JtYW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2CisgICAgICogICAgICAgICAgICB0aGUgbG9uZyB2YWx1ZSB0byBzdG9yZSBpbiB0aGUgaW5zdGFuY2UuCisgICAgICogQHJldHVybiBhIHtAY29kZSBMb25nfSBpbnN0YW5jZSBjb250YWluaW5nIHtAY29kZSB2fS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBMb25nIHZhbHVlT2YobG9uZyB2KSB7CisgICAgICAgIHJldHVybiAgdiA+PSAxMjggfHwgdiA8IC0xMjggPyBuZXcgTG9uZyh2KSA6IFNNQUxMX1ZBTFVFU1soKGludCkgdikgKyAxMjhdOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgY2FjaGUgb2YgaW5zdGFuY2VzIHVzZWQgYnkge0BsaW5rIExvbmcjdmFsdWVPZihsb25nKX0gYW5kIGF1dG8tYm94aW5nLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvbmdbXSBTTUFMTF9WQUxVRVMgPSBuZXcgTG9uZ1syNTZdOworCisgICAgc3RhdGljIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IC0xMjg7IGkgPCAxMjg7IGkrKykgeworICAgICAgICAgICAgU01BTExfVkFMVUVTW2kgKyAxMjhdID0gbmV3IExvbmcoaSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL01hdGguamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvTWF0aC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY4ZGI0ZmEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL01hdGguamF2YQpAQCAtMCwwICsxLDEzNjkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKKworLyoqCisgKiBDbGFzcyBNYXRoIHByb3ZpZGVzIGJhc2ljIG1hdGggY29uc3RhbnRzIGFuZCBvcGVyYXRpb25zIHN1Y2ggYXMgdHJpZ29ub21ldHJpYworICogZnVuY3Rpb25zLCBoeXBlcmJvbGljIGZ1bmN0aW9ucywgZXhwb25lbnRpYWwsIGxvZ2FyaXRobXMsIGV0Yy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE1hdGggeworICAgIC8qKgorICAgICAqIFRoZSBkb3VibGUgdmFsdWUgY2xvc2VzdCB0byBlLCB0aGUgYmFzZSBvZiB0aGUgbmF0dXJhbCBsb2dhcml0aG0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBkb3VibGUgRSA9IDIuNzE4MjgxODI4NDU5MDQ1OworCisgICAgLyoqCisgICAgICogVGhlIGRvdWJsZSB2YWx1ZSBjbG9zZXN0IHRvIHBpLCB0aGUgcmF0aW8gb2YgYSBjaXJjbGUncyBjaXJjdW1mZXJlbmNlIHRvCisgICAgICogaXRzIGRpYW1ldGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgZG91YmxlIFBJID0gMy4xNDE1OTI2NTM1ODk3OTM7CisKKyAgICBwcml2YXRlIHN0YXRpYyBSYW5kb20gcmFuZG9tOworCisgICAgLyoqCisgICAgICogUHJldmVudHMgdGhpcyBjbGFzcyBmcm9tIGJlaW5nIGluc3RhbnRpYXRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIE1hdGgoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIGFyZ3VtZW50LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgYWJzKC0wLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYWJzKCtpbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGFicygtaW5maW5pdHkpID0gK2luZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBhYnMoTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHdob3NlIGFic29sdXRlIHZhbHVlIGhhcyB0byBiZSBjb21wdXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIGFicyhkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGUgYXJndW1lbnQuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBhYnMoLTAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBhYnMoK2luZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYWJzKC1pbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGFicyhOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgd2hvc2UgYWJzb2x1dGUgdmFsdWUgaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGFyZ3VtZW50IGlmIGl0IGlzIHBvc2l0aXZlLCBvdGhlcndpc2UgdGhlIG5lZ2F0aW9uIG9mIHRoZQorICAgICAqICAgICAgICAgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZmxvYXQgYWJzKGZsb2F0IGYpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIGFyZ3VtZW50LgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBhcmd1bWVudCBpcyB7QGNvZGUgSW50ZWdlci5NSU5fVkFMVUV9LCB7QGNvZGUgSW50ZWdlci5NSU5fVkFMVUV9CisgICAgICogaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHdob3NlIGFic29sdXRlIHZhbHVlIGhhcyB0byBiZSBjb21wdXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcmd1bWVudCBpZiBpdCBpcyBwb3NpdGl2ZSwgb3RoZXJ3aXNlIHRoZSBuZWdhdGlvbiBvZiB0aGUKKyAgICAgKiAgICAgICAgIGFyZ3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBhYnMoaW50IGkpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIGFyZ3VtZW50LiBJZiB0aGUgYXJndW1lbnQgaXMge0Bjb2RlCisgICAgICogTG9uZy5NSU5fVkFMVUV9LCB7QGNvZGUgTG9uZy5NSU5fVkFMVUV9IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB3aG9zZSBhYnNvbHV0ZSB2YWx1ZSBoYXMgdG8gYmUgY29tcHV0ZWQuCisgICAgICogQHJldHVybiB0aGUgYXJndW1lbnQgaWYgaXQgaXMgcG9zaXRpdmUsIG90aGVyd2lzZSB0aGUgbmVnYXRpb24gb2YgdGhlCisgICAgICogICAgICAgICBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBsb25nIGFicyhsb25nIGwpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2xvc2VzdCBkb3VibGUgYXBwcm94aW1hdGlvbiBvZiB0aGUgYXJjIGNvc2luZSBvZiB0aGUKKyAgICAgKiBhcmd1bWVudCB3aXRoaW4gdGhlIHJhbmdlIHtAY29kZSBbMC4ucGldfS4gVGhlIHJldHVybmVkIHJlc3VsdCBpcyB3aXRoaW4KKyAgICAgKiAxIHVscCAodW5pdCBpbiB0aGUgbGFzdCBwbGFjZSkgb2YgdGhlIHJlYWwgcmVzdWx0LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgYWNvcygoYW55dGhpbmcgPiAxKSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYWNvcygoYW55dGhpbmcgPCAtMSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGFjb3MoTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIGNvbXB1dGUgYXJjIGNvc2luZSBvZi4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcmMgY29zaW5lIG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgYWNvcyhkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSBhcmMgc2luZSBvZiB0aGUgYXJndW1lbnQKKyAgICAgKiB3aXRoaW4gdGhlIHJhbmdlIHtAY29kZSBbLXBpLzIuLnBpLzJdfS4gVGhlIHJldHVybmVkIHJlc3VsdCBpcyB3aXRoaW4gMQorICAgICAqIHVscCAodW5pdCBpbiB0aGUgbGFzdCBwbGFjZSkgb2YgdGhlIHJlYWwgcmVzdWx0LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgYXNpbigoYW55dGhpbmcgPiAxKSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGFzaW4oKGFueXRoaW5nIDwgLTEpKSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXNpbihOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgd2hvc2UgYXJjIHNpbmUgaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGFyYyBzaW5lIG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgYXNpbihkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSBhcmMgdGFuZ2VudCBvZiB0aGUKKyAgICAgKiBhcmd1bWVudCB3aXRoaW4gdGhlIHJhbmdlIHtAY29kZSBbLXBpLzIuLnBpLzJdfS4gVGhlIHJldHVybmVkIHJlc3VsdCBpcworICAgICAqIHdpdGhpbiAxIHVscCAodW5pdCBpbiB0aGUgbGFzdCBwbGFjZSkgb2YgdGhlIHJlYWwgcmVzdWx0LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgYXRhbigrMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGF0YW4oLTAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBhdGFuKCtpbmZpbml0eSkgPSArcGkvMn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXRhbigtaW5maW5pdHkpID0gLXBpLzJ9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGF0YW4oTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHdob3NlIGFyYyB0YW5nZW50IGhhcyB0byBiZSBjb21wdXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcmMgdGFuZ2VudCBvZiB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIGF0YW4oZG91YmxlIGQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2xvc2VzdCBkb3VibGUgYXBwcm94aW1hdGlvbiBvZiB0aGUgYXJjIHRhbmdlbnQgb2Yge0Bjb2RlCisgICAgICogeS94fSB3aXRoaW4gdGhlIHJhbmdlIHtAY29kZSBbLXBpLi5waV19LiBUaGlzIGlzIHRoZSBhbmdsZSBvZiB0aGUgcG9sYXIKKyAgICAgKiByZXByZXNlbnRhdGlvbiBvZiB0aGUgcmVjdGFuZ3VsYXIgY29vcmRpbmF0ZXMgKHgseSkuIFRoZSByZXR1cm5lZCByZXN1bHQKKyAgICAgKiBpcyB3aXRoaW4gMiB1bHBzICh1bml0cyBpbiB0aGUgbGFzdCBwbGFjZSkgb2YgdGhlIHJlYWwgcmVzdWx0LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgYXRhbjIoKGFueXRoaW5nKSwgTmFOICkgPSBOYU47fTwvbGk+CisgICAgICogPGxpPntAY29kZSBhdGFuMihOYU4gLCAoYW55dGhpbmcpICkgPSBOYU47fTwvbGk+CisgICAgICogPGxpPntAY29kZSBhdGFuMigrMC4wLCArKGFueXRoaW5nIGJ1dCBOYU4pKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGF0YW4yKC0wLjAsICsoYW55dGhpbmcgYnV0IE5hTikpID0gLTAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXRhbjIoKzAuMCwgLShhbnl0aGluZyBidXQgTmFOKSkgPSArcGl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGF0YW4yKC0wLjAsIC0oYW55dGhpbmcgYnV0IE5hTikpID0gLXBpfTwvbGk+CisgICAgICogPGxpPntAY29kZSBhdGFuMigrKGFueXRoaW5nIGJ1dCAwIGFuZCBOYU4pLCAwKSA9ICtwaS8yfTwvbGk+CisgICAgICogPGxpPntAY29kZSBhdGFuMigtKGFueXRoaW5nIGJ1dCAwIGFuZCBOYU4pLCAwKSA9IC1waS8yfTwvbGk+CisgICAgICogPGxpPntAY29kZSBhdGFuMigrKGFueXRoaW5nIGJ1dCBpbmZpbml0eSBhbmQgTmFOKSwgK2luZmluaXR5KX0ge0Bjb2RlID19CisgICAgICoge0Bjb2RlICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGF0YW4yKC0oYW55dGhpbmcgYnV0IGluZmluaXR5IGFuZCBOYU4pLCAraW5maW5pdHkpfSB7QGNvZGUgPX0KKyAgICAgKiB7QGNvZGUgLTAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXRhbjIoKyhhbnl0aGluZyBidXQgaW5maW5pdHkgYW5kIE5hTiksIC1pbmZpbml0eSkgPSArcGl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGF0YW4yKC0oYW55dGhpbmcgYnV0IGluZmluaXR5IGFuZCBOYU4pLCAtaW5maW5pdHkpID0gLXBpfTwvbGk+CisgICAgICogPGxpPntAY29kZSBhdGFuMigraW5maW5pdHksICtpbmZpbml0eSApID0gK3BpLzR9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGF0YW4yKC1pbmZpbml0eSwgK2luZmluaXR5ICkgPSAtcGkvNH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXRhbjIoK2luZmluaXR5LCAtaW5maW5pdHkgKSA9ICszcGkvNH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXRhbjIoLWluZmluaXR5LCAtaW5maW5pdHkgKSA9IC0zcGkvNH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXRhbjIoK2luZmluaXR5LCAoYW55dGhpbmcgYnV0LDAsIE5hTiwgYW5kIGluZmluaXR5KSl9IHtAY29kZQorICAgICAqID19IHtAY29kZSArcGkvMn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXRhbjIoLWluZmluaXR5LCAoYW55dGhpbmcgYnV0LDAsIE5hTiwgYW5kIGluZmluaXR5KSl9IHtAY29kZQorICAgICAqID19IHtAY29kZSAtcGkvMn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIG51bWVyYXRvciBvZiB0aGUgdmFsdWUgd2hvc2UgYXRhbiBoYXMgdG8gYmUgY29tcHV0ZWQuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZW5vbWluYXRvciBvZiB0aGUgdmFsdWUgd2hvc2UgYXRhbiBoYXMgdG8gYmUgY29tcHV0ZWQuCisgICAgICogQHJldHVybiB0aGUgYXJjIHRhbmdlbnQgb2Yge0Bjb2RlIHkveH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIGF0YW4yKGRvdWJsZSB5LCBkb3VibGUgeCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSBjdWJlIHJvb3Qgb2YgdGhlCisgICAgICogYXJndW1lbnQuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBjYnJ0KCswLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgY2JydCgtMC4wKSA9IC0wLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGNicnQoK2luZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgY2JydCgtaW5maW5pdHkpID0gLWluZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBjYnJ0KE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB3aG9zZSBjdWJlIHJvb3QgaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGN1YmUgcm9vdCBvZiB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIGNicnQoZG91YmxlIGQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZG91YmxlIGNvbnZlcnNpb24gb2YgdGhlIG1vc3QgbmVnYXRpdmUgKGNsb3Nlc3QgdG8gbmVnYXRpdmUKKyAgICAgKiBpbmZpbml0eSkgaW50ZWdlciB2YWx1ZSB3aGljaCBpcyBncmVhdGVyIHRoYW4gdGhlIGFyZ3VtZW50LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgY2VpbCgrMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGNlaWwoLTAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBjZWlsKChhbnl0aGluZyBpbiByYW5nZSAoLTEsMCkpID0gLTAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgY2VpbCgraW5maW5pdHkpID0gK2luZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBjZWlsKC1pbmZpbml0eSkgPSAtaW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGNlaWwoTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHdob3NlIGNsb3Nlc3QgaW50ZWdlciB2YWx1ZSBoYXMgdG8gYmUgY29tcHV0ZWQuCisgICAgICogQHJldHVybiB0aGUgY2VpbGluZyBvZiB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIGNlaWwoZG91YmxlIGQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2xvc2VzdCBkb3VibGUgYXBwcm94aW1hdGlvbiBvZiB0aGUgY29zaW5lIG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKiBUaGUgcmV0dXJuZWQgcmVzdWx0IGlzIHdpdGhpbiAxIHVscCAodW5pdCBpbiB0aGUgbGFzdCBwbGFjZSkgb2YgdGhlIHJlYWwKKyAgICAgKiByZXN1bHQuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBjb3MoK2luZmluaXR5KSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgY29zKC1pbmZpbml0eSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGNvcyhOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgYW5nbGUgd2hvc2UgY29zaW5lIGhhcyB0byBiZSBjb21wdXRlZCwgaW4gcmFkaWFucy4KKyAgICAgKiBAcmV0dXJuIHRoZSBjb3NpbmUgb2YgdGhlIGFyZ3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGRvdWJsZSBjb3MoZG91YmxlIGQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2xvc2VzdCBkb3VibGUgYXBwcm94aW1hdGlvbiBvZiB0aGUgaHlwZXJib2xpYyBjb3NpbmUgb2YgdGhlCisgICAgICogYXJndW1lbnQuIFRoZSByZXR1cm5lZCByZXN1bHQgaXMgd2l0aGluIDIuNSB1bHBzICh1bml0cyBpbiB0aGUgbGFzdAorICAgICAqIHBsYWNlKSBvZiB0aGUgcmVhbCByZXN1bHQuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBjb3NoKCtpbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGNvc2goLWluZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgY29zaChOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgd2hvc2UgaHlwZXJib2xpYyBjb3NpbmUgaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGh5cGVyYm9saWMgY29zaW5lIG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgY29zaChkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSByYWlzaW5nICJlIiB0byB0aGUgcG93ZXIKKyAgICAgKiBvZiB0aGUgYXJndW1lbnQuIFRoZSByZXR1cm5lZCByZXN1bHQgaXMgd2l0aGluIDEgdWxwICh1bml0IGluIHRoZSBsYXN0CisgICAgICogcGxhY2UpIG9mIHRoZSByZWFsIHJlc3VsdC4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIGV4cCgraW5maW5pdHkpID0gK2luZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBleHAoLWluZmluaXR5KSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGV4cChOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgd2hvc2UgZXhwb25lbnRpYWwgaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGV4cG9uZW50aWFsIG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgZXhwKGRvdWJsZSBkKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNsb3Nlc3QgZG91YmxlIGFwcHJveGltYXRpb24gb2YgPGk+e0Bjb2RlIGV9PC9pPjxzdXA+IHtAY29kZQorICAgICAqIGR9PC9zdXA+e0Bjb2RlIC0gMX0uIElmIHRoZSBhcmd1bWVudCBpcyB2ZXJ5IGNsb3NlIHRvIDAsIGl0IGlzIG11Y2ggbW9yZQorICAgICAqIGFjY3VyYXRlIHRvIHVzZSB7QGNvZGUgZXhwbTEoZCkrMX0gdGhhbiB7QGNvZGUgZXhwKGQpfSAoZHVlIHRvCisgICAgICogY2FuY2VsbGF0aW9uIG9mIHNpZ25pZmljYW50IGRpZ2l0cykuIFRoZSByZXR1cm5lZCByZXN1bHQgaXMgd2l0aGluIDEgdWxwCisgICAgICogKHVuaXQgaW4gdGhlIGxhc3QgcGxhY2UpIG9mIHRoZSByZWFsIHJlc3VsdC4KKyAgICAgKiA8cD4KKyAgICAgKiBGb3IgYW55IGZpbml0ZSBpbnB1dCwgdGhlIHJlc3VsdCBpcyBub3QgbGVzcyB0aGFuIC0xLjAuIElmIHRoZSByZWFsCisgICAgICogcmVzdWx0IGlzIHdpdGhpbiAwLjUgdWxwIG9mIC0xLCAtMS4wIGlzIHJldHVybmVkLgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgZXhwbTEoKzAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBleHBtMSgtMC4wKSA9IC0wLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGV4cG0xKCtpbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGV4cG0xKC1pbmZpbml0eSkgPSAtMS4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBleHBtMShOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gY29tcHV0ZSB0aGUgPGk+e0Bjb2RlIGV9PC9pPjxzdXA+e0Bjb2RlIGR9IDwvc3VwPgorICAgICAqICAgICAgICAgICAge0Bjb2RlIC0gMX0gb2YuCisgICAgICogQHJldHVybiB0aGUgPGk+e0Bjb2RlIGV9PC9pPjxzdXA+e0Bjb2RlIGR9PC9zdXA+e0Bjb2RlIC0gMX0gdmFsdWUgb2YgdGhlCisgICAgICogICAgICAgICBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgZXhwbTEoZG91YmxlIGQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZG91YmxlIGNvbnZlcnNpb24gb2YgdGhlIG1vc3QgcG9zaXRpdmUgKGNsb3Nlc3QgdG8gcG9zaXRpdmUKKyAgICAgKiBpbmZpbml0eSkgaW50ZWdlciB2YWx1ZSB3aGljaCBpcyBsZXNzIHRoYW4gdGhlIGFyZ3VtZW50LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgZmxvb3IoKzAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBmbG9vcigtMC4wKSA9IC0wLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGZsb29yKCtpbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGZsb29yKC1pbmZpbml0eSkgPSAtaW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGZsb29yKE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB3aG9zZSBjbG9zZXN0IGludGVnZXIgdmFsdWUgaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGZsb29yIG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgZmxvb3IoZG91YmxlIGQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB7QGNvZGUgc3FydCh9PGk+e0Bjb2RlIHh9PC9pPjxzdXA+e0Bjb2RlIDJ9PC9zdXA+e0Bjb2RlICt9IDxpPgorICAgICAqIHtAY29kZSB5fTwvaT48c3VwPntAY29kZSAyfTwvc3VwPntAY29kZSApfS4gVGhlIGZpbmFsIHJlc3VsdCBpcyB3aXRob3V0CisgICAgICogbWVkaXVtIHVuZGVyZmxvdyBvciBvdmVyZmxvdy4gVGhlIHJldHVybmVkIHJlc3VsdCBpcyB3aXRoaW4gMSB1bHAgKHVuaXQKKyAgICAgKiBpbiB0aGUgbGFzdCBwbGFjZSkgb2YgdGhlIHJlYWwgcmVzdWx0LiBJZiBvbmUgcGFyYW1ldGVyIHJlbWFpbnMgY29uc3RhbnQsCisgICAgICogdGhlIHJlc3VsdCBzaG91bGQgYmUgc2VtaS1tb25vdG9uaWMuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBoeXBvdCgraW5maW5pdHksIChhbnl0aGluZyBpbmNsdWRpbmcgTmFOKSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGh5cG90KC1pbmZpbml0eSwgKGFueXRoaW5nIGluY2x1ZGluZyBOYU4pKSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgaHlwb3QoKGFueXRoaW5nIGluY2x1ZGluZyBOYU4pLCAraW5maW5pdHkpID0gK2luZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBoeXBvdCgoYW55dGhpbmcgaW5jbHVkaW5nIE5hTiksIC1pbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGh5cG90KE5hTiwgTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgYSBkb3VibGUgbnVtYmVyLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICBhIGRvdWJsZSBudW1iZXIuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIHNxcnQofTxpPntAY29kZSB4fTwvaT48c3VwPntAY29kZSAyfTwvc3VwPntAY29kZSArfQorICAgICAqICAgICAgICAgPGk+IHtAY29kZSB5fTwvaT48c3VwPntAY29kZSAyfTwvc3VwPntAY29kZSApfSB2YWx1ZSBvZiB0aGUKKyAgICAgKiAgICAgICAgIGFyZ3VtZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgaHlwb3QoZG91YmxlIHgsIGRvdWJsZSB5KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHJlbWFpbmRlciBvZiBkaXZpZGluZyB7QGNvZGUgeH0gYnkge0Bjb2RlIHl9IHVzaW5nIHRoZSBJRUVFCisgICAgICogNzU0IHJ1bGVzLiBUaGUgcmVzdWx0IGlzIHtAY29kZSB4LXJvdW5kKHgvcCkqcH0gd2hlcmUge0Bjb2RlIHJvdW5kKHgvcCl9CisgICAgICogaXMgdGhlIG5lYXJlc3QgaW50ZWdlciAocm91bmRlZCB0byBldmVuKSwgYnV0IHdpdGhvdXQgbnVtZXJpY2FsCisgICAgICogY2FuY2VsbGF0aW9uIHByb2JsZW1zLgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgSUVFRXJlbWFpbmRlcigoYW55dGhpbmcpLCAwKSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgSUVFRXJlbWFpbmRlcigraW5maW5pdHksIChhbnl0aGluZykpID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBJRUVFcmVtYWluZGVyKC1pbmZpbml0eSwgKGFueXRoaW5nKSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIElFRUVyZW1haW5kZXIoTmFOLCAoYW55dGhpbmcpKSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgSUVFRXJlbWFpbmRlcigoYW55dGhpbmcpLCBOYU4pID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBJRUVFcmVtYWluZGVyKHgsICtpbmZpbml0eSkgPSB4IH0gd2hlcmUgeCBpcyBhbnl0aGluZyBidXQKKyAgICAgKiArLy1pbmZpbml0eTwvbGk+CisgICAgICogPGxpPntAY29kZSBJRUVFcmVtYWluZGVyKHgsIC1pbmZpbml0eSkgPSB4IH0gd2hlcmUgeCBpcyBhbnl0aGluZyBidXQKKyAgICAgKiArLy1pbmZpbml0eTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbnVtZXJhdG9yIG9mIHRoZSBvcGVyYXRpb24uCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZW5vbWluYXRvciBvZiB0aGUgb3BlcmF0aW9uLgorICAgICAqIEByZXR1cm4gdGhlIElFRUU3NTQgZmxvYXRpbmcgcG9pbnQgcmVtaW5kZXIgb2Ygb2Yge0Bjb2RlIHgveX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIElFRUVyZW1haW5kZXIoZG91YmxlIHgsIGRvdWJsZSB5KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNsb3Nlc3QgZG91YmxlIGFwcHJveGltYXRpb24gb2YgdGhlIG5hdHVyYWwgbG9nYXJpdGhtIG9mIHRoZQorICAgICAqIGFyZ3VtZW50LiBUaGUgcmV0dXJuZWQgcmVzdWx0IGlzIHdpdGhpbiAxIHVscCAodW5pdCBpbiB0aGUgbGFzdCBwbGFjZSkgb2YKKyAgICAgKiB0aGUgcmVhbCByZXN1bHQuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBsb2coKzAuMCkgPSAtaW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGxvZygtMC4wKSA9IC1pbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbG9nKChhbnl0aGluZyA8IDApID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBsb2coK2luZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbG9nKC1pbmZpbml0eSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGxvZyhOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgd2hvc2UgbG9nIGhhcyB0byBiZSBjb21wdXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBuYXR1cmFsIGxvZ2FyaXRobSBvZiB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIGxvZyhkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSBiYXNlIDEwIGxvZ2FyaXRobSBvZiB0aGUKKyAgICAgKiBhcmd1bWVudC4gVGhlIHJldHVybmVkIHJlc3VsdCBpcyB3aXRoaW4gMSB1bHAgKHVuaXQgaW4gdGhlIGxhc3QgcGxhY2UpIG9mCisgICAgICogdGhlIHJlYWwgcmVzdWx0LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgbG9nMTAoKzAuMCkgPSAtaW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGxvZzEwKC0wLjApID0gLWluZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBsb2cxMCgoYW55dGhpbmcgPCAwKSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbG9nMTAoK2luZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbG9nMTAoLWluZmluaXR5KSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbG9nMTAoTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHdob3NlIGJhc2UgMTAgbG9nIGhhcyB0byBiZSBjb21wdXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBuYXR1cmFsIGxvZ2FyaXRobSBvZiB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIGxvZzEwKGRvdWJsZSBkKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNsb3Nlc3QgZG91YmxlIGFwcHJveGltYXRpb24gb2YgdGhlIG5hdHVyYWwgbG9nYXJpdGhtIG9mIHRoZQorICAgICAqIHN1bSBvZiB0aGUgYXJndW1lbnQgYW5kIDEuIElmIHRoZSBhcmd1bWVudCBpcyB2ZXJ5IGNsb3NlIHRvIDAsIGl0IGlzIG11Y2gKKyAgICAgKiBtb3JlIGFjY3VyYXRlIHRvIHVzZSB7QGNvZGUgbG9nMXAoZCl9IHRoYW4ge0Bjb2RlIGxvZygxLjArZCl9IChkdWUgdG8KKyAgICAgKiBudW1lcmljYWwgY2FuY2VsbGF0aW9uKS4gVGhlIHJldHVybmVkIHJlc3VsdCBpcyB3aXRoaW4gMSB1bHAgKHVuaXQgaW4gdGhlCisgICAgICogbGFzdCBwbGFjZSkgb2YgdGhlIHJlYWwgcmVzdWx0IGFuZCBpcyBzZW1pLW1vbm90b25pYy4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIGxvZzFwKCswLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbG9nMXAoLTAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBsb2cxcCgoYW55dGhpbmcgPCAxKSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGxvZzFwKC0xLjApID0gLWluZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBsb2cxcCgraW5maW5pdHkpID0gK2luZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBsb2cxcCgtaW5maW5pdHkpID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBsb2cxcChOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gY29tcHV0ZSB0aGUge0Bjb2RlIGxuKDErZCl9IG9mLgorICAgICAqIEByZXR1cm4gdGhlIG5hdHVyYWwgbG9nYXJpdGhtIG9mIHRoZSBzdW0gb2YgdGhlIGFyZ3VtZW50IGFuZCAxLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGRvdWJsZSBsb2cxcChkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtb3N0IHBvc2l0aXZlIChjbG9zZXN0IHRvIHBvc2l0aXZlIGluZmluaXR5KSBvZiB0aGUgdHdvCisgICAgICogYXJndW1lbnRzLgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgbWF4KE5hTiwgKGFueXRoaW5nKSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIG1heCgoYW55dGhpbmcpLCBOYU4pID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBtYXgoKzAuMCwgLTAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBtYXgoLTAuMCwgKzAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkMQorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IGFyZ3VtZW50LgorICAgICAqIEBwYXJhbSBkMgorICAgICAqICAgICAgICAgICAgdGhlIHNlY29uZCBhcmd1bWVudC4KKyAgICAgKiBAcmV0dXJuIHRoZSBsYXJnZXIgb2Yge0Bjb2RlIGQxfSBhbmQge0Bjb2RlIGQyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSBtYXgoZG91YmxlIGQxLCBkb3VibGUgZDIpIHsKKyAgICAgICAgaWYgKGQxID4gZDIpIHsKKyAgICAgICAgICAgIHJldHVybiBkMTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZDEgPCBkMikgeworICAgICAgICAgICAgcmV0dXJuIGQyOworICAgICAgICB9CisgICAgICAgIC8qIGlmIGVpdGhlciBhcmcgaXMgTmFOLCByZXR1cm4gTmFOICovCisgICAgICAgIGlmIChkMSAhPSBkMikgeworICAgICAgICAgICAgcmV0dXJuIERvdWJsZS5OYU47CisgICAgICAgIH0KKyAgICAgICAgLyogbWF4KCswLjAsLTAuMCkgPT0gKzAuMCAqLworICAgICAgICAvKiBEb3VibGUuZG91YmxlVG9SYXdMb25nQml0cygwLjBkKSA9PSAwICovCisgICAgICAgIGlmIChEb3VibGUuZG91YmxlVG9SYXdMb25nQml0cyhkMSkgIT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGQyOworICAgICAgICB9CisgICAgICAgIHJldHVybiAwLjBkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1vc3QgcG9zaXRpdmUgKGNsb3Nlc3QgdG8gcG9zaXRpdmUgaW5maW5pdHkpIG9mIHRoZSB0d28KKyAgICAgKiBhcmd1bWVudHMuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBtYXgoTmFOLCAoYW55dGhpbmcpKSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbWF4KChhbnl0aGluZyksIE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIG1heCgrMC4wLCAtMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIG1heCgtMC4wLCArMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGYxCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgYXJndW1lbnQuCisgICAgICogQHBhcmFtIGYyCisgICAgICogICAgICAgICAgICB0aGUgc2Vjb25kIGFyZ3VtZW50LgorICAgICAqIEByZXR1cm4gdGhlIGxhcmdlciBvZiB7QGNvZGUgZjF9IGFuZCB7QGNvZGUgZjJ9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmxvYXQgbWF4KGZsb2F0IGYxLCBmbG9hdCBmMikgeworICAgICAgICBpZiAoZjEgPiBmMikgeworICAgICAgICAgICAgcmV0dXJuIGYxOworICAgICAgICB9CisgICAgICAgIGlmIChmMSA8IGYyKSB7CisgICAgICAgICAgICByZXR1cm4gZjI7CisgICAgICAgIH0KKyAgICAgICAgLyogaWYgZWl0aGVyIGFyZyBpcyBOYU4sIHJldHVybiBOYU4gKi8KKyAgICAgICAgaWYgKGYxICE9IGYyKSB7CisgICAgICAgICAgICByZXR1cm4gRmxvYXQuTmFOOworICAgICAgICB9CisgICAgICAgIC8qIG1heCgrMC4wLC0wLjApID09ICswLjAgKi8KKyAgICAgICAgLyogRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMoMC4wZikgPT0gMCovCisgICAgICAgIGlmIChGbG9hdC5mbG9hdFRvUmF3SW50Qml0cyhmMSkgIT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGYyOworICAgICAgICB9CisgICAgICAgIHJldHVybiAwLjBmOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1vc3QgcG9zaXRpdmUgKGNsb3Nlc3QgdG8gcG9zaXRpdmUgaW5maW5pdHkpIG9mIHRoZSB0d28KKyAgICAgKiBhcmd1bWVudHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaTEKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBhcmd1bWVudC4KKyAgICAgKiBAcGFyYW0gaTIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgYXJndW1lbnQuCisgICAgICogQHJldHVybiB0aGUgbGFyZ2VyIG9mIHtAY29kZSBpMX0gYW5kIHtAY29kZSBpMn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IG1heChpbnQgaTEsIGludCBpMik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtb3N0IHBvc2l0aXZlIChjbG9zZXN0IHRvIHBvc2l0aXZlIGluZmluaXR5KSBvZiB0aGUgdHdvCisgICAgICogYXJndW1lbnRzLgorICAgICAqCisgICAgICogQHBhcmFtIGwxCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgYXJndW1lbnQuCisgICAgICogQHBhcmFtIGwyCisgICAgICogICAgICAgICAgICB0aGUgc2Vjb25kIGFyZ3VtZW50LgorICAgICAqIEByZXR1cm4gdGhlIGxhcmdlciBvZiB7QGNvZGUgbDF9IGFuZCB7QGNvZGUgbDJ9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBtYXgobG9uZyBsMSwgbG9uZyBsMikgeworICAgICAgICByZXR1cm4gbDEgPiBsMiA/IGwxIDogbDI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbW9zdCBuZWdhdGl2ZSAoY2xvc2VzdCB0byBuZWdhdGl2ZSBpbmZpbml0eSkgb2YgdGhlIHR3bworICAgICAqIGFyZ3VtZW50cy4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIG1pbihOYU4sIChhbnl0aGluZykpID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBtaW4oKGFueXRoaW5nKSwgTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbWluKCswLjAsIC0wLjApID0gLTAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbWluKC0wLjAsICswLjApID0gLTAuMH08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZDEKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBhcmd1bWVudC4KKyAgICAgKiBAcGFyYW0gZDIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgYXJndW1lbnQuCisgICAgICogQHJldHVybiB0aGUgc21hbGxlciBvZiB7QGNvZGUgZDF9IGFuZCB7QGNvZGUgZDJ9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIG1pbihkb3VibGUgZDEsIGRvdWJsZSBkMikgeworICAgICAgICBpZiAoZDEgPiBkMikgeworICAgICAgICAgICAgcmV0dXJuIGQyOworICAgICAgICB9CisgICAgICAgIGlmIChkMSA8IGQyKSB7CisgICAgICAgICAgICByZXR1cm4gZDE7CisgICAgICAgIH0KKyAgICAgICAgLyogaWYgZWl0aGVyIGFyZyBpcyBOYU4sIHJldHVybiBOYU4gKi8KKyAgICAgICAgaWYgKGQxICE9IGQyKSB7CisgICAgICAgICAgICByZXR1cm4gRG91YmxlLk5hTjsKKyAgICAgICAgfQorICAgICAgICAvKiBtaW4oKzAuMCwtMC4wKSA9PSAtMC4wICovCisgICAgICAgIC8qIDB4ODAwMDAwMDAwMDAwMDAwMEwgPT0gRG91YmxlLmRvdWJsZVRvUmF3TG9uZ0JpdHMoLTAuMGQpICovCisgICAgICAgIGlmIChEb3VibGUuZG91YmxlVG9SYXdMb25nQml0cyhkMSkgPT0gMHg4MDAwMDAwMDAwMDAwMDAwTCkgeworICAgICAgICAgICAgcmV0dXJuIC0wLjBkOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkMjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtb3N0IG5lZ2F0aXZlIChjbG9zZXN0IHRvIG5lZ2F0aXZlIGluZmluaXR5KSBvZiB0aGUgdHdvCisgICAgICogYXJndW1lbnRzLgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgbWluKE5hTiwgKGFueXRoaW5nKSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIG1pbigoYW55dGhpbmcpLCBOYU4pID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBtaW4oKzAuMCwgLTAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBtaW4oLTAuMCwgKzAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmMQorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IGFyZ3VtZW50LgorICAgICAqIEBwYXJhbSBmMgorICAgICAqICAgICAgICAgICAgdGhlIHNlY29uZCBhcmd1bWVudC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzbWFsbGVyIG9mIHtAY29kZSBmMX0gYW5kIHtAY29kZSBmMn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmbG9hdCBtaW4oZmxvYXQgZjEsIGZsb2F0IGYyKSB7CisgICAgICAgIGlmIChmMSA+IGYyKSB7CisgICAgICAgICAgICByZXR1cm4gZjI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGYxIDwgZjIpIHsKKyAgICAgICAgICAgIHJldHVybiBmMTsKKyAgICAgICAgfQorICAgICAgICAvKiBpZiBlaXRoZXIgYXJnIGlzIE5hTiwgcmV0dXJuIE5hTiAqLworICAgICAgICBpZiAoZjEgIT0gZjIpIHsKKyAgICAgICAgICAgIHJldHVybiBGbG9hdC5OYU47CisgICAgICAgIH0KKyAgICAgICAgLyogbWluKCswLjAsLTAuMCkgPT0gLTAuMCAqLworICAgICAgICAvKiAweDgwMDAwMDAwID09IEZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKC0wLjBmKSAqLworICAgICAgICBpZiAoRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMoZjEpID09IDB4ODAwMDAwMDApIHsKKyAgICAgICAgICAgIHJldHVybiAtMC4wZjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZjI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbW9zdCBuZWdhdGl2ZSAoY2xvc2VzdCB0byBuZWdhdGl2ZSBpbmZpbml0eSkgb2YgdGhlIHR3bworICAgICAqIGFyZ3VtZW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpMQorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IGFyZ3VtZW50LgorICAgICAqIEBwYXJhbSBpMgorICAgICAqICAgICAgICAgICAgdGhlIHNlY29uZCBhcmd1bWVudC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzbWFsbGVyIG9mIHtAY29kZSBpMX0gYW5kIHtAY29kZSBpMn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IG1pbihpbnQgaTEsIGludCBpMik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtb3N0IG5lZ2F0aXZlIChjbG9zZXN0IHRvIG5lZ2F0aXZlIGluZmluaXR5KSBvZiB0aGUgdHdvCisgICAgICogYXJndW1lbnRzLgorICAgICAqCisgICAgICogQHBhcmFtIGwxCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgYXJndW1lbnQuCisgICAgICogQHBhcmFtIGwyCisgICAgICogICAgICAgICAgICB0aGUgc2Vjb25kIGFyZ3VtZW50LgorICAgICAqIEByZXR1cm4gdGhlIHNtYWxsZXIgb2Yge0Bjb2RlIGwxfSBhbmQge0Bjb2RlIGwyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgbWluKGxvbmcgbDEsIGxvbmcgbDIpIHsKKyAgICAgICAgcmV0dXJuIGwxIDwgbDIgPyBsMSA6IGwyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNsb3Nlc3QgZG91YmxlIGFwcHJveGltYXRpb24gb2YgdGhlIHJlc3VsdCBvZiByYWlzaW5nIHtAY29kZQorICAgICAqIHh9IHRvIHRoZSBwb3dlciBvZiB7QGNvZGUgeX0uCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBwb3coKGFueXRoaW5nKSwgKzAuMCkgPSAxLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHBvdygoYW55dGhpbmcpLCAtMC4wKSA9IDEuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcG93KHgsIDEuMCkgPSB4fTwvbGk+CisgICAgICogPGxpPntAY29kZSBwb3coKGFueXRoaW5nKSwgTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcG93KE5hTiwgKGFueXRoaW5nIGV4Y2VwdCAwKSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHBvdygrLy0ofHh8ID4gMSksICtpbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHBvdygrLy0ofHh8ID4gMSksIC1pbmZpbml0eSkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBwb3coKy8tKHx4fCA8IDEpLCAraW5maW5pdHkpID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcG93KCsvLSh8eHwgPCAxKSwgLWluZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcG93KCsvLTEuMCAsICtpbmZpbml0eSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHBvdygrLy0xLjAgLCAtaW5maW5pdHkpID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBwb3coKzAuMCwgKCthbnl0aGluZyBleGNlcHQgMCwgTmFOKSkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBwb3coLTAuMCwgKCthbnl0aGluZyBleGNlcHQgMCwgTmFOLCBvZGQgaW50ZWdlcikpID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcG93KCswLjAsICgtYW55dGhpbmcgZXhjZXB0IDAsIE5hTikpID0gK2luZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBwb3coLTAuMCwgKC1hbnl0aGluZyBleGNlcHQgMCwgTkFOLCBvZGQgaW50ZWdlcikpfSB7QGNvZGUgPX0KKyAgICAgKiB7QGNvZGUgK2luZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBwb3coLTAuMCwgKG9kZCBpbnRlZ2VyKSkgPSAtcG93KCArMCAsIChvZGQgaW50ZWdlcikgKX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcG93KCtpbmZpbml0eSwgKCthbnl0aGluZyBleGNlcHQgMCwgTmFOKSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHBvdygraW5maW5pdHksICgtYW55dGhpbmcgZXhjZXB0IDAsIE5hTikpID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcG93KC1pbmZpbml0eSwgKGFueXRoaW5nKSkgPSAtcG93KDAsICgtYW55dGhpbmcpKX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcG93KCgtYW55dGhpbmcpLCAoaW50ZWdlcikpfSB7QGNvZGUgPX0ge0Bjb2RlCisgICAgICogcG93KC0xLChpbnRlZ2VyKSkqcG93KCthbnl0aGluZyxpbnRlZ2VyKSB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHBvdygoLWFueXRoaW5nIGV4Y2VwdCAwIGFuZCBpbmYpLCAobm9uLWludGVnZXIpKSA9IE5BTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIGJhc2Ugb2YgdGhlIG9wZXJhdGlvbi4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIGV4cG9uZW50IG9mIHRoZSBvcGVyYXRpb24uCisgICAgICogQHJldHVybiB7QGNvZGUgeH0gdG8gdGhlIHBvd2VyIG9mIHtAY29kZSB5fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgcG93KGRvdWJsZSB4LCBkb3VibGUgeSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkb3VibGUgY29udmVyc2lvbiBvZiB0aGUgcmVzdWx0IG9mIHJvdW5kaW5nIHRoZSBhcmd1bWVudCB0bworICAgICAqIGFuIGludGVnZXIuIFRpZSBicmVha3MgYXJlIHJvdW5kZWQgdG93YXJkcyBldmVuLgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgcmludCgrMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHJpbnQoLTAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSByaW50KCtpbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHJpbnQoLWluZmluaXR5KSA9IC1pbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcmludChOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gYmUgcm91bmRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBjbG9zZXN0IGludGVnZXIgdG8gdGhlIGFyZ3VtZW50IChhcyBhIGRvdWJsZSkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIHJpbnQoZG91YmxlIGQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmVzdWx0IG9mIHJvdW5kaW5nIHRoZSBhcmd1bWVudCB0byBhbiBpbnRlZ2VyLiBUaGUgcmVzdWx0IGlzCisgICAgICogZXF1aXZhbGVudCB0byB7QGNvZGUgKGxvbmcpIE1hdGguZmxvb3IoZCswLjUpfS4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIHJvdW5kKCswLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcm91bmQoLTAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSByb3VuZCgoYW55dGhpbmcgPiBMb25nLk1BWF9WQUxVRSkgPSBMb25nLk1BWF9WQUxVRX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcm91bmQoKGFueXRoaW5nIDwgTG9uZy5NSU5fVkFMVUUpID0gTG9uZy5NSU5fVkFMVUV9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHJvdW5kKCtpbmZpbml0eSkgPSBMb25nLk1BWF9WQUxVRX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcm91bmQoLWluZmluaXR5KSA9IExvbmcuTUlOX1ZBTFVFfTwvbGk+CisgICAgICogPGxpPntAY29kZSByb3VuZChOYU4pID0gKzAuMH08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIGJlIHJvdW5kZWQuCisgICAgICogQHJldHVybiB0aGUgY2xvc2VzdCBpbnRlZ2VyIHRvIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgcm91bmQoZG91YmxlIGQpIHsKKyAgICAgICAgLy8gY2hlY2sgZm9yIE5hTgorICAgICAgICBpZiAoZCAhPSBkKSB7CisgICAgICAgICAgICByZXR1cm4gMEw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChsb25nKSBmbG9vcihkICsgMC41ZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmVzdWx0IG9mIHJvdW5kaW5nIHRoZSBhcmd1bWVudCB0byBhbiBpbnRlZ2VyLiBUaGUgcmVzdWx0IGlzCisgICAgICogZXF1aXZhbGVudCB0byB7QGNvZGUgKGludCkgTWF0aC5mbG9vcihmKzAuNSl9LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgcm91bmQoKzAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSByb3VuZCgtMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHJvdW5kKChhbnl0aGluZyA+IEludGVnZXIuTUFYX1ZBTFVFKSA9IEludGVnZXIuTUFYX1ZBTFVFfTwvbGk+CisgICAgICogPGxpPntAY29kZSByb3VuZCgoYW55dGhpbmcgPCBJbnRlZ2VyLk1JTl9WQUxVRSkgPSBJbnRlZ2VyLk1JTl9WQUxVRX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcm91bmQoK2luZmluaXR5KSA9IEludGVnZXIuTUFYX1ZBTFVFfTwvbGk+CisgICAgICogPGxpPntAY29kZSByb3VuZCgtaW5maW5pdHkpID0gSW50ZWdlci5NSU5fVkFMVUV9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHJvdW5kKE5hTikgPSArMC4wfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gYmUgcm91bmRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBjbG9zZXN0IGludGVnZXIgdG8gdGhlIGFyZ3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHJvdW5kKGZsb2F0IGYpIHsKKyAgICAgICAgLy8gY2hlY2sgZm9yIE5hTgorICAgICAgICBpZiAoZiAhPSBmKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKGludCkgZmxvb3IoZiArIDAuNWYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNpZ251bSBmdW5jdGlvbiBvZiB0aGUgYXJndW1lbnQuIElmIHRoZSBhcmd1bWVudCBpcyBsZXNzIHRoYW4KKyAgICAgKiB6ZXJvLCBpdCByZXR1cm5zIC0xLjAuIElmIHRoZSBhcmd1bWVudCBpcyBncmVhdGVyIHRoYW4gemVybywgMS4wIGlzCisgICAgICogcmV0dXJuZWQuIElmIHRoZSBhcmd1bWVudCBpcyBlaXRoZXIgcG9zaXRpdmUgb3IgbmVnYXRpdmUgemVybywgdGhlCisgICAgICogYXJndW1lbnQgaXMgcmV0dXJuZWQgYXMgcmVzdWx0LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgc2lnbnVtKCswLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc2lnbnVtKC0wLjApID0gLTAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc2lnbnVtKCtpbmZpbml0eSkgPSArMS4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBzaWdudW0oLWluZmluaXR5KSA9IC0xLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHNpZ251bShOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgd2hvc2Ugc2lnbnVtIGhhcyB0byBiZSBjb21wdXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgc2lnbnVtIGZ1bmN0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHNpZ251bShkb3VibGUgZCkgeworICAgICAgICBpZiAoRG91YmxlLmlzTmFOKGQpKSB7CisgICAgICAgICAgICByZXR1cm4gRG91YmxlLk5hTjsKKyAgICAgICAgfQorICAgICAgICBkb3VibGUgc2lnID0gZDsKKyAgICAgICAgaWYgKGQgPiAwKSB7CisgICAgICAgICAgICBzaWcgPSAxLjA7CisgICAgICAgIH0gZWxzZSBpZiAoZCA8IDApIHsKKyAgICAgICAgICAgIHNpZyA9IC0xLjA7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNpZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzaWdudW0gZnVuY3Rpb24gb2YgdGhlIGFyZ3VtZW50LiBJZiB0aGUgYXJndW1lbnQgaXMgbGVzcyB0aGFuCisgICAgICogemVybywgaXQgcmV0dXJucyAtMS4wLiBJZiB0aGUgYXJndW1lbnQgaXMgZ3JlYXRlciB0aGFuIHplcm8sIDEuMCBpcworICAgICAqIHJldHVybmVkLiBJZiB0aGUgYXJndW1lbnQgaXMgZWl0aGVyIHBvc2l0aXZlIG9yIG5lZ2F0aXZlIHplcm8sIHRoZQorICAgICAqIGFyZ3VtZW50IGlzIHJldHVybmVkIGFzIHJlc3VsdC4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIHNpZ251bSgrMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHNpZ251bSgtMC4wKSA9IC0wLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHNpZ251bSgraW5maW5pdHkpID0gKzEuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc2lnbnVtKC1pbmZpbml0eSkgPSAtMS4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBzaWdudW0oTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZgorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHdob3NlIHNpZ251bSBoYXMgdG8gYmUgY29tcHV0ZWQuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHNpZ251bSBmdW5jdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZsb2F0IHNpZ251bShmbG9hdCBmKSB7CisgICAgICAgIGlmIChGbG9hdC5pc05hTihmKSkgeworICAgICAgICAgICAgcmV0dXJuIEZsb2F0Lk5hTjsKKyAgICAgICAgfQorICAgICAgICBmbG9hdCBzaWcgPSBmOworICAgICAgICBpZiAoZiA+IDApIHsKKyAgICAgICAgICAgIHNpZyA9IDEuMGY7CisgICAgICAgIH0gZWxzZSBpZiAoZiA8IDApIHsKKyAgICAgICAgICAgIHNpZyA9IC0xLjBmOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzaWc7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2xvc2VzdCBkb3VibGUgYXBwcm94aW1hdGlvbiBvZiB0aGUgc2luZSBvZiB0aGUgYXJndW1lbnQuIFRoZQorICAgICAqIHJldHVybmVkIHJlc3VsdCBpcyB3aXRoaW4gMSB1bHAgKHVuaXQgaW4gdGhlIGxhc3QgcGxhY2UpIG9mIHRoZSByZWFsCisgICAgICogcmVzdWx0LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgc2luKCswLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc2luKC0wLjApID0gLTAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc2luKCtpbmZpbml0eSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHNpbigtaW5maW5pdHkpID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBzaW4oTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIGFuZ2xlIHdob3NlIHNpbiBoYXMgdG8gYmUgY29tcHV0ZWQsIGluIHJhZGlhbnMuCisgICAgICogQHJldHVybiB0aGUgc2luZSBvZiB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIHNpbihkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSBoeXBlcmJvbGljIHNpbmUgb2YgdGhlCisgICAgICogYXJndW1lbnQuIFRoZSByZXR1cm5lZCByZXN1bHQgaXMgd2l0aGluIDIuNSB1bHBzICh1bml0cyBpbiB0aGUgbGFzdAorICAgICAqIHBsYWNlKSBvZiB0aGUgcmVhbCByZXN1bHQuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBzaW5oKCswLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc2luaCgtMC4wKSA9IC0wLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHNpbmgoK2luZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc2luaCgtaW5maW5pdHkpID0gLWluZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBzaW5oKE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB3aG9zZSBoeXBlcmJvbGljIHNpbmUgaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGh5cGVyYm9saWMgc2luZSBvZiB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIHNpbmgoZG91YmxlIGQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2xvc2VzdCBkb3VibGUgYXBwcm94aW1hdGlvbiBvZiB0aGUgc3F1YXJlIHJvb3Qgb2YgdGhlCisgICAgICogYXJndW1lbnQuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBzcXJ0KCswLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc3FydCgtMC4wKSA9IC0wLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHNxcnQoIChhbnl0aGluZyA8IDApICkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHNxcnQoK2luZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc3FydChOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgd2hvc2Ugc3F1YXJlIHJvb3QgaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIHNxdWFyZSByb290IG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgc3FydChkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSB0YW5nZW50IG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKiBUaGUgcmV0dXJuZWQgcmVzdWx0IGlzIHdpdGhpbiAxIHVscCAodW5pdCBpbiB0aGUgbGFzdCBwbGFjZSkgb2YgdGhlIHJlYWwKKyAgICAgKiByZXN1bHQuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSB0YW4oKzAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSB0YW4oLTAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSB0YW4oK2luZmluaXR5KSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdGFuKC1pbmZpbml0eSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHRhbihOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgYW5nbGUgd2hvc2UgdGFuZ2VudCBoYXMgdG8gYmUgY29tcHV0ZWQsIGluIHJhZGlhbnMuCisgICAgICogQHJldHVybiB0aGUgdGFuZ2VudCBvZiB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIHRhbihkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSBoeXBlcmJvbGljIHRhbmdlbnQgb2YgdGhlCisgICAgICogYXJndW1lbnQuIFRoZSBhYnNvbHV0ZSB2YWx1ZSBpcyBhbHdheXMgbGVzcyB0aGFuIDEuIFRoZSByZXR1cm5lZCByZXN1bHQKKyAgICAgKiBpcyB3aXRoaW4gMi41IHVscHMgKHVuaXRzIGluIHRoZSBsYXN0IHBsYWNlKSBvZiB0aGUgcmVhbCByZXN1bHQuIElmIHRoZQorICAgICAqIHJlYWwgcmVzdWx0IGlzIHdpdGhpbiAwLjV1bHAgb2YgMSBvciAtMSwgaXQgc2hvdWxkIHJldHVybiBleGFjdGx5ICsxIG9yCisgICAgICogLTEuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSB0YW5oKCswLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdGFuaCgtMC4wKSA9IC0wLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHRhbmgoK2luZmluaXR5KSA9ICsxLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHRhbmgoLWluZmluaXR5KSA9IC0xLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHRhbmgoTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHdob3NlIGh5cGVyYm9saWMgdGFuZ2VudCBoYXMgdG8gYmUgY29tcHV0ZWQuCisgICAgICogQHJldHVybiB0aGUgaHlwZXJib2xpYyB0YW5nZW50IG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgdGFuaChkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcHNldWRvLXJhbmRvbSBkb3VibGUge0Bjb2RlIG59LCB3aGVyZSB7QGNvZGUgbiA+PSAwLjAgJiYgbiA8IDEuMH0uCisgICAgICogVGhpcyBtZXRob2QgcmV1c2VzIGEgc2luZ2xlIGluc3RhbmNlIG9mIHtAbGluayBqYXZhLnV0aWwuUmFuZG9tfS4KKyAgICAgKiBUaGlzIG1ldGhvZCBpcyB0aHJlYWQtc2FmZSBiZWNhdXNlIGFjY2VzcyB0byB0aGUge0Bjb2RlIFJhbmRvbX0gaXMgc3luY2hyb25pemVkLAorICAgICAqIGJ1dCB0aGlzIGhhcm1zIHNjYWxhYmlsaXR5LiBBcHBsaWNhdGlvbnMgbWF5IGZpbmQgYSBwZXJmb3JtYW5jZSBiZW5lZml0IGZyb20KKyAgICAgKiBhbGxvY2F0aW5nIGEge0Bjb2RlIFJhbmRvbX0gZm9yIGVhY2ggb2YgdGhlaXIgdGhyZWFkcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBwc2V1ZG8tcmFuZG9tIG51bWJlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBkb3VibGUgcmFuZG9tKCkgeworICAgICAgICBpZiAocmFuZG9tID09IG51bGwpIHsKKyAgICAgICAgICAgIHJhbmRvbSA9IG5ldyBSYW5kb20oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmFuZG9tLm5leHREb3VibGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtZWFzdXJlIGluIHJhZGlhbnMgb2YgdGhlIHN1cHBsaWVkIGRlZ3JlZSBhbmdsZS4gVGhlIHJlc3VsdAorICAgICAqIGlzIHtAY29kZSBhbmdkZWcgLyAxODAgKiBwaX0uCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSB0b1JhZGlhbnMoKzAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSB0b1JhZGlhbnMoLTAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSB0b1JhZGlhbnMoK2luZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdG9SYWRpYW5zKC1pbmZpbml0eSkgPSAtaW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHRvUmFkaWFucyhOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbmdkZWcKKyAgICAgKiAgICAgICAgICAgIGFuIGFuZ2xlIGluIGRlZ3JlZXMuCisgICAgICogQHJldHVybiB0aGUgcmFkaWFuIG1lYXN1cmUgb2YgdGhlIGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHRvUmFkaWFucyhkb3VibGUgYW5nZGVnKSB7CisgICAgICAgIHJldHVybiBhbmdkZWcgLyAxODBkICogUEk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbWVhc3VyZSBpbiBkZWdyZWVzIG9mIHRoZSBzdXBwbGllZCByYWRpYW4gYW5nbGUuIFRoZSByZXN1bHQKKyAgICAgKiBpcyB7QGNvZGUgYW5ncmFkICogMTgwIC8gcGl9LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgdG9EZWdyZWVzKCswLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdG9EZWdyZWVzKC0wLjApID0gLTAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdG9EZWdyZWVzKCtpbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHRvRGVncmVlcygtaW5maW5pdHkpID0gLWluZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSB0b0RlZ3JlZXMoTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gYW5ncmFkCisgICAgICogICAgICAgICAgICBhbiBhbmdsZSBpbiByYWRpYW5zLgorICAgICAqIEByZXR1cm4gdGhlIGRlZ3JlZSBtZWFzdXJlIG9mIHRoZSBhbmdsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSB0b0RlZ3JlZXMoZG91YmxlIGFuZ3JhZCkgeworICAgICAgICByZXR1cm4gYW5ncmFkICogMTgwZCAvIFBJOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFyZ3VtZW50J3MgdWxwICh1bml0IGluIHRoZSBsYXN0IHBsYWNlKS4gVGhlIHNpemUgb2YgYSB1bHAgb2YKKyAgICAgKiBhIGRvdWJsZSB2YWx1ZSBpcyB0aGUgcG9zaXRpdmUgZGlzdGFuY2UgYmV0d2VlbiB0aGlzIHZhbHVlIGFuZCB0aGUgZG91YmxlCisgICAgICogdmFsdWUgbmV4dCBsYXJnZXIgaW4gbWFnbml0dWRlLiBGb3Igbm9uLU5hTiB7QGNvZGUgeH0sIHtAY29kZSB1bHAoLXgpID09CisgICAgICogdWxwKHgpfS4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIHVscCgrMC4wKSA9IERvdWJsZS5NSU5fVkFMVUV9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHVscCgtMC4wKSA9IERvdWJsZS5NSU5fVkFMVUV9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHVscCgraW5maW5pdHkpID0gaW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHVscCgtaW5maW5pdHkpID0gaW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHVscChOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgZmxvYXRpbmctcG9pbnQgdmFsdWUgdG8gY29tcHV0ZSB1bHAgb2YuCisgICAgICogQHJldHVybiB0aGUgc2l6ZSBvZiBhIHVscCBvZiB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgdWxwKGRvdWJsZSBkKSB7CisgICAgICAgIC8vIHNwZWNpYWwgY2FzZXMKKyAgICAgICAgaWYgKERvdWJsZS5pc0luZmluaXRlKGQpKSB7CisgICAgICAgICAgICByZXR1cm4gRG91YmxlLlBPU0lUSVZFX0lORklOSVRZOworICAgICAgICB9IGVsc2UgaWYgKGQgPT0gRG91YmxlLk1BWF9WQUxVRSB8fCBkID09IC1Eb3VibGUuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgICByZXR1cm4gcG93KDIsIDk3MSk7CisgICAgICAgIH0KKyAgICAgICAgZCA9IGFicyhkKTsKKyAgICAgICAgcmV0dXJuIG5leHRhZnRlcihkLCBEb3VibGUuTUFYX1ZBTFVFKSAtIGQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGRvdWJsZSBuZXh0YWZ0ZXIoZG91YmxlIHgsIGRvdWJsZSB5KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFyZ3VtZW50J3MgdWxwICh1bml0IGluIHRoZSBsYXN0IHBsYWNlKS4gVGhlIHNpemUgb2YgYSB1bHAgb2YKKyAgICAgKiBhIGZsb2F0IHZhbHVlIGlzIHRoZSBwb3NpdGl2ZSBkaXN0YW5jZSBiZXR3ZWVuIHRoaXMgdmFsdWUgYW5kIHRoZSBmbG9hdAorICAgICAqIHZhbHVlIG5leHQgbGFyZ2VyIGluIG1hZ25pdHVkZS4gRm9yIG5vbi1OYU4ge0Bjb2RlIHh9LCB7QGNvZGUgdWxwKC14KSA9PQorICAgICAqIHVscCh4KX0uCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSB1bHAoKzAuMCkgPSBGbG9hdC5NSU5fVkFMVUV9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHVscCgtMC4wKSA9IEZsb2F0Lk1JTl9WQUxVRX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdWxwKCtpbmZpbml0eSkgPSBpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdWxwKC1pbmZpbml0eSkgPSBpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdWxwKE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGYKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbG9hdGluZy1wb2ludCB2YWx1ZSB0byBjb21wdXRlIHVscCBvZi4KKyAgICAgKiBAcmV0dXJuIHRoZSBzaXplIG9mIGEgdWxwIG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZsb2F0IHVscChmbG9hdCBmKSB7CisgICAgICAgIC8vIHNwZWNpYWwgY2FzZXMKKyAgICAgICAgaWYgKEZsb2F0LmlzTmFOKGYpKSB7CisgICAgICAgICAgICByZXR1cm4gRmxvYXQuTmFOOworICAgICAgICB9IGVsc2UgaWYgKEZsb2F0LmlzSW5maW5pdGUoZikpIHsKKyAgICAgICAgICAgIHJldHVybiBGbG9hdC5QT1NJVElWRV9JTkZJTklUWTsKKyAgICAgICAgfSBlbHNlIGlmIChmID09IEZsb2F0Lk1BWF9WQUxVRSB8fCBmID09IC1GbG9hdC5NQVhfVkFMVUUpIHsKKyAgICAgICAgICAgIHJldHVybiAoZmxvYXQpIHBvdygyLCAxMDQpOworICAgICAgICB9CisKKyAgICAgICAgZiA9IE1hdGguYWJzKGYpOworICAgICAgICBpbnQgaHggPSBGbG9hdC5mbG9hdFRvUmF3SW50Qml0cyhmKTsKKyAgICAgICAgaW50IGh5ID0gRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMoRmxvYXQuTUFYX1ZBTFVFKTsKKyAgICAgICAgaWYgKChoeCAmIDB4N2ZmZmZmZmYpID09IDApIHsgLyogZiA9PSAwICovCisgICAgICAgICAgICByZXR1cm4gRmxvYXQuaW50Qml0c1RvRmxvYXQoKGh5ICYgMHg4MDAwMDAwMCkgfCAweDEpOworICAgICAgICB9CisgICAgICAgIGlmICgoaHggPiAwKSBeIChoeCA+IGh5KSkgeyAvKiB8ZnwgPCB8RmxvYXQuTUFYX1ZBTFVFfCAqLworICAgICAgICAgICAgaHggKz0gMTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGh4IC09IDE7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIEZsb2F0LmludEJpdHNUb0Zsb2F0KGh4KSAtIGY7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGRvdWJsZSB3aXRoIHRoZSBnaXZlbiBtYWduaXR1ZGUgYW5kIHRoZSBzaWduIG9mIHtAY29kZSBzaWdufS4KKyAgICAgKiBJZiB7QGNvZGUgc2lnbn0gaXMgTmFOLCB0aGUgc2lnbiBvZiB0aGUgcmVzdWx0IGlzIGFyYml0cmFyeS4KKyAgICAgKiBJZiB5b3UgbmVlZCBhIGRldGVybWluYXRlIHNpZ24gaW4gc3VjaCBjYXNlcywgdXNlIHtAY29kZSBTdHJpY3RNYXRoLmNvcHlTaWdufS4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgY29weVNpZ24oZG91YmxlIG1hZ25pdHVkZSwgZG91YmxlIHNpZ24pIHsKKyAgICAgICAgbG9uZyBtYWduaXR1ZGVCaXRzID0gRG91YmxlLmRvdWJsZVRvUmF3TG9uZ0JpdHMobWFnbml0dWRlKTsKKyAgICAgICAgbG9uZyBzaWduQml0cyA9IERvdWJsZS5kb3VibGVUb1Jhd0xvbmdCaXRzKHNpZ24pOworICAgICAgICBtYWduaXR1ZGVCaXRzID0gKG1hZ25pdHVkZUJpdHMgJiB+RG91YmxlLlNJR05fTUFTSykgfCAoc2lnbkJpdHMgJiBEb3VibGUuU0lHTl9NQVNLKTsKKyAgICAgICAgcmV0dXJuIERvdWJsZS5sb25nQml0c1RvRG91YmxlKG1hZ25pdHVkZUJpdHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBmbG9hdCB3aXRoIHRoZSBnaXZlbiBtYWduaXR1ZGUgYW5kIHRoZSBzaWduIG9mIHtAY29kZSBzaWdufS4KKyAgICAgKiBJZiB7QGNvZGUgc2lnbn0gaXMgTmFOLCB0aGUgc2lnbiBvZiB0aGUgcmVzdWx0IGlzIGFyYml0cmFyeS4KKyAgICAgKiBJZiB5b3UgbmVlZCBhIGRldGVybWluYXRlIHNpZ24gaW4gc3VjaCBjYXNlcywgdXNlIHtAY29kZSBTdHJpY3RNYXRoLmNvcHlTaWdufS4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmbG9hdCBjb3B5U2lnbihmbG9hdCBtYWduaXR1ZGUsIGZsb2F0IHNpZ24pIHsKKyAgICAgICAgaW50IG1hZ25pdHVkZUJpdHMgPSBGbG9hdC5mbG9hdFRvUmF3SW50Qml0cyhtYWduaXR1ZGUpOworICAgICAgICBpbnQgc2lnbkJpdHMgPSBGbG9hdC5mbG9hdFRvUmF3SW50Qml0cyhzaWduKTsKKyAgICAgICAgbWFnbml0dWRlQml0cyA9IChtYWduaXR1ZGVCaXRzICYgfkZsb2F0LlNJR05fTUFTSykgfCAoc2lnbkJpdHMgJiBGbG9hdC5TSUdOX01BU0spOworICAgICAgICByZXR1cm4gRmxvYXQuaW50Qml0c1RvRmxvYXQobWFnbml0dWRlQml0cyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdW5iaWFzZWQgYmFzZS0yIGV4cG9uZW50IG9mIGZsb2F0IHtAY29kZSBmfS4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZ2V0RXhwb25lbnQoZmxvYXQgZikgeworICAgICAgICBpbnQgYml0cyA9IEZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKGYpOworICAgICAgICBiaXRzID0gKGJpdHMgJiBGbG9hdC5FWFBPTkVOVF9NQVNLKSA+PiBGbG9hdC5NQU5USVNTQV9CSVRTOworICAgICAgICByZXR1cm4gYml0cyAtIEZsb2F0LkVYUE9ORU5UX0JJQVM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdW5iaWFzZWQgYmFzZS0yIGV4cG9uZW50IG9mIGRvdWJsZSB7QGNvZGUgZH0uCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldEV4cG9uZW50KGRvdWJsZSBkKSB7CisgICAgICAgIGxvbmcgYml0cyA9IERvdWJsZS5kb3VibGVUb1Jhd0xvbmdCaXRzKGQpOworICAgICAgICBiaXRzID0gKGJpdHMgJiBEb3VibGUuRVhQT05FTlRfTUFTSykgPj4gRG91YmxlLk1BTlRJU1NBX0JJVFM7CisgICAgICAgIHJldHVybiAoaW50KSBiaXRzIC0gRG91YmxlLkVYUE9ORU5UX0JJQVM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBkb3VibGUgYWZ0ZXIge0Bjb2RlIHN0YXJ0fSBpbiB0aGUgZ2l2ZW4ge0Bjb2RlIGRpcmVjdGlvbn0uCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIG5leHRBZnRlcihkb3VibGUgc3RhcnQsIGRvdWJsZSBkaXJlY3Rpb24pIHsKKyAgICAgICAgaWYgKHN0YXJ0ID09IDAgJiYgZGlyZWN0aW9uID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBkaXJlY3Rpb247CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5leHRhZnRlcihzdGFydCwgZGlyZWN0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGZsb2F0IGFmdGVyIHtAY29kZSBzdGFydH0gaW4gdGhlIGdpdmVuIHtAY29kZSBkaXJlY3Rpb259LgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZsb2F0IG5leHRBZnRlcihmbG9hdCBzdGFydCwgZG91YmxlIGRpcmVjdGlvbikgeworICAgICAgICBpZiAoRmxvYXQuaXNOYU4oc3RhcnQpIHx8IERvdWJsZS5pc05hTihkaXJlY3Rpb24pKSB7CisgICAgICAgICAgICByZXR1cm4gRmxvYXQuTmFOOworICAgICAgICB9CisgICAgICAgIGlmIChzdGFydCA9PSAwICYmIGRpcmVjdGlvbiA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gKGZsb2F0KSBkaXJlY3Rpb247CisgICAgICAgIH0KKyAgICAgICAgaWYgKChzdGFydCA9PSBGbG9hdC5NSU5fVkFMVUUgJiYgZGlyZWN0aW9uIDwgc3RhcnQpCisgICAgICAgICAgICAgICAgfHwgKHN0YXJ0ID09IC1GbG9hdC5NSU5fVkFMVUUgJiYgZGlyZWN0aW9uID4gc3RhcnQpKSB7CisgICAgICAgICAgICByZXR1cm4gKHN0YXJ0ID4gMCA/IDBmIDogLTBmKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoRmxvYXQuaXNJbmZpbml0ZShzdGFydCkgJiYgKGRpcmVjdGlvbiAhPSBzdGFydCkpIHsKKyAgICAgICAgICAgIHJldHVybiAoc3RhcnQgPiAwID8gRmxvYXQuTUFYX1ZBTFVFIDogLUZsb2F0Lk1BWF9WQUxVRSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChzdGFydCA9PSBGbG9hdC5NQVhfVkFMVUUgJiYgZGlyZWN0aW9uID4gc3RhcnQpCisgICAgICAgICAgICAgICAgfHwgKHN0YXJ0ID09IC1GbG9hdC5NQVhfVkFMVUUgJiYgZGlyZWN0aW9uIDwgc3RhcnQpKSB7CisgICAgICAgICAgICByZXR1cm4gKHN0YXJ0ID4gMCA/IEZsb2F0LlBPU0lUSVZFX0lORklOSVRZCisgICAgICAgICAgICAgICAgICAgIDogRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFkpOworICAgICAgICB9CisgICAgICAgIGlmIChkaXJlY3Rpb24gPiBzdGFydCkgeworICAgICAgICAgICAgaWYgKHN0YXJ0ID4gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBGbG9hdC5pbnRCaXRzVG9GbG9hdChGbG9hdC5mbG9hdFRvSW50Qml0cyhzdGFydCkgKyAxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzdGFydCA8IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gRmxvYXQuaW50Qml0c1RvRmxvYXQoRmxvYXQuZmxvYXRUb0ludEJpdHMoc3RhcnQpIC0gMSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gK0Zsb2F0Lk1JTl9WQUxVRTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZGlyZWN0aW9uIDwgc3RhcnQpIHsKKyAgICAgICAgICAgIGlmIChzdGFydCA+IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gRmxvYXQuaW50Qml0c1RvRmxvYXQoRmxvYXQuZmxvYXRUb0ludEJpdHMoc3RhcnQpIC0gMSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc3RhcnQgPCAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIEZsb2F0LmludEJpdHNUb0Zsb2F0KEZsb2F0LmZsb2F0VG9JbnRCaXRzKHN0YXJ0KSArIDEpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIC1GbG9hdC5NSU5fVkFMVUU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChmbG9hdCkgZGlyZWN0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgZG91YmxlIGxhcmdlciB0aGFuIHtAY29kZSBkfS4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgbmV4dFVwKGRvdWJsZSBkKSB7CisgICAgICAgIGlmIChEb3VibGUuaXNOYU4oZCkpIHsKKyAgICAgICAgICAgIHJldHVybiBEb3VibGUuTmFOOworICAgICAgICB9CisgICAgICAgIGlmIChkID09IERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSkgeworICAgICAgICAgICAgcmV0dXJuIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gRG91YmxlLk1JTl9WQUxVRTsKKyAgICAgICAgfSBlbHNlIGlmIChkID4gMCkgeworICAgICAgICAgICAgcmV0dXJuIERvdWJsZS5sb25nQml0c1RvRG91YmxlKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGQpICsgMSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gRG91YmxlLmxvbmdCaXRzVG9Eb3VibGUoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZCkgLSAxKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgZmxvYXQgbGFyZ2VyIHRoYW4ge0Bjb2RlIGZ9LgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZsb2F0IG5leHRVcChmbG9hdCBmKSB7CisgICAgICAgIGlmIChGbG9hdC5pc05hTihmKSkgeworICAgICAgICAgICAgcmV0dXJuIEZsb2F0Lk5hTjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZiA9PSBGbG9hdC5QT1NJVElWRV9JTkZJTklUWSkgeworICAgICAgICAgICAgcmV0dXJuIEZsb2F0LlBPU0lUSVZFX0lORklOSVRZOworICAgICAgICB9CisgICAgICAgIGlmIChmID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBGbG9hdC5NSU5fVkFMVUU7CisgICAgICAgIH0gZWxzZSBpZiAoZiA+IDApIHsKKyAgICAgICAgICAgIHJldHVybiBGbG9hdC5pbnRCaXRzVG9GbG9hdChGbG9hdC5mbG9hdFRvSW50Qml0cyhmKSArIDEpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIEZsb2F0LmludEJpdHNUb0Zsb2F0KEZsb2F0LmZsb2F0VG9JbnRCaXRzKGYpIC0gMSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHtAY29kZSBkfSAqIDJee0Bjb2RlIHNjYWxlRmFjdG9yfS4gVGhlIHJlc3VsdCBtYXkgYmUgcm91bmRlZC4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgc2NhbGIoZG91YmxlIGQsIGludCBzY2FsZUZhY3RvcikgeworICAgICAgICBpZiAoRG91YmxlLmlzTmFOKGQpIHx8IERvdWJsZS5pc0luZmluaXRlKGQpIHx8IGQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGQ7CisgICAgICAgIH0KKyAgICAgICAgLy8gY2hhbmdlIGRvdWJsZSB0byBsb25nIGZvciBjYWxjdWxhdGlvbgorICAgICAgICBsb25nIGJpdHMgPSBEb3VibGUuZG91YmxlVG9Mb25nQml0cyhkKTsKKyAgICAgICAgLy8gdGhlIHNpZ24gb2YgdGhlIHJlc3VsdHMgbXVzdCBiZSB0aGUgc2FtZSBvZiBnaXZlbiBkCisgICAgICAgIGxvbmcgc2lnbiA9IGJpdHMgJiBEb3VibGUuU0lHTl9NQVNLOworICAgICAgICAvLyBjYWxjdWxhdGVzIHRoZSBmYWN0b3Igb2YgdGhlIHJlc3VsdAorICAgICAgICBsb25nIGZhY3RvciA9ICgoYml0cyAmIERvdWJsZS5FWFBPTkVOVF9NQVNLKSA+PiBEb3VibGUuTUFOVElTU0FfQklUUykKKyAgICAgICAgICAgICAgICAtIERvdWJsZS5FWFBPTkVOVF9CSUFTICsgc2NhbGVGYWN0b3I7CisKKyAgICAgICAgLy8gY2FsY3VsYXRlcyB0aGUgZmFjdG9yIG9mIHN1Yi1ub3JtYWwgdmFsdWVzCisgICAgICAgIGludCBzdWJOb3JtYWxGYWN0b3IgPSBMb25nLm51bWJlck9mTGVhZGluZ1plcm9zKGJpdHMgJiB+RG91YmxlLlNJR05fTUFTSykKKyAgICAgICAgICAgICAgICAtIERvdWJsZS5OT05fTUFOVElTU0FfQklUUzsKKyAgICAgICAgaWYgKHN1Yk5vcm1hbEZhY3RvciA8IDApIHsKKyAgICAgICAgICAgIC8vIG5vdCBzdWItbm9ybWFsIHZhbHVlcworICAgICAgICAgICAgc3ViTm9ybWFsRmFjdG9yID0gMDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZhY3RvciA9IGZhY3RvciAtIHN1Yk5vcm1hbEZhY3RvcjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZmFjdG9yID4gRG91YmxlLk1BWF9FWFBPTkVOVCkgeworICAgICAgICAgICAgcmV0dXJuIChkID4gMCA/IERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSA6IERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSk7CisgICAgICAgIH0KKworICAgICAgICBsb25nIHJlc3VsdDsKKyAgICAgICAgLy8gaWYgcmVzdWx0IGlzIGEgc3ViLW5vcm1hbAorICAgICAgICBpZiAoZmFjdG9yIDw9IC1Eb3VibGUuRVhQT05FTlRfQklBUykgeworICAgICAgICAgICAgLy8gdGhlIG51bWJlciBvZiBkaWdpdHMgdGhhdCBzaGlmdHMKKyAgICAgICAgICAgIGxvbmcgZGlnaXRzID0gZmFjdG9yICsgRG91YmxlLkVYUE9ORU5UX0JJQVMgKyBzdWJOb3JtYWxGYWN0b3I7CisgICAgICAgICAgICBpZiAoTWF0aC5hYnMoZCkgPCBEb3VibGUuTUlOX05PUk1BTCkgeworICAgICAgICAgICAgICAgIC8vIG9yaWdpbiBkIGlzIGFscmVhZHkgc3ViLW5vcm1hbAorICAgICAgICAgICAgICAgIHJlc3VsdCA9IHNoaWZ0TG9uZ0JpdHMoYml0cyAmIERvdWJsZS5NQU5USVNTQV9NQVNLLCBkaWdpdHMpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBvcmlnaW4gZCBpcyBub3Qgc3ViLW5vcm1hbCwgY2hhbmdlIG1hbnRpc3NhIHRvIHN1Yi1ub3JtYWwKKyAgICAgICAgICAgICAgICByZXN1bHQgPSBzaGlmdExvbmdCaXRzKGJpdHMgJiBEb3VibGUuTUFOVElTU0FfTUFTSyB8IDB4MDAxMDAwMDAwMDAwMDAwMEwsIGRpZ2l0cyAtIDEpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKE1hdGguYWJzKGQpID49IERvdWJsZS5NSU5fTk9STUFMKSB7CisgICAgICAgICAgICAgICAgLy8gY29tbW9uIHNpdHVhdGlvbgorICAgICAgICAgICAgICAgIHJlc3VsdCA9ICgoZmFjdG9yICsgRG91YmxlLkVYUE9ORU5UX0JJQVMpIDw8IERvdWJsZS5NQU5USVNTQV9CSVRTKQorICAgICAgICAgICAgICAgICAgICAgICAgfCAoYml0cyAmIERvdWJsZS5NQU5USVNTQV9NQVNLKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gb3JpZ2luIGQgaXMgc3ViLW5vcm1hbCwgY2hhbmdlIG1hbnRpc3NhIHRvIG5vcm1hbCBzdHlsZQorICAgICAgICAgICAgICAgIHJlc3VsdCA9ICgoZmFjdG9yICsgRG91YmxlLkVYUE9ORU5UX0JJQVMpIDw8IERvdWJsZS5NQU5USVNTQV9CSVRTKQorICAgICAgICAgICAgICAgICAgICAgICAgfCAoKGJpdHMgPDwgKHN1Yk5vcm1hbEZhY3RvciArIDEpKSAmIERvdWJsZS5NQU5USVNTQV9NQVNLKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gRG91YmxlLmxvbmdCaXRzVG9Eb3VibGUocmVzdWx0IHwgc2lnbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB7QGNvZGUgZH0gKiAyXntAY29kZSBzY2FsZUZhY3Rvcn0uIFRoZSByZXN1bHQgbWF5IGJlIHJvdW5kZWQuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmxvYXQgc2NhbGIoZmxvYXQgZCwgaW50IHNjYWxlRmFjdG9yKSB7CisgICAgICAgIGlmIChGbG9hdC5pc05hTihkKSB8fCBGbG9hdC5pc0luZmluaXRlKGQpIHx8IGQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGQ7CisgICAgICAgIH0KKyAgICAgICAgaW50IGJpdHMgPSBGbG9hdC5mbG9hdFRvSW50Qml0cyhkKTsKKyAgICAgICAgaW50IHNpZ24gPSBiaXRzICYgRmxvYXQuU0lHTl9NQVNLOworICAgICAgICBpbnQgZmFjdG9yID0gKChiaXRzICYgRmxvYXQuRVhQT05FTlRfTUFTSykgPj4gRmxvYXQuTUFOVElTU0FfQklUUykKKyAgICAgICAgICAgICAgICAtIEZsb2F0LkVYUE9ORU5UX0JJQVMgKyBzY2FsZUZhY3RvcjsKKyAgICAgICAgLy8gY2FsY3VsYXRlcyB0aGUgZmFjdG9yIG9mIHN1Yi1ub3JtYWwgdmFsdWVzCisgICAgICAgIGludCBzdWJOb3JtYWxGYWN0b3IgPSBJbnRlZ2VyLm51bWJlck9mTGVhZGluZ1plcm9zKGJpdHMgJiB+RmxvYXQuU0lHTl9NQVNLKQorICAgICAgICAgICAgICAgIC0gRmxvYXQuTk9OX01BTlRJU1NBX0JJVFM7CisgICAgICAgIGlmIChzdWJOb3JtYWxGYWN0b3IgPCAwKSB7CisgICAgICAgICAgICAvLyBub3Qgc3ViLW5vcm1hbCB2YWx1ZXMKKyAgICAgICAgICAgIHN1Yk5vcm1hbEZhY3RvciA9IDA7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmYWN0b3IgPSBmYWN0b3IgLSBzdWJOb3JtYWxGYWN0b3I7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZhY3RvciA+IEZsb2F0Lk1BWF9FWFBPTkVOVCkgeworICAgICAgICAgICAgcmV0dXJuIChkID4gMCA/IEZsb2F0LlBPU0lUSVZFX0lORklOSVRZIDogRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFkpOworICAgICAgICB9CisKKyAgICAgICAgaW50IHJlc3VsdDsKKyAgICAgICAgLy8gaWYgcmVzdWx0IGlzIGEgc3ViLW5vcm1hbAorICAgICAgICBpZiAoZmFjdG9yIDw9IC1GbG9hdC5FWFBPTkVOVF9CSUFTKSB7CisgICAgICAgICAgICAvLyB0aGUgbnVtYmVyIG9mIGRpZ2l0cyB0aGF0IHNoaWZ0cworICAgICAgICAgICAgaW50IGRpZ2l0cyA9IGZhY3RvciArIEZsb2F0LkVYUE9ORU5UX0JJQVMgKyBzdWJOb3JtYWxGYWN0b3I7CisgICAgICAgICAgICBpZiAoTWF0aC5hYnMoZCkgPCBGbG9hdC5NSU5fTk9STUFMKSB7CisgICAgICAgICAgICAgICAgLy8gb3JpZ2luIGQgaXMgYWxyZWFkeSBzdWItbm9ybWFsCisgICAgICAgICAgICAgICAgcmVzdWx0ID0gc2hpZnRJbnRCaXRzKGJpdHMgJiBGbG9hdC5NQU5USVNTQV9NQVNLLCBkaWdpdHMpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBvcmlnaW4gZCBpcyBub3Qgc3ViLW5vcm1hbCwgY2hhbmdlIG1hbnRpc3NhIHRvIHN1Yi1ub3JtYWwKKyAgICAgICAgICAgICAgICByZXN1bHQgPSBzaGlmdEludEJpdHMoYml0cyAmIEZsb2F0Lk1BTlRJU1NBX01BU0sgfCAweDAwODAwMDAwLCBkaWdpdHMgLSAxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChNYXRoLmFicyhkKSA+PSBGbG9hdC5NSU5fTk9STUFMKSB7CisgICAgICAgICAgICAgICAgLy8gY29tbW9uIHNpdHVhdGlvbgorICAgICAgICAgICAgICAgIHJlc3VsdCA9ICgoZmFjdG9yICsgRmxvYXQuRVhQT05FTlRfQklBUykgPDwgRmxvYXQuTUFOVElTU0FfQklUUykKKyAgICAgICAgICAgICAgICAgICAgICAgIHwgKGJpdHMgJiBGbG9hdC5NQU5USVNTQV9NQVNLKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gb3JpZ2luIGQgaXMgc3ViLW5vcm1hbCwgY2hhbmdlIG1hbnRpc3NhIHRvIG5vcm1hbCBzdHlsZQorICAgICAgICAgICAgICAgIHJlc3VsdCA9ICgoZmFjdG9yICsgRmxvYXQuRVhQT05FTlRfQklBUykgPDwgRmxvYXQuTUFOVElTU0FfQklUUykKKyAgICAgICAgICAgICAgICAgICAgICAgIHwgKChiaXRzIDw8IChzdWJOb3JtYWxGYWN0b3IgKyAxKSkgJiBGbG9hdC5NQU5USVNTQV9NQVNLKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gRmxvYXQuaW50Qml0c1RvRmxvYXQocmVzdWx0IHwgc2lnbik7CisgICAgfQorCisgICAgLy8gU2hpZnRzIGludGVnZXIgYml0cyBhcyBmbG9hdCwgaWYgdGhlIGRpZ2l0cyBpcyBwb3NpdGl2ZSwgbGVmdC1zaGlmdDsgaWYKKyAgICAvLyBub3QsIHNoaWZ0IHRvIHJpZ2h0IGFuZCBjYWxjdWxhdGUgaXRzIGNhcnJ5LgorICAgIHByaXZhdGUgc3RhdGljIGludCBzaGlmdEludEJpdHMoaW50IGJpdHMsIGludCBkaWdpdHMpIHsKKyAgICAgICAgaWYgKGRpZ2l0cyA+IDApIHsKKyAgICAgICAgICAgIHJldHVybiBiaXRzIDw8IGRpZ2l0czsKKyAgICAgICAgfQorICAgICAgICAvLyBjaGFuZ2UgaXQgdG8gcG9zaXRpdmUKKyAgICAgICAgaW50IGFic0RpZ2l0cyA9IC1kaWdpdHM7CisgICAgICAgIGlmICghKEludGVnZXIubnVtYmVyT2ZMZWFkaW5nWmVyb3MoYml0cyAmIH5GbG9hdC5TSUdOX01BU0spIDw9ICgzMiAtIGFic0RpZ2l0cykpKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICBpbnQgcmV0ID0gYml0cyA+PiBhYnNEaWdpdHM7CisgICAgICAgIGJvb2xlYW4gaGFsZkJpdCA9ICgoYml0cyA+PiAoYWJzRGlnaXRzIC0gMSkpICYgMHgxKSA9PSAxOworICAgICAgICBpZiAoaGFsZkJpdCkgeworICAgICAgICAgICAgaWYgKEludGVnZXIubnVtYmVyT2ZUcmFpbGluZ1plcm9zKGJpdHMpIDwgKGFic0RpZ2l0cyAtIDEpKSB7CisgICAgICAgICAgICAgICAgcmV0ID0gcmV0ICsgMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChJbnRlZ2VyLm51bWJlck9mVHJhaWxpbmdaZXJvcyhiaXRzKSA9PSAoYWJzRGlnaXRzIC0gMSkpIHsKKyAgICAgICAgICAgICAgICBpZiAoKHJldCAmIDB4MSkgPT0gMSkgeworICAgICAgICAgICAgICAgICAgICByZXQgPSByZXQgKyAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmV0OworICAgIH0KKworICAgIC8vIFNoaWZ0cyBsb25nIGJpdHMgYXMgZG91YmxlLCBpZiB0aGUgZGlnaXRzIGlzIHBvc2l0aXZlLCBsZWZ0LXNoaWZ0OyBpZgorICAgIC8vIG5vdCwgc2hpZnQgdG8gcmlnaHQgYW5kIGNhbGN1bGF0ZSBpdHMgY2FycnkuCisgICAgcHJpdmF0ZSBzdGF0aWMgbG9uZyBzaGlmdExvbmdCaXRzKGxvbmcgYml0cywgbG9uZyBkaWdpdHMpIHsKKyAgICAgICAgaWYgKGRpZ2l0cyA+IDApIHsKKyAgICAgICAgICAgIHJldHVybiBiaXRzIDw8IGRpZ2l0czsKKyAgICAgICAgfQorICAgICAgICAvLyBjaGFuZ2UgaXQgdG8gcG9zaXRpdmUKKyAgICAgICAgbG9uZyBhYnNEaWdpdHMgPSAtZGlnaXRzOworICAgICAgICBpZiAoIShMb25nLm51bWJlck9mTGVhZGluZ1plcm9zKGJpdHMgJiB+RG91YmxlLlNJR05fTUFTSykgPD0gKDY0IC0gYWJzRGlnaXRzKSkpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGxvbmcgcmV0ID0gYml0cyA+PiBhYnNEaWdpdHM7CisgICAgICAgIGJvb2xlYW4gaGFsZkJpdCA9ICgoYml0cyA+PiAoYWJzRGlnaXRzIC0gMSkpICYgMHgxKSA9PSAxOworICAgICAgICBpZiAoaGFsZkJpdCkgeworICAgICAgICAgICAgLy8gc29tZSBiaXRzIHdpbGwgcmVtYWluIGFmdGVyIHNoaWZ0aW5nLCBjYWxjdWxhdGVzIGl0cyBjYXJyeQorICAgICAgICAgICAgLy8gc3Vibm9ybWFsCisgICAgICAgICAgICBpZiAoTG9uZy5udW1iZXJPZlRyYWlsaW5nWmVyb3MoYml0cykgPCAoYWJzRGlnaXRzIC0gMSkpIHsKKyAgICAgICAgICAgICAgICByZXQgPSByZXQgKyAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKExvbmcubnVtYmVyT2ZUcmFpbGluZ1plcm9zKGJpdHMpID09IChhYnNEaWdpdHMgLSAxKSkgeworICAgICAgICAgICAgICAgIGlmICgocmV0ICYgMHgxKSA9PSAxKSB7CisgICAgICAgICAgICAgICAgICAgIHJldCA9IHJldCArIDE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9OZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9OZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmNWVjMDMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL05lZ2F0aXZlQXJyYXlTaXplRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyb3duIHdoZW4gYW4gYXR0ZW1wdCBpcyBtYWRlIHRvIGNyZWF0ZSBhbiBhcnJheSB3aXRoIGEgc2l6ZSBvZiBsZXNzIHRoYW4KKyAqIHplcm8uCisgKi8KK3B1YmxpYyBjbGFzcyBOZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTg5NjAxMTgwNTg1OTY5OTE4NjFMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb259IHRoYXQgaW5jbHVkZXMgdGhlCisgICAgICogY3VycmVudCBzdGFjayB0cmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQKKyAgICAgKiBzdGFjayB0cmFjZSBhbmQgdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBOZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL05vQ2xhc3NEZWZGb3VuZEVycm9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL05vQ2xhc3NEZWZGb3VuZEVycm9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjc5NjcxMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvTm9DbGFzc0RlZkZvdW5kRXJyb3IuamF2YQpAQCAtMCwwICsxLDQ1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gd2hlbiB0aGUgVk0gaXMgdW5hYmxlIHRvIGxvY2F0ZSBhIGNsYXNzIHdoaWNoIGl0IGhhcyBiZWVuCisgKiBhc2tlZCB0byBsb2FkLgorICovCitwdWJsaWMgY2xhc3MgTm9DbGFzc0RlZkZvdW5kRXJyb3IgZXh0ZW5kcyBMaW5rYWdlRXJyb3IgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gOTA5NTg1OTg2MzI4NzAxMjQ1OEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBOb0NsYXNzRGVmRm91bmRFcnJvcn0gdGhhdCBpbmNsdWRlcyB0aGUgY3VycmVudAorICAgICAqIHN0YWNrIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBOb0NsYXNzRGVmRm91bmRFcnJvcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBOb0NsYXNzRGVmRm91bmRFcnJvcn0gd2l0aCB0aGUgY3VycmVudCBzdGFjaworICAgICAqIHRyYWNlIGFuZCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9DbGFzc0RlZkZvdW5kRXJyb3IoU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Ob1N1Y2hGaWVsZEVycm9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL05vU3VjaEZpZWxkRXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYzJjNGFiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Ob1N1Y2hGaWVsZEVycm9yLmphdmEKQEAgLTAsMCArMSw0NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyb3duIHdoZW4gdGhlIFZNIG5vdGljZXMgdGhhdCBhIHByb2dyYW0gdHJpZXMgdG8gcmVmZXJlbmNlLAorICogb24gYSBjbGFzcyBvciBvYmplY3QsIGEgZmllbGQgdGhhdCBkb2VzIG5vdCBleGlzdC4KKyAqIDxwPgorICogTm90ZSB0aGF0IHRoaXMgY2FuIG9ubHkgb2NjdXIgd2hlbiBpbmNvbnNpc3RlbnQgY2xhc3MgZmlsZXMgYXJlIGJlaW5nIGxvYWRlZC4KKyAqLworcHVibGljIGNsYXNzIE5vU3VjaEZpZWxkRXJyb3IgZXh0ZW5kcyBJbmNvbXBhdGlibGVDbGFzc0NoYW5nZUVycm9yIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0zNDU2NDMwMTk1ODg2MTI5MDM1TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIE5vU3VjaEZpZWxkRXJyb3J9IHRoYXQgaW5jbHVkZXMgdGhlIGN1cnJlbnQgc3RhY2sKKyAgICAgKiB0cmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9TdWNoRmllbGRFcnJvcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBOb1N1Y2hGaWVsZEVycm9yfSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlCisgICAgICogYW5kIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBOb1N1Y2hGaWVsZEVycm9yKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZWE2ZWNiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Ob1N1Y2hGaWVsZEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIFRocm93biB3aGVuIHRoZSBWTSBub3RpY2VzIHRoYXQgYSBwcm9ncmFtIHRyaWVzIHRvIHJlZmVyZW5jZSwKKyAqIG9uIGEgY2xhc3Mgb3Igb2JqZWN0LCBhIGZpZWxkIHRoYXQgZG9lcyBub3QgZXhpc3QuCisgKi8KK3B1YmxpYyBjbGFzcyBOb1N1Y2hGaWVsZEV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjE0MzcxNDgwNTI3OTkzODI2MEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBOb1N1Y2hGaWVsZEV4Y2VwdGlvbn0gdGhhdCBpbmNsdWRlcyB0aGUgY3VycmVudAorICAgICAqIHN0YWNrIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBOb1N1Y2hGaWVsZEV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBOb1N1Y2hGaWVsZEV4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudCBzdGFjaworICAgICAqIHRyYWNlIGFuZCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIE5vU3VjaEZpZWxkRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXJyb3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42N2Q1NTk4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFcnJvci5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIFRocm93biB3aGVuIHRoZSBWTSBub3RpY2VzIHRoYXQgYSBwcm9ncmFtIHRyaWVzIHRvIHJlZmVyZW5jZSwKKyAqIG9uIGEgY2xhc3Mgb3Igb2JqZWN0LCBhIG1ldGhvZCB0aGF0IGRvZXMgbm90IGV4aXN0LgorICovCitwdWJsaWMgY2xhc3MgTm9TdWNoTWV0aG9kRXJyb3IgZXh0ZW5kcyBJbmNvbXBhdGlibGVDbGFzc0NoYW5nZUVycm9yIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0zNzY1NTIxNDQyMzcyODMxMzM1TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIE5vU3VjaE1ldGhvZEVycm9yfSB0aGF0IGluY2x1ZGVzIHRoZSBjdXJyZW50CisgICAgICogc3RhY2sgdHJhY2UuCisgICAgICovCisgICAgcHVibGljIE5vU3VjaE1ldGhvZEVycm9yKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIE5vU3VjaE1ldGhvZEVycm9yfSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlCisgICAgICogYW5kIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9TdWNoTWV0aG9kRXJyb3IoU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL05vU3VjaE1ldGhvZEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43Y2FlNDliCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQ2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gd2hlbiB0aGUgVk0gbm90aWNlcyB0aGF0IGEgcHJvZ3JhbSB0cmllcyB0byByZWZlcmVuY2UsCisgKiBvbiBhIGNsYXNzIG9yIG9iamVjdCwgYSBtZXRob2QgdGhhdCBkb2VzIG5vdCBleGlzdC4KKyAqLworcHVibGljIGNsYXNzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1MDM0Mzg4NDQ2MzYyNjAwOTIzTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbn0gdGhhdCBpbmNsdWRlcyB0aGUgY3VycmVudAorICAgICAqIHN0YWNrIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBOb1N1Y2hNZXRob2RFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTm9TdWNoTWV0aG9kRXhjZXB0aW9ufSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrCisgICAgICogdHJhY2UgYW5kIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9TdWNoTWV0aG9kRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9OdWxsUG9pbnRlckV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9OdWxsUG9pbnRlckV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY5ZjEwMzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL051bGxQb2ludGVyRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyb3duIHdoZW4gYSBwcm9ncmFtIHRyaWVzIHRvIGFjY2VzcyBhIGZpZWxkIG9yIG1ldGhvZCBvZiBhbiBvYmplY3Qgb3IgYW4KKyAqIGVsZW1lbnQgb2YgYW4gYXJyYXkgd2hlbiB0aGVyZSBpcyBubyBpbnN0YW5jZSBvciBhcnJheSB0byB1c2UsIHRoYXQgaXMgaWYgdGhlCisgKiBvYmplY3Qgb3IgYXJyYXkgcG9pbnRzIHRvIHtAY29kZSBudWxsfS4gSXQgYWxzbyBvY2N1cnMgaW4gc29tZSBvdGhlciwgbGVzcworICogb2J2aW91cyBjaXJjdW1zdGFuY2VzLCBsaWtlIGEge0Bjb2RlIHRocm93IGV9IHN0YXRlbWVudCB3aGVyZSB0aGUge0BsaW5rCisgKiBUaHJvd2FibGV9IHJlZmVyZW5jZSBpcyB7QGNvZGUgbnVsbH0uCisgKi8KK3B1YmxpYyBjbGFzcyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTE2MjcxMDE4MzM4OTAyODc5Mkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBOdWxsUG9pbnRlckV4Y2VwdGlvbn0gdGhhdCBpbmNsdWRlcyB0aGUgY3VycmVudAorICAgICAqIHN0YWNrIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBOdWxsUG9pbnRlckV4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudCBzdGFjaworICAgICAqIHRyYWNlIGFuZCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIE51bGxQb2ludGVyRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9OdW1iZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvTnVtYmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTdhN2I2MAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvTnVtYmVyLmphdmEKQEAgLTAsMCArMSw4NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKworLyoqCisgKiBUaGUgYWJzdHJhY3Qgc3VwZXJjbGFzcyBvZiB0aGUgY2xhc3NlcyB3aGljaCByZXByZXNlbnQgbnVtZXJpYyBiYXNlIHR5cGVzCisgKiAodGhhdCBpcyB7QGxpbmsgQnl0ZX0sIHtAbGluayBTaG9ydH0sIHtAbGluayBJbnRlZ2VyfSwge0BsaW5rIExvbmd9LAorICoge0BsaW5rIEZsb2F0fSwgYW5kIHtAbGluayBEb3VibGV9LgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTnVtYmVyIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTg3NDI0NDg4MjQ2NTIwNzg5NjVMOworCisgICAgLyoqCisgICAgICogRW1wdHkgZGVmYXVsdCBjb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgTnVtYmVyKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBvYmplY3QncyB2YWx1ZSBhcyBhIGJ5dGUuIE1pZ2h0IGludm9sdmUgcm91bmRpbmcgYW5kL29yCisgICAgICogdHJ1bmNhdGluZyB0aGUgdmFsdWUsIHNvIGl0IGZpdHMgaW50byBhIGJ5dGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmltaXRpdmUgYnl0ZSB2YWx1ZSBvZiB0aGlzIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZSBieXRlVmFsdWUoKSB7CisgICAgICAgIHJldHVybiAoYnl0ZSkgaW50VmFsdWUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgb2JqZWN0J3MgdmFsdWUgYXMgYSBkb3VibGUuIE1pZ2h0IGludm9sdmUgcm91bmRpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmltaXRpdmUgZG91YmxlIHZhbHVlIG9mIHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBkb3VibGUgZG91YmxlVmFsdWUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBvYmplY3QncyB2YWx1ZSBhcyBhIGZsb2F0LiBNaWdodCBpbnZvbHZlIHJvdW5kaW5nLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJpbWl0aXZlIGZsb2F0IHZhbHVlIG9mIHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBmbG9hdCBmbG9hdFZhbHVlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgb2JqZWN0J3MgdmFsdWUgYXMgYW4gaW50LiBNaWdodCBpbnZvbHZlIHJvdW5kaW5nIGFuZC9vcgorICAgICAqIHRydW5jYXRpbmcgdGhlIHZhbHVlLCBzbyBpdCBmaXRzIGludG8gYW4gaW50LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJpbWl0aXZlIGludCB2YWx1ZSBvZiB0aGlzIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGludFZhbHVlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgb2JqZWN0J3MgdmFsdWUgYXMgYSBsb25nLiBNaWdodCBpbnZvbHZlIHJvdW5kaW5nIGFuZC9vcgorICAgICAqIHRydW5jYXRpbmcgdGhlIHZhbHVlLCBzbyBpdCBmaXRzIGludG8gYSBsb25nLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJpbWl0aXZlIGxvbmcgdmFsdWUgb2YgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGxvbmcgbG9uZ1ZhbHVlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgb2JqZWN0J3MgdmFsdWUgYXMgYSBzaG9ydC4gTWlnaHQgaW52b2x2ZSByb3VuZGluZyBhbmQvb3IKKyAgICAgKiB0cnVuY2F0aW5nIHRoZSB2YWx1ZSwgc28gaXQgZml0cyBpbnRvIGEgc2hvcnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmltaXRpdmUgc2hvcnQgdmFsdWUgb2YgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIHNob3J0IHNob3J0VmFsdWUoKSB7CisgICAgICAgIHJldHVybiAoc2hvcnQpIGludFZhbHVlKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9OdW1iZXJGb3JtYXRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvTnVtYmVyRm9ybWF0RXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODYwODE4MAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvTnVtYmVyRm9ybWF0RXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyb3duIHdoZW4gYW4gaW52YWxpZCB2YWx1ZSBpcyBwYXNzZWQgdG8gYSBzdHJpbmctdG8tbnVtYmVyIGNvbnZlcnNpb24KKyAqIG1ldGhvZC4KKyAqLworcHVibGljIGNsYXNzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleHRlbmRzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjg0ODkzODgwNjM2ODk5ODg5NEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBOdW1iZXJGb3JtYXRFeGNlcHRpb259IHRoYXQgaW5jbHVkZXMgdGhlIGN1cnJlbnQKKyAgICAgKiBzdGFjayB0cmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIE51bWJlckZvcm1hdEV4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudCBzdGFjaworICAgICAqIHRyYWNlIGFuZCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIE51bWJlckZvcm1hdEV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL09iamVjdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9PYmplY3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZjRiNDkwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9PYmplY3QuamF2YQpAQCAtMCwwICsxLDQ0MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhlIHJvb3QgY2xhc3Mgb2YgdGhlIEphdmEgY2xhc3MgaGllcmFyY2h5LiBBbGwgbm9uLXByaW1pdGl2ZSB0eXBlcworICogKGluY2x1ZGluZyBhcnJheXMpIGluaGVyaXQgZWl0aGVyIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkgZnJvbSB0aGlzIGNsYXNzLgorICoKKyAqIDxhIG5hbWU9IndyaXRpbmdfZXF1YWxzIj48aDQ+V3JpdGluZyBhIGNvcnJlY3Qge0Bjb2RlIGVxdWFsc30gbWV0aG9kPC9oND48L2E+CisgKiA8cD5Gb2xsb3cgdGhpcyBzdHlsZSB0byB3cml0ZSBhIGNhbm9uaWNhbCB7QGNvZGUgZXF1YWxzfSBtZXRob2Q6CisgKiA8cHJlPgorICogICAvLyBVc2UgQE92ZXJyaWRlIHRvIGF2b2lkIGFjY2lkZW50YWwgb3ZlcmxvYWRpbmcuCisgKiAgICYjeDAwNDA7T3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgKiAgICAgLy8gUmV0dXJuIHRydWUgaWYgdGhlIG9iamVjdHMgYXJlIGlkZW50aWNhbC4KKyAqICAgICAvLyAoVGhpcyBpcyBqdXN0IGFuIG9wdGltaXphdGlvbiwgbm90IHJlcXVpcmVkIGZvciBjb3JyZWN0bmVzcy4pCisgKiAgICAgaWYgKHRoaXMgPT0gbykgeworICogICAgICAgcmV0dXJuIHRydWU7CisgKiAgICAgfQorICoKKyAqICAgICAvLyBSZXR1cm4gZmFsc2UgaWYgdGhlIG90aGVyIG9iamVjdCBoYXMgdGhlIHdyb25nIHR5cGUuCisgKiAgICAgLy8gVGhpcyB0eXBlIG1heSBiZSBhbiBpbnRlcmZhY2UgZGVwZW5kaW5nIG9uIHRoZSBpbnRlcmZhY2UncyBzcGVjaWZpY2F0aW9uLgorICogICAgIGlmICghKG8gaW5zdGFuY2VvZiBNeVR5cGUpKSB7CisgKiAgICAgICByZXR1cm4gZmFsc2U7CisgKiAgICAgfQorICoKKyAqICAgICAvLyBDYXN0IHRvIHRoZSBhcHByb3ByaWF0ZSB0eXBlLgorICogICAgIC8vIFRoaXMgd2lsbCBzdWNjZWVkIGJlY2F1c2Ugb2YgdGhlIGluc3RhbmNlb2YsIGFuZCBsZXRzIHVzIGFjY2VzcyBwcml2YXRlIGZpZWxkcy4KKyAqICAgICBNeVR5cGUgbGhzID0gKE15VHlwZSkgbzsKKyAqCisgKiAgICAgLy8gQ2hlY2sgZWFjaCBmaWVsZC4gUHJpbWl0aXZlIGZpZWxkcywgcmVmZXJlbmNlIGZpZWxkcywgYW5kIG51bGxhYmxlIHJlZmVyZW5jZQorICogICAgIC8vIGZpZWxkcyBhcmUgYWxsIHRyZWF0ZWQgZGlmZmVyZW50bHkuCisgKiAgICAgcmV0dXJuIHByaW1pdGl2ZUZpZWxkID09IGxocy5wcmltaXRpdmVGaWVsZCAmYW1wOyZhbXA7CisgKiAgICAgICAgICAgICByZWZlcmVuY2VGaWVsZC5lcXVhbHMobGhzLnJlZmVyZW5jZUZpZWxkKSAmYW1wOyZhbXA7CisgKiAgICAgICAgICAgICAobnVsbGFibGVGaWVsZCA9PSBudWxsID8gbGhzLm51bGxhYmxlRmllbGQgPT0gbnVsbAorICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGxhYmxlRmllbGQuZXF1YWxzKGxocy5udWxsYWJsZUZpZWxkKSk7CisgKiAgIH0KKyAqIDwvcHJlPgorICogPHA+SWYgeW91IG92ZXJyaWRlIHtAY29kZSBlcXVhbHN9LCB5b3Ugc2hvdWxkIGFsc28gb3ZlcnJpZGUge0Bjb2RlIGhhc2hDb2RlfTogZXF1YWwKKyAqIGluc3RhbmNlcyBtdXN0IGhhdmUgZXF1YWwgaGFzaCBjb2Rlcy4KKyAqCisgKiA8cD5TZWUgPGk+RWZmZWN0aXZlIEphdmE8L2k+IGl0ZW0gOCBmb3IgbXVjaCBtb3JlIGRldGFpbCBhbmQgY2xhcmlmaWNhdGlvbi4KKyAqCisgKiA8YSBuYW1lPSJ3cml0aW5nX2hhc2hDb2RlIj48aDQ+V3JpdGluZyBhIGNvcnJlY3Qge0Bjb2RlIGhhc2hDb2RlfSBtZXRob2Q8L2g0PjwvYT4KKyAqIDxwPkZvbGxvdyB0aGlzIHN0eWxlIHRvIHdyaXRlIGEgY2Fub25pY2FsIHtAY29kZSBoYXNoQ29kZX0gbWV0aG9kOgorICogPHByZT4KKyAqICAgJiN4MDA0MDtPdmVycmlkZSBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICogICAgIC8vIFN0YXJ0IHdpdGggYSBub24temVybyBjb25zdGFudC4KKyAqICAgICBpbnQgcmVzdWx0ID0gMTc7CisgKgorICogICAgIC8vIEluY2x1ZGUgYSBoYXNoIGZvciBlYWNoIGZpZWxkLgorICogICAgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgKGJvb2xlYW5GaWVsZCA/IDEgOiAwKTsKKyAqCisgKiAgICAgcmVzdWx0ID0gMzEgKiByZXN1bHQgKyBieXRlRmllbGQ7CisgKiAgICAgcmVzdWx0ID0gMzEgKiByZXN1bHQgKyBjaGFyRmllbGQ7CisgKiAgICAgcmVzdWx0ID0gMzEgKiByZXN1bHQgKyBzaG9ydEZpZWxkOworICogICAgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgaW50RmllbGQ7CisgKgorICogICAgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgKGludCkgKGxvbmdGaWVsZCBeIChsb25nRmllbGQgPj4+IDMyKSk7CisgKgorICogICAgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgRmxvYXQuZmxvYXRUb0ludEJpdHMoZmxvYXRGaWVsZCk7CisgKgorICogICAgIGxvbmcgZG91YmxlRmllbGRCaXRzID0gRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZG91YmxlRmllbGQpOworICogICAgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgKGludCkgKGRvdWJsZUZpZWxkQml0cyBeIChkb3VibGVGaWVsZEJpdHMgPj4+IDMyKSk7CisgKgorICogICAgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgQXJyYXlzLmhhc2hDb2RlKGFycmF5RmllbGQpOworICoKKyAqICAgICByZXN1bHQgPSAzMSAqIHJlc3VsdCArIHJlZmVyZW5jZUZpZWxkLmhhc2hDb2RlKCk7CisgKiAgICAgcmVzdWx0ID0gMzEgKiByZXN1bHQgKworICogICAgICAgICAobnVsbGFibGVSZWZlcmVuY2VGaWVsZCA9PSBudWxsID8gMAorICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbGFibGVSZWZlcmVuY2VGaWVsZC5oYXNoQ29kZSgpKTsKKyAqCisgKiAgICAgcmV0dXJuIHJlc3VsdDsKKyAqICAgfQorICogPC9wcmU+CisgKgorICogPHA+SWYgeW91IGRvbid0IGludGVuZCB5b3VyIHR5cGUgdG8gYmUgdXNlZCBhcyBhIGhhc2gga2V5LCBkb24ndCBzaW1wbHkgcmVseSBvbiB0aGUgZGVmYXVsdAorICoge0Bjb2RlIGhhc2hDb2RlfSBpbXBsZW1lbnRhdGlvbiwgYmVjYXVzZSB0aGF0IHNpbGVudGx5IGFuZCBub24tb2J2aW91c2x5IGJyZWFrcyBhbnkgZnV0dXJlCisgKiBjb2RlIHRoYXQgZG9lcyB1c2UgeW91ciB0eXBlIGFzIGEgaGFzaCBrZXkuIFlvdSBzaG91bGQgdGhyb3cgaW5zdGVhZDoKKyAqIDxwcmU+CisgKiAgICYjeDAwNDA7T3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAqICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAqICAgfQorICogPC9wcmU+CisgKgorICogPHA+U2VlIDxpPkVmZmVjdGl2ZSBKYXZhPC9pPiBpdGVtIDkgZm9yIG11Y2ggbW9yZSBkZXRhaWwgYW5kIGNsYXJpZmljYXRpb24uCisgKgorICogPGEgbmFtZT0id3JpdGluZ190b1N0cmluZyI+PGg0PldyaXRpbmcgYSB1c2VmdWwge0Bjb2RlIHRvU3RyaW5nfSBtZXRob2Q8L2g0PjwvYT4KKyAqIDxwPkZvciBkZWJ1Z2dpbmcgY29udmVuaWVuY2UsIGl0J3MgY29tbW9uIHRvIG92ZXJyaWRlIHtAY29kZSB0b1N0cmluZ30gaW4gdGhpcyBzdHlsZToKKyAqIDxwcmU+CisgKiAgICYjeDAwNDA7T3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAqICAgICByZXR1cm4gZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiWyIgKworICogICAgICAgICAicHJpbWl0aXZlRmllbGQ9IiArIHByaW1pdGl2ZUZpZWxkICsgIiwgIiArCisgKiAgICAgICAgICJyZWZlcmVuY2VGaWVsZD0iICsgcmVmZXJlbmNlRmllbGQgKyAiLCAiICsKKyAqICAgICAgICAgImFycmF5RmllbGQ9IiArIEFycmF5cy50b1N0cmluZyhhcnJheUZpZWxkKSArICJdIjsKKyAqICAgfQorICogPC9wcmU+CisgKiA8cD5UaGUgc2V0IG9mIGZpZWxkcyB0byBpbmNsdWRlIGlzIGdlbmVyYWxseSB0aGUgc2FtZSBhcyB0aG9zZSB0aGF0IHdvdWxkIGJlIHRlc3RlZAorICogaW4geW91ciB7QGNvZGUgZXF1YWxzfSBpbXBsZW1lbnRhdGlvbi4KKyAqIDxwPlNlZSA8aT5FZmZlY3RpdmUgSmF2YTwvaT4gaXRlbSAxMCBmb3IgbXVjaCBtb3JlIGRldGFpbCBhbmQgY2xhcmlmaWNhdGlvbi4KKyAqLworcHVibGljIGNsYXNzIE9iamVjdCB7CisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgT2JqZWN0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW5kIHJldHVybnMgYSBjb3B5IG9mIHRoaXMge0Bjb2RlIE9iamVjdH0uIFRoZSBkZWZhdWx0CisgICAgICogaW1wbGVtZW50YXRpb24gcmV0dXJucyBhIHNvLWNhbGxlZCAic2hhbGxvdyIgY29weTogSXQgY3JlYXRlcyBhIG5ldworICAgICAqIGluc3RhbmNlIG9mIHRoZSBzYW1lIGNsYXNzIGFuZCB0aGVuIGNvcGllcyB0aGUgZmllbGQgdmFsdWVzIChpbmNsdWRpbmcKKyAgICAgKiBvYmplY3QgcmVmZXJlbmNlcykgZnJvbSB0aGlzIGluc3RhbmNlIHRvIHRoZSBuZXcgaW5zdGFuY2UuIEEgImRlZXAiIGNvcHksCisgICAgICogaW4gY29udHJhc3QsIHdvdWxkIGFsc28gcmVjdXJzaXZlbHkgY2xvbmUgbmVzdGVkIG9iamVjdHMuIEEgc3ViY2xhc3MgdGhhdAorICAgICAqIG5lZWRzIHRvIGltcGxlbWVudCB0aGlzIGtpbmQgb2YgY2xvbmluZyBzaG91bGQgY2FsbCB7QGNvZGUgc3VwZXIuY2xvbmUoKX0KKyAgICAgKiB0byBjcmVhdGUgdGhlIG5ldyBpbnN0YW5jZSBhbmQgdGhlbiBjcmVhdGUgZGVlcCBjb3BpZXMgb2YgdGhlIG5lc3RlZCwKKyAgICAgKiBtdXRhYmxlIG9iamVjdHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGlzIG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBvYmplY3QncyBjbGFzcyBkb2VzIG5vdCBpbXBsZW1lbnQgdGhlIHtAY29kZQorICAgICAqICAgICAgICAgICAgIENsb25lYWJsZX0gaW50ZXJmYWNlLgorICAgICAqLworICAgIHByb3RlY3RlZCBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQ2xvbmVhYmxlKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJDbGFzcyBkb2Vzbid0IGltcGxlbWVudCBDbG9uZWFibGUiKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBpbnRlcm5hbENsb25lKChDbG9uZWFibGUpIHRoaXMpOworICAgIH0KKworICAgIC8qCisgICAgICogTmF0aXZlIGhlbHBlciBtZXRob2QgZm9yIGNsb25pbmcuCisgICAgICovCisgICAgcHJpdmF0ZSBuYXRpdmUgT2JqZWN0IGludGVybmFsQ2xvbmUoQ2xvbmVhYmxlIG8pOworCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFuZCBpbmRpY2F0ZXMgaWYgdGhleQorICAgICAqIGFyZSBlcXVhbC4gSW4gb3JkZXIgdG8gYmUgZXF1YWwsIHtAY29kZSBvfSBtdXN0IHJlcHJlc2VudCB0aGUgc2FtZSBvYmplY3QKKyAgICAgKiBhcyB0aGlzIGluc3RhbmNlIHVzaW5nIGEgY2xhc3Mtc3BlY2lmaWMgY29tcGFyaXNvbi4gVGhlIGdlbmVyYWwgY29udHJhY3QKKyAgICAgKiBpcyB0aGF0IHRoaXMgY29tcGFyaXNvbiBzaG91bGQgYmUgcmVmbGV4aXZlLCBzeW1tZXRyaWMsIGFuZCB0cmFuc2l0aXZlLgorICAgICAqIEFsc28sIG5vIG9iamVjdCByZWZlcmVuY2Ugb3RoZXIgdGhhbiBudWxsIGlzIGVxdWFsIHRvIG51bGwuCisgICAgICoKKyAgICAgKiA8cD5UaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHtAY29kZSB0cnVlfSBvbmx5IGlmIHtAY29kZSB0aGlzID09CisgICAgICogb30uIFNlZSA8YSBocmVmPSJ7QGRvY1Jvb3R9cmVmZXJlbmNlL2phdmEvbGFuZy9PYmplY3QuaHRtbCN3cml0aW5nX2VxdWFscyI+V3JpdGluZyBhIGNvcnJlY3QKKyAgICAgKiB7QGNvZGUgZXF1YWxzfSBtZXRob2Q8L2E+CisgICAgICogaWYgeW91IGludGVuZCBpbXBsZW1lbnRpbmcgeW91ciBvd24ge0Bjb2RlIGVxdWFsc30gbWV0aG9kLgorICAgICAqCisgICAgICogPHA+VGhlIGdlbmVyYWwgY29udHJhY3QgZm9yIHRoZSB7QGNvZGUgZXF1YWxzfSBhbmQge0BsaW5rCisgICAgICogI2hhc2hDb2RlKCl9IG1ldGhvZHMgaXMgdGhhdCBpZiB7QGNvZGUgZXF1YWxzfSByZXR1cm5zIHtAY29kZSB0cnVlfSBmb3IKKyAgICAgKiBhbnkgdHdvIG9iamVjdHMsIHRoZW4ge0Bjb2RlIGhhc2hDb2RlKCl9IG11c3QgcmV0dXJuIHRoZSBzYW1lIHZhbHVlIGZvcgorICAgICAqIHRoZXNlIG9iamVjdHMuIFRoaXMgbWVhbnMgdGhhdCBzdWJjbGFzc2VzIG9mIHtAY29kZSBPYmplY3R9IHVzdWFsbHkKKyAgICAgKiBvdmVycmlkZSBlaXRoZXIgYm90aCBtZXRob2RzIG9yIG5laXRoZXIgb2YgdGhlbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyBpbnN0YW5jZSB3aXRoLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMge0Bjb2RlCisgICAgICogICAgICAgICBPYmplY3R9OyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNoYXNoQ29kZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICByZXR1cm4gdGhpcyA9PSBvOworICAgIH0KKworICAgIC8qKgorICAgICAqIEludm9rZWQgd2hlbiB0aGUgZ2FyYmFnZSBjb2xsZWN0b3IgaGFzIGRldGVjdGVkIHRoYXQgdGhpcyBpbnN0YW5jZSBpcyBubyBsb25nZXIgcmVhY2hhYmxlLgorICAgICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZywgYnV0IHRoaXMgbWV0aG9kIGNhbiBiZSBvdmVycmlkZGVuIHRvIGZyZWUgcmVzb3VyY2VzLgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IG9iamVjdHMgdGhhdCBvdmVycmlkZSB7QGNvZGUgZmluYWxpemV9IGFyZSBzaWduaWZpY2FudGx5IG1vcmUgZXhwZW5zaXZlIHRoYW4KKyAgICAgKiBvYmplY3RzIHRoYXQgZG9uJ3QuIEZpbmFsaXplcnMgbWF5IGJlIHJ1biBhIGxvbmcgdGltZSBhZnRlciB0aGUgb2JqZWN0IGlzIG5vIGxvbmdlcgorICAgICAqIHJlYWNoYWJsZSwgZGVwZW5kaW5nIG9uIG1lbW9yeSBwcmVzc3VyZSwgc28gaXQncyBhIGJhZCBpZGVhIHRvIHJlbHkgb24gdGhlbSBmb3IgY2xlYW51cC4KKyAgICAgKiBOb3RlIGFsc28gdGhhdCBmaW5hbGl6ZXJzIGFyZSBydW4gb24gYSBzaW5nbGUgVk0td2lkZSBmaW5hbGl6ZXIgdGhyZWFkLAorICAgICAqIHNvIGRvaW5nIGJsb2NraW5nIHdvcmsgaW4gYSBmaW5hbGl6ZXIgaXMgYSBiYWQgaWRlYS4gQSBmaW5hbGl6ZXIgaXMgdXN1YWxseSBvbmx5IG5lY2Vzc2FyeQorICAgICAqIGZvciBhIGNsYXNzIHRoYXQgaGFzIGEgbmF0aXZlIHBlZXIgYW5kIG5lZWRzIHRvIGNhbGwgYSBuYXRpdmUgbWV0aG9kIHRvIGRlc3Ryb3kgdGhhdCBwZWVyLgorICAgICAqIEV2ZW4gdGhlbiwgaXQncyBiZXR0ZXIgdG8gcHJvdmlkZSBhbiBleHBsaWNpdCB7QGNvZGUgY2xvc2V9IG1ldGhvZCAoYW5kIGltcGxlbWVudAorICAgICAqIHtAbGluayBqYXZhLmlvLkNsb3NlYWJsZX0pLCBhbmQgaW5zaXN0IHRoYXQgY2FsbGVycyBtYW51YWxseSBkaXNwb3NlIG9mIGluc3RhbmNlcy4gVGhpcworICAgICAqIHdvcmtzIHdlbGwgZm9yIHNvbWV0aGluZyBsaWtlIGZpbGVzLCBidXQgbGVzcyB3ZWxsIGZvciBzb21ldGhpbmcgbGlrZSBhIHtAY29kZSBCaWdJbnRlZ2VyfQorICAgICAqIHdoZXJlIHR5cGljYWwgY2FsbGluZyBjb2RlIHdvdWxkIGhhdmUgdG8gZGVhbCB3aXRoIGxvdHMgb2YgdGVtcG9yYXJpZXMuIFVuZm9ydHVuYXRlbHksCisgICAgICogY29kZSB0aGF0IGNyZWF0ZXMgbG90cyBvZiB0ZW1wb3JhcmllcyBpcyB0aGUgd29yc3Qga2luZCBvZiBjb2RlIGZyb20gdGhlIHBvaW50IG9mIHZpZXcgb2YKKyAgICAgKiB0aGUgc2luZ2xlIGZpbmFsaXplciB0aHJlYWQuCisgICAgICoKKyAgICAgKiA8cD5JZiB5b3UgPGk+bXVzdDwvaT4gdXNlIGZpbmFsaXplcnMsIGNvbnNpZGVyIGF0IGxlYXN0IHByb3ZpZGluZyB5b3VyIG93bgorICAgICAqIHtAbGluayBqYXZhLmxhbmcucmVmLlJlZmVyZW5jZVF1ZXVlfSBhbmQgaGF2aW5nIHlvdXIgb3duIHRocmVhZCBwcm9jZXNzIHRoYXQgcXVldWUuCisgICAgICoKKyAgICAgKiA8cD5Vbmxpa2UgY29uc3RydWN0b3JzLCBmaW5hbGl6ZXJzIGFyZSBub3QgYXV0b21hdGljYWxseSBjaGFpbmVkLiBZb3UgYXJlIHJlc3BvbnNpYmxlIGZvcgorICAgICAqIGNhbGxpbmcge0Bjb2RlIHN1cGVyLmZpbmFsaXplKCl9IHlvdXJzZWxmLgorICAgICAqCisgICAgICogPHA+VW5jYXVnaHQgZXhjZXB0aW9ucyB0aHJvd24gYnkgZmluYWxpemVycyBhcmUgaWdub3JlZCBhbmQgZG8gbm90IHRlcm1pbmF0ZSB0aGUgZmluYWxpemVyCisgICAgICogdGhyZWFkLgorICAgICAqCisgICAgICogU2VlIDxpPkVmZmVjdGl2ZSBKYXZhPC9pPiBJdGVtIDcsICJBdm9pZCBmaW5hbGl6ZXJzIiBmb3IgbW9yZS4KKyAgICAgKi8KKyAgICBARmluZEJ1Z3NTdXBwcmVzc1dhcm5pbmdzKCJGSV9FTVBUWSIpCisgICAgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB1bmlxdWUgaW5zdGFuY2Ugb2Yge0BsaW5rIENsYXNzfSB0aGF0IHJlcHJlc2VudHMgdGhpcworICAgICAqIG9iamVjdCdzIGNsYXNzLiBOb3RlIHRoYXQge0Bjb2RlIGdldENsYXNzKCl9IGlzIGEgc3BlY2lhbCBjYXNlIGluIHRoYXQgaXQKKyAgICAgKiBhY3R1YWxseSByZXR1cm5zIHtAY29kZSBDbGFzczw/IGV4dGVuZHMgRm9vPn0gd2hlcmUge0Bjb2RlIEZvb30gaXMgdGhlCisgICAgICogZXJhc3VyZSBvZiB0aGUgdHlwZSBvZiB0aGUgZXhwcmVzc2lvbiB7QGNvZGUgZ2V0Q2xhc3MoKX0gd2FzIGNhbGxlZCB1cG9uLgorICAgICAqIDxwPgorICAgICAqIEFzIGFuIGV4YW1wbGUsIHRoZSBmb2xsb3dpbmcgY29kZSBhY3R1YWxseSBjb21waWxlcywgYWx0aG91Z2ggb25lIG1pZ2h0CisgICAgICogdGhpbmsgaXQgc2hvdWxkbid0OgorICAgICAqIDxwPgorICAgICAqIDxwcmU+e0Bjb2RlCisgICAgICogICBMaXN0PEludGVnZXI+IGwgPSBuZXcgQXJyYXlMaXN0PEludGVnZXI+KCk7CisgICAgICogICBDbGFzczw/IGV4dGVuZHMgTGlzdD4gYyA9IGwuZ2V0Q2xhc3MoKTt9PC9wcmU+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgb2JqZWN0J3Mge0Bjb2RlIENsYXNzfSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgbmF0aXZlIENsYXNzPD8+IGdldENsYXNzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGludGVnZXIgaGFzaCBjb2RlIGZvciB0aGlzIG9iamVjdC4gQnkgY29udHJhY3QsIGFueSB0d28KKyAgICAgKiBvYmplY3RzIGZvciB3aGljaCB7QGxpbmsgI2VxdWFsc30gcmV0dXJucyB7QGNvZGUgdHJ1ZX0gbXVzdCByZXR1cm4KKyAgICAgKiB0aGUgc2FtZSBoYXNoIGNvZGUgdmFsdWUuIFRoaXMgbWVhbnMgdGhhdCBzdWJjbGFzc2VzIG9mIHtAY29kZSBPYmplY3R9CisgICAgICogdXN1YWxseSBvdmVycmlkZSBib3RoIG1ldGhvZHMgb3IgbmVpdGhlciBtZXRob2QuCisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoYXQgaGFzaCB2YWx1ZXMgbXVzdCBub3QgY2hhbmdlIG92ZXIgdGltZSB1bmxlc3MgaW5mb3JtYXRpb24gdXNlZCBpbiBlcXVhbHMKKyAgICAgKiBjb21wYXJpc29ucyBhbHNvIGNoYW5nZXMuCisgICAgICoKKyAgICAgKiA8cD5TZWUgPGEgaHJlZj0ie0Bkb2NSb290fXJlZmVyZW5jZS9qYXZhL2xhbmcvT2JqZWN0Lmh0bWwjd3JpdGluZ19oYXNoQ29kZSI+V3JpdGluZyBhIGNvcnJlY3QKKyAgICAgKiB7QGNvZGUgaGFzaENvZGV9IG1ldGhvZDwvYT4KKyAgICAgKiBpZiB5b3UgaW50ZW5kIGltcGxlbWVudGluZyB5b3VyIG93biB7QGNvZGUgaGFzaENvZGV9IG1ldGhvZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBvYmplY3QncyBoYXNoIGNvZGUuCisgICAgICogQHNlZSAjZXF1YWxzCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSBpbnQgaGFzaENvZGUoKTsKKworICAgIC8qKgorICAgICAqIENhdXNlcyBhIHRocmVhZCB3aGljaCBpcyB3YWl0aW5nIG9uIHRoaXMgb2JqZWN0J3MgbW9uaXRvciAoYnkgbWVhbnMgb2YKKyAgICAgKiBjYWxsaW5nIG9uZSBvZiB0aGUge0Bjb2RlIHdhaXQoKX0gbWV0aG9kcykgdG8gYmUgd29rZW4gdXAuIElmIG1vcmUgdGhhbgorICAgICAqIG9uZSB0aHJlYWQgaXMgd2FpdGluZywgb25lIG9mIHRoZW0gaXMgY2hvc2VuIGF0IHRoZSBkaXNjcmV0aW9uIG9mIHRoZQorICAgICAqIFZNLiBUaGUgY2hvc2VuIHRocmVhZCB3aWxsIG5vdCBydW4gaW1tZWRpYXRlbHkuIFRoZSB0aHJlYWQKKyAgICAgKiB0aGF0IGNhbGxlZCB7QGNvZGUgbm90aWZ5KCl9IGhhcyB0byByZWxlYXNlIHRoZSBvYmplY3QncyBtb25pdG9yIGZpcnN0LgorICAgICAqIEFsc28sIHRoZSBjaG9zZW4gdGhyZWFkIHN0aWxsIGhhcyB0byBjb21wZXRlIGFnYWluc3Qgb3RoZXIgdGhyZWFkcyB0aGF0CisgICAgICogdHJ5IHRvIHN5bmNocm9uaXplIG9uIHRoZSBzYW1lIG9iamVjdC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBjYW4gb25seSBiZSBpbnZva2VkIGJ5IGEgdGhyZWFkIHdoaWNoIG93bnMgdGhpcyBvYmplY3QncworICAgICAqIG1vbml0b3IuIEEgdGhyZWFkIGJlY29tZXMgb3duZXIgb2YgYW4gb2JqZWN0J3MgbW9uaXRvcgorICAgICAqIDwvcD4KKyAgICAgKiA8dWw+CisgICAgICogPGxpPmJ5IGV4ZWN1dGluZyBhIHN5bmNocm9uaXplZCBtZXRob2Qgb2YgdGhhdCBvYmplY3Q7PC9saT4KKyAgICAgKiA8bGk+YnkgZXhlY3V0aW5nIHRoZSBib2R5IG9mIGEge0Bjb2RlIHN5bmNocm9uaXplZH0gc3RhdGVtZW50IHRoYXQKKyAgICAgKiBzeW5jaHJvbml6ZXMgb24gdGhlIG9iamVjdDs8L2xpPgorICAgICAqIDxsaT5ieSBleGVjdXRpbmcgYSBzeW5jaHJvbml6ZWQgc3RhdGljIG1ldGhvZCBpZiB0aGUgb2JqZWN0IGlzIG9mIHR5cGUKKyAgICAgKiB7QGNvZGUgQ2xhc3N9LjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBzZWUgI25vdGlmeUFsbAorICAgICAqIEBzZWUgI3dhaXQoKQorICAgICAqIEBzZWUgI3dhaXQobG9uZykKKyAgICAgKiBAc2VlICN3YWl0KGxvbmcsaW50KQorICAgICAqIEBzZWUgamF2YS5sYW5nLlRocmVhZAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBuYXRpdmUgdm9pZCBub3RpZnkoKTsKKworICAgIC8qKgorICAgICAqIENhdXNlcyBhbGwgdGhyZWFkcyB3aGljaCBhcmUgd2FpdGluZyBvbiB0aGlzIG9iamVjdCdzIG1vbml0b3IgKGJ5IG1lYW5zCisgICAgICogb2YgY2FsbGluZyBvbmUgb2YgdGhlIHtAY29kZSB3YWl0KCl9IG1ldGhvZHMpIHRvIGJlIHdva2VuIHVwLiBUaGUgdGhyZWFkcworICAgICAqIHdpbGwgbm90IHJ1biBpbW1lZGlhdGVseS4gVGhlIHRocmVhZCB0aGF0IGNhbGxlZCB7QGNvZGUgbm90aWZ5KCl9IGhhcyB0bworICAgICAqIHJlbGVhc2UgdGhlIG9iamVjdCdzIG1vbml0b3IgZmlyc3QuIEFsc28sIHRoZSB0aHJlYWRzIHN0aWxsIGhhdmUgdG8KKyAgICAgKiBjb21wZXRlIGFnYWluc3Qgb3RoZXIgdGhyZWFkcyB0aGF0IHRyeSB0byBzeW5jaHJvbml6ZSBvbiB0aGUgc2FtZSBvYmplY3QuCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgY2FuIG9ubHkgYmUgaW52b2tlZCBieSBhIHRocmVhZCB3aGljaCBvd25zIHRoaXMgb2JqZWN0J3MKKyAgICAgKiBtb25pdG9yLiBBIHRocmVhZCBiZWNvbWVzIG93bmVyIG9mIGFuIG9iamVjdCdzIG1vbml0b3IKKyAgICAgKiA8L3A+CisgICAgICogPHVsPgorICAgICAqIDxsaT5ieSBleGVjdXRpbmcgYSBzeW5jaHJvbml6ZWQgbWV0aG9kIG9mIHRoYXQgb2JqZWN0OzwvbGk+CisgICAgICogPGxpPmJ5IGV4ZWN1dGluZyB0aGUgYm9keSBvZiBhIHtAY29kZSBzeW5jaHJvbml6ZWR9IHN0YXRlbWVudCB0aGF0CisgICAgICogc3luY2hyb25pemVzIG9uIHRoZSBvYmplY3Q7PC9saT4KKyAgICAgKiA8bGk+YnkgZXhlY3V0aW5nIGEgc3luY2hyb25pemVkIHN0YXRpYyBtZXRob2QgaWYgdGhlIG9iamVjdCBpcyBvZiB0eXBlCisgICAgICoge0Bjb2RlIENsYXNzfS48L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgdGhyZWFkIGNhbGxpbmcgdGhpcyBtZXRob2QgaXMgbm90IHRoZSBvd25lciBvZiB0aGlzCisgICAgICogICAgICAgICAgICAgb2JqZWN0J3MgbW9uaXRvci4KKyAgICAgKiBAc2VlICNub3RpZnkKKyAgICAgKiBAc2VlICN3YWl0KCkKKyAgICAgKiBAc2VlICN3YWl0KGxvbmcpCisgICAgICogQHNlZSAjd2FpdChsb25nLGludCkKKyAgICAgKiBAc2VlIGphdmEubGFuZy5UaHJlYWQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgbmF0aXZlIHZvaWQgbm90aWZ5QWxsKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGlzCisgICAgICogb2JqZWN0LiBTdWJjbGFzc2VzIGFyZSBlbmNvdXJhZ2VkIHRvIG92ZXJyaWRlIHRoaXMgbWV0aG9kIGFuZCBwcm92aWRlIGFuCisgICAgICogaW1wbGVtZW50YXRpb24gdGhhdCB0YWtlcyBpbnRvIGFjY291bnQgdGhlIG9iamVjdCdzIHR5cGUgYW5kIGRhdGEuIFRoZQorICAgICAqIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gaXMgZXF1aXZhbGVudCB0byB0aGUgZm9sbG93aW5nIGV4cHJlc3Npb246CisgICAgICogPHByZT4KKyAgICAgKiAgIGdldENsYXNzKCkuZ2V0TmFtZSgpICsgJ0AnICsgSW50ZWdlci50b0hleFN0cmluZyhoYXNoQ29kZSgpKTwvcHJlPgorICAgICAqIDxwPlNlZSA8YSBocmVmPSJ7QGRvY1Jvb3R9cmVmZXJlbmNlL2phdmEvbGFuZy9PYmplY3QuaHRtbCN3cml0aW5nX3RvU3RyaW5nIj5Xcml0aW5nIGEgdXNlZnVsCisgICAgICoge0Bjb2RlIHRvU3RyaW5nfSBtZXRob2Q8L2E+CisgICAgICogaWYgeW91IGludGVuZCBpbXBsZW1lbnRpbmcgeW91ciBvd24ge0Bjb2RlIHRvU3RyaW5nfSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcHJpbnRhYmxlIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBnZXRDbGFzcygpLmdldE5hbWUoKSArICdAJyArIEludGVnZXIudG9IZXhTdHJpbmcoaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2F1c2VzIHRoZSBjYWxsaW5nIHRocmVhZCB0byB3YWl0IHVudGlsIGFub3RoZXIgdGhyZWFkIGNhbGxzIHRoZSB7QGNvZGUKKyAgICAgKiBub3RpZnkoKX0gb3Ige0Bjb2RlIG5vdGlmeUFsbCgpfSBtZXRob2Qgb2YgdGhpcyBvYmplY3QuIFRoaXMgbWV0aG9kIGNhbgorICAgICAqIG9ubHkgYmUgaW52b2tlZCBieSBhIHRocmVhZCB3aGljaCBvd25zIHRoaXMgb2JqZWN0J3MgbW9uaXRvcjsgc2VlCisgICAgICoge0BsaW5rICNub3RpZnkoKX0gb24gaG93IGEgdGhyZWFkIGNhbiBiZWNvbWUgdGhlIG93bmVyIG9mIGEgbW9uaXRvci4KKyAgICAgKiA8cD4KKyAgICAgKiBBIHdhaXRpbmcgdGhyZWFkIGNhbiBiZSBzZW50IHtAY29kZSBpbnRlcnJ1cHQoKX0gdG8gY2F1c2UgaXQgdG8KKyAgICAgKiBwcmVtYXR1cmVseSBzdG9wIHdhaXRpbmcsIHNvIHtAY29kZSB3YWl0fSBzaG91bGQgYmUgY2FsbGVkIGluIGEgbG9vcCB0bworICAgICAqIGNoZWNrIHRoYXQgdGhlIGNvbmRpdGlvbiB0aGF0IGhhcyBiZWVuIHdhaXRlZCBmb3IgaGFzIGJlZW4gbWV0IGJlZm9yZQorICAgICAqIGNvbnRpbnVpbmcuCisgICAgICogPC9wPgorICAgICAqIDxwPgorICAgICAqIFdoaWxlIHRoZSB0aHJlYWQgd2FpdHMsIGl0IGdpdmVzIHVwIG93bmVyc2hpcCBvZiB0aGlzIG9iamVjdCdzIG1vbml0b3IuCisgICAgICogV2hlbiBpdCBpcyBub3RpZmllZCAob3IgaW50ZXJydXB0ZWQpLCBpdCByZS1hY3F1aXJlcyB0aGUgbW9uaXRvciBiZWZvcmUKKyAgICAgKiBpdCBzdGFydHMgcnVubmluZy4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgdGhyZWFkIGNhbGxpbmcgdGhpcyBtZXRob2QgaXMgbm90IHRoZSBvd25lciBvZiB0aGlzCisgICAgICogICAgICAgICAgICAgb2JqZWN0J3MgbW9uaXRvci4KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciB0aHJlYWQgaW50ZXJydXB0cyB0aGlzIHRocmVhZCB3aGlsZSBpdCBpcyB3YWl0aW5nLgorICAgICAqIEBzZWUgI25vdGlmeQorICAgICAqIEBzZWUgI25vdGlmeUFsbAorICAgICAqIEBzZWUgI3dhaXQobG9uZykKKyAgICAgKiBAc2VlICN3YWl0KGxvbmcsaW50KQorICAgICAqIEBzZWUgamF2YS5sYW5nLlRocmVhZAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHdhaXQoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICB3YWl0KDAgLDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhdXNlcyB0aGUgY2FsbGluZyB0aHJlYWQgdG8gd2FpdCB1bnRpbCBhbm90aGVyIHRocmVhZCBjYWxscyB0aGUge0Bjb2RlCisgICAgICogbm90aWZ5KCl9IG9yIHtAY29kZSBub3RpZnlBbGwoKX0gbWV0aG9kIG9mIHRoaXMgb2JqZWN0IG9yIHVudGlsIHRoZQorICAgICAqIHNwZWNpZmllZCB0aW1lb3V0IGV4cGlyZXMuIFRoaXMgbWV0aG9kIGNhbiBvbmx5IGJlIGludm9rZWQgYnkgYSB0aHJlYWQKKyAgICAgKiB3aGljaCBvd25zIHRoaXMgb2JqZWN0J3MgbW9uaXRvcjsgc2VlIHtAbGluayAjbm90aWZ5KCl9IG9uIGhvdyBhIHRocmVhZAorICAgICAqIGNhbiBiZWNvbWUgdGhlIG93bmVyIG9mIGEgbW9uaXRvci4KKyAgICAgKiA8cD4KKyAgICAgKiBBIHdhaXRpbmcgdGhyZWFkIGNhbiBiZSBzZW50IHtAY29kZSBpbnRlcnJ1cHQoKX0gdG8gY2F1c2UgaXQgdG8KKyAgICAgKiBwcmVtYXR1cmVseSBzdG9wIHdhaXRpbmcsIHNvIHtAY29kZSB3YWl0fSBzaG91bGQgYmUgY2FsbGVkIGluIGEgbG9vcCB0bworICAgICAqIGNoZWNrIHRoYXQgdGhlIGNvbmRpdGlvbiB0aGF0IGhhcyBiZWVuIHdhaXRlZCBmb3IgaGFzIGJlZW4gbWV0IGJlZm9yZQorICAgICAqIGNvbnRpbnVpbmcuCisgICAgICogPC9wPgorICAgICAqIDxwPgorICAgICAqIFdoaWxlIHRoZSB0aHJlYWQgd2FpdHMsIGl0IGdpdmVzIHVwIG93bmVyc2hpcCBvZiB0aGlzIG9iamVjdCdzIG1vbml0b3IuCisgICAgICogV2hlbiBpdCBpcyBub3RpZmllZCAob3IgaW50ZXJydXB0ZWQpLCBpdCByZS1hY3F1aXJlcyB0aGUgbW9uaXRvciBiZWZvcmUKKyAgICAgKiBpdCBzdGFydHMgcnVubmluZy4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbWlsbGlzCisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSB0aW1lIHRvIHdhaXQgaW4gbWlsbGlzZWNvbmRzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG1pbGxpcyA8IDB9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB0aHJlYWQgY2FsbGluZyB0aGlzIG1ldGhvZCBpcyBub3QgdGhlIG93bmVyIG9mIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBvYmplY3QncyBtb25pdG9yLgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIHRocmVhZCBpbnRlcnJ1cHRzIHRoaXMgdGhyZWFkIHdoaWxlIGl0IGlzIHdhaXRpbmcuCisgICAgICogQHNlZSAjbm90aWZ5CisgICAgICogQHNlZSAjbm90aWZ5QWxsCisgICAgICogQHNlZSAjd2FpdCgpCisgICAgICogQHNlZSAjd2FpdChsb25nLGludCkKKyAgICAgKiBAc2VlIGphdmEubGFuZy5UaHJlYWQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB3YWl0KGxvbmcgbWlsbGlzKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICB3YWl0KG1pbGxpcywgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2F1c2VzIHRoZSBjYWxsaW5nIHRocmVhZCB0byB3YWl0IHVudGlsIGFub3RoZXIgdGhyZWFkIGNhbGxzIHRoZSB7QGNvZGUKKyAgICAgKiBub3RpZnkoKX0gb3Ige0Bjb2RlIG5vdGlmeUFsbCgpfSBtZXRob2Qgb2YgdGhpcyBvYmplY3Qgb3IgdW50aWwgdGhlCisgICAgICogc3BlY2lmaWVkIHRpbWVvdXQgZXhwaXJlcy4gVGhpcyBtZXRob2QgY2FuIG9ubHkgYmUgaW52b2tlZCBieSBhIHRocmVhZAorICAgICAqIHRoYXQgb3ducyB0aGlzIG9iamVjdCdzIG1vbml0b3I7IHNlZSB7QGxpbmsgI25vdGlmeSgpfSBvbiBob3cgYSB0aHJlYWQKKyAgICAgKiBjYW4gYmVjb21lIHRoZSBvd25lciBvZiBhIG1vbml0b3IuCisgICAgICogPHA+CisgICAgICogQSB3YWl0aW5nIHRocmVhZCBjYW4gYmUgc2VudCB7QGNvZGUgaW50ZXJydXB0KCl9IHRvIGNhdXNlIGl0IHRvCisgICAgICogcHJlbWF0dXJlbHkgc3RvcCB3YWl0aW5nLCBzbyB7QGNvZGUgd2FpdH0gc2hvdWxkIGJlIGNhbGxlZCBpbiBhIGxvb3AgdG8KKyAgICAgKiBjaGVjayB0aGF0IHRoZSBjb25kaXRpb24gdGhhdCBoYXMgYmVlbiB3YWl0ZWQgZm9yIGhhcyBiZWVuIG1ldCBiZWZvcmUKKyAgICAgKiBjb250aW51aW5nLgorICAgICAqIDwvcD4KKyAgICAgKiA8cD4KKyAgICAgKiBXaGlsZSB0aGUgdGhyZWFkIHdhaXRzLCBpdCBnaXZlcyB1cCBvd25lcnNoaXAgb2YgdGhpcyBvYmplY3QncyBtb25pdG9yLgorICAgICAqIFdoZW4gaXQgaXMgbm90aWZpZWQgKG9yIGludGVycnVwdGVkKSwgaXQgcmUtYWNxdWlyZXMgdGhlIG1vbml0b3IgYmVmb3JlCisgICAgICogaXQgc3RhcnRzIHJ1bm5pbmcuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG1pbGxpcworICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gdGltZSB0byB3YWl0IGluIG1pbGxpc2Vjb25kcy4KKyAgICAgKiBAcGFyYW0gbmFub3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBmcmFjdGlvbiBvZiBhIG1pbGxpc2Vjb25kIHRvIHdhaXQsIHNwZWNpZmllZCBpbgorICAgICAqICAgICAgICAgICAgbmFub3NlY29uZHMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbWlsbGlzIDwgMH0sIHtAY29kZSBuYW5vcyA8IDB9IG9yIHtAY29kZSBuYW5vcyA+CisgICAgICogICAgICAgICAgICAgOTk5OTk5fS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgdGhyZWFkIGNhbGxpbmcgdGhpcyBtZXRob2QgaXMgbm90IHRoZSBvd25lciBvZiB0aGlzCisgICAgICogICAgICAgICAgICAgb2JqZWN0J3MgbW9uaXRvci4KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciB0aHJlYWQgaW50ZXJydXB0cyB0aGlzIHRocmVhZCB3aGlsZSBpdCBpcyB3YWl0aW5nLgorICAgICAqIEBzZWUgI25vdGlmeQorICAgICAqIEBzZWUgI25vdGlmeUFsbAorICAgICAqIEBzZWUgI3dhaXQoKQorICAgICAqIEBzZWUgI3dhaXQobG9uZyxpbnQpCisgICAgICogQHNlZSBqYXZhLmxhbmcuVGhyZWFkCisgICAgICovCisgICAgcHVibGljIGZpbmFsIG5hdGl2ZSB2b2lkIHdhaXQobG9uZyBtaWxsaXMsIGludCBuYW5vcykgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9PdXRPZk1lbW9yeUVycm9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL091dE9mTWVtb3J5RXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZWI4OGMzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9PdXRPZk1lbW9yeUVycm9yLmphdmEKQEAgLTAsMCArMSw0NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyb3duIHdoZW4gYSByZXF1ZXN0IGZvciBtZW1vcnkgaXMgbWFkZSB0aGF0IGNhbiBub3QgYmUgc2F0aXNmaWVkIHVzaW5nIHRoZQorICogYXZhaWxhYmxlIHBsYXRmb3JtIHJlc291cmNlcy4gU3VjaCBhIHJlcXVlc3QgbWF5IGJlIG1hZGUgYnkgYm90aCB0aGUgcnVubmluZworICogYXBwbGljYXRpb24gb3IgYnkgYW4gaW50ZXJuYWwgZnVuY3Rpb24gb2YgdGhlIFZNLgorICovCitwdWJsaWMgY2xhc3MgT3V0T2ZNZW1vcnlFcnJvciBleHRlbmRzIFZpcnR1YWxNYWNoaW5lRXJyb3IgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODIyODU2NDA4NjE4NDAxMDUxN0w7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBPdXRPZk1lbW9yeUVycm9yfSB0aGF0IGluY2x1ZGVzIHRoZSBjdXJyZW50IHN0YWNrCisgICAgICogdHJhY2UuCisgICAgICovCisgICAgcHVibGljIE91dE9mTWVtb3J5RXJyb3IoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgT3V0T2ZNZW1vcnlFcnJvcn0gd2l0aCB0aGUgY3VycmVudCBzdGFjayB0cmFjZQorICAgICAqIGFuZCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgT3V0T2ZNZW1vcnlFcnJvcihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL092ZXJyaWRlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL092ZXJyaWRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDJjOTJlYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvT3ZlcnJpZGUuamF2YQpAQCAtMCwwICsxLDM0IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3k7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OworCisvKioKKyAqIEFubm90YXRpb24gdHlwZSB1c2VkIHRvIG1hcmsgbWV0aG9kcyB0aGF0IG92ZXJyaWRlIGEgbWV0aG9kIGRlY2xhcmF0aW9uIGluIGEKKyAqIHN1cGVyY2xhc3MuIENvbXBpbGVycyBwcm9kdWNlIGFuIGVycm9yIGlmIGEgbWV0aG9kIGFubm90YXRlZCB3aXRoIEBPdmVycmlkZQorICogZG9lcyBub3QgYWN0dWFsbHkgb3ZlcnJpZGUgYSBtZXRob2QgaW4gYSBzdXBlcmNsYXNzLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqLworQFRhcmdldChFbGVtZW50VHlwZS5NRVRIT0QpCitAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5TT1VSQ0UpCitwdWJsaWMgQGludGVyZmFjZSBPdmVycmlkZSB7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1BhY2thZ2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvUGFja2FnZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAwY2M4MWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1BhY2thZ2UuamF2YQpAQCAtMCwwICsxLDI5MSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKK2ltcG9ydCBkYWx2aWsuc3lzdGVtLlZNU3RhY2s7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Bbm5vdGF0ZWRFbGVtZW50OworaW1wb3J0IGphdmEubmV0LlVSTDsKKworLyoqCisgKiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBhIEphdmEgcGFja2FnZS4gVGhpcyBpbmNsdWRlcyBpbXBsZW1lbnRhdGlvbiBhbmQKKyAqIHNwZWNpZmljYXRpb24gdmVyc2lvbnMuIFR5cGljYWxseSB0aGlzIGluZm9ybWF0aW9uIGlzIHJldHJpZXZlZCBmcm9tIHRoZQorICogbWFuaWZlc3QuCisgKiA8cD4KKyAqIFBhY2thZ2VzIGFyZSBtYW5hZ2VkIGJ5IGNsYXNzIGxvYWRlcnMuIEFsbCBjbGFzc2VzIGxvYWRlZCBieSB0aGUgc2FtZSBsb2FkZXIKKyAqIGZyb20gdGhlIHNhbWUgcGFja2FnZSBzaGFyZSBhIHtAY29kZSBQYWNrYWdlfSBpbnN0YW5jZS4KKyAqIDwvcD4KKyAqCisgKiBAc2VlIGphdmEubGFuZy5DbGFzc0xvYWRlcgorICovCitwdWJsaWMgY2xhc3MgUGFja2FnZSBpbXBsZW1lbnRzIEFubm90YXRlZEVsZW1lbnQgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFubm90YXRpb25bXSBOT19BTk5PVEFUSU9OUyA9IG5ldyBBbm5vdGF0aW9uWzBdOworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBzcGVjVGl0bGU7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgc3BlY1ZlcnNpb247CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgc3BlY1ZlbmRvcjsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBpbXBsVGl0bGU7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgaW1wbFZlcnNpb247CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgaW1wbFZlbmRvcjsKKyAgICBwcml2YXRlIGZpbmFsIFVSTCBzZWFsQmFzZTsKKworICAgIFBhY2thZ2UoU3RyaW5nIG5hbWUsIFN0cmluZyBzcGVjVGl0bGUsIFN0cmluZyBzcGVjVmVyc2lvbiwgU3RyaW5nIHNwZWNWZW5kb3IsCisgICAgICAgICAgICBTdHJpbmcgaW1wbFRpdGxlLCBTdHJpbmcgaW1wbFZlcnNpb24sIFN0cmluZyBpbXBsVmVuZG9yLCBVUkwgc2VhbEJhc2UpIHsKKyAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgICAgdGhpcy5zcGVjVGl0bGUgPSBzcGVjVGl0bGU7CisgICAgICAgIHRoaXMuc3BlY1ZlcnNpb24gPSBzcGVjVmVyc2lvbjsKKyAgICAgICAgdGhpcy5zcGVjVmVuZG9yID0gc3BlY1ZlbmRvcjsKKyAgICAgICAgdGhpcy5pbXBsVGl0bGUgPSBpbXBsVGl0bGU7CisgICAgICAgIHRoaXMuaW1wbFZlcnNpb24gPSBpbXBsVmVyc2lvbjsKKyAgICAgICAgdGhpcy5pbXBsVmVuZG9yID0gaW1wbFZlbmRvcjsKKyAgICAgICAgdGhpcy5zZWFsQmFzZSA9IHNlYWxCYXNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGFubm90YXRpb24gYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgYW5ub3RhdGlvbiB0eXBlIGFuZAorICAgICAqIHRoaXMgcGFja2FnZSwgaWYgcHJlc2VudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbm5vdGF0aW9uVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGFubm90YXRpb24gdHlwZSB0byBsb29rIGZvci4KKyAgICAgKiBAcmV0dXJuIGFuIGluc3RhbmNlIG9mIHtAbGluayBBbm5vdGF0aW9ufSBvciB7QGNvZGUgbnVsbH0uCisgICAgICogQHNlZSBqYXZhLmxhbmcucmVmbGVjdC5Bbm5vdGF0ZWRFbGVtZW50I2dldEFubm90YXRpb24oamF2YS5sYW5nLkNsYXNzKQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyA8QSBleHRlbmRzIEFubm90YXRpb24+IEEgZ2V0QW5ub3RhdGlvbihDbGFzczxBPiBhbm5vdGF0aW9uVHlwZSkgeworICAgICAgICBmb3IgKEFubm90YXRpb24gYW5ub3RhdGlvbiA6IGdldEFubm90YXRpb25zKCkpIHsKKyAgICAgICAgICAgIGlmIChhbm5vdGF0aW9uVHlwZS5pc0luc3RhbmNlKGFubm90YXRpb24pKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChBKSBhbm5vdGF0aW9uOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gZW1wdHkgYXJyYXkuIFBhY2thZ2UgYW5ub3RhdGlvbnMgYXJlIG5vdCBzdXBwb3J0ZWQgb24gQW5kcm9pZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQW5ub3RhdGlvbltdIGdldEFubm90YXRpb25zKCkgeworICAgICAgICByZXR1cm4gTk9fQU5OT1RBVElPTlM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBlbXB0eSBhcnJheS4gUGFja2FnZSBhbm5vdGF0aW9ucyBhcmUgbm90IHN1cHBvcnRlZCBvbiBBbmRyb2lkLgorICAgICAqLworICAgIHB1YmxpYyBBbm5vdGF0aW9uW10gZ2V0RGVjbGFyZWRBbm5vdGF0aW9ucygpIHsKKyAgICAgICAgcmV0dXJuIE5PX0FOTk9UQVRJT05TOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgYW5ub3RhdGlvbiBpcyBwcmVzZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGFubm90YXRpb25UeXBlCisgICAgICogICAgICAgICAgICB0aGUgYW5ub3RhdGlvbiB0eXBlIHRvIGxvb2sgZm9yLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBhbm5vdGF0aW9uIGlzIHByZXNlbnQ7IHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5yZWZsZWN0LkFubm90YXRlZEVsZW1lbnQjaXNBbm5vdGF0aW9uUHJlc2VudChqYXZhLmxhbmcuQ2xhc3MpCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNBbm5vdGF0aW9uUHJlc2VudChDbGFzczw/IGV4dGVuZHMgQW5ub3RhdGlvbj4gYW5ub3RhdGlvblR5cGUpIHsKKyAgICAgICAgcmV0dXJuIGdldEFubm90YXRpb24oYW5ub3RhdGlvblR5cGUpICE9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGl0bGUgb2YgdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgcGFja2FnZSwgb3Ige0Bjb2RlIG51bGx9CisgICAgICogaWYgdGhpcyBpcyB1bmtub3duLiBUaGUgZm9ybWF0IG9mIHRoaXMgc3RyaW5nIGlzIHVuc3BlY2lmaWVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaW1wbGVtZW50YXRpb24gdGl0bGUsIG1heSBiZSB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRJbXBsZW1lbnRhdGlvblRpdGxlKCkgeworICAgICAgICByZXR1cm4gaW1wbFRpdGxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHZlbmRvciBvciBvcmdhbml6YXRpb24gdGhhdCBwcm92aWRlcyB0aGlzCisgICAgICogaW1wbGVtZW50YXRpb24gb2YgdGhlIHBhY2thZ2UsIG9yIHtAY29kZSBudWxsfSBpZiB0aGlzIGlzIHVua25vd24uIFRoZQorICAgICAqIGZvcm1hdCBvZiB0aGlzIHN0cmluZyBpcyB1bnNwZWNpZmllZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGltcGxlbWVudGF0aW9uIHZlbmRvciBuYW1lLCBtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0SW1wbGVtZW50YXRpb25WZW5kb3IoKSB7CisgICAgICAgIHJldHVybiBpbXBsVmVuZG9yOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZlcnNpb24gb2YgdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgcGFja2FnZSwgb3Ige0Bjb2RlCisgICAgICogbnVsbH0gaWYgdGhpcyBpcyB1bmtub3duLiBUaGUgZm9ybWF0IG9mIHRoaXMgc3RyaW5nIGlzIHVuc3BlY2lmaWVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaW1wbGVtZW50YXRpb24gdmVyc2lvbiwgbWF5IGJlIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEltcGxlbWVudGF0aW9uVmVyc2lvbigpIHsKKyAgICAgICAgcmV0dXJuIGltcGxWZXJzaW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhpcyBwYWNrYWdlIGluIHRoZSBzdGFuZGFyZCBkb3Qgbm90YXRpb247IGZvcgorICAgICAqIGV4YW1wbGU6ICJqYXZhLmxhbmciLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGlzIHBhY2thZ2UuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdHRlbXB0cyB0byBsb2NhdGUgdGhlIHJlcXVlc3RlZCBwYWNrYWdlIGluIHRoZSBjYWxsZXIncyBjbGFzcyBsb2FkZXIuIElmCisgICAgICogbm8gcGFja2FnZSBpbmZvcm1hdGlvbiBjYW4gYmUgbG9jYXRlZCwge0Bjb2RlIG51bGx9IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIHBhY2thZ2VOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcGFja2FnZSB0byBmaW5kLgorICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3RlZCBwYWNrYWdlLCBvciB7QGNvZGUgbnVsbH0uCisgICAgICogQHNlZSBDbGFzc0xvYWRlciNnZXRQYWNrYWdlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBQYWNrYWdlIGdldFBhY2thZ2UoU3RyaW5nIHBhY2thZ2VOYW1lKSB7CisgICAgICAgIENsYXNzTG9hZGVyIGNsYXNzbG9hZGVyID0gVk1TdGFjay5nZXRDYWxsaW5nQ2xhc3NMb2FkZXIoKTsKKyAgICAgICAgaWYgKGNsYXNzbG9hZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIGNsYXNzbG9hZGVyID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2xhc3Nsb2FkZXIuZ2V0UGFja2FnZShwYWNrYWdlTmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbGwgdGhlIHBhY2thZ2VzIGtub3duIHRvIHRoZSBjYWxsZXIncyBjbGFzcyBsb2FkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFsbCB0aGUgcGFja2FnZXMga25vd24gdG8gdGhlIGNhbGxlcidzIGNsYXNzIGxvYWRlci4KKyAgICAgKiBAc2VlIENsYXNzTG9hZGVyI2dldFBhY2thZ2VzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBQYWNrYWdlW10gZ2V0UGFja2FnZXMoKSB7CisgICAgICAgIENsYXNzTG9hZGVyIGNsYXNzbG9hZGVyID0gVk1TdGFjay5nZXRDYWxsaW5nQ2xhc3NMb2FkZXIoKTsKKyAgICAgICAgaWYgKGNsYXNzbG9hZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIGNsYXNzbG9hZGVyID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2xhc3Nsb2FkZXIuZ2V0UGFja2FnZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0aXRsZSBvZiB0aGUgc3BlY2lmaWNhdGlvbiB0aGlzIHBhY2thZ2UgaW1wbGVtZW50cywgb3IKKyAgICAgKiB7QGNvZGUgbnVsbH0gaWYgdGhpcyBpcyB1bmtub3duLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3BlY2lmaWNhdGlvbiB0aXRsZSwgbWF5IGJlIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFNwZWNpZmljYXRpb25UaXRsZSgpIHsKKyAgICAgICAgcmV0dXJuIHNwZWNUaXRsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSB2ZW5kb3Igb3Igb3JnYW5pemF0aW9uIHRoYXQgb3ducyBhbmQgbWFpbnRhaW5zCisgICAgICogdGhlIHNwZWNpZmljYXRpb24gdGhpcyBwYWNrYWdlIGltcGxlbWVudHMsIG9yIHtAY29kZSBudWxsfSBpZiB0aGlzIGlzCisgICAgICogdW5rbm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNwZWNpZmljYXRpb24gdmVuZG9yIG5hbWUsIG1heSBiZSB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTcGVjaWZpY2F0aW9uVmVuZG9yKCkgeworICAgICAgICByZXR1cm4gc3BlY1ZlbmRvcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2ZXJzaW9uIG9mIHRoZSBzcGVjaWZpY2F0aW9uIHRoaXMgcGFja2FnZSBpbXBsZW1lbnRzLCBvcgorICAgICAqIHtAY29kZSBudWxsfSBpZiB0aGlzIGlzIHVua25vd24uIFRoZSB2ZXJzaW9uIHN0cmluZyBpcyBhIHNlcXVlbmNlIG9mCisgICAgICogbm9uLW5lZ2F0aXZlIGludGVnZXJzIHNlcGFyYXRlZCBieSBkb3RzOyBmb3IgZXhhbXBsZTogIjEuMi4zIi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNwZWNpZmljYXRpb24gdmVyc2lvbiBzdHJpbmcsIG1heSBiZSB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTcGVjaWZpY2F0aW9uVmVyc2lvbigpIHsKKyAgICAgICAgcmV0dXJuIHNwZWNWZXJzaW9uOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiBuYW1lLmhhc2hDb2RlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBwYWNrYWdlJ3Mgc3BlY2lmaWNhdGlvbiB2ZXJzaW9uIGlzIGNvbXBhdGlibGUgd2l0aAorICAgICAqIHRoZSBzcGVjaWZpZWQgdmVyc2lvbiBzdHJpbmcuIFZlcnNpb24gc3RyaW5ncyBhcmUgY29tcGFyZWQgYnkgY29tcGFyaW5nCisgICAgICogZWFjaCBkb3Qgc2VwYXJhdGVkIHBhcnQgb2YgdGhlIHZlcnNpb24gYXMgYW4gaW50ZWdlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2ZXJzaW9uCisgICAgICogICAgICAgICAgICB0aGUgdmVyc2lvbiBzdHJpbmcgdG8gY29tcGFyZSBhZ2FpbnN0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBwYWNrYWdlIHZlcnNpb25zIGFyZSBjb21wYXRpYmxlOyB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHBhY2thZ2UncyB2ZXJzaW9uIHN0cmluZyBvciB0aGUgb25lIHByb3ZpZGVkIGFyZSBub3QKKyAgICAgKiAgICAgICAgICAgICBpbiB0aGUgY29ycmVjdCBmb3JtYXQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDb21wYXRpYmxlV2l0aChTdHJpbmcgdmVyc2lvbikgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIHJlcXVlc3RlZCA9IHZlcnNpb24uc3BsaXQoIlxcLiIpOworICAgICAgICBTdHJpbmdbXSBwcm92aWRlZCA9IHNwZWNWZXJzaW9uLnNwbGl0KCJcXC4iKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE1hdGgubWluKHJlcXVlc3RlZC5sZW5ndGgsIHByb3ZpZGVkLmxlbmd0aCk7IGkrKykgeworICAgICAgICAgICAgaW50IHJlcU51bSA9IEludGVnZXIucGFyc2VJbnQocmVxdWVzdGVkW2ldKTsKKyAgICAgICAgICAgIGludCBwcm92TnVtID0gSW50ZWdlci5wYXJzZUludChwcm92aWRlZFtpXSk7CisKKyAgICAgICAgICAgIGlmIChyZXFOdW0gPiBwcm92TnVtKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfSBlbHNlIGlmIChyZXFOdW0gPCBwcm92TnVtKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAocmVxdWVzdGVkLmxlbmd0aCA+IHByb3ZpZGVkLmxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBwYWNrYWdlIGlzIHNlYWxlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgcGFja2FnZSBpcyBzZWFsZWQ7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzU2VhbGVkKCkgeworICAgICAgICByZXR1cm4gc2VhbEJhc2UgIT0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIHBhY2thZ2UgaXMgc2VhbGVkIHdpdGggcmVzcGVjdCB0byB0aGUgc3BlY2lmaWVkCisgICAgICogVVJMLgorICAgICAqCisgICAgICogQHBhcmFtIHVybAorICAgICAqICAgICAgICAgICAgdGhlIFVSTCB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHBhY2thZ2UgaXMgc2VhbGVkIHdpdGgge0Bjb2RlIHVybH07IHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9IG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzU2VhbGVkKFVSTCB1cmwpIHsKKyAgICAgICAgcmV0dXJuIHNlYWxCYXNlICE9IG51bGwgJiYgc2VhbEJhc2Uuc2FtZUZpbGUodXJsKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gInBhY2thZ2UgIiArIG5hbWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Qcm9jZXNzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1Byb2Nlc3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xM2M0ZWQ5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Qcm9jZXNzLmphdmEKQEAgLTAsMCArMSwxMTMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworLyoqCisgKiBSZXByZXNlbnRzIGFuIGV4dGVybmFsIHByb2Nlc3MuIEVuYWJsZXMgd3JpdGluZyB0bywgcmVhZGluZyBmcm9tLCBkZXN0cm95aW5nLAorICogYW5kIHdhaXRpbmcgZm9yIHRoZSBleHRlcm5hbCBwcm9jZXNzLCBhcyB3ZWxsIGFzIHF1ZXJ5aW5nIGl0cyBleGl0IHZhbHVlLiBVc2UKKyAqIHtAbGluayBQcm9jZXNzQnVpbGRlcn0gdG8gY3JlYXRlIHByb2Nlc3Nlcy4KKyAqCisgKiA8cD5UaGUgY2hpbGQgcHJvY2VzcyB3cml0ZXMgaXRzIG91dHB1dCB0byB0d28gc3RyZWFtcywge0Bjb2RlIG91dH0gYW5kCisgKiB7QGNvZGUgZXJyfS4gVGhlc2Ugc3RyZWFtcyBzaG91bGQgYmUgcmVhZCBieSB0aGUgcGFyZW50IHByb2Nlc3MgdXNpbmcge0BsaW5rCisgKiAjZ2V0SW5wdXRTdHJlYW0oKX0gYW5kIHtAbGluayAjZ2V0RXJyb3JTdHJlYW0oKX0gcmVzcGVjdGl2ZWx5LiBJZiB0aGVzZQorICogc3RyZWFtcyBhcmUgbm90IHJlYWQsIHRoZSB0YXJnZXQgcHJvY2VzcyBtYXkgYmxvY2sgd2hpbGUgaXQgYXdhaXRzIGJ1ZmZlcgorICogc3BhY2UuIEl0IGlzbid0IHN1ZmZpY2llbnQgdG8gcmVhZCB0aGUgc3RyZWFtcyBpbiBzZXF1ZW5jZTsgdG8gYXZvaWQgYmxvY2tpbmcKKyAqIGVhY2ggb2YgdGhlIHR3byBzdHJlYW1zIG11c3QgaGF2ZSBpdHMgb3duIHJlYWRlciB0aHJlYWQuIElmIHlvdSBhcmUgbm90CisgKiBpbnRlcmVzdGVkIGluIGRpZmZlcmVudGlhdGluZyB0aGUgb3V0IGFuZCBlcnIgc3RyZWFtcywgdXNlIHtAbGluaworICogUHJvY2Vzc0J1aWxkZXIjcmVkaXJlY3RFcnJvclN0cmVhbShib29sZWFuKSByZWRpcmVjdEVycm9yU3RyZWFtKHRydWUpfSB0bworICogbWVyZ2UgdGhlIHR3byBzdHJlYW1zLiBUaGlzIHNpbXBsaWZpZXMgeW91ciByZWFkaW5nIGNvZGUgYW5kIG1ha2VzIGl0IGVhc2llcgorICogdG8gYXZvaWQgYmxvY2tpbmcgdGhlIHRhcmdldCBwcm9jZXNzLgorICoKKyAqIDxwPlJ1bm5pbmcgcHJvY2Vzc2VzIGhvbGQgcmVzb3VyY2VzLiBXaGVuIGEgcHJvY2VzcyBpcyBubyBsb25nZXIgdXNlZCwgdGhlCisgKiBwcm9jZXNzIHNob3VsZCBiZSBjbG9zZWQgYnkgY2FsbGluZyB7QGxpbmsgI2Rlc3Ryb3l9LiBUaGlzIHdpbGwga2lsbCB0aGUKKyAqIHByb2Nlc3MgYW5kIHJlbGVhc2UgdGhlIHJlc291cmNlcyB0aGF0IGl0IGhvbGRzLgorICoKKyAqIDxwPkZvciBleGFtcGxlLCB0byBydW4ge0Bjb2RlIC9zeXN0ZW0vYmluL3Bpbmd9IHRvIHBpbmcge0Bjb2RlIGFuZHJvaWQuY29tfToKKyAqIDxwcmU+ICAge0Bjb2RlCisgKiAgIFByb2Nlc3MgcHJvY2VzcyA9IG5ldyBQcm9jZXNzQnVpbGRlcigpCisgKiAgICAgICAuY29tbWFuZCgiL3N5c3RlbS9iaW4vcGluZyIsICJhbmRyb2lkLmNvbSIpCisgKiAgICAgICAucmVkaXJlY3RFcnJvclN0cmVhbSh0cnVlKQorICogICAgICAgLnN0YXJ0KCk7CisgKiAgIHRyeSB7CisgKiAgICAgSW5wdXRTdHJlYW0gaW4gPSBwcm9jZXNzLmdldElucHV0U3RyZWFtKCk7CisgKiAgICAgT3V0cHV0U3RyZWFtIG91dCA9IHByb2Nlc3MuZ2V0T3V0cHV0U3RyZWFtKCk7CisgKgorICogICAgIHJlYWRTdHJlYW0oaW4pOworICoKKyAqICAgfSBmaW5hbGx5IHsKKyAqICAgICBwcm9jZXNzLmRlc3Ryb3koKTsKKyAqICAgfQorICogfTwvcHJlPgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgUHJvY2VzcyB7CisKKyAgICAvKioKKyAgICAgKiBUZXJtaW5hdGVzIHRoaXMgcHJvY2VzcyBhbmQgY2xvc2VzIGFueSBhc3NvY2lhdGVkIHN0cmVhbXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZGVzdHJveSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZXhpdCB2YWx1ZSBvZiB0aGUgbmF0aXZlIHByb2Nlc3MgcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3QuCisgICAgICogSXQgaXMgYXZhaWxhYmxlIG9ubHkgd2hlbiB0aGUgbmF0aXZlIHByb2Nlc3MgaGFzIHRlcm1pbmF0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBleGl0IHZhbHVlIG9mIHRoaXMgcHJvY2Vzcy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxUaHJlYWRTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgcHJvY2VzcyBoYXMgbm90IHRlcm1pbmF0ZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBleGl0VmFsdWUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5wdXQgc3RyZWFtIHRoYXQgaXMgY29ubmVjdGVkIHRvIHRoZSBlcnJvciBzdHJlYW0KKyAgICAgKiA8ZW0+KHN0ZGVycik8L2VtPiBvZiB0aGUgbmF0aXZlIHByb2Nlc3MgcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbnB1dCBzdHJlYW0gdG8gcmVhZCBmcm9tIHRoZSBlcnJvciBzdHJlYW0gYXNzb2NpYXRlZCB3aXRoCisgICAgICogICAgICAgICB0aGUgbmF0aXZlIHByb2Nlc3MuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IElucHV0U3RyZWFtIGdldEVycm9yU3RyZWFtKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGlucHV0IHN0cmVhbSB0aGF0IGlzIGNvbm5lY3RlZCB0byB0aGUgc3RhbmRhcmQgb3V0cHV0IHN0cmVhbQorICAgICAqIDxlbT4oc3Rkb3V0KTwvZW0+IG9mIHRoZSBuYXRpdmUgcHJvY2VzcyByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGlucHV0IHN0cmVhbSB0byByZWFkIGZyb20gdGhlIG91dHB1dCBzdHJlYW0gYXNzb2NpYXRlZCB3aXRoCisgICAgICogICAgICAgICB0aGUgbmF0aXZlIHByb2Nlc3MuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIG91dHB1dCBzdHJlYW0gdGhhdCBpcyBjb25uZWN0ZWQgdG8gdGhlIHN0YW5kYXJkIGlucHV0IHN0cmVhbQorICAgICAqIDxlbT4oc3RkaW4pPC9lbT4gb2YgdGhlIG5hdGl2ZSBwcm9jZXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMgb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgb3V0cHV0IHN0cmVhbSB0byB3cml0ZSB0byB0aGUgaW5wdXQgc3RyZWFtIGFzc29jaWF0ZWQgd2l0aAorICAgICAqICAgICAgICAgdGhlIG5hdGl2ZSBwcm9jZXNzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCk7CisKKyAgICAvKioKKyAgICAgKiBDYXVzZXMgdGhlIGNhbGxpbmcgdGhyZWFkIHRvIHdhaXQgZm9yIHRoZSBuYXRpdmUgcHJvY2VzcyBhc3NvY2lhdGVkIHdpdGgKKyAgICAgKiB0aGlzIG9iamVjdCB0byBmaW5pc2ggZXhlY3V0aW5nLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZXhpdCB2YWx1ZSBvZiB0aGUgbmF0aXZlIHByb2Nlc3MgYmVpbmcgd2FpdGVkIG9uLgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2FsbGluZyB0aHJlYWQgaXMgaW50ZXJydXB0ZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCB3YWl0Rm9yKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Qcm9jZXNzQnVpbGRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Qcm9jZXNzQnVpbGRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjViN2VmZGMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1Byb2Nlc3NCdWlsZGVyLmphdmEKQEAgLTAsMCArMSwxOTcgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBDcmVhdGVzIG9wZXJhdGluZyBzeXN0ZW0gcHJvY2Vzc2VzLiBTZWUge0BsaW5rIFByb2Nlc3N9IGZvciBkb2N1bWVudGF0aW9uIGFuZAorICogZXhhbXBsZSB1c2FnZS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFByb2Nlc3NCdWlsZGVyIHsKKworICAgIHByaXZhdGUgTGlzdDxTdHJpbmc+IGNvbW1hbmQ7CisgICAgcHJpdmF0ZSBGaWxlIGRpcmVjdG9yeTsKKyAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFN0cmluZz4gZW52aXJvbm1lbnQ7CisgICAgcHJpdmF0ZSBib29sZWFuIHJlZGlyZWN0RXJyb3JTdHJlYW07CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBQcm9jZXNzQnVpbGRlcn0gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogb3BlcmF0aW5nIHN5c3RlbSBwcm9ncmFtIGFuZCBpdHMgYXJndW1lbnRzLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbW1hbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXF1ZXN0ZWQgb3BlcmF0aW5nIHN5c3RlbSBwcm9ncmFtIGFuZCBpdHMgYXJndW1lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBQcm9jZXNzQnVpbGRlcihTdHJpbmcuLi4gY29tbWFuZCkgeworICAgICAgICB0aGlzKG5ldyBBcnJheUxpc3Q8U3RyaW5nPihBcnJheXMuYXNMaXN0KGNvbW1hbmQpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUHJvY2Vzc0J1aWxkZXJ9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIG9wZXJhdGluZyBzeXN0ZW0gcHJvZ3JhbSBhbmQgaXRzIGFyZ3VtZW50cy4gTm90ZSB0aGF0IHRoZSBsaXN0IHBhc3NlZCB0bworICAgICAqIHRoaXMgY29uc3RydWN0b3IgaXMgbm90IGNvcGllZCwgc28gYW55IHN1YnNlcXVlbnQgdXBkYXRlcyB0byBpdCBhcmUKKyAgICAgKiByZWZsZWN0ZWQgaW4gdGhpcyBpbnN0YW5jZSdzIHN0YXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbW1hbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXF1ZXN0ZWQgb3BlcmF0aW5nIHN5c3RlbSBwcm9ncmFtIGFuZCBpdHMgYXJndW1lbnRzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY29tbWFuZH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBQcm9jZXNzQnVpbGRlcihMaXN0PFN0cmluZz4gY29tbWFuZCkgeworICAgICAgICBpZiAoY29tbWFuZCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmNvbW1hbmQgPSBjb21tYW5kOworCisgICAgICAgIC8vIHVzZSBhIGhhc2h0YWJsZSB0byBwcmV2ZW50IG51bGxzIGZyb20gc25lYWtpbmcgaW4KKyAgICAgICAgdGhpcy5lbnZpcm9ubWVudCA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBTdHJpbmc+KFN5c3RlbS5nZXRlbnYoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHByb2Nlc3MgYnVpbGRlcidzIGN1cnJlbnQgcHJvZ3JhbSBhbmQgYXJndW1lbnRzLiBOb3RlIHRoYXQKKyAgICAgKiB0aGUgcmV0dXJuZWQgbGlzdCBpcyBub3QgYSBjb3B5IGFuZCBtb2RpZmljYXRpb25zIHRvIGl0IHdpbGwgY2hhbmdlIHRoZQorICAgICAqIHN0YXRlIG9mIHRoaXMgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgcHJvY2VzcyBidWlsZGVyJ3MgcHJvZ3JhbSBhbmQgYXJndW1lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBMaXN0PFN0cmluZz4gY29tbWFuZCgpIHsKKyAgICAgICAgcmV0dXJuIGNvbW1hbmQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hhbmdlcyB0aGUgcHJvZ3JhbSBhbmQgYXJndW1lbnRzIG9mIHRoaXMgcHJvY2VzcyBidWlsZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbW1hbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgb3BlcmF0aW5nIHN5c3RlbSBwcm9ncmFtIGFuZCBpdHMgYXJndW1lbnRzLgorICAgICAqIEByZXR1cm4gdGhpcyBwcm9jZXNzIGJ1aWxkZXIgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIFByb2Nlc3NCdWlsZGVyIGNvbW1hbmQoU3RyaW5nLi4uIGNvbW1hbmQpIHsKKyAgICAgICAgcmV0dXJuIGNvbW1hbmQobmV3IEFycmF5TGlzdDxTdHJpbmc+KEFycmF5cy5hc0xpc3QoY29tbWFuZCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGFuZ2VzIHRoZSBwcm9ncmFtIGFuZCBhcmd1bWVudHMgb2YgdGhpcyBwcm9jZXNzIGJ1aWxkZXIuIE5vdGUgdGhhdCB0aGUKKyAgICAgKiBsaXN0IHBhc3NlZCB0byB0aGlzIG1ldGhvZCBpcyBub3QgY29waWVkLCBzbyBhbnkgc3Vic2VxdWVudCB1cGRhdGVzIHRvIGl0CisgICAgICogYXJlIHJlZmxlY3RlZCBpbiB0aGlzIGluc3RhbmNlJ3Mgc3RhdGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29tbWFuZAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBvcGVyYXRpbmcgc3lzdGVtIHByb2dyYW0gYW5kIGl0cyBhcmd1bWVudHMuCisgICAgICogQHJldHVybiB0aGlzIHByb2Nlc3MgYnVpbGRlciBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGNvbW1hbmR9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvY2Vzc0J1aWxkZXIgY29tbWFuZChMaXN0PFN0cmluZz4gY29tbWFuZCkgeworICAgICAgICBpZiAoY29tbWFuZCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmNvbW1hbmQgPSBjb21tYW5kOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB3b3JraW5nIGRpcmVjdG9yeSBvZiB0aGlzIHByb2Nlc3MgYnVpbGRlci4gSWYge0Bjb2RlIG51bGx9IGlzCisgICAgICogcmV0dXJuZWQsIHRoZW4gdGhlIHdvcmtpbmcgZGlyZWN0b3J5IG9mIHRoZSBKYXZhIHByb2Nlc3MgaXMgdXNlZCB3aGVuIGEKKyAgICAgKiBwcm9jZXNzIGlzIHN0YXJ0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5LCBtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBGaWxlIGRpcmVjdG9yeSgpIHsKKyAgICAgICAgcmV0dXJuIGRpcmVjdG9yeTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGFuZ2VzIHRoZSB3b3JraW5nIGRpcmVjdG9yeSBvZiB0aGlzIHByb2Nlc3MgYnVpbGRlci4gSWYgdGhlIHNwZWNpZmllZAorICAgICAqIGRpcmVjdG9yeSBpcyB7QGNvZGUgbnVsbH0sIHRoZW4gdGhlIHdvcmtpbmcgZGlyZWN0b3J5IG9mIHRoZSBKYXZhCisgICAgICogcHJvY2VzcyBpcyB1c2VkIHdoZW4gYSBwcm9jZXNzIGlzIHN0YXJ0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGlyZWN0b3J5CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHdvcmtpbmcgZGlyZWN0b3J5IGZvciB0aGlzIHByb2Nlc3MgYnVpbGRlci4KKyAgICAgKiBAcmV0dXJuIHRoaXMgcHJvY2VzcyBidWlsZGVyIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBQcm9jZXNzQnVpbGRlciBkaXJlY3RvcnkoRmlsZSBkaXJlY3RvcnkpIHsKKyAgICAgICAgdGhpcy5kaXJlY3RvcnkgPSBkaXJlY3Rvcnk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBwcm9jZXNzIGJ1aWxkZXIncyBjdXJyZW50IGVudmlyb25tZW50LiBXaGVuIGEgcHJvY2VzcworICAgICAqIGJ1aWxkZXIgaW5zdGFuY2UgaXMgY3JlYXRlZCwgdGhlIGVudmlyb25tZW50IGlzIHBvcHVsYXRlZCB3aXRoIGEgY29weSBvZgorICAgICAqIHRoZSBlbnZpcm9ubWVudCwgYXMgcmV0dXJuZWQgYnkge0BsaW5rIFN5c3RlbSNnZXRlbnYoKX0uIE5vdGUgdGhhdCB0aGUKKyAgICAgKiBtYXAgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QgaXMgbm90IGEgY29weSBhbmQgYW55IGNoYW5nZXMgbWFkZSB0byBpdCBhcmUKKyAgICAgKiByZWZsZWN0ZWQgaW4gdGhpcyBpbnN0YW5jZSdzIHN0YXRlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWFwIGNvbnRhaW5pbmcgdGhpcyBwcm9jZXNzIGJ1aWxkZXIncyBlbnZpcm9ubWVudCB2YXJpYWJsZXMuCisgICAgICovCisgICAgcHVibGljIE1hcDxTdHJpbmcsIFN0cmluZz4gZW52aXJvbm1lbnQoKSB7CisgICAgICAgIHJldHVybiBlbnZpcm9ubWVudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3RhbmRhcmQgZXJyb3Igc2hvdWxkIGJlIHJlZGlyZWN0ZWQgdG8gc3RhbmRhcmQKKyAgICAgKiBvdXRwdXQuIElmIHJlZGlyZWN0ZWQsIHRoZSB7QGxpbmsgUHJvY2VzcyNnZXRFcnJvclN0cmVhbSgpfSB3aWxsIGFsd2F5cworICAgICAqIHJldHVybiBlbmQgb2Ygc3RyZWFtIGFuZCBzdGFuZGFyZCBlcnJvciBpcyB3cml0dGVuIHRvCisgICAgICoge0BsaW5rIFByb2Nlc3MjZ2V0SW5wdXRTdHJlYW0oKX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3RhbmRhcmQgZXJyb3IgaXMgcmVkaXJlY3RlZDsge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlZGlyZWN0RXJyb3JTdHJlYW0oKSB7CisgICAgICAgIHJldHVybiByZWRpcmVjdEVycm9yU3RyZWFtOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoYW5nZXMgdGhlIHN0YXRlIG9mIHdoZXRoZXIgb3Igbm90IHN0YW5kYXJkIGVycm9yIGlzIHJlZGlyZWN0ZWQgdG8KKyAgICAgKiBzdGFuZGFyZCBvdXRwdXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVkaXJlY3RFcnJvclN0cmVhbQorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IHRvIHJlZGlyZWN0IHN0YW5kYXJkIGVycm9yLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHJldHVybiB0aGlzIHByb2Nlc3MgYnVpbGRlciBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvY2Vzc0J1aWxkZXIgcmVkaXJlY3RFcnJvclN0cmVhbShib29sZWFuIHJlZGlyZWN0RXJyb3JTdHJlYW0pIHsKKyAgICAgICAgdGhpcy5yZWRpcmVjdEVycm9yU3RyZWFtID0gcmVkaXJlY3RFcnJvclN0cmVhbTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3RhcnRzIGEgbmV3IHByb2Nlc3MgYmFzZWQgb24gdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhpcyBwcm9jZXNzIGJ1aWxkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcge0Bjb2RlIFByb2Nlc3N9IGluc3RhbmNlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgb2YgdGhlIGVsZW1lbnRzIG9mIHtAbGluayAjY29tbWFuZCgpfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0BsaW5rICNjb21tYW5kKCl9IGlzIGVtcHR5LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvY2VzcyBzdGFydCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFdlIHB1c2ggcmVzcG9uc2liaWxpdHkgZm9yIGFyZ3VtZW50IGNoZWNraW5nIGludG8gUHJvY2Vzc01hbmFnZXIuCisgICAgICAgIFN0cmluZ1tdIGNtZEFycmF5ID0gY29tbWFuZC50b0FycmF5KG5ldyBTdHJpbmdbY29tbWFuZC5zaXplKCldKTsKKyAgICAgICAgU3RyaW5nW10gZW52QXJyYXkgPSBuZXcgU3RyaW5nW2Vudmlyb25tZW50LnNpemUoKV07CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBTdHJpbmc+IGVudHJ5IDogZW52aXJvbm1lbnQuZW50cnlTZXQoKSkgeworICAgICAgICAgICAgZW52QXJyYXlbaSsrXSA9IGVudHJ5LmdldEtleSgpICsgIj0iICsgZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gUHJvY2Vzc01hbmFnZXIuZ2V0SW5zdGFuY2UoKS5leGVjKGNtZEFycmF5LCBlbnZBcnJheSwgZGlyZWN0b3J5LCByZWRpcmVjdEVycm9yU3RyZWFtKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1Byb2Nlc3NNYW5hZ2VyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1Byb2Nlc3NNYW5hZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzQ4MDE4NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvUHJvY2Vzc01hbmFnZXIuamF2YQpAQCAtMCwwICsxLDM4OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmLlJlZmVyZW5jZVF1ZXVlOworaW1wb3J0IGphdmEubGFuZy5yZWYuV2Vha1JlZmVyZW5jZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgbGliY29yZS5pby5FcnJub0V4Y2VwdGlvbjsKK2ltcG9ydCBsaWJjb3JlLmlvLklvVXRpbHM7CitpbXBvcnQgbGliY29yZS5pby5MaWJjb3JlOworaW1wb3J0IGxpYmNvcmUudXRpbC5NdXRhYmxlSW50OworaW1wb3J0IHN0YXRpYyBsaWJjb3JlLmlvLk9zQ29uc3RhbnRzLio7CisKKy8qKgorICogTWFuYWdlcyBjaGlsZCBwcm9jZXNzZXMuCisgKi8KK2ZpbmFsIGNsYXNzIFByb2Nlc3NNYW5hZ2VyIHsKKyAgICAvKioKKyAgICAgKiBNYXAgZnJvbSBwaWQgdG8gUHJvY2Vzcy4gV2Uga2VlcCB3ZWFrIHJlZmVyZW5jZXMgdG8gdGhlIFByb2Nlc3Mgb2JqZWN0cworICAgICAqIGFuZCBjbGVhbiB1cCB0aGUgZW50cmllcyB3aGVuIG5vIG1vcmUgZXh0ZXJuYWwgcmVmZXJlbmNlcyBhcmUgbGVmdC4gVGhlCisgICAgICogcHJvY2VzcyBvYmplY3RzIHRoZW1zZWx2ZXMgZG9uJ3QgcmVxdWlyZSBtdWNoIG1lbW9yeSwgYnV0IGZpbGUKKyAgICAgKiBkZXNjcmlwdG9ycyAoYXNzb2NpYXRlZCB3aXRoIHN0ZGluL3N0ZG91dC9zdGRlcnIgaW4gdGhpcyBjYXNlKSBjYW4gYmUKKyAgICAgKiBhIHNjYXJjZSByZXNvdXJjZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIE1hcDxJbnRlZ2VyLCBQcm9jZXNzUmVmZXJlbmNlPiBwcm9jZXNzUmVmZXJlbmNlcworICAgICAgICAgICAgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBQcm9jZXNzUmVmZXJlbmNlPigpOworCisgICAgLyoqIEtlZXBzIHRyYWNrIG9mIGdhcmJhZ2UtY29sbGVjdGVkIFByb2Nlc3Nlcy4gKi8KKyAgICBwcml2YXRlIGZpbmFsIFByb2Nlc3NSZWZlcmVuY2VRdWV1ZSByZWZlcmVuY2VRdWV1ZSA9IG5ldyBQcm9jZXNzUmVmZXJlbmNlUXVldWUoKTsKKworICAgIHByaXZhdGUgUHJvY2Vzc01hbmFnZXIoKSB7CisgICAgICAgIC8vIFNwYXduIGEgdGhyZWFkIHRvIGxpc3RlbiBmb3Igc2lnbmFscyBmcm9tIGNoaWxkIHByb2Nlc3Nlcy4KKyAgICAgICAgVGhyZWFkIHJlYXBlclRocmVhZCA9IG5ldyBUaHJlYWQoUHJvY2Vzc01hbmFnZXIuY2xhc3MuZ2V0TmFtZSgpKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHdhdGNoQ2hpbGRyZW4oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgcmVhcGVyVGhyZWFkLnNldERhZW1vbih0cnVlKTsKKyAgICAgICAgcmVhcGVyVGhyZWFkLnN0YXJ0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xlYW5zIHVwIGFmdGVyIGdhcmJhZ2UgY29sbGVjdGVkIHByb2Nlc3Nlcy4gUmVxdWlyZXMgdGhlIGxvY2sgb24gdGhlCisgICAgICogbWFwLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjbGVhblVwKCkgeworICAgICAgICBQcm9jZXNzUmVmZXJlbmNlIHJlZmVyZW5jZTsKKyAgICAgICAgd2hpbGUgKChyZWZlcmVuY2UgPSByZWZlcmVuY2VRdWV1ZS5wb2xsKCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAocHJvY2Vzc1JlZmVyZW5jZXMpIHsKKyAgICAgICAgICAgICAgICBwcm9jZXNzUmVmZXJlbmNlcy5yZW1vdmUocmVmZXJlbmNlLnByb2Nlc3NJZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb29wcyBpbmRlZmluaXRlbHkgYW5kIGNhbGxzIFByb2Nlc3NNYW5hZ2VyLm9uRXhpdCgpIHdoZW4gY2hpbGRyZW4gZXhpdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd2F0Y2hDaGlsZHJlbigpIHsKKyAgICAgICAgTXV0YWJsZUludCBzdGF0dXMgPSBuZXcgTXV0YWJsZUludCgtMSk7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIFdhaXQgZm9yIGNoaWxkcmVuIGluIG91ciBwcm9jZXNzIGdyb3VwLgorICAgICAgICAgICAgICAgIGludCBwaWQgPSBMaWJjb3JlLm9zLndhaXRwaWQoMCwgc3RhdHVzLCAwKTsKKworICAgICAgICAgICAgICAgIC8vIFdvcmsgb3V0IHdoYXQgb25FeGl0IHdhbnRzIHRvIGhlYXIuCisgICAgICAgICAgICAgICAgaW50IGV4aXRWYWx1ZTsKKyAgICAgICAgICAgICAgICBpZiAoV0lGRVhJVEVEKHN0YXR1cy52YWx1ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgZXhpdFZhbHVlID0gV0VYSVRTVEFUVVMoc3RhdHVzLnZhbHVlKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFdJRlNJR05BTEVEKHN0YXR1cy52YWx1ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgZXhpdFZhbHVlID0gV1RFUk1TSUcoc3RhdHVzLnZhbHVlKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFdJRlNUT1BQRUQoc3RhdHVzLnZhbHVlKSkgeworICAgICAgICAgICAgICAgICAgICBleGl0VmFsdWUgPSBXU1RPUFNJRyhzdGF0dXMudmFsdWUpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigidW5leHBlY3RlZCBzdGF0dXMgZnJvbSB3YWl0cGlkOiAiICsgc3RhdHVzLnZhbHVlKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBvbkV4aXQocGlkLCBleGl0VmFsdWUpOworICAgICAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICBpZiAoZXJybm9FeGNlcHRpb24uZXJybm8gPT0gRUNISUxEKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIEV4cGVjdGVkIGVycm5vOiB0aGVyZSBhcmUgbm8gY2hpbGRyZW4gdG8gd2FpdCBmb3IuCisgICAgICAgICAgICAgICAgICAgIC8vIG9uRXhpdCB3aWxsIHNsZWVwIHVudGlsIGl0IGlzIGluZm9ybWVkIG9mIGFub3RoZXIgY2hpbGQgY29taW5nIHRvIGxpZmUuCisgICAgICAgICAgICAgICAgICAgIHdhaXRGb3JNb3JlQ2hpbGRyZW4oKTsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGVycm5vRXhjZXB0aW9uKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxsZWQgYnkge0BsaW5rICN3YXRjaENoaWxkcmVuKCl9IHdoZW4gYSBjaGlsZCBwcm9jZXNzIGV4aXRzLgorICAgICAqCisgICAgICogQHBhcmFtIHBpZCBJRCBvZiBwcm9jZXNzIHRoYXQgZXhpdGVkCisgICAgICogQHBhcmFtIGV4aXRWYWx1ZSB2YWx1ZSB0aGUgcHJvY2VzcyByZXR1cm5lZCB1cG9uIGV4aXQKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgb25FeGl0KGludCBwaWQsIGludCBleGl0VmFsdWUpIHsKKyAgICAgICAgUHJvY2Vzc1JlZmVyZW5jZSBwcm9jZXNzUmVmZXJlbmNlID0gbnVsbDsKKyAgICAgICAgc3luY2hyb25pemVkIChwcm9jZXNzUmVmZXJlbmNlcykgeworICAgICAgICAgICAgY2xlYW5VcCgpOworICAgICAgICAgICAgcHJvY2Vzc1JlZmVyZW5jZSA9IHByb2Nlc3NSZWZlcmVuY2VzLnJlbW92ZShwaWQpOworICAgICAgICB9CisgICAgICAgIGlmIChwcm9jZXNzUmVmZXJlbmNlICE9IG51bGwpIHsKKyAgICAgICAgICAgIFByb2Nlc3NJbXBsIHByb2Nlc3MgPSBwcm9jZXNzUmVmZXJlbmNlLmdldCgpOworICAgICAgICAgICAgaWYgKHByb2Nlc3MgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHByb2Nlc3Muc2V0RXhpdFZhbHVlKGV4aXRWYWx1ZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd2FpdEZvck1vcmVDaGlsZHJlbigpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChwcm9jZXNzUmVmZXJlbmNlcykgeworICAgICAgICAgICAgaWYgKHByb2Nlc3NSZWZlcmVuY2VzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIC8vIFRoZXJlIGFyZSBubyBlbGlnaWJsZSBjaGlsZHJlbjsgd2FpdCBmb3Igb25lIHRvIGJlIGFkZGVkLgorICAgICAgICAgICAgICAgIC8vIFRoaXMgd2FpdCB3aWxsIHJldHVybiBiZWNhdXNlIG9mIHRoZSBub3RpZnlBbGwgY2FsbCBpbiBleGVjLgorICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NSZWZlcmVuY2VzLndhaXQoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW4uCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigidW5leHBlY3RlZCBpbnRlcnJ1cHQiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogQSBuZXcgY2hpbGQgd2FzIHNwYXduZWQganVzdCBiZWZvcmUgd2UgZW50ZXJlZAorICAgICAgICAgICAgICAgICAqIHRoZSBzeW5jaHJvbml6ZWQgYmxvY2suIFdlIGNhbiBqdXN0IGZhbGwgdGhyb3VnaAorICAgICAgICAgICAgICAgICAqIHdpdGhvdXQgZG9pbmcgYW55dGhpbmcgc3BlY2lhbCBhbmQgbGFuZCBiYWNrIGluCisgICAgICAgICAgICAgICAgICogdGhlIG5hdGl2ZSB3YWl0cGlkKCkuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeGVjdXRlcyBhIG5hdGl2ZSBwcm9jZXNzLiBGaWxscyBpbiBpbiwgb3V0LCBhbmQgZXJyIGFuZCByZXR1cm5zIHRoZQorICAgICAqIG5ldyBwcm9jZXNzIElEIHVwb24gc3VjY2Vzcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IGV4ZWMoU3RyaW5nW10gY29tbWFuZCwgU3RyaW5nW10gZW52aXJvbm1lbnQsCisgICAgICAgICAgICBTdHJpbmcgd29ya2luZ0RpcmVjdG9yeSwgRmlsZURlc2NyaXB0b3IgaW4sIEZpbGVEZXNjcmlwdG9yIG91dCwKKyAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yIGVyciwgYm9vbGVhbiByZWRpcmVjdEVycm9yU3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBFeGVjdXRlcyBhIHByb2Nlc3MgYW5kIHJldHVybnMgYW4gb2JqZWN0IHJlcHJlc2VudGluZyBpdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvY2VzcyBleGVjKFN0cmluZ1tdIHRhaW50ZWRDb21tYW5kLCBTdHJpbmdbXSB0YWludGVkRW52aXJvbm1lbnQsIEZpbGUgd29ya2luZ0RpcmVjdG9yeSwKKyAgICAgICAgICAgIGJvb2xlYW4gcmVkaXJlY3RFcnJvclN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gTWFrZSBzdXJlIHdlIHRocm93IHRoZSBzYW1lIGV4Y2VwdGlvbnMgYXMgdGhlIFJJLgorICAgICAgICBpZiAodGFpbnRlZENvbW1hbmQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRhaW50ZWRDb21tYW5kLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgLy8gSGFuZGxlIHNlY3VyaXR5IGFuZCBzYWZldHkgYnkgY29weWluZyBtdXRhYmxlIGlucHV0cyBhbmQgY2hlY2tpbmcgdGhlbS4KKyAgICAgICAgU3RyaW5nW10gY29tbWFuZCA9IHRhaW50ZWRDb21tYW5kLmNsb25lKCk7CisgICAgICAgIFN0cmluZ1tdIGVudmlyb25tZW50ID0gdGFpbnRlZEVudmlyb25tZW50ICE9IG51bGwgPyB0YWludGVkRW52aXJvbm1lbnQuY2xvbmUoKSA6IG51bGw7CisKKyAgICAgICAgLy8gQ2hlY2sgd2UncmUgbm90IHBhc3NpbmcgbnVsbCBTdHJpbmdzIHRvIHRoZSBuYXRpdmUgZXhlYy4KKyAgICAgICAgZm9yIChTdHJpbmcgYXJnIDogY29tbWFuZCkgeworICAgICAgICAgICAgaWYgKGFyZyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gVGhlIGVudmlyb25tZW50IGlzIGFsbG93ZWQgdG8gYmUgbnVsbCBvciBlbXB0eSwgYnV0IG5vIGVsZW1lbnQgbWF5IGJlIG51bGwuCisgICAgICAgIGlmIChlbnZpcm9ubWVudCAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKFN0cmluZyBlbnYgOiBlbnZpcm9ubWVudCkgeworICAgICAgICAgICAgICAgIGlmIChlbnYgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBGaWxlRGVzY3JpcHRvciBpbiA9IG5ldyBGaWxlRGVzY3JpcHRvcigpOworICAgICAgICBGaWxlRGVzY3JpcHRvciBvdXQgPSBuZXcgRmlsZURlc2NyaXB0b3IoKTsKKyAgICAgICAgRmlsZURlc2NyaXB0b3IgZXJyID0gbmV3IEZpbGVEZXNjcmlwdG9yKCk7CisKKyAgICAgICAgU3RyaW5nIHdvcmtpbmdQYXRoID0gKHdvcmtpbmdEaXJlY3RvcnkgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICA/IG51bGwKKyAgICAgICAgICAgICAgICA6IHdvcmtpbmdEaXJlY3RvcnkuZ2V0UGF0aCgpOworCisgICAgICAgIC8vIEVuc3VyZSBvbkV4aXQoKSBkb2Vzbid0IGFjY2VzcyB0aGUgcHJvY2VzcyBtYXAgYmVmb3JlIHdlIGFkZCBvdXIKKyAgICAgICAgLy8gZW50cnkuCisgICAgICAgIHN5bmNocm9uaXplZCAocHJvY2Vzc1JlZmVyZW5jZXMpIHsKKyAgICAgICAgICAgIGludCBwaWQ7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBpZCA9IGV4ZWMoY29tbWFuZCwgZW52aXJvbm1lbnQsIHdvcmtpbmdQYXRoLCBpbiwgb3V0LCBlcnIsIHJlZGlyZWN0RXJyb3JTdHJlYW0pOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIElPRXhjZXB0aW9uIHdyYXBwZXIgPSBuZXcgSU9FeGNlcHRpb24oIkVycm9yIHJ1bm5pbmcgZXhlYygpLiIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiBDb21tYW5kOiAiICsgQXJyYXlzLnRvU3RyaW5nKGNvbW1hbmQpCisgICAgICAgICAgICAgICAgICAgICAgICArICIgV29ya2luZyBEaXJlY3Rvcnk6ICIgKyB3b3JraW5nRGlyZWN0b3J5CisgICAgICAgICAgICAgICAgICAgICAgICArICIgRW52aXJvbm1lbnQ6ICIgKyBBcnJheXMudG9TdHJpbmcoZW52aXJvbm1lbnQpKTsKKyAgICAgICAgICAgICAgICB3cmFwcGVyLmluaXRDYXVzZShlKTsKKyAgICAgICAgICAgICAgICB0aHJvdyB3cmFwcGVyOworICAgICAgICAgICAgfQorICAgICAgICAgICAgUHJvY2Vzc0ltcGwgcHJvY2VzcyA9IG5ldyBQcm9jZXNzSW1wbChwaWQsIGluLCBvdXQsIGVycik7CisgICAgICAgICAgICBQcm9jZXNzUmVmZXJlbmNlIHByb2Nlc3NSZWZlcmVuY2UgPSBuZXcgUHJvY2Vzc1JlZmVyZW5jZShwcm9jZXNzLCByZWZlcmVuY2VRdWV1ZSk7CisgICAgICAgICAgICBwcm9jZXNzUmVmZXJlbmNlcy5wdXQocGlkLCBwcm9jZXNzUmVmZXJlbmNlKTsKKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFRoaXMgd2lsbCB3YWtlIHVwIHRoZSBjaGlsZCBtb25pdG9yIHRocmVhZCBpbiBjYXNlIHRoZXJlCisgICAgICAgICAgICAgKiB3ZXJlbid0IHByZXZpb3VzbHkgYW55IGNoaWxkcmVuIHRvIHdhaXQgb24uCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHByb2Nlc3NSZWZlcmVuY2VzLm5vdGlmeUFsbCgpOworCisgICAgICAgICAgICByZXR1cm4gcHJvY2VzczsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBQcm9jZXNzSW1wbCBleHRlbmRzIFByb2Nlc3MgeworICAgICAgICBwcml2YXRlIGZpbmFsIGludCBwaWQ7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBJbnB1dFN0cmVhbSBlcnJvclN0cmVhbTsKKworICAgICAgICAvKiogUmVhZHMgb3V0cHV0IGZyb20gcHJvY2Vzcy4gKi8KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbTsKKworICAgICAgICAvKiogU2VuZHMgb3V0cHV0IHRvIHByb2Nlc3MuICovCisgICAgICAgIHByaXZhdGUgZmluYWwgT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbTsKKworICAgICAgICAvKiogVGhlIHByb2Nlc3MncyBleGl0IHZhbHVlLiAqLworICAgICAgICBwcml2YXRlIEludGVnZXIgZXhpdFZhbHVlID0gbnVsbDsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgZXhpdFZhbHVlTXV0ZXggPSBuZXcgT2JqZWN0KCk7CisKKyAgICAgICAgUHJvY2Vzc0ltcGwoaW50IHBpZCwgRmlsZURlc2NyaXB0b3IgaW4sIEZpbGVEZXNjcmlwdG9yIG91dCwgRmlsZURlc2NyaXB0b3IgZXJyKSB7CisgICAgICAgICAgICB0aGlzLnBpZCA9IHBpZDsKKworICAgICAgICAgICAgdGhpcy5lcnJvclN0cmVhbSA9IG5ldyBQcm9jZXNzSW5wdXRTdHJlYW0oZXJyKTsKKyAgICAgICAgICAgIHRoaXMuaW5wdXRTdHJlYW0gPSBuZXcgUHJvY2Vzc0lucHV0U3RyZWFtKGluKTsKKyAgICAgICAgICAgIHRoaXMub3V0cHV0U3RyZWFtID0gbmV3IFByb2Nlc3NPdXRwdXRTdHJlYW0ob3V0KTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGRlc3Ryb3koKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIExpYmNvcmUub3Mua2lsbChwaWQsIFNJR0tJTEwpOworICAgICAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5sb2dJKCJGYWlsZWQgdG8gZGVzdHJveSBwcm9jZXNzICIgKyBwaWQsIGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkoaW5wdXRTdHJlYW0pOworICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkoZXJyb3JTdHJlYW0pOworICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkob3V0cHV0U3RyZWFtKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZXhpdFZhbHVlKCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChleGl0VmFsdWVNdXRleCkgeworICAgICAgICAgICAgICAgIGlmIChleGl0VmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQcm9jZXNzIGhhcyBub3QgeWV0IHRlcm1pbmF0ZWQuIik7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcmV0dXJuIGV4aXRWYWx1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRFcnJvclN0cmVhbSgpIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzLmVycm9yU3RyZWFtOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5wdXRTdHJlYW07CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT3V0cHV0U3RyZWFtIGdldE91dHB1dFN0cmVhbSgpIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzLm91dHB1dFN0cmVhbTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgd2FpdEZvcigpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGV4aXRWYWx1ZU11dGV4KSB7CisgICAgICAgICAgICAgICAgd2hpbGUgKGV4aXRWYWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGV4aXRWYWx1ZU11dGV4LndhaXQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGV4aXRWYWx1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHZvaWQgc2V0RXhpdFZhbHVlKGludCBleGl0VmFsdWUpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoZXhpdFZhbHVlTXV0ZXgpIHsKKyAgICAgICAgICAgICAgICB0aGlzLmV4aXRWYWx1ZSA9IGV4aXRWYWx1ZTsKKyAgICAgICAgICAgICAgICBleGl0VmFsdWVNdXRleC5ub3RpZnlBbGwoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuICJQcm9jZXNzW3BpZD0iICsgcGlkICsgIl0iOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFByb2Nlc3NSZWZlcmVuY2UgZXh0ZW5kcyBXZWFrUmVmZXJlbmNlPFByb2Nlc3NJbXBsPiB7CisKKyAgICAgICAgZmluYWwgaW50IHByb2Nlc3NJZDsKKworICAgICAgICBwdWJsaWMgUHJvY2Vzc1JlZmVyZW5jZShQcm9jZXNzSW1wbCByZWZlcmVudCwgUHJvY2Vzc1JlZmVyZW5jZVF1ZXVlIHJlZmVyZW5jZVF1ZXVlKSB7CisgICAgICAgICAgICBzdXBlcihyZWZlcmVudCwgcmVmZXJlbmNlUXVldWUpOworICAgICAgICAgICAgdGhpcy5wcm9jZXNzSWQgPSByZWZlcmVudC5waWQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgUHJvY2Vzc1JlZmVyZW5jZVF1ZXVlIGV4dGVuZHMgUmVmZXJlbmNlUXVldWU8UHJvY2Vzc0ltcGw+IHsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFByb2Nlc3NSZWZlcmVuY2UgcG9sbCgpIHsKKyAgICAgICAgICAgIC8vIFdoeSBjb3VsZG4ndCB0aGV5IGdldCB0aGUgZ2VuZXJpY3MgcmlnaHQgb24gUmVmZXJlbmNlUXVldWU/IDooCisgICAgICAgICAgICBPYmplY3QgcmVmZXJlbmNlID0gc3VwZXIucG9sbCgpOworICAgICAgICAgICAgcmV0dXJuIChQcm9jZXNzUmVmZXJlbmNlKSByZWZlcmVuY2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQcm9jZXNzTWFuYWdlciBpbnN0YW5jZSA9IG5ldyBQcm9jZXNzTWFuYWdlcigpOworCisgICAgLyoqIEdldHMgdGhlIHByb2Nlc3MgbWFuYWdlci4gKi8KKyAgICBwdWJsaWMgc3RhdGljIFByb2Nlc3NNYW5hZ2VyIGdldEluc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gaW5zdGFuY2U7CisgICAgfQorCisgICAgLyoqIEF1dG9tYXRpY2FsbHkgY2xvc2VzIGZkIHdoZW4gY29sbGVjdGVkLiAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFByb2Nlc3NJbnB1dFN0cmVhbSBleHRlbmRzIEZpbGVJbnB1dFN0cmVhbSB7CisKKyAgICAgICAgcHJpdmF0ZSBGaWxlRGVzY3JpcHRvciBmZDsKKworICAgICAgICBwcml2YXRlIFByb2Nlc3NJbnB1dFN0cmVhbShGaWxlRGVzY3JpcHRvciBmZCkgeworICAgICAgICAgICAgc3VwZXIoZmQpOworICAgICAgICAgICAgdGhpcy5mZCA9IGZkOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3VwZXIuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBJb1V0aWxzLmNsb3NlKGZkKTsKKyAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZkID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKiBBdXRvbWF0aWNhbGx5IGNsb3NlcyBmZCB3aGVuIGNvbGxlY3RlZC4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBQcm9jZXNzT3V0cHV0U3RyZWFtIGV4dGVuZHMgRmlsZU91dHB1dFN0cmVhbSB7CisKKyAgICAgICAgcHJpdmF0ZSBGaWxlRGVzY3JpcHRvciBmZDsKKworICAgICAgICBwcml2YXRlIFByb2Nlc3NPdXRwdXRTdHJlYW0oRmlsZURlc2NyaXB0b3IgZmQpIHsKKyAgICAgICAgICAgIHN1cGVyKGZkKTsKKyAgICAgICAgICAgIHRoaXMuZmQgPSBmZDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN1cGVyLmNsb3NlKCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgSW9VdGlscy5jbG9zZShmZCk7CisgICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmZCA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1JlYWRhYmxlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1JlYWRhYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjkwMWU3MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvUmVhZGFibGUuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQ2hhckJ1ZmZlcjsKKworLyoqCisgKiBSZXByZXNlbnRzIGEgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyB0aGF0IGNhbiBiZSBpbmNyZW1lbnRhbGx5IHJlYWQgKGNvcGllZCkKKyAqIGludG8gYSB7QGxpbmsgQ2hhckJ1ZmZlcn0uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUmVhZGFibGUgeworCisgICAgLyoqCisgICAgICogUmVhZHMgY2hhcmFjdGVycyBpbnRvIHRoZSBzcGVjaWZpZWQge0Bjb2RlIENoYXJCdWZmZXJ9LiBUaGUgbWF4aW11bQorICAgICAqIG51bWJlciBvZiBjaGFyYWN0ZXJzIHJlYWQgaXMge0Bjb2RlIENoYXJCdWZmZXIucmVtYWluaW5nKCl9LgorICAgICAqCisgICAgICogQHBhcmFtIGNiCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHRvIGJlIGZpbGxlZCB3aXRoIGNoYXJhY3RlcnMgcmVhZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBhY3R1YWxseSByZWFkLCBvciAtMSBpZiB0aGlzCisgICAgICogICAgICAgICB7QGNvZGUgUmVhZGFibGV9IHJlYWNoZXMgaXRzIGVuZAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIGludCByZWFkKENoYXJCdWZmZXIgY2IpIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvUmVhbFRvU3RyaW5nLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1JlYWxUb1N0cmluZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMxMjAzZWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1JlYWxUb1N0cmluZy5qYXZhCkBAIC0wLDAgKzEsMzIwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworaW1wb3J0IGxpYmNvcmUubWF0aC5NYXRoVXRpbHM7CisKK2ZpbmFsIGNsYXNzIFJlYWxUb1N0cmluZyB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVGhyZWFkTG9jYWw8UmVhbFRvU3RyaW5nPiBJTlNUQU5DRSA9IG5ldyBUaHJlYWRMb2NhbDxSZWFsVG9TdHJpbmc+KCkgeworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIFJlYWxUb1N0cmluZyBpbml0aWFsVmFsdWUoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFJlYWxUb1N0cmluZygpOworICAgICAgICB9CisgICAgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGRvdWJsZSBpbnZMb2dPZlRlbkJhc2VUd28gPSBNYXRoLmxvZygyLjApIC8gTWF0aC5sb2coMTAuMCk7CisKKyAgICBwcml2YXRlIGludCBmaXJzdEs7CisKKyAgICAvKioKKyAgICAgKiBBbiBhcnJheSBvZiBkZWNpbWFsIGRpZ2l0cywgZmlsbGVkIGJ5IGxvbmdEaWdpdEdlbmVyYXRvciBvciBiaWdJbnREaWdpdEdlbmVyYXRvci4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludFtdIGRpZ2l0cyA9IG5ldyBpbnRbNjRdOworCisgICAgLyoqCisgICAgICogTnVtYmVyIG9mIHZhbGlkIGVudHJpZXMgaW4gJ2RpZ2l0cycuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgZGlnaXRDb3VudDsKKworICAgIHByaXZhdGUgUmVhbFRvU3RyaW5nKCkgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgUmVhbFRvU3RyaW5nIGdldEluc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gSU5TVEFOQ0UuZ2V0KCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHJlc3VsdE9yU2lkZUVmZmVjdChBYnN0cmFjdFN0cmluZ0J1aWxkZXIgc2IsIFN0cmluZyBzKSB7CisgICAgICAgIGlmIChzYiAhPSBudWxsKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQwKHMpOworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHM7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBkb3VibGVUb1N0cmluZyhkb3VibGUgZCkgeworICAgICAgICByZXR1cm4gY29udmVydERvdWJsZShudWxsLCBkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhcHBlbmREb3VibGUoQWJzdHJhY3RTdHJpbmdCdWlsZGVyIHNiLCBkb3VibGUgZCkgeworICAgICAgICBjb252ZXJ0RG91YmxlKHNiLCBkKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyBjb252ZXJ0RG91YmxlKEFic3RyYWN0U3RyaW5nQnVpbGRlciBzYiwgZG91YmxlIGlucHV0TnVtYmVyKSB7CisgICAgICAgIGxvbmcgaW5wdXROdW1iZXJCaXRzID0gRG91YmxlLmRvdWJsZVRvUmF3TG9uZ0JpdHMoaW5wdXROdW1iZXIpOworICAgICAgICBib29sZWFuIHBvc2l0aXZlID0gKGlucHV0TnVtYmVyQml0cyAmIERvdWJsZS5TSUdOX01BU0spID09IDA7CisgICAgICAgIGludCBlID0gKGludCkgKChpbnB1dE51bWJlckJpdHMgJiBEb3VibGUuRVhQT05FTlRfTUFTSykgPj4gRG91YmxlLk1BTlRJU1NBX0JJVFMpOworICAgICAgICBsb25nIGYgPSBpbnB1dE51bWJlckJpdHMgJiBEb3VibGUuTUFOVElTU0FfTUFTSzsKKyAgICAgICAgYm9vbGVhbiBtYW50aXNzYUlzWmVybyA9IGYgPT0gMDsKKworICAgICAgICBTdHJpbmcgcXVpY2tSZXN1bHQgPSBudWxsOworICAgICAgICBpZiAoZSA9PSAyMDQ3KSB7CisgICAgICAgICAgICBpZiAobWFudGlzc2FJc1plcm8pIHsKKyAgICAgICAgICAgICAgICBxdWlja1Jlc3VsdCA9IHBvc2l0aXZlID8gIkluZmluaXR5IiA6ICItSW5maW5pdHkiOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBxdWlja1Jlc3VsdCA9ICJOYU4iOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKGUgPT0gMCkgeworICAgICAgICAgICAgaWYgKG1hbnRpc3NhSXNaZXJvKSB7CisgICAgICAgICAgICAgICAgcXVpY2tSZXN1bHQgPSBwb3NpdGl2ZSA/ICIwLjAiIDogIi0wLjAiOworICAgICAgICAgICAgfSBlbHNlIGlmIChmID09IDEpIHsKKyAgICAgICAgICAgICAgICAvLyBzcGVjaWFsIGNhc2UgdG8gaW5jcmVhc2UgcHJlY2lzaW9uIGV2ZW4gdGhvdWdoIDIgKiBEb3VibGUuTUlOX1ZBTFVFIGlzIDEuMGUtMzIzCisgICAgICAgICAgICAgICAgcXVpY2tSZXN1bHQgPSBwb3NpdGl2ZSA/ICI0LjlFLTMyNCIgOiAiLTQuOUUtMzI0IjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAocXVpY2tSZXN1bHQgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdE9yU2lkZUVmZmVjdChzYiwgcXVpY2tSZXN1bHQpOworICAgICAgICB9CisKKyAgICAgICAgaW50IHAgPSBEb3VibGUuRVhQT05FTlRfQklBUyArIERvdWJsZS5NQU5USVNTQV9CSVRTOyAvLyB0aGUgcG93ZXIgb2Zmc2V0IChwcmVjaXNpb24pCisgICAgICAgIGludCBwb3c7CisgICAgICAgIGludCBudW1CaXRzID0gRG91YmxlLk1BTlRJU1NBX0JJVFM7CisgICAgICAgIGlmIChlID09IDApIHsKKyAgICAgICAgICAgIHBvdyA9IDEgLSBwOyAvLyBhIGRlbm9ybWFsaXplZCBudW1iZXIKKyAgICAgICAgICAgIGxvbmcgZmYgPSBmOworICAgICAgICAgICAgd2hpbGUgKChmZiAmIDB4MDAxMDAwMDAwMDAwMDAwMEwpID09IDApIHsKKyAgICAgICAgICAgICAgICBmZiA9IGZmIDw8IDE7CisgICAgICAgICAgICAgICAgbnVtQml0cy0tOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gMCA8IGUgPCAyMDQ3CisgICAgICAgICAgICAvLyBhICJub3JtYWxpemVkIiBudW1iZXIKKyAgICAgICAgICAgIGYgPSBmIHwgMHgwMDEwMDAwMDAwMDAwMDAwTDsKKyAgICAgICAgICAgIHBvdyA9IGUgLSBwOworICAgICAgICB9CisKKyAgICAgICAgZmlyc3RLID0gZGlnaXRDb3VudCA9IDA7CisgICAgICAgIGlmICgtNTkgPCBwb3cgJiYgcG93IDwgNiB8fCAocG93ID09IC01OSAmJiAhbWFudGlzc2FJc1plcm8pKSB7CisgICAgICAgICAgICBsb25nRGlnaXRHZW5lcmF0b3IoZiwgcG93LCBlID09IDAsIG1hbnRpc3NhSXNaZXJvLCBudW1CaXRzKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJpZ0ludERpZ2l0R2VuZXJhdG9yKGYsIHBvdywgZSA9PSAwLCBudW1CaXRzKTsKKyAgICAgICAgfQorICAgICAgICBBYnN0cmFjdFN0cmluZ0J1aWxkZXIgZHN0ID0gKHNiICE9IG51bGwpID8gc2IgOiBuZXcgU3RyaW5nQnVpbGRlcigyNik7CisgICAgICAgIGlmIChpbnB1dE51bWJlciA+PSAxZTdEIHx8IGlucHV0TnVtYmVyIDw9IC0xZTdECisgICAgICAgICAgICAgICAgfHwgKGlucHV0TnVtYmVyID4gLTFlLTNEICYmIGlucHV0TnVtYmVyIDwgMWUtM0QpKSB7CisgICAgICAgICAgICBmcmVlRm9ybWF0RXhwb25lbnRpYWwoZHN0LCBwb3NpdGl2ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmcmVlRm9ybWF0KGRzdCwgcG9zaXRpdmUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoc2IgIT0gbnVsbCkgPyBudWxsIDogZHN0LnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBmbG9hdFRvU3RyaW5nKGZsb2F0IGYpIHsKKyAgICAgICAgcmV0dXJuIGNvbnZlcnRGbG9hdChudWxsLCBmKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhcHBlbmRGbG9hdChBYnN0cmFjdFN0cmluZ0J1aWxkZXIgc2IsIGZsb2F0IGYpIHsKKyAgICAgICAgY29udmVydEZsb2F0KHNiLCBmKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGNvbnZlcnRGbG9hdChBYnN0cmFjdFN0cmluZ0J1aWxkZXIgc2IsIGZsb2F0IGlucHV0TnVtYmVyKSB7CisgICAgICAgIGludCBpbnB1dE51bWJlckJpdHMgPSBGbG9hdC5mbG9hdFRvUmF3SW50Qml0cyhpbnB1dE51bWJlcik7CisgICAgICAgIGJvb2xlYW4gcG9zaXRpdmUgPSAoaW5wdXROdW1iZXJCaXRzICYgRmxvYXQuU0lHTl9NQVNLKSA9PSAwOworICAgICAgICBpbnQgZSA9IChpbnB1dE51bWJlckJpdHMgJiBGbG9hdC5FWFBPTkVOVF9NQVNLKSA+PiBGbG9hdC5NQU5USVNTQV9CSVRTOworICAgICAgICBpbnQgZiA9IGlucHV0TnVtYmVyQml0cyAmIEZsb2F0Lk1BTlRJU1NBX01BU0s7CisgICAgICAgIGJvb2xlYW4gbWFudGlzc2FJc1plcm8gPSBmID09IDA7CisKKyAgICAgICAgU3RyaW5nIHF1aWNrUmVzdWx0ID0gbnVsbDsKKyAgICAgICAgaWYgKGUgPT0gMjU1KSB7CisgICAgICAgICAgICBpZiAobWFudGlzc2FJc1plcm8pIHsKKyAgICAgICAgICAgICAgICBxdWlja1Jlc3VsdCA9IHBvc2l0aXZlID8gIkluZmluaXR5IiA6ICItSW5maW5pdHkiOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBxdWlja1Jlc3VsdCA9ICJOYU4iOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKGUgPT0gMCAmJiBtYW50aXNzYUlzWmVybykgeworICAgICAgICAgICAgcXVpY2tSZXN1bHQgPSBwb3NpdGl2ZSA/ICIwLjAiIDogIi0wLjAiOworICAgICAgICB9CisgICAgICAgIGlmIChxdWlja1Jlc3VsdCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0T3JTaWRlRWZmZWN0KHNiLCBxdWlja1Jlc3VsdCk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgcCA9IEZsb2F0LkVYUE9ORU5UX0JJQVMgKyBGbG9hdC5NQU5USVNTQV9CSVRTOyAvLyB0aGUgcG93ZXIgb2Zmc2V0IChwcmVjaXNpb24pCisgICAgICAgIGludCBwb3c7CisgICAgICAgIGludCBudW1CaXRzID0gRmxvYXQuTUFOVElTU0FfQklUUzsKKyAgICAgICAgaWYgKGUgPT0gMCkgeworICAgICAgICAgICAgcG93ID0gMSAtIHA7IC8vIGEgZGVub3JtYWxpemVkIG51bWJlcgorICAgICAgICAgICAgaWYgKGYgPCA4KSB7IC8vIHdhbnQgbW9yZSBwcmVjaXNpb24gd2l0aCBzbWFsbGVzdCB2YWx1ZXMKKyAgICAgICAgICAgICAgICBmID0gZiA8PCAyOworICAgICAgICAgICAgICAgIHBvdyAtPSAyOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IGZmID0gZjsKKyAgICAgICAgICAgIHdoaWxlICgoZmYgJiAweDAwODAwMDAwKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgZmYgPSBmZiA8PCAxOworICAgICAgICAgICAgICAgIG51bUJpdHMtLTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIDAgPCBlIDwgMjU1CisgICAgICAgICAgICAvLyBhICJub3JtYWxpemVkIiBudW1iZXIKKyAgICAgICAgICAgIGYgPSBmIHwgMHgwMDgwMDAwMDsKKyAgICAgICAgICAgIHBvdyA9IGUgLSBwOworICAgICAgICB9CisKKyAgICAgICAgZmlyc3RLID0gZGlnaXRDb3VudCA9IDA7CisgICAgICAgIGlmICgtNTkgPCBwb3cgJiYgcG93IDwgMzUgfHwgKHBvdyA9PSAtNTkgJiYgIW1hbnRpc3NhSXNaZXJvKSkgeworICAgICAgICAgICAgbG9uZ0RpZ2l0R2VuZXJhdG9yKGYsIHBvdywgZSA9PSAwLCBtYW50aXNzYUlzWmVybywgbnVtQml0cyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBiaWdJbnREaWdpdEdlbmVyYXRvcihmLCBwb3csIGUgPT0gMCwgbnVtQml0cyk7CisgICAgICAgIH0KKyAgICAgICAgQWJzdHJhY3RTdHJpbmdCdWlsZGVyIGRzdCA9IChzYiAhPSBudWxsKSA/IHNiIDogbmV3IFN0cmluZ0J1aWxkZXIoMjYpOworICAgICAgICBpZiAoaW5wdXROdW1iZXIgPj0gMWU3ZiB8fCBpbnB1dE51bWJlciA8PSAtMWU3ZgorICAgICAgICAgICAgICAgIHx8IChpbnB1dE51bWJlciA+IC0xZS0zZiAmJiBpbnB1dE51bWJlciA8IDFlLTNmKSkgeworICAgICAgICAgICAgZnJlZUZvcm1hdEV4cG9uZW50aWFsKGRzdCwgcG9zaXRpdmUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZnJlZUZvcm1hdChkc3QsIHBvc2l0aXZlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKHNiICE9IG51bGwpID8gbnVsbCA6IGRzdC50b1N0cmluZygpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBmcmVlRm9ybWF0RXhwb25lbnRpYWwoQWJzdHJhY3RTdHJpbmdCdWlsZGVyIHNiLCBib29sZWFuIHBvc2l0aXZlKSB7CisgICAgICAgIGludCBkaWdpdEluZGV4ID0gMDsKKyAgICAgICAgaWYgKCFwb3NpdGl2ZSkgeworICAgICAgICAgICAgc2IuYXBwZW5kMCgnLScpOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZDAoKGNoYXIpICgnMCcgKyBkaWdpdHNbZGlnaXRJbmRleCsrXSkpOworICAgICAgICBzYi5hcHBlbmQwKCcuJyk7CisKKyAgICAgICAgaW50IGsgPSBmaXJzdEs7CisgICAgICAgIGludCBleHBvbmVudCA9IGs7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBrLS07CisgICAgICAgICAgICBpZiAoZGlnaXRJbmRleCA+PSBkaWdpdENvdW50KSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzYi5hcHBlbmQwKChjaGFyKSAoJzAnICsgZGlnaXRzW2RpZ2l0SW5kZXgrK10pKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChrID09IGV4cG9uZW50IC0gMSkgeworICAgICAgICAgICAgc2IuYXBwZW5kMCgnMCcpOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZDAoJ0UnKTsKKyAgICAgICAgSW50ZWdyYWxUb1N0cmluZy5hcHBlbmRJbnQoc2IsIGV4cG9uZW50KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZnJlZUZvcm1hdChBYnN0cmFjdFN0cmluZ0J1aWxkZXIgc2IsIGJvb2xlYW4gcG9zaXRpdmUpIHsKKyAgICAgICAgaW50IGRpZ2l0SW5kZXggPSAwOworICAgICAgICBpZiAoIXBvc2l0aXZlKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQwKCctJyk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGsgPSBmaXJzdEs7CisgICAgICAgIGlmIChrIDwgMCkgeworICAgICAgICAgICAgc2IuYXBwZW5kMCgnMCcpOworICAgICAgICAgICAgc2IuYXBwZW5kMCgnLicpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IGsgKyAxOyBpIDwgMDsgKytpKSB7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kMCgnMCcpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGludCBVID0gZGlnaXRzW2RpZ2l0SW5kZXgrK107CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGlmIChVICE9IC0xKSB7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kMCgoY2hhcikgKCcwJyArIFUpKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoayA+PSAtMSkgeworICAgICAgICAgICAgICAgIHNiLmFwcGVuZDAoJzAnKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChrID09IDApIHsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQwKCcuJyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBrLS07CisgICAgICAgICAgICBVID0gZGlnaXRJbmRleCA8IGRpZ2l0Q291bnQgPyBkaWdpdHNbZGlnaXRJbmRleCsrXSA6IC0xOworICAgICAgICB9IHdoaWxlIChVICE9IC0xIHx8IGsgPj0gLTEpOworICAgIH0KKworICAgIHByaXZhdGUgbmF0aXZlIHZvaWQgYmlnSW50RGlnaXRHZW5lcmF0b3IobG9uZyBmLCBpbnQgZSwgYm9vbGVhbiBpc0Rlbm9ybWFsaXplZCwgaW50IHApOworCisgICAgcHJpdmF0ZSB2b2lkIGxvbmdEaWdpdEdlbmVyYXRvcihsb25nIGYsIGludCBlLCBib29sZWFuIGlzRGVub3JtYWxpemVkLAorICAgICAgICAgICAgYm9vbGVhbiBtYW50aXNzYUlzWmVybywgaW50IHApIHsKKyAgICAgICAgbG9uZyBSLCBTLCBNOworICAgICAgICBpZiAoZSA+PSAwKSB7CisgICAgICAgICAgICBNID0gMWwgPDwgZTsKKyAgICAgICAgICAgIGlmICghbWFudGlzc2FJc1plcm8pIHsKKyAgICAgICAgICAgICAgICBSID0gZiA8PCAoZSArIDEpOworICAgICAgICAgICAgICAgIFMgPSAyOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBSID0gZiA8PCAoZSArIDIpOworICAgICAgICAgICAgICAgIFMgPSA0OworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgTSA9IDE7CisgICAgICAgICAgICBpZiAoaXNEZW5vcm1hbGl6ZWQgfHwgIW1hbnRpc3NhSXNaZXJvKSB7CisgICAgICAgICAgICAgICAgUiA9IGYgPDwgMTsKKyAgICAgICAgICAgICAgICBTID0gMWwgPDwgKDEgLSBlKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgUiA9IGYgPDwgMjsKKyAgICAgICAgICAgICAgICBTID0gMWwgPDwgKDIgLSBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGludCBrID0gKGludCkgTWF0aC5jZWlsKChlICsgcCAtIDEpICogaW52TG9nT2ZUZW5CYXNlVHdvIC0gMWUtMTApOworCisgICAgICAgIGlmIChrID4gMCkgeworICAgICAgICAgICAgUyA9IFMgKiBNYXRoVXRpbHMuTE9OR19QT1dFUlNfT0ZfVEVOW2tdOworICAgICAgICB9IGVsc2UgaWYgKGsgPCAwKSB7CisgICAgICAgICAgICBsb25nIHNjYWxlID0gTWF0aFV0aWxzLkxPTkdfUE9XRVJTX09GX1RFTlsta107CisgICAgICAgICAgICBSID0gUiAqIHNjYWxlOworICAgICAgICAgICAgTSA9IE0gPT0gMSA/IHNjYWxlIDogTSAqIHNjYWxlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKFIgKyBNID4gUykgeyAvLyB3YXMgTV9wbHVzCisgICAgICAgICAgICBmaXJzdEsgPSBrOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmlyc3RLID0gayAtIDE7CisgICAgICAgICAgICBSID0gUiAqIDEwOworICAgICAgICAgICAgTSA9IE0gKiAxMDsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gbG93LCBoaWdoOworICAgICAgICBpbnQgVTsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIC8vIFNldCBVIHRvIGZsb29yKFIvUykgYW5kIFIgdG8gdGhlIHJlbWFpbmRlciwgdXNpbmcgKnVuc2lnbmVkKiA2NC1iaXQgZGl2aXNpb24KKyAgICAgICAgICAgIFUgPSAwOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDM7IGkgPj0gMDsgaS0tKSB7CisgICAgICAgICAgICAgICAgbG9uZyByZW1haW5kZXIgPSBSIC0gKFMgPDwgaSk7CisgICAgICAgICAgICAgICAgaWYgKHJlbWFpbmRlciA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIFIgPSByZW1haW5kZXI7CisgICAgICAgICAgICAgICAgICAgIFUgKz0gMSA8PCBpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgbG93ID0gUiA8IE07IC8vIHdhcyBNX21pbnVzCisgICAgICAgICAgICBoaWdoID0gUiArIE0gPiBTOyAvLyB3YXMgTV9wbHVzCisKKyAgICAgICAgICAgIGlmIChsb3cgfHwgaGlnaCkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgUiA9IFIgKiAxMDsKKyAgICAgICAgICAgIE0gPSBNICogMTA7CisgICAgICAgICAgICBkaWdpdHNbZGlnaXRDb3VudCsrXSA9IFU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxvdyAmJiAhaGlnaCkgeworICAgICAgICAgICAgZGlnaXRzW2RpZ2l0Q291bnQrK10gPSBVOworICAgICAgICB9IGVsc2UgaWYgKGhpZ2ggJiYgIWxvdykgeworICAgICAgICAgICAgZGlnaXRzW2RpZ2l0Q291bnQrK10gPSBVICsgMTsKKyAgICAgICAgfSBlbHNlIGlmICgoUiA8PCAxKSA8IFMpIHsKKyAgICAgICAgICAgIGRpZ2l0c1tkaWdpdENvdW50KytdID0gVTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGRpZ2l0c1tkaWdpdENvdW50KytdID0gVSArIDE7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1J1bm5hYmxlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1J1bm5hYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjA5ZDkxNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvUnVubmFibGUuamF2YQpAQCAtMCwwICsxLDMzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworCisvKioKKyAqIFJlcHJlc2VudHMgYSBjb21tYW5kIHRoYXQgY2FuIGJlIGV4ZWN1dGVkLiBPZnRlbiB1c2VkIHRvIHJ1biBjb2RlIGluIGEKKyAqIGRpZmZlcmVudCB7QGxpbmsgVGhyZWFkfS4KKyAqLworcHVibGljIGludGVyZmFjZSBSdW5uYWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBTdGFydHMgZXhlY3V0aW5nIHRoZSBhY3RpdmUgcGFydCBvZiB0aGUgY2xhc3MnIGNvZGUuIFRoaXMgbWV0aG9kIGlzCisgICAgICogY2FsbGVkIHdoZW4gYSB0aHJlYWQgaXMgc3RhcnRlZCB0aGF0IGhhcyBiZWVuIGNyZWF0ZWQgd2l0aCBhIGNsYXNzIHdoaWNoCisgICAgICogaW1wbGVtZW50cyB7QGNvZGUgUnVubmFibGV9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJ1bigpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9SdW50aW1lLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1J1bnRpbWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iM2EwNzk2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9SdW50aW1lLmphdmEKQEAgLTAsMCArMSw2MTYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgZGFsdmlrLnN5c3RlbS5WTURlYnVnOworaW1wb3J0IGRhbHZpay5zeXN0ZW0uVk1TdGFjazsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW1Xcml0ZXI7CitpbXBvcnQgamF2YS5sYW5nLnJlZi5GaW5hbGl6ZXJSZWZlcmVuY2U7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOworaW1wb3J0IGxpYmNvcmUuaW8uTGliY29yZTsKK2ltcG9ydCBzdGF0aWMgbGliY29yZS5pby5Pc0NvbnN0YW50cy5fU0NfTlBST0NFU1NPUlNfT05MTjsKKworLyoqCisgKiBBbGxvd3MgSmF2YSBhcHBsaWNhdGlvbnMgdG8gaW50ZXJmYWNlIHdpdGggdGhlIGVudmlyb25tZW50IGluIHdoaWNoIHRoZXkgYXJlCisgKiBydW5uaW5nLiBBcHBsaWNhdGlvbnMgY2FuIG5vdCBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcywgYnV0IHRoZXkgY2FuCisgKiBnZXQgYSBzaW5nbGV0b24gaW5zdGFuY2UgYnkgaW52b2tpbmcge0BsaW5rICNnZXRSdW50aW1lKCl9LgorICoKKyAqIEBzZWUgU3lzdGVtCisgKi8KK3B1YmxpYyBjbGFzcyBSdW50aW1lIHsKKworICAgIC8qKgorICAgICAqIEhvbGRzIHRoZSBTaW5nbGV0b24gZ2xvYmFsIGluc3RhbmNlIG9mIFJ1bnRpbWUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUnVudGltZSBtUnVudGltZSA9IG5ldyBSdW50aW1lKCk7CisKKyAgICAvKioKKyAgICAgKiBIb2xkcyB0aGUgbGlicmFyeSBwYXRocywgdXNlZCBmb3IgbmF0aXZlIGxpYnJhcnkgbG9va3VwLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nW10gbUxpYlBhdGhzOworCisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIGxpc3Qgb2YgdGhyZWFkcyB0byBydW4gd2hlbiB0aGUgVk0gdGVybWluYXRlcworICAgICAqLworICAgIHByaXZhdGUgTGlzdDxUaHJlYWQ+IHNodXRkb3duSG9va3MgPSBuZXcgQXJyYXlMaXN0PFRocmVhZD4oKTsKKworICAgIC8qKgorICAgICAqIFJlZmxlY3RzIHdoZXRoZXIgZmluYWxpemF0aW9uIHNob3VsZCBiZSBydW4gZm9yIGFsbCBvYmplY3RzCisgICAgICogd2hlbiB0aGUgVk0gdGVybWluYXRlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGZpbmFsaXplT25FeGl0OworCisgICAgLyoqCisgICAgICogUmVmbGVjdHMgd2hldGhlciB3ZSBhcmUgYWxyZWFkeSBzaHV0dGluZyBkb3duIHRoZSBWTS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gc2h1dHRpbmdEb3duOworCisgICAgLyoqCisgICAgICogUmVmbGVjdHMgd2hldGhlciB3ZSBhcmUgdHJhY2luZyBtZXRob2QgY2FsbHMuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIHRyYWNpbmdNZXRob2RzOworCisgICAgLyoqCisgICAgICogUHJldmVudCB0aGlzIGNsYXNzIGZyb20gYmVpbmcgaW5zdGFudGlhdGVkLgorICAgICAqLworICAgIHByaXZhdGUgUnVudGltZSgpeworICAgICAgICBTdHJpbmcgcGF0aExpc3QgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEubGlicmFyeS5wYXRoIiwgIi4iKTsKKyAgICAgICAgU3RyaW5nIHBhdGhTZXAgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoInBhdGguc2VwYXJhdG9yIiwgIjoiKTsKKyAgICAgICAgU3RyaW5nIGZpbGVTZXAgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImZpbGUuc2VwYXJhdG9yIiwgIi8iKTsKKworICAgICAgICBtTGliUGF0aHMgPSBwYXRoTGlzdC5zcGxpdChwYXRoU2VwKTsKKworICAgICAgICAvLyBBZGQgYSAnLycgdG8gdGhlIGVuZCBzbyB3ZSBkb24ndCBoYXZlIHRvIGRvIHRoZSBwcm9wZXJ0eSBsb29rdXAKKyAgICAgICAgLy8gYW5kIGNvbmNhdGVuYXRpb24gbGF0ZXIuCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbUxpYlBhdGhzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoIW1MaWJQYXRoc1tpXS5lbmRzV2l0aChmaWxlU2VwKSkgeworICAgICAgICAgICAgICAgIG1MaWJQYXRoc1tpXSArPSBmaWxlU2VwOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRXhlY3V0ZXMgdGhlIHNwZWNpZmllZCBjb21tYW5kIGFuZCBpdHMgYXJndW1lbnRzIGluIGEgc2VwYXJhdGUgbmF0aXZlCisgICAgICogcHJvY2Vzcy4gVGhlIG5ldyBwcm9jZXNzIGluaGVyaXRzIHRoZSBlbnZpcm9ubWVudCBvZiB0aGUgY2FsbGVyLiBDYWxsaW5nCisgICAgICogdGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byBjYWxsaW5nIHtAY29kZSBleGVjKHByb2dBcnJheSwgbnVsbCwgbnVsbCl9LgorICAgICAqCisgICAgICogQHBhcmFtIHByb2dBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IGNvbnRhaW5pbmcgdGhlIHByb2dyYW0gdG8gZXhlY3V0ZSBhcyB3ZWxsIGFzIGFueQorICAgICAqICAgICAgICAgICAgYXJndW1lbnRzIHRvIHRoZSBwcm9ncmFtLgorICAgICAqIEByZXR1cm4gdGhlIG5ldyB7QGNvZGUgUHJvY2Vzc30gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgbmF0aXZlCisgICAgICogICAgICAgICBwcm9jZXNzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcmVxdWVzdGVkIHByb2dyYW0gY2FuIG5vdCBiZSBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvY2VzcyBleGVjKFN0cmluZ1tdIHByb2dBcnJheSkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZXhlYyhwcm9nQXJyYXksIG51bGwsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4ZWN1dGVzIHRoZSBzcGVjaWZpZWQgY29tbWFuZCBhbmQgaXRzIGFyZ3VtZW50cyBpbiBhIHNlcGFyYXRlIG5hdGl2ZQorICAgICAqIHByb2Nlc3MuIFRoZSBuZXcgcHJvY2VzcyB1c2VzIHRoZSBlbnZpcm9ubWVudCBwcm92aWRlZCBpbiB7QGNvZGUgZW52cH0uCisgICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIGNhbGxpbmcKKyAgICAgKiB7QGNvZGUgZXhlYyhwcm9nQXJyYXksIGVudnAsIG51bGwpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcm9nQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBjb250YWluaW5nIHRoZSBwcm9ncmFtIHRvIGV4ZWN1dGUgYXMgd2VsbCBhcyBhbnkKKyAgICAgKiAgICAgICAgICAgIGFyZ3VtZW50cyB0byB0aGUgcHJvZ3JhbS4KKyAgICAgKiBAcGFyYW0gZW52cAorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IGNvbnRhaW5pbmcgdGhlIGVudmlyb25tZW50IHRvIHN0YXJ0IHRoZSBuZXcgcHJvY2VzcworICAgICAqICAgICAgICAgICAgaW4uCisgICAgICogQHJldHVybiB0aGUgbmV3IHtAY29kZSBQcm9jZXNzfSBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBuYXRpdmUKKyAgICAgKiAgICAgICAgIHByb2Nlc3MuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSByZXF1ZXN0ZWQgcHJvZ3JhbSBjYW4gbm90IGJlIGV4ZWN1dGVkLgorICAgICAqLworICAgIHB1YmxpYyBQcm9jZXNzIGV4ZWMoU3RyaW5nW10gcHJvZ0FycmF5LCBTdHJpbmdbXSBlbnZwKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBleGVjKHByb2dBcnJheSwgZW52cCwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXhlY3V0ZXMgdGhlIHNwZWNpZmllZCBjb21tYW5kIGFuZCBpdHMgYXJndW1lbnRzIGluIGEgc2VwYXJhdGUgbmF0aXZlCisgICAgICogcHJvY2Vzcy4gVGhlIG5ldyBwcm9jZXNzIHVzZXMgdGhlIGVudmlyb25tZW50IHByb3ZpZGVkIGluIHtAY29kZSBlbnZwfQorICAgICAqIGFuZCB0aGUgd29ya2luZyBkaXJlY3Rvcnkgc3BlY2lmaWVkIGJ5IHtAY29kZSBkaXJlY3Rvcnl9LgorICAgICAqCisgICAgICogQHBhcmFtIHByb2dBcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IGNvbnRhaW5pbmcgdGhlIHByb2dyYW0gdG8gZXhlY3V0ZSBhcyB3ZWxsIGFzIGFueQorICAgICAqICAgICAgICAgICAgYXJndW1lbnRzIHRvIHRoZSBwcm9ncmFtLgorICAgICAqIEBwYXJhbSBlbnZwCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgY29udGFpbmluZyB0aGUgZW52aXJvbm1lbnQgdG8gc3RhcnQgdGhlIG5ldyBwcm9jZXNzCisgICAgICogICAgICAgICAgICBpbi4KKyAgICAgKiBAcGFyYW0gZGlyZWN0b3J5CisgICAgICogICAgICAgICAgICB0aGUgZGlyZWN0b3J5IGluIHdoaWNoIHRvIGV4ZWN1dGUgdGhlIHByb2dyYW0uIElmIHtAY29kZSBudWxsfSwKKyAgICAgKiAgICAgICAgICAgIGV4ZWN1dGUgaWYgaW4gdGhlIHNhbWUgZGlyZWN0b3J5IGFzIHRoZSBwYXJlbnQgcHJvY2Vzcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcge0Bjb2RlIFByb2Nlc3N9IG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIG5hdGl2ZQorICAgICAqICAgICAgICAgcHJvY2Vzcy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHJlcXVlc3RlZCBwcm9ncmFtIGNhbiBub3QgYmUgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHVibGljIFByb2Nlc3MgZXhlYyhTdHJpbmdbXSBwcm9nQXJyYXksIFN0cmluZ1tdIGVudnAsIEZpbGUgZGlyZWN0b3J5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBQcm9jZXNzTWFuYWdlciBpcyByZXNwb25zaWJsZSBmb3IgYWxsIGFyZ3VtZW50IGNoZWNraW5nLgorICAgICAgICByZXR1cm4gUHJvY2Vzc01hbmFnZXIuZ2V0SW5zdGFuY2UoKS5leGVjKHByb2dBcnJheSwgZW52cCwgZGlyZWN0b3J5LCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXhlY3V0ZXMgdGhlIHNwZWNpZmllZCBwcm9ncmFtIGluIGEgc2VwYXJhdGUgbmF0aXZlIHByb2Nlc3MuIFRoZSBuZXcKKyAgICAgKiBwcm9jZXNzIGluaGVyaXRzIHRoZSBlbnZpcm9ubWVudCBvZiB0aGUgY2FsbGVyLiBDYWxsaW5nIHRoaXMgbWV0aG9kIGlzCisgICAgICogZXF1aXZhbGVudCB0byBjYWxsaW5nIHtAY29kZSBleGVjKHByb2csIG51bGwsIG51bGwpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcm9nCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcHJvZ3JhbSB0byBleGVjdXRlLgorICAgICAqIEByZXR1cm4gdGhlIG5ldyB7QGNvZGUgUHJvY2Vzc30gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgbmF0aXZlCisgICAgICogICAgICAgICBwcm9jZXNzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcmVxdWVzdGVkIHByb2dyYW0gY2FuIG5vdCBiZSBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvY2VzcyBleGVjKFN0cmluZyBwcm9nKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBleGVjKHByb2csIG51bGwsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4ZWN1dGVzIHRoZSBzcGVjaWZpZWQgcHJvZ3JhbSBpbiBhIHNlcGFyYXRlIG5hdGl2ZSBwcm9jZXNzLiBUaGUgbmV3CisgICAgICogcHJvY2VzcyB1c2VzIHRoZSBlbnZpcm9ubWVudCBwcm92aWRlZCBpbiB7QGNvZGUgZW52cH0uIENhbGxpbmcgdGhpcworICAgICAqIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIGNhbGxpbmcge0Bjb2RlIGV4ZWMocHJvZywgZW52cCwgbnVsbCl9LgorICAgICAqCisgICAgICogQHBhcmFtIHByb2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBwcm9ncmFtIHRvIGV4ZWN1dGUuCisgICAgICogQHBhcmFtIGVudnAKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBjb250YWluaW5nIHRoZSBlbnZpcm9ubWVudCB0byBzdGFydCB0aGUgbmV3IHByb2Nlc3MKKyAgICAgKiAgICAgICAgICAgIGluLgorICAgICAqIEByZXR1cm4gdGhlIG5ldyB7QGNvZGUgUHJvY2Vzc30gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgbmF0aXZlCisgICAgICogICAgICAgICBwcm9jZXNzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcmVxdWVzdGVkIHByb2dyYW0gY2FuIG5vdCBiZSBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvY2VzcyBleGVjKFN0cmluZyBwcm9nLCBTdHJpbmdbXSBlbnZwKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBleGVjKHByb2csIGVudnAsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4ZWN1dGVzIHRoZSBzcGVjaWZpZWQgcHJvZ3JhbSBpbiBhIHNlcGFyYXRlIG5hdGl2ZSBwcm9jZXNzLiBUaGUgbmV3CisgICAgICogcHJvY2VzcyB1c2VzIHRoZSBlbnZpcm9ubWVudCBwcm92aWRlZCBpbiB7QGNvZGUgZW52cH0gYW5kIHRoZSB3b3JraW5nCisgICAgICogZGlyZWN0b3J5IHNwZWNpZmllZCBieSB7QGNvZGUgZGlyZWN0b3J5fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcm9nCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcHJvZ3JhbSB0byBleGVjdXRlLgorICAgICAqIEBwYXJhbSBlbnZwCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgY29udGFpbmluZyB0aGUgZW52aXJvbm1lbnQgdG8gc3RhcnQgdGhlIG5ldyBwcm9jZXNzCisgICAgICogICAgICAgICAgICBpbi4KKyAgICAgKiBAcGFyYW0gZGlyZWN0b3J5CisgICAgICogICAgICAgICAgICB0aGUgZGlyZWN0b3J5IGluIHdoaWNoIHRvIGV4ZWN1dGUgdGhlIHByb2dyYW0uIElmIHtAY29kZSBudWxsfSwKKyAgICAgKiAgICAgICAgICAgIGV4ZWN1dGUgaWYgaW4gdGhlIHNhbWUgZGlyZWN0b3J5IGFzIHRoZSBwYXJlbnQgcHJvY2Vzcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcge0Bjb2RlIFByb2Nlc3N9IG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIG5hdGl2ZQorICAgICAqICAgICAgICAgcHJvY2Vzcy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHJlcXVlc3RlZCBwcm9ncmFtIGNhbiBub3QgYmUgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHVibGljIFByb2Nlc3MgZXhlYyhTdHJpbmcgcHJvZywgU3RyaW5nW10gZW52cCwgRmlsZSBkaXJlY3RvcnkpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gU2FuaXR5IGNoZWNrcworICAgICAgICBpZiAocHJvZyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfSBlbHNlIGlmIChwcm9nLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEJyZWFrIGRvd24gaW50byB0b2tlbnMsIGFzIGRlc2NyaWJlZCBpbiBKYXZhIGRvY3MKKyAgICAgICAgU3RyaW5nVG9rZW5pemVyIHRva2VuaXplciA9IG5ldyBTdHJpbmdUb2tlbml6ZXIocHJvZyk7CisgICAgICAgIGludCBsZW5ndGggPSB0b2tlbml6ZXIuY291bnRUb2tlbnMoKTsKKyAgICAgICAgU3RyaW5nW10gcHJvZ0FycmF5ID0gbmV3IFN0cmluZ1tsZW5ndGhdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBwcm9nQXJyYXlbaV0gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBEZWxlZ2F0ZQorICAgICAgICByZXR1cm4gZXhlYyhwcm9nQXJyYXksIGVudnAsIGRpcmVjdG9yeSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2F1c2VzIHRoZSBWTSB0byBzdG9wIHJ1bm5pbmcgYW5kIHRoZSBwcm9ncmFtIHRvIGV4aXQuIElmCisgICAgICoge0BsaW5rICNydW5GaW5hbGl6ZXJzT25FeGl0KGJvb2xlYW4pfSBoYXMgYmVlbiBwcmV2aW91c2x5IGludm9rZWQgd2l0aCBhCisgICAgICoge0Bjb2RlIHRydWV9IGFyZ3VtZW50LCB0aGVuIGFsbCBvYmplY3RzIHdpbGwgYmUgcHJvcGVybHkKKyAgICAgKiBnYXJiYWdlLWNvbGxlY3RlZCBhbmQgZmluYWxpemVkIGZpcnN0LgorICAgICAqCisgICAgICogQHBhcmFtIGNvZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXR1cm4gY29kZS4gQnkgY29udmVudGlvbiwgbm9uLXplcm8gcmV0dXJuIGNvZGVzIGluZGljYXRlCisgICAgICogICAgICAgICAgICBhYm5vcm1hbCB0ZXJtaW5hdGlvbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZXhpdChpbnQgY29kZSkgeworICAgICAgICAvLyBNYWtlIHN1cmUgd2UgZG9uJ3QgdHJ5IHRoaXMgc2V2ZXJhbCB0aW1lcworICAgICAgICBzeW5jaHJvbml6ZWQodGhpcykgeworICAgICAgICAgICAgaWYgKCFzaHV0dGluZ0Rvd24pIHsKKyAgICAgICAgICAgICAgICBzaHV0dGluZ0Rvd24gPSB0cnVlOworCisgICAgICAgICAgICAgICAgVGhyZWFkW10gaG9va3M7CisgICAgICAgICAgICAgICAgc3luY2hyb25pemVkIChzaHV0ZG93bkhvb2tzKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBhIGNvcHkgb2YgdGhlIGhvb2tzCisgICAgICAgICAgICAgICAgICAgIGhvb2tzID0gbmV3IFRocmVhZFtzaHV0ZG93bkhvb2tzLnNpemUoKV07CisgICAgICAgICAgICAgICAgICAgIHNodXRkb3duSG9va3MudG9BcnJheShob29rcyk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gU3RhcnQgYWxsIHNodXRkb3duIGhvb2tzIGNvbmN1cnJlbnRseQorICAgICAgICAgICAgICAgIGZvciAoVGhyZWFkIGhvb2sgOiBob29rcykgeworICAgICAgICAgICAgICAgICAgICBob29rLnN0YXJ0KCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gV2FpdCBmb3IgYWxsIHNodXRkb3duIGhvb2tzIHRvIGZpbmlzaAorICAgICAgICAgICAgICAgIGZvciAoVGhyZWFkIGhvb2sgOiBob29rcykgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgaG9vay5qb2luKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZ25vcmUsIHNpbmNlIHdlIGFyZSBhdCBWTSBzaHV0ZG93bi4KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIEVuc3VyZSBmaW5hbGl6YXRpb24gb24gZXhpdCwgaWYgcmVxdWVzdGVkCisgICAgICAgICAgICAgICAgaWYgKGZpbmFsaXplT25FeGl0KSB7CisgICAgICAgICAgICAgICAgICAgIHJ1bkZpbmFsaXphdGlvbigpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIEdldCBvdXQgb2YgaGVyZSBmaW5hbGx5Li4uCisgICAgICAgICAgICAgICAgbmF0aXZlRXhpdChjb2RlLCB0cnVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFtb3VudCBvZiBmcmVlIG1lbW9yeSByZXNvdXJjZXMgd2hpY2ggYXJlIGF2YWlsYWJsZSB0byB0aGUKKyAgICAgKiBydW5uaW5nIHByb2dyYW0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBhcHByb3hpbWF0ZSBhbW91bnQgb2YgZnJlZSBtZW1vcnksIG1lYXN1cmVkIGluIGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBuYXRpdmUgbG9uZyBmcmVlTWVtb3J5KCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdG8gdGhlIFZNIHRoYXQgaXQgd291bGQgYmUgYSBnb29kIHRpbWUgdG8gcnVuIHRoZQorICAgICAqIGdhcmJhZ2UgY29sbGVjdG9yLiBOb3RlIHRoYXQgdGhpcyBpcyBhIGhpbnQgb25seS4gVGhlcmUgaXMgbm8gZ3VhcmFudGVlCisgICAgICogdGhhdCB0aGUgZ2FyYmFnZSBjb2xsZWN0b3Igd2lsbCBhY3R1YWxseSBiZSBydW4uCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSB2b2lkIGdjKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzaW5nbGUge0Bjb2RlIFJ1bnRpbWV9IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFJ1bnRpbWV9IG9iamVjdCBmb3IgdGhlIGN1cnJlbnQgYXBwbGljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBSdW50aW1lIGdldFJ1bnRpbWUoKSB7CisgICAgICAgIHJldHVybiBtUnVudGltZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2FkcyBhbmQgbGlua3MgdGhlIGR5bmFtaWMgbGlicmFyeSB0aGF0IGlzIGlkZW50aWZpZWQgdGhyb3VnaCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgcGF0aC4gVGhpcyBtZXRob2QgaXMgc2ltaWxhciB0byB7QGxpbmsgI2xvYWRMaWJyYXJ5KFN0cmluZyl9LAorICAgICAqIGJ1dCBpdCBhY2NlcHRzIGEgZnVsbCBwYXRoIHNwZWNpZmljYXRpb24gd2hlcmVhcyB7QGNvZGUgbG9hZExpYnJhcnl9IGp1c3QKKyAgICAgKiBhY2NlcHRzIHRoZSBuYW1lIG9mIHRoZSBsaWJyYXJ5IHRvIGxvYWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGF0aE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBhYnNvbHV0ZSAocGxhdGZvcm0gZGVwZW5kZW50KSBwYXRoIHRvIHRoZSBsaWJyYXJ5IHRvIGxvYWQuCisgICAgICogQHRocm93cyBVbnNhdGlzZmllZExpbmtFcnJvcgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBsaWJyYXJ5IGNhbiBub3QgYmUgbG9hZGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvYWQoU3RyaW5nIHBhdGhOYW1lKSB7CisgICAgICAgIGxvYWQocGF0aE5hbWUsIFZNU3RhY2suZ2V0Q2FsbGluZ0NsYXNzTG9hZGVyKCkpOworICAgIH0KKworICAgIC8qCisgICAgICogTG9hZHMgYW5kIGxpbmtzIGEgbGlicmFyeSB3aXRob3V0IHNlY3VyaXR5IGNoZWNrcy4KKyAgICAgKi8KKyAgICB2b2lkIGxvYWQoU3RyaW5nIGZpbGVuYW1lLCBDbGFzc0xvYWRlciBsb2FkZXIpIHsKKyAgICAgICAgaWYgKGZpbGVuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibGlicmFyeSBwYXRoIHdhcyBudWxsLiIpOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBlcnJvciA9IG5hdGl2ZUxvYWQoZmlsZW5hbWUsIGxvYWRlcik7CisgICAgICAgIGlmIChlcnJvciAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zYXRpc2ZpZWRMaW5rRXJyb3IoZXJyb3IpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9hZHMgYW5kIGxpbmtzIHRoZSBsaWJyYXJ5IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLiBUaGUgbWFwcGluZyBvZiB0aGUKKyAgICAgKiBzcGVjaWZpZWQgbGlicmFyeSBuYW1lIHRvIHRoZSBmdWxsIHBhdGggZm9yIGxvYWRpbmcgdGhlIGxpYnJhcnkgaXMKKyAgICAgKiBpbXBsZW1lbnRhdGlvbi1kZXBlbmRlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGliTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGxpYnJhcnkgdG8gbG9hZC4KKyAgICAgKiBAdGhyb3dzIFVuc2F0aXNmaWVkTGlua0Vycm9yCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGxpYnJhcnkgY2FuIG5vdCBiZSBsb2FkZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgbG9hZExpYnJhcnkoU3RyaW5nIGxpYk5hbWUpIHsKKyAgICAgICAgbG9hZExpYnJhcnkobGliTmFtZSwgVk1TdGFjay5nZXRDYWxsaW5nQ2xhc3NMb2FkZXIoKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBMb2FkcyBhbmQgbGlua3MgYSBsaWJyYXJ5IHdpdGhvdXQgc2VjdXJpdHkgY2hlY2tzLgorICAgICAqLworICAgIHZvaWQgbG9hZExpYnJhcnkoU3RyaW5nIGxpYnJhcnlOYW1lLCBDbGFzc0xvYWRlciBsb2FkZXIpIHsKKyAgICAgICAgaWYgKGxvYWRlciAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgZmlsZW5hbWUgPSBsb2FkZXIuZmluZExpYnJhcnkobGlicmFyeU5hbWUpOworICAgICAgICAgICAgaWYgKGZpbGVuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zYXRpc2ZpZWRMaW5rRXJyb3IoIkNvdWxkbid0IGxvYWQgIiArIGxpYnJhcnlOYW1lICsgIjogIiArCisgICAgICAgICAgICAgICAgICAgICAgICAiZmluZExpYnJhcnkgcmV0dXJuZWQgbnVsbCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3RyaW5nIGVycm9yID0gbmF0aXZlTG9hZChmaWxlbmFtZSwgbG9hZGVyKTsKKyAgICAgICAgICAgIGlmIChlcnJvciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc2F0aXNmaWVkTGlua0Vycm9yKGVycm9yKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBmaWxlbmFtZSA9IFN5c3RlbS5tYXBMaWJyYXJ5TmFtZShsaWJyYXJ5TmFtZSk7CisgICAgICAgIExpc3Q8U3RyaW5nPiBjYW5kaWRhdGVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIFN0cmluZyBsYXN0RXJyb3IgPSBudWxsOworICAgICAgICBmb3IgKFN0cmluZyBkaXJlY3RvcnkgOiBtTGliUGF0aHMpIHsKKyAgICAgICAgICAgIFN0cmluZyBjYW5kaWRhdGUgPSBkaXJlY3RvcnkgKyBmaWxlbmFtZTsKKyAgICAgICAgICAgIGNhbmRpZGF0ZXMuYWRkKGNhbmRpZGF0ZSk7CisgICAgICAgICAgICBpZiAobmV3IEZpbGUoY2FuZGlkYXRlKS5leGlzdHMoKSkgeworICAgICAgICAgICAgICAgIFN0cmluZyBlcnJvciA9IG5hdGl2ZUxvYWQoY2FuZGlkYXRlLCBsb2FkZXIpOworICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsgLy8gV2Ugc3VjY2Vzc2Z1bGx5IGxvYWRlZCB0aGUgbGlicmFyeS4gSm9iIGRvbmUuCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGxhc3RFcnJvciA9IGVycm9yOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKGxhc3RFcnJvciAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zYXRpc2ZpZWRMaW5rRXJyb3IobGFzdEVycm9yKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgVW5zYXRpc2ZpZWRMaW5rRXJyb3IoIkxpYnJhcnkgIiArIGxpYnJhcnlOYW1lICsgIiBub3QgZm91bmQ7IHRyaWVkICIgKyBjYW5kaWRhdGVzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgdm9pZCBuYXRpdmVFeGl0KGludCBjb2RlLCBib29sZWFuIGlzRXhpdCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgU3RyaW5nIG5hdGl2ZUxvYWQoU3RyaW5nIGZpbGVuYW1lLCBDbGFzc0xvYWRlciBsb2FkZXIpOworCisgICAgLyoqCisgICAgICogUHJvdmlkZXMgYSBoaW50IHRvIHRoZSBWTSB0aGF0IGl0IHdvdWxkIGJlIHVzZWZ1bCB0byBhdHRlbXB0CisgICAgICogdG8gcGVyZm9ybSBhbnkgb3V0c3RhbmRpbmcgb2JqZWN0IGZpbmFsaXphdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBydW5GaW5hbGl6YXRpb24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBGaW5hbGl6ZXJSZWZlcmVuY2UuZmluYWxpemVBbGxFbnF1ZXVlZCgpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLmludGVycnVwdCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZmxhZyB0aGF0IGluZGljYXRlcyB3aGV0aGVyIGFsbCBvYmplY3RzIGFyZSBmaW5hbGl6ZWQgd2hlbiB0aGUKKyAgICAgKiBWTSBpcyBhYm91dCB0byBleGl0LiBOb3RlIHRoYXQgYWxsIGZpbmFsaXphdGlvbiB3aGljaCBvY2N1cnMKKyAgICAgKiB3aGVuIHRoZSBzeXN0ZW0gaXMgZXhpdGluZyBpcyBwZXJmb3JtZWQgYWZ0ZXIgYWxsIHJ1bm5pbmcgdGhyZWFkcyBoYXZlCisgICAgICogYmVlbiB0ZXJtaW5hdGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHJ1bgorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IHRvIGVuYWJsZSBmaW5hbGl6YXRpb24gb24gZXhpdCwge0Bjb2RlIGZhbHNlfSB0bworICAgICAqICAgICAgICAgICAgZGlzYWJsZSBpdC4KKyAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBpcyB1bnNhZmUuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcnVuRmluYWxpemVyc09uRXhpdChib29sZWFuIHJ1bikgeworICAgICAgICBmaW5hbGl6ZU9uRXhpdCA9IHJ1bjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0b3RhbCBhbW91bnQgb2YgbWVtb3J5IHdoaWNoIGlzIGF2YWlsYWJsZSB0byB0aGUgcnVubmluZworICAgICAqIHByb2dyYW0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB0b3RhbCBhbW91bnQgb2YgbWVtb3J5LCBtZWFzdXJlZCBpbiBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgbmF0aXZlIGxvbmcgdG90YWxNZW1vcnkoKTsKKworICAgIC8qKgorICAgICAqIFN3aXRjaGVzIHRoZSBvdXRwdXQgb2YgZGVidWcgaW5mb3JtYXRpb24gZm9yIGluc3RydWN0aW9ucyBvbiBvciBvZmYuCisgICAgICogT24gQW5kcm9pZCwgdGhpcyBtZXRob2QgZG9lcyBub3RoaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIGVuYWJsZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IHRvIHN3aXRjaCB0cmFjaW5nIG9uLCB7QGNvZGUgZmFsc2V9IHRvIHN3aXRjaCBpdAorICAgICAqICAgICAgICAgICAgb2ZmLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRyYWNlSW5zdHJ1Y3Rpb25zKGJvb2xlYW4gZW5hYmxlKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3dpdGNoZXMgdGhlIG91dHB1dCBvZiBkZWJ1ZyBpbmZvcm1hdGlvbiBmb3IgbWV0aG9kcyBvbiBvciBvZmYuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW5hYmxlCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gdG8gc3dpdGNoIHRyYWNpbmcgb24sIHtAY29kZSBmYWxzZX0gdG8gc3dpdGNoIGl0CisgICAgICogICAgICAgICAgICBvZmYuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdHJhY2VNZXRob2RDYWxscyhib29sZWFuIGVuYWJsZSkgeworICAgICAgICBpZiAoZW5hYmxlICE9IHRyYWNpbmdNZXRob2RzKSB7CisgICAgICAgICAgICBpZiAoZW5hYmxlKSB7CisgICAgICAgICAgICAgICAgVk1EZWJ1Zy5zdGFydE1ldGhvZFRyYWNpbmcoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgVk1EZWJ1Zy5zdG9wTWV0aG9kVHJhY2luZygpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJhY2luZ01ldGhvZHMgPSBlbmFibGU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbGl6ZWQgdmVyc2lvbiBvZiB0aGUgc3BlY2lmaWVkIGlucHV0IHN0cmVhbS4gVGhlIGlucHV0CisgICAgICogc3RyZWFtIHRoYXQgaXMgcmV0dXJuZWQgYXV0b21hdGljYWxseSBjb252ZXJ0cyBhbGwgY2hhcmFjdGVycyBmcm9tIHRoZQorICAgICAqIGxvY2FsIGNoYXJhY3RlciBzZXQgdG8gVW5pY29kZSBhZnRlciByZWFkaW5nIHRoZW0gZnJvbSB0aGUgdW5kZXJseWluZworICAgICAqIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBzdHJlYW0gdG8gbG9jYWxpemUuCisgICAgICogQHJldHVybiB0aGUgbG9jYWxpemVkIGlucHV0IHN0cmVhbS4KKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rIElucHV0U3RyZWFtUmVhZGVyfS4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRMb2NhbGl6ZWRJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBzdHJlYW0pIHsKKyAgICAgICAgU3RyaW5nIGVuY29kaW5nID0gU3lzdGVtLmdldFByb3BlcnR5KCJmaWxlLmVuY29kaW5nIiwgIlVURi04Iik7CisgICAgICAgIGlmICghZW5jb2RpbmcuZXF1YWxzKCJVVEYtOCIpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIkNhbm5vdCBsb2NhbGl6ZSAiICsgZW5jb2RpbmcpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzdHJlYW07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbG9jYWxpemVkIHZlcnNpb24gb2YgdGhlIHNwZWNpZmllZCBvdXRwdXQgc3RyZWFtLiBUaGUgb3V0cHV0CisgICAgICogc3RyZWFtIHRoYXQgaXMgcmV0dXJuZWQgYXV0b21hdGljYWxseSBjb252ZXJ0cyBhbGwgY2hhcmFjdGVycyBmcm9tCisgICAgICogVW5pY29kZSB0byB0aGUgbG9jYWwgY2hhcmFjdGVyIHNldCBiZWZvcmUgd3JpdGluZyB0aGVtIHRvIHRoZSB1bmRlcmx5aW5nCisgICAgICogc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBzdHJlYW0gdG8gbG9jYWxpemUuCisgICAgICogQHJldHVybiB0aGUgbG9jYWxpemVkIG91dHB1dCBzdHJlYW0uCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayBPdXRwdXRTdHJlYW1Xcml0ZXJ9LgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIE91dHB1dFN0cmVhbSBnZXRMb2NhbGl6ZWRPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIHN0cmVhbSkgeworICAgICAgICBTdHJpbmcgZW5jb2RpbmcgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImZpbGUuZW5jb2RpbmciLCAiVVRGLTgiKTsKKyAgICAgICAgaWYgKCFlbmNvZGluZy5lcXVhbHMoIlVURi04IikpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiQ2Fubm90IGxvY2FsaXplICIgKyBlbmNvZGluZyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN0cmVhbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWdpc3RlcnMgYSBWTSBzaHV0ZG93biBob29rLiBBIHNodXRkb3duIGhvb2sgaXMgYQorICAgICAqIHtAY29kZSBUaHJlYWR9IHRoYXQgaXMgcmVhZHkgdG8gcnVuLCBidXQgaGFzIG5vdCB5ZXQgYmVlbiBzdGFydGVkLiBBbGwKKyAgICAgKiByZWdpc3RlcmVkIHNodXRkb3duIGhvb2tzIHdpbGwgYmUgZXhlY3V0ZWQgd2hlbiB0aGUgVk0KKyAgICAgKiB0ZXJtaW5hdGVzIG5vcm1hbGx5ICh0eXBpY2FsbHkgd2hlbiB0aGUge0BsaW5rICNleGl0KGludCl9IG1ldGhvZCBpcyBjYWxsZWQpLgorICAgICAqCisgICAgICogPHA+PGk+Tm90ZSB0aGF0IG9uIEFuZHJvaWQsIHRoZSBhcHBsaWNhdGlvbiBsaWZlY3ljbGUgZG9lcyBub3QgaW5jbHVkZSBWTSB0ZXJtaW5hdGlvbiwKKyAgICAgKiBzbyBjYWxsaW5nIHRoaXMgbWV0aG9kIHdpbGwgbm90IGVuc3VyZSB0aGF0IHlvdXIgY29kZSBpcyBydW48L2k+LiBJbnN0ZWFkLCB5b3Ugc2hvdWxkCisgICAgICogdXNlIHRoZSBtb3N0IGFwcHJvcHJpYXRlIGxpZmVjeWNsZSBub3RpZmljYXRpb24gKHtAY29kZSBBY3Rpdml0eS5vblBhdXNlfSwgc2F5KS4KKyAgICAgKgorICAgICAqIDxwPlNodXRkb3duIGhvb2tzIGFyZSBydW4gY29uY3VycmVudGx5IGFuZCBpbiBhbiB1bnNwZWNpZmllZCBvcmRlci4gSG9va3MKKyAgICAgKiBmYWlsaW5nIGR1ZSB0byBhbiB1bmhhbmRsZWQgZXhjZXB0aW9uIGFyZSBub3QgYSBwcm9ibGVtLCBidXQgdGhlIHN0YWNrCisgICAgICogdHJhY2UgbWlnaHQgYmUgcHJpbnRlZCB0byB0aGUgY29uc29sZS4gT25jZSBpbml0aWF0ZWQsIHRoZSB3aG9sZSBzaHV0ZG93bgorICAgICAqIHByb2Nlc3MgY2FuIG9ubHkgYmUgdGVybWluYXRlZCBieSBjYWxsaW5nIHtAY29kZSBoYWx0KCl9LgorICAgICAqCisgICAgICogPHA+SWYge0BsaW5rICNydW5GaW5hbGl6ZXJzT25FeGl0KGJvb2xlYW4pfSBoYXMgYmVlbiBjYWxsZWQgd2l0aCBhIHtAY29kZQorICAgICAqIHRydWV9IGFyZ3VtZW50LCBnYXJiYWdlIGNvbGxlY3Rpb24gYW5kIGZpbmFsaXphdGlvbiB3aWxsIHRha2UgcGxhY2UgYWZ0ZXIKKyAgICAgKiBhbGwgaG9va3MgYXJlIGVpdGhlciBmaW5pc2hlZCBvciBoYXZlIGZhaWxlZC4gVGhlbiB0aGUgVk0KKyAgICAgKiB0ZXJtaW5hdGVzLgorICAgICAqCisgICAgICogPHA+SXQgaXMgcmVjb21tZW5kZWQgdGhhdCBzaHV0ZG93biBob29rcyBkbyBub3QgZG8gYW55IHRpbWUtY29uc3VtaW5nCisgICAgICogYWN0aXZpdGllcywgaW4gb3JkZXIgdG8gbm90IGhvbGQgdXAgdGhlIHNodXRkb3duIHByb2Nlc3MgbG9uZ2VyIHRoYW4KKyAgICAgKiBuZWNlc3NhcnkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaG9vaworICAgICAqICAgICAgICAgICAgdGhlIHNodXRkb3duIGhvb2sgdG8gcmVnaXN0ZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaG9vayBoYXMgYWxyZWFkeSBiZWVuIHN0YXJ0ZWQgb3IgaWYgaXQgaGFzIGFscmVhZHkKKyAgICAgKiAgICAgICAgICAgICBiZWVuIHJlZ2lzdGVyZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgVk0gaXMgYWxyZWFkeSBzaHV0dGluZyBkb3duLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZFNodXRkb3duSG9vayhUaHJlYWQgaG9vaykgeworICAgICAgICAvLyBTYW5pdHkgY2hlY2tzCisgICAgICAgIGlmIChob29rID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiSG9vayBtYXkgbm90IGJlIG51bGwuIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc2h1dHRpbmdEb3duKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJWTSBhbHJlYWR5IHNodXR0aW5nIGRvd24iKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChob29rLmhhc0JlZW5TdGFydGVkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJIb29rIGhhcyBhbHJlYWR5IGJlZW4gc3RhcnRlZCIpOworICAgICAgICB9CisKKyAgICAgICAgc3luY2hyb25pemVkIChzaHV0ZG93bkhvb2tzKSB7CisgICAgICAgICAgICBpZiAoc2h1dGRvd25Ib29rcy5jb250YWlucyhob29rKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkhvb2sgYWxyZWFkeSByZWdpc3RlcmVkLiIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzaHV0ZG93bkhvb2tzLmFkZChob29rKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFVucmVnaXN0ZXJzIGEgcHJldmlvdXNseSByZWdpc3RlcmVkIFZNIHNodXRkb3duIGhvb2suCisgICAgICoKKyAgICAgKiBAcGFyYW0gaG9vaworICAgICAqICAgICAgICAgICAgdGhlIHNodXRkb3duIGhvb2sgdG8gcmVtb3ZlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBob29rIGhhcyBiZWVuIHJlbW92ZWQgc3VjY2Vzc2Z1bGx5OyB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgVk0gaXMgYWxyZWFkeSBzaHV0dGluZyBkb3duLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZVNodXRkb3duSG9vayhUaHJlYWQgaG9vaykgeworICAgICAgICAvLyBTYW5pdHkgY2hlY2tzCisgICAgICAgIGlmIChob29rID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiSG9vayBtYXkgbm90IGJlIG51bGwuIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc2h1dHRpbmdEb3duKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJWTSBhbHJlYWR5IHNodXR0aW5nIGRvd24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHN5bmNocm9uaXplZCAoc2h1dGRvd25Ib29rcykgeworICAgICAgICAgICAgcmV0dXJuIHNodXRkb3duSG9va3MucmVtb3ZlKGhvb2spOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2F1c2VzIHRoZSBWTSB0byBzdG9wIHJ1bm5pbmcsIGFuZCB0aGUgcHJvZ3JhbSB0byBleGl0LgorICAgICAqIE5laXRoZXIgc2h1dGRvd24gaG9va3Mgbm9yIGZpbmFsaXplcnMgYXJlIHJ1biBiZWZvcmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29kZQorICAgICAqICAgICAgICAgICAgdGhlIHJldHVybiBjb2RlLiBCeSBjb252ZW50aW9uLCBub24temVybyByZXR1cm4gY29kZXMgaW5kaWNhdGUKKyAgICAgKiAgICAgICAgICAgIGFibm9ybWFsIHRlcm1pbmF0aW9ucy4KKyAgICAgKiBAc2VlICNhZGRTaHV0ZG93bkhvb2soVGhyZWFkKQorICAgICAqIEBzZWUgI3JlbW92ZVNodXRkb3duSG9vayhUaHJlYWQpCisgICAgICogQHNlZSAjcnVuRmluYWxpemVyc09uRXhpdChib29sZWFuKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGhhbHQoaW50IGNvZGUpIHsKKyAgICAgICAgLy8gR2V0IG91dCBvZiBoZXJlLi4uCisgICAgICAgIG5hdGl2ZUV4aXQoY29kZSwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBwcm9jZXNzb3JzIGF2YWlsYWJsZSB0byB0aGUgVk0sIGF0IGxlYXN0IDEuCisgICAgICovCisgICAgcHVibGljIGludCBhdmFpbGFibGVQcm9jZXNzb3JzKCkgeworICAgICAgICByZXR1cm4gKGludCkgTGliY29yZS5vcy5zeXNjb25mKF9TQ19OUFJPQ0VTU09SU19PTkxOKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIGFtb3VudCBvZiBtZW1vcnkgdGhhdCBtYXkgYmUgdXNlZCBieSB0aGUgdmlydHVhbAorICAgICAqIG1hY2hpbmUsIG9yIHtAY29kZSBMb25nLk1BWF9WQUxVRX0gaWYgdGhlcmUgaXMgbm8gc3VjaCBsaW1pdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gYW1vdW50IG9mIG1lbW9yeSB0aGF0IHRoZSBWTSB3aWxsIHRyeSB0bworICAgICAqICAgICAgICAgYWxsb2NhdGUsIG1lYXN1cmVkIGluIGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBuYXRpdmUgbG9uZyBtYXhNZW1vcnkoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvUnVudGltZUV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9SdW50aW1lRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjI1OTA1ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvUnVudGltZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNzIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIHtAY29kZSBSdW50aW1lRXhjZXB0aW9ufSBpcyB0aGUgc3VwZXJjbGFzcyBvZiBhbGwgY2xhc3NlcyB0aGF0IHJlcHJlc2VudAorICogZXhjZXB0aW9uYWwgY29uZGl0aW9ucyB3aGljaCBvY2N1ciBhcyBhIHJlc3VsdCBvZiBleGVjdXRpbmcgYW4gYXBwbGljYXRpb24gaW4KKyAqIHRoZSBWTS4gVW5saWtlIGNoZWNrZWQgZXhjZXB0aW9ucyAoZXhjZXB0aW9ucyB3aGVyZSB0aGUgdHlwZQorICogZG9lc24ndCBleHRlbmQge0Bjb2RlIFJ1bnRpbWVFeGNlcHRpb259IG9yIHtAbGluayBFcnJvcn0pLCB0aGUgY29tcGlsZXIgZG9lcworICogbm90IHJlcXVpcmUgY29kZSB0byBoYW5kbGUgcnVudGltZSBleGNlcHRpb25zLgorICovCitwdWJsaWMgY2xhc3MgUnVudGltZUV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNzAzNDg5NzE5MDc0NTc2NjkzOUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBSdW50aW1lRXhjZXB0aW9ufSB0aGF0IGluY2x1ZGVzIHRoZSBjdXJyZW50IHN0YWNrCisgICAgICogdHJhY2UuCisgICAgICovCisgICAgcHVibGljIFJ1bnRpbWVFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUnVudGltZUV4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudCBzdGFjayB0cmFjZQorICAgICAqIGFuZCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFJ1bnRpbWVFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorCisgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBSdW50aW1lRXhjZXB0aW9ufSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlLAorICAgICAqIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UgYW5kIHRoZSBzcGVjaWZpZWQgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gdGhyb3dhYmxlCisgICAgICogICAgICAgICAgICB0aGUgY2F1c2Ugb2YgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFJ1bnRpbWVFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UsIFRocm93YWJsZSB0aHJvd2FibGUpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSwgdGhyb3dhYmxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBSdW50aW1lRXhjZXB0aW9ufSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlCisgICAgICogYW5kIHRoZSBzcGVjaWZpZWQgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhyb3dhYmxlCisgICAgICogICAgICAgICAgICB0aGUgY2F1c2Ugb2YgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFJ1bnRpbWVFeGNlcHRpb24oVGhyb3dhYmxlIHRocm93YWJsZSkgeworICAgICAgICBzdXBlcih0aHJvd2FibGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvUnVudGltZVBlcm1pc3Npb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvUnVudGltZVBlcm1pc3Npb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYmVjMDQ5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9SdW50aW1lUGVybWlzc2lvbi5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5CYXNpY1Blcm1pc3Npb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uOworCisvKioKKyAqIExlZ2FjeSBzZWN1cml0eSBjb2RlOyBkbyBub3QgdXNlLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUnVudGltZVBlcm1pc3Npb24gZXh0ZW5kcyBCYXNpY1Blcm1pc3Npb24geworICAgIHB1YmxpYyBSdW50aW1lUGVybWlzc2lvbihTdHJpbmcgcGVybWlzc2lvbk5hbWUpIHsgc3VwZXIoIiIpOyB9CisKKyAgICBwdWJsaWMgUnVudGltZVBlcm1pc3Npb24oU3RyaW5nIG5hbWUsIFN0cmluZyBhY3Rpb25zKSB7IHN1cGVyKCIiLCAiIik7IH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIGdldEFjdGlvbnMoKSB7IHJldHVybiBudWxsOyB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaW1wbGllcyhQZXJtaXNzaW9uIHBlcm1pc3Npb24pIHsgcmV0dXJuIHRydWU7IH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvU2VjdXJpdHlFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvU2VjdXJpdHlFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MmQ2NGE4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TZWN1cml0eUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNzAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIFRocm93biB3aGVuIGEgc2VjdXJpdHkgbWFuYWdlciBjaGVjayBmYWlscy4KKyAqLworcHVibGljIGNsYXNzIFNlY3VyaXR5RXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA2ODc4MzY0OTgzNjc0Mzk0MTY3TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFNlY3VyaXR5RXhjZXB0aW9ufSB0aGF0IGluY2x1ZGVzIHRoZSBjdXJyZW50CisgICAgICogc3RhY2sgdHJhY2UuCisgICAgICovCisgICAgcHVibGljIFNlY3VyaXR5RXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFNlY3VyaXR5RXhjZXB0aW9ufSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlCisgICAgICogYW5kIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2VjdXJpdHlFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgU2VjdXJpdHlFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQgc3RhY2sgdHJhY2UsCisgICAgICogdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZSBhbmQgdGhlIHNwZWNpZmllZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIG9wdGlvbmFsIGNhdXNlIG9mIHRoaXMgZXhjZXB0aW9uLCBtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgU2VjdXJpdHlFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgU2VjdXJpdHlFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQgc3RhY2sgdHJhY2UKKyAgICAgKiBhbmQgdGhlIHNwZWNpZmllZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIG9wdGlvbmFsIGNhdXNlIG9mIHRoaXMgZXhjZXB0aW9uLCBtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgU2VjdXJpdHlFeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKChjYXVzZSA9PSBudWxsID8gbnVsbCA6IGNhdXNlLnRvU3RyaW5nKCkpLCBjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TZWN1cml0eU1hbmFnZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvU2VjdXJpdHlNYW5hZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOThlOTJjYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvU2VjdXJpdHlNYW5hZ2VyLmphdmEKQEAgLTAsMCArMSwxNTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKgorICogPHA+U2VjdXJpdHkgbWFuYWdlcnMgZG8gPHN0cm9uZz5ub3Q8L3N0cm9uZz4gcHJvdmlkZSBhCisgKiBzZWN1cmUgZW52aXJvbm1lbnQgZm9yIGV4ZWN1dGluZyB1bnRydXN0ZWQgY29kZS4gVW50cnVzdGVkIGNvZGUgY2Fubm90IGJlCisgKiBzYWZlbHkgaXNvbGF0ZWQgd2l0aGluIHRoZSBEYWx2aWsgVk0uCisgKi8KK3B1YmxpYyBjbGFzcyBTZWN1cml0eU1hbmFnZXIgeworICAgIC8qKgorICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2NoZWNrUGVybWlzc2lvbn0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHByb3RlY3RlZCBib29sZWFuIGluQ2hlY2s7CisKKyAgICBwdWJsaWMgU2VjdXJpdHlNYW5hZ2VyKCkgeyB9CisKKyAgICBwdWJsaWMgdm9pZCBjaGVja0FjY2VwdChTdHJpbmcgaG9zdCwgaW50IHBvcnQpIHsgfQorCisgICAgcHVibGljIHZvaWQgY2hlY2tBY2Nlc3MoVGhyZWFkIHRocmVhZCkgeyB9CisKKyAgICBwdWJsaWMgdm9pZCBjaGVja0FjY2VzcyhUaHJlYWRHcm91cCBncm91cCkgeyB9CisKKyAgICBwdWJsaWMgdm9pZCBjaGVja0Nvbm5lY3QoU3RyaW5nIGhvc3QsIGludCBwb3J0KSB7IH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrQ29ubmVjdChTdHJpbmcgaG9zdCwgaW50IHBvcnQsIE9iamVjdCBjb250ZXh0KSB7IH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrQ3JlYXRlQ2xhc3NMb2FkZXIoKSB7IH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrRGVsZXRlKFN0cmluZyBmaWxlKSB7IH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrRXhlYyhTdHJpbmcgY21kKSB7IH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrRXhpdChpbnQgc3RhdHVzKSB7IH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrTGluayhTdHJpbmcgbGliTmFtZSkgeyB9CisKKyAgICBwdWJsaWMgdm9pZCBjaGVja0xpc3RlbihpbnQgcG9ydCkgeyB9CisKKyAgICBwdWJsaWMgdm9pZCBjaGVja01lbWJlckFjY2VzcyhDbGFzczw/PiBjbHMsIGludCB0eXBlKSB7IH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrTXVsdGljYXN0KEluZXRBZGRyZXNzIG1hZGRyKSB7IH0KKworICAgIC8qKgorICAgICAqIEBkZXByZWNhdGVkIHVzZSB7QGxpbmsgI2NoZWNrTXVsdGljYXN0KGphdmEubmV0LkluZXRBZGRyZXNzKX0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZCBwdWJsaWMgdm9pZCBjaGVja011bHRpY2FzdChJbmV0QWRkcmVzcyBtYWRkciwgYnl0ZSB0dGwpIHsgfQorCisgICAgcHVibGljIHZvaWQgY2hlY2tQYWNrYWdlQWNjZXNzKFN0cmluZyBwYWNrYWdlTmFtZSkgeyB9CisKKyAgICBwdWJsaWMgdm9pZCBjaGVja1BhY2thZ2VEZWZpbml0aW9uKFN0cmluZyBwYWNrYWdlTmFtZSkgeyB9CisKKyAgICBwdWJsaWMgdm9pZCBjaGVja1Byb3BlcnRpZXNBY2Nlc3MoKSB7IH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrUHJvcGVydHlBY2Nlc3MoU3RyaW5nIGtleSkgeyB9CisKKyAgICBwdWJsaWMgdm9pZCBjaGVja1JlYWQoRmlsZURlc2NyaXB0b3IgZmQpIHsgfQorCisgICAgcHVibGljIHZvaWQgY2hlY2tSZWFkKFN0cmluZyBmaWxlKSB7IH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrUmVhZChTdHJpbmcgZmlsZSwgT2JqZWN0IGNvbnRleHQpIHsgfQorCisgICAgcHVibGljIHZvaWQgY2hlY2tTZWN1cml0eUFjY2VzcyhTdHJpbmcgdGFyZ2V0KSB7IH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrU2V0RmFjdG9yeSgpIHsgfQorCisgICAgcHVibGljIGJvb2xlYW4gY2hlY2tUb3BMZXZlbFdpbmRvdyhPYmplY3Qgd2luZG93KSB7IHJldHVybiB0cnVlOyB9CisKKyAgICBwdWJsaWMgdm9pZCBjaGVja1N5c3RlbUNsaXBib2FyZEFjY2VzcygpIHsgfQorCisgICAgcHVibGljIHZvaWQgY2hlY2tBd3RFdmVudFF1ZXVlQWNjZXNzKCkgeyB9CisKKyAgICBwdWJsaWMgdm9pZCBjaGVja1ByaW50Sm9iQWNjZXNzKCkgeyB9CisKKyAgICBwdWJsaWMgdm9pZCBjaGVja1dyaXRlKEZpbGVEZXNjcmlwdG9yIGZkKSB7IH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrV3JpdGUoU3RyaW5nIGZpbGUpIHsgfQorCisgICAgLyoqCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjY2hlY2tQZXJtaXNzaW9ufS4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZCBwdWJsaWMgYm9vbGVhbiBnZXRJbkNoZWNrKCkgeyByZXR1cm4gaW5DaGVjazsgfQorCisgICAgcHJvdGVjdGVkIENsYXNzW10gZ2V0Q2xhc3NDb250ZXh0KCkgeyByZXR1cm4gbnVsbDsgfQorCisgICAgLyoqCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjY2hlY2tQZXJtaXNzaW9ufS4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZCBwcm90ZWN0ZWQgQ2xhc3NMb2FkZXIgY3VycmVudENsYXNzTG9hZGVyKCkgeyByZXR1cm4gbnVsbDsgfQorCisgICAgLyoqCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjY2hlY2tQZXJtaXNzaW9ufS4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZCBwcm90ZWN0ZWQgaW50IGNsYXNzTG9hZGVyRGVwdGgoKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNjaGVja1Blcm1pc3Npb259LgorICAgICAqLworICAgIEBEZXByZWNhdGVkIHByb3RlY3RlZCBDbGFzczw/PiBjdXJyZW50TG9hZGVkQ2xhc3MoKSB7IHJldHVybiBudWxsOyB9CisKKyAgICAvKioKKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNjaGVja1Blcm1pc3Npb259LgorICAgICAqLworICAgIEBEZXByZWNhdGVkIHByb3RlY3RlZCBpbnQgY2xhc3NEZXB0aChTdHJpbmcgbmFtZSkgeyByZXR1cm4gLTE7IH0KKworICAgIC8qKgorICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2NoZWNrUGVybWlzc2lvbn0uCisgICAgICovCisgICAgQERlcHJlY2F0ZWQgcHJvdGVjdGVkIGJvb2xlYW4gaW5DbGFzcyhTdHJpbmcgbmFtZSkgeyByZXR1cm4gZmFsc2U7IH0KKworICAgIC8qKgorICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2NoZWNrUGVybWlzc2lvbn0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZCBwcm90ZWN0ZWQgYm9vbGVhbiBpbkNsYXNzTG9hZGVyKCkgeyByZXR1cm4gZmFsc2U7IH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgdGhyZWFkJ3MgdGhyZWFkIGdyb3VwLgorICAgICAqLworICAgIHB1YmxpYyBUaHJlYWRHcm91cCBnZXRUaHJlYWRHcm91cCgpIHsKKyAgICAgICAgcmV0dXJuIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0VGhyZWFkR3JvdXAoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldFNlY3VyaXR5Q29udGV4dCgpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihQZXJtaXNzaW9uIHBlcm1pc3Npb24pIHsgfQorCisgICAgcHVibGljIHZvaWQgY2hlY2tQZXJtaXNzaW9uKFBlcm1pc3Npb24gcGVybWlzc2lvbiwgT2JqZWN0IGNvbnRleHQpIHsgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TaG9ydC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TaG9ydC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExMDE4MDUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1Nob3J0LmphdmEKQEAgLTAsMCArMSwzMjEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIFRoZSB3cmFwcGVyIGZvciB0aGUgcHJpbWl0aXZlIHR5cGUge0Bjb2RlIHNob3J0fS4KKyAqCisgKiBAc2VlIGphdmEubGFuZy5OdW1iZXIKKyAqIEBzaW5jZSAxLjEKKyAqLworQEZpbmRCdWdzU3VwcHJlc3NXYXJuaW5ncygiRE1fTlVNQkVSX0NUT1IiKQorcHVibGljIGZpbmFsIGNsYXNzIFNob3J0IGV4dGVuZHMgTnVtYmVyIGltcGxlbWVudHMgQ29tcGFyYWJsZTxTaG9ydD4geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzUxNTcyMzkwODc3Mzg5NDczOEw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdmFsdWUgd2hpY2ggdGhlIHJlY2VpdmVyIHJlcHJlc2VudHMuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBzaG9ydCB2YWx1ZTsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IGZvciB0aGUgbWF4aW11bSB7QGNvZGUgc2hvcnR9IHZhbHVlLCAyPHN1cD4xNTwvc3VwPi0xLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTUFYX1ZBTFVFID0gKHNob3J0KSAweDdGRkY7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCBmb3IgdGhlIG1pbmltdW0ge0Bjb2RlIHNob3J0fSB2YWx1ZSwgLTI8c3VwPjE1PC9zdXA+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTUlOX1ZBTFVFID0gKHNob3J0KSAweDgwMDA7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCBmb3IgdGhlIG51bWJlciBvZiBiaXRzIG5lZWRlZCB0byByZXByZXNlbnQgYSB7QGNvZGUgc2hvcnR9IGluCisgICAgICogdHdvJ3MgY29tcGxlbWVudCBmb3JtLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJWkUgPSAxNjsKKworICAgIC8qKgorICAgICAqIFRoZSB7QGxpbmsgQ2xhc3N9IG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHByaW1pdGl2ZSB0eXBlIHtAY29kZQorICAgICAqIHNob3J0fS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENsYXNzPFNob3J0PiBUWVBFCisgICAgICAgICAgICA9IChDbGFzczxTaG9ydD4pIHNob3J0W10uY2xhc3MuZ2V0Q29tcG9uZW50VHlwZSgpOworICAgIC8vIE5vdGU6IFNob3J0LlRZUEUgY2FuJ3QgYmUgc2V0IHRvICJzaG9ydC5jbGFzcyIsIHNpbmNlICp0aGF0KiBpcworICAgIC8vIGRlZmluZWQgdG8gYmUgImphdmEubGFuZy5TaG9ydC5UWVBFIjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFNob3J0fSBmcm9tIHRoZSBzcGVjaWZpZWQgc3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHNob3J0IHZhbHVlLgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0cmluZ30gY2Fubm90IGJlIHBhcnNlZCBhcyBhIHNob3J0IHZhbHVlLgorICAgICAqIEBzZWUgI3BhcnNlU2hvcnQoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBTaG9ydChTdHJpbmcgc3RyaW5nKSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhwYXJzZVNob3J0KHN0cmluZykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFNob3J0fSB3aXRoIHRoZSBzcGVjaWZpZWQgcHJpbWl0aXZlIHNob3J0IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgcHJpbWl0aXZlIHNob3J0IHZhbHVlIHRvIHN0b3JlIGluIHRoZSBuZXcgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIFNob3J0KHNob3J0IHZhbHVlKSB7CisgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZSBieXRlVmFsdWUoKSB7CisgICAgICAgIHJldHVybiAoYnl0ZSkgdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBvYmplY3QgdG8gdGhlIHNwZWNpZmllZCBzaG9ydCBvYmplY3QgdG8gZGV0ZXJtaW5lIHRoZWlyCisgICAgICogcmVsYXRpdmUgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgc2hvcnQgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyBvYmplY3QgdG8uCisgICAgICogQHJldHVybiBhIG5lZ2F0aXZlIHZhbHVlIGlmIHRoZSB2YWx1ZSBvZiB0aGlzIHNob3J0IGlzIGxlc3MgdGhhbiB0aGUKKyAgICAgKiAgICAgICAgIHZhbHVlIG9mIHtAY29kZSBvYmplY3R9OyAwIGlmIHRoZSB2YWx1ZSBvZiB0aGlzIHNob3J0IGFuZCB0aGUKKyAgICAgKiAgICAgICAgIHZhbHVlIG9mIHtAY29kZSBvYmplY3R9IGFyZSBlcXVhbDsgYSBwb3NpdGl2ZSB2YWx1ZSBpZiB0aGUgdmFsdWUKKyAgICAgKiAgICAgICAgIG9mIHRoaXMgc2hvcnQgaXMgZ3JlYXRlciB0aGFuIHRoZSB2YWx1ZSBvZiB7QGNvZGUgb2JqZWN0fS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9iamVjdH0gaXMgbnVsbC4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5Db21wYXJhYmxlCisgICAgICogQHNpbmNlIDEuMgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKFNob3J0IG9iamVjdCkgeworICAgICAgICByZXR1cm4gY29tcGFyZSh2YWx1ZSwgb2JqZWN0LnZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0d28ge0Bjb2RlIHNob3J0fSB2YWx1ZXMuCisgICAgICogQHJldHVybiAwIGlmIGxocyA9IHJocywgbGVzcyB0aGFuIDAgaWYgbGhzICZsdDsgcmhzLCBhbmQgZ3JlYXRlciB0aGFuIDAgaWYgbGhzICZndDsgcmhzLgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBjb21wYXJlKGxvbmcgbGhzLCBsb25nIHJocykgeworICAgICAgICByZXR1cm4gbGhzID4gcmhzID8gMSA6IChsaHMgPCByaHMgPyAtMSA6IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgc3BlY2lmaWVkIHN0cmluZyBhbmQgcmV0dXJucyBhIHtAY29kZSBTaG9ydH0gaW5zdGFuY2UgaWYgdGhlCisgICAgICogc3RyaW5nIGNhbiBiZSBkZWNvZGVkIGludG8gYSBzaG9ydCB2YWx1ZS4gVGhlIHN0cmluZyBtYXkgYmUgYW4gb3B0aW9uYWwKKyAgICAgKiBtaW51cyBzaWduICItIiBmb2xsb3dlZCBieSBhIGhleGFkZWNpbWFsICgiMHguLi4iIG9yICIjLi4uIiksIG9jdGFsCisgICAgICogKCIwLi4uIiksIG9yIGRlY2ltYWwgKCIuLi4iKSByZXByZXNlbnRhdGlvbiBvZiBhIHNob3J0LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBzaG9ydCB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFNob3J0fSBjb250YWluaW5nIHRoZSB2YWx1ZSByZXByZXNlbnRlZCBieQorICAgICAqICAgICAgICAge0Bjb2RlIHN0cmluZ30uCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RyaW5nfSBjYW5ub3QgYmUgcGFyc2VkIGFzIGEgc2hvcnQgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTaG9ydCBkZWNvZGUoU3RyaW5nIHN0cmluZykgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBpbnRWYWx1ZSA9IEludGVnZXIuZGVjb2RlKHN0cmluZykuaW50VmFsdWUoKTsKKyAgICAgICAgc2hvcnQgcmVzdWx0ID0gKHNob3J0KSBpbnRWYWx1ZTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBpbnRWYWx1ZSkgeworICAgICAgICAgICAgcmV0dXJuIHZhbHVlT2YocmVzdWx0KTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJWYWx1ZSBvdXQgb2YgcmFuZ2UgZm9yIHNob3J0OiBcIiIgKyBzdHJpbmcgKyAiXCIiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZG91YmxlIGRvdWJsZVZhbHVlKCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFuZCBpbmRpY2F0ZXMgaWYgdGhleQorICAgICAqIGFyZSBlcXVhbC4gSW4gb3JkZXIgdG8gYmUgZXF1YWwsIHtAY29kZSBvYmplY3R9IG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YKKyAgICAgKiB7QGNvZGUgU2hvcnR9IGFuZCBoYXZlIHRoZSBzYW1lIHNob3J0IHZhbHVlIGFzIHRoaXMgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHRoaXMgc2hvcnQgd2l0aC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBlcXVhbCB0byB0aGlzCisgICAgICogICAgICAgICB7QGNvZGUgU2hvcnR9OyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICByZXR1cm4gKG9iamVjdCBpbnN0YW5jZW9mIFNob3J0KSAmJiAoKChTaG9ydCkgb2JqZWN0KS52YWx1ZSA9PSB2YWx1ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZsb2F0IGZsb2F0VmFsdWUoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBpbnRWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIGxvbmdWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgc3BlY2lmaWVkIHN0cmluZyBhcyBhIHNpZ25lZCBkZWNpbWFsIHNob3J0IHZhbHVlLiBUaGUgQVNDSUkKKyAgICAgKiBjaGFyYWN0ZXIgXHUwMDJkICgnLScpIGlzIHJlY29nbml6ZWQgYXMgdGhlIG1pbnVzIHNpZ24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgc2hvcnQgdmFsdWUuCisgICAgICogQHJldHVybiB0aGUgcHJpbWl0aXZlIHNob3J0IHZhbHVlIHJlcHJlc2VudGVkIGJ5IHtAY29kZSBzdHJpbmd9LgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0cmluZ30gY2Fubm90IGJlIHBhcnNlZCBhcyBhIHNob3J0IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgc2hvcnQgcGFyc2VTaG9ydChTdHJpbmcgc3RyaW5nKSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHBhcnNlU2hvcnQoc3RyaW5nLCAxMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGFzIGEgc2lnbmVkIHNob3J0IHZhbHVlIHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiByYWRpeC4gVGhlIEFTQ0lJIGNoYXJhY3RlciBcdTAwMmQgKCctJykgaXMgcmVjb2duaXplZCBhcyB0aGUgbWludXMgc2lnbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBzaG9ydCB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gcmFkaXgKKyAgICAgKiAgICAgICAgICAgIHRoZSByYWRpeCB0byB1c2Ugd2hlbiBwYXJzaW5nLgorICAgICAqIEByZXR1cm4gdGhlIHByaW1pdGl2ZSBzaG9ydCB2YWx1ZSByZXByZXNlbnRlZCBieSB7QGNvZGUgc3RyaW5nfSB1c2luZworICAgICAqICAgICAgICAge0Bjb2RlIHJhZGl4fS4KKyAgICAgKiBAdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdHJpbmd9IGNhbm5vdCBiZSBwYXJzZWQgYXMgYSBzaG9ydCB2YWx1ZSwgb3IKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgcmFkaXggPCBDaGFyYWN0ZXIuTUlOX1JBRElYIHx8CisgICAgICogICAgICAgICAgICAgcmFkaXggPiBDaGFyYWN0ZXIuTUFYX1JBRElYfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHNob3J0IHBhcnNlU2hvcnQoU3RyaW5nIHN0cmluZywgaW50IHJhZGl4KSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGludFZhbHVlID0gSW50ZWdlci5wYXJzZUludChzdHJpbmcsIHJhZGl4KTsKKyAgICAgICAgc2hvcnQgcmVzdWx0ID0gKHNob3J0KSBpbnRWYWx1ZTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBpbnRWYWx1ZSkgeworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJWYWx1ZSBvdXQgb2YgcmFuZ2UgZm9yIHNob3J0OiBcIiIgKyBzdHJpbmcgKyAiXCIiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBwcmltaXRpdmUgdmFsdWUgb2YgdGhpcyBzaG9ydC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBvYmplY3QncyBwcmltaXRpdmUgdmFsdWUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHNob3J0IHNob3J0VmFsdWUoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gSW50ZWdlci50b1N0cmluZyh2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhlCisgICAgICogc3BlY2lmaWVkIHNob3J0IHZhbHVlIHdpdGggcmFkaXggMTAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgICB0aGUgc2hvcnQgdG8gY29udmVydCB0byBhIHN0cmluZy4KKyAgICAgKiBAcmV0dXJuIGEgcHJpbnRhYmxlIHJlcHJlc2VudGF0aW9uIG9mIHtAY29kZSB2YWx1ZX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoc2hvcnQgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIEludGVnZXIudG9TdHJpbmcodmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgc3BlY2lmaWVkIHN0cmluZyBhcyBhIHNpZ25lZCBkZWNpbWFsIHNob3J0IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHNob3J0IHZhbHVlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgU2hvcnR9IGluc3RhbmNlIGNvbnRhaW5pbmcgdGhlIHNob3J0IHZhbHVlIHJlcHJlc2VudGVkCisgICAgICogICAgICAgICBieSB7QGNvZGUgc3RyaW5nfS4KKyAgICAgKiBAdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdHJpbmd9IGNhbm5vdCBiZSBwYXJzZWQgYXMgYSBzaG9ydCB2YWx1ZS4KKyAgICAgKiBAc2VlICNwYXJzZVNob3J0KFN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNob3J0IHZhbHVlT2YoU3RyaW5nIHN0cmluZykgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiB2YWx1ZU9mKHBhcnNlU2hvcnQoc3RyaW5nKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGFzIGEgc2lnbmVkIHNob3J0IHZhbHVlIHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiByYWRpeC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBzaG9ydCB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gcmFkaXgKKyAgICAgKiAgICAgICAgICAgIHRoZSByYWRpeCB0byB1c2Ugd2hlbiBwYXJzaW5nLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgU2hvcnR9IGluc3RhbmNlIGNvbnRhaW5pbmcgdGhlIHNob3J0IHZhbHVlIHJlcHJlc2VudGVkCisgICAgICogICAgICAgICBieSB7QGNvZGUgc3RyaW5nfSB1c2luZyB7QGNvZGUgcmFkaXh9LgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0cmluZ30gY2Fubm90IGJlIHBhcnNlZCBhcyBhIHNob3J0IHZhbHVlLCBvcgorICAgICAqICAgICAgICAgICAgIHtAY29kZSByYWRpeCA8IENoYXJhY3Rlci5NSU5fUkFESVggfHwKKyAgICAgKiAgICAgICAgICAgICByYWRpeCA+IENoYXJhY3Rlci5NQVhfUkFESVh9LgorICAgICAqIEBzZWUgI3BhcnNlU2hvcnQoU3RyaW5nLCBpbnQpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTaG9ydCB2YWx1ZU9mKFN0cmluZyBzdHJpbmcsIGludCByYWRpeCkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiB2YWx1ZU9mKHBhcnNlU2hvcnQoc3RyaW5nLCByYWRpeCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldmVyc2VzIHRoZSBieXRlcyBvZiB0aGUgc3BlY2lmaWVkIHNob3J0LgorICAgICAqCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaG9ydCB2YWx1ZSBmb3Igd2hpY2ggdG8gcmV2ZXJzZSBieXRlcy4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXZlcnNlZCB2YWx1ZS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBzaG9ydCByZXZlcnNlQnl0ZXMoc2hvcnQgcykgeworICAgICAgICByZXR1cm4gKHNob3J0KSAoKHMgPDwgOCkgfCAoKHMgPj4+IDgpICYgMHhGRikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgU2hvcnR9IGluc3RhbmNlIGZvciB0aGUgc3BlY2lmaWVkIHNob3J0IHZhbHVlLgorICAgICAqIDxwPgorICAgICAqIElmIGl0IGlzIG5vdCBuZWNlc3NhcnkgdG8gZ2V0IGEgbmV3IHtAY29kZSBTaG9ydH0gaW5zdGFuY2UsIGl0IGlzCisgICAgICogcmVjb21tZW5kZWQgdG8gdXNlIHRoaXMgbWV0aG9kIGluc3RlYWQgb2YgdGhlIGNvbnN0cnVjdG9yLCBzaW5jZSBpdAorICAgICAqIG1haW50YWlucyBhIGNhY2hlIG9mIGluc3RhbmNlcyB3aGljaCBtYXkgcmVzdWx0IGluIGJldHRlciBwZXJmb3JtYW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgc2hvcnQgdmFsdWUgdG8gc3RvcmUgaW4gdGhlIGluc3RhbmNlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgU2hvcnR9IGluc3RhbmNlIGNvbnRhaW5pbmcge0Bjb2RlIHN9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNob3J0IHZhbHVlT2Yoc2hvcnQgcykgeworICAgICAgICByZXR1cm4gcyA8IC0xMjggfHwgcyA+PSAxMjggPyBuZXcgU2hvcnQocykgOiBTTUFMTF9WQUxVRVNbcyArIDEyOF07CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBjYWNoZSBvZiBpbnN0YW5jZXMgdXNlZCBieSB7QGxpbmsgU2hvcnQjdmFsdWVPZihzaG9ydCl9IGFuZCBhdXRvLWJveGluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTaG9ydFtdIFNNQUxMX1ZBTFVFUyA9IG5ldyBTaG9ydFsyNTZdOworCisgICAgc3RhdGljIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IC0xMjg7IGkgPCAxMjg7IGkrKykgeworICAgICAgICAgICAgU01BTExfVkFMVUVTW2kgKyAxMjhdID0gbmV3IFNob3J0KChzaG9ydCkgaSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1N0YWNrT3ZlcmZsb3dFcnJvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TdGFja092ZXJmbG93RXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YWY3ZGVlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TdGFja092ZXJmbG93RXJyb3IuamF2YQpAQCAtMCwwICsxLDQ3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gd2hlbiB0aGUgZGVwdGggb2YgdGhlIHN0YWNrIG9mIHRoZSBydW5uaW5nIHByb2dyYW0gZXhjZWVkcyBzb21lCisgKiBwbGF0Zm9ybSBvciBWTSBzcGVjaWZpYyBsaW1pdC4gVHlwaWNhbGx5LCB0aGlzIHdpbGwgb2NjdXIgb25seQorICogd2hlbiBhIHByb2dyYW0gYmVjb21lcyBpbmZpbml0ZWx5IHJlY3Vyc2l2ZSwgYnV0IGl0IGNhbiBhbHNvIG9jY3VyIGluCisgKiBjb3JyZWN0bHkgd3JpdHRlbiAoYnV0IGRlZXBseSByZWN1cnNpdmUpIHByb2dyYW1zLgorICovCitwdWJsaWMgY2xhc3MgU3RhY2tPdmVyZmxvd0Vycm9yIGV4dGVuZHMgVmlydHVhbE1hY2hpbmVFcnJvciB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA4NjA5MTc1MDM4NDQxNzU5NjA3TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFN0YWNrT3ZlcmZsb3dFcnJvcn0gdGhhdCBpbmNsdWRlcyB0aGUgY3VycmVudAorICAgICAqIHN0YWNrIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBTdGFja092ZXJmbG93RXJyb3IoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgU3RhY2tPdmVyZmxvd0Vycm9yfSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlCisgICAgICogYW5kIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RhY2tPdmVyZmxvd0Vycm9yKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvU3RhY2tUcmFjZUVsZW1lbnQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvU3RhY2tUcmFjZUVsZW1lbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iODMxMjBjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TdGFja1RyYWNlRWxlbWVudC5qYXZhCkBAIC0wLDAgKzEsMjMxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworLyoqCisgKiBBIHJlcHJlc2VudGF0aW9uIG9mIGEgc2luZ2xlIHN0YWNrIGZyYW1lLiBBcnJheXMgb2Yge0Bjb2RlIFN0YWNrVHJhY2VFbGVtZW50fQorICogYXJlIHN0b3JlZCBpbiB7QGxpbmsgVGhyb3dhYmxlfSBvYmplY3RzIHRvIHJlcHJlc2VudCB0aGUgd2hvbGUgc3RhdGUgb2YgdGhlCisgKiBjYWxsIHN0YWNrIGF0IHRoZSB0aW1lIGEge0Bjb2RlIFRocm93YWJsZX0gZ2V0cyB0aHJvd24uCisgKgorICogQHNlZSBUaHJvd2FibGUjZ2V0U3RhY2tUcmFjZSgpCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTdGFja1RyYWNlRWxlbWVudCBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA2OTkyMzM3MTYyMzI2MTcxMDEzTDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOQVRJVkVfTElORV9OVU1CRVIgPSAtMjsKKworICAgIFN0cmluZyBkZWNsYXJpbmdDbGFzczsKKworICAgIFN0cmluZyBtZXRob2ROYW1lOworCisgICAgU3RyaW5nIGZpbGVOYW1lOworCisgICAgaW50IGxpbmVOdW1iZXI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBTdGFja1RyYWNlRWxlbWVudH0gZm9yIGEgc3BlY2lmaWVkIGV4ZWN1dGlvbgorICAgICAqIHBvaW50LgorICAgICAqCisgICAgICogQHBhcmFtIGNscworICAgICAqICAgICAgICAgICAgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBjbGFzcyB3aGVyZSBleGVjdXRpb24gaXMgYXQuCisgICAgICogQHBhcmFtIG1ldGhvZAorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIG1ldGhvZCB3aGVyZSBleGVjdXRpb24gaXMgYXQuCisgICAgICogQHBhcmFtIGZpbGUKKyAgICAgKiAgICAgICAgICAgIFRoZSBuYW1lIG9mIHRoZSBmaWxlIHdoZXJlIGV4ZWN1dGlvbiBpcyBhdCBvciB7QGNvZGUgbnVsbH0uCisgICAgICogQHBhcmFtIGxpbmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaW5lIG9mIHRoZSBmaWxlIHdoZXJlIGV4ZWN1dGlvbiBpcyBhdCwgYSBuZWdhdGl2ZSBudW1iZXIKKyAgICAgKiAgICAgICAgICAgIGlmIHVua25vd24gb3Ige0Bjb2RlIC0yfSBpZiB0aGUgZXhlY3V0aW9uIGlzIGluIGEgbmF0aXZlCisgICAgICogICAgICAgICAgICBtZXRob2QuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBjbHN9IG9yIHtAY29kZSBtZXRob2R9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RhY2tUcmFjZUVsZW1lbnQoU3RyaW5nIGNscywgU3RyaW5nIG1ldGhvZCwgU3RyaW5nIGZpbGUsIGludCBsaW5lKSB7CisgICAgICAgIGlmIChjbHMgPT0gbnVsbCB8fCBtZXRob2QgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgZGVjbGFyaW5nQ2xhc3MgPSBjbHM7CisgICAgICAgIG1ldGhvZE5hbWUgPSBtZXRob2Q7CisgICAgICAgIGZpbGVOYW1lID0gZmlsZTsKKyAgICAgICAgbGluZU51bWJlciA9IGxpbmU7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogUHJpdmF0ZSwgbnVsbGFyeSBjb25zdHJ1Y3RvciBmb3IgVk0gdXNlIG9ubHkuCisgICAgICogPC9wPgorICAgICAqLworICAgIHByaXZhdGUgU3RhY2tUcmFjZUVsZW1lbnQoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFuZCBpbmRpY2F0ZXMgaWYgdGhleQorICAgICAqIGFyZSBlcXVhbC4gSW4gb3JkZXIgdG8gYmUgZXF1YWwsIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBtdXN0IGJlCisgICAgICogZnVsZmlsbGVkOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIG9ian0gbXVzdCBiZSBhIHN0YWNrIHRyYWNlIGVsZW1lbnQsPC9saT4KKyAgICAgKiA8bGk+dGhlIG1ldGhvZCBuYW1lcyBvZiB0aGlzIHN0YWNrIHRyYWNlIGVsZW1lbnQgYW5kIG9mIHtAY29kZSBvYmp9IG11c3QKKyAgICAgKiBub3QgYmUge0Bjb2RlIG51bGx9LDwvbGk+CisgICAgICogPGxpPnRoZSBjbGFzcywgbWV0aG9kIGFuZCBmaWxlIG5hbWVzIGFzIHdlbGwgYXMgdGhlIGxpbmUgbnVtYmVyIG9mIHRoaXMKKyAgICAgKiBzdGFjayB0cmFjZSBlbGVtZW50IGFuZCBvZiB7QGNvZGUgb2JqfSBtdXN0IGJlIGVxdWFsLjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB0aGlzIGluc3RhbmNlIHdpdGguCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgZXF1YWwgdG8gdGhpcworICAgICAqICAgICAgICAge0Bjb2RlIFN0YWNrVHJhY2VFbGVtZW50fTsge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNlZSAjaGFzaENvZGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBTdGFja1RyYWNlRWxlbWVudCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBTdGFja1RyYWNlRWxlbWVudCBjYXN0T2JqID0gKFN0YWNrVHJhY2VFbGVtZW50KSBvYmo7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVW5rbm93biBtZXRob2RzIGFyZSBuZXZlciBlcXVhbCB0byBhbnl0aGluZyAobm90IHN0cmljdGx5IHRvIHNwZWMsCisgICAgICAgICAqIGJ1dCBzcGVjIGRvZXMgbm90IGFsbG93IG51bGwgbWV0aG9kL2NsYXNzIG5hbWVzKQorICAgICAgICAgKi8KKyAgICAgICAgaWYgKChtZXRob2ROYW1lID09IG51bGwpIHx8IChjYXN0T2JqLm1ldGhvZE5hbWUgPT0gbnVsbCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghZ2V0TWV0aG9kTmFtZSgpLmVxdWFscyhjYXN0T2JqLmdldE1ldGhvZE5hbWUoKSkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIWdldENsYXNzTmFtZSgpLmVxdWFscyhjYXN0T2JqLmdldENsYXNzTmFtZSgpKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBsb2NhbEZpbGVOYW1lID0gZ2V0RmlsZU5hbWUoKTsKKyAgICAgICAgaWYgKGxvY2FsRmlsZU5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKGNhc3RPYmouZ2V0RmlsZU5hbWUoKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKCFsb2NhbEZpbGVOYW1lLmVxdWFscyhjYXN0T2JqLmdldEZpbGVOYW1lKCkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChnZXRMaW5lTnVtYmVyKCkgIT0gY2FzdE9iai5nZXRMaW5lTnVtYmVyKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBjbGFzcyBiZWxvbmdpbmcgdG8gdGhpcworICAgICAqIHtAY29kZSBTdGFja1RyYWNlRWxlbWVudH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBmdWxseSBxdWFsaWZpZWQgdHlwZSBuYW1lIG9mIHRoZSBjbGFzcworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2xhc3NOYW1lKCkgeworICAgICAgICByZXR1cm4gKGRlY2xhcmluZ0NsYXNzID09IG51bGwpID8gIjx1bmtub3duIGNsYXNzPiIgOiBkZWNsYXJpbmdDbGFzczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBKYXZhIHNvdXJjZSBmaWxlIGNvbnRhaW5pbmcgY2xhc3MgYmVsb25naW5nIHRvCisgICAgICogdGhpcyB7QGNvZGUgU3RhY2tUcmFjZUVsZW1lbnR9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgZmlsZSwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoaXMgaW5mb3JtYXRpb24gaXMgbm90CisgICAgICogICAgICAgICBhdmFpbGFibGUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRGaWxlTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIGZpbGVOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxpbmUgbnVtYmVyIGluIHRoZSBzb3VyY2UgZm9yIHRoZSBjbGFzcyBiZWxvbmdpbmcgdG8gdGhpcworICAgICAqIHtAY29kZSBTdGFja1RyYWNlRWxlbWVudH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsaW5lIG51bWJlciwgb3IgYSBuZWdhdGl2ZSBudW1iZXIgaWYgdGhpcyBpbmZvcm1hdGlvbiBpcyBub3QKKyAgICAgKiAgICAgICAgIGF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKSB7CisgICAgICAgIHJldHVybiBsaW5lTnVtYmVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIG1ldGhvZCBiZWxvbmdpbmcgdG8gdGhpcyB7QGNvZGUKKyAgICAgKiBTdGFja1RyYWNlRWxlbWVudH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBtZXRob2QsIG9yICI8dW5rbm93biBtZXRob2Q+IiBpZiB0aGlzIGluZm9ybWF0aW9uCisgICAgICogICAgICAgICBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWV0aG9kTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIChtZXRob2ROYW1lID09IG51bGwpID8gIjx1bmtub3duIG1ldGhvZD4iIDogbWV0aG9kTmFtZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAvKgorICAgICAgICAgKiBFaXRoZXIgYm90aCBtZXRob2ROYW1lIGFuZCBkZWNsYXJpbmdDbGFzcyBhcmUgbnVsbCwgb3IgbmVpdGhlciBhcmUKKyAgICAgICAgICogbnVsbC4KKyAgICAgICAgICovCisgICAgICAgIGlmIChtZXRob2ROYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGFsbCB1bmtub3duIG1ldGhvZHMgaGFzaCB0aGUgc2FtZQorICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgLy8gZGVjbGFyaW5nQ2xhc3MgbmV2ZXIgbnVsbCBpZiBtZXRob2ROYW1lIGlzIG5vbi1udWxsCisgICAgICAgIHJldHVybiBtZXRob2ROYW1lLmhhc2hDb2RlKCkgXiBkZWNsYXJpbmdDbGFzcy5oYXNoQ29kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyBpZiB0aGUgbWV0aG9kIG5hbWUgcmV0dXJuZWQgYnkge0BsaW5rICNnZXRNZXRob2ROYW1lKCl9IGlzCisgICAgICogaW1wbGVtZW50ZWQgYXMgYSBuYXRpdmUgbWV0aG9kLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIG1ldGhvZCBpbiB3aGljaCB0aGlzIHN0YWNrIHRyYWNlIGVsZW1lbnQgaXMKKyAgICAgKiAgICAgICAgIGV4ZWN1dGluZyBpcyBhIG5hdGl2ZSBtZXRob2Q7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzTmF0aXZlTWV0aG9kKCkgeworICAgICAgICByZXR1cm4gbGluZU51bWJlciA9PSBOQVRJVkVfTElORV9OVU1CRVI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcig4MCk7CisKKyAgICAgICAgYnVmLmFwcGVuZChnZXRDbGFzc05hbWUoKSk7CisgICAgICAgIGJ1Zi5hcHBlbmQoJy4nKTsKKyAgICAgICAgYnVmLmFwcGVuZChnZXRNZXRob2ROYW1lKCkpOworCisgICAgICAgIGlmIChpc05hdGl2ZU1ldGhvZCgpKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKCIoTmF0aXZlIE1ldGhvZCkiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFN0cmluZyBmTmFtZSA9IGdldEZpbGVOYW1lKCk7CisKKyAgICAgICAgICAgIGlmIChmTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiKFVua25vd24gU291cmNlKSIpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpbnQgbGluZU51bSA9IGdldExpbmVOdW1iZXIoKTsKKworICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJygnKTsKKyAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGZOYW1lKTsKKyAgICAgICAgICAgICAgICBpZiAobGluZU51bSA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJzonKTsKKyAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChsaW5lTnVtKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnKScpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1N0cmljdE1hdGguamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvU3RyaWN0TWF0aC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyMTAyN2IKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1N0cmljdE1hdGguamF2YQpAQCAtMCwwICsxLDEyMzAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIENsYXNzIFN0cmljdE1hdGggcHJvdmlkZXMgYmFzaWMgbWF0aCBjb25zdGFudHMgYW5kIG9wZXJhdGlvbnMgc3VjaCBhcworICogdHJpZ29ub21ldHJpYyBmdW5jdGlvbnMsIGh5cGVyYm9saWMgZnVuY3Rpb25zLCBleHBvbmVudGlhbCwgbG9nYXJpdGhtcywgZXRjLgorICogPHA+CisgKiBJbiBjb250cmFzdCB0byBjbGFzcyB7QGxpbmsgTWF0aH0sIHRoZSBtZXRob2RzIGluIHRoaXMgY2xhc3MgcmV0dXJuIGV4YWN0bHkKKyAqIHRoZSBzYW1lIHJlc3VsdHMgb24gYWxsIHBsYXRmb3Jtcy4gQWxnb3JpdGhtcyBiYXNlZCBvbiB0aGVzZSBtZXRob2RzIHRodXMKKyAqIGJlaGF2ZSB0aGUgc2FtZSAoZS5nLiByZWdhcmRpbmcgbnVtZXJpY2FsIGNvbnZlcmdlbmNlKSBvbiBhbGwgcGxhdGZvcm1zLAorICogY29tcGx5aW5nIHdpdGggdGhlIHNsb2dhbiAid3JpdGUgb25jZSwgcnVuIGV2ZXJ5d2hlcmUiLiBPbiB0aGUgb3RoZXIgc2lkZSwKKyAqIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBjbGFzcyBTdHJpY3RNYXRoIG1heSBiZSBsZXNzIGVmZmljaWVudCB0aGFuIHRoYXQgb2YKKyAqIGNsYXNzIE1hdGgsIGFzIGNsYXNzIFN0cmljdE1hdGggY2Fubm90IHV0aWxpemUgcGxhdGZvcm0gc3BlY2lmaWMgZmVhdHVyZXMKKyAqIHN1Y2ggYXMgYW4gZXh0ZW5kZWQgcHJlY2lzaW9uIG1hdGggY28tcHJvY2Vzc29ycy4KKyAqIDxwPgorICogVGhlIG1ldGhvZHMgaW4gdGhpcyBjbGFzcyBhcmUgc3BlY2lmaWVkIHVzaW5nIHRoZSAiRnJlZWx5IERpc3RyaWJ1dGFibGUgTWF0aAorICogTGlicmFyeSIgKGZkbGlibSksIHZlcnNpb24gNS4zLgorICogPHA+CisgKiA8YSBocmVmPSJodHRwOi8vd3d3Lm5ldGxpYi5vcmcvZmRsaWJtLyI+aHR0cDovL3d3dy5uZXRsaWIub3JnL2ZkbGlibS88L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTdHJpY3RNYXRoIHsKKyAgICAvKioKKyAgICAgKiBUaGUgZG91YmxlIHZhbHVlIGNsb3Nlc3QgdG8gZSwgdGhlIGJhc2Ugb2YgdGhlIG5hdHVyYWwgbG9nYXJpdGhtLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgZG91YmxlIEUgPSBNYXRoLkU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZG91YmxlIHZhbHVlIGNsb3Nlc3QgdG8gcGksIHRoZSByYXRpbyBvZiBhIGNpcmNsZSdzIGNpcmN1bWZlcmVuY2UgdG8KKyAgICAgKiBpdHMgZGlhbWV0ZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBkb3VibGUgUEkgPSBNYXRoLlBJOworCisgICAgLyoqCisgICAgICogUHJldmVudHMgdGhpcyBjbGFzcyBmcm9tIGJlaW5nIGluc3RhbnRpYXRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmljdE1hdGgoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIGFyZ3VtZW50LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgYWJzKC0wLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYWJzKCtpbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGFicygtaW5maW5pdHkpID0gK2luZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBhYnMoTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHdob3NlIGFic29sdXRlIHZhbHVlIGhhcyB0byBiZSBjb21wdXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgYWJzKGRvdWJsZSBkKSB7CisgICAgICAgIHJldHVybiBNYXRoLmFicyhkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGUgYXJndW1lbnQuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBhYnMoLTAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBhYnMoK2luZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYWJzKC1pbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGFicyhOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgd2hvc2UgYWJzb2x1dGUgdmFsdWUgaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGFyZ3VtZW50IGlmIGl0IGlzIHBvc2l0aXZlLCBvdGhlcndpc2UgdGhlIG5lZ2F0aW9uIG9mIHRoZQorICAgICAqICAgICAgICAgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmbG9hdCBhYnMoZmxvYXQgZikgeworICAgICAgICByZXR1cm4gTWF0aC5hYnMoZik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIGFyZ3VtZW50LgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBhcmd1bWVudCBpcyB7QGNvZGUgSW50ZWdlci5NSU5fVkFMVUV9LCB7QGNvZGUgSW50ZWdlci5NSU5fVkFMVUV9CisgICAgICogaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHdob3NlIGFic29sdXRlIHZhbHVlIGhhcyB0byBiZSBjb21wdXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcmd1bWVudCBpZiBpdCBpcyBwb3NpdGl2ZSwgb3RoZXJ3aXNlIHRoZSBuZWdhdGlvbiBvZiB0aGUKKyAgICAgKiAgICAgICAgIGFyZ3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGFicyhpbnQgaSkgeworICAgICAgICByZXR1cm4gTWF0aC5hYnMoaSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIGFyZ3VtZW50LgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBhcmd1bWVudCBpcyB7QGNvZGUgTG9uZy5NSU5fVkFMVUV9LCB7QGNvZGUgTG9uZy5NSU5fVkFMVUV9IGlzCisgICAgICogcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHdob3NlIGFic29sdXRlIHZhbHVlIGhhcyB0byBiZSBjb21wdXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcmd1bWVudCBpZiBpdCBpcyBwb3NpdGl2ZSwgb3RoZXJ3aXNlIHRoZSBuZWdhdGlvbiBvZiB0aGUKKyAgICAgKiAgICAgICAgIGFyZ3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBhYnMobG9uZyBsKSB7CisgICAgICAgIHJldHVybiBNYXRoLmFicyhsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSBhcmMgY29zaW5lIG9mIHRoZQorICAgICAqIGFyZ3VtZW50IHdpdGhpbiB0aGUgcmFuZ2Uge0Bjb2RlIFswLi5waV19LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgYWNvcygoYW55dGhpbmcgPiAxKSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYWNvcygoYW55dGhpbmcgPCAtMSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGFjb3MoTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIGNvbXB1dGUgYXJjIGNvc2luZSBvZi4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcmMgY29zaW5lIG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgYWNvcyhkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSBhcmMgc2luZSBvZiB0aGUgYXJndW1lbnQKKyAgICAgKiB3aXRoaW4gdGhlIHJhbmdlIHtAY29kZSBbLXBpLzIuLnBpLzJdfS4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIGFzaW4oKGFueXRoaW5nID4gMSkpID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBhc2luKChhbnl0aGluZyA8IC0xKSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGFzaW4oTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHdob3NlIGFyYyBzaW5lIGhhcyB0byBiZSBjb21wdXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcmMgc2luZSBvZiB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIGFzaW4oZG91YmxlIGQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2xvc2VzdCBkb3VibGUgYXBwcm94aW1hdGlvbiBvZiB0aGUgYXJjIHRhbmdlbnQgb2YgdGhlCisgICAgICogYXJndW1lbnQgd2l0aGluIHRoZSByYW5nZSB7QGNvZGUgWy1waS8yLi5waS8yXX0uCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBhdGFuKCswLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXRhbigtMC4wKSA9IC0wLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGF0YW4oK2luZmluaXR5KSA9ICtwaS8yfTwvbGk+CisgICAgICogPGxpPntAY29kZSBhdGFuKC1pbmZpbml0eSkgPSAtcGkvMn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXRhbihOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgd2hvc2UgYXJjIHRhbmdlbnQgaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGFyYyB0YW5nZW50IG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgYXRhbihkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSBhcmMgdGFuZ2VudCBvZgorICAgICAqIHtAY29kZSB5L3h9IHdpdGhpbiB0aGUgcmFuZ2Uge0Bjb2RlIFstcGkuLnBpXX0uIFRoaXMgaXMgdGhlIGFuZ2xlIG9mIHRoZQorICAgICAqIHBvbGFyIHJlcHJlc2VudGF0aW9uIG9mIHRoZSByZWN0YW5ndWxhciBjb29yZGluYXRlcyAoeCx5KS4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIGF0YW4yKChhbnl0aGluZyksIE5hTiApID0gTmFOO308L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXRhbjIoTmFOICwgKGFueXRoaW5nKSApID0gTmFOO308L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXRhbjIoKzAuMCwgKyhhbnl0aGluZyBidXQgTmFOKSkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBhdGFuMigtMC4wLCArKGFueXRoaW5nIGJ1dCBOYU4pKSA9IC0wLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGF0YW4yKCswLjAsIC0oYW55dGhpbmcgYnV0IE5hTikpID0gK3BpfTwvbGk+CisgICAgICogPGxpPntAY29kZSBhdGFuMigtMC4wLCAtKGFueXRoaW5nIGJ1dCBOYU4pKSA9IC1waX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXRhbjIoKyhhbnl0aGluZyBidXQgMCBhbmQgTmFOKSwgMCkgPSArcGkvMn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXRhbjIoLShhbnl0aGluZyBidXQgMCBhbmQgTmFOKSwgMCkgPSAtcGkvMn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXRhbjIoKyhhbnl0aGluZyBidXQgaW5maW5pdHkgYW5kIE5hTiksICtpbmZpbml0eSl9IHtAY29kZSA9fQorICAgICAqIHtAY29kZSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBhdGFuMigtKGFueXRoaW5nIGJ1dCBpbmZpbml0eSBhbmQgTmFOKSwgK2luZmluaXR5KX0ge0Bjb2RlID19CisgICAgICoge0Bjb2RlIC0wLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGF0YW4yKCsoYW55dGhpbmcgYnV0IGluZmluaXR5IGFuZCBOYU4pLCAtaW5maW5pdHkpID0gK3BpfTwvbGk+CisgICAgICogPGxpPntAY29kZSBhdGFuMigtKGFueXRoaW5nIGJ1dCBpbmZpbml0eSBhbmQgTmFOKSwgLWluZmluaXR5KSA9IC1waX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgYXRhbjIoK2luZmluaXR5LCAraW5maW5pdHkgKSA9ICtwaS80fTwvbGk+CisgICAgICogPGxpPntAY29kZSBhdGFuMigtaW5maW5pdHksICtpbmZpbml0eSApID0gLXBpLzR9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGF0YW4yKCtpbmZpbml0eSwgLWluZmluaXR5ICkgPSArM3BpLzR9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGF0YW4yKC1pbmZpbml0eSwgLWluZmluaXR5ICkgPSAtM3BpLzR9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGF0YW4yKCtpbmZpbml0eSwgKGFueXRoaW5nIGJ1dCwwLCBOYU4sIGFuZCBpbmZpbml0eSkpfQorICAgICAqIHtAY29kZSA9fSB7QGNvZGUgK3BpLzJ9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGF0YW4yKC1pbmZpbml0eSwgKGFueXRoaW5nIGJ1dCwwLCBOYU4sIGFuZCBpbmZpbml0eSkpfQorICAgICAqIHtAY29kZSA9fSB7QGNvZGUgLXBpLzJ9PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1lcmF0b3Igb2YgdGhlIHZhbHVlIHdob3NlIGF0YW4gaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgZGVub21pbmF0b3Igb2YgdGhlIHZhbHVlIHdob3NlIGF0YW4gaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGFyYyB0YW5nZW50IG9mIHtAY29kZSB5L3h9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGRvdWJsZSBhdGFuMihkb3VibGUgeSwgZG91YmxlIHgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2xvc2VzdCBkb3VibGUgYXBwcm94aW1hdGlvbiBvZiB0aGUgY3ViZSByb290IG9mIHRoZQorICAgICAqIGFyZ3VtZW50LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgY2JydCgrMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGNicnQoLTAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBjYnJ0KCtpbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGNicnQoLWluZmluaXR5KSA9IC1pbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgY2JydChOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgd2hvc2UgY3ViZSByb290IGhhcyB0byBiZSBjb21wdXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBjdWJlIHJvb3Qgb2YgdGhlIGFyZ3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGRvdWJsZSBjYnJ0KGRvdWJsZSBkKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRvdWJsZSBjb252ZXJzaW9uIG9mIHRoZSBtb3N0IG5lZ2F0aXZlIChjbG9zZXN0IHRvIG5lZ2F0aXZlCisgICAgICogaW5maW5pdHkpIGludGVnZXIgdmFsdWUgd2hpY2ggaXMgZ3JlYXRlciB0aGFuIHRoZSBhcmd1bWVudC4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIGNlaWwoKzAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBjZWlsKC0wLjApID0gLTAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgY2VpbCgoYW55dGhpbmcgaW4gcmFuZ2UgKC0xLDApKSA9IC0wLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGNlaWwoK2luZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgY2VpbCgtaW5maW5pdHkpID0gLWluZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBjZWlsKE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB3aG9zZSBjbG9zZXN0IGludGVnZXIgdmFsdWUgaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGNlaWxpbmcgb2YgdGhlIGFyZ3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGRvdWJsZSBjZWlsKGRvdWJsZSBkKTsKKworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2xvc2VzdCBkb3VibGUgYXBwcm94aW1hdGlvbiBvZiB0aGUgaHlwZXJib2xpYyBjb3NpbmUgb2YgdGhlCisgICAgICogYXJndW1lbnQuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBjb3NoKCtpbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGNvc2goLWluZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgY29zaChOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgd2hvc2UgaHlwZXJib2xpYyBjb3NpbmUgaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGh5cGVyYm9saWMgY29zaW5lIG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgY29zaChkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSBjb3NpbmUgb2YgdGhlIGFyZ3VtZW50LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgY29zKCtpbmZpbml0eSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGNvcygtaW5maW5pdHkpID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBjb3MoTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIGFuZ2xlIHdob3NlIGNvc2luZSBoYXMgdG8gYmUgY29tcHV0ZWQsIGluIHJhZGlhbnMuCisgICAgICogQHJldHVybiB0aGUgY29zaW5lIG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgY29zKGRvdWJsZSBkKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNsb3Nlc3QgZG91YmxlIGFwcHJveGltYXRpb24gb2YgdGhlIHJhaXNpbmcgImUiIHRvIHRoZSBwb3dlcgorICAgICAqIG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIGV4cCgraW5maW5pdHkpID0gK2luZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBleHAoLWluZmluaXR5KSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGV4cChOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgd2hvc2UgZXhwb25lbnRpYWwgaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGV4cG9uZW50aWFsIG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgZXhwKGRvdWJsZSBkKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNsb3Nlc3QgZG91YmxlIGFwcHJveGltYXRpb24gb2YgPGk+e0Bjb2RlIGV9PC9pPjxzdXA+CisgICAgICoge0Bjb2RlIGR9PC9zdXA+e0Bjb2RlIC0gMX0uIElmIHRoZSBhcmd1bWVudCBpcyB2ZXJ5IGNsb3NlIHRvIDAsIGl0IGlzCisgICAgICogbXVjaCBtb3JlIGFjY3VyYXRlIHRvIHVzZSB7QGNvZGUgZXhwbTEoZCkrMX0gdGhhbiB7QGNvZGUgZXhwKGQpfSAoZHVlIHRvCisgICAgICogY2FuY2VsbGF0aW9uIG9mIHNpZ25pZmljYW50IGRpZ2l0cykuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBleHBtMSgrMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGV4cG0xKC0wLjApID0gLTAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgZXhwbTEoK2luZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgZXhwbTEoLWluZmluaXR5KSA9IC0xLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGV4cG0xKE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0byBjb21wdXRlIHRoZSA8aT57QGNvZGUgZX08L2k+PHN1cD57QGNvZGUgZH08L3N1cD4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSAtIDF9IG9mLgorICAgICAqIEByZXR1cm4gdGhlIDxpPntAY29kZSBlfTwvaT48c3VwPntAY29kZSBkfTwvc3VwPntAY29kZSAtIDF9IHZhbHVlCisgICAgICogICAgICAgICBvZiB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIGV4cG0xKGRvdWJsZSBkKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRvdWJsZSBjb252ZXJzaW9uIG9mIHRoZSBtb3N0IHBvc2l0aXZlIChjbG9zZXN0IHRvCisgICAgICogcG9zaXRpdmUgaW5maW5pdHkpIGludGVnZXIgdmFsdWUgd2hpY2ggaXMgbGVzcyB0aGFuIHRoZSBhcmd1bWVudC4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIGZsb29yKCswLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgZmxvb3IoLTAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBmbG9vcigraW5maW5pdHkpID0gK2luZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBmbG9vcigtaW5maW5pdHkpID0gLWluZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBmbG9vcihOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkIHRoZSB2YWx1ZSB3aG9zZSBjbG9zZXN0IGludGVnZXIgdmFsdWUgaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGZsb29yIG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgZmxvb3IoZG91YmxlIGQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB7QGNvZGUgc3FydCh9PGk+e0Bjb2RlIHh9PC9pPjxzdXA+e0Bjb2RlIDJ9PC9zdXA+e0Bjb2RlICt9CisgICAgICogPGk+IHtAY29kZSB5fTwvaT48c3VwPntAY29kZSAyfTwvc3VwPntAY29kZSApfS4gVGhlIGZpbmFsIHJlc3VsdCBpcworICAgICAqIHdpdGhvdXQgbWVkaXVtIHVuZGVyZmxvdyBvciBvdmVyZmxvdy4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIGh5cG90KCtpbmZpbml0eSwgKGFueXRoaW5nIGluY2x1ZGluZyBOYU4pKSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgaHlwb3QoLWluZmluaXR5LCAoYW55dGhpbmcgaW5jbHVkaW5nIE5hTikpID0gK2luZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBoeXBvdCgoYW55dGhpbmcgaW5jbHVkaW5nIE5hTiksICtpbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGh5cG90KChhbnl0aGluZyBpbmNsdWRpbmcgTmFOKSwgLWluZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgaHlwb3QoTmFOLCBOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICBhIGRvdWJsZSBudW1iZXIuCisgICAgICogQHBhcmFtIHkKKyAgICAgKiAgICAgICAgICAgIGEgZG91YmxlIG51bWJlci4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgc3FydCh9PGk+e0Bjb2RlIHh9PC9pPjxzdXA+e0Bjb2RlIDJ9PC9zdXA+e0Bjb2RlICt9CisgICAgICogICAgICAgICA8aT4ge0Bjb2RlIHl9PC9pPjxzdXA+e0Bjb2RlIDJ9PC9zdXA+e0Bjb2RlICl9IHZhbHVlIG9mIHRoZQorICAgICAqICAgICAgICAgYXJndW1lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGRvdWJsZSBoeXBvdChkb3VibGUgeCwgZG91YmxlIHkpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmVtYWluZGVyIG9mIGRpdmlkaW5nIHtAY29kZSB4fSBieSB7QGNvZGUgeX0gdXNpbmcgdGhlIElFRUUKKyAgICAgKiA3NTQgcnVsZXMuIFRoZSByZXN1bHQgaXMge0Bjb2RlIHgtcm91bmQoeC9wKSpwfSB3aGVyZSB7QGNvZGUgcm91bmQoeC9wKX0KKyAgICAgKiBpcyB0aGUgbmVhcmVzdCBpbnRlZ2VyIChyb3VuZGVkIHRvIGV2ZW4pLCBidXQgd2l0aG91dCBudW1lcmljYWwKKyAgICAgKiBjYW5jZWxsYXRpb24gcHJvYmxlbXMuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBJRUVFcmVtYWluZGVyKChhbnl0aGluZyksIDApID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBJRUVFcmVtYWluZGVyKCtpbmZpbml0eSwgKGFueXRoaW5nKSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIElFRUVyZW1haW5kZXIoLWluZmluaXR5LCAoYW55dGhpbmcpKSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgSUVFRXJlbWFpbmRlcihOYU4sIChhbnl0aGluZykpID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBJRUVFcmVtYWluZGVyKChhbnl0aGluZyksIE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIElFRUVyZW1haW5kZXIoeCwgK2luZmluaXR5KSA9IHggfSB3aGVyZSB4IGlzIGFueXRoaW5nIGJ1dAorICAgICAqICsvLWluZmluaXR5PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIElFRUVyZW1haW5kZXIoeCwgLWluZmluaXR5KSA9IHggfSB3aGVyZSB4IGlzIGFueXRoaW5nIGJ1dAorICAgICAqICsvLWluZmluaXR5PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1lcmF0b3Igb2YgdGhlIG9wZXJhdGlvbi4KKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIGRlbm9taW5hdG9yIG9mIHRoZSBvcGVyYXRpb24uCisgICAgICogQHJldHVybiB0aGUgSUVFRTc1NCBmbG9hdGluZyBwb2ludCByZW1pbmRlciBvZiBvZiB7QGNvZGUgeC95fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgSUVFRXJlbWFpbmRlcihkb3VibGUgeCwgZG91YmxlIHkpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2xvc2VzdCBkb3VibGUgYXBwcm94aW1hdGlvbiBvZiB0aGUgbmF0dXJhbCBsb2dhcml0aG0gb2YgdGhlCisgICAgICogYXJndW1lbnQuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBsb2coKzAuMCkgPSAtaW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGxvZygtMC4wKSA9IC1pbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbG9nKChhbnl0aGluZyA8IDApID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBsb2coK2luZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbG9nKC1pbmZpbml0eSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGxvZyhOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgd2hvc2UgbG9nIGhhcyB0byBiZSBjb21wdXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBuYXR1cmFsIGxvZ2FyaXRobSBvZiB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIGxvZyhkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSBiYXNlIDEwIGxvZ2FyaXRobSBvZiB0aGUKKyAgICAgKiBhcmd1bWVudC4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIGxvZzEwKCswLjApID0gLWluZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBsb2cxMCgtMC4wKSA9IC1pbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbG9nMTAoKGFueXRoaW5nIDwgMCkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGxvZzEwKCtpbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGxvZzEwKC1pbmZpbml0eSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGxvZzEwKE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB3aG9zZSBiYXNlIDEwIGxvZyBoYXMgdG8gYmUgY29tcHV0ZWQuCisgICAgICogQHJldHVybiB0aGUgbmF0dXJhbCBsb2dhcml0aG0gb2YgdGhlIGFyZ3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGRvdWJsZSBsb2cxMChkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSBuYXR1cmFsIGxvZ2FyaXRobSBvZiB0aGUKKyAgICAgKiBzdW0gb2YgdGhlIGFyZ3VtZW50IGFuZCAxLiBJZiB0aGUgYXJndW1lbnQgaXMgdmVyeSBjbG9zZSB0byAwLCBpdCBpcyBtdWNoCisgICAgICogbW9yZSBhY2N1cmF0ZSB0byB1c2Uge0Bjb2RlIGxvZzFwKGQpfSB0aGFuIHtAY29kZSBsb2coMS4wK2QpfSAoZHVlIHRvCisgICAgICogbnVtZXJpY2FsIGNhbmNlbGxhdGlvbikuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBsb2cxcCgrMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIGxvZzFwKC0wLjApID0gLTAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbG9nMXAoKGFueXRoaW5nIDwgMSkpID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBsb2cxcCgtMS4wKSA9IC1pbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbG9nMXAoK2luZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbG9nMXAoLWluZmluaXR5KSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbG9nMXAoTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIGNvbXB1dGUgdGhlIHtAY29kZSBsbigxK2QpfSBvZi4KKyAgICAgKiBAcmV0dXJuIHRoZSBuYXR1cmFsIGxvZ2FyaXRobSBvZiB0aGUgc3VtIG9mIHRoZSBhcmd1bWVudCBhbmQgMS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgbG9nMXAoZG91YmxlIGQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbW9zdCBwb3NpdGl2ZSAoY2xvc2VzdCB0byBwb3NpdGl2ZSBpbmZpbml0eSkgb2YgdGhlIHR3bworICAgICAqIGFyZ3VtZW50cy4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIG1heChOYU4sIChhbnl0aGluZykpID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBtYXgoKGFueXRoaW5nKSwgTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbWF4KCswLjAsIC0wLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbWF4KC0wLjAsICswLjApID0gKzAuMH08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZDEKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBhcmd1bWVudC4KKyAgICAgKiBAcGFyYW0gZDIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgYXJndW1lbnQuCisgICAgICogQHJldHVybiB0aGUgbGFyZ2VyIG9mIHtAY29kZSBkMX0gYW5kIHtAY29kZSBkMn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgbWF4KGRvdWJsZSBkMSwgZG91YmxlIGQyKSB7CisgICAgICAgIGlmIChkMSA+IGQyKQorICAgICAgICAgICAgcmV0dXJuIGQxOworICAgICAgICBpZiAoZDEgPCBkMikKKyAgICAgICAgICAgIHJldHVybiBkMjsKKyAgICAgICAgLyogaWYgZWl0aGVyIGFyZyBpcyBOYU4sIHJldHVybiBOYU4gKi8KKyAgICAgICAgaWYgKGQxICE9IGQyKQorICAgICAgICAgICAgcmV0dXJuIERvdWJsZS5OYU47CisgICAgICAgIC8qIG1heCggKzAuMCwtMC4wKSA9PSArMC4wICovCisgICAgICAgIGlmIChkMSA9PSAwLjAKKyAgICAgICAgICAgICAgICAmJiAoKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGQxKSAmIERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGQyKSkgJiAweDgwMDAwMDAwMDAwMDAwMDBMKSA9PSAwKQorICAgICAgICAgICAgcmV0dXJuIDAuMDsKKyAgICAgICAgcmV0dXJuIGQxOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1vc3QgcG9zaXRpdmUgKGNsb3Nlc3QgdG8gcG9zaXRpdmUgaW5maW5pdHkpIG9mIHRoZSB0d28KKyAgICAgKiBhcmd1bWVudHMuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBtYXgoTmFOLCAoYW55dGhpbmcpKSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbWF4KChhbnl0aGluZyksIE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIG1heCgrMC4wLCAtMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIG1heCgtMC4wLCArMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGYxCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgYXJndW1lbnQuCisgICAgICogQHBhcmFtIGYyCisgICAgICogICAgICAgICAgICB0aGUgc2Vjb25kIGFyZ3VtZW50LgorICAgICAqIEByZXR1cm4gdGhlIGxhcmdlciBvZiB7QGNvZGUgZjF9IGFuZCB7QGNvZGUgZjJ9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmxvYXQgbWF4KGZsb2F0IGYxLCBmbG9hdCBmMikgeworICAgICAgICBpZiAoZjEgPiBmMikKKyAgICAgICAgICAgIHJldHVybiBmMTsKKyAgICAgICAgaWYgKGYxIDwgZjIpCisgICAgICAgICAgICByZXR1cm4gZjI7CisgICAgICAgIC8qIGlmIGVpdGhlciBhcmcgaXMgTmFOLCByZXR1cm4gTmFOICovCisgICAgICAgIGlmIChmMSAhPSBmMikKKyAgICAgICAgICAgIHJldHVybiBGbG9hdC5OYU47CisgICAgICAgIC8qIG1heCggKzAuMCwtMC4wKSA9PSArMC4wICovCisgICAgICAgIGlmIChmMSA9PSAwLjBmCisgICAgICAgICAgICAgICAgJiYgKChGbG9hdC5mbG9hdFRvSW50Qml0cyhmMSkgJiBGbG9hdC5mbG9hdFRvSW50Qml0cyhmMikpICYgMHg4MDAwMDAwMCkgPT0gMCkKKyAgICAgICAgICAgIHJldHVybiAwLjBmOworICAgICAgICByZXR1cm4gZjE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbW9zdCBwb3NpdGl2ZSAoY2xvc2VzdCB0byBwb3NpdGl2ZSBpbmZpbml0eSkgb2YgdGhlIHR3bworICAgICAqIGFyZ3VtZW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpMQorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IGFyZ3VtZW50LgorICAgICAqIEBwYXJhbSBpMgorICAgICAqICAgICAgICAgICAgdGhlIHNlY29uZCBhcmd1bWVudC4KKyAgICAgKiBAcmV0dXJuIHRoZSBsYXJnZXIgb2Yge0Bjb2RlIGkxfSBhbmQge0Bjb2RlIGkyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBtYXgoaW50IGkxLCBpbnQgaTIpIHsKKyAgICAgICAgcmV0dXJuIE1hdGgubWF4KGkxLCBpMik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbW9zdCBwb3NpdGl2ZSAoY2xvc2VzdCB0byBwb3NpdGl2ZSBpbmZpbml0eSkgb2YgdGhlIHR3bworICAgICAqIGFyZ3VtZW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsMQorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IGFyZ3VtZW50LgorICAgICAqIEBwYXJhbSBsMgorICAgICAqICAgICAgICAgICAgdGhlIHNlY29uZCBhcmd1bWVudC4KKyAgICAgKiBAcmV0dXJuIHRoZSBsYXJnZXIgb2Yge0Bjb2RlIGwxfSBhbmQge0Bjb2RlIGwyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgbWF4KGxvbmcgbDEsIGxvbmcgbDIpIHsKKyAgICAgICAgcmV0dXJuIE1hdGgubWF4KGwxLCBsMik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbW9zdCBuZWdhdGl2ZSAoY2xvc2VzdCB0byBuZWdhdGl2ZSBpbmZpbml0eSkgb2YgdGhlIHR3bworICAgICAqIGFyZ3VtZW50cy4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIG1pbihOYU4sIChhbnl0aGluZykpID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBtaW4oKGFueXRoaW5nKSwgTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbWluKCswLjAsIC0wLjApID0gLTAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgbWluKC0wLjAsICswLjApID0gLTAuMH08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZDEKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBhcmd1bWVudC4KKyAgICAgKiBAcGFyYW0gZDIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgYXJndW1lbnQuCisgICAgICogQHJldHVybiB0aGUgc21hbGxlciBvZiB7QGNvZGUgZDF9IGFuZCB7QGNvZGUgZDJ9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIG1pbihkb3VibGUgZDEsIGRvdWJsZSBkMikgeworICAgICAgICBpZiAoZDEgPiBkMikKKyAgICAgICAgICAgIHJldHVybiBkMjsKKyAgICAgICAgaWYgKGQxIDwgZDIpCisgICAgICAgICAgICByZXR1cm4gZDE7CisgICAgICAgIC8qIGlmIGVpdGhlciBhcmcgaXMgTmFOLCByZXR1cm4gTmFOICovCisgICAgICAgIGlmIChkMSAhPSBkMikKKyAgICAgICAgICAgIHJldHVybiBEb3VibGUuTmFOOworICAgICAgICAvKiBtaW4oICswLjAsLTAuMCkgPT0gLTAuMCAqLworICAgICAgICBpZiAoZDEgPT0gMC4wCisgICAgICAgICAgICAgICAgJiYgKChEb3VibGUuZG91YmxlVG9Mb25nQml0cyhkMSkgfCBEb3VibGUuZG91YmxlVG9Mb25nQml0cyhkMikpICYgMHg4MDAwMDAwMDAwMDAwMDAwbCkgIT0gMCkKKyAgICAgICAgICAgIHJldHVybiAwLjAgKiAoLTEuMCk7CisgICAgICAgIHJldHVybiBkMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtb3N0IG5lZ2F0aXZlIChjbG9zZXN0IHRvIG5lZ2F0aXZlIGluZmluaXR5KSBvZiB0aGUgdHdvCisgICAgICogYXJndW1lbnRzLgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgbWluKE5hTiwgKGFueXRoaW5nKSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIG1pbigoYW55dGhpbmcpLCBOYU4pID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBtaW4oKzAuMCwgLTAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBtaW4oLTAuMCwgKzAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmMQorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IGFyZ3VtZW50LgorICAgICAqIEBwYXJhbSBmMgorICAgICAqICAgICAgICAgICAgdGhlIHNlY29uZCBhcmd1bWVudC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzbWFsbGVyIG9mIHtAY29kZSBmMX0gYW5kIHtAY29kZSBmMn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmbG9hdCBtaW4oZmxvYXQgZjEsIGZsb2F0IGYyKSB7CisgICAgICAgIGlmIChmMSA+IGYyKQorICAgICAgICAgICAgcmV0dXJuIGYyOworICAgICAgICBpZiAoZjEgPCBmMikKKyAgICAgICAgICAgIHJldHVybiBmMTsKKyAgICAgICAgLyogaWYgZWl0aGVyIGFyZyBpcyBOYU4sIHJldHVybiBOYU4gKi8KKyAgICAgICAgaWYgKGYxICE9IGYyKQorICAgICAgICAgICAgcmV0dXJuIEZsb2F0Lk5hTjsKKyAgICAgICAgLyogbWluKCArMC4wLC0wLjApID09IC0wLjAgKi8KKyAgICAgICAgaWYgKGYxID09IDAuMGYKKyAgICAgICAgICAgICAgICAmJiAoKEZsb2F0LmZsb2F0VG9JbnRCaXRzKGYxKSB8IEZsb2F0LmZsb2F0VG9JbnRCaXRzKGYyKSkgJiAweDgwMDAwMDAwKSAhPSAwKQorICAgICAgICAgICAgcmV0dXJuIDAuMGYgKiAoLTEuMGYpOworICAgICAgICByZXR1cm4gZjE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbW9zdCBuZWdhdGl2ZSAoY2xvc2VzdCB0byBuZWdhdGl2ZSBpbmZpbml0eSkgb2YgdGhlIHR3bworICAgICAqIGFyZ3VtZW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpMQorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IGFyZ3VtZW50LgorICAgICAqIEBwYXJhbSBpMgorICAgICAqICAgICAgICAgICAgdGhlIHNlY29uZCBhcmd1bWVudC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzbWFsbGVyIG9mIHtAY29kZSBpMX0gYW5kIHtAY29kZSBpMn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgbWluKGludCBpMSwgaW50IGkyKSB7CisgICAgICAgIHJldHVybiBNYXRoLm1pbihpMSwgaTIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1vc3QgbmVnYXRpdmUgKGNsb3Nlc3QgdG8gbmVnYXRpdmUgaW5maW5pdHkpIG9mIHRoZSB0d28KKyAgICAgKiBhcmd1bWVudHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbDEKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBhcmd1bWVudC4KKyAgICAgKiBAcGFyYW0gbDIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgYXJndW1lbnQuCisgICAgICogQHJldHVybiB0aGUgc21hbGxlciBvZiB7QGNvZGUgbDF9IGFuZCB7QGNvZGUgbDJ9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBtaW4obG9uZyBsMSwgbG9uZyBsMikgeworICAgICAgICByZXR1cm4gTWF0aC5taW4obDEsIGwyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSByZXN1bHQgb2YgcmFpc2luZworICAgICAqIHtAY29kZSB4fSB0byB0aGUgcG93ZXIgb2Yge0Bjb2RlIHl9LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgcG93KChhbnl0aGluZyksICswLjApID0gMS4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBwb3coKGFueXRoaW5nKSwgLTAuMCkgPSAxLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHBvdyh4LCAxLjApID0geH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcG93KChhbnl0aGluZyksIE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHBvdyhOYU4sIChhbnl0aGluZyBleGNlcHQgMCkpID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBwb3coKy8tKHx4fCA+IDEpLCAraW5maW5pdHkpID0gK2luZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBwb3coKy8tKHx4fCA+IDEpLCAtaW5maW5pdHkpID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcG93KCsvLSh8eHwgPCAxKSwgK2luZmluaXR5KSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHBvdygrLy0ofHh8IDwgMSksIC1pbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHBvdygrLy0xLjAgLCAraW5maW5pdHkpID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBwb3coKy8tMS4wICwgLWluZmluaXR5KSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcG93KCswLjAsICgrYW55dGhpbmcgZXhjZXB0IDAsIE5hTikpID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcG93KC0wLjAsICgrYW55dGhpbmcgZXhjZXB0IDAsIE5hTiwgb2RkIGludGVnZXIpKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHBvdygrMC4wLCAoLWFueXRoaW5nIGV4Y2VwdCAwLCBOYU4pKSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcG93KC0wLjAsICgtYW55dGhpbmcgZXhjZXB0IDAsIE5BTiwgb2RkIGludGVnZXIpKX0ge0Bjb2RlID19CisgICAgICoge0Bjb2RlICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcG93KC0wLjAsIChvZGQgaW50ZWdlcikpID0gLXBvdyggKzAgLCAob2RkIGludGVnZXIpICl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHBvdygraW5maW5pdHksICgrYW55dGhpbmcgZXhjZXB0IDAsIE5hTikpID0gK2luZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBwb3coK2luZmluaXR5LCAoLWFueXRoaW5nIGV4Y2VwdCAwLCBOYU4pKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHBvdygtaW5maW5pdHksIChhbnl0aGluZykpID0gLXBvdygwLCAoLWFueXRoaW5nKSl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHBvdygoLWFueXRoaW5nKSwgKGludGVnZXIpKX0ge0Bjb2RlID19CisgICAgICoge0Bjb2RlIHBvdygtMSwoaW50ZWdlcikpKnBvdygrYW55dGhpbmcsaW50ZWdlcil9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHBvdygoLWFueXRoaW5nIGV4Y2VwdCAwIGFuZCBpbmZpbml0eSksIChub24taW50ZWdlcikpfQorICAgICAqIHtAY29kZSA9fSB7QGNvZGUgTkFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgYmFzZSBvZiB0aGUgb3BlcmF0aW9uLgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgZXhwb25lbnQgb2YgdGhlIG9wZXJhdGlvbi4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB4fSB0byB0aGUgcG93ZXIgb2Yge0Bjb2RlIHl9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGRvdWJsZSBwb3coZG91YmxlIHgsIGRvdWJsZSB5KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBwc2V1ZG8tcmFuZG9tIG51bWJlciBiZXR3ZWVuIDAuMCAoaW5jbHVzaXZlKSBhbmQgMS4wCisgICAgICogKGV4Y2x1c2l2ZSkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcHNldWRvLXJhbmRvbSBudW1iZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgcmFuZG9tKCkgeworICAgICAgICByZXR1cm4gTWF0aC5yYW5kb20oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkb3VibGUgY29udmVyc2lvbiBvZiB0aGUgcmVzdWx0IG9mIHJvdW5kaW5nIHRoZSBhcmd1bWVudCB0bworICAgICAqIGFuIGludGVnZXIuIFRpZSBicmVha3MgYXJlIHJvdW5kZWQgdG93YXJkcyBldmVuLgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgcmludCgrMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHJpbnQoLTAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSByaW50KCtpbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHJpbnQoLWluZmluaXR5KSA9IC1pbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcmludChOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gYmUgcm91bmRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBjbG9zZXN0IGludGVnZXIgdG8gdGhlIGFyZ3VtZW50IChhcyBhIGRvdWJsZSkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIHJpbnQoZG91YmxlIGQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmVzdWx0IG9mIHJvdW5kaW5nIHRoZSBhcmd1bWVudCB0byBhbiBpbnRlZ2VyLiBUaGUgcmVzdWx0IGlzCisgICAgICogZXF1aXZhbGVudCB0byB7QGNvZGUgKGxvbmcpIE1hdGguZmxvb3IoZCswLjUpfS4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIHJvdW5kKCswLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcm91bmQoLTAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSByb3VuZCgoYW55dGhpbmcgPiBMb25nLk1BWF9WQUxVRSkgPSBMb25nLk1BWF9WQUxVRX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcm91bmQoKGFueXRoaW5nIDwgTG9uZy5NSU5fVkFMVUUpID0gTG9uZy5NSU5fVkFMVUV9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHJvdW5kKCtpbmZpbml0eSkgPSBMb25nLk1BWF9WQUxVRX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcm91bmQoLWluZmluaXR5KSA9IExvbmcuTUlOX1ZBTFVFfTwvbGk+CisgICAgICogPGxpPntAY29kZSByb3VuZChOYU4pID0gKzAuMH08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIGJlIHJvdW5kZWQuCisgICAgICogQHJldHVybiB0aGUgY2xvc2VzdCBpbnRlZ2VyIHRvIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgcm91bmQoZG91YmxlIGQpIHsKKyAgICAgICAgcmV0dXJuIE1hdGgucm91bmQoZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmVzdWx0IG9mIHJvdW5kaW5nIHRoZSBhcmd1bWVudCB0byBhbiBpbnRlZ2VyLiBUaGUgcmVzdWx0IGlzCisgICAgICogZXF1aXZhbGVudCB0byB7QGNvZGUgKGludCkgTWF0aC5mbG9vcihmKzAuNSl9LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgcm91bmQoKzAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSByb3VuZCgtMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHJvdW5kKChhbnl0aGluZyA+IEludGVnZXIuTUFYX1ZBTFVFKSA9IEludGVnZXIuTUFYX1ZBTFVFfTwvbGk+CisgICAgICogPGxpPntAY29kZSByb3VuZCgoYW55dGhpbmcgPCBJbnRlZ2VyLk1JTl9WQUxVRSkgPSBJbnRlZ2VyLk1JTl9WQUxVRX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgcm91bmQoK2luZmluaXR5KSA9IEludGVnZXIuTUFYX1ZBTFVFfTwvbGk+CisgICAgICogPGxpPntAY29kZSByb3VuZCgtaW5maW5pdHkpID0gSW50ZWdlci5NSU5fVkFMVUV9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHJvdW5kKE5hTikgPSArMC4wfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gYmUgcm91bmRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBjbG9zZXN0IGludGVnZXIgdG8gdGhlIGFyZ3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHJvdW5kKGZsb2F0IGYpIHsKKyAgICAgICAgcmV0dXJuIE1hdGgucm91bmQoZik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2lnbnVtIGZ1bmN0aW9uIG9mIHRoZSBhcmd1bWVudC4gSWYgdGhlIGFyZ3VtZW50IGlzIGxlc3MgdGhhbgorICAgICAqIHplcm8sIGl0IHJldHVybnMgLTEuMC4gSWYgdGhlIGFyZ3VtZW50IGlzIGdyZWF0ZXIgdGhhbiB6ZXJvLCAxLjAgaXMKKyAgICAgKiByZXR1cm5lZC4gSWYgdGhlIGFyZ3VtZW50IGlzIGVpdGhlciBwb3NpdGl2ZSBvciBuZWdhdGl2ZSB6ZXJvLCB0aGUKKyAgICAgKiBhcmd1bWVudCBpcyByZXR1cm5lZCBhcyByZXN1bHQuCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBzaWdudW0oKzAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBzaWdudW0oLTAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBzaWdudW0oK2luZmluaXR5KSA9ICsxLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHNpZ251bSgtaW5maW5pdHkpID0gLTEuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc2lnbnVtKE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB3aG9zZSBzaWdudW0gaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBzaWdudW0gZnVuY3Rpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgc2lnbnVtKGRvdWJsZSBkKXsKKyAgICAgICAgcmV0dXJuIE1hdGguc2lnbnVtKGQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNpZ251bSBmdW5jdGlvbiBvZiB0aGUgYXJndW1lbnQuIElmIHRoZSBhcmd1bWVudCBpcyBsZXNzIHRoYW4KKyAgICAgKiB6ZXJvLCBpdCByZXR1cm5zIC0xLjAuIElmIHRoZSBhcmd1bWVudCBpcyBncmVhdGVyIHRoYW4gemVybywgMS4wIGlzCisgICAgICogcmV0dXJuZWQuIElmIHRoZSBhcmd1bWVudCBpcyBlaXRoZXIgcG9zaXRpdmUgb3IgbmVnYXRpdmUgemVybywgdGhlCisgICAgICogYXJndW1lbnQgaXMgcmV0dXJuZWQgYXMgcmVzdWx0LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgc2lnbnVtKCswLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc2lnbnVtKC0wLjApID0gLTAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc2lnbnVtKCtpbmZpbml0eSkgPSArMS4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBzaWdudW0oLWluZmluaXR5KSA9IC0xLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHNpZ251bShOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgd2hvc2Ugc2lnbnVtIGhhcyB0byBiZSBjb21wdXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgc2lnbnVtIGZ1bmN0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmxvYXQgc2lnbnVtKGZsb2F0IGYpeworICAgICAgICByZXR1cm4gTWF0aC5zaWdudW0oZik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2xvc2VzdCBkb3VibGUgYXBwcm94aW1hdGlvbiBvZiB0aGUgaHlwZXJib2xpYyBzaW5lIG9mIHRoZQorICAgICAqIGFyZ3VtZW50LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgc2luaCgrMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHNpbmgoLTAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBzaW5oKCtpbmZpbml0eSkgPSAraW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHNpbmgoLWluZmluaXR5KSA9IC1pbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc2luaChOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgd2hvc2UgaHlwZXJib2xpYyBzaW5lIGhhcyB0byBiZSBjb21wdXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBoeXBlcmJvbGljIHNpbmUgb2YgdGhlIGFyZ3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGRvdWJsZSBzaW5oKGRvdWJsZSBkKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNsb3Nlc3QgZG91YmxlIGFwcHJveGltYXRpb24gb2YgdGhlIHNpbmUgb2YgdGhlIGFyZ3VtZW50LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgc2luKCswLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc2luKC0wLjApID0gLTAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc2luKCtpbmZpbml0eSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHNpbigtaW5maW5pdHkpID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSBzaW4oTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIGFuZ2xlIHdob3NlIHNpbiBoYXMgdG8gYmUgY29tcHV0ZWQsIGluIHJhZGlhbnMuCisgICAgICogQHJldHVybiB0aGUgc2luZSBvZiB0aGUgYXJndW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZG91YmxlIHNpbihkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGRvdWJsZSBhcHByb3hpbWF0aW9uIG9mIHRoZSBzcXVhcmUgcm9vdCBvZiB0aGUKKyAgICAgKiBhcmd1bWVudC4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIHNxcnQoKzAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSBzcXJ0KC0wLjApID0gLTAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc3FydCggKGFueXRoaW5nIDwgMCkgKSA9IE5hTn08L2xpPgorICAgICAqIDxsaT57QGNvZGUgc3FydCgraW5maW5pdHkpID0gK2luZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSBzcXJ0KE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB3aG9zZSBzcXVhcmUgcm9vdCBoYXMgdG8gYmUgY29tcHV0ZWQuCisgICAgICogQHJldHVybiB0aGUgc3F1YXJlIHJvb3Qgb2YgdGhlIGFyZ3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGRvdWJsZSBzcXJ0KGRvdWJsZSBkKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNsb3Nlc3QgZG91YmxlIGFwcHJveGltYXRpb24gb2YgdGhlIHRhbmdlbnQgb2YgdGhlIGFyZ3VtZW50LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgdGFuKCswLjApID0gKzAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdGFuKC0wLjApID0gLTAuMH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdGFuKCtpbmZpbml0eSkgPSBOYU59PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHRhbigtaW5maW5pdHkpID0gTmFOfTwvbGk+CisgICAgICogPGxpPntAY29kZSB0YW4oTmFOKSA9IE5hTn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIGFuZ2xlIHdob3NlIHRhbmdlbnQgaGFzIHRvIGJlIGNvbXB1dGVkLCBpbiByYWRpYW5zLgorICAgICAqIEByZXR1cm4gdGhlIHRhbmdlbnQgb2YgdGhlIGFyZ3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGRvdWJsZSB0YW4oZG91YmxlIGQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2xvc2VzdCBkb3VibGUgYXBwcm94aW1hdGlvbiBvZiB0aGUgaHlwZXJib2xpYyB0YW5nZW50IG9mIHRoZQorICAgICAqIGFyZ3VtZW50LiBUaGUgYWJzb2x1dGUgdmFsdWUgaXMgYWx3YXlzIGxlc3MgdGhhbiAxLgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgdGFuaCgrMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHRhbmgoLTAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSB0YW5oKCtpbmZpbml0eSkgPSArMS4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSB0YW5oKC1pbmZpbml0eSkgPSAtMS4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSB0YW5oKE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB3aG9zZSBoeXBlcmJvbGljIHRhbmdlbnQgaGFzIHRvIGJlIGNvbXB1dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGh5cGVyYm9saWMgdGFuZ2VudCBvZiB0aGUgYXJndW1lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgdGFuaChkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtZWFzdXJlIGluIGRlZ3JlZXMgb2YgdGhlIHN1cHBsaWVkIHJhZGlhbiBhbmdsZS4gVGhlIHJlc3VsdAorICAgICAqIGlzIHtAY29kZSBhbmdyYWQgKiAxODAgLyBwaX0uCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSB0b0RlZ3JlZXMoKzAuMCkgPSArMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSB0b0RlZ3JlZXMoLTAuMCkgPSAtMC4wfTwvbGk+CisgICAgICogPGxpPntAY29kZSB0b0RlZ3JlZXMoK2luZmluaXR5KSA9ICtpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdG9EZWdyZWVzKC1pbmZpbml0eSkgPSAtaW5maW5pdHl9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHRvRGVncmVlcyhOYU4pID0gTmFOfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbmdyYWQKKyAgICAgKiAgICAgICAgICAgIGFuIGFuZ2xlIGluIHJhZGlhbnMuCisgICAgICogQHJldHVybiB0aGUgZGVncmVlIG1lYXN1cmUgb2YgdGhlIGFuZ2xlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHRvRGVncmVlcyhkb3VibGUgYW5ncmFkKSB7CisgICAgICAgIHJldHVybiBNYXRoLnRvRGVncmVlcyhhbmdyYWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1lYXN1cmUgaW4gcmFkaWFucyBvZiB0aGUgc3VwcGxpZWQgZGVncmVlIGFuZ2xlLiBUaGUgcmVzdWx0CisgICAgICogaXMge0Bjb2RlIGFuZ2RlZyAvIDE4MCAqIHBpfS4KKyAgICAgKiA8cD4KKyAgICAgKiBTcGVjaWFsIGNhc2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIHRvUmFkaWFucygrMC4wKSA9ICswLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHRvUmFkaWFucygtMC4wKSA9IC0wLjB9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHRvUmFkaWFucygraW5maW5pdHkpID0gK2luZmluaXR5fTwvbGk+CisgICAgICogPGxpPntAY29kZSB0b1JhZGlhbnMoLWluZmluaXR5KSA9IC1pbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdG9SYWRpYW5zKE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGFuZ2RlZworICAgICAqICAgICAgICAgICAgYW4gYW5nbGUgaW4gZGVncmVlcy4KKyAgICAgKiBAcmV0dXJuIHRoZSByYWRpYW4gbWVhc3VyZSBvZiB0aGUgYW5nbGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgdG9SYWRpYW5zKGRvdWJsZSBhbmdkZWcpIHsKKyAgICAgICAgcmV0dXJuIE1hdGgudG9SYWRpYW5zKGFuZ2RlZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXJndW1lbnQncyB1bHAgKHVuaXQgaW4gdGhlIGxhc3QgcGxhY2UpLiBUaGUgc2l6ZSBvZiBhIHVscCBvZgorICAgICAqIGEgZG91YmxlIHZhbHVlIGlzIHRoZSBwb3NpdGl2ZSBkaXN0YW5jZSBiZXR3ZWVuIHRoaXMgdmFsdWUgYW5kIHRoZSBkb3VibGUKKyAgICAgKiB2YWx1ZSBuZXh0IGxhcmdlciBpbiBtYWduaXR1ZGUuIEZvciBub24tTmFOIHtAY29kZSB4fSwKKyAgICAgKiB7QGNvZGUgdWxwKC14KSA9PSB1bHAoeCl9LgorICAgICAqIDxwPgorICAgICAqIFNwZWNpYWwgY2FzZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgdWxwKCswLjApID0gRG91YmxlLk1JTl9WQUxVRX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdWxwKC0wLjApID0gRG91YmxlLk1JTl9WQUxVRX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdWxwKCtpbmZpbml0eSkgPSBpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdWxwKC1pbmZpbml0eSkgPSBpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdWxwKE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbG9hdGluZy1wb2ludCB2YWx1ZSB0byBjb21wdXRlIHVscCBvZi4KKyAgICAgKiBAcmV0dXJuIHRoZSBzaXplIG9mIGEgdWxwIG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSB1bHAoZG91YmxlIGQpIHsKKyAgICAgICAgLy8gc3BlY2lhbCBjYXNlcworICAgICAgICBpZiAoRG91YmxlLmlzSW5maW5pdGUoZCkpIHsKKyAgICAgICAgICAgIHJldHVybiBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFk7CisgICAgICAgIH0gZWxzZSBpZiAoZCA9PSBEb3VibGUuTUFYX1ZBTFVFIHx8IGQgPT0gLURvdWJsZS5NQVhfVkFMVUUpIHsKKyAgICAgICAgICAgIHJldHVybiBwb3coMiwgOTcxKTsKKyAgICAgICAgfQorICAgICAgICBkID0gTWF0aC5hYnMoZCk7CisgICAgICAgIHJldHVybiBuZXh0YWZ0ZXIoZCwgRG91YmxlLk1BWF9WQUxVRSkgLSBkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFyZ3VtZW50J3MgdWxwICh1bml0IGluIHRoZSBsYXN0IHBsYWNlKS4gVGhlIHNpemUgb2YgYSB1bHAgb2YKKyAgICAgKiBhIGZsb2F0IHZhbHVlIGlzIHRoZSBwb3NpdGl2ZSBkaXN0YW5jZSBiZXR3ZWVuIHRoaXMgdmFsdWUgYW5kIHRoZSBmbG9hdAorICAgICAqIHZhbHVlIG5leHQgbGFyZ2VyIGluIG1hZ25pdHVkZS4gRm9yIG5vbi1OYU4ge0Bjb2RlIHh9LAorICAgICAqIHtAY29kZSB1bHAoLXgpID09IHVscCh4KX0uCisgICAgICogPHA+CisgICAgICogU3BlY2lhbCBjYXNlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSB1bHAoKzAuMCkgPSBGbG9hdC5NSU5fVkFMVUV9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIHVscCgtMC4wKSA9IEZsb2F0Lk1JTl9WQUxVRX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdWxwKCtpbmZpbml0eSkgPSBpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdWxwKC1pbmZpbml0eSkgPSBpbmZpbml0eX08L2xpPgorICAgICAqIDxsaT57QGNvZGUgdWxwKE5hTikgPSBOYU59PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGYKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbG9hdGluZy1wb2ludCB2YWx1ZSB0byBjb21wdXRlIHVscCBvZi4KKyAgICAgKiBAcmV0dXJuIHRoZSBzaXplIG9mIGEgdWxwIG9mIHRoZSBhcmd1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZsb2F0IHVscChmbG9hdCBmKSB7CisgICAgICAgIHJldHVybiBNYXRoLnVscChmKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgZG91YmxlIG5leHRhZnRlcihkb3VibGUgeCwgZG91YmxlIHkpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGRvdWJsZSB3aXRoIHRoZSBnaXZlbiBtYWduaXR1ZGUgYW5kIHRoZSBzaWduIG9mIHtAY29kZSBzaWdufS4KKyAgICAgKiBJZiB7QGNvZGUgc2lnbn0gaXMgTmFOLCB0aGUgc2lnbiBvZiB0aGUgcmVzdWx0IGlzIHBvc2l0aXZlLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSBjb3B5U2lnbihkb3VibGUgbWFnbml0dWRlLCBkb3VibGUgc2lnbikgeworICAgICAgICAvLyBXZSBtYW51YWxseSBpbmxpbmUgRG91YmxlLmlzTmFOIGhlcmUgYmVjYXVzZSB0aGUgSklUIGNhbid0IGRvIGl0IHlldC4KKyAgICAgICAgLy8gV2l0aCBEb3VibGUuaXNOYU46IDIzNi4zbnMKKyAgICAgICAgLy8gV2l0aCBtYW51YWwgaW5saW5lOiAxNDEuMm5zCisgICAgICAgIC8vIFdpdGggbm8gY2hlY2sgKGkuZS4gTWF0aCdzIGJlaGF2aW9yKTogMTEwLjBucworICAgICAgICAvLyAoVGVzdGVkIG9uIGEgTmV4dXMgT25lLikKKyAgICAgICAgbG9uZyBtYWduaXR1ZGVCaXRzID0gRG91YmxlLmRvdWJsZVRvUmF3TG9uZ0JpdHMobWFnbml0dWRlKTsKKyAgICAgICAgbG9uZyBzaWduQml0cyA9IERvdWJsZS5kb3VibGVUb1Jhd0xvbmdCaXRzKChzaWduICE9IHNpZ24pID8gMS4wIDogc2lnbik7CisgICAgICAgIG1hZ25pdHVkZUJpdHMgPSAobWFnbml0dWRlQml0cyAmIH5Eb3VibGUuU0lHTl9NQVNLKSB8IChzaWduQml0cyAmIERvdWJsZS5TSUdOX01BU0spOworICAgICAgICByZXR1cm4gRG91YmxlLmxvbmdCaXRzVG9Eb3VibGUobWFnbml0dWRlQml0cyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGZsb2F0IHdpdGggdGhlIGdpdmVuIG1hZ25pdHVkZSBhbmQgdGhlIHNpZ24gb2Yge0Bjb2RlIHNpZ259LgorICAgICAqIElmIHtAY29kZSBzaWdufSBpcyBOYU4sIHRoZSBzaWduIG9mIHRoZSByZXN1bHQgaXMgcG9zaXRpdmUuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmxvYXQgY29weVNpZ24oZmxvYXQgbWFnbml0dWRlLCBmbG9hdCBzaWduKSB7CisgICAgICAgIC8vIFdlIG1hbnVhbGx5IGlubGluZSBGbG9hdC5pc05hTiBoZXJlIGJlY2F1c2UgdGhlIEpJVCBjYW4ndCBkbyBpdCB5ZXQuCisgICAgICAgIC8vIFdpdGggRmxvYXQuaXNOYU46IDIxNC43bnMKKyAgICAgICAgLy8gV2l0aCBtYW51YWwgaW5saW5lOiAxMTIuM25zCisgICAgICAgIC8vIFdpdGggbm8gY2hlY2sgKGkuZS4gTWF0aCdzIGJlaGF2aW9yKTogOTMuMW5zCisgICAgICAgIC8vIChUZXN0ZWQgb24gYSBOZXh1cyBPbmUuKQorICAgICAgICBpbnQgbWFnbml0dWRlQml0cyA9IEZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKG1hZ25pdHVkZSk7CisgICAgICAgIGludCBzaWduQml0cyA9IEZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKChzaWduICE9IHNpZ24pID8gMS4wZiA6IHNpZ24pOworICAgICAgICBtYWduaXR1ZGVCaXRzID0gKG1hZ25pdHVkZUJpdHMgJiB+RmxvYXQuU0lHTl9NQVNLKSB8IChzaWduQml0cyAmIEZsb2F0LlNJR05fTUFTSyk7CisgICAgICAgIHJldHVybiBGbG9hdC5pbnRCaXRzVG9GbG9hdChtYWduaXR1ZGVCaXRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBleHBvbmVudCBvZiBmbG9hdCB7QGNvZGUgZn0uCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldEV4cG9uZW50KGZsb2F0IGYpIHsKKyAgICAgICAgcmV0dXJuIE1hdGguZ2V0RXhwb25lbnQoZik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZXhwb25lbnQgb2YgZG91YmxlIHtAY29kZSBkfS4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZ2V0RXhwb25lbnQoZG91YmxlIGQpeworICAgICAgICByZXR1cm4gTWF0aC5nZXRFeHBvbmVudChkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGRvdWJsZSBhZnRlciB7QGNvZGUgc3RhcnR9IGluIHRoZSBnaXZlbiB7QGNvZGUgZGlyZWN0aW9ufS4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgbmV4dEFmdGVyKGRvdWJsZSBzdGFydCwgZG91YmxlIGRpcmVjdGlvbikgeworICAgICAgICBpZiAoc3RhcnQgPT0gMCAmJiBkaXJlY3Rpb24gPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGRpcmVjdGlvbjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV4dGFmdGVyKHN0YXJ0LCBkaXJlY3Rpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgZmxvYXQgYWZ0ZXIge0Bjb2RlIHN0YXJ0fSBpbiB0aGUgZ2l2ZW4ge0Bjb2RlIGRpcmVjdGlvbn0uCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmxvYXQgbmV4dEFmdGVyKGZsb2F0IHN0YXJ0LCBkb3VibGUgZGlyZWN0aW9uKSB7CisgICAgICAgIHJldHVybiBNYXRoLm5leHRBZnRlcihzdGFydCwgZGlyZWN0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGRvdWJsZSBsYXJnZXIgdGhhbiB7QGNvZGUgZH0uCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIG5leHRVcChkb3VibGUgZCkgeworICAgICAgICByZXR1cm4gTWF0aC5uZXh0VXAoZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBmbG9hdCBsYXJnZXIgdGhhbiB7QGNvZGUgZn0uCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmxvYXQgbmV4dFVwKGZsb2F0IGYpIHsKKyAgICAgICAgcmV0dXJuIE1hdGgubmV4dFVwKGYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMge0Bjb2RlIGR9ICogMl57QGNvZGUgc2NhbGVGYWN0b3J9LiBUaGUgcmVzdWx0IG1heSBiZSByb3VuZGVkLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSBzY2FsYihkb3VibGUgZCwgaW50IHNjYWxlRmFjdG9yKSB7CisgICAgICAgIGlmIChEb3VibGUuaXNOYU4oZCkgfHwgRG91YmxlLmlzSW5maW5pdGUoZCkgfHwgZCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gZDsKKyAgICAgICAgfQorICAgICAgICAvLyBjaGFuZ2UgZG91YmxlIHRvIGxvbmcgZm9yIGNhbGN1bGF0aW9uCisgICAgICAgIGxvbmcgYml0cyA9IERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGQpOworICAgICAgICAvLyB0aGUgc2lnbiBvZiB0aGUgcmVzdWx0cyBtdXN0IGJlIHRoZSBzYW1lIG9mIGdpdmVuIGQKKyAgICAgICAgbG9uZyBzaWduID0gYml0cyAmIERvdWJsZS5TSUdOX01BU0s7CisgICAgICAgIC8vIGNhbGN1bGF0ZXMgdGhlIGZhY3RvciBvZiB0aGUgcmVzdWx0CisgICAgICAgIGxvbmcgZmFjdG9yID0gKGludCkgKChiaXRzICYgRG91YmxlLkVYUE9ORU5UX01BU0spID4+IERvdWJsZS5NQU5USVNTQV9CSVRTKQorICAgICAgICAgICAgICAgIC0gRG91YmxlLkVYUE9ORU5UX0JJQVMgKyBzY2FsZUZhY3RvcjsKKworICAgICAgICAvLyBjYWxjdWxhdGVzIHRoZSBmYWN0b3Igb2Ygc3ViLW5vcm1hbCB2YWx1ZXMKKyAgICAgICAgaW50IHN1Yk5vcm1hbEZhY3RvciA9IExvbmcubnVtYmVyT2ZMZWFkaW5nWmVyb3MoYml0cyAmIH5Eb3VibGUuU0lHTl9NQVNLKQorICAgICAgICAgICAgICAgIC0gRG91YmxlLkVYUE9ORU5UX0JJVFM7CisgICAgICAgIGlmIChzdWJOb3JtYWxGYWN0b3IgPCAwKSB7CisgICAgICAgICAgICAvLyBub3Qgc3ViLW5vcm1hbCB2YWx1ZXMKKyAgICAgICAgICAgIHN1Yk5vcm1hbEZhY3RvciA9IDA7CisgICAgICAgIH0KKyAgICAgICAgaWYgKE1hdGguYWJzKGQpIDwgRG91YmxlLk1JTl9OT1JNQUwpIHsKKyAgICAgICAgICAgIGZhY3RvciA9IGZhY3RvciAtIHN1Yk5vcm1hbEZhY3RvcjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZmFjdG9yID4gRG91YmxlLk1BWF9FWFBPTkVOVCkgeworICAgICAgICAgICAgcmV0dXJuIChkID4gMCA/IERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSA6IERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSk7CisgICAgICAgIH0KKworICAgICAgICBsb25nIHJlc3VsdDsKKyAgICAgICAgLy8gaWYgcmVzdWx0IGlzIGEgc3ViLW5vcm1hbAorICAgICAgICBpZiAoZmFjdG9yIDwgLURvdWJsZS5FWFBPTkVOVF9CSUFTKSB7CisgICAgICAgICAgICAvLyB0aGUgbnVtYmVyIG9mIGRpZ2l0cyB0aGF0IHNoaWZ0cworICAgICAgICAgICAgbG9uZyBkaWdpdHMgPSBmYWN0b3IgKyBEb3VibGUuRVhQT05FTlRfQklBUyArIHN1Yk5vcm1hbEZhY3RvcjsKKyAgICAgICAgICAgIGlmIChNYXRoLmFicyhkKSA8IERvdWJsZS5NSU5fTk9STUFMKSB7CisgICAgICAgICAgICAgICAgLy8gb3JpZ2luIGQgaXMgYWxyZWFkeSBzdWItbm9ybWFsCisgICAgICAgICAgICAgICAgcmVzdWx0ID0gc2hpZnRMb25nQml0cyhiaXRzICYgRG91YmxlLk1BTlRJU1NBX01BU0ssIGRpZ2l0cyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIG9yaWdpbiBkIGlzIG5vdCBzdWItbm9ybWFsLCBjaGFuZ2UgbWFudGlzc2EgdG8gc3ViLW5vcm1hbAorICAgICAgICAgICAgICAgIHJlc3VsdCA9IHNoaWZ0TG9uZ0JpdHMoYml0cyAmIERvdWJsZS5NQU5USVNTQV9NQVNLIHwgMHgwMDEwMDAwMDAwMDAwMDAwTCwgZGlnaXRzIC0gMSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoTWF0aC5hYnMoZCkgPj0gRG91YmxlLk1JTl9OT1JNQUwpIHsKKyAgICAgICAgICAgICAgICAvLyBjb21tb24gc2l0dWF0aW9uCisgICAgICAgICAgICAgICAgcmVzdWx0ID0gKChmYWN0b3IgKyBEb3VibGUuRVhQT05FTlRfQklBUykgPDwgRG91YmxlLk1BTlRJU1NBX0JJVFMpCisgICAgICAgICAgICAgICAgICAgICAgICB8IChiaXRzICYgRG91YmxlLk1BTlRJU1NBX01BU0spOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBvcmlnaW4gZCBpcyBzdWItbm9ybWFsLCBjaGFuZ2UgbWFudGlzc2EgdG8gbm9ybWFsIHN0eWxlCisgICAgICAgICAgICAgICAgcmVzdWx0ID0gKChmYWN0b3IgKyBEb3VibGUuRVhQT05FTlRfQklBUykgPDwgRG91YmxlLk1BTlRJU1NBX0JJVFMpCisgICAgICAgICAgICAgICAgICAgICAgICB8ICgoYml0cyA8PCAoc3ViTm9ybWFsRmFjdG9yICsgMSkpICYgRG91YmxlLk1BTlRJU1NBX01BU0spOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBEb3VibGUubG9uZ0JpdHNUb0RvdWJsZShyZXN1bHQgfCBzaWduKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHtAY29kZSBkfSAqIDJee0Bjb2RlIHNjYWxlRmFjdG9yfS4gVGhlIHJlc3VsdCBtYXkgYmUgcm91bmRlZC4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmbG9hdCBzY2FsYihmbG9hdCBkLCBpbnQgc2NhbGVGYWN0b3IpIHsKKyAgICAgICAgaWYgKEZsb2F0LmlzTmFOKGQpIHx8IEZsb2F0LmlzSW5maW5pdGUoZCkgfHwgZCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gZDsKKyAgICAgICAgfQorICAgICAgICBpbnQgYml0cyA9IEZsb2F0LmZsb2F0VG9JbnRCaXRzKGQpOworICAgICAgICBpbnQgc2lnbiA9IGJpdHMgJiBGbG9hdC5TSUdOX01BU0s7CisgICAgICAgIGludCBmYWN0b3IgPSAoKGJpdHMgJiBGbG9hdC5FWFBPTkVOVF9NQVNLKSA+PiBGbG9hdC5NQU5USVNTQV9CSVRTKQorICAgICAgICAgICAgICAgIC0gRmxvYXQuRVhQT05FTlRfQklBUyArIHNjYWxlRmFjdG9yOworICAgICAgICAvLyBjYWxjdWxhdGVzIHRoZSBmYWN0b3Igb2Ygc3ViLW5vcm1hbCB2YWx1ZXMKKyAgICAgICAgaW50IHN1Yk5vcm1hbEZhY3RvciA9IEludGVnZXIubnVtYmVyT2ZMZWFkaW5nWmVyb3MoYml0cyAmIH5GbG9hdC5TSUdOX01BU0spCisgICAgICAgICAgICAgICAgLSBGbG9hdC5FWFBPTkVOVF9CSVRTOworICAgICAgICBpZiAoc3ViTm9ybWFsRmFjdG9yIDwgMCkgeworICAgICAgICAgICAgLy8gbm90IHN1Yi1ub3JtYWwgdmFsdWVzCisgICAgICAgICAgICBzdWJOb3JtYWxGYWN0b3IgPSAwOworICAgICAgICB9CisgICAgICAgIGlmIChNYXRoLmFicyhkKSA8IEZsb2F0Lk1JTl9OT1JNQUwpIHsKKyAgICAgICAgICAgIGZhY3RvciA9IGZhY3RvciAtIHN1Yk5vcm1hbEZhY3RvcjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZmFjdG9yID4gRmxvYXQuTUFYX0VYUE9ORU5UKSB7CisgICAgICAgICAgICByZXR1cm4gKGQgPiAwID8gRmxvYXQuUE9TSVRJVkVfSU5GSU5JVFkgOiBGbG9hdC5ORUdBVElWRV9JTkZJTklUWSk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgcmVzdWx0OworICAgICAgICAvLyBpZiByZXN1bHQgaXMgYSBzdWItbm9ybWFsCisgICAgICAgIGlmIChmYWN0b3IgPCAtRmxvYXQuRVhQT05FTlRfQklBUykgeworICAgICAgICAgICAgLy8gdGhlIG51bWJlciBvZiBkaWdpdHMgdGhhdCBzaGlmdHMKKyAgICAgICAgICAgIGludCBkaWdpdHMgPSBmYWN0b3IgKyBGbG9hdC5FWFBPTkVOVF9CSUFTICsgc3ViTm9ybWFsRmFjdG9yOworICAgICAgICAgICAgaWYgKE1hdGguYWJzKGQpIDwgRmxvYXQuTUlOX05PUk1BTCkgeworICAgICAgICAgICAgICAgIC8vIG9yaWdpbiBkIGlzIGFscmVhZHkgc3ViLW5vcm1hbAorICAgICAgICAgICAgICAgIHJlc3VsdCA9IHNoaWZ0SW50Qml0cyhiaXRzICYgRmxvYXQuTUFOVElTU0FfTUFTSywgZGlnaXRzKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gb3JpZ2luIGQgaXMgbm90IHN1Yi1ub3JtYWwsIGNoYW5nZSBtYW50aXNzYSB0byBzdWItbm9ybWFsCisgICAgICAgICAgICAgICAgcmVzdWx0ID0gc2hpZnRJbnRCaXRzKGJpdHMgJiBGbG9hdC5NQU5USVNTQV9NQVNLIHwgMHgwMDgwMDAwMCwgZGlnaXRzIC0gMSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoTWF0aC5hYnMoZCkgPj0gRmxvYXQuTUlOX05PUk1BTCkgeworICAgICAgICAgICAgICAgIC8vIGNvbW1vbiBzaXR1YXRpb24KKyAgICAgICAgICAgICAgICByZXN1bHQgPSAoKGZhY3RvciArIEZsb2F0LkVYUE9ORU5UX0JJQVMpIDw8IEZsb2F0Lk1BTlRJU1NBX0JJVFMpCisgICAgICAgICAgICAgICAgICAgICAgICB8IChiaXRzICYgRmxvYXQuTUFOVElTU0FfTUFTSyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIG9yaWdpbiBkIGlzIHN1Yi1ub3JtYWwsIGNoYW5nZSBtYW50aXNzYSB0byBub3JtYWwgc3R5bGUKKyAgICAgICAgICAgICAgICByZXN1bHQgPSAoKGZhY3RvciArIEZsb2F0LkVYUE9ORU5UX0JJQVMpIDw8IEZsb2F0Lk1BTlRJU1NBX0JJVFMpCisgICAgICAgICAgICAgICAgICAgICAgICB8ICgoYml0cyA8PCAoc3ViTm9ybWFsRmFjdG9yICsgMSkpICYgRmxvYXQuTUFOVElTU0FfTUFTSyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIEZsb2F0LmludEJpdHNUb0Zsb2F0KHJlc3VsdCB8IHNpZ24pOworICAgIH0KKworICAgIC8vIFNoaWZ0cyBpbnRlZ2VyIGJpdHMgYXMgZmxvYXQsIGlmIHRoZSBkaWdpdHMgaXMgcG9zaXRpdmUsIGxlZnQtc2hpZnQ7IGlmCisgICAgLy8gbm90LCBzaGlmdCB0byByaWdodCBhbmQgY2FsY3VsYXRlIGl0cyBjYXJyeS4KKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgc2hpZnRJbnRCaXRzKGludCBiaXRzLCBpbnQgZGlnaXRzKSB7CisgICAgICAgIGlmIChkaWdpdHMgPiAwKSB7CisgICAgICAgICAgICByZXR1cm4gYml0cyA8PCBkaWdpdHM7CisgICAgICAgIH0KKyAgICAgICAgLy8gY2hhbmdlIGl0IHRvIHBvc2l0aXZlCisgICAgICAgIGludCBhYnNEaWdpdHMgPSAtZGlnaXRzOworICAgICAgICBpZiAoSW50ZWdlci5udW1iZXJPZkxlYWRpbmdaZXJvcyhiaXRzICYgfkZsb2F0LlNJR05fTUFTSykgPD0gKDMyIC0gYWJzRGlnaXRzKSkgeworICAgICAgICAgICAgLy8gc29tZSBiaXRzIHdpbGwgcmVtYWluIGFmdGVyIHNoaWZ0aW5nLCBjYWxjdWxhdGVzIGl0cyBjYXJyeQorICAgICAgICAgICAgaWYgKCgoKGJpdHMgPj4gKGFic0RpZ2l0cyAtIDEpKSAmIDB4MSkgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgfHwgSW50ZWdlci5udW1iZXJPZlRyYWlsaW5nWmVyb3MoYml0cykgPT0gKGFic0RpZ2l0cyAtIDEpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGJpdHMgPj4gYWJzRGlnaXRzOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuICgoYml0cyA+PiBhYnNEaWdpdHMpICsgMSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLy8gU2hpZnRzIGxvbmcgYml0cyBhcyBkb3VibGUsIGlmIHRoZSBkaWdpdHMgaXMgcG9zaXRpdmUsIGxlZnQtc2hpZnQ7IGlmCisgICAgLy8gbm90LCBzaGlmdCB0byByaWdodCBhbmQgY2FsY3VsYXRlIGl0cyBjYXJyeS4KKyAgICBwcml2YXRlIHN0YXRpYyBsb25nIHNoaWZ0TG9uZ0JpdHMobG9uZyBiaXRzLCBsb25nIGRpZ2l0cykgeworICAgICAgICBpZiAoZGlnaXRzID4gMCkgeworICAgICAgICAgICAgcmV0dXJuIGJpdHMgPDwgZGlnaXRzOworICAgICAgICB9CisgICAgICAgIC8vIGNoYW5nZSBpdCB0byBwb3NpdGl2ZQorICAgICAgICBsb25nIGFic0RpZ2l0cyA9IC1kaWdpdHM7CisgICAgICAgIGlmIChMb25nLm51bWJlck9mTGVhZGluZ1plcm9zKGJpdHMgJiB+RG91YmxlLlNJR05fTUFTSykgPD0gKDY0IC0gYWJzRGlnaXRzKSkgeworICAgICAgICAgICAgLy8gc29tZSBiaXRzIHdpbGwgcmVtYWluIGFmdGVyIHNoaWZ0aW5nLCBjYWxjdWxhdGVzIGl0cyBjYXJyeQorICAgICAgICAgICAgaWYgKCgoKGJpdHMgPj4gKGFic0RpZ2l0cyAtIDEpKSAmIDB4MSkgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgfHwgTG9uZy5udW1iZXJPZlRyYWlsaW5nWmVyb3MoYml0cykgPT0gKGFic0RpZ2l0cyAtIDEpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGJpdHMgPj4gYWJzRGlnaXRzOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuICgoYml0cyA+PiBhYnNEaWdpdHMpICsgMSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TdHJpbmcuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvU3RyaW5nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWZkNDIxMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvU3RyaW5nLmphdmEKQEAgLTAsMCArMSwyMDQ1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLkNoYXJCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldHM7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29tcGFyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuRm9ybWF0dGVyOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm47CitpbXBvcnQgbGliY29yZS51dGlsLkVtcHR5QXJyYXk7CisKKy8qKgorICogQW4gaW1tdXRhYmxlIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMvY29kZSB1bml0cyAoe0Bjb2RlIGNoYXJ9cykuIEEKKyAqIHtAY29kZSBTdHJpbmd9IGlzIHJlcHJlc2VudGVkIGJ5IGFycmF5IG9mIFVURi0xNiB2YWx1ZXMsIHN1Y2ggdGhhdAorICogVW5pY29kZSBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcnMgKGNvZGUgcG9pbnRzKSBhcmUgc3RvcmVkL2VuY29kZWQgYXMKKyAqIHN1cnJvZ2F0ZSBwYWlycyB2aWEgVW5pY29kZSBjb2RlIHVuaXRzICh7QGNvZGUgY2hhcn0pLgorICoKKyAqIDxhIG5hbWU9ImJhY2tpbmdfYXJyYXkiPjxoMz5CYWNraW5nIEFycmF5czwvaDM+PC9hPgorICogVGhpcyBjbGFzcyBpcyBpbXBsZW1lbnRlZCB1c2luZyBhIGNoYXJbXS4gVGhlIGxlbmd0aCBvZiB0aGUgYXJyYXkgbWF5IGV4Y2VlZAorICogdGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nLiBGb3IgZXhhbXBsZSwgdGhlIHN0cmluZyAiSGVsbG8iIG1heSBiZSBiYWNrZWQgYnkKKyAqIHRoZSBhcnJheSB7QGNvZGUgWydIJywgJ2UnLCAnbCcsICdsJywgJ28nLCAnVycuICdvJywgJ3InLCAnbCcsICdkJ119IHdpdGgKKyAqIG9mZnNldCAwIGFuZCBsZW5ndGggNS4KKyAqCisgKiA8cD5NdWx0aXBsZSBzdHJpbmdzIGNhbiBzaGFyZSB0aGUgc2FtZSBjaGFyW10gYmVjYXVzZSBzdHJpbmdzIGFyZSBpbW11dGFibGUuCisgKiBUaGUge0BsaW5rICNzdWJzdHJpbmd9IG1ldGhvZCA8c3Ryb25nPmFsd2F5czwvc3Ryb25nPiByZXR1cm5zIGEgc3RyaW5nIHRoYXQKKyAqIHNoYXJlcyB0aGUgYmFja2luZyBhcnJheSBvZiBpdHMgc291cmNlIHN0cmluZy4gR2VuZXJhbGx5IHRoaXMgaXMgYW4KKyAqIG9wdGltaXphdGlvbjogZmV3ZXIgY2hhcmFjdGVyIGFycmF5cyBuZWVkIHRvIGJlIGFsbG9jYXRlZCwgYW5kIGxlc3MgY29weWluZworICogaXMgbmVjZXNzYXJ5LiBCdXQgdGhpcyBjYW4gYWxzbyBsZWFkIHRvIHVud2FudGVkIGhlYXAgcmV0ZW50aW9uLiBUYWtpbmcgYQorICogc2hvcnQgc3Vic3RyaW5nIG9mIGxvbmcgc3RyaW5nIG1lYW5zIHRoYXQgdGhlIGxvbmcgc2hhcmVkIGNoYXJbXSB3b24ndCBiZQorICogZ2FyYmFnZSB1bnRpbCBib3RoIHN0cmluZ3MgYXJlIGdhcmJhZ2UuIFRoaXMgdHlwaWNhbGx5IGhhcHBlbnMgd2hlbiBwYXJzaW5nCisgKiBzbWFsbCBzdWJzdHJpbmdzIG91dCBvZiBhIGxhcmdlIGlucHV0LiBUbyBhdm9pZCB0aGlzIHdoZXJlIG5lY2Vzc2FyeSwgY2FsbAorICoge0Bjb2RlIG5ldyBTdHJpbmcobG9uZ1N0cmluZy5zdWJTdHJpbmcoLi4uKSl9LiBUaGUgc3RyaW5nIGNvcHkgY29uc3RydWN0b3IKKyAqIGFsd2F5cyBlbnN1cmVzIHRoYXQgdGhlIGJhY2tpbmcgYXJyYXkgaXMgbm8gbGFyZ2VyIHRoYW4gbmVjZXNzYXJ5LgorICoKKyAqIEBzZWUgU3RyaW5nQnVmZmVyCisgKiBAc2VlIFN0cmluZ0J1aWxkZXIKKyAqIEBzZWUgQ2hhcnNldAorICogQHNpbmNlIDEuMAorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU3RyaW5nIGltcGxlbWVudHMgU2VyaWFsaXphYmxlLCBDb21wYXJhYmxlPFN0cmluZz4sIENoYXJTZXF1ZW5jZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjg0OTc5NDQ3MDc1NDY2NzcxMEw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIFJFUExBQ0VNRU5UX0NIQVIgPSAoY2hhcikgMHhmZmZkOworCisgICAgLyoqCisgICAgICogQ2FzZUluc2Vuc2l0aXZlQ29tcGFyYXRvciBjb21wYXJlcyBTdHJpbmdzIGlnbm9yaW5nIHRoZSBjYXNlIG9mIHRoZQorICAgICAqIGNoYXJhY3RlcnMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgQ2FzZUluc2Vuc2l0aXZlQ29tcGFyYXRvciBpbXBsZW1lbnRzCisgICAgICAgICAgICBDb21wYXJhdG9yPFN0cmluZz4sIFNlcmlhbGl6YWJsZSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDg1NzU3OTk4MDg5MzMwMjkzMjZMOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb21wYXJlIHRoZSB0d28gb2JqZWN0cyB0byBkZXRlcm1pbmUgdGhlIHJlbGF0aXZlIG9yZGVyaW5nLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gbzEKKyAgICAgICAgICogICAgICAgICAgICBhbiBPYmplY3QgdG8gY29tcGFyZQorICAgICAgICAgKiBAcGFyYW0gbzIKKyAgICAgICAgICogICAgICAgICAgICBhbiBPYmplY3QgdG8gY29tcGFyZQorICAgICAgICAgKiBAcmV0dXJuIGFuIGludCA8IDAgaWYgb2JqZWN0MSBpcyBsZXNzIHRoYW4gb2JqZWN0MiwgMCBpZiB0aGV5IGFyZQorICAgICAgICAgKiAgICAgICAgIGVxdWFsLCBhbmQgPiAwIGlmIG9iamVjdDEgaXMgZ3JlYXRlcgorICAgICAgICAgKgorICAgICAgICAgKiBAZXhjZXB0aW9uIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICAgICBpZiBvYmplY3RzIGFyZSBub3QgdGhlIGNvcnJlY3QgdHlwZQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGludCBjb21wYXJlKFN0cmluZyBvMSwgU3RyaW5nIG8yKSB7CisgICAgICAgICAgICByZXR1cm4gbzEuY29tcGFyZVRvSWdub3JlQ2FzZShvMik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBIGNvbXBhcmF0b3IgaWdub3JpbmcgdGhlIGNhc2Ugb2YgdGhlIGNoYXJhY3RlcnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb21wYXJhdG9yPFN0cmluZz4gQ0FTRV9JTlNFTlNJVElWRV9PUkRFUiA9IG5ldyBDYXNlSW5zZW5zaXRpdmVDb21wYXJhdG9yKCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gQVNDSUk7CisgICAgc3RhdGljIHsKKyAgICAgICAgQVNDSUkgPSBuZXcgY2hhclsxMjhdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEFTQ0lJLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICBBU0NJSVtpXSA9IChjaGFyKSBpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBjaGFyW10gdmFsdWU7CisKKyAgICBwcml2YXRlIGZpbmFsIGludCBvZmZzZXQ7CisKKyAgICBwcml2YXRlIGZpbmFsIGludCBjb3VudDsKKworICAgIHByaXZhdGUgaW50IGhhc2hDb2RlOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBlbXB0eSBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIFN0cmluZygpIHsKKyAgICAgICAgdmFsdWUgPSBFbXB0eUFycmF5LkNIQVI7CisgICAgICAgIG9mZnNldCA9IDA7CisgICAgICAgIGNvdW50ID0gMDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFByaXZhdGUgY29uc3RydWN0b3IgdXNlZCBmb3IgSklUIG9wdGltaXphdGlvbi4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBwcml2YXRlIFN0cmluZyhTdHJpbmcgcywgY2hhciBjKSB7CisgICAgICAgIG9mZnNldCA9IDA7CisgICAgICAgIHZhbHVlID0gbmV3IGNoYXJbcy5jb3VudCArIDFdOworICAgICAgICBjb3VudCA9IHMuY291bnQgKyAxOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHMudmFsdWUsIHMub2Zmc2V0LCB2YWx1ZSwgMCwgcy5jb3VudCk7CisgICAgICAgIHZhbHVlW3MuY291bnRdID0gYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGUgYnl0ZSBhcnJheSB0byBhIHN0cmluZyB1c2luZyB0aGUgc3lzdGVtJ3MKKyAgICAgKiB7QGxpbmsgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0I2RlZmF1bHRDaGFyc2V0IGRlZmF1bHQgY2hhcnNldH0uCisgICAgICovCisgICAgQEZpbmRCdWdzU3VwcHJlc3NXYXJuaW5ncygiRE1fREVGQVVMVF9FTkNPRElORyIpCisgICAgcHVibGljIFN0cmluZyhieXRlW10gZGF0YSkgeworICAgICAgICB0aGlzKGRhdGEsIDAsIGRhdGEubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGUgYnl0ZSBhcnJheSB0byBhIHN0cmluZywgc2V0dGluZyB0aGUgaGlnaCBieXRlIG9mIGV2ZXJ5CisgICAgICogY2hhcmFjdGVyIHRvIHRoZSBzcGVjaWZpZWQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYXJyYXkgdG8gY29udmVydCB0byBhIHN0cmluZy4KKyAgICAgKiBAcGFyYW0gaGlnaAorICAgICAqICAgICAgICAgICAgdGhlIGhpZ2ggYnl0ZSB0byB1c2UuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkYXRhID09IG51bGx9LgorICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI1N0cmluZyhieXRlW10pfSBvciB7QGxpbmsgI1N0cmluZyhieXRlW10sIFN0cmluZyl9IGluc3RlYWQuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgU3RyaW5nKGJ5dGVbXSBkYXRhLCBpbnQgaGlnaCkgeworICAgICAgICB0aGlzKGRhdGEsIGhpZ2gsIDAsIGRhdGEubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyBhIHN1YnNlcXVlbmNlIG9mIHRoZSBieXRlIGFycmF5IHRvIGEgc3RyaW5nIHVzaW5nIHRoZSBzeXN0ZW0ncworICAgICAqIHtAbGluayBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQjZGVmYXVsdENoYXJzZXQgZGVmYXVsdCBjaGFyc2V0fS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGF0YSA9PSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYnl0ZUNvdW50IDwgMCB8fCBvZmZzZXQgPCAwIHx8IG9mZnNldCArIGJ5dGVDb3VudCA+IGRhdGEubGVuZ3RofS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nKGJ5dGVbXSBkYXRhLCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB7CisgICAgICAgIGlmICgob2Zmc2V0IHwgYnl0ZUNvdW50KSA8IDAgfHwgYnl0ZUNvdW50ID4gZGF0YS5sZW5ndGggLSBvZmZzZXQpIHsKKyAgICAgICAgICAgIHRocm93IGZhaWxlZEJvdW5kc0NoZWNrKGRhdGEubGVuZ3RoLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgQ2hhckJ1ZmZlciBjYiA9IENoYXJzZXQuZGVmYXVsdENoYXJzZXQoKS5kZWNvZGUoQnl0ZUJ1ZmZlci53cmFwKGRhdGEsIG9mZnNldCwgYnl0ZUNvdW50KSk7CisgICAgICAgIHRoaXMuY291bnQgPSBjYi5sZW5ndGgoKTsKKyAgICAgICAgdGhpcy5vZmZzZXQgPSAwOworICAgICAgICBpZiAoY291bnQgPiAwKSB7CisgICAgICAgICAgICB2YWx1ZSA9IGNiLmFycmF5KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB2YWx1ZSA9IEVtcHR5QXJyYXkuQ0hBUjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIHRoZSBieXRlIGFycmF5IHRvIGEgc3RyaW5nLCBzZXR0aW5nIHRoZSBoaWdoIGJ5dGUgb2YgZXZlcnkKKyAgICAgKiBjaGFyYWN0ZXIgdG8ge0Bjb2RlIGhpZ2h9LgorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkYXRhID09IG51bGx9LgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBieXRlQ291bnQgPCAwIHx8IG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgYnl0ZUNvdW50ID4gZGF0YS5sZW5ndGh9CisgICAgICoKKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNTdHJpbmcoYnl0ZVtdLCBpbnQsIGludCl9IGluc3RlYWQuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgU3RyaW5nKGJ5dGVbXSBkYXRhLCBpbnQgaGlnaCwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCkgeworICAgICAgICBpZiAoKG9mZnNldCB8IGJ5dGVDb3VudCkgPCAwIHx8IGJ5dGVDb3VudCA+IGRhdGEubGVuZ3RoIC0gb2Zmc2V0KSB7CisgICAgICAgICAgICB0aHJvdyBmYWlsZWRCb3VuZHNDaGVjayhkYXRhLmxlbmd0aCwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICB9CisgICAgICAgIHRoaXMub2Zmc2V0ID0gMDsKKyAgICAgICAgdGhpcy52YWx1ZSA9IG5ldyBjaGFyW2J5dGVDb3VudF07CisgICAgICAgIHRoaXMuY291bnQgPSBieXRlQ291bnQ7CisgICAgICAgIGhpZ2ggPDw9IDg7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgeworICAgICAgICAgICAgdmFsdWVbaV0gPSAoY2hhcikgKGhpZ2ggKyAoZGF0YVtvZmZzZXQrK10gJiAweGZmKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGUgYnl0ZSBhcnJheSB0byBhIHN0cmluZyB1c2luZyB0aGUgbmFtZWQgY2hhcnNldC4KKyAgICAgKgorICAgICAqIDxwPlRoZSBiZWhhdmlvciB3aGVuIHRoZSBieXRlcyBjYW5ub3QgYmUgZGVjb2RlZCBieSB0aGUgbmFtZWQgY2hhcnNldAorICAgICAqIGlzIHVuc3BlY2lmaWVkLiBVc2Uge0BsaW5rIGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldERlY29kZXJ9IGZvciBtb3JlIGNvbnRyb2wuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGRhdGEgPT0gbnVsbH0uCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGJ5dGVDb3VudCA8IDAgfHwgb2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyBieXRlQ291bnQgPiBkYXRhLmxlbmd0aH0uCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG5hbWVkIGNoYXJzZXQgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nKGJ5dGVbXSBkYXRhLCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50LCBTdHJpbmcgY2hhcnNldE5hbWUpIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhkYXRhLCBvZmZzZXQsIGJ5dGVDb3VudCwgQ2hhcnNldC5mb3JOYW1lVUVFKGNoYXJzZXROYW1lKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhlIGJ5dGUgYXJyYXkgdG8gYSBzdHJpbmcgdXNpbmcgdGhlIG5hbWVkIGNoYXJzZXQuCisgICAgICoKKyAgICAgKiA8cD5UaGUgYmVoYXZpb3Igd2hlbiB0aGUgYnl0ZXMgY2Fubm90IGJlIGRlY29kZWQgYnkgdGhlIG5hbWVkIGNoYXJzZXQKKyAgICAgKiBpcyB1bnNwZWNpZmllZC4gVXNlIHtAbGluayBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXREZWNvZGVyfSBmb3IgbW9yZSBjb250cm9sLgorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkYXRhID09IG51bGx9LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBjaGFyc2V0TmFtZX0gaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nKGJ5dGVbXSBkYXRhLCBTdHJpbmcgY2hhcnNldE5hbWUpIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhkYXRhLCAwLCBkYXRhLmxlbmd0aCwgQ2hhcnNldC5mb3JOYW1lVUVFKGNoYXJzZXROYW1lKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhlIGJ5dGUgYXJyYXkgdG8gYSBzdHJpbmcgdXNpbmcgdGhlIGdpdmVuIGNoYXJzZXQuCisgICAgICoKKyAgICAgKiA8cD5UaGUgYmVoYXZpb3Igd2hlbiB0aGUgYnl0ZXMgY2Fubm90IGJlIGRlY29kZWQgYnkgdGhlIGdpdmVuIGNoYXJzZXQKKyAgICAgKiBpcyB0byByZXBsYWNlIG1hbGZvcm1lZCBpbnB1dCBhbmQgdW5tYXBwYWJsZSBjaGFyYWN0ZXJzIHdpdGggdGhlIGNoYXJzZXQncyBkZWZhdWx0CisgICAgICogcmVwbGFjZW1lbnQgc3RyaW5nLiBVc2Uge0BsaW5rIGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldERlY29kZXJ9IGZvciBtb3JlIGNvbnRyb2wuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYnl0ZUNvdW50IDwgMCB8fCBvZmZzZXQgPCAwIHx8IG9mZnNldCArIGJ5dGVDb3VudCA+IGRhdGEubGVuZ3RofQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGF0YSA9PSBudWxsfQorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcoYnl0ZVtdIGRhdGEsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQsIENoYXJzZXQgY2hhcnNldCkgeworICAgICAgICBpZiAoKG9mZnNldCB8IGJ5dGVDb3VudCkgPCAwIHx8IGJ5dGVDb3VudCA+IGRhdGEubGVuZ3RoIC0gb2Zmc2V0KSB7CisgICAgICAgICAgICB0aHJvdyBmYWlsZWRCb3VuZHNDaGVjayhkYXRhLmxlbmd0aCwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICB9CisKKyAgICAgICAgLy8gV2UgaW5saW5lIFVURi04LCBJU08tODg1OS0xLCBhbmQgVVMtQVNDSUkgZGVjb2RlcnMgZm9yIHNwZWVkIGFuZCBiZWNhdXNlICdjb3VudCcgYW5kCisgICAgICAgIC8vICd2YWx1ZScgYXJlIGZpbmFsLgorICAgICAgICBTdHJpbmcgY2Fub25pY2FsQ2hhcnNldE5hbWUgPSBjaGFyc2V0Lm5hbWUoKTsKKyAgICAgICAgaWYgKGNhbm9uaWNhbENoYXJzZXROYW1lLmVxdWFscygiVVRGLTgiKSkgeworICAgICAgICAgICAgYnl0ZVtdIGQgPSBkYXRhOworICAgICAgICAgICAgY2hhcltdIHYgPSBuZXcgY2hhcltieXRlQ291bnRdOworCisgICAgICAgICAgICBpbnQgaWR4ID0gb2Zmc2V0OworICAgICAgICAgICAgaW50IGxhc3QgPSBvZmZzZXQgKyBieXRlQ291bnQ7CisgICAgICAgICAgICBpbnQgcyA9IDA7CitvdXRlcjoKKyAgICAgICAgICAgIHdoaWxlIChpZHggPCBsYXN0KSB7CisgICAgICAgICAgICAgICAgYnl0ZSBiMCA9IGRbaWR4KytdOworICAgICAgICAgICAgICAgIGlmICgoYjAgJiAweDgwKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIDB4eHh4eHh4CisgICAgICAgICAgICAgICAgICAgIC8vIFJhbmdlOiAgVS0wMDAwMDAwMCAtIFUtMDAwMDAwN0YKKyAgICAgICAgICAgICAgICAgICAgaW50IHZhbCA9IGIwICYgMHhmZjsKKyAgICAgICAgICAgICAgICAgICAgdltzKytdID0gKGNoYXIpIHZhbDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCgoYjAgJiAweGUwKSA9PSAweGMwKSB8fCAoKGIwICYgMHhmMCkgPT0gMHhlMCkgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgICgoYjAgJiAweGY4KSA9PSAweGYwKSB8fCAoKGIwICYgMHhmYykgPT0gMHhmOCkgfHwgKChiMCAmIDB4ZmUpID09IDB4ZmMpKSB7CisgICAgICAgICAgICAgICAgICAgIGludCB1dGZDb3VudCA9IDE7CisgICAgICAgICAgICAgICAgICAgIGlmICgoYjAgJiAweGYwKSA9PSAweGUwKSB1dGZDb3VudCA9IDI7CisgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKChiMCAmIDB4ZjgpID09IDB4ZjApIHV0ZkNvdW50ID0gMzsKKyAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoKGIwICYgMHhmYykgPT0gMHhmOCkgdXRmQ291bnQgPSA0OworICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICgoYjAgJiAweGZlKSA9PSAweGZjKSB1dGZDb3VudCA9IDU7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gMTEweHh4eHggKDEweHh4eHh4KSsKKyAgICAgICAgICAgICAgICAgICAgLy8gUmFuZ2U6ICBVLTAwMDAwMDgwIC0gVS0wMDAwMDdGRiAoY291bnQgPT0gMSkKKyAgICAgICAgICAgICAgICAgICAgLy8gUmFuZ2U6ICBVLTAwMDAwODAwIC0gVS0wMDAwRkZGRiAoY291bnQgPT0gMikKKyAgICAgICAgICAgICAgICAgICAgLy8gUmFuZ2U6ICBVLTAwMDEwMDAwIC0gVS0wMDFGRkZGRiAoY291bnQgPT0gMykKKyAgICAgICAgICAgICAgICAgICAgLy8gUmFuZ2U6ICBVLTAwMjAwMDAwIC0gVS0wM0ZGRkZGRiAoY291bnQgPT0gNCkKKyAgICAgICAgICAgICAgICAgICAgLy8gUmFuZ2U6ICBVLTA0MDAwMDAwIC0gVS03RkZGRkZGRiAoY291bnQgPT0gNSkKKworICAgICAgICAgICAgICAgICAgICBpZiAoaWR4ICsgdXRmQ291bnQgPiBsYXN0KSB7CisgICAgICAgICAgICAgICAgICAgICAgICB2W3MrK10gPSBSRVBMQUNFTUVOVF9DSEFSOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IHVzYWJsZSBiaXRzIGZyb20gYjAKKyAgICAgICAgICAgICAgICAgICAgaW50IHZhbCA9IGIwICYgKDB4MWYgPj4gKHV0ZkNvdW50IC0gMSkpOworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHV0ZkNvdW50OyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGUgYiA9IGRbaWR4KytdOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChiICYgMHhDMCkgIT0gMHg4MCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZbcysrXSA9IFJFUExBQ0VNRU5UX0NIQVI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWR4LS07IC8vIFB1dCB0aGUgaW5wdXQgY2hhciBiYWNrCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgb3V0ZXI7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBQdXNoIG5ldyBiaXRzIGluIGZyb20gdGhlIHJpZ2h0IHNpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbCA8PD0gNjsKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbCB8PSBiICYgMHgzZjsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vIE5vdGU6IEphdmEgYWxsb3dzIG92ZXJsb25nIGNoYXIKKyAgICAgICAgICAgICAgICAgICAgLy8gc3BlY2lmaWNhdGlvbnMgVG8gZGlzYWxsb3csIGNoZWNrIHRoYXQgdmFsCisgICAgICAgICAgICAgICAgICAgIC8vIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbWluaW11bQorICAgICAgICAgICAgICAgICAgICAvLyB2YWx1ZSBmb3IgZWFjaCBjb3VudDoKKyAgICAgICAgICAgICAgICAgICAgLy8KKyAgICAgICAgICAgICAgICAgICAgLy8gY291bnQgICAgbWluIHZhbHVlCisgICAgICAgICAgICAgICAgICAgIC8vIC0tLS0tICAgLS0tLS0tLS0tLQorICAgICAgICAgICAgICAgICAgICAvLyAgIDEgICAgICAgICAgIDB4ODAKKyAgICAgICAgICAgICAgICAgICAgLy8gICAyICAgICAgICAgIDB4ODAwCisgICAgICAgICAgICAgICAgICAgIC8vICAgMyAgICAgICAgMHgxMDAwMAorICAgICAgICAgICAgICAgICAgICAvLyAgIDQgICAgICAgMHgyMDAwMDAKKyAgICAgICAgICAgICAgICAgICAgLy8gICA1ICAgICAgMHg0MDAwMDAwCisKKyAgICAgICAgICAgICAgICAgICAgLy8gQWxsb3cgc3Vycm9nYXRlIHZhbHVlcyAoMHhEODAwIC0gMHhERkZGKSB0bworICAgICAgICAgICAgICAgICAgICAvLyBiZSBzcGVjaWZpZWQgdXNpbmcgMy1ieXRlIFVURiB2YWx1ZXMgb25seQorICAgICAgICAgICAgICAgICAgICBpZiAoKHV0ZkNvdW50ICE9IDIpICYmICh2YWwgPj0gMHhEODAwKSAmJiAodmFsIDw9IDB4REZGRikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHZbcysrXSA9IFJFUExBQ0VNRU5UX0NIQVI7CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vIFJlamVjdCBjaGFycyBncmVhdGVyIHRoYW4gdGhlIFVuaWNvZGUgbWF4aW11bSBvZiBVKzEwRkZGRi4KKyAgICAgICAgICAgICAgICAgICAgaWYgKHZhbCA+IDB4MTBGRkZGKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB2W3MrK10gPSBSRVBMQUNFTUVOVF9DSEFSOworICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAvLyBFbmNvZGUgY2hhcnMgZnJvbSBVKzEwMDAwIHVwIGFzIHN1cnJvZ2F0ZSBwYWlycworICAgICAgICAgICAgICAgICAgICBpZiAodmFsIDwgMHgxMDAwMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgdltzKytdID0gKGNoYXIpIHZhbDsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGludCB4ID0gdmFsICYgMHhmZmZmOworICAgICAgICAgICAgICAgICAgICAgICAgaW50IHUgPSAodmFsID4+IDE2KSAmIDB4MWY7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdyA9ICh1IC0gMSkgJiAweGZmZmY7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaGkgPSAweGQ4MDAgfCAodyA8PCA2KSB8ICh4ID4+IDEwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGludCBsbyA9IDB4ZGMwMCB8ICh4ICYgMHgzZmYpOworICAgICAgICAgICAgICAgICAgICAgICAgdltzKytdID0gKGNoYXIpIGhpOworICAgICAgICAgICAgICAgICAgICAgICAgdltzKytdID0gKGNoYXIpIGxvOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gSWxsZWdhbCB2YWx1ZXMgMHg4KiwgMHg5KiwgMHhhKiwgMHhiKiwgMHhmZC0weGZmCisgICAgICAgICAgICAgICAgICAgIHZbcysrXSA9IFJFUExBQ0VNRU5UX0NIQVI7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAocyA9PSBieXRlQ291bnQpIHsKKyAgICAgICAgICAgICAgICAvLyBXZSBndWVzc2VkIHJpZ2h0LCBzbyB3ZSBjYW4gdXNlIG91ciB0ZW1wb3JhcnkgYXJyYXkgYXMtaXMuCisgICAgICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSAwOworICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2OworICAgICAgICAgICAgICAgIHRoaXMuY291bnQgPSBzOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBPdXIgdGVtcG9yYXJ5IGFycmF5IHdhcyB0b28gYmlnLCBzbyByZWFsbG9jYXRlIGFuZCBjb3B5LgorICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gMDsKKyAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gbmV3IGNoYXJbc107CisgICAgICAgICAgICAgICAgdGhpcy5jb3VudCA9IHM7CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh2LCAwLCB2YWx1ZSwgMCwgcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAoY2Fub25pY2FsQ2hhcnNldE5hbWUuZXF1YWxzKCJJU08tODg1OS0xIikpIHsKKyAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gMDsKKyAgICAgICAgICAgIHRoaXMudmFsdWUgPSBuZXcgY2hhcltieXRlQ291bnRdOworICAgICAgICAgICAgdGhpcy5jb3VudCA9IGJ5dGVDb3VudDsKKyAgICAgICAgICAgIENoYXJzZXRzLmlzb0xhdGluMUJ5dGVzVG9DaGFycyhkYXRhLCBvZmZzZXQsIGJ5dGVDb3VudCwgdmFsdWUpOworICAgICAgICB9IGVsc2UgaWYgKGNhbm9uaWNhbENoYXJzZXROYW1lLmVxdWFscygiVVMtQVNDSUkiKSkgeworICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSAwOworICAgICAgICAgICAgdGhpcy52YWx1ZSA9IG5ldyBjaGFyW2J5dGVDb3VudF07CisgICAgICAgICAgICB0aGlzLmNvdW50ID0gYnl0ZUNvdW50OworICAgICAgICAgICAgQ2hhcnNldHMuYXNjaWlCeXRlc1RvQ2hhcnMoZGF0YSwgb2Zmc2V0LCBieXRlQ291bnQsIHZhbHVlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIENoYXJCdWZmZXIgY2IgPSBjaGFyc2V0LmRlY29kZShCeXRlQnVmZmVyLndyYXAoZGF0YSwgb2Zmc2V0LCBieXRlQ291bnQpKTsKKyAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gMDsKKyAgICAgICAgICAgIHRoaXMuY291bnQgPSBjYi5sZW5ndGgoKTsKKyAgICAgICAgICAgIGlmIChjb3VudCA+IDApIHsKKyAgICAgICAgICAgICAgICAvLyBXZSBjb3VsZCB1c2UgY2IuYXJyYXkoKSBkaXJlY3RseSwgYnV0IHRoYXQgd291bGQgbWVhbiB3ZSdkIGhhdmUgdG8gdHJ1c3QKKyAgICAgICAgICAgICAgICAvLyB0aGUgQ2hhcnNldERlY29kZXIgZG9lc24ndCBoYW5nIG9uIHRvIHRoZSBDaGFyQnVmZmVyIGFuZCBtdXRhdGUgaXQgbGF0ZXIsCisgICAgICAgICAgICAgICAgLy8gd2hpY2ggd291bGQgYnJlYWsgU3RyaW5nJ3MgaW1tdXRhYmlsaXR5IGd1YXJhbnRlZS4gSXQgd291bGQgYWxzbyB0ZW5kIHRvCisgICAgICAgICAgICAgICAgLy8gbWVhbiB0aGF0IHdlJ2QgYmUgd2FzdGluZyBtZW1vcnkgYmVjYXVzZSBDaGFyc2V0RGVjb2RlciBkb2Vzbid0IHRyaW0gdGhlCisgICAgICAgICAgICAgICAgLy8gYXJyYXkuIFNvIHdlIGNvcHkuCisgICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IG5ldyBjaGFyW2NvdW50XTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNiLmFycmF5KCksIDAsIHZhbHVlLCAwLCBjb3VudCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSBFbXB0eUFycmF5LkNIQVI7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGUgYnl0ZSBhcnJheSB0byBhIFN0cmluZyB1c2luZyB0aGUgZ2l2ZW4gY2hhcnNldC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIGRhdGEgPT0gbnVsbH0KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIFN0cmluZyhieXRlW10gZGF0YSwgQ2hhcnNldCBjaGFyc2V0KSB7CisgICAgICAgIHRoaXMoZGF0YSwgMCwgZGF0YS5sZW5ndGgsIGNoYXJzZXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMgc3RyaW5nIHRvIGNvbnRhaW4gdGhlIGNoYXJhY3RlcnMgaW4gdGhlIHNwZWNpZmllZAorICAgICAqIGNoYXJhY3RlciBhcnJheS4gTW9kaWZ5aW5nIHRoZSBjaGFyYWN0ZXIgYXJyYXkgYWZ0ZXIgY3JlYXRpbmcgdGhlIHN0cmluZworICAgICAqIGhhcyBubyBlZmZlY3Qgb24gdGhlIHN0cmluZy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIGRhdGEgPT0gbnVsbH0KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nKGNoYXJbXSBkYXRhKSB7CisgICAgICAgIHRoaXMoZGF0YSwgMCwgZGF0YS5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMgc3RyaW5nIHRvIGNvbnRhaW4gdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXJzIGluIHRoZQorICAgICAqIGNoYXJhY3RlciBhcnJheS4gTW9kaWZ5aW5nIHRoZSBjaGFyYWN0ZXIgYXJyYXkgYWZ0ZXIgY3JlYXRpbmcgdGhlIHN0cmluZworICAgICAqIGhhcyBubyBlZmZlY3Qgb24gdGhlIHN0cmluZy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGF0YSA9PSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY2hhckNvdW50IDwgMCB8fCBvZmZzZXQgPCAwIHx8IG9mZnNldCArIGNoYXJDb3VudCA+IGRhdGEubGVuZ3RofQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcoY2hhcltdIGRhdGEsIGludCBvZmZzZXQsIGludCBjaGFyQ291bnQpIHsKKyAgICAgICAgaWYgKChvZmZzZXQgfCBjaGFyQ291bnQpIDwgMCB8fCBjaGFyQ291bnQgPiBkYXRhLmxlbmd0aCAtIG9mZnNldCkgeworICAgICAgICAgICAgdGhyb3cgZmFpbGVkQm91bmRzQ2hlY2soZGF0YS5sZW5ndGgsIG9mZnNldCwgY2hhckNvdW50KTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLm9mZnNldCA9IDA7CisgICAgICAgIHRoaXMudmFsdWUgPSBuZXcgY2hhcltjaGFyQ291bnRdOworICAgICAgICB0aGlzLmNvdW50ID0gY2hhckNvdW50OworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGEsIG9mZnNldCwgdmFsdWUsIDAsIGNvdW50KTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEludGVybmFsIHZlcnNpb24gb2YgdGhlIFN0cmluZyhjaGFyW10sIGludCwgaW50KSBjb25zdHJ1Y3Rvci4KKyAgICAgKiBEb2VzIG5vdCByYW5nZSBjaGVjaywgbnVsbCBjaGVjaywgb3IgY29weSB0aGUgY2hhcmFjdGVyIGFycmF5LgorICAgICAqLworICAgIFN0cmluZyhpbnQgb2Zmc2V0LCBpbnQgY2hhckNvdW50LCBjaGFyW10gY2hhcnMpIHsKKyAgICAgICAgdGhpcy52YWx1ZSA9IGNoYXJzOworICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDsKKyAgICAgICAgdGhpcy5jb3VudCA9IGNoYXJDb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHN0cmluZyB3aXRoIHRoZSBzYW1lIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgYXMge0Bjb2RlCisgICAgICogdG9Db3B5fS4gVGhlIHJldHVybmVkIHN0cmluZydzIDxhIGhyZWY9IiNiYWNraW5nX2FycmF5Ij5iYWNraW5nIGFycmF5PC9hPgorICAgICAqIGlzIG5vIGxhcmdlciB0aGFuIG5lY2Vzc2FyeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nKFN0cmluZyB0b0NvcHkpIHsKKyAgICAgICAgdmFsdWUgPSAodG9Db3B5LnZhbHVlLmxlbmd0aCA9PSB0b0NvcHkuY291bnQpCisgICAgICAgICAgICAgICAgPyB0b0NvcHkudmFsdWUKKyAgICAgICAgICAgICAgICA6IEFycmF5cy5jb3B5T2ZSYW5nZSh0b0NvcHkudmFsdWUsIHRvQ29weS5vZmZzZXQsIHRvQ29weS5vZmZzZXQgKyB0b0NvcHkubGVuZ3RoKCkpOworICAgICAgICBvZmZzZXQgPSAwOworICAgICAgICBjb3VudCA9IHZhbHVlLmxlbmd0aDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFByaXZhdGUgY29uc3RydWN0b3IgdXNlZnVsIGZvciBKSVQgb3B0aW1pemF0aW9uLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCB7ICJ1bnVzZWQiLCAibmxzIiB9KQorICAgIHByaXZhdGUgU3RyaW5nKFN0cmluZyBzMSwgU3RyaW5nIHMyKSB7CisgICAgICAgIGlmIChzMSA9PSBudWxsKSB7CisgICAgICAgICAgICBzMSA9ICJudWxsIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoczIgPT0gbnVsbCkgeworICAgICAgICAgICAgczIgPSAibnVsbCI7CisgICAgICAgIH0KKyAgICAgICAgY291bnQgPSBzMS5jb3VudCArIHMyLmNvdW50OworICAgICAgICB2YWx1ZSA9IG5ldyBjaGFyW2NvdW50XTsKKyAgICAgICAgb2Zmc2V0ID0gMDsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzMS52YWx1ZSwgczEub2Zmc2V0LCB2YWx1ZSwgMCwgczEuY291bnQpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHMyLnZhbHVlLCBzMi5vZmZzZXQsIHZhbHVlLCBzMS5jb3VudCwgczIuY291bnQpOworICAgIH0KKworICAgIC8qCisgICAgICogUHJpdmF0ZSBjb25zdHJ1Y3RvciB1c2VmdWwgZm9yIEpJVCBvcHRpbWl6YXRpb24uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoIHsgInVudXNlZCIsICJubHMiIH0pCisgICAgcHJpdmF0ZSBTdHJpbmcoU3RyaW5nIHMxLCBTdHJpbmcgczIsIFN0cmluZyBzMykgeworICAgICAgICBpZiAoczEgPT0gbnVsbCkgeworICAgICAgICAgICAgczEgPSAibnVsbCI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHMyID09IG51bGwpIHsKKyAgICAgICAgICAgIHMyID0gIm51bGwiOworICAgICAgICB9CisgICAgICAgIGlmIChzMyA9PSBudWxsKSB7CisgICAgICAgICAgICBzMyA9ICJudWxsIjsKKyAgICAgICAgfQorICAgICAgICBjb3VudCA9IHMxLmNvdW50ICsgczIuY291bnQgKyBzMy5jb3VudDsKKyAgICAgICAgdmFsdWUgPSBuZXcgY2hhcltjb3VudF07CisgICAgICAgIG9mZnNldCA9IDA7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoczEudmFsdWUsIHMxLm9mZnNldCwgdmFsdWUsIDAsIHMxLmNvdW50KTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzMi52YWx1ZSwgczIub2Zmc2V0LCB2YWx1ZSwgczEuY291bnQsIHMyLmNvdW50KTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzMy52YWx1ZSwgczMub2Zmc2V0LCB2YWx1ZSwgczEuY291bnQgKyBzMi5jb3VudCwgczMuY291bnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgU3RyaW5nfSBmcm9tIHRoZSBjb250ZW50cyBvZiB0aGUgc3BlY2lmaWVkCisgICAgICoge0Bjb2RlIFN0cmluZ0J1ZmZlcn0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyhTdHJpbmdCdWZmZXIgc3RyaW5nQnVmZmVyKSB7CisgICAgICAgIG9mZnNldCA9IDA7CisgICAgICAgIHN5bmNocm9uaXplZCAoc3RyaW5nQnVmZmVyKSB7CisgICAgICAgICAgICB2YWx1ZSA9IHN0cmluZ0J1ZmZlci5zaGFyZVZhbHVlKCk7CisgICAgICAgICAgICBjb3VudCA9IHN0cmluZ0J1ZmZlci5sZW5ndGgoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgU3RyaW5nfSBmcm9tIHRoZSBzdWItYXJyYXkgb2YgVW5pY29kZSBjb2RlIHBvaW50cy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY29kZVBvaW50cyA9PSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBvZiB0aGUgZWxlbWVudHMgb2Yge0Bjb2RlIGNvZGVQb2ludHN9IGFyZSBub3QgdmFsaWQKKyAgICAgKiAgICAgICAgICAgICBVbmljb2RlIGNvZGUgcG9pbnRzLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXR9IG9yIHtAY29kZSBjb3VudH0gYXJlIG5vdCB3aXRoaW4gdGhlIGJvdW5kcworICAgICAqICAgICAgICAgICAgIG9mIHtAY29kZSBjb2RlUG9pbnRzfS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIFN0cmluZyhpbnRbXSBjb2RlUG9pbnRzLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHsKKyAgICAgICAgaWYgKGNvZGVQb2ludHMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChvZmZzZXQgfCBjb3VudCkgPCAwIHx8IGNvdW50ID4gY29kZVBvaW50cy5sZW5ndGggLSBvZmZzZXQpIHsKKyAgICAgICAgICAgIHRocm93IGZhaWxlZEJvdW5kc0NoZWNrKGNvZGVQb2ludHMubGVuZ3RoLCBvZmZzZXQsIGNvdW50KTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLm9mZnNldCA9IDA7CisgICAgICAgIHRoaXMudmFsdWUgPSBuZXcgY2hhcltjb3VudCAqIDJdOworICAgICAgICBpbnQgZW5kID0gb2Zmc2V0ICsgY291bnQ7CisgICAgICAgIGludCBjID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IG9mZnNldDsgaSA8IGVuZDsgaSsrKSB7CisgICAgICAgICAgICBjICs9IENoYXJhY3Rlci50b0NoYXJzKGNvZGVQb2ludHNbaV0sIHRoaXMudmFsdWUsIGMpOworICAgICAgICB9CisgICAgICAgIHRoaXMuY291bnQgPSBjOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgU3RyaW5nfSBmcm9tIHRoZSBjb250ZW50cyBvZiB0aGUgc3BlY2lmaWVkIHtAY29kZQorICAgICAqIFN0cmluZ0J1aWxkZXJ9LgorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdHJpbmdCdWlsZGVyID09IG51bGx9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nKFN0cmluZ0J1aWxkZXIgc3RyaW5nQnVpbGRlcikgeworICAgICAgICBpZiAoc3RyaW5nQnVpbGRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInN0cmluZ0J1aWxkZXIgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRoaXMub2Zmc2V0ID0gMDsKKyAgICAgICAgdGhpcy5jb3VudCA9IHN0cmluZ0J1aWxkZXIubGVuZ3RoKCk7CisgICAgICAgIHRoaXMudmFsdWUgPSBuZXcgY2hhclt0aGlzLmNvdW50XTsKKyAgICAgICAgc3RyaW5nQnVpbGRlci5nZXRDaGFycygwLCB0aGlzLmNvdW50LCB0aGlzLnZhbHVlLCAwKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgU3RyaW5nfSB0aGF0IGlzIHMxICsgdjEuIE1heSBiZSB1c2VkIGJ5IEpJVCBjb2RlLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgIHByaXZhdGUgU3RyaW5nKFN0cmluZyBzMSwgaW50IHYxKSB7CisgICAgICAgIGlmIChzMSA9PSBudWxsKSB7CisgICAgICAgICAgICBzMSA9ICJudWxsIjsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgczIgPSBTdHJpbmcudmFsdWVPZih2MSk7CisgICAgICAgIGludCBsZW4gPSBzMS5jb3VudCArIHMyLmNvdW50OworICAgICAgICB2YWx1ZSA9IG5ldyBjaGFyW2xlbl07CisgICAgICAgIG9mZnNldCA9IDA7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoczEudmFsdWUsIHMxLm9mZnNldCwgdmFsdWUsIDAsIHMxLmNvdW50KTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzMi52YWx1ZSwgczIub2Zmc2V0LCB2YWx1ZSwgczEuY291bnQsIHMyLmNvdW50KTsKKyAgICAgICAgY291bnQgPSBsZW47CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2hhcmFjdGVyIGF0IHRoZSBzcGVjaWZpZWQgb2Zmc2V0IGluIHRoaXMgc3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgemVyby1iYXNlZCBpbmRleCBpbiB0aGlzIHN0cmluZy4KKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIGluZGV4LgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBpbmRleCA8IDB9IG9yIHtAY29kZSBpbmRleCA+PSBsZW5ndGgoKX0uCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSBjaGFyIGNoYXJBdChpbnQgaW5kZXgpOworCisgICAgcHJpdmF0ZSBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGluZGV4QW5kTGVuZ3RoKGludCBpbmRleCkgeworICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbih0aGlzLCBpbmRleCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHN0YXJ0RW5kQW5kTGVuZ3RoKGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbih0aGlzLCBzdGFydCwgZW5kIC0gc3RhcnQpOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBmYWlsZWRCb3VuZHNDaGVjayhpbnQgYXJyYXlMZW5ndGgsIGludCBvZmZzZXQsIGludCBjb3VudCkgeworICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihhcnJheUxlbmd0aCwgb2Zmc2V0LCBjb3VudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBpc24ndCBlcXVpdmFsZW50IHRvIGVpdGhlciBvZiBJQ1UncyB1X2ZvbGRDYXNlIGNhc2UgZm9sZHMsIGFuZCB0aHVzIGFueSBvZiB0aGUgVW5pY29kZQorICAgICAqIGNhc2UgZm9sZHMsIGJ1dCBpdCdzIHdoYXQgdGhlIFJJIHVzZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBjaGFyIGZvbGRDYXNlKGNoYXIgY2gpIHsKKyAgICAgICAgaWYgKGNoIDwgMTI4KSB7CisgICAgICAgICAgICBpZiAoJ0EnIDw9IGNoICYmIGNoIDw9ICdaJykgeworICAgICAgICAgICAgICAgIHJldHVybiAoY2hhcikgKGNoICsgKCdhJyAtICdBJykpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGNoOworICAgICAgICB9CisgICAgICAgIHJldHVybiBDaGFyYWN0ZXIudG9Mb3dlckNhc2UoQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKGNoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBzdHJpbmcgdG8gdGhpcyBzdHJpbmcgdXNpbmcgdGhlIFVuaWNvZGUgdmFsdWVzIG9mCisgICAgICogdGhlIGNoYXJhY3RlcnMuIFJldHVybnMgMCBpZiB0aGUgc3RyaW5ncyBjb250YWluIHRoZSBzYW1lIGNoYXJhY3RlcnMgaW4KKyAgICAgKiB0aGUgc2FtZSBvcmRlci4gUmV0dXJucyBhIG5lZ2F0aXZlIGludGVnZXIgaWYgdGhlIGZpcnN0IG5vbi1lcXVhbAorICAgICAqIGNoYXJhY3RlciBpbiB0aGlzIHN0cmluZyBoYXMgYSBVbmljb2RlIHZhbHVlIHdoaWNoIGlzIGxlc3MgdGhhbiB0aGUKKyAgICAgKiBVbmljb2RlIHZhbHVlIG9mIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIHNhbWUgcG9zaXRpb24gaW4gdGhlIHNwZWNpZmllZAorICAgICAqIHN0cmluZywgb3IgaWYgdGhpcyBzdHJpbmcgaXMgYSBwcmVmaXggb2YgdGhlIHNwZWNpZmllZCBzdHJpbmcuIFJldHVybnMgYQorICAgICAqIHBvc2l0aXZlIGludGVnZXIgaWYgdGhlIGZpcnN0IG5vbi1lcXVhbCBjaGFyYWN0ZXIgaW4gdGhpcyBzdHJpbmcgaGFzIGEKKyAgICAgKiBVbmljb2RlIHZhbHVlIHdoaWNoIGlzIGdyZWF0ZXIgdGhhbiB0aGUgVW5pY29kZSB2YWx1ZSBvZiB0aGUgY2hhcmFjdGVyIGF0CisgICAgICogdGhlIHNhbWUgcG9zaXRpb24gaW4gdGhlIHNwZWNpZmllZCBzdHJpbmcsIG9yIGlmIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGlzCisgICAgICogYSBwcmVmaXggb2YgdGhpcyBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIGNvbXBhcmUuCisgICAgICogQHJldHVybiAwIGlmIHRoZSBzdHJpbmdzIGFyZSBlcXVhbCwgYSBuZWdhdGl2ZSBpbnRlZ2VyIGlmIHRoaXMgc3RyaW5nIGlzCisgICAgICogICAgICAgICBiZWZvcmUgdGhlIHNwZWNpZmllZCBzdHJpbmcsIG9yIGEgcG9zaXRpdmUgaW50ZWdlciBpZiB0aGlzIHN0cmluZworICAgICAqICAgICAgICAgaXMgYWZ0ZXIgdGhlIHNwZWNpZmllZCBzdHJpbmcuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdHJpbmd9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbmF0aXZlIGludCBjb21wYXJlVG8oU3RyaW5nIHN0cmluZyk7CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIHN0cmluZyB0byB0aGlzIHN0cmluZyB1c2luZyB0aGUgVW5pY29kZSB2YWx1ZXMgb2YKKyAgICAgKiB0aGUgY2hhcmFjdGVycywgaWdub3JpbmcgY2FzZSBkaWZmZXJlbmNlcy4gUmV0dXJucyAwIGlmIHRoZSBzdHJpbmdzCisgICAgICogY29udGFpbiB0aGUgc2FtZSBjaGFyYWN0ZXJzIGluIHRoZSBzYW1lIG9yZGVyLiBSZXR1cm5zIGEgbmVnYXRpdmUgaW50ZWdlcgorICAgICAqIGlmIHRoZSBmaXJzdCBub24tZXF1YWwgY2hhcmFjdGVyIGluIHRoaXMgc3RyaW5nIGhhcyBhIFVuaWNvZGUgdmFsdWUgd2hpY2gKKyAgICAgKiBpcyBsZXNzIHRoYW4gdGhlIFVuaWNvZGUgdmFsdWUgb2YgdGhlIGNoYXJhY3RlciBhdCB0aGUgc2FtZSBwb3NpdGlvbiBpbgorICAgICAqIHRoZSBzcGVjaWZpZWQgc3RyaW5nLCBvciBpZiB0aGlzIHN0cmluZyBpcyBhIHByZWZpeCBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogc3RyaW5nLiBSZXR1cm5zIGEgcG9zaXRpdmUgaW50ZWdlciBpZiB0aGUgZmlyc3Qgbm9uLWVxdWFsIGNoYXJhY3RlciBpbgorICAgICAqIHRoaXMgc3RyaW5nIGhhcyBhIFVuaWNvZGUgdmFsdWUgd2hpY2ggaXMgZ3JlYXRlciB0aGFuIHRoZSBVbmljb2RlIHZhbHVlCisgICAgICogb2YgdGhlIGNoYXJhY3RlciBhdCB0aGUgc2FtZSBwb3NpdGlvbiBpbiB0aGUgc3BlY2lmaWVkIHN0cmluZywgb3IgaWYgdGhlCisgICAgICogc3BlY2lmaWVkIHN0cmluZyBpcyBhIHByZWZpeCBvZiB0aGlzIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gY29tcGFyZS4KKyAgICAgKiBAcmV0dXJuIDAgaWYgdGhlIHN0cmluZ3MgYXJlIGVxdWFsLCBhIG5lZ2F0aXZlIGludGVnZXIgaWYgdGhpcyBzdHJpbmcgaXMKKyAgICAgKiAgICAgICAgIGJlZm9yZSB0aGUgc3BlY2lmaWVkIHN0cmluZywgb3IgYSBwb3NpdGl2ZSBpbnRlZ2VyIGlmIHRoaXMgc3RyaW5nCisgICAgICogICAgICAgICBpcyBhZnRlciB0aGUgc3BlY2lmaWVkIHN0cmluZy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0cmluZ30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvSWdub3JlQ2FzZShTdHJpbmcgc3RyaW5nKSB7CisgICAgICAgIGludCBvMSA9IG9mZnNldCwgbzIgPSBzdHJpbmcub2Zmc2V0LCByZXN1bHQ7CisgICAgICAgIGludCBlbmQgPSBvZmZzZXQgKyAoY291bnQgPCBzdHJpbmcuY291bnQgPyBjb3VudCA6IHN0cmluZy5jb3VudCk7CisgICAgICAgIGNoYXIgYzEsIGMyOworICAgICAgICBjaGFyW10gdGFyZ2V0ID0gc3RyaW5nLnZhbHVlOworICAgICAgICB3aGlsZSAobzEgPCBlbmQpIHsKKyAgICAgICAgICAgIGlmICgoYzEgPSB2YWx1ZVtvMSsrXSkgPT0gKGMyID0gdGFyZ2V0W28yKytdKSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYzEgPSBmb2xkQ2FzZShjMSk7CisgICAgICAgICAgICBjMiA9IGZvbGRDYXNlKGMyKTsKKyAgICAgICAgICAgIGlmICgocmVzdWx0ID0gYzEgLSBjMikgIT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvdW50IC0gc3RyaW5nLmNvdW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbmNhdGVuYXRlcyB0aGlzIHN0cmluZyBhbmQgdGhlIHNwZWNpZmllZCBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIGNvbmNhdGVuYXRlCisgICAgICogQHJldHVybiBhIG5ldyBzdHJpbmcgd2hpY2ggaXMgdGhlIGNvbmNhdGVuYXRpb24gb2YgdGhpcyBzdHJpbmcgYW5kIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGNvbmNhdChTdHJpbmcgc3RyaW5nKSB7CisgICAgICAgIGlmIChzdHJpbmcuY291bnQgPiAwICYmIGNvdW50ID4gMCkgeworICAgICAgICAgICAgY2hhcltdIGJ1ZmZlciA9IG5ldyBjaGFyW2NvdW50ICsgc3RyaW5nLmNvdW50XTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsdWUsIG9mZnNldCwgYnVmZmVyLCAwLCBjb3VudCk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHN0cmluZy52YWx1ZSwgc3RyaW5nLm9mZnNldCwgYnVmZmVyLCBjb3VudCwgc3RyaW5nLmNvdW50KTsKKyAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKDAsIGJ1ZmZlci5sZW5ndGgsIGJ1ZmZlcik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvdW50ID09IDAgPyBzdHJpbmcgOiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIKKyAgICAgKiBhcnJheS4gTW9kaWZ5aW5nIHRoZSBjaGFyYWN0ZXIgYXJyYXkgYWZ0ZXIgY3JlYXRpbmcgdGhlIHN0cmluZyBoYXMgbm8KKyAgICAgKiBlZmZlY3Qgb24gdGhlIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgY2hhcmFjdGVycy4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgc3RyaW5nLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGF0YX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGNvcHlWYWx1ZU9mKGNoYXJbXSBkYXRhKSB7CisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGRhdGEsIDAsIGRhdGEubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHN0cmluZyBjb250YWluaW5nIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVycyBpbiB0aGUgY2hhcmFjdGVyCisgICAgICogYXJyYXkuIE1vZGlmeWluZyB0aGUgY2hhcmFjdGVyIGFycmF5IGFmdGVyIGNyZWF0aW5nIHRoZSBzdHJpbmcgaGFzIG5vCisgICAgICogZWZmZWN0IG9uIHRoZSBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIGNoYXJhY3RlcnMuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnRpbmcgb2Zmc2V0IGluIHRoZSBjaGFyYWN0ZXIgYXJyYXkuCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgc3RyaW5nLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGF0YX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBsZW5ndGggPCAwLCBzdGFydCA8IDB9IG9yIHtAY29kZSBzdGFydCArIGxlbmd0aCA+CisgICAgICogICAgICAgICAgICAgZGF0YS5sZW5ndGh9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGNvcHlWYWx1ZU9mKGNoYXJbXSBkYXRhLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoZGF0YSwgc3RhcnQsIGxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBzdHJpbmcgdG8gdGhpcyBzdHJpbmcgdG8gZGV0ZXJtaW5lIGlmIHRoZQorICAgICAqIHNwZWNpZmllZCBzdHJpbmcgaXMgYSBzdWZmaXguCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3VmZml4CisgICAgICogICAgICAgICAgICB0aGUgc3VmZml4IHRvIGxvb2sgZm9yLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGlzIGEgc3VmZml4IG9mIHRoaXMgc3RyaW5nLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdWZmaXh9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBlbmRzV2l0aChTdHJpbmcgc3VmZml4KSB7CisgICAgICAgIHJldHVybiByZWdpb25NYXRjaGVzKGNvdW50IC0gc3VmZml4LmNvdW50LCBzdWZmaXgsIDAsIHN1ZmZpeC5jb3VudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBvYmplY3QgdG8gdGhpcyBzdHJpbmcgYW5kIHJldHVybnMgdHJ1ZSBpZiB0aGV5IGFyZQorICAgICAqIGVxdWFsLiBUaGUgb2JqZWN0IG11c3QgYmUgYW4gaW5zdGFuY2Ugb2Ygc3RyaW5nIHdpdGggdGhlIHNhbWUgY2hhcmFjdGVycworICAgICAqIGluIHRoZSBzYW1lIG9yZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMgc3RyaW5nLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNlZSAjaGFzaENvZGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIG5hdGl2ZSBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KTsKKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIHRvIHRoaXMgc3RyaW5nIGlnbm9yaW5nIHRoZSBjYXNlIG9mIHRoZQorICAgICAqIGNoYXJhY3RlcnMgYW5kIHJldHVybnMgdHJ1ZSBpZiB0aGV5IGFyZSBlcXVhbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gY29tcGFyZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIHN0cmluZyBpcyBlcXVhbCB0byB0aGlzIHN0cmluZywKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBGaW5kQnVnc1N1cHByZXNzV2FybmluZ3MoIkVTX0NPTVBBUklOR19QQVJBTUVURVJfU1RSSU5HX1dJVEhfRVEiKQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFsc0lnbm9yZUNhc2UoU3RyaW5nIHN0cmluZykgeworICAgICAgICBpZiAoc3RyaW5nID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChzdHJpbmcgPT0gbnVsbCB8fCBjb3VudCAhPSBzdHJpbmcuY291bnQpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpbnQgbzEgPSBvZmZzZXQsIG8yID0gc3RyaW5nLm9mZnNldDsKKyAgICAgICAgaW50IGVuZCA9IG9mZnNldCArIGNvdW50OworICAgICAgICBjaGFyW10gdGFyZ2V0ID0gc3RyaW5nLnZhbHVlOworICAgICAgICB3aGlsZSAobzEgPCBlbmQpIHsKKyAgICAgICAgICAgIGNoYXIgYzEgPSB2YWx1ZVtvMSsrXTsKKyAgICAgICAgICAgIGNoYXIgYzIgPSB0YXJnZXRbbzIrK107CisgICAgICAgICAgICBpZiAoYzEgIT0gYzIgJiYgZm9sZENhc2UoYzEpICE9IGZvbGRDYXNlKGMyKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYW5nbGVzIHRoaXMgc3RyaW5nIGludG8gYSBieXRlIGFycmF5IGJ5IHN0cmlwcGluZyB0aGUgaGlnaCBvcmRlciBiaXRzIGZyb20KKyAgICAgKiBlYWNoIGNoYXJhY3Rlci4gVXNlIHtAbGluayAjZ2V0Qnl0ZXMoKX0gb3Ige0BsaW5rICNnZXRCeXRlcyhTdHJpbmcpfSBpbnN0ZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnRpbmcgb2Zmc2V0IG9mIGNoYXJhY3RlcnMgdG8gY29weS4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgZW5kaW5nIG9mZnNldCBvZiBjaGFyYWN0ZXJzIHRvIGNvcHkuCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXN0aW5hdGlvbiBieXRlIGFycmF5LgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIG9mZnNldCBpbiB0aGUgZGVzdGluYXRpb24gYnl0ZSBhcnJheS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGRhdGF9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwfSwge0Bjb2RlIGVuZCA+IGxlbmd0aCgpfSwge0Bjb2RlIGluZGV4IDwKKyAgICAgKiAgICAgICAgICAgICAwfSBvciB7QGNvZGUgZW5kIC0gc3RhcnQgPiBkYXRhLmxlbmd0aCAtIGluZGV4fS4KKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNnZXRCeXRlcygpfSBvciB7QGxpbmsgI2dldEJ5dGVzKFN0cmluZyl9CisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgdm9pZCBnZXRCeXRlcyhpbnQgc3RhcnQsIGludCBlbmQsIGJ5dGVbXSBkYXRhLCBpbnQgaW5kZXgpIHsKKyAgICAgICAgLy8gTm90ZTogbGFzdCBjaGFyYWN0ZXIgbm90IGNvcGllZCEKKyAgICAgICAgaWYgKHN0YXJ0ID49IDAgJiYgc3RhcnQgPD0gZW5kICYmIGVuZCA8PSBjb3VudCkgeworICAgICAgICAgICAgZW5kICs9IG9mZnNldDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IG9mZnNldCArIHN0YXJ0OyBpIDwgZW5kOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZGF0YVtpbmRleCsrXSA9IChieXRlKSB2YWx1ZVtpXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgICAgIHRocm93IGZhaWxlZEJvdW5kc0NoZWNrKGRhdGEubGVuZ3RoLCBpbmRleCwgZW5kIC0gc3RhcnQpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgc3RhcnRFbmRBbmRMZW5ndGgoc3RhcnQsIGVuZCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGJ5dGUgYXJyYXkgY29udGFpbmluZyB0aGUgY2hhcmFjdGVycyBvZiB0aGlzIHN0cmluZyBlbmNvZGVkIHVzaW5nIHRoZQorICAgICAqIHN5c3RlbSdzIHtAbGluayBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQjZGVmYXVsdENoYXJzZXQgZGVmYXVsdCBjaGFyc2V0fS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBiZWhhdmlvciB3aGVuIHRoaXMgc3RyaW5nIGNhbm5vdCBiZSByZXByZXNlbnRlZCBpbiB0aGUgc3lzdGVtJ3MgZGVmYXVsdCBjaGFyc2V0CisgICAgICogaXMgdW5zcGVjaWZpZWQuIEluIHByYWN0aWNlLCB3aGVuIHRoZSBkZWZhdWx0IGNoYXJzZXQgaXMgVVRGLTggKGFzIGl0IGlzIG9uIEFuZHJvaWQpLAorICAgICAqIGFsbCBzdHJpbmdzIGNhbiBiZSBlbmNvZGVkLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0Qnl0ZXMoKSB7CisgICAgICAgIHJldHVybiBnZXRCeXRlcyhDaGFyc2V0LmRlZmF1bHRDaGFyc2V0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgYnl0ZSBhcnJheSBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXJzIG9mIHRoaXMgc3RyaW5nIGVuY29kZWQgdXNpbmcgdGhlCisgICAgICogbmFtZWQgY2hhcnNldC4KKyAgICAgKgorICAgICAqIDxwPlRoZSBiZWhhdmlvciB3aGVuIHRoaXMgc3RyaW5nIGNhbm5vdCBiZSByZXByZXNlbnRlZCBpbiB0aGUgbmFtZWQgY2hhcnNldAorICAgICAqIGlzIHVuc3BlY2lmaWVkLiBVc2Uge0BsaW5rIGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldEVuY29kZXJ9IGZvciBtb3JlIGNvbnRyb2wuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gaWYgdGhlIGNoYXJzZXQgaXMgbm90IHN1cHBvcnRlZAorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0Qnl0ZXMoU3RyaW5nIGNoYXJzZXROYW1lKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXRCeXRlcyhDaGFyc2V0LmZvck5hbWVVRUUoY2hhcnNldE5hbWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGJ5dGUgYXJyYXkgY29udGFpbmluZyB0aGUgY2hhcmFjdGVycyBvZiB0aGlzIHN0cmluZyBlbmNvZGVkIHVzaW5nIHRoZQorICAgICAqIGdpdmVuIGNoYXJzZXQuCisgICAgICoKKyAgICAgKiA8cD5UaGUgYmVoYXZpb3Igd2hlbiB0aGlzIHN0cmluZyBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgaW4gdGhlIGdpdmVuIGNoYXJzZXQKKyAgICAgKiBpcyB0byByZXBsYWNlIG1hbGZvcm1lZCBpbnB1dCBhbmQgdW5tYXBwYWJsZSBjaGFyYWN0ZXJzIHdpdGggdGhlIGNoYXJzZXQncyBkZWZhdWx0CisgICAgICogcmVwbGFjZW1lbnQgYnl0ZSBhcnJheS4gVXNlIHtAbGluayBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRFbmNvZGVyfSBmb3IgbW9yZSBjb250cm9sLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0Qnl0ZXMoQ2hhcnNldCBjaGFyc2V0KSB7CisgICAgICAgIFN0cmluZyBjYW5vbmljYWxDaGFyc2V0TmFtZSA9IGNoYXJzZXQubmFtZSgpOworICAgICAgICBpZiAoY2Fub25pY2FsQ2hhcnNldE5hbWUuZXF1YWxzKCJVVEYtOCIpKSB7CisgICAgICAgICAgICByZXR1cm4gQ2hhcnNldHMudG9VdGY4Qnl0ZXModmFsdWUsIG9mZnNldCwgY291bnQpOworICAgICAgICB9IGVsc2UgaWYgKGNhbm9uaWNhbENoYXJzZXROYW1lLmVxdWFscygiSVNPLTg4NTktMSIpKSB7CisgICAgICAgICAgICByZXR1cm4gQ2hhcnNldHMudG9Jc29MYXRpbjFCeXRlcyh2YWx1ZSwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgIH0gZWxzZSBpZiAoY2Fub25pY2FsQ2hhcnNldE5hbWUuZXF1YWxzKCJVUy1BU0NJSSIpKSB7CisgICAgICAgICAgICByZXR1cm4gQ2hhcnNldHMudG9Bc2NpaUJ5dGVzKHZhbHVlLCBvZmZzZXQsIGNvdW50KTsKKyAgICAgICAgfSBlbHNlIGlmIChjYW5vbmljYWxDaGFyc2V0TmFtZS5lcXVhbHMoIlVURi0xNkJFIikpIHsKKyAgICAgICAgICAgIHJldHVybiBDaGFyc2V0cy50b0JpZ0VuZGlhblV0ZjE2Qnl0ZXModmFsdWUsIG9mZnNldCwgY291bnQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgQ2hhckJ1ZmZlciBjaGFycyA9IENoYXJCdWZmZXIud3JhcCh0aGlzLnZhbHVlLCB0aGlzLm9mZnNldCwgdGhpcy5jb3VudCk7CisgICAgICAgICAgICBCeXRlQnVmZmVyIGJ1ZmZlciA9IGNoYXJzZXQuZW5jb2RlKGNoYXJzLmFzUmVhZE9ubHlCdWZmZXIoKSk7CisgICAgICAgICAgICBieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVtidWZmZXIubGltaXQoKV07CisgICAgICAgICAgICBidWZmZXIuZ2V0KGJ5dGVzKTsKKyAgICAgICAgICAgIHJldHVybiBieXRlczsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlcnMgaW4gdGhpcyBzdHJpbmcgdG8gdGhlIGNoYXJhY3RlciBhcnJheQorICAgICAqIHN0YXJ0aW5nIGF0IHRoZSBzcGVjaWZpZWQgb2Zmc2V0IGluIHRoZSBjaGFyYWN0ZXIgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydGluZyBvZmZzZXQgb2YgY2hhcmFjdGVycyB0byBjb3B5LgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmRpbmcgb2Zmc2V0IG9mIGNoYXJhY3RlcnMgdG8gY29weS4KKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gY2hhcmFjdGVyIGFycmF5LgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIG9mZnNldCBpbiB0aGUgY2hhcmFjdGVyIGFycmF5LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYnVmZmVyfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0IDwgMH0sIHtAY29kZSBlbmQgPiBsZW5ndGgoKX0sIHtAY29kZSBzdGFydCA+CisgICAgICogICAgICAgICAgICAgZW5kfSwge0Bjb2RlIGluZGV4IDwgMH0sIHtAY29kZSBlbmQgLSBzdGFydCA+IGJ1ZmZlci5sZW5ndGggLQorICAgICAqICAgICAgICAgICAgIGluZGV4fQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGdldENoYXJzKGludCBzdGFydCwgaW50IGVuZCwgY2hhcltdIGJ1ZmZlciwgaW50IGluZGV4KSB7CisgICAgICAgIC8vIE5vdGU6IGxhc3QgY2hhcmFjdGVyIG5vdCBjb3BpZWQhCisgICAgICAgIGlmIChzdGFydCA+PSAwICYmIHN0YXJ0IDw9IGVuZCAmJiBlbmQgPD0gY291bnQpIHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsdWUsIHN0YXJ0ICsgb2Zmc2V0LCBidWZmZXIsIGluZGV4LCBlbmQgLSBzdGFydCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBXZSB0aHJvdyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHJhdGhlciB0aGFuIFN5c3RlbS5hcnJheWNvcHkncyBBSU9PQkUuCisgICAgICAgICAgICB0aHJvdyBzdGFydEVuZEFuZExlbmd0aChzdGFydCwgZW5kKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFZlcnNpb24gb2YgZ2V0Q2hhcnMgd2l0aG91dCBib3VuZHMgY2hlY2tzLCBmb3IgdXNlIGJ5IG90aGVyIGNsYXNzZXMKKyAgICAgKiB3aXRoaW4gdGhlIGphdmEubGFuZyBwYWNrYWdlIG9ubHkuICBUaGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvcgorICAgICAqIGVuc3VyaW5nIHRoYXQgc3RhcnQgPj0gMCAmJiBzdGFydCA8PSBlbmQgJiYgZW5kIDw9IGNvdW50LgorICAgICAqLworICAgIHZvaWQgX2dldENoYXJzKGludCBzdGFydCwgaW50IGVuZCwgY2hhcltdIGJ1ZmZlciwgaW50IGluZGV4KSB7CisgICAgICAgIC8vIE5PVEUgbGFzdCBjaGFyYWN0ZXIgbm90IGNvcGllZCEKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weSh2YWx1ZSwgc3RhcnQgKyBvZmZzZXQsIGJ1ZmZlciwgaW5kZXgsIGVuZCAtIHN0YXJ0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IGhhc2ggPSBoYXNoQ29kZTsKKyAgICAgICAgaWYgKGhhc2ggPT0gMCkgeworICAgICAgICAgICAgaWYgKGNvdW50ID09IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpbmFsIGludCBlbmQgPSBjb3VudCArIG9mZnNldDsKKyAgICAgICAgICAgIGZpbmFsIGNoYXJbXSBjaGFycyA9IHZhbHVlOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IG9mZnNldDsgaSA8IGVuZDsgKytpKSB7CisgICAgICAgICAgICAgICAgaGFzaCA9IDMxKmhhc2ggKyBjaGFyc1tpXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGhhc2hDb2RlID0gaGFzaDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyBpbiB0aGlzIHN0cmluZyBmb3IgdGhlIGZpcnN0IGluZGV4IG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyLgorICAgICAqIFRoZSBzZWFyY2ggZm9yIHRoZSBjaGFyYWN0ZXIgc3RhcnRzIGF0IHRoZSBiZWdpbm5pbmcgYW5kIG1vdmVzIHRvd2FyZHMKKyAgICAgKiB0aGUgZW5kIG9mIHRoaXMgc3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gZmluZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBpbiB0aGlzIHN0cmluZyBvZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciwgLTEgaWYgdGhlCisgICAgICogICAgICAgICBjaGFyYWN0ZXIgaXNuJ3QgZm91bmQuCisgICAgICovCisgICAgcHVibGljIGludCBpbmRleE9mKGludCBjKSB7CisgICAgICAgIC8vIFRPRE86IGp1c3QgInJldHVybiBpbmRleE9mKGMsIDApOyIgd2hlbiB0aGUgSklUIGNhbiBpbmxpbmUgdGhhdCBkZWVwLgorICAgICAgICBpZiAoYyA+IDB4ZmZmZikgeworICAgICAgICAgICAgcmV0dXJuIGluZGV4T2ZTdXBwbGVtZW50YXJ5KGMsIDApOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYXN0SW5kZXhPZihjLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyBpbiB0aGlzIHN0cmluZyBmb3IgdGhlIGluZGV4IG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyLiBUaGUKKyAgICAgKiBzZWFyY2ggZm9yIHRoZSBjaGFyYWN0ZXIgc3RhcnRzIGF0IHRoZSBzcGVjaWZpZWQgb2Zmc2V0IGFuZCBtb3ZlcyB0b3dhcmRzCisgICAgICogdGhlIGVuZCBvZiB0aGlzIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIGZpbmQuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnRpbmcgb2Zmc2V0LgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IGluIHRoaXMgc3RyaW5nIG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyLCAtMSBpZiB0aGUKKyAgICAgKiAgICAgICAgIGNoYXJhY3RlciBpc24ndCBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGluZGV4T2YoaW50IGMsIGludCBzdGFydCkgeworICAgICAgICBpZiAoYyA+IDB4ZmZmZikgeworICAgICAgICAgICAgcmV0dXJuIGluZGV4T2ZTdXBwbGVtZW50YXJ5KGMsIHN0YXJ0KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFzdEluZGV4T2YoYywgc3RhcnQpOworICAgIH0KKworICAgIHByaXZhdGUgbmF0aXZlIGludCBmYXN0SW5kZXhPZihpbnQgYywgaW50IHN0YXJ0KTsKKworICAgIHByaXZhdGUgaW50IGluZGV4T2ZTdXBwbGVtZW50YXJ5KGludCBjLCBpbnQgc3RhcnQpIHsKKyAgICAgICAgaWYgKCFDaGFyYWN0ZXIuaXNTdXBwbGVtZW50YXJ5Q29kZVBvaW50KGMpKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgY2hhcltdIGNoYXJzID0gQ2hhcmFjdGVyLnRvQ2hhcnMoYyk7CisgICAgICAgIFN0cmluZyBuZWVkbGUgPSBuZXcgU3RyaW5nKDAsIGNoYXJzLmxlbmd0aCwgY2hhcnMpOworICAgICAgICByZXR1cm4gaW5kZXhPZihuZWVkbGUsIHN0YXJ0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyBpbiB0aGlzIHN0cmluZyBmb3IgdGhlIGZpcnN0IGluZGV4IG9mIHRoZSBzcGVjaWZpZWQgc3RyaW5nLiBUaGUKKyAgICAgKiBzZWFyY2ggZm9yIHRoZSBzdHJpbmcgc3RhcnRzIGF0IHRoZSBiZWdpbm5pbmcgYW5kIG1vdmVzIHRvd2FyZHMgdGhlIGVuZAorICAgICAqIG9mIHRoaXMgc3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBmaW5kLgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIHNwZWNpZmllZCBzdHJpbmcgaW4gdGhpcworICAgICAqICAgICAgICAgc3RyaW5nLCAtMSBpZiB0aGUgc3BlY2lmaWVkIHN0cmluZyBpcyBub3QgYSBzdWJzdHJpbmcuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdHJpbmd9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGluZGV4T2YoU3RyaW5nIHN0cmluZykgeworICAgICAgICBpbnQgc3RhcnQgPSAwOworICAgICAgICBpbnQgc3ViQ291bnQgPSBzdHJpbmcuY291bnQ7CisgICAgICAgIGludCBfY291bnQgPSBjb3VudDsKKyAgICAgICAgaWYgKHN1YkNvdW50ID4gMCkgeworICAgICAgICAgICAgaWYgKHN1YkNvdW50ID4gX2NvdW50KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2hhcltdIHRhcmdldCA9IHN0cmluZy52YWx1ZTsKKyAgICAgICAgICAgIGludCBzdWJPZmZzZXQgPSBzdHJpbmcub2Zmc2V0OworICAgICAgICAgICAgY2hhciBmaXJzdENoYXIgPSB0YXJnZXRbc3ViT2Zmc2V0XTsKKyAgICAgICAgICAgIGludCBlbmQgPSBzdWJPZmZzZXQgKyBzdWJDb3VudDsKKyAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgaW50IGkgPSBpbmRleE9mKGZpcnN0Q2hhciwgc3RhcnQpOworICAgICAgICAgICAgICAgIGlmIChpID09IC0xIHx8IHN1YkNvdW50ICsgaSA+IF9jb3VudCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7IC8vIGhhbmRsZXMgc3ViQ291bnQgPiBjb3VudCB8fCBzdGFydCA+PSBjb3VudAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpbnQgbzEgPSBvZmZzZXQgKyBpLCBvMiA9IHN1Yk9mZnNldDsKKyAgICAgICAgICAgICAgICBjaGFyW10gX3ZhbHVlID0gdmFsdWU7CisgICAgICAgICAgICAgICAgd2hpbGUgKCsrbzIgPCBlbmQgJiYgX3ZhbHVlWysrbzFdID09IHRhcmdldFtvMl0pIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gSW50ZW50aW9uYWxseSBlbXB0eQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAobzIgPT0gZW5kKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzdGFydCA9IGkgKyAxOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBzdGFydCA8IF9jb3VudCA/IHN0YXJ0IDogX2NvdW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlYXJjaGVzIGluIHRoaXMgc3RyaW5nIGZvciB0aGUgaW5kZXggb2YgdGhlIHNwZWNpZmllZCBzdHJpbmcuIFRoZSBzZWFyY2gKKyAgICAgKiBmb3IgdGhlIHN0cmluZyBzdGFydHMgYXQgdGhlIHNwZWNpZmllZCBvZmZzZXQgYW5kIG1vdmVzIHRvd2FyZHMgdGhlIGVuZAorICAgICAqIG9mIHRoaXMgc3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHN1YlN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBmaW5kLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIG9mZnNldC4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGluIHRoaXMKKyAgICAgKiAgICAgICAgIHN0cmluZywgLTEgaWYgdGhlIHNwZWNpZmllZCBzdHJpbmcgaXMgbm90IGEgc3Vic3RyaW5nLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3ViU3RyaW5nfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIGludCBpbmRleE9mKFN0cmluZyBzdWJTdHJpbmcsIGludCBzdGFydCkgeworICAgICAgICBpZiAoc3RhcnQgPCAwKSB7CisgICAgICAgICAgICBzdGFydCA9IDA7CisgICAgICAgIH0KKyAgICAgICAgaW50IHN1YkNvdW50ID0gc3ViU3RyaW5nLmNvdW50OworICAgICAgICBpbnQgX2NvdW50ID0gY291bnQ7CisgICAgICAgIGlmIChzdWJDb3VudCA+IDApIHsKKyAgICAgICAgICAgIGlmIChzdWJDb3VudCArIHN0YXJ0ID4gX2NvdW50KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2hhcltdIHRhcmdldCA9IHN1YlN0cmluZy52YWx1ZTsKKyAgICAgICAgICAgIGludCBzdWJPZmZzZXQgPSBzdWJTdHJpbmcub2Zmc2V0OworICAgICAgICAgICAgY2hhciBmaXJzdENoYXIgPSB0YXJnZXRbc3ViT2Zmc2V0XTsKKyAgICAgICAgICAgIGludCBlbmQgPSBzdWJPZmZzZXQgKyBzdWJDb3VudDsKKyAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgaW50IGkgPSBpbmRleE9mKGZpcnN0Q2hhciwgc3RhcnQpOworICAgICAgICAgICAgICAgIGlmIChpID09IC0xIHx8IHN1YkNvdW50ICsgaSA+IF9jb3VudCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7IC8vIGhhbmRsZXMgc3ViQ291bnQgPiBjb3VudCB8fCBzdGFydCA+PSBjb3VudAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpbnQgbzEgPSBvZmZzZXQgKyBpLCBvMiA9IHN1Yk9mZnNldDsKKyAgICAgICAgICAgICAgICBjaGFyW10gX3ZhbHVlID0gdmFsdWU7CisgICAgICAgICAgICAgICAgd2hpbGUgKCsrbzIgPCBlbmQgJiYgX3ZhbHVlWysrbzFdID09IHRhcmdldFtvMl0pIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gSW50ZW50aW9uYWxseSBlbXB0eQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAobzIgPT0gZW5kKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzdGFydCA9IGkgKyAxOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBzdGFydCA8IF9jb3VudCA/IHN0YXJ0IDogX2NvdW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW50ZXJuZWQgc3RyaW5nIGVxdWFsIHRvIHRoaXMgc3RyaW5nLiBUaGUgVk0gbWFpbnRhaW5zIGFuIGludGVybmFsIHNldCBvZgorICAgICAqIHVuaXF1ZSBzdHJpbmdzLiBBbGwgc3RyaW5nIGxpdGVyYWxzIGZvdW5kIGluIGxvYWRlZCBjbGFzc2VzJworICAgICAqIGNvbnN0YW50IHBvb2xzIGFyZSBhdXRvbWF0aWNhbGx5IGludGVybmVkLiBNYW51YWxseS1pbnRlcm5lZCBzdHJpbmdzIGFyZSBvbmx5IHdlYWtseQorICAgICAqIHJlZmVyZW5jZWQsIHNvIGNhbGxpbmcge0Bjb2RlIGludGVybn0gd29uJ3QgbGVhZCB0byB1bndhbnRlZCByZXRlbnRpb24uCisgICAgICoKKyAgICAgKiA8cD5JbnRlcm5pbmcgaXMgdHlwaWNhbGx5IHVzZWQgYmVjYXVzZSBpdCBndWFyYW50ZWVzIHRoYXQgZm9yIGludGVybmVkIHN0cmluZ3MKKyAgICAgKiB7QGNvZGUgYX0gYW5kIHtAY29kZSBifSwge0Bjb2RlIGEuZXF1YWxzKGIpfSBjYW4gYmUgc2ltcGxpZmllZCB0bworICAgICAqIHtAY29kZSBhID09IGJ9LiAoVGhpcyBpcyBub3QgdHJ1ZSBvZiBub24taW50ZXJuZWQgc3RyaW5ncy4pCisgICAgICoKKyAgICAgKiA8cD5NYW55IGFwcGxpY2F0aW9ucyBmaW5kIGl0IHNpbXBsZXIgYW5kIG1vcmUgY29udmVuaWVudCB0byB1c2UgYW4gZXhwbGljaXQKKyAgICAgKiB7QGxpbmsgamF2YS51dGlsLkhhc2hNYXB9IHRvIGltcGxlbWVudCB0aGVpciBvd24gcG9vbHMuCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSBTdHJpbmcgaW50ZXJuKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZyBpcyAwLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBuYXRpdmUgYm9vbGVhbiBpc0VtcHR5KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsYXN0IGluZGV4IG9mIHRoZSBjb2RlIHBvaW50IHtAY29kZSBjfSwgb3IgLTEuCisgICAgICogVGhlIHNlYXJjaCBmb3IgdGhlIGNoYXJhY3RlciBzdGFydHMgYXQgdGhlIGVuZCBhbmQgbW92ZXMgdG93YXJkcyB0aGUKKyAgICAgKiBiZWdpbm5pbmcgb2YgdGhpcyBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIGludCBsYXN0SW5kZXhPZihpbnQgYykgeworICAgICAgICBpZiAoYyA+IDB4ZmZmZikgeworICAgICAgICAgICAgcmV0dXJuIGxhc3RJbmRleE9mU3VwcGxlbWVudGFyeShjLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIH0KKyAgICAgICAgaW50IF9jb3VudCA9IGNvdW50OworICAgICAgICBpbnQgX29mZnNldCA9IG9mZnNldDsKKyAgICAgICAgY2hhcltdIF92YWx1ZSA9IHZhbHVlOworICAgICAgICBmb3IgKGludCBpID0gX29mZnNldCArIF9jb3VudCAtIDE7IGkgPj0gX29mZnNldDsgLS1pKSB7CisgICAgICAgICAgICBpZiAoX3ZhbHVlW2ldID09IGMpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gaSAtIF9vZmZzZXQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxhc3QgaW5kZXggb2YgdGhlIGNvZGUgcG9pbnQge0Bjb2RlIGN9LCBvciAtMS4KKyAgICAgKiBUaGUgc2VhcmNoIGZvciB0aGUgY2hhcmFjdGVyIHN0YXJ0cyBhdCBvZmZzZXQge0Bjb2RlIHN0YXJ0fSBhbmQgbW92ZXMgdG93YXJkcworICAgICAqIHRoZSBiZWdpbm5pbmcgb2YgdGhpcyBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIGludCBsYXN0SW5kZXhPZihpbnQgYywgaW50IHN0YXJ0KSB7CisgICAgICAgIGlmIChjID4gMHhmZmZmKSB7CisgICAgICAgICAgICByZXR1cm4gbGFzdEluZGV4T2ZTdXBwbGVtZW50YXJ5KGMsIHN0YXJ0KTsKKyAgICAgICAgfQorICAgICAgICBpbnQgX2NvdW50ID0gY291bnQ7CisgICAgICAgIGludCBfb2Zmc2V0ID0gb2Zmc2V0OworICAgICAgICBjaGFyW10gX3ZhbHVlID0gdmFsdWU7CisgICAgICAgIGlmIChzdGFydCA+PSAwKSB7CisgICAgICAgICAgICBpZiAoc3RhcnQgPj0gX2NvdW50KSB7CisgICAgICAgICAgICAgICAgc3RhcnQgPSBfY291bnQgLSAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChpbnQgaSA9IF9vZmZzZXQgKyBzdGFydDsgaSA+PSBfb2Zmc2V0OyAtLWkpIHsKKyAgICAgICAgICAgICAgICBpZiAoX3ZhbHVlW2ldID09IGMpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGkgLSBfb2Zmc2V0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgbGFzdEluZGV4T2ZTdXBwbGVtZW50YXJ5KGludCBjLCBpbnQgc3RhcnQpIHsKKyAgICAgICAgaWYgKCFDaGFyYWN0ZXIuaXNTdXBwbGVtZW50YXJ5Q29kZVBvaW50KGMpKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgY2hhcltdIGNoYXJzID0gQ2hhcmFjdGVyLnRvQ2hhcnMoYyk7CisgICAgICAgIFN0cmluZyBuZWVkbGUgPSBuZXcgU3RyaW5nKDAsIGNoYXJzLmxlbmd0aCwgY2hhcnMpOworICAgICAgICByZXR1cm4gbGFzdEluZGV4T2YobmVlZGxlLCBzdGFydCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VhcmNoZXMgaW4gdGhpcyBzdHJpbmcgZm9yIHRoZSBsYXN0IGluZGV4IG9mIHRoZSBzcGVjaWZpZWQgc3RyaW5nLiBUaGUKKyAgICAgKiBzZWFyY2ggZm9yIHRoZSBzdHJpbmcgc3RhcnRzIGF0IHRoZSBlbmQgYW5kIG1vdmVzIHRvd2FyZHMgdGhlIGJlZ2lubmluZworICAgICAqIG9mIHRoaXMgc3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBmaW5kLgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIHNwZWNpZmllZCBzdHJpbmcgaW4gdGhpcworICAgICAqICAgICAgICAgc3RyaW5nLCAtMSBpZiB0aGUgc3BlY2lmaWVkIHN0cmluZyBpcyBub3QgYSBzdWJzdHJpbmcuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdHJpbmd9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGxhc3RJbmRleE9mKFN0cmluZyBzdHJpbmcpIHsKKyAgICAgICAgLy8gVXNlIGNvdW50IGluc3RlYWQgb2YgY291bnQgLSAxIHNvIGxhc3RJbmRleE9mKCIiKSByZXR1cm5zIGNvdW50CisgICAgICAgIHJldHVybiBsYXN0SW5kZXhPZihzdHJpbmcsIGNvdW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyBpbiB0aGlzIHN0cmluZyBmb3IgdGhlIGluZGV4IG9mIHRoZSBzcGVjaWZpZWQgc3RyaW5nLiBUaGUgc2VhcmNoCisgICAgICogZm9yIHRoZSBzdHJpbmcgc3RhcnRzIGF0IHRoZSBzcGVjaWZpZWQgb2Zmc2V0IGFuZCBtb3ZlcyB0b3dhcmRzIHRoZQorICAgICAqIGJlZ2lubmluZyBvZiB0aGlzIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdWJTdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gZmluZC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydGluZyBvZmZzZXQuCisgICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgc3BlY2lmaWVkIHN0cmluZyBpbiB0aGlzCisgICAgICogICAgICAgICBzdHJpbmcgLCAtMSBpZiB0aGUgc3BlY2lmaWVkIHN0cmluZyBpcyBub3QgYSBzdWJzdHJpbmcuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdWJTdHJpbmd9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGxhc3RJbmRleE9mKFN0cmluZyBzdWJTdHJpbmcsIGludCBzdGFydCkgeworICAgICAgICBpbnQgc3ViQ291bnQgPSBzdWJTdHJpbmcuY291bnQ7CisgICAgICAgIGlmIChzdWJDb3VudCA8PSBjb3VudCAmJiBzdGFydCA+PSAwKSB7CisgICAgICAgICAgICBpZiAoc3ViQ291bnQgPiAwKSB7CisgICAgICAgICAgICAgICAgaWYgKHN0YXJ0ID4gY291bnQgLSBzdWJDb3VudCkgeworICAgICAgICAgICAgICAgICAgICBzdGFydCA9IGNvdW50IC0gc3ViQ291bnQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIGNvdW50IGFuZCBzdWJDb3VudCBhcmUgYm90aCA+PSAxCisgICAgICAgICAgICAgICAgY2hhcltdIHRhcmdldCA9IHN1YlN0cmluZy52YWx1ZTsKKyAgICAgICAgICAgICAgICBpbnQgc3ViT2Zmc2V0ID0gc3ViU3RyaW5nLm9mZnNldDsKKyAgICAgICAgICAgICAgICBjaGFyIGZpcnN0Q2hhciA9IHRhcmdldFtzdWJPZmZzZXRdOworICAgICAgICAgICAgICAgIGludCBlbmQgPSBzdWJPZmZzZXQgKyBzdWJDb3VudDsKKyAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgICAgICBpbnQgaSA9IGxhc3RJbmRleE9mKGZpcnN0Q2hhciwgc3RhcnQpOworICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGludCBvMSA9IG9mZnNldCArIGksIG8yID0gc3ViT2Zmc2V0OworICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKytvMiA8IGVuZCAmJiB2YWx1ZVsrK28xXSA9PSB0YXJnZXRbbzJdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbnRlbnRpb25hbGx5IGVtcHR5CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKG8yID09IGVuZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgc3RhcnQgPSBpIC0gMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gc3RhcnQgPCBjb3VudCA/IHN0YXJ0IDogY291bnQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNpemUgb2YgdGhpcyBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGlzIHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgbmF0aXZlIGludCBsZW5ndGgoKTsKKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIHRvIHRoaXMgc3RyaW5nIGFuZCBjb21wYXJlcyB0aGUgc3BlY2lmaWVkCisgICAgICogcmFuZ2Ugb2YgY2hhcmFjdGVycyB0byBkZXRlcm1pbmUgaWYgdGhleSBhcmUgdGhlIHNhbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhpc1N0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnRpbmcgb2Zmc2V0IGluIHRoaXMgc3RyaW5nLgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gY29tcGFyZS4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydGluZyBvZmZzZXQgaW4gdGhlIHNwZWNpZmllZCBzdHJpbmcuCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIGNvbXBhcmUuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHJhbmdlcyBvZiBjaGFyYWN0ZXJzIGFyZSBlcXVhbCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdHJpbmd9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiByZWdpb25NYXRjaGVzKGludCB0aGlzU3RhcnQsIFN0cmluZyBzdHJpbmcsIGludCBzdGFydCwgaW50IGxlbmd0aCkgeworICAgICAgICBpZiAoc3RyaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChzdGFydCA8IDAgfHwgc3RyaW5nLmNvdW50IC0gc3RhcnQgPCBsZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpZiAodGhpc1N0YXJ0IDwgMCB8fCBjb3VudCAtIHRoaXNTdGFydCA8IGxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmIChsZW5ndGggPD0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaW50IG8xID0gb2Zmc2V0ICsgdGhpc1N0YXJ0LCBvMiA9IHN0cmluZy5vZmZzZXQgKyBzdGFydDsKKyAgICAgICAgY2hhcltdIHZhbHVlMSA9IHZhbHVlOworICAgICAgICBjaGFyW10gdmFsdWUyID0gc3RyaW5nLnZhbHVlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICBpZiAodmFsdWUxW28xICsgaV0gIT0gdmFsdWUyW28yICsgaV0pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBzdHJpbmcgdG8gdGhpcyBzdHJpbmcgYW5kIGNvbXBhcmVzIHRoZSBzcGVjaWZpZWQKKyAgICAgKiByYW5nZSBvZiBjaGFyYWN0ZXJzIHRvIGRldGVybWluZSBpZiB0aGV5IGFyZSB0aGUgc2FtZS4gV2hlbiBpZ25vcmVDYXNlIGlzCisgICAgICogdHJ1ZSwgdGhlIGNhc2Ugb2YgdGhlIGNoYXJhY3RlcnMgaXMgaWdub3JlZCBkdXJpbmcgdGhlIGNvbXBhcmlzb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaWdub3JlQ2FzZQorICAgICAqICAgICAgICAgICAgc3BlY2lmaWVzIGlmIGNhc2Ugc2hvdWxkIGJlIGlnbm9yZWQuCisgICAgICogQHBhcmFtIHRoaXNTdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIG9mZnNldCBpbiB0aGlzIHN0cmluZy4KKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIGNvbXBhcmUuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnRpbmcgb2Zmc2V0IGluIHRoZSBzcGVjaWZpZWQgc3RyaW5nLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBjb21wYXJlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSByYW5nZXMgb2YgY2hhcmFjdGVycyBhcmUgZXF1YWwsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0cmluZ30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlZ2lvbk1hdGNoZXMoYm9vbGVhbiBpZ25vcmVDYXNlLCBpbnQgdGhpc1N0YXJ0LCBTdHJpbmcgc3RyaW5nLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHsKKyAgICAgICAgaWYgKCFpZ25vcmVDYXNlKSB7CisgICAgICAgICAgICByZXR1cm4gcmVnaW9uTWF0Y2hlcyh0aGlzU3RhcnQsIHN0cmluZywgc3RhcnQsIGxlbmd0aCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHN0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInN0cmluZyA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRoaXNTdGFydCA8IDAgfHwgbGVuZ3RoID4gY291bnQgLSB0aGlzU3RhcnQpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3RhcnQgPCAwIHx8IGxlbmd0aCA+IHN0cmluZy5jb3VudCAtIHN0YXJ0KSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgdGhpc1N0YXJ0ICs9IG9mZnNldDsKKyAgICAgICAgc3RhcnQgKz0gc3RyaW5nLm9mZnNldDsKKyAgICAgICAgaW50IGVuZCA9IHRoaXNTdGFydCArIGxlbmd0aDsKKyAgICAgICAgY2hhcltdIHRhcmdldCA9IHN0cmluZy52YWx1ZTsKKyAgICAgICAgd2hpbGUgKHRoaXNTdGFydCA8IGVuZCkgeworICAgICAgICAgICAgY2hhciBjMSA9IHZhbHVlW3RoaXNTdGFydCsrXTsKKyAgICAgICAgICAgIGNoYXIgYzIgPSB0YXJnZXRbc3RhcnQrK107CisgICAgICAgICAgICBpZiAoYzEgIT0gYzIgJiYgZm9sZENhc2UoYzEpICE9IGZvbGRDYXNlKGMyKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgdGhpcyBzdHJpbmcgcmVwbGFjaW5nIG9jY3VycmVuY2VzIG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIHdpdGgKKyAgICAgKiBhbm90aGVyIGNoYXJhY3Rlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvbGRDaGFyCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIHJlcGxhY2UuCisgICAgICogQHBhcmFtIG5ld0NoYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXBsYWNlbWVudCBjaGFyYWN0ZXIuCisgICAgICogQHJldHVybiBhIG5ldyBzdHJpbmcgd2l0aCBvY2N1cnJlbmNlcyBvZiBvbGRDaGFyIHJlcGxhY2VkIGJ5IG5ld0NoYXIuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyByZXBsYWNlKGNoYXIgb2xkQ2hhciwgY2hhciBuZXdDaGFyKSB7CisgICAgICAgIGNoYXJbXSBidWZmZXIgPSB2YWx1ZTsKKyAgICAgICAgaW50IF9vZmZzZXQgPSBvZmZzZXQ7CisgICAgICAgIGludCBfY291bnQgPSBjb3VudDsKKworICAgICAgICBpbnQgaWR4ID0gX29mZnNldDsKKyAgICAgICAgaW50IGxhc3QgPSBfb2Zmc2V0ICsgX2NvdW50OworICAgICAgICBib29sZWFuIGNvcGllZCA9IGZhbHNlOworICAgICAgICB3aGlsZSAoaWR4IDwgbGFzdCkgeworICAgICAgICAgICAgaWYgKGJ1ZmZlcltpZHhdID09IG9sZENoYXIpIHsKKyAgICAgICAgICAgICAgICBpZiAoIWNvcGllZCkgeworICAgICAgICAgICAgICAgICAgICBjaGFyW10gbmV3QnVmZmVyID0gbmV3IGNoYXJbX2NvdW50XTsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWZmZXIsIF9vZmZzZXQsIG5ld0J1ZmZlciwgMCwgX2NvdW50KTsKKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyID0gbmV3QnVmZmVyOworICAgICAgICAgICAgICAgICAgICBpZHggLT0gX29mZnNldDsKKyAgICAgICAgICAgICAgICAgICAgbGFzdCAtPSBfb2Zmc2V0OworICAgICAgICAgICAgICAgICAgICBjb3BpZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBidWZmZXJbaWR4XSA9IG5ld0NoYXI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZHgrKzsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjb3BpZWQgPyBuZXcgU3RyaW5nKDAsIGNvdW50LCBidWZmZXIpIDogdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgdGhpcyBzdHJpbmcgcmVwbGFjaW5nIG9jY3VycmVuY2VzIG9mIHRoZSBzcGVjaWZpZWQgdGFyZ2V0IHNlcXVlbmNlCisgICAgICogd2l0aCBhbm90aGVyIHNlcXVlbmNlLiBUaGUgc3RyaW5nIGlzIHByb2Nlc3NlZCBmcm9tIHRoZSBiZWdpbm5pbmcgdG8gdGhlCisgICAgICogZW5kLgorICAgICAqCisgICAgICogQHBhcmFtIHRhcmdldAorICAgICAqICAgICAgICAgICAgdGhlIHNlcXVlbmNlIHRvIHJlcGxhY2UuCisgICAgICogQHBhcmFtIHJlcGxhY2VtZW50CisgICAgICogICAgICAgICAgICB0aGUgcmVwbGFjZW1lbnQgc2VxdWVuY2UuCisgICAgICogQHJldHVybiB0aGUgcmVzdWx0aW5nIHN0cmluZy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHRhcmdldH0gb3Ige0Bjb2RlIHJlcGxhY2VtZW50fSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyByZXBsYWNlKENoYXJTZXF1ZW5jZSB0YXJnZXQsIENoYXJTZXF1ZW5jZSByZXBsYWNlbWVudCkgeworICAgICAgICBpZiAodGFyZ2V0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidGFyZ2V0ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocmVwbGFjZW1lbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJyZXBsYWNlbWVudCA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgdGFyZ2V0U3RyaW5nID0gdGFyZ2V0LnRvU3RyaW5nKCk7CisgICAgICAgIGludCBtYXRjaFN0YXJ0ID0gaW5kZXhPZih0YXJnZXRTdHJpbmcsIDApOworICAgICAgICBpZiAobWF0Y2hTdGFydCA9PSAtMSkgeworICAgICAgICAgICAgLy8gSWYgdGhlcmUncyBub3RoaW5nIHRvIHJlcGxhY2UsIHJldHVybiB0aGUgb3JpZ2luYWwgc3RyaW5nIHVudG91Y2hlZC4KKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIHJlcGxhY2VtZW50U3RyaW5nID0gcmVwbGFjZW1lbnQudG9TdHJpbmcoKTsKKworICAgICAgICAvLyBUaGUgZW1wdHkgdGFyZ2V0IG1hdGNoZXMgYXQgdGhlIHN0YXJ0IGFuZCBlbmQgYW5kIGJldHdlZW4gZWFjaCBjaGFyYWN0ZXIuCisgICAgICAgIGludCB0YXJnZXRMZW5ndGggPSB0YXJnZXRTdHJpbmcubGVuZ3RoKCk7CisgICAgICAgIGlmICh0YXJnZXRMZW5ndGggPT0gMCkgeworICAgICAgICAgICAgaW50IHJlc3VsdExlbmd0aCA9IChjb3VudCArIDIpICogcmVwbGFjZW1lbnRTdHJpbmcubGVuZ3RoKCk7CisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKHJlc3VsdExlbmd0aCk7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHJlcGxhY2VtZW50U3RyaW5nKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBvZmZzZXQ7IGkgPCBjb3VudDsgKytpKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCh2YWx1ZVtpXSk7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChyZXBsYWNlbWVudFN0cmluZyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKGNvdW50KTsKKyAgICAgICAgaW50IHNlYXJjaFN0YXJ0ID0gMDsKKyAgICAgICAgZG8geworICAgICAgICAgICAgLy8gQ29weSBjaGFyYWN0ZXJzIGJlZm9yZSB0aGUgbWF0Y2guLi4KKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQodmFsdWUsIG9mZnNldCArIHNlYXJjaFN0YXJ0LCBtYXRjaFN0YXJ0IC0gc2VhcmNoU3RhcnQpOworICAgICAgICAgICAgLy8gSW5zZXJ0IHRoZSByZXBsYWNlbWVudC4uLgorICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChyZXBsYWNlbWVudFN0cmluZyk7CisgICAgICAgICAgICAvLyBBbmQgc2tpcCBvdmVyIHRoZSBtYXRjaC4uLgorICAgICAgICAgICAgc2VhcmNoU3RhcnQgPSBtYXRjaFN0YXJ0ICsgdGFyZ2V0TGVuZ3RoOworICAgICAgICB9IHdoaWxlICgobWF0Y2hTdGFydCA9IGluZGV4T2YodGFyZ2V0U3RyaW5nLCBzZWFyY2hTdGFydCkpICE9IC0xKTsKKyAgICAgICAgLy8gQ29weSBhbnkgdHJhaWxpbmcgY2hhcnMuLi4KKyAgICAgICAgcmVzdWx0LmFwcGVuZCh2YWx1ZSwgb2Zmc2V0ICsgc2VhcmNoU3RhcnQsIGNvdW50IC0gc2VhcmNoU3RhcnQpOworICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBzdHJpbmcgdG8gdGhpcyBzdHJpbmcgdG8gZGV0ZXJtaW5lIGlmIHRoZQorICAgICAqIHNwZWNpZmllZCBzdHJpbmcgaXMgYSBwcmVmaXguCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJlZml4CisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIGxvb2sgZm9yLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGlzIGEgcHJlZml4IG9mIHRoaXMgc3RyaW5nLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHByZWZpeH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN0YXJ0c1dpdGgoU3RyaW5nIHByZWZpeCkgeworICAgICAgICByZXR1cm4gc3RhcnRzV2l0aChwcmVmaXgsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIHRvIHRoaXMgc3RyaW5nLCBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkCisgICAgICogb2Zmc2V0LCB0byBkZXRlcm1pbmUgaWYgdGhlIHNwZWNpZmllZCBzdHJpbmcgaXMgYSBwcmVmaXguCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJlZml4CisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIGxvb2sgZm9yLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIG9mZnNldC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIHN0cmluZyBvY2N1cnMgaW4gdGhpcyBzdHJpbmcgYXQgdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgb2Zmc2V0LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHByZWZpeH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN0YXJ0c1dpdGgoU3RyaW5nIHByZWZpeCwgaW50IHN0YXJ0KSB7CisgICAgICAgIHJldHVybiByZWdpb25NYXRjaGVzKHN0YXJ0LCBwcmVmaXgsIDAsIHByZWZpeC5jb3VudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgc3VmZml4IG9mIHRoaXMgc3RyaW5nLiBUaGUgcmV0dXJuZWQgc3RyaW5nCisgICAgICogc2hhcmVzIHRoaXMgc3RyaW5nJ3MgPGEgaHJlZj0iI2JhY2tpbmdfYXJyYXkiPmJhY2tpbmcgYXJyYXk8L2E+LgorICAgICAqCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIuCisgICAgICogQHJldHVybiBhIG5ldyBzdHJpbmcgY29udGFpbmluZyB0aGUgY2hhcmFjdGVycyBmcm9tIHN0YXJ0IHRvIHRoZSBlbmQgb2YKKyAgICAgKiAgICAgICAgIHRoZSBzdHJpbmcuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0IDwgMH0gb3Ige0Bjb2RlIHN0YXJ0ID4gbGVuZ3RoKCl9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgc3Vic3RyaW5nKGludCBzdGFydCkgeworICAgICAgICBpZiAoc3RhcnQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHN0YXJ0ID49IDAgJiYgc3RhcnQgPD0gY291bnQpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKG9mZnNldCArIHN0YXJ0LCBjb3VudCAtIHN0YXJ0LCB2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgaW5kZXhBbmRMZW5ndGgoc3RhcnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIHN1YnNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgZnJvbSB0aGlzIHN0cmluZy4KKyAgICAgKiBUaGUgcmV0dXJuZWQgc3RyaW5nIHNoYXJlcyB0aGlzIHN0cmluZydzIDxhIGhyZWY9IiNiYWNraW5nX2FycmF5Ij5iYWNraW5nCisgICAgICogYXJyYXk8L2E+LgorICAgICAqCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvbmUgcGFzdCB0aGUgbGFzdCBjaGFyYWN0ZXIuCisgICAgICogQHJldHVybiBhIG5ldyBzdHJpbmcgY29udGFpbmluZyB0aGUgY2hhcmFjdGVycyBmcm9tIHN0YXJ0IHRvIGVuZCAtIDEKKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwfSwge0Bjb2RlIHN0YXJ0ID4gZW5kfSBvciB7QGNvZGUgZW5kID4KKyAgICAgKiAgICAgICAgICAgICBsZW5ndGgoKX0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBzdWJzdHJpbmcoaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIGlmIChzdGFydCA9PSAwICYmIGVuZCA9PSBjb3VudCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKyAgICAgICAgLy8gTk9URSBsYXN0IGNoYXJhY3RlciBub3QgY29waWVkIQorICAgICAgICAvLyBGYXN0IHJhbmdlIGNoZWNrLgorICAgICAgICBpZiAoc3RhcnQgPj0gMCAmJiBzdGFydCA8PSBlbmQgJiYgZW5kIDw9IGNvdW50KSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhvZmZzZXQgKyBzdGFydCwgZW5kIC0gc3RhcnQsIHZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBzdGFydEVuZEFuZExlbmd0aChzdGFydCwgZW5kKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgdGhlIGNoYXJhY3RlcnMgaW4gdGhpcyBzdHJpbmcgdG8gYSBjaGFyYWN0ZXIgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY2hhcmFjdGVyIGFycmF5IGNvbnRhaW5pbmcgdGhlIGNoYXJhY3RlcnMgb2YgdGhpcyBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIGNoYXJbXSB0b0NoYXJBcnJheSgpIHsKKyAgICAgICAgY2hhcltdIGJ1ZmZlciA9IG5ldyBjaGFyW2NvdW50XTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weSh2YWx1ZSwgb2Zmc2V0LCBidWZmZXIsIDAsIGNvdW50KTsKKyAgICAgICAgcmV0dXJuIGJ1ZmZlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGlzIHN0cmluZyB0byBsb3dlciBjYXNlLCB1c2luZyB0aGUgcnVsZXMgb2YgdGhlIHVzZXIncyBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKiBTZWUgIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgbmV3IGxvd2VyIGNhc2Ugc3RyaW5nLCBvciB7QGNvZGUgdGhpc30gaWYgaXQncyBhbHJlYWR5IGFsbCBsb3dlciBjYXNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9Mb3dlckNhc2UoKSB7CisgICAgICAgIHJldHVybiBDYXNlTWFwcGVyLnRvTG93ZXJDYXNlKExvY2FsZS5nZXREZWZhdWx0KCksIHRoaXMsIHZhbHVlLCBvZmZzZXQsIGNvdW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGlzIHN0cmluZyB0byBsb3dlciBjYXNlLCB1c2luZyB0aGUgcnVsZXMgb2Yge0Bjb2RlIGxvY2FsZX0uCisgICAgICoKKyAgICAgKiA8cD5Nb3N0IGNhc2UgbWFwcGluZ3MgYXJlIHVuYWZmZWN0ZWQgYnkgdGhlIGxhbmd1YWdlIG9mIGEge0Bjb2RlIExvY2FsZX0uIEV4Y2VwdGlvbnMgaW5jbHVkZQorICAgICAqIGRvdHRlZCBhbmQgZG90bGVzcyBJIGluIEF6ZXJpIGFuZCBUdXJraXNoIGxvY2FsZXMsIGFuZCBkb3R0ZWQgYW5kIGRvdGxlc3MgSSBhbmQgSiBpbgorICAgICAqIExpdGh1YW5pYW4gbG9jYWxlcy4gT24gdGhlIG90aGVyIGhhbmQsIGl0IGlzbid0IG5lY2Vzc2FyeSB0byBwcm92aWRlIGEgR3JlZWsgbG9jYWxlIHRvIGdldAorICAgICAqIGNvcnJlY3QgY2FzZSBtYXBwaW5nIG9mIEdyZWVrIGNoYXJhY3RlcnM6IGFueSBsb2NhbGUgd2lsbCBkby4KKyAgICAgKgorICAgICAqIDxwPlNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnVuaWNvZGUub3JnL1B1YmxpYy9VTklEQVRBL1NwZWNpYWxDYXNpbmcudHh0Ij5odHRwOi8vd3d3LnVuaWNvZGUub3JnL1B1YmxpYy9VTklEQVRBL1NwZWNpYWxDYXNpbmcudHh0PC9hPgorICAgICAqIGZvciBmdWxsIGRldGFpbHMgb2YgY29udGV4dC0gYW5kIGxhbmd1YWdlLXNwZWNpZmljIHNwZWNpYWwgY2FzZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgbmV3IGxvd2VyIGNhc2Ugc3RyaW5nLCBvciB7QGNvZGUgdGhpc30gaWYgaXQncyBhbHJlYWR5IGFsbCBsb3dlciBjYXNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9Mb3dlckNhc2UoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICByZXR1cm4gQ2FzZU1hcHBlci50b0xvd2VyQ2FzZShsb2NhbGUsIHRoaXMsIHZhbHVlLCBvZmZzZXQsIGNvdW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgc3RyaW5nLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIHRoaXMgdGhpcyBzdHJpbmcgdG8gdXBwZXIgY2FzZSwgdXNpbmcgdGhlIHJ1bGVzIG9mIHRoZSB1c2VyJ3MgZGVmYXVsdCBsb2NhbGUuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqCisgICAgICogQHJldHVybiBhIG5ldyB1cHBlciBjYXNlIHN0cmluZywgb3Ige0Bjb2RlIHRoaXN9IGlmIGl0J3MgYWxyZWFkeSBhbGwgdXBwZXIgY2FzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvVXBwZXJDYXNlKCkgeworICAgICAgICByZXR1cm4gQ2FzZU1hcHBlci50b1VwcGVyQ2FzZShMb2NhbGUuZ2V0RGVmYXVsdCgpLCB0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBjb3VudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhpcyB0aGlzIHN0cmluZyB0byB1cHBlciBjYXNlLCB1c2luZyB0aGUgcnVsZXMgb2Yge0Bjb2RlIGxvY2FsZX0uCisgICAgICoKKyAgICAgKiA8cD5Nb3N0IGNhc2UgbWFwcGluZ3MgYXJlIHVuYWZmZWN0ZWQgYnkgdGhlIGxhbmd1YWdlIG9mIGEge0Bjb2RlIExvY2FsZX0uIEV4Y2VwdGlvbnMgaW5jbHVkZQorICAgICAqIGRvdHRlZCBhbmQgZG90bGVzcyBJIGluIEF6ZXJpIGFuZCBUdXJraXNoIGxvY2FsZXMsIGFuZCBkb3R0ZWQgYW5kIGRvdGxlc3MgSSBhbmQgSiBpbgorICAgICAqIExpdGh1YW5pYW4gbG9jYWxlcy4gT24gdGhlIG90aGVyIGhhbmQsIGl0IGlzbid0IG5lY2Vzc2FyeSB0byBwcm92aWRlIGEgR3JlZWsgbG9jYWxlIHRvIGdldAorICAgICAqIGNvcnJlY3QgY2FzZSBtYXBwaW5nIG9mIEdyZWVrIGNoYXJhY3RlcnM6IGFueSBsb2NhbGUgd2lsbCBkby4KKyAgICAgKgorICAgICAqIDxwPlNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnVuaWNvZGUub3JnL1B1YmxpYy9VTklEQVRBL1NwZWNpYWxDYXNpbmcudHh0Ij5odHRwOi8vd3d3LnVuaWNvZGUub3JnL1B1YmxpYy9VTklEQVRBL1NwZWNpYWxDYXNpbmcudHh0PC9hPgorICAgICAqIGZvciBmdWxsIGRldGFpbHMgb2YgY29udGV4dC0gYW5kIGxhbmd1YWdlLXNwZWNpZmljIHNwZWNpYWwgY2FzZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgbmV3IHVwcGVyIGNhc2Ugc3RyaW5nLCBvciB7QGNvZGUgdGhpc30gaWYgaXQncyBhbHJlYWR5IGFsbCB1cHBlciBjYXNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9VcHBlckNhc2UoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICByZXR1cm4gQ2FzZU1hcHBlci50b1VwcGVyQ2FzZShsb2NhbGUsIHRoaXMsIHZhbHVlLCBvZmZzZXQsIGNvdW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgdGhpcyBzdHJpbmcgcmVtb3Zpbmcgd2hpdGUgc3BhY2UgY2hhcmFjdGVycyBmcm9tIHRoZSBiZWdpbm5pbmcgYW5kCisgICAgICogZW5kIG9mIHRoZSBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgbmV3IHN0cmluZyB3aXRoIGNoYXJhY3RlcnMgPGNvZGU+PD0gXFx1MDAyMDwvY29kZT4gcmVtb3ZlZCBmcm9tCisgICAgICogICAgICAgICB0aGUgYmVnaW5uaW5nIGFuZCB0aGUgZW5kLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdHJpbSgpIHsKKyAgICAgICAgaW50IHN0YXJ0ID0gb2Zmc2V0LCBsYXN0ID0gb2Zmc2V0ICsgY291bnQgLSAxOworICAgICAgICBpbnQgZW5kID0gbGFzdDsKKyAgICAgICAgd2hpbGUgKChzdGFydCA8PSBlbmQpICYmICh2YWx1ZVtzdGFydF0gPD0gJyAnKSkgeworICAgICAgICAgICAgc3RhcnQrKzsKKyAgICAgICAgfQorICAgICAgICB3aGlsZSAoKGVuZCA+PSBzdGFydCkgJiYgKHZhbHVlW2VuZF0gPD0gJyAnKSkgeworICAgICAgICAgICAgZW5kLS07CisgICAgICAgIH0KKyAgICAgICAgaWYgKHN0YXJ0ID09IG9mZnNldCAmJiBlbmQgPT0gbGFzdCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoc3RhcnQsIGVuZCAtIHN0YXJ0ICsgMSwgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIKKyAgICAgKiBhcnJheS4gTW9kaWZ5aW5nIHRoZSBjaGFyYWN0ZXIgYXJyYXkgYWZ0ZXIgY3JlYXRpbmcgdGhlIHN0cmluZyBoYXMgbm8KKyAgICAgKiBlZmZlY3Qgb24gdGhlIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgY2hhcmFjdGVycy4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgc3RyaW5nLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGF0YX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHZhbHVlT2YoY2hhcltdIGRhdGEpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoZGF0YSwgMCwgZGF0YS5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXJzIGluIHRoZSBjaGFyYWN0ZXIKKyAgICAgKiBhcnJheS4gTW9kaWZ5aW5nIHRoZSBjaGFyYWN0ZXIgYXJyYXkgYWZ0ZXIgY3JlYXRpbmcgdGhlIHN0cmluZyBoYXMgbm8KKyAgICAgKiBlZmZlY3Qgb24gdGhlIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgY2hhcmFjdGVycy4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydGluZyBvZmZzZXQgaW4gdGhlIGNoYXJhY3RlciBhcnJheS4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlLgorICAgICAqIEByZXR1cm4gdGhlIG5ldyBzdHJpbmcuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGxlbmd0aCA8IDB9LCB7QGNvZGUgc3RhcnQgPCAwfSBvciB7QGNvZGUgc3RhcnQgKworICAgICAqICAgICAgICAgICAgIGxlbmd0aCA+IGRhdGEubGVuZ3RofQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGF0YX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHZhbHVlT2YoY2hhcltdIGRhdGEsIGludCBzdGFydCwgaW50IGxlbmd0aCkgeworICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhkYXRhLCBzdGFydCwgbGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciB0byBpdHMgc3RyaW5nIHJlcHJlc2VudGF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyLgorICAgICAqIEByZXR1cm4gdGhlIGNoYXJhY3RlciBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdmFsdWVPZihjaGFyIHZhbHVlKSB7CisgICAgICAgIFN0cmluZyBzOworICAgICAgICBpZiAodmFsdWUgPCAxMjgpIHsKKyAgICAgICAgICAgIHMgPSBuZXcgU3RyaW5nKHZhbHVlLCAxLCBBU0NJSSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzID0gbmV3IFN0cmluZygwLCAxLCBuZXcgY2hhcltdIHsgdmFsdWUgfSk7CisgICAgICAgIH0KKyAgICAgICAgcy5oYXNoQ29kZSA9IHZhbHVlOworICAgICAgICByZXR1cm4gczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIGRvdWJsZSB0byBpdHMgc3RyaW5nIHJlcHJlc2VudGF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgZG91YmxlLgorICAgICAqIEByZXR1cm4gdGhlIGRvdWJsZSBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdmFsdWVPZihkb3VibGUgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIERvdWJsZS50b1N0cmluZyh2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhlIHNwZWNpZmllZCBmbG9hdCB0byBpdHMgc3RyaW5nIHJlcHJlc2VudGF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgZmxvYXQuCisgICAgICogQHJldHVybiB0aGUgZmxvYXQgY29udmVydGVkIHRvIGEgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHZhbHVlT2YoZmxvYXQgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIEZsb2F0LnRvU3RyaW5nKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIGludGVnZXIgdG8gaXRzIHN0cmluZyByZXByZXNlbnRhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIuCisgICAgICogQHJldHVybiB0aGUgaW50ZWdlciBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdmFsdWVPZihpbnQgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIEludGVnZXIudG9TdHJpbmcodmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIHRoZSBzcGVjaWZpZWQgbG9uZyB0byBpdHMgc3RyaW5nIHJlcHJlc2VudGF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbG9uZy4KKyAgICAgKiBAcmV0dXJuIHRoZSBsb25nIGNvbnZlcnRlZCB0byBhIHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB2YWx1ZU9mKGxvbmcgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIExvbmcudG9TdHJpbmcodmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHRvIGl0cyBzdHJpbmcgcmVwcmVzZW50YXRpb24uIElmIHRoZSBvYmplY3QKKyAgICAgKiBpcyBudWxsIHJldHVybiB0aGUgc3RyaW5nIHtAY29kZSAibnVsbCJ9LCBvdGhlcndpc2UgdXNlIHtAY29kZQorICAgICAqIHRvU3RyaW5nKCl9IHRvIGdldCB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0LgorICAgICAqIEByZXR1cm4gdGhlIG9iamVjdCBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcsIG9yIHRoZSBzdHJpbmcge0Bjb2RlICJudWxsIn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdmFsdWVPZihPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlICE9IG51bGwgPyB2YWx1ZS50b1N0cmluZygpIDogIm51bGwiOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIHRoZSBzcGVjaWZpZWQgYm9vbGVhbiB0byBpdHMgc3RyaW5nIHJlcHJlc2VudGF0aW9uLiBXaGVuIHRoZQorICAgICAqIGJvb2xlYW4gaXMge0Bjb2RlIHRydWV9IHJldHVybiB7QGNvZGUgInRydWUifSwgb3RoZXJ3aXNlIHJldHVybiB7QGNvZGUKKyAgICAgKiAiZmFsc2UifS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGJvb2xlYW4uCisgICAgICogQHJldHVybiB0aGUgYm9vbGVhbiBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdmFsdWVPZihib29sZWFuIHZhbHVlKSB7CisgICAgICAgIHJldHVybiB2YWx1ZSA/ICJ0cnVlIiA6ICJmYWxzZSI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBTdHJpbmdCdWZmZXIge0Bjb2RlIHN0cmJ1Zn0gYXJlIHRoZQorICAgICAqIHNhbWUgYXMgdGhvc2UgaW4gdGhpcyBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyYnVmCisgICAgICogICAgICAgICAgICB0aGUgU3RyaW5nQnVmZmVyIHRvIGNvbXBhcmUgdGhpcyBzdHJpbmcgdG8uCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGNoYXJhY3RlcnMgaW4ge0Bjb2RlIHN0cmJ1Zn0gYXJlIGlkZW50aWNhbCB0bworICAgICAqICAgICAgICAgdGhvc2UgaW4gdGhpcyBzdHJpbmcuIElmIHRoZXkgYXJlIG5vdCwge0Bjb2RlIGZhbHNlfSB3aWxsIGJlCisgICAgICogICAgICAgICByZXR1cm5lZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0cmJ1Zn0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250ZW50RXF1YWxzKFN0cmluZ0J1ZmZlciBzdHJidWYpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChzdHJidWYpIHsKKyAgICAgICAgICAgIGludCBzaXplID0gc3RyYnVmLmxlbmd0aCgpOworICAgICAgICAgICAgaWYgKGNvdW50ICE9IHNpemUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVnaW9uTWF0Y2hlcygwLCBuZXcgU3RyaW5nKDAsIHNpemUsIHN0cmJ1Zi5nZXRWYWx1ZSgpKSwgMCwKKyAgICAgICAgICAgICAgICAgICAgc2l6ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyBhIHtAY29kZSBDaGFyU2VxdWVuY2V9IHRvIHRoaXMge0Bjb2RlIFN0cmluZ30gdG8gZGV0ZXJtaW5lIGlmCisgICAgICogdGhlaXIgY29udGVudHMgYXJlIGVxdWFsLgorICAgICAqCisgICAgICogQHBhcmFtIGNzCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHRvIGNvbXBhcmUgdG8uCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgZXF1YWwsIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9CisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRlbnRFcXVhbHMoQ2hhclNlcXVlbmNlIGNzKSB7CisgICAgICAgIGlmIChjcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBsZW4gPSBjcy5sZW5ndGgoKTsKKworICAgICAgICBpZiAobGVuICE9IGNvdW50KSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBpZiAobGVuID09IDAgJiYgY291bnQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7IC8vIHNpbmNlIGJvdGggYXJlIGVtcHR5IHN0cmluZ3MKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZWdpb25NYXRjaGVzKDAsIGNzLnRvU3RyaW5nKCksIDAsIGxlbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgd2hldGhlciB0aGlzIHN0cmluZyBtYXRjaGVzIHRoZSBnaXZlbiB7QGNvZGUgcmVndWxhckV4cHJlc3Npb259LiBUaGlzIG1ldGhvZCByZXR1cm5zCisgICAgICogdHJ1ZSBvbmx5IGlmIHRoZSByZWd1bGFyIGV4cHJlc3Npb24gbWF0Y2hlcyB0aGUgPGk+ZW50aXJlPC9pPiBpbnB1dCBzdHJpbmcuIEEgY29tbW9uIG1pc3Rha2UgaXMKKyAgICAgKiB0byBhc3N1bWUgdGhhdCB0aGlzIG1ldGhvZCBiZWhhdmVzIGxpa2Uge0BsaW5rICNjb250YWluc307IGlmIHlvdSB3YW50IHRvIG1hdGNoIGFueXdoZXJlCisgICAgICogd2l0aGluIHRoZSBpbnB1dCBzdHJpbmcsIHlvdSBuZWVkIHRvIGFkZCB7QGNvZGUgLip9IHRvIHRoZSBiZWdpbm5pbmcgYW5kIGVuZCBvZiB5b3VyCisgICAgICogcmVndWxhciBleHByZXNzaW9uLiBTZWUge0BsaW5rIFBhdHRlcm4jbWF0Y2hlc30uCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgc2FtZSByZWd1bGFyIGV4cHJlc3Npb24gaXMgdG8gYmUgdXNlZCBmb3IgbXVsdGlwbGUgb3BlcmF0aW9ucywgaXQgbWF5IGJlIG1vcmUKKyAgICAgKiBlZmZpY2llbnQgdG8gcmV1c2UgYSBjb21waWxlZCB7QGNvZGUgUGF0dGVybn0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFBhdHRlcm5TeW50YXhFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3ludGF4IG9mIHRoZSBzdXBwbGllZCByZWd1bGFyIGV4cHJlc3Npb24gaXMgbm90CisgICAgICogICAgICAgICAgICAgdmFsaWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgcmVndWxhckV4cHJlc3Npb24gPT0gbnVsbH0KKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbWF0Y2hlcyhTdHJpbmcgcmVndWxhckV4cHJlc3Npb24pIHsKKyAgICAgICAgcmV0dXJuIFBhdHRlcm4ubWF0Y2hlcyhyZWd1bGFyRXhwcmVzc2lvbiwgdGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwbGFjZXMgYWxsIG1hdGNoZXMgZm9yIHtAY29kZSByZWd1bGFyRXhwcmVzc2lvbn0gd2l0aGluIHRoaXMgc3RyaW5nIHdpdGggdGhlIGdpdmVuCisgICAgICoge0Bjb2RlIHJlcGxhY2VtZW50fS4KKyAgICAgKiBTZWUge0BsaW5rIFBhdHRlcm59IGZvciByZWd1bGFyIGV4cHJlc3Npb24gc3ludGF4LgorICAgICAqCisgICAgICogPHA+SWYgdGhlIHNhbWUgcmVndWxhciBleHByZXNzaW9uIGlzIHRvIGJlIHVzZWQgZm9yIG11bHRpcGxlIG9wZXJhdGlvbnMsIGl0IG1heSBiZSBtb3JlCisgICAgICogZWZmaWNpZW50IHRvIHJldXNlIGEgY29tcGlsZWQge0Bjb2RlIFBhdHRlcm59LgorICAgICAqCisgICAgICogQHRocm93cyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHN5bnRheCBvZiB0aGUgc3VwcGxpZWQgcmVndWxhciBleHByZXNzaW9uIGlzIG5vdAorICAgICAqICAgICAgICAgICAgIHZhbGlkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIHJlZ3VsYXJFeHByZXNzaW9uID09IG51bGx9CisgICAgICogQHNlZSBQYXR0ZXJuCisgICAgICogQHNpbmNlIDEuNAorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgcmVwbGFjZUFsbChTdHJpbmcgcmVndWxhckV4cHJlc3Npb24sIFN0cmluZyByZXBsYWNlbWVudCkgeworICAgICAgICByZXR1cm4gUGF0dGVybi5jb21waWxlKHJlZ3VsYXJFeHByZXNzaW9uKS5tYXRjaGVyKHRoaXMpLnJlcGxhY2VBbGwocmVwbGFjZW1lbnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2VzIHRoZSBmaXJzdCBtYXRjaCBmb3Ige0Bjb2RlIHJlZ3VsYXJFeHByZXNzaW9ufSB3aXRoaW4gdGhpcyBzdHJpbmcgd2l0aCB0aGUgZ2l2ZW4KKyAgICAgKiB7QGNvZGUgcmVwbGFjZW1lbnR9LgorICAgICAqIFNlZSB7QGxpbmsgUGF0dGVybn0gZm9yIHJlZ3VsYXIgZXhwcmVzc2lvbiBzeW50YXguCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgc2FtZSByZWd1bGFyIGV4cHJlc3Npb24gaXMgdG8gYmUgdXNlZCBmb3IgbXVsdGlwbGUgb3BlcmF0aW9ucywgaXQgbWF5IGJlIG1vcmUKKyAgICAgKiBlZmZpY2llbnQgdG8gcmV1c2UgYSBjb21waWxlZCB7QGNvZGUgUGF0dGVybn0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFBhdHRlcm5TeW50YXhFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3ludGF4IG9mIHRoZSBzdXBwbGllZCByZWd1bGFyIGV4cHJlc3Npb24gaXMgbm90CisgICAgICogICAgICAgICAgICAgdmFsaWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgcmVndWxhckV4cHJlc3Npb24gPT0gbnVsbH0KKyAgICAgKiBAc2VlIFBhdHRlcm4KKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIFN0cmluZyByZXBsYWNlRmlyc3QoU3RyaW5nIHJlZ3VsYXJFeHByZXNzaW9uLCBTdHJpbmcgcmVwbGFjZW1lbnQpIHsKKyAgICAgICAgcmV0dXJuIFBhdHRlcm4uY29tcGlsZShyZWd1bGFyRXhwcmVzc2lvbikubWF0Y2hlcih0aGlzKS5yZXBsYWNlRmlyc3QocmVwbGFjZW1lbnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNwbGl0cyB0aGlzIHN0cmluZyB1c2luZyB0aGUgc3VwcGxpZWQge0Bjb2RlIHJlZ3VsYXJFeHByZXNzaW9ufS4KKyAgICAgKiBFcXVpdmFsZW50IHRvIHtAY29kZSBzcGxpdChyZWd1bGFyRXhwcmVzc2lvbiwgMCl9LgorICAgICAqIFNlZSB7QGxpbmsgUGF0dGVybiNzcGxpdChDaGFyU2VxdWVuY2UsIGludCl9IGZvciBhbiBleHBsYW5hdGlvbiBvZiB7QGNvZGUgbGltaXR9LgorICAgICAqIFNlZSB7QGxpbmsgUGF0dGVybn0gZm9yIHJlZ3VsYXIgZXhwcmVzc2lvbiBzeW50YXguCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgc2FtZSByZWd1bGFyIGV4cHJlc3Npb24gaXMgdG8gYmUgdXNlZCBmb3IgbXVsdGlwbGUgb3BlcmF0aW9ucywgaXQgbWF5IGJlIG1vcmUKKyAgICAgKiBlZmZpY2llbnQgdG8gcmV1c2UgYSBjb21waWxlZCB7QGNvZGUgUGF0dGVybn0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSByZWd1bGFyRXhwcmVzc2lvbiA9PSAgbnVsbH0KKyAgICAgKiBAdGhyb3dzIFBhdHRlcm5TeW50YXhFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3ludGF4IG9mIHRoZSBzdXBwbGllZCByZWd1bGFyIGV4cHJlc3Npb24gaXMgbm90CisgICAgICogICAgICAgICAgICAgdmFsaWQuCisgICAgICogQHNlZSBQYXR0ZXJuCisgICAgICogQHNpbmNlIDEuNAorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBzcGxpdChTdHJpbmcgcmVndWxhckV4cHJlc3Npb24pIHsKKyAgICAgICAgcmV0dXJuIHNwbGl0KHJlZ3VsYXJFeHByZXNzaW9uLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGxpdHMgdGhpcyBzdHJpbmcgdXNpbmcgdGhlIHN1cHBsaWVkIHtAY29kZSByZWd1bGFyRXhwcmVzc2lvbn0uCisgICAgICogU2VlIHtAbGluayBQYXR0ZXJuI3NwbGl0KENoYXJTZXF1ZW5jZSwgaW50KX0gZm9yIGFuIGV4cGxhbmF0aW9uIG9mIHtAY29kZSBsaW1pdH0uCisgICAgICogU2VlIHtAbGluayBQYXR0ZXJufSBmb3IgcmVndWxhciBleHByZXNzaW9uIHN5bnRheC4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBzYW1lIHJlZ3VsYXIgZXhwcmVzc2lvbiBpcyB0byBiZSB1c2VkIGZvciBtdWx0aXBsZSBvcGVyYXRpb25zLCBpdCBtYXkgYmUgbW9yZQorICAgICAqIGVmZmljaWVudCB0byByZXVzZSBhIGNvbXBpbGVkIHtAY29kZSBQYXR0ZXJufS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIHJlZ3VsYXJFeHByZXNzaW9uID09ICBudWxsfQorICAgICAqIEB0aHJvd3MgUGF0dGVyblN5bnRheEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzeW50YXggb2YgdGhlIHN1cHBsaWVkIHJlZ3VsYXIgZXhwcmVzc2lvbiBpcyBub3QKKyAgICAgKiAgICAgICAgICAgICB2YWxpZC4KKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIHNwbGl0KFN0cmluZyByZWd1bGFyRXhwcmVzc2lvbiwgaW50IGxpbWl0KSB7CisgICAgICAgIFN0cmluZ1tdIHJlc3VsdCA9IGphdmEudXRpbC5yZWdleC5TcGxpdHRlci5mYXN0U3BsaXQocmVndWxhckV4cHJlc3Npb24sIHRoaXMsIGxpbWl0KTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdCAhPSBudWxsID8gcmVzdWx0IDogUGF0dGVybi5jb21waWxlKHJlZ3VsYXJFeHByZXNzaW9uKS5zcGxpdCh0aGlzLCBsaW1pdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSGFzIHRoZSBzYW1lIHJlc3VsdCBhcyB0aGUgc3Vic3RyaW5nIGZ1bmN0aW9uLCBidXQgaXMgcHJlc2VudCBzbyB0aGF0CisgICAgICogc3RyaW5nIG1heSBpbXBsZW1lbnQgdGhlIENoYXJTZXF1ZW5jZSBpbnRlcmZhY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgdGhlIGZpcnN0IGNoYXJhY3Rlci4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIG9uZSBwYXN0IHRoZSBsYXN0IGNoYXJhY3RlciB0byBpbmNsdWRlLgorICAgICAqIEByZXR1cm4gdGhlIHN1YnNlcXVlbmNlIHJlcXVlc3RlZC4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwfSwge0Bjb2RlIGVuZCA8IDB9LCB7QGNvZGUgc3RhcnQgPiBlbmR9IG9yCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGVuZCA+IGxlbmd0aCgpfS4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5DaGFyU2VxdWVuY2Ujc3ViU2VxdWVuY2UoaW50LCBpbnQpCisgICAgICogQHNpbmNlIDEuNAorICAgICAqLworICAgIHB1YmxpYyBDaGFyU2VxdWVuY2Ugc3ViU2VxdWVuY2UoaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIHJldHVybiBzdWJzdHJpbmcoc3RhcnQsIGVuZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgVW5pY29kZSBjb2RlIHBvaW50IGF0IHRoZSBnaXZlbiB7QGNvZGUgaW5kZXh9LgorICAgICAqCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHtAY29kZSBpbmRleCA8IDAgfHwgaW5kZXggPj0gbGVuZ3RoKCl9CisgICAgICogQHNlZSBDaGFyYWN0ZXIjY29kZVBvaW50QXQoY2hhcltdLCBpbnQsIGludCkKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIGludCBjb2RlUG9pbnRBdChpbnQgaW5kZXgpIHsKKyAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBjb3VudCkgeworICAgICAgICAgICAgdGhyb3cgaW5kZXhBbmRMZW5ndGgoaW5kZXgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBDaGFyYWN0ZXIuY29kZVBvaW50QXQodmFsdWUsIG9mZnNldCArIGluZGV4LCBvZmZzZXQgKyBjb3VudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgVW5pY29kZSBjb2RlIHBvaW50IHRoYXQgcHJlY2VkZXMgdGhlIGdpdmVuIHtAY29kZSBpbmRleH0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYge0Bjb2RlIGluZGV4IDwgMSB8fCBpbmRleCA+IGxlbmd0aCgpfQorICAgICAqIEBzZWUgQ2hhcmFjdGVyI2NvZGVQb2ludEJlZm9yZShjaGFyW10sIGludCwgaW50KQorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvZGVQb2ludEJlZm9yZShpbnQgaW5kZXgpIHsKKyAgICAgICAgaWYgKGluZGV4IDwgMSB8fCBpbmRleCA+IGNvdW50KSB7CisgICAgICAgICAgICB0aHJvdyBpbmRleEFuZExlbmd0aChpbmRleCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIENoYXJhY3Rlci5jb2RlUG9pbnRCZWZvcmUodmFsdWUsIG9mZnNldCArIGluZGV4LCBvZmZzZXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGN1bGF0ZXMgdGhlIG51bWJlciBvZiBVbmljb2RlIGNvZGUgcG9pbnRzIGJldHdlZW4ge0Bjb2RlIHN0YXJ0fQorICAgICAqIGFuZCB7QGNvZGUgZW5kfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIGluY2x1c2l2ZSBiZWdpbm5pbmcgaW5kZXggb2YgdGhlIHN1YnNlcXVlbmNlLgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNsdXNpdmUgZW5kIGluZGV4IG9mIHRoZSBzdWJzZXF1ZW5jZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgVW5pY29kZSBjb2RlIHBvaW50cyBpbiB0aGUgc3Vic2VxdWVuY2UuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwIHx8IGVuZCA+IGxlbmd0aCgpIHx8IHN0YXJ0ID4gZW5kfQorICAgICAqIEBzZWUgQ2hhcmFjdGVyI2NvZGVQb2ludENvdW50KENoYXJTZXF1ZW5jZSwgaW50LCBpbnQpCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29kZVBvaW50Q291bnQoaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIGlmIChzdGFydCA8IDAgfHwgZW5kID4gY291bnQgfHwgc3RhcnQgPiBlbmQpIHsKKyAgICAgICAgICAgIHRocm93IHN0YXJ0RW5kQW5kTGVuZ3RoKHN0YXJ0LCBlbmQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBDaGFyYWN0ZXIuY29kZVBvaW50Q291bnQodmFsdWUsIG9mZnNldCArIHN0YXJ0LCBlbmQgLSBzdGFydCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyBpZiB0aGlzIHtAY29kZSBTdHJpbmd9IGNvbnRhaW5zIHRoZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIGluCisgICAgICogdGhlIHtAY29kZSBDaGFyU2VxdWVuY2V9IHBhc3NlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjcworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSB0byBzZWFyY2ggZm9yLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIGFyZSBjb250YWluZWQgaW4gdGhpcworICAgICAqICAgICAgICAgc3RyaW5nLCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoQ2hhclNlcXVlbmNlIGNzKSB7CisgICAgICAgIGlmIChjcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW5kZXhPZihjcy50b1N0cmluZygpKSA+PSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGlzIG9iamVjdCB0aGF0IGlzIG9mZnNldCBmcm9tIHtAY29kZSBpbmRleH0gYnkKKyAgICAgKiB7QGNvZGUgY29kZVBvaW50T2Zmc2V0fSBjb2RlIHBvaW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHdpdGhpbiB0aGlzIG9iamVjdCB0byBjYWxjdWxhdGUgdGhlIG9mZnNldCBmcm9tLgorICAgICAqIEBwYXJhbSBjb2RlUG9pbnRPZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgY29kZSBwb2ludHMgdG8gY291bnQuCisgICAgICogQHJldHVybiB0aGUgaW5kZXggd2l0aGluIHRoaXMgb2JqZWN0IHRoYXQgaXMgdGhlIG9mZnNldC4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW5kZXh9IGlzIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiB7QGNvZGUgbGVuZ3RoKCl9CisgICAgICogICAgICAgICAgICAgb3IgaWYgdGhlcmUgYXJlbid0IGVub3VnaCBjb2RlIHBvaW50cyBiZWZvcmUgb3IgYWZ0ZXIge0Bjb2RlCisgICAgICogICAgICAgICAgICAgaW5kZXh9IHRvIG1hdGNoIHtAY29kZSBjb2RlUG9pbnRPZmZzZXR9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IG9mZnNldEJ5Q29kZVBvaW50cyhpbnQgaW5kZXgsIGludCBjb2RlUG9pbnRPZmZzZXQpIHsKKyAgICAgICAgaW50IHMgPSBpbmRleCArIG9mZnNldDsKKyAgICAgICAgaW50IHIgPSBDaGFyYWN0ZXIub2Zmc2V0QnlDb2RlUG9pbnRzKHZhbHVlLCBvZmZzZXQsIGNvdW50LCBzLCBjb2RlUG9pbnRPZmZzZXQpOworICAgICAgICByZXR1cm4gciAtIG9mZnNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbG9jYWxpemVkIGZvcm1hdHRlZCBzdHJpbmcsIHVzaW5nIHRoZSBzdXBwbGllZCBmb3JtYXQgYW5kIGFyZ3VtZW50cywKKyAgICAgKiB1c2luZyB0aGUgdXNlcidzIGRlZmF1bHQgbG9jYWxlLgorICAgICAqCisgICAgICogPHA+SWYgeW91J3JlIGZvcm1hdHRpbmcgYSBzdHJpbmcgb3RoZXIgdGhhbiBmb3IgaHVtYW4KKyAgICAgKiBjb25zdW1wdGlvbiwgeW91IHNob3VsZCB1c2UgdGhlIHtAY29kZSBmb3JtYXQoTG9jYWxlLCBTdHJpbmcsIE9iamVjdC4uLil9CisgICAgICogb3ZlcmxvYWQgYW5kIHN1cHBseSB7QGNvZGUgTG9jYWxlLlVTfS4gU2VlCisgICAgICogIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9ybWF0IHRoZSBmb3JtYXQgc3RyaW5nIChzZWUge0BsaW5rIGphdmEudXRpbC5Gb3JtYXR0ZXIjZm9ybWF0fSkKKyAgICAgKiBAcGFyYW0gYXJncworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgZm9ybWF0dGVyLiBJZiB0aGVyZSBhcmUKKyAgICAgKiAgICAgICAgICAgIG1vcmUgYXJndW1lbnRzIHRoYW4gcmVxdWlyZWQgYnkge0Bjb2RlIGZvcm1hdH0sCisgICAgICogICAgICAgICAgICBhZGRpdGlvbmFsIGFyZ3VtZW50cyBhcmUgaWdub3JlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBmb3JtYXR0ZWQgc3RyaW5nLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIGZvcm1hdCA9PSBudWxsfQorICAgICAqIEB0aHJvd3MgamF2YS51dGlsLklsbGVnYWxGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZm9ybWF0IGlzIGludmFsaWQuCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGZvcm1hdChTdHJpbmcgZm9ybWF0LCBPYmplY3QuLi4gYXJncykgeworICAgICAgICByZXR1cm4gZm9ybWF0KExvY2FsZS5nZXREZWZhdWx0KCksIGZvcm1hdCwgYXJncyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGZvcm1hdHRlZCBzdHJpbmcsIHVzaW5nIHRoZSBzdXBwbGllZCBmb3JtYXQgYW5kIGFyZ3VtZW50cywKKyAgICAgKiBsb2NhbGl6ZWQgdG8gdGhlIGdpdmVuIGxvY2FsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhbGUgdG8gYXBwbHk7IHtAY29kZSBudWxsfSB2YWx1ZSBtZWFucyBubyBsb2NhbGl6YXRpb24uCisgICAgICogQHBhcmFtIGZvcm1hdCB0aGUgZm9ybWF0IHN0cmluZyAoc2VlIHtAbGluayBqYXZhLnV0aWwuRm9ybWF0dGVyI2Zvcm1hdH0pCisgICAgICogQHBhcmFtIGFyZ3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IG9mIGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhlIGZvcm1hdHRlci4gSWYgdGhlcmUgYXJlCisgICAgICogICAgICAgICAgICBtb3JlIGFyZ3VtZW50cyB0aGFuIHJlcXVpcmVkIGJ5IHtAY29kZSBmb3JtYXR9LAorICAgICAqICAgICAgICAgICAgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIGlnbm9yZWQuCisgICAgICogQHJldHVybiB0aGUgZm9ybWF0dGVkIHN0cmluZy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBmb3JtYXQgPT0gbnVsbH0KKyAgICAgKiBAdGhyb3dzIGphdmEudXRpbC5JbGxlZ2FsRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGZvcm1hdCBpcyBpbnZhbGlkLgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBmb3JtYXQoTG9jYWxlIGxvY2FsZSwgU3RyaW5nIGZvcm1hdCwgT2JqZWN0Li4uIGFyZ3MpIHsKKyAgICAgICAgaWYgKGZvcm1hdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm51bGwgZm9ybWF0IGFyZ3VtZW50Iik7CisgICAgICAgIH0KKyAgICAgICAgaW50IGJ1ZmZlclNpemUgPSBmb3JtYXQubGVuZ3RoKCkgKyAoYXJncyA9PSBudWxsID8gMCA6IGFyZ3MubGVuZ3RoICogMTApOworICAgICAgICBGb3JtYXR0ZXIgZiA9IG5ldyBGb3JtYXR0ZXIobmV3IFN0cmluZ0J1aWxkZXIoYnVmZmVyU2l6ZSksIGxvY2FsZSk7CisgICAgICAgIHJldHVybiBmLmZvcm1hdChmb3JtYXQsIGFyZ3MpLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiBhIFN0cmluZy5pbmRleE9mIHRoYXQgaXMgc3VwcG9zZWQgdG8gcGVyZm9ybQorICAgICAqIHN1YnN0YW50aWFsbHkgYmV0dGVyIHRoYW4gdGhlIGRlZmF1bHQgYWxnb3JpdGhtIGlmIHRoZSAibmVlZGxlIiAodGhlCisgICAgICogc3ViU3RyaW5nIGJlaW5nIHNlYXJjaGVkIGZvcikgaXMgYSBjb25zdGFudCBzdHJpbmcuCisgICAgICoKKyAgICAgKiBGb3IgZXhhbXBsZSwgYSBKSVQsIHVwb24gZW5jb3VudGVyaW5nIGEgY2FsbCB0byBTdHJpbmcuaW5kZXhPZihTdHJpbmcpLAorICAgICAqIHdoZXJlIHRoZSBuZWVkbGUgaXMgYSBjb25zdGFudCBzdHJpbmcsIG1heSBjb21wdXRlIHRoZSB2YWx1ZXMgY2FjaGUsIG1kMgorICAgICAqIGFuZCBsYXN0Q2hhciwgYW5kIGNoYW5nZSB0aGUgY2FsbCB0byB0aGUgZm9sbG93aW5nIG1ldGhvZC4KKyAgICAgKi8KKyAgICBARmluZEJ1Z3NTdXBwcmVzc1dhcm5pbmdzKCJVUE1fVU5DQUxMRURfUFJJVkFURV9NRVRIT0QiKQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgIHByaXZhdGUgc3RhdGljIGludCBpbmRleE9mKFN0cmluZyBoYXlzdGFja1N0cmluZywgU3RyaW5nIG5lZWRsZVN0cmluZywKKyAgICAgICAgICAgIGludCBjYWNoZSwgaW50IG1kMiwgY2hhciBsYXN0Q2hhcikgeworICAgICAgICBjaGFyW10gaGF5c3RhY2sgPSBoYXlzdGFja1N0cmluZy52YWx1ZTsKKyAgICAgICAgaW50IGhheXN0YWNrT2Zmc2V0ID0gaGF5c3RhY2tTdHJpbmcub2Zmc2V0OworICAgICAgICBpbnQgaGF5c3RhY2tMZW5ndGggPSBoYXlzdGFja1N0cmluZy5jb3VudDsKKyAgICAgICAgY2hhcltdIG5lZWRsZSA9IG5lZWRsZVN0cmluZy52YWx1ZTsKKyAgICAgICAgaW50IG5lZWRsZU9mZnNldCA9IG5lZWRsZVN0cmluZy5vZmZzZXQ7CisgICAgICAgIGludCBuZWVkbGVMZW5ndGggPSBuZWVkbGVTdHJpbmcuY291bnQ7CisgICAgICAgIGludCBuZWVkbGVMZW5ndGhNaW51czEgPSBuZWVkbGVMZW5ndGggLSAxOworICAgICAgICBpbnQgaGF5c3RhY2tFbmQgPSBoYXlzdGFja09mZnNldCArIGhheXN0YWNrTGVuZ3RoOworICAgICAgICBvdXRlcl9sb29wOiBmb3IgKGludCBpID0gaGF5c3RhY2tPZmZzZXQgKyBuZWVkbGVMZW5ndGhNaW51czE7IGkgPCBoYXlzdGFja0VuZDspIHsKKyAgICAgICAgICAgIGlmIChsYXN0Q2hhciA9PSBoYXlzdGFja1tpXSkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbmVlZGxlTGVuZ3RoTWludXMxOyArK2opIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5lZWRsZVtqICsgbmVlZGxlT2Zmc2V0XSAhPSBoYXlzdGFja1tpICsgagorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gbmVlZGxlTGVuZ3RoTWludXMxXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNraXAgPSAxOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChjYWNoZSAmICgxIDw8IGhheXN0YWNrW2ldKSkgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNraXAgKz0gajsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGkgKz0gTWF0aC5tYXgobWQyLCBza2lwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyX2xvb3A7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGkgLSBuZWVkbGVMZW5ndGhNaW51czEgLSBoYXlzdGFja09mZnNldDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKChjYWNoZSAmICgxIDw8IGhheXN0YWNrW2ldKSkgPT0gMCkgeworICAgICAgICAgICAgICAgIGkgKz0gbmVlZGxlTGVuZ3RoTWludXMxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaSsrOworICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1N0cmluZ0J1ZmZlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TdHJpbmdCdWZmZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNTBiNzIyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TdHJpbmdCdWZmZXIuamF2YQpAQCAtMCwwICsxLDc0NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1GaWVsZDsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworLyoqCisgKiBBIG1vZGlmaWFibGUge0BsaW5rIENoYXJTZXF1ZW5jZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzfSBmb3IgdXNlIGluIGNyZWF0aW5nCisgKiBzdHJpbmdzLCB3aGVyZSBhbGwgYWNjZXNzZXMgYXJlIHN5bmNocm9uaXplZC4gVGhpcyBjbGFzcyBoYXMgbW9zdGx5IGJlZW4gcmVwbGFjZWQKKyAqIGJ5IHtAbGluayBTdHJpbmdCdWlsZGVyfSBiZWNhdXNlIHRoaXMgc3luY2hyb25pemF0aW9uIGlzIHJhcmVseSB1c2VmdWwuIFRoaXMKKyAqIGNsYXNzIGlzIG1haW5seSB1c2VkIHRvIGludGVyYWN0IHdpdGggbGVnYWN5IEFQSXMgdGhhdCBleHBvc2UgaXQuCisgKgorICogPHA+Rm9yIHBhcnRpY3VsYXJseSBjb21wbGV4IHN0cmluZy1idWlsZGluZyBuZWVkcywgY29uc2lkZXIge0BsaW5rIGphdmEudXRpbC5Gb3JtYXR0ZXJ9LgorICoKKyAqIDxwPlRoZSBtYWpvcml0eSBvZiB0aGUgbW9kaWZpY2F0aW9uIG1ldGhvZHMgb24gdGhpcyBjbGFzcyByZXR1cm4ge0Bjb2RlCisgKiB0aGlzfSBzbyB0aGF0IG1ldGhvZCBjYWxscyBjYW4gYmUgY2hhaW5lZCB0b2dldGhlci4gRm9yIGV4YW1wbGU6CisgKiB7QGNvZGUgbmV3IFN0cmluZ0J1ZmZlcigiYSIpLmFwcGVuZCgiYiIpLmFwcGVuZCgiYyIpLnRvU3RyaW5nKCl9LgorICoKKyAqIEBzZWUgQ2hhclNlcXVlbmNlCisgKiBAc2VlIEFwcGVuZGFibGUKKyAqIEBzZWUgU3RyaW5nQnVpbGRlcgorICogQHNlZSBTdHJpbmcKKyAqIEBzZWUgU3RyaW5nI2Zvcm1hdAorICogQHNpbmNlIDEuMAorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU3RyaW5nQnVmZmVyIGV4dGVuZHMgQWJzdHJhY3RTdHJpbmdCdWlsZGVyIGltcGxlbWVudHMKKyAgICAgICAgQXBwZW5kYWJsZSwgU2VyaWFsaXphYmxlLCBDaGFyU2VxdWVuY2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzM4ODY4NTg3NzE0NzkyMTEwN0w7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RTdHJlYW1GaWVsZFtdIHNlcmlhbFBlcnNpc3RlbnRGaWVsZHMgPSB7CisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiY291bnQiLCBpbnQuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInNoYXJlZCIsIGJvb2xlYW4uY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInZhbHVlIiwgY2hhcltdLmNsYXNzKSwKKyAgICB9OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBTdHJpbmdCdWZmZXIgdXNpbmcgdGhlIGRlZmF1bHQgY2FwYWNpdHkgd2hpY2ggaXMgMTYuCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1ZmZlcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFN0cmluZ0J1ZmZlciB1c2luZyB0aGUgc3BlY2lmaWVkIGNhcGFjaXR5LgorICAgICAqCisgICAgICogQHBhcmFtIGNhcGFjaXR5CisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBjYXBhY2l0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVmZmVyKGludCBjYXBhY2l0eSkgeworICAgICAgICBzdXBlcihjYXBhY2l0eSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBTdHJpbmdCdWZmZXIgY29udGFpbmluZyB0aGUgY2hhcmFjdGVycyBpbiB0aGUgc3BlY2lmaWVkCisgICAgICogc3RyaW5nLiBUaGUgY2FwYWNpdHkgb2YgdGhlIG5ldyBidWZmZXIgd2lsbCBiZSB0aGUgbGVuZ3RoIG9mIHRoZQorICAgICAqIHtAY29kZSBTdHJpbmd9IHBsdXMgdGhlIGRlZmF1bHQgY2FwYWNpdHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIGNvbnRlbnQgd2l0aCB3aGljaCB0byBpbml0aWFsaXplIHRoZSBuZXcgaW5zdGFuY2UuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYge0Bjb2RlIHN0cmluZ30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIoU3RyaW5nIHN0cmluZykgeworICAgICAgICBzdXBlcihzdHJpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBTdHJpbmdCdWZmZXIgYW5kIGluaXRpYWxpemVzIGl0IHdpdGggdGhlIGNvbnRlbnQgZnJvbSB0aGUKKyAgICAgKiBzcGVjaWZpZWQge0Bjb2RlIENoYXJTZXF1ZW5jZX0uIFRoZSBjYXBhY2l0eSBvZiB0aGUgbmV3IGJ1ZmZlciB3aWxsIGJlCisgICAgICogdGhlIGxlbmd0aCBvZiB0aGUge0Bjb2RlIENoYXJTZXF1ZW5jZX0gcGx1cyB0aGUgZGVmYXVsdCBjYXBhY2l0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjcworICAgICAqICAgICAgICAgICAgdGhlIGNvbnRlbnQgdG8gaW5pdGlhbGl6ZSB0aGUgaW5zdGFuY2UuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYge0Bjb2RlIGNzfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIoQ2hhclNlcXVlbmNlIGNzKSB7CisgICAgICAgIHN1cGVyKGNzLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIGJvb2xlYW4gdG8gdGhlIGVuZCBvZgorICAgICAqIHRoaXMgU3RyaW5nQnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBhcmd1bWVudCBpcyB7QGNvZGUgdHJ1ZX0gdGhlIHN0cmluZyB7QGNvZGUgInRydWUifSBpcyBhcHBlbmRlZCwKKyAgICAgKiBvdGhlcndpc2UgdGhlIHN0cmluZyB7QGNvZGUgImZhbHNlIn0gaXMgYXBwZW5kZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJvb2xlYW4gdG8gYXBwZW5kLgorICAgICAqIEByZXR1cm4gdGhpcyBTdHJpbmdCdWZmZXIuCisgICAgICogQHNlZSBTdHJpbmcjdmFsdWVPZihib29sZWFuKQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgYXBwZW5kKGJvb2xlYW4gYikgeworICAgICAgICByZXR1cm4gYXBwZW5kKGIgPyAidHJ1ZSIgOiAiZmFsc2UiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIHRvIHRoZSBlbmQgb2YgdGhpcyBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2gKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgdG8gYXBwZW5kLgorICAgICAqIEByZXR1cm4gdGhpcyBTdHJpbmdCdWZmZXIuCisgICAgICogQHNlZSBTdHJpbmcjdmFsdWVPZihjaGFyKQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nQnVmZmVyIGFwcGVuZChjaGFyIGNoKSB7CisgICAgICAgIGFwcGVuZDAoY2gpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCBkb3VibGUgdG8gdGhlIGVuZCBvZiB0aGlzCisgICAgICogU3RyaW5nQnVmZmVyLgorICAgICAqCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb3VibGUgdG8gYXBwZW5kLgorICAgICAqIEByZXR1cm4gdGhpcyBTdHJpbmdCdWZmZXIuCisgICAgICogQHNlZSBTdHJpbmcjdmFsdWVPZihkb3VibGUpCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1ZmZlciBhcHBlbmQoZG91YmxlIGQpIHsKKyAgICAgICAgUmVhbFRvU3RyaW5nLmdldEluc3RhbmNlKCkuYXBwZW5kRG91YmxlKHRoaXMsIGQpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCBmbG9hdCB0byB0aGUgZW5kIG9mIHRoaXMKKyAgICAgKiBTdHJpbmdCdWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZgorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IHRvIGFwcGVuZC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgU3RyaW5nQnVmZmVyLgorICAgICAqIEBzZWUgU3RyaW5nI3ZhbHVlT2YoZmxvYXQpCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1ZmZlciBhcHBlbmQoZmxvYXQgZikgeworICAgICAgICBSZWFsVG9TdHJpbmcuZ2V0SW5zdGFuY2UoKS5hcHBlbmRGbG9hdCh0aGlzLCBmKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQgaW50ZWdlciB0byB0aGUgZW5kIG9mCisgICAgICogdGhpcyBTdHJpbmdCdWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdG8gYXBwZW5kLgorICAgICAqIEByZXR1cm4gdGhpcyBTdHJpbmdCdWZmZXIuCisgICAgICogQHNlZSBTdHJpbmcjdmFsdWVPZihpbnQpCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1ZmZlciBhcHBlbmQoaW50IGkpIHsKKyAgICAgICAgSW50ZWdyYWxUb1N0cmluZy5hcHBlbmRJbnQodGhpcywgaSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIGxvbmcgdG8gdGhlIGVuZCBvZiB0aGlzCisgICAgICogU3RyaW5nQnVmZmVyLgorICAgICAqCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb25nIHRvIGFwcGVuZC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgU3RyaW5nQnVmZmVyLgorICAgICAqIEBzZWUgU3RyaW5nI3ZhbHVlT2YobG9uZykKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGFwcGVuZChsb25nIGwpIHsKKyAgICAgICAgSW50ZWdyYWxUb1N0cmluZy5hcHBlbmRMb25nKHRoaXMsIGwpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCBvYmplY3QgdG8gdGhlIGVuZCBvZiB0aGlzCisgICAgICogU3RyaW5nQnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIHtAY29kZSBudWxsfSB0aGUgc3RyaW5nIHtAY29kZSAibnVsbCJ9IGlzCisgICAgICogYXBwZW5kZWQsIG90aGVyd2lzZSB0aGUgb2JqZWN0cyB7QGNvZGUgdG9TdHJpbmd9IGlzIHVzZWQgdG8gZ2V0IGl0cworICAgICAqIHN0cmluZyByZXByZXNlbnRhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYXBwZW5kIChtYXkgYmUgbnVsbCkuCisgICAgICogQHJldHVybiB0aGlzIFN0cmluZ0J1ZmZlci4KKyAgICAgKiBAc2VlIFN0cmluZyN2YWx1ZU9mKE9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZ0J1ZmZlciBhcHBlbmQoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgICAgICAgIGFwcGVuZE51bGwoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFwcGVuZDAob2JqLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIHNwZWNpZmllZCBzdHJpbmcgdG8gdGhlIGVuZCBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgc3BlY2lmaWVkIHN0cmluZyBpcyB7QGNvZGUgbnVsbH0gdGhlIHN0cmluZyB7QGNvZGUgIm51bGwifSBpcworICAgICAqIGFwcGVuZGVkLCBvdGhlcndpc2UgdGhlIGNvbnRlbnRzIG9mIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGlzIGFwcGVuZGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBhcHBlbmQgKG1heSBiZSBudWxsKS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgU3RyaW5nQnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nQnVmZmVyIGFwcGVuZChTdHJpbmcgc3RyaW5nKSB7CisgICAgICAgIGFwcGVuZDAoc3RyaW5nKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIFN0cmluZ0J1ZmZlciB0byB0aGUgZW5kIG9mIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBzcGVjaWZpZWQgU3RyaW5nQnVmZmVyIGlzIHtAY29kZSBudWxsfSB0aGUgc3RyaW5nIHtAY29kZSAibnVsbCJ9CisgICAgICogaXMgYXBwZW5kZWQsIG90aGVyd2lzZSB0aGUgY29udGVudHMgb2YgdGhlIHNwZWNpZmllZCBTdHJpbmdCdWZmZXIgaXMKKyAgICAgKiBhcHBlbmRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzYgorICAgICAqICAgICAgICAgICAgdGhlIFN0cmluZ0J1ZmZlciB0byBhcHBlbmQgKG1heSBiZSBudWxsKS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgU3RyaW5nQnVmZmVyLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNAorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nQnVmZmVyIGFwcGVuZChTdHJpbmdCdWZmZXIgc2IpIHsKKyAgICAgICAgaWYgKHNiID09IG51bGwpIHsKKyAgICAgICAgICAgIGFwcGVuZE51bGwoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoc2IpIHsKKyAgICAgICAgICAgICAgICBhcHBlbmQwKHNiLmdldFZhbHVlKCksIDAsIHNiLmxlbmd0aCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBjaGFyYWN0ZXIgYXJyYXkgdG8gdGhlIGVuZCBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaGFycworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciBhcnJheSB0byBhcHBlbmQuCisgICAgICogQHJldHVybiB0aGlzIFN0cmluZ0J1ZmZlci4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICBpZiB7QGNvZGUgY2hhcnN9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZ0J1ZmZlciBhcHBlbmQoY2hhcltdIGNoYXJzKSB7CisgICAgICAgIGFwcGVuZDAoY2hhcnMpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyB0byB0aGUgZW5kIG9mIHRoaXMgYnVmZmVyLgorICAgICAqCisgICAgICogQHBhcmFtIGNoYXJzCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIGFycmF5IHRvIGFwcGVuZC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydGluZyBvZmZzZXQuCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzLgorICAgICAqIEByZXR1cm4gdGhpcyBTdHJpbmdCdWZmZXIuCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbGVuZ3RoIDwgMH0gLCB7QGNvZGUgc3RhcnQgPCAwfSBvciB7QGNvZGUgc3RhcnQgKworICAgICAqICAgICAgICAgICAgIGxlbmd0aCA+IGNoYXJzLmxlbmd0aH0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYge0Bjb2RlIGNoYXJzfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmdCdWZmZXIgYXBwZW5kKGNoYXJbXSBjaGFycywgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIGFwcGVuZDAoY2hhcnMsIHN0YXJ0LCBsZW5ndGgpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHRoZSBzcGVjaWZpZWQgQ2hhclNlcXVlbmNlIHRvIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBzcGVjaWZpZWQgQ2hhclNlcXVlbmNlIGlzIHtAY29kZSBudWxsfSB0aGUgc3RyaW5nIHtAY29kZSAibnVsbCJ9CisgICAgICogaXMgYXBwZW5kZWQsIG90aGVyd2lzZSB0aGUgY29udGVudHMgb2YgdGhlIHNwZWNpZmllZCBDaGFyU2VxdWVuY2UgaXMKKyAgICAgKiBhcHBlbmRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgQ2hhclNlcXVlbmNlIHRvIGFwcGVuZC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgU3RyaW5nQnVmZmVyLgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZ0J1ZmZlciBhcHBlbmQoQ2hhclNlcXVlbmNlIHMpIHsKKyAgICAgICAgaWYgKHMgPT0gbnVsbCkgeworICAgICAgICAgICAgYXBwZW5kTnVsbCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYXBwZW5kMChzLCAwLCBzLmxlbmd0aCgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHRoZSBzcGVjaWZpZWQgc3Vic2VxdWVuY2Ugb2YgdGhlIENoYXJTZXF1ZW5jZSB0byB0aGlzIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgc3BlY2lmaWVkIENoYXJTZXF1ZW5jZSBpcyB7QGNvZGUgbnVsbH0sIHRoZW4gdGhlIHN0cmluZyB7QGNvZGUKKyAgICAgKiAibnVsbCJ9IGlzIHVzZWQgdG8gZXh0cmFjdCBhIHN1YnNlcXVlbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBDaGFyU2VxdWVuY2UgdG8gYXBwZW5kLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIGluY2x1c2l2ZSBzdGFydCBpbmRleC4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgZXhjbHVzaXZlIGVuZCBpbmRleC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgU3RyaW5nQnVmZmVyLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydH0gb3Ige0Bjb2RlIGVuZH0gYXJlIG5lZ2F0aXZlLCB7QGNvZGUgc3RhcnR9CisgICAgICogICAgICAgICAgICAgaXMgZ3JlYXRlciB0aGFuIHtAY29kZSBlbmR9IG9yIHtAY29kZSBlbmR9IGlzIGdyZWF0ZXIgdGhhbgorICAgICAqICAgICAgICAgICAgIHRoZSBsZW5ndGggb2Yge0Bjb2RlIHN9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZ0J1ZmZlciBhcHBlbmQoQ2hhclNlcXVlbmNlIHMsIGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBhcHBlbmQwKHMsIHN0YXJ0LCBlbmQpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCBVbmljb2RlIGNvZGUgcG9pbnQgdG8KKyAgICAgKiB0aGUgZW5kIG9mIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBjb2RlIHBvaW50IGlzIGNvbnZlcnRlZCB0byBhIHtAY29kZSBjaGFyW119IGFzIGRlZmluZWQgYnkKKyAgICAgKiB7QGxpbmsgQ2hhcmFjdGVyI3RvQ2hhcnMoaW50KX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29kZVBvaW50CisgICAgICogICAgICAgICAgICB0aGUgVW5pY29kZSBjb2RlIHBvaW50IHRvIGVuY29kZSBhbmQgYXBwZW5kLgorICAgICAqIEByZXR1cm4gdGhpcyBTdHJpbmdCdWZmZXIuCisgICAgICogQHNlZSBDaGFyYWN0ZXIjdG9DaGFycyhpbnQpCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgYXBwZW5kQ29kZVBvaW50KGludCBjb2RlUG9pbnQpIHsKKyAgICAgICAgcmV0dXJuIGFwcGVuZChDaGFyYWN0ZXIudG9DaGFycyhjb2RlUG9pbnQpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGNoYXIgY2hhckF0KGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gc3VwZXIuY2hhckF0KGluZGV4KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBjb2RlUG9pbnRBdChpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmNvZGVQb2ludEF0KGluZGV4KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBjb2RlUG9pbnRCZWZvcmUoaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiBzdXBlci5jb2RlUG9pbnRCZWZvcmUoaW5kZXgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGNvZGVQb2ludENvdW50KGludCBiZWdpbkluZGV4LCBpbnQgZW5kSW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmNvZGVQb2ludENvdW50KGJlZ2luSW5kZXgsIGVuZEluZGV4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWxldGVzIGEgcmFuZ2Ugb2YgY2hhcmFjdGVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyLgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgb25lIHBhc3QgdGhlIGxhc3QgY2hhcmFjdGVyLgorICAgICAqIEByZXR1cm4gdGhpcyBTdHJpbmdCdWZmZXIuCisgICAgICogQHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0IDwgMH0sIHtAY29kZSBzdGFydCA+IGVuZH0gb3Ige0Bjb2RlIGVuZCA+CisgICAgICogICAgICAgICAgICAgbGVuZ3RoKCl9LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nQnVmZmVyIGRlbGV0ZShpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgZGVsZXRlMChzdGFydCwgZW5kKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVsZXRlcyB0aGUgY2hhcmFjdGVyIGF0IHRoZSBzcGVjaWZpZWQgb2Zmc2V0LgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2F0aW9uCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIHRoZSBjaGFyYWN0ZXIgdG8gZGVsZXRlLgorICAgICAqIEByZXR1cm4gdGhpcyBTdHJpbmdCdWZmZXIuCisgICAgICogQHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGxvY2F0aW9uIDwgMH0gb3Ige0Bjb2RlIGxvY2F0aW9uID49IGxlbmd0aCgpfQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nQnVmZmVyIGRlbGV0ZUNoYXJBdChpbnQgbG9jYXRpb24pIHsKKyAgICAgICAgZGVsZXRlQ2hhckF0MChsb2NhdGlvbik7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBlbnN1cmVDYXBhY2l0eShpbnQgbWluKSB7CisgICAgICAgIHN1cGVyLmVuc3VyZUNhcGFjaXR5KG1pbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29waWVzIHRoZSByZXF1ZXN0ZWQgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyB0byB0aGUge0Bjb2RlIGNoYXJbXX0gcGFzc2VkCisgICAgICogc3RhcnRpbmcgYXQge0Bjb2RlIGlkeH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydGluZyBvZmZzZXQgb2YgY2hhcmFjdGVycyB0byBjb3B5LgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmRpbmcgb2Zmc2V0IG9mIGNoYXJhY3RlcnMgdG8gY29weS4KKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gY2hhcmFjdGVyIGFycmF5LgorICAgICAqIEBwYXJhbSBpZHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydGluZyBvZmZzZXQgaW4gdGhlIGNoYXJhY3RlciBhcnJheS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwfSwge0Bjb2RlIGVuZCA+IGxlbmd0aCgpfSwge0Bjb2RlIHN0YXJ0ID4KKyAgICAgKiAgICAgICAgICAgICBlbmR9LCB7QGNvZGUgaW5kZXggPCAwfSwge0Bjb2RlIGVuZCAtIHN0YXJ0ID4gYnVmZmVyLmxlbmd0aCAtCisgICAgICogICAgICAgICAgICAgaW5kZXh9CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGdldENoYXJzKGludCBzdGFydCwgaW50IGVuZCwgY2hhcltdIGJ1ZmZlciwgaW50IGlkeCkgeworICAgICAgICBzdXBlci5nZXRDaGFycyhzdGFydCwgZW5kLCBidWZmZXIsIGlkeCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgaW5kZXhPZihTdHJpbmcgc3ViU3RyaW5nLCBpbnQgc3RhcnQpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmluZGV4T2Yoc3ViU3RyaW5nLCBzdGFydCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgY2hhcmFjdGVyIGludG8gdGhpcyBidWZmZXIgYXQgdGhlIHNwZWNpZmllZCBvZmZzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhdCB3aGljaCB0byBpbnNlcnQuCisgICAgICogQHBhcmFtIGNoCisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIHRvIGluc2VydC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4IDwgMH0gb3Ige0Bjb2RlIGluZGV4ID4gbGVuZ3RoKCl9LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nQnVmZmVyIGluc2VydChpbnQgaW5kZXgsIGNoYXIgY2gpIHsKKyAgICAgICAgaW5zZXJ0MChpbmRleCwgY2gpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCBib29sZWFuIGludG8gdGhpcworICAgICAqIGJ1ZmZlciBhdCB0aGUgc3BlY2lmaWVkIG9mZnNldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGF0IHdoaWNoIHRvIGluc2VydC4KKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJvb2xlYW4gdG8gaW5zZXJ0LgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4IDwgMH0gb3Ige0Bjb2RlIGluZGV4ID4gbGVuZ3RoKCl9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgaW5zZXJ0KGludCBpbmRleCwgYm9vbGVhbiBiKSB7CisgICAgICAgIHJldHVybiBpbnNlcnQoaW5kZXgsIGIgPyAidHJ1ZSIgOiAiZmFsc2UiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCBpbnRlZ2VyIGludG8gdGhpcworICAgICAqIGJ1ZmZlciBhdCB0aGUgc3BlY2lmaWVkIG9mZnNldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGF0IHdoaWNoIHRvIGluc2VydC4KKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdG8gaW5zZXJ0LgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4IDwgMH0gb3Ige0Bjb2RlIGluZGV4ID4gbGVuZ3RoKCl9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgaW5zZXJ0KGludCBpbmRleCwgaW50IGkpIHsKKyAgICAgICAgcmV0dXJuIGluc2VydChpbmRleCwgSW50ZWdlci50b1N0cmluZyhpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQgbG9uZyBpbnRvIHRoaXMgYnVmZmVyCisgICAgICogYXQgdGhlIHNwZWNpZmllZCBvZmZzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhdCB3aGljaCB0byBpbnNlcnQuCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb25nIHRvIGluc2VydC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBpbmRleCA8IDB9IG9yIHtAY29kZSBpbmRleCA+IGxlbmd0aCgpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGluc2VydChpbnQgaW5kZXgsIGxvbmcgbCkgeworICAgICAgICByZXR1cm4gaW5zZXJ0KGluZGV4LCBMb25nLnRvU3RyaW5nKGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCBpbnRvIHRoaXMgYnVmZmVyCisgICAgICogZG91YmxlIGF0IHRoZSBzcGVjaWZpZWQgb2Zmc2V0LgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggYXQgd2hpY2ggdG8gaW5zZXJ0LgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUgZG91YmxlIHRvIGluc2VydC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBpbmRleCA8IDB9IG9yIHtAY29kZSBpbmRleCA+IGxlbmd0aCgpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGluc2VydChpbnQgaW5kZXgsIGRvdWJsZSBkKSB7CisgICAgICAgIHJldHVybiBpbnNlcnQoaW5kZXgsIERvdWJsZS50b1N0cmluZyhkKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQgZmxvYXQgaW50byB0aGlzIGJ1ZmZlcgorICAgICAqIGF0IHRoZSBzcGVjaWZpZWQgb2Zmc2V0LgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggYXQgd2hpY2ggdG8gaW5zZXJ0LgorICAgICAqIEBwYXJhbSBmCisgICAgICogICAgICAgICAgICB0aGUgZmxvYXQgdG8gaW5zZXJ0LgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4IDwgMH0gb3Ige0Bjb2RlIGluZGV4ID4gbGVuZ3RoKCl9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgaW5zZXJ0KGludCBpbmRleCwgZmxvYXQgZikgeworICAgICAgICByZXR1cm4gaW5zZXJ0KGluZGV4LCBGbG9hdC50b1N0cmluZyhmKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGludG8gdGhpcworICAgICAqIGJ1ZmZlciBhdCB0aGUgc3BlY2lmaWVkIG9mZnNldC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyB7QGNvZGUgbnVsbH0sIHRoZSBzdHJpbmcge0Bjb2RlICJudWxsIn0gaXMKKyAgICAgKiBpbnNlcnRlZCwgb3RoZXJ3aXNlIHRoZSBvYmplY3RzIHtAY29kZSB0b1N0cmluZ30gbWV0aG9kIGlzIHVzZWQgdG8gZ2V0CisgICAgICogaXRzIHN0cmluZyByZXByZXNlbnRhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGF0IHdoaWNoIHRvIGluc2VydC4KKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGluc2VydCAobWF5IGJlIG51bGwpLgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4IDwgMH0gb3Ige0Bjb2RlIGluZGV4ID4gbGVuZ3RoKCl9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgaW5zZXJ0KGludCBpbmRleCwgT2JqZWN0IG9iaikgeworICAgICAgICByZXR1cm4gaW5zZXJ0KGluZGV4LCBvYmogPT0gbnVsbCA/ICJudWxsIiA6IG9iai50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzdHJpbmcgaW50byB0aGlzIGJ1ZmZlciBhdCB0aGUgc3BlY2lmaWVkIG9mZnNldC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgc3BlY2lmaWVkIHN0cmluZyBpcyB7QGNvZGUgbnVsbH0sIHRoZSBzdHJpbmcge0Bjb2RlICJudWxsIn0gaXMKKyAgICAgKiBpbnNlcnRlZCwgb3RoZXJ3aXNlIHRoZSBjb250ZW50cyBvZiB0aGUgc3RyaW5nIGlzIGluc2VydGVkLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggYXQgd2hpY2ggdG8gaW5zZXJ0LgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gaW5zZXJ0IChtYXkgYmUgbnVsbCkuCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAdGhyb3dzIFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW5kZXggPCAwfSBvciB7QGNvZGUgaW5kZXggPiBsZW5ndGgoKX0uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmdCdWZmZXIgaW5zZXJ0KGludCBpbmRleCwgU3RyaW5nIHN0cmluZykgeworICAgICAgICBpbnNlcnQwKGluZGV4LCBzdHJpbmcpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBjaGFyYWN0ZXIgYXJyYXkgaW50byB0aGlzIGJ1ZmZlciBhdCB0aGUgc3BlY2lmaWVkIG9mZnNldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGF0IHdoaWNoIHRvIGluc2VydC4KKyAgICAgKiBAcGFyYW0gY2hhcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgYXJyYXkgdG8gaW5zZXJ0LgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4IDwgMH0gb3Ige0Bjb2RlIGluZGV4ID4gbGVuZ3RoKCl9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIGlmIHtAY29kZSBjaGFyc30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nQnVmZmVyIGluc2VydChpbnQgaW5kZXgsIGNoYXJbXSBjaGFycykgeworICAgICAgICBpbnNlcnQwKGluZGV4LCBjaGFycyk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBzdWJzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIGludG8gdGhpcyBidWZmZXIgYXQgdGhlCisgICAgICogc3BlY2lmaWVkIGluZGV4LgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggYXQgd2hpY2ggdG8gaW5zZXJ0LgorICAgICAqIEBwYXJhbSBjaGFycworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciBhcnJheSB0byBpbnNlcnQuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnRpbmcgb2Zmc2V0LgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycy4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY2hhcnN9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbGVuZ3RoIDwgMH0sIHtAY29kZSBzdGFydCA8IDB9LCB7QGNvZGUgc3RhcnQgKworICAgICAqICAgICAgICAgICAgIGxlbmd0aCA+IGNoYXJzLmxlbmd0aH0sIHtAY29kZSBpbmRleCA8IDB9IG9yIHtAY29kZSBpbmRleCA+CisgICAgICogICAgICAgICAgICAgbGVuZ3RoKCl9CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmdCdWZmZXIgaW5zZXJ0KGludCBpbmRleCwgY2hhcltdIGNoYXJzLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHsKKyAgICAgICAgaW5zZXJ0MChpbmRleCwgY2hhcnMsIHN0YXJ0LCBsZW5ndGgpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgQ2hhclNlcXVlbmNlIGludG8gdGhpcyBidWZmZXIgYXQgdGhlIHNwZWNpZmllZAorICAgICAqIGluZGV4LgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBzcGVjaWZpZWQgQ2hhclNlcXVlbmNlIGlzIHtAY29kZSBudWxsfSwgdGhlIHN0cmluZyB7QGNvZGUgIm51bGwifQorICAgICAqIGlzIGluc2VydGVkLCBvdGhlcndpc2UgdGhlIGNvbnRlbnRzIG9mIHRoZSBDaGFyU2VxdWVuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIFRoZSBpbmRleCBhdCB3aGljaCB0byBpbnNlcnQuCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIFRoZSBjaGFyIHNlcXVlbmNlIHRvIGluc2VydC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBpbmRleCA8IDB9IG9yIHtAY29kZSBpbmRleCA+IGxlbmd0aCgpfS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmdCdWZmZXIgaW5zZXJ0KGludCBpbmRleCwgQ2hhclNlcXVlbmNlIHMpIHsKKyAgICAgICAgaW5zZXJ0MChpbmRleCwgcyA9PSBudWxsID8gIm51bGwiIDogcy50b1N0cmluZygpKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIHN1YnNlcXVlbmNlIGludG8gdGhpcyBidWZmZXIgYXQgdGhlIHNwZWNpZmllZAorICAgICAqIGluZGV4LgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBzcGVjaWZpZWQgQ2hhclNlcXVlbmNlIGlzIHtAY29kZSBudWxsfSwgdGhlIHN0cmluZyB7QGNvZGUgIm51bGwifQorICAgICAqIGlzIGluc2VydGVkLCBvdGhlcndpc2UgdGhlIGNvbnRlbnRzIG9mIHRoZSBDaGFyU2VxdWVuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIFRoZSBpbmRleCBhdCB3aGljaCB0byBpbnNlcnQuCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIFRoZSBjaGFyIHNlcXVlbmNlIHRvIGluc2VydC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIFRoZSBpbmNsdXNpdmUgc3RhcnQgaW5kZXggaW4gdGhlIGNoYXIgc2VxdWVuY2UuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgVGhlIGV4Y2x1c2l2ZSBlbmQgaW5kZXggaW4gdGhlIGNoYXIgc2VxdWVuY2UuCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW5kZXh9IGlzIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiB0aGUgY3VycmVudAorICAgICAqICAgICAgICAgICAgIGxlbmd0aCwge0Bjb2RlIHN0YXJ0fSBvciB7QGNvZGUgZW5kfSBhcmUgbmVnYXRpdmUsIHtAY29kZQorICAgICAqICAgICAgICAgICAgIHN0YXJ0fSBpcyBncmVhdGVyIHRoYW4ge0Bjb2RlIGVuZH0gb3Ige0Bjb2RlIGVuZH0gaXMgZ3JlYXRlcgorICAgICAqICAgICAgICAgICAgIHRoYW4gdGhlIGxlbmd0aCBvZiB7QGNvZGUgc30uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nQnVmZmVyIGluc2VydChpbnQgaW5kZXgsIENoYXJTZXF1ZW5jZSBzLAorICAgICAgICAgICAgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIGluc2VydDAoaW5kZXgsIHMsIHN0YXJ0LCBlbmQpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBsYXN0SW5kZXhPZihTdHJpbmcgc3ViU3RyaW5nLCBpbnQgc3RhcnQpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmxhc3RJbmRleE9mKHN1YlN0cmluZywgc3RhcnQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IG9mZnNldEJ5Q29kZVBvaW50cyhpbnQgaW5kZXgsIGludCBjb2RlUG9pbnRPZmZzZXQpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLm9mZnNldEJ5Q29kZVBvaW50cyhpbmRleCwgY29kZVBvaW50T2Zmc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyB0aGUgY2hhcmFjdGVycyBpbiB0aGUgc3BlY2lmaWVkIHJhbmdlIHdpdGggdGhlIGNvbnRlbnRzIG9mIHRoZQorICAgICAqIHNwZWNpZmllZCBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmNsdXNpdmUgYmVnaW4gaW5kZXguCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGV4Y2x1c2l2ZSBlbmQgaW5kZXguCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0aGF0IHdpbGwgcmVwbGFjZSB0aGUgY29udGVudHMgaW4gdGhlIHJhbmdlLgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0fSBvciB7QGNvZGUgZW5kfSBhcmUgbmVnYXRpdmUsIHtAY29kZSBzdGFydH0KKyAgICAgKiAgICAgICAgICAgICBpcyBncmVhdGVyIHRoYW4ge0Bjb2RlIGVuZH0gb3Ige0Bjb2RlIGVuZH0gaXMgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB7QGNvZGUgc30uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmdCdWZmZXIgcmVwbGFjZShpbnQgc3RhcnQsIGludCBlbmQsIFN0cmluZyBzdHJpbmcpIHsKKyAgICAgICAgcmVwbGFjZTAoc3RhcnQsIGVuZCwgc3RyaW5nKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV2ZXJzZXMgdGhlIG9yZGVyIG9mIGNoYXJhY3RlcnMgaW4gdGhpcyBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nQnVmZmVyIHJldmVyc2UoKSB7CisgICAgICAgIHJldmVyc2UwKCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRDaGFyQXQoaW50IGluZGV4LCBjaGFyIGNoKSB7CisgICAgICAgIHN1cGVyLnNldENoYXJBdChpbmRleCwgY2gpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRMZW5ndGgoaW50IGxlbmd0aCkgeworICAgICAgICBzdXBlci5zZXRMZW5ndGgobGVuZ3RoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIENoYXJTZXF1ZW5jZSBzdWJTZXF1ZW5jZShpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLnN1YnN0cmluZyhzdGFydCwgZW5kKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZyBzdWJzdHJpbmcoaW50IHN0YXJ0KSB7CisgICAgICAgIHJldHVybiBzdXBlci5zdWJzdHJpbmcoc3RhcnQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nIHN1YnN0cmluZyhpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLnN1YnN0cmluZyhzdGFydCwgZW5kKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHRyaW1Ub1NpemUoKSB7CisgICAgICAgIHN1cGVyLnRyaW1Ub1NpemUoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBvdXQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGQgZmllbGRzID0gb3V0LnB1dEZpZWxkcygpOworICAgICAgICBmaWVsZHMucHV0KCJjb3VudCIsIGxlbmd0aCgpKTsKKyAgICAgICAgZmllbGRzLnB1dCgic2hhcmVkIiwgZmFsc2UpOworICAgICAgICBmaWVsZHMucHV0KCJ2YWx1ZSIsIGdldFZhbHVlKCkpOworICAgICAgICBvdXQud3JpdGVGaWVsZHMoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkIGZpZWxkcyA9IGluLnJlYWRGaWVsZHMoKTsKKyAgICAgICAgaW50IGNvdW50ID0gZmllbGRzLmdldCgiY291bnQiLCAwKTsKKyAgICAgICAgY2hhcltdIHZhbHVlID0gKGNoYXJbXSkgZmllbGRzLmdldCgidmFsdWUiLCBudWxsKTsKKyAgICAgICAgc2V0KHZhbHVlLCBjb3VudCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1N0cmluZ0J1aWxkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kODg2MTAwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyLmphdmEKQEAgLTAsMCArMSw3MDEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCisvKioKKyAqIEEgbW9kaWZpYWJsZSB7QGxpbmsgQ2hhclNlcXVlbmNlIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnN9IGZvciB1c2UgaW4gY3JlYXRpbmcKKyAqIHN0cmluZ3MuIFRoaXMgY2xhc3MgaXMgaW50ZW5kZWQgYXMgYSBkaXJlY3QgcmVwbGFjZW1lbnQgb2YKKyAqIHtAbGluayBTdHJpbmdCdWZmZXJ9IGZvciBub24tY29uY3VycmVudCB1c2U7IHVubGlrZSB7QGNvZGUgU3RyaW5nQnVmZmVyfSB0aGlzCisgKiBjbGFzcyBpcyBub3Qgc3luY2hyb25pemVkLgorICoKKyAqIDxwPkZvciBwYXJ0aWN1bGFybHkgY29tcGxleCBzdHJpbmctYnVpbGRpbmcgbmVlZHMsIGNvbnNpZGVyIHtAbGluayBqYXZhLnV0aWwuRm9ybWF0dGVyfS4KKyAqCisgKiA8cD5UaGUgbWFqb3JpdHkgb2YgdGhlIG1vZGlmaWNhdGlvbiBtZXRob2RzIG9uIHRoaXMgY2xhc3MgcmV0dXJuIHtAY29kZQorICogdGhpc30gc28gdGhhdCBtZXRob2QgY2FsbHMgY2FuIGJlIGNoYWluZWQgdG9nZXRoZXIuIEZvciBleGFtcGxlOgorICoge0Bjb2RlIG5ldyBTdHJpbmdCdWlsZGVyKCJhIikuYXBwZW5kKCJiIikuYXBwZW5kKCJjIikudG9TdHJpbmcoKX0uCisgKgorICogQHNlZSBDaGFyU2VxdWVuY2UKKyAqIEBzZWUgQXBwZW5kYWJsZQorICogQHNlZSBTdHJpbmdCdWZmZXIKKyAqIEBzZWUgU3RyaW5nCisgKiBAc2VlIFN0cmluZyNmb3JtYXQKKyAqIEBzaW5jZSAxLjUKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFN0cmluZ0J1aWxkZXIgZXh0ZW5kcyBBYnN0cmFjdFN0cmluZ0J1aWxkZXIgaW1wbGVtZW50cworICAgICAgICBBcHBlbmRhYmxlLCBDaGFyU2VxdWVuY2UsIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0MzgzNjg1ODc3MTQ3OTIxMDk5TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gaW5zdGFuY2Ugd2l0aCBhbiBpbml0aWFsIGNhcGFjaXR5IG9mIHtAY29kZSAxNn0uCisgICAgICoKKyAgICAgKiBAc2VlICNjYXBhY2l0eSgpCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1aWxkZXIoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgY2FwYWNpdHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2FwYWNpdHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIGNhcGFjaXR5IHRvIHVzZS4KKyAgICAgKiBAdGhyb3dzIE5lZ2F0aXZlQXJyYXlTaXplRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCB7QGNvZGUgY2FwYWNpdHl9IGlzIG5lZ2F0aXZlLgorICAgICAqIEBzZWUgI2NhcGFjaXR5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVpbGRlcihpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgc3VwZXIoY2FwYWNpdHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gaW5zdGFuY2UgdGhhdCdzIGluaXRpYWxpemVkIHdpdGggdGhlIGNvbnRlbnRzIG9mIHRoZQorICAgICAqIHNwZWNpZmllZCB7QGNvZGUgQ2hhclNlcXVlbmNlfS4gVGhlIGNhcGFjaXR5IG9mIHRoZSBuZXcgYnVpbGRlciB3aWxsIGJlCisgICAgICogdGhlIGxlbmd0aCBvZiB0aGUge0Bjb2RlIENoYXJTZXF1ZW5jZX0gcGx1cyAxNi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzZXEKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2hhclNlcXVlbmNlfSB0byBjb3B5IGludG8gdGhlIGJ1aWxkZXIuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYge0Bjb2RlIHNlcX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWlsZGVyKENoYXJTZXF1ZW5jZSBzZXEpIHsKKyAgICAgICAgc3VwZXIoc2VxLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gaW5zdGFuY2UgdGhhdCdzIGluaXRpYWxpemVkIHdpdGggdGhlIGNvbnRlbnRzIG9mIHRoZQorICAgICAqIHNwZWNpZmllZCB7QGNvZGUgU3RyaW5nfS4gVGhlIGNhcGFjaXR5IG9mIHRoZSBuZXcgYnVpbGRlciB3aWxsIGJlIHRoZQorICAgICAqIGxlbmd0aCBvZiB0aGUge0Bjb2RlIFN0cmluZ30gcGx1cyAxNi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHIKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgU3RyaW5nfSB0byBjb3B5IGludG8gdGhlIGJ1aWxkZXIuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYge0Bjb2RlIHN0cn0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWlsZGVyKFN0cmluZyBzdHIpIHsKKyAgICAgICAgc3VwZXIoc3RyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCB7QGNvZGUgYm9vbGVhbn0gdmFsdWUuCisgICAgICogVGhlIHtAY29kZSBib29sZWFufSB2YWx1ZSBpcyBjb252ZXJ0ZWQgdG8gYSBTdHJpbmcgYWNjb3JkaW5nIHRvIHRoZSBydWxlCisgICAgICogZGVmaW5lZCBieSB7QGxpbmsgU3RyaW5nI3ZhbHVlT2YoYm9vbGVhbil9LgorICAgICAqCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgYm9vbGVhbn0gdmFsdWUgdG8gYXBwZW5kLgorICAgICAqIEByZXR1cm4gdGhpcyBidWlsZGVyLgorICAgICAqIEBzZWUgU3RyaW5nI3ZhbHVlT2YoYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVpbGRlciBhcHBlbmQoYm9vbGVhbiBiKSB7CisgICAgICAgIGFwcGVuZDAoYiA/ICJ0cnVlIiA6ICJmYWxzZSIpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCB7QGNvZGUgY2hhcn0gdmFsdWUuCisgICAgICogVGhlIHtAY29kZSBjaGFyfSB2YWx1ZSBpcyBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcgYWNjb3JkaW5nIHRvIHRoZSBydWxlCisgICAgICogZGVmaW5lZCBieSB7QGxpbmsgU3RyaW5nI3ZhbHVlT2YoY2hhcil9LgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgY2hhcn0gdmFsdWUgdG8gYXBwZW5kLgorICAgICAqIEByZXR1cm4gdGhpcyBidWlsZGVyLgorICAgICAqIEBzZWUgU3RyaW5nI3ZhbHVlT2YoY2hhcikKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVpbGRlciBhcHBlbmQoY2hhciBjKSB7CisgICAgICAgIGFwcGVuZDAoYyk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIHtAY29kZSBpbnR9IHZhbHVlLiBUaGUKKyAgICAgKiB7QGNvZGUgaW50fSB2YWx1ZSBpcyBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcgYWNjb3JkaW5nIHRvIHRoZSBydWxlIGRlZmluZWQKKyAgICAgKiBieSB7QGxpbmsgU3RyaW5nI3ZhbHVlT2YoaW50KX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBpbnR9IHZhbHVlIHRvIGFwcGVuZC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVpbGRlci4KKyAgICAgKiBAc2VlIFN0cmluZyN2YWx1ZU9mKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVpbGRlciBhcHBlbmQoaW50IGkpIHsKKyAgICAgICAgSW50ZWdyYWxUb1N0cmluZy5hcHBlbmRJbnQodGhpcywgaSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIHtAY29kZSBsb25nfSB2YWx1ZS4KKyAgICAgKiBUaGUge0Bjb2RlIGxvbmd9IHZhbHVlIGlzIGNvbnZlcnRlZCB0byBhIHN0cmluZyBhY2NvcmRpbmcgdG8gdGhlIHJ1bGUKKyAgICAgKiBkZWZpbmVkIGJ5IHtAbGluayBTdHJpbmcjdmFsdWVPZihsb25nKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBsb25nfSB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVpbGRlci4KKyAgICAgKiBAc2VlIFN0cmluZyN2YWx1ZU9mKGxvbmcpCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1aWxkZXIgYXBwZW5kKGxvbmcgbCkgeworICAgICAgICBJbnRlZ3JhbFRvU3RyaW5nLmFwcGVuZExvbmcodGhpcywgbCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIHtAY29kZSBmbG9hdH0gdmFsdWUuCisgICAgICogVGhlIHtAY29kZSBmbG9hdH0gdmFsdWUgaXMgY29udmVydGVkIHRvIGEgc3RyaW5nIGFjY29yZGluZyB0byB0aGUgcnVsZQorICAgICAqIGRlZmluZWQgYnkge0BsaW5rIFN0cmluZyN2YWx1ZU9mKGZsb2F0KX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBmbG9hdH0gdmFsdWUgdG8gYXBwZW5kLgorICAgICAqIEByZXR1cm4gdGhpcyBidWlsZGVyLgorICAgICAqIEBzZWUgU3RyaW5nI3ZhbHVlT2YoZmxvYXQpCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1aWxkZXIgYXBwZW5kKGZsb2F0IGYpIHsKKyAgICAgICAgUmVhbFRvU3RyaW5nLmdldEluc3RhbmNlKCkuYXBwZW5kRmxvYXQodGhpcywgZik7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIHtAY29kZSBkb3VibGV9IHZhbHVlLgorICAgICAqIFRoZSB7QGNvZGUgZG91YmxlfSB2YWx1ZSBpcyBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcgYWNjb3JkaW5nIHRvIHRoZSBydWxlCisgICAgICogZGVmaW5lZCBieSB7QGxpbmsgU3RyaW5nI3ZhbHVlT2YoZG91YmxlKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBkb3VibGV9IHZhbHVlIHRvIGFwcGVuZC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVpbGRlci4KKyAgICAgKiBAc2VlIFN0cmluZyN2YWx1ZU9mKGRvdWJsZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVpbGRlciBhcHBlbmQoZG91YmxlIGQpIHsKKyAgICAgICAgUmVhbFRvU3RyaW5nLmdldEluc3RhbmNlKCkuYXBwZW5kRG91YmxlKHRoaXMsIGQpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCB7QGNvZGUgT2JqZWN0fS4KKyAgICAgKiBUaGUge0Bjb2RlIE9iamVjdH0gdmFsdWUgaXMgY29udmVydGVkIHRvIGEgc3RyaW5nIGFjY29yZGluZyB0byB0aGUgcnVsZQorICAgICAqIGRlZmluZWQgYnkge0BsaW5rIFN0cmluZyN2YWx1ZU9mKE9iamVjdCl9LgorICAgICAqCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBPYmplY3R9IHRvIGFwcGVuZC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVpbGRlci4KKyAgICAgKiBAc2VlIFN0cmluZyN2YWx1ZU9mKE9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVpbGRlciBhcHBlbmQoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgICAgICAgIGFwcGVuZE51bGwoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFwcGVuZDAob2JqLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlIGNvbnRlbnRzIG9mIHRoZSBzcGVjaWZpZWQgc3RyaW5nLiBJZiB0aGUgc3RyaW5nIGlzIHtAY29kZQorICAgICAqIG51bGx9LCB0aGVuIHRoZSBzdHJpbmcge0Bjb2RlICJudWxsIn0gaXMgYXBwZW5kZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIGFwcGVuZC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVpbGRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVpbGRlciBhcHBlbmQoU3RyaW5nIHN0cikgeworICAgICAgICBhcHBlbmQwKHN0cik7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlIGNvbnRlbnRzIG9mIHRoZSBzcGVjaWZpZWQge0Bjb2RlIFN0cmluZ0J1ZmZlcn0uIElmIHRoZQorICAgICAqIFN0cmluZ0J1ZmZlciBpcyB7QGNvZGUgbnVsbH0sIHRoZW4gdGhlIHN0cmluZyB7QGNvZGUgIm51bGwifSBpcworICAgICAqIGFwcGVuZGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHNiCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIFN0cmluZ0J1ZmZlcn0gdG8gYXBwZW5kLgorICAgICAqIEByZXR1cm4gdGhpcyBidWlsZGVyLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWlsZGVyIGFwcGVuZChTdHJpbmdCdWZmZXIgc2IpIHsKKyAgICAgICAgaWYgKHNiID09IG51bGwpIHsKKyAgICAgICAgICAgIGFwcGVuZE51bGwoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFwcGVuZDAoc2IuZ2V0VmFsdWUoKSwgMCwgc2IubGVuZ3RoKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIHtAY29kZSBjaGFyW119LgorICAgICAqIFRoZSB7QGNvZGUgY2hhcltdfSBpcyBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcgYWNjb3JkaW5nIHRvIHRoZSBydWxlCisgICAgICogZGVmaW5lZCBieSB7QGxpbmsgU3RyaW5nI3ZhbHVlT2YoY2hhcltdKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgY2hhcltdfSB0byBhcHBlbmQuLgorICAgICAqIEByZXR1cm4gdGhpcyBidWlsZGVyLgorICAgICAqIEBzZWUgU3RyaW5nI3ZhbHVlT2YoY2hhcltdKQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWlsZGVyIGFwcGVuZChjaGFyW10gY2hhcnMpIHsKKyAgICAgICAgYXBwZW5kMChjaGFycyk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIHN1YnNldCBvZiB0aGUge0Bjb2RlCisgICAgICogY2hhcltdfS4gVGhlIHtAY29kZSBjaGFyW119IHZhbHVlIGlzIGNvbnZlcnRlZCB0byBhIFN0cmluZyBhY2NvcmRpbmcgdG8KKyAgICAgKiB0aGUgcnVsZSBkZWZpbmVkIGJ5IHtAbGluayBTdHJpbmcjdmFsdWVPZihjaGFyW10saW50LGludCl9LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBjaGFyW119IHRvIGFwcGVuZC4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5jbHVzaXZlIG9mZnNldCBpbmRleC4KKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMuCisgICAgICogQHJldHVybiB0aGlzIGJ1aWxkZXIuCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0fSBhbmQge0Bjb2RlIGxlbn0gZG8gbm90IHNwZWNpZnkgYSB2YWxpZAorICAgICAqICAgICAgICAgICAgIHN1YnNlcXVlbmNlLgorICAgICAqIEBzZWUgU3RyaW5nI3ZhbHVlT2YoY2hhcltdLGludCxpbnQpCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1aWxkZXIgYXBwZW5kKGNoYXJbXSBzdHIsIGludCBvZmZzZXQsIGludCBsZW4pIHsKKyAgICAgICAgYXBwZW5kMChzdHIsIG9mZnNldCwgbGVuKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQge0Bjb2RlIENoYXJTZXF1ZW5jZX0uCisgICAgICogSWYgdGhlIHtAY29kZSBDaGFyU2VxdWVuY2V9IGlzIHtAY29kZSBudWxsfSwgdGhlbiB0aGUgc3RyaW5nIHtAY29kZQorICAgICAqICJudWxsIn0gaXMgYXBwZW5kZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY3NxCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIENoYXJTZXF1ZW5jZX0gdG8gYXBwZW5kLgorICAgICAqIEByZXR1cm4gdGhpcyBidWlsZGVyLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWlsZGVyIGFwcGVuZChDaGFyU2VxdWVuY2UgY3NxKSB7CisgICAgICAgIGlmIChjc3EgPT0gbnVsbCkgeworICAgICAgICAgICAgYXBwZW5kTnVsbCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYXBwZW5kMChjc3EsIDAsIGNzcS5sZW5ndGgoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQgc3Vic2VxdWVuY2Ugb2YgdGhlCisgICAgICoge0Bjb2RlIENoYXJTZXF1ZW5jZX0uIElmIHRoZSB7QGNvZGUgQ2hhclNlcXVlbmNlfSBpcyB7QGNvZGUgbnVsbH0sIHRoZW4KKyAgICAgKiB0aGUgc3RyaW5nIHtAY29kZSAibnVsbCJ9IGlzIHVzZWQgdG8gZXh0cmFjdCB0aGUgc3Vic2VxdWVuY2UgZnJvbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjc3EKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2hhclNlcXVlbmNlfSB0byBhcHBlbmQuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgYmVnaW5uaW5nIGluZGV4LgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmRpbmcgaW5kZXguCisgICAgICogQHJldHVybiB0aGlzIGJ1aWxkZXIuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0fSBvciB7QGNvZGUgZW5kfSBhcmUgbmVnYXRpdmUsIHtAY29kZSBzdGFydH0KKyAgICAgKiAgICAgICAgICAgICBpcyBncmVhdGVyIHRoYW4ge0Bjb2RlIGVuZH0gb3Ige0Bjb2RlIGVuZH0gaXMgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB7QGNvZGUgY3NxfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVpbGRlciBhcHBlbmQoQ2hhclNlcXVlbmNlIGNzcSwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIGFwcGVuZDAoY3NxLCBzdGFydCwgZW5kKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyB0aGUgZW5jb2RlZCBVbmljb2RlIGNvZGUgcG9pbnQuIFRoZSBjb2RlIHBvaW50IGlzIGNvbnZlcnRlZCB0byBhCisgICAgICoge0Bjb2RlIGNoYXJbXX0gYXMgZGVmaW5lZCBieSB7QGxpbmsgQ2hhcmFjdGVyI3RvQ2hhcnMoaW50KX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29kZVBvaW50CisgICAgICogICAgICAgICAgICB0aGUgVW5pY29kZSBjb2RlIHBvaW50IHRvIGVuY29kZSBhbmQgYXBwZW5kLgorICAgICAqIEByZXR1cm4gdGhpcyBidWlsZGVyLgorICAgICAqIEBzZWUgQ2hhcmFjdGVyI3RvQ2hhcnMoaW50KQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWlsZGVyIGFwcGVuZENvZGVQb2ludChpbnQgY29kZVBvaW50KSB7CisgICAgICAgIGFwcGVuZDAoQ2hhcmFjdGVyLnRvQ2hhcnMoY29kZVBvaW50KSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlbGV0ZXMgYSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIHNwZWNpZmllZCBieSB7QGNvZGUgc3RhcnR9IGFuZCB7QGNvZGUKKyAgICAgKiBlbmR9LiBTaGlmdHMgYW55IHJlbWFpbmluZyBjaGFyYWN0ZXJzIHRvIHRoZSBsZWZ0LgorICAgICAqCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgaW5jbHVzaXZlIHN0YXJ0IGluZGV4LgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNsdXNpdmUgZW5kIGluZGV4LgorICAgICAqIEByZXR1cm4gdGhpcyBidWlsZGVyLgorICAgICAqIEB0aHJvd3MgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydH0gaXMgbGVzcyB0aGFuIHplcm8sIGdyZWF0ZXIgdGhhbiB0aGUgY3VycmVudAorICAgICAqICAgICAgICAgICAgIGxlbmd0aCBvciBncmVhdGVyIHRoYW4ge0Bjb2RlIGVuZH0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1aWxkZXIgZGVsZXRlKGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBkZWxldGUwKHN0YXJ0LCBlbmQpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWxldGVzIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gc2hpZnRzIGFueSByZW1haW5pbmcKKyAgICAgKiBjaGFyYWN0ZXJzIHRvIHRoZSBsZWZ0LgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNoYXJhY3RlciB0byBkZWxldGUuCisgICAgICogQHJldHVybiB0aGlzIGJ1aWxkZXIuCisgICAgICogQHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4fSBpcyBsZXNzIHRoYW4gemVybyBvciBpcyBncmVhdGVyIHRoYW4gb3IKKyAgICAgKiAgICAgICAgICAgICBlcXVhbCB0byB0aGUgY3VycmVudCBsZW5ndGguCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1aWxkZXIgZGVsZXRlQ2hhckF0KGludCBpbmRleCkgeworICAgICAgICBkZWxldGVDaGFyQXQwKGluZGV4KTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQge0Bjb2RlIGJvb2xlYW59IHZhbHVlCisgICAgICogYXQgdGhlIHNwZWNpZmllZCB7QGNvZGUgb2Zmc2V0fS4gVGhlIHtAY29kZSBib29sZWFufSB2YWx1ZSBpcyBjb252ZXJ0ZWQKKyAgICAgKiB0byBhIHN0cmluZyBhY2NvcmRpbmcgdG8gdGhlIHJ1bGUgZGVmaW5lZCBieQorICAgICAqIHtAbGluayBTdHJpbmcjdmFsdWVPZihib29sZWFuKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggdG8gaW5zZXJ0IGF0LgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGJvb2xlYW59IHZhbHVlIHRvIGluc2VydC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVpbGRlci4KKyAgICAgKiBAdGhyb3dzIFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0fSBpcyBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIGN1cnJlbnQKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgbGVuZ3RofS4KKyAgICAgKiBAc2VlIFN0cmluZyN2YWx1ZU9mKGJvb2xlYW4pCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1aWxkZXIgaW5zZXJ0KGludCBvZmZzZXQsIGJvb2xlYW4gYikgeworICAgICAgICBpbnNlcnQwKG9mZnNldCwgYiA/ICJ0cnVlIiA6ICJmYWxzZSIpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCB7QGNvZGUgY2hhcn0gdmFsdWUgYXQKKyAgICAgKiB0aGUgc3BlY2lmaWVkIHtAY29kZSBvZmZzZXR9LiBUaGUge0Bjb2RlIGNoYXJ9IHZhbHVlIGlzIGNvbnZlcnRlZCB0byBhCisgICAgICogc3RyaW5nIGFjY29yZGluZyB0byB0aGUgcnVsZSBkZWZpbmVkIGJ5IHtAbGluayBTdHJpbmcjdmFsdWVPZihjaGFyKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggdG8gaW5zZXJ0IGF0LgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGNoYXJ9IHZhbHVlIHRvIGluc2VydC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVpbGRlci4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0fSBpcyBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIGN1cnJlbnQKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgbGVuZ3RoKCl9LgorICAgICAqIEBzZWUgU3RyaW5nI3ZhbHVlT2YoY2hhcikKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVpbGRlciBpbnNlcnQoaW50IG9mZnNldCwgY2hhciBjKSB7CisgICAgICAgIGluc2VydDAob2Zmc2V0LCBjKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQge0Bjb2RlIGludH0gdmFsdWUgYXQKKyAgICAgKiB0aGUgc3BlY2lmaWVkIHtAY29kZSBvZmZzZXR9LiBUaGUge0Bjb2RlIGludH0gdmFsdWUgaXMgY29udmVydGVkIHRvIGEKKyAgICAgKiBTdHJpbmcgYWNjb3JkaW5nIHRvIHRoZSBydWxlIGRlZmluZWQgYnkge0BsaW5rIFN0cmluZyN2YWx1ZU9mKGludCl9LgorICAgICAqCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHRvIGluc2VydCBhdC4KKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBpbnR9IHZhbHVlIHRvIGluc2VydC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVpbGRlci4KKyAgICAgKiBAdGhyb3dzIFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0fSBpcyBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIGN1cnJlbnQKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgbGVuZ3RoKCl9LgorICAgICAqIEBzZWUgU3RyaW5nI3ZhbHVlT2YoaW50KQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdCdWlsZGVyIGluc2VydChpbnQgb2Zmc2V0LCBpbnQgaSkgeworICAgICAgICBpbnNlcnQwKG9mZnNldCwgSW50ZWdlci50b1N0cmluZyhpKSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIHtAY29kZSBsb25nfSB2YWx1ZSBhdAorICAgICAqIHRoZSBzcGVjaWZpZWQge0Bjb2RlIG9mZnNldH0uIFRoZSB7QGNvZGUgbG9uZ30gdmFsdWUgaXMgY29udmVydGVkIHRvIGEKKyAgICAgKiBTdHJpbmcgYWNjb3JkaW5nIHRvIHRoZSBydWxlIGRlZmluZWQgYnkge0BsaW5rIFN0cmluZyN2YWx1ZU9mKGxvbmcpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCB0byBpbnNlcnQgYXQuCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgbG9uZ30gdmFsdWUgdG8gaW5zZXJ0LgorICAgICAqIEByZXR1cm4gdGhpcyBidWlsZGVyLgorICAgICAqIEB0aHJvd3MgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXR9IGlzIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiB0aGUgY3VycmVudAorICAgICAqICAgICAgICAgICAgIHtjb2RlIGxlbmd0aCgpfS4KKyAgICAgKiBAc2VlIFN0cmluZyN2YWx1ZU9mKGxvbmcpCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1aWxkZXIgaW5zZXJ0KGludCBvZmZzZXQsIGxvbmcgbCkgeworICAgICAgICBpbnNlcnQwKG9mZnNldCwgTG9uZy50b1N0cmluZyhsKSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIHtAY29kZSBmbG9hdH0gdmFsdWUgYXQKKyAgICAgKiB0aGUgc3BlY2lmaWVkIHtAY29kZSBvZmZzZXR9LiBUaGUge0Bjb2RlIGZsb2F0fSB2YWx1ZSBpcyBjb252ZXJ0ZWQgdG8gYQorICAgICAqIHN0cmluZyBhY2NvcmRpbmcgdG8gdGhlIHJ1bGUgZGVmaW5lZCBieSB7QGxpbmsgU3RyaW5nI3ZhbHVlT2YoZmxvYXQpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCB0byBpbnNlcnQgYXQuCisgICAgICogQHBhcmFtIGYKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgZmxvYXR9IHZhbHVlIHRvIGluc2VydC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVpbGRlci4KKyAgICAgKiBAdGhyb3dzIFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0fSBpcyBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIGN1cnJlbnQKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgbGVuZ3RoKCl9LgorICAgICAqIEBzZWUgU3RyaW5nI3ZhbHVlT2YoZmxvYXQpCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1aWxkZXIgaW5zZXJ0KGludCBvZmZzZXQsIGZsb2F0IGYpIHsKKyAgICAgICAgaW5zZXJ0MChvZmZzZXQsIEZsb2F0LnRvU3RyaW5nKGYpKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQge0Bjb2RlIGRvdWJsZX0gdmFsdWUKKyAgICAgKiBhdCB0aGUgc3BlY2lmaWVkIHtAY29kZSBvZmZzZXR9LiBUaGUge0Bjb2RlIGRvdWJsZX0gdmFsdWUgaXMgY29udmVydGVkCisgICAgICogdG8gYSBTdHJpbmcgYWNjb3JkaW5nIHRvIHRoZSBydWxlIGRlZmluZWQgYnkKKyAgICAgKiB7QGxpbmsgU3RyaW5nI3ZhbHVlT2YoZG91YmxlKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggdG8gaW5zZXJ0IGF0LgorICAgICAqIEBwYXJhbSBkCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGRvdWJsZX0gdmFsdWUgdG8gaW5zZXJ0LgorICAgICAqIEByZXR1cm4gdGhpcyBidWlsZGVyLgorICAgICAqIEB0aHJvd3MgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXR9IGlzIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiB0aGUgY3VycmVudAorICAgICAqICAgICAgICAgICAgIHtAY29kZSBsZW5ndGgoKX0uCisgICAgICogQHNlZSBTdHJpbmcjdmFsdWVPZihkb3VibGUpCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1aWxkZXIgaW5zZXJ0KGludCBvZmZzZXQsIGRvdWJsZSBkKSB7CisgICAgICAgIGluc2VydDAob2Zmc2V0LCBEb3VibGUudG9TdHJpbmcoZCkpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCB7QGNvZGUgT2JqZWN0fSBhdCB0aGUKKyAgICAgKiBzcGVjaWZpZWQge0Bjb2RlIG9mZnNldH0uIFRoZSB7QGNvZGUgT2JqZWN0fSB2YWx1ZSBpcyBjb252ZXJ0ZWQgdG8gYQorICAgICAqIFN0cmluZyBhY2NvcmRpbmcgdG8gdGhlIHJ1bGUgZGVmaW5lZCBieSB7QGxpbmsgU3RyaW5nI3ZhbHVlT2YoT2JqZWN0KX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggdG8gaW5zZXJ0IGF0LgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT2JqZWN0fSB0byBpbnNlcnQuCisgICAgICogQHJldHVybiB0aGlzIGJ1aWxkZXIuCisgICAgICogQHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldH0gaXMgbmVnYXRpdmUgb3IgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50CisgICAgICogICAgICAgICAgICAge0Bjb2RlIGxlbmd0aCgpfS4KKyAgICAgKiBAc2VlIFN0cmluZyN2YWx1ZU9mKE9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVpbGRlciBpbnNlcnQoaW50IG9mZnNldCwgT2JqZWN0IG9iaikgeworICAgICAgICBpbnNlcnQwKG9mZnNldCwgb2JqID09IG51bGwgPyAibnVsbCIgOiBvYmoudG9TdHJpbmcoKSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBzdHJpbmcgYXQgdGhlIHNwZWNpZmllZCB7QGNvZGUgb2Zmc2V0fS4gSWYgdGhlCisgICAgICogc3BlY2lmaWVkIHN0cmluZyBpcyBudWxsLCB0aGVuIHRoZSBTdHJpbmcge0Bjb2RlICJudWxsIn0gaXMgaW5zZXJ0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggdG8gaW5zZXJ0IGF0LgorICAgICAqIEBwYXJhbSBzdHIKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgU3RyaW5nfSB0byBpbnNlcnQuCisgICAgICogQHJldHVybiB0aGlzIGJ1aWxkZXIuCisgICAgICogQHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldH0gaXMgbmVnYXRpdmUgb3IgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50CisgICAgICogICAgICAgICAgICAge0Bjb2RlIGxlbmd0aCgpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVpbGRlciBpbnNlcnQoaW50IG9mZnNldCwgU3RyaW5nIHN0cikgeworICAgICAgICBpbnNlcnQwKG9mZnNldCwgc3RyKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQge0Bjb2RlIGNoYXJbXX0gYXQgdGhlCisgICAgICogc3BlY2lmaWVkIHtAY29kZSBvZmZzZXR9LiBUaGUge0Bjb2RlIGNoYXJbXX0gdmFsdWUgaXMgY29udmVydGVkIHRvIGEKKyAgICAgKiBTdHJpbmcgYWNjb3JkaW5nIHRvIHRoZSBydWxlIGRlZmluZWQgYnkge0BsaW5rIFN0cmluZyN2YWx1ZU9mKGNoYXJbXSl9LgorICAgICAqCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHRvIGluc2VydCBhdC4KKyAgICAgKiBAcGFyYW0gY2gKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgY2hhcltdfSB0byBpbnNlcnQuCisgICAgICogQHJldHVybiB0aGlzIGJ1aWxkZXIuCisgICAgICogQHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldH0gaXMgbmVnYXRpdmUgb3IgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50CisgICAgICogICAgICAgICAgICAge0Bjb2RlIGxlbmd0aCgpfS4KKyAgICAgKiBAc2VlIFN0cmluZyN2YWx1ZU9mKGNoYXJbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVpbGRlciBpbnNlcnQoaW50IG9mZnNldCwgY2hhcltdIGNoKSB7CisgICAgICAgIGluc2VydDAob2Zmc2V0LCBjaCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIHN1YnNlcXVlbmNlIG9mIHRoZQorICAgICAqIHtAY29kZSBjaGFyW119IGF0IHRoZSBzcGVjaWZpZWQge0Bjb2RlIG9mZnNldH0uIFRoZSB7QGNvZGUgY2hhcltdfSB2YWx1ZQorICAgICAqIGlzIGNvbnZlcnRlZCB0byBhIFN0cmluZyBhY2NvcmRpbmcgdG8gdGhlIHJ1bGUgZGVmaW5lZCBieQorICAgICAqIHtAbGluayBTdHJpbmcjdmFsdWVPZihjaGFyW10saW50LGludCl9LgorICAgICAqCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHRvIGluc2VydCBhdC4KKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGNoYXJbXX0gdG8gaW5zZXJ0LgorICAgICAqIEBwYXJhbSBzdHJPZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmNsdXNpdmUgaW5kZXguCisgICAgICogQHBhcmFtIHN0ckxlbgorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzLgorICAgICAqIEByZXR1cm4gdGhpcyBidWlsZGVyLgorICAgICAqIEB0aHJvd3MgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXR9IGlzIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiB0aGUgY3VycmVudAorICAgICAqICAgICAgICAgICAgIHtAY29kZSBsZW5ndGgoKX0sIG9yIHtAY29kZSBzdHJPZmZzZXR9IGFuZCB7QGNvZGUgc3RyTGVufSBkbworICAgICAqICAgICAgICAgICAgIG5vdCBzcGVjaWZ5IGEgdmFsaWQgc3Vic2VxdWVuY2UuCisgICAgICogQHNlZSBTdHJpbmcjdmFsdWVPZihjaGFyW10saW50LGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVpbGRlciBpbnNlcnQoaW50IG9mZnNldCwgY2hhcltdIHN0ciwgaW50IHN0ck9mZnNldCwKKyAgICAgICAgICAgIGludCBzdHJMZW4pIHsKKyAgICAgICAgaW5zZXJ0MChvZmZzZXQsIHN0ciwgc3RyT2Zmc2V0LCBzdHJMZW4pOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCB7QGNvZGUgQ2hhclNlcXVlbmNlfQorICAgICAqIGF0IHRoZSBzcGVjaWZpZWQge0Bjb2RlIG9mZnNldH0uIFRoZSB7QGNvZGUgQ2hhclNlcXVlbmNlfSBpcyBjb252ZXJ0ZWQKKyAgICAgKiB0byBhIFN0cmluZyBhcyBkZWZpbmVkIGJ5IHtAbGluayBDaGFyU2VxdWVuY2UjdG9TdHJpbmcoKX0uIElmIHtAY29kZSBzfQorICAgICAqIGlzIHtAY29kZSBudWxsfSwgdGhlbiB0aGUgU3RyaW5nIHtAY29kZSAibnVsbCJ9IGlzIGluc2VydGVkLgorICAgICAqCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHRvIGluc2VydCBhdC4KKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDaGFyU2VxdWVuY2V9IHRvIGluc2VydC4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVpbGRlci4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0fSBpcyBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIGN1cnJlbnQKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgbGVuZ3RoKCl9LgorICAgICAqIEBzZWUgQ2hhclNlcXVlbmNlI3RvU3RyaW5nKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVpbGRlciBpbnNlcnQoaW50IG9mZnNldCwgQ2hhclNlcXVlbmNlIHMpIHsKKyAgICAgICAgaW5zZXJ0MChvZmZzZXQsIHMgPT0gbnVsbCA/ICJudWxsIiA6IHMudG9TdHJpbmcoKSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIHN1YnNlcXVlbmNlIG9mIHRoZQorICAgICAqIHtAY29kZSBDaGFyU2VxdWVuY2V9IGF0IHRoZSBzcGVjaWZpZWQge0Bjb2RlIG9mZnNldH0uIFRoZSB7QGNvZGUKKyAgICAgKiBDaGFyU2VxdWVuY2V9IGlzIGNvbnZlcnRlZCB0byBhIFN0cmluZyBhcyBkZWZpbmVkIGJ5CisgICAgICoge0BsaW5rIENoYXJTZXF1ZW5jZSNzdWJTZXF1ZW5jZShpbnQsIGludCl9LiBJZiB0aGUge0Bjb2RlIENoYXJTZXF1ZW5jZX0KKyAgICAgKiBpcyB7QGNvZGUgbnVsbH0sIHRoZW4gdGhlIHN0cmluZyB7QGNvZGUgIm51bGwifSBpcyB1c2VkIHRvIGRldGVybWluZSB0aGUKKyAgICAgKiBzdWJzZXF1ZW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCB0byBpbnNlcnQgYXQuCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2hhclNlcXVlbmNlfSB0byBpbnNlcnQuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgb2YgdGhlIHN1YnNlcXVlbmNlIG9mIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGVuZCBvZiB0aGUgc3Vic2VxdWVuY2Ugb2YgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVpbGRlci4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0fSBpcyBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIGN1cnJlbnQKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgbGVuZ3RoKCl9LCBvciB7QGNvZGUgc3RhcnR9IGFuZCB7QGNvZGUgZW5kfSBkbyBub3QKKyAgICAgKiAgICAgICAgICAgICBzcGVjaWZ5IGEgdmFsaWQgc3Vic2VxdWVuY2UuCisgICAgICogQHNlZSBDaGFyU2VxdWVuY2Ujc3ViU2VxdWVuY2UoaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1aWxkZXIgaW5zZXJ0KGludCBvZmZzZXQsIENoYXJTZXF1ZW5jZSBzLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgaW5zZXJ0MChvZmZzZXQsIHMsIHN0YXJ0LCBlbmQpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyB0aGUgc3BlY2lmaWVkIHN1YnNlcXVlbmNlIGluIHRoaXMgYnVpbGRlciB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmNsdXNpdmUgYmVnaW4gaW5kZXguCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGV4Y2x1c2l2ZSBlbmQgaW5kZXguCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIHJlcGxhY2VtZW50IHN0cmluZy4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVpbGRlci4KKyAgICAgKiBAdGhyb3dzIFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnR9IGlzIG5lZ2F0aXZlLCBncmVhdGVyIHRoYW4gdGhlIGN1cnJlbnQKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgbGVuZ3RoKCl9IG9yIGdyZWF0ZXIgdGhhbiB7QGNvZGUgZW5kfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICBpZiB7QGNvZGUgc3RyfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1aWxkZXIgcmVwbGFjZShpbnQgc3RhcnQsIGludCBlbmQsIFN0cmluZyBzdHIpIHsKKyAgICAgICAgcmVwbGFjZTAoc3RhcnQsIGVuZCwgc3RyKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV2ZXJzZXMgdGhlIG9yZGVyIG9mIGNoYXJhY3RlcnMgaW4gdGhpcyBidWlsZGVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVpbGRlciByZXZlcnNlKCkgeworICAgICAgICByZXZlcnNlMCgpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1aWxkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGRhdGEgaW4gdGhpcyBidWlsZGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIC8qIE5vdGU6IFRoaXMgbWV0aG9kIGlzIHJlcXVpcmVkIHRvIHdvcmthcm91bmQgYSBjb21waWxlciBidWcKKyAgICAgICAgICogaW4gdGhlIFJJIGphdmFjIChhdCBsZWFzdCBpbiAxLjUuMF8wNikgdGhhdCB3aWxsIGdlbmVyYXRlIGEKKyAgICAgICAgICogcmVmZXJlbmNlIHRvIHRoZSBub24tcHVibGljIEFic3RyYWN0U3RyaW5nQnVpbGRlciBpZiB3ZSBkb24ndAorICAgICAgICAgKiBvdmVycmlkZSBpdCBoZXJlLgorICAgICAgICAgKi8KKyAgICAgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIHN0YXRlIG9mIGEge0Bjb2RlIFN0cmluZ0J1aWxkZXJ9IGZyb20gdGhlIHBhc3NlZCBzdHJlYW0gYW5kCisgICAgICogcmVzdG9yZXMgaXQgdG8gdGhpcyBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmVhbSB0byByZWFkIHRoZSBzdGF0ZSBmcm9tLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3RyZWFtIHRocm93cyBpdCBkdXJpbmcgdGhlIHJlYWQuCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHN0cmVhbSB0aHJvd3MgaXQgZHVyaW5nIHRoZSByZWFkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgICAgICBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgaW4uZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgaW50IGNvdW50ID0gaW4ucmVhZEludCgpOworICAgICAgICBjaGFyW10gdmFsdWUgPSAoY2hhcltdKSBpbi5yZWFkT2JqZWN0KCk7CisgICAgICAgIHNldCh2YWx1ZSwgY291bnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3RhdGUgb2YgdGhpcyBvYmplY3QgdG8gdGhlIHN0cmVhbSBwYXNzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICogICAgICAgICAgICB0aGUgc3RyZWFtIHRvIHdyaXRlIHRoZSBzdGF0ZSB0by4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHN0cmVhbSB0aHJvd3MgaXQgZHVyaW5nIHRoZSB3cml0ZS4KKyAgICAgKiBAc2VyaWFsRGF0YSB7QGNvZGUgaW50fSAtIHRoZSBsZW5ndGggb2YgdGhpcyBvYmplY3QuIHtAY29kZSBjaGFyW119IC0gdGhlCisgICAgICogICAgICAgICAgICAgYnVmZmVyIGZyb20gdGhpcyBvYmplY3QsIHdoaWNoIG1heSBiZSBsYXJnZXIgdGhhbiB0aGUgbGVuZ3RoCisgICAgICogICAgICAgICAgICAgZmllbGQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC5kZWZhdWx0V3JpdGVPYmplY3QoKTsKKyAgICAgICAgb3V0LndyaXRlSW50KGxlbmd0aCgpKTsKKyAgICAgICAgb3V0LndyaXRlT2JqZWN0KGdldFZhbHVlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzkzMGNkMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIFRocm93biB3aGVuIHRoZSBhIHN0cmluZyBpcyBpbmRleGVkIHdpdGggYSB2YWx1ZSBsZXNzIHRoYW4gemVybywgb3IgZ3JlYXRlcgorICogdGhhbiBvciBlcXVhbCB0byB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkuCisgKi8KK3B1YmxpYyBjbGFzcyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4dGVuZHMgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjc2MjkxMDQyMjE1OTYzNzI1OEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9ufSB0aGF0IGluY2x1ZGVzCisgICAgICogdGhlIGN1cnJlbnQgc3RhY2sgdHJhY2UuCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudAorICAgICAqIHN0YWNrIHRyYWNlIGFuZCBhIGRldGFpbCBtZXNzYWdlIHRoYXQgaXMgYmFzZWQgb24gdGhlIHNwZWNpZmllZCBpbnZhbGlkCisgICAgICoge0Bjb2RlIGluZGV4fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHdoaWNoIGlzIG91dCBvZiBib3VuZHMuCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oaW50IGluZGV4KSB7CisgICAgICAgIHN1cGVyKCJTdHJpbmcgaW5kZXggb3V0IG9mIHJhbmdlOiAiICsgaW5kZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQKKyAgICAgKiBzdGFjayB0cmFjZSBhbmQgdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVzZWQgaW50ZXJuYWxseSBmb3IgY29uc2lzdGVudCBoaWdoLXF1YWxpdHkgZXJyb3IgcmVwb3J0aW5nLgorICAgICAqIEBoaWRlCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oU3RyaW5nIHMsIGludCBpbmRleCkgeworICAgICAgICB0aGlzKHMubGVuZ3RoKCksIGluZGV4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2VkIGludGVybmFsbHkgZm9yIGNvbnNpc3RlbnQgaGlnaC1xdWFsaXR5IGVycm9yIHJlcG9ydGluZy4KKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKGludCBzb3VyY2VMZW5ndGgsIGludCBpbmRleCkgeworICAgICAgICBzdXBlcigibGVuZ3RoPSIgKyBzb3VyY2VMZW5ndGggKyAiOyBpbmRleD0iICsgaW5kZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVzZWQgaW50ZXJuYWxseSBmb3IgY29uc2lzdGVudCBoaWdoLXF1YWxpdHkgZXJyb3IgcmVwb3J0aW5nLgorICAgICAqIEBoaWRlCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oU3RyaW5nIHMsIGludCBvZmZzZXQsIGludCBjb3VudCkgeworICAgICAgICB0aGlzKHMubGVuZ3RoKCksIG9mZnNldCwgY291bnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVzZWQgaW50ZXJuYWxseSBmb3IgY29uc2lzdGVudCBoaWdoLXF1YWxpdHkgZXJyb3IgcmVwb3J0aW5nLgorICAgICAqIEBoaWRlCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oaW50IHNvdXJjZUxlbmd0aCwgaW50IG9mZnNldCwKKyAgICAgICAgICAgIGludCBjb3VudCkgeworICAgICAgICBzdXBlcigibGVuZ3RoPSIgKyBzb3VyY2VMZW5ndGggKyAiOyByZWdpb25TdGFydD0iICsgb2Zmc2V0CisgICAgICAgICAgICAgICAgKyAiOyByZWdpb25MZW5ndGg9IiArIGNvdW50KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1N0cmluZ1RvUmVhbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TdHJpbmdUb1JlYWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45N2Y2ZDZiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TdHJpbmdUb1JlYWwuamF2YQpAQCAtMCwwICsxLDMxNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVXNlZCB0byBwYXJzZSBhIHN0cmluZyBhbmQgcmV0dXJuIGVpdGhlciBhIHNpbmdsZSBvciBkb3VibGUgcHJlY2lzaW9uCisgKiBmbG9hdGluZyBwb2ludCBudW1iZXIuCisgKiBAaGlkZQorICovCitmaW5hbCBjbGFzcyBTdHJpbmdUb1JlYWwgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU3RyaW5nRXhwb25lbnRQYWlyIHsKKyAgICAgICAgU3RyaW5nIHM7CisgICAgICAgIGxvbmcgZTsKKyAgICAgICAgYm9vbGVhbiBuZWdhdGl2ZTsKKworICAgICAgICAvLyBGbGFncyBmb3IgdHdvIHNwZWNpYWwgbm9uLWVycm9yIGZhaWx1cmUgY2FzZXMuCisgICAgICAgIGJvb2xlYW4gaW5maW5pdHk7CisgICAgICAgIGJvb2xlYW4gemVybzsKKworICAgICAgICBwdWJsaWMgZmxvYXQgc3BlY2lhbFZhbHVlKCkgeworICAgICAgICAgICAgaWYgKGluZmluaXR5KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlID8gRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFkgOiBGbG9hdC5QT1NJVElWRV9JTkZJTklUWTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuZWdhdGl2ZSA/IC0wLjBmIDogMC4wZjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRha2VzIGEgU3RyaW5nIGFuZCBhbiBpbnRlZ2VyIGV4cG9uZW50LiBUaGUgU3RyaW5nIHNob3VsZCBob2xkIGEgcG9zaXRpdmUKKyAgICAgKiBpbnRlZ2VyIHZhbHVlIChvciB6ZXJvKS4gVGhlIGV4cG9uZW50IHdpbGwgYmUgdXNlZCB0byBjYWxjdWxhdGUgdGhlCisgICAgICogZmxvYXRpbmcgcG9pbnQgbnVtYmVyIGJ5IHRha2luZyB0aGUgcG9zaXRpdmUgaW50ZWdlciB0aGUgU3RyaW5nCisgICAgICogcmVwcmVzZW50cyBhbmQgbXVsdGlwbHlpbmcgYnkgMTAgcmFpc2VkIHRvIHRoZSBwb3dlciBvZiB0aGUgb2YgdGhlCisgICAgICogZXhwb25lbnQuIFJldHVybnMgdGhlIGNsb3Nlc3QgZG91YmxlIHZhbHVlIHRvIHRoZSByZWFsIG51bWJlciwgb3IgRG91YmxlLmxvbmdCaXRzVG9Eb3VibGUoLTEpLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBkb3VibGUgcGFyc2VEYmxJbXBsKFN0cmluZyBzLCBpbnQgZSk7CisKKyAgICAvKioKKyAgICAgKiBUYWtlcyBhIFN0cmluZyBhbmQgYW4gaW50ZWdlciBleHBvbmVudC4gVGhlIFN0cmluZyBzaG91bGQgaG9sZCBhIHBvc2l0aXZlCisgICAgICogaW50ZWdlciB2YWx1ZSAob3IgemVybykuIFRoZSBleHBvbmVudCB3aWxsIGJlIHVzZWQgdG8gY2FsY3VsYXRlIHRoZQorICAgICAqIGZsb2F0aW5nIHBvaW50IG51bWJlciBieSB0YWtpbmcgdGhlIHBvc2l0aXZlIGludGVnZXIgdGhlIFN0cmluZworICAgICAqIHJlcHJlc2VudHMgYW5kIG11bHRpcGx5aW5nIGJ5IDEwIHJhaXNlZCB0byB0aGUgcG93ZXIgb2YgdGhlIG9mIHRoZQorICAgICAqIGV4cG9uZW50LiBSZXR1cm5zIHRoZSBjbG9zZXN0IGZsb2F0IHZhbHVlIHRvIHRoZSByZWFsIG51bWJlciwgb3IgRmxvYXQuaW50Qml0c1RvRmxvYXQoLTEpLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBmbG9hdCBwYXJzZUZsdEltcGwoU3RyaW5nIHMsIGludCBlKTsKKworICAgIHByaXZhdGUgc3RhdGljIE51bWJlckZvcm1hdEV4Y2VwdGlvbiBpbnZhbGlkUmVhbChTdHJpbmcgcywgYm9vbGVhbiBpc0RvdWJsZSkgeworICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkICIgKyAoaXNEb3VibGUgPyAiZG91YmxlIiA6ICJmbG9hdCIpICsgIjogXCIiICsgcyArICJcIiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBTdHJpbmdFeHBvbmVudFBhaXIgY29udGFpbmluZyBhIFN0cmluZyB3aXRoIG5vIGxlYWRpbmcgb3IgdHJhaWxpbmcgd2hpdGUKKyAgICAgKiBzcGFjZSBhbmQgdHJhaWxpbmcgemVyb2VzIGVsaW1pbmF0ZWQuIFRoZSBleHBvbmVudCBvZiB0aGUKKyAgICAgKiBTdHJpbmdFeHBvbmVudFBhaXIgd2lsbCBiZSB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgZmxvYXRpbmcgcG9pbnQgbnVtYmVyIGJ5CisgICAgICogdGFraW5nIHRoZSBwb3NpdGl2ZSBpbnRlZ2VyIHRoZSBTdHJpbmcgcmVwcmVzZW50cyBhbmQgbXVsdGlwbHlpbmcgYnkgMTAKKyAgICAgKiByYWlzZWQgdG8gdGhlIHBvd2VyIG9mIHRoZSBvZiB0aGUgZXhwb25lbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nRXhwb25lbnRQYWlyIGluaXRpYWxQYXJzZShTdHJpbmcgcywgaW50IGxlbmd0aCwgYm9vbGVhbiBpc0RvdWJsZSkgeworICAgICAgICBTdHJpbmdFeHBvbmVudFBhaXIgcmVzdWx0ID0gbmV3IFN0cmluZ0V4cG9uZW50UGFpcigpOworICAgICAgICBpZiAobGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHRocm93IGludmFsaWRSZWFsKHMsIGlzRG91YmxlKTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHQubmVnYXRpdmUgPSAocy5jaGFyQXQoMCkgPT0gJy0nKTsKKworICAgICAgICAvLyBXZSBpZ25vcmUgdHJhaWxpbmcgZG91YmxlIG9yIGZsb2F0IGluZGljYXRvcnM7IHRoZSBtZXRob2QgeW91IGNhbGxlZCBkZXRlcm1pbmVzCisgICAgICAgIC8vIHdoYXQgeW91J2xsIGdldC4KKyAgICAgICAgY2hhciBjID0gcy5jaGFyQXQobGVuZ3RoIC0gMSk7CisgICAgICAgIGlmIChjID09ICdEJyB8fCBjID09ICdkJyB8fCBjID09ICdGJyB8fCBjID09ICdmJykgeworICAgICAgICAgICAgbGVuZ3RoLS07CisgICAgICAgICAgICBpZiAobGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBpbnZhbGlkUmVhbChzLCBpc0RvdWJsZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpbnQgZW5kID0gTWF0aC5tYXgocy5pbmRleE9mKCdFJyksIHMuaW5kZXhPZignZScpKTsKKyAgICAgICAgaWYgKGVuZCAhPSAtMSkgeworICAgICAgICAgICAgLy8gSXMgdGhlcmUgYW55dGhpbmcgYWZ0ZXIgdGhlICdlJz8KKyAgICAgICAgICAgIGlmIChlbmQgKyAxID09IGxlbmd0aCkgeworICAgICAgICAgICAgICAgIHRocm93IGludmFsaWRSZWFsKHMsIGlzRG91YmxlKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gRG8gd2UgaGF2ZSBhbiBvcHRpb25hbCBleHBsaWNpdCBzaWduPworICAgICAgICAgICAgaW50IGV4cG9uZW50T2Zmc2V0ID0gZW5kICsgMTsKKyAgICAgICAgICAgIGJvb2xlYW4gbmVnYXRpdmVFeHBvbmVudCA9IGZhbHNlOworICAgICAgICAgICAgY2hhciBmaXJzdEV4cG9uZW50Q2hhciA9IHMuY2hhckF0KGV4cG9uZW50T2Zmc2V0KTsKKyAgICAgICAgICAgIGlmIChmaXJzdEV4cG9uZW50Q2hhciA9PSAnKycgfHwgZmlyc3RFeHBvbmVudENoYXIgPT0gJy0nKSB7CisgICAgICAgICAgICAgICAgbmVnYXRpdmVFeHBvbmVudCA9IChmaXJzdEV4cG9uZW50Q2hhciA9PSAnLScpOworICAgICAgICAgICAgICAgICsrZXhwb25lbnRPZmZzZXQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIERvIHdlIGhhdmUgYSB2YWxpZCBwb3NpdGl2ZSBpbnRlZ2VyPworICAgICAgICAgICAgU3RyaW5nIGV4cG9uZW50U3RyaW5nID0gcy5zdWJzdHJpbmcoZXhwb25lbnRPZmZzZXQsIGxlbmd0aCk7CisgICAgICAgICAgICBpZiAoZXhwb25lbnRTdHJpbmcuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgaW52YWxpZFJlYWwocywgaXNEb3VibGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHBvbmVudFN0cmluZy5sZW5ndGgoKTsgKytpKSB7CisgICAgICAgICAgICAgICAgY2hhciBjaCA9IGV4cG9uZW50U3RyaW5nLmNoYXJBdChpKTsKKyAgICAgICAgICAgICAgICBpZiAoY2ggPCAnMCcgfHwgY2ggPiAnOScpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgaW52YWxpZFJlYWwocywgaXNEb3VibGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gUGFyc2UgdGhlIGludGVnZXIgZXhwb25lbnQuCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5lID0gSW50ZWdlci5wYXJzZUludChleHBvbmVudFN0cmluZyk7CisgICAgICAgICAgICAgICAgaWYgKG5lZ2F0aXZlRXhwb25lbnQpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmUgPSAtcmVzdWx0LmU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgLy8gV2UgYWxyZWFkeSBjaGVja2VkIHRoZSBzdHJpbmcsIHNvIHRoZSBleHBvbmVudCBtdXN0IGhhdmUgYmVlbiBvdXQgb2YgcmFuZ2UgZm9yIGFuIGludC4KKyAgICAgICAgICAgICAgICBpZiAobmVnYXRpdmVFeHBvbmVudCkgeworICAgICAgICAgICAgICAgICAgICByZXN1bHQuemVybyA9IHRydWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmluZmluaXR5ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGVuZCA9IGxlbmd0aDsKKyAgICAgICAgfQorICAgICAgICBpZiAobGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHRocm93IGludmFsaWRSZWFsKHMsIGlzRG91YmxlKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBzdGFydCA9IDA7CisgICAgICAgIGMgPSBzLmNoYXJBdChzdGFydCk7CisgICAgICAgIGlmIChjID09ICctJykgeworICAgICAgICAgICAgKytzdGFydDsKKyAgICAgICAgICAgIC0tbGVuZ3RoOworICAgICAgICAgICAgcmVzdWx0Lm5lZ2F0aXZlID0gdHJ1ZTsKKyAgICAgICAgfSBlbHNlIGlmIChjID09ICcrJykgeworICAgICAgICAgICAgKytzdGFydDsKKyAgICAgICAgICAgIC0tbGVuZ3RoOworICAgICAgICB9CisgICAgICAgIGlmIChsZW5ndGggPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgaW52YWxpZFJlYWwocywgaXNEb3VibGUpOworICAgICAgICB9CisKKyAgICAgICAgaW50IGRlY2ltYWwgPSBzLmluZGV4T2YoJy4nKTsKKyAgICAgICAgaWYgKGRlY2ltYWwgPiAtMSkgeworICAgICAgICAgICAgcmVzdWx0LmUgLT0gZW5kIC0gZGVjaW1hbCAtIDE7CisgICAgICAgICAgICBzID0gcy5zdWJzdHJpbmcoc3RhcnQsIGRlY2ltYWwpICsgcy5zdWJzdHJpbmcoZGVjaW1hbCArIDEsIGVuZCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzID0gcy5zdWJzdHJpbmcoc3RhcnQsIGVuZCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoKGxlbmd0aCA9IHMubGVuZ3RoKCkpID09IDApIHsKKyAgICAgICAgICAgIHRocm93IGludmFsaWRSZWFsKHMsIGlzRG91YmxlKTsKKyAgICAgICAgfQorCisgICAgICAgIGVuZCA9IGxlbmd0aDsKKyAgICAgICAgd2hpbGUgKGVuZCA+IDEgJiYgcy5jaGFyQXQoZW5kIC0gMSkgPT0gJzAnKSB7CisgICAgICAgICAgICAtLWVuZDsKKyAgICAgICAgfQorCisgICAgICAgIHN0YXJ0ID0gMDsKKyAgICAgICAgd2hpbGUgKHN0YXJ0IDwgZW5kIC0gMSAmJiBzLmNoYXJBdChzdGFydCkgPT0gJzAnKSB7CisgICAgICAgICAgICBzdGFydCsrOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGVuZCAhPSBsZW5ndGggfHwgc3RhcnQgIT0gMCkgeworICAgICAgICAgICAgcmVzdWx0LmUgKz0gbGVuZ3RoIC0gZW5kOworICAgICAgICAgICAgcyA9IHMuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVGhpcyBpcyBhIGhhY2sgZm9yIGh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvSEFSTU9OWS0zMjkKKyAgICAgICAgLy8gVHJpbSB0aGUgbGVuZ3RoIG9mIHZlcnkgc21hbGwgbnVtYmVycywgbmF0aXZlcyBjYW4gb25seSBoYW5kbGUgZG93bgorICAgICAgICAvLyB0byBFLTMwOQorICAgICAgICBmaW5hbCBpbnQgQVBQUk9YX01JTl9NQUdOSVRVREUgPSAtMzU5OworICAgICAgICBmaW5hbCBpbnQgTUFYX0RJR0lUUyA9IDUyOworICAgICAgICBsZW5ndGggPSBzLmxlbmd0aCgpOworICAgICAgICBpZiAobGVuZ3RoID4gTUFYX0RJR0lUUyAmJiByZXN1bHQuZSA8IEFQUFJPWF9NSU5fTUFHTklUVURFKSB7CisgICAgICAgICAgICBpbnQgZCA9IE1hdGgubWluKEFQUFJPWF9NSU5fTUFHTklUVURFIC0gKGludCkgcmVzdWx0LmUsIGxlbmd0aCAtIDEpOworICAgICAgICAgICAgcyA9IHMuc3Vic3RyaW5nKDAsIGxlbmd0aCAtIGQpOworICAgICAgICAgICAgcmVzdWx0LmUgKz0gZDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRoaXMgaXMgYSBoYWNrIGZvciBodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0hBUk1PTlktNjY0MQorICAgICAgICAvLyBUaGUgbWFnaWMgMTAyNCB3YXMgZGV0ZXJtaW5lZCBleHBlcmltZW50YWxseTsgdGhlIG1vcmUgcGxhdXNpYmxlIC0zMjQgYW5kICszMDkgd2VyZQorICAgICAgICAvLyBub3Qgc3VmZmljaWVudCB0byBwYXNzIGJvdGggb3VyIHRlc3RzIGFuZCBoYXJtb255J3MgdGVzdHMuCisgICAgICAgIGlmIChyZXN1bHQuZSA8IC0xMDI0KSB7CisgICAgICAgICAgICByZXN1bHQuemVybyA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdC5lID4gMTAyNCkgeworICAgICAgICAgICAgcmVzdWx0LmluZmluaXR5ID0gdHJ1ZTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKworICAgICAgICByZXN1bHQucyA9IHM7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLy8gUGFyc2VzICIrTmFuIiwgIk5hTiIsICItTmFuIiwgIitJbmZpbml0eSIsICJJbmZpbml0eSIsIGFuZCAiLUluZmluaXR5IiwgY2FzZS1pbnNlbnNpdGl2ZWx5LgorICAgIHByaXZhdGUgc3RhdGljIGZsb2F0IHBhcnNlTmFtZShTdHJpbmcgbmFtZSwgYm9vbGVhbiBpc0RvdWJsZSkgeworICAgICAgICAvLyBFeHBsaWNpdCBzaWduPworICAgICAgICBib29sZWFuIG5lZ2F0aXZlID0gZmFsc2U7CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgaW50IGxlbmd0aCA9IG5hbWUubGVuZ3RoKCk7CisgICAgICAgIGNoYXIgZmlyc3RDaGFyID0gbmFtZS5jaGFyQXQoaSk7CisgICAgICAgIGlmIChmaXJzdENoYXIgPT0gJy0nKSB7CisgICAgICAgICAgICBuZWdhdGl2ZSA9IHRydWU7CisgICAgICAgICAgICArK2k7CisgICAgICAgICAgICAtLWxlbmd0aDsKKyAgICAgICAgfSBlbHNlIGlmIChmaXJzdENoYXIgPT0gJysnKSB7CisgICAgICAgICAgICArK2k7CisgICAgICAgICAgICAtLWxlbmd0aDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChsZW5ndGggPT0gOCAmJiBuYW1lLnJlZ2lvbk1hdGNoZXMoZmFsc2UsIGksICJJbmZpbml0eSIsIDAsIDgpKSB7CisgICAgICAgICAgICByZXR1cm4gbmVnYXRpdmUgPyBGbG9hdC5ORUdBVElWRV9JTkZJTklUWSA6IEZsb2F0LlBPU0lUSVZFX0lORklOSVRZOworICAgICAgICB9CisgICAgICAgIGlmIChsZW5ndGggPT0gMyAmJiBuYW1lLnJlZ2lvbk1hdGNoZXMoZmFsc2UsIGksICJOYU4iLCAwLCAzKSkgeworICAgICAgICAgICAgcmV0dXJuIEZsb2F0Lk5hTjsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBpbnZhbGlkUmVhbChuYW1lLCBpc0RvdWJsZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2xvc2VzdCBkb3VibGUgdmFsdWUgdG8gdGhlIHJlYWwgbnVtYmVyIGluIHRoZSBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIFN0cmluZyB0aGF0IHdpbGwgYmUgcGFyc2VkIHRvIGEgZmxvYXRpbmcgcG9pbnQKKyAgICAgKiBAcmV0dXJuIHRoZSBkb3VibGUgY2xvc2VzdCB0byB0aGUgcmVhbCBudW1iZXIKKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gTnVtYmVyRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIFN0cmluZyBkb2Vzbid0IHJlcHJlc2VudCBhIGRvdWJsZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHBhcnNlRG91YmxlKFN0cmluZyBzKSB7CisgICAgICAgIHMgPSBzLnRyaW0oKTsKKyAgICAgICAgaW50IGxlbmd0aCA9IHMubGVuZ3RoKCk7CisKKyAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBpbnZhbGlkUmVhbChzLCB0cnVlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFNlZSBpZiB0aGlzIGNvdWxkIGJlIGEgbmFtZWQgZG91YmxlCisgICAgICAgIGNoYXIgbGFzdCA9IHMuY2hhckF0KGxlbmd0aCAtIDEpOworICAgICAgICBpZiAobGFzdCA9PSAneScgfHwgbGFzdCA9PSAnTicpIHsKKyAgICAgICAgICAgIHJldHVybiBwYXJzZU5hbWUocywgdHJ1ZSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBTZWUgaWYgaXQgY291bGQgYmUgYSBoZXhhZGVjaW1hbCByZXByZXNlbnRhdGlvbi4KKyAgICAgICAgLy8gV2UgZG9uJ3QgdXNlIHN0YXJ0c1dpdGggYmVjYXVzZSB0aGVyZSBtaWdodCBiZSBhIGxlYWRpbmcgc2lnbi4KKyAgICAgICAgaWYgKHMuaW5kZXhPZigiMHgiKSAhPSAtMSB8fCBzLmluZGV4T2YoIjBYIikgIT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiBIZXhTdHJpbmdQYXJzZXIucGFyc2VEb3VibGUocyk7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdFeHBvbmVudFBhaXIgaW5mbyA9IGluaXRpYWxQYXJzZShzLCBsZW5ndGgsIHRydWUpOworICAgICAgICBpZiAoaW5mby5pbmZpbml0eSB8fCBpbmZvLnplcm8pIHsKKyAgICAgICAgICAgIHJldHVybiBpbmZvLnNwZWNpYWxWYWx1ZSgpOworICAgICAgICB9CisgICAgICAgIGRvdWJsZSByZXN1bHQgPSBwYXJzZURibEltcGwoaW5mby5zLCAoaW50KSBpbmZvLmUpOworICAgICAgICBpZiAoRG91YmxlLmRvdWJsZVRvUmF3TG9uZ0JpdHMocmVzdWx0KSA9PSAweGZmZmZmZmZmZmZmZmZmZmZMKSB7CisgICAgICAgICAgICB0aHJvdyBpbnZhbGlkUmVhbChzLCB0cnVlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW5mby5uZWdhdGl2ZSA/IC1yZXN1bHQgOiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2xvc2VzdCBmbG9hdCB2YWx1ZSB0byB0aGUgcmVhbCBudW1iZXIgaW4gdGhlIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgU3RyaW5nIHRoYXQgd2lsbCBiZSBwYXJzZWQgdG8gYSBmbG9hdGluZyBwb2ludAorICAgICAqIEByZXR1cm4gdGhlIGZsb2F0IGNsb3Nlc3QgdG8gdGhlIHJlYWwgbnVtYmVyCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIE51bWJlckZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSBTdHJpbmcgZG9lc24ndCByZXByZXNlbnQgYSBmbG9hdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmxvYXQgcGFyc2VGbG9hdChTdHJpbmcgcykgeworICAgICAgICBzID0gcy50cmltKCk7CisgICAgICAgIGludCBsZW5ndGggPSBzLmxlbmd0aCgpOworCisgICAgICAgIGlmIChsZW5ndGggPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgaW52YWxpZFJlYWwocywgZmFsc2UpOworICAgICAgICB9CisKKyAgICAgICAgLy8gU2VlIGlmIHRoaXMgY291bGQgYmUgYSBuYW1lZCBmbG9hdAorICAgICAgICBjaGFyIGxhc3QgPSBzLmNoYXJBdChsZW5ndGggLSAxKTsKKyAgICAgICAgaWYgKGxhc3QgPT0gJ3knIHx8IGxhc3QgPT0gJ04nKSB7CisgICAgICAgICAgICByZXR1cm4gcGFyc2VOYW1lKHMsIGZhbHNlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFNlZSBpZiBpdCBjb3VsZCBiZSBhIGhleGFkZWNpbWFsIHJlcHJlc2VudGF0aW9uCisgICAgICAgIC8vIFdlIGRvbid0IHVzZSBzdGFydHNXaXRoIGJlY2F1c2UgdGhlcmUgbWlnaHQgYmUgYSBsZWFkaW5nIHNpZ24uCisgICAgICAgIGlmIChzLmluZGV4T2YoIjB4IikgIT0gLTEgfHwgcy5pbmRleE9mKCIwWCIpICE9IC0xKSB7CisgICAgICAgICAgICByZXR1cm4gSGV4U3RyaW5nUGFyc2VyLnBhcnNlRmxvYXQocyk7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdFeHBvbmVudFBhaXIgaW5mbyA9IGluaXRpYWxQYXJzZShzLCBsZW5ndGgsIGZhbHNlKTsKKyAgICAgICAgaWYgKGluZm8uaW5maW5pdHkgfHwgaW5mby56ZXJvKSB7CisgICAgICAgICAgICByZXR1cm4gaW5mby5zcGVjaWFsVmFsdWUoKTsKKyAgICAgICAgfQorICAgICAgICBmbG9hdCByZXN1bHQgPSBwYXJzZUZsdEltcGwoaW5mby5zLCAoaW50KSBpbmZvLmUpOworICAgICAgICBpZiAoRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMocmVzdWx0KSA9PSAweGZmZmZmZmZmKSB7CisgICAgICAgICAgICB0aHJvdyBpbnZhbGlkUmVhbChzLCBmYWxzZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGluZm8ubmVnYXRpdmUgPyAtcmVzdWx0IDogcmVzdWx0OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvU3VwcHJlc3NXYXJuaW5ncy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TdXBwcmVzc1dhcm5pbmdzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjRjYjBmYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvU3VwcHJlc3NXYXJuaW5ncy5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CisKKy8qKgorICogQW5ub3RhdGlvbiB0eXBlIHVzZWQgdG8gaW5kaWNhdGUgdGhhdCB0aGUgY29tcGlsZXIgc2hvdWxkIG5vdCBpc3N1ZSB0aGUKKyAqIHNwZWNpZmllZCB3YXJuaW5ncyBmb3IgdGhlIG1hcmtlZCBwcm9ncmFtIGVsZW1lbnQuIFdhcm5pbmdzIGFyZSBub3Qgb25seQorICogc3VwcHJlc3NlZCBmb3IgdGhlIGFubm90YXRlZCBlbGVtZW50IGJ1dCBhbHNvIGZvciBhbGwgcHJvZ3JhbSBlbGVtZW50cworICogY29udGFpbmVkIGluIHRoYXQgZWxlbWVudC4KKyAqIDxwPgorICogSXQgaXMgcmVjb21tZW5kZWQgdGhhdCBwcm9ncmFtbWVycyBhbHdheXMgdXNlIHRoaXMgYW5ub3RhdGlvbiBvbiB0aGUgbW9zdAorICogZGVlcGx5IG5lc3RlZCBlbGVtZW50IHdoZXJlIGl0IGlzIGFjdHVhbGx5IG5lZWRlZC4KKyAqCisgKiBAc2luY2UgMS41CisgKi8KK0BUYXJnZXQoIHsgRWxlbWVudFR5cGUuVFlQRSwgRWxlbWVudFR5cGUuRklFTEQsIEVsZW1lbnRUeXBlLk1FVEhPRCwKKyAgICAgICAgRWxlbWVudFR5cGUuUEFSQU1FVEVSLCBFbGVtZW50VHlwZS5DT05TVFJVQ1RPUiwKKyAgICAgICAgRWxlbWVudFR5cGUuTE9DQUxfVkFSSUFCTEUgfSkKK0BSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlNPVVJDRSkKK3B1YmxpYyBAaW50ZXJmYWNlIFN1cHByZXNzV2FybmluZ3MgeworCisgICAgLyoqCisgICAgICogVGhlIGxpc3Qgb2Ygd2FybmluZ3MgYSBjb21waWxlciBzaG91bGQgbm90IGlzc3VlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSB2YWx1ZSgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9TeXN0ZW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvU3lzdGVtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzY1ZWJiYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvU3lzdGVtLmphdmEKQEAgLTAsMCArMSw2ODYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgZGFsdmlrLnN5c3RlbS5WTVJ1bnRpbWU7CitpbXBvcnQgZGFsdmlrLnN5c3RlbS5WTVN0YWNrOworaW1wb3J0IGphdmEuaW8uQ29uc29sZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QcmludFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5DaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLnNwaS5TZWxlY3RvclByb3ZpZGVyOworaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGxpYmNvcmUuaWN1LklDVTsKK2ltcG9ydCBsaWJjb3JlLmlvLkxpYmNvcmU7CitpbXBvcnQgbGliY29yZS5pby5TdHJ1Y3RVdHNuYW1lOworaW1wb3J0IGxpYmNvcmUudXRpbC5ab25lSW5mb0RCOworCisvKioKKyAqIFByb3ZpZGVzIGFjY2VzcyB0byBzeXN0ZW0tcmVsYXRlZCBpbmZvcm1hdGlvbiBhbmQgcmVzb3VyY2VzIGluY2x1ZGluZworICogc3RhbmRhcmQgaW5wdXQgYW5kIG91dHB1dC4gRW5hYmxlcyBjbGllbnRzIHRvIGR5bmFtaWNhbGx5IGxvYWQgbmF0aXZlCisgKiBsaWJyYXJpZXMuIEFsbCBtZXRob2RzIG9mIHRoaXMgY2xhc3MgYXJlIGFjY2Vzc2VkIGluIGEgc3RhdGljIHdheSBhbmQgdGhlCisgKiBjbGFzcyBpdHNlbGYgY2FuIG5vdCBiZSBpbnN0YW50aWF0ZWQuCisgKgorICogQHNlZSBSdW50aW1lCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTeXN0ZW0geworCisgICAgLyoqCisgICAgICogRGVmYXVsdCBpbnB1dCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBJbnB1dFN0cmVhbSBpbjsKKworICAgIC8qKgorICAgICAqIERlZmF1bHQgb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFByaW50U3RyZWFtIG91dDsKKworICAgIC8qKgorICAgICAqIERlZmF1bHQgZXJyb3Igb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFByaW50U3RyZWFtIGVycjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBsaW5lU2VwYXJhdG9yOworICAgIHByaXZhdGUgc3RhdGljIFByb3BlcnRpZXMgc3lzdGVtUHJvcGVydGllczsKKworICAgIHN0YXRpYyB7CisgICAgICAgIC8vIFRPRE86IGFsbCB0aHJlZSBzdHJlYW1zIGFyZSBidWZmZXJlZCBpbiBIYXJtb255LgorICAgICAgICBlcnIgPSBuZXcgUHJpbnRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oRmlsZURlc2NyaXB0b3IuZXJyKSk7CisgICAgICAgIG91dCA9IG5ldyBQcmludFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShGaWxlRGVzY3JpcHRvci5vdXQpKTsKKyAgICAgICAgaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKEZpbGVEZXNjcmlwdG9yLmluKTsKKyAgICAgICAgbGluZVNlcGFyYXRvciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgibGluZS5zZXBhcmF0b3IiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzdGFuZGFyZCBpbnB1dCBzdHJlYW0gdG8gdGhlIGdpdmVuIHVzZXIgZGVmaW5lZCBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3SW4KKyAgICAgKiAgICAgICAgICAgIHRoZSB1c2VyIGRlZmluZWQgaW5wdXQgc3RyZWFtIHRvIHNldCBhcyB0aGUgc3RhbmRhcmQgaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0SW4oSW5wdXRTdHJlYW0gbmV3SW4pIHsKKyAgICAgICAgc2V0RmllbGRJbXBsKCJpbiIsICJMamF2YS9pby9JbnB1dFN0cmVhbTsiLCBuZXdJbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc3RhbmRhcmQgb3V0cHV0IHN0cmVhbSB0byB0aGUgZ2l2ZW4gdXNlciBkZWZpbmVkIG91dHB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3T3V0CisgICAgICogICAgICAgICAgICB0aGUgdXNlciBkZWZpbmVkIG91dHB1dCBzdHJlYW0gdG8gc2V0IGFzIHRoZSBzdGFuZGFyZCBvdXRwdXQKKyAgICAgKiAgICAgICAgICAgIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0T3V0KFByaW50U3RyZWFtIG5ld091dCkgeworICAgICAgICBzZXRGaWVsZEltcGwoIm91dCIsICJMamF2YS9pby9QcmludFN0cmVhbTsiLCBuZXdPdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHN0YW5kYXJkIGVycm9yIG91dHB1dCBzdHJlYW0gdG8gdGhlIGdpdmVuIHVzZXIgZGVmaW5lZCBvdXRwdXQKKyAgICAgKiBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3RXJyCisgICAgICogICAgICAgICAgICB0aGUgdXNlciBkZWZpbmVkIG91dHB1dCBzdHJlYW0gdG8gc2V0IGFzIHRoZSBzdGFuZGFyZCBlcnJvcgorICAgICAqICAgICAgICAgICAgb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0RXJyKFByaW50U3RyZWFtIG5ld0VycikgeworICAgICAgICBzZXRGaWVsZEltcGwoImVyciIsICJMamF2YS9pby9QcmludFN0cmVhbTsiLCBuZXdFcnIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByZXZlbnRzIHRoaXMgY2xhc3MgZnJvbSBiZWluZyBpbnN0YW50aWF0ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBTeXN0ZW0oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29waWVzIHtAY29kZSBsZW5ndGh9IGVsZW1lbnRzIGZyb20gdGhlIGFycmF5IHtAY29kZSBzcmN9LAorICAgICAqIHN0YXJ0aW5nIGF0IG9mZnNldCB7QGNvZGUgc3JjUG9zfSwgaW50byB0aGUgYXJyYXkge0Bjb2RlIGRzdH0sCisgICAgICogc3RhcnRpbmcgYXQgb2Zmc2V0IHtAY29kZSBkc3RQb3N9LgorICAgICAqCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBhcnJheSB0byBjb3B5IHRoZSBjb250ZW50LgorICAgICAqIEBwYXJhbSBzcmNQb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydGluZyBpbmRleCBvZiB0aGUgY29udGVudCBpbiB7QGNvZGUgc3JjfS4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gYXJyYXkgdG8gY29weSB0aGUgZGF0YSBpbnRvLgorICAgICAqIEBwYXJhbSBkc3RQb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydGluZyBpbmRleCBmb3IgdGhlIGNvcGllZCBjb250ZW50IGluIHtAY29kZSBkc3R9LgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gYmUgY29waWVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgYXJyYXljb3B5KE9iamVjdCBzcmMsIGludCBzcmNQb3MsIE9iamVjdCBkc3QsIGludCBkc3RQb3MsIGludCBsZW5ndGgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3VycmVudCBzeXN0ZW0gdGltZSBpbiBtaWxsaXNlY29uZHMgc2luY2UgSmFudWFyeSAxLCAxOTcwCisgICAgICogMDA6MDA6MDAgVVRDLiBUaGlzIG1ldGhvZCBzaG91bGRuJ3QgYmUgdXNlZCBmb3IgbWVhc3VyaW5nIHRpbWVvdXRzIG9yCisgICAgICogb3RoZXIgZWxhcHNlZCB0aW1lIG1lYXN1cmVtZW50cywgYXMgY2hhbmdpbmcgdGhlIHN5c3RlbSB0aW1lIGNhbiBhZmZlY3QKKyAgICAgKiB0aGUgcmVzdWx0cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxvY2FsIHN5c3RlbSB0aW1lIGluIG1pbGxpc2Vjb25kcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBsb25nIGN1cnJlbnRUaW1lTWlsbGlzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHRpbWVzdGFtcCBvZiB0aGUgbW9zdCBwcmVjaXNlIHRpbWVyIGF2YWlsYWJsZSBvbiB0aGUKKyAgICAgKiBsb2NhbCBzeXN0ZW0uIFRoaXMgdGltZXN0YW1wIGNhbiBvbmx5IGJlIHVzZWQgdG8gbWVhc3VyZSBhbiBlbGFwc2VkCisgICAgICogcGVyaW9kIGJ5IGNvbXBhcmluZyBpdCBhZ2FpbnN0IGFub3RoZXIgdGltZXN0YW1wLiBJdCBjYW5ub3QgYmUgdXNlZCBhcyBhCisgICAgICogdmVyeSBleGFjdCBzeXN0ZW0gdGltZSBleHByZXNzaW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY3VycmVudCB0aW1lc3RhbXAgaW4gbmFub3NlY29uZHMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgbG9uZyBuYW5vVGltZSgpOworCisgICAgLyoqCisgICAgICogQ2F1c2VzIHRoZSBWTSB0byBzdG9wIHJ1bm5pbmcgYW5kIHRoZSBwcm9ncmFtIHRvIGV4aXQuIElmCisgICAgICoge0BsaW5rICNydW5GaW5hbGl6ZXJzT25FeGl0KGJvb2xlYW4pfSBoYXMgYmVlbiBwcmV2aW91c2x5IGludm9rZWQgd2l0aCBhCisgICAgICoge0Bjb2RlIHRydWV9IGFyZ3VtZW50LCB0aGVuIGFsbCBvYmplY3RzIHdpbGwgYmUgcHJvcGVybHkKKyAgICAgKiBnYXJiYWdlLWNvbGxlY3RlZCBhbmQgZmluYWxpemVkIGZpcnN0LgorICAgICAqCisgICAgICogQHBhcmFtIGNvZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXR1cm4gY29kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZXhpdChpbnQgY29kZSkgeworICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5leGl0KGNvZGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB0byB0aGUgVk0gdGhhdCBpdCB3b3VsZCBiZSBhIGdvb2QgdGltZSB0byBydW4gdGhlCisgICAgICogZ2FyYmFnZSBjb2xsZWN0b3IuIE5vdGUgdGhhdCB0aGlzIGlzIGEgaGludCBvbmx5LiBUaGVyZSBpcyBubyBndWFyYW50ZWUKKyAgICAgKiB0aGF0IHRoZSBnYXJiYWdlIGNvbGxlY3RvciB3aWxsIGFjdHVhbGx5IGJlIHJ1bi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZ2MoKSB7CisgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmdjKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGVudmlyb25tZW50IHZhcmlhYmxlIHdpdGggdGhlIGdpdmVuIG5hbWUge0Bjb2RlCisgICAgICogdmFyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGUuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBlbnZpcm9ubWVudCB2YXJpYWJsZSBvciB7QGNvZGUgbnVsbH0KKyAgICAgKiAgICAgICAgIGlmIG5vIHZhcmlhYmxlIGV4aXN0cyB3aXRoIHRoZSBnaXZlbiBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldGVudihTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gZ2V0ZW52KG5hbWUsIG51bGwpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRlbnYoU3RyaW5nIG5hbWUsIFN0cmluZyBkZWZhdWx0VmFsdWUpIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJuYW1lID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgdmFsdWUgPSBMaWJjb3JlLm9zLmdldGVudihuYW1lKTsKKyAgICAgICAgcmV0dXJuICh2YWx1ZSAhPSBudWxsKSA/IHZhbHVlIDogZGVmYXVsdFZhbHVlOworICAgIH0KKworICAgIC8qCisgICAgICogUmV0dXJucyBhbiBlbnZpcm9ubWVudCB2YXJpYWJsZS4gTm8gc2VjdXJpdHkgY2hlY2tzIGFyZSBwZXJmb3JtZWQuCisgICAgICogQHBhcmFtIHZhciB0aGUgbmFtZSBvZiB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGUKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGVudmlyb25tZW50IHZhcmlhYmxlCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIFN0cmluZyBnZXRFbnZCeU5hbWUoU3RyaW5nIG5hbWUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiB1bm1vZGlmaWFibGUgbWFwIG9mIGFsbCBhdmFpbGFibGUgZW52aXJvbm1lbnQgdmFyaWFibGVzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWFwIHJlcHJlc2VudGluZyBhbGwgZW52aXJvbm1lbnQgdmFyaWFibGVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTWFwPFN0cmluZywgU3RyaW5nPiBnZXRlbnYoKSB7CisgICAgICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gbWFwID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgICAgIGZvciAoU3RyaW5nIGVudHJ5IDogTGliY29yZS5vcy5lbnZpcm9uKCkpIHsKKyAgICAgICAgICAgIGludCBpbmRleCA9IGVudHJ5LmluZGV4T2YoJz0nKTsKKyAgICAgICAgICAgIGlmIChpbmRleCAhPSAtMSkgeworICAgICAgICAgICAgICAgIG1hcC5wdXQoZW50cnkuc3Vic3RyaW5nKDAsIGluZGV4KSwgZW50cnkuc3Vic3RyaW5nKGluZGV4ICsgMSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU3lzdGVtRW52aXJvbm1lbnQobWFwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmhlcml0ZWQgY2hhbm5lbCBmcm9tIHRoZSBjcmVhdG9yIG9mIHRoZSBjdXJyZW50IHZpcnR1YWwKKyAgICAgKiBtYWNoaW5lLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaW5oZXJpdGVkIHtAbGluayBDaGFubmVsfSBvciB7QGNvZGUgbnVsbH0gaWYgbm9uZSBleGlzdHMuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnJlZC4KKyAgICAgKiBAc2VlIFNlbGVjdG9yUHJvdmlkZXIKKyAgICAgKiBAc2VlIFNlbGVjdG9yUHJvdmlkZXIjaW5oZXJpdGVkQ2hhbm5lbCgpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDaGFubmVsIGluaGVyaXRlZENoYW5uZWwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gU2VsZWN0b3JQcm92aWRlci5wcm92aWRlcigpLmluaGVyaXRlZENoYW5uZWwoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzeXN0ZW0gcHJvcGVydGllcy4gTm90ZSB0aGF0IHRoaXMgaXMgbm90IGEgY29weSwgc28gdGhhdAorICAgICAqIGNoYW5nZXMgbWFkZSB0byB0aGUgcmV0dXJuZWQgUHJvcGVydGllcyBvYmplY3Qgd2lsbCBiZSByZWZsZWN0ZWQgaW4KKyAgICAgKiBzdWJzZXF1ZW50IGNhbGxzIHRvIGdldFByb3BlcnR5IGFuZCBnZXRQcm9wZXJ0aWVzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3lzdGVtIHByb3BlcnRpZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBQcm9wZXJ0aWVzIGdldFByb3BlcnRpZXMoKSB7CisgICAgICAgIGlmIChzeXN0ZW1Qcm9wZXJ0aWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIGluaXRTeXN0ZW1Qcm9wZXJ0aWVzKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN5c3RlbVByb3BlcnRpZXM7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBpbml0U3lzdGVtUHJvcGVydGllcygpIHsKKyAgICAgICAgVk1SdW50aW1lIHJ1bnRpbWUgPSBWTVJ1bnRpbWUuZ2V0UnVudGltZSgpOworICAgICAgICBQcm9wZXJ0aWVzIHAgPSBuZXcgUHJvcGVydGllcygpOworCisgICAgICAgIFN0cmluZyBwcm9qZWN0VXJsID0gImh0dHA6Ly93d3cuYW5kcm9pZC5jb20vIjsKKyAgICAgICAgU3RyaW5nIHByb2plY3ROYW1lID0gIlRoZSBBbmRyb2lkIFByb2plY3QiOworCisgICAgICAgIHAucHV0KCJqYXZhLmJvb3QuY2xhc3MucGF0aCIsIHJ1bnRpbWUuYm9vdENsYXNzUGF0aCgpKTsKKyAgICAgICAgcC5wdXQoImphdmEuY2xhc3MucGF0aCIsIHJ1bnRpbWUuY2xhc3NQYXRoKCkpOworCisgICAgICAgIC8vIE5vbmUgb2YgdGhlc2UgZm91ciBhcmUgbWVhbmluZ2Z1bCBvbiBBbmRyb2lkLCBidXQgdGhlc2Uga2V5cyBhcmUgZ3VhcmFudGVlZAorICAgICAgICAvLyB0byBiZSBwcmVzZW50IGZvciBTeXN0ZW0uZ2V0UHJvcGVydHkuIEZvciBqYXZhLmNsYXNzLnZlcnNpb24sIHdlIHVzZSB0aGUgbWF4aW11bQorICAgICAgICAvLyBjbGFzcyBmaWxlIHZlcnNpb24gdGhhdCBkeCBjdXJyZW50bHkgc3VwcG9ydHMuCisgICAgICAgIHAucHV0KCJqYXZhLmNsYXNzLnZlcnNpb24iLCAiNTAuMCIpOworICAgICAgICBwLnB1dCgiamF2YS5jb21waWxlciIsICIiKTsKKyAgICAgICAgcC5wdXQoImphdmEuZXh0LmRpcnMiLCAiIik7CisgICAgICAgIHAucHV0KCJqYXZhLnZlcnNpb24iLCAiMCIpOworCisgICAgICAgIHAucHV0KCJqYXZhLmhvbWUiLCBnZXRlbnYoIkpBVkFfSE9NRSIsICIvc3lzdGVtIikpOworCisgICAgICAgIHAucHV0KCJqYXZhLmlvLnRtcGRpciIsICIvdG1wIik7CisgICAgICAgIHAucHV0KCJqYXZhLmxpYnJhcnkucGF0aCIsIGdldGVudigiTERfTElCUkFSWV9QQVRIIikpOworCisgICAgICAgIHAucHV0KCJqYXZhLnNwZWNpZmljYXRpb24ubmFtZSIsICJEYWx2aWsgQ29yZSBMaWJyYXJ5Iik7CisgICAgICAgIHAucHV0KCJqYXZhLnNwZWNpZmljYXRpb24udmVuZG9yIiwgcHJvamVjdE5hbWUpOworICAgICAgICBwLnB1dCgiamF2YS5zcGVjaWZpY2F0aW9uLnZlcnNpb24iLCAiMC45Iik7CisKKyAgICAgICAgcC5wdXQoImphdmEudmVuZG9yIiwgcHJvamVjdE5hbWUpOworICAgICAgICBwLnB1dCgiamF2YS52ZW5kb3IudXJsIiwgcHJvamVjdFVybCk7CisgICAgICAgIHAucHV0KCJqYXZhLnZtLm5hbWUiLCAiRGFsdmlrIik7CisgICAgICAgIHAucHV0KCJqYXZhLnZtLnNwZWNpZmljYXRpb24ubmFtZSIsICJEYWx2aWsgVmlydHVhbCBNYWNoaW5lIFNwZWNpZmljYXRpb24iKTsKKyAgICAgICAgcC5wdXQoImphdmEudm0uc3BlY2lmaWNhdGlvbi52ZW5kb3IiLCBwcm9qZWN0TmFtZSk7CisgICAgICAgIHAucHV0KCJqYXZhLnZtLnNwZWNpZmljYXRpb24udmVyc2lvbiIsICIwLjkiKTsKKyAgICAgICAgcC5wdXQoImphdmEudm0udmVuZG9yIiwgcHJvamVjdE5hbWUpOworICAgICAgICBwLnB1dCgiamF2YS52bS52ZXJzaW9uIiwgcnVudGltZS52bVZlcnNpb24oKSk7CisKKyAgICAgICAgcC5wdXQoImZpbGUuc2VwYXJhdG9yIiwgIi8iKTsKKyAgICAgICAgcC5wdXQoImxpbmUuc2VwYXJhdG9yIiwgIlxuIik7CisgICAgICAgIHAucHV0KCJwYXRoLnNlcGFyYXRvciIsICI6Iik7CisKKyAgICAgICAgcC5wdXQoImphdmEucnVudGltZS5uYW1lIiwgIkFuZHJvaWQgUnVudGltZSIpOworICAgICAgICBwLnB1dCgiamF2YS5ydW50aW1lLnZlcnNpb24iLCAiMC45Iik7CisgICAgICAgIHAucHV0KCJqYXZhLnZtLnZlbmRvci51cmwiLCBwcm9qZWN0VXJsKTsKKworICAgICAgICBwLnB1dCgiZmlsZS5lbmNvZGluZyIsICJVVEYtOCIpOworICAgICAgICBwLnB1dCgidXNlci5sYW5ndWFnZSIsICJlbiIpOworICAgICAgICBwLnB1dCgidXNlci5yZWdpb24iLCAiVVMiKTsKKworICAgICAgICBwLnB1dCgidXNlci5ob21lIiwgZ2V0ZW52KCJIT01FIiwgIiIpKTsKKyAgICAgICAgcC5wdXQoInVzZXIubmFtZSIsIGdldGVudigiVVNFUiIsICIiKSk7CisKKyAgICAgICAgU3RydWN0VXRzbmFtZSBpbmZvID0gTGliY29yZS5vcy51bmFtZSgpOworICAgICAgICBwLnB1dCgib3MuYXJjaCIsIGluZm8ubWFjaGluZSk7CisgICAgICAgIHAucHV0KCJvcy5uYW1lIiwgaW5mby5zeXNuYW1lKTsKKyAgICAgICAgcC5wdXQoIm9zLnZlcnNpb24iLCBpbmZvLnJlbGVhc2UpOworCisgICAgICAgIC8vIFVuZG9jdW1lbnRlZCBBbmRyb2lkLW9ubHkgcHJvcGVydGllcy4KKyAgICAgICAgcC5wdXQoImFuZHJvaWQuaWN1LmxpYnJhcnkudmVyc2lvbiIsIElDVS5nZXRJY3VWZXJzaW9uKCkpOworICAgICAgICBwLnB1dCgiYW5kcm9pZC5pY3UudW5pY29kZS52ZXJzaW9uIiwgSUNVLmdldFVuaWNvZGVWZXJzaW9uKCkpOworICAgICAgICAvLyBUT0RPOiBpdCB3b3VsZCBiZSBuaWNlIHRvIGhhdmUgdGhpcyBidXQgY3VycmVudGx5IGl0IGNhdXNlcyBjaXJjdWxhcml0eS4KKyAgICAgICAgLy8gcC5wdXQoImFuZHJvaWQudHpkYXRhLnZlcnNpb24iLCBab25lSW5mb0RCLmdldFZlcnNpb24oKSk7CisgICAgICAgIHBhcnNlUHJvcGVydHlBc3NpZ25tZW50cyhwLCBzcGVjaWFsUHJvcGVydGllcygpKTsKKworICAgICAgICAvLyBPdmVycmlkZSBidWlsdC1pbiBwcm9wZXJ0aWVzIHdpdGggc2V0dGluZ3MgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorICAgICAgICBwYXJzZVByb3BlcnR5QXNzaWdubWVudHMocCwgcnVudGltZS5wcm9wZXJ0aWVzKCkpOworCisgICAgICAgIHN5c3RlbVByb3BlcnRpZXMgPSBwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgImtleT12YWx1ZSIgc3RyaW5ncyBjb250YWluaW5nIGluZm9ybWF0aW9uIG5vdCBvdGhlcndpc2UKKyAgICAgKiBlYXNpbHkgYXZhaWxhYmxlLCBzdWNoIGFzICNkZWZpbmVkIGxpYnJhcnkgdmVyc2lvbnMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIFN0cmluZ1tdIHNwZWNpYWxQcm9wZXJ0aWVzKCk7CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGVhY2ggZWxlbWVudCBvZiAnYXNzaWdubWVudHMnIHRvICdwJywgdHJlYXRpbmcgZWFjaCBlbGVtZW50IGFzIGFuCisgICAgICogYXNzaWdubWVudCBpbiB0aGUgZm9ybSAia2V5PXZhbHVlIi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHBhcnNlUHJvcGVydHlBc3NpZ25tZW50cyhQcm9wZXJ0aWVzIHAsIFN0cmluZ1tdIGFzc2lnbm1lbnRzKSB7CisgICAgICAgIGZvciAoU3RyaW5nIGFzc2lnbm1lbnQgOiBhc3NpZ25tZW50cykgeworICAgICAgICAgICAgaW50IHNwbGl0ID0gYXNzaWdubWVudC5pbmRleE9mKCc9Jyk7CisgICAgICAgICAgICBTdHJpbmcga2V5ID0gYXNzaWdubWVudC5zdWJzdHJpbmcoMCwgc3BsaXQpOworICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gYXNzaWdubWVudC5zdWJzdHJpbmcoc3BsaXQgKyAxKTsKKyAgICAgICAgICAgIHAucHV0KGtleSwgdmFsdWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBwYXJ0aWN1bGFyIHN5c3RlbSBwcm9wZXJ0eSBvciB7QGNvZGUgbnVsbH0gaWYgbm8KKyAgICAgKiBzdWNoIHByb3BlcnR5IGV4aXN0cy4KKyAgICAgKgorICAgICAqIDxwPlRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBhcmUgYWx3YXlzIHByb3ZpZGVkIGJ5IHRoZSBEYWx2aWsgVk06CisgICAgICogPHA+PHRhYmxlIEJPUkRFUj0iMSIgV0lEVEg9IjEwMCUiIENFTExQQURESU5HPSIzIiBDRUxMU1BBQ0lORz0iMCIgU1VNTUFSWT0iIj4KKyAgICAgKiA8dHIgQkdDT0xPUj0iI0NDQ0NGRiIgQ0xBU1M9IlRhYmxlSGVhZGluZ0NvbG9yIj4KKyAgICAgKiAgICAgPHRkPjxiPk5hbWU8L2I+PC90ZD4gICAgICAgIDx0ZD48Yj5NZWFuaW5nPC9iPjwvdGQ+ICAgICAgICAgICAgICAgICAgICA8dGQ+PGI+RXhhbXBsZTwvYj48L3RkPjwvdHI+CisgICAgICogPHRyPjx0ZD5maWxlLnNlcGFyYXRvcjwvdGQ+ICAgICA8dGQ+e0BsaW5rIGphdmEuaW8uRmlsZSNzZXBhcmF0b3J9PC90ZD4gICAgPHRkPntAY29kZSAvfTwvdGQ+PC90cj4KKyAgICAgKgorICAgICAqIDx0cj48dGQ+amF2YS5jbGFzcy5wYXRoPC90ZD4gICAgPHRkPlN5c3RlbSBjbGFzcyBwYXRoPC90ZD4gICAgICAgICAgICAgICAgIDx0ZD57QGNvZGUgLn08L3RkPjwvdHI+CisgICAgICogPHRyPjx0ZD5qYXZhLmNsYXNzLnZlcnNpb248L3RkPiA8dGQ+KE5vdCB1c2VmdWwgb24gQW5kcm9pZCk8L3RkPiAgICAgICAgICAgPHRkPntAY29kZSA1MC4wfTwvdGQ+PC90cj4KKyAgICAgKiA8dHI+PHRkPmphdmEuY29tcGlsZXI8L3RkPiAgICAgIDx0ZD4oTm90IHVzZWZ1bCBvbiBBbmRyb2lkKTwvdGQ+ICAgICAgICAgICA8dGQ+RW1wdHk8L3RkPjwvdHI+CisgICAgICogPHRyPjx0ZD5qYXZhLmV4dC5kaXJzPC90ZD4gICAgICA8dGQ+KE5vdCB1c2VmdWwgb24gQW5kcm9pZCk8L3RkPiAgICAgICAgICAgPHRkPkVtcHR5PC90ZD48L3RyPgorICAgICAqIDx0cj48dGQ+amF2YS5ob21lPC90ZD4gICAgICAgICAgPHRkPkxvY2F0aW9uIG9mIHRoZSBWTSBvbiB0aGUgZmlsZSBzeXN0ZW08L3RkPiA8dGQ+e0Bjb2RlIC9zeXN0ZW19PC90ZD48L3RyPgorICAgICAqIDx0cj48dGQ+amF2YS5pby50bXBkaXI8L3RkPiAgICAgPHRkPlNlZSB7QGxpbmsgamF2YS5pby5GaWxlI2NyZWF0ZVRlbXBGaWxlfTwvdGQ+IDx0ZD57QGNvZGUgL3NkY2FyZH08L3RkPjwvdHI+CisgICAgICogPHRyPjx0ZD5qYXZhLmxpYnJhcnkucGF0aDwvdGQ+ICA8dGQ+U2VhcmNoIHBhdGggZm9yIEpOSSBsaWJyYXJpZXM8L3RkPiAgICAgPHRkPntAY29kZSAvc3lzdGVtL2xpYn08L3RkPjwvdHI+CisgICAgICogPHRyPjx0ZD5qYXZhLnZlbmRvcjwvdGQ+ICAgICAgICA8dGQ+SHVtYW4tcmVhZGFibGUgVk0gdmVuZG9yPC90ZD4gICAgICAgICAgPHRkPntAY29kZSBUaGUgQW5kcm9pZCBQcm9qZWN0fTwvdGQ+PC90cj4KKyAgICAgKiA8dHI+PHRkPmphdmEudmVuZG9yLnVybDwvdGQ+ICAgIDx0ZD5VUkwgZm9yIFZNIHZlbmRvcidzIHdlYiBzaXRlPC90ZD4gICAgICA8dGQ+e0Bjb2RlIGh0dHA6Ly93d3cuYW5kcm9pZC5jb20vfTwvdGQ+PC90cj4KKyAgICAgKiA8dHI+PHRkPmphdmEudmVyc2lvbjwvdGQ+ICAgICAgIDx0ZD4oTm90IHVzZWZ1bCBvbiBBbmRyb2lkKTwvdGQ+ICAgICAgICAgICA8dGQ+e0Bjb2RlIDB9PC90ZD48L3RyPgorICAgICAqCisgICAgICogPHRyPjx0ZD5qYXZhLnNwZWNpZmljYXRpb24udmVyc2lvbjwvdGQ+ICAgIDx0ZD5WTSBsaWJyYXJpZXMgdmVyc2lvbjwvdGQ+ICAgICAgICA8dGQ+e0Bjb2RlIDAuOX08L3RkPjwvdHI+CisgICAgICogPHRyPjx0ZD5qYXZhLnNwZWNpZmljYXRpb24udmVuZG9yPC90ZD4gICAgIDx0ZD5WTSBsaWJyYXJpZXMgdmVuZG9yPC90ZD4gICAgICAgICA8dGQ+e0Bjb2RlIFRoZSBBbmRyb2lkIFByb2plY3R9PC90ZD48L3RyPgorICAgICAqIDx0cj48dGQ+amF2YS5zcGVjaWZpY2F0aW9uLm5hbWU8L3RkPiAgICAgICA8dGQ+Vk0gbGlicmFyaWVzIG5hbWU8L3RkPiAgICAgICAgICAgPHRkPntAY29kZSBEYWx2aWsgQ29yZSBMaWJyYXJ5fTwvdGQ+PC90cj4KKyAgICAgKiA8dHI+PHRkPmphdmEudm0udmVyc2lvbjwvdGQ+ICAgICAgICAgICAgICAgPHRkPlZNIGltcGxlbWVudGF0aW9uIHZlcnNpb248L3RkPiAgIDx0ZD57QGNvZGUgMS4yLjB9PC90ZD48L3RyPgorICAgICAqIDx0cj48dGQ+amF2YS52bS52ZW5kb3I8L3RkPiAgICAgICAgICAgICAgICA8dGQ+Vk0gaW1wbGVtZW50YXRpb24gdmVuZG9yPC90ZD4gICAgPHRkPntAY29kZSBUaGUgQW5kcm9pZCBQcm9qZWN0fTwvdGQ+PC90cj4KKyAgICAgKiA8dHI+PHRkPmphdmEudm0ubmFtZTwvdGQ+ICAgICAgICAgICAgICAgICAgPHRkPlZNIGltcGxlbWVudGF0aW9uIG5hbWU8L3RkPiAgICAgIDx0ZD57QGNvZGUgRGFsdmlrfTwvdGQ+PC90cj4KKyAgICAgKiA8dHI+PHRkPmphdmEudm0uc3BlY2lmaWNhdGlvbi52ZXJzaW9uPC90ZD4gPHRkPlZNIHNwZWNpZmljYXRpb24gdmVyc2lvbjwvdGQ+ICAgIDx0ZD57QGNvZGUgMC45fTwvdGQ+PC90cj4KKyAgICAgKiA8dHI+PHRkPmphdmEudm0uc3BlY2lmaWNhdGlvbi52ZW5kb3I8L3RkPiAgPHRkPlZNIHNwZWNpZmljYXRpb24gdmVuZG9yPC90ZD4gICAgIDx0ZD57QGNvZGUgVGhlIEFuZHJvaWQgUHJvamVjdH08L3RkPjwvdHI+CisgICAgICogPHRyPjx0ZD5qYXZhLnZtLnNwZWNpZmljYXRpb24ubmFtZTwvdGQ+ICAgIDx0ZD5WTSBzcGVjaWZpY2F0aW9uIG5hbWU8L3RkPiAgICAgICA8dGQ+e0Bjb2RlIERhbHZpayBWaXJ0dWFsIE1hY2hpbmUgU3BlY2lmaWNhdGlvbn08L3RkPjwvdHI+CisgICAgICoKKyAgICAgKiA8dHI+PHRkPmxpbmUuc2VwYXJhdG9yPC90ZD4gICAgIDx0ZD5UaGUgc3lzdGVtIGxpbmUgc2VwYXJhdG9yPC90ZD4gICAgICAgICA8dGQ+e0Bjb2RlIFxufTwvdGQ+PC90cj4KKyAgICAgKgorICAgICAqIDx0cj48dGQ+b3MuYXJjaDwvdGQ+ICAgICAgICAgICAgPHRkPk9TIGFyY2hpdGVjdHVyZTwvdGQ+ICAgICAgICAgICAgICAgICAgIDx0ZD57QGNvZGUgYXJtdjdsfTwvdGQ+PC90cj4KKyAgICAgKiA8dHI+PHRkPm9zLm5hbWU8L3RkPiAgICAgICAgICAgIDx0ZD5PUyAoa2VybmVsKSBuYW1lPC90ZD4gICAgICAgICAgICAgICAgICA8dGQ+e0Bjb2RlIExpbnV4fTwvdGQ+PC90cj4KKyAgICAgKiA8dHI+PHRkPm9zLnZlcnNpb248L3RkPiAgICAgICAgIDx0ZD5PUyAoa2VybmVsKSB2ZXJzaW9uPC90ZD4gICAgICAgICAgICAgICA8dGQ+e0Bjb2RlIDIuNi4zMi45LWcxMDNkODQ4fTwvdGQ+PC90cj4KKyAgICAgKgorICAgICAqIDx0cj48dGQ+cGF0aC5zZXBhcmF0b3I8L3RkPiAgICAgPHRkPlNlZSB7QGxpbmsgamF2YS5pby5GaWxlI3BhdGhTZXBhcmF0b3J9PC90ZD4gPHRkPntAY29kZSA6fTwvdGQ+PC90cj4KKyAgICAgKgorICAgICAqIDx0cj48dGQ+dXNlci5kaXI8L3RkPiAgICAgICAgICAgPHRkPkJhc2Ugb2Ygbm9uLWFic29sdXRlIHBhdGhzPC90ZD4gICAgICAgIDx0ZD57QGNvZGUgL308L3RkPjwvdHI+CisgICAgICogPHRyPjx0ZD51c2VyLmhvbWU8L3RkPiAgICAgICAgICA8dGQ+KE5vdCB1c2VmdWwgb24gQW5kcm9pZCk8L3RkPiAgICAgICAgICAgPHRkPkVtcHR5PC90ZD48L3RyPgorICAgICAqIDx0cj48dGQ+dXNlci5uYW1lPC90ZD4gICAgICAgICAgPHRkPihOb3QgdXNlZnVsIG9uIEFuZHJvaWQpPC90ZD4gICAgICAgICAgIDx0ZD5FbXB0eTwvdGQ+PC90cj4KKyAgICAgKgorICAgICAqIDwvdGFibGU+CisgICAgICoKKyAgICAgKiA8cD5JdCBpcyBhIG1pc3Rha2UgdG8gdHJ5IHRvIG92ZXJyaWRlIGFueSBvZiB0aGVzZS4gRG9pbmcgc28gd2lsbCBoYXZlIHVucHJlZGljdGFibGUgcmVzdWx0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBzeXN0ZW0gcHJvcGVydHkgdG8gbG9vayB1cC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHN5c3RlbSBwcm9wZXJ0eSBvciB7QGNvZGUgbnVsbH0gaWYgdGhlCisgICAgICogICAgICAgICBwcm9wZXJ0eSBkb2Vzbid0IGV4aXN0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eU5hbWUpIHsKKyAgICAgICAgcmV0dXJuIGdldFByb3BlcnR5KHByb3BlcnR5TmFtZSwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBwYXJ0aWN1bGFyIHN5c3RlbSBwcm9wZXJ0eS4gVGhlIHtAY29kZQorICAgICAqIGRlZmF1bHRWYWx1ZX0gd2lsbCBiZSByZXR1cm5lZCBpZiBubyBzdWNoIHByb3BlcnR5IGhhcyBiZWVuIGZvdW5kLgorICAgICAqCisgICAgICogQHBhcmFtIHByb3AKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBzeXN0ZW0gcHJvcGVydHkgdG8gbG9vayB1cC4KKyAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgcmV0dXJuIHZhbHVlIGlmIHRoZSBzeXN0ZW0gcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4gbmFtZQorICAgICAqICAgICAgICAgICAgZG9lcyBub3QgZXhpc3QuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBzeXN0ZW0gcHJvcGVydHkgb3IgdGhlIHtAY29kZQorICAgICAqICAgICAgICAgZGVmYXVsdFZhbHVlfSBpZiB0aGUgcHJvcGVydHkgZG9lcyBub3QgZXhpc3QuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0UHJvcGVydHkoU3RyaW5nIHByb3AsIFN0cmluZyBkZWZhdWx0VmFsdWUpIHsKKyAgICAgICAgaWYgKHByb3AuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldFByb3BlcnRpZXMoKS5nZXRQcm9wZXJ0eShwcm9wLCBkZWZhdWx0VmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgcGFydGljdWxhciBzeXN0ZW0gcHJvcGVydHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJvcAorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHN5c3RlbSBwcm9wZXJ0eSB0byBiZSBjaGFuZ2VkLgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBnaXZlbiBwcm9wZXJ0eSB7QGNvZGUgcHJvcH0uCisgICAgICogQHJldHVybiB0aGUgb2xkIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIHByb3BlcnR5CisgICAgICogICAgICAgICBkaWRuJ3QgZXhpc3QuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgc2V0UHJvcGVydHkoU3RyaW5nIHByb3AsIFN0cmluZyB2YWx1ZSkgeworICAgICAgICBpZiAocHJvcC5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKFN0cmluZykgZ2V0UHJvcGVydGllcygpLnNldFByb3BlcnR5KHByb3AsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGEgc3BlY2lmaWMgc3lzdGVtIHByb3BlcnR5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHN5c3RlbSBwcm9wZXJ0eSB0byBiZSByZW1vdmVkLgorICAgICAqIEByZXR1cm4gdGhlIHByb3BlcnR5IHZhbHVlIG9yIHtAY29kZSBudWxsfSBpZiB0aGUgcHJvcGVydHkgZGlkbid0IGV4aXN0LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgYXJndW1lbnQge0Bjb2RlIGtleX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGFyZ3VtZW50IHtAY29kZSBrZXl9IGlzIGVtcHR5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGNsZWFyUHJvcGVydHkoU3RyaW5nIGtleSkgeworICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChrZXkuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChTdHJpbmcpIGdldFByb3BlcnRpZXMoKS5yZW1vdmUoa2V5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGxpbmsgamF2YS5pby5Db25zb2xlfSBhc3NvY2lhdGVkIHdpdGggdGhpcyBWTSwgb3IgbnVsbC4KKyAgICAgKiBOb3QgYWxsIFZNcyB3aWxsIGhhdmUgYW4gYXNzb2NpYXRlZCBjb25zb2xlLiBBIGNvbnNvbGUgaXMgdHlwaWNhbGx5IG9ubHkKKyAgICAgKiBhdmFpbGFibGUgZm9yIHByb2dyYW1zIHJ1biBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ29uc29sZSBjb25zb2xlKCkgeworICAgICAgICByZXR1cm4gQ29uc29sZS5nZXRDb25zb2xlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBudWxsLiBBbmRyb2lkIGRvZXMgbm90IHVzZSB7QGNvZGUgU2VjdXJpdHlNYW5hZ2VyfS4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBvbmx5IHByb3ZpZGVkIGZvciBzb3VyY2UgY29tcGF0aWJpbGl0eS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gbnVsbAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU2VjdXJpdHlNYW5hZ2VyIGdldFNlY3VyaXR5TWFuYWdlcigpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnRlZ2VyIGhhc2ggY29kZSBmb3IgdGhlIHBhcmFtZXRlci4gVGhlIGhhc2ggY29kZSByZXR1cm5lZCBpcworICAgICAqIHRoZSBzYW1lIG9uZSB0aGF0IHdvdWxkIGJlIHJldHVybmVkIGJ5IHRoZSBtZXRob2Qge0Bjb2RlCisgICAgICogamF2YS5sYW5nLk9iamVjdC5oYXNoQ29kZSgpfSwgd2hldGhlciBvciBub3QgdGhlIG9iamVjdCdzIGNsYXNzIGhhcworICAgICAqIG92ZXJyaWRkZW4gaGFzaENvZGUoKS4gVGhlIGhhc2ggY29kZSBmb3Ige0Bjb2RlIG51bGx9IGlzIHtAY29kZSAwfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbk9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjYWxjdWxhdGUgdGhlIGhhc2ggY29kZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUgZm9yIHRoZSBnaXZlbiBvYmplY3QuCisgICAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I2hhc2hDb2RlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IGlkZW50aXR5SGFzaENvZGUoT2JqZWN0IGFuT2JqZWN0KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN5c3RlbSdzIGxpbmUgc2VwYXJhdG9yLiBPbiBBbmRyb2lkLCB0aGlzIGlzIHtAY29kZSAiXG4ifS4gVGhlIHZhbHVlCisgICAgICogY29tZXMgZnJvbSB0aGUgdmFsdWUgb2YgdGhlIHtAY29kZSBsaW5lLnNlcGFyYXRvcn0gc3lzdGVtIHByb3BlcnR5IHdoZW4gdGhlIFZNCisgICAgICogc3RhcnRzLiBMYXRlciBjaGFuZ2VzIHRvIHRoZSBwcm9wZXJ0eSB3aWxsIG5vdCBhZmZlY3QgdGhlIHZhbHVlIHJldHVybmVkIGJ5IHRoaXMKKyAgICAgKiBtZXRob2QuCisgICAgICogQHNpbmNlIDEuNworICAgICAqIEBoaWRlIDEuNyAtIGZpeCBkb2N1bWVudGF0aW9uIHJlZmVyZW5jZXMgdG8gImxpbmUuc2VwYXJhdG9yIiBpbiBGb3JtYXR0ZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgbGluZVNlcGFyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIGxpbmVTZXBhcmF0b3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9hZHMgYW5kIGxpbmtzIHRoZSBkeW5hbWljIGxpYnJhcnkgdGhhdCBpcyBpZGVudGlmaWVkIHRocm91Z2ggdGhlCisgICAgICogc3BlY2lmaWVkIHBhdGguIFRoaXMgbWV0aG9kIGlzIHNpbWlsYXIgdG8ge0BsaW5rICNsb2FkTGlicmFyeShTdHJpbmcpfSwKKyAgICAgKiBidXQgaXQgYWNjZXB0cyBhIGZ1bGwgcGF0aCBzcGVjaWZpY2F0aW9uIHdoZXJlYXMge0Bjb2RlIGxvYWRMaWJyYXJ5fSBqdXN0CisgICAgICogYWNjZXB0cyB0aGUgbmFtZSBvZiB0aGUgbGlicmFyeSB0byBsb2FkLgorICAgICAqCisgICAgICogQHBhcmFtIHBhdGhOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcGF0aCBvZiB0aGUgZmlsZSB0byBiZSBsb2FkZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGxvYWQoU3RyaW5nIHBhdGhOYW1lKSB7CisgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmxvYWQocGF0aE5hbWUsIFZNU3RhY2suZ2V0Q2FsbGluZ0NsYXNzTG9hZGVyKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvYWRzIGFuZCBsaW5rcyB0aGUgbGlicmFyeSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS4gVGhlIG1hcHBpbmcgb2YgdGhlCisgICAgICogc3BlY2lmaWVkIGxpYnJhcnkgbmFtZSB0byB0aGUgZnVsbCBwYXRoIGZvciBsb2FkaW5nIHRoZSBsaWJyYXJ5IGlzCisgICAgICogaW1wbGVtZW50YXRpb24tZGVwZW5kZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGxpYk5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBsaWJyYXJ5IHRvIGxvYWQuCisgICAgICogQHRocm93cyBVbnNhdGlzZmllZExpbmtFcnJvcgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBsaWJyYXJ5IGNvdWxkIG5vdCBiZSBsb2FkZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGxvYWRMaWJyYXJ5KFN0cmluZyBsaWJOYW1lKSB7CisgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmxvYWRMaWJyYXJ5KGxpYk5hbWUsIFZNU3RhY2suZ2V0Q2FsbGluZ0NsYXNzTG9hZGVyKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBoaWRlIGludGVybmFsIHVzZSBvbmx5CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGxvZ0UoU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICAgICAgbG9nKCdFJywgbWVzc2FnZSwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQGhpZGUgaW50ZXJuYWwgdXNlIG9ubHkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbG9nRShTdHJpbmcgbWVzc2FnZSwgVGhyb3dhYmxlIHRoKSB7CisgICAgICAgIGxvZygnRScsIG1lc3NhZ2UsIHRoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAaGlkZSBpbnRlcm5hbCB1c2Ugb25seQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBsb2dJKFN0cmluZyBtZXNzYWdlKSB7CisgICAgICAgIGxvZygnSScsIG1lc3NhZ2UsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBoaWRlIGludGVybmFsIHVzZSBvbmx5CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGxvZ0koU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSB0aCkgeworICAgICAgICBsb2coJ0knLCBtZXNzYWdlLCB0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQGhpZGUgaW50ZXJuYWwgdXNlIG9ubHkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbG9nVyhTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICBsb2coJ1cnLCBtZXNzYWdlLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAaGlkZSBpbnRlcm5hbCB1c2Ugb25seQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBsb2dXKFN0cmluZyBtZXNzYWdlLCBUaHJvd2FibGUgdGgpIHsKKyAgICAgICAgbG9nKCdXJywgbWVzc2FnZSwgdGgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIGxvZyhjaGFyIHR5cGUsIFN0cmluZyBtZXNzYWdlLCBUaHJvd2FibGUgdGgpOworCisgICAgLyoqCisgICAgICogUHJvdmlkZXMgYSBoaW50IHRvIHRoZSBWTSB0aGF0IGl0IHdvdWxkIGJlIHVzZWZ1bCB0byBhdHRlbXB0CisgICAgICogdG8gcGVyZm9ybSBhbnkgb3V0c3RhbmRpbmcgb2JqZWN0IGZpbmFsaXphdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcnVuRmluYWxpemF0aW9uKCkgeworICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5ydW5GaW5hbGl6YXRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbnN1cmVzIHRoYXQsIHdoZW4gdGhlIFZNIGlzIGFib3V0IHRvIGV4aXQsIGFsbCBvYmplY3RzIGFyZQorICAgICAqIGZpbmFsaXplZC4gTm90ZSB0aGF0IGFsbCBmaW5hbGl6YXRpb24gd2hpY2ggb2NjdXJzIHdoZW4gdGhlIHN5c3RlbSBpcworICAgICAqIGV4aXRpbmcgaXMgcGVyZm9ybWVkIGFmdGVyIGFsbCBydW5uaW5nIHRocmVhZHMgaGF2ZSBiZWVuIHRlcm1pbmF0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmxhZworICAgICAqICAgICAgICAgICAgdGhlIGZsYWcgZGV0ZXJtaW5lcyBpZiBmaW5hbGl6YXRpb24gb24gZXhpdCBpcyBlbmFibGVkLgorICAgICAqIEBkZXByZWNhdGVkIHRoaXMgbWV0aG9kIGlzIHVuc2FmZS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHJ1bkZpbmFsaXplcnNPbkV4aXQoYm9vbGVhbiBmbGFnKSB7CisgICAgICAgIFJ1bnRpbWUucnVuRmluYWxpemVyc09uRXhpdChmbGFnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGFsbCBzeXN0ZW0gcHJvcGVydGllcy4gVGhpcyBkb2VzIG5vdCB0YWtlIGEgY29weTsgdGhlIHBhc3NlZC1pbiBvYmplY3QgaXMgdXNlZAorICAgICAqIGRpcmVjdGx5LiBQYXNzaW5nIG51bGwgY2F1c2VzIHRoZSBWTSB0byByZWluaXRpYWxpemUgdGhlIHByb3BlcnRpZXMgdG8gaG93IHRoZXkgd2VyZQorICAgICAqIHdoZW4gdGhlIFZNIHdhcyBzdGFydGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRQcm9wZXJ0aWVzKFByb3BlcnRpZXMgcCkgeworICAgICAgICBzeXN0ZW1Qcm9wZXJ0aWVzID0gcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaHJvd3Mge0Bjb2RlIFNlY3VyaXR5RXhjZXB0aW9ufS4KKyAgICAgKgorICAgICAqIDxwPlNlY3VyaXR5IG1hbmFnZXJzIGRvIDxpPm5vdDwvaT4gcHJvdmlkZSBhIHNlY3VyZSBlbnZpcm9ubWVudCBmb3IKKyAgICAgKiBleGVjdXRpbmcgdW50cnVzdGVkIGNvZGUgYW5kIGFyZSB1bnN1cHBvcnRlZCBvbiBBbmRyb2lkLiBVbnRydXN0ZWQgY29kZQorICAgICAqIGNhbm5vdCBiZSBzYWZlbHkgaXNvbGF0ZWQgd2l0aGluIGEgc2luZ2xlIFZNIG9uIEFuZHJvaWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc20gYSBzZWN1cml0eSBtYW5hZ2VyCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiBhbHdheXMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0U2VjdXJpdHlNYW5hZ2VyKFNlY3VyaXR5TWFuYWdlciBzbSkgeworICAgICAgICBpZiAoc20gIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwbGF0Zm9ybSBzcGVjaWZpYyBmaWxlIG5hbWUgZm9ybWF0IGZvciB0aGUgc2hhcmVkIGxpYnJhcnkKKyAgICAgKiBuYW1lZCBieSB0aGUgYXJndW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXNlckxpYk5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBsaWJyYXJ5IHRvIGxvb2sgdXAuCisgICAgICogQHJldHVybiB0aGUgcGxhdGZvcm0gc3BlY2lmaWMgZmlsZW5hbWUgZm9yIHRoZSBsaWJyYXJ5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIFN0cmluZyBtYXBMaWJyYXJ5TmFtZShTdHJpbmcgdXNlckxpYk5hbWUpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIG5hbWVkIHN0YXRpYyBmaWVsZCBpbiB0aGUgcmVjZWl2ZXIgdG8gdGhlIHBhc3NlZCBpbgorICAgICAqIGFyZ3VtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIHNldCwgb25lIG9mIGluLCBvdXQsIG9yIGVycgorICAgICAqIEBwYXJhbSBzdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgb2YgdGhlIGZpZWxkCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIHZvaWQgc2V0RmllbGRJbXBsKFN0cmluZyBmaWVsZE5hbWUsIFN0cmluZyBzaWduYXR1cmUsIE9iamVjdCBzdHJlYW0pOworCisKKyAgICAvKioKKyAgICAgKiBUaGUgdW5tb2RpZmlhYmxlIGVudmlyb25tZW50IHZhcmlhYmxlcyBtYXAuIFN5c3RlbS5nZXRlbnYoKSBzcGVjaWZpZXMKKyAgICAgKiB0aGF0IHRoaXMgbWFwIG11c3QgdGhyb3cgd2hlbiBwYXNzZWQgbm9uLVN0cmluZyBrZXlzLgorICAgICAqLworICAgIHN0YXRpYyBjbGFzcyBTeXN0ZW1FbnZpcm9ubWVudCBleHRlbmRzIEFic3RyYWN0TWFwPFN0cmluZywgU3RyaW5nPiB7CisgICAgICAgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBtYXA7CisKKyAgICAgICAgcHVibGljIFN5c3RlbUVudmlyb25tZW50KE1hcDxTdHJpbmcsIFN0cmluZz4gbWFwKSB7CisgICAgICAgICAgICB0aGlzLm1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChtYXApOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTZXQ8RW50cnk8U3RyaW5nLCBTdHJpbmc+PiBlbnRyeVNldCgpIHsKKyAgICAgICAgICAgIHJldHVybiBtYXAuZW50cnlTZXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIGdldChPYmplY3Qga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gbWFwLmdldCh0b05vbk51bGxTdHJpbmcoa2V5KSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnNLZXkoT2JqZWN0IGtleSkgeworICAgICAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleSh0b05vbk51bGxTdHJpbmcoa2V5KSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnNWYWx1ZShPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgICAgIHJldHVybiBtYXAuY29udGFpbnNWYWx1ZSh0b05vbk51bGxTdHJpbmcodmFsdWUpKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgU3RyaW5nIHRvTm9uTnVsbFN0cmluZyhPYmplY3QgbykgeworICAgICAgICAgICAgaWYgKG8gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIChTdHJpbmcpIG87CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1RocmVhZC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9UaHJlYWQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNjFmNjY5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9UaHJlYWQuamF2YQpAQCAtMCwwICsxLDEzMDcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgZGFsdmlrLnN5c3RlbS5WTVN0YWNrOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuRW1wdHlBcnJheTsKKworLyoqCisgKiBBIHtAY29kZSBUaHJlYWR9IGlzIGEgY29uY3VycmVudCB1bml0IG9mIGV4ZWN1dGlvbi4gSXQgaGFzIGl0cyBvd24gY2FsbCBzdGFjaworICogZm9yIG1ldGhvZHMgYmVpbmcgaW52b2tlZCwgdGhlaXIgYXJndW1lbnRzIGFuZCBsb2NhbCB2YXJpYWJsZXMuIEVhY2ggdmlydHVhbAorICogbWFjaGluZSBpbnN0YW5jZSBoYXMgYXQgbGVhc3Qgb25lIG1haW4ge0Bjb2RlIFRocmVhZH0gcnVubmluZyB3aGVuIGl0IGlzCisgKiBzdGFydGVkOyB0eXBpY2FsbHksIHRoZXJlIGFyZSBzZXZlcmFsIG90aGVycyBmb3IgaG91c2VrZWVwaW5nLiBUaGUKKyAqIGFwcGxpY2F0aW9uIG1pZ2h0IGRlY2lkZSB0byBsYXVuY2ggYWRkaXRpb25hbCB7QGNvZGUgVGhyZWFkfXMgZm9yIHNwZWNpZmljCisgKiBwdXJwb3Nlcy4KKyAqIDxwPgorICoge0Bjb2RlIFRocmVhZH1zIGluIHRoZSBzYW1lIFZNIGludGVyYWN0IGFuZCBzeW5jaHJvbml6ZSBieSB0aGUgdXNlIG9mIHNoYXJlZAorICogb2JqZWN0cyBhbmQgbW9uaXRvcnMgYXNzb2NpYXRlZCB3aXRoIHRoZXNlIG9iamVjdHMuIFN5bmNocm9uaXplZCBtZXRob2RzIGFuZAorICogcGFydCBvZiB0aGUgQVBJIGluIHtAbGluayBPYmplY3R9IGFsc28gYWxsb3cge0Bjb2RlIFRocmVhZH1zIHRvIGNvb3BlcmF0ZS4KKyAqIDxwPgorICogVGhlcmUgYXJlIGJhc2ljYWxseSB0d28gbWFpbiB3YXlzIG9mIGhhdmluZyBhIHtAY29kZSBUaHJlYWR9IGV4ZWN1dGUKKyAqIGFwcGxpY2F0aW9uIGNvZGUuIE9uZSBpcyBwcm92aWRpbmcgYSBuZXcgY2xhc3MgdGhhdCBleHRlbmRzIHtAY29kZSBUaHJlYWR9CisgKiBhbmQgb3ZlcnJpZGluZyBpdHMge0BsaW5rICNydW4oKX0gbWV0aG9kLiBUaGUgb3RoZXIgaXMgcHJvdmlkaW5nIGEgbmV3CisgKiB7QGNvZGUgVGhyZWFkfSBpbnN0YW5jZSB3aXRoIGEge0BsaW5rIFJ1bm5hYmxlfSBvYmplY3QgZHVyaW5nIGl0cyBjcmVhdGlvbi4KKyAqIEluIGJvdGggY2FzZXMsIHRoZSB7QGxpbmsgI3N0YXJ0KCl9IG1ldGhvZCBtdXN0IGJlIGNhbGxlZCB0byBhY3R1YWxseSBleGVjdXRlCisgKiB0aGUgbmV3IHtAY29kZSBUaHJlYWR9LgorICogPHA+CisgKiBFYWNoIHtAY29kZSBUaHJlYWR9IGhhcyBhbiBpbnRlZ2VyIHByaW9yaXR5IHRoYXQgYmFzaWNhbGx5IGRldGVybWluZXMgdGhlCisgKiBhbW91bnQgb2YgQ1BVIHRpbWUgdGhlIHtAY29kZSBUaHJlYWR9IGdldHMuIEl0IGNhbiBiZSBzZXQgdXNpbmcgdGhlCisgKiB7QGxpbmsgI3NldFByaW9yaXR5KGludCl9IG1ldGhvZC4gQSB7QGNvZGUgVGhyZWFkfSBjYW4gYWxzbyBiZSBtYWRlIGEgZGFlbW9uLAorICogd2hpY2ggbWFrZXMgaXQgcnVuIGluIHRoZSBiYWNrZ3JvdW5kLiBUaGUgbGF0dGVyIGFsc28gYWZmZWN0cyBWTSB0ZXJtaW5hdGlvbgorICogYmVoYXZpb3I6IHRoZSBWTSBkb2VzIG5vdCB0ZXJtaW5hdGUgYXV0b21hdGljYWxseSBhcyBsb25nIGFzIHRoZXJlIGFyZQorICogbm9uLWRhZW1vbiB0aHJlYWRzIHJ1bm5pbmcuCisgKgorICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0CisgKiBAc2VlIGphdmEubGFuZy5UaHJlYWRHcm91cAorICoKKyAqLworcHVibGljIGNsYXNzIFRocmVhZCBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTkFOT1NfUEVSX01JTExJID0gMTAwMDAwMDsKKworICAgIC8qKiBQYXJrIHN0YXRlcyAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFBhcmtTdGF0ZSB7CisgICAgICAgIC8qKiBwYXJrIHN0YXRlIGluZGljYXRpbmcgdW5wYXJrZWQgKi8KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOUEFSS0VEID0gMTsKKworICAgICAgICAvKiogcGFyayBzdGF0ZSBpbmRpY2F0aW5nIHByZWVtcHRpdmVseSB1bnBhcmtlZCAqLworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUFJFRU1QVElWRUxZX1VOUEFSS0VEID0gMjsKKworICAgICAgICAvKiogcGFyayBzdGF0ZSBpbmRpY2F0aW5nIHBhcmtlZCAqLworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUEFSS0VEID0gMzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBIHJlcHJlc2VudGF0aW9uIG9mIGEgdGhyZWFkJ3Mgc3RhdGUuIEEgZ2l2ZW4gdGhyZWFkIG1heSBvbmx5IGJlIGluIG9uZQorICAgICAqIHN0YXRlIGF0IGEgdGltZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZW51bSBTdGF0ZSB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgdGhyZWFkIGhhcyBiZWVuIGNyZWF0ZWQsIGJ1dCBoYXMgbmV2ZXIgYmVlbiBzdGFydGVkLgorICAgICAgICAgKi8KKyAgICAgICAgTkVXLAorICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHRocmVhZCBtYXkgYmUgcnVuLgorICAgICAgICAgKi8KKyAgICAgICAgUlVOTkFCTEUsCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgdGhyZWFkIGlzIGJsb2NrZWQgYW5kIHdhaXRpbmcgZm9yIGEgbG9jay4KKyAgICAgICAgICovCisgICAgICAgIEJMT0NLRUQsCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgdGhyZWFkIGlzIHdhaXRpbmcuCisgICAgICAgICAqLworICAgICAgICBXQUlUSU5HLAorICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHRocmVhZCBpcyB3YWl0aW5nIGZvciBhIHNwZWNpZmllZCBhbW91bnQgb2YgdGltZS4KKyAgICAgICAgICovCisgICAgICAgIFRJTUVEX1dBSVRJTkcsCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgdGhyZWFkIGhhcyBiZWVuIHRlcm1pbmF0ZWQuCisgICAgICAgICAqLworICAgICAgICBURVJNSU5BVEVECisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIG1heGltdW0gcHJpb3JpdHkgdmFsdWUgYWxsb3dlZCBmb3IgYSB0aHJlYWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1BSSU9SSVRZID0gMTA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWluaW11bSBwcmlvcml0eSB2YWx1ZSBhbGxvd2VkIGZvciBhIHRocmVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNSU5fUFJJT1JJVFkgPSAxOworCisgICAgLyoqCisgICAgICogVGhlIG5vcm1hbCAoZGVmYXVsdCkgcHJpb3JpdHkgdmFsdWUgYXNzaWduZWQgdG8gdGhyZWFkcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT1JNX1BSSU9SSVRZID0gNTsKKworICAgIC8qIHNvbWUgb2YgdGhlc2UgYXJlIGFjY2Vzc2VkIGRpcmVjdGx5IGJ5IHRoZSBWTTsgZG8gbm90IHJlbmFtZSB0aGVtICovCisgICAgdm9sYXRpbGUgVk1UaHJlYWQgdm1UaHJlYWQ7CisgICAgdm9sYXRpbGUgVGhyZWFkR3JvdXAgZ3JvdXA7CisgICAgdm9sYXRpbGUgYm9vbGVhbiBkYWVtb247CisgICAgdm9sYXRpbGUgU3RyaW5nIG5hbWU7CisgICAgdm9sYXRpbGUgaW50IHByaW9yaXR5OworICAgIHZvbGF0aWxlIGxvbmcgc3RhY2tTaXplOworICAgIFJ1bm5hYmxlIHRhcmdldDsKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgY291bnQgPSAwOworCisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIHRocmVhZCdzIElELiBXZSBzaW1wbHkgY291bnQgdXB3YXJkcywgc28KKyAgICAgKiBlYWNoIFRocmVhZCBoYXMgYSB1bmlxdWUgSUQuCisgICAgICovCisgICAgcHJpdmF0ZSBsb25nIGlkOworCisgICAgLyoqCisgICAgICogTm9ybWFsIHRocmVhZCBsb2NhbCB2YWx1ZXMuCisgICAgICovCisgICAgVGhyZWFkTG9jYWwuVmFsdWVzIGxvY2FsVmFsdWVzOworCisgICAgLyoqCisgICAgICogSW5oZXJpdGFibGUgdGhyZWFkIGxvY2FsIHZhbHVlcy4KKyAgICAgKi8KKyAgICBUaHJlYWRMb2NhbC5WYWx1ZXMgaW5oZXJpdGFibGVWYWx1ZXM7CisKKyAgICAvKiogQ2FsbGJhY2tzIHRvIHJ1biBvbiBpbnRlcnJ1cHRpb24uICovCisgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PFJ1bm5hYmxlPiBpbnRlcnJ1cHRBY3Rpb25zID0gbmV3IEFycmF5TGlzdDxSdW5uYWJsZT4oKTsKKworICAgIC8qKgorICAgICAqIEhvbGRzIHRoZSBjbGFzcyBsb2FkZXIgZm9yIHRoaXMgVGhyZWFkLCBpbiBjYXNlIHRoZXJlIGlzIG9uZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIENsYXNzTG9hZGVyIGNvbnRleHRDbGFzc0xvYWRlcjsKKworICAgIC8qKgorICAgICAqIEhvbGRzIHRoZSBoYW5kbGVyIGZvciB1bmNhdWdodCBleGNlcHRpb25zIGluIHRoaXMgVGhyZWFkLAorICAgICAqIGluIGNhc2UgdGhlcmUgaXMgb25lLgorICAgICAqLworICAgIHByaXZhdGUgVW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyIHVuY2F1Z2h0SGFuZGxlcjsKKworICAgIC8qKgorICAgICAqIEhvbGRzIHRoZSBkZWZhdWx0IGhhbmRsZXIgZm9yIHVuY2F1Z2h0IGV4Y2VwdGlvbnMsIGluIGNhc2UgdGhlcmUgaXMgb25lLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlciBkZWZhdWx0VW5jYXVnaHRIYW5kbGVyOworCisgICAgLyoqCisgICAgICogUmVmbGVjdHMgd2hldGhlciB0aGlzIFRocmVhZCBoYXMgYWxyZWFkeSBiZWVuIHN0YXJ0ZWQuIEEgVGhyZWFkCisgICAgICogY2FuIG9ubHkgYmUgc3RhcnRlZCBvbmNlIChubyByZWN5Y2xpbmcpLiBBbHNvLCB3ZSBuZWVkIGl0IHRvIGRlZHVjZQorICAgICAqIHRoZSBwcm9wZXIgVGhyZWFkIHN0YXR1cy4KKyAgICAgKi8KKyAgICBib29sZWFuIGhhc0JlZW5TdGFydGVkID0gZmFsc2U7CisKKyAgICAvKiogdGhlIHBhcmsgc3RhdGUgb2YgdGhlIHRocmVhZCAqLworICAgIHByaXZhdGUgaW50IHBhcmtTdGF0ZSA9IFBhcmtTdGF0ZS5VTlBBUktFRDsKKworICAgIC8qKiBUaGUgc3luY2hyb25pemF0aW9uIG9iamVjdCByZXNwb25zaWJsZSBmb3IgdGhpcyB0aHJlYWQgcGFya2luZy4gKi8KKyAgICBwcml2YXRlIE9iamVjdCBwYXJrQmxvY2tlcjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFRocmVhZH0gd2l0aCBubyB7QGNvZGUgUnVubmFibGV9IG9iamVjdCBhbmQgYQorICAgICAqIG5ld2x5IGdlbmVyYXRlZCBuYW1lLiBUaGUgbmV3IHtAY29kZSBUaHJlYWR9IHdpbGwgYmVsb25nIHRvIHRoZSBzYW1lCisgICAgICoge0Bjb2RlIFRocmVhZEdyb3VwfSBhcyB0aGUge0Bjb2RlIFRocmVhZH0gY2FsbGluZyB0aGlzIGNvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHNlZSBqYXZhLmxhbmcuVGhyZWFkR3JvdXAKKyAgICAgKiBAc2VlIGphdmEubGFuZy5SdW5uYWJsZQorICAgICAqLworICAgIHB1YmxpYyBUaHJlYWQoKSB7CisgICAgICAgIGNyZWF0ZShudWxsLCBudWxsLCBudWxsLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBUaHJlYWR9IHdpdGggYSB7QGNvZGUgUnVubmFibGV9IG9iamVjdCBhbmQgYQorICAgICAqIG5ld2x5IGdlbmVyYXRlZCBuYW1lLiBUaGUgbmV3IHtAY29kZSBUaHJlYWR9IHdpbGwgYmVsb25nIHRvIHRoZSBzYW1lCisgICAgICoge0Bjb2RlIFRocmVhZEdyb3VwfSBhcyB0aGUge0Bjb2RlIFRocmVhZH0gY2FsbGluZyB0aGlzIGNvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIHJ1bm5hYmxlCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBSdW5uYWJsZX0gd2hvc2UgbWV0aG9kIDxjb2RlPnJ1bjwvY29kZT4gd2lsbCBiZQorICAgICAqICAgICAgICAgICAgZXhlY3V0ZWQgYnkgdGhlIG5ldyB7QGNvZGUgVGhyZWFkfQorICAgICAqCisgICAgICogQHNlZSBqYXZhLmxhbmcuVGhyZWFkR3JvdXAKKyAgICAgKiBAc2VlIGphdmEubGFuZy5SdW5uYWJsZQorICAgICAqLworICAgIHB1YmxpYyBUaHJlYWQoUnVubmFibGUgcnVubmFibGUpIHsKKyAgICAgICAgY3JlYXRlKG51bGwsIHJ1bm5hYmxlLCBudWxsLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBUaHJlYWR9IHdpdGggYSB7QGNvZGUgUnVubmFibGV9IG9iamVjdCBhbmQgbmFtZQorICAgICAqIHByb3ZpZGVkLiBUaGUgbmV3IHtAY29kZSBUaHJlYWR9IHdpbGwgYmVsb25nIHRvIHRoZSBzYW1lIHtAY29kZQorICAgICAqIFRocmVhZEdyb3VwfSBhcyB0aGUge0Bjb2RlIFRocmVhZH0gY2FsbGluZyB0aGlzIGNvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIHJ1bm5hYmxlCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBSdW5uYWJsZX0gd2hvc2UgbWV0aG9kIDxjb2RlPnJ1bjwvY29kZT4gd2lsbCBiZQorICAgICAqICAgICAgICAgICAgZXhlY3V0ZWQgYnkgdGhlIG5ldyB7QGNvZGUgVGhyZWFkfQorICAgICAqIEBwYXJhbSB0aHJlYWROYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBmb3IgdGhlIHtAY29kZSBUaHJlYWR9IGJlaW5nIGNyZWF0ZWQKKyAgICAgKgorICAgICAqIEBzZWUgamF2YS5sYW5nLlRocmVhZEdyb3VwCisgICAgICogQHNlZSBqYXZhLmxhbmcuUnVubmFibGUKKyAgICAgKi8KKyAgICBwdWJsaWMgVGhyZWFkKFJ1bm5hYmxlIHJ1bm5hYmxlLCBTdHJpbmcgdGhyZWFkTmFtZSkgeworICAgICAgICBpZiAodGhyZWFkTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGNyZWF0ZShudWxsLCBydW5uYWJsZSwgdGhyZWFkTmFtZSwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVGhyZWFkfSB3aXRoIG5vIHtAY29kZSBSdW5uYWJsZX0gb2JqZWN0IGFuZCB0aGUKKyAgICAgKiBuYW1lIHByb3ZpZGVkLiBUaGUgbmV3IHtAY29kZSBUaHJlYWR9IHdpbGwgYmVsb25nIHRvIHRoZSBzYW1lIHtAY29kZQorICAgICAqIFRocmVhZEdyb3VwfSBhcyB0aGUge0Bjb2RlIFRocmVhZH0gY2FsbGluZyB0aGlzIGNvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIHRocmVhZE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIGZvciB0aGUge0Bjb2RlIFRocmVhZH0gYmVpbmcgY3JlYXRlZAorICAgICAqCisgICAgICogQHNlZSBqYXZhLmxhbmcuVGhyZWFkR3JvdXAKKyAgICAgKiBAc2VlIGphdmEubGFuZy5SdW5uYWJsZQorICAgICAqCisgICAgICovCisgICAgcHVibGljIFRocmVhZChTdHJpbmcgdGhyZWFkTmFtZSkgeworICAgICAgICBpZiAodGhyZWFkTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGNyZWF0ZShudWxsLCBudWxsLCB0aHJlYWROYW1lLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBUaHJlYWR9IHdpdGggYSB7QGNvZGUgUnVubmFibGV9IG9iamVjdCBhbmQgYQorICAgICAqIG5ld2x5IGdlbmVyYXRlZCBuYW1lLiBUaGUgbmV3IHtAY29kZSBUaHJlYWR9IHdpbGwgYmVsb25nIHRvIHRoZSB7QGNvZGUKKyAgICAgKiBUaHJlYWRHcm91cH0gcGFzc2VkIGFzIHBhcmFtZXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBncm91cAorICAgICAqICAgICAgICAgICAge0Bjb2RlIFRocmVhZEdyb3VwfSB0byB3aGljaCB0aGUgbmV3IHtAY29kZSBUaHJlYWR9IHdpbGwKKyAgICAgKiAgICAgICAgICAgIGJlbG9uZworICAgICAqIEBwYXJhbSBydW5uYWJsZQorICAgICAqICAgICAgICAgICAgYSB7QGNvZGUgUnVubmFibGV9IHdob3NlIG1ldGhvZCA8Y29kZT5ydW48L2NvZGU+IHdpbGwgYmUKKyAgICAgKiAgICAgICAgICAgIGV4ZWN1dGVkIGJ5IHRoZSBuZXcge0Bjb2RlIFRocmVhZH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxUaHJlYWRTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIDxjb2RlPmdyb3VwLmRlc3Ryb3koKTwvY29kZT4gaGFzIGFscmVhZHkgYmVlbiBkb25lCisgICAgICogQHNlZSBqYXZhLmxhbmcuVGhyZWFkR3JvdXAKKyAgICAgKiBAc2VlIGphdmEubGFuZy5SdW5uYWJsZQorICAgICAqLworICAgIHB1YmxpYyBUaHJlYWQoVGhyZWFkR3JvdXAgZ3JvdXAsIFJ1bm5hYmxlIHJ1bm5hYmxlKSB7CisgICAgICAgIGNyZWF0ZShncm91cCwgcnVubmFibGUsIG51bGwsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFRocmVhZH0gd2l0aCBhIHtAY29kZSBSdW5uYWJsZX0gb2JqZWN0LCB0aGUgZ2l2ZW4KKyAgICAgKiBuYW1lIGFuZCBiZWxvbmdpbmcgdG8gdGhlIHtAY29kZSBUaHJlYWRHcm91cH0gcGFzc2VkIGFzIHBhcmFtZXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBncm91cAorICAgICAqICAgICAgICAgICAgVGhyZWFkR3JvdXAgdG8gd2hpY2ggdGhlIG5ldyB7QGNvZGUgVGhyZWFkfSB3aWxsIGJlbG9uZworICAgICAqIEBwYXJhbSBydW5uYWJsZQorICAgICAqICAgICAgICAgICAgYSB7QGNvZGUgUnVubmFibGV9IHdob3NlIG1ldGhvZCA8Y29kZT5ydW48L2NvZGU+IHdpbGwgYmUKKyAgICAgKiAgICAgICAgICAgIGV4ZWN1dGVkIGJ5IHRoZSBuZXcge0Bjb2RlIFRocmVhZH0KKyAgICAgKiBAcGFyYW0gdGhyZWFkTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgZm9yIHRoZSB7QGNvZGUgVGhyZWFkfSBiZWluZyBjcmVhdGVkCisgICAgICogQHRocm93cyBJbGxlZ2FsVGhyZWFkU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiA8Y29kZT5ncm91cC5kZXN0cm95KCk8L2NvZGU+IGhhcyBhbHJlYWR5IGJlZW4gZG9uZQorICAgICAqIEBzZWUgamF2YS5sYW5nLlRocmVhZEdyb3VwCisgICAgICogQHNlZSBqYXZhLmxhbmcuUnVubmFibGUKKyAgICAgKi8KKyAgICBwdWJsaWMgVGhyZWFkKFRocmVhZEdyb3VwIGdyb3VwLCBSdW5uYWJsZSBydW5uYWJsZSwgU3RyaW5nIHRocmVhZE5hbWUpIHsKKyAgICAgICAgaWYgKHRocmVhZE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBjcmVhdGUoZ3JvdXAsIHJ1bm5hYmxlLCB0aHJlYWROYW1lLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBUaHJlYWR9IHdpdGggbm8ge0Bjb2RlIFJ1bm5hYmxlfSBvYmplY3QsIHRoZQorICAgICAqIGdpdmVuIG5hbWUgYW5kIGJlbG9uZ2luZyB0byB0aGUge0Bjb2RlIFRocmVhZEdyb3VwfSBwYXNzZWQgYXMgcGFyYW1ldGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGdyb3VwCisgICAgICogICAgICAgICAgICB7QGNvZGUgVGhyZWFkR3JvdXB9IHRvIHdoaWNoIHRoZSBuZXcge0Bjb2RlIFRocmVhZH0gd2lsbCBiZWxvbmcKKyAgICAgKiBAcGFyYW0gdGhyZWFkTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgZm9yIHRoZSB7QGNvZGUgVGhyZWFkfSBiZWluZyBjcmVhdGVkCisgICAgICogQHRocm93cyBJbGxlZ2FsVGhyZWFkU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiA8Y29kZT5ncm91cC5kZXN0cm95KCk8L2NvZGU+IGhhcyBhbHJlYWR5IGJlZW4gZG9uZQorICAgICAqIEBzZWUgamF2YS5sYW5nLlRocmVhZEdyb3VwCisgICAgICogQHNlZSBqYXZhLmxhbmcuUnVubmFibGUKKyAgICAgKi8KKyAgICBwdWJsaWMgVGhyZWFkKFRocmVhZEdyb3VwIGdyb3VwLCBTdHJpbmcgdGhyZWFkTmFtZSkgeworICAgICAgICBpZiAodGhyZWFkTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGNyZWF0ZShncm91cCwgbnVsbCwgdGhyZWFkTmFtZSwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVGhyZWFkfSB3aXRoIGEge0Bjb2RlIFJ1bm5hYmxlfSBvYmplY3QsIHRoZSBnaXZlbgorICAgICAqIG5hbWUgYW5kIGJlbG9uZ2luZyB0byB0aGUge0Bjb2RlIFRocmVhZEdyb3VwfSBwYXNzZWQgYXMgcGFyYW1ldGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGdyb3VwCisgICAgICogICAgICAgICAgICB7QGNvZGUgVGhyZWFkR3JvdXB9IHRvIHdoaWNoIHRoZSBuZXcge0Bjb2RlIFRocmVhZH0gd2lsbAorICAgICAqICAgICAgICAgICAgYmVsb25nCisgICAgICogQHBhcmFtIHJ1bm5hYmxlCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBSdW5uYWJsZX0gd2hvc2UgbWV0aG9kIDxjb2RlPnJ1bjwvY29kZT4gd2lsbCBiZQorICAgICAqICAgICAgICAgICAgZXhlY3V0ZWQgYnkgdGhlIG5ldyB7QGNvZGUgVGhyZWFkfQorICAgICAqIEBwYXJhbSB0aHJlYWROYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBmb3IgdGhlIHtAY29kZSBUaHJlYWR9IGJlaW5nIGNyZWF0ZWQKKyAgICAgKiBAcGFyYW0gc3RhY2tTaXplCisgICAgICogICAgICAgICAgICBhIHN0YWNrIHNpemUgZm9yIHRoZSBuZXcge0Bjb2RlIFRocmVhZH0uIFRoaXMgaGFzIGEgaGlnaGx5CisgICAgICogICAgICAgICAgICBwbGF0Zm9ybS1kZXBlbmRlbnQgaW50ZXJwcmV0YXRpb24uIEl0IG1heSBldmVuIGJlIGlnbm9yZWQKKyAgICAgKiAgICAgICAgICAgIGNvbXBsZXRlbHkuCisgICAgICogQHRocm93cyBJbGxlZ2FsVGhyZWFkU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiA8Y29kZT5ncm91cC5kZXN0cm95KCk8L2NvZGU+IGhhcyBhbHJlYWR5IGJlZW4gZG9uZQorICAgICAqIEBzZWUgamF2YS5sYW5nLlRocmVhZEdyb3VwCisgICAgICogQHNlZSBqYXZhLmxhbmcuUnVubmFibGUKKyAgICAgKi8KKyAgICBwdWJsaWMgVGhyZWFkKFRocmVhZEdyb3VwIGdyb3VwLCBSdW5uYWJsZSBydW5uYWJsZSwgU3RyaW5nIHRocmVhZE5hbWUsIGxvbmcgc3RhY2tTaXplKSB7CisgICAgICAgIGlmICh0aHJlYWROYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGNyZWF0ZShncm91cCwgcnVubmFibGUsIHRocmVhZE5hbWUsIHN0YWNrU2l6ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFja2FnZS1zY29wZSBtZXRob2QgaW52b2tlZCBieSBEYWx2aWsgVk0gdG8gY3JlYXRlICJpbnRlcm5hbCIKKyAgICAgKiB0aHJlYWRzIG9yIGF0dGFjaCB0aHJlYWRzIGNyZWF0ZWQgZXh0ZXJuYWxseS4KKyAgICAgKgorICAgICAqIERvbid0IGNhbGwgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKSwgc2luY2UgdGhlcmUgbWF5IG5vdCBiZSBzdWNoCisgICAgICogYSB0aGluZyAoZS5nLiBmb3IgTWFpbikuCisgICAgICovCisgICAgVGhyZWFkKFRocmVhZEdyb3VwIGdyb3VwLCBTdHJpbmcgbmFtZSwgaW50IHByaW9yaXR5LCBib29sZWFuIGRhZW1vbikgeworICAgICAgICBzeW5jaHJvbml6ZWQgKFRocmVhZC5jbGFzcykgeworICAgICAgICAgICAgaWQgPSArK1RocmVhZC5jb3VudDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMubmFtZSA9ICJUaHJlYWQtIiArIGlkOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChncm91cCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcigiZ3JvdXAgbm90IHNwZWNpZmllZCIpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5ncm91cCA9IGdyb3VwOworCisgICAgICAgIHRoaXMudGFyZ2V0ID0gbnVsbDsKKyAgICAgICAgdGhpcy5zdGFja1NpemUgPSAwOworICAgICAgICB0aGlzLnByaW9yaXR5ID0gcHJpb3JpdHk7CisgICAgICAgIHRoaXMuZGFlbW9uID0gZGFlbW9uOworCisgICAgICAgIC8qIGFkZCBvdXJzZWx2ZXMgdG8gb3VyIFRocmVhZEdyb3VwIG9mIGNob2ljZSAqLworICAgICAgICB0aGlzLmdyb3VwLmFkZFRocmVhZCh0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyBhIG5ldywgZXhpc3RpbmcgVGhyZWFkIG9iamVjdCB3aXRoIGEgcnVubmFibGUgb2JqZWN0LAorICAgICAqIHRoZSBnaXZlbiBuYW1lIGFuZCBiZWxvbmdpbmcgdG8gdGhlIFRocmVhZEdyb3VwIHBhc3NlZCBhcyBwYXJhbWV0ZXIuCisgICAgICogVGhpcyBpcyB0aGUgbWV0aG9kIHRoYXQgdGhlIHNldmVyYWwgcHVibGljIGNvbnN0cnVjdG9ycyBkZWxlZ2F0ZSB0aGVpcgorICAgICAqIHdvcmsgdG8uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZ3JvdXAgVGhyZWFkR3JvdXAgdG8gd2hpY2ggdGhlIG5ldyBUaHJlYWQgd2lsbCBiZWxvbmcKKyAgICAgKiBAcGFyYW0gcnVubmFibGUgYSBqYXZhLmxhbmcuUnVubmFibGUgd2hvc2UgbWV0aG9kIDxjb2RlPnJ1bjwvY29kZT4gd2lsbAorICAgICAqICAgICAgICBiZSBleGVjdXRlZCBieSB0aGUgbmV3IFRocmVhZAorICAgICAqIEBwYXJhbSB0aHJlYWROYW1lIE5hbWUgZm9yIHRoZSBUaHJlYWQgYmVpbmcgY3JlYXRlZAorICAgICAqIEBwYXJhbSBzdGFja1NpemUgUGxhdGZvcm0gZGVwZW5kZW50IHN0YWNrIHNpemUKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxUaHJlYWRTdGF0ZUV4Y2VwdGlvbiBpZiA8Y29kZT5ncm91cC5kZXN0cm95KCk8L2NvZGU+IGhhcworICAgICAqICAgICAgICAgYWxyZWFkeSBiZWVuIGRvbmUKKyAgICAgKiBAc2VlIGphdmEubGFuZy5UaHJlYWRHcm91cAorICAgICAqIEBzZWUgamF2YS5sYW5nLlJ1bm5hYmxlCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZShUaHJlYWRHcm91cCBncm91cCwgUnVubmFibGUgcnVubmFibGUsIFN0cmluZyB0aHJlYWROYW1lLCBsb25nIHN0YWNrU2l6ZSkgeworICAgICAgICBUaHJlYWQgY3VycmVudFRocmVhZCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisgICAgICAgIGlmIChncm91cCA9PSBudWxsKSB7CisgICAgICAgICAgICBncm91cCA9IGN1cnJlbnRUaHJlYWQuZ2V0VGhyZWFkR3JvdXAoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChncm91cC5pc0Rlc3Ryb3llZCgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uKCJHcm91cCBhbHJlYWR5IGRlc3Ryb3llZCIpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5ncm91cCA9IGdyb3VwOworCisgICAgICAgIHN5bmNocm9uaXplZCAoVGhyZWFkLmNsYXNzKSB7CisgICAgICAgICAgICBpZCA9ICsrVGhyZWFkLmNvdW50OworICAgICAgICB9CisKKyAgICAgICAgaWYgKHRocmVhZE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhpcy5uYW1lID0gIlRocmVhZC0iICsgaWQ7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aGlzLm5hbWUgPSB0aHJlYWROYW1lOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy50YXJnZXQgPSBydW5uYWJsZTsKKyAgICAgICAgdGhpcy5zdGFja1NpemUgPSBzdGFja1NpemU7CisKKyAgICAgICAgdGhpcy5wcmlvcml0eSA9IGN1cnJlbnRUaHJlYWQuZ2V0UHJpb3JpdHkoKTsKKworICAgICAgICB0aGlzLmNvbnRleHRDbGFzc0xvYWRlciA9IGN1cnJlbnRUaHJlYWQuY29udGV4dENsYXNzTG9hZGVyOworCisgICAgICAgIC8vIFRyYW5zZmVyIG92ZXIgSW5oZXJpdGFibGVUaHJlYWRMb2NhbHMuCisgICAgICAgIGlmIChjdXJyZW50VGhyZWFkLmluaGVyaXRhYmxlVmFsdWVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGluaGVyaXRhYmxlVmFsdWVzID0gbmV3IFRocmVhZExvY2FsLlZhbHVlcyhjdXJyZW50VGhyZWFkLmluaGVyaXRhYmxlVmFsdWVzKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGFkZCBvdXJzZWx2ZXMgdG8gb3VyIFRocmVhZEdyb3VwIG9mIGNob2ljZQorICAgICAgICB0aGlzLmdyb3VwLmFkZFRocmVhZCh0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYWN0aXZlIHtAY29kZSBUaHJlYWR9cyBpbiB0aGUgcnVubmluZyB7QGNvZGUKKyAgICAgKiBUaHJlYWR9J3MgZ3JvdXAgYW5kIGl0cyBzdWJncm91cHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2Yge0Bjb2RlIFRocmVhZH1zCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgYWN0aXZlQ291bnQoKSB7CisgICAgICAgIHJldHVybiBjdXJyZW50VGhyZWFkKCkuZ2V0VGhyZWFkR3JvdXAoKS5hY3RpdmVDb3VudCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERvZXMgbm90aGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBjaGVja0FjY2VzcygpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Ygc3RhY2sgZnJhbWVzIGluIHRoaXMgdGhyZWFkLgorICAgICAqCisgICAgICogQHJldHVybiBOdW1iZXIgb2Ygc3RhY2sgZnJhbWVzCisgICAgICogQGRlcHJlY2F0ZWQgVGhlIHJlc3VsdHMgb2YgdGhpcyBjYWxsIHdlcmUgbmV2ZXIgd2VsbCBkZWZpbmVkLiBUbyBtYWtlCisgICAgICogICAgICAgICAgICAgdGhpbmdzIHdvcnNlLCBpdCB3b3VsZCBkZXBlbmQgb24gd2hldGhlciB0aGUgVGhyZWFkIHdhcworICAgICAqICAgICAgICAgICAgIHN1c3BlbmRlZCBvciBub3QsIGFuZCBzdXNwZW5kIHdhcyBkZXByZWNhdGVkIHRvby4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBpbnQgY291bnRTdGFja0ZyYW1lcygpIHsKKyAgICAgICAgcmV0dXJuIGdldFN0YWNrVHJhY2UoKS5sZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgVGhyZWFkIG9mIHRoZSBjYWxsZXIsIHRoYXQgaXMsIHRoZSBjdXJyZW50IFRocmVhZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgVGhyZWFkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVGhyZWFkIGN1cnJlbnRUaHJlYWQoKSB7CisgICAgICAgIHJldHVybiBWTVRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVzdHJveXMgdGhlIHJlY2VpdmVyIHdpdGhvdXQgYW55IG1vbml0b3IgY2xlYW51cC4KKyAgICAgKgorICAgICAqIEBkZXByZWNhdGVkIE5vdCBpbXBsZW1lbnRlZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyB2b2lkIGRlc3Ryb3koKSB7CisgICAgICAgIHRocm93IG5ldyBOb1N1Y2hNZXRob2RFcnJvcigiVGhyZWFkLmRlc3Ryb3koKSIpOyAvLyBUT0RPIEV4dGVybmFsaXplPz8/CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnRzIHRvIHRoZSBzdGFuZGFyZCBlcnJvciBzdHJlYW0gYSB0ZXh0IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjdXJyZW50CisgICAgICogc3RhY2sgZm9yIHRoaXMgVGhyZWFkLgorICAgICAqCisgICAgICogQHNlZSBUaHJvd2FibGUjcHJpbnRTdGFja1RyYWNlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZHVtcFN0YWNrKCkgeworICAgICAgICBuZXcgVGhyb3dhYmxlKCJzdGFjayBkdW1wIikucHJpbnRTdGFja1RyYWNlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29waWVzIGFuIGFycmF5IHdpdGggYWxsIFRocmVhZHMgd2hpY2ggYXJlIGluIHRoZSBzYW1lIFRocmVhZEdyb3VwIGFzIHRoZQorICAgICAqIHJlY2VpdmVyIC0gYW5kIHN1Ymdyb3VwcyAtIGludG8gdGhlIGFycmF5IDxjb2RlPnRocmVhZHM8L2NvZGU+IHBhc3NlZCBhcworICAgICAqIHBhcmFtZXRlci4gSWYgdGhlIGFycmF5IHBhc3NlZCBhcyBwYXJhbWV0ZXIgaXMgdG9vIHNtYWxsIG5vIGV4Y2VwdGlvbiBpcworICAgICAqIHRocm93biAtIHRoZSBleHRyYSBlbGVtZW50cyBhcmUgc2ltcGx5IG5vdCBjb3BpZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhyZWFkcworICAgICAqICAgICAgICAgICAgYXJyYXkgaW50byB3aGljaCB0aGUgVGhyZWFkcyB3aWxsIGJlIGNvcGllZAorICAgICAqIEByZXR1cm4gSG93IG1hbnkgVGhyZWFkcyB3ZXJlIGNvcGllZCBvdmVyCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZW51bWVyYXRlKFRocmVhZFtdIHRocmVhZHMpIHsKKyAgICAgICAgVGhyZWFkIHRocmVhZCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisgICAgICAgIHJldHVybiB0aHJlYWQuZ2V0VGhyZWFkR3JvdXAoKS5lbnVtZXJhdGUodGhyZWFkcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG1hcCBvZiBhbGwgdGhlIGN1cnJlbnRseSBsaXZlIHRocmVhZHMgdG8gdGhlaXIgc3RhY2sgdHJhY2VzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTWFwPFRocmVhZCwgU3RhY2tUcmFjZUVsZW1lbnRbXT4gZ2V0QWxsU3RhY2tUcmFjZXMoKSB7CisgICAgICAgIE1hcDxUaHJlYWQsIFN0YWNrVHJhY2VFbGVtZW50W10+IG1hcCA9IG5ldyBIYXNoTWFwPFRocmVhZCwgU3RhY2tUcmFjZUVsZW1lbnRbXT4oKTsKKworICAgICAgICAvLyBGaW5kIG91dCBob3cgbWFueSBsaXZlIHRocmVhZHMgd2UgaGF2ZS4gQWxsb2NhdGUgYSBiaXQgbW9yZQorICAgICAgICAvLyBzcGFjZSB0aGFuIG5lZWRlZCwgaW4gY2FzZSBuZXcgb25lcyBhcmUganVzdCBiZWluZyBjcmVhdGVkLgorICAgICAgICBpbnQgY291bnQgPSBUaHJlYWRHcm91cC5tU3lzdGVtLmFjdGl2ZUNvdW50KCk7CisgICAgICAgIFRocmVhZFtdIHRocmVhZHMgPSBuZXcgVGhyZWFkW2NvdW50ICsgY291bnQgLyAyXTsKKworICAgICAgICAvLyBFbnVtZXJhdGUgdGhlIHRocmVhZHMgYW5kIGNvbGxlY3QgdGhlIHN0YWNrdHJhY2VzLgorICAgICAgICBjb3VudCA9IFRocmVhZEdyb3VwLm1TeXN0ZW0uZW51bWVyYXRlKHRocmVhZHMpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgICAgICAgIG1hcC5wdXQodGhyZWFkc1tpXSwgdGhyZWFkc1tpXS5nZXRTdGFja1RyYWNlKCkpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG1hcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb250ZXh0IENsYXNzTG9hZGVyIGZvciB0aGlzIFRocmVhZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQ2xhc3NMb2FkZXIgVGhlIGNvbnRleHQgQ2xhc3NMb2FkZXIKKyAgICAgKiBAc2VlIGphdmEubGFuZy5DbGFzc0xvYWRlcgorICAgICAqIEBzZWUgI2dldENvbnRleHRDbGFzc0xvYWRlcigpCisgICAgICovCisgICAgcHVibGljIENsYXNzTG9hZGVyIGdldENvbnRleHRDbGFzc0xvYWRlcigpIHsKKyAgICAgICAgcmV0dXJuIGNvbnRleHRDbGFzc0xvYWRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGV4Y2VwdGlvbiBoYW5kbGVyIHRoYXQncyBleGVjdXRlZCB3aGVuIHVuY2F1Z2h0CisgICAgICogZXhjZXB0aW9uIHRlcm1pbmF0ZXMgYSB0aHJlYWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIHtAbGluayBVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXJ9IG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmCisgICAgICogICAgICAgICBub25lIGV4aXN0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlciBnZXREZWZhdWx0VW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyKCkgeworICAgICAgICByZXR1cm4gZGVmYXVsdFVuY2F1Z2h0SGFuZGxlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0aHJlYWQncyBpZGVudGlmaWVyLiBUaGUgSUQgaXMgYSBwb3NpdGl2ZSA8Y29kZT5sb25nPC9jb2RlPgorICAgICAqIGdlbmVyYXRlZCBvbiB0aHJlYWQgY3JlYXRpb24sIGlzIHVuaXF1ZSB0byB0aGUgdGhyZWFkLCBhbmQgZG9lc24ndCBjaGFuZ2UKKyAgICAgKiBkdXJpbmcgdGhlIGxpZmV0aW1lIG9mIHRoZSB0aHJlYWQ7IHRoZSBJRCBtYXkgYmUgcmV1c2VkIGFmdGVyIHRoZSB0aHJlYWQKKyAgICAgKiBoYXMgYmVlbiB0ZXJtaW5hdGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdGhyZWFkJ3MgSUQuCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0SWQoKSB7CisgICAgICAgIHJldHVybiBpZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBUaHJlYWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBUaHJlYWQncyBuYW1lCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcmlvcml0eSBvZiB0aGUgVGhyZWFkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgVGhyZWFkJ3MgcHJpb3JpdHkKKyAgICAgKiBAc2VlIFRocmVhZCNzZXRQcmlvcml0eQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UHJpb3JpdHkoKSB7CisgICAgICAgIHJldHVybiBwcmlvcml0eTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHtAbGluayBTdGFja1RyYWNlRWxlbWVudH0gcmVwcmVzZW50aW5nIHRoZSBjdXJyZW50IHRocmVhZCdzIHN0YWNrLgorICAgICAqLworICAgIHB1YmxpYyBTdGFja1RyYWNlRWxlbWVudFtdIGdldFN0YWNrVHJhY2UoKSB7CisgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50IHN0ZVtdID0gVk1TdGFjay5nZXRUaHJlYWRTdGFja1RyYWNlKHRoaXMpOworICAgICAgICByZXR1cm4gc3RlICE9IG51bGwgPyBzdGUgOiBFbXB0eUFycmF5LlNUQUNLX1RSQUNFX0VMRU1FTlQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgVGhyZWFkLiBUaGlzIG1ldGhvZCBpcyB1c2VmdWwgZm9yCisgICAgICogbW9uaXRvcmluZyBwdXJwb3Nlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSB7QGxpbmsgU3RhdGV9IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBTdGF0ZSBnZXRTdGF0ZSgpIHsKKyAgICAgICAgLy8gVE9ETyBUaGlzIGlzIHVnbHkgYW5kIHNob3VsZCBiZSBpbXBsZW1lbnRlZCBiZXR0ZXIuCisgICAgICAgIFZNVGhyZWFkIHZtdCA9IHRoaXMudm1UaHJlYWQ7CisKKyAgICAgICAgLy8gTWFrZSBzdXJlIHdlIGhhdmUgYSB2YWxpZCByZWZlcmVuY2UgdG8gYW4gb2JqZWN0LiBJZiBuYXRpdmUgY29kZQorICAgICAgICAvLyBkZWxldGVzIHRoZSByZWZlcmVuY2Ugd2Ugd29uJ3QgcnVuIGludG8gYSBudWxsIHJlZmVyZW5jZSBsYXRlci4KKyAgICAgICAgVk1UaHJlYWQgdGhyZWFkID0gdm1UaHJlYWQ7CisgICAgICAgIGlmICh0aHJlYWQgIT0gbnVsbCkgeworICAgICAgICAgICAgLy8gSWYgdGhlIFRocmVhZCBPYmplY3QgYmVjYW1lIGludmFsaWQgb3Igd2FzIG5vdCB5ZXQgc3RhcnRlZCwKKyAgICAgICAgICAgIC8vIGdldFN0YXR1cygpIHdpbGwgcmV0dXJuIC0xLgorICAgICAgICAgICAgaW50IHN0YXRlID0gdGhyZWFkLmdldFN0YXR1cygpOworICAgICAgICAgICAgaWYoc3RhdGUgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gVk1UaHJlYWQuU1RBVEVfTUFQW3N0YXRlXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzQmVlblN0YXJ0ZWQgPyBUaHJlYWQuU3RhdGUuVEVSTUlOQVRFRCA6IFRocmVhZC5TdGF0ZS5ORVc7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgVGhyZWFkR3JvdXAgdG8gd2hpY2ggdGhpcyBUaHJlYWQgYmVsb25ncy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIFRocmVhZCdzIFRocmVhZEdyb3VwCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFRocmVhZEdyb3VwIGdldFRocmVhZEdyb3VwKCkgeworICAgICAgICAvLyBUT0RPIFRoaXMgc2hvdWxkIGFjdHVhbGx5IGJlIGRvbmUgYXQgbmF0aXZlIHRlcm1pbmF0aW9uLgorICAgICAgICBpZiAoZ2V0U3RhdGUoKSA9PSBUaHJlYWQuU3RhdGUuVEVSTUlOQVRFRCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gZ3JvdXA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0aHJlYWQncyB1bmNhdWdodCBleGNlcHRpb24gaGFuZGxlci4gSWYgbm90IGV4cGxpY2l0bHkgc2V0LAorICAgICAqIHRoZW4gdGhlIFRocmVhZEdyb3VwJ3MgaGFuZGxlciBpcyByZXR1cm5lZC4gSWYgdGhlIHRocmVhZCBpcyB0ZXJtaW5hdGVkLAorICAgICAqIHRoZW4gPGNvZGU+bnVsbDwvY29kZT4gaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIHtAbGluayBVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXJ9IGluc3RhbmNlIG9yIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyIGdldFVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlcigpIHsKKyAgICAgICAgaWYgKHVuY2F1Z2h0SGFuZGxlciAhPSBudWxsKQorICAgICAgICAgICAgcmV0dXJuIHVuY2F1Z2h0SGFuZGxlcjsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcmV0dXJuIGdyb3VwOyAgICAgICAgICAgLy8gVGhyZWFkR3JvdXAgaXMgaW5zdGFuY2Ugb2YgVUVICisgICAgfQorCisgICAgLyoqCisgICAgICogUG9zdHMgYW4gaW50ZXJydXB0IHJlcXVlc3QgdG8gdGhpcyB7QGNvZGUgVGhyZWFkfS4gVGhlIGJlaGF2aW9yIGRlcGVuZHMgb24KKyAgICAgKiB0aGUgc3RhdGUgb2YgdGhpcyB7QGNvZGUgVGhyZWFkfToKKyAgICAgKiA8dWw+CisgICAgICogPGxpPgorICAgICAqIHtAY29kZSBUaHJlYWR9cyBibG9ja2VkIGluIG9uZSBvZiB7QGNvZGUgT2JqZWN0fSdzIHtAY29kZSB3YWl0KCl9IG1ldGhvZHMKKyAgICAgKiBvciBvbmUgb2Yge0Bjb2RlIFRocmVhZH0ncyB7QGNvZGUgam9pbigpfSBvciB7QGNvZGUgc2xlZXAoKX0gbWV0aG9kcyB3aWxsCisgICAgICogYmUgd29rZW4gdXAsIHRoZWlyIGludGVycnVwdCBzdGF0dXMgd2lsbCBiZSBjbGVhcmVkLCBhbmQgdGhleSByZWNlaXZlIGFuCisgICAgICoge0BsaW5rIEludGVycnVwdGVkRXhjZXB0aW9ufS4KKyAgICAgKiA8bGk+CisgICAgICoge0Bjb2RlIFRocmVhZH1zIGJsb2NrZWQgaW4gYW4gSS9PIG9wZXJhdGlvbiBvZiBhbgorICAgICAqIHtAbGluayBqYXZhLm5pby5jaGFubmVscy5JbnRlcnJ1cHRpYmxlQ2hhbm5lbH0gd2lsbCBoYXZlIHRoZWlyIGludGVycnVwdAorICAgICAqIHN0YXR1cyBzZXQgYW5kIHJlY2VpdmUgYW4KKyAgICAgKiB7QGxpbmsgamF2YS5uaW8uY2hhbm5lbHMuQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb259LiBBbHNvLCB0aGUgY2hhbm5lbAorICAgICAqIHdpbGwgYmUgY2xvc2VkLgorICAgICAqIDxsaT4KKyAgICAgKiB7QGNvZGUgVGhyZWFkfXMgYmxvY2tlZCBpbiBhIHtAbGluayBqYXZhLm5pby5jaGFubmVscy5TZWxlY3Rvcn0gd2lsbCBoYXZlCisgICAgICogdGhlaXIgaW50ZXJydXB0IHN0YXR1cyBzZXQgYW5kIHJldHVybiBpbW1lZGlhdGVseS4gVGhleSBkb24ndCByZWNlaXZlIGFuCisgICAgICogZXhjZXB0aW9uIGluIHRoaXMgY2FzZS4KKyAgICAgKiA8dWw+CisgICAgICoKKyAgICAgKiBAc2VlIFRocmVhZCNpbnRlcnJ1cHRlZAorICAgICAqIEBzZWUgVGhyZWFkI2lzSW50ZXJydXB0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBpbnRlcnJ1cHQoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoaW50ZXJydXB0QWN0aW9ucykgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IGludGVycnVwdEFjdGlvbnMuc2l6ZSgpIC0gMTsgaSA+PSAwOyBpLS0pIHsKKyAgICAgICAgICAgICAgICBpbnRlcnJ1cHRBY3Rpb25zLmdldChpKS5ydW4oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFZNVGhyZWFkIHZtdCA9IHRoaXMudm1UaHJlYWQ7CisgICAgICAgIGlmICh2bXQgIT0gbnVsbCkgeworICAgICAgICAgICAgdm10LmludGVycnVwdCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIDxjb2RlPmJvb2xlYW48L2NvZGU+IGluZGljYXRpbmcgd2hldGhlciB0aGUgY3VycmVudCBUaHJlYWQgKAorICAgICAqIDxjb2RlPmN1cnJlbnRUaHJlYWQoKTwvY29kZT4pIGhhcyBhIHBlbmRpbmcgaW50ZXJydXB0IHJlcXVlc3QgKDxjb2RlPgorICAgICAqIHRydWU8L2NvZGU+KSBvciBub3QgKDxjb2RlPmZhbHNlPC9jb2RlPikuIEl0IGFsc28gaGFzIHRoZSBzaWRlLWVmZmVjdCBvZgorICAgICAqIGNsZWFyaW5nIHRoZSBmbGFnLgorICAgICAqCisgICAgICogQHJldHVybiBhIDxjb2RlPmJvb2xlYW48L2NvZGU+IGluZGljYXRpbmcgdGhlIGludGVycnVwdCBzdGF0dXMKKyAgICAgKiBAc2VlIFRocmVhZCNjdXJyZW50VGhyZWFkCisgICAgICogQHNlZSBUaHJlYWQjaW50ZXJydXB0CisgICAgICogQHNlZSBUaHJlYWQjaXNJbnRlcnJ1cHRlZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpbnRlcnJ1cHRlZCgpIHsKKyAgICAgICAgcmV0dXJuIFZNVGhyZWFkLmludGVycnVwdGVkKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgcmVjZWl2ZXIgaGFzIGFscmVhZHkgYmVlbiBzdGFydGVkIGFuZAorICAgICAqIHN0aWxsIHJ1bnMgY29kZSAoaGFzbid0IGRpZWQgeWV0KS4gUmV0dXJucyA8Y29kZT5mYWxzZTwvY29kZT4gZWl0aGVyIGlmCisgICAgICogdGhlIHJlY2VpdmVyIGhhc24ndCBiZWVuIHN0YXJ0ZWQgeWV0IG9yIGlmIGl0IGhhcyBhbHJlYWR5IHN0YXJ0ZWQgYW5kIHJ1bgorICAgICAqIHRvIGNvbXBsZXRpb24gYW5kIGRpZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgPGNvZGU+Ym9vbGVhbjwvY29kZT4gaW5kaWNhdGluZyB0aGUgbGl2ZW5lc3Mgb2YgdGhlIFRocmVhZAorICAgICAqIEBzZWUgVGhyZWFkI3N0YXJ0CisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNBbGl2ZSgpIHsKKyAgICAgICAgcmV0dXJuICh2bVRocmVhZCAhPSBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgPGNvZGU+Ym9vbGVhbjwvY29kZT4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSByZWNlaXZlciBpcyBhCisgICAgICogZGFlbW9uIFRocmVhZCAoPGNvZGU+dHJ1ZTwvY29kZT4pIG9yIG5vdCAoPGNvZGU+ZmFsc2U8L2NvZGU+KSBBCisgICAgICogZGFlbW9uIFRocmVhZCBvbmx5IHJ1bnMgYXMgbG9uZyBhcyB0aGVyZSBhcmUgbm9uLWRhZW1vbiBUaHJlYWRzIHJ1bm5pbmcuCisgICAgICogV2hlbiB0aGUgbGFzdCBub24tZGFlbW9uIFRocmVhZCBlbmRzLCB0aGUgd2hvbGUgcHJvZ3JhbSBlbmRzIG5vIG1hdHRlciBpZgorICAgICAqIGl0IGhhZCBkYWVtb24gVGhyZWFkcyBzdGlsbCBydW5uaW5nIG9yIG5vdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSA8Y29kZT5ib29sZWFuPC9jb2RlPiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIFRocmVhZCBpcyBhIGRhZW1vbgorICAgICAqIEBzZWUgVGhyZWFkI3NldERhZW1vbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzRGFlbW9uKCkgeworICAgICAgICByZXR1cm4gZGFlbW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSA8Y29kZT5ib29sZWFuPC9jb2RlPiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHJlY2VpdmVyIGhhcyBhCisgICAgICogcGVuZGluZyBpbnRlcnJ1cHQgcmVxdWVzdCAoPGNvZGU+dHJ1ZTwvY29kZT4pIG9yIG5vdCAoCisgICAgICogPGNvZGU+ZmFsc2U8L2NvZGU+KQorICAgICAqCisgICAgICogQHJldHVybiBhIDxjb2RlPmJvb2xlYW48L2NvZGU+IGluZGljYXRpbmcgdGhlIGludGVycnVwdCBzdGF0dXMKKyAgICAgKiBAc2VlIFRocmVhZCNpbnRlcnJ1cHQKKyAgICAgKiBAc2VlIFRocmVhZCNpbnRlcnJ1cHRlZAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzSW50ZXJydXB0ZWQoKSB7CisgICAgICAgIFZNVGhyZWFkIHZtdCA9IHRoaXMudm1UaHJlYWQ7CisgICAgICAgIGlmICh2bXQgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHZtdC5pc0ludGVycnVwdGVkKCk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQmxvY2tzIHRoZSBjdXJyZW50IFRocmVhZCAoPGNvZGU+VGhyZWFkLmN1cnJlbnRUaHJlYWQoKTwvY29kZT4pIHVudGlsCisgICAgICogdGhlIHJlY2VpdmVyIGZpbmlzaGVzIGl0cyBleGVjdXRpb24gYW5kIGRpZXMuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIDxjb2RlPmludGVycnVwdCgpPC9jb2RlPiB3YXMgY2FsbGVkIGZvcgorICAgICAqICAgICAgICAgdGhlIHJlY2VpdmVyIHdoaWxlIGl0IHdhcyBpbiB0aGUgPGNvZGU+am9pbigpPC9jb2RlPiBjYWxsCisgICAgICogQHNlZSBPYmplY3Qjbm90aWZ5QWxsCisgICAgICogQHNlZSBqYXZhLmxhbmcuVGhyZWFkRGVhdGgKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBqb2luKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgVk1UaHJlYWQgdCA9IHZtVGhyZWFkOworICAgICAgICBpZiAodCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBzeW5jaHJvbml6ZWQgKHQpIHsKKyAgICAgICAgICAgIHdoaWxlIChpc0FsaXZlKCkpIHsKKyAgICAgICAgICAgICAgICB0LndhaXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEJsb2NrcyB0aGUgY3VycmVudCBUaHJlYWQgKDxjb2RlPlRocmVhZC5jdXJyZW50VGhyZWFkKCk8L2NvZGU+KSB1bnRpbAorICAgICAqIHRoZSByZWNlaXZlciBmaW5pc2hlcyBpdHMgZXhlY3V0aW9uIGFuZCBkaWVzIG9yIHRoZSBzcGVjaWZpZWQgdGltZW91dAorICAgICAqIGV4cGlyZXMsIHdoYXRldmVyIGhhcHBlbnMgZmlyc3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWlsbGlzIFRoZSBtYXhpbXVtIHRpbWUgdG8gd2FpdCAoaW4gbWlsbGlzZWNvbmRzKS4KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIDxjb2RlPmludGVycnVwdCgpPC9jb2RlPiB3YXMgY2FsbGVkIGZvcgorICAgICAqICAgICAgICAgdGhlIHJlY2VpdmVyIHdoaWxlIGl0IHdhcyBpbiB0aGUgPGNvZGU+am9pbigpPC9jb2RlPiBjYWxsCisgICAgICogQHNlZSBPYmplY3Qjbm90aWZ5QWxsCisgICAgICogQHNlZSBqYXZhLmxhbmcuVGhyZWFkRGVhdGgKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBqb2luKGxvbmcgbWlsbGlzKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBqb2luKG1pbGxpcywgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQmxvY2tzIHRoZSBjdXJyZW50IFRocmVhZCAoPGNvZGU+VGhyZWFkLmN1cnJlbnRUaHJlYWQoKTwvY29kZT4pIHVudGlsCisgICAgICogdGhlIHJlY2VpdmVyIGZpbmlzaGVzIGl0cyBleGVjdXRpb24gYW5kIGRpZXMgb3IgdGhlIHNwZWNpZmllZCB0aW1lb3V0CisgICAgICogZXhwaXJlcywgd2hhdGV2ZXIgaGFwcGVucyBmaXJzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtaWxsaXMgVGhlIG1heGltdW0gdGltZSB0byB3YWl0IChpbiBtaWxsaXNlY29uZHMpLgorICAgICAqIEBwYXJhbSBuYW5vcyBFeHRyYSBuYW5vc2Vjb25kIHByZWNpc2lvbgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgPGNvZGU+aW50ZXJydXB0KCk8L2NvZGU+IHdhcyBjYWxsZWQgZm9yCisgICAgICogICAgICAgICB0aGUgcmVjZWl2ZXIgd2hpbGUgaXQgd2FzIGluIHRoZSA8Y29kZT5qb2luKCk8L2NvZGU+IGNhbGwKKyAgICAgKiBAc2VlIE9iamVjdCNub3RpZnlBbGwKKyAgICAgKiBAc2VlIGphdmEubGFuZy5UaHJlYWREZWF0aAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGpvaW4obG9uZyBtaWxsaXMsIGludCBuYW5vcykgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG1pbGxpcyA8IDAgfHwgbmFub3MgPCAwIHx8IG5hbm9zID49IE5BTk9TX1BFUl9NSUxMSSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgLy8gYXZvaWQgb3ZlcmZsb3c6IGlmIHRvdGFsID4gMjkyLDI3NyB5ZWFycywganVzdCB3YWl0IGZvcmV2ZXIKKyAgICAgICAgYm9vbGVhbiBvdmVyZmxvdyA9IG1pbGxpcyA+PSAoTG9uZy5NQVhfVkFMVUUgLSBuYW5vcykgLyBOQU5PU19QRVJfTUlMTEk7CisgICAgICAgIGJvb2xlYW4gZm9yZXZlciA9IChtaWxsaXMgfCBuYW5vcykgPT0gMDsKKyAgICAgICAgaWYgKGZvcmV2ZXIgfCBvdmVyZmxvdykgeworICAgICAgICAgICAgam9pbigpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgVk1UaHJlYWQgdCA9IHZtVGhyZWFkOworICAgICAgICBpZiAodCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBzeW5jaHJvbml6ZWQgKHQpIHsKKyAgICAgICAgICAgIGlmICghaXNBbGl2ZSgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBndWFyYW50ZWVkIG5vdCB0byBvdmVyZmxvdworICAgICAgICAgICAgbG9uZyBuYW5vc1RvV2FpdCA9IG1pbGxpcyAqIE5BTk9TX1BFUl9NSUxMSSArIG5hbm9zOworCisgICAgICAgICAgICAvLyB3YWl0IHVudGlsIHRoaXMgdGhyZWFkIGNvbXBsZXRlcyBvciB0aGUgdGltZW91dCBoYXMgZWxhcHNlZAorICAgICAgICAgICAgbG9uZyBzdGFydCA9IFN5c3RlbS5uYW5vVGltZSgpOworICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICB0LndhaXQobWlsbGlzLCBuYW5vcyk7CisgICAgICAgICAgICAgICAgaWYgKCFpc0FsaXZlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGxvbmcgbmFub3NFbGFwc2VkID0gU3lzdGVtLm5hbm9UaW1lKCkgLSBzdGFydDsKKyAgICAgICAgICAgICAgICBsb25nIG5hbm9zUmVtYWluaW5nID0gbmFub3NUb1dhaXQgLSBuYW5vc0VsYXBzZWQ7CisgICAgICAgICAgICAgICAgaWYgKG5hbm9zUmVtYWluaW5nIDw9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG1pbGxpcyA9IG5hbm9zUmVtYWluaW5nIC8gTkFOT1NfUEVSX01JTExJOworICAgICAgICAgICAgICAgIG5hbm9zID0gKGludCkgKG5hbm9zUmVtYWluaW5nIC0gbWlsbGlzICogTkFOT1NfUEVSX01JTExJKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRocm93cyB7QGNvZGUgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259LgorICAgICAqCisgICAgICogQHNlZSBUaHJlYWQjc3VzcGVuZCgpCisgICAgICogQGRlcHJlY2F0ZWQgVXNlZCB3aXRoIGRlcHJlY2F0ZWQgbWV0aG9kIHtAbGluayBUaHJlYWQjc3VzcGVuZH0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBmaW5hbCB2b2lkIHJlc3VtZSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbHMgdGhlIDxjb2RlPnJ1bigpPC9jb2RlPiBtZXRob2Qgb2YgdGhlIFJ1bm5hYmxlIG9iamVjdCB0aGUgcmVjZWl2ZXIKKyAgICAgKiBob2xkcy4gSWYgbm8gUnVubmFibGUgaXMgc2V0LCBkb2VzIG5vdGhpbmcuCisgICAgICoKKyAgICAgKiBAc2VlIFRocmVhZCNzdGFydAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgaWYgKHRhcmdldCAhPSBudWxsKSB7CisgICAgICAgICAgICB0YXJnZXQucnVuKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGNvbnRleHQgQ2xhc3NMb2FkZXIgZm9yIHRoZSByZWNlaXZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbCBUaGUgY29udGV4dCBDbGFzc0xvYWRlcgorICAgICAqIEBzZWUgI2dldENvbnRleHRDbGFzc0xvYWRlcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q29udGV4dENsYXNzTG9hZGVyKENsYXNzTG9hZGVyIGNsKSB7CisgICAgICAgIGNvbnRleHRDbGFzc0xvYWRlciA9IGNsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCBpZiB0aGUgcmVjZWl2ZXIgaXMgYSBkYWVtb24gVGhyZWFkIG9yIG5vdC4gVGhpcyBjYW4gb25seSBiZSBkb25lCisgICAgICogYmVmb3JlIHRoZSBUaHJlYWQgc3RhcnRzIHJ1bm5pbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXNEYWVtb24KKyAgICAgKiAgICAgICAgICAgIGluZGljYXRlcyB3aGV0aGVyIHRoZSBUaHJlYWQgc2hvdWxkIGJlIGRhZW1vbiBvciBub3QKKyAgICAgKiBAc2VlIFRocmVhZCNpc0RhZW1vbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldERhZW1vbihib29sZWFuIGlzRGFlbW9uKSB7CisgICAgICAgIGlmIChoYXNCZWVuU3RhcnRlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxUaHJlYWRTdGF0ZUV4Y2VwdGlvbigiVGhyZWFkIGFscmVhZHkgc3RhcnRlZC4iKTsgLy8gVE9ETyBFeHRlcm5hbGl6ZT8KKyAgICAgICAgfQorCisgICAgICAgIGlmICh2bVRocmVhZCA9PSBudWxsKSB7CisgICAgICAgICAgICBkYWVtb24gPSBpc0RhZW1vbjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRlZmF1bHQgdW5jYXVnaHQgZXhjZXB0aW9uIGhhbmRsZXIuIFRoaXMgaGFuZGxlciBpcyBpbnZva2VkIGluCisgICAgICogY2FzZSBhbnkgVGhyZWFkIGRpZXMgZHVlIHRvIGFuIHVuaGFuZGxlZCBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaGFuZGxlcgorICAgICAqICAgICAgICAgICAgVGhlIGhhbmRsZXIgdG8gc2V0IG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldERlZmF1bHRVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXIoVW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyIGhhbmRsZXIpIHsKKyAgICAgICAgVGhyZWFkLmRlZmF1bHRVbmNhdWdodEhhbmRsZXIgPSBoYW5kbGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSBydW5uYWJsZSB0byBiZSBpbnZva2VkIHVwb24gaW50ZXJydXB0aW9uLiBJZiB0aGlzIHRocmVhZCBoYXMKKyAgICAgKiBhbHJlYWR5IGJlZW4gaW50ZXJydXB0ZWQsIHRoZSBydW5uYWJsZSB3aWxsIGJlIGludm9rZWQgaW1tZWRpYXRlbHkuIFRoZQorICAgICAqIGFjdGlvbiBzaG91bGQgYmUgaWRlbXBvdGVudCBhcyBpdCBtYXkgYmUgaW52b2tlZCBtdWx0aXBsZSB0aW1lcyBmb3IgYQorICAgICAqIHNpbmdsZSBpbnRlcnJ1cHRpb24uCisgICAgICoKKyAgICAgKiA8cD5FYWNoIGNhbGwgdG8gdGhpcyBtZXRob2QgbXVzdCBiZSBtYXRjaGVkIHdpdGggYSBjb3JyZXNwb25kaW5nIGNhbGwgdG8KKyAgICAgKiB7QGxpbmsgI3BvcEludGVycnVwdEFjdGlvbiR9LgorICAgICAqCisgICAgICogQGhpZGUgdXNlZCBieSBOSU8KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBwdXNoSW50ZXJydXB0QWN0aW9uJChSdW5uYWJsZSBpbnRlcnJ1cHRBY3Rpb24pIHsKKyAgICAgICAgc3luY2hyb25pemVkIChpbnRlcnJ1cHRBY3Rpb25zKSB7CisgICAgICAgICAgICBpbnRlcnJ1cHRBY3Rpb25zLmFkZChpbnRlcnJ1cHRBY3Rpb24pOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGludGVycnVwdEFjdGlvbiAhPSBudWxsICYmIGlzSW50ZXJydXB0ZWQoKSkgeworICAgICAgICAgICAgaW50ZXJydXB0QWN0aW9uLnJ1bigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB7QGNvZGUgaW50ZXJydXB0QWN0aW9ufSBzbyBpdCBpcyBub3QgaW52b2tlZCB1cG9uIGludGVycnVwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnRlcnJ1cHRBY3Rpb24gdGhlIHB1c2hlZCBhY3Rpb24sIHVzZWQgdG8gY2hlY2sgdGhhdCB0aGUgY2FsbAorICAgICAqICAgICBzdGFjayBpcyBjb3JyZWN0bHkgbmVzdGVkLgorICAgICAqCisgICAgICogQGhpZGUgdXNlZCBieSBOSU8KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBwb3BJbnRlcnJ1cHRBY3Rpb24kKFJ1bm5hYmxlIGludGVycnVwdEFjdGlvbikgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGludGVycnVwdEFjdGlvbnMpIHsKKyAgICAgICAgICAgIFJ1bm5hYmxlIHJlbW92ZWQgPSBpbnRlcnJ1cHRBY3Rpb25zLnJlbW92ZShpbnRlcnJ1cHRBY3Rpb25zLnNpemUoKSAtIDEpOworICAgICAgICAgICAgaWYgKGludGVycnVwdEFjdGlvbiAhPSByZW1vdmVkKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICJFeHBlY3RlZCAiICsgaW50ZXJydXB0QWN0aW9uICsgIiBidXQgd2FzICIgKyByZW1vdmVkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5hbWUgb2YgdGhlIFRocmVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aHJlYWROYW1lIHRoZSBuZXcgbmFtZSBmb3IgdGhlIFRocmVhZAorICAgICAqIEBzZWUgVGhyZWFkI2dldE5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXROYW1lKFN0cmluZyB0aHJlYWROYW1lKSB7CisgICAgICAgIGlmICh0aHJlYWROYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgbmFtZSA9IHRocmVhZE5hbWU7CisgICAgICAgIFZNVGhyZWFkIHZtdCA9IHRoaXMudm1UaHJlYWQ7CisgICAgICAgIGlmICh2bXQgIT0gbnVsbCkgeworICAgICAgICAgICAgLyogbm90aWZ5IHRoZSBWTSB0aGF0IHRoZSB0aHJlYWQgbmFtZSBoYXMgY2hhbmdlZCAqLworICAgICAgICAgICAgdm10Lm5hbWVDaGFuZ2VkKHRocmVhZE5hbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcHJpb3JpdHkgb2YgdGhlIFRocmVhZC4gTm90ZSB0aGF0IHRoZSBmaW5hbCBwcmlvcml0eSBzZXQgbWF5IG5vdAorICAgICAqIGJlIHRoZSBwYXJhbWV0ZXIgdGhhdCB3YXMgcGFzc2VkIC0gaXQgd2lsbCBkZXBlbmQgb24gdGhlIHJlY2VpdmVyJ3MKKyAgICAgKiBUaHJlYWRHcm91cC4gVGhlIHByaW9yaXR5IGNhbm5vdCBiZSBzZXQgdG8gYmUgaGlnaGVyIHRoYW4gdGhlIHJlY2VpdmVyJ3MKKyAgICAgKiBUaHJlYWRHcm91cCdzIG1heFByaW9yaXR5KCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJpb3JpdHkKKyAgICAgKiAgICAgICAgICAgIG5ldyBwcmlvcml0eSBmb3IgdGhlIFRocmVhZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG5ldyBwcmlvcml0eSBpcyBncmVhdGVyIHRoYW4gVGhyZWFkLk1BWF9QUklPUklUWSBvcgorICAgICAqICAgICAgICAgICAgIGxlc3MgdGhhbiBUaHJlYWQuTUlOX1BSSU9SSVRZCisgICAgICogQHNlZSBUaHJlYWQjZ2V0UHJpb3JpdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRQcmlvcml0eShpbnQgcHJpb3JpdHkpIHsKKyAgICAgICAgaWYgKHByaW9yaXR5IDwgVGhyZWFkLk1JTl9QUklPUklUWSB8fCBwcmlvcml0eSA+IFRocmVhZC5NQVhfUFJJT1JJVFkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlByaW9yaXR5IG91dCBvZiByYW5nZSIpOyAvLyBUT0RPIEV4dGVybmFsaXplPworICAgICAgICB9CisKKyAgICAgICAgaWYgKHByaW9yaXR5ID4gZ3JvdXAuZ2V0TWF4UHJpb3JpdHkoKSkgeworICAgICAgICAgICAgcHJpb3JpdHkgPSBncm91cC5nZXRNYXhQcmlvcml0eSgpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5wcmlvcml0eSA9IHByaW9yaXR5OworCisgICAgICAgIFZNVGhyZWFkIHZtdCA9IHRoaXMudm1UaHJlYWQ7CisgICAgICAgIGlmICh2bXQgIT0gbnVsbCkgeworICAgICAgICAgICAgdm10LnNldFByaW9yaXR5KHByaW9yaXR5KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIFNldHMgdGhlIHVuY2F1Z2h0IGV4Y2VwdGlvbiBoYW5kbGVyLiBUaGlzIGhhbmRsZXIgaXMgaW52b2tlZCBpbiBjYXNlIHRoaXMKKyAgICAgKiBUaHJlYWQgZGllcyBkdWUgdG8gYW4gdW5oYW5kbGVkIGV4Y2VwdGlvbi4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaGFuZGxlcgorICAgICAqICAgICAgICAgICAgVGhlIGhhbmRsZXIgdG8gc2V0IG9yIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlcihVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXIgaGFuZGxlcikgeworICAgICAgICB1bmNhdWdodEhhbmRsZXIgPSBoYW5kbGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhdXNlcyB0aGUgdGhyZWFkIHdoaWNoIHNlbnQgdGhpcyBtZXNzYWdlIHRvIHNsZWVwIGZvciB0aGUgZ2l2ZW4gaW50ZXJ2YWwKKyAgICAgKiBvZiB0aW1lIChnaXZlbiBpbiBtaWxsaXNlY29uZHMpLiBUaGUgcHJlY2lzaW9uIGlzIG5vdCBndWFyYW50ZWVkIC0gdGhlCisgICAgICogVGhyZWFkIG1heSBzbGVlcCBtb3JlIG9yIGxlc3MgdGhhbiByZXF1ZXN0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGltZQorICAgICAqICAgICAgICAgICAgVGhlIHRpbWUgdG8gc2xlZXAgaW4gbWlsbGlzZWNvbmRzLgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiA8Y29kZT5pbnRlcnJ1cHQoKTwvY29kZT4gd2FzIGNhbGxlZCBmb3IgdGhpcyBUaHJlYWQgd2hpbGUKKyAgICAgKiAgICAgICAgICAgICBpdCB3YXMgc2xlZXBpbmcKKyAgICAgKiBAc2VlIFRocmVhZCNpbnRlcnJ1cHQoKQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzbGVlcChsb25nIHRpbWUpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIFRocmVhZC5zbGVlcCh0aW1lLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYXVzZXMgdGhlIHRocmVhZCB3aGljaCBzZW50IHRoaXMgbWVzc2FnZSB0byBzbGVlcCBmb3IgdGhlIGdpdmVuIGludGVydmFsCisgICAgICogb2YgdGltZSAoZ2l2ZW4gaW4gbWlsbGlzZWNvbmRzIGFuZCBuYW5vc2Vjb25kcykuIFRoZSBwcmVjaXNpb24gaXMgbm90CisgICAgICogZ3VhcmFudGVlZCAtIHRoZSBUaHJlYWQgbWF5IHNsZWVwIG1vcmUgb3IgbGVzcyB0aGFuIHJlcXVlc3RlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtaWxsaXMKKyAgICAgKiAgICAgICAgICAgIFRoZSB0aW1lIHRvIHNsZWVwIGluIG1pbGxpc2Vjb25kcy4KKyAgICAgKiBAcGFyYW0gbmFub3MKKyAgICAgKiAgICAgICAgICAgIEV4dHJhIG5hbm9zZWNvbmQgcHJlY2lzaW9uCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIDxjb2RlPmludGVycnVwdCgpPC9jb2RlPiB3YXMgY2FsbGVkIGZvciB0aGlzIFRocmVhZCB3aGlsZQorICAgICAqICAgICAgICAgICAgIGl0IHdhcyBzbGVlcGluZworICAgICAqIEBzZWUgVGhyZWFkI2ludGVycnVwdCgpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNsZWVwKGxvbmcgbWlsbGlzLCBpbnQgbmFub3MpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIFZNVGhyZWFkLnNsZWVwKG1pbGxpcywgbmFub3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0YXJ0cyB0aGUgbmV3IFRocmVhZCBvZiBleGVjdXRpb24uIFRoZSA8Y29kZT5ydW4oKTwvY29kZT4gbWV0aG9kIG9mCisgICAgICogdGhlIHJlY2VpdmVyIHdpbGwgYmUgY2FsbGVkIGJ5IHRoZSByZWNlaXZlciBUaHJlYWQgaXRzZWxmIChhbmQgbm90IHRoZQorICAgICAqIFRocmVhZCBjYWxsaW5nIDxjb2RlPnN0YXJ0KCk8L2NvZGU+KS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uIGlmIHRoZSBUaHJlYWQgaGFzIGJlZW4gc3RhcnRlZCBiZWZvcmUKKyAgICAgKgorICAgICAqIEBzZWUgVGhyZWFkI3J1bgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzdGFydCgpIHsKKyAgICAgICAgaWYgKGhhc0JlZW5TdGFydGVkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uKCJUaHJlYWQgYWxyZWFkeSBzdGFydGVkLiIpOyAvLyBUT0RPIEV4dGVybmFsaXplPworICAgICAgICB9CisKKyAgICAgICAgaGFzQmVlblN0YXJ0ZWQgPSB0cnVlOworCisgICAgICAgIFZNVGhyZWFkLmNyZWF0ZSh0aGlzLCBzdGFja1NpemUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcXVlc3RzIHRoZSByZWNlaXZlciBUaHJlYWQgdG8gc3RvcCBhbmQgdGhyb3cgVGhyZWFkRGVhdGguIFRoZSBUaHJlYWQgaXMKKyAgICAgKiByZXN1bWVkIGlmIGl0IHdhcyBzdXNwZW5kZWQgYW5kIGF3YWtlbmVkIGlmIGl0IHdhcyBzbGVlcGluZywgc28gdGhhdCBpdAorICAgICAqIGNhbiBwcm9jZWVkIHRvIHRocm93IFRocmVhZERlYXRoLgorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgYmVjYXVzZSBzdG9wcGluZyBhIHRocmVhZCBpbiB0aGlzIG1hbm5lciBpcyB1bnNhZmUgYW5kIGNhbgorICAgICAqIGxlYXZlIHlvdXIgYXBwbGljYXRpb24gYW5kIHRoZSBWTSBpbiBhbiB1bnByZWRpY3RhYmxlIHN0YXRlLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGZpbmFsIHZvaWQgc3RvcCgpIHsKKyAgICAgICAgc3RvcChuZXcgVGhyZWFkRGVhdGgoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhyb3dzIHtAY29kZSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnRocm93YWJsZSgpPC9jb2RlPiBpcworICAgICAqICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4KKyAgICAgKiBAZGVwcmVjYXRlZCBiZWNhdXNlIHN0b3BwaW5nIGEgdGhyZWFkIGluIHRoaXMgbWFubmVyIGlzIHVuc2FmZSBhbmQgY2FuCisgICAgICogbGVhdmUgeW91ciBhcHBsaWNhdGlvbiBhbmQgdGhlIFZNIGluIGFuIHVucHJlZGljdGFibGUgc3RhdGUuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgZmluYWwgc3luY2hyb25pemVkIHZvaWQgc3RvcChUaHJvd2FibGUgdGhyb3dhYmxlKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRocm93cyB7QGNvZGUgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259LgorICAgICAqCisgICAgICogQHNlZSBUaHJlYWQjcmVzdW1lKCkKKyAgICAgKiBAZGVwcmVjYXRlZCBNYXkgY2F1c2UgZGVhZGxvY2tzLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGZpbmFsIHZvaWQgc3VzcGVuZCgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhlCisgICAgICogVGhyZWFkLiBJdCBpbmNsdWRlcyB0aGUgVGhyZWFkJ3MgbmFtZSwgcHJpb3JpdHksIGFuZCBncm91cCBuYW1lLgorICAgICAqCisgICAgICogQHJldHVybiBhIHByaW50YWJsZSByZXByZXNlbnRhdGlvbiBmb3IgdGhlIHJlY2VpdmVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiAiVGhyZWFkWyIgKyBuYW1lICsgIiwiICsgcHJpb3JpdHkgKyAiLCIgKyBncm91cC5nZXROYW1lKCkgKyAiXSI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2F1c2VzIHRoZSBjYWxsaW5nIFRocmVhZCB0byB5aWVsZCBleGVjdXRpb24gdGltZSB0byBhbm90aGVyIFRocmVhZCB0aGF0CisgICAgICogaXMgcmVhZHkgdG8gcnVuLiBUaGUgYWN0dWFsIHNjaGVkdWxpbmcgaXMgaW1wbGVtZW50YXRpb24tZGVwZW5kZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB5aWVsZCgpIHsKKyAgICAgICAgVk1UaHJlYWQueWllbGQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgY3VycmVudCBUaHJlYWQgaGFzIGEgbW9uaXRvciBsb2NrIG9uIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0IHRoZSBvYmplY3QgdG8gdGVzdCBmb3IgdGhlIG1vbml0b3IgbG9jaworICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY3VycmVudCB0aHJlYWQgaGFzIGEgbW9uaXRvciBsb2NrIG9uIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIG9iamVjdDsgZmFsc2Ugb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGhvbGRzTG9jayhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIHJldHVybiBjdXJyZW50VGhyZWFkKCkudm1UaHJlYWQuaG9sZHNMb2NrKG9iamVjdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW1wbGVtZW50ZWQgYnkgb2JqZWN0cyB0aGF0IHdhbnQgdG8gaGFuZGxlIGNhc2VzIHdoZXJlIGEgdGhyZWFkIGlzIGJlaW5nCisgICAgICogdGVybWluYXRlZCBieSBhbiB1bmNhdWdodCBleGNlcHRpb24uIFVwb24gc3VjaCB0ZXJtaW5hdGlvbiwgdGhlIGhhbmRsZXIKKyAgICAgKiBpcyBub3RpZmllZCBvZiB0aGUgdGVybWluYXRpbmcgdGhyZWFkIGFuZCBjYXVzYWwgZXhjZXB0aW9uLiBJZiB0aGVyZSBpcworICAgICAqIG5vIGV4cGxpY2l0IGhhbmRsZXIgc2V0IHRoZW4gdGhlIHRocmVhZCdzIGdyb3VwIGlzIHRoZSBkZWZhdWx0IGhhbmRsZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnRlcmZhY2UgVW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyIHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB0aHJlYWQgaXMgYmVpbmcgdGVybWluYXRlZCBieSBhbiB1bmNhdWdodCBleGNlcHRpb24uIEZ1cnRoZXIKKyAgICAgICAgICogZXhjZXB0aW9ucyB0aHJvd24gaW4gdGhpcyBtZXRob2QgYXJlIHByZXZlbnQgdGhlIHJlbWFpbmRlciBvZiB0aGUKKyAgICAgICAgICogbWV0aG9kIGZyb20gZXhlY3V0aW5nLCBidXQgYXJlIG90aGVyd2lzZSBpZ25vcmVkLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gdGhyZWFkIHRoZSB0aHJlYWQgdGhhdCBoYXMgYW4gdW5jYXVnaHQgZXhjZXB0aW9uCisgICAgICAgICAqIEBwYXJhbSBleCB0aGUgZXhjZXB0aW9uIHRoYXQgd2FzIHRocm93bgorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCB1bmNhdWdodEV4Y2VwdGlvbihUaHJlYWQgdGhyZWFkLCBUaHJvd2FibGUgZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVucGFya3MgdGhpcyB0aHJlYWQuIFRoaXMgdW5ibG9ja3MgdGhlIHRocmVhZCBpdCBpZiBpdCB3YXMKKyAgICAgKiBwcmV2aW91c2x5IHBhcmtlZCwgb3IgaW5kaWNhdGVzIHRoYXQgdGhlIHRocmVhZCBpcyAicHJlZW1wdGl2ZWx5CisgICAgICogdW5wYXJrZWQiIGlmIGl0IHdhc24ndCBhbHJlYWR5IHBhcmtlZC4gVGhlIGxhdHRlciBtZWFucyB0aGF0IHRoZQorICAgICAqIG5leHQgdGltZSB0aGUgdGhyZWFkIGlzIHRvbGQgdG8gcGFyaywgaXQgd2lsbCBtZXJlbHkgY2xlYXIgaXRzCisgICAgICogbGF0ZW50IHBhcmsgYml0IGFuZCBjYXJyeSBvbiB3aXRob3V0IGJsb2NraW5nLgorICAgICAqCisgICAgICogPHA+U2VlIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5Mb2NrU3VwcG9ydH0gZm9yIG1vcmUKKyAgICAgKiBpbi1kZXB0aCBpbmZvcm1hdGlvbiBvZiB0aGUgYmVoYXZpb3Igb2YgdGhpcyBtZXRob2QuPC9wPgorICAgICAqCisgICAgICogQGhpZGUgZm9yIFVuc2FmZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVucGFyaygpIHsKKyAgICAgICAgVk1UaHJlYWQgdm10ID0gdm1UaHJlYWQ7CisKKyAgICAgICAgaWYgKHZtdCA9PSBudWxsKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogdm1UaHJlYWQgaXMgbnVsbCBiZWZvcmUgdGhlIHRocmVhZCBpcyBzdGFydCgpZWQuIEluCisgICAgICAgICAgICAgKiB0aGlzIGNhc2UsIHdlIGp1c3QgZ28gYWhlYWQgYW5kIHNldCB0aGUgc3RhdGUgdG8KKyAgICAgICAgICAgICAqIFBSRUVNUFRJVkVMWV9VTlBBUktFRC4gU2luY2UgdGhpcyBoYXBwZW5zIGJlZm9yZSB0aGUKKyAgICAgICAgICAgICAqIHRocmVhZCBpcyBzdGFydGVkLCB3ZSBkb24ndCBoYXZlIHRvIHdvcnJ5IGFib3V0CisgICAgICAgICAgICAgKiBzeW5jaHJvbml6aW5nIHdpdGggaXQuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHBhcmtTdGF0ZSA9IFBhcmtTdGF0ZS5QUkVFTVBUSVZFTFlfVU5QQVJLRUQ7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBzeW5jaHJvbml6ZWQgKHZtdCkgeworICAgICAgICAgICAgc3dpdGNoIChwYXJrU3RhdGUpIHsKKyAgICAgICAgICAgICAgICBjYXNlIFBhcmtTdGF0ZS5QUkVFTVBUSVZFTFlfVU5QQVJLRUQ6IHsKKyAgICAgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgICAgICogTm90aGluZyB0byBkbyBpbiB0aGlzIGNhc2U6IEJ5IGRlZmluaXRpb24sIGEKKyAgICAgICAgICAgICAgICAgICAgICogcHJlZW1wdGl2ZWx5IHVucGFya2VkIHRocmVhZCBpcyB0byByZW1haW4gaW4KKyAgICAgICAgICAgICAgICAgICAgICogdGhlIHByZWVtcHRpdmVseSB1bnBhcmtlZCBzdGF0ZSBpZiBpdCBpcyB0b2xkCisgICAgICAgICAgICAgICAgICAgICAqIHRvIHVucGFyay4KKyAgICAgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjYXNlIFBhcmtTdGF0ZS5VTlBBUktFRDogeworICAgICAgICAgICAgICAgICAgICBwYXJrU3RhdGUgPSBQYXJrU3RhdGUuUFJFRU1QVElWRUxZX1VOUEFSS0VEOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZGVmYXVsdCAvKnBhcmtlZCovOiB7CisgICAgICAgICAgICAgICAgICAgIHBhcmtTdGF0ZSA9IFBhcmtTdGF0ZS5VTlBBUktFRDsKKyAgICAgICAgICAgICAgICAgICAgdm10Lm5vdGlmeUFsbCgpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJrcyB0aGUgY3VycmVudCB0aHJlYWQgZm9yIGEgcGFydGljdWxhciBudW1iZXIgb2YgbmFub3NlY29uZHMsIG9yCisgICAgICogaW5kZWZpbml0ZWx5LiBJZiBub3QgaW5kZWZpbml0ZWx5LCB0aGlzIG1ldGhvZCB1bnBhcmtzIHRoZSB0aHJlYWQKKyAgICAgKiBhZnRlciB0aGUgZ2l2ZW4gbnVtYmVyIG9mIG5hbm9zZWNvbmRzIGlmIG5vIG90aGVyIHRocmVhZCB1bnBhcmtzIGl0CisgICAgICogZmlyc3QuIElmIHRoZSB0aHJlYWQgaGFzIGJlZW4gInByZWVtcHRpdmVseSB1bnBhcmtlZCwiIHRoaXMgbWV0aG9kCisgICAgICogY2FuY2VscyB0aGF0IHVucGFya2luZyBhbmQgcmV0dXJucyBpbW1lZGlhdGVseS4gVGhpcyBtZXRob2QgbWF5CisgICAgICogYWxzbyByZXR1cm4gc3B1cmlvdXNseSAodGhhdCBpcywgd2l0aG91dCB0aGUgdGhyZWFkIGJlaW5nIHRvbGQgdG8KKyAgICAgKiB1bnBhcmsgYW5kIHdpdGhvdXQgdGhlIGluZGljYXRlZCBhbW91bnQgb2YgdGltZSBlbGFwc2luZykuCisgICAgICoKKyAgICAgKiA8cD5TZWUge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLkxvY2tTdXBwb3J0fSBmb3IgbW9yZQorICAgICAqIGluLWRlcHRoIGluZm9ybWF0aW9uIG9mIHRoZSBiZWhhdmlvciBvZiB0aGlzIG1ldGhvZC48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBtdXN0IG9ubHkgYmUgY2FsbGVkIHdoZW4gPGNvZGU+dGhpczwvY29kZT4gaXMgdGhlIGN1cnJlbnQKKyAgICAgKiB0aHJlYWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFub3MgbnVtYmVyIG9mIG5hbm9zZWNvbmRzIHRvIHBhcmsgZm9yIG9yIDxjb2RlPjA8L2NvZGU+CisgICAgICogdG8gcGFyayBpbmRlZmluaXRlbHkKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB0aHJvd24gaWYgPGNvZGU+bmFub3MgJmx0OyAwPC9jb2RlPgorICAgICAqCisgICAgICogQGhpZGUgZm9yIFVuc2FmZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHBhcmtGb3IobG9uZyBuYW5vcykgeworICAgICAgICBWTVRocmVhZCB2bXQgPSB2bVRocmVhZDsKKworICAgICAgICBpZiAodm10ID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIFJ1bm5pbmcgdGhyZWFkcyBzaG91bGQgYWx3YXlzIGhhdmUgYW4gYXNzb2NpYXRlZCB2bVRocmVhZC4KKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgICAgICB9CisKKyAgICAgICAgc3luY2hyb25pemVkICh2bXQpIHsKKyAgICAgICAgICAgIHN3aXRjaCAocGFya1N0YXRlKSB7CisgICAgICAgICAgICAgICAgY2FzZSBQYXJrU3RhdGUuUFJFRU1QVElWRUxZX1VOUEFSS0VEOiB7CisgICAgICAgICAgICAgICAgICAgIHBhcmtTdGF0ZSA9IFBhcmtTdGF0ZS5VTlBBUktFRDsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNhc2UgUGFya1N0YXRlLlVOUEFSS0VEOiB7CisgICAgICAgICAgICAgICAgICAgIGxvbmcgbWlsbGlzID0gbmFub3MgLyBOQU5PU19QRVJfTUlMTEk7CisgICAgICAgICAgICAgICAgICAgIG5hbm9zICU9IE5BTk9TX1BFUl9NSUxMSTsKKworICAgICAgICAgICAgICAgICAgICBwYXJrU3RhdGUgPSBQYXJrU3RhdGUuUEFSS0VEOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgdm10LndhaXQobWlsbGlzLCAoaW50KSBuYW5vcyk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICAgICAgICAgKiBOb3RlOiBJZiBwYXJrU3RhdGUgbWFuYWdlcyB0byBiZWNvbWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAqIFBSRUVNUFRJVkVMWV9VTlBBUktFRCBiZWZvcmUgaGl0dGluZyB0aGlzCisgICAgICAgICAgICAgICAgICAgICAgICAgKiBjb2RlLCBpdCBzaG91bGQgbGVmdCBpbiB0aGF0IHN0YXRlLgorICAgICAgICAgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFya1N0YXRlID09IFBhcmtTdGF0ZS5QQVJLRUQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJrU3RhdGUgPSBQYXJrU3RhdGUuVU5QQVJLRUQ7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGRlZmF1bHQgLypwYXJrZWQqLzogeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNob3VsZG4ndCBoYXBwZW46IGF0dGVtcHQgdG8gcmVwYXJrIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFya3MgdGhlIGN1cnJlbnQgdGhyZWFkIHVudGlsIHRoZSBzcGVjaWZpZWQgc3lzdGVtIHRpbWUuIFRoaXMKKyAgICAgKiBtZXRob2QgYXR0ZW1wdHMgdG8gdW5wYXJrIHRoZSBjdXJyZW50IHRocmVhZCBpbW1lZGlhdGVseSBhZnRlcgorICAgICAqIDxjb2RlPlN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpPC9jb2RlPiByZWFjaGVzIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB2YWx1ZSwgaWYgbm8gb3RoZXIgdGhyZWFkIHVucGFya3MgaXQgZmlyc3QuIElmIHRoZSB0aHJlYWQgaGFzCisgICAgICogYmVlbiAicHJlZW1wdGl2ZWx5IHVucGFya2VkLCIgdGhpcyBtZXRob2QgY2FuY2VscyB0aGF0CisgICAgICogdW5wYXJraW5nIGFuZCByZXR1cm5zIGltbWVkaWF0ZWx5LiBUaGlzIG1ldGhvZCBtYXkgYWxzbyByZXR1cm4KKyAgICAgKiBzcHVyaW91c2x5ICh0aGF0IGlzLCB3aXRob3V0IHRoZSB0aHJlYWQgYmVpbmcgdG9sZCB0byB1bnBhcmsKKyAgICAgKiBhbmQgd2l0aG91dCB0aGUgaW5kaWNhdGVkIGFtb3VudCBvZiB0aW1lIGVsYXBzaW5nKS4KKyAgICAgKgorICAgICAqIDxwPlNlZSB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3MuTG9ja1N1cHBvcnR9IGZvciBtb3JlCisgICAgICogaW4tZGVwdGggaW5mb3JtYXRpb24gb2YgdGhlIGJlaGF2aW9yIG9mIHRoaXMgbWV0aG9kLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIG11c3Qgb25seSBiZSBjYWxsZWQgd2hlbiA8Y29kZT50aGlzPC9jb2RlPiBpcyB0aGUKKyAgICAgKiBjdXJyZW50IHRocmVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aW1lIHRoZSB0aW1lIGFmdGVyIHdoaWNoIHRoZSB0aHJlYWQgc2hvdWxkIGJlIHVucGFya2VkLAorICAgICAqIGluIGFic29sdXRlIG1pbGxpc2Vjb25kcy1zaW5jZS10aGUtZXBvY2gKKyAgICAgKgorICAgICAqIEBoaWRlIGZvciBVbnNhZmUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwYXJrVW50aWwobG9uZyB0aW1lKSB7CisgICAgICAgIFZNVGhyZWFkIHZtdCA9IHZtVGhyZWFkOworCisgICAgICAgIGlmICh2bXQgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gUnVubmluZyB0aHJlYWRzIHNob3VsZCBhbHdheXMgaGF2ZSBhbiBhc3NvY2lhdGVkIHZtVGhyZWFkLgorICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CisgICAgICAgIH0KKworICAgICAgICBzeW5jaHJvbml6ZWQgKHZtdCkgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIE5vdGU6IFRoaXMgY29uZmxhdGVzIHRoZSB0d28gdGltZSBiYXNlcyBvZiAid2FsbCBjbG9jayIKKyAgICAgICAgICAgICAqIHRpbWUgYW5kICJtb25vdG9uaWMgdXB0aW1lIiB0aW1lLiBIb3dldmVyLCBnaXZlbiB0aGF0CisgICAgICAgICAgICAgKiB0aGUgdW5kZXJseWluZyBzeXN0ZW0gY2FuIG9ubHkgd2FpdCBvbiBtb25vdG9uaWMgdGltZSwKKyAgICAgICAgICAgICAqIGl0IGlzIHVuY2xlYXIgaWYgdGhlcmUgaXMgYW55IHdheSB0byBhdm9pZCB0aGUKKyAgICAgICAgICAgICAqIGNvbmZsYXRpb24uIFRoZSBkb3duc2lkZSBoZXJlIGlzIHRoYXQgaWYsIGhhdmluZworICAgICAgICAgICAgICogY2FsY3VsYXRlZCB0aGUgZGVsYXksIHRoZSB3YWxsIGNsb2NrIGdldHMgbW92ZWQgYWhlYWQsCisgICAgICAgICAgICAgKiB0aGlzIG1ldGhvZCBtYXkgbm90IHJldHVybiB1bnRpbCB3ZWxsIGFmdGVyIHRoZSB3YWxsCisgICAgICAgICAgICAgKiBjbG9jayBoYXMgcmVhY2hlZCB0aGUgb3JpZ2luYWxseSBkZXNpZ25hdGVkIHRpbWUuIFRoZQorICAgICAgICAgICAgICogcmV2ZXJzZSBwcm9ibGVtICh0aGUgd2FsbCBjbG9jayBiZWluZyB0dXJuZWQgYmFjaykKKyAgICAgICAgICAgICAqIGlzbid0IGEgYmlnIGRlYWwsIHNpbmNlIHRoaXMgbWV0aG9kIGlzIGFsbG93ZWQgdG8KKyAgICAgICAgICAgICAqIHNwdXJpb3VzbHkgcmV0dXJuIGZvciBhbnkgcmVhc29uLCBhbmQgdGhpcyBzaXR1YXRpb24KKyAgICAgICAgICAgICAqIGNhbiBzYWZlbHkgYmUgY29uc3RydWVkIGFzIGp1c3Qgc3VjaCBhIHNwdXJpb3VzIHJldHVybi4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgbG9uZyBkZWxheU1pbGxpcyA9IHRpbWUgLSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKworICAgICAgICAgICAgaWYgKGRlbGF5TWlsbGlzIDw9IDApIHsKKyAgICAgICAgICAgICAgICBwYXJrU3RhdGUgPSBQYXJrU3RhdGUuVU5QQVJLRUQ7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHBhcmtGb3IoZGVsYXlNaWxsaXMgKiBOQU5PU19QRVJfTUlMTEkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9UaHJlYWREZWF0aC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9UaHJlYWREZWF0aC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNmZmJiMGEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1RocmVhZERlYXRoLmphdmEKQEAgLTAsMCArMSwzNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKKy8qKgorICogVGhyZWFkRGVhdGggaXMgdGhyb3duIHdoZW4gYSB0aHJlYWQgc3RvcHMgZXhlY3V0aW5nLiBJdCBpcyB1c2VkIHRvIGFpZCBpbiB0aGUKKyAqIG9yZGVybHkgdW5yb2xsaW5nIG9mIHRoZSB0aHJlYWQncyBzdGFjayAoZWcuIGNsZWFudXAgb2YgbW9uaXRvcnMpLgorICovCitwdWJsaWMgY2xhc3MgVGhyZWFkRGVhdGggZXh0ZW5kcyBFcnJvciB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDQxNzEyODU2NTAzMzA4ODI2OEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MuIE5vdGUgdGhhdCBpbiB0aGUgY2FzZSBvZgorICAgICAqIFRocmVhZERlYXRoLCB0aGUgc3RhY2sgdHJhY2UgbWF5IDxlbT5ub3Q8L2VtPiBiZSBmaWxsZWQgaW4gYSB3YXkgd2hpY2gKKyAgICAgKiBhbGxvd3MgYSBzdGFjayB0cmFjZSB0byBiZSBwcmludGVkLgorICAgICAqLworICAgIHB1YmxpYyBUaHJlYWREZWF0aCgpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1RocmVhZEdyb3VwLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1RocmVhZEdyb3VwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTk5ZTk5ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvVGhyZWFkR3JvdXAuamF2YQpAQCAtMCwwICsxLDcyNiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgamF2YS5sYW5nLnJlZi5XZWFrUmVmZXJlbmNlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGxpYmNvcmUudXRpbC5Db2xsZWN0aW9uVXRpbHM7CisKKy8qKgorICoge0Bjb2RlIFRocmVhZEdyb3VwfSBpcyBhIG1lYW5zIG9mIG9yZ2FuaXppbmcgdGhyZWFkcyBpbnRvIGEgaGllcmFyY2hpY2FsIHN0cnVjdHVyZS4KKyAqIFRoaXMgY2xhc3MgaXMgb2Jzb2xldGUuIFNlZSA8aT5FZmZlY3RpdmUgSmF2YTwvaT4gSXRlbSA3MywgIkF2b2lkIHRocmVhZCBncm91cHMiIGZvciBkZXRhaWxzLgorICogQHNlZSBUaHJlYWQKKyAqLworcHVibGljIGNsYXNzIFRocmVhZEdyb3VwIGltcGxlbWVudHMgVGhyZWFkLlVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlciB7CisKKyAgICAvLyBOYW1lIG9mIHRoaXMgVGhyZWFkR3JvdXAKKyAgICAvLyBWTSBuZWVkcyB0aGlzIGZpZWxkIG5hbWUgZm9yIGRlYnVnZ2luZy4KKyAgICBwcml2YXRlIFN0cmluZyBuYW1lOworCisgICAgLy8gTWF4aW11bSBwcmlvcml0eSBmb3IgVGhyZWFkcyBpbnNpZGUgdGhpcyBUaHJlYWRHcm91cAorICAgIHByaXZhdGUgaW50IG1heFByaW9yaXR5ID0gVGhyZWFkLk1BWF9QUklPUklUWTsKKworICAgIC8vIFRoZSBUaHJlYWRHcm91cCB0byB3aGljaCB0aGlzIFRocmVhZEdyb3VwIGJlbG9uZ3MKKyAgICAvLyBWTSBuZWVkcyB0aGlzIGZpZWxkIG5hbWUgZm9yIGRlYnVnZ2luZy4KKyAgICBmaW5hbCBUaHJlYWRHcm91cCBwYXJlbnQ7CisKKyAgICAvKioKKyAgICAgKiBXZWFrIHJlZmVyZW5jZXMgdG8gdGhlIHRocmVhZHMgaW4gdGhpcyBncm91cC4KKyAgICAgKiBBY2Nlc3MgaXMgZ3VhcmRlZCBieSBzeW5jaHJvbml6aW5nIG9uIHRoaXMgZmllbGQuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PFdlYWtSZWZlcmVuY2U8VGhyZWFkPj4gdGhyZWFkUmVmcyA9IG5ldyBBcnJheUxpc3Q8V2Vha1JlZmVyZW5jZTxUaHJlYWQ+Pig1KTsKKworICAgIC8qKgorICAgICAqIFZpZXcgb2YgdGhlIHRocmVhZHMuCisgICAgICogQWNjZXNzIGlzIGd1YXJkZWQgYnkgc3luY2hyb25pemluZyBvbiB0aHJlYWRSZWZzLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgSXRlcmFibGU8VGhyZWFkPiB0aHJlYWRzID0gQ29sbGVjdGlvblV0aWxzLmRlcmVmZXJlbmNlSXRlcmFibGUodGhyZWFkUmVmcywgdHJ1ZSk7CisKKyAgICAvKioKKyAgICAgKiBUaHJlYWQgZ3JvdXBzLiBBY2Nlc3MgaXMgZ3VhcmRlZCBieSBzeW5jaHJvbml6aW5nIG9uIHRoaXMgZmllbGQuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PFRocmVhZEdyb3VwPiBncm91cHMgPSBuZXcgQXJyYXlMaXN0PFRocmVhZEdyb3VwPigzKTsKKworICAgIC8vIFdoZXRoZXIgdGhpcyBUaHJlYWRHcm91cCBpcyBhIGRhZW1vbiBUaHJlYWRHcm91cCBvciBub3QKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNEYWVtb247CisKKyAgICAvLyBXaGV0aGVyIHRoaXMgVGhyZWFkR3JvdXAgaGFzIGFscmVhZHkgYmVlbiBkZXN0cm95ZWQgb3Igbm90CisgICAgcHJpdmF0ZSBib29sZWFuIGlzRGVzdHJveWVkOworCisgICAgLyogdGhlIFZNIHVzZXMgdGhlc2UgZGlyZWN0bHk7IGRvIG5vdCByZW5hbWUgKi8KKyAgICBzdGF0aWMgZmluYWwgVGhyZWFkR3JvdXAgbVN5c3RlbSA9IG5ldyBUaHJlYWRHcm91cCgpOworICAgIHN0YXRpYyBmaW5hbCBUaHJlYWRHcm91cCBtTWFpbiA9IG5ldyBUaHJlYWRHcm91cChtU3lzdGVtLCAibWFpbiIpOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVGhyZWFkR3JvdXB9IHdpdGggdGhlIGdpdmVuIG5hbWUuIFRoZSBuZXcge0Bjb2RlIFRocmVhZEdyb3VwfQorICAgICAqIHdpbGwgYmUgY2hpbGQgb2YgdGhlIHtAY29kZSBUaHJlYWRHcm91cH0gdG8gd2hpY2ggdGhlIGNhbGxpbmcgdGhyZWFkIGJlbG9uZ3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZQorICAgICAqIEBzZWUgVGhyZWFkI2N1cnJlbnRUaHJlYWQKKyAgICAgKi8KKyAgICBwdWJsaWMgVGhyZWFkR3JvdXAoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgdGhpcyhUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldFRocmVhZEdyb3VwKCksIG5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFRocmVhZEdyb3VwfSB3aXRoIHRoZSBnaXZlbiBuYW1lLCBhcyBhIGNoaWxkIG9mIHRoZQorICAgICAqIGdpdmVuIHtAY29kZSBUaHJlYWRHcm91cH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyZW50IHRoZSBwYXJlbnQKKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIHBhcmVudCA9PSBudWxsfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uIGlmIHtAY29kZSBwYXJlbnR9IGhhcyBiZWVuCisgICAgICogICAgICAgICBkZXN0cm95ZWQgYWxyZWFkeQorICAgICAqLworICAgIHB1YmxpYyBUaHJlYWRHcm91cChUaHJlYWRHcm91cCBwYXJlbnQsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIGlmIChwYXJlbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJwYXJlbnQgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgIHRoaXMucGFyZW50ID0gcGFyZW50OworICAgICAgICBpZiAocGFyZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHBhcmVudC5hZGQodGhpcyk7CisgICAgICAgICAgICB0aGlzLnNldE1heFByaW9yaXR5KHBhcmVudC5nZXRNYXhQcmlvcml0eSgpKTsKKyAgICAgICAgICAgIGlmIChwYXJlbnQuaXNEYWVtb24oKSkgeworICAgICAgICAgICAgICAgIHRoaXMuc2V0RGFlbW9uKHRydWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZSB0aGUgc3BlY2lhbCAic3lzdGVtIiBUaHJlYWRHcm91cC4gV2FzICJtYWluIiBpbiBIYXJtb255LAorICAgICAqIGJ1dCB3ZSBoYXZlIGFuIGFkZGl0aW9uYWwgZ3JvdXAgYWJvdmUgdGhhdCBpbiBBbmRyb2lkLgorICAgICAqLworICAgIHByaXZhdGUgVGhyZWFkR3JvdXAoKSB7CisgICAgICAgIHRoaXMubmFtZSA9ICJzeXN0ZW0iOworICAgICAgICB0aGlzLnBhcmVudCA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHJ1bm5pbmcge0Bjb2RlIFRocmVhZH1zIHdoaWNoIGFyZSBjaGlsZHJlbiBvZiB0aGlzIHRocmVhZCBncm91cCwKKyAgICAgKiBkaXJlY3RseSBvciBpbmRpcmVjdGx5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNoaWxkcmVuCisgICAgICovCisgICAgcHVibGljIGludCBhY3RpdmVDb3VudCgpIHsKKyAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgc3luY2hyb25pemVkICh0aHJlYWRSZWZzKSB7CisgICAgICAgICAgICBmb3IgKFRocmVhZCB0aHJlYWQgOiB0aHJlYWRzKSB7CisgICAgICAgICAgICAgICAgaWYgKHRocmVhZC5pc0FsaXZlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgc3luY2hyb25pemVkIChncm91cHMpIHsKKyAgICAgICAgICAgIGZvciAoVGhyZWFkR3JvdXAgZ3JvdXAgOiBncm91cHMpIHsKKyAgICAgICAgICAgICAgICBjb3VudCArPSBncm91cC5hY3RpdmVDb3VudCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBjb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Yge0Bjb2RlIFRocmVhZEdyb3VwfXMgd2hpY2ggYXJlIGNoaWxkcmVuIG9mIHRoaXMgZ3JvdXAsCisgICAgICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBjaGlsZHJlbgorICAgICAqLworICAgIHB1YmxpYyBpbnQgYWN0aXZlR3JvdXBDb3VudCgpIHsKKyAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgc3luY2hyb25pemVkIChncm91cHMpIHsKKyAgICAgICAgICAgIGZvciAoVGhyZWFkR3JvdXAgZ3JvdXAgOiBncm91cHMpIHsKKyAgICAgICAgICAgICAgICAvLyBPbmUgZm9yIHRoaXMgZ3JvdXAgJiB0aGUgc3ViZ3JvdXBzCisgICAgICAgICAgICAgICAgY291bnQgKz0gMSArIGdyb3VwLmFjdGl2ZUdyb3VwQ291bnQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY291bnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBhIHtAY29kZSBUaHJlYWRHcm91cH0gdG8gdGhpcyB0aHJlYWQgZ3JvdXAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZyBUaHJlYWRHcm91cCB0byBhZGQKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxUaHJlYWRTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGdyb3VwIGhhcyBiZWVuIGRlc3Ryb3llZCBhbHJlYWR5CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGFkZChUaHJlYWRHcm91cCBnKSB0aHJvd3MgSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChncm91cHMpIHsKKyAgICAgICAgICAgIGlmIChpc0Rlc3Ryb3llZCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsVGhyZWFkU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGdyb3Vwcy5hZGQoZyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb2VzIG5vdGhpbmcuIFRoZSBkZWZpbml0aW9uIG9mIHRoaXMgbWV0aG9kIGRlcGVuZHMgb24gdGhlIGRlcHJlY2F0ZWQKKyAgICAgKiBtZXRob2Qge0BsaW5rICNzdXNwZW5kKCl9LiBUaGUgZXhhY3QgYmVoYXZpb3Igb2YgdGhpcyBjYWxsIHdhcyBuZXZlcgorICAgICAqIHNwZWNpZmllZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBiIFVzZWQgdG8gY29udHJvbCBsb3cgbWVtb3J5IGltcGxpY2l0IHN1c3BlbnNpb24KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSAoYWx3YXlzKQorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgUmVxdWlyZWQgZGVwcmVjYXRlZCBtZXRob2Qgc3VzcGVuZCgpLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGJvb2xlYW4gYWxsb3dUaHJlYWRTdXNwZW5zaW9uKGJvb2xlYW4gYikgeworICAgICAgICAvLyBEb2VzIG5vdCBhcHBseSB0byB0aGlzIFZNLCBuby1vcAorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb2VzIG5vdGhpbmcuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgY2hlY2tBY2Nlc3MoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVzdHJveXMgdGhpcyB0aHJlYWQgZ3JvdXAgYW5kIHJlY3Vyc2l2ZWx5IGFsbCBpdHMgc3ViZ3JvdXBzLiBJdCBpcyBvbmx5IGxlZ2FsCisgICAgICogdG8gZGVzdHJveSBhIHtAY29kZSBUaHJlYWRHcm91cH0gdGhhdCBoYXMgbm8gdGhyZWFkcyBpbiBpdC4gQW55IGRhZW1vbgorICAgICAqIHtAY29kZSBUaHJlYWRHcm91cH0gaXMgZGVzdHJveWVkIGF1dG9tYXRpY2FsbHkgd2hlbiBpdCBiZWNvbWVzIGVtcHR5IChubyB0aHJlYWRzCisgICAgICogb3IgdGhyZWFkIGdyb3VwcyBpbiBpdCkuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxUaHJlYWRTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIHRocmVhZCBncm91cCBvciBhbnkgb2YgaXRzCisgICAgICogICAgICAgICBzdWJncm91cHMgaGFzIGJlZW4gZGVzdHJveWVkIGFscmVhZHkgb3IgaWYgaXQgc3RpbGwgY29udGFpbnMKKyAgICAgKiAgICAgICAgIHRocmVhZHMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgZGVzdHJveSgpIHsKKyAgICAgICAgc3luY2hyb25pemVkICh0aHJlYWRSZWZzKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGdyb3VwcykgeworICAgICAgICAgICAgICAgIGlmIChpc0Rlc3Ryb3llZCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUaHJlYWQgZ3JvdXAgd2FzIGFscmVhZHkgZGVzdHJveWVkOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAodGhpcy5uYW1lICE9IG51bGwgPyB0aGlzLm5hbWUgOiAibi9hIikpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAodGhyZWFkcy5pdGVyYXRvcigpLmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUaHJlYWQgZ3JvdXAgc3RpbGwgY29udGFpbnMgdGhyZWFkczogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKHRoaXMubmFtZSAhPSBudWxsID8gdGhpcy5uYW1lIDogIm4vYSIpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gQ2FsbCByZWN1cnNpdmVseSBmb3Igc3ViZ3JvdXBzCisgICAgICAgICAgICAgICAgd2hpbGUgKCFncm91cHMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFdlIGFsd2F5cyBnZXQgdGhlIGZpcnN0IGVsZW1lbnQgLSByZW1lbWJlciwgd2hlbiB0aGUKKyAgICAgICAgICAgICAgICAgICAgLy8gY2hpbGQgZGllcyBpdCByZW1vdmVzIGl0c2VsZiBmcm9tIG91ciBjb2xsZWN0aW9uLiBTZWUKKyAgICAgICAgICAgICAgICAgICAgLy8gYmVsb3cuCisgICAgICAgICAgICAgICAgICAgIGdyb3Vwcy5nZXQoMCkuZGVzdHJveSgpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChwYXJlbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBwYXJlbnQucmVtb3ZlKHRoaXMpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIE5vdyB0aGF0IHRoZSBUaHJlYWRHcm91cCBpcyByZWFsbHkgZGVzdHJveWVkIGl0IGNhbiBiZSB0YWdnZWQgYXMgc28KKyAgICAgICAgICAgICAgICB0aGlzLmlzRGVzdHJveWVkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQXV4aWxpYXJ5IG1ldGhvZCB0aGF0IGRlc3Ryb3lzIHRoaXMgdGhyZWFkIGdyb3VwIGFuZCByZWN1cnNpdmVseSBhbGwgaXRzCisgICAgICogc3ViZ3JvdXBzIGlmIHRoaXMgaXMgYSBkYWVtb24gVGhyZWFkR3JvdXAuCisgICAgICoKKyAgICAgKiBAc2VlICNkZXN0cm95CisgICAgICogQHNlZSAjc2V0RGFlbW9uCisgICAgICogQHNlZSAjaXNEYWVtb24KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZGVzdHJveUlmRW1wdHlEYWVtb24oKSB7CisgICAgICAgIC8vIEhhcyB0byBiZSBub24tZGVzdHJveWVkIGRhZW1vbiB0byBtYWtlIHNlbnNlCisgICAgICAgIHN5bmNocm9uaXplZCAodGhyZWFkUmVmcykgeworICAgICAgICAgICAgaWYgKGlzRGFlbW9uICYmICFpc0Rlc3Ryb3llZCAmJiAhdGhyZWFkcy5pdGVyYXRvcigpLmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoZ3JvdXBzKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChncm91cHMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkZXN0cm95KCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJdGVyYXRlcyBvdmVyIGFsbCBhY3RpdmUgdGhyZWFkcyBpbiB0aGlzIGdyb3VwIChhbmQgaXRzIHN1Yi1ncm91cHMpIGFuZAorICAgICAqIHN0b3JlcyB0aGUgdGhyZWFkcyBpbiB0aGUgZ2l2ZW4gYXJyYXkuIFJldHVybnMgd2hlbiB0aGUgYXJyYXkgaXMgZnVsbCBvcgorICAgICAqIG5vIG1vcmUgdGhyZWFkcyByZW1haW4sIHdoaWNoZXZlciBoYXBwZW5zIGZpcnN0LgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IHRoaXMgbWV0aG9kIHdpbGwgc2lsZW50bHkgaWdub3JlIGFueSB0aHJlYWRzIHRoYXQgZG9uJ3QgZml0IGluIHRoZQorICAgICAqIHN1cHBsaWVkIGFycmF5LgorICAgICAqCisgICAgICogQHBhcmFtIHRocmVhZHMgdGhlIGFycmF5IGludG8gd2hpY2ggdGhlIHtAY29kZSBUaHJlYWR9cyB3aWxsIGJlIGNvcGllZAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiB7QGNvZGUgVGhyZWFkfXMgdGhhdCB3ZXJlIGNvcGllZAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZW51bWVyYXRlKFRocmVhZFtdIHRocmVhZHMpIHsKKyAgICAgICAgcmV0dXJuIGVudW1lcmF0ZSh0aHJlYWRzLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJdGVyYXRlcyBvdmVyIGFsbCBhY3RpdmUgdGhyZWFkcyBpbiB0aGlzIGdyb3VwIChhbmQsIG9wdGlvbmFsbHksIGl0cworICAgICAqIHN1Yi1ncm91cHMpIGFuZCBzdG9yZXMgdGhlIHRocmVhZHMgaW4gdGhlIGdpdmVuIGFycmF5LiBSZXR1cm5zIHdoZW4gdGhlCisgICAgICogYXJyYXkgaXMgZnVsbCBvciBubyBtb3JlIHRocmVhZHMgcmVtYWluLCB3aGljaGV2ZXIgaGFwcGVucyBmaXJzdC4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB0aGlzIG1ldGhvZCB3aWxsIHNpbGVudGx5IGlnbm9yZSBhbnkgdGhyZWFkcyB0aGF0IGRvbid0IGZpdCBpbiB0aGUKKyAgICAgKiBzdXBwbGllZCBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aHJlYWRzIHRoZSBhcnJheSBpbnRvIHdoaWNoIHRoZSB7QGNvZGUgVGhyZWFkfXMgd2lsbCBiZSBjb3BpZWQKKyAgICAgKiBAcGFyYW0gcmVjdXJzZSBpbmRpY2F0ZXMgd2hldGhlciB7QGNvZGUgVGhyZWFkfXMgaW4gc3ViZ3JvdXBzIHNob3VsZCBiZQorICAgICAqICAgICAgICByZWN1cnNpdmVseSBjb3BpZWQgYXMgd2VsbAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiB7QGNvZGUgVGhyZWFkfXMgdGhhdCB3ZXJlIGNvcGllZAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZW51bWVyYXRlKFRocmVhZFtdIHRocmVhZHMsIGJvb2xlYW4gcmVjdXJzZSkgeworICAgICAgICByZXR1cm4gZW51bWVyYXRlR2VuZXJpYyh0aHJlYWRzLCByZWN1cnNlLCAwLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJdGVyYXRlcyBvdmVyIGFsbCB0aHJlYWQgZ3JvdXBzIGluIHRoaXMgZ3JvdXAgKGFuZCBpdHMgc3ViLWdyb3VwcykgYW5kCisgICAgICogYW5kIHN0b3JlcyB0aGUgZ3JvdXBzIGluIHRoZSBnaXZlbiBhcnJheS4gUmV0dXJucyB3aGVuIHRoZSBhcnJheSBpcyBmdWxsCisgICAgICogb3Igbm8gbW9yZSBncm91cHMgcmVtYWluLCB3aGljaGV2ZXIgaGFwcGVucyBmaXJzdC4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB0aGlzIG1ldGhvZCB3aWxsIHNpbGVudGx5IGlnbm9yZSBhbnkgdGhyZWFkIGdyb3VwcyB0aGF0IGRvbid0IGZpdCBpbiB0aGUKKyAgICAgKiBzdXBwbGllZCBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBncm91cHMgdGhlIGFycmF5IGludG8gd2hpY2ggdGhlIHtAY29kZSBUaHJlYWRHcm91cH1zIHdpbGwgYmUgY29waWVkCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHtAY29kZSBUaHJlYWRHcm91cH1zIHRoYXQgd2VyZSBjb3BpZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGVudW1lcmF0ZShUaHJlYWRHcm91cFtdIGdyb3VwcykgeworICAgICAgICByZXR1cm4gZW51bWVyYXRlKGdyb3VwcywgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXRlcmF0ZXMgb3ZlciBhbGwgdGhyZWFkIGdyb3VwcyBpbiB0aGlzIGdyb3VwIChhbmQsIG9wdGlvbmFsbHksIGl0cworICAgICAqIHN1Yi1ncm91cHMpIGFuZCBzdG9yZXMgdGhlIGdyb3VwcyBpbiB0aGUgZ2l2ZW4gYXJyYXkuIFJldHVybnMgd2hlbgorICAgICAqIHRoZSBhcnJheSBpcyBmdWxsIG9yIG5vIG1vcmUgZ3JvdXBzIHJlbWFpbiwgd2hpY2hldmVyIGhhcHBlbnMgZmlyc3QuCisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoYXQgdGhpcyBtZXRob2Qgd2lsbCBzaWxlbnRseSBpZ25vcmUgYW55IHRocmVhZCBncm91cHMgdGhhdCBkb24ndCBmaXQgaW4gdGhlCisgICAgICogc3VwcGxpZWQgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZ3JvdXBzIHRoZSBhcnJheSBpbnRvIHdoaWNoIHRoZSB7QGNvZGUgVGhyZWFkR3JvdXB9cyB3aWxsIGJlIGNvcGllZAorICAgICAqIEBwYXJhbSByZWN1cnNlIGluZGljYXRlcyB3aGV0aGVyIHtAY29kZSBUaHJlYWRHcm91cH1zIGluIHN1Ymdyb3VwcyBzaG91bGQgYmUKKyAgICAgKiAgICAgICAgcmVjdXJzaXZlbHkgY29waWVkIGFzIHdlbGwgb3Igbm90CisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHtAY29kZSBUaHJlYWRHcm91cH1zIHRoYXQgd2VyZSBjb3BpZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGVudW1lcmF0ZShUaHJlYWRHcm91cFtdIGdyb3VwcywgYm9vbGVhbiByZWN1cnNlKSB7CisgICAgICAgIHJldHVybiBlbnVtZXJhdGVHZW5lcmljKGdyb3VwcywgcmVjdXJzZSwgMCwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyBpbnRvIDxwYXJhbT5lbnVtZXJhdGlvbjwvcGFyYW0+IHN0YXJ0aW5nIGF0CisgICAgICogPHBhcmFtPmVudW1lcmF0aW9uSW5kZXg8L3BhcmFtPiBhbGwgVGhyZWFkcyBvciBUaHJlYWRHcm91cHMgaW4gdGhlCisgICAgICogcmVjZWl2ZXIuIElmIDxwYXJhbT5yZWN1cnNlPC9wYXJhbT4gaXMgdHJ1ZSwgcmVjdXJzaXZlbHkgZW51bWVyYXRlIHRoZQorICAgICAqIGVsZW1lbnRzIGluIHN1Ymdyb3Vwcy4KKyAgICAgKgorICAgICAqIElmIHRoZSBhcnJheSBwYXNzZWQgYXMgcGFyYW1ldGVyIGlzIHRvbyBzbWFsbCBubyBleGNlcHRpb24gaXMgdGhyb3duIC0KKyAgICAgKiB0aGUgZXh0cmEgZWxlbWVudHMgYXJlIHNpbXBseSBub3QgY29waWVkLgorICAgICAqCisgICAgICogQHBhcmFtIGVudW1lcmF0aW9uIGFycmF5IGludG8gd2hpY2ggdGhlIGVsZW1lbnRzIHdpbGwgYmUgY29waWVkCisgICAgICogQHBhcmFtIHJlY3Vyc2UgSW5kaWNhdGVzIHdoZXRoZXIgc3ViZ3JvdXBzIHNob3VsZCBiZSBlbnVtZXJhdGVkIG9yIG5vdAorICAgICAqIEBwYXJhbSBlbnVtZXJhdGlvbkluZGV4IEluZGljYXRlcyBpbiB3aGljaCBwb3NpdGlvbiBvZiB0aGUgZW51bWVyYXRpb24KKyAgICAgKiAgICAgICAgYXJyYXkgd2UgYXJlCisgICAgICogQHBhcmFtIGVudW1lcmF0aW5nVGhyZWFkcyBJbmRpY2F0ZXMgd2hldGhlciB3ZSBhcmUgZW51bWVyYXRpbmcgVGhyZWFkcyBvcgorICAgICAqICAgICAgICBUaHJlYWRHcm91cHMKKyAgICAgKiBAcmV0dXJuIEhvdyBtYW55IGVsZW1lbnRzIHdlcmUgZW51bWVyYXRlZC9jb3BpZWQgb3ZlcgorICAgICAqLworICAgIHByaXZhdGUgaW50IGVudW1lcmF0ZUdlbmVyaWMoT2JqZWN0W10gZW51bWVyYXRpb24sIGJvb2xlYW4gcmVjdXJzZSwgaW50IGVudW1lcmF0aW9uSW5kZXgsCisgICAgICAgICAgICBib29sZWFuIGVudW1lcmF0aW5nVGhyZWFkcykgeworICAgICAgICBpZiAoZW51bWVyYXRpbmdUaHJlYWRzKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRocmVhZFJlZnMpIHsKKyAgICAgICAgICAgICAgICAvLyB3YWxrIHRoZSByZWZlcmVuY2VzIGRpcmVjdGx5IHNvIHdlIGNhbiBpdGVyYXRlIGluIHJldmVyc2Ugb3JkZXIKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gdGhyZWFkUmVmcy5zaXplKCkgLSAxOyBpID49IDA7IC0taSkgeworICAgICAgICAgICAgICAgICAgICBUaHJlYWQgdGhyZWFkID0gdGhyZWFkUmVmcy5nZXQoaSkuZ2V0KCk7CisgICAgICAgICAgICAgICAgICAgIGlmICh0aHJlYWQgIT0gbnVsbCAmJiB0aHJlYWQuaXNBbGl2ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW51bWVyYXRpb25JbmRleCA+PSBlbnVtZXJhdGlvbi5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW51bWVyYXRpb25JbmRleDsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGVudW1lcmF0aW9uW2VudW1lcmF0aW9uSW5kZXgrK10gPSB0aHJlYWQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGdyb3VwcykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBncm91cHMuc2l6ZSgpIC0gMTsgaSA+PSAwOyAtLWkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGVudW1lcmF0aW9uSW5kZXggPj0gZW51bWVyYXRpb24ubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW51bWVyYXRpb25JbmRleDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBlbnVtZXJhdGlvbltlbnVtZXJhdGlvbkluZGV4KytdID0gZ3JvdXBzLmdldChpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAocmVjdXJzZSkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChncm91cHMpIHsKKyAgICAgICAgICAgICAgICBmb3IgKFRocmVhZEdyb3VwIGdyb3VwIDogZ3JvdXBzKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChlbnVtZXJhdGlvbkluZGV4ID49IGVudW1lcmF0aW9uLmxlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVudW1lcmF0aW9uSW5kZXg7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZW51bWVyYXRpb25JbmRleCA9IGdyb3VwLmVudW1lcmF0ZUdlbmVyaWMoZW51bWVyYXRpb24sIHJlY3Vyc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW51bWVyYXRpb25JbmRleCwgZW51bWVyYXRpbmdUaHJlYWRzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVudW1lcmF0aW9uSW5kZXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbWF4aW11bSBhbGxvd2VkIHByaW9yaXR5IGZvciBhIHtAY29kZSBUaHJlYWR9IGluIHRoaXMgdGhyZWFkIGdyb3VwLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBwcmlvcml0eQorICAgICAqCisgICAgICogQHNlZSAjc2V0TWF4UHJpb3JpdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdldE1heFByaW9yaXR5KCkgeworICAgICAgICByZXR1cm4gbWF4UHJpb3JpdHk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGlzIHRocmVhZCBncm91cC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGdyb3VwJ3MgbmFtZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHRocmVhZCBncm91cCdzIHBhcmVudCB7QGNvZGUgVGhyZWFkR3JvdXB9LiBJdCBjYW4gYmUgbnVsbCBpZiB0aGlzCisgICAgICogaXMgdGhlIHRoZSByb290IFRocmVhZEdyb3VwLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcGFyZW50CisgICAgICovCisgICAgcHVibGljIGZpbmFsIFRocmVhZEdyb3VwIGdldFBhcmVudCgpIHsKKyAgICAgICAgcmV0dXJuIHBhcmVudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnRlcnJ1cHRzIGV2ZXJ5IHtAY29kZSBUaHJlYWR9IGluIHRoaXMgZ3JvdXAgYW5kIHJlY3Vyc2l2ZWx5IGluIGFsbCBpdHMKKyAgICAgKiBzdWJncm91cHMuCisgICAgICoKKyAgICAgKiBAc2VlIFRocmVhZCNpbnRlcnJ1cHQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBpbnRlcnJ1cHQoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhyZWFkUmVmcykgeworICAgICAgICAgICAgZm9yIChUaHJlYWQgdGhyZWFkIDogdGhyZWFkcykgeworICAgICAgICAgICAgICAgIHRocmVhZC5pbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzeW5jaHJvbml6ZWQgKGdyb3VwcykgeworICAgICAgICAgICAgZm9yIChUaHJlYWRHcm91cCBncm91cCA6IGdyb3VwcykgeworICAgICAgICAgICAgICAgIGdyb3VwLmludGVycnVwdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhpcyB0aHJlYWQgZ3JvdXAgaXMgYSBkYWVtb24ge0Bjb2RlIFRocmVhZEdyb3VwfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIHRocmVhZCBncm91cCBpcyBhIGRhZW1vbiB7QGNvZGUgVGhyZWFkR3JvdXB9CisgICAgICoKKyAgICAgKiBAc2VlICNzZXREYWVtb24KKyAgICAgKiBAc2VlICNkZXN0cm95CisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNEYWVtb24oKSB7CisgICAgICAgIHJldHVybiBpc0RhZW1vbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciB0aGlzIHRocmVhZCBncm91cCBoYXMgYWxyZWFkeSBiZWVuIGRlc3Ryb3llZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIHRocmVhZCBncm91cCBoYXMgYWxyZWFkeSBiZWVuIGRlc3Ryb3llZAorICAgICAqIEBzZWUgI2Rlc3Ryb3kKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gaXNEZXN0cm95ZWQoKSB7CisgICAgICAgIHJldHVybiBpc0Rlc3Ryb3llZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPdXRwdXRzIHRvIHtAY29kZSBTeXN0ZW0ub3V0fSBhIHRleHQgcmVwcmVzZW50YXRpb24gb2YgdGhlCisgICAgICogaGllcmFyY2h5IG9mIHtAY29kZSBUaHJlYWR9cyBhbmQge0Bjb2RlIFRocmVhZEdyb3VwfXMgaW4gdGhpcyB0aHJlYWQgZ3JvdXAgKGFuZCByZWN1cnNpdmVseSkuCisgICAgICogUHJvcGVyIGluZGVudGF0aW9uIGlzIHVzZWQgdG8gc2hvdyB0aGUgbmVzdGluZyBvZiBncm91cHMgaW5zaWRlIGdyb3VwcworICAgICAqIGFuZCB0aHJlYWRzIGluc2lkZSBncm91cHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgbGlzdCgpIHsKKyAgICAgICAgLy8gV2Ugc3RhcnQgaW4gYSBmcmVzaCBsaW5lCisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOworICAgICAgICBsaXN0KDApOworICAgIH0KKworICAgIC8qCisgICAgICogT3V0cHV0cyB0byB7QGNvZGUgU3lzdGVtLm91dH1hIHRleHQgcmVwcmVzZW50YXRpb24gb2YgdGhlCisgICAgICogaGllcmFyY2h5IG9mIFRocmVhZHMgYW5kIFRocmVhZEdyb3VwcyBpbiB0aGlzIHRocmVhZCBncm91cCAoYW5kIHJlY3Vyc2l2ZWx5KS4KKyAgICAgKiBUaGUgaW5kZW50YXRpb24gd2lsbCBiZSBmb3VyIHNwYWNlcyBwZXIgbGV2ZWwgb2YgbmVzdGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsZXZlbHMgSG93IG1hbnkgbGV2ZWxzIG9mIG5lc3RpbmcsIHNvIHRoYXQgcHJvcGVyIGluZGVudGF0aW9uIGNhbgorICAgICAqIGJlIG91dHB1dC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgbGlzdChpbnQgbGV2ZWxzKSB7CisgICAgICAgIGluZGVudChsZXZlbHMpOworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4odGhpcy50b1N0cmluZygpKTsKKworICAgICAgICArK2xldmVsczsKKyAgICAgICAgc3luY2hyb25pemVkICh0aHJlYWRSZWZzKSB7CisgICAgICAgICAgICBmb3IgKFRocmVhZCB0aHJlYWQgOiB0aHJlYWRzKSB7CisgICAgICAgICAgICAgICAgaW5kZW50KGxldmVscyk7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKHRocmVhZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgc3luY2hyb25pemVkIChncm91cHMpIHsKKyAgICAgICAgICAgIGZvciAoVGhyZWFkR3JvdXAgZ3JvdXAgOiBncm91cHMpIHsKKyAgICAgICAgICAgICAgICBncm91cC5saXN0KGxldmVscyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgaW5kZW50KGludCBsZXZlbHMpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZXZlbHM7IGkrKykgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiICAgICIpOyAvLyA0IHNwYWNlcyBmb3IgZWFjaCBsZXZlbAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhpcyB0aHJlYWQgZ3JvdXAgaXMgYSBkaXJlY3Qgb3IgaW5kaXJlY3QgcGFyZW50IGdyb3VwIG9mIGEKKyAgICAgKiBnaXZlbiB7QGNvZGUgVGhyZWFkR3JvdXB9LgorICAgICAqCisgICAgICogQHBhcmFtIGcgdGhlIHBvdGVudGlhbCBjaGlsZCB7QGNvZGUgVGhyZWFkR3JvdXB9CisgICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgdGhyZWFkIGdyb3VwIGlzIHBhcmVudCBvZiB7QGNvZGUgZ30KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBwYXJlbnRPZihUaHJlYWRHcm91cCBnKSB7CisgICAgICAgIHdoaWxlIChnICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmICh0aGlzID09IGcpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGcgPSBnLnBhcmVudDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhbiBpbW1lZGlhdGUgc3ViZ3JvdXAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZyBUaHJlYWRHcm91cCB0byByZW1vdmUKKyAgICAgKgorICAgICAqIEBzZWUgI2FkZChUaHJlYWQpCisgICAgICogQHNlZSAjYWRkKFRocmVhZEdyb3VwKQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZW1vdmUoVGhyZWFkR3JvdXAgZykgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGdyb3VwcykgeworICAgICAgICAgICAgZm9yIChJdGVyYXRvcjxUaHJlYWRHcm91cD4gaSA9IGdyb3Vwcy5pdGVyYXRvcigpOyBpLmhhc05leHQoKTsgKSB7CisgICAgICAgICAgICAgICAgVGhyZWFkR3JvdXAgdGhyZWFkR3JvdXAgPSBpLm5leHQoKTsKKyAgICAgICAgICAgICAgICBpZiAodGhyZWFkR3JvdXAuZXF1YWxzKGcpKSB7CisgICAgICAgICAgICAgICAgICAgIGkucmVtb3ZlKCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBkZXN0cm95SWZFbXB0eURhZW1vbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc3VtZXMgZXZlcnkgdGhyZWFkIGluIHRoaXMgZ3JvdXAgYW5kIHJlY3Vyc2l2ZWx5IGluIGFsbCBpdHMKKyAgICAgKiBzdWJncm91cHMuCisgICAgICoKKyAgICAgKiBAc2VlIFRocmVhZCNyZXN1bWUKKyAgICAgKiBAc2VlICNzdXNwZW5kCisgICAgICoKKyAgICAgKiBAZGVwcmVjYXRlZCBSZXF1aXJlcyBkZXByZWNhdGVkIG1ldGhvZCBUaHJlYWQucmVzdW1lKCkuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBmaW5hbCB2b2lkIHJlc3VtZSgpIHsKKyAgICAgICAgc3luY2hyb25pemVkICh0aHJlYWRSZWZzKSB7CisgICAgICAgICAgICBmb3IgKFRocmVhZCB0aHJlYWQgOiB0aHJlYWRzKSB7CisgICAgICAgICAgICAgICAgdGhyZWFkLnJlc3VtZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHN5bmNocm9uaXplZCAoZ3JvdXBzKSB7CisgICAgICAgICAgICBmb3IgKFRocmVhZEdyb3VwIGdyb3VwIDogZ3JvdXBzKSB7CisgICAgICAgICAgICAgICAgZ3JvdXAucmVzdW1lKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHdoZXRoZXIgdGhpcyBpcyBhIGRhZW1vbiB7QGNvZGUgVGhyZWFkR3JvdXB9IG9yIG5vdC4gRGFlbW9uCisgICAgICogdGhyZWFkIGdyb3VwcyBhcmUgYXV0b21hdGljYWxseSBkZXN0cm95ZWQgd2hlbiB0aGV5IGJlY29tZSBlbXB0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpc0RhZW1vbiB0aGUgbmV3IHZhbHVlCisgICAgICogQHNlZSAjaXNEYWVtb24KKyAgICAgKiBAc2VlICNkZXN0cm95CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgc2V0RGFlbW9uKGJvb2xlYW4gaXNEYWVtb24pIHsKKyAgICAgICAgdGhpcy5pc0RhZW1vbiA9IGlzRGFlbW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbmZpZ3VyZXMgdGhlIG1heGltdW0gYWxsb3dlZCBwcmlvcml0eSBmb3IgYSB7QGNvZGUgVGhyZWFkfSBpbiB0aGlzIGdyb3VwIGFuZAorICAgICAqIHJlY3Vyc2l2ZWx5IGluIGFsbCBpdHMgc3ViZ3JvdXBzLgorICAgICAqCisgICAgICogPHA+QSBjYWxsZXIgY2FuIG5ldmVyIGluY3JlYXNlIHRoZSBtYXhpbXVtIHByaW9yaXR5IG9mIGEgdGhyZWFkIGdyb3VwLgorICAgICAqIFN1Y2ggYW4gYXR0ZW1wdCB3aWxsIG5vdCByZXN1bHQgaW4gYW4gZXhjZXB0aW9uLCBpdCB3aWxsCisgICAgICogc2ltcGx5IGxlYXZlIHRoZSB0aHJlYWQgZ3JvdXAgd2l0aCBpdHMgY3VycmVudCBtYXhpbXVtIHByaW9yaXR5LgorICAgICAqCisgICAgICogQHBhcmFtIG5ld01heCB0aGUgbmV3IG1heGltdW0gcHJpb3JpdHkgdG8gYmUgc2V0CisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgbmV3IHByaW9yaXR5IGlzIGdyZWF0ZXIgdGhhbgorICAgICAqICAgICAgICAgVGhyZWFkLk1BWF9QUklPUklUWSBvciBsZXNzIHRoYW4gVGhyZWFkLk1JTl9QUklPUklUWQorICAgICAqCisgICAgICogQHNlZSAjZ2V0TWF4UHJpb3JpdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRNYXhQcmlvcml0eShpbnQgbmV3TWF4KSB7CisgICAgICAgIGlmIChuZXdNYXggPD0gdGhpcy5tYXhQcmlvcml0eSkgeworICAgICAgICAgICAgaWYgKG5ld01heCA8IFRocmVhZC5NSU5fUFJJT1JJVFkpIHsKKyAgICAgICAgICAgICAgICBuZXdNYXggPSBUaHJlYWQuTUlOX1BSSU9SSVRZOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgcGFyZW50UHJpb3JpdHkgPSBwYXJlbnQgPT0gbnVsbCA/IG5ld01heCA6IHBhcmVudC5nZXRNYXhQcmlvcml0eSgpOworICAgICAgICAgICAgdGhpcy5tYXhQcmlvcml0eSA9IHBhcmVudFByaW9yaXR5IDw9IG5ld01heCA/IHBhcmVudFByaW9yaXR5IDogbmV3TWF4OworICAgICAgICAgICAgc3luY2hyb25pemVkIChncm91cHMpIHsKKyAgICAgICAgICAgICAgICBmb3IgKFRocmVhZEdyb3VwIGdyb3VwIDogZ3JvdXBzKSB7CisgICAgICAgICAgICAgICAgICAgIGdyb3VwLnNldE1heFByaW9yaXR5KG5ld01heCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU3RvcHMgZXZlcnkgdGhyZWFkIGluIHRoaXMgZ3JvdXAgYW5kIHJlY3Vyc2l2ZWx5IGluIGFsbCBpdHMgc3ViZ3JvdXBzLgorICAgICAqCisgICAgICogQHNlZSBUaHJlYWQjc3RvcCgpCisgICAgICogQHNlZSBUaHJlYWQjc3RvcChUaHJvd2FibGUpCisgICAgICogQHNlZSBUaHJlYWREZWF0aAorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgUmVxdWlyZXMgZGVwcmVjYXRlZCBtZXRob2QgVGhyZWFkLnN0b3AoKS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGZpbmFsIHZvaWQgc3RvcCgpIHsKKyAgICAgICAgaWYgKHN0b3BIZWxwZXIoKSkgeworICAgICAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5zdG9wKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHByaXZhdGUgYm9vbGVhbiBzdG9wSGVscGVyKCkgeworICAgICAgICBib29sZWFuIHN0b3BDdXJyZW50ID0gZmFsc2U7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhyZWFkUmVmcykgeworICAgICAgICAgICAgVGhyZWFkIGN1cnJlbnQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICAgICAgZm9yIChUaHJlYWQgdGhyZWFkIDogdGhyZWFkcykgeworICAgICAgICAgICAgICAgIGlmICh0aHJlYWQgPT0gY3VycmVudCkgeworICAgICAgICAgICAgICAgICAgICBzdG9wQ3VycmVudCA9IHRydWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyZWFkLnN0b3AoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgc3luY2hyb25pemVkIChncm91cHMpIHsKKyAgICAgICAgICAgIGZvciAoVGhyZWFkR3JvdXAgZ3JvdXAgOiBncm91cHMpIHsKKyAgICAgICAgICAgICAgICBzdG9wQ3VycmVudCB8PSBncm91cC5zdG9wSGVscGVyKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN0b3BDdXJyZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFN1c3BlbmRzIGV2ZXJ5IHRocmVhZCBpbiB0aGlzIGdyb3VwIGFuZCByZWN1cnNpdmVseSBpbiBhbGwgaXRzCisgICAgICogc3ViZ3JvdXBzLgorICAgICAqCisgICAgICogQHNlZSBUaHJlYWQjc3VzcGVuZAorICAgICAqIEBzZWUgI3Jlc3VtZQorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgUmVxdWlyZXMgZGVwcmVjYXRlZCBtZXRob2QgVGhyZWFkLnN1c3BlbmQoKS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGZpbmFsIHZvaWQgc3VzcGVuZCgpIHsKKyAgICAgICAgaWYgKHN1c3BlbmRIZWxwZXIoKSkgeworICAgICAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5zdXNwZW5kKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHByaXZhdGUgYm9vbGVhbiBzdXNwZW5kSGVscGVyKCkgeworICAgICAgICBib29sZWFuIHN1c3BlbmRDdXJyZW50ID0gZmFsc2U7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhyZWFkUmVmcykgeworICAgICAgICAgICAgVGhyZWFkIGN1cnJlbnQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICAgICAgZm9yIChUaHJlYWQgdGhyZWFkIDogdGhyZWFkcykgeworICAgICAgICAgICAgICAgIGlmICh0aHJlYWQgPT0gY3VycmVudCkgeworICAgICAgICAgICAgICAgICAgICBzdXNwZW5kQ3VycmVudCA9IHRydWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyZWFkLnN1c3BlbmQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgc3luY2hyb25pemVkIChncm91cHMpIHsKKyAgICAgICAgICAgIGZvciAoVGhyZWFkR3JvdXAgZ3JvdXAgOiBncm91cHMpIHsKKyAgICAgICAgICAgICAgICBzdXNwZW5kQ3VycmVudCB8PSBncm91cC5zdXNwZW5kSGVscGVyKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN1c3BlbmRDdXJyZW50OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBnZXRDbGFzcygpLmdldE5hbWUoKSArICJbbmFtZT0iICsgZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgKyAiLG1heFByaW9yaXR5PSIgKyBnZXRNYXhQcmlvcml0eSgpICsgIl0iOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhhbmRsZXMgdW5jYXVnaHQgZXhjZXB0aW9ucy4gQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBpbiBhbnkge0Bjb2RlIFRocmVhZH0KKyAgICAgKiBpcyBmb3J3YXJkZWQgdG8gdGhlIHRocmVhZCdzIHtAY29kZSBUaHJlYWRHcm91cH0gYnkgaW52b2tpbmcgdGhpcworICAgICAqIG1ldGhvZC4KKyAgICAgKgorICAgICAqIDxwPk5ldyBjb2RlIHNob3VsZCB1c2Uge0BsaW5rIFRocmVhZCNzZXRVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXJ9IGluc3RlYWQgb2YgdGhyZWFkIGdyb3Vwcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0IHRoZSBUaHJlYWQgdGhhdCB0ZXJtaW5hdGVkIHdpdGggYW4gdW5jYXVnaHQgZXhjZXB0aW9uCisgICAgICogQHBhcmFtIGUgdGhlIHVuY2F1Z2h0IGV4Y2VwdGlvbiBpdHNlbGYKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1bmNhdWdodEV4Y2VwdGlvbihUaHJlYWQgdCwgVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsKSB7CisgICAgICAgICAgICBwYXJlbnQudW5jYXVnaHRFeGNlcHRpb24odCwgZSk7CisgICAgICAgIH0gZWxzZSBpZiAoVGhyZWFkLmdldERlZmF1bHRVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXIoKSAhPSBudWxsKSB7CisgICAgICAgICAgICAvLyBUT0RPIFRoZSBzcGVjIGlzIHVuY2xlYXIgcmVnYXJkaW5nIHRoaXMuIFdoYXQgZG8gd2UgZG8/CisgICAgICAgICAgICBUaHJlYWQuZ2V0RGVmYXVsdFVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlcigpLnVuY2F1Z2h0RXhjZXB0aW9uKHQsIGUpOworICAgICAgICB9IGVsc2UgaWYgKCEoZSBpbnN0YW5jZW9mIFRocmVhZERlYXRoKSkgeworICAgICAgICAgICAgLy8gTm8gcGFyZW50IGdyb3VwLCBoYXMgdG8gYmUgJ3N5c3RlbScgVGhyZWFkIEdyb3VwCisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZShTeXN0ZW0uZXJyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGxlZCBieSB0aGUgVGhyZWFkIGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIGZpbmFsIHZvaWQgYWRkVGhyZWFkKFRocmVhZCB0aHJlYWQpIHRocm93cyBJbGxlZ2FsVGhyZWFkU3RhdGVFeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKHRocmVhZFJlZnMpIHsKKyAgICAgICAgICAgIGlmIChpc0Rlc3Ryb3llZCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsVGhyZWFkU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocmVhZFJlZnMuYWRkKG5ldyBXZWFrUmVmZXJlbmNlPFRocmVhZD4odGhyZWFkKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxsZWQgYnkgdGhlIFZNIHdoZW4gYSBUaHJlYWQgZGllcy4KKyAgICAgKi8KKyAgICBmaW5hbCB2b2lkIHJlbW92ZVRocmVhZChUaHJlYWQgdGhyZWFkKSB0aHJvd3MgSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkICh0aHJlYWRSZWZzKSB7CisgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yPFRocmVhZD4gaSA9IHRocmVhZHMuaXRlcmF0b3IoKTsgaS5oYXNOZXh0KCk7ICkgeworICAgICAgICAgICAgICAgIGlmIChpLm5leHQoKS5lcXVhbHModGhyZWFkKSkgeworICAgICAgICAgICAgICAgICAgICBpLnJlbW92ZSgpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZGVzdHJveUlmRW1wdHlEYWVtb24oKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1RocmVhZExvY2FsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1RocmVhZExvY2FsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjJkYTUxOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvVGhyZWFkTG9jYWwuamF2YQpAQCAtMCwwICsxLDUzNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgamF2YS5sYW5nLnJlZi5SZWZlcmVuY2U7CitpbXBvcnQgamF2YS5sYW5nLnJlZi5XZWFrUmVmZXJlbmNlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNJbnRlZ2VyOworCisvKioKKyAqIEltcGxlbWVudHMgYSB0aHJlYWQtbG9jYWwgc3RvcmFnZSwgdGhhdCBpcywgYSB2YXJpYWJsZSBmb3Igd2hpY2ggZWFjaCB0aHJlYWQKKyAqIGhhcyBpdHMgb3duIHZhbHVlLiBBbGwgdGhyZWFkcyBzaGFyZSB0aGUgc2FtZSB7QGNvZGUgVGhyZWFkTG9jYWx9IG9iamVjdCwKKyAqIGJ1dCBlYWNoIHNlZXMgYSBkaWZmZXJlbnQgdmFsdWUgd2hlbiBhY2Nlc3NpbmcgaXQsIGFuZCBjaGFuZ2VzIG1hZGUgYnkgb25lCisgKiB0aHJlYWQgZG8gbm90IGFmZmVjdCB0aGUgb3RoZXIgdGhyZWFkcy4gVGhlIGltcGxlbWVudGF0aW9uIHN1cHBvcnRzCisgKiB7QGNvZGUgbnVsbH0gdmFsdWVzLgorICoKKyAqIEBzZWUgamF2YS5sYW5nLlRocmVhZAorICogQGF1dGhvciBCb2IgTGVlCisgKi8KK3B1YmxpYyBjbGFzcyBUaHJlYWRMb2NhbDxUPiB7CisKKyAgICAvKiBUaGFua3MgdG8gSm9zaCBCbG9jaCBhbmQgRG91ZyBMZWEgZm9yIGNvZGUgcmV2aWV3cyBhbmQgaW1wbCBhZHZpY2UuICovCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHRocmVhZC1sb2NhbCB2YXJpYWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGhyZWFkTG9jYWwoKSB7fQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhpcyB2YXJpYWJsZSBmb3IgdGhlIGN1cnJlbnQgdGhyZWFkLiBJZiBhbiBlbnRyeQorICAgICAqIGRvZXNuJ3QgeWV0IGV4aXN0IGZvciB0aGlzIHZhcmlhYmxlIG9uIHRoaXMgdGhyZWFkLCB0aGlzIG1ldGhvZCB3aWxsCisgICAgICogY3JlYXRlIGFuIGVudHJ5LCBwb3B1bGF0aW5nIHRoZSB2YWx1ZSB3aXRoIHRoZSByZXN1bHQgb2YKKyAgICAgKiB7QGxpbmsgI2luaXRpYWxWYWx1ZSgpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHZhcmlhYmxlIGZvciB0aGUgY2FsbGluZyB0aHJlYWQuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIFQgZ2V0KCkgeworICAgICAgICAvLyBPcHRpbWl6ZWQgZm9yIHRoZSBmYXN0IHBhdGguCisgICAgICAgIFRocmVhZCBjdXJyZW50VGhyZWFkID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKyAgICAgICAgVmFsdWVzIHZhbHVlcyA9IHZhbHVlcyhjdXJyZW50VGhyZWFkKTsKKyAgICAgICAgaWYgKHZhbHVlcyAhPSBudWxsKSB7CisgICAgICAgICAgICBPYmplY3RbXSB0YWJsZSA9IHZhbHVlcy50YWJsZTsKKyAgICAgICAgICAgIGludCBpbmRleCA9IGhhc2ggJiB2YWx1ZXMubWFzazsKKyAgICAgICAgICAgIGlmICh0aGlzLnJlZmVyZW5jZSA9PSB0YWJsZVtpbmRleF0pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gKFQpIHRhYmxlW2luZGV4ICsgMV07CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB2YWx1ZXMgPSBpbml0aWFsaXplVmFsdWVzKGN1cnJlbnRUaHJlYWQpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIChUKSB2YWx1ZXMuZ2V0QWZ0ZXJNaXNzKHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb3ZpZGVzIHRoZSBpbml0aWFsIHZhbHVlIG9mIHRoaXMgdmFyaWFibGUgZm9yIHRoZSBjdXJyZW50IHRocmVhZC4KKyAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHtAY29kZSBudWxsfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIHZhcmlhYmxlLgorICAgICAqLworICAgIHByb3RlY3RlZCBUIGluaXRpYWxWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhpcyB2YXJpYWJsZSBmb3IgdGhlIGN1cnJlbnQgdGhyZWFkLiBJZiBzZXQgdG8KKyAgICAgKiB7QGNvZGUgbnVsbH0sIHRoZSB2YWx1ZSB3aWxsIGJlIHNldCB0byBudWxsIGFuZCB0aGUgdW5kZXJseWluZyBlbnRyeSB3aWxsCisgICAgICogc3RpbGwgYmUgcHJlc2VudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgbmV3IHZhbHVlIG9mIHRoZSB2YXJpYWJsZSBmb3IgdGhlIGNhbGxlciB0aHJlYWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0KFQgdmFsdWUpIHsKKyAgICAgICAgVGhyZWFkIGN1cnJlbnRUaHJlYWQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICBWYWx1ZXMgdmFsdWVzID0gdmFsdWVzKGN1cnJlbnRUaHJlYWQpOworICAgICAgICBpZiAodmFsdWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHZhbHVlcyA9IGluaXRpYWxpemVWYWx1ZXMoY3VycmVudFRocmVhZCk7CisgICAgICAgIH0KKyAgICAgICAgdmFsdWVzLnB1dCh0aGlzLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgZW50cnkgZm9yIHRoaXMgdmFyaWFibGUgaW4gdGhlIGN1cnJlbnQgdGhyZWFkLiBJZiB0aGlzIGNhbGwKKyAgICAgKiBpcyBmb2xsb3dlZCBieSBhIHtAbGluayAjZ2V0KCl9IGJlZm9yZSBhIHtAbGluayAjc2V0fSwKKyAgICAgKiB7QGNvZGUgI2dldCgpfSB3aWxsIGNhbGwge0BsaW5rICNpbml0aWFsVmFsdWUoKX0gYW5kIGNyZWF0ZSBhIG5ldworICAgICAqIGVudHJ5IHdpdGggdGhlIHJlc3VsdGluZyB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgIFRocmVhZCBjdXJyZW50VGhyZWFkID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKyAgICAgICAgVmFsdWVzIHZhbHVlcyA9IHZhbHVlcyhjdXJyZW50VGhyZWFkKTsKKyAgICAgICAgaWYgKHZhbHVlcyAhPSBudWxsKSB7CisgICAgICAgICAgICB2YWx1ZXMucmVtb3ZlKHRoaXMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBWYWx1ZXMgaW5zdGFuY2UgZm9yIHRoaXMgdGhyZWFkIGFuZCB2YXJpYWJsZSB0eXBlLgorICAgICAqLworICAgIFZhbHVlcyBpbml0aWFsaXplVmFsdWVzKFRocmVhZCBjdXJyZW50KSB7CisgICAgICAgIHJldHVybiBjdXJyZW50LmxvY2FsVmFsdWVzID0gbmV3IFZhbHVlcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgVmFsdWVzIGluc3RhbmNlIGZvciB0aGlzIHRocmVhZCBhbmQgdmFyaWFibGUgdHlwZS4KKyAgICAgKi8KKyAgICBWYWx1ZXMgdmFsdWVzKFRocmVhZCBjdXJyZW50KSB7CisgICAgICAgIHJldHVybiBjdXJyZW50LmxvY2FsVmFsdWVzOworICAgIH0KKworICAgIC8qKiBXZWFrIHJlZmVyZW5jZSB0byB0aGlzIHRocmVhZCBsb2NhbCBpbnN0YW5jZS4gKi8KKyAgICBwcml2YXRlIGZpbmFsIFJlZmVyZW5jZTxUaHJlYWRMb2NhbDxUPj4gcmVmZXJlbmNlCisgICAgICAgICAgICA9IG5ldyBXZWFrUmVmZXJlbmNlPFRocmVhZExvY2FsPFQ+Pih0aGlzKTsKKworICAgIC8qKiBIYXNoIGNvdW50ZXIuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgQXRvbWljSW50ZWdlciBoYXNoQ291bnRlciA9IG5ldyBBdG9taWNJbnRlZ2VyKDApOworCisgICAgLyoqCisgICAgICogSW50ZXJuYWwgaGFzaC4gV2UgZGVsaWJlcmF0ZWx5IGRvbid0IGJvdGhlciB3aXRoICNoYXNoQ29kZSgpLgorICAgICAqIEhhc2hlcyBtdXN0IGJlIGV2ZW4uIFRoaXMgZW5zdXJlcyB0aGF0IHRoZSByZXN1bHQgb2YKKyAgICAgKiAoaGFzaCAmICh0YWJsZS5sZW5ndGggLSAxKSkgcG9pbnRzIHRvIGEga2V5IGFuZCBub3QgYSB2YWx1ZS4KKyAgICAgKgorICAgICAqIFdlIGluY3JlbWVudCBieSBEb3VnIExlYSdzIE1hZ2ljIE51bWJlcihUTSkgKCoyIHNpbmNlIGtleXMgYXJlIGluCisgICAgICogZXZlcnkgb3RoZXIgYnVja2V0KSB0byBoZWxwIHByZXZlbnQgY2x1c3RlcmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBoYXNoID0gaGFzaENvdW50ZXIuZ2V0QW5kQWRkKDB4NjFjODg2NDcgKiAyKTsKKworICAgIC8qKgorICAgICAqIFBlci10aHJlYWQgbWFwIG9mIFRocmVhZExvY2FsIGluc3RhbmNlcyB0byB2YWx1ZXMuCisgICAgICovCisgICAgc3RhdGljIGNsYXNzIFZhbHVlcyB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNpemUgbXVzdCBhbHdheXMgYmUgYSBwb3dlciBvZiAyLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOSVRJQUxfU0laRSA9IDE2OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBQbGFjZWhvbGRlciBmb3IgZGVsZXRlZCBlbnRyaWVzLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0IFRPTUJTVE9ORSA9IG5ldyBPYmplY3QoKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogTWFwIGVudHJpZXMuIENvbnRhaW5zIGFsdGVybmF0aW5nIGtleXMgKFRocmVhZExvY2FsKSBhbmQgdmFsdWVzLgorICAgICAgICAgKiBUaGUgbGVuZ3RoIGlzIGFsd2F5cyBhIHBvd2VyIG9mIDIuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIE9iamVjdFtdIHRhYmxlOworCisgICAgICAgIC8qKiBVc2VkIHRvIHR1cm4gaGFzaGVzIGludG8gaW5kaWNlcy4gKi8KKyAgICAgICAgcHJpdmF0ZSBpbnQgbWFzazsKKworICAgICAgICAvKiogTnVtYmVyIG9mIGxpdmUgZW50cmllcy4gKi8KKyAgICAgICAgcHJpdmF0ZSBpbnQgc2l6ZTsKKworICAgICAgICAvKiogTnVtYmVyIG9mIHRvbWJzdG9uZXMuICovCisgICAgICAgIHByaXZhdGUgaW50IHRvbWJzdG9uZXM7CisKKyAgICAgICAgLyoqIE1heGltdW0gbnVtYmVyIG9mIGxpdmUgZW50cmllcyBhbmQgdG9tYnN0b25lcy4gKi8KKyAgICAgICAgcHJpdmF0ZSBpbnQgbWF4aW11bUxvYWQ7CisKKyAgICAgICAgLyoqIFBvaW50cyB0byB0aGUgbmV4dCBjZWxsIHRvIGNsZWFuIHVwLiAqLworICAgICAgICBwcml2YXRlIGludCBjbGVhbjsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldywgZW1wdHkgaW5zdGFuY2UuCisgICAgICAgICAqLworICAgICAgICBWYWx1ZXMoKSB7CisgICAgICAgICAgICBpbml0aWFsaXplVGFibGUoSU5JVElBTF9TSVpFKTsKKyAgICAgICAgICAgIHRoaXMuc2l6ZSA9IDA7CisgICAgICAgICAgICB0aGlzLnRvbWJzdG9uZXMgPSAwOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFVzZWQgZm9yIEluaGVyaXRhYmxlVGhyZWFkTG9jYWxzLgorICAgICAgICAgKi8KKyAgICAgICAgVmFsdWVzKFZhbHVlcyBmcm9tUGFyZW50KSB7CisgICAgICAgICAgICB0aGlzLnRhYmxlID0gZnJvbVBhcmVudC50YWJsZS5jbG9uZSgpOworICAgICAgICAgICAgdGhpcy5tYXNrID0gZnJvbVBhcmVudC5tYXNrOworICAgICAgICAgICAgdGhpcy5zaXplID0gZnJvbVBhcmVudC5zaXplOworICAgICAgICAgICAgdGhpcy50b21ic3RvbmVzID0gZnJvbVBhcmVudC50b21ic3RvbmVzOworICAgICAgICAgICAgdGhpcy5tYXhpbXVtTG9hZCA9IGZyb21QYXJlbnQubWF4aW11bUxvYWQ7CisgICAgICAgICAgICB0aGlzLmNsZWFuID0gZnJvbVBhcmVudC5jbGVhbjsKKyAgICAgICAgICAgIGluaGVyaXRWYWx1ZXMoZnJvbVBhcmVudCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogSW5oZXJpdHMgdmFsdWVzIGZyb20gYSBwYXJlbnQgdGhyZWFkLgorICAgICAgICAgKi8KKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bmNoZWNrZWQifSkKKyAgICAgICAgcHJpdmF0ZSB2b2lkIGluaGVyaXRWYWx1ZXMoVmFsdWVzIGZyb21QYXJlbnQpIHsKKyAgICAgICAgICAgIC8vIFRyYW5zZmVyIHZhbHVlcyBmcm9tIHBhcmVudCB0byBjaGlsZCB0aHJlYWQuCisgICAgICAgICAgICBPYmplY3RbXSB0YWJsZSA9IHRoaXMudGFibGU7CisgICAgICAgICAgICBmb3IgKGludCBpID0gdGFibGUubGVuZ3RoIC0gMjsgaSA+PSAwOyBpIC09IDIpIHsKKyAgICAgICAgICAgICAgICBPYmplY3QgayA9IHRhYmxlW2ldOworCisgICAgICAgICAgICAgICAgaWYgKGsgPT0gbnVsbCB8fCBrID09IFRPTUJTVE9ORSkgeworICAgICAgICAgICAgICAgICAgICAvLyBTa2lwIHRoaXMgZW50cnkuCisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIFRoZSB0YWJsZSBjYW4gb25seSBjb250YWluIG51bGwsIHRvbWJzdG9uZXMgYW5kIHJlZmVyZW5jZXMuCisgICAgICAgICAgICAgICAgUmVmZXJlbmNlPEluaGVyaXRhYmxlVGhyZWFkTG9jYWw8Pz4+IHJlZmVyZW5jZQorICAgICAgICAgICAgICAgICAgICAgICAgPSAoUmVmZXJlbmNlPEluaGVyaXRhYmxlVGhyZWFkTG9jYWw8Pz4+KSBrOworICAgICAgICAgICAgICAgIC8vIFJhdyB0eXBlIGVuYWJsZXMgdXMgdG8gcGFzcyBpbiBhbiBPYmplY3QgYmVsb3cuCisgICAgICAgICAgICAgICAgSW5oZXJpdGFibGVUaHJlYWRMb2NhbCBrZXkgPSByZWZlcmVuY2UuZ2V0KCk7CisgICAgICAgICAgICAgICAgaWYgKGtleSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFJlcGxhY2UgdmFsdWUgd2l0aCBmaWx0ZXJlZCB2YWx1ZS4KKyAgICAgICAgICAgICAgICAgICAgLy8gV2Ugc2hvdWxkIGp1c3QgbGV0IGV4Y2VwdGlvbnMgYnViYmxlIG91dCBhbmQgdGFuaworICAgICAgICAgICAgICAgICAgICAvLyB0aGUgdGhyZWFkIGNyZWF0aW9uCisgICAgICAgICAgICAgICAgICAgIHRhYmxlW2kgKyAxXSA9IGtleS5jaGlsZFZhbHVlKGZyb21QYXJlbnQudGFibGVbaSArIDFdKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAvLyBUaGUga2V5IHdhcyByZWNsYWltZWQuCisgICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldID0gVE9NQlNUT05FOworICAgICAgICAgICAgICAgICAgICB0YWJsZVtpICsgMV0gPSBudWxsOworICAgICAgICAgICAgICAgICAgICBmcm9tUGFyZW50LnRhYmxlW2ldID0gVE9NQlNUT05FOworICAgICAgICAgICAgICAgICAgICBmcm9tUGFyZW50LnRhYmxlW2kgKyAxXSA9IG51bGw7CisKKyAgICAgICAgICAgICAgICAgICAgdG9tYnN0b25lcysrOworICAgICAgICAgICAgICAgICAgICBmcm9tUGFyZW50LnRvbWJzdG9uZXMrKzsKKworICAgICAgICAgICAgICAgICAgICBzaXplLS07CisgICAgICAgICAgICAgICAgICAgIGZyb21QYXJlbnQuc2l6ZS0tOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDcmVhdGVzIGEgbmV3LCBlbXB0eSB0YWJsZSB3aXRoIHRoZSBnaXZlbiBjYXBhY2l0eS4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgdm9pZCBpbml0aWFsaXplVGFibGUoaW50IGNhcGFjaXR5KSB7CisgICAgICAgICAgICB0aGlzLnRhYmxlID0gbmV3IE9iamVjdFtjYXBhY2l0eSAqIDJdOworICAgICAgICAgICAgdGhpcy5tYXNrID0gdGFibGUubGVuZ3RoIC0gMTsKKyAgICAgICAgICAgIHRoaXMuY2xlYW4gPSAwOworICAgICAgICAgICAgdGhpcy5tYXhpbXVtTG9hZCA9IGNhcGFjaXR5ICogMiAvIDM7IC8vIDIvMworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENsZWFucyB1cCBhZnRlciBnYXJiYWdlLWNvbGxlY3RlZCB0aHJlYWQgbG9jYWxzLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSB2b2lkIGNsZWFuVXAoKSB7CisgICAgICAgICAgICBpZiAocmVoYXNoKCkpIHsKKyAgICAgICAgICAgICAgICAvLyBJZiB3ZSByZWhhc2hlZCwgd2UgbmVlZG4ndCBjbGVhbiB1cCAoY2xlYW4gdXAgaGFwcGVucyBhcworICAgICAgICAgICAgICAgIC8vIGEgc2lkZSBlZmZlY3QpLgorICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHNpemUgPT0gMCkgeworICAgICAgICAgICAgICAgIC8vIE5vIGxpdmUgZW50cmllcyA9PSBub3RoaW5nIHRvIGNsZWFuLgorICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gQ2xlYW4gbG9nKHRhYmxlLmxlbmd0aCkgZW50cmllcyBwaWNraW5nIHVwIHdoZXJlIHdlIGxlZnQgb2ZmCisgICAgICAgICAgICAvLyBsYXN0IHRpbWUuCisgICAgICAgICAgICBpbnQgaW5kZXggPSBjbGVhbjsKKyAgICAgICAgICAgIE9iamVjdFtdIHRhYmxlID0gdGhpcy50YWJsZTsKKyAgICAgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSB0YWJsZS5sZW5ndGg7IGNvdW50ZXIgPiAwOyBjb3VudGVyID4+PSAxLAorICAgICAgICAgICAgICAgICAgICBpbmRleCA9IG5leHQoaW5kZXgpKSB7CisgICAgICAgICAgICAgICAgT2JqZWN0IGsgPSB0YWJsZVtpbmRleF07CisKKyAgICAgICAgICAgICAgICBpZiAoayA9PSBUT01CU1RPTkUgfHwgayA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOyAvLyBvbiB0byBuZXh0IGVudHJ5CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gVGhlIHRhYmxlIGNhbiBvbmx5IGNvbnRhaW4gbnVsbCwgdG9tYnN0b25lcyBhbmQgcmVmZXJlbmNlcy4KKyAgICAgICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgICAgICAgICBSZWZlcmVuY2U8VGhyZWFkTG9jYWw8Pz4+IHJlZmVyZW5jZQorICAgICAgICAgICAgICAgICAgICAgICAgPSAoUmVmZXJlbmNlPFRocmVhZExvY2FsPD8+PikgazsKKyAgICAgICAgICAgICAgICBpZiAocmVmZXJlbmNlLmdldCgpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyB0aHJlYWQgbG9jYWwgd2FzIHJlY2xhaW1lZCBieSB0aGUgZ2FyYmFnZSBjb2xsZWN0b3IuCisgICAgICAgICAgICAgICAgICAgIHRhYmxlW2luZGV4XSA9IFRPTUJTVE9ORTsKKyAgICAgICAgICAgICAgICAgICAgdGFibGVbaW5kZXggKyAxXSA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgIHRvbWJzdG9uZXMrKzsKKyAgICAgICAgICAgICAgICAgICAgc2l6ZS0tOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gUG9pbnQgY3Vyc29yIHRvIG5leHQgaW5kZXguCisgICAgICAgICAgICBjbGVhbiA9IGluZGV4OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJlaGFzaGVzIHRoZSB0YWJsZSwgZXhwYW5kaW5nIG9yIGNvbnRyYWN0aW5nIGl0IGFzIG5lY2Vzc2FyeS4KKyAgICAgICAgICogR2V0cyByaWQgb2YgdG9tYnN0b25lcy4gUmV0dXJucyB0cnVlIGlmIGEgcmVoYXNoIG9jY3VycmVkLgorICAgICAgICAgKiBXZSBtdXN0IHJlaGFzaCBldmVyeSB0aW1lIHdlIGZpbGwgYSBudWxsIHNsb3Q7IHdlIGRlcGVuZCBvbiB0aGUKKyAgICAgICAgICogcHJlc2VuY2Ugb2YgbnVsbCBzbG90cyB0byBlbmQgc2VhcmNoZXMgKG90aGVyd2lzZSwgd2UnbGwgaW5maW5pdGVseQorICAgICAgICAgKiBsb29wKS4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiByZWhhc2goKSB7CisgICAgICAgICAgICBpZiAodG9tYnN0b25lcyArIHNpemUgPCBtYXhpbXVtTG9hZCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IGNhcGFjaXR5ID0gdGFibGUubGVuZ3RoID4+IDE7CisKKyAgICAgICAgICAgIC8vIERlZmF1bHQgdG8gdGhlIHNhbWUgY2FwYWNpdHkuIFRoaXMgd2lsbCBjcmVhdGUgYSB0YWJsZSBvZiB0aGUKKyAgICAgICAgICAgIC8vIHNhbWUgc2l6ZSBhbmQgbW92ZSBvdmVyIHRoZSBsaXZlIGVudHJpZXMsIGFuYWxvZ291cyB0byBhCisgICAgICAgICAgICAvLyBnYXJiYWdlIGNvbGxlY3Rpb24uIFRoaXMgc2hvdWxkIG9ubHkgaGFwcGVuIGlmIHlvdSBjaHVybiBhCisgICAgICAgICAgICAvLyBidW5jaCBvZiB0aHJlYWQgbG9jYWwgZ2FyYmFnZSAocmVtb3ZpbmcgYW5kIHJlaW5zZXJ0aW5nCisgICAgICAgICAgICAvLyB0aGUgc2FtZSB0aHJlYWQgbG9jYWxzIG92ZXIgYW5kIG92ZXIgd2lsbCBvdmVyd3JpdGUgdG9tYnN0b25lcworICAgICAgICAgICAgLy8gYW5kIG5vdCBmaWxsIHVwIHRoZSB0YWJsZSkuCisgICAgICAgICAgICBpbnQgbmV3Q2FwYWNpdHkgPSBjYXBhY2l0eTsKKworICAgICAgICAgICAgaWYgKHNpemUgPiAoY2FwYWNpdHkgPj4gMSkpIHsKKyAgICAgICAgICAgICAgICAvLyBNb3JlIHRoYW4gMS8yIGZpbGxlZCB3LyBsaXZlIGVudHJpZXMuCisgICAgICAgICAgICAgICAgLy8gRG91YmxlIHNpemUuCisgICAgICAgICAgICAgICAgbmV3Q2FwYWNpdHkgPSBjYXBhY2l0eSAqIDI7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIE9iamVjdFtdIG9sZFRhYmxlID0gdGhpcy50YWJsZTsKKworICAgICAgICAgICAgLy8gQWxsb2NhdGUgbmV3IHRhYmxlLgorICAgICAgICAgICAgaW5pdGlhbGl6ZVRhYmxlKG5ld0NhcGFjaXR5KTsKKworICAgICAgICAgICAgLy8gV2Ugd29uJ3QgaGF2ZSBhbnkgdG9tYnN0b25lcyBhZnRlciB0aGlzLgorICAgICAgICAgICAgdGhpcy50b21ic3RvbmVzID0gMDsKKworICAgICAgICAgICAgLy8gSWYgd2UgaGF2ZSBubyBsaXZlIGVudHJpZXMsIHdlIGNhbiBxdWl0IGhlcmUuCisgICAgICAgICAgICBpZiAoc2l6ZSA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIE1vdmUgb3ZlciBlbnRyaWVzLgorICAgICAgICAgICAgZm9yIChpbnQgaSA9IG9sZFRhYmxlLmxlbmd0aCAtIDI7IGkgPj0gMDsgaSAtPSAyKSB7CisgICAgICAgICAgICAgICAgT2JqZWN0IGsgPSBvbGRUYWJsZVtpXTsKKyAgICAgICAgICAgICAgICBpZiAoayA9PSBudWxsIHx8IGsgPT0gVE9NQlNUT05FKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFNraXAgdGhpcyBlbnRyeS4KKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gVGhlIHRhYmxlIGNhbiBvbmx5IGNvbnRhaW4gbnVsbCwgdG9tYnN0b25lcyBhbmQgcmVmZXJlbmNlcy4KKyAgICAgICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgICAgICAgICBSZWZlcmVuY2U8VGhyZWFkTG9jYWw8Pz4+IHJlZmVyZW5jZQorICAgICAgICAgICAgICAgICAgICAgICAgPSAoUmVmZXJlbmNlPFRocmVhZExvY2FsPD8+PikgazsKKyAgICAgICAgICAgICAgICBUaHJlYWRMb2NhbDw/PiBrZXkgPSByZWZlcmVuY2UuZ2V0KCk7CisgICAgICAgICAgICAgICAgaWYgKGtleSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIEVudHJ5IGlzIHN0aWxsIGxpdmUuIE1vdmUgaXQgb3Zlci4KKyAgICAgICAgICAgICAgICAgICAgYWRkKGtleSwgb2xkVGFibGVbaSArIDFdKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAvLyBUaGUga2V5IHdhcyByZWNsYWltZWQuCisgICAgICAgICAgICAgICAgICAgIHNpemUtLTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEFkZHMgYW4gZW50cnkgZHVyaW5nIHJlaGFzaGluZy4gQ29tcGFyZWQgdG8gcHV0KCksIHRoaXMgbWV0aG9kCisgICAgICAgICAqIGRvZXNuJ3QgaGF2ZSB0byBjbGVhbiB1cCwgY2hlY2sgZm9yIGV4aXN0aW5nIGVudHJpZXMsIGFjY291bnQgZm9yCisgICAgICAgICAqIHRvbWJzdG9uZXMsIGV0Yy4KKyAgICAgICAgICovCisgICAgICAgIHZvaWQgYWRkKFRocmVhZExvY2FsPD8+IGtleSwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgICAgICBmb3IgKGludCBpbmRleCA9IGtleS5oYXNoICYgbWFzazs7IGluZGV4ID0gbmV4dChpbmRleCkpIHsKKyAgICAgICAgICAgICAgICBPYmplY3QgayA9IHRhYmxlW2luZGV4XTsKKyAgICAgICAgICAgICAgICBpZiAoayA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRhYmxlW2luZGV4XSA9IGtleS5yZWZlcmVuY2U7CisgICAgICAgICAgICAgICAgICAgIHRhYmxlW2luZGV4ICsgMV0gPSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTZXRzIGVudHJ5IGZvciBnaXZlbiBUaHJlYWRMb2NhbCB0byBnaXZlbiB2YWx1ZSwgY3JlYXRpbmcgYW4KKyAgICAgICAgICogZW50cnkgaWYgbmVjZXNzYXJ5LgorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBwdXQoVGhyZWFkTG9jYWw8Pz4ga2V5LCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgICAgIGNsZWFuVXAoKTsKKworICAgICAgICAgICAgLy8gS2VlcCB0cmFjayBvZiBmaXJzdCB0b21ic3RvbmUuIFRoYXQncyB3aGVyZSB3ZSB3YW50IHRvIGdvIGJhY2sKKyAgICAgICAgICAgIC8vIGFuZCBhZGQgYW4gZW50cnkgaWYgbmVjZXNzYXJ5LgorICAgICAgICAgICAgaW50IGZpcnN0VG9tYnN0b25lID0gLTE7CisKKyAgICAgICAgICAgIGZvciAoaW50IGluZGV4ID0ga2V5Lmhhc2ggJiBtYXNrOzsgaW5kZXggPSBuZXh0KGluZGV4KSkgeworICAgICAgICAgICAgICAgIE9iamVjdCBrID0gdGFibGVbaW5kZXhdOworCisgICAgICAgICAgICAgICAgaWYgKGsgPT0ga2V5LnJlZmVyZW5jZSkgeworICAgICAgICAgICAgICAgICAgICAvLyBSZXBsYWNlIGV4aXN0aW5nIGVudHJ5LgorICAgICAgICAgICAgICAgICAgICB0YWJsZVtpbmRleCArIDFdID0gdmFsdWU7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoayA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdFRvbWJzdG9uZSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmlsbCBpbiBudWxsIHNsb3QuCisgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZVtpbmRleF0gPSBrZXkucmVmZXJlbmNlOworICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVbaW5kZXggKyAxXSA9IHZhbHVlOworICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSsrOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgLy8gR28gYmFjayBhbmQgcmVwbGFjZSBmaXJzdCB0b21ic3RvbmUuCisgICAgICAgICAgICAgICAgICAgIHRhYmxlW2ZpcnN0VG9tYnN0b25lXSA9IGtleS5yZWZlcmVuY2U7CisgICAgICAgICAgICAgICAgICAgIHRhYmxlW2ZpcnN0VG9tYnN0b25lICsgMV0gPSB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgdG9tYnN0b25lcy0tOworICAgICAgICAgICAgICAgICAgICBzaXplKys7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBSZW1lbWJlciBmaXJzdCB0b21ic3RvbmUuCisgICAgICAgICAgICAgICAgaWYgKGZpcnN0VG9tYnN0b25lID09IC0xICYmIGsgPT0gVE9NQlNUT05FKSB7CisgICAgICAgICAgICAgICAgICAgIGZpcnN0VG9tYnN0b25lID0gaW5kZXg7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgdmFsdWUgZm9yIGdpdmVuIFRocmVhZExvY2FsIGFmdGVyIG5vdCBmaW5kaW5nIGl0IGluIHRoZSBmaXJzdAorICAgICAgICAgKiBzbG90LgorICAgICAgICAgKi8KKyAgICAgICAgT2JqZWN0IGdldEFmdGVyTWlzcyhUaHJlYWRMb2NhbDw/PiBrZXkpIHsKKyAgICAgICAgICAgIE9iamVjdFtdIHRhYmxlID0gdGhpcy50YWJsZTsKKyAgICAgICAgICAgIGludCBpbmRleCA9IGtleS5oYXNoICYgbWFzazsKKworICAgICAgICAgICAgLy8gSWYgdGhlIGZpcnN0IHNsb3QgaXMgZW1wdHksIHRoZSBzZWFyY2ggaXMgb3Zlci4KKyAgICAgICAgICAgIGlmICh0YWJsZVtpbmRleF0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IGtleS5pbml0aWFsVmFsdWUoKTsKKworICAgICAgICAgICAgICAgIC8vIElmIHRoZSB0YWJsZSBpcyBzdGlsbCB0aGUgc2FtZSBhbmQgdGhlIHNsb3QgaXMgc3RpbGwgZW1wdHkuLi4KKyAgICAgICAgICAgICAgICBpZiAodGhpcy50YWJsZSA9PSB0YWJsZSAmJiB0YWJsZVtpbmRleF0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0YWJsZVtpbmRleF0gPSBrZXkucmVmZXJlbmNlOworICAgICAgICAgICAgICAgICAgICB0YWJsZVtpbmRleCArIDFdID0gdmFsdWU7CisgICAgICAgICAgICAgICAgICAgIHNpemUrKzsKKworICAgICAgICAgICAgICAgICAgICBjbGVhblVwKCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBUaGUgdGFibGUgY2hhbmdlZCBkdXJpbmcgaW5pdGlhbFZhbHVlKCkuCisgICAgICAgICAgICAgICAgcHV0KGtleSwgdmFsdWUpOworICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gS2VlcCB0cmFjayBvZiBmaXJzdCB0b21ic3RvbmUuIFRoYXQncyB3aGVyZSB3ZSB3YW50IHRvIGdvIGJhY2sKKyAgICAgICAgICAgIC8vIGFuZCBhZGQgYW4gZW50cnkgaWYgbmVjZXNzYXJ5LgorICAgICAgICAgICAgaW50IGZpcnN0VG9tYnN0b25lID0gLTE7CisKKyAgICAgICAgICAgIC8vIENvbnRpbnVlIHNlYXJjaC4KKyAgICAgICAgICAgIGZvciAoaW5kZXggPSBuZXh0KGluZGV4KTs7IGluZGV4ID0gbmV4dChpbmRleCkpIHsKKyAgICAgICAgICAgICAgICBPYmplY3QgcmVmZXJlbmNlID0gdGFibGVbaW5kZXhdOworICAgICAgICAgICAgICAgIGlmIChyZWZlcmVuY2UgPT0ga2V5LnJlZmVyZW5jZSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFibGVbaW5kZXggKyAxXTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBJZiBubyBlbnRyeSB3YXMgZm91bmQuLi4KKyAgICAgICAgICAgICAgICBpZiAocmVmZXJlbmNlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0ga2V5LmluaXRpYWxWYWx1ZSgpOworCisgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSB0YWJsZSBpcyBzdGlsbCB0aGUgc2FtZS4uLgorICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50YWJsZSA9PSB0YWJsZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgd2UgcGFzc2VkIGEgdG9tYnN0b25lIGFuZCB0aGF0IHNsb3Qgc3RpbGwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnRhaW5zIGEgdG9tYnN0b25lLi4uCisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlyc3RUb21ic3RvbmUgPiAtMQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiB0YWJsZVtmaXJzdFRvbWJzdG9uZV0gPT0gVE9NQlNUT05FKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVbZmlyc3RUb21ic3RvbmVdID0ga2V5LnJlZmVyZW5jZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZVtmaXJzdFRvbWJzdG9uZSArIDFdID0gdmFsdWU7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9tYnN0b25lcy0tOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUrKzsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vIG5lZWQgdG8gY2xlYW4gdXAgaGVyZS4gV2UgYXJlbid0IGZpbGxpbmcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbiBhIG51bGwgc2xvdC4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgc2xvdCBpcyBzdGlsbCBlbXB0eS4uLgorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRhYmxlW2luZGV4XSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVbaW5kZXhdID0ga2V5LnJlZmVyZW5jZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZVtpbmRleCArIDFdID0gdmFsdWU7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSsrOworCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYW5VcCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vIFRoZSB0YWJsZSBjaGFuZ2VkIGR1cmluZyBpbml0aWFsVmFsdWUoKS4KKyAgICAgICAgICAgICAgICAgICAgcHV0KGtleSwgdmFsdWUpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGZpcnN0VG9tYnN0b25lID09IC0xICYmIHJlZmVyZW5jZSA9PSBUT01CU1RPTkUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gS2VlcCB0cmFjayBvZiB0aGlzIHRvbWJzdG9uZSBzbyB3ZSBjYW4gb3ZlcndyaXRlIGl0LgorICAgICAgICAgICAgICAgICAgICBmaXJzdFRvbWJzdG9uZSA9IGluZGV4OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZW1vdmVzIGVudHJ5IGZvciB0aGUgZ2l2ZW4gVGhyZWFkTG9jYWwuCisgICAgICAgICAqLworICAgICAgICB2b2lkIHJlbW92ZShUaHJlYWRMb2NhbDw/PiBrZXkpIHsKKyAgICAgICAgICAgIGNsZWFuVXAoKTsKKworICAgICAgICAgICAgZm9yIChpbnQgaW5kZXggPSBrZXkuaGFzaCAmIG1hc2s7OyBpbmRleCA9IG5leHQoaW5kZXgpKSB7CisgICAgICAgICAgICAgICAgT2JqZWN0IHJlZmVyZW5jZSA9IHRhYmxlW2luZGV4XTsKKworICAgICAgICAgICAgICAgIGlmIChyZWZlcmVuY2UgPT0ga2V5LnJlZmVyZW5jZSkgeworICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIQorICAgICAgICAgICAgICAgICAgICB0YWJsZVtpbmRleF0gPSBUT01CU1RPTkU7CisgICAgICAgICAgICAgICAgICAgIHRhYmxlW2luZGV4ICsgMV0gPSBudWxsOworICAgICAgICAgICAgICAgICAgICB0b21ic3RvbmVzKys7CisgICAgICAgICAgICAgICAgICAgIHNpemUtLTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChyZWZlcmVuY2UgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAvLyBObyBlbnRyeSBmb3VuZC4KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBHZXRzIHRoZSBuZXh0IGluZGV4LiBJZiB3ZSdyZSBhdCB0aGUgZW5kIG9mIHRoZSB0YWJsZSwgd2Ugd3JhcCBiYWNrCisgICAgICAgICAqIGFyb3VuZCB0byAwLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBpbnQgbmV4dChpbnQgaW5kZXgpIHsKKyAgICAgICAgICAgIHJldHVybiAoaW5kZXggKyAyKSAmIG1hc2s7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1Rocm93YWJsZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9UaHJvd2FibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNTYxODMyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9UaHJvd2FibGUuamF2YQpAQCAtMCwwICsxLDQ2NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGxpYmNvcmUudXRpbC5FbXB0eUFycmF5OworCisvKioKKyAqIFRoZSBzdXBlcmNsYXNzIG9mIGFsbCBjbGFzc2VzIHdoaWNoIGNhbiBiZSB0aHJvd24gYnkgdGhlIFZNLiBUaGUKKyAqIHR3byBkaXJlY3Qgc3ViY2xhc3NlcyBhcmUgcmVjb3ZlcmFibGUgZXhjZXB0aW9ucyAoe0Bjb2RlIEV4Y2VwdGlvbn0pIGFuZAorICogdW5yZWNvdmVyYWJsZSBlcnJvcnMgKHtAY29kZSBFcnJvcn0pLiBUaGlzIGNsYXNzIHByb3ZpZGVzIGNvbW1vbiBtZXRob2RzIGZvcgorICogYWNjZXNzaW5nIGEgc3RyaW5nIG1lc3NhZ2Ugd2hpY2ggcHJvdmlkZXMgZXh0cmEgaW5mb3JtYXRpb24gYWJvdXQgdGhlCisgKiBjaXJjdW1zdGFuY2VzIGluIHdoaWNoIHRoZSB7QGNvZGUgVGhyb3dhYmxlfSB3YXMgY3JlYXRlZCAoYmFzaWNhbGx5IGFuIGVycm9yCisgKiBtZXNzYWdlIGluIG1vc3QgY2FzZXMpLCBhbmQgZm9yIHNhdmluZyBhIHN0YWNrIHRyYWNlICh0aGF0IGlzLCBhIHJlY29yZCBvZgorICogdGhlIGNhbGwgc3RhY2sgYXQgYSBwYXJ0aWN1bGFyIHBvaW50IGluIHRpbWUpIHdoaWNoIGNhbiBiZSBwcmludGVkIGxhdGVyLgorICogPHA+CisgKiBBIHtAY29kZSBUaHJvd2FibGV9IGNhbiBhbHNvIGluY2x1ZGUgYSBjYXVzZSwgd2hpY2ggaXMgYSBuZXN0ZWQge0Bjb2RlCisgKiBUaHJvd2FibGV9IHRoYXQgcmVwcmVzZW50cyB0aGUgb3JpZ2luYWwgcHJvYmxlbSB0aGF0IGxlZCB0byB0aGlzIHtAY29kZQorICogVGhyb3dhYmxlfS4gSXQgaXMgb2Z0ZW4gdXNlZCBmb3Igd3JhcHBpbmcgdmFyaW91cyB0eXBlcyBvZiBlcnJvcnMgaW50byBhCisgKiBjb21tb24ge0Bjb2RlIFRocm93YWJsZX0gd2l0aG91dCBsb3NpbmcgdGhlIGRldGFpbGVkIG9yaWdpbmFsIGVycm9yCisgKiBpbmZvcm1hdGlvbi4gV2hlbiBwcmludGluZyB0aGUgc3RhY2sgdHJhY2UsIHRoZSB0cmFjZSBvZiB0aGUgY2F1c2UgaXMKKyAqIGluY2x1ZGVkLgorICoKKyAqIEBzZWUgRXJyb3IKKyAqIEBzZWUgRXhjZXB0aW9uCisgKiBAc2VlIFJ1bnRpbWVFeGNlcHRpb24KKyAqLworcHVibGljIGNsYXNzIFRocm93YWJsZSBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzA0MjY4NjA1NTY1ODA0NzI4NUw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWVzc2FnZSBwcm92aWRlZCB3aGVuIHRoZSBleGNlcHRpb24gd2FzIGNyZWF0ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZGV0YWlsTWVzc2FnZTsKKworICAgIC8qKgorICAgICAqIFRoZSBjYXVzZSBvZiB0aGlzIFRocm93YWJsZS4gTnVsbCB3aGVuIHRoZXJlIGlzIG5vIGNhdXNlLgorICAgICAqLworICAgIHByaXZhdGUgVGhyb3dhYmxlIGNhdXNlID0gdGhpczsKKworICAgIC8qKgorICAgICAqIFRocm93YWJsZXMgc3VwcHJlc3NlZCBieSB0aGlzIHRocm93YWJsZS4gTnVsbCB3aGVuIHN1cHByZXNzZWQgZXhjZXB0aW9ucworICAgICAqIGFyZSBkaXNhYmxlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIExpc3Q8VGhyb3dhYmxlPiBzdXBwcmVzc2VkRXhjZXB0aW9ucyA9IG5ldyBBcnJheUxpc3Q8VGhyb3dhYmxlPigpOworCisgICAgLyoqCisgICAgICogQW4gaW50ZXJtZWRpYXRlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzdGFjayB0cmFjZS4gIFRoaXMgZmllbGQgbWF5CisgICAgICogYmUgYWNjZXNzZWQgYnkgdGhlIFZNOyBkbyBub3QgcmVuYW1lLgorICAgICAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgT2JqZWN0IHN0YWNrU3RhdGU7CisKKyAgICAvKioKKyAgICAgKiBBIGZ1bGx5LWV4cGFuZGVkIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzdGFjayB0cmFjZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0YWNrVHJhY2VFbGVtZW50W10gc3RhY2tUcmFjZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFRocm93YWJsZX0gdGhhdCBpbmNsdWRlcyB0aGUgY3VycmVudCBzdGFjayB0cmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGhyb3dhYmxlKCkgeworICAgICAgICBmaWxsSW5TdGFja1RyYWNlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVGhyb3dhYmxlfSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlIGFuZCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIHtAY29kZSBUaHJvd2FibGV9LgorICAgICAqLworICAgIHB1YmxpYyBUaHJvd2FibGUoU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgdGhpcygpOworICAgICAgICB0aGlzLmRldGFpbE1lc3NhZ2UgPSBkZXRhaWxNZXNzYWdlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFRocm93YWJsZX0gd2l0aCB0aGUgY3VycmVudCBzdGFjayB0cmFjZSwgdGhlCisgICAgICogc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlIGFuZCB0aGUgc3BlY2lmaWVkIGNhdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyB7QGNvZGUgVGhyb3dhYmxlfS4KKyAgICAgKiBAcGFyYW0gdGhyb3dhYmxlCisgICAgICogICAgICAgICAgICB0aGUgY2F1c2Ugb2YgdGhpcyB7QGNvZGUgVGhyb3dhYmxlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGhyb3dhYmxlKFN0cmluZyBkZXRhaWxNZXNzYWdlLCBUaHJvd2FibGUgdGhyb3dhYmxlKSB7CisgICAgICAgIHRoaXMoKTsKKyAgICAgICAgdGhpcy5kZXRhaWxNZXNzYWdlID0gZGV0YWlsTWVzc2FnZTsKKyAgICAgICAgY2F1c2UgPSB0aHJvd2FibGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVGhyb3dhYmxlfSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlIGFuZCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhyb3dhYmxlCisgICAgICogICAgICAgICAgICB0aGUgY2F1c2Ugb2YgdGhpcyB7QGNvZGUgVGhyb3dhYmxlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGhyb3dhYmxlKFRocm93YWJsZSB0aHJvd2FibGUpIHsKKyAgICAgICAgdGhpcygpOworICAgICAgICB0aGlzLmRldGFpbE1lc3NhZ2UgPSB0aHJvd2FibGUgPT0gbnVsbCA/IG51bGwgOiB0aHJvd2FibGUudG9TdHJpbmcoKTsKKyAgICAgICAgY2F1c2UgPSB0aHJvd2FibGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVGhyb3dhYmxlfSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrIHRyYWNlLCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UgYW5kIHRoZSBzcGVjaWZpZWQgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW5hYmxlU3VwcHJlc3Npb24gaWYgZmFsc2UsIHRocm93YWJsZXMgcGFzc2VkIHRvIHtAbGluaworICAgICAqICAgICAjYWRkU3VwcHJlc3NlZChUaHJvd2FibGUpfSB3aWxsIGJlIHNpbGVudGx5IGRpc2NhcmRlZC4KKyAgICAgKiBAc2luY2UgMS43CisgICAgICogQGhpZGUgMS43CisgICAgICovCisgICAgcHJvdGVjdGVkIFRocm93YWJsZShTdHJpbmcgZGV0YWlsTWVzc2FnZSwgVGhyb3dhYmxlIHRocm93YWJsZSwgYm9vbGVhbiBlbmFibGVTdXBwcmVzc2lvbikgeworICAgICAgICB0aGlzKGRldGFpbE1lc3NhZ2UsIHRocm93YWJsZSk7CisgICAgICAgIGlmICghZW5hYmxlU3VwcHJlc3Npb24pIHsKKyAgICAgICAgICAgIHRoaXMuc3VwcHJlc3NlZEV4Y2VwdGlvbnMgPSBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVjb3JkcyB0aGUgc3RhY2sgdHJhY2UgZnJvbSB0aGUgcG9pbnQgd2hlcmUgdGhpcyBtZXRob2QgaGFzIGJlZW4gY2FsbGVkCisgICAgICogdG8gdGhpcyB7QGNvZGUgVGhyb3dhYmxlfS4gVGhpcyBtZXRob2QgaXMgaW52b2tlZCBieSB0aGUge0Bjb2RlIFRocm93YWJsZX0gY29uc3RydWN0b3JzLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgcHVibGljIHNvIHRoYXQgY29kZSAoc3VjaCBhcyBhbiBSUEMgc3lzdGVtKSB3aGljaCBjYXRjaGVzCisgICAgICogYSB7QGNvZGUgVGhyb3dhYmxlfSBhbmQgdGhlbiByZS10aHJvd3MgaXQgY2FuIHJlcGxhY2UgdGhlIGNvbnN0cnVjdGlvbi10aW1lIHN0YWNrIHRyYWNlCisgICAgICogd2l0aCBhIHN0YWNrIHRyYWNlIGZyb20gdGhlIGxvY2F0aW9uIHdoZXJlIHRoZSBleGNlcHRpb24gd2FzIHJlLXRocm93biwgYnkgPGk+Y2FsbGluZzwvaT4KKyAgICAgKiB7QGNvZGUgZmlsbEluU3RhY2tUcmFjZX0uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBub24tZmluYWwgc28gdGhhdCBub24tSmF2YSBsYW5ndWFnZSBpbXBsZW1lbnRhdGlvbnMgY2FuIGRpc2FibGUgVk0gc3RhY2sKKyAgICAgKiB0cmFjZXMgZm9yIHRoZWlyIGxhbmd1YWdlLiBGaWxsaW5nIGluIHRoZSBzdGFjayB0cmFjZSBpcyByZWxhdGl2ZWx5IGV4cGVuc2l2ZS4KKyAgICAgKiA8aT5PdmVycmlkaW5nPC9pPiB0aGlzIG1ldGhvZCBpbiB0aGUgcm9vdCBvZiBhIGxhbmd1YWdlJ3MgZXhjZXB0aW9uIGhpZXJhcmNoeSBhbGxvd3MgdGhlCisgICAgICogbGFuZ3VhZ2UgdG8gYXZvaWQgcGF5aW5nIGZvciBzb21ldGhpbmcgaXQgZG9lc24ndCBuZWVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIHtAY29kZSBUaHJvd2FibGV9IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBUaHJvd2FibGUgZmlsbEluU3RhY2tUcmFjZSgpIHsKKyAgICAgICAgLy8gRmlsbCBpbiB0aGUgaW50ZXJtZWRpYXRlIHJlcHJlc2VudGF0aW9uCisgICAgICAgIHN0YWNrU3RhdGUgPSBuYXRpdmVGaWxsSW5TdGFja1RyYWNlKCk7CisgICAgICAgIC8vIE1hcmsgdGhlIGZ1bGwgcmVwcmVzZW50YXRpb24gYXMgZW1wdHkKKyAgICAgICAgc3RhY2tUcmFjZSA9IG51bGw7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGV4dHJhIGluZm9ybWF0aW9uIG1lc3NhZ2Ugd2hpY2ggd2FzIHByb3ZpZGVkIHdoZW4gdGhpcworICAgICAqIHtAY29kZSBUaHJvd2FibGV9IHdhcyBjcmVhdGVkLiBSZXR1cm5zIHtAY29kZSBudWxsfSBpZiBubyBtZXNzYWdlIHdhcworICAgICAqIHByb3ZpZGVkIGF0IGNyZWF0aW9uIHRpbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMge0Bjb2RlIFRocm93YWJsZX0ncyBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2UoKSB7CisgICAgICAgIHJldHVybiBkZXRhaWxNZXNzYWdlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGV4dHJhIGluZm9ybWF0aW9uIG1lc3NhZ2Ugd2hpY2ggd2FzIHByb3ZpZGVkIHdoZW4gdGhpcworICAgICAqIHtAY29kZSBUaHJvd2FibGV9IHdhcyBjcmVhdGVkLiBSZXR1cm5zIHtAY29kZSBudWxsfSBpZiBubyBtZXNzYWdlIHdhcworICAgICAqIHByb3ZpZGVkIGF0IGNyZWF0aW9uIHRpbWUuIFN1YmNsYXNzZXMgbWF5IG92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIHJldHVybgorICAgICAqIGxvY2FsaXplZCB0ZXh0IGZvciB0aGUgbWVzc2FnZS4gQW5kcm9pZCByZXR1cm5zIHRoZSByZWd1bGFyIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIHtAY29kZSBUaHJvd2FibGV9J3MgbG9jYWxpemVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxpemVkTWVzc2FnZSgpIHsKKyAgICAgICAgcmV0dXJuIGdldE1lc3NhZ2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhcnJheSBvZiBzdGFjayB0cmFjZSBlbGVtZW50cyBvZiB0aGlzIHtAY29kZSBUaHJvd2FibGV9LiBFYWNoCisgICAgICoge0Bjb2RlIFN0YWNrVHJhY2VFbGVtZW50fSByZXByZXNlbnRzIGFuIGVudHJ5IGluIHRoZSBjYWxsIHN0YWNrLiBUaGUKKyAgICAgKiBlbGVtZW50IGF0IHBvc2l0aW9uIDAgaXMgdGhlIHRvcCBvZiB0aGUgc3RhY2ssIHRoYXQgaXMsIHRoZSBzdGFjayBmcmFtZQorICAgICAqIHdoZXJlIHRoaXMge0Bjb2RlIFRocm93YWJsZX0gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHJldHVybiBhIGNvcHkgb2YgdGhlIGFycmF5IG9mIHtAY29kZSBTdGFja1RyYWNlRWxlbWVudH1zIHJlcHJlc2VudGluZworICAgICAqICAgICAgICAgdGhlIGNhbGwgc3RhY2suIENoYW5nZXMgaW4gdGhlIGFycmF5IG9idGFpbmVkIGZyb20gdGhpcyBjYWxsIHdpbGwKKyAgICAgKiAgICAgICAgIG5vdCBjaGFuZ2UgdGhlIGNhbGwgc3RhY2sgc3RvcmVkIGluIHRoaXMge0Bjb2RlIFRocm93YWJsZX0uCisgICAgICogQHNlZSAjcHJpbnRTdGFja1RyYWNlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RhY2tUcmFjZUVsZW1lbnRbXSBnZXRTdGFja1RyYWNlKCkgeworICAgICAgICByZXR1cm4gZ2V0SW50ZXJuYWxTdGFja1RyYWNlKCkuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBhcnJheSBvZiBzdGFjayB0cmFjZSBlbGVtZW50cy4gRWFjaCB7QGNvZGUgU3RhY2tUcmFjZUVsZW1lbnR9CisgICAgICogcmVwcmVzZW50cyBhbiBlbnRyeSBpbiB0aGUgY2FsbCBzdGFjay4gQSBjb3B5IG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkgaXMKKyAgICAgKiBzdG9yZWQgaW4gdGhpcyB7QGNvZGUgVGhyb3dhYmxlfS4gd2lsbCBiZSByZXR1cm5lZCBieSB7QGNvZGUKKyAgICAgKiBnZXRTdGFja1RyYWNlKCl9IGFuZCBwcmludGVkIGJ5IHtAY29kZSBwcmludFN0YWNrVHJhY2UoKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHJhY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgYXJyYXkgb2Yge0Bjb2RlIFN0YWNrVHJhY2VFbGVtZW50fXMuIEEgY29weSBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgIGFycmF5IGlzIHN0b3JlZCBpbiB0aGlzIHtAY29kZSBUaHJvd2FibGV9LCBzbyBzdWJzZXF1ZW50CisgICAgICogICAgICAgICAgICBjaGFuZ2VzIHRvIHtAY29kZSB0cmFjZX0gd2lsbCBub3QgY2hhbmdlIHRoZSBjYWxsIHN0YWNrIHN0b3JlZAorICAgICAqICAgICAgICAgICAgaW4gdGhpcyB7QGNvZGUgVGhyb3dhYmxlfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IGVsZW1lbnQgaW4ge0Bjb2RlIHRyYWNlfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHNlZSAjcHJpbnRTdGFja1RyYWNlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTdGFja1RyYWNlKFN0YWNrVHJhY2VFbGVtZW50W10gdHJhY2UpIHsKKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnRbXSBuZXdUcmFjZSA9IHRyYWNlLmNsb25lKCk7CisgICAgICAgIGZvciAoU3RhY2tUcmFjZUVsZW1lbnQgZWxlbWVudCA6IG5ld1RyYWNlKSB7CisgICAgICAgICAgICBpZiAoZWxlbWVudCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgc3RhY2tUcmFjZSA9IG5ld1RyYWNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIHByaW50YWJsZSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZSBUaHJvd2FibGV9J3Mgc3RhY2sgdHJhY2UKKyAgICAgKiB0byB0aGUge0Bjb2RlIFN5c3RlbS5lcnJ9IHN0cmVhbS4KKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50U3RhY2tUcmFjZSgpIHsKKyAgICAgICAgcHJpbnRTdGFja1RyYWNlKFN5c3RlbS5lcnIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvdW50cyB0aGUgbnVtYmVyIG9mIGR1cGxpY2F0ZSBzdGFjayBmcmFtZXMsIHN0YXJ0aW5nIGZyb20gdGhlCisgICAgICogZW5kIG9mIHRoZSBzdGFjay4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjdXJyZW50U3RhY2sgYSBzdGFjayB0byBjb21wYXJlCisgICAgICogQHBhcmFtIHBhcmVudFN0YWNrIGEgc3RhY2sgdG8gY29tcGFyZQorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGR1cGxpY2F0ZSBzdGFjayBmcmFtZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGNvdW50RHVwbGljYXRlcyhTdGFja1RyYWNlRWxlbWVudFtdIGN1cnJlbnRTdGFjaywKKyAgICAgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50W10gcGFyZW50U3RhY2spIHsKKyAgICAgICAgaW50IGR1cGxpY2F0ZXMgPSAwOworICAgICAgICBpbnQgcGFyZW50SW5kZXggPSBwYXJlbnRTdGFjay5sZW5ndGg7CisgICAgICAgIGZvciAoaW50IGkgPSBjdXJyZW50U3RhY2subGVuZ3RoOyAtLWkgPj0gMCAmJiAtLXBhcmVudEluZGV4ID49IDA7KSB7CisgICAgICAgICAgICBTdGFja1RyYWNlRWxlbWVudCBwYXJlbnRGcmFtZSA9IHBhcmVudFN0YWNrW3BhcmVudEluZGV4XTsKKyAgICAgICAgICAgIGlmIChwYXJlbnRGcmFtZS5lcXVhbHMoY3VycmVudFN0YWNrW2ldKSkgeworICAgICAgICAgICAgICAgIGR1cGxpY2F0ZXMrKzsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBTdGFja1RyYWNlRWxlbWVudC4gRWFjaCBTdGFja1RyYWNlRWxlbWVudAorICAgICAqIHJlcHJlc2VudHMgYSBlbnRyeSBvbiB0aGUgc3RhY2suCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIFN0YWNrVHJhY2VFbGVtZW50IHJlcHJlc2VudGluZyB0aGUgc3RhY2sKKyAgICAgKi8KKyAgICBwcml2YXRlIFN0YWNrVHJhY2VFbGVtZW50W10gZ2V0SW50ZXJuYWxTdGFja1RyYWNlKCkgeworICAgICAgICBpZiAoc3RhY2tUcmFjZSA9PSBudWxsKSB7CisgICAgICAgICAgICBzdGFja1RyYWNlID0gbmF0aXZlR2V0U3RhY2tUcmFjZShzdGFja1N0YXRlKTsKKyAgICAgICAgICAgIHN0YWNrU3RhdGUgPSBudWxsOyAvLyBDbGVhbiB1cCBpbnRlcm1lZGlhdGUgcmVwcmVzZW50YXRpb24KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3RhY2tUcmFjZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBwcmludGFibGUgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgVGhyb3dhYmxlfSdzIHN0YWNrIHRyYWNlCisgICAgICogdG8gdGhlIHNwZWNpZmllZCBwcmludCBzdHJlYW0uIElmIHRoZSB7QGNvZGUgVGhyb3dhYmxlfSBjb250YWlucyBhCisgICAgICoge0BsaW5rICNnZXRDYXVzZSgpIGNhdXNlfSwgdGhlIG1ldGhvZCB3aWxsIGJlIGludm9rZWQgcmVjdXJzaXZlbHkgZm9yCisgICAgICogdGhlIG5lc3RlZCB7QGNvZGUgVGhyb3dhYmxlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlcnIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJlYW0gdG8gd3JpdGUgdGhlIHN0YWNrIHRyYWNlIG9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50U3RhY2tUcmFjZShQcmludFN0cmVhbSBlcnIpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByaW50U3RhY2tUcmFjZShlcnIsICIiLCBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQXBwZW5kYWJsZS5hcHBlbmQgdGhyb3dzIElPRXhjZXB0aW9uIGJ1dCBQcmludFN0cmVhbS5hcHBlbmQgZG9lc24ndC4KKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgcHJpbnRhYmxlIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMge0Bjb2RlIFRocm93YWJsZX0ncyBzdGFjayB0cmFjZQorICAgICAqIHRvIHRoZSBzcGVjaWZpZWQgcHJpbnQgd3JpdGVyLiBJZiB0aGUge0Bjb2RlIFRocm93YWJsZX0gY29udGFpbnMgYQorICAgICAqIHtAbGluayAjZ2V0Q2F1c2UoKSBjYXVzZX0sIHRoZSBtZXRob2Qgd2lsbCBiZSBpbnZva2VkIHJlY3Vyc2l2ZWx5IGZvciB0aGUKKyAgICAgKiBuZXN0ZWQge0Bjb2RlIFRocm93YWJsZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXJyCisgICAgICogICAgICAgICAgICB0aGUgd3JpdGVyIHRvIHdyaXRlIHRoZSBzdGFjayB0cmFjZSBvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludFN0YWNrVHJhY2UoUHJpbnRXcml0ZXIgZXJyKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmludFN0YWNrVHJhY2UoZXJyLCAiIiwgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEFwcGVuZGFibGUuYXBwZW5kIHRocm93cyBJT0V4Y2VwdGlvbiwgYnV0IFByaW50V3JpdGVyLmFwcGVuZCBkb2Vzbid0LgorICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gaW5kZW50IGFkZGl0aW9uYWwgaW5kZW50YXRpb24gb24gZWFjaCBsaW5lIG9mIHRoZSBzdGFjayB0cmFjZS4KKyAgICAgKiAgICAgVGhpcyBpcyB0aGUgZW1wdHkgc3RyaW5nIGZvciBhbGwgYnV0IHN1cHByZXNzZWQgdGhyb3dhYmxlcy4KKyAgICAgKiBAcGFyYW0gcGFyZW50U3RhY2sgdGhlIHBhcmVudCBzdGFjayB0cmFjZSB0byBzdXBwcmVzcyBkdXBsaWNhdGVzIGZyb20sIG9yCisgICAgICogICAgIG51bGwgaWYgdGhpcyBzdGFjayB0cmFjZSBoYXMgbm8gcGFyZW50LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwcmludFN0YWNrVHJhY2UoQXBwZW5kYWJsZSBlcnIsIFN0cmluZyBpbmRlbnQsIFN0YWNrVHJhY2VFbGVtZW50W10gcGFyZW50U3RhY2spCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBlcnIuYXBwZW5kKHRvU3RyaW5nKCkpOworICAgICAgICBlcnIuYXBwZW5kKCJcbiIpOworCisgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50W10gc3RhY2sgPSBnZXRJbnRlcm5hbFN0YWNrVHJhY2UoKTsKKyAgICAgICAgaWYgKHN0YWNrICE9IG51bGwpIHsKKyAgICAgICAgICAgIGludCBkdXBsaWNhdGVzID0gcGFyZW50U3RhY2sgIT0gbnVsbCA/IGNvdW50RHVwbGljYXRlcyhzdGFjaywgcGFyZW50U3RhY2spIDogMDsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3RhY2subGVuZ3RoIC0gZHVwbGljYXRlczsgaSsrKSB7CisgICAgICAgICAgICAgICAgZXJyLmFwcGVuZChpbmRlbnQpOworICAgICAgICAgICAgICAgIGVyci5hcHBlbmQoIlx0YXQgIik7CisgICAgICAgICAgICAgICAgZXJyLmFwcGVuZChzdGFja1tpXS50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICBlcnIuYXBwZW5kKCJcbiIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZHVwbGljYXRlcyA+IDApIHsKKyAgICAgICAgICAgICAgICBlcnIuYXBwZW5kKGluZGVudCk7CisgICAgICAgICAgICAgICAgZXJyLmFwcGVuZCgiXHQuLi4gIik7CisgICAgICAgICAgICAgICAgZXJyLmFwcGVuZChJbnRlZ2VyLnRvU3RyaW5nKGR1cGxpY2F0ZXMpKTsKKyAgICAgICAgICAgICAgICBlcnIuYXBwZW5kKCIgbW9yZVxuIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBQcmludCBzdXBwcmVzc2VkIGV4Y2VwdGlvbnMgaW5kZW50ZWQgb25lIGxldmVsIGRlZXBlci4KKyAgICAgICAgaWYgKHN1cHByZXNzZWRFeGNlcHRpb25zICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoVGhyb3dhYmxlIHRocm93YWJsZSA6IHN1cHByZXNzZWRFeGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgZXJyLmFwcGVuZChpbmRlbnQpOworICAgICAgICAgICAgICAgIGVyci5hcHBlbmQoIlx0U3VwcHJlc3NlZDogIik7CisgICAgICAgICAgICAgICAgdGhyb3dhYmxlLnByaW50U3RhY2tUcmFjZShlcnIsIGluZGVudCArICJcdCIsIHN0YWNrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFRocm93YWJsZSBjYXVzZSA9IGdldENhdXNlKCk7CisgICAgICAgIGlmIChjYXVzZSAhPSBudWxsKSB7CisgICAgICAgICAgICBlcnIuYXBwZW5kKGluZGVudCk7CisgICAgICAgICAgICBlcnIuYXBwZW5kKCJDYXVzZWQgYnk6ICIpOworICAgICAgICAgICAgY2F1c2UucHJpbnRTdGFja1RyYWNlKGVyciwgaW5kZW50LCBzdGFjayk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gZ2V0TG9jYWxpemVkTWVzc2FnZSgpOworICAgICAgICBTdHJpbmcgbmFtZSA9IGdldENsYXNzKCkuZ2V0TmFtZSgpOworICAgICAgICBpZiAobXNnID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBuYW1lOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuYW1lICsgIjogIiArIG1zZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGUgY2F1c2Ugb2YgdGhpcyB7QGNvZGUgVGhyb3dhYmxlfS4gVGhlIGNhdXNlIGNhbiBvbmx5IGJlCisgICAgICogaW5pdGlhbGl6ZWQgb25jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYXVzZSBvZiB0aGlzIHtAY29kZSBUaHJvd2FibGV9LgorICAgICAqIEByZXR1cm4gdGhpcyB7QGNvZGUgVGhyb3dhYmxlfSBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBUaHJvd2FibGV9IGlzIHRoaXMgb2JqZWN0LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNhdXNlIGhhcyBhbHJlYWR5IGJlZW4gaW5pdGlhbGl6ZWQuCisgICAgICovCisgICAgcHVibGljIFRocm93YWJsZSBpbml0Q2F1c2UoVGhyb3dhYmxlIHRocm93YWJsZSkgeworICAgICAgICBpZiAoY2F1c2UgIT0gdGhpcykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiQ2F1c2UgYWxyZWFkeSBpbml0aWFsaXplZCIpOworICAgICAgICB9CisgICAgICAgIGlmICh0aHJvd2FibGUgPT0gdGhpcykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigidGhyb3dhYmxlID09IHRoaXMiKTsKKyAgICAgICAgfQorICAgICAgICBjYXVzZSA9IHRocm93YWJsZTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2F1c2Ugb2YgdGhpcyB7QGNvZGUgVGhyb3dhYmxlfSwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzCisgICAgICogbm8gY2F1c2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRocm93YWJsZSB0aGlzIHtAY29kZSBUaHJvd2FibGV9J3MgY2F1c2UuCisgICAgICovCisgICAgcHVibGljIFRocm93YWJsZSBnZXRDYXVzZSgpIHsKKyAgICAgICAgaWYgKGNhdXNlID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjYXVzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHtAY29kZSB0aHJvd2FibGV9IHRvIHRoZSBsaXN0IG9mIHRocm93YWJsZXMgc3VwcHJlc3NlZCBieSB0aGlzLiBUaGUKKyAgICAgKiB0aHJvd2FibGUgd2lsbCBpbmNsdWRlZCB3aGVuIHRoaXMgZXhjZXB0aW9uJ3Mgc3RhY2sgdHJhY2UgaXMgcHJpbnRlZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSB0aHJvd2FibGUgPT0gdGhpc30uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgdGhyb3dhYmxlID09IG51bGx9LgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBhZGRTdXBwcmVzc2VkKFRocm93YWJsZSB0aHJvd2FibGUpIHsKKyAgICAgICAgaWYgKHRocm93YWJsZSA9PSB0aGlzKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzdXBwcmVzc2VkID09IHRoaXMiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodGhyb3dhYmxlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigic3VwcHJlc3NlZCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHN1cHByZXNzZWRFeGNlcHRpb25zICE9IG51bGwpIHsKKyAgICAgICAgICAgIHN1cHByZXNzZWRFeGNlcHRpb25zLmFkZCh0aHJvd2FibGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGhyb3dhYmxlcyBzdXBwcmVzc2VkIGJ5IHRoaXMuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS43CisgICAgICogQGhpZGUgMS43CisgICAgICovCisgICAgcHVibGljIGZpbmFsIFRocm93YWJsZVtdIGdldFN1cHByZXNzZWQoKSB7CisgICAgICAgIHJldHVybiAoc3VwcHJlc3NlZEV4Y2VwdGlvbnMgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICA/IHN1cHByZXNzZWRFeGNlcHRpb25zLnRvQXJyYXkobmV3IFRocm93YWJsZVtzdXBwcmVzc2VkRXhjZXB0aW9ucy5zaXplKCldKQorICAgICAgICAgICAgICAgIDogRW1wdHlBcnJheS5USFJPV0FCTEU7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIGVuc3VyZSB0aGUgc3RhY2tUcmFjZSBmaWVsZCBpcyBpbml0aWFsaXplZAorICAgICAgICBnZXRJbnRlcm5hbFN0YWNrVHJhY2UoKTsKKyAgICAgICAgb3V0LmRlZmF1bHRXcml0ZU9iamVjdCgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBpbi5kZWZhdWx0UmVhZE9iamVjdCgpOworCisgICAgICAgIGlmIChzdXBwcmVzc2VkRXhjZXB0aW9ucyAhPSBudWxsKSB7CisgICAgICAgICAgICAvLyB0aGUgZGVzZXJpYWxpemVkIGxpc3QgbWF5IGJlIHVubW9kaWZpYWJsZSwgc28ganVzdCBjcmVhdGUgYSBtdXRhYmxlIGNvcHkKKyAgICAgICAgICAgIHN1cHByZXNzZWRFeGNlcHRpb25zID0gbmV3IEFycmF5TGlzdDxUaHJvd2FibGU+KHN1cHByZXNzZWRFeGNlcHRpb25zKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQ3JlYXRlcyBhIGNvbXBhY3QsIFZNLXNwZWNpZmljIGNvbGxlY3Rpb24gb2YgZ29vZGllcywgc3VpdGFibGUgZm9yCisgICAgICogc3RvcmluZyBpbiB0aGUgInN0YWNrU3RhdGUiIGZpZWxkLCBiYXNlZCBvbiB0aGUgY3VycmVudCB0aHJlYWQncworICAgICAqIGNhbGwgc3RhY2suCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIE9iamVjdCBuYXRpdmVGaWxsSW5TdGFja1RyYWNlKCk7CisKKyAgICAvKgorICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgU3RhY2tUcmFjZUVsZW1lbnQgb2JqZWN0cyBmcm9tIHRoZSBkYXRhIGhlbGQKKyAgICAgKiBpbiAic3RhY2tTdGF0ZSIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIFN0YWNrVHJhY2VFbGVtZW50W10gbmF0aXZlR2V0U3RhY2tUcmFjZShPYmplY3Qgc3RhY2tTdGF0ZSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1R5cGVOb3RQcmVzZW50RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1R5cGVOb3RQcmVzZW50RXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGE4ODUzZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvVHlwZU5vdFByZXNlbnRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDU1IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gd2hlbiBhIHByb2dyYW0gdHJpZXMgdG8gYWNjZXNzIGEgY2xhc3MsIGludGVyZmFjZSwgZW51bSBvciBhbm5vdGF0aW9uCisgKiB0eXBlIHRocm91Z2ggYSBzdHJpbmcgdGhhdCBjb250YWlucyB0aGUgdHlwZSdzIG5hbWUgYW5kIHRoZSB0eXBlIGNhbm5vdCBiZQorICogZm91bmQuIFRoaXMgZXhjZXB0aW9uIGlzIGFuIHVuY2hlY2tlZCBhbHRlcm5hdGl2ZSB0bworICoge0BsaW5rIGphdmEubGFuZy5DbGFzc05vdEZvdW5kRXhjZXB0aW9ufS4KKyAqCisgKiBAc2luY2UgMS41CisgKi8KK3B1YmxpYyBjbGFzcyBUeXBlTm90UHJlc2VudEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC01MTAxMjE0MTk1NzE2NTM0NDk2TDsKKworICAgIHByaXZhdGUgU3RyaW5nIHR5cGVOYW1lOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVHlwZU5vdFByZXNlbnRFeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQgc3RhY2sKKyAgICAgKiB0cmFjZSwgYSBkZXRhaWwgbWVzc2FnZSB0aGF0IGluY2x1ZGVzIHRoZSBuYW1lIG9mIHRoZSB0eXBlIHRoYXQgY291bGQgbm90CisgICAgICogYmUgZm91bmQgYW5kIHRoZSB7QGNvZGUgVGhyb3dhYmxlfSB0aGF0IGNhdXNlZCB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSB0eXBlIHRoYXQgY291bGQgbm90IGJlIGZvdW5kLgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIG9wdGlvbmFsIGNhdXNlIG9mIHRoaXMgZXhjZXB0aW9uLCBtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBUeXBlTm90UHJlc2VudEV4Y2VwdGlvbihTdHJpbmcgdHlwZU5hbWUsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcigiVHlwZSAiICsgdHlwZU5hbWUgKyAiIG5vdCBwcmVzZW50IiwgY2F1c2UpOworICAgICAgICB0aGlzLnR5cGVOYW1lID0gdHlwZU5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIHR5cGUgdGhhdCBjb3VsZCBub3QgYmUgZm91bmQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSB0eXBlIHRoYXQgY2F1c2VkIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdHlwZU5hbWUoKSB7CisgICAgICAgIHJldHVybiB0eXBlTmFtZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1Vua25vd25FcnJvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Vbmtub3duRXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MWJmZTUwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Vbmtub3duRXJyb3IuamF2YQpAQCAtMCwwICsxLDQ1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gd2hlbiB0aGUgVk0gbXVzdCB0aHJvdyBhbiBlcnJvciB3aGljaCBkb2VzIG5vdCBtYXRjaCBhbnkKKyAqIGtub3duIGV4Y2VwdGlvbmFsIGNvbmRpdGlvbi4KKyAqLworcHVibGljIGNsYXNzIFVua25vd25FcnJvciBleHRlbmRzIFZpcnR1YWxNYWNoaW5lRXJyb3IgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjUyNDc4NDg2MDY3Njc3MTg0OUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBVbmtub3duRXJyb3J9IHRoYXQgaW5jbHVkZXMgdGhlIGN1cnJlbnQgc3RhY2sKKyAgICAgKiB0cmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5rbm93bkVycm9yKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFVua25vd25FcnJvcn0gd2l0aCB0aGUgY3VycmVudCBzdGFjayB0cmFjZSBhbmQKKyAgICAgKiB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFVua25vd25FcnJvcihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1Vuc2FmZUJ5dGVTZXF1ZW5jZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9VbnNhZmVCeXRlU2VxdWVuY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMjhiYjAxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9VbnNhZmVCeXRlU2VxdWVuY2UuamF2YQpAQCAtMCwwICsxLDgzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CisKKy8qKgorICogQSBjaGVhcGVyIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBmb3IgaW50ZXJuYWwgdXNlLiBUaGlzIGNsYXNzIGlzIHVuc3luY2hyb25pemVkLAorICogYW5kIHJldHVybnMgaXRzIGludGVybmFsIGFycmF5IGlmIGl0J3MgdGhlIHJpZ2h0IHNpemUuIFRoaXMgbWFrZXMgU3RyaW5nLmdldEJ5dGVzKCJVVEYtOCIpCisgKiAxMHggZmFzdGVyIHRoYW4gdGhlIGJhc2VsaW5lIG5vbi1mYXN0LXBhdGggaW1wbGVtZW50YXRpb24gaW5zdGVhZCBvZiA4eCBmYXN0ZXIgd2hlbiB1c2luZworICogQnl0ZUFycmF5T3V0cHV0U3RyZWFtLiBXaGVuIEdDIGFuZCB1bmNvbnRlbmRlZCBzeW5jaHJvbml6YXRpb24gYmVjb21lIGNoZWFwLCB3ZSBzaG91bGQgYmUKKyAqIGFibGUgdG8gZ2V0IHJpZCBvZiB0aGlzIGNsYXNzLiBJbiB0aGUgbWVhbnRpbWUsIGlmIHlvdSBuZWVkIHRvIGFkZCBmdXJ0aGVyIEFQSSwgcGxlYXNlIHRyeQorICogdG8ga2VlcCBpdCBwbHVnLWNvbXBhdGlibGUgd2l0aCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gd2l0aCBhbiBleWUgdG8gZnV0dXJlIG9ic29sZXNjZW5jZS4KKyAqCisgKiBAaGlkZQorICovCitwdWJsaWMgY2xhc3MgVW5zYWZlQnl0ZVNlcXVlbmNlIHsKKyAgICBwcml2YXRlIGJ5dGVbXSBieXRlczsKKyAgICBwcml2YXRlIGludCBjb3VudDsKKworICAgIHB1YmxpYyBVbnNhZmVCeXRlU2VxdWVuY2UoaW50IGluaXRpYWxDYXBhY2l0eSkgeworICAgICAgICB0aGlzLmJ5dGVzID0gbmV3IGJ5dGVbaW5pdGlhbENhcGFjaXR5XTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgIHJldHVybiBjb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNb3ZlcyB0aGUgd3JpdGUgcG9pbnRlciBiYWNrIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNlcXVlbmNlLAorICAgICAqIGJ1dCB3aXRob3V0IHJlc2l6aW5nIG9yIHJlYWxsb2NhdGluZyB0aGUgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJld2luZCgpIHsKKyAgICAgICAgY291bnQgPSAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICAgICAgaWYgKGNvdW50ICsgbGVuZ3RoID49IGJ5dGVzLmxlbmd0aCkgeworICAgICAgICAgICAgYnl0ZVtdIG5ld0J5dGVzID0gbmV3IGJ5dGVbKGNvdW50ICsgbGVuZ3RoKSAqIDJdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShieXRlcywgMCwgbmV3Qnl0ZXMsIDAsIGNvdW50KTsKKyAgICAgICAgICAgIGJ5dGVzID0gbmV3Qnl0ZXM7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWZmZXIsIG9mZnNldCwgYnl0ZXMsIGNvdW50LCBsZW5ndGgpOworICAgICAgICBjb3VudCArPSBsZW5ndGg7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHsKKyAgICAgICAgaWYgKGNvdW50ID09IGJ5dGVzLmxlbmd0aCkgeworICAgICAgICAgICAgYnl0ZVtdIG5ld0J5dGVzID0gbmV3IGJ5dGVbY291bnQgKiAyXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnl0ZXMsIDAsIG5ld0J5dGVzLCAwLCBjb3VudCk7CisgICAgICAgICAgICBieXRlcyA9IG5ld0J5dGVzOworICAgICAgICB9CisgICAgICAgIGJ5dGVzW2NvdW50KytdID0gKGJ5dGUpIGI7CisgICAgfQorCisgICAgQEZpbmRCdWdzU3VwcHJlc3NXYXJuaW5ncygiRUlfRVhQT1NFX1JFUCIpCisgICAgcHVibGljIGJ5dGVbXSB0b0J5dGVBcnJheSgpIHsKKyAgICAgICAgaWYgKGNvdW50ID09IGJ5dGVzLmxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIGJ5dGVzOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtjb3VudF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnl0ZXMsIDAsIHJlc3VsdCwgMCwgY291bnQpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoQ2hhcnNldCBjcykgeworICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhieXRlcywgMCwgY291bnQsIGNzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1Vuc2F0aXNmaWVkTGlua0Vycm9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1Vuc2F0aXNmaWVkTGlua0Vycm9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjA1YzI2ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvVW5zYXRpc2ZpZWRMaW5rRXJyb3IuamF2YQpAQCAtMCwwICsxLDQ1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gd2hlbiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gaW52b2tlIGEgbmF0aXZlIGZvciB3aGljaCBhbiBpbXBsZW1lbnRhdGlvbgorICogY291bGQgbm90IGJlIGZvdW5kLgorICovCitwdWJsaWMgY2xhc3MgVW5zYXRpc2ZpZWRMaW5rRXJyb3IgZXh0ZW5kcyBMaW5rYWdlRXJyb3IgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQwMTkzNDMyNDE2MTY4Nzk0MjhMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVW5zYXRpc2ZpZWRMaW5rRXJyb3J9IHRoYXQgaW5jbHVkZXMgdGhlIGN1cnJlbnQKKyAgICAgKiBzdGFjayB0cmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5zYXRpc2ZpZWRMaW5rRXJyb3IoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVW5zYXRpc2ZpZWRMaW5rRXJyb3J9IHdpdGggdGhlIGN1cnJlbnQgc3RhY2sKKyAgICAgKiB0cmFjZSBhbmQgdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBVbnNhdGlzZmllZExpbmtFcnJvcihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1Vuc3VwcG9ydGVkQ2xhc3NWZXJzaW9uRXJyb3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvVW5zdXBwb3J0ZWRDbGFzc1ZlcnNpb25FcnJvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVjNmE2Y2YKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1Vuc3VwcG9ydGVkQ2xhc3NWZXJzaW9uRXJyb3IuamF2YQpAQCAtMCwwICsxLDQ1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gd2hlbiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gbG9hZCBhIGNsYXNzIHdpdGggYSBmb3JtYXQgdmVyc2lvbiB0aGF0IGlzCisgKiBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBWTS4KKyAqLworcHVibGljIGNsYXNzIFVuc3VwcG9ydGVkQ2xhc3NWZXJzaW9uRXJyb3IgZXh0ZW5kcyBDbGFzc0Zvcm1hdEVycm9yIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03MTIzMjc5MjEyODgzNDk3MzczTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFVuc3VwcG9ydGVkQ2xhc3NWZXJzaW9uRXJyb3J9IHRoYXQgaW5jbHVkZXMgdGhlCisgICAgICogY3VycmVudCBzdGFjayB0cmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5zdXBwb3J0ZWRDbGFzc1ZlcnNpb25FcnJvcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBVbnN1cHBvcnRlZENsYXNzVmVyc2lvbkVycm9yfSB3aXRoIHRoZSBjdXJyZW50CisgICAgICogc3RhY2sgdHJhY2UgYW5kIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5zdXBwb3J0ZWRDbGFzc1ZlcnNpb25FcnJvcihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1Vuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1Vuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzFiMWEzZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDcwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZzsKKworLyoqCisgKiBUaHJvd24gd2hlbiBhbiB1bnN1cHBvcnRlZCBvcGVyYXRpb24gaXMgYXR0ZW1wdGVkLgorICovCitwdWJsaWMgY2xhc3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xMjQyNTk5OTc5MDU1MDg0NjczTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufSB0aGF0IGluY2x1ZGVzIHRoZQorICAgICAqIGN1cnJlbnQgc3RhY2sgdHJhY2UuCisgICAgICovCisgICAgcHVibGljIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufSB3aXRoIHRoZSBjdXJyZW50CisgICAgICogc3RhY2sgdHJhY2UgYW5kIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQKKyAgICAgKiBzdGFjayB0cmFjZSwgdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZSBhbmQgdGhlIHNwZWNpZmllZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIG9wdGlvbmFsIGNhdXNlIG9mIHRoaXMgZXhjZXB0aW9uLCBtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259IHdpdGggdGhlIGN1cnJlbnQKKyAgICAgKiBzdGFjayB0cmFjZSBhbmQgdGhlIHNwZWNpZmllZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIG9wdGlvbmFsIGNhdXNlIG9mIHRoaXMgZXhjZXB0aW9uLCBtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKChjYXVzZSA9PSBudWxsID8gbnVsbCA6IGNhdXNlLnRvU3RyaW5nKCkpLCBjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9WTUNsYXNzTG9hZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1ZNQ2xhc3NMb2FkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NjA0MzYwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9WTUNsYXNzTG9hZGVyLmphdmEKQEAgLTAsMCArMSw5MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCitpbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCitjbGFzcyBWTUNsYXNzTG9hZGVyIHsKKworICAgIC8qKgorICAgICAqIEdldCBhIHJlc291cmNlIGZyb20gYSBmaWxlIGluIHRoZSBib290c3RyYXAgY2xhc3MgcGF0aC4KKyAgICAgKgorICAgICAqIEl0IHdvdWxkIGJlIHNpbXBsZXIgdG8ganVzdCB3YWxrIHRocm91Z2ggdGhlIGNsYXNzIHBhdGggZWxlbWVudHMKKyAgICAgKiBvdXJzZWx2ZXMsIGJ1dCB0aGF0IHdvdWxkIHJlcXVpcmUgcmVvcGVuaW5nIEphciBmaWxlcy4KKyAgICAgKgorICAgICAqIFdlIGFzc3VtZSB0aGF0IHRoZSBib290Y2xhc3NwYXRoIGNhbid0IGNoYW5nZSBvbmNlIHRoZSBWTSBoYXMKKyAgICAgKiBzdGFydGVkLiAgVGhpcyBhc3N1bXB0aW9uIHNlZW1zIHRvIGJlIHN1cHBvcnRlZCBieSB0aGUgc3BlYy4KKyAgICAgKi8KKyAgICBzdGF0aWMgVVJMIGdldFJlc291cmNlKFN0cmluZyBuYW1lKSB7CisgICAgICAgIGludCBudW1FbnRyaWVzID0gZ2V0Qm9vdENsYXNzUGF0aFNpemUoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1FbnRyaWVzOyBpKyspIHsKKyAgICAgICAgICAgIFN0cmluZyB1cmxTdHIgPSBnZXRCb290Q2xhc3NQYXRoUmVzb3VyY2UobmFtZSwgaSk7CisgICAgICAgICAgICBpZiAodXJsU3RyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVSTCh1cmxTdHIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtdWUpIHsKKyAgICAgICAgICAgICAgICAgICAgbXVlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgICAgICAgICAvLyB1bmV4cGVjdGVkOyBrZWVwIGdvaW5nCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qCisgICAgICogR2V0IGFuIGVudW1lcmF0aW9uIHdpdGggYWxsIG1hdGNoaW5nIHJlc291cmNlcy4KKyAgICAgKi8KKyAgICBzdGF0aWMgTGlzdDxVUkw+IGdldFJlc291cmNlcyhTdHJpbmcgbmFtZSkgeworICAgICAgICBBcnJheUxpc3Q8VVJMPiBsaXN0ID0gbmV3IEFycmF5TGlzdDxVUkw+KCk7CisgICAgICAgIGludCBudW1FbnRyaWVzID0gZ2V0Qm9vdENsYXNzUGF0aFNpemUoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1FbnRyaWVzOyBpKyspIHsKKyAgICAgICAgICAgIFN0cmluZyB1cmxTdHIgPSBnZXRCb290Q2xhc3NQYXRoUmVzb3VyY2UobmFtZSwgaSk7CisgICAgICAgICAgICBpZiAodXJsU3RyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBsaXN0LmFkZChuZXcgVVJMKHVybFN0cikpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtdWUpIHsKKyAgICAgICAgICAgICAgICAgICAgbXVlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgICAgICAgICAvLyB1bmV4cGVjdGVkOyBrZWVwIGdvaW5nCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBsaXN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIExvYWQgY2xhc3Mgd2l0aCBib290c3RyYXAgY2xhc3MgbG9hZGVyLgorICAgICAqLworICAgIG5hdGl2ZSBzdGF0aWMgQ2xhc3MgbG9hZENsYXNzKFN0cmluZyBuYW1lLCBib29sZWFuIHJlc29sdmUpIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uOworCisgICAgbmF0aXZlIHN0YXRpYyBDbGFzcyBnZXRQcmltaXRpdmVDbGFzcyhjaGFyIHR5cGUpOworCisgICAgbmF0aXZlIHN0YXRpYyBDbGFzcyBkZWZpbmVDbGFzcyhDbGFzc0xvYWRlciBjbCwgU3RyaW5nIG5hbWUsIGJ5dGVbXSBkYXRhLCBpbnQgb2Zmc2V0LCBpbnQgbGVuKQorICAgICAgICAgICAgdGhyb3dzIENsYXNzRm9ybWF0RXJyb3I7CisKKyAgICBuYXRpdmUgc3RhdGljIENsYXNzIGRlZmluZUNsYXNzKENsYXNzTG9hZGVyIGNsLCBieXRlW10gZGF0YSwgaW50IG9mZnNldCwgaW50IGxlbikKKyAgICAgICAgICAgIHRocm93cyBDbGFzc0Zvcm1hdEVycm9yOworCisgICAgbmF0aXZlIHN0YXRpYyBDbGFzcyBmaW5kTG9hZGVkQ2xhc3MoQ2xhc3NMb2FkZXIgY2wsIFN0cmluZyBuYW1lKTsKKworICAgIC8qKgorICAgICAqIEJvb3QgY2xhc3MgcGF0aCBtYW5pcHVsYXRpb24sIGZvciBnZXRSZXNvdXJjZXMoKS4KKyAgICAgKi8KKyAgICBuYXRpdmUgcHJpdmF0ZSBzdGF0aWMgaW50IGdldEJvb3RDbGFzc1BhdGhTaXplKCk7CisgICAgbmF0aXZlIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRCb290Q2xhc3NQYXRoUmVzb3VyY2UoU3RyaW5nIG5hbWUsIGludCBpbmRleCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1ZNVGhyZWFkLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1ZNVGhyZWFkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDFmNmVlMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvVk1UaHJlYWQuamF2YQpAQCAtMCwwICsxLDc3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKK2NsYXNzIFZNVGhyZWFkIHsKKyAgICBUaHJlYWQgdGhyZWFkOworICAgIGludCB2bURhdGE7CisKKyAgICBWTVRocmVhZChUaHJlYWQgdCkgeworICAgICAgICB0aHJlYWQgPSB0OworICAgIH0KKworICAgIG5hdGl2ZSBzdGF0aWMgdm9pZCBjcmVhdGUoVGhyZWFkIHQsIGxvbmcgc3RhY2tTaXplKTsKKworICAgIHN0YXRpYyBuYXRpdmUgVGhyZWFkIGN1cnJlbnRUaHJlYWQoKTsKKyAgICBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gaW50ZXJydXB0ZWQoKTsKKyAgICBzdGF0aWMgbmF0aXZlIHZvaWQgc2xlZXAgKGxvbmcgbXNlYywgaW50IG5zZWMpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbjsKKyAgICBzdGF0aWMgbmF0aXZlIHZvaWQgeWllbGQoKTsKKworICAgIG5hdGl2ZSB2b2lkIGludGVycnVwdCgpOworCisgICAgbmF0aXZlIGJvb2xlYW4gaXNJbnRlcnJ1cHRlZCgpOworCisgICAgLyoqCisgICAgICogIFN0YXJ0cyB0aGUgVk1UaHJlYWQgKGFuZCB0aHVzIHRoZSBKYXZhIFRocmVhZCkgd2l0aCB0aGUgZ2l2ZW4KKyAgICAgKiAgc3RhY2sgc2l6ZS4KKyAgICAgKi8KKyAgICB2b2lkIHN0YXJ0KGxvbmcgc3RhY2tTaXplKSB7CisgICAgICAgIFZNVGhyZWFkLmNyZWF0ZSh0aHJlYWQsIHN0YWNrU2l6ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUXVlcmllcyB3aGV0aGVyIHRoaXMgVGhyZWFkIGhvbGRzIGEgbW9uaXRvciBsb2NrIG9uIHRoZQorICAgICAqIGdpdmVuIG9iamVjdC4KKyAgICAgKi8KKyAgICBuYXRpdmUgYm9vbGVhbiBob2xkc0xvY2soT2JqZWN0IG9iamVjdCk7CisKKyAgICBuYXRpdmUgdm9pZCBzZXRQcmlvcml0eShpbnQgbmV3UHJpb3JpdHkpOworICAgIG5hdGl2ZSBpbnQgZ2V0U3RhdHVzKCk7CisKKyAgICAvKioKKyAgICAgKiBIb2xkcyBhIG1hcHBpbmcgZnJvbSBuYXRpdmUgVGhyZWFkIHN0YXR1c2VzIHRvIEphdmEgb25lLiBSZXF1aXJlZCBmb3IKKyAgICAgKiB0cmFuc2xhdGluZyBiYWNrIHRoZSByZXN1bHQgb2YgZ2V0U3RhdHVzKCkuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIFRocmVhZC5TdGF0ZVtdIFNUQVRFX01BUCA9IG5ldyBUaHJlYWQuU3RhdGVbXSB7CisgICAgICAgIFRocmVhZC5TdGF0ZS5URVJNSU5BVEVELCAgICAgLy8gWk9NQklFCisgICAgICAgIFRocmVhZC5TdGF0ZS5SVU5OQUJMRSwgICAgICAgLy8gUlVOTklORworICAgICAgICBUaHJlYWQuU3RhdGUuVElNRURfV0FJVElORywgIC8vIFRJTUVEX1dBSVQKKyAgICAgICAgVGhyZWFkLlN0YXRlLkJMT0NLRUQsICAgICAgICAvLyBNT05JVE9SCisgICAgICAgIFRocmVhZC5TdGF0ZS5XQUlUSU5HLCAgICAgICAgLy8gV0FJVAorICAgICAgICBUaHJlYWQuU3RhdGUuTkVXLCAgICAgICAgICAgIC8vIElOSVRJQUxJWklORworICAgICAgICBUaHJlYWQuU3RhdGUuTkVXLCAgICAgICAgICAgIC8vIFNUQVJUSU5HCisgICAgICAgIFRocmVhZC5TdGF0ZS5SVU5OQUJMRSwgICAgICAgLy8gTkFUSVZFCisgICAgICAgIFRocmVhZC5TdGF0ZS5XQUlUSU5HLCAgICAgICAgLy8gVk1XQUlUCisgICAgICAgIFRocmVhZC5TdGF0ZS5SVU5OQUJMRSAgICAgICAgLy8gU1VTUEVOREVECisgICAgfTsKKworICAgIC8qKgorICAgICAqIFRlbGwgdGhlIFZNIHRoYXQgdGhlIHRocmVhZCdzIG5hbWUgaGFzIGNoYW5nZWQuICBUaGlzIGlzIHVzZWZ1bCBmb3IKKyAgICAgKiBERE1TLCB3aGljaCB3b3VsZCBvdGhlcndpc2UgYmUgb2JsaXZpb3VzIHRvIFRocmVhZC5zZXROYW1lIGNhbGxzLgorICAgICAqLworICAgIG5hdGl2ZSB2b2lkIG5hbWVDaGFuZ2VkKFN0cmluZyBuZXdOYW1lKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvVmVyaWZ5RXJyb3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvVmVyaWZ5RXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNWJiYWY2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9WZXJpZnlFcnJvci5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisvKioKKyAqIFRocm93biB3aGVuIHRoZSBWTSBub3RpY2VzIHRoYXQgYW4gYXR0ZW1wdCBpcyBtYWRlIHRvIGxvYWQgYQorICogY2xhc3Mgd2hpY2ggZG9lcyBub3QgcGFzcyB0aGUgY2xhc3MgdmVyaWZpY2F0aW9uIHBoYXNlLgorICovCitwdWJsaWMgY2xhc3MgVmVyaWZ5RXJyb3IgZXh0ZW5kcyBMaW5rYWdlRXJyb3IgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzAwMTk2MjM5NjA5ODQ5ODc4NUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBWZXJpZnlFcnJvcn0gdGhhdCBpbmNsdWRlcyB0aGUgY3VycmVudCBzdGFjaworICAgICAqIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyBWZXJpZnlFcnJvcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBWZXJpZnlFcnJvcn0gd2l0aCB0aGUgY3VycmVudCBzdGFjayB0cmFjZSBhbmQgdGhlCisgICAgICogc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFZlcmlmeUVycm9yKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvVmlydHVhbE1hY2hpbmVFcnJvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9WaXJ0dWFsTWFjaGluZUVycm9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2VmMWVlYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvVmlydHVhbE1hY2hpbmVFcnJvci5qYXZhCkBAIC0wLDAgKzEsNDggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nOworCisKKy8qKgorICoge0Bjb2RlIFZpcnR1YWxNYWNoaW5lRXJyb3J9IGlzIHRoZSBzdXBlcmNsYXNzIG9mIGFsbCBlcnJvciBjbGFzc2VzIHRoYXQgb2NjdXIKKyAqIGR1cmluZyB0aGUgb3BlcmF0aW9uIG9mIHRoZSBWTS4KKyAqCisgKiBAc2VlIEVycm9yCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBWaXJ0dWFsTWFjaGluZUVycm9yIGV4dGVuZHMgRXJyb3IgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNDE2MTk4MzkyNjU3MTU2ODY3MEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBWaXJ0dWFsTWFjaGluZUVycm9yfSB0aGF0IGluY2x1ZGVzIHRoZSBjdXJyZW50CisgICAgICogc3RhY2sgdHJhY2UuCisgICAgICovCisgICAgcHVibGljIFZpcnR1YWxNYWNoaW5lRXJyb3IoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVmlydHVhbE1hY2hpbmVFcnJvcn0gd2l0aCB0aGUgY3VycmVudCBzdGFjayB0cmFjZQorICAgICAqIGFuZCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFZpcnR1YWxNYWNoaW5lRXJyb3IoU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Wb2lkLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL1ZvaWQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOWYyNjdhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9Wb2lkLmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmc7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgbGliY29yZS51dGlsLkVtcHR5QXJyYXk7CisKKy8qKgorICogUGxhY2Vob2xkZXIgY2xhc3MgZm9yIHRoZSBKYXZhIGtleXdvcmQge0Bjb2RlIHZvaWR9LgorICoKKyAqIEBzaW5jZSAxLjEKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFZvaWQgeworCisgICAgLyoqCisgICAgICogVGhlIHtAbGluayBDbGFzc30gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcHJpbWl0aXZlIHR5cGUge0Bjb2RlIHZvaWR9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3M8Vm9pZD4gVFlQRSA9IGxvb2t1cFR5cGUoKTsKKyAgICAvLyBOb3RlOiBWb2lkLlRZUEUgY2FuJ3QgYmUgc2V0IHRvICJ2b2lkLmNsYXNzIiwgc2luY2UgKnRoYXQqIGlzCisgICAgLy8gZGVmaW5lZCB0byBiZSAiamF2YS5sYW5nLlZvaWQuVFlQRSI7CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIHN0YXRpYyBDbGFzczxWb2lkPiBsb29rdXBUeXBlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgTWV0aG9kIG1ldGhvZCA9IFJ1bm5hYmxlLmNsYXNzLmdldE1ldGhvZCgicnVuIiwgRW1wdHlBcnJheS5DTEFTUyk7CisgICAgICAgICAgICByZXR1cm4gKENsYXNzPFZvaWQ+KSBtZXRob2QuZ2V0UmV0dXJuVHlwZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBWb2lkKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvYW5ub3RhdGlvbi9Bbm5vdGF0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL2Fubm90YXRpb24vQW5ub3RhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI5MjIwOTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL2Fubm90YXRpb24vQW5ub3RhdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTI1IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzCisgKiB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiBUaGUgQVNGCisgKiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVAorICogV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlCisgKiBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgorICogdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcuYW5ub3RhdGlvbjsKKworLyoqCisgKiBEZWZpbmVzIHRoZSBpbnRlcmZhY2UgaW1wbGVtZW50ZWQgYnkgYWxsIGFubm90YXRpb25zLiBOb3RlIHRoYXQgdGhlIGludGVyZmFjZQorICogaXRzZWxmIGlzIDxpPm5vdDwvaT4gYW4gYW5ub3RhdGlvbiwgYW5kIG5laXRoZXIgaXMgYW4gaW50ZXJmYWNlIHRoYXQgc2ltcGx5CisgKiBleHRlbmRzIHRoaXMgb25lLiBPbmx5IHRoZSBjb21waWxlciBpcyBhYmxlIHRvIGNyZWF0ZSBwcm9wZXIgYW5ub3RhdGlvbgorICogdHlwZXMuCisgKgorICogQHNpbmNlIDEuNQorICovCitwdWJsaWMgaW50ZXJmYWNlIEFubm90YXRpb24geworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdHlwZSBvZiB0aGlzIGFubm90YXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEge0Bjb2RlIENsYXNzfSBpbnN0YW5jZSByZXByZXNlbnRpbmcgdGhlIGFubm90YXRpb24gdHlwZS4KKyAgICAgKi8KKyAgICBDbGFzczw/IGV4dGVuZHMgQW5ub3RhdGlvbj4gYW5ub3RhdGlvblR5cGUoKTsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciBvciBub3QgdGhpcyBhbm5vdGF0aW9uIGlzIGVxdWl2YWxlbnQgdG8gdGhlIGFubm90YXRpb24KKyAgICAgKiBwYXNzZWQuIFRoaXMgaXMgZGV0ZXJtaW5lZCBhY2NvcmRpbmcgdG8gdGhlIGZvbGxvd2luZyBydWxlczoKKyAgICAgKgorICAgICAqIDx1bD4KKyAgICAgKiAgICAgPGxpPgorICAgICAqICAgICAgICAgVHdvIGFubm90YXRpb25zIHtAY29kZSB4fSBhbmQge0Bjb2RlIHl9IGFyZSBlcXVhbCBpZiBhbmQgb25seSBpZgorICAgICAqICAgICAgICAgdGhleSBhcmUgbWVtYmVycyBvZiB0aGUgc2FtZSBhbm5vdGF0aW9uIHR5cGUgYW5kIGFsbCB0aGUgbWVtYmVyCisgICAgICogICAgICAgICB2YWx1ZXMgb2Yge0Bjb2RlIHh9IGFyZSBlcXVhbCB0byB0aGUgY29ycmVzcG9uZGluZyBtZW1iZXIgdmFsdWVzCisgICAgICogICAgICAgICBvZiB7QGNvZGUgeX0uCisgICAgICogICAgIDwvbGk+CisgICAgICogICAgIDxsaT4KKyAgICAgKiAgICAgICAgIFRoZSBlcXVhbGl0eSBvZiBwcmltaXRpdmUgbWVtYmVyIHZhbHVlcyB7QGNvZGUgeH0gYW5kIHtAY29kZSB5fQorICAgICAqICAgICAgICAgaXMgZGV0ZXJtaW5lZCAoaW4gYSB3YXkgc2ltaWxhciB0bykgdXNpbmcgdGhlIGNvcnJlc3BvbmRpbmcKKyAgICAgKiAgICAgICAgIHdyYXBwZXIgY2xhc3Nlcy4gRm9yIGV4YW1wbGUsCisgICAgICogICAgICAgICB7QGNvZGUgSW50ZWdlci52YWx1ZU9mKHgpLmVxdWFscyhJbnRlZ2VyLnZhbHVlT2YoeSl9IGlzIHVzZWQgZm9yCisgICAgICogICAgICAgICB7QGNvZGUgaW50fSB2YWx1ZXMuIE5vdGU6IFRoZSBiZWhhdmlvciBpcyBpZGVudGljYWwgdG8gdGhlCisgICAgICogICAgICAgICB7QGNvZGUgPT19IG9wZXJhdG9yIGZvciBhbGwgYnV0IHRoZSBmbG9hdGluZyBwb2ludCB0eXBlLCBzbyB0aGUKKyAgICAgKiAgICAgICAgIGltcGxlbWVudGF0aW9uIG1heSBhcyB3ZWxsIHVzZSB7QGNvZGUgPT19IGluIHRoZXNlIGNhc2VzIGZvcgorICAgICAqICAgICAgICAgcGVyZm9ybWFuY2UgcmVhc29ucy4gT25seSBmb3IgdGhlIHtAY29kZSBmbG9hdH0gYW5kIHtAY29kZSBkb3VibGV9CisgICAgICogICAgICAgICB0eXBlcyB0aGUgcmVzdWx0IHdpbGwgYmUgc2xpZ2h0bHkgZGlmZmVyZW50OiB7QGNvZGUgTmFOfSBpcyBlcXVhbAorICAgICAqICAgICAgICAgdG8ge0Bjb2RlIE5hTn0sIGFuZCB7QGNvZGUgLTAuMH0gaXMgZXF1YWwgdG8ge0Bjb2RlIDAuMH0sIGJvdGggb2YKKyAgICAgKiAgICAgICAgIHdoaWNoIGlzIG5vcm1hbGx5IG5vdCB0aGUgY2FzZS4KKyAgICAgKiAgICAgPC9saT4KKyAgICAgKiAgICAgPGxpPgorICAgICAqICAgICAgICAgVGhlIGVxdWFsaXR5IG9mIHR3byBhcnJheSBtZW1iZXIgdmFsdWVzIHtAY29kZSB4fSBhbmQge0Bjb2RlIHl9CisgICAgICogICAgICAgICBpcyBkZXRlcm1pbmVkIHVzaW5nIHRoZSBjb3JyZXNwb25kaW5nIHtAY29kZSBlcXVhbHMoeCwgeSl9CisgICAgICogICAgICAgICBoZWxwZXIgZnVuY3Rpb24gaW4ge0BsaW5rIGphdmEudXRpbC5BcnJheXN9LgorICAgICAqICAgICA8L2xpPgorICAgICAqICAgICA8bGk+CisgICAgICogICAgICAgICBUaGUgaGFzaCBjb2RlIGZvciBhbGwgb3RoZXIgbWVtYmVyIHZhbHVlcyBpcyBkZXRlcm1pbmVkIGJ5IHNpbXBseQorICAgICAqICAgICAgICAgY2FsbGluZyB0aGVpciB7QGNvZGUgZXF1YWxzKCl9IG1ldGhvZC4KKyAgICAgKiAgICAgPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgVGhlIG9iamVjdCB0byBjb21wYXJlIHRvLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIG9ian0gaXMgZXF1YWwgdG8gdGhpcyBhbm5vdGF0aW9uLAorICAgICAqICAgICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgb2YgdGhpcyBhbm5vdGF0aW9uLiBUaGUgaGFzaCBjb2RlIGlzIGRldGVybWluZWQKKyAgICAgKiBhY2NvcmRpbmcgdG8gdGhlIGZvbGxvd2luZyBydWxlczoKKyAgICAgKgorICAgICAqIDx1bD4KKyAgICAgKiAgICAgPGxpPgorICAgICAqICAgICAgICAgVGhlIGhhc2ggY29kZSBvZiBhbiBhbm5vdGF0aW9uIGlzIHRoZSBzdW0gb2YgdGhlIGhhc2ggY29kZXMgb2YKKyAgICAgKiAgICAgICAgIGl0cyBhbm5vdGF0aW9uIG1lbWJlcnMuCisgICAgICogICAgIDwvbGk+CisgICAgICogICAgIDxsaT4KKyAgICAgKiAgICAgICAgIFRoZSBoYXNoIGNvZGUgb2YgYW4gYW5ub3RhdGlvbiBtZW1iZXIgaXMgY2FsY3VsYXRlZCBhcyB7QGNvZGUKKyAgICAgKiAgICAgICAgICgweDdmICogbi5oYXNoQ29kZSgpKSBeIHYuaGFzaENvZGUoKSl9LCB3aGVyZSB7QGNvZGUgbn0gaXMgdGhlCisgICAgICogICAgICAgICBuYW1lIG9mIHRoZSBtZW1iZXIgKGFzIGEge0Bjb2RlIFN0cmluZ30pIGFuZCB7QGNvZGUgdn0gaXRzIHZhbHVlLgorICAgICAqICAgICA8L2xpPgorICAgICAqICAgICA8bGk+CisgICAgICogICAgICAgICBUaGUgaGFzaCBjb2RlIGZvciBhIHByaW1pdGl2ZSBtZW1iZXIgdmFsdWUgaXMgZGV0ZXJtaW5lZCB1c2luZworICAgICAqICAgICAgICAgdGhlIGNvcnJlc3BvbmRpbmcgd3JhcHBlciB0eXBlLiBGb3IgZXhhbXBsZSwge0Bjb2RlCisgICAgICogICAgICAgICBJbnRlZ2VyLnZhbHVlT2YodikuaGFzaENvZGUoKX0gaXMgdXNlZCBmb3IgYW4ge0Bjb2RlIGludH0gdmFsdWUKKyAgICAgKiAgICAgICAgIHtAY29kZSB2fS4KKyAgICAgKiAgICAgPC9saT4KKyAgICAgKiAgICAgPGxpPgorICAgICAqICAgICAgICAgVGhlIGhhc2ggY29kZSBmb3IgYW4gYXJyYXkgbWVtYmVyIHZhbHVlIHtAY29kZSB2fSBpcyBkZXRlcm1pbmVkCisgICAgICogICAgICAgICB1c2luZyB0aGUgY29ycmVzcG9uZGluZyB7QGNvZGUgaGFzaENvZGUodil9IGhlbHBlciBmdW5jdGlvbiBpbgorICAgICAqICAgICAgICAge0BsaW5rIGphdmEudXRpbC5BcnJheXN9LgorICAgICAqICAgICA8L2xpPgorICAgICAqICAgICA8bGk+CisgICAgICogICAgICAgICBUaGUgaGFzaCBjb2RlIGZvciBhbGwgb3RoZXIgbWVtYmVyIHZhbHVlcyBpcyBkZXRlcm1pbmVkIGJ5IHNpbXBseQorICAgICAqICAgICAgICAgY2FsbGluZyB0aGVpciB7QGNvZGUgaGFzaENvZGV9IG1ldGhvZC4KKyAgICAgKiAgICAgPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlLgorICAgICAqLworICAgIGludCBoYXNoQ29kZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBTdHJpbmd9IHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgYW5ub3RhdGlvbi4gSXQgaXMgbm90CisgICAgICogc3RyaWN0bHkgZGVmaW5lZCB3aGF0IHRoZSByZXByZXNlbnRhdGlvbiBoYXMgdG8gbG9vayBsaWtlLCBidXQgaXQgdXN1YWxseQorICAgICAqIGNvbnNpc3RzIG9mIHRoZSBuYW1lIG9mIHRoZSBhbm5vdGF0aW9uLCBwcmVjZWRlZCBieSBhICJAIi4gSWYgdGhlCisgICAgICogYW5ub3RhdGlvbiBjb250YWlucyBmaWVsZCBtZW1iZXJzLCB0aGVpciBuYW1lcyBhbmQgdmFsdWVzIGFyZSBhbHNvCisgICAgICogaW5jbHVkZWQgaW4gdGhlIHJlc3VsdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBTdHJpbmd9IHRoYXQgcmVwcmVzZW50cyB0aGlzIGFubm90YXRpb24uCisgICAgICovCisgICAgU3RyaW5nIHRvU3RyaW5nKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL2Fubm90YXRpb24vQW5ub3RhdGlvbkZvcm1hdEVycm9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL2Fubm90YXRpb24vQW5ub3RhdGlvbkZvcm1hdEVycm9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTBhYzQzMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvYW5ub3RhdGlvbi9Bbm5vdGF0aW9uRm9ybWF0RXJyb3IuamF2YQpAQCAtMCwwICsxLDY2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzCisgKiB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiBUaGUgQVNGCisgKiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVAorICogV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlCisgKiBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgorICogdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcuYW5ub3RhdGlvbjsKKworLyoqCisgKiBJbmRpY2F0ZXMgdGhhdCBhbiBhbm5vdGF0aW9uIGluIHRoZSBiaW5hcnkgcmVwcmVzZW50YXRpb24gb2YgYSBjbGFzcyBpcworICogc3ludGFjdGljYWxseSBpbmNvcnJlY3QgYW5kIHRoZSBhbm5vdGF0aW9uIHBhcnNlciBpcyB1bmFibGUgdG8gcHJvY2VzcyBpdC4KKyAqIFRoaXMgZXhjZXB0aW9uIGlzIHVubGlrZWx5IHRvIGV2ZXIgb2NjdXIsIGdpdmVuIHRoYXQgdGhlIGNvZGUgaGFzIGJlZW4KKyAqIGNvbXBpbGVkIGJ5IGFuIG9yZGluYXJ5IEphdmEgY29tcGlsZXIuCisgKgorICogQHNpbmNlIDEuNQorICovCitwdWJsaWMgY2xhc3MgQW5ub3RhdGlvbkZvcm1hdEVycm9yIGV4dGVuZHMgRXJyb3IgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQyNTY3MDE1NjIzMzM2Njk4OTJMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBpbnN0YW5jZSB3aXRoIHRoZSBtZXNzYWdlIHByb3ZpZGVkLgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWxzIG9mIHRoZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgQW5ub3RhdGlvbkZvcm1hdEVycm9yKFN0cmluZyBtZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gaW5zdGFuY2Ugd2l0aCBhIG1lc3NhZ2UgYW5kIGEgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbHMgb2YgdGhlIGVycm9yLgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGNhdXNlIG9mIHRoZSBlcnJvciBvciB7QGNvZGUgbnVsbH0gaWYgbm9uZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQW5ub3RhdGlvbkZvcm1hdEVycm9yKFN0cmluZyBtZXNzYWdlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gaW5zdGFuY2Ugd2l0aCBhIGNhdXNlLiBJZiB0aGUgY2F1c2UgaXMgbm90CisgICAgICoge0Bjb2RlIG51bGx9LCB0aGVuIHtAY29kZSBjYXVzZS50b1N0cmluZygpfSBpcyB1c2VkIGFzIHRoZQorICAgICAqIGVycm9yJ3MgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGNhdXNlIG9mIHRoZSBlcnJvciBvciB7QGNvZGUgbnVsbH0gaWYgbm9uZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQW5ub3RhdGlvbkZvcm1hdEVycm9yKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSA9PSBudWxsID8gbnVsbCA6IGNhdXNlLnRvU3RyaW5nKCksIGNhdXNlKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvYW5ub3RhdGlvbi9Bbm5vdGF0aW9uVHlwZU1pc21hdGNoRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL2Fubm90YXRpb24vQW5ub3RhdGlvblR5cGVNaXNtYXRjaEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjNjdhMmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL2Fubm90YXRpb24vQW5ub3RhdGlvblR5cGVNaXNtYXRjaEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoIHRoaXMKKyAqIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuIFRoZSBBU0YKKyAqIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUCisgKiBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUKKyAqIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCisgKiB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZy5hbm5vdGF0aW9uOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworCisvKioKKyAqIEluZGljYXRlcyB0aGF0IGFuIGFubm90YXRpb24gdHlwZSBoYXMgY2hhbmdlZCBzaW5jZSBpdCB3YXMgY29tcGlsZWQgb3IKKyAqIHNlcmlhbGl6ZWQuCisgKgorICogQHNpbmNlIDEuNQorICovCitwdWJsaWMgY2xhc3MgQW5ub3RhdGlvblR5cGVNaXNtYXRjaEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODEyNTkyNTM1NTc2NTU3MDE5MUw7CisKKyAgICBwcml2YXRlIE1ldGhvZCBlbGVtZW50OworCisgICAgcHJpdmF0ZSBTdHJpbmcgZm91bmRUeXBlOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBpbnN0YW5jZSBmb3IgdGhlIGdpdmVuIHR5cGUgZWxlbWVudCBhbmQgdGhlIHR5cGUgZm91bmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZWxlbWVudAorICAgICAqICAgICAgICAgICAgdGhlIGFubm90YXRpb24gdHlwZSBlbGVtZW50LgorICAgICAqIEBwYXJhbSBmb3VuZFR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnZhbGlkIHR5cGUgdGhhdCB3YXMgZm91bmQuIFRoaXMgaXMgYWN0dWFsbHkgdGhlIHRleHR1YWwKKyAgICAgKiAgICAgICAgICAgIHR5cGUgZGVzY3JpcHRpb24gZm91bmQgaW4gdGhlIGJpbmFyeSBjbGFzcyByZXByZXNlbnRhdGlvbiwKKyAgICAgKiAgICAgICAgICAgIHNvIGl0IG1heSBub3QgYmUgaHVtYW4tcmVhZGFibGUuCisgICAgICovCisgICAgcHVibGljIEFubm90YXRpb25UeXBlTWlzbWF0Y2hFeGNlcHRpb24oTWV0aG9kIGVsZW1lbnQsIFN0cmluZyBmb3VuZFR5cGUpIHsKKyAgICAgICAgc3VwZXIoIlRoZSBhbm5vdGF0aW9uIGVsZW1lbnQgIiArIGVsZW1lbnQgKyAiIGRvZXNuJ3QgbWF0Y2ggdGhlIHR5cGUgIiArIGZvdW5kVHlwZSk7CisgICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7CisgICAgICAgIHRoaXMuZm91bmRUeXBlID0gZm91bmRUeXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1ldGhvZCBvYmplY3QgZm9yIHRoZSBpbnZhbGlkIHR5cGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0BsaW5rIE1ldGhvZH0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIE1ldGhvZCBlbGVtZW50KCkgeworICAgICAgICByZXR1cm4gZWxlbWVudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbnZhbGlkIHR5cGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIGludmFsaWQgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGZvdW5kVHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIGZvdW5kVHlwZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL2Fubm90YXRpb24vRG9jdW1lbnRlZC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9hbm5vdGF0aW9uL0RvY3VtZW50ZWQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NjdmMjk0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9hbm5vdGF0aW9uL0RvY3VtZW50ZWQuamF2YQpAQCAtMCwwICsxLDMwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzCisgKiB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiBUaGUgQVNGCisgKiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVAorICogV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlCisgKiBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgorICogdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcuYW5ub3RhdGlvbjsKKworLyoqCisgKiBEZWZpbmVzIGEgbWV0YS1hbm5vdGF0aW9uIGZvciBpbmRpY2F0aW5nIHRoYXQgYW4gYW5ub3RhdGlvbiBpcyBkb2N1bWVudGVkIGFuZAorICogY29uc2lkZXJlZCBwYXJ0IG9mIHRoZSBwdWJsaWMgQVBJLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqLworQERvY3VtZW50ZWQKK0BSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCitAVGFyZ2V0KEVsZW1lbnRUeXBlLkFOTk9UQVRJT05fVFlQRSkKK3B1YmxpYyBAaW50ZXJmYWNlIERvY3VtZW50ZWQgeworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9hbm5vdGF0aW9uL0VsZW1lbnRUeXBlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL2Fubm90YXRpb24vRWxlbWVudFR5cGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOWJlNTlmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9hbm5vdGF0aW9uL0VsZW1lbnRUeXBlLmphdmEKQEAgLTAsMCArMSw2MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGggdGhpcworICogd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gVGhlIEFTRgorICogbGljZW5zZXMgdGhpcyBmaWxlIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQKKyAqIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZQorICogTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKKyAqIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nLmFubm90YXRpb247CisKKy8qKgorICogRGVmaW5lcyBhbiBlbnVtZXJhdGlvbiBmb3IgSmF2YSBwcm9ncmFtIGVsZW1lbnRzLiBJdCBpcyB1c2VkIGluIGNvbmp1bmN0aW9uCisgKiB3aXRoIHRoZSB7QGxpbmsgVGFyZ2V0fSBtZXRhLWFubm90YXRpb24gdG8gcmVzdHJpY3QgdGhlIHVzZSBvZiBhbiBhbm5vdGF0aW9uCisgKiB0byBjZXJ0YWluIHByb2dyYW0gZWxlbWVudHMuCisgKgorICogQHNpbmNlIDEuNQorICovCitwdWJsaWMgZW51bSBFbGVtZW50VHlwZSB7CisgICAgLyoqCisgICAgICogQ2xhc3MsIGludGVyZmFjZSBvciBlbnVtIGRlY2xhcmF0aW9uLgorICAgICAqLworICAgIFRZUEUsCisgICAgLyoqCisgICAgICogRmllbGQgZGVjbGFyYXRpb24uCisgICAgICovCisgICAgRklFTEQsCisgICAgLyoqCisgICAgICogTWV0aG9kIGRlY2xhcmF0aW9uLgorICAgICAqLworICAgIE1FVEhPRCwKKyAgICAvKioKKyAgICAgKiBQYXJhbWV0ZXIgZGVjbGFyYXRpb24uCisgICAgICovCisgICAgUEFSQU1FVEVSLAorICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIGRlY2xhcmF0aW9uLgorICAgICAqLworICAgIENPTlNUUlVDVE9SLAorICAgIC8qKgorICAgICAqIExvY2FsIHZhcmlhYmxlIGRlY2xhcmF0aW9uLgorICAgICAqLworICAgIExPQ0FMX1ZBUklBQkxFLAorICAgIC8qKgorICAgICAqIEFubm90YXRpb24gdHlwZSBkZWNsYXJhdGlvbi4KKyAgICAgKi8KKyAgICBBTk5PVEFUSU9OX1RZUEUsCisgICAgLyoqCisgICAgICogUGFja2FnZSBkZWNsYXJhdGlvbi4KKyAgICAgKi8KKyAgICBQQUNLQUdFCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL2Fubm90YXRpb24vSW5jb21wbGV0ZUFubm90YXRpb25FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvYW5ub3RhdGlvbi9JbmNvbXBsZXRlQW5ub3RhdGlvbkV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBmYTdiM2EKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL2Fubm90YXRpb24vSW5jb21wbGV0ZUFubm90YXRpb25FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDY5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzCisgKiB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiBUaGUgQVNGCisgKiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVAorICogV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlCisgKiBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgorICogdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcuYW5ub3RhdGlvbjsKKworLyoqCisgKiBJbmRpY2F0ZXMgdGhhdCBhbiBlbGVtZW50IG9mIGFuIGFubm90YXRpb24gdHlwZSB3YXMgYWNjZXNzZWQgdGhhdCB3YXMgYWRkZWQKKyAqIGFmdGVyIHRoZSB0eXBlIHdhcyBjb21waWxlZCBvciBzZXJpYWxpemVkLiBUaGlzIGRvZXMgbm90IGFwcGx5IHRvIG5ldworICogZWxlbWVudHMgdGhhdCBoYXZlIGRlZmF1bHQgdmFsdWVzLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqLworcHVibGljIGNsYXNzIEluY29tcGxldGVBbm5vdGF0aW9uRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA4NDQ1MDk3NDAyNzQxODExOTEyTDsKKworICAgIHByaXZhdGUgQ2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+IGFubm90YXRpb25UeXBlOworCisgICAgcHJpdmF0ZSBTdHJpbmcgZWxlbWVudE5hbWU7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIGluc3RhbmNlIHdpdGggdGhlIGluY29tcGxldGUgYW5ub3RhdGlvbiB0eXBlIGFuZCB0aGUgbmFtZQorICAgICAqIG9mIHRoZSBlbGVtZW50IHRoYXQncyBtaXNzaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIGFubm90YXRpb25UeXBlCisgICAgICogICAgICAgICAgICB0aGUgYW5ub3RhdGlvbiB0eXBlLgorICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGluY29tcGxldGUgZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5jb21wbGV0ZUFubm90YXRpb25FeGNlcHRpb24oQ2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+IGFubm90YXRpb25UeXBlLAorICAgICAgICAgICAgU3RyaW5nIGVsZW1lbnROYW1lKSB7CisgICAgICAgIHN1cGVyKCJUaGUgZWxlbWVudCAiICsgZWxlbWVudE5hbWUgKyAiIGlzIG5vdCBjb21wbGV0ZSBmb3IgdGhlIGFubm90YXRpb24gIiArCisgICAgICAgICAgICAgICAgYW5ub3RhdGlvblR5cGUuZ2V0TmFtZSgpKTsKKyAgICAgICAgdGhpcy5hbm5vdGF0aW9uVHlwZSA9IGFubm90YXRpb25UeXBlOworICAgICAgICB0aGlzLmVsZW1lbnROYW1lID0gZWxlbWVudE5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYW5ub3RhdGlvbiB0eXBlLgorICAgICAqCisgICAgICogQHJldHVybiBhIENsYXNzIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBDbGFzczw/IGV4dGVuZHMgQW5ub3RhdGlvbj4gYW5ub3RhdGlvblR5cGUoKSB7CisgICAgICAgIHJldHVybiBhbm5vdGF0aW9uVHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmNvbXBsZXRlIGVsZW1lbnQncyBuYW1lLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGVsZW1lbnROYW1lKCkgeworICAgICAgICByZXR1cm4gZWxlbWVudE5hbWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9hbm5vdGF0aW9uL0luaGVyaXRlZC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9hbm5vdGF0aW9uL0luaGVyaXRlZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM1MGY4MDQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL2Fubm90YXRpb24vSW5oZXJpdGVkLmphdmEKQEAgLTAsMCArMSwzMCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGggdGhpcworICogd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gVGhlIEFTRgorICogbGljZW5zZXMgdGhpcyBmaWxlIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQKKyAqIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZQorICogTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKKyAqIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nLmFubm90YXRpb247CisKKy8qKgorICogRGVmaW5lcyBhIG1ldGEtYW5ub3RhdGlvbiBmb3IgaW5kaWNhdGluZyB0aGF0IGFuIGFubm90YXRpb24gaXMgYXV0b21hdGljYWxseQorICogaW5oZXJpdGVkLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqLworQERvY3VtZW50ZWQKK0BSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCitAVGFyZ2V0KEVsZW1lbnRUeXBlLkFOTk9UQVRJT05fVFlQRSkKK3B1YmxpYyBAaW50ZXJmYWNlIEluaGVyaXRlZCB7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL2Fubm90YXRpb24vUmV0ZW50aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL2Fubm90YXRpb24vUmV0ZW50aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTJhNWM0ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvYW5ub3RhdGlvbi9SZXRlbnRpb24uamF2YQpAQCAtMCwwICsxLDMyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzCisgKiB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiBUaGUgQVNGCisgKiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVAorICogV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlCisgKiBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgorICogdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcuYW5ub3RhdGlvbjsKKworLyoqCisgKiBEZWZpbmVzIGEgbWV0YS1hbm5vdGF0aW9uIGZvciBkZXRlcm1pbmluZyB0aGUgc2NvcGUgb2YgcmV0ZW50aW9uIGZvciBhbgorICogYW5ub3RhdGlvbi4gSWYgdGhlIHJldGVudGlvbiBhbm5vdGF0aW9uIGlzIG5vdCBzZXQge0Bjb2RlCisgKiBSZXRlbnRpb25Qb2xpY3kuQ0xBU1N9IGlzIHVzZWQgYXMgZGVmYXVsdCByZXRlbnRpb24uCisgKgorICogQHNpbmNlIDEuNQorICovCitARG9jdW1lbnRlZAorQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKK0BUYXJnZXQoRWxlbWVudFR5cGUuQU5OT1RBVElPTl9UWVBFKQorcHVibGljIEBpbnRlcmZhY2UgUmV0ZW50aW9uIHsKKyAgICBSZXRlbnRpb25Qb2xpY3kgdmFsdWUoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvYW5ub3RhdGlvbi9SZXRlbnRpb25Qb2xpY3kuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvYW5ub3RhdGlvbi9SZXRlbnRpb25Qb2xpY3kuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZGE1ODk4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9hbm5vdGF0aW9uL1JldGVudGlvblBvbGljeS5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoIHRoaXMKKyAqIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuIFRoZSBBU0YKKyAqIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUCisgKiBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUKKyAqIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCisgKiB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZy5hbm5vdGF0aW9uOworCisvKioKKyAqIERlZmluZXMgYW4gZW51bWVyYXRpb24gZm9yIGFubm90YXRpb24gcmV0ZW50aW9uIHBvbGljaWVzLiBVc2VkIGluIGNvbmp1bmN0aW9uCisgKiB3aXRoIHRoZSB7QGxpbmsgUmV0ZW50aW9ufSBhbm5vdGF0aW9uIHRvIHNwZWNpZnkgYW4gYW5ub3RhdGlvbidzIHRpbWUtdG8tbGl2ZQorICogaW4gdGhlIG92ZXJhbGwgZGV2ZWxvcG1lbnQgbGlmZSBjeWNsZS4KKyAqCisgKiBAc2luY2UgMS41CisgKi8KK3B1YmxpYyBlbnVtIFJldGVudGlvblBvbGljeSB7CisgICAgLyoqCisgICAgICogQW5ub3RhdGlvbiBpcyBvbmx5IGF2YWlsYWJsZSBpbiB0aGUgc291cmNlIGNvZGUuCisgICAgICovCisgICAgU09VUkNFLAorICAgIC8qKgorICAgICAqIEFubm90YXRpb24gaXMgYXZhaWxhYmxlIGluIHRoZSBzb3VyY2UgY29kZSBhbmQgaW4gdGhlIGNsYXNzIGZpbGUsIGJ1dCBub3QKKyAgICAgKiBhdCBydW50aW1lLiBUaGlzIGlzIHRoZSBkZWZhdWx0IHBvbGljeS4KKyAgICAgKi8KKyAgICBDTEFTUywKKyAgICAvKioKKyAgICAgKiBBbm5vdGF0aW9uIGlzIGF2YWlsYWJsZSBpbiB0aGUgc291cmNlIGNvZGUsIHRoZSBjbGFzcyBmaWxlIGFuZCBpcworICAgICAqIGF2YWlsYWJsZSBhdCBydW50aW1lLgorICAgICAqLworICAgIFJVTlRJTUUKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvYW5ub3RhdGlvbi9UYXJnZXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvYW5ub3RhdGlvbi9UYXJnZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NDE0ZTQ3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9hbm5vdGF0aW9uL1RhcmdldC5qYXZhCkBAIC0wLDAgKzEsMzEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoIHRoaXMKKyAqIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuIFRoZSBBU0YKKyAqIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUCisgKiBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUKKyAqIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCisgKiB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZy5hbm5vdGF0aW9uOworCisvKioKKyAqIERlZmluZXMgYSBtZXRhLWFubm90YXRpb24gZm9yIGRldGVybWluaW5nIHdoYXQge0BsaW5rIEVsZW1lbnRUeXBlfXMgYW4KKyAqIGFubm90YXRpb24gY2FuIGJlIGFwcGxpZWQgdG8uCisgKgorICogQHNpbmNlIDEuNQorICovCitARG9jdW1lbnRlZAorQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKK0BUYXJnZXQoRWxlbWVudFR5cGUuQU5OT1RBVElPTl9UWVBFKQorcHVibGljIEBpbnRlcmZhY2UgVGFyZ2V0IHsKKyAgICBFbGVtZW50VHlwZVtdIHZhbHVlKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZi9GaW5hbGl6ZXJSZWZlcmVuY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmL0ZpbmFsaXplclJlZmVyZW5jZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFhZGYxZjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZi9GaW5hbGl6ZXJSZWZlcmVuY2UuamF2YQpAQCAtMCwwICsxLDEwNyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nLnJlZjsKKworLyoqCisgKiBAaGlkZQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRmluYWxpemVyUmVmZXJlbmNlPFQ+IGV4dGVuZHMgUmVmZXJlbmNlPFQ+IHsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFJlZmVyZW5jZVF1ZXVlPE9iamVjdD4gcXVldWUgPSBuZXcgUmVmZXJlbmNlUXVldWU8T2JqZWN0PigpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgRmluYWxpemVyUmVmZXJlbmNlIGhlYWQgPSBudWxsOworCisgICAgcHJpdmF0ZSBUIHpvbWJpZTsKKworICAgIHByaXZhdGUgRmluYWxpemVyUmVmZXJlbmNlIHByZXY7CisKKyAgICBwcml2YXRlIEZpbmFsaXplclJlZmVyZW5jZSBuZXh0OworCisgICAgcHVibGljIEZpbmFsaXplclJlZmVyZW5jZShUIHIsIFJlZmVyZW5jZVF1ZXVlPD8gc3VwZXIgVD4gcSkgeworICAgICAgICBzdXBlcihyLCBxKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgVCBnZXQoKSB7CisgICAgICAgIHJldHVybiB6b21iaWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgIHpvbWJpZSA9IG51bGw7CisgICAgfQorCisgICAgc3RhdGljIHZvaWQgYWRkKE9iamVjdCByZWZlcmVudCkgeworICAgICAgICBGaW5hbGl6ZXJSZWZlcmVuY2U8Pz4gcmVmZXJlbmNlID0gbmV3IEZpbmFsaXplclJlZmVyZW5jZTxPYmplY3Q+KHJlZmVyZW50LCBxdWV1ZSk7CisgICAgICAgIHN5bmNocm9uaXplZCAoRmluYWxpemVyUmVmZXJlbmNlLmNsYXNzKSB7CisgICAgICAgICAgICByZWZlcmVuY2UucHJldiA9IG51bGw7CisgICAgICAgICAgICByZWZlcmVuY2UubmV4dCA9IGhlYWQ7CisgICAgICAgICAgICBpZiAoaGVhZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaGVhZC5wcmV2ID0gcmVmZXJlbmNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaGVhZCA9IHJlZmVyZW5jZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCByZW1vdmUoRmluYWxpemVyUmVmZXJlbmNlIHJlZmVyZW5jZSkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKEZpbmFsaXplclJlZmVyZW5jZS5jbGFzcykgeworICAgICAgICAgICAgRmluYWxpemVyUmVmZXJlbmNlIG5leHQgPSByZWZlcmVuY2UubmV4dDsKKyAgICAgICAgICAgIEZpbmFsaXplclJlZmVyZW5jZSBwcmV2ID0gcmVmZXJlbmNlLnByZXY7CisgICAgICAgICAgICByZWZlcmVuY2UubmV4dCA9IG51bGw7CisgICAgICAgICAgICByZWZlcmVuY2UucHJldiA9IG51bGw7CisgICAgICAgICAgICBpZiAocHJldiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcHJldi5uZXh0ID0gbmV4dDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaGVhZCA9IG5leHQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobmV4dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgbmV4dC5wcmV2ID0gcHJldjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgb25jZSBhbGwgY3VycmVudGx5LWVucXVldWVkIHJlZmVyZW5jZXMgaGF2ZSBiZWVuIGZpbmFsaXplZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmluYWxpemVBbGxFbnF1ZXVlZCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIFNlbnRpbmVsIHNlbnRpbmVsID0gbmV3IFNlbnRpbmVsKCk7CisgICAgICAgIEZpbmFsaXplclJlZmVyZW5jZTxPYmplY3Q+IHJlZmVyZW5jZSA9IG5ldyBGaW5hbGl6ZXJSZWZlcmVuY2U8T2JqZWN0PihudWxsLCBxdWV1ZSk7CisgICAgICAgIHJlZmVyZW5jZS56b21iaWUgPSBzZW50aW5lbDsKKyAgICAgICAgcmVmZXJlbmNlLmVucXVldWVJbnRlcm5hbCgpOworICAgICAgICBzZW50aW5lbC5hd2FpdEZpbmFsaXphdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgbWFya2VyIG9iamVjdCB0aGF0IHdlIGNhbiBpbW1lZGlhdGVseSBlbnF1ZXVlLiBXaGVuIHRoaXMgb2JqZWN0J3MKKyAgICAgKiBmaW5hbGl6ZSgpIG1ldGhvZCBpcyBjYWxsZWQsIHdlIGtub3cgYWxsIHByZXZpb3VzbHktZW5xdWV1ZWQgZmluYWxpemFibGUKKyAgICAgKiByZWZlcmVuY2VzIGhhdmUgYmVlbiBmaW5hbGl6ZWQuCisgICAgICoKKyAgICAgKiA8cD5FYWNoIGluc3RhbmNlIG9mIHRoaXMgY2xhc3Mgd2lsbCBiZSBmaW5hbGl6ZWQgdHdpY2UgYXMgaXQgaXMgZW5xdWV1ZWQKKyAgICAgKiBkaXJlY3RseSBhbmQgYnkgdGhlIGdhcmJhZ2UgY29sbGVjdG9yLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFNlbnRpbmVsIHsKKyAgICAgICAgYm9vbGVhbiBmaW5hbGl6ZWQgPSBmYWxzZTsKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBzeW5jaHJvbml6ZWQgdm9pZCBmaW5hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICAgICAgZmluYWxpemVkID0gdHJ1ZTsKKyAgICAgICAgICAgIG5vdGlmeUFsbCgpOworICAgICAgICB9CisgICAgICAgIHN5bmNocm9uaXplZCB2b2lkIGF3YWl0RmluYWxpemF0aW9uKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHdoaWxlICghZmluYWxpemVkKSB7CisgICAgICAgICAgICAgICAgd2FpdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWYvUGhhbnRvbVJlZmVyZW5jZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWYvUGhhbnRvbVJlZmVyZW5jZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI3MjZkOTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZi9QaGFudG9tUmVmZXJlbmNlLmphdmEKQEAgLTAsMCArMSw3MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcucmVmOworCisvKioKKyAqIEltcGxlbWVudHMgYSBwaGFudG9tIHJlZmVyZW5jZSwgd2hpY2ggaXMgdGhlIHdlYWtlc3Qgb2YgdGhlIHRocmVlIHR5cGVzIG9mCisgKiByZWZlcmVuY2VzLiBPbmNlIHRoZSBnYXJiYWdlIGNvbGxlY3RvciBkZWNpZGVzIHRoYXQgYW4gb2JqZWN0IHtAY29kZSBvYmp9IGlzCisgKiBwaGFudG9tLXJlYWNoYWJsZSwgaXQgaXMgYmVpbmcgZW5xdWV1ZWQKKyAqIG9uIHRoZSBjb3JyZXNwb25kaW5nIHF1ZXVlLCBidXQgaXRzIHJlZmVyZW50IGlzIG5vdCBjbGVhcmVkLiBUaGF0IGlzLCB0aGUKKyAqIHJlZmVyZW5jZSBxdWV1ZSBvZiB0aGUgcGhhbnRvbSByZWZlcmVuY2UgbXVzdCBleHBsaWNpdGx5IGJlIHByb2Nlc3NlZCBieSBzb21lCisgKiBhcHBsaWNhdGlvbiBjb2RlLiBBcyBhIGNvbnNlcXVlbmNlLCBhIHBoYW50b20gcmVmZXJlbmNlIHRoYXQgaXMgbm90CisgKiByZWdpc3RlcmVkIHdpdGggYW55IHJlZmVyZW5jZSBxdWV1ZSBkb2VzIG5vdCBtYWtlIGFueSBzZW5zZS4KKyAqIDxwPgorICogUGhhbnRvbSByZWZlcmVuY2VzIGFyZSB1c2VmdWwgZm9yIGltcGxlbWVudGluZyBjbGVhbnVwIG9wZXJhdGlvbnMgdGhhdCBhcmUKKyAqIG5lY2Vzc2FyeSBiZWZvcmUgYW4gb2JqZWN0IGdldHMgZ2FyYmFnZS1jb2xsZWN0ZWQuIFRoZXkgYXJlIHNvbWV0aW1lcyBtb3JlCisgKiBmbGV4aWJsZSB0aGFuIHRoZSB7QGxpbmsgT2JqZWN0I2ZpbmFsaXplKCl9IG1ldGhvZC4KKyAqLworcHVibGljIGNsYXNzIFBoYW50b21SZWZlcmVuY2U8VD4gZXh0ZW5kcyBSZWZlcmVuY2U8VD4geworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBwaGFudG9tIHJlZmVyZW5jZSBhbmQgcmVnaXN0ZXJzIGl0IHdpdGggdGhlIGdpdmVuCisgICAgICogcmVmZXJlbmNlIHF1ZXVlLiBUaGUgcmVmZXJlbmNlIHF1ZXVlIG1heSBiZSB7QGNvZGUgbnVsbH0sIGJ1dCB0aGlzIGNhc2UKKyAgICAgKiBkb2VzIG5vdCBtYWtlIGFueSBzZW5zZSwgc2luY2UgdGhlIHJlZmVyZW5jZSB3aWxsIG5ldmVyIGJlIGVucXVldWVkLCBhbmQKKyAgICAgKiB0aGUge0BsaW5rICNnZXQoKX0gbWV0aG9kIGFsd2F5cyByZXR1cm5zIHtAY29kZSBudWxsfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByIHRoZSByZWZlcmVudCB0byB0cmFjaworICAgICAqIEBwYXJhbSBxIHRoZSBxdWV1ZSB0byByZWdpc3RlciB0aGUgcGhhbnRvbSByZWZlcmVuY2Ugb2JqZWN0IHdpdGgKKyAgICAgKi8KKyAgICBwdWJsaWMgUGhhbnRvbVJlZmVyZW5jZShUIHIsIFJlZmVyZW5jZVF1ZXVlPD8gc3VwZXIgVD4gcSkgeworICAgICAgICBzdXBlcihyLCBxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHtAY29kZSBudWxsfS4gIFRoZSByZWZlcmVudCBvZiBhIHBoYW50b20gcmVmZXJlbmNlIGlzIG5vdAorICAgICAqIGFjY2Vzc2libGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSBudWxsfSAoYWx3YXlzKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBUIGdldCgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWYvUmVmZXJlbmNlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZi9SZWZlcmVuY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NWZiYjA0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWYvUmVmZXJlbmNlLmphdmEKQEAgLTAsMCArMSwxNDYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nLnJlZjsKKworLyoqCisgKiBQcm92aWRlcyBhbiBhYnN0cmFjdCBjbGFzcyB3aGljaCBkZXNjcmliZXMgYmVoYXZpb3IgY29tbW9uIHRvIGFsbCByZWZlcmVuY2UKKyAqIG9iamVjdHMuIEl0IGlzIG5vdCBwb3NzaWJsZSB0byBjcmVhdGUgaW1tZWRpYXRlIHN1YmNsYXNzZXMgb2YKKyAqIHtAY29kZSBSZWZlcmVuY2V9IGluIGFkZGl0aW9uIHRvIHRoZSBvbmVzIHByb3ZpZGVkIGJ5IHRoaXMgcGFja2FnZS4gSXQgaXMKKyAqIGFsc28gbm90IGRlc2lyYWJsZSB0byBkbyBzbywgc2luY2UgcmVmZXJlbmNlcyByZXF1aXJlIHZlcnkgY2xvc2UgY29vcGVyYXRpb24KKyAqIHdpdGggdGhlIHN5c3RlbSdzIGdhcmJhZ2UgY29sbGVjdG9yLiBUaGUgZXhpc3RpbmcsIHNwZWNpYWxpemVkIHJlZmVyZW5jZQorICogY2xhc3NlcyBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgUmVmZXJlbmNlPFQ+IHsKKworICAgIC8qKgorICAgICAqIFRoZSBvYmplY3QgdG8gd2hpY2ggdGhpcyByZWZlcmVuY2UgcmVmZXJzLgorICAgICAqIFZNIHJlcXVpcmVtZW50OiB0aGlzIGZpZWxkIDxlbT5tdXN0PC9lbT4gYmUgY2FsbGVkICJyZWZlcmVudCIKKyAgICAgKiBhbmQgYmUgYW4gb2JqZWN0LgorICAgICAqLworICAgIHZvbGF0aWxlIFQgcmVmZXJlbnQ7CisKKyAgICAvKioKKyAgICAgKiBJZiBub24tbnVsbCwgdGhlIHF1ZXVlIG9uIHdoaWNoIHRoaXMgcmVmZXJlbmNlIHdpbGwgYmUgZW5xdWV1ZWQKKyAgICAgKiB3aGVuIHRoZSByZWZlcmVudCBpcyBhcHByb3ByaWF0ZWx5IHJlYWNoYWJsZS4KKyAgICAgKiBWTSByZXF1aXJlbWVudDogdGhpcyBmaWVsZCA8ZW0+bXVzdDwvZW0+IGJlIGNhbGxlZCAicXVldWUiCisgICAgICogYW5kIGJlIGEgamF2YS5sYW5nLnJlZi5SZWZlcmVuY2VRdWV1ZS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICB2b2xhdGlsZSBSZWZlcmVuY2VRdWV1ZSBxdWV1ZTsKKworICAgIC8qKgorICAgICAqIFVzZWQgaW50ZXJuYWxseSBieSBqYXZhLmxhbmcucmVmLlJlZmVyZW5jZVF1ZXVlLgorICAgICAqIFZNIHJlcXVpcmVtZW50OiB0aGlzIGZpZWxkIDxlbT5tdXN0PC9lbT4gYmUgY2FsbGVkICJxdWV1ZU5leHQiCisgICAgICogYW5kIGJlIGEgamF2YS5sYW5nLnJlZi5SZWZlcmVuY2UuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgdm9sYXRpbGUgUmVmZXJlbmNlIHF1ZXVlTmV4dDsKKworICAgIC8qKgorICAgICAqIFVzZWQgaW50ZXJuYWxseSBieSB0aGUgVk0uICBUaGlzIGZpZWxkIGZvcm1zIGEgY2lyY3VsYXIgYW5kCisgICAgICogc2luZ2x5IGxpbmtlZCBsaXN0IG9mIHJlZmVyZW5jZSBvYmplY3RzIGRpc2NvdmVyZWQgYnkgdGhlCisgICAgICogZ2FyYmFnZSBjb2xsZWN0b3IgYW5kIGF3YWl0aW5nIHByb2Nlc3NpbmcgYnkgdGhlIHJlZmVyZW5jZQorICAgICAqIHF1ZXVlIHRocmVhZC4KKyAgICAgKgorICAgICAqIEBoaWRlCisgICAgICovCisgICAgcHVibGljIHZvbGF0aWxlIFJlZmVyZW5jZTw/PiBwZW5kaW5nTmV4dDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcy4KKyAgICAgKi8KKyAgICBSZWZlcmVuY2UoKSB7CisgICAgfQorCisgICAgUmVmZXJlbmNlKFQgciwgUmVmZXJlbmNlUXVldWUgcSkgeworICAgICAgICByZWZlcmVudCA9IHI7CisgICAgICAgIHF1ZXVlID0gcTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYWtlcyB0aGUgcmVmZXJlbnQge0Bjb2RlIG51bGx9LiBUaGlzIGRvZXMgbm90IGZvcmNlIHRoZSByZWZlcmVuY2UKKyAgICAgKiBvYmplY3QgdG8gYmUgZW5xdWV1ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgIHJlZmVyZW50ID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGFuIG9iamVjdCB0byBpdHMgcmVmZXJlbmNlIHF1ZXVlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBjYWxsIGhhcyBjYXVzZWQgdGhlIHtAY29kZSBSZWZlcmVuY2V9IHRvCisgICAgICogYmVjb21lIGVucXVldWVkLCBvciB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZQorICAgICAqCisgICAgICogQGhpZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgc3luY2hyb25pemVkIGJvb2xlYW4gZW5xdWV1ZUludGVybmFsKCkgeworICAgICAgICBpZiAocXVldWUgIT0gbnVsbCAmJiBxdWV1ZU5leHQgPT0gbnVsbCkgeworICAgICAgICAgICAgcXVldWUuZW5xdWV1ZSh0aGlzKTsKKyAgICAgICAgICAgIHF1ZXVlID0gbnVsbDsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGb3JjZXMgdGhlIHJlZmVyZW5jZSBvYmplY3QgdG8gYmUgZW5xdWV1ZWQgaWYgaXQgaGFzIGJlZW4gYXNzb2NpYXRlZCB3aXRoCisgICAgICogYSBxdWV1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgY2FsbCBoYXMgY2F1c2VkIHRoZSB7QGNvZGUgUmVmZXJlbmNlfSB0bworICAgICAqIGJlY29tZSBlbnF1ZXVlZCwgb3Ige0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBlbnF1ZXVlKCkgeworICAgICAgICByZXR1cm4gZW5xdWV1ZUludGVybmFsKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmVmZXJlbnQgb2YgdGhlIHJlZmVyZW5jZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZWZlcmVudCB0byB3aGljaCByZWZlcmVuY2UgcmVmZXJzLCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlCisgICAgICogICAgICAgICBvYmplY3QgaGFzIGJlZW4gY2xlYXJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVCBnZXQoKSB7CisgICAgICAgIHJldHVybiByZWZlcmVudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgcmVmZXJlbmNlIG9iamVjdCBoYXMgYmVlbiBlbnF1ZXVlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSB7QGNvZGUgUmVmZXJlbmNlfSBoYXMgYmVlbiBlbnF1ZXVlZCwge0Bjb2RlCisgICAgICogICAgICAgICBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFbnF1ZXVlZCgpIHsKKyAgICAgICAgcmV0dXJuIHF1ZXVlTmV4dCAhPSBudWxsOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWYvUmVmZXJlbmNlUXVldWUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmL1JlZmVyZW5jZVF1ZXVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmM5YjRkNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmL1JlZmVyZW5jZVF1ZXVlLmphdmEKQEAgLTAsMCArMSwxNjIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nLnJlZjsKKworLyoqCisgKiBUaGUge0Bjb2RlIFJlZmVyZW5jZVF1ZXVlfSBpcyB0aGUgY29udGFpbmVyIG9uIHdoaWNoIHJlZmVyZW5jZSBvYmplY3RzIGFyZQorICogZW5xdWV1ZWQgd2hlbiB0aGUgZ2FyYmFnZSBjb2xsZWN0b3IgZGV0ZWN0cyB0aGUgcmVhY2hhYmlsaXR5IHR5cGUgc3BlY2lmaWVkCisgKiBmb3IgdGhlIHJlZmVyZW50LgorICoKKyAqIEBzaW5jZSAxLjIKKyAqLworcHVibGljIGNsYXNzIFJlZmVyZW5jZVF1ZXVlPFQ+IHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTkFOT1NfUEVSX01JTExJID0gMTAwMDAwMDsKKworICAgIHByaXZhdGUgUmVmZXJlbmNlPD8gZXh0ZW5kcyBUPiBoZWFkOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBSZWZlcmVuY2VRdWV1ZSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGF2YWlsYWJsZSByZWZlcmVuY2UgZnJvbSB0aGUgcXVldWUsIHJlbW92aW5nIGl0IGluIHRoZQorICAgICAqIHByb2Nlc3MuIERvZXMgbm90IHdhaXQgZm9yIGEgcmVmZXJlbmNlIHRvIGJlY29tZSBhdmFpbGFibGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGF2YWlsYWJsZSByZWZlcmVuY2UsIG9yIHtAY29kZSBudWxsfSBpZiBubyByZWZlcmVuY2UgaXMKKyAgICAgKiAgICAgICAgIGltbWVkaWF0ZWx5IGF2YWlsYWJsZQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgUmVmZXJlbmNlPD8gZXh0ZW5kcyBUPiBwb2xsKCkgeworICAgICAgICBpZiAoaGVhZCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIFJlZmVyZW5jZTw/IGV4dGVuZHMgVD4gcmV0OworCisgICAgICAgIHJldCA9IGhlYWQ7CisKKyAgICAgICAgaWYgKGhlYWQgPT0gaGVhZC5xdWV1ZU5leHQpIHsKKyAgICAgICAgICAgIGhlYWQgPSBudWxsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaGVhZCA9IGhlYWQucXVldWVOZXh0OworICAgICAgICB9CisKKyAgICAgICAgcmV0LnF1ZXVlTmV4dCA9IG51bGw7CisKKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGF2YWlsYWJsZSByZWZlcmVuY2UgZnJvbSB0aGUgcXVldWUsIHJlbW92aW5nIGl0IGluIHRoZQorICAgICAqIHByb2Nlc3MuIFdhaXRzIGluZGVmaW5pdGVseSBmb3IgYSByZWZlcmVuY2UgdG8gYmVjb21lIGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgdGhlIGJsb2NraW5nIGNhbGwgd2FzIGludGVycnVwdGVkCisgICAgICovCisgICAgcHVibGljIFJlZmVyZW5jZTw/IGV4dGVuZHMgVD4gcmVtb3ZlKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHJlbW92ZSgwTCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBhdmFpbGFibGUgcmVmZXJlbmNlIGZyb20gdGhlIHF1ZXVlLCByZW1vdmluZyBpdCBpbiB0aGUKKyAgICAgKiBwcm9jZXNzLiBXYWl0cyBmb3IgYSByZWZlcmVuY2UgdG8gYmVjb21lIGF2YWlsYWJsZSBvciB0aGUgZ2l2ZW4gdGltZW91dAorICAgICAqIHBlcmlvZCB0byBlbGFwc2UsIHdoaWNoZXZlciBoYXBwZW5zIGZpcnN0LgorICAgICAqCisgICAgICogQHBhcmFtIHRpbWVvdXRNaWxsaXMgbWF4aW11bSB0aW1lIHRvIHNwZW5kIHdhaXRpbmcgZm9yIGEgcmVmZXJlbmNlIG9iamVjdAorICAgICAqICAgICB0byBiZWNvbWUgYXZhaWxhYmxlLiBBIHZhbHVlIG9mIHtAY29kZSAwfSByZXN1bHRzIGluIHRoZSBtZXRob2QKKyAgICAgKiAgICAgd2FpdGluZyBpbmRlZmluaXRlbHkuCisgICAgICogQHJldHVybiB0aGUgbmV4dCBhdmFpbGFibGUgcmVmZXJlbmNlLCBvciB7QGNvZGUgbnVsbH0gaWYgbm8gcmVmZXJlbmNlCisgICAgICogICAgIGJlY29tZXMgYXZhaWxhYmxlIHdpdGhpbiB0aGUgdGltZW91dCBwZXJpb2QKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgdGltZW91dE1pbGxpcyA8IDB9LgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgdGhlIGJsb2NraW5nIGNhbGwgd2FzIGludGVycnVwdGVkCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBSZWZlcmVuY2U8PyBleHRlbmRzIFQ+IHJlbW92ZShsb25nIHRpbWVvdXRNaWxsaXMpCisgICAgICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBpZiAodGltZW91dE1pbGxpcyA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInRpbWVvdXQgPCAwOiAiICsgdGltZW91dE1pbGxpcyk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoaGVhZCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gcG9sbCgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gYXZvaWQgb3ZlcmZsb3c6IGlmIHRvdGFsID4gMjkyIHllYXJzLCBqdXN0IHdhaXQgZm9yZXZlcgorICAgICAgICBpZiAodGltZW91dE1pbGxpcyA9PSAwIHx8ICh0aW1lb3V0TWlsbGlzID4gTG9uZy5NQVhfVkFMVUUgLyBOQU5PU19QRVJfTUlMTEkpKSB7CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgd2FpdCgwKTsKKyAgICAgICAgICAgIH0gd2hpbGUgKGhlYWQgPT0gbnVsbCk7CisgICAgICAgICAgICByZXR1cm4gcG9sbCgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gZ3VhcmFudGVlZCB0byBub3Qgb3ZlcmZsb3cKKyAgICAgICAgbG9uZyBuYW5vc1RvV2FpdCA9IHRpbWVvdXRNaWxsaXMgKiBOQU5PU19QRVJfTUlMTEk7CisgICAgICAgIGludCB0aW1lb3V0TmFub3MgPSAwOworCisgICAgICAgIC8vIHdhaXQgdW50aWwgbm90aWZpZWQgb3IgdGhlIHRpbWVvdXQgaGFzIGVsYXBzZWQKKyAgICAgICAgbG9uZyBzdGFydFRpbWUgPSBTeXN0ZW0ubmFub1RpbWUoKTsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIHdhaXQodGltZW91dE1pbGxpcywgdGltZW91dE5hbm9zKTsKKyAgICAgICAgICAgIGlmIChoZWFkICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGxvbmcgbmFub3NFbGFwc2VkID0gU3lzdGVtLm5hbm9UaW1lKCkgLSBzdGFydFRpbWU7CisgICAgICAgICAgICBsb25nIG5hbm9zUmVtYWluaW5nID0gbmFub3NUb1dhaXQgLSBuYW5vc0VsYXBzZWQ7CisgICAgICAgICAgICBpZiAobmFub3NSZW1haW5pbmcgPD0gMCkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGltZW91dE1pbGxpcyA9IG5hbm9zUmVtYWluaW5nIC8gTkFOT1NfUEVSX01JTExJOworICAgICAgICAgICAgdGltZW91dE5hbm9zID0gKGludCkgKG5hbm9zUmVtYWluaW5nIC0gdGltZW91dE1pbGxpcyAqIE5BTk9TX1BFUl9NSUxMSSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHBvbGwoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbnF1ZXVlIHRoZSByZWZlcmVuY2Ugb2JqZWN0IG9uIHRoZSByZWNlaXZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWZlcmVuY2UKKyAgICAgKiAgICAgICAgICAgIHJlZmVyZW5jZSBvYmplY3QgdG8gYmUgZW5xdWV1ZWQuCisgICAgICogQHJldHVybiBib29sZWFuIHRydWUgaWYgcmVmZXJlbmNlIGlzIGVucXVldWVkLiBmYWxzZSBpZiByZWZlcmVuY2UgZmFpbGVkCisgICAgICogICAgICAgICB0byBlbnF1ZXVlLgorICAgICAqLworICAgIHN5bmNocm9uaXplZCB2b2lkIGVucXVldWUoUmVmZXJlbmNlPD8gZXh0ZW5kcyBUPiByZWZlcmVuY2UpIHsKKyAgICAgICAgaWYgKGhlYWQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmVmZXJlbmNlLnF1ZXVlTmV4dCA9IHJlZmVyZW5jZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlZmVyZW5jZS5xdWV1ZU5leHQgPSBoZWFkOworICAgICAgICB9CisgICAgICAgIGhlYWQgPSByZWZlcmVuY2U7CisgICAgICAgIG5vdGlmeSgpOworICAgIH0KKworICAgIC8qKiBAaGlkZSAqLworICAgIHB1YmxpYyBzdGF0aWMgUmVmZXJlbmNlIHVuZW5xdWV1ZWQgPSBudWxsOworCisgICAgc3RhdGljIHZvaWQgYWRkKFJlZmVyZW5jZTw/PiBsaXN0KSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoUmVmZXJlbmNlUXVldWUuY2xhc3MpIHsKKyAgICAgICAgICAgIGlmICh1bmVucXVldWVkID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB1bmVucXVldWVkID0gbGlzdDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgUmVmZXJlbmNlPD8+IG5leHQgPSB1bmVucXVldWVkLnBlbmRpbmdOZXh0OworICAgICAgICAgICAgICAgIHVuZW5xdWV1ZWQucGVuZGluZ05leHQgPSBsaXN0LnBlbmRpbmdOZXh0OworICAgICAgICAgICAgICAgIGxpc3QucGVuZGluZ05leHQgPSBuZXh0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgUmVmZXJlbmNlUXVldWUuY2xhc3Mubm90aWZ5QWxsKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZi9Tb2Z0UmVmZXJlbmNlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZi9Tb2Z0UmVmZXJlbmNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODg4MDE3MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmL1NvZnRSZWZlcmVuY2UuamF2YQpAQCAtMCwwICsxLDExMSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcucmVmOworCisvKioKKyAqIEltcGxlbWVudHMgYSBzb2Z0IHJlZmVyZW5jZSwgd2hpY2ggaXMgdGhlIGxlYXN0LXdlYWsgb2YgdGhlIHRocmVlIHR5cGVzIG9mCisgKiByZWZlcmVuY2VzLiBPbmNlIHRoZSBnYXJiYWdlIGNvbGxlY3RvciBoYXMgZGVjaWRlZCB0aGF0IGFuIG9iamVjdCB7QGNvZGUgb2JqfQorICogaXMgc29mdGx5LXJlYWNoYWJsZSwgdGhlIGZvbGxvd2luZworICogbWF5IGhhcHBlbiwgZWl0aGVyIGltbWVkaWF0ZWx5IG9yIGF0IGEgbGF0ZXIgcG9pbnQ6CisgKgorICogPHVsPgorICogICA8bGk+CisgKiAgICAgQSBzZXQge0Bjb2RlIHJlZn0gb2YgcmVmZXJlbmNlcyBpcyBkZXRlcm1pbmVkLiB7QGNvZGUgcmVmfSBjb250YWlucyB0aGUKKyAqICAgICBmb2xsb3dpbmcgZWxlbWVudHM6CisgKiAgICAgPHVsPgorICogICAgICAgPGxpPgorICogICAgICAgICBBbGwgc29mdCByZWZlcmVuY2VzIHBvaW50aW5nIHRvIHtAY29kZSBvYmp9LgorICogICAgICAgPC9saT4KKyAqICAgICAgIDxsaT4KKyAqICAgICAgICAgQWxsIHNvZnQgcmVmZXJlbmNlcyBwb2ludGluZyB0byBvYmplY3RzIGZyb20gd2hpY2gge0Bjb2RlIG9ian0gaXMKKyAqICAgICAgICAgc3Ryb25nbHkgcmVhY2hhYmxlLgorICogICAgICAgPC9saT4KKyAqICAgICA8L3VsPgorICogICA8L2xpPgorICogICA8bGk+CisgKiAgICAgQWxsIHJlZmVyZW5jZXMgaW4ge0Bjb2RlIHJlZn0gYXJlIGF0b21pY2FsbHkgY2xlYXJlZC4KKyAqICAgPC9saT4KKyAqICAgPGxpPgorICogICAgIEF0IHRoZSBzYW1lIHRpbWUgb3Igc29tZSB0aW1lIGluIHRoZSBmdXR1cmUsIGFsbCByZWZlcmVuY2VzIGluIHtAY29kZQorICogICAgIHJlZn0gd2lsbCBiZSBlbnF1ZXVlZCB3aXRoIHRoZWlyIGNvcnJlc3BvbmRpbmcgcmVmZXJlbmNlIHF1ZXVlcywgaWYgYW55LgorICogICA8L2xpPgorICogPC91bD4KKyAqCisgKiBUaGUgc3lzdGVtIG1heSBkZWNpZGUgbm90IHRvIGNsZWFyIGFuZCBlbnF1ZXVlIHNvZnQgcmVmZXJlbmNlcyB1bnRpbCBhIGxhdGVyCisgKiB0aW1lLCB5ZXQgYWxsIHtAY29kZSBTb2Z0UmVmZXJlbmNlfXMgcG9pbnRpbmcgdG8gc29mdGx5IHJlYWNoYWJsZSBvYmplY3RzIGFyZQorICogZ3VhcmFudGVlZCB0byBiZSBjbGVhcmVkIGJlZm9yZSB0aGUgVk0gd2lsbCB0aHJvdyBhbiB7QGxpbmsKKyAqIGphdmEubGFuZy5PdXRPZk1lbW9yeUVycm9yfS4KKyAqCisgKiBTb2Z0IHJlZmVyZW5jZXMgYXJlIHVzZWZ1bCBmb3IgY2FjaGVzIHRoYXQgc2hvdWxkIGF1dG9tYXRpY2FsbHkgaGF2ZQorICogdGhlaXIgZW50cmllcyByZW1vdmVkIG9uY2UgdGhleSBhcmUgbm90IHJlZmVyZW5jZWQgYW55IG1vcmUgKGZyb20gb3V0c2lkZSksCisgKiBhbmQgdGhlcmUgaXMgYSBuZWVkIGZvciBtZW1vcnkuIFRoZSBkaWZmZXJlbmNlIGJldHdlZW4gYSB7QGNvZGUKKyAqIFNvZnRSZWZlcmVuY2V9IGFuZCBhIHtAY29kZSBXZWFrUmVmZXJlbmNlfSBpcyB0aGUgcG9pbnQgb2YgdGltZSBhdCB3aGljaCB0aGUKKyAqIGRlY2lzaW9uIGlzIG1hZGUgdG8gY2xlYXIgYW5kIGVucXVldWUgdGhlIHJlZmVyZW5jZToKKyAqCisgKiA8dWw+CisgKiAgIDxsaT4KKyAqICAgICBBIHtAY29kZSBTb2Z0UmVmZXJlbmNlfSBzaG91bGQgYmUgY2xlYXJlZCBhbmQgZW5xdWV1ZWQgPGVtPmFzIGxhdGUgYXMKKyAqICAgICBwb3NzaWJsZTwvZW0+LCB0aGF0IGlzLCBpbiBjYXNlIHRoZSBWTSBpcyBpbiBkYW5nZXIgb2YgcnVubmluZyBvdXQgb2YKKyAqICAgICBtZW1vcnkuCisgKiAgIDwvbGk+CisgKiAgIDxsaT4KKyAqICAgICBBIHtAY29kZSBXZWFrUmVmZXJlbmNlfSBtYXkgYmUgY2xlYXJlZCBhbmQgZW5xdWV1ZWQgYXMgc29vbiBhcyBpcworICogICAgIGtub3duIHRvIGJlIHdlYWtseS1yZWZlcmVuY2VkLgorICogICA8L2xpPgorICogPC91bD4KKyAqLworcHVibGljIGNsYXNzIFNvZnRSZWZlcmVuY2U8VD4gZXh0ZW5kcyBSZWZlcmVuY2U8VD4geworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBzb2Z0IHJlZmVyZW5jZSB0byB0aGUgZ2l2ZW4gcmVmZXJlbnQuIFRoZSBuZXdseSBjcmVhdGVkCisgICAgICogcmVmZXJlbmNlIGlzIG5vdCByZWdpc3RlcmVkIHdpdGggYW55IHJlZmVyZW5jZSBxdWV1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByIHRoZSByZWZlcmVudCB0byB0cmFjaworICAgICAqLworICAgIHB1YmxpYyBTb2Z0UmVmZXJlbmNlKFQgcikgeworICAgICAgICBzdXBlcihyLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHNvZnQgcmVmZXJlbmNlIHRvIHRoZSBnaXZlbiByZWZlcmVudC4gVGhlIG5ld2x5IGNyZWF0ZWQKKyAgICAgKiByZWZlcmVuY2UgaXMgcmVnaXN0ZXJlZCB3aXRoIHRoZSBnaXZlbiByZWZlcmVuY2UgcXVldWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gciB0aGUgcmVmZXJlbnQgdG8gdHJhY2sKKyAgICAgKiBAcGFyYW0gcSB0aGUgcXVldWUgdG8gcmVnaXN0ZXIgdG8gdGhlIHJlZmVyZW5jZSBvYmplY3Qgd2l0aC4gQSBudWxsIHZhbHVlCisgICAgICogICAgICAgICAgcmVzdWx0cyBpbiBhIHdlYWsgcmVmZXJlbmNlIHRoYXQgaXMgbm90IGFzc29jaWF0ZWQgd2l0aCBhbnkKKyAgICAgKiAgICAgICAgICBxdWV1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU29mdFJlZmVyZW5jZShUIHIsIFJlZmVyZW5jZVF1ZXVlPD8gc3VwZXIgVD4gcSkgeworICAgICAgICBzdXBlcihyLCBxKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZi9XZWFrUmVmZXJlbmNlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZi9XZWFrUmVmZXJlbmNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWNlNDUwYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmL1dlYWtSZWZlcmVuY2UuamF2YQpAQCAtMCwwICsxLDExMCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcucmVmOworCisvKioKKyAqIEltcGxlbWVudHMgYSB3ZWFrIHJlZmVyZW5jZSwgd2hpY2ggaXMgdGhlIG1pZGRsZSBvZiB0aGUgdGhyZWUgdHlwZXMgb2YKKyAqIHJlZmVyZW5jZXMuIE9uY2UgdGhlIGdhcmJhZ2UgY29sbGVjdG9yIGRlY2lkZXMgdGhhdCBhbiBvYmplY3Qge0Bjb2RlIG9ian0gaXMKKyAqIGlzIHdlYWtseS1yZWFjaGFibGUsIHRoZSBmb2xsb3dpbmcKKyAqIGhhcHBlbnM6CisgKgorICogPHVsPgorICogICA8bGk+CisgKiAgICAgQSBzZXQge0Bjb2RlIHJlZn0gb2YgcmVmZXJlbmNlcyBpcyBkZXRlcm1pbmVkLiB7QGNvZGUgcmVmfSBjb250YWlucyB0aGUKKyAqICAgICBmb2xsb3dpbmcgZWxlbWVudHM6CisgKiAgICAgPHVsPgorICogICAgICAgPGxpPgorICogICAgICAgICBBbGwgd2VhayByZWZlcmVuY2VzIHBvaW50aW5nIHRvIHtAY29kZSBvYmp9LgorICogICAgICAgPC9saT4KKyAqICAgICAgIDxsaT4KKyAqICAgICAgICAgQWxsIHdlYWsgcmVmZXJlbmNlcyBwb2ludGluZyB0byBvYmplY3RzIGZyb20gd2hpY2gge0Bjb2RlIG9ian0gaXMKKyAqICAgICAgICAgZWl0aGVyIHN0cm9uZ2x5IG9yIHNvZnRseSByZWFjaGFibGUuCisgKiAgICAgICA8L2xpPgorICogICAgIDwvdWw+CisgKiAgIDwvbGk+CisgKiAgIDxsaT4KKyAqICAgICBBbGwgcmVmZXJlbmNlcyBpbiB7QGNvZGUgcmVmfSBhcmUgYXRvbWljYWxseSBjbGVhcmVkLgorICogICA8L2xpPgorICogICA8bGk+CisgKiAgICAgQWxsIG9iamVjdHMgZm9ybWVybHkgYmVpbmcgcmVmZXJlbmNlZCBieSB7QGNvZGUgcmVmfSBiZWNvbWUgZWxpZ2libGUgZm9yCisgKiAgICAgZmluYWxpemF0aW9uLgorICogICA8L2xpPgorICogICA8bGk+CisgKiAgICAgQXQgc29tZSBmdXR1cmUgcG9pbnQsIGFsbCByZWZlcmVuY2VzIGluIHtAY29kZSByZWZ9IHdpbGwgYmUgZW5xdWV1ZWQKKyAqICAgICB3aXRoIHRoZWlyIGNvcnJlc3BvbmRpbmcgcmVmZXJlbmNlIHF1ZXVlcywgaWYgYW55LgorICogICA8L2xpPgorICogPC91bD4KKyAqCisgKiBXZWFrIHJlZmVyZW5jZXMgYXJlIHVzZWZ1bCBmb3IgbWFwcGluZ3MgdGhhdCBzaG91bGQgaGF2ZSB0aGVpciBlbnRyaWVzCisgKiByZW1vdmVkIGF1dG9tYXRpY2FsbHkgb25jZSB0aGV5IGFyZSBub3QgcmVmZXJlbmNlZCBhbnkgbW9yZSAoZnJvbSBvdXRzaWRlKS4KKyAqIFRoZSBkaWZmZXJlbmNlIGJldHdlZW4gYSB7QGNvZGUgU29mdFJlZmVyZW5jZX0gYW5kIGEge0Bjb2RlIFdlYWtSZWZlcmVuY2V9IGlzCisgKiB0aGUgcG9pbnQgb2YgdGltZSBhdCB3aGljaCB0aGUgZGVjaXNpb24gaXMgbWFkZSB0byBjbGVhciBhbmQgZW5xdWV1ZSB0aGUKKyAqIHJlZmVyZW5jZToKKyAqCisgKiA8dWw+CisgKiAgIDxsaT4KKyAqICAgICBBIHtAY29kZSBTb2Z0UmVmZXJlbmNlfSBzaG91bGQgYmUgY2xlYXJlZCBhbmQgZW5xdWV1ZWQgPGVtPmFzIGxhdGUgYXMKKyAqICAgICBwb3NzaWJsZTwvZW0+LCB0aGF0IGlzLCBpbiBjYXNlIHRoZSBWTSBpcyBpbiBkYW5nZXIgb2YgcnVubmluZyBvdXQgb2YKKyAqICAgICBtZW1vcnkuCisgKiAgIDwvbGk+CisgKiAgIDxsaT4KKyAqICAgICBBIHtAY29kZSBXZWFrUmVmZXJlbmNlfSBtYXkgYmUgY2xlYXJlZCBhbmQgZW5xdWV1ZWQgYXMgc29vbiBhcyBpcworICogICAgIGtub3duIHRvIGJlIHdlYWtseS1yZWZlcmVuY2VkLgorICogICA8L2xpPgorICogPC91bD4KKyAqLworcHVibGljIGNsYXNzIFdlYWtSZWZlcmVuY2U8VD4gZXh0ZW5kcyBSZWZlcmVuY2U8VD4geworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB3ZWFrIHJlZmVyZW5jZSB0byB0aGUgZ2l2ZW4gcmVmZXJlbnQuIFRoZSBuZXdseSBjcmVhdGVkCisgICAgICogcmVmZXJlbmNlIGlzIG5vdCByZWdpc3RlcmVkIHdpdGggYW55IHJlZmVyZW5jZSBxdWV1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByIHRoZSByZWZlcmVudCB0byB0cmFjaworICAgICAqLworICAgIHB1YmxpYyBXZWFrUmVmZXJlbmNlKFQgcikgeworICAgICAgICBzdXBlcihyLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHdlYWsgcmVmZXJlbmNlIHRvIHRoZSBnaXZlbiByZWZlcmVudC4gVGhlIG5ld2x5IGNyZWF0ZWQKKyAgICAgKiByZWZlcmVuY2UgaXMgcmVnaXN0ZXJlZCB3aXRoIHRoZSBnaXZlbiByZWZlcmVuY2UgcXVldWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gciB0aGUgcmVmZXJlbnQgdG8gdHJhY2sKKyAgICAgKiBAcGFyYW0gcSB0aGUgcXVldWUgdG8gcmVnaXN0ZXIgdG8gdGhlIHJlZmVyZW5jZSBvYmplY3Qgd2l0aC4gQSBudWxsIHZhbHVlCisgICAgICogICAgICAgICAgcmVzdWx0cyBpbiBhIHdlYWsgcmVmZXJlbmNlIHRoYXQgaXMgbm90IGFzc29jaWF0ZWQgd2l0aCBhbnkKKyAgICAgKiAgICAgICAgICBxdWV1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgV2Vha1JlZmVyZW5jZShUIHIsIFJlZmVyZW5jZVF1ZXVlPD8gc3VwZXIgVD4gcSkgeworICAgICAgICBzdXBlcihyLCBxKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZi9wYWNrYWdlLmh0bWwgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZi9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDNkOGU4YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDk4IEBACis8aHRtbD4KKyAgPGJvZHk+CisgICAgPHA+CisgICAgICBQcm92aWRlcyB0aGUgc3lzdGVtJ3Mge0BsaW5rIGphdmEubGFuZy5yZWYuUmVmZXJlbmNlUXVldWV9IGltcGxlbWVudGF0aW9uIGFzIHdlbGwgYXMKKyAgICAgIGRpZmZlcmVudCBmb3JtcyBvZiByZWZlcmVuY2Ugb2JqZWN0cyB3aGljaCBpbXBvc2Ugc3BlY2lhbCBiZWhhdmlvciBvbiB0aGUKKyAgICAgIGdhcmJhZ2UgY29sbGVjdG9yLiBUaGUgYmVoYXZpb3IgZGVwZW5kcyBvbiB0aGUgdHlwZSBvZiB7QGxpbmsgamF2YS5sYW5nLnJlZi5SZWZlcmVuY2V9CisgICAgICBiZWluZyB1c2VkLiBUaHJlZSBkaWZmZXJlbnQgdHlwZSBvZiByZWZlcmVuY2VzIGV4aXN0LCBlYWNoIGJlaW5nIHdlYWtlcgorICAgICAgdGhhbiB0aGUgcHJlY2VkaW5nIG9uZToge0BsaW5rIGphdmEubGFuZy5yZWYuU29mdFJlZmVyZW5jZX0sIHtAbGluayBqYXZhLmxhbmcucmVmLldlYWtSZWZlcmVuY2V9LCBhbmQKKyAgICAgIHtAbGluayBqYXZhLmxhbmcucmVmLlBoYW50b21SZWZlcmVuY2V9LiAiV2Vha25lc3MiIGhlcmUgbWVhbnMgdGhhdCBsZXNzIHJlc3RyaWN0aW9ucyBhcmUKKyAgICAgIGJlaW5nIGltcG9zZWQgb24gdGhlIGdhcmJhZ2UgY29sbGVjdG9yIGFzIHRvIHdoZW4gaXQgaXMgYWxsb3dlZCB0bworICAgICAgYWN0dWFsbHkgZ2FyYmFnZS1jb2xsZWN0IHRoZSByZWZlcmVuY2VkIG9iamVjdC4KKyAgICA8L3A+CisgICAgPHA+CisgICAgICBJbiBvcmRlciB0byB1c2UgcmVmZXJlbmNlIG9iamVjdHMgcHJvcGVybHkgaXQgaXMgaW1wb3J0YW50IHRvIHVuZGVyc3RhbmQKKyAgICAgIHRoZSBkaWZmZXJlbnQgdHlwZXMgb2YgcmVhY2hhYmlsaXR5IHRoYXQgdHJpZ2dlciB0aGVpciBjbGVhcmluZyBhbmQKKyAgICAgIGVucXVldWVpbmcuIFRoZSBmb2xsb3dpbmcgdGFibGUgbGlzdHMgdGhlc2UsIGZyb20gc3Ryb25nZXN0IHRvIHdlYWtlc3QuCisgICAgICBGb3IgZWFjaCByb3csIGFuIG9iamVjdCBpcyBzYWlkIHRvIGhhdmUgdGhlIHJlYWNoYWJpbGl0eSBvbiB0aGUgbGVmdCBzaWRlCisgICAgICBpZiAoYW5kIG9ubHkgaWYpIGl0IGZ1bGZpbGxzIGFsbCBvZiB0aGUgcmVxdWlyZW1lbnRzIG9uIHRoZSByaWdodCBzaWRlLiBJbgorICAgICAgYWxsIHJvd3MsIGNvbnNpZGVyIHRoZSA8ZW0+cm9vdCBzZXQ8L2VtPiB0byBiZSBhIHNldCBvZiByZWZlcmVuY2VzIHRoYXQKKyAgICAgIGFyZSAicmVzaXN0YW50IiB0byBnYXJiYWdlIGNvbGxlY3Rpb24gKHRoYXQgaXMsIHJ1bm5pbmcgdGhyZWFkcywgbWV0aG9kCisgICAgICBwYXJhbWV0ZXJzLCBsb2NhbCB2YXJpYWJsZXMsIHN0YXRpYyBmaWVsZHMgYW5kIHRoZSBsaWtlKS4gIAorICAgIDwvcD4KKyAgICA8cD4KKyAgICAgIDxhIG5hbWU9ImRlZmluaXRpb25zIj48L2E+IAorICAgICAgPHRhYmxlPgorICAgICAgICA8dHI+CisgICAgICAgICAgPHRkPgorICAgICAgICAgICAgU3Ryb25nbHkgcmVhY2hhYmxlCisgICAgICAgICAgPC90ZD4KKyAgICAgICAgICA8dGQ+CisgICAgICAgICAgICA8dWw+CisgICAgICAgICAgICAgIDxsaT4KKyAgICAgICAgICAgICAgICBUaGVyZSBleGlzdHMgYXQgbGVhc3Qgb25lIHBhdGggZnJvbSB0aGUgcm9vdCBzZXQgdG8gdGhlIG9iamVjdAorICAgICAgICAgICAgICAgIHRoYXQgZG9lcyBub3QgdHJhdmVyc2UgYW55IGluc3RhbmNlIG9mIGEge0BsaW5rIGphdmEubGFuZy5yZWYuUmVmZXJlbmNlfQorICAgICAgICAgICAgICAgIHN1YmNsYXNzLgorICAgICAgICAgICAgICA8L2xpPgorICAgICAgICAgICAgPC91bD4KKyAgICAgICAgICA8L3RkPgorICAgICAgICA8L3RyPgorCisgICAgICAgIDx0cj4KKyAgICAgICAgICA8dGQ+CisgICAgICAgICAgICBTb2Z0bHkgcmVhY2hhYmxlCisgICAgICAgICAgPC90ZD4KKyAgICAgICAgICA8dGQ+CisgICAgICAgICAgICA8dWw+CisgICAgICAgICAgICAgIDxsaT4KKyAgICAgICAgICAgICAgICBUaGUgb2JqZWN0IGlzIG5vdCBzdHJvbmdseSByZWFjaGFibGUuCisgICAgICAgICAgICAgIDwvbGk+CisgICAgICAgICAgICAgIDxsaT4KKyAgICAgICAgICAgICAgICBUaGVyZSBleGlzdHMgYXQgbGVhc3Qgb25lIHBhdGggZnJvbSB0aGUgcm9vdCBzZXQgdG8gdGhlIG9iamVjdAorICAgICAgICAgICAgICAgIHRoYXQgZG9lcyB0cmF2ZXJzZSBhIHtAbGluayBqYXZhLmxhbmcucmVmLlNvZnRSZWZlcmVuY2V9IGluc3RhbmNlLCBidXQgbm8KKyAgICAgICAgICAgICAgICB7QGxpbmsgamF2YS5sYW5nLnJlZi5XZWFrUmVmZXJlbmNlfSBvciB7QGxpbmsgamF2YS5sYW5nLnJlZi5QaGFudG9tUmVmZXJlbmNlfSBpbnN0YW5jZXMuCisgICAgICAgICAgICAgIDwvbGk+CisgICAgICAgICAgICA8L3VsPgorICAgICAgICAgIDwvdGQ+CisgICAgICAgIDwvdHI+CisKKyAgICAgICAgPHRyPgorICAgICAgICAgIDx0ZD4KKyAgICAgICAgICAgIFdlYWtseSByZWFjaGFibGUKKyAgICAgICAgICA8L3RkPgorICAgICAgICAgIDx0ZD4KKyAgICAgICAgICAgIDx1bD4KKyAgICAgICAgICAgICAgPGxpPgorICAgICAgICAgICAgICAgIFRoZSBvYmplY3QgaXMgbmVpdGhlciBzdHJvbmdseSBub3Igc29mdGx5IHJlYWNoYWJsZS4KKyAgICAgICAgICAgICAgPC9saT4KKyAgICAgICAgICAgICAgPGxpPgorICAgICAgICAgICAgICAgIFRoZXJlIGV4aXN0cyBhdCBsZWFzdCBvbmUgcGF0aCBmcm9tIHRoZSByb290IHNldCB0byB0aGUgb2JqZWN0CisgICAgICAgICAgICAgICAgdGhhdCBkb2VzIHRyYXZlcnNlIGEge0BsaW5rIGphdmEubGFuZy5yZWYuV2Vha1JlZmVyZW5jZX0gaW5zdGFuY2UsIGJ1dCBubworICAgICAgICAgICAgICAgIHtAbGluayBqYXZhLmxhbmcucmVmLlBoYW50b21SZWZlcmVuY2V9IGluc3RhbmNlcy4KKyAgICAgICAgICAgICAgPC9saT4KKyAgICAgICAgICAgIDwvdWw+CisgICAgICAgICAgPC90ZD4KKyAgICAgICAgPC90cj4KKyAgICAgICAKKyAgICAgICAgPHRyPgorICAgICAgICAgIDx0ZD4KKyAgICAgICAgICAgIFBoYW50b20tcmVhY2hhYmxlCisgICAgICAgICAgPC90ZD4KKyAgICAgICAgICA8dGQ+CisgICAgICAgICAgICA8dWw+CisgICAgICAgICAgICAgIDxsaT4KKyAgICAgICAgICAgICAgICBUaGUgb2JqZWN0IGlzIG5laXRoZXIgc3Ryb25nbHksIHNvZnRseSBub3Igd2Vha2x5IHJlYWNoYWJsZS4KKyAgICAgICAgICAgICAgPC9saT4KKyAgICAgICAgICAgICAgPGxpPgorICAgICAgICAgICAgICAgIFRoZSBvYmplY3QgaXMgcmVmZXJlbmNlZCBieSBhIHtAbGluayBqYXZhLmxhbmcucmVmLlBoYW50b21SZWZlcmVuY2V9IGluc3RhbmNlLgorICAgICAgICAgICAgICA8L2xpPgorICAgICAgICAgICAgICA8bGk+CisgICAgICAgICAgICAgICAgVGhlIG9iamVjdCBoYXMgYWxyZWFkeSBiZWVuIGZpbmFsaXplZC4KKyAgICAgICAgICAgICAgPC9saT4KKyAgICAgICAgICAgIDwvdWw+CisgICAgICAgICAgPC90ZD4KKyAgICAgICAgPC90cj4KKyAgICAgIDwvdGFibGU+CisgICAgPC9wPgorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvQWNjZXNzaWJsZU9iamVjdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L0FjY2Vzc2libGVPYmplY3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZGRlMGMyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L0FjY2Vzc2libGVPYmplY3QuamF2YQpAQCAtMCwwICsxLDMyMiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcucmVmbGVjdDsKKworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkua2VybmVsLnZtLlN0cmluZ1V0aWxzOworCisvKioKKyAqIHtAY29kZSBBY2Nlc3NpYmxlT2JqZWN0fSBpcyB0aGUgc3VwZXJjbGFzcyBvZiBhbGwgbWVtYmVyIHJlZmxlY3Rpb24gY2xhc3NlcworICogKEZpZWxkLCBDb25zdHJ1Y3RvciwgTWV0aG9kKS4gQWNjZXNzaWJsZU9iamVjdCBwcm92aWRlcyB0aGUgYWJpbGl0eSB0byB0b2dnbGUKKyAqIGEgZmxhZyBjb250cm9sbGluZyBhY2Nlc3MgY2hlY2tzIGZvciB0aGVzZSBvYmplY3RzLiBCeSBkZWZhdWx0LCBhY2Nlc3NpbmcgYQorICogbWVtYmVyIChmb3IgZXhhbXBsZSwgc2V0dGluZyBhIGZpZWxkIG9yIGludm9raW5nIGEgbWV0aG9kKSBjaGVja3MgdGhlCisgKiB2YWxpZGl0eSBvZiB0aGUgYWNjZXNzIChmb3IgZXhhbXBsZSwgaW52b2tpbmcgYSBwcml2YXRlIG1ldGhvZCBmcm9tIG91dHNpZGUKKyAqIHRoZSBkZWZpbmluZyBjbGFzcyBpcyBwcm9oaWJpdGVkKSBhbmQgdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWYgdGhlCisgKiBvcGVyYXRpb24gaXMgbm90IHBlcm1pdHRlZC4gSWYgdGhlIGFjY2Vzc2libGUgZmxhZyBpcyBzZXQgdG8gdHJ1ZSwgdGhlc2UKKyAqIGNoZWNrcyBhcmUgb21pdHRlZC4gVGhpcyBhbGxvd3MgcHJpdmlsZWdlZCBjb2RlLCBzdWNoIGFzIEphdmEgb2JqZWN0CisgKiBzZXJpYWxpemF0aW9uLCBvYmplY3QgaW5zcGVjdG9ycywgYW5kIGRlYnVnZ2VycyB0byBoYXZlIGNvbXBsZXRlIGFjY2VzcyB0bworICogb2JqZWN0cy4KKyAqCisgKiBAc2VlIEZpZWxkCisgKiBAc2VlIENvbnN0cnVjdG9yCisgKiBAc2VlIE1ldGhvZAorICovCitwdWJsaWMgY2xhc3MgQWNjZXNzaWJsZU9iamVjdCBpbXBsZW1lbnRzIEFubm90YXRlZEVsZW1lbnQgeworCisgICAgLy8gSWYgdHJ1ZSwgb2JqZWN0IGlzIGFjY2Vzc2libGUsIGJ5cGFzc2luZyBub3JtYWwgYWNjZXNzIGNoZWNrcworICAgIGJvb2xlYW4gZmxhZyA9IGZhbHNlOworCisgICAgLy8gSG9sZHMgYSBtYXBwaW5nIGZyb20gSmF2YSB0eXBlIG5hbWVzIHRvIG5hdGl2ZSB0eXBlIGNvZGVzLgorICAgIHN0YXRpYyBIYXNodGFibGU8U3RyaW5nLCBTdHJpbmc+IHRyYW5zOworCisgICAgc3RhdGljIHsKKyAgICAgICAgdHJhbnMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgU3RyaW5nPig5KTsKKyAgICAgICAgdHJhbnMucHV0KCJieXRlIiwgIkIiKTsKKyAgICAgICAgdHJhbnMucHV0KCJjaGFyIiwgIkMiKTsKKyAgICAgICAgdHJhbnMucHV0KCJzaG9ydCIsICJTIik7CisgICAgICAgIHRyYW5zLnB1dCgiaW50IiwgIkkiKTsKKyAgICAgICAgdHJhbnMucHV0KCJsb25nIiwgIkoiKTsKKyAgICAgICAgdHJhbnMucHV0KCJmbG9hdCIsICJGIik7CisgICAgICAgIHRyYW5zLnB1dCgiZG91YmxlIiwgIkQiKTsKKyAgICAgICAgdHJhbnMucHV0KCJ2b2lkIiwgIlYiKTsKKyAgICAgICAgdHJhbnMucHV0KCJib29sZWFuIiwgIloiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdHRlbXB0cyB0byBzZXQgdGhlIHZhbHVlIG9mIHRoZSBhY2Nlc3NpYmxlIGZsYWcgZm9yIGFsbCB0aGUgb2JqZWN0cyBpbgorICAgICAqIHRoZSBhcnJheSBwcm92aWRlZC4gU2V0dGluZyB0aGlzCisgICAgICogZmxhZyB0byB7QGNvZGUgZmFsc2V9IHdpbGwgZW5hYmxlIGFjY2VzcyBjaGVja3MsIHNldHRpbmcgdG8ge0Bjb2RlIHRydWV9CisgICAgICogd2lsbCBkaXNhYmxlIHRoZW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0cworICAgICAqICAgICAgICAgICAgdGhlIGFjY2Vzc2libGUgb2JqZWN0cworICAgICAqIEBwYXJhbSBmbGFnCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgYWNjZXNzaWJsZSBmbGFnCisgICAgICoKKyAgICAgKiBAc2VlICNzZXRBY2Nlc3NpYmxlKGJvb2xlYW4pCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldEFjY2Vzc2libGUoQWNjZXNzaWJsZU9iamVjdFtdIG9iamVjdHMsIGJvb2xlYW4gZmxhZykgeworICAgICAgICBzeW5jaHJvbml6ZWQoQWNjZXNzaWJsZU9iamVjdC5jbGFzcykgeworICAgICAgICAgICAgZm9yIChBY2Nlc3NpYmxlT2JqZWN0IG9iamVjdCA6IG9iamVjdHMpIHsKKyAgICAgICAgICAgICAgICBvYmplY3QuZmxhZyA9IGZsYWc7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBBY2Nlc3NpYmxlT2JqZWN0fSBpbnN0YW5jZS4ge0Bjb2RlCisgICAgICogQWNjZXNzaWJsZU9iamVjdH0gaW5zdGFuY2VzIGNhbiBvbmx5IGJlIGNvbnN0cnVjdGVkIGJ5IHRoZSB2aXJ0dWFsCisgICAgICogbWFjaGluZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQWNjZXNzaWJsZU9iamVjdCgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIG9iamVjdCBpcyBhY2Nlc3NpYmxlIHdpdGhvdXQgYWNjZXNzIGNoZWNrcyBiZWluZworICAgICAqIHBlcmZvcm1lZC4gUmV0dXJucyB0aGUgYWNjZXNzaWJsZSBmbGFnLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBvYmplY3QgaXMgYWNjZXNzaWJsZSB3aXRob3V0IGFjY2VzcworICAgICAqICAgICAgICAgY2hlY2tzLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQWNjZXNzaWJsZSgpIHsKKyAgICAgICAgcmV0dXJuIGZsYWc7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gc2V0IHRoZSB2YWx1ZSBvZiB0aGUgYWNjZXNzaWJsZSBmbGFnLiBTZXR0aW5nIHRoaXMgZmxhZyB0bworICAgICAqIHtAY29kZSBmYWxzZX0gd2lsbCBlbmFibGUgYWNjZXNzIGNoZWNrcywgc2V0dGluZyB0byB7QGNvZGUgdHJ1ZX0gd2lsbAorICAgICAqIGRpc2FibGUgdGhlbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmbGFnCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgYWNjZXNzaWJsZSBmbGFnCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QWNjZXNzaWJsZShib29sZWFuIGZsYWcpIHsKKyAgICAgICAgdGhpcy5mbGFnID0gZmxhZzsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0Fubm90YXRpb25QcmVzZW50KENsYXNzPD8gZXh0ZW5kcyBBbm5vdGF0aW9uPiBhbm5vdGF0aW9uVHlwZSkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQW5ub3RhdGlvbltdIGdldERlY2xhcmVkQW5ub3RhdGlvbnMoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIHB1YmxpYyBBbm5vdGF0aW9uW10gZ2V0QW5ub3RhdGlvbnMoKSB7CisgICAgICAgIC8vIGZvciBhbGwgYnV0IENsYXNzLCBnZXRBbm5vdGF0aW9ucyA9PSBnZXREZWNsYXJlZEFubm90YXRpb25zCisgICAgICAgIHJldHVybiBnZXREZWNsYXJlZEFubm90YXRpb25zKCk7CisgICAgfQorCisgICAgcHVibGljIDxUIGV4dGVuZHMgQW5ub3RhdGlvbj4gVCBnZXRBbm5vdGF0aW9uKENsYXNzPFQ+IGFubm90YXRpb25UeXBlKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNpZ25hdHVyZSBmb3IgYSBjbGFzcy4gVGhpcyBpcyB0aGUga2luZCBvZiBzaWduYXR1cmUgdXNlZAorICAgICAqIGludGVybmFsbHkgYnkgdGhlIEpWTSwgd2l0aCBvbmUtY2hhcmFjdGVyIGNvZGVzIHJlcHJlc2VudGluZyB0aGUgYmFzaWMKKyAgICAgKiB0eXBlcy4gSXQgaXMgbm90IHN1aXRhYmxlIGZvciBwcmludGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbGF6egorICAgICAqICAgICAgICAgICAgdGhlIGNsYXNzIGZvciB3aGljaCBhIHNpZ25hdHVyZSBpcyByZXF1aXJlZAorICAgICAqCisgICAgICogQHJldHVybiBUaGUgc2lnbmF0dXJlIGFzIGEgc3RyaW5nCisgICAgICovCisgICAgU3RyaW5nIGdldFNpZ25hdHVyZShDbGFzczw/PiBjbGF6eikgeworICAgICAgICBTdHJpbmcgcmVzdWx0ID0gIiI7CisgICAgICAgIFN0cmluZyBuZXh0VHlwZSA9IGNsYXp6LmdldE5hbWUoKTsKKworICAgICAgICBpZih0cmFucy5jb250YWluc0tleShuZXh0VHlwZSkpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IHRyYW5zLmdldChuZXh0VHlwZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZihjbGF6ei5pc0FycmF5KCkpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSAiWyIgKyBnZXRTaWduYXR1cmUoY2xhenouZ2V0Q29tcG9uZW50VHlwZSgpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gIkwiICsgbmV4dFR5cGUgKyAiOyI7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcHJpbnRhYmxlIFN0cmluZyBjb25zaXN0aW5nIG9mIHRoZSBjYW5vbmljYWwgbmFtZXMgb2YgdGhlCisgICAgICogY2xhc3NlcyBjb250YWluZWQgaW4gYW4gYXJyYXkuIFRoZSBmb3JtIGlzIHRoYXQgdXNlZCBpbiBwYXJhbWV0ZXIgYW5kCisgICAgICogZXhjZXB0aW9uIGxpc3RzLCB0aGF0IGlzLCB0aGUgY2xhc3Mgb3IgdHlwZSBuYW1lcyBhcmUgc2VwYXJhdGVkIGJ5CisgICAgICogY29tbWFzLgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGVzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgY2xhc3NlcworICAgICAqCisgICAgICogQHJldHVybiBUaGUgU3RyaW5nIG9mIG5hbWVzCisgICAgICovCisgICAgU3RyaW5nIHRvU3RyaW5nKENsYXNzPD8+W10gdHlwZXMpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCisgICAgICAgIGlmICh0eXBlcy5sZW5ndGggIT0gMCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCh0eXBlc1swXS5nZXROYW1lKCkpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCB0eXBlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJywnKTsKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHR5cGVzW2ldLmdldE5hbWUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgU2lnbmF0dXJlIGF0dHJpYnV0ZSBmb3IgdGhpcyBpbnN0YW5jZS4gUmV0dXJucyB7QGNvZGUgbnVsbH0KKyAgICAgKiBpZiBub3QgZm91bmQuCisgICAgICovCisgICAgLypwYWNrYWdlKi8gU3RyaW5nIGdldFNpZ25hdHVyZUF0dHJpYnV0ZSgpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogTm90ZTogVGhpcyBtZXRob2Qgd291bGQgaGF2ZSBiZWVuIGRlY2xhcmVkIGFic3RyYWN0LCBidXQgdGhlCisgICAgICAgICAqIHN0YW5kYXJkIEFQSSBsaXN0cyB0aGlzIGNsYXNzIGFzIGNvbmNyZXRlLgorICAgICAgICAgKi8KKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmUgdGhlIHNpZ25hdHVyZSBhdHRyaWJ1dGUgZnJvbSBhbiBhcmJpdHJhcnkgY2xhc3MuICBUaGlzIGlzCisgICAgICogdGhlIHNhbWUgYXMgQ2xhc3MuZ2V0U2lnbmF0dXJlQXR0cmlidXRlKCksIGJ1dCBpdCBjYW4gYmUgdXNlZCBmcm9tCisgICAgICogdGhlIGphdmEubGFuZy5yZWZsZWN0IHBhY2thZ2UuCisgICAgICovCisgICAgLypwYWNrYWdlKi8gc3RhdGljIFN0cmluZyBnZXRDbGFzc1NpZ25hdHVyZUF0dHJpYnV0ZShDbGFzcyBjbGF6eikgeworICAgICAgICBPYmplY3RbXSBhbm5vdGF0aW9uID0gZ2V0Q2xhc3NTaWduYXR1cmVBbm5vdGF0aW9uKGNsYXp6KTsKKworICAgICAgICBpZiAoYW5ub3RhdGlvbiA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBTdHJpbmdVdGlscy5jb21iaW5lU3RyaW5ncyhhbm5vdGF0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZSB0aGUgc2lnbmF0dXJlIGFubm90YXRpb24gZnJvbSBhbiBhcmJpdHJhcnkgY2xhc3MuICBUaGlzIGlzCisgICAgICogdGhlIHNhbWUgYXMgQ2xhc3MuZ2V0U2lnbmF0dXJlQXR0cmlidXRlKCksIGJ1dCBpdCBjYW4gYmUgdXNlZCBmcm9tCisgICAgICogdGhlIGphdmEubGFuZy5yZWZsZWN0IHBhY2thZ2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIE9iamVjdFtdIGdldENsYXNzU2lnbmF0dXJlQW5ub3RhdGlvbihDbGFzcyBjbGF6eik7CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHRoZSBzcGVjaWZpZWQgY2xhc3MgbmFtZSB0byB0aGUgYnVmZmVyLiBUaGUgY2xhc3MgbWF5IHJlcHJlc2VudAorICAgICAqIGEgc2ltcGxlIHR5cGUsIGEgcmVmZXJlbmNlIHR5cGUgb3IgYW4gYXJyYXkgdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzYiBidWZmZXIKKyAgICAgKiBAcGFyYW0gb2JqIHRoZSBjbGFzcyB3aGljaCBuYW1lIHNob3VsZCBiZSBhcHBlbmRlZCB0byB0aGUgYnVmZmVyCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGFueSBvZiB0aGUgYXJndW1lbnRzIGlzIG51bGwKKyAgICAgKi8KKyAgICB2b2lkIGFwcGVuZEFycmF5VHlwZShTdHJpbmdCdWlsZGVyIHNiLCBDbGFzczw/PiBvYmopIHsKKyAgICAgICAgaW50IGRpbWVuc2lvbnMgPSAwOworICAgICAgICB3aGlsZSAob2JqLmlzQXJyYXkoKSkgeworICAgICAgICAgICAgb2JqID0gb2JqLmdldENvbXBvbmVudFR5cGUoKTsKKyAgICAgICAgICAgIGRpbWVuc2lvbnMrKzsKKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQob2JqLmdldE5hbWUoKSk7CisgICAgICAgIGZvciAoaW50IGQgPSAwOyBkIDwgZGltZW5zaW9uczsgZCsrKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIltdIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIG5hbWVzIG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkgY2xhc3NlcyB0byB0aGUgYnVmZmVyLiBUaGUgYXJyYXkKKyAgICAgKiBlbGVtZW50cyBtYXkgcmVwcmVzZW50IGEgc2ltcGxlIHR5cGUsIGEgcmVmZXJlbmNlIHR5cGUgb3IgYW4gYXJyYXkgdHlwZS4KKyAgICAgKiBPdXRwdXQgZm9ybWF0OiBqYXZhLmxhbmcuT2JqZWN0W10sIGphdmEuaW8uRmlsZSwgdm9pZAorICAgICAqCisgICAgICogQHBhcmFtIHR5cGVzIGFycmF5IG9mIGNsYXNzZXMgdG8gcHJpbnQgdGhlIG5hbWVzCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBhbnkgb2YgdGhlIGFyZ3VtZW50cyBpcyBudWxsCisgICAgICovCisgICAgdm9pZCBhcHBlbmRBcnJheUdlbmVyaWNUeXBlKFN0cmluZ0J1aWxkZXIgc2IsIFR5cGVbXSB0eXBlcykgeworICAgICAgICBpZiAodHlwZXMubGVuZ3RoID4gMCkgeworICAgICAgICAgICAgYXBwZW5kR2VuZXJpY1R5cGUoc2IsIHR5cGVzWzBdKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgdHlwZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoJywnKTsKKyAgICAgICAgICAgICAgICBhcHBlbmRHZW5lcmljVHlwZShzYiwgdHlwZXNbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyB0aGUgZ2VuZXJpYyB0eXBlIHJlcHJlc2VudGF0aW9uIHRvIHRoZSBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2IgYnVmZmVyCisgICAgICogQHBhcmFtIG9iaiB0aGUgZ2VuZXJpYyB0eXBlIHdoaWNoIHJlcHJlc2VudGF0aW9uIHNob3VsZCBiZSBhcHBlbmRlZCB0byB0aGUgYnVmZmVyCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGFueSBvZiB0aGUgYXJndW1lbnRzIGlzIG51bGwKKyAgICAgKi8KKyAgICB2b2lkIGFwcGVuZEdlbmVyaWNUeXBlKFN0cmluZ0J1aWxkZXIgc2IsIFR5cGUgb2JqKSB7CisgICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBUeXBlVmFyaWFibGUpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgoKFR5cGVWYXJpYWJsZSlvYmopLmdldE5hbWUoKSk7CisgICAgICAgIH0gZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgUGFyYW1ldGVyaXplZFR5cGUpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZChvYmoudG9TdHJpbmcoKSk7CisgICAgICAgIH0gZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgR2VuZXJpY0FycmF5VHlwZSkgeyAvL1hYWDogaXMgaXQgYSB3b3JraW5nIGJyYW5jaD8KKyAgICAgICAgICAgIFR5cGUgc2ltcGxpZmllZCA9ICgoR2VuZXJpY0FycmF5VHlwZSlvYmopLmdldEdlbmVyaWNDb21wb25lbnRUeXBlKCk7CisgICAgICAgICAgICBhcHBlbmRHZW5lcmljVHlwZShzYiwgc2ltcGxpZmllZCk7CisgICAgICAgICAgICBzYi5hcHBlbmQoIltdIik7CisgICAgICAgIH0gZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgQ2xhc3MpIHsKKyAgICAgICAgICAgIENsYXNzIGMgPSAoKENsYXNzPD8+KW9iaik7CisgICAgICAgICAgICBpZiAoYy5pc0FycmF5KCkpeworICAgICAgICAgICAgICAgIFN0cmluZyBhc1tdID0gYy5nZXROYW1lKCkuc3BsaXQoIlxcWyIpOworICAgICAgICAgICAgICAgIGludCBsZW4gPSBhcy5sZW5ndGgtMTsKKyAgICAgICAgICAgICAgICBpZiAoYXNbbGVuXS5sZW5ndGgoKSA+IDEpeworICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoYXNbbGVuXS5zdWJzdHJpbmcoMSwgYXNbbGVuXS5sZW5ndGgoKS0xKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgY2hhciBjaCA9IGFzW2xlbl0uY2hhckF0KDApOworICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJ0knKQorICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCJpbnQiKTsKKyAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY2ggPT0gJ0InKQorICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCJieXRlIik7CisgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNoID09ICdKJykKKyAgICAgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgibG9uZyIpOworICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChjaCA9PSAnRicpCisgICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoImZsb2F0Iik7CisgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNoID09ICdEJykKKyAgICAgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgiZG91YmxlIik7CisgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNoID09ICdTJykKKyAgICAgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgic2hvcnQiKTsKKyAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY2ggPT0gJ0MnKQorICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCJjaGFyIik7CisgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNoID09ICdaJykKKyAgICAgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgiYm9vbGVhbiIpOworICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChjaCA9PSAnVicpIC8vWFhYOiBpcyBpdCBhIHdvcmtpbmcgYnJhbmNoPworICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCJ2b2lkIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspeworICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIltdIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoYy5nZXROYW1lKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L0Fubm90YXRlZEVsZW1lbnQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9Bbm5vdGF0ZWRFbGVtZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTBkZTZkNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9Bbm5vdGF0ZWRFbGVtZW50LmphdmEKQEAgLTAsMCArMSw3MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcucmVmbGVjdDsKKworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb247CisKKy8qKgorICogVGhpcyBpbnRlcmZhY2UgcHJvdmlkZXMgcmVmbGVjdGl2ZSBhY2Nlc3MgdG8gYW5ub3RhdGlvbiBpbmZvcm1hdGlvbi4KKyAqCisgKiBAc2luY2UgMS41CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQW5ub3RhdGVkRWxlbWVudCB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zLCBmb3IgdGhpcyBlbGVtZW50LCB0aGUgYW5ub3RhdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgdHlwZSwgb3IKKyAgICAgKiB7QGNvZGUgbnVsbH0gaWYgbm8gYW5ub3RhdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgdHlwZSBpcyBwcmVzZW50CisgICAgICogKGluY2x1ZGluZyBpbmhlcml0ZWQgYW5ub3RhdGlvbnMpLgorICAgICAqCisgICAgICogQHBhcmFtIGFubm90YXRpb25UeXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgYW5ub3RhdGlvbiB0byBzZWFyY2ggZm9yCisgICAgICogQHJldHVybiB0aGUgYW5ub3RhdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgdHlwZSBvciB7QGNvZGUgbnVsbH0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFubm90YXRpb25UeXBlfSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKi8KKyAgICA8VCBleHRlbmRzIEFubm90YXRpb24+IFQgZ2V0QW5ub3RhdGlvbihDbGFzczxUPiBhbm5vdGF0aW9uVHlwZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zLCBmb3IgdGhpcyBlbGVtZW50LCBhbiBhcnJheSBjb250YWluaW5nIGFsbCBhbm5vdGF0aW9ucyAoaW5jbHVkaW5nCisgICAgICogaW5oZXJpdGVkIGFubm90YXRpb25zKS4gSWYgdGhlcmUgYXJlIG5vIGFubm90YXRpb25zIHByZXNlbnQsIHRoaXMgbWV0aG9kCisgICAgICogcmV0dXJucyBhIHplcm8gbGVuZ3RoIGFycmF5LgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBhbGwgYW5ub3RhdGlvbnMgZm9yIHRoaXMgZWxlbWVudAorICAgICAqLworICAgIEFubm90YXRpb25bXSBnZXRBbm5vdGF0aW9ucygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucywgZm9yIHRoaXMgZWxlbWVudCwgYWxsIGFubm90YXRpb25zIHRoYXQgYXJlIGV4cGxpY2l0bHkgZGVjbGFyZWQKKyAgICAgKiAobm90IGluaGVyaXRlZCkuIElmIHRoZXJlIGFyZSBubyBkZWNsYXJlZCBhbm5vdGF0aW9ucyBwcmVzZW50LCB0aGlzCisgICAgICogbWV0aG9kIHJldHVybnMgYSB6ZXJvIGxlbmd0aCBhcnJheS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgYW5ub3RhdGlvbnMgZGVjbGFyZWQgZm9yIHRoaXMgZWxlbWVudAorICAgICAqLworICAgIEFubm90YXRpb25bXSBnZXREZWNsYXJlZEFubm90YXRpb25zKCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhpcyBlbGVtZW50IGhhcyBhbiBhbm5vdGF0aW9uIHdpdGggdGhlCisgICAgICogc3BlY2lmaWVkIGFubm90YXRpb24gdHlwZSAoaW5jbHVkaW5nIGluaGVyaXRlZCBhbm5vdGF0aW9ucykuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYW5ub3RhdGlvblR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSBhbm5vdGF0aW9uIHRvIHNlYXJjaCBmb3IKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgYW5ub3RhdGlvbiBleGlzdHMsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhbm5vdGF0aW9uVHlwZX0gaXMge0Bjb2RlIG51bGx9CisgICAgICovCisgICAgYm9vbGVhbiBpc0Fubm90YXRpb25QcmVzZW50KENsYXNzPD8gZXh0ZW5kcyBBbm5vdGF0aW9uPiBhbm5vdGF0aW9uVHlwZSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvQXJyYXkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9BcnJheS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlY2ZhZTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvQXJyYXkuamF2YQpAQCAtMCwwICsxLDc3NiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcucmVmbGVjdDsKKworLyoqCisgKiBUaGlzIGNsYXNzIHByb3ZpZGVzIHN0YXRpYyBtZXRob2RzIHRvIGNyZWF0ZSBhbmQgYWNjZXNzIGFycmF5cyBkeW5hbWljYWxseS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEFycmF5IHsKKworICAgIC8qKgorICAgICAqIFByZXZlbnQgdGhpcyBjbGFzcyBmcm9tIGJlaW5nIGluc3RhbnRpYXRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIEFycmF5KCl7CisgICAgICAgIC8vZG8gbm90aGluZworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGVsZW1lbnQgb2YgdGhlIGFycmF5IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIFRoaXMgcmVwcm9kdWNlcworICAgICAqIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlIGFycmF5W2luZGV4XX0uIElmIHRoZSBhcnJheSBjb21wb25lbnQgaXMgYSBwcmltaXRpdmUKKyAgICAgKiB0eXBlLCB0aGUgcmVzdWx0IGlzIGF1dG9tYXRpY2FsbHkgYm94ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheQorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0ZWQgZWxlbWVudCwgcG9zc2libHkgYm94ZWQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgYXJyYXkgaXMgbnVsbAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFycmF5fSBpcyBub3QgYW4gYXJyYXkKKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSAgaW5kZXggPCAwIHx8IGluZGV4ID49IGFycmF5Lmxlbmd0aH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIE9iamVjdCBnZXQoT2JqZWN0IGFycmF5LCBpbnQgaW5kZXgpCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24geworICAgICAgICBpZiAoYXJyYXkgaW5zdGFuY2VvZiBPYmplY3RbXSkKKyAgICAgICAgICAgIHJldHVybiAoKE9iamVjdFtdKSBhcnJheSlbaW5kZXhdOworCisgICAgICAgIGlmIChhcnJheSBpbnN0YW5jZW9mIGJvb2xlYW5bXSkKKyAgICAgICAgICAgIHJldHVybiAoKGJvb2xlYW5bXSkgYXJyYXkpW2luZGV4XSA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0U7CisKKyAgICAgICAgaWYgKGFycmF5IGluc3RhbmNlb2YgYnl0ZVtdKQorICAgICAgICAgICAgcmV0dXJuIEJ5dGUudmFsdWVPZigoKGJ5dGVbXSkgYXJyYXkpW2luZGV4XSk7CisKKyAgICAgICAgaWYgKGFycmF5IGluc3RhbmNlb2YgY2hhcltdKQorICAgICAgICAgICAgcmV0dXJuIENoYXJhY3Rlci52YWx1ZU9mKCgoY2hhcltdKSBhcnJheSlbaW5kZXhdKTsKKworICAgICAgICBpZiAoYXJyYXkgaW5zdGFuY2VvZiBzaG9ydFtdKQorICAgICAgICAgICAgcmV0dXJuIFNob3J0LnZhbHVlT2YoKChzaG9ydFtdKSBhcnJheSlbaW5kZXhdKTsKKworICAgICAgICBpZiAoYXJyYXkgaW5zdGFuY2VvZiBpbnRbXSkKKyAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLnZhbHVlT2YoKChpbnRbXSkgYXJyYXkpW2luZGV4XSk7CisKKyAgICAgICAgaWYgKGFycmF5IGluc3RhbmNlb2YgbG9uZ1tdKQorICAgICAgICAgICAgcmV0dXJuIExvbmcudmFsdWVPZigoKGxvbmdbXSkgYXJyYXkpW2luZGV4XSk7CisKKyAgICAgICAgaWYgKGFycmF5IGluc3RhbmNlb2YgZmxvYXRbXSkKKyAgICAgICAgICAgIHJldHVybiBuZXcgRmxvYXQoKChmbG9hdFtdKSBhcnJheSlbaW5kZXhdKTsKKworICAgICAgICBpZiAoYXJyYXkgaW5zdGFuY2VvZiBkb3VibGVbXSkKKyAgICAgICAgICAgIHJldHVybiBuZXcgRG91YmxlKCgoZG91YmxlW10pIGFycmF5KVtpbmRleF0pOworCisgICAgICAgIGlmIChhcnJheSA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm90IGFuIGFycmF5Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZWxlbWVudCBvZiB0aGUgYXJyYXkgYXQgdGhlIHNwZWNpZmllZCBpbmRleCwgY29udmVydGVkIHRvIGEKKyAgICAgKiB7QGNvZGUgYm9vbGVhbn0sIGlmIHBvc3NpYmxlLiBUaGlzIHJlcHJvZHVjZXMgdGhlIGVmZmVjdCBvZiB7QGNvZGUKKyAgICAgKiBhcnJheVtpbmRleF19CisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheQorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0ZWQgZWxlbWVudAorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgYXJyYXl9IGlzIHtAY29kZSBudWxsfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFycmF5fSBpcyBub3QgYW4gYXJyYXkgb3IgdGhlIGVsZW1lbnQgYXQgdGhlCisgICAgICogICAgICAgICAgICAgaW5kZXggcG9zaXRpb24gY2FuIG5vdCBiZSBjb252ZXJ0ZWQgdG8gdGhlIHJldHVybiB0eXBlCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW5kZXggPCAwIHx8IGluZGV4ID49IGFycmF5Lmxlbmd0aH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZ2V0Qm9vbGVhbihPYmplY3QgYXJyYXksIGludCBpbmRleCkKKyAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhcnJheSBpbnN0YW5jZW9mIGJvb2xlYW5bXSkgeworICAgICAgICAgICAgcmV0dXJuICgoYm9vbGVhbltdKSBhcnJheSlbaW5kZXhdOworICAgICAgICB9IGVsc2UgaWYgKGFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9IGVsc2UgaWYgKGFycmF5LmdldENsYXNzKCkuaXNBcnJheSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJXcm9uZyBhcnJheSB0eXBlIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJOb3QgYW4gYXJyYXkiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGVsZW1lbnQgb2YgdGhlIGFycmF5IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXgsIGNvbnZlcnRlZCB0byBhCisgICAgICoge0Bjb2RlIGJ5dGV9LCBpZiBwb3NzaWJsZS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlCisgICAgICogYXJyYXlbaW5kZXhdfQorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleAorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVxdWVzdGVkIGVsZW1lbnQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGFycmF5fSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhcnJheX0gaXMgbm90IGFuIGFycmF5IG9yIHRoZSBlbGVtZW50IGF0IHRoZQorICAgICAqICAgICAgICAgICAgIGluZGV4IHBvc2l0aW9uIGNhbiBub3QgYmUgY29udmVydGVkIHRvIHRoZSByZXR1cm4gdHlwZQorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4IDwgMCB8fCBpbmRleCA+PSBhcnJheS5sZW5ndGh9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlIGdldEJ5dGUoT2JqZWN0IGFycmF5LCBpbnQgaW5kZXgpCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24geworICAgICAgICBpZiAoYXJyYXkgaW5zdGFuY2VvZiBieXRlW10pIHsKKyAgICAgICAgICAgIHJldHVybiAoKGJ5dGVbXSkgYXJyYXkpW2luZGV4XTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRCb29sZWFuKGFycmF5LCBpbmRleCkgPyAoYnl0ZSkxIDogKGJ5dGUpMDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGVsZW1lbnQgb2YgdGhlIGFycmF5IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXgsIGNvbnZlcnRlZCB0byBhCisgICAgICoge0Bjb2RlIGNoYXJ9LCBpZiBwb3NzaWJsZS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlCisgICAgICogYXJyYXlbaW5kZXhdfQorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleAorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVxdWVzdGVkIGVsZW1lbnQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGFycmF5fSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhcnJheX0gaXMgbm90IGFuIGFycmF5IG9yIHRoZSBlbGVtZW50IGF0IHRoZQorICAgICAqICAgICAgICAgICAgIGluZGV4IHBvc2l0aW9uIGNhbiBub3QgYmUgY29udmVydGVkIHRvIHRoZSByZXR1cm4gdHlwZQorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4IDwgMCB8fCBpbmRleCA+PSBhcnJheS5sZW5ndGh9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjaGFyIGdldENoYXIoT2JqZWN0IGFycmF5LCBpbnQgaW5kZXgpCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24geworICAgICAgICBpZiAoYXJyYXkgaW5zdGFuY2VvZiBjaGFyW10pIHsKKyAgICAgICAgICAgIHJldHVybiAoKGNoYXJbXSkgYXJyYXkpW2luZGV4XTsKKyAgICAgICAgfSBlbHNlIGlmIChhcnJheSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfSBlbHNlIGlmIChhcnJheS5nZXRDbGFzcygpLmlzQXJyYXkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiV3JvbmcgYXJyYXkgdHlwZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm90IGFuIGFycmF5Iik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50IG9mIHRoZSBhcnJheSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LCBjb252ZXJ0ZWQgdG8gYQorICAgICAqIHtAY29kZSBkb3VibGV9LCBpZiBwb3NzaWJsZS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlCisgICAgICogYXJyYXlbaW5kZXhdfQorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleAorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVxdWVzdGVkIGVsZW1lbnQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGFycmF5fSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhcnJheX0gaXMgbm90IGFuIGFycmF5IG9yIHRoZSBlbGVtZW50IGF0IHRoZQorICAgICAqICAgICAgICAgICAgIGluZGV4IHBvc2l0aW9uIGNhbiBub3QgYmUgY29udmVydGVkIHRvIHRoZSByZXR1cm4gdHlwZQorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4IDwgMCB8fCBpbmRleCA+PSBhcnJheS5sZW5ndGh9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGUgZ2V0RG91YmxlKE9iamVjdCBhcnJheSwgaW50IGluZGV4KQorICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFycmF5IGluc3RhbmNlb2YgZG91YmxlW10pIHsKKyAgICAgICAgICAgIHJldHVybiAoKGRvdWJsZVtdKSBhcnJheSlbaW5kZXhdOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIGdldEZsb2F0KGFycmF5LCBpbmRleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50IG9mIHRoZSBhcnJheSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LCBjb252ZXJ0ZWQgdG8gYQorICAgICAqIHtAY29kZSBmbG9hdH0sIGlmIHBvc3NpYmxlLiBUaGlzIHJlcHJvZHVjZXMgdGhlIGVmZmVjdCBvZiB7QGNvZGUKKyAgICAgKiBhcnJheVtpbmRleF19CisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheQorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0ZWQgZWxlbWVudAorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgYXJyYXl9IGlzIHtAY29kZSBudWxsfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFycmF5fSBpcyBub3QgYW4gYXJyYXkgb3IgdGhlIGVsZW1lbnQgYXQgdGhlCisgICAgICogICAgICAgICAgICAgaW5kZXggcG9zaXRpb24gY2FuIG5vdCBiZSBjb252ZXJ0ZWQgdG8gdGhlIHJldHVybiB0eXBlCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW5kZXggPCAwIHx8IGluZGV4ID49IGFycmF5Lmxlbmd0aH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZsb2F0IGdldEZsb2F0KE9iamVjdCBhcnJheSwgaW50IGluZGV4KQorICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFycmF5IGluc3RhbmNlb2YgZmxvYXRbXSkgeworICAgICAgICAgICAgcmV0dXJuICgoZmxvYXRbXSkgYXJyYXkpW2luZGV4XTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRMb25nKGFycmF5LCBpbmRleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50IG9mIHRoZSBhcnJheSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LCBjb252ZXJ0ZWQgdG8gYW4KKyAgICAgKiB7QGNvZGUgaW50fSwgaWYgcG9zc2libGUuIFRoaXMgcmVwcm9kdWNlcyB0aGUgZWZmZWN0IG9mIHtAY29kZQorICAgICAqIGFycmF5W2luZGV4XX0KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5CisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgKKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3RlZCBlbGVtZW50CisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBhcnJheX0gaXMge0Bjb2RlIG51bGx9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYXJyYXl9IGlzIG5vdCBhbiBhcnJheSBvciB0aGUgZWxlbWVudCBhdCB0aGUKKyAgICAgKiAgICAgICAgICAgICBpbmRleCBwb3NpdGlvbiBjYW4gbm90IGJlIGNvbnZlcnRlZCB0byB0aGUgcmV0dXJuIHR5cGUKKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBpbmRleCA8IDAgfHwgaW5kZXggPj0gYXJyYXkubGVuZ3RofQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldEludChPYmplY3QgYXJyYXksIGludCBpbmRleCkKKyAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhcnJheSBpbnN0YW5jZW9mIGludFtdKSB7CisgICAgICAgICAgICByZXR1cm4gKChpbnRbXSkgYXJyYXkpW2luZGV4XTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRTaG9ydChhcnJheSwgaW5kZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBhcnJheS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlCisgICAgICogYXJyYXkubGVuZ3RofQorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkKKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgYXJyYXkKKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGFycmF5fSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhcnJheX0gaXMgbm90IGFuIGFycmF5CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZ2V0TGVuZ3RoKE9iamVjdCBhcnJheSkgeworICAgICAgICBpZiAoYXJyYXkgaW5zdGFuY2VvZiBPYmplY3RbXSkKKyAgICAgICAgICAgIHJldHVybiAoKE9iamVjdFtdKSBhcnJheSkubGVuZ3RoOworCisgICAgICAgIGlmIChhcnJheSBpbnN0YW5jZW9mIGJvb2xlYW5bXSkKKyAgICAgICAgICAgIHJldHVybiAoKGJvb2xlYW5bXSkgYXJyYXkpLmxlbmd0aDsKKworICAgICAgICBpZiAoYXJyYXkgaW5zdGFuY2VvZiBieXRlW10pCisgICAgICAgICAgICByZXR1cm4gKChieXRlW10pIGFycmF5KS5sZW5ndGg7CisKKyAgICAgICAgaWYgKGFycmF5IGluc3RhbmNlb2YgY2hhcltdKQorICAgICAgICAgICAgcmV0dXJuICgoY2hhcltdKSBhcnJheSkubGVuZ3RoOworCisgICAgICAgIGlmIChhcnJheSBpbnN0YW5jZW9mIHNob3J0W10pCisgICAgICAgICAgICByZXR1cm4gKChzaG9ydFtdKSBhcnJheSkubGVuZ3RoOworCisgICAgICAgIGlmIChhcnJheSBpbnN0YW5jZW9mIGludFtdKQorICAgICAgICAgICAgcmV0dXJuICgoaW50W10pIGFycmF5KS5sZW5ndGg7CisKKyAgICAgICAgaWYgKGFycmF5IGluc3RhbmNlb2YgbG9uZ1tdKQorICAgICAgICAgICAgcmV0dXJuICgobG9uZ1tdKSBhcnJheSkubGVuZ3RoOworCisgICAgICAgIGlmIChhcnJheSBpbnN0YW5jZW9mIGZsb2F0W10pCisgICAgICAgICAgICByZXR1cm4gKChmbG9hdFtdKSBhcnJheSkubGVuZ3RoOworCisgICAgICAgIGlmIChhcnJheSBpbnN0YW5jZW9mIGRvdWJsZVtdKQorICAgICAgICAgICAgcmV0dXJuICgoZG91YmxlW10pIGFycmF5KS5sZW5ndGg7CisKKyAgICAgICAgaWYgKGFycmF5ID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJOb3QgYW4gYXJyYXkiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50IG9mIHRoZSBhcnJheSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LCBjb252ZXJ0ZWQgdG8gYQorICAgICAqIHtAY29kZSBsb25nfSwgaWYgcG9zc2libGUuIFRoaXMgcmVwcm9kdWNlcyB0aGUgZWZmZWN0IG9mIHtAY29kZQorICAgICAqIGFycmF5W2luZGV4XX0KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5CisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgKKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3RlZCBlbGVtZW50CisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBhcnJheX0gaXMge0Bjb2RlIG51bGx9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYXJyYXl9IGlzIG5vdCBhbiBhcnJheSBvciB0aGUgZWxlbWVudCBhdCB0aGUKKyAgICAgKiAgICAgICAgICAgICBpbmRleCBwb3NpdGlvbiBjYW4gbm90IGJlIGNvbnZlcnRlZCB0byB0aGUgcmV0dXJuIHR5cGUKKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBpbmRleCA8IDAgfHwgaW5kZXggPj0gYXJyYXkubGVuZ3RofQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBnZXRMb25nKE9iamVjdCBhcnJheSwgaW50IGluZGV4KQorICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFycmF5IGluc3RhbmNlb2YgbG9uZ1tdKSB7CisgICAgICAgICAgICByZXR1cm4gKChsb25nW10pIGFycmF5KVtpbmRleF07CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0SW50KGFycmF5LCBpbmRleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50IG9mIHRoZSBhcnJheSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LCBjb252ZXJ0ZWQgdG8gYQorICAgICAqIHtAY29kZSBzaG9ydH0sIGlmIHBvc3NpYmxlLiBUaGlzIHJlcHJvZHVjZXMgdGhlIGVmZmVjdCBvZiB7QGNvZGUKKyAgICAgKiBhcnJheVtpbmRleF19CisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheQorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0ZWQgZWxlbWVudAorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgYXJyYXl9IGlzIHtAY29kZSBudWxsfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFycmF5fSBpcyBub3QgYW4gYXJyYXkgb3IgdGhlIGVsZW1lbnQgYXQgdGhlCisgICAgICogICAgICAgICAgICAgaW5kZXggcG9zaXRpb24gY2FuIG5vdCBiZSBjb252ZXJ0ZWQgdG8gdGhlIHJldHVybiB0eXBlCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW5kZXggPCAwIHx8IGluZGV4ID49IGFycmF5Lmxlbmd0aH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHNob3J0IGdldFNob3J0KE9iamVjdCBhcnJheSwgaW50IGluZGV4KQorICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFycmF5IGluc3RhbmNlb2Ygc2hvcnRbXSkKKyAgICAgICAgICAgIHJldHVybiAoKHNob3J0W10pIGFycmF5KVtpbmRleF07CisKKyAgICAgICAgcmV0dXJuIGdldEJ5dGUoYXJyYXksIGluZGV4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IG11bHRpZGltZW5zaW9uYWwgYXJyYXkgb2YgdGhlIHNwZWNpZmllZCBjb21wb25lbnQgdHlwZSBhbmQKKyAgICAgKiBkaW1lbnNpb25zLiBUaGlzIHJlcHJvZHVjZXMgdGhlIGVmZmVjdCBvZiB7QGNvZGUgbmV3CisgICAgICogY29tcG9uZW50VHlwZVtkMF1bZDFdLi4uW2RuXX0gZm9yIGEgZGltZW5zaW9ucyBhcnJheSBvZiB7IGQwLCBkMSwgLi4uICwKKyAgICAgKiBkbiB9LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbXBvbmVudFR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb21wb25lbnQgdHlwZSBvZiB0aGUgbmV3IGFycmF5CisgICAgICogQHBhcmFtIGRpbWVuc2lvbnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkaW1lbnNpb25zIG9mIHRoZSBuZXcgYXJyYXkKKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5ldyBhcnJheQorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjb21wb25lbnQgdHlwZSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKiBAdGhyb3dzIE5lZ2F0aXZlQXJyYXlTaXplRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IG9mIHRoZSBkaW1lbnNpb25zIGFyZSBuZWdhdGl2ZQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGFycmF5IG9mIGRpbWVuc2lvbnMgaXMgb2Ygc2l6ZSB6ZXJvLCBvciBleGNlZWRzIHRoZQorICAgICAqICAgICAgICAgICAgIGxpbWl0IG9mIHRoZSBudW1iZXIgb2YgZGltZW5zaW9uIGZvciBhbiBhcnJheSAoY3VycmVudGx5IDI1NSkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIE9iamVjdCBuZXdJbnN0YW5jZShDbGFzczw/PiBjb21wb25lbnRUeXBlLCBpbnQuLi4gZGltZW5zaW9ucykKKyAgICAgICAgICAgIHRocm93cyBOZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGRpbWVuc2lvbnMubGVuZ3RoIDw9IDAgfHwgZGltZW5zaW9ucy5sZW5ndGggPiAyNTUpCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJCYWQgbnVtYmVyIG9mIGRpbWVuc2lvbnMiKTsKKworICAgICAgICBpZiAoY29tcG9uZW50VHlwZSA9PSB2b2lkLmNsYXNzKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworCisgICAgICAgIGlmIChjb21wb25lbnRUeXBlID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKworICAgICAgICByZXR1cm4gY3JlYXRlTXVsdGlBcnJheShjb21wb25lbnRUeXBlLCBkaW1lbnNpb25zKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENyZWF0ZSBhIG11bHRpLWRpbWVuc2lvbmFsIGFycmF5IG9mIG9iamVjdHMgd2l0aCB0aGUgc3BlY2lmaWVkIHR5cGUuCisgICAgICovCisgICAgbmF0aXZlIHByaXZhdGUgc3RhdGljIE9iamVjdCBjcmVhdGVNdWx0aUFycmF5KENsYXNzPD8+IGNvbXBvbmVudFR5cGUsCisgICAgICAgIGludFtdIGRpbWVuc2lvbnMpIHRocm93cyBOZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgYXJyYXkgb2YgdGhlIHNwZWNpZmllZCBjb21wb25lbnQgdHlwZSBhbmQgbGVuZ3RoLiBUaGlzCisgICAgICogcmVwcm9kdWNlcyB0aGUgZWZmZWN0IG9mIHtAY29kZSBuZXcgY29tcG9uZW50VHlwZVtzaXplXX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29tcG9uZW50VHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGNvbXBvbmVudCB0eXBlIG9mIHRoZSBuZXcgYXJyYXkKKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgbmV3IGFycmF5CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgYXJyYXkKKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY29tcG9uZW50IHR5cGUgaXMgbnVsbAorICAgICAqIEB0aHJvd3MgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc2l6ZSA8IDB9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBPYmplY3QgbmV3SW5zdGFuY2UoQ2xhc3M8Pz4gY29tcG9uZW50VHlwZSwgaW50IHNpemUpCisgICAgICAgICAgICB0aHJvd3MgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24geworICAgICAgICBpZiAoIWNvbXBvbmVudFR5cGUuaXNQcmltaXRpdmUoKSkgeworICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU9iamVjdEFycmF5KGNvbXBvbmVudFR5cGUsIHNpemUpOworICAgICAgICB9CisgICAgICAgIGlmIChjb21wb25lbnRUeXBlID09IGJvb2xlYW4uY2xhc3MpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgYm9vbGVhbltzaXplXTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY29tcG9uZW50VHlwZSA9PSBieXRlLmNsYXNzKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbc2l6ZV07CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvbXBvbmVudFR5cGUgPT0gY2hhci5jbGFzcykgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBjaGFyW3NpemVdOworICAgICAgICB9CisgICAgICAgIGlmIChjb21wb25lbnRUeXBlID09IHNob3J0LmNsYXNzKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IHNob3J0W3NpemVdOworICAgICAgICB9CisgICAgICAgIGlmIChjb21wb25lbnRUeXBlID09IGludC5jbGFzcykgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBpbnRbc2l6ZV07CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvbXBvbmVudFR5cGUgPT0gbG9uZy5jbGFzcykgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBsb25nW3NpemVdOworICAgICAgICB9CisgICAgICAgIGlmIChjb21wb25lbnRUeXBlID09IGZsb2F0LmNsYXNzKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IGZsb2F0W3NpemVdOworICAgICAgICB9CisgICAgICAgIGlmIChjb21wb25lbnRUeXBlID09IGRvdWJsZS5jbGFzcykgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBkb3VibGVbc2l6ZV07CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvbXBvbmVudFR5cGUgPT0gdm9pZC5jbGFzcykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgIH0KKworICAgIC8qCisgICAgICogQ3JlYXRlIGEgb25lLWRpbWVuc2lvbmFsIGFycmF5IG9mIG9iamVjdHMgd2l0aCB0aGUgc3BlY2lmaWVkIHR5cGUuCisgICAgICovCisgICAgbmF0aXZlIHByaXZhdGUgc3RhdGljIE9iamVjdCBjcmVhdGVPYmplY3RBcnJheShDbGFzczw/PiBjb21wb25lbnRUeXBlLAorICAgICAgICBpbnQgbGVuZ3RoKSB0aHJvd3MgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBlbGVtZW50IG9mIHRoZSBhcnJheSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IHRvIHRoZSB2YWx1ZS4gVGhpcworICAgICAqIHJlcHJvZHVjZXMgdGhlIGVmZmVjdCBvZiB7QGNvZGUgYXJyYXlbaW5kZXhdID0gdmFsdWV9LiBJZiB0aGUgYXJyYXkKKyAgICAgKiBjb21wb25lbnQgaXMgYSBwcmltaXRpdmUgdHlwZSwgdGhlIHZhbHVlIGlzIGF1dG9tYXRpY2FsbHkgdW5ib3hlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5CisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUKKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGFycmF5fSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhcnJheX0gaXMgbm90IGFuIGFycmF5IG9yIHRoZSB2YWx1ZSBjYW5ub3QgYmUKKyAgICAgKiAgICAgICAgICAgICBjb252ZXJ0ZWQgdG8gdGhlIGFycmF5IHR5cGUgYnkgYSB3aWRlbmluZyBjb252ZXJzaW9uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgIGluZGV4IDwgMCB8fCBpbmRleCA+PSBhcnJheS5sZW5ndGh9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldChPYmplY3QgYXJyYXksIGludCBpbmRleCwgT2JqZWN0IHZhbHVlKQorICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFhcnJheS5nZXRDbGFzcygpLmlzQXJyYXkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm90IGFuIGFycmF5IHR5cGUiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChhcnJheSBpbnN0YW5jZW9mIE9iamVjdFtdKSB7CisgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCAmJgorICAgICAgICAgICAgICAgICFhcnJheS5nZXRDbGFzcygpLmdldENvbXBvbmVudFR5cGUoKS5pc0luc3RhbmNlKHZhbHVlKSkgeworICAgICAgICAgICAgICAgIC8vIGluY29tcGF0aWJsZSBvYmplY3QgdHlwZSBmb3IgdGhpcyBhcnJheQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIldyb25nIGFycmF5IHR5cGUiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgKChPYmplY3RbXSkgYXJyYXkpW2luZGV4XSA9IHZhbHVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQcmltaXRpdmUgYXJyYXkgY2FuJ3QgdGFrZSBudWxsIHZhbHVlcy4iKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQm9vbGVhbikKKyAgICAgICAgICAgICAgICBzZXRCb29sZWFuKGFycmF5LCBpbmRleCwgKChCb29sZWFuKSB2YWx1ZSkuYm9vbGVhblZhbHVlKCkpOworICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBCeXRlKQorICAgICAgICAgICAgICAgIHNldEJ5dGUoYXJyYXksIGluZGV4LCAoKEJ5dGUpIHZhbHVlKS5ieXRlVmFsdWUoKSk7CisgICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIENoYXJhY3RlcikKKyAgICAgICAgICAgICAgICBzZXRDaGFyKGFycmF5LCBpbmRleCwgKChDaGFyYWN0ZXIpIHZhbHVlKS5jaGFyVmFsdWUoKSk7CisgICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFNob3J0KQorICAgICAgICAgICAgICAgIHNldFNob3J0KGFycmF5LCBpbmRleCwgKChTaG9ydCkgdmFsdWUpLnNob3J0VmFsdWUoKSk7CisgICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEludGVnZXIpCisgICAgICAgICAgICAgICAgc2V0SW50KGFycmF5LCBpbmRleCwgKChJbnRlZ2VyKSB2YWx1ZSkuaW50VmFsdWUoKSk7CisgICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExvbmcpCisgICAgICAgICAgICAgICAgc2V0TG9uZyhhcnJheSwgaW5kZXgsICgoTG9uZykgdmFsdWUpLmxvbmdWYWx1ZSgpKTsKKyAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgRmxvYXQpCisgICAgICAgICAgICAgICAgc2V0RmxvYXQoYXJyYXksIGluZGV4LCAoKEZsb2F0KSB2YWx1ZSkuZmxvYXRWYWx1ZSgpKTsKKyAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgRG91YmxlKQorICAgICAgICAgICAgICAgIHNldERvdWJsZShhcnJheSwgaW5kZXgsICgoRG91YmxlKSB2YWx1ZSkuZG91YmxlVmFsdWUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBlbGVtZW50IG9mIHRoZSBhcnJheSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IHRvIHRoZSB7QGNvZGUKKyAgICAgKiBib29sZWFufSB2YWx1ZS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlIGFycmF5W2luZGV4XSA9CisgICAgICogdmFsdWV9LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleAorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZQorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgYXJyYXl9IGlzIHtAY29kZSBudWxsfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBhcnJheX0gaXMgbm90IGFuIGFycmF5IG9yIHRoZSB2YWx1ZSBjYW5ub3QgYmUKKyAgICAgKiAgICAgICAgICAgICBjb252ZXJ0ZWQgdG8gdGhlIGFycmF5IHR5cGUgYnkgYSB3aWRlbmluZyBjb252ZXJzaW9uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgIGluZGV4IDwgMCB8fCBpbmRleCA+PSBhcnJheS5sZW5ndGh9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldEJvb2xlYW4oT2JqZWN0IGFycmF5LCBpbnQgaW5kZXgsIGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgICAgaWYgKGFycmF5IGluc3RhbmNlb2YgYm9vbGVhbltdKSB7CisgICAgICAgICAgICAoKGJvb2xlYW5bXSkgYXJyYXkpW2luZGV4XSA9IHZhbHVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc2V0Qnl0ZShhcnJheSwgaW5kZXgsIHZhbHVlID8gKGJ5dGUpMSA6IChieXRlKTApOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZWxlbWVudCBvZiB0aGUgYXJyYXkgYXQgdGhlIHNwZWNpZmllZCBpbmRleCB0byB0aGUge0Bjb2RlIGJ5dGV9CisgICAgICogdmFsdWUuIFRoaXMgcmVwcm9kdWNlcyB0aGUgZWZmZWN0IG9mIHtAY29kZSBhcnJheVtpbmRleF0gPSB2YWx1ZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheQorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4CisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBhcnJheX0gaXMge0Bjb2RlIG51bGx9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGFycmF5fSBpcyBub3QgYW4gYXJyYXkgb3IgdGhlIHZhbHVlIGNhbm5vdCBiZQorICAgICAqICAgICAgICAgICAgIGNvbnZlcnRlZCB0byB0aGUgYXJyYXkgdHlwZSBieSBhIHdpZGVuaW5nIGNvbnZlcnNpb24KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSAgaW5kZXggPCAwIHx8IGluZGV4ID49IGFycmF5Lmxlbmd0aH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0Qnl0ZShPYmplY3QgYXJyYXksIGludCBpbmRleCwgYnl0ZSB2YWx1ZSkKKyAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhcnJheSBpbnN0YW5jZW9mIGJ5dGVbXSkgeworICAgICAgICAgICAgKChieXRlW10pIGFycmF5KVtpbmRleF0gPSB2YWx1ZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHNldFNob3J0KGFycmF5LCBpbmRleCwgdmFsdWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBlbGVtZW50IG9mIHRoZSBhcnJheSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IHRvIHRoZSB7QGNvZGUgY2hhcn0KKyAgICAgKiB2YWx1ZS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlIGFycmF5W2luZGV4XSA9IHZhbHVlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5CisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUKKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGFycmF5fSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgYXJyYXl9IGlzIG5vdCBhbiBhcnJheSBvciB0aGUgdmFsdWUgY2Fubm90IGJlCisgICAgICogICAgICAgICAgICAgY29udmVydGVkIHRvIHRoZSBhcnJheSB0eXBlIGJ5IGEgd2lkZW5pbmcgY29udmVyc2lvbgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlICBpbmRleCA8IDAgfHwgaW5kZXggPj0gYXJyYXkubGVuZ3RofQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRDaGFyKE9iamVjdCBhcnJheSwgaW50IGluZGV4LCBjaGFyIHZhbHVlKQorICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFycmF5IGluc3RhbmNlb2YgY2hhcltdKSB7CisgICAgICAgICAgICAoKGNoYXJbXSkgYXJyYXkpW2luZGV4XSA9IHZhbHVlOworICAgICAgICB9IGVsc2UgaWYgKGFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9IGVsc2UgaWYgKCFhcnJheS5nZXRDbGFzcygpLmlzQXJyYXkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm90IGFuIGFycmF5Iik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJXcm9uZyBhcnJheSB0eXBlIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGVsZW1lbnQgb2YgdGhlIGFycmF5IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggdG8gdGhlIHtAY29kZSBkb3VibGV9CisgICAgICogdmFsdWUuIFRoaXMgcmVwcm9kdWNlcyB0aGUgZWZmZWN0IG9mIHtAY29kZSBhcnJheVtpbmRleF0gPSB2YWx1ZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheQorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4CisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBhcnJheX0gaXMge0Bjb2RlIG51bGx9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGFycmF5fSBpcyBub3QgYW4gYXJyYXkgb3IgdGhlIHZhbHVlIGNhbm5vdCBiZQorICAgICAqICAgICAgICAgICAgIGNvbnZlcnRlZCB0byB0aGUgYXJyYXkgdHlwZSBieSBhIHdpZGVuaW5nIGNvbnZlcnNpb24KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSAgaW5kZXggPCAwIHx8IGluZGV4ID49IGFycmF5Lmxlbmd0aH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0RG91YmxlKE9iamVjdCBhcnJheSwgaW50IGluZGV4LCBkb3VibGUgdmFsdWUpCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24geworICAgICAgICBpZiAoYXJyYXkgaW5zdGFuY2VvZiBkb3VibGVbXSkgeworICAgICAgICAgICAgKChkb3VibGVbXSkgYXJyYXkpW2luZGV4XSA9IHZhbHVlOworICAgICAgICB9IGVsc2UgaWYgKGFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9IGVsc2UgaWYgKCFhcnJheS5nZXRDbGFzcygpLmlzQXJyYXkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm90IGFuIGFycmF5Iik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJXcm9uZyBhcnJheSB0eXBlIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGVsZW1lbnQgb2YgdGhlIGFycmF5IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggdG8gdGhlIHtAY29kZSBmbG9hdH0KKyAgICAgKiB2YWx1ZS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlIGFycmF5W2luZGV4XSA9IHZhbHVlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5CisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUKKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGFycmF5fSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgYXJyYXl9IGlzIG5vdCBhbiBhcnJheSBvciB0aGUgdmFsdWUgY2Fubm90IGJlCisgICAgICogICAgICAgICAgICAgY29udmVydGVkIHRvIHRoZSBhcnJheSB0eXBlIGJ5IGEgd2lkZW5pbmcgY29udmVyc2lvbgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlICBpbmRleCA8IDAgfHwgaW5kZXggPj0gYXJyYXkubGVuZ3RofQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRGbG9hdChPYmplY3QgYXJyYXksIGludCBpbmRleCwgZmxvYXQgdmFsdWUpCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24geworICAgICAgICBpZiAoYXJyYXkgaW5zdGFuY2VvZiBmbG9hdFtdKSB7CisgICAgICAgICAgICAoKGZsb2F0W10pIGFycmF5KVtpbmRleF0gPSB2YWx1ZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHNldERvdWJsZShhcnJheSwgaW5kZXgsIHZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZWxlbWVudCBvZiB0aGUgYXJyYXkgYXQgdGhlIHNwZWNpZmllZCBpbmRleCB0byB0aGUge0Bjb2RlIGludH0KKyAgICAgKiB2YWx1ZS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlIGFycmF5W2luZGV4XSA9IHZhbHVlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5CisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUKKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGFycmF5fSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgYXJyYXl9IGlzIG5vdCBhbiBhcnJheSBvciB0aGUgdmFsdWUgY2Fubm90IGJlCisgICAgICogICAgICAgICAgICAgY29udmVydGVkIHRvIHRoZSBhcnJheSB0eXBlIGJ5IGEgd2lkZW5pbmcgY29udmVyc2lvbgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlICBpbmRleCA8IDAgfHwgaW5kZXggPj0gYXJyYXkubGVuZ3RofQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRJbnQoT2JqZWN0IGFycmF5LCBpbnQgaW5kZXgsIGludCB2YWx1ZSkKKyAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhcnJheSBpbnN0YW5jZW9mIGludFtdKSB7CisgICAgICAgICAgICAoKGludFtdKSBhcnJheSlbaW5kZXhdID0gdmFsdWU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzZXRMb25nKGFycmF5LCBpbmRleCwgdmFsdWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBlbGVtZW50IG9mIHRoZSBhcnJheSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IHRvIHRoZSB7QGNvZGUgbG9uZ30KKyAgICAgKiB2YWx1ZS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlIGFycmF5W2luZGV4XSA9IHZhbHVlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5CisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUKKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGFycmF5fSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgYXJyYXl9IGlzIG5vdCBhbiBhcnJheSBvciB0aGUgdmFsdWUgY2Fubm90IGJlCisgICAgICogICAgICAgICAgICAgY29udmVydGVkIHRvIHRoZSBhcnJheSB0eXBlIGJ5IGEgd2lkZW5pbmcgY29udmVyc2lvbgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlICBpbmRleCA8IDAgfHwgaW5kZXggPj0gYXJyYXkubGVuZ3RofQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRMb25nKE9iamVjdCBhcnJheSwgaW50IGluZGV4LCBsb25nIHZhbHVlKQorICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFycmF5IGluc3RhbmNlb2YgbG9uZ1tdKSB7CisgICAgICAgICAgICAoKGxvbmdbXSkgYXJyYXkpW2luZGV4XSA9IHZhbHVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc2V0RmxvYXQoYXJyYXksIGluZGV4LCB2YWx1ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGVsZW1lbnQgb2YgdGhlIGFycmF5IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggdG8gdGhlIHtAY29kZSBzaG9ydH0KKyAgICAgKiB2YWx1ZS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlIGFycmF5W2luZGV4XSA9IHZhbHVlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5CisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUKKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGFycmF5fSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgYXJyYXl9IGlzIG5vdCBhbiBhcnJheSBvciB0aGUgdmFsdWUgY2Fubm90IGJlCisgICAgICogICAgICAgICAgICAgY29udmVydGVkIHRvIHRoZSBhcnJheSB0eXBlIGJ5IGEgd2lkZW5pbmcgY29udmVyc2lvbgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlICBpbmRleCA8IDAgfHwgaW5kZXggPj0gYXJyYXkubGVuZ3RofQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRTaG9ydChPYmplY3QgYXJyYXksIGludCBpbmRleCwgc2hvcnQgdmFsdWUpCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24geworICAgICAgICBpZiAoYXJyYXkgaW5zdGFuY2VvZiBzaG9ydFtdKSB7CisgICAgICAgICAgICAoKHNob3J0W10pIGFycmF5KVtpbmRleF0gPSB2YWx1ZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHNldEludChhcnJheSwgaW5kZXgsIHZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L0NvbnN0cnVjdG9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvQ29uc3RydWN0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMDNlMjhiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L0NvbnN0cnVjdG9yLmphdmEKQEAgLTAsMCArMSw0NjAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5Bbm5vdGF0aW9uOworaW1wb3J0IGxpYmNvcmUudXRpbC5FbXB0eUFycmF5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5rZXJuZWwudm0uU3RyaW5nVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkubGFuZy5yZWZsZWN0LkdlbmVyaWNTaWduYXR1cmVQYXJzZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkubGFuZy5yZWZsZWN0Lkxpc3RPZlR5cGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLmxhbmcucmVmbGVjdC5UeXBlczsKKworLyoqCisgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBjb25zdHJ1Y3Rvci4gSW5mb3JtYXRpb24gYWJvdXQgdGhlIGNvbnN0cnVjdG9yIGNhbiBiZQorICogYWNjZXNzZWQsIGFuZCB0aGUgY29uc3RydWN0b3IgY2FuIGJlIGludm9rZWQgZHluYW1pY2FsbHkuCisgKgorICogQHBhcmFtIDxUPiB0aGUgY2xhc3MgdGhhdCBkZWNsYXJlcyB0aGlzIGNvbnN0cnVjdG9yCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBDb25zdHJ1Y3RvcjxUPiBleHRlbmRzIEFjY2Vzc2libGVPYmplY3QgaW1wbGVtZW50cyBHZW5lcmljRGVjbGFyYXRpb24sCisgICAgICAgIE1lbWJlciB7CisKKyAgICBDbGFzczxUPiBkZWNsYXJpbmdDbGFzczsKKworICAgIENsYXNzPD8+W10gcGFyYW1ldGVyVHlwZXM7CisKKyAgICBDbGFzczw/PltdIGV4Y2VwdGlvblR5cGVzOworCisgICAgTGlzdE9mVHlwZXMgZ2VuZXJpY0V4Y2VwdGlvblR5cGVzOworICAgIExpc3RPZlR5cGVzIGdlbmVyaWNQYXJhbWV0ZXJUeXBlczsKKyAgICBUeXBlVmFyaWFibGU8Q29uc3RydWN0b3I8VD4+W10gZm9ybWFsVHlwZVBhcmFtZXRlcnM7CisgICAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIGdlbmVyaWNUeXBlc0FyZUluaXRpYWxpemVkID0gZmFsc2U7CisKKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIGluaXRHZW5lcmljVHlwZXMoKSB7CisgICAgICAgIGlmICghZ2VuZXJpY1R5cGVzQXJlSW5pdGlhbGl6ZWQpIHsKKyAgICAgICAgICAgIFN0cmluZyBzaWduYXR1cmVBdHRyaWJ1dGUgPSBnZXRTaWduYXR1cmVBdHRyaWJ1dGUoKTsKKyAgICAgICAgICAgIEdlbmVyaWNTaWduYXR1cmVQYXJzZXIgcGFyc2VyID0gbmV3IEdlbmVyaWNTaWduYXR1cmVQYXJzZXIoCisgICAgICAgICAgICAgICAgICAgIGRlY2xhcmluZ0NsYXNzLmdldENsYXNzTG9hZGVyKCkpOworICAgICAgICAgICAgcGFyc2VyLnBhcnNlRm9yQ29uc3RydWN0b3IodGhpcywgc2lnbmF0dXJlQXR0cmlidXRlLCBleGNlcHRpb25UeXBlcyk7CisgICAgICAgICAgICBmb3JtYWxUeXBlUGFyYW1ldGVycyA9IHBhcnNlci5mb3JtYWxUeXBlUGFyYW1ldGVyczsKKyAgICAgICAgICAgIGdlbmVyaWNQYXJhbWV0ZXJUeXBlcyA9IHBhcnNlci5wYXJhbWV0ZXJUeXBlczsKKyAgICAgICAgICAgIGdlbmVyaWNFeGNlcHRpb25UeXBlcyA9IHBhcnNlci5leGNlcHRpb25UeXBlczsKKyAgICAgICAgICAgIGdlbmVyaWNUeXBlc0FyZUluaXRpYWxpemVkID0gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGludCBzbG90OworCisgICAgLyoqCisgICAgICogUHJldmVudCB0aGlzIGNsYXNzIGZyb20gYmVpbmcgaW5zdGFudGlhdGVkLgorICAgICAqLworICAgIHByaXZhdGUgQ29uc3RydWN0b3IoKXsKKyAgICAgICAgLy9kbyBub3RoaW5nCisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiB0aGUgY2xhc3MuIE9ubHkgY2FsbGVkIGZyb20gbmF0aXZlIGNvZGUsIHRodXMKKyAgICAgKiBwcml2YXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGRlY2xhcmluZ0NsYXNzCisgICAgICogICAgICAgICAgICB0aGUgY2xhc3MgdGhpcyBjb25zdHJ1Y3RvciBvYmplY3QgYmVsb25ncyB0bworICAgICAqIEBwYXJhbSBwdHlwZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgdHlwZXMgb2YgdGhlIGNvbnN0cnVjdG9yCisgICAgICogQHBhcmFtIGV4dHlwZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNlcHRpb24gdHlwZXMgb2YgdGhlIGNvbnN0cnVjdG9yCisgICAgICogQHBhcmFtIHNsb3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBzbG90IG9mIHRoZSBjb25zdHJ1Y3RvciBpbnNpZGUgdGhlIFZNIGNsYXNzIHN0cnVjdHVyZQorICAgICAqLworICAgIHByaXZhdGUgQ29uc3RydWN0b3IgKENsYXNzPFQ+IGRlY2xhcmluZ0NsYXNzLCBDbGFzczw/PltdIHB0eXBlcywgQ2xhc3M8Pz5bXSBleHR5cGVzLCBpbnQgc2xvdCl7CisgICAgICAgIHRoaXMuZGVjbGFyaW5nQ2xhc3MgPSBkZWNsYXJpbmdDbGFzczsKKyAgICAgICAgdGhpcy5wYXJhbWV0ZXJUeXBlcyA9IHB0eXBlczsKKyAgICAgICAgdGhpcy5leGNlcHRpb25UeXBlcyA9IGV4dHlwZXM7ICAgICAgICAgIC8vIG1heSBiZSBudWxsCisgICAgICAgIHRoaXMuc2xvdCA9IHNsb3Q7CisgICAgfQorCisgICAgQE92ZXJyaWRlIC8qcGFja2FnZSovIFN0cmluZyBnZXRTaWduYXR1cmVBdHRyaWJ1dGUoKSB7CisgICAgICAgIE9iamVjdFtdIGFubm90YXRpb24gPSBNZXRob2QuZ2V0U2lnbmF0dXJlQW5ub3RhdGlvbihkZWNsYXJpbmdDbGFzcywgc2xvdCk7CisKKyAgICAgICAgaWYgKGFubm90YXRpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gU3RyaW5nVXRpbHMuY29tYmluZVN0cmluZ3MoYW5ub3RhdGlvbik7CisgICAgfQorCisgICAgcHVibGljIFR5cGVWYXJpYWJsZTxDb25zdHJ1Y3RvcjxUPj5bXSBnZXRUeXBlUGFyYW1ldGVycygpIHsKKyAgICAgICAgaW5pdEdlbmVyaWNUeXBlcygpOworICAgICAgICByZXR1cm4gZm9ybWFsVHlwZVBhcmFtZXRlcnMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGNvbnN0cnVjdG9yJ3MgZGVjbGFyYXRpb24sCisgICAgICogaW5jbHVkaW5nIHRoZSB0eXBlIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGNvbnN0cnVjdG9yJ3MgZGVjbGFyYXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvR2VuZXJpY1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKDgwKTsKKyAgICAgICAgaW5pdEdlbmVyaWNUeXBlcygpOworICAgICAgICAvLyBhcHBlbmQgbW9kaWZpZXJzIGlmIGFueQorICAgICAgICBpbnQgbW9kaWZpZXIgPSBnZXRNb2RpZmllcnMoKTsKKyAgICAgICAgaWYgKG1vZGlmaWVyICE9IDApIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZChNb2RpZmllci50b1N0cmluZyhtb2RpZmllciAmIH5Nb2RpZmllci5WQVJBUkdTKSkuYXBwZW5kKCcgJyk7CisgICAgICAgIH0KKyAgICAgICAgLy8gYXBwZW5kIHR5cGUgcGFyYW1ldGVycworICAgICAgICBpZiAoZm9ybWFsVHlwZVBhcmFtZXRlcnMgIT0gbnVsbCAmJiBmb3JtYWxUeXBlUGFyYW1ldGVycy5sZW5ndGggPiAwKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoJzwnKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZm9ybWFsVHlwZVBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBhcHBlbmRHZW5lcmljVHlwZShzYiwgZm9ybWFsVHlwZVBhcmFtZXRlcnNbaV0pOworICAgICAgICAgICAgICAgIGlmIChpIDwgZm9ybWFsVHlwZVBhcmFtZXRlcnMubGVuZ3RoIC0gMSkgeworICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIiwiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzYi5hcHBlbmQoIj4gIik7CisgICAgICAgIH0KKyAgICAgICAgLy8gYXBwZW5kIGNvbnN0cnVjdG9yIG5hbWUKKyAgICAgICAgYXBwZW5kQXJyYXlUeXBlKHNiLCBnZXREZWNsYXJpbmdDbGFzcygpKTsKKyAgICAgICAgLy8gYXBwZW5kIHBhcmFtZXRlcnMKKyAgICAgICAgc2IuYXBwZW5kKCcoJyk7CisgICAgICAgIGFwcGVuZEFycmF5R2VuZXJpY1R5cGUoc2IsCisgICAgICAgICAgICAgICAgVHlwZXMuZ2V0Q2xvbmVkVHlwZUFycmF5KGdlbmVyaWNQYXJhbWV0ZXJUeXBlcykpOworICAgICAgICBzYi5hcHBlbmQoJyknKTsKKyAgICAgICAgLy8gYXBwZW5kIGV4Y2VwdGlvbnMgaWYgYW55CisgICAgICAgIFR5cGVbXSBnZW5lcmljRXhjZXB0aW9uVHlwZUFycmF5ID0KKyAgICAgICAgICAgICAgICBUeXBlcy5nZXRDbG9uZWRUeXBlQXJyYXkoZ2VuZXJpY0V4Y2VwdGlvblR5cGVzKTsKKyAgICAgICAgaWYgKGdlbmVyaWNFeGNlcHRpb25UeXBlQXJyYXkubGVuZ3RoID4gMCkgeworICAgICAgICAgICAgc2IuYXBwZW5kKCIgdGhyb3dzICIpOworICAgICAgICAgICAgYXBwZW5kQXJyYXlHZW5lcmljVHlwZShzYiwgZ2VuZXJpY0V4Y2VwdGlvblR5cGVBcnJheSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZ2VuZXJpYyBwYXJhbWV0ZXIgdHlwZXMgYXMgYW4gYXJyYXkgb2Yge0Bjb2RlIFR5cGV9CisgICAgICogaW5zdGFuY2VzLCBpbiBkZWNsYXJhdGlvbiBvcmRlci4gSWYgdGhpcyBjb25zdHJ1Y3RvciBoYXMgbm8gZ2VuZXJpYworICAgICAqIHBhcmFtZXRlcnMsIGFuIGVtcHR5IGFycmF5IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcGFyYW1ldGVyIHR5cGVzCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEdlbmVyaWNTaWduYXR1cmVGb3JtYXRFcnJvcgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBnZW5lcmljIGNvbnN0cnVjdG9yIHNpZ25hdHVyZSBpcyBpbnZhbGlkCisgICAgICogQHRocm93cyBUeXBlTm90UHJlc2VudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBwYXJhbWV0ZXIgdHlwZSBwb2ludHMgdG8gYSBtaXNzaW5nIHR5cGUKKyAgICAgKiBAdGhyb3dzIE1hbGZvcm1lZFBhcmFtZXRlcml6ZWRUeXBlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IHBhcmFtZXRlciB0eXBlIHBvaW50cyB0byBhIHR5cGUgdGhhdCBjYW5ub3QgYmUKKyAgICAgKiAgICAgICAgICAgICBpbnN0YW50aWF0ZWQgZm9yIHNvbWUgcmVhc29uCisgICAgICovCisgICAgcHVibGljIFR5cGVbXSBnZXRHZW5lcmljUGFyYW1ldGVyVHlwZXMoKSB7CisgICAgICAgIGluaXRHZW5lcmljVHlwZXMoKTsKKyAgICAgICAgcmV0dXJuIFR5cGVzLmdldENsb25lZFR5cGVBcnJheShnZW5lcmljUGFyYW1ldGVyVHlwZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGV4Y2VwdGlvbiB0eXBlcyBhcyBhbiBhcnJheSBvZiB7QGNvZGUgVHlwZX0gaW5zdGFuY2VzLiBJZgorICAgICAqIHRoaXMgY29uc3RydWN0b3IgaGFzIG5vIGRlY2xhcmVkIGV4Y2VwdGlvbnMsIGFuIGVtcHR5IGFycmF5IHdpbGwgYmUKKyAgICAgKiByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgZ2VuZXJpYyBleGNlcHRpb24gdHlwZXMKKyAgICAgKgorICAgICAqIEB0aHJvd3MgR2VuZXJpY1NpZ25hdHVyZUZvcm1hdEVycm9yCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdlbmVyaWMgY29uc3RydWN0b3Igc2lnbmF0dXJlIGlzIGludmFsaWQKKyAgICAgKiBAdGhyb3dzIFR5cGVOb3RQcmVzZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IGV4Y2VwdGlvbiB0eXBlIHBvaW50cyB0byBhIG1pc3NpbmcgdHlwZQorICAgICAqIEB0aHJvd3MgTWFsZm9ybWVkUGFyYW1ldGVyaXplZFR5cGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgZXhjZXB0aW9uIHR5cGUgcG9pbnRzIHRvIGEgdHlwZSB0aGF0IGNhbm5vdCBiZQorICAgICAqICAgICAgICAgICAgIGluc3RhbnRpYXRlZCBmb3Igc29tZSByZWFzb24KKyAgICAgKi8KKyAgICBwdWJsaWMgVHlwZVtdIGdldEdlbmVyaWNFeGNlcHRpb25UeXBlcygpIHsKKyAgICAgICAgaW5pdEdlbmVyaWNUeXBlcygpOworICAgICAgICByZXR1cm4gVHlwZXMuZ2V0Q2xvbmVkVHlwZUFycmF5KGdlbmVyaWNFeGNlcHRpb25UeXBlcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEFubm90YXRpb25bXSBnZXREZWNsYXJlZEFubm90YXRpb25zKCkgeworICAgICAgICByZXR1cm4gTWV0aG9kLmdldERlY2xhcmVkQW5ub3RhdGlvbnMoZGVjbGFyaW5nQ2xhc3MsIHNsb3QpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgPEEgZXh0ZW5kcyBBbm5vdGF0aW9uPiBBIGdldEFubm90YXRpb24oQ2xhc3M8QT4gYW5ub3RhdGlvblR5cGUpIHsKKyAgICAgICAgaWYgKGFubm90YXRpb25UeXBlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiYW5ub3RhdGlvblR5cGUgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBNZXRob2QuZ2V0QW5ub3RhdGlvbihkZWNsYXJpbmdDbGFzcywgc2xvdCwgYW5ub3RhdGlvblR5cGUpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc0Fubm90YXRpb25QcmVzZW50KENsYXNzPD8gZXh0ZW5kcyBBbm5vdGF0aW9uPiBhbm5vdGF0aW9uVHlwZSkgeworICAgICAgICBpZiAoYW5ub3RhdGlvblR5cGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJhbm5vdGF0aW9uVHlwZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIE1ldGhvZC5pc0Fubm90YXRpb25QcmVzZW50KGRlY2xhcmluZ0NsYXNzLCBzbG90LCBhbm5vdGF0aW9uVHlwZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBhcnJheXMgdGhhdCByZXByZXNlbnQgdGhlIGFubm90YXRpb25zIG9mIHRoZSBmb3JtYWwKKyAgICAgKiBwYXJhbWV0ZXJzIG9mIHRoaXMgY29uc3RydWN0b3IuIElmIHRoZXJlIGFyZSBubyBwYXJhbWV0ZXJzIG9uIHRoaXMKKyAgICAgKiBjb25zdHJ1Y3RvciwgdGhlbiBhbiBlbXB0eSBhcnJheSBpcyByZXR1cm5lZC4gSWYgdGhlcmUgYXJlIG5vIGFubm90YXRpb25zCisgICAgICogc2V0LCB0aGVuIGFuIGFycmF5IG9mIGVtcHR5IGFycmF5cyBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgYXJyYXlzIG9mIHtAY29kZSBBbm5vdGF0aW9ufSBpbnN0YW5jZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgQW5ub3RhdGlvbltdW10gZ2V0UGFyYW1ldGVyQW5ub3RhdGlvbnMoKSB7CisgICAgICAgIEFubm90YXRpb25bXVtdIHBhcmFtZXRlckFubm90YXRpb25zCisgICAgICAgICAgICAgICAgPSBNZXRob2QuZ2V0UGFyYW1ldGVyQW5ub3RhdGlvbnMoZGVjbGFyaW5nQ2xhc3MsIHNsb3QpOworICAgICAgICBpZiAocGFyYW1ldGVyQW5ub3RhdGlvbnMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBNZXRob2Qubm9Bbm5vdGF0aW9ucyhwYXJhbWV0ZXJUeXBlcy5sZW5ndGgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBwYXJhbWV0ZXJBbm5vdGF0aW9uczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhpcyBjb25zdHJ1Y3RvciB0YWtlcyBhIHZhcmlhYmxlIG51bWJlciBvZgorICAgICAqIGFyZ3VtZW50cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGEgdmFyYXJnIGlzIGRlY2xhcmUsIG90aGVyd2lzZQorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzVmFyQXJncygpIHsKKyAgICAgICAgaW50IG1vZHMgPSBNZXRob2QuZ2V0TWV0aG9kTW9kaWZpZXJzKGRlY2xhcmluZ0NsYXNzLCBzbG90KTsKKyAgICAgICAgcmV0dXJuIChtb2RzICYgTW9kaWZpZXIuVkFSQVJHUykgIT0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhpcyBjb25zdHJ1Y3RvciBpcyBzeW50aGV0aWMgKGFydGlmaWNpYWxseQorICAgICAqIGludHJvZHVjZWQgYnkgdGhlIGNvbXBpbGVyKS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgY29uc3RydWN0b3IgaXMgc3ludGhldGljLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1N5bnRoZXRpYygpIHsKKyAgICAgICAgaW50IG1vZHMgPSBNZXRob2QuZ2V0TWV0aG9kTW9kaWZpZXJzKGRlY2xhcmluZ0NsYXNzLCBzbG90KTsKKyAgICAgICAgcmV0dXJuIChtb2RzICYgTW9kaWZpZXIuU1lOVEhFVElDKSAhPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgc3BlY2lmaWVkIHtAY29kZSBvYmplY3R9IGlzIGVxdWFsIHRvIHRoaXMKKyAgICAgKiBjb25zdHJ1Y3Rvci4gVG8gYmUgZXF1YWwsIHRoZSBzcGVjaWZpZWQgb2JqZWN0IG11c3QgYmUgYW4gaW5zdGFuY2UKKyAgICAgKiBvZiB7QGNvZGUgQ29uc3RydWN0b3J9IHdpdGggdGhlIHNhbWUgZGVjbGFyaW5nIGNsYXNzIGFuZCBwYXJhbWV0ZXIgdHlwZXMKKyAgICAgKiBhcyB0aGlzIGNvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBlcXVhbCB0byB0aGlzCisgICAgICogICAgICAgICBjb25zdHJ1Y3Rvciwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKgorICAgICAqIEBzZWUgI2hhc2hDb2RlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIENvbnN0cnVjdG9yICYmIHRvU3RyaW5nKCkuZXF1YWxzKG9iamVjdC50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbGFzcyB0aGF0IGRlY2xhcmVzIHRoaXMgY29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkZWNsYXJpbmcgY2xhc3MKKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xhc3M8VD4gZ2V0RGVjbGFyaW5nQ2xhc3MoKSB7CisgICAgICAgIHJldHVybiBkZWNsYXJpbmdDbGFzczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBleGNlcHRpb24gdHlwZXMgYXMgYW4gYXJyYXkgb2Yge0Bjb2RlIENsYXNzfSBpbnN0YW5jZXMuIElmCisgICAgICogdGhpcyBjb25zdHJ1Y3RvciBoYXMgbm8gZGVjbGFyZWQgZXhjZXB0aW9ucywgYW4gZW1wdHkgYXJyYXkgd2lsbCBiZQorICAgICAqIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZGVjbGFyZWQgZXhjZXB0aW9uIGNsYXNzZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xhc3M8Pz5bXSBnZXRFeGNlcHRpb25UeXBlcygpIHsKKyAgICAgICAgaWYgKGV4Y2VwdGlvblR5cGVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBFbXB0eUFycmF5LkNMQVNTOworICAgICAgICB9CisgICAgICAgIHJldHVybiBleGNlcHRpb25UeXBlcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1vZGlmaWVycyBmb3IgdGhpcyBjb25zdHJ1Y3Rvci4gVGhlIHtAbGluayBNb2RpZmllcn0gY2xhc3MKKyAgICAgKiBzaG91bGQgYmUgdXNlZCB0byBkZWNvZGUgdGhlIHJlc3VsdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1vZGlmaWVycyBmb3IgdGhpcyBjb25zdHJ1Y3RvcgorICAgICAqCisgICAgICogQHNlZSBNb2RpZmllcgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TW9kaWZpZXJzKCkgeworICAgICAgICByZXR1cm4gTWV0aG9kLmdldE1ldGhvZE1vZGlmaWVycyhkZWNsYXJpbmdDbGFzcywgc2xvdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGlzIGNvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGlzIGNvbnN0cnVjdG9yCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gZGVjbGFyaW5nQ2xhc3MuZ2V0TmFtZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgdGhlIHtAY29kZSBDbGFzc30gb2JqZWN0cyBhc3NvY2lhdGVkIHdpdGggdGhlCisgICAgICogcGFyYW1ldGVyIHR5cGVzIG9mIHRoaXMgY29uc3RydWN0b3IuIElmIHRoZSBjb25zdHJ1Y3RvciB3YXMgZGVjbGFyZWQgd2l0aAorICAgICAqIG5vIHBhcmFtZXRlcnMsIGFuIGVtcHR5IGFycmF5IHdpbGwgYmUgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwYXJhbWV0ZXIgdHlwZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xhc3M8Pz5bXSBnZXRQYXJhbWV0ZXJUeXBlcygpIHsKKyAgICAgICAgcmV0dXJuIHBhcmFtZXRlclR5cGVzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29uc3RydWN0b3IncyBzaWduYXR1cmUgaW4gbm9uLXByaW50YWJsZSBmb3JtLiBUaGlzIGlzIGNhbGxlZAorICAgICAqIChvbmx5KSBmcm9tIElPIG5hdGl2ZSBjb2RlIGFuZCBuZWVkZWQgZm9yIGRlcml2aW5nIHRoZSBzZXJpYWxWZXJzaW9uVUlECisgICAgICogb2YgdGhlIGNsYXNzCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb25zdHJ1Y3RvcidzIHNpZ25hdHVyZQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgIHByaXZhdGUgU3RyaW5nIGdldFNpZ25hdHVyZSgpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCisgICAgICAgIHJlc3VsdC5hcHBlbmQoJygnKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJhbWV0ZXJUeXBlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChnZXRTaWduYXR1cmUocGFyYW1ldGVyVHlwZXNbaV0pKTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHQuYXBwZW5kKCIpViIpOworCisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGludGVnZXIgaGFzaCBjb2RlIGZvciB0aGlzIGNvbnN0cnVjdG9yLiBDb25zdHJ1Y3RvcnMgd2hpY2ggYXJlCisgICAgICogZXF1YWwgcmV0dXJuIHRoZSBzYW1lIHZhbHVlIGZvciB0aGlzIG1ldGhvZC4gVGhlIGhhc2ggY29kZSBmb3IgYQorICAgICAqIENvbnN0cnVjdG9yIGlzIHRoZSBoYXNoIGNvZGUgb2YgdGhlIG5hbWUgb2YgdGhlIGRlY2xhcmluZyBjbGFzcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZQorICAgICAqCisgICAgICogQHNlZSAjZXF1YWxzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIGRlY2xhcmluZ0NsYXNzLmdldE5hbWUoKS5oYXNoQ29kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGRlY2xhcmluZyBjbGFzcywgaW5pdGlhbGl6ZWQgYnkgZHluYW1pY2FsbHkKKyAgICAgKiBpbnZva2luZyB0aGUgY29uc3RydWN0b3IgcmVwcmVzZW50ZWQgYnkgdGhpcyB7QGNvZGUgQ29uc3RydWN0b3J9IG9iamVjdC4KKyAgICAgKiBUaGlzIHJlcHJvZHVjZXMgdGhlIGVmZmVjdCBvZiB7QGNvZGUgbmV3IGRlY2xhcmluZ0NsYXNzKGFyZzEsIGFyZzIsIC4uLiAsCisgICAgICogYXJnTil9IFRoaXMgbWV0aG9kIHBlcmZvcm1zIHRoZSBmb2xsb3dpbmc6CisgICAgICogPHVsPgorICAgICAqIDxsaT5BIG5ldyBpbnN0YW5jZSBvZiB0aGUgZGVjbGFyaW5nIGNsYXNzIGlzIGNyZWF0ZWQuIElmIHRoZSBkZWNsYXJpbmcKKyAgICAgKiBjbGFzcyBjYW5ub3QgYmUgaW5zdGFudGlhdGVkIChpLmUuIGFic3RyYWN0IGNsYXNzLCBhbiBpbnRlcmZhY2UsIGFuIGFycmF5CisgICAgICogdHlwZSwgb3IgYSBwcmltaXRpdmUgdHlwZSkgdGhlbiBhbiBJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGlzIHRocm93bi48L2xpPgorICAgICAqIDxsaT5JZiB0aGlzIENvbnN0cnVjdG9yIG9iamVjdCBpcyBlbmZvcmNpbmcgYWNjZXNzIGNvbnRyb2wgKHNlZQorICAgICAqIHtAbGluayBBY2Nlc3NpYmxlT2JqZWN0fSkgYW5kIHRoaXMgY29uc3RydWN0b3IgaXMgbm90IGFjY2Vzc2libGUgZnJvbSB0aGUKKyAgICAgKiBjdXJyZW50IGNvbnRleHQsIGFuIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaXMgdGhyb3duLjwvbGk+CisgICAgICogPGxpPklmIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHBhc3NlZCBhbmQgdGhlIG51bWJlciBvZiBwYXJhbWV0ZXJzIGRvIG5vdAorICAgICAqIG1hdGNoLCBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duLjwvbGk+CisgICAgICogPGxpPkZvciBlYWNoIGFyZ3VtZW50IHBhc3NlZDoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPklmIHRoZSBjb3JyZXNwb25kaW5nIHBhcmFtZXRlciB0eXBlIGlzIGEgcHJpbWl0aXZlIHR5cGUsIHRoZSBhcmd1bWVudAorICAgICAqIGlzIHVuYm94ZWQuIElmIHRoZSB1bmJveGluZyBmYWlscywgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzCisgICAgICogdGhyb3duLjwvbGk+CisgICAgICogPGxpPklmIHRoZSByZXN1bHRpbmcgYXJndW1lbnQgY2Fubm90IGJlIGNvbnZlcnRlZCB0byB0aGUgcGFyYW1ldGVyIHR5cGUKKyAgICAgKiB2aWEgYSB3aWRlbmluZyBjb252ZXJzaW9uLCBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duLjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiA8bGk+VGhlIGNvbnN0cnVjdG9yIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIENvbnN0cnVjdG9yfSBvYmplY3QgaXMKKyAgICAgKiB0aGVuIGludm9rZWQuIElmIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24gZHVyaW5nIHRoZSBpbnZvY2F0aW9uLCBpdCBpcworICAgICAqIGNhdWdodCBhbmQgd3JhcHBlZCBpbiBhbiBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uLiBUaGlzIGV4Y2VwdGlvbiBpcworICAgICAqIHRoZW4gdGhyb3duLiBJZiB0aGUgaW52b2NhdGlvbiBjb21wbGV0ZXMgbm9ybWFsbHksIHRoZSBuZXdseSBpbml0aWFsaXplZAorICAgICAqIG9iamVjdCBpcyByZXR1cm5lZC4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGFyZ3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcmd1bWVudHMgdG8gdGhlIGNvbnN0cnVjdG9yCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcsIGluaXRpYWxpemVkLCBvYmplY3QKKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gSW5zdGFudGlhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSBjbGFzcyBjYW5ub3QgYmUgaW5zdGFudGlhdGVkCisgICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhpcyBjb25zdHJ1Y3RvciBpcyBub3QgYWNjZXNzaWJsZQorICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW4gaW5jb3JyZWN0IG51bWJlciBvZiBhcmd1bWVudHMgYXJlIHBhc3NlZCwgb3IgYW4KKyAgICAgKiAgICAgICAgICAgICAgICBhcmd1bWVudCBjb3VsZCBub3QgYmUgY29udmVydGVkIGJ5IGEgd2lkZW5pbmcgY29udmVyc2lvbgorICAgICAqIEBleGNlcHRpb24gSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGFuIGV4Y2VwdGlvbiB3YXMgdGhyb3duIGJ5IHRoZSBpbnZva2VkIGNvbnN0cnVjdG9yCisgICAgICoKKyAgICAgKiBAc2VlIEFjY2Vzc2libGVPYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgVCBuZXdJbnN0YW5jZShPYmplY3QuLi4gYXJncykgdGhyb3dzIEluc3RhbnRpYXRpb25FeGNlcHRpb24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gY29uc3RydWN0TmF0aXZlIChhcmdzLCBkZWNsYXJpbmdDbGFzcywgcGFyYW1ldGVyVHlwZXMsIHNsb3QsIGZsYWcpOworICAgIH0KKworICAgIHByaXZhdGUgbmF0aXZlIFQgY29uc3RydWN0TmF0aXZlKE9iamVjdFtdIGFyZ3MsIENsYXNzPFQ+IGRlY2xhcmluZ0NsYXNzLAorICAgICAgICAgICAgQ2xhc3M8Pz5bXSBwYXJhbWV0ZXJUeXBlcywgaW50IHNsb3QsCisgICAgICAgICAgICBib29sZWFuIG5vQWNjZXNzQ2hlY2spIHRocm93cyBJbnN0YW50aWF0aW9uRXhjZXB0aW9uLCBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIGNvbmNpc2UsIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIG9mIHRoaXMKKyAgICAgKiBjb25zdHJ1Y3Rvci4gVGhlIGZvcm1hdCBvZiB0aGUgc3RyaW5nIGlzOgorICAgICAqCisgICAgICogPG9sPgorICAgICAqICAgPGxpPm1vZGlmaWVycyAoaWYgYW55KQorICAgICAqICAgPGxpPmRlY2xhcmluZyBjbGFzcyBuYW1lCisgICAgICogICA8bGk+JygnCisgICAgICogICA8bGk+cGFyYW1ldGVyIHR5cGVzLCBzZXBhcmF0ZWQgYnkgJywnIChpZiBhbnkpCisgICAgICogICA8bGk+JyknCisgICAgICogICA8bGk+J3Rocm93cycgcGx1cyBleGNlcHRpb24gdHlwZXMsIHNlcGFyYXRlZCBieSAnLCcgKGlmIGFueSkKKyAgICAgKiA8L29sPgorICAgICAqCisgICAgICogRm9yIGV4YW1wbGU6CisgICAgICoge0Bjb2RlIHB1YmxpYyBTdHJpbmcoYnl0ZVtdLFN0cmluZykgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb259CisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcHJpbnRhYmxlIHJlcHJlc2VudGF0aW9uIGZvciB0aGlzIGNvbnN0cnVjdG9yCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcihNb2RpZmllci50b1N0cmluZyhnZXRNb2RpZmllcnMoKSkpOworCisgICAgICAgIGlmIChyZXN1bHQubGVuZ3RoKCkgIT0gMCkKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJyAnKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZChkZWNsYXJpbmdDbGFzcy5nZXROYW1lKCkpOworICAgICAgICByZXN1bHQuYXBwZW5kKCIoIik7CisgICAgICAgIHJlc3VsdC5hcHBlbmQodG9TdHJpbmcocGFyYW1ldGVyVHlwZXMpKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZCgiKSIpOworICAgICAgICBpZiAoZXhjZXB0aW9uVHlwZXMgIT0gbnVsbCAmJiBleGNlcHRpb25UeXBlcy5sZW5ndGggIT0gMCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiIHRocm93cyAiKTsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQodG9TdHJpbmcoZXhjZXB0aW9uVHlwZXMpKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvRmllbGQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9GaWVsZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg3Yzk1NWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvRmllbGQuamF2YQpAQCAtMCwwICsxLDkzNCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcucmVmbGVjdDsKKworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb247CitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255Lmtlcm5lbC52bS5TdHJpbmdVdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS5sYW5nLnJlZmxlY3QuR2VuZXJpY1NpZ25hdHVyZVBhcnNlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS5sYW5nLnJlZmxlY3QuVHlwZXM7CisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgZmllbGQuIEluZm9ybWF0aW9uIGFib3V0IHRoZSBmaWVsZCBjYW4gYmUgYWNjZXNzZWQsCisgKiBhbmQgdGhlIGZpZWxkJ3MgdmFsdWUgY2FuIGJlIGFjY2Vzc2VkIGR5bmFtaWNhbGx5LgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRmllbGQgZXh0ZW5kcyBBY2Nlc3NpYmxlT2JqZWN0IGltcGxlbWVudHMgTWVtYmVyIHsKKworICAgIC8qKgorICAgICAqIE9yZGVycyBmaWVsZHMgYnkgdGhlaXIgbmFtZSBhbmQgZGVjbGFyaW5nIGNsYXNzLgorICAgICAqCisgICAgICogQGhpZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbXBhcmF0b3I8RmllbGQ+IE9SREVSX0JZX05BTUVfQU5EX0RFQ0xBUklOR19DTEFTUworICAgICAgICAgICAgPSBuZXcgQ29tcGFyYXRvcjxGaWVsZD4oKSB7CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGNvbXBhcmUoRmllbGQgYSwgRmllbGQgYikgeworICAgICAgICAgICAgaW50IGNvbXBhcmlzb24gPSBhLm5hbWUuY29tcGFyZVRvKGIubmFtZSk7CisgICAgICAgICAgICBpZiAoY29tcGFyaXNvbiAhPSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNvbXBhcmlzb247CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBhLmdldERlY2xhcmluZ0NsYXNzKCkuZ2V0TmFtZSgpLmNvbXBhcmVUbyhiLmdldERlY2xhcmluZ0NsYXNzKCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBwcml2YXRlIENsYXNzPD8+IGRlY2xhcmluZ0NsYXNzOworCisgICAgcHJpdmF0ZSBDbGFzczw/PiB0eXBlOworCisgICAgcHJpdmF0ZSBUeXBlIGdlbmVyaWNUeXBlOworCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIGdlbmVyaWNUeXBlc0FyZUluaXRpYWxpemVkID0gZmFsc2U7CisKKyAgICBwcml2YXRlIFN0cmluZyBuYW1lOworCisgICAgcHJpdmF0ZSBpbnQgc2xvdDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgVFlQRV9CT09MRUFOID0gJ1onOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhciBUWVBFX0JZVEUgPSAnQic7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIFRZUEVfQ0hBUiA9ICdDJzsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgVFlQRV9TSE9SVCA9ICdTJzsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgVFlQRV9JTlRFR0VSID0gJ0knOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhciBUWVBFX0ZMT0FUID0gJ0YnOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhciBUWVBFX0xPTkcgPSAnSic7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIFRZUEVfRE9VQkxFID0gJ0QnOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgY2xvbmUgb2YgdGhlIGdpdmVuIGluc3RhbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIG9yaWcgbm9uLW51bGw7IHRoZSBvcmlnaW5hbCBpbnN0YW5jZSB0byBjbG9uZQorICAgICAqLworICAgIC8qcGFja2FnZSovIEZpZWxkKEZpZWxkIG9yaWcpIHsKKyAgICAgICAgdGhpcyhvcmlnLmRlY2xhcmluZ0NsYXNzLCBvcmlnLnR5cGUsIG9yaWcubmFtZSwgb3JpZy5zbG90KTsKKworICAgICAgICAvLyBDb3B5IHRoZSBhY2Nlc3NpYmxlIGZsYWcuCisgICAgICAgIGlmIChvcmlnLmZsYWcpIHsKKyAgICAgICAgICAgIHRoaXMuZmxhZyA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIEZpZWxkKENsYXNzPD8+IGRlY2xhcmluZ0NsYXNzLCBDbGFzczw/PiB0eXBlLCBTdHJpbmcgbmFtZSwgaW50IHNsb3QpIHsKKyAgICAgICAgdGhpcy5kZWNsYXJpbmdDbGFzcyA9IGRlY2xhcmluZ0NsYXNzOworICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgICAgICB0aGlzLnNsb3QgPSBzbG90OworICAgIH0KKworICAgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgaW5pdEdlbmVyaWNUeXBlKCkgeworICAgICAgICBpZiAoIWdlbmVyaWNUeXBlc0FyZUluaXRpYWxpemVkKSB7CisgICAgICAgICAgICBTdHJpbmcgc2lnbmF0dXJlQXR0cmlidXRlID0gZ2V0U2lnbmF0dXJlQXR0cmlidXRlKCk7CisgICAgICAgICAgICBHZW5lcmljU2lnbmF0dXJlUGFyc2VyIHBhcnNlciA9IG5ldyBHZW5lcmljU2lnbmF0dXJlUGFyc2VyKAorICAgICAgICAgICAgICAgICAgICBkZWNsYXJpbmdDbGFzcy5nZXRDbGFzc0xvYWRlcigpKTsKKyAgICAgICAgICAgIHBhcnNlci5wYXJzZUZvckZpZWxkKHRoaXMuZGVjbGFyaW5nQ2xhc3MsIHNpZ25hdHVyZUF0dHJpYnV0ZSk7CisgICAgICAgICAgICBnZW5lcmljVHlwZSA9IHBhcnNlci5maWVsZFR5cGU7CisgICAgICAgICAgICBpZiAoZ2VuZXJpY1R5cGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGdlbmVyaWNUeXBlID0gZ2V0VHlwZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZ2VuZXJpY1R5cGVzQXJlSW5pdGlhbGl6ZWQgPSB0cnVlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqIHtAaW5oZXJpdERvY30gKi8KKyAgICBAT3ZlcnJpZGUKKyAgICAvKiBwYWNrYWdlICovU3RyaW5nIGdldFNpZ25hdHVyZUF0dHJpYnV0ZSgpIHsKKyAgICAgICAgT2JqZWN0W10gYW5ub3RhdGlvbiA9IGdldFNpZ25hdHVyZUFubm90YXRpb24oZGVjbGFyaW5nQ2xhc3MsIHNsb3QpOworCisgICAgICAgIGlmIChhbm5vdGF0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIFN0cmluZ1V0aWxzLmNvbWJpbmVTdHJpbmdzKGFubm90YXRpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgU2lnbmF0dXJlIGFubm90YXRpb24gZm9yIHRoaXMgZmllbGQuIFJldHVybnMgbnVsbCBpZiBub3QgZm91bmQuCisgICAgICovCisgICAgbmF0aXZlIHByaXZhdGUgT2JqZWN0W10gZ2V0U2lnbmF0dXJlQW5ub3RhdGlvbihDbGFzcyBkZWNsYXJpbmdDbGFzcywgaW50IHNsb3QpOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoaXMgZmllbGQgaXMgc3ludGhldGljLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBmaWVsZCBpcyBzeW50aGV0aWMsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNTeW50aGV0aWMoKSB7CisgICAgICAgIGludCBmbGFncyA9IGdldEZpZWxkTW9kaWZpZXJzKGRlY2xhcmluZ0NsYXNzLCBzbG90KTsKKyAgICAgICAgcmV0dXJuIChmbGFncyAmIE1vZGlmaWVyLlNZTlRIRVRJQykgIT0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBmaWVsZCwgaW5jbHVkaW5nIHRoZSBmaWVsZCdzCisgICAgICogZ2VuZXJpYyB0eXBlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgZmllbGQKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvR2VuZXJpY1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKDgwKTsKKyAgICAgICAgLy8gYXBwZW5kIG1vZGlmaWVycyBpZiBhbnkKKyAgICAgICAgaW50IG1vZGlmaWVyID0gZ2V0TW9kaWZpZXJzKCk7CisgICAgICAgIGlmIChtb2RpZmllciAhPSAwKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoTW9kaWZpZXIudG9TdHJpbmcobW9kaWZpZXIpKS5hcHBlbmQoJyAnKTsKKyAgICAgICAgfQorICAgICAgICAvLyBhcHBlbmQgZ2VuZXJpYyB0eXBlCisgICAgICAgIGFwcGVuZEdlbmVyaWNUeXBlKHNiLCBnZXRHZW5lcmljVHlwZSgpKTsKKyAgICAgICAgc2IuYXBwZW5kKCcgJyk7CisgICAgICAgIC8vIGFwcGVuZCBmdWxsIGZpZWxkIG5hbWUKKyAgICAgICAgc2IuYXBwZW5kKGdldERlY2xhcmluZ0NsYXNzKCkuZ2V0TmFtZSgpKS5hcHBlbmQoJy4nKS5hcHBlbmQoZ2V0TmFtZSgpKTsKKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoaXMgZmllbGQgaXMgYW4gZW51bWVyYXRpb24gY29uc3RhbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGZpZWxkIGlzIGFuIGVudW1lcmF0aW9uIGNvbnN0YW50LCB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VudW1Db25zdGFudCgpIHsKKyAgICAgICAgaW50IGZsYWdzID0gZ2V0RmllbGRNb2RpZmllcnMoZGVjbGFyaW5nQ2xhc3MsIHNsb3QpOworICAgICAgICByZXR1cm4gKGZsYWdzICYgTW9kaWZpZXIuRU5VTSkgIT0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBnZW5lcmljIHR5cGUgb2YgdGhpcyBmaWVsZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGdlbmVyaWMgdHlwZQorICAgICAqIEB0aHJvd3MgR2VuZXJpY1NpZ25hdHVyZUZvcm1hdEVycm9yCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdlbmVyaWMgZmllbGQgc2lnbmF0dXJlIGlzIGludmFsaWQKKyAgICAgKiBAdGhyb3dzIFR5cGVOb3RQcmVzZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdlbmVyaWMgdHlwZSBwb2ludHMgdG8gYSBtaXNzaW5nIHR5cGUKKyAgICAgKiBAdGhyb3dzIE1hbGZvcm1lZFBhcmFtZXRlcml6ZWRUeXBlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdlbmVyaWMgdHlwZSBwb2ludHMgdG8gYSB0eXBlIHRoYXQgY2Fubm90IGJlCisgICAgICogICAgICAgICAgICAgaW5zdGFudGlhdGVkIGZvciBzb21lIHJlYXNvbgorICAgICAqLworICAgIHB1YmxpYyBUeXBlIGdldEdlbmVyaWNUeXBlKCkgeworICAgICAgICBpbml0R2VuZXJpY1R5cGUoKTsKKyAgICAgICAgcmV0dXJuIFR5cGVzLmdldFR5cGUoZ2VuZXJpY1R5cGUpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgQW5ub3RhdGlvbltdIGdldERlY2xhcmVkQW5ub3RhdGlvbnMoKSB7CisgICAgICAgIHJldHVybiBnZXREZWNsYXJlZEFubm90YXRpb25zKGRlY2xhcmluZ0NsYXNzLCBzbG90KTsKKyAgICB9CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIEFubm90YXRpb25bXSBnZXREZWNsYXJlZEFubm90YXRpb25zKENsYXNzIGRlY2xhcmluZ0NsYXNzLCBpbnQgc2xvdCk7CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIDxBIGV4dGVuZHMgQW5ub3RhdGlvbj4gQSBnZXRBbm5vdGF0aW9uKENsYXNzPEE+IGFubm90YXRpb25UeXBlKSB7CisgICAgICAgIGlmIChhbm5vdGF0aW9uVHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImFubm90YXRpb25UeXBlID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0QW5ub3RhdGlvbihkZWNsYXJpbmdDbGFzcywgc2xvdCwgYW5ub3RhdGlvblR5cGUpOworICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgPEEgZXh0ZW5kcyBBbm5vdGF0aW9uPiBBIGdldEFubm90YXRpb24oCisgICAgICAgICAgICBDbGFzczw/PiBkZWNsYXJpbmdDbGFzcywgaW50IHNsb3QsIENsYXNzPEE+IGFubm90YXRpb25UeXBlKTsKKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc0Fubm90YXRpb25QcmVzZW50KENsYXNzPD8gZXh0ZW5kcyBBbm5vdGF0aW9uPiBhbm5vdGF0aW9uVHlwZSkgeworICAgICAgICBpZiAoYW5ub3RhdGlvblR5cGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJhbm5vdGF0aW9uVHlwZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlzQW5ub3RhdGlvblByZXNlbnQoZGVjbGFyaW5nQ2xhc3MsIHNsb3QsIGFubm90YXRpb25UeXBlKTsKKyAgICB9CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gaXNBbm5vdGF0aW9uUHJlc2VudCgKKyAgICAgICAgICAgIENsYXNzPD8+IGRlY2xhcmluZ0NsYXNzLCBpbnQgc2xvdCwgQ2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+IGFubm90YXRpb25UeXBlKTsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgc3BlY2lmaWVkIHtAY29kZSBvYmplY3R9IGlzIGVxdWFsIHRvIHRoaXMKKyAgICAgKiBmaWVsZC4gVG8gYmUgZXF1YWwsIHRoZSBzcGVjaWZpZWQgb2JqZWN0IG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YKKyAgICAgKiB7QGNvZGUgRmllbGR9IHdpdGggdGhlIHNhbWUgZGVjbGFyaW5nIGNsYXNzLCB0eXBlIGFuZCBuYW1lIGFzIHRoaXMgZmllbGQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBlcXVhbCB0byB0aGlzIG1ldGhvZCwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICogQHNlZSAjaGFzaENvZGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICByZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgRmllbGQgJiYgdG9TdHJpbmcoKS5lcXVhbHMob2JqZWN0LnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBmaWVsZCBpbiB0aGUgc3BlY2lmaWVkIG9iamVjdC4gVGhpcyByZXByb2R1Y2VzCisgICAgICogdGhlIGVmZmVjdCBvZiB7QGNvZGUgb2JqZWN0LmZpZWxkTmFtZX0KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSB0eXBlIG9mIHRoaXMgZmllbGQgaXMgYSBwcmltaXRpdmUgdHlwZSwgdGhlIGZpZWxkIHZhbHVlIGlzCisgICAgICogYXV0b21hdGljYWxseSBib3hlZC4KKyAgICAgKgorICAgICAqIDxwPklmIHRoaXMgZmllbGQgaXMgc3RhdGljLCB0aGUgb2JqZWN0IGFyZ3VtZW50IGlzIGlnbm9yZWQuCisgICAgICogT3RoZXJ3aXNlLCBpZiB0aGUgb2JqZWN0IGlzIG51bGwsIGEgTnVsbFBvaW50ZXJFeGNlcHRpb24gaXMgdGhyb3duLiBJZgorICAgICAqIHRoZSBvYmplY3QgaXMgbm90IGFuIGluc3RhbmNlIG9mIHRoZSBkZWNsYXJpbmcgY2xhc3Mgb2YgdGhlIG1ldGhvZCwgYW4KKyAgICAgKiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogPHA+SWYgdGhpcyBGaWVsZCBvYmplY3QgaXMgZW5mb3JjaW5nIGFjY2VzcyBjb250cm9sIChzZWUgQWNjZXNzaWJsZU9iamVjdCkKKyAgICAgKiBhbmQgdGhpcyBmaWVsZCBpcyBub3QgYWNjZXNzaWJsZSBmcm9tIHRoZSBjdXJyZW50IGNvbnRleHQsIGFuCisgICAgICogSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFjY2VzcworICAgICAqIEByZXR1cm4gdGhlIGZpZWxkIHZhbHVlLCBwb3NzaWJseSBib3hlZAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgb2JqZWN0IGlzIHtAY29kZSBudWxsfSBhbmQgdGhlIGZpZWxkIGlzIG5vbi1zdGF0aWMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGUgZGVjbGFyaW5nIGNsYXNzCisgICAgICogQHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBmaWVsZCBpcyBub3QgYWNjZXNzaWJsZQorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0KE9iamVjdCBvYmplY3QpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZ2V0RmllbGQob2JqZWN0LCBkZWNsYXJpbmdDbGFzcywgdHlwZSwgc2xvdCwgZmxhZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkIGluIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFzIGEge0Bjb2RlCisgICAgICogYm9vbGVhbn0uIFRoaXMgcmVwcm9kdWNlcyB0aGUgZWZmZWN0IG9mIHtAY29kZSBvYmplY3QuZmllbGROYW1lfQorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgZmllbGQgaXMgc3RhdGljLCB0aGUgb2JqZWN0IGFyZ3VtZW50IGlzIGlnbm9yZWQuCisgICAgICogT3RoZXJ3aXNlLCBpZiB0aGUgb2JqZWN0IGlzIHtAY29kZSBudWxsfSwgYSBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcworICAgICAqIHRocm93bi4gSWYgdGhlIG9iamVjdCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgdGhlIGRlY2xhcmluZyBjbGFzcyBvZiB0aGUKKyAgICAgKiBtZXRob2QsIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBGaWVsZCBvYmplY3QgaXMgZW5mb3JjaW5nIGFjY2VzcyBjb250cm9sIChzZWUgQWNjZXNzaWJsZU9iamVjdCkKKyAgICAgKiBhbmQgdGhpcyBmaWVsZCBpcyBub3QgYWNjZXNzaWJsZSBmcm9tIHRoZSBjdXJyZW50IGNvbnRleHQsIGFuCisgICAgICogSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFjY2VzcworICAgICAqIEByZXR1cm4gdGhlIGZpZWxkIHZhbHVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9IGFuZCB0aGUgZmllbGQgaXMgbm9uLXN0YXRpYworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBkZWNsYXJpbmcgY2xhc3MKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpZWxkIGlzIG5vdCBhY2Nlc3NpYmxlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0Qm9vbGVhbihPYmplY3Qgb2JqZWN0KSB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXRaRmllbGQob2JqZWN0LCBkZWNsYXJpbmdDbGFzcywgdHlwZSwgc2xvdCwgZmxhZywgVFlQRV9CT09MRUFOKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQgaW4gdGhlIHNwZWNpZmllZCBvYmplY3QgYXMgYSB7QGNvZGUgYnl0ZX0uCisgICAgICogVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlIG9iamVjdC5maWVsZE5hbWV9CisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBmaWVsZCBpcyBzdGF0aWMsIHRoZSBvYmplY3QgYXJndW1lbnQgaXMgaWdub3JlZC4KKyAgICAgKiBPdGhlcndpc2UsIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9LCBhIE51bGxQb2ludGVyRXhjZXB0aW9uIGlzCisgICAgICogdGhyb3duLiBJZiB0aGUgb2JqZWN0IGlzIG5vdCBhbiBpbnN0YW5jZSBvZiB0aGUgZGVjbGFyaW5nIGNsYXNzIG9mIHRoZQorICAgICAqIG1ldGhvZCwgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIEZpZWxkIG9iamVjdCBpcyBlbmZvcmNpbmcgYWNjZXNzIGNvbnRyb2wgKHNlZSBBY2Nlc3NpYmxlT2JqZWN0KQorICAgICAqIGFuZCB0aGlzIGZpZWxkIGlzIG5vdCBhY2Nlc3NpYmxlIGZyb20gdGhlIGN1cnJlbnQgY29udGV4dCwgYW4KKyAgICAgKiBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYWNjZXNzCisgICAgICogQHJldHVybiB0aGUgZmllbGQgdmFsdWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBpcyB7QGNvZGUgbnVsbH0gYW5kIHRoZSBmaWVsZCBpcyBub24tc3RhdGljCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgb2JqZWN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggdGhlIGRlY2xhcmluZyBjbGFzcworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgZmllbGQgaXMgbm90IGFjY2Vzc2libGUKKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZSBnZXRCeXRlKE9iamVjdCBvYmplY3QpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZ2V0QkZpZWxkKG9iamVjdCwgZGVjbGFyaW5nQ2xhc3MsIHR5cGUsIHNsb3QsIGZsYWcsIFRZUEVfQllURSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkIGluIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFzIGEge0Bjb2RlIGNoYXJ9LgorICAgICAqIFRoaXMgcmVwcm9kdWNlcyB0aGUgZWZmZWN0IG9mIHtAY29kZSBvYmplY3QuZmllbGROYW1lfQorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgZmllbGQgaXMgc3RhdGljLCB0aGUgb2JqZWN0IGFyZ3VtZW50IGlzIGlnbm9yZWQuCisgICAgICogT3RoZXJ3aXNlLCBpZiB0aGUgb2JqZWN0IGlzIHtAY29kZSBudWxsfSwgYSBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcworICAgICAqIHRocm93bi4gSWYgdGhlIG9iamVjdCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgdGhlIGRlY2xhcmluZyBjbGFzcyBvZiB0aGUKKyAgICAgKiBtZXRob2QsIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBGaWVsZCBvYmplY3QgaXMgZW5mb3JjaW5nIGFjY2VzcyBjb250cm9sIChzZWUgQWNjZXNzaWJsZU9iamVjdCkKKyAgICAgKiBhbmQgdGhpcyBmaWVsZCBpcyBub3QgYWNjZXNzaWJsZSBmcm9tIHRoZSBjdXJyZW50IGNvbnRleHQsIGFuCisgICAgICogSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFjY2VzcworICAgICAqIEByZXR1cm4gdGhlIGZpZWxkIHZhbHVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9IGFuZCB0aGUgZmllbGQgaXMgbm9uLXN0YXRpYworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBkZWNsYXJpbmcgY2xhc3MKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpZWxkIGlzIG5vdCBhY2Nlc3NpYmxlCisgICAgICovCisgICAgcHVibGljIGNoYXIgZ2V0Q2hhcihPYmplY3Qgb2JqZWN0KSB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGdldENGaWVsZChvYmplY3QsIGRlY2xhcmluZ0NsYXNzLCB0eXBlLCBzbG90LCBmbGFnLCBUWVBFX0NIQVIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNsYXNzIHRoYXQgZGVjbGFyZXMgdGhpcyBmaWVsZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGRlY2xhcmluZyBjbGFzcworICAgICAqLworICAgIHB1YmxpYyBDbGFzczw/PiBnZXREZWNsYXJpbmdDbGFzcygpIHsKKyAgICAgICAgcmV0dXJuIGRlY2xhcmluZ0NsYXNzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBmaWVsZCBpbiB0aGUgc3BlY2lmaWVkIG9iamVjdCBhcyBhIHtAY29kZQorICAgICAqIGRvdWJsZX0uIFRoaXMgcmVwcm9kdWNlcyB0aGUgZWZmZWN0IG9mIHtAY29kZSBvYmplY3QuZmllbGROYW1lfQorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgZmllbGQgaXMgc3RhdGljLCB0aGUgb2JqZWN0IGFyZ3VtZW50IGlzIGlnbm9yZWQuCisgICAgICogT3RoZXJ3aXNlLCBpZiB0aGUgb2JqZWN0IGlzIHtAY29kZSBudWxsfSwgYSBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcworICAgICAqIHRocm93bi4gSWYgdGhlIG9iamVjdCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgdGhlIGRlY2xhcmluZyBjbGFzcyBvZiB0aGUKKyAgICAgKiBtZXRob2QsIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBGaWVsZCBvYmplY3QgaXMgZW5mb3JjaW5nIGFjY2VzcyBjb250cm9sIChzZWUgQWNjZXNzaWJsZU9iamVjdCkKKyAgICAgKiBhbmQgdGhpcyBmaWVsZCBpcyBub3QgYWNjZXNzaWJsZSBmcm9tIHRoZSBjdXJyZW50IGNvbnRleHQsIGFuCisgICAgICogSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFjY2VzcworICAgICAqIEByZXR1cm4gdGhlIGZpZWxkIHZhbHVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9IGFuZCB0aGUgZmllbGQgaXMgbm9uLXN0YXRpYworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBkZWNsYXJpbmcgY2xhc3MKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpZWxkIGlzIG5vdCBhY2Nlc3NpYmxlCisgICAgICovCisgICAgcHVibGljIGRvdWJsZSBnZXREb3VibGUoT2JqZWN0IG9iamVjdCkgdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXRERmllbGQob2JqZWN0LCBkZWNsYXJpbmdDbGFzcywgdHlwZSwgc2xvdCwgZmxhZywgVFlQRV9ET1VCTEUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBmaWVsZCBpbiB0aGUgc3BlY2lmaWVkIG9iamVjdCBhcyBhIHtAY29kZSBmbG9hdH0KKyAgICAgKiAuIFRoaXMgcmVwcm9kdWNlcyB0aGUgZWZmZWN0IG9mIHtAY29kZSBvYmplY3QuZmllbGROYW1lfQorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgZmllbGQgaXMgc3RhdGljLCB0aGUgb2JqZWN0IGFyZ3VtZW50IGlzIGlnbm9yZWQuCisgICAgICogT3RoZXJ3aXNlLCBpZiB0aGUgb2JqZWN0IGlzIHtAY29kZSBudWxsfSwgYSBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcworICAgICAqIHRocm93bi4gSWYgdGhlIG9iamVjdCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgdGhlIGRlY2xhcmluZyBjbGFzcyBvZiB0aGUKKyAgICAgKiBtZXRob2QsIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBGaWVsZCBvYmplY3QgaXMgZW5mb3JjaW5nIGFjY2VzcyBjb250cm9sIChzZWUgQWNjZXNzaWJsZU9iamVjdCkKKyAgICAgKiBhbmQgdGhpcyBmaWVsZCBpcyBub3QgYWNjZXNzaWJsZSBmcm9tIHRoZSBjdXJyZW50IGNvbnRleHQsIGFuCisgICAgICogSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFjY2VzcworICAgICAqIEByZXR1cm4gdGhlIGZpZWxkIHZhbHVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9IGFuZCB0aGUgZmllbGQgaXMgbm9uLXN0YXRpYworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBkZWNsYXJpbmcgY2xhc3MKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpZWxkIGlzIG5vdCBhY2Nlc3NpYmxlCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldEZsb2F0KE9iamVjdCBvYmplY3QpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZ2V0RkZpZWxkKG9iamVjdCwgZGVjbGFyaW5nQ2xhc3MsIHR5cGUsIHNsb3QsIGZsYWcsIFRZUEVfRkxPQVQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBmaWVsZCBpbiB0aGUgc3BlY2lmaWVkIG9iamVjdCBhcyBhbiB7QGNvZGUgaW50fS4KKyAgICAgKiBUaGlzIHJlcHJvZHVjZXMgdGhlIGVmZmVjdCBvZiB7QGNvZGUgb2JqZWN0LmZpZWxkTmFtZX0KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIGZpZWxkIGlzIHN0YXRpYywgdGhlIG9iamVjdCBhcmd1bWVudCBpcyBpZ25vcmVkLgorICAgICAqIE90aGVyd2lzZSwgaWYgdGhlIG9iamVjdCBpcyB7QGNvZGUgbnVsbH0sIGEgTnVsbFBvaW50ZXJFeGNlcHRpb24gaXMKKyAgICAgKiB0aHJvd24uIElmIHRoZSBvYmplY3QgaXMgbm90IGFuIGluc3RhbmNlIG9mIHRoZSBkZWNsYXJpbmcgY2xhc3Mgb2YgdGhlCisgICAgICogbWV0aG9kLCBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgRmllbGQgb2JqZWN0IGlzIGVuZm9yY2luZyBhY2Nlc3MgY29udHJvbCAoc2VlIEFjY2Vzc2libGVPYmplY3QpCisgICAgICogYW5kIHRoaXMgZmllbGQgaXMgbm90IGFjY2Vzc2libGUgZnJvbSB0aGUgY3VycmVudCBjb250ZXh0LCBhbgorICAgICAqIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBhY2Nlc3MKKyAgICAgKiBAcmV0dXJuIHRoZSBmaWVsZCB2YWx1ZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgb2JqZWN0IGlzIHtAY29kZSBudWxsfSBhbmQgdGhlIGZpZWxkIGlzIG5vbi1zdGF0aWMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGUgZGVjbGFyaW5nIGNsYXNzCisgICAgICogQHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBmaWVsZCBpcyBub3QgYWNjZXNzaWJsZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SW50KE9iamVjdCBvYmplY3QpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZ2V0SUZpZWxkKG9iamVjdCwgZGVjbGFyaW5nQ2xhc3MsIHR5cGUsIHNsb3QsIGZsYWcsIFRZUEVfSU5URUdFUik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkIGluIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFzIGEge0Bjb2RlIGxvbmd9LgorICAgICAqIFRoaXMgcmVwcm9kdWNlcyB0aGUgZWZmZWN0IG9mIHtAY29kZSBvYmplY3QuZmllbGROYW1lfQorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgZmllbGQgaXMgc3RhdGljLCB0aGUgb2JqZWN0IGFyZ3VtZW50IGlzIGlnbm9yZWQuCisgICAgICogT3RoZXJ3aXNlLCBpZiB0aGUgb2JqZWN0IGlzIHtAY29kZSBudWxsfSwgYSBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcworICAgICAqIHRocm93bi4gSWYgdGhlIG9iamVjdCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgdGhlIGRlY2xhcmluZyBjbGFzcyBvZiB0aGUKKyAgICAgKiBtZXRob2QsIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBGaWVsZCBvYmplY3QgaXMgZW5mb3JjaW5nIGFjY2VzcyBjb250cm9sIChzZWUgQWNjZXNzaWJsZU9iamVjdCkKKyAgICAgKiBhbmQgdGhpcyBmaWVsZCBpcyBub3QgYWNjZXNzaWJsZSBmcm9tIHRoZSBjdXJyZW50IGNvbnRleHQsIGFuCisgICAgICogSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFjY2VzcworICAgICAqIEByZXR1cm4gdGhlIGZpZWxkIHZhbHVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9IGFuZCB0aGUgZmllbGQgaXMgbm9uLXN0YXRpYworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBkZWNsYXJpbmcgY2xhc3MKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpZWxkIGlzIG5vdCBhY2Nlc3NpYmxlCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0TG9uZyhPYmplY3Qgb2JqZWN0KSB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGdldEpGaWVsZChvYmplY3QsIGRlY2xhcmluZ0NsYXNzLCB0eXBlLCBzbG90LCBmbGFnLCBUWVBFX0xPTkcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1vZGlmaWVycyBmb3IgdGhpcyBmaWVsZC4gVGhlIHtAbGluayBNb2RpZmllcn0gY2xhc3Mgc2hvdWxkCisgICAgICogYmUgdXNlZCB0byBkZWNvZGUgdGhlIHJlc3VsdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1vZGlmaWVycyBmb3IgdGhpcyBmaWVsZAorICAgICAqIEBzZWUgTW9kaWZpZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1vZGlmaWVycygpIHsKKyAgICAgICAgcmV0dXJuIGdldEZpZWxkTW9kaWZpZXJzKGRlY2xhcmluZ0NsYXNzLCBzbG90KTsKKyAgICB9CisKKyAgICBwcml2YXRlIG5hdGl2ZSBpbnQgZ2V0RmllbGRNb2RpZmllcnMoQ2xhc3M8Pz4gZGVjbGFyaW5nQ2xhc3MsIGludCBzbG90KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhpcyBmaWVsZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhpcyBmaWVsZAorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkIGluIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFzIGEge0Bjb2RlIHNob3J0fQorICAgICAqIC4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlIG9iamVjdC5maWVsZE5hbWV9CisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBmaWVsZCBpcyBzdGF0aWMsIHRoZSBvYmplY3QgYXJndW1lbnQgaXMgaWdub3JlZC4KKyAgICAgKiBPdGhlcndpc2UsIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9LCBhIE51bGxQb2ludGVyRXhjZXB0aW9uIGlzCisgICAgICogdGhyb3duLiBJZiB0aGUgb2JqZWN0IGlzIG5vdCBhbiBpbnN0YW5jZSBvZiB0aGUgZGVjbGFyaW5nIGNsYXNzIG9mIHRoZQorICAgICAqIG1ldGhvZCwgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIEZpZWxkIG9iamVjdCBpcyBlbmZvcmNpbmcgYWNjZXNzIGNvbnRyb2wgKHNlZSBBY2Nlc3NpYmxlT2JqZWN0KQorICAgICAqIGFuZCB0aGlzIGZpZWxkIGlzIG5vdCBhY2Nlc3NpYmxlIGZyb20gdGhlIGN1cnJlbnQgY29udGV4dCwgYW4KKyAgICAgKiBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYWNjZXNzCisgICAgICogQHJldHVybiB0aGUgZmllbGQgdmFsdWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBpcyB7QGNvZGUgbnVsbH0gYW5kIHRoZSBmaWVsZCBpcyBub24tc3RhdGljCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgb2JqZWN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggdGhlIGRlY2xhcmluZyBjbGFzcworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgZmllbGQgaXMgbm90IGFjY2Vzc2libGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc2hvcnQgZ2V0U2hvcnQoT2JqZWN0IG9iamVjdCkgdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXRTRmllbGQob2JqZWN0LCBkZWNsYXJpbmdDbGFzcywgdHlwZSwgc2xvdCwgZmxhZywgVFlQRV9TSE9SVCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29uc3RydWN0b3IncyBzaWduYXR1cmUgaW4gbm9uLXByaW50YWJsZSBmb3JtLiBUaGlzIGlzIGNhbGxlZAorICAgICAqIChvbmx5KSBmcm9tIElPIG5hdGl2ZSBjb2RlIGFuZCBuZWVkZWQgZm9yIGRlcml2aW5nIHRoZSBzZXJpYWxWZXJzaW9uVUlECisgICAgICogb2YgdGhlIGNsYXNzCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb25zdHJ1Y3RvcidzIHNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBwcml2YXRlIFN0cmluZyBnZXRTaWduYXR1cmUoKSB7CisgICAgICAgIHJldHVybiBnZXRTaWduYXR1cmUodHlwZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSB7QGxpbmsgQ2xhc3N9IGFzc29jaWF0ZWQgd2l0aCB0aGUgdHlwZSBvZiB0aGlzIGZpZWxkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdHlwZSBvZiB0aGlzIGZpZWxkCisgICAgICovCisgICAgcHVibGljIENsYXNzPD8+IGdldFR5cGUoKSB7CisgICAgICAgIHJldHVybiB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW50ZWdlciBoYXNoIGNvZGUgZm9yIHRoaXMgZmllbGQuIE9iamVjdHMgd2hpY2ggYXJlIGVxdWFsCisgICAgICogcmV0dXJuIHRoZSBzYW1lIHZhbHVlIGZvciB0aGlzIG1ldGhvZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgaGFzaCBjb2RlIGZvciBhIEZpZWxkIGlzIHRoZSBleGNsdXNpdmUtb3IgY29tYmluYXRpb24gb2YgdGhlIGhhc2gKKyAgICAgKiBjb2RlIG9mIHRoZSBmaWVsZCdzIG5hbWUgYW5kIHRoZSBoYXNoIGNvZGUgb2YgdGhlIG5hbWUgb2YgaXRzIGRlY2xhcmluZworICAgICAqIGNsYXNzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIGZvciB0aGlzIGZpZWxkCisgICAgICogQHNlZSAjZXF1YWxzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWUuaGFzaENvZGUoKSBeIGdldERlY2xhcmluZ0NsYXNzKCkuZ2V0TmFtZSgpLmhhc2hDb2RlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkIGluIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHRvIHRoZSB2YWx1ZS4gVGhpcworICAgICAqIHJlcHJvZHVjZXMgdGhlIGVmZmVjdCBvZiB7QGNvZGUgb2JqZWN0LmZpZWxkTmFtZSA9IHZhbHVlfQorICAgICAqCisgICAgICogPHA+SWYgdGhpcyBmaWVsZCBpcyBzdGF0aWMsIHRoZSBvYmplY3QgYXJndW1lbnQgaXMgaWdub3JlZC4KKyAgICAgKiBPdGhlcndpc2UsIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9LCBhIE51bGxQb2ludGVyRXhjZXB0aW9uIGlzCisgICAgICogdGhyb3duLiBJZiB0aGUgb2JqZWN0IGlzIG5vdCBhbiBpbnN0YW5jZSBvZiB0aGUgZGVjbGFyaW5nIGNsYXNzIG9mIHRoZQorICAgICAqIG1ldGhvZCwgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIDxwPklmIHRoaXMgRmllbGQgb2JqZWN0IGlzIGVuZm9yY2luZyBhY2Nlc3MgY29udHJvbCAoc2VlIEFjY2Vzc2libGVPYmplY3QpCisgICAgICogYW5kIHRoaXMgZmllbGQgaXMgbm90IGFjY2Vzc2libGUgZnJvbSB0aGUgY3VycmVudCBjb250ZXh0LCBhbgorICAgICAqIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGZpZWxkIHR5cGUgaXMgYSBwcmltaXRpdmUgdHlwZSwgdGhlIHZhbHVlIGlzIGF1dG9tYXRpY2FsbHkKKyAgICAgKiB1bmJveGVkLiBJZiB0aGUgdW5ib3hpbmcgZmFpbHMsIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyB0aHJvd24uIElmCisgICAgICogdGhlIHZhbHVlIGNhbm5vdCBiZSBjb252ZXJ0ZWQgdG8gdGhlIGZpZWxkIHR5cGUgdmlhIGEgd2lkZW5pbmcKKyAgICAgKiBjb252ZXJzaW9uLCBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBhY2Nlc3MKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBpcyB7QGNvZGUgbnVsbH0gYW5kIHRoZSBmaWVsZCBpcyBub24tc3RhdGljCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgb2JqZWN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggdGhlIGRlY2xhcmluZyBjbGFzcworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgZmllbGQgaXMgbm90IGFjY2Vzc2libGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXQoT2JqZWN0IG9iamVjdCwgT2JqZWN0IHZhbHVlKSB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIHNldEZpZWxkKG9iamVjdCwgZGVjbGFyaW5nQ2xhc3MsIHR5cGUsIHNsb3QsIGZsYWcsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQgaW4gdGhlIHNwZWNpZmllZCBvYmplY3QgdG8gdGhlIHtAY29kZQorICAgICAqIGJvb2xlYW59IHZhbHVlLiBUaGlzIHJlcHJvZHVjZXMgdGhlIGVmZmVjdCBvZiB7QGNvZGUgb2JqZWN0LmZpZWxkTmFtZSA9CisgICAgICogdmFsdWV9CisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBmaWVsZCBpcyBzdGF0aWMsIHRoZSBvYmplY3QgYXJndW1lbnQgaXMgaWdub3JlZC4KKyAgICAgKiBPdGhlcndpc2UsIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9LCBhIE51bGxQb2ludGVyRXhjZXB0aW9uIGlzCisgICAgICogdGhyb3duLiBJZiB0aGUgb2JqZWN0IGlzIG5vdCBhbiBpbnN0YW5jZSBvZiB0aGUgZGVjbGFyaW5nIGNsYXNzIG9mIHRoZQorICAgICAqIG1ldGhvZCwgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIEZpZWxkIG9iamVjdCBpcyBlbmZvcmNpbmcgYWNjZXNzIGNvbnRyb2wgKHNlZSBBY2Nlc3NpYmxlT2JqZWN0KQorICAgICAqIGFuZCB0aGlzIGZpZWxkIGlzIG5vdCBhY2Nlc3NpYmxlIGZyb20gdGhlIGN1cnJlbnQgY29udGV4dCwgYW4KKyAgICAgKiBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgdmFsdWUgY2Fubm90IGJlIGNvbnZlcnRlZCB0byB0aGUgZmllbGQgdHlwZSB2aWEgYSB3aWRlbmluZworICAgICAqIGNvbnZlcnNpb24sIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFjY2VzcworICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgb2JqZWN0IGlzIHtAY29kZSBudWxsfSBhbmQgdGhlIGZpZWxkIGlzIG5vbi1zdGF0aWMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGUgZGVjbGFyaW5nIGNsYXNzCisgICAgICogQHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBmaWVsZCBpcyBub3QgYWNjZXNzaWJsZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJvb2xlYW4oT2JqZWN0IG9iamVjdCwgYm9vbGVhbiB2YWx1ZSkgdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBzZXRaRmllbGQob2JqZWN0LCBkZWNsYXJpbmdDbGFzcywgdHlwZSwgc2xvdCwgZmxhZywgVFlQRV9CT09MRUFOLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkIGluIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHRvIHRoZSB7QGNvZGUgYnl0ZX0KKyAgICAgKiB2YWx1ZS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlIG9iamVjdC5maWVsZE5hbWUgPSB2YWx1ZX0KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIGZpZWxkIGlzIHN0YXRpYywgdGhlIG9iamVjdCBhcmd1bWVudCBpcyBpZ25vcmVkLgorICAgICAqIE90aGVyd2lzZSwgaWYgdGhlIG9iamVjdCBpcyB7QGNvZGUgbnVsbH0sIGEgTnVsbFBvaW50ZXJFeGNlcHRpb24gaXMKKyAgICAgKiB0aHJvd24uIElmIHRoZSBvYmplY3QgaXMgbm90IGFuIGluc3RhbmNlIG9mIHRoZSBkZWNsYXJpbmcgY2xhc3Mgb2YgdGhlCisgICAgICogbWV0aG9kLCBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgRmllbGQgb2JqZWN0IGlzIGVuZm9yY2luZyBhY2Nlc3MgY29udHJvbCAoc2VlIEFjY2Vzc2libGVPYmplY3QpCisgICAgICogYW5kIHRoaXMgZmllbGQgaXMgbm90IGFjY2Vzc2libGUgZnJvbSB0aGUgY3VycmVudCBjb250ZXh0LCBhbgorICAgICAqIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSB2YWx1ZSBjYW5ub3QgYmUgY29udmVydGVkIHRvIHRoZSBmaWVsZCB0eXBlIHZpYSBhIHdpZGVuaW5nCisgICAgICogY29udmVyc2lvbiwgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYWNjZXNzCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9IGFuZCB0aGUgZmllbGQgaXMgbm9uLXN0YXRpYworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBkZWNsYXJpbmcgY2xhc3MKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpZWxkIGlzIG5vdCBhY2Nlc3NpYmxlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Qnl0ZShPYmplY3Qgb2JqZWN0LCBieXRlIHZhbHVlKSB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIHNldEJGaWVsZChvYmplY3QsIGRlY2xhcmluZ0NsYXNzLCB0eXBlLCBzbG90LCBmbGFnLCBUWVBFX0JZVEUsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQgaW4gdGhlIHNwZWNpZmllZCBvYmplY3QgdG8gdGhlIHtAY29kZSBjaGFyfQorICAgICAqIHZhbHVlLiBUaGlzIHJlcHJvZHVjZXMgdGhlIGVmZmVjdCBvZiB7QGNvZGUgb2JqZWN0LmZpZWxkTmFtZSA9IHZhbHVlfQorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgZmllbGQgaXMgc3RhdGljLCB0aGUgb2JqZWN0IGFyZ3VtZW50IGlzIGlnbm9yZWQuCisgICAgICogT3RoZXJ3aXNlLCBpZiB0aGUgb2JqZWN0IGlzIHtAY29kZSBudWxsfSwgYSBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcworICAgICAqIHRocm93bi4gSWYgdGhlIG9iamVjdCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgdGhlIGRlY2xhcmluZyBjbGFzcyBvZiB0aGUKKyAgICAgKiBtZXRob2QsIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBGaWVsZCBvYmplY3QgaXMgZW5mb3JjaW5nIGFjY2VzcyBjb250cm9sIChzZWUgQWNjZXNzaWJsZU9iamVjdCkKKyAgICAgKiBhbmQgdGhpcyBmaWVsZCBpcyBub3QgYWNjZXNzaWJsZSBmcm9tIHRoZSBjdXJyZW50IGNvbnRleHQsIGFuCisgICAgICogSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICogPHA+CisgICAgICogSWYgdGhlIHZhbHVlIGNhbm5vdCBiZSBjb252ZXJ0ZWQgdG8gdGhlIGZpZWxkIHR5cGUgdmlhIGEgd2lkZW5pbmcKKyAgICAgKiBjb252ZXJzaW9uLCBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBhY2Nlc3MKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBpcyB7QGNvZGUgbnVsbH0gYW5kIHRoZSBmaWVsZCBpcyBub24tc3RhdGljCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgb2JqZWN0IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggdGhlIGRlY2xhcmluZyBjbGFzcworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgZmllbGQgaXMgbm90IGFjY2Vzc2libGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDaGFyKE9iamVjdCBvYmplY3QsIGNoYXIgdmFsdWUpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgc2V0Q0ZpZWxkKG9iamVjdCwgZGVjbGFyaW5nQ2xhc3MsIHR5cGUsIHNsb3QsIGZsYWcsIFRZUEVfQ0hBUiwgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBmaWVsZCBpbiB0aGUgc3BlY2lmaWVkIG9iamVjdCB0byB0aGUge0Bjb2RlIGRvdWJsZX0KKyAgICAgKiB2YWx1ZS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlIG9iamVjdC5maWVsZE5hbWUgPSB2YWx1ZX0KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIGZpZWxkIGlzIHN0YXRpYywgdGhlIG9iamVjdCBhcmd1bWVudCBpcyBpZ25vcmVkLgorICAgICAqIE90aGVyd2lzZSwgaWYgdGhlIG9iamVjdCBpcyB7QGNvZGUgbnVsbH0sIGEgTnVsbFBvaW50ZXJFeGNlcHRpb24gaXMKKyAgICAgKiB0aHJvd24uIElmIHRoZSBvYmplY3QgaXMgbm90IGFuIGluc3RhbmNlIG9mIHRoZSBkZWNsYXJpbmcgY2xhc3Mgb2YgdGhlCisgICAgICogbWV0aG9kLCBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgRmllbGQgb2JqZWN0IGlzIGVuZm9yY2luZyBhY2Nlc3MgY29udHJvbCAoc2VlIEFjY2Vzc2libGVPYmplY3QpCisgICAgICogYW5kIHRoaXMgZmllbGQgaXMgbm90IGFjY2Vzc2libGUgZnJvbSB0aGUgY3VycmVudCBjb250ZXh0LCBhbgorICAgICAqIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSB2YWx1ZSBjYW5ub3QgYmUgY29udmVydGVkIHRvIHRoZSBmaWVsZCB0eXBlIHZpYSBhIHdpZGVuaW5nCisgICAgICogY29udmVyc2lvbiwgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYWNjZXNzCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9IGFuZCB0aGUgZmllbGQgaXMgbm9uLXN0YXRpYworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBkZWNsYXJpbmcgY2xhc3MKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpZWxkIGlzIG5vdCBhY2Nlc3NpYmxlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RG91YmxlKE9iamVjdCBvYmplY3QsIGRvdWJsZSB2YWx1ZSkgdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBzZXRERmllbGQob2JqZWN0LCBkZWNsYXJpbmdDbGFzcywgdHlwZSwgc2xvdCwgZmxhZywgVFlQRV9ET1VCTEUsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQgaW4gdGhlIHNwZWNpZmllZCBvYmplY3QgdG8gdGhlIHtAY29kZSBmbG9hdH0KKyAgICAgKiB2YWx1ZS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlIG9iamVjdC5maWVsZE5hbWUgPSB2YWx1ZX0KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIGZpZWxkIGlzIHN0YXRpYywgdGhlIG9iamVjdCBhcmd1bWVudCBpcyBpZ25vcmVkLgorICAgICAqIE90aGVyd2lzZSwgaWYgdGhlIG9iamVjdCBpcyB7QGNvZGUgbnVsbH0sIGEgTnVsbFBvaW50ZXJFeGNlcHRpb24gaXMKKyAgICAgKiB0aHJvd24uIElmIHRoZSBvYmplY3QgaXMgbm90IGFuIGluc3RhbmNlIG9mIHRoZSBkZWNsYXJpbmcgY2xhc3Mgb2YgdGhlCisgICAgICogbWV0aG9kLCBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgRmllbGQgb2JqZWN0IGlzIGVuZm9yY2luZyBhY2Nlc3MgY29udHJvbCAoc2VlIEFjY2Vzc2libGVPYmplY3QpCisgICAgICogYW5kIHRoaXMgZmllbGQgaXMgbm90IGFjY2Vzc2libGUgZnJvbSB0aGUgY3VycmVudCBjb250ZXh0LCBhbgorICAgICAqIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSB2YWx1ZSBjYW5ub3QgYmUgY29udmVydGVkIHRvIHRoZSBmaWVsZCB0eXBlIHZpYSBhIHdpZGVuaW5nCisgICAgICogY29udmVyc2lvbiwgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYWNjZXNzCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9IGFuZCB0aGUgZmllbGQgaXMgbm9uLXN0YXRpYworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBkZWNsYXJpbmcgY2xhc3MKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpZWxkIGlzIG5vdCBhY2Nlc3NpYmxlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RmxvYXQoT2JqZWN0IG9iamVjdCwgZmxvYXQgdmFsdWUpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgc2V0RkZpZWxkKG9iamVjdCwgZGVjbGFyaW5nQ2xhc3MsIHR5cGUsIHNsb3QsIGZsYWcsIFRZUEVfRkxPQVQsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIHRoZSBmaWVsZCBpbiB0aGUgc3BlY2lmaWVkIG9iamVjdCB0byB0aGUge0Bjb2RlIGludH0KKyAgICAgKiB2YWx1ZS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlIG9iamVjdC5maWVsZE5hbWUgPSB2YWx1ZX0KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIGZpZWxkIGlzIHN0YXRpYywgdGhlIG9iamVjdCBhcmd1bWVudCBpcyBpZ25vcmVkLgorICAgICAqIE90aGVyd2lzZSwgaWYgdGhlIG9iamVjdCBpcyB7QGNvZGUgbnVsbH0sIGEgTnVsbFBvaW50ZXJFeGNlcHRpb24gaXMKKyAgICAgKiB0aHJvd24uIElmIHRoZSBvYmplY3QgaXMgbm90IGFuIGluc3RhbmNlIG9mIHRoZSBkZWNsYXJpbmcgY2xhc3Mgb2YgdGhlCisgICAgICogbWV0aG9kLCBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgRmllbGQgb2JqZWN0IGlzIGVuZm9yY2luZyBhY2Nlc3MgY29udHJvbCAoc2VlIEFjY2Vzc2libGVPYmplY3QpCisgICAgICogYW5kIHRoaXMgZmllbGQgaXMgbm90IGFjY2Vzc2libGUgZnJvbSB0aGUgY3VycmVudCBjb250ZXh0LCBhbgorICAgICAqIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSB2YWx1ZSBjYW5ub3QgYmUgY29udmVydGVkIHRvIHRoZSBmaWVsZCB0eXBlIHZpYSBhIHdpZGVuaW5nCisgICAgICogY29udmVyc2lvbiwgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYWNjZXNzCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9IGFuZCB0aGUgZmllbGQgaXMgbm9uLXN0YXRpYworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBkZWNsYXJpbmcgY2xhc3MKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpZWxkIGlzIG5vdCBhY2Nlc3NpYmxlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SW50KE9iamVjdCBvYmplY3QsIGludCB2YWx1ZSkgdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBzZXRJRmllbGQob2JqZWN0LCBkZWNsYXJpbmdDbGFzcywgdHlwZSwgc2xvdCwgZmxhZywgVFlQRV9JTlRFR0VSLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkIGluIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHRvIHRoZSB7QGNvZGUgbG9uZ30KKyAgICAgKiB2YWx1ZS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlIG9iamVjdC5maWVsZE5hbWUgPSB2YWx1ZX0KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIGZpZWxkIGlzIHN0YXRpYywgdGhlIG9iamVjdCBhcmd1bWVudCBpcyBpZ25vcmVkLgorICAgICAqIE90aGVyd2lzZSwgaWYgdGhlIG9iamVjdCBpcyB7QGNvZGUgbnVsbH0sIGEgTnVsbFBvaW50ZXJFeGNlcHRpb24gaXMKKyAgICAgKiB0aHJvd24uIElmIHRoZSBvYmplY3QgaXMgbm90IGFuIGluc3RhbmNlIG9mIHRoZSBkZWNsYXJpbmcgY2xhc3Mgb2YgdGhlCisgICAgICogbWV0aG9kLCBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgRmllbGQgb2JqZWN0IGlzIGVuZm9yY2luZyBhY2Nlc3MgY29udHJvbCAoc2VlIEFjY2Vzc2libGVPYmplY3QpCisgICAgICogYW5kIHRoaXMgZmllbGQgaXMgbm90IGFjY2Vzc2libGUgZnJvbSB0aGUgY3VycmVudCBjb250ZXh0LCBhbgorICAgICAqIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSB2YWx1ZSBjYW5ub3QgYmUgY29udmVydGVkIHRvIHRoZSBmaWVsZCB0eXBlIHZpYSBhIHdpZGVuaW5nCisgICAgICogY29udmVyc2lvbiwgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYWNjZXNzCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9IGFuZCB0aGUgZmllbGQgaXMgbm9uLXN0YXRpYworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBkZWNsYXJpbmcgY2xhc3MKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpZWxkIGlzIG5vdCBhY2Nlc3NpYmxlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TG9uZyhPYmplY3Qgb2JqZWN0LCBsb25nIHZhbHVlKSB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIHNldEpGaWVsZChvYmplY3QsIGRlY2xhcmluZ0NsYXNzLCB0eXBlLCBzbG90LCBmbGFnLCBUWVBFX0xPTkcsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQgaW4gdGhlIHNwZWNpZmllZCBvYmplY3QgdG8gdGhlIHtAY29kZSBzaG9ydH0KKyAgICAgKiB2YWx1ZS4gVGhpcyByZXByb2R1Y2VzIHRoZSBlZmZlY3Qgb2Yge0Bjb2RlIG9iamVjdC5maWVsZE5hbWUgPSB2YWx1ZX0KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIGZpZWxkIGlzIHN0YXRpYywgdGhlIG9iamVjdCBhcmd1bWVudCBpcyBpZ25vcmVkLgorICAgICAqIE90aGVyd2lzZSwgaWYgdGhlIG9iamVjdCBpcyB7QGNvZGUgbnVsbH0sIGEgTnVsbFBvaW50ZXJFeGNlcHRpb24gaXMKKyAgICAgKiB0aHJvd24uIElmIHRoZSBvYmplY3QgaXMgbm90IGFuIGluc3RhbmNlIG9mIHRoZSBkZWNsYXJpbmcgY2xhc3Mgb2YgdGhlCisgICAgICogbWV0aG9kLCBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgRmllbGQgb2JqZWN0IGlzIGVuZm9yY2luZyBhY2Nlc3MgY29udHJvbCAoc2VlIEFjY2Vzc2libGVPYmplY3QpCisgICAgICogYW5kIHRoaXMgZmllbGQgaXMgbm90IGFjY2Vzc2libGUgZnJvbSB0aGUgY3VycmVudCBjb250ZXh0LCBhbgorICAgICAqIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSB2YWx1ZSBjYW5ub3QgYmUgY29udmVydGVkIHRvIHRoZSBmaWVsZCB0eXBlIHZpYSBhIHdpZGVuaW5nCisgICAgICogY29udmVyc2lvbiwgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYWNjZXNzCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9IGFuZCB0aGUgZmllbGQgaXMgbm9uLXN0YXRpYworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBkZWNsYXJpbmcgY2xhc3MKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGZpZWxkIGlzIG5vdCBhY2Nlc3NpYmxlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2hvcnQoT2JqZWN0IG9iamVjdCwgc2hvcnQgdmFsdWUpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgc2V0U0ZpZWxkKG9iamVjdCwgZGVjbGFyaW5nQ2xhc3MsIHR5cGUsIHNsb3QsIGZsYWcsIFRZUEVfU0hPUlQsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGlzCisgICAgICogZmllbGQuCisgICAgICogPHA+CisgICAgICogVGhlIGZvcm1hdCBvZiB0aGUgc3RyaW5nIGlzOgorICAgICAqIDxvbD4KKyAgICAgKiAgIDxsaT5tb2RpZmllcnMgKGlmIGFueSkKKyAgICAgKiAgIDxsaT50eXBlCisgICAgICogICA8bGk+ZGVjbGFyaW5nIGNsYXNzIG5hbWUKKyAgICAgKiAgIDxsaT4nLicKKyAgICAgKiAgIDxsaT5maWVsZCBuYW1lCisgICAgICogPC9vbD4KKyAgICAgKiA8cD4KKyAgICAgKiBGb3IgZXhhbXBsZToge0Bjb2RlIHB1YmxpYyBzdGF0aWMgamF2YS5pby5JbnB1dFN0cmVhbQorICAgICAqIGphdmEubGFuZy5TeXN0ZW0uaW59CisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcHJpbnRhYmxlIHJlcHJlc2VudGF0aW9uIGZvciB0aGlzIGZpZWxkCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcihNb2RpZmllci50b1N0cmluZyhnZXRNb2RpZmllcnMoKSkpOworICAgICAgICBpZiAocmVzdWx0Lmxlbmd0aCgpICE9IDApIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJyAnKTsKKyAgICAgICAgfQorICAgICAgICBhcHBlbmRBcnJheVR5cGUocmVzdWx0LCB0eXBlKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZCgnICcpOworICAgICAgICByZXN1bHQuYXBwZW5kKGRlY2xhcmluZ0NsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQoJy4nKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZChuYW1lKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgIH0KKworICAgIHByaXZhdGUgbmF0aXZlIE9iamVjdCBnZXRGaWVsZChPYmplY3QgbywgQ2xhc3M8Pz4gZGVjbGFyaW5nQ2xhc3MsIENsYXNzPD8+IHR5cGUsIGludCBzbG90LAorICAgICAgICAgICAgYm9vbGVhbiBub0FjY2Vzc0NoZWNrKSB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbjsKKworICAgIHByaXZhdGUgbmF0aXZlIGRvdWJsZSBnZXRERmllbGQoT2JqZWN0IG8sIENsYXNzPD8+IGRlY2xhcmluZ0NsYXNzLCBDbGFzczw/PiB0eXBlLCBpbnQgc2xvdCwKKyAgICAgICAgICAgIGJvb2xlYW4gbm9BY2Nlc3NDaGVjaywgY2hhciBkZXNjcmlwdG9yKSB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbjsKKworICAgIHByaXZhdGUgbmF0aXZlIGludCBnZXRJRmllbGQoT2JqZWN0IG8sIENsYXNzPD8+IGRlY2xhcmluZ0NsYXNzLCBDbGFzczw/PiB0eXBlLCBpbnQgc2xvdCwKKyAgICAgICAgICAgIGJvb2xlYW4gbm9BY2Nlc3NDaGVjaywgY2hhciBkZXNjcmlwdG9yKSB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbjsKKworICAgIHByaXZhdGUgbmF0aXZlIGxvbmcgZ2V0SkZpZWxkKE9iamVjdCBvLCBDbGFzczw/PiBkZWNsYXJpbmdDbGFzcywgQ2xhc3M8Pz4gdHlwZSwgaW50IHNsb3QsCisgICAgICAgICAgICBib29sZWFuIG5vQWNjZXNzQ2hlY2ssIGNoYXIgZGVzY3JpcHRvcikgdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb247CisKKyAgICBwcml2YXRlIG5hdGl2ZSBib29sZWFuIGdldFpGaWVsZChPYmplY3QgbywgQ2xhc3M8Pz4gZGVjbGFyaW5nQ2xhc3MsIENsYXNzPD8+IHR5cGUsIGludCBzbG90LAorICAgICAgICAgICAgYm9vbGVhbiBub0FjY2Vzc0NoZWNrLCBjaGFyIGRlc2NyaXB0b3IpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uOworCisgICAgcHJpdmF0ZSBuYXRpdmUgZmxvYXQgZ2V0RkZpZWxkKE9iamVjdCBvLCBDbGFzczw/PiBkZWNsYXJpbmdDbGFzcywgQ2xhc3M8Pz4gdHlwZSwgaW50IHNsb3QsCisgICAgICAgICAgICBib29sZWFuIG5vQWNjZXNzQ2hlY2ssIGNoYXIgZGVzY3JpcHRvcikgdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb247CisKKyAgICBwcml2YXRlIG5hdGl2ZSBjaGFyIGdldENGaWVsZChPYmplY3QgbywgQ2xhc3M8Pz4gZGVjbGFyaW5nQ2xhc3MsIENsYXNzPD8+IHR5cGUsIGludCBzbG90LAorICAgICAgICAgICAgYm9vbGVhbiBub0FjY2Vzc0NoZWNrLCBjaGFyIGRlc2NyaXB0b3IpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uOworCisgICAgcHJpdmF0ZSBuYXRpdmUgc2hvcnQgZ2V0U0ZpZWxkKE9iamVjdCBvLCBDbGFzczw/PiBkZWNsYXJpbmdDbGFzcywgQ2xhc3M8Pz4gdHlwZSwgaW50IHNsb3QsCisgICAgICAgICAgICBib29sZWFuIG5vQWNjZXNzQ2hlY2ssIGNoYXIgZGVzY3JpcHRvcikgdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb247CisKKyAgICBwcml2YXRlIG5hdGl2ZSBieXRlIGdldEJGaWVsZChPYmplY3QgbywgQ2xhc3M8Pz4gZGVjbGFyaW5nQ2xhc3MsIENsYXNzPD8+IHR5cGUsIGludCBzbG90LAorICAgICAgICAgICAgYm9vbGVhbiBub0FjY2Vzc0NoZWNrLCBjaGFyIGRlc2NyaXB0b3IpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uOworCisgICAgcHJpdmF0ZSBuYXRpdmUgdm9pZCBzZXRGaWVsZChPYmplY3QgbywgQ2xhc3M8Pz4gZGVjbGFyaW5nQ2xhc3MsIENsYXNzPD8+IHR5cGUsIGludCBzbG90LAorICAgICAgICAgICAgYm9vbGVhbiBub0FjY2Vzc0NoZWNrLCBPYmplY3QgdmFsdWUpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uOworCisgICAgcHJpdmF0ZSBuYXRpdmUgdm9pZCBzZXRERmllbGQoT2JqZWN0IG8sIENsYXNzPD8+IGRlY2xhcmluZ0NsYXNzLCBDbGFzczw/PiB0eXBlLCBpbnQgc2xvdCwKKyAgICAgICAgICAgIGJvb2xlYW4gbm9BY2Nlc3NDaGVjaywgY2hhciBkZXNjcmlwdG9yLCBkb3VibGUgdikgdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb247CisKKyAgICBwcml2YXRlIG5hdGl2ZSB2b2lkIHNldElGaWVsZChPYmplY3QgbywgQ2xhc3M8Pz4gZGVjbGFyaW5nQ2xhc3MsIENsYXNzPD8+IHR5cGUsIGludCBzbG90LAorICAgICAgICAgICAgYm9vbGVhbiBub0FjY2Vzc0NoZWNrLCBjaGFyIGRlc2NyaXB0b3IsIGludCBpKSB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbjsKKworICAgIHByaXZhdGUgbmF0aXZlIHZvaWQgc2V0SkZpZWxkKE9iamVjdCBvLCBDbGFzczw/PiBkZWNsYXJpbmdDbGFzcywgQ2xhc3M8Pz4gdHlwZSwgaW50IHNsb3QsCisgICAgICAgICAgICBib29sZWFuIG5vQWNjZXNzQ2hlY2ssIGNoYXIgZGVzY3JpcHRvciwgbG9uZyBqKSB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbjsKKworICAgIHByaXZhdGUgbmF0aXZlIHZvaWQgc2V0WkZpZWxkKE9iamVjdCBvLCBDbGFzczw/PiBkZWNsYXJpbmdDbGFzcywgQ2xhc3M8Pz4gdHlwZSwgaW50IHNsb3QsCisgICAgICAgICAgICBib29sZWFuIG5vQWNjZXNzQ2hlY2ssIGNoYXIgZGVzY3JpcHRvciwgYm9vbGVhbiB6KSB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbjsKKworICAgIHByaXZhdGUgbmF0aXZlIHZvaWQgc2V0RkZpZWxkKE9iamVjdCBvLCBDbGFzczw/PiBkZWNsYXJpbmdDbGFzcywgQ2xhc3M8Pz4gdHlwZSwgaW50IHNsb3QsCisgICAgICAgICAgICBib29sZWFuIG5vQWNjZXNzQ2hlY2ssIGNoYXIgZGVzY3JpcHRvciwgZmxvYXQgZikgdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb247CisKKyAgICBwcml2YXRlIG5hdGl2ZSB2b2lkIHNldENGaWVsZChPYmplY3QgbywgQ2xhc3M8Pz4gZGVjbGFyaW5nQ2xhc3MsIENsYXNzPD8+IHR5cGUsIGludCBzbG90LAorICAgICAgICAgICAgYm9vbGVhbiBub0FjY2Vzc0NoZWNrLCBjaGFyIGRlc2NyaXB0b3IsIGNoYXIgYykgdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb247CisKKyAgICBwcml2YXRlIG5hdGl2ZSB2b2lkIHNldFNGaWVsZChPYmplY3QgbywgQ2xhc3M8Pz4gZGVjbGFyaW5nQ2xhc3MsIENsYXNzPD8+IHR5cGUsIGludCBzbG90LAorICAgICAgICAgICAgYm9vbGVhbiBub0FjY2Vzc0NoZWNrLCBjaGFyIGRlc2NyaXB0b3IsIHNob3J0IHMpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uOworCisgICAgcHJpdmF0ZSBuYXRpdmUgdm9pZCBzZXRCRmllbGQoT2JqZWN0IG8sIENsYXNzPD8+IGRlY2xhcmluZ0NsYXNzLCBDbGFzczw/PiB0eXBlLCBpbnQgc2xvdCwKKyAgICAgICAgICAgIGJvb2xlYW4gbm9BY2Nlc3NDaGVjaywgY2hhciBkZXNjcmlwdG9yLCBieXRlIGIpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvR2VuZXJpY0FycmF5VHlwZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L0dlbmVyaWNBcnJheVR5cGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MzQ0MDE5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L0dlbmVyaWNBcnJheVR5cGUuamF2YQpAQCAtMCwwICsxLDM5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZy5yZWZsZWN0OworCisvKioKKyAqIFRoaXMgaW50ZXJmYWNlIHJlcHJlc2VudHMgYW4gYXJyYXkgdHlwZSB3aXRoIGEgY29tcG9uZW50IHR5cGUgdGhhdCBpcyBlaXRoZXIKKyAqIGEgcGFyYW1ldGVyaXplZCB0eXBlIG9yIGEgdHlwZSB2YXJpYWJsZS4KKyAqCisgKiBAc2luY2UgMS41CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgR2VuZXJpY0FycmF5VHlwZSBleHRlbmRzIFR5cGUgeworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNvbXBvbmVudCB0eXBlIG9mIHRoaXMgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb21wb25lbnQgdHlwZSBvZiB0aGlzIGFycmF5CisgICAgICoKKyAgICAgKiBAdGhyb3dzIFR5cGVOb3RQcmVzZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNvbXBvbmVudCB0eXBlIHBvaW50cyB0byBhIG1pc3NpbmcgdHlwZQorICAgICAqIEB0aHJvd3MgTWFsZm9ybWVkUGFyYW1ldGVyaXplZFR5cGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY29tcG9uZW50IHR5cGUgcG9pbnRzIHRvIGEgdHlwZSB0aGF0IGNhbm5vdCBiZQorICAgICAqICAgICAgICAgICAgIGluc3RhbnRpYXRlZCBmb3Igc29tZSByZWFzb24KKyAgICAgKi8KKyAgICBUeXBlIGdldEdlbmVyaWNDb21wb25lbnRUeXBlKCk7Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L0dlbmVyaWNEZWNsYXJhdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L0dlbmVyaWNEZWNsYXJhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNlZWRhOTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvR2VuZXJpY0RlY2xhcmF0aW9uLmphdmEKQEAgLTAsMCArMSwzNSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcucmVmbGVjdDsKKworLyoqCisgKiBDb21tb24gaW50ZXJmYWNlIGZvciBsYW5ndWFnZSBjb25zdHJ1Y3RzIHRoYXQgZGVjbGFyZSB0eXBlIHBhcmFtZXRlcnMuCisgKgorICogQHNpbmNlIDEuNQorICovCitwdWJsaWMgaW50ZXJmYWNlIEdlbmVyaWNEZWNsYXJhdGlvbiB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWNsYXJlZCB0eXBlIHBhcmFtZXRlcnMgaW4gZGVjbGFyYXRpb24gb3JkZXIuIElmIHRoZXJlIGFyZQorICAgICAqIG5vIHR5cGUgcGFyYW1ldGVycywgdGhpcyBtZXRob2QgcmV0dXJucyBhIHplcm8gbGVuZ3RoIGFycmF5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZGVjbGFyZWQgdHlwZSBwYXJhbWV0ZXJzIGluIGRlY2xhcmF0aW9uIG9yZGVyCisgICAgICogQHRocm93cyBHZW5lcmljU2lnbmF0dXJlRm9ybWF0RXJyb3IKKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2lnbmF0dXJlIGlzIG1hbGZvcm1lZAorICAgICAqLworICAgIFR5cGVWYXJpYWJsZTw/PltdIGdldFR5cGVQYXJhbWV0ZXJzKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvR2VuZXJpY1NpZ25hdHVyZUZvcm1hdEVycm9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvR2VuZXJpY1NpZ25hdHVyZUZvcm1hdEVycm9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2Y0NGFmNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9HZW5lcmljU2lnbmF0dXJlRm9ybWF0RXJyb3IuamF2YQpAQCAtMCwwICsxLDM1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZy5yZWZsZWN0OworCisvKioKKyAqIEluZGljYXRlcyB0aGF0IGEgbWFsZm9ybWVkIHNpZ25hdHVyZSBoYXMgYmVlbiBlbmNvdW50ZXJlZCB2aWEgYSByZWZsZWN0aXZlCisgKiBtZXRob2QuCisgKgorICogQHNpbmNlIDEuNQorICovCitwdWJsaWMgY2xhc3MgR2VuZXJpY1NpZ25hdHVyZUZvcm1hdEVycm9yIGV4dGVuZHMgQ2xhc3NGb3JtYXRFcnJvciB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA2NzA5OTE5MTQ3MTM3OTExMDM0TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEdlbmVyaWNTaWduYXR1cmVGb3JtYXRFcnJvcn0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIEdlbmVyaWNTaWduYXR1cmVGb3JtYXRFcnJvcigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvbkhhbmRsZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9JbnZvY2F0aW9uSGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMzMDkwNGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvbkhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDYwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZy5yZWZsZWN0OworCisvKioKKyAqIEltcGxlbWVudG9ycyBvZiB0aGlzIGludGVyZmFjZSBkaXNwYXRjaCBtZXRob2RzIGludm9rZWQgb24gcHJveHkgaW5zdGFuY2VzLgorICoKKyAqIEBzZWUgUHJveHkKKyAqLworcHVibGljIGludGVyZmFjZSBJbnZvY2F0aW9uSGFuZGxlciB7CisKKyAgICAvKioKKyAgICAgKiBIYW5kbGVzIHRoZSBtZXRob2Qgd2hpY2ggd2FzIG9yaWdpbmFsbHkgaW52b2tlZCBvbiB0aGUgcHJveHkgaW5zdGFuY2UuIEEKKyAgICAgKiB0eXBpY2FsIHVzYWdlIHBhdHRlcm4gZm9sbG93cyBiZWxvdzoKKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogcHVibGljIE9iamVjdCBpbnZva2UoT2JqZWN0IHByb3h5LCBNZXRob2QgbWV0aG9kLCBPYmplY3RbXSBhcmdzKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgKiAgICAgLy9kbyBzb21lIHByb2Nlc3NpbmcgYmVmb3JlIHRoZSBtZXRob2QgaW52b2NhdGlvbgorICAgICAqCisgICAgICogICAgIC8vaW52b2tlIHRoZSBtZXRob2QKKyAgICAgKiAgICAgT2JqZWN0IHJlc3VsdCA9IG1ldGhvZC5pbnZva2UocHJveHksIGFyZ3MpOworICAgICAqCisgICAgICogICAgIC8vZG8gc29tZSBwcm9jZXNzaW5nIGFmdGVyIHRoZSBtZXRob2QgaW52b2NhdGlvbgorICAgICAqICAgICByZXR1cm4gcmVzdWx0OworICAgICAqIH08L3ByZT4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcm94eQorICAgICAqICAgICAgICAgICAgdGhlIHByb3h5IGluc3RhbmNlIG9uIHdoaWNoIHRoZSBtZXRob2Qgd2FzIGludm9rZWQKKyAgICAgKiBAcGFyYW0gbWV0aG9kCisgICAgICogICAgICAgICAgICB0aGUgbWV0aG9kIGludm9rZWQgb24gdGhlIHByb3h5IGluc3RhbmNlCisgICAgICogQHBhcmFtIGFyZ3MKKyAgICAgKiAgICAgICAgICAgIGFuIGFycmF5IG9mIG9iamVjdHMgY29udGFpbmluZyB0aGUgcGFyYW1ldGVycyBwYXNzZWQgdG8gdGhlCisgICAgICogICAgICAgICAgICBtZXRob2QsIG9yIHtAY29kZSBudWxsfSBpZiBubyBhcmd1bWVudHMgYXJlIGV4cGVjdGVkLgorICAgICAqICAgICAgICAgICAgUHJpbWl0aXZlIHR5cGVzIGFyZSBib3hlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBleGVjdXRpbmcgdGhlIG1ldGhvZC4gUHJpbWl0aXZlIHR5cGVzIGFyZSBib3hlZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgdGhlIGV4Y2VwdGlvbiB0byB0aHJvdyBmcm9tIHRoZSBpbnZva2VkIG1ldGhvZCBvbiB0aGUgcHJveHkuCisgICAgICogICAgICAgICAgICAgVGhlIGV4Y2VwdGlvbiBtdXN0IG1hdGNoIG9uZSBvZiB0aGUgZGVjbGFyZWQgZXhjZXB0aW9uIHR5cGVzCisgICAgICogICAgICAgICAgICAgb2YgdGhlIGludm9rZWQgbWV0aG9kIG9yIGFueSB1bmNoZWNrZWQgZXhjZXB0aW9uIHR5cGUuIElmIG5vdAorICAgICAqICAgICAgICAgICAgIHRoZW4gYW4ge0Bjb2RlIFVuZGVjbGFyZWRUaHJvd2FibGVFeGNlcHRpb259IGlzIHRocm93bgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgaW52b2tlKE9iamVjdCBwcm94eSwgTWV0aG9kIG1ldGhvZCwgT2JqZWN0W10gYXJncykgdGhyb3dzIFRocm93YWJsZTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE4NzQ0MWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsODcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nLnJlZmxlY3Q7CisKKy8qKgorICogVGhpcyBjbGFzcyBwcm92aWRlcyBhIHdyYXBwZXIgZm9yIGFuIGV4Y2VwdGlvbiB0aHJvd24gYnkgYSB7QGNvZGUgTWV0aG9kfSBvcgorICoge0Bjb2RlIENvbnN0cnVjdG9yfSBpbnZvY2F0aW9uLgorICoKKyAqIEBzZWUgTWV0aG9kI2ludm9rZQorICogQHNlZSBDb25zdHJ1Y3RvciNuZXdJbnN0YW5jZQorICovCitwdWJsaWMgY2xhc3MgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0MDg1MDg4NzMxOTI2NzAxMTY3TDsKKworICAgIHByaXZhdGUgVGhyb3dhYmxlIHRhcmdldDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb259IGluc3RhbmNlIHdpdGggYQorICAgICAqIHtAY29kZSBudWxsfSBjYXVzZSAvIHRhcmdldCBleGNlcHRpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24oKSB7CisgICAgICAgIHN1cGVyKChUaHJvd2FibGUpIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb259IGluc3RhbmNlIHdpdGggaXRzCisgICAgICogY2F1c2UgLyB0YXJnZXQgZXhjZXB0aW9uIGZpbGxlZCBpbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNlcHRpb24gd2hpY2ggb2NjdXJyZWQgd2hpbGUgcnVubmluZyB0aGUgTWV0aG9kIG9yCisgICAgICogICAgICAgICAgICBDb25zdHJ1Y3RvcgorICAgICAqLworICAgIHB1YmxpYyBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uKFRocm93YWJsZSBleGNlcHRpb24pIHsKKyAgICAgICAgc3VwZXIobnVsbCwgZXhjZXB0aW9uKTsKKyAgICAgICAgdGFyZ2V0ID0gZXhjZXB0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb259IGluc3RhbmNlIHdpdGggaXRzCisgICAgICogY2F1c2UgLyB0YXJnZXQgZXhjZXB0aW9uIGFuZCBtZXNzYWdlIGZpbGxlZCBpbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24KKyAgICAgKiBAcGFyYW0gZXhjZXB0aW9uCisgICAgICogICAgICAgICAgICB0aGUgZXhjZXB0aW9uIHdoaWNoIG9jY3VycmVkIHdoaWxlIHJ1bm5pbmcgdGhlIE1ldGhvZCBvcgorICAgICAqICAgICAgICAgICAgQ29uc3RydWN0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbihUaHJvd2FibGUgZXhjZXB0aW9uLCBTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlLCBleGNlcHRpb24pOworICAgICAgICB0YXJnZXQgPSBleGNlcHRpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGFyZ2V0IGV4Y2VwdGlvbiwgd2hpY2ggbWF5IGJlIHtAY29kZSBudWxsfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHRhcmdldCBleGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgVGhyb3dhYmxlIGdldFRhcmdldEV4Y2VwdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIHRhcmdldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjYXVzZSBvZiB0aGlzIGV4Y2VwdGlvbiwgd2hpY2ggbWF5IGJlIHtAY29kZSBudWxsfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNhdXNlIG9mIHRoaXMgZXhjZXB0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFRocm93YWJsZSBnZXRDYXVzZSgpIHsKKyAgICAgICAgcmV0dXJuIHRhcmdldDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvTWFsZm9ybWVkUGFyYW1ldGVyaXplZFR5cGVFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9NYWxmb3JtZWRQYXJhbWV0ZXJpemVkVHlwZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNlZGYxNTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvTWFsZm9ybWVkUGFyYW1ldGVyaXplZFR5cGVFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDM1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZy5yZWZsZWN0OworCisvKioKKyAqIEluZGljYXRlcyB0aGF0IGEgbWFsZm9ybWVkIHBhcmFtZXRlcml6ZWQgdHlwZSBoYXMgYmVlbiBlbmNvdW50ZXJlZCBieSBhCisgKiByZWZsZWN0aXZlIG1ldGhvZC4KKyAqCisgKiBAc2luY2UgMS41CisgKi8KK3B1YmxpYyBjbGFzcyBNYWxmb3JtZWRQYXJhbWV0ZXJpemVkVHlwZUV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTU2OTY1NTc3ODg1ODYyMjA5NjRMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTWFsZm9ybWVkUGFyYW1ldGVyaXplZFR5cGVFeGNlcHRpb259IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBNYWxmb3JtZWRQYXJhbWV0ZXJpemVkVHlwZUV4Y2VwdGlvbigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvTWVtYmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvTWVtYmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTQzYWM2ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9NZW1iZXIuamF2YQpAQCAtMCwwICsxLDczIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZy5yZWZsZWN0OworCisvKioKKyAqIENvbW1vbiBpbnRlcmZhY2UgcHJvdmlkaW5nIGFjY2VzcyB0byByZWZsZWN0aXZlIGluZm9ybWF0aW9uIG9uIGNsYXNzIG1lbWJlcnMuCisgKgorICogQHNlZSBGaWVsZAorICogQHNlZSBDb25zdHJ1Y3RvcgorICogQHNlZSBNZXRob2QKKyAqLworcHVibGljIGludGVyZmFjZSBNZW1iZXIgeworCisgICAgLyoqCisgICAgICogRGVzaWduYXRlcyBhbGwgcHVibGljIG1lbWJlcnMgb2YgYSBjbGFzcyBvciBpbnRlcmZhY2UgKGluY2x1ZGluZworICAgICAqIGluaGVyaXRlZCBtZW1iZXJzKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQVUJMSUMgPSAwOworCisgICAgLyoqCisgICAgICogRGVzaWduYXRlcyBhbGwgZGVjbGFyZWQgbWVtYmVycyBvZiBhIGNsYXNzIG9yIGludGVyZmFjZSAod2l0aG91dAorICAgICAqIGluaGVyaXRlZCBtZW1iZXJzKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUNMQVJFRCA9IDE7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbGFzcyB0aGF0IGRlY2xhcmVzIHRoaXMgbWVtYmVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZGVjbGFyaW5nIGNsYXNzCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgQ2xhc3M8Pz4gZ2V0RGVjbGFyaW5nQ2xhc3MoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1vZGlmaWVycyBmb3IgdGhpcyBtZW1iZXIuIFRoZSB7QGxpbmsgTW9kaWZpZXJ9IGNsYXNzIHNob3VsZAorICAgICAqIGJlIHVzZWQgdG8gZGVjb2RlIHRoZSByZXN1bHQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtb2RpZmllcnMgZm9yIHRoaXMgbWVtYmVyCisgICAgICoKKyAgICAgKiBAc2VlIE1vZGlmaWVyCisgICAgICovCisgICAgaW50IGdldE1vZGlmaWVycygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGlzIG1lbWJlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhpcyBtZW1iZXIKKyAgICAgKi8KKyAgICBTdHJpbmcgZ2V0TmFtZSgpOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoaXMgbWVtYmVyIGlzIHN5bnRoZXRpYyAoYXJ0aWZpY2lhbGx5CisgICAgICogaW50cm9kdWNlZCBieSB0aGUgY29tcGlsZXIpLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBtZW1iZXIgaXMgc3ludGhldGljLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZQorICAgICAqLworICAgIGJvb2xlYW4gaXNTeW50aGV0aWMoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YTljMGYxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L01ldGhvZC5qYXZhCkBAIC0wLDAgKzEsNTgzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZy5yZWZsZWN0OworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29tcGFyYXRvcjsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuRW1wdHlBcnJheTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkua2VybmVsLnZtLlN0cmluZ1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLmxhbmcucmVmbGVjdC5HZW5lcmljU2lnbmF0dXJlUGFyc2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLmxhbmcucmVmbGVjdC5MaXN0T2ZUeXBlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS5sYW5nLnJlZmxlY3QuVHlwZXM7CisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgbWV0aG9kLiBJbmZvcm1hdGlvbiBhYm91dCB0aGUgbWV0aG9kIGNhbiBiZSBhY2Nlc3NlZCwKKyAqIGFuZCB0aGUgbWV0aG9kIGNhbiBiZSBpbnZva2VkIGR5bmFtaWNhbGx5LgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTWV0aG9kIGV4dGVuZHMgQWNjZXNzaWJsZU9iamVjdCBpbXBsZW1lbnRzIEdlbmVyaWNEZWNsYXJhdGlvbiwgTWVtYmVyIHsKKworICAgIC8qKgorICAgICAqIE9yZGVycyBtZXRob2RzIGJ5IHRoZWlyIG5hbWUsIHBhcmFtZXRlcnMgYW5kIHJldHVybiB0eXBlLgorICAgICAqCisgICAgICogQGhpZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbXBhcmF0b3I8TWV0aG9kPiBPUkRFUl9CWV9TSUdOQVRVUkUgPSBuZXcgQ29tcGFyYXRvcjxNZXRob2Q+KCkgeworICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoTWV0aG9kIGEsIE1ldGhvZCBiKSB7CisgICAgICAgICAgICBpbnQgY29tcGFyaXNvbiA9IGEubmFtZS5jb21wYXJlVG8oYi5uYW1lKTsKKyAgICAgICAgICAgIGlmIChjb21wYXJpc29uICE9IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY29tcGFyaXNvbjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQ2xhc3M8Pz5bXSBhUGFyYW1ldGVycyA9IGEucGFyYW1ldGVyVHlwZXM7CisgICAgICAgICAgICBDbGFzczw/PltdIGJQYXJhbWV0ZXJzID0gYi5wYXJhbWV0ZXJUeXBlczsKKyAgICAgICAgICAgIGludCBsZW5ndGggPSBNYXRoLm1pbihhUGFyYW1ldGVycy5sZW5ndGgsIGJQYXJhbWV0ZXJzLmxlbmd0aCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgY29tcGFyaXNvbiA9IGFQYXJhbWV0ZXJzW2ldLmdldE5hbWUoKS5jb21wYXJlVG8oYlBhcmFtZXRlcnNbaV0uZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBpZiAoY29tcGFyaXNvbiAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb21wYXJpc29uOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGFQYXJhbWV0ZXJzLmxlbmd0aCAhPSBiUGFyYW1ldGVycy5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYVBhcmFtZXRlcnMubGVuZ3RoIC0gYlBhcmFtZXRlcnMubGVuZ3RoOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB0aGlzIGlzIG5lY2Vzc2FyeSBmb3IgbWV0aG9kcyB0aGF0IGhhdmUgY292YXJpYW50IHJldHVybiB0eXBlcy4KKyAgICAgICAgICAgIHJldHVybiBhLmdldFJldHVyblR5cGUoKS5nZXROYW1lKCkuY29tcGFyZVRvKGIuZ2V0UmV0dXJuVHlwZSgpLmdldE5hbWUoKSk7CisgICAgICAgIH0KKyAgICB9OworCisgICAgcHJpdmF0ZSBpbnQgc2xvdDsKKworICAgIHByaXZhdGUgQ2xhc3M8Pz4gZGVjbGFyaW5nQ2xhc3M7CisKKyAgICBwcml2YXRlIFN0cmluZyBuYW1lOworCisgICAgcHJpdmF0ZSBDbGFzczw/PltdIHBhcmFtZXRlclR5cGVzOworCisgICAgcHJpdmF0ZSBDbGFzczw/PltdIGV4Y2VwdGlvblR5cGVzOworCisgICAgcHJpdmF0ZSBDbGFzczw/PiByZXR1cm5UeXBlOworCisgICAgcHJpdmF0ZSBMaXN0T2ZUeXBlcyBnZW5lcmljRXhjZXB0aW9uVHlwZXM7CisgICAgcHJpdmF0ZSBMaXN0T2ZUeXBlcyBnZW5lcmljUGFyYW1ldGVyVHlwZXM7CisgICAgcHJpdmF0ZSBUeXBlIGdlbmVyaWNSZXR1cm5UeXBlOworICAgIHByaXZhdGUgVHlwZVZhcmlhYmxlPE1ldGhvZD5bXSBmb3JtYWxUeXBlUGFyYW1ldGVyczsKKyAgICBwcml2YXRlIHZvbGF0aWxlIGJvb2xlYW4gZ2VuZXJpY1R5cGVzQXJlSW5pdGlhbGl6ZWQgPSBmYWxzZTsKKworICAgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgaW5pdEdlbmVyaWNUeXBlcygpIHsKKyAgICAgICAgaWYgKCFnZW5lcmljVHlwZXNBcmVJbml0aWFsaXplZCkgeworICAgICAgICAgICAgU3RyaW5nIHNpZ25hdHVyZUF0dHJpYnV0ZSA9IGdldFNpZ25hdHVyZUF0dHJpYnV0ZSgpOworICAgICAgICAgICAgR2VuZXJpY1NpZ25hdHVyZVBhcnNlciBwYXJzZXIgPSBuZXcgR2VuZXJpY1NpZ25hdHVyZVBhcnNlcigKKyAgICAgICAgICAgICAgICAgICAgZGVjbGFyaW5nQ2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKSk7CisgICAgICAgICAgICBwYXJzZXIucGFyc2VGb3JNZXRob2QodGhpcywgc2lnbmF0dXJlQXR0cmlidXRlLCBleGNlcHRpb25UeXBlcyk7CisgICAgICAgICAgICBmb3JtYWxUeXBlUGFyYW1ldGVycyA9IHBhcnNlci5mb3JtYWxUeXBlUGFyYW1ldGVyczsKKyAgICAgICAgICAgIGdlbmVyaWNQYXJhbWV0ZXJUeXBlcyA9IHBhcnNlci5wYXJhbWV0ZXJUeXBlczsKKyAgICAgICAgICAgIGdlbmVyaWNFeGNlcHRpb25UeXBlcyA9IHBhcnNlci5leGNlcHRpb25UeXBlczsKKyAgICAgICAgICAgIGdlbmVyaWNSZXR1cm5UeXBlID0gcGFyc2VyLnJldHVyblR5cGU7CisgICAgICAgICAgICBnZW5lcmljVHlwZXNBcmVJbml0aWFsaXplZCA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBjbG9uZSBvZiB0aGUgZ2l2ZW4gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3JpZyBub24tbnVsbDsgdGhlIG9yaWdpbmFsIGluc3RhbmNlIHRvIGNsb25lCisgICAgICovCisgICAgLypwYWNrYWdlKi8gTWV0aG9kKE1ldGhvZCBvcmlnKSB7CisgICAgICAgIHRoaXMob3JpZy5kZWNsYXJpbmdDbGFzcywgb3JpZy5wYXJhbWV0ZXJUeXBlcywgb3JpZy5leGNlcHRpb25UeXBlcywKKyAgICAgICAgICAgICAgICBvcmlnLnJldHVyblR5cGUsIG9yaWcubmFtZSwgb3JpZy5zbG90KTsKKworICAgICAgICAvLyBDb3B5IHRoZSBhY2Nlc3NpYmxlIGZsYWcuCisgICAgICAgIGlmIChvcmlnLmZsYWcpIHsKKyAgICAgICAgICAgIHRoaXMuZmxhZyA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIE1ldGhvZChDbGFzczw/PiBkZWNsYXJpbmcsIENsYXNzPD8+W10gcGFyYW1UeXBlcywgQ2xhc3M8Pz5bXSBleGNlcHRUeXBlcywgQ2xhc3M8Pz4gcmV0dXJuVHlwZSwgU3RyaW5nIG5hbWUsIGludCBzbG90KQorICAgIHsKKyAgICAgICAgdGhpcy5kZWNsYXJpbmdDbGFzcyA9IGRlY2xhcmluZzsKKyAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgICAgdGhpcy5zbG90ID0gc2xvdDsKKyAgICAgICAgdGhpcy5wYXJhbWV0ZXJUeXBlcyA9IHBhcmFtVHlwZXM7CisgICAgICAgIHRoaXMuZXhjZXB0aW9uVHlwZXMgPSBleGNlcHRUeXBlczsgICAgICAvLyBtYXkgYmUgbnVsbAorICAgICAgICB0aGlzLnJldHVyblR5cGUgPSByZXR1cm5UeXBlOworICAgIH0KKworICAgIHB1YmxpYyBUeXBlVmFyaWFibGU8TWV0aG9kPltdIGdldFR5cGVQYXJhbWV0ZXJzKCkgeworICAgICAgICBpbml0R2VuZXJpY1R5cGVzKCk7CisgICAgICAgIHJldHVybiBmb3JtYWxUeXBlUGFyYW1ldGVycy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKiB7QGluaGVyaXREb2N9ICovCisgICAgQE92ZXJyaWRlIC8qcGFja2FnZSovIFN0cmluZyBnZXRTaWduYXR1cmVBdHRyaWJ1dGUoKSB7CisgICAgICAgIE9iamVjdFtdIGFubm90YXRpb24gPSBnZXRTaWduYXR1cmVBbm5vdGF0aW9uKGRlY2xhcmluZ0NsYXNzLCBzbG90KTsKKworICAgICAgICBpZiAoYW5ub3RhdGlvbiA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBTdHJpbmdVdGlscy5jb21iaW5lU3RyaW5ncyhhbm5vdGF0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBTaWduYXR1cmUgYW5ub3RhdGlvbiBmb3IgdGhpcyBtZXRob2QuIFJldHVybnMge0Bjb2RlIG51bGx9IGlmCisgICAgICogbm90IGZvdW5kLgorICAgICAqLworICAgIHN0YXRpYyBuYXRpdmUgT2JqZWN0W10gZ2V0U2lnbmF0dXJlQW5ub3RhdGlvbihDbGFzcyBkZWNsYXJpbmdDbGFzcywgaW50IHNsb3QpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtZXRob2QncyBkZWNsYXJhdGlvbiwgaW5jbHVkaW5nCisgICAgICogdGhlIHR5cGUgcGFyYW1ldGVycy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG1ldGhvZAorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9HZW5lcmljU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoODApOworCisgICAgICAgIGluaXRHZW5lcmljVHlwZXMoKTsKKworICAgICAgICAvLyBhcHBlbmQgbW9kaWZpZXJzIGlmIGFueQorICAgICAgICBpbnQgbW9kaWZpZXIgPSBnZXRNb2RpZmllcnMoKTsKKyAgICAgICAgaWYgKG1vZGlmaWVyICE9IDApIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZChNb2RpZmllci50b1N0cmluZyhtb2RpZmllciAmIH4oTW9kaWZpZXIuQlJJREdFICsKKyAgICAgICAgICAgICAgICAgICAgTW9kaWZpZXIuVkFSQVJHUykpKS5hcHBlbmQoJyAnKTsKKyAgICAgICAgfQorICAgICAgICAvLyBhcHBlbmQgdHlwZSBwYXJhbWV0ZXJzCisgICAgICAgIGlmIChmb3JtYWxUeXBlUGFyYW1ldGVycyAhPSBudWxsICYmIGZvcm1hbFR5cGVQYXJhbWV0ZXJzLmxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgnPCcpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmb3JtYWxUeXBlUGFyYW1ldGVycy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGFwcGVuZEdlbmVyaWNUeXBlKHNiLCBmb3JtYWxUeXBlUGFyYW1ldGVyc1tpXSk7CisgICAgICAgICAgICAgICAgaWYgKGkgPCBmb3JtYWxUeXBlUGFyYW1ldGVycy5sZW5ndGggLSAxKSB7CisgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgiLCIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNiLmFwcGVuZCgiPiAiKTsKKyAgICAgICAgfQorICAgICAgICAvLyBhcHBlbmQgcmV0dXJuIHR5cGUKKyAgICAgICAgYXBwZW5kR2VuZXJpY1R5cGUoc2IsIFR5cGVzLmdldFR5cGUoZ2VuZXJpY1JldHVyblR5cGUpKTsKKyAgICAgICAgc2IuYXBwZW5kKCcgJyk7CisgICAgICAgIC8vIGFwcGVuZCBtZXRob2QgbmFtZQorICAgICAgICBhcHBlbmRBcnJheVR5cGUoc2IsIGdldERlY2xhcmluZ0NsYXNzKCkpOworICAgICAgICBzYi5hcHBlbmQoIi4iKS5hcHBlbmQoZ2V0TmFtZSgpKTsKKyAgICAgICAgLy8gYXBwZW5kIHBhcmFtZXRlcnMKKyAgICAgICAgc2IuYXBwZW5kKCcoJyk7CisgICAgICAgIGFwcGVuZEFycmF5R2VuZXJpY1R5cGUoc2IsCisgICAgICAgICAgICAgICAgVHlwZXMuZ2V0Q2xvbmVkVHlwZUFycmF5KGdlbmVyaWNQYXJhbWV0ZXJUeXBlcykpOworICAgICAgICBzYi5hcHBlbmQoJyknKTsKKyAgICAgICAgLy8gYXBwZW5kIGV4Y2VwdGlvbnMgaWYgYW55CisgICAgICAgIFR5cGVbXSBnZW5lcmljRXhjZXB0aW9uVHlwZUFycmF5ID0gVHlwZXMuZ2V0Q2xvbmVkVHlwZUFycmF5KAorICAgICAgICAgICAgICAgIGdlbmVyaWNFeGNlcHRpb25UeXBlcyk7CisgICAgICAgIGlmIChnZW5lcmljRXhjZXB0aW9uVHlwZUFycmF5Lmxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiIHRocm93cyAiKTsKKyAgICAgICAgICAgIGFwcGVuZEFycmF5R2VuZXJpY1R5cGUoc2IsIGdlbmVyaWNFeGNlcHRpb25UeXBlQXJyYXkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHBhcmFtZXRlciB0eXBlcyBhcyBhbiBhcnJheSBvZiB7QGNvZGUgVHlwZX0gaW5zdGFuY2VzLCBpbgorICAgICAqIGRlY2xhcmF0aW9uIG9yZGVyLiBJZiB0aGlzIG1ldGhvZCBoYXMgbm8gcGFyYW1ldGVycywgYW4gZW1wdHkgYXJyYXkgaXMKKyAgICAgKiByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlciB0eXBlcworICAgICAqCisgICAgICogQHRocm93cyBHZW5lcmljU2lnbmF0dXJlRm9ybWF0RXJyb3IKKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2VuZXJpYyBtZXRob2Qgc2lnbmF0dXJlIGlzIGludmFsaWQKKyAgICAgKiBAdGhyb3dzIFR5cGVOb3RQcmVzZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IHBhcmFtZXRlciB0eXBlIHBvaW50cyB0byBhIG1pc3NpbmcgdHlwZQorICAgICAqIEB0aHJvd3MgTWFsZm9ybWVkUGFyYW1ldGVyaXplZFR5cGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgcGFyYW1ldGVyIHR5cGUgcG9pbnRzIHRvIGEgdHlwZSB0aGF0IGNhbm5vdCBiZQorICAgICAqICAgICAgICAgICAgIGluc3RhbnRpYXRlZCBmb3Igc29tZSByZWFzb24KKyAgICAgKi8KKyAgICBwdWJsaWMgVHlwZVtdIGdldEdlbmVyaWNQYXJhbWV0ZXJUeXBlcygpIHsKKyAgICAgICAgaW5pdEdlbmVyaWNUeXBlcygpOworICAgICAgICByZXR1cm4gVHlwZXMuZ2V0Q2xvbmVkVHlwZUFycmF5KGdlbmVyaWNQYXJhbWV0ZXJUeXBlcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZXhjZXB0aW9uIHR5cGVzIGFzIGFuIGFycmF5IG9mIHtAY29kZSBUeXBlfSBpbnN0YW5jZXMuIElmCisgICAgICogdGhpcyBtZXRob2QgaGFzIG5vIGRlY2xhcmVkIGV4Y2VwdGlvbnMsIGFuIGVtcHR5IGFycmF5IHdpbGwgYmUgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIGdlbmVyaWMgZXhjZXB0aW9uIHR5cGVzCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEdlbmVyaWNTaWduYXR1cmVGb3JtYXRFcnJvcgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBnZW5lcmljIG1ldGhvZCBzaWduYXR1cmUgaXMgaW52YWxpZAorICAgICAqIEB0aHJvd3MgVHlwZU5vdFByZXNlbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgZXhjZXB0aW9uIHR5cGUgcG9pbnRzIHRvIGEgbWlzc2luZyB0eXBlCisgICAgICogQHRocm93cyBNYWxmb3JtZWRQYXJhbWV0ZXJpemVkVHlwZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBleGNlcHRpb24gdHlwZSBwb2ludHMgdG8gYSB0eXBlIHRoYXQgY2Fubm90IGJlCisgICAgICogICAgICAgICAgICAgaW5zdGFudGlhdGVkIGZvciBzb21lIHJlYXNvbgorICAgICAqLworICAgIHB1YmxpYyBUeXBlW10gZ2V0R2VuZXJpY0V4Y2VwdGlvblR5cGVzKCkgeworICAgICAgICBpbml0R2VuZXJpY1R5cGVzKCk7CisgICAgICAgIHJldHVybiBUeXBlcy5nZXRDbG9uZWRUeXBlQXJyYXkoZ2VuZXJpY0V4Y2VwdGlvblR5cGVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIG1ldGhvZCBhcyBhIHtAY29kZSBUeXBlfSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgbWV0aG9kCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEdlbmVyaWNTaWduYXR1cmVGb3JtYXRFcnJvcgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBnZW5lcmljIG1ldGhvZCBzaWduYXR1cmUgaXMgaW52YWxpZAorICAgICAqIEB0aHJvd3MgVHlwZU5vdFByZXNlbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcmV0dXJuIHR5cGUgcG9pbnRzIHRvIGEgbWlzc2luZyB0eXBlCisgICAgICogQHRocm93cyBNYWxmb3JtZWRQYXJhbWV0ZXJpemVkVHlwZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSByZXR1cm4gdHlwZSBwb2ludHMgdG8gYSB0eXBlIHRoYXQgY2Fubm90IGJlCisgICAgICogICAgICAgICAgICAgaW5zdGFudGlhdGVkIGZvciBzb21lIHJlYXNvbgorICAgICAqLworICAgIHB1YmxpYyBUeXBlIGdldEdlbmVyaWNSZXR1cm5UeXBlKCkgeworICAgICAgICBpbml0R2VuZXJpY1R5cGVzKCk7CisgICAgICAgIHJldHVybiBUeXBlcy5nZXRUeXBlKGdlbmVyaWNSZXR1cm5UeXBlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQW5ub3RhdGlvbltdIGdldERlY2xhcmVkQW5ub3RhdGlvbnMoKSB7CisgICAgICAgIHJldHVybiBnZXREZWNsYXJlZEFubm90YXRpb25zKGRlY2xhcmluZ0NsYXNzLCBzbG90KTsKKyAgICB9CisgICAgc3RhdGljIG5hdGl2ZSBBbm5vdGF0aW9uW10gZ2V0RGVjbGFyZWRBbm5vdGF0aW9ucyhDbGFzczw/PiBkZWNsYXJpbmdDbGFzcywgaW50IHNsb3QpOworCisgICAgQE92ZXJyaWRlIHB1YmxpYyA8QSBleHRlbmRzIEFubm90YXRpb24+IEEgZ2V0QW5ub3RhdGlvbihDbGFzczxBPiBhbm5vdGF0aW9uVHlwZSkgeworICAgICAgICBpZiAoYW5ub3RhdGlvblR5cGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJhbm5vdGF0aW9uVHlwZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEFubm90YXRpb24oZGVjbGFyaW5nQ2xhc3MsIHNsb3QsIGFubm90YXRpb25UeXBlKTsKKyAgICB9CisgICAgc3RhdGljIG5hdGl2ZSA8QSBleHRlbmRzIEFubm90YXRpb24+IEEgZ2V0QW5ub3RhdGlvbigKKyAgICAgICAgICAgIENsYXNzPD8+IGRlY2xhcmluZ0NsYXNzLCBpbnQgc2xvdCwgQ2xhc3M8QT4gYW5ub3RhdGlvblR5cGUpOworCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGlzQW5ub3RhdGlvblByZXNlbnQoQ2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+IGFubm90YXRpb25UeXBlKSB7CisgICAgICAgIGlmIChhbm5vdGF0aW9uVHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImFubm90YXRpb25UeXBlID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaXNBbm5vdGF0aW9uUHJlc2VudChkZWNsYXJpbmdDbGFzcywgc2xvdCwgYW5ub3RhdGlvblR5cGUpOworICAgIH0KKyAgICBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gaXNBbm5vdGF0aW9uUHJlc2VudCgKKyAgICAgICAgICAgIENsYXNzPD8+IGRlY2xhcmluZ0NsYXNzLCBpbnQgc2xvdCwgQ2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+IGFubm90YXRpb25UeXBlKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFubm90YXRpb25bXSBOT19BTk5PVEFUSU9OUyA9IG5ldyBBbm5vdGF0aW9uWzBdOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBlbXB0eSBBbm5vdGF0aW9uIGFycmF5cy4KKyAgICAgKi8KKyAgICAvKnBhY2thZ2UqLyBzdGF0aWMgQW5ub3RhdGlvbltdW10gbm9Bbm5vdGF0aW9ucyhpbnQgc2l6ZSkgeworICAgICAgICBBbm5vdGF0aW9uW11bXSBhbm5vdGF0aW9ucyA9IG5ldyBBbm5vdGF0aW9uW3NpemVdW107CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBhbm5vdGF0aW9uc1tpXSA9IE5PX0FOTk9UQVRJT05TOworICAgICAgICB9CisgICAgICAgIHJldHVybiBhbm5vdGF0aW9uczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGFycmF5cyB0aGF0IHJlcHJlc2VudCB0aGUgYW5ub3RhdGlvbnMgb2YgdGhlIGZvcm1hbAorICAgICAqIHBhcmFtZXRlcnMgb2YgdGhpcyBtZXRob2QuIElmIHRoZXJlIGFyZSBubyBwYXJhbWV0ZXJzIG9uIHRoaXMgbWV0aG9kLAorICAgICAqIHRoZW4gYW4gZW1wdHkgYXJyYXkgaXMgcmV0dXJuZWQuIElmIHRoZXJlIGFyZSBubyBhbm5vdGF0aW9ucyBzZXQsIHRoZW4KKyAgICAgKiBhbmQgYXJyYXkgb2YgZW1wdHkgYXJyYXlzIGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBhcnJheXMgb2Yge0Bjb2RlIEFubm90YXRpb259IGluc3RhbmNlcworICAgICAqLworICAgIHB1YmxpYyBBbm5vdGF0aW9uW11bXSBnZXRQYXJhbWV0ZXJBbm5vdGF0aW9ucygpIHsKKyAgICAgICAgQW5ub3RhdGlvbltdW10gcGFyYW1ldGVyQW5ub3RhdGlvbnMKKyAgICAgICAgICAgICAgICA9IGdldFBhcmFtZXRlckFubm90YXRpb25zKGRlY2xhcmluZ0NsYXNzLCBzbG90KTsKKyAgICAgICAgaWYgKHBhcmFtZXRlckFubm90YXRpb25zLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbm9Bbm5vdGF0aW9ucyhwYXJhbWV0ZXJUeXBlcy5sZW5ndGgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBwYXJhbWV0ZXJBbm5vdGF0aW9uczsKKyAgICB9CisKKyAgICBzdGF0aWMgbmF0aXZlIEFubm90YXRpb25bXVtdIGdldFBhcmFtZXRlckFubm90YXRpb25zKENsYXNzIGRlY2xhcmluZ0NsYXNzLCBpbnQgc2xvdCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhpcyBtZXRob2QgdGFrZXMgYSB2YXJpYWJsZSBudW1iZXIgYXJndW1lbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBhIHZhcmFyZyBpcyBkZWNsYXJlZCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1ZhckFyZ3MoKSB7CisgICAgICAgIGludCBtb2RpZmllcnMgPSBnZXRNZXRob2RNb2RpZmllcnMoZGVjbGFyaW5nQ2xhc3MsIHNsb3QpOworICAgICAgICByZXR1cm4gKG1vZGlmaWVycyAmIE1vZGlmaWVyLlZBUkFSR1MpICE9IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoaXMgbWV0aG9kIGlzIGEgYnJpZGdlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBtZXRob2QgaXMgYSBicmlkZ2UsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNCcmlkZ2UoKSB7CisgICAgICAgIGludCBtb2RpZmllcnMgPSBnZXRNZXRob2RNb2RpZmllcnMoZGVjbGFyaW5nQ2xhc3MsIHNsb3QpOworICAgICAgICByZXR1cm4gKG1vZGlmaWVycyAmIE1vZGlmaWVyLkJSSURHRSkgIT0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhpcyBtZXRob2QgaXMgc3ludGhldGljLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBtZXRob2QgaXMgc3ludGhldGljLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzU3ludGhldGljKCkgeworICAgICAgICBpbnQgbW9kaWZpZXJzID0gZ2V0TWV0aG9kTW9kaWZpZXJzKGRlY2xhcmluZ0NsYXNzLCBzbG90KTsKKyAgICAgICAgcmV0dXJuIChtb2RpZmllcnMgJiBNb2RpZmllci5TWU5USEVUSUMpICE9IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhlIGFubm90YXRpb24gbWVtYmVyIHJlcHJlc2VudGVkIGJ5IHRoaXMKKyAgICAgKiBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkZWZhdWx0IHZhbHVlLCBvciB7QGNvZGUgbnVsbH0gaWYgbm9uZQorICAgICAqCisgICAgICogQHRocm93cyBUeXBlTm90UHJlc2VudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgYW5ub3RhdGlvbiBtZW1iZXIgaXMgb2YgdHlwZSB7QGNvZGUgQ2xhc3N9IGFuZCBubworICAgICAqICAgICAgICAgICAgIGRlZmluaXRpb24gY2FuIGJlIGZvdW5kCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXREZWZhdWx0VmFsdWUoKSB7CisgICAgICAgIHJldHVybiBnZXREZWZhdWx0VmFsdWUoZGVjbGFyaW5nQ2xhc3MsIHNsb3QpOworICAgIH0KKyAgICBuYXRpdmUgcHJpdmF0ZSBPYmplY3QgZ2V0RGVmYXVsdFZhbHVlKENsYXNzIGRlY2xhcmluZ0NsYXNzLCBpbnQgc2xvdCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhlIHNwZWNpZmllZCB7QGNvZGUgb2JqZWN0fSBpcyBlcXVhbCB0byB0aGlzCisgICAgICogbWV0aG9kLiBUbyBiZSBlcXVhbCwgdGhlIHNwZWNpZmllZCBvYmplY3QgbXVzdCBiZSBhbiBpbnN0YW5jZQorICAgICAqIG9mIHtAY29kZSBNZXRob2R9IHdpdGggdGhlIHNhbWUgZGVjbGFyaW5nIGNsYXNzIGFuZCBwYXJhbWV0ZXIgdHlwZXMKKyAgICAgKiBhcyB0aGlzIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZQorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgZXF1YWwgdG8gdGhpcworICAgICAqICAgICAgICAgbWV0aG9kLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZQorICAgICAqCisgICAgICogQHNlZSAjaGFzaENvZGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICByZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgTWV0aG9kICYmIHRvU3RyaW5nKCkuZXF1YWxzKG9iamVjdC50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbGFzcyB0aGF0IGRlY2xhcmVzIHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZGVjbGFyaW5nIGNsYXNzCisgICAgICovCisgICAgcHVibGljIENsYXNzPD8+IGdldERlY2xhcmluZ0NsYXNzKCkgeworICAgICAgICByZXR1cm4gZGVjbGFyaW5nQ2xhc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZXhjZXB0aW9uIHR5cGVzIGFzIGFuIGFycmF5IG9mIHtAY29kZSBDbGFzc30gaW5zdGFuY2VzLiBJZgorICAgICAqIHRoaXMgbWV0aG9kIGhhcyBubyBkZWNsYXJlZCBleGNlcHRpb25zLCBhbiBlbXB0eSBhcnJheSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGRlY2xhcmVkIGV4Y2VwdGlvbiBjbGFzc2VzCisgICAgICovCisgICAgcHVibGljIENsYXNzPD8+W10gZ2V0RXhjZXB0aW9uVHlwZXMoKSB7CisgICAgICAgIGlmIChleGNlcHRpb25UeXBlcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gRW1wdHlBcnJheS5DTEFTUzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZXhjZXB0aW9uVHlwZXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtb2RpZmllcnMgZm9yIHRoaXMgbWV0aG9kLiBUaGUge0BsaW5rIE1vZGlmaWVyfSBjbGFzcyBzaG91bGQKKyAgICAgKiBiZSB1c2VkIHRvIGRlY29kZSB0aGUgcmVzdWx0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbW9kaWZpZXJzIGZvciB0aGlzIG1ldGhvZAorICAgICAqCisgICAgICogQHNlZSBNb2RpZmllcgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TW9kaWZpZXJzKCkgeworICAgICAgICByZXR1cm4gZ2V0TWV0aG9kTW9kaWZpZXJzKGRlY2xhcmluZ0NsYXNzLCBzbG90KTsKKyAgICB9CisKKyAgICBzdGF0aWMgbmF0aXZlIGludCBnZXRNZXRob2RNb2RpZmllcnMoQ2xhc3M8Pz4gZGVjbGFyaW5nQ2xhc3MsIGludCBzbG90KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIG1ldGhvZCByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBNZXRob2R9CisgICAgICogaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoaXMgbWV0aG9kCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHtAY29kZSBDbGFzc30gb2JqZWN0cyBhc3NvY2lhdGVkIHdpdGggdGhlIHBhcmFtZXRlcgorICAgICAqIHR5cGVzIG9mIHRoaXMgbWV0aG9kLiBJZiB0aGUgbWV0aG9kIHdhcyBkZWNsYXJlZCB3aXRoIG5vIHBhcmFtZXRlcnMsIGFuCisgICAgICogZW1wdHkgYXJyYXkgd2lsbCBiZSByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlciB0eXBlcworICAgICAqLworICAgIHB1YmxpYyBDbGFzczw/PltdIGdldFBhcmFtZXRlclR5cGVzKCkgeworICAgICAgICByZXR1cm4gcGFyYW1ldGVyVHlwZXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgQ2xhc3N9IGFzc29jaWF0ZWQgd2l0aCB0aGUgcmV0dXJuIHR5cGUgb2YgdGhpcworICAgICAqIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJldHVybiB0eXBlCisgICAgICovCisgICAgcHVibGljIENsYXNzPD8+IGdldFJldHVyblR5cGUoKSB7CisgICAgICAgIHJldHVybiByZXR1cm5UeXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW50ZWdlciBoYXNoIGNvZGUgZm9yIHRoaXMgbWV0aG9kLiBPYmplY3RzIHdoaWNoIGFyZSBlcXVhbAorICAgICAqIHJldHVybiB0aGUgc2FtZSB2YWx1ZSBmb3IgdGhpcyBtZXRob2QuIFRoZSBoYXNoIGNvZGUgZm9yIHRoaXMgTWV0aG9kIGlzCisgICAgICogdGhlIGhhc2ggY29kZSBvZiB0aGUgbmFtZSBvZiB0aGlzIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gaGFzaCBjb2RlIGZvciB0aGlzIG1ldGhvZAorICAgICAqCisgICAgICogQHNlZSAjZXF1YWxzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWUuaGFzaENvZGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByZXN1bHQgb2YgZHluYW1pY2FsbHkgaW52b2tpbmcgdGhpcyBtZXRob2QuIEVxdWl2YWxlbnQgdG8KKyAgICAgKiB7QGNvZGUgcmVjZWl2ZXIubWV0aG9kTmFtZShhcmcxLCBhcmcyLCAuLi4gLCBhcmdOKX0uCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgbWV0aG9kIGlzIHN0YXRpYywgdGhlIHJlY2VpdmVyIGFyZ3VtZW50IGlzIGlnbm9yZWQgKGFuZCBtYXkgYmUgbnVsbCkuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgbWV0aG9kIHRha2VzIG5vIGFyZ3VtZW50cywgeW91IGNhbiBwYXNzIHtAY29kZSAoT2JqZWN0W10pIG51bGx9IGluc3RlYWQgb2YKKyAgICAgKiBhbGxvY2F0aW5nIGFuIGVtcHR5IGFycmF5LgorICAgICAqCisgICAgICogPHA+SWYgeW91J3JlIGNhbGxpbmcgYSB2YXJhcmdzIG1ldGhvZCwgeW91IG5lZWQgdG8gcGFzcyBhbiB7QGNvZGUgT2JqZWN0W119IGZvciB0aGUKKyAgICAgKiB2YXJhcmdzIHBhcmFtZXRlcjogdGhhdCBjb252ZXJzaW9uIGlzIHVzdWFsbHkgZG9uZSBpbiB7QGNvZGUgamF2YWN9LCBub3QgdGhlIFZNLCBhbmQKKyAgICAgKiB0aGUgcmVmbGVjdGlvbiBtYWNoaW5lcnkgZG9lcyBub3QgZG8gdGhpcyBmb3IgeW91LiAoSXQgY291bGRuJ3QsIGJlY2F1c2UgaXQgd291bGQgYmUKKyAgICAgKiBhbWJpZ3VvdXMuKQorICAgICAqCisgICAgICogPHA+UmVmbGVjdGl2ZSBtZXRob2QgaW52b2NhdGlvbiBmb2xsb3dzIHRoZSB1c3VhbCBwcm9jZXNzIGZvciBtZXRob2QgbG9va3VwLgorICAgICAqCisgICAgICogPHA+SWYgYW4gZXhjZXB0aW9uIGlzIHRocm93biBkdXJpbmcgdGhlIGludm9jYXRpb24gaXQgaXMgY2F1Z2h0IGFuZAorICAgICAqIHdyYXBwZWQgaW4gYW4gSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbi4gVGhpcyBleGNlcHRpb24gaXMgdGhlbiB0aHJvd24uCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgaW52b2NhdGlvbiBjb21wbGV0ZXMgbm9ybWFsbHksIHRoZSByZXR1cm4gdmFsdWUgaXRzZWxmIGlzCisgICAgICogcmV0dXJuZWQuIElmIHRoZSBtZXRob2QgaXMgZGVjbGFyZWQgdG8gcmV0dXJuIGEgcHJpbWl0aXZlIHR5cGUsIHRoZQorICAgICAqIHJldHVybiB2YWx1ZSBpcyBib3hlZC4gSWYgdGhlIHJldHVybiB0eXBlIGlzIHZvaWQsIG51bGwgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVjZWl2ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3Qgb24gd2hpY2ggdG8gY2FsbCB0aGlzIG1ldGhvZCAob3IgbnVsbCBmb3Igc3RhdGljIG1ldGhvZHMpCisgICAgICogQHBhcmFtIGFyZ3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcmd1bWVudHMgdG8gdGhlIG1ldGhvZAorICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdAorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSByZWNlaXZlciA9PSBudWxsfSBmb3IgYSBub24tc3RhdGljIG1ldGhvZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbWV0aG9kIGlzIG5vdCBhY2Nlc3NpYmxlIChzZWUge0BsaW5rIEFjY2Vzc2libGVPYmplY3R9KQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG51bWJlciBvZiBhcmd1bWVudHMgZG9lc24ndCBtYXRjaCB0aGUgbnVtYmVyIG9mIHBhcmFtZXRlcnMsIHRoZSByZWNlaXZlcgorICAgICAqICAgICAgICAgICAgIGlzIGluY29tcGF0aWJsZSB3aXRoIHRoZSBkZWNsYXJpbmcgY2xhc3MsIG9yIGFuIGFyZ3VtZW50IGNvdWxkIG5vdCBiZSB1bmJveGVkCisgICAgICogICAgICAgICAgICAgb3IgY29udmVydGVkIGJ5IGEgd2lkZW5pbmcgY29udmVyc2lvbiB0byB0aGUgY29ycmVzcG9uZGluZyBwYXJhbWV0ZXIgdHlwZQorICAgICAqIEB0aHJvd3MgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGV4Y2VwdGlvbiB3YXMgdGhyb3duIGJ5IHRoZSBpbnZva2VkIG1ldGhvZAorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgaW52b2tlKE9iamVjdCByZWNlaXZlciwgT2JqZWN0Li4uIGFyZ3MpCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFyZ3MgPT0gbnVsbCkgeworICAgICAgICAgICAgYXJncyA9IEVtcHR5QXJyYXkuT0JKRUNUOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpbnZva2VOYXRpdmUocmVjZWl2ZXIsIGFyZ3MsIGRlY2xhcmluZ0NsYXNzLCBwYXJhbWV0ZXJUeXBlcywgcmV0dXJuVHlwZSwgc2xvdCwgZmxhZyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBuYXRpdmUgT2JqZWN0IGludm9rZU5hdGl2ZShPYmplY3Qgb2JqLCBPYmplY3RbXSBhcmdzLCBDbGFzczw/PiBkZWNsYXJpbmdDbGFzcywKKyAgICAgICAgICAgIENsYXNzPD8+W10gcGFyYW1ldGVyVHlwZXMsIENsYXNzPD8+IHJldHVyblR5cGUsIGludCBzbG90LCBib29sZWFuIG5vQWNjZXNzQ2hlY2spCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIGNvbmNpc2UsIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIG9mIHRoaXMKKyAgICAgKiBtZXRob2QuIFRoZSBmb3JtYXQgb2YgdGhlIHN0cmluZyBpczoKKyAgICAgKgorICAgICAqIDxvbD4KKyAgICAgKiAgIDxsaT5tb2RpZmllcnMgKGlmIGFueSkKKyAgICAgKiAgIDxsaT5yZXR1cm4gdHlwZSBvciAndm9pZCcKKyAgICAgKiAgIDxsaT5kZWNsYXJpbmcgY2xhc3MgbmFtZQorICAgICAqICAgPGxpPicoJworICAgICAqICAgPGxpPnBhcmFtZXRlciB0eXBlcywgc2VwYXJhdGVkIGJ5ICcsJyAoaWYgYW55KQorICAgICAqICAgPGxpPicpJworICAgICAqICAgPGxpPid0aHJvd3MnIHBsdXMgZXhjZXB0aW9uIHR5cGVzLCBzZXBhcmF0ZWQgYnkgJywnIChpZiBhbnkpCisgICAgICogPC9vbD4KKyAgICAgKgorICAgICAqIEZvciBleGFtcGxlOiB7QGNvZGUgcHVibGljIG5hdGl2ZSBPYmplY3QKKyAgICAgKiBqYXZhLmxhbmcuTWV0aG9kLmludm9rZShPYmplY3QsT2JqZWN0KSB0aHJvd3MKKyAgICAgKiBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICxJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9ufQorICAgICAqCisgICAgICogQHJldHVybiBhIHByaW50YWJsZSByZXByZXNlbnRhdGlvbiBmb3IgdGhpcyBtZXRob2QKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKE1vZGlmaWVyLnRvU3RyaW5nKGdldE1vZGlmaWVycygpKSk7CisKKyAgICAgICAgaWYgKHJlc3VsdC5sZW5ndGgoKSAhPSAwKQorICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnICcpOworICAgICAgICByZXN1bHQuYXBwZW5kKHJldHVyblR5cGUuZ2V0TmFtZSgpKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZCgnICcpOworICAgICAgICByZXN1bHQuYXBwZW5kKGRlY2xhcmluZ0NsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQoJy4nKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZChuYW1lKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZCgiKCIpOworICAgICAgICByZXN1bHQuYXBwZW5kKHRvU3RyaW5nKHBhcmFtZXRlclR5cGVzKSk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQoIikiKTsKKyAgICAgICAgaWYgKGV4Y2VwdGlvblR5cGVzICE9IG51bGwgJiYgZXhjZXB0aW9uVHlwZXMubGVuZ3RoICE9IDApIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIiB0aHJvd3MgIik7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHRvU3RyaW5nKGV4Y2VwdGlvblR5cGVzKSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29uc3RydWN0b3IncyBzaWduYXR1cmUgaW4gbm9uLXByaW50YWJsZSBmb3JtLiBUaGlzIGlzIGNhbGxlZAorICAgICAqIChvbmx5KSBmcm9tIElPIG5hdGl2ZSBjb2RlIGFuZCBuZWVkZWQgZm9yIGRlcml2aW5nIHRoZSBzZXJpYWxWZXJzaW9uVUlECisgICAgICogb2YgdGhlIGNsYXNzCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBjb25zdHJ1Y3RvcidzIHNpZ25hdHVyZS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBwcml2YXRlIFN0cmluZyBnZXRTaWduYXR1cmUoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKworICAgICAgICByZXN1bHQuYXBwZW5kKCcoJyk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyYW1ldGVyVHlwZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoZ2V0U2lnbmF0dXJlKHBhcmFtZXRlclR5cGVzW2ldKSk7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0LmFwcGVuZCgnKScpOworICAgICAgICByZXN1bHQuYXBwZW5kKGdldFNpZ25hdHVyZShyZXR1cm5UeXBlKSk7CisKKyAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L01vZGlmaWVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvTW9kaWZpZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMjVkZWQxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L01vZGlmaWVyLmphdmEKQEAgLTAsMCArMSwzNzAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nLnJlZmxlY3Q7CisKKy8qKgorICogVGhpcyBjbGFzcyBwcm92aWRlcyBzdGF0aWMgbWV0aG9kcyB0byBkZWNvZGUgY2xhc3MgYW5kIG1lbWJlciBtb2RpZmllcnMuCisgKgorICogQHNlZSBDbGFzcyNnZXRNb2RpZmllcnMoKQorICogQHNlZSBNZW1iZXIjZ2V0TW9kaWZpZXJzKCkKKyAqLworcHVibGljIGNsYXNzIE1vZGlmaWVyIHsKKworICAgIC8qKgorICAgICAqIFRoZSB7QGNvZGUgaW50fSB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIHtAY29kZSBwdWJsaWN9CisgICAgICogbW9kaWZpZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFVCTElDID0gMHgxOworCisgICAgLyoqCisgICAgICogVGhlIHtAY29kZSBpbnR9IHZhbHVlIHJlcHJlc2VudGluZyB0aGUge0Bjb2RlIHByaXZhdGV9CisgICAgICogbW9kaWZpZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJJVkFURSA9IDB4MjsKKworICAgIC8qKgorICAgICAqIFRoZSB7QGNvZGUgaW50fSB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIHtAY29kZSBwcm90ZWN0ZWR9CisgICAgICogbW9kaWZpZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJPVEVDVEVEID0gMHg0OworCisgICAgLyoqCisgICAgICogVGhlIHtAY29kZSBpbnR9IHZhbHVlIHJlcHJlc2VudGluZyB0aGUge0Bjb2RlIHN0YXRpY30gbW9kaWZpZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RBVElDID0gMHg4OworCisgICAgLyoqCisgICAgICogVGhlIHtAY29kZSBpbnR9IHZhbHVlIHJlcHJlc2VudGluZyB0aGUge0Bjb2RlIGZpbmFsfSBtb2RpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSU5BTCA9IDB4MTA7CisKKyAgICAvKioKKyAgICAgKiBUaGUge0Bjb2RlIGludH0gdmFsdWUgcmVwcmVzZW50aW5nIHRoZSB7QGNvZGUgc3luY2hyb25pemVkfQorICAgICAqIG1vZGlmaWVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNZTkNIUk9OSVpFRCA9IDB4MjA7CisKKyAgICAvKioKKyAgICAgKiBUaGUge0Bjb2RlIGludH0gdmFsdWUgcmVwcmVzZW50aW5nIHRoZSB7QGNvZGUgdm9sYXRpbGV9CisgICAgICogbW9kaWZpZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVk9MQVRJTEUgPSAweDQwOworCisgICAgLyoqCisgICAgICogVGhlIHtAY29kZSBpbnR9IHZhbHVlIHJlcHJlc2VudGluZyB0aGUge0Bjb2RlIHRyYW5zaWVudH0KKyAgICAgKiBtb2RpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUUkFOU0lFTlQgPSAweDgwOworCisgICAgLyoqCisgICAgICogVGhlIHtAY29kZSBpbnR9IHZhbHVlIHJlcHJlc2VudGluZyB0aGUge0Bjb2RlIG5hdGl2ZX0gbW9kaWZpZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkFUSVZFID0gMHgxMDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUge0Bjb2RlIGludH0gdmFsdWUgcmVwcmVzZW50aW5nIHRoZSB7QGNvZGUgaW50ZXJmYWNlfQorICAgICAqIG1vZGlmaWVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVEVSRkFDRSA9IDB4MjAwOworCisgICAgLyoqCisgICAgICogVGhlIHtAY29kZSBpbnR9IHZhbHVlIHJlcHJlc2VudGluZyB0aGUge0Bjb2RlIGFic3RyYWN0fQorICAgICAqIG1vZGlmaWVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFCU1RSQUNUID0gMHg0MDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUge0Bjb2RlIGludH0gdmFsdWUgcmVwcmVzZW50aW5nIHRoZSB7QGNvZGUgc3RyaWN0fSBtb2RpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJJQ1QgPSAweDgwMDsKKworICAgIC8vIE5vbi1wdWJsaWMgdHlwZXMgcmVxdWlyZWQgYnkgSmF2YSA1IHVwZGF0ZSB0byBjbGFzcyBmaWxlIGZvcm1hdAorICAgIHN0YXRpYyBmaW5hbCBpbnQgQlJJREdFID0gMHg0MDsKKworICAgIHN0YXRpYyBmaW5hbCBpbnQgVkFSQVJHUyA9IDB4ODA7CisKKyAgICBzdGF0aWMgZmluYWwgaW50IFNZTlRIRVRJQyA9IDB4MTAwMDsKKworICAgIHN0YXRpYyBmaW5hbCBpbnQgQU5OT1RBVElPTiA9IDB4MjAwMDsKKworICAgIHN0YXRpYyBmaW5hbCBpbnQgRU5VTSA9IDB4NDAwMDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIE1vZGlmaWVyfSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTW9kaWZpZXIoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG1hc2sgb2YgYWxsIHRoZSBtb2RpZmllcnMgdGhhdCBtYXkgYmUgYXBwbGllZCB0byBjbGFzc2VzLgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBjbGFzc01vZGlmaWVycygpIHsKKyAgICAgICAgcmV0dXJuIFBVQkxJQyB8IFBST1RFQ1RFRCB8IFBSSVZBVEUgfCBBQlNUUkFDVCB8IFNUQVRJQyB8IEZJTkFMIHwgU1RSSUNUOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBtYXNrIG9mIGFsbCB0aGUgbW9kaWZpZXJzIHRoYXQgbWF5IGJlIGFwcGxpZWQgdG8gY29uc3RydWN0b3JzLgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBjb25zdHJ1Y3Rvck1vZGlmaWVycygpIHsKKyAgICAgICAgcmV0dXJuIFBVQkxJQyB8IFBST1RFQ1RFRCB8IFBSSVZBVEU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG1hc2sgb2YgYWxsIHRoZSBtb2RpZmllcnMgdGhhdCBtYXkgYmUgYXBwbGllZCB0byBmaWVsZHMuCisgICAgICogQHNpbmNlIDEuNworICAgICAqIEBoaWRlIDEuNworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGZpZWxkTW9kaWZpZXJzKCkgeworICAgICAgICByZXR1cm4gUFVCTElDIHwgUFJPVEVDVEVEIHwgUFJJVkFURSB8IFNUQVRJQyB8IEZJTkFMIHwgVFJBTlNJRU5UIHwgVk9MQVRJTEU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG1hc2sgb2YgYWxsIHRoZSBtb2RpZmllcnMgdGhhdCBtYXkgYmUgYXBwbGllZCB0byBpbnRlcmZhY2VzLgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBpbnRlcmZhY2VNb2RpZmllcnMoKSB7CisgICAgICAgIHJldHVybiBQVUJMSUMgfCBQUk9URUNURUQgfCBQUklWQVRFIHwgQUJTVFJBQ1QgfCBTVEFUSUMgfCBTVFJJQ1Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG1hc2sgb2YgYWxsIHRoZSBtb2RpZmllcnMgdGhhdCBtYXkgYmUgYXBwbGllZCB0byBtZXRob2RzLgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBtZXRob2RNb2RpZmllcnMoKSB7CisgICAgICAgIHJldHVybiBQVUJMSUMgfCBQUk9URUNURUQgfCBQUklWQVRFIHwgQUJTVFJBQ1QgfCBTVEFUSUMgfCBGSU5BTCB8IFNZTkNIUk9OSVpFRCB8IE5BVElWRSB8IFNUUklDVDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhlIHNwZWNpZmllZCBtb2RpZmllcnMgY29udGFpbiB0aGUge0Bjb2RlCisgICAgICogYWJzdHJhY3R9IG1vZGlmaWVyLgorICAgICAqCisgICAgICogQHBhcmFtIG1vZGlmaWVycworICAgICAqICAgICAgICAgICAgdGhlIG1vZGlmaWVycyB0byB0ZXN0CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBtb2RpZmllcnMgY29udGFpbiB0aGUge0Bjb2RlCisgICAgICogICAgICAgICBhYnN0cmFjdH0gbW9kaWZpZXIsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzQWJzdHJhY3QoaW50IG1vZGlmaWVycykgeworICAgICAgICByZXR1cm4gKChtb2RpZmllcnMgJiBBQlNUUkFDVCkgIT0gMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBzcGVjaWZpZWQgbW9kaWZpZXJzIGNvbnRhaW4gdGhlIHtAY29kZQorICAgICAqIGZpbmFsfSBtb2RpZmllci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb2RpZmllcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBtb2RpZmllcnMgdG8gdGVzdAorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgbW9kaWZpZXJzIGNvbnRhaW4gdGhlIHtAY29kZQorICAgICAqICAgICAgICAgZmluYWx9IG1vZGlmaWVyLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0ZpbmFsKGludCBtb2RpZmllcnMpIHsKKyAgICAgICAgcmV0dXJuICgobW9kaWZpZXJzICYgRklOQUwpICE9IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgc3BlY2lmaWVkIG1vZGlmaWVycyBjb250YWluIHRoZSB7QGNvZGUKKyAgICAgKiBpbnRlcmZhY2V9IG1vZGlmaWVyLgorICAgICAqCisgICAgICogQHBhcmFtIG1vZGlmaWVycworICAgICAqICAgICAgICAgICAgdGhlIG1vZGlmaWVycyB0byB0ZXN0CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBtb2RpZmllcnMgY29udGFpbiB0aGUge0Bjb2RlCisgICAgICogICAgICAgICBpbnRlcmZhY2V9IG1vZGlmaWVyLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0ludGVyZmFjZShpbnQgbW9kaWZpZXJzKSB7CisgICAgICAgIHJldHVybiAoKG1vZGlmaWVycyAmIElOVEVSRkFDRSkgIT0gMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBzcGVjaWZpZWQgbW9kaWZpZXJzIGNvbnRhaW4gdGhlIHtAY29kZQorICAgICAqIG5hdGl2ZX0gbW9kaWZpZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbW9kaWZpZXJzCisgICAgICogICAgICAgICAgICB0aGUgbW9kaWZpZXJzIHRvIHRlc3QKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG1vZGlmaWVycyBjb250YWluIHRoZSB7QGNvZGUKKyAgICAgKiAgICAgICAgIG5hdGl2ZX0gbW9kaWZpZXIsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTmF0aXZlKGludCBtb2RpZmllcnMpIHsKKyAgICAgICAgcmV0dXJuICgobW9kaWZpZXJzICYgTkFUSVZFKSAhPSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhlIHNwZWNpZmllZCBtb2RpZmllcnMgY29udGFpbiB0aGUge0Bjb2RlCisgICAgICogcHJpdmF0ZX0gbW9kaWZpZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbW9kaWZpZXJzCisgICAgICogICAgICAgICAgICB0aGUgbW9kaWZpZXJzIHRvIHRlc3QKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG1vZGlmaWVycyBjb250YWluIHRoZSB7QGNvZGUKKyAgICAgKiAgICAgICAgIHByaXZhdGV9IG1vZGlmaWVyLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1ByaXZhdGUoaW50IG1vZGlmaWVycykgeworICAgICAgICByZXR1cm4gKChtb2RpZmllcnMgJiBQUklWQVRFKSAhPSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhlIHNwZWNpZmllZCBtb2RpZmllcnMgY29udGFpbiB0aGUge0Bjb2RlCisgICAgICogcHJvdGVjdGVkfSBtb2RpZmllci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb2RpZmllcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBtb2RpZmllcnMgdG8gdGVzdAorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgbW9kaWZpZXJzIGNvbnRhaW4gdGhlIHtAY29kZQorICAgICAqICAgICAgICAgcHJvdGVjdGVkfSBtb2RpZmllciwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNQcm90ZWN0ZWQoaW50IG1vZGlmaWVycykgeworICAgICAgICByZXR1cm4gKChtb2RpZmllcnMgJiBQUk9URUNURUQpICE9IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgc3BlY2lmaWVkIG1vZGlmaWVycyBjb250YWluIHRoZSB7QGNvZGUKKyAgICAgKiBwdWJsaWN9IG1vZGlmaWVyLgorICAgICAqCisgICAgICogQHBhcmFtIG1vZGlmaWVycworICAgICAqICAgICAgICAgICAgdGhlIG1vZGlmaWVycyB0byB0ZXN0CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBtb2RpZmllcnMgY29udGFpbiB0aGUge0Bjb2RlCisgICAgICogICAgICAgICBwdWJsaWN9IG1vZGlmaWVyLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1B1YmxpYyhpbnQgbW9kaWZpZXJzKSB7CisgICAgICAgIHJldHVybiAoKG1vZGlmaWVycyAmIFBVQkxJQykgIT0gMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBzcGVjaWZpZWQgbW9kaWZpZXJzIGNvbnRhaW4gdGhlIHtAY29kZQorICAgICAqIHN0YXRpY30gbW9kaWZpZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbW9kaWZpZXJzCisgICAgICogICAgICAgICAgICB0aGUgbW9kaWZpZXJzIHRvIHRlc3QKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG1vZGlmaWVycyBjb250YWluIHRoZSB7QGNvZGUKKyAgICAgKiAgICAgICAgIHN0YXRpY30gbW9kaWZpZXIsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzU3RhdGljKGludCBtb2RpZmllcnMpIHsKKyAgICAgICAgcmV0dXJuICgobW9kaWZpZXJzICYgU1RBVElDKSAhPSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhlIHNwZWNpZmllZCBtb2RpZmllcnMgY29udGFpbiB0aGUge0Bjb2RlCisgICAgICogc3RyaWN0fSBtb2RpZmllci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb2RpZmllcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBtb2RpZmllcnMgdG8gdGVzdAorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgbW9kaWZpZXJzIGNvbnRhaW4gdGhlIHtAY29kZQorICAgICAqICAgICAgICAgc3RyaWN0fSBtb2RpZmllciwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNTdHJpY3QoaW50IG1vZGlmaWVycykgeworICAgICAgICByZXR1cm4gKChtb2RpZmllcnMgJiBTVFJJQ1QpICE9IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgc3BlY2lmaWVkIG1vZGlmaWVycyBjb250YWluIHRoZSB7QGNvZGUKKyAgICAgKiBzeW5jaHJvbml6ZWR9IG1vZGlmaWVyLgorICAgICAqCisgICAgICogQHBhcmFtIG1vZGlmaWVycworICAgICAqICAgICAgICAgICAgdGhlIG1vZGlmaWVycyB0byB0ZXN0CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBtb2RpZmllcnMgY29udGFpbiB0aGUge0Bjb2RlCisgICAgICogICAgICAgICBzeW5jaHJvbml6ZWR9IG1vZGlmaWVyLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1N5bmNocm9uaXplZChpbnQgbW9kaWZpZXJzKSB7CisgICAgICAgIHJldHVybiAoKG1vZGlmaWVycyAmIFNZTkNIUk9OSVpFRCkgIT0gMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBzcGVjaWZpZWQgbW9kaWZpZXJzIGNvbnRhaW4gdGhlIHtAY29kZQorICAgICAqIHRyYW5zaWVudH0gbW9kaWZpZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbW9kaWZpZXJzCisgICAgICogICAgICAgICAgICB0aGUgbW9kaWZpZXJzIHRvIHRlc3QKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG1vZGlmaWVycyBjb250YWluIHRoZSB7QGNvZGUKKyAgICAgKiAgICAgICAgIHRyYW5zaWVudH0gbW9kaWZpZXIsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzVHJhbnNpZW50KGludCBtb2RpZmllcnMpIHsKKyAgICAgICAgcmV0dXJuICgobW9kaWZpZXJzICYgVFJBTlNJRU5UKSAhPSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhlIHNwZWNpZmllZCBtb2RpZmllcnMgY29udGFpbiB0aGUge0Bjb2RlCisgICAgICogdm9sYXRpbGV9IG1vZGlmaWVyLgorICAgICAqCisgICAgICogQHBhcmFtIG1vZGlmaWVycworICAgICAqICAgICAgICAgICAgdGhlIG1vZGlmaWVycyB0byB0ZXN0CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBtb2RpZmllcnMgY29udGFpbiB0aGUge0Bjb2RlCisgICAgICogICAgICAgICB2b2xhdGlsZX0gbW9kaWZpZXIsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzVm9sYXRpbGUoaW50IG1vZGlmaWVycykgeworICAgICAgICByZXR1cm4gKChtb2RpZmllcnMgJiBWT0xBVElMRSkgIT0gMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYWxsIG1vZGlmaWVycworICAgICAqIHByZXNlbnQgaW4gdGhlIHNwZWNpZmllZCBtb2RpZmllcnMuIE1vZGlmaWVycyBhcHBlYXIgaW4gdGhlIG9yZGVyCisgICAgICogc3BlY2lmaWVkIGJ5IHRoZSBKYXZhIExhbmd1YWdlIFNwZWNpZmljYXRpb246CisgICAgICoKKyAgICAgKiB7QGNvZGUgcHVibGljIHByaXZhdGUgcHJvdGVjdGVkIGFic3RyYWN0IHN0YXRpYyBmaW5hbCB0cmFuc2llbnQgdm9sYXRpbGUgbmF0aXZlIHN5bmNocm9uaXplZCBpbnRlcmZhY2Ugc3RyaWN0fQorICAgICAqCisgICAgICogQHBhcmFtIG1vZGlmaWVycworICAgICAqICAgICAgICAgICAgdGhlIG1vZGlmaWVycyB0byBwcmludAorICAgICAqIEByZXR1cm4gYSBwcmludGFibGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIG1vZGlmaWVycworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgamF2YS5sYW5nLlN0cmluZyB0b1N0cmluZyhpbnQgbW9kaWZpZXJzKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKworICAgICAgICBpZiAoaXNQdWJsaWMobW9kaWZpZXJzKSkgeworICAgICAgICAgICAgYnVmLmFwcGVuZCgicHVibGljICIpOworICAgICAgICB9CisgICAgICAgIGlmIChpc1Byb3RlY3RlZChtb2RpZmllcnMpKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKCJwcm90ZWN0ZWQgIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlzUHJpdmF0ZShtb2RpZmllcnMpKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKCJwcml2YXRlICIpOworICAgICAgICB9CisgICAgICAgIGlmIChpc0Fic3RyYWN0KG1vZGlmaWVycykpIHsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoImFic3RyYWN0ICIpOworICAgICAgICB9CisgICAgICAgIGlmIChpc1N0YXRpYyhtb2RpZmllcnMpKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKCJzdGF0aWMgIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlzRmluYWwobW9kaWZpZXJzKSkgeworICAgICAgICAgICAgYnVmLmFwcGVuZCgiZmluYWwgIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlzVHJhbnNpZW50KG1vZGlmaWVycykpIHsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoInRyYW5zaWVudCAiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaXNWb2xhdGlsZShtb2RpZmllcnMpKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKCJ2b2xhdGlsZSAiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaXNTeW5jaHJvbml6ZWQobW9kaWZpZXJzKSkgeworICAgICAgICAgICAgYnVmLmFwcGVuZCgic3luY2hyb25pemVkICIpOworICAgICAgICB9CisgICAgICAgIGlmIChpc05hdGl2ZShtb2RpZmllcnMpKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKCJuYXRpdmUgIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlzU3RyaWN0KG1vZGlmaWVycykpIHsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoInN0cmljdGZwICIpOworICAgICAgICB9CisgICAgICAgIGlmIChpc0ludGVyZmFjZShtb2RpZmllcnMpKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKCJpbnRlcmZhY2UgIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJ1Zi5sZW5ndGgoKSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gIiI7CisgICAgICAgIH0KKyAgICAgICAgYnVmLnNldExlbmd0aChidWYubGVuZ3RoKCkgLSAxKTsKKyAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9QYXJhbWV0ZXJpemVkVHlwZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L1BhcmFtZXRlcml6ZWRUeXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTliNmUzNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9QYXJhbWV0ZXJpemVkVHlwZS5qYXZhCkBAIC0wLDAgKzEsNzYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nLnJlZmxlY3Q7CisKKy8qKgorICogVGhpcyBpbnRlcmZhY2UgcmVwcmVzZW50cyBhIHBhcmFtZXRlcml6ZWQgdHlwZSBzdWNoIGFzIHtAY29kZQorICogJ1NldCZsdDtTdHJpbmcmZ3Q7J30uCisgKgorICogQHNpbmNlIDEuNQorICovCitwdWJsaWMgaW50ZXJmYWNlIFBhcmFtZXRlcml6ZWRUeXBlIGV4dGVuZHMgVHlwZSB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHRoZSBhY3R1YWwgdHlwZSBhcmd1bWVudHMgZm9yIHRoaXMgdHlwZS4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIHR5cGUgbW9kZWxzIGEgbm9uIHBhcmFtZXRlcml6ZWQgdHlwZSBuZXN0ZWQgd2l0aGluIGEKKyAgICAgKiBwYXJhbWV0ZXJpemVkIHR5cGUsIHRoaXMgbWV0aG9kIHJldHVybnMgYSB6ZXJvIGxlbmd0aCBhcnJheS4gVGhlIGdlbmVyaWMKKyAgICAgKiB0eXBlIG9mIHRoZSBmb2xsb3dpbmcge0Bjb2RlIGZpZWxkfSBkZWNsYXJhdGlvbiBpcyBhbiBleGFtcGxlIGZvciBhCisgICAgICogcGFyYW1ldGVyaXplZCB0eXBlIHdpdGhvdXQgdHlwZSBhcmd1bWVudHMuCisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqIEEmbHQ7U3RyaW5nJmd0Oy5CIGZpZWxkOworICAgICAqCisgICAgICogY2xhc3MgQSZsdDtUJmd0OyB7CisgICAgICogICAgIGNsYXNzIEIgeworICAgICAqICAgICB9CisgICAgICogfTwvcHJlPgorICAgICAqCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBhY3R1YWwgdHlwZSBhcmd1bWVudHMKKyAgICAgKgorICAgICAqIEB0aHJvd3MgVHlwZU5vdFByZXNlbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBvbmUgb2YgdGhlIHR5cGUgYXJndW1lbnRzIGNhbm5vdCBiZSBmb3VuZAorICAgICAqIEB0aHJvd3MgTWFsZm9ybWVkUGFyYW1ldGVyaXplZFR5cGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBvbmUgb2YgdGhlIHR5cGUgYXJndW1lbnRzIGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQgZm9yIHNvbWUKKyAgICAgKiAgICAgICAgICAgICByZWFzb24KKyAgICAgKi8KKyAgICBUeXBlW10gZ2V0QWN0dWFsVHlwZUFyZ3VtZW50cygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGFyZW50IC8gb3duZXIgdHlwZSwgaWYgdGhpcyB0eXBlIGlzIGFuIGlubmVyIHR5cGUsIG90aGVyd2lzZQorICAgICAqIHtAY29kZSBudWxsfSBpcyByZXR1cm5lZCBpZiB0aGlzIGlzIGEgdG9wLWxldmVsIHR5cGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBvd25lciB0eXBlIG9yIHtAY29kZSBudWxsfSBpZiB0aGlzIGlzIGEgdG9wLWxldmVsIHR5cGUKKyAgICAgKgorICAgICAqIEB0aHJvd3MgVHlwZU5vdFByZXNlbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBvbmUgb2YgdGhlIHR5cGUgYXJndW1lbnRzIGNhbm5vdCBiZSBmb3VuZAorICAgICAqIEB0aHJvd3MgTWFsZm9ybWVkUGFyYW1ldGVyaXplZFR5cGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgb3duZXIgdHlwZSBjYW5ub3QgYmUgaW5zdGFudGlhdGVkIGZvciBzb21lIHJlYXNvbgorICAgICAqLworICAgIFR5cGUgZ2V0T3duZXJUeXBlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWNsYXJpbmcgdHlwZSBvZiB0aGlzIHBhcmFtZXRlcml6ZWQgdHlwZS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcmF3IHR5cGUgb2Yge0Bjb2RlIFNldDxTdHJpbmc+IGZpZWxkO30gaXMge0Bjb2RlIFNldH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByYXcgdHlwZSBvZiB0aGlzIHBhcmFtZXRlcml6ZWQgdHlwZQorICAgICAqLworICAgIFR5cGUgZ2V0UmF3VHlwZSgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L1Byb3h5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvUHJveHkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMjQ1MTRkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L1Byb3h5LmphdmEKQEAgLTAsMCArMSwyNzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmLldlYWtSZWZlcmVuY2U7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuV2Vha0hhc2hNYXA7CisKKy8qKgorICoge0Bjb2RlIFByb3h5fSBkZWZpbmVzIG1ldGhvZHMgZm9yIGNyZWF0aW5nIGR5bmFtaWMgcHJveHkgY2xhc3NlcyBhbmQgaW5zdGFuY2VzLgorICogQSBwcm94eSBjbGFzcyBpbXBsZW1lbnRzIGEgZGVjbGFyZWQgc2V0IG9mIGludGVyZmFjZXMgYW5kIGRlbGVnYXRlcyBtZXRob2QKKyAqIGludm9jYXRpb25zIHRvIGFuIHtAY29kZSBJbnZvY2F0aW9uSGFuZGxlcn0uCisgKgorICogQHNlZSBJbnZvY2F0aW9uSGFuZGxlcgorICogQHNpbmNlIDEuMworICovCitwdWJsaWMgY2xhc3MgUHJveHkgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTIyMjI1NjgwNTY2ODY2MjM3OTdMOworCisgICAgLy8gbWFwcyBjbGFzcyBsb2FkZXJzIHRvIGNyZWF0ZWQgY2xhc3NlcyBieSBpbnRlcmZhY2UgbmFtZXMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8Q2xhc3NMb2FkZXIsIE1hcDxTdHJpbmcsIFdlYWtSZWZlcmVuY2U8Q2xhc3M8Pz4+Pj4gbG9hZGVyQ2FjaGUgPSBuZXcgV2Vha0hhc2hNYXA8Q2xhc3NMb2FkZXIsIE1hcDxTdHJpbmcsIFdlYWtSZWZlcmVuY2U8Q2xhc3M8Pz4+Pj4oKTsKKworICAgIC8vIHRvIGZpbmQgcHJldmlvdXNseSBjcmVhdGVkIHR5cGVzCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPENsYXNzPD8+LCBTdHJpbmc+IHByb3h5Q2FjaGUgPSBuZXcgV2Vha0hhc2hNYXA8Q2xhc3M8Pz4sIFN0cmluZz4oKTsKKworICAgIHByaXZhdGUgc3RhdGljIGludCBOZXh0Q2xhc3NOYW1lSW5kZXggPSAwOworCisgICAgLyoqCisgICAgICogVGhlIGludm9jYXRpb24gaGFuZGxlciBvbiB3aGljaCB0aGUgbWV0aG9kIGNhbGxzIGFyZSBkaXNwYXRjaGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBJbnZvY2F0aW9uSGFuZGxlciBoOworCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgICAgcHJpdmF0ZSBQcm94eSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBQcm94eX0gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGludm9jYXRpb24KKyAgICAgKiBoYW5kbGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnZvY2F0aW9uIGhhbmRsZXIgZm9yIHRoZSBuZXdseSBjcmVhdGVkIHByb3h5CisgICAgICovCisgICAgcHJvdGVjdGVkIFByb3h5KEludm9jYXRpb25IYW5kbGVyIGgpIHsKKyAgICAgICAgdGhpcy5oID0gaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkeW5hbWljYWxseSBidWlsdCB7QGNvZGUgQ2xhc3N9IGZvciB0aGUgc3BlY2lmaWVkIGludGVyZmFjZXMuCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2xhc3N9IHdoZW4gbmVjZXNzYXJ5LiBUaGUgb3JkZXIgb2YgdGhlIGludGVyZmFjZXMKKyAgICAgKiBpcyByZWxldmFudC4gSW52b2NhdGlvbnMgb2YgdGhpcyBtZXRob2Qgd2l0aCB0aGUgc2FtZSBpbnRlcmZhY2VzIGJ1dAorICAgICAqIGRpZmZlcmVudCBvcmRlciByZXN1bHQgaW4gZGlmZmVyZW50IGdlbmVyYXRlZCBjbGFzc2VzLiBUaGUgaW50ZXJmYWNlcworICAgICAqIG11c3QgYmUgdmlzaWJsZSBmcm9tIHRoZSBzdXBwbGllZCBjbGFzcyBsb2FkZXI7IG5vIGR1cGxpY2F0ZXMgYXJlCisgICAgICogcGVybWl0dGVkLiBBbGwgbm9uLXB1YmxpYyBpbnRlcmZhY2VzIG11c3QgYmUgZGVmaW5lZCBpbiB0aGUgc2FtZSBwYWNrYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGxvYWRlcgorICAgICAqICAgICAgICAgICAgdGhlIGNsYXNzIGxvYWRlciB0aGF0IHdpbGwgZGVmaW5lIHRoZSBwcm94eSBjbGFzcworICAgICAqIEBwYXJhbSBpbnRlcmZhY2VzCisgICAgICogICAgICAgICAgICBhbiBhcnJheSBvZiB7QGNvZGUgQ2xhc3N9IG9iamVjdHMsIGVhY2ggb25lIGlkZW50aWZ5aW5nIGFuCisgICAgICogICAgICAgICAgICBpbnRlcmZhY2UgdGhhdCB3aWxsIGJlIGltcGxlbWVudGVkIGJ5IHRoZSByZXR1cm5lZCBwcm94eQorICAgICAqICAgICAgICAgICAgY2xhc3MKKyAgICAgKiBAcmV0dXJuIGEgcHJveHkgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIGFsbCBvZiB0aGUgaW50ZXJmYWNlcyByZWZlcnJlZCB0bworICAgICAqICAgICAgICAgaW4gdGhlIGNvbnRlbnRzIG9mIHtAY29kZSBpbnRlcmZhY2VzfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW55IG9mIHRoZSBpbnRlcmZhY2UgcmVzdHJpY3Rpb25zIGFyZSB2aW9sYXRlZAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBlaXRoZXIge0Bjb2RlIGludGVyZmFjZXN9IG9yIGFueSBvZiBpdHMgZWxlbWVudHMgYXJlCisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIG51bGx9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDbGFzczw/PiBnZXRQcm94eUNsYXNzKENsYXNzTG9hZGVyIGxvYWRlciwKKyAgICAgICAgICAgIENsYXNzPD8+Li4uIGludGVyZmFjZXMpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICAvLyBjaGVjayB0aGF0IGludGVyZmFjZXMgYXJlIGEgdmFsaWQgYXJyYXkgb2YgdmlzaWJsZSBpbnRlcmZhY2VzCisgICAgICAgIGlmIChpbnRlcmZhY2VzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBjb21tb25QYWNrYWdlTmFtZSA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwLCBsZW5ndGggPSBpbnRlcmZhY2VzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBDbGFzczw/PiBuZXh0ID0gaW50ZXJmYWNlc1tpXTsKKyAgICAgICAgICAgIGlmIChuZXh0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN0cmluZyBuYW1lID0gbmV4dC5nZXROYW1lKCk7CisgICAgICAgICAgICBpZiAoIW5leHQuaXNJbnRlcmZhY2UoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24obmFtZSArICIgaXMgbm90IGFuIGludGVyZmFjZSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGxvYWRlciAhPSBuZXh0LmdldENsYXNzTG9hZGVyKCkpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBpZiAobmV4dCAhPSBDbGFzcy5mb3JOYW1lKG5hbWUsIGZhbHNlLCBsb2FkZXIpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKG5hbWUgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGlzIG5vdCB2aXNpYmxlIGZyb20gY2xhc3MgbG9hZGVyIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24obmFtZSArICIgaXMgbm90IHZpc2libGUgZnJvbSBjbGFzcyBsb2FkZXIiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKGludCBqID0gaSArIDE7IGogPCBsZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgIGlmIChuZXh0ID09IGludGVyZmFjZXNbal0pIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihuYW1lICsgIiBhcHBlYXJzIG1vcmUgdGhhbiBvbmNlIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFNb2RpZmllci5pc1B1YmxpYyhuZXh0LmdldE1vZGlmaWVycygpKSkgeworICAgICAgICAgICAgICAgIGludCBsYXN0ID0gbmFtZS5sYXN0SW5kZXhPZignLicpOworICAgICAgICAgICAgICAgIFN0cmluZyBwID0gbGFzdCA9PSAtMSA/ICIiIDogbmFtZS5zdWJzdHJpbmcoMCwgbGFzdCk7CisgICAgICAgICAgICAgICAgaWYgKGNvbW1vblBhY2thZ2VOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgY29tbW9uUGFja2FnZU5hbWUgPSBwOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWNvbW1vblBhY2thZ2VOYW1lLmVxdWFscyhwKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJub24tcHVibGljIGludGVyZmFjZXMgbXVzdCBiZSAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW4gdGhlIHNhbWUgcGFja2FnZSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHNlYXJjaCBjYWNoZSBmb3IgbWF0Y2hpbmcgcHJveHkgY2xhc3MgdXNpbmcgdGhlIGNsYXNzIGxvYWRlcgorICAgICAgICBzeW5jaHJvbml6ZWQgKGxvYWRlckNhY2hlKSB7CisgICAgICAgICAgICBNYXA8U3RyaW5nLCBXZWFrUmVmZXJlbmNlPENsYXNzPD8+Pj4gaW50ZXJmYWNlQ2FjaGUgPSBsb2FkZXJDYWNoZQorICAgICAgICAgICAgICAgICAgICAuZ2V0KGxvYWRlcik7CisgICAgICAgICAgICBpZiAoaW50ZXJmYWNlQ2FjaGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGxvYWRlckNhY2hlCisgICAgICAgICAgICAgICAgICAgICAgICAucHV0KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2FkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnRlcmZhY2VDYWNoZSA9IG5ldyBIYXNoTWFwPFN0cmluZywgV2Vha1JlZmVyZW5jZTxDbGFzczw/Pj4+KCkpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU3RyaW5nIGludGVyZmFjZUtleSA9ICIiOworICAgICAgICAgICAgaWYgKGludGVyZmFjZXMubGVuZ3RoID09IDEpIHsKKyAgICAgICAgICAgICAgICBpbnRlcmZhY2VLZXkgPSBpbnRlcmZhY2VzWzBdLmdldE5hbWUoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBuYW1lcyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAsIGxlbmd0aCA9IGludGVyZmFjZXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgbmFtZXMuYXBwZW5kKGludGVyZmFjZXNbaV0uZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgbmFtZXMuYXBwZW5kKCcgJyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGludGVyZmFjZUtleSA9IG5hbWVzLnRvU3RyaW5nKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIENsYXNzPD8+IG5ld0NsYXNzOworICAgICAgICAgICAgV2Vha1JlZmVyZW5jZTxDbGFzczw/Pj4gcmVmID0gaW50ZXJmYWNlQ2FjaGUuZ2V0KGludGVyZmFjZUtleSk7CisgICAgICAgICAgICBpZiAocmVmID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgbmV4dENsYXNzTmFtZSA9ICIkUHJveHkiICsgTmV4dENsYXNzTmFtZUluZGV4Kys7CisgICAgICAgICAgICAgICAgaWYgKGNvbW1vblBhY2thZ2VOYW1lICE9IG51bGwgJiYgY29tbW9uUGFja2FnZU5hbWUubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIG5leHRDbGFzc05hbWUgPSBjb21tb25QYWNrYWdlTmFtZSArICIuIiArIG5leHRDbGFzc05hbWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChsb2FkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBsb2FkZXIgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBuZXdDbGFzcyA9IGdlbmVyYXRlUHJveHkobmV4dENsYXNzTmFtZS5yZXBsYWNlKCcuJywgJy8nKSwgaW50ZXJmYWNlcywgbG9hZGVyKTsKKyAgICAgICAgICAgICAgICAvLyBOZWVkIGEgd2VhayByZWZlcmVuY2UgdG8gdGhlIGNsYXNzIHNvIGl0IGNhbgorICAgICAgICAgICAgICAgIC8vIGJlIHVubG9hZGVkIGlmIHRoZSBjbGFzcyBsb2FkZXIgaXMgZGlzY2FyZGVkCisgICAgICAgICAgICAgICAgaW50ZXJmYWNlQ2FjaGUucHV0KGludGVyZmFjZUtleSwgbmV3IFdlYWtSZWZlcmVuY2U8Q2xhc3M8Pz4+KG5ld0NsYXNzKSk7CisgICAgICAgICAgICAgICAgc3luY2hyb25pemVkIChwcm94eUNhY2hlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIHRoZSB2YWx1ZSBpcyB1bnVzZWQKKyAgICAgICAgICAgICAgICAgICAgcHJveHlDYWNoZS5wdXQobmV3Q2xhc3MsICIiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG5ld0NsYXNzID0gcmVmLmdldCgpOworICAgICAgICAgICAgICAgIGFzc2VydCBuZXdDbGFzcyAhPSBudWxsIDogIlxuaW50ZXJmYWNlS2V5PVwiIiArIGludGVyZmFjZUtleSArICJcIiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJcbmxvYWRlckNhY2hlPVwiIiArIGxvYWRlckNhY2hlICsgIlwiIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIlxuaW50ZkNhY2hlPVwiIiArIGludGVyZmFjZUNhY2hlICsgIlwiIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIlxucHJveHlDYWNoZT1cIiIgKyBwcm94eUNhY2hlICsgIlwiIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuZXdDbGFzczsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgdGhlIGR5bmFtaWNhbGx5IGJ1aWx0IGNsYXNzIGZvciB0aGUgc3BlY2lmaWVkCisgICAgICogaW50ZXJmYWNlcy4gTWV0aG9kIGludm9jYXRpb25zIG9uIHRoZSByZXR1cm5lZCBpbnN0YW5jZSBhcmUgZm9yd2FyZGVkIHRvCisgICAgICogdGhlIHNwZWNpZmllZCBpbnZvY2F0aW9uIGhhbmRsZXIuIFRoZSBpbnRlcmZhY2VzIG11c3QgYmUgdmlzaWJsZSBmcm9tIHRoZQorICAgICAqIHN1cHBsaWVkIGNsYXNzIGxvYWRlcjsgbm8gZHVwbGljYXRlcyBhcmUgcGVybWl0dGVkLiBBbGwgbm9uLXB1YmxpYworICAgICAqIGludGVyZmFjZXMgbXVzdCBiZSBkZWZpbmVkIGluIHRoZSBzYW1lIHBhY2thZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9hZGVyCisgICAgICogICAgICAgICAgICB0aGUgY2xhc3MgbG9hZGVyIHRoYXQgd2lsbCBkZWZpbmUgdGhlIHByb3h5IGNsYXNzCisgICAgICogQHBhcmFtIGludGVyZmFjZXMKKyAgICAgKiAgICAgICAgICAgIGFuIGFycmF5IG9mIHtAY29kZSBDbGFzc30gb2JqZWN0cywgZWFjaCBvbmUgaWRlbnRpZnlpbmcgYW4KKyAgICAgKiAgICAgICAgICAgIGludGVyZmFjZSB0aGF0IHdpbGwgYmUgaW1wbGVtZW50ZWQgYnkgdGhlIHJldHVybmVkIHByb3h5CisgICAgICogICAgICAgICAgICBvYmplY3QKKyAgICAgKiBAcGFyYW0gaAorICAgICAqICAgICAgICAgICAgdGhlIGludm9jYXRpb24gaGFuZGxlciB0aGF0IGhhbmRsZXMgdGhlIGRpc3BhdGNoZWQgbWV0aG9kCisgICAgICogICAgICAgICAgICBpbnZvY2F0aW9ucworICAgICAqIEByZXR1cm4gYSBuZXcgcHJveHkgb2JqZWN0IHRoYXQgZGVsZWdhdGVzIHRvIHRoZSBoYW5kbGVyIHtAY29kZSBofQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW55IG9mIHRoZSBpbnRlcmZhY2UgcmVzdHJpY3Rpb25zIGFyZSB2aW9sYXRlZAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgaW50ZXJmYWNlcyBvciBhbnkgb2YgaXRzIGVsZW1lbnRzIGFyZSBudWxsCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBPYmplY3QgbmV3UHJveHlJbnN0YW5jZShDbGFzc0xvYWRlciBsb2FkZXIsCisgICAgICAgICAgICBDbGFzczw/PltdIGludGVyZmFjZXMsIEludm9jYXRpb25IYW5kbGVyIGgpCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGggPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBnZXRQcm94eUNsYXNzKGxvYWRlciwgaW50ZXJmYWNlcykuZ2V0Q29uc3RydWN0b3IoCisgICAgICAgICAgICAgICAgICAgIG5ldyBDbGFzczw/PltdIHsgSW52b2NhdGlvbkhhbmRsZXIuY2xhc3MgfSkubmV3SW5zdGFuY2UoCisgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGggfSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgKEludGVybmFsRXJyb3IpIChuZXcgSW50ZXJuYWxFcnJvcihleC50b1N0cmluZygpKQorICAgICAgICAgICAgICAgICAgICAuaW5pdENhdXNlKGV4KSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IChJbnRlcm5hbEVycm9yKSAobmV3IEludGVybmFsRXJyb3IoZXgudG9TdHJpbmcoKSkKKyAgICAgICAgICAgICAgICAgICAgLmluaXRDYXVzZShleCkpOworICAgICAgICB9IGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyAoSW50ZXJuYWxFcnJvcikgKG5ldyBJbnRlcm5hbEVycm9yKGV4LnRvU3RyaW5nKCkpCisgICAgICAgICAgICAgICAgICAgIC5pbml0Q2F1c2UoZXgpKTsKKyAgICAgICAgfSBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgVGhyb3dhYmxlIHRhcmdldCA9IGV4LmdldFRhcmdldEV4Y2VwdGlvbigpOworICAgICAgICAgICAgdGhyb3cgKEludGVybmFsRXJyb3IpIChuZXcgSW50ZXJuYWxFcnJvcih0YXJnZXQudG9TdHJpbmcoKSkKKyAgICAgICAgICAgICAgICAgICAgLmluaXRDYXVzZSh0YXJnZXQpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgc3BlY2lmaWVkIGNsYXNzIGlzIGEgZHluYW1pY2FsbHkgZ2VuZXJhdGVkCisgICAgICogcHJveHkgY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2wKKyAgICAgKiAgICAgICAgICAgIHRoZSBjbGFzcworICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBjbGFzcyBpcyBhIHByb3h5IGNsYXNzLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIGNsYXNzIGlzIHtAY29kZSBudWxsfQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1Byb3h5Q2xhc3MoQ2xhc3M8Pz4gY2wpIHsKKyAgICAgICAgaWYgKGNsID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHN5bmNocm9uaXplZCAocHJveHlDYWNoZSkgeworICAgICAgICAgICAgcmV0dXJuIHByb3h5Q2FjaGUuY29udGFpbnNLZXkoY2wpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW52b2NhdGlvbiBoYW5kbGVyIG9mIHRoZSBzcGVjaWZpZWQgcHJveHkgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJveHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm94eSBpbnN0YW5jZQorICAgICAqIEByZXR1cm4gdGhlIGludm9jYXRpb24gaGFuZGxlciBvZiB0aGUgc3BlY2lmaWVkIHByb3h5IGluc3RhbmNlCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgc3VwcGxpZWQge0Bjb2RlIHByb3h5fSBpcyBub3QgYSBwcm94eSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEludm9jYXRpb25IYW5kbGVyIGdldEludm9jYXRpb25IYW5kbGVyKE9iamVjdCBwcm94eSkKKyAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworCisgICAgICAgIGlmIChpc1Byb3h5Q2xhc3MocHJveHkuZ2V0Q2xhc3MoKSkpIHsKKyAgICAgICAgICAgIHJldHVybiAoKFByb3h5KSBwcm94eSkuaDsKKyAgICAgICAgfQorCisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm5vdCBhIHByb3h5IGluc3RhbmNlIik7CisgICAgfQorCisgICAgbmF0aXZlIHByaXZhdGUgc3RhdGljIENsYXNzIGdlbmVyYXRlUHJveHkoU3RyaW5nIG5hbWUsIENsYXNzW10gaW50ZXJmYWNlcywKKyAgICAgICAgQ2xhc3NMb2FkZXIgbG9hZGVyKTsKKworICAgIC8qCisgICAgICogVGhlIFZNIGNsb25lcyB0aGlzIG1ldGhvZCdzIGRlc2NyaXB0b3Igd2hlbiBnZW5lcmF0aW5nIGEgcHJveHkgY2xhc3MuCisgICAgICogVGhlcmUgaXMgbm8gaW1wbGVtZW50YXRpb24uCisgICAgICovCisgICAgbmF0aXZlIHByaXZhdGUgc3RhdGljIHZvaWQgY29uc3RydWN0b3JQcm90b3R5cGUoSW52b2NhdGlvbkhhbmRsZXIgaCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvUmVmbGVjdFBlcm1pc3Npb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9SZWZsZWN0UGVybWlzc2lvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRkMTBhODAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvUmVmbGVjdFBlcm1pc3Npb24uamF2YQpAQCAtMCwwICsxLDM0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubGFuZy5yZWZsZWN0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5CYXNpY1Blcm1pc3Npb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uOworCisvKioKKyAqIExlZ2FjeSBzZWN1cml0eSBjb2RlOyBkbyBub3QgdXNlLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUmVmbGVjdFBlcm1pc3Npb24gZXh0ZW5kcyBCYXNpY1Blcm1pc3Npb24geworICAgIHB1YmxpYyBSZWZsZWN0UGVybWlzc2lvbihTdHJpbmcgbmFtZSkgeyBzdXBlcigiIik7IH0KKworICAgIHB1YmxpYyBSZWZsZWN0UGVybWlzc2lvbihTdHJpbmcgbmFtZSwgU3RyaW5nIGFjdGlvbnMpIHsgc3VwZXIoIiIsICIiKTsgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgZ2V0QWN0aW9ucygpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpbXBsaWVzKFBlcm1pc3Npb24gcGVybWlzc2lvbikgeyByZXR1cm4gdHJ1ZTsgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L1R5cGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9UeXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjhiMDA4MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9UeXBlLmphdmEKQEAgLTAsMCArMSwyNiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcucmVmbGVjdDsKKworLyoqCisgKiBDb21tb24gaW50ZXJmYWNlIGltcGxlbWVudGVkIGJ5IGFsbCBKYXZhIHR5cGVzLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqLworcHVibGljIGludGVyZmFjZSBUeXBlIHsKKyAgICAvLyBFbXB0eQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L1R5cGVWYXJpYWJsZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L1R5cGVWYXJpYWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZhYjYzZGIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvVHlwZVZhcmlhYmxlLmphdmEKQEAgLTAsMCArMSw1OSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcucmVmbGVjdDsKKworLyoqCisgKiBUaGlzIGludGVyZmFjZSByZXByZXNlbnRzIGEgdHlwZSB2YXJpYWJsZXMgc3VjaCBhcyB7QGNvZGUgJ1QnfSBpbiB7QGNvZGUKKyAqICdwdWJsaWMgaW50ZXJmYWNlIENvbXBhcmFibGU8VD4nfSwgdGhlIGJvdW5kZWQge0Bjb2RlICdUJ30gaW4ge0Bjb2RlCisgKiAncHVibGljIGludGVyZmFjZSBBPFQgZXh0ZW5kcyBOdW1iZXI+J30gb3IgdGhlIG11bHRpcGxlIGJvdW5kZWQge0Bjb2RlCisgKiAnVCd9IGluIHtAY29kZSAncHVibGljIGludGVyZmFjZSBCPFQgZXh0ZW5kcyBOdW1iZXIgJiBDbG9uZWFibGU+J30uCisgKgorICogQHBhcmFtIDxEPgorICogICAgICAgICAgICB0aGUgZ2VuZXJpYyBkZWNsYXJhdGlvbiB0aGF0IGRlY2xhcmVzIHRoaXMgdHlwZSB2YXJpYWJsZQorICogQHNpbmNlIDEuNQorICovCitwdWJsaWMgaW50ZXJmYWNlIFR5cGVWYXJpYWJsZTxEIGV4dGVuZHMgR2VuZXJpY0RlY2xhcmF0aW9uPiBleHRlbmRzIFR5cGUgeworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdXBwZXIgYm91bmRzIG9mIHRoaXMgdHlwZSB2YXJpYWJsZS4ge0Bjb2RlIE9iamVjdH0gaXMgdGhlCisgICAgICogaW1wbGljaXQgdXBwZXIgYm91bmQgaWYgbm8gb3RoZXIgYm91bmRzIGFyZSBkZWNsYXJlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHVwcGVyIGJvdW5kcyBvZiB0aGlzIHR5cGUgdmFyaWFibGUKKyAgICAgKgorICAgICAqIEB0aHJvd3MgVHlwZU5vdFByZXNlbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgb2YgdGhlIGJvdW5kcyBwb2ludHMgdG8gYSBtaXNzaW5nIHR5cGUKKyAgICAgKiBAdGhyb3dzIE1hbGZvcm1lZFBhcmFtZXRlcml6ZWRUeXBlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IG9mIHRoZSBib3VuZHMgcG9pbnRzIHRvIGEgdHlwZSB0aGF0IGNhbm5vdCBiZQorICAgICAqICAgICAgICAgICAgIGluc3RhbnRpYXRlZCBmb3Igc29tZSByZWFzb24KKyAgICAgKi8KKyAgICBUeXBlW10gZ2V0Qm91bmRzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsYW5ndWFnZSBjb25zdHJ1Y3QgdGhhdCBkZWNsYXJlcyB0aGlzIHR5cGUgdmFyaWFibGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBnZW5lcmljIGRlY2xhcmF0aW9uCisgICAgICovCisgICAgRCBnZXRHZW5lcmljRGVjbGFyYXRpb24oKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhpcyB0eXBlIHZhcmlhYmxlIGFzIGl0IGlzIHNwZWNpZmllZCBpbiBzb3VyY2UKKyAgICAgKiBjb2RlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGlzIHR5cGUgdmFyaWFibGUKKyAgICAgKi8KKyAgICBTdHJpbmcgZ2V0TmFtZSgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L1VuZGVjbGFyZWRUaHJvd2FibGVFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9VbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjVlZWQxNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL2xhbmcvcmVmbGVjdC9VbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw4MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcucmVmbGVjdDsKKworLyoqCisgKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGEgd3JhcHBlciBmb3IgYW4gdW5kZWNsYXJlZCwgY2hlY2tlZCBleGNlcHRpb24gdGhyb3duIGJ5CisgKiBhbiBJbnZvY2F0aW9uSGFuZGxlci4KKyAqCisgKiBAc2VlIGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25IYW5kbGVyI2ludm9rZQorICovCitwdWJsaWMgY2xhc3MgVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzMwMTI3MTE0MDU1MDU2NjM5TDsKKworICAgIHByaXZhdGUgVGhyb3dhYmxlIHVuZGVjbGFyZWRUaHJvd2FibGU7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBVbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9ufSBpbnN0YW5jZSB3aXRoIHRoZQorICAgICAqIHVuZGVjbGFyZWQsIGNoZWNrZWQgZXhjZXB0aW9uIHRoYXQgb2NjdXJyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhjZXB0aW9uCisgICAgICogICAgICAgICAgICB0aGUgdW5kZWNsYXJlZCwgY2hlY2tlZCBleGNlcHRpb24gdGhhdCBvY2N1cnJlZAorICAgICAqLworICAgIHB1YmxpYyBVbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9uKFRocm93YWJsZSBleGNlcHRpb24pIHsKKyAgICAgICAgdGhpcy51bmRlY2xhcmVkVGhyb3dhYmxlID0gZXhjZXB0aW9uOworICAgICAgICBpbml0Q2F1c2UoZXhjZXB0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBVbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9ufSBpbnN0YW5jZSB3aXRoIHRoZQorICAgICAqIHVuZGVjbGFyZWQsIGNoZWNrZWQgZXhjZXB0aW9uIHRoYXQgb2NjdXJyZWQgYW5kIGEgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24KKyAgICAgKiBAcGFyYW0gZXhjZXB0aW9uCisgICAgICogICAgICAgICAgICB0aGUgdW5kZWNsYXJlZCwgY2hlY2tlZCBleGNlcHRpb24gdGhhdCBvY2N1cnJlZAorICAgICAqLworICAgIHB1YmxpYyBVbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9uKFRocm93YWJsZSBleGNlcHRpb24sCisgICAgICAgICAgICBTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICAgICAgdGhpcy51bmRlY2xhcmVkVGhyb3dhYmxlID0gZXhjZXB0aW9uOworICAgICAgICBpbml0Q2F1c2UoZXhjZXB0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB1bmRlY2xhcmVkLCBjaGVja2VkIGV4Y2VwdGlvbiB0aGF0IG9jY3VycmVkLCB3aGljaCBtYXkgYmUKKyAgICAgKiB7QGNvZGUgbnVsbH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB1bmRlY2xhcmVkLCBjaGVja2VkIGV4Y2VwdGlvbiB0aGF0IG9jY3VycmVkCisgICAgICovCisgICAgcHVibGljIFRocm93YWJsZSBnZXRVbmRlY2xhcmVkVGhyb3dhYmxlKCkgeworICAgICAgICByZXR1cm4gdW5kZWNsYXJlZFRocm93YWJsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB1bmRlY2xhcmVkLCBjaGVja2VkIGV4Y2VwdGlvbiB0aGF0IG9jY3VycmVkLCB3aGljaCBtYXkgYmUKKyAgICAgKiB7QGNvZGUgbnVsbH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB1bmRlY2xhcmVkLCBjaGVja2VkIGV4Y2VwdGlvbiB0aGF0IG9jY3VycmVkCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFRocm93YWJsZSBnZXRDYXVzZSgpIHsKKyAgICAgICAgcmV0dXJuIHVuZGVjbGFyZWRUaHJvd2FibGU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L1dpbGRjYXJkVHlwZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbGFuZy9yZWZsZWN0L1dpbGRjYXJkVHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMxZTEwMjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9sYW5nL3JlZmxlY3QvV2lsZGNhcmRUeXBlLmphdmEKQEAgLTAsMCArMSw2NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLmxhbmcucmVmbGVjdDsKKworLyoqCisgKiBBIHBhdHRlcm4gdHlwZSwgc3VjaCBhcyB0aGUgdXBwZXIgYm91bmRlZCB3aWxkY2FyZCB7QGNvZGUKKyAqID8gZXh0ZW5kcyBDbG9zZWFibGV9IG9yIHRoZSBsb3dlciBib3VuZGVkIHdpbGRjYXJkIHtAY29kZSA/IHN1cGVyIFN0cmluZ30uCisgKgorICogPHA+QWx0aG91Z2ggdGhpcyBpbnRlcmZhY2UgcGVybWl0cyBhbiBhcmJpdHJhcnkgbnVtYmVyIG9mIHVwcGVyIGFuZCBsb3dlcgorICogYm91bmRzLCBhbGwgd2lsZGNhcmQgdHlwZXMgb2YgSmF2YSBsYW5ndWFnZSBwcm9ncmFtcyBhcmUgaW4gb25lIG9mIHR3byBmb3JtczoKKyAqIDxvbD4KKyAqIDxsaT48c3Ryb25nPk5vIGxvd2VyIGJvdW5kIGFuZCBvbmUgdXBwZXIgYm91bmQuPC9zdHJvbmc+IFN1Y2ggdHlwZXMgYXJlCisgKiAgICAgd3JpdHRlbiBsaWtlIHtAY29kZSA/IGV4dGVuZHMgamF2YS5sYW5nLk51bWJlcn0uIFdoZW4gdGhlIHVwcGVyIGJvdW5kIGlzCisgKiAgICAge0Bjb2RlIGphdmEubGFuZy5PYmplY3R9LCB0aGUge0Bjb2RlIGV4dGVuZHMgamF2YS5sYW5nLk9iamVjdH0gc3VmZml4IGlzCisgKiAgICAgb3B0aW9uYWw6IHtAY29kZSBTZXQ8Pz59IGlzIHNob3J0aGFuZCBmb3Ige0Bjb2RlCisgKiAgICAgU2V0PD8gZXh0ZW5kcyBqYXZhLmxhbmcuT2JqZWN0Pn0uCisgKiA8bGk+PHN0cm9uZz5PbmUgbG93ZXIgYm91bmQgYW5kIGFuIHVwcGVyIGJvdW5kIG9mIHtAY29kZQorICogICAgIGphdmEubGFuZy5PYmplY3R9Ljwvc3Ryb25nPiBTdWNoIHR5cGVzIGFyZSB3cml0dGVuIGxpa2Uge0Bjb2RlCisgKiAgICAgPyBzdXBlciBqYXZhLmxhbmcuU3RyaW5nfS4KKyAqIDwvb2w+CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgV2lsZGNhcmRUeXBlIGV4dGVuZHMgVHlwZSB7CisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXJyYXkgb2YgdHlwZXMgdGhhdCByZXByZXNlbnQgdGhlIHVwcGVyIGJvdW5kcyBvZiB0aGlzIHR5cGUuCisgICAgICogVGhlIGRlZmF1bHQgdXBwZXIgYm91bmQgaXMge0Bjb2RlIE9iamVjdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIHVwcGVyIGJvdW5kcyB0eXBlcworICAgICAqCisgICAgICogQHRocm93cyBUeXBlTm90UHJlc2VudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBvZiB0aGUgYm91bmRzIHBvaW50cyB0byBhIG1pc3NpbmcgdHlwZQorICAgICAqIEB0aHJvd3MgTWFsZm9ybWVkUGFyYW1ldGVyaXplZFR5cGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgYm91bmQgcG9pbnRzIHRvIGEgdHlwZSB0aGF0IGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQgZm9yCisgICAgICogICAgICAgICAgICAgc29tZSByZWFzb24KKyAgICAgKi8KKyAgICBUeXBlW10gZ2V0VXBwZXJCb3VuZHMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFycmF5IG9mIHR5cGVzIHRoYXQgcmVwcmVzZW50IHRoZSBsb3dlciBib3VuZHMgb2YgdGhpcyB0eXBlLgorICAgICAqIFRoZSBkZWZhdWx0IGxvd2VyIGJvdW5kIGlzIHtAY29kZSBudWxsfSwgaW4gd2hpY2ggY2FzZSBhbiBlbXB0eSBhcnJheSBpcworICAgICAqIHJldHVybmVkLiBTaW5jZSBvbmx5IG9uZSBsb3dlciBib3VuZCBpcyBhbGxvd2VkLCB0aGUgcmV0dXJuZWQgYXJyYXkncworICAgICAqIGxlbmd0aCB3aWxsIG5ldmVyIGV4Y2VlZCBvbmUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIGxvd2VyIGJvdW5kcyB0eXBlcworICAgICAqCisgICAgICogQHRocm93cyBUeXBlTm90UHJlc2VudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBvZiB0aGUgYm91bmRzIHBvaW50cyB0byBhIG1pc3NpbmcgdHlwZQorICAgICAqIEB0aHJvd3MgTWFsZm9ybWVkUGFyYW1ldGVyaXplZFR5cGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgb2YgdGhlIGJvdW5kcyBwb2ludHMgdG8gYSB0eXBlIHRoYXQgY2Fubm90IGJlCisgICAgICogICAgICAgICAgICAgaW5zdGFudGlhdGVkIGZvciBzb21lIHJlYXNvbgorICAgICAqLworICAgIFR5cGVbXSBnZXRMb3dlckJvdW5kcygpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbWF0aC9CaWdEZWNpbWFsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9tYXRoL0JpZ0RlY2ltYWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYTVmM2NkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbWF0aC9CaWdEZWNpbWFsLmphdmEKQEAgLTAsMCArMSwyOTk5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubWF0aDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGxpYmNvcmUubWF0aC5NYXRoVXRpbHM7CisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGltbXV0YWJsZSBpbnRlZ2VyIG51bWJlcnMgb2YgYXJiaXRyYXJ5IGxlbmd0aC4gTGFyZ2UKKyAqIG51bWJlcnMgYXJlIHR5cGljYWxseSB1c2VkIGluIHNlY3VyaXR5IGFwcGxpY2F0aW9ucyBhbmQgdGhlcmVmb3JlIEJpZ0ludGVnZXJzCisgKiBvZmZlciBkZWRpY2F0ZWQgZnVuY3Rpb25hbGl0eSBsaWtlIHRoZSBnZW5lcmF0aW9uIG9mIGxhcmdlIHByaW1lIG51bWJlcnMgb3IKKyAqIHRoZSBjb21wdXRhdGlvbiBvZiBtb2R1bGFyIGludmVyc2UuCisgKiA8cD4KKyAqIFNpbmNlIHRoZSBjbGFzcyB3YXMgbW9kZWxlZCB0byBvZmZlciBhbGwgdGhlIGZ1bmN0aW9uYWxpdHkgYXMgdGhlIHtAbGluayBJbnRlZ2VyfQorICogY2xhc3MgZG9lcywgaXQgcHJvdmlkZXMgZXZlbiBtZXRob2RzIHRoYXQgb3BlcmF0ZSBiaXR3aXNlIG9uIGEgdHdvJ3MKKyAqIGNvbXBsZW1lbnQgcmVwcmVzZW50YXRpb24gb2YgbGFyZ2UgaW50ZWdlcnMuIE5vdGUgaG93ZXZlciB0aGF0IHRoZQorICogaW1wbGVtZW50YXRpb25zIGZhdm9ycyBhbiBpbnRlcm5hbCByZXByZXNlbnRhdGlvbiB3aGVyZSBtYWduaXR1ZGUgYW5kIHNpZ24KKyAqIGFyZSB0cmVhdGVkIHNlcGFyYXRlbHkuIEhlbmNlIHN1Y2ggb3BlcmF0aW9ucyBhcmUgaW5lZmZpY2llbnQgYW5kIHNob3VsZCBiZQorICogZGlzY291cmFnZWQuIEluIHNpbXBsZSB3b3JkczogRG8gTk9UIGltcGxlbWVudCBhbnkgYml0IGZpZWxkcyBiYXNlZCBvbgorICogQmlnSW50ZWdlci4KKyAqLworcHVibGljIGNsYXNzIEJpZ0RlY2ltYWwgZXh0ZW5kcyBOdW1iZXIgaW1wbGVtZW50cyBDb21wYXJhYmxlPEJpZ0RlY2ltYWw+LCBTZXJpYWxpemFibGUgeworCisgICAgLyoqCisgICAgICogUm91bmRpbmcgbW9kZSB3aGVyZSBwb3NpdGl2ZSB2YWx1ZXMgYXJlIHJvdW5kZWQgdG93YXJkcyBwb3NpdGl2ZSBpbmZpbml0eQorICAgICAqIGFuZCBuZWdhdGl2ZSB2YWx1ZXMgdG93YXJkcyBuZWdhdGl2ZSBpbmZpbml0eS4KKyAgICAgKgorICAgICAqIEBzZWUgUm91bmRpbmdNb2RlI1VQCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUk9VTkRfVVAgPSAwOworCisgICAgLyoqCisgICAgICogUm91bmRpbmcgbW9kZSB3aGVyZSB0aGUgdmFsdWVzIGFyZSByb3VuZGVkIHRvd2FyZHMgemVyby4KKyAgICAgKgorICAgICAqIEBzZWUgUm91bmRpbmdNb2RlI0RPV04KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST1VORF9ET1dOID0gMTsKKworICAgIC8qKgorICAgICAqIFJvdW5kaW5nIG1vZGUgdG8gcm91bmQgdG93YXJkcyBwb3NpdGl2ZSBpbmZpbml0eS4gRm9yIHBvc2l0aXZlIHZhbHVlcworICAgICAqIHRoaXMgcm91bmRpbmcgbW9kZSBiZWhhdmVzIGFzIHtAbGluayAjUk9VTkRfVVB9LCBmb3IgbmVnYXRpdmUgdmFsdWVzIGFzCisgICAgICoge0BsaW5rICNST1VORF9ET1dOfS4KKyAgICAgKgorICAgICAqIEBzZWUgUm91bmRpbmdNb2RlI0NFSUxJTkcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST1VORF9DRUlMSU5HID0gMjsKKworICAgIC8qKgorICAgICAqIFJvdW5kaW5nIG1vZGUgdG8gcm91bmQgdG93YXJkcyBuZWdhdGl2ZSBpbmZpbml0eS4gRm9yIHBvc2l0aXZlIHZhbHVlcworICAgICAqIHRoaXMgcm91bmRpbmcgbW9kZSBiZWhhdmVzIGFzIHtAbGluayAjUk9VTkRfRE9XTn0sIGZvciBuZWdhdGl2ZSB2YWx1ZXMgYXMKKyAgICAgKiB7QGxpbmsgI1JPVU5EX1VQfS4KKyAgICAgKgorICAgICAqIEBzZWUgUm91bmRpbmdNb2RlI0ZMT09SCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUk9VTkRfRkxPT1IgPSAzOworCisgICAgLyoqCisgICAgICogUm91bmRpbmcgbW9kZSB3aGVyZSB2YWx1ZXMgYXJlIHJvdW5kZWQgdG93YXJkcyB0aGUgbmVhcmVzdCBuZWlnaGJvci4KKyAgICAgKiBUaWVzIGFyZSBicm9rZW4gYnkgcm91bmRpbmcgdXAuCisgICAgICoKKyAgICAgKiBAc2VlIFJvdW5kaW5nTW9kZSNIQUxGX1VQCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUk9VTkRfSEFMRl9VUCA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBSb3VuZGluZyBtb2RlIHdoZXJlIHZhbHVlcyBhcmUgcm91bmRlZCB0b3dhcmRzIHRoZSBuZWFyZXN0IG5laWdoYm9yLgorICAgICAqIFRpZXMgYXJlIGJyb2tlbiBieSByb3VuZGluZyBkb3duLgorICAgICAqCisgICAgICogQHNlZSBSb3VuZGluZ01vZGUjSEFMRl9ET1dOCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUk9VTkRfSEFMRl9ET1dOID0gNTsKKworICAgIC8qKgorICAgICAqIFJvdW5kaW5nIG1vZGUgd2hlcmUgdmFsdWVzIGFyZSByb3VuZGVkIHRvd2FyZHMgdGhlIG5lYXJlc3QgbmVpZ2hib3IuCisgICAgICogVGllcyBhcmUgYnJva2VuIGJ5IHJvdW5kaW5nIHRvIHRoZSBldmVuIG5laWdoYm9yLgorICAgICAqCisgICAgICogQHNlZSBSb3VuZGluZ01vZGUjSEFMRl9FVkVOCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUk9VTkRfSEFMRl9FVkVOID0gNjsKKworICAgIC8qKgorICAgICAqIFJvdW5kaW5nIG1vZGUgd2hlcmUgdGhlIHJvdW5kaW5nIG9wZXJhdGlvbnMgdGhyb3dzIGFuIHtAY29kZQorICAgICAqIEFyaXRobWV0aWNFeGNlcHRpb259IGZvciB0aGUgY2FzZSB0aGF0IHJvdW5kaW5nIGlzIG5lY2Vzc2FyeSwgaS5lLiBmb3IKKyAgICAgKiB0aGUgY2FzZSB0aGF0IHRoZSB2YWx1ZSBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgZXhhY3RseS4KKyAgICAgKgorICAgICAqIEBzZWUgUm91bmRpbmdNb2RlI1VOTkVDRVNTQVJZCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUk9VTkRfVU5ORUNFU1NBUlkgPSA3OworCisgICAgLyoqIFRoaXMgaXMgdGhlIHNlcmlhbFZlcnNpb25VSUQgdXNlZCBieSB0aGUgc3VuIGltcGxlbWVudGF0aW9uLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDYxMDg4NzQ4ODcxNDM2OTY0NjNMOworCisgICAgLyoqIFRoZSBkb3VibGUgY2xvc2VzdCB0byB7QGNvZGUgTG9nMTAoMil9LiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGRvdWJsZSBMT0cxMF8yID0gMC4zMDEwMjk5OTU2NjM5ODEyOworCisgICAgLyoqIFRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uIGlzIGNhY2hlZC4gKi8KKyAgICBwcml2YXRlIHRyYW5zaWVudCBTdHJpbmcgdG9TdHJpbmdJbWFnZSA9IG51bGw7CisKKyAgICAvKiogQ2FjaGUgZm9yIHRoZSBoYXNoIGNvZGUuICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IGhhc2hDb2RlID0gMDsKKworICAgIC8qKgorICAgICAqIEFuIGFycmF5IHdpdGggcG93ZXJzIG9mIGZpdmUgdGhhdCBmaXQgaW4gdGhlIHR5cGUgPGNvZGU+bG9uZzwvY29kZT4KKyAgICAgKiAoPGNvZGU+NV4wLDVeMSwuLi4sNV4yNzwvY29kZT4pLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEJpZ0ludGVnZXJbXSBGSVZFX1BPVzsKKworICAgIC8qKgorICAgICAqIEFuIGFycmF5IHdpdGggcG93ZXJzIG9mIHRlbiB0aGF0IGZpdCBpbiB0aGUgdHlwZSA8Y29kZT5sb25nPC9jb2RlPgorICAgICAqICg8Y29kZT4xMF4wLDEwXjEsLi4uLDEwXjE4PC9jb2RlPikuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQmlnSW50ZWdlcltdIFRFTl9QT1c7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nW10gTE9OR19GSVZFX1BPVyA9IG5ldyBsb25nW10KKyAgICB7ICAgMUwsCisgICAgICAgIDVMLAorICAgICAgICAyNUwsCisgICAgICAgIDEyNUwsCisgICAgICAgIDYyNUwsCisgICAgICAgIDMxMjVMLAorICAgICAgICAxNTYyNUwsCisgICAgICAgIDc4MTI1TCwKKyAgICAgICAgMzkwNjI1TCwKKyAgICAgICAgMTk1MzEyNUwsCisgICAgICAgIDk3NjU2MjVMLAorICAgICAgICA0ODgyODEyNUwsCisgICAgICAgIDI0NDE0MDYyNUwsCisgICAgICAgIDEyMjA3MDMxMjVMLAorICAgICAgICA2MTAzNTE1NjI1TCwKKyAgICAgICAgMzA1MTc1NzgxMjVMLAorICAgICAgICAxNTI1ODc4OTA2MjVMLAorICAgICAgICA3NjI5Mzk0NTMxMjVMLAorICAgICAgICAzODE0Njk3MjY1NjI1TCwKKyAgICAgICAgMTkwNzM0ODYzMjgxMjVMLAorICAgICAgICA5NTM2NzQzMTY0MDYyNUwsCisgICAgICAgIDQ3NjgzNzE1ODIwMzEyNUwsCisgICAgICAgIDIzODQxODU3OTEwMTU2MjVMLAorICAgICAgICAxMTkyMDkyODk1NTA3ODEyNUwsCisgICAgICAgIDU5NjA0NjQ0Nzc1MzkwNjI1TCwKKyAgICAgICAgMjk4MDIzMjIzODc2OTUzMTI1TCwKKyAgICAgICAgMTQ5MDExNjExOTM4NDc2NTYyNUwsCisgICAgICAgIDc0NTA1ODA1OTY5MjM4MjgxMjVMLCB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gTE9OR19GSVZFX1BPV19CSVRfTEVOR1RIID0gbmV3IGludFtMT05HX0ZJVkVfUE9XLmxlbmd0aF07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gTE9OR19QT1dFUlNfT0ZfVEVOX0JJVF9MRU5HVEggPSBuZXcgaW50W01hdGhVdGlscy5MT05HX1BPV0VSU19PRl9URU4ubGVuZ3RoXTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCSV9TQ0FMRURfQllfWkVST19MRU5HVEggPSAxMTsKKworICAgIC8qKgorICAgICAqIEFuIGFycmF5IHdpdGggdGhlIGZpcnN0IDxjb2RlPkJpZ0ludGVnZXI8L2NvZGU+IHNjYWxlZCBieSB6ZXJvLgorICAgICAqICg8Y29kZT5bMCwwXSxbMSwwXSwuLi4sWzEwLDBdPC9jb2RlPikuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQmlnRGVjaW1hbFtdIEJJX1NDQUxFRF9CWV9aRVJPID0gbmV3IEJpZ0RlY2ltYWxbQklfU0NBTEVEX0JZX1pFUk9fTEVOR1RIXTsKKworICAgIC8qKgorICAgICAqIEFuIGFycmF5IHdpdGggdGhlIHplcm8gbnVtYmVyIHNjYWxlZCBieSB0aGUgZmlyc3QgcG9zaXRpdmUgc2NhbGVzLgorICAgICAqICg8Y29kZT4wKjEwXjAsIDAqMTBeMSwgLi4uLCAwKjEwXjEwPC9jb2RlPikuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQmlnRGVjaW1hbFtdIFpFUk9fU0NBTEVEX0JZID0gbmV3IEJpZ0RlY2ltYWxbMTFdOworCisgICAgLyoqIEFuIGFycmF5IGZpbGxlZCB3aXRoIGNoYXJhY3RlcnMgPGNvZGU+JzAnPC9jb2RlPi4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gQ0hfWkVST1MgPSBuZXcgY2hhclsxMDBdOworCisgICAgc3RhdGljIHsKKyAgICAgICAgQXJyYXlzLmZpbGwoQ0hfWkVST1MsICcwJyk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBaRVJPX1NDQUxFRF9CWS5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgQklfU0NBTEVEX0JZX1pFUk9baV0gPSBuZXcgQmlnRGVjaW1hbChpLCAwKTsKKyAgICAgICAgICAgIFpFUk9fU0NBTEVEX0JZW2ldID0gbmV3IEJpZ0RlY2ltYWwoMCwgaSk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBMT05HX0ZJVkVfUE9XX0JJVF9MRU5HVEgubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIExPTkdfRklWRV9QT1dfQklUX0xFTkdUSFtpXSA9IGJpdExlbmd0aChMT05HX0ZJVkVfUE9XW2ldKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IExPTkdfUE9XRVJTX09GX1RFTl9CSVRfTEVOR1RILmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICBMT05HX1BPV0VSU19PRl9URU5fQklUX0xFTkdUSFtpXSA9IGJpdExlbmd0aChNYXRoVXRpbHMuTE9OR19QT1dFUlNfT0ZfVEVOW2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRha2luZyB0aGUgcmVmZXJlbmNlcyBvZiB1c2VmdWwgcG93ZXJzLgorICAgICAgICBURU5fUE9XID0gTXVsdGlwbGljYXRpb24uYmlnVGVuUG93czsKKyAgICAgICAgRklWRV9QT1cgPSBNdWx0aXBsaWNhdGlvbi5iaWdGaXZlUG93czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29uc3RhbnQgemVybyBhcyBhIHtAY29kZSBCaWdEZWNpbWFsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEJpZ0RlY2ltYWwgWkVSTyA9IG5ldyBCaWdEZWNpbWFsKDAsIDApOworCisgICAgLyoqCisgICAgICogVGhlIGNvbnN0YW50IG9uZSBhcyBhIHtAY29kZSBCaWdEZWNpbWFsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEJpZ0RlY2ltYWwgT05FID0gbmV3IEJpZ0RlY2ltYWwoMSwgMCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29uc3RhbnQgdGVuIGFzIGEge0Bjb2RlIEJpZ0RlY2ltYWx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQmlnRGVjaW1hbCBURU4gPSBuZXcgQmlnRGVjaW1hbCgxMCwgMCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYXJiaXRyYXJ5IHByZWNpc2lvbiBpbnRlZ2VyICh1bnNjYWxlZCB2YWx1ZSkgaW4gdGhlIGludGVybmFsCisgICAgICogcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIEJpZ0RlY2ltYWx9LgorICAgICAqLworICAgIHByaXZhdGUgQmlnSW50ZWdlciBpbnRWYWw7CisKKyAgICBwcml2YXRlIHRyYW5zaWVudCBpbnQgYml0TGVuZ3RoOworCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgbG9uZyBzbWFsbFZhbHVlOworCisgICAgLyoqCisgICAgICogVGhlIDMyLWJpdCBpbnRlZ2VyIHNjYWxlIGluIHRoZSBpbnRlcm5hbCByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUgQmlnRGVjaW1hbH0uCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgc2NhbGU7CisKKyAgICAvKioKKyAgICAgKiBSZXByZXNlbnQgdGhlIG51bWJlciBvZiBkZWNpbWFsIGRpZ2l0cyBpbiB0aGUgdW5zY2FsZWQgdmFsdWUuIFRoaXMKKyAgICAgKiBwcmVjaXNpb24gaXMgY2FsY3VsYXRlZCB0aGUgZmlyc3QgdGltZSwgYW5kIHVzZWQgaW4gdGhlIGZvbGxvd2luZyBjYWxscworICAgICAqIG9mIG1ldGhvZCA8Y29kZT5wcmVjaXNpb24oKTwvY29kZT4uIE5vdGUgdGhhdCBzb21lIGNhbGwgdG8gdGhlIHByaXZhdGUKKyAgICAgKiBtZXRob2QgPGNvZGU+aW5wbGFjZVJvdW5kKCk8L2NvZGU+IGNvdWxkIHVwZGF0ZSB0aGlzIGZpZWxkLgorICAgICAqCisgICAgICogQHNlZSAjcHJlY2lzaW9uKCkKKyAgICAgKiBAc2VlICNpbnBsYWNlUm91bmQoTWF0aENvbnRleHQpCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IHByZWNpc2lvbiA9IDA7CisKKyAgICBwcml2YXRlIEJpZ0RlY2ltYWwobG9uZyBzbWFsbFZhbHVlLCBpbnQgc2NhbGUpeworICAgICAgICB0aGlzLnNtYWxsVmFsdWUgPSBzbWFsbFZhbHVlOworICAgICAgICB0aGlzLnNjYWxlID0gc2NhbGU7CisgICAgICAgIHRoaXMuYml0TGVuZ3RoID0gYml0TGVuZ3RoKHNtYWxsVmFsdWUpOworICAgIH0KKworICAgIHByaXZhdGUgQmlnRGVjaW1hbChpbnQgc21hbGxWYWx1ZSwgaW50IHNjYWxlKXsKKyAgICAgICAgdGhpcy5zbWFsbFZhbHVlID0gc21hbGxWYWx1ZTsKKyAgICAgICAgdGhpcy5zY2FsZSA9IHNjYWxlOworICAgICAgICB0aGlzLmJpdExlbmd0aCA9IGJpdExlbmd0aChzbWFsbFZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBCaWdEZWNpbWFsfSBpbnN0YW5jZSBmcm9tIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uCisgICAgICogZ2l2ZW4gYXMgYSBjaGFyYWN0ZXIgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiAgICAgICAgICAgIGFycmF5IG9mIGNoYXJhY3RlcnMgY29udGFpbmluZyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mCisgICAgICogICAgICAgICAgICB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICBmaXJzdCBpbmRleCB0byBiZSBjb3BpZWQuCisgICAgICogQHBhcmFtIGxlbgorICAgICAqICAgICAgICAgICAgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gYmUgdXNlZC4KKyAgICAgKiBAdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwIHx8IGxlbiA8PSAwIHx8IG9mZnNldCtsZW4tMSA8IDAgfHwKKyAgICAgKiAgICAgICAgICAgICBvZmZzZXQrbGVuLTEgPj0gaW4ubGVuZ3RofSwgb3IgaWYge0Bjb2RlIGlufSBkb2VzIG5vdAorICAgICAqICAgICAgICAgICAgIGNvbnRhaW4gYSB2YWxpZCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBiaWcgZGVjaW1hbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbChjaGFyW10gaW4sIGludCBvZmZzZXQsIGludCBsZW4pIHsKKyAgICAgICAgaW50IGJlZ2luID0gb2Zmc2V0OyAvLyBmaXJzdCBpbmRleCB0byBiZSBjb3BpZWQKKyAgICAgICAgaW50IGxhc3QgPSBvZmZzZXQgKyAobGVuIC0gMSk7IC8vIGxhc3QgaW5kZXggdG8gYmUgY29waWVkCisgICAgICAgIFN0cmluZyBzY2FsZVN0cmluZzsgLy8gYnVmZmVyIGZvciBzY2FsZQorICAgICAgICBTdHJpbmdCdWlsZGVyIHVuc2NhbGVkQnVmZmVyOyAvLyBidWZmZXIgZm9yIHVuc2NhbGVkIHZhbHVlCisgICAgICAgIGxvbmcgbmV3U2NhbGU7IC8vIHRoZSBuZXcgc2NhbGUKKworICAgICAgICBpZiAoaW4gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChsYXN0ID49IGluLmxlbmd0aCkgfHwgKG9mZnNldCA8IDApIHx8IChsZW4gPD0gMCkgfHwgKGxhc3QgPCAwKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigiQmFkIG9mZnNldC9sZW5ndGg6IG9mZnNldD0iICsgb2Zmc2V0ICsKKyAgICAgICAgICAgICAgICAgICAgIiBsZW49IiArIGxlbiArICIgaW4ubGVuZ3RoPSIgKyBpbi5sZW5ndGgpOworICAgICAgICB9CisgICAgICAgIHVuc2NhbGVkQnVmZmVyID0gbmV3IFN0cmluZ0J1aWxkZXIobGVuKTsKKyAgICAgICAgaW50IGJ1Zkxlbmd0aCA9IDA7CisgICAgICAgIC8vIFRvIHNraXAgYSBwb3NzaWJsZSAnKycgc3ltYm9sCisgICAgICAgIGlmICgob2Zmc2V0IDw9IGxhc3QpICYmIChpbltvZmZzZXRdID09ICcrJykpIHsKKyAgICAgICAgICAgIG9mZnNldCsrOworICAgICAgICAgICAgYmVnaW4rKzsKKyAgICAgICAgfQorICAgICAgICBpbnQgY291bnRlciA9IDA7CisgICAgICAgIGJvb2xlYW4gd2FzTm9uWmVybyA9IGZhbHNlOworICAgICAgICAvLyBBY2N1bXVsYXRpbmcgYWxsIGRpZ2l0cyB1bnRpbCBhIHBvc3NpYmxlIGRlY2ltYWwgcG9pbnQKKyAgICAgICAgZm9yICg7IChvZmZzZXQgPD0gbGFzdCkgJiYgKGluW29mZnNldF0gIT0gJy4nKSAmJiAoaW5bb2Zmc2V0XSAhPSAnZScpICYmIChpbltvZmZzZXRdICE9ICdFJyk7IG9mZnNldCsrKSB7CisgICAgICAgICAgICBpZiAoIXdhc05vblplcm8pIHsKKyAgICAgICAgICAgICAgICBpZiAoaW5bb2Zmc2V0XSA9PSAnMCcpIHsKKyAgICAgICAgICAgICAgICAgICAgY291bnRlcisrOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHdhc05vblplcm8gPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisgICAgICAgIHVuc2NhbGVkQnVmZmVyLmFwcGVuZChpbiwgYmVnaW4sIG9mZnNldCAtIGJlZ2luKTsKKyAgICAgICAgYnVmTGVuZ3RoICs9IG9mZnNldCAtIGJlZ2luOworICAgICAgICAvLyBBIGRlY2ltYWwgcG9pbnQgd2FzIGZvdW5kCisgICAgICAgIGlmICgob2Zmc2V0IDw9IGxhc3QpICYmIChpbltvZmZzZXRdID09ICcuJykpIHsKKyAgICAgICAgICAgIG9mZnNldCsrOworICAgICAgICAgICAgLy8gQWNjdW11bGF0aW5nIGFsbCBkaWdpdHMgdW50aWwgYSBwb3NzaWJsZSBleHBvbmVudAorICAgICAgICAgICAgYmVnaW4gPSBvZmZzZXQ7CisgICAgICAgICAgICBmb3IgKDsgKG9mZnNldCA8PSBsYXN0KSAmJiAoaW5bb2Zmc2V0XSAhPSAnZScpCisgICAgICAgICAgICAmJiAoaW5bb2Zmc2V0XSAhPSAnRScpOyBvZmZzZXQrKykgeworICAgICAgICAgICAgICAgIGlmICghd2FzTm9uWmVybykgeworICAgICAgICAgICAgICAgICAgICBpZiAoaW5bb2Zmc2V0XSA9PSAnMCcpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIrKzsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHdhc05vblplcm8gPSB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgc2NhbGUgPSBvZmZzZXQgLSBiZWdpbjsKKyAgICAgICAgICAgIGJ1Zkxlbmd0aCArPXNjYWxlOworICAgICAgICAgICAgdW5zY2FsZWRCdWZmZXIuYXBwZW5kKGluLCBiZWdpbiwgc2NhbGUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc2NhbGUgPSAwOworICAgICAgICB9CisgICAgICAgIC8vIEFuIGV4cG9uZW50IHdhcyBmb3VuZAorICAgICAgICBpZiAoKG9mZnNldCA8PSBsYXN0KSAmJiAoKGluW29mZnNldF0gPT0gJ2UnKSB8fCAoaW5bb2Zmc2V0XSA9PSAnRScpKSkgeworICAgICAgICAgICAgb2Zmc2V0Kys7CisgICAgICAgICAgICAvLyBDaGVja2luZyBmb3IgYSBwb3NzaWJsZSBzaWduIG9mIHNjYWxlCisgICAgICAgICAgICBiZWdpbiA9IG9mZnNldDsKKyAgICAgICAgICAgIGlmICgob2Zmc2V0IDw9IGxhc3QpICYmIChpbltvZmZzZXRdID09ICcrJykpIHsKKyAgICAgICAgICAgICAgICBvZmZzZXQrKzsKKyAgICAgICAgICAgICAgICBpZiAoKG9mZnNldCA8PSBsYXN0KSAmJiAoaW5bb2Zmc2V0XSAhPSAnLScpKSB7CisgICAgICAgICAgICAgICAgICAgIGJlZ2luKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gQWNjdW11bGF0aW5nIGFsbCByZW1haW5pbmcgZGlnaXRzCisgICAgICAgICAgICBzY2FsZVN0cmluZyA9IFN0cmluZy52YWx1ZU9mKGluLCBiZWdpbiwgbGFzdCArIDEgLSBiZWdpbik7CisgICAgICAgICAgICAvLyBDaGVja2luZyBpZiB0aGUgc2NhbGUgaXMgZGVmaW5lZAorICAgICAgICAgICAgbmV3U2NhbGUgPSAobG9uZylzY2FsZSAtIEludGVnZXIucGFyc2VJbnQoc2NhbGVTdHJpbmcpOworICAgICAgICAgICAgc2NhbGUgPSAoaW50KW5ld1NjYWxlOworICAgICAgICAgICAgaWYgKG5ld1NjYWxlICE9IHNjYWxlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigiU2NhbGUgb3V0IG9mIHJhbmdlIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gUGFyc2luZyB0aGUgdW5zY2FsZWQgdmFsdWUKKyAgICAgICAgaWYgKGJ1Zkxlbmd0aCA8IDE5KSB7CisgICAgICAgICAgICBzbWFsbFZhbHVlID0gTG9uZy5wYXJzZUxvbmcodW5zY2FsZWRCdWZmZXIudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBiaXRMZW5ndGggPSBiaXRMZW5ndGgoc21hbGxWYWx1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzZXRVbnNjYWxlZFZhbHVlKG5ldyBCaWdJbnRlZ2VyKHVuc2NhbGVkQnVmZmVyLnRvU3RyaW5nKCkpKTsKKyAgICAgICAgfQorICAgICAgICBwcmVjaXNpb24gPSB1bnNjYWxlZEJ1ZmZlci5sZW5ndGgoKSAtIGNvdW50ZXI7CisgICAgICAgIGlmICh1bnNjYWxlZEJ1ZmZlci5jaGFyQXQoMCkgPT0gJy0nKSB7CisgICAgICAgICAgICBwcmVjaXNpb24gLS07CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBCaWdEZWNpbWFsfSBpbnN0YW5jZSBmcm9tIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uCisgICAgICogZ2l2ZW4gYXMgYSBjaGFyYWN0ZXIgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiAgICAgICAgICAgIGFycmF5IG9mIGNoYXJhY3RlcnMgY29udGFpbmluZyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mCisgICAgICogICAgICAgICAgICB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICBmaXJzdCBpbmRleCB0byBiZSBjb3BpZWQuCisgICAgICogQHBhcmFtIGxlbgorICAgICAqICAgICAgICAgICAgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gYmUgdXNlZC4KKyAgICAgKiBAcGFyYW0gbWMKKyAgICAgKiAgICAgICAgICAgIHJvdW5kaW5nIG1vZGUgYW5kIHByZWNpc2lvbiBmb3IgdGhlIHJlc3VsdCBvZiB0aGlzIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwIHx8IGxlbiA8PSAwIHx8IG9mZnNldCtsZW4tMSA8IDAgfHwKKyAgICAgKiAgICAgICAgICAgICBvZmZzZXQrbGVuLTEgPj0gaW4ubGVuZ3RofSwgb3IgaWYge0Bjb2RlIGlufSBkb2VzIG5vdAorICAgICAqICAgICAgICAgICAgIGNvbnRhaW4gYSB2YWxpZCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBiaWcgZGVjaW1hbC4KKyAgICAgKiBAdGhyb3dzIEFyaXRobWV0aWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbWMucHJlY2lzaW9uID4gMH0gYW5kIHtAY29kZSBtYy5yb3VuZGluZ01vZGUgPT0KKyAgICAgKiAgICAgICAgICAgICBVTk5FQ0VTU0FSWX0gYW5kIHRoZSBuZXcgYmlnIGRlY2ltYWwgY2Fubm90IGJlIHJlcHJlc2VudGVkCisgICAgICogICAgICAgICAgICAgd2l0aGluIHRoZSBnaXZlbiBwcmVjaXNpb24gd2l0aG91dCByb3VuZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbChjaGFyW10gaW4sIGludCBvZmZzZXQsIGludCBsZW4sIE1hdGhDb250ZXh0IG1jKSB7CisgICAgICAgIHRoaXMoaW4sIG9mZnNldCwgbGVuKTsKKyAgICAgICAgaW5wbGFjZVJvdW5kKG1jKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBCaWdEZWNpbWFsfSBpbnN0YW5jZSBmcm9tIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uCisgICAgICogZ2l2ZW4gYXMgYSBjaGFyYWN0ZXIgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiAgICAgICAgICAgIGFycmF5IG9mIGNoYXJhY3RlcnMgY29udGFpbmluZyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mCisgICAgICogICAgICAgICAgICB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfS4KKyAgICAgKiBAdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBpbn0gZG9lcyBub3QgY29udGFpbiBhIHZhbGlkIHN0cmluZyByZXByZXNlbnRhdGlvbgorICAgICAqICAgICAgICAgICAgIG9mIGEgYmlnIGRlY2ltYWwuCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwoY2hhcltdIGluKSB7CisgICAgICAgIHRoaXMoaW4sIDAsIGluLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gaW5zdGFuY2UgZnJvbSBhIHN0cmluZyByZXByZXNlbnRhdGlvbgorICAgICAqIGdpdmVuIGFzIGEgY2hhcmFjdGVyIGFycmF5LiBUaGUgcmVzdWx0IGlzIHJvdW5kZWQgYWNjb3JkaW5nIHRvIHRoZQorICAgICAqIHNwZWNpZmllZCBtYXRoIGNvbnRleHQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiAgICAgICAgICAgIGFycmF5IG9mIGNoYXJhY3RlcnMgY29udGFpbmluZyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mCisgICAgICogICAgICAgICAgICB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfS4KKyAgICAgKiBAcGFyYW0gbWMKKyAgICAgKiAgICAgICAgICAgIHJvdW5kaW5nIG1vZGUgYW5kIHByZWNpc2lvbiBmb3IgdGhlIHJlc3VsdCBvZiB0aGlzIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBpbn0gZG9lcyBub3QgY29udGFpbiBhIHZhbGlkIHN0cmluZyByZXByZXNlbnRhdGlvbgorICAgICAqICAgICAgICAgICAgIG9mIGEgYmlnIGRlY2ltYWwuCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG1jLnByZWNpc2lvbiA+IDB9IGFuZCB7QGNvZGUgbWMucm91bmRpbmdNb2RlID09CisgICAgICogICAgICAgICAgICAgVU5ORUNFU1NBUll9IGFuZCB0aGUgbmV3IGJpZyBkZWNpbWFsIGNhbm5vdCBiZSByZXByZXNlbnRlZAorICAgICAqICAgICAgICAgICAgIHdpdGhpbiB0aGUgZ2l2ZW4gcHJlY2lzaW9uIHdpdGhvdXQgcm91bmRpbmcuCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwoY2hhcltdIGluLCBNYXRoQ29udGV4dCBtYykgeworICAgICAgICB0aGlzKGluLCAwLCBpbi5sZW5ndGgpOworICAgICAgICBpbnBsYWNlUm91bmQobWMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlIGZyb20gYSBzdHJpbmcKKyAgICAgKiByZXByZXNlbnRhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHN0cmluZyBjb250YWluaW5nIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIEJpZ0RlY2ltYWx9LgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHZhbH0gZG9lcyBub3QgY29udGFpbiBhIHZhbGlkIHN0cmluZyByZXByZXNlbnRhdGlvbgorICAgICAqICAgICAgICAgICAgIG9mIGEgYmlnIGRlY2ltYWwuCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwoU3RyaW5nIHZhbCkgeworICAgICAgICB0aGlzKHZhbC50b0NoYXJBcnJheSgpLCAwLCB2YWwubGVuZ3RoKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlIGZyb20gYSBzdHJpbmcKKyAgICAgKiByZXByZXNlbnRhdGlvbi4gVGhlIHJlc3VsdCBpcyByb3VuZGVkIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIG1hdGgKKyAgICAgKiBjb250ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZQorICAgICAqICAgICAgICAgICAgQmlnRGVjaW1hbH0uCisgICAgICogQHBhcmFtIG1jCisgICAgICogICAgICAgICAgICByb3VuZGluZyBtb2RlIGFuZCBwcmVjaXNpb24gZm9yIHRoZSByZXN1bHQgb2YgdGhpcyBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgdmFsfSBkb2VzIG5vdCBjb250YWluIGEgdmFsaWQgc3RyaW5nIHJlcHJlc2VudGF0aW9uCisgICAgICogICAgICAgICAgICAgb2YgYSBiaWcgZGVjaW1hbC4KKyAgICAgKiBAdGhyb3dzIEFyaXRobWV0aWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbWMucHJlY2lzaW9uID4gMH0gYW5kIHtAY29kZSBtYy5yb3VuZGluZ01vZGUgPT0KKyAgICAgKiAgICAgICAgICAgICBVTk5FQ0VTU0FSWX0gYW5kIHRoZSBuZXcgYmlnIGRlY2ltYWwgY2Fubm90IGJlIHJlcHJlc2VudGVkCisgICAgICogICAgICAgICAgICAgd2l0aGluIHRoZSBnaXZlbiBwcmVjaXNpb24gd2l0aG91dCByb3VuZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbChTdHJpbmcgdmFsLCBNYXRoQ29udGV4dCBtYykgeworICAgICAgICB0aGlzKHZhbC50b0NoYXJBcnJheSgpLCAwLCB2YWwubGVuZ3RoKCkpOworICAgICAgICBpbnBsYWNlUm91bmQobWMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlIGZyb20gdGhlIDY0Yml0IGRvdWJsZQorICAgICAqIHtAY29kZSB2YWx9LiBUaGUgY29uc3RydWN0ZWQgYmlnIGRlY2ltYWwgaXMgZXF1aXZhbGVudCB0byB0aGUgZ2l2ZW4KKyAgICAgKiBkb3VibGUuIEZvciBleGFtcGxlLCB7QGNvZGUgbmV3IEJpZ0RlY2ltYWwoMC4xKX0gaXMgZXF1YWwgdG8ge0Bjb2RlCisgICAgICogMC4xMDAwMDAwMDAwMDAwMDAwMDU1NTExMTUxMjMxMjU3ODI3MDIxMTgxNTgzNDA0NTQxMDE1NjI1fS4gVGhpcyBoYXBwZW5zCisgICAgICogYXMge0Bjb2RlIDAuMX0gY2Fubm90IGJlIHJlcHJlc2VudGVkIGV4YWN0bHkgaW4gYmluYXJ5LgorICAgICAqIDxwPgorICAgICAqIFRvIGdlbmVyYXRlIGEgYmlnIGRlY2ltYWwgaW5zdGFuY2Ugd2hpY2ggaXMgZXF1aXZhbGVudCB0byB7QGNvZGUgMC4xfSB1c2UKKyAgICAgKiB0aGUge0Bjb2RlIEJpZ0RlY2ltYWwoU3RyaW5nKX0gY29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsCisgICAgICogICAgICAgICAgICBkb3VibGUgdmFsdWUgdG8gYmUgY29udmVydGVkIHRvIGEge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlLgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHZhbH0gaXMgaW5maW5pdHkgb3Igbm90IGEgbnVtYmVyLgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsKGRvdWJsZSB2YWwpIHsKKyAgICAgICAgaWYgKERvdWJsZS5pc0luZmluaXRlKHZhbCkgfHwgRG91YmxlLmlzTmFOKHZhbCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oIkluZmluaXR5IG9yIE5hTjogIiArIHZhbCk7CisgICAgICAgIH0KKyAgICAgICAgbG9uZyBiaXRzID0gRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHModmFsKTsgLy8gSUVFRS03NTQKKyAgICAgICAgbG9uZyBtYW50aXNzYTsKKyAgICAgICAgaW50IHRyYWlsaW5nWmVyb3M7CisgICAgICAgIC8vIEV4dHJhY3RpbmcgdGhlIGV4cG9uZW50LCBub3RlIHRoYXQgdGhlIGJpYXMgaXMgMTAyMworICAgICAgICBzY2FsZSA9IDEwNzUgLSAoaW50KSgoYml0cyA+PiA1MikgJiAweDdGRkwpOworICAgICAgICAvLyBFeHRyYWN0aW5nIHRoZSA1MiBiaXRzIG9mIHRoZSBtYW50aXNzYS4KKyAgICAgICAgbWFudGlzc2EgPSAoc2NhbGUgPT0gMTA3NSkgPyAoYml0cyAmIDB4RkZGRkZGRkZGRkZGRkwpIDw8IDEKKyAgICAgICAgICAgICAgICA6IChiaXRzICYgMHhGRkZGRkZGRkZGRkZGTCkgfCAweDEwMDAwMDAwMDAwMDAwTDsKKyAgICAgICAgaWYgKG1hbnRpc3NhID09IDApIHsKKyAgICAgICAgICAgIHNjYWxlID0gMDsKKyAgICAgICAgICAgIHByZWNpc2lvbiA9IDE7CisgICAgICAgIH0KKyAgICAgICAgLy8gVG8gc2ltcGxpZnkgYWxsIGZhY3RvcnMgJzInIGluIHRoZSBtYW50aXNzYQorICAgICAgICBpZiAoc2NhbGUgPiAwKSB7CisgICAgICAgICAgICB0cmFpbGluZ1plcm9zID0gTWF0aC5taW4oc2NhbGUsIExvbmcubnVtYmVyT2ZUcmFpbGluZ1plcm9zKG1hbnRpc3NhKSk7CisgICAgICAgICAgICBtYW50aXNzYSA+Pj49IHRyYWlsaW5nWmVyb3M7CisgICAgICAgICAgICBzY2FsZSAtPSB0cmFpbGluZ1plcm9zOworICAgICAgICB9CisgICAgICAgIC8vIENhbGN1bGF0aW5nIHRoZSBuZXcgdW5zY2FsZWQgdmFsdWUgYW5kIHRoZSBuZXcgc2NhbGUKKyAgICAgICAgaWYoKGJpdHMgPj4gNjMpICE9IDApIHsKKyAgICAgICAgICAgIG1hbnRpc3NhID0gLW1hbnRpc3NhOworICAgICAgICB9CisgICAgICAgIGludCBtYW50aXNzYUJpdHMgPSBiaXRMZW5ndGgobWFudGlzc2EpOworICAgICAgICBpZiAoc2NhbGUgPCAwKSB7CisgICAgICAgICAgICBiaXRMZW5ndGggPSBtYW50aXNzYUJpdHMgPT0gMCA/IDAgOiBtYW50aXNzYUJpdHMgLSBzY2FsZTsKKyAgICAgICAgICAgIGlmKGJpdExlbmd0aCA8IDY0KSB7CisgICAgICAgICAgICAgICAgc21hbGxWYWx1ZSA9IG1hbnRpc3NhIDw8ICgtc2NhbGUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBCaWdJbnQgYmkgPSBuZXcgQmlnSW50KCk7CisgICAgICAgICAgICAgICAgYmkucHV0TG9uZ0ludChtYW50aXNzYSk7CisgICAgICAgICAgICAgICAgYmkuc2hpZnQoLXNjYWxlKTsKKyAgICAgICAgICAgICAgICBpbnRWYWwgPSBuZXcgQmlnSW50ZWdlcihiaSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzY2FsZSA9IDA7CisgICAgICAgIH0gZWxzZSBpZiAoc2NhbGUgPiAwKSB7CisgICAgICAgICAgICAvLyBtICogMl5lID0gIChtICogNV4oLWUpKSAqIDEwXmUKKyAgICAgICAgICAgIGlmKHNjYWxlIDwgTE9OR19GSVZFX1BPVy5sZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgJiYgbWFudGlzc2FCaXRzK0xPTkdfRklWRV9QT1dfQklUX0xFTkdUSFtzY2FsZV0gPCA2NCkgeworICAgICAgICAgICAgICAgIHNtYWxsVmFsdWUgPSBtYW50aXNzYSAqIExPTkdfRklWRV9QT1dbc2NhbGVdOworICAgICAgICAgICAgICAgIGJpdExlbmd0aCA9IGJpdExlbmd0aChzbWFsbFZhbHVlKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc2V0VW5zY2FsZWRWYWx1ZShNdWx0aXBsaWNhdGlvbi5tdWx0aXBseUJ5Rml2ZVBvdyhCaWdJbnRlZ2VyLnZhbHVlT2YobWFudGlzc2EpLCBzY2FsZSkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeyAvLyBzY2FsZSA9PSAwCisgICAgICAgICAgICBzbWFsbFZhbHVlID0gbWFudGlzc2E7CisgICAgICAgICAgICBiaXRMZW5ndGggPSBtYW50aXNzYUJpdHM7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBCaWdEZWNpbWFsfSBpbnN0YW5jZSBmcm9tIHRoZSA2NGJpdCBkb3VibGUKKyAgICAgKiB7QGNvZGUgdmFsfS4gVGhlIGNvbnN0cnVjdGVkIGJpZyBkZWNpbWFsIGlzIGVxdWl2YWxlbnQgdG8gdGhlIGdpdmVuCisgICAgICogZG91YmxlLiBGb3IgZXhhbXBsZSwge0Bjb2RlIG5ldyBCaWdEZWNpbWFsKDAuMSl9IGlzIGVxdWFsIHRvIHtAY29kZQorICAgICAqIDAuMTAwMDAwMDAwMDAwMDAwMDA1NTUxMTE1MTIzMTI1NzgyNzAyMTE4MTU4MzQwNDU0MTAxNTYyNX0uIFRoaXMgaGFwcGVucworICAgICAqIGFzIHtAY29kZSAwLjF9IGNhbm5vdCBiZSByZXByZXNlbnRlZCBleGFjdGx5IGluIGJpbmFyeS4KKyAgICAgKiA8cD4KKyAgICAgKiBUbyBnZW5lcmF0ZSBhIGJpZyBkZWNpbWFsIGluc3RhbmNlIHdoaWNoIGlzIGVxdWl2YWxlbnQgdG8ge0Bjb2RlIDAuMX0gdXNlCisgICAgICogdGhlIHtAY29kZSBCaWdEZWNpbWFsKFN0cmluZyl9IGNvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgZG91YmxlIHZhbHVlIHRvIGJlIGNvbnZlcnRlZCB0byBhIHtAY29kZSBCaWdEZWNpbWFsfSBpbnN0YW5jZS4KKyAgICAgKiBAcGFyYW0gbWMKKyAgICAgKiAgICAgICAgICAgIHJvdW5kaW5nIG1vZGUgYW5kIHByZWNpc2lvbiBmb3IgdGhlIHJlc3VsdCBvZiB0aGlzIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSB2YWx9IGlzIGluZmluaXR5IG9yIG5vdCBhIG51bWJlci4KKyAgICAgKiBAdGhyb3dzIEFyaXRobWV0aWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbWMucHJlY2lzaW9uID4gMH0gYW5kIHtAY29kZSBtYy5yb3VuZGluZ01vZGUgPT0KKyAgICAgKiAgICAgICAgICAgICBVTk5FQ0VTU0FSWX0gYW5kIHRoZSBuZXcgYmlnIGRlY2ltYWwgY2Fubm90IGJlIHJlcHJlc2VudGVkCisgICAgICogICAgICAgICAgICAgd2l0aGluIHRoZSBnaXZlbiBwcmVjaXNpb24gd2l0aG91dCByb3VuZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbChkb3VibGUgdmFsLCBNYXRoQ29udGV4dCBtYykgeworICAgICAgICB0aGlzKHZhbCk7CisgICAgICAgIGlucGxhY2VSb3VuZChtYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gaW5zdGFuY2UgZnJvbSB0aGUgZ2l2ZW4gYmlnIGludGVnZXIKKyAgICAgKiB7QGNvZGUgdmFsfS4gVGhlIHNjYWxlIG9mIHRoZSByZXN1bHQgaXMge0Bjb2RlIDB9LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAge0Bjb2RlIEJpZ0ludGVnZXJ9IHZhbHVlIHRvIGJlIGNvbnZlcnRlZCB0byBhIHtAY29kZQorICAgICAqICAgICAgICAgICAgQmlnRGVjaW1hbH0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwoQmlnSW50ZWdlciB2YWwpIHsKKyAgICAgICAgdGhpcyh2YWwsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlIGZyb20gdGhlIGdpdmVuIGJpZyBpbnRlZ2VyCisgICAgICoge0Bjb2RlIHZhbH0uIFRoZSBzY2FsZSBvZiB0aGUgcmVzdWx0IGlzIHtAY29kZSAwfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBCaWdJbnRlZ2VyfSB2YWx1ZSB0byBiZSBjb252ZXJ0ZWQgdG8gYSB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIEJpZ0RlY2ltYWx9IGluc3RhbmNlLgorICAgICAqIEBwYXJhbSBtYworICAgICAqICAgICAgICAgICAgcm91bmRpbmcgbW9kZSBhbmQgcHJlY2lzaW9uIGZvciB0aGUgcmVzdWx0IG9mIHRoaXMgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBtYy5wcmVjaXNpb24gPiAwfSBhbmQge0Bjb2RlIG1jLnJvdW5kaW5nTW9kZSA9PQorICAgICAqICAgICAgICAgICAgIFVOTkVDRVNTQVJZfSBhbmQgdGhlIG5ldyBiaWcgZGVjaW1hbCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQKKyAgICAgKiAgICAgICAgICAgICB3aXRoaW4gdGhlIGdpdmVuIHByZWNpc2lvbiB3aXRob3V0IHJvdW5kaW5nLgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsKEJpZ0ludGVnZXIgdmFsLCBNYXRoQ29udGV4dCBtYykgeworICAgICAgICB0aGlzKHZhbCk7CisgICAgICAgIGlucGxhY2VSb3VuZChtYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gaW5zdGFuY2UgZnJvbSBhIGdpdmVuIHVuc2NhbGVkIHZhbHVlCisgICAgICoge0Bjb2RlIHVuc2NhbGVkVmFsfSBhbmQgYSBnaXZlbiBzY2FsZS4gVGhlIHZhbHVlIG9mIHRoaXMgaW5zdGFuY2UgaXMKKyAgICAgKiB7QGNvZGUgdW5zY2FsZWRWYWx9IDEwXigte0Bjb2RlIHNjYWxlfSkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdW5zY2FsZWRWYWwKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBCaWdJbnRlZ2VyfSByZXByZXNlbnRpbmcgdGhlIHVuc2NhbGVkIHZhbHVlIG9mIHRoaXMKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBCaWdEZWNpbWFsfSBpbnN0YW5jZS4KKyAgICAgKiBAcGFyYW0gc2NhbGUKKyAgICAgKiAgICAgICAgICAgIHNjYWxlIG9mIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgdW5zY2FsZWRWYWwgPT0gbnVsbH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwoQmlnSW50ZWdlciB1bnNjYWxlZFZhbCwgaW50IHNjYWxlKSB7CisgICAgICAgIGlmICh1bnNjYWxlZFZhbCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnNjYWxlID0gc2NhbGU7CisgICAgICAgIHNldFVuc2NhbGVkVmFsdWUodW5zY2FsZWRWYWwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlIGZyb20gYSBnaXZlbiB1bnNjYWxlZCB2YWx1ZQorICAgICAqIHtAY29kZSB1bnNjYWxlZFZhbH0gYW5kIGEgZ2l2ZW4gc2NhbGUuIFRoZSB2YWx1ZSBvZiB0aGlzIGluc3RhbmNlIGlzCisgICAgICoge0Bjb2RlIHVuc2NhbGVkVmFsfSAxMF4oLXtAY29kZSBzY2FsZX0pLiBUaGUgcmVzdWx0IGlzIHJvdW5kZWQgYWNjb3JkaW5nCisgICAgICogdG8gdGhlIHNwZWNpZmllZCBtYXRoIGNvbnRleHQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdW5zY2FsZWRWYWwKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBCaWdJbnRlZ2VyfSByZXByZXNlbnRpbmcgdGhlIHVuc2NhbGVkIHZhbHVlIG9mIHRoaXMKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBCaWdEZWNpbWFsfSBpbnN0YW5jZS4KKyAgICAgKiBAcGFyYW0gc2NhbGUKKyAgICAgKiAgICAgICAgICAgIHNjYWxlIG9mIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlLgorICAgICAqIEBwYXJhbSBtYworICAgICAqICAgICAgICAgICAgcm91bmRpbmcgbW9kZSBhbmQgcHJlY2lzaW9uIGZvciB0aGUgcmVzdWx0IG9mIHRoaXMgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBtYy5wcmVjaXNpb24gPiAwfSBhbmQge0Bjb2RlIG1jLnJvdW5kaW5nTW9kZSA9PQorICAgICAqICAgICAgICAgICAgIFVOTkVDRVNTQVJZfSBhbmQgdGhlIG5ldyBiaWcgZGVjaW1hbCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQKKyAgICAgKiAgICAgICAgICAgICB3aXRoaW4gdGhlIGdpdmVuIHByZWNpc2lvbiB3aXRob3V0IHJvdW5kaW5nLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgdW5zY2FsZWRWYWwgPT0gbnVsbH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwoQmlnSW50ZWdlciB1bnNjYWxlZFZhbCwgaW50IHNjYWxlLCBNYXRoQ29udGV4dCBtYykgeworICAgICAgICB0aGlzKHVuc2NhbGVkVmFsLCBzY2FsZSk7CisgICAgICAgIGlucGxhY2VSb3VuZChtYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gaW5zdGFuY2UgZnJvbSB0aGUgZ2l2ZW4gaW50CisgICAgICoge0Bjb2RlIHZhbH0uIFRoZSBzY2FsZSBvZiB0aGUgcmVzdWx0IGlzIDAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsCisgICAgICogICAgICAgICAgICBpbnQgdmFsdWUgdG8gYmUgY29udmVydGVkIHRvIGEge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsKGludCB2YWwpIHsKKyAgICAgICAgdGhpcyh2YWwsMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gaW5zdGFuY2UgZnJvbSB0aGUgZ2l2ZW4gaW50IHtAY29kZQorICAgICAqIHZhbH0uIFRoZSBzY2FsZSBvZiB0aGUgcmVzdWx0IGlzIHtAY29kZSAwfS4gVGhlIHJlc3VsdCBpcyByb3VuZGVkCisgICAgICogYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgbWF0aCBjb250ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgaW50IHZhbHVlIHRvIGJlIGNvbnZlcnRlZCB0byBhIHtAY29kZSBCaWdEZWNpbWFsfSBpbnN0YW5jZS4KKyAgICAgKiBAcGFyYW0gbWMKKyAgICAgKiAgICAgICAgICAgIHJvdW5kaW5nIG1vZGUgYW5kIHByZWNpc2lvbiBmb3IgdGhlIHJlc3VsdCBvZiB0aGlzIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIEFyaXRobWV0aWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbWMucHJlY2lzaW9uID4gMH0gYW5kIHtAY29kZSBjLnJvdW5kaW5nTW9kZSA9PQorICAgICAqICAgICAgICAgICAgIFVOTkVDRVNTQVJZfSBhbmQgdGhlIG5ldyBiaWcgZGVjaW1hbCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQKKyAgICAgKiAgICAgICAgICAgICB3aXRoaW4gdGhlIGdpdmVuIHByZWNpc2lvbiB3aXRob3V0IHJvdW5kaW5nLgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsKGludCB2YWwsIE1hdGhDb250ZXh0IG1jKSB7CisgICAgICAgIHRoaXModmFsLDApOworICAgICAgICBpbnBsYWNlUm91bmQobWMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlIGZyb20gdGhlIGdpdmVuIGxvbmcge0Bjb2RlCisgICAgICogdmFsfS4gVGhlIHNjYWxlIG9mIHRoZSByZXN1bHQgaXMge0Bjb2RlIDB9LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgbG9uZyB2YWx1ZSB0byBiZSBjb252ZXJ0ZWQgdG8gYSB7QGNvZGUgQmlnRGVjaW1hbH0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwobG9uZyB2YWwpIHsKKyAgICAgICAgdGhpcyh2YWwsMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gaW5zdGFuY2UgZnJvbSB0aGUgZ2l2ZW4gbG9uZyB7QGNvZGUKKyAgICAgKiB2YWx9LiBUaGUgc2NhbGUgb2YgdGhlIHJlc3VsdCBpcyB7QGNvZGUgMH0uIFRoZSByZXN1bHQgaXMgcm91bmRlZAorICAgICAqIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIG1hdGggY29udGV4dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIGxvbmcgdmFsdWUgdG8gYmUgY29udmVydGVkIHRvIGEge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlLgorICAgICAqIEBwYXJhbSBtYworICAgICAqICAgICAgICAgICAgcm91bmRpbmcgbW9kZSBhbmQgcHJlY2lzaW9uIGZvciB0aGUgcmVzdWx0IG9mIHRoaXMgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBtYy5wcmVjaXNpb24gPiAwfSBhbmQge0Bjb2RlIG1jLnJvdW5kaW5nTW9kZSA9PQorICAgICAqICAgICAgICAgICAgIFVOTkVDRVNTQVJZfSBhbmQgdGhlIG5ldyBiaWcgZGVjaW1hbCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQKKyAgICAgKiAgICAgICAgICAgICB3aXRoaW4gdGhlIGdpdmVuIHByZWNpc2lvbiB3aXRob3V0IHJvdW5kaW5nLgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsKGxvbmcgdmFsLCBNYXRoQ29udGV4dCBtYykgeworICAgICAgICB0aGlzKHZhbCk7CisgICAgICAgIGlucGxhY2VSb3VuZChtYyk7CisgICAgfQorCisgICAgLyogUHVibGljIE1ldGhvZHMgKi8KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlIHdob3NlIHZhbHVlIGlzIGVxdWFsIHRvIHtAY29kZQorICAgICAqIHVuc2NhbGVkVmFsfSAxMF4oLXtAY29kZSBzY2FsZX0pLiBUaGUgc2NhbGUgb2YgdGhlIHJlc3VsdCBpcyB7QGNvZGUKKyAgICAgKiBzY2FsZX0sIGFuZCBpdHMgdW5zY2FsZWQgdmFsdWUgaXMge0Bjb2RlIHVuc2NhbGVkVmFsfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1bnNjYWxlZFZhbAorICAgICAqICAgICAgICAgICAgdW5zY2FsZWQgdmFsdWUgdG8gYmUgdXNlZCB0byBjb25zdHJ1Y3QgdGhlIG5ldyB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIEJpZ0RlY2ltYWx9LgorICAgICAqIEBwYXJhbSBzY2FsZQorICAgICAqICAgICAgICAgICAgc2NhbGUgdG8gYmUgdXNlZCB0byBjb25zdHJ1Y3QgdGhlIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0uCisgICAgICogQHJldHVybiB7QGNvZGUgQmlnRGVjaW1hbH0gaW5zdGFuY2Ugd2l0aCB0aGUgdmFsdWUge0Bjb2RlIHVuc2NhbGVkVmFsfSoKKyAgICAgKiAgICAgICAgIDEwXigte0Bjb2RlIHVuc2NhbGVkVmFsfSkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCaWdEZWNpbWFsIHZhbHVlT2YobG9uZyB1bnNjYWxlZFZhbCwgaW50IHNjYWxlKSB7CisgICAgICAgIGlmIChzY2FsZSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsdWVPZih1bnNjYWxlZFZhbCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCh1bnNjYWxlZFZhbCA9PSAwKSAmJiAoc2NhbGUgPj0gMCkKKyAgICAgICAgICAgICAgICAmJiAoc2NhbGUgPCBaRVJPX1NDQUxFRF9CWS5sZW5ndGgpKSB7CisgICAgICAgICAgICByZXR1cm4gWkVST19TQ0FMRURfQllbc2NhbGVdOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgQmlnRGVjaW1hbCh1bnNjYWxlZFZhbCwgc2NhbGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlIHdob3NlIHZhbHVlIGlzIGVxdWFsIHRvIHtAY29kZQorICAgICAqIHVuc2NhbGVkVmFsfS4gVGhlIHNjYWxlIG9mIHRoZSByZXN1bHQgaXMge0Bjb2RlIDB9LCBhbmQgaXRzIHVuc2NhbGVkCisgICAgICogdmFsdWUgaXMge0Bjb2RlIHVuc2NhbGVkVmFsfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1bnNjYWxlZFZhbAorICAgICAqICAgICAgICAgICAgdmFsdWUgdG8gYmUgY29udmVydGVkIHRvIGEge0Bjb2RlIEJpZ0RlY2ltYWx9LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlIHdpdGggdGhlIHZhbHVlIHtAY29kZSB1bnNjYWxlZFZhbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCaWdEZWNpbWFsIHZhbHVlT2YobG9uZyB1bnNjYWxlZFZhbCkgeworICAgICAgICBpZiAoKHVuc2NhbGVkVmFsID49IDApICYmICh1bnNjYWxlZFZhbCA8IEJJX1NDQUxFRF9CWV9aRVJPX0xFTkdUSCkpIHsKKyAgICAgICAgICAgIHJldHVybiBCSV9TQ0FMRURfQllfWkVST1soaW50KXVuc2NhbGVkVmFsXTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEJpZ0RlY2ltYWwodW5zY2FsZWRWYWwsMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gaW5zdGFuY2Ugd2hvc2UgdmFsdWUgaXMgZXF1YWwgdG8ge0Bjb2RlCisgICAgICogdmFsfS4gVGhlIG5ldyBkZWNpbWFsIGlzIGNvbnN0cnVjdGVkIGFzIGlmIHRoZSB7QGNvZGUgQmlnRGVjaW1hbChTdHJpbmcpfQorICAgICAqIGNvbnN0cnVjdG9yIGlzIGNhbGxlZCB3aXRoIGFuIGFyZ3VtZW50IHdoaWNoIGlzIGVxdWFsIHRvIHtAY29kZQorICAgICAqIERvdWJsZS50b1N0cmluZyh2YWwpfS4gRm9yIGV4YW1wbGUsIHtAY29kZSB2YWx1ZU9mKCIwLjEiKX0gaXMgY29udmVydGVkIHRvCisgICAgICogKHVuc2NhbGVkPTEsIHNjYWxlPTEpLCBhbHRob3VnaCB0aGUgZG91YmxlIHtAY29kZSAwLjF9IGNhbm5vdCBiZQorICAgICAqIHJlcHJlc2VudGVkIGV4YWN0bHkgYXMgYSBkb3VibGUgdmFsdWUuIEluIGNvbnRyYXN0IHRvIHRoYXQsIGEgbmV3IHtAY29kZQorICAgICAqIEJpZ0RlY2ltYWwoMC4xKX0gaW5zdGFuY2UgaGFzIHRoZSB2YWx1ZSB7QGNvZGUKKyAgICAgKiAwLjEwMDAwMDAwMDAwMDAwMDAwNTU1MTExNTEyMzEyNTc4MjcwMjExODE1ODM0MDQ1NDEwMTU2MjV9IHdpdGggYW4KKyAgICAgKiB1bnNjYWxlZCB2YWx1ZSB7QGNvZGUgMTAwMDAwMDAwMDAwMDAwMDA1NTUxMTE1MTIzMTI1NzgyNzAyMTE4MTU4MzQwNDU0MTAxNTYyNX0KKyAgICAgKiBhbmQgdGhlIHNjYWxlIHtAY29kZSA1NX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsCisgICAgICogICAgICAgICAgICBkb3VibGUgdmFsdWUgdG8gYmUgY29udmVydGVkIHRvIGEge0Bjb2RlIEJpZ0RlY2ltYWx9LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlIHdpdGggdGhlIHZhbHVlIHtAY29kZSB2YWx9LgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHZhbH0gaXMgaW5maW5pdGUgb3Ige0Bjb2RlIHZhbH0gaXMgbm90IGEgbnVtYmVyCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCaWdEZWNpbWFsIHZhbHVlT2YoZG91YmxlIHZhbCkgeworICAgICAgICBpZiAoRG91YmxlLmlzSW5maW5pdGUodmFsKSB8fCBEb3VibGUuaXNOYU4odmFsKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigiSW5maW5pdHkgb3IgTmFOOiAiICsgdmFsKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEJpZ0RlY2ltYWwoRG91YmxlLnRvU3RyaW5nKHZhbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IHdob3NlIHZhbHVlIGlzIHtAY29kZSB0aGlzICsgYXVnZW5kfS4KKyAgICAgKiBUaGUgc2NhbGUgb2YgdGhlIHJlc3VsdCBpcyB0aGUgbWF4aW11bSBvZiB0aGUgc2NhbGVzIG9mIHRoZSB0d28KKyAgICAgKiBhcmd1bWVudHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXVnZW5kCisgICAgICogICAgICAgICAgICB2YWx1ZSB0byBiZSBhZGRlZCB0byB7QGNvZGUgdGhpc30uCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpcyArIGF1Z2VuZH0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhdWdlbmQgPT0gbnVsbH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwgYWRkKEJpZ0RlY2ltYWwgYXVnZW5kKSB7CisgICAgICAgIGludCBkaWZmU2NhbGUgPSB0aGlzLnNjYWxlIC0gYXVnZW5kLnNjYWxlOworICAgICAgICAvLyBGYXN0IHJldHVybiB3aGVuIHNvbWUgb3BlcmFuZCBpcyB6ZXJvCisgICAgICAgIGlmICh0aGlzLmlzWmVybygpKSB7CisgICAgICAgICAgICBpZiAoZGlmZlNjYWxlIDw9IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYXVnZW5kOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGF1Z2VuZC5pc1plcm8oKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKGF1Z2VuZC5pc1plcm8oKSkgeworICAgICAgICAgICAgaWYgKGRpZmZTY2FsZSA+PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gTGV0IGJlOiAgdGhpcyA9IFt1MSxzMV0gIGFuZCAgYXVnZW5kID0gW3UyLHMyXQorICAgICAgICBpZiAoZGlmZlNjYWxlID09IDApIHsKKyAgICAgICAgICAgIC8vIGNhc2UgczEgPT0gczI6IFt1MSArIHUyICwgczFdCisgICAgICAgICAgICBpZiAoTWF0aC5tYXgodGhpcy5iaXRMZW5ndGgsIGF1Z2VuZC5iaXRMZW5ndGgpICsgMSA8IDY0KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlT2YodGhpcy5zbWFsbFZhbHVlICsgYXVnZW5kLnNtYWxsVmFsdWUsIHRoaXMuc2NhbGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBCaWdEZWNpbWFsKHRoaXMuZ2V0VW5zY2FsZWRWYWx1ZSgpLmFkZChhdWdlbmQuZ2V0VW5zY2FsZWRWYWx1ZSgpKSwgdGhpcy5zY2FsZSk7CisgICAgICAgIH0gZWxzZSBpZiAoZGlmZlNjYWxlID4gMCkgeworICAgICAgICAgICAgLy8gY2FzZSBzMSA+IHMyIDogWyh1MSArIHUyKSAqIDEwIF4gKHMxIC0gczIpICwgczFdCisgICAgICAgICAgICByZXR1cm4gYWRkQW5kTXVsdDEwKHRoaXMsIGF1Z2VuZCwgZGlmZlNjYWxlKTsKKyAgICAgICAgfSBlbHNlIHsvLyBjYXNlIHMyID4gczEgOiBbKHUyICsgdTEpICogMTAgXiAoczIgLSBzMSkgLCBzMl0KKyAgICAgICAgICAgIHJldHVybiBhZGRBbmRNdWx0MTAoYXVnZW5kLCB0aGlzLCAtZGlmZlNjYWxlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIEJpZ0RlY2ltYWwgYWRkQW5kTXVsdDEwKEJpZ0RlY2ltYWwgdGhpc1ZhbHVlLEJpZ0RlY2ltYWwgYXVnZW5kLCBpbnQgZGlmZlNjYWxlKSB7CisgICAgICAgIGlmKGRpZmZTY2FsZSA8IE1hdGhVdGlscy5MT05HX1BPV0VSU19PRl9URU4ubGVuZ3RoICYmCisgICAgICAgICAgICAgICAgTWF0aC5tYXgodGhpc1ZhbHVlLmJpdExlbmd0aCxhdWdlbmQuYml0TGVuZ3RoK0xPTkdfUE9XRVJTX09GX1RFTl9CSVRfTEVOR1RIW2RpZmZTY2FsZV0pKzE8NjQpIHsKKyAgICAgICAgICAgIHJldHVybiB2YWx1ZU9mKHRoaXNWYWx1ZS5zbWFsbFZhbHVlK2F1Z2VuZC5zbWFsbFZhbHVlKk1hdGhVdGlscy5MT05HX1BPV0VSU19PRl9URU5bZGlmZlNjYWxlXSx0aGlzVmFsdWUuc2NhbGUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgQmlnSW50IGJpID0gTXVsdGlwbGljYXRpb24ubXVsdGlwbHlCeVRlblBvdyhhdWdlbmQuZ2V0VW5zY2FsZWRWYWx1ZSgpLGRpZmZTY2FsZSkuZ2V0QmlnSW50KCk7CisgICAgICAgICAgICBiaS5hZGQodGhpc1ZhbHVlLmdldFVuc2NhbGVkVmFsdWUoKS5nZXRCaWdJbnQoKSk7CisgICAgICAgICAgICByZXR1cm4gbmV3IEJpZ0RlY2ltYWwobmV3IEJpZ0ludGVnZXIoYmkpLCB0aGlzVmFsdWUuc2NhbGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gd2hvc2UgdmFsdWUgaXMge0Bjb2RlIHRoaXMgKyBhdWdlbmR9LgorICAgICAqIFRoZSByZXN1bHQgaXMgcm91bmRlZCBhY2NvcmRpbmcgdG8gdGhlIHBhc3NlZCBjb250ZXh0IHtAY29kZSBtY30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXVnZW5kCisgICAgICogICAgICAgICAgICB2YWx1ZSB0byBiZSBhZGRlZCB0byB7QGNvZGUgdGhpc30uCisgICAgICogQHBhcmFtIG1jCisgICAgICogICAgICAgICAgICByb3VuZGluZyBtb2RlIGFuZCBwcmVjaXNpb24gZm9yIHRoZSByZXN1bHQgb2YgdGhpcyBvcGVyYXRpb24uCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpcyArIGF1Z2VuZH0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhdWdlbmQgPT0gbnVsbH0gb3Ige0Bjb2RlIG1jID09IG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsIGFkZChCaWdEZWNpbWFsIGF1Z2VuZCwgTWF0aENvbnRleHQgbWMpIHsKKyAgICAgICAgQmlnRGVjaW1hbCBsYXJnZXI7IC8vIG9wZXJhbmQgd2l0aCB0aGUgbGFyZ2VzdCB1bnNjYWxlZCB2YWx1ZQorICAgICAgICBCaWdEZWNpbWFsIHNtYWxsZXI7IC8vIG9wZXJhbmQgd2l0aCB0aGUgc21hbGxlc3QgdW5zY2FsZWQgdmFsdWUKKyAgICAgICAgQmlnSW50ZWdlciB0ZW1wQkk7CisgICAgICAgIGxvbmcgZGlmZlNjYWxlID0gKGxvbmcpdGhpcy5zY2FsZSAtIGF1Z2VuZC5zY2FsZTsKKyAgICAgICAgaW50IGxhcmdlclNpZ251bTsKKyAgICAgICAgLy8gU29tZSBvcGVyYW5kIGlzIHplcm8gb3IgdGhlIHByZWNpc2lvbiBpcyBpbmZpbml0eQorICAgICAgICBpZiAoKGF1Z2VuZC5pc1plcm8oKSkgfHwgKHRoaXMuaXNaZXJvKCkpCisgICAgICAgICAgICAgICAgfHwgKG1jLmdldFByZWNpc2lvbigpID09IDApKSB7CisgICAgICAgICAgICByZXR1cm4gYWRkKGF1Z2VuZCkucm91bmQobWMpOworICAgICAgICB9CisgICAgICAgIC8vIENhc2VzIHdoZXJlIHRoZXJlIGlzIHJvb20gZm9yIG9wdGltaXphdGlvbnMKKyAgICAgICAgaWYgKHRoaXMuYXBwcm94UHJlY2lzaW9uKCkgPCBkaWZmU2NhbGUgLSAxKSB7CisgICAgICAgICAgICBsYXJnZXIgPSBhdWdlbmQ7CisgICAgICAgICAgICBzbWFsbGVyID0gdGhpczsKKyAgICAgICAgfSBlbHNlIGlmIChhdWdlbmQuYXBwcm94UHJlY2lzaW9uKCkgPCAtZGlmZlNjYWxlIC0gMSkgeworICAgICAgICAgICAgbGFyZ2VyID0gdGhpczsKKyAgICAgICAgICAgIHNtYWxsZXIgPSBhdWdlbmQ7CisgICAgICAgIH0gZWxzZSB7Ly8gTm8gb3B0aW1pemF0aW9uIGlzIGRvbmUKKyAgICAgICAgICAgIHJldHVybiBhZGQoYXVnZW5kKS5yb3VuZChtYyk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG1jLmdldFByZWNpc2lvbigpID49IGxhcmdlci5hcHByb3hQcmVjaXNpb24oKSkgeworICAgICAgICAgICAgLy8gTm8gb3B0aW1pemF0aW9uIGlzIGRvbmUKKyAgICAgICAgICAgIHJldHVybiBhZGQoYXVnZW5kKS5yb3VuZChtYyk7CisgICAgICAgIH0KKyAgICAgICAgLy8gQ2FzZXMgd2hlcmUgaXQncyB1bm5lY2Vzc2FyeSB0byBhZGQgdHdvIG51bWJlcnMgd2l0aCB2ZXJ5IGRpZmZlcmVudCBzY2FsZXMKKyAgICAgICAgbGFyZ2VyU2lnbnVtID0gbGFyZ2VyLnNpZ251bSgpOworICAgICAgICBpZiAobGFyZ2VyU2lnbnVtID09IHNtYWxsZXIuc2lnbnVtKCkpIHsKKyAgICAgICAgICAgIHRlbXBCSSA9IE11bHRpcGxpY2F0aW9uLm11bHRpcGx5QnlQb3NpdGl2ZUludChsYXJnZXIuZ2V0VW5zY2FsZWRWYWx1ZSgpLDEwKQorICAgICAgICAgICAgLmFkZChCaWdJbnRlZ2VyLnZhbHVlT2YobGFyZ2VyU2lnbnVtKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0ZW1wQkkgPSBsYXJnZXIuZ2V0VW5zY2FsZWRWYWx1ZSgpLnN1YnRyYWN0KAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YobGFyZ2VyU2lnbnVtKSk7CisgICAgICAgICAgICB0ZW1wQkkgPSBNdWx0aXBsaWNhdGlvbi5tdWx0aXBseUJ5UG9zaXRpdmVJbnQodGVtcEJJLDEwKQorICAgICAgICAgICAgLmFkZChCaWdJbnRlZ2VyLnZhbHVlT2YobGFyZ2VyU2lnbnVtICogOSkpOworICAgICAgICB9CisgICAgICAgIC8vIFJvdW5kaW5nIHRoZSBpbXByb3ZlZCBhZGRpbmcKKyAgICAgICAgbGFyZ2VyID0gbmV3IEJpZ0RlY2ltYWwodGVtcEJJLCBsYXJnZXIuc2NhbGUgKyAxKTsKKyAgICAgICAgcmV0dXJuIGxhcmdlci5yb3VuZChtYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gd2hvc2UgdmFsdWUgaXMge0Bjb2RlIHRoaXMgLSBzdWJ0cmFoZW5kfS4KKyAgICAgKiBUaGUgc2NhbGUgb2YgdGhlIHJlc3VsdCBpcyB0aGUgbWF4aW11bSBvZiB0aGUgc2NhbGVzIG9mIHRoZSB0d28gYXJndW1lbnRzLgorICAgICAqCisgICAgICogQHBhcmFtIHN1YnRyYWhlbmQKKyAgICAgKiAgICAgICAgICAgIHZhbHVlIHRvIGJlIHN1YnRyYWN0ZWQgZnJvbSB7QGNvZGUgdGhpc30uCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpcyAtIHN1YnRyYWhlbmR9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3VidHJhaGVuZCA9PSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbCBzdWJ0cmFjdChCaWdEZWNpbWFsIHN1YnRyYWhlbmQpIHsKKyAgICAgICAgaW50IGRpZmZTY2FsZSA9IHRoaXMuc2NhbGUgLSBzdWJ0cmFoZW5kLnNjYWxlOworICAgICAgICAvLyBGYXN0IHJldHVybiB3aGVuIHNvbWUgb3BlcmFuZCBpcyB6ZXJvCisgICAgICAgIGlmICh0aGlzLmlzWmVybygpKSB7CisgICAgICAgICAgICBpZiAoZGlmZlNjYWxlIDw9IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VidHJhaGVuZC5uZWdhdGUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzdWJ0cmFoZW5kLmlzWmVybygpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAoc3VidHJhaGVuZC5pc1plcm8oKSkgeworICAgICAgICAgICAgaWYgKGRpZmZTY2FsZSA+PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gTGV0IGJlOiB0aGlzID0gW3UxLHMxXSBhbmQgc3VidHJhaGVuZCA9IFt1MixzMl0gc286CisgICAgICAgIGlmIChkaWZmU2NhbGUgPT0gMCkgeworICAgICAgICAgICAgLy8gY2FzZSBzMSA9IHMyIDogW3UxIC0gdTIgLCBzMV0KKyAgICAgICAgICAgIGlmIChNYXRoLm1heCh0aGlzLmJpdExlbmd0aCwgc3VidHJhaGVuZC5iaXRMZW5ndGgpICsgMSA8IDY0KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlT2YodGhpcy5zbWFsbFZhbHVlIC0gc3VidHJhaGVuZC5zbWFsbFZhbHVlLHRoaXMuc2NhbGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBCaWdEZWNpbWFsKHRoaXMuZ2V0VW5zY2FsZWRWYWx1ZSgpLnN1YnRyYWN0KHN1YnRyYWhlbmQuZ2V0VW5zY2FsZWRWYWx1ZSgpKSwgdGhpcy5zY2FsZSk7CisgICAgICAgIH0gZWxzZSBpZiAoZGlmZlNjYWxlID4gMCkgeworICAgICAgICAgICAgLy8gY2FzZSBzMSA+IHMyIDogWyB1MSAtIHUyICogMTAgXiAoczEgLSBzMikgLCBzMSBdCisgICAgICAgICAgICBpZihkaWZmU2NhbGUgPCBNYXRoVXRpbHMuTE9OR19QT1dFUlNfT0ZfVEVOLmxlbmd0aCAmJgorICAgICAgICAgICAgICAgICAgICBNYXRoLm1heCh0aGlzLmJpdExlbmd0aCxzdWJ0cmFoZW5kLmJpdExlbmd0aCtMT05HX1BPV0VSU19PRl9URU5fQklUX0xFTkdUSFtkaWZmU2NhbGVdKSsxPDY0KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlT2YodGhpcy5zbWFsbFZhbHVlLXN1YnRyYWhlbmQuc21hbGxWYWx1ZSpNYXRoVXRpbHMuTE9OR19QT1dFUlNfT0ZfVEVOW2RpZmZTY2FsZV0sdGhpcy5zY2FsZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IEJpZ0RlY2ltYWwodGhpcy5nZXRVbnNjYWxlZFZhbHVlKCkuc3VidHJhY3QoCisgICAgICAgICAgICAgICAgICAgIE11bHRpcGxpY2F0aW9uLm11bHRpcGx5QnlUZW5Qb3coc3VidHJhaGVuZC5nZXRVbnNjYWxlZFZhbHVlKCksZGlmZlNjYWxlKSksIHRoaXMuc2NhbGUpOworICAgICAgICB9IGVsc2Ugey8vIGNhc2UgczIgPiBzMSA6IFsgdTEgKiAxMCBeIChzMiAtIHMxKSAtIHUyICwgczIgXQorICAgICAgICAgICAgZGlmZlNjYWxlID0gLWRpZmZTY2FsZTsKKyAgICAgICAgICAgIGlmKGRpZmZTY2FsZSA8IE1hdGhVdGlscy5MT05HX1BPV0VSU19PRl9URU4ubGVuZ3RoICYmCisgICAgICAgICAgICAgICAgICAgIE1hdGgubWF4KHRoaXMuYml0TGVuZ3RoK0xPTkdfUE9XRVJTX09GX1RFTl9CSVRfTEVOR1RIW2RpZmZTY2FsZV0sc3VidHJhaGVuZC5iaXRMZW5ndGgpKzE8NjQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVPZih0aGlzLnNtYWxsVmFsdWUqTWF0aFV0aWxzLkxPTkdfUE9XRVJTX09GX1RFTltkaWZmU2NhbGVdLXN1YnRyYWhlbmQuc21hbGxWYWx1ZSxzdWJ0cmFoZW5kLnNjYWxlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuZXcgQmlnRGVjaW1hbChNdWx0aXBsaWNhdGlvbi5tdWx0aXBseUJ5VGVuUG93KHRoaXMuZ2V0VW5zY2FsZWRWYWx1ZSgpLGRpZmZTY2FsZSkKKyAgICAgICAgICAgIC5zdWJ0cmFjdChzdWJ0cmFoZW5kLmdldFVuc2NhbGVkVmFsdWUoKSksIHN1YnRyYWhlbmQuc2NhbGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gd2hvc2UgdmFsdWUgaXMge0Bjb2RlIHRoaXMgLSBzdWJ0cmFoZW5kfS4KKyAgICAgKiBUaGUgcmVzdWx0IGlzIHJvdW5kZWQgYWNjb3JkaW5nIHRvIHRoZSBwYXNzZWQgY29udGV4dCB7QGNvZGUgbWN9LgorICAgICAqCisgICAgICogQHBhcmFtIHN1YnRyYWhlbmQKKyAgICAgKiAgICAgICAgICAgIHZhbHVlIHRvIGJlIHN1YnRyYWN0ZWQgZnJvbSB7QGNvZGUgdGhpc30uCisgICAgICogQHBhcmFtIG1jCisgICAgICogICAgICAgICAgICByb3VuZGluZyBtb2RlIGFuZCBwcmVjaXNpb24gZm9yIHRoZSByZXN1bHQgb2YgdGhpcyBvcGVyYXRpb24uCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpcyAtIHN1YnRyYWhlbmR9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3VidHJhaGVuZCA9PSBudWxsfSBvciB7QGNvZGUgbWMgPT0gbnVsbH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwgc3VidHJhY3QoQmlnRGVjaW1hbCBzdWJ0cmFoZW5kLCBNYXRoQ29udGV4dCBtYykgeworICAgICAgICBsb25nIGRpZmZTY2FsZSA9IHN1YnRyYWhlbmQuc2NhbGUgLSAobG9uZyl0aGlzLnNjYWxlOworICAgICAgICBpbnQgdGhpc1NpZ251bTsKKyAgICAgICAgQmlnRGVjaW1hbCBsZWZ0T3BlcmFuZDsgLy8gaXQgd2lsbCBiZSBvbmx5IHRoZSBsZWZ0IG9wZXJhbmQgKHRoaXMpCisgICAgICAgIEJpZ0ludGVnZXIgdGVtcEJJOworICAgICAgICAvLyBTb21lIG9wZXJhbmQgaXMgemVybyBvciB0aGUgcHJlY2lzaW9uIGlzIGluZmluaXR5CisgICAgICAgIGlmICgoc3VidHJhaGVuZC5pc1plcm8oKSkgfHwgKHRoaXMuaXNaZXJvKCkpCisgICAgICAgICAgICAgICAgfHwgKG1jLmdldFByZWNpc2lvbigpID09IDApKSB7CisgICAgICAgICAgICByZXR1cm4gc3VidHJhY3Qoc3VidHJhaGVuZCkucm91bmQobWMpOworICAgICAgICB9CisgICAgICAgIC8vIE5vdzogICB0aGlzICE9IDAgICBhbmQgICBzdWJ0cmFoZW5kICE9IDAKKyAgICAgICAgaWYgKHN1YnRyYWhlbmQuYXBwcm94UHJlY2lzaW9uKCkgPCBkaWZmU2NhbGUgLSAxKSB7CisgICAgICAgICAgICAvLyBDYXNlcyB3aGVyZSBpdCBpcyB1bm5lY2Vzc2FyeSB0byBzdWJ0cmFjdCB0d28gbnVtYmVycyB3aXRoIHZlcnkgZGlmZmVyZW50IHNjYWxlcworICAgICAgICAgICAgaWYgKG1jLmdldFByZWNpc2lvbigpIDwgdGhpcy5hcHByb3hQcmVjaXNpb24oKSkgeworICAgICAgICAgICAgICAgIHRoaXNTaWdudW0gPSB0aGlzLnNpZ251bSgpOworICAgICAgICAgICAgICAgIGlmICh0aGlzU2lnbnVtICE9IHN1YnRyYWhlbmQuc2lnbnVtKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGVtcEJJID0gTXVsdGlwbGljYXRpb24ubXVsdGlwbHlCeVBvc2l0aXZlSW50KHRoaXMuZ2V0VW5zY2FsZWRWYWx1ZSgpLCAxMCkKKyAgICAgICAgICAgICAgICAgICAgLmFkZChCaWdJbnRlZ2VyLnZhbHVlT2YodGhpc1NpZ251bSkpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRlbXBCSSA9IHRoaXMuZ2V0VW5zY2FsZWRWYWx1ZSgpLnN1YnRyYWN0KEJpZ0ludGVnZXIudmFsdWVPZih0aGlzU2lnbnVtKSk7CisgICAgICAgICAgICAgICAgICAgIHRlbXBCSSA9IE11bHRpcGxpY2F0aW9uLm11bHRpcGx5QnlQb3NpdGl2ZUludCh0ZW1wQkksIDEwKQorICAgICAgICAgICAgICAgICAgICAuYWRkKEJpZ0ludGVnZXIudmFsdWVPZih0aGlzU2lnbnVtICogOSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBSb3VuZGluZyB0aGUgaW1wcm92ZWQgc3VidHJhY3RpbmcKKyAgICAgICAgICAgICAgICBsZWZ0T3BlcmFuZCA9IG5ldyBCaWdEZWNpbWFsKHRlbXBCSSwgdGhpcy5zY2FsZSArIDEpOworICAgICAgICAgICAgICAgIHJldHVybiBsZWZ0T3BlcmFuZC5yb3VuZChtYyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gTm8gb3B0aW1pemF0aW9uIGlzIGRvbmUKKyAgICAgICAgcmV0dXJuIHN1YnRyYWN0KHN1YnRyYWhlbmQpLnJvdW5kKG1jKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBCaWdEZWNpbWFsfSB3aG9zZSB2YWx1ZSBpcyB7QGNvZGUgdGhpcyAqCisgICAgICogbXVsdGlwbGljYW5kfS4gVGhlIHNjYWxlIG9mIHRoZSByZXN1bHQgaXMgdGhlIHN1bSBvZiB0aGUgc2NhbGVzIG9mIHRoZQorICAgICAqIHR3byBhcmd1bWVudHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXVsdGlwbGljYW5kCisgICAgICogICAgICAgICAgICB2YWx1ZSB0byBiZSBtdWx0aXBsaWVkIHdpdGgge0Bjb2RlIHRoaXN9LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXMgKiBtdWx0aXBsaWNhbmR9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbXVsdGlwbGljYW5kID09IG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsIG11bHRpcGx5KEJpZ0RlY2ltYWwgbXVsdGlwbGljYW5kKSB7CisgICAgICAgIGxvbmcgbmV3U2NhbGUgPSAobG9uZyl0aGlzLnNjYWxlICsgbXVsdGlwbGljYW5kLnNjYWxlOworCisgICAgICAgIGlmICgodGhpcy5pc1plcm8oKSkgfHwgKG11bHRpcGxpY2FuZC5pc1plcm8oKSkpIHsKKyAgICAgICAgICAgIHJldHVybiB6ZXJvU2NhbGVkQnkobmV3U2NhbGUpOworICAgICAgICB9CisgICAgICAgIC8qIExldCBiZTogdGhpcyA9IFt1MSxzMV0gYW5kIG11bHRpcGxpY2FuZCA9IFt1MixzMl0gc286CisgICAgICAgICAqIHRoaXMgeCBtdWx0aXBsaWNhbmQgPSBbIHMxICogczIgLCBzMSArIHMyIF0gKi8KKyAgICAgICAgaWYodGhpcy5iaXRMZW5ndGggKyBtdWx0aXBsaWNhbmQuYml0TGVuZ3RoIDwgNjQpIHsKKyAgICAgICAgICAgIHJldHVybiB2YWx1ZU9mKHRoaXMuc21hbGxWYWx1ZSptdWx0aXBsaWNhbmQuc21hbGxWYWx1ZSwgc2FmZUxvbmdUb0ludChuZXdTY2FsZSkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgQmlnRGVjaW1hbCh0aGlzLmdldFVuc2NhbGVkVmFsdWUoKS5tdWx0aXBseSgKKyAgICAgICAgICAgICAgICBtdWx0aXBsaWNhbmQuZ2V0VW5zY2FsZWRWYWx1ZSgpKSwgc2FmZUxvbmdUb0ludChuZXdTY2FsZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IHdob3NlIHZhbHVlIGlzIHtAY29kZSB0aGlzICoKKyAgICAgKiBtdWx0aXBsaWNhbmR9LiBUaGUgcmVzdWx0IGlzIHJvdW5kZWQgYWNjb3JkaW5nIHRvIHRoZSBwYXNzZWQgY29udGV4dAorICAgICAqIHtAY29kZSBtY30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXVsdGlwbGljYW5kCisgICAgICogICAgICAgICAgICB2YWx1ZSB0byBiZSBtdWx0aXBsaWVkIHdpdGgge0Bjb2RlIHRoaXN9LgorICAgICAqIEBwYXJhbSBtYworICAgICAqICAgICAgICAgICAgcm91bmRpbmcgbW9kZSBhbmQgcHJlY2lzaW9uIGZvciB0aGUgcmVzdWx0IG9mIHRoaXMgb3BlcmF0aW9uLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXMgKiBtdWx0aXBsaWNhbmR9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbXVsdGlwbGljYW5kID09IG51bGx9IG9yIHtAY29kZSBtYyA9PSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbCBtdWx0aXBseShCaWdEZWNpbWFsIG11bHRpcGxpY2FuZCwgTWF0aENvbnRleHQgbWMpIHsKKyAgICAgICAgQmlnRGVjaW1hbCByZXN1bHQgPSBtdWx0aXBseShtdWx0aXBsaWNhbmQpOworCisgICAgICAgIHJlc3VsdC5pbnBsYWNlUm91bmQobWMpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IHdob3NlIHZhbHVlIGlzIHtAY29kZSB0aGlzIC8gZGl2aXNvcn0uCisgICAgICogQXMgc2NhbGUgb2YgdGhlIHJlc3VsdCB0aGUgcGFyYW1ldGVyIHtAY29kZSBzY2FsZX0gaXMgdXNlZC4gSWYgcm91bmRpbmcKKyAgICAgKiBpcyByZXF1aXJlZCB0byBtZWV0IHRoZSBzcGVjaWZpZWQgc2NhbGUsIHRoZW4gdGhlIHNwZWNpZmllZCByb3VuZGluZyBtb2RlCisgICAgICoge0Bjb2RlIHJvdW5kaW5nTW9kZX0gaXMgYXBwbGllZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkaXZpc29yCisgICAgICogICAgICAgICAgICB2YWx1ZSBieSB3aGljaCB7QGNvZGUgdGhpc30gaXMgZGl2aWRlZC4KKyAgICAgKiBAcGFyYW0gc2NhbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzY2FsZSBvZiB0aGUgcmVzdWx0IHJldHVybmVkLgorICAgICAqIEBwYXJhbSByb3VuZGluZ01vZGUKKyAgICAgKiAgICAgICAgICAgIHJvdW5kaW5nIG1vZGUgdG8gYmUgdXNlZCB0byByb3VuZCB0aGUgcmVzdWx0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXMgLyBkaXZpc29yfSByb3VuZGVkIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gcm91bmRpbmcKKyAgICAgKiAgICAgICAgIG1vZGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkaXZpc29yID09IG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHJvdW5kaW5nTW9kZX0gaXMgbm90IGEgdmFsaWQgcm91bmRpbmcgbW9kZS4KKyAgICAgKiBAdGhyb3dzIEFyaXRobWV0aWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGl2aXNvciA9PSAwfS4KKyAgICAgKiBAdGhyb3dzIEFyaXRobWV0aWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcm91bmRpbmdNb2RlID09IFJPVU5EX1VOTkVDRVNTQVJZfSBhbmQgcm91bmRpbmcgaXMKKyAgICAgKiAgICAgICAgICAgICBuZWNlc3NhcnkgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBzY2FsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbCBkaXZpZGUoQmlnRGVjaW1hbCBkaXZpc29yLCBpbnQgc2NhbGUsIGludCByb3VuZGluZ01vZGUpIHsKKyAgICAgICAgcmV0dXJuIGRpdmlkZShkaXZpc29yLCBzY2FsZSwgUm91bmRpbmdNb2RlLnZhbHVlT2Yocm91bmRpbmdNb2RlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gd2hvc2UgdmFsdWUgaXMge0Bjb2RlIHRoaXMgLyBkaXZpc29yfS4KKyAgICAgKiBBcyBzY2FsZSBvZiB0aGUgcmVzdWx0IHRoZSBwYXJhbWV0ZXIge0Bjb2RlIHNjYWxlfSBpcyB1c2VkLiBJZiByb3VuZGluZworICAgICAqIGlzIHJlcXVpcmVkIHRvIG1lZXQgdGhlIHNwZWNpZmllZCBzY2FsZSwgdGhlbiB0aGUgc3BlY2lmaWVkIHJvdW5kaW5nIG1vZGUKKyAgICAgKiB7QGNvZGUgcm91bmRpbmdNb2RlfSBpcyBhcHBsaWVkLgorICAgICAqCisgICAgICogQHBhcmFtIGRpdmlzb3IKKyAgICAgKiAgICAgICAgICAgIHZhbHVlIGJ5IHdoaWNoIHtAY29kZSB0aGlzfSBpcyBkaXZpZGVkLgorICAgICAqIEBwYXJhbSBzY2FsZQorICAgICAqICAgICAgICAgICAgdGhlIHNjYWxlIG9mIHRoZSByZXN1bHQgcmV0dXJuZWQuCisgICAgICogQHBhcmFtIHJvdW5kaW5nTW9kZQorICAgICAqICAgICAgICAgICAgcm91bmRpbmcgbW9kZSB0byBiZSB1c2VkIHRvIHJvdW5kIHRoZSByZXN1bHQuCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpcyAvIGRpdmlzb3J9IHJvdW5kZWQgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiByb3VuZGluZworICAgICAqICAgICAgICAgbW9kZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGRpdmlzb3IgPT0gbnVsbH0gb3Ige0Bjb2RlIHJvdW5kaW5nTW9kZSA9PSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIEFyaXRobWV0aWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGl2aXNvciA9PSAwfS4KKyAgICAgKiBAdGhyb3dzIEFyaXRobWV0aWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcm91bmRpbmdNb2RlID09IFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSfVkgYW5kCisgICAgICogICAgICAgICAgICAgcm91bmRpbmcgaXMgbmVjZXNzYXJ5IGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gc2NhbGUgYW5kIGdpdmVuCisgICAgICogICAgICAgICAgICAgcHJlY2lzaW9uLgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsIGRpdmlkZShCaWdEZWNpbWFsIGRpdmlzb3IsIGludCBzY2FsZSwgUm91bmRpbmdNb2RlIHJvdW5kaW5nTW9kZSkgeworICAgICAgICAvLyBMZXQgYmU6IHRoaXMgPSBbdTEsczFdICBhbmQgIGRpdmlzb3IgPSBbdTIsczJdCisgICAgICAgIGlmIChyb3VuZGluZ01vZGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRpdmlzb3IuaXNaZXJvKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBcml0aG1ldGljRXhjZXB0aW9uKCJEaXZpc2lvbiBieSB6ZXJvIik7CisgICAgICAgIH0KKworICAgICAgICBsb25nIGRpZmZTY2FsZSA9ICgobG9uZyl0aGlzLnNjYWxlIC0gZGl2aXNvci5zY2FsZSkgLSBzY2FsZTsKKyAgICAgICAgaWYodGhpcy5iaXRMZW5ndGggPCA2NCAmJiBkaXZpc29yLmJpdExlbmd0aCA8IDY0ICkgeworICAgICAgICAgICAgaWYoZGlmZlNjYWxlID09IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZGl2aWRlUHJpbWl0aXZlTG9uZ3ModGhpcy5zbWFsbFZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgZGl2aXNvci5zbWFsbFZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGUsCisgICAgICAgICAgICAgICAgICAgICAgICByb3VuZGluZ01vZGUgKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZihkaWZmU2NhbGUgPiAwKSB7CisgICAgICAgICAgICAgICAgaWYoZGlmZlNjYWxlIDwgTWF0aFV0aWxzLkxPTkdfUE9XRVJTX09GX1RFTi5sZW5ndGggJiYKKyAgICAgICAgICAgICAgICAgICAgICAgIGRpdmlzb3IuYml0TGVuZ3RoICsgTE9OR19QT1dFUlNfT0ZfVEVOX0JJVF9MRU5HVEhbKGludClkaWZmU2NhbGVdIDwgNjQpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRpdmlkZVByaW1pdGl2ZUxvbmdzKHRoaXMuc21hbGxWYWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXZpc29yLnNtYWxsVmFsdWUqTWF0aFV0aWxzLkxPTkdfUE9XRVJTX09GX1RFTlsoaW50KWRpZmZTY2FsZV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmRpbmdNb2RlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeyAvLyBkaWZmU2NhbGUgPCAwCisgICAgICAgICAgICAgICAgaWYoLWRpZmZTY2FsZSA8IE1hdGhVdGlscy5MT05HX1BPV0VSU19PRl9URU4ubGVuZ3RoICYmCisgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJpdExlbmd0aCArIExPTkdfUE9XRVJTX09GX1RFTl9CSVRfTEVOR1RIWyhpbnQpLWRpZmZTY2FsZV0gPCA2NCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGl2aWRlUHJpbWl0aXZlTG9uZ3ModGhpcy5zbWFsbFZhbHVlKk1hdGhVdGlscy5MT05HX1BPV0VSU19PRl9URU5bKGludCktZGlmZlNjYWxlXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXZpc29yLnNtYWxsVmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmRpbmdNb2RlKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBCaWdJbnRlZ2VyIHNjYWxlZERpdmlkZW5kID0gdGhpcy5nZXRVbnNjYWxlZFZhbHVlKCk7CisgICAgICAgIEJpZ0ludGVnZXIgc2NhbGVkRGl2aXNvciA9IGRpdmlzb3IuZ2V0VW5zY2FsZWRWYWx1ZSgpOyAvLyBmb3Igc2NhbGluZyBvZiAndTInCisKKyAgICAgICAgaWYgKGRpZmZTY2FsZSA+IDApIHsKKyAgICAgICAgICAgIC8vIE11bHRpcGx5ICd1MicgIGJ5OiAgMTBeKChzMSAtIHMyKSAtIHNjYWxlKQorICAgICAgICAgICAgc2NhbGVkRGl2aXNvciA9IE11bHRpcGxpY2F0aW9uLm11bHRpcGx5QnlUZW5Qb3coc2NhbGVkRGl2aXNvciwgKGludClkaWZmU2NhbGUpOworICAgICAgICB9IGVsc2UgaWYgKGRpZmZTY2FsZSA8IDApIHsKKyAgICAgICAgICAgIC8vIE11bHRpcGx5ICd1MScgIGJ5OiAgMTBeKHNjYWxlIC0gKHMxIC0gczIpKQorICAgICAgICAgICAgc2NhbGVkRGl2aWRlbmQgID0gTXVsdGlwbGljYXRpb24ubXVsdGlwbHlCeVRlblBvdyhzY2FsZWREaXZpZGVuZCwgKGludCktZGlmZlNjYWxlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZGl2aWRlQmlnSW50ZWdlcnMoc2NhbGVkRGl2aWRlbmQsIHNjYWxlZERpdmlzb3IsIHNjYWxlLCByb3VuZGluZ01vZGUpOworICAgICAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBCaWdEZWNpbWFsIGRpdmlkZUJpZ0ludGVnZXJzKEJpZ0ludGVnZXIgc2NhbGVkRGl2aWRlbmQsIEJpZ0ludGVnZXIgc2NhbGVkRGl2aXNvciwgaW50IHNjYWxlLCBSb3VuZGluZ01vZGUgcm91bmRpbmdNb2RlKSB7CisKKyAgICAgICAgQmlnSW50ZWdlcltdIHF1b3RBbmRSZW0gPSBzY2FsZWREaXZpZGVuZC5kaXZpZGVBbmRSZW1haW5kZXIoc2NhbGVkRGl2aXNvcik7ICAvLyBxdW90aWVudCBhbmQgcmVtYWluZGVyCisgICAgICAgIC8vIElmIGFmdGVyIGRpdmlzaW9uIHRoZXJlIGlzIGEgcmVtYWluZGVyLi4uCisgICAgICAgIEJpZ0ludGVnZXIgcXVvdGllbnQgPSBxdW90QW5kUmVtWzBdOworICAgICAgICBCaWdJbnRlZ2VyIHJlbWFpbmRlciA9IHF1b3RBbmRSZW1bMV07CisgICAgICAgIGlmIChyZW1haW5kZXIuc2lnbnVtKCkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBCaWdEZWNpbWFsKHF1b3RpZW50LCBzY2FsZSk7CisgICAgICAgIH0KKyAgICAgICAgaW50IHNpZ24gPSBzY2FsZWREaXZpZGVuZC5zaWdudW0oKSAqIHNjYWxlZERpdmlzb3Iuc2lnbnVtKCk7CisgICAgICAgIGludCBjb21wUmVtOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gJ2NvbXBhcmUgdG8gcmVtYWluZGVyJworICAgICAgICBpZihzY2FsZWREaXZpc29yLmJpdExlbmd0aCgpIDwgNjMpIHsgLy8gNjMgaW4gb3JkZXIgdG8gYXZvaWQgb3V0IG9mIGxvbmcgYWZ0ZXIgKjIKKyAgICAgICAgICAgIGxvbmcgcmVtID0gcmVtYWluZGVyLmxvbmdWYWx1ZSgpOworICAgICAgICAgICAgbG9uZyBkaXZpc29yID0gc2NhbGVkRGl2aXNvci5sb25nVmFsdWUoKTsKKyAgICAgICAgICAgIGNvbXBSZW0gPSBsb25nQ29tcGFyZVRvKE1hdGguYWJzKHJlbSkgKiAyLE1hdGguYWJzKGRpdmlzb3IpKTsKKyAgICAgICAgICAgIC8vIFRvIGxvb2sgaWYgdGhlcmUgaXMgYSBjYXJyeQorICAgICAgICAgICAgY29tcFJlbSA9IHJvdW5kaW5nQmVoYXZpb3IocXVvdGllbnQudGVzdEJpdCgwKSA/IDEgOiAwLAorICAgICAgICAgICAgICAgICAgICBzaWduICogKDUgKyBjb21wUmVtKSwgcm91bmRpbmdNb2RlKTsKKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gQ2hlY2tpbmcgaWY6ICByZW1haW5kZXIgKiAyID49IHNjYWxlZERpdmlzb3IKKyAgICAgICAgICAgIGNvbXBSZW0gPSByZW1haW5kZXIuYWJzKCkuc2hpZnRMZWZ0T25lQml0KCkuY29tcGFyZVRvKHNjYWxlZERpdmlzb3IuYWJzKCkpOworICAgICAgICAgICAgY29tcFJlbSA9IHJvdW5kaW5nQmVoYXZpb3IocXVvdGllbnQudGVzdEJpdCgwKSA/IDEgOiAwLAorICAgICAgICAgICAgICAgICAgICBzaWduICogKDUgKyBjb21wUmVtKSwgcm91bmRpbmdNb2RlKTsKKyAgICAgICAgfQorICAgICAgICAgICAgaWYgKGNvbXBSZW0gIT0gMCkgeworICAgICAgICAgICAgaWYocXVvdGllbnQuYml0TGVuZ3RoKCkgPCA2MykgeworICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZU9mKHF1b3RpZW50LmxvbmdWYWx1ZSgpICsgY29tcFJlbSxzY2FsZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBxdW90aWVudCA9IHF1b3RpZW50LmFkZChCaWdJbnRlZ2VyLnZhbHVlT2YoY29tcFJlbSkpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBCaWdEZWNpbWFsKHF1b3RpZW50LCBzY2FsZSk7CisgICAgICAgIH0KKyAgICAgICAgLy8gQ29uc3RydWN0aW5nIHRoZSByZXN1bHQgd2l0aCB0aGUgYXBwcm9wcmlhdGUgdW5zY2FsZWQgdmFsdWUKKyAgICAgICAgcmV0dXJuIG5ldyBCaWdEZWNpbWFsKHF1b3RpZW50LCBzY2FsZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgQmlnRGVjaW1hbCBkaXZpZGVQcmltaXRpdmVMb25ncyhsb25nIHNjYWxlZERpdmlkZW5kLCBsb25nIHNjYWxlZERpdmlzb3IsIGludCBzY2FsZSwgUm91bmRpbmdNb2RlIHJvdW5kaW5nTW9kZSkgeworICAgICAgICBsb25nIHF1b3RpZW50ID0gc2NhbGVkRGl2aWRlbmQgLyBzY2FsZWREaXZpc29yOworICAgICAgICBsb25nIHJlbWFpbmRlciA9IHNjYWxlZERpdmlkZW5kICUgc2NhbGVkRGl2aXNvcjsKKyAgICAgICAgaW50IHNpZ24gPSBMb25nLnNpZ251bSggc2NhbGVkRGl2aWRlbmQgKSAqIExvbmcuc2lnbnVtKCBzY2FsZWREaXZpc29yICk7CisgICAgICAgIGlmIChyZW1haW5kZXIgIT0gMCkgeworICAgICAgICAgICAgLy8gQ2hlY2tpbmcgaWY6ICByZW1haW5kZXIgKiAyID49IHNjYWxlZERpdmlzb3IKKyAgICAgICAgICAgIGludCBjb21wUmVtOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gJ2NvbXBhcmUgdG8gcmVtYWluZGVyJworICAgICAgICAgICAgY29tcFJlbSA9IGxvbmdDb21wYXJlVG8oTWF0aC5hYnMocmVtYWluZGVyKSAqIDIsTWF0aC5hYnMoc2NhbGVkRGl2aXNvcikpOworICAgICAgICAgICAgLy8gVG8gbG9vayBpZiB0aGVyZSBpcyBhIGNhcnJ5CisgICAgICAgICAgICBxdW90aWVudCArPSByb3VuZGluZ0JlaGF2aW9yKCgoaW50KXF1b3RpZW50KSAmIDEsCisgICAgICAgICAgICAgICAgICAgIHNpZ24gKiAoNSArIGNvbXBSZW0pLAorICAgICAgICAgICAgICAgICAgICByb3VuZGluZ01vZGUpOworICAgICAgICB9CisgICAgICAgIC8vIENvbnN0cnVjdGluZyB0aGUgcmVzdWx0IHdpdGggdGhlIGFwcHJvcHJpYXRlIHVuc2NhbGVkIHZhbHVlCisgICAgICAgIHJldHVybiB2YWx1ZU9mKHF1b3RpZW50LCBzY2FsZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gd2hvc2UgdmFsdWUgaXMge0Bjb2RlIHRoaXMgLyBkaXZpc29yfS4KKyAgICAgKiBUaGUgc2NhbGUgb2YgdGhlIHJlc3VsdCBpcyB0aGUgc2NhbGUgb2Yge0Bjb2RlIHRoaXN9LiBJZiByb3VuZGluZyBpcworICAgICAqIHJlcXVpcmVkIHRvIG1lZXQgdGhlIHNwZWNpZmllZCBzY2FsZSwgdGhlbiB0aGUgc3BlY2lmaWVkIHJvdW5kaW5nIG1vZGUKKyAgICAgKiB7QGNvZGUgcm91bmRpbmdNb2RlfSBpcyBhcHBsaWVkLgorICAgICAqCisgICAgICogQHBhcmFtIGRpdmlzb3IKKyAgICAgKiAgICAgICAgICAgIHZhbHVlIGJ5IHdoaWNoIHtAY29kZSB0aGlzfSBpcyBkaXZpZGVkLgorICAgICAqIEBwYXJhbSByb3VuZGluZ01vZGUKKyAgICAgKiAgICAgICAgICAgIHJvdW5kaW5nIG1vZGUgdG8gYmUgdXNlZCB0byByb3VuZCB0aGUgcmVzdWx0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXMgLyBkaXZpc29yfSByb3VuZGVkIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gcm91bmRpbmcKKyAgICAgKiAgICAgICAgIG1vZGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkaXZpc29yID09IG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHJvdW5kaW5nTW9kZX0gaXMgbm90IGEgdmFsaWQgcm91bmRpbmcgbW9kZS4KKyAgICAgKiBAdGhyb3dzIEFyaXRobWV0aWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGl2aXNvciA9PSAwfS4KKyAgICAgKiBAdGhyb3dzIEFyaXRobWV0aWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcm91bmRpbmdNb2RlID09IFJPVU5EX1VOTkVDRVNTQVJZfSBhbmQgcm91bmRpbmcgaXMKKyAgICAgKiAgICAgICAgICAgICBuZWNlc3NhcnkgYWNjb3JkaW5nIHRvIHRoZSBzY2FsZSBvZiB0aGlzLgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsIGRpdmlkZShCaWdEZWNpbWFsIGRpdmlzb3IsIGludCByb3VuZGluZ01vZGUpIHsKKyAgICAgICAgcmV0dXJuIGRpdmlkZShkaXZpc29yLCBzY2FsZSwgUm91bmRpbmdNb2RlLnZhbHVlT2Yocm91bmRpbmdNb2RlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gd2hvc2UgdmFsdWUgaXMge0Bjb2RlIHRoaXMgLyBkaXZpc29yfS4KKyAgICAgKiBUaGUgc2NhbGUgb2YgdGhlIHJlc3VsdCBpcyB0aGUgc2NhbGUgb2Yge0Bjb2RlIHRoaXN9LiBJZiByb3VuZGluZyBpcworICAgICAqIHJlcXVpcmVkIHRvIG1lZXQgdGhlIHNwZWNpZmllZCBzY2FsZSwgdGhlbiB0aGUgc3BlY2lmaWVkIHJvdW5kaW5nIG1vZGUKKyAgICAgKiB7QGNvZGUgcm91bmRpbmdNb2RlfSBpcyBhcHBsaWVkLgorICAgICAqCisgICAgICogQHBhcmFtIGRpdmlzb3IKKyAgICAgKiAgICAgICAgICAgIHZhbHVlIGJ5IHdoaWNoIHtAY29kZSB0aGlzfSBpcyBkaXZpZGVkLgorICAgICAqIEBwYXJhbSByb3VuZGluZ01vZGUKKyAgICAgKiAgICAgICAgICAgIHJvdW5kaW5nIG1vZGUgdG8gYmUgdXNlZCB0byByb3VuZCB0aGUgcmVzdWx0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXMgLyBkaXZpc29yfSByb3VuZGVkIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gcm91bmRpbmcKKyAgICAgKiAgICAgICAgIG1vZGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkaXZpc29yID09IG51bGx9IG9yIHtAY29kZSByb3VuZGluZ01vZGUgPT0gbnVsbH0uCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGRpdmlzb3IgPT0gMH0uCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHJvdW5kaW5nTW9kZSA9PSBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUll9IGFuZAorICAgICAqICAgICAgICAgICAgIHJvdW5kaW5nIGlzIG5lY2Vzc2FyeSBhY2NvcmRpbmcgdG8gdGhlIHNjYWxlIG9mIHRoaXMuCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwgZGl2aWRlKEJpZ0RlY2ltYWwgZGl2aXNvciwgUm91bmRpbmdNb2RlIHJvdW5kaW5nTW9kZSkgeworICAgICAgICByZXR1cm4gZGl2aWRlKGRpdmlzb3IsIHNjYWxlLCByb3VuZGluZ01vZGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IHdob3NlIHZhbHVlIGlzIHtAY29kZSB0aGlzIC8gZGl2aXNvcn0uCisgICAgICogVGhlIHNjYWxlIG9mIHRoZSByZXN1bHQgaXMgdGhlIGRpZmZlcmVuY2Ugb2YgdGhlIHNjYWxlcyBvZiB7QGNvZGUgdGhpc30KKyAgICAgKiBhbmQge0Bjb2RlIGRpdmlzb3J9LiBJZiB0aGUgZXhhY3QgcmVzdWx0IHJlcXVpcmVzIG1vcmUgZGlnaXRzLCB0aGVuIHRoZQorICAgICAqIHNjYWxlIGlzIGFkanVzdGVkIGFjY29yZGluZ2x5LiBGb3IgZXhhbXBsZSwge0Bjb2RlIDEvMTI4ID0gMC4wMDc4MTI1fQorICAgICAqIHdoaWNoIGhhcyBhIHNjYWxlIG9mIHtAY29kZSA3fSBhbmQgcHJlY2lzaW9uIHtAY29kZSA1fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkaXZpc29yCisgICAgICogICAgICAgICAgICB2YWx1ZSBieSB3aGljaCB7QGNvZGUgdGhpc30gaXMgZGl2aWRlZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0aGlzIC8gZGl2aXNvcn0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkaXZpc29yID09IG51bGx9LgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkaXZpc29yID09IDB9LgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSByZXN1bHQgY2Fubm90IGJlIHJlcHJlc2VudGVkIGV4YWN0bHkuCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwgZGl2aWRlKEJpZ0RlY2ltYWwgZGl2aXNvcikgeworICAgICAgICBCaWdJbnRlZ2VyIHAgPSB0aGlzLmdldFVuc2NhbGVkVmFsdWUoKTsKKyAgICAgICAgQmlnSW50ZWdlciBxID0gZGl2aXNvci5nZXRVbnNjYWxlZFZhbHVlKCk7CisgICAgICAgIEJpZ0ludGVnZXIgZ2NkOyAvLyBncmVhdGVzdCBjb21tb24gZGl2aXNvciBiZXR3ZWVuICdwJyBhbmQgJ3EnCisgICAgICAgIEJpZ0ludGVnZXIgcXVvdEFuZFJlbVtdOworICAgICAgICBsb25nIGRpZmZTY2FsZSA9IChsb25nKXNjYWxlIC0gZGl2aXNvci5zY2FsZTsKKyAgICAgICAgaW50IG5ld1NjYWxlOyAvLyB0aGUgbmV3IHNjYWxlIGZvciBmaW5hbCBxdW90aWVudAorICAgICAgICBpbnQgazsgLy8gbnVtYmVyIG9mIGZhY3RvcnMgIjIiIGluICdxJworICAgICAgICBpbnQgbCA9IDA7IC8vIG51bWJlciBvZiBmYWN0b3JzICI1IiBpbiAncScKKyAgICAgICAgaW50IGkgPSAxOworICAgICAgICBpbnQgbGFzdFBvdyA9IEZJVkVfUE9XLmxlbmd0aCAtIDE7CisKKyAgICAgICAgaWYgKGRpdmlzb3IuaXNaZXJvKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBcml0aG1ldGljRXhjZXB0aW9uKCJEaXZpc2lvbiBieSB6ZXJvIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHAuc2lnbnVtKCkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHplcm9TY2FsZWRCeShkaWZmU2NhbGUpOworICAgICAgICB9CisgICAgICAgIC8vIFRvIGRpdmlkZSBib3RoIGJ5IHRoZSBHQ0QKKyAgICAgICAgZ2NkID0gcC5nY2QocSk7CisgICAgICAgIHAgPSBwLmRpdmlkZShnY2QpOworICAgICAgICBxID0gcS5kaXZpZGUoZ2NkKTsKKyAgICAgICAgLy8gVG8gc2ltcGxpZnkgYWxsICIyIiBmYWN0b3JzIG9mIHEsIGRpdmlkaW5nIGJ5IDJeaworICAgICAgICBrID0gcS5nZXRMb3dlc3RTZXRCaXQoKTsKKyAgICAgICAgcSA9IHEuc2hpZnRSaWdodChrKTsKKyAgICAgICAgLy8gVG8gc2ltcGxpZnkgYWxsICI1IiBmYWN0b3JzIG9mIHEsIGRpdmlkaW5nIGJ5IDVebAorICAgICAgICBkbyB7CisgICAgICAgICAgICBxdW90QW5kUmVtID0gcS5kaXZpZGVBbmRSZW1haW5kZXIoRklWRV9QT1dbaV0pOworICAgICAgICAgICAgaWYgKHF1b3RBbmRSZW1bMV0uc2lnbnVtKCkgPT0gMCkgeworICAgICAgICAgICAgICAgIGwgKz0gaTsKKyAgICAgICAgICAgICAgICBpZiAoaSA8IGxhc3RQb3cpIHsKKyAgICAgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBxID0gcXVvdEFuZFJlbVswXTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKGkgPT0gMSkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaSA9IDE7CisgICAgICAgICAgICB9CisgICAgICAgIH0gd2hpbGUgKHRydWUpOworICAgICAgICAvLyBJZiAgYWJzKHEpICE9IDEgIHRoZW4gdGhlIHF1b3RpZW50IGlzIHBlcmlvZGljCisgICAgICAgIGlmICghcS5hYnMoKS5lcXVhbHMoQmlnSW50ZWdlci5PTkUpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJpdGhtZXRpY0V4Y2VwdGlvbigiTm9uLXRlcm1pbmF0aW5nIGRlY2ltYWwgZXhwYW5zaW9uOyBubyBleGFjdCByZXByZXNlbnRhYmxlIGRlY2ltYWwgcmVzdWx0Iik7CisgICAgICAgIH0KKyAgICAgICAgLy8gVGhlIHNpZ24gb2YgdGhlIGlzIGZpeGVkIGFuZCB0aGUgcXVvdGllbnQgd2lsbCBiZSBzYXZlZCBpbiAncCcKKyAgICAgICAgaWYgKHEuc2lnbnVtKCkgPCAwKSB7CisgICAgICAgICAgICBwID0gcC5uZWdhdGUoKTsKKyAgICAgICAgfQorICAgICAgICAvLyBDaGVja2luZyBpZiB0aGUgbmV3IHNjYWxlIGlzIG91dCBvZiByYW5nZQorICAgICAgICBuZXdTY2FsZSA9IHNhZmVMb25nVG9JbnQoZGlmZlNjYWxlICsgTWF0aC5tYXgoaywgbCkpOworICAgICAgICAvLyBrID49IDAgIGFuZCAgbCA+PSAwICBpbXBsaWVzIHRoYXQgIGsgLSBsICBpcyBpbiB0aGUgMzItYml0IHJhbmdlCisgICAgICAgIGkgPSBrIC0gbDsKKworICAgICAgICBwID0gKGkgPiAwKSA/IE11bHRpcGxpY2F0aW9uLm11bHRpcGx5QnlGaXZlUG93KHAsIGkpCisgICAgICAgIDogcC5zaGlmdExlZnQoLWkpOworICAgICAgICByZXR1cm4gbmV3IEJpZ0RlY2ltYWwocCwgbmV3U2NhbGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IHdob3NlIHZhbHVlIGlzIHtAY29kZSB0aGlzIC8gZGl2aXNvcn0uCisgICAgICogVGhlIHJlc3VsdCBpcyByb3VuZGVkIGFjY29yZGluZyB0byB0aGUgcGFzc2VkIGNvbnRleHQge0Bjb2RlIG1jfS4gSWYgdGhlCisgICAgICogcGFzc2VkIG1hdGggY29udGV4dCBzcGVjaWZpZXMgcHJlY2lzaW9uIHtAY29kZSAwfSwgdGhlbiB0aGlzIGNhbGwgaXMKKyAgICAgKiBlcXVpdmFsZW50IHRvIHtAY29kZSB0aGlzLmRpdmlkZShkaXZpc29yKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGl2aXNvcgorICAgICAqICAgICAgICAgICAgdmFsdWUgYnkgd2hpY2gge0Bjb2RlIHRoaXN9IGlzIGRpdmlkZWQuCisgICAgICogQHBhcmFtIG1jCisgICAgICogICAgICAgICAgICByb3VuZGluZyBtb2RlIGFuZCBwcmVjaXNpb24gZm9yIHRoZSByZXN1bHQgb2YgdGhpcyBvcGVyYXRpb24uCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpcyAvIGRpdmlzb3J9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGl2aXNvciA9PSBudWxsfSBvciB7QGNvZGUgbWMgPT0gbnVsbH0uCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGRpdmlzb3IgPT0gMH0uCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG1jLmdldFJvdW5kaW5nTW9kZSgpID09IFVOTkVDRVNTQVJZfSBhbmQgcm91bmRpbmcKKyAgICAgKiAgICAgICAgICAgICBpcyBuZWNlc3NhcnkgYWNjb3JkaW5nIHtAY29kZSBtYy5nZXRQcmVjaXNpb24oKX0uCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwgZGl2aWRlKEJpZ0RlY2ltYWwgZGl2aXNvciwgTWF0aENvbnRleHQgbWMpIHsKKyAgICAgICAgLyogQ2FsY3VsYXRpbmcgaG93IG1hbnkgemVyb3MgbXVzdCBiZSBhcHBlbmQgdG8gJ2RpdmlkZW5kJworICAgICAgICAgKiB0byBvYnRhaW4gYSAgcXVvdGllbnQgd2l0aCBhdCBsZWFzdCAnbWMucHJlY2lzaW9uKCknIGRpZ2l0cyAqLworICAgICAgICBsb25nIHRyYWlsaW5nWmVyb3MgPSBtYy5nZXRQcmVjaXNpb24oKSArIDJMCisgICAgICAgICAgICAgICAgKyBkaXZpc29yLmFwcHJveFByZWNpc2lvbigpIC0gYXBwcm94UHJlY2lzaW9uKCk7CisgICAgICAgIGxvbmcgZGlmZlNjYWxlID0gKGxvbmcpc2NhbGUgLSBkaXZpc29yLnNjYWxlOworICAgICAgICBsb25nIG5ld1NjYWxlID0gZGlmZlNjYWxlOyAvLyBzY2FsZSBvZiB0aGUgZmluYWwgcXVvdGllbnQKKyAgICAgICAgaW50IGNvbXBSZW07IC8vIHRvIGNvbXBhcmUgdGhlIHJlbWFpbmRlcgorICAgICAgICBpbnQgaSA9IDE7IC8vIGluZGV4CisgICAgICAgIGludCBsYXN0UG93ID0gVEVOX1BPVy5sZW5ndGggLSAxOyAvLyBsYXN0IHBvd2VyIG9mIHRlbgorICAgICAgICBCaWdJbnRlZ2VyIGludGVnZXJRdW90OyAvLyBmb3IgdGVtcG9yYWwgcmVzdWx0cworICAgICAgICBCaWdJbnRlZ2VyIHF1b3RBbmRSZW1bXSA9IHtnZXRVbnNjYWxlZFZhbHVlKCl9OworICAgICAgICAvLyBJbiBzcGVjaWFsIGNhc2VzIGl0IHJlZHVjZXMgdGhlIHByb2JsZW0gdG8gY2FsbCB0aGUgZHVhbCBtZXRob2QKKyAgICAgICAgaWYgKChtYy5nZXRQcmVjaXNpb24oKSA9PSAwKSB8fCAodGhpcy5pc1plcm8oKSkKKyAgICAgICAgfHwgKGRpdmlzb3IuaXNaZXJvKCkpKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpcy5kaXZpZGUoZGl2aXNvcik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRyYWlsaW5nWmVyb3MgPiAwKSB7CisgICAgICAgICAgICAvLyBUbyBhcHBlbmQgdHJhaWxpbmcgemVyb3MgYXQgZW5kIG9mIGRpdmlkZW5kCisgICAgICAgICAgICBxdW90QW5kUmVtWzBdID0gZ2V0VW5zY2FsZWRWYWx1ZSgpLm11bHRpcGx5KCBNdWx0aXBsaWNhdGlvbi5wb3dlck9mMTAodHJhaWxpbmdaZXJvcykgKTsKKyAgICAgICAgICAgIG5ld1NjYWxlICs9IHRyYWlsaW5nWmVyb3M7CisgICAgICAgIH0KKyAgICAgICAgcXVvdEFuZFJlbSA9IHF1b3RBbmRSZW1bMF0uZGl2aWRlQW5kUmVtYWluZGVyKCBkaXZpc29yLmdldFVuc2NhbGVkVmFsdWUoKSApOworICAgICAgICBpbnRlZ2VyUXVvdCA9IHF1b3RBbmRSZW1bMF07CisgICAgICAgIC8vIENhbGN1bGF0aW5nIHRoZSBleGFjdCBxdW90aWVudCB3aXRoIGF0IGxlYXN0ICdtYy5wcmVjaXNpb24oKScgZGlnaXRzCisgICAgICAgIGlmIChxdW90QW5kUmVtWzFdLnNpZ251bSgpICE9IDApIHsKKyAgICAgICAgICAgIC8vIENoZWNraW5nIGlmOiAgIDIgKiByZW1haW5kZXIgPj0gZGl2aXNvciA/CisgICAgICAgICAgICBjb21wUmVtID0gcXVvdEFuZFJlbVsxXS5zaGlmdExlZnRPbmVCaXQoKS5jb21wYXJlVG8oIGRpdmlzb3IuZ2V0VW5zY2FsZWRWYWx1ZSgpICk7CisgICAgICAgICAgICAvLyBxdW90IDo9IHF1b3QgKiAxMCArIHI7ICAgICB3aXRoICdyJyBpbiB7LTYsLTUsLTQsIDAsKzQsKzUsKzZ9CisgICAgICAgICAgICBpbnRlZ2VyUXVvdCA9IGludGVnZXJRdW90Lm11bHRpcGx5KEJpZ0ludGVnZXIuVEVOKQorICAgICAgICAgICAgLmFkZChCaWdJbnRlZ2VyLnZhbHVlT2YocXVvdEFuZFJlbVswXS5zaWdudW0oKSAqICg1ICsgY29tcFJlbSkpKTsKKyAgICAgICAgICAgIG5ld1NjYWxlKys7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBUbyBzdHJpcCB0cmFpbGluZyB6ZXJvcyB1bnRpbCB0aGUgcHJlZmVycmVkIHNjYWxlIGlzIHJlYWNoZWQKKyAgICAgICAgICAgIHdoaWxlICghaW50ZWdlclF1b3QudGVzdEJpdCgwKSkgeworICAgICAgICAgICAgICAgIHF1b3RBbmRSZW0gPSBpbnRlZ2VyUXVvdC5kaXZpZGVBbmRSZW1haW5kZXIoVEVOX1BPV1tpXSk7CisgICAgICAgICAgICAgICAgaWYgKChxdW90QW5kUmVtWzFdLnNpZ251bSgpID09IDApCisgICAgICAgICAgICAgICAgICAgICAgICAmJiAobmV3U2NhbGUgLSBpID49IGRpZmZTY2FsZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgbmV3U2NhbGUgLT0gaTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCBsYXN0UG93KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpKys7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaW50ZWdlclF1b3QgPSBxdW90QW5kUmVtWzBdOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChpID09IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGkgPSAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBUbyBwZXJmb3JtIHJvdW5kaW5nCisgICAgICAgIHJldHVybiBuZXcgQmlnRGVjaW1hbChpbnRlZ2VyUXVvdCwgc2FmZUxvbmdUb0ludChuZXdTY2FsZSksIG1jKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBCaWdEZWNpbWFsfSB3aG9zZSB2YWx1ZSBpcyB0aGUgaW50ZWdyYWwgcGFydCBvZgorICAgICAqIHtAY29kZSB0aGlzIC8gZGl2aXNvcn0uIFRoZSBxdW90aWVudCBpcyByb3VuZGVkIGRvd24gdG93YXJkcyB6ZXJvIHRvIHRoZQorICAgICAqIG5leHQgaW50ZWdlci4gRm9yIGV4YW1wbGUsIHtAY29kZSAwLjUvMC4yID0gMn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGl2aXNvcgorICAgICAqICAgICAgICAgICAgdmFsdWUgYnkgd2hpY2gge0Bjb2RlIHRoaXN9IGlzIGRpdmlkZWQuCisgICAgICogQHJldHVybiBpbnRlZ3JhbCBwYXJ0IG9mIHtAY29kZSB0aGlzIC8gZGl2aXNvcn0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkaXZpc29yID09IG51bGx9LgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkaXZpc29yID09IDB9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsIGRpdmlkZVRvSW50ZWdyYWxWYWx1ZShCaWdEZWNpbWFsIGRpdmlzb3IpIHsKKyAgICAgICAgQmlnSW50ZWdlciBpbnRlZ3JhbFZhbHVlOyAvLyB0aGUgaW50ZWdlciBvZiByZXN1bHQKKyAgICAgICAgQmlnSW50ZWdlciBwb3dlck9mVGVuOyAvLyBzb21lIHBvd2VyIG9mIHRlbgorICAgICAgICBCaWdJbnRlZ2VyIHF1b3RBbmRSZW1bXSA9IHtnZXRVbnNjYWxlZFZhbHVlKCl9OworICAgICAgICBsb25nIG5ld1NjYWxlID0gKGxvbmcpdGhpcy5zY2FsZSAtIGRpdmlzb3Iuc2NhbGU7CisgICAgICAgIGxvbmcgdGVtcFNjYWxlID0gMDsKKyAgICAgICAgaW50IGkgPSAxOworICAgICAgICBpbnQgbGFzdFBvdyA9IFRFTl9QT1cubGVuZ3RoIC0gMTsKKworICAgICAgICBpZiAoZGl2aXNvci5pc1plcm8oKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFyaXRobWV0aWNFeGNlcHRpb24oIkRpdmlzaW9uIGJ5IHplcm8iKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoKGRpdmlzb3IuYXBwcm94UHJlY2lzaW9uKCkgKyBuZXdTY2FsZSA+IHRoaXMuYXBwcm94UHJlY2lzaW9uKCkgKyAxTCkKKyAgICAgICAgfHwgKHRoaXMuaXNaZXJvKCkpKSB7CisgICAgICAgICAgICAvKiBJZiB0aGUgZGl2aXNvcidzIGludGVnZXIgcGFydCBpcyBncmVhdGVyIHRoYW4gdGhpcydzIGludGVnZXIgcGFydCwKKyAgICAgICAgICAgICAqIHRoZSByZXN1bHQgbXVzdCBiZSB6ZXJvIHdpdGggdGhlIGFwcHJvcHJpYXRlIHNjYWxlICovCisgICAgICAgICAgICBpbnRlZ3JhbFZhbHVlID0gQmlnSW50ZWdlci5aRVJPOworICAgICAgICB9IGVsc2UgaWYgKG5ld1NjYWxlID09IDApIHsKKyAgICAgICAgICAgIGludGVncmFsVmFsdWUgPSBnZXRVbnNjYWxlZFZhbHVlKCkuZGl2aWRlKCBkaXZpc29yLmdldFVuc2NhbGVkVmFsdWUoKSApOworICAgICAgICB9IGVsc2UgaWYgKG5ld1NjYWxlID4gMCkgeworICAgICAgICAgICAgcG93ZXJPZlRlbiA9IE11bHRpcGxpY2F0aW9uLnBvd2VyT2YxMChuZXdTY2FsZSk7CisgICAgICAgICAgICBpbnRlZ3JhbFZhbHVlID0gZ2V0VW5zY2FsZWRWYWx1ZSgpLmRpdmlkZSggZGl2aXNvci5nZXRVbnNjYWxlZFZhbHVlKCkubXVsdGlwbHkocG93ZXJPZlRlbikgKTsKKyAgICAgICAgICAgIGludGVncmFsVmFsdWUgPSBpbnRlZ3JhbFZhbHVlLm11bHRpcGx5KHBvd2VyT2ZUZW4pOworICAgICAgICB9IGVsc2Ugey8vIChuZXdTY2FsZSA8IDApCisgICAgICAgICAgICBwb3dlck9mVGVuID0gTXVsdGlwbGljYXRpb24ucG93ZXJPZjEwKC1uZXdTY2FsZSk7CisgICAgICAgICAgICBpbnRlZ3JhbFZhbHVlID0gZ2V0VW5zY2FsZWRWYWx1ZSgpLm11bHRpcGx5KHBvd2VyT2ZUZW4pLmRpdmlkZSggZGl2aXNvci5nZXRVbnNjYWxlZFZhbHVlKCkgKTsKKyAgICAgICAgICAgIC8vIFRvIHN0cmlwIHRyYWlsaW5nIHplcm9zIGFwcHJveGltYXRpbmcgdG8gdGhlIHByZWZlcnJlZCBzY2FsZQorICAgICAgICAgICAgd2hpbGUgKCFpbnRlZ3JhbFZhbHVlLnRlc3RCaXQoMCkpIHsKKyAgICAgICAgICAgICAgICBxdW90QW5kUmVtID0gaW50ZWdyYWxWYWx1ZS5kaXZpZGVBbmRSZW1haW5kZXIoVEVOX1BPV1tpXSk7CisgICAgICAgICAgICAgICAgaWYgKChxdW90QW5kUmVtWzFdLnNpZ251bSgpID09IDApCisgICAgICAgICAgICAgICAgICAgICAgICAmJiAodGVtcFNjYWxlIC0gaSA+PSBuZXdTY2FsZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGVtcFNjYWxlIC09IGk7CisgICAgICAgICAgICAgICAgICAgIGlmIChpIDwgbGFzdFBvdykgeworICAgICAgICAgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGludGVncmFsVmFsdWUgPSBxdW90QW5kUmVtWzBdOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChpID09IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGkgPSAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG5ld1NjYWxlID0gdGVtcFNjYWxlOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoKGludGVncmFsVmFsdWUuc2lnbnVtKCkgPT0gMCkKKyAgICAgICAgPyB6ZXJvU2NhbGVkQnkobmV3U2NhbGUpCisgICAgICAgICAgICAgICAgOiBuZXcgQmlnRGVjaW1hbChpbnRlZ3JhbFZhbHVlLCBzYWZlTG9uZ1RvSW50KG5ld1NjYWxlKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IHdob3NlIHZhbHVlIGlzIHRoZSBpbnRlZ3JhbCBwYXJ0IG9mCisgICAgICoge0Bjb2RlIHRoaXMgLyBkaXZpc29yfS4gVGhlIHF1b3RpZW50IGlzIHJvdW5kZWQgZG93biB0b3dhcmRzIHplcm8gdG8gdGhlCisgICAgICogbmV4dCBpbnRlZ2VyLiBUaGUgcm91bmRpbmcgbW9kZSBwYXNzZWQgd2l0aCB0aGUgcGFyYW1ldGVyIHtAY29kZSBtY30gaXMKKyAgICAgKiBub3QgY29uc2lkZXJlZC4gQnV0IGlmIHRoZSBwcmVjaXNpb24gb2Yge0Bjb2RlIG1jID4gMH0gYW5kIHRoZSBpbnRlZ3JhbAorICAgICAqIHBhcnQgcmVxdWlyZXMgbW9yZSBkaWdpdHMsIHRoZW4gYW4ge0Bjb2RlIEFyaXRobWV0aWNFeGNlcHRpb259IGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkaXZpc29yCisgICAgICogICAgICAgICAgICB2YWx1ZSBieSB3aGljaCB7QGNvZGUgdGhpc30gaXMgZGl2aWRlZC4KKyAgICAgKiBAcGFyYW0gbWMKKyAgICAgKiAgICAgICAgICAgIG1hdGggY29udGV4dCB3aGljaCBkZXRlcm1pbmVzIHRoZSBtYXhpbWFsIHByZWNpc2lvbiBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgIHJlc3VsdC4KKyAgICAgKiBAcmV0dXJuIGludGVncmFsIHBhcnQgb2Yge0Bjb2RlIHRoaXMgLyBkaXZpc29yfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGRpdmlzb3IgPT0gbnVsbH0gb3Ige0Bjb2RlIG1jID09IG51bGx9LgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkaXZpc29yID09IDB9LgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBtYy5nZXRQcmVjaXNpb24oKSA+IDB9IGFuZCB0aGUgcmVzdWx0IHJlcXVpcmVzIG1vcmUKKyAgICAgKiAgICAgICAgICAgICBkaWdpdHMgdG8gYmUgcmVwcmVzZW50ZWQuCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwgZGl2aWRlVG9JbnRlZ3JhbFZhbHVlKEJpZ0RlY2ltYWwgZGl2aXNvciwgTWF0aENvbnRleHQgbWMpIHsKKyAgICAgICAgaW50IG1jUHJlY2lzaW9uID0gbWMuZ2V0UHJlY2lzaW9uKCk7CisgICAgICAgIGludCBkaWZmUHJlY2lzaW9uID0gdGhpcy5wcmVjaXNpb24oKSAtIGRpdmlzb3IucHJlY2lzaW9uKCk7CisgICAgICAgIGludCBsYXN0UG93ID0gVEVOX1BPVy5sZW5ndGggLSAxOworICAgICAgICBsb25nIGRpZmZTY2FsZSA9IChsb25nKXRoaXMuc2NhbGUgLSBkaXZpc29yLnNjYWxlOworICAgICAgICBsb25nIG5ld1NjYWxlID0gZGlmZlNjYWxlOworICAgICAgICBsb25nIHF1b3RQcmVjaXNpb24gPSBkaWZmUHJlY2lzaW9uIC0gZGlmZlNjYWxlICsgMTsKKyAgICAgICAgQmlnSW50ZWdlciBxdW90QW5kUmVtW10gPSBuZXcgQmlnSW50ZWdlclsyXTsKKyAgICAgICAgLy8gSW4gc3BlY2lhbCBjYXNlcyBpdCBjYWxsIHRoZSBkdWFsIG1ldGhvZAorICAgICAgICBpZiAoKG1jUHJlY2lzaW9uID09IDApIHx8ICh0aGlzLmlzWmVybygpKSB8fCAoZGl2aXNvci5pc1plcm8oKSkpIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzLmRpdmlkZVRvSW50ZWdyYWxWYWx1ZShkaXZpc29yKTsKKyAgICAgICAgfQorICAgICAgICAvLyBMZXQgYmU6ICAgdGhpcyA9IFt1MSxzMV0gICBhbmQgICBkaXZpc29yID0gW3UyLHMyXQorICAgICAgICBpZiAocXVvdFByZWNpc2lvbiA8PSAwKSB7CisgICAgICAgICAgICBxdW90QW5kUmVtWzBdID0gQmlnSW50ZWdlci5aRVJPOworICAgICAgICB9IGVsc2UgaWYgKGRpZmZTY2FsZSA9PSAwKSB7CisgICAgICAgICAgICAvLyBDQVNFIHMxID09IHMyOiAgdG8gY2FsY3VsYXRlICAgdTEgLyB1MgorICAgICAgICAgICAgcXVvdEFuZFJlbVswXSA9IHRoaXMuZ2V0VW5zY2FsZWRWYWx1ZSgpLmRpdmlkZSggZGl2aXNvci5nZXRVbnNjYWxlZFZhbHVlKCkgKTsKKyAgICAgICAgfSBlbHNlIGlmIChkaWZmU2NhbGUgPiAwKSB7CisgICAgICAgICAgICAvLyBDQVNFIHMxID49IHMyOiAgdG8gY2FsY3VsYXRlICAgdTEgLyAodTIgKiAxMF4oczEtczIpCisgICAgICAgICAgICBxdW90QW5kUmVtWzBdID0gdGhpcy5nZXRVbnNjYWxlZFZhbHVlKCkuZGl2aWRlKAorICAgICAgICAgICAgICAgICAgICBkaXZpc29yLmdldFVuc2NhbGVkVmFsdWUoKS5tdWx0aXBseShNdWx0aXBsaWNhdGlvbi5wb3dlck9mMTAoZGlmZlNjYWxlKSkgKTsKKyAgICAgICAgICAgIC8vIFRvIGNob3NlICAxMF5uZXdTY2FsZSAgdG8gZ2V0IGEgcXVvdGllbnQgd2l0aCBhdCBsZWFzdCAnbWMucHJlY2lzaW9uKCknIGRpZ2l0cworICAgICAgICAgICAgbmV3U2NhbGUgPSBNYXRoLm1pbihkaWZmU2NhbGUsIE1hdGgubWF4KG1jUHJlY2lzaW9uIC0gcXVvdFByZWNpc2lvbiArIDEsIDApKTsKKyAgICAgICAgICAgIC8vIFRvIGNhbGN1bGF0ZTogKHUxIC8gKHUyICogMTBeKHMxLXMyKSkgKiAxMF5uZXdTY2FsZQorICAgICAgICAgICAgcXVvdEFuZFJlbVswXSA9IHF1b3RBbmRSZW1bMF0ubXVsdGlwbHkoTXVsdGlwbGljYXRpb24ucG93ZXJPZjEwKG5ld1NjYWxlKSk7CisgICAgICAgIH0gZWxzZSB7Ly8gQ0FTRSBzMiA+IHMxOgorICAgICAgICAgICAgLyogVG8gY2FsY3VsYXRlIHRoZSBtaW5pbXVtIHBvd2VyIG9mIHRlbiwgc3VjaCB0aGF0IHRoZSBxdW90aWVudAorICAgICAgICAgICAgICogICAodTEgKiAxMF5leHApIC8gdTIgICBoYXMgYXQgbGVhc3QgJ21jLnByZWNpc2lvbigpJyBkaWdpdHMuICovCisgICAgICAgICAgICBsb25nIGV4cCA9IE1hdGgubWluKC1kaWZmU2NhbGUsIE1hdGgubWF4KChsb25nKW1jUHJlY2lzaW9uIC0gZGlmZlByZWNpc2lvbiwgMCkpOworICAgICAgICAgICAgbG9uZyBjb21wUmVtRGl2OworICAgICAgICAgICAgLy8gTGV0IGJlOiAgICh1MSAqIDEwXmV4cCkgLyB1MiA9IFtxLHJdCisgICAgICAgICAgICBxdW90QW5kUmVtID0gdGhpcy5nZXRVbnNjYWxlZFZhbHVlKCkubXVsdGlwbHkoTXVsdGlwbGljYXRpb24ucG93ZXJPZjEwKGV4cCkpLgorICAgICAgICAgICAgICAgICAgICBkaXZpZGVBbmRSZW1haW5kZXIoZGl2aXNvci5nZXRVbnNjYWxlZFZhbHVlKCkpOworICAgICAgICAgICAgbmV3U2NhbGUgKz0gZXhwOyAvLyBUbyBmaXggdGhlIHNjYWxlCisgICAgICAgICAgICBleHAgPSAtbmV3U2NhbGU7IC8vIFRoZSByZW1haW5pbmcgcG93ZXIgb2YgdGVuCisgICAgICAgICAgICAvLyBJZiBhZnRlciBkaXZpc2lvbiB0aGVyZSBpcyBhIHJlbWFpbmRlci4uLgorICAgICAgICAgICAgaWYgKChxdW90QW5kUmVtWzFdLnNpZ251bSgpICE9IDApICYmIChleHAgPiAwKSkgeworICAgICAgICAgICAgICAgIC8vIExvZzEwKHIpICsgKChzMiAtIHMxKSAtIGV4cCkgPiBtYy5wcmVjaXNpb24gPworICAgICAgICAgICAgICAgIGNvbXBSZW1EaXYgPSAobmV3IEJpZ0RlY2ltYWwocXVvdEFuZFJlbVsxXSkpLnByZWNpc2lvbigpCisgICAgICAgICAgICAgICAgKyBleHAgLSBkaXZpc29yLnByZWNpc2lvbigpOworICAgICAgICAgICAgICAgIGlmIChjb21wUmVtRGl2ID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gVG8gY2FsY3VsYXRlOiAgKHIgKiAxMF5leHAyKSAvIHUyCisgICAgICAgICAgICAgICAgICAgIHF1b3RBbmRSZW1bMV0gPSBxdW90QW5kUmVtWzFdLm11bHRpcGx5KE11bHRpcGxpY2F0aW9uLnBvd2VyT2YxMChleHApKS4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXZpZGUoZGl2aXNvci5nZXRVbnNjYWxlZFZhbHVlKCkpOworICAgICAgICAgICAgICAgICAgICBjb21wUmVtRGl2ID0gTWF0aC5hYnMocXVvdEFuZFJlbVsxXS5zaWdudW0oKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChjb21wUmVtRGl2ID4gMCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXJpdGhtZXRpY0V4Y2VwdGlvbigiRGl2aXNpb24gaW1wb3NzaWJsZSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBGYXN0IHJldHVybiBpZiB0aGUgcXVvdGllbnQgaXMgemVybworICAgICAgICBpZiAocXVvdEFuZFJlbVswXS5zaWdudW0oKSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gemVyb1NjYWxlZEJ5KGRpZmZTY2FsZSk7CisgICAgICAgIH0KKyAgICAgICAgQmlnSW50ZWdlciBzdHJpcHBlZEJJID0gcXVvdEFuZFJlbVswXTsKKyAgICAgICAgQmlnRGVjaW1hbCBpbnRlZ3JhbFZhbHVlID0gbmV3IEJpZ0RlY2ltYWwocXVvdEFuZFJlbVswXSk7CisgICAgICAgIGxvbmcgcmVzdWx0UHJlY2lzaW9uID0gaW50ZWdyYWxWYWx1ZS5wcmVjaXNpb24oKTsKKyAgICAgICAgaW50IGkgPSAxOworICAgICAgICAvLyBUbyBzdHJpcCB0cmFpbGluZyB6ZXJvcyB1bnRpbCB0aGUgc3BlY2lmaWVkIHByZWNpc2lvbiBpcyByZWFjaGVkCisgICAgICAgIHdoaWxlICghc3RyaXBwZWRCSS50ZXN0Qml0KDApKSB7CisgICAgICAgICAgICBxdW90QW5kUmVtID0gc3RyaXBwZWRCSS5kaXZpZGVBbmRSZW1haW5kZXIoVEVOX1BPV1tpXSk7CisgICAgICAgICAgICBpZiAoKHF1b3RBbmRSZW1bMV0uc2lnbnVtKCkgPT0gMCkgJiYKKyAgICAgICAgICAgICAgICAgICAgKChyZXN1bHRQcmVjaXNpb24gLSBpID49IG1jUHJlY2lzaW9uKQorICAgICAgICAgICAgICAgICAgICB8fCAobmV3U2NhbGUgLSBpID49IGRpZmZTY2FsZSkpICkgeworICAgICAgICAgICAgICAgIHJlc3VsdFByZWNpc2lvbiAtPSBpOworICAgICAgICAgICAgICAgIG5ld1NjYWxlIC09IGk7CisgICAgICAgICAgICAgICAgaWYgKGkgPCBsYXN0UG93KSB7CisgICAgICAgICAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc3RyaXBwZWRCSSA9IHF1b3RBbmRSZW1bMF07CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmIChpID09IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGkgPSAxOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIFRvIGNoZWNrIGlmIHRoZSByZXN1bHQgZml0IGluICdtYy5wcmVjaXNpb24oKScgZGlnaXRzCisgICAgICAgIGlmIChyZXN1bHRQcmVjaXNpb24gPiBtY1ByZWNpc2lvbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFyaXRobWV0aWNFeGNlcHRpb24oIkRpdmlzaW9uIGltcG9zc2libGUiKTsKKyAgICAgICAgfQorICAgICAgICBpbnRlZ3JhbFZhbHVlLnNjYWxlID0gc2FmZUxvbmdUb0ludChuZXdTY2FsZSk7CisgICAgICAgIGludGVncmFsVmFsdWUuc2V0VW5zY2FsZWRWYWx1ZShzdHJpcHBlZEJJKTsKKyAgICAgICAgcmV0dXJuIGludGVncmFsVmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gd2hvc2UgdmFsdWUgaXMge0Bjb2RlIHRoaXMgJSBkaXZpc29yfS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcmVtYWluZGVyIGlzIGRlZmluZWQgYXMge0Bjb2RlIHRoaXMgLQorICAgICAqIHRoaXMuZGl2aWRlVG9JbnRlZ3JhbFZhbHVlKGRpdmlzb3IpICogZGl2aXNvcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGl2aXNvcgorICAgICAqICAgICAgICAgICAgdmFsdWUgYnkgd2hpY2gge0Bjb2RlIHRoaXN9IGlzIGRpdmlkZWQuCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpcyAlIGRpdmlzb3J9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGl2aXNvciA9PSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIEFyaXRobWV0aWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGl2aXNvciA9PSAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbCByZW1haW5kZXIoQmlnRGVjaW1hbCBkaXZpc29yKSB7CisgICAgICAgIHJldHVybiBkaXZpZGVBbmRSZW1haW5kZXIoZGl2aXNvcilbMV07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gd2hvc2UgdmFsdWUgaXMge0Bjb2RlIHRoaXMgJSBkaXZpc29yfS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcmVtYWluZGVyIGlzIGRlZmluZWQgYXMge0Bjb2RlIHRoaXMgLQorICAgICAqIHRoaXMuZGl2aWRlVG9JbnRlZ3JhbFZhbHVlKGRpdmlzb3IpICogZGl2aXNvcn0uCisgICAgICogPHA+CisgICAgICogVGhlIHNwZWNpZmllZCByb3VuZGluZyBtb2RlIHtAY29kZSBtY30gaXMgdXNlZCBmb3IgdGhlIGRpdmlzaW9uIG9ubHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGl2aXNvcgorICAgICAqICAgICAgICAgICAgdmFsdWUgYnkgd2hpY2gge0Bjb2RlIHRoaXN9IGlzIGRpdmlkZWQuCisgICAgICogQHBhcmFtIG1jCisgICAgICogICAgICAgICAgICByb3VuZGluZyBtb2RlIGFuZCBwcmVjaXNpb24gdG8gYmUgdXNlZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0aGlzICUgZGl2aXNvcn0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkaXZpc29yID09IG51bGx9LgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkaXZpc29yID09IDB9LgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBtYy5nZXRQcmVjaXNpb24oKSA+IDB9IGFuZCB0aGUgcmVzdWx0IG9mIHtAY29kZQorICAgICAqICAgICAgICAgICAgIHRoaXMuZGl2aWRlVG9JbnRlZ3JhbFZhbHVlKGRpdmlzb3IsIG1jKX0gcmVxdWlyZXMgbW9yZSBkaWdpdHMKKyAgICAgKiAgICAgICAgICAgICB0byBiZSByZXByZXNlbnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbCByZW1haW5kZXIoQmlnRGVjaW1hbCBkaXZpc29yLCBNYXRoQ29udGV4dCBtYykgeworICAgICAgICByZXR1cm4gZGl2aWRlQW5kUmVtYWluZGVyKGRpdmlzb3IsIG1jKVsxXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIEJpZ0RlY2ltYWx9IGFycmF5IHdoaWNoIGNvbnRhaW5zIHRoZSBpbnRlZ3JhbCBwYXJ0IG9mCisgICAgICoge0Bjb2RlIHRoaXMgLyBkaXZpc29yfSBhdCBpbmRleCAwIGFuZCB0aGUgcmVtYWluZGVyIHtAY29kZSB0aGlzICUKKyAgICAgKiBkaXZpc29yfSBhdCBpbmRleCAxLiBUaGUgcXVvdGllbnQgaXMgcm91bmRlZCBkb3duIHRvd2FyZHMgemVybyB0byB0aGUKKyAgICAgKiBuZXh0IGludGVnZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGl2aXNvcgorICAgICAqICAgICAgICAgICAgdmFsdWUgYnkgd2hpY2gge0Bjb2RlIHRoaXN9IGlzIGRpdmlkZWQuCisgICAgICogQHJldHVybiB7QGNvZGUgW3RoaXMuZGl2aWRlVG9JbnRlZ3JhbFZhbHVlKGRpdmlzb3IpLAorICAgICAqICAgICAgICAgdGhpcy5yZW1haW5kZXIoZGl2aXNvcildfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGRpdmlzb3IgPT0gbnVsbH0uCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGRpdmlzb3IgPT0gMH0uCisgICAgICogQHNlZSAjZGl2aWRlVG9JbnRlZ3JhbFZhbHVlCisgICAgICogQHNlZSAjcmVtYWluZGVyCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWxbXSBkaXZpZGVBbmRSZW1haW5kZXIoQmlnRGVjaW1hbCBkaXZpc29yKSB7CisgICAgICAgIEJpZ0RlY2ltYWwgcXVvdEFuZFJlbVtdID0gbmV3IEJpZ0RlY2ltYWxbMl07CisKKyAgICAgICAgcXVvdEFuZFJlbVswXSA9IHRoaXMuZGl2aWRlVG9JbnRlZ3JhbFZhbHVlKGRpdmlzb3IpOworICAgICAgICBxdW90QW5kUmVtWzFdID0gdGhpcy5zdWJ0cmFjdCggcXVvdEFuZFJlbVswXS5tdWx0aXBseShkaXZpc29yKSApOworICAgICAgICByZXR1cm4gcXVvdEFuZFJlbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIEJpZ0RlY2ltYWx9IGFycmF5IHdoaWNoIGNvbnRhaW5zIHRoZSBpbnRlZ3JhbCBwYXJ0IG9mCisgICAgICoge0Bjb2RlIHRoaXMgLyBkaXZpc29yfSBhdCBpbmRleCAwIGFuZCB0aGUgcmVtYWluZGVyIHtAY29kZSB0aGlzICUKKyAgICAgKiBkaXZpc29yfSBhdCBpbmRleCAxLiBUaGUgcXVvdGllbnQgaXMgcm91bmRlZCBkb3duIHRvd2FyZHMgemVybyB0byB0aGUKKyAgICAgKiBuZXh0IGludGVnZXIuIFRoZSByb3VuZGluZyBtb2RlIHBhc3NlZCB3aXRoIHRoZSBwYXJhbWV0ZXIge0Bjb2RlIG1jfSBpcworICAgICAqIG5vdCBjb25zaWRlcmVkLiBCdXQgaWYgdGhlIHByZWNpc2lvbiBvZiB7QGNvZGUgbWMgPiAwfSBhbmQgdGhlIGludGVncmFsCisgICAgICogcGFydCByZXF1aXJlcyBtb3JlIGRpZ2l0cywgdGhlbiBhbiB7QGNvZGUgQXJpdGhtZXRpY0V4Y2VwdGlvbn0gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHBhcmFtIGRpdmlzb3IKKyAgICAgKiAgICAgICAgICAgIHZhbHVlIGJ5IHdoaWNoIHtAY29kZSB0aGlzfSBpcyBkaXZpZGVkLgorICAgICAqIEBwYXJhbSBtYworICAgICAqICAgICAgICAgICAgbWF0aCBjb250ZXh0IHdoaWNoIGRldGVybWluZXMgdGhlIG1heGltYWwgcHJlY2lzaW9uIG9mIHRoZQorICAgICAqICAgICAgICAgICAgcmVzdWx0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIFt0aGlzLmRpdmlkZVRvSW50ZWdyYWxWYWx1ZShkaXZpc29yKSwKKyAgICAgKiAgICAgICAgIHRoaXMucmVtYWluZGVyKGRpdmlzb3IpXX0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkaXZpc29yID09IG51bGx9LgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkaXZpc29yID09IDB9LgorICAgICAqIEBzZWUgI2RpdmlkZVRvSW50ZWdyYWxWYWx1ZQorICAgICAqIEBzZWUgI3JlbWFpbmRlcgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsW10gZGl2aWRlQW5kUmVtYWluZGVyKEJpZ0RlY2ltYWwgZGl2aXNvciwgTWF0aENvbnRleHQgbWMpIHsKKyAgICAgICAgQmlnRGVjaW1hbCBxdW90QW5kUmVtW10gPSBuZXcgQmlnRGVjaW1hbFsyXTsKKworICAgICAgICBxdW90QW5kUmVtWzBdID0gdGhpcy5kaXZpZGVUb0ludGVncmFsVmFsdWUoZGl2aXNvciwgbWMpOworICAgICAgICBxdW90QW5kUmVtWzFdID0gdGhpcy5zdWJ0cmFjdCggcXVvdEFuZFJlbVswXS5tdWx0aXBseShkaXZpc29yKSApOworICAgICAgICByZXR1cm4gcXVvdEFuZFJlbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBCaWdEZWNpbWFsfSB3aG9zZSB2YWx1ZSBpcyB7QGNvZGUgdGhpcyBeIG59LiBUaGUKKyAgICAgKiBzY2FsZSBvZiB0aGUgcmVzdWx0IGlzIHtAY29kZSBufSB0aW1lcyB0aGUgc2NhbGVzIG9mIHtAY29kZSB0aGlzfS4KKyAgICAgKiA8cD4KKyAgICAgKiB7QGNvZGUgeC5wb3coMCl9IHJldHVybnMge0Bjb2RlIDF9LCBldmVuIGlmIHtAY29kZSB4ID09IDB9LgorICAgICAqIDxwPgorICAgICAqIEltcGxlbWVudGF0aW9uIE5vdGU6IFRoZSBpbXBsZW1lbnRhdGlvbiBpcyBiYXNlZCBvbiB0aGUgQU5TSSBzdGFuZGFyZAorICAgICAqIFgzLjI3NC0xOTk2IGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuCisgICAgICogICAgICAgICAgICBleHBvbmVudCB0byB3aGljaCB7QGNvZGUgdGhpc30gaXMgcmFpc2VkLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXMgXiBufS4KKyAgICAgKiBAdGhyb3dzIEFyaXRobWV0aWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbiA8IDB9IG9yIHtAY29kZSBuID4gOTk5OTk5OTk5fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbCBwb3coaW50IG4pIHsKKyAgICAgICAgaWYgKG4gPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIE9ORTsKKyAgICAgICAgfQorICAgICAgICBpZiAoKG4gPCAwKSB8fCAobiA+IDk5OTk5OTk5OSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBcml0aG1ldGljRXhjZXB0aW9uKCJJbnZhbGlkIG9wZXJhdGlvbiIpOworICAgICAgICB9CisgICAgICAgIGxvbmcgbmV3U2NhbGUgPSBzY2FsZSAqIChsb25nKW47CisgICAgICAgIC8vIExldCBiZTogdGhpcyA9IFt1LHNdICAgc286ICB0aGlzXm4gPSBbdV5uLCBzKm5dCisgICAgICAgIHJldHVybiBpc1plcm8oKSA/IHplcm9TY2FsZWRCeShuZXdTY2FsZSkKKyAgICAgICAgICAgICAgICA6IG5ldyBCaWdEZWNpbWFsKGdldFVuc2NhbGVkVmFsdWUoKS5wb3cobiksIHNhZmVMb25nVG9JbnQobmV3U2NhbGUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBCaWdEZWNpbWFsfSB3aG9zZSB2YWx1ZSBpcyB7QGNvZGUgdGhpcyBeIG59LiBUaGUKKyAgICAgKiByZXN1bHQgaXMgcm91bmRlZCBhY2NvcmRpbmcgdG8gdGhlIHBhc3NlZCBjb250ZXh0IHtAY29kZSBtY30uCisgICAgICogPHA+CisgICAgICogSW1wbGVtZW50YXRpb24gTm90ZTogVGhlIGltcGxlbWVudGF0aW9uIGlzIGJhc2VkIG9uIHRoZSBBTlNJIHN0YW5kYXJkCisgICAgICogWDMuMjc0LTE5OTYgYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHBhcmFtIG4KKyAgICAgKiAgICAgICAgICAgIGV4cG9uZW50IHRvIHdoaWNoIHtAY29kZSB0aGlzfSBpcyByYWlzZWQuCisgICAgICogQHBhcmFtIG1jCisgICAgICogICAgICAgICAgICByb3VuZGluZyBtb2RlIGFuZCBwcmVjaXNpb24gZm9yIHRoZSByZXN1bHQgb2YgdGhpcyBvcGVyYXRpb24uCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpcyBeIG59LgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBuIDwgMH0gb3Ige0Bjb2RlIG4gPiA5OTk5OTk5OTl9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsIHBvdyhpbnQgbiwgTWF0aENvbnRleHQgbWMpIHsKKyAgICAgICAgLy8gVGhlIEFOU0kgc3RhbmRhcmQgWDMuMjc0LTE5OTYgYWxnb3JpdGhtCisgICAgICAgIGludCBtID0gTWF0aC5hYnMobik7CisgICAgICAgIGludCBtY1ByZWNpc2lvbiA9IG1jLmdldFByZWNpc2lvbigpOworICAgICAgICBpbnQgZWxlbmd0aCA9IChpbnQpTWF0aC5sb2cxMChtKSArIDE7ICAgLy8gZGVjaW1hbCBkaWdpdHMgaW4gJ24nCisgICAgICAgIGludCBvbmVCaXRNYXNrOyAvLyBtYXNrIG9mIGJpdHMKKyAgICAgICAgQmlnRGVjaW1hbCBhY2N1bTsgLy8gdGhlIHNpbmdsZSBhY2N1bXVsYXRvcgorICAgICAgICBNYXRoQ29udGV4dCBuZXdQcmVjaXNpb24gPSBtYzsgLy8gTWF0aENvbnRleHQgYnkgZGVmYXVsdAorCisgICAgICAgIC8vIEluIHBhcnRpY3VsYXIgY2FzZXMsIGl0IHJlZHVjZXMgdGhlIHByb2JsZW0gdG8gY2FsbCB0aGUgb3RoZXIgJ3BvdygpJworICAgICAgICBpZiAoKG4gPT0gMCkgfHwgKChpc1plcm8oKSkgJiYgKG4gPiAwKSkpIHsKKyAgICAgICAgICAgIHJldHVybiBwb3cobik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChtID4gOTk5OTk5OTk5KSB8fCAoKG1jUHJlY2lzaW9uID09IDApICYmIChuIDwgMCkpCisgICAgICAgICAgICAgICAgfHwgKChtY1ByZWNpc2lvbiA+IDApICYmIChlbGVuZ3RoID4gbWNQcmVjaXNpb24pKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFyaXRobWV0aWNFeGNlcHRpb24oIkludmFsaWQgb3BlcmF0aW9uIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG1jUHJlY2lzaW9uID4gMCkgeworICAgICAgICAgICAgbmV3UHJlY2lzaW9uID0gbmV3IE1hdGhDb250ZXh0KCBtY1ByZWNpc2lvbiArIGVsZW5ndGggKyAxLAorICAgICAgICAgICAgICAgICAgICBtYy5nZXRSb3VuZGluZ01vZGUoKSk7CisgICAgICAgIH0KKyAgICAgICAgLy8gVGhlIHJlc3VsdCBpcyBjYWxjdWxhdGVkIGFzIGlmICduJyB3ZXJlIHBvc2l0aXZlCisgICAgICAgIGFjY3VtID0gcm91bmQobmV3UHJlY2lzaW9uKTsKKyAgICAgICAgb25lQml0TWFzayA9IEludGVnZXIuaGlnaGVzdE9uZUJpdChtKSA+PiAxOworCisgICAgICAgIHdoaWxlIChvbmVCaXRNYXNrID4gMCkgeworICAgICAgICAgICAgYWNjdW0gPSBhY2N1bS5tdWx0aXBseShhY2N1bSwgbmV3UHJlY2lzaW9uKTsKKyAgICAgICAgICAgIGlmICgobSAmIG9uZUJpdE1hc2spID09IG9uZUJpdE1hc2spIHsKKyAgICAgICAgICAgICAgICBhY2N1bSA9IGFjY3VtLm11bHRpcGx5KHRoaXMsIG5ld1ByZWNpc2lvbik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBvbmVCaXRNYXNrID4+PSAxOworICAgICAgICB9CisgICAgICAgIC8vIElmICduJyBpcyBuZWdhdGl2ZSwgdGhlIHZhbHVlIGlzIGRpdmlkZWQgaW50byAnT05FJworICAgICAgICBpZiAobiA8IDApIHsKKyAgICAgICAgICAgIGFjY3VtID0gT05FLmRpdmlkZShhY2N1bSwgbmV3UHJlY2lzaW9uKTsKKyAgICAgICAgfQorICAgICAgICAvLyBUaGUgZmluYWwgdmFsdWUgaXMgcm91bmRlZCB0byB0aGUgZGVzdGluYXRpb24gcHJlY2lzaW9uCisgICAgICAgIGFjY3VtLmlucGxhY2VSb3VuZChtYyk7CisgICAgICAgIHJldHVybiBhY2N1bTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBCaWdEZWNpbWFsfSB3aG9zZSB2YWx1ZSBpcyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YKKyAgICAgKiB7QGNvZGUgdGhpc30uIFRoZSBzY2FsZSBvZiB0aGUgcmVzdWx0IGlzIHRoZSBzYW1lIGFzIHRoZSBzY2FsZSBvZiB0aGlzLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgYWJzKHRoaXMpfQorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsIGFicygpIHsKKyAgICAgICAgcmV0dXJuICgoc2lnbnVtKCkgPCAwKSA/IG5lZ2F0ZSgpIDogdGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gd2hvc2UgdmFsdWUgaXMgdGhlIGFic29sdXRlIHZhbHVlIG9mCisgICAgICoge0Bjb2RlIHRoaXN9LiBUaGUgcmVzdWx0IGlzIHJvdW5kZWQgYWNjb3JkaW5nIHRvIHRoZSBwYXNzZWQgY29udGV4dAorICAgICAqIHtAY29kZSBtY30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWMKKyAgICAgKiAgICAgICAgICAgIHJvdW5kaW5nIG1vZGUgYW5kIHByZWNpc2lvbiBmb3IgdGhlIHJlc3VsdCBvZiB0aGlzIG9wZXJhdGlvbi4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSBhYnModGhpcyl9CisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwgYWJzKE1hdGhDb250ZXh0IG1jKSB7CisgICAgICAgIEJpZ0RlY2ltYWwgcmVzdWx0ID0gYWJzKCk7CisgICAgICAgIHJlc3VsdC5pbnBsYWNlUm91bmQobWMpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IHdob3NlIHZhbHVlIGlzIHRoZSB7QGNvZGUgLXRoaXN9LiBUaGUKKyAgICAgKiBzY2FsZSBvZiB0aGUgcmVzdWx0IGlzIHRoZSBzYW1lIGFzIHRoZSBzY2FsZSBvZiB0aGlzLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgLXRoaXN9CisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwgbmVnYXRlKCkgeworICAgICAgICBpZihiaXRMZW5ndGggPCA2MyB8fCAoYml0TGVuZ3RoID09IDYzICYmIHNtYWxsVmFsdWUhPUxvbmcuTUlOX1ZBTFVFKSkgeworICAgICAgICAgICAgcmV0dXJuIHZhbHVlT2YoLXNtYWxsVmFsdWUsc2NhbGUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgQmlnRGVjaW1hbChnZXRVbnNjYWxlZFZhbHVlKCkubmVnYXRlKCksIHNjYWxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBCaWdEZWNpbWFsfSB3aG9zZSB2YWx1ZSBpcyB0aGUge0Bjb2RlIC10aGlzfS4gVGhlCisgICAgICogcmVzdWx0IGlzIHJvdW5kZWQgYWNjb3JkaW5nIHRvIHRoZSBwYXNzZWQgY29udGV4dCB7QGNvZGUgbWN9LgorICAgICAqCisgICAgICogQHBhcmFtIG1jCisgICAgICogICAgICAgICAgICByb3VuZGluZyBtb2RlIGFuZCBwcmVjaXNpb24gZm9yIHRoZSByZXN1bHQgb2YgdGhpcyBvcGVyYXRpb24uCisgICAgICogQHJldHVybiB7QGNvZGUgLXRoaXN9CisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwgbmVnYXRlKE1hdGhDb250ZXh0IG1jKSB7CisgICAgICAgIEJpZ0RlY2ltYWwgcmVzdWx0ID0gbmVnYXRlKCk7CisgICAgICAgIHJlc3VsdC5pbnBsYWNlUm91bmQobWMpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IHdob3NlIHZhbHVlIGlzIHtAY29kZSArdGhpc30uIFRoZSBzY2FsZQorICAgICAqIG9mIHRoZSByZXN1bHQgaXMgdGhlIHNhbWUgYXMgdGhlIHNjYWxlIG9mIHRoaXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0aGlzfQorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsIHBsdXMoKSB7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IHdob3NlIHZhbHVlIGlzIHtAY29kZSArdGhpc30uIFRoZSByZXN1bHQKKyAgICAgKiBpcyByb3VuZGVkIGFjY29yZGluZyB0byB0aGUgcGFzc2VkIGNvbnRleHQge0Bjb2RlIG1jfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtYworICAgICAqICAgICAgICAgICAgcm91bmRpbmcgbW9kZSBhbmQgcHJlY2lzaW9uIGZvciB0aGUgcmVzdWx0IG9mIHRoaXMgb3BlcmF0aW9uLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXN9LCByb3VuZGVkCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwgcGx1cyhNYXRoQ29udGV4dCBtYykgeworICAgICAgICByZXR1cm4gcm91bmQobWMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNpZ24gb2YgdGhpcyB7QGNvZGUgQmlnRGVjaW1hbH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSAtMX0gaWYge0Bjb2RlIHRoaXMgPCAwfSwKKyAgICAgKiAgICAgICAgIHtAY29kZSAwfSBpZiB7QGNvZGUgdGhpcyA9PSAwfSwKKyAgICAgKiAgICAgICAgIHtAY29kZSAxfSBpZiB7QGNvZGUgdGhpcyA+IDB9LiAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNpZ251bSgpIHsKKyAgICAgICAgaWYoIGJpdExlbmd0aCA8IDY0KSB7CisgICAgICAgICAgICByZXR1cm4gTG9uZy5zaWdudW0oIHRoaXMuc21hbGxWYWx1ZSApOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRVbnNjYWxlZFZhbHVlKCkuc2lnbnVtKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGlzWmVybygpIHsKKyAgICAgICAgLy9XYXRjaCBvdXQ6IC0xIGhhcyBhIGJpdExlbmd0aD0wCisgICAgICAgIHJldHVybiBiaXRMZW5ndGggPT0gMCAmJiB0aGlzLnNtYWxsVmFsdWUgIT0gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2NhbGUgb2YgdGhpcyB7QGNvZGUgQmlnRGVjaW1hbH0uIFRoZSBzY2FsZSBpcyB0aGUgbnVtYmVyIG9mCisgICAgICogZGlnaXRzIGJlaGluZCB0aGUgZGVjaW1hbCBwb2ludC4gVGhlIHZhbHVlIG9mIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9IGlzCisgICAgICogdGhlIHVuc2lnbmVkVmFsdWUgKiAxMF4oLXNjYWxlKS4gSWYgdGhlIHNjYWxlIGlzIG5lZ2F0aXZlLCB0aGVuIHRoaXMKKyAgICAgKiB7QGNvZGUgQmlnRGVjaW1hbH0gcmVwcmVzZW50cyBhIGJpZyBpbnRlZ2VyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc2NhbGUgb2YgdGhpcyB7QGNvZGUgQmlnRGVjaW1hbH0uCisgICAgICovCisgICAgcHVibGljIGludCBzY2FsZSgpIHsKKyAgICAgICAgcmV0dXJuIHNjYWxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByZWNpc2lvbiBvZiB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfS4gVGhlIHByZWNpc2lvbiBpcyB0aGUKKyAgICAgKiBudW1iZXIgb2YgZGVjaW1hbCBkaWdpdHMgdXNlZCB0byByZXByZXNlbnQgdGhpcyBkZWNpbWFsLiBJdCBpcyBlcXVpdmFsZW50CisgICAgICogdG8gdGhlIG51bWJlciBvZiBkaWdpdHMgb2YgdGhlIHVuc2NhbGVkIHZhbHVlLiBUaGUgcHJlY2lzaW9uIG9mIHtAY29kZSAwfQorICAgICAqIGlzIHtAY29kZSAxfSAoaW5kZXBlbmRlbnQgb2YgdGhlIHNjYWxlKS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByZWNpc2lvbiBvZiB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHByZWNpc2lvbigpIHsKKyAgICAgICAgLy8gQ2hlY2tpbmcgaWYgdGhlIHByZWNpc2lvbiBhbHJlYWR5IHdhcyBjYWxjdWxhdGVkCisgICAgICAgIGlmIChwcmVjaXNpb24gPiAwKSB7CisgICAgICAgICAgICByZXR1cm4gcHJlY2lzaW9uOworICAgICAgICB9CisKKyAgICAgICAgaW50IGJpdExlbmd0aCA9IHRoaXMuYml0TGVuZ3RoOworCisgICAgICAgIGlmIChiaXRMZW5ndGggPT0gMCkgeworICAgICAgICAgICAgcHJlY2lzaW9uID0gMTsKKyAgICAgICAgfSBlbHNlIGlmIChiaXRMZW5ndGggPCA2NCkgeworICAgICAgICAgICAgcHJlY2lzaW9uID0gZGVjaW1hbERpZ2l0c0luTG9uZyhzbWFsbFZhbHVlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGludCBkZWNpbWFsRGlnaXRzID0gMSArIChpbnQpICgoYml0TGVuZ3RoIC0gMSkgKiBMT0cxMF8yKTsKKyAgICAgICAgICAgIC8vIElmIGFmdGVyIGRpdmlzaW9uIHRoZSBudW1iZXIgaXNuJ3QgemVybywgdGhlcmUgZXhpc3RzIGFuIGFkZGl0aW9uYWwgZGlnaXQKKyAgICAgICAgICAgIGlmIChnZXRVbnNjYWxlZFZhbHVlKCkuZGl2aWRlKE11bHRpcGxpY2F0aW9uLnBvd2VyT2YxMChkZWNpbWFsRGlnaXRzKSkuc2lnbnVtKCkgIT0gMCkgeworICAgICAgICAgICAgICAgIGRlY2ltYWxEaWdpdHMrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHByZWNpc2lvbiA9IGRlY2ltYWxEaWdpdHM7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHByZWNpc2lvbjsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBkZWNpbWFsRGlnaXRzSW5Mb25nKGxvbmcgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlID09IExvbmcuTUlOX1ZBTFVFKSB7CisgICAgICAgICAgICByZXR1cm4gMTk7IC8vIHNwZWNpYWwgY2FzZSByZXF1aXJlZCBiZWNhdXNlIGFicyhNSU5fVkFMVUUpID09IE1JTl9WQUxVRQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW50IGluZGV4ID0gQXJyYXlzLmJpbmFyeVNlYXJjaChNYXRoVXRpbHMuTE9OR19QT1dFUlNfT0ZfVEVOLCBNYXRoLmFicyh2YWx1ZSkpOworICAgICAgICAgICAgcmV0dXJuIChpbmRleCA8IDApID8gKC1pbmRleCAtIDEpIDogKGluZGV4ICsgMSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB1bnNjYWxlZCB2YWx1ZSAobWFudGlzc2EpIG9mIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlCisgICAgICogYXMgYSB7QGNvZGUgQmlnSW50ZWdlcn0uIFRoZSB1bnNjYWxlZCB2YWx1ZSBjYW4gYmUgY29tcHV0ZWQgYXMge0Bjb2RlCisgICAgICogdGhpc30gMTBeKHNjYWxlKS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdW5zY2FsZWQgdmFsdWUgKHRoaXMgKiAxMF4oc2NhbGUpKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciB1bnNjYWxlZFZhbHVlKCkgeworICAgICAgICByZXR1cm4gZ2V0VW5zY2FsZWRWYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IHdob3NlIHZhbHVlIGlzIHtAY29kZSB0aGlzfSwgcm91bmRlZAorICAgICAqIGFjY29yZGluZyB0byB0aGUgcGFzc2VkIGNvbnRleHQge0Bjb2RlIG1jfS4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB7QGNvZGUgbWMucHJlY2lzaW9uID0gMH0sIHRoZW4gbm8gcm91bmRpbmcgaXMgcGVyZm9ybWVkLgorICAgICAqIDxwPgorICAgICAqIElmIHtAY29kZSBtYy5wcmVjaXNpb24gPiAwfSBhbmQge0Bjb2RlIG1jLnJvdW5kaW5nTW9kZSA9PSBVTk5FQ0VTU0FSWX0sCisgICAgICogdGhlbiBhbiB7QGNvZGUgQXJpdGhtZXRpY0V4Y2VwdGlvbn0gaXMgdGhyb3duIGlmIHRoZSByZXN1bHQgY2Fubm90IGJlCisgICAgICogcmVwcmVzZW50ZWQgZXhhY3RseSB3aXRoaW4gdGhlIGdpdmVuIHByZWNpc2lvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtYworICAgICAqICAgICAgICAgICAgcm91bmRpbmcgbW9kZSBhbmQgcHJlY2lzaW9uIGZvciB0aGUgcmVzdWx0IG9mIHRoaXMgb3BlcmF0aW9uLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXN9IHJvdW5kZWQgYWNjb3JkaW5nIHRvIHRoZSBwYXNzZWQgY29udGV4dC4KKyAgICAgKiBAdGhyb3dzIEFyaXRobWV0aWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbWMucHJlY2lzaW9uID4gMH0gYW5kIHtAY29kZSBtYy5yb3VuZGluZ01vZGUgPT0KKyAgICAgKiAgICAgICAgICAgICBVTk5FQ0VTU0FSWX0gYW5kIHRoaXMgY2Fubm90IGJlIHJlcHJlc2VudGVkIHdpdGhpbiB0aGUgZ2l2ZW4KKyAgICAgKiAgICAgICAgICAgICBwcmVjaXNpb24uCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwgcm91bmQoTWF0aENvbnRleHQgbWMpIHsKKyAgICAgICAgQmlnRGVjaW1hbCB0aGlzQkQgPSBuZXcgQmlnRGVjaW1hbChnZXRVbnNjYWxlZFZhbHVlKCksIHNjYWxlKTsKKworICAgICAgICB0aGlzQkQuaW5wbGFjZVJvdW5kKG1jKTsKKyAgICAgICAgcmV0dXJuIHRoaXNCRDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBCaWdEZWNpbWFsfSBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgc2NhbGUuCisgICAgICogPHA+CisgICAgICogSWYgdGhlIG5ldyBzY2FsZSBpcyBncmVhdGVyIHRoYW4gdGhlIG9sZCBzY2FsZSwgdGhlbiBhZGRpdGlvbmFsIHplcm9zIGFyZQorICAgICAqIGFkZGVkIHRvIHRoZSB1bnNjYWxlZCB2YWx1ZS4gSW4gdGhpcyBjYXNlIG5vIHJvdW5kaW5nIGlzIG5lY2Vzc2FyeS4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgbmV3IHNjYWxlIGlzIHNtYWxsZXIgdGhhbiB0aGUgb2xkIHNjYWxlLCB0aGVuIHRyYWlsaW5nIGRpZ2l0cyBhcmUKKyAgICAgKiByZW1vdmVkLiBJZiB0aGVzZSB0cmFpbGluZyBkaWdpdHMgYXJlIG5vdCB6ZXJvLCB0aGVuIHRoZSByZW1haW5pbmcKKyAgICAgKiB1bnNjYWxlZCB2YWx1ZSBoYXMgdG8gYmUgcm91bmRlZC4gRm9yIHRoaXMgcm91bmRpbmcgb3BlcmF0aW9uIHRoZQorICAgICAqIHNwZWNpZmllZCByb3VuZGluZyBtb2RlIGlzIHVzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3U2NhbGUKKyAgICAgKiAgICAgICAgICAgIHNjYWxlIG9mIHRoZSByZXN1bHQgcmV0dXJuZWQuCisgICAgICogQHBhcmFtIHJvdW5kaW5nTW9kZQorICAgICAqICAgICAgICAgICAgcm91bmRpbmcgbW9kZSB0byBiZSB1c2VkIHRvIHJvdW5kIHRoZSByZXN1bHQuCisgICAgICogQHJldHVybiBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHNjYWxlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcm91bmRpbmdNb2RlID09IG51bGx9LgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSByb3VuZGluZ01vZGUgPT0gUk9VTkRfVU5ORUNFU1NBUll9IGFuZCByb3VuZGluZyBpcworICAgICAqICAgICAgICAgICAgIG5lY2Vzc2FyeSBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIHNjYWxlLgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsIHNldFNjYWxlKGludCBuZXdTY2FsZSwgUm91bmRpbmdNb2RlIHJvdW5kaW5nTW9kZSkgeworICAgICAgICBpZiAocm91bmRpbmdNb2RlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGxvbmcgZGlmZlNjYWxlID0gbmV3U2NhbGUgLSAobG9uZylzY2FsZTsKKyAgICAgICAgLy8gTGV0IGJlOiAgJ3RoaXMnID0gW3Usc10KKyAgICAgICAgaWYoZGlmZlNjYWxlID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICB9CisgICAgICAgIGlmKGRpZmZTY2FsZSA+IDApIHsKKyAgICAgICAgLy8gcmV0dXJuICBbdSAqIDEwXihzMiAtIHMpLCBuZXdTY2FsZV0KKyAgICAgICAgICAgIGlmKGRpZmZTY2FsZSA8IE1hdGhVdGlscy5MT05HX1BPV0VSU19PRl9URU4ubGVuZ3RoICYmCisgICAgICAgICAgICAgICAgICAgICh0aGlzLmJpdExlbmd0aCArIExPTkdfUE9XRVJTX09GX1RFTl9CSVRfTEVOR1RIWyhpbnQpZGlmZlNjYWxlXSkgPCA2NCApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVPZih0aGlzLnNtYWxsVmFsdWUqTWF0aFV0aWxzLkxPTkdfUE9XRVJTX09GX1RFTlsoaW50KWRpZmZTY2FsZV0sbmV3U2NhbGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBCaWdEZWNpbWFsKE11bHRpcGxpY2F0aW9uLm11bHRpcGx5QnlUZW5Qb3coZ2V0VW5zY2FsZWRWYWx1ZSgpLChpbnQpZGlmZlNjYWxlKSwgbmV3U2NhbGUpOworICAgICAgICB9CisgICAgICAgIC8vIGRpZmZTY2FsZSA8IDAKKyAgICAgICAgLy8gcmV0dXJuICBbdSxzXSAvIFsxLG5ld1NjYWxlXSAgd2l0aCB0aGUgYXBwcm9wcmlhdGUgc2NhbGUgYW5kIHJvdW5kaW5nCisgICAgICAgIGlmKHRoaXMuYml0TGVuZ3RoIDwgNjQgJiYgLWRpZmZTY2FsZSA8IE1hdGhVdGlscy5MT05HX1BPV0VSU19PRl9URU4ubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gZGl2aWRlUHJpbWl0aXZlTG9uZ3ModGhpcy5zbWFsbFZhbHVlLCBNYXRoVXRpbHMuTE9OR19QT1dFUlNfT0ZfVEVOWyhpbnQpLWRpZmZTY2FsZV0sIG5ld1NjYWxlLHJvdW5kaW5nTW9kZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRpdmlkZUJpZ0ludGVnZXJzKHRoaXMuZ2V0VW5zY2FsZWRWYWx1ZSgpLE11bHRpcGxpY2F0aW9uLnBvd2VyT2YxMCgtZGlmZlNjYWxlKSxuZXdTY2FsZSxyb3VuZGluZ01vZGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBzY2FsZS4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgbmV3IHNjYWxlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgb2xkIHNjYWxlLCB0aGVuIGFkZGl0aW9uYWwgemVyb3MgYXJlCisgICAgICogYWRkZWQgdG8gdGhlIHVuc2NhbGVkIHZhbHVlLiBJbiB0aGlzIGNhc2Ugbm8gcm91bmRpbmcgaXMgbmVjZXNzYXJ5LgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBuZXcgc2NhbGUgaXMgc21hbGxlciB0aGFuIHRoZSBvbGQgc2NhbGUsIHRoZW4gdHJhaWxpbmcgZGlnaXRzIGFyZQorICAgICAqIHJlbW92ZWQuIElmIHRoZXNlIHRyYWlsaW5nIGRpZ2l0cyBhcmUgbm90IHplcm8sIHRoZW4gdGhlIHJlbWFpbmluZworICAgICAqIHVuc2NhbGVkIHZhbHVlIGhhcyB0byBiZSByb3VuZGVkLiBGb3IgdGhpcyByb3VuZGluZyBvcGVyYXRpb24gdGhlCisgICAgICogc3BlY2lmaWVkIHJvdW5kaW5nIG1vZGUgaXMgdXNlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdTY2FsZQorICAgICAqICAgICAgICAgICAgc2NhbGUgb2YgdGhlIHJlc3VsdCByZXR1cm5lZC4KKyAgICAgKiBAcGFyYW0gcm91bmRpbmdNb2RlCisgICAgICogICAgICAgICAgICByb3VuZGluZyBtb2RlIHRvIGJlIHVzZWQgdG8gcm91bmQgdGhlIHJlc3VsdC4KKyAgICAgKiBAcmV0dXJuIGEgbmV3IHtAY29kZSBCaWdEZWNpbWFsfSBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgc2NhbGUuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcm91bmRpbmdNb2RlfSBpcyBub3QgYSB2YWxpZCByb3VuZGluZyBtb2RlLgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSByb3VuZGluZ01vZGUgPT0gUk9VTkRfVU5ORUNFU1NBUll9IGFuZCByb3VuZGluZyBpcworICAgICAqICAgICAgICAgICAgIG5lY2Vzc2FyeSBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIHNjYWxlLgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsIHNldFNjYWxlKGludCBuZXdTY2FsZSwgaW50IHJvdW5kaW5nTW9kZSkgeworICAgICAgICByZXR1cm4gc2V0U2NhbGUobmV3U2NhbGUsIFJvdW5kaW5nTW9kZS52YWx1ZU9mKHJvdW5kaW5nTW9kZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBzY2FsZS4gSWYKKyAgICAgKiB0aGUgbmV3IHNjYWxlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgb2xkIHNjYWxlLCB0aGVuIGFkZGl0aW9uYWwgemVyb3MgYXJlCisgICAgICogYWRkZWQgdG8gdGhlIHVuc2NhbGVkIHZhbHVlLiBJZiB0aGUgbmV3IHNjYWxlIGlzIHNtYWxsZXIgdGhhbiB0aGUgb2xkCisgICAgICogc2NhbGUsIHRoZW4gdHJhaWxpbmcgemVyb3MgYXJlIHJlbW92ZWQuIElmIHRoZSB0cmFpbGluZyBkaWdpdHMgYXJlIG5vdAorICAgICAqIHplcm9zIHRoZW4gYW4gQXJpdGhtZXRpY0V4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICogPHA+CisgICAgICogSWYgbm8gZXhjZXB0aW9uIGlzIHRocm93biwgdGhlbiB0aGUgZm9sbG93aW5nIGVxdWF0aW9uIGhvbGRzOiB7QGNvZGUKKyAgICAgKiB4LnNldFNjYWxlKHMpLmNvbXBhcmVUbyh4KSA9PSAwfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdTY2FsZQorICAgICAqICAgICAgICAgICAgc2NhbGUgb2YgdGhlIHJlc3VsdCByZXR1cm5lZC4KKyAgICAgKiBAcmV0dXJuIGEgbmV3IHtAY29kZSBCaWdEZWNpbWFsfSBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgc2NhbGUuCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgcm91bmRpbmcgd291bGQgYmUgbmVjZXNzYXJ5LgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsIHNldFNjYWxlKGludCBuZXdTY2FsZSkgeworICAgICAgICByZXR1cm4gc2V0U2NhbGUobmV3U2NhbGUsIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gaW5zdGFuY2Ugd2hlcmUgdGhlIGRlY2ltYWwgcG9pbnQgaGFzCisgICAgICogYmVlbiBtb3ZlZCB7QGNvZGUgbn0gcGxhY2VzIHRvIHRoZSBsZWZ0LiBJZiB7QGNvZGUgbiA8IDB9IHRoZW4gdGhlCisgICAgICogZGVjaW1hbCBwb2ludCBpcyBtb3ZlZCB7QGNvZGUgLW59IHBsYWNlcyB0byB0aGUgcmlnaHQuCisgICAgICogPHA+CisgICAgICogVGhlIHJlc3VsdCBpcyBvYnRhaW5lZCBieSBjaGFuZ2luZyBpdHMgc2NhbGUuIElmIHRoZSBzY2FsZSBvZiB0aGUgcmVzdWx0CisgICAgICogYmVjb21lcyBuZWdhdGl2ZSwgdGhlbiBpdHMgcHJlY2lzaW9uIGlzIGluY3JlYXNlZCBzdWNoIHRoYXQgdGhlIHNjYWxlIGlzCisgICAgICogemVyby4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlLCB0aGF0IHtAY29kZSBtb3ZlUG9pbnRMZWZ0KDApfSByZXR1cm5zIGEgcmVzdWx0IHdoaWNoIGlzCisgICAgICogbWF0aGVtYXRpY2FsbHkgZXF1aXZhbGVudCwgYnV0IHdoaWNoIGhhcyB7QGNvZGUgc2NhbGUgPj0gMH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbgorICAgICAqICAgICAgICAgICAgbnVtYmVyIG9mIHBsYWNlZCB0aGUgZGVjaW1hbCBwb2ludCBoYXMgdG8gYmUgbW92ZWQuCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpcyAqIDEwXigtbn0pLgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsIG1vdmVQb2ludExlZnQoaW50IG4pIHsKKyAgICAgICAgcmV0dXJuIG1vdmVQb2ludChzY2FsZSArIChsb25nKW4pOworICAgIH0KKworICAgIHByaXZhdGUgQmlnRGVjaW1hbCBtb3ZlUG9pbnQobG9uZyBuZXdTY2FsZSkgeworICAgICAgICBpZiAoaXNaZXJvKCkpIHsKKyAgICAgICAgICAgIHJldHVybiB6ZXJvU2NhbGVkQnkoTWF0aC5tYXgobmV3U2NhbGUsIDApKTsKKyAgICAgICAgfQorICAgICAgICAvKgorICAgICAgICAgKiBXaGVuOiAnbic9PSBJbnRlZ2VyLk1JTl9WQUxVRSBpc24ndCBwb3NzaWJsZSB0byBjYWxsIHRvCisgICAgICAgICAqIG1vdmVQb2ludFJpZ2h0KC1uKSBzaW5jZSAtSW50ZWdlci5NSU5fVkFMVUUgPT0gSW50ZWdlci5NSU5fVkFMVUUKKyAgICAgICAgICovCisgICAgICAgIGlmKG5ld1NjYWxlID49IDApIHsKKyAgICAgICAgICAgIGlmKGJpdExlbmd0aCA8IDY0KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlT2Yoc21hbGxWYWx1ZSwgc2FmZUxvbmdUb0ludChuZXdTY2FsZSkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBCaWdEZWNpbWFsKGdldFVuc2NhbGVkVmFsdWUoKSwgc2FmZUxvbmdUb0ludChuZXdTY2FsZSkpOworICAgICAgICB9CisgICAgICAgIGlmKC1uZXdTY2FsZSA8IE1hdGhVdGlscy5MT05HX1BPV0VSU19PRl9URU4ubGVuZ3RoICYmCisgICAgICAgICAgICAgICAgYml0TGVuZ3RoICsgTE9OR19QT1dFUlNfT0ZfVEVOX0JJVF9MRU5HVEhbKGludCktbmV3U2NhbGVdIDwgNjQgKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsdWVPZihzbWFsbFZhbHVlKk1hdGhVdGlscy5MT05HX1BPV0VSU19PRl9URU5bKGludCktbmV3U2NhbGVdLDApOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgQmlnRGVjaW1hbChNdWx0aXBsaWNhdGlvbi5tdWx0aXBseUJ5VGVuUG93KAorICAgICAgICAgICAgICAgIGdldFVuc2NhbGVkVmFsdWUoKSwgc2FmZUxvbmdUb0ludCgtbmV3U2NhbGUpKSwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQmlnRGVjaW1hbH0gaW5zdGFuY2Ugd2hlcmUgdGhlIGRlY2ltYWwgcG9pbnQgaGFzCisgICAgICogYmVlbiBtb3ZlZCB7QGNvZGUgbn0gcGxhY2VzIHRvIHRoZSByaWdodC4gSWYge0Bjb2RlIG4gPCAwfSB0aGVuIHRoZQorICAgICAqIGRlY2ltYWwgcG9pbnQgaXMgbW92ZWQge0Bjb2RlIC1ufSBwbGFjZXMgdG8gdGhlIGxlZnQuCisgICAgICogPHA+CisgICAgICogVGhlIHJlc3VsdCBpcyBvYnRhaW5lZCBieSBjaGFuZ2luZyBpdHMgc2NhbGUuIElmIHRoZSBzY2FsZSBvZiB0aGUgcmVzdWx0CisgICAgICogYmVjb21lcyBuZWdhdGl2ZSwgdGhlbiBpdHMgcHJlY2lzaW9uIGlzIGluY3JlYXNlZCBzdWNoIHRoYXQgdGhlIHNjYWxlIGlzCisgICAgICogemVyby4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlLCB0aGF0IHtAY29kZSBtb3ZlUG9pbnRSaWdodCgwKX0gcmV0dXJucyBhIHJlc3VsdCB3aGljaCBpcworICAgICAqIG1hdGhlbWF0aWNhbGx5IGVxdWl2YWxlbnQsIGJ1dCB3aGljaCBoYXMgc2NhbGUgPj0gMC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuCisgICAgICogICAgICAgICAgICBudW1iZXIgb2YgcGxhY2VkIHRoZSBkZWNpbWFsIHBvaW50IGhhcyB0byBiZSBtb3ZlZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0aGlzICogMTBebn0uCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwgbW92ZVBvaW50UmlnaHQoaW50IG4pIHsKKyAgICAgICAgcmV0dXJuIG1vdmVQb2ludChzY2FsZSAtIChsb25nKW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IHdob3NlIHZhbHVlIGlzIHtAY29kZSB0aGlzfSAxMF57QGNvZGUgbn0uCisgICAgICogVGhlIHNjYWxlIG9mIHRoZSByZXN1bHQgaXMge0Bjb2RlIHRoaXMuc2NhbGUoKX0gLSB7QGNvZGUgbn0uCisgICAgICogVGhlIHByZWNpc2lvbiBvZiB0aGUgcmVzdWx0IGlzIHRoZSBwcmVjaXNpb24gb2Yge0Bjb2RlIHRoaXN9LgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMge0BsaW5rICNtb3ZlUG9pbnRSaWdodH0sIGV4Y2VwdCB0aGF0CisgICAgICogdGhlIHByZWNpc2lvbiBpcyBub3QgY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuCisgICAgICogICAgICAgICAgICBudW1iZXIgb2YgcGxhY2VzIHRoZSBkZWNpbWFsIHBvaW50IGhhcyB0byBiZSBtb3ZlZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0aGlzICogMTBebn0KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbCBzY2FsZUJ5UG93ZXJPZlRlbihpbnQgbikgeworICAgICAgICBsb25nIG5ld1NjYWxlID0gc2NhbGUgLSAobG9uZyluOworICAgICAgICBpZihiaXRMZW5ndGggPCA2NCkgeworICAgICAgICAgICAgLy9UYWtpbmcgY2FyZSB3aGVuIGEgMCBpcyB0byBiZSBzY2FsZWQKKyAgICAgICAgICAgIGlmKCBzbWFsbFZhbHVlPT0wICApeworICAgICAgICAgICAgICAgIHJldHVybiB6ZXJvU2NhbGVkQnkoIG5ld1NjYWxlICk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdmFsdWVPZihzbWFsbFZhbHVlLCBzYWZlTG9uZ1RvSW50KG5ld1NjYWxlKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBCaWdEZWNpbWFsKGdldFVuc2NhbGVkVmFsdWUoKSwgc2FmZUxvbmdUb0ludChuZXdTY2FsZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlIHdpdGggdGhlIHNhbWUgdmFsdWUgYXMge0Bjb2RlCisgICAgICogdGhpc30gYnV0IHdpdGggYSB1bnNjYWxlZCB2YWx1ZSB3aGVyZSB0aGUgdHJhaWxpbmcgemVyb3MgaGF2ZSBiZWVuCisgICAgICogcmVtb3ZlZC4gSWYgdGhlIHVuc2NhbGVkIHZhbHVlIG9mIHtAY29kZSB0aGlzfSBoYXMgbiB0cmFpbGluZyB6ZXJvcywgdGhlbgorICAgICAqIHRoZSBzY2FsZSBhbmQgdGhlIHByZWNpc2lvbiBvZiB0aGUgcmVzdWx0IGhhcyBiZWVuIHJlZHVjZWQgYnkgbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBuZXcge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlIGVxdWl2YWxlbnQgdG8gdGhpcyB3aGVyZSB0aGUKKyAgICAgKiAgICAgICAgIHRyYWlsaW5nIHplcm9zIG9mIHRoZSB1bnNjYWxlZCB2YWx1ZSBoYXZlIGJlZW4gcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbCBzdHJpcFRyYWlsaW5nWmVyb3MoKSB7CisgICAgICAgIGludCBpID0gMTsgLy8gMSA8PSBpIDw9IDE4CisgICAgICAgIGludCBsYXN0UG93ID0gVEVOX1BPVy5sZW5ndGggLSAxOworICAgICAgICBsb25nIG5ld1NjYWxlID0gc2NhbGU7CisKKyAgICAgICAgaWYgKGlzWmVybygpKSB7CisgICAgICAgICAgICAvLyBQcmVzZXJ2ZSBSSSBjb21wYXRpYmlsaXR5LCBzbyBCaWdEZWNpbWFsLmVxdWFscyAod2hpY2ggY2hlY2tzCisgICAgICAgICAgICAvLyB2YWx1ZSAqYW5kKiBzY2FsZSkgY29udGludWVzIHRvIHdvcmsuCisgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgfQorICAgICAgICBCaWdJbnRlZ2VyIHN0cmlwcGVkQkkgPSBnZXRVbnNjYWxlZFZhbHVlKCk7CisgICAgICAgIEJpZ0ludGVnZXJbXSBxdW90QW5kUmVtOworCisgICAgICAgIC8vIHdoaWxlIHRoZSBudW1iZXIgaXMgZXZlbi4uLgorICAgICAgICB3aGlsZSAoIXN0cmlwcGVkQkkudGVzdEJpdCgwKSkgeworICAgICAgICAgICAgLy8gVG8gZGl2aWRlIGJ5IDEwXmkKKyAgICAgICAgICAgIHF1b3RBbmRSZW0gPSBzdHJpcHBlZEJJLmRpdmlkZUFuZFJlbWFpbmRlcihURU5fUE9XW2ldKTsKKyAgICAgICAgICAgIC8vIFRvIGxvb2sgdGhlIHJlbWFpbmRlcgorICAgICAgICAgICAgaWYgKHF1b3RBbmRSZW1bMV0uc2lnbnVtKCkgPT0gMCkgeworICAgICAgICAgICAgICAgIC8vIFRvIGFkanVzdCB0aGUgc2NhbGUKKyAgICAgICAgICAgICAgICBuZXdTY2FsZSAtPSBpOworICAgICAgICAgICAgICAgIGlmIChpIDwgbGFzdFBvdykgeworICAgICAgICAgICAgICAgICAgICAvLyBUbyBzZXQgdG8gdGhlIG5leHQgcG93ZXIKKyAgICAgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzdHJpcHBlZEJJID0gcXVvdEFuZFJlbVswXTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKGkgPT0gMSkgeworICAgICAgICAgICAgICAgICAgICAvLyAndGhpcycgaGFzIG5vIG1vcmUgdHJhaWxpbmcgemVyb3MKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIFRvIHNldCB0byB0aGUgc21hbGxlc3QgcG93ZXIgb2YgdGVuCisgICAgICAgICAgICAgICAgaSA9IDE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBCaWdEZWNpbWFsKHN0cmlwcGVkQkksIHNhZmVMb25nVG9JbnQobmV3U2NhbGUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfSB3aXRoIHtAY29kZSB2YWx9LiBSZXR1cm5zIG9uZSBvZiB0aGUKKyAgICAgKiB0aHJlZSB2YWx1ZXMge0Bjb2RlIDF9LCB7QGNvZGUgMH0sIG9yIHtAY29kZSAtMX0uIFRoZSBtZXRob2QgYmVoYXZlcyBhcworICAgICAqIGlmIHtAY29kZSB0aGlzLnN1YnRyYWN0KHZhbCl9IGlzIGNvbXB1dGVkLiBJZiB0aGlzIGRpZmZlcmVuY2UgaXMgPiAwIHRoZW4KKyAgICAgKiAxIGlzIHJldHVybmVkLCBpZiB0aGUgZGlmZmVyZW5jZSBpcyA8IDAgdGhlbiAtMSBpcyByZXR1cm5lZCwgYW5kIGlmIHRoZQorICAgICAqIGRpZmZlcmVuY2UgaXMgMCB0aGVuIDAgaXMgcmV0dXJuZWQuIFRoaXMgbWVhbnMsIHRoYXQgaWYgdHdvIGRlY2ltYWwKKyAgICAgKiBpbnN0YW5jZXMgYXJlIGNvbXBhcmVkIHdoaWNoIGFyZSBlcXVhbCBpbiB2YWx1ZSBidXQgZGlmZmVyIGluIHNjYWxlLCB0aGVuCisgICAgICogdGhlc2UgdHdvIGluc3RhbmNlcyBhcmUgY29uc2lkZXJlZCBhcyBlcXVhbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHZhbHVlIHRvIGJlIGNvbXBhcmVkIHdpdGgge0Bjb2RlIHRoaXN9LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIDF9IGlmIHtAY29kZSB0aGlzID4gdmFsfSwge0Bjb2RlIC0xfSBpZiB7QGNvZGUgdGhpcyA8IHZhbH0sCisgICAgICogICAgICAgICB7QGNvZGUgMH0gaWYge0Bjb2RlIHRoaXMgPT0gdmFsfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHZhbCA9PSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhCaWdEZWNpbWFsIHZhbCkgeworICAgICAgICBpbnQgdGhpc1NpZ24gPSBzaWdudW0oKTsKKyAgICAgICAgaW50IHZhbHVlU2lnbiA9IHZhbC5zaWdudW0oKTsKKworICAgICAgICBpZiggdGhpc1NpZ24gPT0gdmFsdWVTaWduKSB7CisgICAgICAgICAgICBpZih0aGlzLnNjYWxlID09IHZhbC5zY2FsZSAmJiB0aGlzLmJpdExlbmd0aDw2NCAmJiB2YWwuYml0TGVuZ3RoPDY0ICkgeworICAgICAgICAgICAgICAgIHJldHVybiAoc21hbGxWYWx1ZSA8IHZhbC5zbWFsbFZhbHVlKSA/IC0xIDogKHNtYWxsVmFsdWUgPiB2YWwuc21hbGxWYWx1ZSkgPyAxIDogMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGxvbmcgZGlmZlNjYWxlID0gKGxvbmcpdGhpcy5zY2FsZSAtIHZhbC5zY2FsZTsKKyAgICAgICAgICAgIGludCBkaWZmUHJlY2lzaW9uID0gdGhpcy5hcHByb3hQcmVjaXNpb24oKSAtIHZhbC5hcHByb3hQcmVjaXNpb24oKTsKKyAgICAgICAgICAgIGlmIChkaWZmUHJlY2lzaW9uID4gZGlmZlNjYWxlICsgMSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0aGlzU2lnbjsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZGlmZlByZWNpc2lvbiA8IGRpZmZTY2FsZSAtIDEpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLXRoaXNTaWduOworICAgICAgICAgICAgfSBlbHNlIHsvLyB0aGlzU2lnbiA9PSB2YWwuc2lnbnVtKCkgIGFuZCAgZGlmZlByZWNpc2lvbiBpcyBhcHJveC4gZGlmZlNjYWxlCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlciB0aGlzVW5zY2FsZWQgPSB0aGlzLmdldFVuc2NhbGVkVmFsdWUoKTsKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHZhbFVuc2NhbGVkID0gdmFsLmdldFVuc2NhbGVkVmFsdWUoKTsKKyAgICAgICAgICAgICAgICAvLyBJZiBhbnkgb2YgYm90aCBwcmVjaXNpb24gaXMgYmlnZ2VyLCBhcHBlbmQgemVyb3MgdG8gdGhlIHNob3J0ZXIgb25lCisgICAgICAgICAgICAgICAgaWYgKGRpZmZTY2FsZSA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpc1Vuc2NhbGVkID0gdGhpc1Vuc2NhbGVkLm11bHRpcGx5KE11bHRpcGxpY2F0aW9uLnBvd2VyT2YxMCgtZGlmZlNjYWxlKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkaWZmU2NhbGUgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIHZhbFVuc2NhbGVkID0gdmFsVW5zY2FsZWQubXVsdGlwbHkoTXVsdGlwbGljYXRpb24ucG93ZXJPZjEwKGRpZmZTY2FsZSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gdGhpc1Vuc2NhbGVkLmNvbXBhcmVUbyh2YWxVbnNjYWxlZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAodGhpc1NpZ24gPCB2YWx1ZVNpZ24pIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfSBlbHNlICB7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHtAY29kZSB4fSBpcyBhIHtAY29kZSBCaWdEZWNpbWFsfSBpbnN0YW5jZSBhbmQgaWYKKyAgICAgKiB0aGlzIGluc3RhbmNlIGlzIGVxdWFsIHRvIHRoaXMgYmlnIGRlY2ltYWwuIFR3byBiaWcgZGVjaW1hbHMgYXJlIGVxdWFsIGlmCisgICAgICogdGhlaXIgdW5zY2FsZWQgdmFsdWUgYW5kIHRoZWlyIHNjYWxlIGlzIGVxdWFsLiBGb3IgZXhhbXBsZSwgMS4wCisgICAgICogKDEwKjEwXigtMSkpIGlzIG5vdCBlcXVhbCB0byAxLjAwICgxMDAqMTBeKC0yKSkuIFNpbWlsYXJseSwgemVybworICAgICAqIGluc3RhbmNlcyBhcmUgbm90IGVxdWFsIGlmIHRoZWlyIHNjYWxlIGRpZmZlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgb2JqZWN0IHRvIGJlIGNvbXBhcmVkIHdpdGgge0Bjb2RlIHRoaXN9LgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB7QGNvZGUgeH0gaXMgYSB7QGNvZGUgQmlnRGVjaW1hbH0gYW5kIHtAY29kZSB0aGlzID09IHh9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgeCkgeworICAgICAgICBpZiAodGhpcyA9PSB4KSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoeCBpbnN0YW5jZW9mIEJpZ0RlY2ltYWwpIHsKKyAgICAgICAgICAgIEJpZ0RlY2ltYWwgeDEgPSAoQmlnRGVjaW1hbCkgeDsKKyAgICAgICAgICAgIHJldHVybiB4MS5zY2FsZSA9PSBzY2FsZQorICAgICAgICAgICAgICAgICAgICYmIChiaXRMZW5ndGggPCA2NCA/ICh4MS5zbWFsbFZhbHVlID09IHNtYWxsVmFsdWUpCisgICAgICAgICAgICAgICAgICAgIDogaW50VmFsLmVxdWFscyh4MS5pbnRWYWwpKTsKKworCisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1pbmltdW0gb2YgdGhpcyB7QGNvZGUgQmlnRGVjaW1hbH0gYW5kIHtAY29kZSB2YWx9LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdmFsdWUgdG8gYmUgdXNlZCB0byBjb21wdXRlIHRoZSBtaW5pbXVtIHdpdGggdGhpcy4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSBtaW4odGhpcywgdmFsfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHZhbCA9PSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbCBtaW4oQmlnRGVjaW1hbCB2YWwpIHsKKyAgICAgICAgcmV0dXJuICgoY29tcGFyZVRvKHZhbCkgPD0gMCkgPyB0aGlzIDogdmFsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIG9mIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9IGFuZCB7QGNvZGUgdmFsfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHZhbHVlIHRvIGJlIHVzZWQgdG8gY29tcHV0ZSB0aGUgbWF4aW11bSB3aXRoIHRoaXMuCisgICAgICogQHJldHVybiB7QGNvZGUgbWF4KHRoaXMsIHZhbH0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSB2YWwgPT0gbnVsbH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0RlY2ltYWwgbWF4KEJpZ0RlY2ltYWwgdmFsKSB7CisgICAgICAgIHJldHVybiAoKGNvbXBhcmVUbyh2YWwpID49IDApID8gdGhpcyA6IHZhbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGhhc2ggY29kZSBmb3IgdGhpcyB7QGNvZGUgQmlnRGVjaW1hbH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGhhc2ggY29kZSBmb3Ige0Bjb2RlIHRoaXN9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGlmIChoYXNoQ29kZSAhPSAwKSB7CisgICAgICAgICAgICByZXR1cm4gaGFzaENvZGU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJpdExlbmd0aCA8IDY0KSB7CisgICAgICAgICAgICBoYXNoQ29kZSA9IChpbnQpKHNtYWxsVmFsdWUgJiAweGZmZmZmZmZmKTsKKyAgICAgICAgICAgIGhhc2hDb2RlID0gMzMgKiBoYXNoQ29kZSArICAoaW50KSgoc21hbGxWYWx1ZSA+PiAzMikgJiAweGZmZmZmZmZmKTsKKyAgICAgICAgICAgIGhhc2hDb2RlID0gMTcgKiBoYXNoQ29kZSArIHNjYWxlOworICAgICAgICAgICAgcmV0dXJuIGhhc2hDb2RlOworICAgICAgICB9CisgICAgICAgIGhhc2hDb2RlID0gMTcgKiBpbnRWYWwuaGFzaENvZGUoKSArIHNjYWxlOworICAgICAgICByZXR1cm4gaGFzaENvZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNhbm9uaWNhbCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgQmlnRGVjaW1hbH0uIElmCisgICAgICogbmVjZXNzYXJ5LCBzY2llbnRpZmljIG5vdGF0aW9uIGlzIHVzZWQuIFRoaXMgcmVwcmVzZW50YXRpb24gYWx3YXlzIHByaW50cworICAgICAqIGFsbCBzaWduaWZpY2FudCBkaWdpdHMgb2YgdGhpcyB2YWx1ZS4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgc2NhbGUgaXMgbmVnYXRpdmUgb3IgaWYge0Bjb2RlIHNjYWxlIC0gcHJlY2lzaW9uID49IDZ9IHRoZW4KKyAgICAgKiBzY2llbnRpZmljIG5vdGF0aW9uIGlzIHVzZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHtAY29kZSB0aGlzfSBpbiBzY2llbnRpZmljIG5vdGF0aW9uIGlmCisgICAgICogICAgICAgICBuZWNlc3NhcnkuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgaWYgKHRvU3RyaW5nSW1hZ2UgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHRvU3RyaW5nSW1hZ2U7CisgICAgICAgIH0KKyAgICAgICAgaWYoYml0TGVuZ3RoIDwgMzIpIHsKKyAgICAgICAgICAgIHRvU3RyaW5nSW1hZ2UgPSBDb252ZXJzaW9uLnRvRGVjaW1hbFNjYWxlZFN0cmluZyhzbWFsbFZhbHVlLHNjYWxlKTsKKyAgICAgICAgICAgIHJldHVybiB0b1N0cmluZ0ltYWdlOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBpbnRTdHJpbmcgPSBnZXRVbnNjYWxlZFZhbHVlKCkudG9TdHJpbmcoKTsKKyAgICAgICAgaWYgKHNjYWxlID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBpbnRTdHJpbmc7CisgICAgICAgIH0KKyAgICAgICAgaW50IGJlZ2luID0gKGdldFVuc2NhbGVkVmFsdWUoKS5zaWdudW0oKSA8IDApID8gMiA6IDE7CisgICAgICAgIGludCBlbmQgPSBpbnRTdHJpbmcubGVuZ3RoKCk7CisgICAgICAgIGxvbmcgZXhwb25lbnQgPSAtKGxvbmcpc2NhbGUgKyBlbmQgLSBiZWdpbjsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCisgICAgICAgIHJlc3VsdC5hcHBlbmQoaW50U3RyaW5nKTsKKyAgICAgICAgaWYgKChzY2FsZSA+IDApICYmIChleHBvbmVudCA+PSAtNikpIHsKKyAgICAgICAgICAgIGlmIChleHBvbmVudCA+PSAwKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0Lmluc2VydChlbmQgLSBzY2FsZSwgJy4nKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmVzdWx0Lmluc2VydChiZWdpbiAtIDEsICIwLiIpOworICAgICAgICAgICAgICAgIHJlc3VsdC5pbnNlcnQoYmVnaW4gKyAxLCBDSF9aRVJPUywgMCwgLShpbnQpZXhwb25lbnQgLSAxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChlbmQgLSBiZWdpbiA+PSAxKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0Lmluc2VydChiZWdpbiwgJy4nKTsKKyAgICAgICAgICAgICAgICBlbmQrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdC5pbnNlcnQoZW5kLCAnRScpOworICAgICAgICAgICAgaWYgKGV4cG9uZW50ID4gMCkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5pbnNlcnQoKytlbmQsICcrJyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHQuaW5zZXJ0KCsrZW5kLCBMb25nLnRvU3RyaW5nKGV4cG9uZW50KSk7CisgICAgICAgIH0KKyAgICAgICAgdG9TdHJpbmdJbWFnZSA9IHJlc3VsdC50b1N0cmluZygpOworICAgICAgICByZXR1cm4gdG9TdHJpbmdJbWFnZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9LiBUaGlzCisgICAgICogcmVwcmVzZW50YXRpb24gYWx3YXlzIHByaW50cyBhbGwgc2lnbmlmaWNhbnQgZGlnaXRzIG9mIHRoaXMgdmFsdWUuCisgICAgICogPHA+CisgICAgICogSWYgdGhlIHNjYWxlIGlzIG5lZ2F0aXZlIG9yIGlmIHtAY29kZSBzY2FsZSAtIHByZWNpc2lvbiA+PSA2fSB0aGVuCisgICAgICogZW5naW5lZXJpbmcgbm90YXRpb24gaXMgdXNlZC4gRW5naW5lZXJpbmcgbm90YXRpb24gaXMgc2ltaWxhciB0byB0aGUKKyAgICAgKiBzY2llbnRpZmljIG5vdGF0aW9uIGV4Y2VwdCB0aGF0IHRoZSBleHBvbmVudCBpcyBtYWRlIHRvIGJlIGEgbXVsdGlwbGUgb2YKKyAgICAgKiAzIHN1Y2ggdGhhdCB0aGUgaW50ZWdlciBwYXJ0IGlzID49IDEgYW5kIDwgMTAwMC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIHRoaXN9IGluIGVuZ2luZWVyaW5nIG5vdGF0aW9uCisgICAgICogICAgICAgICBpZiBuZWNlc3NhcnkuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b0VuZ2luZWVyaW5nU3RyaW5nKCkgeworICAgICAgICBTdHJpbmcgaW50U3RyaW5nID0gZ2V0VW5zY2FsZWRWYWx1ZSgpLnRvU3RyaW5nKCk7CisgICAgICAgIGlmIChzY2FsZSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gaW50U3RyaW5nOworICAgICAgICB9CisgICAgICAgIGludCBiZWdpbiA9IChnZXRVbnNjYWxlZFZhbHVlKCkuc2lnbnVtKCkgPCAwKSA/IDIgOiAxOworICAgICAgICBpbnQgZW5kID0gaW50U3RyaW5nLmxlbmd0aCgpOworICAgICAgICBsb25nIGV4cG9uZW50ID0gLShsb25nKXNjYWxlICsgZW5kIC0gYmVnaW47CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoaW50U3RyaW5nKTsKKworICAgICAgICBpZiAoKHNjYWxlID4gMCkgJiYgKGV4cG9uZW50ID49IC02KSkgeworICAgICAgICAgICAgaWYgKGV4cG9uZW50ID49IDApIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuaW5zZXJ0KGVuZCAtIHNjYWxlLCAnLicpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuaW5zZXJ0KGJlZ2luIC0gMSwgIjAuIik7CisgICAgICAgICAgICAgICAgcmVzdWx0Lmluc2VydChiZWdpbiArIDEsIENIX1pFUk9TLCAwLCAtKGludClleHBvbmVudCAtIDEpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW50IGRlbHRhID0gZW5kIC0gYmVnaW47CisgICAgICAgICAgICBpbnQgcmVtID0gKGludCkoZXhwb25lbnQgJSAzKTsKKworICAgICAgICAgICAgaWYgKHJlbSAhPSAwKSB7CisgICAgICAgICAgICAgICAgLy8gYWRqdXN0IGV4cG9uZW50IHNvIGl0IGlzIGEgbXVsdGlwbGUgb2YgdGhyZWUKKyAgICAgICAgICAgICAgICBpZiAoZ2V0VW5zY2FsZWRWYWx1ZSgpLnNpZ251bSgpID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gemVybyB2YWx1ZQorICAgICAgICAgICAgICAgICAgICByZW0gPSAocmVtIDwgMCkgPyAtcmVtIDogMyAtIHJlbTsKKyAgICAgICAgICAgICAgICAgICAgZXhwb25lbnQgKz0gcmVtOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIC8vIG5vbnplcm8gdmFsdWUKKyAgICAgICAgICAgICAgICAgICAgcmVtID0gKHJlbSA8IDApID8gcmVtICsgMyA6IHJlbTsKKyAgICAgICAgICAgICAgICAgICAgZXhwb25lbnQgLT0gcmVtOworICAgICAgICAgICAgICAgICAgICBiZWdpbiArPSByZW07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChkZWx0YSA8IDMpIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHJlbSAtIGRlbHRhOyBpID4gMDsgaS0tKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuaW5zZXJ0KGVuZCsrLCAnMCcpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGVuZCAtIGJlZ2luID49IDEpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuaW5zZXJ0KGJlZ2luLCAnLicpOworICAgICAgICAgICAgICAgIGVuZCsrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGV4cG9uZW50ICE9IDApIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuaW5zZXJ0KGVuZCwgJ0UnKTsKKyAgICAgICAgICAgICAgICBpZiAoZXhwb25lbnQgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5pbnNlcnQoKytlbmQsICcrJyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJlc3VsdC5pbnNlcnQoKytlbmQsIExvbmcudG9TdHJpbmcoZXhwb25lbnQpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfS4gTm8gc2NpZW50aWZpYworICAgICAqIG5vdGF0aW9uIGlzIHVzZWQuIFRoaXMgbWV0aG9kcyBhZGRzIHplcm9zIHdoZXJlIG5lY2Vzc2FyeS4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIHN0cmluZyByZXByZXNlbnRhdGlvbiBpcyB1c2VkIHRvIGNyZWF0ZSBhIG5ldyBpbnN0YW5jZSwgdGhpcworICAgICAqIGluc3RhbmNlIGlzIGdlbmVyYWxseSBub3QgaWRlbnRpY2FsIHRvIHtAY29kZSB0aGlzfSBhcyB0aGUgcHJlY2lzaW9uCisgICAgICogY2hhbmdlcy4KKyAgICAgKiA8cD4KKyAgICAgKiB7QGNvZGUgeC5lcXVhbHMobmV3IEJpZ0RlY2ltYWwoeC50b1BsYWluU3RyaW5nKCkpfSB1c3VhbGx5IHJldHVybnMKKyAgICAgKiB7QGNvZGUgZmFsc2V9LgorICAgICAqIDxwPgorICAgICAqIHtAY29kZSB4LmNvbXBhcmVUbyhuZXcgQmlnRGVjaW1hbCh4LnRvUGxhaW5TdHJpbmcoKSl9IHJldHVybnMge0Bjb2RlIDB9LgorICAgICAqCisgICAgICogQHJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUgdGhpc30gd2l0aG91dCBleHBvbmVudCBwYXJ0LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9QbGFpblN0cmluZygpIHsKKyAgICAgICAgU3RyaW5nIGludFN0ciA9IGdldFVuc2NhbGVkVmFsdWUoKS50b1N0cmluZygpOworICAgICAgICBpZiAoKHNjYWxlID09IDApIHx8ICgoaXNaZXJvKCkpICYmIChzY2FsZSA8IDApKSkgeworICAgICAgICAgICAgcmV0dXJuIGludFN0cjsKKyAgICAgICAgfQorICAgICAgICBpbnQgYmVnaW4gPSAoc2lnbnVtKCkgPCAwKSA/IDEgOiAwOworICAgICAgICBpbnQgZGVsdGEgPSBzY2FsZTsKKyAgICAgICAgLy8gV2UgdGFrZSBzcGFjZSBmb3IgYWxsIGRpZ2l0cywgcGx1cyBhIHBvc3NpYmxlIGRlY2ltYWwgcG9pbnQsIHBsdXMgJ3NjYWxlJworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKGludFN0ci5sZW5ndGgoKSArIDEgKyBNYXRoLmFicyhzY2FsZSkpOworCisgICAgICAgIGlmIChiZWdpbiA9PSAxKSB7CisgICAgICAgICAgICAvLyBJZiB0aGUgbnVtYmVyIGlzIG5lZ2F0aXZlLCB3ZSBpbnNlcnQgYSAnLScgY2hhcmFjdGVyIGF0IGZyb250CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCctJyk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNjYWxlID4gMCkgeworICAgICAgICAgICAgZGVsdGEgLT0gKGludFN0ci5sZW5ndGgoKSAtIGJlZ2luKTsKKyAgICAgICAgICAgIGlmIChkZWx0YSA+PSAwKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiMC4iKTsKKyAgICAgICAgICAgICAgICAvLyBUbyBhcHBlbmQgemVyb3MgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQKKyAgICAgICAgICAgICAgICBmb3IgKDsgZGVsdGEgPiBDSF9aRVJPUy5sZW5ndGg7IGRlbHRhIC09IENIX1pFUk9TLmxlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKENIX1pFUk9TKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChDSF9aRVJPUywgMCwgZGVsdGEpOworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoaW50U3RyLnN1YnN0cmluZyhiZWdpbikpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkZWx0YSA9IGJlZ2luIC0gZGVsdGE7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChpbnRTdHIuc3Vic3RyaW5nKGJlZ2luLCBkZWx0YSkpOworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJy4nKTsKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGludFN0ci5zdWJzdHJpbmcoZGVsdGEpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsvLyAoc2NhbGUgPD0gMCkKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoaW50U3RyLnN1YnN0cmluZyhiZWdpbikpOworICAgICAgICAgICAgLy8gVG8gYXBwZW5kIHRyYWlsaW5nIHplcm9zCisgICAgICAgICAgICBmb3IgKDsgZGVsdGEgPCAtQ0hfWkVST1MubGVuZ3RoOyBkZWx0YSArPSBDSF9aRVJPUy5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKENIX1pFUk9TKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoQ0hfWkVST1MsIDAsIC1kZWx0YSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyB7QGNvZGUgQmlnRGVjaW1hbH0gYXMgYSBiaWcgaW50ZWdlciBpbnN0YW5jZS4gQSBmcmFjdGlvbmFsCisgICAgICogcGFydCBpcyBkaXNjYXJkZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9IGFzIGEgYmlnIGludGVnZXIgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgdG9CaWdJbnRlZ2VyKCkgeworICAgICAgICBpZiAoKHNjYWxlID09IDApIHx8IChpc1plcm8oKSkpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRVbnNjYWxlZFZhbHVlKCk7CisgICAgICAgIH0gZWxzZSBpZiAoc2NhbGUgPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0VW5zY2FsZWRWYWx1ZSgpLm11bHRpcGx5KE11bHRpcGxpY2F0aW9uLnBvd2VyT2YxMCgtKGxvbmcpc2NhbGUpKTsKKyAgICAgICAgfSBlbHNlIHsvLyAoc2NhbGUgPiAwKQorICAgICAgICAgICAgcmV0dXJuIGdldFVuc2NhbGVkVmFsdWUoKS5kaXZpZGUoTXVsdGlwbGljYXRpb24ucG93ZXJPZjEwKHNjYWxlKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9IGFzIGEgYmlnIGludGVnZXIgaW5zdGFuY2UgaWYgaXQgaGFzIG5vCisgICAgICogZnJhY3Rpb25hbCBwYXJ0LiBJZiB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfSBoYXMgYSBmcmFjdGlvbmFsIHBhcnQsIGkuZS4KKyAgICAgKiBpZiByb3VuZGluZyB3b3VsZCBiZSBuZWNlc3NhcnksIGFuIHtAY29kZSBBcml0aG1ldGljRXhjZXB0aW9ufSBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9IGFzIGEgYmlnIGludGVnZXIgdmFsdWUuCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgcm91bmRpbmcgaXMgbmVjZXNzYXJ5LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIHRvQmlnSW50ZWdlckV4YWN0KCkgeworICAgICAgICBpZiAoKHNjYWxlID09IDApIHx8IChpc1plcm8oKSkpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRVbnNjYWxlZFZhbHVlKCk7CisgICAgICAgIH0gZWxzZSBpZiAoc2NhbGUgPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0VW5zY2FsZWRWYWx1ZSgpLm11bHRpcGx5KE11bHRpcGxpY2F0aW9uLnBvd2VyT2YxMCgtKGxvbmcpc2NhbGUpKTsKKyAgICAgICAgfSBlbHNlIHsvLyAoc2NhbGUgPiAwKQorICAgICAgICAgICAgQmlnSW50ZWdlcltdIGludGVnZXJBbmRGcmFjdGlvbjsKKyAgICAgICAgICAgIC8vIEFuIG9wdGltaXphdGlvbiBiZWZvcmUgZG8gYSBoZWF2eSBkaXZpc2lvbgorICAgICAgICAgICAgaWYgKChzY2FsZSA+IGFwcHJveFByZWNpc2lvbigpKSB8fCAoc2NhbGUgPiBnZXRVbnNjYWxlZFZhbHVlKCkuZ2V0TG93ZXN0U2V0Qml0KCkpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFyaXRobWV0aWNFeGNlcHRpb24oIlJvdW5kaW5nIG5lY2Vzc2FyeSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50ZWdlckFuZEZyYWN0aW9uID0gZ2V0VW5zY2FsZWRWYWx1ZSgpLmRpdmlkZUFuZFJlbWFpbmRlcihNdWx0aXBsaWNhdGlvbi5wb3dlck9mMTAoc2NhbGUpKTsKKyAgICAgICAgICAgIGlmIChpbnRlZ2VyQW5kRnJhY3Rpb25bMV0uc2lnbnVtKCkgIT0gMCkgeworICAgICAgICAgICAgICAgIC8vIEl0IGV4aXN0cyBhIG5vbi16ZXJvIGZyYWN0aW9uYWwgcGFydAorICAgICAgICAgICAgICAgIHRocm93IG5ldyBBcml0aG1ldGljRXhjZXB0aW9uKCJSb3VuZGluZyBuZWNlc3NhcnkiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBpbnRlZ2VyQW5kRnJhY3Rpb25bMF07CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9IGFzIGFuIGxvbmcgdmFsdWUuIEFueSBmcmFjdGlvbmFsIHBhcnQgaXMKKyAgICAgKiBkaXNjYXJkZWQuIElmIHRoZSBpbnRlZ3JhbCBwYXJ0IG9mIHtAY29kZSB0aGlzfSBpcyB0b28gYmlnIHRvIGJlCisgICAgICogcmVwcmVzZW50ZWQgYXMgYW4gbG9uZywgdGhlbiB7QGNvZGUgdGhpc30gJSAyXjY0IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfSBhcyBhIGxvbmcgdmFsdWUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgbG9uZ1ZhbHVlKCkgeworICAgICAgICAvKgorICAgICAgICAgKiBJZiBzY2FsZSA8PSAtNjQgdGhlcmUgYXJlIGF0IGxlYXN0IDY0IHRyYWlsaW5nIGJpdHMgemVybyBpbgorICAgICAgICAgKiAxMF4oLXNjYWxlKS4gSWYgdGhlIHNjYWxlIGlzIHBvc2l0aXZlIGFuZCB2ZXJ5IGxhcmdlIHRoZSBsb25nIHZhbHVlCisgICAgICAgICAqIGNvdWxkIGJlIHplcm8uCisgICAgICAgICAqLworICAgICAgICByZXR1cm4gKChzY2FsZSA8PSAtNjQpIHx8IChzY2FsZSA+IGFwcHJveFByZWNpc2lvbigpKSA/IDBMCisgICAgICAgICAgICAgICAgOiB0b0JpZ0ludGVnZXIoKS5sb25nVmFsdWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfSBhcyBhIGxvbmcgdmFsdWUgaWYgaXQgaGFzIG5vIGZyYWN0aW9uYWwKKyAgICAgKiBwYXJ0IGFuZCBpZiBpdHMgdmFsdWUgZml0cyB0byB0aGUgaW50IHJhbmdlIChbLTJeezYzfS4uMl57NjN9LTFdKS4gSWYKKyAgICAgKiB0aGVzZSBjb25kaXRpb25zIGFyZSBub3QgbWV0LCBhbiB7QGNvZGUgQXJpdGhtZXRpY0V4Y2VwdGlvbn0gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfSBhcyBhIGxvbmcgdmFsdWUuCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgcm91bmRpbmcgaXMgbmVjZXNzYXJ5IG9yIHRoZSBudW1iZXIgZG9lc24ndCBmaXQgaW4gYSBsb25nLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGxvbmdWYWx1ZUV4YWN0KCkgeworICAgICAgICByZXR1cm4gdmFsdWVFeGFjdCg2NCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfSBhcyBhbiBpbnQgdmFsdWUuIEFueSBmcmFjdGlvbmFsIHBhcnQgaXMKKyAgICAgKiBkaXNjYXJkZWQuIElmIHRoZSBpbnRlZ3JhbCBwYXJ0IG9mIHtAY29kZSB0aGlzfSBpcyB0b28gYmlnIHRvIGJlCisgICAgICogcmVwcmVzZW50ZWQgYXMgYW4gaW50LCB0aGVuIHtAY29kZSB0aGlzfSAlIDJeMzIgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9IGFzIGEgaW50IHZhbHVlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaW50VmFsdWUoKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIElmIHNjYWxlIDw9IC0zMiB0aGVyZSBhcmUgYXQgbGVhc3QgMzIgdHJhaWxpbmcgYml0cyB6ZXJvIGluCisgICAgICAgICAqIDEwXigtc2NhbGUpLiBJZiB0aGUgc2NhbGUgaXMgcG9zaXRpdmUgYW5kIHZlcnkgbGFyZ2UgdGhlIGxvbmcgdmFsdWUKKyAgICAgICAgICogY291bGQgYmUgemVyby4KKyAgICAgICAgICovCisgICAgICAgIHJldHVybiAoKHNjYWxlIDw9IC0zMikgfHwgKHNjYWxlID4gYXBwcm94UHJlY2lzaW9uKCkpCisgICAgICAgID8gMAorICAgICAgICAgICAgICAgIDogdG9CaWdJbnRlZ2VyKCkuaW50VmFsdWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfSBhcyBhIGludCB2YWx1ZSBpZiBpdCBoYXMgbm8gZnJhY3Rpb25hbAorICAgICAqIHBhcnQgYW5kIGlmIGl0cyB2YWx1ZSBmaXRzIHRvIHRoZSBpbnQgcmFuZ2UgKFstMl57MzF9Li4yXnszMX0tMV0pLiBJZgorICAgICAqIHRoZXNlIGNvbmRpdGlvbnMgYXJlIG5vdCBtZXQsIGFuIHtAY29kZSBBcml0aG1ldGljRXhjZXB0aW9ufSBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9IGFzIGEgaW50IHZhbHVlLgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHJvdW5kaW5nIGlzIG5lY2Vzc2FyeSBvciB0aGUgbnVtYmVyIGRvZXNuJ3QgZml0IGluIGEgaW50LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgaW50VmFsdWVFeGFjdCgpIHsKKyAgICAgICAgcmV0dXJuIChpbnQpdmFsdWVFeGFjdCgzMik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfSBhcyBhIHNob3J0IHZhbHVlIGlmIGl0IGhhcyBubyBmcmFjdGlvbmFsCisgICAgICogcGFydCBhbmQgaWYgaXRzIHZhbHVlIGZpdHMgdG8gdGhlIHNob3J0IHJhbmdlIChbLTJeezE1fS4uMl57MTV9LTFdKS4gSWYKKyAgICAgKiB0aGVzZSBjb25kaXRpb25zIGFyZSBub3QgbWV0LCBhbiB7QGNvZGUgQXJpdGhtZXRpY0V4Y2VwdGlvbn0gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfSBhcyBhIHNob3J0IHZhbHVlLgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHJvdW5kaW5nIGlzIG5lY2Vzc2FyeSBvZiB0aGUgbnVtYmVyIGRvZXNuJ3QgZml0IGluIGEKKyAgICAgKiAgICAgICAgICAgICBzaG9ydC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2hvcnQgc2hvcnRWYWx1ZUV4YWN0KCkgeworICAgICAgICByZXR1cm4gKHNob3J0KXZhbHVlRXhhY3QoMTYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyB7QGNvZGUgQmlnRGVjaW1hbH0gYXMgYSBieXRlIHZhbHVlIGlmIGl0IGhhcyBubyBmcmFjdGlvbmFsCisgICAgICogcGFydCBhbmQgaWYgaXRzIHZhbHVlIGZpdHMgdG8gdGhlIGJ5dGUgcmFuZ2UgKFstMTI4Li4xMjddKS4gSWYgdGhlc2UKKyAgICAgKiBjb25kaXRpb25zIGFyZSBub3QgbWV0LCBhbiB7QGNvZGUgQXJpdGhtZXRpY0V4Y2VwdGlvbn0gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfSBhcyBhIGJ5dGUgdmFsdWUuCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgcm91bmRpbmcgaXMgbmVjZXNzYXJ5IG9yIHRoZSBudW1iZXIgZG9lc24ndCBmaXQgaW4gYSBieXRlLgorICAgICAqLworICAgIHB1YmxpYyBieXRlIGJ5dGVWYWx1ZUV4YWN0KCkgeworICAgICAgICByZXR1cm4gKGJ5dGUpdmFsdWVFeGFjdCg4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9IGFzIGEgZmxvYXQgdmFsdWUuIElmIHtAY29kZSB0aGlzfSBpcyB0b28KKyAgICAgKiBiaWcgdG8gYmUgcmVwcmVzZW50ZWQgYXMgYW4gZmxvYXQsIHRoZW4ge0Bjb2RlIEZsb2F0LlBPU0lUSVZFX0lORklOSVRZfQorICAgICAqIG9yIHtAY29kZSBGbG9hdC5ORUdBVElWRV9JTkZJTklUWX0gaXMgcmV0dXJuZWQuCisgICAgICogPHA+CisgICAgICogTm90ZSwgdGhhdCBpZiB0aGUgdW5zY2FsZWQgdmFsdWUgaGFzIG1vcmUgdGhhbiAyNCBzaWduaWZpY2FudCBkaWdpdHMsCisgICAgICogdGhlbiB0aGlzIGRlY2ltYWwgY2Fubm90IGJlIHJlcHJlc2VudGVkIGV4YWN0bHkgaW4gYSBmbG9hdCB2YXJpYWJsZS4gSW4KKyAgICAgKiB0aGlzIGNhc2UgdGhlIHJlc3VsdCBpcyByb3VuZGVkLgorICAgICAqIDxwPgorICAgICAqIEZvciBleGFtcGxlLCBpZiB0aGUgaW5zdGFuY2Uge0Bjb2RlIHgxID0gbmV3IEJpZ0RlY2ltYWwoIjAuMSIpfSBjYW5ub3QgYmUKKyAgICAgKiByZXByZXNlbnRlZCBleGFjdGx5IGFzIGEgZmxvYXQsIGFuZCB0aHVzIHtAY29kZSB4MS5lcXVhbHMobmV3CisgICAgICogQmlnRGVjaW1hbCh4MS5mb2xhdFZhbHVlKCkpfSByZXR1cm5zIHtAY29kZSBmYWxzZX0gZm9yIHRoaXMgY2FzZS4KKyAgICAgKiA8cD4KKyAgICAgKiBTaW1pbGFybHksIGlmIHRoZSBpbnN0YW5jZSB7QGNvZGUgbmV3IEJpZ0RlY2ltYWwoMTY3NzcyMTcpfSBpcyBjb252ZXJ0ZWQKKyAgICAgKiB0byBhIGZsb2F0LCB0aGUgcmVzdWx0IGlzIHtAY29kZSAxLjY3NzcyMTZFfTcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9IGFzIGEgZmxvYXQgdmFsdWUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZsb2F0IGZsb2F0VmFsdWUoKSB7CisgICAgICAgIC8qIEEgc2ltaWxhciBjb2RlIGxpa2UgaW4gZG91YmxlVmFsdWUoKSBjb3VsZCBiZSByZXBlYXRlZCBoZXJlLAorICAgICAgICAgKiBidXQgdGhpcyBzaW1wbGUgaW1wbGVtZW50YXRpb24gaXMgcXVpdGUgZWZmaWNpZW50LiAqLworICAgICAgICBmbG9hdCBmbG9hdFJlc3VsdCA9IHNpZ251bSgpOworICAgICAgICBsb25nIHBvd2VyT2ZUd28gPSB0aGlzLmJpdExlbmd0aCAtIChsb25nKShzY2FsZSAvIExPRzEwXzIpOworICAgICAgICBpZiAoKHBvd2VyT2ZUd28gPCAtMTQ5KSB8fCAoZmxvYXRSZXN1bHQgPT0gMC4wZikpIHsKKyAgICAgICAgICAgIC8vIENhc2VzIHdoaWNoICd0aGlzJyBpcyB2ZXJ5IHNtYWxsCisgICAgICAgICAgICBmbG9hdFJlc3VsdCAqPSAwLjBmOworICAgICAgICB9IGVsc2UgaWYgKHBvd2VyT2ZUd28gPiAxMjkpIHsKKyAgICAgICAgICAgIC8vIENhc2VzIHdoaWNoICd0aGlzJyBpcyB2ZXJ5IGxhcmdlCisgICAgICAgICAgICBmbG9hdFJlc3VsdCAqPSBGbG9hdC5QT1NJVElWRV9JTkZJTklUWTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZsb2F0UmVzdWx0ID0gKGZsb2F0KWRvdWJsZVZhbHVlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZsb2F0UmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyB7QGNvZGUgQmlnRGVjaW1hbH0gYXMgYSBkb3VibGUgdmFsdWUuIElmIHtAY29kZSB0aGlzfSBpcyB0b28KKyAgICAgKiBiaWcgdG8gYmUgcmVwcmVzZW50ZWQgYXMgYW4gZmxvYXQsIHRoZW4ge0Bjb2RlIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWX0KKyAgICAgKiBvciB7QGNvZGUgRG91YmxlLk5FR0FUSVZFX0lORklOSVRZfSBpcyByZXR1cm5lZC4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlLCB0aGF0IGlmIHRoZSB1bnNjYWxlZCB2YWx1ZSBoYXMgbW9yZSB0aGFuIDUzIHNpZ25pZmljYW50IGRpZ2l0cywKKyAgICAgKiB0aGVuIHRoaXMgZGVjaW1hbCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgZXhhY3RseSBpbiBhIGRvdWJsZSB2YXJpYWJsZS4gSW4KKyAgICAgKiB0aGlzIGNhc2UgdGhlIHJlc3VsdCBpcyByb3VuZGVkLgorICAgICAqIDxwPgorICAgICAqIEZvciBleGFtcGxlLCBpZiB0aGUgaW5zdGFuY2Uge0Bjb2RlIHgxID0gbmV3IEJpZ0RlY2ltYWwoIjAuMSIpfSBjYW5ub3QgYmUKKyAgICAgKiByZXByZXNlbnRlZCBleGFjdGx5IGFzIGEgZG91YmxlLCBhbmQgdGh1cyB7QGNvZGUgeDEuZXF1YWxzKG5ldworICAgICAqIEJpZ0RlY2ltYWwoeDEuZG91YmxlVmFsdWUoKSl9IHJldHVybnMge0Bjb2RlIGZhbHNlfSBmb3IgdGhpcyBjYXNlLgorICAgICAqIDxwPgorICAgICAqIFNpbWlsYXJseSwgaWYgdGhlIGluc3RhbmNlIHtAY29kZSBuZXcgQmlnRGVjaW1hbCg5MDA3MTk5MjU0NzQwOTkzTCl9IGlzCisgICAgICogY29udmVydGVkIHRvIGEgZG91YmxlLCB0aGUgcmVzdWx0IGlzIHtAY29kZSA5LjAwNzE5OTI1NDc0MDk5MkUxNX0uCisgICAgICogPHA+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9IGFzIGEgZG91YmxlIHZhbHVlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkb3VibGUgZG91YmxlVmFsdWUoKSB7CisgICAgICAgIGludCBzaWduID0gc2lnbnVtKCk7CisgICAgICAgIGludCBleHBvbmVudCA9IDEwNzY7IC8vIGJpYXMgKyA1MworICAgICAgICBpbnQgbG93ZXN0U2V0Qml0OworICAgICAgICBpbnQgZGlzY2FyZGVkU2l6ZTsKKyAgICAgICAgbG9uZyBwb3dlck9mVHdvID0gdGhpcy5iaXRMZW5ndGggLSAobG9uZykoc2NhbGUgLyBMT0cxMF8yKTsKKyAgICAgICAgbG9uZyBiaXRzOyAvLyBJRUVFLTc1NCBTdGFuZGFyZAorICAgICAgICBsb25nIHRlbXBCaXRzOyAvLyBmb3IgdGVtcG9yYWwgY2FsY3VsYXRpb25zCisgICAgICAgIEJpZ0ludGVnZXIgbWFudGlzc2E7CisKKyAgICAgICAgaWYgKChwb3dlck9mVHdvIDwgLTEwNzQpIHx8IChzaWduID09IDApKSB7CisgICAgICAgICAgICAvLyBDYXNlcyB3aGljaCAndGhpcycgaXMgdmVyeSBzbWFsbAorICAgICAgICAgICAgcmV0dXJuIChzaWduICogMC4wZCk7CisgICAgICAgIH0gZWxzZSBpZiAocG93ZXJPZlR3byA+IDEwMjUpIHsKKyAgICAgICAgICAgIC8vIENhc2VzIHdoaWNoICd0aGlzJyBpcyB2ZXJ5IGxhcmdlCisgICAgICAgICAgICByZXR1cm4gKHNpZ24gKiBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFkpOworICAgICAgICB9CisgICAgICAgIG1hbnRpc3NhID0gZ2V0VW5zY2FsZWRWYWx1ZSgpLmFicygpOworICAgICAgICAvLyBMZXQgYmU6ICB0aGlzID0gW3Usc10sIHdpdGggcyA+IDAKKyAgICAgICAgaWYgKHNjYWxlIDw9IDApIHsKKyAgICAgICAgICAgIC8vIG1hbnRpc3NhID0gYWJzKHUpICogMTBecworICAgICAgICAgICAgbWFudGlzc2EgPSBtYW50aXNzYS5tdWx0aXBseShNdWx0aXBsaWNhdGlvbi5wb3dlck9mMTAoLXNjYWxlKSk7CisgICAgICAgIH0gZWxzZSB7Ly8gKHNjYWxlID4gMCkKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgcXVvdEFuZFJlbVtdOworICAgICAgICAgICAgQmlnSW50ZWdlciBwb3dlck9mVGVuID0gTXVsdGlwbGljYXRpb24ucG93ZXJPZjEwKHNjYWxlKTsKKyAgICAgICAgICAgIGludCBrID0gMTAwIC0gKGludClwb3dlck9mVHdvOworICAgICAgICAgICAgaW50IGNvbXBSZW07CisKKyAgICAgICAgICAgIGlmIChrID4gMCkgeworICAgICAgICAgICAgICAgIC8qIENvbXB1dGluZyAobWFudGlzc2EgKiAyXmspICwgd2hlcmUgJ2snIGlzIGEgZW5vdWdoIGJpZworICAgICAgICAgICAgICAgICAqIHBvd2VyIG9mICcyJyB0byBjYW4gZGl2aWRlIGJ5IDEwXnMgKi8KKyAgICAgICAgICAgICAgICBtYW50aXNzYSA9IG1hbnRpc3NhLnNoaWZ0TGVmdChrKTsKKyAgICAgICAgICAgICAgICBleHBvbmVudCAtPSBrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gQ29tcHV0aW5nIChtYW50aXNzYSAqIDJeaykgLyAxMF5zCisgICAgICAgICAgICBxdW90QW5kUmVtID0gbWFudGlzc2EuZGl2aWRlQW5kUmVtYWluZGVyKHBvd2VyT2ZUZW4pOworICAgICAgICAgICAgLy8gVG8gY2hlY2sgaWYgdGhlIGZyYWN0aW9uYWwgcGFydCA+PSAwLjUKKyAgICAgICAgICAgIGNvbXBSZW0gPSBxdW90QW5kUmVtWzFdLnNoaWZ0TGVmdE9uZUJpdCgpLmNvbXBhcmVUbyhwb3dlck9mVGVuKTsKKyAgICAgICAgICAgIC8vIFRvIGFkZCB0d28gcm91bmRlZCBiaXRzIGF0IGVuZCBvZiBtYW50aXNzYQorICAgICAgICAgICAgbWFudGlzc2EgPSBxdW90QW5kUmVtWzBdLnNoaWZ0TGVmdCgyKS5hZGQoCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZigoY29tcFJlbSAqIChjb21wUmVtICsgMykpIC8gMiArIDEpKTsKKyAgICAgICAgICAgIGV4cG9uZW50IC09IDI7CisgICAgICAgIH0KKyAgICAgICAgbG93ZXN0U2V0Qml0ID0gbWFudGlzc2EuZ2V0TG93ZXN0U2V0Qml0KCk7CisgICAgICAgIGRpc2NhcmRlZFNpemUgPSBtYW50aXNzYS5iaXRMZW5ndGgoKSAtIDU0OworICAgICAgICBpZiAoZGlzY2FyZGVkU2l6ZSA+IDApIHsvLyAobiA+IDU0KQorICAgICAgICAgICAgLy8gbWFudGlzc2EgPSAoYWJzKHUpICogMTBecykgPj4gKG4gLSA1NCkKKyAgICAgICAgICAgIGJpdHMgPSBtYW50aXNzYS5zaGlmdFJpZ2h0KGRpc2NhcmRlZFNpemUpLmxvbmdWYWx1ZSgpOworICAgICAgICAgICAgdGVtcEJpdHMgPSBiaXRzOworICAgICAgICAgICAgLy8gI2JpdHMgPSA1NCwgdG8gY2hlY2sgaWYgdGhlIGRpc2NhcmRlZCBmcmFjdGlvbiBwcm9kdWNlcyBhIGNhcnJ5CisgICAgICAgICAgICBpZiAoKCgoYml0cyAmIDEpID09IDEpICYmIChsb3dlc3RTZXRCaXQgPCBkaXNjYXJkZWRTaXplKSkKKyAgICAgICAgICAgICAgICAgICAgfHwgKChiaXRzICYgMykgPT0gMykpIHsKKyAgICAgICAgICAgICAgICBiaXRzICs9IDI7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7Ly8gKG4gPD0gNTQpCisgICAgICAgICAgICAvLyBtYW50aXNzYSA9IChhYnModSkgKiAxMF5zKSA8PCAoNTQgLSBuKQorICAgICAgICAgICAgYml0cyA9IG1hbnRpc3NhLmxvbmdWYWx1ZSgpIDw8IC1kaXNjYXJkZWRTaXplOworICAgICAgICAgICAgdGVtcEJpdHMgPSBiaXRzOworICAgICAgICAgICAgLy8gI2JpdHMgPSA1NCwgdG8gY2hlY2sgaWYgdGhlIGRpc2NhcmRlZCBmcmFjdGlvbiBwcm9kdWNlcyBhIGNhcnJ5OgorICAgICAgICAgICAgaWYgKChiaXRzICYgMykgPT0gMykgeworICAgICAgICAgICAgICAgIGJpdHMgKz0gMjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBUZXN0aW5nIGJpdCA1NCB0byBjaGVjayBpZiB0aGUgY2FycnkgY3JlYXRlcyBhIG5ldyBiaW5hcnkgZGlnaXQKKyAgICAgICAgaWYgKChiaXRzICYgMHg0MDAwMDAwMDAwMDAwMEwpID09IDApIHsKKyAgICAgICAgICAgIC8vIFRvIGRyb3AgdGhlIGxhc3QgYml0IG9mIG1hbnRpc3NhIChmaXJzdCBkaXNjYXJkZWQpCisgICAgICAgICAgICBiaXRzID4+PSAxOworICAgICAgICAgICAgLy8gZXhwb25lbnQgPSAyXihzLW4rNTMrYmlhcykKKyAgICAgICAgICAgIGV4cG9uZW50ICs9IGRpc2NhcmRlZFNpemU7CisgICAgICAgIH0gZWxzZSB7Ly8gI2JpdHMgPSA1NAorICAgICAgICAgICAgYml0cyA+Pj0gMjsKKyAgICAgICAgICAgIGV4cG9uZW50ICs9IGRpc2NhcmRlZFNpemUgKyAxOworICAgICAgICB9CisgICAgICAgIC8vIFRvIHRlc3QgaWYgdGhlIDUzLWJpdHMgbnVtYmVyIGZpdHMgaW4gJ2RvdWJsZScKKyAgICAgICAgaWYgKGV4cG9uZW50ID4gMjA0Nikgey8vIChleHBvbmVudCAtIGJpYXMgPiAxMDIzKQorICAgICAgICAgICAgcmV0dXJuIChzaWduICogRG91YmxlLlBPU0lUSVZFX0lORklOSVRZKTsKKyAgICAgICAgfSBlbHNlIGlmIChleHBvbmVudCA8PSAwKSB7Ly8gKGV4cG9uZW50IC0gYmlhcyA8PSAtMTAyMykKKyAgICAgICAgICAgIC8vIERlbm9ybWFsaXplZCBudW1iZXJzIChoYXZpbmcgZXhwb25lbnQgPT0gMCkKKyAgICAgICAgICAgIGlmIChleHBvbmVudCA8IC01Mykgey8vIGV4cG9uZW50IC0gYmlhcyA8IC0xMDc2CisgICAgICAgICAgICAgICAgcmV0dXJuIChzaWduICogMC4wZCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyAtMTA3NiA8PSBleHBvbmVudCAtIGJpYXMgPD0gLTEwMjMKKyAgICAgICAgICAgIC8vIFRvIGRpc2NhcmQgJy0gZXhwb25lbnQgKyAxJyBiaXRzCisgICAgICAgICAgICBiaXRzID0gdGVtcEJpdHMgPj4gMTsKKyAgICAgICAgICAgIHRlbXBCaXRzID0gYml0cyAmICgtMUwgPj4+ICg2MyArIGV4cG9uZW50KSk7CisgICAgICAgICAgICBiaXRzID4+PSAoLWV4cG9uZW50ICk7CisgICAgICAgICAgICAvLyBUbyB0ZXN0IGlmIGFmdGVyIGRpc2NhcmQgYml0cywgYSBuZXcgY2FycnkgaXMgZ2VuZXJhdGVkCisgICAgICAgICAgICBpZiAoKChiaXRzICYgMykgPT0gMykgfHwgKCgoYml0cyAmIDEpID09IDEpICYmICh0ZW1wQml0cyAhPSAwKQorICAgICAgICAgICAgJiYgKGxvd2VzdFNldEJpdCA8IGRpc2NhcmRlZFNpemUpKSkgeworICAgICAgICAgICAgICAgIGJpdHMgKz0gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGV4cG9uZW50ID0gMDsKKyAgICAgICAgICAgIGJpdHMgPj49IDE7CisgICAgICAgIH0KKyAgICAgICAgLy8gQ29uc3RydWN0IHRoZSA2NCBkb3VibGUgYml0czogW3NpZ24oMSksIGV4cG9uZW50KDExKSwgbWFudGlzc2EoNTIpXQorICAgICAgICBiaXRzID0gKHNpZ24gJiAweDgwMDAwMDAwMDAwMDAwMDBMKSB8ICgobG9uZylleHBvbmVudCA8PCA1MikKKyAgICAgICAgICAgICAgICB8IChiaXRzICYgMHhGRkZGRkZGRkZGRkZGTCk7CisgICAgICAgIHJldHVybiBEb3VibGUubG9uZ0JpdHNUb0RvdWJsZShiaXRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB1bml0IGluIHRoZSBsYXN0IHBsYWNlIChVTFApIG9mIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9CisgICAgICogaW5zdGFuY2UuIEFuIFVMUCBpcyB0aGUgZGlzdGFuY2UgdG8gdGhlIG5lYXJlc3QgYmlnIGRlY2ltYWwgd2l0aCB0aGUgc2FtZQorICAgICAqIHByZWNpc2lvbi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgYW1vdW50IG9mIGEgcm91bmRpbmcgZXJyb3IgaW4gdGhlIGV2YWx1YXRpb24gb2YgYSBmbG9hdGluZy1wb2ludAorICAgICAqIG9wZXJhdGlvbiBpcyBvZnRlbiBleHByZXNzZWQgaW4gVUxQcy4gQW4gZXJyb3Igb2YgMSBVTFAgaXMgb2Z0ZW4gc2VlbiBhcworICAgICAqIGEgdG9sZXJhYmxlIGVycm9yLgorICAgICAqIDxwPgorICAgICAqIEZvciBjbGFzcyB7QGNvZGUgQmlnRGVjaW1hbH0sIHRoZSBVTFAgb2YgYSBudW1iZXIgaXMgc2ltcGx5IDEwXigtc2NhbGUpLgorICAgICAqIDxwPgorICAgICAqIEZvciBleGFtcGxlLCB7QGNvZGUgbmV3IEJpZ0RlY2ltYWwoMC4xKS51bHAoKX0gcmV0dXJucyB7QGNvZGUgMUUtNTV9LgorICAgICAqCisgICAgICogQHJldHVybiB1bml0IGluIHRoZSBsYXN0IHBsYWNlIChVTFApIG9mIHRoaXMge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsIHVscCgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlT2YoMSwgc2NhbGUpOworICAgIH0KKworICAgIC8qIFByaXZhdGUgTWV0aG9kcyAqLworCisgICAgLyoqCisgICAgICogSXQgZG9lcyBhbGwgcm91bmRpbmcgd29yayBvZiB0aGUgcHVibGljIG1ldGhvZAorICAgICAqIHtAY29kZSByb3VuZChNYXRoQ29udGV4dCl9LCBwZXJmb3JtaW5nIGFuIGlucGxhY2Ugcm91bmRpbmcKKyAgICAgKiB3aXRob3V0IGNyZWF0aW5nIGEgbmV3IG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtYworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBNYXRoQ29udGV4dH0gZm9yIHBlcmZvcm0gdGhlIHJvdW5kaW5nLgorICAgICAqIEBzZWUgI3JvdW5kKE1hdGhDb250ZXh0KQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpbnBsYWNlUm91bmQoTWF0aENvbnRleHQgbWMpIHsKKyAgICAgICAgaW50IG1jUHJlY2lzaW9uID0gbWMuZ2V0UHJlY2lzaW9uKCk7CisgICAgICAgIGlmIChhcHByb3hQcmVjaXNpb24oKSA8IG1jUHJlY2lzaW9uIHx8IG1jUHJlY2lzaW9uID09IDApIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpbnQgZGlzY2FyZGVkUHJlY2lzaW9uID0gcHJlY2lzaW9uKCkgLSBtY1ByZWNpc2lvbjsKKyAgICAgICAgLy8gSWYgbm8gcm91bmRpbmcgaXMgbmVjZXNzYXJ5IGl0IHJldHVybnMgaW1tZWRpYXRlbHkKKyAgICAgICAgaWYgKChkaXNjYXJkZWRQcmVjaXNpb24gPD0gMCkpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICAvLyBXaGVuIHRoZSBudW1iZXIgaXMgc21hbGwgcGVyZm9ybSBhbiBlZmZpY2llbnQgcm91bmRpbmcKKyAgICAgICAgaWYgKHRoaXMuYml0TGVuZ3RoIDwgNjQpIHsKKyAgICAgICAgICAgIHNtYWxsUm91bmQobWMsIGRpc2NhcmRlZFByZWNpc2lvbik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgLy8gR2V0dGluZyB0aGUgaW50ZWdlciBwYXJ0IGFuZCB0aGUgZGlzY2FyZGVkIGZyYWN0aW9uCisgICAgICAgIEJpZ0ludGVnZXIgc2l6ZU9mRnJhY3Rpb24gPSBNdWx0aXBsaWNhdGlvbi5wb3dlck9mMTAoZGlzY2FyZGVkUHJlY2lzaW9uKTsKKyAgICAgICAgQmlnSW50ZWdlcltdIGludGVnZXJBbmRGcmFjdGlvbiA9IGdldFVuc2NhbGVkVmFsdWUoKS5kaXZpZGVBbmRSZW1haW5kZXIoc2l6ZU9mRnJhY3Rpb24pOworICAgICAgICBsb25nIG5ld1NjYWxlID0gKGxvbmcpc2NhbGUgLSBkaXNjYXJkZWRQcmVjaXNpb247CisgICAgICAgIGludCBjb21wUmVtOworICAgICAgICBCaWdEZWNpbWFsIHRlbXBCRDsKKyAgICAgICAgLy8gSWYgdGhlIGRpc2NhcmRlZCBmcmFjdGlvbiBpcyBub24temVybywgcGVyZm9ybSByb3VuZGluZworICAgICAgICBpZiAoaW50ZWdlckFuZEZyYWN0aW9uWzFdLnNpZ251bSgpICE9IDApIHsKKyAgICAgICAgICAgIC8vIFRvIGNoZWNrIGlmIHRoZSBkaXNjYXJkZWQgZnJhY3Rpb24gPj0gMC41CisgICAgICAgICAgICBjb21wUmVtID0gKGludGVnZXJBbmRGcmFjdGlvblsxXS5hYnMoKS5zaGlmdExlZnRPbmVCaXQoKS5jb21wYXJlVG8oc2l6ZU9mRnJhY3Rpb24pKTsKKyAgICAgICAgICAgIC8vIFRvIGxvb2sgaWYgdGhlcmUgaXMgYSBjYXJyeQorICAgICAgICAgICAgY29tcFJlbSA9ICByb3VuZGluZ0JlaGF2aW9yKCBpbnRlZ2VyQW5kRnJhY3Rpb25bMF0udGVzdEJpdCgwKSA/IDEgOiAwLAorICAgICAgICAgICAgICAgICAgICBpbnRlZ2VyQW5kRnJhY3Rpb25bMV0uc2lnbnVtKCkgKiAoNSArIGNvbXBSZW0pLAorICAgICAgICAgICAgICAgICAgICBtYy5nZXRSb3VuZGluZ01vZGUoKSk7CisgICAgICAgICAgICBpZiAoY29tcFJlbSAhPSAwKSB7CisgICAgICAgICAgICAgICAgaW50ZWdlckFuZEZyYWN0aW9uWzBdID0gaW50ZWdlckFuZEZyYWN0aW9uWzBdLmFkZChCaWdJbnRlZ2VyLnZhbHVlT2YoY29tcFJlbSkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGVtcEJEID0gbmV3IEJpZ0RlY2ltYWwoaW50ZWdlckFuZEZyYWN0aW9uWzBdKTsKKyAgICAgICAgICAgIC8vIElmIGFmdGVyIHRvIGFkZCB0aGUgaW5jcmVtZW50IHRoZSBwcmVjaXNpb24gY2hhbmdlZCwgd2Ugbm9ybWFsaXplIHRoZSBzaXplCisgICAgICAgICAgICBpZiAodGVtcEJELnByZWNpc2lvbigpID4gbWNQcmVjaXNpb24pIHsKKyAgICAgICAgICAgICAgICBpbnRlZ2VyQW5kRnJhY3Rpb25bMF0gPSBpbnRlZ2VyQW5kRnJhY3Rpb25bMF0uZGl2aWRlKEJpZ0ludGVnZXIuVEVOKTsKKyAgICAgICAgICAgICAgICBuZXdTY2FsZS0tOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIFRvIHVwZGF0ZSBhbGwgaW50ZXJuYWwgZmllbGRzCisgICAgICAgIHNjYWxlID0gc2FmZUxvbmdUb0ludChuZXdTY2FsZSk7CisgICAgICAgIHByZWNpc2lvbiA9IG1jUHJlY2lzaW9uOworICAgICAgICBzZXRVbnNjYWxlZFZhbHVlKGludGVnZXJBbmRGcmFjdGlvblswXSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGxvbmdDb21wYXJlVG8obG9uZyB2YWx1ZTEsIGxvbmcgdmFsdWUyKSB7CisgICAgICAgIHJldHVybiB2YWx1ZTEgPiB2YWx1ZTIgPyAxIDogKHZhbHVlMSA8IHZhbHVlMiA/IC0xIDogMCk7CisgICAgfQorICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGltcGxlbWVudHMgYW4gZWZmaWNpZW50IHJvdW5kaW5nIGZvciBudW1iZXJzIHdoaWNoIHVuc2NhbGVkCisgICAgICogdmFsdWUgZml0cyBpbiB0aGUgdHlwZSB7QGNvZGUgbG9uZ30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb250ZXh0IHRvIHVzZQorICAgICAqIEBwYXJhbSBkaXNjYXJkZWRQcmVjaXNpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgZGVjaW1hbCBkaWdpdHMgdGhhdCBhcmUgZGlzY2FyZGVkCisgICAgICogQHNlZSAjcm91bmQoTWF0aENvbnRleHQpCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNtYWxsUm91bmQoTWF0aENvbnRleHQgbWMsIGludCBkaXNjYXJkZWRQcmVjaXNpb24pIHsKKyAgICAgICAgbG9uZyBzaXplT2ZGcmFjdGlvbiA9IE1hdGhVdGlscy5MT05HX1BPV0VSU19PRl9URU5bZGlzY2FyZGVkUHJlY2lzaW9uXTsKKyAgICAgICAgbG9uZyBuZXdTY2FsZSA9IChsb25nKXNjYWxlIC0gZGlzY2FyZGVkUHJlY2lzaW9uOworICAgICAgICBsb25nIHVuc2NhbGVkVmFsID0gc21hbGxWYWx1ZTsKKyAgICAgICAgLy8gR2V0dGluZyB0aGUgaW50ZWdlciBwYXJ0IGFuZCB0aGUgZGlzY2FyZGVkIGZyYWN0aW9uCisgICAgICAgIGxvbmcgaW50ZWdlciA9IHVuc2NhbGVkVmFsIC8gc2l6ZU9mRnJhY3Rpb247CisgICAgICAgIGxvbmcgZnJhY3Rpb24gPSB1bnNjYWxlZFZhbCAlIHNpemVPZkZyYWN0aW9uOworICAgICAgICBpbnQgY29tcFJlbTsKKyAgICAgICAgLy8gSWYgdGhlIGRpc2NhcmRlZCBmcmFjdGlvbiBpcyBub24temVybyBwZXJmb3JtIHJvdW5kaW5nCisgICAgICAgIGlmIChmcmFjdGlvbiAhPSAwKSB7CisgICAgICAgICAgICAvLyBUbyBjaGVjayBpZiB0aGUgZGlzY2FyZGVkIGZyYWN0aW9uID49IDAuNQorICAgICAgICAgICAgY29tcFJlbSA9IGxvbmdDb21wYXJlVG8oTWF0aC5hYnMoZnJhY3Rpb24pICogMiwgc2l6ZU9mRnJhY3Rpb24pOworICAgICAgICAgICAgLy8gVG8gbG9vayBpZiB0aGVyZSBpcyBhIGNhcnJ5CisgICAgICAgICAgICBpbnRlZ2VyICs9IHJvdW5kaW5nQmVoYXZpb3IoICgoaW50KWludGVnZXIpICYgMSwKKyAgICAgICAgICAgICAgICAgICAgTG9uZy5zaWdudW0oZnJhY3Rpb24pICogKDUgKyBjb21wUmVtKSwKKyAgICAgICAgICAgICAgICAgICAgbWMuZ2V0Um91bmRpbmdNb2RlKCkpOworICAgICAgICAgICAgLy8gSWYgYWZ0ZXIgdG8gYWRkIHRoZSBpbmNyZW1lbnQgdGhlIHByZWNpc2lvbiBjaGFuZ2VkLCB3ZSBub3JtYWxpemUgdGhlIHNpemUKKyAgICAgICAgICAgIGlmIChNYXRoLmxvZzEwKE1hdGguYWJzKGludGVnZXIpKSA+PSBtYy5nZXRQcmVjaXNpb24oKSkgeworICAgICAgICAgICAgICAgIGludGVnZXIgLz0gMTA7CisgICAgICAgICAgICAgICAgbmV3U2NhbGUtLTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBUbyB1cGRhdGUgYWxsIGludGVybmFsIGZpZWxkcworICAgICAgICBzY2FsZSA9IHNhZmVMb25nVG9JbnQobmV3U2NhbGUpOworICAgICAgICBwcmVjaXNpb24gPSBtYy5nZXRQcmVjaXNpb24oKTsKKyAgICAgICAgc21hbGxWYWx1ZSA9IGludGVnZXI7CisgICAgICAgIGJpdExlbmd0aCA9IGJpdExlbmd0aChpbnRlZ2VyKTsKKyAgICAgICAgaW50VmFsID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYW4gaW5jcmVtZW50IHRoYXQgY2FuIGJlIC0xLDAgb3IgMSwgZGVwZW5kaW5nIG9mCisgICAgICoge0Bjb2RlIHJvdW5kaW5nTW9kZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyaXR5Qml0CisgICAgICogICAgICAgICAgICBjYW4gYmUgMCBvciAxLCBpdCdzIG9ubHkgdXNlZCBpbiB0aGUgY2FzZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIEhBTEZfRVZFTn0KKyAgICAgKiBAcGFyYW0gZnJhY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBtYW50aXNzYSB0byBiZSBhbmFseXplZAorICAgICAqIEBwYXJhbSByb3VuZGluZ01vZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHJvdW5kaW5nCisgICAgICogQHJldHVybiB0aGUgY2FycnkgcHJvcGFnYXRlZCBhZnRlciByb3VuZGluZworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCByb3VuZGluZ0JlaGF2aW9yKGludCBwYXJpdHlCaXQsIGludCBmcmFjdGlvbiwgUm91bmRpbmdNb2RlIHJvdW5kaW5nTW9kZSkgeworICAgICAgICBpbnQgaW5jcmVtZW50ID0gMDsgLy8gdGhlIGNhcnJ5IGFmdGVyIHJvdW5kaW5nCisKKyAgICAgICAgc3dpdGNoIChyb3VuZGluZ01vZGUpIHsKKyAgICAgICAgICAgIGNhc2UgVU5ORUNFU1NBUlk6CisgICAgICAgICAgICAgICAgaWYgKGZyYWN0aW9uICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFyaXRobWV0aWNFeGNlcHRpb24oIlJvdW5kaW5nIG5lY2Vzc2FyeSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgVVA6CisgICAgICAgICAgICAgICAgaW5jcmVtZW50ID0gSW50ZWdlci5zaWdudW0oZnJhY3Rpb24pOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBET1dOOgorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBDRUlMSU5HOgorICAgICAgICAgICAgICAgIGluY3JlbWVudCA9IE1hdGgubWF4KEludGVnZXIuc2lnbnVtKGZyYWN0aW9uKSwgMCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIEZMT09SOgorICAgICAgICAgICAgICAgIGluY3JlbWVudCA9IE1hdGgubWluKEludGVnZXIuc2lnbnVtKGZyYWN0aW9uKSwgMCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIEhBTEZfVVA6CisgICAgICAgICAgICAgICAgaWYgKE1hdGguYWJzKGZyYWN0aW9uKSA+PSA1KSB7CisgICAgICAgICAgICAgICAgICAgIGluY3JlbWVudCA9IEludGVnZXIuc2lnbnVtKGZyYWN0aW9uKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIEhBTEZfRE9XTjoKKyAgICAgICAgICAgICAgICBpZiAoTWF0aC5hYnMoZnJhY3Rpb24pID4gNSkgeworICAgICAgICAgICAgICAgICAgICBpbmNyZW1lbnQgPSBJbnRlZ2VyLnNpZ251bShmcmFjdGlvbik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBIQUxGX0VWRU46CisgICAgICAgICAgICAgICAgaWYgKE1hdGguYWJzKGZyYWN0aW9uKSArIHBhcml0eUJpdCA+IDUpIHsKKyAgICAgICAgICAgICAgICAgICAgaW5jcmVtZW50ID0gSW50ZWdlci5zaWdudW0oZnJhY3Rpb24pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW5jcmVtZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHtAY29kZSBpbnRWYWx9IGhhcyBhIGZyYWN0aW9uYWwgcGFydCB0aHJvd3MgYW4gZXhjZXB0aW9uLAorICAgICAqIG90aGVyd2lzZSBpdCBjb3VudHMgdGhlIG51bWJlciBvZiBiaXRzIG9mIHZhbHVlIGFuZCBjaGVja3MgaWYgaXQncyBvdXQgb2YKKyAgICAgKiB0aGUgcmFuZ2Ugb2YgdGhlIHByaW1pdGl2ZSB0eXBlLiBJZiB0aGUgbnVtYmVyIGZpdHMgaW4gdGhlIHByaW1pdGl2ZSB0eXBlCisgICAgICogcmV0dXJucyB0aGlzIG51bWJlciBhcyB7QGNvZGUgbG9uZ30sIG90aGVyd2lzZSB0aHJvd3MgYW4KKyAgICAgKiBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYml0TGVuZ3RoT2ZUeXBlCisgICAgICogICAgICAgICAgICBudW1iZXIgb2YgYml0cyBvZiB0aGUgdHlwZSB3aG9zZSB2YWx1ZSB3aWxsIGJlIGNhbGN1bGF0ZWQKKyAgICAgKiAgICAgICAgICAgIGV4YWN0bHkKKyAgICAgKiBAcmV0dXJuIHRoZSBleGFjdCB2YWx1ZSBvZiB0aGUgaW50ZWdlciBwYXJ0IG9mIHtAY29kZSBCaWdEZWNpbWFsfQorICAgICAqICAgICAgICAgd2hlbiBpcyBwb3NzaWJsZQorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbiB3aGVuIHJvdW5kaW5nIGlzIG5lY2Vzc2FyeSBvciB0aGUKKyAgICAgKiAgICAgICAgICAgICBudW1iZXIgZG9uJ3QgZml0IGluIHRoZSBwcmltaXRpdmUgdHlwZQorICAgICAqLworICAgIHByaXZhdGUgbG9uZyB2YWx1ZUV4YWN0KGludCBiaXRMZW5ndGhPZlR5cGUpIHsKKyAgICAgICAgQmlnSW50ZWdlciBiaWdJbnRlZ2VyID0gdG9CaWdJbnRlZ2VyRXhhY3QoKTsKKworICAgICAgICBpZiAoYmlnSW50ZWdlci5iaXRMZW5ndGgoKSA8IGJpdExlbmd0aE9mVHlwZSkgeworICAgICAgICAgICAgLy8gSXQgZml0cyBpbiB0aGUgcHJpbWl0aXZlIHR5cGUKKyAgICAgICAgICAgIHJldHVybiBiaWdJbnRlZ2VyLmxvbmdWYWx1ZSgpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBBcml0aG1ldGljRXhjZXB0aW9uKCJSb3VuZGluZyBuZWNlc3NhcnkiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgcHJlY2lzaW9uIGFscmVhZHkgd2FzIGNhbGN1bGF0ZWQgaXQgcmV0dXJucyB0aGF0IHZhbHVlLCBvdGhlcndpc2UKKyAgICAgKiBpdCBjYWxjdWxhdGVzIGEgdmVyeSBnb29kIGFwcHJveGltYXRpb24gZWZmaWNpZW50bHkgLiBOb3RlIHRoYXQgdGhpcworICAgICAqIHZhbHVlIHdpbGwgYmUge0Bjb2RlIHByZWNpc2lvbigpfSBvciB7QGNvZGUgcHJlY2lzaW9uKCktMX0KKyAgICAgKiBpbiB0aGUgd29yc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXBwcm94aW1hdGlvbiBvZiB7QGNvZGUgcHJlY2lzaW9uKCl9IHZhbHVlCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgYXBwcm94UHJlY2lzaW9uKCkgeworICAgICAgICByZXR1cm4gcHJlY2lzaW9uID4gMAorICAgICAgICAgICAgICAgID8gcHJlY2lzaW9uCisgICAgICAgICAgICAgICAgOiAoaW50KSAoKHRoaXMuYml0TGVuZ3RoIC0gMSkgKiBMT0cxMF8yKSArIDE7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHNhZmVMb25nVG9JbnQobG9uZyBsb25nVmFsdWUpIHsKKyAgICAgICAgaWYgKGxvbmdWYWx1ZSA8IEludGVnZXIuTUlOX1ZBTFVFIHx8IGxvbmdWYWx1ZSA+IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJpdGhtZXRpY0V4Y2VwdGlvbigiT3V0IG9mIGludCByYW5nZTogIiArIGxvbmdWYWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChpbnQpIGxvbmdWYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJdCByZXR1cm5zIHRoZSB2YWx1ZSAwIHdpdGggdGhlIG1vc3QgYXBwcm94aW1hdGVkIHNjYWxlIG9mIHR5cGUKKyAgICAgKiB7QGNvZGUgaW50fS4gaWYge0Bjb2RlIGxvbmdTY2FsZSA+IEludGVnZXIuTUFYX1ZBTFVFfSB0aGUKKyAgICAgKiBzY2FsZSB3aWxsIGJlIHtAY29kZSBJbnRlZ2VyLk1BWF9WQUxVRX07IGlmCisgICAgICoge0Bjb2RlIGxvbmdTY2FsZSA8IEludGVnZXIuTUlOX1ZBTFVFfSB0aGUgc2NhbGUgd2lsbCBiZQorICAgICAqIHtAY29kZSBJbnRlZ2VyLk1JTl9WQUxVRX07IG90aGVyd2lzZSB7QGNvZGUgbG9uZ1NjYWxlfSBpcworICAgICAqIGNhc3RlZCB0byB0aGUgdHlwZSB7QGNvZGUgaW50fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb25nU2NhbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzY2FsZSB0byB3aGljaCB0aGUgdmFsdWUgMCB3aWxsIGJlIHNjYWxlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSAwIHNjYWxlZCBieSB0aGUgY2xvc2VyIHNjYWxlIG9mIHR5cGUge0Bjb2RlIGludH0uCisgICAgICogQHNlZSAjc2NhbGUKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBCaWdEZWNpbWFsIHplcm9TY2FsZWRCeShsb25nIGxvbmdTY2FsZSkgeworICAgICAgICBpZiAobG9uZ1NjYWxlID09IChpbnQpIGxvbmdTY2FsZSkgeworICAgICAgICAgICAgcmV0dXJuIHZhbHVlT2YoMCwoaW50KWxvbmdTY2FsZSk7CisgICAgICAgICAgICB9CisgICAgICAgIGlmIChsb25nU2NhbGUgPj0gMCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBCaWdEZWNpbWFsKCAwLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBCaWdEZWNpbWFsKCAwLCBJbnRlZ2VyLk1JTl9WQUxVRSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzaWducyBhbGwgdHJhbnNpZW50IGZpZWxkcyB1cG9uIGRlc2VyaWFsaXphdGlvbiBvZiBhCisgICAgICoge0Bjb2RlIEJpZ0RlY2ltYWx9IGluc3RhbmNlIChiaXRMZW5ndGggYW5kIHNtYWxsVmFsdWUpLiBUaGUgdHJhbnNpZW50CisgICAgICogZmllbGQgcHJlY2lzaW9uIGlzIGFzc2lnbmVkIGxhemlseS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIGluLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisKKyAgICAgICAgdGhpcy5iaXRMZW5ndGggPSBpbnRWYWwuYml0TGVuZ3RoKCk7CisgICAgICAgIGlmICh0aGlzLmJpdExlbmd0aCA8IDY0KSB7CisgICAgICAgICAgICB0aGlzLnNtYWxsVmFsdWUgPSBpbnRWYWwubG9uZ1ZhbHVlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmVwYXJlcyB0aGlzIHtAY29kZSBCaWdEZWNpbWFsfSBmb3Igc2VyaWFsaXphdGlvbiwgaS5lLiB0aGUKKyAgICAgKiBub24tdHJhbnNpZW50IGZpZWxkIHtAY29kZSBpbnRWYWx9IGlzIGFzc2lnbmVkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBnZXRVbnNjYWxlZFZhbHVlKCk7CisgICAgICAgIG91dC5kZWZhdWx0V3JpdGVPYmplY3QoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIEJpZ0ludGVnZXIgZ2V0VW5zY2FsZWRWYWx1ZSgpIHsKKyAgICAgICAgaWYoaW50VmFsID09IG51bGwpIHsKKyAgICAgICAgICAgIGludFZhbCA9IEJpZ0ludGVnZXIudmFsdWVPZihzbWFsbFZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW50VmFsOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzZXRVbnNjYWxlZFZhbHVlKEJpZ0ludGVnZXIgdW5zY2FsZWRWYWx1ZSkgeworICAgICAgICB0aGlzLmludFZhbCA9IHVuc2NhbGVkVmFsdWU7CisgICAgICAgIHRoaXMuYml0TGVuZ3RoID0gdW5zY2FsZWRWYWx1ZS5iaXRMZW5ndGgoKTsKKyAgICAgICAgaWYodGhpcy5iaXRMZW5ndGggPCA2NCkgeworICAgICAgICAgICAgdGhpcy5zbWFsbFZhbHVlID0gdW5zY2FsZWRWYWx1ZS5sb25nVmFsdWUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGludCBiaXRMZW5ndGgobG9uZyBzbWFsbFZhbHVlKSB7CisgICAgICAgIGlmKHNtYWxsVmFsdWUgPCAwKSB7CisgICAgICAgICAgICBzbWFsbFZhbHVlID0gfnNtYWxsVmFsdWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDY0IC0gTG9uZy5udW1iZXJPZkxlYWRpbmdaZXJvcyhzbWFsbFZhbHVlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgYml0TGVuZ3RoKGludCBzbWFsbFZhbHVlKSB7CisgICAgICAgIGlmKHNtYWxsVmFsdWUgPCAwKSB7CisgICAgICAgICAgICBzbWFsbFZhbHVlID0gfnNtYWxsVmFsdWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDMyIC0gSW50ZWdlci5udW1iZXJPZkxlYWRpbmdaZXJvcyhzbWFsbFZhbHVlKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL21hdGgvQmlnSW50LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9tYXRoL0JpZ0ludC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE3Njg2NzYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9tYXRoL0JpZ0ludC5qYXZhCkBAIC0wLDAgKzEsMzkwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm1hdGg7CisKKy8qCisgKiBJbiBjb250cmFzdCB0byBCaWdJbnRlZ2VycyB0aGlzIGNsYXNzIGRvZXNuJ3QgZmFrZSB0d28ncyBjb21wbGVtZW50IHJlcHJlc2VudGF0aW9uLgorICogQW55IEJpdC1PcGVyYXRpb25zLCBpbmNsdWRpbmcgU2hpZnRpbmcsIHNvbGVseSByZWdhcmQgdGhlIHVuc2lnbmVkIG1hZ25pdHVkZS4KKyAqIE1vcmVvdmVyIEJpZ0ludCBvYmplY3RzIGFyZSBtdXRhYmxlIGFuZCBvZmZlciBlZmZpY2llbnQgaW4tcGxhY2Utb3BlcmF0aW9ucy4KKyAqLworZmluYWwgY2xhc3MgQmlnSW50IHsKKworICAgIC8qIEZpZWxkcyB1c2VkIGZvciB0aGUgaW50ZXJuYWwgcmVwcmVzZW50YXRpb24uICovCisgICAgdHJhbnNpZW50IGludCBiaWdudW0gPSAwOworCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAodGhpcy5iaWdudW0gIT0gMCkgeworICAgICAgICAgICAgICAgIE5hdGl2ZUJOLkJOX2ZyZWUodGhpcy5iaWdudW0pOworICAgICAgICAgICAgICAgIHRoaXMuYmlnbnVtID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHN1cGVyLmZpbmFsaXplKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gdGhpcy5kZWNTdHJpbmcoKTsKKyAgICB9CisKKyAgICBpbnQgZ2V0TmF0aXZlQklHTlVNKCkgeworICAgICAgICByZXR1cm4gdGhpcy5iaWdudW07CisgICAgfQorCisgICAgc3RhdGljIGludCBjb25zdW1lRXJyb3JzKFN0cmluZ0J1aWxkZXIgc2IpIHsKKyAgICAgICAgaW50IGNudCA9IDA7CisgICAgICAgIGludCBlLCByZWFzb247CisgICAgICAgIHdoaWxlICgoZSA9IE5hdGl2ZUJOLkVSUl9nZXRfZXJyb3IoKSkgIT0gMCkgeworICAgICAgICAgICAgcmVhc29uID0gZSAmIDI1NTsKKyAgICAgICAgICAgIGlmIChyZWFzb24gPT0gMTAzKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFyaXRobWV0aWNFeGNlcHRpb24oIkJpZ0ludGVnZXIgZGl2aXNpb24gYnkgemVybyIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHJlYXNvbiA9PSAxMDgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXJpdGhtZXRpY0V4Y2VwdGlvbigiQmlnSW50ZWdlciBub3QgaW52ZXJ0aWJsZSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHJlYXNvbiA9PSA2NSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBPdXRPZk1lbW9yeUVycm9yKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzYi5hcHBlbmQoZSkuYXBwZW5kKCI6ICIpOworICAgICAgICAgICAgU3RyaW5nIHMgPSBOYXRpdmVCTi5FUlJfZXJyb3Jfc3RyaW5nKGUpOworICAgICAgICAgICAgc2IuYXBwZW5kKHMpOworICAgICAgICAgICAgY250Kys7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNudDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIENoZWNrKGJvb2xlYW4gc3VjY2VzcykgeworICAgICAgICBpZiAoIXN1Y2Nlc3MpIHsKKyAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiKG9wZW5zc2wpRVJSOiAiKTsKKyAgICAgICAgICAgIGludCBjbnQgPSBjb25zdW1lRXJyb3JzKHNiKTsKKyAgICAgICAgICAgIGlmIChjbnQgPiAwKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBBcml0aG1ldGljRXhjZXB0aW9uKHNiLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisKKyAgICBwcml2YXRlIHZvaWQgbWFrZVZhbGlkKCkgeworICAgICAgICBpZiAodGhpcy5iaWdudW0gPT0gMCkgeworICAgICAgICAgICAgdGhpcy5iaWdudW0gPSBOYXRpdmVCTi5CTl9uZXcoKTsKKyAgICAgICAgICAgIENoZWNrKHRoaXMuYmlnbnVtICE9IDApOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgQmlnSW50IG5ld0JpZ0ludCgpIHsKKyAgICAgICAgQmlnSW50IGJpID0gbmV3IEJpZ0ludCgpOworICAgICAgICBiaS5iaWdudW0gPSBOYXRpdmVCTi5CTl9uZXcoKTsKKyAgICAgICAgQ2hlY2soYmkuYmlnbnVtICE9IDApOworICAgICAgICByZXR1cm4gYmk7CisgICAgfQorCisKKyAgICBzdGF0aWMgaW50IGNtcChCaWdJbnQgYSwgQmlnSW50IGIpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUJOLkJOX2NtcChhLmJpZ251bSwgYi5iaWdudW0pOworICAgIH0KKworCisgICAgdm9pZCBwdXRDb3B5KEJpZ0ludCBmcm9tKSB7CisgICAgICAgIHRoaXMubWFrZVZhbGlkKCk7CisgICAgICAgIENoZWNrKE5hdGl2ZUJOLkJOX2NvcHkodGhpcy5iaWdudW0sIGZyb20uYmlnbnVtKSk7CisgICAgfQorCisgICAgQmlnSW50IGNvcHkoKSB7CisgICAgICAgIEJpZ0ludCBiaSA9IG5ldyBCaWdJbnQoKTsKKyAgICAgICAgYmkucHV0Q29weSh0aGlzKTsKKyAgICAgICAgcmV0dXJuIGJpOworICAgIH0KKworCisgICAgdm9pZCBwdXRMb25nSW50KGxvbmcgdmFsKSB7CisgICAgICAgIHRoaXMubWFrZVZhbGlkKCk7CisgICAgICAgIENoZWNrKE5hdGl2ZUJOLnB1dExvbmdJbnQodGhpcy5iaWdudW0sIHZhbCkpOworICAgIH0KKworICAgIHZvaWQgcHV0VUxvbmdJbnQobG9uZyB2YWwsIGJvb2xlYW4gbmVnKSB7CisgICAgICAgIHRoaXMubWFrZVZhbGlkKCk7CisgICAgICAgIENoZWNrKE5hdGl2ZUJOLnB1dFVMb25nSW50KHRoaXMuYmlnbnVtLCB2YWwsIG5lZykpOworICAgIH0KKworICAgIHByaXZhdGUgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGludmFsaWRCaWdJbnRlZ2VyKFN0cmluZyBzKSB7CisgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oIkludmFsaWQgQmlnSW50ZWdlcjogIiArIHMpOworICAgIH0KKworICAgIHZvaWQgcHV0RGVjU3RyaW5nKFN0cmluZyBvcmlnaW5hbCkgeworICAgICAgICBTdHJpbmcgcyA9IGNoZWNrU3RyaW5nKG9yaWdpbmFsLCAxMCk7CisgICAgICAgIHRoaXMubWFrZVZhbGlkKCk7CisgICAgICAgIGludCB1c2VkTGVuID0gTmF0aXZlQk4uQk5fZGVjMmJuKHRoaXMuYmlnbnVtLCBzKTsKKyAgICAgICAgQ2hlY2soKHVzZWRMZW4gPiAwKSk7CisgICAgICAgIGlmICh1c2VkTGVuIDwgcy5sZW5ndGgoKSkgeworICAgICAgICAgICAgdGhyb3cgaW52YWxpZEJpZ0ludGVnZXIob3JpZ2luYWwpOworICAgICAgICB9CisgICAgfQorCisgICAgdm9pZCBwdXRIZXhTdHJpbmcoU3RyaW5nIG9yaWdpbmFsKSB7CisgICAgICAgIFN0cmluZyBzID0gY2hlY2tTdHJpbmcob3JpZ2luYWwsIDE2KTsKKyAgICAgICAgdGhpcy5tYWtlVmFsaWQoKTsKKyAgICAgICAgaW50IHVzZWRMZW4gPSBOYXRpdmVCTi5CTl9oZXgyYm4odGhpcy5iaWdudW0sIHMpOworICAgICAgICBDaGVjaygodXNlZExlbiA+IDApKTsKKyAgICAgICAgaWYgKHVzZWRMZW4gPCBzLmxlbmd0aCgpKSB7CisgICAgICAgICAgICB0aHJvdyBpbnZhbGlkQmlnSW50ZWdlcihvcmlnaW5hbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHN1aXRhYmxlIGZvciBwYXNzaW5nIHRvIE9wZW5TU0wuCisgICAgICogVGhyb3dzIGlmICdzJyBkb2Vzbid0IG1hdGNoIEphdmEncyBydWxlcyBmb3IgdmFsaWQgQmlnSW50ZWdlciBzdHJpbmdzLgorICAgICAqIEJOX2RlYzJibiBhbmQgQk5faGV4MmJuIGRvIHZlcnkgbGl0dGxlIGNoZWNraW5nLCBzbyB3ZSBuZWVkIHRvIG1hbnVhbGx5CisgICAgICogZW5zdXJlIHdlIGNvbXBseSB3aXRoIEphdmEncyBydWxlcy4KKyAgICAgKiBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTcwMzYKKyAgICAgKi8KKyAgICBTdHJpbmcgY2hlY2tTdHJpbmcoU3RyaW5nIHMsIGludCBiYXNlKSB7CisgICAgICAgIGlmIChzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIC8vIEEgdmFsaWQgYmlnIGludGVnZXIgY29uc2lzdHMgb2YgYW4gb3B0aW9uYWwgJy0nIG9yICcrJyBmb2xsb3dlZCBieQorICAgICAgICAvLyBvbmUgb3IgbW9yZSBkaWdpdCBjaGFyYWN0ZXJzIGFwcHJvcHJpYXRlIHRvIHRoZSBnaXZlbiBiYXNlLAorICAgICAgICAvLyBhbmQgbm8gb3RoZXIgY2hhcmFjdGVycy4KKyAgICAgICAgaW50IGNoYXJDb3VudCA9IHMubGVuZ3RoKCk7CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgaWYgKGNoYXJDb3VudCA+IDApIHsKKyAgICAgICAgICAgIGNoYXIgY2ggPSBzLmNoYXJBdCgwKTsKKyAgICAgICAgICAgIGlmIChjaCA9PSAnKycpIHsKKyAgICAgICAgICAgICAgICAvLyBKYXZhIHN1cHBvcnRzIGxlYWRpbmcgKywgYnV0IE9wZW5TU0wgZG9lc24ndCwgc28gd2UgbmVlZCB0byBzdHJpcCBpdC4KKyAgICAgICAgICAgICAgICBzID0gcy5zdWJzdHJpbmcoMSk7CisgICAgICAgICAgICAgICAgLS1jaGFyQ291bnQ7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09ICctJykgeworICAgICAgICAgICAgICAgICsraTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoY2hhckNvdW50IC0gaSA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBpbnZhbGlkQmlnSW50ZWdlcihzKTsKKyAgICAgICAgfQorICAgICAgICBib29sZWFuIG5vbkFzY2lpID0gZmFsc2U7CisgICAgICAgIGZvciAoOyBpIDwgY2hhckNvdW50OyArK2kpIHsKKyAgICAgICAgICAgIGNoYXIgY2ggPSBzLmNoYXJBdChpKTsKKyAgICAgICAgICAgIGlmIChDaGFyYWN0ZXIuZGlnaXQoY2gsIGJhc2UpID09IC0xKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgaW52YWxpZEJpZ0ludGVnZXIocyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY2ggPiAxMjgpIHsKKyAgICAgICAgICAgICAgICBub25Bc2NpaSA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5vbkFzY2lpID8gdG9Bc2NpaShzLCBiYXNlKSA6IHM7CisgICAgfQorCisgICAgLy8gSmF2YSBzdXBwb3J0cyBub24tQVNDSUkgZGVjaW1hbCBkaWdpdHMsIGJ1dCBPcGVuU1NMIGRvZXNuJ3QuCisgICAgLy8gV2UgbmVlZCB0byB0cmFuc2xhdGUgdGhlIGRlY2ltYWwgZGlnaXRzIGJ1dCBsZWF2ZSBhbnkgb3RoZXIgY2hhcmFjdGVycyBhbG9uZS4KKyAgICAvLyBUaGlzIG1ldGhvZCBhc3N1bWVzIGl0J3MgYmVpbmcgY2FsbGVkIG9uIGEgc3RyaW5nIHRoYXQgaGFzIGFscmVhZHkgYmVlbiB2YWxpZGF0ZWQuCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHRvQXNjaWkoU3RyaW5nIHMsIGludCBiYXNlKSB7CisgICAgICAgIGludCBsZW5ndGggPSBzLmxlbmd0aCgpOworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKGxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIGNoYXIgY2ggPSBzLmNoYXJBdChpKTsKKyAgICAgICAgICAgIGludCB2YWx1ZSA9IENoYXJhY3Rlci5kaWdpdChjaCwgYmFzZSk7CisgICAgICAgICAgICBpZiAodmFsdWUgPj0gMCAmJiB2YWx1ZSA8PSA5KSB7CisgICAgICAgICAgICAgICAgY2ggPSAoY2hhcikgKCcwJyArIHZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoY2gpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICB2b2lkIHB1dEJpZ0VuZGlhbihieXRlW10gYSwgYm9vbGVhbiBuZWcpIHsKKyAgICAgICAgdGhpcy5tYWtlVmFsaWQoKTsKKyAgICAgICAgQ2hlY2soTmF0aXZlQk4uQk5fYmluMmJuKGEsIGEubGVuZ3RoLCBuZWcsIHRoaXMuYmlnbnVtKSk7CisgICAgfQorCisgICAgdm9pZCBwdXRMaXR0bGVFbmRpYW5JbnRzKGludFtdIGEsIGJvb2xlYW4gbmVnKSB7CisgICAgICAgIHRoaXMubWFrZVZhbGlkKCk7CisgICAgICAgIENoZWNrKE5hdGl2ZUJOLmxpdEVuZEludHMyYm4oYSwgYS5sZW5ndGgsIG5lZywgdGhpcy5iaWdudW0pKTsKKyAgICB9CisKKyAgICB2b2lkIHB1dEJpZ0VuZGlhblR3b3NDb21wbGVtZW50KGJ5dGVbXSBhKSB7CisgICAgICAgIHRoaXMubWFrZVZhbGlkKCk7CisgICAgICAgIENoZWNrKE5hdGl2ZUJOLnR3b3NDb21wMmJuKGEsIGEubGVuZ3RoLCB0aGlzLmJpZ251bSkpOworICAgIH0KKworCisgICAgbG9uZyBsb25nSW50KCkgeworICAgICAgICByZXR1cm4gTmF0aXZlQk4ubG9uZ0ludCh0aGlzLmJpZ251bSk7CisgICAgfQorCisgICAgU3RyaW5nIGRlY1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUJOLkJOX2JuMmRlYyh0aGlzLmJpZ251bSk7CisgICAgfQorCisgICAgU3RyaW5nIGhleFN0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUJOLkJOX2JuMmhleCh0aGlzLmJpZ251bSk7CisgICAgfQorCisgICAgYnl0ZVtdIGJpZ0VuZGlhbk1hZ25pdHVkZSgpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUJOLkJOX2JuMmJpbih0aGlzLmJpZ251bSk7CisgICAgfQorCisgICAgaW50W10gbGl0dGxlRW5kaWFuSW50c01hZ25pdHVkZSgpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUJOLmJuMmxpdEVuZEludHModGhpcy5iaWdudW0pOworICAgIH0KKworICAgIGludCBzaWduKCkgeworICAgICAgICByZXR1cm4gTmF0aXZlQk4uc2lnbih0aGlzLmJpZ251bSk7CisgICAgfQorCisgICAgdm9pZCBzZXRTaWduKGludCB2YWwpIHsKKyAgICAgICAgaWYgKHZhbCA+IDApIHsKKyAgICAgICAgICAgIE5hdGl2ZUJOLkJOX3NldF9uZWdhdGl2ZSh0aGlzLmJpZ251bSwgMCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAodmFsIDwgMCkgTmF0aXZlQk4uQk5fc2V0X25lZ2F0aXZlKHRoaXMuYmlnbnVtLCAxKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGJvb2xlYW4gdHdvc0NvbXBGaXRzSW50b0J5dGVzKGludCBkZXNpcmVkQnl0ZUNvdW50KSB7CisgICAgICAgIGludCBhY3R1YWxCeXRlQ291bnQgPSAoTmF0aXZlQk4uYml0TGVuZ3RoKHRoaXMuYmlnbnVtKSArIDcpIC8gODsKKyAgICAgICAgcmV0dXJuIGFjdHVhbEJ5dGVDb3VudCA8PSBkZXNpcmVkQnl0ZUNvdW50OworICAgIH0KKworICAgIGludCBiaXRMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBOYXRpdmVCTi5iaXRMZW5ndGgodGhpcy5iaWdudW0pOworICAgIH0KKworICAgIGJvb2xlYW4gaXNCaXRTZXQoaW50IG4pIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUJOLkJOX2lzX2JpdF9zZXQodGhpcy5iaWdudW0sIG4pOworICAgIH0KKworICAgIC8vIG4gPiAwOiBzaGlmdCBsZWZ0IChtdWx0aXBseSkKKyAgICBzdGF0aWMgQmlnSW50IHNoaWZ0KEJpZ0ludCBhLCBpbnQgbikgeworICAgICAgICBCaWdJbnQgciA9IG5ld0JpZ0ludCgpOworICAgICAgICBDaGVjayhOYXRpdmVCTi5CTl9zaGlmdChyLmJpZ251bSwgYS5iaWdudW0sIG4pKTsKKyAgICAgICAgcmV0dXJuIHI7CisgICAgfQorCisgICAgdm9pZCBzaGlmdChpbnQgbikgeworICAgICAgICBDaGVjayhOYXRpdmVCTi5CTl9zaGlmdCh0aGlzLmJpZ251bSwgdGhpcy5iaWdudW0sIG4pKTsKKyAgICB9CisKKyAgICB2b2lkIGFkZFBvc2l0aXZlSW50KGludCB3KSB7CisgICAgICAgIENoZWNrKE5hdGl2ZUJOLkJOX2FkZF93b3JkKHRoaXMuYmlnbnVtLCB3KSk7CisgICAgfQorCisgICAgdm9pZCBtdWx0aXBseUJ5UG9zaXRpdmVJbnQoaW50IHcpIHsKKyAgICAgICAgQ2hlY2soTmF0aXZlQk4uQk5fbXVsX3dvcmQodGhpcy5iaWdudW0sIHcpKTsKKyAgICB9CisKKyAgICBzdGF0aWMgaW50IHJlbWFpbmRlckJ5UG9zaXRpdmVJbnQoQmlnSW50IGEsIGludCB3KSB7CisgICAgICAgIGludCByZW0gPSBOYXRpdmVCTi5CTl9tb2Rfd29yZChhLmJpZ251bSwgdyk7CisgICAgICAgIENoZWNrKHJlbSAhPSAtMSk7CisgICAgICAgIHJldHVybiByZW07CisgICAgfQorCisgICAgc3RhdGljIEJpZ0ludCBhZGRpdGlvbihCaWdJbnQgYSwgQmlnSW50IGIpIHsKKyAgICAgICAgQmlnSW50IHIgPSBuZXdCaWdJbnQoKTsKKyAgICAgICAgQ2hlY2soTmF0aXZlQk4uQk5fYWRkKHIuYmlnbnVtLCBhLmJpZ251bSwgYi5iaWdudW0pKTsKKyAgICAgICAgcmV0dXJuIHI7CisgICAgfQorCisgICAgdm9pZCBhZGQoQmlnSW50IGEpIHsKKyAgICAgICAgQ2hlY2soTmF0aXZlQk4uQk5fYWRkKHRoaXMuYmlnbnVtLCB0aGlzLmJpZ251bSwgYS5iaWdudW0pKTsKKyAgICB9CisKKyAgICBzdGF0aWMgQmlnSW50IHN1YnRyYWN0aW9uKEJpZ0ludCBhLCBCaWdJbnQgYikgeworICAgICAgICBCaWdJbnQgciA9IG5ld0JpZ0ludCgpOworICAgICAgICBDaGVjayhOYXRpdmVCTi5CTl9zdWIoci5iaWdudW0sIGEuYmlnbnVtLCBiLmJpZ251bSkpOworICAgICAgICByZXR1cm4gcjsKKyAgICB9CisKKworICAgIHN0YXRpYyBCaWdJbnQgZ2NkKEJpZ0ludCBhLCBCaWdJbnQgYikgeworICAgICAgICBCaWdJbnQgciA9IG5ld0JpZ0ludCgpOworICAgICAgICBDaGVjayhOYXRpdmVCTi5CTl9nY2Qoci5iaWdudW0sIGEuYmlnbnVtLCBiLmJpZ251bSkpOworICAgICAgICByZXR1cm4gcjsKKyAgICB9CisKKyAgICBzdGF0aWMgQmlnSW50IHByb2R1Y3QoQmlnSW50IGEsIEJpZ0ludCBiKSB7CisgICAgICAgIEJpZ0ludCByID0gbmV3QmlnSW50KCk7CisgICAgICAgIENoZWNrKE5hdGl2ZUJOLkJOX211bChyLmJpZ251bSwgYS5iaWdudW0sIGIuYmlnbnVtKSk7CisgICAgICAgIHJldHVybiByOworICAgIH0KKworICAgIHN0YXRpYyBCaWdJbnQgYmlnRXhwKEJpZ0ludCBhLCBCaWdJbnQgcCkgeworICAgICAgICAvLyBTaWduIG9mIHAgaXMgaWdub3JlZCEKKyAgICAgICAgQmlnSW50IHIgPSBuZXdCaWdJbnQoKTsKKyAgICAgICAgQ2hlY2soTmF0aXZlQk4uQk5fZXhwKHIuYmlnbnVtLCBhLmJpZ251bSwgcC5iaWdudW0pKTsKKyAgICAgICAgcmV0dXJuIHI7CisgICAgfQorCisgICAgc3RhdGljIEJpZ0ludCBleHAoQmlnSW50IGEsIGludCBwKSB7CisgICAgICAgIC8vIFNpZ24gb2YgcCBpcyBpZ25vcmVkIQorICAgICAgICBCaWdJbnQgcG93ZXIgPSBuZXcgQmlnSW50KCk7CisgICAgICAgIHBvd2VyLnB1dExvbmdJbnQocCk7CisgICAgICAgIHJldHVybiBiaWdFeHAoYSwgcG93ZXIpOworICAgICAgICAvLyBPUFRJT05BTDoKKyAgICAgICAgLy8gaW50IEJOX3NxcihCaWdJbnRlZ2VyIHIsIEJpZ0ludGVnZXIgYSwgQk5fQ1RYIGN0eCk7CisgICAgICAgIC8vIGludCBCTl9zcXIoQklHTlVNICpyLCBjb25zdCBCSUdOVU0gKmEsQk5fQ1RYICpjdHgpOworICAgIH0KKworICAgIHN0YXRpYyB2b2lkIGRpdmlzaW9uKEJpZ0ludCBkaXZpZGVuZCwgQmlnSW50IGRpdmlzb3IsCisgICAgICAgICAgICBCaWdJbnQgcXVvdGllbnQsIEJpZ0ludCByZW1haW5kZXIpIHsKKyAgICAgICAgaW50IHF1b3QsIHJlbTsKKyAgICAgICAgaWYgKHF1b3RpZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHF1b3RpZW50Lm1ha2VWYWxpZCgpOworICAgICAgICAgICAgcXVvdCA9IHF1b3RpZW50LmJpZ251bTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHF1b3QgPSAwOworICAgICAgICB9CisgICAgICAgIGlmIChyZW1haW5kZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVtYWluZGVyLm1ha2VWYWxpZCgpOworICAgICAgICAgICAgcmVtID0gcmVtYWluZGVyLmJpZ251bTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlbSA9IDA7CisgICAgICAgIH0KKyAgICAgICAgQ2hlY2soTmF0aXZlQk4uQk5fZGl2KHF1b3QsIHJlbSwgZGl2aWRlbmQuYmlnbnVtLCBkaXZpc29yLmJpZ251bSkpOworICAgIH0KKworICAgIHN0YXRpYyBCaWdJbnQgbW9kdWx1cyhCaWdJbnQgYSwgQmlnSW50IG0pIHsKKyAgICAgICAgLy8gU2lnbiBvZiBwIGlzIGlnbm9yZWQhID8KKyAgICAgICAgQmlnSW50IHIgPSBuZXdCaWdJbnQoKTsKKyAgICAgICAgQ2hlY2soTmF0aXZlQk4uQk5fbm5tb2Qoci5iaWdudW0sIGEuYmlnbnVtLCBtLmJpZ251bSkpOworICAgICAgICByZXR1cm4gcjsKKyAgICB9CisKKyAgICBzdGF0aWMgQmlnSW50IG1vZEV4cChCaWdJbnQgYSwgQmlnSW50IHAsIEJpZ0ludCBtKSB7CisgICAgICAgIC8vIFNpZ24gb2YgcCBpcyBpZ25vcmVkIQorICAgICAgICBCaWdJbnQgciA9IG5ld0JpZ0ludCgpOworICAgICAgICBDaGVjayhOYXRpdmVCTi5CTl9tb2RfZXhwKHIuYmlnbnVtLCBhLmJpZ251bSwgcC5iaWdudW0sIG0uYmlnbnVtKSk7CisKKyAgICAgICAgLy8gT1BUSU9OQUw6CisgICAgICAgIC8vIGludCBCTl9tb2Rfc3FyKEJJR05VTSAqciwgY29uc3QgQklHTlVNICphLCBjb25zdCBCSUdOVU0gKm0sIEJOX0NUWCAqY3R4KTsKKyAgICAgICAgcmV0dXJuIHI7CisgICAgfQorCisKKyAgICBzdGF0aWMgQmlnSW50IG1vZEludmVyc2UoQmlnSW50IGEsIEJpZ0ludCBtKSB7CisgICAgICAgIEJpZ0ludCByID0gbmV3QmlnSW50KCk7CisgICAgICAgIENoZWNrKE5hdGl2ZUJOLkJOX21vZF9pbnZlcnNlKHIuYmlnbnVtLCBhLmJpZ251bSwgbS5iaWdudW0pKTsKKyAgICAgICAgcmV0dXJuIHI7CisgICAgfQorCisKKyAgICBzdGF0aWMgQmlnSW50IGdlbmVyYXRlUHJpbWVEZWZhdWx0KGludCBiaXRMZW5ndGgpIHsKKyAgICAgICAgQmlnSW50IHIgPSBuZXdCaWdJbnQoKTsKKyAgICAgICAgQ2hlY2soTmF0aXZlQk4uQk5fZ2VuZXJhdGVfcHJpbWVfZXgoci5iaWdudW0sIGJpdExlbmd0aCwgZmFsc2UsIDAsIDAsIDApKTsKKyAgICAgICAgcmV0dXJuIHI7CisgICAgfQorCisgICAgYm9vbGVhbiBpc1ByaW1lKGludCBjZXJ0YWludHkpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUJOLkJOX2lzX3ByaW1lX2V4KGJpZ251bSwgY2VydGFpbnR5LCAwKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9tYXRoL0JpZ0ludGVnZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL21hdGgvQmlnSW50ZWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU1OGJmZDUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9tYXRoL0JpZ0ludGVnZXIuamF2YQpAQCAtMCwwICsxLDEyMjMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5tYXRoOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CisKKy8qKgorICogQW4gaW1tdXRhYmxlIHNpZ25lZCBpbnRlZ2VyIG9mIGFyYml0cmFyeSBtYWduaXR1ZGUuCisgKgorICogPGgzPkZhc3QgQ3J5cHRvZ3JhcGh5PC9oMz4KKyAqIFRoaXMgaW1wbGVtZW50YXRpb24gaXMgZWZmaWNpZW50IGZvciBvcGVyYXRpb25zIHRyYWRpdGlvbmFsbHkgdXNlZCBpbgorICogY3J5cHRvZ3JhcGh5LCBzdWNoIGFzIHRoZSBnZW5lcmF0aW9uIG9mIGxhcmdlIHByaW1lIG51bWJlcnMgYW5kIGNvbXB1dGF0aW9uCisgKiBvZiB0aGUgbW9kdWxhciBpbnZlcnNlLgorICoKKyAqIDxoMz5TbG93IFR3bydzIENvbXBsZW1lbnQgQml0d2lzZSBPcGVyYXRpb25zPC9oMz4KKyAqIFRoaXMgQVBJIGluY2x1ZGVzIG9wZXJhdGlvbnMgZm9yIGJpdHdpc2Ugb3BlcmF0aW9ucyBpbiB0d28ncyBjb21wbGVtZW50CisgKiByZXByZXNlbnRhdGlvbi4gVHdvJ3MgY29tcGxlbWVudCBpcyBub3QgdGhlIGludGVybmFsIHJlcHJlc2VudGF0aW9uIHVzZWQgYnkKKyAqIHRoaXMgaW1wbGVtZW50YXRpb24sIHNvIHN1Y2ggbWV0aG9kcyBtYXkgYmUgaW5lZmZpY2llbnQuIFVzZSB7QGxpbmsKKyAqIGphdmEudXRpbC5CaXRTZXR9IGZvciBoaWdoLXBlcmZvcm1hbmNlIGJpdHdpc2Ugb3BlcmF0aW9ucyBvbgorICogYXJiaXRyYXJpbHktbGFyZ2Ugc2VxdWVuY2VzIG9mIGJpdHMuCisgKi8KK3B1YmxpYyBjbGFzcyBCaWdJbnRlZ2VyIGV4dGVuZHMgTnVtYmVyCisgICAgICAgIGltcGxlbWVudHMgQ29tcGFyYWJsZTxCaWdJbnRlZ2VyPiwgU2VyaWFsaXphYmxlIHsKKworICAgIC8qKiBUaGlzIGlzIHRoZSBzZXJpYWxWZXJzaW9uVUlEIHVzZWQgYnkgdGhlIHN1biBpbXBsZW1lbnRhdGlvbi4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODI4NzU3NDI1NTkzNjQ3MjI5MUw7CisKKyAgICBwcml2YXRlIHRyYW5zaWVudCBCaWdJbnQgYmlnSW50OworCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgYm9vbGVhbiBuYXRpdmVJc1ZhbGlkID0gZmFsc2U7CisKKyAgICBwcml2YXRlIHRyYW5zaWVudCBib29sZWFuIGphdmFJc1ZhbGlkID0gZmFsc2U7CisKKyAgICAvKiogVGhlIG1hZ25pdHVkZSBvZiB0aGlzIGluIHRoZSBsaXR0bGUtZW5kaWFuIHJlcHJlc2VudGF0aW9uLiAqLworICAgIHRyYW5zaWVudCBpbnRbXSBkaWdpdHM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbGVuZ3RoIG9mIHRoaXMgaW4gbWVhc3VyZWQgaW4gaW50cy4gQ2FuIGJlIGxlc3MgdGhhbgorICAgICAqIGRpZ2l0cy5sZW5ndGgoKS4KKyAgICAgKi8KKyAgICB0cmFuc2llbnQgaW50IG51bWJlckxlbmd0aDsKKworICAgIC8qKiBUaGUgc2lnbiBvZiB0aGlzLiAqLworICAgIHRyYW5zaWVudCBpbnQgc2lnbjsKKworICAgIC8qKiBUaGUge0Bjb2RlIEJpZ0ludGVnZXJ9IGNvbnN0YW50IDAuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBCaWdJbnRlZ2VyIFpFUk8gPSBuZXcgQmlnSW50ZWdlcigwLCAwKTsKKworICAgIC8qKiBUaGUge0Bjb2RlIEJpZ0ludGVnZXJ9IGNvbnN0YW50IDEuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBCaWdJbnRlZ2VyIE9ORSA9IG5ldyBCaWdJbnRlZ2VyKDEsIDEpOworCisgICAgLyoqIFRoZSB7QGNvZGUgQmlnSW50ZWdlcn0gY29uc3RhbnQgMTAuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBCaWdJbnRlZ2VyIFRFTiA9IG5ldyBCaWdJbnRlZ2VyKDEsIDEwKTsKKworICAgIC8qKiBUaGUge0Bjb2RlIEJpZ0ludGVnZXJ9IGNvbnN0YW50IC0xLiAqLworICAgIHN0YXRpYyBmaW5hbCBCaWdJbnRlZ2VyIE1JTlVTX09ORSA9IG5ldyBCaWdJbnRlZ2VyKC0xLCAxKTsKKworICAgIC8qKiBBbGwgdGhlIHtAY29kZSBCaWdJbnRlZ2VyfSBudW1iZXJzIGluIHRoZSByYW5nZSBbMCwxMF0gYXJlIGNhY2hlZC4gKi8KKyAgICBzdGF0aWMgZmluYWwgQmlnSW50ZWdlcltdIFNNQUxMX1ZBTFVFUyA9IHsgWkVSTywgT05FLCBuZXcgQmlnSW50ZWdlcigxLCAyKSwKKyAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKDEsIDMpLCBuZXcgQmlnSW50ZWdlcigxLCA0KSwgbmV3IEJpZ0ludGVnZXIoMSwgNSksCisgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigxLCA2KSwgbmV3IEJpZ0ludGVnZXIoMSwgNyksIG5ldyBCaWdJbnRlZ2VyKDEsIDgpLAorICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoMSwgOSksIFRFTiB9OworCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IGZpcnN0Tm9uemVyb0RpZ2l0ID0gLTI7CisKKyAgICAvKiogc2lnbiBmaWVsZCwgdXNlZCBmb3Igc2VyaWFsaXphdGlvbi4gKi8KKyAgICBwcml2YXRlIGludCBzaWdudW07CisKKyAgICAvKiogYWJzb2x1dGUgdmFsdWUgZmllbGQsIHVzZWQgZm9yIHNlcmlhbGl6YXRpb24gKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBtYWduaXR1ZGU7CisKKyAgICAvKiogQ2FjaGUgZm9yIHRoZSBoYXNoIGNvZGUuICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IGhhc2hDb2RlID0gMDsKKworICAgIEJpZ0ludGVnZXIoQmlnSW50IGJpZ0ludCkgeworICAgICAgICBpZiAoYmlnSW50ID09IG51bGwgfHwgYmlnSW50LmdldE5hdGl2ZUJJR05VTSgpID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgICAgICB9CisgICAgICAgIHNldEJpZ0ludChiaWdJbnQpOworICAgIH0KKworICAgIEJpZ0ludGVnZXIoaW50IHNpZ24sIGxvbmcgdmFsdWUpIHsKKyAgICAgICAgQmlnSW50IGJpZ0ludCA9IG5ldyBCaWdJbnQoKTsKKyAgICAgICAgYmlnSW50LnB1dFVMb25nSW50KHZhbHVlLCAoc2lnbiA8IDApKTsKKyAgICAgICAgc2V0QmlnSW50KGJpZ0ludCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG51bWJlciB3aXRob3V0IGNyZWF0aW5nIG5ldyBzcGFjZS4gVGhpcyBjb25zdHJ1Y3Qgc2hvdWxkIGJlCisgICAgICogdXNlZCBvbmx5IGlmIHRoZSB0aHJlZSBmaWVsZHMgb2YgcmVwcmVzZW50YXRpb24gYXJlIGtub3duLgorICAgICAqCisgICAgICogQHBhcmFtIHNpZ24gdGhlIHNpZ24gb2YgdGhlIG51bWJlci4KKyAgICAgKiBAcGFyYW0gbnVtYmVyTGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIGludGVybmFsIGFycmF5LgorICAgICAqIEBwYXJhbSBkaWdpdHMgYSByZWZlcmVuY2Ugb2Ygc29tZSBhcnJheSBjcmVhdGVkIGJlZm9yZS4KKyAgICAgKi8KKyAgICBCaWdJbnRlZ2VyKGludCBzaWduLCBpbnQgbnVtYmVyTGVuZ3RoLCBpbnRbXSBkaWdpdHMpIHsKKyAgICAgICAgc2V0SmF2YVJlcHJlc2VudGF0aW9uKHNpZ24sIG51bWJlckxlbmd0aCwgZGlnaXRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgcmFuZG9tIG5vbi1uZWdhdGl2ZSB7QGNvZGUgQmlnSW50ZWdlcn0gaW5zdGFuY2UgaW4gdGhlIHJhbmdlCisgICAgICoge0Bjb2RlIFswLCBwb3coMiwgbnVtQml0cyktMV19LgorICAgICAqCisgICAgICogQHBhcmFtIG51bUJpdHMgbWF4aW11bSBsZW5ndGggb2YgdGhlIG5ldyB7QGNvZGUgQmlnSW50ZWdlcn0gaW4gYml0cy4KKyAgICAgKiBAcGFyYW0gcmFuZG9tIGlzIHRoZSByYW5kb20gbnVtYmVyIGdlbmVyYXRvciB0byBiZSB1c2VkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBudW1CaXRzfSA8IDAuCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIoaW50IG51bUJpdHMsIFJhbmRvbSByYW5kb20pIHsKKyAgICAgICAgaWYgKG51bUJpdHMgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJudW1CaXRzIDwgMDogIiArIG51bUJpdHMpOworICAgICAgICB9CisgICAgICAgIGlmIChudW1CaXRzID09IDApIHsKKyAgICAgICAgICAgIHNldEphdmFSZXByZXNlbnRhdGlvbigwLCAxLCBuZXcgaW50W10geyAwIH0pOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW50IHNpZ24gPSAxOworICAgICAgICAgICAgaW50IG51bWJlckxlbmd0aCA9IChudW1CaXRzICsgMzEpID4+IDU7CisgICAgICAgICAgICBpbnRbXSBkaWdpdHMgPSBuZXcgaW50W251bWJlckxlbmd0aF07CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bWJlckxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgZGlnaXRzW2ldID0gcmFuZG9tLm5leHRJbnQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIFVzaW5nIG9ubHkgdGhlIG5lY2Vzc2FyeSBiaXRzCisgICAgICAgICAgICBkaWdpdHNbbnVtYmVyTGVuZ3RoIC0gMV0gPj4+PSAoLW51bUJpdHMpICYgMzE7CisgICAgICAgICAgICBzZXRKYXZhUmVwcmVzZW50YXRpb24oc2lnbiwgbnVtYmVyTGVuZ3RoLCBkaWdpdHMpOworICAgICAgICB9CisgICAgICAgIGphdmFJc1ZhbGlkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgcmFuZG9tIHtAY29kZSBCaWdJbnRlZ2VyfSBpbnN0YW5jZSBpbiB0aGUgcmFuZ2Uge0Bjb2RlIFswLAorICAgICAqIHBvdygyLCBiaXRMZW5ndGgpLTFdfSB3aGljaCBpcyBwcm9iYWJseSBwcmltZS4gVGhlIHByb2JhYmlsaXR5IHRoYXQgdGhlCisgICAgICogcmV0dXJuZWQge0Bjb2RlIEJpZ0ludGVnZXJ9IGlzIHByaW1lIGlzIGJleW9uZAorICAgICAqIHtAY29kZSAxIC0gMS9wb3coMiwgY2VydGFpbnR5KX0uCisgICAgICoKKyAgICAgKiA8cD48Yj5JbXBsZW1lbnRhdGlvbiBOb3RlOjwvYj4gdGhlIHtAY29kZSBSYW5kb219IGFyZ3VtZW50IGlzIGlnbm9yZWQuCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIE9wZW5TU0wncyB7QGNvZGUgYm5fcmFuZH0gYXMgYSBzb3VyY2Ugb2YKKyAgICAgKiBjcnlwdG9ncmFwaGljYWxseSBzdHJvbmcgcHNldWRvLXJhbmRvbSBudW1iZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGJpdExlbmd0aCBsZW5ndGggb2YgdGhlIG5ldyB7QGNvZGUgQmlnSW50ZWdlcn0gaW4gYml0cy4KKyAgICAgKiBAcGFyYW0gY2VydGFpbnR5IHRvbGVyYXRlZCBwcmltYWxpdHkgdW5jZXJ0YWludHkuCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uIGlmIHtAY29kZSBiaXRMZW5ndGggPCAyfS4KKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cub3BlbnNzbC5vcmcvZG9jcy9jcnlwdG8vQk5fcmFuZC5odG1sIj4KKyAgICAgKiAgICAgIFNwZWNpZmljYXRpb24gb2YgcmFuZG9tIGdlbmVyYXRvciB1c2VkIGZyb20gT3BlblNTTCBsaWJyYXJ5PC9hPgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyKGludCBiaXRMZW5ndGgsIGludCBjZXJ0YWludHksIFJhbmRvbSB1bnVzZWQpIHsKKyAgICAgICAgaWYgKGJpdExlbmd0aCA8IDIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBcml0aG1ldGljRXhjZXB0aW9uKCJiaXRMZW5ndGggPCAyOiAiICsgYml0TGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICBzZXRCaWdJbnQoQmlnSW50LmdlbmVyYXRlUHJpbWVEZWZhdWx0KGJpdExlbmd0aCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJpZ0ludGVnZXJ9IGJ5IHBhcnNpbmcge0Bjb2RlIHZhbHVlfS4gVGhlIHN0cmluZworICAgICAqIHJlcHJlc2VudGF0aW9uIGNvbnNpc3RzIG9mIGFuIG9wdGlvbmFsIHBsdXMgb3IgbWludXMgc2lnbiBmb2xsb3dlZCBieSBhCisgICAgICogbm9uLWVtcHR5IHNlcXVlbmNlIG9mIGRlY2ltYWwgZGlnaXRzLiBEaWdpdHMgYXJlIGludGVycHJldGVkIGFzIGlmIGJ5CisgICAgICoge0Bjb2RlIENoYXJhY3Rlci5kaWdpdChjaGFyLDEwKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBuZXcge0Bjb2RlIEJpZ0ludGVnZXJ9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIHZhbHVlID09IG51bGx9LgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGlmIHtAY29kZSB2YWx1ZX0gaXMgbm90IGEgdmFsaWQKKyAgICAgKiAgICAgcmVwcmVzZW50YXRpb24gb2YgYSB7QGNvZGUgQmlnSW50ZWdlcn0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIoU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIEJpZ0ludCBiaWdJbnQgPSBuZXcgQmlnSW50KCk7CisgICAgICAgIGJpZ0ludC5wdXREZWNTdHJpbmcodmFsdWUpOworICAgICAgICBzZXRCaWdJbnQoYmlnSW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBCaWdJbnRlZ2VyfSBpbnN0YW5jZSBieSBwYXJzaW5nIHtAY29kZSB2YWx1ZX0uCisgICAgICogVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBjb25zaXN0cyBvZiBhbiBvcHRpb25hbCBwbHVzIG9yIG1pbnVzIHNpZ24KKyAgICAgKiBmb2xsb3dlZCBieSBhIG5vbi1lbXB0eSBzZXF1ZW5jZSBvZiBkaWdpdHMgaW4gdGhlIHNwZWNpZmllZCByYWRpeC4gRGlnaXRzCisgICAgICogYXJlIGludGVycHJldGVkIGFzIGlmIGJ5IHtAY29kZSBDaGFyYWN0ZXIuZGlnaXQoY2hhciwgcmFkaXgpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG5ldyB7QGNvZGUgQmlnSW50ZWdlcn0uCisgICAgICogQHBhcmFtIHJhZGl4IHRoZSBiYXNlIHRvIGJlIHVzZWQgZm9yIHRoZSBjb252ZXJzaW9uLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIHZhbHVlID09IG51bGx9LgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGlmIHtAY29kZSB2YWx1ZX0gaXMgbm90IGEgdmFsaWQKKyAgICAgKiAgICAgcmVwcmVzZW50YXRpb24gb2YgYSB7QGNvZGUgQmlnSW50ZWdlcn0gb3IgaWYge0Bjb2RlIHJhZGl4IDwKKyAgICAgKiAgICAgQ2hhcmFjdGVyLk1JTl9SQURJWH0gb3Ige0Bjb2RlIHJhZGl4ID4gQ2hhcmFjdGVyLk1BWF9SQURJWH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIoU3RyaW5nIHZhbHVlLCBpbnQgcmFkaXgpIHsKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidmFsdWUgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChyYWRpeCA9PSAxMCkgeworICAgICAgICAgICAgQmlnSW50IGJpZ0ludCA9IG5ldyBCaWdJbnQoKTsKKyAgICAgICAgICAgIGJpZ0ludC5wdXREZWNTdHJpbmcodmFsdWUpOworICAgICAgICAgICAgc2V0QmlnSW50KGJpZ0ludCk7CisgICAgICAgIH0gZWxzZSBpZiAocmFkaXggPT0gMTYpIHsKKyAgICAgICAgICAgIEJpZ0ludCBiaWdJbnQgPSBuZXcgQmlnSW50KCk7CisgICAgICAgICAgICBiaWdJbnQucHV0SGV4U3RyaW5nKHZhbHVlKTsKKyAgICAgICAgICAgIHNldEJpZ0ludChiaWdJbnQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKHJhZGl4IDwgQ2hhcmFjdGVyLk1JTl9SQURJWCB8fCByYWRpeCA+IENoYXJhY3Rlci5NQVhfUkFESVgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkIHJhZGl4OiAiICsgcmFkaXgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHZhbHVlLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oInZhbHVlLmlzRW1wdHkoKSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQmlnSW50ZWdlci5wYXJzZUZyb21TdHJpbmcodGhpcywgdmFsdWUsIHJhZGl4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJpZ0ludGVnZXJ9IGluc3RhbmNlIHdpdGggdGhlIGdpdmVuIHNpZ24gYW5kCisgICAgICogbWFnbml0dWRlLgorICAgICAqCisgICAgICogQHBhcmFtIHNpZ251bSBzaWduIG9mIHRoZSBuZXcge0Bjb2RlIEJpZ0ludGVnZXJ9ICgtMSBmb3IgbmVnYXRpdmUsIDAgZm9yCisgICAgICogICAgIHplcm8sIDEgZm9yIHBvc2l0aXZlKS4KKyAgICAgKiBAcGFyYW0gbWFnbml0dWRlIG1hZ25pdHVkZSBvZiB0aGUgbmV3IHtAY29kZSBCaWdJbnRlZ2VyfSB3aXRoIHRoZSBtb3N0CisgICAgICogICAgIHNpZ25pZmljYW50IGJ5dGUgZmlyc3QuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgbWFnbml0dWRlID09IG51bGx9LgorICAgICAqIEB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGlmIHRoZSBzaWduIGlzIG5vdCBvbmUgb2YgLTEsIDAsIDEgb3IgaWYKKyAgICAgKiAgICAgdGhlIHNpZ24gaXMgemVybyBhbmQgdGhlIG1hZ25pdHVkZSBjb250YWlucyBub24temVybyBlbnRyaWVzLgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyKGludCBzaWdudW0sIGJ5dGVbXSBtYWduaXR1ZGUpIHsKKyAgICAgICAgaWYgKG1hZ25pdHVkZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hZ25pdHVkZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNpZ251bSA8IC0xIHx8IHNpZ251bSA+IDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oIkludmFsaWQgc2lnbnVtOiAiICsgc2lnbnVtKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc2lnbnVtID09IDApIHsKKyAgICAgICAgICAgIGZvciAoYnl0ZSBlbGVtZW50IDogbWFnbml0dWRlKSB7CisgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJzaWdudW0tbWFnbml0dWRlIG1pc21hdGNoIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIEJpZ0ludCBiaWdJbnQgPSBuZXcgQmlnSW50KCk7CisgICAgICAgIGJpZ0ludC5wdXRCaWdFbmRpYW4obWFnbml0dWRlLCBzaWdudW0gPCAwKTsKKyAgICAgICAgc2V0QmlnSW50KGJpZ0ludCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQmlnSW50ZWdlcn0gZnJvbSB0aGUgZ2l2ZW4gdHdvJ3MgY29tcGxlbWVudAorICAgICAqIHJlcHJlc2VudGF0aW9uLiBUaGUgbW9zdCBzaWduaWZpY2FudCBieXRlIGlzIHRoZSBlbnRyeSBhdCBpbmRleCAwLiBUaGUKKyAgICAgKiBtb3N0IHNpZ25pZmljYW50IGJpdCBvZiB0aGlzIGVudHJ5IGRldGVybWluZXMgdGhlIHNpZ24gb2YgdGhlIG5ldyB7QGNvZGUKKyAgICAgKiBCaWdJbnRlZ2VyfSBpbnN0YW5jZS4gVGhlIGFycmF5IG11c3QgYmUgbm9uZW1wdHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUgdHdvJ3MgY29tcGxlbWVudCByZXByZXNlbnRhdGlvbiBvZiB0aGUgbmV3IHtAY29kZQorICAgICAqICAgICBCaWdJbnRlZ2VyfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSB2YWx1ZSA9PSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiBpZiB0aGUgbGVuZ3RoIG9mIHtAY29kZSB2YWx1ZX0gaXMgemVyby4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlcihieXRlW10gdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJ2YWx1ZS5sZW5ndGggPT0gMCIpOworICAgICAgICB9CisgICAgICAgIEJpZ0ludCBiaWdJbnQgPSBuZXcgQmlnSW50KCk7CisgICAgICAgIGJpZ0ludC5wdXRCaWdFbmRpYW5Ud29zQ29tcGxlbWVudCh2YWx1ZSk7CisgICAgICAgIHNldEJpZ0ludChiaWdJbnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGludGVybmFsIG5hdGl2ZSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGJpZyBpbnRlZ2VyLCBjb21wdXRpbmcKKyAgICAgKiBpdCBpZiBuZWNlc3NhcnkuCisgICAgICovCisgICAgQmlnSW50IGdldEJpZ0ludCgpIHsKKyAgICAgICAgaWYgKG5hdGl2ZUlzVmFsaWQpIHsKKyAgICAgICAgICAgIHJldHVybiBiaWdJbnQ7CisgICAgICAgIH0KKworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGlmIChuYXRpdmVJc1ZhbGlkKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGJpZ0ludDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEJpZ0ludCBiaWdJbnQgPSBuZXcgQmlnSW50KCk7CisgICAgICAgICAgICBiaWdJbnQucHV0TGl0dGxlRW5kaWFuSW50cyhkaWdpdHMsIChzaWduIDwgMCkpOworICAgICAgICAgICAgc2V0QmlnSW50KGJpZ0ludCk7CisgICAgICAgICAgICByZXR1cm4gYmlnSW50OworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNldEJpZ0ludChCaWdJbnQgYmlnSW50KSB7CisgICAgICAgIHRoaXMuYmlnSW50ID0gYmlnSW50OworICAgICAgICB0aGlzLm5hdGl2ZUlzVmFsaWQgPSB0cnVlOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzZXRKYXZhUmVwcmVzZW50YXRpb24oaW50IHNpZ24sIGludCBudW1iZXJMZW5ndGgsIGludFtdIGRpZ2l0cykgeworICAgICAgICAvLyBkZWNyZW1lbnQgbnVtYmVyTGVuZ3RoIHRvIGRyb3AgbGVhZGluZyB6ZXJvZXMuLi4KKyAgICAgICAgd2hpbGUgKG51bWJlckxlbmd0aCA+IDAgJiYgZGlnaXRzWy0tbnVtYmVyTGVuZ3RoXSA9PSAwKSB7CisgICAgICAgICAgICA7CisgICAgICAgIH0KKyAgICAgICAgLy8gLi4uIGFuZCB0aGVuIGluY3JlbWVudCBpdCBiYWNrIGJlY2F1c2Ugd2UgYWx3YXlzIGRyb3Agb25lIHRvbyBtYW55CisgICAgICAgIGlmIChkaWdpdHNbbnVtYmVyTGVuZ3RoKytdID09IDApIHsKKyAgICAgICAgICAgIHNpZ24gPSAwOworICAgICAgICB9CisgICAgICAgIHRoaXMuc2lnbiA9IHNpZ247CisgICAgICAgIHRoaXMuZGlnaXRzID0gZGlnaXRzOworICAgICAgICB0aGlzLm51bWJlckxlbmd0aCA9IG51bWJlckxlbmd0aDsKKyAgICAgICAgdGhpcy5qYXZhSXNWYWxpZCA9IHRydWU7CisgICAgfQorCisgICAgdm9pZCBwcmVwYXJlSmF2YVJlcHJlc2VudGF0aW9uKCkgeworICAgICAgICBpZiAoamF2YUlzVmFsaWQpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgaWYgKGphdmFJc1ZhbGlkKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHNpZ24gPSBiaWdJbnQuc2lnbigpOworICAgICAgICAgICAgaW50W10gZGlnaXRzID0gKHNpZ24gIT0gMCkgPyBiaWdJbnQubGl0dGxlRW5kaWFuSW50c01hZ25pdHVkZSgpIDogbmV3IGludFtdIHsgMCB9OworICAgICAgICAgICAgc2V0SmF2YVJlcHJlc2VudGF0aW9uKHNpZ24sIGRpZ2l0cy5sZW5ndGgsIGRpZ2l0cyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKiogUmV0dXJucyBhIHtAY29kZSBCaWdJbnRlZ2VyfSB3aG9zZSB2YWx1ZSBpcyBlcXVhbCB0byB7QGNvZGUgdmFsdWV9LiAqLworICAgIHB1YmxpYyBzdGF0aWMgQmlnSW50ZWdlciB2YWx1ZU9mKGxvbmcgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlIDwgMCkgeworICAgICAgICAgICAgaWYgKHZhbHVlICE9IC0xKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKC0xLCAtdmFsdWUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIE1JTlVTX09ORTsKKyAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA8IFNNQUxMX1ZBTFVFUy5sZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiBTTUFMTF9WQUxVRVNbKGludCkgdmFsdWVdOworICAgICAgICB9IGVsc2Ugey8vICh2YWx1ZSA+IDEwKQorICAgICAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKDEsIHZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHR3bydzIGNvbXBsZW1lbnQgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgQmlnSW50ZWdlcn0gaW4KKyAgICAgKiBhIGJ5dGUgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSB0b0J5dGVBcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIHR3b3NDb21wbGVtZW50KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBCaWdJbnRlZ2VyfSB3aG9zZSB2YWx1ZSBpcyB0aGUgYWJzb2x1dGUgdmFsdWUgb2Yge0Bjb2RlCisgICAgICogdGhpc30uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgYWJzKCkgeworICAgICAgICBCaWdJbnQgYmlnSW50ID0gZ2V0QmlnSW50KCk7CisgICAgICAgIGlmIChiaWdJbnQuc2lnbigpID49IDApIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICB9CisgICAgICAgIEJpZ0ludCBhID0gYmlnSW50LmNvcHkoKTsKKyAgICAgICAgYS5zZXRTaWduKDEpOworICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoYSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBCaWdJbnRlZ2VyfSB3aG9zZSB2YWx1ZSBpcyB0aGUge0Bjb2RlIC10aGlzfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBuZWdhdGUoKSB7CisgICAgICAgIEJpZ0ludCBiaWdJbnQgPSBnZXRCaWdJbnQoKTsKKyAgICAgICAgaW50IHNpZ24gPSBiaWdJbnQuc2lnbigpOworICAgICAgICBpZiAoc2lnbiA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgfQorICAgICAgICBCaWdJbnQgYSA9IGJpZ0ludC5jb3B5KCk7CisgICAgICAgIGEuc2V0U2lnbigtc2lnbik7CisgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcihhKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIEJpZ0ludGVnZXJ9IHdob3NlIHZhbHVlIGlzIHtAY29kZSB0aGlzICsgdmFsdWV9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGFkZChCaWdJbnRlZ2VyIHZhbHVlKSB7CisgICAgICAgIEJpZ0ludCBsaHMgPSBnZXRCaWdJbnQoKTsKKyAgICAgICAgQmlnSW50IHJocyA9IHZhbHVlLmdldEJpZ0ludCgpOworICAgICAgICBpZiAocmhzLnNpZ24oKSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgfQorICAgICAgICBpZiAobGhzLnNpZ24oKSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKEJpZ0ludC5hZGRpdGlvbihsaHMsIHJocykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgQmlnSW50ZWdlcn0gd2hvc2UgdmFsdWUgaXMge0Bjb2RlIHRoaXMgLSB2YWx1ZX0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgc3VidHJhY3QoQmlnSW50ZWdlciB2YWx1ZSkgeworICAgICAgICBCaWdJbnQgbGhzID0gZ2V0QmlnSW50KCk7CisgICAgICAgIEJpZ0ludCByaHMgPSB2YWx1ZS5nZXRCaWdJbnQoKTsKKyAgICAgICAgaWYgKHJocy5zaWduKCkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKEJpZ0ludC5zdWJ0cmFjdGlvbihsaHMsIHJocykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNpZ24gb2YgdGhpcyB7QGNvZGUgQmlnSW50ZWdlcn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSAtMX0gaWYge0Bjb2RlIHRoaXMgPCAwfSwge0Bjb2RlIDB9IGlmIHtAY29kZSB0aGlzID09IDB9LAorICAgICAqICAgICB7QGNvZGUgMX0gaWYge0Bjb2RlIHRoaXMgPiAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNpZ251bSgpIHsKKyAgICAgICAgaWYgKGphdmFJc1ZhbGlkKSB7CisgICAgICAgICAgICByZXR1cm4gc2lnbjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0QmlnSW50KCkuc2lnbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgQmlnSW50ZWdlcn0gd2hvc2UgdmFsdWUgaXMge0Bjb2RlIHRoaXMgPj4gbn0uIEZvcgorICAgICAqIG5lZ2F0aXZlIGFyZ3VtZW50cywgdGhlIHJlc3VsdCBpcyBhbHNvIG5lZ2F0aXZlLiBUaGUgc2hpZnQgZGlzdGFuY2UgbWF5CisgICAgICogYmUgbmVnYXRpdmUgd2hpY2ggbWVhbnMgdGhhdCB7QGNvZGUgdGhpc30gaXMgc2hpZnRlZCBsZWZ0LgorICAgICAqCisgICAgICogPHA+PGI+SW1wbGVtZW50YXRpb24gTm90ZTo8L2I+IFVzYWdlIG9mIHRoaXMgbWV0aG9kIG9uIG5lZ2F0aXZlIHZhbHVlcyBpcworICAgICAqIG5vdCByZWNvbW1lbmRlZCBhcyB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBpcyBub3QgZWZmaWNpZW50LgorICAgICAqCisgICAgICogQHBhcmFtIG4gc2hpZnQgZGlzdGFuY2UKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0aGlzID4+IG59IGlmIHtAY29kZSBuID49IDB9OyB7QGNvZGUgdGhpcyA8PCAoLW4pfQorICAgICAqICAgICBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBzaGlmdFJpZ2h0KGludCBuKSB7CisgICAgICAgIHJldHVybiBzaGlmdExlZnQoLW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgQmlnSW50ZWdlcn0gd2hvc2UgdmFsdWUgaXMge0Bjb2RlIHRoaXMgPDwgbn0uIFRoZQorICAgICAqIHJlc3VsdCBpcyBlcXVpdmFsZW50IHRvIHtAY29kZSB0aGlzICogcG93KDIsIG4pfSBpZiBuID49IDAuIFRoZSBzaGlmdAorICAgICAqIGRpc3RhbmNlIG1heSBiZSBuZWdhdGl2ZSB3aGljaCBtZWFucyB0aGF0IHtAY29kZSB0aGlzfSBpcyBzaGlmdGVkIHJpZ2h0LgorICAgICAqIFRoZSByZXN1bHQgdGhlbiBjb3JyZXNwb25kcyB0byB7QGNvZGUgZmxvb3IodGhpcyAvIHBvdygyLCAtbikpfS4KKyAgICAgKgorICAgICAqIDxwPjxiPkltcGxlbWVudGF0aW9uIE5vdGU6PC9iPiBVc2FnZSBvZiB0aGlzIG1ldGhvZCBvbiBuZWdhdGl2ZSB2YWx1ZXMgaXMKKyAgICAgKiBub3QgcmVjb21tZW5kZWQgYXMgdGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gaXMgbm90IGVmZmljaWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuIHNoaWZ0IGRpc3RhbmNlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXMgPDwgbn0gaWYge0Bjb2RlIG4gPj0gMH07IHtAY29kZSB0aGlzID4+ICgtbil9LgorICAgICAqICAgICBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBzaGlmdExlZnQoaW50IG4pIHsKKyAgICAgICAgaWYgKG4gPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKyAgICAgICAgaW50IHNpZ24gPSBzaWdudW0oKTsKKyAgICAgICAgaWYgKHNpZ24gPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChzaWduID4gMCkgfHwgKG4gPj0gMCkpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcihCaWdJbnQuc2hpZnQoZ2V0QmlnSW50KCksIG4pKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIE5lZ2F0aXZlIG51bWJlcnMgZmFraW5nIDIncyBjb21wbGVtZW50OgorICAgICAgICAgICAgLy8gTm90IHdvcnRoIG9wdGltaXppbmcgdGhpczoKKyAgICAgICAgICAgIC8vIFN0aWNraW5nIHRvIEhhcm1vbnkgSmF2YSBpbXBsZW1lbnRhdGlvbi4KKyAgICAgICAgICAgIHJldHVybiBCaXRMZXZlbC5zaGlmdFJpZ2h0KHRoaXMsIC1uKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEJpZ0ludGVnZXIgc2hpZnRMZWZ0T25lQml0KCkgeworICAgICAgICByZXR1cm4gKHNpZ251bSgpID09IDApID8gdGhpcyA6IEJpdExldmVsLnNoaWZ0TGVmdE9uZUJpdCh0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhlIHZhbHVlJ3MgdHdvJ3MgY29tcGxlbWVudCByZXByZXNlbnRhdGlvbiB3aXRob3V0CisgICAgICogbGVhZGluZyB6ZXJvcyBmb3IgcG9zaXRpdmUgbnVtYmVycyAvIHdpdGhvdXQgbGVhZGluZyBvbmVzIGZvciBuZWdhdGl2ZQorICAgICAqIHZhbHVlcy4KKyAgICAgKgorICAgICAqIDxwPlRoZSB0d28ncyBjb21wbGVtZW50IHJlcHJlc2VudGF0aW9uIG9mIHtAY29kZSB0aGlzfSB3aWxsIGJlIGF0IGxlYXN0CisgICAgICoge0Bjb2RlIGJpdExlbmd0aCgpICsgMX0gYml0cyBsb25nLgorICAgICAqCisgICAgICogPHA+VGhlIHZhbHVlIHdpbGwgZml0IGludG8gYW4ge0Bjb2RlIGludH0gaWYge0Bjb2RlIGJpdExlbmd0aCgpIDwgMzJ9IG9yCisgICAgICogaW50byBhIHtAY29kZSBsb25nfSBpZiB7QGNvZGUgYml0TGVuZ3RoKCkgPCA2NH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIG1pbmltYWwgdHdvJ3MgY29tcGxlbWVudCByZXByZXNlbnRhdGlvbiBmb3IKKyAgICAgKiAgICAge0Bjb2RlIHRoaXN9IHdpdGhvdXQgdGhlIHNpZ24gYml0LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgYml0TGVuZ3RoKCkgeworICAgICAgICAvLyBPcHRpbWl6YXRpb24gdG8gYXZvaWQgdW5uZWNlc3NhcnkgZHVwbGljYXRlIHJlcHJlc2VudGF0aW9uOgorICAgICAgICBpZiAoIW5hdGl2ZUlzVmFsaWQgJiYgamF2YUlzVmFsaWQpIHsKKyAgICAgICAgICAgIHJldHVybiBCaXRMZXZlbC5iaXRMZW5ndGgodGhpcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEJpZ0ludCgpLmJpdExlbmd0aCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHdoZXRoZXIgdGhlIGJpdCBhdCBwb3NpdGlvbiBuIGluIHtAY29kZSB0aGlzfSBpcyBzZXQuIFRoZSByZXN1bHQgaXMKKyAgICAgKiBlcXVpdmFsZW50IHRvIHtAY29kZSB0aGlzICYgcG93KDIsIG4pICE9IDB9LgorICAgICAqCisgICAgICogPHA+PGI+SW1wbGVtZW50YXRpb24gTm90ZTo8L2I+IFVzYWdlIG9mIHRoaXMgbWV0aG9kIGlzIG5vdCByZWNvbW1lbmRlZCBhcworICAgICAqIHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIGlzIG5vdCBlZmZpY2llbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbiBwb3NpdGlvbiB3aGVyZSB0aGUgYml0IGluIHtAY29kZSB0aGlzfSBoYXMgdG8gYmUgaW5zcGVjdGVkLgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbiBpZiB7QGNvZGUgbiA8IDB9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHRlc3RCaXQoaW50IG4pIHsKKyAgICAgICAgaWYgKG4gPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJpdGhtZXRpY0V4Y2VwdGlvbigibiA8IDA6ICIgKyBuKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgc2lnbiA9IHNpZ251bSgpOworICAgICAgICBpZiAoc2lnbiA+IDAgJiYgbmF0aXZlSXNWYWxpZCAmJiAhamF2YUlzVmFsaWQpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRCaWdJbnQoKS5pc0JpdFNldChuKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIE5lZ2F0aXZlIG51bWJlcnMgZmFraW5nIDIncyBjb21wbGVtZW50OgorICAgICAgICAgICAgLy8gTm90IHdvcnRoIG9wdGltaXppbmcgdGhpczoKKyAgICAgICAgICAgIC8vIFN0aWNraW5nIHRvIEhhcm1vbnkgSmF2YSBpbXBsZW1lbnRhdGlvbi4KKyAgICAgICAgICAgIHByZXBhcmVKYXZhUmVwcmVzZW50YXRpb24oKTsKKyAgICAgICAgICAgIGlmIChuID09IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gKChkaWdpdHNbMF0gJiAxKSAhPSAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBpbnRDb3VudCA9IG4gPj4gNTsKKyAgICAgICAgICAgIGlmIChpbnRDb3VudCA+PSBudW1iZXJMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gKHNpZ24gPCAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBkaWdpdCA9IGRpZ2l0c1tpbnRDb3VudF07CisgICAgICAgICAgICBuID0gKDEgPDwgKG4gJiAzMSkpOyAvLyBpbnQgd2l0aCAxIHNldCB0byB0aGUgbmVlZGVkIHBvc2l0aW9uCisgICAgICAgICAgICBpZiAoc2lnbiA8IDApIHsKKyAgICAgICAgICAgICAgICBpbnQgZmlyc3ROb25aZXJvRGlnaXQgPSBnZXRGaXJzdE5vbnplcm9EaWdpdCgpOworICAgICAgICAgICAgICAgIGlmIChpbnRDb3VudCA8IGZpcnN0Tm9uWmVyb0RpZ2l0KSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGZpcnN0Tm9uWmVyb0RpZ2l0ID09IGludENvdW50KSB7CisgICAgICAgICAgICAgICAgICAgIGRpZ2l0ID0gLWRpZ2l0OworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGRpZ2l0ID0gfmRpZ2l0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAoKGRpZ2l0ICYgbikgIT0gMCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIEJpZ0ludGVnZXJ9IHdoaWNoIGhhcyB0aGUgc2FtZSBiaW5hcnkgcmVwcmVzZW50YXRpb24KKyAgICAgKiBhcyB7QGNvZGUgdGhpc30gYnV0IHdpdGggdGhlIGJpdCBhdCBwb3NpdGlvbiBuIHNldC4gVGhlIHJlc3VsdCBpcworICAgICAqIGVxdWl2YWxlbnQgdG8ge0Bjb2RlIHRoaXMgfCBwb3coMiwgbil9LgorICAgICAqCisgICAgICogPHA+PGI+SW1wbGVtZW50YXRpb24gTm90ZTo8L2I+IFVzYWdlIG9mIHRoaXMgbWV0aG9kIGlzIG5vdCByZWNvbW1lbmRlZCBhcworICAgICAqIHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIGlzIG5vdCBlZmZpY2llbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbiBwb3NpdGlvbiB3aGVyZSB0aGUgYml0IGluIHtAY29kZSB0aGlzfSBoYXMgdG8gYmUgc2V0LgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbiBpZiB7QGNvZGUgbiA8IDB9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIHNldEJpdChpbnQgbikgeworICAgICAgICBwcmVwYXJlSmF2YVJlcHJlc2VudGF0aW9uKCk7CisgICAgICAgIGlmICghdGVzdEJpdChuKSkgeworICAgICAgICAgICAgcmV0dXJuIEJpdExldmVsLmZsaXBCaXQodGhpcywgbik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgQmlnSW50ZWdlcn0gd2hpY2ggaGFzIHRoZSBzYW1lIGJpbmFyeSByZXByZXNlbnRhdGlvbgorICAgICAqIGFzIHtAY29kZSB0aGlzfSBidXQgd2l0aCB0aGUgYml0IGF0IHBvc2l0aW9uIG4gY2xlYXJlZC4gVGhlIHJlc3VsdCBpcworICAgICAqIGVxdWl2YWxlbnQgdG8ge0Bjb2RlIHRoaXMgJiB+cG93KDIsIG4pfS4KKyAgICAgKgorICAgICAqIDxwPjxiPkltcGxlbWVudGF0aW9uIE5vdGU6PC9iPiBVc2FnZSBvZiB0aGlzIG1ldGhvZCBpcyBub3QgcmVjb21tZW5kZWQgYXMKKyAgICAgKiB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBpcyBub3QgZWZmaWNpZW50LgorICAgICAqCisgICAgICogQHBhcmFtIG4gcG9zaXRpb24gd2hlcmUgdGhlIGJpdCBpbiB7QGNvZGUgdGhpc30gaGFzIHRvIGJlIGNsZWFyZWQuCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uIGlmIHtAY29kZSBuIDwgMH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgY2xlYXJCaXQoaW50IG4pIHsKKyAgICAgICAgcHJlcGFyZUphdmFSZXByZXNlbnRhdGlvbigpOworICAgICAgICBpZiAodGVzdEJpdChuKSkgeworICAgICAgICAgICAgcmV0dXJuIEJpdExldmVsLmZsaXBCaXQodGhpcywgbik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgQmlnSW50ZWdlcn0gd2hpY2ggaGFzIHRoZSBzYW1lIGJpbmFyeSByZXByZXNlbnRhdGlvbgorICAgICAqIGFzIHtAY29kZSB0aGlzfSBidXQgd2l0aCB0aGUgYml0IGF0IHBvc2l0aW9uIG4gZmxpcHBlZC4gVGhlIHJlc3VsdCBpcworICAgICAqIGVxdWl2YWxlbnQgdG8ge0Bjb2RlIHRoaXMgXiBwb3coMiwgbil9LgorICAgICAqCisgICAgICogPHA+PGI+SW1wbGVtZW50YXRpb24gTm90ZTo8L2I+IFVzYWdlIG9mIHRoaXMgbWV0aG9kIGlzIG5vdCByZWNvbW1lbmRlZCBhcworICAgICAqIHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIGlzIG5vdCBlZmZpY2llbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbiBwb3NpdGlvbiB3aGVyZSB0aGUgYml0IGluIHtAY29kZSB0aGlzfSBoYXMgdG8gYmUgZmxpcHBlZC4KKyAgICAgKiBAdGhyb3dzIEFyaXRobWV0aWNFeGNlcHRpb24gaWYge0Bjb2RlIG4gPCAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBmbGlwQml0KGludCBuKSB7CisgICAgICAgIHByZXBhcmVKYXZhUmVwcmVzZW50YXRpb24oKTsKKyAgICAgICAgaWYgKG4gPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJpdGhtZXRpY0V4Y2VwdGlvbigibiA8IDA6ICIgKyBuKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gQml0TGV2ZWwuZmxpcEJpdCh0aGlzLCBuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwb3NpdGlvbiBvZiB0aGUgbG93ZXN0IHNldCBiaXQgaW4gdGhlIHR3bydzIGNvbXBsZW1lbnQKKyAgICAgKiByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZSBCaWdJbnRlZ2VyfS4gSWYgYWxsIGJpdHMgYXJlIHplcm8gKHRoaXM9PTApCisgICAgICogdGhlbiAtMSBpcyByZXR1cm5lZCBhcyByZXN1bHQuCisgICAgICoKKyAgICAgKiA8cD48Yj5JbXBsZW1lbnRhdGlvbiBOb3RlOjwvYj4gVXNhZ2Ugb2YgdGhpcyBtZXRob2QgaXMgbm90IHJlY29tbWVuZGVkIGFzCisgICAgICogdGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gaXMgbm90IGVmZmljaWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExvd2VzdFNldEJpdCgpIHsKKyAgICAgICAgcHJlcGFyZUphdmFSZXByZXNlbnRhdGlvbigpOworICAgICAgICBpZiAoc2lnbiA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgLy8gKHNpZ24gIT0gMCkgaW1wbGllcyB0aGF0IGV4aXN0cyBzb21lIG5vbiB6ZXJvIGRpZ2l0CisgICAgICAgIGludCBpID0gZ2V0Rmlyc3ROb256ZXJvRGlnaXQoKTsKKyAgICAgICAgcmV0dXJuICgoaSA8PCA1KSArIEludGVnZXIubnVtYmVyT2ZUcmFpbGluZ1plcm9zKGRpZ2l0c1tpXSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBiaXRzIGluIHRoZSB0d28ncyBjb21wbGVtZW50IHJlcHJlc2VudGF0aW9uIG9mCisgICAgICoge0Bjb2RlIHRoaXN9IHdoaWNoIGRpZmZlciBmcm9tIHRoZSBzaWduIGJpdC4gSWYge0Bjb2RlIHRoaXN9IGlzIG5lZ2F0aXZlLAorICAgICAqIHRoZSByZXN1bHQgaXMgZXF1aXZhbGVudCB0byB0aGUgbnVtYmVyIG9mIGJpdHMgc2V0IGluIHRoZSB0d28ncworICAgICAqIGNvbXBsZW1lbnQgcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIC10aGlzIC0gMX0uCisgICAgICoKKyAgICAgKiA8cD5Vc2Uge0Bjb2RlIGJpdExlbmd0aCgwKX0gdG8gZmluZCB0aGUgbGVuZ3RoIG9mIHRoZSBiaW5hcnkgdmFsdWUgaW4KKyAgICAgKiBiaXRzLgorICAgICAqCisgICAgICogPHA+PGI+SW1wbGVtZW50YXRpb24gTm90ZTo8L2I+IFVzYWdlIG9mIHRoaXMgbWV0aG9kIGlzIG5vdCByZWNvbW1lbmRlZCBhcworICAgICAqIHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIGlzIG5vdCBlZmZpY2llbnQuCisgICAgICovCisgICAgcHVibGljIGludCBiaXRDb3VudCgpIHsKKyAgICAgICAgcHJlcGFyZUphdmFSZXByZXNlbnRhdGlvbigpOworICAgICAgICByZXR1cm4gQml0TGV2ZWwuYml0Q291bnQodGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBCaWdJbnRlZ2VyfSB3aG9zZSB2YWx1ZSBpcyB7QGNvZGUgfnRoaXN9LiBUaGUgcmVzdWx0CisgICAgICogb2YgdGhpcyBvcGVyYXRpb24gaXMge0Bjb2RlIC10aGlzLTF9LgorICAgICAqCisgICAgICogPHA+PGI+SW1wbGVtZW50YXRpb24gTm90ZTo8L2I+IFVzYWdlIG9mIHRoaXMgbWV0aG9kIGlzIG5vdCByZWNvbW1lbmRlZCBhcworICAgICAqIHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIGlzIG5vdCBlZmZpY2llbnQuCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgbm90KCkgeworICAgICAgICB0aGlzLnByZXBhcmVKYXZhUmVwcmVzZW50YXRpb24oKTsKKyAgICAgICAgcmV0dXJuIExvZ2ljYWwubm90KHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgQmlnSW50ZWdlcn0gd2hvc2UgdmFsdWUgaXMge0Bjb2RlIHRoaXMgJiB2YWx1ZX0uCisgICAgICoKKyAgICAgKiA8cD48Yj5JbXBsZW1lbnRhdGlvbiBOb3RlOjwvYj4gVXNhZ2Ugb2YgdGhpcyBtZXRob2QgaXMgbm90IHJlY29tbWVuZGVkCisgICAgICogYXMgdGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gaXMgbm90IGVmZmljaWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSB0byBiZSBhbmQnZWQgd2l0aCB7QGNvZGUgdGhpc30uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgdmFsdWUgPT0gbnVsbH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgYW5kKEJpZ0ludGVnZXIgdmFsdWUpIHsKKyAgICAgICAgdGhpcy5wcmVwYXJlSmF2YVJlcHJlc2VudGF0aW9uKCk7CisgICAgICAgIHZhbHVlLnByZXBhcmVKYXZhUmVwcmVzZW50YXRpb24oKTsKKyAgICAgICAgcmV0dXJuIExvZ2ljYWwuYW5kKHRoaXMsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIEJpZ0ludGVnZXJ9IHdob3NlIHZhbHVlIGlzIHtAY29kZSB0aGlzIHwgdmFsdWV9LgorICAgICAqCisgICAgICogPHA+PGI+SW1wbGVtZW50YXRpb24gTm90ZTo8L2I+IFVzYWdlIG9mIHRoaXMgbWV0aG9kIGlzIG5vdCByZWNvbW1lbmRlZCBhcworICAgICAqIHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIGlzIG5vdCBlZmZpY2llbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUgdmFsdWUgdG8gYmUgb3InZWQgd2l0aCB7QGNvZGUgdGhpc30uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgdmFsdWUgPT0gbnVsbH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgb3IoQmlnSW50ZWdlciB2YWx1ZSkgeworICAgICAgICB0aGlzLnByZXBhcmVKYXZhUmVwcmVzZW50YXRpb24oKTsKKyAgICAgICAgdmFsdWUucHJlcGFyZUphdmFSZXByZXNlbnRhdGlvbigpOworICAgICAgICByZXR1cm4gTG9naWNhbC5vcih0aGlzLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBCaWdJbnRlZ2VyfSB3aG9zZSB2YWx1ZSBpcyB7QGNvZGUgdGhpcyBeIHZhbHVlfS4KKyAgICAgKgorICAgICAqIDxwPjxiPkltcGxlbWVudGF0aW9uIE5vdGU6PC9iPiBVc2FnZSBvZiB0aGlzIG1ldGhvZCBpcyBub3QgcmVjb21tZW5kZWQgYXMKKyAgICAgKiB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBpcyBub3QgZWZmaWNpZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlIHZhbHVlIHRvIGJlIHhvcidlZCB3aXRoIHtAY29kZSB0aGlzfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIHZhbHVlID09IG51bGx9CisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgeG9yKEJpZ0ludGVnZXIgdmFsdWUpIHsKKyAgICAgICAgdGhpcy5wcmVwYXJlSmF2YVJlcHJlc2VudGF0aW9uKCk7CisgICAgICAgIHZhbHVlLnByZXBhcmVKYXZhUmVwcmVzZW50YXRpb24oKTsKKyAgICAgICAgcmV0dXJuIExvZ2ljYWwueG9yKHRoaXMsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIEJpZ0ludGVnZXJ9IHdob3NlIHZhbHVlIGlzIHtAY29kZSB0aGlzICYgfnZhbHVlfS4KKyAgICAgKiBFdmFsdWF0aW5nIHtAY29kZSB4LmFuZE5vdCh2YWx1ZSl9IHJldHVybnMgdGhlIHNhbWUgcmVzdWx0IGFzIHtAY29kZQorICAgICAqIHguYW5kKHZhbHVlLm5vdCgpKX0uCisgICAgICoKKyAgICAgKiA8cD48Yj5JbXBsZW1lbnRhdGlvbiBOb3RlOjwvYj4gVXNhZ2Ugb2YgdGhpcyBtZXRob2QgaXMgbm90IHJlY29tbWVuZGVkCisgICAgICogYXMgdGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gaXMgbm90IGVmZmljaWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSB0byBiZSBub3QnZWQgYW5kIHRoZW4gYW5kJ2VkIHdpdGgge0Bjb2RlIHRoaXN9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIHZhbHVlID09IG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGFuZE5vdChCaWdJbnRlZ2VyIHZhbHVlKSB7CisgICAgICAgIHRoaXMucHJlcGFyZUphdmFSZXByZXNlbnRhdGlvbigpOworICAgICAgICB2YWx1ZS5wcmVwYXJlSmF2YVJlcHJlc2VudGF0aW9uKCk7CisgICAgICAgIHJldHVybiBMb2dpY2FsLmFuZE5vdCh0aGlzLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHtAY29kZSBCaWdJbnRlZ2VyfSBhcyBhbiBpbnQgdmFsdWUuIElmIHtAY29kZSB0aGlzfSBpcyB0b28KKyAgICAgKiBiaWcgdG8gYmUgcmVwcmVzZW50ZWQgYXMgYW4gaW50LCB0aGVuIHtAY29kZSB0aGlzICUgKDEgPDwgMzIpfSBpcworICAgICAqIHJldHVybmVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaW50VmFsdWUoKSB7CisgICAgICAgIGlmIChuYXRpdmVJc1ZhbGlkICYmIGJpZ0ludC50d29zQ29tcEZpdHNJbnRvQnl0ZXMoNCkpIHsKKyAgICAgICAgICAgIHJldHVybiAoaW50KSBiaWdJbnQubG9uZ0ludCgpOworICAgICAgICB9CisgICAgICAgIHRoaXMucHJlcGFyZUphdmFSZXByZXNlbnRhdGlvbigpOworICAgICAgICByZXR1cm4gKHNpZ24gKiBkaWdpdHNbMF0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyB7QGNvZGUgQmlnSW50ZWdlcn0gYXMgYSBsb25nIHZhbHVlLiBJZiB7QGNvZGUgdGhpc30gaXMgdG9vCisgICAgICogYmlnIHRvIGJlIHJlcHJlc2VudGVkIGFzIGEgbG9uZywgdGhlbiB7QGNvZGUgdGhpcyAlIHBvdygyLCA2NCl9IGlzCisgICAgICogcmV0dXJuZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgbG9uZ1ZhbHVlKCkgeworICAgICAgICBpZiAobmF0aXZlSXNWYWxpZCAmJiBiaWdJbnQudHdvc0NvbXBGaXRzSW50b0J5dGVzKDgpKSB7CisgICAgICAgICAgICByZXR1cm4gYmlnSW50LmxvbmdJbnQoKTsKKyAgICAgICAgfQorICAgICAgICBwcmVwYXJlSmF2YVJlcHJlc2VudGF0aW9uKCk7CisgICAgICAgIGxvbmcgdmFsdWUgPSBudW1iZXJMZW5ndGggPiAxCisgICAgICAgICAgICAgICAgPyAoKGxvbmcpIGRpZ2l0c1sxXSkgPDwgMzIgfCBkaWdpdHNbMF0gJiAweEZGRkZGRkZGTAorICAgICAgICAgICAgICAgIDogZGlnaXRzWzBdICYgMHhGRkZGRkZGRkw7CisgICAgICAgIHJldHVybiBzaWduICogdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHtAY29kZSBCaWdJbnRlZ2VyfSBhcyBhIGZsb2F0LiBJZiB7QGNvZGUgdGhpc30gaXMgdG9vIGJpZyB0bworICAgICAqIGJlIHJlcHJlc2VudGVkIGFzIGEgZmxvYXQsIHRoZW4ge0Bjb2RlIEZsb2F0LlBPU0lUSVZFX0lORklOSVRZfSBvcgorICAgICAqIHtAY29kZSBGbG9hdC5ORUdBVElWRV9JTkZJTklUWX0gaXMgcmV0dXJuZWQuIE5vdGUgdGhhdCBub3QgYWxsIGludGVnZXJzCisgICAgICogaW4gdGhlIHJhbmdlIHtAY29kZSBbLUZsb2F0Lk1BWF9WQUxVRSwgRmxvYXQuTUFYX1ZBTFVFXX0gY2FuIGJlIGV4YWN0bHkKKyAgICAgKiByZXByZXNlbnRlZCBhcyBhIGZsb2F0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdCBmbG9hdFZhbHVlKCkgeworICAgICAgICByZXR1cm4gKGZsb2F0KSBkb3VibGVWYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyB7QGNvZGUgQmlnSW50ZWdlcn0gYXMgYSBkb3VibGUuIElmIHtAY29kZSB0aGlzfSBpcyB0b28gYmlnCisgICAgICogdG8gYmUgcmVwcmVzZW50ZWQgYXMgYSBkb3VibGUsIHRoZW4ge0Bjb2RlIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWX0gb3IKKyAgICAgKiB7QGNvZGUgRG91YmxlLk5FR0FUSVZFX0lORklOSVRZfSBpcyByZXR1cm5lZC4gTm90ZSB0aGF0IG5vdCBhbGwgaW50ZWdlcnMKKyAgICAgKiBpbiB0aGUgcmFuZ2Uge0Bjb2RlIFstRG91YmxlLk1BWF9WQUxVRSwgRG91YmxlLk1BWF9WQUxVRV19IGNhbiBiZSBleGFjdGx5CisgICAgICogcmVwcmVzZW50ZWQgYXMgYSBkb3VibGUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGRvdWJsZSBkb3VibGVWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIENvbnZlcnNpb24uYmlnSW50ZWdlcjJEb3VibGUodGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyB7QGNvZGUgQmlnSW50ZWdlcn0gd2l0aCB7QGNvZGUgdmFsdWV9LiBSZXR1cm5zIHtAY29kZSAtMX0KKyAgICAgKiBpZiB7QGNvZGUgdGhpcyA8IHZhbHVlfSwge0Bjb2RlIDB9IGlmIHtAY29kZSB0aGlzID09IHZhbHVlfSBhbmQge0Bjb2RlIDF9CisgICAgICogaWYge0Bjb2RlIHRoaXMgPiB2YWx1ZX0sIC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSB0byBiZSBjb21wYXJlZCB3aXRoIHtAY29kZSB0aGlzfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSB2YWx1ZSA9PSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhCaWdJbnRlZ2VyIHZhbHVlKSB7CisgICAgICAgIHJldHVybiBCaWdJbnQuY21wKGdldEJpZ0ludCgpLCB2YWx1ZS5nZXRCaWdJbnQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbWluaW11bSBvZiB0aGlzIHtAY29kZSBCaWdJbnRlZ2VyfSBhbmQge0Bjb2RlIHZhbHVlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSB0byBiZSB1c2VkIHRvIGNvbXB1dGUgdGhlIG1pbmltdW0gd2l0aCB7QGNvZGUgdGhpc30uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgdmFsdWUgPT0gbnVsbH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgbWluKEJpZ0ludGVnZXIgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZVRvKHZhbHVlKSA9PSAtMSA/IHRoaXMgOiB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIG9mIHRoaXMge0Bjb2RlIEJpZ0ludGVnZXJ9IGFuZCB7QGNvZGUgdmFsdWV9LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlIHZhbHVlIHRvIGJlIHVzZWQgdG8gY29tcHV0ZSB0aGUgbWF4aW11bSB3aXRoIHtAY29kZSB0aGlzfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIHZhbHVlID09IG51bGx9CisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgbWF4KEJpZ0ludGVnZXIgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZVRvKHZhbHVlKSA9PSAxID8gdGhpcyA6IHZhbHVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGlmIChoYXNoQ29kZSAhPSAwKSB7CisgICAgICAgICAgICByZXR1cm4gaGFzaENvZGU7CisgICAgICAgIH0KKyAgICAgICAgcHJlcGFyZUphdmFSZXByZXNlbnRhdGlvbigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bWJlckxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICBoYXNoQ29kZSA9IGhhc2hDb2RlICogMzMgKyBkaWdpdHNbaV07CisgICAgICAgIH0KKyAgICAgICAgaGFzaENvZGUgPSBoYXNoQ29kZSAqIHNpZ247CisgICAgICAgIHJldHVybiBoYXNoQ29kZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHgpIHsKKyAgICAgICAgaWYgKHRoaXMgPT0geCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHggaW5zdGFuY2VvZiBCaWdJbnRlZ2VyKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpcy5jb21wYXJlVG8oKEJpZ0ludGVnZXIpIHgpID09IDA7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgQmlnSW50ZWdlcn0gaW4gZGVjaW1hbAorICAgICAqIGZvcm0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIGdldEJpZ0ludCgpLmRlY1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZQorICAgICAqIEJpZ0ludGVnZXJ9IHdpdGggYmFzZSByYWRpeC4gSWYge0Bjb2RlIHJhZGl4IDwgQ2hhcmFjdGVyLk1JTl9SQURJWH0gb3IKKyAgICAgKiB7QGNvZGUgcmFkaXggPiBDaGFyYWN0ZXIuTUFYX1JBRElYfSB0aGVuIGEgZGVjaW1hbCByZXByZXNlbnRhdGlvbiBpcworICAgICAqIHJldHVybmVkLiBUaGUgY2hhcmFjdGVycyBvZiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGFyZSBnZW5lcmF0ZWQgd2l0aAorICAgICAqIG1ldGhvZCB7QGNvZGUgQ2hhcmFjdGVyLmZvckRpZ2l0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByYWRpeCBiYXNlIHRvIGJlIHVzZWQgZm9yIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZyhpbnQgcmFkaXgpIHsKKyAgICAgICAgaWYgKHJhZGl4ID09IDEwKSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0QmlnSW50KCkuZGVjU3RyaW5nKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBwcmVwYXJlSmF2YVJlcHJlc2VudGF0aW9uKCk7CisgICAgICAgICAgICByZXR1cm4gQ29udmVyc2lvbi5iaWdJbnRlZ2VyMlN0cmluZyh0aGlzLCByYWRpeCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIEJpZ0ludGVnZXJ9IHdob3NlIHZhbHVlIGlzIGdyZWF0ZXN0IGNvbW1vbiBkaXZpc29yCisgICAgICogb2Yge0Bjb2RlIHRoaXN9IGFuZCB7QGNvZGUgdmFsdWV9LiBJZiB7QGNvZGUgdGhpcyA9PSAwfSBhbmQge0Bjb2RlCisgICAgICogdmFsdWUgPT0gMH0gdGhlbiB6ZXJvIGlzIHJldHVybmVkLCBvdGhlcndpc2UgdGhlIHJlc3VsdCBpcyBwb3NpdGl2ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSB3aXRoIHdoaWNoIHRoZSBncmVhdGVzdCBjb21tb24gZGl2aXNvciBpcyBjb21wdXRlZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSB2YWx1ZSA9PSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnY2QoQmlnSW50ZWdlciB2YWx1ZSkgeworICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoQmlnSW50LmdjZChnZXRCaWdJbnQoKSwgdmFsdWUuZ2V0QmlnSW50KCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIEJpZ0ludGVnZXJ9IHdob3NlIHZhbHVlIGlzIHtAY29kZSB0aGlzICogdmFsdWV9LgorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgdmFsdWUgPT0gbnVsbH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgbXVsdGlwbHkoQmlnSW50ZWdlciB2YWx1ZSkgeworICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoQmlnSW50LnByb2R1Y3QoZ2V0QmlnSW50KCksIHZhbHVlLmdldEJpZ0ludCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBCaWdJbnRlZ2VyfSB3aG9zZSB2YWx1ZSBpcyB7QGNvZGUgcG93KHRoaXMsIGV4cCl9LgorICAgICAqCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uIGlmIHtAY29kZSBleHAgPCAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBwb3coaW50IGV4cCkgeworICAgICAgICBpZiAoZXhwIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFyaXRobWV0aWNFeGNlcHRpb24oImV4cCA8IDA6ICIgKyBleHApOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcihCaWdJbnQuZXhwKGdldEJpZ0ludCgpLCBleHApKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgdHdvIGVsZW1lbnQge0Bjb2RlIEJpZ0ludGVnZXJ9IGFycmF5IGNvbnRhaW5pbmcKKyAgICAgKiB7QGNvZGUgdGhpcyAvIGRpdmlzb3J9IGF0IGluZGV4IDAgYW5kIHtAY29kZSB0aGlzICUgZGl2aXNvcn0gYXQgaW5kZXggMS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkaXZpc29yIHZhbHVlIGJ5IHdoaWNoIHtAY29kZSB0aGlzfSBpcyBkaXZpZGVkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIGRpdmlzb3IgPT0gbnVsbH0uCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uIGlmIHtAY29kZSBkaXZpc29yID09IDB9LgorICAgICAqIEBzZWUgI2RpdmlkZQorICAgICAqIEBzZWUgI3JlbWFpbmRlcgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyW10gZGl2aWRlQW5kUmVtYWluZGVyKEJpZ0ludGVnZXIgZGl2aXNvcikgeworICAgICAgICBCaWdJbnQgZGl2aXNvckJpZ0ludCA9IGRpdmlzb3IuZ2V0QmlnSW50KCk7CisgICAgICAgIEJpZ0ludCBxdW90aWVudCA9IG5ldyBCaWdJbnQoKTsKKyAgICAgICAgQmlnSW50IHJlbWFpbmRlciA9IG5ldyBCaWdJbnQoKTsKKyAgICAgICAgQmlnSW50LmRpdmlzaW9uKGdldEJpZ0ludCgpLCBkaXZpc29yQmlnSW50LCBxdW90aWVudCwgcmVtYWluZGVyKTsKKyAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyW10ge25ldyBCaWdJbnRlZ2VyKHF1b3RpZW50KSwgbmV3IEJpZ0ludGVnZXIocmVtYWluZGVyKSB9OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgQmlnSW50ZWdlcn0gd2hvc2UgdmFsdWUgaXMge0Bjb2RlIHRoaXMgLyBkaXZpc29yfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkaXZpc29yIHZhbHVlIGJ5IHdoaWNoIHtAY29kZSB0aGlzfSBpcyBkaXZpZGVkLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXMgLyBkaXZpc29yfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBkaXZpc29yID09IG51bGx9LgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbiBpZiB7QGNvZGUgZGl2aXNvciA9PSAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBkaXZpZGUoQmlnSW50ZWdlciBkaXZpc29yKSB7CisgICAgICAgIEJpZ0ludCBxdW90aWVudCA9IG5ldyBCaWdJbnQoKTsKKyAgICAgICAgQmlnSW50LmRpdmlzaW9uKGdldEJpZ0ludCgpLCBkaXZpc29yLmdldEJpZ0ludCgpLCBxdW90aWVudCwgbnVsbCk7CisgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcihxdW90aWVudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBCaWdJbnRlZ2VyfSB3aG9zZSB2YWx1ZSBpcyB7QGNvZGUgdGhpcyAlIGRpdmlzb3J9LgorICAgICAqIFJlZ2FyZGluZyBzaWducyB0aGlzIG1ldGhvZHMgaGFzIHRoZSBzYW1lIGJlaGF2aW9yIGFzIHRoZSAlIG9wZXJhdG9yIG9uCisgICAgICogaW50czogdGhlIHNpZ24gb2YgdGhlIHJlbWFpbmRlciBpcyB0aGUgc2FtZSBhcyB0aGUgc2lnbiBvZiB0aGlzLgorICAgICAqCisgICAgICogQHBhcmFtIGRpdmlzb3IgdmFsdWUgYnkgd2hpY2gge0Bjb2RlIHRoaXN9IGlzIGRpdmlkZWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgZGl2aXNvciA9PSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIEFyaXRobWV0aWNFeGNlcHRpb24gaWYge0Bjb2RlIGRpdmlzb3IgPT0gMH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgcmVtYWluZGVyKEJpZ0ludGVnZXIgZGl2aXNvcikgeworICAgICAgICBCaWdJbnQgcmVtYWluZGVyID0gbmV3IEJpZ0ludCgpOworICAgICAgICBCaWdJbnQuZGl2aXNpb24oZ2V0QmlnSW50KCksIGRpdmlzb3IuZ2V0QmlnSW50KCksIG51bGwsIHJlbWFpbmRlcik7CisgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcihyZW1haW5kZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgQmlnSW50ZWdlcn0gd2hvc2UgdmFsdWUgaXMge0Bjb2RlIDEvdGhpcyBtb2QgbX0uIFRoZQorICAgICAqIG1vZHVsdXMge0Bjb2RlIG19IG11c3QgYmUgcG9zaXRpdmUuIFRoZSByZXN1bHQgaXMgZ3VhcmFudGVlZCB0byBiZSBpbiB0aGUKKyAgICAgKiBpbnRlcnZhbCB7QGNvZGUgWzAsIG0pfSAoMCBpbmNsdXNpdmUsIG0gZXhjbHVzaXZlKS4gSWYge0Bjb2RlIHRoaXN9IGlzCisgICAgICogbm90IHJlbGF0aXZlbHkgcHJpbWUgdG8gbSwgdGhlbiBhbiBleGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHBhcmFtIG0gdGhlIG1vZHVsdXMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgbSA9PSBudWxsfQorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbiBpZiB7QGNvZGUgbSA8IDAgb3J9IGlmIHtAY29kZSB0aGlzfSBpcyBub3QKKyAgICAgKiAgICAgcmVsYXRpdmVseSBwcmltZSB0byB7QGNvZGUgbX0KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBtb2RJbnZlcnNlKEJpZ0ludGVnZXIgbSkgeworICAgICAgICBpZiAobS5zaWdudW0oKSA8PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJpdGhtZXRpY0V4Y2VwdGlvbigibW9kdWx1cyBub3QgcG9zaXRpdmUiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoQmlnSW50Lm1vZEludmVyc2UoZ2V0QmlnSW50KCksIG0uZ2V0QmlnSW50KCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIEJpZ0ludGVnZXJ9IHdob3NlIHZhbHVlIGlzIHtAY29kZQorICAgICAqIHBvdyh0aGlzLCBleHBvbmVudCkgbW9kIG19LiBUaGUgbW9kdWx1cyB7QGNvZGUgbX0gbXVzdCBiZSBwb3NpdGl2ZS4gVGhlCisgICAgICogcmVzdWx0IGlzIGd1YXJhbnRlZWQgdG8gYmUgaW4gdGhlIGludGVydmFsIHtAY29kZSBbMCwgbSl9ICgwIGluY2x1c2l2ZSwKKyAgICAgKiBtIGV4Y2x1c2l2ZSkuIElmIHRoZSBleHBvbmVudCBpcyBuZWdhdGl2ZSwgdGhlbiB7QGNvZGUKKyAgICAgKiBwb3codGhpcy5tb2RJbnZlcnNlKG0pLCAtZXhwb25lbnQpIG1vZCBtfSBpcyBjb21wdXRlZC4gVGhlIGludmVyc2Ugb2YKKyAgICAgKiB0aGlzIG9ubHkgZXhpc3RzIGlmIHtAY29kZSB0aGlzfSBpcyByZWxhdGl2ZWx5IHByaW1lIHRvIG0sIG90aGVyd2lzZSBhbgorICAgICAqIGV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhwb25lbnQgdGhlIGV4cG9uZW50LgorICAgICAqIEBwYXJhbSBtIHRoZSBtb2R1bHVzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIG0gPT0gbnVsbH0gb3Ige0Bjb2RlIGV4cG9uZW50ID09CisgICAgICogICAgIG51bGx9LgorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbiBpZiB7QGNvZGUgbSA8IDB9IG9yIGlmIHtAY29kZSBleHBvbmVudDwwfSBhbmQKKyAgICAgKiAgICAgdGhpcyBpcyBub3QgcmVsYXRpdmVseSBwcmltZSB0byB7QGNvZGUgbX0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgbW9kUG93KEJpZ0ludGVnZXIgZXhwb25lbnQsIEJpZ0ludGVnZXIgbSkgeworICAgICAgICBpZiAobS5zaWdudW0oKSA8PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJpdGhtZXRpY0V4Y2VwdGlvbigibS5zaWdudW0oKSA8PSAwIik7CisgICAgICAgIH0KKyAgICAgICAgQmlnSW50ZWdlciBiYXNlID0gZXhwb25lbnQuc2lnbnVtKCkgPCAwID8gbW9kSW52ZXJzZShtKSA6IHRoaXM7CisgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcihCaWdJbnQubW9kRXhwKGJhc2UuZ2V0QmlnSW50KCksIGV4cG9uZW50LmdldEJpZ0ludCgpLCBtLmdldEJpZ0ludCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBCaWdJbnRlZ2VyfSB3aG9zZSB2YWx1ZSBpcyB7QGNvZGUgdGhpcyBtb2QgbX0uIFRoZQorICAgICAqIG1vZHVsdXMge0Bjb2RlIG19IG11c3QgYmUgcG9zaXRpdmUuIFRoZSByZXN1bHQgaXMgZ3VhcmFudGVlZCB0byBiZSBpbiB0aGUKKyAgICAgKiBpbnRlcnZhbCB7QGNvZGUgWzAsIG0pfSAoMCBpbmNsdXNpdmUsIG0gZXhjbHVzaXZlKS4gVGhlIGJlaGF2aW9yIG9mIHRoaXMKKyAgICAgKiBmdW5jdGlvbiBpcyBub3QgZXF1aXZhbGVudCB0byB0aGUgYmVoYXZpb3Igb2YgdGhlICUgb3BlcmF0b3IgZGVmaW5lZCBmb3IKKyAgICAgKiB0aGUgYnVpbHQtaW4ge0Bjb2RlIGludH0ncy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtIHRoZSBtb2R1bHVzLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXMgbW9kIG19LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIG0gPT0gbnVsbH0uCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uIGlmIHtAY29kZSBtIDwgMH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgbW9kKEJpZ0ludGVnZXIgbSkgeworICAgICAgICBpZiAobS5zaWdudW0oKSA8PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJpdGhtZXRpY0V4Y2VwdGlvbigibS5zaWdudW0oKSA8PSAwIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKEJpZ0ludC5tb2R1bHVzKGdldEJpZ0ludCgpLCBtLmdldEJpZ0ludCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgd2hldGhlciB0aGlzIHtAY29kZSBCaWdJbnRlZ2VyfSBpcyBwcm9iYWJseSBwcmltZS4gSWYge0Bjb2RlIHRydWV9CisgICAgICogaXMgcmV0dXJuZWQsIHRoZW4gdGhpcyBpcyBwcmltZSB3aXRoIGEgcHJvYmFiaWxpdHkgYmV5b25kCisgICAgICoge0Bjb2RlIDEgLSAxL3BvdygyLCBjZXJ0YWludHkpfS4gSWYge0Bjb2RlIGZhbHNlfSBpcyByZXR1cm5lZCwgdGhlbiB0aGlzCisgICAgICogaXMgZGVmaW5pdGVseSBjb21wb3NpdGUuIElmIHRoZSBhcmd1bWVudCB7QGNvZGUgY2VydGFpbnR5fSA8PSAwLCB0aGVuCisgICAgICogdGhpcyBtZXRob2QgcmV0dXJucyB0cnVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNlcnRhaW50eSB0b2xlcmF0ZWQgcHJpbWFsaXR5IHVuY2VydGFpbnR5LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9LCBpZiB7QGNvZGUgdGhpc30gaXMgcHJvYmFibHkgcHJpbWUsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUHJvYmFibGVQcmltZShpbnQgY2VydGFpbnR5KSB7CisgICAgICAgIGlmIChjZXJ0YWludHkgPD0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEJpZ0ludCgpLmlzUHJpbWUoY2VydGFpbnR5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzbWFsbGVzdCBpbnRlZ2VyIHggPiB7QGNvZGUgdGhpc30gd2hpY2ggaXMgcHJvYmFibHkgcHJpbWUgYXMKKyAgICAgKiBhIHtAY29kZSBCaWdJbnRlZ2VyfSBpbnN0YW5jZS4gVGhlIHByb2JhYmlsaXR5IHRoYXQgdGhlIHJldHVybmVkIHtAY29kZQorICAgICAqIEJpZ0ludGVnZXJ9IGlzIHByaW1lIGlzIGJleW9uZCB7QGNvZGUgMSAtIDEvcG93KDIsIDgwKX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHNtYWxsZXN0IGludGVnZXIgPiB7QGNvZGUgdGhpc30gd2hpY2ggaXMgcHJvYmFibHkgcHJpbWUuCisgICAgICogQHRocm93cyBBcml0aG1ldGljRXhjZXB0aW9uIGlmIHtAY29kZSB0aGlzIDwgMH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgbmV4dFByb2JhYmxlUHJpbWUoKSB7CisgICAgICAgIGlmIChzaWduIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFyaXRobWV0aWNFeGNlcHRpb24oInNpZ24gPCAwIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIFByaW1hbGl0eS5uZXh0UHJvYmFibGVQcmltZSh0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcmFuZG9tIHBvc2l0aXZlIHtAY29kZSBCaWdJbnRlZ2VyfSBpbnN0YW5jZSBpbiB0aGUgcmFuZ2Uge0Bjb2RlCisgICAgICogWzAsIHBvdygyLCBiaXRMZW5ndGgpLTFdfSB3aGljaCBpcyBwcm9iYWJseSBwcmltZS4gVGhlIHByb2JhYmlsaXR5IHRoYXQKKyAgICAgKiB0aGUgcmV0dXJuZWQge0Bjb2RlIEJpZ0ludGVnZXJ9IGlzIHByaW1lIGlzIGJleW9uZCB7QGNvZGUKKyAgICAgKiAxIC0gMS9wb3coMiwgODApfS4KKyAgICAgKgorICAgICAqIDxwPjxiPkltcGxlbWVudGF0aW9uIE5vdGU6PC9iPiBDdXJyZW50bHkge0Bjb2RlIHJhbmRvbX0gaXMgaWdub3JlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBiaXRMZW5ndGggbGVuZ3RoIG9mIHRoZSBuZXcge0Bjb2RlIEJpZ0ludGVnZXJ9IGluIGJpdHMuCisgICAgICogQHJldHVybiBwcm9iYWJseSBwcmltZSByYW5kb20ge0Bjb2RlIEJpZ0ludGVnZXJ9IGluc3RhbmNlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBiaXRMZW5ndGggPCAyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEJpZ0ludGVnZXIgcHJvYmFibGVQcmltZShpbnQgYml0TGVuZ3RoLCBSYW5kb20gdW51c2VkKSB7CisgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcihiaXRMZW5ndGgsIDEwMCwgdW51c2VkKTsKKyAgICB9CisKKyAgICAvKiBQcml2YXRlIE1ldGhvZHMgKi8KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHR3bydzIGNvbXBsZW1lbnQgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBCaWdJbnRlZ2VyIGluIGEgYnl0ZQorICAgICAqIGFycmF5LgorICAgICAqCisgICAgICogQHJldHVybiB0d28ncyBjb21wbGVtZW50IHJlcHJlc2VudGF0aW9uIG9mIHtAY29kZSB0aGlzfQorICAgICAqLworICAgIHByaXZhdGUgYnl0ZVtdIHR3b3NDb21wbGVtZW50KCkgeworICAgICAgICBwcmVwYXJlSmF2YVJlcHJlc2VudGF0aW9uKCk7CisgICAgICAgIGlmICh0aGlzLnNpZ24gPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBieXRlW10geyAwIH07CisgICAgICAgIH0KKyAgICAgICAgQmlnSW50ZWdlciB0ZW1wID0gdGhpczsKKyAgICAgICAgaW50IGJpdExlbiA9IGJpdExlbmd0aCgpOworICAgICAgICBpbnQgaVRoaXMgPSBnZXRGaXJzdE5vbnplcm9EaWdpdCgpOworICAgICAgICBpbnQgYnl0ZXNMZW4gPSAoYml0TGVuID4+IDMpICsgMTsKKyAgICAgICAgLyogUHV0cyB0aGUgbGl0dGxlLWVuZGlhbiBpbnQgYXJyYXkgcmVwcmVzZW50aW5nIHRoZSBtYWduaXR1ZGUKKyAgICAgICAgICogb2YgdGhpcyBCaWdJbnRlZ2VyIGludG8gdGhlIGJpZy1lbmRpYW4gYnl0ZSBhcnJheS4gKi8KKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbYnl0ZXNMZW5dOworICAgICAgICBpbnQgZmlyc3RCeXRlTnVtYmVyID0gMDsKKyAgICAgICAgaW50IGhpZ2hCeXRlczsKKyAgICAgICAgaW50IGJ5dGVzSW5JbnRlZ2VyID0gNDsKKyAgICAgICAgaW50IGhCOworCisgICAgICAgIGlmIChieXRlc0xlbiAtIChudW1iZXJMZW5ndGggPDwgMikgPT0gMSkgeworICAgICAgICAgICAgYnl0ZXNbMF0gPSAoYnl0ZSkgKChzaWduIDwgMCkgPyAtMSA6IDApOworICAgICAgICAgICAgaGlnaEJ5dGVzID0gNDsKKyAgICAgICAgICAgIGZpcnN0Qnl0ZU51bWJlcisrOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaEIgPSBieXRlc0xlbiAmIDM7CisgICAgICAgICAgICBoaWdoQnl0ZXMgPSAoaEIgPT0gMCkgPyA0IDogaEI7CisgICAgICAgIH0KKworICAgICAgICBpbnQgZGlnaXRJbmRleCA9IGlUaGlzOworICAgICAgICBieXRlc0xlbiAtPSBpVGhpcyA8PCAyOworCisgICAgICAgIGlmIChzaWduIDwgMCkgeworICAgICAgICAgICAgaW50IGRpZ2l0ID0gLXRlbXAuZGlnaXRzW2RpZ2l0SW5kZXhdOworICAgICAgICAgICAgZGlnaXRJbmRleCsrOworICAgICAgICAgICAgaWYgKGRpZ2l0SW5kZXggPT0gbnVtYmVyTGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgYnl0ZXNJbkludGVnZXIgPSBoaWdoQnl0ZXM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ5dGVzSW5JbnRlZ2VyOyBpKyssIGRpZ2l0ID4+PSA4KSB7CisgICAgICAgICAgICAgICAgYnl0ZXNbLS1ieXRlc0xlbl0gPSAoYnl0ZSkgZGlnaXQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB3aGlsZSAoYnl0ZXNMZW4gPiBmaXJzdEJ5dGVOdW1iZXIpIHsKKyAgICAgICAgICAgICAgICBkaWdpdCA9IH50ZW1wLmRpZ2l0c1tkaWdpdEluZGV4XTsKKyAgICAgICAgICAgICAgICBkaWdpdEluZGV4Kys7CisgICAgICAgICAgICAgICAgaWYgKGRpZ2l0SW5kZXggPT0gbnVtYmVyTGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVzSW5JbnRlZ2VyID0gaGlnaEJ5dGVzOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ5dGVzSW5JbnRlZ2VyOyBpKyssIGRpZ2l0ID4+PSA4KSB7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVzWy0tYnl0ZXNMZW5dID0gKGJ5dGUpIGRpZ2l0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHdoaWxlIChieXRlc0xlbiA+IGZpcnN0Qnl0ZU51bWJlcikgeworICAgICAgICAgICAgICAgIGludCBkaWdpdCA9IHRlbXAuZGlnaXRzW2RpZ2l0SW5kZXhdOworICAgICAgICAgICAgICAgIGRpZ2l0SW5kZXgrKzsKKyAgICAgICAgICAgICAgICBpZiAoZGlnaXRJbmRleCA9PSBudW1iZXJMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgYnl0ZXNJbkludGVnZXIgPSBoaWdoQnl0ZXM7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYnl0ZXNJbkludGVnZXI7IGkrKywgZGlnaXQgPj49IDgpIHsKKyAgICAgICAgICAgICAgICAgICAgYnl0ZXNbLS1ieXRlc0xlbl0gPSAoYnl0ZSkgZGlnaXQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBieXRlczsKKyAgICB9CisKKworICAgIHN0YXRpYyBpbnQgbXVsdGlwbHlCeUludChpbnRbXSByZXMsIGludFtdIGEsIGludCBhU2l6ZSwgaW50IGZhY3RvcikgeworICAgICAgICBsb25nIGNhcnJ5ID0gMDsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFTaXplOyBpKyspIHsKKyAgICAgICAgICAgIGNhcnJ5ICs9IChhW2ldICYgMHhGRkZGRkZGRkwpICogKGZhY3RvciAmIDB4RkZGRkZGRkZMKTsKKyAgICAgICAgICAgIHJlc1tpXSA9IChpbnQpIGNhcnJ5OworICAgICAgICAgICAgY2FycnkgPj4+PSAzMjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKGludCkgY2Fycnk7CisgICAgfQorCisgICAgc3RhdGljIGludCBpbnBsYWNlQWRkKGludFtdIGEsIGludCBhU2l6ZSwgaW50IGFkZGVuZCkgeworICAgICAgICBsb25nIGNhcnJ5ID0gYWRkZW5kICYgMHhGRkZGRkZGRkw7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IChjYXJyeSAhPSAwKSAmJiAoaSA8IGFTaXplKTsgaSsrKSB7CisgICAgICAgICAgICBjYXJyeSArPSBhW2ldICYgMHhGRkZGRkZGRkw7CisgICAgICAgICAgICBhW2ldID0gKGludCkgY2Fycnk7CisgICAgICAgICAgICBjYXJyeSA+Pj0gMzI7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChpbnQpIGNhcnJ5OworICAgIH0KKworICAgIC8qKiBAc2VlIEJpZ0ludGVnZXIjQmlnSW50ZWdlcihTdHJpbmcsIGludCkgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHBhcnNlRnJvbVN0cmluZyhCaWdJbnRlZ2VyIGJpLCBTdHJpbmcgdmFsdWUsIGludCByYWRpeCkgeworICAgICAgICBpbnQgc3RyaW5nTGVuZ3RoID0gdmFsdWUubGVuZ3RoKCk7CisgICAgICAgIGludCBlbmRDaGFyID0gc3RyaW5nTGVuZ3RoOworCisgICAgICAgIGludCBzaWduOworICAgICAgICBpbnQgc3RhcnRDaGFyOworICAgICAgICBpZiAodmFsdWUuY2hhckF0KDApID09ICctJykgeworICAgICAgICAgICAgc2lnbiA9IC0xOworICAgICAgICAgICAgc3RhcnRDaGFyID0gMTsKKyAgICAgICAgICAgIHN0cmluZ0xlbmd0aC0tOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc2lnbiA9IDE7CisgICAgICAgICAgICBzdGFydENoYXIgPSAwOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogV2UgdXNlIHRoZSBmb2xsb3dpbmcgYWxnb3JpdGhtOiBzcGxpdCBhIHN0cmluZyBpbnRvIHBvcnRpb25zIG9mIG4KKyAgICAgICAgICogY2hhcmFjdGVycyBhbmQgY29udmVydCBlYWNoIHBvcnRpb24gdG8gYW4gaW50ZWdlciBhY2NvcmRpbmcgdG8gdGhlCisgICAgICAgICAqIHJhZGl4LiBUaGVuIGNvbnZlcnQgYW4gcG93KHJhZGl4LCBuKSBiYXNlZCBudW1iZXIgdG8gYmluYXJ5IHVzaW5nIHRoZQorICAgICAgICAgKiBtdWx0aXBsaWNhdGlvbiBtZXRob2QuIFNlZSBELiBLbnV0aCwgVGhlIEFydCBvZiBDb21wdXRlciBQcm9ncmFtbWluZywKKyAgICAgICAgICogdm9sLiAyLgorICAgICAgICAgKi8KKworICAgICAgICBpbnQgY2hhcnNQZXJJbnQgPSBDb252ZXJzaW9uLmRpZ2l0Rml0SW5JbnRbcmFkaXhdOworICAgICAgICBpbnQgYmlnUmFkaXhEaWdpdHNMZW5ndGggPSBzdHJpbmdMZW5ndGggLyBjaGFyc1BlckludDsKKyAgICAgICAgaW50IHRvcENoYXJzID0gc3RyaW5nTGVuZ3RoICUgY2hhcnNQZXJJbnQ7CisKKyAgICAgICAgaWYgKHRvcENoYXJzICE9IDApIHsKKyAgICAgICAgICAgIGJpZ1JhZGl4RGlnaXRzTGVuZ3RoKys7CisgICAgICAgIH0KKyAgICAgICAgaW50W10gZGlnaXRzID0gbmV3IGludFtiaWdSYWRpeERpZ2l0c0xlbmd0aF07CisgICAgICAgIC8vIEdldCB0aGUgbWF4aW1hbCBwb3dlciBvZiByYWRpeCB0aGF0IGZpdHMgaW4gaW50CisgICAgICAgIGludCBiaWdSYWRpeCA9IENvbnZlcnNpb24uYmlnUmFkaWNlc1tyYWRpeCAtIDJdOworICAgICAgICAvLyBQYXJzZSBhbiBpbnB1dCBzdHJpbmcgYW5kIGFjY3VtdWxhdGUgdGhlIEJpZ0ludGVnZXIncyBtYWduaXR1ZGUKKyAgICAgICAgaW50IGRpZ2l0SW5kZXggPSAwOyAvLyBpbmRleCBvZiBkaWdpdHMgYXJyYXkKKyAgICAgICAgaW50IHN1YnN0ckVuZCA9IHN0YXJ0Q2hhciArICgodG9wQ2hhcnMgPT0gMCkgPyBjaGFyc1BlckludCA6IHRvcENoYXJzKTsKKworICAgICAgICBmb3IgKGludCBzdWJzdHJTdGFydCA9IHN0YXJ0Q2hhcjsgc3Vic3RyU3RhcnQgPCBlbmRDaGFyOworICAgICAgICAgICAgICAgIHN1YnN0clN0YXJ0ID0gc3Vic3RyRW5kLCBzdWJzdHJFbmQgPSBzdWJzdHJTdGFydCArIGNoYXJzUGVySW50KSB7CisgICAgICAgICAgICBpbnQgYmlnUmFkaXhEaWdpdCA9IEludGVnZXIucGFyc2VJbnQodmFsdWUuc3Vic3RyaW5nKHN1YnN0clN0YXJ0LCBzdWJzdHJFbmQpLCByYWRpeCk7CisgICAgICAgICAgICBpbnQgbmV3RGlnaXQgPSBtdWx0aXBseUJ5SW50KGRpZ2l0cywgZGlnaXRzLCBkaWdpdEluZGV4LCBiaWdSYWRpeCk7CisgICAgICAgICAgICBuZXdEaWdpdCArPSBpbnBsYWNlQWRkKGRpZ2l0cywgZGlnaXRJbmRleCwgYmlnUmFkaXhEaWdpdCk7CisgICAgICAgICAgICBkaWdpdHNbZGlnaXRJbmRleCsrXSA9IG5ld0RpZ2l0OworICAgICAgICB9CisgICAgICAgIGludCBudW1iZXJMZW5ndGggPSBkaWdpdEluZGV4OworICAgICAgICBiaS5zZXRKYXZhUmVwcmVzZW50YXRpb24oc2lnbiwgbnVtYmVyTGVuZ3RoLCBkaWdpdHMpOworICAgIH0KKworICAgIGludCBnZXRGaXJzdE5vbnplcm9EaWdpdCgpIHsKKyAgICAgICAgaWYgKGZpcnN0Tm9uemVyb0RpZ2l0ID09IC0yKSB7CisgICAgICAgICAgICBpbnQgaTsKKyAgICAgICAgICAgIGlmICh0aGlzLnNpZ24gPT0gMCkgeworICAgICAgICAgICAgICAgIGkgPSAtMTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgZGlnaXRzW2ldID09IDA7IGkrKykgeworICAgICAgICAgICAgICAgICAgICA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgZmlyc3ROb256ZXJvRGlnaXQgPSBpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmaXJzdE5vbnplcm9EaWdpdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29weSBvZiB0aGUgY3VycmVudCBpbnN0YW5jZSB0byBhY2hpZXZlIGltbXV0YWJpbGl0eQorICAgICAqLworICAgIEJpZ0ludGVnZXIgY29weSgpIHsKKyAgICAgICAgcHJlcGFyZUphdmFSZXByZXNlbnRhdGlvbigpOworICAgICAgICBpbnRbXSBjb3B5RGlnaXRzID0gbmV3IGludFtudW1iZXJMZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRpZ2l0cywgMCwgY29weURpZ2l0cywgMCwgbnVtYmVyTGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKHNpZ24sIG51bWJlckxlbmd0aCwgY29weURpZ2l0cyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzaWducyBhbGwgdHJhbnNpZW50IGZpZWxkcyB1cG9uIGRlc2VyaWFsaXphdGlvbiBvZiBhIHtAY29kZSBCaWdJbnRlZ2VyfQorICAgICAqIGluc3RhbmNlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIGluKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgaW4uZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgQmlnSW50IGJpZ0ludCA9IG5ldyBCaWdJbnQoKTsKKyAgICAgICAgYmlnSW50LnB1dEJpZ0VuZGlhbihtYWduaXR1ZGUsIHNpZ251bSA8IDApOworICAgICAgICBzZXRCaWdJbnQoYmlnSW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmVwYXJlcyB0aGlzIHtAY29kZSBCaWdJbnRlZ2VyfSBmb3Igc2VyaWFsaXphdGlvbiwgaS5lLiB0aGUKKyAgICAgKiBub24tdHJhbnNpZW50IGZpZWxkcyB7QGNvZGUgc2lnbnVtfSBhbmQge0Bjb2RlIG1hZ25pdHVkZX0gYXJlIGFzc2lnbmVkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCaWdJbnQgYmlnSW50ID0gZ2V0QmlnSW50KCk7CisgICAgICAgIHNpZ251bSA9IGJpZ0ludC5zaWduKCk7CisgICAgICAgIG1hZ25pdHVkZSA9IGJpZ0ludC5iaWdFbmRpYW5NYWduaXR1ZGUoKTsKKyAgICAgICAgb3V0LmRlZmF1bHRXcml0ZU9iamVjdCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL21hdGgvQml0TGV2ZWwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL21hdGgvQml0TGV2ZWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MWY3YTliCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbWF0aC9CaXRMZXZlbC5qYXZhCkBAIC0wLDAgKzEsMjU1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubWF0aDsKKworLyoqCisgKiBTdGF0aWMgbGlicmFyeSB0aGF0IHByb3ZpZGVzIGFsbCB0aGUgPGI+Yml0IGxldmVsPC9iPiBvcGVyYXRpb25zIGZvcgorICoge0BsaW5rIEJpZ0ludGVnZXJ9LiBUaGUgb3BlcmF0aW9ucyBhcmU6CisgKiA8dWwgdHlwZT0iY2lyY2xlIj4KKyAqIDxsaT5MZWZ0IFNoaWZ0aW5nPC9saT4KKyAqIDxsaT5SaWdodCBTaGlmdGluZzwvbGk+CisgKiA8bGk+Qml0IGNsZWFyaW5nPC9saT4KKyAqIDxsaT5CaXQgc2V0dGluZzwvbGk+CisgKiA8bGk+Qml0IGNvdW50aW5nPC9saT4KKyAqIDxsaT5CaXQgdGVzdGluZzwvbGk+CisgKiA8bGk+R2V0dGluZyBvZiB0aGUgbG93ZXN0IGJpdCBzZXQ8L2xpPgorICogPC91bD4KKyAqIEFsbCBvcGVyYXRpb25zIGFyZSBwcm92aWRlZCBpbiBpbW11dGFibGUgd2F5LCBhbmQgc29tZSBpbiBib3RoIG11dGFibGUgYW5kCisgKiBpbW11dGFibGUuCisgKi8KK2NsYXNzIEJpdExldmVsIHsKKworICAgIC8qKiBKdXN0IHRvIGRlbm90ZSB0aGF0IHRoaXMgY2xhc3MgY2FuJ3QgYmUgaW5zdGFudGlhdGVkLiAqLworICAgIHByaXZhdGUgQml0TGV2ZWwoKSB7fQorCisgICAgLyoqIEBzZWUgQmlnSW50ZWdlciNiaXRMZW5ndGgoKSAqLworICAgIHN0YXRpYyBpbnQgYml0TGVuZ3RoKEJpZ0ludGVnZXIgdmFsKSB7CisgICAgICAgIHZhbC5wcmVwYXJlSmF2YVJlcHJlc2VudGF0aW9uKCk7CisgICAgICAgIGlmICh2YWwuc2lnbiA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICBpbnQgYkxlbmd0aCA9ICh2YWwubnVtYmVyTGVuZ3RoIDw8IDUpOworICAgICAgICBpbnQgaGlnaERpZ2l0ID0gdmFsLmRpZ2l0c1t2YWwubnVtYmVyTGVuZ3RoIC0gMV07CisKKyAgICAgICAgaWYgKHZhbC5zaWduIDwgMCkgeworICAgICAgICAgICAgaW50IGkgPSB2YWwuZ2V0Rmlyc3ROb256ZXJvRGlnaXQoKTsKKyAgICAgICAgICAgIC8vIFdlIHJlZHVjZSB0aGUgcHJvYmxlbSB0byB0aGUgcG9zaXRpdmUgY2FzZS4KKyAgICAgICAgICAgIGlmIChpID09IHZhbC5udW1iZXJMZW5ndGggLSAxKSB7CisgICAgICAgICAgICAgICAgaGlnaERpZ2l0LS07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gU3VidHJhY3RpbmcgYWxsIHNpZ24gYml0cworICAgICAgICBiTGVuZ3RoIC09IEludGVnZXIubnVtYmVyT2ZMZWFkaW5nWmVyb3MoaGlnaERpZ2l0KTsKKyAgICAgICAgcmV0dXJuIGJMZW5ndGg7CisgICAgfQorCisgICAgLyoqIEBzZWUgQmlnSW50ZWdlciNiaXRDb3VudCgpICovCisgICAgc3RhdGljIGludCBiaXRDb3VudChCaWdJbnRlZ2VyIHZhbCkgeworICAgICAgICB2YWwucHJlcGFyZUphdmFSZXByZXNlbnRhdGlvbigpOworICAgICAgICBpbnQgYkNvdW50ID0gMDsKKworICAgICAgICBpZiAodmFsLnNpZ24gPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBpbnQgaSA9IHZhbC5nZXRGaXJzdE5vbnplcm9EaWdpdCgpOworICAgICAgICBpZiAodmFsLnNpZ24gPiAwKSB7CisgICAgICAgICAgICBmb3IgKCA7IGkgPCB2YWwubnVtYmVyTGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBiQ291bnQgKz0gSW50ZWdlci5iaXRDb3VudCh2YWwuZGlnaXRzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsvLyAoc2lnbiA8IDApCisgICAgICAgICAgICAvLyB0aGlzIGRpZ2l0IGFic29yYnMgdGhlIGNhcnJ5CisgICAgICAgICAgICBiQ291bnQgKz0gSW50ZWdlci5iaXRDb3VudCgtdmFsLmRpZ2l0c1tpXSk7CisgICAgICAgICAgICBmb3IgKGkrKzsgaSA8IHZhbC5udW1iZXJMZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGJDb3VudCArPSBJbnRlZ2VyLmJpdENvdW50KH52YWwuZGlnaXRzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIFdlIHRha2UgdGhlIGNvbXBsZW1lbnQgc3VtOgorICAgICAgICAgICAgYkNvdW50ID0gKHZhbC5udW1iZXJMZW5ndGggPDwgNSkgLSBiQ291bnQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJDb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGZhc3QgYml0IHRlc3RpbmcgZm9yIHBvc2l0aXZlIG51bWJlcnMuIFRoZSBiaXQgdG8gdG8gYmUgdGVzdGVkCisgICAgICogbXVzdCBiZSBpbiB0aGUgcmFuZ2Uge0Bjb2RlIFswLCB2YWwuYml0TGVuZ3RoKCktMV19CisgICAgICovCisgICAgc3RhdGljIGJvb2xlYW4gdGVzdEJpdChCaWdJbnRlZ2VyIHZhbCwgaW50IG4pIHsKKyAgICAgICAgdmFsLnByZXBhcmVKYXZhUmVwcmVzZW50YXRpb24oKTsKKyAgICAgICAgLy8gUFJFOiAwIDw9IG4gPCB2YWwuYml0TGVuZ3RoKCkKKyAgICAgICAgcmV0dXJuICgodmFsLmRpZ2l0c1tuID4+IDVdICYgKDEgPDwgKG4gJiAzMSkpKSAhPSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayBpZiB0aGVyZSBhcmUgMXMgaW4gdGhlIGxvd2VzdCBiaXRzIG9mIHRoaXMgQmlnSW50ZWdlcgorICAgICAqCisgICAgICogQHBhcmFtIG51bWJlck9mQml0cyB0aGUgbnVtYmVyIG9mIHRoZSBsb3dlc3QgYml0cyB0byBjaGVjaworICAgICAqIEByZXR1cm4gZmFsc2UgaWYgYWxsIGJpdHMgYXJlIDBzLCB0cnVlIG90aGVyd2lzZQorICAgICAqLworICAgIHN0YXRpYyBib29sZWFuIG5vblplcm9Ecm9wcGVkQml0cyhpbnQgbnVtYmVyT2ZCaXRzLCBpbnRbXSBkaWdpdHMpIHsKKyAgICAgICAgaW50IGludENvdW50ID0gbnVtYmVyT2ZCaXRzID4+IDU7CisgICAgICAgIGludCBiaXRDb3VudCA9IG51bWJlck9mQml0cyAmIDMxOworICAgICAgICBpbnQgaTsKKworICAgICAgICBmb3IgKGkgPSAwOyAoaSA8IGludENvdW50KSAmJiAoZGlnaXRzW2ldID09IDApOyBpKyspIHsKKyAgICAgICAgICAgIDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKChpICE9IGludENvdW50KSB8fCAoZGlnaXRzW2ldIDw8ICgzMiAtIGJpdENvdW50KSAhPSAwKSk7CisgICAgfQorCisgICAgc3RhdGljIHZvaWQgc2hpZnRMZWZ0T25lQml0KGludFtdIHJlc3VsdCwgaW50W10gc291cmNlLCBpbnQgc3JjTGVuKSB7CisgICAgICAgIGludCBjYXJyeSA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3JjTGVuOyBpKyspIHsKKyAgICAgICAgICAgIGludCB2YWwgPSBzb3VyY2VbaV07CisgICAgICAgICAgICByZXN1bHRbaV0gPSAodmFsIDw8IDEpIHwgY2Fycnk7CisgICAgICAgICAgICBjYXJyeSA9IHZhbCA+Pj4gMzE7CisgICAgICAgIH0KKyAgICAgICAgaWYoY2FycnkgIT0gMCkgeworICAgICAgICAgICAgcmVzdWx0W3NyY0xlbl0gPSBjYXJyeTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBCaWdJbnRlZ2VyIHNoaWZ0TGVmdE9uZUJpdChCaWdJbnRlZ2VyIHNvdXJjZSkgeworICAgICAgICBzb3VyY2UucHJlcGFyZUphdmFSZXByZXNlbnRhdGlvbigpOworICAgICAgICBpbnQgc3JjTGVuID0gc291cmNlLm51bWJlckxlbmd0aDsKKyAgICAgICAgaW50IHJlc0xlbiA9IHNyY0xlbiArIDE7CisgICAgICAgIGludFtdIHJlc0RpZ2l0cyA9IG5ldyBpbnRbcmVzTGVuXTsKKyAgICAgICAgc2hpZnRMZWZ0T25lQml0KHJlc0RpZ2l0cywgc291cmNlLmRpZ2l0cywgc3JjTGVuKTsKKyAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKHNvdXJjZS5zaWduLCByZXNMZW4sIHJlc0RpZ2l0cyk7CisgICAgfQorCisgICAgLyoqIEBzZWUgQmlnSW50ZWdlciNzaGlmdFJpZ2h0KGludCkgKi8KKyAgICBzdGF0aWMgQmlnSW50ZWdlciBzaGlmdFJpZ2h0KEJpZ0ludGVnZXIgc291cmNlLCBpbnQgY291bnQpIHsKKyAgICAgICAgc291cmNlLnByZXBhcmVKYXZhUmVwcmVzZW50YXRpb24oKTsKKyAgICAgICAgaW50IGludENvdW50ID0gY291bnQgPj4gNTsgLy8gY291bnQgb2YgaW50ZWdlcnMKKyAgICAgICAgY291bnQgJj0gMzE7IC8vIGNvdW50IG9mIHJlbWFpbmluZyBiaXRzCisgICAgICAgIGlmIChpbnRDb3VudCA+PSBzb3VyY2UubnVtYmVyTGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gKChzb3VyY2Uuc2lnbiA8IDApID8gQmlnSW50ZWdlci5NSU5VU19PTkUgOiBCaWdJbnRlZ2VyLlpFUk8pOworICAgICAgICB9CisgICAgICAgIGludCBpOworICAgICAgICBpbnQgcmVzTGVuZ3RoID0gc291cmNlLm51bWJlckxlbmd0aCAtIGludENvdW50OworICAgICAgICBpbnRbXSByZXNEaWdpdHMgPSBuZXcgaW50W3Jlc0xlbmd0aCArIDFdOworCisgICAgICAgIHNoaWZ0UmlnaHQocmVzRGlnaXRzLCByZXNMZW5ndGgsIHNvdXJjZS5kaWdpdHMsIGludENvdW50LCBjb3VudCk7CisgICAgICAgIGlmIChzb3VyY2Uuc2lnbiA8IDApIHsKKyAgICAgICAgICAgIC8vIENoZWNraW5nIGlmIHRoZSBkcm9wcGVkIGJpdHMgYXJlIHplcm9zICh0aGUgcmVtYWluZGVyIGVxdWFscyB0bworICAgICAgICAgICAgLy8gMCkKKyAgICAgICAgICAgIGZvciAoaSA9IDA7IChpIDwgaW50Q291bnQpICYmIChzb3VyY2UuZGlnaXRzW2ldID09IDApOyBpKyspIHsKKyAgICAgICAgICAgICAgICA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBJZiB0aGUgcmVtYWluZGVyIGlzIG5vdCB6ZXJvLCBhZGQgMSB0byB0aGUgcmVzdWx0CisgICAgICAgICAgICBpZiAoKGkgPCBpbnRDb3VudCkKKyAgICAgICAgICAgICAgICAgICAgfHwgKChjb3VudCA+IDApICYmICgoc291cmNlLmRpZ2l0c1tpXSA8PCAoMzIgLSBjb3VudCkpICE9IDApKSkgeworICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IChpIDwgcmVzTGVuZ3RoKSAmJiAocmVzRGlnaXRzW2ldID09IC0xKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChpID09IHJlc0xlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICByZXNMZW5ndGgrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmVzRGlnaXRzW2ldKys7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKHNvdXJjZS5zaWduLCByZXNMZW5ndGgsIHJlc0RpZ2l0cyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2hpZnRzIHJpZ2h0IGFuIGFycmF5IG9mIGludGVnZXJzLiBUb3RhbCBzaGlmdCBkaXN0YW5jZSBpbiBiaXRzIGlzCisgICAgICogaW50Q291bnQgKiAzMiArIGNvdW50LgorICAgICAqCisgICAgICogQHBhcmFtIHJlc3VsdAorICAgICAqICAgICAgICAgICAgdGhlIGRlc3RpbmF0aW9uIGFycmF5CisgICAgICogQHBhcmFtIHJlc3VsdExlbgorICAgICAqICAgICAgICAgICAgdGhlIGRlc3RpbmF0aW9uIGFycmF5J3MgbGVuZ3RoCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBhcnJheQorICAgICAqIEBwYXJhbSBpbnRDb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBiZSBzaGlmdGVkCisgICAgICogQHBhcmFtIGNvdW50CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJpdHMgdG8gYmUgc2hpZnRlZAorICAgICAqIEByZXR1cm4gZHJvcHBlZCBiaXQncyBhcmUgYWxsIHplcm8gKGkuZS4gcmVtYWlkZXIgaXMgemVybykKKyAgICAgKi8KKyAgICBzdGF0aWMgYm9vbGVhbiBzaGlmdFJpZ2h0KGludFtdIHJlc3VsdCwgaW50IHJlc3VsdExlbiwgaW50W10gc291cmNlLCBpbnQgaW50Q291bnQsIGludCBjb3VudCkgeworICAgICAgICBpbnQgaTsKKyAgICAgICAgYm9vbGVhbiBhbGxaZXJvID0gdHJ1ZTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IGludENvdW50OyBpKyspCisgICAgICAgICAgICBhbGxaZXJvICY9IHNvdXJjZVtpXSA9PSAwOworICAgICAgICBpZiAoY291bnQgPT0gMCkgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzb3VyY2UsIGludENvdW50LCByZXN1bHQsIDAsIHJlc3VsdExlbik7CisgICAgICAgICAgICBpID0gcmVzdWx0TGVuOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW50IGxlZnRTaGlmdENvdW50ID0gMzIgLSBjb3VudDsKKworICAgICAgICAgICAgYWxsWmVybyAmPSAoIHNvdXJjZVtpXSA8PCBsZWZ0U2hpZnRDb3VudCApID09IDA7CisgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcmVzdWx0TGVuIC0gMTsgaSsrKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0W2ldID0gKCBzb3VyY2VbaSArIGludENvdW50XSA+Pj4gY291bnQgKQorICAgICAgICAgICAgICAgIHwgKCBzb3VyY2VbaSArIGludENvdW50ICsgMV0gPDwgbGVmdFNoaWZ0Q291bnQgKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdFtpXSA9ICggc291cmNlW2kgKyBpbnRDb3VudF0gPj4+IGNvdW50ICk7CisgICAgICAgICAgICBpKys7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYWxsWmVybzsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZmxpcEJpdCBvbiB0aGUgQmlnSW50ZWdlciwgcmV0dXJuaW5nIGEgQmlnSW50ZWdlciB3aXRoIHRoZSB0aGUKKyAgICAgKiBzcGVjaWZpZWQgYml0IGZsaXBwZWQuCisgICAgICovCisgICAgc3RhdGljIEJpZ0ludGVnZXIgZmxpcEJpdChCaWdJbnRlZ2VyIHZhbCwgaW50IG4peworICAgICAgICB2YWwucHJlcGFyZUphdmFSZXByZXNlbnRhdGlvbigpOworICAgICAgICBpbnQgcmVzU2lnbiA9ICh2YWwuc2lnbiA9PSAwKSA/IDEgOiB2YWwuc2lnbjsKKyAgICAgICAgaW50IGludENvdW50ID0gbiA+PiA1OworICAgICAgICBpbnQgYml0TiA9IG4gJiAzMTsKKyAgICAgICAgaW50IHJlc0xlbmd0aCA9IE1hdGgubWF4KGludENvdW50ICsgMSwgdmFsLm51bWJlckxlbmd0aCkgKyAxOworICAgICAgICBpbnRbXSByZXNEaWdpdHMgPSBuZXcgaW50W3Jlc0xlbmd0aF07CisgICAgICAgIGludCBpOworCisgICAgICAgIGludCBiaXROdW1iZXIgPSAxIDw8IGJpdE47CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsLmRpZ2l0cywgMCwgcmVzRGlnaXRzLCAwLCB2YWwubnVtYmVyTGVuZ3RoKTsKKworICAgICAgICBpZiAodmFsLnNpZ24gPCAwKSB7CisgICAgICAgICAgICBpZiAoaW50Q291bnQgPj0gdmFsLm51bWJlckxlbmd0aCkgeworICAgICAgICAgICAgICAgIHJlc0RpZ2l0c1tpbnRDb3VudF0gPSBiaXROdW1iZXI7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vdmFsLnNpZ248MCB5IGludENvdW50IDwgdmFsLm51bWJlckxlbmd0aAorICAgICAgICAgICAgICAgIGludCBmaXJzdE5vblplcm9EaWdpdCA9IHZhbC5nZXRGaXJzdE5vbnplcm9EaWdpdCgpOworICAgICAgICAgICAgICAgIGlmIChpbnRDb3VudCA+IGZpcnN0Tm9uWmVyb0RpZ2l0KSB7CisgICAgICAgICAgICAgICAgICAgIHJlc0RpZ2l0c1tpbnRDb3VudF0gXj0gYml0TnVtYmVyOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaW50Q291bnQgPCBmaXJzdE5vblplcm9EaWdpdCkgeworICAgICAgICAgICAgICAgICAgICByZXNEaWdpdHNbaW50Q291bnRdID0gLWJpdE51bWJlcjsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpPWludENvdW50ICsgMTsgaSA8IGZpcnN0Tm9uWmVyb0RpZ2l0OyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc0RpZ2l0c1tpXT0tMTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSByZXNEaWdpdHNbaV0tLTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpID0gaW50Q291bnQ7CisgICAgICAgICAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IC0oKC1yZXNEaWdpdHNbaW50Q291bnRdKSBeIGJpdE51bWJlcik7CisgICAgICAgICAgICAgICAgICAgIGlmIChyZXNEaWdpdHNbaV0gPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpKys7IHJlc0RpZ2l0c1tpXSA9PSAtMSA7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IDA7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICByZXNEaWdpdHNbaV0rKzsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsvL2Nhc2Ugd2hlcmUgdmFsIGlzIHBvc2l0aXZlCisgICAgICAgICAgICByZXNEaWdpdHNbaW50Q291bnRdIF49IGJpdE51bWJlcjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIocmVzU2lnbiwgcmVzTGVuZ3RoLCByZXNEaWdpdHMpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL21hdGgvQ29udmVyc2lvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbWF0aC9Db252ZXJzaW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTg1ZmZmNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL21hdGgvQ29udmVyc2lvbi5qYXZhCkBAIC0wLDAgKzEsNDYxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubWF0aDsKKworLyoqCisgKiBTdGF0aWMgbGlicmFyeSB0aGF0IHByb3ZpZGVzIHtAbGluayBCaWdJbnRlZ2VyfSBiYXNlIGNvbnZlcnNpb24gZnJvbS90byBhbnkKKyAqIGludGVnZXIgcmVwcmVzZW50ZWQgaW4gYW4ge0BsaW5rIGphdmEubGFuZy5TdHJpbmd9IE9iamVjdC4KKyAqLworY2xhc3MgQ29udmVyc2lvbiB7CisKKyAgICAvKiogSnVzdCB0byBkZW5vdGUgdGhhdCB0aGlzIGNsYXNzIGNhbid0IGJlIGluc3RhbnRpYXRlZCAqLworICAgIHByaXZhdGUgQ29udmVyc2lvbigpIHt9CisKKyAgICAvKioKKyAgICAgKiBIb2xkcyB0aGUgbWF4aW1hbCBleHBvbmVudCBmb3IgZWFjaCByYWRpeCwgc28gdGhhdCByYWRpeDxzdXA+ZGlnaXRGaXRJbkludFtyYWRpeF08L3N1cD4KKyAgICAgKiBmaXQgaW4gYW4ge0Bjb2RlIGludH0gKDMyIGJpdHMpLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBpbnRbXSBkaWdpdEZpdEluSW50ID0geyAtMSwgLTEsIDMxLCAxOSwgMTUsIDEzLCAxMSwKKyAgICAgICAgICAgIDExLCAxMCwgOSwgOSwgOCwgOCwgOCwgOCwgNywgNywgNywgNywgNywgNywgNywgNiwgNiwgNiwgNiwgNiwgNiwgNiwKKyAgICAgICAgICAgIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDUgfTsKKworICAgIC8qKgorICAgICAqIGJpZ1JhZGljZXMgdmFsdWVzIGFyZSBwcmVjb21wdXRlZCBtYXhpbWFsIHBvd2VycyBvZiByYWRpY2VzIChpbnRlZ2VyCisgICAgICogbnVtYmVycyBmcm9tIDIgdG8gMzYpIHRoYXQgZml0IGludG8gdW5zaWduZWQgaW50ICgzMiBiaXRzKS4gYmlnUmFkaWNlc1swXSA9CisgICAgICogMiBeIDMxLCBiaWdSYWRpY2VzWzhdID0gMTAgXiA5LCBldGMuCisgICAgICovCisKKyAgICBzdGF0aWMgZmluYWwgaW50W10gYmlnUmFkaWNlcyA9IHsgLTIxNDc0ODM2NDgsIDExNjIyNjE0NjcsCisgICAgICAgICAgICAxMDczNzQxODI0LCAxMjIwNzAzMTI1LCAzNjI3OTcwNTYsIDE5NzczMjY3NDMsIDEwNzM3NDE4MjQsCisgICAgICAgICAgICAzODc0MjA0ODksIDEwMDAwMDAwMDAsIDIxNDM1ODg4MSwgNDI5OTgxNjk2LCA4MTU3MzA3MjEsIDE0NzU3ODkwNTYsCisgICAgICAgICAgICAxNzA4NTkzNzUsIDI2ODQzNTQ1NiwgNDEwMzM4NjczLCA2MTIyMjAwMzIsIDg5Mzg3MTczOSwgMTI4MDAwMDAwMCwKKyAgICAgICAgICAgIDE4MDEwODg1NDEsIDExMzM3OTkwNCwgMTQ4MDM1ODg5LCAxOTExMDI5NzYsIDI0NDE0MDYyNSwgMzA4OTE1Nzc2LAorICAgICAgICAgICAgMzg3NDIwNDg5LCA0ODE4OTAzMDQsIDU5NDgyMzMyMSwgNzI5MDAwMDAwLCA4ODc1MDM2ODEsIDEwNzM3NDE4MjQsCisgICAgICAgICAgICAxMjkxNDY3OTY5LCAxNTQ0ODA0NDE2LCAxODM4MjY1NjI1LCA2MDQ2NjE3NiB9OworCisKKyAgICAvKiogQHNlZSBCaWdJbnRlZ2VyI3RvU3RyaW5nKGludCkgKi8KKyAgICBzdGF0aWMgU3RyaW5nIGJpZ0ludGVnZXIyU3RyaW5nKEJpZ0ludGVnZXIgdmFsLCBpbnQgcmFkaXgpIHsKKyAgICAgICAgdmFsLnByZXBhcmVKYXZhUmVwcmVzZW50YXRpb24oKTsKKyAgICAgICAgaW50IHNpZ24gPSB2YWwuc2lnbjsKKyAgICAgICAgaW50IG51bWJlckxlbmd0aCA9IHZhbC5udW1iZXJMZW5ndGg7CisgICAgICAgIGludFtdIGRpZ2l0cyA9IHZhbC5kaWdpdHM7CisKKyAgICAgICAgaWYgKHNpZ24gPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuICIwIjsKKyAgICAgICAgfQorICAgICAgICBpZiAobnVtYmVyTGVuZ3RoID09IDEpIHsKKyAgICAgICAgICAgIGludCBoaWdoRGlnaXQgPSBkaWdpdHNbbnVtYmVyTGVuZ3RoIC0gMV07CisgICAgICAgICAgICBsb25nIHYgPSBoaWdoRGlnaXQgJiAweEZGRkZGRkZGTDsKKyAgICAgICAgICAgIGlmIChzaWduIDwgMCkgeworICAgICAgICAgICAgICAgIHYgPSAtdjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBMb25nLnRvU3RyaW5nKHYsIHJhZGl4KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoKHJhZGl4ID09IDEwKSB8fCAocmFkaXggPCBDaGFyYWN0ZXIuTUlOX1JBRElYKQorICAgICAgICAgICAgICAgIHx8IChyYWRpeCA+IENoYXJhY3Rlci5NQVhfUkFESVgpKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsLnRvU3RyaW5nKCk7CisgICAgICAgIH0KKyAgICAgICAgZG91YmxlIGJpdHNGb3JSYWRpeERpZ2l0OworICAgICAgICBiaXRzRm9yUmFkaXhEaWdpdCA9IE1hdGgubG9nKHJhZGl4KSAvIE1hdGgubG9nKDIpOworICAgICAgICBpbnQgcmVzTGVuZ3RoSW5DaGFycyA9IChpbnQpICh2YWwuYWJzKCkuYml0TGVuZ3RoKCkgLyBiaXRzRm9yUmFkaXhEaWdpdCArICgoc2lnbiA8IDApID8gMQorICAgICAgICAgICAgICAgIDogMCkpICsgMTsKKworICAgICAgICBjaGFyW10gcmVzdWx0ID0gbmV3IGNoYXJbcmVzTGVuZ3RoSW5DaGFyc107CisgICAgICAgIGludCBjdXJyZW50Q2hhciA9IHJlc0xlbmd0aEluQ2hhcnM7CisgICAgICAgIGludCByZXNEaWdpdDsKKyAgICAgICAgaWYgKHJhZGl4ICE9IDE2KSB7CisgICAgICAgICAgICBpbnRbXSB0ZW1wID0gbmV3IGludFtudW1iZXJMZW5ndGhdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShkaWdpdHMsIDAsIHRlbXAsIDAsIG51bWJlckxlbmd0aCk7CisgICAgICAgICAgICBpbnQgdGVtcExlbiA9IG51bWJlckxlbmd0aDsKKyAgICAgICAgICAgIGludCBjaGFyc1BlckludCA9IGRpZ2l0Rml0SW5JbnRbcmFkaXhdOworICAgICAgICAgICAgaW50IGk7CisgICAgICAgICAgICAvLyBnZXQgdGhlIG1heGltYWwgcG93ZXIgb2YgcmFkaXggdGhhdCBmaXRzIGluIGludAorICAgICAgICAgICAgaW50IGJpZ1JhZGl4ID0gYmlnUmFkaWNlc1tyYWRpeCAtIDJdOworICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICAvLyBkaXZpZGUgdGhlIGFycmF5IG9mIGRpZ2l0cyBieSBiaWdSYWRpeCBhbmQgY29udmVydCByZW1haW5kZXJzCisgICAgICAgICAgICAgICAgLy8gdG8gY2hhcmFjdGVycyBjb2xsZWN0aW5nIHRoZW0gaW4gdGhlIGNoYXIgYXJyYXkKKyAgICAgICAgICAgICAgICByZXNEaWdpdCA9IERpdmlzaW9uLmRpdmlkZUFycmF5QnlJbnQodGVtcCwgdGVtcCwgdGVtcExlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGJpZ1JhZGl4KTsKKyAgICAgICAgICAgICAgICBpbnQgcHJldmlvdXMgPSBjdXJyZW50Q2hhcjsKKyAgICAgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdFstLWN1cnJlbnRDaGFyXSA9IENoYXJhY3Rlci5mb3JEaWdpdCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNEaWdpdCAlIHJhZGl4LCByYWRpeCk7CisgICAgICAgICAgICAgICAgfSB3aGlsZSAoKChyZXNEaWdpdCAvPSByYWRpeCkgIT0gMCkgJiYgKGN1cnJlbnRDaGFyICE9IDApKTsKKyAgICAgICAgICAgICAgICBpbnQgZGVsdGEgPSBjaGFyc1BlckludCAtIHByZXZpb3VzICsgY3VycmVudENoYXI7CisgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGRlbHRhICYmIGN1cnJlbnRDaGFyID4gMDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdFstLWN1cnJlbnRDaGFyXSA9ICcwJzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZm9yIChpID0gdGVtcExlbiAtIDE7IChpID4gMCkgJiYgKHRlbXBbaV0gPT0gMCk7IGktLSkgeworICAgICAgICAgICAgICAgICAgICA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRlbXBMZW4gPSBpICsgMTsKKyAgICAgICAgICAgICAgICBpZiAoKHRlbXBMZW4gPT0gMSkgJiYgKHRlbXBbMF0gPT0gMCkpIHsgLy8gdGhlIHF1b3RpZW50IGlzIDAKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gcmFkaXggPT0gMTYKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtYmVyTGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgKGogPCA4KSAmJiAoY3VycmVudENoYXIgPiAwKTsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc0RpZ2l0ID0gZGlnaXRzW2ldID4+IChqIDw8IDIpICYgMHhmOworICAgICAgICAgICAgICAgICAgICByZXN1bHRbLS1jdXJyZW50Q2hhcl0gPSBDaGFyYWN0ZXIuZm9yRGlnaXQocmVzRGlnaXQsIDE2KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgd2hpbGUgKHJlc3VsdFtjdXJyZW50Q2hhcl0gPT0gJzAnKSB7CisgICAgICAgICAgICBjdXJyZW50Q2hhcisrOworICAgICAgICB9CisgICAgICAgIGlmIChzaWduID09IC0xKSB7CisgICAgICAgICAgICByZXN1bHRbLS1jdXJyZW50Q2hhcl0gPSAnLSc7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcocmVzdWx0LCBjdXJyZW50Q2hhciwgcmVzTGVuZ3RoSW5DaGFycyAtIGN1cnJlbnRDaGFyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBCdWlsZHMgdGhlIGNvcnJlc3BvbmRlbnQge0Bjb2RlIFN0cmluZ30gcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIHZhbH0KKyAgICAgKiBiZWluZyBzY2FsZWQgYnkge0Bjb2RlIHNjYWxlfS4KKyAgICAgKgorICAgICAqIEBzZWUgQmlnSW50ZWdlciN0b1N0cmluZygpCisgICAgICogQHNlZSBCaWdEZWNpbWFsI3RvU3RyaW5nKCkKKyAgICAgKi8KKyAgICBzdGF0aWMgU3RyaW5nIHRvRGVjaW1hbFNjYWxlZFN0cmluZyhCaWdJbnRlZ2VyIHZhbCwgaW50IHNjYWxlKSB7CisgICAgICAgIHZhbC5wcmVwYXJlSmF2YVJlcHJlc2VudGF0aW9uKCk7CisgICAgICAgIGludCBzaWduID0gdmFsLnNpZ247CisgICAgICAgIGludCBudW1iZXJMZW5ndGggPSB2YWwubnVtYmVyTGVuZ3RoOworICAgICAgICBpbnRbXSBkaWdpdHMgPSB2YWwuZGlnaXRzOworICAgICAgICBpbnQgcmVzTGVuZ3RoSW5DaGFyczsKKyAgICAgICAgaW50IGN1cnJlbnRDaGFyOworICAgICAgICBjaGFyW10gcmVzdWx0OworCisgICAgICAgIGlmIChzaWduID09IDApIHsKKyAgICAgICAgICAgIHN3aXRjaCAoc2NhbGUpIHsKKyAgICAgICAgICAgICAgICBjYXNlIDA6CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAiMCI7CisgICAgICAgICAgICAgICAgY2FzZSAxOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gIjAuMCI7CisgICAgICAgICAgICAgICAgY2FzZSAyOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gIjAuMDAiOworICAgICAgICAgICAgICAgIGNhc2UgMzoKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuICIwLjAwMCI7CisgICAgICAgICAgICAgICAgY2FzZSA0OgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gIjAuMDAwMCI7CisgICAgICAgICAgICAgICAgY2FzZSA1OgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gIjAuMDAwMDAiOworICAgICAgICAgICAgICAgIGNhc2UgNjoKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuICIwLjAwMDAwMCI7CisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQxID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNjYWxlIDwgMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0MS5hcHBlbmQoIjBFKyIpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0MS5hcHBlbmQoIjBFIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0MS5hcHBlbmQoLXNjYWxlKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDEudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBvbmUgMzItYml0IHVuc2lnbmVkIHZhbHVlIG1heSBjb250YWlucyAxMCBkZWNpbWFsIGRpZ2l0cworICAgICAgICByZXNMZW5ndGhJbkNoYXJzID0gbnVtYmVyTGVuZ3RoICogMTAgKyAxICsgNzsKKyAgICAgICAgLy8gRXhwbGFuYXRpb24gd2h5ICsxKzc6CisgICAgICAgIC8vICsxIC0gb25lIGNoYXIgZm9yIHNpZ24gaWYgbmVlZGVkLgorICAgICAgICAvLyArNyAtIEZvciAic3BlY2lhbCBjYXNlIDIiIChzZWUgYmVsb3cpIHdlIGhhdmUgNyBmcmVlIGNoYXJzIGZvcgorICAgICAgICAvLyBpbnNlcnRpbmcgbmVjZXNzYXJ5IHNjYWxlZCBkaWdpdHMuCisgICAgICAgIHJlc3VsdCA9IG5ldyBjaGFyW3Jlc0xlbmd0aEluQ2hhcnMgKyAxXTsKKyAgICAgICAgLy8gYWxsb2NhdGVkIFtyZXNMZW5ndGhJbkNoYXJzKzFdIGNoYXJhY3RlcnMuCisgICAgICAgIC8vIGEgZnJlZSBsYXRlc3QgY2hhcmFjdGVyIG1heSBiZSB1c2VkIGZvciAic3BlY2lhbCBjYXNlIDEiIChzZWUKKyAgICAgICAgLy8gYmVsb3cpCisgICAgICAgIGN1cnJlbnRDaGFyID0gcmVzTGVuZ3RoSW5DaGFyczsKKyAgICAgICAgaWYgKG51bWJlckxlbmd0aCA9PSAxKSB7CisgICAgICAgICAgICBpbnQgaGlnaERpZ2l0ID0gZGlnaXRzWzBdOworICAgICAgICAgICAgaWYgKGhpZ2hEaWdpdCA8IDApIHsKKyAgICAgICAgICAgICAgICBsb25nIHYgPSBoaWdoRGlnaXQgJiAweEZGRkZGRkZGTDsKKyAgICAgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgICAgIGxvbmcgcHJldiA9IHY7CisgICAgICAgICAgICAgICAgICAgIHYgLz0gMTA7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdFstLWN1cnJlbnRDaGFyXSA9IChjaGFyKSAoMHgwMDMwICsgKChpbnQpIChwcmV2IC0gdiAqIDEwKSkpOworICAgICAgICAgICAgICAgIH0gd2hpbGUgKHYgIT0gMCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGludCB2ID0gaGlnaERpZ2l0OworICAgICAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHByZXYgPSB2OworICAgICAgICAgICAgICAgICAgICB2IC89IDEwOworICAgICAgICAgICAgICAgICAgICByZXN1bHRbLS1jdXJyZW50Q2hhcl0gPSAoY2hhcikgKDB4MDAzMCArIChwcmV2IC0gdiAqIDEwKSk7CisgICAgICAgICAgICAgICAgfSB3aGlsZSAodiAhPSAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGludFtdIHRlbXAgPSBuZXcgaW50W251bWJlckxlbmd0aF07CisgICAgICAgICAgICBpbnQgdGVtcExlbiA9IG51bWJlckxlbmd0aDsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGlnaXRzLCAwLCB0ZW1wLCAwLCB0ZW1wTGVuKTsKKyAgICAgICAgICAgIEJJR19MT09QOiB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgIC8vIGRpdmlkZSB0aGUgYXJyYXkgb2YgZGlnaXRzIGJ5IGJpZ1JhZGl4IGFuZCBjb252ZXJ0CisgICAgICAgICAgICAgICAgLy8gcmVtYWluZGVycworICAgICAgICAgICAgICAgIC8vIHRvIGNoYXJhY3RlcnMgY29sbGVjdGluZyB0aGVtIGluIHRoZSBjaGFyIGFycmF5CisgICAgICAgICAgICAgICAgbG9uZyByZXN1bHQxMSA9IDA7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaTEgPSB0ZW1wTGVuIC0gMTsgaTEgPj0gMDsgaTEtLSkgeworICAgICAgICAgICAgICAgICAgICBsb25nIHRlbXAxID0gKHJlc3VsdDExIDw8IDMyKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKHRlbXBbaTFdICYgMHhGRkZGRkZGRkwpOworICAgICAgICAgICAgICAgICAgICBsb25nIHJlcyA9IGRpdmlkZUxvbmdCeUJpbGxpb24odGVtcDEpOworICAgICAgICAgICAgICAgICAgICB0ZW1wW2kxXSA9IChpbnQpIHJlczsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0MTEgPSAoaW50KSAocmVzID4+IDMyKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaW50IHJlc0RpZ2l0ID0gKGludCkgcmVzdWx0MTE7CisgICAgICAgICAgICAgICAgaW50IHByZXZpb3VzID0gY3VycmVudENoYXI7CisgICAgICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgICAgICByZXN1bHRbLS1jdXJyZW50Q2hhcl0gPSAoY2hhcikgKDB4MDAzMCArIChyZXNEaWdpdCAlIDEwKSk7CisgICAgICAgICAgICAgICAgfSB3aGlsZSAoKChyZXNEaWdpdCAvPSAxMCkgIT0gMCkgJiYgKGN1cnJlbnRDaGFyICE9IDApKTsKKyAgICAgICAgICAgICAgICBpbnQgZGVsdGEgPSA5IC0gcHJldmlvdXMgKyBjdXJyZW50Q2hhcjsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgKGkgPCBkZWx0YSkgJiYgKGN1cnJlbnRDaGFyID4gMCk7IGkrKykgeworICAgICAgICAgICAgICAgICAgICByZXN1bHRbLS1jdXJyZW50Q2hhcl0gPSAnMCc7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGludCBqID0gdGVtcExlbiAtIDE7CisgICAgICAgICAgICAgICAgZm9yICg7IHRlbXBbal0gPT0gMDsgai0tKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChqID09IDApIHsgLy8gbWVhbnMgdGVtcFswXSA9PSAwCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBCSUdfTE9PUDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0ZW1wTGVuID0gaiArIDE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB3aGlsZSAocmVzdWx0W2N1cnJlbnRDaGFyXSA9PSAnMCcpIHsKKyAgICAgICAgICAgICAgICBjdXJyZW50Q2hhcisrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGJvb2xlYW4gbmVnTnVtYmVyID0gKHNpZ24gPCAwKTsKKyAgICAgICAgaW50IGV4cG9uZW50ID0gcmVzTGVuZ3RoSW5DaGFycyAtIGN1cnJlbnRDaGFyIC0gc2NhbGUgLSAxOworICAgICAgICBpZiAoc2NhbGUgPT0gMCkgeworICAgICAgICAgICAgaWYgKG5lZ051bWJlcikgeworICAgICAgICAgICAgICAgIHJlc3VsdFstLWN1cnJlbnRDaGFyXSA9ICctJzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKHJlc3VsdCwgY3VycmVudENoYXIsIHJlc0xlbmd0aEluQ2hhcnMKKyAgICAgICAgICAgICAgICAgICAgLSBjdXJyZW50Q2hhcik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChzY2FsZSA+IDApICYmIChleHBvbmVudCA+PSAtNikpIHsKKyAgICAgICAgICAgIGlmIChleHBvbmVudCA+PSAwKSB7CisgICAgICAgICAgICAgICAgLy8gc3BlY2lhbCBjYXNlIDEKKyAgICAgICAgICAgICAgICBpbnQgaW5zZXJ0UG9pbnQgPSBjdXJyZW50Q2hhciArIGV4cG9uZW50OworICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSByZXNMZW5ndGhJbkNoYXJzIC0gMTsgaiA+PSBpbnNlcnRQb2ludDsgai0tKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdFtqICsgMV0gPSByZXN1bHRbal07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJlc3VsdFsrK2luc2VydFBvaW50XSA9ICcuJzsKKyAgICAgICAgICAgICAgICBpZiAobmVnTnVtYmVyKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdFstLWN1cnJlbnRDaGFyXSA9ICctJzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcocmVzdWx0LCBjdXJyZW50Q2hhciwgcmVzTGVuZ3RoSW5DaGFycworICAgICAgICAgICAgICAgICAgICAgICAgLSBjdXJyZW50Q2hhciArIDEpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gc3BlY2lhbCBjYXNlIDIKKyAgICAgICAgICAgIGZvciAoaW50IGogPSAyOyBqIDwgLWV4cG9uZW50ICsgMTsgaisrKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0Wy0tY3VycmVudENoYXJdID0gJzAnOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0Wy0tY3VycmVudENoYXJdID0gJy4nOworICAgICAgICAgICAgcmVzdWx0Wy0tY3VycmVudENoYXJdID0gJzAnOworICAgICAgICAgICAgaWYgKG5lZ051bWJlcikgeworICAgICAgICAgICAgICAgIHJlc3VsdFstLWN1cnJlbnRDaGFyXSA9ICctJzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKHJlc3VsdCwgY3VycmVudENoYXIsIHJlc0xlbmd0aEluQ2hhcnMKKyAgICAgICAgICAgICAgICAgICAgLSBjdXJyZW50Q2hhcik7CisgICAgICAgIH0KKyAgICAgICAgaW50IHN0YXJ0UG9pbnQgPSBjdXJyZW50Q2hhciArIDE7CisgICAgICAgIGludCBlbmRQb2ludCA9IHJlc0xlbmd0aEluQ2hhcnM7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0MSA9IG5ldyBTdHJpbmdCdWlsZGVyKDE2ICsgZW5kUG9pbnQgLSBzdGFydFBvaW50KTsKKyAgICAgICAgaWYgKG5lZ051bWJlcikgeworICAgICAgICAgICAgcmVzdWx0MS5hcHBlbmQoJy0nKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZW5kUG9pbnQgLSBzdGFydFBvaW50ID49IDEpIHsKKyAgICAgICAgICAgIHJlc3VsdDEuYXBwZW5kKHJlc3VsdFtjdXJyZW50Q2hhcl0pOworICAgICAgICAgICAgcmVzdWx0MS5hcHBlbmQoJy4nKTsKKyAgICAgICAgICAgIHJlc3VsdDEuYXBwZW5kKHJlc3VsdCwgY3VycmVudENoYXIgKyAxLCByZXNMZW5ndGhJbkNoYXJzCisgICAgICAgICAgICAgICAgICAgIC0gY3VycmVudENoYXIgLSAxKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlc3VsdDEuYXBwZW5kKHJlc3VsdCwgY3VycmVudENoYXIsIHJlc0xlbmd0aEluQ2hhcnMKKyAgICAgICAgICAgICAgICAgICAgLSBjdXJyZW50Q2hhcik7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0MS5hcHBlbmQoJ0UnKTsKKyAgICAgICAgaWYgKGV4cG9uZW50ID4gMCkgeworICAgICAgICAgICAgcmVzdWx0MS5hcHBlbmQoJysnKTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHQxLmFwcGVuZChJbnRlZ2VyLnRvU3RyaW5nKGV4cG9uZW50KSk7CisgICAgICAgIHJldHVybiByZXN1bHQxLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyogY2FuIHByb2Nlc3Mgb25seSAzMi1iaXQgbnVtYmVycyAqLworICAgIHN0YXRpYyBTdHJpbmcgdG9EZWNpbWFsU2NhbGVkU3RyaW5nKGxvbmcgdmFsdWUsIGludCBzY2FsZSkgeworICAgICAgICBpbnQgcmVzTGVuZ3RoSW5DaGFyczsKKyAgICAgICAgaW50IGN1cnJlbnRDaGFyOworICAgICAgICBjaGFyW10gcmVzdWx0OworICAgICAgICBib29sZWFuIG5lZ051bWJlciA9IHZhbHVlIDwgMDsKKyAgICAgICAgaWYobmVnTnVtYmVyKSB7CisgICAgICAgICAgICB2YWx1ZSA9IC12YWx1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAodmFsdWUgPT0gMCkgeworICAgICAgICAgICAgc3dpdGNoIChzY2FsZSkgeworICAgICAgICAgICAgICAgIGNhc2UgMDogcmV0dXJuICIwIjsKKyAgICAgICAgICAgICAgICBjYXNlIDE6IHJldHVybiAiMC4wIjsKKyAgICAgICAgICAgICAgICBjYXNlIDI6IHJldHVybiAiMC4wMCI7CisgICAgICAgICAgICAgICAgY2FzZSAzOiByZXR1cm4gIjAuMDAwIjsKKyAgICAgICAgICAgICAgICBjYXNlIDQ6IHJldHVybiAiMC4wMDAwIjsKKyAgICAgICAgICAgICAgICBjYXNlIDU6IHJldHVybiAiMC4wMDAwMCI7CisgICAgICAgICAgICAgICAgY2FzZSA2OiByZXR1cm4gIjAuMDAwMDAwIjsKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdDEgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICAgICAgICAgICAgICBpZiAoc2NhbGUgIDwgMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0MS5hcHBlbmQoIjBFKyIpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0MS5hcHBlbmQoIjBFIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0MS5hcHBlbmQoIChzY2FsZSA9PSBJbnRlZ2VyLk1JTl9WQUxVRSkgPyAiMjE0NzQ4MzY0OCIgOiBJbnRlZ2VyLnRvU3RyaW5nKC1zY2FsZSkpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0MS50b1N0cmluZygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIG9uZSAzMi1iaXQgdW5zaWduZWQgdmFsdWUgbWF5IGNvbnRhaW5zIDEwIGRlY2ltYWwgZGlnaXRzCisgICAgICAgIHJlc0xlbmd0aEluQ2hhcnMgPSAxODsKKyAgICAgICAgLy8gRXhwbGFuYXRpb24gd2h5ICsxKzc6CisgICAgICAgIC8vICsxIC0gb25lIGNoYXIgZm9yIHNpZ24gaWYgbmVlZGVkLgorICAgICAgICAvLyArNyAtIEZvciAic3BlY2lhbCBjYXNlIDIiIChzZWUgYmVsb3cpIHdlIGhhdmUgNyBmcmVlIGNoYXJzIGZvcgorICAgICAgICAvLyAgaW5zZXJ0aW5nIG5lY2Vzc2FyeSBzY2FsZWQgZGlnaXRzLgorICAgICAgICByZXN1bHQgPSBuZXcgY2hhcltyZXNMZW5ndGhJbkNoYXJzKzFdOworICAgICAgICAvLyAgQWxsb2NhdGVkIFtyZXNMZW5ndGhJbkNoYXJzKzFdIGNoYXJhY3RlcnMuCisgICAgICAgIC8vIGEgZnJlZSBsYXRlc3QgY2hhcmFjdGVyIG1heSBiZSB1c2VkIGZvciAic3BlY2lhbCBjYXNlIDEiIChzZWUgYmVsb3cpCisgICAgICAgIGN1cnJlbnRDaGFyID0gcmVzTGVuZ3RoSW5DaGFyczsKKyAgICAgICAgbG9uZyB2ID0gdmFsdWU7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGxvbmcgcHJldiA9IHY7CisgICAgICAgICAgICB2IC89IDEwOworICAgICAgICAgICAgcmVzdWx0Wy0tY3VycmVudENoYXJdID0gKGNoYXIpICgweDAwMzAgKyAocHJldiAtIHYgKiAxMCkpOworICAgICAgICB9IHdoaWxlICh2ICE9IDApOworCisgICAgICAgIGxvbmcgZXhwb25lbnQgPSAobG9uZylyZXNMZW5ndGhJbkNoYXJzIC0gKGxvbmcpY3VycmVudENoYXIgLSBzY2FsZSAtIDFMOworICAgICAgICBpZiAoc2NhbGUgPT0gMCkgeworICAgICAgICAgICAgaWYgKG5lZ051bWJlcikgeworICAgICAgICAgICAgICAgIHJlc3VsdFstLWN1cnJlbnRDaGFyXSA9ICctJzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKHJlc3VsdCwgY3VycmVudENoYXIsIHJlc0xlbmd0aEluQ2hhcnMgLSBjdXJyZW50Q2hhcik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNjYWxlID4gMCAmJiBleHBvbmVudCA+PSAtNikgeworICAgICAgICAgICAgaWYgKGV4cG9uZW50ID49IDApIHsKKyAgICAgICAgICAgICAgICAvLyBzcGVjaWFsIGNhc2UgMQorICAgICAgICAgICAgICAgIGludCBpbnNlcnRQb2ludCA9IGN1cnJlbnRDaGFyICsgKGludCkgZXhwb25lbnQgOworICAgICAgICAgICAgICAgIGZvciAoaW50IGo9cmVzTGVuZ3RoSW5DaGFycy0xOyBqPj1pbnNlcnRQb2ludDsgai0tKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdFtqKzFdID0gcmVzdWx0W2pdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXN1bHRbKytpbnNlcnRQb2ludF09Jy4nOworICAgICAgICAgICAgICAgIGlmIChuZWdOdW1iZXIpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0Wy0tY3VycmVudENoYXJdID0gJy0nOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhyZXN1bHQsIGN1cnJlbnRDaGFyLCByZXNMZW5ndGhJbkNoYXJzIC0gY3VycmVudENoYXIgKyAxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIHNwZWNpYWwgY2FzZSAyCisgICAgICAgICAgICBmb3IgKGludCBqID0gMjsgaiA8IC1leHBvbmVudCArIDE7IGorKykgeworICAgICAgICAgICAgICAgIHJlc3VsdFstLWN1cnJlbnRDaGFyXSA9ICcwJzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdFstLWN1cnJlbnRDaGFyXSA9ICcuJzsKKyAgICAgICAgICAgIHJlc3VsdFstLWN1cnJlbnRDaGFyXSA9ICcwJzsKKyAgICAgICAgICAgIGlmIChuZWdOdW1iZXIpIHsKKyAgICAgICAgICAgICAgICByZXN1bHRbLS1jdXJyZW50Q2hhcl0gPSAnLSc7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhyZXN1bHQsIGN1cnJlbnRDaGFyLCByZXNMZW5ndGhJbkNoYXJzIC0gY3VycmVudENoYXIpOworICAgICAgICB9CisgICAgICAgIGludCBzdGFydFBvaW50ID0gY3VycmVudENoYXIgKyAxOworICAgICAgICBpbnQgZW5kUG9pbnQgPSByZXNMZW5ndGhJbkNoYXJzOworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdDEgPSBuZXcgU3RyaW5nQnVpbGRlcigxNiArIGVuZFBvaW50IC0gc3RhcnRQb2ludCk7CisgICAgICAgIGlmIChuZWdOdW1iZXIpIHsKKyAgICAgICAgICAgIHJlc3VsdDEuYXBwZW5kKCctJyk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVuZFBvaW50IC0gc3RhcnRQb2ludCA+PSAxKSB7CisgICAgICAgICAgICByZXN1bHQxLmFwcGVuZChyZXN1bHRbY3VycmVudENoYXJdKTsKKyAgICAgICAgICAgIHJlc3VsdDEuYXBwZW5kKCcuJyk7CisgICAgICAgICAgICByZXN1bHQxLmFwcGVuZChyZXN1bHQsY3VycmVudENoYXIrMSxyZXNMZW5ndGhJbkNoYXJzIC0gY3VycmVudENoYXItMSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXN1bHQxLmFwcGVuZChyZXN1bHQsY3VycmVudENoYXIscmVzTGVuZ3RoSW5DaGFycyAtIGN1cnJlbnRDaGFyKTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHQxLmFwcGVuZCgnRScpOworICAgICAgICBpZiAoZXhwb25lbnQgPiAwKSB7CisgICAgICAgICAgICByZXN1bHQxLmFwcGVuZCgnKycpOworICAgICAgICB9CisgICAgICAgIHJlc3VsdDEuYXBwZW5kKExvbmcudG9TdHJpbmcoZXhwb25lbnQpKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDEudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBzdGF0aWMgbG9uZyBkaXZpZGVMb25nQnlCaWxsaW9uKGxvbmcgYSkgeworICAgICAgICBsb25nIHF1b3Q7CisgICAgICAgIGxvbmcgcmVtOworCisgICAgICAgIGlmIChhID49IDApIHsKKyAgICAgICAgICAgIGxvbmcgYkxvbmcgPSAxMDAwMDAwMDAwTDsKKyAgICAgICAgICAgIHF1b3QgPSAoYSAvIGJMb25nKTsKKyAgICAgICAgICAgIHJlbSA9IChhICUgYkxvbmcpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIE1ha2UgdGhlIGRpdmlkZW5kIHBvc2l0aXZlIHNoaWZ0aW5nIGl0IHJpZ2h0IGJ5IDEgYml0IHRoZW4gZ2V0CisgICAgICAgICAgICAgKiB0aGUgcXVvdGllbnQgYW4gcmVtYWluZGVyIGFuZCBjb3JyZWN0IHRoZW0gcHJvcGVybHkKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgbG9uZyBhUG9zID0gYSA+Pj4gMTsKKyAgICAgICAgICAgIGxvbmcgYlBvcyA9IDEwMDAwMDAwMDBMID4+PiAxOworICAgICAgICAgICAgcXVvdCA9IGFQb3MgLyBiUG9zOworICAgICAgICAgICAgcmVtID0gYVBvcyAlIGJQb3M7CisgICAgICAgICAgICAvLyBkb3VibGUgdGhlIHJlbWFpbmRlciBhbmQgYWRkIDEgaWYgJ2EnIGlzIG9kZAorICAgICAgICAgICAgcmVtID0gKHJlbSA8PCAxKSArIChhICYgMSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuICgocmVtIDw8IDMyKSB8IChxdW90ICYgMHhGRkZGRkZGRkwpKTsKKyAgICB9CisKKyAgICAvKiogQHNlZSBCaWdJbnRlZ2VyI2RvdWJsZVZhbHVlKCkgKi8KKyAgICBzdGF0aWMgZG91YmxlIGJpZ0ludGVnZXIyRG91YmxlKEJpZ0ludGVnZXIgdmFsKSB7CisgICAgICAgIHZhbC5wcmVwYXJlSmF2YVJlcHJlc2VudGF0aW9uKCk7CisgICAgICAgIC8vIHZhbC5iaXRMZW5ndGgoKSA8IDY0CisgICAgICAgIGlmICgodmFsLm51bWJlckxlbmd0aCA8IDIpCisgICAgICAgICAgICAgICAgfHwgKCh2YWwubnVtYmVyTGVuZ3RoID09IDIpICYmICh2YWwuZGlnaXRzWzFdID4gMCkpKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsLmxvbmdWYWx1ZSgpOworICAgICAgICB9CisgICAgICAgIC8vIHZhbC5iaXRMZW5ndGgoKSA+PSAzMyAqIDMyID4gMTAyNAorICAgICAgICBpZiAodmFsLm51bWJlckxlbmd0aCA+IDMyKSB7CisgICAgICAgICAgICByZXR1cm4gKCh2YWwuc2lnbiA+IDApID8gRG91YmxlLlBPU0lUSVZFX0lORklOSVRZCisgICAgICAgICAgICAgICAgICAgIDogRG91YmxlLk5FR0FUSVZFX0lORklOSVRZKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgYml0TGVuID0gdmFsLmFicygpLmJpdExlbmd0aCgpOworICAgICAgICBsb25nIGV4cG9uZW50ID0gYml0TGVuIC0gMTsKKyAgICAgICAgaW50IGRlbHRhID0gYml0TGVuIC0gNTQ7CisgICAgICAgIC8vIFdlIG5lZWQgNTQgdG9wIGJpdHMgZnJvbSB0aGlzLCB0aGUgNTN0aCBiaXQgaXMgYWx3YXlzIDEgaW4gbFZhbC4KKyAgICAgICAgbG9uZyBsVmFsID0gdmFsLmFicygpLnNoaWZ0UmlnaHQoZGVsdGEpLmxvbmdWYWx1ZSgpOworICAgICAgICAvKgorICAgICAgICAgKiBUYWtlIDUzIGJpdHMgZnJvbSBsVmFsIHRvIG1hbnRpc3NhLiBUaGUgbGVhc3Qgc2lnbmlmaWNhbnQgYml0IGlzCisgICAgICAgICAqIG5lZWRlZCBmb3Igcm91bmRpbmcuCisgICAgICAgICAqLworICAgICAgICBsb25nIG1hbnRpc3NhID0gbFZhbCAmIDB4MUZGRkZGRkZGRkZGRkZMOworICAgICAgICBpZiAoZXhwb25lbnQgPT0gMTAyMykgeworICAgICAgICAgICAgaWYgKG1hbnRpc3NhID09IDBYMUZGRkZGRkZGRkZGRkZMKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuICgodmFsLnNpZ24gPiAwKSA/IERvdWJsZS5QT1NJVElWRV9JTkZJTklUWQorICAgICAgICAgICAgICAgICAgICAgICAgOiBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG1hbnRpc3NhID09IDB4MUZGRkZGRkZGRkZGRkVMKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuICgodmFsLnNpZ24gPiAwKSA/IERvdWJsZS5NQVhfVkFMVUUgOiAtRG91YmxlLk1BWF9WQUxVRSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gUm91bmQgdGhlIG1hbnRpc3NhCisgICAgICAgIGlmICgoKG1hbnRpc3NhICYgMSkgPT0gMSkKKyAgICAgICAgICAgICAgICAmJiAoKChtYW50aXNzYSAmIDIpID09IDIpIHx8IEJpdExldmVsLm5vblplcm9Ecm9wcGVkQml0cyhkZWx0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbC5kaWdpdHMpKSkgeworICAgICAgICAgICAgbWFudGlzc2EgKz0gMjsKKyAgICAgICAgfQorICAgICAgICBtYW50aXNzYSA+Pj0gMTsgLy8gZHJvcCB0aGUgcm91bmRpbmcgYml0CisgICAgICAgIGxvbmcgcmVzU2lnbiA9ICh2YWwuc2lnbiA8IDApID8gMHg4MDAwMDAwMDAwMDAwMDAwTCA6IDA7CisgICAgICAgIGV4cG9uZW50ID0gKCgxMDIzICsgZXhwb25lbnQpIDw8IDUyKSAmIDB4N0ZGMDAwMDAwMDAwMDAwMEw7CisgICAgICAgIGxvbmcgcmVzdWx0ID0gcmVzU2lnbiB8IGV4cG9uZW50IHwgbWFudGlzc2E7CisgICAgICAgIHJldHVybiBEb3VibGUubG9uZ0JpdHNUb0RvdWJsZShyZXN1bHQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL21hdGgvRGl2aXNpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL21hdGgvRGl2aXNpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNjQyNzgzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbWF0aC9EaXZpc2lvbi5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5tYXRoOworCisvKioKKyAqIFN0YXRpYyBsaWJyYXJ5IHRoYXQgcHJvdmlkZXMgYWxsIG9wZXJhdGlvbnMgcmVsYXRlZCB3aXRoIGRpdmlzaW9uIGFuZCBtb2R1bGFyCisgKiBhcml0aG1ldGljIHRvIHtAbGluayBCaWdJbnRlZ2VyfS4gU29tZSBtZXRob2RzIGFyZSBwcm92aWRlZCBpbiBib3RoIG11dGFibGUKKyAqIGFuZCBpbW11dGFibGUgd2F5LiBUaGVyZSBhcmUgc2V2ZXJhbCB2YXJpYW50cyBwcm92aWRlZCBsaXN0ZWQgYmVsb3c6CisgKgorICogPHVsIHR5cGU9ImNpcmNsZSI+CisgKiA8bGk+IDxiPkRpdmlzaW9uPC9iPgorICogPHVsIHR5cGU9ImNpcmNsZSI+CisgKiA8bGk+e0BsaW5rIEJpZ0ludGVnZXJ9IGRpdmlzaW9uIGFuZCByZW1haW5kZXIgYnkge0BsaW5rIEJpZ0ludGVnZXJ9LjwvbGk+CisgKiA8bGk+e0BsaW5rIEJpZ0ludGVnZXJ9IGRpdmlzaW9uIGFuZCByZW1haW5kZXIgYnkge0Bjb2RlIGludH0uPC9saT4KKyAqIDxsaT48aT5nY2Q8L2k+IGJldHdlZW4ge0BsaW5rIEJpZ0ludGVnZXJ9IG51bWJlcnMuPC9saT4KKyAqIDwvdWw+CisgKiA8L2xpPgorICogPGxpPiA8Yj5Nb2R1bGFyIGFyaXRobWV0aWMgPC9iPgorICogPHVsIHR5cGU9ImNpcmNsZSI+CisgKiA8bGk+TW9kdWxhciBleHBvbmVudGlhdGlvbiBiZXR3ZWVuIHtAbGluayBCaWdJbnRlZ2VyfSBudW1iZXJzLjwvbGk+CisgKiA8bGk+TW9kdWxhciBpbnZlcnNlIG9mIGEge0BsaW5rIEJpZ0ludGVnZXJ9IG51bWJlcnMuPC9saT4KKyAqIDwvdWw+CisgKiA8L2xpPgorICo8L3VsPgorICovCitjbGFzcyBEaXZpc2lvbiB7CisKKyAgICAvKioKKyAgICAgKiBEaXZpZGVzIGFuIGFycmF5IGJ5IGFuIGludGVnZXIgdmFsdWUuIEltcGxlbWVudHMgdGhlIEtudXRoJ3MgZGl2aXNpb24KKyAgICAgKiBhbGdvcml0aG0uIFNlZSBELiBLbnV0aCwgVGhlIEFydCBvZiBDb21wdXRlciBQcm9ncmFtbWluZywgdm9sLiAyLgorICAgICAqCisgICAgICogQHJldHVybiByZW1haW5kZXIKKyAgICAgKi8KKyAgICBzdGF0aWMgaW50IGRpdmlkZUFycmF5QnlJbnQoaW50W10gcXVvdGllbnQsIGludFtdIGRpdmlkZW5kLCBmaW5hbCBpbnQgZGl2aWRlbmRMZW5ndGgsCisgICAgICAgICAgICBmaW5hbCBpbnQgZGl2aXNvcikgeworCisgICAgICAgIGxvbmcgcmVtID0gMDsKKyAgICAgICAgbG9uZyBiTG9uZyA9IGRpdmlzb3IgJiAweGZmZmZmZmZmTDsKKworICAgICAgICBmb3IgKGludCBpID0gZGl2aWRlbmRMZW5ndGggLSAxOyBpID49IDA7IGktLSkgeworICAgICAgICAgICAgbG9uZyB0ZW1wID0gKHJlbSA8PCAzMikgfCAoZGl2aWRlbmRbaV0gJiAweGZmZmZmZmZmTCk7CisgICAgICAgICAgICBsb25nIHF1b3Q7CisgICAgICAgICAgICBpZiAodGVtcCA+PSAwKSB7CisgICAgICAgICAgICAgICAgcXVvdCA9ICh0ZW1wIC8gYkxvbmcpOworICAgICAgICAgICAgICAgIHJlbSA9ICh0ZW1wICUgYkxvbmcpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAqIG1ha2UgdGhlIGRpdmlkZW5kIHBvc2l0aXZlIHNoaWZ0aW5nIGl0IHJpZ2h0IGJ5IDEgYml0IHRoZW4KKyAgICAgICAgICAgICAgICAgKiBnZXQgdGhlIHF1b3RpZW50IGFuIHJlbWFpbmRlciBhbmQgY29ycmVjdCB0aGVtIHByb3Blcmx5CisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgbG9uZyBhUG9zID0gdGVtcCA+Pj4gMTsKKyAgICAgICAgICAgICAgICBsb25nIGJQb3MgPSBkaXZpc29yID4+PiAxOworICAgICAgICAgICAgICAgIHF1b3QgPSBhUG9zIC8gYlBvczsKKyAgICAgICAgICAgICAgICByZW0gPSBhUG9zICUgYlBvczsKKyAgICAgICAgICAgICAgICAvLyBkb3VibGUgdGhlIHJlbWFpbmRlciBhbmQgYWRkIDEgaWYgYSBpcyBvZGQKKyAgICAgICAgICAgICAgICByZW0gPSAocmVtIDw8IDEpICsgKHRlbXAgJiAxKTsKKyAgICAgICAgICAgICAgICBpZiAoKGRpdmlzb3IgJiAxKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBkaXZpc29yIGlzIG9kZAorICAgICAgICAgICAgICAgICAgICBpZiAocXVvdCA8PSByZW0pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlbSAtPSBxdW90OworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHF1b3QgLSByZW0gPD0gYkxvbmcpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW0gKz0gYkxvbmcgLSBxdW90OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1b3QgLT0gMTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtICs9IChiTG9uZyA8PCAxKSAtIHF1b3Q7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVvdCAtPSAyOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcXVvdGllbnRbaV0gPSAoaW50KSAocXVvdCAmIDB4ZmZmZmZmZmZMKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKGludCkgcmVtOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL21hdGgvTG9naWNhbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbWF0aC9Mb2dpY2FsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWRlMDkyNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL21hdGgvTG9naWNhbC5qYXZhCkBAIC0wLDAgKzEsNzczIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubWF0aDsKKworLyoqCisgKiBUaGUgbGlicmFyeSBpbXBsZW1lbnRzIHNvbWUgbG9naWNhbCBvcGVyYXRpb25zIG92ZXIge0Bjb2RlIEJpZ0ludGVnZXJ9LiBUaGUKKyAqIG9wZXJhdGlvbnMgcHJvdmlkZWQgYXJlIGxpc3RlZCBiZWxvdy4KKyAqIDx1bCB0eXBlPSJjaXJjbGUiPgorICogPGxpPm5vdDwvbGk+CisgKiA8bGk+YW5kPC9saT4KKyAqIDxsaT5hbmROb3Q8L2xpPgorICogPGxpPm9yPC9saT4KKyAqIDxsaT54b3I8L2xpPgorICogPC91bD4KKyAqLworY2xhc3MgTG9naWNhbCB7CisKKyAgICAvKiogSnVzdCB0byBkZW5vdGUgdGhhdCB0aGlzIGNsYXNzIGNhbid0IGJlIGluc3RhbnRpYXRlZC4gKi8KKworICAgIHByaXZhdGUgTG9naWNhbCgpIHt9CisKKworICAgIC8qKiBAc2VlIEJpZ0ludGVnZXIjbm90KCkgKi8KKyAgICBzdGF0aWMgQmlnSW50ZWdlciBub3QoQmlnSW50ZWdlciB2YWwpIHsKKyAgICAgICAgaWYgKHZhbC5zaWduID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBCaWdJbnRlZ2VyLk1JTlVTX09ORTsKKyAgICAgICAgfQorICAgICAgICBpZiAodmFsLmVxdWFscyhCaWdJbnRlZ2VyLk1JTlVTX09ORSkpIHsKKyAgICAgICAgICAgIHJldHVybiBCaWdJbnRlZ2VyLlpFUk87CisgICAgICAgIH0KKyAgICAgICAgaW50W10gcmVzRGlnaXRzID0gbmV3IGludFt2YWwubnVtYmVyTGVuZ3RoICsgMV07CisgICAgICAgIGludCBpOworCisgICAgICAgIGlmICh2YWwuc2lnbiA+IDApIHsKKyAgICAgICAgICAgIC8vIH52YWwgPSAtdmFsICsgMQorICAgICAgICAgICAgaWYgKHZhbC5kaWdpdHNbdmFsLm51bWJlckxlbmd0aCAtIDFdICE9IC0xKSB7CisgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgdmFsLmRpZ2l0c1tpXSA9PSAtMTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IChpIDwgdmFsLm51bWJlckxlbmd0aCkgJiYgKHZhbC5kaWdpdHNbaV0gPT0gLTEpOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoaSA9PSB2YWwubnVtYmVyTGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IDE7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcigtdmFsLnNpZ24sIGkgKyAxLCByZXNEaWdpdHMpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIEhlcmUgYSBjYXJyeSAxIHdhcyBnZW5lcmF0ZWQKKyAgICAgICAgfSBlbHNlIHsvLyAodmFsLnNpZ24gPCAwKQorICAgICAgICAgICAgLy8gfnZhbCA9IC12YWwgLSAxCisgICAgICAgICAgICBmb3IgKGkgPSAwOyB2YWwuZGlnaXRzW2ldID09IDA7IGkrKykgeworICAgICAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gSGVyZSBhIGJvcnJvdyAtMSB3YXMgZ2VuZXJhdGVkCisgICAgICAgIH0KKyAgICAgICAgLy8gTm93LCB0aGUgY2FycnkvYm9ycm93IGNhbiBiZSBhYnNvcmJlZAorICAgICAgICByZXNEaWdpdHNbaV0gPSB2YWwuZGlnaXRzW2ldICsgdmFsLnNpZ247CisgICAgICAgIC8vIENvcHlpbmcgdGhlIHJlbWFpbmluZyB1bmNoYW5nZWQgZGlnaXQKKyAgICAgICAgZm9yIChpKys7IGkgPCB2YWwubnVtYmVyTGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IHZhbC5kaWdpdHNbaV07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKC12YWwuc2lnbiwgaSwgcmVzRGlnaXRzKTsKKyAgICB9CisKKyAgICAvKiogQHNlZSBCaWdJbnRlZ2VyI2FuZChCaWdJbnRlZ2VyKSAqLworICAgIHN0YXRpYyBCaWdJbnRlZ2VyIGFuZChCaWdJbnRlZ2VyIHZhbCwgQmlnSW50ZWdlciB0aGF0KSB7CisgICAgICAgIGlmICh0aGF0LnNpZ24gPT0gMCB8fCB2YWwuc2lnbiA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gQmlnSW50ZWdlci5aRVJPOworICAgICAgICB9CisgICAgICAgIGlmICh0aGF0LmVxdWFscyhCaWdJbnRlZ2VyLk1JTlVTX09ORSkpeworICAgICAgICAgICAgcmV0dXJuIHZhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAodmFsLmVxdWFscyhCaWdJbnRlZ2VyLk1JTlVTX09ORSkpIHsKKyAgICAgICAgICAgIHJldHVybiB0aGF0OworICAgICAgICB9CisKKyAgICAgICAgaWYgKHZhbC5zaWduID4gMCkgeworICAgICAgICAgICAgaWYgKHRoYXQuc2lnbiA+IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYW5kUG9zaXRpdmUodmFsLCB0aGF0KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGFuZERpZmZTaWducyh2YWwsIHRoYXQpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKHRoYXQuc2lnbiA+IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYW5kRGlmZlNpZ25zKHRoYXQsIHZhbCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHZhbC5udW1iZXJMZW5ndGggPiB0aGF0Lm51bWJlckxlbmd0aCkgeworICAgICAgICAgICAgICAgIHJldHVybiBhbmROZWdhdGl2ZSh2YWwsIHRoYXQpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYW5kTmVnYXRpdmUodGhhdCwgdmFsKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKiBAcmV0dXJuIHNpZ24gPSAxLCBtYWduaXR1ZGUgPSB2YWwubWFnbml0dWRlICYgdGhhdC5tYWduaXR1ZGUqLworICAgIHN0YXRpYyBCaWdJbnRlZ2VyIGFuZFBvc2l0aXZlKEJpZ0ludGVnZXIgdmFsLCBCaWdJbnRlZ2VyIHRoYXQpIHsKKyAgICAgICAgLy8gUFJFOiBib3RoIGFyZ3VtZW50cyBhcmUgcG9zaXRpdmUKKyAgICAgICAgaW50IHJlc0xlbmd0aCA9IE1hdGgubWluKHZhbC5udW1iZXJMZW5ndGgsIHRoYXQubnVtYmVyTGVuZ3RoKTsKKyAgICAgICAgaW50IGkgPSBNYXRoLm1heCh2YWwuZ2V0Rmlyc3ROb256ZXJvRGlnaXQoKSwgdGhhdC5nZXRGaXJzdE5vbnplcm9EaWdpdCgpKTsKKworICAgICAgICBpZiAoaSA+PSByZXNMZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiBCaWdJbnRlZ2VyLlpFUk87CisgICAgICAgIH0KKworICAgICAgICBpbnRbXSByZXNEaWdpdHMgPSBuZXcgaW50W3Jlc0xlbmd0aF07CisgICAgICAgIGZvciAoIDsgaSA8IHJlc0xlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSB2YWwuZGlnaXRzW2ldICYgdGhhdC5kaWdpdHNbaV07CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoMSwgcmVzTGVuZ3RoLCByZXNEaWdpdHMpOworICAgIH0KKworICAgIC8qKiBAcmV0dXJuIHNpZ24gPSBwb3NpdGl2ZS5tYWduaXR1ZGUgJiBtYWduaXR1ZGUgPSAtbmVnYXRpdmUubWFnbml0dWRlICovCisgICAgc3RhdGljIEJpZ0ludGVnZXIgYW5kRGlmZlNpZ25zKEJpZ0ludGVnZXIgcG9zaXRpdmUsIEJpZ0ludGVnZXIgbmVnYXRpdmUpIHsKKyAgICAgICAgLy8gUFJFOiBwb3NpdGl2ZSBpcyBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgaXMgbmVnYXRpdmUKKyAgICAgICAgaW50IGlQb3MgPSBwb3NpdGl2ZS5nZXRGaXJzdE5vbnplcm9EaWdpdCgpOworICAgICAgICBpbnQgaU5lZyA9IG5lZ2F0aXZlLmdldEZpcnN0Tm9uemVyb0RpZ2l0KCk7CisKKyAgICAgICAgLy8gTG9vayBpZiB0aGUgdHJhaWxpbmcgemVyb3Mgb2YgdGhlIG5lZ2F0aXZlIHdpbGwgImJsYW5rIiBhbGwKKyAgICAgICAgLy8gdGhlIHBvc2l0aXZlIGRpZ2l0cworICAgICAgICBpZiAoaU5lZyA+PSBwb3NpdGl2ZS5udW1iZXJMZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiBCaWdJbnRlZ2VyLlpFUk87CisgICAgICAgIH0KKyAgICAgICAgaW50IHJlc0xlbmd0aCA9IHBvc2l0aXZlLm51bWJlckxlbmd0aDsKKyAgICAgICAgaW50W10gcmVzRGlnaXRzID0gbmV3IGludFtyZXNMZW5ndGhdOworCisgICAgICAgIC8vIE11c3Qgc3RhcnQgZnJvbSBtYXgoaVBvcywgaU5lZykKKyAgICAgICAgaW50IGkgPSBNYXRoLm1heChpUG9zLCBpTmVnKTsKKyAgICAgICAgaWYgKGkgPT0gaU5lZykgeworICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gLW5lZ2F0aXZlLmRpZ2l0c1tpXSAmIHBvc2l0aXZlLmRpZ2l0c1tpXTsKKyAgICAgICAgICAgIGkrKzsKKyAgICAgICAgfQorICAgICAgICBpbnQgbGltaXQgPSBNYXRoLm1pbihuZWdhdGl2ZS5udW1iZXJMZW5ndGgsIHBvc2l0aXZlLm51bWJlckxlbmd0aCk7CisgICAgICAgIGZvciAoIDsgaSA8IGxpbWl0OyBpKyspIHsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IH5uZWdhdGl2ZS5kaWdpdHNbaV0gJiBwb3NpdGl2ZS5kaWdpdHNbaV07CisgICAgICAgIH0KKyAgICAgICAgLy8gaWYgdGhlIG5lZ2F0aXZlIHdhcyBzaG9ydGVyIG11c3QgY29weSB0aGUgcmVtYWluaW5nIGRpZ2l0cworICAgICAgICAvLyBmcm9tIHBvc2l0aXZlCisgICAgICAgIGlmIChpID49IG5lZ2F0aXZlLm51bWJlckxlbmd0aCkgeworICAgICAgICAgICAgZm9yICggOyBpIDwgcG9zaXRpdmUubnVtYmVyTGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSBwb3NpdGl2ZS5kaWdpdHNbaV07CisgICAgICAgICAgICB9CisgICAgICAgIH0gLy8gZWxzZSBwb3NpdGl2ZSBlbmRlZCBhbmQgbXVzdCAiY29weSIgdmlydHVhbCAwJ3MsIGRvIG5vdGhpbmcgdGhlbgorCisgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcigxLCByZXNMZW5ndGgsIHJlc0RpZ2l0cyk7CisgICAgfQorCisgICAgLyoqIEByZXR1cm4gc2lnbiA9IC0xLCBtYWduaXR1ZGUgPSAtKC1sb25nZXIubWFnbml0dWRlICYgLXNob3J0ZXIubWFnbml0dWRlKSovCisgICAgc3RhdGljIEJpZ0ludGVnZXIgYW5kTmVnYXRpdmUoQmlnSW50ZWdlciBsb25nZXIsIEJpZ0ludGVnZXIgc2hvcnRlcikgeworICAgICAgICAvLyBQUkU6IGxvbmdlciBhbmQgc2hvcnRlciBhcmUgbmVnYXRpdmUKKyAgICAgICAgLy8gUFJFOiBsb25nZXIgaGFzIGF0IGxlYXN0IGFzIG1hbnkgZGlnaXRzIGFzIHNob3J0ZXIKKyAgICAgICAgaW50IGlMb25nZXIgPSBsb25nZXIuZ2V0Rmlyc3ROb256ZXJvRGlnaXQoKTsKKyAgICAgICAgaW50IGlTaG9ydGVyID0gc2hvcnRlci5nZXRGaXJzdE5vbnplcm9EaWdpdCgpOworCisgICAgICAgIC8vIERvZXMgc2hvcnRlciBtYXR0ZXI/CisgICAgICAgIGlmIChpTG9uZ2VyID49IHNob3J0ZXIubnVtYmVyTGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gbG9uZ2VyOworICAgICAgICB9CisKKyAgICAgICAgaW50IHJlc0xlbmd0aDsKKyAgICAgICAgaW50W10gcmVzRGlnaXRzOworICAgICAgICBpbnQgaSA9IE1hdGgubWF4KGlTaG9ydGVyLCBpTG9uZ2VyKTsKKyAgICAgICAgaW50IGRpZ2l0OworICAgICAgICBpZiAoaVNob3J0ZXIgPiBpTG9uZ2VyKSB7CisgICAgICAgICAgICBkaWdpdCA9IC1zaG9ydGVyLmRpZ2l0c1tpXSAmIH5sb25nZXIuZGlnaXRzW2ldOworICAgICAgICB9IGVsc2UgaWYgKGlTaG9ydGVyIDwgaUxvbmdlcikgeworICAgICAgICAgICAgZGlnaXQgPSB+c2hvcnRlci5kaWdpdHNbaV0gJiAtbG9uZ2VyLmRpZ2l0c1tpXTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGRpZ2l0ID0gLXNob3J0ZXIuZGlnaXRzW2ldICYgLWxvbmdlci5kaWdpdHNbaV07CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRpZ2l0ID09IDApIHsKKyAgICAgICAgICAgIGZvciAoaSsrOyBpIDwgc2hvcnRlci5udW1iZXJMZW5ndGggJiYgKGRpZ2l0ID0gfihsb25nZXIuZGlnaXRzW2ldIHwgc2hvcnRlci5kaWdpdHNbaV0pKSA9PSAwOyBpKyspCisgICAgICAgICAgICAgICAgOyAgLy8gZGlnaXQgPSB+bG9uZ2VyLmRpZ2l0c1tpXSAmIH5zaG9ydGVyLmRpZ2l0c1tpXQorICAgICAgICAgICAgaWYgKGRpZ2l0ID09IDApIHsKKyAgICAgICAgICAgICAgICAvLyBzaG9ydGVyIGhhcyBvbmx5IHRoZSByZW1haW5pbmcgdmlydHVhbCBzaWduIGJpdHMKKyAgICAgICAgICAgICAgICBmb3IgKCA7IGkgPCBsb25nZXIubnVtYmVyTGVuZ3RoICYmIChkaWdpdCA9IH5sb25nZXIuZGlnaXRzW2ldKSA9PSAwOyBpKyspCisgICAgICAgICAgICAgICAgICAgIDsKKyAgICAgICAgICAgICAgICBpZiAoZGlnaXQgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICByZXNMZW5ndGggPSBsb25nZXIubnVtYmVyTGVuZ3RoICsgMTsKKyAgICAgICAgICAgICAgICAgICAgcmVzRGlnaXRzID0gbmV3IGludFtyZXNMZW5ndGhdOworICAgICAgICAgICAgICAgICAgICByZXNEaWdpdHNbcmVzTGVuZ3RoIC0gMV0gPSAxOworCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcigtMSwgcmVzTGVuZ3RoLCByZXNEaWdpdHMpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXNMZW5ndGggPSBsb25nZXIubnVtYmVyTGVuZ3RoOworICAgICAgICAgICAgICAgIHJlc0RpZ2l0cyA9IG5ldyBpbnRbcmVzTGVuZ3RoXTsKKyAgICAgICAgcmVzRGlnaXRzW2ldID0gLWRpZ2l0OworICAgICAgICBmb3IgKGkrKzsgaSA8IHNob3J0ZXIubnVtYmVyTGVuZ3RoOyBpKyspeworICAgICAgICAgICAgLy8gcmVzRGlnaXRzW2ldID0gfih+bG9uZ2VyLmRpZ2l0c1tpXSAmIH5zaG9ydGVyLmRpZ2l0c1tpXTspCisgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSBsb25nZXIuZGlnaXRzW2ldIHwgc2hvcnRlci5kaWdpdHNbaV07CisgICAgICAgIH0KKyAgICAgICAgLy8gc2hvcnRlciBoYXMgb25seSB0aGUgcmVtYWluaW5nIHZpcnR1YWwgc2lnbiBiaXRzCisgICAgICAgIGZvciAoIDsgaSA8IGxvbmdlci5udW1iZXJMZW5ndGg7IGkrKyl7CisgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSBsb25nZXIuZGlnaXRzW2ldOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKC0xLCByZXNMZW5ndGgsIHJlc0RpZ2l0cyk7CisgICAgfQorCisgICAgLyoqIEBzZWUgQmlnSW50ZWdlciNhbmROb3QoQmlnSW50ZWdlcikgKi8KKyAgICBzdGF0aWMgQmlnSW50ZWdlciBhbmROb3QoQmlnSW50ZWdlciB2YWwsIEJpZ0ludGVnZXIgdGhhdCkgeworICAgICAgICBpZiAodGhhdC5zaWduID09IDAgKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsOworICAgICAgICB9CisgICAgICAgIGlmICh2YWwuc2lnbiA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gQmlnSW50ZWdlci5aRVJPOworICAgICAgICB9CisgICAgICAgIGlmICh2YWwuZXF1YWxzKEJpZ0ludGVnZXIuTUlOVVNfT05FKSkgeworICAgICAgICAgICAgcmV0dXJuIHRoYXQubm90KCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRoYXQuZXF1YWxzKEJpZ0ludGVnZXIuTUlOVVNfT05FKSl7CisgICAgICAgICAgICByZXR1cm4gQmlnSW50ZWdlci5aRVJPOworICAgICAgICB9CisKKyAgICAgICAgLy9pZiB2YWwgPT0gdGhhdCwgcmV0dXJuIDAKKworICAgICAgIGlmICh2YWwuc2lnbiA+IDApIHsKKyAgICAgICAgICAgIGlmICh0aGF0LnNpZ24gPiAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGFuZE5vdFBvc2l0aXZlKHZhbCwgdGhhdCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBhbmROb3RQb3NpdGl2ZU5lZ2F0aXZlKHZhbCwgdGhhdCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKHRoYXQuc2lnbiA+IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYW5kTm90TmVnYXRpdmVQb3NpdGl2ZSh2YWwsIHRoYXQpOworICAgICAgICAgICAgfSBlbHNlICB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGFuZE5vdE5lZ2F0aXZlKHZhbCwgdGhhdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKiogQHJldHVybiBzaWduID0gMSwgbWFnbml0dWRlID0gdmFsLm1hZ25pdHVkZSAmIH50aGF0Lm1hZ25pdHVkZSovCisgICAgc3RhdGljIEJpZ0ludGVnZXIgYW5kTm90UG9zaXRpdmUoQmlnSW50ZWdlciB2YWwsIEJpZ0ludGVnZXIgdGhhdCkgeworICAgICAgICAvLyBQUkU6IGJvdGggYXJndW1lbnRzIGFyZSBwb3NpdGl2ZQorICAgICAgICBpbnRbXSByZXNEaWdpdHMgPSBuZXcgaW50W3ZhbC5udW1iZXJMZW5ndGhdOworCisgICAgICAgIGludCBsaW1pdCA9IE1hdGgubWluKHZhbC5udW1iZXJMZW5ndGgsIHRoYXQubnVtYmVyTGVuZ3RoKTsKKyAgICAgICAgaW50IGk7CisgICAgICAgIGZvciAoaSA9IHZhbC5nZXRGaXJzdE5vbnplcm9EaWdpdCgpOyBpIDwgbGltaXQ7IGkrKykgeworICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gdmFsLmRpZ2l0c1tpXSAmIH50aGF0LmRpZ2l0c1tpXTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKCA7IGkgPCB2YWwubnVtYmVyTGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IHZhbC5kaWdpdHNbaV07CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoMSwgdmFsLm51bWJlckxlbmd0aCwgcmVzRGlnaXRzKTsKKyAgICB9CisKKyAgICAvKiogQHJldHVybiBzaWduID0gMSwgbWFnbml0dWRlID0gcG9zaXRpdmUubWFnbml0dWRlICYgfigtbmVnYXRpdmUubWFnbml0dWRlKSovCisgICAgc3RhdGljIEJpZ0ludGVnZXIgYW5kTm90UG9zaXRpdmVOZWdhdGl2ZShCaWdJbnRlZ2VyIHBvc2l0aXZlLCBCaWdJbnRlZ2VyIG5lZ2F0aXZlKSB7CisgICAgICAgIC8vIFBSRTogcG9zaXRpdmUgPiAwICYmIG5lZ2F0aXZlIDwgMAorICAgICAgICBpbnQgaU5lZyA9IG5lZ2F0aXZlLmdldEZpcnN0Tm9uemVyb0RpZ2l0KCk7CisgICAgICAgIGludCBpUG9zID0gcG9zaXRpdmUuZ2V0Rmlyc3ROb256ZXJvRGlnaXQoKTsKKworICAgICAgICBpZiAoaU5lZyA+PSBwb3NpdGl2ZS5udW1iZXJMZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiBwb3NpdGl2ZTsKKyAgICAgICAgfQorCisgICAgICAgIGludCByZXNMZW5ndGggPSBNYXRoLm1pbihwb3NpdGl2ZS5udW1iZXJMZW5ndGgsIG5lZ2F0aXZlLm51bWJlckxlbmd0aCk7CisgICAgICAgIGludFtdIHJlc0RpZ2l0cyA9IG5ldyBpbnRbcmVzTGVuZ3RoXTsKKworICAgICAgICAvLyBBbHdheXMgc3RhcnQgZnJvbSBmaXJzdCBub24gemVybyBvZiBwb3NpdGl2ZQorICAgICAgICBpbnQgaSA9IGlQb3M7CisgICAgICAgIGZvciAoIDsgaSA8IGlOZWc7IGkrKykgeworICAgICAgICAgICAgLy8gcmVzRGlnaXRzW2ldID0gcG9zaXRpdmUuZGlnaXRzW2ldICYgLTEgKH4wKQorICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gcG9zaXRpdmUuZGlnaXRzW2ldOworICAgICAgICB9CisgICAgICAgIGlmIChpID09IGlOZWcpIHsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IHBvc2l0aXZlLmRpZ2l0c1tpXSAmIChuZWdhdGl2ZS5kaWdpdHNbaV0gLSAxKTsKKyAgICAgICAgICAgIGkrKzsKKyAgICAgICAgfQorICAgICAgICBmb3IgKCA7IGkgPCByZXNMZW5ndGg7IGkrKykgeworICAgICAgICAgICAgLy8gcmVzRGlnaXRzW2ldID0gcG9zaXRpdmUuZGlnaXRzW2ldICYgfih+bmVnYXRpdmUuZGlnaXRzW2ldKTsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IHBvc2l0aXZlLmRpZ2l0c1tpXSAmIG5lZ2F0aXZlLmRpZ2l0c1tpXTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcigxLCByZXNMZW5ndGgsIHJlc0RpZ2l0cyk7CisgICAgfQorCisgICAgLyoqIEByZXR1cm4gc2lnbiA9IC0xLCBtYWduaXR1ZGUgPSAtKC1uZWdhdGl2ZS5tYWduaXR1ZGUgJiB+cG9zaXRpdmUubWFnbml0dWRlKSovCisgICAgc3RhdGljIEJpZ0ludGVnZXIgYW5kTm90TmVnYXRpdmVQb3NpdGl2ZShCaWdJbnRlZ2VyIG5lZ2F0aXZlLCBCaWdJbnRlZ2VyIHBvc2l0aXZlKSB7CisgICAgICAgIC8vIFBSRTogbmVnYXRpdmUgPCAwICYmIHBvc2l0aXZlID4gMAorICAgICAgICBpbnQgcmVzTGVuZ3RoOworICAgICAgICBpbnRbXSByZXNEaWdpdHM7CisgICAgICAgIGludCBsaW1pdDsKKyAgICAgICAgaW50IGRpZ2l0OworCisgICAgICAgIGludCBpTmVnID0gbmVnYXRpdmUuZ2V0Rmlyc3ROb256ZXJvRGlnaXQoKTsKKyAgICAgICAgaW50IGlQb3MgPSBwb3NpdGl2ZS5nZXRGaXJzdE5vbnplcm9EaWdpdCgpOworCisgICAgICAgIGlmIChpTmVnID49IHBvc2l0aXZlLm51bWJlckxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlOworICAgICAgICB9CisKKyAgICAgICAgcmVzTGVuZ3RoID0gTWF0aC5tYXgobmVnYXRpdmUubnVtYmVyTGVuZ3RoLCBwb3NpdGl2ZS5udW1iZXJMZW5ndGgpOworICAgICAgICBpbnQgaSA9IGlOZWc7CisgICAgICAgIGlmIChpUG9zID4gaU5lZykgeworICAgICAgICAgICAgcmVzRGlnaXRzID0gbmV3IGludFtyZXNMZW5ndGhdOworICAgICAgICAgICAgbGltaXQgPSBNYXRoLm1pbihuZWdhdGl2ZS5udW1iZXJMZW5ndGgsIGlQb3MpOworICAgICAgICAgICAgZm9yICggOyBpIDwgbGltaXQ7IGkrKykgeworICAgICAgICAgICAgICAgIC8vIDFzdCBjYXNlOiAgcmVzRGlnaXRzIFtpXSA9IC0oLW5lZ2F0aXZlLmRpZ2l0c1tpXSAmICh+MCkpCisgICAgICAgICAgICAgICAgLy8gb3RoZXJ3aXNlOiByZXNEaWdpdHNbaV0gPSB+KH5uZWdhdGl2ZS5kaWdpdHNbaV0gJiB+MCkgIDsKKyAgICAgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSBuZWdhdGl2ZS5kaWdpdHNbaV07CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaSA9PSBuZWdhdGl2ZS5udW1iZXJMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGkgPSBpUG9zOyBpIDwgcG9zaXRpdmUubnVtYmVyTGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gcmVzRGlnaXRzW2ldID0gfih+cG9zaXRpdmUuZGlnaXRzW2ldICYgLTEpOworICAgICAgICAgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSBwb3NpdGl2ZS5kaWdpdHNbaV07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZGlnaXQgPSAtbmVnYXRpdmUuZGlnaXRzW2ldICYgfnBvc2l0aXZlLmRpZ2l0c1tpXTsKKyAgICAgICAgICAgIGlmIChkaWdpdCA9PSAwKSB7CisgICAgICAgICAgICAgICAgbGltaXQgPSBNYXRoLm1pbihwb3NpdGl2ZS5udW1iZXJMZW5ndGgsIG5lZ2F0aXZlLm51bWJlckxlbmd0aCk7CisgICAgICAgICAgICAgICAgZm9yIChpKys7IGkgPCBsaW1pdCAmJiAoZGlnaXQgPSB+KG5lZ2F0aXZlLmRpZ2l0c1tpXSB8IHBvc2l0aXZlLmRpZ2l0c1tpXSkpID09IDA7IGkrKykKKyAgICAgICAgICAgICAgICAgICAgOyAvLyBkaWdpdCA9IH5uZWdhdGl2ZS5kaWdpdHNbaV0gJiB+cG9zaXRpdmUuZGlnaXRzW2ldCisgICAgICAgICAgICAgICAgaWYgKGRpZ2l0ID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHNob3J0ZXIgaGFzIG9ubHkgdGhlIHJlbWFpbmluZyB2aXJ0dWFsIHNpZ24gYml0cworICAgICAgICAgICAgICAgICAgICBmb3IgKCA7IGkgPCBwb3NpdGl2ZS5udW1iZXJMZW5ndGggJiYgKGRpZ2l0ID0gfnBvc2l0aXZlLmRpZ2l0c1tpXSkgPT0gMDsgaSsrKQorICAgICAgICAgICAgICAgICAgICAgICAgOyAvLyBkaWdpdCA9IC0xICYgfnBvc2l0aXZlLmRpZ2l0c1tpXQorICAgICAgICAgICAgICAgICAgICBmb3IgKCA7IGkgPCBuZWdhdGl2ZS5udW1iZXJMZW5ndGggJiYgKGRpZ2l0ID0gfm5lZ2F0aXZlLmRpZ2l0c1tpXSkgPT0gMDsgaSsrKQorICAgICAgICAgICAgICAgICAgICAgICAgOyAvLyBkaWdpdCA9IH5uZWdhdGl2ZS5kaWdpdHNbaV0gJiB+MAorICAgICAgICAgICAgICAgICAgICBpZiAoZGlnaXQgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzTGVuZ3RoKys7CisgICAgICAgICAgICAgICAgICAgICAgICByZXNEaWdpdHMgPSBuZXcgaW50W3Jlc0xlbmd0aF07CisgICAgICAgICAgICAgICAgICAgICAgICByZXNEaWdpdHNbcmVzTGVuZ3RoIC0gMV0gPSAxOworCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoLTEsIHJlc0xlbmd0aCwgcmVzRGlnaXRzKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc0RpZ2l0cyA9IG5ldyBpbnRbcmVzTGVuZ3RoXTsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IC1kaWdpdDsKKyAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgIGxpbWl0ID0gTWF0aC5taW4ocG9zaXRpdmUubnVtYmVyTGVuZ3RoLCBuZWdhdGl2ZS5udW1iZXJMZW5ndGgpOworICAgICAgICBmb3IgKCA7IGkgPCBsaW1pdDsgaSsrKSB7CisgICAgICAgICAgICAvL3Jlc0RpZ2l0c1tpXSA9IH4ofm5lZ2F0aXZlLmRpZ2l0c1tpXSAmIH5wb3NpdGl2ZS5kaWdpdHNbaV0pOworICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gbmVnYXRpdmUuZGlnaXRzW2ldIHwgcG9zaXRpdmUuZGlnaXRzW2ldOworICAgICAgICB9CisgICAgICAgIC8vIEFjdHVhbGx5IG9uZSBvZiB0aGUgbmV4dCB0d28gY3ljbGVzIHdpbGwgYmUgZXhlY3V0ZWQKKyAgICAgICAgZm9yICggOyBpIDwgbmVnYXRpdmUubnVtYmVyTGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IG5lZ2F0aXZlLmRpZ2l0c1tpXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgIGZvciAoIDsgaSA8IHBvc2l0aXZlLm51bWJlckxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSBwb3NpdGl2ZS5kaWdpdHNbaV07CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoLTEsIHJlc0xlbmd0aCwgcmVzRGlnaXRzKTsKKyAgICB9CisKKyAgICAvKiogQHJldHVybiBzaWduID0gMSwgbWFnbml0dWRlID0gLXZhbC5tYWduaXR1ZGUgJiB+KC10aGF0Lm1hZ25pdHVkZSkqLworICAgIHN0YXRpYyBCaWdJbnRlZ2VyIGFuZE5vdE5lZ2F0aXZlKEJpZ0ludGVnZXIgdmFsLCBCaWdJbnRlZ2VyIHRoYXQpIHsKKyAgICAgICAgLy8gUFJFOiB2YWwgPCAwICYmIHRoYXQgPCAwCisgICAgICAgIGludCBpVmFsID0gdmFsLmdldEZpcnN0Tm9uemVyb0RpZ2l0KCk7CisgICAgICAgIGludCBpVGhhdCA9IHRoYXQuZ2V0Rmlyc3ROb256ZXJvRGlnaXQoKTsKKworICAgICAgICBpZiAoaVZhbCA+PSB0aGF0Lm51bWJlckxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIEJpZ0ludGVnZXIuWkVSTzsKKyAgICAgICAgfQorCisgICAgICAgIGludCByZXNMZW5ndGggPSB0aGF0Lm51bWJlckxlbmd0aDsKKyAgICAgICAgaW50W10gcmVzRGlnaXRzID0gbmV3IGludFtyZXNMZW5ndGhdOworICAgICAgICBpbnQgbGltaXQ7CisgICAgICAgIGludCBpID0gaVZhbDsKKyAgICAgICAgaWYgKGlWYWwgPCBpVGhhdCkgeworICAgICAgICAgICAgLy8gcmVzRGlnaXRzW2ldID0gLXZhbC5kaWdpdHNbaV0gJiAtMTsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IC12YWwuZGlnaXRzW2ldOworICAgICAgICAgICAgbGltaXQgPSBNYXRoLm1pbih2YWwubnVtYmVyTGVuZ3RoLCBpVGhhdCk7CisgICAgICAgICAgICBmb3IgKGkrKzsgaSA8IGxpbWl0OyBpKyspIHsKKyAgICAgICAgICAgICAgICAvLyByZXNEaWdpdHNbaV0gPSB+dmFsLmRpZ2l0c1tpXSAmIC0xOworICAgICAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IH52YWwuZGlnaXRzW2ldOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGkgPT0gdmFsLm51bWJlckxlbmd0aCkgeworICAgICAgICAgICAgICAgIGZvciAoIDsgaSA8IGlUaGF0OyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gcmVzRGlnaXRzW2ldID0gLTEgJiAtMTsKKyAgICAgICAgICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIHJlc0RpZ2l0c1tpXSA9IC0xICYgfi10aGF0LmRpZ2l0c1tpXTsKKyAgICAgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSB0aGF0LmRpZ2l0c1tpXSAtIDE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gcmVzRGlnaXRzW2ldID0gfnZhbC5kaWdpdHNbaV0gJiB+LXRoYXQuZGlnaXRzW2ldOworICAgICAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IH52YWwuZGlnaXRzW2ldICYgKHRoYXQuZGlnaXRzW2ldIC0gMSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAoaVRoYXQgPCBpVmFsICkgeworICAgICAgICAgICAgLy8gcmVzRGlnaXRzW2ldID0gLXZhbC5kaWdpdHNbaV0gJiB+fnRoYXQuZGlnaXRzW2ldOworICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gLXZhbC5kaWdpdHNbaV0gJiB0aGF0LmRpZ2l0c1tpXTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIHJlc0RpZ2l0c1tpXSA9IC12YWwuZGlnaXRzW2ldICYgfi10aGF0LmRpZ2l0c1tpXTsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IC12YWwuZGlnaXRzW2ldICYgKHRoYXQuZGlnaXRzW2ldIC0gMSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgbGltaXQgPSBNYXRoLm1pbih2YWwubnVtYmVyTGVuZ3RoLCB0aGF0Lm51bWJlckxlbmd0aCk7CisgICAgICAgIGZvciAoaSsrOyBpIDwgbGltaXQ7IGkrKykgeworICAgICAgICAgICAgLy8gcmVzRGlnaXRzW2ldID0gfnZhbC5kaWdpdHNbaV0gJiB+fnRoYXQuZGlnaXRzW2ldOworICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gfnZhbC5kaWdpdHNbaV0gJiB0aGF0LmRpZ2l0c1tpXTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKCA7IGkgPCB0aGF0Lm51bWJlckxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAvLyByZXNEaWdpdHNbaV0gPSAtMSAmIH5+dGhhdC5kaWdpdHNbaV07CisgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSB0aGF0LmRpZ2l0c1tpXTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcigxLCByZXNMZW5ndGgsIHJlc0RpZ2l0cyk7CisgICAgfQorCisgICAgLyoqIEBzZWUgQmlnSW50ZWdlciNvcihCaWdJbnRlZ2VyKSAqLworICAgIHN0YXRpYyBCaWdJbnRlZ2VyIG9yKEJpZ0ludGVnZXIgdmFsLCBCaWdJbnRlZ2VyIHRoYXQpIHsKKyAgICAgICAgaWYgKHRoYXQuZXF1YWxzKEJpZ0ludGVnZXIuTUlOVVNfT05FKSB8fCB2YWwuZXF1YWxzKEJpZ0ludGVnZXIuTUlOVVNfT05FKSkgeworICAgICAgICAgICAgcmV0dXJuIEJpZ0ludGVnZXIuTUlOVVNfT05FOworICAgICAgICB9CisgICAgICAgIGlmICh0aGF0LnNpZ24gPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHZhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAodmFsLnNpZ24gPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHRoYXQ7CisgICAgICAgIH0KKworICAgICAgICBpZiAodmFsLnNpZ24gPiAwKSB7CisgICAgICAgICAgICBpZiAodGhhdC5zaWduID4gMCkgeworICAgICAgICAgICAgICAgIGlmICh2YWwubnVtYmVyTGVuZ3RoID4gdGhhdC5udW1iZXJMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9yUG9zaXRpdmUodmFsLCB0aGF0KTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3JQb3NpdGl2ZSh0aGF0LCB2YWwpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG9yRGlmZlNpZ25zKHZhbCwgdGhhdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAodGhhdC5zaWduID4gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBvckRpZmZTaWducyh0aGF0LCB2YWwpOworICAgICAgICAgICAgfSBlbHNlIGlmICh0aGF0LmdldEZpcnN0Tm9uemVyb0RpZ2l0KCkgPiB2YWwuZ2V0Rmlyc3ROb256ZXJvRGlnaXQoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBvck5lZ2F0aXZlKHRoYXQsIHZhbCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBvck5lZ2F0aXZlKHZhbCwgdGhhdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKiogQHJldHVybiBzaWduID0gMSwgbWFnbml0dWRlID0gbG9uZ2VyLm1hZ25pdHVkZSB8IHNob3J0ZXIubWFnbml0dWRlKi8KKyAgICBzdGF0aWMgQmlnSW50ZWdlciBvclBvc2l0aXZlKEJpZ0ludGVnZXIgbG9uZ2VyLCBCaWdJbnRlZ2VyIHNob3J0ZXIpIHsKKyAgICAgICAgLy8gUFJFOiBsb25nZXIgYW5kIHNob3J0ZXIgYXJlIHBvc2l0aXZlOworICAgICAgICAvLyBQUkU6IGxvbmdlciBoYXMgYXQgbGVhc3QgYXMgbWFueSBkaWdpdHMgYXMgc2hvcnRlcgorICAgICAgICBpbnQgcmVzTGVuZ3RoID0gbG9uZ2VyLm51bWJlckxlbmd0aDsKKyAgICAgICAgaW50W10gcmVzRGlnaXRzID0gbmV3IGludFtyZXNMZW5ndGhdOworCisgICAgICAgIGludCBpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc2hvcnRlci5udW1iZXJMZW5ndGg7IGkrKykgeworICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gbG9uZ2VyLmRpZ2l0c1tpXSB8IHNob3J0ZXIuZGlnaXRzW2ldOworICAgICAgICB9CisgICAgICAgIGZvciAoIDsgaSA8IHJlc0xlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSBsb25nZXIuZGlnaXRzW2ldOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKDEsIHJlc0xlbmd0aCwgcmVzRGlnaXRzKTsKKyAgICB9CisKKyAgICAvKiogQHJldHVybiBzaWduID0gLTEsIG1hZ25pdHVkZSA9IC0oLXZhbC5tYWduaXR1ZGUgfCAtdGhhdC5tYWduaXR1ZGUpICovCisgICAgc3RhdGljIEJpZ0ludGVnZXIgb3JOZWdhdGl2ZShCaWdJbnRlZ2VyIHZhbCwgQmlnSW50ZWdlciB0aGF0KXsKKyAgICAgICAgLy8gUFJFOiB2YWwgYW5kIHRoYXQgYXJlIG5lZ2F0aXZlOworICAgICAgICAvLyBQUkU6IHZhbCBoYXMgYXQgbGVhc3QgYXMgbWFueSB0cmFpbGluZyB6ZXJvcyBkaWdpdHMgYXMgdGhhdAorICAgICAgICBpbnQgaVRoYXQgPSB0aGF0LmdldEZpcnN0Tm9uemVyb0RpZ2l0KCk7CisgICAgICAgIGludCBpVmFsID0gdmFsLmdldEZpcnN0Tm9uemVyb0RpZ2l0KCk7CisgICAgICAgIGludCBpOworCisgICAgICAgIGlmIChpVmFsID49IHRoYXQubnVtYmVyTGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gdGhhdDsKKyAgICAgICAgfWVsc2UgaWYgKGlUaGF0ID49IHZhbC5udW1iZXJMZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiB2YWw7CisgICAgICAgIH0KKworICAgICAgICBpbnQgcmVzTGVuZ3RoID0gTWF0aC5taW4odmFsLm51bWJlckxlbmd0aCwgdGhhdC5udW1iZXJMZW5ndGgpOworICAgICAgICBpbnRbXSByZXNEaWdpdHMgPSBuZXcgaW50W3Jlc0xlbmd0aF07CisKKyAgICAgICAgLy9Mb29raW5nIGZvciB0aGUgZmlyc3Qgbm9uLXplcm8gZGlnaXQgb2YgdGhlIHJlc3VsdAorICAgICAgICBpZiAoaVRoYXQgPT0gaVZhbCkgeworICAgICAgICAgICAgcmVzRGlnaXRzW2lWYWxdID0gLSgtdmFsLmRpZ2l0c1tpVmFsXSB8IC10aGF0LmRpZ2l0c1tpVmFsXSk7CisgICAgICAgICAgICBpID0gaVZhbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZvciAoaSA9IGlUaGF0OyBpIDwgaVZhbDsgaSsrKSB7CisgICAgICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gdGhhdC5kaWdpdHNbaV07CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSB0aGF0LmRpZ2l0c1tpXSAmICh2YWwuZGlnaXRzW2ldIC0gMSk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGkrKzsgaSA8IHJlc0xlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSB2YWwuZGlnaXRzW2ldICYgdGhhdC5kaWdpdHNbaV07CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoLTEsIHJlc0xlbmd0aCwgcmVzRGlnaXRzKTsKKyAgICB9CisKKyAgICAvKiogQHJldHVybiBzaWduID0gLTEsIG1hZ25pdHVkZSA9IC0ocG9zaXRpdmUubWFnbml0dWRlIHwgLW5lZ2F0aXZlLm1hZ25pdHVkZSkgKi8KKyAgICBzdGF0aWMgQmlnSW50ZWdlciBvckRpZmZTaWducyhCaWdJbnRlZ2VyIHBvc2l0aXZlLCBCaWdJbnRlZ2VyIG5lZ2F0aXZlKXsKKyAgICAgICAgLy8gSnVtcGluZyBvdmVyIHRoZSBsZWFzdCBzaWduaWZpY2FudCB6ZXJvIGJpdHMKKyAgICAgICAgaW50IGlOZWcgPSBuZWdhdGl2ZS5nZXRGaXJzdE5vbnplcm9EaWdpdCgpOworICAgICAgICBpbnQgaVBvcyA9IHBvc2l0aXZlLmdldEZpcnN0Tm9uemVyb0RpZ2l0KCk7CisgICAgICAgIGludCBpOworICAgICAgICBpbnQgbGltaXQ7CisKKyAgICAgICAgLy8gTG9vayBpZiB0aGUgdHJhaWxpbmcgemVyb3Mgb2YgdGhlIHBvc2l0aXZlIHdpbGwgImNvcHkiIGFsbAorICAgICAgICAvLyB0aGUgbmVnYXRpdmUgZGlnaXRzCisgICAgICAgIGlmIChpUG9zID49IG5lZ2F0aXZlLm51bWJlckxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlOworICAgICAgICB9CisgICAgICAgIGludCByZXNMZW5ndGggPSBuZWdhdGl2ZS5udW1iZXJMZW5ndGg7CisgICAgICAgIGludFtdIHJlc0RpZ2l0cyA9IG5ldyBpbnRbcmVzTGVuZ3RoXTsKKworICAgICAgICBpZiAoaU5lZyA8IGlQb3MgKSB7CisgICAgICAgICAgICAvLyBXZSBrbm93IGZvciBzdXJlIHRoYXQgdGhpcyB3aWxsCisgICAgICAgICAgICAvLyBiZSB0aGUgZmlyc3Qgbm9uIHplcm8gZGlnaXQgaW4gdGhlIHJlc3VsdAorICAgICAgICAgICAgZm9yIChpID0gaU5lZzsgaSA8IGlQb3M7IGkrKykgeworICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gbmVnYXRpdmUuZGlnaXRzW2ldOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKGlQb3MgPCBpTmVnKSB7CisgICAgICAgICAgICBpID0gaVBvczsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IC1wb3NpdGl2ZS5kaWdpdHNbaV07CisgICAgICAgICAgICBsaW1pdCA9IE1hdGgubWluKHBvc2l0aXZlLm51bWJlckxlbmd0aCwgaU5lZyk7CisgICAgICAgICAgICBmb3IgKGkrKzsgaSA8IGxpbWl0OyBpKysgKSB7CisgICAgICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gfnBvc2l0aXZlLmRpZ2l0c1tpXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpICE9IHBvc2l0aXZlLm51bWJlckxlbmd0aCkgeworICAgICAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IH4oLW5lZ2F0aXZlLmRpZ2l0c1tpXSB8IHBvc2l0aXZlLmRpZ2l0c1tpXSk7CisgICAgICAgICAgICB9IGVsc2V7CisgICAgICAgICAgICAgICAgICBmb3IgKDsgaTxpTmVnOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSAtMTsKKyAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgIC8vIHJlc0RpZ2l0c1tpXSA9IH4oLW5lZ2F0aXZlLmRpZ2l0c1tpXSB8IDApOworICAgICAgICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gbmVnYXRpdmUuZGlnaXRzW2ldIC0gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGkrKzsKKyAgICAgICAgfSBlbHNlIHsvLyBpTmVnID09IGlQb3MKKyAgICAgICAgICAgIC8vIEFwcGx5aW5nIHR3byBjb21wbGVtZW50IHRvIG5lZ2F0aXZlIGFuZCB0byByZXN1bHQKKyAgICAgICAgICAgIGkgPSBpUG9zOworICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gLSgtbmVnYXRpdmUuZGlnaXRzW2ldIHwgcG9zaXRpdmUuZGlnaXRzW2ldKTsKKyAgICAgICAgICAgIGkrKzsKKyAgICAgICAgfQorICAgICAgICBsaW1pdCA9IE1hdGgubWluKG5lZ2F0aXZlLm51bWJlckxlbmd0aCwgcG9zaXRpdmUubnVtYmVyTGVuZ3RoKTsKKyAgICAgICAgZm9yICg7IGkgPCBsaW1pdDsgaSsrKSB7CisgICAgICAgICAgICAvLyBBcHBseWluZyB0d28gY29tcGxlbWVudCB0byBuZWdhdGl2ZSBhbmQgdG8gcmVzdWx0CisgICAgICAgICAgICAvLyByZXNEaWdpdHNbaV0gPSB+KH5uZWdhdGl2ZS5kaWdpdHNbaV0gfCBwb3NpdGl2ZS5kaWdpdHNbaV0gKTsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IG5lZ2F0aXZlLmRpZ2l0c1tpXSAmIH5wb3NpdGl2ZS5kaWdpdHNbaV07CisgICAgICAgIH0KKyAgICAgICAgZm9yICggOyBpIDwgbmVnYXRpdmUubnVtYmVyTGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IG5lZ2F0aXZlLmRpZ2l0c1tpXTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcigtMSwgcmVzTGVuZ3RoLCByZXNEaWdpdHMpOworICAgIH0KKworICAgIC8qKiBAc2VlIEJpZ0ludGVnZXIjeG9yKEJpZ0ludGVnZXIpICovCisgICAgc3RhdGljIEJpZ0ludGVnZXIgeG9yKEJpZ0ludGVnZXIgdmFsLCBCaWdJbnRlZ2VyIHRoYXQpIHsKKyAgICAgICAgaWYgKHRoYXQuc2lnbiA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsOworICAgICAgICB9CisgICAgICAgIGlmICh2YWwuc2lnbiA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gdGhhdDsKKyAgICAgICAgfQorICAgICAgICBpZiAodGhhdC5lcXVhbHMoQmlnSW50ZWdlci5NSU5VU19PTkUpKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsLm5vdCgpOworICAgICAgICB9CisgICAgICAgIGlmICh2YWwuZXF1YWxzKEJpZ0ludGVnZXIuTUlOVVNfT05FKSkgeworICAgICAgICAgICAgcmV0dXJuIHRoYXQubm90KCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAodmFsLnNpZ24gPiAwKSB7CisgICAgICAgICAgICBpZiAodGhhdC5zaWduID4gMCkgeworICAgICAgICAgICAgICAgIGlmICh2YWwubnVtYmVyTGVuZ3RoID4gdGhhdC5udW1iZXJMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHhvclBvc2l0aXZlKHZhbCwgdGhhdCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHhvclBvc2l0aXZlKHRoYXQsIHZhbCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4geG9yRGlmZlNpZ25zKHZhbCwgdGhhdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAodGhhdC5zaWduID4gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiB4b3JEaWZmU2lnbnModGhhdCwgdmFsKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodGhhdC5nZXRGaXJzdE5vbnplcm9EaWdpdCgpID4gdmFsLmdldEZpcnN0Tm9uemVyb0RpZ2l0KCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4geG9yTmVnYXRpdmUodGhhdCwgdmFsKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHhvck5lZ2F0aXZlKHZhbCwgdGhhdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKiogQHJldHVybiBzaWduID0gMCwgbWFnbml0dWRlID0gbG9uZ2VyLm1hZ25pdHVkZSB8IHNob3J0ZXIubWFnbml0dWRlICovCisgICAgc3RhdGljIEJpZ0ludGVnZXIgeG9yUG9zaXRpdmUoQmlnSW50ZWdlciBsb25nZXIsIEJpZ0ludGVnZXIgc2hvcnRlcikgeworICAgICAgICAvLyBQUkU6IGxvbmdlciBhbmQgc2hvcnRlciBhcmUgcG9zaXRpdmU7CisgICAgICAgIC8vIFBSRTogbG9uZ2VyIGhhcyBhdCBsZWFzdCBhcyBtYW55IGRpZ2l0cyBhcyBzaG9ydGVyCisgICAgICAgIGludCByZXNMZW5ndGggPSBsb25nZXIubnVtYmVyTGVuZ3RoOworICAgICAgICBpbnRbXSByZXNEaWdpdHMgPSBuZXcgaW50W3Jlc0xlbmd0aF07CisgICAgICAgIGludCBpID0gTWF0aC5taW4obG9uZ2VyLmdldEZpcnN0Tm9uemVyb0RpZ2l0KCksIHNob3J0ZXIuZ2V0Rmlyc3ROb256ZXJvRGlnaXQoKSk7CisgICAgICAgIGZvciAoIDsgaSA8IHNob3J0ZXIubnVtYmVyTGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IGxvbmdlci5kaWdpdHNbaV0gXiBzaG9ydGVyLmRpZ2l0c1tpXTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKCA7IGkgPCBsb25nZXIubnVtYmVyTGVuZ3RoOyBpKysgKXsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IGxvbmdlci5kaWdpdHNbaV07CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoMSwgcmVzTGVuZ3RoLCByZXNEaWdpdHMpOworICAgIH0KKworICAgIC8qKiBAcmV0dXJuIHNpZ24gPSAwLCBtYWduaXR1ZGUgPSAtdmFsLm1hZ25pdHVkZSBeIC10aGF0Lm1hZ25pdHVkZSAqLworICAgIHN0YXRpYyBCaWdJbnRlZ2VyIHhvck5lZ2F0aXZlKEJpZ0ludGVnZXIgdmFsLCBCaWdJbnRlZ2VyIHRoYXQpeworICAgICAgICAvLyBQUkU6IHZhbCBhbmQgdGhhdCBhcmUgbmVnYXRpdmUKKyAgICAgICAgLy8gUFJFOiB2YWwgaGFzIGF0IGxlYXN0IGFzIG1hbnkgdHJhaWxpbmcgemVybyBkaWdpdHMgYXMgdGhhdAorICAgICAgICBpbnQgcmVzTGVuZ3RoID0gTWF0aC5tYXgodmFsLm51bWJlckxlbmd0aCwgdGhhdC5udW1iZXJMZW5ndGgpOworICAgICAgICBpbnRbXSByZXNEaWdpdHMgPSBuZXcgaW50W3Jlc0xlbmd0aF07CisgICAgICAgIGludCBpVmFsID0gdmFsLmdldEZpcnN0Tm9uemVyb0RpZ2l0KCk7CisgICAgICAgIGludCBpVGhhdCA9IHRoYXQuZ2V0Rmlyc3ROb256ZXJvRGlnaXQoKTsKKyAgICAgICAgaW50IGkgPSBpVGhhdDsKKyAgICAgICAgaW50IGxpbWl0OworCisKKyAgICAgICAgaWYgKGlWYWwgPT0gaVRoYXQpIHsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IC12YWwuZGlnaXRzW2ldIF4gLXRoYXQuZGlnaXRzW2ldOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gLXRoYXQuZGlnaXRzW2ldOworICAgICAgICAgICAgbGltaXQgPSBNYXRoLm1pbih0aGF0Lm51bWJlckxlbmd0aCwgaVZhbCk7CisgICAgICAgICAgICBmb3IgKGkrKzsgaSA8IGxpbWl0OyBpKyspIHsKKyAgICAgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSB+dGhhdC5kaWdpdHNbaV07CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBSZW1haW5zIGRpZ2l0cyBpbiB0aGF0PworICAgICAgICAgICAgaWYgKGkgPT0gdGhhdC5udW1iZXJMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAvL0p1bXBpbmcgb3ZlciB0aGUgcmVtYWluaW5nIHplcm8gdG8gdGhlIGZpcnN0IG5vbiBvbmUKKyAgICAgICAgICAgICAgICBmb3IgKCA7aSA8IGlWYWw7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAvL3Jlc0RpZ2l0c1tpXSA9IDAgXiAtMTsKKyAgICAgICAgICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vcmVzRGlnaXRzW2ldID0gLXZhbC5kaWdpdHNbaV0gXiAtMTsKKyAgICAgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSB2YWwuZGlnaXRzW2ldIC0gMTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gLXZhbC5kaWdpdHNbaV0gXiB+dGhhdC5kaWdpdHNbaV07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBsaW1pdCA9IE1hdGgubWluKHZhbC5udW1iZXJMZW5ndGgsIHRoYXQubnVtYmVyTGVuZ3RoKTsKKyAgICAgICAgLy9QZXJmb3JtIF4gYmV0d2VlbiB0aGF0IGFsIHZhbCB1bnRpbCB0aGF0IGVuZHMKKyAgICAgICAgZm9yIChpKys7IGkgPCBsaW1pdDsgaSsrKSB7CisgICAgICAgICAgICAvL3Jlc0RpZ2l0c1tpXSA9IH52YWwuZGlnaXRzW2ldIF4gfnRoYXQuZGlnaXRzW2ldOworICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gdmFsLmRpZ2l0c1tpXSBeIHRoYXQuZGlnaXRzW2ldOworICAgICAgICB9CisgICAgICAgIC8vUGVyZm9ybSBeIGJldHdlZW4gdmFsIGRpZ2l0cyBhbmQgLTEgdW50aWwgdmFsIGVuZHMKKyAgICAgICAgZm9yICggOyBpIDwgdmFsLm51bWJlckxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAvL3Jlc0RpZ2l0c1tpXSA9IH52YWwuZGlnaXRzW2ldIF4gLTEgIDsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IHZhbC5kaWdpdHNbaV0gOworICAgICAgICB9CisgICAgICAgIGZvciAoIDsgaSA8IHRoYXQubnVtYmVyTGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIC8vcmVzRGlnaXRzW2ldID0gLTEgXiB+dGhhdC5kaWdpdHNbaV0gOworICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gdGhhdC5kaWdpdHNbaV07CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoMSwgcmVzTGVuZ3RoLCByZXNEaWdpdHMpOworICAgIH0KKworICAgIC8qKiBAcmV0dXJuIHNpZ24gPSAxLCBtYWduaXR1ZGUgPSAtKHBvc2l0aXZlLm1hZ25pdHVkZSBeIC1uZWdhdGl2ZS5tYWduaXR1ZGUpKi8KKyAgICBzdGF0aWMgQmlnSW50ZWdlciB4b3JEaWZmU2lnbnMoQmlnSW50ZWdlciBwb3NpdGl2ZSwgQmlnSW50ZWdlciBuZWdhdGl2ZSl7CisgICAgICAgIGludCByZXNMZW5ndGggPSBNYXRoLm1heChuZWdhdGl2ZS5udW1iZXJMZW5ndGgsIHBvc2l0aXZlLm51bWJlckxlbmd0aCk7CisgICAgICAgIGludFtdIHJlc0RpZ2l0czsKKyAgICAgICAgaW50IGlOZWcgPSBuZWdhdGl2ZS5nZXRGaXJzdE5vbnplcm9EaWdpdCgpOworICAgICAgICBpbnQgaVBvcyA9IHBvc2l0aXZlLmdldEZpcnN0Tm9uemVyb0RpZ2l0KCk7CisgICAgICAgIGludCBpOworICAgICAgICBpbnQgbGltaXQ7CisKKyAgICAgICAgLy9UaGUgZmlyc3QKKyAgICAgICAgaWYgKGlOZWcgPCBpUG9zKSB7CisgICAgICAgICAgICByZXNEaWdpdHMgPSBuZXcgaW50W3Jlc0xlbmd0aF07CisgICAgICAgICAgICBpID0gaU5lZzsKKyAgICAgICAgICAgIC8vcmVzRGlnaXRzW2ldID0gLSgtbmVnYXRpdmUuZGlnaXRzW2ldKTsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IG5lZ2F0aXZlLmRpZ2l0c1tpXTsKKyAgICAgICAgICAgIGxpbWl0ID0gTWF0aC5taW4obmVnYXRpdmUubnVtYmVyTGVuZ3RoLCBpUG9zKTsKKyAgICAgICAgICAgIC8vU2tpcCB0aGUgcG9zaXRpdmUgZGlnaXRzIHdoaWxlIHRoZXkgYXJlIHplcm9zCisgICAgICAgICAgICBmb3IgKGkrKzsgaSA8IGxpbWl0OyBpKyspIHsKKyAgICAgICAgICAgICAgICAvL3Jlc0RpZ2l0c1tpXSA9IH4ofm5lZ2F0aXZlLmRpZ2l0c1tpXSk7CisgICAgICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gbmVnYXRpdmUuZGlnaXRzW2ldOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy9pZiB0aGUgbmVnYXRpdmUgaGFzIG5vIG1vcmUgZWxlbWVudHMsIG11c3QgZmlsbCB0aGUKKyAgICAgICAgICAgIC8vcmVzdWx0IHdpdGggdGhlIHJlbWFpbmluZyBkaWdpdHMgb2YgdGhlIHBvc2l0aXZlCisgICAgICAgICAgICBpZiAoaSA9PSBuZWdhdGl2ZS5udW1iZXJMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBmb3IgKCA7IGkgPCBwb3NpdGl2ZS5udW1iZXJMZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAvL3Jlc0RpZ2l0c1tpXSA9IH4ocG9zaXRpdmUuZGlnaXRzW2ldIF4gLTEpIC0+IH4ofnBvc2l0aXZlLmRpZ2l0c1tpXSkKKyAgICAgICAgICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gcG9zaXRpdmUuZGlnaXRzW2ldOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChpUG9zIDwgaU5lZykgeworICAgICAgICAgICAgcmVzRGlnaXRzID0gbmV3IGludFtyZXNMZW5ndGhdOworICAgICAgICAgICAgaSA9IGlQb3M7CisgICAgICAgICAgICAvL0FwcGx5aW5nIHR3byBjb21wbGVtZW50IHRvIHRoZSBmaXJzdCBub24temVybyBkaWdpdCBvZiB0aGUgcmVzdWx0CisgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSAtcG9zaXRpdmUuZGlnaXRzW2ldOworICAgICAgICAgICAgbGltaXQgPSBNYXRoLm1pbihwb3NpdGl2ZS5udW1iZXJMZW5ndGgsIGlOZWcpOworICAgICAgICAgICAgZm9yIChpKys7IGkgPCBsaW1pdDsgaSsrKSB7CisgICAgICAgICAgICAgICAgLy9Db250aW51ZSBhcHBseWluZyB0d28gY29tcGxlbWVudCB0aGUgcmVzdWx0CisgICAgICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gfnBvc2l0aXZlLmRpZ2l0c1tpXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vV2hlbiB0aGUgZmlyc3Qgbm9uLXplcm8gZGlnaXQgb2YgdGhlIG5lZ2F0aXZlIGlzIHJlYWNoZWQsIG11c3QgYXBwbHkKKyAgICAgICAgICAgIC8vdHdvIGNvbXBsZW1lbnQgKGFyaXRobWV0aWMgbmVnYXRpb24pIHRvIGl0LCBhbmQgdGhlbiBvcGVyYXRlCisgICAgICAgICAgICBpZiAoaSA9PSBpTmVnKSB7CisgICAgICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gfihwb3NpdGl2ZS5kaWdpdHNbaV0gXiAtbmVnYXRpdmUuZGlnaXRzW2ldKTsKKyAgICAgICAgICAgICAgICBpKys7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vaWYgdGhlIHBvc2l0aXZlIGhhcyBubyBtb3JlIGVsZW1lbnRzIG11c3QgZmlsbCB0aGUgcmVtYWluaW5nIGRpZ2l0cyB3aXRoCisgICAgICAgICAgICAgICAgLy90aGUgbmVnYXRpdmUgb25lcworICAgICAgICAgICAgICAgIGZvciAoIDsgaSA8IGlOZWc7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAvLyByZXNEaWdpdHNbaV0gPSB+KDAgXiAwKQorICAgICAgICAgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSAtMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZm9yICggOyBpIDwgbmVnYXRpdmUubnVtYmVyTGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgLy9yZXNEaWdpdHNbaV0gPSB+KH5uZWdhdGl2ZS5kaWdpdHNbaV0gXiAwKQorICAgICAgICAgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSBuZWdhdGl2ZS5kaWdpdHNbaV07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvL1RoZSBmaXJzdCBub24temVybyBkaWdpdCBvZiB0aGUgcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIGFyZSB0aGUgc2FtZQorICAgICAgICAgICAgaSA9IGlOZWc7CisgICAgICAgICAgICBpbnQgZGlnaXQgPSBwb3NpdGl2ZS5kaWdpdHNbaV0gXiAtbmVnYXRpdmUuZGlnaXRzW2ldOworICAgICAgICAgICAgaWYgKGRpZ2l0ID09IDApIHsKKyAgICAgICAgICAgICAgICBsaW1pdCA9IE1hdGgubWluKHBvc2l0aXZlLm51bWJlckxlbmd0aCwgbmVnYXRpdmUubnVtYmVyTGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBmb3IgKGkrKzsgaSA8IGxpbWl0ICYmIChkaWdpdCA9IHBvc2l0aXZlLmRpZ2l0c1tpXSBeIH5uZWdhdGl2ZS5kaWdpdHNbaV0pID09IDA7IGkrKykKKyAgICAgICAgICAgICAgICAgICAgOworICAgICAgICAgICAgICAgIGlmIChkaWdpdCA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIHNob3J0ZXIgaGFzIG9ubHkgdGhlIHJlbWFpbmluZyB2aXJ0dWFsIHNpZ24gYml0cworICAgICAgICAgICAgICAgICAgICBmb3IgKCA7IGkgPCBwb3NpdGl2ZS5udW1iZXJMZW5ndGggJiYgKGRpZ2l0ID0gfnBvc2l0aXZlLmRpZ2l0c1tpXSkgPT0gMDsgaSsrKQorICAgICAgICAgICAgICAgICAgICAgICAgOworICAgICAgICAgICAgICAgICAgICBmb3IgKCA7IGkgPCBuZWdhdGl2ZS5udW1iZXJMZW5ndGggJiYgKGRpZ2l0ID0gfm5lZ2F0aXZlLmRpZ2l0c1tpXSkgPT0gMDsgaSsrKQorICAgICAgICAgICAgICAgICAgICAgICAgOworICAgICAgICAgICAgICAgICAgICBpZiAoZGlnaXQgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzTGVuZ3RoID0gcmVzTGVuZ3RoICsgMTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc0RpZ2l0cyA9IG5ldyBpbnRbcmVzTGVuZ3RoXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc0RpZ2l0c1tyZXNMZW5ndGggLSAxXSA9IDE7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcigtMSwgcmVzTGVuZ3RoLCByZXNEaWdpdHMpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAgICAgcmVzRGlnaXRzID0gbmV3IGludFtyZXNMZW5ndGhdOworICAgICAgICAgICAgcmVzRGlnaXRzW2ldID0gLWRpZ2l0OworICAgICAgICAgICAgaSsrOworICAgICAgICB9CisKKyAgICAgICAgbGltaXQgPSBNYXRoLm1pbihuZWdhdGl2ZS5udW1iZXJMZW5ndGgsIHBvc2l0aXZlLm51bWJlckxlbmd0aCk7CisgICAgICAgIGZvciAoIDsgaSA8IGxpbWl0OyBpKyspIHsKKyAgICAgICAgICAgIHJlc0RpZ2l0c1tpXSA9IH4ofm5lZ2F0aXZlLmRpZ2l0c1tpXSBeIHBvc2l0aXZlLmRpZ2l0c1tpXSk7CisgICAgICAgIH0KKyAgICAgICAgZm9yICggOyBpIDwgcG9zaXRpdmUubnVtYmVyTGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIC8vIHJlc0RpZ2l0c1tpXSA9IH4ocG9zaXRpdmUuZGlnaXRzW2ldIF4gLTEpCisgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSBwb3NpdGl2ZS5kaWdpdHNbaV07CisgICAgICAgIH0KKyAgICAgICAgZm9yICggOyBpIDwgbmVnYXRpdmUubnVtYmVyTGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIC8vIHJlc0RpZ2l0c1tpXSA9IH4oMCBeIH5uZWdhdGl2ZS5kaWdpdHNbaV0pCisgICAgICAgICAgICByZXNEaWdpdHNbaV0gPSBuZWdhdGl2ZS5kaWdpdHNbaV07CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoLTEsIHJlc0xlbmd0aCwgcmVzRGlnaXRzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9tYXRoL01hdGhDb250ZXh0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9tYXRoL01hdGhDb250ZXh0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmYzZjFlZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL21hdGgvTWF0aENvbnRleHQuamF2YQpAQCAtMCwwICsxLDI0OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm1hdGg7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5pby5TdHJlYW1Db3JydXB0ZWRFeGNlcHRpb247CisKKy8qKgorICogSW1tdXRhYmxlIG9iamVjdHMgZGVzY3JpYmluZyBzZXR0aW5ncyBzdWNoIGFzIHJvdW5kaW5nIG1vZGUgYW5kIGRpZ2l0CisgKiBwcmVjaXNpb24gZm9yIHRoZSBudW1lcmljYWwgb3BlcmF0aW9ucyBwcm92aWRlZCBieSBjbGFzcyB7QGxpbmsgQmlnRGVjaW1hbH0uCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBNYXRoQ29udGV4dCBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTU3OTcyMDAwNDc4Njg0ODI1NUw7CisKKyAgICAvKioKKyAgICAgKiBBIHtAY29kZSBNYXRoQ29udGV4dH0gd2hpY2ggY29ycmVzcG9uZHMgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSUVFRV83NTQtMTk4NSI+SUVFRSA3NTQ8L2E+IHF1YWRydXBsZQorICAgICAqIGRlY2ltYWwgcHJlY2lzaW9uIGZvcm1hdDogMzQgZGlnaXQgcHJlY2lzaW9uIGFuZAorICAgICAqIHtAbGluayBSb3VuZGluZ01vZGUjSEFMRl9FVkVOfSByb3VuZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hdGhDb250ZXh0IERFQ0lNQUwxMjggPSBuZXcgTWF0aENvbnRleHQoMzQsIFJvdW5kaW5nTW9kZS5IQUxGX0VWRU4pOworCisgICAgLyoqCisgICAgICogQSB7QGNvZGUgTWF0aENvbnRleHR9IHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lFRUVfNzU0LTE5ODUiPklFRUUgNzU0PC9hPiBzaW5nbGUgZGVjaW1hbAorICAgICAqIHByZWNpc2lvbiBmb3JtYXQ6IDcgZGlnaXQgcHJlY2lzaW9uIGFuZCB7QGxpbmsgUm91bmRpbmdNb2RlI0hBTEZfRVZFTn0KKyAgICAgKiByb3VuZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hdGhDb250ZXh0IERFQ0lNQUwzMiA9IG5ldyBNYXRoQ29udGV4dCg3LCBSb3VuZGluZ01vZGUuSEFMRl9FVkVOKTsKKworICAgIC8qKgorICAgICAqIEEge0Bjb2RlIE1hdGhDb250ZXh0fSB3aGljaCBjb3JyZXNwb25kcyB0byB0aGUgPGEgaHJlZj0iaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JRUVFXzc1NC0xOTg1Ij5JRUVFIDc1NDwvYT4gZG91YmxlIGRlY2ltYWwKKyAgICAgKiBwcmVjaXNpb24gZm9ybWF0OiAxNiBkaWdpdCBwcmVjaXNpb24gYW5kIHtAbGluayBSb3VuZGluZ01vZGUjSEFMRl9FVkVOfQorICAgICAqIHJvdW5kaW5nLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWF0aENvbnRleHQgREVDSU1BTDY0ID0gbmV3IE1hdGhDb250ZXh0KDE2LCBSb3VuZGluZ01vZGUuSEFMRl9FVkVOKTsKKworICAgIC8qKgorICAgICAqIEEge0Bjb2RlIE1hdGhDb250ZXh0fSBmb3IgdW5saW1pdGVkIHByZWNpc2lvbiB3aXRoCisgICAgICoge0BsaW5rIFJvdW5kaW5nTW9kZSNIQUxGX1VQfSByb3VuZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hdGhDb250ZXh0IFVOTElNSVRFRCA9IG5ldyBNYXRoQ29udGV4dCgwLCBSb3VuZGluZ01vZGUuSEFMRl9VUCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtYmVyIG9mIGRpZ2l0cyB0byBiZSB1c2VkIGZvciBhbiBvcGVyYXRpb247IHJlc3VsdHMgYXJlIHJvdW5kZWQgdG8KKyAgICAgKiB0aGlzIHByZWNpc2lvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBwcmVjaXNpb247CisKKyAgICAvKioKKyAgICAgKiBBIHtAY29kZSBSb3VuZGluZ01vZGV9IG9iamVjdCB3aGljaCBzcGVjaWZpZXMgdGhlIGFsZ29yaXRobSB0byBiZSB1c2VkCisgICAgICogZm9yIHJvdW5kaW5nLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgUm91bmRpbmdNb2RlIHJvdW5kaW5nTW9kZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIE1hdGhDb250ZXh0fSB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlY2lzaW9uIGFuZAorICAgICAqIHdpdGggdGhlIHJvdW5kaW5nIG1vZGUge0BsaW5rIFJvdW5kaW5nTW9kZSNIQUxGX1VQIEhBTEZfVVB9LiBJZiB0aGUKKyAgICAgKiBwcmVjaXNpb24gcGFzc2VkIGlzIHplcm8sIHRoZW4gdGhpcyBpbXBsaWVzIHRoYXQgdGhlIGNvbXB1dGF0aW9ucyBoYXZlIHRvCisgICAgICogYmUgcGVyZm9ybWVkIGV4YWN0LCB0aGUgcm91bmRpbmcgbW9kZSBpbiB0aGlzIGNhc2UgaXMgaXJyZWxldmFudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcmVjaXNpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmVjaXNpb24gZm9yIHRoZSBuZXcge0Bjb2RlIE1hdGhDb250ZXh0fS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBwcmVjaXNpb24gPCAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWF0aENvbnRleHQoaW50IHByZWNpc2lvbikgeworICAgICAgICB0aGlzKHByZWNpc2lvbiwgUm91bmRpbmdNb2RlLkhBTEZfVVApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIE1hdGhDb250ZXh0fSB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlY2lzaW9uIGFuZAorICAgICAqIHdpdGggdGhlIHNwZWNpZmllZCByb3VuZGluZyBtb2RlLiBJZiB0aGUgcHJlY2lzaW9uIHBhc3NlZCBpcyB6ZXJvLCB0aGVuCisgICAgICogdGhpcyBpbXBsaWVzIHRoYXQgdGhlIGNvbXB1dGF0aW9ucyBoYXZlIHRvIGJlIHBlcmZvcm1lZCBleGFjdCwgdGhlCisgICAgICogcm91bmRpbmcgbW9kZSBpbiB0aGlzIGNhc2UgaXMgaXJyZWxldmFudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcmVjaXNpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmVjaXNpb24gZm9yIHRoZSBuZXcge0Bjb2RlIE1hdGhDb250ZXh0fS4KKyAgICAgKiBAcGFyYW0gcm91bmRpbmdNb2RlCisgICAgICogICAgICAgICAgICB0aGUgcm91bmRpbmcgbW9kZSBmb3IgdGhlIG5ldyB7QGNvZGUgTWF0aENvbnRleHR9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHByZWNpc2lvbiA8IDB9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcm91bmRpbmdNb2RlfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIE1hdGhDb250ZXh0KGludCBwcmVjaXNpb24sIFJvdW5kaW5nTW9kZSByb3VuZGluZ01vZGUpIHsKKyAgICAgICAgdGhpcy5wcmVjaXNpb24gPSBwcmVjaXNpb247CisgICAgICAgIHRoaXMucm91bmRpbmdNb2RlID0gcm91bmRpbmdNb2RlOworICAgICAgICBjaGVja1ZhbGlkKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTWF0aENvbnRleHR9IGZyb20gYSBzdHJpbmcuIFRoZSBzdHJpbmcgaGFzIHRvCisgICAgICogc3BlY2lmeSB0aGUgcHJlY2lzaW9uIGFuZCB0aGUgcm91bmRpbmcgbW9kZSB0byBiZSB1c2VkIGFuZCBoYXMgdG8gZm9sbG93CisgICAgICogdGhlIGZvbGxvd2luZyBzeW50YXg6ICJwcmVjaXNpb249Jmx0O3ByZWNpc2lvbiZndDsgcm91bmRpbmdNb2RlPSZsdDtyb3VuZGluZ01vZGUmZ3Q7IgorICAgICAqIFRoaXMgaXMgdGhlIHNhbWUgZm9ybSBhcyB0aGUgb25lIHJldHVybmVkIGJ5IHRoZSB7QGxpbmsgI3RvU3RyaW5nfQorICAgICAqIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHN0cmluZyBpcyBub3QgaW4gdGhlIGNvcnJlY3QgZm9ybWF0IG9yIGlmIHRoZQorICAgICAqICAgICAgICAgICAgIHByZWNpc2lvbiBzcGVjaWZpZWQgaXMgPCAwLgorICAgICAqLworICAgIHB1YmxpYyBNYXRoQ29udGV4dChTdHJpbmcgcykgeworICAgICAgICBpbnQgcHJlY2lzaW9uTGVuZ3RoID0gInByZWNpc2lvbj0iLmxlbmd0aCgpOworICAgICAgICBpbnQgcm91bmRpbmdNb2RlTGVuZ3RoID0gInJvdW5kaW5nTW9kZT0iLmxlbmd0aCgpOworCisgICAgICAgIGludCBzcGFjZUluZGV4OworICAgICAgICBpZiAoIXMuc3RhcnRzV2l0aCgicHJlY2lzaW9uPSIpIHx8IChzcGFjZUluZGV4ID0gcy5pbmRleE9mKCcgJywgcHJlY2lzaW9uTGVuZ3RoKSkgPT0gLTEpIHsKKyAgICAgICAgICAgIHRocm93IGludmFsaWRNYXRoQ29udGV4dCgiTWlzc2luZyBwcmVjaXNpb24iLCBzKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcHJlY2lzaW9uU3RyaW5nID0gcy5zdWJzdHJpbmcocHJlY2lzaW9uTGVuZ3RoLCBzcGFjZUluZGV4KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoaXMucHJlY2lzaW9uID0gSW50ZWdlci5wYXJzZUludChwcmVjaXNpb25TdHJpbmcpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gbmZlKSB7CisgICAgICAgICAgICB0aHJvdyBpbnZhbGlkTWF0aENvbnRleHQoIkJhZCBwcmVjaXNpb24iLCBzKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCByb3VuZGluZ01vZGVTdGFydCA9IHNwYWNlSW5kZXggKyAxOworICAgICAgICBpZiAoIXMucmVnaW9uTWF0Y2hlcyhyb3VuZGluZ01vZGVTdGFydCwgInJvdW5kaW5nTW9kZT0iLCAwLCByb3VuZGluZ01vZGVMZW5ndGgpKSB7CisgICAgICAgICAgICB0aHJvdyBpbnZhbGlkTWF0aENvbnRleHQoIk1pc3Npbmcgcm91bmRpbmcgbW9kZSIsIHMpOworICAgICAgICB9CisgICAgICAgIHJvdW5kaW5nTW9kZVN0YXJ0ICs9IHJvdW5kaW5nTW9kZUxlbmd0aDsKKyAgICAgICAgdGhpcy5yb3VuZGluZ01vZGUgPSBSb3VuZGluZ01vZGUudmFsdWVPZihzLnN1YnN0cmluZyhyb3VuZGluZ01vZGVTdGFydCkpOworCisgICAgICAgIGNoZWNrVmFsaWQoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpbnZhbGlkTWF0aENvbnRleHQoU3RyaW5nIHJlYXNvbiwgU3RyaW5nIHMpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihyZWFzb24gKyAiOiAiICsgcyk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrVmFsaWQoKSB7CisgICAgICAgIGlmIChwcmVjaXNpb24gPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJOZWdhdGl2ZSBwcmVjaXNpb246ICIgKyBwcmVjaXNpb24pOworICAgICAgICB9CisgICAgICAgIGlmIChyb3VuZGluZ01vZGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJyb3VuZGluZ01vZGUgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJlY2lzaW9uLiBUaGUgcHJlY2lzaW9uIGlzIHRoZSBudW1iZXIgb2YgZGlnaXRzIHVzZWQgZm9yIGFuCisgICAgICogb3BlcmF0aW9uLiBSZXN1bHRzIGFyZSByb3VuZGVkIHRvIHRoaXMgcHJlY2lzaW9uLiBUaGUgcHJlY2lzaW9uIGlzCisgICAgICogZ3VhcmFudGVlZCB0byBiZSBub24gbmVnYXRpdmUuIElmIHRoZSBwcmVjaXNpb24gaXMgemVybywgdGhlbiB0aGUKKyAgICAgKiBjb21wdXRhdGlvbnMgaGF2ZSB0byBiZSBwZXJmb3JtZWQgZXhhY3QsIHJlc3VsdHMgYXJlIG5vdCByb3VuZGVkIGluIHRoaXMKKyAgICAgKiBjYXNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJlY2lzaW9uLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UHJlY2lzaW9uKCkgeworICAgICAgICByZXR1cm4gcHJlY2lzaW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHJvdW5kaW5nIG1vZGUuIFRoZSByb3VuZGluZyBtb2RlIGlzIHRoZSBzdHJhdGVneSB0byBiZSB1c2VkCisgICAgICogdG8gcm91bmQgcmVzdWx0cy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcm91bmRpbmcgbW9kZSBpcyBvbmUgb2YKKyAgICAgKiB7QGxpbmsgUm91bmRpbmdNb2RlI1VQfSwKKyAgICAgKiB7QGxpbmsgUm91bmRpbmdNb2RlI0RPV059LAorICAgICAqIHtAbGluayBSb3VuZGluZ01vZGUjQ0VJTElOR30sCisgICAgICoge0BsaW5rIFJvdW5kaW5nTW9kZSNGTE9PUn0sCisgICAgICoge0BsaW5rIFJvdW5kaW5nTW9kZSNIQUxGX1VQfSwKKyAgICAgKiB7QGxpbmsgUm91bmRpbmdNb2RlI0hBTEZfRE9XTn0sCisgICAgICoge0BsaW5rIFJvdW5kaW5nTW9kZSNIQUxGX0VWRU59LCBvcgorICAgICAqIHtAbGluayBSb3VuZGluZ01vZGUjVU5ORUNFU1NBUll9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcm91bmRpbmcgbW9kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUm91bmRpbmdNb2RlIGdldFJvdW5kaW5nTW9kZSgpIHsKKyAgICAgICAgcmV0dXJuIHJvdW5kaW5nTW9kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgeCBpcyBhIHtAY29kZSBNYXRoQ29udGV4dH0gd2l0aCB0aGUgc2FtZSBwcmVjaXNpb24KKyAgICAgKiBzZXR0aW5nIGFuZCB0aGUgc2FtZSByb3VuZGluZyBtb2RlIGFzIHRoaXMge0Bjb2RlIE1hdGhDb250ZXh0fSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICBvYmplY3QgdG8gYmUgY29tcGFyZWQuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgTWF0aENvbnRleHR9IGluc3RhbmNlIGlzIGVxdWFsIHRvIHRoZQorICAgICAqICAgICAgICAge0Bjb2RlIHh9IGFyZ3VtZW50OyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHgpIHsKKyAgICAgICAgcmV0dXJuICgoeCBpbnN0YW5jZW9mIE1hdGhDb250ZXh0KQorICAgICAgICAgICAgICAgICYmICgoKE1hdGhDb250ZXh0KSB4KS5nZXRQcmVjaXNpb24oKSA9PSBwcmVjaXNpb24pICYmICgoKE1hdGhDb250ZXh0KSB4KQorICAgICAgICAgICAgICAgIC5nZXRSb3VuZGluZ01vZGUoKSA9PSByb3VuZGluZ01vZGUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgZm9yIHRoaXMge0Bjb2RlIE1hdGhDb250ZXh0fSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZSBmb3IgdGhpcyB7QGNvZGUgTWF0aENvbnRleHR9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIC8vIE1ha2UgcGxhY2UgZm9yIHRoZSBuZWNlc3NhcnkgYml0cyB0byByZXByZXNlbnQgOCByb3VuZGluZyBtb2RlcworICAgICAgICByZXR1cm4gKChwcmVjaXNpb24gPDwgMykgfCByb3VuZGluZ01vZGUub3JkaW5hbCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gZm9yIHRoaXMge0Bjb2RlIE1hdGhDb250ZXh0fSBpbnN0YW5jZS4KKyAgICAgKiBUaGUgc3RyaW5nIGhhcyB0aGUgZm9ybQorICAgICAqIHtAY29kZQorICAgICAqICJwcmVjaXNpb249PHByZWNpc2lvbj4gcm91bmRpbmdNb2RlPTxyb3VuZGluZ01vZGU+IgorICAgICAqIH0gd2hlcmUge0Bjb2RlIDxwcmVjaXNpb24+fSBpcyBhbiBpbnRlZ2VyIGRlc2NyaWJpbmcgdGhlIG51bWJlcgorICAgICAqIG9mIGRpZ2l0cyB1c2VkIGZvciBvcGVyYXRpb25zIGFuZCB7QGNvZGUgPHJvdW5kaW5nTW9kZT59IGlzIHRoZQorICAgICAqIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcm91bmRpbmcgbW9kZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gZm9yIHRoaXMge0Bjb2RlIE1hdGhDb250ZXh0fSBpbnN0YW5jZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiAicHJlY2lzaW9uPSIgKyBwcmVjaXNpb24gKyAiIHJvdW5kaW5nTW9kZT0iICsgcm91bmRpbmdNb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1ha2VzIGNoZWNrcyB1cG9uIGRlc2VyaWFsaXphdGlvbiBvZiBhIHtAY29kZSBNYXRoQ29udGV4dH0gaW5zdGFuY2UuCisgICAgICogQ2hlY2tzIHdoZXRoZXIge0Bjb2RlIHByZWNpc2lvbiA+PSAwfSBhbmQge0Bjb2RlIHJvdW5kaW5nTW9kZSAhPSBudWxsfQorICAgICAqCisgICAgICogQHRocm93cyBTdHJlYW1Db3JydXB0ZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcHJlY2lzaW9uIDwgMH0KKyAgICAgKiBAdGhyb3dzIFN0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSByb3VuZGluZ01vZGUgPT0gbnVsbH0KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBzKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBzLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGVja1ZhbGlkKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbihleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbWF0aC9NdWx0aXBsaWNhdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbWF0aC9NdWx0aXBsaWNhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk4Y2FiZWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9tYXRoL011bHRpcGxpY2F0aW9uLmphdmEKQEAgLTAsMCArMSwxOTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5tYXRoOworCisvKioKKyAqIFN0YXRpYyBsaWJyYXJ5IHRoYXQgcHJvdmlkZXMgYWxsIG11bHRpcGxpY2F0aW9uIG9mIHtAbGluayBCaWdJbnRlZ2VyfSBtZXRob2RzLgorICovCitjbGFzcyBNdWx0aXBsaWNhdGlvbiB7CisKKyAgICAvKiogSnVzdCB0byBkZW5vdGUgdGhhdCB0aGlzIGNsYXNzIGNhbid0IGJlIGluc3RhbnRpYXRlZC4gKi8KKyAgICBwcml2YXRlIE11bHRpcGxpY2F0aW9uKCkge30KKworICAgIC8vIEJFR0lOIGFuZHJvaWQtcmVtb3ZlZAorICAgIC8vIC8qKgorICAgIC8vICAqIEJyZWFrIHBvaW50IGluIGRpZ2l0cyAobnVtYmVyIG9mIHtAY29kZSBpbnR9IGVsZW1lbnRzKQorICAgIC8vICAqIGJldHdlZW4gS2FyYXRzdWJhIGFuZCBQZW5jaWwgYW5kIFBhcGVyIG11bHRpcGx5LgorICAgIC8vICAqLworICAgIC8vIHN0YXRpYyBmaW5hbCBpbnQgd2hlblVzZUthcmF0c3ViYSA9IDYzOyAvLyBhbiBoZXVyaXN0aWMgdmFsdWUKKyAgICAvLyBFTkQgYW5kcm9pZC1yZW1vdmVkCisKKyAgICAvKioKKyAgICAgKiBBbiBhcnJheSB3aXRoIHBvd2VycyBvZiB0ZW4gdGhhdCBmaXQgaW4gdGhlIHR5cGUge0Bjb2RlIGludH0uCisgICAgICogKHtAY29kZSAxMF4wLDEwXjEsLi4uLDEwXjl9KQorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBpbnRbXSB0ZW5Qb3dzID0geworICAgICAgICAxLCAxMCwgMTAwLCAxMDAwLCAxMDAwMCwgMTAwMDAwLCAxMDAwMDAwLCAxMDAwMDAwMCwgMTAwMDAwMDAwLCAxMDAwMDAwMDAwCisgICAgfTsKKworICAgIC8qKgorICAgICAqIEFuIGFycmF5IHdpdGggcG93ZXJzIG9mIGZpdmUgdGhhdCBmaXQgaW4gdGhlIHR5cGUge0Bjb2RlIGludH0uCisgICAgICogKHtAY29kZSA1XjAsNV4xLC4uLiw1XjEzfSkKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgaW50W10gZml2ZVBvd3MgPSB7CisgICAgICAgIDEsIDUsIDI1LCAxMjUsIDYyNSwgMzEyNSwgMTU2MjUsIDc4MTI1LCAzOTA2MjUsCisgICAgICAgIDE5NTMxMjUsIDk3NjU2MjUsIDQ4ODI4MTI1LCAyNDQxNDA2MjUsIDEyMjA3MDMxMjUKKyAgICB9OworCisgICAgLyoqCisgICAgICogQW4gYXJyYXkgd2l0aCB0aGUgZmlyc3QgcG93ZXJzIG9mIHRlbiBpbiB7QGNvZGUgQmlnSW50ZWdlcn0gdmVyc2lvbi4KKyAgICAgKiAoe0Bjb2RlIDEwXjAsMTBeMSwuLi4sMTBeMzF9KQorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBCaWdJbnRlZ2VyW10gYmlnVGVuUG93cyA9IG5ldyBCaWdJbnRlZ2VyWzMyXTsKKworICAgIC8qKgorICAgICAqIEFuIGFycmF5IHdpdGggdGhlIGZpcnN0IHBvd2VycyBvZiBmaXZlIGluIHtAY29kZSBCaWdJbnRlZ2VyfSB2ZXJzaW9uLgorICAgICAqICh7QGNvZGUgNV4wLDVeMSwuLi4sNV4zMX0pCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIEJpZ0ludGVnZXIgYmlnRml2ZVBvd3NbXSA9IG5ldyBCaWdJbnRlZ2VyWzMyXTsKKworCisKKyAgICBzdGF0aWMgeworICAgICAgICBpbnQgaTsKKyAgICAgICAgbG9uZyBmaXZlUG93ID0gMUw7CisKKyAgICAgICAgZm9yIChpID0gMDsgaSA8PSAxODsgaSsrKSB7CisgICAgICAgICAgICBiaWdGaXZlUG93c1tpXSA9IEJpZ0ludGVnZXIudmFsdWVPZihmaXZlUG93KTsKKyAgICAgICAgICAgIGJpZ1RlblBvd3NbaV0gPSBCaWdJbnRlZ2VyLnZhbHVlT2YoZml2ZVBvdyA8PCBpKTsKKyAgICAgICAgICAgIGZpdmVQb3cgKj0gNTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKDsgaSA8IGJpZ1RlblBvd3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGJpZ0ZpdmVQb3dzW2ldID0gYmlnRml2ZVBvd3NbaSAtIDFdLm11bHRpcGx5KGJpZ0ZpdmVQb3dzWzFdKTsKKyAgICAgICAgICAgIGJpZ1RlblBvd3NbaV0gPSBiaWdUZW5Qb3dzW2kgLSAxXS5tdWx0aXBseShCaWdJbnRlZ2VyLlRFTik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBCRUdJTiBhbmRyb2lkLW5vdGU6IG11bHRpcGx5IGhhcyBiZWVuIHJlbW92ZWQgaW4gZmF2b3Igb2YgdXNpbmcgT3BlblNTTCBCSUdOVU0KKyAgICAvLyBFTkQgYW5kcm9pZC1ub3RlCisKKyAgICAvKioKKyAgICAgKiBNdWx0aXBsaWVzIGEgbnVtYmVyIGJ5IGEgcG9zaXRpdmUgaW50ZWdlci4KKyAgICAgKiBAcGFyYW0gdmFsIGFuIGFyYml0cmFyeSB7QGNvZGUgQmlnSW50ZWdlcn0KKyAgICAgKiBAcGFyYW0gZmFjdG9yIGEgcG9zaXRpdmUge0Bjb2RlIGludH0gbnVtYmVyCisgICAgICogQHJldHVybiB7QGNvZGUgdmFsICogZmFjdG9yfQorICAgICAqLworICAgIHN0YXRpYyBCaWdJbnRlZ2VyIG11bHRpcGx5QnlQb3NpdGl2ZUludChCaWdJbnRlZ2VyIHZhbCwgaW50IGZhY3RvcikgeworICAgICAgICBCaWdJbnQgYmkgPSB2YWwuZ2V0QmlnSW50KCkuY29weSgpOworICAgICAgICBiaS5tdWx0aXBseUJ5UG9zaXRpdmVJbnQoZmFjdG9yKTsKKyAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKGJpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNdWx0aXBsaWVzIGEgbnVtYmVyIGJ5IGEgcG93ZXIgb2YgdGVuLgorICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW4ge0Bjb2RlIEJpZ0RlY2ltYWx9IGNsYXNzLgorICAgICAqIEBwYXJhbSB2YWwgdGhlIG51bWJlciB0byBiZSBtdWx0aXBsaWVkCisgICAgICogQHBhcmFtIGV4cCBhIHBvc2l0aXZlIHtAY29kZSBsb25nfSBleHBvbmVudAorICAgICAqIEByZXR1cm4ge0Bjb2RlIHZhbCAqIDEwPHN1cD5leHA8L3N1cD59CisgICAgICovCisgICAgc3RhdGljIEJpZ0ludGVnZXIgbXVsdGlwbHlCeVRlblBvdyhCaWdJbnRlZ2VyIHZhbCwgbG9uZyBleHApIHsKKyAgICAgICAgLy8gUFJFOiBleHAgPj0gMAorICAgICAgICByZXR1cm4gKChleHAgPCB0ZW5Qb3dzLmxlbmd0aCkKKyAgICAgICAgPyBtdWx0aXBseUJ5UG9zaXRpdmVJbnQodmFsLCB0ZW5Qb3dzWyhpbnQpZXhwXSkKKyAgICAgICAgOiB2YWwubXVsdGlwbHkocG93ZXJPZjEwKGV4cCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJdCBjYWxjdWxhdGVzIGEgcG93ZXIgb2YgdGVuLCB3aGljaCBleHBvbmVudCBjb3VsZCBiZSBvdXQgb2YgMzItYml0IHJhbmdlLgorICAgICAqIE5vdGUgdGhhdCBpbnRlcm5hbGx5IHRoaXMgbWV0aG9kIHdpbGwgYmUgdXNlZCBpbiB0aGUgd29yc3QgY2FzZSB3aXRoCisgICAgICogYW4gZXhwb25lbnQgZXF1YWxzIHRvOiB7QGNvZGUgSW50ZWdlci5NQVhfVkFMVUUgLSBJbnRlZ2VyLk1JTl9WQUxVRX0uCisgICAgICogQHBhcmFtIGV4cCB0aGUgZXhwb25lbnQgb2YgcG93ZXIgb2YgdGVuLCBpdCBtdXN0IGJlIHBvc2l0aXZlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgQmlnSW50ZWdlcn0gd2l0aCB2YWx1ZSB7QGNvZGUgMTA8c3VwPmV4cDwvc3VwPn0uCisgICAgICovCisgICAgc3RhdGljIEJpZ0ludGVnZXIgcG93ZXJPZjEwKGxvbmcgZXhwKSB7CisgICAgICAgIC8vIFBSRTogZXhwID49IDAKKyAgICAgICAgaW50IGludEV4cCA9IChpbnQpZXhwOworICAgICAgICAvLyAiU01BTEwgUE9XRVJTIgorICAgICAgICBpZiAoZXhwIDwgYmlnVGVuUG93cy5sZW5ndGgpIHsKKyAgICAgICAgICAgIC8vIFRoZSBsYXJnZXN0IHBvd2VyIHRoYXQgZml0IGluICdsb25nJyB0eXBlCisgICAgICAgICAgICByZXR1cm4gYmlnVGVuUG93c1tpbnRFeHBdOworICAgICAgICB9IGVsc2UgaWYgKGV4cCA8PSA1MCkgeworICAgICAgICAgICAgLy8gVG8gY2FsY3VsYXRlOiAgICAxMF5leHAKKyAgICAgICAgICAgIHJldHVybiBCaWdJbnRlZ2VyLlRFTi5wb3coaW50RXhwKTsKKyAgICAgICAgfSBlbHNlIGlmIChleHAgPD0gMTAwMCkgeworICAgICAgICAgICAgLy8gVG8gY2FsY3VsYXRlOiAgICA1XmV4cCAqIDJeZXhwCisgICAgICAgICAgICByZXR1cm4gYmlnRml2ZVBvd3NbMV0ucG93KGludEV4cCkuc2hpZnRMZWZ0KGludEV4cCk7CisgICAgICAgIH0KKyAgICAgICAgLy8gIkxBUkdFIFBPV0VSUyIKKyAgICAgICAgLyoKKyAgICAgICAgICogVG8gY2hlY2sgaWYgdGhlcmUgaXMgZnJlZSBtZW1vcnkgdG8gYWxsb2NhdGUgYSBCaWdJbnRlZ2VyIG9mIHRoZQorICAgICAgICAgKiBlc3RpbWF0ZWQgc2l6ZSwgbWVhc3VyZWQgaW4gYnl0ZXM6IDEgKyBbZXhwIC8gbG9nMTAoMildCisgICAgICAgICAqLworICAgICAgICBsb25nIGJ5dGVBcnJheVNpemUgPSAxICsgKGxvbmcpKGV4cCAvIDIuNDA4MjM5OTY1MzExODQ5Nik7CisKKyAgICAgICAgaWYgKGJ5dGVBcnJheVNpemUgPiBSdW50aW1lLmdldFJ1bnRpbWUoKS5mcmVlTWVtb3J5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBcml0aG1ldGljRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGV4cCA8PSBJbnRlZ2VyLk1BWF9WQUxVRSkgeworICAgICAgICAgICAgLy8gVG8gY2FsY3VsYXRlOiAgICA1XmV4cCAqIDJeZXhwCisgICAgICAgICAgICByZXR1cm4gYmlnRml2ZVBvd3NbMV0ucG93KGludEV4cCkuc2hpZnRMZWZ0KGludEV4cCk7CisgICAgICAgIH0KKyAgICAgICAgLyoKKyAgICAgICAgICogIkhVR0UgUE9XRVJTIgorICAgICAgICAgKgorICAgICAgICAgKiBUaGlzIGJyYW5jaCBwcm9iYWJseSB3b24ndCBiZSBleGVjdXRlZCBzaW5jZSB0aGUgcG93ZXIgb2YgdGVuIGlzIHRvbworICAgICAgICAgKiBiaWcuCisgICAgICAgICAqLworICAgICAgICAvLyBUbyBjYWxjdWxhdGU6ICAgIDVeZXhwCisgICAgICAgIEJpZ0ludGVnZXIgcG93ZXJPZkZpdmUgPSBiaWdGaXZlUG93c1sxXS5wb3coSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICBCaWdJbnRlZ2VyIHJlcyA9IHBvd2VyT2ZGaXZlOworICAgICAgICBsb25nIGxvbmdFeHAgPSBleHAgLSBJbnRlZ2VyLk1BWF9WQUxVRTsKKworICAgICAgICBpbnRFeHAgPSAoaW50KShleHAgJSBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIHdoaWxlIChsb25nRXhwID4gSW50ZWdlci5NQVhfVkFMVUUpIHsKKyAgICAgICAgICAgIHJlcyA9IHJlcy5tdWx0aXBseShwb3dlck9mRml2ZSk7CisgICAgICAgICAgICBsb25nRXhwIC09IEludGVnZXIuTUFYX1ZBTFVFOworICAgICAgICB9CisgICAgICAgIHJlcyA9IHJlcy5tdWx0aXBseShiaWdGaXZlUG93c1sxXS5wb3coaW50RXhwKSk7CisgICAgICAgIC8vIFRvIGNhbGN1bGF0ZTogICAgNV5leHAgPDwgZXhwCisgICAgICAgIHJlcyA9IHJlcy5zaGlmdExlZnQoSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICBsb25nRXhwID0gZXhwIC0gSW50ZWdlci5NQVhfVkFMVUU7CisgICAgICAgIHdoaWxlIChsb25nRXhwID4gSW50ZWdlci5NQVhfVkFMVUUpIHsKKyAgICAgICAgICAgIHJlcyA9IHJlcy5zaGlmdExlZnQoSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICAgICAgbG9uZ0V4cCAtPSBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgICAgICAgfQorICAgICAgICByZXMgPSByZXMuc2hpZnRMZWZ0KGludEV4cCk7CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogTXVsdGlwbGllcyBhIG51bWJlciBieSBhIHBvd2VyIG9mIGZpdmUuCisgICAgICogVGhpcyBtZXRob2QgaXMgdXNlZCBpbiB7QGNvZGUgQmlnRGVjaW1hbH0gY2xhc3MuCisgICAgICogQHBhcmFtIHZhbCB0aGUgbnVtYmVyIHRvIGJlIG11bHRpcGxpZWQKKyAgICAgKiBAcGFyYW0gZXhwIGEgcG9zaXRpdmUge0Bjb2RlIGludH0gZXhwb25lbnQKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB2YWwgKiA1PHN1cD5leHA8L3N1cD59CisgICAgICovCisgICAgc3RhdGljIEJpZ0ludGVnZXIgbXVsdGlwbHlCeUZpdmVQb3coQmlnSW50ZWdlciB2YWwsIGludCBleHApIHsKKyAgICAgICAgLy8gUFJFOiBleHAgPj0gMAorICAgICAgICBpZiAoZXhwIDwgZml2ZVBvd3MubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gbXVsdGlwbHlCeVBvc2l0aXZlSW50KHZhbCwgZml2ZVBvd3NbZXhwXSk7CisgICAgICAgIH0gZWxzZSBpZiAoZXhwIDwgYmlnRml2ZVBvd3MubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsLm11bHRpcGx5KGJpZ0ZpdmVQb3dzW2V4cF0pOworICAgICAgICB9IGVsc2Ugey8vIExhcmdlIHBvd2VycyBvZiBmaXZlCisgICAgICAgICAgICByZXR1cm4gdmFsLm11bHRpcGx5KGJpZ0ZpdmVQb3dzWzFdLnBvdyhleHApKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL21hdGgvTmF0aXZlQk4uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL21hdGgvTmF0aXZlQk4uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NWJiMmEyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbWF0aC9OYXRpdmVCTi5qYXZhCkBAIC0wLDAgKzEsMTY1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm1hdGg7CisKK2ZpbmFsIGNsYXNzIE5hdGl2ZUJOIHsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBFUlJfZ2V0X2Vycm9yKCk7CisgICAgLy8gdW5zaWduZWQgbG9uZyBFUlJfZ2V0X2Vycm9yKHZvaWQpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgU3RyaW5nIEVSUl9lcnJvcl9zdHJpbmcoaW50IGUpOworICAgIC8vIGNoYXIgKkVSUl9lcnJvcl9zdHJpbmcodW5zaWduZWQgbG9uZyBlLCBjaGFyICpidWYpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEJOX25ldygpOworICAgIC8vIEJJR05VTSAqQk5fbmV3KHZvaWQpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBCTl9mcmVlKGludCBhKTsKKyAgICAvLyB2b2lkIEJOX2ZyZWUoQklHTlVNICphKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBCTl9jbXAoaW50IGEsIGludCBiKTsKKyAgICAvLyBpbnQgQk5fY21wKGNvbnN0IEJJR05VTSAqYSwgY29uc3QgQklHTlVNICpiKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gQk5fY29weShpbnQgdG8sIGludCBmcm9tKTsKKyAgICAvLyBSZXR1cm5zIGJvb2xlYW4gc3VjY2VzcyBBTkQgTk9UIHJlc3VsdCBCSUdOVU0gaGFuZGxlIQorICAgIC8vIEJJR05VTSAqQk5fY29weShCSUdOVU0gKnRvLCBjb25zdCBCSUdOVU0gKmZyb20pOworLy8gICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEJOX2R1cChpbnQgZnJvbSk7CisgICAgLy8gQklHTlVNICpCTl9kdXAoY29uc3QgQklHTlVNICphKTsKKworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBwdXRMb25nSW50KGludCBhLCBsb25nIGR3KTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gcHV0VUxvbmdJbnQoaW50IGEsIGxvbmcgZHcsIGJvb2xlYW4gbmVnKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBCTl9kZWMyYm4oaW50IGEsIFN0cmluZyBzdHIpOworICAgIC8vIGludCBCTl9kZWMyYm4oQklHTlVNICoqYSwgY29uc3QgY2hhciAqc3RyKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBCTl9oZXgyYm4oaW50IGEsIFN0cmluZyBzdHIpOworICAgIC8vIGludCBCTl9oZXgyYm4oQklHTlVNICoqYSwgY29uc3QgY2hhciAqc3RyKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gQk5fYmluMmJuKGJ5dGVbXSBzLCBpbnQgbGVuLCBib29sZWFuIG5lZywgaW50IHJldCk7CisgICAgLy8gUmV0dXJucyBib29sZWFuIHN1Y2Nlc3MgQU5EIE5PVCByZXN1bHQgQklHTlVNIGhhbmRsZSEKKyAgICAvLyBCSUdOVU0gKiBCTl9iaW4yYm4oY29uc3QgdW5zaWduZWQgY2hhciAqcywgaW50IGxlbiwgQklHTlVNICpyZXQpOworICAgIC8vIEJOLURvY3U6IHMgaXMgdGFrZW4gYXMgdW5zaWduZWQgYmlnIGVuZGlhbjsKKyAgICAvLyBBZGRpdGlvbmFsIHBhcmFtZXRlcjogbmVnLgorCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBsaXRFbmRJbnRzMmJuKGludFtdIGludHMsIGludCBsZW4sIGJvb2xlYW4gbmVnLCBpbnQgcmV0KTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gdHdvc0NvbXAyYm4oYnl0ZVtdIHMsIGludCBsZW4sIGludCByZXQpOworCisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBsb25nIGxvbmdJbnQoaW50IGEpOworICAgIC8vIHVuc2lnbmVkIGxvbmcgQk5fZ2V0X3dvcmQoQklHTlVNICphKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIFN0cmluZyBCTl9ibjJkZWMoaW50IGEpOworICAgIC8vIGNoYXIgKiBCTl9ibjJkZWMoY29uc3QgQklHTlVNICphKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIFN0cmluZyBCTl9ibjJoZXgoaW50IGEpOworICAgIC8vIGNoYXIgKiBCTl9ibjJoZXgoY29uc3QgQklHTlVNICphKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJ5dGVbXSBCTl9ibjJiaW4oaW50IGEpOworICAgIC8vIFJldHVybnMgcmVzdWx0IGJ5dGVbXSBBTkQgTk9UIGxlbmd0aC4KKyAgICAvLyBpbnQgQk5fYm4yYmluKGNvbnN0IEJJR05VTSAqYSwgdW5zaWduZWQgY2hhciAqdG8pOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50W10gYm4ybGl0RW5kSW50cyhpbnQgYSk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgc2lnbihpbnQgYSk7CisgICAgLy8gUmV0dXJucyAtMSwgMCwgMSBBTkQgTk9UIGJvb2xlYW4uCisgICAgLy8gI2RlZmluZSBCTl9pc19uZWdhdGl2ZShhKSAoKGEpLT5uZWcgIT0gMCkKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgQk5fc2V0X25lZ2F0aXZlKGludCBiLCBpbnQgbik7CisgICAgLy8gdm9pZCBCTl9zZXRfbmVnYXRpdmUoQklHTlVNICpiLCBpbnQgbik7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgYml0TGVuZ3RoKGludCBhKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gQk5faXNfYml0X3NldChpbnQgYSwgaW50IG4pOworICAgIC8vIGludCBCTl9pc19iaXRfc2V0KGNvbnN0IEJJR05VTSAqYSwgaW50IG4pOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBtb2RpZnlCaXQoaW50IGEsIGludCBuLCBpbnQgb3ApOworICAgIC8vIFJldHVybnMgYm9vbGVhbiBzdWNjZXNzLgorICAgIC8vIG9wOiAwID0gcmVzZXQ7IDEgPSBzZXQ7IC0xID0gZmxpcAorICAgIC8vIHVzZXMgQk5fc2V0X2JpdCgpLCBCTl9jbGVhcl9iaXQoKSBhbmQgQk5faXNfYml0X3NldCgpCisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIEJOX3NoaWZ0KGludCByLCBpbnQgYSwgaW50IG4pOworICAgIC8vIGludCBCTl9zaGlmdChCSUdOVU0gKnIsIGNvbnN0IEJJR05VTSAqYSwgaW50IG4pOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBCTl9hZGRfd29yZChpbnQgYSwgaW50IHcpOworICAgIC8vIEFUVEVOVElPTjogdyBpcyB0cmVhdGVkIGFzIHVuc2lnbmVkLgorICAgIC8vIGludCBCTl9hZGRfd29yZChCSUdOVU0gKmEsIEJOX1VMT05HIHcpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBCTl9zdWJfd29yZChpbnQgYSwgaW50IHcpOworICAgIC8vIEFUVEVOVElPTjogdyBpcyB0cmVhdGVkIGFzIHVuc2lnbmVkLgorICAgIC8vIGludCBCTl9zdWJfd29yZChCSUdOVU0gKmEsIEJOX1VMT05HIHcpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBCTl9tdWxfd29yZChpbnQgYSwgaW50IHcpOworICAgIC8vIEFUVEVOVElPTjogdyBpcyB0cmVhdGVkIGFzIHVuc2lnbmVkLgorICAgIC8vIGludCBCTl9tdWxfd29yZChCSUdOVU0gKmEsIEJOX1VMT05HIHcpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEJOX2Rpdl93b3JkKGludCBhLCBpbnQgdyk7CisgICAgLy8gQVRURU5USU9OOiB3IGlzIHRyZWF0ZWQgYXMgdW5zaWduZWQuCisgICAgLy8gQk5fVUxPTkcgQk5fZGl2X3dvcmQoQklHTlVNICphLCBCTl9VTE9ORyB3KTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBCTl9tb2Rfd29yZChpbnQgYSwgaW50IHcpOworICAgIC8vIEFUVEVOVElPTjogdyBpcyB0cmVhdGVkIGFzIHVuc2lnbmVkLgorICAgIC8vIEJOX1VMT05HIEJOX21vZF93b3JkKEJJR05VTSAqYSwgQk5fVUxPTkcgdyk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIEJOX2FkZChpbnQgciwgaW50IGEsIGludCBiKTsKKyAgICAvLyBpbnQgQk5fYWRkKEJJR05VTSAqciwgY29uc3QgQklHTlVNICphLCBjb25zdCBCSUdOVU0gKmIpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBCTl9zdWIoaW50IHIsIGludCBhLCBpbnQgYik7CisgICAgLy8gaW50IEJOX3N1YihCSUdOVU0gKnIsIGNvbnN0IEJJR05VTSAqYSwgY29uc3QgQklHTlVNICpiKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gQk5fZ2NkKGludCByLCBpbnQgYSwgaW50IGIpOworICAgIC8vIGludCBCTl9nY2QoQklHTlVNICpyLCBjb25zdCBCSUdOVU0gKmEsIGNvbnN0IEJJR05VTSAqYiwgQk5fQ1RYICpjdHgpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBCTl9tdWwoaW50IHIsIGludCBhLCBpbnQgYik7CisgICAgLy8gaW50IEJOX211bChCSUdOVU0gKnIsIGNvbnN0IEJJR05VTSAqYSwgY29uc3QgQklHTlVNICpiLCBCTl9DVFggKmN0eCk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIEJOX2V4cChpbnQgciwgaW50IGEsIGludCBwKTsKKyAgICAvLyBpbnQgQk5fZXhwKEJJR05VTSAqciwgY29uc3QgQklHTlVNICphLCBjb25zdCBCSUdOVU0gKnAsIEJOX0NUWCAqY3R4KTsKKworICAgIC8vIE9QVElPTkFMOgorLy8gICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEJOX3NxcihCaWdJbnRlZ2VyIHIsIEJpZ0ludGVnZXIgYSwgQk5fQ1RYIGN0eCk7CisgICAgLy8gaW50IEJOX3NxcihCSUdOVU0gKnIsIGNvbnN0IEJJR05VTSAqYSxCTl9DVFggKmN0eCk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIEJOX2RpdihpbnQgZHYsIGludCByZW0sIGludCBtLCBpbnQgZCk7CisgICAgLy8gaW50IEJOX2RpdihCSUdOVU0gKmR2LCBCSUdOVU0gKnJlbSwgY29uc3QgQklHTlVNICptLCBjb25zdCBCSUdOVU0gKmQsIEJOX0NUWCAqY3R4KTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gQk5fbm5tb2QoaW50IHIsIGludCBhLCBpbnQgbSk7CisgICAgLy8gaW50IEJOX25ubW9kKEJJR05VTSAqciwgY29uc3QgQklHTlVNICphLCBjb25zdCBCSUdOVU0gKm0sIEJOX0NUWCAqY3R4KTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gQk5fbW9kX2V4cChpbnQgciwgaW50IGEsIGludCBwLCBpbnQgbSk7CisgICAgLy8gaW50IEJOX21vZF9leHAoQklHTlVNICpyLCBjb25zdCBCSUdOVU0gKmEsIGNvbnN0IEJJR05VTSAqcCwgY29uc3QgQklHTlVNICptLCBCTl9DVFggKmN0eCk7CisKKyAgICAvLyBPUFRJT05BTDoKKy8vICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gQk5fbW9kX3NxcihCaWdJbnRlZ2VyIHIsIEJpZ0ludGVnZXIgYSwgQmlnSW50ZWdlciBtLCBCTl9DVFggY3R4KTsKKyAgICAvLyBpbnQgQk5fbW9kX3NxcihCSUdOVU0gKnIsIGNvbnN0IEJJR05VTSAqYSwgY29uc3QgQklHTlVNICptLCBCTl9DVFggKmN0eCk7CisKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gQk5fbW9kX2ludmVyc2UoaW50IHJldCwgaW50IGEsIGludCBuKTsKKyAgICAvLyBSZXR1cm5zIGJvb2xlYW4gc3VjY2VzcyBBTkQgTk9UIHJlc3VsdCBCSUdOVU0gaGFuZGxlIQorICAgIC8vIEJJR05VTSAqIEJOX21vZF9pbnZlcnNlKEJJR05VTSAqcmV0LCBjb25zdCBCSUdOVU0gKmEsIGNvbnN0IEJJR05VTSAqbiwgQk5fQ1RYICpjdHgpOworCisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIEJOX2dlbmVyYXRlX3ByaW1lX2V4KGludCByZXQsIGludCBiaXRzLCBib29sZWFuIHNhZmUsCisgICAgICAgICAgICBpbnQgYWRkLCBpbnQgcmVtLCBpbnQgY2IpOworICAgIC8vIGludCBCTl9nZW5lcmF0ZV9wcmltZV9leChCSUdOVU0gKnJldCwgaW50IGJpdHMsIGludCBzYWZlLAorICAgIC8vICAgICAgICAgY29uc3QgQklHTlVNICphZGQsIGNvbnN0IEJJR05VTSAqcmVtLCBCTl9HRU5DQiAqY2IpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBCTl9pc19wcmltZV9leChpbnQgcCwgaW50IG5jaGVja3MsIGludCBjYik7CisgICAgLy8gaW50IEJOX2lzX3ByaW1lX2V4KGNvbnN0IEJJR05VTSAqcCwgaW50IG5jaGVja3MsIEJOX0NUWCAqY3R4LCBCTl9HRU5DQiAqY2IpOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9tYXRoL1ByaW1hbGl0eS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbWF0aC9QcmltYWxpdHkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYWNjODkzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbWF0aC9QcmltYWxpdHkuamF2YQpAQCAtMCwwICsxLDE0NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm1hdGg7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIFByb3ZpZGVzIHByaW1hbGl0eSBwcm9iYWJpbGlzdGljIG1ldGhvZHMuCisgKi8KK2NsYXNzIFByaW1hbGl0eSB7CisKKyAgICAvKiogSnVzdCB0byBkZW5vdGUgdGhhdCB0aGlzIGNsYXNzIGNhbid0IGJlIGluc3RhbnRpYXRlZC4gKi8KKyAgICBwcml2YXRlIFByaW1hbGl0eSgpIHt9CisKKyAgICAvKiogQWxsIHByaW1lIG51bWJlcnMgd2l0aCBiaXQgbGVuZ3RoIGxlc3NlciB0aGFuIDEwIGJpdHMuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gcHJpbWVzID0geyAyLCAzLCA1LCA3LCAxMSwgMTMsIDE3LCAxOSwgMjMsIDI5LAorICAgICAgICAgICAgMzEsIDM3LCA0MSwgNDMsIDQ3LCA1MywgNTksIDYxLCA2NywgNzEsIDczLCA3OSwgODMsIDg5LCA5NywgMTAxLAorICAgICAgICAgICAgMTAzLCAxMDcsIDEwOSwgMTEzLCAxMjcsIDEzMSwgMTM3LCAxMzksIDE0OSwgMTUxLCAxNTcsIDE2MywgMTY3LAorICAgICAgICAgICAgMTczLCAxNzksIDE4MSwgMTkxLCAxOTMsIDE5NywgMTk5LCAyMTEsIDIyMywgMjI3LCAyMjksIDIzMywgMjM5LAorICAgICAgICAgICAgMjQxLCAyNTEsIDI1NywgMjYzLCAyNjksIDI3MSwgMjc3LCAyODEsIDI4MywgMjkzLCAzMDcsIDMxMSwgMzEzLAorICAgICAgICAgICAgMzE3LCAzMzEsIDMzNywgMzQ3LCAzNDksIDM1MywgMzU5LCAzNjcsIDM3MywgMzc5LCAzODMsIDM4OSwgMzk3LAorICAgICAgICAgICAgNDAxLCA0MDksIDQxOSwgNDIxLCA0MzEsIDQzMywgNDM5LCA0NDMsIDQ0OSwgNDU3LCA0NjEsIDQ2MywgNDY3LAorICAgICAgICAgICAgNDc5LCA0ODcsIDQ5MSwgNDk5LCA1MDMsIDUwOSwgNTIxLCA1MjMsIDU0MSwgNTQ3LCA1NTcsIDU2MywgNTY5LAorICAgICAgICAgICAgNTcxLCA1NzcsIDU4NywgNTkzLCA1OTksIDYwMSwgNjA3LCA2MTMsIDYxNywgNjE5LCA2MzEsIDY0MSwgNjQzLAorICAgICAgICAgICAgNjQ3LCA2NTMsIDY1OSwgNjYxLCA2NzMsIDY3NywgNjgzLCA2OTEsIDcwMSwgNzA5LCA3MTksIDcyNywgNzMzLAorICAgICAgICAgICAgNzM5LCA3NDMsIDc1MSwgNzU3LCA3NjEsIDc2OSwgNzczLCA3ODcsIDc5NywgODA5LCA4MTEsIDgyMSwgODIzLAorICAgICAgICAgICAgODI3LCA4MjksIDgzOSwgODUzLCA4NTcsIDg1OSwgODYzLCA4NzcsIDg4MSwgODgzLCA4ODcsIDkwNywgOTExLAorICAgICAgICAgICAgOTE5LCA5MjksIDkzNywgOTQxLCA5NDcsIDk1MywgOTY3LCA5NzEsIDk3NywgOTgzLCA5OTEsIDk5NywgMTAwOSwKKyAgICAgICAgICAgIDEwMTMsIDEwMTksIDEwMjEgfTsKKworICAgIC8qKiBBbGwge0Bjb2RlIEJpZ0ludGVnZXJ9IHByaW1lIG51bWJlcnMgd2l0aCBiaXQgbGVuZ3RoIGxlc3NlciB0aGFuIDEwIGJpdHMuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQmlnSW50ZWdlciBCSXByaW1lc1tdID0gbmV3IEJpZ0ludGVnZXJbcHJpbWVzLmxlbmd0aF07CisKKy8vICAgIC8qKgorLy8gICAgICogSXQgZW5jb2RlcyBob3cgbWFueSBpdGVyYXRpb25zIG9mIE1pbGxlci1SYWJpbiB0ZXN0IGFyZSBuZWVkIHRvIGdldCBhbgorLy8gICAgICogZXJyb3IgYm91bmQgbm90IGdyZWF0ZXIgdGhhbiB7QGNvZGUgMjxzdXA+KC0xMDApPC9zdXA+fS4gRm9yIGV4YW1wbGU6CisvLyAgICAgKiBmb3IgYSB7QGNvZGUgMTAwMH0tYml0IG51bWJlciB3ZSBuZWVkIHtAY29kZSA0fSBpdGVyYXRpb25zLCBzaW5jZQorLy8gICAgICoge0Bjb2RlIEJJVFNbM10gPCAxMDAwIDw9IEJJVFNbNF19LgorLy8gICAgICovCisvLyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnRbXSBCSVRTID0geyAwLCAwLCAxODU0LCAxMjMzLCA5MjcsIDc0NywgNjI3LCA1NDMsCisvLyAgICAgICAgICAgIDQ4MCwgNDMxLCAzOTMsIDM2MSwgMzM1LCAzMTQsIDI5NSwgMjc5LCAyNjUsIDI1MywgMjQyLCAyMzIsIDIyMywKKy8vICAgICAgICAgICAgMjE2LCAxODEsIDE2OSwgMTU4LCAxNTAsIDE0NSwgMTQwLCAxMzYsIDEzMiwgMTI3LCAxMjMsIDExOSwgMTE0LAorLy8gICAgICAgICAgICAxMTAsIDEwNSwgMTAxLCA5NiwgOTIsIDg3LCA4MywgNzgsIDczLCA2OSwgNjQsIDU5LCA1NCwgNDksIDQ0LCAzOCwKKy8vICAgICAgICAgICAgMzIsIDI2LCAxIH07CisvLworLy8gICAgLyoqCisvLyAgICAgKiBJdCBlbmNvZGVzIGhvdyBtYW55IGktYml0IHByaW1lcyB0aGVyZSBhcmUgaW4gdGhlIHRhYmxlIGZvcgorLy8gICAgICoge0Bjb2RlIGk9MiwuLi4sMTB9LiBGb3IgZXhhbXBsZSB7QGNvZGUgb2Zmc2V0UHJpbWVzWzZdfSBzYXlzIHRoYXQgZnJvbQorLy8gICAgICogaW5kZXgge0Bjb2RlIDExfSBleGlzdHMge0Bjb2RlIDd9IGNvbnNlY3V0aXZlIHtAY29kZSA2fS1iaXQgcHJpbWUKKy8vICAgICAqIG51bWJlcnMgaW4gdGhlIGFycmF5LgorLy8gICAgICovCisvLyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnRbXVtdIG9mZnNldFByaW1lcyA9IHsgbnVsbCwgbnVsbCwgeyAwLCAyIH0sCisvLyAgICAgICAgICAgIHsgMiwgMiB9LCB7IDQsIDIgfSwgeyA2LCA1IH0sIHsgMTEsIDcgfSwgeyAxOCwgMTMgfSwgeyAzMSwgMjMgfSwKKy8vICAgICAgICAgICAgeyA1NCwgNDMgfSwgeyA5NywgNzUgfSB9OworCisgICAgc3RhdGljIHsvLyBUbyBpbml0aWFsaXplIHRoZSBkdWFsIHRhYmxlIG9mIEJpZ0ludGVnZXIgcHJpbWVzCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJpbWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBCSXByaW1lc1tpXSA9IEJpZ0ludGVnZXIudmFsdWVPZihwcmltZXNbaV0pOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSXQgdXNlcyB0aGUgc2lldmUgb2YgRXJhdG9zdGhlbmVzIHRvIGRpc2NhcmQgc2V2ZXJhbCBjb21wb3NpdGUgbnVtYmVycyBpbgorICAgICAqIHNvbWUgYXBwcm9wcmlhdGUgcmFuZ2UgKGF0IHRoZSBtb21lbnQge0Bjb2RlIFt0aGlzLCB0aGlzICsgMTAyNF19KS4gQWZ0ZXIKKyAgICAgKiB0aGlzIHByb2Nlc3MgaXQgYXBwbGllcyB0aGUgTWlsbGVyLVJhYmluIHRlc3QgdG8gdGhlIG51bWJlcnMgdGhhdCB3ZXJlCisgICAgICogbm90IGRpc2NhcmRlZCBpbiB0aGUgc2lldmUuCisgICAgICoKKyAgICAgKiBAc2VlIEJpZ0ludGVnZXIjbmV4dFByb2JhYmxlUHJpbWUoKQorICAgICAqLworICAgIHN0YXRpYyBCaWdJbnRlZ2VyIG5leHRQcm9iYWJsZVByaW1lKEJpZ0ludGVnZXIgbikgeworICAgICAgICAvLyBQUkU6IG4gPj0gMAorICAgICAgICBpbnQgaSwgajsKKy8vICAgICAgICBpbnQgY2VydGFpbnR5OworICAgICAgICBpbnQgZ2FwU2l6ZSA9IDEwMjQ7IC8vIGZvciBzZWFyY2hpbmcgb2YgdGhlIG5leHQgcHJvYmFibGUgcHJpbWUgbnVtYmVyCisgICAgICAgIGludFtdIG1vZHVsZXMgPSBuZXcgaW50W3ByaW1lcy5sZW5ndGhdOworICAgICAgICBib29sZWFuIGlzRGl2aXNpYmxlW10gPSBuZXcgYm9vbGVhbltnYXBTaXplXTsKKyAgICAgICAgQmlnSW50IG5pID0gbi5nZXRCaWdJbnQoKTsKKyAgICAgICAgLy8gSWYgbiA8ICJsYXN0IHByaW1lIG9mIHRhYmxlIiBzZWFyY2hlcyBuZXh0IHByaW1lIGluIHRoZSB0YWJsZQorICAgICAgICBpZiAobmkuYml0TGVuZ3RoKCkgPD0gMTApIHsKKyAgICAgICAgICAgIGludCBsID0gKGludCluaS5sb25nSW50KCk7CisgICAgICAgICAgICBpZiAobCA8IHByaW1lc1twcmltZXMubGVuZ3RoIC0gMV0pIHsKKyAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBsID49IHByaW1lc1tpXTsgaSsrKSB7fQorICAgICAgICAgICAgICAgIHJldHVybiBCSXByaW1lc1tpXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEJpZ0ludCBzdGFydFBvaW50ID0gbmkuY29weSgpOworICAgICAgICBCaWdJbnQgcHJvYlByaW1lID0gbmV3IEJpZ0ludCgpOworCisgICAgICAgIC8vIEZpeCBzdGFydFBvaW50IHRvICJuZXh0IG9kZCBudW1iZXIiOgorICAgICAgICBzdGFydFBvaW50LmFkZFBvc2l0aXZlSW50KEJpZ0ludC5yZW1haW5kZXJCeVBvc2l0aXZlSW50KG5pLCAyKSArIDEpOworCisvLyAgICAgICAgLy8gVG8gc2V0IHRoZSBpbXByb3ZlZCBjZXJ0YWludHkgb2YgTWlsbGVyLVJhYmluCisvLyAgICAgICAgaiA9IHN0YXJ0UG9pbnQuYml0TGVuZ3RoKCk7CisvLyAgICAgICAgZm9yIChjZXJ0YWludHkgPSAyOyBqIDwgQklUU1tjZXJ0YWludHldOyBjZXJ0YWludHkrKykgeworLy8gICAgICAgICAgICA7CisvLyAgICAgICAgfQorCisgICAgICAgIC8vIFRvIGNhbGN1bGF0ZSBtb2R1bGVzOiBOIG1vZCBwMSwgTiBtb2QgcDIsIC4uLiBmb3IgZmlyc3QgcHJpbWVzLgorICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcHJpbWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBtb2R1bGVzW2ldID0gQmlnSW50LnJlbWFpbmRlckJ5UG9zaXRpdmVJbnQoc3RhcnRQb2ludCwgcHJpbWVzW2ldKSAtIGdhcFNpemU7CisgICAgICAgIH0KKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIC8vIEF0IHRoaXMgcG9pbnQsIGFsbCBudW1iZXJzIGluIHRoZSBnYXAgYXJlIGluaXRpYWxpemVkIGFzCisgICAgICAgICAgICAvLyBwcm9iYWJseSBwcmltZXMKKyAgICAgICAgICAgIEFycmF5cy5maWxsKGlzRGl2aXNpYmxlLCBmYWxzZSk7CisgICAgICAgICAgICAvLyBUbyBkaXNjYXJkIG11bHRpcGxlcyBvZiBmaXJzdCBwcmltZXMKKyAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBwcmltZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBtb2R1bGVzW2ldID0gKG1vZHVsZXNbaV0gKyBnYXBTaXplKSAlIHByaW1lc1tpXTsKKyAgICAgICAgICAgICAgICBqID0gKG1vZHVsZXNbaV0gPT0gMCkgPyAwIDogKHByaW1lc1tpXSAtIG1vZHVsZXNbaV0pOworICAgICAgICAgICAgICAgIGZvciAoOyBqIDwgZ2FwU2l6ZTsgaiArPSBwcmltZXNbaV0pIHsKKyAgICAgICAgICAgICAgICAgICAgaXNEaXZpc2libGVbal0gPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIFRvIGV4ZWN1dGUgTWlsbGVyLVJhYmluIGZvciBub24tZGl2aXNpYmxlIG51bWJlcnMgYnkgYWxsIGZpcnN0CisgICAgICAgICAgICAvLyBwcmltZXMKKyAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBnYXBTaXplOyBqKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoIWlzRGl2aXNpYmxlW2pdKSB7CisgICAgICAgICAgICAgICAgICAgIHByb2JQcmltZS5wdXRDb3B5KHN0YXJ0UG9pbnQpOworICAgICAgICAgICAgICAgICAgICBwcm9iUHJpbWUuYWRkUG9zaXRpdmVJbnQoaik7CisgICAgICAgICAgICAgICAgICAgIGlmIChwcm9iUHJpbWUuaXNQcmltZSgxMDApKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIocHJvYlByaW1lKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHN0YXJ0UG9pbnQuYWRkUG9zaXRpdmVJbnQoZ2FwU2l6ZSk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL21hdGgvUm91bmRpbmdNb2RlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9tYXRoL1JvdW5kaW5nTW9kZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY0YzE4MWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9tYXRoL1JvdW5kaW5nTW9kZS5qYXZhCkBAIC0wLDAgKzEsMTIyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubWF0aDsKKworLyoqCisgKiBTcGVjaWZpZXMgdGhlIHJvdW5kaW5nIGJlaGF2aW9yIGZvciBvcGVyYXRpb25zIHdob3NlIHJlc3VsdHMgY2Fubm90IGJlCisgKiByZXByZXNlbnRlZCBleGFjdGx5LgorICovCitwdWJsaWMgZW51bSBSb3VuZGluZ01vZGUgeworCisgICAgLyoqCisgICAgICogUm91bmRpbmcgbW9kZSB3aGVyZSBwb3NpdGl2ZSB2YWx1ZXMgYXJlIHJvdW5kZWQgdG93YXJkcyBwb3NpdGl2ZSBpbmZpbml0eQorICAgICAqIGFuZCBuZWdhdGl2ZSB2YWx1ZXMgdG93YXJkcyBuZWdhdGl2ZSBpbmZpbml0eS4KKyAgICAgKiA8YnI+CisgICAgICogUnVsZToge0Bjb2RlIHgucm91bmQoKS5hYnMoKSA+PSB4LmFicygpfQorICAgICAqLworICAgIFVQKEJpZ0RlY2ltYWwuUk9VTkRfVVApLAorCisgICAgLyoqCisgICAgICogUm91bmRpbmcgbW9kZSB3aGVyZSB0aGUgdmFsdWVzIGFyZSByb3VuZGVkIHRvd2FyZHMgemVyby4KKyAgICAgKiA8YnI+CisgICAgICogUnVsZToge0Bjb2RlIHgucm91bmQoKS5hYnMoKSA8PSB4LmFicygpfQorICAgICAqLworICAgIERPV04oQmlnRGVjaW1hbC5ST1VORF9ET1dOKSwKKworICAgIC8qKgorICAgICAqIFJvdW5kaW5nIG1vZGUgdG8gcm91bmQgdG93YXJkcyBwb3NpdGl2ZSBpbmZpbml0eS4gRm9yIHBvc2l0aXZlIHZhbHVlcworICAgICAqIHRoaXMgcm91bmRpbmcgbW9kZSBiZWhhdmVzIGFzIHtAbGluayAjVVB9LCBmb3IgbmVnYXRpdmUgdmFsdWVzIGFzCisgICAgICoge0BsaW5rICNET1dOfS4KKyAgICAgKiA8YnI+CisgICAgICogUnVsZToge0Bjb2RlIHgucm91bmQoKSA+PSB4fQorICAgICAqLworICAgIENFSUxJTkcoQmlnRGVjaW1hbC5ST1VORF9DRUlMSU5HKSwKKworICAgIC8qKgorICAgICAqIFJvdW5kaW5nIG1vZGUgdG8gcm91bmQgdG93YXJkcyBuZWdhdGl2ZSBpbmZpbml0eS4gRm9yIHBvc2l0aXZlIHZhbHVlcworICAgICAqIHRoaXMgcm91bmRpbmcgbW9kZSBiZWhhdmVzIGFzIHtAbGluayAjRE9XTn0sIGZvciBuZWdhdGl2ZSB2YWx1ZXMgYXMKKyAgICAgKiB7QGxpbmsgI1VQfS4KKyAgICAgKiA8YnI+CisgICAgICogUnVsZToge0Bjb2RlIHgucm91bmQoKSA8PSB4fQorICAgICAqLworICAgIEZMT09SKEJpZ0RlY2ltYWwuUk9VTkRfRkxPT1IpLAorCisgICAgLyoqCisgICAgICogUm91bmRpbmcgbW9kZSB3aGVyZSB2YWx1ZXMgYXJlIHJvdW5kZWQgdG93YXJkcyB0aGUgbmVhcmVzdCBuZWlnaGJvci4gVGllcworICAgICAqIGFyZSBicm9rZW4gYnkgcm91bmRpbmcgdXAuCisgICAgICovCisgICAgSEFMRl9VUChCaWdEZWNpbWFsLlJPVU5EX0hBTEZfVVApLAorCisgICAgLyoqCisgICAgICogUm91bmRpbmcgbW9kZSB3aGVyZSB2YWx1ZXMgYXJlIHJvdW5kZWQgdG93YXJkcyB0aGUgbmVhcmVzdCBuZWlnaGJvci4gVGllcworICAgICAqIGFyZSBicm9rZW4gYnkgcm91bmRpbmcgZG93bi4KKyAgICAgKi8KKyAgICBIQUxGX0RPV04oQmlnRGVjaW1hbC5ST1VORF9IQUxGX0RPV04pLAorCisgICAgLyoqCisgICAgICogUm91bmRpbmcgbW9kZSB3aGVyZSB2YWx1ZXMgYXJlIHJvdW5kZWQgdG93YXJkcyB0aGUgbmVhcmVzdCBuZWlnaGJvci4gVGllcworICAgICAqIGFyZSBicm9rZW4gYnkgcm91bmRpbmcgdG8gdGhlIGV2ZW4gbmVpZ2hib3IuCisgICAgICovCisgICAgSEFMRl9FVkVOKEJpZ0RlY2ltYWwuUk9VTkRfSEFMRl9FVkVOKSwKKworICAgIC8qKgorICAgICAqIFJvdW5kaW5nIG1vZGUgd2hlcmUgdGhlIHJvdW5kaW5nIG9wZXJhdGlvbnMgdGhyb3dzIGFuIEFyaXRobWV0aWNFeGNlcHRpb24KKyAgICAgKiBmb3IgdGhlIGNhc2UgdGhhdCByb3VuZGluZyBpcyBuZWNlc3NhcnksIGkuZS4gZm9yIHRoZSBjYXNlIHRoYXQgdGhlIHZhbHVlCisgICAgICogY2Fubm90IGJlIHJlcHJlc2VudGVkIGV4YWN0bHkuCisgICAgICovCisgICAgVU5ORUNFU1NBUlkoQmlnRGVjaW1hbC5ST1VORF9VTk5FQ0VTU0FSWSk7CisKKyAgICAvKiogVGhlIG9sZCBjb25zdGFudCBvZiA8Y29kZT5CaWdEZWNpbWFsPC9jb2RlPi4gKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBiaWdEZWNpbWFsUk07CisKKyAgICAvKiogSXQgc2V0cyB0aGUgb2xkIGNvbnN0YW50LiAqLworICAgIFJvdW5kaW5nTW9kZShpbnQgcm0pIHsKKyAgICAgICAgYmlnRGVjaW1hbFJNID0gcm07CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgcm91bmRpbmcgbW9kZSBjb25zdGFudHMgZnJvbSBjbGFzcyB7QGNvZGUgQmlnRGVjaW1hbH0gaW50bworICAgICAqIHtAY29kZSBSb3VuZGluZ01vZGV9IHZhbHVlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb2RlCisgICAgICogICAgICAgICAgICByb3VuZGluZyBtb2RlIGNvbnN0YW50IGFzIGRlZmluZWQgaW4gY2xhc3Mge0Bjb2RlIEJpZ0RlY2ltYWx9CisgICAgICogQHJldHVybiBjb3JyZXNwb25kaW5nIHJvdW5kaW5nIG1vZGUgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBSb3VuZGluZ01vZGUgdmFsdWVPZihpbnQgbW9kZSkgeworICAgICAgICBzd2l0Y2ggKG1vZGUpIHsKKyAgICAgICAgICAgIGNhc2UgQmlnRGVjaW1hbC5ST1VORF9DRUlMSU5HOgorICAgICAgICAgICAgICAgIHJldHVybiBDRUlMSU5HOworICAgICAgICAgICAgY2FzZSBCaWdEZWNpbWFsLlJPVU5EX0RPV046CisgICAgICAgICAgICAgICAgcmV0dXJuIERPV047CisgICAgICAgICAgICBjYXNlIEJpZ0RlY2ltYWwuUk9VTkRfRkxPT1I6CisgICAgICAgICAgICAgICAgcmV0dXJuIEZMT09SOworICAgICAgICAgICAgY2FzZSBCaWdEZWNpbWFsLlJPVU5EX0hBTEZfRE9XTjoKKyAgICAgICAgICAgICAgICByZXR1cm4gSEFMRl9ET1dOOworICAgICAgICAgICAgY2FzZSBCaWdEZWNpbWFsLlJPVU5EX0hBTEZfRVZFTjoKKyAgICAgICAgICAgICAgICByZXR1cm4gSEFMRl9FVkVOOworICAgICAgICAgICAgY2FzZSBCaWdEZWNpbWFsLlJPVU5EX0hBTEZfVVA6CisgICAgICAgICAgICAgICAgcmV0dXJuIEhBTEZfVVA7CisgICAgICAgICAgICBjYXNlIEJpZ0RlY2ltYWwuUk9VTkRfVU5ORUNFU1NBUlk6CisgICAgICAgICAgICAgICAgcmV0dXJuIFVOTkVDRVNTQVJZOworICAgICAgICAgICAgY2FzZSBCaWdEZWNpbWFsLlJPVU5EX1VQOgorICAgICAgICAgICAgICAgIHJldHVybiBVUDsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCByb3VuZGluZyBtb2RlIik7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvQWRkcmVzc0NhY2hlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvQWRkcmVzc0NhY2hlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDhmNWQ4MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9BZGRyZXNzQ2FjaGUuamF2YQpAQCAtMCwwICsxLDEzOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKK2ltcG9ydCBsaWJjb3JlLnV0aWwuQmFzaWNMcnVDYWNoZTsKKworLyoqCisgKiBJbXBsZW1lbnRzIGNhY2hpbmcgZm9yIHtAY29kZSBJbmV0QWRkcmVzc30uIFdlIHVzZSBhIHVuaWZpZWQgY2FjaGUgZm9yIGJvdGggcG9zaXRpdmUgYW5kIG5lZ2F0aXZlCisgKiBjYWNoZSBlbnRyaWVzLgorICovCitjbGFzcyBBZGRyZXNzQ2FjaGUgeworICAgIC8qKgorICAgICAqIFdoZW4gdGhlIGNhY2hlIGNvbnRhaW5zIG1vcmUgZW50cmllcyB0aGFuIHRoaXMsIHdlIHN0YXJ0IGRyb3BwaW5nIHRoZSBvbGRlc3Qgb25lcy4KKyAgICAgKiBUaGlzIHNob3VsZCBiZSBhIHBvd2VyIG9mIHR3byB0byBhdm9pZCB3YXN0ZWQgc3BhY2UgaW4gb3VyIGN1c3RvbSBtYXAuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9FTlRSSUVTID0gNTEyOworCisgICAgLy8gRGVmYXVsdCB0aW1lLXRvLWxpdmUgZm9yIHBvc2l0aXZlIGNhY2hlIGVudHJpZXMuIDYwMCBzZWNvbmRzICgxMCBtaW51dGVzKS4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIERFRkFVTFRfUE9TSVRJVkVfVFRMX05BTk9TID0gNjAwICogMTAwMDAwMDAwMEw7CisgICAgLy8gRGVmYXVsdCB0aW1lLXRvLWxpdmUgZm9yIG5lZ2F0aXZlIGNhY2hlIGVudHJpZXMuIDEwIHNlY29uZHMuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBERUZBVUxUX05FR0FUSVZFX1RUTF9OQU5PUyA9IDEwICogMTAwMDAwMDAwMEw7CisKKyAgICAvLyBUaGUgYWN0dWFsIGNhY2hlLgorICAgIHByaXZhdGUgZmluYWwgQmFzaWNMcnVDYWNoZTxTdHJpbmcsIEFkZHJlc3NDYWNoZUVudHJ5PiBjYWNoZQorICAgICAgICAgICAgPSBuZXcgQmFzaWNMcnVDYWNoZTxTdHJpbmcsIEFkZHJlc3NDYWNoZUVudHJ5PihNQVhfRU5UUklFUyk7CisKKyAgICBzdGF0aWMgY2xhc3MgQWRkcmVzc0NhY2hlRW50cnkgeworICAgICAgICAvLyBFaXRoZXIgYW4gSW5ldEFkZHJlc3NbXSBmb3IgYSBwb3NpdGl2ZSBlbnRyeSwKKyAgICAgICAgLy8gb3IgYSBTdHJpbmcgZGV0YWlsIG1lc3NhZ2UgZm9yIGEgbmVnYXRpdmUgZW50cnkuCisgICAgICAgIGZpbmFsIE9iamVjdCB2YWx1ZTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGFic29sdXRlIGV4cGlyeSB0aW1lIGluIG5hbm9zZWNvbmRzLiBOYW5vc2Vjb25kcyBmcm9tIFN5c3RlbS5uYW5vVGltZSBpcyBpZGVhbAorICAgICAgICAgKiBiZWNhdXNlIC0tIHVubGlrZSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMgLS0gaXQgY2FuIG5ldmVyIGdvIGJhY2t3YXJkcy4KKyAgICAgICAgICoKKyAgICAgICAgICogVW5sZXNzIHdlIG5lZWQgdG8gY29wZSB3aXRoIEROUyBUVExzIG9mIDI5MiB5ZWFycywgd2UgZG9uJ3QgbmVlZCB0byB3b3JyeSBhYm91dCBvdmVyZmxvdy4KKyAgICAgICAgICovCisgICAgICAgIGZpbmFsIGxvbmcgZXhwaXJ5TmFub3M7CisKKyAgICAgICAgQWRkcmVzc0NhY2hlRW50cnkoT2JqZWN0IHZhbHVlLCBsb25nIGV4cGlyeU5hbm9zKSB7CisgICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgICAgICAgICB0aGlzLmV4cGlyeU5hbm9zID0gZXhwaXJ5TmFub3M7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGFsbCBlbnRyaWVzIGZyb20gdGhlIGNhY2hlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBjYWNoZS5ldmljdEFsbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNhY2hlZCBJbmV0QWRkcmVzc1tdIGFzc29jaWF0ZWQgd2l0aCAnaG9zdG5hbWUnLiBSZXR1cm5zIG51bGwgaWYgbm90aGluZyBpcyBrbm93bgorICAgICAqIGFib3V0ICdob3N0bmFtZScuIFJldHVybnMgYSBTdHJpbmcgc3VpdGFibGUgZm9yIHVzZSBhcyBhbiBVbmtub3duSG9zdEV4Y2VwdGlvbiBkZXRhaWwKKyAgICAgKiBtZXNzYWdlIGlmICdob3N0bmFtZScgaXMga25vd24gbm90IHRvIGV4aXN0LgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0KFN0cmluZyBob3N0bmFtZSkgeworICAgICAgICBBZGRyZXNzQ2FjaGVFbnRyeSBlbnRyeSA9IGNhY2hlLmdldChob3N0bmFtZSk7CisgICAgICAgIC8vIERvIHdlIGhhdmUgYSB2YWxpZCBjYWNoZSBlbnRyeT8KKyAgICAgICAgaWYgKGVudHJ5ICE9IG51bGwgJiYgZW50cnkuZXhwaXJ5TmFub3MgPj0gU3lzdGVtLm5hbm9UaW1lKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBlbnRyeS52YWx1ZTsKKyAgICAgICAgfQorICAgICAgICAvLyBFaXRoZXIgd2UgZGlkbid0IGZpbmQgYW55dGhpbmcsIG9yIGl0IGhhZCBleHBpcmVkLgorICAgICAgICAvLyBObyBuZWVkIHRvIHJlbW92ZSBleHBpcmVkIGVudHJpZXM6IHRoZSBjYWxsZXIgd2lsbCBwcm92aWRlIGEgcmVwbGFjZW1lbnQgc2hvcnRseS4KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzb2NpYXRlcyB0aGUgZ2l2ZW4gJ2FkZHJlc3Nlcycgd2l0aCAnaG9zdG5hbWUnLiBUaGUgYXNzb2NpYXRpb24gd2lsbCBleHBpcmUgYWZ0ZXIgYQorICAgICAqIGNlcnRhaW4gbGVuZ3RoIG9mIHRpbWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHV0KFN0cmluZyBob3N0bmFtZSwgSW5ldEFkZHJlc3NbXSBhZGRyZXNzZXMpIHsKKyAgICAgICAgcHV0KGhvc3RuYW1lLCBhZGRyZXNzZXMsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFzc29jaWF0ZXMgdGhlIGdpdmVuICdkZXRhaWxNZXNzYWdlJyB3aXRoICdob3N0bmFtZScuIFRoZSBhc3NvY2lhdGlvbiB3aWxsIGV4cGlyZSBhZnRlciBhCisgICAgICogY2VydGFpbiBsZW5ndGggb2YgdGltZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXQoU3RyaW5nIGhvc3RuYW1lLCBTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBwdXQoaG9zdG5hbWUsIGRldGFpbE1lc3NhZ2UsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBc3NvY2lhdGVzIHRoZSBnaXZlbiAnYWRkcmVzc2VzJyB3aXRoICdob3N0bmFtZScuIFRoZSBhc3NvY2lhdGlvbiB3aWxsIGV4cGlyZSBhZnRlciBhCisgICAgICogY2VydGFpbiBsZW5ndGggb2YgdGltZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXQoU3RyaW5nIGhvc3RuYW1lLCBPYmplY3QgdmFsdWUsIGJvb2xlYW4gaXNQb3NpdGl2ZSkgeworICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIGV4cGlyeSB0aW1lLgorICAgICAgICBTdHJpbmcgcHJvcGVydHlOYW1lID0gaXNQb3NpdGl2ZSA/ICJuZXR3b3JrYWRkcmVzcy5jYWNoZS50dGwiIDogIm5ldHdvcmthZGRyZXNzLmNhY2hlLm5lZ2F0aXZlLnR0bCI7CisgICAgICAgIGxvbmcgZGVmYXVsdFR0bE5hbm9zID0gaXNQb3NpdGl2ZSA/IERFRkFVTFRfUE9TSVRJVkVfVFRMX05BTk9TIDogREVGQVVMVF9ORUdBVElWRV9UVExfTkFOT1M7CisgICAgICAgIGxvbmcgZXhwaXJ5TmFub3MgPSBTeXN0ZW0ubmFub1RpbWUoKSArIGRlZmF1bHRUdGxOYW5vczsKKyAgICAgICAgLy8gVXBkYXRlIHRoZSBjYWNoZS4KKyAgICAgICAgY2FjaGUucHV0KGhvc3RuYW1lLCBuZXcgQWRkcmVzc0NhY2hlRW50cnkodmFsdWUsIGV4cGlyeU5hbm9zKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVjb3JkcyB0aGF0ICdob3N0bmFtZScgaXMga25vd24gbm90IHRvIGhhdmUgYW55IGFzc29jaWF0ZWQgYWRkcmVzc2VzLiAoSS5lLiBpbnNlcnQgYQorICAgICAqIG5lZ2F0aXZlIGNhY2hlIGVudHJ5LikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXRVbmtub3duSG9zdChTdHJpbmcgaG9zdG5hbWUsIFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHB1dChob3N0bmFtZSwgZGV0YWlsTWVzc2FnZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBsb25nIGN1c3RvbVR0bChTdHJpbmcgcHJvcGVydHlOYW1lLCBsb25nIGRlZmF1bHRUdGxOYW5vcykgeworICAgICAgICBTdHJpbmcgdHRsU3RyaW5nID0gU3lzdGVtLmdldFByb3BlcnR5KHByb3BlcnR5TmFtZSwgbnVsbCk7CisgICAgICAgIGlmICh0dGxTdHJpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIFN5c3RlbS5uYW5vVGltZSgpICsgZGVmYXVsdFR0bE5hbm9zOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsb25nIHR0bFMgPSBMb25nLnBhcnNlTG9uZyh0dGxTdHJpbmcpOworICAgICAgICAgICAgLy8gRm9yIHRoZSBzeXN0ZW0gcHJvcGVydGllcywgLTEgbWVhbnMgImNhY2hlIGZvcmV2ZXIiIGFuZCAwIG1lYW5zICJkb24ndCBjYWNoZSIuCisgICAgICAgICAgICBpZiAodHRsUyA9PSAtMSkgeworICAgICAgICAgICAgICAgIHJldHVybiBMb25nLk1BWF9WQUxVRTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodHRsUyA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIExvbmcuTUlOX1ZBTFVFOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gU3lzdGVtLm5hbm9UaW1lKCkgKyB0dGxTICogMTAwMDAwMDAwMEw7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgcmV0dXJuIFN5c3RlbS5uYW5vVGltZSgpICsgZGVmYXVsdFR0bE5hbm9zOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0F1dGhlbnRpY2F0b3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9BdXRoZW50aWNhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmM2NmM4OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9BdXRoZW50aWNhdG9yLmphdmEKQEAgLTAsMCArMSwyOTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKKy8qKgorICogQW4gaW1wbGVtZW50YXRpb24gb2YgdGhpcyBjbGFzcyBpcyBhYmxlIHRvIG9idGFpbiBhdXRoZW50aWNhdGlvbiBpbmZvcm1hdGlvbgorICogZm9yIGEgY29ubmVjdGlvbiBpbiBzZXZlcmFsIHdheXMuIEZvciB0aGlzIHB1cnBvc2UgaXQgaGFzIHRvIHNldCB0aGUgZGVmYXVsdAorICogYXV0aGVudGljYXRvciB3aGljaCBleHRlbmRzIHtAY29kZSBBdXRoZW50aWNhdG9yfSBieSB7QGNvZGUKKyAqIHNldERlZmF1bHQoQXV0aGVudGljYXRvciBhKX0uIFRoZW4gaXQgc2hvdWxkIG92ZXJyaWRlIHtAY29kZQorICogZ2V0UGFzc3dvcmRBdXRoZW50aWNhdGlvbigpfSB3aGljaCBkaWN0YXRlcyBob3cgdGhlIGF1dGhlbnRpY2F0aW9uIGluZm8gaXMKKyAqIG9idGFpbmVkLiBVc3VhbGx5LCBpdCBwcm9tcHRzIHRoZSB1c2VyIGZvciB0aGUgcmVxdWlyZWQgaW5wdXQuCisgKgorICogQHNlZSAjc2V0RGVmYXVsdAorICogQHNlZSAjZ2V0UGFzc3dvcmRBdXRoZW50aWNhdGlvbgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQXV0aGVudGljYXRvciB7CisKKyAgICAvLyB0aGUgZGVmYXVsdCBhdXRoZW50aWNhdG9yIHRoYXQgbmVlZHMgdG8gYmUgc2V0CisgICAgcHJpdmF0ZSBzdGF0aWMgQXV0aGVudGljYXRvciB0aGlzQXV0aGVudGljYXRvcjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE5ldFBlcm1pc3Npb24gcmVxdWVzdFBhc3N3b3JkQXV0aGVudGljYXRpb25QZXJtaXNzaW9uID0gbmV3IE5ldFBlcm1pc3Npb24oCisgICAgICAgICAgICAicmVxdWVzdFBhc3N3b3JkQXV0aGVudGljYXRpb24iKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE5ldFBlcm1pc3Npb24gc2V0RGVmYXVsdEF1dGhlbnRpY2F0b3JQZXJtaXNzaW9uID0gbmV3IE5ldFBlcm1pc3Npb24oCisgICAgICAgICAgICAic2V0RGVmYXVsdEF1dGhlbnRpY2F0b3IiKTsKKworICAgIC8vIHRoZSByZXF1ZXN0ZXIgY29ubmVjdGlvbiBpbmZvCisgICAgcHJpdmF0ZSBTdHJpbmcgaG9zdDsKKworICAgIHByaXZhdGUgSW5ldEFkZHJlc3MgYWRkcjsKKworICAgIHByaXZhdGUgaW50IHBvcnQ7CisKKyAgICBwcml2YXRlIFN0cmluZyBwcm90b2NvbDsKKworICAgIHByaXZhdGUgU3RyaW5nIHByb21wdDsKKworICAgIHByaXZhdGUgU3RyaW5nIHNjaGVtZTsKKworICAgIHByaXZhdGUgVVJMIHVybDsKKworICAgIHByaXZhdGUgUmVxdWVzdG9yVHlwZSBydDsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNvbGxlY3RlZCB1c2VybmFtZSBhbmQgcGFzc3dvcmQgZm9yIGF1dGhvcml6YXRpb24uIFRoZQorICAgICAqIHN1YmNsYXNzIGhhcyB0byBvdmVycmlkZSB0aGlzIG1ldGhvZCB0byByZXR1cm4gYSB2YWx1ZSBkaWZmZXJlbnQgdG8gdGhlCisgICAgICogZGVmYXVsdCB3aGljaCBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogPHA+CisgICAgICogUmV0dXJucyB7QGNvZGUgbnVsbH0gYnkgZGVmYXVsdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gY29sbGVjdGVkIHBhc3N3b3JkIGF1dGhlbnRpY2F0aW9uIGRhdGEuCisgICAgICovCisgICAgcHJvdGVjdGVkIFBhc3N3b3JkQXV0aGVudGljYXRpb24gZ2V0UGFzc3dvcmRBdXRoZW50aWNhdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcG9ydCBvZiB0aGUgY29ubmVjdGlvbiB0aGF0IHJlcXVlc3RzIGF1dGhvcml6YXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHBvcnQgb2YgdGhlIGNvbm5lY3Rpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIGludCBnZXRSZXF1ZXN0aW5nUG9ydCgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMucG9ydDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhZGRyZXNzIG9mIHRoZSBjb25uZWN0aW9uIHRoYXQgcmVxdWVzdHMgYXV0aG9yaXphdGlvbiBvcgorICAgICAqIHtAY29kZSBudWxsfSBpZiB1bmtub3duLgorICAgICAqCisgICAgICogQHJldHVybiBhZGRyZXNzIG9mIHRoZSBjb25uZWN0aW9uLgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBJbmV0QWRkcmVzcyBnZXRSZXF1ZXN0aW5nU2l0ZSgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuYWRkcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByZWFsbSAocHJvbXB0IHN0cmluZykgb2YgdGhlIGNvbm5lY3Rpb24gdGhhdCByZXF1ZXN0cworICAgICAqIGF1dGhvcml6YXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHByb21wdCBzdHJpbmcgb2YgdGhlIGNvbm5lY3Rpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIFN0cmluZyBnZXRSZXF1ZXN0aW5nUHJvbXB0KCkgeworICAgICAgICByZXR1cm4gdGhpcy5wcm9tcHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJvdG9jb2wgb2YgdGhlIGNvbm5lY3Rpb24gdGhhdCByZXF1ZXN0cyBhdXRob3JpemF0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBwcm90b2NvbCBvZiB0aGUgY29ubmVjdGlvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgU3RyaW5nIGdldFJlcXVlc3RpbmdQcm90b2NvbCgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMucHJvdG9jb2w7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2NoZW1lIG9mIHRoZSBjb25uZWN0aW9uIHRoYXQgcmVxdWVzdHMgYXV0aG9yaXphdGlvbiwgZm9yCisgICAgICogZXhhbXBsZSBIVFRQIEJhc2ljIEF1dGhlbnRpY2F0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBzY2hlbWUgb2YgdGhlIGNvbm5lY3Rpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIFN0cmluZyBnZXRSZXF1ZXN0aW5nU2NoZW1lKCkgeworICAgICAgICByZXR1cm4gdGhpcy5zY2hlbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW52b2tlcyB0aGUgbWV0aG9kcyBvZiB0aGUgcmVnaXN0ZXJlZAorICAgICAqIGF1dGhlbnRpY2F0b3IgdG8gZ2V0IHRoZSBhdXRoZW50aWNhdGlvbiBpbmZvLgorICAgICAqCisgICAgICogQHJldHVybiBwYXNzd29yZCBhdXRoZW50aWNhdGlvbiBpbmZvIG9yIHtAY29kZSBudWxsfSBpZiBubyBhdXRoZW50aWNhdG9yCisgICAgICogICAgICAgICBleGlzdHMuCisgICAgICogQHBhcmFtIHJBZGRyCisgICAgICogICAgICAgICAgICBhZGRyZXNzIG9mIHRoZSBjb25uZWN0aW9uIHRoYXQgcmVxdWVzdHMgYXV0aGVudGljYXRpb24uCisgICAgICogQHBhcmFtIHJQb3J0CisgICAgICogICAgICAgICAgICBwb3J0IG9mIHRoZSBjb25uZWN0aW9uIHRoYXQgcmVxdWVzdHMgYXV0aGVudGljYXRpb24uCisgICAgICogQHBhcmFtIHJQcm90b2NvbAorICAgICAqICAgICAgICAgICAgcHJvdG9jb2wgb2YgdGhlIGNvbm5lY3Rpb24gdGhhdCByZXF1ZXN0cyBhdXRoZW50aWNhdGlvbi4KKyAgICAgKiBAcGFyYW0gclByb21wdAorICAgICAqICAgICAgICAgICAgcmVhbG0gb2YgdGhlIGNvbm5lY3Rpb24gdGhhdCByZXF1ZXN0cyBhdXRoZW50aWNhdGlvbi4KKyAgICAgKiBAcGFyYW0gclNjaGVtZQorICAgICAqICAgICAgICAgICAgc2NoZW1lIG9mIHRoZSBjb25uZWN0aW9uIHRoYXQgcmVxdWVzdHMgYXV0aGVudGljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiByZXF1ZXN0UGFzc3dvcmRBdXRoZW50aWNhdGlvbigKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIHJBZGRyLCBpbnQgclBvcnQsIFN0cmluZyByUHJvdG9jb2wsIFN0cmluZyByUHJvbXB0LAorICAgICAgICAgICAgU3RyaW5nIHJTY2hlbWUpIHsKKyAgICAgICAgaWYgKHRoaXNBdXRoZW50aWNhdG9yID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIC8vIHNldCB0aGUgcmVxdWVzdGVyIGluZm8gc28gaXQga25vd3Mgd2hhdCBpdCBpcyByZXF1ZXN0aW5nCisgICAgICAgIC8vIGF1dGhlbnRpY2F0aW9uIGZvcgorICAgICAgICB0aGlzQXV0aGVudGljYXRvci5hZGRyID0gckFkZHI7CisgICAgICAgIHRoaXNBdXRoZW50aWNhdG9yLnBvcnQgPSByUG9ydDsKKyAgICAgICAgdGhpc0F1dGhlbnRpY2F0b3IucHJvdG9jb2wgPSByUHJvdG9jb2w7CisgICAgICAgIHRoaXNBdXRoZW50aWNhdG9yLnByb21wdCA9IHJQcm9tcHQ7CisgICAgICAgIHRoaXNBdXRoZW50aWNhdG9yLnNjaGVtZSA9IHJTY2hlbWU7CisgICAgICAgIHRoaXNBdXRoZW50aWNhdG9yLnJ0ID0gUmVxdWVzdG9yVHlwZS5TRVJWRVI7CisKKyAgICAgICAgLy8gcmV0dXJucyB0aGUgYXV0aGVudGljYXRpb24gaW5mbyBvYnRhaW5lZCBieSB0aGUgcmVnaXN0ZXJlZAorICAgICAgICAvLyBBdXRoZW50aWNhdG9yCisgICAgICAgIHJldHVybiB0aGlzQXV0aGVudGljYXRvci5nZXRQYXNzd29yZEF1dGhlbnRpY2F0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB7QGNvZGUgYX0gYXMgdGhlIGRlZmF1bHQgYXV0aGVudGljYXRvci4gSXQgd2lsbCBiZSBjYWxsZWQgd2hlbmV2ZXIKKyAgICAgKiB0aGUgcmVhbG0gdGhhdCB0aGUgVVJMIGlzIHBvaW50aW5nIHRvIHJlcXVpcmVzIGF1dGhvcml6YXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYQorICAgICAqICAgICAgICAgICAgYXV0aGVudGljYXRvciB3aGljaCBoYXMgdG8gYmUgc2V0IGFzIGRlZmF1bHQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldERlZmF1bHQoQXV0aGVudGljYXRvciBhKSB7CisgICAgICAgIHRoaXNBdXRoZW50aWNhdG9yID0gYTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnZva2VzIHRoZSBtZXRob2RzIG9mIHRoZSByZWdpc3RlcmVkCisgICAgICogYXV0aGVudGljYXRvciB0byBnZXQgdGhlIGF1dGhlbnRpY2F0aW9uIGluZm8uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHBhc3N3b3JkIGF1dGhlbnRpY2F0aW9uIGluZm8gb3Ige0Bjb2RlIG51bGx9IGlmIG5vIGF1dGhlbnRpY2F0b3IKKyAgICAgKiAgICAgICAgIGV4aXN0cy4KKyAgICAgKiBAcGFyYW0gckhvc3QKKyAgICAgKiAgICAgICAgICAgIGhvc3QgbmFtZSBvZiB0aGUgY29ubmVjdGlvbiB0aGF0IHJlcXVlc3RzIGF1dGhlbnRpY2F0aW9uLgorICAgICAqIEBwYXJhbSByQWRkcgorICAgICAqICAgICAgICAgICAgYWRkcmVzcyBvZiB0aGUgY29ubmVjdGlvbiB0aGF0IHJlcXVlc3RzIGF1dGhlbnRpY2F0aW9uLgorICAgICAqIEBwYXJhbSByUG9ydAorICAgICAqICAgICAgICAgICAgcG9ydCBvZiB0aGUgY29ubmVjdGlvbiB0aGF0IHJlcXVlc3RzIGF1dGhlbnRpY2F0aW9uLgorICAgICAqIEBwYXJhbSByUHJvdG9jb2wKKyAgICAgKiAgICAgICAgICAgIHByb3RvY29sIG9mIHRoZSBjb25uZWN0aW9uIHRoYXQgcmVxdWVzdHMgYXV0aGVudGljYXRpb24uCisgICAgICogQHBhcmFtIHJQcm9tcHQKKyAgICAgKiAgICAgICAgICAgIHJlYWxtIG9mIHRoZSBjb25uZWN0aW9uIHRoYXQgcmVxdWVzdHMgYXV0aGVudGljYXRpb24uCisgICAgICogQHBhcmFtIHJTY2hlbWUKKyAgICAgKiAgICAgICAgICAgIHNjaGVtZSBvZiB0aGUgY29ubmVjdGlvbiB0aGF0IHJlcXVlc3RzIGF1dGhlbnRpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIFBhc3N3b3JkQXV0aGVudGljYXRpb24gcmVxdWVzdFBhc3N3b3JkQXV0aGVudGljYXRpb24oCisgICAgICAgICAgICBTdHJpbmcgckhvc3QsIEluZXRBZGRyZXNzIHJBZGRyLCBpbnQgclBvcnQsIFN0cmluZyByUHJvdG9jb2wsCisgICAgICAgICAgICBTdHJpbmcgclByb21wdCwgU3RyaW5nIHJTY2hlbWUpIHsKKyAgICAgICAgaWYgKHRoaXNBdXRoZW50aWNhdG9yID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIC8vIHNldCB0aGUgcmVxdWVzdGVyIGluZm8gc28gaXQga25vd3Mgd2hhdCBpdCBpcyByZXF1ZXN0aW5nCisgICAgICAgIC8vIGF1dGhlbnRpY2F0aW9uIGZvcgorICAgICAgICB0aGlzQXV0aGVudGljYXRvci5ob3N0ID0gckhvc3Q7CisgICAgICAgIHRoaXNBdXRoZW50aWNhdG9yLmFkZHIgPSByQWRkcjsKKyAgICAgICAgdGhpc0F1dGhlbnRpY2F0b3IucG9ydCA9IHJQb3J0OworICAgICAgICB0aGlzQXV0aGVudGljYXRvci5wcm90b2NvbCA9IHJQcm90b2NvbDsKKyAgICAgICAgdGhpc0F1dGhlbnRpY2F0b3IucHJvbXB0ID0gclByb21wdDsKKyAgICAgICAgdGhpc0F1dGhlbnRpY2F0b3Iuc2NoZW1lID0gclNjaGVtZTsKKyAgICAgICAgdGhpc0F1dGhlbnRpY2F0b3IucnQgPSBSZXF1ZXN0b3JUeXBlLlNFUlZFUjsKKworICAgICAgICAvLyByZXR1cm5zIHRoZSBhdXRoZW50aWNhdGlvbiBpbmZvIG9idGFpbmVkIGJ5IHRoZSByZWdpc3RlcmVkCisgICAgICAgIC8vIEF1dGhlbnRpY2F0b3IKKyAgICAgICAgcmV0dXJuIHRoaXNBdXRoZW50aWNhdG9yLmdldFBhc3N3b3JkQXV0aGVudGljYXRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBob3N0IG5hbWUgb2YgdGhlIGNvbm5lY3Rpb24gdGhhdCByZXF1ZXN0cyBhdXRoZW50aWNhdGlvbiBvcgorICAgICAqIHtAY29kZSBudWxsfSBpZiB1bmtub3duLgorICAgICAqCisgICAgICogQHJldHVybiBuYW1lIG9mIHRoZSByZXF1ZXN0aW5nIGhvc3Qgb3Ige0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBTdHJpbmcgZ2V0UmVxdWVzdGluZ0hvc3QoKSB7CisgICAgICAgIHJldHVybiBob3N0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEludm9rZXMgdGhlIG1ldGhvZHMgb2YgdGhlIHJlZ2lzdGVyZWQKKyAgICAgKiBhdXRoZW50aWNhdG9yIHRvIGdldCB0aGUgYXV0aGVudGljYXRpb24gaW5mby4KKyAgICAgKgorICAgICAqIEByZXR1cm4gcGFzc3dvcmQgYXV0aGVudGljYXRpb24gaW5mbyBvciB7QGNvZGUgbnVsbH0gaWYgbm8gYXV0aGVudGljYXRvcgorICAgICAqICAgICAgICAgZXhpc3RzLgorICAgICAqIEBwYXJhbSBySG9zdAorICAgICAqICAgICAgICAgICAgaG9zdCBuYW1lIG9mIHRoZSBjb25uZWN0aW9uIHRoYXQgcmVxdWVzdHMgYXV0aGVudGljYXRpb24uCisgICAgICogQHBhcmFtIHJBZGRyCisgICAgICogICAgICAgICAgICBhZGRyZXNzIG9mIHRoZSBjb25uZWN0aW9uIHRoYXQgcmVxdWVzdHMgYXV0aGVudGljYXRpb24uCisgICAgICogQHBhcmFtIHJQb3J0CisgICAgICogICAgICAgICAgICBwb3J0IG9mIHRoZSBjb25uZWN0aW9uIHRoYXQgcmVxdWVzdHMgYXV0aGVudGljYXRpb24uCisgICAgICogQHBhcmFtIHJQcm90b2NvbAorICAgICAqICAgICAgICAgICAgcHJvdG9jb2wgb2YgdGhlIGNvbm5lY3Rpb24gdGhhdCByZXF1ZXN0cyBhdXRoZW50aWNhdGlvbi4KKyAgICAgKiBAcGFyYW0gclByb21wdAorICAgICAqICAgICAgICAgICAgcmVhbG0gb2YgdGhlIGNvbm5lY3Rpb24gdGhhdCByZXF1ZXN0cyBhdXRoZW50aWNhdGlvbi4KKyAgICAgKiBAcGFyYW0gclNjaGVtZQorICAgICAqICAgICAgICAgICAgc2NoZW1lIG9mIHRoZSBjb25uZWN0aW9uIHRoYXQgcmVxdWVzdHMgYXV0aGVudGljYXRpb24uCisgICAgICogQHBhcmFtIHJVUkwKKyAgICAgKiAgICAgICAgICAgIHVybCBvZiB0aGUgY29ubmVjdGlvbiB0aGF0IHJlcXVlc3RzIGF1dGhlbnRpY2F0aW9uLgorICAgICAqIEBwYXJhbSByZXFUeXBlCisgICAgICogICAgICAgICAgICByZXF1ZXN0b3IgdHlwZSBvZiB0aGUgY29ubmVjdGlvbiB0aGF0IHJlcXVlc3RzIGF1dGhlbnRpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiByZXF1ZXN0UGFzc3dvcmRBdXRoZW50aWNhdGlvbigKKyAgICAgICAgICAgIFN0cmluZyBySG9zdCwgSW5ldEFkZHJlc3MgckFkZHIsIGludCByUG9ydCwgU3RyaW5nIHJQcm90b2NvbCwKKyAgICAgICAgICAgIFN0cmluZyByUHJvbXB0LCBTdHJpbmcgclNjaGVtZSwgVVJMIHJVUkwsCisgICAgICAgICAgICBBdXRoZW50aWNhdG9yLlJlcXVlc3RvclR5cGUgcmVxVHlwZSkgeworICAgICAgICBpZiAodGhpc0F1dGhlbnRpY2F0b3IgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgLy8gc2V0cyB0aGUgcmVxdWVzdGVyIGluZm8gc28gaXQga25vd3Mgd2hhdCBpdCBpcyByZXF1ZXN0aW5nCisgICAgICAgIC8vIGF1dGhlbnRpY2F0aW9uIGZvcgorICAgICAgICB0aGlzQXV0aGVudGljYXRvci5ob3N0ID0gckhvc3Q7CisgICAgICAgIHRoaXNBdXRoZW50aWNhdG9yLmFkZHIgPSByQWRkcjsKKyAgICAgICAgdGhpc0F1dGhlbnRpY2F0b3IucG9ydCA9IHJQb3J0OworICAgICAgICB0aGlzQXV0aGVudGljYXRvci5wcm90b2NvbCA9IHJQcm90b2NvbDsKKyAgICAgICAgdGhpc0F1dGhlbnRpY2F0b3IucHJvbXB0ID0gclByb21wdDsKKyAgICAgICAgdGhpc0F1dGhlbnRpY2F0b3Iuc2NoZW1lID0gclNjaGVtZTsKKyAgICAgICAgdGhpc0F1dGhlbnRpY2F0b3IudXJsID0gclVSTDsKKyAgICAgICAgdGhpc0F1dGhlbnRpY2F0b3IucnQgPSByZXFUeXBlOworCisgICAgICAgIC8vIHJldHVybnMgdGhlIGF1dGhlbnRpY2F0aW9uIGluZm8gb2J0YWluZWQgYnkgdGhlIHJlZ2lzdGVyZWQKKyAgICAgICAgLy8gQXV0aGVudGljYXRvcgorICAgICAgICByZXR1cm4gdGhpc0F1dGhlbnRpY2F0b3IuZ2V0UGFzc3dvcmRBdXRoZW50aWNhdGlvbigpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgVVJMIG9mIHRoZSBhdXRoZW50aWNhdGlvbiByZXF1ZXN0LgorICAgICAqCisgICAgICogQHJldHVybiBhdXRoZW50aWNhdGlvbiByZXF1ZXN0IHVybC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgVVJMIGdldFJlcXVlc3RpbmdVUkwoKSB7CisgICAgICAgIHJldHVybiB1cmw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdHlwZSBvZiB0aGlzIHJlcXVlc3QsIGl0IGNhbiBiZSB7QGNvZGUgUFJPWFl9IG9yIHtAY29kZSBTRVJWRVJ9LgorICAgICAqCisgICAgICogQHJldHVybiBSZXF1ZXN0b3JUeXBlIG9mIHRoZSBhdXRoZW50aWNhdGlvbiByZXF1ZXN0LgorICAgICAqLworICAgIHByb3RlY3RlZCBBdXRoZW50aWNhdG9yLlJlcXVlc3RvclR5cGUgZ2V0UmVxdWVzdG9yVHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIHJ0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEVudW1lcmF0aW9uIGNsYXNzIGZvciB0aGUgb3JpZ2luIG9mIHRoZSBhdXRoZW50aWNhdGlvbiByZXF1ZXN0LgorICAgICAqLworICAgIHB1YmxpYyBlbnVtIFJlcXVlc3RvclR5cGUgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUeXBlIG9mIHByb3h5IHNlcnZlcgorICAgICAgICAgKi8KKyAgICAgICAgUFJPWFksCisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFR5cGUgb2Ygb3JpZ2luIHNlcnZlcgorICAgICAgICAgKi8KKyAgICAgICAgU0VSVkVSCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0JpbmRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9CaW5kRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2NmOTViZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9CaW5kRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworLyoqCisgKiBBIHtAY29kZSBCaW5kRXhjZXB0aW9ufSBpcyB0aHJvd24gd2hlbiBhIHByb2Nlc3MgY2Fubm90IGJpbmQgYSBsb2NhbAorICogYWRkcmVzcy9wb3J0LCBlaXRoZXIgYmVjYXVzZSBpdCBpcyBhbHJlYWR5IGJvdW5kIG9yIHJlc2VydmVkIGJ5IHRoZSBPUy4KKyAqCisgKiA8cD5Nb3N0IGFwcGxpY2F0aW9ucyA8c3Ryb25nPnNob3VsZCBub3Q8L3N0cm9uZz4gY2F0Y2ggdGhpcyBleGNlcHRpb247IGl0IGlzCisgKiBtb3JlIHJvYnVzdCB0byBjYXRjaCB0aGUgc3VwZXJjbGFzcyB7QGNvZGUgU29ja2V0RXhjZXB0aW9ufS4KKyAqLworcHVibGljIGNsYXNzIEJpbmRFeGNlcHRpb24gZXh0ZW5kcyBTb2NrZXRFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTU5NDUwMDU3NjgyNTE3MjI5NTFMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmluZEV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIHdpdGggdGhlIGdpdmVuIGRldGFpbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBCaW5kRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugd2l0aCB0aGUgZ2l2ZW4gZGV0YWlsIG1lc3NhZ2UgYW5kIGNhdXNlLgorICAgICAqIEBoaWRlCisgICAgICovCisgICAgcHVibGljIEJpbmRFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlLCBjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0NhY2hlUmVxdWVzdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0NhY2hlUmVxdWVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlhNjYzZGQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvQ2FjaGVSZXF1ZXN0LmphdmEKQEAgLTAsMCArMSw1NyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKKy8qKgorICoge0Bjb2RlIENhY2hlUmVxdWVzdH0gaXMgYSBraW5kIG9mIGNoYW5uZWwgZm9yIHN0b3JpbmcgcmVzb3VyY2UgZGF0YSBpbiB0aGUKKyAqIHtAY29kZSBSZXNwb25zZUNhY2hlfS4gQSBwcm90b2NvbCBoYW5kbGVyIGNhbGxzIHRoZSB7QGNvZGUgT3V0cHV0U3RyZWFtfQorICogd2hpY2ggaXMgcHJvdmlkZWQgYnkgdGhlIHtAY29kZSBDYWNoZVJlcXVlc3R9IG9iamVjdCwgdG8gc3RvcmUgdGhlIHJlc291cmNlCisgKiBkYXRhIGludG8gdGhlIGNhY2hlLiBJdCBhbHNvIGFsbG93cyB0aGUgdXNlciB0byBpbnRlcnJ1cHQgYW5kIGFib3J0IHRoZQorICogY3VycmVudCBzdG9yZSBvcGVyYXRpb24gYnkgY2FsbGluZyB0aGUgbWV0aG9kIHtAY29kZSBhYm9ydH0uIElmIGFuIHtAY29kZQorICogSU9FeGNlcHRpb259IG9jY3VycyB3aGlsZSByZWFkaW5nIHRoZSByZXNwb25zZSBvciB3cml0aW5nIGRhdGEgdG8gdGhlIGNhY2hlLAorICogdGhlIGN1cnJlbnQgY2FjaGUgc3RvcmUgb3BlcmF0aW9uIGlzIGFiYW5kb25lZC4KKyAqCisgKiBAc2VlIFJlc3BvbnNlQ2FjaGUKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIENhY2hlUmVxdWVzdCB7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2FjaGVSZXF1ZXN0KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEFib3J0cyB0aGUgY3VycmVudCBjYWNoZSBvcGVyYXRpb24uIElmIGFuIHtAY29kZSBJT0V4Y2VwdGlvbn0gb2NjdXJzCisgICAgICogd2hpbGUgcmVhZGluZyB0aGUgcmVzcG9uc2Ugb3Igd3JpdGluZyByZXNvdXJjZSBkYXRhIHRvIHRoZSBjYWNoZSwgdGhlCisgICAgICogY3VycmVudCBjYWNoZSBzdG9yZSBvcGVyYXRpb24gaXMgYWJvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBhYm9ydCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiB7QGNvZGUgT3V0cHV0U3RyZWFtfSB3aGljaCBpcyB1c2VkIHRvIHdyaXRlIHRoZSByZXNwb25zZSBib2R5LgorICAgICAqCisgICAgICogQHJldHVybiBhbiB7QGNvZGUgT3V0cHV0U3RyZWFtfSB3aGljaCBpcyB1c2VkIHRvIHdyaXRlIHRoZSByZXNwb25zZSBib2R5LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3IgaXMgZW5jb3VudGVyZWQgZHVyaW5nIHdyaXRpbmcgcmVzcG9uc2UgYm9keQorICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgT3V0cHV0U3RyZWFtIGdldEJvZHkoKSB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvQ2FjaGVSZXNwb25zZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0NhY2hlUmVzcG9uc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNzEzMzkxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0NhY2hlUmVzcG9uc2UuamF2YQpAQCAtMCwwICsxLDU1IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogQSByZXNwb25zZSBjYWNoZSBlbnRyeS4gQSB7QGNvZGUgQ2FjaGVSZXNwb25zZX0gb2JqZWN0IHByb3ZpZGVzIGFuIHtAY29kZQorICogSW5wdXRTdHJlYW19IHRvIGFjY2VzcyB0aGUgcmVzcG9uc2UgYm9keSBhbmQgYSB7QGNvZGUgTWFwfSBmb3IgdGhlIHJlc3BvbnNlIGhlYWRlcnMuCisgKiBAc2VlIFJlc3BvbnNlQ2FjaGUKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIENhY2hlUmVzcG9uc2UgeworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4ge0Bjb2RlIElucHV0U3RyZWFtfSB0byBhY2Nlc3MgdGhlIHJlc3BvbnNlIGJvZHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBJbnB1dFN0cmVhbX0gd2hpY2ggY2FuIGJlIHVzZWQgdG8gZmV0Y2ggdGhlIHJlc3BvbnNlCisgICAgICogICAgICAgICBib2R5LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3IgaXMgZW5jb3VudGVyZWQgd2hpbGUgcmV0cmlldmluZyB0aGUgcmVzcG9uc2UKKyAgICAgKiAgICAgICAgICAgICBib2R5LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBJbnB1dFN0cmVhbSBnZXRCb2R5KCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbW11dGFibGUge0Bjb2RlIE1hcH0gd2hpY2ggY29udGFpbnMgdGhlIHJlc3BvbnNlIGhlYWRlcnMKKyAgICAgKiBpbmZvcm1hdGlvbi4gTm90ZSB0aGF0IHtAY29kZSBVUkxDb25uZWN0aW9ufSBtYXkgbmVlZCB0aGUgb3JpZ2luYWwgaGVhZGVycyB0byBiZQorICAgICAqIGFibGUgdG8gZnVsbHkgcmVjb25zdHJ1Y3QgdGhlIHJlc3BvbnNlLiBJbiBwYXJ0aWN1bGFyLCBmYWlsdXJlIHRvIHByb3ZpZGUKKyAgICAgKiBhIG1hcHBpbmcgZnJvbSBudWxsIHRvIHRoZSBvcmlnaW5hbCBIVFRQIHN0YXR1cyBsaW5lIHdpbGwgcHJldmVudCBhbgorICAgICAqIHtAY29kZSBIdHRwVVJMQ29ubmVjdGlvbn0gZnJvbSByZXR1cm5pbmcgdGhlIGNvcnJlY3QgcmVzcG9uc2UgY29kZS4KKyAgICAgKiBTZWUge0BsaW5rIFVSTENvbm5lY3Rpb24jZ2V0SGVhZGVyRmllbGRzfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gaW1tdXRhYmxlIHtAY29kZSBNYXB9IHdoaWNoIGNvbnRhaW5zIHRoZSByZXNwb25zZSBoZWFkZXJzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3IgaXMgZW5jb3VudGVyZWQgd2hpbGUgcmV0cmlldmluZyB0aGUgcmVzcG9uc2UKKyAgICAgKiAgICAgICAgICAgICBoZWFkZXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IGdldEhlYWRlcnMoKSB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvQ29ubmVjdEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0Nvbm5lY3RFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNjZhN2U1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0Nvbm5lY3RFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDUxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCisvKioKKyAqIEEge0Bjb2RlIENvbm5lY3RFeGNlcHRpb259IGlzIHRocm93biBpZiBhIGNvbm5lY3Rpb24gY2Fubm90IGJlIGVzdGFibGlzaGVkIHRvCisgKiBhIHJlbW90ZSBob3N0IG9uIGEgc3BlY2lmaWMgcG9ydC4KKyAqCisgKiA8cD5Nb3N0IGFwcGxpY2F0aW9ucyA8c3Ryb25nPnNob3VsZCBub3Q8L3N0cm9uZz4gY2F0Y2ggdGhpcyBleGNlcHRpb247IGl0IGlzCisgKiBtb3JlIHJvYnVzdCB0byBjYXRjaCB0aGUgc3VwZXJjbGFzcyB7QGNvZGUgU29ja2V0RXhjZXB0aW9ufS4KKyAqLworcHVibGljIGNsYXNzIENvbm5lY3RFeGNlcHRpb24gZXh0ZW5kcyBTb2NrZXRFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzgzMTQwNDI3MTYyMjM2OTIxNUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBDb25uZWN0RXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugd2l0aCB0aGUgZ2l2ZW4gZGV0YWlsIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIENvbm5lY3RFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSB3aXRoIHRoZSBnaXZlbiBkZXRhaWwgbWVzc2FnZSBhbmQgY2F1c2UuCisgICAgICogQGhpZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29ubmVjdEV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UsIGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvQ29udGVudEhhbmRsZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Db250ZW50SGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhlMGJiYjcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvQ29udGVudEhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDY3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGNvbnZlcnRzIHRoZSBjb250ZW50IG9mIGEgY2VydGFpbiBmb3JtYXQgKGkuZS4gYSBNSU1FIHR5cGUpIGludG8gYQorICogSmF2YSB0eXBlIG9iamVjdC4gSXQgaXMgY3JlYXRlZCBieSB7QGNvZGUgQ29udGVudEhhbmRsZXJGYWN0b3J5fS4gVGhlIGRhdGEKKyAqIHZhbHVlcyBzaG91bGQgYmUgYWNjZXNzZWQgdmlhIHtAY29kZSBVUkx9IG9yIHtAY29kZSBVUkxDb25uZWN0aW9ufS4KKyAqCisgKiBAc2VlIENvbnRlbnRIYW5kbGVyRmFjdG9yeQorICogQHNlZSBVUkwjZ2V0Q29udGVudCgpCisgKiBAc2VlIFVSTENvbm5lY3Rpb24jZ2V0Q29udGVudCgpCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBDb250ZW50SGFuZGxlciB7CisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgb2JqZWN0IHBvaW50ZWQgYnkgdGhlIHNwZWNpZmllZCBVUkwgY29ubmVjdGlvbiB7QGNvZGUgdUNvbm59LgorICAgICAqCisgICAgICogQHBhcmFtIHVDb25uCisgICAgICogICAgICAgICAgICBVUkwgY29ubmVjdGlvbiB0aGF0IHBvaW50cyB0byB0aGUgZGVzaXJlZCBvYmplY3QuCisgICAgICogQHJldHVybiBvYmplY3QgcmVmZXJyZWQgYnkge0Bjb2RlIHVDb25ufS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSU8gZXJyb3Igb2NjdXJzIGR1cmluZyB0aGUgcmV0cmlldmFsIG9mIHRoZSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgT2JqZWN0IGdldENvbnRlbnQoVVJMQ29ubmVjdGlvbiB1Q29ubikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgb2JqZWN0IHBvaW50ZWQgYnkgdGhlIHNwZWNpZmllZCBVUkwgY29ubmVjdGlvbiB7QGNvZGUgdUNvbm59LgorICAgICAqCisgICAgICogQHBhcmFtIHVDb25uCisgICAgICogICAgICAgICAgICBVUkwgY29ubmVjdGlvbiB0aGF0IHBvaW50cyB0byB0aGUgZGVzaXJlZCBvYmplY3QuCisgICAgICogQHBhcmFtIHR5cGVzCisgICAgICogICAgICAgICAgICBsaXN0IG9mIGFjY2VwdGFibGUgY29udGVudCB0eXBlcy4KKyAgICAgKiBAcmV0dXJuIHJlc291cmNlIG9iamVjdCBwb2ludGVkIGJ5IHRoaXMgVVJMIG9yIHtAY29kZSBudWxsfSBpZiB0aGUKKyAgICAgKiAgICAgICAgIGNvbnRlbnQgZG9lc24ndCBtYXRjaCBvbmUgb2YgdGhlIHNwZWNpZmllZCBjb250ZW50IHR5cGVzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnJlZCB3aGlsZSBvYnRhaW5pbmcgdGhlIGNvbnRlbnQuCisgICAgICovCisgICAgLy8gQ2xhc3MgYXJnIG5vdCBnZW5lcmlmaWVkIGluIHRoZSBzcGVjLgorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29udGVudChVUkxDb25uZWN0aW9uIHVDb25uLCBDbGFzc1tdIHR5cGVzKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0IGNvbnRlbnQgPSBnZXRDb250ZW50KHVDb25uKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKHR5cGVzW2ldLmlzSW5zdGFuY2UoY29udGVudCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY29udGVudDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvQ29udGVudEhhbmRsZXJGYWN0b3J5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvQ29udGVudEhhbmRsZXJGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjIwNmVmZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Db250ZW50SGFuZGxlckZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDM1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCisvKioKKyAqIERlZmluZXMgYSBmYWN0b3J5IHdoaWNoIGlzIHJlc3BvbnNpYmxlIGZvciBjcmVhdGluZyBhIHtAY29kZSBDb250ZW50SGFuZGxlcn0uCisgKgorICogQHNlZSBDb250ZW50SGFuZGxlcgorICovCitwdWJsaWMgaW50ZXJmYWNlIENvbnRlbnRIYW5kbGVyRmFjdG9yeSB7CisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGNvbnRlbnQgaGFuZGxlciB0byBoYW5kbGUge0Bjb2RlIGNvbnRlbnRUeXBlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb250ZW50VHlwZQorICAgICAqICAgICAgICAgICAgc3BlY2lmaWVzIHRoZSBjb250ZW50IHR5cGUgd2hpY2ggaXMgaGFuZGxlZCBieSB0aGUgcmV0dXJuZWQKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBDb250ZW50SGFuZGxlcn0uCisgICAgICogQHJldHVybiBjb250ZW50IGhhbmRsZXIgb2JqZWN0IGZvciBhIHNwZWNpZmljIGNvbnRlbnQgdHlwZS4KKyAgICAgKi8KKyAgICBDb250ZW50SGFuZGxlciBjcmVhdGVDb250ZW50SGFuZGxlcihTdHJpbmcgY29udGVudFR5cGUpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0Nvb2tpZUhhbmRsZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Db29raWVIYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODA2M2FjZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Db29raWVIYW5kbGVyLmphdmEKQEAgLTAsMCArMSw3MSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGEgd2F5IHRvIG1hbmFnZSBjb29raWVzIHdpdGggYSBIVFRQIHByb3RvY29sIGhhbmRsZXIuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBDb29raWVIYW5kbGVyIHsKKworICAgIHByaXZhdGUgc3RhdGljIENvb2tpZUhhbmRsZXIgc3lzdGVtV2lkZUNvb2tpZUhhbmRsZXI7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzeXN0ZW0td2lkZSBjb29raWUgaGFuZGxlciBvciB7QGNvZGUgbnVsbH0gaWYgbm90IHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIENvb2tpZUhhbmRsZXIgZ2V0RGVmYXVsdCgpIHsKKyAgICAgICAgcmV0dXJuIHN5c3RlbVdpZGVDb29raWVIYW5kbGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHN5c3RlbS13aWRlIGNvb2tpZSBoYW5kbGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXREZWZhdWx0KENvb2tpZUhhbmRsZXIgY0hhbmRsZXIpIHsKKyAgICAgICAgc3lzdGVtV2lkZUNvb2tpZUhhbmRsZXIgPSBjSGFuZGxlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFsbCBjb29raWVzIGZvciBhIHNwZWNpZmljIFVSSSBmcm9tIHRoZSBjb29raWUgY2FjaGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJpCisgICAgICogICAgICAgICAgICBhIFVSSSB0byBzZWFyY2ggZm9yIGFwcGxpY2FibGUgY29va2llcy4KKyAgICAgKiBAcGFyYW0gcmVxdWVzdEhlYWRlcnMKKyAgICAgKiAgICAgICAgICAgIGEgbGlzdCBvZiByZXF1ZXN0IGhlYWRlcnMuCisgICAgICogQHJldHVybiBhbiB1bmNoYW5nZWFibGUgbWFwIG9mIGFsbCBhcHByb3ByaWF0ZSBjb29raWVzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIHRoZSBJL08gb3BlcmF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IGdldChVUkkgdXJpLAorICAgICAgICAgICAgTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PiByZXF1ZXN0SGVhZGVycykgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyBhbGwgY29va2llcyBvZiBhIHNwZWNpZmljIFVSSSBpbiB0aGUge0Bjb2RlIHJlc3BvbnNlSGVhZGVyc30gaW50bworICAgICAqIHRoZSBjb29raWUgY2FjaGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJpCisgICAgICogICAgICAgICAgICB0aGUgb3JpZ2luIFVSSSBvZiB0aGUgY29va2llcy4KKyAgICAgKiBAcGFyYW0gcmVzcG9uc2VIZWFkZXJzCisgICAgICogICAgICAgICAgICBhIGxpc3Qgb2YgcmVxdWVzdCBoZWFkZXJzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIHRoZSBJL08gb3BlcmF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHB1dChVUkkgdXJpLCBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IHJlc3BvbnNlSGVhZGVycykKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Db29raWVNYW5hZ2VyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvQ29va2llTWFuYWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxYmQ4MzIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvQ29va2llTWFuYWdlci5qYXZhCkBAIC0wLDAgKzEsMjUxIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCisvKioKKyAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgYSBjb25jcmV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBDb29raWVIYW5kbGVyLiBJdCBzZXBhcmF0ZXMKKyAqIHRoZSBzdG9yYWdlIG9mIGNvb2tpZXMgZnJvbSB0aGUgcG9saWN5IHdoaWNoIGRlY2lkZXMgdG8gYWNjZXB0IG9yIGRlbnkKKyAqIGNvb2tpZXMuIFRoZSBjb25zdHJ1Y3RvciBjYW4gaGF2ZSB0d28gYXJndW1lbnRzOiBhIENvb2tpZVN0b3JlIGFuZCBhCisgKiBDb29raWVQb2xpY3kuIFRoZSBmb3JtZXIgaXMgaW4gY2hhcmdlIG9mIGNvb2tpZSBzdG9yYWdlIGFuZCB0aGUgbGF0dGVyIG1ha2VzCisgKiBkZWNpc2lvbiBvbiBhY2NlcHRhbmNlL3JlamVjdGlvbi4KKyAqCisgKiBDb29raWVIYW5kbGVyIGlzIGluIHRoZSBjZW50ZXIgb2YgY29va2llIG1hbmFnZW1lbnQuIFVzZXIgY2FuIG1ha2UgdXNlIG9mCisgKiBDb29raWVIYW5kbGVyLnNldERlZmF1bHQgdG8gc2V0IGEgQ29va2llTWFuYWdlciBhcyB0aGUgZGVmYXVsdCBvbmUgdXNlZC4KKyAqCisgKiBDb29raWVNYW5hZ2VyLnB1dCB1c2VzIENvb2tpZVBvbGljeS5zaG91bGRBY2NlcHQgdG8gZGVjaWRlIHdoZXRoZXIgdG8gcHV0CisgKiBzb21lIGNvb2tpZXMgaW50byBhIGNvb2tpZSBzdG9yZS4gVGhyZWUgYnVpbHQtaW4gQ29va2llUG9saWN5IGlzIGRlZmluZWQ6CisgKiBBQ0NFUFRfQUxMLCBBQ0NFUFRfTk9ORSBhbmQgQUNDRVBUX09SSUdJTkFMX1NFUlZFUi4gVXNlcnMgY2FuIGFsc28gY3VzdG9taXplCisgKiB0aGUgcG9saWN5IGJ5IGltcGxlbWVudGluZyBDb29raWVQb2xpY3kuIEFueSBhY2NlcHRlZCBIVFRQIGNvb2tpZSBpcyBzdG9yZWQKKyAqIGluIENvb2tpZVN0b3JlIGFuZCB1c2VycyBjYW4gYWxzbyBoYXZlIHRoZWlyIG93biBpbXBsZW1lbnRhdGlvbi4gVXAgdG8gbm93LAorICogT25seSBhZGQoVVJJLCBIdHRwQ29va2llKSBhbmQgZ2V0KFVSSSkgYXJlIHVzZWQgYnkgQ29va2llTWFuYWdlci4gT3RoZXIKKyAqIG1ldGhvZHMgaW4gdGhpcyBjbGFzcyBtYXkgcHJvYmFibHkgYmUgdXNlZCBpbiBhIG1vcmUgY29tcGxpY2F0ZWQKKyAqIGltcGxlbWVudGF0aW9uLgorICoKKyAqIFRoZXJlIGFyZSBtYW55IHdheXMgdG8gY3VzdG9taXplIHVzZXIncyBvd24gSFRUUCBjb29raWUgbWFuYWdlbWVudDoKKyAqCisgKiBGaXJzdCwgY2FsbCBDb29raWVIYW5kbGVyLnNldERlZmF1bHQgdG8gc2V0IGEgbmV3IENvb2tpZUhhbmRsZXIKKyAqIGltcGxlbWVudGF0aW9uLiBTZWNvbmQsIGNhbGwgQ29va2llSGFuZGxlci5nZXREZWZhdWx0IHRvIHVzZSBDb29raWVNYW5hZ2VyLgorICogVGhlIENvb2tpZVBvbGljeSBhbmQgQ29va2llU3RvcmUgdXNlZCBhcmUgY3VzdG9taXplZC4gVGhpcmQsIHVzZSB0aGUKKyAqIGN1c3RvbWl6ZWQgQ29va2llUG9saWN5IGFuZCB0aGUgQ29va2llU3RvcmUuCisgKgorICogVGhpcyBpbXBsZW1lbnRhdGlvbiBjb25mb3JtcyB0byA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyOTY1LnR4dCI+UkZDIDI5NjU8L2E+IHNlY3Rpb24gMy4zLgorICoKKyAqIEBzaW5jZSAxLjYKKyAqLworcHVibGljIGNsYXNzIENvb2tpZU1hbmFnZXIgZXh0ZW5kcyBDb29raWVIYW5kbGVyIHsKKyAgICBwcml2YXRlIENvb2tpZVN0b3JlIHN0b3JlOworCisgICAgcHJpdmF0ZSBDb29raWVQb2xpY3kgcG9saWN5OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFZFUlNJT05fWkVST19IRUFERVIgPSAiU2V0LWNvb2tpZSI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkVSU0lPTl9PTkVfSEVBREVSID0gIlNldC1jb29raWUyIjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgY29va2llIG1hbmFnZXIuCisgICAgICoKKyAgICAgKiBUaGUgaW52b2NhdGlvbiBvZiB0aGlzIGNvbnN0cnVjdG9yIGlzIHRoZSBzYW1lIGFzIHRoZSBpbnZvY2F0aW9uIG9mCisgICAgICogQ29va2llTWFuYWdlcihudWxsLCBudWxsKS4KKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBDb29raWVNYW5hZ2VyKCkgeworICAgICAgICB0aGlzKG51bGwsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgY29va2llIG1hbmFnZXIgdXNpbmcgYSBzcGVjaWZpZWQgY29va2llIHN0b3JlIGFuZCBhCisgICAgICogY29va2llIHBvbGljeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdG9yZQorICAgICAqICAgICAgICAgICAgYSBDb29raWVTdG9yZSB0byBiZSB1c2VkIGJ5IGNvb2tpZSBtYW5hZ2VyLiBUaGUgbWFuYWdlciB3aWxsCisgICAgICogICAgICAgICAgICB1c2UgYSBkZWZhdWx0IG9uZSBpZiB0aGUgYXJnIGlzIG51bGwuCisgICAgICogQHBhcmFtIGNvb2tpZVBvbGljeQorICAgICAqICAgICAgICAgICAgYSBDb29raWVQb2xpY3kgdG8gYmUgdXNlZCBieSBjb29raWUgbWFuYWdlcgorICAgICAqICAgICAgICAgICAgQUNDRVBUX09SSUdJTkFMX1NFUlZFUiB3aWxsIGJlIHVzZWQgaWYgdGhlIGFyZyBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBDb29raWVNYW5hZ2VyKENvb2tpZVN0b3JlIHN0b3JlLCBDb29raWVQb2xpY3kgY29va2llUG9saWN5KSB7CisgICAgICAgIHRoaXMuc3RvcmUgPSBzdG9yZSA9PSBudWxsID8gbmV3IENvb2tpZVN0b3JlSW1wbCgpIDogc3RvcmU7CisgICAgICAgIHBvbGljeSA9IGNvb2tpZVBvbGljeSA9PSBudWxsID8gQ29va2llUG9saWN5LkFDQ0VQVF9PUklHSU5BTF9TRVJWRVIKKyAgICAgICAgICAgICAgICA6IGNvb2tpZVBvbGljeTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyBhbmQgZ2V0cyBhbGwgY29va2llcyBpbiB0aGUgY2FjaGUgYnkgdGhlIHNwZWNpZmllZCB1cmkgaW4gdGhlCisgICAgICogcmVxdWVzdCBoZWFkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJpCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIHVyaSB0byBzZWFyY2ggZm9yCisgICAgICogQHBhcmFtIHJlcXVlc3RIZWFkZXJzCisgICAgICogICAgICAgICAgICBhIGxpc3Qgb2YgcmVxdWVzdCBoZWFkZXJzCisgICAgICogQHJldHVybiBhIG1hcCB0aGF0IHJlY29yZCBhbGwgc3VjaCBjb29raWVzLCB0aGUgbWFwIGlzIHVuY2hhbmdlYWJsZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBzb21lIGVycm9yIG9mIEkvTyBvcGVyYXRpb24gb2NjdXJzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gZ2V0KFVSSSB1cmksCisgICAgICAgICAgICBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IHJlcXVlc3RIZWFkZXJzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodXJpID09IG51bGwgfHwgcmVxdWVzdEhlYWRlcnMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgTGlzdDxIdHRwQ29va2llPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PEh0dHBDb29raWU+KCk7CisgICAgICAgIGZvciAoSHR0cENvb2tpZSBjb29raWUgOiBzdG9yZS5nZXQodXJpKSkgeworICAgICAgICAgICAgaWYgKEh0dHBDb29raWUucGF0aE1hdGNoZXMoY29va2llLCB1cmkpCisgICAgICAgICAgICAgICAgICAgICYmIEh0dHBDb29raWUuc2VjdXJlTWF0Y2hlcyhjb29raWUsIHVyaSkKKyAgICAgICAgICAgICAgICAgICAgJiYgSHR0cENvb2tpZS5wb3J0TWF0Y2hlcyhjb29raWUsIHVyaSkpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYWRkKGNvb2tpZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gY29va2llc1RvSGVhZGVycyhyZXN1bHQpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gY29va2llc1RvSGVhZGVycyhMaXN0PEh0dHBDb29raWU+IGNvb2tpZXMpIHsKKyAgICAgICAgaWYgKGNvb2tpZXMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW1wdHlNYXAoKTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKworICAgICAgICAvLyBJZiBhbGwgY29va2llcyBhcmUgdmVyc2lvbiAxLCBhZGQgYSB2ZXJzaW9uIDEgaGVhZGVyLiBObyBoZWFkZXIgZm9yIHZlcnNpb24gMCBjb29raWVzLgorICAgICAgICBpbnQgbWluVmVyc2lvbiA9IDE7CisgICAgICAgIGZvciAoSHR0cENvb2tpZSBjb29raWUgOiBjb29raWVzKSB7CisgICAgICAgICAgICBtaW5WZXJzaW9uID0gTWF0aC5taW4obWluVmVyc2lvbiwgY29va2llLmdldFZlcnNpb24oKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG1pblZlcnNpb24gPT0gMSkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiJFZlcnNpb249XCIxXCI7ICIpOworICAgICAgICB9CisKKyAgICAgICAgcmVzdWx0LmFwcGVuZChjb29raWVzLmdldCgwKS50b1N0cmluZygpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBjb29raWVzLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCI7ICIpLmFwcGVuZChjb29raWVzLmdldChpKS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5zaW5nbGV0b25NYXAoIkNvb2tpZSIsIENvbGxlY3Rpb25zLnNpbmdsZXRvbkxpc3QocmVzdWx0LnRvU3RyaW5nKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGNvb2tpZXMgYWNjb3JkaW5nIHRvIHVyaSBhbmQgcmVzcG9uc2VIZWFkZXJzCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJpCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIHVyaQorICAgICAqIEBwYXJhbSByZXNwb25zZUhlYWRlcnMKKyAgICAgKiAgICAgICAgICAgIGEgbGlzdCBvZiByZXF1ZXN0IGhlYWRlcnMKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgc29tZSBlcnJvciBvZiBJL08gb3BlcmF0aW9uIG9jY3VycworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHB1dChVUkkgdXJpLCBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IHJlc3BvbnNlSGVhZGVycykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHVyaSA9PSBudWxsIHx8IHJlc3BvbnNlSGVhZGVycyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBwYXJzZSBhbmQgY29uc3RydWN0IGNvb2tpZXMgYWNjb3JkaW5nIHRvIHRoZSBtYXAKKyAgICAgICAgTGlzdDxIdHRwQ29va2llPiBjb29raWVzID0gcGFyc2VDb29raWUocmVzcG9uc2VIZWFkZXJzKTsKKyAgICAgICAgZm9yIChIdHRwQ29va2llIGNvb2tpZSA6IGNvb2tpZXMpIHsKKworICAgICAgICAgICAgLy8gaWYgdGhlIGNvb2tpZSBkb2Vzbid0IGhhdmUgYSBkb21haW4sIHNldCBvbmUuIFRoZSBwb2xpY3kgd2lsbCBkbyB2YWxpZGF0aW9uLgorICAgICAgICAgICAgaWYgKGNvb2tpZS5nZXREb21haW4oKSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY29va2llLnNldERvbWFpbih1cmkuZ2V0SG9zdCgpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gaWYgdGhlIGNvb2tpZSBkb2Vzbid0IGhhdmUgYSBwYXRoLCBzZXQgb25lLiBJZiBpdCBkb2VzLCB2YWxpZGF0ZSBpdC4KKyAgICAgICAgICAgIGlmIChjb29raWUuZ2V0UGF0aCgpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjb29raWUuc2V0UGF0aChwYXRoVG9Db29raWVQYXRoKHVyaS5nZXRQYXRoKCkpKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIUh0dHBDb29raWUucGF0aE1hdGNoZXMoY29va2llLCB1cmkpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGlmIHRoZSBjb29raWUgaGFzIHRoZSBwbGFjZWhvbGRlciBwb3J0IGxpc3QgIiIsIHNldCB0aGUgcG9ydC4gT3RoZXJ3aXNlIHZhbGlkYXRlIGl0LgorICAgICAgICAgICAgaWYgKCIiLmVxdWFscyhjb29raWUuZ2V0UG9ydGxpc3QoKSkpIHsKKyAgICAgICAgICAgICAgICBjb29raWUuc2V0UG9ydGxpc3QoSW50ZWdlci50b1N0cmluZyh1cmkuZ2V0RWZmZWN0aXZlUG9ydCgpKSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGNvb2tpZS5nZXRQb3J0bGlzdCgpICE9IG51bGwgJiYgIUh0dHBDb29raWUucG9ydE1hdGNoZXMoY29va2llLCB1cmkpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGlmIHRoZSBjb29raWUgY29uZm9ybXMgdG8gdGhlIHBvbGljeSwgYWRkIGl0IGludG8gdGhlIHN0b3JlCisgICAgICAgICAgICBpZiAocG9saWN5LnNob3VsZEFjY2VwdCh1cmksIGNvb2tpZSkpIHsKKyAgICAgICAgICAgICAgICBzdG9yZS5hZGQodXJpLCBjb29raWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvb2tpZS1zYWZlIHBhdGggYnkgdHJ1bmNhdGluZyBldmVyeXRoaW5nIGFmdGVyIHRoZSBsYXN0ICIvIi4KKyAgICAgKiBXaGVuIHJlcXVlc3QgcGF0aCBsaWtlICIvZm9vL2Jhci5odG1sIiB5aWVsZHMgYSBjb29raWUsIHRoYXQgY29va2llJ3MKKyAgICAgKiBkZWZhdWx0IHBhdGggaXMgIi9mb28vIi4KKyAgICAgKi8KKyAgICBzdGF0aWMgU3RyaW5nIHBhdGhUb0Nvb2tpZVBhdGgoU3RyaW5nIHBhdGgpIHsKKyAgICAgICAgaWYgKHBhdGggPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuICIvIjsKKyAgICAgICAgfQorICAgICAgICBpbnQgbGFzdFNsYXNoID0gcGF0aC5sYXN0SW5kZXhPZignLycpOyAvLyAtMSB5aWVsZHMgdGhlIGVtcHR5IHN0cmluZworICAgICAgICByZXR1cm4gcGF0aC5zdWJzdHJpbmcoMCwgbGFzdFNsYXNoICsgMSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgTGlzdDxIdHRwQ29va2llPiBwYXJzZUNvb2tpZShNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IHJlc3BvbnNlSGVhZGVycykgeworICAgICAgICBMaXN0PEh0dHBDb29raWU+IGNvb2tpZXMgPSBuZXcgQXJyYXlMaXN0PEh0dHBDb29raWU+KCk7CisgICAgICAgIGZvciAoTWFwLkVudHJ5PFN0cmluZywgTGlzdDxTdHJpbmc+PiBlbnRyeSA6IHJlc3BvbnNlSGVhZGVycy5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICBTdHJpbmcga2V5ID0gZW50cnkuZ2V0S2V5KCk7CisgICAgICAgICAgICAvLyBPbmx5ICJTZXQtY29va2llIiBhbmQgIlNldC1jb29raWUyIiBwYWlyIHdpbGwgYmUgcGFyc2VkCisgICAgICAgICAgICBpZiAoa2V5ICE9IG51bGwgJiYgKGtleS5lcXVhbHNJZ25vcmVDYXNlKFZFUlNJT05fWkVST19IRUFERVIpCisgICAgICAgICAgICAgICAgICAgIHx8IGtleS5lcXVhbHNJZ25vcmVDYXNlKFZFUlNJT05fT05FX0hFQURFUikpKSB7CisgICAgICAgICAgICAgICAgLy8gcGFyc2UgbGlzdCBlbGVtZW50cyBvbmUgYnkgb25lCisgICAgICAgICAgICAgICAgZm9yIChTdHJpbmcgY29va2llU3RyIDogZW50cnkuZ2V0VmFsdWUoKSkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChIdHRwQ29va2llIGNvb2tpZSA6IEh0dHBDb29raWUucGFyc2UoY29va2llU3RyKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb2tpZXMuYWRkKGNvb2tpZSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIHN0cmluZyBpcyBpbnZhbGlkLCBqdW1wIHRvIHRoZSBuZXh0IG9uZS4KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29va2llczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjb29raWUgcG9saWN5IG9mIHRoaXMgY29va2llIG1hbmFnZXIuCisgICAgICoKKyAgICAgKiBBQ0NFUFRfT1JJR0lOQUxfU0VSVkVSIGlzIHRoZSBkZWZhdWx0IHBvbGljeSBmb3IgQ29va2llTWFuYWdlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb29raWVQb2xpY3kKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb29raWUgcG9saWN5LiBpZiBudWxsLCB0aGUgb3JpZ2luYWwgcG9saWN5IHdpbGwgbm90IGJlCisgICAgICogICAgICAgICAgICBjaGFuZ2VkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvb2tpZVBvbGljeShDb29raWVQb2xpY3kgY29va2llUG9saWN5KSB7CisgICAgICAgIGlmIChjb29raWVQb2xpY3kgIT0gbnVsbCkgeworICAgICAgICAgICAgcG9saWN5ID0gY29va2llUG9saWN5OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBjdXJyZW50IGNvb2tpZSBzdG9yZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNvb2tpZSBzdG9yZSBjdXJyZW50bHkgdXNlZCBieSBjb29raWUgbWFuYWdlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29va2llU3RvcmUgZ2V0Q29va2llU3RvcmUoKSB7CisgICAgICAgIHJldHVybiBzdG9yZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvQ29va2llUG9saWN5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvQ29va2llUG9saWN5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDRjODY2OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Db29raWVQb2xpY3kuamF2YQpAQCAtMCwwICsxLDY4IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCisvKioKKyAqIENvb2tpZVBvbGljeSBoYXMgdGhyZWUgcHJlLWRlZmluZWQgcG9saWN5LiBUaGV5IGFyZSBBQ0NFUFRfQUxMLCBBQ0NFUFRfTk9ORQorICogYW5kIEFDQ0VQVF9PUklHSU5BTF9TRVJWRVIgcmVzcGVjdGl2ZWx5LiBUaGV5IGFyZSB1c2VkIHRvIGRlY2lkZSB3aGljaAorICogY29va2llcyBzaG91bGQgYmUgYWNjZXB0ZWQgYW5kIHdoaWNoIHNob3VsZCBub3QgYmUuCisgKgorICogU2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzI5NjUudHh0Ij5SRkMgMjk2NTwvYT4gc2VjdGlvbnMgMy4zIGFuZCA3IGZvciBtb3JlIGRldGFpbC4KKyAqCisgKiBAc2luY2UgMS42CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQ29va2llUG9saWN5IHsKKworICAgIC8qKgorICAgICAqIEEgcHJlLWRlZmluZWQgcG9saWN5LCBhY2NlcHRzIGFsbCBjb29raWVzLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBDb29raWVQb2xpY3kgQUNDRVBUX0FMTCA9IG5ldyBDb29raWVQb2xpY3koKSB7CisgICAgICAgIHB1YmxpYyBib29sZWFuIHNob3VsZEFjY2VwdChVUkkgdXJpLCBIdHRwQ29va2llIGNvb2tpZSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICB9OworCisgICAgLyoqCisgICAgICogQSBwcmUtZGVmaW5lZCBwb2xpY3ksIGFjY2VwdHMgbm8gY29va2llcyBhdCBhbGwuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIENvb2tpZVBvbGljeSBBQ0NFUFRfTk9ORSA9IG5ldyBDb29raWVQb2xpY3koKSB7CisgICAgICAgIHB1YmxpYyBib29sZWFuIHNob3VsZEFjY2VwdChVUkkgdXJpLCBIdHRwQ29va2llIGNvb2tpZSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfTsKKworICAgIC8qKgorICAgICAqIEEgcHJlLWRlZmluZWQgcG9saWN5LCBvbmx5IGFjY2VwdHMgY29va2llcyBmcm9tIG9yaWdpbmFsIHNlcnZlci4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgQ29va2llUG9saWN5IEFDQ0VQVF9PUklHSU5BTF9TRVJWRVIgPSBuZXcgQ29va2llUG9saWN5KCkgeworICAgICAgICBwdWJsaWMgYm9vbGVhbiBzaG91bGRBY2NlcHQoVVJJIHVyaSwgSHR0cENvb2tpZSBjb29raWUpIHsKKyAgICAgICAgICAgIHJldHVybiBIdHRwQ29va2llLmRvbWFpbk1hdGNoZXMoY29va2llLmdldERvbWFpbigpLCB1cmkuZ2V0SG9zdCgpKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGRldGVybWluZSB3aGV0aGVyIG9yIG5vdCB0aGUgc3BlY2lmaWVkIGNvb2tpZQorICAgICAqIHNob3VsZCBiZSBhY2NlcHRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmkKKyAgICAgKiAgICAgICAgICAgIHRoZSBVUkkgdG8gdXNlZCB0byBkZXRlcm1pbmUgYWNjZXB0YWJpbGl0eQorICAgICAqIEBwYXJhbSBjb29raWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBIdHRwQ29va2llIHRvIGJlIGRldGVybWluZWQKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBjb29raWUgc2hvdWxkIGJlIGFjY2VwdGVkOyBmYWxzZSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBib29sZWFuIHNob3VsZEFjY2VwdChVUkkgdXJpLCBIdHRwQ29va2llIGNvb2tpZSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvQ29va2llU3RvcmUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Db29raWVTdG9yZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQwOWI3ZTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvQ29va2llU3RvcmUuamF2YQpAQCAtMCwwICsxLDEwMyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIEEgQ29va2llU3RvcmUgb2JqZWN0IGlzIGEgcmVwb3NpdG9yeSBmb3IgY29va2llcy4KKyAqCisgKiBDb29raWVNYW5hZ2VyIHdpbGwgc3RvcmUgY29va2llcyBvZiBldmVyeSBpbmNvbWluZyBIVFRQIHJlc3BvbnNlIGludG8KKyAqIENvb2tpZVN0b3JlLCBhbmQgcmV0cmlldmUgY29va2llcyBmb3IgZXZlcnkgb3V0Z29pbmcgSFRUUCByZXF1ZXN0LkV4cGlyZWQKKyAqIEh0dHBDb29raWVzIHNob3VsZCBiZSByZW1vdmVkIGZyb20gdGhpcyBzdG9yZSBieSB0aGVtc2VsdmVzLgorICoKKyAqIEBzaW5jZSAxLjYKKyAqLworcHVibGljIGludGVyZmFjZSBDb29raWVTdG9yZSB7CisKKyAgICAvKioKKyAgICAgKiBTYXZlcyBhIEhUVFAgY29va2llIHRvIHRoaXMgc3RvcmUuIFRoaXMgaXMgY2FsbGVkIGZvciBldmVyeSBpbmNvbWluZyBIVFRQCisgICAgICogcmVzcG9uc2UuCisgICAgICoKKyAgICAgKiBBIGNvb2tpZSBtYXkgb3IgbWF5IG5vdCBoYXMgYW4gYXNzb2NpYXRlZCBVUkkuIElmIG5vdCwgdGhlIGNvb2tpZSdzCisgICAgICogZG9tYWluIGFuZCBwYXRoIGF0dHJpYnV0ZSB3aWxsIHNob3cgY3JhZGxlbGFuZC4gSWYgdGhlcmUgaXMgYW4KKyAgICAgKiBhc3NvY2lhdGVkIFVSSSBhbmQgbm8gZG9tYWluIGFuZCBwYXRoIGF0dHJpYnV0ZSBhcmUgc3BlaWNpZmVkIGZvciB0aGUKKyAgICAgKiBjb29raWUsIHRoZSBnaXZlbiBVUkkgd2lsbCBpbmRpY2F0ZSB3aGVyZSB0aGlzIGNvb2tpZSBjb21lcyBmcm9tLgorICAgICAqCisgICAgICogSWYgYSBjb29raWUgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gVVJJIGFscmVhZHkgZXhpc3RzLCB0aGVuIGl0IGlzCisgICAgICogcmVwbGFjZWQgd2l0aCB0aGUgbmV3IG9uZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmkKKyAgICAgKiAgICAgICAgICAgIHRoZSB1cmkgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgY29va2llLiBBIG51bGwgdmFsdWUKKyAgICAgKiAgICAgICAgICAgIGluZGljYXRlcyB0aGUgY29va2llIGlzIG5vdCBhc3NvY2lhdGVkIHdpdGggYSBVUkkKKyAgICAgKiBAcGFyYW0gY29va2llCisgICAgICogICAgICAgICAgICB0aGUgY29va2llIHRvIGJlIHN0b3JlZAorICAgICAqLworICAgIHZvaWQgYWRkKFVSSSB1cmksIEh0dHBDb29raWUgY29va2llKTsKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBjb29raWVzIHRoYXQgbWF0Y2ggdGhlIHNwZWNpZmllZCBVUkkuIFJldHVybiBub3QgZXhwaXJlZCBjb29raWVzLgorICAgICAqIEZvciBldmVyeSBvdXRnb2luZyBIVFRQIHJlcXVlc3QsIHRoaXMgbWV0aG9kIHdpbGwgYmUgY2FsbGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHVyaQorICAgICAqICAgICAgICAgICAgdGhlIHVyaSB0aGlzIGNvb2tpZSBhc3NvY2lhdGVkIHdpdGguIElmIG51bGwsIHRoaXMgY29va2llIHdpbGwKKyAgICAgKiAgICAgICAgICAgIG5vdCBiZSBhc3NvY2lhdGVkIHdpdGggYW4gVVJJCisgICAgICogQHJldHVybiBhbiBpbW11dGFibGUgbGlzdCBvZiBIdHRwQ29va2llcywgcmV0dXJuIGVtcHR5IGxpc3QgaWYgbm8gY29va2llcworICAgICAqICAgICAgICAgbWF0Y2ggdGhlIGdpdmVuIFVSSQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB1cmkgaXMgbnVsbAorICAgICAqLworICAgIExpc3Q8SHR0cENvb2tpZT4gZ2V0KFVSSSB1cmkpOworCisgICAgLyoqCisgICAgICogR2V0IGFsbCBjb29raWVzIGluIGNvb2tpZSBzdG9yZSB3aGljaCBhcmUgbm90IGV4cGlyZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGVtcHR5IGxpc3QgaWYgdGhlcmUncyBubyBodHRwIGNvb2tpZSBpbiBzdG9yZSwgb3IgYW4gaW1tdXRhYmxlCisgICAgICogICAgICAgICBsaXN0IG9mIGNvb2tpZXMKKyAgICAgKi8KKyAgICBMaXN0PEh0dHBDb29raWU+IGdldENvb2tpZXMoKTsKKworICAgIC8qKgorICAgICAqIEdldCBhIHNldCBvZiBVUklzLCB3aGljaCBpcyBjb21wb3NlZCBvZiBhc3NvY2lhdGVkIFVSSSB3aXRoIGFsbCB0aGUKKyAgICAgKiBjb29raWVzIGluIHRoZSBzdG9yZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gemVyby1sZW5ndGggbGlzdCBpZiBubyBjb29raWUgaW4gdGhlIHN0b3JlIGlzIGFzc29jaWF0ZWQgd2l0aCBhbnkKKyAgICAgKiAgICAgICAgIFVSSXMsIG90aGVyd2lzZSBhbiBpbW11dGFibGUgbGlzdCBvZiBVUklzLgorICAgICAqLworICAgIExpc3Q8VVJJPiBnZXRVUklzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmUgdGhlIHNwZWNpZmllZCBjb29raWUgZnJvbSB0aGUgc3RvcmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJpCisgICAgICogICAgICAgICAgICB0aGUgdXJpIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGNvb2tpZS4gSWYgdGhlIGNvb2tpZSBpcworICAgICAqICAgICAgICAgICAgbm90IGFzc29jaWF0ZWQgd2l0aCBhbiBVUkkgd2hlbiBhZGRlZCwgdXJpIHNob3VsZCBiZSBudWxsOworICAgICAqICAgICAgICAgICAgb3RoZXJ3aXNlIHRoZSB1cmkgc2hvdWxkIGJlIG5vbi1udWxsLgorICAgICAqIEBwYXJhbSBjb29raWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb29raWUgdG8gYmUgcmVtb3ZlZAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNvb2tpZSBpcyBjb250YWluZWQgaW4gdGhpcyBzdG9yZSBhbmQKKyAgICAgKiAgICAgICAgIHJlbW92ZWQgc3VjY2Vzc2Z1bGx5CisgICAgICovCisgICAgYm9vbGVhbiByZW1vdmUoVVJJIHVyaSwgSHR0cENvb2tpZSBjb29raWUpOworCisgICAgLyoqCisgICAgICogQ2xlYXIgdGhpcyBjb29raWUgc3RvcmUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgYW55IGNvb2tpZXMgd2VyZSByZW1vdmVkIGFzIGEgcmVzdWx0IG9mIHRoaXMgY2FsbC4KKyAgICAgKi8KKyAgICBib29sZWFuIHJlbW92ZUFsbCgpOworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Db29raWVTdG9yZUltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Db29raWVTdG9yZUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNmY3NGE5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0Nvb2tpZVN0b3JlSW1wbC5qYXZhCkBAIC0wLDAgKzEsMTQzIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogQW4gaW4tbWVtb3J5IGNvb2tpZSBzdG9yZS4KKyAqLworZmluYWwgY2xhc3MgQ29va2llU3RvcmVJbXBsIGltcGxlbWVudHMgQ29va2llU3RvcmUgeworCisgICAgLyoqIHRoaXMgbWFwIG1heSBoYXZlIG51bGwga2V5cyEgKi8KKyAgICBwcml2YXRlIGZpbmFsIE1hcDxVUkksIExpc3Q8SHR0cENvb2tpZT4+IG1hcCA9IG5ldyBIYXNoTWFwPFVSSSwgTGlzdDxIdHRwQ29va2llPj4oKTsKKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhZGQoVVJJIHVyaSwgSHR0cENvb2tpZSBjb29raWUpIHsKKyAgICAgICAgaWYgKGNvb2tpZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImNvb2tpZSA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICB1cmkgPSBjb29raWVzVXJpKHVyaSk7CisgICAgICAgIExpc3Q8SHR0cENvb2tpZT4gY29va2llcyA9IG1hcC5nZXQodXJpKTsKKyAgICAgICAgaWYgKGNvb2tpZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgY29va2llcyA9IG5ldyBBcnJheUxpc3Q8SHR0cENvb2tpZT4oKTsKKyAgICAgICAgICAgIG1hcC5wdXQodXJpLCBjb29raWVzKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNvb2tpZXMucmVtb3ZlKGNvb2tpZSk7CisgICAgICAgIH0KKyAgICAgICAgY29va2llcy5hZGQoY29va2llKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFVSSSBjb29raWVzVXJpKFVSSSB1cmkpIHsKKyAgICAgICAgaWYgKHVyaSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBVUkkoImh0dHAiLCB1cmkuZ2V0SG9zdCgpLCBudWxsLCBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoVVJJU3ludGF4RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiB1cmk7IC8vIHByb2JhYmx5IGEgVVJJIHdpdGggbm8gaG9zdAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCBMaXN0PEh0dHBDb29raWU+IGdldChVUkkgdXJpKSB7CisgICAgICAgIGlmICh1cmkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ1cmkgPT0gbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgTGlzdDxIdHRwQ29va2llPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PEh0dHBDb29raWU+KCk7CisKKyAgICAgICAgLy8gZ2V0IGNvb2tpZXMgYXNzb2NpYXRlZCB3aXRoIGdpdmVuIFVSSS4gSWYgbm9uZSwgcmV0dXJucyBhbiBlbXB0eSBsaXN0CisgICAgICAgIExpc3Q8SHR0cENvb2tpZT4gY29va2llc0ZvclVyaSA9IG1hcC5nZXQodXJpKTsKKyAgICAgICAgaWYgKGNvb2tpZXNGb3JVcmkgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChJdGVyYXRvcjxIdHRwQ29va2llPiBpID0gY29va2llc0ZvclVyaS5pdGVyYXRvcigpOyBpLmhhc05leHQoKTsgKSB7CisgICAgICAgICAgICAgICAgSHR0cENvb2tpZSBjb29raWUgPSBpLm5leHQoKTsKKyAgICAgICAgICAgICAgICBpZiAoY29va2llLmhhc0V4cGlyZWQoKSkgeworICAgICAgICAgICAgICAgICAgICBpLnJlbW92ZSgpOyAvLyByZW1vdmUgZXhwaXJlZCBjb29raWVzCisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChjb29raWUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIGdldCBhbGwgY29va2llcyB0aGF0IGRvbWFpbiBtYXRjaGVzIHRoZSBVUkkKKyAgICAgICAgZm9yIChNYXAuRW50cnk8VVJJLCBMaXN0PEh0dHBDb29raWU+PiBlbnRyeSA6IG1hcC5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICBpZiAodXJpLmVxdWFscyhlbnRyeS5nZXRLZXkoKSkpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsgLy8gc2tpcCB0aGUgZ2l2ZW4gVVJJOyB3ZSd2ZSBhbHJlYWR5IGhhbmRsZWQgaXQKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgTGlzdDxIdHRwQ29va2llPiBlbnRyeUNvb2tpZXMgPSBlbnRyeS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgZm9yIChJdGVyYXRvcjxIdHRwQ29va2llPiBpID0gZW50cnlDb29raWVzLml0ZXJhdG9yKCk7IGkuaGFzTmV4dCgpOyApIHsKKyAgICAgICAgICAgICAgICBIdHRwQ29va2llIGNvb2tpZSA9IGkubmV4dCgpOworICAgICAgICAgICAgICAgIGlmICghSHR0cENvb2tpZS5kb21haW5NYXRjaGVzKGNvb2tpZS5nZXREb21haW4oKSwgdXJpLmdldEhvc3QoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChjb29raWUuaGFzRXhwaXJlZCgpKSB7CisgICAgICAgICAgICAgICAgICAgIGkucmVtb3ZlKCk7IC8vIHJlbW92ZSBleHBpcmVkIGNvb2tpZXMKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFyZXN1bHQuY29udGFpbnMoY29va2llKSkgeworICAgICAgICAgICAgICAgICAgICByZXN1bHQuYWRkKGNvb2tpZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVzdWx0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIExpc3Q8SHR0cENvb2tpZT4gZ2V0Q29va2llcygpIHsKKyAgICAgICAgTGlzdDxIdHRwQ29va2llPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PEh0dHBDb29raWU+KCk7CisgICAgICAgIGZvciAoTGlzdDxIdHRwQ29va2llPiBsaXN0IDogbWFwLnZhbHVlcygpKSB7CisgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yPEh0dHBDb29raWU+IGkgPSBsaXN0Lml0ZXJhdG9yKCk7IGkuaGFzTmV4dCgpOyApIHsKKyAgICAgICAgICAgICAgICBIdHRwQ29va2llIGNvb2tpZSA9IGkubmV4dCgpOworICAgICAgICAgICAgICAgIGlmIChjb29raWUuaGFzRXhwaXJlZCgpKSB7CisgICAgICAgICAgICAgICAgICAgIGkucmVtb3ZlKCk7IC8vIHJlbW92ZSBleHBpcmVkIGNvb2tpZXMKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFyZXN1bHQuY29udGFpbnMoY29va2llKSkgeworICAgICAgICAgICAgICAgICAgICByZXN1bHQuYWRkKGNvb2tpZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlc3VsdCk7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCBMaXN0PFVSST4gZ2V0VVJJcygpIHsKKyAgICAgICAgTGlzdDxVUkk+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8VVJJPihtYXAua2V5U2V0KCkpOworICAgICAgICByZXN1bHQucmVtb3ZlKG51bGwpOyAvLyBzaWdoCisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlc3VsdCk7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIHJlbW92ZShVUkkgdXJpLCBIdHRwQ29va2llIGNvb2tpZSkgeworICAgICAgICBpZiAoY29va2llID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiY29va2llID09IG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIExpc3Q8SHR0cENvb2tpZT4gY29va2llcyA9IG1hcC5nZXQoY29va2llc1VyaSh1cmkpKTsKKyAgICAgICAgaWYgKGNvb2tpZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGNvb2tpZXMucmVtb3ZlKGNvb2tpZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gcmVtb3ZlQWxsKCkgeworICAgICAgICBib29sZWFuIHJlc3VsdCA9ICFtYXAuaXNFbXB0eSgpOworICAgICAgICBtYXAuY2xlYXIoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvRGF0YWdyYW1QYWNrZXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9EYXRhZ3JhbVBhY2tldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY2MzU4NWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvRGF0YWdyYW1QYWNrZXQuamF2YQpAQCAtMCwwICsxLDMyNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworLyoqCisgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBkYXRhZ3JhbSBwYWNrZXQgd2hpY2ggY29udGFpbnMgZGF0YSBlaXRoZXIgdG8gYmUgc2VudAorICogb3IgcmVjZWl2ZWQgdGhyb3VnaCBhIHtAY29kZSBEYXRhZ3JhbVNvY2tldH0uIEl0IGhvbGRzIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHN1Y2ggYXMgaXRzIHNvdXJjZSBvciBkZXN0aW5hdGlvbiBob3N0LgorICoKKyAqIEBzZWUgRGF0YWdyYW1Tb2NrZXQKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIERhdGFncmFtUGFja2V0IHsKKworICAgIGJ5dGVbXSBkYXRhOworCisgICAgLyoqCisgICAgICogTGVuZ3RoIG9mIHRoZSBkYXRhIHRvIGJlIHNlbnQgb3Igc2l6ZSBvZiBkYXRhIHRoYXQgd2FzIHJlY2VpdmVkIHZpYQorICAgICAqIERhdGFncmFtU29ja2V0I3JlY2VpdmUoKSBtZXRob2QgY2FsbC4KKyAgICAgKi8KKyAgICBpbnQgbGVuZ3RoOworCisgICAgLyoqCisgICAgICogU2l6ZSBvZiBpbnRlcm5hbCBidWZmZXIgdGhhdCBpcyB1c2VkIHRvIHN0b3JlIHJlY2VpdmVkIGRhdGEuIFNob3VsZCBiZQorICAgICAqIGdyZWF0ZXIgb3IgZXF1YWwgdG8gImxlbmd0aCIgZmllbGQuCisgICAgICovCisgICAgaW50IGNhcGFjaXR5OworCisgICAgSW5ldEFkZHJlc3MgYWRkcmVzczsKKworICAgIGludCBwb3J0ID0gLTE7IC8vIFRoZSBkZWZhdWx0IHBvcnQgbnVtYmVyIGlzIC0xCisKKyAgICBpbnQgb2Zmc2V0ID0gMDsKKworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRGF0YWdyYW1QYWNrZXR9IG9iamVjdCB0byByZWNlaXZlIGRhdGEgdXAgdG8KKyAgICAgKiB7QGNvZGUgbGVuZ3RofSBieXRlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICBhIGJ5dGUgYXJyYXkgdG8gc3RvcmUgdGhlIHJlYWQgY2hhcmFjdGVycy4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YWdyYW1QYWNrZXQoYnl0ZVtdIGRhdGEsIGludCBsZW5ndGgpIHsKKyAgICAgICAgdGhpcyhkYXRhLCAwLCBsZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIERhdGFncmFtUGFja2V0fSBvYmplY3QgdG8gcmVjZWl2ZSBkYXRhIHVwIHRvCisgICAgICoge0Bjb2RlIGxlbmd0aH0gYnl0ZXMgd2l0aCBhIHNwZWNpZmllZCBidWZmZXIgb2Zmc2V0LgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIGEgYnl0ZSBhcnJheSB0byBzdG9yZSB0aGUgcmVhZCBjaGFyYWN0ZXJzLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgb2YgdGhlIGJ5dGUgYXJyYXkgd2hlcmUgdGhlIGJ5dGVzIGlzIHdyaXR0ZW4uCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YWdyYW1QYWNrZXQoYnl0ZVtdIGRhdGEsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICAgICAgc2V0RGF0YShkYXRhLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRGF0YWdyYW1QYWNrZXR9IG9iamVjdCB0byBzZW5kIGRhdGEgdG8gdGhlIHBvcnQKKyAgICAgKiB7QGNvZGUgYVBvcnR9IG9mIHRoZSBhZGRyZXNzIHtAY29kZSBob3N0fS4gVGhlIHtAY29kZSBsZW5ndGh9IG11c3QgYmUKKyAgICAgKiBsZXNzZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgc2l6ZSBvZiB7QGNvZGUgZGF0YX0uIFRoZSBmaXJzdCB7QGNvZGUKKyAgICAgKiBsZW5ndGh9IGJ5dGVzIGZyb20gdGhlIGJ5dGUgYXJyYXkgcG9zaXRpb24ge0Bjb2RlIG9mZnNldH0gYXJlIHNlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgYSBieXRlIGFycmF5IHdoaWNoIHN0b3JlcyB0aGUgY2hhcmFjdGVycyB0byBiZSBzZW50LgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgb2Yge0Bjb2RlIGRhdGF9IHdoZXJlIHRvIHJlYWQgZnJvbS4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIGRhdGEuCisgICAgICogQHBhcmFtIGhvc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBhZGRyZXNzIG9mIHRoZSB0YXJnZXQgaG9zdC4KKyAgICAgKiBAcGFyYW0gYVBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IG9mIHRoZSB0YXJnZXQgaG9zdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YWdyYW1QYWNrZXQoYnl0ZVtdIGRhdGEsIGludCBvZmZzZXQsIGludCBsZW5ndGgsCisgICAgICAgICAgICBJbmV0QWRkcmVzcyBob3N0LCBpbnQgYVBvcnQpIHsKKyAgICAgICAgdGhpcyhkYXRhLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIHNldFBvcnQoYVBvcnQpOworICAgICAgICBhZGRyZXNzID0gaG9zdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBEYXRhZ3JhbVBhY2tldH0gb2JqZWN0IHRvIHNlbmQgZGF0YSB0byB0aGUgcG9ydAorICAgICAqIHtAY29kZSBhUG9ydH0gb2YgdGhlIGFkZHJlc3Mge0Bjb2RlIGhvc3R9LiBUaGUge0Bjb2RlIGxlbmd0aH0gbXVzdCBiZQorICAgICAqIGxlc3NlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBzaXplIG9mIHtAY29kZSBkYXRhfS4gVGhlIGZpcnN0IHtAY29kZQorICAgICAqIGxlbmd0aH0gYnl0ZXMgYXJlIHNlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgYSBieXRlIGFycmF5IHdoaWNoIHN0b3JlcyB0aGUgY2hhcmFjdGVycyB0byBiZSBzZW50LgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgZGF0YS4KKyAgICAgKiBAcGFyYW0gaG9zdAorICAgICAqICAgICAgICAgICAgdGhlIGFkZHJlc3Mgb2YgdGhlIHRhcmdldCBob3N0LgorICAgICAqIEBwYXJhbSBwb3J0CisgICAgICogICAgICAgICAgICB0aGUgcG9ydCBvZiB0aGUgdGFyZ2V0IGhvc3QuCisgICAgICovCisgICAgcHVibGljIERhdGFncmFtUGFja2V0KGJ5dGVbXSBkYXRhLCBpbnQgbGVuZ3RoLCBJbmV0QWRkcmVzcyBob3N0LCBpbnQgcG9ydCkgeworICAgICAgICB0aGlzKGRhdGEsIDAsIGxlbmd0aCwgaG9zdCwgcG9ydCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2VuZGVyIG9yIGRlc3RpbmF0aW9uIElQIGFkZHJlc3Mgb2YgdGhpcyBkYXRhZ3JhbSBwYWNrZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBhZGRyZXNzIGZyb20gd2hlcmUgdGhlIGRhdGFncmFtIHdhcyByZWNlaXZlZCBvciB0byB3aGljaCBpdAorICAgICAqICAgICAgICAgaXMgc2VudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEluZXRBZGRyZXNzIGdldEFkZHJlc3MoKSB7CisgICAgICAgIHJldHVybiBhZGRyZXNzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgb2YgdGhpcyBkYXRhZ3JhbSBwYWNrZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZWNlaXZlZCBkYXRhIG9yIHRoZSBkYXRhIHRvIGJlIHNlbnQuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBieXRlW10gZ2V0RGF0YSgpIHsKKyAgICAgICAgcmV0dXJuIGRhdGE7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhIHN0b3JlZCBpbiB0aGlzIGRhdGFncmFtIHBhY2tldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgcmVjZWl2ZWQgZGF0YSBvciB0aGUgZGF0YSB0byBiZSBzZW50LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldExlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBvZmZzZXQgb2YgdGhlIGRhdGEgc3RvcmVkIGluIHRoaXMgZGF0YWdyYW0gcGFja2V0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcG9zaXRpb24gb2YgdGhlIHJlY2VpdmVkIGRhdGEgb3IgdGhlIGRhdGEgdG8gYmUgc2VudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBvZmZzZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcG9ydCBudW1iZXIgb2YgdGhlIHRhcmdldCBvciBzZW5kZXIgaG9zdCBvZiB0aGlzIGRhdGFncmFtCisgICAgICogcGFja2V0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcG9ydCBudW1iZXIgb2YgdGhlIG9yaWdpbiBvciB0YXJnZXQgaG9zdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRQb3J0KCkgeworICAgICAgICByZXR1cm4gcG9ydDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBJUCBhZGRyZXNzIG9mIHRoZSB0YXJnZXQgaG9zdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhZGRyCisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IGhvc3QgYWRkcmVzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0QWRkcmVzcyhJbmV0QWRkcmVzcyBhZGRyKSB7CisgICAgICAgIGFkZHJlc3MgPSBhZGRyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRhdGEgYnVmZmVyIGZvciB0aGlzIGRhdGFncmFtIHBhY2tldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0RGF0YShieXRlW10gZGF0YSwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCkgeworICAgICAgICBpZiAoKG9mZnNldCB8IGJ5dGVDb3VudCkgPCAwIHx8IG9mZnNldCA+IGRhdGEubGVuZ3RoIHx8IGJ5dGVDb3VudCA+IGRhdGEubGVuZ3RoIC0gb2Zmc2V0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5kYXRhID0gZGF0YTsKKyAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7CisgICAgICAgIHRoaXMubGVuZ3RoID0gYnl0ZUNvdW50OworICAgICAgICB0aGlzLmNhcGFjaXR5ID0gYnl0ZUNvdW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRhdGEgYnVmZmVyIGZvciB0aGlzIGRhdGFncmFtIHBhY2tldC4gVGhlIGxlbmd0aCBvZiB0aGUgZGF0YWdyYW0KKyAgICAgKiBwYWNrZXQgaXMgc2V0IHRvIHRoZSBidWZmZXIgbGVuZ3RoLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZgorICAgICAqICAgICAgICAgICAgdGhlIGJ1ZmZlciB0byBzdG9yZSB0aGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0RGF0YShieXRlW10gYnVmKSB7CisgICAgICAgIGxlbmd0aCA9IGJ1Zi5sZW5ndGg7IC8vIFRoaXMgd2lsbCBjaGVjayBmb3IgbnVsbAorICAgICAgICBjYXBhY2l0eSA9IGJ1Zi5sZW5ndGg7CisgICAgICAgIGRhdGEgPSBidWY7CisgICAgICAgIG9mZnNldCA9IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY3VycmVudCBjYXBhY2l0eSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgY2FwYWNpdHkgdmFsdWUKKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgaW50IGdldENhcGFjaXR5KCkgeworICAgICAgICByZXR1cm4gY2FwYWNpdHk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhZ3JhbSBwYWNrZXQuIFRoaXMgbGVuZ3RoIHBsdXMgdGhlIG9mZnNldCBtdXN0CisgICAgICogYmUgbGVzc2VyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGJ1ZmZlciBzaXplLgorICAgICAqCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGlzIGRhdGFncmFtIHBhY2tldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0TGVuZ3RoKGludCBsZW5ndGgpIHsKKyAgICAgICAgc2V0TGVuZ3RoT25seShsZW5ndGgpOworICAgICAgICB0aGlzLmNhcGFjaXR5ID0gbGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFuIGFsdGVybmF0aXZlIHRvIHtAbGluayAjc2V0TGVuZ3RoKGludCl9LCB0aGF0IGRvZXNuJ3QgcmVzZXQgdGhlIHtAbGluayAjY2FwYWNpdHl9CisgICAgICogZmllbGQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGVuIHRoZSBsZW5ndGggb2YgdGhpcyBkYXRhZ3JhbSBwYWNrZXQKKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgdm9pZCBzZXRMZW5ndGhPbmx5KGludCBsZW5ndGgpIHsKKyAgICAgICAgaWYgKGxlbmd0aCA8IDAgfHwgb2Zmc2V0ICsgbGVuZ3RoID4gZGF0YS5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJsZW5ndGg9IiArIGxlbmd0aCArICIsIG9mZnNldD0iICsgb2Zmc2V0ICsKKyAgICAgICAgICAgICAgICAgICAgIiwgYnVmZmVyIHNpemU9IiArIGRhdGEubGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwb3J0IG51bWJlciBvZiB0aGUgdGFyZ2V0IGhvc3Qgb2YgdGhpcyBkYXRhZ3JhbSBwYWNrZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYVBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgaG9zdCBwb3J0IG51bWJlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0UG9ydChpbnQgYVBvcnQpIHsKKyAgICAgICAgaWYgKGFQb3J0IDwgMCB8fCBhUG9ydCA+IDY1NTM1KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQb3J0IG91dCBvZiByYW5nZTogIiArIGFQb3J0KTsKKyAgICAgICAgfQorICAgICAgICBwb3J0ID0gYVBvcnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRGF0YWdyYW1QYWNrZXR9IG9iamVjdCB0byBzZW5kIGRhdGEgdG8gdGhlCisgICAgICogYWRkcmVzcyB7QGNvZGUgc29ja0FkZHJ9LiBUaGUge0Bjb2RlIGxlbmd0aH0gbXVzdCBiZSBsZXNzZXIgdGhhbiBvciBlcXVhbAorICAgICAqIHRvIHRoZSBzaXplIG9mIHtAY29kZSBkYXRhfS4gVGhlIGZpcnN0IHtAY29kZSBsZW5ndGh9IGJ5dGVzIG9mIHRoZSBkYXRhCisgICAgICogYXJlIHNlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYXJyYXkgdG8gc3RvcmUgdGhlIGRhdGEuCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YS4KKyAgICAgKiBAcGFyYW0gc29ja0FkZHIKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgaG9zdCBhZGRyZXNzIGFuZCBwb3J0LgorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3IgaW4gdGhlIHVuZGVybHlpbmcgcHJvdG9jb2wgb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBEYXRhZ3JhbVBhY2tldChieXRlW10gZGF0YSwgaW50IGxlbmd0aCwgU29ja2V0QWRkcmVzcyBzb2NrQWRkcikgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoZGF0YSwgMCwgbGVuZ3RoKTsKKyAgICAgICAgc2V0U29ja2V0QWRkcmVzcyhzb2NrQWRkcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRGF0YWdyYW1QYWNrZXR9IG9iamVjdCB0byBzZW5kIGRhdGEgdG8gdGhlCisgICAgICogYWRkcmVzcyB7QGNvZGUgc29ja0FkZHJ9LiBUaGUge0Bjb2RlIGxlbmd0aH0gbXVzdCBiZSBsZXNzZXIgdGhhbiBvciBlcXVhbAorICAgICAqIHRvIHRoZSBzaXplIG9mIHtAY29kZSBkYXRhfS4gVGhlIGZpcnN0IHtAY29kZSBsZW5ndGh9IGJ5dGVzIG9mIHRoZSBkYXRhCisgICAgICogYXJlIHNlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYXJyYXkgdG8gc3RvcmUgdGhlIGRhdGEuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvZiB0aGUgZGF0YS4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhLgorICAgICAqIEBwYXJhbSBzb2NrQWRkcgorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBob3N0IGFkZHJlc3MgYW5kIHBvcnQuCisgICAgICogQHRocm93cyBTb2NrZXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBpbiB0aGUgdW5kZXJseWluZyBwcm90b2NvbCBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIERhdGFncmFtUGFja2V0KGJ5dGVbXSBkYXRhLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoLAorICAgICAgICAgICAgU29ja2V0QWRkcmVzcyBzb2NrQWRkcikgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoZGF0YSwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICBzZXRTb2NrZXRBZGRyZXNzKHNvY2tBZGRyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBob3N0IGFkZHJlc3MgYW5kIHRoZSBwb3J0IHRvIHdoaWNoIHRoaXMgZGF0YWdyYW0gcGFja2V0IGlzIHNlbnQKKyAgICAgKiBhcyBhIHtAY29kZSBTb2NrZXRBZGRyZXNzfSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBTb2NrZXRBZGRyZXNzIG9mIHRoZSB0YXJnZXQgaG9zdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFNvY2tldEFkZHJlc3MgZ2V0U29ja2V0QWRkcmVzcygpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBJbmV0U29ja2V0QWRkcmVzcyhnZXRBZGRyZXNzKCksIGdldFBvcnQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUge0Bjb2RlIFNvY2tldEFkZHJlc3N9IGZvciB0aGlzIGRhdGFncmFtIHBhY2tldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzb2NrQWRkcgorICAgICAqICAgICAgICAgICAgdGhlIFNvY2tldEFkZHJlc3Mgb2YgdGhlIHRhcmdldCBob3N0LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRTb2NrZXRBZGRyZXNzKFNvY2tldEFkZHJlc3Mgc29ja0FkZHIpIHsKKyAgICAgICAgaWYgKCEoc29ja0FkZHIgaW5zdGFuY2VvZiBJbmV0U29ja2V0QWRkcmVzcykpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlNvY2tldCBhZGRyZXNzIG5vdCBhbiBJbmV0U29ja2V0QWRkcmVzczogIiArCisgICAgICAgICAgICAgICAgICAgIChzb2NrQWRkciA9PSBudWxsID8gbnVsbCA6IHNvY2tBZGRyLmdldENsYXNzKCkpKTsKKyAgICAgICAgfQorICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBpbmV0QWRkciA9IChJbmV0U29ja2V0QWRkcmVzcykgc29ja0FkZHI7CisgICAgICAgIGlmIChpbmV0QWRkci5pc1VucmVzb2x2ZWQoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiU29ja2V0IGFkZHJlc3MgdW5yZXNvbHZlZDogIiArIHNvY2tBZGRyKTsKKyAgICAgICAgfQorICAgICAgICBwb3J0ID0gaW5ldEFkZHIuZ2V0UG9ydCgpOworICAgICAgICBhZGRyZXNzID0gaW5ldEFkZHIuZ2V0QWRkcmVzcygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9EYXRhZ3JhbVNvY2tldC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0RhdGFncmFtU29ja2V0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDg3YTE4YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9EYXRhZ3JhbVNvY2tldC5qYXZhCkBAIC0wLDAgKzEsNjYyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkRhdGFncmFtQ2hhbm5lbDsKK2ltcG9ydCBsaWJjb3JlLmlvLkVycm5vRXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUuaW8uTGliY29yZTsKK2ltcG9ydCBzdGF0aWMgbGliY29yZS5pby5Pc0NvbnN0YW50cy4qOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIFVEUCBzb2NrZXQgZm9yIHNlbmRpbmcgYW5kIHJlY2VpdmluZyB7QGNvZGUKKyAqIERhdGFncmFtUGFja2V0fS4gQSB7QGNvZGUgRGF0YWdyYW1Tb2NrZXR9IG9iamVjdCBjYW4gYmUgdXNlZCBmb3IgYm90aAorICogZW5kcG9pbnRzIG9mIGEgY29ubmVjdGlvbiBmb3IgYSBwYWNrZXQgZGVsaXZlcnkgc2VydmljZS4KKyAqCisgKiBAc2VlIERhdGFncmFtUGFja2V0CisgKiBAc2VlIERhdGFncmFtU29ja2V0SW1wbEZhY3RvcnkKKyAqLworcHVibGljIGNsYXNzIERhdGFncmFtU29ja2V0IHsKKworICAgIERhdGFncmFtU29ja2V0SW1wbCBpbXBsOworCisgICAgSW5ldEFkZHJlc3MgYWRkcmVzczsKKworICAgIGludCBwb3J0ID0gLTE7CisKKyAgICBzdGF0aWMgRGF0YWdyYW1Tb2NrZXRJbXBsRmFjdG9yeSBmYWN0b3J5OworCisgICAgYm9vbGVhbiBpc0JvdW5kID0gZmFsc2U7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNDb25uZWN0ZWQgPSBmYWxzZTsKKworICAgIHByaXZhdGUgU29ja2V0RXhjZXB0aW9uIHBlbmRpbmdDb25uZWN0RXhjZXB0aW9uOworCisgICAgcHJpdmF0ZSBib29sZWFuIGlzQ2xvc2VkID0gZmFsc2U7CisKKyAgICBwcml2YXRlIE9iamVjdCBsb2NrID0gbmV3IE9iamVjdCgpOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIFVEUCBkYXRhZ3JhbSBzb2NrZXQgd2hpY2ggaXMgYm91bmQgdG8gYW55IGF2YWlsYWJsZSBwb3J0IG9uCisgICAgICogdGhlIGxvY2FsaG9zdC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNyZWF0aW5nIG9yIGJpbmRpbmcgdGhlIHNvY2tldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YWdyYW1Tb2NrZXQoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcygwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgVURQIGRhdGFncmFtIHNvY2tldCB3aGljaCBpcyBib3VuZCB0byB0aGUgc3BlY2lmaWMgcG9ydAorICAgICAqIHtAY29kZSBhUG9ydH0gb24gdGhlIGxvY2FsaG9zdC4gVmFsaWQgdmFsdWVzIGZvciB7QGNvZGUgYVBvcnR9IGFyZQorICAgICAqIGJldHdlZW4gMCBhbmQgNjU1MzUgaW5jbHVzaXZlLgorICAgICAqCisgICAgICogQHBhcmFtIGFQb3J0CisgICAgICogICAgICAgICAgICB0aGUgcG9ydCB0byBiaW5kIG9uIHRoZSBsb2NhbGhvc3QuCisgICAgICogQHRocm93cyBTb2NrZXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY3JlYXRpbmcgb3IgYmluZGluZyB0aGUgc29ja2V0LgorICAgICAqLworICAgIHB1YmxpYyBEYXRhZ3JhbVNvY2tldChpbnQgYVBvcnQpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBjaGVja1BvcnQoYVBvcnQpOworICAgICAgICBjcmVhdGVTb2NrZXQoYVBvcnQsIEluZXQ0QWRkcmVzcy5BTlkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBVRFAgZGF0YWdyYW0gc29ja2V0IHdoaWNoIGlzIGJvdW5kIHRvIHRoZSBzcGVjaWZpYyBsb2NhbAorICAgICAqIGFkZHJlc3Mge0Bjb2RlIGFkZHJ9IG9uIHBvcnQge0Bjb2RlIGFQb3J0fS4gVmFsaWQgdmFsdWVzIGZvciB7QGNvZGUKKyAgICAgKiBhUG9ydH0gYXJlIGJldHdlZW4gMCBhbmQgNjU1MzUgaW5jbHVzaXZlLgorICAgICAqCisgICAgICogQHBhcmFtIGFQb3J0CisgICAgICogICAgICAgICAgICB0aGUgcG9ydCB0byBiaW5kIG9uIHRoZSBsb2NhbGhvc3QuCisgICAgICogQHBhcmFtIGFkZHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBhZGRyZXNzIHRvIGJpbmQgb24gdGhlIGxvY2FsaG9zdC4KKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjcmVhdGluZyBvciBiaW5kaW5nIHRoZSBzb2NrZXQuCisgICAgICovCisgICAgcHVibGljIERhdGFncmFtU29ja2V0KGludCBhUG9ydCwgSW5ldEFkZHJlc3MgYWRkcikgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrUG9ydChhUG9ydCk7CisgICAgICAgIGNyZWF0ZVNvY2tldChhUG9ydCwgKGFkZHIgPT0gbnVsbCkgPyBJbmV0NEFkZHJlc3MuQU5ZIDogYWRkcik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrUG9ydChpbnQgYVBvcnQpIHsKKyAgICAgICAgaWYgKGFQb3J0IDwgMCB8fCBhUG9ydCA+IDY1NTM1KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQb3J0IG91dCBvZiByYW5nZTogIiArIGFQb3J0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGlzIFVEUCBkYXRhZ3JhbSBzb2NrZXQgYW5kIGFsbCBwb3NzaWJseSBhc3NvY2lhdGVkIGNoYW5uZWxzLgorICAgICAqLworICAgIC8vIEluIHRoZSBkb2N1bWVudGF0aW9uIGpkazEuMS43YS9ndWlkZS9uZXQvbWlzY05ldC5odG1sLCB0aGlzIG1ldGhvZCBpcworICAgIC8vIG5vdGVkIGFzIG5vdCBiZWluZyBzeW5jaHJvbml6ZWQuCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgIGlzQ2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgaW1wbC5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERpc2Nvbm5lY3RzIHRoaXMgVURQIGRhdGFncmFtIHNvY2tldCBmcm9tIHRoZSByZW1vdGUgaG9zdC4gVGhpcyBtZXRob2QKKyAgICAgKiBjYWxsZWQgb24gYW4gdW5jb25uZWN0ZWQgc29ja2V0IGRvZXMgbm90aGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkaXNjb25uZWN0KCkgeworICAgICAgICBpZiAoaXNDbG9zZWQoKSB8fCAhaXNDb25uZWN0ZWQoKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGltcGwuZGlzY29ubmVjdCgpOworICAgICAgICBhZGRyZXNzID0gbnVsbDsKKyAgICAgICAgcG9ydCA9IC0xOworICAgICAgICBpc0Nvbm5lY3RlZCA9IGZhbHNlOworICAgIH0KKworICAgIHN5bmNocm9uaXplZCB2b2lkIGNyZWF0ZVNvY2tldChpbnQgYVBvcnQsIEluZXRBZGRyZXNzIGFkZHIpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBpbXBsID0gZmFjdG9yeSAhPSBudWxsID8gZmFjdG9yeS5jcmVhdGVEYXRhZ3JhbVNvY2tldEltcGwoKQorICAgICAgICAgICAgICAgIDogbmV3IFBsYWluRGF0YWdyYW1Tb2NrZXRJbXBsKCk7CisgICAgICAgIGltcGwuY3JlYXRlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbXBsLmJpbmQoYVBvcnQsIGFkZHIpOworICAgICAgICAgICAgaXNCb3VuZCA9IHRydWU7CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBjbG9zZSgpOworICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHtAY29kZSBJbmV0QWRkcmVzc30gaW5zdGFuY2UgcmVwcmVzZW50aW5nIHRoZSByZW1vdGUgYWRkcmVzcyB0bworICAgICAqIHdoaWNoIHRoaXMgVURQIGRhdGFncmFtIHNvY2tldCBpcyBjb25uZWN0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZW1vdGUgYWRkcmVzcyB0aGlzIHNvY2tldCBpcyBjb25uZWN0ZWQgdG8gb3Ige0Bjb2RlIG51bGx9IGlmCisgICAgICogICAgICAgICB0aGlzIHNvY2tldCBpcyBub3QgY29ubmVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyBJbmV0QWRkcmVzcyBnZXRJbmV0QWRkcmVzcygpIHsKKyAgICAgICAgcmV0dXJuIGFkZHJlc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUge0Bjb2RlIEluZXRBZGRyZXNzfSBpbnN0YW5jZSByZXByZXNlbnRpbmcgdGhlIGJvdW5kIGxvY2FsCisgICAgICogYWRkcmVzcyBvZiB0aGlzIFVEUCBkYXRhZ3JhbSBzb2NrZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsb2NhbCBhZGRyZXNzIHRvIHdoaWNoIHRoaXMgc29ja2V0IGlzIGJvdW5kIHRvIG9yIHtAY29kZQorICAgICAqICAgICAgICAgbnVsbH0gaWYgdGhpcyBzb2NrZXQgaXMgY2xvc2VkLgorICAgICAqLworICAgIHB1YmxpYyBJbmV0QWRkcmVzcyBnZXRMb2NhbEFkZHJlc3MoKSB7CisgICAgICAgIGlmIChpc0Nsb3NlZCgpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoIWlzQm91bmQoKSkgeworICAgICAgICAgICAgcmV0dXJuIEluZXQ0QWRkcmVzcy5BTlk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGltcGwuZ2V0TG9jYWxBZGRyZXNzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9jYWwgcG9ydCB3aGljaCB0aGlzIHNvY2tldCBpcyBib3VuZCB0by4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxvY2FsIHBvcnQgb2YgdGhpcyBzb2NrZXQgb3Ige0Bjb2RlIC0xfSBpZiB0aGlzIHNvY2tldCBpcworICAgICAqICAgICAgICAgY2xvc2VkIGFuZCB7QGNvZGUgMH0gaWYgaXQgaXMgdW5ib3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExvY2FsUG9ydCgpIHsKKyAgICAgICAgaWYgKGlzQ2xvc2VkKCkpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIWlzQm91bmQoKSkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGltcGwuZ2V0TG9jYWxQb3J0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcmVtb3RlIHBvcnQgd2hpY2ggdGhpcyBzb2NrZXQgaXMgY29ubmVjdGVkIHRvLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVtb3RlIHBvcnQgb2YgdGhpcyBzb2NrZXQuIFRoZSByZXR1cm4gdmFsdWUge0Bjb2RlIC0xfQorICAgICAqICAgICAgICAgaW5kaWNhdGVzIHRoYXQgdGhpcyBzb2NrZXQgaXMgbm90IGNvbm5lY3RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFBvcnQoKSB7CisgICAgICAgIHJldHVybiBwb3J0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgc29ja2V0IGlzIG11bHRpY2FzdCBvciBub3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZXR1cm4gdmFsdWUgaXMgYWx3YXlzIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgYm9vbGVhbiBpc011bHRpY2FzdFNvY2tldCgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBzb2NrZXQncyB7QGxpbmsgU29ja2V0T3B0aW9ucyNTT19SQ1ZCVUYgcmVjZWl2ZSBidWZmZXIgc2l6ZX0uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0UmVjZWl2ZUJ1ZmZlclNpemUoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIHJldHVybiAoKEludGVnZXIpIGltcGwuZ2V0T3B0aW9uKFNvY2tldE9wdGlvbnMuU09fUkNWQlVGKSkuaW50VmFsdWUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgc29ja2V0J3Mge0BsaW5rIFNvY2tldE9wdGlvbnMjU09fU05EQlVGIHNlbmQgYnVmZmVyIHNpemV9LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldFNlbmRCdWZmZXJTaXplKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICByZXR1cm4gKChJbnRlZ2VyKSBpbXBsLmdldE9wdGlvbihTb2NrZXRPcHRpb25zLlNPX1NOREJVRikpLmludFZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc29ja2V0IHtAbGluayBTb2NrZXRPcHRpb25zI1NPX1RJTUVPVVQgcmVjZWl2ZSB0aW1lb3V0fS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGdldHRpbmcgdGhlIG9wdGlvbiB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRTb1RpbWVvdXQoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIHJldHVybiAoKEludGVnZXIpIGltcGwuZ2V0T3B0aW9uKFNvY2tldE9wdGlvbnMuU09fVElNRU9VVCkpLmludFZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVjZWl2ZXMgYSBwYWNrZXQgZnJvbSB0aGlzIHNvY2tldCBhbmQgc3RvcmVzIGl0IGluIHRoZSBhcmd1bWVudCB7QGNvZGUKKyAgICAgKiBwYWNrfS4gQWxsIGZpZWxkcyBvZiB7QGNvZGUgcGFja30gbXVzdCBiZSBzZXQgYWNjb3JkaW5nIHRvIHRoZSBkYXRhCisgICAgICogcmVjZWl2ZWQuIElmIHRoZSByZWNlaXZlZCBkYXRhIGlzIGxvbmdlciB0aGFuIHRoZSBwYWNrZXQgYnVmZmVyIHNpemUgaXQKKyAgICAgKiBpcyB0cnVuY2F0ZWQuIFRoaXMgbWV0aG9kIGJsb2NrcyB1bnRpbCBhIHBhY2tldCBpcyByZWNlaXZlZCBvciBhIHRpbWVvdXQKKyAgICAgKiBoYXMgZXhwaXJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYWNrCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIERhdGFncmFtUGFja2V0fSB0byBzdG9yZSB0aGUgcmVjZWl2ZWQgZGF0YS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlY2VpdmluZyB0aGUgcGFja2V0LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZWNlaXZlKERhdGFncmFtUGFja2V0IHBhY2spIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBlbnN1cmVCb3VuZCgpOworICAgICAgICBpZiAocGFjayA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocGVuZGluZ0Nvbm5lY3RFeGNlcHRpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbigiUGVuZGluZyBjb25uZWN0IGZhaWx1cmUiLCBwZW5kaW5nQ29ubmVjdEV4Y2VwdGlvbik7CisgICAgICAgIH0KKworICAgICAgICBwYWNrLnNldExlbmd0aChwYWNrLmdldENhcGFjaXR5KCkpOworICAgICAgICBpbXBsLnJlY2VpdmUocGFjayk7CisgICAgICAgIC8vIHBhY2sncyBsZW5ndGggZmllbGQgaXMgbm93IHVwZGF0ZWQgYnkgbmF0aXZlIGNvZGUgY2FsbDsKKyAgICAgICAgLy8gcGFjaydzIGNhcGFjaXR5IGZpZWxkIGlzIHVuY2hhbmdlZAorICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmRzIGEgcGFja2V0IG92ZXIgdGhpcyBzb2NrZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFjaworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBEYXRhZ3JhbVBhY2tldH0gd2hpY2ggaGFzIHRvIGJlIHNlbnQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBzZW5kaW5nIHRoZSBwYWNrZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2VuZChEYXRhZ3JhbVBhY2tldCBwYWNrKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgZW5zdXJlQm91bmQoKTsKKworICAgICAgICBJbmV0QWRkcmVzcyBwYWNrQWRkciA9IHBhY2suZ2V0QWRkcmVzcygpOworICAgICAgICBpZiAoYWRkcmVzcyAhPSBudWxsKSB7IC8vIFRoZSBzb2NrZXQgaXMgY29ubmVjdGVkCisgICAgICAgICAgICBpZiAocGFja0FkZHIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmICghYWRkcmVzcy5lcXVhbHMocGFja0FkZHIpIHx8IHBvcnQgIT0gcGFjay5nZXRQb3J0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiUGFja2V0IGFkZHJlc3MgbWlzbWF0Y2ggd2l0aCBjb25uZWN0ZWQgYWRkcmVzcyIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcGFjay5zZXRBZGRyZXNzKGFkZHJlc3MpOworICAgICAgICAgICAgICAgIHBhY2suc2V0UG9ydChwb3J0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIG5vdCBjb25uZWN0ZWQgc28gdGhlIHRhcmdldCBhZGRyZXNzIGlzIG5vdCBhbGxvd2VkIHRvIGJlIG51bGwKKyAgICAgICAgICAgIGlmIChwYWNrQWRkciA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJEZXN0aW5hdGlvbiBhZGRyZXNzIGlzIG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpbXBsLnNlbmQocGFjayk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmV0d29yayBpbnRlcmZhY2UgdXNlZCBieSB0aGlzIHNvY2tldC4gIEFueSBwYWNrZXRzIHNlbnQKKyAgICAgKiB2aWEgdGhpcyBzb2NrZXQgYXJlIHRyYW5zbWl0dGVkIHZpYSB0aGUgc3BlY2lmaWVkIGludGVyZmFjZS4gIEFueQorICAgICAqIHBhY2tldHMgcmVjZWl2ZWQgYnkgdGhpcyBzb2NrZXQgd2lsbCBjb21lIGZyb20gdGhlIHNwZWNpZmllZAorICAgICAqIGludGVyZmFjZS4gIEJyb2FkY2FzdCBkYXRhZ3JhbXMgcmVjZWl2ZWQgb24gdGhpcyBpbnRlcmZhY2Ugd2lsbAorICAgICAqIGJlIHByb2Nlc3NlZCBieSB0aGlzIHNvY2tldC4gVGhpcyBjb3JyZXNwb25kcyB0byBMaW51eCdzIFNPX0JJTkRUT0RFVklDRS4KKyAgICAgKgorICAgICAqIEBoaWRlIHVzZWQgYnkgR29vZ2xlVFYgZm9yIERIQ1AKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROZXR3b3JrSW50ZXJmYWNlKE5ldHdvcmtJbnRlcmZhY2UgbmV0SW50ZXJmYWNlKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG5ldEludGVyZmFjZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm5ldHdvcmtJbnRlcmZhY2UgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMaWJjb3JlLm9zLnNldHNvY2tvcHRJZnJlcShpbXBsLmZkLCBTT0xfU09DS0VULCBTT19CSU5EVE9ERVZJQ0UsIG5ldEludGVyZmFjZS5nZXROYW1lKCkpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzU29ja2V0RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoaXMgc29ja2V0J3Mge0BsaW5rIFNvY2tldE9wdGlvbnMjU09fU05EQlVGIHNlbmQgYnVmZmVyIHNpemV9LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRTZW5kQnVmZmVyU2l6ZShpbnQgc2l6ZSkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzaXplIDwgMSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigic2l6ZSA8IDEiKTsKKyAgICAgICAgfQorICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgaW1wbC5zZXRPcHRpb24oU29ja2V0T3B0aW9ucy5TT19TTkRCVUYsIEludGVnZXIudmFsdWVPZihzaXplKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGlzIHNvY2tldCdzIHtAbGluayBTb2NrZXRPcHRpb25zI1NPX1NOREJVRiByZWNlaXZlIGJ1ZmZlciBzaXplfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0UmVjZWl2ZUJ1ZmZlclNpemUoaW50IHNpemUpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBpZiAoc2l6ZSA8IDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInNpemUgPCAxIik7CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIGltcGwuc2V0T3B0aW9uKFNvY2tldE9wdGlvbnMuU09fUkNWQlVGLCBJbnRlZ2VyLnZhbHVlT2Yoc2l6ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHtAbGluayBTb2NrZXRPcHRpb25zI1NPX1RJTUVPVVQgcmVhZCB0aW1lb3V0fSBpbiBtaWxsaXNlY29uZHMgZm9yIHRoaXMgc29ja2V0LgorICAgICAqIFRoaXMgcmVjZWl2ZSB0aW1lb3V0IGRlZmluZXMgdGhlIHBlcmlvZCB0aGUgc29ja2V0IHdpbGwgYmxvY2sgd2FpdGluZyB0bworICAgICAqIHJlY2VpdmUgZGF0YSBiZWZvcmUgdGhyb3dpbmcgYW4ge0Bjb2RlIEludGVycnVwdGVkSU9FeGNlcHRpb259LiBUaGUgdmFsdWUKKyAgICAgKiB7QGNvZGUgMH0gKGRlZmF1bHQpIGlzIHVzZWQgdG8gc2V0IGFuIGluZmluaXRlIHRpbWVvdXQuIFRvIGhhdmUgZWZmZWN0CisgICAgICogdGhpcyBvcHRpb24gbXVzdCBiZSBzZXQgYmVmb3JlIHRoZSBibG9ja2luZyBtZXRob2Qgd2FzIGNhbGxlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aW1lb3V0IHRoZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyBvciAwIGZvciBubyB0aW1lb3V0LgorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHNldHRpbmcgdGhlIG9wdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0U29UaW1lb3V0KGludCB0aW1lb3V0KSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRpbWVvdXQgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ0aW1lb3V0IDwgMCIpOworICAgICAgICB9CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBpbXBsLnNldE9wdGlvbihTb2NrZXRPcHRpb25zLlNPX1RJTUVPVVQsIEludGVnZXIudmFsdWVPZih0aW1lb3V0KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc29ja2V0IGltcGxlbWVudGF0aW9uIGZhY3RvcnkuIFRoaXMgbWF5IG9ubHkgYmUgaW52b2tlZCBvbmNlCisgICAgICogb3ZlciB0aGUgbGlmZXRpbWUgb2YgdGhlIGFwcGxpY2F0aW9uLiBUaGlzIGZhY3RvcnkgaXMgdXNlZCB0byBjcmVhdGUKKyAgICAgKiBhIG5ldyBkYXRhZ3JhbSBzb2NrZXQgaW1wbGVtZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmFjCisgICAgICogICAgICAgICAgICB0aGUgc29ja2V0IGZhY3RvcnkgdG8gdXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgZmFjdG9yeSBoYXMgYWxyZWFkeSBiZWVuIHNldC4KKyAgICAgKiBAc2VlIERhdGFncmFtU29ja2V0SW1wbEZhY3RvcnkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCB2b2lkIHNldERhdGFncmFtU29ja2V0SW1wbEZhY3RvcnkoRGF0YWdyYW1Tb2NrZXRJbXBsRmFjdG9yeSBmYWMpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoZmFjdG9yeSAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKCJGYWN0b3J5IGFscmVhZHkgc2V0Iik7CisgICAgICAgIH0KKyAgICAgICAgZmFjdG9yeSA9IGZhYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBEYXRhZ3JhbVNvY2tldH0gdXNpbmcgdGhlIHNwZWNpZmljIGRhdGFncmFtCisgICAgICogc29ja2V0IGltcGxlbWVudGF0aW9uIHtAY29kZSBzb2NrZXRJbXBsfS4gVGhlIGNyZWF0ZWQge0Bjb2RlCisgICAgICogRGF0YWdyYW1Tb2NrZXR9IHdpbGwgbm90IGJlIGJvdW5kLgorICAgICAqCisgICAgICogQHBhcmFtIHNvY2tldEltcGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBEYXRhZ3JhbVNvY2tldEltcGwgdG8gdXNlLgorICAgICAqLworICAgIHByb3RlY3RlZCBEYXRhZ3JhbVNvY2tldChEYXRhZ3JhbVNvY2tldEltcGwgc29ja2V0SW1wbCkgeworICAgICAgICBpZiAoc29ja2V0SW1wbCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbXBsID0gc29ja2V0SW1wbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBEYXRhZ3JhbVNvY2tldH0gYm91bmQgdG8gdGhlIGhvc3QvcG9ydCBzcGVjaWZpZWQKKyAgICAgKiBieSB0aGUge0Bjb2RlIFNvY2tldEFkZHJlc3N9IHtAY29kZSBsb2NhbEFkZHJ9IG9yIGFuIHVuYm91bmQge0Bjb2RlCisgICAgICogRGF0YWdyYW1Tb2NrZXR9IGlmIHRoZSB7QGNvZGUgU29ja2V0QWRkcmVzc30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2FsQWRkcgorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsIG1hY2hpbmUgYWRkcmVzcyBhbmQgcG9ydCB0byBiaW5kIHRvLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIFNvY2tldEFkZHJlc3MgaXMgbm90IHN1cHBvcnRlZAorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycyBjcmVhdGluZyBvciBiaW5kaW5nIHRoZSBzb2NrZXQuCisgICAgICovCisgICAgcHVibGljIERhdGFncmFtU29ja2V0KFNvY2tldEFkZHJlc3MgbG9jYWxBZGRyKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGxvY2FsQWRkciAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoIShsb2NhbEFkZHIgaW5zdGFuY2VvZiBJbmV0U29ja2V0QWRkcmVzcykpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJMb2NhbCBhZGRyZXNzIG5vdCBhbiBJbmV0U29ja2V0QWRkcmVzczogIiArCisgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbEFkZHIuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjaGVja1BvcnQoKChJbmV0U29ja2V0QWRkcmVzcykgbG9jYWxBZGRyKS5nZXRQb3J0KCkpOworICAgICAgICB9CisgICAgICAgIGltcGwgPSBmYWN0b3J5ICE9IG51bGwgPyBmYWN0b3J5LmNyZWF0ZURhdGFncmFtU29ja2V0SW1wbCgpCisgICAgICAgICAgICAgICAgOiBuZXcgUGxhaW5EYXRhZ3JhbVNvY2tldEltcGwoKTsKKyAgICAgICAgaW1wbC5jcmVhdGUoKTsKKyAgICAgICAgaWYgKGxvY2FsQWRkciAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGJpbmQobG9jYWxBZGRyKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIFNvY2tldE9wdGlvbnMuU09fQlJPQURDQVNUIGlzIHNldCBieSBkZWZhdWx0IGZvciBEYXRhZ3JhbVNvY2tldAorICAgICAgICBzZXRCcm9hZGNhc3QodHJ1ZSk7CisgICAgfQorCisgICAgdm9pZCBjaGVja09wZW4oKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzQ2xvc2VkKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oIlNvY2tldCBpcyBjbG9zZWQiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBlbnN1cmVCb3VuZCgpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBpZiAoIWlzQm91bmQoKSkgeworICAgICAgICAgICAgaW1wbC5iaW5kKDAsIEluZXQ0QWRkcmVzcy5BTlkpOworICAgICAgICAgICAgaXNCb3VuZCA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBCaW5kcyB0aGlzIHNvY2tldCB0byB0aGUgbG9jYWwgYWRkcmVzcyBhbmQgcG9ydCBzcGVjaWZpZWQgYnkge0Bjb2RlCisgICAgICogbG9jYWxBZGRyfS4gSWYgdGhpcyB2YWx1ZSBpcyB7QGNvZGUgbnVsbH0gYW55IGZyZWUgcG9ydCBvbiBhIHZhbGlkIGxvY2FsCisgICAgICogYWRkcmVzcyBpcyB1c2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2FsQWRkcgorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsIG1hY2hpbmUgYWRkcmVzcyBhbmQgcG9ydCB0byBiaW5kIG9uLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIFNvY2tldEFkZHJlc3MgaXMgbm90IHN1cHBvcnRlZAorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNvY2tldCBpcyBhbHJlYWR5IGJvdW5kIG9yIGEgcHJvYmxlbSBvY2N1cnMgZHVyaW5nCisgICAgICogICAgICAgICAgICAgYmluZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBiaW5kKFNvY2tldEFkZHJlc3MgbG9jYWxBZGRyKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIGludCBsb2NhbFBvcnQgPSAwOworICAgICAgICBJbmV0QWRkcmVzcyBhZGRyID0gSW5ldDRBZGRyZXNzLkFOWTsKKyAgICAgICAgaWYgKGxvY2FsQWRkciAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoIShsb2NhbEFkZHIgaW5zdGFuY2VvZiBJbmV0U29ja2V0QWRkcmVzcykpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJMb2NhbCBhZGRyZXNzIG5vdCBhbiBJbmV0U29ja2V0QWRkcmVzczogIiArCisgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbEFkZHIuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBpbmV0QWRkciA9IChJbmV0U29ja2V0QWRkcmVzcykgbG9jYWxBZGRyOworICAgICAgICAgICAgYWRkciA9IGluZXRBZGRyLmdldEFkZHJlc3MoKTsKKyAgICAgICAgICAgIGlmIChhZGRyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKCJIb3N0IGlzIHVucmVzb2x2ZWQ6ICIgKyBpbmV0QWRkci5nZXRIb3N0TmFtZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGxvY2FsUG9ydCA9IGluZXRBZGRyLmdldFBvcnQoKTsKKyAgICAgICAgICAgIGNoZWNrUG9ydChsb2NhbFBvcnQpOworICAgICAgICB9CisgICAgICAgIGltcGwuYmluZChsb2NhbFBvcnQsIGFkZHIpOworICAgICAgICBpc0JvdW5kID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25uZWN0cyB0aGlzIGRhdGFncmFtIHNvY2tldCB0byB0aGUgYWRkcmVzcyBhbmQgcG9ydCBzcGVjaWZpZWQgYnkge0Bjb2RlIHBlZXJ9LgorICAgICAqIEZ1dHVyZSBjYWxscyB0byB7QGxpbmsgI3NlbmR9IHdpbGwgdXNlIHRoaXMgYXMgdGhlIGRlZmF1bHQgdGFyZ2V0LCBhbmQge0BsaW5rICNyZWNlaXZlfQorICAgICAqIHdpbGwgb25seSBhY2NlcHQgcGFja2V0cyBmcm9tIHRoaXMgc291cmNlLgorICAgICAqCisgICAgICogQHRocm93cyBTb2NrZXRFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNvbm5lY3QoU29ja2V0QWRkcmVzcyBwZWVyKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBlZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicGVlciA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIShwZWVyIGluc3RhbmNlb2YgSW5ldFNvY2tldEFkZHJlc3MpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJwZWVyIG5vdCBhbiBJbmV0U29ja2V0QWRkcmVzczogIiArIHBlZXIuZ2V0Q2xhc3MoKSk7CisgICAgICAgIH0KKworICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBpc2EgPSAoSW5ldFNvY2tldEFkZHJlc3MpIHBlZXI7CisgICAgICAgIGlmIChpc2EuZ2V0QWRkcmVzcygpID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oIkhvc3QgaXMgdW5yZXNvbHZlZDogIiArIGlzYS5nZXRIb3N0TmFtZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgICAgICBlbnN1cmVCb3VuZCgpOworCisgICAgICAgICAgICB0aGlzLmFkZHJlc3MgPSBpc2EuZ2V0QWRkcmVzcygpOworICAgICAgICAgICAgdGhpcy5wb3J0ID0gaXNhLmdldFBvcnQoKTsKKyAgICAgICAgICAgIHRoaXMuaXNDb25uZWN0ZWQgPSB0cnVlOworCisgICAgICAgICAgICBpbXBsLmNvbm5lY3QoYWRkcmVzcywgcG9ydCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25uZWN0cyB0aGlzIGRhdGFncmFtIHNvY2tldCB0byB0aGUgc3BlY2lmaWMge0Bjb2RlIGFkZHJlc3N9IGFuZCB7QGNvZGUgcG9ydH0uCisgICAgICogRnV0dXJlIGNhbGxzIHRvIHtAbGluayAjc2VuZH0gd2lsbCB1c2UgdGhpcyBhcyB0aGUgZGVmYXVsdCB0YXJnZXQsIGFuZCB7QGxpbmsgI3JlY2VpdmV9CisgICAgICogd2lsbCBvbmx5IGFjY2VwdCBwYWNrZXRzIGZyb20gdGhpcyBzb3VyY2UuCisgICAgICoKKyAgICAgKiA8cD5CZXdhcmU6IGJlY2F1c2UgaXQgY2FuJ3QgdGhyb3csIHRoaXMgbWV0aG9kIHNpbGVudGx5IGlnbm9yZXMgZmFpbHVyZXMuCisgICAgICogVXNlIHtAbGluayAjY29ubmVjdChTb2NrZXRBZGRyZXNzKX0gaW5zdGVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjb25uZWN0KEluZXRBZGRyZXNzIGFkZHJlc3MsIGludCBwb3J0KSB7CisgICAgICAgIGlmIChhZGRyZXNzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImFkZHJlc3MgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uZWN0KG5ldyBJbmV0U29ja2V0QWRkcmVzcyhhZGRyZXNzLCBwb3J0KSk7CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBjb25uZWN0RXhjZXB0aW9uKSB7CisgICAgICAgICAgICAvLyBUT0RPOiBvciBqdXN0IHVzZSBTbmVha3lUaHJvdz8gVGhlcmUncyBhIGNsZWFyIEFQSSBidWcgaGVyZS4KKyAgICAgICAgICAgIHBlbmRpbmdDb25uZWN0RXhjZXB0aW9uID0gY29ubmVjdEV4Y2VwdGlvbjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHNvY2tldCBpcyBib3VuZCB0byBhIGxvY2FsIGFkZHJlc3MuIFNlZSB7QGxpbmsgI2JpbmR9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQm91bmQoKSB7CisgICAgICAgIHJldHVybiBpc0JvdW5kOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGRhdGFncmFtIHNvY2tldCBpcyBjb25uZWN0ZWQgdG8gYSByZW1vdGUgYWRkcmVzcy4gU2VlIHtAbGluayAjY29ubmVjdH0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDb25uZWN0ZWQoKSB7CisgICAgICAgIHJldHVybiBpc0Nvbm5lY3RlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgU29ja2V0QWRkcmVzc30gdGhpcyBzb2NrZXQgaXMgY29ubmVjdGVkIHRvLCBvciBudWxsIGZvciBhbiB1bmNvbm5lY3RlZAorICAgICAqIHNvY2tldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU29ja2V0QWRkcmVzcyBnZXRSZW1vdGVTb2NrZXRBZGRyZXNzKCkgeworICAgICAgICBpZiAoIWlzQ29ubmVjdGVkKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgSW5ldFNvY2tldEFkZHJlc3MoZ2V0SW5ldEFkZHJlc3MoKSwgZ2V0UG9ydCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgU29ja2V0QWRkcmVzc30gdGhpcyBzb2NrZXQgaXMgYm91bmQgdG8sIG9yIG51bGwgZm9yIGFuIHVuYm91bmQgc29ja2V0LgorICAgICAqLworICAgIHB1YmxpYyBTb2NrZXRBZGRyZXNzIGdldExvY2FsU29ja2V0QWRkcmVzcygpIHsKKyAgICAgICAgaWYgKCFpc0JvdW5kKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgSW5ldFNvY2tldEFkZHJlc3MoZ2V0TG9jYWxBZGRyZXNzKCksIGdldExvY2FsUG9ydCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzb2NrZXQgb3B0aW9uIHtAY29kZSBTb2NrZXRPcHRpb25zLlNPX1JFVVNFQUREUn0uIFRoaXMgb3B0aW9uCisgICAgICogaGFzIHRvIGJlIGVuYWJsZWQgaWYgbW9yZSB0aGFuIG9uZSBVRFAgc29ja2V0IHdhbnRzIHRvIGJlIGJvdW5kIHRvIHRoZQorICAgICAqIHNhbWUgYWRkcmVzcy4gVGhhdCBjb3VsZCBiZSBuZWVkZWQgZm9yIHJlY2VpdmluZyBtdWx0aWNhc3QgcGFja2V0cy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGVyZSBpcyBhbiB1bmRlZmluZWQgYmVoYXZpb3IgaWYgdGhpcyBvcHRpb24gaXMgc2V0IGFmdGVyIHRoZSBzb2NrZXQgaXMKKyAgICAgKiBhbHJlYWR5IGJvdW5kLgorICAgICAqCisgICAgICogQHBhcmFtIHJldXNlCisgICAgICogICAgICAgICAgICB0aGUgc29ja2V0IG9wdGlvbiB2YWx1ZSB0byBlbmFibGUgb3IgZGlzYWJsZSB0aGlzIG9wdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzb2NrZXQgaXMgY2xvc2VkIG9yIHRoZSBvcHRpb24gY291bGQgbm90IGJlIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSZXVzZUFkZHJlc3MoYm9vbGVhbiByZXVzZSkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBpbXBsLnNldE9wdGlvbihTb2NrZXRPcHRpb25zLlNPX1JFVVNFQUREUiwgQm9vbGVhbi52YWx1ZU9mKHJldXNlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3RhdGUgb2YgdGhlIHNvY2tldCBvcHRpb24ge0Bjb2RlIFNvY2tldE9wdGlvbnMuU09fUkVVU0VBRERSfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBvcHRpb24gaXMgZW5hYmxlZCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTb2NrZXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc29ja2V0IGlzIGNsb3NlZCBvciB0aGUgb3B0aW9uIGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0UmV1c2VBZGRyZXNzKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICByZXR1cm4gKChCb29sZWFuKSBpbXBsLmdldE9wdGlvbihTb2NrZXRPcHRpb25zLlNPX1JFVVNFQUREUikpLmJvb2xlYW5WYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHNvY2tldCBvcHRpb24ge0Bjb2RlIFNvY2tldE9wdGlvbnMuU09fQlJPQURDQVNUfS4gVGhpcyBvcHRpb24KKyAgICAgKiBtdXN0IGJlIGVuYWJsZWQgdG8gc2VuZCBicm9hZGNhc3QgbWVzc2FnZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnJvYWRjYXN0CisgICAgICogICAgICAgICAgICB0aGUgc29ja2V0IG9wdGlvbiB2YWx1ZSB0byBlbmFibGUgb3IgZGlzYWJsZSB0aGlzIG9wdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzb2NrZXQgaXMgY2xvc2VkIG9yIHRoZSBvcHRpb24gY291bGQgbm90IGJlIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCcm9hZGNhc3QoYm9vbGVhbiBicm9hZGNhc3QpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgaW1wbC5zZXRPcHRpb24oU29ja2V0T3B0aW9ucy5TT19CUk9BRENBU1QsIEJvb2xlYW4udmFsdWVPZihicm9hZGNhc3QpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzdGF0ZSBvZiB0aGUgc29ja2V0IG9wdGlvbiB7QGNvZGUgU29ja2V0T3B0aW9ucy5TT19CUk9BRENBU1R9LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIG9wdGlvbiBpcyBlbmFibGVkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzb2NrZXQgaXMgY2xvc2VkIG9yIHRoZSBvcHRpb24gaXMgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRCcm9hZGNhc3QoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIHJldHVybiAoKEJvb2xlYW4pIGltcGwuZ2V0T3B0aW9uKFNvY2tldE9wdGlvbnMuU09fQlJPQURDQVNUKSkuYm9vbGVhblZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUge0BzZWUgU29ja2V0T3B0aW9ucyNJUF9UT1N9IHZhbHVlIGZvciBldmVyeSBwYWNrZXQgc2VudCBieSB0aGlzIHNvY2tldC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNvY2tldCBpcyBjbG9zZWQgb3IgdGhlIG9wdGlvbiBjb3VsZCBub3QgYmUgc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRyYWZmaWNDbGFzcyhpbnQgdmFsdWUpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgaWYgKHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDI1NSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGltcGwuc2V0T3B0aW9uKFNvY2tldE9wdGlvbnMuSVBfVE9TLCBJbnRlZ2VyLnZhbHVlT2YodmFsdWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgc29ja2V0J3Mge0BzZWUgU29ja2V0T3B0aW9ucyNJUF9UT1N9IHNldHRpbmcuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzb2NrZXQgaXMgY2xvc2VkIG9yIHRoZSBvcHRpb24gaXMgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFRyYWZmaWNDbGFzcygpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgcmV0dXJuIChJbnRlZ2VyKSBpbXBsLmdldE9wdGlvbihTb2NrZXRPcHRpb25zLklQX1RPUyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3RhdGUgb2YgdGhpcyBzb2NrZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc29ja2V0IGlzIGNsb3NlZCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDbG9zZWQoKSB7CisgICAgICAgIHJldHVybiBpc0Nsb3NlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgc29ja2V0J3Mge0Bjb2RlIERhdGFncmFtQ2hhbm5lbH0sIGlmIG9uZSBleGlzdHMuIEEgY2hhbm5lbCBpcworICAgICAqIGF2YWlsYWJsZSBvbmx5IGlmIHRoaXMgc29ja2V0IHdyYXBzIGEgY2hhbm5lbC4gKFRoYXQgaXMsIHlvdSBjYW4gZ28gZnJvbSBhCisgICAgICogY2hhbm5lbCB0byBhIHNvY2tldCBhbmQgYmFjayBhZ2FpbiwgYnV0IHlvdSBjYW4ndCBnbyBmcm9tIGFuIGFyYml0cmFyeSBzb2NrZXQgdG8gYSBjaGFubmVsLikKKyAgICAgKiBJbiBwcmFjdGljZSwgdGhpcyBtZWFucyB0aGF0IHRoZSBzb2NrZXQgbXVzdCBoYXZlIGJlZW4gY3JlYXRlZCBieQorICAgICAqIHtAbGluayBqYXZhLm5pby5jaGFubmVscy5EYXRhZ3JhbUNoYW5uZWwjb3Blbn0uCisgICAgICovCisgICAgcHVibGljIERhdGFncmFtQ2hhbm5lbCBnZXRDaGFubmVsKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAaGlkZSBpbnRlcm5hbCB1c2Ugb25seQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBGaWxlRGVzY3JpcHRvciBnZXRGaWxlRGVzY3JpcHRvciQoKSB7CisgICAgICAgIHJldHVybiBpbXBsLmZkOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9EYXRhZ3JhbVNvY2tldEltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9EYXRhZ3JhbVNvY2tldEltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZTcwNmMzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0RhdGFncmFtU29ja2V0SW1wbC5qYXZhCkBAIC0wLDAgKzEsMjc5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUuaW8uSW9CcmlkZ2U7CisKKy8qKgorICogVGhlIGFic3RyYWN0IHN1cGVyY2xhc3MgZm9yIGRhdGFncmFtIGFuZCBtdWx0aWNhc3Qgc29ja2V0IGltcGxlbWVudGF0aW9ucy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIERhdGFncmFtU29ja2V0SW1wbCBpbXBsZW1lbnRzIFNvY2tldE9wdGlvbnMgeworCisgICAgLyoqCisgICAgICogRmlsZSBkZXNjcmlwdG9yIHRoYXQgaXMgdXNlZCB0byBhZGRyZXNzIHRoaXMgc29ja2V0LgorICAgICAqLworICAgIHByb3RlY3RlZCBGaWxlRGVzY3JpcHRvciBmZDsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgdGhlIGxvY2FsIHBvcnQgdG8gd2hpY2ggdGhpcyBzb2NrZXQgaXMgYm91bmQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBsb2NhbFBvcnQ7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIHVuYm91bmQgZGF0YWdyYW0gc29ja2V0IGltcGxlbWVudGF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBEYXRhZ3JhbVNvY2tldEltcGwoKSB7CisgICAgICAgIGxvY2FsUG9ydCA9IC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIEJpbmRzIHRoZSBkYXRhZ3JhbSBzb2NrZXQgdG8gdGhlIGdpdmVuIGxvY2FsaG9zdC9wb3J0LiBTb2NrZXRzIG11c3QgYmUKKyAgICAgKiBib3VuZCBwcmlvciB0byBhdHRlbXB0aW5nIHRvIHNlbmQgb3IgcmVjZWl2ZSBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIHBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IG9uIHRoZSBsb2NhbGhvc3QgdG8gYmluZC4KKyAgICAgKiBAcGFyYW0gYWRkcgorICAgICAqICAgICAgICAgICAgdGhlIGFkZHJlc3Mgb24gdGhlIG11bHRpaG9tZWQgbG9jYWxob3N0IHRvIGJpbmQuCisgICAgICogQHRocm93cyBTb2NrZXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgYmluZGluZywgZm9yIGV4YW1wbGUsIGlmIHRoZSBwb3J0CisgICAgICogICAgICAgICAgICAgICAgaGFzIGJlZW4gYWxyZWFkeSBib3VuZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBiaW5kKGludCBwb3J0LCBJbmV0QWRkcmVzcyBhZGRyKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgc29ja2V0LgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGNsb3NlKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBhbGxvY2F0ZXMgdGhlIHNvY2tldCBkZXNjcmlwdG9yIGluIHRoZSB1bmRlcmx5aW5nIG9wZXJhdGluZworICAgICAqIHN5c3RlbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNyZWF0aW5nIHRoZSBzb2NrZXQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgY3JlYXRlKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHtAY29kZSBGaWxlRGVzY3JpcHRvcn0gb2YgdGhpcyBkYXRhZ3JhbSBzb2NrZXQsIHdoaWNoIGlzIGludmFsaWQKKyAgICAgKiBpZiB0aGUgc29ja2V0IGlzIGNsb3NlZCBvciBub3QgYm91bmQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IGZpbGUgZGVzY3JpcHRvciBvZiB0aGlzIHNvY2tldC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRmlsZURlc2NyaXB0b3IgZ2V0RmlsZURlc2NyaXB0b3IoKSB7CisgICAgICAgIHJldHVybiBmZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBhZGRyZXNzIHRvIHdoaWNoIHRoZSBzb2NrZXQgaXMgYm91bmQuCisgICAgICovCisgICAgSW5ldEFkZHJlc3MgZ2V0TG9jYWxBZGRyZXNzKCkgeworICAgICAgICByZXR1cm4gSW9CcmlkZ2UuZ2V0U29ja2V0TG9jYWxBZGRyZXNzKGZkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBwb3J0IHRvIHdoaWNoIHRoaXMgc29ja2V0IGlzIGJvdW5kLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgZ2V0TG9jYWxQb3J0KCkgeworICAgICAgICByZXR1cm4gbG9jYWxQb3J0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHRpbWUtdG8tbGl2ZSAoVFRMKSBmb3IgbXVsdGljYXN0IHBhY2tldHMgc2VudCBvbiB0aGlzIHNvY2tldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHRpbWUtdG8tbGl2ZSBvcHRpb24gYXMgYSBieXRlIHZhbHVlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgZ2V0dGluZyB0aGUgdGltZS10by1saXZlIG9wdGlvbgorICAgICAqICAgICAgICAgICAgIHZhbHVlLgorICAgICAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IHtAbGluayAjZ2V0VGltZVRvTGl2ZX0KKyAgICAgKiBAc2VlICNnZXRUaW1lVG9MaXZlKCkKKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHByb3RlY3RlZCBhYnN0cmFjdCBieXRlIGdldFRUTCgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHRpbWUtdG8tbGl2ZSAoVFRMKSBmb3IgbXVsdGljYXN0IHBhY2tldHMgc2VudCBvbiB0aGlzIHNvY2tldC4KKyAgICAgKiBUaGUgVFRMIG9wdGlvbiBkZWZpbmVzIGhvdyBtYW55IHJvdXRlcnMgYSBwYWNrZXQgbWF5IGJlIHBhc3MgYmVmb3JlIGl0IGlzCisgICAgICogZGlzY2FyZGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdGltZS10by1saXZlIG9wdGlvbiBhcyBhbiBpbnRlZ2VyIHZhbHVlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgZ2V0dGluZyB0aGUgdGltZS10by1saXZlIG9wdGlvbgorICAgICAqICAgICAgICAgICAgIHZhbHVlLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBpbnQgZ2V0VGltZVRvTGl2ZSgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEFkZHMgdGhpcyBzb2NrZXQgdG8gdGhlIG11bHRpY2FzdCBncm91cCB7QGNvZGUgYWRkcn0uIEEgc29ja2V0IG11c3Qgam9pbgorICAgICAqIGEgZ3JvdXAgYmVmb3JlIGJlaW5nIGFibGUgdG8gcmVjZWl2ZSBkYXRhLiBGdXJ0aGVyLCBhIHNvY2tldCBtYXkgYmUgYQorICAgICAqIG1lbWJlciBvZiBtdWx0aXBsZSBncm91cHMgYnV0IG1heSBqb2luIGFueSBncm91cCBvbmx5IG9uY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWRkcgorICAgICAqICAgICAgICAgICAgdGhlIG11bHRpY2FzdCBncm91cCB0byB3aGljaCB0aGlzIHNvY2tldCBoYXMgdG8gYmUgam9pbmVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgam9pbmluZyB0aGUgc3BlY2lmaWVkIG11bHRpY2FzdAorICAgICAqICAgICAgICAgICAgIGdyb3VwLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGpvaW4oSW5ldEFkZHJlc3MgYWRkcikgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQWRkcyB0aGlzIHNvY2tldCB0byB0aGUgbXVsdGljYXN0IGdyb3VwIHtAY29kZSBhZGRyfS4gQSBzb2NrZXQgbXVzdCBqb2luCisgICAgICogYSBncm91cCBiZWZvcmUgYmVpbmcgYWJsZSB0byByZWNlaXZlIGRhdGEuIEZ1cnRoZXIsIGEgc29ja2V0IG1heSBiZSBhCisgICAgICogbWVtYmVyIG9mIG11bHRpcGxlIGdyb3VwcyBidXQgbWF5IGpvaW4gYW55IGdyb3VwIG9ubHkgb25jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhZGRyCisgICAgICogICAgICAgICAgICB0aGUgbXVsdGljYXN0IGdyb3VwIHRvIHdoaWNoIHRoaXMgc29ja2V0IGhhcyB0byBiZSBqb2luZWQuCisgICAgICogQHBhcmFtIG5ldEludGVyZmFjZQorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsIG5ldHdvcmsgaW50ZXJmYWNlIHdoaWNoIHdpbGwgcmVjZWl2ZSB0aGUgbXVsdGljYXN0CisgICAgICogICAgICAgICAgICBkYXRhZ3JhbSBwYWNrZXRzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgam9pbmluZyB0aGUgc3BlY2lmaWVkIG11bHRpY2FzdAorICAgICAqICAgICAgICAgICAgIGdyb3VwLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGpvaW5Hcm91cChTb2NrZXRBZGRyZXNzIGFkZHIsCisgICAgICAgICAgICBOZXR3b3JrSW50ZXJmYWNlIG5ldEludGVyZmFjZSkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGlzIHNvY2tldCBmcm9tIHRoZSBtdWx0aWNhc3QgZ3JvdXAge0Bjb2RlIGFkZHJ9LgorICAgICAqCisgICAgICogQHBhcmFtIGFkZHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBtdWx0aWNhc3QgZ3JvdXAgdG8gYmUgbGVmdC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGxlYXZpbmcgdGhlIGdyb3VwIG9yIG5vIG11bHRpY2FzdAorICAgICAqICAgICAgICAgICAgIGFkZHJlc3Mgd2FzIGFzc2lnbmVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGxlYXZlKEluZXRBZGRyZXNzIGFkZHIpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhpcyBzb2NrZXQgZnJvbSB0aGUgbXVsdGljYXN0IGdyb3VwIHtAY29kZSBhZGRyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhZGRyCisgICAgICogICAgICAgICAgICB0aGUgbXVsdGljYXN0IGdyb3VwIHRvIGJlIGxlZnQuCisgICAgICogQHBhcmFtIG5ldEludGVyZmFjZQorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsIG5ldHdvcmsgaW50ZXJmYWNlIG9uIHdoaWNoIHRoaXMgc29ja2V0IGhhcyB0byBiZQorICAgICAqICAgICAgICAgICAgcmVtb3ZlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGxlYXZpbmcgdGhlIGdyb3VwLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGxlYXZlR3JvdXAoU29ja2V0QWRkcmVzcyBhZGRyLAorICAgICAgICAgICAgTmV0d29ya0ludGVyZmFjZSBuZXRJbnRlcmZhY2UpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFBlZWtzIGF0IHRoZSBpbmNvbWluZyBwYWNrZXQgdG8gdGhpcyBzb2NrZXQgYW5kIHJldHVybnMgdGhlIGFkZHJlc3Mgb2YKKyAgICAgKiB0aGUge0Bjb2RlIHNlbmRlcn0uIFRoZSBtZXRob2Qgd2lsbCBibG9jayB1bnRpbCBhIHBhY2tldCBpcyByZWNlaXZlZCBvcgorICAgICAqIHRpbWVvdXQgZXhwaXJlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzZW5kZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBvcmlnaW4gYWRkcmVzcyBvZiBhIHBhY2tldC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhZGRyZXNzIG9mIHtAY29kZSBzZW5kZXJ9IGFzIGFuIGludGVnZXIgdmFsdWUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9yIGEgdGltZW91dCBvY2N1cnMgd2hpbGUgcmVhZGluZyB0aGUgYWRkcmVzcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW50IHBlZWsoSW5ldEFkZHJlc3Mgc2VuZGVyKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlcyBkYXRhIGFuZCBzdG9yZXMgaXQgaW4gdGhlIHN1cHBsaWVkIGRhdGFncmFtIHBhY2tldCB7QGNvZGUgcGFja30uCisgICAgICogVGhpcyBjYWxsIHdpbGwgYmxvY2sgdW50aWwgZWl0aGVyIGRhdGEgaGFzIGJlZW4gcmVjZWl2ZWQgb3IsIGlmIGEgdGltZW91dAorICAgICAqIGlzIHNldCwgdGhlIHRpbWVvdXQgaGFzIGV4cGlyZWQuIElmIHRoZSB0aW1lb3V0IGV4cGlyZXMgYW4ge0Bjb2RlCisgICAgICogSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbn0gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHBhcmFtIHBhY2sKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhZ3JhbSBwYWNrZXQgY29udGFpbmVyIHRvIGZpbGwgaW4gdGhlIHJlY2VpdmVkIGRhdGEuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9yIHRpbWVvdXQgb2NjdXJzIHdoaWxlIHJlY2VpdmluZyBkYXRhLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIHJlY2VpdmUoRGF0YWdyYW1QYWNrZXQgcGFjaykgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2VuZHMgdGhlIGdpdmVuIGRhdGFncmFtIHBhY2tldCB7QGNvZGUgcGFja30uIFRoZSBwYWNrZXQgY29udGFpbnMgdGhlCisgICAgICogZGF0YSBhbmQgdGhlIGFkZHJlc3MgYW5kIHBvcnQgaW5mb3JtYXRpb24gb2YgdGhlIHRhcmdldCBob3N0IGFzIHdlbGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFjaworICAgICAqICAgICAgICAgICAgdGhlIGRhdGFncmFtIHBhY2tldCB0byBiZSBzZW50LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgc2VuZGluZyB0aGUgcGFja2V0LgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIHNlbmQoRGF0YWdyYW1QYWNrZXQgcGFjaykgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdGltZS10by1saXZlIChUVEwpIG9wdGlvbiBmb3IgbXVsdGljYXN0IHBhY2tldHMgc2VudCBvbiB0aGlzCisgICAgICogc29ja2V0LgorICAgICAqCisgICAgICogQHBhcmFtIHR0bAorICAgICAqICAgICAgICAgICAgdGhlIHRpbWUtdG8tbGl2ZSBvcHRpb24gdmFsdWUuIFZhbGlkIHZhbHVlcyBhcmUgMCAmbHQ7IHR0bAorICAgICAqICAgICAgICAgICAgJmx0Oz0gMjU1LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgc2V0dGluZyB0aGUgb3B0aW9uLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIHNldFRpbWVUb0xpdmUoaW50IHR0bCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdGltZS10by1saXZlIChUVEwpIG9wdGlvbiBmb3IgbXVsdGljYXN0IHBhY2tldHMgc2VudCBvbiB0aGlzCisgICAgICogc29ja2V0LgorICAgICAqCisgICAgICogQHBhcmFtIHR0bAorICAgICAqICAgICAgICAgICAgdGhlIHRpbWUtdG8tbGl2ZSBvcHRpb24gdmFsdWUuIFZhbGlkIHZhbHVlcyBhcmUgMCAmbHQ7IHR0bAorICAgICAqICAgICAgICAgICAgJmx0Oz0gMjU1LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgc2V0dGluZyB0aGUgb3B0aW9uLgorICAgICAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IHtAbGluayAjc2V0VGltZVRvTGl2ZX0KKyAgICAgKiBAc2VlICNzZXRUaW1lVG9MaXZlKGludCkKKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIHNldFRUTChieXRlIHR0bCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ29ubmVjdHMgdGhpcyBzb2NrZXQgdG8gdGhlIHNwZWNpZmllZCByZW1vdGUgYWRkcmVzcyBhbmQgcG9ydC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmV0QWRkcgorICAgICAqICAgICAgICAgICAgdGhlIGFkZHJlc3Mgb2YgdGhlIHRhcmdldCBob3N0IHdoaWNoIGhhcyB0byBiZSBjb25uZWN0ZWQuCisgICAgICogQHBhcmFtIHBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IG9uIHRoZSB0YXJnZXQgaG9zdCB3aGljaCBoYXMgdG8gYmUgY29ubmVjdGVkLgorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIGRhdGFncmFtIHNvY2tldCBjYW5ub3QgYmUgY29ubmVjdGVkIHRvIHRoZQorICAgICAqICAgICAgICAgICAgICAgIHNwZWNpZmllZCByZW1vdGUgYWRkcmVzcyBhbmQgcG9ydC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBjb25uZWN0KEluZXRBZGRyZXNzIGluZXRBZGRyLCBpbnQgcG9ydCkKKyAgICAgICAgICAgIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICAvLyBkbyBub3RoaW5nCisgICAgfQorCisgICAgLyoqCisgICAgICogRGlzY29ubmVjdHMgdGhpcyBzb2NrZXQgZnJvbSB0aGUgcmVtb3RlIGhvc3QuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgZGlzY29ubmVjdCgpIHsKKyAgICAgICAgLy8gZG8gbm90aGluZworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlY2VpdmVzIGRhdGEgaW50byB0aGUgc3VwcGxpZWQgZGF0YWdyYW0gcGFja2V0IGJ5IHBlZWtpbmcuIFRoZSBkYXRhIGlzCisgICAgICogbm90IHJlbW92ZWQgZnJvbSBzb2NrZXQgYnVmZmVyIGFuZCBjYW4gYmUgcmVjZWl2ZWQgYWdhaW4gYnkgYW5vdGhlcgorICAgICAqIHtAY29kZSBwZWVrRGF0YSgpfSBvciB7QGNvZGUgcmVjZWl2ZSgpfSBjYWxsLiBUaGlzIGNhbGwgYmxvY2tzIHVudGlsCisgICAgICogZWl0aGVyIGRhdGEgaGFzIGJlZW4gcmVjZWl2ZWQgb3IsIGlmIGEgdGltZW91dCBpcyBzZXQsIHRoZSB0aW1lb3V0IGhhcworICAgICAqIGJlZW4gZXhwaXJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYWNrCisgICAgICogICAgICAgICAgICB0aGUgZGF0YWdyYW0gcGFja2V0IHVzZWQgdG8gc3RvcmUgdGhlIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgcG9ydCB0aGUgcGFja2V0IHdhcyByZWNlaXZlZCBmcm9tLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcGVla2luZyBhdCB0aGUgZGF0YS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW50IHBlZWtEYXRhKERhdGFncmFtUGFja2V0IHBhY2spIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9EYXRhZ3JhbVNvY2tldEltcGxGYWN0b3J5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvRGF0YWdyYW1Tb2NrZXRJbXBsRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlhMWRmMmEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvRGF0YWdyYW1Tb2NrZXRJbXBsRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMzUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKKy8qKgorICogVGhpcyBpbnRlcmZhY2UgZGVmaW5lcyBhIGZhY3RvcnkgZm9yIGRhdGFncmFtIHNvY2tldCBpbXBsZW1lbnRhdGlvbnMuIEl0IGlzCisgKiB1c2VkIGJ5IHRoZSBjbGFzcyB7QGNvZGUgRGF0YWdyYW1Tb2NrZXR9IHRvIGNyZWF0ZSBhIG5ldyBkYXRhZ3JhbSBzb2NrZXQKKyAqIGltcGxlbWVudGF0aW9uLgorICoKKyAqIEBzZWUgRGF0YWdyYW1Tb2NrZXQKKyAqLworcHVibGljIGludGVyZmFjZSBEYXRhZ3JhbVNvY2tldEltcGxGYWN0b3J5IHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIERhdGFncmFtU29ja2V0SW1wbH0gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgZGF0YWdyYW0gc29ja2V0IGltcGxlbWVudGF0aW9uLgorICAgICAqLworICAgIERhdGFncmFtU29ja2V0SW1wbCBjcmVhdGVEYXRhZ3JhbVNvY2tldEltcGwoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9EZWZhdWx0RmlsZU5hbWVNYXAuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9EZWZhdWx0RmlsZU5hbWVNYXAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZjI1NGQ5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0RlZmF1bHRGaWxlTmFtZU1hcC5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBsaWJjb3JlLm5ldC5NaW1lVXRpbHM7CisKKy8qKgorICogSW1wbGVtZW50cyB7QGxpbmsgRmlsZU5hbWVNYXB9IGluIHRlcm1zIG9mIHtAbGluayBsaWJjb3JlLm5ldC5NaW1lVXRpbHN9LgorICovCitjbGFzcyBEZWZhdWx0RmlsZU5hbWVNYXAgaW1wbGVtZW50cyBGaWxlTmFtZU1hcCB7CisgICAgcHVibGljIFN0cmluZyBnZXRDb250ZW50VHlwZUZvcihTdHJpbmcgZmlsZW5hbWUpIHsKKyAgICAgICAgaWYgKGZpbGVuYW1lLmVuZHNXaXRoKCIvIikpIHsKKyAgICAgICAgICAgIC8vIGEgZGlyZWN0b3J5LCByZXR1cm4gaHRtbAorICAgICAgICAgICAgcmV0dXJuIE1pbWVVdGlscy5ndWVzc01pbWVUeXBlRnJvbUV4dGVuc2lvbigiaHRtbCIpOworICAgICAgICB9CisgICAgICAgIGludCBsYXN0Q2hhckluRXh0ZW5zaW9uID0gZmlsZW5hbWUubGFzdEluZGV4T2YoJyMnKTsKKyAgICAgICAgaWYgKGxhc3RDaGFySW5FeHRlbnNpb24gPCAwKSB7CisgICAgICAgICAgICBsYXN0Q2hhckluRXh0ZW5zaW9uID0gZmlsZW5hbWUubGVuZ3RoKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGZpcnN0Q2hhckluRXh0ZW5zaW9uID0gZmlsZW5hbWUubGFzdEluZGV4T2YoJy4nKSArIDE7CisgICAgICAgIFN0cmluZyBleHQgPSAiIjsKKyAgICAgICAgaWYgKGZpcnN0Q2hhckluRXh0ZW5zaW9uID4gZmlsZW5hbWUubGFzdEluZGV4T2YoJy8nKSkgeworICAgICAgICAgICAgZXh0ID0gZmlsZW5hbWUuc3Vic3RyaW5nKGZpcnN0Q2hhckluRXh0ZW5zaW9uLCBsYXN0Q2hhckluRXh0ZW5zaW9uKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gTWltZVV0aWxzLmd1ZXNzTWltZVR5cGVGcm9tRXh0ZW5zaW9uKGV4dC50b0xvd2VyQ2FzZShMb2NhbGUuVVMpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvRmlsZU5hbWVNYXAuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9GaWxlTmFtZU1hcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmExMDRhODQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvRmlsZU5hbWVNYXAuamF2YQpAQCAtMCwwICsxLDM1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCisvKioKKyAqIERlZmluZXMgYSBzY2hlbWUgZm9yIG1hcHBpbmcgYSBmaWxlbmFtZSB0eXBlIHRvIGEgTUlNRSBjb250ZW50IHR5cGUuIE1haW5seQorICogdXNlZCBieSB7QGNvZGUgVVJMU3RyZWFtSGFuZGxlcn0gZm9yIGRldGVybWluaW5nIHRoZSByaWdodCBjb250ZW50IGhhbmRsZXIgdG8KKyAqIGhhbmRsZSB0aGUgcmVzb3VyY2UuCisgKgorICogQHNlZSBDb250ZW50SGFuZGxlcgorICogQHNlZSBVUkxDb25uZWN0aW9uI2dldEZpbGVOYW1lTWFwKCkKKyAqIEBzZWUgVVJMQ29ubmVjdGlvbiNndWVzc0NvbnRlbnRUeXBlRnJvbU5hbWUoU3RyaW5nKQorICogQHNlZSBVUkxTdHJlYW1IYW5kbGVyCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRmlsZU5hbWVNYXAgeworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIE1JTUUgdHlwZSAoc3VjaCBhcyAidGV4dC9wbGFpbiIpIGZvciB0aGUgZ2l2ZW4gZmlsZW5hbWUsIG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb250ZW50VHlwZUZvcihTdHJpbmcgZmlsZW5hbWUpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0h0dHBDb29raWUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9IdHRwQ29va2llLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDU3YWZlZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9IdHRwQ29va2llLmphdmEKQEAgLTAsMCArMSw3MjkgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGxpYmNvcmUubmV0Lmh0dHAuSHR0cERhdGU7CitpbXBvcnQgbGliY29yZS51dGlsLk9iamVjdHM7CisKKy8qKgorICogQW4gb3BhcXVlIGtleS12YWx1ZSB2YWx1ZSBwYWlyIGhlbGQgYnkgYW4gSFRUUCBjbGllbnQgdG8gcGVybWl0IGEgc3RhdGVmdWwKKyAqIHNlc3Npb24gd2l0aCBhbiBIVFRQIHNlcnZlci4gVGhpcyBjbGFzcyBwYXJzZXMgY29va2llIGhlYWRlcnMgZm9yIGFsbCB0aHJlZQorICogY29tbW9ubHkgdXNlZCBIVFRQIGNvb2tpZSBzcGVjaWZpY2F0aW9uczoKKyAqCisgKiA8dWw+CisgKiAgICAgPGxpPlRoZSBOZXRzY2FwZSBjb29raWUgc3BlYyBpcyBvZmZpY2lhbGx5IG9ic29sZXRlIGJ1dCB3aWRlbHkgdXNlZCBpbgorICogICAgICAgICBwcmFjdGljZS4gRWFjaCBjb29raWUgY29udGFpbnMgb25lIGtleS12YWx1ZSBwYWlyIGFuZCB0aGUgZm9sbG93aW5nCisgKiAgICAgICAgIGF0dHJpYnV0ZXM6IHtAY29kZSBEb21haW59LCB7QGNvZGUgRXhwaXJlc30sIHtAY29kZSBQYXRofSwgYW5kCisgKiAgICAgICAgIHtAY29kZSBTZWN1cmV9LiBUaGUge0BsaW5rICNnZXRWZXJzaW9uKCkgdmVyc2lvbn0gb2YgY29va2llcyBpbiB0aGlzCisgKiAgICAgICAgIGZvcm1hdCBpcyB7QGNvZGUgMH0uCisgKiAgICAgICAgIDxwPlRoZXJlIGFyZSBubyBhY2Nlc3NvcnMgZm9yIHRoZSB7QGNvZGUgRXhwaXJlc30gYXR0cmlidXRlLiBXaGVuCisgKiAgICAgICAgIHBhcnNlZCwgZXhwaXJlcyBhdHRyaWJ1dGVzIGFyZSBhc3NpZ25lZCB0byB0aGUge0BsaW5rICNnZXRNYXhBZ2UoKQorICogICAgICAgICBNYXgtQWdlfSBhdHRyaWJ1dGUgYXMgYW4gb2Zmc2V0IGZyb20ge0BsaW5rIFN5c3RlbSNjdXJyZW50VGltZU1pbGxpcygpCisgKiAgICAgICAgIG5vd30uCisgKiAgICAgPGxpPjxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIxMDkudHh0Ij5SRkMgMjEwOTwvYT4gZm9ybWFsaXplcworICogICAgICAgICB0aGUgTmV0c2NhcGUgY29va2llIHNwZWMuIEl0IHJlcGxhY2VzIHRoZSB7QGNvZGUgRXhwaXJlc30gdGltZXN0YW1wCisgKiAgICAgICAgIHdpdGggYSB7QGNvZGUgTWF4LUFnZX0gZHVyYXRpb24gYW5kIGFkZHMge0Bjb2RlIENvbW1lbnR9IGFuZCB7QGNvZGUKKyAqICAgICAgICAgVmVyc2lvbn0gYXR0cmlidXRlcy4gVGhlIHtAbGluayAjZ2V0VmVyc2lvbigpIHZlcnNpb259IG9mIGNvb2tpZXMgaW4KKyAqICAgICAgICAgdGhpcyBmb3JtYXQgaXMge0Bjb2RlIDF9LgorICogICAgIDxsaT48YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyOTY1LnR4dCI+UkZDIDI5NjU8L2E+IHJlZmluZXMKKyAqICAgICAgICAgUkZDIDIxMDkuIEl0IGFkZHMge0Bjb2RlIERpc2NhcmR9LCB7QGNvZGUgUG9ydH0sIGFuZCB7QGNvZGUKKyAqICAgICAgICAgQ29tbWVudFVSTH0gYXR0cmlidXRlcyBhbmQgcmVuYW1lcyB0aGUgaGVhZGVyIGZyb20ge0Bjb2RlIFNldC1Db29raWV9CisgKiAgICAgICAgIHRvIHtAY29kZSBTZXQtQ29va2llMn0uIFRoZSB7QGxpbmsgI2dldFZlcnNpb24oKSB2ZXJzaW9ufSBvZiBjb29raWVzCisgKiAgICAgICAgIGluIHRoaXMgZm9ybWF0IGlzIHtAY29kZSAxfS4KKyAqIDwvdWw+CisgKgorICogPHA+VGhpcyBpbXBsZW1lbnRhdGlvbiBzaWxlbnRseSBkaXNjYXJkcyB1bnJlY29nbml6ZWQgYXR0cmlidXRlcy4gSW4KKyAqIHBhcnRpY3VsYXIsIHRoZSB7QGNvZGUgSHR0cE9ubHl9IGF0dHJpYnV0ZSBpcyB3aWRlbHkgc2VydmVkIGJ1dCBpc24ndCBpbiBhbnkKKyAqIG9mIHRoZSBhYm92ZSBzcGVjcy4gSXQgd2FzIGludHJvZHVjZWQgYnkgSW50ZXJuZXQgRXhwbG9yZXIgdG8gcHJldmVudCBzZXJ2ZXIKKyAqIGNvb2tpZXMgZnJvbSBiZWluZyBleHBvc2VkIGluIHRoZSBET00gdG8gSmF2YVNjcmlwdCwgZXRjLgorICoKKyAqIEBzaW5jZSAxLjYKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEh0dHBDb29raWUgaW1wbGVtZW50cyBDbG9uZWFibGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2V0PFN0cmluZz4gUkVTRVJWRURfTkFNRVMgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7CisKKyAgICBzdGF0aWMgeworICAgICAgICBSRVNFUlZFRF9OQU1FUy5hZGQoImNvbW1lbnQiKTsgICAgLy8gICAgICAgICAgIFJGQyAyMTA5ICBSRkMgMjk2NQorICAgICAgICBSRVNFUlZFRF9OQU1FUy5hZGQoImNvbW1lbnR1cmwiKTsgLy8gICAgICAgICAgICAgICAgICAgICBSRkMgMjk2NQorICAgICAgICBSRVNFUlZFRF9OQU1FUy5hZGQoImRpc2NhcmQiKTsgICAgLy8gICAgICAgICAgICAgICAgICAgICBSRkMgMjk2NQorICAgICAgICBSRVNFUlZFRF9OQU1FUy5hZGQoImRvbWFpbiIpOyAgICAgLy8gTmV0c2NhcGUgIFJGQyAyMTA5ICBSRkMgMjk2NQorICAgICAgICBSRVNFUlZFRF9OQU1FUy5hZGQoImV4cGlyZXMiKTsgICAgLy8gTmV0c2NhcGUKKyAgICAgICAgUkVTRVJWRURfTkFNRVMuYWRkKCJtYXgtYWdlIik7ICAgIC8vICAgICAgICAgICBSRkMgMjEwOSAgUkZDIDI5NjUKKyAgICAgICAgUkVTRVJWRURfTkFNRVMuYWRkKCJwYXRoIik7ICAgICAgIC8vIE5ldHNjYXBlICBSRkMgMjEwOSAgUkZDIDI5NjUKKyAgICAgICAgUkVTRVJWRURfTkFNRVMuYWRkKCJwb3J0Iik7ICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgUkZDIDI5NjUKKyAgICAgICAgUkVTRVJWRURfTkFNRVMuYWRkKCJzZWN1cmUiKTsgICAgIC8vIE5ldHNjYXBlICBSRkMgMjEwOSAgUkZDIDI5NjUKKyAgICAgICAgUkVTRVJWRURfTkFNRVMuYWRkKCJ2ZXJzaW9uIik7ICAgIC8vICAgICAgICAgICBSRkMgMjEwOSAgUkZDIDI5NjUKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYge0Bjb2RlIGhvc3R9IG1hdGNoZXMgdGhlIGRvbWFpbiBwYXR0ZXJuIHtAY29kZSBkb21haW59LgorICAgICAqCisgICAgICogQHBhcmFtIGRvbWFpblBhdHRlcm4gYSBob3N0IG5hbWUgKGxpa2Uge0Bjb2RlIGFuZHJvaWQuY29tfSBvciB7QGNvZGUKKyAgICAgKiAgICAgbG9jYWxob3N0fSksIG9yIGEgcGF0dGVybiB0byBtYXRjaCBzdWJkb21haW5zIG9mIGEgZG9tYWluIG5hbWUgKGxpa2UKKyAgICAgKiAgICAge0Bjb2RlIC5hbmRyb2lkLmNvbX0pLiBBIHNwZWNpYWwgY2FzZSBwYXR0ZXJuIGlzIHtAY29kZSAubG9jYWx9LAorICAgICAqICAgICB3aGljaCBtYXRjaGVzIGFsbCBob3N0cyB3aXRob3V0IGEgVExEIChsaWtlIHtAY29kZSBsb2NhbGhvc3R9KS4KKyAgICAgKiBAcGFyYW0gaG9zdCB0aGUgaG9zdCBuYW1lIG9yIElQIGFkZHJlc3MgZnJvbSBhbiBIVFRQIHJlcXVlc3QuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGRvbWFpbk1hdGNoZXMoU3RyaW5nIGRvbWFpblBhdHRlcm4sIFN0cmluZyBob3N0KSB7CisgICAgICAgIGlmIChkb21haW5QYXR0ZXJuID09IG51bGwgfHwgaG9zdCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgYSA9IGhvc3QudG9Mb3dlckNhc2UoTG9jYWxlLlVTKTsKKyAgICAgICAgU3RyaW5nIGIgPSBkb21haW5QYXR0ZXJuLnRvTG93ZXJDYXNlKExvY2FsZS5VUyk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogRnJvbSB0aGUgc3BlYzogImJvdGggaG9zdCBuYW1lcyBhcmUgSVAgYWRkcmVzc2VzIGFuZCB0aGVpciBob3N0IG5hbWUgc3RyaW5ncyBtYXRjaAorICAgICAgICAgKiBleGFjdGx5OyBvciBib3RoIGhvc3QgbmFtZXMgYXJlIEZRRE4gc3RyaW5ncyBhbmQgdGhlaXIgaG9zdCBuYW1lIHN0cmluZ3MgbWF0Y2ggZXhhY3RseSIKKyAgICAgICAgICovCisgICAgICAgIGlmIChhLmVxdWFscyhiKSAmJiAoaXNGdWxseVF1YWxpZmllZERvbWFpbk5hbWUoYSwgMCkgfHwgSW5ldEFkZHJlc3MuaXNOdW1lcmljKGEpKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFpc0Z1bGx5UXVhbGlmaWVkRG9tYWluTmFtZShhLCAwKSkgeworICAgICAgICAgICAgcmV0dXJuIGIuZXF1YWxzKCIubG9jYWwiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIE5vdCBpbiB0aGUgc3BlYyEgSWYgcHJlZml4aW5nIGEgaG9zdG5hbWUgd2l0aCAiLiIgY2F1c2VzIGl0IHRvIGVxdWFsIHRoZSBkb21haW4gcGF0dGVybiwKKyAgICAgICAgICogdGhlbiBpdCBzaG91bGQgbWF0Y2guIFRoaXMgaXMgbmVjZXNzYXJ5IHNvIHRoYXQgdGhlIHBhdHRlcm4gIi5nb29nbGUuY29tIiB3aWxsIG1hdGNoIHRoZQorICAgICAgICAgKiBob3N0ICJnb29nbGUuY29tIi4KKyAgICAgICAgICovCisgICAgICAgIGlmIChiLmxlbmd0aCgpID09IDEgKyBhLmxlbmd0aCgpCisgICAgICAgICAgICAgICAgJiYgYi5zdGFydHNXaXRoKCIuIikKKyAgICAgICAgICAgICAgICAmJiBiLmVuZHNXaXRoKGEpCisgICAgICAgICAgICAgICAgJiYgaXNGdWxseVF1YWxpZmllZERvbWFpbk5hbWUoYiwgMSkpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogRnJvbSB0aGUgc3BlYzogIkEgaXMgYSBIRE4gc3RyaW5nIGFuZCBoYXMgdGhlIGZvcm0gTkIsIHdoZXJlIE4gaXMgYQorICAgICAgICAgKiBub24tZW1wdHkgbmFtZSBzdHJpbmcsIEIgaGFzIHRoZSBmb3JtIC5CJywgYW5kIEInIGlzIGEgSEROIHN0cmluZy4KKyAgICAgICAgICogKFNvLCB4LnkuY29tIGRvbWFpbi1tYXRjaGVzIC5ZLmNvbSBidXQgbm90IFkuY29tLikKKyAgICAgICAgICovCisgICAgICAgIHJldHVybiBhLmxlbmd0aCgpID4gYi5sZW5ndGgoKQorICAgICAgICAgICAgICAgICYmIGEuZW5kc1dpdGgoYikKKyAgICAgICAgICAgICAgICAmJiAoKGIuc3RhcnRzV2l0aCgiLiIpICYmIGlzRnVsbHlRdWFsaWZpZWREb21haW5OYW1lKGIsIDEpKSB8fCBiLmVxdWFscygiLmxvY2FsIikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB7QGNvZGUgY29va2llfSBzaG91bGQgYmUgc2VudCB0byBvciBhY2NlcHRlZCBmcm9tIHtAY29kZSB1cml9IHdpdGggcmVzcGVjdAorICAgICAqIHRvIHRoZSBjb29raWUncyBwYXRoLiBDb29raWVzIG1hdGNoIGJ5IGRpcmVjdG9yeSBwcmVmaXg6IFVSSSAiL2ZvbyIgbWF0Y2hlcyBjb29raWVzICIvZm9vIiwKKyAgICAgKiAiL2Zvby8iIGFuZCAiL2Zvby9iYXIiLCBidXQgbm90ICIvIiBvciAiL2Zvb2JhciIuCisgICAgICovCisgICAgc3RhdGljIGJvb2xlYW4gcGF0aE1hdGNoZXMoSHR0cENvb2tpZSBjb29raWUsIFVSSSB1cmkpIHsKKyAgICAgICAgU3RyaW5nIHVyaVBhdGggPSBtYXRjaGFibGVQYXRoKHVyaS5nZXRQYXRoKCkpOworICAgICAgICBTdHJpbmcgY29va2llUGF0aCA9IG1hdGNoYWJsZVBhdGgoY29va2llLmdldFBhdGgoKSk7CisgICAgICAgIHJldHVybiB1cmlQYXRoLnN0YXJ0c1dpdGgoY29va2llUGF0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHtAY29kZSBjb29raWV9IHNob3VsZCBiZSBzZW50IHRvIHtAY29kZSB1cml9IHdpdGggcmVzcGVjdCB0byB0aGUgY29va2llJ3MKKyAgICAgKiBzZWN1cmUgYXR0cmlidXRlLiBTZWN1cmUgY29va2llcyBzaG91bGQgbm90IGJlIHNlbnQgaW4gaW5zZWN1cmUgKGllLiBub24tSFRUUFMpIHJlcXVlc3RzLgorICAgICAqLworICAgIHN0YXRpYyBib29sZWFuIHNlY3VyZU1hdGNoZXMoSHR0cENvb2tpZSBjb29raWUsIFVSSSB1cmkpIHsKKyAgICAgICAgcmV0dXJuICFjb29raWUuZ2V0U2VjdXJlKCkgfHwgImh0dHBzIi5lcXVhbHNJZ25vcmVDYXNlKHVyaS5nZXRTY2hlbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHtAY29kZSBjb29raWV9IHNob3VsZCBiZSBzZW50IHRvIHtAY29kZSB1cml9IHdpdGggcmVzcGVjdCB0byB0aGUgY29va2llJ3MKKyAgICAgKiBwb3J0IGxpc3QuCisgICAgICovCisgICAgc3RhdGljIGJvb2xlYW4gcG9ydE1hdGNoZXMoSHR0cENvb2tpZSBjb29raWUsIFVSSSB1cmkpIHsKKyAgICAgICAgaWYgKGNvb2tpZS5nZXRQb3J0bGlzdCgpID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBBcnJheXMuYXNMaXN0KGNvb2tpZS5nZXRQb3J0bGlzdCgpLnNwbGl0KCIsIikpCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKEludGVnZXIudG9TdHJpbmcodXJpLmdldEVmZmVjdGl2ZVBvcnQoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBub24tbnVsbCBwYXRoIGVuZGluZyBpbiAiLyIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIG1hdGNoYWJsZVBhdGgoU3RyaW5nIHBhdGgpIHsKKyAgICAgICAgaWYgKHBhdGggPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuICIvIjsKKyAgICAgICAgfSBlbHNlIGlmIChwYXRoLmVuZHNXaXRoKCIvIikpIHsKKyAgICAgICAgICAgIHJldHVybiBwYXRoOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIHBhdGggKyAiLyI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYge0Bjb2RlIHMuc3Vic3RyaW5nKGZpcnN0Q2hhcmFjdGVyKX0gY29udGFpbnMgYSBkb3QKKyAgICAgKiBiZXR3ZWVuIGl0cyBmaXJzdCBhbmQgbGFzdCBjaGFyYWN0ZXJzLCBleGNsdXNpdmUuIFRoaXMgY29uc2lkZXJzIGJvdGgKKyAgICAgKiB7QGNvZGUgYW5kcm9pZC5jb219IGFuZCB7QGNvZGUgY28udWt9IHRvIGJlIGZ1bGx5IHF1YWxpZmllZCBkb21haW4gbmFtZXMsCisgICAgICogYnV0IG5vdCB7QGNvZGUgYW5kcm9pZC5jb20ufSwge0Bjb2RlIC5jb219LiBvciB7QGNvZGUgYW5kcm9pZH0uCisgICAgICoKKyAgICAgKiA8cD5BbHRob3VnaCB0aGlzIGltcGxlbWVudHMgdGhlIGNvb2tpZSBzcGVjJ3MgZGVmaW5pdGlvbiBvZiBGUUROLCBpdCBpcworICAgICAqIG5vdCBnZW5lcmFsIHB1cnBvc2UuIEZvciBleGFtcGxlLCB0aGlzIHJldHVybnMgdHJ1ZSBmb3IgSVB2NCBhZGRyZXNzZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0Z1bGx5UXVhbGlmaWVkRG9tYWluTmFtZShTdHJpbmcgcywgaW50IGZpcnN0Q2hhcmFjdGVyKSB7CisgICAgICAgIGludCBkb3RQb3NpdGlvbiA9IHMuaW5kZXhPZignLicsIGZpcnN0Q2hhcmFjdGVyICsgMSk7CisgICAgICAgIHJldHVybiBkb3RQb3NpdGlvbiAhPSAtMSAmJiBkb3RQb3NpdGlvbiA8IHMubGVuZ3RoKCkgLSAxOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBjb29raWUgZnJvbSBhIHN0cmluZy4gVGhlIHN0cmluZyBzaG91bGQgY29tcGx5IHdpdGgKKyAgICAgKiBzZXQtY29va2llIG9yIHNldC1jb29raWUyIGhlYWRlciBmb3JtYXQgYXMgc3BlY2lmaWVkIGluCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjk2NS50eHQiPlJGQyAyOTY1PC9hPi4gU2luY2UKKyAgICAgKiBzZXQtY29va2llczIgc3ludGF4IGFsbG93cyBtb3JlIHRoYW4gb25lIGNvb2tpZSBkZWZpbml0aW9ucyBpbiBvbmUKKyAgICAgKiBoZWFkZXIsIHRoZSByZXR1cm5lZCBvYmplY3QgaXMgYSBsaXN0LgorICAgICAqCisgICAgICogQHBhcmFtIGhlYWRlcgorICAgICAqICAgICAgICAgICAgYSBzZXQtY29va2llIG9yIHNldC1jb29raWUyIGhlYWRlci4KKyAgICAgKiBAcmV0dXJuIGEgbGlzdCBvZiBjb25zdHJ1Y3RlZCBjb29raWVzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3RyaW5nIGRvZXMgbm90IGNvbXBseSB3aXRoIGNvb2tpZSBzcGVjaWZpY2F0aW9uLCBvcgorICAgICAqICAgICAgICAgICAgIHRoZSBjb29raWUgbmFtZSBjb250YWlucyBpbGxlZ2FsIGNoYXJhY3RlcnMsIG9yIHJlc2VydmVkCisgICAgICogICAgICAgICAgICAgdG9rZW5zIG9mIGNvb2tpZSBzcGVjaWZpY2F0aW9uIGFwcGVhcnMKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgaGVhZGVyIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIExpc3Q8SHR0cENvb2tpZT4gcGFyc2UoU3RyaW5nIGhlYWRlcikgeworICAgICAgICByZXR1cm4gbmV3IENvb2tpZVBhcnNlcihoZWFkZXIpLnBhcnNlKCk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIENvb2tpZVBhcnNlciB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSSUJVVEVfTkFNRV9URVJNSU5BVE9SUyA9ICIsOz0gXHQiOworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0hJVEVTUEFDRSA9ICIgXHQiOworICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBpbnB1dDsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgaW5wdXRMb3dlckNhc2U7CisgICAgICAgIHByaXZhdGUgaW50IHBvcyA9IDA7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVGhlIGNvb2tpZSdzIHZlcnNpb24gaXMgc2V0IGJhc2VkIG9uIGFuIG92ZXJseSBjb21wbGV4IGhldXJpc3RpYzoKKyAgICAgICAgICogSWYgaXQgaGFzIGFuIGV4cGlyZXMgYXR0cmlidXRlLCB0aGUgdmVyc2lvbiBpcyAwLgorICAgICAgICAgKiBPdGhlcndpc2UsIGlmIGl0IGhhcyBhIG1heC1hZ2UgYXR0cmlidXRlLCB0aGUgdmVyc2lvbiBpcyAxLgorICAgICAgICAgKiBPdGhlcndpc2UsIGlmIHRoZSBjb29raWUgc3RhcnRlZCB3aXRoICJTZXQtQ29va2llMiIsIHRoZSB2ZXJzaW9uIGlzIDEuCisgICAgICAgICAqIE90aGVyd2lzZSwgaWYgaXQgaGFzIGFueSBleHBsaWNpdCB2ZXJzaW9uIGF0dHJpYnV0ZXMsIHVzZSB0aGUgZmlyc3Qgb25lLgorICAgICAgICAgKiBPdGhlcndpc2UsIHRoZSB2ZXJzaW9uIGlzIDAuCisgICAgICAgICAqLworICAgICAgICBib29sZWFuIGhhc0V4cGlyZXMgPSBmYWxzZTsKKyAgICAgICAgYm9vbGVhbiBoYXNNYXhBZ2UgPSBmYWxzZTsKKyAgICAgICAgYm9vbGVhbiBoYXNWZXJzaW9uID0gZmFsc2U7CisKKyAgICAgICAgQ29va2llUGFyc2VyKFN0cmluZyBpbnB1dCkgeworICAgICAgICAgICAgdGhpcy5pbnB1dCA9IGlucHV0OworICAgICAgICAgICAgdGhpcy5pbnB1dExvd2VyQ2FzZSA9IGlucHV0LnRvTG93ZXJDYXNlKExvY2FsZS5VUyk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTGlzdDxIdHRwQ29va2llPiBwYXJzZSgpIHsKKyAgICAgICAgICAgIExpc3Q8SHR0cENvb2tpZT4gY29va2llcyA9IG5ldyBBcnJheUxpc3Q8SHR0cENvb2tpZT4oMik7CisKKyAgICAgICAgICAgIC8vIFRoZSBSSSBwZXJtaXRzIGlucHV0IHdpdGhvdXQgZWl0aGVyIHRoZSAiU2V0LUNvb2tpZToiIG9yICJTZXQtQ29va2llMiIgaGVhZGVycy4KKyAgICAgICAgICAgIGJvb2xlYW4gcHJlMjk2NSA9IHRydWU7CisgICAgICAgICAgICBpZiAoaW5wdXRMb3dlckNhc2Uuc3RhcnRzV2l0aCgic2V0LWNvb2tpZTI6IikpIHsKKyAgICAgICAgICAgICAgICBwb3MgKz0gInNldC1jb29raWUyOiIubGVuZ3RoKCk7CisgICAgICAgICAgICAgICAgcHJlMjk2NSA9IGZhbHNlOworICAgICAgICAgICAgICAgIGhhc1ZlcnNpb24gPSB0cnVlOworICAgICAgICAgICAgfSBlbHNlIGlmIChpbnB1dExvd2VyQ2FzZS5zdGFydHNXaXRoKCJzZXQtY29va2llOiIpKSB7CisgICAgICAgICAgICAgICAgcG9zICs9ICJzZXQtY29va2llOiIubGVuZ3RoKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBSZWFkIGEgY29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgY29va2llcy4gTm90ZSB0aGF0IHRoZSB2YWx1ZXMgbWF5IGNvbnRhaW4gY29tbWFzIQorICAgICAgICAgICAgICogICA8TkFNRT4gIj0iIDxWQUxVRT4gKCAiOyIgPEFUVFIgTkFNRT4gKCAiPSIgPEFUVFIgVkFMVUU+ICk/ICkqCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSByZWFkQXR0cmlidXRlTmFtZShmYWxzZSk7CisgICAgICAgICAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoY29va2llcy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5vIGNvb2tpZXMgaW4gIiArIGlucHV0KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llczsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoIXJlYWRFcXVhbHNTaWduKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRXhwZWN0ZWQgJz0nIGFmdGVyICIgKyBuYW1lICsgIiBpbiAiICsgaW5wdXQpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IHJlYWRBdHRyaWJ1dGVWYWx1ZShwcmUyOTY1ID8gIjsiIDogIiw7Iik7CisgICAgICAgICAgICAgICAgSHR0cENvb2tpZSBjb29raWUgPSBuZXcgSHR0cENvb2tpZShuYW1lLCB2YWx1ZSk7CisgICAgICAgICAgICAgICAgY29va2llLnZlcnNpb24gPSBwcmUyOTY1ID8gMCA6IDE7CisgICAgICAgICAgICAgICAgY29va2llcy5hZGQoY29va2llKTsKKworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogUmVhZCB0aGUgYXR0cmlidXRlcyBvZiB0aGUgY3VycmVudCBjb29raWUuIEVhY2ggaXRlcmF0aW9uIG9mIHRoaXMgbG9vcCBzaG91bGQKKyAgICAgICAgICAgICAgICAgKiBlbnRlciB3aXRoIGlucHV0IGVpdGhlciBleGhhdXN0ZWQgb3IgcHJlZml4ZWQgd2l0aCAnOycgb3IgJywnIGFzIGluICI7cGF0aD0vIgorICAgICAgICAgICAgICAgICAqIGFuZCAiLENPT0tJRTI9dmFsdWUyIi4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgICAgICBza2lwV2hpdGVzcGFjZSgpOworICAgICAgICAgICAgICAgICAgICBpZiAocG9zID09IGlucHV0Lmxlbmd0aCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dC5jaGFyQXQocG9zKSA9PSAnLCcpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBvcysrOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7IC8vIGEgdHJ1ZSBjb21tYSBkZWxpbWl0ZXI7IHRoZSBjdXJyZW50IGNvb2tpZSBpcyBjb21wbGV0ZS4KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbnB1dC5jaGFyQXQocG9zKSA9PSAnOycpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBvcysrOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF0dHJpYnV0ZU5hbWUgPSByZWFkQXR0cmlidXRlTmFtZSh0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZU5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7IC8vIGZvciBlbXB0eSBhdHRyaWJ1dGUgYXMgaW4gIlNldC1Db29raWU6IGZvbz1Gb287O3BhdGg9LyIKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICAgICAqIFNpbmNlIGV4cGlyZXMgYW5kIHBvcnQgYXR0cmlidXRlcyBjb21tb25seSBpbmNsdWRlIGNvbW1hIGRlbGltaXRlcnMsIGFsd2F5cworICAgICAgICAgICAgICAgICAgICAgKiBzY2FuIHVudGlsIGEgc2VtaWNvbG9uIHdoZW4gcGFyc2luZyB0aGVzZSBhdHRyaWJ1dGVzLgorICAgICAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRlcm1pbmF0b3JzID0gcHJlMjk2NQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICJleHBpcmVzIi5lcXVhbHMoYXR0cmlidXRlTmFtZSkgfHwgInBvcnQiLmVxdWFscyhhdHRyaWJ1dGVOYW1lKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gIjsiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAiOywiOworICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXR0cmlidXRlVmFsdWUgPSBudWxsOworICAgICAgICAgICAgICAgICAgICBpZiAocmVhZEVxdWFsc1NpZ24oKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlVmFsdWUgPSByZWFkQXR0cmlidXRlVmFsdWUodGVybWluYXRvcnMpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHNldEF0dHJpYnV0ZShjb29raWUsIGF0dHJpYnV0ZU5hbWUsIGF0dHJpYnV0ZVZhbHVlKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoaGFzRXhwaXJlcykgeworICAgICAgICAgICAgICAgICAgICBjb29raWUudmVyc2lvbiA9IDA7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChoYXNNYXhBZ2UpIHsKKyAgICAgICAgICAgICAgICAgICAgY29va2llLnZlcnNpb24gPSAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCBzZXRBdHRyaWJ1dGUoSHR0cENvb2tpZSBjb29raWUsIFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpIHsKKyAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscygiY29tbWVudCIpICYmIGNvb2tpZS5jb21tZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjb29raWUuY29tbWVudCA9IHZhbHVlOworICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFscygiY29tbWVudHVybCIpICYmIGNvb2tpZS5jb21tZW50VVJMID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjb29raWUuY29tbWVudFVSTCA9IHZhbHVlOworICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFscygiZGlzY2FyZCIpKSB7CisgICAgICAgICAgICAgICAgY29va2llLmRpc2NhcmQgPSB0cnVlOworICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFscygiZG9tYWluIikgJiYgY29va2llLmRvbWFpbiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY29va2llLmRvbWFpbiA9IHZhbHVlOworICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFscygiZXhwaXJlcyIpKSB7CisgICAgICAgICAgICAgICAgaGFzRXhwaXJlcyA9IHRydWU7CisgICAgICAgICAgICAgICAgaWYgKGNvb2tpZS5tYXhBZ2UgPT0gLTFMKSB7CisgICAgICAgICAgICAgICAgICAgIERhdGUgZGF0ZSA9IEh0dHBEYXRlLnBhcnNlKHZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgY29va2llLnNldEV4cGlyZXMoZGF0ZSk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb29raWUubWF4QWdlID0gMDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHMoIm1heC1hZ2UiKSAmJiBjb29raWUubWF4QWdlID09IC0xTCkgeworICAgICAgICAgICAgICAgIGhhc01heEFnZSA9IHRydWU7CisgICAgICAgICAgICAgICAgY29va2llLm1heEFnZSA9IExvbmcucGFyc2VMb25nKHZhbHVlKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHMoInBhdGgiKSAmJiBjb29raWUucGF0aCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY29va2llLnBhdGggPSB2YWx1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHMoInBvcnQiKSAmJiBjb29raWUucG9ydExpc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGNvb2tpZS5wb3J0TGlzdCA9IHZhbHVlICE9IG51bGwgPyB2YWx1ZSA6ICIiOworICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFscygic2VjdXJlIikpIHsKKyAgICAgICAgICAgICAgICBjb29raWUuc2VjdXJlID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHMoInZlcnNpb24iKSAmJiAhaGFzVmVyc2lvbikgeworICAgICAgICAgICAgICAgIGNvb2tpZS52ZXJzaW9uID0gSW50ZWdlci5wYXJzZUludCh2YWx1ZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgbmV4dCBhdHRyaWJ1dGUgbmFtZSwgb3IgbnVsbCBpZiB0aGUgaW5wdXQgaGFzIGJlZW4KKyAgICAgICAgICogZXhoYXVzdGVkLiBSZXR1cm5zIHd0aCB0aGUgY3Vyc29yIG9uIHRoZSBkZWxpbWl0ZXIgdGhhdCBmb2xsb3dzLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgcmVhZEF0dHJpYnV0ZU5hbWUoYm9vbGVhbiByZXR1cm5Mb3dlckNhc2UpIHsKKyAgICAgICAgICAgIHNraXBXaGl0ZXNwYWNlKCk7CisgICAgICAgICAgICBpbnQgYyA9IGZpbmQoQVRUUklCVVRFX05BTUVfVEVSTUlOQVRPUlMpOworICAgICAgICAgICAgU3RyaW5nIGZvclN1YnN0cmluZyA9IHJldHVybkxvd2VyQ2FzZSA/IGlucHV0TG93ZXJDYXNlIDogaW5wdXQ7CisgICAgICAgICAgICBTdHJpbmcgcmVzdWx0ID0gcG9zIDwgYyA/IGZvclN1YnN0cmluZy5zdWJzdHJpbmcocG9zLCBjKSA6IG51bGw7CisgICAgICAgICAgICBwb3MgPSBjOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgYW4gZXF1YWxzIHNpZ24gd2FzIHJlYWQgYW5kIGNvbnN1bWVkLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIHJlYWRFcXVhbHNTaWduKCkgeworICAgICAgICAgICAgc2tpcFdoaXRlc3BhY2UoKTsKKyAgICAgICAgICAgIGlmIChwb3MgPCBpbnB1dC5sZW5ndGgoKSAmJiBpbnB1dC5jaGFyQXQocG9zKSA9PSAnPScpIHsKKyAgICAgICAgICAgICAgICBwb3MrKzsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZWFkcyBhbiBhdHRyaWJ1dGUgdmFsdWUsIGJ5IHBhcnNpbmcgZWl0aGVyIGEgcXVvdGVkIHN0cmluZyBvciB1bnRpbAorICAgICAgICAgKiB0aGUgbmV4dCBjaGFyYWN0ZXIgaW4ge0Bjb2RlIHRlcm1pbmF0b3JzfS4gVGhlIHRlcm1pbmF0b3IgY2hhcmFjdGVyCisgICAgICAgICAqIGlzIG5vdCBjb25zdW1lZC4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgU3RyaW5nIHJlYWRBdHRyaWJ1dGVWYWx1ZShTdHJpbmcgdGVybWluYXRvcnMpIHsKKyAgICAgICAgICAgIHNraXBXaGl0ZXNwYWNlKCk7CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBRdW90ZWQgc3RyaW5nOiByZWFkICd0aWwgdGhlIGNsb3NlIHF1b3RlLiBUaGUgc3BlYyBtZW50aW9ucyBvbmx5ICJkb3VibGUgcXVvdGVzIgorICAgICAgICAgICAgICogYnV0IFJJIGJ1ZyA2OTAxMTcwIGNsYWltcyB0aGF0ICdzaW5nbGUgcXVvdGVzJyBhcmUgYWxzbyB1c2VkLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAocG9zIDwgaW5wdXQubGVuZ3RoKCkgJiYgKGlucHV0LmNoYXJBdChwb3MpID09ICciJyB8fCBpbnB1dC5jaGFyQXQocG9zKSA9PSAnXCcnKSkgeworICAgICAgICAgICAgICAgIGNoYXIgcXVvdGVDaGFyYWN0ZXIgPSBpbnB1dC5jaGFyQXQocG9zKyspOworICAgICAgICAgICAgICAgIGludCBjbG9zZVF1b3RlID0gaW5wdXQuaW5kZXhPZihxdW90ZUNoYXJhY3RlciwgcG9zKTsKKyAgICAgICAgICAgICAgICBpZiAoY2xvc2VRdW90ZSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbnRlcm1pbmF0ZWQgc3RyaW5nIGxpdGVyYWwgaW4gIiArIGlucHV0KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGlucHV0LnN1YnN0cmluZyhwb3MsIGNsb3NlUXVvdGUpOworICAgICAgICAgICAgICAgIHBvcyA9IGNsb3NlUXVvdGUgKyAxOworICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGludCBjID0gZmluZCh0ZXJtaW5hdG9ycyk7CisgICAgICAgICAgICBTdHJpbmcgcmVzdWx0ID0gaW5wdXQuc3Vic3RyaW5nKHBvcywgYyk7CisgICAgICAgICAgICBwb3MgPSBjOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBjaGFyYWN0ZXIgaW4ge0Bjb2RlIGNoYXJzfSwgb3IgdGhlIGVuZAorICAgICAgICAgKiBvZiB0aGUgc3RyaW5nLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBpbnQgZmluZChTdHJpbmcgY2hhcnMpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGMgPSBwb3M7IGMgPCBpbnB1dC5sZW5ndGgoKTsgYysrKSB7CisgICAgICAgICAgICAgICAgaWYgKGNoYXJzLmluZGV4T2YoaW5wdXQuY2hhckF0KGMpKSAhPSAtMSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gYzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gaW5wdXQubGVuZ3RoKCk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgc2tpcFdoaXRlc3BhY2UoKSB7CisgICAgICAgICAgICBmb3IgKDsgcG9zIDwgaW5wdXQubGVuZ3RoKCk7IHBvcysrKSB7CisgICAgICAgICAgICAgICAgaWYgKFdISVRFU1BBQ0UuaW5kZXhPZihpbnB1dC5jaGFyQXQocG9zKSkgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgY29tbWVudDsKKyAgICBwcml2YXRlIFN0cmluZyBjb21tZW50VVJMOworICAgIHByaXZhdGUgYm9vbGVhbiBkaXNjYXJkOworICAgIHByaXZhdGUgU3RyaW5nIGRvbWFpbjsKKyAgICBwcml2YXRlIGxvbmcgbWF4QWdlID0gLTFsOworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG5hbWU7CisgICAgcHJpdmF0ZSBTdHJpbmcgcGF0aDsKKyAgICBwcml2YXRlIFN0cmluZyBwb3J0TGlzdDsKKyAgICBwcml2YXRlIGJvb2xlYW4gc2VjdXJlOworICAgIHByaXZhdGUgU3RyaW5nIHZhbHVlOworICAgIHByaXZhdGUgaW50IHZlcnNpb24gPSAxOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBjb29raWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBhIG5vbi1lbXB0eSBzdHJpbmcgdGhhdCBjb250YWlucyBvbmx5IHByaW50YWJsZSBBU0NJSSwgbm8KKyAgICAgKiAgICAgY29tbWFzIG9yIHNlbWljb2xvbnMsIGFuZCBpcyBub3QgcHJlZml4ZWQgd2l0aCAge0Bjb2RlICR9LiBNYXkgbm90IGJlCisgICAgICogICAgIGFuIEhUVFAgYXR0cmlidXRlIG5hbWUuCisgICAgICogQHBhcmFtIHZhbHVlIGFuIG9wYXF1ZSB2YWx1ZSBmcm9tIHRoZSBIVFRQIHNlcnZlci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgbmFtZX0gaXMgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSHR0cENvb2tpZShTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIFN0cmluZyBudHJpbSA9IG5hbWUudHJpbSgpOyAvLyBlcmFzZSBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlCisgICAgICAgIGlmICghaXNWYWxpZE5hbWUobnRyaW0pKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICB0aGlzLm5hbWUgPSBudHJpbTsKKyAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgIH0KKworCisgICAgcHJpdmF0ZSBib29sZWFuIGlzVmFsaWROYW1lKFN0cmluZyBuKSB7CisgICAgICAgIC8vIG5hbWUgY2Fubm90IGJlIGVtcHR5IG9yIGJlZ2luIHdpdGggJyQnIG9yIGVxdWFscyB0aGUgcmVzZXJ2ZWQKKyAgICAgICAgLy8gYXR0cmlidXRlcyAoY2FzZS1pbnNlbnNpdGl2ZSkKKyAgICAgICAgYm9vbGVhbiBpc1ZhbGlkID0gIShuLmxlbmd0aCgpID09IDAgfHwgbi5zdGFydHNXaXRoKCIkIikKKyAgICAgICAgICAgICAgICB8fCBSRVNFUlZFRF9OQU1FUy5jb250YWlucyhuLnRvTG93ZXJDYXNlKExvY2FsZS5VUykpKTsKKyAgICAgICAgaWYgKGlzVmFsaWQpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbi5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgY2hhciBuYW1lQ2hhciA9IG4uY2hhckF0KGkpOworICAgICAgICAgICAgICAgIC8vIG5hbWUgbXVzdCBiZSBBU0NJSSBjaGFyYWN0ZXJzIGFuZCBjYW5ub3QgY29udGFpbiAnOycsICcsJyBhbmQKKyAgICAgICAgICAgICAgICAvLyB3aGl0ZXNwYWNlCisgICAgICAgICAgICAgICAgaWYgKG5hbWVDaGFyIDwgMAorICAgICAgICAgICAgICAgICAgICAgICAgfHwgbmFtZUNoYXIgPj0gMTI3CisgICAgICAgICAgICAgICAgICAgICAgICB8fCBuYW1lQ2hhciA9PSAnOycKKyAgICAgICAgICAgICAgICAgICAgICAgIHx8IG5hbWVDaGFyID09ICcsJworICAgICAgICAgICAgICAgICAgICAgICAgfHwgKENoYXJhY3Rlci5pc1doaXRlc3BhY2UobmFtZUNoYXIpICYmIG5hbWVDaGFyICE9ICcgJykpIHsKKyAgICAgICAgICAgICAgICAgICAgaXNWYWxpZCA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlzVmFsaWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIENvbW1lbnR9IGF0dHJpYnV0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbW1lbnQoKSB7CisgICAgICAgIHJldHVybiBjb21tZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHtAY29kZSBDb21tZW50VVJMfSBhdHRyaWJ1dGUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb21tZW50VVJMKCkgeworICAgICAgICByZXR1cm4gY29tbWVudFVSTDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgRGlzY2FyZH0gYXR0cmlidXRlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldERpc2NhcmQoKSB7CisgICAgICAgIHJldHVybiBkaXNjYXJkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBEb21haW59IGF0dHJpYnV0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldERvbWFpbigpIHsKKyAgICAgICAgcmV0dXJuIGRvbWFpbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgTWF4LUFnZX0gYXR0cmlidXRlLCBpbiBkZWx0YS1zZWNvbmRzLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldE1heEFnZSgpIHsKKyAgICAgICAgcmV0dXJuIG1heEFnZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoaXMgY29va2llLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIFBhdGh9IGF0dHJpYnV0ZS4gVGhpcyBjb29raWUgaXMgdmlzaWJsZSB0byBhbGwKKyAgICAgKiBzdWJwYXRocy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFBhdGgoKSB7CisgICAgICAgIHJldHVybiBwYXRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBQb3J0fSBhdHRyaWJ1dGUsIHVzdWFsbHkgY29udGFpbmluZyBjb21tYS1zZXBhcmF0ZWQKKyAgICAgKiBwb3J0IG51bWJlcnMuIEEgbnVsbCBwb3J0IGluZGljYXRlcyB0aGF0IHRoZSBjb29raWUgbWF5IGJlIHNlbnQgdG8gYW55CisgICAgICogcG9ydC4gVGhlIGVtcHR5IHN0cmluZyBpbmRpY2F0ZXMgdGhhdCB0aGUgY29va2llIHNob3VsZCBvbmx5IGJlIHNlbnQgdG8KKyAgICAgKiB0aGUgcG9ydCBvZiB0aGUgb3JpZ2luYXRpbmcgcmVxdWVzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFBvcnRsaXN0KCkgeworICAgICAgICByZXR1cm4gcG9ydExpc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIFNlY3VyZX0gYXR0cmlidXRlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldFNlY3VyZSgpIHsKKyAgICAgICAgcmV0dXJuIHNlY3VyZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGlzIGNvb2tpZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmVyc2lvbiBvZiB0aGlzIGNvb2tpZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFZlcnNpb24oKSB7CisgICAgICAgIHJldHVybiB2ZXJzaW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGNvb2tpZSdzIE1heC1BZ2UgaXMgMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNFeHBpcmVkKCkgeworICAgICAgICAvLyAtMSBpbmRpY2F0ZXMgdGhlIGNvb2tpZSB3aWxsIHBlcnNpc3QgdW50aWwgYnJvd3NlciBzaHV0ZG93bgorICAgICAgICAvLyBzbyB0aGUgY29va2llIGlzIG5vdCBleHBpcmVkLgorICAgICAgICBpZiAobWF4QWdlID09IC0xbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBleHBpcmVkID0gZmFsc2U7CisgICAgICAgIGlmIChtYXhBZ2UgPD0gMGwpIHsKKyAgICAgICAgICAgIGV4cGlyZWQgPSB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBleHBpcmVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUge0Bjb2RlIENvbW1lbnR9IGF0dHJpYnV0ZSBvZiB0aGlzIGNvb2tpZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb21tZW50KFN0cmluZyBjb21tZW50KSB7CisgICAgICAgIHRoaXMuY29tbWVudCA9IGNvbW1lbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSB7QGNvZGUgQ29tbWVudFVSTH0gYXR0cmlidXRlIG9mIHRoaXMgY29va2llLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvbW1lbnRVUkwoU3RyaW5nIGNvbW1lbnRVUkwpIHsKKyAgICAgICAgdGhpcy5jb21tZW50VVJMID0gY29tbWVudFVSTDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHtAY29kZSBEaXNjYXJkfSBhdHRyaWJ1dGUgb2YgdGhpcyBjb29raWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGlzY2FyZChib29sZWFuIGRpc2NhcmQpIHsKKyAgICAgICAgdGhpcy5kaXNjYXJkID0gZGlzY2FyZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHtAY29kZSBEb21haW59IGF0dHJpYnV0ZSBvZiB0aGlzIGNvb2tpZS4gSFRUUCBjbGllbnRzIHNlbmQKKyAgICAgKiBjb29raWVzIG9ubHkgdG8gbWF0Y2hpbmcgZG9tYWlucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREb21haW4oU3RyaW5nIHBhdHRlcm4pIHsKKyAgICAgICAgZG9tYWluID0gcGF0dGVybiA9PSBudWxsID8gbnVsbCA6IHBhdHRlcm4udG9Mb3dlckNhc2UoTG9jYWxlLlVTKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB7QGNvZGUgTWF4LUFnZX0gYXR0cmlidXRlIG9mIHRoaXMgY29va2llLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1heEFnZShsb25nIGRlbHRhU2Vjb25kcykgeworICAgICAgICBtYXhBZ2UgPSBkZWx0YVNlY29uZHM7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNldEV4cGlyZXMoRGF0ZSBleHBpcmVzKSB7CisgICAgICAgIG1heEFnZSA9IChleHBpcmVzLmdldFRpbWUoKSAtIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKSAvIDEwMDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSB7QGNvZGUgUGF0aH0gYXR0cmlidXRlIG9mIHRoaXMgY29va2llLiBIVFRQIGNsaWVudHMgc2VuZCBjb29raWVzCisgICAgICogdG8gdGhpcyBwYXRoIGFuZCBpdHMgc3VicGF0aHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UGF0aChTdHJpbmcgcGF0aCkgeworICAgICAgICB0aGlzLnBhdGggPSBwYXRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUge0Bjb2RlIFBvcnR9IGF0dHJpYnV0ZSBvZiB0aGlzIGNvb2tpZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQb3J0bGlzdChTdHJpbmcgcG9ydExpc3QpIHsKKyAgICAgICAgdGhpcy5wb3J0TGlzdCA9IHBvcnRMaXN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHtAY29kZSBTZWN1cmV9IGF0dHJpYnV0ZSBvZiB0aGlzIGNvb2tpZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTZWN1cmUoYm9vbGVhbiBzZWN1cmUpIHsKKyAgICAgICAgdGhpcy5zZWN1cmUgPSBzZWN1cmU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgb3BhcXVlIHZhbHVlIG9mIHRoaXMgY29va2llLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlKFN0cmluZyB2YWx1ZSkgeworICAgICAgICAvLyBGSVhNRTogQWNjb3JkaW5nIHRvIHNwZWMsIHZlcnNpb24gMCBjb29raWUgdmFsdWUgZG9lcyBub3QgYWxsb3cgbWFueQorICAgICAgICAvLyBzeW1ib2xzLiBCdXQgUkkgZG9lcyBub3QgaW1wbGVtZW50IGl0LiBGb2xsb3cgUkkgdGVtcG9yYXJpbHkuCisgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB7QGNvZGUgVmVyc2lvbn0gYXR0cmlidXRlIG9mIHRoZSBjb29raWUuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB2IGlzIG5laXRoZXIgMCBub3IgMQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFZlcnNpb24oaW50IHYpIHsKKyAgICAgICAgaWYgKHYgIT0gMCAmJiB2ICE9IDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB2ZXJzaW9uID0gdjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB7QGNvZGUgb2JqZWN0fSBpcyBhIGNvb2tpZSB3aXRoIHRoZSBzYW1lIGRvbWFpbiwgbmFtZSBhbmQKKyAgICAgKiBwYXRoLiBEb21haW4gYW5kIG5hbWUgdXNlIGNhc2UtaW5zZW5zaXRpdmUgY29tcGFyaXNvbjsgcGF0aCB1c2VzIGEKKyAgICAgKiBjYXNlLXNlbnNpdGl2ZSBjb21wYXJpc29uLgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBpZiAob2JqZWN0ID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBIdHRwQ29va2llKSB7CisgICAgICAgICAgICBIdHRwQ29va2llIHRoYXQgPSAoSHR0cENvb2tpZSkgb2JqZWN0OworICAgICAgICAgICAgcmV0dXJuIG5hbWUuZXF1YWxzSWdub3JlQ2FzZSh0aGF0LmdldE5hbWUoKSkKKyAgICAgICAgICAgICAgICAgICAgJiYgKGRvbWFpbiAhPSBudWxsID8gZG9tYWluLmVxdWFsc0lnbm9yZUNhc2UodGhhdC5kb21haW4pIDogdGhhdC5kb21haW4gPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgJiYgT2JqZWN0cy5lcXVhbChwYXRoLCB0aGF0LnBhdGgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgb2YgdGhpcyBIVFRQIGNvb2tpZTogPHByZT4gICB7QGNvZGUKKyAgICAgKiAgIG5hbWUudG9Mb3dlckNhc2UoTG9jYWxlLlVTKS5oYXNoQ29kZSgpCisgICAgICogICAgICAgKyAoZG9tYWluID09IG51bGwgPyAwIDogZG9tYWluLnRvTG93ZXJDYXNlKExvY2FsZS5VUykuaGFzaENvZGUoKSkKKyAgICAgKiAgICAgICArIChwYXRoID09IG51bGwgPyAwIDogcGF0aC5oYXNoQ29kZSgpKQorICAgICAqIH08L3ByZT4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWUudG9Mb3dlckNhc2UoTG9jYWxlLlVTKS5oYXNoQ29kZSgpCisgICAgICAgICAgICAgICAgKyAoZG9tYWluID09IG51bGwgPyAwIDogZG9tYWluLnRvTG93ZXJDYXNlKExvY2FsZS5VUykuaGFzaENvZGUoKSkKKyAgICAgICAgICAgICAgICArIChwYXRoID09IG51bGwgPyAwIDogcGF0aC5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGlzIGNvb2tpZSBpbiB0aGUgZm9ybWF0IHVzZWQgYnkgdGhlCisgICAgICoge0Bjb2RlIENvb2tpZX0gaGVhZGVyIGxpbmUgaW4gYW4gSFRUUCByZXF1ZXN0LgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBpZiAodmVyc2lvbiA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbmFtZSArICI9IiArIHZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpCisgICAgICAgICAgICAgICAgLmFwcGVuZChuYW1lKQorICAgICAgICAgICAgICAgIC5hcHBlbmQoIj0iKQorICAgICAgICAgICAgICAgIC5hcHBlbmQoIlwiIikKKyAgICAgICAgICAgICAgICAuYXBwZW5kKHZhbHVlKQorICAgICAgICAgICAgICAgIC5hcHBlbmQoIlwiIik7CisgICAgICAgIGFwcGVuZEF0dHJpYnV0ZShyZXN1bHQsICJQYXRoIiwgcGF0aCk7CisgICAgICAgIGFwcGVuZEF0dHJpYnV0ZShyZXN1bHQsICJEb21haW4iLCBkb21haW4pOworICAgICAgICBhcHBlbmRBdHRyaWJ1dGUocmVzdWx0LCAiUG9ydCIsIHBvcnRMaXN0KTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhcHBlbmRBdHRyaWJ1dGUoU3RyaW5nQnVpbGRlciBidWlsZGVyLCBTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsICYmIGJ1aWxkZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoIjskIik7CisgICAgICAgICAgICBidWlsZGVyLmFwcGVuZChuYW1lKTsKKyAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCI9XCIiKTsKKyAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKHZhbHVlKTsKKyAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCJcIiIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0h0dHBSZXRyeUV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0h0dHBSZXRyeUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlOWZkYTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvSHR0cFJldHJ5RXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw5MSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogSWYgYSBIVFRQIHJlcXVlc3QgaGFzIHRvIGJlIHJldHJpZWQsIHRoaXMgZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duIGlmIHRoZQorICogcmVxdWVzdCBjYW5ub3QgYmUgcmV0cmllZCBhdXRvbWF0aWNhbGx5LgorICovCitwdWJsaWMgY2xhc3MgSHR0cFJldHJ5RXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTkxODYwMjIyODY0NjkxMTEzODFMOworCisgICAgcHJpdmF0ZSBpbnQgcmVzcG9uc2VDb2RlOworCisgICAgcHJpdmF0ZSBTdHJpbmcgbG9jYXRpb24gPSBudWxsOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgSHR0cFJldHJ5RXhjZXB0aW9ufSBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiByZXNwb25zZSBjb2RlIGFuZCB0aGUgZ2l2ZW4gZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBjb2RlCisgICAgICogICAgICAgICAgICB0aGUgSFRUUCByZXNwb25zZSBjb2RlIGZyb20gdGFyZ2V0IGhvc3QuCisgICAgICovCisgICAgcHVibGljIEh0dHBSZXRyeUV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsLCBpbnQgY29kZSkgeworICAgICAgICBzdXBlcihkZXRhaWwpOworICAgICAgICByZXNwb25zZUNvZGUgPSBjb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEh0dHBSZXRyeUV4Y2VwdGlvbn0gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogcmVzcG9uc2UgY29kZSwgdGhlIGdpdmVuIGRldGFpbCBtZXNzYWdlIGFuZCB0aGUgdmFsdWUgb2YgdGhlIGxvY2F0aW9uCisgICAgICogZmllbGQgZnJvbSB0aGUgcmVzcG9uc2UgaGVhZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbAorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gY29kZQorICAgICAqICAgICAgICAgICAgdGhlIEhUVFAgcmVzcG9uc2UgY29kZSBmcm9tIHRhcmdldCBob3N0LgorICAgICAqIEBwYXJhbSBsb2NhdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGRlc3RpbmF0aW9uIFVSTCBvZiB0aGUgcmVkaXJlY3Rpb24uCisgICAgICovCisgICAgcHVibGljIEh0dHBSZXRyeUV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsLCBpbnQgY29kZSwgU3RyaW5nIGxvY2F0aW9uKSB7CisgICAgICAgIHN1cGVyKGRldGFpbCk7CisgICAgICAgIHJlc3BvbnNlQ29kZSA9IGNvZGU7CisgICAgICAgIHRoaXMubG9jYXRpb24gPSBsb2NhdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsb2NhdGlvbiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN0b3JlZCBsb2NhdGlvbiBmcm9tIHRoZSBIVFRQIGhlYWRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldExvY2F0aW9uKCkgeworICAgICAgICByZXR1cm4gbG9jYXRpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFJlYXNvbigpIHsKKyAgICAgICAgcmV0dXJuIGdldE1lc3NhZ2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSByZXNwb25zZSBjb2RlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgSFRUUCByZXNwb25zZSBjb2RlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgcmVzcG9uc2VDb2RlKCkgeworICAgICAgICByZXR1cm4gcmVzcG9uc2VDb2RlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9IdHRwVVJMQ29ubmVjdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0h0dHBVUkxDb25uZWN0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTU0ZTExYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9IdHRwVVJMQ29ubmVjdGlvbi5qYXZhCkBAIC0wLDAgKzEsNzgzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgbGliY29yZS5uZXQuaHR0cC5IdHRwRW5naW5lOworCisvKioKKyAqIEFuIHtAbGluayBVUkxDb25uZWN0aW9ufSBmb3IgSFRUUCAoPGEKKyAqIGhyZWY9Imh0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzI2MTYiPlJGQyAyNjE2PC9hPikgdXNlZCB0byBzZW5kIGFuZAorICogcmVjZWl2ZSBkYXRhIG92ZXIgdGhlIHdlYi4gRGF0YSBtYXkgYmUgb2YgYW55IHR5cGUgYW5kIGxlbmd0aC4gVGhpcyBjbGFzcyBtYXkKKyAqIGJlIHVzZWQgdG8gc2VuZCBhbmQgcmVjZWl2ZSBzdHJlYW1pbmcgZGF0YSB3aG9zZSBsZW5ndGggaXMgbm90IGtub3duIGluCisgKiBhZHZhbmNlLgorICoKKyAqIDxwPlVzZXMgb2YgdGhpcyBjbGFzcyBmb2xsb3cgYSBwYXR0ZXJuOgorICogPG9sPgorICogICA8bGk+T2J0YWluIGEgbmV3IHtAY29kZSBIdHRwVVJMQ29ubmVjdGlvbn0gYnkgY2FsbGluZyB7QGxpbmsKKyAqICAgICAgIFVSTCNvcGVuQ29ubmVjdGlvbigpIFVSTC5vcGVuQ29ubmVjdGlvbigpfSBhbmQgY2FzdGluZyB0aGUgcmVzdWx0IHRvCisgKiAgICAgICB7QGNvZGUgSHR0cFVSTENvbm5lY3Rpb259LgorICogICA8bGk+UHJlcGFyZSB0aGUgcmVxdWVzdC4gVGhlIHByaW1hcnkgcHJvcGVydHkgb2YgYSByZXF1ZXN0IGlzIGl0cyBVUkkuCisgKiAgICAgICBSZXF1ZXN0IGhlYWRlcnMgbWF5IGFsc28gaW5jbHVkZSBtZXRhZGF0YSBzdWNoIGFzIGNyZWRlbnRpYWxzLCBwcmVmZXJyZWQKKyAqICAgICAgIGNvbnRlbnQgdHlwZXMsIGFuZCBzZXNzaW9uIGNvb2tpZXMuCisgKiAgIDxsaT5PcHRpb25hbGx5IHVwbG9hZCBhIHJlcXVlc3QgYm9keS4gSW5zdGFuY2VzIG11c3QgYmUgY29uZmlndXJlZCB3aXRoCisgKiAgICAgICB7QGxpbmsgI3NldERvT3V0cHV0KGJvb2xlYW4pIHNldERvT3V0cHV0KHRydWUpfSBpZiB0aGV5IGluY2x1ZGUgYQorICogICAgICAgcmVxdWVzdCBib2R5LiBUcmFuc21pdCBkYXRhIGJ5IHdyaXRpbmcgdG8gdGhlIHN0cmVhbSByZXR1cm5lZCBieSB7QGxpbmsKKyAqICAgICAgICNnZXRPdXRwdXRTdHJlYW0oKX0uCisgKiAgIDxsaT5SZWFkIHRoZSByZXNwb25zZS4gUmVzcG9uc2UgaGVhZGVycyB0eXBpY2FsbHkgaW5jbHVkZSBtZXRhZGF0YSBzdWNoIGFzCisgKiAgICAgICB0aGUgcmVzcG9uc2UgYm9keSdzIGNvbnRlbnQgdHlwZSBhbmQgbGVuZ3RoLCBtb2RpZmllZCBkYXRlcyBhbmQgc2Vzc2lvbgorICogICAgICAgY29va2llcy4gVGhlIHJlc3BvbnNlIGJvZHkgbWF5IGJlIHJlYWQgZnJvbSB0aGUgc3RyZWFtIHJldHVybmVkIGJ5IHtAbGluaworICogICAgICAgI2dldElucHV0U3RyZWFtKCl9LiBJZiB0aGUgcmVzcG9uc2UgaGFzIG5vIGJvZHksIHRoYXQgbWV0aG9kIHJldHVybnMgYW4KKyAqICAgICAgIGVtcHR5IHN0cmVhbS4KKyAqICAgPGxpPkRpc2Nvbm5lY3QuIE9uY2UgdGhlIHJlc3BvbnNlIGJvZHkgaGFzIGJlZW4gcmVhZCwgdGhlIHtAY29kZQorICogICAgICAgSHR0cFVSTENvbm5lY3Rpb259IHNob3VsZCBiZSBjbG9zZWQgYnkgY2FsbGluZyB7QGxpbmsgI2Rpc2Nvbm5lY3QoKX0uCisgKiAgICAgICBEaXNjb25uZWN0aW5nIHJlbGVhc2VzIHRoZSByZXNvdXJjZXMgaGVsZCBieSBhIGNvbm5lY3Rpb24gc28gdGhleSBtYXkKKyAqICAgICAgIGJlIGNsb3NlZCBvciByZXVzZWQuCisgKiA8L29sPgorICoKKyAqIDxwPkZvciBleGFtcGxlLCB0byByZXRyaWV2ZSB0aGUgd2VicGFnZSBhdCB7QGNvZGUgaHR0cDovL3d3dy5hbmRyb2lkLmNvbS99OgorICogPHByZT4gICB7QGNvZGUKKyAqICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6Ly93d3cuYW5kcm9pZC5jb20vIik7CisgKiAgIEh0dHBVUkxDb25uZWN0aW9uIHVybENvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHVybC5vcGVuQ29ubmVjdGlvbigpOworICogICB0cnkgeworICogICAgIElucHV0U3RyZWFtIGluID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0odXJsQ29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpKTsKKyAqICAgICByZWFkU3RyZWFtKGluKTsKKyAqICAgfSBmaW5hbGx5IHsKKyAqICAgICB1cmxDb25uZWN0aW9uLmRpc2Nvbm5lY3QoKTsKKyAqICAgfQorICogfTwvcHJlPgorICoKKyAqIDxoMz5TZWN1cmUgQ29tbXVuaWNhdGlvbiB3aXRoIEhUVFBTPC9oMz4KKworICogQ2FsbGluZyB7QGxpbmsgVVJMI29wZW5Db25uZWN0aW9uKCl9IG9uIGEgVVJMIHdpdGggdGhlICJodHRwcyIKKyAqIHNjaGVtZSB3aWxsIHJldHVybiBhbiB7QGNvZGUgSHR0cHNVUkxDb25uZWN0aW9ufSwgd2hpY2ggYWxsb3dzIGZvcgorICogb3ZlcnJpZGluZyB0aGUgZGVmYXVsdCB7QGxpbmsgamF2YXgubmV0LnNzbC5Ib3N0bmFtZVZlcmlmaWVyCisgKiBIb3N0bmFtZVZlcmlmaWVyfSBhbmQge0BsaW5rIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0RmFjdG9yeQorICogU1NMU29ja2V0RmFjdG9yeX0uIEFuIGFwcGxpY2F0aW9uLXN1cHBsaWVkIHtAY29kZSBTU0xTb2NrZXRGYWN0b3J5fQorICogY3JlYXRlZCBmcm9tIGFuIHtAbGluayBqYXZheC5uZXQuc3NsLlNTTENvbnRleHQgU1NMQ29udGV4dH0gY2FuCisgKiBwcm92aWRlIGEgY3VzdG9tIHtAbGluayBqYXZheC5uZXQuc3NsLlg1MDlUcnVzdE1hbmFnZXIKKyAqIFg1MDlUcnVzdE1hbmFnZXJ9IGZvciB2ZXJpZnlpbmcgY2VydGlmaWNhdGUgY2hhaW5zIGFuZCBhIGN1c3RvbQorICoge0BsaW5rIGphdmF4Lm5ldC5zc2wuWDUwOUtleU1hbmFnZXIgWDUwOUtleU1hbmFnZXJ9IGZvciBzdXBwbHlpbmcKKyAqIGNsaWVudCBjZXJ0aWZpY2F0ZXMuIFNlZSB7QGxpbmsgamF2YXgubmV0LnNzbC5IdHRwc1VSTENvbm5lY3Rpb24KKyAqIEh0dHBzVVJMQ29ubmVjdGlvbn0gZm9yIG1vcmUgZGV0YWlscy4KKyAqCisgKiA8aDM+UmVzcG9uc2UgSGFuZGxpbmc8L2gzPgorICoge0Bjb2RlIEh0dHBVUkxDb25uZWN0aW9ufSB3aWxsIGZvbGxvdyB1cCB0byBmaXZlIEhUVFAgcmVkaXJlY3RzLiBJdCB3aWxsCisgKiBmb2xsb3cgcmVkaXJlY3RzIGZyb20gb25lIG9yaWdpbiBzZXJ2ZXIgdG8gYW5vdGhlci4gVGhpcyBpbXBsZW1lbnRhdGlvbgorICogZG9lc24ndCBmb2xsb3cgcmVkaXJlY3RzIGZyb20gSFRUUFMgdG8gSFRUUCBvciB2aWNlIHZlcnNhLgorICoKKyAqIDxwPklmIHRoZSBIVFRQIHJlc3BvbnNlIGluZGljYXRlcyB0aGF0IGFuIGVycm9yIG9jY3VycmVkLCB7QGxpbmsKKyAqICNnZXRJbnB1dFN0cmVhbSgpfSB3aWxsIHRocm93IGFuIHtAbGluayBJT0V4Y2VwdGlvbn0uIFVzZSB7QGxpbmsKKyAqICNnZXRFcnJvclN0cmVhbSgpfSB0byByZWFkIHRoZSBlcnJvciByZXNwb25zZS4gVGhlIGhlYWRlcnMgY2FuIGJlIHJlYWQgaW4KKyAqIHRoZSBub3JtYWwgd2F5IHVzaW5nIHtAbGluayAjZ2V0SGVhZGVyRmllbGRzKCl9LAorICoKKyAqIDxoMz5Qb3N0aW5nIENvbnRlbnQ8L2gzPgorICogVG8gdXBsb2FkIGRhdGEgdG8gYSB3ZWIgc2VydmVyLCBjb25maWd1cmUgdGhlIGNvbm5lY3Rpb24gZm9yIG91dHB1dCB1c2luZworICoge0BsaW5rICNzZXREb091dHB1dChib29sZWFuKSBzZXREb091dHB1dCh0cnVlKX0uCisgKgorICogPHA+Rm9yIGJlc3QgcGVyZm9ybWFuY2UsIHlvdSBzaG91bGQgY2FsbCBlaXRoZXIge0BsaW5rCisgKiAjc2V0Rml4ZWRMZW5ndGhTdHJlYW1pbmdNb2RlKGludCl9IHdoZW4gdGhlIGJvZHkgbGVuZ3RoIGlzIGtub3duIGluIGFkdmFuY2UsCisgKiBvciB7QGxpbmsgI3NldENodW5rZWRTdHJlYW1pbmdNb2RlKGludCl9IHdoZW4gaXQgaXMgbm90LiBPdGhlcndpc2Uge0Bjb2RlCisgKiBIdHRwVVJMQ29ubmVjdGlvbn0gd2lsbCBiZSBmb3JjZWQgdG8gYnVmZmVyIHRoZSBjb21wbGV0ZSByZXF1ZXN0IGJvZHkgaW4KKyAqIG1lbW9yeSBiZWZvcmUgaXQgaXMgdHJhbnNtaXR0ZWQsIHdhc3RpbmcgKGFuZCBwb3NzaWJseSBleGhhdXN0aW5nKSBoZWFwIGFuZAorICogaW5jcmVhc2luZyBsYXRlbmN5LgorICoKKyAqIDxwPkZvciBleGFtcGxlLCB0byBwZXJmb3JtIGFuIHVwbG9hZDogPHByZT4gICB7QGNvZGUKKyAqICAgSHR0cFVSTENvbm5lY3Rpb24gdXJsQ29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgKiAgIHRyeSB7CisgKiAgICAgdXJsQ29ubmVjdGlvbi5zZXREb091dHB1dCh0cnVlKTsKKyAqICAgICB1cmxDb25uZWN0aW9uLnNldENodW5rZWRTdHJlYW1pbmdNb2RlKDApOworICoKKyAqICAgICBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKHVybENvbm5lY3Rpb24uZ2V0T3V0cHV0U3RyZWFtKCkpOworICogICAgIHdyaXRlU3RyZWFtKG91dCk7CisgKgorICogICAgIElucHV0U3RyZWFtIGluID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0odXJsQ29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpKTsKKyAqICAgICByZWFkU3RyZWFtKGluKTsKKyAqICAgfSBmaW5hbGx5IHsKKyAqICAgICB1cmxDb25uZWN0aW9uLmRpc2Nvbm5lY3QoKTsKKyAqICAgfQorICogfTwvcHJlPgorICoKKyAqIDxoMz5QZXJmb3JtYW5jZTwvaDM+CisgKiBUaGUgaW5wdXQgYW5kIG91dHB1dCBzdHJlYW1zIHJldHVybmVkIGJ5IHRoaXMgY2xhc3MgYXJlIDxzdHJvbmc+bm90CisgKiBidWZmZXJlZDwvc3Ryb25nPi4gTW9zdCBjYWxsZXJzIHNob3VsZCB3cmFwIHRoZSByZXR1cm5lZCBzdHJlYW1zIHdpdGgge0BsaW5rCisgKiBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW0gQnVmZmVyZWRJbnB1dFN0cmVhbX0gb3Ige0BsaW5rCisgKiBqYXZhLmlvLkJ1ZmZlcmVkT3V0cHV0U3RyZWFtIEJ1ZmZlcmVkT3V0cHV0U3RyZWFtfS4gQ2FsbGVycyB0aGF0IGRvIG9ubHkgYnVsaworICogcmVhZHMgb3Igd3JpdGVzIG1heSBvbWl0IGJ1ZmZlcmluZy4KKyAqCisgKiA8cD5XaGVuIHRyYW5zZmVycmluZyBsYXJnZSBhbW91bnRzIG9mIGRhdGEgdG8gb3IgZnJvbSBhIHNlcnZlciwgdXNlIHN0cmVhbXMKKyAqIHRvIGxpbWl0IGhvdyBtdWNoIGRhdGEgaXMgaW4gbWVtb3J5IGF0IG9uY2UuIFVubGVzcyB5b3UgbmVlZCB0aGUgZW50aXJlCisgKiBib2R5IHRvIGJlIGluIG1lbW9yeSBhdCBvbmNlLCBwcm9jZXNzIGl0IGFzIGEgc3RyZWFtIChyYXRoZXIgdGhhbiBzdG9yaW5nCisgKiB0aGUgY29tcGxldGUgYm9keSBhcyBhIHNpbmdsZSBieXRlIGFycmF5IG9yIHN0cmluZykuCisgKgorICogPHA+VG8gcmVkdWNlIGxhdGVuY3ksIHRoaXMgY2xhc3MgbWF5IHJldXNlIHRoZSBzYW1lIHVuZGVybHlpbmcge0Bjb2RlIFNvY2tldH0KKyAqIGZvciBtdWx0aXBsZSByZXF1ZXN0L3Jlc3BvbnNlIHBhaXJzLiBBcyBhIHJlc3VsdCwgSFRUUCBjb25uZWN0aW9ucyBtYXkgYmUKKyAqIGhlbGQgb3BlbiBsb25nZXIgdGhhbiBuZWNlc3NhcnkuIENhbGxzIHRvIHtAbGluayAjZGlzY29ubmVjdCgpfSBtYXkgcmV0dXJuCisgKiB0aGUgc29ja2V0IHRvIGEgcG9vbCBvZiBjb25uZWN0ZWQgc29ja2V0cy4gVGhpcyBiZWhhdmlvciBjYW4gYmUgZGlzYWJsZWQgYnkKKyAqIHNldHRpbmcgdGhlICJodHRwLmtlZXBBbGl2ZSIgc3lzdGVtIHByb3BlcnR5IHRvICJmYWxzZSIgYmVmb3JlIGlzc3VpbmcgYW55CisgKiBIVFRQIHJlcXVlc3RzLiBUaGUgImh0dHAubWF4Q29ubmVjdGlvbnMiIHByb3BlcnR5IG1heSBiZSB1c2VkIHRvIGNvbnRyb2wgaG93CisgKiBtYW55IGlkbGUgY29ubmVjdGlvbnMgdG8gZWFjaCBzZXJ2ZXIgd2lsbCBiZSBoZWxkLgorICoKKyAqIDxwPkJ5IGRlZmF1bHQsIHRoaXMgaW1wbGVtZW50YXRpb24gb2Yge0Bjb2RlIEh0dHBVUkxDb25uZWN0aW9ufSByZXF1ZXN0cyB0aGF0CisgKiBzZXJ2ZXJzIHVzZSBnemlwIGNvbXByZXNzaW9uLiBTaW5jZSB7QGxpbmsgI2dldENvbnRlbnRMZW5ndGgoKX0gcmV0dXJucyB0aGUKKyAqIG51bWJlciBvZiBieXRlcyB0cmFuc21pdHRlZCwgeW91IGNhbm5vdCB1c2UgdGhhdCBtZXRob2QgdG8gcHJlZGljdCBob3cgbWFueQorICogYnl0ZXMgY2FuIGJlIHJlYWQgZnJvbSB7QGxpbmsgI2dldElucHV0U3RyZWFtKCl9LiBJbnN0ZWFkLCByZWFkIHRoYXQgc3RyZWFtCisgKiB1bnRpbCBpdCBpcyBleGhhdXN0ZWQ6IHdoZW4ge0BsaW5rIElucHV0U3RyZWFtI3JlYWR9IHJldHVybnMgLTEuIEd6aXAKKyAqIGNvbXByZXNzaW9uIGNhbiBiZSBkaXNhYmxlZCBieSBzZXR0aW5nIHRoZSBhY2NlcHRhYmxlIGVuY29kaW5ncyBpbiB0aGUKKyAqIHJlcXVlc3QgaGVhZGVyOiA8cHJlPiAgIHtAY29kZQorICogICB1cmxDb25uZWN0aW9uLnNldFJlcXVlc3RQcm9wZXJ0eSgiQWNjZXB0LUVuY29kaW5nIiwgImlkZW50aXR5Iik7CisgKiB9PC9wcmU+CisgKgorICogPGgzPkhhbmRsaW5nIE5ldHdvcmsgU2lnbi1PbjwvaDM+CisgKiBTb21lIFdpLUZpIG5ldHdvcmtzIGJsb2NrIEludGVybmV0IGFjY2VzcyB1bnRpbCB0aGUgdXNlciBjbGlja3MgdGhyb3VnaCBhCisgKiBzaWduLW9uIHBhZ2UuIFN1Y2ggc2lnbi1vbiBwYWdlcyBhcmUgdHlwaWNhbGx5IHByZXNlbnRlZCBieSB1c2luZyBIVFRQCisgKiByZWRpcmVjdHMuIFlvdSBjYW4gdXNlIHtAbGluayAjZ2V0VVJMKCl9IHRvIHRlc3QgaWYgeW91ciBjb25uZWN0aW9uIGhhcyBiZWVuCisgKiB1bmV4cGVjdGVkbHkgcmVkaXJlY3RlZC4gVGhpcyBjaGVjayBpcyBub3QgdmFsaWQgdW50aWwgPHN0cm9uZz5hZnRlcjwvc3Ryb25nPgorICogdGhlIHJlc3BvbnNlIGhlYWRlcnMgaGF2ZSBiZWVuIHJlY2VpdmVkLCB3aGljaCB5b3UgY2FuIHRyaWdnZXIgYnkgY2FsbGluZworICoge0BsaW5rICNnZXRIZWFkZXJGaWVsZHMoKX0gb3Ige0BsaW5rICNnZXRJbnB1dFN0cmVhbSgpfS4gRm9yIGV4YW1wbGUsIHRvCisgKiBjaGVjayB0aGF0IGEgcmVzcG9uc2Ugd2FzIG5vdCByZWRpcmVjdGVkIHRvIGFuIHVuZXhwZWN0ZWQgaG9zdDoKKyAqIDxwcmU+ICAge0Bjb2RlCisgKiAgIEh0dHBVUkxDb25uZWN0aW9uIHVybENvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHVybC5vcGVuQ29ubmVjdGlvbigpOworICogICB0cnkgeworICogICAgIElucHV0U3RyZWFtIGluID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0odXJsQ29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpKTsKKyAqICAgICBpZiAoIXVybC5nZXRIb3N0KCkuZXF1YWxzKHVybENvbm5lY3Rpb24uZ2V0VVJMKCkuZ2V0SG9zdCgpKSkgeworICogICAgICAgLy8gd2Ugd2VyZSByZWRpcmVjdGVkISBLaWNrIHRoZSB1c2VyIG91dCB0byB0aGUgYnJvd3NlciB0byBzaWduIG9uPworICogICAgIH0KKyAqICAgICAuLi4KKyAqICAgfSBmaW5hbGx5IHsKKyAqICAgICB1cmxDb25uZWN0aW9uLmRpc2Nvbm5lY3QoKTsKKyAqICAgfQorICogfTwvcHJlPgorICoKKyAqIDxoMz5IVFRQIEF1dGhlbnRpY2F0aW9uPC9oMz4KKyAqIHtAY29kZSBIdHRwVVJMQ29ubmVjdGlvbn0gc3VwcG9ydHMgPGEKKyAqIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzI2MTciPkhUVFAgYmFzaWMgYXV0aGVudGljYXRpb248L2E+LiBVc2UKKyAqIHtAbGluayBBdXRoZW50aWNhdG9yfSB0byBzZXQgdGhlIFZNLXdpZGUgYXV0aGVudGljYXRpb24gaGFuZGxlcjoKKyAqIDxwcmU+ICAge0Bjb2RlCisgKiAgIEF1dGhlbnRpY2F0b3Iuc2V0RGVmYXVsdChuZXcgQXV0aGVudGljYXRvcigpIHsKKyAqICAgICBwcm90ZWN0ZWQgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiBnZXRQYXNzd29yZEF1dGhlbnRpY2F0aW9uKCkgeworICogICAgICAgcmV0dXJuIG5ldyBQYXNzd29yZEF1dGhlbnRpY2F0aW9uKHVzZXJuYW1lLCBwYXNzd29yZC50b0NoYXJBcnJheSgpKTsKKyAqICAgICB9CisgKiAgIH0pOworICogfTwvcHJlPgorICogVW5sZXNzIHBhaXJlZCB3aXRoIEhUVFBTLCB0aGlzIGlzIDxzdHJvbmc+bm90PC9zdHJvbmc+IGEgc2VjdXJlIG1lY2hhbmlzbSBmb3IKKyAqIHVzZXIgYXV0aGVudGljYXRpb24uIEluIHBhcnRpY3VsYXIsIHRoZSB1c2VybmFtZSwgcGFzc3dvcmQsIHJlcXVlc3QgYW5kCisgKiByZXNwb25zZSBhcmUgYWxsIHRyYW5zbWl0dGVkIG92ZXIgdGhlIG5ldHdvcmsgd2l0aG91dCBlbmNyeXB0aW9uLgorICoKKyAqIDxoMz5TZXNzaW9ucyB3aXRoIENvb2tpZXM8L2gzPgorICogVG8gZXN0YWJsaXNoIGFuZCBtYWludGFpbiBhIHBvdGVudGlhbGx5IGxvbmctbGl2ZWQgc2Vzc2lvbiBiZXR3ZWVuIGNsaWVudAorICogYW5kIHNlcnZlciwge0Bjb2RlIEh0dHBVUkxDb25uZWN0aW9ufSBpbmNsdWRlcyBhbiBleHRlbnNpYmxlIGNvb2tpZSBtYW5hZ2VyLgorICogRW5hYmxlIFZNLXdpZGUgY29va2llIG1hbmFnZW1lbnQgdXNpbmcge0BsaW5rIENvb2tpZUhhbmRsZXJ9IGFuZCB7QGxpbmsKKyAqIENvb2tpZU1hbmFnZXJ9OiA8cHJlPiAgIHtAY29kZQorICogICBDb29raWVNYW5hZ2VyIGNvb2tpZU1hbmFnZXIgPSBuZXcgQ29va2llTWFuYWdlcigpOworICogICBDb29raWVIYW5kbGVyLnNldERlZmF1bHQoY29va2llTWFuYWdlcik7CisgKiB9PC9wcmU+CisgKiBCeSBkZWZhdWx0LCB7QGNvZGUgQ29va2llTWFuYWdlcn0gYWNjZXB0cyBjb29raWVzIGZyb20gdGhlIDxhCisgKiBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9Qcm90b2NvbHMvcmZjMjYxNi9yZmMyNjE2LXNlYzEuaHRtbCI+b3JpZ2luCisgKiBzZXJ2ZXI8L2E+IG9ubHkuIFR3byBvdGhlciBwb2xpY2llcyBhcmUgaW5jbHVkZWQ6IHtAbGluaworICogQ29va2llUG9saWN5I0FDQ0VQVF9BTEx9IGFuZCB7QGxpbmsgQ29va2llUG9saWN5I0FDQ0VQVF9OT05FfS4gSW1wbGVtZW50CisgKiB7QGxpbmsgQ29va2llUG9saWN5fSB0byBkZWZpbmUgYSBjdXN0b20gcG9saWN5LgorICoKKyAqIDxwPlRoZSBkZWZhdWx0IHtAY29kZSBDb29raWVNYW5hZ2VyfSBrZWVwcyBhbGwgYWNjZXB0ZWQgY29va2llcyBpbiBtZW1vcnkuIEl0CisgKiB3aWxsIGZvcmdldCB0aGVzZSBjb29raWVzIHdoZW4gdGhlIFZNIGV4aXRzLiBJbXBsZW1lbnQge0BsaW5rIENvb2tpZVN0b3JlfSB0bworICogZGVmaW5lIGEgY3VzdG9tIGNvb2tpZSBzdG9yZS4KKyAqCisgKiA8cD5JbiBhZGRpdGlvbiB0byB0aGUgY29va2llcyBzZXQgYnkgSFRUUCByZXNwb25zZXMsIHlvdSBtYXkgc2V0IGNvb2tpZXMKKyAqIHByb2dyYW1tYXRpY2FsbHkuIFRvIGJlIGluY2x1ZGVkIGluIEhUVFAgcmVxdWVzdCBoZWFkZXJzLCBjb29raWVzIG11c3QgaGF2ZQorICogdGhlIGRvbWFpbiBhbmQgcGF0aCBwcm9wZXJ0aWVzIHNldC4KKyAqCisgKiA8cD5CeSBkZWZhdWx0LCBuZXcgaW5zdGFuY2VzIG9mIHtAY29kZSBIdHRwQ29va2llfSB3b3JrIG9ubHkgd2l0aCBzZXJ2ZXJzCisgKiB0aGF0IHN1cHBvcnQgPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjk2NS50eHQiPlJGQyAyOTY1PC9hPgorICogY29va2llcy4gTWFueSB3ZWIgc2VydmVycyBzdXBwb3J0IG9ubHkgdGhlIG9sZGVyIHNwZWNpZmljYXRpb24sIDxhCisgKiBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMTA5LnR4dCI+UkZDIDIxMDk8L2E+LiBGb3IgY29tcGF0aWJpbGl0eQorICogd2l0aCB0aGUgbW9zdCB3ZWIgc2VydmVycywgc2V0IHRoZSBjb29raWUgdmVyc2lvbiB0byAwLgorICoKKyAqIDxwPkZvciBleGFtcGxlLCB0byByZWNlaXZlIHtAY29kZSB3d3cudHdpdHRlci5jb219IGluIEZyZW5jaDogPHByZT4gICB7QGNvZGUKKyAqICAgSHR0cENvb2tpZSBjb29raWUgPSBuZXcgSHR0cENvb2tpZSgibGFuZyIsICJmciIpOworICogICBjb29raWUuc2V0RG9tYWluKCJ0d2l0dGVyLmNvbSIpOworICogICBjb29raWUuc2V0UGF0aCgiLyIpOworICogICBjb29raWUuc2V0VmVyc2lvbigwKTsKKyAqICAgY29va2llTWFuYWdlci5nZXRDb29raWVTdG9yZSgpLmFkZChuZXcgVVJJKCJodHRwOi8vdHdpdHRlci5jb20vIiksIGNvb2tpZSk7CisgKiB9PC9wcmU+CisgKgorICogPGgzPkhUVFAgTWV0aG9kczwvaDM+CisgKiA8cD57QGNvZGUgSHR0cFVSTENvbm5lY3Rpb259IHVzZXMgdGhlIHtAY29kZSBHRVR9IG1ldGhvZCBieSBkZWZhdWx0LiBJdCB3aWxsCisgKiB1c2Uge0Bjb2RlIFBPU1R9IGlmIHtAbGluayAjc2V0RG9PdXRwdXQgc2V0RG9PdXRwdXQodHJ1ZSl9IGhhcyBiZWVuIGNhbGxlZC4KKyAqIE90aGVyIEhUVFAgbWV0aG9kcyAoe0Bjb2RlIE9QVElPTlN9LCB7QGNvZGUgSEVBRH0sIHtAY29kZSBQVVR9LCB7QGNvZGUKKyAqIERFTEVURX0gYW5kIHtAY29kZSBUUkFDRX0pIGNhbiBiZSB1c2VkIHdpdGgge0BsaW5rICNzZXRSZXF1ZXN0TWV0aG9kfS4KKyAqCisgKiA8aDM+UHJveGllczwvaDM+CisgKiBCeSBkZWZhdWx0LCB0aGlzIGNsYXNzIHdpbGwgY29ubmVjdCBkaXJlY3RseSB0byB0aGUgPGEKKyAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1Byb3RvY29scy9yZmMyNjE2L3JmYzI2MTYtc2VjMS5odG1sIj5vcmlnaW4KKyAqIHNlcnZlcjwvYT4uIEl0IGNhbiBhbHNvIGNvbm5lY3QgdmlhIGFuIHtAbGluayBQcm94eS5UeXBlI0hUVFAgSFRUUH0gb3Ige0BsaW5rCisgKiBQcm94eS5UeXBlI1NPQ0tTIFNPQ0tTfSBwcm94eS4gVG8gdXNlIGEgcHJveHksIHVzZSB7QGxpbmsKKyAqIFVSTCNvcGVuQ29ubmVjdGlvbihQcm94eSkgVVJMLm9wZW5Db25uZWN0aW9uKFByb3h5KX0gd2hlbiBjcmVhdGluZyB0aGUKKyAqIGNvbm5lY3Rpb24uCisgKgorICogPGgzPklQdjYgU3VwcG9ydDwvaDM+CisgKiA8cD5UaGlzIGNsYXNzIGluY2x1ZGVzIHRyYW5zcGFyZW50IHN1cHBvcnQgZm9yIElQdjYuIEZvciBob3N0cyB3aXRoIGJvdGggSVB2NAorICogYW5kIElQdjYgYWRkcmVzc2VzLCBpdCB3aWxsIGF0dGVtcHQgdG8gY29ubmVjdCB0byBlYWNoIG9mIGEgaG9zdCdzIGFkZHJlc3NlcworICogdW50aWwgYSBjb25uZWN0aW9uIGlzIGVzdGFibGlzaGVkLgorICoKKyAqIDxoMz5SZXNwb25zZSBDYWNoaW5nPC9oMz4KKyAqIDxwPntAY29kZSBIdHRwVVJMQ29ubmVjdGlvbn0gc3VwcG9ydHMgYSBWTS13aWRlIEhUVFAgcmVzcG9uc2UgY2FjaGUuCisgKiBJbXBsZW1lbnQge0BsaW5rIFJlc3BvbnNlQ2FjaGV9IGFuZCB1c2Uge0BsaW5rIFJlc3BvbnNlQ2FjaGUjc2V0RGVmYXVsdH0gdG8KKyAqIGluc3RhbGwgYSBjdXN0b20gY2FjaGUuIEltcGxlbWVudGluZyB0aGlzIEFQSSBpcyBvbmVyb3VzOiBjb3JyZWN0CisgKiBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIGZvbGxvdyBhbGwgY2FjaGluZyBydWxlcyBkZWZpbmVkIGJ5IDxhCisgKiBocmVmPSJodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMyNjE2I3NlY3Rpb24tMTMiPlNlY3Rpb24gMTMgb2YgUkZDCisgKiAyNjE2PC9hPi4KKyAqCisgKiA8cD5FYWNoIGluc3RhbmNlIG9mIHtAY29kZSBIdHRwVVJMQ29ubmVjdGlvbn0gbWF5IGJlIHVzZWQgZm9yIG9uZQorICogcmVxdWVzdC9yZXNwb25zZSBwYWlyLiBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyBhcmUgbm90IHRocmVhZCBzYWZlLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgSHR0cFVSTENvbm5lY3Rpb24gZXh0ZW5kcyBVUkxDb25uZWN0aW9uIHsKKworICAgIC8qKgorICAgICAqIFRoZSBzdWJzZXQgb2YgSFRUUCBtZXRob2RzIHRoYXQgdGhlIHVzZXIgbWF5IHNlbGVjdCB2aWEge0BsaW5rCisgICAgICogI3NldFJlcXVlc3RNZXRob2QoU3RyaW5nKX0uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gUEVSTUlUVEVEX1VTRVJfTUVUSE9EUyA9IHsKKyAgICAgICAgICAgIEh0dHBFbmdpbmUuT1BUSU9OUywKKyAgICAgICAgICAgIEh0dHBFbmdpbmUuR0VULAorICAgICAgICAgICAgSHR0cEVuZ2luZS5IRUFELAorICAgICAgICAgICAgSHR0cEVuZ2luZS5QT1NULAorICAgICAgICAgICAgSHR0cEVuZ2luZS5QVVQsCisgICAgICAgICAgICBIdHRwRW5naW5lLkRFTEVURSwKKyAgICAgICAgICAgIEh0dHBFbmdpbmUuVFJBQ0UKKyAgICAgICAgICAgIC8vIE5vdGU6IHdlIGRvbid0IGFsbG93IHVzZXJzIHRvIHNwZWNpZnkgIkNPTk5FQ1QiCisgICAgfTsKKworICAgIC8qKgorICAgICAqIFRoZSBIVFRQIHJlcXVlc3QgbWV0aG9kIG9mIHRoaXMge0Bjb2RlIEh0dHBVUkxDb25uZWN0aW9ufS4gVGhlIGRlZmF1bHQKKyAgICAgKiB2YWx1ZSBpcyB7QGNvZGUgIkdFVCJ9LgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgbWV0aG9kID0gSHR0cEVuZ2luZS5HRVQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3RhdHVzIGNvZGUgb2YgdGhlIHJlc3BvbnNlIG9idGFpbmVkIGZyb20gdGhlIEhUVFAgcmVxdWVzdC4gVGhlCisgICAgICogZGVmYXVsdCB2YWx1ZSBpcyB7QGNvZGUgLTF9LgorICAgICAqIDxwPgorICAgICAqIDxsaT4xeHg6IEluZm9ybWF0aW9uYWw8L2xpPgorICAgICAqIDxsaT4yeHg6IFN1Y2Nlc3M8L2xpPgorICAgICAqIDxsaT4zeHg6IFJlbG9jYXRpb24vUmVkaXJlY3Rpb248L2xpPgorICAgICAqIDxsaT40eHg6IENsaWVudCBFcnJvcjwvbGk+CisgICAgICogPGxpPjV4eDogU2VydmVyIEVycm9yPC9saT4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHJlc3BvbnNlQ29kZSA9IC0xOworCisgICAgLyoqCisgICAgICogVGhlIEhUVFAgcmVzcG9uc2UgbWVzc2FnZSB3aGljaCBjb3JyZXNwb25kcyB0byB0aGUgcmVzcG9uc2UgY29kZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHJlc3BvbnNlTWVzc2FnZTsKKworICAgIC8qKgorICAgICAqIEZsYWcgdG8gZGVmaW5lIHdoZXRoZXIgdGhlIHByb3RvY29sIHdpbGwgYXV0b21hdGljYWxseSBmb2xsb3cgcmVkaXJlY3RzCisgICAgICogb3Igbm90LiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyB7QGNvZGUgdHJ1ZX0uCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gaW5zdGFuY2VGb2xsb3dSZWRpcmVjdHMgPSBmb2xsb3dSZWRpcmVjdHM7CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGZvbGxvd1JlZGlyZWN0cyA9IHRydWU7CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgSFRUUCBjaHVua2VkIGVuY29kaW5nIGlzIGVuYWJsZWQgdGhpcyBwYXJhbWV0ZXIgZGVmaW5lcyB0aGUKKyAgICAgKiBjaHVuay1sZW5ndGguIERlZmF1bHQgdmFsdWUgaXMge0Bjb2RlIC0xfSB0aGF0IG1lYW5zIHRoZSBjaHVua2VkIGVuY29kaW5nCisgICAgICogbW9kZSBpcyBkaXNhYmxlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGNodW5rTGVuZ3RoID0gLTE7CisKKyAgICAvKioKKyAgICAgKiBJZiB1c2luZyBIVFRQIGZpeGVkLWxlbmd0aCBzdHJlYW1pbmcgbW9kZSB0aGlzIHBhcmFtZXRlciBkZWZpbmVzIHRoZQorICAgICAqIGZpeGVkIGxlbmd0aCBvZiBjb250ZW50LiBEZWZhdWx0IHZhbHVlIGlzIHtAY29kZSAtMX0gdGhhdCBtZWFucyB0aGUKKyAgICAgKiBmaXhlZC1sZW5ndGggc3RyZWFtaW5nIG1vZGUgaXMgZGlzYWJsZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBmaXhlZENvbnRlbnRMZW5ndGggPSAtMTsKKworICAgIC8vIDJYWDogZ2VuZXJhbGx5ICJPSyIKKyAgICAvLyAzWFg6IHJlbG9jYXRpb24vcmVkaXJlY3QKKyAgICAvLyA0WFg6IGNsaWVudCBlcnJvcgorICAgIC8vIDVYWDogc2VydmVyIGVycm9yCisgICAgLyoqCisgICAgICogTnVtZXJpYyBzdGF0dXMgY29kZSwgMjAyOiBBY2NlcHRlZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfQUNDRVBURUQgPSAyMDI7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCA1MDI6IEJhZCBHYXRld2F5CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9CQURfR0FURVdBWSA9IDUwMjsKKworICAgIC8qKgorICAgICAqIE51bWVyaWMgc3RhdHVzIGNvZGUsIDQwNTogQmFkIE1ldGhvZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfQkFEX01FVEhPRCA9IDQwNTsKKworICAgIC8qKgorICAgICAqIE51bWVyaWMgc3RhdHVzIGNvZGUsIDQwMDogQmFkIFJlcXVlc3QKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX0JBRF9SRVFVRVNUID0gNDAwOworCisgICAgLyoqCisgICAgICogTnVtZXJpYyBzdGF0dXMgY29kZSwgNDA4OiBDbGllbnQgVGltZW91dAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfQ0xJRU5UX1RJTUVPVVQgPSA0MDg7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCA0MDk6IENvbmZsaWN0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9DT05GTElDVCA9IDQwOTsKKworICAgIC8qKgorICAgICAqIE51bWVyaWMgc3RhdHVzIGNvZGUsIDIwMTogQ3JlYXRlZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfQ1JFQVRFRCA9IDIwMTsKKworICAgIC8qKgorICAgICAqIE51bWVyaWMgc3RhdHVzIGNvZGUsIDQxMzogRW50aXR5IHRvbyBsYXJnZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfRU5USVRZX1RPT19MQVJHRSA9IDQxMzsKKworICAgIC8qKgorICAgICAqIE51bWVyaWMgc3RhdHVzIGNvZGUsIDQwMzogRm9yYmlkZGVuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9GT1JCSURERU4gPSA0MDM7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCA1MDQ6IEdhdGV3YXkgdGltZW91dAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfR0FURVdBWV9USU1FT1VUID0gNTA0OworCisgICAgLyoqCisgICAgICogTnVtZXJpYyBzdGF0dXMgY29kZSwgNDEwOiBHb25lCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9HT05FID0gNDEwOworCisgICAgLyoqCisgICAgICogTnVtZXJpYyBzdGF0dXMgY29kZSwgNTAwOiBJbnRlcm5hbCBlcnJvcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfSU5URVJOQUxfRVJST1IgPSA1MDA7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCA0MTE6IExlbmd0aCByZXF1aXJlZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfTEVOR1RIX1JFUVVJUkVEID0gNDExOworCisgICAgLyoqCisgICAgICogTnVtZXJpYyBzdGF0dXMgY29kZSwgMzAxIE1vdmVkIHBlcm1hbmVudGx5CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9NT1ZFRF9QRVJNID0gMzAxOworCisgICAgLyoqCisgICAgICogTnVtZXJpYyBzdGF0dXMgY29kZSwgMzAyOiBNb3ZlZCB0ZW1wb3JhcmlseQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfTU9WRURfVEVNUCA9IDMwMjsKKworICAgIC8qKgorICAgICAqIE51bWVyaWMgc3RhdHVzIGNvZGUsIDMwMDogTXVsdGlwbGUgY2hvaWNlcworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfTVVMVF9DSE9JQ0UgPSAzMDA7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCAyMDQ6IE5vIGNvbnRlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX05PX0NPTlRFTlQgPSAyMDQ7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCA0MDY6IE5vdCBhY2NlcHRhYmxlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9OT1RfQUNDRVBUQUJMRSA9IDQwNjsKKworICAgIC8qKgorICAgICAqIE51bWVyaWMgc3RhdHVzIGNvZGUsIDIwMzogTm90IGF1dGhvcml0YXRpdmUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX05PVF9BVVRIT1JJVEFUSVZFID0gMjAzOworCisgICAgLyoqCisgICAgICogTnVtZXJpYyBzdGF0dXMgY29kZSwgNDA0OiBOb3QgZm91bmQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX05PVF9GT1VORCA9IDQwNDsKKworICAgIC8qKgorICAgICAqIE51bWVyaWMgc3RhdHVzIGNvZGUsIDUwMTogTm90IGltcGxlbWVudGVkCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9OT1RfSU1QTEVNRU5URUQgPSA1MDE7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCAzMDQ6IE5vdCBtb2RpZmllZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfTk9UX01PRElGSUVEID0gMzA0OworCisgICAgLyoqCisgICAgICogTnVtZXJpYyBzdGF0dXMgY29kZSwgMjAwOiBPSworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfT0sgPSAyMDA7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCAyMDY6IFBhcnRpYWwKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX1BBUlRJQUwgPSAyMDY7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCA0MDI6IFBheW1lbnQgcmVxdWlyZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX1BBWU1FTlRfUkVRVUlSRUQgPSA0MDI7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCA0MTI6IFByZWNvbmRpdGlvbiBmYWlsZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX1BSRUNPTl9GQUlMRUQgPSA0MTI7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCA0MDc6IFByb3h5IGF1dGhlbnRpY2F0aW9uIHJlcXVpcmVkCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9QUk9YWV9BVVRIID0gNDA3OworCisgICAgLyoqCisgICAgICogTnVtZXJpYyBzdGF0dXMgY29kZSwgNDE0OiBSZXF1ZXN0IHRvbyBsb25nCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9SRVFfVE9PX0xPTkcgPSA0MTQ7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCAyMDU6IFJlc2V0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9SRVNFVCA9IDIwNTsKKworICAgIC8qKgorICAgICAqIE51bWVyaWMgc3RhdHVzIGNvZGUsIDMwMzogU2VlIG90aGVyCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9TRUVfT1RIRVIgPSAzMDM7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCA1MDA6IEludGVybmFsIGVycm9yCisgICAgICoKKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNIVFRQX0lOVEVSTkFMX0VSUk9SfQorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9TRVJWRVJfRVJST1IgPSA1MDA7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCAzMDU6IFVzZSBwcm94eS4KKyAgICAgKgorICAgICAqIDxwPkxpa2UgRmlyZWZveCBhbmQgQ2hyb21lLCB0aGlzIGNsYXNzIGRvZXNuJ3QgaG9ub3IgdGhpcyByZXNwb25zZSBjb2RlLgorICAgICAqIE90aGVyIGltcGxlbWVudGF0aW9ucyByZXNwb25kIHRvIHRoaXMgc3RhdHVzIGNvZGUgYnkgcmV0cnlpbmcgdGhlIHJlcXVlc3QKKyAgICAgKiB1c2luZyB0aGUgSFRUUCBwcm94eSBuYW1lZCBieSB0aGUgcmVzcG9uc2UncyBMb2NhdGlvbiBoZWFkZXIgZmllbGQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9VU0VfUFJPWFkgPSAzMDU7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCA0MDE6IFVuYXV0aG9yaXplZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfVU5BVVRIT1JJWkVEID0gNDAxOworCisgICAgLyoqCisgICAgICogTnVtZXJpYyBzdGF0dXMgY29kZSwgNDE1OiBVbnN1cHBvcnRlZCB0eXBlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9VTlNVUFBPUlRFRF9UWVBFID0gNDE1OworCisgICAgLyoqCisgICAgICogTnVtZXJpYyBzdGF0dXMgY29kZSwgNTAzOiBVbmF2YWlsYWJsZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfVU5BVkFJTEFCTEUgPSA1MDM7CisKKyAgICAvKioKKyAgICAgKiBOdW1lcmljIHN0YXR1cyBjb2RlLCA1MDU6IFZlcnNpb24gbm90IHN1cHBvcnRlZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfVkVSU0lPTiA9IDUwNTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEh0dHBVUkxDb25uZWN0aW9ufSBpbnN0YW5jZSBwb2ludGluZyB0byB0aGUKKyAgICAgKiByZXNvdXJjZSBzcGVjaWZpZWQgYnkgdGhlIHtAY29kZSB1cmx9LgorICAgICAqCisgICAgICogQHBhcmFtIHVybAorICAgICAqICAgICAgICAgICAgdGhlIFVSTCBvZiB0aGlzIGNvbm5lY3Rpb24uCisgICAgICogQHNlZSBVUkwKKyAgICAgKiBAc2VlIFVSTENvbm5lY3Rpb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSHR0cFVSTENvbm5lY3Rpb24oVVJMIHVybCkgeworICAgICAgICBzdXBlcih1cmwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGUgY29ubmVjdGlvbiB0byB0aGUgSFRUUCBzZXJ2ZXIuCisgICAgICoKKyAgICAgKiBAc2VlIFVSTENvbm5lY3Rpb24jY29ubmVjdCgpCisgICAgICogQHNlZSBVUkxDb25uZWN0aW9uI2Nvbm5lY3RlZAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGRpc2Nvbm5lY3QoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5wdXQgc3RyZWFtIGZyb20gdGhlIHNlcnZlciBpbiB0aGUgY2FzZSBvZiBhbiBlcnJvciBzdWNoIGFzCisgICAgICogdGhlIHJlcXVlc3RlZCBmaWxlIGhhcyBub3QgYmVlbiBmb3VuZCBvbiB0aGUgcmVtb3RlIHNlcnZlci4gVGhpcyBzdHJlYW0KKyAgICAgKiBjYW4gYmUgdXNlZCB0byByZWFkIHRoZSBkYXRhIHRoZSBzZXJ2ZXIgd2lsbCBzZW5kIGJhY2suCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBlcnJvciBpbnB1dCBzdHJlYW0gcmV0dXJuZWQgYnkgdGhlIHNlcnZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0RXJyb3JTdHJlYW0oKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHtAY29kZSBmb2xsb3dSZWRpcmVjdHN9IHdoaWNoIGluZGljYXRlcyBpZiB0aGlzCisgICAgICogY29ubmVjdGlvbiBmb2xsb3dzIGEgZGlmZmVyZW50IFVSTCByZWRpcmVjdGVkIGJ5IHRoZSBzZXJ2ZXIuIEl0IGlzCisgICAgICogZW5hYmxlZCBieSBkZWZhdWx0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGZsYWcuCisgICAgICogQHNlZSAjc2V0Rm9sbG93UmVkaXJlY3RzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGdldEZvbGxvd1JlZGlyZWN0cygpIHsKKyAgICAgICAgcmV0dXJuIGZvbGxvd1JlZGlyZWN0czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwZXJtaXNzaW9uIG9iamVjdCAoaW4gdGhpcyBjYXNlIHtAY29kZSBTb2NrZXRQZXJtaXNzaW9ufSkKKyAgICAgKiB3aXRoIHRoZSBob3N0IGFuZCB0aGUgcG9ydCBudW1iZXIgYXMgdGhlIHRhcmdldCBuYW1lIGFuZCB7QGNvZGUKKyAgICAgKiAicmVzb2x2ZSwgY29ubmVjdCJ9IGFzIHRoZSBhY3Rpb24gbGlzdC4gSWYgdGhlIHBvcnQgbnVtYmVyIG9mIHRoaXMgVVJMCisgICAgICogaW5zdGFuY2UgaXMgbG93ZXIgdGhhbiB7QGNvZGUgMH0gdGhlIHBvcnQgd2lsbCBiZSBzZXQgdG8ge0Bjb2RlIDgwfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHBlcm1pc3Npb24gb2JqZWN0IHJlcXVpcmVkIGZvciB0aGlzIGNvbm5lY3Rpb24uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIElPIGV4Y2VwdGlvbiBvY2N1cnMgZHVyaW5nIHRoZSBjcmVhdGlvbiBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgICBwZXJtaXNzaW9uIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uIGdldFBlcm1pc3Npb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgcG9ydCA9IHVybC5nZXRQb3J0KCk7CisgICAgICAgIGlmIChwb3J0IDwgMCkgeworICAgICAgICAgICAgcG9ydCA9IDgwOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU29ja2V0UGVybWlzc2lvbih1cmwuZ2V0SG9zdCgpICsgIjoiICsgcG9ydCwKKyAgICAgICAgICAgICAgICAiY29ubmVjdCwgcmVzb2x2ZSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHJlcXVlc3QgbWV0aG9kIHdoaWNoIHdpbGwgYmUgdXNlZCB0byBtYWtlIHRoZSByZXF1ZXN0IHRvIHRoZQorICAgICAqIHJlbW90ZSBIVFRQIHNlcnZlci4gQWxsIHBvc3NpYmxlIG1ldGhvZHMgb2YgdGhpcyBIVFRQIGltcGxlbWVudGF0aW9uIGlzCisgICAgICogbGlzdGVkIGluIHRoZSBjbGFzcyBkZWZpbml0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVxdWVzdCBtZXRob2Qgc3RyaW5nLgorICAgICAqIEBzZWUgI21ldGhvZAorICAgICAqIEBzZWUgI3NldFJlcXVlc3RNZXRob2QKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFJlcXVlc3RNZXRob2QoKSB7CisgICAgICAgIHJldHVybiBtZXRob2Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmVzcG9uc2UgY29kZSByZXR1cm5lZCBieSB0aGUgcmVtb3RlIEhUVFAgc2VydmVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVzcG9uc2UgY29kZSwgLTEgaWYgbm8gdmFsaWQgcmVzcG9uc2UgY29kZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYW4gSU8gZXJyb3IgZHVyaW5nIHRoZSByZXRyaWV2YWwuCisgICAgICogQHNlZSAjZ2V0UmVzcG9uc2VNZXNzYWdlCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSZXNwb25zZUNvZGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBDYWxsIGdldElucHV0U3RyZWFtKCkgZmlyc3Qgc2luY2UgZ2V0SGVhZGVyRmllbGQoKSBkb2Vzbid0IHJldHVybgorICAgICAgICAvLyBleGNlcHRpb25zCisgICAgICAgIGdldElucHV0U3RyZWFtKCk7CisgICAgICAgIFN0cmluZyByZXNwb25zZSA9IGdldEhlYWRlckZpZWxkKDApOworICAgICAgICBpZiAocmVzcG9uc2UgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIHJlc3BvbnNlID0gcmVzcG9uc2UudHJpbSgpOworICAgICAgICBpbnQgbWFyayA9IHJlc3BvbnNlLmluZGV4T2YoIiAiKSArIDE7CisgICAgICAgIGlmIChtYXJrID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBpbnQgbGFzdCA9IG1hcmsgKyAzOworICAgICAgICBpZiAobGFzdCA+IHJlc3BvbnNlLmxlbmd0aCgpKSB7CisgICAgICAgICAgICBsYXN0ID0gcmVzcG9uc2UubGVuZ3RoKCk7CisgICAgICAgIH0KKyAgICAgICAgcmVzcG9uc2VDb2RlID0gSW50ZWdlci5wYXJzZUludChyZXNwb25zZS5zdWJzdHJpbmcobWFyaywgbGFzdCkpOworICAgICAgICBpZiAobGFzdCArIDEgPD0gcmVzcG9uc2UubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgIHJlc3BvbnNlTWVzc2FnZSA9IHJlc3BvbnNlLnN1YnN0cmluZyhsYXN0ICsgMSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3BvbnNlQ29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByZXNwb25zZSBtZXNzYWdlIHJldHVybmVkIGJ5IHRoZSByZW1vdGUgSFRUUCBzZXJ2ZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZXNwb25zZSBtZXNzYWdlLiB7QGNvZGUgbnVsbH0gaWYgbm8gc3VjaCByZXNwb25zZSBleGlzdHMuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGFuIGVycm9yIGR1cmluZyB0aGUgcmV0cmlldmFsLgorICAgICAqIEBzZWUgI2dldFJlc3BvbnNlQ29kZSgpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRSZXNwb25zZU1lc3NhZ2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAocmVzcG9uc2VNZXNzYWdlICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiByZXNwb25zZU1lc3NhZ2U7CisgICAgICAgIH0KKyAgICAgICAgZ2V0UmVzcG9uc2VDb2RlKCk7CisgICAgICAgIHJldHVybiByZXNwb25zZU1lc3NhZ2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZmxhZyBvZiB3aGV0aGVyIHRoaXMgY29ubmVjdGlvbiB3aWxsIGZvbGxvdyByZWRpcmVjdHMgcmV0dXJuZWQKKyAgICAgKiBieSB0aGUgcmVtb3RlIHNlcnZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhdXRvCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gZW5hYmxlIG9yIGRpc2FibGUgdGhpcyBvcHRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldEZvbGxvd1JlZGlyZWN0cyhib29sZWFuIGF1dG8pIHsKKyAgICAgICAgZm9sbG93UmVkaXJlY3RzID0gYXV0bzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSByZXF1ZXN0IGNvbW1hbmQgd2hpY2ggd2lsbCBiZSBzZW50IHRvIHRoZSByZW1vdGUgSFRUUCBzZXJ2ZXIuCisgICAgICogVGhpcyBtZXRob2QgY2FuIG9ubHkgYmUgY2FsbGVkIGJlZm9yZSB0aGUgY29ubmVjdGlvbiBpcyBtYWRlLgorICAgICAqCisgICAgICogQHBhcmFtIG1ldGhvZAorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIG1ldGhvZCB0byBiZSB1c2VkLgorICAgICAqIEB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGlzIGNhbGxlZCBhZnRlciBjb25uZWN0ZWQsIG9yIHRoZSBtZXRob2QgaXMgbm90CisgICAgICogICAgICAgICAgICAgc3VwcG9ydGVkIGJ5IHRoaXMgSFRUUCBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKiBAc2VlICNnZXRSZXF1ZXN0TWV0aG9kKCkKKyAgICAgKiBAc2VlICNtZXRob2QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSZXF1ZXN0TWV0aG9kKFN0cmluZyBtZXRob2QpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjb25uZWN0ZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBQcm90b2NvbEV4Y2VwdGlvbigiQ29ubmVjdGlvbiBhbHJlYWR5IGVzdGFibGlzaGVkIik7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChTdHJpbmcgcGVybWl0dGVkVXNlck1ldGhvZCA6IFBFUk1JVFRFRF9VU0VSX01FVEhPRFMpIHsKKyAgICAgICAgICAgIGlmIChwZXJtaXR0ZWRVc2VyTWV0aG9kLmVxdWFscyhtZXRob2QpKSB7CisgICAgICAgICAgICAgICAgLy8gaWYgdGhlcmUgaXMgYSBzdXBwb3J0ZWQgbWV0aG9kIHRoYXQgbWF0Y2hlcyB0aGUgZGVzaXJlZAorICAgICAgICAgICAgICAgIC8vIG1ldGhvZCwgdGhlbiBzZXQgdGhlIGN1cnJlbnQgbWV0aG9kIGFuZCByZXR1cm4KKyAgICAgICAgICAgICAgICB0aGlzLm1ldGhvZCA9IHBlcm1pdHRlZFVzZXJNZXRob2Q7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIGlmIG5vbmUgbWF0Y2hlcywgdGhlbiB0aHJvdyBQcm90b2NvbEV4Y2VwdGlvbgorICAgICAgICB0aHJvdyBuZXcgUHJvdG9jb2xFeGNlcHRpb24oIlVua25vd24gbWV0aG9kICciICsgbWV0aG9kICsgIic7IG11c3QgYmUgb25lIG9mICIgKworICAgICAgICAgICAgICAgIEFycmF5cy50b1N0cmluZyhQRVJNSVRURURfVVNFUl9NRVRIT0RTKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgY29ubmVjdGlvbiB1c2VzIGEgcHJveHkgc2VydmVyIG9yIG5vdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgY29ubmVjdGlvbiBwYXNzZXMgYSBwcm94eSBzZXJ2ZXIsIGZhbHNlCisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gdXNpbmdQcm94eSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5jb2RpbmcgdXNlZCB0byB0cmFuc21pdCB0aGUgcmVzcG9uc2UgYm9keSBvdmVyIHRoZSBuZXR3b3JrLgorICAgICAqIFRoaXMgaXMgbnVsbCBvciAiaWRlbnRpdHkiIGlmIHRoZSBjb250ZW50IHdhcyBub3QgZW5jb2RlZCwgb3IgImd6aXAiIGlmCisgICAgICogdGhlIGJvZHkgd2FzIGd6aXAgY29tcHJlc3NlZC4gTW9zdCBjYWxsZXJzIHdpbGwgYmUgbW9yZSBpbnRlcmVzdGVkIGluIHRoZQorICAgICAqIHtAbGluayAjZ2V0Q29udGVudFR5cGUoKSBjb250ZW50IHR5cGV9LCB3aGljaCBtYXkgYWxzbyBpbmNsdWRlIHRoZQorICAgICAqIGNvbnRlbnQncyBjaGFyYWN0ZXIgZW5jb2RpbmcuCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgZ2V0Q29udGVudEVuY29kaW5nKCkgeworICAgICAgICByZXR1cm4gc3VwZXIuZ2V0Q29udGVudEVuY29kaW5nKCk7IC8vIG92ZXJyaWRkZW4gZm9yIEphdmFkb2Mgb25seQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIGNvbm5lY3Rpb24gZm9sbG93cyByZWRpcmVjdHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGNvbm5lY3Rpb24gZm9sbG93cyByZWRpcmVjdHMsIGZhbHNlCisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0SW5zdGFuY2VGb2xsb3dSZWRpcmVjdHMoKSB7CisgICAgICAgIHJldHVybiBpbnN0YW5jZUZvbGxvd1JlZGlyZWN0czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHdoZXRoZXIgdGhpcyBjb25uZWN0aW9uIGZvbGxvd3MgcmVkaXJlY3RzLgorICAgICAqCisgICAgICogQHBhcmFtIGZvbGxvd1JlZGlyZWN0cworICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGlmIHRoaXMgY29ubmVjdGlvbiB3aWxsIGZvbGxvd3MgcmVkaXJlY3RzLCBmYWxzZQorICAgICAqICAgICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEluc3RhbmNlRm9sbG93UmVkaXJlY3RzKGJvb2xlYW4gZm9sbG93UmVkaXJlY3RzKSB7CisgICAgICAgIGluc3RhbmNlRm9sbG93UmVkaXJlY3RzID0gZm9sbG93UmVkaXJlY3RzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRhdGUgdmFsdWUgaW4gbWlsbGlzZWNvbmRzIHNpbmNlIHtAY29kZSAwMS4wMS4xOTcwLCAwMDowMGh9CisgICAgICogY29ycmVzcG9uZGluZyB0byB0aGUgaGVhZGVyIGZpZWxkIHtAY29kZSBmaWVsZH0uIFRoZSB7QGNvZGUgZGVmYXVsdFZhbHVlfQorICAgICAqIHdpbGwgYmUgcmV0dXJuZWQgaWYgbm8gc3VjaCBmaWVsZCBjYW4gYmUgZm91bmQgaW4gdGhlIHJlc3BvbnNlIGhlYWRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgdGhlIGhlYWRlciBmaWVsZCBuYW1lLgorICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZWZhdWx0IHZhbHVlIHRvIHVzZSBpZiB0aGUgc3BlY2lmaWVkIGhlYWRlciBmaWVsZCB3b250IGJlCisgICAgICogICAgICAgICAgICBmb3VuZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBoZWFkZXIgZmllbGQgcmVwcmVzZW50ZWQgaW4gbWlsbGlzZWNvbmRzIHNpbmNlIEphbnVhcnkgMSwKKyAgICAgKiAgICAgICAgIDE5NzAgR01ULgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIGdldEhlYWRlckZpZWxkRGF0ZShTdHJpbmcgZmllbGQsIGxvbmcgZGVmYXVsdFZhbHVlKSB7CisgICAgICAgIHJldHVybiBzdXBlci5nZXRIZWFkZXJGaWVsZERhdGUoZmllbGQsIGRlZmF1bHRWYWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgdGhlIGxlbmd0aCBvZiBhIEhUVFAgcmVxdWVzdCBib2R5IGlzIGtub3duIGFoZWFkLCBzZXRzIGZpeGVkIGxlbmd0aCB0bworICAgICAqIGVuYWJsZSBzdHJlYW1pbmcgd2l0aG91dCBidWZmZXJpbmcuIFNldHMgYWZ0ZXIgY29ubmVjdGlvbiB3aWxsIGNhdXNlIGFuCisgICAgICogZXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHNlZSAjc2V0Q2h1bmtlZFN0cmVhbWluZ01vZGUKKyAgICAgKiBAcGFyYW0gY29udGVudExlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIGZpeGVkIGxlbmd0aCBvZiB0aGUgSFRUUCByZXF1ZXN0IGJvZHkuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbHJlYWR5IGNvbm5lY3RlZCBvciBhbm90aGVyIG1vZGUgYWxyZWFkeSBzZXQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY29udGVudExlbmd0aH0gaXMgbGVzcyB0aGFuIHplcm8uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Rml4ZWRMZW5ndGhTdHJlYW1pbmdNb2RlKGludCBjb250ZW50TGVuZ3RoKSB7CisgICAgICAgIGlmIChzdXBlci5jb25uZWN0ZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkFscmVhZHkgY29ubmVjdGVkIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNodW5rTGVuZ3RoID4gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiQWxyZWFkeSBpbiBjaHVua2VkIG1vZGUiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY29udGVudExlbmd0aCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImNvbnRlbnRMZW5ndGggPCAwIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5maXhlZENvbnRlbnRMZW5ndGggPSBjb250ZW50TGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0cmVhbSBhIHJlcXVlc3QgYm9keSB3aG9zZSBsZW5ndGggaXMgbm90IGtub3duIGluIGFkdmFuY2UuIE9sZCBIVFRQLzEuMAorICAgICAqIG9ubHkgc2VydmVycyBtYXkgbm90IHN1cHBvcnQgdGhpcyBtb2RlLgorICAgICAqCisgICAgICogPHA+V2hlbiBIVFRQIGNodW5rZWQgZW5jb2RpbmcgaXMgdXNlZCwgdGhlIHN0cmVhbSBpcyBkaXZpZGVkIGludG8KKyAgICAgKiBjaHVua3MsIGVhY2ggcHJlZml4ZWQgd2l0aCBhIGhlYWRlciBjb250YWluaW5nIHRoZSBjaHVuaydzIHNpemUuIFNldHRpbmcKKyAgICAgKiBhIGxhcmdlIGNodW5rIGxlbmd0aCByZXF1aXJlcyBhIGxhcmdlIGludGVybmFsIGJ1ZmZlciwgcG90ZW50aWFsbHkKKyAgICAgKiB3YXN0aW5nIG1lbW9yeS4gU2V0dGluZyBhIHNtYWxsIGNodW5rIGxlbmd0aCBpbmNyZWFzZXMgdGhlIG51bWJlciBvZgorICAgICAqIGJ5dGVzIHRoYXQgbXVzdCBiZSB0cmFuc21pdHRlZCBiZWNhdXNlIG9mIHRoZSBoZWFkZXIgb24gZXZlcnkgY2h1bmsuCisgICAgICogTW9zdCBjYWxsZXIgc2hvdWxkIHVzZSB7QGNvZGUgMH0gdG8gZ2V0IHRoZSBzeXN0ZW0gZGVmYXVsdC4KKyAgICAgKgorICAgICAqIEBzZWUgI3NldEZpeGVkTGVuZ3RoU3RyZWFtaW5nTW9kZQorICAgICAqIEBwYXJhbSBjaHVua0xlbmd0aCB0aGUgbGVuZ3RoIHRvIHVzZSwgb3Ige0Bjb2RlIDB9IGZvciB0aGUgZGVmYXVsdCBjaHVuaworICAgICAqICAgICBsZW5ndGguCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgYWxyZWFkeSBjb25uZWN0ZWQgb3IgYW5vdGhlciBtb2RlCisgICAgICogICAgIGFscmVhZHkgc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENodW5rZWRTdHJlYW1pbmdNb2RlKGludCBjaHVua0xlbmd0aCkgeworICAgICAgICBpZiAoc3VwZXIuY29ubmVjdGVkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJBbHJlYWR5IGNvbm5lY3RlZCIpOworICAgICAgICB9CisgICAgICAgIGlmIChmaXhlZENvbnRlbnRMZW5ndGggPj0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiQWxyZWFkeSBpbiBmaXhlZC1sZW5ndGggbW9kZSIpOworICAgICAgICB9CisgICAgICAgIGlmIChjaHVua0xlbmd0aCA8PSAwKSB7CisgICAgICAgICAgICB0aGlzLmNodW5rTGVuZ3RoID0gSHR0cEVuZ2luZS5ERUZBVUxUX0NIVU5LX0xFTkdUSDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRoaXMuY2h1bmtMZW5ndGggPSBjaHVua0xlbmd0aDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9JRE4uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9JRE4uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZTYwMjA5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0lETi5qYXZhCkBAIC0wLDAgKzEsMTA2IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgbGliY29yZS5pY3UuTmF0aXZlSUROOworCisvKioKKyAqIENvbnZlcnRzIGludGVybmF0aW9uYWxpemVkIGRvbWFpbiBuYW1lcyBiZXR3ZWVuIFVuaWNvZGUgYW5kIHRoZSBBU0NJSSBDb21wYXRpYmxlIEVuY29kaW5nCisgKiAoQUNFKSByZXByZXNlbnRhdGlvbi4KKyAqCisgKiA8cD5TZWUgPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzQ5MC50eHQiPlJGQyAzNDkwPC9hPiBmb3IgZnVsbCBkZXRhaWxzLgorICoKKyAqIEBzaW5jZSAxLjYKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIElETiB7CisgICAgLyoqCisgICAgICogV2hlbiBzZXQsIGFsbG93cyBJRE4gdG8gcHJvY2VzcyB1bmFzc2lnbmVkIHVuaWNvZGUgcG9pbnRzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFMTE9XX1VOQVNTSUdORUQgPSAxOworCisgICAgLyoqCisgICAgICogV2hlbiBzZXQsIEFTQ0lJIHN0cmluZ3MgYXJlIGNoZWNrZWQgYWdhaW5zdAorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzExMjIudHh0Ij5SRkMgMTEyMjwvYT4gYW5kCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMTEyMy50eHQiPlJGQyAxMTIzPC9hPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVU0VfU1REM19BU0NJSV9SVUxFUyA9IDI7CisKKyAgICBwcml2YXRlIElETigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmFuc2Zvcm0gYSBVbmljb2RlIFN0cmluZyB0byBBU0NJSSBDb21wYXRpYmxlIEVuY29kaW5nIFN0cmluZyBhY2NvcmRpbmcKKyAgICAgKiB0byB0aGUgYWxnb3JpdGhtIGRlZmluZWQgaW4gPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzQ5MC50eHQiPlJGQyAzNDkwPC9hPi4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSB0cmFuc2Zvcm1hdGlvbiBmYWlscyAoYmVjYXVzZSB0aGUgaW5wdXQgaXMgbm90IGEgdmFsaWQgSUROKSwgYW4KKyAgICAgKiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBjYW4gaGFuZGxlIGVpdGhlciBhbiBpbmRpdmlkdWFsIGxhYmVsIG9yIGFuIGVudGlyZSBkb21haW4gbmFtZS4KKyAgICAgKiBJbiB0aGUgbGF0dGVyIGNhc2UsIHRoZSBzZXBhcmF0b3JzIGFyZTogVSswMDJFIChmdWxsIHN0b3ApLCBVKzMwMDIgKGlkZW9ncmFwaGljIGZ1bGwgc3RvcCksCisgICAgICogVStGRjBFIChmdWxsd2lkdGggZnVsbCBzdG9wKSwgYW5kIFUrRkY2MSAoaGFsZndpZHRoIGlkZW9ncmFwaGljIGZ1bGwgc3RvcCkuCisgICAgICogQWxsIG9mIHRoZXNlIHdpbGwgYmVjb21lIFUrMDAyRSAoZnVsbCBzdG9wKSBpbiB0aGUgcmVzdWx0LgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0IHRoZSBVbmljb2RlIG5hbWUKKyAgICAgKiBAcGFyYW0gZmxhZ3MgMCwge0Bjb2RlIEFMTE9XX1VOQVNTSUdORUR9LCB7QGNvZGUgVVNFX1NURDNfQVNDSUlfUlVMRVN9LAorICAgICAqICAgICAgICAgb3Ige0Bjb2RlIEFMTE9XX1VOQVNTSUdORUQgfCBVU0VfU1REM19BU0NJSV9SVUxFU30KKyAgICAgKiBAcmV0dXJuIHRoZSBBQ0UgbmFtZQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBpbnB1dH0gZG9lcyBub3QgY29uZm9ybSB0byA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzNDkwLnR4dCI+UkZDIDM0OTA8L2E+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9BU0NJSShTdHJpbmcgaW5wdXQsIGludCBmbGFncykgeworICAgICAgICByZXR1cm4gTmF0aXZlSUROLnRvQVNDSUkoaW5wdXQsIGZsYWdzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVpdmFsZW50IHRvIHtAY29kZSB0b0FTQ0lJKGlucHV0LCAwKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQgdGhlIFVuaWNvZGUgbmFtZQorICAgICAqIEByZXR1cm4gdGhlIEFDRSBuYW1lCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGlucHV0fSBkb2VzIG5vdCBjb25mb3JtIHRvIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzM0OTAudHh0Ij5SRkMgMzQ5MDwvYT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b0FTQ0lJKFN0cmluZyBpbnB1dCkgeworICAgICAgICByZXR1cm4gdG9BU0NJSShpbnB1dCwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJhbnNsYXRlcyBhIHN0cmluZyBmcm9tIEFTQ0lJIENvbXBhdGlibGUgRW5jb2RpbmcgKEFDRSkgdG8gVW5pY29kZQorICAgICAqIGFjY29yZGluZyB0byB0aGUgYWxnb3JpdGhtIGRlZmluZWQgaW4gPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzQ5MC50eHQiPlJGQyAzNDkwPC9hPi4KKyAgICAgKgorICAgICAqIDxwPlVubGlrZSB7QGNvZGUgdG9BU0NJSX0sIHRoaXMgdHJhbnNmb3JtYXRpb24gY2Fubm90IGZhaWwuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBjYW4gaGFuZGxlIGVpdGhlciBhbiBpbmRpdmlkdWFsIGxhYmVsIG9yIGFuIGVudGlyZSBkb21haW4gbmFtZS4KKyAgICAgKiBJbiB0aGUgbGF0dGVyIGNhc2UsIHRoZSBzZXBhcmF0b3JzIGFyZTogVSswMDJFIChmdWxsIHN0b3ApLCBVKzMwMDIgKGlkZW9ncmFwaGljIGZ1bGwgc3RvcCksCisgICAgICogVStGRjBFIChmdWxsd2lkdGggZnVsbCBzdG9wKSwgYW5kIFUrRkY2MSAoaGFsZndpZHRoIGlkZW9ncmFwaGljIGZ1bGwgc3RvcCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQgdGhlIEFDRSBuYW1lCisgICAgICogQHJldHVybiB0aGUgVW5pY29kZSBuYW1lCisgICAgICogQHBhcmFtIGZsYWdzIDAsIHtAY29kZSBBTExPV19VTkFTU0lHTkVEfSwge0Bjb2RlIFVTRV9TVEQzX0FTQ0lJX1JVTEVTfSwKKyAgICAgKiAgICAgICAgIG9yIHtAY29kZSBBTExPV19VTkFTU0lHTkVEIHwgVVNFX1NURDNfQVNDSUlfUlVMRVN9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9Vbmljb2RlKFN0cmluZyBpbnB1dCwgaW50IGZsYWdzKSB7CisgICAgICAgIHJldHVybiBOYXRpdmVJRE4udG9Vbmljb2RlKGlucHV0LCBmbGFncyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgdG9Vbmljb2RlKGlucHV0LCAwKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQgdGhlIEFDRSBuYW1lCisgICAgICogQHJldHVybiB0aGUgVW5pY29kZSBuYW1lCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9Vbmljb2RlKFN0cmluZyBpbnB1dCkgeworICAgICAgICByZXR1cm4gTmF0aXZlSUROLnRvVW5pY29kZShpbnB1dCwgMCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0luZXQ0QWRkcmVzcy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0luZXQ0QWRkcmVzcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdjMjY2MzkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvSW5ldDRBZGRyZXNzLmphdmEKQEAgLTAsMCArMSwxMzEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlT3JkZXI7CitpbXBvcnQgbGliY29yZS5pby5NZW1vcnk7CitpbXBvcnQgc3RhdGljIGxpYmNvcmUuaW8uT3NDb25zdGFudHMuKjsKKworLyoqCisgKiBBbiBJUHY0IGFkZHJlc3MuIFNlZSB7QGxpbmsgSW5ldEFkZHJlc3N9LgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSW5ldDRBZGRyZXNzIGV4dGVuZHMgSW5ldEFkZHJlc3MgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzI4NjMxNjc2NDkxMDMxNjUwN0w7CisKKyAgICAvKioKKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW5ldEFkZHJlc3MgQU5ZID0KKyAgICAgICAgICAgIG5ldyBJbmV0NEFkZHJlc3MobmV3IGJ5dGVbXSB7IDAsIDAsIDAsIDAgfSwgbnVsbCk7CisKKyAgICAvKioKKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW5ldEFkZHJlc3MgQUxMID0KKyAgICAgICAgICAgIG5ldyBJbmV0NEFkZHJlc3MobmV3IGJ5dGVbXSB7IChieXRlKSAyNTUsIChieXRlKSAyNTUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMjU1LCAoYnl0ZSkgMjU1IH0sIG51bGwpOworCisgICAgLyoqCisgICAgICogQGhpZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEluZXRBZGRyZXNzIExPT1BCQUNLID0KKyAgICAgICAgICAgIG5ldyBJbmV0NEFkZHJlc3MobmV3IGJ5dGVbXSB7IDEyNywgMCwgMCwgMSB9LCAibG9jYWxob3N0Iik7CisKKyAgICBJbmV0NEFkZHJlc3MoYnl0ZVtdIGlwYWRkcmVzcywgU3RyaW5nIGhvc3ROYW1lKSB7CisgICAgICAgIHN1cGVyKEFGX0lORVQsIGlwYWRkcmVzcywgaG9zdE5hbWUpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc0FueUxvY2FsQWRkcmVzcygpIHsKKyAgICAgICAgcmV0dXJuIGlwYWRkcmVzc1swXSA9PSAwICYmIGlwYWRkcmVzc1sxXSA9PSAwICYmIGlwYWRkcmVzc1syXSA9PSAwICYmIGlwYWRkcmVzc1szXSA9PSAwOyAvLyAwLjAuMC4wCisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGlzTGlua0xvY2FsQWRkcmVzcygpIHsKKyAgICAgICAgLy8gVGhlIFJJIGRvZXMgbm90IHJldHVybiB0cnVlIGZvciBsb29wYmFjayBhZGRyZXNzZXMgZXZlbiB0aG91Z2ggUkZDIDM0ODQgc2F5cyB0byBkbyBzby4KKyAgICAgICAgcmV0dXJuICgoaXBhZGRyZXNzWzBdICYgMHhmZikgPT0gMTY5KSAmJiAoKGlwYWRkcmVzc1sxXSAmIDB4ZmYpID09IDI1NCk7IC8vIDE2OS4yNTQvMTYKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaXNMb29wYmFja0FkZHJlc3MoKSB7CisgICAgICAgIHJldHVybiAoKGlwYWRkcmVzc1swXSAmIDB4ZmYpID09IDEyNyk7IC8vIDEyNy84CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGlzTUNHbG9iYWwoKSB7CisgICAgICAgIC8vIENoZWNrIGlmIHdlIGhhdmUgYSBwcmVmaXggb2YgMTExMAorICAgICAgICBpZiAoIWlzTXVsdGljYXN0QWRkcmVzcygpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBpbnQgYWRkcmVzcyA9IE1lbW9yeS5wZWVrSW50KGlwYWRkcmVzcywgMCwgQnl0ZU9yZGVyLkJJR19FTkRJQU4pOworICAgICAgICAvKgorICAgICAgICAgKiBOb3cgY2hlY2sgdGhlIGJvdW5kYXJpZXMgb2YgdGhlIGdsb2JhbCBzcGFjZSBpZiB3ZSBoYXZlIGFuIGFkZHJlc3MKKyAgICAgICAgICogdGhhdCBpcyBwcmVmaXhlZCBieSBzb21ldGhpbmcgbGVzcyB0aGFuIDExMTAwMDAwMDAwMDAwMDAwMDAwMDAwMQorICAgICAgICAgKiAoZm9ydHVuYXRlbHkgd2UgZG9uJ3QgaGF2ZSB0byB3b3JyeSBhYm91dCBzaWduIGFmdGVyIHNoaWZ0aW5nIDggYml0cworICAgICAgICAgKiByaWdodCkgaXQgaXMgbm90IG11bHRpY2FzdC4gKCA8IDIyNC4wLjEuMCkKKyAgICAgICAgICovCisgICAgICAgIGlmIChhZGRyZXNzID4+PiA4IDwgMHhFMDAwMDEpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIE5vdyBjaGVjayB0aGUgaGlnaCBib3VuZGFyeSB3aGljaCBpcyBwcmVmaXhlZCBieSAxMTEwMTExMCA9IDB4RUUuIElmCisgICAgICAgICAqIHRoZSB2YWx1ZSBpcyBoaWdoZXIgdGhhbiB0aGlzIHRoYW4gaXQgaXMgbm90IE1DR2xvYmFsICggPgorICAgICAgICAgKiAyMzguMjU1LjI1NS4yNTUgKQorICAgICAgICAgKi8KKyAgICAgICAgaWYgKGFkZHJlc3MgPj4+IDI0ID4gMHhFRSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGlzTUNMaW5rTG9jYWwoKSB7CisgICAgICAgIHJldHVybiAoKGlwYWRkcmVzc1swXSAmIDB4ZmYpID09IDIyNCkgJiYgKGlwYWRkcmVzc1sxXSA9PSAwKSAmJiAoaXBhZGRyZXNzWzJdID09IDApOyAvLyAyMjQuMC4wLzI0CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGlzTUNOb2RlTG9jYWwoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaXNNQ09yZ0xvY2FsKCkgeworICAgICAgICByZXR1cm4gKChpcGFkZHJlc3NbMF0gJiAweGZmKSA9PSAyMzkpICYmICgoaXBhZGRyZXNzWzFdICYgMHhmYykgPT0gMTkyKTsgLy8gMjM5LjE5Mi8xNAorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc01DU2l0ZUxvY2FsKCkgeworICAgICAgICByZXR1cm4gKChpcGFkZHJlc3NbMF0gJiAweGZmKSA9PSAyMzkpICYmICgoaXBhZGRyZXNzWzFdICYgMHhmZikgPT0gMjU1KTsgLy8gMjM5LjI1NS8xNgorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc011bHRpY2FzdEFkZHJlc3MoKSB7CisgICAgICAgIHJldHVybiAoaXBhZGRyZXNzWzBdICYgMHhmMCkgPT0gMjI0OyAvLyAyMjQvNAorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc1NpdGVMb2NhbEFkZHJlc3MoKSB7CisgICAgICAgIGlmICgoaXBhZGRyZXNzWzBdICYgMHhmZikgPT0gMTApIHsgLy8gMTAvOAorICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0gZWxzZSBpZiAoKChpcGFkZHJlc3NbMF0gJiAweGZmKSA9PSAxNzIpICYmICgoaXBhZGRyZXNzWzFdICYgMHhmMCkgPT0gMTYpKSB7IC8vIDE3Mi4xNi8xMgorICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0gZWxzZSBpZiAoKChpcGFkZHJlc3NbMF0gJiAweGZmKSA9PSAxOTIpICYmICgoaXBhZGRyZXNzWzFdICYgMHhmZikgPT0gMTY4KSkgeyAvLyAxOTIuMTY4LzE2CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHJpdmF0ZSBPYmplY3Qgd3JpdGVSZXBsYWNlKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgSW5ldDRBZGRyZXNzKGlwYWRkcmVzcywgaG9zdE5hbWUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9JbmV0NkFkZHJlc3MuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9JbmV0NkFkZHJlc3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zN2U5YzE4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0luZXQ2QWRkcmVzcy5qYXZhCkBAIC0wLDAgKzEsMjg2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0U3RyZWFtRmllbGQ7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgc3RhdGljIGxpYmNvcmUuaW8uT3NDb25zdGFudHMuKjsKKworLyoqCisgKiBBbiBJUHY2IGFkZHJlc3MuIFNlZSB7QGxpbmsgSW5ldEFkZHJlc3N9LgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSW5ldDZBZGRyZXNzIGV4dGVuZHMgSW5ldEFkZHJlc3MgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjg4MDQxMDA3MDUxNjc5MzM3N0w7CisKKyAgICAvKioKKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW5ldEFkZHJlc3MgQU5ZID0KKyAgICAgICAgICAgIG5ldyBJbmV0NkFkZHJlc3MobmV3IGJ5dGVbXSB7MCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCB9LCBudWxsLCAwKTsKKworICAgIC8qKgorICAgICAqIEBoaWRlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBJbmV0QWRkcmVzcyBMT09QQkFDSyA9CisgICAgICAgICAgICBuZXcgSW5ldDZBZGRyZXNzKG5ldyBieXRlW10gezAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEgfSwKKyAgICAgICAgICAgICAgICAgICAgImxvY2FsaG9zdCIsIDApOworCisgICAgcHJpdmF0ZSBib29sZWFuIHNjb3BlX2lkX3NldDsKKyAgICBwcml2YXRlIGludCBzY29wZV9pZDsKKworICAgIHByaXZhdGUgYm9vbGVhbiBzY29wZV9pZm5hbWVfc2V0OworICAgIHByaXZhdGUgU3RyaW5nIGlmbmFtZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4ge0Bjb2RlIEluZXRBZGRyZXNzfSByZXByZXNlbnRpbmcgdGhlIHtAY29kZSBhZGRyZXNzfSBhbmQKKyAgICAgKiB7QGNvZGUgbmFtZX0gYW5kIHtAY29kZSBzY29wZV9pZH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWRkcmVzcworICAgICAqICAgICAgICAgICAgdGhlIG5ldHdvcmsgYWRkcmVzcy4KKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBhZGRyZXNzLgorICAgICAqIEBwYXJhbSBzY29wZV9pZAorICAgICAqICAgICAgICAgICAgdGhlIHNjb3BlIGlkIGZvciBsaW5rLSBvciBzaXRlLWxvY2FsIGFkZHJlc3Nlcy4KKyAgICAgKi8KKyAgICBJbmV0NkFkZHJlc3MoYnl0ZVtdIGlwYWRkcmVzcywgU3RyaW5nIGhvc3ROYW1lLCBpbnQgc2NvcGVfaWQpIHsKKyAgICAgICAgc3VwZXIoQUZfSU5FVDYsIGlwYWRkcmVzcywgaG9zdE5hbWUpOworICAgICAgICB0aGlzLnNjb3BlX2lkID0gc2NvcGVfaWQ7CisgICAgICAgIHRoaXMuc2NvcGVfaWRfc2V0ID0gKHNjb3BlX2lkICE9IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gSVB2NiBhZGRyZXNzIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4ge0Bjb2RlIGhvc3R9LCB7QGNvZGUKKyAgICAgKiBhZGRyfSBhbmQge0Bjb2RlIHNjb3BlX2lkfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3N0CisgICAgICogICAgICAgICAgICB0aGUgaG9zdCBuYW1lIGFzc29jaWF0ZWQgd2l0aCB0aGUgYWRkcmVzcy4KKyAgICAgKiBAcGFyYW0gYWRkcgorICAgICAqICAgICAgICAgICAgdGhlIG5ldHdvcmsgYWRkcmVzcy4KKyAgICAgKiBAcGFyYW0gc2NvcGVfaWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzY29wZSBpZCBmb3IgbGluay0gb3Igc2l0ZS1sb2NhbCBhZGRyZXNzZXMuCisgICAgICogQHJldHVybiB0aGUgSW5ldDZBZGRyZXNzIGluc3RhbmNlIHJlcHJlc2VudGluZyB0aGUgSVAgYWRkcmVzcy4KKyAgICAgKiBAdGhyb3dzIFVua25vd25Ib3N0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGFkZHJlc3MgaXMgbnVsbCBvciBoYXMgYW4gaW52YWxpZCBsZW5ndGguCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJbmV0NkFkZHJlc3MgZ2V0QnlBZGRyZXNzKFN0cmluZyBob3N0LCBieXRlW10gYWRkciwgaW50IHNjb3BlX2lkKQorICAgICAgICAgICAgdGhyb3dzIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFkZHIgPT0gbnVsbCB8fCBhZGRyLmxlbmd0aCAhPSAxNikgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVua25vd25Ib3N0RXhjZXB0aW9uKCJOb3QgYW4gSVB2NiBhZGRyZXNzOiAiICsgQXJyYXlzLnRvU3RyaW5nKGFkZHIpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc2NvcGVfaWQgPCAwKSB7CisgICAgICAgICAgICBzY29wZV9pZCA9IDA7CisgICAgICAgIH0KKyAgICAgICAgLy8gVE9ETzogc2hvdWxkIHdlIGNsb25lICdhZGRyJz8KKyAgICAgICAgcmV0dXJuIG5ldyBJbmV0NkFkZHJlc3MoYWRkciwgaG9zdCwgc2NvcGVfaWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gSVB2NiBhZGRyZXNzIGluc3RhbmNlIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4ge0Bjb2RlIGhvc3R9LAorICAgICAqIHtAY29kZSBhZGRyfSBhbmQge0Bjb2RlIG5pZn0uIHtAY29kZSBzY29wZV9pZH0gaXMgc2V0IGFjY29yZGluZyB0byB0aGUKKyAgICAgKiBnaXZlbiB7QGNvZGUgbmlmfSBhbmQgdGhlIHtAY29kZSBhZGRyfSB0eXBlIChmb3IgZXhhbXBsZSBzaXRlLWxvY2FsIG9yCisgICAgICogbGluay1sb2NhbCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaG9zdAorICAgICAqICAgICAgICAgICAgdGhlIGhvc3RuYW1lIGFzc29jaWF0ZWQgd2l0aCB0aGUgYWRkcmVzcy4KKyAgICAgKiBAcGFyYW0gYWRkcgorICAgICAqICAgICAgICAgICAgdGhlIG5ldHdvcmsgYWRkcmVzcy4KKyAgICAgKiBAcGFyYW0gbmlmCisgICAgICogICAgICAgICAgICB0aGUgbmV0d29yayBpbnRlcmZhY2UgdGhhdCB0aGlzIGFkZHJlc3MgaXMgYXNzb2NpYXRlZCB3aXRoLgorICAgICAqIEByZXR1cm4gdGhlIEluZXQ2QWRkcmVzcyBpbnN0YW5jZSByZXByZXNlbnRpbmcgdGhlIElQIGFkZHJlc3MuCisgICAgICogQHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhZGRyZXNzIGlzIHtAY29kZSBudWxsfSBvciBoYXMgYW4gaW52YWxpZCBsZW5ndGggb3IKKyAgICAgKiAgICAgICAgICAgICB0aGUgaW50ZXJmYWNlIGRvZXNuJ3QgaGF2ZSBhIG51bWVyaWMgc2NvcGUgaWQgZm9yIHRoZSBnaXZlbgorICAgICAqICAgICAgICAgICAgIGFkZHJlc3MgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEluZXQ2QWRkcmVzcyBnZXRCeUFkZHJlc3MoU3RyaW5nIGhvc3QsIGJ5dGVbXSBhZGRyLAorICAgICAgICAgICAgTmV0d29ya0ludGVyZmFjZSBuaWYpIHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisKKyAgICAgICAgSW5ldDZBZGRyZXNzIGFkZHJlc3MgPSBJbmV0NkFkZHJlc3MuZ2V0QnlBZGRyZXNzKGhvc3QsIGFkZHIsIDApOworCisgICAgICAgIC8vIGlmIG5pZiBpcyBudWxsLCBub3RoaW5nIG5lZWRzIHRvIGJlIHNldC4KKyAgICAgICAgaWYgKG5pZiA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gYWRkcmVzczsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGZpbmQgdGhlIGZpcnN0IGFkZHJlc3Mgd2hpY2ggbWF0Y2hlcyB0aGUgdHlwZSBhZGRyLAorICAgICAgICAvLyB0aGVuIHNldCB0aGUgc2NvcGVfaWQgYW5kIGlmbmFtZS4KKyAgICAgICAgRW51bWVyYXRpb248SW5ldEFkZHJlc3M+IGFkZHJlc3NMaXN0ID0gbmlmLmdldEluZXRBZGRyZXNzZXMoKTsKKyAgICAgICAgd2hpbGUgKGFkZHJlc3NMaXN0Lmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICBJbmV0QWRkcmVzcyBpYSA9IGFkZHJlc3NMaXN0Lm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICBpZiAoaWEuZ2V0QWRkcmVzcygpLmxlbmd0aCA9PSAxNikgeworICAgICAgICAgICAgICAgIEluZXQ2QWRkcmVzcyB2NmlhID0gKEluZXQ2QWRkcmVzcykgaWE7CisgICAgICAgICAgICAgICAgYm9vbGVhbiBpc1NhbWVUeXBlID0gdjZpYS5jb21wYXJlTG9jYWxUeXBlKGFkZHJlc3MpOworICAgICAgICAgICAgICAgIGlmIChpc1NhbWVUeXBlKSB7CisgICAgICAgICAgICAgICAgICAgIGFkZHJlc3Muc2NvcGVfaWRfc2V0ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgYWRkcmVzcy5zY29wZV9pZCA9IHY2aWEuc2NvcGVfaWQ7CisgICAgICAgICAgICAgICAgICAgIGFkZHJlc3Muc2NvcGVfaWZuYW1lX3NldCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIGFkZHJlc3MuaWZuYW1lID0gbmlmLmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIGlmIG5vIGFkZHJlc3MgbWF0Y2hlcyB0aGUgdHlwZSBvZiBhZGRyLCB0aHJvd3MgYW4KKyAgICAgICAgLy8gVW5rbm93bkhvc3RFeGNlcHRpb24uCisgICAgICAgIGlmICghYWRkcmVzcy5zY29wZV9pZF9zZXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbmtub3duSG9zdEV4Y2VwdGlvbigiU2NvcGUgaWQgbm90IGZvdW5kIGZvciBhZGRyZXNzOiAiICsgQXJyYXlzLnRvU3RyaW5nKGFkZHIpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYWRkcmVzczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiBvbmUgb2YgZm9sbG93aW5nIGNhc2VzIGFwcGxpZXM6CisgICAgICogPHA+CisgICAgICogPG9sPgorICAgICAqICA8bGk+Ym90aCBhZGRyZXNzZXMgYXJlIHNpdGUgbG9jYWw8L2xpPgorICAgICAqICA8bGk+Ym90aCBhZGRyZXNzZXMgYXJlIGxpbmsgbG9jYWw8L2xpPgorICAgICAqICA8bGk+e0Bjb2RlIGlhfSBpcyBuZWl0aGVyIHNpdGUgbG9jYWwgbm9yIGxpbmsgbG9jYWw8L2xpPgorICAgICAqIDwvb2w+CisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGNvbXBhcmVMb2NhbFR5cGUoSW5ldDZBZGRyZXNzIGlhKSB7CisgICAgICAgIGlmIChpYS5pc1NpdGVMb2NhbEFkZHJlc3MoKSAmJiBpc1NpdGVMb2NhbEFkZHJlc3MoKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlhLmlzTGlua0xvY2FsQWRkcmVzcygpICYmIGlzTGlua0xvY2FsQWRkcmVzcygpKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIWlhLmlzU2l0ZUxvY2FsQWRkcmVzcygpICYmICFpYS5pc0xpbmtMb2NhbEFkZHJlc3MoKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc0FueUxvY2FsQWRkcmVzcygpIHsKKyAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMoaXBhZGRyZXNzLCBJbmV0NkFkZHJlc3MuQU5ZLmlwYWRkcmVzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgSVB2NiBhZGRyZXNzIGlzIGFuIElQdjQtY29tcGF0aWJsZSBhZGRyZXNzIG9yIG5vdC4KKyAgICAgKiBBbiBJUHY0LWNvbXBhdGlibGUgYWRkcmVzcyBoYXMgdGhlIHByZWZpeCB7QGNvZGUgOjovOTZ9IGFuZCBpcyBhIGRlcHJlY2F0ZWQKKyAgICAgKiBhbmQgbm8tbG9uZ2VyIHVzZWQgZXF1aXZhbGVudCBvZiB0aGUgbW9kZXJuIElQdjQtbWFwcGVkIElQdjYgYWRkcmVzc2VzLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzSVB2NENvbXBhdGlibGVBZGRyZXNzKCkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEyOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChpcGFkZHJlc3NbaV0gIT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaXNMaW5rTG9jYWxBZGRyZXNzKCkgeworICAgICAgICByZXR1cm4gKChpcGFkZHJlc3NbMF0gJiAweGZmKSA9PSAweGZlKSAmJiAoKGlwYWRkcmVzc1sxXSAmIDB4YzApID09IDB4ODApOyAvLyBmZTgwOi8xMAorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc0xvb3BiYWNrQWRkcmVzcygpIHsKKyAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMoaXBhZGRyZXNzLCBJbmV0NkFkZHJlc3MuTE9PUEJBQ0suaXBhZGRyZXNzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaXNNQ0dsb2JhbCgpIHsKKyAgICAgICAgcmV0dXJuICgoaXBhZGRyZXNzWzBdICYgMHhmZikgPT0gMHhmZikgJiYgKChpcGFkZHJlc3NbMV0gJiAweDBmKSA9PSAweDBlKTsgLy8gZmZ4ZTovMTYKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaXNNQ0xpbmtMb2NhbCgpIHsKKyAgICAgICAgcmV0dXJuICgoaXBhZGRyZXNzWzBdICYgMHhmZikgPT0gMHhmZikgJiYgKChpcGFkZHJlc3NbMV0gJiAweDBmKSA9PSAweDAyKTsgLy8gZmZ4MjovMTYKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaXNNQ05vZGVMb2NhbCgpIHsKKyAgICAgICAgcmV0dXJuICgoaXBhZGRyZXNzWzBdICYgMHhmZikgPT0gMHhmZikgJiYgKChpcGFkZHJlc3NbMV0gJiAweDBmKSA9PSAweDAxKTsgLy8gZmZ4MTovMTYKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaXNNQ09yZ0xvY2FsKCkgeworICAgICAgICByZXR1cm4gKChpcGFkZHJlc3NbMF0gJiAweGZmKSA9PSAweGZmKSAmJiAoKGlwYWRkcmVzc1sxXSAmIDB4MGYpID09IDB4MDgpOyAvLyBmZng4Oi8xNgorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc01DU2l0ZUxvY2FsKCkgeworICAgICAgICByZXR1cm4gKChpcGFkZHJlc3NbMF0gJiAweGZmKSA9PSAweGZmKSAmJiAoKGlwYWRkcmVzc1sxXSAmIDB4MGYpID09IDB4MDUpOyAvLyBmZng1Oi8xNgorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc011bHRpY2FzdEFkZHJlc3MoKSB7CisgICAgICAgIHJldHVybiAoKGlwYWRkcmVzc1swXSAmIDB4ZmYpID09IDB4ZmYpOyAvLyBmZjo6LzgKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaXNTaXRlTG9jYWxBZGRyZXNzKCkgeworICAgICAgICByZXR1cm4gKChpcGFkZHJlc3NbMF0gJiAweGZmKSA9PSAweGZlKSAmJiAoKGlwYWRkcmVzc1sxXSAmIDB4YzApID09IDB4YzApOyAvLyBmZWMwOi8xMAorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNjb3BlIGlkIGlmIHRoaXMgYWRkcmVzcyBpcyBzY29wZWQgdG8gYW4gaW50ZXJmYWNlLCAwIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFNjb3BlSWQoKSB7CisgICAgICAgIHJldHVybiBzY29wZV9pZF9zZXQgPyBzY29wZV9pZCA6IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV0d29yayBpbnRlcmZhY2UgaWYgdGhpcyBhZGRyZXNzIGlzIGluc3RhbmNlZCB3aXRoIGEgc2NvcGVkCisgICAgICogbmV0d29yayBpbnRlcmZhY2UsIG51bGwgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBOZXR3b3JrSW50ZXJmYWNlIGdldFNjb3BlZEludGVyZmFjZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiAoc2NvcGVfaWZuYW1lX3NldCAmJiBpZm5hbWUgIT0gbnVsbCkgPyBOZXR3b3JrSW50ZXJmYWNlLmdldEJ5TmFtZShpZm5hbWUpIDogbnVsbDsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFN0cmVhbUZpZWxkW10gc2VyaWFsUGVyc2lzdGVudEZpZWxkcyA9IHsKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJpcGFkZHJlc3MiLCBieXRlW10uY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInNjb3BlX2lkIiwgaW50LmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJzY29wZV9pZF9zZXQiLCBib29sZWFuLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJzY29wZV9pZm5hbWVfc2V0IiwgYm9vbGVhbi5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiaWZuYW1lIiwgU3RyaW5nLmNsYXNzKSwKKyAgICB9OworCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdE91dHB1dFN0cmVhbS5QdXRGaWVsZCBmaWVsZHMgPSBzdHJlYW0ucHV0RmllbGRzKCk7CisgICAgICAgIGlmIChpcGFkZHJlc3MgPT0gbnVsbCkgeworICAgICAgICAgICAgZmllbGRzLnB1dCgiaXBhZGRyZXNzIiwgbnVsbCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmaWVsZHMucHV0KCJpcGFkZHJlc3MiLCBpcGFkZHJlc3MpOworICAgICAgICB9CisKKyAgICAgICAgZmllbGRzLnB1dCgic2NvcGVfaWQiLCBzY29wZV9pZCk7CisgICAgICAgIGZpZWxkcy5wdXQoInNjb3BlX2lkX3NldCIsIHNjb3BlX2lkX3NldCk7CisgICAgICAgIGZpZWxkcy5wdXQoInNjb3BlX2lmbmFtZV9zZXQiLCBzY29wZV9pZm5hbWVfc2V0KTsKKyAgICAgICAgZmllbGRzLnB1dCgiaWZuYW1lIiwgaWZuYW1lKTsKKyAgICAgICAgc3RyZWFtLndyaXRlRmllbGRzKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBPYmplY3RJbnB1dFN0cmVhbS5HZXRGaWVsZCBmaWVsZHMgPSBzdHJlYW0ucmVhZEZpZWxkcygpOworICAgICAgICBpcGFkZHJlc3MgPSAoYnl0ZVtdKSBmaWVsZHMuZ2V0KCJpcGFkZHJlc3MiLCBudWxsKTsKKyAgICAgICAgc2NvcGVfaWQgPSBmaWVsZHMuZ2V0KCJzY29wZV9pZCIsIDApOworICAgICAgICBzY29wZV9pZF9zZXQgPSBmaWVsZHMuZ2V0KCJzY29wZV9pZF9zZXQiLCBmYWxzZSk7CisgICAgICAgIGlmbmFtZSA9IChTdHJpbmcpIGZpZWxkcy5nZXQoImlmbmFtZSIsIG51bGwpOworICAgICAgICBzY29wZV9pZm5hbWVfc2V0ID0gZmllbGRzLmdldCgic2NvcGVfaWZuYW1lX3NldCIsIGZhbHNlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgaWYgKGlmbmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKSArICIlIiArIGlmbmFtZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc2NvcGVfaWQgIT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCkgKyAiJSIgKyBzY29wZV9pZDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvSW5ldEFkZHJlc3MuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9JbmV0QWRkcmVzcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxMmEzNTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvSW5ldEFkZHJlc3MuamF2YQpAQCAtMCwwICsxLDg1NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworaW1wb3J0IGRhbHZpay5zeXN0ZW0uQmxvY2tHdWFyZDsKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUZpZWxkOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEubmlvLkJ5dGVPcmRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuQ29tcGFyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ291bnREb3duTGF0Y2g7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0Jvb2xlYW47CitpbXBvcnQgbGliY29yZS5pby5FcnJub0V4Y2VwdGlvbjsKK2ltcG9ydCBsaWJjb3JlLmlvLkdhaUV4Y2VwdGlvbjsKK2ltcG9ydCBsaWJjb3JlLmlvLklvQnJpZGdlOworaW1wb3J0IGxpYmNvcmUuaW8uTGliY29yZTsKK2ltcG9ydCBsaWJjb3JlLmlvLk1lbW9yeTsKK2ltcG9ydCBsaWJjb3JlLmlvLlN0cnVjdEFkZHJpbmZvOworaW1wb3J0IHN0YXRpYyBsaWJjb3JlLmlvLk9zQ29uc3RhbnRzLio7CisKKy8qKgorICogQW4gSW50ZXJuZXQgUHJvdG9jb2wgKElQKSBhZGRyZXNzLiBUaGlzIGNhbiBiZSBlaXRoZXIgYW4gSVB2NCBhZGRyZXNzIG9yIGFuIElQdjYgYWRkcmVzcywgYW5kCisgKiBpbiBwcmFjdGljZSB5b3UnbGwgaGF2ZSBhbiBpbnN0YW5jZSBvZiBlaXRoZXIge0Bjb2RlIEluZXQ0QWRkcmVzc30gb3Ige0Bjb2RlIEluZXQ2QWRkcmVzc30gKHRoaXMKKyAqIGNsYXNzIGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQgZGlyZWN0bHkpLiBNb3N0IGNvZGUgZG9lcyBub3QgbmVlZCB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIHRoZSB0d28KKyAqIGZhbWlsaWVzLCBhbmQgc2hvdWxkIHVzZSB7QGNvZGUgSW5ldEFkZHJlc3N9LgorICoKKyAqIDxwPkFuIHtAY29kZSBJbmV0QWRkcmVzc30gbWF5IGhhdmUgYSBob3N0bmFtZSAoYWNjZXNzaWJsZSB2aWEge0Bjb2RlIGdldEhvc3ROYW1lfSksIGJ1dCBtYXkgbm90LAorICogZGVwZW5kaW5nIG9uIGhvdyB0aGUge0Bjb2RlIEluZXRBZGRyZXNzfSB3YXMgY3JlYXRlZC4KKyAqCisgKiA8aDQ+SVB2NCBudW1lcmljIGFkZHJlc3MgZm9ybWF0czwvaDQ+CisgKiA8cD5UaGUge0Bjb2RlIGdldEFsbEJ5TmFtZX0gbWV0aG9kIGFjY2VwdHMgSVB2NCBhZGRyZXNzZXMgaW4gdGhlICJkZWNpbWFsLWRvdHRlZC1xdWFkIiBmb3JtIG9ubHk6CisgKiA8dWw+CisgKiA8bGk+e0Bjb2RlICIxLjIuMy40In0gLSAxLjIuMy40CisgKiA8L3VsPgorICoKKyAqIDxoND5JUHY2IG51bWVyaWMgYWRkcmVzcyBmb3JtYXRzPC9oND4KKyAqIDxwPlRoZSB7QGNvZGUgZ2V0QWxsQnlOYW1lfSBtZXRob2QgYWNjZXB0cyBJUHY2IGFkZHJlc3NlcyBpbiB0aGUgZm9sbG93aW5nIGZvcm1zICh0aGlzIHRleHQKKyAqIGNvbWVzIGZyb20gPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjM3My50eHQiPlJGQyAyMzczPC9hPiwgd2hpY2ggeW91IHNob3VsZCBjb25zdWx0CisgKiBmb3IgZnVsbCBkZXRhaWxzIG9mIElQdjYgYWRkcmVzc2luZyk6CisgKiA8dWw+CisgKiA8bGk+PHA+VGhlIHByZWZlcnJlZCBmb3JtIGlzIHtAY29kZSB4Ong6eDp4Ong6eDp4Onh9LCB3aGVyZSB0aGUgJ3gncyBhcmUgdGhlCisgKiBoZXhhZGVjaW1hbCB2YWx1ZXMgb2YgdGhlIGVpZ2h0IDE2LWJpdCBwaWVjZXMgb2YgdGhlIGFkZHJlc3MuCisgKiBOb3RlIHRoYXQgaXQgaXMgbm90IG5lY2Vzc2FyeSB0byB3cml0ZSB0aGUgbGVhZGluZyB6ZXJvcyBpbiBhbgorICogaW5kaXZpZHVhbCBmaWVsZCwgYnV0IHRoZXJlIG11c3QgYmUgYXQgbGVhc3Qgb25lIG51bWVyYWwgaW4gZXZlcnkKKyAqIGZpZWxkIChleGNlcHQgZm9yIHRoZSBjYXNlIGRlc2NyaWJlZCBpbiB0aGUgbmV4dCBidWxsZXQpLgorICogRXhhbXBsZXM6CisgKiA8cHJlPgorICogICAgIEZFREM6QkE5ODo3NjU0OjMyMTA6RkVEQzpCQTk4Ojc2NTQ6MzIxMAorICogICAgIDEwODA6MDowOjA6ODo4MDA6MjAwQzo0MTdBPC9wcmU+CisgKiA8L2xpPgorICogPGxpPkR1ZSB0byBzb21lIG1ldGhvZHMgb2YgYWxsb2NhdGluZyBjZXJ0YWluIHN0eWxlcyBvZiBJUHY2CisgKiBhZGRyZXNzZXMsIGl0IHdpbGwgYmUgY29tbW9uIGZvciBhZGRyZXNzZXMgdG8gY29udGFpbiBsb25nIHN0cmluZ3MKKyAqIG9mIHplcm8gYml0cy4gIEluIG9yZGVyIHRvIG1ha2Ugd3JpdGluZyBhZGRyZXNzZXMgY29udGFpbmluZyB6ZXJvCisgKiBiaXRzIGVhc2llciBhIHNwZWNpYWwgc3ludGF4IGlzIGF2YWlsYWJsZSB0byBjb21wcmVzcyB0aGUgemVyb3MuCisgKiBUaGUgdXNlIG9mICI6OiIgaW5kaWNhdGVzIG11bHRpcGxlIGdyb3VwcyBvZiAxNi1iaXRzIG9mIHplcm9zLgorICogVGhlICI6OiIgY2FuIG9ubHkgYXBwZWFyIG9uY2UgaW4gYW4gYWRkcmVzcy4gIFRoZSAiOjoiIGNhbiBhbHNvIGJlCisgKiB1c2VkIHRvIGNvbXByZXNzIHRoZSBsZWFkaW5nIGFuZC9vciB0cmFpbGluZyB6ZXJvcyBpbiBhbiBhZGRyZXNzLgorICoKKyAqIEZvciBleGFtcGxlIHRoZSBmb2xsb3dpbmcgYWRkcmVzc2VzOgorICogPHByZT4KKyAqICAgICAxMDgwOjA6MDowOjg6ODAwOjIwMEM6NDE3QSAgYSB1bmljYXN0IGFkZHJlc3MKKyAqICAgICBGRjAxOjA6MDowOjA6MDowOjEwMSAgICAgICAgYSBtdWx0aWNhc3QgYWRkcmVzcworICogICAgIDA6MDowOjA6MDowOjA6MSAgICAgICAgICAgICB0aGUgbG9vcGJhY2sgYWRkcmVzcworICogICAgIDA6MDowOjA6MDowOjA6MCAgICAgICAgICAgICB0aGUgdW5zcGVjaWZpZWQgYWRkcmVzc2VzPC9wcmU+CisgKiBtYXkgYmUgcmVwcmVzZW50ZWQgYXM6CisgKiA8cHJlPgorICogICAgIDEwODA6Ojg6ODAwOjIwMEM6NDE3QSAgICAgICBhIHVuaWNhc3QgYWRkcmVzcworICogICAgIEZGMDE6OjEwMSAgICAgICAgICAgICAgICAgICBhIG11bHRpY2FzdCBhZGRyZXNzCisgKiAgICAgOjoxICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBsb29wYmFjayBhZGRyZXNzCisgKiAgICAgOjogICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSB1bnNwZWNpZmllZCBhZGRyZXNzZXM8L3ByZT4KKyAqIDwvbGk+CisgKiA8bGk+PHA+QW4gYWx0ZXJuYXRpdmUgZm9ybSB0aGF0IGlzIHNvbWV0aW1lcyBtb3JlIGNvbnZlbmllbnQgd2hlbiBkZWFsaW5nCisgKiB3aXRoIGEgbWl4ZWQgZW52aXJvbm1lbnQgb2YgSVB2NCBhbmQgSVB2NiBub2RlcyBpcworICoge0Bjb2RlIHg6eDp4Ong6eDp4OmQuZC5kLmR9LCB3aGVyZSB0aGUgJ3gncyBhcmUgdGhlIGhleGFkZWNpbWFsIHZhbHVlcyBvZgorICogdGhlIHNpeCBoaWdoLW9yZGVyIDE2LWJpdCBwaWVjZXMgb2YgdGhlIGFkZHJlc3MsIGFuZCB0aGUgJ2QncyBhcmUKKyAqIHRoZSBkZWNpbWFsIHZhbHVlcyBvZiB0aGUgZm91ciBsb3ctb3JkZXIgOC1iaXQgcGllY2VzIG9mIHRoZQorICogYWRkcmVzcyAoc3RhbmRhcmQgSVB2NCByZXByZXNlbnRhdGlvbikuICBFeGFtcGxlczoKKyAqIDxwcmU+CisgKiAgICAgMDowOjA6MDowOjA6MTMuMS42OC4zCisgKiAgICAgMDowOjA6MDowOkZGRkY6MTI5LjE0NC41Mi4zODwvcHJlPgorICogb3IgaW4gY29tcHJlc3NlZCBmb3JtOgorICogPHByZT4KKyAqICAgICA6OjEzLjEuNjguMworICogICAgIDo6RkZGRjoxMjkuMTQ0LjUyLjM4PC9wcmU+CisgKiA8L2xpPgorICogPC91bD4KKyAqIDxwPlNjb3BlcyBhcmUgZ2l2ZW4gdXNpbmcgYSB0cmFpbGluZyB7QGNvZGUgJX0gZm9sbG93ZWQgYnkgdGhlIHNjb3BlIGlkLCBhcyBpbgorICoge0Bjb2RlIDEwODA6Ojg6ODAwOjIwMEM6NDE3QSUyfSBvciB7QGNvZGUgMTA4MDo6ODo4MDA6MjAwQzo0MTdBJWVuMH0uCisgKiBTZWUgPGEgaHJlZj0iaHR0cHM6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzQwMDcudHh0Ij5SRkMgNDAwNzwvYT4gZm9yIG1vcmUgb24gSVB2NidzIHNjb3BlZAorICogYWRkcmVzcyBhcmNoaXRlY3R1cmUuCisgKgorICogPHA+QWRkaXRpb25hbGx5LCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHksIElQdjYgYWRkcmVzc2VzIG1heSBiZSBzdXJyb3VuZGVkIGJ5IHNxdWFyZQorICogYnJhY2tldHMuCisgKgorICogPGg0PkROUyBjYWNoaW5nPC9oND4KKyAqIDxwPk9uIEFuZHJvaWQsIGFkZHJlc3NlcyBhcmUgY2FjaGVkIGZvciA2MDAgc2Vjb25kcyAoMTAgbWludXRlcykgYnkgZGVmYXVsdC4gRmFpbGVkIGxvb2t1cHMgYXJlCisgKiBjYWNoZWQgZm9yIDEwIHNlY29uZHMuIFRoZSB1bmRlcmx5aW5nIEMgbGlicmFyeSBvciBPUyBtYXkgY2FjaGUgZm9yIGxvbmdlciwgYnV0IHlvdSBjYW4gY29udHJvbAorICogdGhlIEphdmEtbGV2ZWwgY2FjaGluZyB3aXRoIHRoZSB1c3VhbCB7QGNvZGUgIm5ldHdvcmthZGRyZXNzLmNhY2hlLnR0bCJ9IGFuZAorICoge0Bjb2RlICJuZXR3b3JrYWRkcmVzcy5jYWNoZS5uZWdhdGl2ZS50dGwifSBzeXN0ZW0gcHJvcGVydGllcy4gVGhlc2UgYXJlIHBhcnNlZCBhcyBpbnRlZ2VyCisgKiBudW1iZXJzIG9mIHNlY29uZHMsIHdoZXJlIHRoZSBzcGVjaWFsIHZhbHVlIDAgbWVhbnMgImRvbid0IGNhY2hlIiBhbmQgLTEgbWVhbnMgImNhY2hlIGZvcmV2ZXIiLgorICoKKyAqIDxwPk5vdGUgYWxzbyB0aGF0IG9uIEFuZHJvaWQgJm5kYXNoOyB1bmxpa2UgdGhlIFJJICZuZGFzaDsgdGhlIGNhY2hlIGlzIG5vdCB1bmJvdW5kZWQuIFRoZQorICogY3VycmVudCBpbXBsZW1lbnRhdGlvbiBjYWNoZXMgYXJvdW5kIDUxMiBlbnRyaWVzLCByZW1vdmVkIG9uIGEgbGVhc3QtcmVjZW50bHktdXNlZCBiYXNpcy4KKyAqIChPYnZpb3VzbHksIHlvdSBzaG91bGQgbm90IHJlbHkgb24gdGhlc2UgZGV0YWlscy4pCisgKgorICogQHNlZSBJbmV0NEFkZHJlc3MKKyAqIEBzZWUgSW5ldDZBZGRyZXNzCisgKi8KK3B1YmxpYyBjbGFzcyBJbmV0QWRkcmVzcyBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisgICAgLyoqIE91ciBKYXZhLXNpZGUgRE5TIGNhY2hlLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFkZHJlc3NDYWNoZSBhZGRyZXNzQ2FjaGUgPSBuZXcgQWRkcmVzc0NhY2hlKCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzMjg2MzE2NzY0OTEwMzE2NTA3TDsKKworICAgIHByaXZhdGUgaW50IGZhbWlseTsKKworICAgIGJ5dGVbXSBpcGFkZHJlc3M7CisKKyAgICBTdHJpbmcgaG9zdE5hbWU7CisKKyAgICAvKioKKyAgICAgKiBVc2VkIGJ5IHRoZSBEYXRhZ3JhbVNvY2tldC5kaXNjb25uZWN0IGltcGxlbWVudGF0aW9uLgorICAgICAqIEBoaWRlIGludGVybmFsIHVzZSBvbmx5CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBJbmV0QWRkcmVzcyBVTlNQRUNJRklFRCA9IG5ldyBJbmV0QWRkcmVzcyhBRl9VTlNQRUMsIG51bGwsIG51bGwpOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiB7QGNvZGUgSW5ldEFkZHJlc3N9LgorICAgICAqCisgICAgICogTm90ZTogdGhpcyBjb25zdHJ1Y3RvciBpcyBmb3Igc3ViY2xhc3NlcyBvbmx5LgorICAgICAqLworICAgIEluZXRBZGRyZXNzKGludCBmYW1pbHksIGJ5dGVbXSBpcGFkZHJlc3MsIFN0cmluZyBob3N0TmFtZSkgeworICAgICAgICB0aGlzLmZhbWlseSA9IGZhbWlseTsKKyAgICAgICAgdGhpcy5pcGFkZHJlc3MgPSBpcGFkZHJlc3M7CisgICAgICAgIHRoaXMuaG9zdE5hbWUgPSBob3N0TmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIHtAY29kZSBJbmV0QWRkcmVzc30gaW5zdGFuY2UgYWdhaW5zdCB0aGUgc3BlY2lmaWVkIGFkZHJlc3MKKyAgICAgKiBpbiB7QGNvZGUgb2JqfS4gVHdvIGFkZHJlc3NlcyBhcmUgZXF1YWwgaWYgdGhlaXIgYWRkcmVzcyBieXRlIGFycmF5cyBoYXZlCisgICAgICogdGhlIHNhbWUgbGVuZ3RoIGFuZCBpZiB0aGUgYnl0ZXMgaW4gdGhlIGFycmF5cyBhcmUgZXF1YWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGJlIHRlc3RlZCBmb3IgZXF1YWxpdHkuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYm90aCBvYmplY3RzIGFyZSBlcXVhbCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgSW5ldEFkZHJlc3MpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHModGhpcy5pcGFkZHJlc3MsICgoSW5ldEFkZHJlc3MpIG9iaikuaXBhZGRyZXNzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBJUCBhZGRyZXNzIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlIEluZXRBZGRyZXNzfSBpbnN0YW5jZQorICAgICAqIGFzIGEgYnl0ZSBhcnJheS4gVGhlIGVsZW1lbnRzIGFyZSBpbiBuZXR3b3JrIG9yZGVyICh0aGUgaGlnaGVzdCBvcmRlcgorICAgICAqIGFkZHJlc3MgYnl0ZSBpcyBpbiB0aGUgemVyb3RoIGVsZW1lbnQpLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYWRkcmVzcyBpbiBmb3JtIG9mIGEgYnl0ZSBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEFkZHJlc3MoKSB7CisgICAgICAgIHJldHVybiBpcGFkZHJlc3MuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyBhbiBhcnJheSBvZiBieXRlIGFycmF5cyByZXByZXNlbnRpbmcgcmF3IElQIGFkZHJlc3NlcyBvZiBhIGhvc3QKKyAgICAgKiB0byBhbiBhcnJheSBvZiBJbmV0QWRkcmVzcyBvYmplY3RzLgorICAgICAqCisgICAgICogQHBhcmFtIHJhd0FkZHJlc3NlcyB0aGUgcmF3IGFkZHJlc3NlcyB0byBjb252ZXJ0LgorICAgICAqIEBwYXJhbSBob3N0TmFtZSB0aGUgaG9zdG5hbWUgY29ycmVzcG9uZGluZyB0byB0aGUgSVAgYWRkcmVzcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIEluZXRBZGRyZXNzZXMsIGFwcHJvcHJpYXRlbHkgc29ydGVkLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIEluZXRBZGRyZXNzW10gYnl0ZXNUb0luZXRBZGRyZXNzZXMoYnl0ZVtdW10gcmF3QWRkcmVzc2VzLCBTdHJpbmcgaG9zdE5hbWUpCisgICAgICAgICAgICB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24geworICAgICAgICAvLyBDb252ZXJ0IHRoZSBieXRlIGFycmF5cyB0byBJbmV0QWRkcmVzc2VzLgorICAgICAgICBJbmV0QWRkcmVzc1tdIHJldHVybmVkQWRkcmVzc2VzID0gbmV3IEluZXRBZGRyZXNzW3Jhd0FkZHJlc3Nlcy5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJhd0FkZHJlc3Nlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgcmV0dXJuZWRBZGRyZXNzZXNbaV0gPSBtYWtlSW5ldEFkZHJlc3MocmF3QWRkcmVzc2VzW2ldLCBob3N0TmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJldHVybmVkQWRkcmVzc2VzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYWxsIElQIGFkZHJlc3NlcyBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIHtAY29kZSBob3N0fSBpZGVudGlmaWVkCisgICAgICogYnkgbmFtZSBvciBsaXRlcmFsIElQIGFkZHJlc3MuIFRoZSBJUCBhZGRyZXNzIGlzIHJlc29sdmVkIGJ5IHRoZQorICAgICAqIGNvbmZpZ3VyZWQgbmFtZSBzZXJ2aWNlLiBJZiB0aGUgaG9zdCBuYW1lIGlzIGVtcHR5IG9yIHtAY29kZSBudWxsfSBhbgorICAgICAqIHtAY29kZSBVbmtub3duSG9zdEV4Y2VwdGlvbn0gaXMgdGhyb3duLiBJZiB0aGUgaG9zdCBuYW1lIGlzIGEgbGl0ZXJhbCBJUAorICAgICAqIGFkZHJlc3Mgc3RyaW5nIGFuIGFycmF5IHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgc2luZ2xlIHtAY29kZSBJbmV0QWRkcmVzc30KKyAgICAgKiBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3N0IHRoZSBob3N0bmFtZSBvciBsaXRlcmFsIElQIHN0cmluZyB0byBiZSByZXNvbHZlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBhZGRyZXNzZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgaG9zdC4KKyAgICAgKiBAdGhyb3dzIFVua25vd25Ib3N0RXhjZXB0aW9uIGlmIHRoZSBhZGRyZXNzIGxvb2t1cCBmYWlscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEluZXRBZGRyZXNzW10gZ2V0QWxsQnlOYW1lKFN0cmluZyBob3N0KSB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZ2V0QWxsQnlOYW1lSW1wbChob3N0KS5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIEluZXRBZGRyZXNzZXMgZm9yIHtAY29kZSBob3N0fS4gVGhlIHJldHVybmVkIGFycmF5IGlzIHNoYXJlZAorICAgICAqIGFuZCBtdXN0IGJlIGNsb25lZCBiZWZvcmUgaXQgaXMgcmV0dXJuZWQgdG8gYXBwbGljYXRpb24gY29kZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBJbmV0QWRkcmVzc1tdIGdldEFsbEJ5TmFtZUltcGwoU3RyaW5nIGhvc3QpIHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChob3N0ID09IG51bGwgfHwgaG9zdC5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHJldHVybiBsb29wYmFja0FkZHJlc3NlcygpOworICAgICAgICB9CisKKyAgICAgICAgLy8gSXMgaXQgYSBudW1lcmljIGFkZHJlc3M/CisgICAgICAgIEluZXRBZGRyZXNzIHJlc3VsdCA9IHBhcnNlTnVtZXJpY0FkZHJlc3NOb1Rocm93KGhvc3QpOworICAgICAgICBpZiAocmVzdWx0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IGRpc2FsbG93RGVwcmVjYXRlZEZvcm1hdHMoaG9zdCwgcmVzdWx0KTsKKyAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbmtub3duSG9zdEV4Y2VwdGlvbigiRGVwcmVjYXRlZCBJUHY0IGFkZHJlc3MgZm9ybWF0OiAiICsgaG9zdCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IEluZXRBZGRyZXNzW10geyByZXN1bHQgfTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBsb29rdXBIb3N0QnlOYW1lKGhvc3QpLmNsb25lKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgSW5ldEFkZHJlc3MgbWFrZUluZXRBZGRyZXNzKGJ5dGVbXSBieXRlcywgU3RyaW5nIGhvc3ROYW1lKSB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24geworICAgICAgICBpZiAoYnl0ZXMubGVuZ3RoID09IDQpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgSW5ldDRBZGRyZXNzKGJ5dGVzLCBob3N0TmFtZSk7CisgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMubGVuZ3RoID09IDE2KSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEluZXQ2QWRkcmVzcyhieXRlcywgaG9zdE5hbWUsIDApOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgYmFkQWRkcmVzc0xlbmd0aChieXRlcyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBJbmV0QWRkcmVzcyBkaXNhbGxvd0RlcHJlY2F0ZWRGb3JtYXRzKFN0cmluZyBhZGRyZXNzLCBJbmV0QWRkcmVzcyBpbmV0QWRkcmVzcykgeworICAgICAgICAvLyBPbmx5IElQdjQgYWRkcmVzc2VzIGFyZSBwcm9ibGVtYXRpYy4KKyAgICAgICAgaWYgKCEoaW5ldEFkZHJlc3MgaW5zdGFuY2VvZiBJbmV0NEFkZHJlc3MpIHx8IGFkZHJlc3MuaW5kZXhPZignOicpICE9IC0xKSB7CisgICAgICAgICAgICByZXR1cm4gaW5ldEFkZHJlc3M7CisgICAgICAgIH0KKyAgICAgICAgLy8gSWYgaW5ldF9wdG9uKDMpIGNhbid0IHBhcnNlIGl0LCBpdCBtdXN0IGhhdmUgYmVlbiBhIGRlcHJlY2F0ZWQgZm9ybWF0LgorICAgICAgICAvLyBXZSBuZWVkIHRvIHJldHVybiBpbmV0X3B0b24oMykncyByZXN1bHQgdG8gZW5zdXJlIHRoYXQgbnVtYmVycyBhc3N1bWVkIHRvIGJlIG9jdGFsCisgICAgICAgIC8vIGJ5IGdldGFkZHJpbmZvKDMpIGFyZSByZWludGVycHJldGVkIGJ5IGluZXRfcHRvbigzKSBhcyBkZWNpbWFsLgorICAgICAgICByZXR1cm4gTGliY29yZS5vcy5pbmV0X3B0b24oQUZfSU5FVCwgYWRkcmVzcyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgSW5ldEFkZHJlc3MgcGFyc2VOdW1lcmljQWRkcmVzc05vVGhyb3coU3RyaW5nIGFkZHJlc3MpIHsKKyAgICAgICAgLy8gQWNjZXB0IElQdjYgYWRkcmVzc2VzIChvbmx5KSBpbiBzcXVhcmUgYnJhY2tldHMgZm9yIGNvbXBhdGliaWxpdHkuCisgICAgICAgIGlmIChhZGRyZXNzLnN0YXJ0c1dpdGgoIlsiKSAmJiBhZGRyZXNzLmVuZHNXaXRoKCJdIikgJiYgYWRkcmVzcy5pbmRleE9mKCc6JykgIT0gLTEpIHsKKyAgICAgICAgICAgIGFkZHJlc3MgPSBhZGRyZXNzLnN1YnN0cmluZygxLCBhZGRyZXNzLmxlbmd0aCgpIC0gMSk7CisgICAgICAgIH0KKyAgICAgICAgU3RydWN0QWRkcmluZm8gaGludHMgPSBuZXcgU3RydWN0QWRkcmluZm8oKTsKKyAgICAgICAgaGludHMuYWlfZmxhZ3MgPSBBSV9OVU1FUklDSE9TVDsKKyAgICAgICAgSW5ldEFkZHJlc3NbXSBhZGRyZXNzZXMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWRkcmVzc2VzID0gTGliY29yZS5vcy5nZXRhZGRyaW5mbyhhZGRyZXNzLCBoaW50cyk7CisgICAgICAgIH0gY2F0Y2ggKEdhaUV4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChhZGRyZXNzZXMgIT0gbnVsbCkgPyBhZGRyZXNzZXNbMF0gOiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFkZHJlc3Mgb2YgYSBob3N0IGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gaG9zdCBzdHJpbmcgbmFtZQorICAgICAqIHtAY29kZSBob3N0fS4gVGhlIGhvc3Qgc3RyaW5nIG1heSBiZSBlaXRoZXIgYSBtYWNoaW5lIG5hbWUgb3IgYSBkb3R0ZWQKKyAgICAgKiBzdHJpbmcgSVAgYWRkcmVzcy4gSWYgdGhlIGxhdHRlciwgdGhlIHtAY29kZSBob3N0TmFtZX0gZmllbGQgaXMKKyAgICAgKiBkZXRlcm1pbmVkIHVwb24gZGVtYW5kLiB7QGNvZGUgaG9zdH0gY2FuIGJlIHtAY29kZSBudWxsfSB3aGljaCBtZWFucyB0aGF0CisgICAgICogYW4gYWRkcmVzcyBvZiB0aGUgbG9vcGJhY2sgaW50ZXJmYWNlIGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGhvc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBob3N0TmFtZSB0byBiZSByZXNvbHZlZCB0byBhbiBhZGRyZXNzIG9yIHtAY29kZSBudWxsfS4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgSW5ldEFkZHJlc3N9IGluc3RhbmNlIHJlcHJlc2VudGluZyB0aGUgaG9zdC4KKyAgICAgKiBAdGhyb3dzIFVua25vd25Ib3N0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGFkZHJlc3MgbG9va3VwIGZhaWxzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgSW5ldEFkZHJlc3MgZ2V0QnlOYW1lKFN0cmluZyBob3N0KSB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZ2V0QWxsQnlOYW1lSW1wbChob3N0KVswXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1lcmljIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgSVAgYWRkcmVzcyAoc3VjaCBhcyAiMTI3LjAuMC4xIikuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRIb3N0QWRkcmVzcygpIHsKKyAgICAgICAgcmV0dXJuIExpYmNvcmUub3MuZ2V0bmFtZWluZm8odGhpcywgTklfTlVNRVJJQ0hPU1QpOyAvLyBDYW4ndCB0aHJvdy4KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBob3N0IG5hbWUgY29ycmVzcG9uZGluZyB0byB0aGlzIElQIGFkZHJlc3MuIFRoaXMgbWF5IG9yIG1heSBub3QgYmUgYQorICAgICAqIGZ1bGx5LXF1YWxpZmllZCBuYW1lLiBJZiB0aGUgSVAgYWRkcmVzcyBjb3VsZCBub3QgYmUgcmVzb2x2ZWQsIHRoZSBudW1lcmljIHJlcHJlc2VudGF0aW9uCisgICAgICogaXMgcmV0dXJuZWQgaW5zdGVhZCAoc2VlIHtAbGluayAjZ2V0SG9zdEFkZHJlc3N9KS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEhvc3ROYW1lKCkgeworICAgICAgICBpZiAoaG9zdE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBob3N0TmFtZSA9IGdldEhvc3RCeUFkZHJJbXBsKHRoaXMpLmhvc3ROYW1lOworICAgICAgICAgICAgfSBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBob3N0TmFtZSA9IGdldEhvc3RBZGRyZXNzKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGhvc3ROYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZ1bGx5IHF1YWxpZmllZCBob3N0bmFtZSBjb3JyZXNwb25kaW5nIHRvIHRoaXMgSVAgYWRkcmVzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENhbm9uaWNhbEhvc3ROYW1lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGdldEhvc3RCeUFkZHJJbXBsKHRoaXMpLmhvc3ROYW1lOworICAgICAgICB9IGNhdGNoIChVbmtub3duSG9zdEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgcmV0dXJuIGdldEhvc3RBZGRyZXNzKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIHtAY29kZSBJbmV0QWRkcmVzc30gZm9yIHRoZSBsb2NhbCBob3N0IGlmIHBvc3NpYmxlLCBvciB0aGUKKyAgICAgKiBsb29wYmFjayBhZGRyZXNzIG90aGVyd2lzZS4gVGhpcyBtZXRob2Qgd29ya3MgYnkgZ2V0dGluZyB0aGUgaG9zdG5hbWUsCisgICAgICogcGVyZm9ybWluZyBhIEROUyBsb29rdXAsIGFuZCB0aGVuIHRha2luZyB0aGUgZmlyc3QgcmV0dXJuZWQgYWRkcmVzcy4KKyAgICAgKiBGb3IgZGV2aWNlcyB3aXRoIG11bHRpcGxlIG5ldHdvcmsgaW50ZXJmYWNlcyBhbmQvb3IgbXVsdGlwbGUgYWRkcmVzc2VzCisgICAgICogcGVyIGludGVyZmFjZSwgdGhpcyBkb2VzIG5vdCBuZWNlc3NhcmlseSByZXR1cm4gdGhlIHtAY29kZSBJbmV0QWRkcmVzc30KKyAgICAgKiB5b3Ugd2FudC4KKyAgICAgKgorICAgICAqIDxwPk11bHRpcGxlIGludGVyZmFjZS9hZGRyZXNzIGNvbmZpZ3VyYXRpb25zIHdlcmUgcmVsYXRpdmVseSByYXJlCisgICAgICogd2hlbiB0aGlzIEFQSSB3YXMgZGVzaWduZWQsIGJ1dCBtdWx0aXBsZSBpbnRlcmZhY2VzIGFyZSB0aGUgZGVmYXVsdCBmb3IKKyAgICAgKiBtb2Rlcm4gbW9iaWxlIGRldmljZXMgKHdpdGggc2VwYXJhdGUgd2lmaSBhbmQgcmFkaW8gaW50ZXJmYWNlcyksIGFuZAorICAgICAqIHRoZSBuZWVkIHRvIHN1cHBvcnQgYm90aCBJUHY0IGFuZCBJUHY2IGhhcyBtYWRlIG11bHRpcGxlIGFkZHJlc3NlcworICAgICAqIGNvbW1vbnBsYWNlLiBOZXcgY29kZSBzaG91bGQgdGh1cyBhdm9pZCB0aGlzIG1ldGhvZCBleGNlcHQgd2hlcmUgaXQncworICAgICAqIGJhc2ljYWxseSBiZWluZyB1c2VkIHRvIGdldCBhIGxvb3BiYWNrIGFkZHJlc3Mgb3IgZXF1aXZhbGVudC4KKyAgICAgKgorICAgICAqIDxwPlRoZXJlIGFyZSB0d28gbWFpbiB3YXlzIHRvIGdldCBhIG1vcmUgc3BlY2lmaWMgYW5zd2VyOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+SWYgeW91IGhhdmUgYSBjb25uZWN0ZWQgc29ja2V0LCB5b3Ugc2hvdWxkIHByb2JhYmx5IHVzZQorICAgICAqIHtAbGluayBTb2NrZXQjZ2V0TG9jYWxBZGRyZXNzfSBpbnN0ZWFkOiB0aGF0IHdpbGwgZ2l2ZSB5b3UgdGhlIGFkZHJlc3MKKyAgICAgKiB0aGF0J3MgYWN0dWFsbHkgaW4gdXNlIGZvciB0aGF0IGNvbm5lY3Rpb24uIChJdCdzIG5vdCBwb3NzaWJsZSB0byBhc2sKKyAgICAgKiB0aGUgcXVlc3Rpb24gIndoYXQgbG9jYWwgYWRkcmVzcyB3b3VsZCBhIGNvbm5lY3Rpb24gdG8gYSBnaXZlbiByZW1vdGUKKyAgICAgKiBhZGRyZXNzIHVzZT8iOyB5b3UgaGF2ZSB0byBhY3R1YWxseSBtYWtlIHRoZSBjb25uZWN0aW9uIGFuZCBzZWUuKTwvbGk+CisgICAgICogPGxpPkZvciBvdGhlciB1c2UgY2FzZXMsIHNlZSB7QGxpbmsgTmV0d29ya0ludGVyZmFjZX0sIHdoaWNoIGxldHMgeW91CisgICAgICogZW51bWVyYXRlIGFsbCBhdmFpbGFibGUgbmV0d29yayBpbnRlcmZhY2VzIGFuZCB0aGVpciBhZGRyZXNzZXMuPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IGlmIHRoZSBob3N0IGRvZXNuJ3QgaGF2ZSBhIGhvc3RuYW1lIHNldCZuYnNwOyZuZGFzaDsgYXMKKyAgICAgKiBBbmRyb2lkIGRldmljZXMgdHlwaWNhbGx5IGRvbid0Jm5ic3A7Jm5kYXNoOyB0aGlzIG1ldGhvZCB3aWxsCisgICAgICogZWZmZWN0aXZlbHkgcmV0dXJuIHRoZSBsb29wYmFjayBhZGRyZXNzLCBhbGJlaXQgYnkgZ2V0dGluZyB0aGUgbmFtZQorICAgICAqIHtAY29kZSBsb2NhbGhvc3R9IGFuZCB0aGVuIGRvaW5nIGEgbG9va3VwIHRvIHRyYW5zbGF0ZSB0aGF0IHRvCisgICAgICoge0Bjb2RlIDEyNy4wLjAuMX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBJbmV0QWRkcmVzc30gcmVwcmVzZW50aW5nIHRoZSBsb2NhbCBob3N0LCBvciB0aGUKKyAgICAgKiBsb29wYmFjayBhZGRyZXNzLgorICAgICAqIEB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgYWRkcmVzcyBsb29rdXAgZmFpbHMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJbmV0QWRkcmVzcyBnZXRMb2NhbEhvc3QoKSB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgaG9zdCA9IExpYmNvcmUub3MudW5hbWUoKS5ub2RlbmFtZTsKKyAgICAgICAgcmV0dXJuIGxvb2t1cEhvc3RCeU5hbWUoaG9zdClbMF07CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaGFzaGNvZGUgb2YgdGhlIHJlcHJlc2VudGVkIElQIGFkZHJlc3MuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBhcHByb3ByaWF0ZSBoYXNoY29kZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gQXJyYXlzLmhhc2hDb2RlKGlwYWRkcmVzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzb2x2ZXMgYSBob3N0bmFtZSB0byBpdHMgSVAgYWRkcmVzc2VzIHVzaW5nIGEgY2FjaGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaG9zdCB0aGUgaG9zdG5hbWUgdG8gcmVzb2x2ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBJUCBhZGRyZXNzZXMgb2YgdGhlIGhvc3QuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgSW5ldEFkZHJlc3NbXSBsb29rdXBIb3N0QnlOYW1lKFN0cmluZyBob3N0KSB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24geworICAgICAgICBCbG9ja0d1YXJkLmdldFRocmVhZFBvbGljeSgpLm9uTmV0d29yaygpOworICAgICAgICAvLyBEbyB3ZSBoYXZlIGEgcmVzdWx0IGNhY2hlZD8KKyAgICAgICAgT2JqZWN0IGNhY2hlZFJlc3VsdCA9IGFkZHJlc3NDYWNoZS5nZXQoaG9zdCk7CisgICAgICAgIGlmIChjYWNoZWRSZXN1bHQgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKGNhY2hlZFJlc3VsdCBpbnN0YW5jZW9mIEluZXRBZGRyZXNzW10pIHsKKyAgICAgICAgICAgICAgICAvLyBBIGNhY2hlZCBwb3NpdGl2ZSByZXN1bHQuCisgICAgICAgICAgICAgICAgcmV0dXJuIChJbmV0QWRkcmVzc1tdKSBjYWNoZWRSZXN1bHQ7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIEEgY2FjaGVkIG5lZ2F0aXZlIHJlc3VsdC4KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5rbm93bkhvc3RFeGNlcHRpb24oKFN0cmluZykgY2FjaGVkUmVzdWx0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RydWN0QWRkcmluZm8gaGludHMgPSBuZXcgU3RydWN0QWRkcmluZm8oKTsKKyAgICAgICAgICAgIGhpbnRzLmFpX2ZsYWdzID0gQUlfQUREUkNPTkZJRzsKKyAgICAgICAgICAgIGhpbnRzLmFpX2ZhbWlseSA9IEFGX1VOU1BFQzsKKyAgICAgICAgICAgIC8vIElmIHdlIGRvbid0IHNwZWNpZnkgYSBzb2NrZXQgdHlwZSwgZXZlcnkgYWRkcmVzcyB3aWxsIGFwcGVhciB0d2ljZSwgb25jZQorICAgICAgICAgICAgLy8gZm9yIFNPQ0tfU1RSRUFNIGFuZCBvbmUgZm9yIFNPQ0tfREdSQU0uIFNpbmNlIHdlIGRvIG5vdCByZXR1cm4gdGhlIGZhbWlseQorICAgICAgICAgICAgLy8gYW55d2F5LCBqdXN0IHBpY2sgb25lLgorICAgICAgICAgICAgaGludHMuYWlfc29ja3R5cGUgPSBTT0NLX1NUUkVBTTsKKyAgICAgICAgICAgIEluZXRBZGRyZXNzW10gYWRkcmVzc2VzID0gTGliY29yZS5vcy5nZXRhZGRyaW5mbyhob3N0LCBoaW50cyk7CisgICAgICAgICAgICAvLyBUT0RPOiBzaG91bGQgZ2V0YWRkcmluZm8gc2V0IHRoZSBob3N0bmFtZSBvZiB0aGUgSW5ldEFkZHJlc3NlcyBpdCByZXR1cm5zPworICAgICAgICAgICAgZm9yIChJbmV0QWRkcmVzcyBhZGRyZXNzIDogYWRkcmVzc2VzKSB7CisgICAgICAgICAgICAgICAgYWRkcmVzcy5ob3N0TmFtZSA9IGhvc3Q7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhZGRyZXNzQ2FjaGUucHV0KGhvc3QsIGFkZHJlc3Nlcyk7CisgICAgICAgICAgICByZXR1cm4gYWRkcmVzc2VzOworICAgICAgICB9IGNhdGNoIChHYWlFeGNlcHRpb24gZ2FpRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAvLyBUT0RPOiBiaW9uaWMgY3VycmVudGx5IHJldHVybnMgRUFJX05PREFUQSwgd2hpY2ggaXMgaW5kaXN0aW5ndWlzaGFibGUgZnJvbSBhIHJlYWwKKyAgICAgICAgICAgIC8vIGZhaWx1cmUuIFdlIG5lZWQgdG8gZml4IGJpb25pYyBiZWZvcmUgd2UgY2FuIHJlcG9ydCBhIG1vcmUgdXNlZnVsIGVycm9yLgorICAgICAgICAgICAgLy8gaWYgKGdhaUV4Y2VwdGlvbi5lcnJvciA9PSBFQUlfU1lTVEVNKSB7CisgICAgICAgICAgICAvLyAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oIlBlcm1pc3Npb24gZGVuaWVkIChtaXNzaW5nIElOVEVSTkVUIHBlcm1pc3Npb24/KSIpOworICAgICAgICAgICAgLy8gfQorICAgICAgICAgICAgU3RyaW5nIGRldGFpbE1lc3NhZ2UgPSAiVW5hYmxlIHRvIHJlc29sdmUgaG9zdCBcIiIgKyBob3N0ICsgIlwiOiAiICsgTGliY29yZS5vcy5nYWlfc3RyZXJyb3IoZ2FpRXhjZXB0aW9uLmVycm9yKTsKKyAgICAgICAgICAgIGFkZHJlc3NDYWNoZS5wdXRVbmtub3duSG9zdChob3N0LCBkZXRhaWxNZXNzYWdlKTsKKyAgICAgICAgICAgIHRocm93IGdhaUV4Y2VwdGlvbi5yZXRocm93QXNVbmtub3duSG9zdEV4Y2VwdGlvbihkZXRhaWxNZXNzYWdlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIGVudHJpZXMgZnJvbSB0aGUgVk0ncyBETlMgY2FjaGUuIFRoaXMgZG9lcyBub3QgYWZmZWN0IHRoZSBDIGxpYnJhcnkncyBETlMKKyAgICAgKiBjYWNoZSwgbm9yIGFueSBjYWNoaW5nIEROUyBzZXJ2ZXJzIGJldHdlZW4geW91IGFuZCB0aGUgY2Fub25pY2FsIHNlcnZlci4KKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjbGVhckRuc0NhY2hlKCkgeworICAgICAgICBhZGRyZXNzQ2FjaGUuY2xlYXIoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBJbmV0QWRkcmVzcyBnZXRIb3N0QnlBZGRySW1wbChJbmV0QWRkcmVzcyBhZGRyZXNzKSB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24geworICAgICAgICBCbG9ja0d1YXJkLmdldFRocmVhZFBvbGljeSgpLm9uTmV0d29yaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIGhvc3RuYW1lID0gTGliY29yZS5vcy5nZXRuYW1laW5mbyhhZGRyZXNzLCBOSV9OQU1FUkVRRCk7CisgICAgICAgICAgICByZXR1cm4gbWFrZUluZXRBZGRyZXNzKGFkZHJlc3MuaXBhZGRyZXNzLmNsb25lKCksIGhvc3RuYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoR2FpRXhjZXB0aW9uIGdhaUV4Y2VwdGlvbikgeworICAgICAgICAgICAgdGhyb3cgZ2FpRXhjZXB0aW9uLnJldGhyb3dBc1Vua25vd25Ib3N0RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGlzCisgICAgICogSVAgYWRkcmVzcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGRlc2NyaXB0aW9uLCBhcyBob3N0L2FkZHJlc3MuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIChob3N0TmFtZSA9PSBudWxsID8gIiIgOiBob3N0TmFtZSkgKyAiLyIgKyBnZXRIb3N0QWRkcmVzcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3RyaW5nIGlzIGEgdmFsaWQgbnVtZXJpYyBJUHY0IG9yIElQdjYgYWRkcmVzcyAoc3VjaCBhcyAiMTkyLjE2OC4wLjEiKS4KKyAgICAgKiBUaGlzIGNvcGVzIHdpdGggYWxsIGZvcm1zIG9mIGFkZHJlc3MgdGhhdCBKYXZhIHN1cHBvcnRzLCBkZXRhaWxlZCBpbiB0aGUge0BsaW5rIEluZXRBZGRyZXNzfQorICAgICAqIGNsYXNzIGRvY3VtZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAaGlkZSB1c2VkIGJ5IGZyYW1ld29ya3MvYmFzZSB0byBlbnN1cmUgdGhhdCBhIGdldEFsbEJ5TmFtZSB3b24ndCBjYXVzZSBhIEROUyBsb29rdXAuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTnVtZXJpYyhTdHJpbmcgYWRkcmVzcykgeworICAgICAgICBJbmV0QWRkcmVzcyBpbmV0QWRkcmVzcyA9IHBhcnNlTnVtZXJpY0FkZHJlc3NOb1Rocm93KGFkZHJlc3MpOworICAgICAgICByZXR1cm4gaW5ldEFkZHJlc3MgIT0gbnVsbCAmJiBkaXNhbGxvd0RlcHJlY2F0ZWRGb3JtYXRzKGFkZHJlc3MsIGluZXRBZGRyZXNzKSAhPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gSW5ldEFkZHJlc3MgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gbnVtZXJpYyBhZGRyZXNzIChzdWNoCisgICAgICogYXMge0Bjb2RlICIxOTIuMTY4LjAuMSJ9IG9yIHtAY29kZSAiMjAwMTo0ODYwOjgwMGQ6OjY4In0pLgorICAgICAqIFRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIgZG8gYSBETlMgbG9va3VwLiBOb24tbnVtZXJpYyBhZGRyZXNzZXMgYXJlIGVycm9ycy4KKyAgICAgKgorICAgICAqIEBoaWRlIHVzZWQgYnkgZnJhbWV3b3Jrcy9iYXNlJ3MgTmV0d29ya1V0aWxzLm51bWVyaWNUb0luZXRBZGRyZXNzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIG51bWVyaWNBZGRyZXNzfSBpcyBub3QgYSBudW1lcmljIGFkZHJlc3MKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEluZXRBZGRyZXNzIHBhcnNlTnVtZXJpY0FkZHJlc3MoU3RyaW5nIG51bWVyaWNBZGRyZXNzKSB7CisgICAgICAgIGlmIChudW1lcmljQWRkcmVzcyA9PSBudWxsIHx8IG51bWVyaWNBZGRyZXNzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIEluZXQ2QWRkcmVzcy5MT09QQkFDSzsKKyAgICAgICAgfQorICAgICAgICBJbmV0QWRkcmVzcyByZXN1bHQgPSBwYXJzZU51bWVyaWNBZGRyZXNzTm9UaHJvdyhudW1lcmljQWRkcmVzcyk7CisgICAgICAgIHJlc3VsdCA9IGRpc2FsbG93RGVwcmVjYXRlZEZvcm1hdHMobnVtZXJpY0FkZHJlc3MsIHJlc3VsdCk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm90IGEgbnVtZXJpYyBhZGRyZXNzOiAiICsgbnVtZXJpY0FkZHJlc3MpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgSW5ldEFkZHJlc3NbXSBsb29wYmFja0FkZHJlc3NlcygpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBJbmV0QWRkcmVzc1tdIHsgSW5ldDZBZGRyZXNzLkxPT1BCQUNLLCBJbmV0NEFkZHJlc3MuTE9PUEJBQ0sgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBJUHY2IGxvb3BiYWNrIGFkZHJlc3Mge0Bjb2RlIDo6MX0gb3IgdGhlIElQdjQgbG9vcGJhY2sgYWRkcmVzcyB7QGNvZGUgMTI3LjAuMC4xfS4KKyAgICAgKiBAc2luY2UgMS43CisgICAgICogQGhpZGUgMS43CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJbmV0QWRkcmVzcyBnZXRMb29wYmFja0FkZHJlc3MoKSB7CisgICAgICAgIHJldHVybiBJbmV0NkFkZHJlc3MuTE9PUEJBQ0s7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgaXMgdGhlIElQdjYgdW5zcGVjaWZpZWQgd2lsZGNhcmQgYWRkcmVzcyB7QGNvZGUgOjp9CisgICAgICogb3IgdGhlIElQdjQgImFueSIgYWRkcmVzcywge0Bjb2RlIDAuMC4wLjB9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQW55TG9jYWxBZGRyZXNzKCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgYWRkcmVzcyBpcyBhIGxpbmstbG9jYWwgYWRkcmVzcyBvciBub3QuCisgICAgICoKKyAgICAgKiA8cD5WYWxpZCBJUHY2IGxpbmstbG9jYWwgYWRkcmVzc2VzIGhhdmUgdGhlIHByZWZpeCB7QGNvZGUgZmU4MDo6LzEwfS4KKyAgICAgKgorICAgICAqIDxwPjxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzM0ODQudHh0Ij5SRkMgMzQ4NDwvYT4KKyAgICAgKiAiRGVmYXVsdCBBZGRyZXNzIFNlbGVjdGlvbiBmb3IgSW50ZXJuZXQgUHJvdG9jb2wgVmVyc2lvbiA2IChJUHY2KSIgc3RhdGVzCisgICAgICogdGhhdCBib3RoIElQdjQgYXV0by1jb25maWd1cmF0aW9uIGFkZHJlc3NlcyAocHJlZml4IHtAY29kZSAxNjkuMjU0LzE2fSkgYW5kCisgICAgICogSVB2NCBsb29wYmFjayBhZGRyZXNzZXMgKHByZWZpeCB7QGNvZGUgMTI3Lzh9KSBoYXZlIGxpbmstbG9jYWwgc2NvcGUsIGJ1dAorICAgICAqIHtAbGluayBJbmV0NEFkZHJlc3N9IG9ubHkgY29uc2lkZXJzIHRoZSBhdXRvLWNvbmZpZ3VyYXRpb24gYWRkcmVzc2VzCisgICAgICogdG8gaGF2ZSBsaW5rLWxvY2FsIHNjb3BlLiBUaGF0IGlzOiB0aGUgSVB2NCBsb29wYmFjayBhZGRyZXNzIHJldHVybnMgZmFsc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNMaW5rTG9jYWxBZGRyZXNzKCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgYWRkcmVzcyBpcyBhIGxvb3BiYWNrIGFkZHJlc3Mgb3Igbm90LgorICAgICAqCisgICAgICogPHA+VmFsaWQgSVB2NCBsb29wYmFjayBhZGRyZXNzZXMgaGF2ZSB0aGUgcHJlZml4IHtAY29kZSAxMjcvOH0uCisgICAgICoKKyAgICAgKiA8cD5UaGUgb25seSB2YWxpZCBJUHY2IGxvb3BiYWNrIGFkZHJlc3MgaXMge0Bjb2RlIDo6MX0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNMb29wYmFja0FkZHJlc3MoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBhZGRyZXNzIGlzIGEgZ2xvYmFsIG11bHRpY2FzdCBhZGRyZXNzIG9yIG5vdC4KKyAgICAgKgorICAgICAqIDxwPlZhbGlkIElQdjYgZ2xvYmFsIG11bHRpY2FzdCBhZGRyZXNzZXMgaGF2ZSB0aGUgcHJlZml4IHtAY29kZSBmZnhlOjovMTZ9LAorICAgICAqIHdoZXJlIHtAY29kZSB4fSBpcyBhIHNldCBvZiBmbGFncyBhbmQgdGhlIGFkZGl0aW9uYWwgMTEyIGJpdHMgbWFrZQorICAgICAqIHVwIHRoZSBnbG9iYWwgbXVsdGljYXN0IGFkZHJlc3Mgc3BhY2UuCisgICAgICoKKyAgICAgKiA8cD5WYWxpZCBJUHY0IGdsb2JhbCBtdWx0aWNhc3QgYWRkcmVzc2VzIGFyZSB0aGUgcmFuZ2Ugb2YgYWRkcmVzc2VzCisgICAgICogZnJvbSB7QGNvZGUgMjI0LjAuMS4wfSB0byB7QGNvZGUgMjM4LjI1NS4yNTUuMjU1fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc01DR2xvYmFsKCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgYWRkcmVzcyBpcyBhIGxpbmstbG9jYWwgbXVsdGljYXN0IGFkZHJlc3Mgb3Igbm90LgorICAgICAqCisgICAgICogPHA+VmFsaWQgSVB2NiBsaW5rLWxvY2FsIG11bHRpY2FzdCBhZGRyZXNzZXMgaGF2ZSB0aGUgcHJlZml4IHtAY29kZSBmZngyOjovMTZ9LAorICAgICAqIHdoZXJlIHggaXMgYSBzZXQgb2YgZmxhZ3MgYW5kIHRoZSBhZGRpdGlvbmFsIDExMiBiaXRzIG1ha2UgdXAgdGhlIGxpbmstbG9jYWwgbXVsdGljYXN0CisgICAgICogYWRkcmVzcyBzcGFjZS4KKyAgICAgKgorICAgICAqIDxwPlZhbGlkIElQdjQgbGluay1sb2NhbCBtdWx0aWNhc3QgYWRkcmVzc2VzIGhhdmUgdGhlIHByZWZpeCB7QGNvZGUgMjI0LjAuMC8yNH0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNNQ0xpbmtMb2NhbCgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIGFkZHJlc3MgaXMgYSBub2RlLWxvY2FsIG11bHRpY2FzdCBhZGRyZXNzIG9yIG5vdC4KKyAgICAgKgorICAgICAqIDxwPlZhbGlkIElQdjYgbm9kZS1sb2NhbCBtdWx0aWNhc3QgYWRkcmVzc2VzIGhhdmUgdGhlIHByZWZpeCB7QGNvZGUgZmZ4MTo6LzE2fSwKKyAgICAgKiB3aGVyZSB4IGlzIGEgc2V0IG9mIGZsYWdzIGFuZCB0aGUgYWRkaXRpb25hbCAxMTIgYml0cyBtYWtlIHVwIHRoZSBsaW5rLWxvY2FsIG11bHRpY2FzdAorICAgICAqIGFkZHJlc3Mgc3BhY2UuCisgICAgICoKKyAgICAgKiA8cD5UaGVyZSBhcmUgbm8gdmFsaWQgSVB2NCBub2RlLWxvY2FsIG11bHRpY2FzdCBhZGRyZXNzZXMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNNQ05vZGVMb2NhbCgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIGFkZHJlc3MgaXMgYSBvcmdhbml6YXRpb24tbG9jYWwgbXVsdGljYXN0IGFkZHJlc3Mgb3Igbm90LgorICAgICAqCisgICAgICogPHA+VmFsaWQgSVB2NiBvcmdhbml6YXRpb24tbG9jYWwgbXVsdGljYXN0IGFkZHJlc3NlcyBoYXZlIHRoZSBwcmVmaXgge0Bjb2RlIGZmeDg6Oi8xNn0sCisgICAgICogd2hlcmUgeCBpcyBhIHNldCBvZiBmbGFncyBhbmQgdGhlIGFkZGl0aW9uYWwgMTEyIGJpdHMgbWFrZSB1cCB0aGUgbGluay1sb2NhbCBtdWx0aWNhc3QKKyAgICAgKiBhZGRyZXNzIHNwYWNlLgorICAgICAqCisgICAgICogPHA+VmFsaWQgSVB2NCBvcmdhbml6YXRpb24tbG9jYWwgbXVsdGljYXN0IGFkZHJlc3NlcyBoYXZlIHRoZSBwcmVmaXgge0Bjb2RlIDIzOS4xOTIvMTR9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzTUNPcmdMb2NhbCgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIGFkZHJlc3MgaXMgYSBzaXRlLWxvY2FsIG11bHRpY2FzdCBhZGRyZXNzIG9yIG5vdC4KKyAgICAgKgorICAgICAqIDxwPlZhbGlkIElQdjYgc2l0ZS1sb2NhbCBtdWx0aWNhc3QgYWRkcmVzc2VzIGhhdmUgdGhlIHByZWZpeCB7QGNvZGUgZmZ4NTo6LzE2fSwKKyAgICAgKiB3aGVyZSB4IGlzIGEgc2V0IG9mIGZsYWdzIGFuZCB0aGUgYWRkaXRpb25hbCAxMTIgYml0cyBtYWtlIHVwIHRoZSBsaW5rLWxvY2FsIG11bHRpY2FzdAorICAgICAqIGFkZHJlc3Mgc3BhY2UuCisgICAgICoKKyAgICAgKiA8cD5WYWxpZCBJUHY0IHNpdGUtbG9jYWwgbXVsdGljYXN0IGFkZHJlc3NlcyBoYXZlIHRoZSBwcmVmaXgge0Bjb2RlIDIzOS4yNTUvMTZ9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzTUNTaXRlTG9jYWwoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBhZGRyZXNzIGlzIGEgbXVsdGljYXN0IGFkZHJlc3Mgb3Igbm90LgorICAgICAqCisgICAgICogPHA+VmFsaWQgSVB2NiBtdWx0aWNhc3QgYWRkcmVzc2VzIGhhdmUgdGhlIHByZWZpeCB7QGNvZGUgZmY6Oi84fS4KKyAgICAgKgorICAgICAqIDxwPlZhbGlkIElQdjQgbXVsdGljYXN0IGFkZHJlc3NlcyBoYXZlIHRoZSBwcmVmaXgge0Bjb2RlIDIyNC80fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc011bHRpY2FzdEFkZHJlc3MoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBhZGRyZXNzIGlzIGEgc2l0ZS1sb2NhbCBhZGRyZXNzIG9yIG5vdC4KKyAgICAgKgorICAgICAqIDxwPkZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBtZXRob2QsIHZhbGlkIElQdjYgc2l0ZS1sb2NhbCBhZGRyZXNzZXMgaGF2ZQorICAgICAqIHRoZSBkZXByZWNhdGVkIHByZWZpeCB7QGNvZGUgZmVjMDo6LzEwfSBmcm9tCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMTg4NC50eHQiPlJGQyAxODg0PC9hPiwKKyAgICAgKiA8aT5ub3Q8L2k+IHRoZSBtb2Rlcm4gcHJlZml4IHtAY29kZSBmYzAwOjovN30gZnJvbQorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzQxOTMudHh0Ij5SRkMgNDE5MzwvYT4uCisgICAgICoKKyAgICAgKiA8cD48YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzNDg0LnR4dCI+UkZDIDM0ODQ8L2E+CisgICAgICogIkRlZmF1bHQgQWRkcmVzcyBTZWxlY3Rpb24gZm9yIEludGVybmV0IFByb3RvY29sIFZlcnNpb24gNiAoSVB2NikiIHN0YXRlcworICAgICAqIHRoYXQgSVB2NCBwcml2YXRlIGFkZHJlc3NlcyBoYXZlIHRoZSBwcmVmaXgge0Bjb2RlIDEwLzh9LCB7QGNvZGUgMTcyLjE2LzEyfSwKKyAgICAgKiBvciB7QGNvZGUgMTkyLjE2OC8xNn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGluc3RhbmNlIHJlcHJlc2VudHMgYSBzaXRlLWxvY2FsIGFkZHJlc3MsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NpdGVMb2NhbEFkZHJlc3MoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmllcyB0byByZWFjaCB0aGlzIHtAY29kZSBJbmV0QWRkcmVzc30uIFRoaXMgbWV0aG9kIGZpcnN0IHRyaWVzIHRvIHVzZQorICAgICAqIElDTVAgPGk+KElDTVAgRUNITyBSRVFVRVNUKTwvaT4sIGZhbGxpbmcgYmFjayB0byBhIFRDUCBjb25uZWN0aW9uCisgICAgICogb24gcG9ydCA3IChFY2hvKSBvZiB0aGUgcmVtb3RlIGhvc3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGltZW91dAorICAgICAqICAgICAgICAgICAgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgYmVmb3JlIHRoZSB0ZXN0IGZhaWxzIGlmIG5vIGNvbm5lY3Rpb24KKyAgICAgKiAgICAgICAgICAgIGNvdWxkIGJlIGVzdGFibGlzaGVkLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgYWRkcmVzcyBpcyByZWFjaGFibGUsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyBhbiBJL08gb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGltZW91dCBpcyBsZXNzIHRoYW4gemVyby4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1JlYWNoYWJsZShpbnQgdGltZW91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGlzUmVhY2hhYmxlKG51bGwsIDAsIHRpbWVvdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyaWVzIHRvIHJlYWNoIHRoaXMge0Bjb2RlIEluZXRBZGRyZXNzfS4gVGhpcyBtZXRob2QgZmlyc3QgdHJpZXMgdG8gdXNlCisgICAgICogSUNNUCA8aT4oSUNNUCBFQ0hPIFJFUVVFU1QpPC9pPiwgZmFsbGluZyBiYWNrIHRvIGEgVENQIGNvbm5lY3Rpb24KKyAgICAgKiBvbiBwb3J0IDcgKEVjaG8pIG9mIHRoZSByZW1vdGUgaG9zdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXR3b3JrSW50ZXJmYWNlCisgICAgICogICAgICAgICAgICB0aGUgbmV0d29yayBpbnRlcmZhY2Ugb24gd2hpY2ggdG8gY29ubmVjdGlvbiBzaG91bGQgYmUKKyAgICAgKiAgICAgICAgICAgIGVzdGFibGlzaGVkLgorICAgICAqIEBwYXJhbSB0dGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIGNvdW50IG9mIGhvcHMgKHRpbWUtdG8tbGl2ZSkuCisgICAgICogQHBhcmFtIHRpbWVvdXQKKyAgICAgKiAgICAgICAgICAgIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGJlZm9yZSB0aGUgdGVzdCBmYWlscyBpZiBubyBjb25uZWN0aW9uCisgICAgICogICAgICAgICAgICBjb3VsZCBiZSBlc3RhYmxpc2hlZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGFkZHJlc3MgaXMgcmVhY2hhYmxlLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBkdXJpbmcgYW4gSS9PIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHR0bCBvciB0aW1lb3V0IGlzIGxlc3MgdGhhbiB6ZXJvLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUmVhY2hhYmxlKE5ldHdvcmtJbnRlcmZhY2UgbmV0d29ya0ludGVyZmFjZSwgZmluYWwgaW50IHR0bCwgZmluYWwgaW50IHRpbWVvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0dGwgPCAwIHx8IHRpbWVvdXQgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ0dGwgPCAwIHx8IHRpbWVvdXQgPCAwIik7CisgICAgICAgIH0KKworICAgICAgICAvLyBUaGUgc2ltcGxlIGNhc2UuCisgICAgICAgIGlmIChuZXR3b3JrSW50ZXJmYWNlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBpc1JlYWNoYWJsZSh0aGlzLCBudWxsLCB0aW1lb3V0KTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRyeSBlYWNoIE5ldHdvcmtJbnRlcmZhY2UgaW4gcGFyYWxsZWwuCisgICAgICAgIC8vIFVzZSBhIHRocmVhZCBwb29sIEV4ZWN1dG9yPworICAgICAgICBMaXN0PEluZXRBZGRyZXNzPiBzb3VyY2VBZGRyZXNzZXMgPSBDb2xsZWN0aW9ucy5saXN0KG5ldHdvcmtJbnRlcmZhY2UuZ2V0SW5ldEFkZHJlc3NlcygpKTsKKyAgICAgICAgaWYgKHNvdXJjZUFkZHJlc3Nlcy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBJbmV0QWRkcmVzcyBkZXN0aW5hdGlvbkFkZHJlc3MgPSB0aGlzOworICAgICAgICBmaW5hbCBDb3VudERvd25MYXRjaCBsYXRjaCA9IG5ldyBDb3VudERvd25MYXRjaChzb3VyY2VBZGRyZXNzZXMuc2l6ZSgpKTsKKyAgICAgICAgZmluYWwgQXRvbWljQm9vbGVhbiBpc1JlYWNoYWJsZSA9IG5ldyBBdG9taWNCb29sZWFuKGZhbHNlKTsKKyAgICAgICAgZm9yIChmaW5hbCBJbmV0QWRkcmVzcyBzb3VyY2VBZGRyZXNzIDogc291cmNlQWRkcmVzc2VzKSB7CisgICAgICAgICAgICBuZXcgVGhyZWFkKCkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNSZWFjaGFibGUoZGVzdGluYXRpb25BZGRyZXNzLCBzb3VyY2VBZGRyZXNzLCB0aW1lb3V0KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzUmVhY2hhYmxlLnNldCh0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXYWtlIHRoZSBtYWluIHRocmVhZCBzbyBpdCBjYW4gcmV0dXJuIHN1Y2Nlc3Mgd2l0aG91dAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdhaXRpbmcgZm9yIGFueSBvdGhlciB0aHJlYWRzIHRvIHRpbWUgb3V0LgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChsYXRjaC5nZXRDb3VudCgpID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRjaC5jb3VudERvd24oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBsYXRjaC5jb3VudERvd24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9LnN0YXJ0KCk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxhdGNoLmF3YWl0KCk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuaW50ZXJydXB0KCk7IC8vIExlYXZlIHRoZSBpbnRlcnJ1cHRlZCBiaXQgc2V0LgorICAgICAgICB9CisgICAgICAgIHJldHVybiBpc1JlYWNoYWJsZS5nZXQoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNSZWFjaGFibGUoSW5ldEFkZHJlc3MgZGVzdGluYXRpb24sIEluZXRBZGRyZXNzIHNvdXJjZSwgaW50IHRpbWVvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRPRE86IHRyeSBJQ01QIGZpcnN0IChodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTIwMTA2KQorICAgICAgICBGaWxlRGVzY3JpcHRvciBmZCA9IElvQnJpZGdlLnNvY2tldCh0cnVlKTsKKyAgICAgICAgYm9vbGVhbiByZWFjaGVkID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoc291cmNlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBJb0JyaWRnZS5iaW5kKGZkLCBzb3VyY2UsIDApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgSW9CcmlkZ2UuY29ubmVjdChmZCwgZGVzdGluYXRpb24sIDcsIHRpbWVvdXQpOworICAgICAgICAgICAgcmVhY2hlZCA9IHRydWU7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGlmIChlLmdldENhdXNlKCkgaW5zdGFuY2VvZiBFcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgIC8vICJDb25uZWN0aW9uIHJlZnVzZWQiIG1lYW5zIHRoZSBJUCBhZGRyZXNzIHdhcyByZWFjaGFibGUuCisgICAgICAgICAgICAgICAgcmVhY2hlZCA9ICgoKEVycm5vRXhjZXB0aW9uKSBlLmdldENhdXNlKCkpLmVycm5vID09IEVDT05OUkVGVVNFRCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBJb0JyaWRnZS5jbG9zZVNvY2tldChmZCk7CisKKyAgICAgICAgcmV0dXJuIHJlYWNoZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgZ2V0QnlBZGRyZXNzKG51bGwsIGlwQWRkcmVzcyl9LiBIYW5keSBmb3IgYWRkcmVzc2VzIHdpdGgKKyAgICAgKiBubyBhc3NvY2lhdGVkIGhvc3RuYW1lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgSW5ldEFkZHJlc3MgZ2V0QnlBZGRyZXNzKGJ5dGVbXSBpcEFkZHJlc3MpIHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXRCeUFkZHJlc3MobnVsbCwgaXBBZGRyZXNzLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIHtAY29kZSBJbmV0QWRkcmVzc30gY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gbmV0d29yay1vcmRlcgorICAgICAqIGJ5dGVzIHtAY29kZSBpcEFkZHJlc3N9IGFuZCB7QGNvZGUgc2NvcGVJZH0uCisgICAgICoKKyAgICAgKiA8cD5Gb3IgYW4gSVB2NCBhZGRyZXNzLCB0aGUgYnl0ZSBhcnJheSBtdXN0IGJlIG9mIGxlbmd0aCA0LgorICAgICAqIEZvciBJUHY2LCB0aGUgYnl0ZSBhcnJheSBtdXN0IGJlIG9mIGxlbmd0aCAxNi4gQW55IG90aGVyIGxlbmd0aCB3aWxsIGNhdXNlIGFuIHtAY29kZQorICAgICAqIFVua25vd25Ib3N0RXhjZXB0aW9ufS4KKyAgICAgKgorICAgICAqIDxwPk5vIHJldmVyc2UgbG9va3VwIGlzIHBlcmZvcm1lZC4gVGhlIGdpdmVuIHtAY29kZSBob3N0TmFtZX0gKHdoaWNoIG1heSBiZSBudWxsKSBpcworICAgICAqIGFzc29jaWF0ZWQgd2l0aCB0aGUgbmV3IHtAY29kZSBJbmV0QWRkcmVzc30gd2l0aCBubyB2YWxpZGF0aW9uIGRvbmUuCisgICAgICoKKyAgICAgKiA8cD4oTm90ZSB0aGF0IG51bWVyaWMgYWRkcmVzc2VzIHN1Y2ggYXMge0Bjb2RlICIxMjcuMC4wLjEifSBhcmUgbmFtZXMgZm9yIHRoZQorICAgICAqIHB1cnBvc2VzIG9mIHRoaXMgQVBJLiBNb3N0IGNhbGxlcnMgcHJvYmFibHkgd2FudCB7QGxpbmsgI2dldEFsbEJ5TmFtZX0gaW5zdGVhZC4pCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFVua25vd25Ib3N0RXhjZXB0aW9uIGlmIHtAY29kZSBpcEFkZHJlc3N9IGlzIG51bGwgb3IgdGhlIHdyb25nIGxlbmd0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEluZXRBZGRyZXNzIGdldEJ5QWRkcmVzcyhTdHJpbmcgaG9zdE5hbWUsIGJ5dGVbXSBpcEFkZHJlc3MpIHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXRCeUFkZHJlc3MoaG9zdE5hbWUsIGlwQWRkcmVzcywgMCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgSW5ldEFkZHJlc3MgZ2V0QnlBZGRyZXNzKFN0cmluZyBob3N0TmFtZSwgYnl0ZVtdIGlwQWRkcmVzcywgaW50IHNjb3BlSWQpIHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpcEFkZHJlc3MgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVua25vd25Ib3N0RXhjZXB0aW9uKCJpcEFkZHJlc3MgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChpcEFkZHJlc3MubGVuZ3RoID09IDQpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgSW5ldDRBZGRyZXNzKGlwQWRkcmVzcy5jbG9uZSgpLCBob3N0TmFtZSk7CisgICAgICAgIH0gZWxzZSBpZiAoaXBBZGRyZXNzLmxlbmd0aCA9PSAxNikgeworICAgICAgICAgICAgLy8gRmlyc3QgY2hlY2sgdG8gc2VlIGlmIHRoZSBhZGRyZXNzIGlzIGFuIElQdjYtbWFwcGVkCisgICAgICAgICAgICAvLyBJUHY0IGFkZHJlc3MuIElmIGl0IGlzLCB0aGVuIHdlIGNhbiBtYWtlIGl0IGEgSVB2NAorICAgICAgICAgICAgLy8gYWRkcmVzcywgb3RoZXJ3aXNlLCB3ZSdsbCBjcmVhdGUgYW4gSVB2NiBhZGRyZXNzLgorICAgICAgICAgICAgaWYgKGlzSVB2NE1hcHBlZEFkZHJlc3MoaXBBZGRyZXNzKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSW5ldDRBZGRyZXNzKGlwdjRNYXBwZWRUb0lQdjQoaXBBZGRyZXNzKSwgaG9zdE5hbWUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEluZXQ2QWRkcmVzcyhpcEFkZHJlc3MuY2xvbmUoKSwgaG9zdE5hbWUsIHNjb3BlSWQpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgYmFkQWRkcmVzc0xlbmd0aChpcEFkZHJlc3MpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgVW5rbm93bkhvc3RFeGNlcHRpb24gYmFkQWRkcmVzc0xlbmd0aChieXRlW10gYnl0ZXMpIHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbmtub3duSG9zdEV4Y2VwdGlvbigiQWRkcmVzcyBpcyBuZWl0aGVyIDQgb3IgMTYgYnl0ZXM6ICIgKyBBcnJheXMudG9TdHJpbmcoYnl0ZXMpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzSVB2NE1hcHBlZEFkZHJlc3MoYnl0ZVtdIGlwQWRkcmVzcykgeworICAgICAgICAvLyBDaGVjayBpZiB0aGUgYWRkcmVzcyBtYXRjaGVzIDo6RkZGRjpkLmQuZC5kCisgICAgICAgIC8vIFRoZSBmaXJzdCAxMCBieXRlcyBhcmUgMC4gVGhlIG5leHQgdG8gYXJlIC0xIChGRikuCisgICAgICAgIC8vIFRoZSBsYXN0IDQgYnl0ZXMgYXJlIHZhcmllZC4KKyAgICAgICAgaWYgKGlwQWRkcmVzcyA9PSBudWxsIHx8IGlwQWRkcmVzcy5sZW5ndGggIT0gMTYpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChpcEFkZHJlc3NbaV0gIT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoaXBBZGRyZXNzWzEwXSAhPSAtMSB8fCBpcEFkZHJlc3NbMTFdICE9IC0xKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdIGlwdjRNYXBwZWRUb0lQdjQoYnl0ZVtdIG1hcHBlZEFkZHJlc3MpIHsKKyAgICAgICAgYnl0ZVtdIGlwdjRBZGRyZXNzID0gbmV3IGJ5dGVbNF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNDsgaSsrKSB7CisgICAgICAgICAgICBpcHY0QWRkcmVzc1tpXSA9IG1hcHBlZEFkZHJlc3NbMTIgKyBpXTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaXB2NEFkZHJlc3M7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0U3RyZWFtRmllbGRbXSBzZXJpYWxQZXJzaXN0ZW50RmllbGRzID0geworICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImFkZHJlc3MiLCBpbnQuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImZhbWlseSIsIGludC5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiaG9zdE5hbWUiLCBTdHJpbmcuY2xhc3MpLAorICAgIH07CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtLlB1dEZpZWxkIGZpZWxkcyA9IHN0cmVhbS5wdXRGaWVsZHMoKTsKKyAgICAgICAgaWYgKGlwYWRkcmVzcyA9PSBudWxsKSB7CisgICAgICAgICAgICBmaWVsZHMucHV0KCJhZGRyZXNzIiwgMCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmaWVsZHMucHV0KCJhZGRyZXNzIiwgTWVtb3J5LnBlZWtJbnQoaXBhZGRyZXNzLCAwLCBCeXRlT3JkZXIuQklHX0VORElBTikpOworICAgICAgICB9CisgICAgICAgIGZpZWxkcy5wdXQoImZhbWlseSIsIGZhbWlseSk7CisgICAgICAgIGZpZWxkcy5wdXQoImhvc3ROYW1lIiwgaG9zdE5hbWUpOworCisgICAgICAgIHN0cmVhbS53cml0ZUZpZWxkcygpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0uR2V0RmllbGQgZmllbGRzID0gc3RyZWFtLnJlYWRGaWVsZHMoKTsKKyAgICAgICAgaW50IGFkZHIgPSBmaWVsZHMuZ2V0KCJhZGRyZXNzIiwgMCk7CisgICAgICAgIGlwYWRkcmVzcyA9IG5ldyBieXRlWzRdOworICAgICAgICBNZW1vcnkucG9rZUludChpcGFkZHJlc3MsIDAsIGFkZHIsIEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICAgICAgaG9zdE5hbWUgPSAoU3RyaW5nKSBmaWVsZHMuZ2V0KCJob3N0TmFtZSIsIG51bGwpOworICAgICAgICBmYW1pbHkgPSBmaWVsZHMuZ2V0KCJmYW1pbHkiLCAyKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFRoZSBzcGVjIHJlcXVpcmVzIHRoYXQgaWYgd2UgZW5jb3VudGVyIGEgZ2VuZXJpYyBJbmV0QWRkcmVzcyBpbgorICAgICAqIHNlcmlhbGl6ZWQgZm9ybSB0aGVuIHdlIHNob3VsZCBpbnRlcnByZXQgaXQgYXMgYW4gSW5ldDRBZGRyZXNzLgorICAgICAqLworICAgIHByaXZhdGUgT2JqZWN0IHJlYWRSZXNvbHZlKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgSW5ldDRBZGRyZXNzKGlwYWRkcmVzcywgaG9zdE5hbWUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9JbmV0U29ja2V0QWRkcmVzcy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L0luZXRTb2NrZXRBZGRyZXNzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDFiNTMwMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9JbmV0U29ja2V0QWRkcmVzcy5qYXZhCkBAIC0wLDAgKzEsMjQxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIHNvY2tldCBlbmRwb2ludCBkZXNjcmliZWQgYnkgYSBJUCBhZGRyZXNzIGFuZCBhIHBvcnQKKyAqIG51bWJlci4gSXQgaXMgYSBjb25jcmV0ZSBpbXBsZW1lbnRhdGlvbiBvZiB7QGNvZGUgU29ja2V0QWRkcmVzc30gZm9yIElQLgorICovCitwdWJsaWMgY2xhc3MgSW5ldFNvY2tldEFkZHJlc3MgZXh0ZW5kcyBTb2NrZXRBZGRyZXNzIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDUwNzYwMDE0MDEyMzQ2MzEyMzdMOworCisgICAgLy8gRXhhY3RseSBvbmUgb2YgaG9zdG5hbWUgb3IgYWRkciBzaG91bGQgYmUgc2V0LgorICAgIHByaXZhdGUgZmluYWwgSW5ldEFkZHJlc3MgYWRkcjsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBob3N0bmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIGludCBwb3J0OworCisgICAgLyoqCisgICAgICogQGhpZGUgaW50ZXJuYWwgdXNlIG9ubHkKKyAgICAgKi8KKyAgICBwdWJsaWMgSW5ldFNvY2tldEFkZHJlc3MoKSB7CisgICAgICAgIC8vIFRoZXNlIHdpbGwgYmUgZmlsbGVkIGluIHRoZSBuYXRpdmUgaW1wbGVtZW50YXRpb24gb2YgcmVjdmZyb20uCisgICAgICAgIHRoaXMuYWRkciA9IG51bGw7CisgICAgICAgIHRoaXMuaG9zdG5hbWUgPSBudWxsOworICAgICAgICB0aGlzLnBvcnQgPSAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgc29ja2V0IGVuZHBvaW50IHdpdGggdGhlIGdpdmVuIHBvcnQgbnVtYmVyIHtAY29kZSBwb3J0fSBhbmQKKyAgICAgKiBubyBzcGVjaWZpZWQgYWRkcmVzcy4gVGhlIHJhbmdlIGZvciB2YWxpZCBwb3J0IG51bWJlcnMgaXMgYmV0d2VlbiAwIGFuZAorICAgICAqIDY1NTM1IGluY2x1c2l2ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwb3J0CisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIHBvcnQgbnVtYmVyIHRvIHdoaWNoIHRoaXMgc29ja2V0IGlzIGJvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBJbmV0U29ja2V0QWRkcmVzcyhpbnQgcG9ydCkgeworICAgICAgICB0aGlzKChJbmV0QWRkcmVzcykgbnVsbCwgcG9ydCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHNvY2tldCBlbmRwb2ludCB3aXRoIHRoZSBnaXZlbiBwb3J0IG51bWJlciB7QGNvZGUgcG9ydH0gYW5kCisgICAgICoge0Bjb2RlIGFkZHJlc3N9LiBUaGUgcmFuZ2UgZm9yIHZhbGlkIHBvcnQgbnVtYmVycyBpcyBiZXR3ZWVuIDAgYW5kIDY1NTM1CisgICAgICogaW5jbHVzaXZlLiBJZiB7QGNvZGUgYWRkcmVzc30gaXMge0Bjb2RlIG51bGx9IHRoaXMgc29ja2V0IGlzIGJvdW5kIHRvIHRoZQorICAgICAqIElQdjQgd2lsZGNhcmQgYWRkcmVzcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwb3J0CisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIHBvcnQgbnVtYmVyIHRvIHdoaWNoIHRoaXMgc29ja2V0IGlzIGJvdW5kLgorICAgICAqIEBwYXJhbSBhZGRyZXNzCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGFkZHJlc3MgdG8gd2hpY2ggdGhpcyBzb2NrZXQgaXMgYm91bmQuCisgICAgICovCisgICAgcHVibGljIEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzIGFkZHJlc3MsIGludCBwb3J0KSB7CisgICAgICAgIGlmIChwb3J0IDwgMCB8fCBwb3J0ID4gNjU1MzUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInBvcnQ9IiArIHBvcnQpOworICAgICAgICB9CisgICAgICAgIHRoaXMuYWRkciA9IChhZGRyZXNzID09IG51bGwpID8gSW5ldDRBZGRyZXNzLkFOWSA6IGFkZHJlc3M7CisgICAgICAgIHRoaXMuaG9zdG5hbWUgPSBudWxsOworICAgICAgICB0aGlzLnBvcnQgPSBwb3J0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBzb2NrZXQgZW5kcG9pbnQgd2l0aCB0aGUgZ2l2ZW4gcG9ydCBudW1iZXIge0Bjb2RlIHBvcnR9IGFuZCB0aGUKKyAgICAgKiBob3N0bmFtZSB7QGNvZGUgaG9zdH0uIFRoZSBob3N0bmFtZSBpcyB0cmllZCB0byBiZSByZXNvbHZlZCBhbmQgY2Fubm90IGJlCisgICAgICoge0Bjb2RlIG51bGx9LiBUaGUgcmFuZ2UgZm9yIHZhbGlkIHBvcnQgbnVtYmVycyBpcyBiZXR3ZWVuIDAgYW5kIDY1NTM1CisgICAgICogaW5jbHVzaXZlLgorICAgICAqCisgICAgICogQHBhcmFtIHBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgcG9ydCBudW1iZXIgdG8gd2hpY2ggdGhpcyBzb2NrZXQgaXMgYm91bmQuCisgICAgICogQHBhcmFtIGhvc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgaG9zdG5hbWUgdG8gd2hpY2ggdGhpcyBzb2NrZXQgaXMgYm91bmQuCisgICAgICovCisgICAgcHVibGljIEluZXRTb2NrZXRBZGRyZXNzKFN0cmluZyBob3N0LCBpbnQgcG9ydCkgeworICAgICAgICB0aGlzKGhvc3QsIHBvcnQsIHRydWUpOworICAgIH0KKworICAgIC8qCisgICAgICogSW50ZXJuYWwgY29uc3RydWN0b3IgZm9yIEluZXRTb2NrZXRBZGRyZXNzKFN0cmluZywgaW50KSBhbmQKKyAgICAgKiBjcmVhdGVVbnJlc29sdmVkKFN0cmluZywgaW50KTsKKyAgICAgKi8KKyAgICBJbmV0U29ja2V0QWRkcmVzcyhTdHJpbmcgaG9zdG5hbWUsIGludCBwb3J0LCBib29sZWFuIG5lZWRSZXNvbHZlZCkgeworICAgICAgICBpZiAoaG9zdG5hbWUgPT0gbnVsbCB8fCBwb3J0IDwgMCB8fCBwb3J0ID4gNjU1MzUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImhvc3Q9IiArIGhvc3RuYW1lICsgIiwgcG9ydD0iICsgcG9ydCk7CisgICAgICAgIH0KKworICAgICAgICBJbmV0QWRkcmVzcyBhZGRyID0gbnVsbDsKKyAgICAgICAgaWYgKG5lZWRSZXNvbHZlZCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhZGRyID0gSW5ldEFkZHJlc3MuZ2V0QnlOYW1lKGhvc3RuYW1lKTsKKyAgICAgICAgICAgICAgICBob3N0bmFtZSA9IG51bGw7CisgICAgICAgICAgICB9IGNhdGNoIChVbmtub3duSG9zdEV4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5hZGRyID0gYWRkcjsKKyAgICAgICAgdGhpcy5ob3N0bmFtZSA9IGhvc3RuYW1lOworICAgICAgICB0aGlzLnBvcnQgPSBwb3J0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4ge0Bjb2RlIEluZXRTb2NrZXRBZGRyZXNzfSB3aXRob3V0IHRyeWluZyB0byByZXNvbHZlIHRoZQorICAgICAqIGhvc3RuYW1lIGludG8gYW4ge0Bjb2RlIEluZXRBZGRyZXNzfS4gVGhlIGFkZHJlc3MgZmllbGQgaXMgbWFya2VkIGFzCisgICAgICogdW5yZXNvbHZlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3N0CisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGhvc3RuYW1lIHRvIHdoaWNoIHRoaXMgc29ja2V0IGlzIGJvdW5kLgorICAgICAqIEBwYXJhbSBwb3J0CisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIHBvcnQgbnVtYmVyIHRvIHdoaWNoIHRoaXMgc29ja2V0IGlzIGJvdW5kLgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgSW5ldFNvY2tldEFkZHJlc3MgaW5zdGFuY2UuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaG9zdG5hbWUge0Bjb2RlIGhvc3R9IGlzIHtAY29kZSBudWxsfSBvciB0aGUgcG9ydCBpcworICAgICAqICAgICAgICAgICAgIG5vdCBpbiB0aGUgcmFuZ2UgYmV0d2VlbiAwIGFuZCA2NTUzNS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEluZXRTb2NrZXRBZGRyZXNzIGNyZWF0ZVVucmVzb2x2ZWQoU3RyaW5nIGhvc3QsIGludCBwb3J0KSB7CisgICAgICAgIHJldHVybiBuZXcgSW5ldFNvY2tldEFkZHJlc3MoaG9zdCwgcG9ydCwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHBvcnQgbnVtYmVyIG9mIHRoaXMgc29ja2V0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc29ja2V0IGVuZHBvaW50IHBvcnQgbnVtYmVyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UG9ydCgpIHsKKyAgICAgICAgcmV0dXJuIHBvcnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYWRkcmVzcyBvZiB0aGlzIHNvY2tldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNvY2tldCBlbmRwb2ludCBhZGRyZXNzLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBJbmV0QWRkcmVzcyBnZXRBZGRyZXNzKCkgeworICAgICAgICByZXR1cm4gYWRkcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBob3N0bmFtZSwgZG9pbmcgYSByZXZlcnNlIGxvb2t1cCBvbiB0aGUge0Bjb2RlIEluZXRBZGRyZXNzfSBpZiBubworICAgICAqIGhvc3RuYW1lIHN0cmluZyB3YXMgcHJvdmlkZWQgYXQgY29uc3RydWN0aW9uIHRpbWUuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRIb3N0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIChhZGRyICE9IG51bGwpID8gYWRkci5nZXRIb3N0TmFtZSgpIDogaG9zdG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaG9zdG5hbWUgaWYga25vd24sIG9yIHRoZSByZXN1bHQgb2Yge0Bjb2RlIEluZXRBZGRyZXNzLmdldEhvc3RBZGRyZXNzfS4KKyAgICAgKiBVbmxpa2Uge0BsaW5rICNnZXRIb3N0TmFtZX0sIHRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIgY2F1c2UgYSBETlMgbG9va3VwLgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAaGlkZSAxLjcgLSByZW1lbWJlciB0byBhZGQgYSBsaW5rIGluIHRoZSBnZXRIb3N0TmFtZSBkb2N1bWVudGF0aW9uIQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0SG9zdFN0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIChob3N0bmFtZSAhPSBudWxsKSA/IGhvc3RuYW1lIDogYWRkci5nZXRIb3N0QWRkcmVzcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIHNvY2tldCBhZGRyZXNzIGlzIHVucmVzb2x2ZWQgb3Igbm90LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBzb2NrZXQgYWRkcmVzcyBpcyB1bnJlc29sdmVkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNVbnJlc29sdmVkKCkgeworICAgICAgICByZXR1cm4gYWRkciA9PSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBzb2NrZXQgaW5jbHVkZWQgdGhlIGFkZHJlc3MgYW5kIHRoZQorICAgICAqIHBvcnQgbnVtYmVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYWRkcmVzcyBhbmQgcG9ydCBudW1iZXIgYXMgYSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiAoKGFkZHIgIT0gbnVsbCkgPyBhZGRyLnRvU3RyaW5nKCkgOiBob3N0bmFtZSkgKyAiOiIgKyBwb3J0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHR3byBzb2NrZXQgZW5kcG9pbnRzIGFuZCByZXR1cm5zIHRydWUgaWYgdGhleSBhcmUgZXF1YWwuIFR3bworICAgICAqIHNvY2tldCBlbmRwb2ludHMgYXJlIGVxdWFsIGlmIHRoZSBJUCBhZGRyZXNzIG9yIHRoZSBob3N0bmFtZSBvZiBib3RoIGFyZQorICAgICAqIGVxdWFsIGFuZCB0aGV5IGFyZSBib3VuZCB0byB0aGUgc2FtZSBwb3J0LgorICAgICAqCisgICAgICogQHBhcmFtIHNvY2tldEFkZHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYmUgdGVzdGVkIGZvciBlcXVhbGl0eS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHNvY2tldCBhbmQgdGhlIGdpdmVuIHNvY2tldCBvYmplY3Qge0Bjb2RlCisgICAgICogICAgICAgICBzb2NrZXRBZGRyfSBhcmUgZXF1YWwsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGVxdWFscyhPYmplY3Qgc29ja2V0QWRkcikgeworICAgICAgICBpZiAodGhpcyA9PSBzb2NrZXRBZGRyKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShzb2NrZXRBZGRyIGluc3RhbmNlb2YgSW5ldFNvY2tldEFkZHJlc3MpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgaVNvY2tBZGRyID0gKEluZXRTb2NrZXRBZGRyZXNzKSBzb2NrZXRBZGRyOworCisgICAgICAgIC8vIGNoZWNrIHRoZSBwb3J0cyBhcyB3ZSBhbHdheXMgbmVlZCB0byBkbyB0aGlzCisgICAgICAgIGlmIChwb3J0ICE9IGlTb2NrQWRkci5wb3J0KSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICAvLyB3ZSBvbmx5IHVzZSB0aGUgaG9zdG5hbWVzIGluIHRoZSBjb21wYXJpc29uIGlmIHRoZSBhZGRycyB3ZXJlIG5vdAorICAgICAgICAvLyByZXNvbHZlZAorICAgICAgICBpZiAoKGFkZHIgPT0gbnVsbCkgJiYgKGlTb2NrQWRkci5hZGRyID09IG51bGwpKSB7CisgICAgICAgICAgICByZXR1cm4gaG9zdG5hbWUuZXF1YWxzKGlTb2NrQWRkci5ob3N0bmFtZSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBhZGRycyB3ZXJlIHJlc29sdmVkIHNvIHVzZSB0aGVtIGZvciB0aGUgY29tcGFyaXNvbgorICAgICAgICBpZiAoYWRkciA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBpZiB3ZSBhcmUgaGVyZSB3ZSBrbm93IGlTb2NrQWRkciBpcyBub3QgbnVsbCBzbyBqdXN0IHJldHVybgorICAgICAgICAgICAgLy8gZmFsc2UKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYWRkci5lcXVhbHMoaVNvY2tBZGRyLmFkZHIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGlmIChhZGRyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBob3N0bmFtZS5oYXNoQ29kZSgpICsgcG9ydDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYWRkci5oYXNoQ29kZSgpICsgcG9ydDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIHN0cmVhbS5kZWZhdWx0UmVhZE9iamVjdCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9JbnRlcmZhY2VBZGRyZXNzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvSW50ZXJmYWNlQWRkcmVzcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYxMmVlYjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvSW50ZXJmYWNlQWRkcmVzcy5qYXZhCkBAIC0wLDAgKzEsMTMxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworLyoqCisgKiBJZGVudGlmaWVzIG9uZSBvZiBhIG5ldHdvcmsgaW50ZXJmYWNlJ3MgYWRkcmVzc2VzLgorICogVGhlc2UgYXJlIHBhc3NlZCBiYWNrIGZyb20gdGhlIEpOSSBiZWhpbmQgTmV0d29ya0ludGVyZmFjZS5nZXROZXR3b3JrSW50ZXJmYWNlcy4KKyAqIE11bHRpcGxlIGFkZHJlc3NlcyBmb3IgdGhlIHNhbWUgaW50ZXJmYWNlIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgb24gdGhlIEphdmEgc2lkZS4KKyAqCisgKiBAc2luY2UgMS42CisgKi8KK3B1YmxpYyBjbGFzcyBJbnRlcmZhY2VBZGRyZXNzIHsKKyAgICAvKioKKyAgICAgKiBBbiBJUHY0IG9yIElQdjYgYWRkcmVzcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIEluZXRBZGRyZXNzIGFkZHJlc3M7CisKKyAgICAvKioKKyAgICAgKiBUaGUgSVB2NCBicm9hZGNhc3QgYWRkcmVzcywgb3IgbnVsbCBmb3IgSVB2Ni4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIEluZXRBZGRyZXNzIGJyb2FkY2FzdEFkZHJlc3M7CisKKyAgICBwcml2YXRlIGZpbmFsIHNob3J0IHByZWZpeExlbmd0aDsKKworICAgIC8qKgorICAgICAqIEZvciBJUHY0LgorICAgICAqLworICAgIEludGVyZmFjZUFkZHJlc3MoSW5ldDRBZGRyZXNzIGFkZHJlc3MsIEluZXQ0QWRkcmVzcyBicm9hZGNhc3RBZGRyZXNzLCBJbmV0NEFkZHJlc3MgbWFzaykgeworICAgICAgICB0aGlzLmFkZHJlc3MgPSBhZGRyZXNzOworICAgICAgICB0aGlzLmJyb2FkY2FzdEFkZHJlc3MgPSBicm9hZGNhc3RBZGRyZXNzOworICAgICAgICB0aGlzLnByZWZpeExlbmd0aCA9IGNvdW50UHJlZml4TGVuZ3RoKG1hc2spOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZvciBJUHY2LgorICAgICAqLworICAgIEludGVyZmFjZUFkZHJlc3MoSW5ldDZBZGRyZXNzIGFkZHJlc3MsIHNob3J0IHByZWZpeExlbmd0aCkgeworICAgICAgICB0aGlzLmFkZHJlc3MgPSBhZGRyZXNzOworICAgICAgICB0aGlzLmJyb2FkY2FzdEFkZHJlc3MgPSBudWxsOworICAgICAgICB0aGlzLnByZWZpeExlbmd0aCA9IHByZWZpeExlbmd0aDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBzaG9ydCBjb3VudFByZWZpeExlbmd0aChJbmV0NEFkZHJlc3MgbWFzaykgeworICAgICAgICBzaG9ydCBjb3VudCA9IDA7CisgICAgICAgIGZvciAoYnl0ZSBiIDogbWFzay5pcGFkZHJlc3MpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgODsgKytpKSB7CisgICAgICAgICAgICAgICAgaWYgKChiICYgKDEgPDwgaSkpICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgKytjb3VudDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvdW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHdoZXRoZXIgdGhpcyBvYmplY3QgaXMgZXF1YWwgdG8gYW5vdGhlciBvbmUuIFJldHVybnMgdHJ1ZSBpZgorICAgICAqIHRoZSBhZGRyZXNzLCBicm9hZGNhc3QgYWRkcmVzcyBhbmQgcHJlZml4IGxlbmd0aCBhcmUgYWxsIGVxdWFsLgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiB0aGUgb2JqZWN0IHRvIGJlIGNvbXBhcmVkLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiAnb2JqJyBpcyBlcXVhbCB0byB0aGlzIEludGVyZmFjZUFkZHJlc3MsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAob2JqID09IHRoaXMpeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgSW50ZXJmYWNlQWRkcmVzcykpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBJbnRlcmZhY2VBZGRyZXNzIHJocyA9IChJbnRlcmZhY2VBZGRyZXNzKSBvYmo7CisgICAgICAgIHJldHVybiAoKGFkZHJlc3MgPT0gbnVsbCkgPyByaHMuYWRkcmVzcyA9PSBudWxsIDogYWRkcmVzcy5lcXVhbHMocmhzLmFkZHJlc3MpKSAmJgorICAgICAgICAgICAgICAgIChyaHMucHJlZml4TGVuZ3RoID09IHByZWZpeExlbmd0aCkgJiYKKyAgICAgICAgICAgICAgICAoKGJyb2FkY2FzdEFkZHJlc3MgPT0gbnVsbCkgPyByaHMuYnJvYWRjYXN0QWRkcmVzcyA9PSBudWxsIDogYnJvYWRjYXN0QWRkcmVzcy5lcXVhbHMocmhzLmJyb2FkY2FzdEFkZHJlc3MpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBpbnQgaGFzaENvZGUgPSBhZGRyZXNzID09IG51bGwgPyAwIDogLWFkZHJlc3MuaGFzaENvZGUoKTsKKyAgICAgICAgaGFzaENvZGUgKz0gYnJvYWRjYXN0QWRkcmVzcyA9PSBudWxsID8gMCA6IGJyb2FkY2FzdEFkZHJlc3MuaGFzaENvZGUoKTsKKyAgICAgICAgaGFzaENvZGUgKz0gcHJlZml4TGVuZ3RoOworICAgICAgICByZXR1cm4gaGFzaENvZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBmb3IgdGhpcyBpbnRlcmZhY2UgYWRkcmVzcy4KKyAgICAgKiBUaGUgc3RyaW5nIGlzIG9mIHRoZSBmb3JtOiBJbmV0QWRkcmVzcyAvIHByZWZpeCBsZW5ndGggWyBicm9hZGNhc3QgYWRkcmVzcyBdLgorICAgICAqCisgICAgICogQHJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGludGVyZmFjZSBhZGRyZXNzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBhZGRyZXNzICsgIi8iICsgcHJlZml4TGVuZ3RoICsgIiBbIiArIGJyb2FkY2FzdEFkZHJlc3MgKyAiXSI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgSW5ldEFkZHJlc3MgZm9yIHRoaXMgYWRkcmVzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5ldEFkZHJlc3MgZ2V0QWRkcmVzcygpIHsKKyAgICAgICAgcmV0dXJuIGFkZHJlc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3VibmV0LWRpcmVjdGVkIGJyb2FkY2FzdCBhZGRyZXNzIGlmIHRoaXMgaXMgYW4gSVB2NCBpbnRlcmZhY2UsIG51bGwgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBJbmV0QWRkcmVzcyBnZXRCcm9hZGNhc3QoKSB7CisgICAgICAgIHJldHVybiBicm9hZGNhc3RBZGRyZXNzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5ldHdvcmsgcHJlZml4IGxlbmd0aCBpbiBiaXRzLgorICAgICAqIChJbiBJUHY0IHBhcmxhbmNlLCB0aGlzIGlzIGtub3duIGFzIHRoZSBzdWJuZXQgbWFzaywKKyAgICAgKiBidXQgdGhpcyBtZXRob2QgYXBwbGllcyB0byBJUHY2IGFkZHJlc3NlcyB0b28uKQorICAgICAqLworICAgIHB1YmxpYyBzaG9ydCBnZXROZXR3b3JrUHJlZml4TGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gcHJlZml4TGVuZ3RoOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9KYXJVUkxDb25uZWN0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvSmFyVVJMQ29ubmVjdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRiODQ4OTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvSmFyVVJMQ29ubmVjdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTkyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLmphci5BdHRyaWJ1dGVzOworaW1wb3J0IGphdmEudXRpbC5qYXIuSmFyRW50cnk7CitpbXBvcnQgamF2YS51dGlsLmphci5KYXJGaWxlOworaW1wb3J0IGphdmEudXRpbC5qYXIuTWFuaWZlc3Q7CisKKy8qKgorICogVGhpcyBjbGFzcyBlc3RhYmxpc2hlcyBhIGNvbm5lY3Rpb24gdG8gYSB7QGNvZGUgamFyOn0gVVJMIHVzaW5nIHRoZSB7QGNvZGUKKyAqIEpBUn0gcHJvdG9jb2wuIEEge0Bjb2RlIEphclVSTENvbm5lY3Rpb259IGluc3RhbmNlIGNhbiByZWZlciB0byBlaXRoZXIgYSBKQVIKKyAqIGFyY2hpdmUgZmlsZSBvciB0byBhbiBlbnRyeSBvZiBzdWNoIGEgZmlsZS4ge0Bjb2RlIGphcjp9IFVSTHMgYXJlIHNwZWNpZmllZAorICogYXMgZm9sbG93czogPGk+amFyOnthcmNoaXZlLXVybH0hL3tlbnRyeX08L2k+IHdoZXJlICIhLyIgaXMgY2FsbGVkIGEKKyAqIHNlcGFyYXRvci4gVGhpcyBzZXBhcmF0b3IgaXMgaW1wb3J0YW50IHRvIGRldGVybWluZSBpZiBhbiBhcmNoaXZlIG9yIGFuIGVudHJ5CisgKiBvZiBhbiBhcmNoaXZlIGlzIHJlZmVycmVkLgorICogPHA+CisgKiBFeGFtcGxlczoKKyAqIDxsaT5BcmNoaXZlOiB7QGNvZGUgamFyOmh0dHA6Ly93d3cuZXhhbXBsZS5jb20vYXBwbGV0cy9hcmNoaXZlLmphciEvfTwvbGk+CisgKiA8bGk+RmlsZSBFbnRyeToge0Bjb2RlCisgKiBqYXI6aHR0cDovL3d3dy5leGFtcGxlLmNvbS9hcHBsZXRzL2FyY2hpdmUuamFyIS90ZXN0LmNsYXNzfTwvbGk+CisgKiA8bGk+RGlyZWN0b3J5IEVudHJ5OiB7QGNvZGUKKyAqIGphcjpodHRwOi8vd3d3LmV4YW1wbGUuY29tL2FwcGxldHMvYXJjaGl2ZS5qYXIhL2FwcGxldHMvfTwvbGk+CisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBKYXJVUkxDb25uZWN0aW9uIGV4dGVuZHMgVVJMQ29ubmVjdGlvbiB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbG9jYXRpb24gcGFydCBvZiB0aGUgcmVwcmVzZW50ZWQgVVJMLgorICAgICAqLworICAgIHByb3RlY3RlZCBVUkxDb25uZWN0aW9uIGphckZpbGVVUkxDb25uZWN0aW9uOworCisgICAgcHJpdmF0ZSBTdHJpbmcgZW50cnlOYW1lOworCisgICAgcHJpdmF0ZSBVUkwgZmlsZVVSTDsKKworICAgIC8vIHRoZSBmaWxlIGNvbXBvbmVudCBvZiB0aGUgVVJMCisgICAgcHJpdmF0ZSBTdHJpbmcgZmlsZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIEphclVSTENvbm5lY3Rpb259IHRoYXQgcmVmZXJzIHRvIHRoZQorICAgICAqIHNwZWNpZmllZCBVUkwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJsCisgICAgICogICAgICAgICAgICB0aGUgVVJMIHRoYXQgY29udGFpbnMgdGhlIGxvY2F0aW9uIHRvIGNvbm5lY3QgdG8uCisgICAgICogQHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBpbnZhbGlkIFVSTCBoYXMgYmVlbiBlbnRlcmVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBKYXJVUkxDb25uZWN0aW9uKFVSTCB1cmwpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgICAgICBzdXBlcih1cmwpOworICAgICAgICBmaWxlID0gdXJsLmdldEZpbGUoKTsKKyAgICAgICAgaW50IHNlcElkeDsKKyAgICAgICAgaWYgKChzZXBJZHggPSBmaWxlLmluZGV4T2YoIiEvIikpIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSTEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGZpbGVVUkwgPSBuZXcgVVJMKHVybC5nZXRGaWxlKCkuc3Vic3RyaW5nKDAsc2VwSWR4KSk7CisgICAgICAgIHNlcElkeCArPSAyOworICAgICAgICBpZiAoZmlsZS5sZW5ndGgoKSA9PSBzZXBJZHgpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBlbnRyeU5hbWUgPSBmaWxlLnN1YnN0cmluZyhzZXBJZHgsIGZpbGUubGVuZ3RoKCkpOworICAgICAgICBpZiAodXJsLmdldFJlZigpICE9IG51bGwpIHsKKyAgICAgICAgICAgIGVudHJ5TmFtZSArPSAiIyIgKyB1cmwuZ2V0UmVmKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFsbCBhdHRyaWJ1dGVzIG9mIHRoZSB7QGNvZGUgSmFyRW50cnl9IHJlZmVyZW5jZWQgYnkgdGhpcyB7QGNvZGUKKyAgICAgKiBKYXJVUkxDb25uZWN0aW9ufS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIHJlZmVyZW5jZWQge0Bjb2RlIEphckVudHJ5fS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBvY2N1cnMgd2hpbGUgcmV0cmlldmluZyB0aGUKKyAgICAgKiAgICAgICAgICAgICAgICBKQVItZW50cmllcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXR0cmlidXRlcyBnZXRBdHRyaWJ1dGVzKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24geworICAgICAgICBKYXJFbnRyeSBqRW50cnkgPSBnZXRKYXJFbnRyeSgpOworICAgICAgICByZXR1cm4gKGpFbnRyeSA9PSBudWxsKSA/IG51bGwgOiBqRW50cnkuZ2V0QXR0cmlidXRlcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYWxsIGNlcnRpZmljYXRlcyBvZiB0aGUge0Bjb2RlIEphckVudHJ5fSByZWZlcmVuY2VkIGJ5IHRoaXMKKyAgICAgKiB7QGNvZGUgSmFyVVJMQ29ubmVjdGlvbn0gaW5zdGFuY2UuIFRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIHtAY29kZSBudWxsfQorICAgICAqIHVudGlsIHRoZSB7QGNvZGUgSW5wdXRTdHJlYW19IGhhcyBiZWVuIGNvbXBsZXRlbHkgdmVyaWZpZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjZXJ0aWZpY2F0ZXMgb2YgdGhlIHtAY29kZSBKYXJFbnRyeX0gYXMgYW4gYXJyYXkuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGFuIEkvTyBleGNlcHRpb24gb2NjdXJzIHdoaWxlIGdldHRpbmcgdGhlCisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIEphckVudHJ5fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVbXSBnZXRDZXJ0aWZpY2F0ZXMoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CisgICAgICAgIEphckVudHJ5IGpFbnRyeSA9IGdldEphckVudHJ5KCk7CisgICAgICAgIGlmIChqRW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gakVudHJ5LmdldENlcnRpZmljYXRlcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWUgb2YgdGhlIGVudHJ5IHJlZmVyZW5jZWQgYnkgdGhpcyB7QGNvZGUgSmFyVVJMQ29ubmVjdGlvbn0uCisgICAgICogVGhlIHJldHVybiB2YWx1ZSB3aWxsIGJlIHtAY29kZSBudWxsfSBpZiB0aGlzIGluc3RhbmNlIHJlZmVycyB0byBhIEpBUgorICAgICAqIGZpbGUgcmF0aGVyIHRoYW4gYW4gSkFSIGZpbGUgZW50cnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgSmFyRW50cnl9IG5hbWUgdGhpcyBpbnN0YW5jZSByZWZlcnMgdG8uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRFbnRyeU5hbWUoKSB7CisgICAgICAgIHJldHVybiBlbnRyeU5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUge0Bjb2RlIEphckVudHJ5fSBvYmplY3Qgb2YgdGhlIGVudHJ5IHJlZmVyZW5jZWQgYnkgdGhpcyB7QGNvZGUKKyAgICAgKiBKYXJVUkxDb25uZWN0aW9ufS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJlZmVyZW5jZWQge0Bjb2RlIEphckVudHJ5fSBvYmplY3Qgb3Ige0Bjb2RlIG51bGx9IGlmIG5vCisgICAgICogICAgICAgICBlbnRyeSBuYW1lIGlzIHNwZWNpZmllZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGdldHRpbmcgdGhlIGZpbGUgb3IgZmlsZS1lbnRyeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSmFyRW50cnkgZ2V0SmFyRW50cnkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIWNvbm5lY3RlZCkgeworICAgICAgICAgICAgY29ubmVjdCgpOworICAgICAgICB9CisgICAgICAgIGlmIChlbnRyeU5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgLy8gVGhlIGVudHJ5IG11c3QgZXhpc3Qgc2luY2UgdGhlIGNvbm5lY3Qgc3VjY2VlZGVkCisgICAgICAgIHJldHVybiBnZXRKYXJGaWxlKCkuZ2V0SmFyRW50cnkoZW50cnlOYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtYW5pZmVzdCBmaWxlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEpBUi1VUkwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtYW5pZmVzdCBvZiB0aGUgcmVmZXJlbmNlZCBKQVItZmlsZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGdldHRpbmcgdGhlIG1hbmlmZXN0IGZpbGUuCisgICAgICovCisgICAgcHVibGljIE1hbmlmZXN0IGdldE1hbmlmZXN0KCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gKE1hbmlmZXN0KWdldEphckZpbGUoKS5nZXRNYW5pZmVzdCgpLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUge0Bjb2RlIEphckZpbGV9IG9iamVjdCByZWZlcmVuY2VkIGJ5IHRoaXMge0Bjb2RlCisgICAgICogSmFyVVJMQ29ubmVjdGlvbn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZWZlcmVuY2VkIEphckZpbGUgb2JqZWN0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBhbiBJL08gZXhjZXB0aW9uIG9jY3VycyB3aGlsZSByZXRyaWV2aW5nIHRoZSBKQVItZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgSmFyRmlsZSBnZXRKYXJGaWxlKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBVUkwgdG8gdGhlIEpBUi1maWxlIHJlZmVyZW5jZWQgYnkgdGhpcyB7QGNvZGUgSmFyVVJMQ29ubmVjdGlvbn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBVUkwgdG8gdGhlIEpBUi1maWxlIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSB3YXMgYW4gZXJyb3IKKyAgICAgKiAgICAgICAgIHJldHJpZXZpbmcgdGhlIFVSTC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMIGdldEphckZpbGVVUkwoKSB7CisgICAgICAgIHJldHVybiBmaWxlVVJMOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYWxsIGF0dHJpYnV0ZXMgb2YgdGhlIG1hbmlmZXN0IGZpbGUgcmVmZXJlbmNlZCBieSB0aGlzIHtAY29kZQorICAgICAqIEphclVSTENvbm5lY3Rpb259LiBJZiB0aGlzIGluc3RhbmNlIHJlZmVycyB0byBhIEpBUi1maWxlIHJhdGhlciB0aGFuIGEKKyAgICAgKiBKQVItZmlsZSBlbnRyeSwge0Bjb2RlIG51bGx9IHdpbGwgYmUgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBtYW5pZmVzdCBmaWxlIG9yIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW4gSS9PIGV4Y2VwdGlvbiBvY2N1cnMgd2hpbGUgcmV0cmlldmluZyB0aGUge0Bjb2RlCisgICAgICogICAgICAgICAgICAgICAgSmFyRmlsZX0uCisgICAgICovCisgICAgcHVibGljIEF0dHJpYnV0ZXMgZ2V0TWFpbkF0dHJpYnV0ZXMoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CisgICAgICAgIE1hbmlmZXN0IG0gPSBnZXRKYXJGaWxlKCkuZ2V0TWFuaWZlc3QoKTsKKyAgICAgICAgcmV0dXJuIChtID09IG51bGwpID8gbnVsbCA6IG0uZ2V0TWFpbkF0dHJpYnV0ZXMoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvTWFsZm9ybWVkVVJMRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvTWFsZm9ybWVkVVJMRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzZiODJjNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9NYWxmb3JtZWRVUkxFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDUyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBUaGlzIGV4Y2VwdGlvbiBpcyB0aHJvd24gd2hlbiBhIHByb2dyYW0gYXR0ZW1wdHMgdG8gY3JlYXRlIGFuIFVSTCBmcm9tIGFuCisgKiBpbmNvcnJlY3Qgc3BlY2lmaWNhdGlvbi4KKyAqCisgKiBAc2VlIFVSTAorICovCitwdWJsaWMgY2xhc3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTE4Mjc4NzUyMjIwMDQxNTg2Nkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBNYWxmb3JtZWRVUkxFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSB3aXRoIHRoZSBnaXZlbiBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWFsZm9ybWVkVVJMRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugd2l0aCBnaXZlbiBkZXRhaWwgbWVzc2FnZSBhbmQgY2F1c2UuCisgICAgICogQGhpZGUgaW50ZXJuYWwgdXNlIG9ubHkKKyAgICAgKi8KKyAgICBwdWJsaWMgTWFsZm9ybWVkVVJMRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSwgY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9NdWx0aWNhc3RTb2NrZXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9NdWx0aWNhc3RTb2NrZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40OThhMTMyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L011bHRpY2FzdFNvY2tldC5qYXZhCkBAIC0wLDAgKzEsMzYyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgbGliY29yZS5pby5Jb1V0aWxzOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIG11bHRpY2FzdCBzb2NrZXQgZm9yIHNlbmRpbmcgYW5kIHJlY2VpdmluZyBJUAorICogbXVsdGljYXN0IGRhdGFncmFtIHBhY2tldHMuCisgKgorICogQHNlZSBEYXRhZ3JhbVNvY2tldAorICovCitwdWJsaWMgY2xhc3MgTXVsdGljYXN0U29ja2V0IGV4dGVuZHMgRGF0YWdyYW1Tb2NrZXQgeworICAgIC8qKgorICAgICAqIFN0b3JlcyB0aGUgYWRkcmVzcyBzdXBwbGllZCB0byBzZXRJbnRlcmZhY2Ugc28gd2UgY2FuIHJldHVybiBpdCBmcm9tIGdldEludGVyZmFjZS4gVGhlCisgICAgICogdHJhbnNsYXRpb24gdG8gYW4gaW50ZXJmYWNlIGluZGV4IGlzIGxvc3N5IGJlY2F1c2UgYW4gaW50ZXJmYWNlIGNhbiBoYXZlIG11bHRpcGxlIGFkZHJlc3Nlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIEluZXRBZGRyZXNzIHNldEFkZHJlc3M7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbXVsdGljYXN0IHNvY2tldCwgYm91bmQgdG8gYW55IGF2YWlsYWJsZSBwb3J0IG9uIHRoZQorICAgICAqIGxvY2FsIGhvc3QuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTXVsdGljYXN0U29ja2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc2V0UmV1c2VBZGRyZXNzKHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBtdWx0aWNhc3Qgc29ja2V0LCBib3VuZCB0byB0aGUgc3BlY2lmaWVkIHtAY29kZSBwb3J0fSBvbiB0aGUKKyAgICAgKiBsb2NhbCBob3N0LgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIE11bHRpY2FzdFNvY2tldChpbnQgcG9ydCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIocG9ydCk7CisgICAgICAgIHNldFJldXNlQWRkcmVzcyh0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIE11bHRpY2FzdFNvY2tldH0gYm91bmQgdG8gdGhlIGFkZHJlc3MgYW5kIHBvcnQgc3BlY2lmaWVkIGJ5CisgICAgICoge0Bjb2RlIGxvY2FsQWRkcmVzc30sIG9yIGFuIHVuYm91bmQge0Bjb2RlIE11bHRpY2FzdFNvY2tldH0gaWYge0Bjb2RlIGxvY2FsQWRkcmVzcyA9PSBudWxsfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBsb2NhbEFkZHJlc3N9IGlzIG5vdCBzdXBwb3J0ZWQgKGJlY2F1c2UgaXQncyBub3QKKyAgICAgKiBhbiB7QGNvZGUgSW5ldFNvY2tldEFkZHJlc3N9LCBzYXkpLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBNdWx0aWNhc3RTb2NrZXQoU29ja2V0QWRkcmVzcyBsb2NhbEFkZHJlc3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKGxvY2FsQWRkcmVzcyk7CisgICAgICAgIHNldFJldXNlQWRkcmVzcyh0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFkZHJlc3Mgb2YgdGhlIG91dGdvaW5nIG5ldHdvcmsgaW50ZXJmYWNlIHVzZWQgYnkgdGhpcyBzb2NrZXQuIFRvIGF2b2lkCisgICAgICogaW5oZXJlbnQgdW5wcmVkaWN0YWJpbGl0eSwgbmV3IGNvZGUgc2hvdWxkIHVzZSB7QGxpbmsgI2dldE5ldHdvcmtJbnRlcmZhY2V9IGluc3RlYWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIEluZXRBZGRyZXNzIGdldEludGVyZmFjZSgpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgaWYgKHNldEFkZHJlc3MgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHNldEFkZHJlc3M7CisgICAgICAgIH0KKyAgICAgICAgSW5ldEFkZHJlc3MgaXB2WGFkZHJlc3MgPSAoSW5ldEFkZHJlc3MpIGltcGwuZ2V0T3B0aW9uKFNvY2tldE9wdGlvbnMuSVBfTVVMVElDQVNUX0lGKTsKKyAgICAgICAgaWYgKGlwdlhhZGRyZXNzLmlzQW55TG9jYWxBZGRyZXNzKCkpIHsKKyAgICAgICAgICAgIC8vIHRoZSBhZGRyZXNzIHdhcyBub3Qgc2V0IGF0IHRoZSBJUHY0IGxldmVsIHNvIGNoZWNrIHRoZSBJUHY2CisgICAgICAgICAgICAvLyBsZXZlbAorICAgICAgICAgICAgTmV0d29ya0ludGVyZmFjZSB0aGVJbnRlcmZhY2UgPSBnZXROZXR3b3JrSW50ZXJmYWNlKCk7CisgICAgICAgICAgICBpZiAodGhlSW50ZXJmYWNlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBFbnVtZXJhdGlvbjxJbmV0QWRkcmVzcz4gYWRkcmVzc2VzID0gdGhlSW50ZXJmYWNlLmdldEluZXRBZGRyZXNzZXMoKTsKKyAgICAgICAgICAgICAgICBpZiAoYWRkcmVzc2VzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGFkZHJlc3Nlcy5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MgbmV4dEFkZHJlc3MgPSBhZGRyZXNzZXMubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0QWRkcmVzcyBpbnN0YW5jZW9mIEluZXQ2QWRkcmVzcykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXh0QWRkcmVzczsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaXB2WGFkZHJlc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgb3V0Z29pbmcgbmV0d29yayBpbnRlcmZhY2UgdXNlZCBieSB0aGlzIHNvY2tldC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTmV0d29ya0ludGVyZmFjZSBnZXROZXR3b3JrSW50ZXJmYWNlKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBpbnQgaW5kZXggPSAoSW50ZWdlcikgaW1wbC5nZXRPcHRpb24oU29ja2V0T3B0aW9ucy5JUF9NVUxUSUNBU1RfSUYyKTsKKyAgICAgICAgaWYgKGluZGV4ICE9IDApIHsKKyAgICAgICAgICAgIHJldHVybiBOZXR3b3JrSW50ZXJmYWNlLmdldEJ5SW5kZXgoaW5kZXgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBOZXR3b3JrSW50ZXJmYWNlLmZvclVuYm91bmRNdWx0aWNhc3RTb2NrZXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0aW1lLXRvLWxpdmUgKFRUTCkgZm9yIG11bHRpY2FzdCBwYWNrZXRzIHNlbnQgb24gdGhpcyBzb2NrZXQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFRpbWVUb0xpdmUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgcmV0dXJuIGltcGwuZ2V0VGltZVRvTGl2ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRpbWUtdG8tbGl2ZSAoVFRMKSBmb3IgbXVsdGljYXN0IHBhY2tldHMgc2VudCBvbiB0aGlzIHNvY2tldC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzLgorICAgICAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IHtAbGluayAjZ2V0VGltZVRvTGl2ZX0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBieXRlIGdldFRUTCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICByZXR1cm4gaW1wbC5nZXRUVEwoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoaXMgc29ja2V0IHRvIHRoZSBzcGVjaWZpZWQgbXVsdGljYXN0IGdyb3VwLiBBIHNvY2tldCBtdXN0IGpvaW4gYQorICAgICAqIGdyb3VwIGJlZm9yZSBkYXRhIG1heSBiZSByZWNlaXZlZC4gQSBzb2NrZXQgbWF5IGJlIGEgbWVtYmVyIG9mIG11bHRpcGxlCisgICAgICogZ3JvdXBzIGJ1dCBtYXkgam9pbiBhbnkgZ3JvdXAgb25seSBvbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIGdyb3VwQWRkcgorICAgICAqICAgICAgICAgICAgdGhlIG11bHRpY2FzdCBncm91cCB0byBiZSBqb2luZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgam9pbkdyb3VwKEluZXRBZGRyZXNzIGdyb3VwQWRkcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tKb2luT3JMZWF2ZShncm91cEFkZHIpOworICAgICAgICBpbXBsLmpvaW4oZ3JvdXBBZGRyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoaXMgc29ja2V0IHRvIHRoZSBzcGVjaWZpZWQgbXVsdGljYXN0IGdyb3VwLiBBIHNvY2tldCBtdXN0IGpvaW4gYQorICAgICAqIGdyb3VwIGJlZm9yZSBkYXRhIG1heSBiZSByZWNlaXZlZC4gQSBzb2NrZXQgbWF5IGJlIGEgbWVtYmVyIG9mIG11bHRpcGxlCisgICAgICogZ3JvdXBzIGJ1dCBtYXkgam9pbiBhbnkgZ3JvdXAgb25seSBvbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIGdyb3VwQWRkcmVzcworICAgICAqICAgICAgICAgICAgdGhlIG11bHRpY2FzdCBncm91cCB0byBiZSBqb2luZWQuCisgICAgICogQHBhcmFtIG5ldEludGVyZmFjZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldHdvcmsgaW50ZXJmYWNlIG9uIHdoaWNoIHRoZSBkYXRhZ3JhbSBwYWNrZXRzIHdpbGwgYmUKKyAgICAgKiAgICAgICAgICAgIHJlY2VpdmVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGFkZHJlc3MgaXMgbm90IGEgbXVsdGljYXN0IGFkZHJlc3MuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBtdWx0aWNhc3QgZ3JvdXAgaXMgc3BlY2lmaWVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGpvaW5Hcm91cChTb2NrZXRBZGRyZXNzIGdyb3VwQWRkcmVzcywgTmV0d29ya0ludGVyZmFjZSBuZXRJbnRlcmZhY2UpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrSm9pbk9yTGVhdmUoZ3JvdXBBZGRyZXNzLCBuZXRJbnRlcmZhY2UpOworICAgICAgICBpbXBsLmpvaW5Hcm91cChncm91cEFkZHJlc3MsIG5ldEludGVyZmFjZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGlzIHNvY2tldCBmcm9tIHRoZSBzcGVjaWZpZWQgbXVsdGljYXN0IGdyb3VwLgorICAgICAqCisgICAgICogQHBhcmFtIGdyb3VwQWRkcgorICAgICAqICAgICAgICAgICAgdGhlIG11bHRpY2FzdCBncm91cCB0byBiZSBsZWZ0LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgZ3JvdXBBZGRyfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgZ3JvdXAgYWRkcmVzcyBpcyBub3QgYSBtdWx0aWNhc3QgYWRkcmVzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBsZWF2ZUdyb3VwKEluZXRBZGRyZXNzIGdyb3VwQWRkcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tKb2luT3JMZWF2ZShncm91cEFkZHIpOworICAgICAgICBpbXBsLmxlYXZlKGdyb3VwQWRkcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGlzIHNvY2tldCBmcm9tIHRoZSBzcGVjaWZpZWQgbXVsdGljYXN0IGdyb3VwLgorICAgICAqCisgICAgICogQHBhcmFtIGdyb3VwQWRkcmVzcworICAgICAqICAgICAgICAgICAgdGhlIG11bHRpY2FzdCBncm91cCB0byBiZSBsZWZ0LgorICAgICAqIEBwYXJhbSBuZXRJbnRlcmZhY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXR3b3JrIGludGVyZmFjZSBvbiB3aGljaCB0aGUgYWRkcmVzc2VzIHNob3VsZCBiZQorICAgICAqICAgICAgICAgICAgZHJvcHBlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBncm91cCBhZGRyZXNzIGlzIG5vdCBhIG11bHRpY2FzdCBhZGRyZXNzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGdyb3VwQWRkcmVzc30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxlYXZlR3JvdXAoU29ja2V0QWRkcmVzcyBncm91cEFkZHJlc3MsIE5ldHdvcmtJbnRlcmZhY2UgbmV0SW50ZXJmYWNlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja0pvaW5PckxlYXZlKGdyb3VwQWRkcmVzcywgbmV0SW50ZXJmYWNlKTsKKyAgICAgICAgaW1wbC5sZWF2ZUdyb3VwKGdyb3VwQWRkcmVzcywgbmV0SW50ZXJmYWNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tKb2luT3JMZWF2ZShTb2NrZXRBZGRyZXNzIGdyb3VwQWRkcmVzcywgTmV0d29ya0ludGVyZmFjZSBuZXRJbnRlcmZhY2UpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBpZiAoZ3JvdXBBZGRyZXNzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImdyb3VwQWRkcmVzcyA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAobmV0SW50ZXJmYWNlICE9IG51bGwgJiYgIW5ldEludGVyZmFjZS5nZXRJbmV0QWRkcmVzc2VzKCkuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oIk5vIGFkZHJlc3MgYXNzb2NpYXRlZCB3aXRoIGludGVyZmFjZTogIiArIG5ldEludGVyZmFjZSk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIShncm91cEFkZHJlc3MgaW5zdGFuY2VvZiBJbmV0U29ja2V0QWRkcmVzcykpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkdyb3VwIGFkZHJlc3Mgbm90IGFuIEluZXRTb2NrZXRBZGRyZXNzOiAiICsKKyAgICAgICAgICAgICAgICAgICAgZ3JvdXBBZGRyZXNzLmdldENsYXNzKCkpOworICAgICAgICB9CisKKyAgICAgICAgSW5ldEFkZHJlc3MgZ3JvdXBBZGRyID0gKChJbmV0U29ja2V0QWRkcmVzcykgZ3JvdXBBZGRyZXNzKS5nZXRBZGRyZXNzKCk7CisgICAgICAgIGlmIChncm91cEFkZHIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbigiR3JvdXAgYWRkcmVzcyBoYXMgbm8gYWRkcmVzczogIiArIGdyb3VwQWRkcmVzcyk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWdyb3VwQWRkci5pc011bHRpY2FzdEFkZHJlc3MoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJOb3QgYSBtdWx0aWNhc3QgZ3JvdXA6ICIgKyBncm91cEFkZHIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrSm9pbk9yTGVhdmUoSW5ldEFkZHJlc3MgZ3JvdXBBZGRyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgaWYgKCFncm91cEFkZHIuaXNNdWx0aWNhc3RBZGRyZXNzKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiTm90IGEgbXVsdGljYXN0IGdyb3VwOiAiICsgZ3JvdXBBZGRyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmRzIHRoZSBnaXZlbiB7QGNvZGUgcGFja2V0fSBvbiB0aGlzIHNvY2tldCwgdXNpbmcgdGhlIGdpdmVuIHtAY29kZSB0dGx9LiBUaGlzIG1ldGhvZCBpcworICAgICAqIGRlcHJlY2F0ZWQgYmVjYXVzZSBpdCBtb2RpZmllcyB0aGUgVFRMIHNvY2tldCBvcHRpb24gZm9yIHRoaXMgc29ja2V0IHR3aWNlIG9uIGVhY2ggY2FsbC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzLgorICAgICAqIEBkZXByZWNhdGVkIHVzZSB7QGxpbmsgI3NldFRpbWVUb0xpdmV9LgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHZvaWQgc2VuZChEYXRhZ3JhbVBhY2tldCBwYWNrZXQsIGJ5dGUgdHRsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgSW5ldEFkZHJlc3MgcGFja0FkZHIgPSBwYWNrZXQuZ2V0QWRkcmVzcygpOworICAgICAgICBpbnQgY3VyclRUTCA9IGdldFRpbWVUb0xpdmUoKTsKKyAgICAgICAgaWYgKHBhY2tBZGRyLmlzTXVsdGljYXN0QWRkcmVzcygpICYmIChieXRlKSBjdXJyVFRMICE9IHR0bCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzZXRUaW1lVG9MaXZlKHR0bCAmIDB4ZmYpOworICAgICAgICAgICAgICAgIGltcGwuc2VuZChwYWNrZXQpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBzZXRUaW1lVG9MaXZlKGN1cnJUVEwpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW1wbC5zZW5kKHBhY2tldCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBvdXRnb2luZyBuZXR3b3JrIGludGVyZmFjZSB1c2VkIGJ5IHRoaXMgc29ja2V0LiBUaGUgaW50ZXJmYWNlIHVzZWQgaXMgdGhlIGZpcnN0CisgICAgICogaW50ZXJmYWNlIGZvdW5kIHRvIGhhdmUgdGhlIGdpdmVuIHtAY29kZSBhZGRyZXNzfS4gVG8gYXZvaWQgaW5oZXJlbnQgdW5wcmVkaWN0YWJpbGl0eSwKKyAgICAgKiBuZXcgY29kZSBzaG91bGQgdXNlIHtAbGluayAjZ2V0TmV0d29ya0ludGVyZmFjZX0gaW5zdGVhZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRJbnRlcmZhY2UoSW5ldEFkZHJlc3MgYWRkcmVzcykgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBpZiAoYWRkcmVzcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImFkZHJlc3MgPT0gbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgTmV0d29ya0ludGVyZmFjZSBuZXR3b3JrSW50ZXJmYWNlID0gTmV0d29ya0ludGVyZmFjZS5nZXRCeUluZXRBZGRyZXNzKGFkZHJlc3MpOworICAgICAgICBpZiAobmV0d29ya0ludGVyZmFjZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKCJBZGRyZXNzIG5vdCBhc3NvY2lhdGVkIHdpdGggYW4gaW50ZXJmYWNlOiAiICsgYWRkcmVzcyk7CisgICAgICAgIH0KKyAgICAgICAgaW1wbC5zZXRPcHRpb24oU29ja2V0T3B0aW9ucy5JUF9NVUxUSUNBU1RfSUYyLCBuZXR3b3JrSW50ZXJmYWNlLmdldEluZGV4KCkpOworICAgICAgICB0aGlzLnNldEFkZHJlc3MgPSBhZGRyZXNzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG91dGdvaW5nIG5ldHdvcmsgaW50ZXJmYWNlIHVzZWQgYnkgdGhpcyBzb2NrZXQgdG8gdGhlIGdpdmVuCisgICAgICoge0Bjb2RlIG5ldHdvcmtJbnRlcmZhY2V9LgorICAgICAqCisgICAgICogQHRocm93cyBTb2NrZXRFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5ldHdvcmtJbnRlcmZhY2UoTmV0d29ya0ludGVyZmFjZSBuZXR3b3JrSW50ZXJmYWNlKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIGlmIChuZXR3b3JrSW50ZXJmYWNlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oIm5ldHdvcmtJbnRlcmZhY2UgPT0gbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgaW1wbC5zZXRPcHRpb24oU29ja2V0T3B0aW9ucy5JUF9NVUxUSUNBU1RfSUYyLCBuZXR3b3JrSW50ZXJmYWNlLmdldEluZGV4KCkpOworICAgICAgICB0aGlzLnNldEFkZHJlc3MgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHRpbWUtdG8tbGl2ZSAoVFRMKSBmb3IgbXVsdGljYXN0IHBhY2tldHMgc2VudCBvbiB0aGlzIHNvY2tldC4KKyAgICAgKiBWYWxpZCBUVEwgdmFsdWVzIGFyZSBiZXR3ZWVuIDAgYW5kIDI1NSBpbmNsdXNpdmUuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lVG9MaXZlKGludCB0dGwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBpZiAodHRsIDwgMCB8fCB0dGwgPiAyNTUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlRpbWVUb0xpdmUgb3V0IG9mIGJvdW5kczogIiArIHR0bCk7CisgICAgICAgIH0KKyAgICAgICAgaW1wbC5zZXRUaW1lVG9MaXZlKHR0bCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdGltZS10by1saXZlIChUVEwpIGZvciBtdWx0aWNhc3QgcGFja2V0cyBzZW50IG9uIHRoaXMgc29ja2V0LgorICAgICAqIFZhbGlkIFRUTCB2YWx1ZXMgYXJlIGJldHdlZW4gMCBhbmQgMjU1IGluY2x1c2l2ZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzLgorICAgICAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IHtAbGluayAjc2V0VGltZVRvTGl2ZX0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyB2b2lkIHNldFRUTChieXRlIHR0bCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIGltcGwuc2V0VFRMKHR0bCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgc3luY2hyb25pemVkIHZvaWQgY3JlYXRlU29ja2V0KGludCBhUG9ydCwgSW5ldEFkZHJlc3MgYWRkcikgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGltcGwgPSBmYWN0b3J5ICE9IG51bGwgPyBmYWN0b3J5LmNyZWF0ZURhdGFncmFtU29ja2V0SW1wbCgpIDogbmV3IFBsYWluRGF0YWdyYW1Tb2NrZXRJbXBsKCk7CisgICAgICAgIGltcGwuY3JlYXRlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbXBsLnNldE9wdGlvbihTb2NrZXRPcHRpb25zLlNPX1JFVVNFQUREUiwgQm9vbGVhbi5UUlVFKTsKKyAgICAgICAgICAgIGltcGwuYmluZChhUG9ydCwgYWRkcik7CisgICAgICAgICAgICBpc0JvdW5kID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGNsb3NlKCk7CisgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIG11bHRpY2FzdCBsb29wYmFjayBpcyA8aT5kaXNhYmxlZDwvaT4uCisgICAgICogU2VlIHtAbGluayBTb2NrZXRPcHRpb25zI0lQX01VTFRJQ0FTVF9MT09QfSwgYW5kIG5vdGUgdGhhdCB0aGUgc2Vuc2Ugb2YgdGhpcyBpcyB0aGUKKyAgICAgKiBvcHBvc2l0ZSBvZiB0aGUgdW5kZXJseWluZyBVbml4IHtAY29kZSBJUF9NVUxUSUNBU1RfTE9PUH0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0TG9vcGJhY2tNb2RlKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICByZXR1cm4gISgoQm9vbGVhbikgaW1wbC5nZXRPcHRpb24oU29ja2V0T3B0aW9ucy5JUF9NVUxUSUNBU1RfTE9PUCkpLmJvb2xlYW5WYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERpc2FibGVzIG11bHRpY2FzdCBsb29wYmFjayBpZiB7QGNvZGUgZGlzYWJsZSA9PSB0cnVlfS4KKyAgICAgKiBTZWUge0BsaW5rIFNvY2tldE9wdGlvbnMjSVBfTVVMVElDQVNUX0xPT1B9LCBhbmQgbm90ZSB0aGF0IHRoZSBzZW5zZSBvZiB0aGlzIGlzIHRoZQorICAgICAqIG9wcG9zaXRlIG9mIHRoZSB1bmRlcmx5aW5nIFVuaXgge0Bjb2RlIElQX01VTFRJQ0FTVF9MT09QfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMb29wYmFja01vZGUoYm9vbGVhbiBkaXNhYmxlKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIGltcGwuc2V0T3B0aW9uKFNvY2tldE9wdGlvbnMuSVBfTVVMVElDQVNUX0xPT1AsIEJvb2xlYW4udmFsdWVPZighZGlzYWJsZSkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9OZXRQZXJtaXNzaW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvTmV0UGVybWlzc2lvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxYTI2MzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvTmV0UGVybWlzc2lvbi5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkJhc2ljUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBOZXRQZXJtaXNzaW9uIGV4dGVuZHMgQmFzaWNQZXJtaXNzaW9uIHsKKyAgICBwdWJsaWMgTmV0UGVybWlzc2lvbihTdHJpbmcgbmFtZSkgeyBzdXBlcigiIik7IH0KKworICAgIHB1YmxpYyBOZXRQZXJtaXNzaW9uKFN0cmluZyBuYW1lLCBTdHJpbmcgYWN0aW9ucykgeyBzdXBlcigiIiwgIiIpOyB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyBnZXRBY3Rpb25zKCkgeyByZXR1cm4gbnVsbDsgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGltcGxpZXMoUGVybWlzc2lvbiBwZXJtaXNzaW9uKSB7IHJldHVybiB0cnVlOyB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvTmV0d29ya0ludGVyZmFjZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L05ldHdvcmtJbnRlcmZhY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNmQ5YWY0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L05ldHdvcmtJbnRlcmZhY2UuamF2YQpAQCAtMCwwICsxLDQ4NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgamF2YS5pby5GaWxlUmVhZGVyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkxpbmtlZExpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBsaWJjb3JlLmlvLkVycm5vRXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKK2ltcG9ydCBsaWJjb3JlLmlvLkxpYmNvcmU7CitpbXBvcnQgc3RhdGljIGxpYmNvcmUuaW8uT3NDb25zdGFudHMuKjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIHVzZWQgdG8gcmVwcmVzZW50IGEgbmV0d29yayBpbnRlcmZhY2Ugb2YgdGhlIGxvY2FsIGRldmljZS4gQW4KKyAqIGludGVyZmFjZSBpcyBkZWZpbmVkIGJ5IGl0cyBhZGRyZXNzIGFuZCBhIHBsYXRmb3JtIGRlcGVuZGVudCBuYW1lLiBUaGUgY2xhc3MKKyAqIHByb3ZpZGVzIG1ldGhvZHMgdG8gZ2V0IGFsbCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgYXZhaWxhYmxlIGludGVyZmFjZXMgb2YgdGhlCisgKiBzeXN0ZW0gb3IgdG8gaWRlbnRpZnkgdGhlIGxvY2FsIGludGVyZmFjZSBvZiBhIGpvaW5lZCBtdWx0aWNhc3QgZ3JvdXAuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBOZXR3b3JrSW50ZXJmYWNlIGV4dGVuZHMgT2JqZWN0IHsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBuYW1lOworICAgIHByaXZhdGUgZmluYWwgaW50IGludGVyZmFjZUluZGV4OworICAgIHByaXZhdGUgZmluYWwgTGlzdDxJbnRlcmZhY2VBZGRyZXNzPiBpbnRlcmZhY2VBZGRyZXNzZXM7CisgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PEluZXRBZGRyZXNzPiBhZGRyZXNzZXM7CisKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8TmV0d29ya0ludGVyZmFjZT4gY2hpbGRyZW4gPSBuZXcgTGlua2VkTGlzdDxOZXR3b3JrSW50ZXJmYWNlPigpOworCisgICAgcHJpdmF0ZSBOZXR3b3JrSW50ZXJmYWNlIHBhcmVudCA9IG51bGw7CisKKyAgICBwcml2YXRlIE5ldHdvcmtJbnRlcmZhY2UoU3RyaW5nIG5hbWUsIGludCBpbnRlcmZhY2VJbmRleCwKKyAgICAgICAgICAgIExpc3Q8SW5ldEFkZHJlc3M+IGFkZHJlc3NlcywgTGlzdDxJbnRlcmZhY2VBZGRyZXNzPiBpbnRlcmZhY2VBZGRyZXNzZXMpIHsKKyAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgICAgdGhpcy5pbnRlcmZhY2VJbmRleCA9IGludGVyZmFjZUluZGV4OworICAgICAgICB0aGlzLmFkZHJlc3NlcyA9IGFkZHJlc3NlczsKKyAgICAgICAgdGhpcy5pbnRlcmZhY2VBZGRyZXNzZXMgPSBpbnRlcmZhY2VBZGRyZXNzZXM7CisgICAgfQorCisgICAgc3RhdGljIE5ldHdvcmtJbnRlcmZhY2UgZm9yVW5ib3VuZE11bHRpY2FzdFNvY2tldCgpIHsKKyAgICAgICAgLy8gVGhpcyBpcyB3aGF0IHRoZSBSSSByZXR1cm5zIGZvciBhIE11bHRpY2FzdFNvY2tldCB0aGF0IGhhc24ndCBiZWVuIGNvbnN0cmFpbmVkCisgICAgICAgIC8vIHRvIGEgc3BlY2lmaWMgaW50ZXJmYWNlLgorICAgICAgICByZXR1cm4gbmV3IE5ldHdvcmtJbnRlcmZhY2UobnVsbCwgLTEsCisgICAgICAgICAgICAgICAgQXJyYXlzLmFzTGlzdChJbmV0NkFkZHJlc3MuQU5ZKSwgQ29sbGVjdGlvbnMuPEludGVyZmFjZUFkZHJlc3M+ZW1wdHlMaXN0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGluZGV4IGZvciB0aGUgbmV0d29yayBpbnRlcmZhY2UsIG9yIC0xIGlmIHVua25vd24uCisgICAgICoKKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEluZGV4KCkgeworICAgICAgICByZXR1cm4gaW50ZXJmYWNlSW5kZXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGlzIG5ldHdvcmsgaW50ZXJmYWNlIChzdWNoIGFzICJldGgwIiBvciAibG8iKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gZW51bWVyYXRpb24gb2YgdGhlIGFkZHJlc3NlcyBib3VuZCB0byB0aGlzIG5ldHdvcmsgaW50ZXJmYWNlLgorICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxJbmV0QWRkcmVzcz4gZ2V0SW5ldEFkZHJlc3NlcygpIHsKKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVudW1lcmF0aW9uKGFkZHJlc3Nlcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGh1bWFuLXJlYWRhYmxlIG5hbWUgZm9yIHRoaXMgbmV0d29yayBpbnRlcmZhY2UuIE9uIEFuZHJvaWQsIHRoaXMgaXMgdGhlIHNhbWUKKyAgICAgKiBzdHJpbmcgYXMgcmV0dXJuZWQgYnkge0BsaW5rICNnZXROYW1lfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldERpc3BsYXlOYW1lKCkgeworICAgICAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgTmV0d29ya0ludGVyZmFjZX0gY29ycmVzcG9uZGluZyB0byB0aGUgbmFtZWQgbmV0d29yayBpbnRlcmZhY2UsIG9yIG51bGwKKyAgICAgKiBpZiBubyBpbnRlcmZhY2UgaGFzIHRoaXMgbmFtZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBpbnRlcmZhY2VOYW1lID09IG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTmV0d29ya0ludGVyZmFjZSBnZXRCeU5hbWUoU3RyaW5nIGludGVyZmFjZU5hbWUpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBpZiAoaW50ZXJmYWNlTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImludGVyZmFjZU5hbWUgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmICghaXNWYWxpZEludGVyZmFjZU5hbWUoaW50ZXJmYWNlTmFtZSkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgaW50IGludGVyZmFjZUluZGV4ID0gcmVhZEludEZpbGUoIi9zeXMvY2xhc3MvbmV0LyIgKyBpbnRlcmZhY2VOYW1lICsgIi9pZmluZGV4Iik7CisgICAgICAgIExpc3Q8SW5ldEFkZHJlc3M+IGFkZHJlc3NlcyA9IG5ldyBBcnJheUxpc3Q8SW5ldEFkZHJlc3M+KCk7CisgICAgICAgIExpc3Q8SW50ZXJmYWNlQWRkcmVzcz4gaW50ZXJmYWNlQWRkcmVzc2VzID0gbmV3IEFycmF5TGlzdDxJbnRlcmZhY2VBZGRyZXNzPigpOworICAgICAgICBjb2xsZWN0SXB2NkFkZHJlc3NlcyhpbnRlcmZhY2VOYW1lLCBpbnRlcmZhY2VJbmRleCwgYWRkcmVzc2VzLCBpbnRlcmZhY2VBZGRyZXNzZXMpOworICAgICAgICBjb2xsZWN0SXB2NEFkZHJlc3MoaW50ZXJmYWNlTmFtZSwgYWRkcmVzc2VzLCBpbnRlcmZhY2VBZGRyZXNzZXMpOworCisgICAgICAgIHJldHVybiBuZXcgTmV0d29ya0ludGVyZmFjZShpbnRlcmZhY2VOYW1lLCBpbnRlcmZhY2VJbmRleCwgYWRkcmVzc2VzLCBpbnRlcmZhY2VBZGRyZXNzZXMpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY29sbGVjdElwdjZBZGRyZXNzZXMoU3RyaW5nIGludGVyZmFjZU5hbWUsIGludCBpbnRlcmZhY2VJbmRleCwKKyAgICAgICAgICAgIExpc3Q8SW5ldEFkZHJlc3M+IGFkZHJlc3NlcywgTGlzdDxJbnRlcmZhY2VBZGRyZXNzPiBpbnRlcmZhY2VBZGRyZXNzZXMpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICAvLyBGb3JtYXQgb2YgL3Byb2MvbmV0L2lmX2luZXQ2IChhbGwgbnVtZXJpYyBmaWVsZHMgYXJlIGltcGxpY2l0IGhleCkuCisgICAgICAgIC8vIDEuIElQdjYgYWRkcmVzcworICAgICAgICAvLyAyLiBpbnRlcmZhY2UgaW5kZXgKKyAgICAgICAgLy8gMy4gcHJlZml4IGxlbmd0aAorICAgICAgICAvLyA0LiBzY29wZQorICAgICAgICAvLyA1LiBmbGFncworICAgICAgICAvLyA2LiBpbnRlcmZhY2UgbmFtZQorICAgICAgICAvLyAiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEgMDEgODAgMTAgODAgICAgICAgbG8iCisgICAgICAgIEJ1ZmZlcmVkUmVhZGVyIGluID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBGaWxlUmVhZGVyKCIvcHJvYy9uZXQvaWZfaW5ldDYiKSk7CisgICAgICAgICAgICBTdHJpbmcgc3VmZml4ID0gIiAiICsgaW50ZXJmYWNlTmFtZTsKKyAgICAgICAgICAgIFN0cmluZyBsaW5lOworICAgICAgICAgICAgd2hpbGUgKChsaW5lID0gaW4ucmVhZExpbmUoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmICghbGluZS5lbmRzV2l0aChzdWZmaXgpKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBieXRlW10gYWRkcmVzc0J5dGVzID0gbmV3IGJ5dGVbMTZdOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWRkcmVzc0J5dGVzLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICAgICAgICAgIGFkZHJlc3NCeXRlc1tpXSA9IChieXRlKSBJbnRlZ2VyLnBhcnNlSW50KGxpbmUuc3Vic3RyaW5nKDIqaSwgMippICsgMiksIDE2KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc2hvcnQgcHJlZml4TGVuZ3RoID0gU2hvcnQucGFyc2VTaG9ydChsaW5lLnN1YnN0cmluZygzNiwgMzgpLCAxNik7CisgICAgICAgICAgICAgICAgSW5ldDZBZGRyZXNzIGluZXQ2QWRkcmVzcyA9IG5ldyBJbmV0NkFkZHJlc3MoYWRkcmVzc0J5dGVzLCBudWxsLCBpbnRlcmZhY2VJbmRleCk7CisKKyAgICAgICAgICAgICAgICBhZGRyZXNzZXMuYWRkKGluZXQ2QWRkcmVzcyk7CisgICAgICAgICAgICAgICAgaW50ZXJmYWNlQWRkcmVzc2VzLmFkZChuZXcgSW50ZXJmYWNlQWRkcmVzcyhpbmV0NkFkZHJlc3MsIHByZWZpeExlbmd0aCkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IHJldGhyb3dBc1NvY2tldEV4Y2VwdGlvbihleCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBJb1V0aWxzLmNsb3NlUXVpZXRseShpbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNvbGxlY3RJcHY0QWRkcmVzcyhTdHJpbmcgaW50ZXJmYWNlTmFtZSwgTGlzdDxJbmV0QWRkcmVzcz4gYWRkcmVzc2VzLAorICAgICAgICAgICAgTGlzdDxJbnRlcmZhY2VBZGRyZXNzPiBpbnRlcmZhY2VBZGRyZXNzZXMpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBGaWxlRGVzY3JpcHRvciBmZCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmZCA9IExpYmNvcmUub3Muc29ja2V0KEFGX0lORVQsIFNPQ0tfREdSQU0sIDApOworICAgICAgICAgICAgSW5ldEFkZHJlc3MgYWRkcmVzcyA9IExpYmNvcmUub3MuaW9jdGxJbmV0QWRkcmVzcyhmZCwgU0lPQ0dJRkFERFIsIGludGVyZmFjZU5hbWUpOworICAgICAgICAgICAgSW5ldEFkZHJlc3MgYnJvYWRjYXN0ID0gTGliY29yZS5vcy5pb2N0bEluZXRBZGRyZXNzKGZkLCBTSU9DR0lGQlJEQUREUiwgaW50ZXJmYWNlTmFtZSk7CisgICAgICAgICAgICBJbmV0QWRkcmVzcyBuZXRtYXNrID0gTGliY29yZS5vcy5pb2N0bEluZXRBZGRyZXNzKGZkLCBTSU9DR0lGTkVUTUFTSywgaW50ZXJmYWNlTmFtZSk7CisgICAgICAgICAgICBpZiAoYnJvYWRjYXN0LmVxdWFscyhJbmV0NEFkZHJlc3MuQU5ZKSkgeworICAgICAgICAgICAgICAgIGJyb2FkY2FzdCA9IG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGFkZHJlc3Nlcy5hZGQoYWRkcmVzcyk7CisgICAgICAgICAgICBpbnRlcmZhY2VBZGRyZXNzZXMuYWRkKG5ldyBJbnRlcmZhY2VBZGRyZXNzKChJbmV0NEFkZHJlc3MpIGFkZHJlc3MsCisgICAgICAgICAgICAgICAgICAgIChJbmV0NEFkZHJlc3MpIGJyb2FkY2FzdCwgKEluZXQ0QWRkcmVzcykgbmV0bWFzaykpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgaWYgKGVycm5vRXhjZXB0aW9uLmVycm5vICE9IEVBRERSTk9UQVZBSUwpIHsKKyAgICAgICAgICAgICAgICAvLyBFQUREUk5PVEFWQUlMIGp1c3QgbWVhbnMgbm8gSVB2NCBhZGRyZXNzIGZvciB0aGlzIGludGVyZmFjZS4KKyAgICAgICAgICAgICAgICAvLyBBbnl0aGluZyBlbHNlIGlzIGEgcmVhbCBlcnJvci4KKyAgICAgICAgICAgICAgICB0aHJvdyByZXRocm93QXNTb2NrZXRFeGNlcHRpb24oZXJybm9FeGNlcHRpb24pOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IHJldGhyb3dBc1NvY2tldEV4Y2VwdGlvbihleCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBJb1V0aWxzLmNsb3NlUXVpZXRseShmZCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBARmluZEJ1Z3NTdXBwcmVzc1dhcm5pbmdzKCJETUlfSEFSRENPREVEX0FCU09MVVRFX0ZJTEVOQU1FIikKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzVmFsaWRJbnRlcmZhY2VOYW1lKFN0cmluZyBpbnRlcmZhY2VOYW1lKSB7CisgICAgICAgIC8vIERvbid0IGp1c3Qgc3RhdCBiZWNhdXNlIGEgY3JhZnR5IHVzZXIgbWlnaHQgaGF2ZSAvIG9yIC4uIGluIHRoZSBzdXBwb3NlZCBpbnRlcmZhY2UgbmFtZS4KKyAgICAgICAgZm9yIChTdHJpbmcgdmFsaWROYW1lIDogbmV3IEZpbGUoIi9zeXMvY2xhc3MvbmV0IikubGlzdCgpKSB7CisgICAgICAgICAgICBpZiAoaW50ZXJmYWNlTmFtZS5lcXVhbHModmFsaWROYW1lKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgcmVhZEludEZpbGUoU3RyaW5nIHBhdGgpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHMgPSBJb1V0aWxzLnJlYWRGaWxlQXNTdHJpbmcocGF0aCkudHJpbSgpOworICAgICAgICAgICAgaWYgKHMuc3RhcnRzV2l0aCgiMHgiKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLnBhcnNlSW50KHMuc3Vic3RyaW5nKDIpLCAxNik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLnBhcnNlSW50KHMpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IHJldGhyb3dBc1NvY2tldEV4Y2VwdGlvbihleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTb2NrZXRFeGNlcHRpb24gcmV0aHJvd0FzU29ja2V0RXhjZXB0aW9uKEV4Y2VwdGlvbiBleCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIFNvY2tldEV4Y2VwdGlvbiByZXN1bHQgPSBuZXcgU29ja2V0RXhjZXB0aW9uKCk7CisgICAgICAgIHJlc3VsdC5pbml0Q2F1c2UoZXgpOworICAgICAgICB0aHJvdyByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIE5ldHdvcmtJbnRlcmZhY2V9IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIGFkZHJlc3MsIG9yIG51bGwgaWYgbm8KKyAgICAgKiBpbnRlcmZhY2UgaGFzIHRoaXMgYWRkcmVzcy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBhZGRyZXNzID09IG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTmV0d29ya0ludGVyZmFjZSBnZXRCeUluZXRBZGRyZXNzKEluZXRBZGRyZXNzIGFkZHJlc3MpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBpZiAoYWRkcmVzcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImFkZHJlc3MgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGZvciAoTmV0d29ya0ludGVyZmFjZSBuZXR3b3JrSW50ZXJmYWNlIDogZ2V0TmV0d29ya0ludGVyZmFjZXNMaXN0KCkpIHsKKyAgICAgICAgICAgIGlmIChuZXR3b3JrSW50ZXJmYWNlLmFkZHJlc3Nlcy5jb250YWlucyhhZGRyZXNzKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXR3b3JrSW50ZXJmYWNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIE5ldHdvcmtJbnRlcmZhY2UgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gaW50ZXJmYWNlIGluZGV4LCBvciBudWxsIGlmIG5vCisgICAgICogaW50ZXJmYWNlIGhhcyB0aGlzIGluZGV4LgorICAgICAqCisgICAgICogQHRocm93cyBTb2NrZXRFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzLgorICAgICAqIEBoaWRlIDEuNworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTmV0d29ya0ludGVyZmFjZSBnZXRCeUluZGV4KGludCBpbmRleCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBuYW1lID0gTGliY29yZS5vcy5pZl9pbmRleHRvbmFtZShpbmRleCk7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBOZXR3b3JrSW50ZXJmYWNlLmdldEJ5TmFtZShuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgbGlzdCBvZiBhbGwgbmV0d29yayBpbnRlcmZhY2VzIGF2YWlsYWJsZSBvbiB0aGUgbG9jYWwgc3lzdGVtIG9yCisgICAgICoge0Bjb2RlIG51bGx9IGlmIG5vIGludGVyZmFjZSBpcyBhdmFpbGFibGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsaXN0IG9mIHtAY29kZSBOZXR3b3JrSW50ZXJmYWNlfSBpbnN0YW5jZXMgcmVwcmVzZW50aW5nIHRoZQorICAgICAqICAgICAgICAgYXZhaWxhYmxlIGludGVyZmFjZXMuCisgICAgICogQHRocm93cyBTb2NrZXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgZ2V0dGluZyB0aGUgbmV0d29yayBpbnRlcmZhY2UKKyAgICAgKiAgICAgICAgICAgICBpbmZvcm1hdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEVudW1lcmF0aW9uPE5ldHdvcmtJbnRlcmZhY2U+IGdldE5ldHdvcmtJbnRlcmZhY2VzKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbnVtZXJhdGlvbihnZXROZXR3b3JrSW50ZXJmYWNlc0xpc3QoKSk7CisgICAgfQorCisgICAgQEZpbmRCdWdzU3VwcHJlc3NXYXJuaW5ncygiRE1JX0hBUkRDT0RFRF9BQlNPTFVURV9GSUxFTkFNRSIpCisgICAgcHJpdmF0ZSBzdGF0aWMgTGlzdDxOZXR3b3JrSW50ZXJmYWNlPiBnZXROZXR3b3JrSW50ZXJmYWNlc0xpc3QoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nW10gaW50ZXJmYWNlTmFtZXMgPSBuZXcgRmlsZSgiL3N5cy9jbGFzcy9uZXQiKS5saXN0KCk7CisgICAgICAgIE5ldHdvcmtJbnRlcmZhY2VbXSBpbnRlcmZhY2VzID0gbmV3IE5ldHdvcmtJbnRlcmZhY2VbaW50ZXJmYWNlTmFtZXMubGVuZ3RoXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnRlcmZhY2VOYW1lcy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgaW50ZXJmYWNlc1tpXSA9IE5ldHdvcmtJbnRlcmZhY2UuZ2V0QnlOYW1lKGludGVyZmFjZU5hbWVzW2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIExpc3Q8TmV0d29ya0ludGVyZmFjZT4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxOZXR3b3JrSW50ZXJmYWNlPigpOworICAgICAgICBib29sZWFuW10gcGVla2VkID0gbmV3IGJvb2xlYW5baW50ZXJmYWNlcy5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGludGVyZmFjZXMubGVuZ3RoOyBjb3VudGVyKyspIHsKKyAgICAgICAgICAgIC8vIElmIHRoaXMgaW50ZXJmYWNlIGhhcyBiZWVuIHRvdWNoZWQsIGNvbnRpbnVlLgorICAgICAgICAgICAgaWYgKHBlZWtlZFtjb3VudGVyXSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IGNvdW50ZXIyID0gY291bnRlcjsKKyAgICAgICAgICAgIC8vIENoZWNrcyB3aGV0aGVyIHRoZSBmb2xsb3dpbmcgaW50ZXJmYWNlcyBhcmUgY2hpbGRyZW4uCisgICAgICAgICAgICBmb3IgKDsgY291bnRlcjIgPCBpbnRlcmZhY2VzLmxlbmd0aDsgY291bnRlcjIrKykgeworICAgICAgICAgICAgICAgIGlmIChwZWVrZWRbY291bnRlcjJdKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoaW50ZXJmYWNlc1tjb3VudGVyMl0ubmFtZS5zdGFydHNXaXRoKGludGVyZmFjZXNbY291bnRlcl0ubmFtZSArICI6IikpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gVGFnZ2VkIGFzIHBlZWtlZAorICAgICAgICAgICAgICAgICAgICBwZWVrZWRbY291bnRlcjJdID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgaW50ZXJmYWNlc1tjb3VudGVyXS5jaGlsZHJlbi5hZGQoaW50ZXJmYWNlc1tjb3VudGVyMl0pOworICAgICAgICAgICAgICAgICAgICBpbnRlcmZhY2VzW2NvdW50ZXIyXS5wYXJlbnQgPSBpbnRlcmZhY2VzW2NvdW50ZXJdOworICAgICAgICAgICAgICAgICAgICBpbnRlcmZhY2VzW2NvdW50ZXJdLmFkZHJlc3Nlcy5hZGRBbGwoaW50ZXJmYWNlc1tjb3VudGVyMl0uYWRkcmVzc2VzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBUYWdnZWQgYXMgcGVla2VkCisgICAgICAgICAgICByZXN1bHQuYWRkKGludGVyZmFjZXNbY291bnRlcl0pOworICAgICAgICAgICAgcGVla2VkW2NvdW50ZXJdID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHRvIHRoaXMge0Bjb2RlIE5ldHdvcmtJbnRlcmZhY2V9IGFuZAorICAgICAqIHJldHVybnMgd2hldGhlciB0aGV5IGFyZSBlcXVhbCBvciBub3QuIFRoZSBvYmplY3QgbXVzdCBiZSBhbiBpbnN0YW5jZSBvZgorICAgICAqIHtAY29kZSBOZXR3b3JrSW50ZXJmYWNlfSB3aXRoIHRoZSBzYW1lIG5hbWUsIGRpc3BsYXkgbmFtZSwgYW5kIGxpc3QKKyAgICAgKiBvZiBpbnRlcmZhY2UgYWRkcmVzc2VzLgorICAgICAqCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHdpdGggdGhpcyBpbnN0YW5jZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBlcXVhbCB0byB0aGlzIHtAY29kZQorICAgICAqICAgICAgICAgTmV0d29ya0ludGVyZmFjZX0sIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgI2hhc2hDb2RlKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIE5ldHdvcmtJbnRlcmZhY2UpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgTmV0d29ya0ludGVyZmFjZSByaHMgPSAoTmV0d29ya0ludGVyZmFjZSkgb2JqOworICAgICAgICAvLyBUT0RPOiBzaG91bGQgdGhlIG9yZGVyIG9mIHRoZSBhZGRyZXNzZXMgbWF0dGVyICh3ZSB1c2UgTGlzdC5lcXVhbHMpPworICAgICAgICByZXR1cm4gaW50ZXJmYWNlSW5kZXggPT0gcmhzLmludGVyZmFjZUluZGV4ICYmCisgICAgICAgICAgICAgICAgbmFtZS5lcXVhbHMocmhzLm5hbWUpICYmCisgICAgICAgICAgICAgICAgYWRkcmVzc2VzLmVxdWFscyhyaHMuYWRkcmVzc2VzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgZm9yIHRoaXMge0Bjb2RlIE5ldHdvcmtJbnRlcmZhY2V9LiBTaW5jZSB0aGUKKyAgICAgKiBuYW1lIHNob3VsZCBiZSB1bmlxdWUgZm9yIGVhY2ggbmV0d29yayBpbnRlcmZhY2UgdGhlIGhhc2ggY29kZSBpcworICAgICAqIGdlbmVyYXRlZCB1c2luZyB0aGUgbmFtZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWUuaGFzaENvZGUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKDI1KTsKKyAgICAgICAgc2IuYXBwZW5kKCJbIik7CisgICAgICAgIHNiLmFwcGVuZChuYW1lKTsKKyAgICAgICAgc2IuYXBwZW5kKCJdWyIpOworICAgICAgICBzYi5hcHBlbmQoaW50ZXJmYWNlSW5kZXgpOworICAgICAgICBzYi5hcHBlbmQoIl0iKTsKKyAgICAgICAgZm9yIChJbmV0QWRkcmVzcyBhZGRyZXNzIDogYWRkcmVzc2VzKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIlsiKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZChhZGRyZXNzLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgc2IuYXBwZW5kKCJdIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIExpc3Qgb2YgdGhlIEludGVyZmFjZUFkZHJlc3NlcyBmb3IgdGhpcyBuZXR3b3JrIGludGVyZmFjZS4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIExpc3Q8SW50ZXJmYWNlQWRkcmVzcz4gZ2V0SW50ZXJmYWNlQWRkcmVzc2VzKCkgeworICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChpbnRlcmZhY2VBZGRyZXNzZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gZW51bWVyYXRpb24gb2YgYWxsIHRoZSBzdWItaW50ZXJmYWNlcyBvZiB0aGlzIG5ldHdvcmsgaW50ZXJmYWNlLgorICAgICAqIFN1Yi1pbnRlcmZhY2VzIGFyZSBhbHNvIGtub3duIGFzIHZpcnR1YWwgaW50ZXJmYWNlcy4KKyAgICAgKgorICAgICAqIDxwPkZvciBleGFtcGxlLCB7QGNvZGUgZXRoMDoxfSB3b3VsZCBiZSBhIHN1Yi1pbnRlcmZhY2Ugb2Yge0Bjb2RlIGV0aDB9LgorICAgICAqCisgICAgICogQHJldHVybiBhbiBFbnVtZXJhdGlvbiBvZiBhbGwgdGhlIHN1Yi1pbnRlcmZhY2VzIG9mIHRoaXMgbmV0d29yayBpbnRlcmZhY2UKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIEVudW1lcmF0aW9uPE5ldHdvcmtJbnRlcmZhY2U+IGdldFN1YkludGVyZmFjZXMoKSB7CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbnVtZXJhdGlvbihjaGlsZHJlbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGFyZW50IE5ldHdvcmtJbnRlcmZhY2Ugb2YgdGhpcyBpbnRlcmZhY2UgaWYgdGhpcyBpcyBhCisgICAgICogc3ViLWludGVyZmFjZSwgb3IgbnVsbCBpZiBpdCdzIGEgcGh5c2ljYWwgKG5vbiB2aXJ0dWFsKSBpbnRlcmZhY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBOZXR3b3JrSW50ZXJmYWNlIHRoaXMgaW50ZXJmYWNlIGlzIGF0dGFjaGVkIHRvLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgTmV0d29ya0ludGVyZmFjZSBnZXRQYXJlbnQoKSB7CisgICAgICAgIHJldHVybiBwYXJlbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgbmV0d29yayBpbnRlcmZhY2UgaXMgdXAuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGludGVyZmFjZSBpcyB1cC4KKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1VwKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBoYXNGbGFnKElGRl9VUCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgbmV0d29yayBpbnRlcmZhY2UgaXMgYSBsb29wYmFjayBpbnRlcmZhY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGludGVyZmFjZSBpcyBhIGxvb3BiYWNrIGludGVyZmFjZS4KKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0xvb3BiYWNrKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBoYXNGbGFnKElGRl9MT09QQkFDSyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgbmV0d29yayBpbnRlcmZhY2UgaXMgYSBwb2ludC10by1wb2ludCBpbnRlcmZhY2UuCisgICAgICogKEZvciBleGFtcGxlLCBhIFBQUCBjb25uZWN0aW9uIHVzaW5nIGEgbW9kZW0uKQorICAgICAqCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBpbnRlcmZhY2UgaXMgcG9pbnQtdG8tcG9pbnQuCisgICAgICogQHRocm93cyBTb2NrZXRFeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNQb2ludFRvUG9pbnQoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGhhc0ZsYWcoSUZGX1BPSU5UT1BPSU5UKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBuZXR3b3JrIGludGVyZmFjZSBzdXBwb3J0cyBtdWx0aWNhc3QuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c011bHRpY2FzdCgpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gaGFzRmxhZyhJRkZfTVVMVElDQVNUKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaGFzRmxhZyhpbnQgbWFzaykgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBmbGFncyA9IHJlYWRJbnRGaWxlKCIvc3lzL2NsYXNzL25ldC8iICsgbmFtZSArICIvZmxhZ3MiKTsKKyAgICAgICAgcmV0dXJuIChmbGFncyAmIG1hc2spICE9IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaGFyZHdhcmUgYWRkcmVzcyBvZiB0aGUgaW50ZXJmYWNlLCBpZiBpdCBoYXMgb25lLCBvciBudWxsIG90aGVyd2lzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0SGFyZHdhcmVBZGRyZXNzKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBQYXJzZSBjb2xvbi1zZXBhcmF0ZWQgYnl0ZXMgd2l0aCBhIHRyYWlsaW5nIG5ld2xpbmU6ICJhYTpiYjpjYzpkZDplZTpmZlxuIi4KKyAgICAgICAgICAgIFN0cmluZyBzID0gSW9VdGlscy5yZWFkRmlsZUFzU3RyaW5nKCIvc3lzL2NsYXNzL25ldC8iICsgbmFtZSArICIvYWRkcmVzcyIpOworICAgICAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW3MubGVuZ3RoKCkvM107CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlc3VsdC5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgICAgIHJlc3VsdFtpXSA9IChieXRlKSBJbnRlZ2VyLnBhcnNlSW50KHMuc3Vic3RyaW5nKDMqaSwgMyppICsgMiksIDE2KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIFdlIG9ubHkgd2FudCB0byByZXR1cm4gbm9uLXplcm8gaGFyZHdhcmUgYWRkcmVzc2VzLgorICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXN1bHQubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICBpZiAocmVzdWx0W2ldICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyByZXRocm93QXNTb2NrZXRFeGNlcHRpb24oZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgTWF4aW11bSBUcmFuc21pc3Npb24gVW5pdCAoTVRVKSBvZiB0aGlzIGludGVyZmFjZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBNVFUgZm9yIHRoZSBpbnRlcmZhY2UuCisgICAgICogQHRocm93cyBTb2NrZXRFeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIGludCBnZXRNVFUoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHJlYWRJbnRGaWxlKCIvc3lzL2NsYXNzL25ldC8iICsgbmFtZSArICIvbXR1Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgaW50ZXJmYWNlIGlzIGEgdmlydHVhbCBpbnRlcmZhY2UgKGFsc28gY2FsbGVkCisgICAgICogYSBzdWItaW50ZXJmYWNlKS4gVmlydHVhbCBpbnRlcmZhY2VzIGFyZSwgb24gc29tZSBzeXN0ZW1zLCBpbnRlcmZhY2VzCisgICAgICogY3JlYXRlZCBhcyBhIGNoaWxkIG9mIGEgcGh5c2ljYWwgaW50ZXJmYWNlIGFuZCBnaXZlbiBkaWZmZXJlbnQgc2V0dGluZ3MKKyAgICAgKiAobGlrZSBhZGRyZXNzIG9yIE1UVSkuIFVzdWFsbHkgdGhlIG5hbWUgb2YgdGhlIGludGVyZmFjZSB3aWxsIHRoZSBuYW1lIG9mCisgICAgICogdGhlIHBhcmVudCBmb2xsb3dlZCBieSBhIGNvbG9uICg6KSBhbmQgYSBudW1iZXIgaWRlbnRpZnlpbmcgdGhlIGNoaWxkLAorICAgICAqIHNpbmNlIHRoZXJlIGNhbiBiZSBzZXZlcmFsIHZpcnR1YWwgaW50ZXJmYWNlcyBhdHRhY2hlZCB0byBhIHNpbmdsZQorICAgICAqIHBoeXNpY2FsIGludGVyZmFjZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGludGVyZmFjZSBpcyBhIHZpcnR1YWwgaW50ZXJmYWNlLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1ZpcnR1YWwoKSB7CisgICAgICAgIHJldHVybiBwYXJlbnQgIT0gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvTm9Sb3V0ZVRvSG9zdEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L05vUm91dGVUb0hvc3RFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YjJiMjU1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L05vUm91dGVUb0hvc3RFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDUyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCisvKioKKyAqIFRoZSB7QGNvZGUgTm9Sb3V0ZVRvSG9zdEV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gd2hpbGUgYXR0ZW1wdGluZyB0byBjb25uZWN0CisgKiB0byBhIHJlbW90ZSBob3N0IGJ1dCB0aGUgaG9zdCBjYW5ub3QgYmUgcmVhY2hlZCBmb3IgaW5zdGFuY2UgYmVjYXVzZSBvZiBhCisgKiBiYWRseSBjb25maWd1cmVkIHJvdXRlciBvciBhIGJsb2NraW5nIGZpcmV3YWxsLgorICoKKyAqIDxwPk1vc3QgYXBwbGljYXRpb25zIDxzdHJvbmc+c2hvdWxkIG5vdDwvc3Ryb25nPiBjYXRjaCB0aGlzIGV4Y2VwdGlvbjsgaXQgaXMKKyAqIG1vcmUgcm9idXN0IHRvIGNhdGNoIHRoZSBzdXBlcmNsYXNzIHtAY29kZSBTb2NrZXRFeGNlcHRpb259LgorICovCitwdWJsaWMgY2xhc3MgTm9Sb3V0ZVRvSG9zdEV4Y2VwdGlvbiBleHRlbmRzIFNvY2tldEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTg5NzU1MDg5NDg3MzQ5Mzc5MEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBOb1JvdXRlVG9Ib3N0RXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugd2l0aCB0aGUgZ2l2ZW4gZGV0YWlsIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIE5vUm91dGVUb0hvc3RFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSB3aXRoIGdpdmVuIGRldGFpbCBtZXNzYWdlIGFuZCBjYXVzZS4KKyAgICAgKiBAaGlkZSBpbnRlcm5hbCB1c2Ugb25seQorICAgICAqLworICAgIHB1YmxpYyBOb1JvdXRlVG9Ib3N0RXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSwgY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9QYXNzd29yZEF1dGhlbnRpY2F0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvUGFzc3dvcmRBdXRoZW50aWNhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhYWMyMDQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvUGFzc3dvcmRBdXRoZW50aWNhdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKKy8qKgorICogVGhpcyBpbW11dGFibGUgY2xhc3MgaXMgYSBkYXRhIHN0cnVjdHVyZSB0aGF0IGVuY2Fwc3VsYXRlcyB1c2VybmFtZSBhbmQKKyAqIHBhc3N3b3JkIHdoaWNoIGlzIHVzZWQgYnkgdGhlIHtAY29kZSBBdXRoZW50aWNhdG9yfSBjbGFzcy4KKyAqCisgKiBAc2VlIEF1dGhlbnRpY2F0b3IKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFBhc3N3b3JkQXV0aGVudGljYXRpb24geworCisgICAgcHJpdmF0ZSBTdHJpbmcgdXNlck5hbWU7CisKKyAgICBwcml2YXRlIGNoYXJbXSBwYXNzd29yZDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgYSBwYXNzd29yZCBhdXRoZW50aWNhdGlvbiB3aXRoIGEgc3BlY2lmaWVkCisgICAgICogdXNlcm5hbWUgYW5kIHBhc3N3b3JkLgorICAgICAqCisgICAgICogQHBhcmFtIHVzZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgdXNlcm5hbWUgdG8gc3RvcmUuCisgICAgICogQHBhcmFtIHBhc3N3b3JkCisgICAgICogICAgICAgICAgICB0aGUgYXNzb2NpYXRlZCBwYXNzd29yZCB0byBzdG9yZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFzc3dvcmRBdXRoZW50aWNhdGlvbihTdHJpbmcgdXNlck5hbWUsIGNoYXJbXSBwYXNzd29yZCkgeworICAgICAgICB0aGlzLnVzZXJOYW1lID0gdXNlck5hbWU7CisgICAgICAgIHRoaXMucGFzc3dvcmQgPSBwYXNzd29yZC5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBjbG9uZSBvZiB0aGUgcGFzc3dvcmQgc3RvcmVkIGJ5IHRoaXMgaW5zdGFuY2UuIFRoZSB1c2VyIGlzCisgICAgICogcmVzcG9uc2libGUgdG8gZmluYWxpemUgdGhlIHJldHVybmVkIGFycmF5IGlmIHRoZSBwYXNzd29yZCBjbG9uZSBpcyBubworICAgICAqIGxvbmdlciBuZWVkZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb3BpZWQgcGFzc3dvcmQuCisgICAgICovCisgICAgcHVibGljIGNoYXJbXSBnZXRQYXNzd29yZCgpIHsKKyAgICAgICAgcmV0dXJuIHBhc3N3b3JkLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdXNlcm5hbWUgc3RvcmVkIGJ5IHRoaXMgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdG9yZWQgdXNlcm5hbWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRVc2VyTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIHVzZXJOYW1lOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9QbGFpbkRhdGFncmFtU29ja2V0SW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1BsYWluRGF0YWdyYW1Tb2NrZXRJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWQwMTQ2OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9QbGFpbkRhdGFncmFtU29ja2V0SW1wbC5qYXZhCkBAIC0wLDAgKzEsMjM4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgZGFsdmlrLnN5c3RlbS5DbG9zZUd1YXJkOworaW1wb3J0IGphdmEuaW8uRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5EYXRhZ3JhbVBhY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldEltcGw7CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuTmV0d29ya0ludGVyZmFjZTsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNvY2tldEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKK2ltcG9ydCBsaWJjb3JlLmlvLkVycm5vRXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUuaW8uSW9CcmlkZ2U7CitpbXBvcnQgbGliY29yZS5pby5MaWJjb3JlOworaW1wb3J0IGxpYmNvcmUuaW8uU3RydWN0R3JvdXBSZXE7CitpbXBvcnQgbGliY29yZS51dGlsLkVtcHR5QXJyYXk7CitpbXBvcnQgc3RhdGljIGxpYmNvcmUuaW8uT3NDb25zdGFudHMuKjsKKworLyoqCisgKiBAaGlkZSB1c2VkIGluIGphdmEubmlvLgorICovCitwdWJsaWMgY2xhc3MgUGxhaW5EYXRhZ3JhbVNvY2tldEltcGwgZXh0ZW5kcyBEYXRhZ3JhbVNvY2tldEltcGwgeworCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIGlzTmF0aXZlQ29ubmVjdGVkOworCisgICAgcHJpdmF0ZSBmaW5hbCBDbG9zZUd1YXJkIGd1YXJkID0gQ2xvc2VHdWFyZC5nZXQoKTsKKworICAgIC8qKgorICAgICAqIHVzZWQgdG8ga2VlcCBhZGRyZXNzIHRvIHdoaWNoIHRoZSBzb2NrZXQgd2FzIGNvbm5lY3RlZCB0byBhdCB0aGUgbmF0aXZlCisgICAgICogbGV2ZWwKKyAgICAgKi8KKyAgICBwcml2YXRlIEluZXRBZGRyZXNzIGNvbm5lY3RlZEFkZHJlc3M7CisKKyAgICBwcml2YXRlIGludCBjb25uZWN0ZWRQb3J0ID0gLTE7CisKKyAgICBwdWJsaWMgUGxhaW5EYXRhZ3JhbVNvY2tldEltcGwoRmlsZURlc2NyaXB0b3IgZmQsIGludCBsb2NhbFBvcnQpIHsKKyAgICAgICAgdGhpcy5mZCA9IGZkOworICAgICAgICB0aGlzLmxvY2FsUG9ydCA9IGxvY2FsUG9ydDsKKyAgICAgICAgaWYgKGZkLnZhbGlkKCkpIHsKKyAgICAgICAgICAgIGd1YXJkLm9wZW4oImNsb3NlIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgUGxhaW5EYXRhZ3JhbVNvY2tldEltcGwoKSB7CisgICAgICAgIGZkID0gbmV3IEZpbGVEZXNjcmlwdG9yKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGJpbmQoaW50IHBvcnQsIEluZXRBZGRyZXNzIGFkZHJlc3MpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBJb0JyaWRnZS5iaW5kKGZkLCBhZGRyZXNzLCBwb3J0KTsKKyAgICAgICAgaWYgKHBvcnQgIT0gMCkgeworICAgICAgICAgICAgbG9jYWxQb3J0ID0gcG9ydDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGxvY2FsUG9ydCA9IElvQnJpZGdlLmdldFNvY2tldExvY2FsUG9ydChmZCk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldE9wdGlvbihTb2NrZXRPcHRpb25zLlNPX0JST0FEQ0FTVCwgQm9vbGVhbi5UUlVFKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNsb3NlKCkgeworICAgICAgICBndWFyZC5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW9CcmlkZ2UuY2xvc2VTb2NrZXQoZmQpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjcmVhdGUoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5mZCA9IElvQnJpZGdlLnNvY2tldChmYWxzZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoZ3VhcmQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGd1YXJkLndhcm5JZk9wZW4oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNsb3NlKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzdXBlci5maW5hbGl6ZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0T3B0aW9uKGludCBvcHRpb24pIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gSW9CcmlkZ2UuZ2V0U29ja2V0T3B0aW9uKGZkLCBvcHRpb24pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0VGltZVRvTGl2ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiAoSW50ZWdlcikgZ2V0T3B0aW9uKElvQnJpZGdlLkpBVkFfSVBfTVVMVElDQVNUX1RUTCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGUgZ2V0VFRMKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIChieXRlKSBnZXRUaW1lVG9MaXZlKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RydWN0R3JvdXBSZXEgbWFrZUdyb3VwUmVxKEluZXRBZGRyZXNzIGdyX2dyb3VwLCBOZXR3b3JrSW50ZXJmYWNlIG5ldHdvcmtJbnRlcmZhY2UpIHsKKyAgICAgICAgaW50IGdyX2ludGVyZmFjZSA9IChuZXR3b3JrSW50ZXJmYWNlICE9IG51bGwpID8gbmV0d29ya0ludGVyZmFjZS5nZXRJbmRleCgpIDogMDsKKyAgICAgICAgcmV0dXJuIG5ldyBTdHJ1Y3RHcm91cFJlcShncl9pbnRlcmZhY2UsIGdyX2dyb3VwKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBqb2luKEluZXRBZGRyZXNzIGFkZHIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHNldE9wdGlvbihJb0JyaWRnZS5KQVZBX01DQVNUX0pPSU5fR1JPVVAsIG1ha2VHcm91cFJlcShhZGRyLCBudWxsKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgam9pbkdyb3VwKFNvY2tldEFkZHJlc3MgYWRkciwgTmV0d29ya0ludGVyZmFjZSBuZXRJbnRlcmZhY2UpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhZGRyIGluc3RhbmNlb2YgSW5ldFNvY2tldEFkZHJlc3MpIHsKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIGdyb3VwQWRkciA9ICgoSW5ldFNvY2tldEFkZHJlc3MpIGFkZHIpLmdldEFkZHJlc3MoKTsKKyAgICAgICAgICAgIHNldE9wdGlvbihJb0JyaWRnZS5KQVZBX01DQVNUX0pPSU5fR1JPVVAsIG1ha2VHcm91cFJlcShncm91cEFkZHIsIG5ldEludGVyZmFjZSkpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgbGVhdmUoSW5ldEFkZHJlc3MgYWRkcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc2V0T3B0aW9uKElvQnJpZGdlLkpBVkFfTUNBU1RfTEVBVkVfR1JPVVAsIG1ha2VHcm91cFJlcShhZGRyLCBudWxsKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgbGVhdmVHcm91cChTb2NrZXRBZGRyZXNzIGFkZHIsIE5ldHdvcmtJbnRlcmZhY2UgbmV0SW50ZXJmYWNlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoYWRkciBpbnN0YW5jZW9mIEluZXRTb2NrZXRBZGRyZXNzKSB7CisgICAgICAgICAgICBJbmV0QWRkcmVzcyBncm91cEFkZHIgPSAoKEluZXRTb2NrZXRBZGRyZXNzKSBhZGRyKS5nZXRBZGRyZXNzKCk7CisgICAgICAgICAgICBzZXRPcHRpb24oSW9CcmlkZ2UuSkFWQV9NQ0FTVF9MRUFWRV9HUk9VUCwgbWFrZUdyb3VwUmVxKGdyb3VwQWRkciwgbmV0SW50ZXJmYWNlKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IHBlZWsoSW5ldEFkZHJlc3Mgc2VuZGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBXZSBkb24ndCBhY3R1YWxseSB3YW50IHRoZSBkYXRhOiB3ZSBqdXN0IHdhbnQgdGhlIERhdGFncmFtUGFja2V0J3MgZmlsbGVkLWluIGFkZHJlc3MuCisgICAgICAgIERhdGFncmFtUGFja2V0IHBhY2tldCA9IG5ldyBEYXRhZ3JhbVBhY2tldChFbXB0eUFycmF5LkJZVEUsIDApOworICAgICAgICBpbnQgcmVzdWx0ID0gcGVla0RhdGEocGFja2V0KTsKKyAgICAgICAgLy8gTm90ZTogZXZpbCBzaWRlLWVmZmVjdCBvbiBJbmV0QWRkcmVzcyEgVGhpcyBtZXRob2Qgc2hvdWxkIGhhdmUgcmV0dXJuZWQgSW5ldFNvY2tldEFkZHJlc3MhCisgICAgICAgIHNlbmRlci5pcGFkZHJlc3MgPSBwYWNrZXQuZ2V0QWRkcmVzcygpLmdldEFkZHJlc3MoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZG9SZWN2KERhdGFncmFtUGFja2V0IHBhY2ssIGludCBmbGFncykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSW9CcmlkZ2UucmVjdmZyb20oZmFsc2UsIGZkLCBwYWNrLmdldERhdGEoKSwgcGFjay5nZXRPZmZzZXQoKSwgcGFjay5nZXRMZW5ndGgoKSwgZmxhZ3MsIHBhY2ssIGlzTmF0aXZlQ29ubmVjdGVkKTsKKyAgICAgICAgaWYgKGlzTmF0aXZlQ29ubmVjdGVkKSB7CisgICAgICAgICAgICB1cGRhdGVQYWNrZXRSZWN2QWRkcmVzcyhwYWNrKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJlY2VpdmUoRGF0YWdyYW1QYWNrZXQgcGFjaykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZG9SZWN2KHBhY2ssIDApOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcGVla0RhdGEoRGF0YWdyYW1QYWNrZXQgcGFjaykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZG9SZWN2KHBhY2ssIE1TR19QRUVLKTsKKyAgICAgICAgcmV0dXJuIHBhY2suZ2V0UG9ydCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNlbmQoRGF0YWdyYW1QYWNrZXQgcGFja2V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgcG9ydCA9IGlzTmF0aXZlQ29ubmVjdGVkID8gMCA6IHBhY2tldC5nZXRQb3J0KCk7CisgICAgICAgIEluZXRBZGRyZXNzIGFkZHJlc3MgPSBpc05hdGl2ZUNvbm5lY3RlZCA/IG51bGwgOiBwYWNrZXQuZ2V0QWRkcmVzcygpOworICAgICAgICBJb0JyaWRnZS5zZW5kdG8oZmQsIHBhY2tldC5nZXREYXRhKCksIHBhY2tldC5nZXRPZmZzZXQoKSwgcGFja2V0LmdldExlbmd0aCgpLCAwLCBhZGRyZXNzLCBwb3J0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRPcHRpb24oaW50IG9wdGlvbiwgT2JqZWN0IHZhbHVlKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgSW9CcmlkZ2Uuc2V0U29ja2V0T3B0aW9uKGZkLCBvcHRpb24sIHZhbHVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lVG9MaXZlKGludCB0dGwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHNldE9wdGlvbihJb0JyaWRnZS5KQVZBX0lQX01VTFRJQ0FTVF9UVEwsIEludGVnZXIudmFsdWVPZih0dGwpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRUVEwoYnl0ZSB0dGwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHNldFRpbWVUb0xpdmUoKGludCkgdHRsICYgMHhmZik7IC8vIEF2b2lkIHNpZ24gZXh0ZW5zaW9uLgorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNvbm5lY3QoSW5ldEFkZHJlc3MgaW5ldEFkZHIsIGludCBwb3J0KSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgSW9CcmlkZ2UuY29ubmVjdChmZCwgaW5ldEFkZHIsIHBvcnQpOyAvLyBUaHJvd3Mgb24gZmFpbHVyZS4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm5lY3RlZEFkZHJlc3MgPSBJbmV0QWRkcmVzcy5nZXRCeUFkZHJlc3MoaW5ldEFkZHIuZ2V0QWRkcmVzcygpKTsKKyAgICAgICAgfSBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gdGhpcyBpcyBuZXZlciBleHBlY3RlZCB0byBoYXBwZW4gYXMgd2Ugc2hvdWxkIG5vdCBoYXZlIGdvdHRlbgorICAgICAgICAgICAgLy8gaGVyZSBpZiB0aGUgYWRkcmVzcyBpcyBub3QgcmVzb2x2YWJsZQorICAgICAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbigiSG9zdCBpcyB1bnJlc29sdmVkOiAiICsgaW5ldEFkZHIuZ2V0SG9zdE5hbWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgY29ubmVjdGVkUG9ydCA9IHBvcnQ7CisgICAgICAgIGlzTmF0aXZlQ29ubmVjdGVkID0gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkaXNjb25uZWN0KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgTGliY29yZS5vcy5jb25uZWN0KGZkLCBJbmV0QWRkcmVzcy5VTlNQRUNJRklFRCwgMCk7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZXJybm9FeGNlcHRpb24pOworICAgICAgICB9CisgICAgICAgIGNvbm5lY3RlZFBvcnQgPSAtMTsKKyAgICAgICAgY29ubmVjdGVkQWRkcmVzcyA9IG51bGw7CisgICAgICAgIGlzTmF0aXZlQ29ubmVjdGVkID0gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSByZWNlaXZlZCBhZGRyZXNzIGFuZCBwb3J0IGluIHRoZSBwYWNrZXQuIFdlIGRvIHRoaXMgd2hlbiB0aGUKKyAgICAgKiBEYXRhZ3JhbSBzb2NrZXQgaXMgY29ubmVjdGVkIGF0IHRoZSBuYXRpdmUgbGV2ZWwgYW5kIHRoZQorICAgICAqIHJlY3ZDb25ubmVjdGVkRGF0YWdyYW1JbXBsIGRvZXMgbm90IHVwZGF0ZSB0aGUgcGFja2V0IHdpdGggYWRkcmVzcyBmcm9tCisgICAgICogd2hpY2ggdGhlIHBhY2tldCB3YXMgcmVjZWl2ZWQKKyAgICAgKgorICAgICAqIEBwYXJhbSBwYWNrZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYWNrZXQgdG8gYmUgdXBkYXRlZAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB1cGRhdGVQYWNrZXRSZWN2QWRkcmVzcyhEYXRhZ3JhbVBhY2tldCBwYWNrZXQpIHsKKyAgICAgICAgcGFja2V0LnNldEFkZHJlc3MoY29ubmVjdGVkQWRkcmVzcyk7CisgICAgICAgIHBhY2tldC5zZXRQb3J0KGNvbm5lY3RlZFBvcnQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9QbGFpblNlcnZlclNvY2tldEltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9QbGFpblNlcnZlclNvY2tldEltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZmMxYTlkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1BsYWluU2VydmVyU29ja2V0SW1wbC5qYXZhCkBAIC0wLDAgKzEsNDMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuU29ja2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlNvY2tldE9wdGlvbnM7CisKKy8qKgorICogQGhpZGUgdXNlZCBpbiBqYXZhLm5pby4KKyAqLworcHVibGljIGNsYXNzIFBsYWluU2VydmVyU29ja2V0SW1wbCBleHRlbmRzIFBsYWluU29ja2V0SW1wbCB7CisgICAgcHVibGljIFBsYWluU2VydmVyU29ja2V0SW1wbCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgUGxhaW5TZXJ2ZXJTb2NrZXRJbXBsKEZpbGVEZXNjcmlwdG9yIGZkKSB7CisgICAgICAgIHN1cGVyKGZkKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoYm9vbGVhbiBpc1N0cmVhbWluZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuY3JlYXRlKGlzU3RyZWFtaW5nKTsKKyAgICAgICAgaWYgKGlzU3RyZWFtaW5nKSB7CisgICAgICAgICAgICBzZXRPcHRpb24oU29ja2V0T3B0aW9ucy5TT19SRVVTRUFERFIsIEJvb2xlYW4uVFJVRSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvUGxhaW5Tb2NrZXRJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvUGxhaW5Tb2NrZXRJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjBkZmNjMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9QbGFpblNvY2tldEltcGwuamF2YQpAQCAtMCwwICsxLDUxOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworaW1wb3J0IGRhbHZpay5zeXN0ZW0uQ2xvc2VHdWFyZDsKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5Db25uZWN0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlByb3h5OworaW1wb3J0IGphdmEubmV0LlNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlNvY2tldEltcGw7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0VGltZW91dEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlT3JkZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBsaWJjb3JlLmlvLkVycm5vRXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUuaW8uSW9CcmlkZ2U7CitpbXBvcnQgbGliY29yZS5pby5MaWJjb3JlOworaW1wb3J0IGxpYmNvcmUuaW8uTWVtb3J5OworaW1wb3J0IGxpYmNvcmUuaW8uU3RyZWFtczsKK2ltcG9ydCBzdGF0aWMgbGliY29yZS5pby5Pc0NvbnN0YW50cy4qOworCisvKioKKyAqIEBoaWRlIHVzZWQgaW4gamF2YS5uaW8uCisgKi8KK3B1YmxpYyBjbGFzcyBQbGFpblNvY2tldEltcGwgZXh0ZW5kcyBTb2NrZXRJbXBsIHsKKworICAgIC8vIEZvciBTT0NLUyBzdXBwb3J0LiBBIFNPQ0tTIGJpbmQoKSB1c2VzIHRoZSBsYXN0CisgICAgLy8gaG9zdCBjb25uZWN0ZWQgdG8gaW4gaXRzIHJlcXVlc3QuCisgICAgcHJpdmF0ZSBzdGF0aWMgSW5ldEFkZHJlc3MgbGFzdENvbm5lY3RlZEFkZHJlc3M7CisKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgbGFzdENvbm5lY3RlZFBvcnQ7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gc3RyZWFtaW5nID0gdHJ1ZTsKKworICAgIHByaXZhdGUgYm9vbGVhbiBzaHV0ZG93bklucHV0OworCisgICAgcHJpdmF0ZSBQcm94eSBwcm94eTsKKworICAgIHByaXZhdGUgZmluYWwgQ2xvc2VHdWFyZCBndWFyZCA9IENsb3NlR3VhcmQuZ2V0KCk7CisKKyAgICBwdWJsaWMgUGxhaW5Tb2NrZXRJbXBsKEZpbGVEZXNjcmlwdG9yIGZkKSB7CisgICAgICAgIHRoaXMuZmQgPSBmZDsKKyAgICAgICAgaWYgKGZkLnZhbGlkKCkpIHsKKyAgICAgICAgICAgIGd1YXJkLm9wZW4oImNsb3NlIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgUGxhaW5Tb2NrZXRJbXBsKFByb3h5IHByb3h5KSB7CisgICAgICAgIHRoaXMobmV3IEZpbGVEZXNjcmlwdG9yKCkpOworICAgICAgICB0aGlzLnByb3h5ID0gcHJveHk7CisgICAgfQorCisgICAgcHVibGljIFBsYWluU29ja2V0SW1wbCgpIHsKKyAgICAgICAgdGhpcyhuZXcgRmlsZURlc2NyaXB0b3IoKSk7CisgICAgfQorCisgICAgcHVibGljIFBsYWluU29ja2V0SW1wbChGaWxlRGVzY3JpcHRvciBmZCwgaW50IGxvY2FscG9ydCwgSW5ldEFkZHJlc3MgYWRkciwgaW50IHBvcnQpIHsKKyAgICAgICAgdGhpcy5mZCA9IGZkOworICAgICAgICB0aGlzLmxvY2FscG9ydCA9IGxvY2FscG9ydDsKKyAgICAgICAgdGhpcy5hZGRyZXNzID0gYWRkcjsKKyAgICAgICAgdGhpcy5wb3J0ID0gcG9ydDsKKyAgICAgICAgaWYgKGZkLnZhbGlkKCkpIHsKKyAgICAgICAgICAgIGd1YXJkLm9wZW4oImNsb3NlIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBhY2NlcHQoU29ja2V0SW1wbCBuZXdJbXBsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodXNpbmdTb2NrcygpKSB7CisgICAgICAgICAgICAoKFBsYWluU29ja2V0SW1wbCkgbmV3SW1wbCkuc29ja3NCaW5kKCk7CisgICAgICAgICAgICAoKFBsYWluU29ja2V0SW1wbCkgbmV3SW1wbCkuc29ja3NBY2NlcHQoKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBwZWVyQWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcygpOworICAgICAgICAgICAgRmlsZURlc2NyaXB0b3IgY2xpZW50RmQgPSBMaWJjb3JlLm9zLmFjY2VwdChmZCwgcGVlckFkZHJlc3MpOworCisgICAgICAgICAgICAvLyBUT0RPOiB3ZSBjYW4ndCBqdXN0IHNldCBuZXdJbXBsLmZkIHRvIGNsaWVudEZkIGJlY2F1c2UgYSBuaW8gU29ja2V0Q2hhbm5lbCBtYXkKKyAgICAgICAgICAgIC8vIGJlIHNoYXJpbmcgdGhlIEZpbGVEZXNjcmlwdG9yLiBodHRwOi8vYi8vNDQ1Mjk4MS4KKyAgICAgICAgICAgIG5ld0ltcGwuZmQuc2V0SW50JChjbGllbnRGZC5nZXRJbnQkKCkpOworCisgICAgICAgICAgICBuZXdJbXBsLmFkZHJlc3MgPSBwZWVyQWRkcmVzcy5nZXRBZGRyZXNzKCk7CisgICAgICAgICAgICBuZXdJbXBsLnBvcnQgPSBwZWVyQWRkcmVzcy5nZXRQb3J0KCk7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICBpZiAoZXJybm9FeGNlcHRpb24uZXJybm8gPT0gRUFHQUlOIHx8IGVycm5vRXhjZXB0aW9uLmVycm5vID09IEVXT1VMREJMT0NLKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNvY2tldFRpbWVvdXRFeGNlcHRpb24oZXJybm9FeGNlcHRpb24pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzU29ja2V0RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBSZXNldCB0aGUgY2xpZW50J3MgaW5oZXJpdGVkIHJlYWQgdGltZW91dCB0byB0aGUgSmF2YS1zcGVjaWZpZWQgZGVmYXVsdCBvZiAwLgorICAgICAgICBuZXdJbXBsLnNldE9wdGlvbihTb2NrZXRPcHRpb25zLlNPX1RJTUVPVVQsIEludGVnZXIudmFsdWVPZigwKSk7CisKKyAgICAgICAgbmV3SW1wbC5sb2NhbHBvcnQgPSBJb0JyaWRnZS5nZXRTb2NrZXRMb2NhbFBvcnQobmV3SW1wbC5mZCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIHVzaW5nU29ja3MoKSB7CisgICAgICAgIHJldHVybiBwcm94eSAhPSBudWxsICYmIHByb3h5LnR5cGUoKSA9PSBQcm94eS5UeXBlLlNPQ0tTOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGluaXRMb2NhbFBvcnQoaW50IGxvY2FsUG9ydCkgeworICAgICAgICB0aGlzLmxvY2FscG9ydCA9IGxvY2FsUG9ydDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBpbml0UmVtb3RlQWRkcmVzc0FuZFBvcnQoSW5ldEFkZHJlc3MgcmVtb3RlQWRkcmVzcywgaW50IHJlbW90ZVBvcnQpIHsKKyAgICAgICAgdGhpcy5hZGRyZXNzID0gcmVtb3RlQWRkcmVzczsKKyAgICAgICAgdGhpcy5wb3J0ID0gcmVtb3RlUG9ydDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tOb3RDbG9zZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIWZkLnZhbGlkKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oIlNvY2tldCBpcyBjbG9zZWQiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBzeW5jaHJvbml6ZWQgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgIC8vIHdlIG5lZWQgdG8gY2hlY2sgaWYgdGhlIGlucHV0IGhhcyBiZWVuIHNodXRkb3duLiBJZiBzbworICAgICAgICAvLyB3ZSBzaG91bGQgcmV0dXJuIHRoYXQgdGhlcmUgaXMgbm8gZGF0YSB0byBiZSByZWFkCisgICAgICAgIGlmIChzaHV0ZG93bklucHV0KSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gSW9CcmlkZ2UuYXZhaWxhYmxlKGZkKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgYmluZChJbmV0QWRkcmVzcyBhZGRyZXNzLCBpbnQgcG9ydCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSW9CcmlkZ2UuYmluZChmZCwgYWRkcmVzcywgcG9ydCk7CisgICAgICAgIHRoaXMuYWRkcmVzcyA9IGFkZHJlc3M7CisgICAgICAgIGlmIChwb3J0ICE9IDApIHsKKyAgICAgICAgICAgIHRoaXMubG9jYWxwb3J0ID0gcG9ydDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRoaXMubG9jYWxwb3J0ID0gSW9CcmlkZ2UuZ2V0U29ja2V0TG9jYWxQb3J0KGZkKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGd1YXJkLmNsb3NlKCk7CisgICAgICAgIElvQnJpZGdlLmNsb3NlU29ja2V0KGZkKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBjb25uZWN0KFN0cmluZyBhSG9zdCwgaW50IGFQb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjb25uZWN0KEluZXRBZGRyZXNzLmdldEJ5TmFtZShhSG9zdCksIGFQb3J0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBjb25uZWN0KEluZXRBZGRyZXNzIGFuQWRkciwgaW50IGFQb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjb25uZWN0KGFuQWRkciwgYVBvcnQsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbm5lY3RzIHRoaXMgc29ja2V0IHRvIHRoZSBzcGVjaWZpZWQgcmVtb3RlIGhvc3QgYWRkcmVzcy9wb3J0LgorICAgICAqCisgICAgICogQHBhcmFtIGFuQWRkcgorICAgICAqICAgICAgICAgICAgdGhlIHJlbW90ZSBob3N0IGFkZHJlc3MgdG8gY29ubmVjdCB0bworICAgICAqIEBwYXJhbSBhUG9ydAorICAgICAqICAgICAgICAgICAgdGhlIHJlbW90ZSBwb3J0IHRvIGNvbm5lY3QgdG8KKyAgICAgKiBAcGFyYW0gdGltZW91dAorICAgICAqICAgICAgICAgICAgYSB0aW1lb3V0IHdoZXJlIHN1cHBvcnRlZC4gMCBtZWFucyBubyB0aW1lb3V0CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjb25uZWN0aW5nCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNvbm5lY3QoSW5ldEFkZHJlc3MgYW5BZGRyLCBpbnQgYVBvcnQsIGludCB0aW1lb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBJbmV0QWRkcmVzcyBub3JtYWxBZGRyID0gYW5BZGRyLmlzQW55TG9jYWxBZGRyZXNzKCkgPyBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSA6IGFuQWRkcjsKKyAgICAgICAgaWYgKHN0cmVhbWluZyAmJiB1c2luZ1NvY2tzKCkpIHsKKyAgICAgICAgICAgIHNvY2tzQ29ubmVjdChhbkFkZHIsIGFQb3J0LCAwKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIElvQnJpZGdlLmNvbm5lY3QoZmQsIG5vcm1hbEFkZHIsIGFQb3J0LCB0aW1lb3V0KTsKKyAgICAgICAgfQorICAgICAgICBzdXBlci5hZGRyZXNzID0gbm9ybWFsQWRkcjsKKyAgICAgICAgc3VwZXIucG9ydCA9IGFQb3J0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGNyZWF0ZShib29sZWFuIHN0cmVhbWluZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5zdHJlYW1pbmcgPSBzdHJlYW1pbmc7CisgICAgICAgIHRoaXMuZmQgPSBJb0JyaWRnZS5zb2NrZXQoc3RyZWFtaW5nKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChndWFyZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZ3VhcmQud2FybklmT3BlbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2xvc2UoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHN1cGVyLmZpbmFsaXplKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHN5bmNocm9uaXplZCBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgIHJldHVybiBuZXcgUGxhaW5Tb2NrZXRJbnB1dFN0cmVhbSh0aGlzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBQbGFpblNvY2tldElucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworICAgICAgICBwcml2YXRlIGZpbmFsIFBsYWluU29ja2V0SW1wbCBzb2NrZXRJbXBsOworCisgICAgICAgIHB1YmxpYyBQbGFpblNvY2tldElucHV0U3RyZWFtKFBsYWluU29ja2V0SW1wbCBzb2NrZXRJbXBsKSB7CisgICAgICAgICAgICB0aGlzLnNvY2tldEltcGwgPSBzb2NrZXRJbXBsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBzb2NrZXRJbXBsLmF2YWlsYWJsZSgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHNvY2tldEltcGwuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIFN0cmVhbXMucmVhZFNpbmdsZUJ5dGUodGhpcyk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCByZWFkKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gc29ja2V0SW1wbC5yZWFkKGJ1ZmZlciwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0T3B0aW9uKGludCBvcHRpb24pIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gSW9CcmlkZ2UuZ2V0U29ja2V0T3B0aW9uKGZkLCBvcHRpb24pOworICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgc3luY2hyb25pemVkIE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja05vdENsb3NlZCgpOworICAgICAgICByZXR1cm4gbmV3IFBsYWluU29ja2V0T3V0cHV0U3RyZWFtKHRoaXMpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFBsYWluU29ja2V0T3V0cHV0U3RyZWFtIGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBQbGFpblNvY2tldEltcGwgc29ja2V0SW1wbDsKKworICAgICAgICBwdWJsaWMgUGxhaW5Tb2NrZXRPdXRwdXRTdHJlYW0oUGxhaW5Tb2NrZXRJbXBsIHNvY2tldEltcGwpIHsKKyAgICAgICAgICAgIHRoaXMuc29ja2V0SW1wbCA9IHNvY2tldEltcGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgc29ja2V0SW1wbC5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHdyaXRlKGludCBvbmVCeXRlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgU3RyZWFtcy53cml0ZVNpbmdsZUJ5dGUodGhpcywgb25lQnl0ZSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHNvY2tldEltcGwud3JpdGUoYnVmZmVyLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBsaXN0ZW4oaW50IGJhY2tsb2cpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh1c2luZ1NvY2tzKCkpIHsKKyAgICAgICAgICAgIC8vIERvIG5vdGhpbmcgZm9yIGEgU09DS1MgY29ubmVjdGlvbi4gVGhlIGxpc3RlbiBvY2N1cnMgb24gdGhlCisgICAgICAgICAgICAvLyBzZXJ2ZXIgZHVyaW5nIHRoZSBiaW5kLgorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMaWJjb3JlLm9zLmxpc3RlbihmZCwgYmFja2xvZyk7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyBlcnJub0V4Y2VwdGlvbi5yZXRocm93QXNTb2NrZXRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldE9wdGlvbihpbnQgb3B0aW9uLCBPYmplY3QgdmFsdWUpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBJb0JyaWRnZS5zZXRTb2NrZXRPcHRpb24oZmQsIG9wdGlvbiwgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFNPQ0tTIHByb3h5IHNlcnZlciBwb3J0LgorICAgICAqLworICAgIHByaXZhdGUgaW50IHNvY2tzR2V0U2VydmVyUG9ydCgpIHsKKyAgICAgICAgLy8gZ2V0IHNvY2tzIHNlcnZlciBwb3J0IGZyb20gcHJveHkuIEl0IGlzIHVubmVjZXNzYXJ5IHRvIGNoZWNrCisgICAgICAgIC8vICJzb2Nrc1Byb3h5UG9ydCIgcHJvcGVydHksIHNpbmNlIHByb3h5IHNldHRpbmcgc2hvdWxkIG9ubHkgYmUKKyAgICAgICAgLy8gZGV0ZXJtaW5lZCBieSBQcm94eVNlbGVjdG9yLgorICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBhZGRyID0gKEluZXRTb2NrZXRBZGRyZXNzKSBwcm94eS5hZGRyZXNzKCk7CisgICAgICAgIHJldHVybiBhZGRyLmdldFBvcnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBJbmV0QWRkcmVzcyBvZiB0aGUgU09DS1MgcHJveHkgc2VydmVyLgorICAgICAqLworICAgIHByaXZhdGUgSW5ldEFkZHJlc3Mgc29ja3NHZXRTZXJ2ZXJBZGRyZXNzKCkgdGhyb3dzIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHByb3h5TmFtZTsKKyAgICAgICAgLy8gZ2V0IHNvY2tzIHNlcnZlciBhZGRyZXNzIGZyb20gcHJveHkuIEl0IGlzIHVubmVjZXNzYXJ5IHRvIGNoZWNrCisgICAgICAgIC8vICJzb2Nrc1Byb3h5SG9zdCIgcHJvcGVydHksIHNpbmNlIGFsbCBwcm94eSBzZXR0aW5nIHNob3VsZCBiZQorICAgICAgICAvLyBkZXRlcm1pbmVkIGJ5IFByb3h5U2VsZWN0b3IuCisgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIGFkZHIgPSAoSW5ldFNvY2tldEFkZHJlc3MpIHByb3h5LmFkZHJlc3MoKTsKKyAgICAgICAgcHJveHlOYW1lID0gYWRkci5nZXRIb3N0TmFtZSgpOworICAgICAgICBpZiAocHJveHlOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHByb3h5TmFtZSA9IGFkZHIuZ2V0QWRkcmVzcygpLmdldEhvc3RBZGRyZXNzKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIEluZXRBZGRyZXNzLmdldEJ5TmFtZShwcm94eU5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbm5lY3QgdXNpbmcgYSBTT0NLUyBzZXJ2ZXIuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNvY2tzQ29ubmVjdChJbmV0QWRkcmVzcyBhcHBsaWNhdGlvblNlcnZlckFkZHJlc3MsIGludCBhcHBsaWNhdGlvblNlcnZlclBvcnQsIGludCB0aW1lb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW9CcmlkZ2UuY29ubmVjdChmZCwgc29ja3NHZXRTZXJ2ZXJBZGRyZXNzKCksIHNvY2tzR2V0U2VydmVyUG9ydCgpLCB0aW1lb3V0KTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oIlNPQ0tTIGNvbm5lY3Rpb24gZmFpbGVkIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICBzb2Nrc1JlcXVlc3RDb25uZWN0aW9uKGFwcGxpY2F0aW9uU2VydmVyQWRkcmVzcywgYXBwbGljYXRpb25TZXJ2ZXJQb3J0KTsKKworICAgICAgICBsYXN0Q29ubmVjdGVkQWRkcmVzcyA9IGFwcGxpY2F0aW9uU2VydmVyQWRkcmVzczsKKyAgICAgICAgbGFzdENvbm5lY3RlZFBvcnQgPSBhcHBsaWNhdGlvblNlcnZlclBvcnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVxdWVzdCBhIFNPQ0tTIGNvbm5lY3Rpb24gdG8gdGhlIGFwcGxpY2F0aW9uIHNlcnZlciBnaXZlbi4gSWYgdGhlCisgICAgICogcmVxdWVzdCBmYWlscyB0byBjb21wbGV0ZSBzdWNjZXNzZnVsbHksIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNvY2tzUmVxdWVzdENvbm5lY3Rpb24oSW5ldEFkZHJlc3MgYXBwbGljYXRpb25TZXJ2ZXJBZGRyZXNzLAorICAgICAgICAgICAgaW50IGFwcGxpY2F0aW9uU2VydmVyUG9ydCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc29ja3NTZW5kUmVxdWVzdChTb2NrczRNZXNzYWdlLkNPTU1BTkRfQ09OTkVDVCwKKyAgICAgICAgICAgICAgICBhcHBsaWNhdGlvblNlcnZlckFkZHJlc3MsIGFwcGxpY2F0aW9uU2VydmVyUG9ydCk7CisgICAgICAgIFNvY2tzNE1lc3NhZ2UgcmVwbHkgPSBzb2Nrc1JlYWRSZXBseSgpOworICAgICAgICBpZiAocmVwbHkuZ2V0Q29tbWFuZE9yUmVzdWx0KCkgIT0gU29ja3M0TWVzc2FnZS5SRVRVUk5fU1VDQ0VTUykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHJlcGx5LmdldEVycm9yU3RyaW5nKHJlcGx5LmdldENvbW1hbmRPclJlc3VsdCgpKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtIGFuIGFjY2VwdCBmb3IgYSBTT0NLUyBiaW5kLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNvY2tzQWNjZXB0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU29ja3M0TWVzc2FnZSByZXBseSA9IHNvY2tzUmVhZFJlcGx5KCk7CisgICAgICAgIGlmIChyZXBseS5nZXRDb21tYW5kT3JSZXN1bHQoKSAhPSBTb2NrczRNZXNzYWdlLlJFVFVSTl9TVUNDRVNTKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24ocmVwbHkuZ2V0RXJyb3JTdHJpbmcocmVwbHkuZ2V0Q29tbWFuZE9yUmVzdWx0KCkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNodXRkb3duIHRoZSBpbnB1dCBwb3J0aW9uIG9mIHRoZSBzb2NrZXQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2h1dGRvd25JbnB1dCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHNodXRkb3duSW5wdXQgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgTGliY29yZS5vcy5zaHV0ZG93bihmZCwgU0hVVF9SRCk7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyBlcnJub0V4Y2VwdGlvbi5yZXRocm93QXNTb2NrZXRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNodXRkb3duIHRoZSBvdXRwdXQgcG9ydGlvbiBvZiB0aGUgc29ja2V0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNodXRkb3duT3V0cHV0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIExpYmNvcmUub3Muc2h1dGRvd24oZmQsIFNIVVRfV1IpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzU29ja2V0RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBCaW5kIHVzaW5nIGEgU09DS1Mgc2VydmVyLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzb2Nrc0JpbmQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW9CcmlkZ2UuY29ubmVjdChmZCwgc29ja3NHZXRTZXJ2ZXJBZGRyZXNzKCksIHNvY2tzR2V0U2VydmVyUG9ydCgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5hYmxlIHRvIGNvbm5lY3QgdG8gU09DS1Mgc2VydmVyIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBUaGVyZSBtdXN0IGJlIGEgY29ubmVjdGlvbiB0byBhbiBhcHBsaWNhdGlvbiBob3N0IGZvciB0aGUgYmluZCB0byB3b3JrLgorICAgICAgICBpZiAobGFzdENvbm5lY3RlZEFkZHJlc3MgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbigiSW52YWxpZCBTT0NLUyBjbGllbnQiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFVzZSB0aGUgbGFzdCBjb25uZWN0ZWQgYWRkcmVzcyBhbmQgcG9ydCBpbiB0aGUgYmluZCByZXF1ZXN0LgorICAgICAgICBzb2Nrc1NlbmRSZXF1ZXN0KFNvY2tzNE1lc3NhZ2UuQ09NTUFORF9CSU5ELCBsYXN0Q29ubmVjdGVkQWRkcmVzcywKKyAgICAgICAgICAgICAgICBsYXN0Q29ubmVjdGVkUG9ydCk7CisgICAgICAgIFNvY2tzNE1lc3NhZ2UgcmVwbHkgPSBzb2Nrc1JlYWRSZXBseSgpOworCisgICAgICAgIGlmIChyZXBseS5nZXRDb21tYW5kT3JSZXN1bHQoKSAhPSBTb2NrczRNZXNzYWdlLlJFVFVSTl9TVUNDRVNTKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24ocmVwbHkuZ2V0RXJyb3JTdHJpbmcocmVwbHkuZ2V0Q29tbWFuZE9yUmVzdWx0KCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEEgcGVjdWxpYXJpdHkgb2Ygc29ja3MgNCAtIGlmIHRoZSBhZGRyZXNzIHJldHVybmVkIGlzIDAsIHVzZSB0aGUKKyAgICAgICAgLy8gb3JpZ2luYWwgc29ja3Mgc2VydmVyIGFkZHJlc3MuCisgICAgICAgIGlmIChyZXBseS5nZXRJUCgpID09IDApIHsKKyAgICAgICAgICAgIGFkZHJlc3MgPSBzb2Nrc0dldFNlcnZlckFkZHJlc3MoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIElQdjYgc3VwcG9ydCBub3QgeWV0IHJlcXVpcmVkIGFzCisgICAgICAgICAgICAvLyBjdXJyZW50bHkgdGhlIFNvY2tzNE1lc3NhZ2UuZ2V0SVAoKSBvbmx5IHJldHVybnMgaW50LAorICAgICAgICAgICAgLy8gc28gb25seSB3b3JrcyB3aXRoIElQdjQgNGJ5dGUgYWRkcmVzc2VzCisgICAgICAgICAgICBieXRlW10gcmVwbHlCeXRlcyA9IG5ldyBieXRlWzRdOworICAgICAgICAgICAgTWVtb3J5LnBva2VJbnQocmVwbHlCeXRlcywgMCwgcmVwbHkuZ2V0SVAoKSwgQnl0ZU9yZGVyLkJJR19FTkRJQU4pOworICAgICAgICAgICAgYWRkcmVzcyA9IEluZXRBZGRyZXNzLmdldEJ5QWRkcmVzcyhyZXBseUJ5dGVzKTsKKyAgICAgICAgfQorICAgICAgICBsb2NhbHBvcnQgPSByZXBseS5nZXRQb3J0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZCBhIFNPQ0tTIFY0IHJlcXVlc3QuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNvY2tzU2VuZFJlcXVlc3QoaW50IGNvbW1hbmQsIEluZXRBZGRyZXNzIGFkZHJlc3MsIGludCBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTb2NrczRNZXNzYWdlIHJlcXVlc3QgPSBuZXcgU29ja3M0TWVzc2FnZSgpOworICAgICAgICByZXF1ZXN0LnNldENvbW1hbmRPclJlc3VsdChjb21tYW5kKTsKKyAgICAgICAgcmVxdWVzdC5zZXRQb3J0KHBvcnQpOworICAgICAgICByZXF1ZXN0LnNldElQKGFkZHJlc3MuZ2V0QWRkcmVzcygpKTsKKyAgICAgICAgcmVxdWVzdC5zZXRVc2VySWQoImRlZmF1bHQiKTsKKworICAgICAgICBnZXRPdXRwdXRTdHJlYW0oKS53cml0ZShyZXF1ZXN0LmdldEJ5dGVzKCksIDAsIHJlcXVlc3QuZ2V0TGVuZ3RoKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgYSBTT0NLUyBWNCByZXBseS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFNvY2tzNE1lc3NhZ2Ugc29ja3NSZWFkUmVwbHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTb2NrczRNZXNzYWdlIHJlcGx5ID0gbmV3IFNvY2tzNE1lc3NhZ2UoKTsKKyAgICAgICAgaW50IGJ5dGVzUmVhZCA9IDA7CisgICAgICAgIHdoaWxlIChieXRlc1JlYWQgPCBTb2NrczRNZXNzYWdlLlJFUExZX0xFTkdUSCkgeworICAgICAgICAgICAgaW50IGNvdW50ID0gZ2V0SW5wdXRTdHJlYW0oKS5yZWFkKHJlcGx5LmdldEJ5dGVzKCksIGJ5dGVzUmVhZCwKKyAgICAgICAgICAgICAgICAgICAgU29ja3M0TWVzc2FnZS5SRVBMWV9MRU5HVEggLSBieXRlc1JlYWQpOworICAgICAgICAgICAgaWYgKGNvdW50ID09IC0xKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBieXRlc1JlYWQgKz0gY291bnQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKFNvY2tzNE1lc3NhZ2UuUkVQTFlfTEVOR1RIICE9IGJ5dGVzUmVhZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbigiTWFsZm9ybWVkIHJlcGx5IGZyb20gU09DS1Mgc2VydmVyIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlcGx5OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGNvbm5lY3QoU29ja2V0QWRkcmVzcyByZW1vdGVBZGRyLCBpbnQgdGltZW91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgaW5ldEFkZHIgPSAoSW5ldFNvY2tldEFkZHJlc3MpIHJlbW90ZUFkZHI7CisgICAgICAgIGNvbm5lY3QoaW5ldEFkZHIuZ2V0QWRkcmVzcygpLCBpbmV0QWRkci5nZXRQb3J0KCksIHRpbWVvdXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBib29sZWFuIHN1cHBvcnRzVXJnZW50RGF0YSgpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2VuZFVyZ2VudERhdGEoaW50IHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlW10geyAoYnl0ZSkgdmFsdWUgfTsKKyAgICAgICAgICAgIExpYmNvcmUub3Muc2VuZHRvKGZkLCBidWZmZXIsIDAsIDEsIE1TR19PT0IsIG51bGwsIDApOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzU29ja2V0RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGb3IgUGxhaW5Tb2NrZXRJbnB1dFN0cmVhbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCByZWFkKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChieXRlQ291bnQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICBpZiAoc2h1dGRvd25JbnB1dCkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGludCByZWFkQ291bnQgPSBJb0JyaWRnZS5yZWN2ZnJvbSh0cnVlLCBmZCwgYnVmZmVyLCBvZmZzZXQsIGJ5dGVDb3VudCwgMCwgbnVsbCwgZmFsc2UpOworICAgICAgICAvLyBSZXR1cm4gb2YgemVybyBieXRlcyBmb3IgYSBibG9ja2luZyBzb2NrZXQgbWVhbnMgYSB0aW1lb3V0IG9jY3VycmVkCisgICAgICAgIGlmIChyZWFkQ291bnQgPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNvY2tldFRpbWVvdXRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICAvLyBSZXR1cm4gb2YgLTEgaW5kaWNhdGVzIHRoZSBwZWVyIHdhcyBjbG9zZWQKKyAgICAgICAgaWYgKHJlYWRDb3VudCA9PSAtMSkgeworICAgICAgICAgICAgc2h1dGRvd25JbnB1dCA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlYWRDb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGb3IgUGxhaW5Tb2NrZXRPdXRwdXRTdHJlYW0uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGJ1ZmZlci5sZW5ndGgsIG9mZnNldCwgYnl0ZUNvdW50KTsKKyAgICAgICAgaWYgKHN0cmVhbWluZykgeworICAgICAgICAgICAgd2hpbGUgKGJ5dGVDb3VudCA+IDApIHsKKyAgICAgICAgICAgICAgICBpbnQgYnl0ZXNXcml0dGVuID0gSW9CcmlkZ2Uuc2VuZHRvKGZkLCBidWZmZXIsIG9mZnNldCwgYnl0ZUNvdW50LCAwLCBudWxsLCAwKTsKKyAgICAgICAgICAgICAgICBieXRlQ291bnQgLT0gYnl0ZXNXcml0dGVuOworICAgICAgICAgICAgICAgIG9mZnNldCArPSBieXRlc1dyaXR0ZW47CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBVbmxpa2Ugd3JpdGVzIHRvIGEgc3RyZWFtaW5nIHNvY2tldCwgd3JpdGVzIHRvIGEgZGF0YWdyYW0KKyAgICAgICAgICAgIC8vIHNvY2tldCBhcmUgYWxsLW9yLW5vdGhpbmcsIHNvIHdlIGRvbid0IG5lZWQgYSBsb29wIGhlcmUuCisgICAgICAgICAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTE1MzA0CisgICAgICAgICAgICBJb0JyaWRnZS5zZW5kdG8oZmQsIGJ1ZmZlciwgb2Zmc2V0LCBieXRlQ291bnQsIDAsIGFkZHJlc3MsIHBvcnQpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1BvcnRVbnJlYWNoYWJsZUV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1BvcnRVbnJlYWNoYWJsZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxMjEwNjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvUG9ydFVucmVhY2hhYmxlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworLyoqCisgKiBUaGlzIHtAY29kZSBQb3J0VW5yZWFjaGFibGVFeGNlcHRpb259IHdpbGwgYmUgdGhyb3duIGlmIGFuIHtAY29kZQorICogSUNNUF9Qb3J0X1VucmVhY2hhYmxlfSBtZXNzYWdlIGhhcyBiZWVuIHJlY2VpdmVkLgorICoKKyAqIDxwPk1vc3QgYXBwbGljYXRpb25zIDxzdHJvbmc+c2hvdWxkIG5vdDwvc3Ryb25nPiBjYXRjaCB0aGlzIGV4Y2VwdGlvbjsgaXQgaXMKKyAqIG1vcmUgcm9idXN0IHRvIGNhdGNoIHRoZSBzdXBlcmNsYXNzIHtAY29kZSBTb2NrZXRFeGNlcHRpb259LgorICovCitwdWJsaWMgY2xhc3MgUG9ydFVucmVhY2hhYmxlRXhjZXB0aW9uIGV4dGVuZHMgU29ja2V0RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDg0NjI1NDE5OTIzNzY1MDczMjNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUG9ydFVucmVhY2hhYmxlRXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugd2l0aCB0aGUgZ2l2ZW4gZGV0YWlsIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIFBvcnRVbnJlYWNoYWJsZUV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIHdpdGggZ2l2ZW4gZGV0YWlsIG1lc3NhZ2UgYW5kIGNhdXNlLgorICAgICAqIEBoaWRlIGludGVybmFsIHVzZSBvbmx5CisgICAgICovCisgICAgcHVibGljIFBvcnRVbnJlYWNoYWJsZUV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UsIGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvUHJvdG9jb2xFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Qcm90b2NvbEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwYmVjNTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvUHJvdG9jb2xFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQ5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCisvKioKKyAqIFNpZ25hbHMgdGhhdCBlaXRoZXIgYSBjb25uZWN0aW9uIGF0dGVtcHQgdG8gYSBzb2NrZXQgb2YgdGhlIHdyb25nIHR5cGUsIHRoZQorICogYXBwbGljYXRpb24gb2YgYW4gdW5zdXBwb3J0ZWQgb3BlcmF0aW9uIG9yIHRoYXQgYSBnZW5lcmFsIGVycm9yIGluIHRoZQorICogdW5kZXJseWluZyBwcm90b2NvbCBoYXMgb2NjdXJyZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBQcm90b2NvbEV4Y2VwdGlvbiBleHRlbmRzIGphdmEuaW8uSU9FeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTYwOTg0NDk0NDIwNjIzODgwODBMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvdG9jb2xFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSB3aXRoIHRoZSBnaXZlbiBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvdG9jb2xFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSB3aXRoIGdpdmVuIGRldGFpbCBtZXNzYWdlIGFuZCBjYXVzZS4KKyAgICAgKiBAaGlkZSBpbnRlcm5hbCB1c2Ugb25seQorICAgICAqLworICAgIHB1YmxpYyBQcm90b2NvbEV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UsIGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvUHJveHkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Qcm94eS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM0MGVmMzkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvUHJveHkuamF2YQpAQCAtMCwwICsxLDE3NyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgamF2YS5uZXQ7CisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIHByb3h5IHNlcnZlciBzZXR0aW5ncy4gQSBjcmVhdGVkIGluc3RhbmNlIG9mIHtAY29kZQorICogUHJveHl9IHN0b3JlcyBhIHR5cGUgYW5kIGFuIGFkZHJlc3MgYW5kIGlzIGltbXV0YWJsZS4gVGhlcmUgYXJlIHRocmVlIHR5cGVzCisgKiBvZiBwcm94aWVzOgorICogPHVsPgorICogPGxpPkRJUkVDVDwvbGk+CisgKiA8bGk+SFRUUDwvbGk+CisgKiA8bGk+U09DS1M8L2xpPjwvdWwKKyAqLworcHVibGljIGNsYXNzIFByb3h5IHsKKworICAgIC8qKgorICAgICAqIFJlcHJlc2VudHMgdGhlIHByb3h5IHR5cGUgc2V0dGluZyB7QGNvZGUgUHJveHkuVHlwZS5ESVJFQ1R9LiBJdCB0ZWxscworICAgICAqIHByb3RvY29sIGhhbmRsZXJzIHRoYXQgdGhlcmUgaXMgbm8gcHJveHkgdG8gYmUgdXNlZC4gVGhlIGFkZHJlc3MgaXMgc2V0CisgICAgICogdG8ge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUHJveHkgTk9fUFJPWFkgPSBuZXcgUHJveHkoKTsKKworICAgIHByaXZhdGUgUHJveHkuVHlwZSB0eXBlOworCisgICAgcHJpdmF0ZSBTb2NrZXRBZGRyZXNzIGFkZHJlc3M7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBQcm94eX0gaW5zdGFuY2UuIHtAY29kZSBTb2NrZXRBZGRyZXNzfSBtdXN0IE5PVCBiZQorICAgICAqIHtAY29kZSBudWxsfSB3aGVuIHtAY29kZSB0eXBlfSBpcyBlaXRoZXIge0Bjb2RlIFByb3h5LlR5cGUuSFRUUH0gb3IKKyAgICAgKiB7QGNvZGUgUHJveHkuVHlwZS5TT0NLU30uIFRvIGNyZWF0ZSBhIHtAY29kZSBQcm94eX0gaW5zdGFuY2UgcmVwcmVzZW50aW5nCisgICAgICogdGhlIHByb3h5IHR5cGUge0Bjb2RlIFByb3h5LlR5cGUuRElSRUNUfSwgdXNlIHtAY29kZSBQcm94eS5OT19QUk9YWX0KKyAgICAgKiBpbnN0ZWFkIG9mIHRoaXMgY29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHByb3h5IHR5cGUgb2YgdGhpcyBpbnN0YW5jZS4KKyAgICAgKiBAcGFyYW0gc2EKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm94eSBhZGRyZXNzIG9mIHRoaXMgaW5zdGFuY2UuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFyYW1ldGVyIHtAY29kZSB0eXBlfSBpcyBzZXQgdG8ge0Bjb2RlCisgICAgICogICAgICAgICAgICAgUHJveHkuVHlwZS5ESVJFQ1R9IG9yIHRoZSB2YWx1ZSBmb3Ige0Bjb2RlIFNvY2tldEFkZHJlc3N9IGlzCisgICAgICogICAgICAgICAgICAge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBQcm94eShQcm94eS5UeXBlIHR5cGUsIFNvY2tldEFkZHJlc3Mgc2EpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogRG9uJ3QgdXNlIERJUkVDVCB0eXBlIHRvIGNvbnN0cnVjdCBhIHByb3h5IGluc3RhbmNlIGRpcmVjdGx5LgorICAgICAgICAgKiBTb2NrZXRBZGRyZXNzIG11c3QgTk9UIGJlIG51bGwuCisgICAgICAgICAqLworICAgICAgICBpZiAodHlwZSA9PSBUeXBlLkRJUkVDVCB8fCBzYSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbGxlZ2FsIFByb3h5LlR5cGUgb3IgU29ja2V0QWRkcmVzcyBhcmd1bWVudCIpOworICAgICAgICB9CisgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgICAgIGFkZHJlc3MgPSBzYTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENvbnN0cnVjdHMgYSBQcm94eSBpbnN0YW5jZSwgd2hpY2ggaXMgUHJveHkuRElSRUNUIHR5cGUgd2l0aCBudWxsCisgICAgICogU29ja2V0QWRkcmVzcy4gVGhpcyBjb25zdHJ1Y3RvciBpcyB1c2VkIGZvciBOT19QUk9YWS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFByb3h5KCkgeworICAgICAgICB0eXBlID0gVHlwZS5ESVJFQ1Q7CisgICAgICAgIGFkZHJlc3MgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHR5cGUgb2YgdGhpcyB7QGNvZGUgUHJveHl9IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3RvcmVkIHByb3h5IHR5cGUuCisgICAgICovCisgICAgcHVibGljIFByb3h5LlR5cGUgdHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYWRkcmVzcyBvZiB0aGlzIHtAY29kZSBQcm94eX0gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdG9yZWQgcHJveHkgYWRkcmVzcyBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIHByb3h5IHR5cGUgaXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBESVJFQ1R9LgorICAgICAqLworICAgIHB1YmxpYyBTb2NrZXRBZGRyZXNzIGFkZHJlc3MoKSB7CisgICAgICAgIHJldHVybiBhZGRyZXNzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMge0Bjb2RlIFByb3h5fSBpbnN0YW5jZS4gVGhlIHN0cmluZworICAgICAqIGluY2x1ZGVzIHRoZSB0d28gcGFydHMge0Bjb2RlIHR5cGUudG9TdHJpbmcoKX0gYW5kIHtAY29kZQorICAgICAqIGFkZHJlc3MudG9TdHJpbmcoKX0gaWYge0Bjb2RlIGFkZHJlc3N9IGlzIG5vdCB7QGNvZGUgbnVsbH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZXByZXNlbnRpbmcgc3RyaW5nIG9mIHRoaXMgcHJveHkuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgaWYgKHR5cGUgIT0gbnVsbCkgeworICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQodHlwZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICBidWlsZGVyLmFwcGVuZCgiQCIpOworICAgICAgICBpZiAodHlwZSAhPSBQcm94eS5UeXBlLkRJUkVDVCAmJiBhZGRyZXNzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKGFkZHJlc3MudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIHtAY29kZSBvYmp9IHRvIHRoaXMge0Bjb2RlIFByb3h5fSBpbnN0YW5jZSBhbmQKKyAgICAgKiByZXR1cm5zIHdoZXRoZXIgdGhleSBhcmUgZXF1YWwgb3Igbm90LiBUaGUgZ2l2ZW4gb2JqZWN0IG11c3QgYmUgYW4KKyAgICAgKiBpbnN0YW5jZSBvZiB7QGNvZGUgUHJveHl9IHdpdGggdGhlIHNhbWUgYWRkcmVzcyBhbmQgdGhlIHNhbWUgdHlwZSB2YWx1ZQorICAgICAqIHRvIGJlIGVxdWFsLgorICAgICAqCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHdpdGggdGhpcyBpbnN0YW5jZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZ2l2ZW4gb2JqZWN0IHJlcHJlc2VudHMgdGhlIHNhbWUge0Bjb2RlCisgICAgICogICAgICAgICBQcm94eX0gYXMgdGhpcyBpbnN0YW5jZSwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNlZSAjaGFzaENvZGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAodGhpcyA9PSBvYmopIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIFByb3h5KSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIFByb3h5IGFub3RoZXIgPSAoUHJveHkpIG9iajsKKyAgICAgICAgLy8gYWRkcmVzcyBpcyBudWxsIHdoZW4gYW5kIG9ubHkgd2hlbiBpdCdzIE5PX1BST1hZLgorICAgICAgICByZXR1cm4gKHR5cGUgPT0gYW5vdGhlci50eXBlKSAmJiBhZGRyZXNzLmVxdWFscyhhbm90aGVyLmFkZHJlc3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGhhc2hjb2RlIGZvciB0aGlzIHtAY29kZSBQcm94eX0gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoY29kZSB2YWx1ZSBmb3IgdGhpcyBQcm94eSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBpbnQgcmV0ID0gMDsKKyAgICAgICAgcmV0ICs9IHR5cGUuaGFzaENvZGUoKTsKKyAgICAgICAgaWYgKGFkZHJlc3MgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0ICs9IGFkZHJlc3MuaGFzaENvZGUoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmV0OworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAY29kZSBFbnVtfSBjbGFzcyBmb3IgdGhlIHByb3h5IHR5cGUuIFBvc3NpYmxlIG9wdGlvbnMgYXJlIHtAY29kZQorICAgICAqIERJUkVDVH0sIHtAY29kZSBIVFRQfSBhbmQge0Bjb2RlIFNPQ0tTfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZW51bSBUeXBlIHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIERpcmVjdCBjb25uZWN0aW9uLiBDb25uZWN0IHdpdGhvdXQgYW55IHByb3h5LgorICAgICAgICAgKi8KKyAgICAgICAgRElSRUNULAorCisgICAgICAgIC8qKgorICAgICAgICAgKiBIVFRQIHR5cGUgcHJveHkuIEl0J3Mgb2Z0ZW4gdXNlZCBieSBwcm90b2NvbCBoYW5kbGVycyBzdWNoIGFzIEhUVFAsCisgICAgICAgICAqIEhUVFBTIGFuZCBGVFAuCisgICAgICAgICAqLworICAgICAgICBIVFRQLAorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTT0NLUyB0eXBlIHByb3h5LgorICAgICAgICAgKi8KKyAgICAgICAgU09DS1MKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvUHJveHlTZWxlY3Rvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1Byb3h5U2VsZWN0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMTY2ZGI3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1Byb3h5U2VsZWN0b3IuamF2YQpAQCAtMCwwICsxLDEzMCBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKgorICogU2VsZWN0cyB0aGUgcHJveHkgc2VydmVyIHRvIHVzZSwgaWYgYW55LCB3aGVuIGNvbm5lY3RpbmcgdG8gYSBnaXZlbiBVUkwuCisgKgorICogPGgzPlN5c3RlbSBQcm9wZXJ0aWVzPC9oMz4KKyAqIDxwPlRoZSBkZWZhdWx0IHByb3h5IHNlbGVjdG9yIGlzIGNvbmZpZ3VyZWQgYnkgc3lzdGVtIHByb3BlcnRpZXMuCisgKgorICogPHRhYmxlIGJvcmRlcj0iMSIgY2VsbHBhZGRpbmc9IjMiIGNlbGxzcGFjaW5nPSIwIj4KKyAqIDx0ciBjbGFzcz0iVGFibGVIZWFkaW5nQ29sb3IiPjx0aCBjb2xzcGFuPSI0Ij5Ib3N0bmFtZSBwYXR0ZXJuczwvdGg+PC90cj4KKyAqIDx0cj48dGg+VVJMIHNjaGVtZTwvdGg+PHRoPnByb3BlcnR5IG5hbWU8L3RoPjx0aD5kZXNjcmlwdGlvbjwvdGg+PHRoPmRlZmF1bHQ8L3RoPjwvdHI+CisgKiA8dHI+PHRkPmZ0cDwvdGQ+PHRkPmZ0cC5ub25Qcm94eUhvc3RzPC90ZD48dGQ+SG9zdG5hbWUgcGF0dGVybiBmb3IgRlRQIHNlcnZlcnMgdG8gY29ubmVjdCB0bworICogICAgIGRpcmVjdGx5ICh3aXRob3V0IGEgcHJveHkpLjwvdGQ+PHRkPio8L3RkPjwvdHI+CisgKiA8dHI+PHRkPmh0dHA8L3RkPjx0ZD5odHRwLm5vblByb3h5SG9zdHM8L3RkPjx0ZD5Ib3N0bmFtZSBwYXR0ZXJuIGZvciBIVFRQIHNlcnZlcnMgdG8gY29ubmVjdCB0bworICogICAgIGRpcmVjdGx5ICh3aXRob3V0IGEgcHJveHkpLjwvdGQ+PHRkPio8L3RkPjwvdHI+CisgKiA8dHI+PHRkPmh0dHBzPC90ZD48dGQ+aHR0cHMubm9uUHJveHlIb3N0czwvdGQ+PHRkPkhvc3RuYW1lIHBhdHRlcm4gZm9yIEhUVFBTIHNlcnZlcnMgdG8gY29ubmVjdAorICogICAgIHRvIGRpcmVjdGx5ICh3aXRob3V0IGEgcHJveHkpLjwvdGQ+PHRkPio8L3RkPjwvdHI+CisgKiA8dHI+PHRkIGNvbHNwYW49IjQiPjxicj48L3RkPjwvdHI+CisgKgorICogPHRyIGNsYXNzPSJUYWJsZUhlYWRpbmdDb2xvciI+PHRoIGNvbHNwYW49IjQiPntAbGlua3BsYWluIFByb3h5LlR5cGUjSFRUUCBIVFRQIFByb3hpZXN9PC90aD48L3RyPgorICogPHRyPjx0aD5VUkwgc2NoZW1lPC90aD48dGg+cHJvcGVydHkgbmFtZTwvdGg+PHRoPmRlc2NyaXB0aW9uPC90aD48dGg+ZGVmYXVsdDwvdGg+PC90cj4KKyAqIDx0cj48dGQgcm93c3Bhbj0iMiI+ZnRwPC90ZD48dGQ+ZnRwLnByb3h5SG9zdDwvdGQ+PHRkPkhvc3RuYW1lIG9mIHRoZSBIVFRQIHByb3h5IHNlcnZlciB1c2VkIGZvcgorICogICAgIEZUUCByZXF1ZXN0cy48L3RkPjx0ZD48L3RkPjwvdHI+CisgKiA8dHI+PHRkPmZ0cC5wcm94eVBvcnQ8L3RkPjx0ZD5Qb3J0IG51bWJlciBvZiB0aGUgSFRUUCBwcm94eSBzZXJ2ZXIgdXNlZCBmb3IgRlRQCisgKiAgICAgcmVxdWVzdHMuPC90ZD48dGQ+ODA8L3RkPjwvdHI+CisgKiA8dHI+PHRkIHJvd3NwYW49IjIiPmh0dHA8L3RkPjx0ZD5odHRwLnByb3h5SG9zdDwvdGQ+PHRkPkhvc3RuYW1lIG9mIHRoZSBIVFRQIHByb3h5IHNlcnZlciB1c2VkCisgKiAgICAgZm9yIEhUVFAgcmVxdWVzdHMuPC90ZD48dGQ+PC90ZD48L3RyPgorICogPHRyPjx0ZD5odHRwLnByb3h5UG9ydDwvdGQ+PHRkPlBvcnQgbnVtYmVyIG9mIHRoZSBIVFRQIHByb3h5IHNlcnZlciB1c2VkIGZvciBIVFRQCisgKiAgICAgcmVxdWVzdHMuPC90ZD48dGQ+ODA8L3RkPjwvdHI+CisgKiA8dHI+PHRkIHJvd3NwYW49IjIiPmh0dHBzPC90ZD48dGQ+aHR0cHMucHJveHlIb3N0PC90ZD48dGQ+SG9zdG5hbWUgb2YgdGhlIEhUVFAgcHJveHkgc2VydmVyIHVzZWQKKyAqICAgICBmb3IgSFRUUFMgcmVxdWVzdHMuPC90ZD48dGQ+PC90ZD48L3RyPgorICogPHRyPjx0ZD5odHRwcy5wcm94eVBvcnQ8L3RkPjx0ZD5Qb3J0IG51bWJlciBvZiB0aGUgSFRUUCBwcm94eSBzZXJ2ZXIgdXNlZCBmb3IgSFRUUFMKKyAqICAgICByZXF1ZXN0cy48L3RkPjx0ZD40NDM8L3RkPjwvdHI+CisgKiA8dHI+PHRkIHJvd3NwYW49IjIiPmZ0cCwgaHR0cCBvciBodHRwczwvdGQ+PHRkPnByb3h5SG9zdDwvdGQ+PHRkPkhvc3RuYW1lIG9mIHRoZSBIVFRQIHByb3h5CisgKiAgICAgc2VydmVyIHVzZWQgZm9yIEZUUCwgSFRUUCBhbmQgSFRUUFMgcmVxdWVzdHMuPC90ZD48dGQ+PC90ZD48L3RyPgorICogPHRyPjx0ZD5wcm94eVBvcnQ8L3RkPjx0ZD5Qb3J0IG51bWJlciBvZiB0aGUgSFRUUCBwcm94eSBzZXJ2ZXIuPC90ZD48dGQ+ODAgZm9yIEZUUCBhbmQgSFRUUAorICogICAgIDxicj40NDMgZm9yIEhUVFBTPC90ZD48L3RyPgorICogPHRyPjx0ZCBjb2xzcGFuPSI0Ij48YnI+PC90ZD48L3RyPgorICoKKyAqIDx0ciBjbGFzcz0iVGFibGVIZWFkaW5nQ29sb3IiPjx0aCBjb2xzcGFuPSI0Ij57QGxpbmtwbGFpbiBQcm94eS5UeXBlI1NPQ0tTIFNPQ0tTCisgKiAgICAgUHJveGllc308L3RoPjwvdHI+CisgKiA8dHI+PHRoPlVSTCBzY2hlbWU8L3RoPjx0aD5wcm9wZXJ0eSBuYW1lPC90aD48dGg+ZGVzY3JpcHRpb248L3RoPjx0aD5kZWZhdWx0PC90aD48L3RyPgorICogPHRyPjx0ZCByb3dzcGFuPSIyIj5mdHAsIGh0dHAsIGh0dHBzIG9yIHNvY2tldDwvdGQ+PHRkPnNvY2tzUHJveHlIb3N0PC90ZD48dGQ+SG9zdG5hbWUgb2YgdGhlCisgKiAgICAgU09DS1MgcHJveHkgc2VydmVyIHVzZWQgZm9yIEZUUCwgSFRUUCwgSFRUUFMgYW5kIHJhdyBzb2NrZXRzLjxicj5SYXcgc29ja2V0IFVSTHMgYXJlIG9mIHRoZQorICogICAgIGZvcm0gPGNvZGU+c29ja2V0Oi8vPGk+aG9zdDwvaT46PGk+cG9ydDwvaT48L2NvZGU+PC90ZD48dGQ+PC90ZD48L3RyPgorICogPHRyPjx0ZD5zb2Nrc1Byb3h5UG9ydDwvdGQ+PHRkPlBvcnQgbnVtYmVyIG9mIHRoZSBTT0NLUyBwcm94eSBzZXJ2ZXIuPC90ZD48dGQ+MTA4MDwvdGQ+PC90cj4KKyAqIDwvdGFibGU+CisgKgorICogPHA+SG9zdG5hbWUgcGF0dGVybnMgc3BlY2lmeSB3aGljaCBob3N0cyBzaG91bGQgYmUgY29ubmVjdGVkIHRvIGRpcmVjdGx5LAorICogaWdub3JpbmcgYW55IG90aGVyIHByb3h5IHN5c3RlbSBwcm9wZXJ0aWVzLiBJZiB0aGUgVVJMJ3MgaG9zdCBtYXRjaGVzIHRoZQorICogY29ycmVzcG9uZGluZyBob3N0bmFtZSBwYXR0ZXJuLCB7QGxpbmsgUHJveHkjTk9fUFJPWFl9IGlzIHJldHVybmVkLgorICoKKyAqIDxwPlRoZSBmb3JtYXQgb2YgYSBob3N0bmFtZSBwYXR0ZXJuIGlzIGEgbGlzdCBvZiBob3N0bmFtZXMgdGhhdCBhcmUKKyAqIHNlcGFyYXRlZCBieSB7QGNvZGUgfH0gYW5kIHRoYXQgdXNlIHtAY29kZSAqfSBhcyBhIHdpbGRjYXJkLiBGb3IgZXhhbXBsZSwKKyAqIHNldHRpbmcgdGhlIHtAY29kZSBodHRwLm5vblByb3h5SG9zdHN9IHByb3BlcnR5IHRvIHtAY29kZQorICogKi5hbmRyb2lkLmNvbXwqLmtlcm5lbC5vcmd9IHdpbGwgY2F1c2UgcmVxdWVzdHMgdG8ge0Bjb2RlCisgKiBodHRwOi8vZGV2ZWxvcGVyLmFuZHJvaWQuY29tfSB0byBiZSBtYWRlIHdpdGhvdXQgYSBwcm94eS4KKyAqCisgKiA8cD5UaGUgZGVmYXVsdCBwcm94eSBzZWxlY3RvciBhbHdheXMgcmV0dXJucyBleGFjdGx5IG9uZSBwcm94eS4gSWYgbm8gcHJveHkKKyAqIGlzIGFwcGxpY2FibGUsIHtAbGluayBQcm94eSNOT19QUk9YWX0gaXMgcmV0dXJuZWQuIElmIG11bHRpcGxlIHByb3hpZXMgYXJlCisgKiBhcHBsaWNhYmxlLCBzdWNoIGFzIHdoZW4gYm90aCB0aGUge0Bjb2RlIHByb3h5SG9zdH0gYW5kIHtAY29kZQorICogc29ja3NQcm94eUhvc3R9IHN5c3RlbSBwcm9wZXJ0aWVzIGFyZSBzZXQsIHRoZSByZXN1bHQgaXMgdGhlIHByb3BlcnR5IGxpc3RlZAorICogZWFybGllc3QgaW4gdGhlIHRhYmxlIGFib3ZlLgorICoKKyAqIDxoMz5BbHRlcm5hdGl2ZXM8L2gzPgorICogPHA+VG8gcmVxdWVzdCBhIFVSTCB3aXRob3V0IGludm9sdmluZyB0aGUgc3lzdGVtIHByb3h5IHNlbGVjdG9yLCBleHBsaWNpdGx5CisgKiBzcGVjaWZ5IGEgcHJveHkgb3Ige0BsaW5rIFByb3h5I05PX1BST1hZfSB1c2luZyB7QGxpbmsKKyAqIFVSTCNvcGVuQ29ubmVjdGlvbihQcm94eSl9LgorICoKKyAqIDxwPlVzZSB7QGxpbmsgUHJveHlTZWxlY3RvciNzZXREZWZhdWx0KFByb3h5U2VsZWN0b3IpfSB0byBpbnN0YWxsIGEgY3VzdG9tCisgKiBwcm94eSBzZWxlY3Rvci4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFByb3h5U2VsZWN0b3IgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgUHJveHlTZWxlY3RvciBkZWZhdWx0U2VsZWN0b3IgPSBuZXcgUHJveHlTZWxlY3RvckltcGwoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgcHJveHkgc2VsZWN0b3IsIG9yIG51bGwgaWYgbm9uZSBleGlzdHMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBQcm94eVNlbGVjdG9yIGdldERlZmF1bHQoKSB7CisgICAgICAgIHJldHVybiBkZWZhdWx0U2VsZWN0b3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGVmYXVsdCBwcm94eSBzZWxlY3Rvci4gSWYge0Bjb2RlIHNlbGVjdG9yfSBpcyBudWxsLCB0aGUgY3VycmVudAorICAgICAqIHByb3h5IHNlbGVjdG9yIHdpbGwgYmUgcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0RGVmYXVsdChQcm94eVNlbGVjdG9yIHNlbGVjdG9yKSB7CisgICAgICAgIGRlZmF1bHRTZWxlY3RvciA9IHNlbGVjdG9yOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByb3h5IHNlcnZlcnMgdG8gdXNlIG9uIGNvbm5lY3Rpb25zIHRvIHtAY29kZSB1cml9LiBUaGlzIGxpc3QKKyAgICAgKiB3aWxsIGNvbnRhaW4ge0BsaW5rIFByb3h5I05PX1BST1hZfSBpZiBubyBwcm94eSBzZXJ2ZXIgc2hvdWxkIGJlIHVzZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgdXJpfSBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBMaXN0PFByb3h5PiBzZWxlY3QoVVJJIHVyaSk7CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGlzIHtAY29kZSBQcm94eVNlbGVjdG9yfSB0aGF0IGEgY29ubmVjdGlvbiB0byB0aGUgcHJveHkgc2VydmVyCisgICAgICogY291bGQgbm90IGJlIGVzdGFibGlzaGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHVyaSB0aGUgVVJJIHRvIHdoaWNoIHRoZSBjb25uZWN0aW9uIGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZC4KKyAgICAgKiBAcGFyYW0gYWRkcmVzcyB0aGUgYWRkcmVzcyBvZiB0aGUgcHJveHkuCisgICAgICogQHBhcmFtIGZhaWx1cmUgdGhlIGV4Y2VwdGlvbiB3aGljaCB3YXMgdGhyb3duIGR1cmluZyBjb25uZWN0aW9uCisgICAgICogICAgIGVzdGFibGlzaG1lbnQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYW55IGFyZ3VtZW50IGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgY29ubmVjdEZhaWxlZChVUkkgdXJpLCBTb2NrZXRBZGRyZXNzIGFkZHJlc3MsIElPRXhjZXB0aW9uIGZhaWx1cmUpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1Byb3h5U2VsZWN0b3JJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvUHJveHlTZWxlY3RvckltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NzJiOWU1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1Byb3h5U2VsZWN0b3JJbXBsLmphdmEKQEAgLTAsMCArMSwxNDMgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworZmluYWwgY2xhc3MgUHJveHlTZWxlY3RvckltcGwgZXh0ZW5kcyBQcm94eVNlbGVjdG9yIHsKKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBjb25uZWN0RmFpbGVkKFVSSSB1cmksIFNvY2tldEFkZHJlc3Mgc2EsIElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICBpZiAodXJpID09IG51bGwgfHwgc2EgPT0gbnVsbCB8fCBpb2UgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBMaXN0PFByb3h5PiBzZWxlY3QoVVJJIHVyaSkgeworICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuc2luZ2xldG9uTGlzdChzZWxlY3RPbmVQcm94eSh1cmkpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFByb3h5IHNlbGVjdE9uZVByb3h5KFVSSSB1cmkpIHsKKyAgICAgICAgaWYgKHVyaSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ1cmkgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBzY2hlbWUgPSB1cmkuZ2V0U2NoZW1lKCk7CisgICAgICAgIGlmIChzY2hlbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigic2NoZW1lID09IG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBwb3J0ID0gLTE7CisgICAgICAgIFByb3h5IHByb3h5ID0gbnVsbDsKKyAgICAgICAgU3RyaW5nIG5vblByb3h5SG9zdHNLZXkgPSBudWxsOworICAgICAgICBib29sZWFuIGh0dHBQcm94eU9rYXkgPSB0cnVlOworICAgICAgICBpZiAoImh0dHAiLmVxdWFsc0lnbm9yZUNhc2Uoc2NoZW1lKSkgeworICAgICAgICAgICAgcG9ydCA9IDgwOworICAgICAgICAgICAgbm9uUHJveHlIb3N0c0tleSA9ICJodHRwLm5vblByb3h5SG9zdHMiOworICAgICAgICAgICAgcHJveHkgPSBsb29rdXBQcm94eSgiaHR0cC5wcm94eUhvc3QiLCAiaHR0cC5wcm94eVBvcnQiLCBQcm94eS5UeXBlLkhUVFAsIHBvcnQpOworICAgICAgICB9IGVsc2UgaWYgKCJodHRwcyIuZXF1YWxzSWdub3JlQ2FzZShzY2hlbWUpKSB7CisgICAgICAgICAgICBwb3J0ID0gNDQzOworICAgICAgICAgICAgbm9uUHJveHlIb3N0c0tleSA9ICJodHRwcy5ub25Qcm94eUhvc3RzIjsgLy8gUkkgZG9lc24ndCBzdXBwb3J0IHRoaXMKKyAgICAgICAgICAgIHByb3h5ID0gbG9va3VwUHJveHkoImh0dHBzLnByb3h5SG9zdCIsICJodHRwcy5wcm94eVBvcnQiLCBQcm94eS5UeXBlLkhUVFAsIHBvcnQpOworICAgICAgICB9IGVsc2UgaWYgKCJmdHAiLmVxdWFsc0lnbm9yZUNhc2Uoc2NoZW1lKSkgeworICAgICAgICAgICAgcG9ydCA9IDgwOyAvLyBub3QgMjEgYXMgeW91IG1pZ2h0IGd1ZXNzCisgICAgICAgICAgICBub25Qcm94eUhvc3RzS2V5ID0gImZ0cC5ub25Qcm94eUhvc3RzIjsKKyAgICAgICAgICAgIHByb3h5ID0gbG9va3VwUHJveHkoImZ0cC5wcm94eUhvc3QiLCAiZnRwLnByb3h5UG9ydCIsIFByb3h5LlR5cGUuSFRUUCwgcG9ydCk7CisgICAgICAgIH0gZWxzZSBpZiAoInNvY2tldCIuZXF1YWxzSWdub3JlQ2FzZShzY2hlbWUpKSB7CisgICAgICAgICAgICBodHRwUHJveHlPa2F5ID0gZmFsc2U7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gUHJveHkuTk9fUFJPWFk7CisgICAgICAgIH0KKworICAgICAgICBpZiAobm9uUHJveHlIb3N0c0tleSAhPSBudWxsCisgICAgICAgICAgICAgICAgJiYgaXNOb25Qcm94eUhvc3QodXJpLmdldEhvc3QoKSwgU3lzdGVtLmdldFByb3BlcnR5KG5vblByb3h5SG9zdHNLZXkpKSkgeworICAgICAgICAgICAgcmV0dXJuIFByb3h5Lk5PX1BST1hZOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHByb3h5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBwcm94eTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChodHRwUHJveHlPa2F5KSB7CisgICAgICAgICAgICBwcm94eSA9IGxvb2t1cFByb3h5KCJwcm94eUhvc3QiLCAicHJveHlQb3J0IiwgUHJveHkuVHlwZS5IVFRQLCBwb3J0KTsKKyAgICAgICAgICAgIGlmIChwcm94eSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHByb3h5OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJveHkgPSBsb29rdXBQcm94eSgic29ja3NQcm94eUhvc3QiLCAic29ja3NQcm94eVBvcnQiLCBQcm94eS5UeXBlLlNPQ0tTLCAxMDgwKTsKKyAgICAgICAgaWYgKHByb3h5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBwcm94eTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBQcm94eS5OT19QUk9YWTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcm94eSBpZGVudGlmaWVkIGJ5IHRoZSB7QGNvZGUgaG9zdEtleX0gc3lzdGVtIHByb3BlcnR5LCBvcgorICAgICAqIG51bGwuCisgICAgICovCisgICAgcHJpdmF0ZSBQcm94eSBsb29rdXBQcm94eShTdHJpbmcgaG9zdEtleSwgU3RyaW5nIHBvcnRLZXksIFByb3h5LlR5cGUgdHlwZSwgaW50IGRlZmF1bHRQb3J0KSB7CisgICAgICAgIFN0cmluZyBob3N0ID0gU3lzdGVtLmdldFByb3BlcnR5KGhvc3RLZXkpOworICAgICAgICBpZiAoaG9zdCA9PSBudWxsIHx8IGhvc3QuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIGludCBwb3J0ID0gZ2V0U3lzdGVtUHJvcGVydHlJbnQocG9ydEtleSwgZGVmYXVsdFBvcnQpOworICAgICAgICByZXR1cm4gbmV3IFByb3h5KHR5cGUsIEluZXRTb2NrZXRBZGRyZXNzLmNyZWF0ZVVucmVzb2x2ZWQoaG9zdCwgcG9ydCkpOworICAgIH0KKworICAgIHByaXZhdGUgaW50IGdldFN5c3RlbVByb3BlcnR5SW50KFN0cmluZyBrZXksIGludCBkZWZhdWx0VmFsdWUpIHsKKyAgICAgICAgU3RyaW5nIHN0cmluZyA9IFN5c3RlbS5nZXRQcm9wZXJ0eShrZXkpOworICAgICAgICBpZiAoc3RyaW5nICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIEludGVnZXIucGFyc2VJbnQoc3RyaW5nKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHtAY29kZSBub25Qcm94eUhvc3RzfSBzeXN0ZW0gcHJvcGVydHkgcGF0dGVybiBleGlzdHMKKyAgICAgKiBhbmQgbWF0Y2hlcyB7QGNvZGUgaG9zdH0uCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGlzTm9uUHJveHlIb3N0KFN0cmluZyBob3N0LCBTdHJpbmcgbm9uUHJveHlIb3N0cykgeworICAgICAgICBpZiAoaG9zdCA9PSBudWxsIHx8IG5vblByb3h5SG9zdHMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLy8gY29uc3RydWN0IHBhdHRlcm4KKyAgICAgICAgU3RyaW5nQnVpbGRlciBwYXR0ZXJuQnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbm9uUHJveHlIb3N0cy5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBjaGFyIGMgPSBub25Qcm94eUhvc3RzLmNoYXJBdChpKTsKKyAgICAgICAgICAgIHN3aXRjaCAoYykgeworICAgICAgICAgICAgY2FzZSAnLic6CisgICAgICAgICAgICAgICAgcGF0dGVybkJ1aWxkZXIuYXBwZW5kKCJcXC4iKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJyonOgorICAgICAgICAgICAgICAgIHBhdHRlcm5CdWlsZGVyLmFwcGVuZCgiLioiKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgcGF0dGVybkJ1aWxkZXIuYXBwZW5kKGMpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIGhvc3QgaXMgdGhlIG5vblByb3h5SG9zdHMuCisgICAgICAgIFN0cmluZyBwYXR0ZXJuID0gcGF0dGVybkJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICAgICAgcmV0dXJuIGhvc3QubWF0Y2hlcyhwYXR0ZXJuKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvUmVzcG9uc2VDYWNoZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1Jlc3BvbnNlQ2FjaGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYmI0ZjBmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1Jlc3BvbnNlQ2FjaGUuamF2YQpAQCAtMCwwICsxLDg1IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBqYXZhLm5ldDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBDYWNoZXMge0Bjb2RlIFVSTENvbm5lY3Rpb259IHJlc3BvbnNlcy4KKyAqIDxwPlRoZSBzeXN0ZW0ncyBkZWZhdWx0IGNhY2hlIGNhbiBiZSBzZXQgdXNpbmcge0BsaW5rICNzZXREZWZhdWx0fS4KKyAqIElmIHtAbGluayBVUkxDb25uZWN0aW9uI2dldFVzZUNhY2hlc30gcmV0dXJucyB0cnVlLCB7QGNvZGUgVVJMQ29ubmVjdGlvbn0gd2lsbCB1c2UgdGhlCisgKiBkZWZhdWx0IHJlc3BvbnNlIGNhY2hlLCBpZiBvbmUgaGFzIGJlZW4gc2V0LgorICogPHA+QWx0aG91Z2gge0Bjb2RlIFVSTENvbm5lY3Rpb259IHdpbGwgYWx3YXlzIGNhbGwge0BsaW5rICNwdXR9LCB0aGUgc3BlY2lmaWMKKyAqIHtAY29kZSBSZXNwb25zZUNhY2hlfSBpbXBsZW1lbnRhdGlvbiBnZXRzIHRvIGRlY2lkZSB3aGF0IHdpbGwgYWN0dWFsbHkgYmUgY2FjaGVkLAorICogYW5kIGZvciBob3cgbG9uZy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFJlc3BvbnNlQ2FjaGUgeworICAgIHByaXZhdGUgc3RhdGljIFJlc3BvbnNlQ2FjaGUgZGVmYXVsdFJlc3BvbnNlQ2FjaGUgPSBudWxsOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3lzdGVtJ3MgZGVmYXVsdCByZXNwb25zZSBjYWNoZSwgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFJlc3BvbnNlQ2FjaGUgZ2V0RGVmYXVsdCgpIHsKKyAgICAgICAgcmV0dXJuIGRlZmF1bHRSZXNwb25zZUNhY2hlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHN5c3RlbSdzIGRlZmF1bHQgcmVzcG9uc2UgY2FjaGUuIFVzZSBudWxsIHRvIHJlbW92ZSB0aGUgcmVzcG9uc2UgY2FjaGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldERlZmF1bHQoUmVzcG9uc2VDYWNoZSByZXNwb25zZUNhY2hlKSB7CisgICAgICAgIGRlZmF1bHRSZXNwb25zZUNhY2hlID0gcmVzcG9uc2VDYWNoZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjYWNoZWQgcmVzcG9uc2UgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gcmVxdWVzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmkKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXF1ZXN0IFVSSS4KKyAgICAgKiBAcGFyYW0gcmVxdWVzdE1ldGhvZAorICAgICAqICAgICAgICAgICAgdGhlIHJlcXVlc3QgbWV0aG9kLgorICAgICAqIEBwYXJhbSByZXF1ZXN0SGVhZGVycworICAgICAqICAgICAgICAgICAgYSBtYXAgb2YgcmVxdWVzdCBoZWFkZXJzLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBDYWNoZVJlc3BvbnNlfSBvYmplY3QgaWYgdGhlIHJlcXVlc3QgaXMgYXZhaWxhYmxlIGluIHRoZSBjYWNoZQorICAgICAqICAgICAgICAgb3Ige0Bjb2RlIG51bGx9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSBnZXR0aW5nIHRoZSBjYWNoZWQgZGF0YS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBvbmUgb2YgdGhlIHBhcmFtZXRlcnMgaXMgc2V0IHRvIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQ2FjaGVSZXNwb25zZSBnZXQoVVJJIHVyaSwgU3RyaW5nIHJlcXVlc3RNZXRob2QsCisgICAgICAgICAgICBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IHJlcXVlc3RIZWFkZXJzKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBBbGxvd3MgdGhlIHByb3RvY29sIGhhbmRsZXIgdG8gY2FjaGUgZGF0YSBhZnRlciByZXRyaWV2aW5nIHJlc291cmNlcy4gVGhlCisgICAgICoge0Bjb2RlIFJlc3BvbnNlQ2FjaGV9IGRlY2lkZXMgd2hldGhlciB0aGUgcmVzb3VyY2UgZGF0YSBzaG91bGQgYmUgY2FjaGVkCisgICAgICogb3Igbm90LiBJZiBzbywgdGhpcyBtZXRob2QgcmV0dXJucyBhIHtAY29kZSBDYWNoZVJlcXVlc3R9IHRvIHdyaXRlIHRoZQorICAgICAqIHJlc291cmNlIGRhdGEgdG8uIE90aGVyd2lzZSwgdGhpcyBtZXRob2QgcmV0dXJucyB7QGNvZGUgbnVsbH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJpCisgICAgICogICAgICAgICAgICB0aGUgcmVmZXJlbmNlIHRvIHRoZSByZXF1ZXN0ZWQgcmVzb3VyY2UuCisgICAgICogQHBhcmFtIGNvbm5lY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb25uZWN0aW9uIHRvIGZldGNoIHRoZSByZXNwb25zZS4KKyAgICAgKiBAcmV0dXJuIGEgQ2FjaGVSZXF1ZXN0IG9iamVjdCB3aXRoIGEgV3JpdGVhYmxlQnl0ZUNoYW5uZWwgaWYgdGhlIHJlc291cmNlCisgICAgICogICAgICAgICBoYXMgdG8gYmUgY2FjaGVkLCB7QGNvZGUgbnVsbH0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIGFkZGluZyB0aGUgcmVzb3VyY2UuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgb25lIG9mIHRoZSBwYXJhbWV0ZXJzIGlzIHNldCB0byB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENhY2hlUmVxdWVzdCBwdXQoVVJJIHVyaSwgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvU2VjdXJlQ2FjaGVSZXNwb25zZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1NlY3VyZUNhY2hlUmVzcG9uc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MGU0NGIyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1NlY3VyZUNhY2hlUmVzcG9uc2UuamF2YQpAQCAtMCwwICsxLDkzIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBqYXZhLm5ldDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uOworCisvKioKKyAqIEEgc2VjdXJlIGNhY2hlIHJlc3BvbnNlIHJlcHJlc2VudHMgZGF0YSB3aGljaCBpcyBvcmlnaW5hbGx5IHJldHJpZXZlZCBvdmVyIGEKKyAqIHNlY3VyZSBjb25uZWN0aW9uLiBTdWNoIGEgY29ubmVjdGlvbiBjYW4gYmUgc2VjdXJlZCBieSB1c2luZyBhIGNyeXB0b2dyYXBoaWMKKyAqIHByb3RvY29sIGxpa2UgVExTIG9yIFNTTC4KKyAqCisgKiBAc2VlIFJlc3BvbnNlQ2FjaGUKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFNlY3VyZUNhY2hlUmVzcG9uc2UgZXh0ZW5kcyBDYWNoZVJlc3BvbnNlIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2VjdXJlQ2FjaGVSZXNwb25zZSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjaXBoZXIgc3VpdGUgc3RyaW5nIG9uIHRoZSBjb25uZWN0aW9uIHdoaWNoIGlzIG9yaWdpbmFsbHkgdXNlZAorICAgICAqIHRvIHJldHJpZXZlIHRoZSBuZXR3b3JrIHJlc291cmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2lwaGVyIHN1aXRlIHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldENpcGhlclN1aXRlKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsb2NhbCBjZXJ0aWZpY2F0ZSBjaGFpbi4gV2hlbiB0aGUgb3JpZ2luYWwgY29ubmVjdGlvbiByZXRyaWV2ZWQKKyAgICAgKiB0aGUgcmVzb3VyY2UgZGF0YSwgdGhpcyBjZXJ0aWZpY2F0ZSBjaGFpbiB3YXMgc2VudCB0byB0aGUgc2VydmVyIGR1cmluZworICAgICAqIGhhbmRzaGFraW5nIHByb2Nlc3MuIFRoaXMgbWV0aG9kIG9ubHkgdGFrZXMgZWZmZWN0IHdoZW4gY2VydGlmaWNhdGUtYmFzZWQKKyAgICAgKiBjaXBoZXIgc3VpdGUgaXMgZW5hYmxlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRlIGNoYWluIHRoYXQgd2FzIHNlbnQgdG8gdGhlIHNlcnZlci4gSWYgbm8KKyAgICAgKiAgICAgICAgIGNlcnRpZmljYXRlIGNoYWluIHdhcyBzZW50LCB0aGUgbWV0aG9kIHJldHVybnMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBMaXN0PENlcnRpZmljYXRlPiBnZXRMb2NhbENlcnRpZmljYXRlQ2hhaW4oKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNhY2hlZCBzZXJ2ZXIncyBjZXJ0aWZpY2F0ZSBjaGFpbi4gQXMgcGFydCBvZiBkZWZpbmluZyB0aGUKKyAgICAgKiBzZXNzaW9uLCB0aGUgY2VydGlmaWNhdGUgY2hhaW4gd2FzIGVzdGFibGlzaGVkIHdoZW4gdGhlIG9yaWdpbmFsCisgICAgICogY29ubmVjdGlvbiByZXRyaWV2ZWQgbmV0d29yayByZXNvdXJjZS4gVGhpcyBtZXRob2QgY2FuIG9ubHkgYmUgaW52b2tlZAorICAgICAqIHdoZW4gY2VydGlmaWNhdGVkLWJhc2VkIGNpcGhlciBzdWl0ZSBpcyBlbmFibGVkLiBPdGhlcndpc2UsIGl0IHRocm93cyBhbgorICAgICAqIHtAY29kZSBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzZXJ2ZXIncyBjZXJ0aWZpY2F0ZSBjaGFpbi4KKyAgICAgKiBAdGhyb3dzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBlZXIgaXMgdW52ZXJpZmllZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgTGlzdDxDZXJ0aWZpY2F0ZT4gZ2V0U2VydmVyQ2VydGlmaWNhdGVDaGFpbigpCisgICAgICAgICAgICB0aHJvd3MgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzZXJ2ZXIncyBwcmluY2lwbGUuIFdoZW4gdGhlIG9yaWdpbmFsIGNvbm5lY3Rpb24gcmV0cmlldmVkCisgICAgICogbmV0d29yayByZXNvdXJjZSwgdGhlIHByaW5jaXBsZSB3YXMgZXN0YWJsaXNoZWQgd2hlbiBkZWZpbmluZyB0aGUKKyAgICAgKiBzZXNzaW9uLgorICAgICAqCisgICAgICogQHJldHVybiBhIHByaW5jaXBhbCBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBzZXJ2ZXIncyBwcmluY2lwYWwuCisgICAgICogQHRocm93cyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwZWVyIGlzIHVudmVyaWZpZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFByaW5jaXBhbCBnZXRQZWVyUHJpbmNpcGFsKCkKKyAgICAgICAgICAgIHRocm93cyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxvY2FsIHByaW5jaXBsZSB0aGF0IHRoZSBvcmlnaW5hbCBjb25uZWN0aW9uIHNlbnQgdG8gdGhlIHNlcnZlci4KKyAgICAgKiBXaGVuIHRoZSBvcmlnaW5hbCBjb25uZWN0aW9uIGZldGNoZWQgdGhlIG5ldHdvcmsgcmVzb3VyY2UsIHRoZSBwcmluY2lwbGUKKyAgICAgKiB3YXMgc2VudCB0byB0aGUgc2VydmVyIGR1cmluZyBoYW5kc2hha2luZyBwcm9jZXNzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbG9jYWwgcHJpbmNpcGFsIG9iamVjdCBiZWluZyBzZW50IHRvIHRoZSBzZXJ2ZXIuIFJldHVybnMgYW4KKyAgICAgKiAgICAgICAgIHtAY29kZSBYNTAwUHJpbmNpcGFsfSBvYmplY3QgZm9yIFg1MDktYmFzZWQgY2lwaGVyIHN1aXRlcy4gSWYgbm8KKyAgICAgKiAgICAgICAgIHByaW5jaXBhbCB3YXMgc2VudCwgaXQgcmV0dXJucyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFByaW5jaXBhbCBnZXRMb2NhbFByaW5jaXBhbCgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1NlcnZlclNvY2tldC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1NlcnZlclNvY2tldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJhOGQ2MjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvU2VydmVyU29ja2V0LmphdmEKQEAgLTAsMCArMSw0MzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlcnZlclNvY2tldENoYW5uZWw7CisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgc2VydmVyLXNpZGUgc29ja2V0IHRoYXQgd2FpdHMgZm9yIGluY29taW5nIGNsaWVudAorICogY29ubmVjdGlvbnMuIEEge0Bjb2RlIFNlcnZlclNvY2tldH0gaGFuZGxlcyB0aGUgcmVxdWVzdHMgYW5kIHNlbmRzIGJhY2sgYW4KKyAqIGFwcHJvcHJpYXRlIHJlcGx5LiBUaGUgYWN0dWFsIHRhc2tzIHRoYXQgYSBzZXJ2ZXIgc29ja2V0IG11c3QgYWNjb21wbGlzaCBhcmUKKyAqIGltcGxlbWVudGVkIGJ5IGFuIGludGVybmFsIHtAY29kZSBTb2NrZXRJbXBsfSBpbnN0YW5jZS4KKyAqLworcHVibGljIGNsYXNzIFNlcnZlclNvY2tldCB7CisgICAgLyoqCisgICAgICogVGhlIFJJIHNwZWNpZmllcyB0aGF0IHdoZXJlIHRoZSBjYWxsZXIgZG9lc24ndCBnaXZlIGFuIGV4cGxpY2l0IGJhY2tsb2csCisgICAgICogdGhlIGRlZmF1bHQgaXMgNTAuIFRoZSBPUyBkaXNhZ3JlZXMsIHNvIHdlIG5lZWQgdG8gZXhwbGljaXRseSBjYWxsIGxpc3RlbigyKS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9CQUNLTE9HID0gNTA7CisKKyAgICBwcml2YXRlIGZpbmFsIFNvY2tldEltcGwgaW1wbDsKKworICAgIC8qKgorICAgICAqIEBoaWRlIGludGVybmFsIHVzZSBvbmx5CisgICAgICovCisgICAgcHVibGljIFNvY2tldEltcGwgZ2V0SW1wbCQoKSB7CisgICAgICAgIHJldHVybiBpbXBsOworICAgIH0KKworICAgIHN0YXRpYyBTb2NrZXRJbXBsRmFjdG9yeSBmYWN0b3J5OworCisgICAgcHJpdmF0ZSBib29sZWFuIGlzQm91bmQ7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNDbG9zZWQ7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHVuYm91bmQge0Bjb2RlIFNlcnZlclNvY2tldH0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjcmVhdGluZyB0aGUgc29ja2V0LgorICAgICAqLworICAgIHB1YmxpYyBTZXJ2ZXJTb2NrZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLmltcGwgPSBmYWN0b3J5ICE9IG51bGwgPyBmYWN0b3J5LmNyZWF0ZVNvY2tldEltcGwoKQorICAgICAgICAgICAgICAgIDogbmV3IFBsYWluU2VydmVyU29ja2V0SW1wbCgpOworICAgICAgICBpbXBsLmNyZWF0ZSh0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBTZXJ2ZXJTb2NrZXR9IGluc3RhbmNlIGJvdW5kIHRvIHRoZSBnaXZlbiB7QGNvZGUgcG9ydH0uCisgICAgICogVGhlIGJhY2tsb2cgaXMgc2V0IHRvIDUwLiBJZiB7QGNvZGUgcG9ydCA9PSAwfSwgYSBwb3J0IHdpbGwgYmUgYXNzaWduZWQgYnkgdGhlIE9TLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY3JlYXRpbmcgdGhlIHNvY2tldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2VydmVyU29ja2V0KGludCBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKHBvcnQsIERFRkFVTFRfQkFDS0xPRywgSW5ldDRBZGRyZXNzLkFOWSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgU2VydmVyU29ja2V0fSBpbnN0YW5jZSBib3VuZCB0byB0aGUgZ2l2ZW4ge0Bjb2RlIHBvcnR9LgorICAgICAqIFRoZSBiYWNrbG9nIGlzIHNldCB0byB7QGNvZGUgYmFja2xvZ30uCisgICAgICogSWYge0Bjb2RlIHBvcnQgPT0gMH0sIGEgcG9ydCB3aWxsIGJlIGFzc2lnbmVkIGJ5IHRoZSBPUy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNyZWF0aW5nIHRoZSBzb2NrZXQuCisgICAgICovCisgICAgcHVibGljIFNlcnZlclNvY2tldChpbnQgcG9ydCwgaW50IGJhY2tsb2cpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMocG9ydCwgYmFja2xvZywgSW5ldDRBZGRyZXNzLkFOWSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgU2VydmVyU29ja2V0fSBpbnN0YW5jZSBib3VuZCB0byB0aGUgZ2l2ZW4ge0Bjb2RlIGxvY2FsQWRkcmVzc30KKyAgICAgKiBhbmQge0Bjb2RlIHBvcnR9LiBUaGUgYmFja2xvZyBpcyBzZXQgdG8ge0Bjb2RlIGJhY2tsb2d9LgorICAgICAqIElmIHtAY29kZSBsb2NhbEFkZHJlc3MgPT0gbnVsbH0sIHRoZSBBTlkgYWRkcmVzcyBpcyB1c2VkLgorICAgICAqIElmIHtAY29kZSBwb3J0ID09IDB9LCBhIHBvcnQgd2lsbCBiZSBhc3NpZ25lZCBieSB0aGUgT1MuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjcmVhdGluZyB0aGUgc29ja2V0LgorICAgICAqLworICAgIHB1YmxpYyBTZXJ2ZXJTb2NrZXQoaW50IHBvcnQsIGludCBiYWNrbG9nLCBJbmV0QWRkcmVzcyBsb2NhbEFkZHJlc3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrTGlzdGVuKHBvcnQpOworICAgICAgICB0aGlzLmltcGwgPSBmYWN0b3J5ICE9IG51bGwgPyBmYWN0b3J5LmNyZWF0ZVNvY2tldEltcGwoKQorICAgICAgICAgICAgICAgIDogbmV3IFBsYWluU2VydmVyU29ja2V0SW1wbCgpOworICAgICAgICBJbmV0QWRkcmVzcyBhZGRyID0gKGxvY2FsQWRkcmVzcyA9PSBudWxsKSA/IEluZXQ0QWRkcmVzcy5BTlkgOiBsb2NhbEFkZHJlc3M7CisKKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICBpbXBsLmNyZWF0ZSh0cnVlKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaW1wbC5iaW5kKGFkZHIsIHBvcnQpOworICAgICAgICAgICAgICAgIGlzQm91bmQgPSB0cnVlOworICAgICAgICAgICAgICAgIGltcGwubGlzdGVuKGJhY2tsb2cgPiAwID8gYmFja2xvZyA6IERFRkFVTFRfQkFDS0xPRyk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV2FpdHMgZm9yIGFuIGluY29taW5nIHJlcXVlc3QgYW5kIGJsb2NrcyB1bnRpbCB0aGUgY29ubmVjdGlvbiBpcyBvcGVuZWQuCisgICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhIHNvY2tldCBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBqdXN0IG9wZW5lZAorICAgICAqIGNvbm5lY3Rpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb25uZWN0aW9uIHJlcHJlc2VudGluZyBzb2NrZXQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBhY2NlcHRpbmcgYSBuZXcgY29ubmVjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU29ja2V0IGFjY2VwdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBpZiAoIWlzQm91bmQoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbigiU29ja2V0IGlzIG5vdCBib3VuZCIpOworICAgICAgICB9CisKKyAgICAgICAgU29ja2V0IGFTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbXBsQWNjZXB0KGFTb2NrZXQpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBhU29ja2V0OworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja0xpc3RlbihpbnQgYVBvcnQpIHsKKyAgICAgICAgaWYgKGFQb3J0IDwgMCB8fCBhUG9ydCA+IDY1NTM1KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQb3J0IG91dCBvZiByYW5nZTogIiArIGFQb3J0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGlzIHNlcnZlciBzb2NrZXQgYW5kIGl0cyBpbXBsZW1lbnRhdGlvbi4gQW55IGF0dGVtcHQgdG8gY29ubmVjdAorICAgICAqIHRvIHRoaXMgc29ja2V0IHRoZXJlYWZ0ZXIgd2lsbCBmYWlsLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjbG9zaW5nIHRoaXMgc29ja2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaXNDbG9zZWQgPSB0cnVlOworICAgICAgICBpbXBsLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9jYWwgSVAgYWRkcmVzcyBvZiB0aGlzIHNlcnZlciBzb2NrZXQgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqIHNvY2tldCBpcyB1bmJvdW5kLiBUaGlzIGlzIHVzZWZ1bCBmb3IgbXVsdGlob21lZCBob3N0cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxvY2FsIGFkZHJlc3Mgb2YgdGhpcyBzZXJ2ZXIgc29ja2V0LgorICAgICAqLworICAgIHB1YmxpYyBJbmV0QWRkcmVzcyBnZXRJbmV0QWRkcmVzcygpIHsKKyAgICAgICAgaWYgKCFpc0JvdW5kKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpbXBsLmdldEluZXRBZGRyZXNzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9jYWwgcG9ydCBvZiB0aGlzIHNlcnZlciBzb2NrZXQgb3Ige0Bjb2RlIC0xfSBpZiB0aGUgc29ja2V0IGlzCisgICAgICogdW5ib3VuZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxvY2FsIHBvcnQgdGhpcyBzZXJ2ZXIgaXMgbGlzdGVuaW5nIG9uLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TG9jYWxQb3J0KCkgeworICAgICAgICBpZiAoIWlzQm91bmQoKSkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpbXBsLmdldExvY2FsUG9ydCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNvY2tldCB7QGxpbmsgU29ja2V0T3B0aW9ucyNTT19USU1FT1VUIGFjY2VwdCB0aW1lb3V0fS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgb3B0aW9uIGNhbm5vdCBiZSByZXRyaWV2ZWQuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0U29UaW1lb3V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIHJldHVybiAoKEludGVnZXIpIGltcGwuZ2V0T3B0aW9uKFNvY2tldE9wdGlvbnMuU09fVElNRU9VVCkpLmludFZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW52b2tlcyB0aGUgc2VydmVyIHNvY2tldCBpbXBsZW1lbnRhdGlvbiB0byBhY2NlcHQgYSBjb25uZWN0aW9uIG9uIHRoZQorICAgICAqIGdpdmVuIHNvY2tldCB7QGNvZGUgYVNvY2tldH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYVNvY2tldAorICAgICAqICAgICAgICAgICAgdGhlIGNvbmNyZXRlIHtAY29kZSBTb2NrZXRJbXBsfSB0byBhY2NlcHQgdGhlIGNvbm5lY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHJlcXVlc3Qgb24uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjb25uZWN0aW9uIGNhbm5vdCBiZSBhY2NlcHRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBpbXBsQWNjZXB0KFNvY2tldCBhU29ja2V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGltcGwuYWNjZXB0KGFTb2NrZXQuaW1wbCk7CisgICAgICAgICAgICBhU29ja2V0LmFjY2VwdGVkKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzZXJ2ZXIgc29ja2V0IGltcGxlbWVudGF0aW9uIGZhY3Rvcnkgb2YgdGhpcyBpbnN0YW5jZS4gVGhpcworICAgICAqIG1ldGhvZCBtYXkgb25seSBiZSBpbnZva2VkIHdpdGggc3VmZmljaWVudCBzZWN1cml0eSBwcml2aWxlZ2UgYW5kIG9ubHkKKyAgICAgKiBvbmNlIGR1cmluZyB0aGUgYXBwbGljYXRpb24gbGlmZXRpbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYUZhY3RvcnkKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJlYW1pbmcgc29ja2V0IGZhY3RvcnkgdG8gYmUgdXNlZCBmb3IgZnVydGhlciBzb2NrZXQKKyAgICAgKiAgICAgICAgICAgIGluc3RhbnRpYXRpb25zLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZmFjdG9yeSBjb3VsZCBub3QgYmUgc2V0IG9yIGlzIGFscmVhZHkgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIHZvaWQgc2V0U29ja2V0RmFjdG9yeShTb2NrZXRJbXBsRmFjdG9yeSBhRmFjdG9yeSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGZhY3RvcnkgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbigiRmFjdG9yeSBhbHJlYWR5IHNldCIpOworICAgICAgICB9CisgICAgICAgIGZhY3RvcnkgPSBhRmFjdG9yeTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB7QGxpbmsgU29ja2V0T3B0aW9ucyNTT19USU1FT1VUIGFjY2VwdCB0aW1lb3V0fSBpbiBtaWxsaXNlY29uZHMgZm9yIHRoaXMgc29ja2V0LgorICAgICAqIFRoaXMgYWNjZXB0IHRpbWVvdXQgZGVmaW5lcyB0aGUgcGVyaW9kIHRoZSBzb2NrZXQgd2lsbCBibG9jayB3YWl0aW5nIHRvCisgICAgICogYWNjZXB0IGEgY29ubmVjdGlvbiBiZWZvcmUgdGhyb3dpbmcgYW4ge0Bjb2RlIEludGVycnVwdGVkSU9FeGNlcHRpb259LiBUaGUgdmFsdWUKKyAgICAgKiB7QGNvZGUgMH0gKGRlZmF1bHQpIGlzIHVzZWQgdG8gc2V0IGFuIGluZmluaXRlIHRpbWVvdXQuIFRvIGhhdmUgZWZmZWN0CisgICAgICogdGhpcyBvcHRpb24gbXVzdCBiZSBzZXQgYmVmb3JlIHRoZSBibG9ja2luZyBtZXRob2Qgd2FzIGNhbGxlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aW1lb3V0IHRoZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyBvciAwIGZvciBubyB0aW1lb3V0LgorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHNldHRpbmcgdGhlIG9wdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0U29UaW1lb3V0KGludCB0aW1lb3V0KSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIGlmICh0aW1lb3V0IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigidGltZW91dCA8IDAiKTsKKyAgICAgICAgfQorICAgICAgICBpbXBsLnNldE9wdGlvbihTb2NrZXRPcHRpb25zLlNPX1RJTUVPVVQsIEludGVnZXIudmFsdWVPZih0aW1lb3V0KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBzZXJ2ZXIgc29ja2V0IGluY2x1ZGluZyB0aGUKKyAgICAgKiBhZGRyZXNzLCBwb3J0IGFuZCB0aGUgc3RhdGUuIFRoZSBwb3J0IGZpZWxkIGlzIHNldCB0byB7QGNvZGUgMH0gaWYgdGhlcmUKKyAgICAgKiBpcyBubyBjb25uZWN0aW9uIHRvIHRoZSBzZXJ2ZXIgc29ja2V0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdGV4dHVhbCBzb2NrZXQgcmVwcmVzZW50YXRpb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcig2NCk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQoIlNlcnZlclNvY2tldFsiKTsKKyAgICAgICAgaWYgKCFpc0JvdW5kKCkpIHsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQuYXBwZW5kKCJ1bmJvdW5kXSIpLnRvU3RyaW5nKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdC5hcHBlbmQoImFkZHI9IikKKyAgICAgICAgICAgICAgICAuYXBwZW5kKGdldEluZXRBZGRyZXNzKCkuZ2V0SG9zdE5hbWUoKSkuYXBwZW5kKCIvIikKKyAgICAgICAgICAgICAgICAuYXBwZW5kKGdldEluZXRBZGRyZXNzKCkuZ2V0SG9zdEFkZHJlc3MoKSkuYXBwZW5kKAorICAgICAgICAgICAgICAgICAgICAgICAgIixwb3J0PTAsbG9jYWxwb3J0PSIpCisgICAgICAgICAgICAgICAgLmFwcGVuZChnZXRMb2NhbFBvcnQoKSkuYXBwZW5kKCJdIikKKyAgICAgICAgICAgICAgICAudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBCaW5kcyB0aGlzIHNlcnZlciBzb2NrZXQgdG8gdGhlIGdpdmVuIGxvY2FsIHNvY2tldCBhZGRyZXNzIHdpdGggYSBtYXhpbXVtCisgICAgICogYmFja2xvZyBvZiA1MCB1bmFjY2VwdGVkIGNvbm5lY3Rpb25zLiBJZiB0aGUge0Bjb2RlIGxvY2FsQWRkcn0gaXMgc2V0IHRvCisgICAgICoge0Bjb2RlIG51bGx9IHRoZSBzb2NrZXQgd2lsbCBiZSBib3VuZCB0byBhbiBhdmFpbGFibGUgbG9jYWwgYWRkcmVzcyBvbgorICAgICAqIGFueSBmcmVlIHBvcnQgb2YgdGhlIHN5c3RlbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhbEFkZHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhbCBhZGRyZXNzIGFuZCBwb3J0IHRvIGJpbmQgb24uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIFNvY2tldEFkZHJlc3N9IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzb2NrZXQgaXMgYWxyZWFkeSBib3VuZCBvciBhIHByb2JsZW0gb2NjdXJzIGR1cmluZworICAgICAqICAgICAgICAgICAgIGJpbmRpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYmluZChTb2NrZXRBZGRyZXNzIGxvY2FsQWRkcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYmluZChsb2NhbEFkZHIsIERFRkFVTFRfQkFDS0xPRyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQmluZHMgdGhpcyBzZXJ2ZXIgc29ja2V0IHRvIHRoZSBnaXZlbiBsb2NhbCBzb2NrZXQgYWRkcmVzcy4gSWYgdGhlCisgICAgICoge0Bjb2RlIGxvY2FsQWRkcn0gaXMgc2V0IHRvIHtAY29kZSBudWxsfSB0aGUgc29ja2V0IHdpbGwgYmUgYm91bmQgdG8gYW4KKyAgICAgKiBhdmFpbGFibGUgbG9jYWwgYWRkcmVzcyBvbiBhbnkgZnJlZSBwb3J0IG9mIHRoZSBzeXN0ZW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYWxBZGRyIHRoZSBsb2NhbCBtYWNoaW5lIGFkZHJlc3MgYW5kIHBvcnQgdG8gYmluZCBvbi4KKyAgICAgKiBAcGFyYW0gYmFja2xvZyB0aGUgbWF4aW11bSBudW1iZXIgb2YgdW5hY2NlcHRlZCBjb25uZWN0aW9ucy4gUGFzc2luZyAwIG9yCisgICAgICogICAgIGEgbmVnYXRpdmUgdmFsdWUgeWllbGRzIHRoZSBkZWZhdWx0IGJhY2tsb2cgb2YgNTAuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIHtAY29kZSBTb2NrZXRBZGRyZXNzfSBpcyBub3QKKyAgICAgKiAgICAgc3VwcG9ydGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgdGhlIHNvY2tldCBpcyBhbHJlYWR5IGJvdW5kIG9yIGEgcHJvYmxlbSBvY2N1cnMKKyAgICAgKiAgICAgZHVyaW5nIGJpbmRpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYmluZChTb2NrZXRBZGRyZXNzIGxvY2FsQWRkciwgaW50IGJhY2tsb2cpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBpZiAoaXNCb3VuZCgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQmluZEV4Y2VwdGlvbigiU29ja2V0IGlzIGFscmVhZHkgYm91bmQiKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgcG9ydCA9IDA7CisgICAgICAgIEluZXRBZGRyZXNzIGFkZHIgPSBJbmV0NEFkZHJlc3MuQU5ZOworICAgICAgICBpZiAobG9jYWxBZGRyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmICghKGxvY2FsQWRkciBpbnN0YW5jZW9mIEluZXRTb2NrZXRBZGRyZXNzKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkxvY2FsIGFkZHJlc3Mgbm90IGFuIEluZXRTb2NrZXRBZGRyZXNzOiAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsQWRkci5nZXRDbGFzcygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIGluZXRBZGRyID0gKEluZXRTb2NrZXRBZGRyZXNzKSBsb2NhbEFkZHI7CisgICAgICAgICAgICBpZiAoKGFkZHIgPSBpbmV0QWRkci5nZXRBZGRyZXNzKCkpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKCJIb3N0IGlzIHVucmVzb2x2ZWQ6ICIgKyBpbmV0QWRkci5nZXRIb3N0TmFtZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBvcnQgPSBpbmV0QWRkci5nZXRQb3J0KCk7CisgICAgICAgIH0KKworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaW1wbC5iaW5kKGFkZHIsIHBvcnQpOworICAgICAgICAgICAgICAgIGlzQm91bmQgPSB0cnVlOworICAgICAgICAgICAgICAgIGltcGwubGlzdGVuKGJhY2tsb2cgPiAwID8gYmFja2xvZyA6IERFRkFVTFRfQkFDS0xPRyk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9jYWwgc29ja2V0IGFkZHJlc3Mgb2YgdGhpcyBzZXJ2ZXIgc29ja2V0IG9yIHtAY29kZSBudWxsfSBpZgorICAgICAqIHRoZSBzb2NrZXQgaXMgdW5ib3VuZC4gVGhpcyBpcyB1c2VmdWwgb24gbXVsdGlob21lZCBob3N0cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxvY2FsIHNvY2tldCBhZGRyZXNzIGFuZCBwb3J0IHRoaXMgc29ja2V0IGlzIGJvdW5kIHRvLgorICAgICAqLworICAgIHB1YmxpYyBTb2NrZXRBZGRyZXNzIGdldExvY2FsU29ja2V0QWRkcmVzcygpIHsKKyAgICAgICAgaWYgKCFpc0JvdW5kKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgSW5ldFNvY2tldEFkZHJlc3MoZ2V0SW5ldEFkZHJlc3MoKSwgZ2V0TG9jYWxQb3J0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIHNlcnZlciBzb2NrZXQgaXMgYm91bmQgdG8gYSBsb2NhbCBhZGRyZXNzIGFuZCBwb3J0CisgICAgICogb3Igbm90LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBzb2NrZXQgaXMgYm91bmQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQm91bmQoKSB7CisgICAgICAgIHJldHVybiBpc0JvdW5kOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIHNlcnZlciBzb2NrZXQgaXMgY2xvc2VkIG9yIG5vdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgc29ja2V0IGlzIGNsb3NlZCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDbG9zZWQoKSB7CisgICAgICAgIHJldHVybiBpc0Nsb3NlZDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tPcGVuKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpc0Nsb3NlZCgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKCJTb2NrZXQgaXMgY2xvc2VkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBmb3IgdGhlIHNvY2tldCBvcHRpb24ge0Bjb2RlIFNvY2tldE9wdGlvbnMuU09fUkVVU0VBRERSfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZXVzZQorICAgICAqICAgICAgICAgICAgdGhlIHNvY2tldCBvcHRpb24gc2V0dGluZy4KKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBzZXR0aW5nIHRoZSBvcHRpb24gdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmV1c2VBZGRyZXNzKGJvb2xlYW4gcmV1c2UpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgaW1wbC5zZXRPcHRpb24oU29ja2V0T3B0aW9ucy5TT19SRVVTRUFERFIsIEJvb2xlYW4udmFsdWVPZihyZXVzZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBzb2NrZXQgb3B0aW9uIHtAY29kZSBTb2NrZXRPcHRpb25zLlNPX1JFVVNFQUREUn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgb3B0aW9uIGlzIGVuYWJsZWQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU29ja2V0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgdGhlIG9wdGlvbiB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRSZXVzZUFkZHJlc3MoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIHJldHVybiAoKEJvb2xlYW4pIGltcGwuZ2V0T3B0aW9uKFNvY2tldE9wdGlvbnMuU09fUkVVU0VBRERSKSkuYm9vbGVhblZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGlzIHNvY2tldCdzIHtAbGluayBTb2NrZXRPcHRpb25zI1NPX1NOREJVRiByZWNlaXZlIGJ1ZmZlciBzaXplfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSZWNlaXZlQnVmZmVyU2l6ZShpbnQgc2l6ZSkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBpZiAoc2l6ZSA8IDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInNpemUgPCAxIik7CisgICAgICAgIH0KKyAgICAgICAgaW1wbC5zZXRPcHRpb24oU29ja2V0T3B0aW9ucy5TT19SQ1ZCVUYsIEludGVnZXIudmFsdWVPZihzaXplKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHNvY2tldCdzIHtAbGluayBTb2NrZXRPcHRpb25zI1NPX1JDVkJVRiByZWNlaXZlIGJ1ZmZlciBzaXplfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFJlY2VpdmVCdWZmZXJTaXplKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICByZXR1cm4gKChJbnRlZ2VyKSBpbXBsLmdldE9wdGlvbihTb2NrZXRPcHRpb25zLlNPX1JDVkJVRikpLmludFZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHNvY2tldCdzIHtAY29kZSBTZXJ2ZXJTb2NrZXRDaGFubmVsfSwgaWYgb25lIGV4aXN0cy4gQSBjaGFubmVsIGlzCisgICAgICogYXZhaWxhYmxlIG9ubHkgaWYgdGhpcyBzb2NrZXQgd3JhcHMgYSBjaGFubmVsLiAoVGhhdCBpcywgeW91IGNhbiBnbyBmcm9tIGEKKyAgICAgKiBjaGFubmVsIHRvIGEgc29ja2V0IGFuZCBiYWNrIGFnYWluLCBidXQgeW91IGNhbid0IGdvIGZyb20gYW4gYXJiaXRyYXJ5IHNvY2tldCB0byBhIGNoYW5uZWwuKQorICAgICAqIEluIHByYWN0aWNlLCB0aGlzIG1lYW5zIHRoYXQgdGhlIHNvY2tldCBtdXN0IGhhdmUgYmVlbiBjcmVhdGVkIGJ5CisgICAgICoge0BsaW5rIGphdmEubmlvLmNoYW5uZWxzLlNlcnZlclNvY2tldENoYW5uZWwjb3Blbn0uCisgICAgICovCisgICAgcHVibGljIFNlcnZlclNvY2tldENoYW5uZWwgZ2V0Q2hhbm5lbCgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBwZXJmb3JtYW5jZSBwcmVmZXJlbmNlcyBmb3IgY29ubmVjdGlvbiB0aW1lLCBsYXRlbmN5IGFuZCBiYW5kd2lkdGguCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgZG9lcyBjdXJyZW50bHkgbm90aGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb25uZWN0aW9uVGltZQorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgaW1wb3J0YW5jZSBvZiBhIHNob3J0IGNvbm5lY3RpbmcKKyAgICAgKiAgICAgICAgICAgIHRpbWUuCisgICAgICogQHBhcmFtIGxhdGVuY3kKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIGltcG9ydGFuY2Ugb2YgbG93IGxhdGVuY3kuCisgICAgICogQHBhcmFtIGJhbmR3aWR0aAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgaW1wb3J0YW5jZSBvZiBoaWdoIGJhbmR3aWR0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQZXJmb3JtYW5jZVByZWZlcmVuY2VzKGludCBjb25uZWN0aW9uVGltZSwgaW50IGxhdGVuY3ksIGludCBiYW5kd2lkdGgpIHsKKyAgICAgICAgLy8gT3VyIHNvY2tldCBpbXBsZW1lbnRhdGlvbiBvbmx5IHByb3ZpZGUgb25lIHByb3RvY29sOiBUQ1AvSVAsIHNvCisgICAgICAgIC8vIHdlIGRvIG5vdGhpbmcgZm9yIHRoaXMgbWV0aG9kCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1NvY2tldC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1NvY2tldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2NjFmMjgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvU29ja2V0LmphdmEKQEAgLTAsMCArMSw5ODkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5Tb2NrZXRDaGFubmVsOworaW1wb3J0IGxpYmNvcmUuaW8uSW9CcmlkZ2U7CisKKy8qKgorICogUHJvdmlkZXMgYSBjbGllbnQtc2lkZSBUQ1Agc29ja2V0LgorICovCitwdWJsaWMgY2xhc3MgU29ja2V0IHsKKyAgICBwcml2YXRlIHN0YXRpYyBTb2NrZXRJbXBsRmFjdG9yeSBmYWN0b3J5OworCisgICAgZmluYWwgU29ja2V0SW1wbCBpbXBsOworICAgIHByaXZhdGUgZmluYWwgUHJveHkgcHJveHk7CisKKyAgICB2b2xhdGlsZSBib29sZWFuIGlzQ3JlYXRlZCA9IGZhbHNlOworICAgIHByaXZhdGUgYm9vbGVhbiBpc0JvdW5kID0gZmFsc2U7CisgICAgcHJpdmF0ZSBib29sZWFuIGlzQ29ubmVjdGVkID0gZmFsc2U7CisgICAgcHJpdmF0ZSBib29sZWFuIGlzQ2xvc2VkID0gZmFsc2U7CisgICAgcHJpdmF0ZSBib29sZWFuIGlzSW5wdXRTaHV0ZG93biA9IGZhbHNlOworICAgIHByaXZhdGUgYm9vbGVhbiBpc091dHB1dFNodXRkb3duID0gZmFsc2U7CisKKyAgICBwcml2YXRlIEluZXRBZGRyZXNzIGxvY2FsQWRkcmVzcyA9IEluZXQ0QWRkcmVzcy5BTlk7CisKKyAgICBwcml2YXRlIGZpbmFsIE9iamVjdCBjb25uZWN0TG9jayA9IG5ldyBPYmplY3QoKTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgdW5jb25uZWN0ZWQgc29ja2V0LiBXaGVuIGEgU29ja2V0SW1wbEZhY3RvcnkgaXMgZGVmaW5lZCBpdAorICAgICAqIGNyZWF0ZXMgdGhlIGludGVybmFsIHNvY2tldCBpbXBsZW1lbnRhdGlvbiwgb3RoZXJ3aXNlIHRoZSBkZWZhdWx0IHNvY2tldAorICAgICAqIGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBmb3IgdGhpcyBzb2NrZXQuCisgICAgICoKKyAgICAgKiBAc2VlIFNvY2tldEltcGxGYWN0b3J5CisgICAgICogQHNlZSBTb2NrZXRJbXBsCisgICAgICovCisgICAgcHVibGljIFNvY2tldCgpIHsKKyAgICAgICAgdGhpcy5pbXBsID0gZmFjdG9yeSAhPSBudWxsID8gZmFjdG9yeS5jcmVhdGVTb2NrZXRJbXBsKCkgOiBuZXcgUGxhaW5Tb2NrZXRJbXBsKCk7CisgICAgICAgIHRoaXMucHJveHkgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgdW5jb25uZWN0ZWQgc29ja2V0IHVzaW5nIHRoZSBnaXZlbiBwcm94eSB0eXBlLiBXaGVuIGEKKyAgICAgKiB7QGNvZGUgU29ja2V0SW1wbEZhY3Rvcnl9IGlzIGRlZmluZWQgaXQgY3JlYXRlcyB0aGUgaW50ZXJuYWwgc29ja2V0CisgICAgICogaW1wbGVtZW50YXRpb24sIG90aGVyd2lzZSB0aGUgZGVmYXVsdCBzb2NrZXQgaW1wbGVtZW50YXRpb24gd2lsbCBiZSB1c2VkCisgICAgICogZm9yIHRoaXMgc29ja2V0LgorICAgICAqIDxwPgorICAgICAqIEV4YW1wbGUgdGhhdCB3aWxsIGNyZWF0ZSBhIHNvY2tldCBjb25uZWN0aW9uIHRocm91Z2ggYSB7QGNvZGUgU09DS1N9CisgICAgICogcHJveHkgc2VydmVyOiA8YnI+CisgICAgICoge0Bjb2RlIFNvY2tldCBzb2NrID0gbmV3IFNvY2tldChuZXcgUHJveHkoUHJveHkuVHlwZS5TT0NLUywgbmV3CisgICAgICogSW5ldFNvY2tldEFkZHJlc3MoInRlc3QuZG9tYWluLm9yZyIsIDIxMzApKSk7fQorICAgICAqCisgICAgICogQHBhcmFtIHByb3h5CisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIHByb3h5IGZvciB0aGlzIHNvY2tldC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhcmd1bWVudCB7QGNvZGUgcHJveHl9IGlzIHtAY29kZSBudWxsfSBvciBvZiBhbgorICAgICAqICAgICAgICAgICAgIGludmFsaWQgdHlwZS4KKyAgICAgKiBAc2VlIFNvY2tldEltcGxGYWN0b3J5CisgICAgICogQHNlZSBTb2NrZXRJbXBsCisgICAgICovCisgICAgcHVibGljIFNvY2tldChQcm94eSBwcm94eSkgeworICAgICAgICBpZiAocHJveHkgPT0gbnVsbCB8fCBwcm94eS50eXBlKCkgPT0gUHJveHkuVHlwZS5IVFRQKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIHByb3h5OiAiICsgcHJveHkpOworICAgICAgICB9CisgICAgICAgIHRoaXMucHJveHkgPSBwcm94eTsKKyAgICAgICAgdGhpcy5pbXBsID0gZmFjdG9yeSAhPSBudWxsID8gZmFjdG9yeS5jcmVhdGVTb2NrZXRJbXBsKCkgOiBuZXcgUGxhaW5Tb2NrZXRJbXBsKHByb3h5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmllcyB0byBjb25uZWN0IGEgc29ja2V0IHRvIGFsbCBJUCBhZGRyZXNzZXMgb2YgdGhlIGdpdmVuIGhvc3RuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIGRzdE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgaG9zdCBuYW1lIG9yIElQIGFkZHJlc3MgdG8gY29ubmVjdCB0by4KKyAgICAgKiBAcGFyYW0gZHN0UG9ydAorICAgICAqICAgICAgICAgICAgdGhlIHBvcnQgb24gdGhlIHRhcmdldCBob3N0IHRvIGNvbm5lY3QgdG8uCisgICAgICogQHBhcmFtIGxvY2FsQWRkcmVzcworICAgICAqICAgICAgICAgICAgdGhlIGFkZHJlc3Mgb24gdGhlIGxvY2FsIGhvc3QgdG8gYmluZCB0by4KKyAgICAgKiBAcGFyYW0gbG9jYWxQb3J0CisgICAgICogICAgICAgICAgICB0aGUgcG9ydCBvbiB0aGUgbG9jYWwgaG9zdCB0byBiaW5kIHRvLgorICAgICAqIEBwYXJhbSBzdHJlYW1pbmcKKyAgICAgKiAgICAgICAgICAgIGlmIHtAY29kZSB0cnVlfSBhIHN0cmVhbWluZyBzb2NrZXQgaXMgcmV0dXJuZWQsIGEgZGF0YWdyYW0KKyAgICAgKiAgICAgICAgICAgIHNvY2tldCBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBob3N0IG5hbWUgY291bGQgbm90IGJlIHJlc29sdmVkIGludG8gYW4gSVAgYWRkcmVzcy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNyZWF0aW5nIHRoZSBzb2NrZXQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHRyeUFsbEFkZHJlc3NlcyhTdHJpbmcgZHN0TmFtZSwgaW50IGRzdFBvcnQsIEluZXRBZGRyZXNzCisgICAgICAgICAgICBsb2NhbEFkZHJlc3MsIGludCBsb2NhbFBvcnQsIGJvb2xlYW4gc3RyZWFtaW5nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBJbmV0QWRkcmVzc1tdIGRzdEFkZHJlc3NlcyA9IEluZXRBZGRyZXNzLmdldEFsbEJ5TmFtZShkc3ROYW1lKTsKKyAgICAgICAgLy8gTG9vcCB0aHJvdWdoIGFsbCB0aGUgZGVzdGluYXRpb24gYWRkcmVzc2VzIGV4Y2VwdCB0aGUgbGFzdCwgdHJ5aW5nIHRvCisgICAgICAgIC8vIGNvbm5lY3QgdG8gZWFjaCBvbmUgYW5kIGlnbm9yaW5nIGVycm9ycy4gVGhlcmUgbXVzdCBiZSBhdCBsZWFzdCBvbmUKKyAgICAgICAgLy8gYWRkcmVzcywgb3IgZ2V0QWxsQnlOYW1lIHdvdWxkIGhhdmUgdGhyb3duIFVua25vd25Ib3N0RXhjZXB0aW9uLgorICAgICAgICBJbmV0QWRkcmVzcyBkc3RBZGRyZXNzOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRzdEFkZHJlc3Nlcy5sZW5ndGggLSAxOyBpKyspIHsKKyAgICAgICAgICAgIGRzdEFkZHJlc3MgPSBkc3RBZGRyZXNzZXNbaV07CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNoZWNrRGVzdGluYXRpb24oZHN0QWRkcmVzcywgZHN0UG9ydCk7CisgICAgICAgICAgICAgICAgc3RhcnR1cFNvY2tldChkc3RBZGRyZXNzLCBkc3RQb3J0LCBsb2NhbEFkZHJlc3MsIGxvY2FsUG9ydCwgc3RyZWFtaW5nKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gTm93IHRyeSB0byBjb25uZWN0IHRvIHRoZSBsYXN0IGFkZHJlc3MgaW4gdGhlIGFycmF5LCBoYW5kaW5nIGJhY2sgdG8KKyAgICAgICAgLy8gdGhlIGNhbGxlciBhbnkgZXhjZXB0aW9ucyB0aGF0IGFyZSB0aHJvd24uCisgICAgICAgIGRzdEFkZHJlc3MgPSBkc3RBZGRyZXNzZXNbZHN0QWRkcmVzc2VzLmxlbmd0aCAtIDFdOworICAgICAgICBjaGVja0Rlc3RpbmF0aW9uKGRzdEFkZHJlc3MsIGRzdFBvcnQpOworICAgICAgICBzdGFydHVwU29ja2V0KGRzdEFkZHJlc3MsIGRzdFBvcnQsIGxvY2FsQWRkcmVzcywgbG9jYWxQb3J0LCBzdHJlYW1pbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgc3RyZWFtaW5nIHNvY2tldCBjb25uZWN0ZWQgdG8gdGhlIHRhcmdldCBob3N0IHNwZWNpZmllZCBieQorICAgICAqIHRoZSBwYXJhbWV0ZXJzIHtAY29kZSBkc3ROYW1lfSBhbmQge0Bjb2RlIGRzdFBvcnR9LiBUaGUgc29ja2V0IGlzIGJvdW5kCisgICAgICogdG8gYW55IGF2YWlsYWJsZSBwb3J0IG9uIHRoZSBsb2NhbCBob3N0LgorICAgICAqCisgICAgICogPHA+VGhpcyBpbXBsZW1lbnRhdGlvbiB0cmllcyBlYWNoIElQIGFkZHJlc3MgZm9yIHRoZSBnaXZlbiBob3N0bmFtZSAoaW4KKyAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzNDg0LnR4dCI+UkZDIDM0ODQ8L2E+IG9yZGVyKQorICAgICAqIHVudGlsIGl0IGVpdGhlciBjb25uZWN0cyBzdWNjZXNzZnVsbHkgb3IgaXQgZXhoYXVzdHMgdGhlIHNldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkc3ROYW1lCisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IGhvc3QgbmFtZSBvciBJUCBhZGRyZXNzIHRvIGNvbm5lY3QgdG8uCisgICAgICogQHBhcmFtIGRzdFBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IG9uIHRoZSB0YXJnZXQgaG9zdCB0byBjb25uZWN0IHRvLgorICAgICAqIEB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaG9zdCBuYW1lIGNvdWxkIG5vdCBiZSByZXNvbHZlZCBpbnRvIGFuIElQIGFkZHJlc3MuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjcmVhdGluZyB0aGUgc29ja2V0LgorICAgICAqLworICAgIHB1YmxpYyBTb2NrZXQoU3RyaW5nIGRzdE5hbWUsIGludCBkc3RQb3J0KSB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhkc3ROYW1lLCBkc3RQb3J0LCBudWxsLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHN0cmVhbWluZyBzb2NrZXQgY29ubmVjdGVkIHRvIHRoZSB0YXJnZXQgaG9zdCBzcGVjaWZpZWQgYnkKKyAgICAgKiB0aGUgcGFyYW1ldGVycyB7QGNvZGUgZHN0TmFtZX0gYW5kIHtAY29kZSBkc3RQb3J0fS4gT24gdGhlIGxvY2FsIGVuZHBvaW50CisgICAgICogdGhlIHNvY2tldCBpcyBib3VuZCB0byB0aGUgZ2l2ZW4gYWRkcmVzcyB7QGNvZGUgbG9jYWxBZGRyZXNzfSBvbiBwb3J0CisgICAgICoge0Bjb2RlIGxvY2FsUG9ydH0uIElmIHtAY29kZSBob3N0fSBpcyB7QGNvZGUgbnVsbH0gYSBsb29wYmFjayBhZGRyZXNzIGlzIHVzZWQgdG8gY29ubmVjdCB0by4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gdHJpZXMgZWFjaCBJUCBhZGRyZXNzIGZvciB0aGUgZ2l2ZW4gaG9zdG5hbWUgKGluCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzQ4NC50eHQiPlJGQyAzNDg0PC9hPiBvcmRlcikKKyAgICAgKiB1bnRpbCBpdCBlaXRoZXIgY29ubmVjdHMgc3VjY2Vzc2Z1bGx5IG9yIGl0IGV4aGF1c3RzIHRoZSBzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZHN0TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBob3N0IG5hbWUgb3IgSVAgYWRkcmVzcyB0byBjb25uZWN0IHRvLgorICAgICAqIEBwYXJhbSBkc3RQb3J0CisgICAgICogICAgICAgICAgICB0aGUgcG9ydCBvbiB0aGUgdGFyZ2V0IGhvc3QgdG8gY29ubmVjdCB0by4KKyAgICAgKiBAcGFyYW0gbG9jYWxBZGRyZXNzCisgICAgICogICAgICAgICAgICB0aGUgYWRkcmVzcyBvbiB0aGUgbG9jYWwgaG9zdCB0byBiaW5kIHRvLgorICAgICAqIEBwYXJhbSBsb2NhbFBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IG9uIHRoZSBsb2NhbCBob3N0IHRvIGJpbmQgdG8uCisgICAgICogQHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBob3N0IG5hbWUgY291bGQgbm90IGJlIHJlc29sdmVkIGludG8gYW4gSVAgYWRkcmVzcy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNyZWF0aW5nIHRoZSBzb2NrZXQuCisgICAgICovCisgICAgcHVibGljIFNvY2tldChTdHJpbmcgZHN0TmFtZSwgaW50IGRzdFBvcnQsIEluZXRBZGRyZXNzIGxvY2FsQWRkcmVzcywgaW50IGxvY2FsUG9ydCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcygpOworICAgICAgICB0cnlBbGxBZGRyZXNzZXMoZHN0TmFtZSwgZHN0UG9ydCwgbG9jYWxBZGRyZXNzLCBsb2NhbFBvcnQsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgc3RyZWFtaW5nIG9yIGRhdGFncmFtIHNvY2tldCBjb25uZWN0ZWQgdG8gdGhlIHRhcmdldCBob3N0CisgICAgICogc3BlY2lmaWVkIGJ5IHRoZSBwYXJhbWV0ZXJzIHtAY29kZSBob3N0TmFtZX0gYW5kIHtAY29kZSBwb3J0fS4gVGhlIHNvY2tldAorICAgICAqIGlzIGJvdW5kIHRvIGFueSBhdmFpbGFibGUgcG9ydCBvbiB0aGUgbG9jYWwgaG9zdC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gdHJpZXMgZWFjaCBJUCBhZGRyZXNzIGZvciB0aGUgZ2l2ZW4gaG9zdG5hbWUgKGluCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzQ4NC50eHQiPlJGQyAzNDg0PC9hPiBvcmRlcikKKyAgICAgKiB1bnRpbCBpdCBlaXRoZXIgY29ubmVjdHMgc3VjY2Vzc2Z1bGx5IG9yIGl0IGV4aGF1c3RzIHRoZSBzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaG9zdE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgaG9zdCBuYW1lIG9yIElQIGFkZHJlc3MgdG8gY29ubmVjdCB0by4KKyAgICAgKiBAcGFyYW0gcG9ydAorICAgICAqICAgICAgICAgICAgdGhlIHBvcnQgb24gdGhlIHRhcmdldCBob3N0IHRvIGNvbm5lY3QgdG8uCisgICAgICogQHBhcmFtIHN0cmVhbWluZworICAgICAqICAgICAgICAgICAgaWYge0Bjb2RlIHRydWV9IGEgc3RyZWFtaW5nIHNvY2tldCBpcyByZXR1cm5lZCwgYSBkYXRhZ3JhbQorICAgICAqICAgICAgICAgICAgc29ja2V0IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFVua25vd25Ib3N0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGhvc3QgbmFtZSBjb3VsZCBub3QgYmUgcmVzb2x2ZWQgaW50byBhbiBJUCBhZGRyZXNzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY3JlYXRpbmcgdGhlIHNvY2tldC4KKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0Bjb2RlIFNvY2tldChTdHJpbmcsIGludCl9IGluc3RlYWQgb2YgdGhpcyBmb3Igc3RyZWFtaW5nCisgICAgICogICAgICAgICAgICAgc29ja2V0cyBvciBhbiBhcHByb3ByaWF0ZSBjb25zdHJ1Y3RvciBvZiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBEYXRhZ3JhbVNvY2tldH0gZm9yIFVEUCB0cmFuc3BvcnQuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgU29ja2V0KFN0cmluZyBob3N0TmFtZSwgaW50IHBvcnQsIGJvb2xlYW4gc3RyZWFtaW5nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKCk7CisgICAgICAgIHRyeUFsbEFkZHJlc3Nlcyhob3N0TmFtZSwgcG9ydCwgbnVsbCwgMCwgc3RyZWFtaW5nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHN0cmVhbWluZyBzb2NrZXQgY29ubmVjdGVkIHRvIHRoZSB0YXJnZXQgaG9zdCBzcGVjaWZpZWQgYnkKKyAgICAgKiB0aGUgcGFyYW1ldGVycyB7QGNvZGUgZHN0QWRkcmVzc30gYW5kIHtAY29kZSBkc3RQb3J0fS4gVGhlIHNvY2tldCBpcworICAgICAqIGJvdW5kIHRvIGFueSBhdmFpbGFibGUgcG9ydCBvbiB0aGUgbG9jYWwgaG9zdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkc3RBZGRyZXNzCisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IGhvc3QgYWRkcmVzcyB0byBjb25uZWN0IHRvLgorICAgICAqIEBwYXJhbSBkc3RQb3J0CisgICAgICogICAgICAgICAgICB0aGUgcG9ydCBvbiB0aGUgdGFyZ2V0IGhvc3QgdG8gY29ubmVjdCB0by4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNyZWF0aW5nIHRoZSBzb2NrZXQuCisgICAgICovCisgICAgcHVibGljIFNvY2tldChJbmV0QWRkcmVzcyBkc3RBZGRyZXNzLCBpbnQgZHN0UG9ydCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcygpOworICAgICAgICBjaGVja0Rlc3RpbmF0aW9uKGRzdEFkZHJlc3MsIGRzdFBvcnQpOworICAgICAgICBzdGFydHVwU29ja2V0KGRzdEFkZHJlc3MsIGRzdFBvcnQsIG51bGwsIDAsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgc3RyZWFtaW5nIHNvY2tldCBjb25uZWN0ZWQgdG8gdGhlIHRhcmdldCBob3N0IHNwZWNpZmllZCBieQorICAgICAqIHRoZSBwYXJhbWV0ZXJzIHtAY29kZSBkc3RBZGRyZXNzfSBhbmQge0Bjb2RlIGRzdFBvcnR9LiBPbiB0aGUgbG9jYWwKKyAgICAgKiBlbmRwb2ludCB0aGUgc29ja2V0IGlzIGJvdW5kIHRvIHRoZSBnaXZlbiBhZGRyZXNzIHtAY29kZSBsb2NhbEFkZHJlc3N9IG9uCisgICAgICogcG9ydCB7QGNvZGUgbG9jYWxQb3J0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkc3RBZGRyZXNzCisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IGhvc3QgYWRkcmVzcyB0byBjb25uZWN0IHRvLgorICAgICAqIEBwYXJhbSBkc3RQb3J0CisgICAgICogICAgICAgICAgICB0aGUgcG9ydCBvbiB0aGUgdGFyZ2V0IGhvc3QgdG8gY29ubmVjdCB0by4KKyAgICAgKiBAcGFyYW0gbG9jYWxBZGRyZXNzCisgICAgICogICAgICAgICAgICB0aGUgYWRkcmVzcyBvbiB0aGUgbG9jYWwgaG9zdCB0byBiaW5kIHRvLgorICAgICAqIEBwYXJhbSBsb2NhbFBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IG9uIHRoZSBsb2NhbCBob3N0IHRvIGJpbmQgdG8uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjcmVhdGluZyB0aGUgc29ja2V0LgorICAgICAqLworICAgIHB1YmxpYyBTb2NrZXQoSW5ldEFkZHJlc3MgZHN0QWRkcmVzcywgaW50IGRzdFBvcnQsCisgICAgICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbEFkZHJlc3MsIGludCBsb2NhbFBvcnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoKTsKKyAgICAgICAgY2hlY2tEZXN0aW5hdGlvbihkc3RBZGRyZXNzLCBkc3RQb3J0KTsKKyAgICAgICAgc3RhcnR1cFNvY2tldChkc3RBZGRyZXNzLCBkc3RQb3J0LCBsb2NhbEFkZHJlc3MsIGxvY2FsUG9ydCwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBzdHJlYW1pbmcgb3IgZGF0YWdyYW0gc29ja2V0IGNvbm5lY3RlZCB0byB0aGUgdGFyZ2V0IGhvc3QKKyAgICAgKiBzcGVjaWZpZWQgYnkgdGhlIHBhcmFtZXRlcnMge0Bjb2RlIGFkZHJ9IGFuZCB7QGNvZGUgcG9ydH0uIFRoZSBzb2NrZXQgaXMKKyAgICAgKiBib3VuZCB0byBhbnkgYXZhaWxhYmxlIHBvcnQgb24gdGhlIGxvY2FsIGhvc3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWRkcgorICAgICAqICAgICAgICAgICAgdGhlIEludGVybmV0IGFkZHJlc3MgdG8gY29ubmVjdCB0by4KKyAgICAgKiBAcGFyYW0gcG9ydAorICAgICAqICAgICAgICAgICAgdGhlIHBvcnQgb24gdGhlIHRhcmdldCBob3N0IHRvIGNvbm5lY3QgdG8uCisgICAgICogQHBhcmFtIHN0cmVhbWluZworICAgICAqICAgICAgICAgICAgaWYge0Bjb2RlIHRydWV9IGEgc3RyZWFtaW5nIHNvY2tldCBpcyByZXR1cm5lZCwgYSBkYXRhZ3JhbQorICAgICAqICAgICAgICAgICAgc29ja2V0IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNyZWF0aW5nIHRoZSBzb2NrZXQuCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAY29kZSBTb2NrZXQoSW5ldEFkZHJlc3MsIGludCl9IGluc3RlYWQgb2YgdGhpcyBmb3IKKyAgICAgKiAgICAgICAgICAgICBzdHJlYW1pbmcgc29ja2V0cyBvciBhbiBhcHByb3ByaWF0ZSBjb25zdHJ1Y3RvciBvZiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBEYXRhZ3JhbVNvY2tldH0gZm9yIFVEUCB0cmFuc3BvcnQuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgU29ja2V0KEluZXRBZGRyZXNzIGFkZHIsIGludCBwb3J0LCBib29sZWFuIHN0cmVhbWluZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcygpOworICAgICAgICBjaGVja0Rlc3RpbmF0aW9uKGFkZHIsIHBvcnQpOworICAgICAgICBzdGFydHVwU29ja2V0KGFkZHIsIHBvcnQsIG51bGwsIDAsIHN0cmVhbWluZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiB1bmNvbm5lY3RlZCBzb2NrZXQgd2l0aCB0aGUgZ2l2ZW4gc29ja2V0IGltcGxlbWVudGF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGltcGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb2NrZXQgaW1wbGVtZW50YXRpb24gdG8gYmUgdXNlZC4KKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjcmVhdGluZyB0aGUgc29ja2V0LgorICAgICAqLworICAgIHByb3RlY3RlZCBTb2NrZXQoU29ja2V0SW1wbCBpbXBsKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5pbXBsID0gaW1wbDsKKyAgICAgICAgdGhpcy5wcm94eSA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGNvbm5lY3Rpb24gZGVzdGluYXRpb24gc2F0aXNmaWVzIHRoZSBzZWN1cml0eSBwb2xpY3kKKyAgICAgKiBhbmQgdGhlIHZhbGlkaXR5IG9mIHRoZSBwb3J0IHJhbmdlLgorICAgICAqCisgICAgICogQHBhcmFtIGRlc3RBZGRyCisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gaG9zdCBhZGRyZXNzLgorICAgICAqIEBwYXJhbSBkc3RQb3J0CisgICAgICogICAgICAgICAgICB0aGUgcG9ydCBvbiB0aGUgZGVzdGluYXRpb24gaG9zdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY2hlY2tEZXN0aW5hdGlvbihJbmV0QWRkcmVzcyBkZXN0QWRkciwgaW50IGRzdFBvcnQpIHsKKyAgICAgICAgaWYgKGRzdFBvcnQgPCAwIHx8IGRzdFBvcnQgPiA2NTUzNSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiUG9ydCBvdXQgb2YgcmFuZ2U6ICIgKyBkc3RQb3J0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGUgc29ja2V0LiBJdCBpcyBub3QgcG9zc2libGUgdG8gcmVjb25uZWN0IG9yIHJlYmluZCB0byB0aGlzCisgICAgICogc29ja2V0IHRoZXJlYWZ0ZXIgd2hpY2ggbWVhbnMgYSBuZXcgc29ja2V0IGluc3RhbmNlIGhhcyB0byBiZSBjcmVhdGVkLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjbG9zaW5nIHRoZSBzb2NrZXQuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaXNDbG9zZWQgPSB0cnVlOworICAgICAgICAvLyBSSSBjb21wYXRpYmlsaXR5OiB0aGUgUkkgcmV0dXJucyB0aGUgYW55IGFkZHJlc3MgKGJ1dCB0aGUgb3JpZ2luYWwgbG9jYWwgcG9ydCkgYWZ0ZXIgY2xvc2UuCisgICAgICAgIGxvY2FsQWRkcmVzcyA9IEluZXQ0QWRkcmVzcy5BTlk7CisgICAgICAgIGltcGwuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBJUCBhZGRyZXNzIG9mIHRoZSB0YXJnZXQgaG9zdCB0aGlzIHNvY2tldCBpcyBjb25uZWN0ZWQgdG8sIG9yIG51bGwgaWYgdGhpcworICAgICAqIHNvY2tldCBpcyBub3QgeWV0IGNvbm5lY3RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5ldEFkZHJlc3MgZ2V0SW5ldEFkZHJlc3MoKSB7CisgICAgICAgIGlmICghaXNDb25uZWN0ZWQoKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGltcGwuZ2V0SW5ldEFkZHJlc3MoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGlucHV0IHN0cmVhbSB0byByZWFkIGRhdGEgZnJvbSB0aGlzIHNvY2tldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUtb3JpZW50ZWQgaW5wdXQgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY3JlYXRpbmcgdGhlIGlucHV0IHN0cmVhbSBvciB0aGUKKyAgICAgKiAgICAgICAgICAgICBzb2NrZXQgaXMgaW4gYW4gaW52YWxpZCBzdGF0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja09wZW5BbmRDcmVhdGUoZmFsc2UpOworICAgICAgICBpZiAoaXNJbnB1dFNodXRkb3duKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oIlNvY2tldCBpbnB1dCBpcyBzaHV0ZG93biIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpbXBsLmdldElucHV0U3RyZWFtKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHNvY2tldCdzIHtAbGluayBTb2NrZXRPcHRpb25zI1NPX0tFRVBBTElWRX0gc2V0dGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRLZWVwQWxpdmUoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuQW5kQ3JlYXRlKHRydWUpOworICAgICAgICByZXR1cm4gKEJvb2xlYW4pIGltcGwuZ2V0T3B0aW9uKFNvY2tldE9wdGlvbnMuU09fS0VFUEFMSVZFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBJUCBhZGRyZXNzIHRoaXMgc29ja2V0IGlzIGJvdW5kIHRvLCBvciB7QGNvZGUgSW5ldEFkZHJlc3MuQU5ZfSBpZgorICAgICAqIHRoZSBzb2NrZXQgaXMgdW5ib3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5ldEFkZHJlc3MgZ2V0TG9jYWxBZGRyZXNzKCkgeworICAgICAgICByZXR1cm4gbG9jYWxBZGRyZXNzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxvY2FsIHBvcnQgdGhpcyBzb2NrZXQgaXMgYm91bmQgdG8sIG9yIC0xIGlmIHRoZSBzb2NrZXQgaXMgdW5ib3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExvY2FsUG9ydCgpIHsKKyAgICAgICAgaWYgKCFpc0JvdW5kKCkpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW1wbC5nZXRMb2NhbFBvcnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIG91dHB1dCBzdHJlYW0gdG8gd3JpdGUgZGF0YSBpbnRvIHRoaXMgc29ja2V0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYnl0ZS1vcmllbnRlZCBvdXRwdXQgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY3JlYXRpbmcgdGhlIG91dHB1dCBzdHJlYW0gb3IgdGhlCisgICAgICogICAgICAgICAgICAgc29ja2V0IGlzIGluIGFuIGludmFsaWQgc3RhdGUuCisgICAgICovCisgICAgcHVibGljIE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja09wZW5BbmRDcmVhdGUoZmFsc2UpOworICAgICAgICBpZiAoaXNPdXRwdXRTaHV0ZG93bigpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKCJTb2NrZXQgb3V0cHV0IGlzIHNodXRkb3duIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGltcGwuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcG9ydCBudW1iZXIgb2YgdGhlIHRhcmdldCBob3N0IHRoaXMgc29ja2V0IGlzIGNvbm5lY3RlZCB0bywgb3IgMCBpZiB0aGlzIHNvY2tldAorICAgICAqIGlzIG5vdCB5ZXQgY29ubmVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UG9ydCgpIHsKKyAgICAgICAgaWYgKCFpc0Nvbm5lY3RlZCgpKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW1wbC5nZXRQb3J0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHNvY2tldCdzIHtAbGluayBTb2NrZXRPcHRpb25zI1NPX0xJTkdFUiBsaW5nZXJ9IHRpbWVvdXQgaW4gc2Vjb25kcywgb3IgLTEKKyAgICAgKiBmb3Igbm8gbGluZ2VyIChpLmUuIHtAY29kZSBjbG9zZX0gd2lsbCByZXR1cm4gaW1tZWRpYXRlbHkpLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U29MaW5nZXIoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuQW5kQ3JlYXRlKHRydWUpOworICAgICAgICAvLyBUaGUgUkkgZXhwbGljaXRseSBndWFyYW50ZWVzIHRoaXMgaWRpb2N5IGluIHRoZSBTb2NrZXRPcHRpb25zLnNldE9wdGlvbiBkb2N1bWVudGF0aW9uLgorICAgICAgICBPYmplY3QgdmFsdWUgPSBpbXBsLmdldE9wdGlvbihTb2NrZXRPcHRpb25zLlNPX0xJTkdFUik7CisgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEludGVnZXIpIHsKKyAgICAgICAgICAgIHJldHVybiAoSW50ZWdlcikgdmFsdWU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgc29ja2V0J3Mge0BsaW5rIFNvY2tldE9wdGlvbnMjU09fUkNWQlVGIHJlY2VpdmUgYnVmZmVyIHNpemV9LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldFJlY2VpdmVCdWZmZXJTaXplKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbkFuZENyZWF0ZSh0cnVlKTsKKyAgICAgICAgcmV0dXJuIChJbnRlZ2VyKSBpbXBsLmdldE9wdGlvbihTb2NrZXRPcHRpb25zLlNPX1JDVkJVRik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHNvY2tldCdzIHtAbGluayBTb2NrZXRPcHRpb25zI1NPX1NOREJVRiBzZW5kIGJ1ZmZlciBzaXplfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRTZW5kQnVmZmVyU2l6ZSgpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBjaGVja09wZW5BbmRDcmVhdGUodHJ1ZSk7CisgICAgICAgIHJldHVybiAoSW50ZWdlcikgaW1wbC5nZXRPcHRpb24oU29ja2V0T3B0aW9ucy5TT19TTkRCVUYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBzb2NrZXQncyB7QGxpbmsgU29ja2V0T3B0aW9ucyNTT19USU1FT1VUIHJlY2VpdmUgdGltZW91dH0uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0U29UaW1lb3V0KCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbkFuZENyZWF0ZSh0cnVlKTsKKyAgICAgICAgcmV0dXJuIChJbnRlZ2VyKSBpbXBsLmdldE9wdGlvbihTb2NrZXRPcHRpb25zLlNPX1RJTUVPVVQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBzb2NrZXQncyB7QGNvZGUgU29ja2V0T3B0aW9ucyNUQ1BfTk9ERUxBWX0gc2V0dGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRUY3BOb0RlbGF5KCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbkFuZENyZWF0ZSh0cnVlKTsKKyAgICAgICAgcmV0dXJuIChCb29sZWFuKSBpbXBsLmdldE9wdGlvbihTb2NrZXRPcHRpb25zLlRDUF9OT0RFTEFZKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoaXMgc29ja2V0J3Mge0BsaW5rIFNvY2tldE9wdGlvbnMjU09fS0VFUEFMSVZFfSBvcHRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0S2VlcEFsaXZlKGJvb2xlYW4ga2VlcEFsaXZlKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGltcGwgIT0gbnVsbCkgeworICAgICAgICAgICAgY2hlY2tPcGVuQW5kQ3JlYXRlKHRydWUpOworICAgICAgICAgICAgaW1wbC5zZXRPcHRpb24oU29ja2V0T3B0aW9ucy5TT19LRUVQQUxJVkUsIEJvb2xlYW4udmFsdWVPZihrZWVwQWxpdmUpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGludGVybmFsIGZhY3RvcnkgZm9yIGNyZWF0aW5nIHNvY2tldCBpbXBsZW1lbnRhdGlvbnMuIFRoaXMgbWF5CisgICAgICogb25seSBiZSBleGVjdXRlZCBvbmNlIGR1cmluZyB0aGUgbGlmZXRpbWUgb2YgdGhlIGFwcGxpY2F0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGZhYworICAgICAqICAgICAgICAgICAgdGhlIHNvY2tldCBpbXBsZW1lbnRhdGlvbiBmYWN0b3J5IHRvIGJlIHNldC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGZhY3RvcnkgaGFzIGJlZW4gYWxyZWFkeSBzZXQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRTb2NrZXRJbXBsRmFjdG9yeShTb2NrZXRJbXBsRmFjdG9yeSBmYWMpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoZmFjdG9yeSAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKCJGYWN0b3J5IGFscmVhZHkgc2V0Iik7CisgICAgICAgIH0KKyAgICAgICAgZmFjdG9yeSA9IGZhYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoaXMgc29ja2V0J3Mge0BsaW5rIFNvY2tldE9wdGlvbnMjU09fU05EQlVGIHNlbmQgYnVmZmVyIHNpemV9LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRTZW5kQnVmZmVyU2l6ZShpbnQgc2l6ZSkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbkFuZENyZWF0ZSh0cnVlKTsKKyAgICAgICAgaWYgKHNpemUgPCAxKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzaXplIDwgMSIpOworICAgICAgICB9CisgICAgICAgIGltcGwuc2V0T3B0aW9uKFNvY2tldE9wdGlvbnMuU09fU05EQlVGLCBJbnRlZ2VyLnZhbHVlT2Yoc2l6ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhpcyBzb2NrZXQncyB7QGxpbmsgU29ja2V0T3B0aW9ucyNTT19TTkRCVUYgcmVjZWl2ZSBidWZmZXIgc2l6ZX0uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFJlY2VpdmVCdWZmZXJTaXplKGludCBzaXplKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuQW5kQ3JlYXRlKHRydWUpOworICAgICAgICBpZiAoc2l6ZSA8IDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInNpemUgPCAxIik7CisgICAgICAgIH0KKyAgICAgICAgaW1wbC5zZXRPcHRpb24oU29ja2V0T3B0aW9ucy5TT19SQ1ZCVUYsIEludGVnZXIudmFsdWVPZihzaXplKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGlzIHNvY2tldCdzIHtAbGluayBTb2NrZXRPcHRpb25zI1NPX0xJTkdFUiBsaW5nZXJ9IHRpbWVvdXQgaW4gc2Vjb25kcy4KKyAgICAgKiBJZiB7QGNvZGUgb259IGlzIGZhbHNlLCB7QGNvZGUgdGltZW91dH0gaXMgaXJyZWxldmFudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTb0xpbmdlcihib29sZWFuIG9uLCBpbnQgdGltZW91dCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbkFuZENyZWF0ZSh0cnVlKTsKKyAgICAgICAgLy8gVGhlIFJJIGV4cGxpY2l0bHkgZ3VhcmFudGVlcyB0aGlzIGlkaW9jeSBpbiB0aGUgU29ja2V0T3B0aW9ucy5zZXRPcHRpb24gZG9jdW1lbnRhdGlvbi4KKyAgICAgICAgaWYgKG9uICYmIHRpbWVvdXQgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ0aW1lb3V0IDwgMCIpOworICAgICAgICB9CisgICAgICAgIGlmIChvbikgeworICAgICAgICAgICAgaW1wbC5zZXRPcHRpb24oU29ja2V0T3B0aW9ucy5TT19MSU5HRVIsIEludGVnZXIudmFsdWVPZih0aW1lb3V0KSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpbXBsLnNldE9wdGlvbihTb2NrZXRPcHRpb25zLlNPX0xJTkdFUiwgQm9vbGVhbi5GQUxTRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoaXMgc29ja2V0J3Mge0BsaW5rIFNvY2tldE9wdGlvbnMjU09fVElNRU9VVCByZWFkIHRpbWVvdXR9IGluIG1pbGxpc2Vjb25kcy4KKyAgICAgKiBVc2UgMCBmb3Igbm8gdGltZW91dC4KKyAgICAgKiBUbyB0YWtlIGVmZmVjdCwgdGhpcyBvcHRpb24gbXVzdCBiZSBzZXQgYmVmb3JlIHRoZSBibG9ja2luZyBtZXRob2Qgd2FzIGNhbGxlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0U29UaW1lb3V0KGludCB0aW1lb3V0KSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuQW5kQ3JlYXRlKHRydWUpOworICAgICAgICBpZiAodGltZW91dCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInRpbWVvdXQgPCAwIik7CisgICAgICAgIH0KKyAgICAgICAgaW1wbC5zZXRPcHRpb24oU29ja2V0T3B0aW9ucy5TT19USU1FT1VULCBJbnRlZ2VyLnZhbHVlT2YodGltZW91dCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhpcyBzb2NrZXQncyB7QGxpbmsgU29ja2V0T3B0aW9ucyNUQ1BfTk9ERUxBWX0gb3B0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRjcE5vRGVsYXkoYm9vbGVhbiBvbikgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbkFuZENyZWF0ZSh0cnVlKTsKKyAgICAgICAgaW1wbC5zZXRPcHRpb24oU29ja2V0T3B0aW9ucy5UQ1BfTk9ERUxBWSwgQm9vbGVhbi52YWx1ZU9mKG9uKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHN0cmVhbSBzb2NrZXQsIGJpbmRzIGl0IHRvIHRoZSBub21pbmF0ZWQgbG9jYWwgYWRkcmVzcy9wb3J0LAorICAgICAqIHRoZW4gY29ubmVjdHMgaXQgdG8gdGhlIG5vbWluYXRlZCBkZXN0aW5hdGlvbiBhZGRyZXNzL3BvcnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZHN0QWRkcmVzcworICAgICAqICAgICAgICAgICAgdGhlIGRlc3RpbmF0aW9uIGhvc3QgYWRkcmVzcy4KKyAgICAgKiBAcGFyYW0gZHN0UG9ydAorICAgICAqICAgICAgICAgICAgdGhlIHBvcnQgb24gdGhlIGRlc3RpbmF0aW9uIGhvc3QuCisgICAgICogQHBhcmFtIGxvY2FsQWRkcmVzcworICAgICAqICAgICAgICAgICAgdGhlIGFkZHJlc3Mgb24gdGhlIGxvY2FsIG1hY2hpbmUgdG8gYmluZC4KKyAgICAgKiBAcGFyYW0gbG9jYWxQb3J0CisgICAgICogICAgICAgICAgICB0aGUgcG9ydCBvbiB0aGUgbG9jYWwgbWFjaGluZSB0byBiaW5kLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aHJvd24gaWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyB0aGUgYmluZCBvciBjb25uZWN0CisgICAgICogICAgICAgICAgICAgb3BlcmF0aW9ucy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc3RhcnR1cFNvY2tldChJbmV0QWRkcmVzcyBkc3RBZGRyZXNzLCBpbnQgZHN0UG9ydCwKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIGxvY2FsQWRkcmVzcywgaW50IGxvY2FsUG9ydCwgYm9vbGVhbiBzdHJlYW1pbmcpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIGlmIChsb2NhbFBvcnQgPCAwIHx8IGxvY2FsUG9ydCA+IDY1NTM1KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJMb2NhbCBwb3J0IG91dCBvZiByYW5nZTogIiArIGxvY2FsUG9ydCk7CisgICAgICAgIH0KKworICAgICAgICBJbmV0QWRkcmVzcyBhZGRyID0gbG9jYWxBZGRyZXNzID09IG51bGwgPyBJbmV0NEFkZHJlc3MuQU5ZIDogbG9jYWxBZGRyZXNzOworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGltcGwuY3JlYXRlKHN0cmVhbWluZyk7CisgICAgICAgICAgICBpc0NyZWF0ZWQgPSB0cnVlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAoIXN0cmVhbWluZyB8fCAhdXNpbmdTb2NrcygpKSB7CisgICAgICAgICAgICAgICAgICAgIGltcGwuYmluZChhZGRyLCBsb2NhbFBvcnQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpc0JvdW5kID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBpbXBsLmNvbm5lY3QoZHN0QWRkcmVzcywgZHN0UG9ydCk7CisgICAgICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIGNhY2hlTG9jYWxBZGRyZXNzKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgaW1wbC5jbG9zZSgpOworICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gdXNpbmdTb2NrcygpIHsKKyAgICAgICAgcmV0dXJuIHByb3h5ICE9IG51bGwgJiYgcHJveHkudHlwZSgpID09IFByb3h5LlR5cGUuU09DS1M7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBTdHJpbmd9IGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUKKyAgICAgKiBzb2NrZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgc29ja2V0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIGlmICghaXNDb25uZWN0ZWQoKSkgeworICAgICAgICAgICAgcmV0dXJuICJTb2NrZXRbdW5jb25uZWN0ZWRdIjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW1wbC50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGUgaW5wdXQgc3RyZWFtIG9mIHRoaXMgc29ja2V0LiBBbnkgZnVydGhlciBkYXRhIHNlbnQgdG8gdGhpcworICAgICAqIHNvY2tldCB3aWxsIGJlIGRpc2NhcmRlZC4gUmVhZGluZyBmcm9tIHRoaXMgc29ja2V0IGFmdGVyIHRoaXMgbWV0aG9kIGhhcworICAgICAqIGJlZW4gY2FsbGVkIHdpbGwgcmV0dXJuIHRoZSB2YWx1ZSB7QGNvZGUgRU9GfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY2xvc2luZyB0aGUgc29ja2V0IGlucHV0IHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBpbnB1dCBzdHJlYW0gaXMgYWxyZWFkeSBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2h1dGRvd25JbnB1dCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpc0lucHV0U2h1dGRvd24oKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbigiU29ja2V0IGlucHV0IGlzIHNodXRkb3duIik7CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tPcGVuQW5kQ3JlYXRlKGZhbHNlKTsKKyAgICAgICAgaW1wbC5zaHV0ZG93bklucHV0KCk7CisgICAgICAgIGlzSW5wdXRTaHV0ZG93biA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoZSBvdXRwdXQgc3RyZWFtIG9mIHRoaXMgc29ja2V0LiBBbGwgYnVmZmVyZWQgZGF0YSB3aWxsIGJlIHNlbnQKKyAgICAgKiBmb2xsb3dlZCBieSB0aGUgdGVybWluYXRpb24gc2VxdWVuY2UuIFdyaXRpbmcgdG8gdGhlIGNsb3NlZCBvdXRwdXQgc3RyZWFtCisgICAgICogd2lsbCBjYXVzZSBhbiB7QGNvZGUgSU9FeGNlcHRpb259LgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjbG9zaW5nIHRoZSBzb2NrZXQgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvdXRwdXQgc3RyZWFtIGlzIGFscmVhZHkgY2xvc2VkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNodXRkb3duT3V0cHV0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzT3V0cHV0U2h1dGRvd24oKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbigiU29ja2V0IG91dHB1dCBpcyBzaHV0ZG93biIpOworICAgICAgICB9CisgICAgICAgIGNoZWNrT3BlbkFuZENyZWF0ZShmYWxzZSk7CisgICAgICAgIGltcGwuc2h1dGRvd25PdXRwdXQoKTsKKyAgICAgICAgaXNPdXRwdXRTaHV0ZG93biA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIHNvY2tldCBpcyBjbG9zZWQsIGFuZCB0aHJvd3MgYW4gZXhjZXB0aW9uLiBPdGhlcndpc2UKKyAgICAgKiBjcmVhdGVzIHRoZSB1bmRlcmx5aW5nIFNvY2tldEltcGwuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzb2NrZXQgaXMgY2xvc2VkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjaGVja09wZW5BbmRDcmVhdGUoYm9vbGVhbiBjcmVhdGUpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBpZiAoaXNDbG9zZWQoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbigiU29ja2V0IGlzIGNsb3NlZCIpOworICAgICAgICB9CisgICAgICAgIGlmICghY3JlYXRlKSB7CisgICAgICAgICAgICBpZiAoIWlzQ29ubmVjdGVkKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKCJTb2NrZXQgaXMgbm90IGNvbm5lY3RlZCIpOworICAgICAgICAgICAgICAgIC8vIGEgY29ubmVjdGVkIHNvY2tldCBtdXN0IGJlIGNyZWF0ZWQKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIHJldHVybiBkaXJlY3RseSB0byBmaXggYSBwb3NzaWJsZSBidWcsIGlmICFjcmVhdGUsIHNob3VsZCByZXR1cm4KKyAgICAgICAgICAgICAqIGhlcmUKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGlmIChpc0NyZWF0ZWQpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGlmIChpc0NyZWF0ZWQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGltcGwuY3JlYXRlKHRydWUpOworICAgICAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlzQ3JlYXRlZCA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBhZGRyZXNzIGFuZCBwb3J0IG9mIHRoaXMgc29ja2V0IGFzIGEgU29ja2V0QWRkcmVzcyBvcgorICAgICAqIG51bGwgaWYgdGhlIHNvY2tldCBpcyB1bmJvdW5kLiBUaGlzIGlzIHVzZWZ1bCBvbiBtdWx0aWhvbWVkCisgICAgICogaG9zdHMuCisgICAgICovCisgICAgcHVibGljIFNvY2tldEFkZHJlc3MgZ2V0TG9jYWxTb2NrZXRBZGRyZXNzKCkgeworICAgICAgICBpZiAoIWlzQm91bmQoKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBJbmV0U29ja2V0QWRkcmVzcyhnZXRMb2NhbEFkZHJlc3MoKSwgZ2V0TG9jYWxQb3J0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHJlbW90ZSBhZGRyZXNzIGFuZCBwb3J0IG9mIHRoaXMgc29ja2V0IGFzIGEge0Bjb2RlCisgICAgICogU29ja2V0QWRkcmVzc30gb3IgbnVsbCBpZiB0aGUgc29ja2V0IGlzIG5vdCBjb25uZWN0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZW1vdGUgc29ja2V0IGFkZHJlc3MgYW5kIHBvcnQuCisgICAgICovCisgICAgcHVibGljIFNvY2tldEFkZHJlc3MgZ2V0UmVtb3RlU29ja2V0QWRkcmVzcygpIHsKKyAgICAgICAgaWYgKCFpc0Nvbm5lY3RlZCgpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEluZXRTb2NrZXRBZGRyZXNzKGdldEluZXRBZGRyZXNzKCksIGdldFBvcnQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgc29ja2V0IGlzIGJvdW5kIHRvIGEgbG9jYWwgYWRkcmVzcyBhbmQgcG9ydC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzb2NrZXQgaXMgYm91bmQgdG8gYSBsb2NhbCBhZGRyZXNzLCB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNCb3VuZCgpIHsKKyAgICAgICAgcmV0dXJuIGlzQm91bmQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgc29ja2V0IGlzIGNvbm5lY3RlZCB0byBhIHJlbW90ZSBob3N0LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNvY2tldCBpcyBjb25uZWN0ZWQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQ29ubmVjdGVkKCkgeworICAgICAgICByZXR1cm4gaXNDb25uZWN0ZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgc29ja2V0IGlzIGNsb3NlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzb2NrZXQgaXMgY2xvc2VkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0Nsb3NlZCgpIHsKKyAgICAgICAgcmV0dXJuIGlzQ2xvc2VkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEJpbmRzIHRoaXMgc29ja2V0IHRvIHRoZSBnaXZlbiBsb2NhbCBob3N0IGFkZHJlc3MgYW5kIHBvcnQgc3BlY2lmaWVkIGJ5CisgICAgICogdGhlIFNvY2tldEFkZHJlc3Mge0Bjb2RlIGxvY2FsQWRkcn0uIElmIHtAY29kZSBsb2NhbEFkZHJ9IGlzIHNldCB0bworICAgICAqIHtAY29kZSBudWxsfSwgdGhpcyBzb2NrZXQgd2lsbCBiZSBib3VuZCB0byBhbiBhdmFpbGFibGUgbG9jYWwgYWRkcmVzcyBvbgorICAgICAqIGFueSBmcmVlIHBvcnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYWxBZGRyCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWMgYWRkcmVzcyBhbmQgcG9ydCBvbiB0aGUgbG9jYWwgbWFjaGluZSB0byBiaW5kIHRvLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIFNvY2tldEFkZHJlc3MgaXMgaW52YWxpZCBvciBub3Qgc3VwcG9ydGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc29ja2V0IGlzIGFscmVhZHkgYm91bmQgb3IgYW4gZXJyb3Igb2NjdXJzIHdoaWxlCisgICAgICogICAgICAgICAgICAgYmluZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBiaW5kKFNvY2tldEFkZHJlc3MgbG9jYWxBZGRyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja09wZW5BbmRDcmVhdGUodHJ1ZSk7CisgICAgICAgIGlmIChpc0JvdW5kKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCaW5kRXhjZXB0aW9uKCJTb2NrZXQgaXMgYWxyZWFkeSBib3VuZCIpOworICAgICAgICB9CisKKyAgICAgICAgaW50IHBvcnQgPSAwOworICAgICAgICBJbmV0QWRkcmVzcyBhZGRyID0gSW5ldDRBZGRyZXNzLkFOWTsKKyAgICAgICAgaWYgKGxvY2FsQWRkciAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoIShsb2NhbEFkZHIgaW5zdGFuY2VvZiBJbmV0U29ja2V0QWRkcmVzcykpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJMb2NhbCBhZGRyZXNzIG5vdCBhbiBJbmV0U29ja2V0QWRkcmVzczogIiArCisgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbEFkZHIuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBpbmV0QWRkciA9IChJbmV0U29ja2V0QWRkcmVzcykgbG9jYWxBZGRyOworICAgICAgICAgICAgaWYgKChhZGRyID0gaW5ldEFkZHIuZ2V0QWRkcmVzcygpKSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVua25vd25Ib3N0RXhjZXB0aW9uKCJIb3N0IGlzIHVucmVzb2x2ZWQ6ICIgKyBpbmV0QWRkci5nZXRIb3N0TmFtZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBvcnQgPSBpbmV0QWRkci5nZXRQb3J0KCk7CisgICAgICAgIH0KKworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaW1wbC5iaW5kKGFkZHIsIHBvcnQpOworICAgICAgICAgICAgICAgIGlzQm91bmQgPSB0cnVlOworICAgICAgICAgICAgICAgIGNhY2hlTG9jYWxBZGRyZXNzKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgaW1wbC5jbG9zZSgpOworICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25uZWN0cyB0aGlzIHNvY2tldCB0byB0aGUgZ2l2ZW4gcmVtb3RlIGhvc3QgYWRkcmVzcyBhbmQgcG9ydCBzcGVjaWZpZWQKKyAgICAgKiBieSB0aGUgU29ja2V0QWRkcmVzcyB7QGNvZGUgcmVtb3RlQWRkcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVtb3RlQWRkcgorICAgICAqICAgICAgICAgICAgdGhlIGFkZHJlc3MgYW5kIHBvcnQgb2YgdGhlIHJlbW90ZSBob3N0IHRvIGNvbm5lY3QgdG8uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2l2ZW4gU29ja2V0QWRkcmVzcyBpcyBpbnZhbGlkIG9yIG5vdCBzdXBwb3J0ZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzb2NrZXQgaXMgYWxyZWFkeSBjb25uZWN0ZWQgb3IgYW4gZXJyb3Igb2NjdXJzIHdoaWxlCisgICAgICogICAgICAgICAgICAgY29ubmVjdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjb25uZWN0KFNvY2tldEFkZHJlc3MgcmVtb3RlQWRkcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY29ubmVjdChyZW1vdGVBZGRyLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25uZWN0cyB0aGlzIHNvY2tldCB0byB0aGUgZ2l2ZW4gcmVtb3RlIGhvc3QgYWRkcmVzcyBhbmQgcG9ydCBzcGVjaWZpZWQKKyAgICAgKiBieSB0aGUgU29ja2V0QWRkcmVzcyB7QGNvZGUgcmVtb3RlQWRkcn0gd2l0aCB0aGUgc3BlY2lmaWVkIHRpbWVvdXQuIFRoZQorICAgICAqIGNvbm5lY3RpbmcgbWV0aG9kIHdpbGwgYmxvY2sgdW50aWwgdGhlIGNvbm5lY3Rpb24gaXMgZXN0YWJsaXNoZWQgb3IgYW4KKyAgICAgKiBlcnJvciBvY2N1cnJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZW1vdGVBZGRyCisgICAgICogICAgICAgICAgICB0aGUgYWRkcmVzcyBhbmQgcG9ydCBvZiB0aGUgcmVtb3RlIGhvc3QgdG8gY29ubmVjdCB0by4KKyAgICAgKiBAcGFyYW0gdGltZW91dAorICAgICAqICAgICAgICAgICAgdGhlIHRpbWVvdXQgdmFsdWUgaW4gbWlsbGlzZWNvbmRzIG9yIHtAY29kZSAwfSBmb3IgYW4gaW5maW5pdGUKKyAgICAgKiAgICAgICAgICAgIHRpbWVvdXQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2l2ZW4gU29ja2V0QWRkcmVzcyBpcyBpbnZhbGlkIG9yIG5vdCBzdXBwb3J0ZWQgb3IgdGhlCisgICAgICogICAgICAgICAgICAgdGltZW91dCB2YWx1ZSBpcyBuZWdhdGl2ZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNvY2tldCBpcyBhbHJlYWR5IGNvbm5lY3RlZCBvciBhbiBlcnJvciBvY2N1cnMgd2hpbGUKKyAgICAgKiAgICAgICAgICAgICBjb25uZWN0aW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNvbm5lY3QoU29ja2V0QWRkcmVzcyByZW1vdGVBZGRyLCBpbnQgdGltZW91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuQW5kQ3JlYXRlKHRydWUpOworICAgICAgICBpZiAodGltZW91dCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInRpbWVvdXQgPCAwIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlzQ29ubmVjdGVkKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oIkFscmVhZHkgY29ubmVjdGVkIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJlbW90ZUFkZHIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicmVtb3RlQWRkciA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIShyZW1vdGVBZGRyIGluc3RhbmNlb2YgSW5ldFNvY2tldEFkZHJlc3MpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJSZW1vdGUgYWRkcmVzcyBub3QgYW4gSW5ldFNvY2tldEFkZHJlc3M6ICIgKworICAgICAgICAgICAgICAgICAgICByZW1vdGVBZGRyLmdldENsYXNzKCkpOworICAgICAgICB9CisgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIGluZXRBZGRyID0gKEluZXRTb2NrZXRBZGRyZXNzKSByZW1vdGVBZGRyOworICAgICAgICBJbmV0QWRkcmVzcyBhZGRyOworICAgICAgICBpZiAoKGFkZHIgPSBpbmV0QWRkci5nZXRBZGRyZXNzKCkpID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbmtub3duSG9zdEV4Y2VwdGlvbigiSG9zdCBpcyB1bnJlc29sdmVkOiAiICsgaW5ldEFkZHIuZ2V0SG9zdE5hbWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgaW50IHBvcnQgPSBpbmV0QWRkci5nZXRQb3J0KCk7CisKKyAgICAgICAgY2hlY2tEZXN0aW5hdGlvbihhZGRyLCBwb3J0KTsKKyAgICAgICAgc3luY2hyb25pemVkIChjb25uZWN0TG9jaykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAoIWlzQm91bmQoKSkgeworICAgICAgICAgICAgICAgICAgICAvLyBzb2NrZXQgYWxyZWFkeSBjcmVhdGVkIGF0IHRoaXMgcG9pbnQgYnkgZWFybGllciBjYWxsIG9yCisgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrT3BlbkFuZENyZWF0ZSB0aGlzIGNhdXNlZCB1cyB0byBsb3NlIHNvY2tldAorICAgICAgICAgICAgICAgICAgICAvLyBvcHRpb25zIG9uIGNyZWF0ZQorICAgICAgICAgICAgICAgICAgICAvLyBpbXBsLmNyZWF0ZSh0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCF1c2luZ1NvY2tzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGltcGwuYmluZChJbmV0NEFkZHJlc3MuQU5ZLCAwKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpc0JvdW5kID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaW1wbC5jb25uZWN0KHJlbW90ZUFkZHIsIHRpbWVvdXQpOworICAgICAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBjYWNoZUxvY2FsQWRkcmVzcygpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGltcGwuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBpbmNvbWluZyBjaGFubmVsIG9mIHRoZSBzb2NrZXQgaGFzIGFscmVhZHkgYmVlbgorICAgICAqIGNsb3NlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHJlYWRpbmcgZnJvbSB0aGlzIHNvY2tldCBpcyBub3QgcG9zc2libGUgYW55bW9yZSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzSW5wdXRTaHV0ZG93bigpIHsKKyAgICAgICAgcmV0dXJuIGlzSW5wdXRTaHV0ZG93bjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIG91dGdvaW5nIGNoYW5uZWwgb2YgdGhlIHNvY2tldCBoYXMgYWxyZWFkeSBiZWVuCisgICAgICogY2xvc2VkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgd3JpdGluZyB0byB0aGlzIHNvY2tldCBpcyBub3QgcG9zc2libGUgYW55bW9yZSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzT3V0cHV0U2h1dGRvd24oKSB7CisgICAgICAgIHJldHVybiBpc091dHB1dFNodXRkb3duOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhpcyBzb2NrZXQncyB7QGxpbmsgU29ja2V0T3B0aW9ucyNTT19SRVVTRUFERFJ9IG9wdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSZXVzZUFkZHJlc3MoYm9vbGVhbiByZXVzZSkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbkFuZENyZWF0ZSh0cnVlKTsKKyAgICAgICAgaW1wbC5zZXRPcHRpb24oU29ja2V0T3B0aW9ucy5TT19SRVVTRUFERFIsIEJvb2xlYW4udmFsdWVPZihyZXVzZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBzb2NrZXQncyB7QGxpbmsgU29ja2V0T3B0aW9ucyNTT19SRVVTRUFERFJ9IHNldHRpbmcuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0UmV1c2VBZGRyZXNzKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbkFuZENyZWF0ZSh0cnVlKTsKKyAgICAgICAgcmV0dXJuIChCb29sZWFuKSBpbXBsLmdldE9wdGlvbihTb2NrZXRPcHRpb25zLlNPX1JFVVNFQUREUik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGlzIHNvY2tldCdzIHtAbGluayBTb2NrZXRPcHRpb25zI1NPX09PQklOTElORX0gb3B0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE9PQklubGluZShib29sZWFuIG9vYmlubGluZSkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbkFuZENyZWF0ZSh0cnVlKTsKKyAgICAgICAgaW1wbC5zZXRPcHRpb24oU29ja2V0T3B0aW9ucy5TT19PT0JJTkxJTkUsIEJvb2xlYW4udmFsdWVPZihvb2JpbmxpbmUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgc29ja2V0J3Mge0BsaW5rIFNvY2tldE9wdGlvbnMjU09fT09CSU5MSU5FfSBzZXR0aW5nLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldE9PQklubGluZSgpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBjaGVja09wZW5BbmRDcmVhdGUodHJ1ZSk7CisgICAgICAgIHJldHVybiAoQm9vbGVhbikgaW1wbC5nZXRPcHRpb24oU29ja2V0T3B0aW9ucy5TT19PT0JJTkxJTkUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhpcyBzb2NrZXQncyB7QGxpbmsgU29ja2V0T3B0aW9ucyNJUF9UT1N9IHZhbHVlIGZvciBldmVyeSBwYWNrZXQgc2VudCBieSB0aGlzIHNvY2tldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUcmFmZmljQ2xhc3MoaW50IHZhbHVlKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuQW5kQ3JlYXRlKHRydWUpOworICAgICAgICBpZiAodmFsdWUgPCAwIHx8IHZhbHVlID4gMjU1KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW1wbC5zZXRPcHRpb24oU29ja2V0T3B0aW9ucy5JUF9UT1MsIEludGVnZXIudmFsdWVPZih2YWx1ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBzb2NrZXQncyB7QHNlZSBTb2NrZXRPcHRpb25zI0lQX1RPU30gc2V0dGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFRyYWZmaWNDbGFzcygpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBjaGVja09wZW5BbmRDcmVhdGUodHJ1ZSk7CisgICAgICAgIHJldHVybiAoSW50ZWdlcikgaW1wbC5nZXRPcHRpb24oU29ja2V0T3B0aW9ucy5JUF9UT1MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmRzIHRoZSBnaXZlbiBzaW5nbGUgYnl0ZSBkYXRhIHdoaWNoIGlzIHJlcHJlc2VudGVkIGJ5IHRoZSBsb3dlc3Qgb2N0ZXQKKyAgICAgKiBvZiB7QGNvZGUgdmFsdWV9IGFzICJUQ1AgdXJnZW50IGRhdGEiLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSBvZiB1cmdlbnQgZGF0YSB0byBiZSBzZW50LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgc2VuZGluZyB1cmdlbnQgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZW5kVXJnZW50RGF0YShpbnQgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGltcGwuc2VuZFVyZ2VudERhdGEodmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgYXBwcm9wcmlhdGUgZmxhZ3MgZm9yIGEgc29ja2V0IGNyZWF0ZWQgYnkge0Bjb2RlCisgICAgICogU2VydmVyU29ja2V0LmFjY2VwdCgpfS4KKyAgICAgKgorICAgICAqIEBzZWUgU2VydmVyU29ja2V0I2ltcGxBY2NlcHQKKyAgICAgKi8KKyAgICB2b2lkIGFjY2VwdGVkKCkgeworICAgICAgICBpc0NyZWF0ZWQgPSBpc0JvdW5kID0gaXNDb25uZWN0ZWQgPSB0cnVlOworICAgICAgICBjYWNoZUxvY2FsQWRkcmVzcygpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjYWNoZUxvY2FsQWRkcmVzcygpIHsKKyAgICAgICAgdGhpcy5sb2NhbEFkZHJlc3MgPSBJb0JyaWRnZS5nZXRTb2NrZXRMb2NhbEFkZHJlc3MoaW1wbC5mZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHNvY2tldCdzIHtAY29kZSBTb2NrZXRDaGFubmVsfSwgaWYgb25lIGV4aXN0cy4gQSBjaGFubmVsIGlzCisgICAgICogYXZhaWxhYmxlIG9ubHkgaWYgdGhpcyBzb2NrZXQgd3JhcHMgYSBjaGFubmVsLiAoVGhhdCBpcywgeW91IGNhbiBnbyBmcm9tIGEKKyAgICAgKiBjaGFubmVsIHRvIGEgc29ja2V0IGFuZCBiYWNrIGFnYWluLCBidXQgeW91IGNhbid0IGdvIGZyb20gYW4gYXJiaXRyYXJ5IHNvY2tldCB0byBhIGNoYW5uZWwuKQorICAgICAqIEluIHByYWN0aWNlLCB0aGlzIG1lYW5zIHRoYXQgdGhlIHNvY2tldCBtdXN0IGhhdmUgYmVlbiBjcmVhdGVkIGJ5CisgICAgICoge0BsaW5rIGphdmEubmlvLmNoYW5uZWxzLlNlcnZlclNvY2tldENoYW5uZWwjYWNjZXB0fSBvcgorICAgICAqIHtAbGluayBqYXZhLm5pby5jaGFubmVscy5Tb2NrZXRDaGFubmVsI29wZW59LgorICAgICAqLworICAgIHB1YmxpYyBTb2NrZXRDaGFubmVsIGdldENoYW5uZWwoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBoaWRlIGludGVybmFsIHVzZSBvbmx5CisgICAgICovCisgICAgcHVibGljIEZpbGVEZXNjcmlwdG9yIGdldEZpbGVEZXNjcmlwdG9yJCgpIHsKKyAgICAgICAgcmV0dXJuIGltcGwuZmQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBwZXJmb3JtYW5jZSBwcmVmZXJlbmNlcyBmb3IgY29ubmVjdGlvblRpbWUsIGxhdGVuY3kgYW5kIGJhbmR3aWR0aC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGRvZXMgY3VycmVudGx5IG5vdGhpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29ubmVjdGlvblRpbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIGltcG9ydGFuY2Ugb2YgYSBzaG9ydCBjb25uZWN0aW5nCisgICAgICogICAgICAgICAgICB0aW1lLgorICAgICAqIEBwYXJhbSBsYXRlbmN5CisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBpbXBvcnRhbmNlIG9mIGxvdyBsYXRlbmN5LgorICAgICAqIEBwYXJhbSBiYW5kd2lkdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIGltcG9ydGFuY2Ugb2YgaGlnaCBiYW5kd2lkdGguCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UGVyZm9ybWFuY2VQcmVmZXJlbmNlcyhpbnQgY29ubmVjdGlvblRpbWUsIGludCBsYXRlbmN5LCBpbnQgYmFuZHdpZHRoKSB7CisgICAgICAgIC8vIE91ciBzb2NrZXQgaW1wbGVtZW50YXRpb24gb25seSBwcm92aWRlIG9uZSBwcm90b2NvbDogVENQL0lQLCBzbworICAgICAgICAvLyB3ZSBkbyBub3RoaW5nIGZvciB0aGlzIG1ldGhvZAorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Tb2NrZXRBZGRyZXNzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvU29ja2V0QWRkcmVzcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcwZDI2ZGEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvU29ja2V0QWRkcmVzcy5qYXZhCkBAIC0wLDAgKzEsMzYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworLyoqCisgKiBUaGlzIGFic3RyYWN0IGNsYXNzIHJlcHJlc2VudHMgYSBwcm90b2NvbC1pbmRlcGVuZGVudCBiYXNlIGZvcgorICogc29ja2V0LWVuZHBvaW50IHJlcHJlc2VudGluZyBjbGFzc2VzLiBUaGUgY2xhc3MgaGFzIHRvIGJlIGltcGxlbWVudGVkCisgKiBhY2NvcmRpbmcgdG8gYSBzcGVjaWZpYyBwcm90b2NvbC4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFNvY2tldEFkZHJlc3MgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTIxNTcyMDc0ODM0MjU0OTg2Nkw7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBTb2NrZXRBZGRyZXNzfSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU29ja2V0QWRkcmVzcygpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvU29ja2V0RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvU29ja2V0RXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjNlNWMwMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Tb2NrZXRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDU3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBUaGlzIHtAY29kZSBTb2NrZXRFeGNlcHRpb259IG1heSBiZSB0aHJvd24gZHVyaW5nIHNvY2tldCBjcmVhdGlvbiBvciBzZXR0aW5nCisgKiBvcHRpb25zLCBhbmQgaXMgdGhlIHN1cGVyY2xhc3Mgb2YgYWxsIG90aGVyIHNvY2tldCByZWxhdGVkIGV4Y2VwdGlvbnMuCisgKi8KK3B1YmxpYyBjbGFzcyBTb2NrZXRFeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTkzNTg3NDMwMzU1Njg4NjkzNEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBTb2NrZXRFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSB3aXRoIHRoZSBnaXZlbiBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU29ja2V0RXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIHdpdGggdGhlIGdpdmVuIGNhdXNlLgorICAgICAqIEBoaWRlIGludGVybmFsIHVzZSBvbmx5CisgICAgICovCisgICAgcHVibGljIFNvY2tldEV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugd2l0aCBnaXZlbiBkZXRhaWwgbWVzc2FnZSBhbmQgY2F1c2UuCisgICAgICogQGhpZGUgaW50ZXJuYWwgdXNlIG9ubHkKKyAgICAgKi8KKyAgICBwdWJsaWMgU29ja2V0RXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSwgY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Tb2NrZXRJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvU29ja2V0SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkyZGU5Y2YKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvU29ja2V0SW1wbC5qYXZhCkBAIC0wLDAgKzEsMjk3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyB0aGUgYmFzZSBvZiBhbGwgc3RyZWFtaW5nIHNvY2tldCBpbXBsZW1lbnRhdGlvbiBjbGFzc2VzLgorICogU3RyZWFtaW5nIHNvY2tldHMgYXJlIHdyYXBwZWQgYnkgdHdvIGNsYXNzZXMsIHtAY29kZSBTZXJ2ZXJTb2NrZXR9IGFuZAorICoge0Bjb2RlIFNvY2tldH0gYXQgdGhlIHNlcnZlciBhbmQgY2xpZW50IGVuZCBvZiBhIGNvbm5lY3Rpb24uIEF0IHRoZSBzZXJ2ZXIsCisgKiB0aGVyZSBhcmUgdHdvIHR5cGVzIG9mIHNvY2tldHMgZW5nYWdlZCBpbiBjb21tdW5pY2F0aW9uLCB0aGUge0Bjb2RlCisgKiBTZXJ2ZXJTb2NrZXR9IG9uIGEgd2VsbCBrbm93biBwb3J0IChyZWZlcnJlZCB0byBhcyBsaXN0ZW5lcikgdXNlZCB0bworICogZXN0YWJsaXNoIGEgY29ubmVjdGlvbiBhbmQgdGhlIHJlc3VsdGluZyB7QGNvZGUgU29ja2V0fSAocmVmZXJyZWQgdG8gYXMKKyAqIGhvc3QpLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU29ja2V0SW1wbCBpbXBsZW1lbnRzIFNvY2tldE9wdGlvbnMgeworCisgICAgLyoqCisgICAgICogVGhlIHJlbW90ZSBhZGRyZXNzIHRoaXMgc29ja2V0IGlzIGNvbm5lY3RlZCB0by4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSW5ldEFkZHJlc3MgYWRkcmVzczsKKworICAgIC8qKgorICAgICAqIFRoZSByZW1vdGUgcG9ydCB0aGlzIHNvY2tldCBpcyBjb25uZWN0ZWQgdG8uCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBwb3J0OworCisgICAgLyoqCisgICAgICogVGhlIGZpbGUgZGVzY3JpcHRvciBvZiB0aGlzIHNvY2tldC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRmlsZURlc2NyaXB0b3IgZmQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbG9jYWwgcG9ydCB0aGlzIHNvY2tldCBpcyBjb25uZWN0ZWQgdG8uCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBsb2NhbHBvcnQ7CisKKyAgICAvKioKKyAgICAgKiBXYWl0cyBmb3IgYW4gaW5jb21pbmcgcmVxdWVzdCBhbmQgYmxvY2tzIHVudGlsIHRoZSBjb25uZWN0aW9uIGlzIG9wZW5lZAorICAgICAqIG9uIHRoZSBnaXZlbiBzb2NrZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3U29ja2V0CisgICAgICogICAgICAgICAgICB0aGUgc29ja2V0IHRvIGFjY2VwdCBjb25uZWN0aW9ucyBvbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGFjY2VwdGluZyBhIG5ldyBjb25uZWN0aW9uLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGFjY2VwdChTb2NrZXRJbXBsIG5ld1NvY2tldCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXZhaWxhYmxlIG51bWJlciBvZiBieXRlcyB3aGljaCBhcmUgcmVhZGFibGUgZnJvbSB0aGlzIHNvY2tldAorICAgICAqIHdpdGhvdXQgYmxvY2tpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBtYXkgYmUgcmVhZCB3aXRob3V0IGJsb2NraW5nLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcmVhZGluZyB0aGUgbnVtYmVyIG9mIGJ5dGVzLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQmluZHMgdGhpcyBzb2NrZXQgdG8gdGhlIHNwZWNpZmllZCBsb2NhbCBob3N0IGFkZHJlc3MgYW5kIHBvcnQgbnVtYmVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFkZHJlc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhbCBtYWNoaW5lIGFkZHJlc3MgdG8gYmluZCB0aGlzIHNvY2tldCB0by4KKyAgICAgKiBAcGFyYW0gcG9ydAorICAgICAqICAgICAgICAgICAgdGhlIHBvcnQgb24gdGhlIGxvY2FsIG1hY2hpbmUgdG8gYmluZCB0aGlzIHNvY2tldCB0by4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGJpbmRpbmcgdGhpcyBzb2NrZXQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgYmluZChJbmV0QWRkcmVzcyBhZGRyZXNzLCBpbnQgcG9ydCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgc29ja2V0LiBUaGlzIG1ha2VzIGxhdGVyIGFjY2VzcyBpbnZhbGlkLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjbG9zaW5nIHRoaXMgc29ja2V0LgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ29ubmVjdHMgdGhpcyBzb2NrZXQgdG8gdGhlIHNwZWNpZmllZCByZW1vdGUgaG9zdCBhbmQgcG9ydCBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaG9zdAorICAgICAqICAgICAgICAgICAgdGhlIHJlbW90ZSBob3N0IHRoaXMgc29ja2V0IGhhcyB0byBiZSBjb25uZWN0ZWQgdG8uCisgICAgICogQHBhcmFtIHBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSByZW1vdGUgcG9ydCBvbiB3aGljaCB0aGlzIHNvY2tldCBoYXMgdG8gYmUgY29ubmVjdGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY29ubmVjdGluZyB0byB0aGUgcmVtb3RlIGhvc3QuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgY29ubmVjdChTdHJpbmcgaG9zdCwgaW50IHBvcnQpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENvbm5lY3RzIHRoaXMgc29ja2V0IHRvIHRoZSBzcGVjaWZpZWQgcmVtb3RlIGhvc3QgYWRkcmVzcyBhbmQgcG9ydAorICAgICAqIG51bWJlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhZGRyZXNzCisgICAgICogICAgICAgICAgICB0aGUgcmVtb3RlIGhvc3QgYWRkcmVzcyB0aGlzIHNvY2tldCBoYXMgdG8gYmUgY29ubmVjdGVkIHRvLgorICAgICAqIEBwYXJhbSBwb3J0CisgICAgICogICAgICAgICAgICB0aGUgcmVtb3RlIHBvcnQgb24gd2hpY2ggdGhpcyBzb2NrZXQgaGFzIHRvIGJlIGNvbm5lY3RlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNvbm5lY3RpbmcgdG8gdGhlIHJlbW90ZSBob3N0LgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGNvbm5lY3QoSW5ldEFkZHJlc3MgYWRkcmVzcywgaW50IHBvcnQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHVuY29ubmVjdGVkIHNvY2tldC4gVGhlIGFyZ3VtZW50IHtAY29kZSBpc1N0cmVhbWluZ30KKyAgICAgKiBkZWZpbmVzIHdoZXRoZXIgdGhlIG5ldyBzb2NrZXQgaXMgYSBzdHJlYW1pbmcgb3IgYSBkYXRhZ3JhbSBzb2NrZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXNTdHJlYW1pbmcKKyAgICAgKiAgICAgICAgICAgIGRlZmluZXMgd2hldGhlciB0aGUgdHlwZSBvZiB0aGUgbmV3IHNvY2tldCBpcyBzdHJlYW1pbmcgb3IKKyAgICAgKiAgICAgICAgICAgIGRhdGFncmFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY3JlYXRpbmcgdGhlIHNvY2tldC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBjcmVhdGUoYm9vbGVhbiBpc1N0cmVhbWluZykgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZmlsZSBkZXNjcmlwdG9yIG9mIHRoaXMgc29ja2V0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZmlsZSBkZXNjcmlwdG9yIG9mIHRoaXMgc29ja2V0LgorICAgICAqLworICAgIHByb3RlY3RlZCBGaWxlRGVzY3JpcHRvciBnZXRGaWxlRGVzY3JpcHRvcigpIHsKKyAgICAgICAgcmV0dXJuIGZkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBoaWRlIHVzZWQgYnkgamF2YS5uaW8KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3IgZ2V0RkQkKCkgeworICAgICAgICByZXR1cm4gZmQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcmVtb3RlIGFkZHJlc3MgdGhpcyBzb2NrZXQgaXMgY29ubmVjdGVkIHRvLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVtb3RlIGFkZHJlc3Mgb2YgdGhpcyBzb2NrZXQuCisgICAgICovCisgICAgcHJvdGVjdGVkIEluZXRBZGRyZXNzIGdldEluZXRBZGRyZXNzKCkgeworICAgICAgICByZXR1cm4gYWRkcmVzczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBpbnB1dCBzdHJlYW0gb2YgdGhpcyBzb2NrZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbnB1dCBzdHJlYW0gb2YgdGhpcyBzb2NrZXQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBhY2Nlc3NpbmcgdGhlIGlucHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsb2NhbCBwb3J0IG51bWJlciBvZiB0aGlzIHNvY2tldC4gVGhlIGZpZWxkIGlzIGluaXRpYWxpemVkIHRvCisgICAgICoge0Bjb2RlIC0xfSBhbmQgdXBvbiBkZW1hbmQgd2lsbCBnbyB0byB0aGUgSVAgc3RhY2sgdG8gZ2V0IHRoZSBib3VuZAorICAgICAqIHZhbHVlLiBTZWUgdGhlIGNsYXNzIGNvbW1lbnQgZm9yIHRoZSBjb250ZXh0IG9mIHRoZSBsb2NhbCBwb3J0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbG9jYWwgcG9ydCBudW1iZXIgdGhpcyBzb2NrZXQgaXMgYm91bmQgdG8uCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBnZXRMb2NhbFBvcnQoKSB7CisgICAgICAgIHJldHVybiBsb2NhbHBvcnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgb3V0cHV0IHN0cmVhbSBvZiB0aGlzIHNvY2tldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG91dHB1dCBzdHJlYW0gb2YgdGhpcyBzb2NrZXQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBhY2Nlc3NpbmcgdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSByZW1vdGUgcG9ydCBudW1iZXIgb2YgdGhpcyBzb2NrZXQuIFRoaXMgdmFsdWUgaXMgbm90IG1lYW5pbmdmdWwKKyAgICAgKiB3aGVuIHRoaXMgaW5zdGFuY2UgaXMgd3JhcHBlZCBieSBhIHtAY29kZSBTZXJ2ZXJTb2NrZXR9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVtb3RlIHBvcnQgdGhpcyBzb2NrZXQgaXMgY29ubmVjdGVkIHRvLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgZ2V0UG9ydCgpIHsKKyAgICAgICAgcmV0dXJuIHBvcnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogTGlzdGVucyBmb3IgY29ubmVjdGlvbiByZXF1ZXN0cyBvbiB0aGlzIHN0cmVhbWluZyBzb2NrZXQuIEluY29taW5nCisgICAgICogY29ubmVjdGlvbiByZXF1ZXN0cyBhcmUgcXVldWVkIHVwIHRvIHRoZSBsaW1pdCBzcGVjaWZpZWQgYnkge0Bjb2RlCisgICAgICogYmFja2xvZ30uIEFkZGl0aW9uYWwgcmVxdWVzdHMgYXJlIHJlamVjdGVkLiBUaGlzIG1ldGhvZAorICAgICAqIG1heSBvbmx5IGJlIGludm9rZWQgb24gc3RyZWFtIHNvY2tldHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYmFja2xvZworICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gbnVtYmVyIG9mIG91dHN0YW5kaW5nIGNvbm5lY3Rpb24gcmVxdWVzdHMuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBsaXN0ZW5pbmcuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgbGlzdGVuKGludCBiYWNrbG9nKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUKKyAgICAgKiBzb2NrZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgc29ja2V0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiAiU29ja2V0W2FkZHJlc3M9IiArIGdldEluZXRBZGRyZXNzKCkgKworICAgICAgICAgICAgICAgICIscG9ydD0iICsgcG9ydCArICIsbG9jYWxQb3J0PSIgKyBnZXRMb2NhbFBvcnQoKSArICJdIjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhlIGlucHV0IGNoYW5uZWwgb2YgdGhpcyBzb2NrZXQuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gYWx3YXlzIHRocm93cyBhbiB7QGxpbmsgSU9FeGNlcHRpb259IHRvCisgICAgICogaW5kaWNhdGUgdGhhdCB0aGUgc3ViY2xhc3Mgc2hvdWxkIGhhdmUgb3ZlcnJpZGRlbiB0aGlzIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhbHdheXMgYmVjYXVzZSB0aGlzIG1ldGhvZCBzaG91bGQgYmUgb3ZlcnJpZGRlbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzaHV0ZG93bklucHV0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJNZXRob2QgaGFzIG5vdCBiZWVuIGltcGxlbWVudGVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoZSBvdXRwdXQgY2hhbm5lbCBvZiB0aGlzIHNvY2tldC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBhbHdheXMgdGhyb3dzIGFuIHtAbGluayBJT0V4Y2VwdGlvbn0gdG8KKyAgICAgKiBpbmRpY2F0ZSB0aGF0IHRoZSBzdWJjbGFzcyBzaG91bGQgaGF2ZSBvdmVycmlkZGVuIHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGFsd2F5cyBiZWNhdXNlIHRoaXMgbWV0aG9kIHNob3VsZCBiZSBvdmVycmlkZGVuLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNodXRkb3duT3V0cHV0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJNZXRob2QgaGFzIG5vdCBiZWVuIGltcGxlbWVudGVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29ubmVjdHMgdGhpcyBzb2NrZXQgdG8gdGhlIHJlbW90ZSBob3N0IGFkZHJlc3MgYW5kIHBvcnQgbnVtYmVyIHNwZWNpZmllZAorICAgICAqIGJ5IHRoZSB7QGNvZGUgU29ja2V0QWRkcmVzc30gb2JqZWN0IHdpdGggdGhlIGdpdmVuIHRpbWVvdXQuIFRoaXMgbWV0aG9kCisgICAgICogd2lsbCBibG9jayBpbmRlZmluaXRlbHkgaWYgdGhlIHRpbWVvdXQgaXMgc2V0IHRvIHplcm8uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVtb3RlQWRkcgorICAgICAqICAgICAgICAgICAgdGhlIHJlbW90ZSBob3N0IGFkZHJlc3MgYW5kIHBvcnQgbnVtYmVyIHRvIGNvbm5lY3QgdG8uCisgICAgICogQHBhcmFtIHRpbWVvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSB0aW1lb3V0IHZhbHVlIGluIG1pbGxpc2Vjb25kcy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNvbm5lY3RpbmcuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgY29ubmVjdChTb2NrZXRBZGRyZXNzIHJlbW90ZUFkZHIsIGludCB0aW1lb3V0KSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHNvY2tldCBzdXBwb3J0cyB1cmdlbnQgZGF0YSBvciBub3QuIFN1YmNsYXNzZXMgc2hvdWxkCisgICAgICogb3ZlcnJpZGUgdGhpcyBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSBmYWxzZX0gYmVjYXVzZSBzdWJjbGFzc2VzIG11c3Qgb3ZlcnJpZGUgdGhpcyBtZXRob2QuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gc3VwcG9ydHNVcmdlbnREYXRhKCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZHMgdGhlIHNpbmdsZSBieXRlIG9mIHVyZ2VudCBkYXRhIG9uIHRoZSBzb2NrZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIG9mIHVyZ2VudCBkYXRhLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgc2VuZGluZyB1cmdlbnQgZGF0YS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBzZW5kVXJnZW50RGF0YShpbnQgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgcGVyZm9ybWFuY2UgcHJlZmVyZW5jZSBmb3IgY29ubmVjdGlvbiB0aW1lLCBsYXRlbmN5IGFuZCBiYW5kd2lkdGguCisgICAgICogRG9lcyBub3RoaW5nIGJ5IGRlZmF1bHQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29ubmVjdGlvblRpbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbXBvcnRhbmNlIG9mIGNvbm5lY3QgdGltZS4KKyAgICAgKiBAcGFyYW0gbGF0ZW5jeQorICAgICAqICAgICAgICAgICAgdGhlIGltcG9ydGFuY2Ugb2YgbGF0ZW5jeS4KKyAgICAgKiBAcGFyYW0gYmFuZHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgaW1wb3J0YW5jZSBvZiBiYW5kd2lkdGguCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0UGVyZm9ybWFuY2VQcmVmZXJlbmNlcyhpbnQgY29ubmVjdGlvblRpbWUsIGludCBsYXRlbmN5LCBpbnQgYmFuZHdpZHRoKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1NvY2tldEltcGxGYWN0b3J5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvU29ja2V0SW1wbEZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YmQwYzI0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1NvY2tldEltcGxGYWN0b3J5LmphdmEKQEAgLTAsMCArMSwzMSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworLyoqCisgKiBUaGlzIGludGVyZmFjZSBkZWZpbmVzIGEgZmFjdG9yeSBmb3Igc29ja2V0IGltcGxlbWVudGF0aW9ucy4KKyAqLworcHVibGljIGludGVyZmFjZSBTb2NrZXRJbXBsRmFjdG9yeSB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBTb2NrZXRJbXBsfSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQge0Bjb2RlIFNvY2tldEltcGx9IGluc3RhbmNlLgorICAgICAqLworICAgIFNvY2tldEltcGwgY3JlYXRlU29ja2V0SW1wbCgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1NvY2tldE9wdGlvbnMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Tb2NrZXRPcHRpb25zLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTIzZmM5NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Tb2NrZXRPcHRpb25zLmphdmEKQEAgLTAsMCArMSwxNjMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKKworLyoqCisgKiBEZWZpbmVzIGFuIGludGVyZmFjZSBmb3Igc29ja2V0IGltcGxlbWVudGF0aW9ucyB0byBnZXQgYW5kIHNldCBzb2NrZXQKKyAqIG9wdGlvbnMuIEl0IGlzIGltcGxlbWVudGVkIGJ5IHRoZSBjbGFzc2VzIHtAY29kZSBTb2NrZXRJbXBsfSBhbmQge0Bjb2RlCisgKiBEYXRhZ3JhbVNvY2tldEltcGx9LgorICoKKyAqIEBzZWUgU29ja2V0SW1wbAorICogQHNlZSBEYXRhZ3JhbVNvY2tldEltcGwKKyAqLworcHVibGljIGludGVyZmFjZSBTb2NrZXRPcHRpb25zIHsKKyAgICAvKioKKyAgICAgKiBOdW1iZXIgb2Ygc2Vjb25kcyB0byB3YWl0IHdoZW4gY2xvc2luZyBhIHNvY2tldCBpZiB0aGVyZQorICAgICAqIGlzIHN0aWxsIHNvbWUgYnVmZmVyZWQgZGF0YSB0byBiZSBzZW50LgorICAgICAqCisgICAgICogPHA+SWYgdGhpcyBvcHRpb24gaXMgc2V0IHRvIDAsIHRoZSBUQ1Agc29ja2V0IGlzIGNsb3NlZCBmb3JjZWZ1bGx5IGFuZCB0aGUKKyAgICAgKiBjYWxsIHRvIHtAY29kZSBjbG9zZX0gcmV0dXJucyBpbW1lZGlhdGVseS4KKyAgICAgKgorICAgICAqIDxwPklmIHRoaXMgb3B0aW9uIGlzIHNldCB0byBhIHZhbHVlIGdyZWF0ZXIgdGhhbiAwLCB0aGUgdmFsdWUgaXMgaW50ZXJwcmV0ZWQKKyAgICAgKiBhcyB0aGUgbnVtYmVyIG9mIHNlY29uZHMgdG8gd2FpdC4gSWYgYWxsIGRhdGEgY291bGQgYmUgc2VudAorICAgICAqIGR1cmluZyB0aGlzIHRpbWUsIHRoZSBzb2NrZXQgaXMgY2xvc2VkIG5vcm1hbGx5LiBPdGhlcndpc2UgdGhlIGNvbm5lY3Rpb24gd2lsbCBiZQorICAgICAqIGNsb3NlZCBmb3JjZWZ1bGx5LgorICAgICAqCisgICAgICogPHA+VmFsaWQgdmFsdWVzIGZvciB0aGlzIG9wdGlvbiBhcmUgaW4gdGhlIHJhbmdlIDAgdG8gNjU1MzUgaW5jbHVzaXZlLiAoTGFyZ2VyCisgICAgICogdGltZW91dHMgd2lsbCBiZSB0cmVhdGVkIGFzIDY1NTM1cyB0aW1lb3V0czsgcm91Z2hseSAxOCBob3Vycy4pCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fTElOR0VSID0gMTI4OworCisgICAgLyoqCisgICAgICogSW50ZWdlciB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyBmb3IgYmxvY2tpbmcgYWNjZXB0IG9yIHJlYWQvcmVjZWl2ZSBvcGVyYXRpb25zIChidXQgbm90CisgICAgICogd3JpdGUvc2VuZCBvcGVyYXRpb25zKS4gQSB0aW1lb3V0IG9mIDAgbWVhbnMgbm8gdGltZW91dC4gTmVnYXRpdmUKKyAgICAgKiB0aW1lb3V0cyBhcmUgbm90IGFsbG93ZWQuCisgICAgICoKKyAgICAgKiA8cD5BbiB7QGNvZGUgSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbn0gaXMgdGhyb3duIGlmIHRoaXMgdGltZW91dCBleHBpcmVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNPX1RJTUVPVVQgPSA0MTAyOworCisgICAgLyoqCisgICAgICogVGhpcyBib29sZWFuIG9wdGlvbiBzcGVjaWZpZXMgd2hldGhlciBkYXRhIGlzIHNlbnQgaW1tZWRpYXRlbHkgb24gdGhpcyBzb2NrZXQuCisgICAgICogQXMgYSBzaWRlLWVmZmVjdCB0aGlzIGNvdWxkIGxlYWQgdG8gbG93IHBhY2tldCBlZmZpY2llbmN5LiBUaGUKKyAgICAgKiBzb2NrZXQgaW1wbGVtZW50YXRpb24gdXNlcyB0aGUgTmFnbGUncyBhbGdvcml0aG0gdG8gdHJ5IHRvIHJlYWNoIGEgaGlnaGVyCisgICAgICogcGFja2V0IGVmZmljaWVuY3kgaWYgdGhpcyBvcHRpb24gaXMgZGlzYWJsZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVENQX05PREVMQVkgPSAxOworCisgICAgLyoqCisgICAgICogVGhpcyBpcyBhbiBJUHY0LW9ubHkgc29ja2V0IG9wdGlvbiB3aG9zZSBmdW5jdGlvbmFsaXR5IGlzIHN1YnN1bWVkIGJ5CisgICAgICoge0BsaW5rICNJUF9NVUxUSUNBU1RfSUZ9IGFuZCBub3QgaW1wbGVtZW50ZWQgb24gQW5kcm9pZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJUF9NVUxUSUNBU1RfSUYgPSAxNjsKKworICAgIC8qKgorICAgICAqIFRoaXMgb3B0aW9uIGRvZXMgbm90IGNvcnJlc3BvbmQgdG8gYW55IFVuaXggc29ja2V0IG9wdGlvbiBhbmQgaXMgbm90IGltcGxlbWVudGVkIG9uIEFuZHJvaWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fQklOREFERFIgPSAxNTsKKworICAgIC8qKgorICAgICAqIFRoaXMgYm9vbGVhbiBvcHRpb24gc3BlY2lmaWVzIHdoZXRoZXIgYSByZXVzZSBvZiBhIGxvY2FsIGFkZHJlc3MgaXMgYWxsb3dlZCBldmVuCisgICAgICogaWYgYW5vdGhlciBzb2NrZXQgaXMgbm90IHlldCByZW1vdmVkIGJ5IHRoZSBvcGVyYXRpbmcgc3lzdGVtLiBJdCdzIG9ubHkKKyAgICAgKiBhdmFpbGFibGUgb24gYSB7QGNvZGUgTXVsdGljYXN0U29ja2V0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT19SRVVTRUFERFIgPSA0OworCisgICAgLyoqCisgICAgICogVGhlIHNpemUgaW4gYnl0ZXMgb2YgYSBzb2NrZXQncyBzZW5kIGJ1ZmZlci4gVGhpcyBtdXN0IGJlIGFuIGludGVnZXIgZ3JlYXRlciB0aGFuIDAuCisgICAgICogVGhpcyBpcyBhIGhpbnQgdG8gdGhlIGtlcm5lbDsgdGhlIGtlcm5lbCBtYXkgdXNlIGEgbGFyZ2VyIGJ1ZmZlci4KKyAgICAgKgorICAgICAqIDxwPkZvciBkYXRhZ3JhbSBzb2NrZXRzLCBpdCBpcyBpbXBsZW1lbnRhdGlvbi1kZWZpbmVkIHdoZXRoZXIgcGFja2V0cyBsYXJnZXIgdGhhbgorICAgICAqIHRoaXMgc2l6ZSBjYW4gYmUgc2VudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT19TTkRCVUYgPSA0MDk3OworCisgICAgLyoqCisgICAgICogVGhlIHNpemUgaW4gYnl0ZXMgb2YgYSBzb2NrZXQncyByZWNlaXZlIGJ1ZmZlci4gVGhpcyBtdXN0IGJlIGFuIGludGVnZXIgZ3JlYXRlciB0aGFuIDAuCisgICAgICogVGhpcyBpcyBhIGhpbnQgdG8gdGhlIGtlcm5lbDsgdGhlIGtlcm5lbCBtYXkgdXNlIGEgbGFyZ2VyIGJ1ZmZlci4KKyAgICAgKgorICAgICAqIDxwPkZvciBkYXRhZ3JhbSBzb2NrZXRzLCBwYWNrZXRzIGxhcmdlciB0aGFuIHRoaXMgdmFsdWUgd2lsbCBiZSBkaXNjYXJkZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fUkNWQlVGID0gNDA5ODsKKworICAgIC8qKgorICAgICAqIFRoaXMgYm9vbGVhbiBvcHRpb24gc3BlY2lmaWVzIHdoZXRoZXIgdGhlIGtlcm5lbCBzZW5kcyBrZWVwYWxpdmUgbWVzc2FnZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fS0VFUEFMSVZFID0gODsKKworICAgIC8qKgorICAgICAqIFRoaXMgaW50ZWdlciBvcHRpb24gc3BlY2lmaWVzIHRoZSB2YWx1ZSBmb3IgdGhlIHR5cGUtb2Ytc2VydmljZSBmaWVsZCBvZiB0aGUgSVB2NCBoZWFkZXIsCisgICAgICogb3IgdGhlIHRyYWZmaWMgY2xhc3MgZmllbGQgb2YgdGhlIElQdjYgaGVhZGVyLiBUaGVzZSBjb3JyZXNwb25kIHRvIHRoZSBJUF9UT1MgYW5kIElQVjZfVENMQVNTCisgICAgICogc29ja2V0IG9wdGlvbnMuIFRoZXNlIG1heSBiZSBpZ25vcmVkIGJ5IHRoZSB1bmRlcmx5aW5nIE9TLiBWYWx1ZXMgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDI1NQorICAgICAqIGluY2x1c2l2ZS4KKyAgICAgKgorICAgICAqIDxwPlNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMxMzQ5LnR4dCI+UkZDIDEzNDk8L2E+IGZvciBtb3JlIGFib3V0IElQdjQKKyAgICAgKiBhbmQgPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjQ2MC50eHQiPlJGQyAyNDYwPC9hPiBmb3IgbW9yZSBhYm91dCBJUHY2LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElQX1RPUyA9IDM7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGJvb2xlYW4gb3B0aW9uIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBsb2NhbCBsb29wYmFjayBvZiBtdWx0aWNhc3QgcGFja2V0cyBpcworICAgICAqIGVuYWJsZWQgb3IgZGlzYWJsZWQuIFRoaXMgb3B0aW9uIGlzIGVuYWJsZWQgYnkgZGVmYXVsdCBvbiBtdWx0aWNhc3QKKyAgICAgKiBzb2NrZXRzLiBOb3RlIHRoYXQgdGhlIHNlbnNlIG9mIHRoaXMgb3B0aW9uIGluIEphdmEgaXMgdGhlCisgICAgICogPGk+b3Bwb3NpdGU8L2k+IG9mIHRoZSB1bmRlcmx5aW5nIFVuaXgge0Bjb2RlIElQX01VTFRJQ0FTVF9MT09QfS4KKyAgICAgKiBTZWUge0BsaW5rIE11bHRpY2FzdFNvY2tldCNzZXRMb29wYmFja01vZGV9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElQX01VTFRJQ0FTVF9MT09QID0gMTg7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGJvb2xlYW4gb3B0aW9uIGNhbiBiZSB1c2VkIHRvIGVuYWJsZSBicm9hZGNhc3Rpbmcgb24gZGF0YWdyYW0gc29ja2V0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT19CUk9BRENBU1QgPSAzMjsKKworICAgIC8qKgorICAgICAqIFRoaXMgYm9vbGVhbiBvcHRpb24gc3BlY2lmaWVzIHdoZXRoZXIgc2VuZGluZyBUQ1AgdXJnZW50IGRhdGEgaXMgc3VwcG9ydGVkIG9uCisgICAgICogdGhpcyBzb2NrZXQgb3Igbm90LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNPX09PQklOTElORSA9IDQwOTk7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGludGVnZXIgb3B0aW9uIHNldHMgdGhlIG91dGdvaW5nIGludGVyZmFjZSBmb3IgbXVsdGljYXN0IHBhY2tldHMKKyAgICAgKiB1c2luZyBhbiBpbnRlcmZhY2UgaW5kZXguCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSVBfTVVMVElDQVNUX0lGMiA9IDMxOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgc29ja2V0IG9wdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG9wdGlvbiB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gb3B0SUQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvcHRpb24gaWRlbnRpZmllci4KKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyByZWFkaW5nIHRoZSBvcHRpb24gdmFsdWUuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRPcHRpb24oaW50IG9wdElEKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBzb2NrZXQgb3B0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIG9wdElECisgICAgICogICAgICAgICAgICB0aGUgb3B0aW9uIGlkZW50aWZpZXIuCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIGJlIHNldCBmb3IgdGhlIG9wdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNvY2tldEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBzZXR0aW5nIHRoZSBvcHRpb24gdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0T3B0aW9uKGludCBvcHRJRCwgT2JqZWN0IHZhbCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Tb2NrZXRQZXJtaXNzaW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvU29ja2V0UGVybWlzc2lvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZiYmZjNzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvU29ja2V0UGVybWlzc2lvbi5qYXZhCkBAIC0wLDAgKzEsMzIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTb2NrZXRQZXJtaXNzaW9uIGV4dGVuZHMgUGVybWlzc2lvbiBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisgICAgcHVibGljIFNvY2tldFBlcm1pc3Npb24oU3RyaW5nIGhvc3QsIFN0cmluZyBhY3Rpb24pIHsgc3VwZXIoIiIpOyB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyBnZXRBY3Rpb25zKCkgeyByZXR1cm4gbnVsbDsgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGltcGxpZXMoUGVybWlzc2lvbiBwZXJtaXNzaW9uKSB7IHJldHVybiB0cnVlOyB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvU29ja2V0VGltZW91dEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1NvY2tldFRpbWVvdXRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZjhlZjgyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1NvY2tldFRpbWVvdXRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDU4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JbnRlcnJ1cHRlZElPRXhjZXB0aW9uOworCisvKioKKyAqIFRoaXMgZXhjZXB0aW9uIGlzIHRocm93biB3aGVuIGEgdGltZW91dCBleHBpcmVkIG9uIGEgc29ja2V0IHtAY29kZSByZWFkfSBvcgorICoge0Bjb2RlIGFjY2VwdH0gb3BlcmF0aW9uLgorICovCitwdWJsaWMgY2xhc3MgU29ja2V0VGltZW91dEV4Y2VwdGlvbiBleHRlbmRzIEludGVycnVwdGVkSU9FeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTg4NDY2NTQ4NDE4MjYzNTIzMDBMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU29ja2V0VGltZW91dEV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIHdpdGggdGhlIGdpdmVuIGRldGFpbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBTb2NrZXRUaW1lb3V0RXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugd2l0aCBnaXZlbiBjYXVzZS4KKyAgICAgKiBAaGlkZSBpbnRlcm5hbCB1c2Ugb25seQorICAgICAqLworICAgIHB1YmxpYyBTb2NrZXRUaW1lb3V0RXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihudWxsLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSB3aXRoIGdpdmVuIGRldGFpbCBtZXNzYWdlIGFuZCBjYXVzZS4KKyAgICAgKiBAaGlkZSBpbnRlcm5hbCB1c2Ugb25seQorICAgICAqLworICAgIHB1YmxpYyBTb2NrZXRUaW1lb3V0RXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSwgY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Tb2NrZXRVdGlscy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1NvY2tldFV0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzY0ZWUxZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Tb2NrZXRVdGlscy5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCisvKioKKyAqIEBoaWRlIGludGVybmFsIHVzZSBvbmx5CisgKi8KK3B1YmxpYyBjbGFzcyBTb2NrZXRVdGlscyB7CisgICAgLyoqCisgICAgICogSGVscHMgdXMgcmV1c2UgbW9yZSBvZiBTb2NrZXQncyBpbXBsZW1lbnRhdGlvbiBpbiBTb2NrZXRDaGFubmVsSW1wbC5Tb2NrZXRBZGFwdGVyLgorICAgICAqIEl0J3Mgbm90IHRoZSBjYXNlIHRoYXQgd2Ugc2hvdWxkIHNldCBpc0NyZWF0ZWQgaW4gdGhlIFNvY2tldChTb2NrZXRJbXBsKSBjb25zdHJ1Y3RvcjsKKyAgICAgKiBTb2NrZXRJbXBsLmNyZWF0ZSBzaG91bGQgYmUgY2FsbGVkIGluIGdlbmVyYWwuIEJ1dCBmb3IgU29ja2V0Q2hhbm5lbEltcGwuU29ja2V0QWRhcHRlcidzCisgICAgICogU29ja2V0SW1wbCwgd2UgZG9uJ3Qgd2FudCB0aGF0IGJlaGF2aW9yLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRDcmVhdGVkKFNvY2tldCBzKSB7CisgICAgICAgIHMuaXNDcmVhdGVkID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwcml2YXRlIFNvY2tldFV0aWxzKCkgeyB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvU29ja3M0TWVzc2FnZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1NvY2tzNE1lc3NhZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMTkzNTIwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1NvY2tzNE1lc3NhZ2UuamF2YQpAQCAtMCwwICsxLDIxNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVPcmRlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRzOworaW1wb3J0IGxpYmNvcmUuaW8uTWVtb3J5OworCitjbGFzcyBTb2NrczRNZXNzYWdlIHsKKyAgICBzdGF0aWMgZmluYWwgaW50IENPTU1BTkRfQ09OTkVDVCA9IDE7CisKKyAgICBzdGF0aWMgZmluYWwgaW50IENPTU1BTkRfQklORCA9IDI7CisKKyAgICBzdGF0aWMgZmluYWwgaW50IFJFVFVSTl9TVUNDRVNTID0gOTA7CisKKyAgICBzdGF0aWMgZmluYWwgaW50IFJFVFVSTl9GQUlMVVJFID0gOTE7CisKKyAgICBzdGF0aWMgZmluYWwgaW50IFJFVFVSTl9DQU5OT1RfQ09OTkVDVF9UT19JREVOVEQgPSA5MjsKKworICAgIHN0YXRpYyBmaW5hbCBpbnQgUkVUVVJOX0RJRkZFUkVOVF9VU0VSX0lEUyA9IDkzOworCisgICAgc3RhdGljIGZpbmFsIGludCBSRVBMWV9MRU5HVEggPSA4OworCisgICAgc3RhdGljIGZpbmFsIGludCBJTkRFWF9WRVJTSU9OID0gMDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTT0NLU19WRVJTSU9OID0gNDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTkRFWF9DT01NQU5EID0gMTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTkRFWF9QT1JUID0gMjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTkRFWF9JUCA9IDQ7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5ERVhfVVNFUl9JRCA9IDg7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQlVGRkVSX0xFTkdUSCA9IDI1NjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfVVNFUl9JRF9MRU5HVEggPSBCVUZGRVJfTEVOR1RIIC0gSU5ERVhfVVNFUl9JRDsKKworICAgIHByb3RlY3RlZCBieXRlW10gYnVmZmVyOworCisgICAgcHVibGljIFNvY2tzNE1lc3NhZ2UoKSB7CisgICAgICAgIGJ1ZmZlciA9IG5ldyBieXRlW0JVRkZFUl9MRU5HVEhdOworICAgICAgICBzZXRWZXJzaW9uTnVtYmVyKFNPQ0tTX1ZFUlNJT04pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgcmVxdWVzdCdzIGNvbW1hbmQgb3IgcmVzdWx0LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Q29tbWFuZE9yUmVzdWx0KCkgeworICAgICAgICByZXR1cm4gYnVmZmVyW0lOREVYX0NPTU1BTkRdOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgcmVxdWVzdCdzIGNvbW1hbmQgb3IgcmVzdWx0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvbW1hbmRPclJlc3VsdChpbnQgY29tbWFuZCkgeworICAgICAgICBidWZmZXJbSU5ERVhfQ09NTUFORF0gPSAoYnl0ZSkgY29tbWFuZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByZXF1ZXN0J3MgcG9ydCBudW1iZXIuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRQb3J0KCkgeworICAgICAgICByZXR1cm4gTWVtb3J5LnBlZWtTaG9ydChidWZmZXIsIElOREVYX1BPUlQsIEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHJlcXVlc3QncyBwb3J0IG51bWJlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQb3J0KGludCBwb3J0KSB7CisgICAgICAgIE1lbW9yeS5wb2tlU2hvcnQoYnVmZmVyLCBJTkRFWF9QT1JULCAoc2hvcnQpIHBvcnQsIEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBJUCBhZGRyZXNzIG9mIHRoZSByZXF1ZXN0IGFzIGFuIGludGVnZXIuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRJUCgpIHsKKyAgICAgICAgcmV0dXJuIE1lbW9yeS5wZWVrSW50KGJ1ZmZlciwgSU5ERVhfSVAsIEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIElQIGFkZHJlc3MuIFRoaXMgZXhwZWN0cyBhbiBhcnJheSBvZiBmb3VyIGJ5dGVzIGluIGhvc3Qgb3JkZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SVAoYnl0ZVtdIGlwKSB7CisgICAgICAgIGJ1ZmZlcltJTkRFWF9JUF0gPSBpcFswXTsKKyAgICAgICAgYnVmZmVyW0lOREVYX0lQICsgMV0gPSBpcFsxXTsKKyAgICAgICAgYnVmZmVyW0lOREVYX0lQICsgMl0gPSBpcFsyXTsKKyAgICAgICAgYnVmZmVyW0lOREVYX0lQICsgM10gPSBpcFszXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB1c2VyIGlkIGZvciBhdXRoZW50aWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFVzZXJJZCgpIHsKKyAgICAgICAgcmV0dXJuIGdldFN0cmluZyhJTkRFWF9VU0VSX0lELCBNQVhfVVNFUl9JRF9MRU5HVEgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgdXNlciBpZCBmb3IgYXV0aGVudGljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VXNlcklkKFN0cmluZyBpZCkgeworICAgICAgICBzZXRTdHJpbmcoSU5ERVhfVVNFUl9JRCwgTUFYX1VTRVJfSURfTEVOR1RILCBpZCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcig1MCk7CisgICAgICAgIGJ1Zi5hcHBlbmQoIlZlcnNpb246ICIpOworICAgICAgICBidWYuYXBwZW5kKEludGVnZXIudG9IZXhTdHJpbmcoZ2V0VmVyc2lvbk51bWJlcigpKSk7CisgICAgICAgIGJ1Zi5hcHBlbmQoIiBDb21tYW5kOiAiKTsKKyAgICAgICAgYnVmLmFwcGVuZChJbnRlZ2VyLnRvSGV4U3RyaW5nKGdldENvbW1hbmRPclJlc3VsdCgpKSk7CisgICAgICAgIGJ1Zi5hcHBlbmQoIiBQb3J0OiAiKTsKKyAgICAgICAgYnVmLmFwcGVuZChnZXRQb3J0KCkpOworICAgICAgICBidWYuYXBwZW5kKCIgSVA6ICIpOworICAgICAgICBidWYuYXBwZW5kKEludGVnZXIudG9IZXhTdHJpbmcoZ2V0SVAoKSkpOworICAgICAgICBidWYuYXBwZW5kKCIgVXNlciBJRDogIik7CisgICAgICAgIGJ1Zi5hcHBlbmQoZ2V0VXNlcklkKCkpOworICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHVzZWQgZm9yIHRoZSByZXF1ZXN0LiBUaGlzIG1ldGhvZAorICAgICAqIHNlYXJjaGVzIGZvciB0aGUgZW5kIG9mIHRoZSB1c2VyIGlkLCB0aGVuIHNlYXJjaGVzIGZvciB0aGUgZW5kIG9mIHRoZQorICAgICAqIHBhc3N3b3JkIGFuZCByZXR1cm5zIHRoZSBmaW5hbCBpbmRleCBhcyB0aGUgcmVxdWVzdHMgbGVuZ3RoLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgeworICAgICAgICBpbnQgaW5kZXggPSAwOworCisgICAgICAgIC8vIExvb2sgZm9yIHRoZSBlbmQgb2YgdGhlIHVzZXIgaWQuCisgICAgICAgIGZvciAoaW5kZXggPSBJTkRFWF9VU0VSX0lEOyBidWZmZXJbaW5kZXhdICE9IDA7IGluZGV4KyspIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBGaW5kcyB0aGUgZW5kIG9mIHRoZSB1c2VyIGlkIGJ5IHNlYXJjaGluZyBmb3IgdGhlIG51bGwKKyAgICAgICAgICAgICAqIHRlcm1pbmF0aW9uIG9mIHRoZSB1c2VyIGlkIHN0cmluZy4KKyAgICAgICAgICAgICAqLworICAgICAgICB9CisKKyAgICAgICAgLy8gSW5jcmVtZW50IHRoZSBpbmRleCB0byBpbmNsdWRlIHRoZSBOVUxMIGNoYXJhY3RlciBpbiB0aGUgbGVuZ3RoOworICAgICAgICBpbmRleCsrOworICAgICAgICByZXR1cm4gaW5kZXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBlcnJvciBzdHJpbmcgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gZXJyb3IgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRFcnJvclN0cmluZyhpbnQgZXJyb3IpIHsKKyAgICAgICAgc3dpdGNoIChlcnJvcikgeworICAgICAgICBjYXNlIFJFVFVSTl9GQUlMVVJFOgorICAgICAgICAgICAgcmV0dXJuICJGYWlsdXJlIHRvIGNvbm5lY3QgdG8gU09DS1Mgc2VydmVyIjsKKyAgICAgICAgY2FzZSBSRVRVUk5fQ0FOTk9UX0NPTk5FQ1RfVE9fSURFTlREOgorICAgICAgICAgICAgcmV0dXJuICJVbmFibGUgdG8gY29ubmVjdCB0byBpZGVudGQgdG8gdmVyaWZ5IHVzZXIiOworICAgICAgICBjYXNlIFJFVFVSTl9ESUZGRVJFTlRfVVNFUl9JRFM6CisgICAgICAgICAgICByZXR1cm4gIkZhaWx1cmUgLSB1c2VyIGlkcyBkbyBub3QgbWF0Y2giOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgcmV0dXJuICJTdWNjZXNzIjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1lc3NhZ2UncyBieXRlIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEJ5dGVzKCkgeworICAgICAgICByZXR1cm4gYnVmZmVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhIFN0cmluZyBmcm9tIHRoZSBidWZmZXIgYXQgdGhlIG9mZnNldCBnaXZlbi4gVGhlIG1ldGhvZCByZWFkcyB1bnRpbAorICAgICAqIGl0IGVuY291bnRlcnMgYSBudWxsIHZhbHVlIG9yIHJlYWNoZXMgdGhlIG1heExlbmd0aCBnaXZlbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBnZXRTdHJpbmcoaW50IG9mZnNldCwgaW50IG1heExlbmd0aCkgeworICAgICAgICBpbnQgaW5kZXggPSBvZmZzZXQ7CisgICAgICAgIGludCBsYXN0SW5kZXggPSBpbmRleCArIG1heExlbmd0aDsKKyAgICAgICAgd2hpbGUgKGluZGV4IDwgbGFzdEluZGV4ICYmIChidWZmZXJbaW5kZXhdICE9IDApKSB7CisgICAgICAgICAgICBpbmRleCsrOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGJ1ZmZlciwgb2Zmc2V0LCBpbmRleCAtIG9mZnNldCwgQ2hhcnNldHMuSVNPXzg4NTlfMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgU09DS1MgdmVyc2lvbiBudW1iZXIuIFNob3VsZCBhbHdheXMgYmUgNC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBnZXRWZXJzaW9uTnVtYmVyKCkgeworICAgICAgICByZXR1cm4gYnVmZmVyW0lOREVYX1ZFUlNJT05dOworICAgIH0KKworICAgIC8qKgorICAgICAqIFB1dCBhIHN0cmluZyBpbnRvIHRoZSBidWZmZXIgYXQgdGhlIG9mZnNldCBnaXZlbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0U3RyaW5nKGludCBvZmZzZXQsIGludCBtYXhMZW5ndGgsIFN0cmluZyB0aGVTdHJpbmcpIHsKKyAgICAgICAgYnl0ZVtdIHN0cmluZ0J5dGVzID0gdGhlU3RyaW5nLmdldEJ5dGVzKENoYXJzZXRzLklTT184ODU5XzEpOworICAgICAgICBpbnQgbGVuZ3RoID0gTWF0aC5taW4oc3RyaW5nQnl0ZXMubGVuZ3RoLCBtYXhMZW5ndGgpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHN0cmluZ0J5dGVzLCAwLCBidWZmZXIsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgYnVmZmVyW29mZnNldCArIGxlbmd0aF0gPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgU09DS1MgdmVyc2lvbiBudW1iZXIuIFRoaXMgc2hvdWxkIGFsd2F5cyBiZSA0LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRWZXJzaW9uTnVtYmVyKGludCBudW1iZXIpIHsKKyAgICAgICAgYnVmZmVyW0lOREVYX1ZFUlNJT05dID0gKGJ5dGUpIG51bWJlcjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvVVJJLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvVVJJLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmI3YjFkYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9VUkkuamF2YQpAQCAtMCwwICsxLDEzNzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBsaWJjb3JlLm5ldC5VcmlDb2RlYzsKK2ltcG9ydCBsaWJjb3JlLm5ldC51cmwuVXJsVXRpbHM7CisKKy8qKgorICogQSBVbmlmb3JtIFJlc291cmNlIElkZW50aWZpZXIgdGhhdCBpZGVudGlmaWVzIGFuIGFic3RyYWN0IG9yIHBoeXNpY2FsCisgKiByZXNvdXJjZSwgYXMgc3BlY2lmaWVkIGJ5IDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Ij5SRkMKKyAqIDIzOTY8L2E+LgorICoKKyAqIDxoMz5QYXJ0cyBvZiBhIFVSSTwvaDM+CisgKiBBIFVSSSBpcyBjb21wb3NlZCBvZiBtYW55IHBhcnRzLiBUaGlzIGNsYXNzIGNhbiBib3RoIHBhcnNlIFVSSSBzdHJpbmdzIGludG8KKyAqIHBhcnRzIGFuZCBjb21wb3NlIFVSSSBzdHJpbmdzIGZyb20gcGFydHMuIEZvciBleGFtcGxlLCBjb25zaWRlciB0aGUgcGFydHMgb2YKKyAqIHRoaXMgVVJJOgorICoge0Bjb2RlIGh0dHA6Ly91c2VybmFtZTpwYXNzd29yZEBob3N0OjgwODAvZGlyZWN0b3J5L2ZpbGU/cXVlcnkjZnJhZ21lbnR9CisgKiA8dGFibGU+CisgKiA8dHI+PHRoPkNvbXBvbmVudCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90aD48dGg+RXhhbXBsZSB2YWx1ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+PHRoPkFsc28ga25vd24gYXM8L3RoPjwvdHI+CisgKiA8dHI+PHRkPntAbGluayAjZ2V0U2NoZW1lKCkgU2NoZW1lfSAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+e0Bjb2RlIGh0dHB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+PHRkPnByb3RvY29sPC90ZD48L3RyPgorICogPHRyPjx0ZD57QGxpbmsgI2dldFNjaGVtZVNwZWNpZmljUGFydCgpIFNjaGVtZS1zcGVjaWZpYyBwYXJ0fTwvdGQ+PHRkPntAY29kZSAvL3VzZXJuYW1lOnBhc3N3b3JkQGhvc3Q6ODA4MC9kaXJlY3RvcnkvZmlsZT9xdWVyeSNmcmFnbWVudH08L3RkPjx0ZD48L3RkPjwvdHI+CisgKiA8dHI+PHRkPntAbGluayAjZ2V0QXV0aG9yaXR5KCkgQXV0aG9yaXR5fSAgICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+e0Bjb2RlIHVzZXJuYW1lOnBhc3N3b3JkQGhvc3Q6ODA4MH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+PHRkPjwvdGQ+PC90cj4KKyAqIDx0cj48dGQ+e0BsaW5rICNnZXRVc2VySW5mbygpIFVzZXIgSW5mb30gICAgICAgICAgICAgICAgICAgICA8L3RkPjx0ZD57QGNvZGUgdXNlcm5hbWU6cGFzc3dvcmR9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+PC90ZD48L3RyPgorICogPHRyPjx0ZD57QGxpbmsgI2dldEhvc3QoKSBIb3N0fSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+PHRkPntAY29kZSBob3N0fSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPjx0ZD48L3RkPjwvdHI+CisgKiA8dHI+PHRkPntAbGluayAjZ2V0UG9ydCgpIFBvcnR9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+e0Bjb2RlIDgwODB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+PHRkPjwvdGQ+PC90cj4KKyAqIDx0cj48dGQ+e0BsaW5rICNnZXRQYXRoKCkgUGF0aH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPjx0ZD57QGNvZGUgL2RpcmVjdG9yeS9maWxlfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+PC90ZD48L3RyPgorICogPHRyPjx0ZD57QGxpbmsgI2dldFF1ZXJ5KCkgUXVlcnl9ICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+PHRkPntAY29kZSBxdWVyeX0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPjx0ZD48L3RkPjwvdHI+CisgKiA8dHI+PHRkPntAbGluayAjZ2V0RnJhZ21lbnQoKSBGcmFnbWVudH0gICAgICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+e0Bjb2RlIGZyYWdtZW50fSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+PHRkPnJlZjwvdGQ+PC90cj4KKyAqIDwvdGFibGU+CisgKgorICogPGgzPkFic29sdXRlIHZzLiBSZWxhdGl2ZSBVUklzPC9oMz4KKyAqIFVSSXMgYXJlIGVpdGhlciB7QGxpbmsgI2lzQWJzb2x1dGUoKSBhYnNvbHV0ZSBvciByZWxhdGl2ZX0uCisgKiA8dWw+CisgKiAgICAgPGxpPjxzdHJvbmc+QWJzb2x1dGU6PC9zdHJvbmc+IHtAY29kZSBodHRwOi8vYW5kcm9pZC5jb20vcm9ib3RzLnR4dH0KKyAqICAgICA8bGk+PHN0cm9uZz5SZWxhdGl2ZTo8L3N0cm9uZz4ge0Bjb2RlIHJvYm90cy50eHR9CisgKiA8L3VsPgorICoKKyAqIDxwPkFic29sdXRlIFVSSXMgYWx3YXlzIGhhdmUgYSBzY2hlbWUuIElmIGl0cyBzY2hlbWUgaXMgc3VwcG9ydGVkIGJ5IHtAbGluaworICogVVJMfSwgeW91IGNhbiB1c2Uge0BsaW5rICN0b1VSTH0gdG8gY29udmVydCBhbiBhYnNvbHV0ZSBVUkkgdG8gYSBVUkwuCisgKgorICogPHA+UmVsYXRpdmUgVVJJcyBkbyBub3QgaGF2ZSBhIHNjaGVtZSBhbmQgY2Fubm90IGJlIGNvbnZlcnRlZCB0byBVUkxzLiBJZiB5b3UKKyAqIGhhdmUgdGhlIGFic29sdXRlIFVSSSB0aGF0IGEgcmVsYXRpdmUgVVJJIGlzIHJlbGF0aXZlIHRvLCB5b3UgY2FuIHVzZSB7QGxpbmsKKyAqICNyZXNvbHZlfSB0byBjb21wdXRlIHRoZSByZWZlcmVuY2VkIGFic29sdXRlIFVSSS4gU3ltbWV0cmljYWxseSwgeW91IGNhbiB1c2UKKyAqIHtAbGluayAjcmVsYXRpdml6ZX0gdG8gY29tcHV0ZSB0aGUgcmVsYXRpdmUgVVJJIGZyb20gb25lIFVSSSB0byBhbm90aGVyLgorICogPHByZT4gICB7QGNvZGUKKyAqICAgVVJJIGFic29sdXRlID0gbmV3IFVSSSgiaHR0cDovL2FuZHJvaWQuY29tLyIpOworICogICBVUkkgcmVsYXRpdmUgPSBuZXcgVVJJKCJyb2JvdHMudHh0Iik7CisgKiAgIFVSSSByZXNvbHZlZCA9IG5ldyBVUkkoImh0dHA6Ly9hbmRyb2lkLmNvbS9yb2JvdHMudHh0Iik7CisgKgorICogICAvLyBwcmludCAiaHR0cDovL2FuZHJvaWQuY29tL3JvYm90cy50eHQiCisgKiAgIFN5c3RlbS5vdXQucHJpbnRsbihhYnNvbHV0ZS5yZXNvbHZlKHJlbGF0aXZlKSk7CisgKgorICogICAvLyBwcmludCAicm9ib3RzLnR4dCIKKyAqICAgU3lzdGVtLm91dC5wcmludGxuKGFic29sdXRlLnJlbGF0aXZpemUocmVzb2x2ZWQpKTsKKyAqIH08L3ByZT4KKyAqCisgKiA8aDM+T3BhcXVlIHZzLiBIaWVyYXJjaGljYWwgVVJJczwvaDM+CisgKiBBYnNvbHV0ZSBVUklzIGFyZSBlaXRoZXIge0BsaW5rICNpc09wYXF1ZSgpIG9wYXF1ZSBvciBoaWVyYXJjaGljYWx9LiBSZWxhdGl2ZQorICogVVJJcyBhcmUgYWx3YXlzIGhpZXJhcmNoaWNhbC4KKyAqIDx1bD4KKyAqICAgICA8bGk+PHN0cm9uZz5IaWVyYXJjaGljYWw6PC9zdHJvbmc+IHtAY29kZSBodHRwOi8vYW5kcm9pZC5jb20vcm9ib3RzLnR4dH0KKyAqICAgICA8bGk+PHN0cm9uZz5PcGFxdWU6PC9zdHJvbmc+IHtAY29kZSBtYWlsdG86cm9ib3RzQGV4YW1wbGUuY29tfQorICogPC91bD4KKyAqCisgKiA8cD5PcGFxdWUgVVJJcyBoYXZlIGJvdGggYSBzY2hlbWUgYW5kIGEgc2NoZW1lLXNwZWNpZmljIHBhcnQgdGhhdCBkb2VzIG5vdAorICogYmVnaW4gd2l0aCB0aGUgc2xhc2ggY2hhcmFjdGVyOiB7QGNvZGUgL30uIFRoZSBjb250ZW50cyBvZiB0aGUKKyAqIHNjaGVtZS1zcGVjaWZpYyBwYXJ0IG9mIGFuIG9wYXF1ZSBVUkkgaXMgbm90IHBhcnNlZCBzbyBhbiBvcGFxdWUgVVJJIG5ldmVyCisgKiBoYXMgYW4gYXV0aG9yaXR5LCB1c2VyIGluZm8sIGhvc3QsIHBvcnQsIHBhdGggb3IgcXVlcnkuIEFuIG9wYXF1ZSBVUklzIG1heQorICogaGF2ZSBhIGZyYWdtZW50LCBob3dldmVyLiBBIHR5cGljYWwgb3BhcXVlIFVSSSBpcworICoge0Bjb2RlIG1haWx0bzpyb2JvdHNAZXhhbXBsZS5jb219LgorICogPHRhYmxlPgorICogPHRyPjx0aD5Db21wb25lbnQgICAgICAgICAgIDwvdGg+PHRoPkV4YW1wbGUgdmFsdWUgICAgICAgICAgICAgPC90aD48L3RyPgorICogPHRyPjx0ZD5TY2hlbWUgICAgICAgICAgICAgIDwvdGQ+PHRkPntAY29kZSBtYWlsdG99ICAgICAgICAgICAgPC90ZD48L3RyPgorICogPHRyPjx0ZD5TY2hlbWUtc3BlY2lmaWMgcGFydDwvdGQ+PHRkPntAY29kZSByb2JvdHNAZXhhbXBsZS5jb219PC90ZD48L3RyPgorICogPHRyPjx0ZD5GcmFnbWVudCAgICAgICAgICAgIDwvdGQ+PHRkPiAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD48L3RyPgorICogPC90YWJsZT4KKyAqIDxwPkhpZXJhcmNoaWNhbCBVUklzIG1heSBoYXZlIHZhbHVlcyBmb3IgYW55IFVSTCBjb21wb25lbnQuIFRoZXkgYWx3YXlzCisgKiBoYXZlIGEgbm9uLW51bGwgcGF0aCwgdGhvdWdoIHRoYXQgcGF0aCBtYXkgYmUgdGhlIGVtcHR5IHN0cmluZy4KKyAqCisgKiA8aDM+RW5jb2RpbmcgYW5kIERlY29kaW5nIFVSSSBDb21wb25lbnRzPC9oMz4KKyAqIEVhY2ggY29tcG9uZW50IG9mIGEgVVJJIHBlcm1pdHMgYSBsaW1pdGVkIHNldCBvZiBsZWdhbCBjaGFyYWN0ZXJzLiBPdGhlcgorICogY2hhcmFjdGVycyBtdXN0IGZpcnN0IGJlIDxpPmVuY29kZWQ8L2k+IGJlZm9yZSB0aGV5IGNhbiBiZSBlbWJlZGRlZCBpbiBhIFVSSS4KKyAqIFRvIHJlY292ZXIgdGhlIG9yaWdpbmFsIGNoYXJhY3RlcnMgZnJvbSBhIFVSSSwgdGhleSBtYXkgYmUgPGk+ZGVjb2RlZDwvaT4uCisgKiA8c3Ryb25nPkNvbnRyYXJ5IHRvIHdoYXQgeW91IG1pZ2h0IGV4cGVjdCw8L3N0cm9uZz4gdGhpcyBjbGFzcyB1c2VzIHRoZQorICogdGVybSA8aT5yYXc8L2k+IHRvIHJlZmVyIHRvIGVuY29kZWQgc3RyaW5ncy4gVGhlIG5vbi08aT5yYXc8L2k+IGFjY2Vzc29ycworICogcmV0dXJuIGRlY29kZWQgc3RyaW5ncy4gRm9yIGV4YW1wbGUsIGNvbnNpZGVyIGhvdyB0aGlzIFVSSSBpcyBkZWNvZGVkOgorICoge0Bjb2RlIGh0dHA6Ly91c2VyOnBhNTV3JTNGcmRAaG9zdDo4MC9kb2MlN0NzZWFyY2g/cT1ncmVlbiUyMHJvYm90cyNvdmVyJTIwNiUyMn0KKyAqIDx0YWJsZT4KKyAqIDx0cj48dGg+Q29tcG9uZW50ICAgICAgICAgICA8L3RoPjx0aD5MZWdhbCBDaGFyYWN0ZXJzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+PHRoPk90aGVyIENvbnN0cmFpbnRzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+PHRoPlJhdyBWYWx1ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+PHRoPlZhbHVlPC90aD48L3RyPgorICogPHRyPjx0ZD5TY2hlbWUgICAgICAgICAgICAgIDwvdGQ+PHRkPntAY29kZSAwLTl9LCB7QGNvZGUgYS16fSwge0Bjb2RlIEEtWn0sIHtAY29kZSArLS59ICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+Rmlyc3QgY2hhcmFjdGVyIG11c3QgYmUgaW4ge0Bjb2RlIGEten0sIHtAY29kZSBBLVp9PC90ZD48dGQ+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+e0Bjb2RlIGh0dHB9PC90ZD48L3RyPgorICogPHRyPjx0ZD5TY2hlbWUtc3BlY2lmaWMgcGFydDwvdGQ+PHRkPntAY29kZSAwLTl9LCB7QGNvZGUgYS16fSwge0Bjb2RlIEEtWn0sIHtAY29kZSBfLSEuficoKSosOzokJis9Py9bXUB9PC90ZD48dGQ+Tm9uLUFTQ0lJIGNoYXJhY3RlcnMgb2theSAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+e0Bjb2RlIC8vdXNlcjpwYTU1dyUzRnJkQGhvc3Q6ODAvZG9jJTdDc2VhcmNoP3E9Z3JlZW4lMjByb2JvdHN9PC90ZD48dGQ+e0Bjb2RlIC8vdXNlcjpwYTU1dz9yZEBob3N0OjgwL2RvY3xzZWFyY2g/cT1ncmVlbiByb2JvdHN9PC90ZD48L3RyPgorICogPHRyPjx0ZD5BdXRob3JpdHkgICAgICAgICAgIDwvdGQ+PHRkPntAY29kZSAwLTl9LCB7QGNvZGUgYS16fSwge0Bjb2RlIEEtWn0sIHtAY29kZSBfLSEuficoKSosOzokJis9QFtdfSAgPC90ZD48dGQ+Tm9uLUFTQ0lJIGNoYXJhY3RlcnMgb2theSAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+e0Bjb2RlIHVzZXI6cGE1NXclM0ZyZEBob3N0OjgwfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+e0Bjb2RlIHVzZXI6cGE1NXc/cmRAaG9zdDo4MH08L3RkPjwvdHI+CisgKiA8dHI+PHRkPlVzZXIgSW5mbyAgICAgICAgICAgPC90ZD48dGQ+e0Bjb2RlIDAtOX0sIHtAY29kZSBhLXp9LCB7QGNvZGUgQS1afSwge0Bjb2RlIF8tIS5+JygpKiw7OiQmKz19ICAgICA8L3RkPjx0ZD5Ob24tQVNDSUkgY2hhcmFjdGVycyBva2F5ICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPjx0ZD57QGNvZGUgdXNlcjpwYTU1dyUzRnJkfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPjx0ZD57QGNvZGUgdXNlcjpwYTU1dz9yZH08L3RkPjwvdHI+CisgKiA8dHI+PHRkPkhvc3QgICAgICAgICAgICAgICAgPC90ZD48dGQ+e0Bjb2RlIDAtOX0sIHtAY29kZSBhLXp9LCB7QGNvZGUgQS1afSwge0Bjb2RlIC0uW119ICAgICAgICAgICAgICAgICA8L3RkPjx0ZD5Eb21haW4gbmFtZSwgSVB2NCBhZGRyZXNzIG9yIFtJUHY2IGFkZHJlc3NdICAgICAgICA8L3RkPjx0ZD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPjx0ZD5ob3N0PC90ZD48L3RyPgorICogPHRyPjx0ZD5Qb3J0ICAgICAgICAgICAgICAgIDwvdGQ+PHRkPntAY29kZSAwLTl9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+e0Bjb2RlIDgwfTwvdGQ+PC90cj4KKyAqIDx0cj48dGQ+UGF0aCAgICAgICAgICAgICAgICA8L3RkPjx0ZD57QGNvZGUgMC05fSwge0Bjb2RlIGEten0sIHtAY29kZSBBLVp9LCB7QGNvZGUgXy0hLn4nKCkqLDs6JCYrPS9AfSAgIDwvdGQ+PHRkPk5vbi1BU0NJSSBjaGFyYWN0ZXJzIG9rYXkgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+PHRkPntAY29kZSAvZG9jJTdDc2VhcmNofSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+PHRkPntAY29kZSAvZG9jfHNlYXJjaH08L3RkPjwvdHI+CisgKiA8dHI+PHRkPlF1ZXJ5ICAgICAgICAgICAgICAgPC90ZD48dGQ+e0Bjb2RlIDAtOX0sIHtAY29kZSBhLXp9LCB7QGNvZGUgQS1afSwge0Bjb2RlIF8tIS5+JygpKiw7OiQmKz0/L1tdQH08L3RkPjx0ZD5Ob24tQVNDSUkgY2hhcmFjdGVycyBva2F5ICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPjx0ZD57QGNvZGUgcT1ncmVlbiUyMHJvYm90c30gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPjx0ZD57QGNvZGUgcT1ncmVlbiByb2JvdHN9PC90ZD48L3RyPgorICogPHRyPjx0ZD5GcmFnbWVudCAgICAgICAgICAgIDwvdGQ+PHRkPntAY29kZSAwLTl9LCB7QGNvZGUgYS16fSwge0Bjb2RlIEEtWn0sIHtAY29kZSBfLSEuficoKSosOzokJis9Py9bXUB9PC90ZD48dGQ+Tm9uLUFTQ0lJIGNoYXJhY3RlcnMgb2theSAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+e0Bjb2RlIG92ZXIlMjA2JTIyfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD48dGQ+e0Bjb2RlIG92ZXIgNiJ9PC90ZD48L3RyPgorICogPC90YWJsZT4KKyAqIEEgVVJJJ3MgaG9zdCwgcG9ydCBhbmQgc2NoZW1lIGFyZSBub3QgZWxpZ2libGUgZm9yIGVuY29kaW5nIGFuZCBtdXN0IG5vdAorICogY29udGFpbiBpbGxlZ2FsIGNoYXJhY3RlcnMuCisgKgorICogPHA+VG8gZW5jb2RlIGEgVVJJLCBpbnZva2UgYW55IG9mIHRoZSBtdWx0aXBsZS1wYXJhbWV0ZXIgY29uc3RydWN0b3JzIG9mIHRoaXMKKyAqIGNsYXNzLiBUaGVzZSBjb25zdHJ1Y3RvcnMgYWNjZXB0IHlvdXIgb3JpZ2luYWwgc3RyaW5ncyBhbmQgZW5jb2RlIHRoZW0gaW50bworICogdGhlaXIgcmF3IGZvcm0uCisgKgorICogPHA+VG8gZGVjb2RlIGEgVVJJLCBpbnZva2UgdGhlIHNpbmdsZS1zdHJpbmcgY29uc3RydWN0b3IsIGFuZCB0aGVuIHVzZSB0aGUKKyAqIGFwcHJvcHJpYXRlIGFjY2Vzc29yIG1ldGhvZHMgdG8gZ2V0IHRoZSBkZWNvZGVkIGNvbXBvbmVudHMuCisgKgorICogPHA+VGhlIHtAbGluayBVUkx9IGNsYXNzIGNhbiBiZSB1c2VkIHRvIHJldHJpZXZlIHJlc291cmNlcyBieSB0aGVpciBVUkkuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBVUkkgaW1wbGVtZW50cyBDb21wYXJhYmxlPFVSST4sIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjA1MjQyNDI4NDExMDk2MDIxM2w7CisKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIFVOUkVTRVJWRUQgPSAiXy0hLn5cJygpKiI7CisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBQVU5DVFVBVElPTiA9ICIsOzokJis9IjsKKworICAgIHN0YXRpYyBmaW5hbCBVcmlDb2RlYyBVU0VSX0lORk9fRU5DT0RFUiA9IG5ldyBQYXJ0RW5jb2RlcigiIik7CisgICAgc3RhdGljIGZpbmFsIFVyaUNvZGVjIFBBVEhfRU5DT0RFUiA9IG5ldyBQYXJ0RW5jb2RlcigiL0AiKTsKKyAgICBzdGF0aWMgZmluYWwgVXJpQ29kZWMgQVVUSE9SSVRZX0VOQ09ERVIgPSBuZXcgUGFydEVuY29kZXIoIkBbXSIpOworCisgICAgLyoqIGZvciBqYXZhLm5ldC5VUkwsIHdoaWNoIGZvb2xpc2hseSBjb21iaW5lcyB0aGVzZSB0d28gcGFydHMgKi8KKyAgICBzdGF0aWMgZmluYWwgVXJpQ29kZWMgRklMRV9BTkRfUVVFUllfRU5DT0RFUiA9IG5ldyBQYXJ0RW5jb2RlcigiL0A/Iik7CisKKyAgICAvKiogZm9yIHF1ZXJ5LCBmcmFnbWVudCwgYW5kIHNjaGVtZS1zcGVjaWZpYyBwYXJ0ICovCisgICAgc3RhdGljIGZpbmFsIFVyaUNvZGVjIEFMTF9MRUdBTF9FTkNPREVSID0gbmV3IFBhcnRFbmNvZGVyKCI/L1tdQCIpOworCisgICAgLyoqIFJldGFpbnMgYWxsIEFTQ0lJIGNoYXJzIGluY2x1ZGluZyBkZWxpbWl0ZXJzLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFVyaUNvZGVjIEFTQ0lJX09OTFkgPSBuZXcgVXJpQ29kZWMoKSB7CisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgYm9vbGVhbiBpc1JldGFpbmVkKGNoYXIgYykgeworICAgICAgICAgICAgcmV0dXJuIGMgPD0gMTI3OworICAgICAgICB9CisgICAgfTsKKworICAgIC8qKgorICAgICAqIEVuY29kZXMgdGhlIHVuZXNjYXBlZCBjaGFyYWN0ZXJzIG9mIHtAY29kZSBzfSB0aGF0IGFyZSBub3QgcGVybWl0dGVkLgorICAgICAqIFBlcm1pdHRlZCBjaGFyYWN0ZXJzIGFyZToKKyAgICAgKiA8dWw+CisgICAgICogICA8bGk+VW5yZXNlcnZlZCBjaGFyYWN0ZXJzIGluIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Ij5SRkMgMjM5NjwvYT4uCisgICAgICogICA8bGk+e0Bjb2RlIGV4dHJhT2theUNoYXJzfSwKKyAgICAgKiAgIDxsaT5ub24tQVNDSUksIG5vbi1jb250cm9sLCBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXJzCisgICAgICogPC91bD4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBQYXJ0RW5jb2RlciBleHRlbmRzIFVyaUNvZGVjIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZXh0cmFMZWdhbENoYXJhY3RlcnM7CisKKyAgICAgICAgUGFydEVuY29kZXIoU3RyaW5nIGV4dHJhTGVnYWxDaGFyYWN0ZXJzKSB7CisgICAgICAgICAgICB0aGlzLmV4dHJhTGVnYWxDaGFyYWN0ZXJzID0gZXh0cmFMZWdhbENoYXJhY3RlcnM7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIGJvb2xlYW4gaXNSZXRhaW5lZChjaGFyIGMpIHsKKyAgICAgICAgICAgIHJldHVybiBVTlJFU0VSVkVELmluZGV4T2YoYykgIT0gLTEKKyAgICAgICAgICAgICAgICAgICAgfHwgUFVOQ1RVQVRJT04uaW5kZXhPZihjKSAhPSAtMQorICAgICAgICAgICAgICAgICAgICB8fCBleHRyYUxlZ2FsQ2hhcmFjdGVycy5pbmRleE9mKGMpICE9IC0xCisgICAgICAgICAgICAgICAgICAgIHx8IChjID4gMTI3ICYmICFDaGFyYWN0ZXIuaXNTcGFjZUNoYXIoYykgJiYgIUNoYXJhY3Rlci5pc0lTT0NvbnRyb2woYykpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgc3RyaW5nOworICAgIHByaXZhdGUgdHJhbnNpZW50IFN0cmluZyBzY2hlbWU7CisgICAgcHJpdmF0ZSB0cmFuc2llbnQgU3RyaW5nIHNjaGVtZVNwZWNpZmljUGFydDsKKyAgICBwcml2YXRlIHRyYW5zaWVudCBTdHJpbmcgYXV0aG9yaXR5OworICAgIHByaXZhdGUgdHJhbnNpZW50IFN0cmluZyB1c2VySW5mbzsKKyAgICBwcml2YXRlIHRyYW5zaWVudCBTdHJpbmcgaG9zdDsKKyAgICBwcml2YXRlIHRyYW5zaWVudCBpbnQgcG9ydCA9IC0xOworICAgIHByaXZhdGUgdHJhbnNpZW50IFN0cmluZyBwYXRoOworICAgIHByaXZhdGUgdHJhbnNpZW50IFN0cmluZyBxdWVyeTsKKyAgICBwcml2YXRlIHRyYW5zaWVudCBTdHJpbmcgZnJhZ21lbnQ7CisgICAgcHJpdmF0ZSB0cmFuc2llbnQgYm9vbGVhbiBvcGFxdWU7CisgICAgcHJpdmF0ZSB0cmFuc2llbnQgYm9vbGVhbiBhYnNvbHV0ZTsKKyAgICBwcml2YXRlIHRyYW5zaWVudCBib29sZWFuIHNlcnZlckF1dGhvcml0eSA9IGZhbHNlOworCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IGhhc2ggPSAtMTsKKworICAgIHByaXZhdGUgVVJJKCkge30KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgVVJJIGluc3RhbmNlIGJ5IHBhcnNpbmcge0Bjb2RlIHNwZWN9LgorICAgICAqCisgICAgICogQHBhcmFtIHNwZWMgYSBVUkkgd2hvc2UgaWxsZWdhbCBjaGFyYWN0ZXJzIGhhdmUgYWxsIGJlZW4gZW5jb2RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJJKFN0cmluZyBzcGVjKSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgcGFyc2VVUkkoc3BlYywgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgVVJJIGluc3RhbmNlIG9mIHRoZSBnaXZlbiB1bmVuY29kZWQgY29tcG9uZW50IHBhcnRzLgorICAgICAqCisgICAgICogQHBhcmFtIHNjaGVtZSB0aGUgVVJJIHNjaGVtZSwgb3IgbnVsbCBmb3IgYSBub24tYWJzb2x1dGUgVVJJLgorICAgICAqLworICAgIHB1YmxpYyBVUkkoU3RyaW5nIHNjaGVtZSwgU3RyaW5nIHNjaGVtZVNwZWNpZmljUGFydCwgU3RyaW5nIGZyYWdtZW50KQorICAgICAgICAgICAgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgdXJpID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgaWYgKHNjaGVtZSAhPSBudWxsKSB7CisgICAgICAgICAgICB1cmkuYXBwZW5kKHNjaGVtZSk7CisgICAgICAgICAgICB1cmkuYXBwZW5kKCc6Jyk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNjaGVtZVNwZWNpZmljUGFydCAhPSBudWxsKSB7CisgICAgICAgICAgICBBTExfTEVHQUxfRU5DT0RFUi5hcHBlbmRFbmNvZGVkKHVyaSwgc2NoZW1lU3BlY2lmaWNQYXJ0KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZnJhZ21lbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgdXJpLmFwcGVuZCgnIycpOworICAgICAgICAgICAgQUxMX0xFR0FMX0VOQ09ERVIuYXBwZW5kRW5jb2RlZCh1cmksIGZyYWdtZW50KTsKKyAgICAgICAgfQorCisgICAgICAgIHBhcnNlVVJJKHVyaS50b1N0cmluZygpLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBVUkkgaW5zdGFuY2Ugb2YgdGhlIGdpdmVuIHVuZW5jb2RlZCBjb21wb25lbnQgcGFydHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2NoZW1lIHRoZSBVUkkgc2NoZW1lLCBvciBudWxsIGZvciBhIG5vbi1hYnNvbHV0ZSBVUkkuCisgICAgICovCisgICAgcHVibGljIFVSSShTdHJpbmcgc2NoZW1lLCBTdHJpbmcgdXNlckluZm8sIFN0cmluZyBob3N0LCBpbnQgcG9ydCwgU3RyaW5nIHBhdGgsIFN0cmluZyBxdWVyeSwKKyAgICAgICAgICAgIFN0cmluZyBmcmFnbWVudCkgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzY2hlbWUgPT0gbnVsbCAmJiB1c2VySW5mbyA9PSBudWxsICYmIGhvc3QgPT0gbnVsbCAmJiBwYXRoID09IG51bGwKKyAgICAgICAgICAgICAgICAmJiBxdWVyeSA9PSBudWxsICYmIGZyYWdtZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMucGF0aCA9ICIiOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHNjaGVtZSAhPSBudWxsICYmIHBhdGggIT0gbnVsbCAmJiAhcGF0aC5pc0VtcHR5KCkgJiYgcGF0aC5jaGFyQXQoMCkgIT0gJy8nKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVVJJU3ludGF4RXhjZXB0aW9uKHBhdGgsICJSZWxhdGl2ZSBwYXRoIik7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdCdWlsZGVyIHVyaSA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGlmIChzY2hlbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgdXJpLmFwcGVuZChzY2hlbWUpOworICAgICAgICAgICAgdXJpLmFwcGVuZCgnOicpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHVzZXJJbmZvICE9IG51bGwgfHwgaG9zdCAhPSBudWxsIHx8IHBvcnQgIT0gLTEpIHsKKyAgICAgICAgICAgIHVyaS5hcHBlbmQoIi8vIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAodXNlckluZm8gIT0gbnVsbCkgeworICAgICAgICAgICAgVVNFUl9JTkZPX0VOQ09ERVIuYXBwZW5kRW5jb2RlZCh1cmksIHVzZXJJbmZvKTsKKyAgICAgICAgICAgIHVyaS5hcHBlbmQoJ0AnKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChob3N0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGNoZWNrIGZvciBJUHY2IGFkZHJlc3NlcyB0aGF0IGhhc24ndCBiZWVuIGVuY2xvc2VkIGluIHNxdWFyZSBicmFja2V0cworICAgICAgICAgICAgaWYgKGhvc3QuaW5kZXhPZignOicpICE9IC0xICYmIGhvc3QuaW5kZXhPZignXScpID09IC0xICYmIGhvc3QuaW5kZXhPZignWycpID09IC0xKSB7CisgICAgICAgICAgICAgICAgaG9zdCA9ICJbIiArIGhvc3QgKyAiXSI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB1cmkuYXBwZW5kKGhvc3QpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHBvcnQgIT0gLTEpIHsKKyAgICAgICAgICAgIHVyaS5hcHBlbmQoJzonKTsKKyAgICAgICAgICAgIHVyaS5hcHBlbmQocG9ydCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAocGF0aCAhPSBudWxsKSB7CisgICAgICAgICAgICBQQVRIX0VOQ09ERVIuYXBwZW5kRW5jb2RlZCh1cmksIHBhdGgpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHF1ZXJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHVyaS5hcHBlbmQoJz8nKTsKKyAgICAgICAgICAgIEFMTF9MRUdBTF9FTkNPREVSLmFwcGVuZEVuY29kZWQodXJpLCBxdWVyeSk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZnJhZ21lbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgdXJpLmFwcGVuZCgnIycpOworICAgICAgICAgICAgQUxMX0xFR0FMX0VOQ09ERVIuYXBwZW5kRW5jb2RlZCh1cmksIGZyYWdtZW50KTsKKyAgICAgICAgfQorCisgICAgICAgIHBhcnNlVVJJKHVyaS50b1N0cmluZygpLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IFVSSSBpbnN0YW5jZSBvZiB0aGUgZ2l2ZW4gdW5lbmNvZGVkIGNvbXBvbmVudCBwYXJ0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzY2hlbWUgdGhlIFVSSSBzY2hlbWUsIG9yIG51bGwgZm9yIGEgbm9uLWFic29sdXRlIFVSSS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJJKFN0cmluZyBzY2hlbWUsIFN0cmluZyBob3N0LCBTdHJpbmcgcGF0aCwgU3RyaW5nIGZyYWdtZW50KSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhzY2hlbWUsIG51bGwsIGhvc3QsIC0xLCBwYXRoLCBudWxsLCBmcmFnbWVudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBVUkkgaW5zdGFuY2Ugb2YgdGhlIGdpdmVuIHVuZW5jb2RlZCBjb21wb25lbnQgcGFydHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2NoZW1lIHRoZSBVUkkgc2NoZW1lLCBvciBudWxsIGZvciBhIG5vbi1hYnNvbHV0ZSBVUkkuCisgICAgICovCisgICAgcHVibGljIFVSSShTdHJpbmcgc2NoZW1lLCBTdHJpbmcgYXV0aG9yaXR5LCBTdHJpbmcgcGF0aCwgU3RyaW5nIHF1ZXJ5LAorICAgICAgICAgICAgU3RyaW5nIGZyYWdtZW50KSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNjaGVtZSAhPSBudWxsICYmIHBhdGggIT0gbnVsbCAmJiAhcGF0aC5pc0VtcHR5KCkgJiYgcGF0aC5jaGFyQXQoMCkgIT0gJy8nKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVVJJU3ludGF4RXhjZXB0aW9uKHBhdGgsICJSZWxhdGl2ZSBwYXRoIik7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdCdWlsZGVyIHVyaSA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGlmIChzY2hlbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgdXJpLmFwcGVuZChzY2hlbWUpOworICAgICAgICAgICAgdXJpLmFwcGVuZCgnOicpOworICAgICAgICB9CisgICAgICAgIGlmIChhdXRob3JpdHkgIT0gbnVsbCkgeworICAgICAgICAgICAgdXJpLmFwcGVuZCgiLy8iKTsKKyAgICAgICAgICAgIEFVVEhPUklUWV9FTkNPREVSLmFwcGVuZEVuY29kZWQodXJpLCBhdXRob3JpdHkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHBhdGggIT0gbnVsbCkgeworICAgICAgICAgICAgUEFUSF9FTkNPREVSLmFwcGVuZEVuY29kZWQodXJpLCBwYXRoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocXVlcnkgIT0gbnVsbCkgeworICAgICAgICAgICAgdXJpLmFwcGVuZCgnPycpOworICAgICAgICAgICAgQUxMX0xFR0FMX0VOQ09ERVIuYXBwZW5kRW5jb2RlZCh1cmksIHF1ZXJ5KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZnJhZ21lbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgdXJpLmFwcGVuZCgnIycpOworICAgICAgICAgICAgQUxMX0xFR0FMX0VOQ09ERVIuYXBwZW5kRW5jb2RlZCh1cmksIGZyYWdtZW50KTsKKyAgICAgICAgfQorCisgICAgICAgIHBhcnNlVVJJKHVyaS50b1N0cmluZygpLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQnJlYWtzIHVyaSBpbnRvIGl0cyBjb21wb25lbnQgcGFydHMuIFRoaXMgZmlyc3Qgc3BsaXRzIFVSSSBpbnRvIHNjaGVtZSwKKyAgICAgKiBzY2hlbWUtc3BlY2lmaWMgcGFydCBhbmQgZnJhZ21lbnQ6CisgICAgICogICBbc2NoZW1lOl1bc2NoZW1lLXNwZWNpZmljIHBhcnRdWyNmcmFnbWVudF0KKyAgICAgKgorICAgICAqIFRoZW4gaXQgYnJlYWtzIHRoZSBzY2hlbWUtc3BlY2lmaWMgcGFydCBpbnRvIGF1dGhvcml0eSwgcGF0aCBhbmQgcXVlcnk6CisgICAgICogICBbLy9hdXRob3JpdHldW3BhdGhdWz9xdWVyeV0KKyAgICAgKgorICAgICAqIEZpbmFsbHkgaXQgZGVsZWdhdGVzIHRvIHBhcnNlQXV0aG9yaXR5IHRvIGJyZWFrIHRoZSBhdXRob3JpdHkgaW50byB1c2VyCisgICAgICogaW5mbywgaG9zdCBhbmQgcG9ydDoKKyAgICAgKiAgIFt1c2VyLWluZm9AXVtob3N0XVs6cG9ydF0KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcGFyc2VVUkkoU3RyaW5nIHVyaSwgYm9vbGVhbiBmb3JjZVNlcnZlcikgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIHN0cmluZyA9IHVyaTsKKworICAgICAgICAvLyAiI2ZyYWdtZW50IgorICAgICAgICBpbnQgZnJhZ21lbnRTdGFydCA9IFVybFV0aWxzLmZpbmRGaXJzdE9mKHVyaSwgIiMiLCAwLCB1cmkubGVuZ3RoKCkpOworICAgICAgICBpZiAoZnJhZ21lbnRTdGFydCA8IHVyaS5sZW5ndGgoKSkgeworICAgICAgICAgICAgZnJhZ21lbnQgPSBBTExfTEVHQUxfRU5DT0RFUi52YWxpZGF0ZSh1cmksIGZyYWdtZW50U3RhcnQgKyAxLCB1cmkubGVuZ3RoKCksICJmcmFnbWVudCIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gc2NoZW1lOgorICAgICAgICBpbnQgc3RhcnQ7CisgICAgICAgIGludCBjb2xvbiA9IFVybFV0aWxzLmZpbmRGaXJzdE9mKHVyaSwgIjoiLCAwLCBmcmFnbWVudFN0YXJ0KTsKKyAgICAgICAgaWYgKGNvbG9uIDwgVXJsVXRpbHMuZmluZEZpcnN0T2YodXJpLCAiLz8jIiwgMCwgZnJhZ21lbnRTdGFydCkpIHsKKyAgICAgICAgICAgIGFic29sdXRlID0gdHJ1ZTsKKyAgICAgICAgICAgIHNjaGVtZSA9IHZhbGlkYXRlU2NoZW1lKHVyaSwgY29sb24pOworICAgICAgICAgICAgc3RhcnQgPSBjb2xvbiArIDE7CisKKyAgICAgICAgICAgIGlmIChzdGFydCA9PSBmcmFnbWVudFN0YXJ0KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVSSVN5bnRheEV4Y2VwdGlvbih1cmksICJTY2hlbWUtc3BlY2lmaWMgcGFydCBleHBlY3RlZCIsIHN0YXJ0KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gVVJJcyB3aXRoIHNjaGVtZXMgZm9sbG93ZWQgYnkgYSBub24tLyBjaGFyIGFyZSBvcGFxdWUgYW5kIG5lZWQgbm8gZnVydGhlciBwYXJzaW5nLgorICAgICAgICAgICAgaWYgKCF1cmkucmVnaW9uTWF0Y2hlcyhzdGFydCwgIi8iLCAwLCAxKSkgeworICAgICAgICAgICAgICAgIG9wYXF1ZSA9IHRydWU7CisgICAgICAgICAgICAgICAgc2NoZW1lU3BlY2lmaWNQYXJ0ID0gQUxMX0xFR0FMX0VOQ09ERVIudmFsaWRhdGUoCisgICAgICAgICAgICAgICAgICAgICAgICB1cmksIHN0YXJ0LCBmcmFnbWVudFN0YXJ0LCAic2NoZW1lIHNwZWNpZmljIHBhcnQiKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBhYnNvbHV0ZSA9IGZhbHNlOworICAgICAgICAgICAgc3RhcnQgPSAwOworICAgICAgICB9CisKKyAgICAgICAgb3BhcXVlID0gZmFsc2U7CisgICAgICAgIHNjaGVtZVNwZWNpZmljUGFydCA9IHVyaS5zdWJzdHJpbmcoc3RhcnQsIGZyYWdtZW50U3RhcnQpOworCisgICAgICAgIC8vICIvL2F1dGhvcml0eSIKKyAgICAgICAgaW50IGZpbGVTdGFydDsKKyAgICAgICAgaWYgKHVyaS5yZWdpb25NYXRjaGVzKHN0YXJ0LCAiLy8iLCAwLCAyKSkgeworICAgICAgICAgICAgaW50IGF1dGhvcml0eVN0YXJ0ID0gc3RhcnQgKyAyOworICAgICAgICAgICAgZmlsZVN0YXJ0ID0gVXJsVXRpbHMuZmluZEZpcnN0T2YodXJpLCAiLz8iLCBhdXRob3JpdHlTdGFydCwgZnJhZ21lbnRTdGFydCk7CisgICAgICAgICAgICBpZiAoYXV0aG9yaXR5U3RhcnQgPT0gdXJpLmxlbmd0aCgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVSSVN5bnRheEV4Y2VwdGlvbih1cmksICJBdXRob3JpdHkgZXhwZWN0ZWQiLCB1cmkubGVuZ3RoKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGF1dGhvcml0eVN0YXJ0IDwgZmlsZVN0YXJ0KSB7CisgICAgICAgICAgICAgICAgYXV0aG9yaXR5ID0gQVVUSE9SSVRZX0VOQ09ERVIudmFsaWRhdGUodXJpLCBhdXRob3JpdHlTdGFydCwgZmlsZVN0YXJ0LCAiYXV0aG9yaXR5Iik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmaWxlU3RhcnQgPSBzdGFydDsKKyAgICAgICAgfQorCisgICAgICAgIC8vICJwYXRoIgorICAgICAgICBpbnQgcXVlcnlTdGFydCA9IFVybFV0aWxzLmZpbmRGaXJzdE9mKHVyaSwgIj8iLCBmaWxlU3RhcnQsIGZyYWdtZW50U3RhcnQpOworICAgICAgICBwYXRoID0gUEFUSF9FTkNPREVSLnZhbGlkYXRlKHVyaSwgZmlsZVN0YXJ0LCBxdWVyeVN0YXJ0LCAicGF0aCIpOworCisgICAgICAgIC8vICI/cXVlcnkiCisgICAgICAgIGlmIChxdWVyeVN0YXJ0IDwgZnJhZ21lbnRTdGFydCkgeworICAgICAgICAgICAgcXVlcnkgPSBBTExfTEVHQUxfRU5DT0RFUi52YWxpZGF0ZSh1cmksIHF1ZXJ5U3RhcnQgKyAxLCBmcmFnbWVudFN0YXJ0LCAicXVlcnkiKTsKKyAgICAgICAgfQorCisgICAgICAgIHBhcnNlQXV0aG9yaXR5KGZvcmNlU2VydmVyKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyB2YWxpZGF0ZVNjaGVtZShTdHJpbmcgdXJpLCBpbnQgZW5kKSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGVuZCA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVVJJU3ludGF4RXhjZXB0aW9uKHVyaSwgIlNjaGVtZSBleHBlY3RlZCIsIDApOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbmQ7IGkrKykgeworICAgICAgICAgICAgaWYgKCFVcmxVdGlscy5pc1ZhbGlkU2NoZW1lQ2hhcihpLCB1cmkuY2hhckF0KGkpKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBVUklTeW50YXhFeGNlcHRpb24odXJpLCAiSWxsZWdhbCBjaGFyYWN0ZXIgaW4gc2NoZW1lIiwgMCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gdXJpLnN1YnN0cmluZygwLCBlbmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEJyZWFrcyB0aGlzIFVSSSdzIGF1dGhvcml0eSBpbnRvIHVzZXIgaW5mbywgaG9zdCBhbmQgcG9ydCBwYXJ0cy4KKyAgICAgKiAgIFt1c2VyLWluZm9AXVtob3N0XVs6cG9ydF0KKyAgICAgKiBJZiBhbnkgcGFydCBvZiB0aGlzIGZhaWxzIHRoaXMgbWV0aG9kIHdpbGwgZ2l2ZSB1cCBhbmQgcG90ZW50aWFsbHkgbGVhdmUKKyAgICAgKiB0aGVzZSBmaWVsZHMgd2l0aCB0aGVpciBkZWZhdWx0IHZhbHVlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmb3JjZVNlcnZlciB0cnVlIHRvIGFsd2F5cyB0aHJvdyBpZiB0aGUgYXV0aG9yaXR5IGNhbm5vdCBiZQorICAgICAqICAgICBwYXJzZWQuIElmIGZhbHNlLCB0aGlzIG1ldGhvZCBtYXkgc3RpbGwgdGhyb3cgZm9yIHNvbWUga2luZHMgb2YKKyAgICAgKiAgICAgZXJyb3JzOyB0aGlzIHVucHJlZGljdGFibGUgYmVoYXZpb3IgaXMgY29uc2lzdGVudCB3aXRoIHRoZSBSSS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcGFyc2VBdXRob3JpdHkoYm9vbGVhbiBmb3JjZVNlcnZlcikgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhdXRob3JpdHkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIHRlbXBVc2VySW5mbyA9IG51bGw7CisgICAgICAgIFN0cmluZyB0ZW1wID0gYXV0aG9yaXR5OworICAgICAgICBpbnQgaW5kZXggPSB0ZW1wLmluZGV4T2YoJ0AnKTsKKyAgICAgICAgaW50IGhvc3RJbmRleCA9IDA7CisgICAgICAgIGlmIChpbmRleCAhPSAtMSkgeworICAgICAgICAgICAgLy8gcmVtb3ZlIHVzZXIgaW5mbworICAgICAgICAgICAgdGVtcFVzZXJJbmZvID0gdGVtcC5zdWJzdHJpbmcoMCwgaW5kZXgpOworICAgICAgICAgICAgdmFsaWRhdGVVc2VySW5mbyhhdXRob3JpdHksIHRlbXBVc2VySW5mbywgMCk7CisgICAgICAgICAgICB0ZW1wID0gdGVtcC5zdWJzdHJpbmcoaW5kZXggKyAxKTsgLy8gaG9zdFs6cG9ydF0gaXMgbGVmdAorICAgICAgICAgICAgaG9zdEluZGV4ID0gaW5kZXggKyAxOworICAgICAgICB9CisKKyAgICAgICAgaW5kZXggPSB0ZW1wLmxhc3RJbmRleE9mKCc6Jyk7CisgICAgICAgIGludCBlbmRJbmRleCA9IHRlbXAuaW5kZXhPZignXScpOworCisgICAgICAgIFN0cmluZyB0ZW1wSG9zdDsKKyAgICAgICAgaW50IHRlbXBQb3J0ID0gLTE7CisgICAgICAgIGlmIChpbmRleCAhPSAtMSAmJiBlbmRJbmRleCA8IGluZGV4KSB7CisgICAgICAgICAgICAvLyBkZXRlcm1pbmUgcG9ydCBhbmQgaG9zdAorICAgICAgICAgICAgdGVtcEhvc3QgPSB0ZW1wLnN1YnN0cmluZygwLCBpbmRleCk7CisKKyAgICAgICAgICAgIGlmIChpbmRleCA8ICh0ZW1wLmxlbmd0aCgpIC0gMSkpIHsgLy8gcG9ydCBwYXJ0IGlzIG5vdCBlbXB0eQorICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHRlbXBQb3J0ID0gSW50ZWdlci5wYXJzZUludCh0ZW1wLnN1YnN0cmluZyhpbmRleCArIDEpKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXBQb3J0IDwgMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvcmNlU2VydmVyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVSSVN5bnRheEV4Y2VwdGlvbihhdXRob3JpdHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCBwb3J0IG51bWJlciIsIGhvc3RJbmRleCArIGluZGV4ICsgMSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBpZiAoZm9yY2VTZXJ2ZXIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBVUklTeW50YXhFeGNlcHRpb24oYXV0aG9yaXR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCBwb3J0IG51bWJlciIsIGhvc3RJbmRleCArIGluZGV4ICsgMSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRlbXBIb3N0ID0gdGVtcDsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh0ZW1wSG9zdC5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIGlmIChmb3JjZVNlcnZlcikgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBVUklTeW50YXhFeGNlcHRpb24oYXV0aG9yaXR5LCAiRXhwZWN0ZWQgaG9zdCIsIGhvc3RJbmRleCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWlzVmFsaWRIb3N0KGZvcmNlU2VydmVyLCB0ZW1wSG9zdCkpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRoaXMgaXMgYSBzZXJ2ZXIgYmFzZWQgdXJpLAorICAgICAgICAvLyBmaWxsIGluIHRoZSB1c2VySW5mbywgaG9zdCBhbmQgcG9ydCBmaWVsZHMKKyAgICAgICAgdXNlckluZm8gPSB0ZW1wVXNlckluZm87CisgICAgICAgIGhvc3QgPSB0ZW1wSG9zdDsKKyAgICAgICAgcG9ydCA9IHRlbXBQb3J0OworICAgICAgICBzZXJ2ZXJBdXRob3JpdHkgPSB0cnVlOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB2YWxpZGF0ZVVzZXJJbmZvKFN0cmluZyB1cmksIFN0cmluZyB1c2VySW5mbywgaW50IGluZGV4KQorICAgICAgICAgICAgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdXNlckluZm8ubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgY2hhciBjaCA9IHVzZXJJbmZvLmNoYXJBdChpKTsKKyAgICAgICAgICAgIGlmIChjaCA9PSAnXScgfHwgY2ggPT0gJ1snKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVSSVN5bnRheEV4Y2VwdGlvbih1cmksICJJbGxlZ2FsIGNoYXJhY3RlciBpbiB1c2VySW5mbyIsIGluZGV4ICsgaSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYge0Bjb2RlIGhvc3R9IGlzIGEgd2VsbC1mb3JtZWQgaG9zdCBuYW1lIG9yIElQIGFkZHJlc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9yY2VTZXJ2ZXIgdHJ1ZSB0byBhbHdheXMgdGhyb3cgaWYgdGhlIGhvc3QgY2Fubm90IGJlIHBhcnNlZC4gSWYKKyAgICAgKiAgICAgZmFsc2UsIHRoaXMgbWV0aG9kIG1heSBzdGlsbCB0aHJvdyBmb3Igc29tZSBraW5kcyBvZiBlcnJvcnM7IHRoaXMKKyAgICAgKiAgICAgdW5wcmVkaWN0YWJsZSBiZWhhdmlvciBpcyBjb25zaXN0ZW50IHdpdGggdGhlIFJJLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpc1ZhbGlkSG9zdChib29sZWFuIGZvcmNlU2VydmVyLCBTdHJpbmcgaG9zdCkgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChob3N0LnN0YXJ0c1dpdGgoIlsiKSkgeworICAgICAgICAgICAgLy8gSVB2NiBhZGRyZXNzCisgICAgICAgICAgICBpZiAoIWhvc3QuZW5kc1dpdGgoIl0iKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBVUklTeW50YXhFeGNlcHRpb24oaG9zdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICJFeHBlY3RlZCBhIGNsb3Npbmcgc3F1YXJlIGJyYWNrZXQgZm9yIElQdjYgYWRkcmVzcyIsIDApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKEluZXRBZGRyZXNzLmlzTnVtZXJpYyhob3N0KSkgeworICAgICAgICAgICAgICAgIC8vIElmIGl0J3MgbnVtZXJpYywgdGhlIHByZXNlbmNlIG9mIHNxdWFyZSBicmFja2V0cyBndWFyYW50ZWVzCisgICAgICAgICAgICAgICAgLy8gdGhhdCBpdCdzIGEgbnVtZXJpYyBJUHY2IGFkZHJlc3MuCisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aHJvdyBuZXcgVVJJU3ludGF4RXhjZXB0aW9uKGhvc3QsICJNYWxmb3JtZWQgSVB2NiBhZGRyZXNzIik7CisgICAgICAgIH0KKworICAgICAgICAvLyAnWycgYW5kICddJyBjYW4gb25seSBiZSB0aGUgZmlyc3QgY2hhciBhbmQgbGFzdCBjaGFyCisgICAgICAgIC8vIG9mIHRoZSBob3N0IG5hbWUKKyAgICAgICAgaWYgKGhvc3QuaW5kZXhPZignWycpICE9IC0xIHx8IGhvc3QuaW5kZXhPZignXScpICE9IC0xKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVVJJU3ludGF4RXhjZXB0aW9uKGhvc3QsICJJbGxlZ2FsIGNoYXJhY3RlciBpbiBob3N0IG5hbWUiLCAwKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBpbmRleCA9IGhvc3QubGFzdEluZGV4T2YoJy4nKTsKKyAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA9PSBob3N0Lmxlbmd0aCgpIC0gMQorICAgICAgICAgICAgICAgIHx8ICFDaGFyYWN0ZXIuaXNEaWdpdChob3N0LmNoYXJBdChpbmRleCArIDEpKSkgeworICAgICAgICAgICAgLy8gZG9tYWluIG5hbWUKKyAgICAgICAgICAgIGlmIChpc1ZhbGlkRG9tYWluTmFtZShob3N0KSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGZvcmNlU2VydmVyKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVSSVN5bnRheEV4Y2VwdGlvbihob3N0LCAiSWxsZWdhbCBjaGFyYWN0ZXIgaW4gaG9zdCBuYW1lIiwgMCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICAvLyBJUHY0IGFkZHJlc3M/CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbmV0QWRkcmVzcyBpYSA9IEluZXRBZGRyZXNzLnBhcnNlTnVtZXJpY0FkZHJlc3MoaG9zdCk7CisgICAgICAgICAgICBpZiAoaWEgaW5zdGFuY2VvZiBJbmV0NEFkZHJlc3MpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChmb3JjZVNlcnZlcikgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVSSVN5bnRheEV4Y2VwdGlvbihob3N0LCAiTWFsZm9ybWVkIElQdjQgYWRkcmVzcyIsIDApOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNWYWxpZERvbWFpbk5hbWUoU3RyaW5nIGhvc3QpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFVyaUNvZGVjLnZhbGlkYXRlU2ltcGxlKGhvc3QsICItLiIpOworICAgICAgICB9IGNhdGNoIChVUklTeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGxhc3RMYWJlbCA9IG51bGw7CisgICAgICAgIGZvciAoU3RyaW5nIHRva2VuIDogaG9zdC5zcGxpdCgiXFwuIikpIHsKKyAgICAgICAgICAgIGxhc3RMYWJlbCA9IHRva2VuOworICAgICAgICAgICAgaWYgKGxhc3RMYWJlbC5zdGFydHNXaXRoKCItIikgfHwgbGFzdExhYmVsLmVuZHNXaXRoKCItIikpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAobGFzdExhYmVsID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghbGFzdExhYmVsLmVxdWFscyhob3N0KSkgeworICAgICAgICAgICAgY2hhciBjaCA9IGxhc3RMYWJlbC5jaGFyQXQoMCk7CisgICAgICAgICAgICBpZiAoY2ggPj0gJzAnICYmIGNoIDw9ICc5JykgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIFVSSSB3aXRoIHRoZSBnaXZlbiBhcmd1bWVudCB7QGNvZGUgdXJpfS4gVGhpcyBtZXRob2Qgd2lsbAorICAgICAqIHJldHVybiBhIG5lZ2F0aXZlIHZhbHVlIGlmIHRoaXMgVVJJIGluc3RhbmNlIGlzIGxlc3MgdGhhbiB0aGUgZ2l2ZW4KKyAgICAgKiBhcmd1bWVudCBhbmQgYSBwb3NpdGl2ZSB2YWx1ZSBpZiB0aGlzIFVSSSBpbnN0YW5jZSBpcyBncmVhdGVyIHRoYW4gdGhlCisgICAgICogZ2l2ZW4gYXJndW1lbnQuIFRoZSByZXR1cm4gdmFsdWUge0Bjb2RlIDB9IGluZGljYXRlcyB0aGF0IHRoZSB0d28KKyAgICAgKiBpbnN0YW5jZXMgcmVwcmVzZW50IHRoZSBzYW1lIFVSSS4gVG8gZGVmaW5lIHRoZSBvcmRlciB0aGUgc2luZ2xlIHBhcnRzIG9mCisgICAgICogdGhlIFVSSSBhcmUgY29tcGFyZWQgd2l0aCBlYWNoIG90aGVyLiBTdHJpbmcgY29tcG9uZW50cyB3aWxsIGJlIG9yZGVyZWQKKyAgICAgKiBpbiB0aGUgbmF0dXJhbCBjYXNlLXNlbnNpdGl2ZSB3YXkuIEEgaGllcmFyY2hpY2FsIFVSSSBpcyBsZXNzIHRoYW4gYW4KKyAgICAgKiBvcGFxdWUgVVJJIGFuZCBpZiBvbmUgcGFydCBpcyB7QGNvZGUgbnVsbH0gdGhlIFVSSSB3aXRoIHRoZSB1bmRlZmluZWQKKyAgICAgKiBwYXJ0IGlzIGxlc3MgdGhhbiB0aGUgb3RoZXIgb25lLgorICAgICAqCisgICAgICogQHBhcmFtIHVyaQorICAgICAqICAgICAgICAgICAgdGhlIFVSSSB0aGlzIGluc3RhbmNlIGhhcyB0byBjb21wYXJlIHdpdGguCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBvcmRlciBvZiB0aGUgdHdvIGluc3RhbmNlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhVUkkgdXJpKSB7CisgICAgICAgIGludCByZXQ7CisKKyAgICAgICAgLy8gY29tcGFyZSBzY2hlbWVzCisgICAgICAgIGlmIChzY2hlbWUgPT0gbnVsbCAmJiB1cmkuc2NoZW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfSBlbHNlIGlmIChzY2hlbWUgIT0gbnVsbCAmJiB1cmkuc2NoZW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9IGVsc2UgaWYgKHNjaGVtZSAhPSBudWxsICYmIHVyaS5zY2hlbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0ID0gc2NoZW1lLmNvbXBhcmVUb0lnbm9yZUNhc2UodXJpLnNjaGVtZSk7CisgICAgICAgICAgICBpZiAocmV0ICE9IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmV0OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gY29tcGFyZSBvcGFjaXRpZXMKKyAgICAgICAgaWYgKCFvcGFxdWUgJiYgdXJpLm9wYXF1ZSkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9IGVsc2UgaWYgKG9wYXF1ZSAmJiAhdXJpLm9wYXF1ZSkgeworICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIH0gZWxzZSBpZiAob3BhcXVlICYmIHVyaS5vcGFxdWUpIHsKKyAgICAgICAgICAgIHJldCA9IHNjaGVtZVNwZWNpZmljUGFydC5jb21wYXJlVG8odXJpLnNjaGVtZVNwZWNpZmljUGFydCk7CisgICAgICAgICAgICBpZiAocmV0ICE9IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmV0OworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworCisgICAgICAgICAgICAvLyBvdGhlcndpc2UgYm90aCBtdXN0IGJlIGhpZXJhcmNoaWNhbAorCisgICAgICAgICAgICAvLyBjb21wYXJlIGF1dGhvcml0aWVzCisgICAgICAgICAgICBpZiAoYXV0aG9yaXR5ICE9IG51bGwgJiYgdXJpLmF1dGhvcml0eSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGF1dGhvcml0eSA9PSBudWxsICYmIHVyaS5hdXRob3JpdHkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoYXV0aG9yaXR5ICE9IG51bGwgJiYgdXJpLmF1dGhvcml0eSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWYgKGhvc3QgIT0gbnVsbCAmJiB1cmkuaG9zdCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGJvdGggYXJlIHNlcnZlciBiYXNlZCwgc28gY29tcGFyZSB1c2VySW5mbywgaG9zdCwgcG9ydAorICAgICAgICAgICAgICAgICAgICBpZiAodXNlckluZm8gIT0gbnVsbCAmJiB1cmkudXNlckluZm8gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodXNlckluZm8gPT0gbnVsbCAmJiB1cmkudXNlckluZm8gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHVzZXJJbmZvICE9IG51bGwgJiYgdXJpLnVzZXJJbmZvICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IHVzZXJJbmZvLmNvbXBhcmVUbyh1cmkudXNlckluZm8pOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJldCAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldDsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vIHVzZXJJbmZvJ3MgYXJlIHRoZSBzYW1lLCBjb21wYXJlIGhvc3RuYW1lCisgICAgICAgICAgICAgICAgICAgIHJldCA9IGhvc3QuY29tcGFyZVRvSWdub3JlQ2FzZSh1cmkuaG9zdCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChyZXQgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldDsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vIGNvbXBhcmUgcG9ydAorICAgICAgICAgICAgICAgICAgICBpZiAocG9ydCAhPSB1cmkucG9ydCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBvcnQgLSB1cmkucG9ydDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIG9uZSBvciBib3RoIGFyZSByZWdpc3RyeSBiYXNlZCwgY29tcGFyZSB0aGUgd2hvbGUKKyAgICAgICAgICAgICAgICAgICAgLy8gYXV0aG9yaXR5CisgICAgICAgICAgICAgICAgICAgIHJldCA9IGF1dGhvcml0eS5jb21wYXJlVG8odXJpLmF1dGhvcml0eSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChyZXQgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gYXV0aG9yaXRpZXMgYXJlIHRoZSBzYW1lCisgICAgICAgICAgICAvLyBjb21wYXJlIHBhdGhzCisgICAgICAgICAgICByZXQgPSBwYXRoLmNvbXBhcmVUbyh1cmkucGF0aCk7CisgICAgICAgICAgICBpZiAocmV0ICE9IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmV0OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBjb21wYXJlIHF1ZXJpZXMKKworICAgICAgICAgICAgaWYgKHF1ZXJ5ICE9IG51bGwgJiYgdXJpLnF1ZXJ5ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAocXVlcnkgPT0gbnVsbCAmJiB1cmkucXVlcnkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAocXVlcnkgIT0gbnVsbCAmJiB1cmkucXVlcnkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldCA9IHF1ZXJ5LmNvbXBhcmVUbyh1cmkucXVlcnkpOworICAgICAgICAgICAgICAgIGlmIChyZXQgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIGV2ZXJ5dGhpbmcgZWxzZSBpcyBpZGVudGljYWwsIHNvIGNvbXBhcmUgZnJhZ21lbnRzCisgICAgICAgIGlmIChmcmFnbWVudCAhPSBudWxsICYmIHVyaS5mcmFnbWVudCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfSBlbHNlIGlmIChmcmFnbWVudCA9PSBudWxsICYmIHVyaS5mcmFnbWVudCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0gZWxzZSBpZiAoZnJhZ21lbnQgIT0gbnVsbCAmJiB1cmkuZnJhZ21lbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0ID0gZnJhZ21lbnQuY29tcGFyZVRvKHVyaS5mcmFnbWVudCk7CisgICAgICAgICAgICBpZiAocmV0ICE9IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmV0OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gaWRlbnRpY2FsCisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIFVSSSBmb3JtZWQgYnkgcGFyc2luZyB7QGNvZGUgdXJpfS4gVGhpcyBtZXRob2QgYmVoYXZlcworICAgICAqIGlkZW50aWNhbGx5IHRvIHRoZSBzdHJpbmcgY29uc3RydWN0b3IgYnV0IHRocm93cyBhIGRpZmZlcmVudCBleGNlcHRpb24KKyAgICAgKiBvbiBmYWlsdXJlLiBUaGUgY29uc3RydWN0b3IgZmFpbHMgd2l0aCBhIGNoZWNrZWQge0BsaW5rCisgICAgICogVVJJU3ludGF4RXhjZXB0aW9ufTsgdGhpcyBtZXRob2QgZmFpbHMgd2l0aCBhbiB1bmNoZWNrZWQge0BsaW5rCisgICAgICogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFVSSSBjcmVhdGUoU3RyaW5nIHVyaSkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBVUkkodXJpKTsKKyAgICAgICAgfSBjYXRjaCAoVVJJU3ludGF4RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBVUkkgZHVwbGljYXRlKCkgeworICAgICAgICBVUkkgY2xvbmUgPSBuZXcgVVJJKCk7CisgICAgICAgIGNsb25lLmFic29sdXRlID0gYWJzb2x1dGU7CisgICAgICAgIGNsb25lLmF1dGhvcml0eSA9IGF1dGhvcml0eTsKKyAgICAgICAgY2xvbmUuZnJhZ21lbnQgPSBmcmFnbWVudDsKKyAgICAgICAgY2xvbmUuaG9zdCA9IGhvc3Q7CisgICAgICAgIGNsb25lLm9wYXF1ZSA9IG9wYXF1ZTsKKyAgICAgICAgY2xvbmUucGF0aCA9IHBhdGg7CisgICAgICAgIGNsb25lLnBvcnQgPSBwb3J0OworICAgICAgICBjbG9uZS5xdWVyeSA9IHF1ZXJ5OworICAgICAgICBjbG9uZS5zY2hlbWUgPSBzY2hlbWU7CisgICAgICAgIGNsb25lLnNjaGVtZVNwZWNpZmljUGFydCA9IHNjaGVtZVNwZWNpZmljUGFydDsKKyAgICAgICAgY2xvbmUudXNlckluZm8gPSB1c2VySW5mbzsKKyAgICAgICAgY2xvbmUuc2VydmVyQXV0aG9yaXR5ID0gc2VydmVyQXV0aG9yaXR5OworICAgICAgICByZXR1cm4gY2xvbmU7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUYWtlcyBhIHN0cmluZyB0aGF0IG1heSBjb250YWluIGhleCBzZXF1ZW5jZXMgbGlrZSAlRjEgb3IgJTJiIGFuZAorICAgICAqIGNvbnZlcnRzIHRoZSBoZXggdmFsdWVzIGZvbGxvd2luZyB0aGUgJyUnIHRvIGxvd2VyY2FzZQorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGNvbnZlcnRIZXhUb0xvd2VyQ2FzZShTdHJpbmcgcykgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKCIiKTsKKyAgICAgICAgaWYgKHMuaW5kZXhPZignJScpID09IC0xKSB7CisgICAgICAgICAgICByZXR1cm4gczsKKyAgICAgICAgfQorCisgICAgICAgIGludCBpbmRleCwgcHJldkluZGV4ID0gMDsKKyAgICAgICAgd2hpbGUgKChpbmRleCA9IHMuaW5kZXhPZignJScsIHByZXZJbmRleCkpICE9IC0xKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHMuc3Vic3RyaW5nKHByZXZJbmRleCwgaW5kZXggKyAxKSk7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHMuc3Vic3RyaW5nKGluZGV4ICsgMSwgaW5kZXggKyAzKS50b0xvd2VyQ2FzZShMb2NhbGUuVVMpKTsKKyAgICAgICAgICAgIGluZGV4ICs9IDM7CisgICAgICAgICAgICBwcmV2SW5kZXggPSBpbmRleDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHtAY29kZSBmaXJzdH0gYW5kIHtAY29kZSBzZWNvbmR9IGFyZSBlcXVhbCBhZnRlcgorICAgICAqIHVuZXNjYXBpbmcgaGV4IHNlcXVlbmNlcyBsaWtlICVGMSBhbmQgJTJiLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBlc2NhcGVkRXF1YWxzKFN0cmluZyBmaXJzdCwgU3RyaW5nIHNlY29uZCkgeworICAgICAgICBpZiAoZmlyc3QuaW5kZXhPZignJScpICE9IHNlY29uZC5pbmRleE9mKCclJykpIHsKKyAgICAgICAgICAgIHJldHVybiBmaXJzdC5lcXVhbHMoc2Vjb25kKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBpbmRleCwgcHJldkluZGV4ID0gMDsKKyAgICAgICAgd2hpbGUgKChpbmRleCA9IGZpcnN0LmluZGV4T2YoJyUnLCBwcmV2SW5kZXgpKSAhPSAtMQorICAgICAgICAgICAgICAgICYmIHNlY29uZC5pbmRleE9mKCclJywgcHJldkluZGV4KSA9PSBpbmRleCkgeworICAgICAgICAgICAgYm9vbGVhbiBtYXRjaCA9IGZpcnN0LnN1YnN0cmluZyhwcmV2SW5kZXgsIGluZGV4KS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgIHNlY29uZC5zdWJzdHJpbmcocHJldkluZGV4LCBpbmRleCkpOworICAgICAgICAgICAgaWYgKCFtYXRjaCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgbWF0Y2ggPSBmaXJzdC5zdWJzdHJpbmcoaW5kZXggKyAxLCBpbmRleCArIDMpLmVxdWFsc0lnbm9yZUNhc2UoCisgICAgICAgICAgICAgICAgICAgIHNlY29uZC5zdWJzdHJpbmcoaW5kZXggKyAxLCBpbmRleCArIDMpKTsKKyAgICAgICAgICAgIGlmICghbWF0Y2gpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGluZGV4ICs9IDM7CisgICAgICAgICAgICBwcmV2SW5kZXggPSBpbmRleDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmlyc3Quc3Vic3RyaW5nKHByZXZJbmRleCkuZXF1YWxzKHNlY29uZC5zdWJzdHJpbmcocHJldkluZGV4KSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICBpZiAoIShvIGluc3RhbmNlb2YgVVJJKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIFVSSSB1cmkgPSAoVVJJKSBvOworCisgICAgICAgIGlmICh1cmkuZnJhZ21lbnQgPT0gbnVsbCAmJiBmcmFnbWVudCAhPSBudWxsIHx8IHVyaS5mcmFnbWVudCAhPSBudWxsCisgICAgICAgICAgICAgICAgJiYgZnJhZ21lbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9IGVsc2UgaWYgKHVyaS5mcmFnbWVudCAhPSBudWxsICYmIGZyYWdtZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmICghZXNjYXBlZEVxdWFscyh1cmkuZnJhZ21lbnQsIGZyYWdtZW50KSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmICh1cmkuc2NoZW1lID09IG51bGwgJiYgc2NoZW1lICE9IG51bGwgfHwgdXJpLnNjaGVtZSAhPSBudWxsCisgICAgICAgICAgICAgICAgJiYgc2NoZW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfSBlbHNlIGlmICh1cmkuc2NoZW1lICE9IG51bGwgJiYgc2NoZW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmICghdXJpLnNjaGVtZS5lcXVhbHNJZ25vcmVDYXNlKHNjaGVtZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAodXJpLm9wYXF1ZSAmJiBvcGFxdWUpIHsKKyAgICAgICAgICAgIHJldHVybiBlc2NhcGVkRXF1YWxzKHVyaS5zY2hlbWVTcGVjaWZpY1BhcnQsCisgICAgICAgICAgICAgICAgICAgIHNjaGVtZVNwZWNpZmljUGFydCk7CisgICAgICAgIH0gZWxzZSBpZiAoIXVyaS5vcGFxdWUgJiYgIW9wYXF1ZSkgeworICAgICAgICAgICAgaWYgKCFlc2NhcGVkRXF1YWxzKHBhdGgsIHVyaS5wYXRoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHVyaS5xdWVyeSAhPSBudWxsICYmIHF1ZXJ5ID09IG51bGwgfHwgdXJpLnF1ZXJ5ID09IG51bGwKKyAgICAgICAgICAgICAgICAgICAgJiYgcXVlcnkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodXJpLnF1ZXJ5ICE9IG51bGwgJiYgcXVlcnkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmICghZXNjYXBlZEVxdWFscyh1cmkucXVlcnksIHF1ZXJ5KSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAodXJpLmF1dGhvcml0eSAhPSBudWxsICYmIGF1dGhvcml0eSA9PSBudWxsCisgICAgICAgICAgICAgICAgICAgIHx8IHVyaS5hdXRob3JpdHkgPT0gbnVsbCAmJiBhdXRob3JpdHkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodXJpLmF1dGhvcml0eSAhPSBudWxsICYmIGF1dGhvcml0eSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWYgKHVyaS5ob3N0ICE9IG51bGwgJiYgaG9zdCA9PSBudWxsIHx8IHVyaS5ob3N0ID09IG51bGwKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIGhvc3QgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh1cmkuaG9zdCA9PSBudWxsICYmIGhvc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAvLyBib3RoIGFyZSByZWdpc3RyeSBiYXNlZCwgc28gY29tcGFyZSB0aGUgd2hvbGUgYXV0aG9yaXR5CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBlc2NhcGVkRXF1YWxzKHVyaS5hdXRob3JpdHksIGF1dGhvcml0eSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gdXJpLmhvc3QgIT0gbnVsbCAmJiBob3N0ICE9IG51bGwsIHNvIHNlcnZlci1iYXNlZAorICAgICAgICAgICAgICAgICAgICBpZiAoIWhvc3QuZXF1YWxzSWdub3JlQ2FzZSh1cmkuaG9zdCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGlmIChwb3J0ICE9IHVyaS5wb3J0KSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBpZiAodXJpLnVzZXJJbmZvICE9IG51bGwgJiYgdXNlckluZm8gPT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHVyaS51c2VySW5mbyA9PSBudWxsICYmIHVzZXJJbmZvICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh1cmkudXNlckluZm8gIT0gbnVsbCAmJiB1c2VySW5mbyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXNjYXBlZEVxdWFscyh1c2VySW5mbywgdXJpLnVzZXJJbmZvKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBubyBhdXRob3JpdHkKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gb25lIGlzIG9wYXF1ZSwgdGhlIG90aGVyIGhpZXJhcmNoaWNhbAorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2NoZW1lIG9mIHRoaXMgVVJJLCBvciBudWxsIGlmIHRoaXMgVVJJIGhhcyBubyBzY2hlbWUuIFRoaXMKKyAgICAgKiBpcyBhbHNvIGtub3duIGFzIHRoZSBwcm90b2NvbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFNjaGVtZSgpIHsKKyAgICAgICAgcmV0dXJuIHNjaGVtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWNvZGVkIHNjaGVtZS1zcGVjaWZpYyBwYXJ0IG9mIHRoaXMgVVJJLCBvciBudWxsIGlmIHRoaXMgVVJJCisgICAgICogaGFzIG5vIHNjaGVtZS1zcGVjaWZpYyBwYXJ0LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2NoZW1lU3BlY2lmaWNQYXJ0KCkgeworICAgICAgICByZXR1cm4gZGVjb2RlKHNjaGVtZVNwZWNpZmljUGFydCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5jb2RlZCBzY2hlbWUtc3BlY2lmaWMgcGFydCBvZiB0aGlzIFVSSSwgb3IgbnVsbCBpZiB0aGlzIFVSSQorICAgICAqIGhhcyBubyBzY2hlbWUtc3BlY2lmaWMgcGFydC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFJhd1NjaGVtZVNwZWNpZmljUGFydCgpIHsKKyAgICAgICAgcmV0dXJuIHNjaGVtZVNwZWNpZmljUGFydDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWNvZGVkIGF1dGhvcml0eSBwYXJ0IG9mIHRoaXMgVVJJLCBvciBudWxsIGlmIHRoaXMgVVJJIGhhcworICAgICAqIG5vIGF1dGhvcml0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEF1dGhvcml0eSgpIHsKKyAgICAgICAgcmV0dXJuIGRlY29kZShhdXRob3JpdHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGVuY29kZWQgYXV0aG9yaXR5IG9mIHRoaXMgVVJJLCBvciBudWxsIGlmIHRoaXMgVVJJIGhhcyBubworICAgICAqIGF1dGhvcml0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFJhd0F1dGhvcml0eSgpIHsKKyAgICAgICAgcmV0dXJuIGF1dGhvcml0eTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWNvZGVkIHVzZXIgaW5mbyBvZiB0aGlzIFVSSSwgb3IgbnVsbCBpZiB0aGlzIFVSSSBoYXMgbm8KKyAgICAgKiB1c2VyIGluZm8uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRVc2VySW5mbygpIHsKKyAgICAgICAgcmV0dXJuIGRlY29kZSh1c2VySW5mbyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5jb2RlZCB1c2VyIGluZm8gb2YgdGhpcyBVUkksIG9yIG51bGwgaWYgdGhpcyBVUkkgaGFzIG5vCisgICAgICogdXNlciBpbmZvLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UmF3VXNlckluZm8oKSB7CisgICAgICAgIHJldHVybiB1c2VySW5mbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBob3N0IG9mIHRoaXMgVVJJLCBvciBudWxsIGlmIHRoaXMgVVJJIGhhcyBubyBob3N0LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0SG9zdCgpIHsKKyAgICAgICAgcmV0dXJuIGhvc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcG9ydCBudW1iZXIgb2YgdGhpcyBVUkksIG9yIHtAY29kZSAtMX0gaWYgdGhpcyBVUkkgaGFzIG5vCisgICAgICogZXhwbGljaXQgcG9ydC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFBvcnQoKSB7CisgICAgICAgIHJldHVybiBwb3J0OworICAgIH0KKworICAgIC8qKiBAaGlkZSAqLworICAgIHB1YmxpYyBpbnQgZ2V0RWZmZWN0aXZlUG9ydCgpIHsKKyAgICAgICAgcmV0dXJuIGdldEVmZmVjdGl2ZVBvcnQoc2NoZW1lLCBwb3J0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwb3J0IHRvIHVzZSBmb3Ige0Bjb2RlIHNjaGVtZX0gY29ubmVjdGlvbnMgd2lsbCB1c2Ugd2hlbgorICAgICAqIHtAbGluayAjZ2V0UG9ydH0gcmV0dXJucyB7QGNvZGUgc3BlY2lmaWVkUG9ydH0uCisgICAgICoKKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldEVmZmVjdGl2ZVBvcnQoU3RyaW5nIHNjaGVtZSwgaW50IHNwZWNpZmllZFBvcnQpIHsKKyAgICAgICAgaWYgKHNwZWNpZmllZFBvcnQgIT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiBzcGVjaWZpZWRQb3J0OworICAgICAgICB9CisKKyAgICAgICAgaWYgKCJodHRwIi5lcXVhbHNJZ25vcmVDYXNlKHNjaGVtZSkpIHsKKyAgICAgICAgICAgIHJldHVybiA4MDsKKyAgICAgICAgfSBlbHNlIGlmICgiaHR0cHMiLmVxdWFsc0lnbm9yZUNhc2Uoc2NoZW1lKSkgeworICAgICAgICAgICAgcmV0dXJuIDQ0MzsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRlY29kZWQgcGF0aCBvZiB0aGlzIFVSSSwgb3IgbnVsbCBpZiB0aGlzIFVSSSBoYXMgbm8gcGF0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFBhdGgoKSB7CisgICAgICAgIHJldHVybiBkZWNvZGUocGF0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5jb2RlZCBwYXRoIG9mIHRoaXMgVVJJLCBvciBudWxsIGlmIHRoaXMgVVJJIGhhcyBubyBwYXRoLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UmF3UGF0aCgpIHsKKyAgICAgICAgcmV0dXJuIHBhdGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGVjb2RlZCBxdWVyeSBvZiB0aGlzIFVSSSwgb3IgbnVsbCBpZiB0aGlzIFVSSSBoYXMgbm8gcXVlcnkuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRRdWVyeSgpIHsKKyAgICAgICAgcmV0dXJuIGRlY29kZShxdWVyeSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5jb2RlZCBxdWVyeSBvZiB0aGlzIFVSSSwgb3IgbnVsbCBpZiB0aGlzIFVSSSBoYXMgbm8gcXVlcnkuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRSYXdRdWVyeSgpIHsKKyAgICAgICAgcmV0dXJuIHF1ZXJ5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRlY29kZWQgZnJhZ21lbnQgb2YgdGhpcyBVUkksIG9yIG51bGwgaWYgdGhpcyBVUkkgaGFzIG5vCisgICAgICogZnJhZ21lbnQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRGcmFnbWVudCgpIHsKKyAgICAgICAgcmV0dXJuIGRlY29kZShmcmFnbWVudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZW5jb2RlZCBmcmFnbWVudCBvZiB0aGlzIFVSSSwgb3IgbnVsbCBpZiB0aGlzIFVSSSBoYXMgbm8KKyAgICAgKiBmcmFnbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFJhd0ZyYWdtZW50KCkgeworICAgICAgICByZXR1cm4gZnJhZ21lbnQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGlmIChoYXNoID09IC0xKSB7CisgICAgICAgICAgICBoYXNoID0gZ2V0SGFzaFN0cmluZygpLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGhhc2g7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgVVJJIGlzIGFic29sdXRlLCB3aGljaCBtZWFucyB0aGF0IGEgc2NoZW1lIGlzCisgICAgICogZGVmaW5lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0Fic29sdXRlKCkgeworICAgICAgICAvLyBUT0RPOiBzaW1wbGlmeSB0byAnc2NoZW1lICE9IG51bGwnID8KKyAgICAgICAgcmV0dXJuIGFic29sdXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIFVSSSBpcyBvcGFxdWUuIE9wYXF1ZSBVUklzIGFyZSBhYnNvbHV0ZSBhbmQgaGF2ZSBhCisgICAgICogc2NoZW1lLXNwZWNpZmljIHBhcnQgdGhhdCBkb2VzIG5vdCBzdGFydCB3aXRoIGEgc2xhc2ggY2hhcmFjdGVyLiBBbGwKKyAgICAgKiBwYXJ0cyBleGNlcHQgc2NoZW1lLCBzY2hlbWUtc3BlY2lmaWMgYW5kIGZyYWdtZW50IGFyZSB1bmRlZmluZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNPcGFxdWUoKSB7CisgICAgICAgIHJldHVybiBvcGFxdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbm9ybWFsaXplZCBwYXRoLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIG5vcm1hbGl6ZShTdHJpbmcgcGF0aCwgYm9vbGVhbiBkaXNjYXJkUmVsYXRpdmVQcmVmaXgpIHsKKyAgICAgICAgcGF0aCA9IFVybFV0aWxzLmNhbm9uaWNhbGl6ZVBhdGgocGF0aCwgZGlzY2FyZFJlbGF0aXZlUHJlZml4KTsKKworICAgICAgICAvKgorICAgICAgICAgKiBJZiB0aGUgcGF0aCBjb250YWlucyBhIGNvbG9uIGJlZm9yZSB0aGUgZmlyc3QgY29sb24sIHByZXBlbmQKKyAgICAgICAgICogIi4vIiB0byBkaWZmZXJlbnRpYXRlIHRoZSBwYXRoIGZyb20gYSBzY2hlbWUgcHJlZml4LgorICAgICAgICAgKi8KKyAgICAgICAgaW50IGNvbG9uID0gcGF0aC5pbmRleE9mKCc6Jyk7CisgICAgICAgIGlmIChjb2xvbiAhPSAtMSkgeworICAgICAgICAgICAgaW50IHNsYXNoID0gcGF0aC5pbmRleE9mKCcvJyk7CisgICAgICAgICAgICBpZiAoc2xhc2ggPT0gLTEgfHwgY29sb24gPCBzbGFzaCkgeworICAgICAgICAgICAgICAgIHBhdGggPSAiLi8iICsgcGF0aDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBwYXRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIE5vcm1hbGl6ZXMgdGhlIHBhdGggcGFydCBvZiB0aGlzIFVSSS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gVVJJIG9iamVjdCB3aGljaCByZXByZXNlbnRzIHRoaXMgaW5zdGFuY2Ugd2l0aCBhIG5vcm1hbGl6ZWQKKyAgICAgKiAgICAgICAgIHBhdGguCisgICAgICovCisgICAgcHVibGljIFVSSSBub3JtYWxpemUoKSB7CisgICAgICAgIGlmIChvcGFxdWUpIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBub3JtYWxpemVkUGF0aCA9IG5vcm1hbGl6ZShwYXRoLCBmYWxzZSk7CisgICAgICAgIC8vIGlmIHRoZSBwYXRoIGlzIGFscmVhZHkgbm9ybWFsaXplZCwgcmV0dXJuIHRoaXMKKyAgICAgICAgaWYgKHBhdGguZXF1YWxzKG5vcm1hbGl6ZWRQYXRoKSkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKyAgICAgICAgLy8gZ2V0IGFuIGV4YWN0IGNvcHkgb2YgdGhlIFVSSSByZS1jYWxjdWxhdGUgdGhlIHNjaGVtZSBzcGVjaWZpYyBwYXJ0CisgICAgICAgIC8vIHNpbmNlIHRoZSBwYXRoIG9mIHRoZSBub3JtYWxpemVkIFVSSSBpcyBkaWZmZXJlbnQgZnJvbSB0aGlzIFVSSS4KKyAgICAgICAgVVJJIHJlc3VsdCA9IGR1cGxpY2F0ZSgpOworICAgICAgICByZXN1bHQucGF0aCA9IG5vcm1hbGl6ZWRQYXRoOworICAgICAgICByZXN1bHQuc2V0U2NoZW1lU3BlY2lmaWNQYXJ0KCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJpZXMgdG8gcGFyc2UgdGhlIGF1dGhvcml0eSBjb21wb25lbnQgb2YgdGhpcyBVUkkgdG8gZGl2aWRlIGl0IGludG8gdGhlCisgICAgICogaG9zdCwgcG9ydCwgYW5kIHVzZXItaW5mby4gSWYgdGhpcyBVUkkgaXMgYWxyZWFkeSBkZXRlcm1pbmVkIGFzIGEKKyAgICAgKiBTZXJ2ZXJBdXRob3JpdHkgdGhpcyBpbnN0YW5jZSB3aWxsIGJlIHJldHVybmVkIHdpdGhvdXQgY2hhbmdlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBpbnN0YW5jZSB3aXRoIHRoZSBjb21wb25lbnRzIG9mIHRoZSBwYXJzZWQgc2VydmVyIGF1dGhvcml0eS4KKyAgICAgKiBAdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhdXRob3JpdHkgcGFydCBjb3VsZCBub3QgYmUgcGFyc2VkIGFzIGEgc2VydmVyLWJhc2VkCisgICAgICogICAgICAgICAgICAgYXV0aG9yaXR5LgorICAgICAqLworICAgIHB1YmxpYyBVUkkgcGFyc2VTZXJ2ZXJBdXRob3JpdHkoKSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFzZXJ2ZXJBdXRob3JpdHkpIHsKKyAgICAgICAgICAgIHBhcnNlQXV0aG9yaXR5KHRydWUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1ha2VzIHRoZSBnaXZlbiBVUkkge0Bjb2RlIHJlbGF0aXZlfSB0byBhIHJlbGF0aXZlIFVSSSBhZ2FpbnN0IHRoZSBVUkkKKyAgICAgKiByZXByZXNlbnRlZCBieSB0aGlzIGluc3RhbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIHJlbGF0aXZlCisgICAgICogICAgICAgICAgICB0aGUgVVJJIHdoaWNoIGhhcyB0byBiZSByZWxhdGl2aXplZCBhZ2FpbnN0IHRoaXMgVVJJLgorICAgICAqIEByZXR1cm4gdGhlIHJlbGF0aXZlIFVSSS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJJIHJlbGF0aXZpemUoVVJJIHJlbGF0aXZlKSB7CisgICAgICAgIGlmIChyZWxhdGl2ZS5vcGFxdWUgfHwgb3BhcXVlKSB7CisgICAgICAgICAgICByZXR1cm4gcmVsYXRpdmU7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc2NoZW1lID09IG51bGwgPyByZWxhdGl2ZS5zY2hlbWUgIT0gbnVsbCA6ICFzY2hlbWUKKyAgICAgICAgICAgICAgICAuZXF1YWxzKHJlbGF0aXZlLnNjaGVtZSkpIHsKKyAgICAgICAgICAgIHJldHVybiByZWxhdGl2ZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChhdXRob3JpdHkgPT0gbnVsbCA/IHJlbGF0aXZlLmF1dGhvcml0eSAhPSBudWxsIDogIWF1dGhvcml0eQorICAgICAgICAgICAgICAgIC5lcXVhbHMocmVsYXRpdmUuYXV0aG9yaXR5KSkgeworICAgICAgICAgICAgcmV0dXJuIHJlbGF0aXZlOworICAgICAgICB9CisKKyAgICAgICAgLy8gbm9ybWFsaXplIGJvdGggcGF0aHMKKyAgICAgICAgU3RyaW5nIHRoaXNQYXRoID0gbm9ybWFsaXplKHBhdGgsIGZhbHNlKTsKKyAgICAgICAgU3RyaW5nIHJlbGF0aXZlUGF0aCA9IG5vcm1hbGl6ZShyZWxhdGl2ZS5wYXRoLCBmYWxzZSk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogaWYgdGhlIHBhdGhzIGFyZW4ndCBlcXVhbCwgdGhlbiB3ZSBuZWVkIHRvIGRldGVybWluZSBpZiB0aGlzIFVSSSdzCisgICAgICAgICAqIHBhdGggaXMgYSBwYXJlbnQgcGF0aCAoYmVnaW5zIHdpdGgpIHRoZSByZWxhdGl2ZSBVUkkncyBwYXRoCisgICAgICAgICAqLworICAgICAgICBpZiAoIXRoaXNQYXRoLmVxdWFscyhyZWxhdGl2ZVBhdGgpKSB7CisgICAgICAgICAgICAvLyBkcm9wIGV2ZXJ5dGhpbmcgYWZ0ZXIgdGhlIGxhc3Qgc2xhc2ggaW4gdGhpcyBwYXRoCisgICAgICAgICAgICB0aGlzUGF0aCA9IHRoaXNQYXRoLnN1YnN0cmluZygwLCB0aGlzUGF0aC5sYXN0SW5kZXhPZignLycpICsgMSk7CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBpZiB0aGUgcmVsYXRpdmUgVVJJJ3MgcGF0aCBkb2Vzbid0IHN0YXJ0IHdpdGggdGhpcyBVUkkncyBwYXRoLAorICAgICAgICAgICAgICogdGhlbiBqdXN0IHJldHVybiB0aGUgcmVsYXRpdmUgVVJJOyB0aGUgVVJJcyBoYXZlIG5vdGhpbmcgaW4KKyAgICAgICAgICAgICAqIGNvbW1vbgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAoIXJlbGF0aXZlUGF0aC5zdGFydHNXaXRoKHRoaXNQYXRoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiByZWxhdGl2ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFVSSSByZXN1bHQgPSBuZXcgVVJJKCk7CisgICAgICAgIHJlc3VsdC5mcmFnbWVudCA9IHJlbGF0aXZlLmZyYWdtZW50OworICAgICAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTsKKyAgICAgICAgLy8gdGhlIHJlc3VsdCBVUkkgaXMgdGhlIHJlbWFpbmRlciBvZiB0aGUgcmVsYXRpdmUgVVJJJ3MgcGF0aAorICAgICAgICByZXN1bHQucGF0aCA9IHJlbGF0aXZlUGF0aC5zdWJzdHJpbmcodGhpc1BhdGgubGVuZ3RoKCkpOworICAgICAgICByZXN1bHQuc2V0U2NoZW1lU3BlY2lmaWNQYXJ0KCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzb2x2ZXMgdGhlIGdpdmVuIFVSSSB7QGNvZGUgcmVsYXRpdmV9IGFnYWluc3QgdGhlIFVSSSByZXByZXNlbnRlZCBieQorICAgICAqIHRoaXMgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVsYXRpdmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBVUkkgd2hpY2ggaGFzIHRvIGJlIHJlc29sdmVkIGFnYWluc3QgdGhpcyBVUkkuCisgICAgICogQHJldHVybiB0aGUgcmVzb2x2ZWQgVVJJLgorICAgICAqLworICAgIHB1YmxpYyBVUkkgcmVzb2x2ZShVUkkgcmVsYXRpdmUpIHsKKyAgICAgICAgaWYgKHJlbGF0aXZlLmFic29sdXRlIHx8IG9wYXF1ZSkgeworICAgICAgICAgICAgcmV0dXJuIHJlbGF0aXZlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHJlbGF0aXZlLmF1dGhvcml0eSAhPSBudWxsKSB7CisgICAgICAgICAgICAvLyBJZiB0aGUgcmVsYXRpdmUgVVJJIGhhcyBhbiBhdXRob3JpdHksIHRoZSByZXN1bHQgaXMgdGhlIHJlbGF0aXZlCisgICAgICAgICAgICAvLyB3aXRoIHRoaXMgVVJJJ3Mgc2NoZW1lLgorICAgICAgICAgICAgVVJJIHJlc3VsdCA9IHJlbGF0aXZlLmR1cGxpY2F0ZSgpOworICAgICAgICAgICAgcmVzdWx0LnNjaGVtZSA9IHNjaGVtZTsKKyAgICAgICAgICAgIHJlc3VsdC5hYnNvbHV0ZSA9IGFic29sdXRlOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChyZWxhdGl2ZS5wYXRoLmlzRW1wdHkoKSAmJiByZWxhdGl2ZS5zY2hlbWUgPT0gbnVsbCAmJiByZWxhdGl2ZS5xdWVyeSA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBpZiB0aGUgcmVsYXRpdmUgVVJJIG9ubHkgY29uc2lzdHMgb2YgYXQgbW9zdCBhIGZyYWdtZW50LAorICAgICAgICAgICAgVVJJIHJlc3VsdCA9IGR1cGxpY2F0ZSgpOworICAgICAgICAgICAgcmVzdWx0LmZyYWdtZW50ID0gcmVsYXRpdmUuZnJhZ21lbnQ7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgVVJJIHJlc3VsdCA9IGR1cGxpY2F0ZSgpOworICAgICAgICByZXN1bHQuZnJhZ21lbnQgPSByZWxhdGl2ZS5mcmFnbWVudDsKKyAgICAgICAgcmVzdWx0LnF1ZXJ5ID0gcmVsYXRpdmUucXVlcnk7CisgICAgICAgIFN0cmluZyByZXNvbHZlZFBhdGg7CisgICAgICAgIGlmIChyZWxhdGl2ZS5wYXRoLnN0YXJ0c1dpdGgoIi8iKSkgeworICAgICAgICAgICAgLy8gVGhlIHJlbGF0aXZlIFVSSSBoYXMgYW4gYWJzb2x1dGUgcGF0aDsgdXNlIGl0LgorICAgICAgICAgICAgcmVzb2x2ZWRQYXRoID0gcmVsYXRpdmUucGF0aDsKKyAgICAgICAgfSBlbHNlIGlmIChyZWxhdGl2ZS5wYXRoLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgLy8gVGhlIHJlbGF0aXZlIFVSSSBoYXMgbm8gcGF0aDsgdXNlIHRoZSBiYXNlIHBhdGguCisgICAgICAgICAgICByZXNvbHZlZFBhdGggPSBwYXRoOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gVGhlIHJlbGF0aXZlIFVSSSBoYXMgYSByZWxhdGl2ZSBwYXRoOyBjb21iaW5lIHRoZSBwYXRocy4KKyAgICAgICAgICAgIGludCBlbmRJbmRleCA9IHBhdGgubGFzdEluZGV4T2YoJy8nKSArIDE7CisgICAgICAgICAgICByZXNvbHZlZFBhdGggPSBwYXRoLnN1YnN0cmluZygwLCBlbmRJbmRleCkgKyByZWxhdGl2ZS5wYXRoOworICAgICAgICB9CisgICAgICAgIHJlc3VsdC5wYXRoID0gVXJsVXRpbHMuYXV0aG9yaXR5U2FmZVBhdGgocmVzdWx0LmF1dGhvcml0eSwgbm9ybWFsaXplKHJlc29sdmVkUGF0aCwgdHJ1ZSkpOworICAgICAgICByZXN1bHQuc2V0U2NoZW1lU3BlY2lmaWNQYXJ0KCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogSGVscGVyIG1ldGhvZCB1c2VkIHRvIHJlLWNhbGN1bGF0ZSB0aGUgc2NoZW1lIHNwZWNpZmljIHBhcnQgb2YgdGhlCisgICAgICogcmVzb2x2ZWQgb3Igbm9ybWFsaXplZCBVUklzCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNldFNjaGVtZVNwZWNpZmljUGFydCgpIHsKKyAgICAgICAgLy8gc3NwID0gWy8vYXV0aG9yaXR5XVtwYXRoXVs/cXVlcnldCisgICAgICAgIFN0cmluZ0J1aWxkZXIgc3NwID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgaWYgKGF1dGhvcml0eSAhPSBudWxsKSB7CisgICAgICAgICAgICBzc3AuYXBwZW5kKCIvLyIgKyBhdXRob3JpdHkpOworICAgICAgICB9CisgICAgICAgIGlmIChwYXRoICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNzcC5hcHBlbmQocGF0aCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHF1ZXJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNzcC5hcHBlbmQoIj8iICsgcXVlcnkpOworICAgICAgICB9CisgICAgICAgIHNjaGVtZVNwZWNpZmljUGFydCA9IHNzcC50b1N0cmluZygpOworICAgICAgICAvLyByZXNldCBzdHJpbmcsIHNvIHRoYXQgaXQgY2FuIGJlIHJlLWNhbGN1bGF0ZWQgY29ycmVjdGx5IHdoZW4gYXNrZWQuCisgICAgICAgIHN0cmluZyA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBVUkkgaW5zdGFuY2UgYnkgcGFyc2luZyB0aGUgZ2l2ZW4gc3RyaW5nIHtAY29kZSByZWxhdGl2ZX0KKyAgICAgKiBhbmQgcmVzb2x2ZXMgdGhlIGNyZWF0ZWQgVVJJIGFnYWluc3QgdGhlIFVSSSByZXByZXNlbnRlZCBieSB0aGlzCisgICAgICogaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVsYXRpdmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBnaXZlbiBzdHJpbmcgdG8gY3JlYXRlIHRoZSBuZXcgVVJJIGluc3RhbmNlIHdoaWNoIGhhcyB0bworICAgICAqICAgICAgICAgICAgYmUgcmVzb2x2ZWQgbGF0ZXIgb24uCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCBhbmQgcmVzb2x2ZWQgVVJJLgorICAgICAqLworICAgIHB1YmxpYyBVUkkgcmVzb2x2ZShTdHJpbmcgcmVsYXRpdmUpIHsKKyAgICAgICAgcmV0dXJuIHJlc29sdmUoY3JlYXRlKHJlbGF0aXZlKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgZGVjb2RlKFN0cmluZyBzKSB7CisgICAgICAgIHJldHVybiBzICE9IG51bGwgPyBVcmlDb2RlYy5kZWNvZGUocykgOiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRleHR1YWwgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgVVJJIGluc3RhbmNlIHVzaW5nIHRoZQorICAgICAqIFVTLUFTQ0lJIGVuY29kaW5nLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgVVMtQVNDSUkgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgVVJJLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9BU0NJSVN0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBBU0NJSV9PTkxZLmFwcGVuZEVuY29kZWQocmVzdWx0LCB0b1N0cmluZygpKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGVuY29kZWQgVVJJLgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBpZiAoc3RyaW5nICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBzdHJpbmc7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGlmIChzY2hlbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChzY2hlbWUpOworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnOicpOworICAgICAgICB9CisgICAgICAgIGlmIChvcGFxdWUpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoc2NoZW1lU3BlY2lmaWNQYXJ0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChhdXRob3JpdHkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIi8vIik7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChhdXRob3JpdHkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAocGF0aCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChwYXRoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHF1ZXJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCc/Jyk7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChxdWVyeSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoZnJhZ21lbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnIycpOworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChmcmFnbWVudCk7CisgICAgICAgIH0KKworICAgICAgICBzdHJpbmcgPSByZXN1bHQudG9TdHJpbmcoKTsKKyAgICAgICAgcmV0dXJuIHN0cmluZzsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEZvcm0gYSBzdHJpbmcgZnJvbSB0aGUgY29tcG9uZW50cyBvZiB0aGlzIFVSSSwgc2ltaWxhcmx5IHRvIHRoZQorICAgICAqIHRvU3RyaW5nKCkgbWV0aG9kLiBCdXQgdGhpcyBtZXRob2QgY29udmVydHMgc2NoZW1lIGFuZCBob3N0IHRvIGxvd2VyY2FzZSwKKyAgICAgKiBhbmQgY29udmVydHMgZXNjYXBlZCBvY3RldHMgdG8gbG93ZXJjYXNlLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGdldEhhc2hTdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgaWYgKHNjaGVtZSAhPSBudWxsKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHNjaGVtZS50b0xvd2VyQ2FzZShMb2NhbGUuVVMpKTsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJzonKTsKKyAgICAgICAgfQorICAgICAgICBpZiAob3BhcXVlKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHNjaGVtZVNwZWNpZmljUGFydCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoYXV0aG9yaXR5ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCIvLyIpOworICAgICAgICAgICAgICAgIGlmIChob3N0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChhdXRob3JpdHkpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlmICh1c2VySW5mbyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHVzZXJJbmZvICsgIkAiKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGhvc3QudG9Mb3dlckNhc2UoTG9jYWxlLlVTKSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChwb3J0ICE9IC0xKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCI6IiArIHBvcnQpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAocGF0aCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChwYXRoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHF1ZXJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCc/Jyk7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChxdWVyeSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoZnJhZ21lbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnIycpOworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChmcmFnbWVudCk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gY29udmVydEhleFRvTG93ZXJDYXNlKHJlc3VsdC50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyB0aGlzIFVSSSBpbnN0YW5jZSB0byBhIFVSTC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgVVJMIHJlcHJlc2VudGluZyB0aGUgc2FtZSByZXNvdXJjZSBhcyB0aGlzIFVSSS4KKyAgICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjcmVhdGluZyB0aGUgVVJMIG9yIG5vIHByb3RvY29sCisgICAgICogICAgICAgICAgICAgaGFuZGxlciBjb3VsZCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMIHRvVVJMKCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghYWJzb2x1dGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlVSSSBpcyBub3QgYWJzb2x1dGU6ICIgKyB0b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFVSTCh0b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgaW4uZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcnNlVVJJKHN0cmluZywgZmFsc2UpOworICAgICAgICB9IGNhdGNoIChVUklTeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gY2FsbCB0b1N0cmluZygpIHRvIGVuc3VyZSB0aGUgdmFsdWUgb2Ygc3RyaW5nIGZpZWxkIGlzIGNhbGN1bGF0ZWQKKyAgICAgICAgdG9TdHJpbmcoKTsKKyAgICAgICAgb3V0LmRlZmF1bHRXcml0ZU9iamVjdCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9VUklTeW50YXhFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9VUklTeW50YXhFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMDhmNDQ0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1VSSVN5bnRheEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTMxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCisvKioKKyAqIEEge0Bjb2RlIFVSSVN5bnRheEV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gaWYgc29tZSBpbmZvcm1hdGlvbiBjb3VsZCBub3QgYmUgcGFyc2VkCisgKiB3aGlsZSBjcmVhdGluZyBhIFVSSS4KKyAqLworcHVibGljIGNsYXNzIFVSSVN5bnRheEV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAyMTM3OTc5NjgwODk3NDg4ODkxTDsKKworICAgIHByaXZhdGUgU3RyaW5nIGlucHV0OworCisgICAgcHJpdmF0ZSBpbnQgaW5kZXg7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBVUklTeW50YXhFeGNlcHRpb259IGluc3RhbmNlIGNvbnRhaW5pbmcgdGhlCisgICAgICogc3RyaW5nIHRoYXQgY2F1c2VkIHRoZSBleGNlcHRpb24sIGEgZGVzY3JpcHRpb24gb2YgdGhlIHByb2JsZW0gYW5kIHRoZQorICAgICAqIGluZGV4IGF0IHdoaWNoIHRoZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dAorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0aGF0IGNhdXNlZCB0aGUgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSByZWFzb24gd2h5IHRoZSBleGNlcHRpb24gb2NjdXJyZWQuCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIGV4Y2VwdGlvbiBvY2N1cnJlZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgb25lIG9mIHRoZSBhcmd1bWVudHMge0Bjb2RlIGlucHV0fSBvciB7QGNvZGUgcmVhc29ufSBpcworICAgICAqICAgICAgICAgICAgIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB2YWx1ZSBmb3Ige0Bjb2RlIGluZGV4fSBpcyBsZXNzZXIgdGhhbiB7QGNvZGUgLTF9LgorICAgICAqLworICAgIHB1YmxpYyBVUklTeW50YXhFeGNlcHRpb24oU3RyaW5nIGlucHV0LCBTdHJpbmcgcmVhc29uLCBpbnQgaW5kZXgpIHsKKyAgICAgICAgc3VwZXIocmVhc29uKTsKKworICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCB8fCByZWFzb24gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoaW5kZXggPCAtMSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5pbnB1dCA9IGlucHV0OworICAgICAgICB0aGlzLmluZGV4ID0gaW5kZXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVVJJU3ludGF4RXhjZXB0aW9ufSBpbnN0YW5jZSBjb250YWluaW5nIHRoZQorICAgICAqIHN0cmluZyB0aGF0IGNhdXNlZCB0aGUgZXhjZXB0aW9uIGFuZCBhIGRlc2NyaXB0aW9uIG9mIHRoZSBwcm9ibGVtLgorICAgICAqCisgICAgICpAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdGhhdCBjYXVzZWQgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgcmVhc29uIHdoeSB0aGUgZXhjZXB0aW9uIG9jY3VycmVkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBvbmUgb2YgdGhlIGFyZ3VtZW50cyB7QGNvZGUgaW5wdXR9IG9yIHtAY29kZSByZWFzb259IGlzCisgICAgICogICAgICAgICAgICAge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBVUklTeW50YXhFeGNlcHRpb24oU3RyaW5nIGlucHV0LCBTdHJpbmcgcmVhc29uKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbik7CisKKyAgICAgICAgaWYgKGlucHV0ID09IG51bGwgfHwgcmVhc29uID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5pbnB1dCA9IGlucHV0OworICAgICAgICBpbmRleCA9IC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBzeW50YXggZXJyb3Igd2FzIGZvdW5kIG9yIHtAY29kZSAtMX0gaWYgdGhlCisgICAgICogaW5kZXggaXMgdW5rbm93bi91bmF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBzeW50YXggZXJyb3IuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRJbmRleCgpIHsKKyAgICAgICAgcmV0dXJuIGluZGV4OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBkZXNjcmlwdGlvbiBvZiB0aGUgc3ludGF4IGVycm9yLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIHN5bnRheCBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFJlYXNvbigpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmdldE1lc3NhZ2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBpbml0aWFsIHN0cmluZyB0aGF0IGNvbnRhaW5zIGFuIGludmFsaWQgc3ludGF4LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIHRoYXQgY2F1c2VkIHRoZSBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRJbnB1dCgpIHsKKyAgICAgICAgcmV0dXJuIGlucHV0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBkZXNjcmlwdGlvbiBvZiB0aGUgZXhjZXB0aW9uLCBpbmNsdWRpbmcgdGhlIHJlYXNvbiwgdGhlIHN0cmluZworICAgICAqIHRoYXQgY2F1c2VkIHRoZSBzeW50YXggZXJyb3IgYW5kIHRoZSBwb3NpdGlvbiBvZiB0aGUgc3ludGF4IGVycm9yIGlmCisgICAgICogYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHJldHVybiBhIHN0aW5nIGNvbnRhaW5pbmcgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5UaHJvd2FibGUjZ2V0TWVzc2FnZSgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkgeworICAgICAgICBTdHJpbmcgcmVhc29uID0gc3VwZXIuZ2V0TWVzc2FnZSgpOworICAgICAgICBpZiAoaW5kZXggIT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiByZWFzb24gKyAiIGF0IGluZGV4ICIgKyBpbmRleCArICI6ICIgKyBpbnB1dDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVhc29uICsgIjogIiArIGlucHV0OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9VUkwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9VUkwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMjVkMjIzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1VSTC5qYXZhCkBAIC0wLDAgKzEsNjY3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuamFyLkphckZpbGU7CitpbXBvcnQgbGliY29yZS5uZXQuaHR0cC5IdHRwSGFuZGxlcjsKK2ltcG9ydCBsaWJjb3JlLm5ldC5odHRwLkh0dHBzSGFuZGxlcjsKK2ltcG9ydCBsaWJjb3JlLm5ldC51cmwuRmlsZUhhbmRsZXI7CitpbXBvcnQgbGliY29yZS5uZXQudXJsLkZ0cEhhbmRsZXI7CitpbXBvcnQgbGliY29yZS5uZXQudXJsLkphckhhbmRsZXI7CitpbXBvcnQgbGliY29yZS5uZXQudXJsLlVybFV0aWxzOworCisvKioKKyAqIEEgVW5pZm9ybSBSZXNvdXJjZSBMb2NhdG9yIHRoYXQgaWRlbnRpZmllcyB0aGUgbG9jYXRpb24gb2YgYW4gSW50ZXJuZXQKKyAqIHJlc291cmNlIGFzIHNwZWNpZmllZCBieSA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMxNzM4LnR4dCI+UkZDCisgKiAxNzM4PC9hPi4KKyAqCisgKiA8aDM+UGFydHMgb2YgYSBVUkw8L2gzPgorICogQSBVUkwgaXMgY29tcG9zZWQgb2YgbWFueSBwYXJ0cy4gVGhpcyBjbGFzcyBjYW4gYm90aCBwYXJzZSBVUkwgc3RyaW5ncyBpbnRvCisgKiBwYXJ0cyBhbmQgY29tcG9zZSBVUkwgc3RyaW5ncyBmcm9tIHBhcnRzLiBGb3IgZXhhbXBsZSwgY29uc2lkZXIgdGhlIHBhcnRzIG9mCisgKiB0aGlzIFVSTDoKKyAqIHtAY29kZSBodHRwOi8vdXNlcm5hbWU6cGFzc3dvcmRAaG9zdDo4MDgwL2RpcmVjdG9yeS9maWxlP3F1ZXJ5I3JlZn06CisgKiA8dGFibGU+CisgKiA8dHI+PHRoPkNvbXBvbmVudDwvdGg+PHRoPkV4YW1wbGUgdmFsdWU8L3RoPjx0aD5BbHNvIGtub3duIGFzPC90aD48L3RyPgorICogPHRyPjx0ZD57QGxpbmsgI2dldFByb3RvY29sKCkgUHJvdG9jb2x9PC90ZD48dGQ+e0Bjb2RlIGh0dHB9PC90ZD48dGQ+c2NoZW1lPC90ZD48L3RyPgorICogPHRyPjx0ZD57QGxpbmsgI2dldEF1dGhvcml0eSgpIEF1dGhvcml0eX08L3RkPjx0ZD57QGNvZGUgdXNlcm5hbWU6cGFzc3dvcmRAaG9zdDo4MDgwfTwvdGQ+PHRkPjwvdGQ+PC90cj4KKyAqIDx0cj48dGQ+e0BsaW5rICNnZXRVc2VySW5mbygpIFVzZXIgSW5mb308L3RkPjx0ZD57QGNvZGUgdXNlcm5hbWU6cGFzc3dvcmR9PC90ZD48dGQ+PC90ZD48L3RyPgorICogPHRyPjx0ZD57QGxpbmsgI2dldEhvc3QoKSBIb3N0fTwvdGQ+PHRkPntAY29kZSBob3N0fTwvdGQ+PHRkPjwvdGQ+PC90cj4KKyAqIDx0cj48dGQ+e0BsaW5rICNnZXRQb3J0KCkgUG9ydH08L3RkPjx0ZD57QGNvZGUgODA4MH08L3RkPjx0ZD48L3RkPjwvdHI+CisgKiA8dHI+PHRkPntAbGluayAjZ2V0RmlsZSgpIEZpbGV9PC90ZD48dGQ+e0Bjb2RlIC9kaXJlY3RvcnkvZmlsZT9xdWVyeX08L3RkPjx0ZD48L3RkPjwvdHI+CisgKiA8dHI+PHRkPntAbGluayAjZ2V0UGF0aCgpIFBhdGh9PC90ZD48dGQ+e0Bjb2RlIC9kaXJlY3RvcnkvZmlsZX08L3RkPjx0ZD48L3RkPjwvdHI+CisgKiA8dHI+PHRkPntAbGluayAjZ2V0UXVlcnkoKSBRdWVyeX08L3RkPjx0ZD57QGNvZGUgcXVlcnl9PC90ZD48dGQ+PC90ZD48L3RyPgorICogPHRyPjx0ZD57QGxpbmsgI2dldFJlZigpIFJlZn08L3RkPjx0ZD57QGNvZGUgcmVmfTwvdGQ+PHRkPmZyYWdtZW50PC90ZD48L3RyPgorICogPC90YWJsZT4KKyAqCisgKiA8aDM+U3VwcG9ydGVkIFByb3RvY29sczwvaDM+CisgKiBUaGlzIGNsYXNzIG1heSBiZSB1c2VkIHRvIGNvbnN0cnVjdCBVUkxzIHdpdGggdGhlIGZvbGxvd2luZyBwcm90b2NvbHM6CisgKiA8dWw+CisgKiA8bGk+PHN0cm9uZz5maWxlPC9zdHJvbmc+OiByZWFkIGZpbGVzIGZyb20gdGhlIGxvY2FsIGZpbGVzeXN0ZW0uCisgKiA8bGk+PHN0cm9uZz5mdHA8L3N0cm9uZz46IDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzk1OS50eHQiPkZpbGUKKyAqICAgICBUcmFuc2ZlciBQcm90b2NvbDwvYT4KKyAqIDxsaT48c3Ryb25nPmh0dHA8L3N0cm9uZz46IDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzI2MTYudHh0Ij5IeXBlcnRleHQKKyAqICAgICBUcmFuc2ZlciBQcm90b2NvbDwvYT4KKyAqIDxsaT48c3Ryb25nPmh0dHBzPC9zdHJvbmc+OiA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyODE4LnR4dCI+SFRUUAorICogICAgIG92ZXIgVExTPC9hPgorICogPGxpPjxzdHJvbmc+amFyPC9zdHJvbmc+OiByZWFkIHtAbGluayBKYXJGaWxlIEphciBmaWxlc30gZnJvbSB0aGUKKyAqICAgICBmaWxlc3lzdGVtPC9saT4KKyAqIDwvdWw+CisgKiBJbiBnZW5lcmFsLCBhdHRlbXB0cyB0byBjcmVhdGUgVVJMcyB3aXRoIGFueSBvdGhlciBwcm90b2NvbCB3aWxsIGZhaWwgd2l0aCBhCisgKiB7QGxpbmsgTWFsZm9ybWVkVVJMRXhjZXB0aW9ufS4gQXBwbGljYXRpb25zIG1heSBpbnN0YWxsIGhhbmRsZXJzIGZvciBvdGhlcgorICogc2NoZW1lcyB1c2luZyB7QGxpbmsgI3NldFVSTFN0cmVhbUhhbmRsZXJGYWN0b3J5fSBvciB3aXRoIHRoZSB7QGNvZGUKKyAqIGphdmEucHJvdG9jb2wuaGFuZGxlci5wa2dzfSBzeXN0ZW0gcHJvcGVydHkuCisgKgorICogPHA+VGhlIHtAbGluayBVUkl9IGNsYXNzIGNhbiBiZSB1c2VkIHRvIG1hbmlwdWxhdGUgVVJMcyBvZiBhbnkgcHJvdG9jb2wuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBVUkwgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03NjI3NjI5Njg4MzYxNTI0MTEwTDsKKworICAgIHByaXZhdGUgc3RhdGljIFVSTFN0cmVhbUhhbmRsZXJGYWN0b3J5IHN0cmVhbUhhbmRsZXJGYWN0b3J5OworCisgICAgLyoqIENhY2hlIG9mIHByb3RvY29scyB0byB0aGVpciBoYW5kbGVycyAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEhhc2h0YWJsZTxTdHJpbmcsIFVSTFN0cmVhbUhhbmRsZXI+IHN0cmVhbUhhbmRsZXJzCisgICAgICAgICAgICA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBVUkxTdHJlYW1IYW5kbGVyPigpOworCisgICAgcHJpdmF0ZSBTdHJpbmcgcHJvdG9jb2w7CisgICAgcHJpdmF0ZSBTdHJpbmcgYXV0aG9yaXR5OworICAgIHByaXZhdGUgU3RyaW5nIGhvc3Q7CisgICAgcHJpdmF0ZSBpbnQgcG9ydCA9IC0xOworICAgIHByaXZhdGUgU3RyaW5nIGZpbGU7CisgICAgcHJpdmF0ZSBTdHJpbmcgcmVmOworCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgU3RyaW5nIHVzZXJJbmZvOworICAgIHByaXZhdGUgdHJhbnNpZW50IFN0cmluZyBwYXRoOworICAgIHByaXZhdGUgdHJhbnNpZW50IFN0cmluZyBxdWVyeTsKKworICAgIHRyYW5zaWVudCBVUkxTdHJlYW1IYW5kbGVyIHN0cmVhbUhhbmRsZXI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY2FjaGVkIGhhc2ggY29kZSwgb3IgMCBpZiBpdCBoYXNuJ3QgYmVlbiBjb21wdXRlZCB5ZXQuIFVubGlrZSB0aGUgUkksCisgICAgICogdGhpcyBpbXBsZW1lbnRhdGlvbidzIGhhc2hDb2RlIGlzIHRyYW5zaWVudCBiZWNhdXNlIHRoZSBoYXNoIGNvZGUgaXMKKyAgICAgKiB1bnNwZWNpZmllZCBhbmQgbWF5IHZhcnkgYmV0d2VlbiBWTXMgb3IgdmVyc2lvbnMuCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IGhhc2hDb2RlOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc3RyZWFtIGhhbmRsZXIgZmFjdG9yeSBmb3IgdGhpcyBWTS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgRXJyb3IgaWYgYSBVUkxTdHJlYW1IYW5kbGVyRmFjdG9yeSBoYXMgYWxyZWFkeSBiZWVuIGluc3RhbGxlZAorICAgICAqICAgICBmb3IgdGhlIGN1cnJlbnQgVk0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRVUkxTdHJlYW1IYW5kbGVyRmFjdG9yeShVUkxTdHJlYW1IYW5kbGVyRmFjdG9yeSBmYWN0b3J5KSB7CisgICAgICAgIGlmIChzdHJlYW1IYW5kbGVyRmFjdG9yeSAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkZhY3RvcnkgYWxyZWFkeSBzZXQiKTsKKyAgICAgICAgfQorICAgICAgICBzdHJlYW1IYW5kbGVycy5jbGVhcigpOworICAgICAgICBzdHJlYW1IYW5kbGVyRmFjdG9yeSA9IGZhY3Rvcnk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBVUkwgaW5zdGFuY2UgYnkgcGFyc2luZyB7QGNvZGUgc3BlY30uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBpZiB7QGNvZGUgc3BlY30gY291bGQgbm90IGJlIHBhcnNlZCBhcyBhCisgICAgICogICAgIFVSTC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMKFN0cmluZyBzcGVjKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcygoVVJMKSBudWxsLCBzcGVjLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IFVSTCBieSByZXNvbHZpbmcge0Bjb2RlIHNwZWN9IHJlbGF0aXZlIHRvIHtAY29kZSBjb250ZXh0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb250ZXh0IHRoZSBVUkwgdG8gd2hpY2gge0Bjb2RlIHNwZWN9IGlzIHJlbGF0aXZlLCBvciBudWxsIGZvcgorICAgICAqICAgICBubyBjb250ZXh0IGluIHdoaWNoIGNhc2Uge0Bjb2RlIHNwZWN9IG11c3QgYmUgYW4gYWJzb2x1dGUgVVJMLgorICAgICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGlmIHtAY29kZSBzcGVjfSBjb3VsZCBub3QgYmUgcGFyc2VkIGFzIGEKKyAgICAgKiAgICAgVVJMIG9yIGhhcyBhbiB1bnN1cHBvcnRlZCBwcm90b2NvbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMKFVSTCBjb250ZXh0LCBTdHJpbmcgc3BlYykgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoY29udGV4dCwgc3BlYywgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBVUkwgYnkgcmVzb2x2aW5nIHtAY29kZSBzcGVjfSByZWxhdGl2ZSB0byB7QGNvZGUgY29udGV4dH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29udGV4dCB0aGUgVVJMIHRvIHdoaWNoIHtAY29kZSBzcGVjfSBpcyByZWxhdGl2ZSwgb3IgbnVsbCBmb3IKKyAgICAgKiAgICAgbm8gY29udGV4dCBpbiB3aGljaCBjYXNlIHtAY29kZSBzcGVjfSBtdXN0IGJlIGFuIGFic29sdXRlIFVSTC4KKyAgICAgKiBAcGFyYW0gaGFuZGxlciB0aGUgc3RyZWFtIGhhbmRsZXIgZm9yIHRoaXMgVVJMLCBvciBudWxsIGZvciB0aGUKKyAgICAgKiAgICAgcHJvdG9jb2wncyBkZWZhdWx0IHN0cmVhbSBoYW5kbGVyLgorICAgICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBzdHJpbmcge0Bjb2RlIHNwZWN9IGNvdWxkIG5vdAorICAgICAqICAgICBiZSBwYXJzZWQgYXMgYSBVUkwgb3IgYW4gaW52YWxpZCBwcm90b2NvbCBoYXMgYmVlbiBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMKFVSTCBjb250ZXh0LCBTdHJpbmcgc3BlYywgVVJMU3RyZWFtSGFuZGxlciBoYW5kbGVyKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNwZWMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSTEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChoYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHN0cmVhbUhhbmRsZXIgPSBoYW5kbGVyOworICAgICAgICB9CisgICAgICAgIHNwZWMgPSBzcGVjLnRyaW0oKTsKKworICAgICAgICBwcm90b2NvbCA9IFVybFV0aWxzLmdldFNjaGVtZVByZWZpeChzcGVjKTsKKyAgICAgICAgaW50IHNjaGVtZVNwZWNpZmljUGFydFN0YXJ0ID0gcHJvdG9jb2wgIT0gbnVsbCA/IChwcm90b2NvbC5sZW5ndGgoKSArIDEpIDogMDsKKworICAgICAgICAvLyBJZiB0aGUgY29udGV4dCBVUkwgaGFzIGEgZGlmZmVyZW50IHByb3RvY29sLCBkaXNjYXJkIGl0IGJlY2F1c2Ugd2UgY2FuJ3QgdXNlIGl0LgorICAgICAgICBpZiAocHJvdG9jb2wgIT0gbnVsbCAmJiBjb250ZXh0ICE9IG51bGwgJiYgIXByb3RvY29sLmVxdWFscyhjb250ZXh0LnByb3RvY29sKSkgeworICAgICAgICAgICAgY29udGV4dCA9IG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvLyBJbmhlcml0IGZyb20gdGhlIGNvbnRleHQgVVJMIGlmIGl0IGV4aXN0cy4KKyAgICAgICAgaWYgKGNvbnRleHQgIT0gbnVsbCkgeworICAgICAgICAgICAgc2V0KGNvbnRleHQucHJvdG9jb2wsIGNvbnRleHQuZ2V0SG9zdCgpLCBjb250ZXh0LmdldFBvcnQoKSwgY29udGV4dC5nZXRBdXRob3JpdHkoKSwKKyAgICAgICAgICAgICAgICAgICAgY29udGV4dC5nZXRVc2VySW5mbygpLCBjb250ZXh0LmdldFBhdGgoKSwgY29udGV4dC5nZXRRdWVyeSgpLAorICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmdldFJlZigpKTsKKyAgICAgICAgICAgIGlmIChzdHJlYW1IYW5kbGVyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzdHJlYW1IYW5kbGVyID0gY29udGV4dC5zdHJlYW1IYW5kbGVyOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKHByb3RvY29sID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUkxFeGNlcHRpb24oIlByb3RvY29sIG5vdCBmb3VuZDogIiArIHNwZWMpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHN0cmVhbUhhbmRsZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgc2V0dXBTdHJlYW1IYW5kbGVyKCk7CisgICAgICAgICAgICBpZiAoc3RyZWFtSGFuZGxlciA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSTEV4Y2VwdGlvbigiVW5rbm93biBwcm90b2NvbDogIiArIHByb3RvY29sKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFBhcnNlIHRoZSBVUkwuIElmIHRoZSBoYW5kbGVyIHRocm93cyBhbnkgZXhjZXB0aW9uLCB0aHJvdyBNYWxmb3JtZWRVUkxFeGNlcHRpb24gaW5zdGVhZC4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0cmVhbUhhbmRsZXIucGFyc2VVUkwodGhpcywgc3BlYywgc2NoZW1lU3BlY2lmaWNQYXJ0U3RhcnQsIHNwZWMubGVuZ3RoKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSTEV4Y2VwdGlvbihlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBVUkwgb2YgdGhlIGdpdmVuIGNvbXBvbmVudCBwYXJ0cy4gVGhlIFVSTCB1c2VzIHRoZQorICAgICAqIHByb3RvY29sJ3MgZGVmYXVsdCBwb3J0LgorICAgICAqCisgICAgICogQHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24gaWYgdGhlIGNvbWJpbmF0aW9uIG9mIGFsbCBhcmd1bWVudHMgZG8gbm90CisgICAgICogICAgIHJlcHJlc2VudCBhIHZhbGlkIFVSTCBvciBpZiB0aGUgcHJvdG9jb2wgaXMgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMKFN0cmluZyBwcm90b2NvbCwgU3RyaW5nIGhvc3QsIFN0cmluZyBmaWxlKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhwcm90b2NvbCwgaG9zdCwgLTEsIGZpbGUsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgVVJMIG9mIHRoZSBnaXZlbiBjb21wb25lbnQgcGFydHMuIFRoZSBVUkwgdXNlcyB0aGUKKyAgICAgKiBwcm90b2NvbCdzIGRlZmF1bHQgcG9ydC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3N0IHRoZSBob3N0IG5hbWUgb3IgSVAgYWRkcmVzcyBvZiB0aGUgbmV3IFVSTC4KKyAgICAgKiBAcGFyYW0gcG9ydCB0aGUgcG9ydCwgb3Ige0Bjb2RlIC0xfSBmb3IgdGhlIHByb3RvY29sJ3MgZGVmYXVsdCBwb3J0LgorICAgICAqIEBwYXJhbSBmaWxlIHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZS4KKyAgICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBpZiB0aGUgY29tYmluYXRpb24gb2YgYWxsIGFyZ3VtZW50cyBkbyBub3QKKyAgICAgKiAgICAgcmVwcmVzZW50IGEgdmFsaWQgVVJMIG9yIGlmIHRoZSBwcm90b2NvbCBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyBVUkwoU3RyaW5nIHByb3RvY29sLCBTdHJpbmcgaG9zdCwgaW50IHBvcnQsIFN0cmluZyBmaWxlKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhwcm90b2NvbCwgaG9zdCwgcG9ydCwgZmlsZSwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBVUkwgb2YgdGhlIGdpdmVuIGNvbXBvbmVudCBwYXJ0cy4gVGhlIFVSTCB1c2VzIHRoZQorICAgICAqIHByb3RvY29sJ3MgZGVmYXVsdCBwb3J0LgorICAgICAqCisgICAgICogQHBhcmFtIGhvc3QgdGhlIGhvc3QgbmFtZSBvciBJUCBhZGRyZXNzIG9mIHRoZSBuZXcgVVJMLgorICAgICAqIEBwYXJhbSBwb3J0IHRoZSBwb3J0LCBvciB7QGNvZGUgLTF9IGZvciB0aGUgcHJvdG9jb2wncyBkZWZhdWx0IHBvcnQuCisgICAgICogQHBhcmFtIGZpbGUgdGhlIG5hbWUgb2YgdGhlIHJlc291cmNlLgorICAgICAqIEBwYXJhbSBoYW5kbGVyIHRoZSBzdHJlYW0gaGFuZGxlciBmb3IgdGhpcyBVUkwsIG9yIG51bGwgZm9yIHRoZQorICAgICAqICAgICBwcm90b2NvbCdzIGRlZmF1bHQgc3RyZWFtIGhhbmRsZXIuCisgICAgICogQHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24gaWYgdGhlIGNvbWJpbmF0aW9uIG9mIGFsbCBhcmd1bWVudHMgZG8gbm90CisgICAgICogICAgIHJlcHJlc2VudCBhIHZhbGlkIFVSTCBvciBpZiB0aGUgcHJvdG9jb2wgaXMgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMKFN0cmluZyBwcm90b2NvbCwgU3RyaW5nIGhvc3QsIGludCBwb3J0LCBTdHJpbmcgZmlsZSwKKyAgICAgICAgICAgIFVSTFN0cmVhbUhhbmRsZXIgaGFuZGxlcikgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwb3J0IDwgLTEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUkxFeGNlcHRpb24oInBvcnQgPCAtMTogIiArIHBvcnQpOworICAgICAgICB9CisgICAgICAgIGlmIChwcm90b2NvbCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInByb3RvY29sID09IG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFdyYXAgSVB2NiBhZGRyZXNzZXMgaW4gc3F1YXJlIGJyYWNrZXRzIGlmIHRoZXkgYXJlbid0IGFscmVhZHkuCisgICAgICAgIGlmIChob3N0ICE9IG51bGwgJiYgaG9zdC5jb250YWlucygiOiIpICYmIGhvc3QuY2hhckF0KDApICE9ICdbJykgeworICAgICAgICAgICAgaG9zdCA9ICJbIiArIGhvc3QgKyAiXSI7CisgICAgICAgIH0KKworICAgICAgICB0aGlzLnByb3RvY29sID0gcHJvdG9jb2w7CisgICAgICAgIHRoaXMuaG9zdCA9IGhvc3Q7CisgICAgICAgIHRoaXMucG9ydCA9IHBvcnQ7CisKKyAgICAgICAgZmlsZSA9IFVybFV0aWxzLmF1dGhvcml0eVNhZmVQYXRoKGhvc3QsIGZpbGUpOworCisgICAgICAgIC8vIFNldCB0aGUgZmllbGRzIGZyb20gdGhlIGFyZ3VtZW50cy4gSGFuZGxlIHRoZSBjYXNlIHdoZXJlIHRoZQorICAgICAgICAvLyBwYXNzZWQgaW4gImZpbGUiIGluY2x1ZGVzIGJvdGggYSBmaWxlIGFuZCBhIHJlZmVyZW5jZSBwYXJ0LgorICAgICAgICBpbnQgaGFzaCA9IGZpbGUuaW5kZXhPZigiIyIpOworICAgICAgICBpZiAoaGFzaCAhPSAtMSkgeworICAgICAgICAgICAgdGhpcy5maWxlID0gZmlsZS5zdWJzdHJpbmcoMCwgaGFzaCk7CisgICAgICAgICAgICB0aGlzLnJlZiA9IGZpbGUuc3Vic3RyaW5nKGhhc2ggKyAxKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRoaXMuZmlsZSA9IGZpbGU7CisgICAgICAgIH0KKyAgICAgICAgZml4VVJMKGZhbHNlKTsKKworICAgICAgICAvLyBTZXQgdGhlIHN0cmVhbSBoYW5kbGVyIGZvciB0aGUgVVJMIGVpdGhlciB0byB0aGUgaGFuZGxlcgorICAgICAgICAvLyBhcmd1bWVudCBpZiBpdCB3YXMgc3BlY2lmaWVkLCBvciB0byB0aGUgZGVmYXVsdCBmb3IgdGhlCisgICAgICAgIC8vIHJlY2VpdmVyJ3MgcHJvdG9jb2wgaWYgdGhlIGhhbmRsZXIgd2FzIG51bGwuCisgICAgICAgIGlmIChoYW5kbGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHNldHVwU3RyZWFtSGFuZGxlcigpOworICAgICAgICAgICAgaWYgKHN0cmVhbUhhbmRsZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUkxFeGNlcHRpb24oIlVua25vd24gcHJvdG9jb2w6ICIgKyBwcm90b2NvbCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzdHJlYW1IYW5kbGVyID0gaGFuZGxlcjsKKyAgICAgICAgfQorICAgIH0KKworICAgIHZvaWQgZml4VVJMKGJvb2xlYW4gZml4SG9zdCkgeworICAgICAgICBpbnQgaW5kZXg7CisgICAgICAgIGlmIChob3N0ICE9IG51bGwgJiYgaG9zdC5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgICAgIGF1dGhvcml0eSA9IGhvc3Q7CisgICAgICAgICAgICBpZiAocG9ydCAhPSAtMSkgeworICAgICAgICAgICAgICAgIGF1dGhvcml0eSA9IGF1dGhvcml0eSArICI6IiArIHBvcnQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZpeEhvc3QpIHsKKyAgICAgICAgICAgIGlmIChob3N0ICE9IG51bGwgJiYgKGluZGV4ID0gaG9zdC5sYXN0SW5kZXhPZignQCcpKSA+IC0xKSB7CisgICAgICAgICAgICAgICAgdXNlckluZm8gPSBob3N0LnN1YnN0cmluZygwLCBpbmRleCk7CisgICAgICAgICAgICAgICAgaG9zdCA9IGhvc3Quc3Vic3RyaW5nKGluZGV4ICsgMSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHVzZXJJbmZvID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoZmlsZSAhPSBudWxsICYmIChpbmRleCA9IGZpbGUuaW5kZXhPZignPycpKSA+IC0xKSB7CisgICAgICAgICAgICBxdWVyeSA9IGZpbGUuc3Vic3RyaW5nKGluZGV4ICsgMSk7CisgICAgICAgICAgICBwYXRoID0gZmlsZS5zdWJzdHJpbmcoMCwgaW5kZXgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcXVlcnkgPSBudWxsOworICAgICAgICAgICAgcGF0aCA9IGZpbGU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwcm9wZXJ0aWVzIG9mIHRoaXMgVVJMIHVzaW5nIHRoZSBwcm92aWRlZCBhcmd1bWVudHMuIE9ubHkgYQorICAgICAqIHtAY29kZSBVUkxTdHJlYW1IYW5kbGVyfSBjYW4gdXNlIHRoaXMgbWV0aG9kIHRvIHNldCBmaWVsZHMgb2YgdGhlCisgICAgICogZXhpc3RpbmcgVVJMIGluc3RhbmNlLiBBIFVSTCBpcyBnZW5lcmFsbHkgY29uc3RhbnQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0KFN0cmluZyBwcm90b2NvbCwgU3RyaW5nIGhvc3QsIGludCBwb3J0LCBTdHJpbmcgZmlsZSwgU3RyaW5nIHJlZikgeworICAgICAgICBpZiAodGhpcy5wcm90b2NvbCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aGlzLnByb3RvY29sID0gcHJvdG9jb2w7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5ob3N0ID0gaG9zdDsKKyAgICAgICAgdGhpcy5maWxlID0gZmlsZTsKKyAgICAgICAgdGhpcy5wb3J0ID0gcG9ydDsKKyAgICAgICAgdGhpcy5yZWYgPSByZWY7CisgICAgICAgIGhhc2hDb2RlID0gMDsKKyAgICAgICAgZml4VVJMKHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIFVSTCBlcXVhbHMge0Bjb2RlIG99LiBVUkxzIGFyZSBlcXVhbCBpZiB0aGV5IGhhdmUKKyAgICAgKiB0aGUgc2FtZSBwcm90b2NvbCwgaG9zdCwgcG9ydCwgZmlsZSwgYW5kIHJlZmVyZW5jZS4KKyAgICAgKgorICAgICAqIDxoMz5OZXR3b3JrIEkvTyBXYXJuaW5nPC9oMz4KKyAgICAgKiA8cD5Tb21lIGltcGxlbWVudGF0aW9ucyBvZiBVUkwuZXF1YWxzKCkgcmVzb2x2ZSBob3N0IG5hbWVzIG92ZXIgdGhlCisgICAgICogbmV0d29yay4gVGhpcyBpcyBwcm9ibGVtYXRpYzoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPjxzdHJvbmc+VGhlIG5ldHdvcmsgbWF5IGJlIHNsb3cuPC9zdHJvbmc+IE1hbnkgY2xhc3NlcywgaW5jbHVkaW5nCisgICAgICogY29yZSBjb2xsZWN0aW9ucyBsaWtlIHtAbGluayBqYXZhLnV0aWwuTWFwIE1hcH0gYW5kIHtAbGluayBqYXZhLnV0aWwuU2V0CisgICAgICogU2V0fSBleHBlY3QgdGhhdCB7QGNvZGUgZXF1YWxzfSBhbmQge0Bjb2RlIGhhc2hDb2RlfSB3aWxsIHJldHVybiBxdWlja2x5LgorICAgICAqIEJ5IHZpb2xhdGluZyB0aGlzIGFzc3VtcHRpb24sIHRoaXMgbWV0aG9kIHBvc2VkIHBvdGVudGlhbCBwZXJmb3JtYW5jZQorICAgICAqIHByb2JsZW1zLgorICAgICAqIDxsaT48c3Ryb25nPkVxdWFsIElQIGFkZHJlc3NlcyBkbyBub3QgaW1wbHkgZXF1YWwgY29udGVudC48L3N0cm9uZz4KKyAgICAgKiBWaXJ0dWFsIGhvc3RpbmcgcGVybWl0cyB1bnJlbGF0ZWQgc2l0ZXMgdG8gc2hhcmUgYW4gSVAgYWRkcmVzcy4gVGhpcworICAgICAqIG1ldGhvZCBjb3VsZCByZXBvcnQgdHdvIG90aGVyd2lzZSB1bnJlbGF0ZWQgVVJMcyB0byBiZSBlcXVhbCBiZWNhdXNlCisgICAgICogdGhleSdyZSBob3N0ZWQgb24gdGhlIHNhbWUgc2VydmVyLjwvbGk+CisgICAgICogPGxpPjxzdHJvbmc+VGhlIG5ldHdvcmsgbWFueSBub3QgYmUgYXZhaWxhYmxlLjwvc3Ryb25nPiBUd28gVVJMcyBjb3VsZCBiZQorICAgICAqIGVxdWFsIHdoZW4gYSBuZXR3b3JrIGlzIGF2YWlsYWJsZSBhbmQgdW5lcXVhbCBvdGhlcndpc2UuPC9saT4KKyAgICAgKiA8bGk+PHN0cm9uZz5UaGUgbmV0d29yayBtYXkgY2hhbmdlLjwvc3Ryb25nPiBUaGUgSVAgYWRkcmVzcyBmb3IgYSBnaXZlbgorICAgICAqIGhvc3QgbmFtZSB2YXJpZXMgYnkgbmV0d29yayBhbmQgb3ZlciB0aW1lLiBUaGlzIGlzIHByb2JsZW1hdGljIGZvciBtb2JpbGUKKyAgICAgKiBkZXZpY2VzLiBUd28gVVJMcyBjb3VsZCBiZSBlcXVhbCBvbiBzb21lIG5ldHdvcmtzIGFuZCB1bmVxdWFsIG9uCisgICAgICogb3RoZXJzLjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiA8cD5UaGlzIHByb2JsZW0gaXMgZml4ZWQgaW4gQW5kcm9pZCBpbiB0aGUgSWNlIENyZWFtIFNhbmR3aWNoIHJlbGVhc2UuIEluCisgICAgICogdGhhdCByZWxlYXNlLCBVUkxzIGFyZSBvbmx5IGVxdWFsIGlmIHRoZWlyIGhvc3QgbmFtZXMgYXJlIGVxdWFsIChpZ25vcmluZworICAgICAqIGNhc2UpLgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgaWYgKG8gPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzID09IG8pIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLmdldENsYXNzKCkgIT0gby5nZXRDbGFzcygpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN0cmVhbUhhbmRsZXIuZXF1YWxzKHRoaXMsIChVUkwpIG8pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIFVSTCByZWZlcnMgdG8gdGhlIHNhbWUgcmVzb3VyY2UgYXMge0Bjb2RlIG90aGVyVVJMfS4KKyAgICAgKiBBbGwgVVJMIGNvbXBvbmVudHMgZXhjZXB0IHRoZSByZWZlcmVuY2UgZmllbGQgYXJlIGNvbXBhcmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHNhbWVGaWxlKFVSTCBvdGhlclVSTCkgeworICAgICAgICByZXR1cm4gc3RyZWFtSGFuZGxlci5zYW1lRmlsZSh0aGlzLCBvdGhlclVSTCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGlmIChoYXNoQ29kZSA9PSAwKSB7CisgICAgICAgICAgICBoYXNoQ29kZSA9IHN0cmVhbUhhbmRsZXIuaGFzaENvZGUodGhpcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGhhc2hDb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHJlY2VpdmVyJ3Mgc3RyZWFtIGhhbmRsZXIgdG8gb25lIHdoaWNoIGlzIGFwcHJvcHJpYXRlIGZvciBpdHMKKyAgICAgKiBwcm90b2NvbC4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB0aGlzIHdpbGwgb3ZlcndyaXRlIGFueSBleGlzdGluZyBzdHJlYW0gaGFuZGxlciB3aXRoIHRoZSBuZXcKKyAgICAgKiBvbmUuIFNlbmRlcnMgbXVzdCBjaGVjayBpZiB0aGUgc3RyZWFtSGFuZGxlciBpcyBudWxsIGJlZm9yZSBjYWxsaW5nIHRoZQorICAgICAqIG1ldGhvZCBpZiB0aGV5IGRvIG5vdCB3YW50IHRoaXMgYmVoYXZpb3IgKGEgc3BlZWQgb3B0aW1pemF0aW9uKS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGlmIG5vIHJlYXNvbmFibGUgaGFuZGxlciBpcyBhdmFpbGFibGUuCisgICAgICovCisgICAgdm9pZCBzZXR1cFN0cmVhbUhhbmRsZXIoKSB7CisgICAgICAgIC8vIENoZWNrIGZvciBhIGNhY2hlZCAocHJldmlvdXNseSBsb29rZWQgdXApIGhhbmRsZXIgZm9yCisgICAgICAgIC8vIHRoZSByZXF1ZXN0ZWQgcHJvdG9jb2wuCisgICAgICAgIHN0cmVhbUhhbmRsZXIgPSBzdHJlYW1IYW5kbGVycy5nZXQocHJvdG9jb2wpOworICAgICAgICBpZiAoc3RyZWFtSGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICAvLyBJZiB0aGVyZSBpcyBhIHN0cmVhbSBoYW5kbGVyIGZhY3RvcnksIHRoZW4gYXR0ZW1wdCB0bworICAgICAgICAvLyB1c2UgaXQgdG8gY3JlYXRlIHRoZSBoYW5kbGVyLgorICAgICAgICBpZiAoc3RyZWFtSGFuZGxlckZhY3RvcnkgIT0gbnVsbCkgeworICAgICAgICAgICAgc3RyZWFtSGFuZGxlciA9IHN0cmVhbUhhbmRsZXJGYWN0b3J5LmNyZWF0ZVVSTFN0cmVhbUhhbmRsZXIocHJvdG9jb2wpOworICAgICAgICAgICAgaWYgKHN0cmVhbUhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHN0cmVhbUhhbmRsZXJzLnB1dChwcm90b2NvbCwgc3RyZWFtSGFuZGxlcik7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gQ2hlY2sgaWYgdGhlcmUgaXMgYSBsaXN0IG9mIHBhY2thZ2VzIHdoaWNoIGNhbiBwcm92aWRlIGhhbmRsZXJzLgorICAgICAgICAvLyBJZiBzbywgdGhlbiB3YWxrIHRoaXMgbGlzdCBsb29raW5nIGZvciBhbiBhcHBsaWNhYmxlIG9uZS4KKyAgICAgICAgU3RyaW5nIHBhY2thZ2VMaXN0ID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLnByb3RvY29sLmhhbmRsZXIucGtncyIpOworICAgICAgICBDbGFzc0xvYWRlciBjb250ZXh0Q2xhc3NMb2FkZXIgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpOworICAgICAgICBpZiAocGFja2FnZUxpc3QgIT0gbnVsbCAmJiBjb250ZXh0Q2xhc3NMb2FkZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChTdHJpbmcgcGFja2FnZU5hbWUgOiBwYWNrYWdlTGlzdC5zcGxpdCgiXFx8IikpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lID0gcGFja2FnZU5hbWUgKyAiLiIgKyBwcm90b2NvbCArICIuSGFuZGxlciI7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgQ2xhc3M8Pz4gYyA9IGNvbnRleHRDbGFzc0xvYWRlci5sb2FkQ2xhc3MoY2xhc3NOYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgc3RyZWFtSGFuZGxlciA9IChVUkxTdHJlYW1IYW5kbGVyKSBjLm5ld0luc3RhbmNlKCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChzdHJlYW1IYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUhhbmRsZXJzLnB1dChwcm90b2NvbCwgc3RyZWFtSGFuZGxlcik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIEZhbGwgYmFjayB0byBhIGJ1aWx0LWluIHN0cmVhbSBoYW5kbGVyIGlmIHRoZSB1c2VyIGRpZG4ndCBzdXBwbHkgb25lCisgICAgICAgIGlmIChwcm90b2NvbC5lcXVhbHMoImZpbGUiKSkgeworICAgICAgICAgICAgc3RyZWFtSGFuZGxlciA9IG5ldyBGaWxlSGFuZGxlcigpOworICAgICAgICB9IGVsc2UgaWYgKHByb3RvY29sLmVxdWFscygiZnRwIikpIHsKKyAgICAgICAgICAgIHN0cmVhbUhhbmRsZXIgPSBuZXcgRnRwSGFuZGxlcigpOworICAgICAgICB9IGVsc2UgaWYgKHByb3RvY29sLmVxdWFscygiaHR0cCIpKSB7CisgICAgICAgICAgICBzdHJlYW1IYW5kbGVyID0gbmV3IEh0dHBIYW5kbGVyKCk7CisgICAgICAgIH0gZWxzZSBpZiAocHJvdG9jb2wuZXF1YWxzKCJodHRwcyIpKSB7CisgICAgICAgICAgICBzdHJlYW1IYW5kbGVyID0gbmV3IEh0dHBzSGFuZGxlcigpOworICAgICAgICB9IGVsc2UgaWYgKHByb3RvY29sLmVxdWFscygiamFyIikpIHsKKyAgICAgICAgICAgIHN0cmVhbUhhbmRsZXIgPSBuZXcgSmFySGFuZGxlcigpOworICAgICAgICB9CisgICAgICAgIGlmIChzdHJlYW1IYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHN0cmVhbUhhbmRsZXJzLnB1dChwcm90b2NvbCwgc3RyZWFtSGFuZGxlcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb250ZW50IG9mIHRoZSByZXNvdXJjZSB3aGljaCBpcyByZWZlcnJlZCBieSB0aGlzIFVSTC4gQnkKKyAgICAgKiBkZWZhdWx0IHRoaXMgcmV0dXJucyBhbiB7QGNvZGUgSW5wdXRTdHJlYW19LCBvciBudWxsIGlmIHRoZSBjb250ZW50IHR5cGUKKyAgICAgKiBvZiB0aGUgcmVzcG9uc2UgaXMgdW5rbm93bi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgT2JqZWN0IGdldENvbnRlbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gb3BlbkNvbm5lY3Rpb24oKS5nZXRDb250ZW50KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgb3BlbkNvbm5lY3Rpb24oKS5nZXRDb250ZW50KHR5cGVzKX0uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIC8vIFBhcmFtIG5vdCBnZW5lcmljIGluIHNwZWMKKyAgICBwdWJsaWMgZmluYWwgT2JqZWN0IGdldENvbnRlbnQoQ2xhc3NbXSB0eXBlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG9wZW5Db25uZWN0aW9uKCkuZ2V0Q29udGVudCh0eXBlcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgb3BlbkNvbm5lY3Rpb24oKS5nZXRJbnB1dFN0cmVhbSh0eXBlcyl9LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBJbnB1dFN0cmVhbSBvcGVuU3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG9wZW5Db25uZWN0aW9uKCkuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGNvbm5lY3Rpb24gdG8gdGhlIHJlc291cmNlIHJlZmVycmVkIHRvIGJ5IHRoaXMgVVJMLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgb3BlbmluZyB0aGUgY29ubmVjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMQ29ubmVjdGlvbiBvcGVuQ29ubmVjdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzdHJlYW1IYW5kbGVyLm9wZW5Db25uZWN0aW9uKHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgY29ubmVjdGlvbiB0byB0aGUgcmVzb3VyY2UgcmVmZXJyZWQgdG8gYnkgdGhpcyBVUkwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJveHkgdGhlIHByb3h5IHRocm91Z2ggd2hpY2ggdGhlIGNvbm5lY3Rpb24gd2lsbCBiZSBlc3RhYmxpc2hlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgb3BlbmluZyB0aGUgY29ubmVjdGlvbi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgYXJndW1lbnQgcHJveHkgaXMgbnVsbCBvciBvZiBpcworICAgICAqICAgICBhbiBpbnZhbGlkIHR5cGUuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGUgcHJvdG9jb2wgaGFuZGxlciBkb2VzIG5vdAorICAgICAqICAgICBzdXBwb3J0IG9wZW5pbmcgY29ubmVjdGlvbnMgdGhyb3VnaCBwcm94aWVzLgorICAgICAqLworICAgIHB1YmxpYyBVUkxDb25uZWN0aW9uIG9wZW5Db25uZWN0aW9uKFByb3h5IHByb3h5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAocHJveHkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicHJveHkgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzdHJlYW1IYW5kbGVyLm9wZW5Db25uZWN0aW9uKHRoaXMsIHByb3h5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBVUkkgZXF1aXZhbGVudCB0byB0aGlzIFVSTC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIGlmIHRoaXMgVVJMIGNhbm5vdCBiZSBjb252ZXJ0ZWQgaW50byBhIFVSSS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJJIHRvVVJJKCkgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgVVJJKHRvRXh0ZXJuYWxGb3JtKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuY29kZXMgdGhpcyBVUkwgdG8gdGhlIGVxdWl2YWxlbnQgVVJJIGFmdGVyIGVzY2FwaW5nIGNoYXJhY3RlcnMgdGhhdCBhcmUKKyAgICAgKiBub3QgcGVybWl0dGVkIGJ5IFVSSS4KKyAgICAgKgorICAgICAqIEBoaWRlCisgICAgICovCisgICAgcHVibGljIFVSSSB0b1VSSUxlbmllbnQoKSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHN0cmVhbUhhbmRsZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihwcm90b2NvbCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBVUkkoc3RyZWFtSGFuZGxlci50b0V4dGVybmFsRm9ybSh0aGlzLCB0cnVlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUgcmVwcmVzZW50YXRpb24gb2YKKyAgICAgKiB0aGlzIFVSTC4gVGhlIHJldHVybmVkIHN0cmluZyBpcyB0aGUgc2FtZSBhcyB0aGUgcmVzdWx0IG9mIHRoZSBtZXRob2QKKyAgICAgKiB7QGNvZGUgdG9FeHRlcm5hbEZvcm0oKX0uCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiB0b0V4dGVybmFsRm9ybSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIGNvbmNpc2UsIGh1bWFuLXJlYWRhYmxlIHJlcHJlc2VudGF0aW9uIG9mCisgICAgICogdGhpcyBVUkwuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b0V4dGVybmFsRm9ybSgpIHsKKyAgICAgICAgaWYgKHN0cmVhbUhhbmRsZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuICJ1bmtub3duIHByb3RvY29sKCIgKyBwcm90b2NvbCArICIpOi8vIiArIGhvc3QgKyBmaWxlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzdHJlYW1IYW5kbGVyLnRvRXh0ZXJuYWxGb3JtKHRoaXMpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0cmVhbS5kZWZhdWx0UmVhZE9iamVjdCgpOworICAgICAgICAgICAgaWYgKGhvc3QgIT0gbnVsbCAmJiBhdXRob3JpdHkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGZpeFVSTCh0cnVlKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoYXV0aG9yaXR5ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpbnQgaW5kZXg7CisgICAgICAgICAgICAgICAgaWYgKChpbmRleCA9IGF1dGhvcml0eS5sYXN0SW5kZXhPZignQCcpKSA+IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIHVzZXJJbmZvID0gYXV0aG9yaXR5LnN1YnN0cmluZygwLCBpbmRleCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChmaWxlICE9IG51bGwgJiYgKGluZGV4ID0gZmlsZS5pbmRleE9mKCc/JykpID4gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgcXVlcnkgPSBmaWxlLnN1YnN0cmluZyhpbmRleCArIDEpOworICAgICAgICAgICAgICAgICAgICBwYXRoID0gZmlsZS5zdWJzdHJpbmcoMCwgaW5kZXgpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHBhdGggPSBmaWxlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNldHVwU3RyZWFtSGFuZGxlcigpOworICAgICAgICAgICAgaWYgKHN0cmVhbUhhbmRsZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5rbm93biBwcm90b2NvbDogIiArIHByb3RvY29sKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGhhc2hDb2RlID0gMDsgLy8gbmVjZXNzYXJ5IHVudGlsIGh0dHA6Ly9iLzQ0NzEyNDkgaXMgZml4ZWQKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHMuZGVmYXVsdFdyaXRlT2JqZWN0KCk7CisgICAgfQorCisgICAgLyoqIEBoaWRlICovCisgICAgcHVibGljIGludCBnZXRFZmZlY3RpdmVQb3J0KCkgeworICAgICAgICByZXR1cm4gVVJJLmdldEVmZmVjdGl2ZVBvcnQocHJvdG9jb2wsIHBvcnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByb3RvY29sIG9mIHRoaXMgVVJMIGxpa2UgImh0dHAiIG9yICJmaWxlIi4gVGhpcyBpcyBhbHNvCisgICAgICoga25vd24gYXMgdGhlIHNjaGVtZS4gVGhlIHJldHVybmVkIHN0cmluZyBpcyBsb3dlciBjYXNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJvdG9jb2woKSB7CisgICAgICAgIHJldHVybiBwcm90b2NvbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhdXRob3JpdHkgcGFydCBvZiB0aGlzIFVSTCwgb3IgbnVsbCBpZiB0aGlzIFVSTCBoYXMgbm8KKyAgICAgKiBhdXRob3JpdHkuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRBdXRob3JpdHkoKSB7CisgICAgICAgIHJldHVybiBhdXRob3JpdHk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdXNlciBpbmZvIG9mIHRoaXMgVVJMLCBvciBudWxsIGlmIHRoaXMgVVJMIGhhcyBubyB1c2VyIGluZm8uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRVc2VySW5mbygpIHsKKyAgICAgICAgcmV0dXJuIHVzZXJJbmZvOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhvc3QgbmFtZSBvciBJUCBhZGRyZXNzIG9mIHRoaXMgVVJMLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0SG9zdCgpIHsKKyAgICAgICAgcmV0dXJuIGhvc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcG9ydCBudW1iZXIgb2YgdGhpcyBVUkwgb3Ige0Bjb2RlIC0xfSBpZiB0aGlzIFVSTCBoYXMgbm8KKyAgICAgKiBleHBsaWNpdCBwb3J0LgorICAgICAqCisgICAgICogPHA+SWYgdGhpcyBVUkwgaGFzIG5vIGV4cGxpY2l0IHBvcnQsIGNvbm5lY3Rpb25zIG9wZW5lZCB1c2luZyB0aGlzIFVSTAorICAgICAqIHdpbGwgdXNlIGl0cyB7QGxpbmsgI2dldERlZmF1bHRQb3J0KCkgZGVmYXVsdCBwb3J0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFBvcnQoKSB7CisgICAgICAgIHJldHVybiBwb3J0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgcG9ydCBudW1iZXIgb2YgdGhlIHByb3RvY29sIHVzZWQgYnkgdGhpcyBVUkwuIElmIG5vCisgICAgICogZGVmYXVsdCBwb3J0IGlzIGRlZmluZWQgYnkgdGhlIHByb3RvY29sIG9yIHRoZSB7QGNvZGUgVVJMU3RyZWFtSGFuZGxlcn0sCisgICAgICoge0Bjb2RlIC0xfSB3aWxsIGJlIHJldHVybmVkLgorICAgICAqCisgICAgICogQHNlZSBVUkxTdHJlYW1IYW5kbGVyI2dldERlZmF1bHRQb3J0CisgICAgICovCisgICAgcHVibGljIGludCBnZXREZWZhdWx0UG9ydCgpIHsKKyAgICAgICAgcmV0dXJuIHN0cmVhbUhhbmRsZXIuZ2V0RGVmYXVsdFBvcnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBmaWxlIG9mIHRoaXMgVVJMLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RmlsZSgpIHsKKyAgICAgICAgcmV0dXJuIGZpbGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGF0aCBwYXJ0IG9mIHRoaXMgVVJMLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGF0aCgpIHsKKyAgICAgICAgcmV0dXJuIHBhdGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcXVlcnkgcGFydCBvZiB0aGlzIFVSTCwgb3IgbnVsbCBpZiB0aGlzIFVSTCBoYXMgbm8gcXVlcnkuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRRdWVyeSgpIHsKKyAgICAgICAgcmV0dXJuIHF1ZXJ5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSByZWZlcmVuY2UgcGFydCBvZiB0aGlzIFVSTCwgb3IgbnVsbCBpZiB0aGlzIFVSTAorICAgICAqIGhhcyBubyByZWZlcmVuY2UgcGFydC4gVGhpcyBpcyBhbHNvIGtub3duIGFzIHRoZSBmcmFnbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFJlZigpIHsKKyAgICAgICAgcmV0dXJuIHJlZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwcm9wZXJ0aWVzIG9mIHRoaXMgVVJMIHVzaW5nIHRoZSBwcm92aWRlZCBhcmd1bWVudHMuIE9ubHkgYQorICAgICAqIHtAY29kZSBVUkxTdHJlYW1IYW5kbGVyfSBjYW4gdXNlIHRoaXMgbWV0aG9kIHRvIHNldCBmaWVsZHMgb2YgdGhlCisgICAgICogZXhpc3RpbmcgVVJMIGluc3RhbmNlLiBBIFVSTCBpcyBnZW5lcmFsbHkgY29uc3RhbnQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0KFN0cmluZyBwcm90b2NvbCwgU3RyaW5nIGhvc3QsIGludCBwb3J0LCBTdHJpbmcgYXV0aG9yaXR5LCBTdHJpbmcgdXNlckluZm8sCisgICAgICAgICAgICBTdHJpbmcgcGF0aCwgU3RyaW5nIHF1ZXJ5LCBTdHJpbmcgcmVmKSB7CisgICAgICAgIFN0cmluZyBmaWxlID0gcGF0aDsKKyAgICAgICAgaWYgKHF1ZXJ5ICE9IG51bGwgJiYgIXF1ZXJ5LmlzRW1wdHkoKSkgeworICAgICAgICAgICAgZmlsZSArPSAiPyIgKyBxdWVyeTsKKyAgICAgICAgfQorICAgICAgICBzZXQocHJvdG9jb2wsIGhvc3QsIHBvcnQsIGZpbGUsIHJlZik7CisgICAgICAgIHRoaXMuYXV0aG9yaXR5ID0gYXV0aG9yaXR5OworICAgICAgICB0aGlzLnVzZXJJbmZvID0gdXNlckluZm87CisgICAgICAgIHRoaXMucGF0aCA9IHBhdGg7CisgICAgICAgIHRoaXMucXVlcnkgPSBxdWVyeTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvVVJMQ2xhc3NMb2FkZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9VUkxDbGFzc0xvYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjOGJjNDMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvVVJMQ2xhc3NMb2FkZXIuamF2YQpAQCAtMCwwICsxLDEwMTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkZpbGVQZXJtaXNzaW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuQ29kZVNvdXJjZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb25Db2xsZWN0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlQ2xhc3NMb2FkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CitpbXBvcnQgamF2YS51dGlsLmphci5BdHRyaWJ1dGVzOworaW1wb3J0IGphdmEudXRpbC5qYXIuSmFyRW50cnk7CitpbXBvcnQgamF2YS51dGlsLmphci5KYXJGaWxlOworaW1wb3J0IGphdmEudXRpbC5qYXIuTWFuaWZlc3Q7CitpbXBvcnQgbGliY29yZS5pby5Jb1V0aWxzOworaW1wb3J0IGxpYmNvcmUuaW8uU3RyZWFtczsKKworLyoqCisgKiBUaGlzIGNsYXNzIGxvYWRlciBpcyByZXNwb25zaWJsZSBmb3IgbG9hZGluZyBjbGFzc2VzIGFuZCByZXNvdXJjZXMgZnJvbSBhCisgKiBsaXN0IG9mIFVSTHMgd2hpY2ggY2FuIHJlZmVyIHRvIGVpdGhlciBkaXJlY3RvcmllcyBvciBKQVIgZmlsZXMuIENsYXNzZXMKKyAqIGxvYWRlZCBieSB0aGlzIHtAY29kZSBVUkxDbGFzc0xvYWRlcn0gYXJlIGdyYW50ZWQgcGVybWlzc2lvbiB0byBhY2Nlc3MgdGhlCisgKiBVUkxzIGNvbnRhaW5lZCBpbiB0aGUgVVJMIHNlYXJjaCBsaXN0LgorICovCitARmluZEJ1Z3NTdXBwcmVzc1dhcm5pbmdzKHsgIkRNSV9DT0xMRUNUSU9OX09GX1VSTFMiLCAiRFBfQ1JFQVRFX0NMQVNTTE9BREVSX0lOU0lERV9ET19QUklWSUxFR0VEIiB9KQorcHVibGljIGNsYXNzIFVSTENsYXNzTG9hZGVyIGV4dGVuZHMgU2VjdXJlQ2xhc3NMb2FkZXIgeworCisgICAgQXJyYXlMaXN0PFVSTD4gb3JpZ2luYWxVcmxzOworCisgICAgTGlzdDxVUkw+IHNlYXJjaExpc3Q7CisgICAgQXJyYXlMaXN0PFVSTEhhbmRsZXI+IGhhbmRsZXJMaXN0OworICAgIE1hcDxVUkwsIFVSTEhhbmRsZXI+IGhhbmRsZXJNYXAgPSBuZXcgSGFzaE1hcDxVUkwsIFVSTEhhbmRsZXI+KCk7CisKKyAgICBwcml2YXRlIFVSTFN0cmVhbUhhbmRsZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBzdGF0aWMgY2xhc3MgSW5kZXhGaWxlIHsKKworICAgICAgICBwcml2YXRlIEhhc2hNYXA8U3RyaW5nLCBBcnJheUxpc3Q8VVJMPj4gbWFwOworICAgICAgICAvL3ByaXZhdGUgVVJMQ2xhc3NMb2FkZXIgaG9zdDsKKworCisgICAgICAgIHN0YXRpYyBJbmRleEZpbGUgcmVhZEluZGV4RmlsZShKYXJGaWxlIGpmLCBKYXJFbnRyeSBpbmRleEVudHJ5LCBVUkwgdXJsKSB7CisgICAgICAgICAgICBCdWZmZXJlZFJlYWRlciBpbiA9IG51bGw7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIEFkZCBtYXBwaW5ncyBmcm9tIHJlc291cmNlIHRvIGphciBmaWxlCisgICAgICAgICAgICAgICAgU3RyaW5nIHBhcmVudFVSTFN0cmluZyA9IGdldFBhcmVudFVSTCh1cmwpLnRvRXh0ZXJuYWxGb3JtKCk7CisgICAgICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9ICJqYXI6IiArIHBhcmVudFVSTFN0cmluZyArICIvIjsKKyAgICAgICAgICAgICAgICBpcyA9IGpmLmdldElucHV0U3RyZWFtKGluZGV4RW50cnkpOworICAgICAgICAgICAgICAgIGluID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihpcywgQ2hhcnNldHMuVVRGXzgpKTsKKyAgICAgICAgICAgICAgICBIYXNoTWFwPFN0cmluZywgQXJyYXlMaXN0PFVSTD4+IHByZV9tYXAgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIEFycmF5TGlzdDxVUkw+PigpOworICAgICAgICAgICAgICAgIC8vIElnbm9yZSB0aGUgMiBmaXJzdCBsaW5lcyAoaW5kZXggdmVyc2lvbikKKyAgICAgICAgICAgICAgICBpZiAoaW4ucmVhZExpbmUoKSA9PSBudWxsKSByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICBpZiAoaW4ucmVhZExpbmUoKSA9PSBudWxsKSByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICBUT1BfQ1lDTEU6CisgICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxpbmUgPSBpbi5yZWFkTGluZSgpOworICAgICAgICAgICAgICAgICAgICBpZiAobGluZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBVUkwgamFyID0gbmV3IFVSTChwcmVmaXggKyBsaW5lICsgIiEvIik7CisgICAgICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBsaW5lID0gaW4ucmVhZExpbmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsaW5lID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBUT1BfQ1lDTEU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGluZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5TGlzdDxVUkw+IGxpc3Q7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJlX21hcC5jb250YWluc0tleShsaW5lKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QgPSBwcmVfbWFwLmdldChsaW5lKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdCA9IG5ldyBBcnJheUxpc3Q8VVJMPigpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZV9tYXAucHV0KGxpbmUsIGxpc3QpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5hZGQoamFyKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoIXByZV9tYXAuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSW5kZXhGaWxlKHByZV9tYXApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gSWdub3JlIHRoaXMgamFyJ3MgaW5kZXgKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBJZ25vcmUgdGhpcyBqYXIncyBpbmRleAorICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBJb1V0aWxzLmNsb3NlUXVpZXRseShpbik7CisgICAgICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkoaXMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHN0YXRpYyBVUkwgZ2V0UGFyZW50VVJMKFVSTCB1cmwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBVUkwgZmlsZVVSTCA9ICgoSmFyVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCkpLmdldEphckZpbGVVUkwoKTsKKyAgICAgICAgICAgIFN0cmluZyBmaWxlID0gZmlsZVVSTC5nZXRGaWxlKCk7CisgICAgICAgICAgICBTdHJpbmcgcGFyZW50RmlsZSA9IG5ldyBGaWxlKGZpbGUpLmdldFBhcmVudCgpOworICAgICAgICAgICAgcGFyZW50RmlsZSA9IHBhcmVudEZpbGUucmVwbGFjZShGaWxlLnNlcGFyYXRvckNoYXIsICcvJyk7CisgICAgICAgICAgICBpZiAocGFyZW50RmlsZS5jaGFyQXQoMCkgIT0gJy8nKSB7CisgICAgICAgICAgICAgICAgcGFyZW50RmlsZSA9ICIvIiArIHBhcmVudEZpbGU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBVUkwgcGFyZW50VVJMID0gbmV3IFVSTChmaWxlVVJMLmdldFByb3RvY29sKCksIGZpbGVVUkwKKyAgICAgICAgICAgICAgICAgICAgLmdldEhvc3QoKSwgZmlsZVVSTC5nZXRQb3J0KCksIHBhcmVudEZpbGUpOworICAgICAgICAgICAgcmV0dXJuIHBhcmVudFVSTDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBJbmRleEZpbGUoSGFzaE1hcDxTdHJpbmcsIEFycmF5TGlzdDxVUkw+PiBtYXApIHsKKyAgICAgICAgICAgIHRoaXMubWFwID0gbWFwOworICAgICAgICB9CisKKyAgICAgICAgQXJyYXlMaXN0PFVSTD4gZ2V0KFN0cmluZyBuYW1lKSB7CisgICAgICAgICAgICByZXR1cm4gbWFwLmdldChuYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIFVSTEhhbmRsZXIgeworICAgICAgICBVUkwgdXJsOworICAgICAgICBVUkwgY29kZVNvdXJjZVVybDsKKworICAgICAgICBwdWJsaWMgVVJMSGFuZGxlcihVUkwgdXJsKSB7CisgICAgICAgICAgICB0aGlzLnVybCA9IHVybDsKKyAgICAgICAgICAgIHRoaXMuY29kZVNvdXJjZVVybCA9IHVybDsKKyAgICAgICAgfQorCisgICAgICAgIHZvaWQgZmluZFJlc291cmNlcyhTdHJpbmcgbmFtZSwgQXJyYXlMaXN0PFVSTD4gcmVzb3VyY2VzKSB7CisgICAgICAgICAgICBVUkwgcmVzID0gZmluZFJlc291cmNlKG5hbWUpOworICAgICAgICAgICAgaWYgKHJlcyAhPSBudWxsICYmICFyZXNvdXJjZXMuY29udGFpbnMocmVzKSkgeworICAgICAgICAgICAgICAgIHJlc291cmNlcy5hZGQocmVzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIENsYXNzPD8+IGZpbmRDbGFzcyhTdHJpbmcgcGFja2FnZU5hbWUsIFN0cmluZyBuYW1lLCBTdHJpbmcgb3JpZ05hbWUpIHsKKyAgICAgICAgICAgIFVSTCByZXNVUkwgPSB0YXJnZXRVUkwodXJsLCBuYW1lKTsKKyAgICAgICAgICAgIGlmIChyZXNVUkwgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gcmVzVVJMLm9wZW5TdHJlYW0oKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUNsYXNzKGlzLCBwYWNrYWdlTmFtZSwgb3JpZ05hbWUpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisKKyAgICAgICAgQ2xhc3M8Pz4gY3JlYXRlQ2xhc3MoSW5wdXRTdHJlYW0gaXMsIFN0cmluZyBwYWNrYWdlTmFtZSwgU3RyaW5nIG9yaWdOYW1lKSB7CisgICAgICAgICAgICBpZiAoaXMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnl0ZVtdIGNsQnVmOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjbEJ1ZiA9IFN0cmVhbXMucmVhZEZ1bGx5KGlzKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChwYWNrYWdlTmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHBhY2thZ2VEb3ROYW1lID0gcGFja2FnZU5hbWUucmVwbGFjZSgnLycsICcuJyk7CisgICAgICAgICAgICAgICAgUGFja2FnZSBwYWNrYWdlT2JqID0gZ2V0UGFja2FnZShwYWNrYWdlRG90TmFtZSk7CisgICAgICAgICAgICAgICAgaWYgKHBhY2thZ2VPYmogPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBkZWZpbmVQYWNrYWdlKHBhY2thZ2VEb3ROYW1lLCBudWxsLCBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChwYWNrYWdlT2JqLmlzU2VhbGVkKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigiUGFja2FnZSBpcyBzZWFsZWQiKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBkZWZpbmVDbGFzcyhvcmlnTmFtZSwgY2xCdWYsIDAsIGNsQnVmLmxlbmd0aCwgbmV3IENvZGVTb3VyY2UoY29kZVNvdXJjZVVybCwgKENlcnRpZmljYXRlW10pIG51bGwpKTsKKyAgICAgICAgfQorCisgICAgICAgIFVSTCBmaW5kUmVzb3VyY2UoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgIFVSTCByZXNVUkwgPSB0YXJnZXRVUkwodXJsLCBuYW1lKTsKKyAgICAgICAgICAgIGlmIChyZXNVUkwgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFVSTENvbm5lY3Rpb24gdWMgPSByZXNVUkwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgdWMuZ2V0SW5wdXRTdHJlYW0oKS5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICAvLyBIVFRQIGNhbiByZXR1cm4gYSBzdHJlYW0gb24gYSBub24tZXhpc3RlbnQgZmlsZQorICAgICAgICAgICAgICAgICAgICAvLyBTbyBjaGVjayBmb3IgdGhlIHJldHVybiBjb2RlOworICAgICAgICAgICAgICAgICAgICBpZiAoIXJlc1VSTC5nZXRQcm90b2NvbCgpLmVxdWFscygiaHR0cCIpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzVVJMOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGludCBjb2RlOworICAgICAgICAgICAgICAgICAgICBpZiAoKGNvZGUgPSAoKEh0dHBVUkxDb25uZWN0aW9uKSB1YykuZ2V0UmVzcG9uc2VDb2RlKCkpID49IDIwMAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGNvZGUgPCAzMDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNVUkw7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBVUkwgdGFyZ2V0VVJMKFVSTCBiYXNlLCBTdHJpbmcgbmFtZSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIGZpbGVCdWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgICAgICAgICBmaWxlQnVpbGRlci5hcHBlbmQoYmFzZS5nZXRGaWxlKCkpOworICAgICAgICAgICAgICAgIFVSSS5QQVRIX0VOQ09ERVIuYXBwZW5kRW5jb2RlZChmaWxlQnVpbGRlciwgbmFtZSk7CisgICAgICAgICAgICAgICAgU3RyaW5nIGZpbGUgPSBmaWxlQnVpbGRlci50b1N0cmluZygpOworCisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVUkwoYmFzZS5nZXRQcm90b2NvbCgpLCBiYXNlLmdldEhvc3QoKSwgYmFzZS5nZXRQb3J0KCksIGZpbGUsIG51bGwpOworICAgICAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgfQorCisgICAgY2xhc3MgVVJMSmFySGFuZGxlciBleHRlbmRzIFVSTEhhbmRsZXIgeworICAgICAgICBmaW5hbCBKYXJGaWxlIGpmOworICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4TmFtZTsKKyAgICAgICAgZmluYWwgSW5kZXhGaWxlIGluZGV4OworICAgICAgICBmaW5hbCBNYXA8VVJMLCBVUkxIYW5kbGVyPiBzdWJIYW5kbGVycyA9IG5ldyBIYXNoTWFwPFVSTCwgVVJMSGFuZGxlcj4oKTsKKworICAgICAgICBwdWJsaWMgVVJMSmFySGFuZGxlcihVUkwgdXJsLCBVUkwgamFyVVJMLCBKYXJGaWxlIGpmLCBTdHJpbmcgcHJlZml4TmFtZSkgeworICAgICAgICAgICAgc3VwZXIodXJsKTsKKyAgICAgICAgICAgIHRoaXMuamYgPSBqZjsKKyAgICAgICAgICAgIHRoaXMucHJlZml4TmFtZSA9IHByZWZpeE5hbWU7CisgICAgICAgICAgICB0aGlzLmNvZGVTb3VyY2VVcmwgPSBqYXJVUkw7CisgICAgICAgICAgICBmaW5hbCBKYXJFbnRyeSBqZSA9IGpmLmdldEphckVudHJ5KCJNRVRBLUlORi9JTkRFWC5MSVNUIik7CisgICAgICAgICAgICB0aGlzLmluZGV4ID0gKGplID09IG51bGwgPyBudWxsIDogSW5kZXhGaWxlLnJlYWRJbmRleEZpbGUoamYsIGplLCB1cmwpKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBVUkxKYXJIYW5kbGVyKFVSTCB1cmwsIFVSTCBqYXJVUkwsIEphckZpbGUgamYsIFN0cmluZyBwcmVmaXhOYW1lLCBJbmRleEZpbGUgaW5kZXgpIHsKKyAgICAgICAgICAgIHN1cGVyKHVybCk7CisgICAgICAgICAgICB0aGlzLmpmID0gamY7CisgICAgICAgICAgICB0aGlzLnByZWZpeE5hbWUgPSBwcmVmaXhOYW1lOworICAgICAgICAgICAgdGhpcy5pbmRleCA9IGluZGV4OworICAgICAgICAgICAgdGhpcy5jb2RlU291cmNlVXJsID0gamFyVVJMOworICAgICAgICB9CisKKyAgICAgICAgSW5kZXhGaWxlIGdldEluZGV4KCkgeworICAgICAgICAgICAgcmV0dXJuIGluZGV4OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHZvaWQgZmluZFJlc291cmNlcyhTdHJpbmcgbmFtZSwgQXJyYXlMaXN0PFVSTD4gcmVzb3VyY2VzKSB7CisgICAgICAgICAgICBVUkwgcmVzID0gZmluZFJlc291cmNlSW5Pd24obmFtZSk7CisgICAgICAgICAgICBpZiAocmVzICE9IG51bGwgJiYgIXJlc291cmNlcy5jb250YWlucyhyZXMpKSB7CisgICAgICAgICAgICAgICAgcmVzb3VyY2VzLmFkZChyZXMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGluZGV4ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpbnQgcG9zID0gbmFtZS5sYXN0SW5kZXhPZigiLyIpOworICAgICAgICAgICAgICAgIC8vIG9ubHkga2VlcCB0aGUgZGlyZWN0b3J5IHBhcnQgb2YgdGhlIHJlc291cmNlCisgICAgICAgICAgICAgICAgLy8gYXMgaW5kZXgubGlzdCBvbmx5IGtlZXBzIHRyYWNrIG9mIGRpcmVjdG9yaWVzIGFuZCByb290IGZpbGVzCisgICAgICAgICAgICAgICAgU3RyaW5nIGluZGV4ZWROYW1lID0gKHBvcyA+IDApID8gbmFtZS5zdWJzdHJpbmcoMCwgcG9zKSA6IG5hbWU7CisgICAgICAgICAgICAgICAgQXJyYXlMaXN0PFVSTD4gdXJscyA9IGluZGV4LmdldChpbmRleGVkTmFtZSk7CisgICAgICAgICAgICAgICAgaWYgKHVybHMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB1cmxzLnJlbW92ZSh1cmwpOworICAgICAgICAgICAgICAgICAgICBmb3IgKFVSTCB1cmwgOiB1cmxzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBVUkxIYW5kbGVyIGggPSBnZXRTdWJIYW5kbGVyKHVybCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaC5maW5kUmVzb3VyY2VzKG5hbWUsIHJlc291cmNlcyk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBDbGFzczw/PiBmaW5kQ2xhc3MoU3RyaW5nIHBhY2thZ2VOYW1lLCBTdHJpbmcgbmFtZSwgU3RyaW5nIG9yaWdOYW1lKSB7CisgICAgICAgICAgICBTdHJpbmcgZW50cnlOYW1lID0gcHJlZml4TmFtZSArIG5hbWU7CisgICAgICAgICAgICBKYXJFbnRyeSBlbnRyeSA9IGpmLmdldEphckVudHJ5KGVudHJ5TmFtZSk7CisgICAgICAgICAgICBpZiAoZW50cnkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8qKgorICAgICAgICAgICAgICAgICAqIEF2b2lkIHJlY3Vyc2l2ZSBsb2FkIGNsYXNzLCBlc3BlY2lhbGx5IHRoZSBjbGFzcworICAgICAgICAgICAgICAgICAqIGlzIGFuIGltcGxlbWVudGF0aW9uIGNsYXNzIG9mIHNlY3VyaXR5IHByb3ZpZGVyCisgICAgICAgICAgICAgICAgICogYW5kIHRoZSBqYXIgaXMgc2lnbmVkLgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIE1hbmlmZXN0IG1hbmlmZXN0ID0gamYuZ2V0TWFuaWZlc3QoKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUNsYXNzKGVudHJ5LCBtYW5pZmVzdCwgcGFja2FnZU5hbWUsIG9yaWdOYW1lKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGluZGV4ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBBcnJheUxpc3Q8VVJMPiB1cmxzOworICAgICAgICAgICAgICAgIGlmIChwYWNrYWdlTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHVybHMgPSBpbmRleC5nZXQobmFtZSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdXJscyA9IGluZGV4LmdldChwYWNrYWdlTmFtZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICh1cmxzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdXJscy5yZW1vdmUodXJsKTsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChVUkwgdXJsIDogdXJscykgeworICAgICAgICAgICAgICAgICAgICAgICAgVVJMSGFuZGxlciBoID0gZ2V0U3ViSGFuZGxlcih1cmwpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGggIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzPD8+IHJlcyA9IGguZmluZENsYXNzKHBhY2thZ2VOYW1lLCBuYW1lLCBvcmlnTmFtZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXM7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIENsYXNzPD8+IGNyZWF0ZUNsYXNzKEphckVudHJ5IGVudHJ5LCBNYW5pZmVzdCBtYW5pZmVzdCwgU3RyaW5nIHBhY2thZ2VOYW1lLCBTdHJpbmcgb3JpZ05hbWUpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBjbEJ1ZjsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBqZi5nZXRJbnB1dFN0cmVhbShlbnRyeSk7CisgICAgICAgICAgICAgICAgY2xCdWYgPSBTdHJlYW1zLnJlYWRGdWxseShpcyk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocGFja2FnZU5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIFN0cmluZyBwYWNrYWdlRG90TmFtZSA9IHBhY2thZ2VOYW1lLnJlcGxhY2UoJy8nLCAnLicpOworICAgICAgICAgICAgICAgIFBhY2thZ2UgcGFja2FnZU9iaiA9IGdldFBhY2thZ2UocGFja2FnZURvdE5hbWUpOworICAgICAgICAgICAgICAgIGlmIChwYWNrYWdlT2JqID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG1hbmlmZXN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlZmluZVBhY2thZ2UocGFja2FnZURvdE5hbWUsIG1hbmlmZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2RlU291cmNlVXJsKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlZmluZVBhY2thZ2UocGFja2FnZURvdE5hbWUsIG51bGwsIG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBleGNlcHRpb24gPSBwYWNrYWdlT2JqLmlzU2VhbGVkKCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChtYW5pZmVzdCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNTZWFsZWQobWFuaWZlc3QsIHBhY2thZ2VOYW1lICsgIi8iKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9ICFwYWNrYWdlT2JqCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaXNTZWFsZWQoY29kZVNvdXJjZVVybCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKGV4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKFN0cmluZy5mb3JtYXQoIlBhY2thZ2UgJXMgaXMgc2VhbGVkIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2FnZU5hbWUpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIENvZGVTb3VyY2UgY29kZVMgPSBuZXcgQ29kZVNvdXJjZShjb2RlU291cmNlVXJsLCBlbnRyeS5nZXRDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgICAgICByZXR1cm4gZGVmaW5lQ2xhc3Mob3JpZ05hbWUsIGNsQnVmLCAwLCBjbEJ1Zi5sZW5ndGgsIGNvZGVTKTsKKyAgICAgICAgfQorCisgICAgICAgIFVSTCBmaW5kUmVzb3VyY2VJbk93bihTdHJpbmcgbmFtZSkgeworICAgICAgICAgICAgU3RyaW5nIGVudHJ5TmFtZSA9IHByZWZpeE5hbWUgKyBuYW1lOworICAgICAgICAgICAgaWYgKGpmLmdldEVudHJ5KGVudHJ5TmFtZSkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiB0YXJnZXRVUkwodXJsLCBuYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIFVSTCBmaW5kUmVzb3VyY2UoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgIFVSTCByZXMgPSBmaW5kUmVzb3VyY2VJbk93bihuYW1lKTsKKyAgICAgICAgICAgIGlmIChyZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiByZXM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaW5kZXggIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGludCBwb3MgPSBuYW1lLmxhc3RJbmRleE9mKCIvIik7CisgICAgICAgICAgICAgICAgLy8gb25seSBrZWVwIHRoZSBkaXJlY3RvcnkgcGFydCBvZiB0aGUgcmVzb3VyY2UKKyAgICAgICAgICAgICAgICAvLyBhcyBpbmRleC5saXN0IG9ubHkga2VlcHMgdHJhY2sgb2YgZGlyZWN0b3JpZXMgYW5kIHJvb3QgZmlsZXMKKyAgICAgICAgICAgICAgICBTdHJpbmcgaW5kZXhlZE5hbWUgPSAocG9zID4gMCkgPyBuYW1lLnN1YnN0cmluZygwLCBwb3MpIDogbmFtZTsKKyAgICAgICAgICAgICAgICBBcnJheUxpc3Q8VVJMPiB1cmxzID0gaW5kZXguZ2V0KGluZGV4ZWROYW1lKTsKKyAgICAgICAgICAgICAgICBpZiAodXJscyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHVybHMucmVtb3ZlKHVybCk7CisgICAgICAgICAgICAgICAgICAgIGZvciAoVVJMIHVybCA6IHVybHMpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFVSTEhhbmRsZXIgaCA9IGdldFN1YkhhbmRsZXIodXJsKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXMgPSBoLmZpbmRSZXNvdXJjZShuYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgc3luY2hyb25pemVkIFVSTEhhbmRsZXIgZ2V0U3ViSGFuZGxlcihVUkwgdXJsKSB7CisgICAgICAgICAgICBVUkxIYW5kbGVyIHN1YiA9IHN1YkhhbmRsZXJzLmdldCh1cmwpOworICAgICAgICAgICAgaWYgKHN1YiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1YjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN0cmluZyBwcm90b2NvbCA9IHVybC5nZXRQcm90b2NvbCgpOworICAgICAgICAgICAgaWYgKHByb3RvY29sLmVxdWFscygiamFyIikpIHsKKyAgICAgICAgICAgICAgICBzdWIgPSBjcmVhdGVVUkxKYXJIYW5kbGVyKHVybCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHByb3RvY29sLmVxdWFscygiZmlsZSIpKSB7CisgICAgICAgICAgICAgICAgc3ViID0gY3JlYXRlVVJMU3ViSmFySGFuZGxlcih1cmwpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzdWIgPSBjcmVhdGVVUkxIYW5kbGVyKHVybCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc3ViICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzdWJIYW5kbGVycy5wdXQodXJsLCBzdWIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHN1YjsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgVVJMSGFuZGxlciBjcmVhdGVVUkxTdWJKYXJIYW5kbGVyKFVSTCB1cmwpIHsKKyAgICAgICAgICAgIFN0cmluZyBwcmVmaXhOYW1lOworICAgICAgICAgICAgU3RyaW5nIGZpbGUgPSB1cmwuZ2V0RmlsZSgpOworICAgICAgICAgICAgaWYgKHVybC5nZXRGaWxlKCkuZW5kc1dpdGgoIiEvIikpIHsKKyAgICAgICAgICAgICAgICBwcmVmaXhOYW1lID0gIiI7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGludCBzZXBJZHggPSBmaWxlLmxhc3RJbmRleE9mKCIhLyIpOworICAgICAgICAgICAgICAgIGlmIChzZXBJZHggPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gSW52YWxpZCBVUkwsIGRvbid0IGxvb2sgaGVyZSBhZ2FpbgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc2VwSWR4ICs9IDI7CisgICAgICAgICAgICAgICAgcHJlZml4TmFtZSA9IGZpbGUuc3Vic3RyaW5nKHNlcElkeCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFVSTCBqYXJVUkwgPSAoKEphclVSTENvbm5lY3Rpb24pIHVybAorICAgICAgICAgICAgICAgICAgICAgICAgLm9wZW5Db25uZWN0aW9uKCkpLmdldEphckZpbGVVUkwoKTsKKyAgICAgICAgICAgICAgICBKYXJVUkxDb25uZWN0aW9uIGp1YyA9IChKYXJVUkxDb25uZWN0aW9uKSBuZXcgVVJMKAorICAgICAgICAgICAgICAgICAgICAgICAgImphciIsICIiLAorICAgICAgICAgICAgICAgICAgICAgICAgamFyVVJMLnRvRXh0ZXJuYWxGb3JtKCkgKyAiIS8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICAgICAgICAgIEphckZpbGUgamYgPSBqdWMuZ2V0SmFyRmlsZSgpOworICAgICAgICAgICAgICAgIFVSTEphckhhbmRsZXIgamFySCA9IG5ldyBVUkxKYXJIYW5kbGVyKHVybCwgamFyVVJMLCBqZiwgcHJlZml4TmFtZSwgbnVsbCk7CisgICAgICAgICAgICAgICAgLy8gVE9ETyA6IHRvIHRoaW5rIHdoYXQgd2Ugc2hvdWxkIGRvIHdpdGggaW5kZXhlcyAmIG1hbmlmZXN0LmNsYXNzIGZpbGUgaGVyZQorICAgICAgICAgICAgICAgIHJldHVybiBqYXJIOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgIH0KKworICAgIGNsYXNzIFVSTEZpbGVIYW5kbGVyIGV4dGVuZHMgVVJMSGFuZGxlciB7CisgICAgICAgIHByaXZhdGUgU3RyaW5nIHByZWZpeDsKKworICAgICAgICBwdWJsaWMgVVJMRmlsZUhhbmRsZXIoVVJMIHVybCkgeworICAgICAgICAgICAgc3VwZXIodXJsKTsKKyAgICAgICAgICAgIFN0cmluZyBiYXNlRmlsZSA9IHVybC5nZXRGaWxlKCk7CisgICAgICAgICAgICBTdHJpbmcgaG9zdCA9IHVybC5nZXRIb3N0KCk7CisgICAgICAgICAgICBpbnQgaG9zdExlbmd0aCA9IDA7CisgICAgICAgICAgICBpZiAoaG9zdCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaG9zdExlbmd0aCA9IGhvc3QubGVuZ3RoKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKDIgKyBob3N0TGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICsgYmFzZUZpbGUubGVuZ3RoKCkpOworICAgICAgICAgICAgaWYgKGhvc3RMZW5ndGggPiAwKSB7CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiLy8iKS5hcHBlbmQoaG9zdCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBiYXNlRmlsZSBhbHdheXMgZW5kcyB3aXRoICcvJworICAgICAgICAgICAgYnVmLmFwcGVuZChiYXNlRmlsZSk7CisgICAgICAgICAgICBwcmVmaXggPSBidWYudG9TdHJpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBDbGFzczw/PiBmaW5kQ2xhc3MoU3RyaW5nIHBhY2thZ2VOYW1lLCBTdHJpbmcgbmFtZSwgU3RyaW5nIG9yaWdOYW1lKSB7CisgICAgICAgICAgICBTdHJpbmcgZmlsZW5hbWUgPSBwcmVmaXggKyBuYW1lOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmaWxlbmFtZSA9IFVSTERlY29kZXIuZGVjb2RlKGZpbGVuYW1lLCAiVVRGLTgiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgRmlsZSBmaWxlID0gbmV3IEZpbGUoZmlsZW5hbWUpOworICAgICAgICAgICAgaWYgKGZpbGUuZXhpc3RzKCkpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVDbGFzcyhpcywgcGFja2FnZU5hbWUsIG9yaWdOYW1lKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIFVSTCBmaW5kUmVzb3VyY2UoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgIGludCBpZHggPSAwOworICAgICAgICAgICAgU3RyaW5nIGZpbGVuYW1lOworCisgICAgICAgICAgICAvLyBEbyBub3QgY3JlYXRlIGEgVU5DIHBhdGgsIGkuZS4gXFxob3N0CisgICAgICAgICAgICB3aGlsZSAoaWR4IDwgbmFtZS5sZW5ndGgoKSAmJgorICAgICAgICAgICAgICAgICAgICgobmFtZS5jaGFyQXQoaWR4KSA9PSAnLycpIHx8IChuYW1lLmNoYXJBdChpZHgpID09ICdcXCcpKSkgeworICAgICAgICAgICAgICAgIGlkeCsrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoaWR4ID4gMCkgeworICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cmluZyhpZHgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZpbGVuYW1lID0gVVJMRGVjb2Rlci5kZWNvZGUocHJlZml4LCAiVVRGLTgiKSArIG5hbWU7CisKKyAgICAgICAgICAgICAgICBpZiAobmV3IEZpbGUoZmlsZW5hbWUpLmV4aXN0cygpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0YXJnZXRVUkwodXJsLCBuYW1lKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gbXVzdCBub3QgaGFwcGVuCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFVSTENsYXNzTG9hZGVyfSBpbnN0YW5jZS4gVGhlIG5ld2x5IGNyZWF0ZWQKKyAgICAgKiBpbnN0YW5jZSB3aWxsIGhhdmUgdGhlIHN5c3RlbSBDbGFzc0xvYWRlciBhcyBpdHMgcGFyZW50LiBVUkxzIHRoYXQgZW5kCisgICAgICogd2l0aCAiLyIgYXJlIGFzc3VtZWQgdG8gYmUgZGlyZWN0b3JpZXMsIG90aGVyd2lzZSB0aGV5IGFyZSBhc3N1bWVkIHRvIGJlCisgICAgICogSkFSIGZpbGVzLgorICAgICAqCisgICAgICogQHBhcmFtIHVybHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IG9mIFVSTHMgd2hlcmUgYSBzcGVjaWZpYyBjbGFzcyBvciBmaWxlIGNvdWxkIGJlCisgICAgICogICAgICAgICAgICBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMQ2xhc3NMb2FkZXIoVVJMW10gdXJscykgeworICAgICAgICB0aGlzKHVybHMsIENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCksIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgVVJMQ2xhc3NMb2FkZXIgaW5zdGFuY2UuIFRoZSBuZXdseSBjcmVhdGVkIGluc3RhbmNlIHdpbGwKKyAgICAgKiBoYXZlIHRoZSBzeXN0ZW0gQ2xhc3NMb2FkZXIgYXMgaXRzIHBhcmVudC4gVVJMcyB0aGF0IGVuZCB3aXRoICIvIiBhcmUKKyAgICAgKiBhc3N1bWVkIHRvIGJlIGRpcmVjdG9yaWVzLCBvdGhlcndpc2UgdGhleSBhcmUgYXNzdW1lZCB0byBiZSBKQVIgZmlsZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJscworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgVVJMcyB3aGVyZSBhIHNwZWNpZmljIGNsYXNzIG9yIGZpbGUgY291bGQgYmUKKyAgICAgKiAgICAgICAgICAgIGZvdW5kLgorICAgICAqIEBwYXJhbSBwYXJlbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjbGFzcyBsb2FkZXIgdG8gYXNzaWduIGFzIHRoaXMgbG9hZGVyJ3MgcGFyZW50LgorICAgICAqLworICAgIHB1YmxpYyBVUkxDbGFzc0xvYWRlcihVUkxbXSB1cmxzLCBDbGFzc0xvYWRlciBwYXJlbnQpIHsKKyAgICAgICAgdGhpcyh1cmxzLCBwYXJlbnQsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIHNwZWNpZmllZCBVUkwgdG8gdGhlIHNlYXJjaCBsaXN0LgorICAgICAqCisgICAgICogQHBhcmFtIHVybAorICAgICAqICAgICAgICAgICAgdGhlIFVSTCB3aGljaCBpcyB0byBhZGQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgYWRkVVJMKFVSTCB1cmwpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9yaWdpbmFsVXJscy5hZGQodXJsKTsKKyAgICAgICAgICAgIHNlYXJjaExpc3QuYWRkKGNyZWF0ZVNlYXJjaFVSTCh1cmwpKTsKKyAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYWxsIGtub3duIFVSTHMgd2hpY2ggcG9pbnQgdG8gdGhlIHNwZWNpZmllZCByZXNvdXJjZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcmVxdWVzdGVkIHJlc291cmNlLgorICAgICAqIEByZXR1cm4gdGhlIGVudW1lcmF0aW9uIG9mIFVSTHMgd2hpY2ggcG9pbnQgdG8gdGhlIHNwZWNpZmllZCByZXNvdXJjZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSBhdHRlbXB0aW5nIHRvIGNvbm5lY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEVudW1lcmF0aW9uPFVSTD4gZmluZFJlc291cmNlcyhmaW5hbCBTdHJpbmcgbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgQXJyYXlMaXN0PFVSTD4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxVUkw+KCk7CisgICAgICAgIGludCBuID0gMDsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIFVSTEhhbmRsZXIgaGFuZGxlciA9IGdldEhhbmRsZXIobisrKTsKKyAgICAgICAgICAgIGlmIChoYW5kbGVyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGhhbmRsZXIuZmluZFJlc291cmNlcyhuYW1lLCByZXN1bHQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbnVtZXJhdGlvbihyZXN1bHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYWxsIHBlcm1pc3Npb25zIGZvciB0aGUgc3BlY2lmaWVkIHtAY29kZSBjb2Rlc291cmNlfS4gRmlyc3QsIHRoaXMKKyAgICAgKiBtZXRob2QgcmV0cmlldmVzIHRoZSBwZXJtaXNzaW9ucyBmcm9tIHRoZSBzeXN0ZW0gcG9saWN5LiBJZiB0aGUgcHJvdG9jb2wKKyAgICAgKiBpcyAiZmlsZTovIiB0aGVuIGEgbmV3IHBlcm1pc3Npb24sIHtAY29kZSBGaWxlUGVybWlzc2lvbn0sIGdyYW50aW5nIHRoZQorICAgICAqIHJlYWQgcGVybWlzc2lvbiB0byB0aGUgZmlsZSBpcyBhZGRlZCB0byB0aGUgcGVybWlzc2lvbiBjb2xsZWN0aW9uLgorICAgICAqIE90aGVyd2lzZSwgY29ubmVjdGluZyB0byBhbmQgYWNjZXB0aW5nIGNvbm5lY3Rpb25zIGZyb20gdGhlIFVSTCBpcworICAgICAqIGdyYW50ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29kZXNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIGNvZGUgc291cmNlIG9iamVjdCB3aG9zZSBwZXJtaXNzaW9ucyBoYXZlIHRvIGJlIGtub3duLgorICAgICAqIEByZXR1cm4gdGhlIGxpc3Qgb2YgcGVybWlzc2lvbnMgYWNjb3JkaW5nIHRvIHRoZSBjb2RlIHNvdXJjZSBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIFBlcm1pc3Npb25Db2xsZWN0aW9uIGdldFBlcm1pc3Npb25zKGZpbmFsIENvZGVTb3VyY2UgY29kZXNvdXJjZSkgeworICAgICAgICBQZXJtaXNzaW9uQ29sbGVjdGlvbiBwYyA9IHN1cGVyLmdldFBlcm1pc3Npb25zKGNvZGVzb3VyY2UpOworICAgICAgICBVUkwgdSA9IGNvZGVzb3VyY2UuZ2V0TG9jYXRpb24oKTsKKyAgICAgICAgaWYgKHUuZ2V0UHJvdG9jb2woKS5lcXVhbHMoImphciIpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBhIFVSTCBmb3IgdGhlIHJlc291cmNlIHRoZSBqYXIgcmVmZXJzIHRvCisgICAgICAgICAgICAgICAgdSA9ICgoSmFyVVJMQ29ubmVjdGlvbikgdS5vcGVuQ29ubmVjdGlvbigpKS5nZXRKYXJGaWxlVVJMKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gVGhpcyBzaG91bGQgbmV2ZXIgb2NjdXIuIElmIGl0IGRvZXMgY29udGludWUgdXNpbmcgdGhlIGphcgorICAgICAgICAgICAgICAgIC8vIFVSTAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmICh1LmdldFByb3RvY29sKCkuZXF1YWxzKCJmaWxlIikpIHsKKyAgICAgICAgICAgIFN0cmluZyBwYXRoID0gdS5nZXRGaWxlKCk7CisgICAgICAgICAgICBTdHJpbmcgaG9zdCA9IHUuZ2V0SG9zdCgpOworICAgICAgICAgICAgaWYgKGhvc3QgIT0gbnVsbCAmJiBob3N0Lmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgICAgIHBhdGggPSAiLy8iICsgaG9zdCArIHBhdGg7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChGaWxlLnNlcGFyYXRvckNoYXIgIT0gJy8nKSB7CisgICAgICAgICAgICAgICAgcGF0aCA9IHBhdGgucmVwbGFjZSgnLycsIEZpbGUuc2VwYXJhdG9yQ2hhcik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaXNEaXJlY3RvcnkodSkpIHsKKyAgICAgICAgICAgICAgICBwYy5hZGQobmV3IEZpbGVQZXJtaXNzaW9uKHBhdGggKyAiLSIsICJyZWFkIikpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBwYy5hZGQobmV3IEZpbGVQZXJtaXNzaW9uKHBhdGgsICJyZWFkIikpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgU3RyaW5nIGhvc3QgPSB1LmdldEhvc3QoKTsKKyAgICAgICAgICAgIGlmIChob3N0Lmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgICAgICBob3N0ID0gImxvY2FsaG9zdCI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwYy5hZGQobmV3IFNvY2tldFBlcm1pc3Npb24oaG9zdCwgImNvbm5lY3QsIGFjY2VwdCIpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcGM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2VhcmNoIGxpc3Qgb2YgdGhpcyB7QGNvZGUgVVJMQ2xhc3NMb2FkZXJ9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGlzdCBvZiBhbGwga25vd24gVVJMcyBvZiB0aGlzIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBVUkxbXSBnZXRVUkxzKCkgeworICAgICAgICByZXR1cm4gb3JpZ2luYWxVcmxzLnRvQXJyYXkobmV3IFVSTFtvcmlnaW5hbFVybHMuc2l6ZSgpXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyBpZiB0aGUgVVJMIGlzIHBvaW50aW5nIHRvIGEgZGlyZWN0b3J5LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNEaXJlY3RvcnkoVVJMIHVybCkgeworICAgICAgICBTdHJpbmcgZmlsZSA9IHVybC5nZXRGaWxlKCk7CisgICAgICAgIHJldHVybiAoZmlsZS5sZW5ndGgoKSA+IDAgJiYgZmlsZS5jaGFyQXQoZmlsZS5sZW5ndGgoKSAtIDEpID09ICcvJyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgVVJMQ2xhc3NMb2FkZXJ9IGluc3RhbmNlIGZvciB0aGUgZ2l2ZW4gVVJMcyBhbmQgdGhlCisgICAgICogc3lzdGVtIHtAY29kZSBDbGFzc0xvYWRlcn0gYXMgaXRzIHBhcmVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmxzCisgICAgICogICAgICAgICAgICB0aGUgbGlzdCBvZiBVUkxzIHRoYXQgaXMgcGFzc2VkIHRvIHRoZSBuZXcge0Bjb2RlCisgICAgICogICAgICAgICAgICBVUkxDbGFzc0xvYWRlcn0uCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCB7QGNvZGUgVVJMQ2xhc3NMb2FkZXJ9IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVVJMQ2xhc3NMb2FkZXIgbmV3SW5zdGFuY2UoZmluYWwgVVJMW10gdXJscykgeworICAgICAgICByZXR1cm4gbmV3IFVSTENsYXNzTG9hZGVyKHVybHMsIENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIFVSTENsYXNzTG9hZGVyfSBpbnN0YW5jZSBmb3IgdGhlIGdpdmVuIFVSTHMgYW5kIHRoZQorICAgICAqIHNwZWNpZmllZCB7QGNvZGUgQ2xhc3NMb2FkZXJ9IGFzIGl0cyBwYXJlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJscworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgVVJMcyB0aGF0IGlzIHBhc3NlZCB0byB0aGUgbmV3IFVSTENsYXNzTG9hZGVyLgorICAgICAqIEBwYXJhbSBwYXJlbnRDbAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmVudCBjbGFzcyBsb2FkZXIgdGhhdCBpcyBwYXNzZWQgdG8gdGhlIG5ldworICAgICAqICAgICAgICAgICAgVVJMQ2xhc3NMb2FkZXIuCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCB7QGNvZGUgVVJMQ2xhc3NMb2FkZXJ9IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVVJMQ2xhc3NMb2FkZXIgbmV3SW5zdGFuY2UoZmluYWwgVVJMW10gdXJscywgZmluYWwgQ2xhc3NMb2FkZXIgcGFyZW50Q2wpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBVUkxDbGFzc0xvYWRlcih1cmxzLCBwYXJlbnRDbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgVVJMQ2xhc3NMb2FkZXJ9IGluc3RhbmNlLiBUaGUgbmV3bHkgY3JlYXRlZAorICAgICAqIGluc3RhbmNlIHdpbGwgaGF2ZSB0aGUgc3BlY2lmaWVkIHtAY29kZSBDbGFzc0xvYWRlcn0gYXMgaXRzIHBhcmVudCBhbmQKKyAgICAgKiB1c2UgdGhlIHNwZWNpZmllZCBmYWN0b3J5IHRvIGNyZWF0ZSBzdHJlYW0gaGFuZGxlcnMuIFVSTHMgdGhhdCBlbmQgd2l0aAorICAgICAqICIvIiBhcmUgYXNzdW1lZCB0byBiZSBkaXJlY3Rvcmllcywgb3RoZXJ3aXNlIHRoZXkgYXJlIGFzc3VtZWQgdG8gYmUgSkFSCisgICAgICogZmlsZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2VhcmNoVXJscworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgVVJMcyB3aGVyZSBhIHNwZWNpZmljIGNsYXNzIG9yIGZpbGUgY291bGQgYmUKKyAgICAgKiAgICAgICAgICAgIGZvdW5kLgorICAgICAqIEBwYXJhbSBwYXJlbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2xhc3NMb2FkZXJ9IHRvIGFzc2lnbiBhcyB0aGlzIGxvYWRlcidzIHBhcmVudC4KKyAgICAgKiBAcGFyYW0gZmFjdG9yeQorICAgICAqICAgICAgICAgICAgdGhlIGZhY3RvcnkgdGhhdCB3aWxsIGJlIHVzZWQgdG8gY3JlYXRlIHByb3RvY29sLXNwZWNpZmljCisgICAgICogICAgICAgICAgICBzdHJlYW0gaGFuZGxlcnMuCisgICAgICovCisgICAgcHVibGljIFVSTENsYXNzTG9hZGVyKFVSTFtdIHNlYXJjaFVybHMsIENsYXNzTG9hZGVyIHBhcmVudCwgVVJMU3RyZWFtSGFuZGxlckZhY3RvcnkgZmFjdG9yeSkgeworICAgICAgICBzdXBlcihwYXJlbnQpOworICAgICAgICB0aGlzLmZhY3RvcnkgPSBmYWN0b3J5OworICAgICAgICBpbnQgbmJVcmxzID0gc2VhcmNoVXJscy5sZW5ndGg7CisgICAgICAgIG9yaWdpbmFsVXJscyA9IG5ldyBBcnJheUxpc3Q8VVJMPihuYlVybHMpOworICAgICAgICBoYW5kbGVyTGlzdCA9IG5ldyBBcnJheUxpc3Q8VVJMSGFuZGxlcj4obmJVcmxzKTsKKyAgICAgICAgc2VhcmNoTGlzdCA9IENvbGxlY3Rpb25zLnN5bmNocm9uaXplZExpc3QobmV3IEFycmF5TGlzdDxVUkw+KG5iVXJscykpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5iVXJsczsgaSsrKSB7CisgICAgICAgICAgICBvcmlnaW5hbFVybHMuYWRkKHNlYXJjaFVybHNbaV0pOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzZWFyY2hMaXN0LmFkZChjcmVhdGVTZWFyY2hVUkwoc2VhcmNoVXJsc1tpXSkpOworICAgICAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRyaWVzIHRvIGxvY2F0ZSBhbmQgbG9hZCB0aGUgc3BlY2lmaWVkIGNsYXNzIHVzaW5nIHRoZSBrbm93biBVUkxzLiBJZiB0aGUKKyAgICAgKiBjbGFzcyBjb3VsZCBiZSBmb3VuZCwgYSBjbGFzcyBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBsb2FkZWQgY2xhc3Mgd2lsbAorICAgICAqIGJlIHJldHVybmVkLgorICAgICAqCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBjbGFzcyBjYW5ub3QgYmUgbG9hZGVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBDbGFzczw/PiBmaW5kQ2xhc3MoZmluYWwgU3RyaW5nIGNsYXNzTmFtZSkgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgcGFydGlhbE5hbWUgPSBjbGFzc05hbWUucmVwbGFjZSgnLicsICcvJyk7CisgICAgICAgIGZpbmFsIFN0cmluZyBjbGFzc0ZpbGVOYW1lID0gbmV3IFN0cmluZ0J1aWxkZXIocGFydGlhbE5hbWUpLmFwcGVuZCgiLmNsYXNzIikudG9TdHJpbmcoKTsKKyAgICAgICAgU3RyaW5nIHBhY2thZ2VOYW1lID0gbnVsbDsKKyAgICAgICAgaW50IHBvc2l0aW9uID0gcGFydGlhbE5hbWUubGFzdEluZGV4T2YoJy8nKTsKKyAgICAgICAgaWYgKChwb3NpdGlvbiA9IHBhcnRpYWxOYW1lLmxhc3RJbmRleE9mKCcvJykpICE9IC0xKSB7CisgICAgICAgICAgICBwYWNrYWdlTmFtZSA9IHBhcnRpYWxOYW1lLnN1YnN0cmluZygwLCBwb3NpdGlvbik7CisgICAgICAgIH0KKyAgICAgICAgaW50IG4gPSAwOworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgVVJMSGFuZGxlciBoYW5kbGVyID0gZ2V0SGFuZGxlcihuKyspOworICAgICAgICAgICAgaWYgKGhhbmRsZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQ2xhc3M8Pz4gcmVzID0gaGFuZGxlci5maW5kQ2xhc3MocGFja2FnZU5hbWUsIGNsYXNzRmlsZU5hbWUsIGNsYXNzTmFtZSk7CisgICAgICAgICAgICBpZiAocmVzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uKGNsYXNzTmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBVUkwgdGhhdCB3aWxsIGJlIGNoZWNrZWQgaWYgaXQgY29udGFpbnMgdGhlIGNsYXNzIG9yIHJlc291cmNlLgorICAgICAqIElmIHRoZSBmaWxlIGNvbXBvbmVudCBvZiB0aGUgVVJMIGlzIG5vdCBhIGRpcmVjdG9yeSwgYSBKYXIgVVJMIHdpbGwgYmUKKyAgICAgKiBjcmVhdGVkLgorICAgICAqCisgICAgICogQHJldHVybiBqYXZhLm5ldC5VUkwgYSB0ZXN0IFVSTAorICAgICAqLworICAgIHByaXZhdGUgVVJMIGNyZWF0ZVNlYXJjaFVSTChVUkwgdXJsKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHVybCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gdXJsOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIHByb3RvY29sID0gdXJsLmdldFByb3RvY29sKCk7CisKKyAgICAgICAgaWYgKGlzRGlyZWN0b3J5KHVybCkgfHwgcHJvdG9jb2wuZXF1YWxzKCJqYXIiKSkgeworICAgICAgICAgICAgcmV0dXJuIHVybDsKKyAgICAgICAgfQorICAgICAgICBpZiAoZmFjdG9yeSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFVSTCgiamFyIiwgIiIsCisgICAgICAgICAgICAgICAgICAgIC0xLCB1cmwudG9TdHJpbmcoKSArICIhLyIpOworICAgICAgICB9CisgICAgICAgIC8vIHVzZSBqYXIgcHJvdG9jb2wgYXMgdGhlIHN0cmVhbSBoYW5kbGVyIHByb3RvY29sCisgICAgICAgIHJldHVybiBuZXcgVVJMKCJqYXIiLCAiIiwKKyAgICAgICAgICAgICAgICAtMSwgdXJsLnRvU3RyaW5nKCkgKyAiIS8iLAorICAgICAgICAgICAgICAgIGZhY3RvcnkuY3JlYXRlVVJMU3RyZWFtSGFuZGxlcigiamFyIikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gVVJMIHJlZmVyZW5jaW5nIHRoZSBzcGVjaWZpZWQgcmVzb3VyY2Ugb3Ige0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqIHJlc291cmNlIGNvdWxkIG5vdCBiZSBmb3VuZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcmVxdWVzdGVkIHJlc291cmNlLgorICAgICAqIEByZXR1cm4gdGhlIFVSTCB3aGljaCBwb2ludHMgdG8gdGhlIGdpdmVuIHJlc291cmNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBVUkwgZmluZFJlc291cmNlKGZpbmFsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGludCBuID0gMDsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIFVSTEhhbmRsZXIgaGFuZGxlciA9IGdldEhhbmRsZXIobisrKTsKKyAgICAgICAgICAgIGlmIChoYW5kbGVyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFVSTCByZXMgPSBoYW5kbGVyLmZpbmRSZXNvdXJjZShuYW1lKTsKKyAgICAgICAgICAgIGlmIChyZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiByZXM7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBVUkxIYW5kbGVyIGdldEhhbmRsZXIoaW50IG51bSkgeworICAgICAgICBpZiAobnVtIDwgaGFuZGxlckxpc3Quc2l6ZSgpKSB7CisgICAgICAgICAgICByZXR1cm4gaGFuZGxlckxpc3QuZ2V0KG51bSk7CisgICAgICAgIH0KKyAgICAgICAgbWFrZU5ld0hhbmRsZXIoKTsKKyAgICAgICAgaWYgKG51bSA8IGhhbmRsZXJMaXN0LnNpemUoKSkgeworICAgICAgICAgICAgcmV0dXJuIGhhbmRsZXJMaXN0LmdldChudW0pOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgbWFrZU5ld0hhbmRsZXIoKSB7CisgICAgICAgIHdoaWxlICghc2VhcmNoTGlzdC5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIFVSTCBuZXh0Q2FuZGlkYXRlID0gc2VhcmNoTGlzdC5yZW1vdmUoMCk7CisgICAgICAgICAgICBpZiAobmV4dENhbmRpZGF0ZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJBIFVSTCBpcyBudWxsIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIWhhbmRsZXJNYXAuY29udGFpbnNLZXkobmV4dENhbmRpZGF0ZSkpIHsKKyAgICAgICAgICAgICAgICBVUkxIYW5kbGVyIHJlc3VsdDsKKyAgICAgICAgICAgICAgICBTdHJpbmcgcHJvdG9jb2wgPSBuZXh0Q2FuZGlkYXRlLmdldFByb3RvY29sKCk7CisgICAgICAgICAgICAgICAgaWYgKHByb3RvY29sLmVxdWFscygiamFyIikpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gY3JlYXRlVVJMSmFySGFuZGxlcihuZXh0Q2FuZGlkYXRlKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHByb3RvY29sLmVxdWFscygiZmlsZSIpKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNyZWF0ZVVSTEZpbGVIYW5kbGVyKG5leHRDYW5kaWRhdGUpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNyZWF0ZVVSTEhhbmRsZXIobmV4dENhbmRpZGF0ZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBoYW5kbGVyTWFwLnB1dChuZXh0Q2FuZGlkYXRlLCByZXN1bHQpOworICAgICAgICAgICAgICAgICAgICBoYW5kbGVyTGlzdC5hZGQocmVzdWx0KTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgVVJMSGFuZGxlciBjcmVhdGVVUkxIYW5kbGVyKFVSTCB1cmwpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBVUkxIYW5kbGVyKHVybCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBVUkxIYW5kbGVyIGNyZWF0ZVVSTEZpbGVIYW5kbGVyKFVSTCB1cmwpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBVUkxGaWxlSGFuZGxlcih1cmwpOworICAgIH0KKworICAgIHByaXZhdGUgVVJMSGFuZGxlciBjcmVhdGVVUkxKYXJIYW5kbGVyKFVSTCB1cmwpIHsKKyAgICAgICAgU3RyaW5nIHByZWZpeE5hbWU7CisgICAgICAgIFN0cmluZyBmaWxlID0gdXJsLmdldEZpbGUoKTsKKyAgICAgICAgaWYgKHVybC5nZXRGaWxlKCkuZW5kc1dpdGgoIiEvIikpIHsKKyAgICAgICAgICAgIHByZWZpeE5hbWUgPSAiIjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGludCBzZXBJZHggPSBmaWxlLmxhc3RJbmRleE9mKCIhLyIpOworICAgICAgICAgICAgaWYgKHNlcElkeCA9PSAtMSkgeworICAgICAgICAgICAgICAgIC8vIEludmFsaWQgVVJMLCBkb24ndCBsb29rIGhlcmUgYWdhaW4KKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNlcElkeCArPSAyOworICAgICAgICAgICAgcHJlZml4TmFtZSA9IGZpbGUuc3Vic3RyaW5nKHNlcElkeCk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFVSTCBqYXJVUkwgPSAoKEphclVSTENvbm5lY3Rpb24pIHVybAorICAgICAgICAgICAgICAgICAgICAub3BlbkNvbm5lY3Rpb24oKSkuZ2V0SmFyRmlsZVVSTCgpOworICAgICAgICAgICAgSmFyVVJMQ29ubmVjdGlvbiBqdWMgPSAoSmFyVVJMQ29ubmVjdGlvbikgbmV3IFVSTCgKKyAgICAgICAgICAgICAgICAgICAgImphciIsICIiLAorICAgICAgICAgICAgICAgICAgICBqYXJVUkwudG9FeHRlcm5hbEZvcm0oKSArICIhLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgICAgICBKYXJGaWxlIGpmID0ganVjLmdldEphckZpbGUoKTsKKyAgICAgICAgICAgIFVSTEphckhhbmRsZXIgamFySCA9IG5ldyBVUkxKYXJIYW5kbGVyKHVybCwgamFyVVJMLCBqZiwgcHJlZml4TmFtZSk7CisKKyAgICAgICAgICAgIGlmIChqYXJILmdldEluZGV4KCkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIE1hbmlmZXN0IG1hbmlmZXN0ID0gamYuZ2V0TWFuaWZlc3QoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG1hbmlmZXN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjbGFzc3BhdGggPSBtYW5pZmVzdC5nZXRNYWluQXR0cmlidXRlcygpLmdldFZhbHVlKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdHRyaWJ1dGVzLk5hbWUuQ0xBU1NfUEFUSCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2xhc3NwYXRoICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWFyY2hMaXN0LmFkZEFsbCgwLCBnZXRJbnRlcm5hbFVSTHModXJsLCBjbGFzc3BhdGgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gamFySDsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlZmluZXMgYSBuZXcgcGFja2FnZSB1c2luZyB0aGUgaW5mb3JtYXRpb24gZXh0cmFjdGVkIGZyb20gdGhlIHNwZWNpZmllZAorICAgICAqIG1hbmlmZXN0LgorICAgICAqCisgICAgICogQHBhcmFtIHBhY2thZ2VOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgbmV3IHBhY2thZ2UuCisgICAgICogQHBhcmFtIG1hbmlmZXN0CisgICAgICogICAgICAgICAgICB0aGUgbWFuaWZlc3QgY29udGFpbmluZyBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIGZvciB0aGUgbmV3CisgICAgICogICAgICAgICAgICBwYWNrYWdlLgorICAgICAqIEBwYXJhbSB1cmwKKyAgICAgKiAgICAgICAgICAgIHRoZSBVUkwgdG8gdGhlIGNvZGUgc291cmNlIGZvciB0aGUgbmV3IHBhY2thZ2UuCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCBwYWNrYWdlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwYWNrYWdlIHdpdGggdGhlIGdpdmVuIG5hbWUgYWxyZWFkeSBleGlzdHMuCisgICAgICovCisgICAgcHJvdGVjdGVkIFBhY2thZ2UgZGVmaW5lUGFja2FnZShTdHJpbmcgcGFja2FnZU5hbWUsIE1hbmlmZXN0IG1hbmlmZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJMIHVybCkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIEF0dHJpYnV0ZXMgbWFpbkF0dHJpYnV0ZXMgPSBtYW5pZmVzdC5nZXRNYWluQXR0cmlidXRlcygpOworICAgICAgICBTdHJpbmcgZGlyTmFtZSA9IHBhY2thZ2VOYW1lLnJlcGxhY2UoJy4nLCAnLycpICsgIi8iOworICAgICAgICBBdHRyaWJ1dGVzIHBhY2thZ2VBdHRyaWJ1dGVzID0gbWFuaWZlc3QuZ2V0QXR0cmlidXRlcyhkaXJOYW1lKTsKKyAgICAgICAgYm9vbGVhbiBub0VudHJ5ID0gZmFsc2U7CisgICAgICAgIGlmIChwYWNrYWdlQXR0cmlidXRlcyA9PSBudWxsKSB7CisgICAgICAgICAgICBub0VudHJ5ID0gdHJ1ZTsKKyAgICAgICAgICAgIHBhY2thZ2VBdHRyaWJ1dGVzID0gbWFpbkF0dHJpYnV0ZXM7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHNwZWNpZmljYXRpb25UaXRsZSA9IHBhY2thZ2VBdHRyaWJ1dGVzCisgICAgICAgICAgICAgICAgLmdldFZhbHVlKEF0dHJpYnV0ZXMuTmFtZS5TUEVDSUZJQ0FUSU9OX1RJVExFKTsKKyAgICAgICAgaWYgKHNwZWNpZmljYXRpb25UaXRsZSA9PSBudWxsICYmICFub0VudHJ5KSB7CisgICAgICAgICAgICBzcGVjaWZpY2F0aW9uVGl0bGUgPSBtYWluQXR0cmlidXRlcworICAgICAgICAgICAgICAgICAgICAuZ2V0VmFsdWUoQXR0cmlidXRlcy5OYW1lLlNQRUNJRklDQVRJT05fVElUTEUpOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBzcGVjaWZpY2F0aW9uVmVyc2lvbiA9IHBhY2thZ2VBdHRyaWJ1dGVzCisgICAgICAgICAgICAgICAgLmdldFZhbHVlKEF0dHJpYnV0ZXMuTmFtZS5TUEVDSUZJQ0FUSU9OX1ZFUlNJT04pOworICAgICAgICBpZiAoc3BlY2lmaWNhdGlvblZlcnNpb24gPT0gbnVsbCAmJiAhbm9FbnRyeSkgeworICAgICAgICAgICAgc3BlY2lmaWNhdGlvblZlcnNpb24gPSBtYWluQXR0cmlidXRlcworICAgICAgICAgICAgICAgICAgICAuZ2V0VmFsdWUoQXR0cmlidXRlcy5OYW1lLlNQRUNJRklDQVRJT05fVkVSU0lPTik7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHNwZWNpZmljYXRpb25WZW5kb3IgPSBwYWNrYWdlQXR0cmlidXRlcworICAgICAgICAgICAgICAgIC5nZXRWYWx1ZShBdHRyaWJ1dGVzLk5hbWUuU1BFQ0lGSUNBVElPTl9WRU5ET1IpOworICAgICAgICBpZiAoc3BlY2lmaWNhdGlvblZlbmRvciA9PSBudWxsICYmICFub0VudHJ5KSB7CisgICAgICAgICAgICBzcGVjaWZpY2F0aW9uVmVuZG9yID0gbWFpbkF0dHJpYnV0ZXMKKyAgICAgICAgICAgICAgICAgICAgLmdldFZhbHVlKEF0dHJpYnV0ZXMuTmFtZS5TUEVDSUZJQ0FUSU9OX1ZFTkRPUik7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIGltcGxlbWVudGF0aW9uVGl0bGUgPSBwYWNrYWdlQXR0cmlidXRlcworICAgICAgICAgICAgICAgIC5nZXRWYWx1ZShBdHRyaWJ1dGVzLk5hbWUuSU1QTEVNRU5UQVRJT05fVElUTEUpOworICAgICAgICBpZiAoaW1wbGVtZW50YXRpb25UaXRsZSA9PSBudWxsICYmICFub0VudHJ5KSB7CisgICAgICAgICAgICBpbXBsZW1lbnRhdGlvblRpdGxlID0gbWFpbkF0dHJpYnV0ZXMKKyAgICAgICAgICAgICAgICAgICAgLmdldFZhbHVlKEF0dHJpYnV0ZXMuTmFtZS5JTVBMRU1FTlRBVElPTl9USVRMRSk7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIGltcGxlbWVudGF0aW9uVmVyc2lvbiA9IHBhY2thZ2VBdHRyaWJ1dGVzCisgICAgICAgICAgICAgICAgLmdldFZhbHVlKEF0dHJpYnV0ZXMuTmFtZS5JTVBMRU1FTlRBVElPTl9WRVJTSU9OKTsKKyAgICAgICAgaWYgKGltcGxlbWVudGF0aW9uVmVyc2lvbiA9PSBudWxsICYmICFub0VudHJ5KSB7CisgICAgICAgICAgICBpbXBsZW1lbnRhdGlvblZlcnNpb24gPSBtYWluQXR0cmlidXRlcworICAgICAgICAgICAgICAgICAgICAuZ2V0VmFsdWUoQXR0cmlidXRlcy5OYW1lLklNUExFTUVOVEFUSU9OX1ZFUlNJT04pOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBpbXBsZW1lbnRhdGlvblZlbmRvciA9IHBhY2thZ2VBdHRyaWJ1dGVzCisgICAgICAgICAgICAgICAgLmdldFZhbHVlKEF0dHJpYnV0ZXMuTmFtZS5JTVBMRU1FTlRBVElPTl9WRU5ET1IpOworICAgICAgICBpZiAoaW1wbGVtZW50YXRpb25WZW5kb3IgPT0gbnVsbCAmJiAhbm9FbnRyeSkgeworICAgICAgICAgICAgaW1wbGVtZW50YXRpb25WZW5kb3IgPSBtYWluQXR0cmlidXRlcworICAgICAgICAgICAgICAgICAgICAuZ2V0VmFsdWUoQXR0cmlidXRlcy5OYW1lLklNUExFTUVOVEFUSU9OX1ZFTkRPUik7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZGVmaW5lUGFja2FnZShwYWNrYWdlTmFtZSwgc3BlY2lmaWNhdGlvblRpdGxlLAorICAgICAgICAgICAgICAgIHNwZWNpZmljYXRpb25WZXJzaW9uLCBzcGVjaWZpY2F0aW9uVmVuZG9yLCBpbXBsZW1lbnRhdGlvblRpdGxlLAorICAgICAgICAgICAgICAgIGltcGxlbWVudGF0aW9uVmVyc2lvbiwgaW1wbGVtZW50YXRpb25WZW5kb3IsIGlzU2VhbGVkKG1hbmlmZXN0LAorICAgICAgICAgICAgICAgIGRpck5hbWUpID8gdXJsIDogbnVsbCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGlzU2VhbGVkKE1hbmlmZXN0IG1hbmlmZXN0LCBTdHJpbmcgZGlyTmFtZSkgeworICAgICAgICBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMgPSBtYW5pZmVzdC5nZXRBdHRyaWJ1dGVzKGRpck5hbWUpOworICAgICAgICBpZiAoYXR0cmlidXRlcyAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBhdHRyaWJ1dGVzLmdldFZhbHVlKEF0dHJpYnV0ZXMuTmFtZS5TRUFMRUQpOworICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuZXF1YWxzSWdub3JlQ2FzZSgidHJ1ZSIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIEF0dHJpYnV0ZXMgbWFpbkF0dHJpYnV0ZXMgPSBtYW5pZmVzdC5nZXRNYWluQXR0cmlidXRlcygpOworICAgICAgICBTdHJpbmcgdmFsdWUgPSBtYWluQXR0cmlidXRlcy5nZXRWYWx1ZShBdHRyaWJ1dGVzLk5hbWUuU0VBTEVEKTsKKyAgICAgICAgcmV0dXJuICh2YWx1ZSAhPSBudWxsICYmIHZhbHVlLmVxdWFsc0lnbm9yZUNhc2UoInRydWUiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogcmV0dXJucyBVUkxzIHJlZmVyZW5jZWQgaW4gdGhlIHN0cmluZyBjbGFzc3BhdGguCisgICAgICoKKyAgICAgKiBAcGFyYW0gcm9vdAorICAgICAqICAgICAgICAgICAgdGhlIGphciBVUkwgdGhhdCBjbGFzc3BhdGggaXMgcmVsYXRlZCB0bworICAgICAqIEBwYXJhbSBjbGFzc3BhdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSByZWxhdGl2ZSBVUkxzIHNlcGFyYXRlZCBieSBzcGFjZXMKKyAgICAgKiBAcmV0dXJuIFVSTFtdIHRoZSBVUkxzIGNvbnRhaW5lZCBpbiB0aGUgc3RyaW5nIGNsYXNzcGF0aC4KKyAgICAgKi8KKyAgICBwcml2YXRlIEFycmF5TGlzdDxVUkw+IGdldEludGVybmFsVVJMcyhVUkwgcm9vdCwgU3RyaW5nIGNsYXNzcGF0aCkgeworICAgICAgICAvLyBDbGFzcy1wYXRoIGF0dHJpYnV0ZSBpcyBjb21wb3NlZCBvZiBzcGFjZS1zZXBhcmF0ZWQgdmFsdWVzLgorICAgICAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5pemVyID0gbmV3IFN0cmluZ1Rva2VuaXplcihjbGFzc3BhdGgpOworICAgICAgICBBcnJheUxpc3Q8VVJMPiBhZGRlZFVSTHMgPSBuZXcgQXJyYXlMaXN0PFVSTD4oKTsKKyAgICAgICAgU3RyaW5nIGZpbGUgPSByb290LmdldEZpbGUoKTsKKyAgICAgICAgaW50IGphckluZGV4ID0gZmlsZS5sYXN0SW5kZXhPZigiIS8iKSAtIDE7CisgICAgICAgIGludCBpbmRleCA9IGZpbGUubGFzdEluZGV4T2YoIi8iLCBqYXJJbmRleCkgKyAxOworICAgICAgICBpZiAoaW5kZXggPT0gMCkgeworICAgICAgICAgICAgaW5kZXggPSBmaWxlLmxhc3RJbmRleE9mKAorICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZ2V0UHJvcGVydHkoImZpbGUuc2VwYXJhdG9yIiksIGphckluZGV4KSArIDE7CisgICAgICAgIH0KKyAgICAgICAgZmlsZSA9IGZpbGUuc3Vic3RyaW5nKDAsIGluZGV4KTsKKyAgICAgICAgd2hpbGUgKHRva2VuaXplci5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgU3RyaW5nIGVsZW1lbnQgPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7CisgICAgICAgICAgICBpZiAoIWVsZW1lbnQuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgLy8gVGFrZSBhYnNvbHV0ZSBwYXRoIGNhc2UgaW50byBjb25zaWRlcmF0aW9uCisgICAgICAgICAgICAgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKG5ldyBVUkwoZmlsZSksIGVsZW1lbnQpOworICAgICAgICAgICAgICAgICAgICBhZGRlZFVSTHMuYWRkKGNyZWF0ZVNlYXJjaFVSTCh1cmwpKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAvLyBOb3RoaW5nIGlzIGFkZGVkCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBhZGRlZFVSTHM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1VSTENvbm5lY3Rpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9VUkxDb25uZWN0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYThkOTY3YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9VUkxDb25uZWN0aW9uLmphdmEKQEAgLTAsMCArMSwxMDQ4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBBIGNvbm5lY3Rpb24gdG8gYSBVUkwgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4gRm9yIEhUVFAgY29ubmVjdGlvbnMsIHNlZQorICoge0BsaW5rIEh0dHBVUkxDb25uZWN0aW9ufSBmb3IgZG9jdW1lbnRhdGlvbiBvZiBIVFRQLXNwZWNpZmljIGZlYXR1cmVzLgorICoKKyAqIDxwPkZvciBleGFtcGxlLCB0byByZXRyaWV2ZSB7QGNvZGUKKyAqIGZ0cDovL21pcnJvci5jc2NsdWIudXdhdGVybG9vLmNhL2luZGV4Lmh0bWx9OiA8cHJlPiAgIHtAY29kZQorICogICBVUkwgdXJsID0gbmV3IFVSTCgiZnRwOi8vbWlycm9yLmNzY2x1Yi51d2F0ZXJsb28uY2EvaW5kZXguaHRtbCIpOworICogICBVUkxDb25uZWN0aW9uIHVybENvbm5lY3Rpb24gPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAqICAgSW5wdXRTdHJlYW0gaW4gPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbSh1cmxDb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCkpOworICogICB0cnkgeworICogICAgIHJlYWRTdHJlYW0oaW4pOworICogICB9IGZpbmFsbHkgeworICogICAgIGluLmNsb3NlKCk7CisgKiAgIH0KKyAqIH08L3ByZT4KKyAqCisgKiA8cD57QGNvZGUgVVJMQ29ubmVjdGlvbn0gbXVzdCBiZSBjb25maWd1cmVkIGJlZm9yZSBpdCBoYXMgY29ubmVjdGVkIHRvIHRoZQorICogcmVtb3RlIHJlc291cmNlLiBJbnN0YW5jZXMgb2Yge0Bjb2RlIFVSTENvbm5lY3Rpb259IGFyZSBub3QgcmV1c2FibGU6IHlvdQorICogbXVzdCB1c2UgYSBkaWZmZXJlbnQgaW5zdGFuY2UgZm9yIGVhY2ggY29ubmVjdGlvbiB0byBhIHJlc291cmNlLgorICoKKyAqIDxoMz5UaW1lb3V0czwvaDM+CisgKiB7QGNvZGUgVVJMQ29ubmVjdGlvbn0gc3VwcG9ydHMgdHdvIHRpbWVvdXRzOiBhIHtAbGluayAjc2V0Q29ubmVjdFRpbWVvdXQKKyAqIGNvbm5lY3QgdGltZW91dH0gYW5kIGEge0BsaW5rICNzZXRSZWFkVGltZW91dCByZWFkIHRpbWVvdXR9LiBCeSBkZWZhdWx0LAorICogb3BlcmF0aW9ucyBuZXZlciB0aW1lIG91dC4KKyAqCisgKiA8aDM+QnVpbHQtaW4gUHJvdG9jb2xzPC9oMz4KKyAqIDx1bD4KKyAqICAgPGxpPjxzdHJvbmc+RmlsZTwvc3Ryb25nPjxicj4KKyAqICAgICAgUmVzb3VyY2VzIGZyb20gdGhlIGxvY2FsIGZpbGUgc3lzdGVtIGNhbiBiZSBsb2FkZWQgdXNpbmcge0Bjb2RlIGZpbGU6fQorICogICAgICBVUklzLiBGaWxlIGNvbm5lY3Rpb25zIGNhbiBvbmx5IGJlIHVzZWQgZm9yIGlucHV0LgorICogICA8bGk+PHN0cm9uZz5GVFA8L3N0cm9uZz48YnI+CisgKiAgICAgIEZpbGUgVHJhbnNmZXIgUHJvdG9jb2wgKDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzk1OS50eHQiPlJGQyA5NTk8L2E+KQorICogICAgICBpcyBzdXBwb3J0ZWQsIGJ1dCB3aXRoIG5vIHB1YmxpYyBzdWJjbGFzcy4gRlRQIGNvbm5lY3Rpb25zIGNhbgorICogICAgICBiZSB1c2VkIGZvciBpbnB1dCBvciBvdXRwdXQgYnV0IG5vdCBib3RoLgorICogICAgICA8cD5CeSBkZWZhdWx0LCBGVFAgY29ubmVjdGlvbnMgd2lsbCBiZSBtYWRlIHVzaW5nIHtAY29kZSBhbm9ueW1vdXN9IGFzCisgKiAgICAgIHRoZSB1c2VybmFtZSBhbmQgdGhlIGVtcHR5IHN0cmluZyBhcyB0aGUgcGFzc3dvcmQuIFNwZWNpZnkgYWx0ZXJuYXRlCisgKiAgICAgIHVzZXJuYW1lcyBhbmQgcGFzc3dvcmRzIGluIHRoZSBVUkw6IHtAY29kZQorICogICAgICBmdHA6Ly91c2VybmFtZTpwYXNzd29yZEBob3N0L3BhdGh9LgorICogICA8bGk+PHN0cm9uZz5IVFRQIGFuZCBIVFRQUzwvc3Ryb25nPjxicj4KKyAqICAgICAgUmVmZXIgdG8gdGhlIHtAbGluayBIdHRwVVJMQ29ubmVjdGlvbn0gYW5kIHtAbGluaworICogICAgICBqYXZheC5uZXQuc3NsLkh0dHBzVVJMQ29ubmVjdGlvbiBIdHRwc1VSTENvbm5lY3Rpb259IHN1YmNsYXNzZXMuCisgKiAgIDxsaT48c3Ryb25nPkphcjwvc3Ryb25nPjxicj4KKyAqICAgICAgUmVmZXIgdG8gdGhlIHtAbGluayBKYXJVUkxDb25uZWN0aW9ufSBzdWJjbGFzcy4KKyAqIDwvdWw+CisgKgorICogPGgzPlJlZ2lzdGVyaW5nIEFkZGl0aW9uYWwgUHJvdG9jb2xzPC9oMz4KKyAqIFVzZSB7QGxpbmsgVVJMI3NldFVSTFN0cmVhbUhhbmRsZXJGYWN0b3J5fSB0byByZWdpc3RlciBoYW5kbGVycyBmb3Igb3RoZXIKKyAqIHByb3RvY29sIHR5cGVzLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgVVJMQ29ubmVjdGlvbiB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgVVJMIHdoaWNoIHJlcHJlc2VudHMgdGhlIHJlbW90ZSB0YXJnZXQgb2YgdGhpcyB7QGNvZGUgVVJMQ29ubmVjdGlvbn0uCisgICAgICovCisgICAgcHJvdGVjdGVkIFVSTCB1cmw7CisKKyAgICBwcml2YXRlIFN0cmluZyBjb250ZW50VHlwZTsKKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gZGVmYXVsdEFsbG93VXNlckludGVyYWN0aW9uOworCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBkZWZhdWx0VXNlQ2FjaGVzID0gdHJ1ZTsKKworICAgIENvbnRlbnRIYW5kbGVyIGRlZmF1bHRIYW5kbGVyID0gbmV3IERlZmF1bHRDb250ZW50SGFuZGxlcigpOworCisgICAgcHJpdmF0ZSBsb25nIGxhc3RNb2RpZmllZCA9IC0xOworCisgICAgLyoqCisgICAgICogVGhlIGRhdGEgbXVzdCBiZSBtb2RpZmllZCBtb3JlIHJlY2VudGx5IHRoYW4gdGhpcyB0aW1lIGluIG1pbGxpc2Vjb25kcworICAgICAqIHNpbmNlIEphbnVhcnkgMSwgMTk3MCwgR01UIHRvIGJlIHRyYW5zbWl0dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBsb25nIGlmTW9kaWZpZWRTaW5jZTsKKworICAgIC8qKgorICAgICAqIFNwZWNpZmllcyB3aGV0aGVyIHRoZSB1c2luZyBvZiBjYWNoZXMgaXMgZW5hYmxlZCBvciB0aGUgZGF0YSBoYXMgdG8gYmUKKyAgICAgKiByZWNlbnQgZm9yIGV2ZXJ5IHJlcXVlc3QuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gdXNlQ2FjaGVzID0gZGVmYXVsdFVzZUNhY2hlczsKKworICAgIC8qKgorICAgICAqIFNwZWNpZmllcyB3aGV0aGVyIHRoaXMge0Bjb2RlIFVSTENvbm5lY3Rpb259IGlzIGFscmVhZHkgY29ubmVjdGVkIHRvIHRoZQorICAgICAqIHJlbW90ZSByZXNvdXJjZS4gSWYgdGhpcyBmaWVsZCBpcyBzZXQgdG8ge0Bjb2RlIHRydWV9IHRoZSBmbGFncyBmb3IKKyAgICAgKiBzZXR0aW5nIHVwIHRoZSBjb25uZWN0aW9uIGFyZSBub3QgY2hhbmdlYWJsZSBhbnltb3JlLgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGNvbm5lY3RlZDsKKworICAgIC8qKgorICAgICAqIFNwZWNpZmllcyB3aGV0aGVyIHRoaXMge0Bjb2RlIFVSTENvbm5lY3Rpb259IGFsbG93cyBzZW5kaW5nIGRhdGEuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gZG9PdXRwdXQ7CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWZpZXMgd2hldGhlciB0aGlzIHtAY29kZSBVUkxDb25uZWN0aW9ufSBhbGxvd3MgcmVjZWl2aW5nIGRhdGEuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gZG9JbnB1dCA9IHRydWU7CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWZpZXMgd2hldGhlciB0aGlzIHtAY29kZSBVUkxDb25uZWN0aW9ufSBhbGxvd3MgdXNlciBpbnRlcmFjdGlvbiBhcworICAgICAqIGl0IGlzIG5lZWRlZCBmb3IgYXV0aGVudGljYXRpb24gcHVycG9zZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gYWxsb3dVc2VySW50ZXJhY3Rpb24gPSBkZWZhdWx0QWxsb3dVc2VySW50ZXJhY3Rpb247CisKKyAgICBwcml2YXRlIHN0YXRpYyBDb250ZW50SGFuZGxlckZhY3RvcnkgY29udGVudEhhbmRsZXJGYWN0b3J5OworCisgICAgcHJpdmF0ZSBpbnQgcmVhZFRpbWVvdXQgPSAwOworCisgICAgcHJpdmF0ZSBpbnQgY29ubmVjdFRpbWVvdXQgPSAwOworCisgICAgLyoqCisgICAgICogQ2FjaGUgZm9yIHN0b3JpbmcgY29udGVudCBoYW5kbGVyCisgICAgICovCisgICAgc3RhdGljIEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4gY29udGVudEhhbmRsZXJzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKKworICAgIC8qKgorICAgICAqIEEgaGFzaHRhYmxlIHRoYXQgbWFwcyB0aGUgZmlsZW5hbWUgZXh0ZW5zaW9uIChrZXkpIHRvIGEgTUlNRS10eXBlCisgICAgICogKGVsZW1lbnQpCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgRmlsZU5hbWVNYXAgZmlsZU5hbWVNYXA7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBVUkxDb25uZWN0aW9ufSBpbnN0YW5jZSBwb2ludGluZyB0byB0aGUgcmVzb3VyY2UKKyAgICAgKiBzcGVjaWZpZWQgYnkgdGhlIGdpdmVuIFVSTC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmwKKyAgICAgKiAgICAgICAgICAgIHRoZSBVUkwgd2hpY2ggcmVwcmVzZW50cyB0aGUgcmVzb3VyY2UgdGhpcyB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFVSTENvbm5lY3Rpb259IHdpbGwgcG9pbnQgdG8uCisgICAgICovCisgICAgcHJvdGVjdGVkIFVSTENvbm5lY3Rpb24oVVJMIHVybCkgeworICAgICAgICB0aGlzLnVybCA9IHVybDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPcGVucyBhIGNvbm5lY3Rpb24gdG8gdGhlIHJlc291cmNlLiBUaGlzIG1ldGhvZCB3aWxsIDxzdHJvbmc+bm90PC9zdHJvbmc+CisgICAgICogcmVjb25uZWN0IHRvIGEgcmVzb3VyY2UgYWZ0ZXIgdGhlIGluaXRpYWwgY29ubmVjdGlvbiBoYXMgYmVlbiBjbG9zZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGNvbm5lY3RpbmcgdG8gdGhlIHJlc291cmNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGNvbm5lY3QoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBvcHRpb24gdmFsdWUgd2hpY2ggaW5kaWNhdGVzIHdoZXRoZXIgdXNlciBpbnRlcmFjdGlvbiBpcyBhbGxvd2VkCisgICAgICogb24gdGhpcyB7QGNvZGUgVVJMQ29ubmVjdGlvbn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgb3B0aW9uIHtAY29kZSBhbGxvd1VzZXJJbnRlcmFjdGlvbn0uCisgICAgICogQHNlZSAjYWxsb3dVc2VySW50ZXJhY3Rpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRBbGxvd1VzZXJJbnRlcmFjdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIGFsbG93VXNlckludGVyYWN0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY29udGVudCBvZiB0aGUgcmVzb3VyY2UgdGhpcyB7QGNvZGUKKyAgICAgKiBVUkxDb25uZWN0aW9ufSBpcyBjb25uZWN0ZWQgdG8uIEZpcnN0LCBpdCBhdHRlbXB0cyB0byBnZXQgdGhlIGNvbnRlbnQKKyAgICAgKiB0eXBlIGZyb20gdGhlIG1ldGhvZCB7QGNvZGUgZ2V0Q29udGVudFR5cGUoKX0gd2hpY2ggbG9va3MgYXQgdGhlIHJlc3BvbnNlCisgICAgICogaGVhZGVyIGZpZWxkICJDb250ZW50LVR5cGUiLiBJZiBub25lIGlzIGZvdW5kIGl0IHdpbGwgZ3Vlc3MgdGhlIGNvbnRlbnQKKyAgICAgKiB0eXBlIGZyb20gdGhlIGZpbGVuYW1lIGV4dGVuc2lvbi4gSWYgdGhhdCBmYWlscyB0aGUgc3RyZWFtIGl0c2VsZiB3aWxsIGJlCisgICAgICogdXNlZCB0byBndWVzcyB0aGUgY29udGVudCB0eXBlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29udGVudCByZXByZXNlbnRpbmcgb2JqZWN0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgb2J0YWluaW5nIHRoZSBjb250ZW50LgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29udGVudCgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFjb25uZWN0ZWQpIHsKKyAgICAgICAgICAgIGNvbm5lY3QoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICgoY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpKSA9PSBudWxsKSB7CisgICAgICAgICAgICBpZiAoKGNvbnRlbnRUeXBlID0gZ3Vlc3NDb250ZW50VHlwZUZyb21OYW1lKHVybC5nZXRGaWxlKCkpKSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY29udGVudFR5cGUgPSBndWVzc0NvbnRlbnRUeXBlRnJvbVN0cmVhbShnZXRJbnB1dFN0cmVhbSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoY29udGVudFR5cGUgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGdldENvbnRlbnRIYW5kbGVyKGNvbnRlbnRUeXBlKS5nZXRDb250ZW50KHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY29udGVudCBvZiB0aGUgcmVzb3VyY2UgdGhpcyB7QGNvZGUKKyAgICAgKiBVUkxDb25uZWN0aW9ufSBpcyBjb25uZWN0ZWQgdG8uIEZpcnN0LCBpdCBhdHRlbXB0cyB0byBnZXQgdGhlIGNvbnRlbnQKKyAgICAgKiB0eXBlIGZyb20gdGhlIG1ldGhvZCB7QGNvZGUgZ2V0Q29udGVudFR5cGUoKX0gd2hpY2ggbG9va3MgYXQgdGhlIHJlc3BvbnNlCisgICAgICogaGVhZGVyIGZpZWxkICJDb250ZW50LVR5cGUiLiBJZiBub25lIGlzIGZvdW5kIGl0IHdpbGwgZ3Vlc3MgdGhlIGNvbnRlbnQKKyAgICAgKiB0eXBlIGZyb20gdGhlIGZpbGVuYW1lIGV4dGVuc2lvbi4gSWYgdGhhdCBmYWlscyB0aGUgc3RyZWFtIGl0c2VsZiB3aWxsIGJlCisgICAgICogdXNlZCB0byBndWVzcyB0aGUgY29udGVudCB0eXBlLiBUaGUgY29udGVudCB0eXBlIG11c3QgbWF0Y2ggd2l0aCBvbmUgb2YKKyAgICAgKiB0aGUgbGlzdCB7QGNvZGUgdHlwZXN9LgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGVzCisgICAgICogICAgICAgICAgICB0aGUgbGlzdCBvZiBhY2NlcHRhYmxlIGNvbnRlbnQgdHlwZXMuCisgICAgICogQHJldHVybiB0aGUgY29udGVudCByZXByZXNlbnRpbmcgb2JqZWN0IG9yIHtAY29kZSBudWxsfSBpZiB0aGUgY29udGVudAorICAgICAqICAgICAgICAgdHlwZSBkb2VzIG5vdCBtYXRjaCB3aXRoIG9uZSBvZiB0aGUgc3BlY2lmaWVkIHR5cGVzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgb2J0YWluaW5nIHRoZSBjb250ZW50LgorICAgICAqLworICAgIC8vIFBhcmFtIGlzIG5vdCBnZW5lcmljIGluIHNwZWMKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgT2JqZWN0IGdldENvbnRlbnQoQ2xhc3NbXSB0eXBlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFjb25uZWN0ZWQpIHsKKyAgICAgICAgICAgIGNvbm5lY3QoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICgoY29udGVudFR5cGUgPSBnZXRDb250ZW50VHlwZSgpKSA9PSBudWxsKSB7CisgICAgICAgICAgICBpZiAoKGNvbnRlbnRUeXBlID0gZ3Vlc3NDb250ZW50VHlwZUZyb21OYW1lKHVybC5nZXRGaWxlKCkpKSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY29udGVudFR5cGUgPSBndWVzc0NvbnRlbnRUeXBlRnJvbVN0cmVhbShnZXRJbnB1dFN0cmVhbSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoY29udGVudFR5cGUgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGdldENvbnRlbnRIYW5kbGVyKGNvbnRlbnRUeXBlKS5nZXRDb250ZW50KHRoaXMsIHR5cGVzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb250ZW50IGVuY29kaW5nIHR5cGUgc3BlY2lmaWVkIGJ5IHRoZSByZXNwb25zZSBoZWFkZXIgZmllbGQKKyAgICAgKiB7QGNvZGUgY29udGVudC1lbmNvZGluZ30gb3Ige0Bjb2RlIG51bGx9IGlmIHRoaXMgZmllbGQgaXMgbm90IHNldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSByZXNwb25zZSBoZWFkZXIgZmllbGQge0Bjb2RlIGNvbnRlbnQtZW5jb2Rpbmd9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29udGVudEVuY29kaW5nKCkgeworICAgICAgICByZXR1cm4gZ2V0SGVhZGVyRmllbGQoIkNvbnRlbnQtRW5jb2RpbmciKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzcGVjaWZpYyBDb250ZW50SGFuZGxlciB0aGF0IHdpbGwgaGFuZGxlIHRoZSB0eXBlIHtAY29kZQorICAgICAqIGNvbnRlbnRUeXBlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICBUaGUgdHlwZSB0aGF0IG5lZWRzIHRvIGJlIGhhbmRsZWQKKyAgICAgKiBAcmV0dXJuIEFuIGluc3RhbmNlIG9mIHRoZSBDb250ZW50IEhhbmRsZXIKKyAgICAgKi8KKyAgICBwcml2YXRlIENvbnRlbnRIYW5kbGVyIGdldENvbnRlbnRIYW5kbGVyKFN0cmluZyB0eXBlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBSZXBsYWNlIGFsbCBub24tYWxwaGFudW1lcmljIGNoYXJhY3RlciBieSAnXycKKyAgICAgICAgZmluYWwgU3RyaW5nIHR5cGVTdHJpbmcgPSBwYXJzZVR5cGVTdHJpbmcodHlwZS5yZXBsYWNlKCcvJywgJy4nKSk7CisKKyAgICAgICAgLy8gaWYgdGhlcmUncyBhIGNhY2hlZCBjb250ZW50IGhhbmRsZXIsIHVzZSBpdAorICAgICAgICBPYmplY3QgY0hhbmRsZXIgPSBjb250ZW50SGFuZGxlcnMuZ2V0KHR5cGUpOworICAgICAgICBpZiAoY0hhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIChDb250ZW50SGFuZGxlcikgY0hhbmRsZXI7CisgICAgICAgIH0KKworICAgICAgICBpZiAoY29udGVudEhhbmRsZXJGYWN0b3J5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGNIYW5kbGVyID0gY29udGVudEhhbmRsZXJGYWN0b3J5LmNyZWF0ZUNvbnRlbnRIYW5kbGVyKHR5cGUpOworICAgICAgICAgICAgY29udGVudEhhbmRsZXJzLnB1dCh0eXBlLCBjSGFuZGxlcik7CisgICAgICAgICAgICByZXR1cm4gKENvbnRlbnRIYW5kbGVyKSBjSGFuZGxlcjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHNlYXJjaCB0aHJvdWdoIHRoZSBwYWNrYWdlIGxpc3QgZm9yIHRoZSByaWdodCBjbGFzcyBmb3IgdGhlIENvbnRlbnQgVHlwZQorICAgICAgICBTdHJpbmcgcGFja2FnZUxpc3QgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuY29udGVudC5oYW5kbGVyLnBrZ3MiKTsKKyAgICAgICAgaWYgKHBhY2thZ2VMaXN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIHBhY2thZ2VOYW1lIDogcGFja2FnZUxpc3Quc3BsaXQoIlxcfCIpKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9IHBhY2thZ2VOYW1lICsgIi4iICsgdHlwZVN0cmluZzsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBDbGFzczw/PiBrbGFzcyA9IENsYXNzLmZvck5hbWUoY2xhc3NOYW1lLCB0cnVlLCBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpKTsKKyAgICAgICAgICAgICAgICAgICAgY0hhbmRsZXIgPSBrbGFzcy5uZXdJbnN0YW5jZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChjSGFuZGxlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIFRyeSBsb29raW5nIHVwIEFXVCBpbWFnZSBjb250ZW50IGhhbmRsZXJzCisgICAgICAgICAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9ICJvcmcuYXBhY2hlLmhhcm1vbnkuYXd0Lnd3dy5jb250ZW50LiIgKyB0eXBlU3RyaW5nOworICAgICAgICAgICAgICAgIGNIYW5kbGVyID0gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUpLm5ld0luc3RhbmNlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfSBjYXRjaCAoSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmICghKGNIYW5kbGVyIGluc3RhbmNlb2YgQ29udGVudEhhbmRsZXIpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVua25vd25TZXJ2aWNlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb250ZW50SGFuZGxlcnMucHV0KHR5cGUsIGNIYW5kbGVyKTsgLy8gaWYgd2UgZ290IHRoZSBoYW5kbGVyLAorICAgICAgICAgICAgLy8gY2FjaGUgaXQgZm9yIG5leHQgdGltZQorICAgICAgICAgICAgcmV0dXJuIChDb250ZW50SGFuZGxlcikgY0hhbmRsZXI7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZGVmYXVsdEhhbmRsZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29udGVudCBsZW5ndGggaW4gYnl0ZXMgc3BlY2lmaWVkIGJ5IHRoZSByZXNwb25zZSBoZWFkZXIgZmllbGQKKyAgICAgKiB7QGNvZGUgY29udGVudC1sZW5ndGh9IG9yIHtAY29kZSAtMX0gaWYgdGhpcyBmaWVsZCBpcyBub3Qgc2V0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHJlc3BvbnNlIGhlYWRlciBmaWVsZCB7QGNvZGUgY29udGVudC1sZW5ndGh9LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Q29udGVudExlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIGdldEhlYWRlckZpZWxkSW50KCJDb250ZW50LUxlbmd0aCIsIC0xKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBNSU1FLXR5cGUgb2YgdGhlIGNvbnRlbnQgc3BlY2lmaWVkIGJ5IHRoZSByZXNwb25zZSBoZWFkZXIgZmllbGQKKyAgICAgKiB7QGNvZGUgY29udGVudC10eXBlfSBvciB7QGNvZGUgbnVsbH0gaWYgdHlwZSBpcyB1bmtub3duLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHJlc3BvbnNlIGhlYWRlciBmaWVsZCB7QGNvZGUgY29udGVudC10eXBlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgeworICAgICAgICByZXR1cm4gZ2V0SGVhZGVyRmllbGQoIkNvbnRlbnQtVHlwZSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRpbWVzdGFtcCB3aGVuIHRoaXMgcmVzcG9uc2UgaGFzIGJlZW4gc2VudCBhcyBhIGRhdGUgaW4KKyAgICAgKiBtaWxsaXNlY29uZHMgc2luY2UgSmFudWFyeSAxLCAxOTcwIEdNVCBvciB7QGNvZGUgMH0gaWYgdGhpcyB0aW1lc3RhbXAgaXMKKyAgICAgKiB1bmtub3duLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc2VuZGluZyB0aW1lc3RhbXAgb2YgdGhlIGN1cnJlbnQgcmVzcG9uc2UuCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0RGF0ZSgpIHsKKyAgICAgICAgcmV0dXJuIGdldEhlYWRlckZpZWxkRGF0ZSgiRGF0ZSIsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgc2V0dGluZyB3aGV0aGVyIHRoaXMgY29ubmVjdGlvbiBhbGxvd3MgdXNlciBpbnRlcmFjdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBkZWZhdWx0IHNldHRpbmcge0Bjb2RlCisgICAgICogICAgICAgICBkZWZhdWx0QWxsb3dVc2VySW50ZXJhY3Rpb259LgorICAgICAqIEBzZWUgI2FsbG93VXNlckludGVyYWN0aW9uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGdldERlZmF1bHRBbGxvd1VzZXJJbnRlcmFjdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIGRlZmF1bHRBbGxvd1VzZXJJbnRlcmFjdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIG51bGwuCisgICAgICoKKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNnZXRSZXF1ZXN0UHJvcGVydHl9CisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXREZWZhdWx0UmVxdWVzdFByb3BlcnR5KFN0cmluZyBmaWVsZCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHNldHRpbmcgd2hldGhlciB0aGlzIGNvbm5lY3Rpb24gYWxsb3dzIHVzaW5nIGNhY2hlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBkZWZhdWx0IHNldHRpbmcge0Bjb2RlIGRlZmF1bHRVc2VDYWNoZXN9LgorICAgICAqIEBzZWUgI3VzZUNhY2hlcworICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldERlZmF1bHRVc2VDYWNoZXMoKSB7CisgICAgICAgIHJldHVybiBkZWZhdWx0VXNlQ2FjaGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBvcHRpb24ge0Bjb2RlIGRvSW5wdXR9IHdoaWNoIHNwZWNpZmllcyB3aGV0aGVyIHRoaXMKKyAgICAgKiBjb25uZWN0aW9uIGFsbG93cyB0byByZWNlaXZlIGRhdGEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGNvbm5lY3Rpb24gYWxsb3dzIGlucHV0LCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHNlZSAjZG9JbnB1dAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldERvSW5wdXQoKSB7CisgICAgICAgIHJldHVybiBkb0lucHV0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBvcHRpb24ge0Bjb2RlIGRvT3V0cHV0fSB3aGljaCBzcGVjaWZpZXMgd2hldGhlcgorICAgICAqIHRoaXMgY29ubmVjdGlvbiBhbGxvd3MgdG8gc2VuZCBkYXRhLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBjb25uZWN0aW9uIGFsbG93cyBvdXRwdXQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNkb091dHB1dAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldERvT3V0cHV0KCkgeworICAgICAgICByZXR1cm4gZG9PdXRwdXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGltZXN0YW1wIHdoZW4gdGhpcyByZXNwb25zZSB3aWxsIGJlIGV4cGlyZWQgaW4gbWlsbGlzZWNvbmRzCisgICAgICogc2luY2UgSmFudWFyeSAxLCAxOTcwIEdNVCBvciB7QGNvZGUgMH0gaWYgdGhpcyB0aW1lc3RhbXAgaXMgdW5rbm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSByZXNwb25zZSBoZWFkZXIgZmllbGQge0Bjb2RlIGV4cGlyZXN9LgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldEV4cGlyYXRpb24oKSB7CisgICAgICAgIHJldHVybiBnZXRIZWFkZXJGaWVsZERhdGUoIkV4cGlyZXMiLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0YWJsZSB3aGljaCBpcyB1c2VkIGJ5IGFsbCB7QGNvZGUgVVJMQ29ubmVjdGlvbn0gaW5zdGFuY2VzIHRvCisgICAgICogZGV0ZXJtaW5lIHRoZSBNSU1FLXR5cGUgYWNjb3JkaW5nIHRvIGEgZmlsZSBleHRlbnNpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBmaWxlIG5hbWUgbWFwIHRvIGRldGVybWluZSB0aGUgTUlNRS10eXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgRmlsZU5hbWVNYXAgZ2V0RmlsZU5hbWVNYXAoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoVVJMQ29ubmVjdGlvbi5jbGFzcykgeworICAgICAgICAgICAgaWYgKGZpbGVOYW1lTWFwID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmaWxlTmFtZU1hcCA9IG5ldyBEZWZhdWx0RmlsZU5hbWVNYXAoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmaWxlTmFtZU1hcDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhlYWRlciB2YWx1ZSBhdCB0aGUgZmllbGQgcG9zaXRpb24ge0Bjb2RlIHBvc30gb3Ige0Bjb2RlIG51bGx9CisgICAgICogaWYgdGhlIGhlYWRlciBoYXMgZmV3ZXIgdGhhbiB7QGNvZGUgcG9zfSBmaWVsZHMuIFRoZSBiYXNlCisgICAgICogaW1wbGVtZW50YXRpb24gb2YgdGhpcyBtZXRob2QgcmV0dXJucyBhbHdheXMge0Bjb2RlIG51bGx9LgorICAgICAqCisgICAgICogPHA+U29tZSBpbXBsZW1lbnRhdGlvbnMgKG5vdGFibHkge0Bjb2RlIEh0dHBVUkxDb25uZWN0aW9ufSkgaW5jbHVkZSBhIG1hcHBpbmcKKyAgICAgKiBmb3IgdGhlIG51bGwga2V5OyBpbiBIVFRQJ3MgY2FzZSwgdGhpcyBtYXBzIHRvIHRoZSBIVFRQIHN0YXR1cyBsaW5lIGFuZCBpcworICAgICAqIHRyZWF0ZWQgYXMgYmVpbmcgYXQgcG9zaXRpb24gMCB3aGVuIGluZGV4aW5nIGludG8gdGhlIGhlYWRlciBmaWVsZHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcG9zCisgICAgICogICAgICAgICAgICB0aGUgZmllbGQgcG9zaXRpb24gb2YgdGhlIHJlc3BvbnNlIGhlYWRlci4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQgYXQgcG9zaXRpb24ge0Bjb2RlIHBvc30uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRIZWFkZXJGaWVsZChpbnQgcG9zKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gdW5tb2RpZmlhYmxlIG1hcCBvZiB0aGUgcmVzcG9uc2UtaGVhZGVyIGZpZWxkcyBhbmQgdmFsdWVzLiBUaGUKKyAgICAgKiByZXNwb25zZS1oZWFkZXIgZmllbGQgbmFtZXMgYXJlIHRoZSBrZXkgdmFsdWVzIG9mIHRoZSBtYXAuIFRoZSBtYXAgdmFsdWVzCisgICAgICogYXJlIGxpc3RzIG9mIGhlYWRlciBmaWVsZCB2YWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGEgcGFydGljdWxhciBrZXkgbmFtZS4KKyAgICAgKgorICAgICAqIDxwPlNvbWUgaW1wbGVtZW50YXRpb25zIChub3RhYmx5IHtAY29kZSBIdHRwVVJMQ29ubmVjdGlvbn0pIGluY2x1ZGUgYSBtYXBwaW5nCisgICAgICogZm9yIHRoZSBudWxsIGtleTsgaW4gSFRUUCdzIGNhc2UsIHRoaXMgbWFwcyB0byB0aGUgSFRUUCBzdGF0dXMgbGluZSBhbmQgaXMKKyAgICAgKiB0cmVhdGVkIGFzIGJlaW5nIGF0IHBvc2l0aW9uIDAgd2hlbiBpbmRleGluZyBpbnRvIHRoZSBoZWFkZXIgZmllbGRzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVzcG9uc2UtaGVhZGVyIHJlcHJlc2VudGluZyBnZW5lcmljIG1hcC4KKyAgICAgKiBAc2luY2UgMS40CisgICAgICovCisgICAgcHVibGljIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gZ2V0SGVhZGVyRmllbGRzKCkgeworICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW1wdHlNYXAoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIHVubW9kaWZpYWJsZSBtYXAgb2YgZ2VuZXJhbCByZXF1ZXN0IHByb3BlcnRpZXMgdXNlZCBieSB0aGlzCisgICAgICogY29ubmVjdGlvbi4gVGhlIHJlcXVlc3QgcHJvcGVydHkgbmFtZXMgYXJlIHRoZSBrZXkgdmFsdWVzIG9mIHRoZSBtYXAuIFRoZQorICAgICAqIG1hcCB2YWx1ZXMgYXJlIGxpc3RzIG9mIHByb3BlcnR5IHZhbHVlcyBvZiB0aGUgY29ycmVzcG9uZGluZyBrZXkgbmFtZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QtcHJvcGVydHkgcmVwcmVzZW50aW5nIGdlbmVyaWMgbWFwLgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PiBnZXRSZXF1ZXN0UHJvcGVydGllcygpIHsKKyAgICAgICAgY2hlY2tOb3RDb25uZWN0ZWQoKTsKKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5TWFwKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrTm90Q29ubmVjdGVkKCkgeworICAgICAgICBpZiAoY29ubmVjdGVkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJBbHJlYWR5IGNvbm5lY3RlZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgZ2l2ZW4gcHJvcGVydHkgdG8gdGhlIHJlcXVlc3QgaGVhZGVyLiBFeGlzdGluZyBwcm9wZXJ0aWVzIHdpdGgKKyAgICAgKiB0aGUgc2FtZSBuYW1lIHdpbGwgbm90IGJlIG92ZXJ3cml0dGVuIGJ5IHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICB0aGUgcmVxdWVzdCBwcm9wZXJ0eSBmaWVsZCBuYW1lIHRvIGFkZC4KKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgd2hpY2ggaXMgdG8gYWRkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNvbm5lY3Rpb24gaGFzIGJlZW4gYWxyZWFkeSBlc3RhYmxpc2hlZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHByb3BlcnR5IG5hbWUgaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRSZXF1ZXN0UHJvcGVydHkoU3RyaW5nIGZpZWxkLCBTdHJpbmcgbmV3VmFsdWUpIHsKKyAgICAgICAgY2hlY2tOb3RDb25uZWN0ZWQoKTsKKyAgICAgICAgaWYgKGZpZWxkID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiZmllbGQgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGhlYWRlciBmaWVsZCBzcGVjaWZpZWQgYnkge0Bjb2RlIGtleX0gb3Ige0Bjb2RlCisgICAgICogbnVsbH0gaWYgdGhlcmUgaXMgbm8gZmllbGQgd2l0aCB0aGlzIG5hbWUuIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mCisgICAgICogdGhpcyBtZXRob2QgcmV0dXJucyBhbHdheXMge0Bjb2RlIG51bGx9LgorICAgICAqCisgICAgICogPHA+U29tZSBpbXBsZW1lbnRhdGlvbnMgKG5vdGFibHkge0Bjb2RlIEh0dHBVUkxDb25uZWN0aW9ufSkgaW5jbHVkZSBhIG1hcHBpbmcKKyAgICAgKiBmb3IgdGhlIG51bGwga2V5OyBpbiBIVFRQJ3MgY2FzZSwgdGhpcyBtYXBzIHRvIHRoZSBIVFRQIHN0YXR1cyBsaW5lIGFuZCBpcworICAgICAqIHRyZWF0ZWQgYXMgYmVpbmcgYXQgcG9zaXRpb24gMCB3aGVuIGluZGV4aW5nIGludG8gdGhlIGhlYWRlciBmaWVsZHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgaGVhZGVyIGZpZWxkLgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBoZWFkZXIgZmllbGQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRIZWFkZXJGaWVsZChTdHJpbmcga2V5KSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNwZWNpZmllZCBoZWFkZXIgdmFsdWUgYXMgYSBkYXRlIGluIG1pbGxpc2Vjb25kcyBzaW5jZSBKYW51YXJ5CisgICAgICogMSwgMTk3MCBHTVQuIFJldHVybnMgdGhlIHtAY29kZSBkZWZhdWx0VmFsdWV9IGlmIG5vIHN1Y2ggaGVhZGVyIGZpZWxkCisgICAgICogY291bGQgYmUgZm91bmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmllbGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBoZWFkZXIgZmllbGQgbmFtZSB3aG9zZSB2YWx1ZSBpcyBuZWVkZWQuCisgICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgdmFsdWUgaWYgbm8gZmllbGQgaGFzIGJlZW4gZm91bmQuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBoZWFkZXIgZmllbGQgYXMgYSBkYXRlIGluCisgICAgICogICAgICAgICBtaWxsaXNlY29uZHMuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgbG9uZyBnZXRIZWFkZXJGaWVsZERhdGUoU3RyaW5nIGZpZWxkLCBsb25nIGRlZmF1bHRWYWx1ZSkgeworICAgICAgICBTdHJpbmcgZGF0ZSA9IGdldEhlYWRlckZpZWxkKGZpZWxkKTsKKyAgICAgICAgaWYgKGRhdGUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIERhdGUucGFyc2UoZGF0ZSk7IC8vIFRPRE86IHVzZSBIdHRwRGF0ZS5wYXJzZSgpCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3BlY2lmaWVkIGhlYWRlciB2YWx1ZSBhcyBhIG51bWJlci4gUmV0dXJucyB0aGUge0Bjb2RlCisgICAgICogZGVmYXVsdFZhbHVlfSBpZiBubyBzdWNoIGhlYWRlciBmaWVsZCBjb3VsZCBiZSBmb3VuZCBvciB0aGUgdmFsdWUgY291bGQKKyAgICAgKiBub3QgYmUgcGFyc2VkIGFzIGFuIHtAY29kZSBJbnRlZ2VyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgdGhlIGhlYWRlciBmaWVsZCBuYW1lIHdob3NlIHZhbHVlIGlzIG5lZWRlZC4KKyAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgZGVmYXVsdCB2YWx1ZSBpZiBubyBmaWVsZCBoYXMgYmVlbiBmb3VuZC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGhlYWRlciBmaWVsZCBhcyBhIG51bWJlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEhlYWRlckZpZWxkSW50KFN0cmluZyBmaWVsZCwgaW50IGRlZmF1bHRWYWx1ZSkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIEludGVnZXIucGFyc2VJbnQoZ2V0SGVhZGVyRmllbGQoZmllbGQpKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBoZWFkZXIgZmllbGQgYXQgdGhlIGdpdmVuIHBvc2l0aW9uIHtAY29kZSBwb3NufSBvcgorICAgICAqIHtAY29kZSBudWxsfSBpZiB0aGVyZSBhcmUgZmV3ZXIgdGhhbiB7QGNvZGUgcG9zbn0gZmllbGRzLiBUaGUgYmFzZQorICAgICAqIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kIHJldHVybnMgYWx3YXlzIHtAY29kZSBudWxsfS4KKyAgICAgKgorICAgICAqIDxwPlNvbWUgaW1wbGVtZW50YXRpb25zIChub3RhYmx5IHtAY29kZSBIdHRwVVJMQ29ubmVjdGlvbn0pIGluY2x1ZGUgYSBtYXBwaW5nCisgICAgICogZm9yIHRoZSBudWxsIGtleTsgaW4gSFRUUCdzIGNhc2UsIHRoaXMgbWFwcyB0byB0aGUgSFRUUCBzdGF0dXMgbGluZSBhbmQgaXMKKyAgICAgKiB0cmVhdGVkIGFzIGJlaW5nIGF0IHBvc2l0aW9uIDAgd2hlbiBpbmRleGluZyBpbnRvIHRoZSBoZWFkZXIgZmllbGRzLgorICAgICAqCisgICAgICogQHBhcmFtIHBvc24KKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3NpdGlvbiBvZiB0aGUgaGVhZGVyIGZpZWxkIHdoaWNoIGhhcyB0byBiZSByZXR1cm5lZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBoZWFkZXIgZmllbGQgbmFtZSBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRIZWFkZXJGaWVsZEtleShpbnQgcG9zbikgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwb2ludCBvZiB0aW1lIHNpbmNlIHdoZW4gdGhlIGRhdGEgbXVzdCBiZSBtb2RpZmllZCB0byBiZQorICAgICAqIHRyYW5zbWl0dGVkLiBTb21lIHByb3RvY29scyB0cmFuc21pdCBkYXRhIG9ubHkgaWYgaXQgaGFzIGJlZW4gbW9kaWZpZWQKKyAgICAgKiBtb3JlIHJlY2VudGx5IHRoYW4gYSBwYXJ0aWN1bGFyIHRpbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB0aW1lIGluIG1pbGxpc2Vjb25kcyBzaW5jZSBKYW51YXJ5IDEsIDE5NzAgR01ULgorICAgICAqIEBzZWUgI2lmTW9kaWZpZWRTaW5jZQorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldElmTW9kaWZpZWRTaW5jZSgpIHsKKyAgICAgICAgcmV0dXJuIGlmTW9kaWZpZWRTaW5jZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIHtAY29kZSBJbnB1dFN0cmVhbX0gZm9yIHJlYWRpbmcgZGF0YSBmcm9tIHRoZSByZXNvdXJjZSBwb2ludGVkIGJ5CisgICAgICogdGhpcyB7QGNvZGUgVVJMQ29ubmVjdGlvbn0uIEl0IHRocm93cyBhbiBVbmtub3duU2VydmljZUV4Y2VwdGlvbiBieQorICAgICAqIGRlZmF1bHQuIFRoaXMgbWV0aG9kIG11c3QgYmUgb3ZlcnJpZGRlbiBieSBpdHMgc3ViY2xhc3Nlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIElucHV0U3RyZWFtIHRvIHJlYWQgZGF0YSBmcm9tLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBJbnB1dFN0cmVhbSBjb3VsZCBiZSBjcmVhdGVkLgorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbmtub3duU2VydmljZUV4Y2VwdGlvbigiRG9lcyBub3Qgc3VwcG9ydCB3cml0aW5nIHRvIHRoZSBpbnB1dCBzdHJlYW0iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgcmVzcG9uc2UgaGVhZGVyIGZpZWxkIHtAY29kZSBsYXN0LW1vZGlmaWVkfSBvcgorICAgICAqIHtAY29kZSAwfSBpZiB0aGlzIHZhbHVlIGlzIG5vdCBzZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUge0Bjb2RlIGxhc3QtbW9kaWZpZWR9IGhlYWRlciBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRMYXN0TW9kaWZpZWQoKSB7CisgICAgICAgIGlmIChsYXN0TW9kaWZpZWQgIT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiBsYXN0TW9kaWZpZWQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGxhc3RNb2RpZmllZCA9IGdldEhlYWRlckZpZWxkRGF0ZSgiTGFzdC1Nb2RpZmllZCIsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4ge0Bjb2RlIE91dHB1dFN0cmVhbX0gZm9yIHdyaXRpbmcgZGF0YSB0byB0aGlzIHtAY29kZQorICAgICAqIFVSTENvbm5lY3Rpb259LiBJdCB0aHJvd3MgYW4ge0Bjb2RlIFVua25vd25TZXJ2aWNlRXhjZXB0aW9ufSBieSBkZWZhdWx0LgorICAgICAqIFRoaXMgbWV0aG9kIG11c3QgYmUgb3ZlcnJpZGRlbiBieSBpdHMgc3ViY2xhc3Nlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIE91dHB1dFN0cmVhbSB0byB3cml0ZSBkYXRhLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBPdXRwdXRTdHJlYW0gY291bGQgYmUgY3JlYXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgT3V0cHV0U3RyZWFtIGdldE91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbmtub3duU2VydmljZUV4Y2VwdGlvbigiRG9lcyBub3Qgc3VwcG9ydCB3cml0aW5nIHRvIHRoZSBvdXRwdXQgc3RyZWFtIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBQZXJtaXNzaW9ufSBvYmplY3QgcmVwcmVzZW50aW5nIGFsbCBuZWVkZWQgcGVybWlzc2lvbnMgdG8KKyAgICAgKiBvcGVuIHRoaXMgY29ubmVjdGlvbi4gVGhlIHJldHVybmVkIHBlcm1pc3Npb24gb2JqZWN0IGRlcGVuZHMgb24gdGhlIHN0YXRlCisgICAgICogb2YgdGhlIGNvbm5lY3Rpb24gYW5kIHdpbGwgYmUge0Bjb2RlIG51bGx9IGlmIG5vIHBlcm1pc3Npb25zIGFyZQorICAgICAqIG5lY2Vzc2FyeS4gQnkgZGVmYXVsdCwgdGhpcyBtZXRob2QgcmV0dXJucyB7QGNvZGUgQWxsUGVybWlzc2lvbn0uCisgICAgICogU3ViY2xhc3NlcyBzaG91bGQgb3ZlcndyaXRlIHRoaXMgbWV0aG9kIHRvIHJldHVybiBhbiBhcHByb3ByaWF0ZQorICAgICAqIHBlcm1pc3Npb24gb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcGVybWlzc2lvbiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBuZWVkZWQgcGVybWlzc2lvbnMgdG8gb3BlbgorICAgICAqICAgICAgICAgdGhpcyBjb25uZWN0aW9uLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIGNyZWF0aW5nIHRoZSBwZXJtaXNzaW9uIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uIGdldFBlcm1pc3Npb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3IGphdmEuc2VjdXJpdHkuQWxsUGVybWlzc2lvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSByZXF1ZXN0IGhlYWRlciBwcm9wZXJ0eSBzcGVjaWZpZWQgYnkge2NvZGUgZmllbGR9CisgICAgICogb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIG5vIGZpZWxkIHdpdGggdGhpcyBuYW1lLiBUaGUgYmFzZQorICAgICAqIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kIHJldHVybnMgYWx3YXlzIHtAY29kZSBudWxsfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlcXVlc3QgaGVhZGVyIHByb3BlcnR5LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjb25uZWN0aW9uIGhhcyBiZWVuIGFscmVhZHkgZXN0YWJsaXNoZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRSZXF1ZXN0UHJvcGVydHkoU3RyaW5nIGZpZWxkKSB7CisgICAgICAgIGNoZWNrTm90Q29ubmVjdGVkKCk7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIFVSTCByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBVUkxDb25uZWN0aW9ufS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIFVSTCBvZiB0aGlzIGNvbm5lY3Rpb24uCisgICAgICovCisgICAgcHVibGljIFVSTCBnZXRVUkwoKSB7CisgICAgICAgIHJldHVybiB1cmw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGZsYWcgd2hpY2ggc3BlY2lmaWVzIHdoZXRoZXIgdGhpcyB7QGNvZGUKKyAgICAgKiBVUkxDb25uZWN0aW9ufSBhbGxvd3MgdG8gdXNlIGNhY2hlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHVzaW5nIGNhY2hlcyBpcyBhbGxvd2VkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRVc2VDYWNoZXMoKSB7CisgICAgICAgIHJldHVybiB1c2VDYWNoZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB0aGUgTUlNRS10eXBlIG9mIHRoZSBnaXZlbiByZXNvdXJjZSB7QGNvZGUgdXJsfSBieSByZXNvbHZpbmcKKyAgICAgKiB0aGUgZmlsZW5hbWUgZXh0ZW5zaW9uIHdpdGggdGhlIGludGVybmFsIEZpbGVOYW1lTWFwLiBBbnkgZnJhZ21lbnQKKyAgICAgKiBpZGVudGlmaWVyIGlzIHJlbW92ZWQgYmVmb3JlIHByb2Nlc3NpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJsCisgICAgICogICAgICAgICAgICB0aGUgVVJMIHdpdGggdGhlIGZpbGVuYW1lIHRvIGdldCB0aGUgTUlNRSB0eXBlLgorICAgICAqIEByZXR1cm4gdGhlIGd1ZXNzZWQgY29udGVudCB0eXBlIG9yIHtAY29kZSBudWxsfSBpZiB0aGUgdHlwZSBjb3VsZCBub3QgYmUKKyAgICAgKiAgICAgICAgIGRldGVybWluZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ3Vlc3NDb250ZW50VHlwZUZyb21OYW1lKFN0cmluZyB1cmwpIHsKKyAgICAgICAgcmV0dXJuIGdldEZpbGVOYW1lTWFwKCkuZ2V0Q29udGVudFR5cGVGb3IodXJsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHRoZSBNSU1FLXR5cGUgb2YgdGhlIHJlc291cmNlIHJlcHJlc2VudGVkIGJ5IHRoZSBpbnB1dCBzdHJlYW0KKyAgICAgKiB7QGNvZGUgaXN9IGJ5IHJlYWRpbmcgaXRzIGZpcnN0IGZldyBjaGFyYWN0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGlzCisgICAgICogICAgICAgICAgICB0aGUgcmVzb3VyY2UgcmVwcmVzZW50aW5nIGlucHV0IHN0cmVhbSB0byBkZXRlcm1pbmUgdGhlCisgICAgICogICAgICAgICAgICBjb250ZW50IHR5cGUuCisgICAgICogQHJldHVybiB0aGUgZ3Vlc3NlZCBjb250ZW50IHR5cGUgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZSB0eXBlIGNvdWxkIG5vdCBiZQorICAgICAqICAgICAgICAgZGV0ZXJtaW5lZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBndWVzc0NvbnRlbnRUeXBlRnJvbVN0cmVhbShJbnB1dFN0cmVhbSBpcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpcy5tYXJrU3VwcG9ydGVkKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIC8vIExvb2sgYWhlYWQgdXAgdG8gNjQgYnl0ZXMgZm9yIHRoZSBsb25nZXN0IGVuY29kZWQgaGVhZGVyCisgICAgICAgIGlzLm1hcmsoNjQpOworICAgICAgICBieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVs2NF07CisgICAgICAgIGludCBsZW5ndGggPSBpcy5yZWFkKGJ5dGVzKTsKKyAgICAgICAgaXMucmVzZXQoKTsKKworICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBkYXRhIGZyb20gdGhlIGlucHV0IHN0cmVhbSwgd2UgY2FuJ3QgZGV0ZXJtaW5lIGNvbnRlbnQgdHlwZS4KKyAgICAgICAgaWYgKGxlbmd0aCA9PSAtMSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvLyBDaGVjayBmb3IgVW5pY29kZSBCT00gZW5jb2RpbmcgaW5kaWNhdG9ycworICAgICAgICBTdHJpbmcgZW5jb2RpbmcgPSAiVVMtQVNDSUkiOworICAgICAgICBpbnQgc3RhcnQgPSAwOworICAgICAgICBpZiAobGVuZ3RoID4gMSkgeworICAgICAgICAgICAgaWYgKChieXRlc1swXSA9PSAoYnl0ZSkgMHhGRikgJiYgKGJ5dGVzWzFdID09IChieXRlKSAweEZFKSkgeworICAgICAgICAgICAgICAgIGVuY29kaW5nID0gIlVURi0xNkxFIjsKKyAgICAgICAgICAgICAgICBzdGFydCA9IDI7CisgICAgICAgICAgICAgICAgbGVuZ3RoIC09IGxlbmd0aCAmIDE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoKGJ5dGVzWzBdID09IChieXRlKSAweEZFKSAmJiAoYnl0ZXNbMV0gPT0gKGJ5dGUpIDB4RkYpKSB7CisgICAgICAgICAgICAgICAgZW5jb2RpbmcgPSAiVVRGLTE2QkUiOworICAgICAgICAgICAgICAgIHN0YXJ0ID0gMjsKKyAgICAgICAgICAgICAgICBsZW5ndGggLT0gbGVuZ3RoICYgMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChsZW5ndGggPiAyKSB7CisgICAgICAgICAgICAgICAgaWYgKChieXRlc1swXSA9PSAoYnl0ZSkgMHhFRikgJiYgKGJ5dGVzWzFdID09IChieXRlKSAweEJCKQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgKGJ5dGVzWzJdID09IChieXRlKSAweEJGKSkgeworICAgICAgICAgICAgICAgICAgICBlbmNvZGluZyA9ICJVVEYtOCI7CisgICAgICAgICAgICAgICAgICAgIHN0YXJ0ID0gMzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGxlbmd0aCA+IDMpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKChieXRlc1swXSA9PSAoYnl0ZSkgMHgwMCkgJiYgKGJ5dGVzWzFdID09IChieXRlKSAweDAwKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIChieXRlc1syXSA9PSAoYnl0ZSkgMHhGRSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAoYnl0ZXNbM10gPT0gKGJ5dGUpIDB4RkYpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGluZyA9ICJVVEYtMzJCRSI7CisgICAgICAgICAgICAgICAgICAgICAgICBzdGFydCA9IDQ7CisgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggLT0gbGVuZ3RoICYgMzsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoKGJ5dGVzWzBdID09IChieXRlKSAweEZGKSAmJiAoYnl0ZXNbMV0gPT0gKGJ5dGUpIDB4RkUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKGJ5dGVzWzJdID09IChieXRlKSAweDAwKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIChieXRlc1szXSA9PSAoYnl0ZSkgMHgwMCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGVuY29kaW5nID0gIlVURi0zMkxFIjsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0ID0gNDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCAtPSBsZW5ndGggJiAzOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGhlYWRlciA9IG5ldyBTdHJpbmcoYnl0ZXMsIHN0YXJ0LCBsZW5ndGggLSBzdGFydCwgZW5jb2RpbmcpOworCisgICAgICAgIC8vIENoZWNrIGJpbmFyeSB0eXBlcworICAgICAgICBpZiAoaGVhZGVyLnN0YXJ0c1dpdGgoIlBLIikpIHsKKyAgICAgICAgICAgIHJldHVybiAiYXBwbGljYXRpb24vemlwIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoaGVhZGVyLnN0YXJ0c1dpdGgoIkdJIikpIHsKKyAgICAgICAgICAgIHJldHVybiAiaW1hZ2UvZ2lmIjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIENoZWNrIHRleHQgdHlwZXMKKyAgICAgICAgU3RyaW5nIHRleHRIZWFkZXIgPSBoZWFkZXIudHJpbSgpLnRvVXBwZXJDYXNlKExvY2FsZS5VUyk7CisgICAgICAgIGlmICh0ZXh0SGVhZGVyLnN0YXJ0c1dpdGgoIjwhRE9DVFlQRSBIVE1MIikgfHwKKyAgICAgICAgICAgICAgICB0ZXh0SGVhZGVyLnN0YXJ0c1dpdGgoIjxIVE1MIikgfHwKKyAgICAgICAgICAgICAgICB0ZXh0SGVhZGVyLnN0YXJ0c1dpdGgoIjxIRUFEIikgfHwKKyAgICAgICAgICAgICAgICB0ZXh0SGVhZGVyLnN0YXJ0c1dpdGgoIjxCT0RZIikgfHwKKyAgICAgICAgICAgICAgICB0ZXh0SGVhZGVyLnN0YXJ0c1dpdGgoIjxIRUFEIikpIHsKKyAgICAgICAgICAgIHJldHVybiAidGV4dC9odG1sIjsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh0ZXh0SGVhZGVyLnN0YXJ0c1dpdGgoIjw/WE1MIikpIHsKKyAgICAgICAgICAgIHJldHVybiAiYXBwbGljYXRpb24veG1sIjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEdpdmUgdXAKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYW55IG5lY2Vzc2FyeSBzdHJpbmcgcGFyc2luZyBvbiB0aGUgaW5wdXQgc3RyaW5nIHN1Y2ggYXMKKyAgICAgKiBjb252ZXJ0aW5nIG5vbi1hbHBoYW51bWVyaWMgY2hhcmFjdGVyIGludG8gdW5kZXJzY29yZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlU3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgcGFyc2VkIHN0cmluZworICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyB0byBiZSBwYXJzZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBwYXJzZVR5cGVTdHJpbmcoU3RyaW5nIHR5cGVTdHJpbmcpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcih0eXBlU3RyaW5nKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXN1bHQubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgLy8gaWYgbm9uLWFscGhhbnVtZXJpYywgcmVwbGFjZSBpdCB3aXRoICdfJworICAgICAgICAgICAgY2hhciBjID0gcmVzdWx0LmNoYXJBdChpKTsKKyAgICAgICAgICAgIGlmICghKENoYXJhY3Rlci5pc0xldHRlcihjKSB8fCBDaGFyYWN0ZXIuaXNEaWdpdChjKSB8fCBjID09ICcuJykpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuc2V0Q2hhckF0KGksICdfJyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgY29ubmVjdGlvbiBhbGxvd3MgdXNlciBpbnRlcmFjdGlvbgorICAgICAqIG9yIG5vdC4gVGhpcyBtZXRob2QgY2FuIG9ubHkgYmUgY2FsbGVkIHByaW9yIHRvIHRoZSBjb25uZWN0aW9uCisgICAgICogZXN0YWJsaXNobWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIG9mIHRoZSBmbGFnIHRvIGJlIHNldC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbWV0aG9kIGF0dGVtcHRzIHRvIGNoYW5nZSB0aGUgZmxhZyBhZnRlciB0aGUKKyAgICAgKiAgICAgICAgICAgICBjb25uZWN0aW9uIGhhcyBiZWVuIGVzdGFibGlzaGVkLgorICAgICAqIEBzZWUgI2FsbG93VXNlckludGVyYWN0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QWxsb3dVc2VySW50ZXJhY3Rpb24oYm9vbGVhbiBuZXdWYWx1ZSkgeworICAgICAgICBjaGVja05vdENvbm5lY3RlZCgpOworICAgICAgICB0aGlzLmFsbG93VXNlckludGVyYWN0aW9uID0gbmV3VmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgaW50ZXJuYWxseSB1c2VkIGNvbnRlbnQgaGFuZGxlciBmYWN0b3J5LiBUaGUgY29udGVudCBmYWN0b3J5IGNhbgorICAgICAqIG9ubHkgYmUgc2V0IG9uY2UgZHVyaW5nIHRoZSBsaWZldGltZSBvZiB0aGUgYXBwbGljYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29udGVudEZhY3RvcnkKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb250ZW50IGZhY3RvcnkgdG8gYmUgc2V0LgorICAgICAqIEB0aHJvd3MgRXJyb3IKKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZmFjdG9yeSBoYXMgYmVlbiBhbHJlYWR5IHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCB2b2lkIHNldENvbnRlbnRIYW5kbGVyRmFjdG9yeShDb250ZW50SGFuZGxlckZhY3RvcnkgY29udGVudEZhY3RvcnkpIHsKKyAgICAgICAgaWYgKGNvbnRlbnRIYW5kbGVyRmFjdG9yeSAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkZhY3RvcnkgYWxyZWFkeSBzZXQiKTsKKyAgICAgICAgfQorICAgICAgICBjb250ZW50SGFuZGxlckZhY3RvcnkgPSBjb250ZW50RmFjdG9yeTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkZWZhdWx0IHZhbHVlIGZvciB0aGUgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyBjb25uZWN0aW9uCisgICAgICogYWxsb3dzIHVzZXIgaW50ZXJhY3Rpb24gb3Igbm90LiBFeGlzdGluZyB7QGNvZGUgVVJMQ29ubmVjdGlvbn1zIGFyZQorICAgICAqIHVuYWZmZWN0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxsb3dzCisgICAgICogICAgICAgICAgICB0aGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGUgZmxhZyB0byBiZSB1c2VkIGZvciBuZXcgY29ubmVjdGlvbnMuCisgICAgICogQHNlZSAjZGVmYXVsdEFsbG93VXNlckludGVyYWN0aW9uCisgICAgICogQHNlZSAjYWxsb3dVc2VySW50ZXJhY3Rpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0RGVmYXVsdEFsbG93VXNlckludGVyYWN0aW9uKGJvb2xlYW4gYWxsb3dzKSB7CisgICAgICAgIGRlZmF1bHRBbGxvd1VzZXJJbnRlcmFjdGlvbiA9IGFsbG93czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb2VzIG5vdGhpbmcuCisgICAgICoKKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rIFVSTENvbm5lY3Rpb24jc2V0UmVxdWVzdFByb3BlcnR5KFN0cmluZywgU3RyaW5nKX0uCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0RGVmYXVsdFJlcXVlc3RQcm9wZXJ0eShTdHJpbmcgZmllbGQsIFN0cmluZyB2YWx1ZSkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRoZSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGlzIGNvbm5lY3Rpb24KKyAgICAgKiBhbGxvd3MgdG8gdXNlIGNhY2hlcy4gRXhpc3Rpbmcge0Bjb2RlIFVSTENvbm5lY3Rpb259cyBhcmUgdW5hZmZlY3RlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdWYWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlIGZsYWcgdG8gYmUgdXNlZCBmb3IgbmV3IGNvbm5lY3Rpb25zLgorICAgICAqIEBzZWUgI3VzZUNhY2hlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERlZmF1bHRVc2VDYWNoZXMoYm9vbGVhbiBuZXdWYWx1ZSkgeworICAgICAgICBkZWZhdWx0VXNlQ2FjaGVzID0gbmV3VmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyB7QGNvZGUgVVJMQ29ubmVjdGlvbn0gYWxsb3dzIGlucHV0LgorICAgICAqIEl0IGNhbm5vdCBiZSBzZXQgYWZ0ZXIgdGhlIGNvbm5lY3Rpb24gaXMgZXN0YWJsaXNoZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBmbGFnIHRvIGJlIHNldC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFcnJvcgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbWV0aG9kIGF0dGVtcHRzIHRvIGNoYW5nZSB0aGUgdmFsdWUgYWZ0ZXIgdGhlCisgICAgICogICAgICAgICAgICAgY29ubmVjdGlvbiBoYXMgYmVlbiBhbHJlYWR5IGVzdGFibGlzaGVkLgorICAgICAqIEBzZWUgI2RvSW5wdXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREb0lucHV0KGJvb2xlYW4gbmV3VmFsdWUpIHsKKyAgICAgICAgY2hlY2tOb3RDb25uZWN0ZWQoKTsKKyAgICAgICAgdGhpcy5kb0lucHV0ID0gbmV3VmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyB7QGNvZGUgVVJMQ29ubmVjdGlvbn0gYWxsb3dzCisgICAgICogb3V0cHV0LiBJdCBjYW5ub3QgYmUgc2V0IGFmdGVyIHRoZSBjb25uZWN0aW9uIGlzIGVzdGFibGlzaGVkLgorICAgICAqCisgICAgICogQHBhcmFtIG5ld1ZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgZmxhZyB0byBiZSBzZXQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQWNjZXNzRXJyb3IKKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBhdHRlbXB0cyB0byBjaGFuZ2UgdGhlIHZhbHVlIGFmdGVyIHRoZQorICAgICAqICAgICAgICAgICAgIGNvbm5lY3Rpb24gaGFzIGJlZW4gYWxyZWFkeSBlc3RhYmxpc2hlZC4KKyAgICAgKiBAc2VlICNkb091dHB1dAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERvT3V0cHV0KGJvb2xlYW4gbmV3VmFsdWUpIHsKKyAgICAgICAgY2hlY2tOb3RDb25uZWN0ZWQoKTsKKyAgICAgICAgdGhpcy5kb091dHB1dCA9IG5ld1ZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGludGVybmFsIG1hcCB3aGljaCBpcyB1c2VkIGJ5IGFsbCB7QGNvZGUgVVJMQ29ubmVjdGlvbn0KKyAgICAgKiBpbnN0YW5jZXMgdG8gZGV0ZXJtaW5lIHRoZSBNSU1FLXR5cGUgYWNjb3JkaW5nIHRvIGEgZmlsZW5hbWUgZXh0ZW5zaW9uLgorICAgICAqCisgICAgICogQHBhcmFtIG1hcAorICAgICAqICAgICAgICAgICAgdGhlIE1JTUUgdGFibGUgdG8gYmUgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRGaWxlTmFtZU1hcChGaWxlTmFtZU1hcCBtYXApIHsKKyAgICAgICAgc3luY2hyb25pemVkIChVUkxDb25uZWN0aW9uLmNsYXNzKSB7CisgICAgICAgICAgICBmaWxlTmFtZU1hcCA9IG1hcDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHBvaW50IG9mIHRpbWUgc2luY2Ugd2hlbiB0aGUgZGF0YSBtdXN0IGJlIG1vZGlmaWVkIHRvIGJlCisgICAgICogdHJhbnNtaXR0ZWQuIFNvbWUgcHJvdG9jb2xzIHRyYW5zbWl0IGRhdGEgb25seSBpZiBpdCBoYXMgYmVlbiBtb2RpZmllZAorICAgICAqIG1vcmUgcmVjZW50bHkgdGhhbiBhIHBhcnRpY3VsYXIgdGltZS4gVGhlIGRhdGEgd2lsbCBiZSB0cmFuc21pdHRlZAorICAgICAqIHJlZ2FyZGxlc3Mgb2YgaXRzIHRpbWVzdGFtcCBpZiB0aGlzIG9wdGlvbiBpcyBzZXQgdG8ge0Bjb2RlIDB9LgorICAgICAqCisgICAgICogQHBhcmFtIG5ld1ZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgdGltZSBpbiBtaWxsaXNlY29uZHMgc2luY2UgSmFudWFyeSAxLCAxOTcwIEdNVC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIFVSTENvbm5lY3Rpb259IGhhcyBhbHJlYWR5IGJlZW4gY29ubmVjdGVkLgorICAgICAqIEBzZWUgI2lmTW9kaWZpZWRTaW5jZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldElmTW9kaWZpZWRTaW5jZShsb25nIG5ld1ZhbHVlKSB7CisgICAgICAgIGNoZWNrTm90Q29ubmVjdGVkKCk7CisgICAgICAgIHRoaXMuaWZNb2RpZmllZFNpbmNlID0gbmV3VmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCByZXF1ZXN0IGhlYWRlciBmaWVsZC4gVGhlIHZhbHVlIHdpbGwgb25seQorICAgICAqIGJlIHVzZWQgYnkgdGhlIGN1cnJlbnQge0Bjb2RlIFVSTENvbm5lY3Rpb259IGluc3RhbmNlLiBUaGlzIG1ldGhvZCBjYW4KKyAgICAgKiBvbmx5IGJlIGNhbGxlZCBiZWZvcmUgdGhlIGNvbm5lY3Rpb24gaXMgZXN0YWJsaXNoZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmllbGQKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXF1ZXN0IGhlYWRlciBmaWVsZCB0byBiZSBzZXQuCisgICAgICogQHBhcmFtIG5ld1ZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcHJvcGVydHkuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY29ubmVjdGlvbiBoYXMgYmVlbiBhbHJlYWR5IGVzdGFibGlzaGVkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFyYW1ldGVyIHtAY29kZSBmaWVsZH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFJlcXVlc3RQcm9wZXJ0eShTdHJpbmcgZmllbGQsIFN0cmluZyBuZXdWYWx1ZSkgeworICAgICAgICBjaGVja05vdENvbm5lY3RlZCgpOworICAgICAgICBpZiAoZmllbGQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJmaWVsZCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGlzIGNvbm5lY3Rpb24gYWxsb3dzIHRvIHVzZSBjYWNoZXMgb3IKKyAgICAgKiBub3QuIFRoaXMgbWV0aG9kIGNhbiBvbmx5IGJlIGNhbGxlZCBwcmlvciB0byB0aGUgY29ubmVjdGlvbgorICAgICAqIGVzdGFibGlzaG1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSBvZiB0aGUgZmxhZyB0byBiZSBzZXQuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBhdHRlbXB0cyB0byBjaGFuZ2UgdGhlIGZsYWcgYWZ0ZXIgdGhlCisgICAgICogICAgICAgICAgICAgY29ubmVjdGlvbiBoYXMgYmVlbiBlc3RhYmxpc2hlZC4KKyAgICAgKiBAc2VlICN1c2VDYWNoZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRVc2VDYWNoZXMoYm9vbGVhbiBuZXdWYWx1ZSkgeworICAgICAgICBjaGVja05vdENvbm5lY3RlZCgpOworICAgICAgICB0aGlzLnVzZUNhY2hlcyA9IG5ld1ZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHRpbWVvdXQgdmFsdWUgaW4gbWlsbGlzZWNvbmRzIGZvciBlc3RhYmxpc2hpbmcgdGhlIGNvbm5lY3Rpb24gdG8KKyAgICAgKiB0aGUgcmVzb3VyY2UgcG9pbnRlZCBieSB0aGlzIHtAY29kZSBVUkxDb25uZWN0aW9ufSBpbnN0YW5jZS4gQSB7QGNvZGUKKyAgICAgKiBTb2NrZXRUaW1lb3V0RXhjZXB0aW9ufSBpcyB0aHJvd24gaWYgdGhlIGNvbm5lY3Rpb24gY291bGQgbm90IGJlCisgICAgICogZXN0YWJsaXNoZWQgaW4gdGhpcyB0aW1lLiBEZWZhdWx0IGlzIHtAY29kZSAwfSB3aGljaCBzdGFuZHMgZm9yIGFuCisgICAgICogaW5maW5pdGUgdGltZW91dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aW1lb3V0CisgICAgICogICAgICAgICAgICB0aGUgY29ubmVjdGluZyB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYXJhbWV0ZXIge0Bjb2RlIHRpbWVvdXR9IGlzIGxlc3MgdGhhbiB6ZXJvLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvbm5lY3RUaW1lb3V0KGludCB0aW1lb3V0KSB7CisgICAgICAgIGlmICh0aW1lb3V0IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigidGltZW91dCA8IDAiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmNvbm5lY3RUaW1lb3V0ID0gdGltZW91dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb25maWd1cmVkIGNvbm5lY3RpbmcgdGltZW91dC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNvbm5lY3RpbmcgdGltZW91dCB2YWx1ZSBpbiBtaWxsaXNlY29uZHMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRDb25uZWN0VGltZW91dCgpIHsKKyAgICAgICAgcmV0dXJuIGNvbm5lY3RUaW1lb3V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHRpbWVvdXQgdmFsdWUgaW4gbWlsbGlzZWNvbmRzIGZvciByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmVhbQorICAgICAqIG9mIGFuIGVzdGFibGlzaGVkIGNvbm5lY3Rpb24gdG8gdGhlIHJlc291cmNlLiBBIHtAY29kZQorICAgICAqIFNvY2tldFRpbWVvdXRFeGNlcHRpb259IGlzIHRocm93biBpZiB0aGUgY29ubmVjdGlvbiBjb3VsZCBub3QgYmUKKyAgICAgKiBlc3RhYmxpc2hlZCBpbiB0aGlzIHRpbWUuIERlZmF1bHQgaXMge0Bjb2RlIDB9IHdoaWNoIHN0YW5kcyBmb3IgYW4KKyAgICAgKiBpbmZpbml0ZSB0aW1lb3V0LgorICAgICAqCisgICAgICogQHBhcmFtIHRpbWVvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSByZWFkaW5nIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBhcmFtZXRlciB7QGNvZGUgdGltZW91dH0gaXMgbGVzcyB0aGFuIHplcm8uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmVhZFRpbWVvdXQoaW50IHRpbWVvdXQpIHsKKyAgICAgICAgaWYgKHRpbWVvdXQgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ0aW1lb3V0IDwgMCIpOworICAgICAgICB9CisgICAgICAgIHRoaXMucmVhZFRpbWVvdXQgPSB0aW1lb3V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNvbmZpZ3VyZWQgdGltZW91dCBmb3IgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBzdHJlYW0gb2YgYW4KKyAgICAgKiBlc3RhYmxpc2hlZCBjb25uZWN0aW9uIHRvIHRoZSByZXNvdXJjZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJlYWRpbmcgdGltZW91dCB2YWx1ZSBpbiBtaWxsaXNlY29uZHMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSZWFkVGltZW91dCgpIHsKKyAgICAgICAgcmV0dXJuIHJlYWRUaW1lb3V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBjb250YWluaW5nIHRoZSBuYW1lIG9mIHRoaXMgY2xhc3MgYW5kCisgICAgICogdGhlIFVSTC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZSBVUkxDb25uZWN0aW9ufSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiOiIgKyB1cmwudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgRGVmYXVsdENvbnRlbnRIYW5kbGVyIGV4dGVuZHMgamF2YS5uZXQuQ29udGVudEhhbmRsZXIgeworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIE9iamVjdCBnZXRDb250ZW50KFVSTENvbm5lY3Rpb24gdSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiB1LmdldElucHV0U3RyZWFtKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvVVJMRGVjb2Rlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1VSTERlY29kZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMzRmZTRhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1VSTERlY29kZXIuamF2YQpAQCAtMCwwICsxLDY5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBsaWJjb3JlLm5ldC5VcmlDb2RlYzsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIHVzZWQgdG8gZGVjb2RlIGEgc3RyaW5nIHdoaWNoIGlzIGVuY29kZWQgaW4gdGhlIHtAY29kZQorICogYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkfSBNSU1FIGNvbnRlbnQgdHlwZS4KKyAqLworcHVibGljIGNsYXNzIFVSTERlY29kZXIgeworICAgIC8qKgorICAgICAqIERlY29kZXMgdGhlIGFyZ3VtZW50IHdoaWNoIGlzIGFzc3VtZWQgdG8gYmUgZW5jb2RlZCBpbiB0aGUge0Bjb2RlCisgICAgICogeC13d3ctZm9ybS11cmxlbmNvZGVkfSBNSU1FIGNvbnRlbnQgdHlwZS4KKyAgICAgKiA8cD4KKyAgICAgKicrJyB3aWxsIGJlIGNvbnZlcnRlZCB0byBzcGFjZSwgJyUnIGFuZCB0d28gZm9sbG93aW5nIGhleCBkaWdpdAorICAgICAqIGNoYXJhY3RlcnMgYXJlIGNvbnZlcnRlZCB0byB0aGUgZXF1aXZhbGVudCBieXRlIHZhbHVlLiBBbGwgb3RoZXIKKyAgICAgKiBjaGFyYWN0ZXJzIGFyZSBwYXNzZWQgdGhyb3VnaCB1bm1vZGlmaWVkLiBGb3IgZXhhbXBsZSAiQStCK0MgJTI0JTI1IiAtPgorICAgICAqICJBIEIgQyAkJSIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIGVuY29kZWQgc3RyaW5nLgorICAgICAqIEByZXR1cm4gdGhlIGRlY29kZWQgY2xlYXItdGV4dCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gc3RyaW5nLgorICAgICAqIEBkZXByZWNhdGVkIHVzZSB7QGxpbmsgI2RlY29kZShTdHJpbmcsIFN0cmluZyl9IGluc3RlYWQuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBkZWNvZGUoU3RyaW5nIHMpIHsKKyAgICAgICAgcmV0dXJuIFVyaUNvZGVjLmRlY29kZShzLCB0cnVlLCBDaGFyc2V0LmRlZmF1bHRDaGFyc2V0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlY29kZXMgdGhlIGFyZ3VtZW50IHdoaWNoIGlzIGFzc3VtZWQgdG8gYmUgZW5jb2RlZCBpbiB0aGUge0Bjb2RlCisgICAgICogeC13d3ctZm9ybS11cmxlbmNvZGVkfSBNSU1FIGNvbnRlbnQgdHlwZSB1c2luZyB0aGUgc3BlY2lmaWVkIGVuY29kaW5nCisgICAgICogc2NoZW1lLgorICAgICAqIDxwPgorICAgICAqJysnIHdpbGwgYmUgY29udmVydGVkIHRvIHNwYWNlLCAnJScgYW5kIHR3byBmb2xsb3dpbmcgaGV4IGRpZ2l0CisgICAgICogY2hhcmFjdGVycyBhcmUgY29udmVydGVkIHRvIHRoZSBlcXVpdmFsZW50IGJ5dGUgdmFsdWUuIEFsbCBvdGhlcgorICAgICAqIGNoYXJhY3RlcnMgYXJlIHBhc3NlZCB0aHJvdWdoIHVubW9kaWZpZWQuIEZvciBleGFtcGxlICJBK0IrQyAlMjQlMjUiIC0+CisgICAgICogIkEgQiBDICQlIi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgZW5jb2RlZCBzdHJpbmcuCisgICAgICogQHBhcmFtIGVuY29kaW5nCisgICAgICogICAgICAgICAgICB0aGUgZW5jb2Rpbmcgc2NoZW1lIHRvIGJlIHVzZWQuCisgICAgICogQHJldHVybiB0aGUgZGVjb2RlZCBjbGVhci10ZXh0IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBzdHJpbmcuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBlbmNvZGluZyBzY2hlbWUgaXMgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBkZWNvZGUoU3RyaW5nIHMsIFN0cmluZyBlbmNvZGluZykgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgICAgICByZXR1cm4gVXJpQ29kZWMuZGVjb2RlKHMsIHRydWUsIENoYXJzZXQuZm9yTmFtZShlbmNvZGluZykpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9VUkxFbmNvZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvVVJMRW5jb2Rlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVkZDg1YjAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvVVJMRW5jb2Rlci5qYXZhCkBAIC0wLDAgKzEsNTkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldHM7CitpbXBvcnQgbGliY29yZS5uZXQuVXJpQ29kZWM7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyB1c2VkIHRvIGVuY29kZSBhIHN0cmluZyB1c2luZyB0aGUgZm9ybWF0IHJlcXVpcmVkIGJ5CisgKiB7QGNvZGUgYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkfSBNSU1FIGNvbnRlbnQgdHlwZS4KKyAqCisgKiA8cD5BbGwgY2hhcmFjdGVycyBleGNlcHQgbGV0dGVycyAoJ2EnLi4neicsICdBJy4uJ1onKSBhbmQgbnVtYmVycyAoJzAnLi4nOScpCisgKiBhbmQgY2hhcmFjdGVycyAnLicsICctJywgJyonLCAnXycgYXJlIGNvbnZlcnRlZCBpbnRvIHRoZWlyIGhleGFkZWNpbWFsIHZhbHVlCisgKiBwcmVwZW5kZWQgYnkgJyUnLiBGb3IgZXhhbXBsZTogJyMnIC0+ICUyMy4gSW4gYWRkaXRpb24sIHNwYWNlcyBhcmUKKyAqIHN1YnN0aXR1dGVkIGJ5ICcrJy4KKyAqLworcHVibGljIGNsYXNzIFVSTEVuY29kZXIgeworICAgIHByaXZhdGUgVVJMRW5jb2RlcigpIHt9CisKKyAgICBzdGF0aWMgVXJpQ29kZWMgRU5DT0RFUiA9IG5ldyBVcmlDb2RlYygpIHsKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBib29sZWFuIGlzUmV0YWluZWQoY2hhciBjKSB7CisgICAgICAgICAgICByZXR1cm4gIiAuLSpfIi5pbmRleE9mKGMpICE9IC0xOworICAgICAgICB9CisgICAgfTsKKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8ge0Bjb2RlIGVuY29kZShzLCAiVVRGLTgiKX0uCisgICAgICoKKyAgICAgKiBAZGVwcmVjYXRlZCB1c2Uge0BsaW5rICNlbmNvZGUoU3RyaW5nLCBTdHJpbmcpfSBpbnN0ZWFkLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZW5jb2RlKFN0cmluZyBzKSB7CisgICAgICAgIHJldHVybiBFTkNPREVSLmVuY29kZShzLCBDaGFyc2V0cy5VVEZfOCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlcyB7QGNvZGUgc30gdXNpbmcgdGhlIHtAbGluayBDaGFyc2V0fSBuYW1lZCBieSB7QGNvZGUgY2hhcnNldE5hbWV9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGVuY29kZShTdHJpbmcgcywgU3RyaW5nIGNoYXJzZXROYW1lKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBFTkNPREVSLmVuY29kZShzLCBDaGFyc2V0LmZvck5hbWUoY2hhcnNldE5hbWUpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvVVJMU3RyZWFtSGFuZGxlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1VSTFN0cmVhbUhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YTA0YjZmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1VSTFN0cmVhbUhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDM2MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgbGliY29yZS5uZXQudXJsLlVybFV0aWxzOworaW1wb3J0IGxpYmNvcmUudXRpbC5PYmplY3RzOworCisvKioKKyAqIFRoZSBhYnN0cmFjdCBjbGFzcyB7QGNvZGUgVVJMU3RyZWFtSGFuZGxlcn0gaXMgdGhlIGJhc2UgZm9yIGFsbCBjbGFzc2VzIHdoaWNoCisgKiBjYW4gaGFuZGxlIHRoZSBjb21tdW5pY2F0aW9uIHdpdGggYSBVUkwgb2JqZWN0IG92ZXIgYSBwYXJ0aWN1bGFyIHByb3RvY29sCisgKiB0eXBlLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgVVJMU3RyZWFtSGFuZGxlciB7CisgICAgLyoqCisgICAgICogRXN0YWJsaXNoZXMgYSBuZXcgY29ubmVjdGlvbiB0byB0aGUgcmVzb3VyY2Ugc3BlY2lmaWVkIGJ5IHRoZSBVUkwge0Bjb2RlCisgICAgICogdX0uIFNpbmNlIGRpZmZlcmVudCBwcm90b2NvbHMgYWxzbyBoYXZlIHVuaXF1ZSB3YXlzIG9mIGNvbm5lY3RpbmcsIGl0CisgICAgICogbXVzdCBiZSBvdmVyd3JpdHRlbiBieSB0aGUgc3ViY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdQorICAgICAqICAgICAgICAgICAgdGhlIFVSTCB0byB0aGUgcmVzb3VyY2Ugd2hlcmUgYSBjb25uZWN0aW9uIGhhcyB0byBiZSBvcGVuZWQuCisgICAgICogQHJldHVybiB0aGUgb3BlbmVkIFVSTENvbm5lY3Rpb24gdG8gdGhlIHNwZWNpZmllZCByZXNvdXJjZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyBkdXJpbmcgb3BlbmluZyB0aGUgY29ubmVjdGlvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgVVJMQ29ubmVjdGlvbiBvcGVuQ29ubmVjdGlvbihVUkwgdSkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRXN0YWJsaXNoZXMgYSBuZXcgY29ubmVjdGlvbiB0byB0aGUgcmVzb3VyY2Ugc3BlY2lmaWVkIGJ5IHRoZSBVUkwge0Bjb2RlCisgICAgICogdX0gdXNpbmcgdGhlIGdpdmVuIHtAY29kZSBwcm94eX0uIFNpbmNlIGRpZmZlcmVudCBwcm90b2NvbHMgYWxzbyBoYXZlCisgICAgICogdW5pcXVlIHdheXMgb2YgY29ubmVjdGluZywgaXQgbXVzdCBiZSBvdmVyd3JpdHRlbiBieSB0aGUgc3ViY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdQorICAgICAqICAgICAgICAgICAgdGhlIFVSTCB0byB0aGUgcmVzb3VyY2Ugd2hlcmUgYSBjb25uZWN0aW9uIGhhcyB0byBiZSBvcGVuZWQuCisgICAgICogQHBhcmFtIHByb3h5CisgICAgICogICAgICAgICAgICB0aGUgcHJveHkgdGhhdCBpcyB1c2VkIHRvIG1ha2UgdGhlIGNvbm5lY3Rpb24uCisgICAgICogQHJldHVybiB0aGUgb3BlbmVkIFVSTENvbm5lY3Rpb24gdG8gdGhlIHNwZWNpZmllZCByZXNvdXJjZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3VycyBkdXJpbmcgb3BlbmluZyB0aGUgY29ubmVjdGlvbi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBhcmd1bWVudCBpcyB7QGNvZGUgbnVsbH0gb3IgdGhlIHR5cGUgb2YgcHJveHkgaXMKKyAgICAgKiAgICAgICAgICAgICB3cm9uZy4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHByb3RvY29sIGhhbmRsZXIgZG9lc24ndCBzdXBwb3J0IHRoaXMgbWV0aG9kLgorICAgICAqLworICAgIHByb3RlY3RlZCBVUkxDb25uZWN0aW9uIG9wZW5Db25uZWN0aW9uKFVSTCB1LCBQcm94eSBwcm94eSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBjbGVhciB0ZXh0IFVSTCBpbiB7QGNvZGUgc3RyfSBpbnRvIGEgVVJMIG9iamVjdC4gVVJMIHN0cmluZ3MKKyAgICAgKiBnZW5lcmFsbHkgaGF2ZSB0aGUgZm9sbG93aW5nIGZvcm1hdDoKKyAgICAgKiA8cD4KKyAgICAgKiBodHRwOi8vd3d3LmNvbXBhbnkuY29tL2phdmEvZmlsZTEuamF2YSNyZWZlcmVuY2UKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgc3RyaW5nIGlzIHBhcnNlZCBpbiBIVFRQIGZvcm1hdC4gSWYgdGhlIHByb3RvY29sIGhhcyBhIGRpZmZlcmVudCBVUkwKKyAgICAgKiBmb3JtYXQgdGhpcyBtZXRob2QgbXVzdCBiZSBvdmVycmlkZGVuLgorICAgICAqCisgICAgICogQHBhcmFtIHVybAorICAgICAqICAgICAgICAgICAgdGhlIFVSTCB0byBmaWxsIGluIHRoZSBwYXJzZWQgY2xlYXIgdGV4dCBVUkwgcGFydHMuCisgICAgICogQHBhcmFtIHNwZWMKKyAgICAgKiAgICAgICAgICAgIHRoZSBVUkwgc3RyaW5nIHRoYXQgaXMgdG8gYmUgcGFyc2VkLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyBwb3NpdGlvbiBmcm9tIHdoZXJlIHRvIGJlZ2luIHBhcnNpbmcuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyBwb3NpdGlvbiB0byBzdG9wIHBhcnNpbmcuCisgICAgICogQHNlZSAjdG9FeHRlcm5hbEZvcm0KKyAgICAgKiBAc2VlIFVSTAorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHBhcnNlVVJMKFVSTCB1cmwsIFN0cmluZyBzcGVjLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgaWYgKHRoaXMgIT0gdXJsLnN0cmVhbUhhbmRsZXIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigiT25seSBhIFVSTCdzIHN0cmVhbSBoYW5kbGVyIGlzIHBlcm1pdHRlZCB0byBtdXRhdGUgaXQiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZW5kIDwgc3RhcnQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKHNwZWMsIHN0YXJ0LCBlbmQgLSBzdGFydCk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgZmlsZVN0YXJ0OworICAgICAgICBTdHJpbmcgYXV0aG9yaXR5OworICAgICAgICBTdHJpbmcgdXNlckluZm87CisgICAgICAgIFN0cmluZyBob3N0OworICAgICAgICBpbnQgcG9ydCA9IC0xOworICAgICAgICBTdHJpbmcgcGF0aDsKKyAgICAgICAgU3RyaW5nIHF1ZXJ5OworICAgICAgICBTdHJpbmcgcmVmOworICAgICAgICBpZiAoc3BlYy5yZWdpb25NYXRjaGVzKHN0YXJ0LCAiLy8iLCAwLCAyKSkgeworICAgICAgICAgICAgLy8gUGFyc2UgdGhlIGF1dGhvcml0eSBmcm9tIHRoZSBzcGVjLgorICAgICAgICAgICAgaW50IGF1dGhvcml0eVN0YXJ0ID0gc3RhcnQgKyAyOworICAgICAgICAgICAgZmlsZVN0YXJ0ID0gVXJsVXRpbHMuZmluZEZpcnN0T2Yoc3BlYywgIi8/IyIsIGF1dGhvcml0eVN0YXJ0LCBlbmQpOworICAgICAgICAgICAgYXV0aG9yaXR5ID0gc3BlYy5zdWJzdHJpbmcoYXV0aG9yaXR5U3RhcnQsIGZpbGVTdGFydCk7CisgICAgICAgICAgICBpbnQgdXNlckluZm9FbmQgPSBVcmxVdGlscy5maW5kRmlyc3RPZihzcGVjLCAiQCIsIGF1dGhvcml0eVN0YXJ0LCBmaWxlU3RhcnQpOworICAgICAgICAgICAgaW50IGhvc3RTdGFydDsKKyAgICAgICAgICAgIGlmICh1c2VySW5mb0VuZCAhPSBmaWxlU3RhcnQpIHsKKyAgICAgICAgICAgICAgICB1c2VySW5mbyA9IHNwZWMuc3Vic3RyaW5nKGF1dGhvcml0eVN0YXJ0LCB1c2VySW5mb0VuZCk7CisgICAgICAgICAgICAgICAgaG9zdFN0YXJ0ID0gdXNlckluZm9FbmQgKyAxOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB1c2VySW5mbyA9IG51bGw7CisgICAgICAgICAgICAgICAgaG9zdFN0YXJ0ID0gYXV0aG9yaXR5U3RhcnQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBFeHRyYWN0IHRoZSBob3N0IGFuZCBwb3J0LiBUaGUgaG9zdCBtYXkgYmUgYW4gSVB2NiBhZGRyZXNzIHdpdGgKKyAgICAgICAgICAgICAqIGNvbG9ucyBsaWtlICJbOjoxXSIsIGluIHdoaWNoIGNhc2Ugd2UgbG9vayBmb3IgdGhlIHBvcnQgZGVsaW1pdGVyCisgICAgICAgICAgICAgKiBjb2xvbiBhZnRlciB0aGUgJ10nIGNoYXJhY3Rlci4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaW50IGNvbG9uU2VhcmNoRnJvbSA9IGhvc3RTdGFydDsKKyAgICAgICAgICAgIGludCBpcHY2RW5kID0gVXJsVXRpbHMuZmluZEZpcnN0T2Yoc3BlYywgIl0iLCBob3N0U3RhcnQsIGZpbGVTdGFydCk7CisgICAgICAgICAgICBpZiAoaXB2NkVuZCAhPSBmaWxlU3RhcnQpIHsKKyAgICAgICAgICAgICAgICBpZiAoVXJsVXRpbHMuZmluZEZpcnN0T2Yoc3BlYywgIjoiLCBob3N0U3RhcnQsIGlwdjZFbmQpID09IGlwdjZFbmQpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRXhwZWN0ZWQgYW4gSVB2NiBhZGRyZXNzOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzcGVjLnN1YnN0cmluZyhob3N0U3RhcnQsIGlwdjZFbmQgKyAxKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvbG9uU2VhcmNoRnJvbSA9IGlwdjZFbmQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgaG9zdEVuZCA9IFVybFV0aWxzLmZpbmRGaXJzdE9mKHNwZWMsICI6IiwgY29sb25TZWFyY2hGcm9tLCBmaWxlU3RhcnQpOworICAgICAgICAgICAgaG9zdCA9IHNwZWMuc3Vic3RyaW5nKGhvc3RTdGFydCwgaG9zdEVuZCk7CisgICAgICAgICAgICBpbnQgcG9ydFN0YXJ0ID0gaG9zdEVuZCArIDE7CisgICAgICAgICAgICBpZiAocG9ydFN0YXJ0IDwgZmlsZVN0YXJ0KSB7CisgICAgICAgICAgICAgICAgcG9ydCA9IEludGVnZXIucGFyc2VJbnQoc3BlYy5zdWJzdHJpbmcocG9ydFN0YXJ0LCBmaWxlU3RhcnQpKTsKKyAgICAgICAgICAgICAgICBpZiAocG9ydCA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicG9ydCA8IDA6ICIgKyBwb3J0KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwYXRoID0gbnVsbDsKKyAgICAgICAgICAgIHF1ZXJ5ID0gbnVsbDsKKyAgICAgICAgICAgIHJlZiA9IG51bGw7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBHZXQgdGhlIGF1dGhvcml0eSBmcm9tIHRoZSBjb250ZXh0IFVSTC4KKyAgICAgICAgICAgIGZpbGVTdGFydCA9IHN0YXJ0OworICAgICAgICAgICAgYXV0aG9yaXR5ID0gdXJsLmdldEF1dGhvcml0eSgpOworICAgICAgICAgICAgdXNlckluZm8gPSB1cmwuZ2V0VXNlckluZm8oKTsKKyAgICAgICAgICAgIGhvc3QgPSB1cmwuZ2V0SG9zdCgpOworICAgICAgICAgICAgaWYgKGhvc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGhvc3QgPSAiIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBvcnQgPSB1cmwuZ2V0UG9ydCgpOworICAgICAgICAgICAgcGF0aCA9IHVybC5nZXRQYXRoKCk7CisgICAgICAgICAgICBxdWVyeSA9IHVybC5nZXRRdWVyeSgpOworICAgICAgICAgICAgcmVmID0gdXJsLmdldFJlZigpOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogRXh0cmFjdCB0aGUgcGF0aCwgcXVlcnkgYW5kIGZyYWdtZW50LiBFYWNoIHBhcnQgaGFzIGl0cyBvd24gbGVhZGluZworICAgICAgICAgKiBkZWxpbWl0ZXIgY2hhcmFjdGVyLiBUaGUgcXVlcnkgY2FuIGNvbnRhaW4gc2xhc2hlcyBhbmQgdGhlIGZyYWdtZW50CisgICAgICAgICAqIGNhbiBjb250YWluIHNsYXNoZXMgYW5kIHF1ZXN0aW9uIG1hcmtzLgorICAgICAgICAgKiAgICAvIHBhdGggPyBxdWVyeSAjIGZyYWdtZW50CisgICAgICAgICAqLworICAgICAgICBpbnQgcG9zID0gZmlsZVN0YXJ0OworICAgICAgICB3aGlsZSAocG9zIDwgZW5kKSB7CisgICAgICAgICAgICBpbnQgbmV4dFBvczsKKyAgICAgICAgICAgIHN3aXRjaCAoc3BlYy5jaGFyQXQocG9zKSkgeworICAgICAgICAgICAgY2FzZSAnIyc6CisgICAgICAgICAgICAgICAgbmV4dFBvcyA9IGVuZDsKKyAgICAgICAgICAgICAgICByZWYgPSBzcGVjLnN1YnN0cmluZyhwb3MgKyAxLCBuZXh0UG9zKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJz8nOgorICAgICAgICAgICAgICAgIG5leHRQb3MgPSBVcmxVdGlscy5maW5kRmlyc3RPZihzcGVjLCAiIyIsIHBvcywgZW5kKTsKKyAgICAgICAgICAgICAgICBxdWVyeSA9IHNwZWMuc3Vic3RyaW5nKHBvcyArIDEsIG5leHRQb3MpOworICAgICAgICAgICAgICAgIHJlZiA9IG51bGw7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIG5leHRQb3MgPSBVcmxVdGlscy5maW5kRmlyc3RPZihzcGVjLCAiPyMiLCBwb3MsIGVuZCk7CisgICAgICAgICAgICAgICAgcGF0aCA9IHJlbGF0aXZlUGF0aChwYXRoLCBzcGVjLnN1YnN0cmluZyhwb3MsIG5leHRQb3MpKTsKKyAgICAgICAgICAgICAgICBxdWVyeSA9IG51bGw7CisgICAgICAgICAgICAgICAgcmVmID0gbnVsbDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBvcyA9IG5leHRQb3M7CisgICAgICAgIH0KKworICAgICAgICBpZiAocGF0aCA9PSBudWxsKSB7CisgICAgICAgICAgICBwYXRoID0gIiI7CisgICAgICAgIH0KKworICAgICAgICBwYXRoID0gVXJsVXRpbHMuYXV0aG9yaXR5U2FmZVBhdGgoYXV0aG9yaXR5LCBwYXRoKTsKKworICAgICAgICBzZXRVUkwodXJsLCB1cmwuZ2V0UHJvdG9jb2woKSwgaG9zdCwgcG9ydCwgYXV0aG9yaXR5LCB1c2VySW5mbywgcGF0aCwgcXVlcnksIHJlZik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBwYXRoIGJ5IHJlc29sdmluZyB7QGNvZGUgcGF0aH0gcmVsYXRpdmUgdG8ge0Bjb2RlIGJhc2V9LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyByZWxhdGl2ZVBhdGgoU3RyaW5nIGJhc2UsIFN0cmluZyBwYXRoKSB7CisgICAgICAgIGlmIChwYXRoLnN0YXJ0c1dpdGgoIi8iKSkgeworICAgICAgICAgICAgcmV0dXJuIFVybFV0aWxzLmNhbm9uaWNhbGl6ZVBhdGgocGF0aCwgdHJ1ZSk7CisgICAgICAgIH0gZWxzZSBpZiAoYmFzZSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgY29tYmluZWQgPSBiYXNlLnN1YnN0cmluZygwLCBiYXNlLmxhc3RJbmRleE9mKCcvJykgKyAxKSArIHBhdGg7CisgICAgICAgICAgICByZXR1cm4gVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aChjb21iaW5lZCwgdHJ1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gcGF0aDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZpZWxkcyBvZiB0aGUgVVJMIHtAY29kZSB1fSB0byB0aGUgdmFsdWVzIG9mIHRoZSBzdXBwbGllZAorICAgICAqIGFyZ3VtZW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1CisgICAgICogICAgICAgICAgICB0aGUgbm9uLW51bGwgVVJMIG9iamVjdCB0byBiZSBzZXQuCisgICAgICogQHBhcmFtIHByb3RvY29sCisgICAgICogICAgICAgICAgICB0aGUgcHJvdG9jb2wuCisgICAgICogQHBhcmFtIGhvc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBob3N0IG5hbWUuCisgICAgICogQHBhcmFtIHBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IG51bWJlci4KKyAgICAgKiBAcGFyYW0gZmlsZQorICAgICAqICAgICAgICAgICAgdGhlIGZpbGUgY29tcG9uZW50LgorICAgICAqIEBwYXJhbSByZWYKKyAgICAgKiAgICAgICAgICAgIHRoZSByZWZlcmVuY2UuCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIHNldFVSTChVUkwsIFN0cmluZyBTdHJpbmcsIGludCwgU3RyaW5nLCBTdHJpbmcsIFN0cmluZywKKyAgICAgKiAgICAgICAgICAgICBTdHJpbmcsIFN0cmluZykgaW5zdGVhZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHByb3RlY3RlZCB2b2lkIHNldFVSTChVUkwgdSwgU3RyaW5nIHByb3RvY29sLCBTdHJpbmcgaG9zdCwgaW50IHBvcnQsCisgICAgICAgICAgICBTdHJpbmcgZmlsZSwgU3RyaW5nIHJlZikgeworICAgICAgICBpZiAodGhpcyAhPSB1LnN0cmVhbUhhbmRsZXIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHUuc2V0KHByb3RvY29sLCBob3N0LCBwb3J0LCBmaWxlLCByZWYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZpZWxkcyBvZiB0aGUgVVJMIHtAY29kZSB1fSB0byB0aGUgdmFsdWVzIG9mIHRoZSBzdXBwbGllZAorICAgICAqIGFyZ3VtZW50cy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVUkwoVVJMIHUsIFN0cmluZyBwcm90b2NvbCwgU3RyaW5nIGhvc3QsIGludCBwb3J0LAorICAgICAgICAgICAgU3RyaW5nIGF1dGhvcml0eSwgU3RyaW5nIHVzZXJJbmZvLCBTdHJpbmcgcGF0aCwgU3RyaW5nIHF1ZXJ5LAorICAgICAgICAgICAgU3RyaW5nIHJlZikgeworICAgICAgICBpZiAodGhpcyAhPSB1LnN0cmVhbUhhbmRsZXIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHUuc2V0KHByb3RvY29sLCBob3N0LCBwb3J0LCBhdXRob3JpdHksIHVzZXJJbmZvLCBwYXRoLCBxdWVyeSwgcmVmKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbGVhciB0ZXh0IHJlcHJlc2VudGF0aW9uIG9mIGEgZ2l2ZW4gVVJMIHVzaW5nIEhUVFAgZm9ybWF0LgorICAgICAqCisgICAgICogQHBhcmFtIHVybAorICAgICAqICAgICAgICAgICAgdGhlIFVSTCBvYmplY3QgdG8gYmUgY29udmVydGVkLgorICAgICAqIEByZXR1cm4gdGhlIGNsZWFyIHRleHQgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNwZWNpZmllZCBVUkwuCisgICAgICogQHNlZSAjcGFyc2VVUkwKKyAgICAgKiBAc2VlIFVSTCN0b0V4dGVybmFsRm9ybSgpCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZyB0b0V4dGVybmFsRm9ybShVUkwgdXJsKSB7CisgICAgICAgIHJldHVybiB0b0V4dGVybmFsRm9ybSh1cmwsIGZhbHNlKTsKKyAgICB9CisKKyAgICBTdHJpbmcgdG9FeHRlcm5hbEZvcm0oVVJMIHVybCwgYm9vbGVhbiBlc2NhcGVJbGxlZ2FsQ2hhcmFjdGVycykgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQodXJsLmdldFByb3RvY29sKCkpOworICAgICAgICByZXN1bHQuYXBwZW5kKCc6Jyk7CisKKyAgICAgICAgU3RyaW5nIGF1dGhvcml0eSA9IHVybC5nZXRBdXRob3JpdHkoKTsKKyAgICAgICAgaWYgKGF1dGhvcml0eSAhPSBudWxsKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCIvLyIpOworICAgICAgICAgICAgaWYgKGVzY2FwZUlsbGVnYWxDaGFyYWN0ZXJzKSB7CisgICAgICAgICAgICAgICAgVVJJLkFVVEhPUklUWV9FTkNPREVSLmFwcGVuZFBhcnRpYWxseUVuY29kZWQocmVzdWx0LCBhdXRob3JpdHkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGF1dGhvcml0eSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgZmlsZUFuZFF1ZXJ5ID0gdXJsLmdldEZpbGUoKTsKKyAgICAgICAgaWYgKGZpbGVBbmRRdWVyeSAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoZXNjYXBlSWxsZWdhbENoYXJhY3RlcnMpIHsKKyAgICAgICAgICAgICAgICBVUkkuRklMRV9BTkRfUVVFUllfRU5DT0RFUi5hcHBlbmRQYXJ0aWFsbHlFbmNvZGVkKHJlc3VsdCwgZmlsZUFuZFF1ZXJ5KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChmaWxlQW5kUXVlcnkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIHJlZiA9IHVybC5nZXRSZWYoKTsKKyAgICAgICAgaWYgKHJlZiAhPSBudWxsKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCcjJyk7CisgICAgICAgICAgICBpZiAoZXNjYXBlSWxsZWdhbENoYXJhY3RlcnMpIHsKKyAgICAgICAgICAgICAgICBVUkkuQUxMX0xFR0FMX0VOQ09ERVIuYXBwZW5kUGFydGlhbGx5RW5jb2RlZChyZXN1bHQsIHJlZik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQocmVmKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYge0Bjb2RlIGF9IGFuZCB7QGNvZGUgYn0gaGF2ZSB0aGUgc2FtZSBwcm90b2NvbCwgaG9zdCwKKyAgICAgKiBwb3J0LCBmaWxlLCBhbmQgcmVmZXJlbmNlLgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGVxdWFscyhVUkwgYSwgVVJMIGIpIHsKKyAgICAgICAgcmV0dXJuIHNhbWVGaWxlKGEsIGIpCisgICAgICAgICAgICAgICAgJiYgT2JqZWN0cy5lcXVhbChhLmdldFJlZigpLCBiLmdldFJlZigpKQorICAgICAgICAgICAgICAgICYmIE9iamVjdHMuZXF1YWwoYS5nZXRRdWVyeSgpLCBiLmdldFF1ZXJ5KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgcG9ydCBvZiB0aGUgcHJvdG9jb2wgdXNlZCBieSB0aGUgaGFuZGxlZCBVUkwuIFRoZQorICAgICAqIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gYWx3YXlzIHJldHVybnMge0Bjb2RlIC0xfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGdldERlZmF1bHRQb3J0KCkgeworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaG9zdCBhZGRyZXNzIG9mIHtAY29kZSB1cmx9LgorICAgICAqLworICAgIHByb3RlY3RlZCBJbmV0QWRkcmVzcyBnZXRIb3N0QWRkcmVzcyhVUkwgdXJsKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgaG9zdCA9IHVybC5nZXRIb3N0KCk7CisgICAgICAgICAgICBpZiAoaG9zdCA9PSBudWxsIHx8IGhvc3QubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIEluZXRBZGRyZXNzLmdldEJ5TmFtZShob3N0KTsKKyAgICAgICAgfSBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgb2Yge0Bjb2RlIHVybH0uCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBoYXNoQ29kZShVUkwgdXJsKSB7CisgICAgICAgIHJldHVybiB0b0V4dGVybmFsRm9ybSh1cmwpLmhhc2hDb2RlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBob3N0cyBvZiB7QGNvZGUgYX0gYW5kIHtAY29kZSBifSBhcmUgZXF1YWwuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gaG9zdHNFcXVhbChVUkwgYSwgVVJMIGIpIHsKKyAgICAgICAgLy8gVVJMcyB3aXRoIHRoZSBzYW1lIGNhc2UtaW5zZW5zaXRpdmUgaG9zdCBuYW1lIGhhdmUgZXF1YWwgaG9zdHMKKyAgICAgICAgU3RyaW5nIGFIb3N0ID0gYS5nZXRIb3N0KCk7CisgICAgICAgIFN0cmluZyBiSG9zdCA9IGIuZ2V0SG9zdCgpOworICAgICAgICByZXR1cm4gKGFIb3N0ID09IGJIb3N0KSB8fCBhSG9zdCAhPSBudWxsICYmIGFIb3N0LmVxdWFsc0lnbm9yZUNhc2UoYkhvc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB7QGNvZGUgYX0gYW5kIHtAY29kZSBifSBoYXZlIHRoZSBzYW1lIHByb3RvY29sLCBob3N0LAorICAgICAqIHBvcnQgYW5kIGZpbGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gc2FtZUZpbGUoVVJMIGEsIFVSTCBiKSB7CisgICAgICAgIHJldHVybiBPYmplY3RzLmVxdWFsKGEuZ2V0UHJvdG9jb2woKSwgYi5nZXRQcm90b2NvbCgpKQorICAgICAgICAgICAgICAgICYmIGhvc3RzRXF1YWwoYSwgYikKKyAgICAgICAgICAgICAgICAmJiBhLmdldEVmZmVjdGl2ZVBvcnQoKSA9PSBiLmdldEVmZmVjdGl2ZVBvcnQoKQorICAgICAgICAgICAgICAgICYmIE9iamVjdHMuZXF1YWwoYS5nZXRGaWxlKCksIGIuZ2V0RmlsZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvVVJMU3RyZWFtSGFuZGxlckZhY3RvcnkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9VUkxTdHJlYW1IYW5kbGVyRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFkODIxMmEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvVVJMU3RyZWFtSGFuZGxlckZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDM1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCisvKioKKyAqIERlZmluZXMgYSBmYWN0b3J5IHdoaWNoIGNyZWF0ZXMgYW4ge0Bjb2RlIFVSTFN0cmVhbUhhbmRsZXJ9IGZvciBhIHNwZWNpZmllZAorICogcHJvdG9jb2wuIEl0IGlzIHVzZWQgYnkgdGhlIGNsYXNzIHtAY29kZSBVUkx9LgorICovCitwdWJsaWMgaW50ZXJmYWNlIFVSTFN0cmVhbUhhbmRsZXJGYWN0b3J5IHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFVSTFN0cmVhbUhhbmRsZXJ9IGluc3RhbmNlIGZvciB0aGUgZ2l2ZW4ge0Bjb2RlCisgICAgICogcHJvdG9jb2x9LgorICAgICAqCisgICAgICogQHBhcmFtIHByb3RvY29sCisgICAgICogICAgICAgICAgICB0aGUgcHJvdG9jb2wgZm9yIHdoaWNoIGEgaGFuZGxlciBpcyBuZWVkZWQuCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCBoYW5kbGVyLgorICAgICAqLworICAgIFVSTFN0cmVhbUhhbmRsZXIgY3JlYXRlVVJMU3RyZWFtSGFuZGxlcihTdHJpbmcgcHJvdG9jb2wpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1Vua25vd25Ib3N0RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvVW5rbm93bkhvc3RFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YzQ4NzNlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmV0L1Vua25vd25Ib3N0RXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5ldDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogVGhyb3duIHdoZW4gYSBob3N0bmFtZSBjYW4gbm90IGJlIHJlc29sdmVkLgorICovCitwdWJsaWMgY2xhc3MgVW5rbm93bkhvc3RFeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDYzOTEyNjA3NjA1Mjg3NTQwM0w7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBVbmtub3duSG9zdEV4Y2VwdGlvbn0gaW5zdGFuY2Ugd2l0aCBubyBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKiBDYWxsZXJzIHNob3VsZCB1c3VhbGx5IHN1cHBseSBhIGRldGFpbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBVbmtub3duSG9zdEV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBVbmtub3duSG9zdEV4Y2VwdGlvbn0gaW5zdGFuY2Ugd2l0aCB0aGUgZ2l2ZW4gZGV0YWlsIG1lc3NhZ2UuCisgICAgICogVGhlIGRldGFpbCBtZXNzYWdlIHNob3VsZCBnZW5lcmFsbHkgY29udGFpbiB0aGUgaG9zdG5hbWUgYW5kIGEgcmVhc29uIGZvciB0aGUgZmFpbHVyZSwKKyAgICAgKiBpZiBrbm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBVbmtub3duSG9zdEV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvVW5rbm93blNlcnZpY2VFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25ldC9Vbmtub3duU2VydmljZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJkY2Y2YTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uZXQvVW5rbm93blNlcnZpY2VFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDUyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBJcyB0aHJvd24gaWYgbm8gYXBwcm9wcmlhdGUge0Bjb2RlIENvbnRlbnRIYW5kbGVyfSBjb3VsZCBiZSBmb3VuZCBmb3IgYQorICogcGFydGljdWxhciBzZXJ2aWNlIHJlcXVlc3RlZCBieSB0aGUgVVJMIGNvbm5lY3Rpb24uIFRoaXMgY291bGQgYmUgaGFwcGVuZWQgaWYKKyAqIHRoZXJlIGlzIGFuIGludmFsaWQgTUlNRSB0eXBlIG9yIHRoZSBhcHBsaWNhdGlvbiB3YW50cyB0byBzZW5kIGRhdGEgb3ZlciBhCisgKiByZWFkLW9ubHkgY29ubmVjdGlvbi4KKyAqLworcHVibGljIGNsYXNzIFVua25vd25TZXJ2aWNlRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQxNjkwMzMyNDg4NTM2Mzk1MDhMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5rbm93blNlcnZpY2VFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSB3aXRoIHRoZSBnaXZlbiBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5rbm93blNlcnZpY2VFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSB3aXRoIGdpdmVuIGRldGFpbCBtZXNzYWdlIGFuZCBjYXVzZS4KKyAgICAgKiBAaGlkZSBpbnRlcm5hbCB1c2Ugb25seQorICAgICAqLworICAgIHB1YmxpYyBVbmtub3duU2VydmljZUV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UsIGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vQmFzZUJ5dGVCdWZmZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9CYXNlQnl0ZUJ1ZmZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ2Y2ZiOTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vQmFzZUJ5dGVCdWZmZXIuamF2YQpAQCAtMCwwICsxLDc4IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCisvKioKKyAqIFNlcnZlcyBhcyB0aGUgcm9vdCBvZiBvdGhlciBieXRlIGJ1ZmZlciBpbXBsIGNsYXNzZXMsIGltcGxlbWVudHMgY29tbW9uCisgKiBtZXRob2RzIHRoYXQgY2FuIGJlIHNoYXJlZCBieSBjaGlsZCBjbGFzc2VzLgorICovCithYnN0cmFjdCBjbGFzcyBCYXNlQnl0ZUJ1ZmZlciBleHRlbmRzIEJ5dGVCdWZmZXIgeworCisgICAgcHJvdGVjdGVkIEJhc2VCeXRlQnVmZmVyKGludCBjYXBhY2l0eSwgTWVtb3J5QmxvY2sgYmxvY2spIHsKKyAgICAgICAgc3VwZXIoY2FwYWNpdHksIGJsb2NrKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgQ2hhckJ1ZmZlciBhc0NoYXJCdWZmZXIoKSB7CisgICAgICAgIHJldHVybiBDaGFyVG9CeXRlQnVmZmVyQWRhcHRlci5hc0NoYXJCdWZmZXIodGhpcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIERvdWJsZUJ1ZmZlciBhc0RvdWJsZUJ1ZmZlcigpIHsKKyAgICAgICAgcmV0dXJuIERvdWJsZVRvQnl0ZUJ1ZmZlckFkYXB0ZXIuYXNEb3VibGVCdWZmZXIodGhpcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIEZsb2F0QnVmZmVyIGFzRmxvYXRCdWZmZXIoKSB7CisgICAgICAgIHJldHVybiBGbG9hdFRvQnl0ZUJ1ZmZlckFkYXB0ZXIuYXNGbG9hdEJ1ZmZlcih0aGlzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgSW50QnVmZmVyIGFzSW50QnVmZmVyKCkgeworICAgICAgICByZXR1cm4gSW50VG9CeXRlQnVmZmVyQWRhcHRlci5hc0ludEJ1ZmZlcih0aGlzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgTG9uZ0J1ZmZlciBhc0xvbmdCdWZmZXIoKSB7CisgICAgICAgIHJldHVybiBMb25nVG9CeXRlQnVmZmVyQWRhcHRlci5hc0xvbmdCdWZmZXIodGhpcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIFNob3J0QnVmZmVyIGFzU2hvcnRCdWZmZXIoKSB7CisgICAgICAgIHJldHVybiBTaG9ydFRvQnl0ZUJ1ZmZlckFkYXB0ZXIuYXNTaG9ydEJ1ZmZlcih0aGlzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgY2hhciBnZXRDaGFyKCkgeworICAgICAgICByZXR1cm4gKGNoYXIpIGdldFNob3J0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGNoYXIgZ2V0Q2hhcihpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIChjaGFyKSBnZXRTaG9ydChpbmRleCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0Q2hhcihjaGFyIHZhbHVlKSB7CisgICAgICAgIHJldHVybiBwdXRTaG9ydCgoc2hvcnQpIHZhbHVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRDaGFyKGludCBpbmRleCwgY2hhciB2YWx1ZSkgeworICAgICAgICByZXR1cm4gcHV0U2hvcnQoaW5kZXgsIChzaG9ydCkgdmFsdWUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9CdWZmZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9CdWZmZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMzg0MGE1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0J1ZmZlci5qYXZhCkBAIC0wLDAgKzEsNDIzIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCisvKioKKyAqIEEgYnVmZmVyIGlzIGEgbGlzdCBvZiBlbGVtZW50cyBvZiBhIHNwZWNpZmljIHByaW1pdGl2ZSB0eXBlLgorICogPHA+CisgKiBBIGJ1ZmZlciBjYW4gYmUgZGVzY3JpYmVkIGJ5IHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczoKKyAqIDx1bD4KKyAqIDxsaT5DYXBhY2l0eTogdGhlIG51bWJlciBvZiBlbGVtZW50cyBhIGJ1ZmZlciBjYW4gaG9sZC4gQ2FwYWNpdHkgbWF5IG5vdCBiZQorICogbmVnYXRpdmUgYW5kIG5ldmVyIGNoYW5nZXMuPC9saT4KKyAqIDxsaT5Qb3NpdGlvbjogYSBjdXJzb3Igb2YgdGhpcyBidWZmZXIuIEVsZW1lbnRzIGFyZSByZWFkIG9yIHdyaXR0ZW4gYXQgdGhlCisgKiBwb3NpdGlvbiBpZiB5b3UgZG8gbm90IHNwZWNpZnkgYW4gaW5kZXggZXhwbGljaXRseS4gUG9zaXRpb24gbWF5IG5vdCBiZQorICogbmVnYXRpdmUgYW5kIG5vdCBncmVhdGVyIHRoYW4gdGhlIGxpbWl0LjwvbGk+CisgKiA8bGk+TGltaXQ6IGNvbnRyb2xzIHRoZSBzY29wZSBvZiBhY2Nlc3NpYmxlIGVsZW1lbnRzLiBZb3UgY2FuIG9ubHkgcmVhZCBvcgorICogd3JpdGUgZWxlbWVudHMgZnJvbSBpbmRleCB6ZXJvIHRvIDxjb2RlPmxpbWl0IC0gMTwvY29kZT4uIEFjY2Vzc2luZworICogZWxlbWVudHMgb3V0IG9mIHRoZSBzY29wZSB3aWxsIGNhdXNlIGFuIGV4Y2VwdGlvbi4gTGltaXQgbWF5IG5vdCBiZSBuZWdhdGl2ZQorICogYW5kIG5vdCBncmVhdGVyIHRoYW4gY2FwYWNpdHkuPC9saT4KKyAqIDxsaT5NYXJrOiB1c2VkIHRvIHJlbWVtYmVyIHRoZSBjdXJyZW50IHBvc2l0aW9uLCBzbyB0aGF0IHlvdSBjYW4gcmVzZXQgdGhlCisgKiBwb3NpdGlvbiBsYXRlci4gTWFyayBtYXkgbm90IGJlIG5lZ2F0aXZlIGFuZCBubyBncmVhdGVyIHRoYW4gcG9zaXRpb24uPC9saT4KKyAqIDxsaT5BIGJ1ZmZlciBjYW4gYmUgcmVhZC1vbmx5IG9yIHJlYWQtd3JpdGUuIFRyeWluZyB0byBtb2RpZnkgdGhlIGVsZW1lbnRzCisgKiBvZiBhIHJlYWQtb25seSBidWZmZXIgd2lsbCBjYXVzZSBhIDxjb2RlPlJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uPC9jb2RlPiwKKyAqIHdoaWxlIGNoYW5naW5nIHRoZSBwb3NpdGlvbiwgbGltaXQgYW5kIG1hcmsgb2YgYSByZWFkLW9ubHkgYnVmZmVyIGlzIE9LLjwvbGk+CisgKiA8bGk+QSBidWZmZXIgY2FuIGJlIGRpcmVjdCBvciBpbmRpcmVjdC4gQSBkaXJlY3QgYnVmZmVyIHdpbGwgdHJ5IGl0cyBiZXN0IHRvCisgKiB0YWtlIGFkdmFudGFnZSBvZiBuYXRpdmUgbWVtb3J5IEFQSXMgYW5kIGl0IG1heSBub3Qgc3RheSBpbiB0aGUgSmF2YSBoZWFwLAorICogdGh1cyBpdCBpcyBub3QgYWZmZWN0ZWQgYnkgZ2FyYmFnZSBjb2xsZWN0aW9uLjwvbGk+CisgKiA8L3VsPgorICogPHA+CisgKiBCdWZmZXJzIGFyZSBub3QgdGhyZWFkLXNhZmUuIElmIGNvbmN1cnJlbnQgYWNjZXNzIHRvIGEgYnVmZmVyIGluc3RhbmNlIGlzCisgKiByZXF1aXJlZCwgdGhlbiB0aGUgY2FsbGVycyBhcmUgcmVzcG9uc2libGUgdG8gdGFrZSBjYXJlIG9mIHRoZQorICogc3luY2hyb25pemF0aW9uIGlzc3Vlcy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEJ1ZmZlciB7CisgICAgLyoqCisgICAgICogPGNvZGU+VU5TRVRfTUFSSzwvY29kZT4gbWVhbnMgdGhlIG1hcmsgaGFzIG5vdCBiZWVuIHNldC4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgaW50IFVOU0VUX01BUksgPSAtMTsKKworICAgIC8qKgorICAgICAqIFRoZSBjYXBhY2l0eSBvZiB0aGlzIGJ1ZmZlciwgd2hpY2ggbmV2ZXIgY2hhbmdlcy4KKyAgICAgKi8KKyAgICBmaW5hbCBpbnQgY2FwYWNpdHk7CisKKyAgICAvKioKKyAgICAgKiA8Y29kZT5saW1pdCAtIDE8L2NvZGU+IGlzIHRoZSBsYXN0IGVsZW1lbnQgdGhhdCBjYW4gYmUgcmVhZCBvciB3cml0dGVuLgorICAgICAqIExpbWl0IG11c3QgYmUgbm8gbGVzcyB0aGFuIHplcm8gYW5kIG5vIGdyZWF0ZXIgdGhhbiA8Y29kZT5jYXBhY2l0eTwvY29kZT4uCisgICAgICovCisgICAgaW50IGxpbWl0OworCisgICAgLyoqCisgICAgICogTWFyayBpcyB3aGVyZSBwb3NpdGlvbiB3aWxsIGJlIHNldCB3aGVuIDxjb2RlPnJlc2V0KCk8L2NvZGU+IGlzIGNhbGxlZC4KKyAgICAgKiBNYXJrIGlzIG5vdCBzZXQgYnkgZGVmYXVsdC4gTWFyayBpcyBhbHdheXMgbm8gbGVzcyB0aGFuIHplcm8gYW5kIG5vCisgICAgICogZ3JlYXRlciB0aGFuIDxjb2RlPnBvc2l0aW9uPC9jb2RlPi4KKyAgICAgKi8KKyAgICBpbnQgbWFyayA9IFVOU0VUX01BUks7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY3VycmVudCBwb3NpdGlvbiBvZiB0aGlzIGJ1ZmZlci4gUG9zaXRpb24gaXMgYWx3YXlzIG5vIGxlc3MgdGhhbiB6ZXJvCisgICAgICogYW5kIG5vIGdyZWF0ZXIgdGhhbiA8Y29kZT5saW1pdDwvY29kZT4uCisgICAgICovCisgICAgaW50IHBvc2l0aW9uID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBsb2cgYmFzZSAyIG9mIHRoZSBlbGVtZW50IHNpemUgb2YgdGhpcyBidWZmZXIuICBFYWNoIHR5cGVkIHN1YmNsYXNzCisgICAgICogKEJ5dGVCdWZmZXIsIENoYXJCdWZmZXIsIGV0Yy4pIGlzIHJlc3BvbnNpYmxlIGZvciBpbml0aWFsaXppbmcgdGhpcworICAgICAqIHZhbHVlLiAgVGhlIHZhbHVlIGlzIHVzZWQgYnkgSk5JIGNvZGUgaW4gZnJhbWV3b3Jrcy9iYXNlLyB0byBhdm9pZCB0aGUKKyAgICAgKiBuZWVkIGZvciBjb3N0bHkgJ2luc3RhbmNlb2YnIHRlc3RzLgorICAgICAqLworICAgIGZpbmFsIGludCBfZWxlbWVudFNpemVTaGlmdDsKKworICAgIC8qKgorICAgICAqIEZvciBkaXJlY3QgYnVmZmVycywgdGhlIGVmZmVjdGl2ZSBhZGRyZXNzIG9mIHRoZSBkYXRhOyB6ZXJvIG90aGVyd2lzZS4KKyAgICAgKiBUaGlzIGlzIHNldCBpbiB0aGUgY29uc3RydWN0b3IuCisgICAgICogVE9ETzogbWFrZSB0aGlzIGZpbmFsIGF0IHRoZSBjb3N0IG9mIGxvYWRzIG9mIGV4dHJhIGNvbnN0cnVjdG9ycz8gW2hvdyBtYW55P10KKyAgICAgKi8KKyAgICBpbnQgZWZmZWN0aXZlRGlyZWN0QWRkcmVzczsKKworICAgIC8qKgorICAgICAqIEZvciBkaXJlY3QgYnVmZmVycywgdGhlIHVuZGVybHlpbmcgTWVtb3J5QmxvY2s7IG51bGwgb3RoZXJ3aXNlLgorICAgICAqLworICAgIGZpbmFsIE1lbW9yeUJsb2NrIGJsb2NrOworCisgICAgQnVmZmVyKGludCBlbGVtZW50U2l6ZVNoaWZ0LCBpbnQgY2FwYWNpdHksIE1lbW9yeUJsb2NrIGJsb2NrKSB7CisgICAgICAgIHRoaXMuX2VsZW1lbnRTaXplU2hpZnQgPSBlbGVtZW50U2l6ZVNoaWZ0OworICAgICAgICBpZiAoY2FwYWNpdHkgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJjYXBhY2l0eSA8IDA6ICIgKyBjYXBhY2l0eSk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5jYXBhY2l0eSA9IHRoaXMubGltaXQgPSBjYXBhY2l0eTsKKyAgICAgICAgdGhpcy5ibG9jayA9IGJsb2NrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFycmF5IHRoYXQgYmFja3MgdGhpcyBidWZmZXIgKG9wdGlvbmFsIG9wZXJhdGlvbikuCisgICAgICogVGhlIHJldHVybmVkIHZhbHVlIGlzIHRoZSBhY3R1YWwgYXJyYXksIG5vdCBhIGNvcHksIHNvIG1vZGlmaWNhdGlvbnMKKyAgICAgKiB0byB0aGUgYXJyYXkgd3JpdGUgdGhyb3VnaCB0byB0aGUgYnVmZmVyLgorICAgICAqCisgICAgICogPHA+U3ViY2xhc3NlcyBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2Qgd2l0aCBhIGNvdmFyaWFudCByZXR1cm4gdHlwZQorICAgICAqIHRvIHByb3ZpZGUgdGhlIGV4YWN0IHR5cGUgb2YgdGhlIGFycmF5LgorICAgICAqCisgICAgICogPHA+VXNlIHtAY29kZSBoYXNBcnJheX0gdG8gZW5zdXJlIHRoaXMgbWV0aG9kIHdvbid0IHRocm93LgorICAgICAqIChBIHNlcGFyYXRlIGNhbGwgdG8ge0Bjb2RlIGlzUmVhZE9ubHl9IGlzIG5vdCBuZWNlc3NhcnkuKQorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYXJyYXkKKyAgICAgKiBAdGhyb3dzIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uIGlmIHRoZSBidWZmZXIgaXMgcmVhZC1vbmx5CisgICAgICogICAgICAgICBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGUgYnVmZmVyIGRvZXMgbm90IGV4cG9zZSBhbiBhcnJheQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgT2JqZWN0IGFycmF5KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBvZmZzZXQgaW50byB0aGUgYXJyYXkgcmV0dXJuZWQgYnkge0Bjb2RlIGFycmF5fSBvZiB0aGUgZmlyc3QKKyAgICAgKiBlbGVtZW50IG9mIHRoZSBidWZmZXIgKG9wdGlvbmFsIG9wZXJhdGlvbikuIFRoZSBiYWNraW5nIGFycmF5IChpZiB0aGVyZSBpcyBvbmUpCisgICAgICogaXMgbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIHNpemUgYXMgdGhlIGJ1ZmZlciwgYW5kIHBvc2l0aW9uIDAgaW4gdGhlIGJ1ZmZlciBpcworICAgICAqIG5vdCBuZWNlc3NhcmlseSB0aGUgMHRoIGVsZW1lbnQgaW4gdGhlIGFycmF5LiBVc2UKKyAgICAgKiB7QGNvZGUgYnVmZmVyLmFycmF5KClbb2Zmc2V0ICsgYnVmZmVyLmFycmF5T2Zmc2V0KCl9IHRvIGFjY2VzcyBlbGVtZW50IHtAY29kZSBvZmZzZXR9CisgICAgICogaW4ge0Bjb2RlIGJ1ZmZlcn0uCisgICAgICoKKyAgICAgKiA8cD5Vc2Uge0Bjb2RlIGhhc0FycmF5fSB0byBlbnN1cmUgdGhpcyBtZXRob2Qgd29uJ3QgdGhyb3cuCisgICAgICogKEEgc2VwYXJhdGUgY2FsbCB0byB7QGNvZGUgaXNSZWFkT25seX0gaXMgbm90IG5lY2Vzc2FyeS4pCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBvZmZzZXQKKyAgICAgKiBAdGhyb3dzIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uIGlmIHRoZSBidWZmZXIgaXMgcmVhZC1vbmx5CisgICAgICogICAgICAgICBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGUgYnVmZmVyIGRvZXMgbm90IGV4cG9zZSBhbiBhcnJheQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGFycmF5T2Zmc2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjYXBhY2l0eSBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyB0aGF0IGFyZSBjb250YWluZWQgaW4gdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBjYXBhY2l0eSgpIHsKKyAgICAgICAgcmV0dXJuIGNhcGFjaXR5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFVzZWQgZm9yIHRoZSBzY2FsYXIgZ2V0L3B1dCBvcGVyYXRpb25zLgorICAgICAqLworICAgIHZvaWQgY2hlY2tJbmRleChpbnQgaW5kZXgpIHsKKyAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBsaW1pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oImluZGV4PSIgKyBpbmRleCArICIsIGxpbWl0PSIgKyBsaW1pdCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2VkIGZvciB0aGUgQnl0ZUJ1ZmZlciBvcGVyYXRpb25zIHRoYXQgZ2V0IHR5cGVzIGxhcmdlciB0aGFuIGEgYnl0ZS4KKyAgICAgKi8KKyAgICB2b2lkIGNoZWNrSW5kZXgoaW50IGluZGV4LCBpbnQgc2l6ZU9mVHlwZSkgeworICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID4gbGltaXQgLSBzaXplT2ZUeXBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiaW5kZXg9IiArIGluZGV4ICsgIiwgbGltaXQ9IiArIGxpbWl0ICsKKyAgICAgICAgICAgICAgICAgICAgIiwgc2l6ZSBvZiB0eXBlPSIgKyBzaXplT2ZUeXBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGludCBjaGVja0dldEJvdW5kcyhpbnQgYnl0ZXNQZXJFbGVtZW50LCBpbnQgbGVuZ3RoLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHsKKyAgICAgICAgaW50IGJ5dGVDb3VudCA9IGJ5dGVzUGVyRWxlbWVudCAqIGNvdW50OworICAgICAgICBpZiAoKG9mZnNldCB8IGNvdW50KSA8IDAgfHwgb2Zmc2V0ID4gbGVuZ3RoIHx8IGxlbmd0aCAtIG9mZnNldCA8IGNvdW50KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigib2Zmc2V0PSIgKyBvZmZzZXQgKworICAgICAgICAgICAgICAgICAgICAiLCBjb3VudD0iICsgY291bnQgKyAiLCBsZW5ndGg9IiArIGxlbmd0aCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJ5dGVDb3VudCA+IHJlbWFpbmluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ5dGVDb3VudDsKKyAgICB9CisKKyAgICBpbnQgY2hlY2tQdXRCb3VuZHMoaW50IGJ5dGVzUGVyRWxlbWVudCwgaW50IGxlbmd0aCwgaW50IG9mZnNldCwgaW50IGNvdW50KSB7CisgICAgICAgIGludCBieXRlQ291bnQgPSBieXRlc1BlckVsZW1lbnQgKiBjb3VudDsKKyAgICAgICAgaWYgKChvZmZzZXQgfCBjb3VudCkgPCAwIHx8IG9mZnNldCA+IGxlbmd0aCB8fCBsZW5ndGggLSBvZmZzZXQgPCBjb3VudCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oIm9mZnNldD0iICsgb2Zmc2V0ICsKKyAgICAgICAgICAgICAgICAgICAgIiwgY291bnQ9IiArIGNvdW50ICsgIiwgbGVuZ3RoPSIgKyBsZW5ndGgpOworICAgICAgICB9CisgICAgICAgIGlmIChieXRlQ291bnQgPiByZW1haW5pbmcoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlzUmVhZE9ubHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ5dGVDb3VudDsKKyAgICB9CisKKyAgICB2b2lkIGNoZWNrU3RhcnRFbmRSZW1haW5pbmcoaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIGlmIChlbmQgPCBzdGFydCB8fCBzdGFydCA8IDAgfHwgZW5kID4gcmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJzdGFydD0iICsgc3RhcnQgKyAiLCBlbmQ9IiArIGVuZCArCisgICAgICAgICAgICAgICAgICAgICIsIHJlbWFpbmluZygpPSIgKyByZW1haW5pbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbGVhcnMgdGhpcyBidWZmZXIuCisgICAgICogPHA+CisgICAgICogV2hpbGUgdGhlIGNvbnRlbnQgb2YgdGhpcyBidWZmZXIgaXMgbm90IGNoYW5nZWQsIHRoZSBmb2xsb3dpbmcgaW50ZXJuYWwKKyAgICAgKiBjaGFuZ2VzIHRha2UgcGxhY2U6IHRoZSBjdXJyZW50IHBvc2l0aW9uIGlzIHJlc2V0IGJhY2sgdG8gdGhlIHN0YXJ0IG9mCisgICAgICogdGhlIGJ1ZmZlciwgdGhlIHZhbHVlIG9mIHRoZSBidWZmZXIgbGltaXQgaXMgbWFkZSBlcXVhbCB0byB0aGUgY2FwYWNpdHkKKyAgICAgKiBhbmQgbWFyayBpcyBjbGVhcmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQnVmZmVyIGNsZWFyKCkgeworICAgICAgICBwb3NpdGlvbiA9IDA7CisgICAgICAgIG1hcmsgPSBVTlNFVF9NQVJLOworICAgICAgICBsaW1pdCA9IGNhcGFjaXR5OworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGbGlwcyB0aGlzIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbGltaXQgaXMgc2V0IHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uLCB0aGVuIHRoZSBwb3NpdGlvbiBpcyBzZXQgdG8KKyAgICAgKiB6ZXJvLCBhbmQgdGhlIG1hcmsgaXMgY2xlYXJlZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgY29udGVudCBvZiB0aGlzIGJ1ZmZlciBpcyBub3QgY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEJ1ZmZlciBmbGlwKCkgeworICAgICAgICBsaW1pdCA9IHBvc2l0aW9uOworICAgICAgICBwb3NpdGlvbiA9IDA7CisgICAgICAgIG1hcmsgPSBVTlNFVF9NQVJLOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYge0Bjb2RlIGFycmF5fSBhbmQge0Bjb2RlIGFycmF5T2Zmc2V0fSB3b24ndCB0aHJvdy4gVGhpcyBtZXRob2QgZG9lcyBub3QKKyAgICAgKiByZXR1cm4gdHJ1ZSBmb3IgYnVmZmVycyBub3QgYmFja2VkIGJ5IGFycmF5cyBiZWNhdXNlIHRoZSBvdGhlciBtZXRob2RzIHdvdWxkIHRocm93CisgICAgICoge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufSwgbm9yIGRvZXMgaXQgcmV0dXJuIHRydWUgZm9yIGJ1ZmZlcnMgYmFja2VkIGJ5CisgICAgICogcmVhZC1vbmx5IGFycmF5cywgYmVjYXVzZSB0aGUgb3RoZXIgbWV0aG9kcyB3b3VsZCB0aHJvdyB7QGNvZGUgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb259LgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBoYXNBcnJheSgpOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIGlmIHRoZXJlIGFyZSBlbGVtZW50cyByZW1haW5pbmcgaW4gdGhpcyBidWZmZXIsIHRoYXQgaXMgaWYKKyAgICAgKiB7QGNvZGUgcG9zaXRpb24gPCBsaW1pdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGVyZSBhcmUgZWxlbWVudHMgcmVtYWluaW5nIGluIHRoaXMgYnVmZmVyLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaGFzUmVtYWluaW5nKCkgeworICAgICAgICByZXR1cm4gcG9zaXRpb24gPCBsaW1pdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhIGRpcmVjdCBidWZmZXIuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzRGlyZWN0KCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIGJ1ZmZlciBpcyByZWFkLW9ubHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGJ1ZmZlciBpcyByZWFkLW9ubHksIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc1JlYWRPbmx5KCk7CisKKyAgICBmaW5hbCB2b2lkIGNoZWNrV3JpdGFibGUoKSB7CisgICAgICAgIGlmIChpc1JlYWRPbmx5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInJlYWQtb25seSBidWZmZXIiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxpbWl0IG9mIHRoaXMgYnVmZmVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGltaXQgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBsaW1pdCgpIHsKKyAgICAgICAgcmV0dXJuIGxpbWl0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGxpbWl0IG9mIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBidWZmZXIgaXMgaW4gZXhjZXNzIG9mCisgICAgICogPGNvZGU+bmV3TGltaXQ8L2NvZGU+IHRoZW4sIG9uIHJldHVybmluZyBmcm9tIHRoaXMgY2FsbCwgaXQgd2lsbCBoYXZlCisgICAgICogYmVlbiBhZGp1c3RlZCB0byBiZSBlcXVpdmFsZW50IHRvIDxjb2RlPm5ld0xpbWl0PC9jb2RlPi4gSWYgdGhlIG1hcmsKKyAgICAgKiBpcyBzZXQgYW5kIGlzIGdyZWF0ZXIgdGhhbiB0aGUgbmV3IGxpbWl0LCB0aGVuIGl0IGlzIGNsZWFyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3TGltaXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgbGltaXQsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgICAgICBjYXBhY2l0eS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgPGNvZGU+bmV3TGltaXQ8L2NvZGU+IGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEJ1ZmZlciBsaW1pdChpbnQgbmV3TGltaXQpIHsKKyAgICAgICAgbGltaXRJbXBsKG5ld0xpbWl0KTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3VidmVydHMgdGhlIGZhY3QgdGhhdCBsaW1pdChpbnQpIGlzIGZpbmFsLCBmb3IgdGhlIGJlbmVmaXQgb2YgTWFwcGVkQnl0ZUJ1ZmZlckFkYXB0ZXIuCisgICAgICovCisgICAgdm9pZCBsaW1pdEltcGwoaW50IG5ld0xpbWl0KSB7CisgICAgICAgIGlmIChuZXdMaW1pdCA8IDAgfHwgbmV3TGltaXQgPiBjYXBhY2l0eSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQmFkIGxpbWl0IChjYXBhY2l0eSAiICsgY2FwYWNpdHkgKyAiKTogIiArIG5ld0xpbWl0KTsKKyAgICAgICAgfQorCisgICAgICAgIGxpbWl0ID0gbmV3TGltaXQ7CisgICAgICAgIGlmIChwb3NpdGlvbiA+IG5ld0xpbWl0KSB7CisgICAgICAgICAgICBwb3NpdGlvbiA9IG5ld0xpbWl0OworICAgICAgICB9CisgICAgICAgIGlmICgobWFyayAhPSBVTlNFVF9NQVJLKSAmJiAobWFyayA+IG5ld0xpbWl0KSkgeworICAgICAgICAgICAgbWFyayA9IFVOU0VUX01BUks7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXJrcyB0aGUgY3VycmVudCBwb3NpdGlvbiwgc28gdGhhdCB0aGUgcG9zaXRpb24gbWF5IHJldHVybiB0byB0aGlzIHBvaW50CisgICAgICogbGF0ZXIgYnkgY2FsbGluZyA8Y29kZT5yZXNldCgpPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEJ1ZmZlciBtYXJrKCkgeworICAgICAgICBtYXJrID0gcG9zaXRpb247CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHBvc2l0aW9uIG9mIHRoaXMgYnVmZmVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhpcyBidWZmZXIncyBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgcG9zaXRpb24oKSB7CisgICAgICAgIHJldHVybiBwb3NpdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwb3NpdGlvbiBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgbWFyayBpcyBzZXQgYW5kIGl0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbmV3IHBvc2l0aW9uLCB0aGVuIGl0IGlzCisgICAgICogY2xlYXJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdQb3NpdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBwb3NpdGlvbiwgbXVzdCBiZSBub3QgbmVnYXRpdmUgYW5kIG5vdCBncmVhdGVyIHRoYW4KKyAgICAgKiAgICAgICAgICAgIGxpbWl0LgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiA8Y29kZT5uZXdQb3NpdGlvbjwvY29kZT4gaXMgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQnVmZmVyIHBvc2l0aW9uKGludCBuZXdQb3NpdGlvbikgeworICAgICAgICBwb3NpdGlvbkltcGwobmV3UG9zaXRpb24pOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICB2b2lkIHBvc2l0aW9uSW1wbChpbnQgbmV3UG9zaXRpb24pIHsKKyAgICAgICAgaWYgKG5ld1Bvc2l0aW9uIDwgMCB8fCBuZXdQb3NpdGlvbiA+IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJCYWQgcG9zaXRpb24gKGxpbWl0ICIgKyBsaW1pdCArICIpOiAiICsgbmV3UG9zaXRpb24pOworICAgICAgICB9CisKKyAgICAgICAgcG9zaXRpb24gPSBuZXdQb3NpdGlvbjsKKyAgICAgICAgaWYgKChtYXJrICE9IFVOU0VUX01BUkspICYmIChtYXJrID4gcG9zaXRpb24pKSB7CisgICAgICAgICAgICBtYXJrID0gVU5TRVRfTUFSSzsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiByZW1haW5pbmcgZWxlbWVudHMgaW4gdGhpcyBidWZmZXIsIHRoYXQgaXMKKyAgICAgKiB7QGNvZGUgbGltaXQgLSBwb3NpdGlvbn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgcmVtYWluaW5nIGVsZW1lbnRzIGluIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgcmVtYWluaW5nKCkgeworICAgICAgICByZXR1cm4gbGltaXQgLSBwb3NpdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhlIHBvc2l0aW9uIG9mIHRoaXMgYnVmZmVyIHRvIHRoZSA8Y29kZT5tYXJrPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBJbnZhbGlkTWFya0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSBtYXJrIGlzIG5vdCBzZXQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEJ1ZmZlciByZXNldCgpIHsKKyAgICAgICAgaWYgKG1hcmsgPT0gVU5TRVRfTUFSSykgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRNYXJrRXhjZXB0aW9uKCJNYXJrIG5vdCBzZXQiKTsKKyAgICAgICAgfQorICAgICAgICBwb3NpdGlvbiA9IG1hcms7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJld2luZHMgdGhpcyBidWZmZXIuCisgICAgICogPHA+CisgICAgICogVGhlIHBvc2l0aW9uIGlzIHNldCB0byB6ZXJvLCBhbmQgdGhlIG1hcmsgaXMgY2xlYXJlZC4gVGhlIGNvbnRlbnQgb2YgdGhpcworICAgICAqIGJ1ZmZlciBpcyBub3QgY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEJ1ZmZlciByZXdpbmQoKSB7CisgICAgICAgIHBvc2l0aW9uID0gMDsKKyAgICAgICAgbWFyayA9IFVOU0VUX01BUks7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGJ1Zi5hcHBlbmQoZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworICAgICAgICBidWYuYXBwZW5kKCIsIHN0YXR1czogY2FwYWNpdHk9Iik7CisgICAgICAgIGJ1Zi5hcHBlbmQoY2FwYWNpdHkpOworICAgICAgICBidWYuYXBwZW5kKCIgcG9zaXRpb249Iik7CisgICAgICAgIGJ1Zi5hcHBlbmQocG9zaXRpb24pOworICAgICAgICBidWYuYXBwZW5kKCIgbGltaXQ9Iik7CisgICAgICAgIGJ1Zi5hcHBlbmQobGltaXQpOworICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0J1ZmZlck92ZXJmbG93RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MjhmY2VkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0J1ZmZlck92ZXJmbG93RXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzMiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworLyoqCisgKiBBIDxjb2RlPkJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gd2hlbiBlbGVtZW50cyBhcmUgd3JpdHRlbgorICogdG8gYSBidWZmZXIgYnV0IHRoZXJlIGlzIG5vdCBlbm91Z2ggcmVtYWluaW5nIHNwYWNlIGluIHRoZSBidWZmZXIuCisgKi8KK3B1YmxpYyBjbGFzcyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTU0ODQ4OTc2MzQzMTkxNDQ1MzVMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIDxjb2RlPkJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0J1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0J1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA4MThhZTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzMiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworLyoqCisgKiBBIDxjb2RlPkJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duIHdoZW4gZWxlbWVudHMgYXJlIHJlYWQKKyAqIGZyb20gYSBidWZmZXIgYnV0IHRoZXJlIGFyZSBub3QgZW5vdWdoIHJlbWFpbmluZyBlbGVtZW50cyBpbiB0aGUgYnVmZmVyLgorICovCitwdWJsaWMgY2xhc3MgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTcxMzMxMzY1ODY5MTYyMjIwNkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgPGNvZGU+QnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9CeXRlQnVmZmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vQnl0ZUJ1ZmZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVmNzI1YzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vQnl0ZUJ1ZmZlci5qYXZhCkBAIC0wLDAgKzEsMTAzNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgbGliY29yZS5pby5NZW1vcnk7CisKKy8qKgorICogQSBidWZmZXIgZm9yIGJ5dGVzLgorICogPHA+CisgKiBBIGJ5dGUgYnVmZmVyIGNhbiBiZSBjcmVhdGVkIGluIGVpdGhlciBvbmUgb2YgdGhlIGZvbGxvd2luZyB3YXlzOgorICogPHVsPgorICogPGxpPntAbGluayAjYWxsb2NhdGUoaW50KSBBbGxvY2F0ZX0gYSBuZXcgYnl0ZSBhcnJheSBhbmQgY3JlYXRlIGEgYnVmZmVyCisgKiBiYXNlZCBvbiBpdDs8L2xpPgorICogPGxpPntAbGluayAjYWxsb2NhdGVEaXJlY3QoaW50KSBBbGxvY2F0ZX0gYSBtZW1vcnkgYmxvY2sgYW5kIGNyZWF0ZSBhIGRpcmVjdAorICogYnVmZmVyIGJhc2VkIG9uIGl0OzwvbGk+CisgKiA8bGk+e0BsaW5rICN3cmFwKGJ5dGVbXSkgV3JhcH0gYW4gZXhpc3RpbmcgYnl0ZSBhcnJheSB0byBjcmVhdGUgYSBuZXcKKyAqIGJ1ZmZlci48L2xpPgorICogPC91bD4KKyAqCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBCeXRlQnVmZmVyIGV4dGVuZHMgQnVmZmVyIGltcGxlbWVudHMgQ29tcGFyYWJsZTxCeXRlQnVmZmVyPiB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgYnl0ZSBidWZmZXIgYmFzZWQgb24gYSBuZXdseSBhbGxvY2F0ZWQgYnl0ZSBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXBhY2l0eQorICAgICAqICAgICAgICAgICAgdGhlIGNhcGFjaXR5IG9mIHRoZSBuZXcgYnVmZmVyCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCBieXRlIGJ1ZmZlci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBjYXBhY2l0eSA8IDB9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQnl0ZUJ1ZmZlciBhbGxvY2F0ZShpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgaWYgKGNhcGFjaXR5IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgUmVhZFdyaXRlSGVhcEJ5dGVCdWZmZXIoY2FwYWNpdHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBkaXJlY3QgYnl0ZSBidWZmZXIgYmFzZWQgb24gYSBuZXdseSBhbGxvY2F0ZWQgbWVtb3J5IGJsb2NrLgorICAgICAqCisgICAgICogQHBhcmFtIGNhcGFjaXR5CisgICAgICogICAgICAgICAgICB0aGUgY2FwYWNpdHkgb2YgdGhlIG5ldyBidWZmZXIKKyAgICAgKiBAcmV0dXJuIHRoZSBjcmVhdGVkIGJ5dGUgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGNhcGFjaXR5IDwgMH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCeXRlQnVmZmVyIGFsbG9jYXRlRGlyZWN0KGludCBjYXBhY2l0eSkgeworICAgICAgICBpZiAoY2FwYWNpdHkgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBSZWFkV3JpdGVEaXJlY3RCeXRlQnVmZmVyKGNhcGFjaXR5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGJ5dGUgYnVmZmVyIGJ5IHdyYXBwaW5nIHRoZSBnaXZlbiBieXRlIGFycmF5LgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcworICAgICAqIHtAY29kZSB3cmFwKGFycmF5LCAwLCBhcnJheS5sZW5ndGgpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYXJyYXkgd2hpY2ggdGhlIG5ldyBidWZmZXIgd2lsbCBiZSBiYXNlZCBvbgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgYnl0ZSBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCeXRlQnVmZmVyIHdyYXAoYnl0ZVtdIGFycmF5KSB7CisgICAgICAgIHJldHVybiBuZXcgUmVhZFdyaXRlSGVhcEJ5dGVCdWZmZXIoYXJyYXkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgYnl0ZSBidWZmZXIgYnkgd3JhcHBpbmcgdGhlIGdpdmVuIGJ5dGUgYXJyYXkuCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIncyBwb3NpdGlvbiB3aWxsIGJlIHtAY29kZSBzdGFydH0sIGxpbWl0IHdpbGwgYmUKKyAgICAgKiB7QGNvZGUgc3RhcnQgKyBieXRlQ291bnR9LCBjYXBhY2l0eSB3aWxsIGJlIHRoZSBsZW5ndGggb2YgdGhlIGFycmF5LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSBhcnJheSB3aGljaCB0aGUgbmV3IGJ1ZmZlciB3aWxsIGJlIGJhc2VkIG9uLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IGluZGV4LCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBhbmQgbm90IGdyZWF0ZXIgdGhhbgorICAgICAqICAgICAgICAgICAge0Bjb2RlIGFycmF5Lmxlbmd0aH0uCisgICAgICogQHBhcmFtIGJ5dGVDb3VudAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIG5vdCBncmVhdGVyIHRoYW4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBhcnJheS5sZW5ndGggLSBzdGFydH0uCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCBieXRlIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBlaXRoZXIge0Bjb2RlIHN0YXJ0fSBvciB7QGNvZGUgYnl0ZUNvdW50fSBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQnl0ZUJ1ZmZlciB3cmFwKGJ5dGVbXSBhcnJheSwgaW50IHN0YXJ0LCBpbnQgYnl0ZUNvdW50KSB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGFycmF5Lmxlbmd0aCwgc3RhcnQsIGJ5dGVDb3VudCk7CisgICAgICAgIEJ5dGVCdWZmZXIgYnVmID0gbmV3IFJlYWRXcml0ZUhlYXBCeXRlQnVmZmVyKGFycmF5KTsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gc3RhcnQ7CisgICAgICAgIGJ1Zi5saW1pdCA9IHN0YXJ0ICsgYnl0ZUNvdW50OworICAgICAgICByZXR1cm4gYnVmOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBieXRlIG9yZGVyIG9mIHRoaXMgYnVmZmVyLCBkZWZhdWx0IGlzIHtAY29kZSBCSUdfRU5ESUFOfS4KKyAgICAgKi8KKyAgICBCeXRlT3JkZXIgb3JkZXIgPSBCeXRlT3JkZXIuQklHX0VORElBTjsKKworICAgIEJ5dGVCdWZmZXIoaW50IGNhcGFjaXR5LCBNZW1vcnlCbG9jayBibG9jaykgeworICAgICAgICBzdXBlcigwLCBjYXBhY2l0eSwgYmxvY2spOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGJ5dGUgYXJyYXkgd2hpY2ggdGhpcyBidWZmZXIgaXMgYmFzZWQgb24sIGlmIHRoZXJlIGlzIG9uZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgYXJyYXkgd2hpY2ggdGhpcyBidWZmZXIgaXMgYmFzZWQgb24uCisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoaXMgYnVmZmVyIGlzIGJhc2VkIG9uIGEgcmVhZC1vbmx5IGFycmF5LgorICAgICAqIEBleGNlcHRpb24gVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGlzIGJ1ZmZlciBpcyBub3QgYmFzZWQgb24gYW4gYXJyYXkuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJ5dGVbXSBhcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIHByb3RlY3RlZEFycmF5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgb2Zmc2V0IG9mIHRoZSBieXRlIGFycmF5IHdoaWNoIHRoaXMgYnVmZmVyIGlzIGJhc2VkIG9uLCBpZgorICAgICAqIHRoZXJlIGlzIG9uZS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgb2Zmc2V0IGlzIHRoZSBpbmRleCBvZiB0aGUgYXJyYXkgd2hpY2ggY29ycmVzcG9uZHMgdG8gdGhlIHplcm8KKyAgICAgKiBwb3NpdGlvbiBvZiB0aGUgYnVmZmVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgb2Zmc2V0IG9mIHRoZSBieXRlIGFycmF5IHdoaWNoIHRoaXMgYnVmZmVyIGlzIGJhc2VkIG9uLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGlzIGJ1ZmZlciBpcyBiYXNlZCBvbiBhIHJlYWQtb25seSBhcnJheS4KKyAgICAgKiBAZXhjZXB0aW9uIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhpcyBidWZmZXIgaXMgbm90IGJhc2VkIG9uIGFuIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgYXJyYXlPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBwcm90ZWN0ZWRBcnJheU9mZnNldCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjaGFyIGJ1ZmZlciB3aGljaCBpcyBiYXNlZCBvbiB0aGUgcmVtYWluaW5nIGNvbnRlbnQgb2YgdGhpcworICAgICAqIGJ5dGUgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyJ3MgcG9zaXRpb24gaXMgemVybywgaXRzIGxpbWl0IGFuZCBjYXBhY2l0eSBpcyB0aGUgbnVtYmVyCisgICAgICogb2YgcmVtYWluaW5nIGJ5dGVzIGRpdmlkZWQgYnkgdHdvLCBhbmQgaXRzIG1hcmsgaXMgbm90IHNldC4gVGhlIG5ldworICAgICAqIGJ1ZmZlcidzIHJlYWQtb25seSBwcm9wZXJ0eSBhbmQgYnl0ZSBvcmRlciBhcmUgdGhlIHNhbWUgYXMgdGhpcyBidWZmZXIncy4KKyAgICAgKiBUaGUgbmV3IGJ1ZmZlciBpcyBkaXJlY3QgaWYgdGhpcyBieXRlIGJ1ZmZlciBpcyBkaXJlY3QuCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIsIHdoaWNoIG1lYW5zIGVpdGhlcgorICAgICAqIGJ1ZmZlcidzIGNoYW5nZSBvZiBjb250ZW50IHdpbGwgYmUgdmlzaWJsZSB0byB0aGUgb3RoZXIuIFRoZSB0d28gYnVmZmVyJ3MKKyAgICAgKiBwb3NpdGlvbiwgbGltaXQgYW5kIG1hcmsgYXJlIGluZGVwZW5kZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIGNoYXIgYnVmZmVyIHdoaWNoIGlzIGJhc2VkIG9uIHRoZSBjb250ZW50IG9mIHRoaXMgYnl0ZSBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENoYXJCdWZmZXIgYXNDaGFyQnVmZmVyKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgZG91YmxlIGJ1ZmZlciB3aGljaCBpcyBiYXNlZCBvbiB0aGUgcmVtYWluaW5nIGNvbnRlbnQgb2YgdGhpcworICAgICAqIGJ5dGUgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyJ3MgcG9zaXRpb24gaXMgemVybywgaXRzIGxpbWl0IGFuZCBjYXBhY2l0eSBpcyB0aGUgbnVtYmVyCisgICAgICogb2YgcmVtYWluaW5nIGJ5dGVzIGRpdmlkZWQgYnkgZWlnaHQsIGFuZCBpdHMgbWFyayBpcyBub3Qgc2V0LiBUaGUgbmV3CisgICAgICogYnVmZmVyJ3MgcmVhZC1vbmx5IHByb3BlcnR5IGFuZCBieXRlIG9yZGVyIGFyZSB0aGUgc2FtZSBhcyB0aGlzIGJ1ZmZlcidzLgorICAgICAqIFRoZSBuZXcgYnVmZmVyIGlzIGRpcmVjdCBpZiB0aGlzIGJ5dGUgYnVmZmVyIGlzIGRpcmVjdC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbmV3IGJ1ZmZlciBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlciwgd2hpY2ggbWVhbnMgZWl0aGVyCisgICAgICogYnVmZmVyJ3MgY2hhbmdlIG9mIGNvbnRlbnQgd2lsbCBiZSB2aXNpYmxlIHRvIHRoZSBvdGhlci4gVGhlIHR3byBidWZmZXIncworICAgICAqIHBvc2l0aW9uLCBsaW1pdCBhbmQgbWFyayBhcmUgaW5kZXBlbmRlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgZG91YmxlIGJ1ZmZlciB3aGljaCBpcyBiYXNlZCBvbiB0aGUgY29udGVudCBvZiB0aGlzIGJ5dGUKKyAgICAgKiAgICAgICAgIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRG91YmxlQnVmZmVyIGFzRG91YmxlQnVmZmVyKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgZmxvYXQgYnVmZmVyIHdoaWNoIGlzIGJhc2VkIG9uIHRoZSByZW1haW5pbmcgY29udGVudCBvZiB0aGlzCisgICAgICogYnl0ZSBidWZmZXIuCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIncyBwb3NpdGlvbiBpcyB6ZXJvLCBpdHMgbGltaXQgYW5kIGNhcGFjaXR5IGlzIHRoZSBudW1iZXIKKyAgICAgKiBvZiByZW1haW5pbmcgYnl0ZXMgZGl2aWRlZCBieSBmb3VyLCBhbmQgaXRzIG1hcmsgaXMgbm90IHNldC4gVGhlIG5ldworICAgICAqIGJ1ZmZlcidzIHJlYWQtb25seSBwcm9wZXJ0eSBhbmQgYnl0ZSBvcmRlciBhcmUgdGhlIHNhbWUgYXMgdGhpcyBidWZmZXIncy4KKyAgICAgKiBUaGUgbmV3IGJ1ZmZlciBpcyBkaXJlY3QgaWYgdGhpcyBieXRlIGJ1ZmZlciBpcyBkaXJlY3QuCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIsIHdoaWNoIG1lYW5zIGVpdGhlcgorICAgICAqIGJ1ZmZlcidzIGNoYW5nZSBvZiBjb250ZW50IHdpbGwgYmUgdmlzaWJsZSB0byB0aGUgb3RoZXIuIFRoZSB0d28gYnVmZmVyJ3MKKyAgICAgKiBwb3NpdGlvbiwgbGltaXQgYW5kIG1hcmsgYXJlIGluZGVwZW5kZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIGZsb2F0IGJ1ZmZlciB3aGljaCBpcyBiYXNlZCBvbiB0aGUgY29udGVudCBvZiB0aGlzIGJ5dGUgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBGbG9hdEJ1ZmZlciBhc0Zsb2F0QnVmZmVyKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgaW50IGJ1ZmZlciB3aGljaCBpcyBiYXNlZCBvbiB0aGUgcmVtYWluaW5nIGNvbnRlbnQgb2YgdGhpcyBieXRlCisgICAgICogYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyJ3MgcG9zaXRpb24gaXMgemVybywgaXRzIGxpbWl0IGFuZCBjYXBhY2l0eSBpcyB0aGUgbnVtYmVyCisgICAgICogb2YgcmVtYWluaW5nIGJ5dGVzIGRpdmlkZWQgYnkgZm91ciwgYW5kIGl0cyBtYXJrIGlzIG5vdCBzZXQuIFRoZSBuZXcKKyAgICAgKiBidWZmZXIncyByZWFkLW9ubHkgcHJvcGVydHkgYW5kIGJ5dGUgb3JkZXIgYXJlIHRoZSBzYW1lIGFzIHRoaXMgYnVmZmVyJ3MuCisgICAgICogVGhlIG5ldyBidWZmZXIgaXMgZGlyZWN0IGlmIHRoaXMgYnl0ZSBidWZmZXIgaXMgZGlyZWN0LgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyIHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLCB3aGljaCBtZWFucyBlaXRoZXIKKyAgICAgKiBidWZmZXIncyBjaGFuZ2Ugb2YgY29udGVudCB3aWxsIGJlIHZpc2libGUgdG8gdGhlIG90aGVyLiBUaGUgdHdvIGJ1ZmZlcidzCisgICAgICogcG9zaXRpb24sIGxpbWl0IGFuZCBtYXJrIGFyZSBpbmRlcGVuZGVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBpbnQgYnVmZmVyIHdoaWNoIGlzIGJhc2VkIG9uIHRoZSBjb250ZW50IG9mIHRoaXMgYnl0ZSBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEludEJ1ZmZlciBhc0ludEJ1ZmZlcigpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGxvbmcgYnVmZmVyIHdoaWNoIGlzIGJhc2VkIG9uIHRoZSByZW1haW5pbmcgY29udGVudCBvZiB0aGlzCisgICAgICogYnl0ZSBidWZmZXIuCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIncyBwb3NpdGlvbiBpcyB6ZXJvLCBpdHMgbGltaXQgYW5kIGNhcGFjaXR5IGlzIHRoZSBudW1iZXIKKyAgICAgKiBvZiByZW1haW5pbmcgYnl0ZXMgZGl2aWRlZCBieSBlaWdodCwgYW5kIGl0cyBtYXJrIGlzIG5vdCBzZXQuIFRoZSBuZXcKKyAgICAgKiBidWZmZXIncyByZWFkLW9ubHkgcHJvcGVydHkgYW5kIGJ5dGUgb3JkZXIgYXJlIHRoZSBzYW1lIGFzIHRoaXMgYnVmZmVyJ3MuCisgICAgICogVGhlIG5ldyBidWZmZXIgaXMgZGlyZWN0IGlmIHRoaXMgYnl0ZSBidWZmZXIgaXMgZGlyZWN0LgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyIHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLCB3aGljaCBtZWFucyBlaXRoZXIKKyAgICAgKiBidWZmZXIncyBjaGFuZ2Ugb2YgY29udGVudCB3aWxsIGJlIHZpc2libGUgdG8gdGhlIG90aGVyLiBUaGUgdHdvIGJ1ZmZlcidzCisgICAgICogcG9zaXRpb24sIGxpbWl0IGFuZCBtYXJrIGFyZSBpbmRlcGVuZGVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBsb25nIGJ1ZmZlciB3aGljaCBpcyBiYXNlZCBvbiB0aGUgY29udGVudCBvZiB0aGlzIGJ5dGUgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBMb25nQnVmZmVyIGFzTG9uZ0J1ZmZlcigpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHJlYWQtb25seSBidWZmZXIgdGhhdCBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcmV0dXJuZWQgYnVmZmVyIGlzIGd1YXJhbnRlZWQgdG8gYmUgYSBuZXcgaW5zdGFuY2UsIGV2ZW4gaWYgdGhpcworICAgICAqIGJ1ZmZlciBpcyByZWFkLW9ubHkgaXRzZWxmLiBUaGUgbmV3IGJ1ZmZlcidzIHBvc2l0aW9uLCBsaW1pdCwgY2FwYWNpdHkKKyAgICAgKiBhbmQgbWFyayBhcmUgdGhlIHNhbWUgYXMgdGhpcyBidWZmZXIuCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIsIHdoaWNoIG1lYW5zIHRoaXMKKyAgICAgKiBidWZmZXIncyBjaGFuZ2Ugb2YgY29udGVudCB3aWxsIGJlIHZpc2libGUgdG8gdGhlIG5ldyBidWZmZXIuIFRoZSB0d28KKyAgICAgKiBidWZmZXIncyBwb3NpdGlvbiwgbGltaXQgYW5kIG1hcmsgYXJlIGluZGVwZW5kZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIHJlYWQtb25seSB2ZXJzaW9uIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCeXRlQnVmZmVyIGFzUmVhZE9ubHlCdWZmZXIoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzaG9ydCBidWZmZXIgd2hpY2ggaXMgYmFzZWQgb24gdGhlIHJlbWFpbmluZyBjb250ZW50IG9mIHRoaXMKKyAgICAgKiBieXRlIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbmV3IGJ1ZmZlcidzIHBvc2l0aW9uIGlzIHplcm8sIGl0cyBsaW1pdCBhbmQgY2FwYWNpdHkgaXMgdGhlIG51bWJlcgorICAgICAqIG9mIHJlbWFpbmluZyBieXRlcyBkaXZpZGVkIGJ5IHR3bywgYW5kIGl0cyBtYXJrIGlzIG5vdCBzZXQuIFRoZSBuZXcKKyAgICAgKiBidWZmZXIncyByZWFkLW9ubHkgcHJvcGVydHkgYW5kIGJ5dGUgb3JkZXIgYXJlIHRoZSBzYW1lIGFzIHRoaXMgYnVmZmVyJ3MuCisgICAgICogVGhlIG5ldyBidWZmZXIgaXMgZGlyZWN0IGlmIHRoaXMgYnl0ZSBidWZmZXIgaXMgZGlyZWN0LgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyIHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLCB3aGljaCBtZWFucyBlaXRoZXIKKyAgICAgKiBidWZmZXIncyBjaGFuZ2Ugb2YgY29udGVudCB3aWxsIGJlIHZpc2libGUgdG8gdGhlIG90aGVyLiBUaGUgdHdvIGJ1ZmZlcidzCisgICAgICogcG9zaXRpb24sIGxpbWl0IGFuZCBtYXJrIGFyZSBpbmRlcGVuZGVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzaG9ydCBidWZmZXIgd2hpY2ggaXMgYmFzZWQgb24gdGhlIGNvbnRlbnQgb2YgdGhpcyBieXRlIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2hvcnRCdWZmZXIgYXNTaG9ydEJ1ZmZlcigpOworCisgICAgLyoqCisgICAgICogQ29tcGFjdHMgdGhpcyBieXRlIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcmVtYWluaW5nIGJ5dGVzIHdpbGwgYmUgbW92ZWQgdG8gdGhlIGhlYWQgb2YgdGhlCisgICAgICogYnVmZmVyLCBzdGFydGluZyBmcm9tIHBvc2l0aW9uIHplcm8uIFRoZW4gdGhlIHBvc2l0aW9uIGlzIHNldCB0bworICAgICAqIHtAY29kZSByZW1haW5pbmcoKX07IHRoZSBsaW1pdCBpcyBzZXQgdG8gY2FwYWNpdHk7IHRoZSBtYXJrIGlzCisgICAgICogY2xlYXJlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXN9CisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCeXRlQnVmZmVyIGNvbXBhY3QoKTsKKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSByZW1haW5pbmcgYnl0ZXMgb2YgdGhpcyBidWZmZXIgdG8gYW5vdGhlciBieXRlIGJ1ZmZlcidzCisgICAgICogcmVtYWluaW5nIGJ5dGVzLgorICAgICAqCisgICAgICogQHBhcmFtIG90aGVyQnVmZmVyCisgICAgICogICAgICAgICAgICBhbm90aGVyIGJ5dGUgYnVmZmVyLgorICAgICAqIEByZXR1cm4gYSBuZWdhdGl2ZSB2YWx1ZSBpZiB0aGlzIGlzIGxlc3MgdGhhbiB7QGNvZGUgb3RoZXJ9OyAwIGlmIHRoaXMKKyAgICAgKiAgICAgICAgIGVxdWFscyB0byB7QGNvZGUgb3RoZXJ9OyBhIHBvc2l0aXZlIHZhbHVlIGlmIHRoaXMgaXMgZ3JlYXRlcgorICAgICAqICAgICAgICAgdGhhbiB7QGNvZGUgb3RoZXJ9LgorICAgICAqIEBleGNlcHRpb24gQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIG90aGVyfSBpcyBub3QgYSBieXRlIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhCeXRlQnVmZmVyIG90aGVyQnVmZmVyKSB7CisgICAgICAgIGludCBjb21wYXJlUmVtYWluaW5nID0gKHJlbWFpbmluZygpIDwgb3RoZXJCdWZmZXIucmVtYWluaW5nKCkpID8gcmVtYWluaW5nKCkKKyAgICAgICAgICAgICAgICA6IG90aGVyQnVmZmVyLnJlbWFpbmluZygpOworICAgICAgICBpbnQgdGhpc1BvcyA9IHBvc2l0aW9uOworICAgICAgICBpbnQgb3RoZXJQb3MgPSBvdGhlckJ1ZmZlci5wb3NpdGlvbjsKKyAgICAgICAgYnl0ZSB0aGlzQnl0ZSwgb3RoZXJCeXRlOworICAgICAgICB3aGlsZSAoY29tcGFyZVJlbWFpbmluZyA+IDApIHsKKyAgICAgICAgICAgIHRoaXNCeXRlID0gZ2V0KHRoaXNQb3MpOworICAgICAgICAgICAgb3RoZXJCeXRlID0gb3RoZXJCdWZmZXIuZ2V0KG90aGVyUG9zKTsKKyAgICAgICAgICAgIGlmICh0aGlzQnl0ZSAhPSBvdGhlckJ5dGUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdGhpc0J5dGUgPCBvdGhlckJ5dGUgPyAtMSA6IDE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aGlzUG9zKys7CisgICAgICAgICAgICBvdGhlclBvcysrOworICAgICAgICAgICAgY29tcGFyZVJlbWFpbmluZy0tOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZW1haW5pbmcoKSAtIG90aGVyQnVmZmVyLnJlbWFpbmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBkdXBsaWNhdGVkIGJ1ZmZlciB0aGF0IHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBkdXBsaWNhdGVkIGJ1ZmZlcidzIHBvc2l0aW9uLCBsaW1pdCwgY2FwYWNpdHkgYW5kIG1hcmsgYXJlIHRoZSBzYW1lCisgICAgICogYXMgdGhpcyBidWZmZXIncy4gVGhlIGR1cGxpY2F0ZWQgYnVmZmVyJ3MgcmVhZC1vbmx5IHByb3BlcnR5IGFuZCBieXRlCisgICAgICogb3JkZXIgYXJlIHRoZSBzYW1lIGFzIHRoaXMgYnVmZmVyJ3MgdG9vLgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyIHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLCB3aGljaCBtZWFucyBlaXRoZXIKKyAgICAgKiBidWZmZXIncyBjaGFuZ2Ugb2YgY29udGVudCB3aWxsIGJlIHZpc2libGUgdG8gdGhlIG90aGVyLiBUaGUgdHdvIGJ1ZmZlcidzCisgICAgICogcG9zaXRpb24sIGxpbWl0IGFuZCBtYXJrIGFyZSBpbmRlcGVuZGVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBkdXBsaWNhdGVkIGJ1ZmZlciB0aGF0IHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCeXRlQnVmZmVyIGR1cGxpY2F0ZSgpOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhpcyBieXRlIGJ1ZmZlciBpcyBlcXVhbCB0byBhbm90aGVyIG9iamVjdC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB7QGNvZGUgb3RoZXJ9IGlzIG5vdCBhIGJ5dGUgYnVmZmVyIHRoZW4ge0Bjb2RlIGZhbHNlfSBpcyByZXR1cm5lZC4gVHdvCisgICAgICogYnl0ZSBidWZmZXJzIGFyZSBlcXVhbCBpZiBhbmQgb25seSBpZiB0aGVpciByZW1haW5pbmcgYnl0ZXMgYXJlIGV4YWN0bHkKKyAgICAgKiB0aGUgc2FtZS4gUG9zaXRpb24sIGxpbWl0LCBjYXBhY2l0eSBhbmQgbWFyayBhcmUgbm90IGNvbnNpZGVyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3RoZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB3aXRoIHRoaXMgYnl0ZSBidWZmZXIuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBieXRlIGJ1ZmZlciBpcyBlcXVhbCB0byB7QGNvZGUgb3RoZXJ9LAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgeworICAgICAgICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIEJ5dGVCdWZmZXIpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgQnl0ZUJ1ZmZlciBvdGhlckJ1ZmZlciA9IChCeXRlQnVmZmVyKSBvdGhlcjsKKworICAgICAgICBpZiAocmVtYWluaW5nKCkgIT0gb3RoZXJCdWZmZXIucmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBteVBvc2l0aW9uID0gcG9zaXRpb247CisgICAgICAgIGludCBvdGhlclBvc2l0aW9uID0gb3RoZXJCdWZmZXIucG9zaXRpb247CisgICAgICAgIGJvb2xlYW4gZXF1YWxTb0ZhciA9IHRydWU7CisgICAgICAgIHdoaWxlIChlcXVhbFNvRmFyICYmIChteVBvc2l0aW9uIDwgbGltaXQpKSB7CisgICAgICAgICAgICBlcXVhbFNvRmFyID0gZ2V0KG15UG9zaXRpb24rKykgPT0gb3RoZXJCdWZmZXIuZ2V0KG90aGVyUG9zaXRpb24rKyk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZXF1YWxTb0ZhcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBieXRlIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IDEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBieXRlIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHBvc2l0aW9uIGlzIGVxdWFsIG9yIGdyZWF0ZXIgdGhhbiBsaW1pdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYnl0ZSBnZXQoKTsKKworICAgIC8qKgorICAgICAqIFJlYWRzIGJ5dGVzIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24gaW50byB0aGUgc3BlY2lmaWVkIGJ5dGUgYXJyYXkgYW5kCisgICAgICogaW5jcmVhc2VzIHRoZSBwb3NpdGlvbiBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuCisgICAgICogPHA+CisgICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzCisgICAgICoge0Bjb2RlIGdldChkc3QsIDAsIGRzdC5sZW5ndGgpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXN0aW5hdGlvbiBieXRlIGFycmF5LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXN9CisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgZHN0Lmxlbmd0aH0gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSByZW1haW5pbmcoKX0uCisgICAgICovCisgICAgcHVibGljIEJ5dGVCdWZmZXIgZ2V0KGJ5dGVbXSBkc3QpIHsKKyAgICAgICAgcmV0dXJuIGdldChkc3QsIDAsIGRzdC5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGJ5dGVzIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24gaW50byB0aGUgc3BlY2lmaWVkIGJ5dGUgYXJyYXksCisgICAgICogc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCBvZmZzZXQsIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IHRoZQorICAgICAqIG51bWJlciBvZiBieXRlcyByZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBieXRlIGFycmF5LgorICAgICAqIEBwYXJhbSBkc3RPZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgb2YgdGhlIGJ5dGUgYXJyYXksIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZAorICAgICAqICAgICAgICAgICAgbm90IGdyZWF0ZXIgdGhhbiB7QGNvZGUgZHN0Lmxlbmd0aH0uCisgICAgICogQHBhcmFtIGJ5dGVDb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyB0byByZWFkLCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBhbmQgbm90CisgICAgICogICAgICAgICAgICBncmVhdGVyIHRoYW4ge0Bjb2RlIGRzdC5sZW5ndGggLSBkc3RPZmZzZXR9CisgICAgICogQHJldHVybiB7QGNvZGUgdGhpc30KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYge0Bjb2RlIGRzdE9mZnNldCA8IDAgfHwgIGJ5dGVDb3VudCA8IDB9CisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24gaWYge0Bjb2RlIGJ5dGVDb3VudCA+IHJlbWFpbmluZygpfQorICAgICAqLworICAgIHB1YmxpYyBCeXRlQnVmZmVyIGdldChieXRlW10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGRzdC5sZW5ndGgsIGRzdE9mZnNldCwgYnl0ZUNvdW50KTsKKyAgICAgICAgaWYgKGJ5dGVDb3VudCA+IHJlbWFpbmluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IGRzdE9mZnNldDsgaSA8IGRzdE9mZnNldCArIGJ5dGVDb3VudDsgKytpKSB7CisgICAgICAgICAgICBkc3RbaV0gPSBnZXQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBieXRlIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggYW5kIGRvZXMgbm90IGNoYW5nZSB0aGUgcG9zaXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIGxlc3MgdGhhbiBsaW1pdC4KKyAgICAgKiBAcmV0dXJuIHRoZSBieXRlIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgaW5kZXggaXMgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYnl0ZSBnZXQoaW50IGluZGV4KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNoYXIgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24gYW5kIGluY3JlYXNlcyB0aGUgcG9zaXRpb24gYnkgMi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgMiBieXRlcyBzdGFydGluZyBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiBhcmUgY29tcG9zZWQgaW50byBhIGNoYXIKKyAgICAgKiBhY2NvcmRpbmcgdG8gdGhlIGN1cnJlbnQgYnl0ZSBvcmRlciBhbmQgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFyIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHBvc2l0aW9uIGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgbGltaXQgLSAyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgY2hhciBnZXRDaGFyKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjaGFyIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogPHA+CisgICAgICogVGhlIDIgYnl0ZXMgc3RhcnRpbmcgZnJvbSB0aGUgc3BlY2lmaWVkIGluZGV4IGFyZSBjb21wb3NlZCBpbnRvIGEgY2hhcgorICAgICAqIGFjY29yZGluZyB0byB0aGUgY3VycmVudCBieXRlIG9yZGVyIGFuZCByZXR1cm5lZC4gVGhlIHBvc2l0aW9uIGlzIG5vdAorICAgICAqIGNoYW5nZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIGVxdWFsIG9yIGxlc3MgdGhhbgorICAgICAqICAgICAgICAgICAge0Bjb2RlIGxpbWl0IC0gMn0uCisgICAgICogQHJldHVybiB0aGUgY2hhciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgorICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBpbmRleH0gaXMgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgY2hhciBnZXRDaGFyKGludCBpbmRleCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkb3VibGUgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24gYW5kIGluY3JlYXNlcyB0aGUgcG9zaXRpb24gYnkKKyAgICAgKiA4LgorICAgICAqIDxwPgorICAgICAqIFRoZSA4IGJ5dGVzIHN0YXJ0aW5nIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24gYXJlIGNvbXBvc2VkIGludG8gYSBkb3VibGUKKyAgICAgKiBhY2NvcmRpbmcgdG8gdGhlIGN1cnJlbnQgYnl0ZSBvcmRlciBhbmQgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkb3VibGUgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgcG9zaXRpb24gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSBsaW1pdCAtIDh9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBkb3VibGUgZ2V0RG91YmxlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkb3VibGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgOCBieXRlcyBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IGFyZSBjb21wb3NlZCBpbnRvIGEgZG91YmxlCisgICAgICogYWNjb3JkaW5nIHRvIHRoZSBjdXJyZW50IGJ5dGUgb3JkZXIgYW5kIHJldHVybmVkLiBUaGUgcG9zaXRpb24gaXMgbm90CisgICAgICogY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBhbmQgZXF1YWwgb3IgbGVzcyB0aGFuCisgICAgICogICAgICAgICAgICB7QGNvZGUgbGltaXQgLSA4fS4KKyAgICAgKiBAcmV0dXJuIHRoZSBkb3VibGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgaW5kZXh9IGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGRvdWJsZSBnZXREb3VibGUoaW50IGluZGV4KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZsb2F0IGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5CisgICAgICogNC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgNCBieXRlcyBzdGFydGluZyBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiBhcmUgY29tcG9zZWQgaW50byBhIGZsb2F0CisgICAgICogYWNjb3JkaW5nIHRvIHRoZSBjdXJyZW50IGJ5dGUgb3JkZXIgYW5kIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZmxvYXQgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgcG9zaXRpb24gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSBsaW1pdCAtIDR9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBmbG9hdCBnZXRGbG9hdCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZmxvYXQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgNCBieXRlcyBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IGFyZSBjb21wb3NlZCBpbnRvIGEgZmxvYXQKKyAgICAgKiBhY2NvcmRpbmcgdG8gdGhlIGN1cnJlbnQgYnl0ZSBvcmRlciBhbmQgcmV0dXJuZWQuIFRoZSBwb3NpdGlvbiBpcyBub3QKKyAgICAgKiBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBlcXVhbCBvciBsZXNzIHRoYW4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBsaW1pdCAtIDR9LgorICAgICAqIEByZXR1cm4gdGhlIGZsb2F0IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4fSBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBmbG9hdCBnZXRGbG9hdChpbnQgaW5kZXgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW50IGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IDQuCisgICAgICogPHA+CisgICAgICogVGhlIDQgYnl0ZXMgc3RhcnRpbmcgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24gYXJlIGNvbXBvc2VkIGludG8gYSBpbnQKKyAgICAgKiBhY2NvcmRpbmcgdG8gdGhlIGN1cnJlbnQgYnl0ZSBvcmRlciBhbmQgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbnQgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgcG9zaXRpb24gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSBsaW1pdCAtIDR9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0SW50KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgNCBieXRlcyBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IGFyZSBjb21wb3NlZCBpbnRvIGEgaW50CisgICAgICogYWNjb3JkaW5nIHRvIHRoZSBjdXJyZW50IGJ5dGUgb3JkZXIgYW5kIHJldHVybmVkLiBUaGUgcG9zaXRpb24gaXMgbm90CisgICAgICogY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBhbmQgZXF1YWwgb3IgbGVzcyB0aGFuCisgICAgICogICAgICAgICAgICB7QGNvZGUgbGltaXQgLSA0fS4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgaW5kZXh9IGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRJbnQoaW50IGluZGV4KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxvbmcgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24gYW5kIGluY3JlYXNlcyB0aGUgcG9zaXRpb24gYnkgOC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgOCBieXRlcyBzdGFydGluZyBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiBhcmUgY29tcG9zZWQgaW50byBhIGxvbmcKKyAgICAgKiBhY2NvcmRpbmcgdG8gdGhlIGN1cnJlbnQgYnl0ZSBvcmRlciBhbmQgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsb25nIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHBvc2l0aW9uIGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgbGltaXQgLSA4fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgbG9uZyBnZXRMb25nKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb25nIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogPHA+CisgICAgICogVGhlIDggYnl0ZXMgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBhcmUgY29tcG9zZWQgaW50byBhIGxvbmcKKyAgICAgKiBhY2NvcmRpbmcgdG8gdGhlIGN1cnJlbnQgYnl0ZSBvcmRlciBhbmQgcmV0dXJuZWQuIFRoZSBwb3NpdGlvbiBpcyBub3QKKyAgICAgKiBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBlcXVhbCBvciBsZXNzIHRoYW4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBsaW1pdCAtIDh9LgorICAgICAqIEByZXR1cm4gdGhlIGxvbmcgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgaW5kZXh9IGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGxvbmcgZ2V0TG9uZyhpbnQgaW5kZXgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2hvcnQgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24gYW5kIGluY3JlYXNlcyB0aGUgcG9zaXRpb24gYnkgMi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgMiBieXRlcyBzdGFydGluZyBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiBhcmUgY29tcG9zZWQgaW50byBhIHNob3J0CisgICAgICogYWNjb3JkaW5nIHRvIHRoZSBjdXJyZW50IGJ5dGUgb3JkZXIgYW5kIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc2hvcnQgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgcG9zaXRpb24gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSBsaW1pdCAtIDJ9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBzaG9ydCBnZXRTaG9ydCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2hvcnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgMiBieXRlcyBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IGFyZSBjb21wb3NlZCBpbnRvIGEgc2hvcnQKKyAgICAgKiBhY2NvcmRpbmcgdG8gdGhlIGN1cnJlbnQgYnl0ZSBvcmRlciBhbmQgcmV0dXJuZWQuIFRoZSBwb3NpdGlvbiBpcyBub3QKKyAgICAgKiBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBlcXVhbCBvciBsZXNzIHRoYW4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBsaW1pdCAtIDJ9LgorICAgICAqIEByZXR1cm4gdGhlIHNob3J0IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4fSBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBzaG9ydCBnZXRTaG9ydChpbnQgaW5kZXgpOworCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaGFzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBwcm90ZWN0ZWRIYXNBcnJheSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGN1bGF0ZXMgdGhpcyBidWZmZXIncyBoYXNoIGNvZGUgZnJvbSB0aGUgcmVtYWluaW5nIGNoYXJzLiBUaGUKKyAgICAgKiBwb3NpdGlvbiwgbGltaXQsIGNhcGFjaXR5IGFuZCBtYXJrIGRvbid0IGFmZmVjdCB0aGUgaGFzaCBjb2RlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIGNhbGN1bGF0ZWQgZnJvbSB0aGUgcmVtYWluaW5nIGJ5dGVzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGludCBteVBvc2l0aW9uID0gcG9zaXRpb247CisgICAgICAgIGludCBoYXNoID0gMDsKKyAgICAgICAgd2hpbGUgKG15UG9zaXRpb24gPCBsaW1pdCkgeworICAgICAgICAgICAgaGFzaCA9IGhhc2ggKyBnZXQobXlQb3NpdGlvbisrKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIGJ1ZmZlciBpcyBkaXJlY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGJ1ZmZlciBpcyBkaXJlY3QsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzRGlyZWN0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBieXRlIG9yZGVyIHVzZWQgYnkgdGhpcyBidWZmZXIgd2hlbiBjb252ZXJ0aW5nIGJ5dGVzIGZyb20vdG8KKyAgICAgKiBvdGhlciBwcmltaXRpdmUgdHlwZXMuCisgICAgICogPHA+CisgICAgICogVGhlIGRlZmF1bHQgYnl0ZSBvcmRlciBvZiBieXRlIGJ1ZmZlciBpcyBhbHdheXMKKyAgICAgKiB7QGxpbmsgQnl0ZU9yZGVyI0JJR19FTkRJQU4gQklHX0VORElBTn0KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgb3JkZXIgdXNlZCBieSB0aGlzIGJ1ZmZlciB3aGVuIGNvbnZlcnRpbmcgYnl0ZXMgZnJvbS90bworICAgICAqICAgICAgICAgb3RoZXIgcHJpbWl0aXZlIHR5cGVzLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBCeXRlT3JkZXIgb3JkZXIoKSB7CisgICAgICAgIHJldHVybiBvcmRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBieXRlIG9yZGVyIG9mIHRoaXMgYnVmZmVyLgorICAgICAqCisgICAgICogQHBhcmFtIGJ5dGVPcmRlcgorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgb3JkZXIgdG8gc2V0LiBJZiB7QGNvZGUgbnVsbH0gdGhlbiB0aGUgb3JkZXIKKyAgICAgKiAgICAgICAgICAgIHdpbGwgYmUge0BsaW5rIEJ5dGVPcmRlciNMSVRUTEVfRU5ESUFOIExJVFRMRV9FTkRJQU59LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXN9CisgICAgICogQHNlZSBCeXRlT3JkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQnl0ZUJ1ZmZlciBvcmRlcihCeXRlT3JkZXIgYnl0ZU9yZGVyKSB7CisgICAgICAgIG9yZGVySW1wbChieXRlT3JkZXIpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdWJ2ZXJ0cyB0aGUgZmFjdCB0aGF0IG9yZGVyKEJ5dGVPcmRlcikgaXMgZmluYWwsIGZvciB0aGUgYmVuZWZpdCBvZiBNYXBwZWRCeXRlQnVmZmVyQWRhcHRlci4KKyAgICAgKi8KKyAgICB2b2lkIG9yZGVySW1wbChCeXRlT3JkZXIgYnl0ZU9yZGVyKSB7CisgICAgICAgIGlmIChieXRlT3JkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgYnl0ZU9yZGVyID0gQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU47CisgICAgICAgIH0KKyAgICAgICAgb3JkZXIgPSBieXRlT3JkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hpbGQgY2xhc3MgaW1wbGVtZW50cyB0aGlzIG1ldGhvZCB0byByZWFsaXplIHtAY29kZSBhcnJheSgpfS4KKyAgICAgKgorICAgICAqIEBzZWUgI2FycmF5KCkKKyAgICAgKi8KKyAgICBhYnN0cmFjdCBieXRlW10gcHJvdGVjdGVkQXJyYXkoKTsKKworICAgIC8qKgorICAgICAqIENoaWxkIGNsYXNzIGltcGxlbWVudHMgdGhpcyBtZXRob2QgdG8gcmVhbGl6ZSB7QGNvZGUgYXJyYXlPZmZzZXQoKX0uCisgICAgICoKKyAgICAgKiBAc2VlICNhcnJheU9mZnNldCgpCisgICAgICovCisgICAgYWJzdHJhY3QgaW50IHByb3RlY3RlZEFycmF5T2Zmc2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBDaGlsZCBjbGFzcyBpbXBsZW1lbnRzIHRoaXMgbWV0aG9kIHRvIHJlYWxpemUge0Bjb2RlIGhhc0FycmF5KCl9LgorICAgICAqCisgICAgICogQHNlZSAjaGFzQXJyYXkoKQorICAgICAqLworICAgIGFic3RyYWN0IGJvb2xlYW4gcHJvdGVjdGVkSGFzQXJyYXkoKTsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgZ2l2ZW4gYnl0ZSB0byB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQgaW5jcmVhc2VzIHRoZSBwb3NpdGlvbgorICAgICAqIGJ5IDEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpc30KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcG9zaXRpb24gaXMgZXF1YWwgb3IgZ3JlYXRlciB0aGFuIGxpbWl0LgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnl0ZUJ1ZmZlciBwdXQoYnl0ZSBiKTsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyBieXRlcyBpbiB0aGUgZ2l2ZW4gYnl0ZSBhcnJheSB0byB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQKKyAgICAgKiBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbi4KKyAgICAgKiA8cD4KKyAgICAgKiBDYWxsaW5nIHRoaXMgbWV0aG9kIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMKKyAgICAgKiB7QGNvZGUgcHV0KHNyYywgMCwgc3JjLmxlbmd0aCl9LgorICAgICAqCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBieXRlIGFycmF5LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXN9CisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSByZW1haW5pbmcoKX0gaXMgbGVzcyB0aGFuIHtAY29kZSBzcmMubGVuZ3RofS4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEJ5dGVCdWZmZXIgcHV0KGJ5dGVbXSBzcmMpIHsKKyAgICAgICAgcmV0dXJuIHB1dChzcmMsIDAsIHNyYy5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBieXRlcyBpbiB0aGUgZ2l2ZW4gYnl0ZSBhcnJheSwgc3RhcnRpbmcgZnJvbSB0aGUgc3BlY2lmaWVkIG9mZnNldCwKKyAgICAgKiB0byB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQgaW5jcmVhc2VzIHRoZSBwb3NpdGlvbiBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzCisgICAgICogd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgYnl0ZSBhcnJheS4KKyAgICAgKiBAcGFyYW0gc3JjT2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIGJ5dGUgYXJyYXksIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QgZ3JlYXRlcgorICAgICAqICAgICAgICAgICAgdGhhbiB7QGNvZGUgc3JjLmxlbmd0aH0uCisgICAgICogQHBhcmFtIGJ5dGVDb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyB0byB3cml0ZSwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIG5vdAorICAgICAqICAgICAgICAgICAgZ3JlYXRlciB0aGFuIHtAY29kZSBzcmMubGVuZ3RoIC0gc3JjT2Zmc2V0fS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0aGlzfQorICAgICAqIEBleGNlcHRpb24gQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgcmVtYWluaW5nKCl9IGlzIGxlc3MgdGhhbiB7QGNvZGUgYnl0ZUNvdW50fS4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBlaXRoZXIge0Bjb2RlIHNyY09mZnNldH0gb3Ige0Bjb2RlIGJ5dGVDb3VudH0gaXMgaW52YWxpZC4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0KGJ5dGVbXSBzcmMsIGludCBzcmNPZmZzZXQsIGludCBieXRlQ291bnQpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoc3JjLmxlbmd0aCwgc3JjT2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICBpZiAoYnl0ZUNvdW50ID4gcmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSBzcmNPZmZzZXQ7IGkgPCBzcmNPZmZzZXQgKyBieXRlQ291bnQ7ICsraSkgeworICAgICAgICAgICAgcHV0KHNyY1tpXSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGFsbCB0aGUgcmVtYWluaW5nIGJ5dGVzIG9mIHRoZSB7QGNvZGUgc3JjfSBieXRlIGJ1ZmZlciB0byB0aGlzCisgICAgICogYnVmZmVyJ3MgY3VycmVudCBwb3NpdGlvbiwgYW5kIGluY3JlYXNlcyBib3RoIGJ1ZmZlcnMnIHBvc2l0aW9uIGJ5IHRoZQorICAgICAqIG51bWJlciBvZiBieXRlcyBjb3BpZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGJ5dGUgYnVmZmVyLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXN9CisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzcmMucmVtYWluaW5nKCl9IGlzIGdyZWF0ZXIgdGhhbiB0aGlzIGJ1ZmZlcidzCisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIHJlbWFpbmluZygpfS4KKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzcmN9IGlzIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXQoQnl0ZUJ1ZmZlciBzcmMpIHsKKyAgICAgICAgaWYgKHNyYyA9PSB0aGlzKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzcmMgPT0gdGhpcyIpOworICAgICAgICB9CisgICAgICAgIGludCBzcmNCeXRlQ291bnQgPSBzcmMucmVtYWluaW5nKCk7CisgICAgICAgIGlmIChzcmNCeXRlQ291bnQgPiByZW1haW5pbmcoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBPYmplY3Qgc3JjT2JqZWN0ID0gc3JjLmlzRGlyZWN0KCkgPyBzcmMgOiBOaW9VdGlscy51bnNhZmVBcnJheShzcmMpOworICAgICAgICBpbnQgc3JjT2Zmc2V0ID0gc3JjLnBvc2l0aW9uKCk7CisgICAgICAgIGlmICghc3JjLmlzRGlyZWN0KCkpIHsKKyAgICAgICAgICAgIHNyY09mZnNldCArPSBOaW9VdGlscy51bnNhZmVBcnJheU9mZnNldChzcmMpOworICAgICAgICB9CisKKyAgICAgICAgQnl0ZUJ1ZmZlciBkc3QgPSB0aGlzOworICAgICAgICBPYmplY3QgZHN0T2JqZWN0ID0gZHN0LmlzRGlyZWN0KCkgPyBkc3QgOiBOaW9VdGlscy51bnNhZmVBcnJheShkc3QpOworICAgICAgICBpbnQgZHN0T2Zmc2V0ID0gZHN0LnBvc2l0aW9uKCk7CisgICAgICAgIGlmICghZHN0LmlzRGlyZWN0KCkpIHsKKyAgICAgICAgICAgIGRzdE9mZnNldCArPSBOaW9VdGlscy51bnNhZmVBcnJheU9mZnNldChkc3QpOworICAgICAgICB9CisKKyAgICAgICAgTWVtb3J5Lm1lbW1vdmUoZHN0T2JqZWN0LCBkc3RPZmZzZXQsIHNyY09iamVjdCwgc3JjT2Zmc2V0LCBzcmNCeXRlQ291bnQpOworICAgICAgICBzcmMucG9zaXRpb24oc3JjLmxpbWl0KCkpOworICAgICAgICBkc3QucG9zaXRpb24oZHN0LnBvc2l0aW9uKCkgKyBzcmNCeXRlQ291bnQpOworCisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIGEgYnl0ZSB0byB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgYnVmZmVyIHdpdGhvdXQgY2hhbmdpbmcgdGhlCisgICAgICogcG9zaXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIGxlc3MgdGhhbiB0aGUgbGltaXQuCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIHRvIHdyaXRlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXN9CisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4fSBpcyBpbnZhbGlkLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnl0ZUJ1ZmZlciBwdXQoaW50IGluZGV4LCBieXRlIGIpOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBnaXZlbiBjaGFyIHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uCisgICAgICogYnkgMi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgY2hhciBpcyBjb252ZXJ0ZWQgdG8gYnl0ZXMgdXNpbmcgdGhlIGN1cnJlbnQgYnl0ZSBvcmRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGNoYXIgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpc30KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcG9zaXRpb24gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSBsaW1pdCAtIDJ9LgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnl0ZUJ1ZmZlciBwdXRDaGFyKGNoYXIgdmFsdWUpOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBnaXZlbiBjaGFyIHRvIHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyBidWZmZXIuCisgICAgICogPHA+CisgICAgICogVGhlIGNoYXIgaXMgY29udmVydGVkIHRvIGJ5dGVzIHVzaW5nIHRoZSBjdXJyZW50IGJ5dGUgb3JkZXIuIFRoZSBwb3NpdGlvbgorICAgICAqIGlzIG5vdCBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBlcXVhbCBvciBsZXNzIHRoYW4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBsaW1pdCAtIDJ9LgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGNoYXIgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpc30KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgaW5kZXh9IGlzIGludmFsaWQuCisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCeXRlQnVmZmVyIHB1dENoYXIoaW50IGluZGV4LCBjaGFyIHZhbHVlKTsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgZ2l2ZW4gZG91YmxlIHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uCisgICAgICogYnkgOC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZG91YmxlIGlzIGNvbnZlcnRlZCB0byBieXRlcyB1c2luZyB0aGUgY3VycmVudCBieXRlIG9yZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgZG91YmxlIHRvIHdyaXRlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXN9CisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHBvc2l0aW9uIGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgbGltaXQgLSA4fS4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ5dGVCdWZmZXIgcHV0RG91YmxlKGRvdWJsZSB2YWx1ZSk7CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGdpdmVuIGRvdWJsZSB0byB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBkb3VibGUgaXMgY29udmVydGVkIHRvIGJ5dGVzIHVzaW5nIHRoZSBjdXJyZW50IGJ5dGUgb3JkZXIuIFRoZQorICAgICAqIHBvc2l0aW9uIGlzIG5vdCBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBlcXVhbCBvciBsZXNzIHRoYW4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBsaW1pdCAtIDh9LgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGRvdWJsZSB0byB3cml0ZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0aGlzfQorICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBpbmRleH0gaXMgaW52YWxpZC4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ5dGVCdWZmZXIgcHV0RG91YmxlKGludCBpbmRleCwgZG91YmxlIHZhbHVlKTsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgZ2l2ZW4gZmxvYXQgdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gYW5kIGluY3JlYXNlcyB0aGUgcG9zaXRpb24KKyAgICAgKiBieSA0LgorICAgICAqIDxwPgorICAgICAqIFRoZSBmbG9hdCBpcyBjb252ZXJ0ZWQgdG8gYnl0ZXMgdXNpbmcgdGhlIGN1cnJlbnQgYnl0ZSBvcmRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IHRvIHdyaXRlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXN9CisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHBvc2l0aW9uIGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgbGltaXQgLSA0fS4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ5dGVCdWZmZXIgcHV0RmxvYXQoZmxvYXQgdmFsdWUpOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBnaXZlbiBmbG9hdCB0byB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBmbG9hdCBpcyBjb252ZXJ0ZWQgdG8gYnl0ZXMgdXNpbmcgdGhlIGN1cnJlbnQgYnl0ZSBvcmRlci4gVGhlCisgICAgICogcG9zaXRpb24gaXMgbm90IGNoYW5nZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIGVxdWFsIG9yIGxlc3MgdGhhbgorICAgICAqICAgICAgICAgICAge0Bjb2RlIGxpbWl0IC0gNH0uCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgZmxvYXQgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpc30KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgaW5kZXh9IGlzIGludmFsaWQuCisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCeXRlQnVmZmVyIHB1dEZsb2F0KGludCBpbmRleCwgZmxvYXQgdmFsdWUpOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBnaXZlbiBpbnQgdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gYW5kIGluY3JlYXNlcyB0aGUgcG9zaXRpb24gYnkKKyAgICAgKiA0LgorICAgICAqIDxwPgorICAgICAqIFRoZSBpbnQgaXMgY29udmVydGVkIHRvIGJ5dGVzIHVzaW5nIHRoZSBjdXJyZW50IGJ5dGUgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnQgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpc30KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcG9zaXRpb24gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSBsaW1pdCAtIDR9LgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnl0ZUJ1ZmZlciBwdXRJbnQoaW50IHZhbHVlKTsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgZ2l2ZW4gaW50IHRvIHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyBidWZmZXIuCisgICAgICogPHA+CisgICAgICogVGhlIGludCBpcyBjb252ZXJ0ZWQgdG8gYnl0ZXMgdXNpbmcgdGhlIGN1cnJlbnQgYnl0ZSBvcmRlci4gVGhlIHBvc2l0aW9uCisgICAgICogaXMgbm90IGNoYW5nZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIGVxdWFsIG9yIGxlc3MgdGhhbgorICAgICAqICAgICAgICAgICAge0Bjb2RlIGxpbWl0IC0gNH0uCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgaW50IHRvIHdyaXRlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXN9CisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGluZGV4fSBpcyBpbnZhbGlkLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnl0ZUJ1ZmZlciBwdXRJbnQoaW50IGluZGV4LCBpbnQgdmFsdWUpOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBnaXZlbiBsb25nIHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uCisgICAgICogYnkgOC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbG9uZyBpcyBjb252ZXJ0ZWQgdG8gYnl0ZXMgdXNpbmcgdGhlIGN1cnJlbnQgYnl0ZSBvcmRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGxvbmcgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpc30KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcG9zaXRpb24gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSBsaW1pdCAtIDh9LgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnl0ZUJ1ZmZlciBwdXRMb25nKGxvbmcgdmFsdWUpOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBnaXZlbiBsb25nIHRvIHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyBidWZmZXIuCisgICAgICogPHA+CisgICAgICogVGhlIGxvbmcgaXMgY29udmVydGVkIHRvIGJ5dGVzIHVzaW5nIHRoZSBjdXJyZW50IGJ5dGUgb3JkZXIuIFRoZSBwb3NpdGlvbgorICAgICAqIGlzIG5vdCBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBlcXVhbCBvciBsZXNzIHRoYW4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBsaW1pdCAtIDh9LgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGxvbmcgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpc30KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgaW5kZXh9IGlzIGludmFsaWQuCisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCeXRlQnVmZmVyIHB1dExvbmcoaW50IGluZGV4LCBsb25nIHZhbHVlKTsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgZ2l2ZW4gc2hvcnQgdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gYW5kIGluY3JlYXNlcyB0aGUgcG9zaXRpb24KKyAgICAgKiBieSAyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBzaG9ydCBpcyBjb252ZXJ0ZWQgdG8gYnl0ZXMgdXNpbmcgdGhlIGN1cnJlbnQgYnl0ZSBvcmRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHNob3J0IHRvIHdyaXRlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRoaXN9CisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHBvc2l0aW9uIGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgbGltaXQgLSAyfS4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ5dGVCdWZmZXIgcHV0U2hvcnQoc2hvcnQgdmFsdWUpOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBnaXZlbiBzaG9ydCB0byB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBzaG9ydCBpcyBjb252ZXJ0ZWQgdG8gYnl0ZXMgdXNpbmcgdGhlIGN1cnJlbnQgYnl0ZSBvcmRlci4gVGhlCisgICAgICogcG9zaXRpb24gaXMgbm90IGNoYW5nZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIGVxdWFsIG9yIGxlc3MgdGhhbgorICAgICAqICAgICAgICAgICAge0Bjb2RlIGxpbWl0IC0gMn0uCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgc2hvcnQgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB7QGNvZGUgdGhpc30KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgaW5kZXh9IGlzIGludmFsaWQuCisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCeXRlQnVmZmVyIHB1dFNob3J0KGludCBpbmRleCwgc2hvcnQgdmFsdWUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNsaWNlZCBidWZmZXIgdGhhdCBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgc2xpY2VkIGJ1ZmZlcidzIGNhcGFjaXR5IHdpbGwgYmUgdGhpcyBidWZmZXIncworICAgICAqIHtAY29kZSByZW1haW5pbmcoKX0sIGFuZCBpdCdzIHplcm8gcG9zaXRpb24gd2lsbCBjb3JyZXNwb25kIHRvCisgICAgICogdGhpcyBidWZmZXIncyBjdXJyZW50IHBvc2l0aW9uLiBUaGUgbmV3IGJ1ZmZlcidzIHBvc2l0aW9uIHdpbGwgYmUgMCwKKyAgICAgKiBsaW1pdCB3aWxsIGJlIGl0cyBjYXBhY2l0eSwgYW5kIGl0cyBtYXJrIGlzIGNsZWFyZWQuIFRoZSBuZXcgYnVmZmVyJ3MKKyAgICAgKiByZWFkLW9ubHkgcHJvcGVydHkgYW5kIGJ5dGUgb3JkZXIgYXJlIHRoZSBzYW1lIGFzIHRoaXMgYnVmZmVyJ3MuCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIsIHdoaWNoIG1lYW5zIGVpdGhlcgorICAgICAqIGJ1ZmZlcidzIGNoYW5nZSBvZiBjb250ZW50IHdpbGwgYmUgdmlzaWJsZSB0byB0aGUgb3RoZXIuIFRoZSB0d28gYnVmZmVyJ3MKKyAgICAgKiBwb3NpdGlvbiwgbGltaXQgYW5kIG1hcmsgYXJlIGluZGVwZW5kZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIHNsaWNlZCBidWZmZXIgdGhhdCBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnl0ZUJ1ZmZlciBzbGljZSgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0J5dGVPcmRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0J5dGVPcmRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI4NmM5NzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vQnl0ZU9yZGVyLmphdmEKQEAgLTAsMCArMSw4MCBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworLyoqCisgKiBEZWZpbmVzIGJ5dGUgb3JkZXIgY29uc3RhbnRzLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQnl0ZU9yZGVyIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBCeXRlT3JkZXIgTkFUSVZFX09SREVSOworCisgICAgLyoqCisgICAgICogVGhpcyBjb25zdGFudCByZXByZXNlbnRzIGJpZyBlbmRpYW4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBCeXRlT3JkZXIgQklHX0VORElBTjsKKworICAgIC8qKgorICAgICAqIFRoaXMgY29uc3RhbnQgcmVwcmVzZW50cyBsaXR0bGUgZW5kaWFuLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQnl0ZU9yZGVyIExJVFRMRV9FTkRJQU47CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBpc0xpdHRsZUVuZGlhbigpOworCisgICAgc3RhdGljIHsKKyAgICAgICAgYm9vbGVhbiBpc0xpdHRsZUVuZGlhbiA9IGlzTGl0dGxlRW5kaWFuKCk7CisgICAgICAgIEJJR19FTkRJQU4gPSBuZXcgQnl0ZU9yZGVyKCJCSUdfRU5ESUFOIiwgaXNMaXR0bGVFbmRpYW4pOworICAgICAgICBMSVRUTEVfRU5ESUFOID0gbmV3IEJ5dGVPcmRlcigiTElUVExFX0VORElBTiIsICFpc0xpdHRsZUVuZGlhbik7CisgICAgICAgIE5BVElWRV9PUkRFUiA9IGlzTGl0dGxlRW5kaWFuID8gTElUVExFX0VORElBTiA6IEJJR19FTkRJQU47CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbmFtZTsKKworICAgIC8qKgorICAgICAqIFRoaXMgaXMgdGhlIG9ubHkgdGhpbmcgdGhhdCBCeXRlT3JkZXIgaXMgcmVhbGx5IHVzZWQgZm9yOiB0byBrbm93IHdoZXRoZXIgd2UgbmVlZCB0byBzd2FwCisgICAgICogYnl0ZXMgdG8gZ2V0IHRoaXMgb3JkZXIsIGdpdmVuIGJ5dGVzIGluIG5hdGl2ZSBvcmRlci4gKFRoYXQgaXMsIHRoaXMgaXMgdGhlIG9wcG9zaXRlIG9mCisgICAgICogdGhlIGh5cG90aGV0aWNhbCAiaXNOYXRpdmVPcmRlciIuKQorICAgICAqIEBoaWRlIC0gbmVlZGVkIGluIGxpYmNvcmUuaW8gdG9vLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIG5lZWRzU3dhcDsKKworICAgIHByaXZhdGUgQnl0ZU9yZGVyKFN0cmluZyBuYW1lLCBib29sZWFuIG5lZWRzU3dhcCkgeworICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgICAgICB0aGlzLm5lZWRzU3dhcCA9IG5lZWRzU3dhcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHBsYXRmb3JtIGJ5dGUgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBieXRlIG9yZGVyIG9iamVjdCwgd2hpY2ggaXMgZWl0aGVyIExJVFRMRV9FTkRJQU4gb3IKKyAgICAgKiAgICAgICAgIEJJR19FTkRJQU4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCeXRlT3JkZXIgbmF0aXZlT3JkZXIoKSB7CisgICAgICAgIHJldHVybiBOQVRJVkVfT1JERVI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyB0aGF0IGRlc2NyaWJlcyB0aGlzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gIkJJR19FTkRJQU4iIGZvciB7QGxpbmsgI0JJR19FTkRJQU4gQnl0ZU9yZGVyLkJJR19FTkRJQU59CisgICAgICogICAgICAgICBvYmplY3RzLCAiTElUVExFX0VORElBTiIgZm9yCisgICAgICogICAgICAgICB7QGxpbmsgI0xJVFRMRV9FTkRJQU4gQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU59IG9iamVjdHMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0NoYXJBcnJheUJ1ZmZlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0NoYXJBcnJheUJ1ZmZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUzZDdmYjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vQ2hhckFycmF5QnVmZmVyLmphdmEKQEAgLTAsMCArMSw5OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworLyoqCisgKiBDaGFyQXJyYXlCdWZmZXIsIFJlYWRXcml0ZUNoYXJBcnJheUJ1ZmZlciBhbmQgUmVhZE9ubHlDaGFyQXJyYXlCdWZmZXIgY29tcG9zZQorICogdGhlIGltcGxlbWVudGF0aW9uIG9mIGFycmF5IGJhc2VkIGNoYXIgYnVmZmVycy4KKyAqIDxwPgorICogQ2hhckFycmF5QnVmZmVyIGltcGxlbWVudHMgYWxsIHRoZSBzaGFyZWQgcmVhZG9ubHkgbWV0aG9kcyBhbmQgaXMgZXh0ZW5kZWQgYnkKKyAqIHRoZSBvdGhlciB0d28gY2xhc3Nlcy4KKyAqIDwvcD4KKyAqIDxwPgorICogQWxsIG1ldGhvZHMgYXJlIG1hcmtlZCBmaW5hbCBmb3IgcnVudGltZSBwZXJmb3JtYW5jZS4KKyAqIDwvcD4KKyAqCisgKi8KK2Fic3RyYWN0IGNsYXNzIENoYXJBcnJheUJ1ZmZlciBleHRlbmRzIENoYXJCdWZmZXIgeworCisgICAgcHJvdGVjdGVkIGZpbmFsIGNoYXJbXSBiYWNraW5nQXJyYXk7CisKKyAgICBwcm90ZWN0ZWQgZmluYWwgaW50IG9mZnNldDsKKworICAgIENoYXJBcnJheUJ1ZmZlcihjaGFyW10gYXJyYXkpIHsKKyAgICAgICAgdGhpcyhhcnJheS5sZW5ndGgsIGFycmF5LCAwKTsKKyAgICB9CisKKyAgICBDaGFyQXJyYXlCdWZmZXIoaW50IGNhcGFjaXR5KSB7CisgICAgICAgIHRoaXMoY2FwYWNpdHksIG5ldyBjaGFyW2NhcGFjaXR5XSwgMCk7CisgICAgfQorCisgICAgQ2hhckFycmF5QnVmZmVyKGludCBjYXBhY2l0eSwgY2hhcltdIGJhY2tpbmdBcnJheSwgaW50IG9mZnNldCkgeworICAgICAgICBzdXBlcihjYXBhY2l0eSk7CisgICAgICAgIHRoaXMuYmFja2luZ0FycmF5ID0gYmFja2luZ0FycmF5OworICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgY2hhciBnZXQoKSB7CisgICAgICAgIGlmIChwb3NpdGlvbiA9PSBsaW1pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBiYWNraW5nQXJyYXlbb2Zmc2V0ICsgcG9zaXRpb24rK107CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGNoYXIgZ2V0KGludCBpbmRleCkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4KTsKKyAgICAgICAgcmV0dXJuIGJhY2tpbmdBcnJheVtvZmZzZXQgKyBpbmRleF07CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIENoYXJCdWZmZXIgZ2V0KGNoYXJbXSBkc3QsIGludCBzcmNPZmZzZXQsIGludCBjaGFyQ291bnQpIHsKKyAgICAgICAgaWYgKGNoYXJDb3VudCA+IHJlbWFpbmluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uLCBkc3QsIHNyY09mZnNldCwgY2hhckNvdW50KTsKKyAgICAgICAgcG9zaXRpb24gKz0gY2hhckNvdW50OworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0RpcmVjdCgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBCeXRlT3JkZXIgb3JkZXIoKSB7CisgICAgICAgIHJldHVybiBCeXRlT3JkZXIubmF0aXZlT3JkZXIoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgQ2hhclNlcXVlbmNlIHN1YlNlcXVlbmNlKGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBjaGVja1N0YXJ0RW5kUmVtYWluaW5nKHN0YXJ0LCBlbmQpOworICAgICAgICBDaGFyQnVmZmVyIHJlc3VsdCA9IGR1cGxpY2F0ZSgpOworICAgICAgICByZXN1bHQubGltaXQocG9zaXRpb24gKyBlbmQpOworICAgICAgICByZXN1bHQucG9zaXRpb24ocG9zaXRpb24gKyBzdGFydCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIFN0cmluZy5jb3B5VmFsdWVPZihiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uLCByZW1haW5pbmcoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0NoYXJCdWZmZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9DaGFyQnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDNiYWMwNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9DaGFyQnVmZmVyLmphdmEKQEAgLTAsMCArMSw3NTAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogQSBidWZmZXIgb2YgY2hhcnMuCisgKiA8cD4KKyAqIEEgY2hhciBidWZmZXIgY2FuIGJlIGNyZWF0ZWQgaW4gZWl0aGVyIG9uZSBvZiB0aGUgZm9sbG93aW5nIHdheXM6CisgKiA8dWw+CisgKiA8bGk+e0BsaW5rICNhbGxvY2F0ZShpbnQpIEFsbG9jYXRlfSBhIG5ldyBjaGFyIGFycmF5IGFuZCBjcmVhdGUgYSBidWZmZXIKKyAqIGJhc2VkIG9uIGl0OzwvbGk+CisgKiA8bGk+e0BsaW5rICN3cmFwKGNoYXJbXSkgV3JhcH0gYW4gZXhpc3RpbmcgY2hhciBhcnJheSB0byBjcmVhdGUgYSBuZXcKKyAqIGJ1ZmZlcjs8L2xpPgorICogPGxpPntAbGluayAjd3JhcChDaGFyU2VxdWVuY2UpIFdyYXB9IGFuIGV4aXN0aW5nIGNoYXIgc2VxdWVuY2UgdG8gY3JlYXRlIGEKKyAqIG5ldyBidWZmZXI7PC9saT4KKyAqIDxsaT5Vc2Uge0BsaW5rIGphdmEubmlvLkJ5dGVCdWZmZXIjYXNDaGFyQnVmZmVyKCkgQnl0ZUJ1ZmZlci5hc0NoYXJCdWZmZXJ9CisgKiB0byBjcmVhdGUgYSBjaGFyIGJ1ZmZlciBiYXNlZCBvbiBhIGJ5dGUgYnVmZmVyLjwvbGk+CisgKiA8L3VsPgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ2hhckJ1ZmZlciBleHRlbmRzIEJ1ZmZlciBpbXBsZW1lbnRzCisgICAgICAgIENvbXBhcmFibGU8Q2hhckJ1ZmZlcj4sIENoYXJTZXF1ZW5jZSwgQXBwZW5kYWJsZSwgUmVhZGFibGUgeworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGNoYXIgYnVmZmVyIGJhc2VkIG9uIGEgbmV3bHkgYWxsb2NhdGVkIGNoYXIgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2FwYWNpdHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYXBhY2l0eSBvZiB0aGUgbmV3IGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBjcmVhdGVkIGNoYXIgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGNhcGFjaXR5fSBpcyBsZXNzIHRoYW4gemVyby4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIENoYXJCdWZmZXIgYWxsb2NhdGUoaW50IGNhcGFjaXR5KSB7CisgICAgICAgIGlmIChjYXBhY2l0eSA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFJlYWRXcml0ZUNoYXJBcnJheUJ1ZmZlcihjYXBhY2l0eSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBjaGFyIGJ1ZmZlciBieSB3cmFwcGluZyB0aGUgZ2l2ZW4gY2hhciBhcnJheS4KKyAgICAgKiA8cD4KKyAgICAgKiBDYWxsaW5nIHRoaXMgbWV0aG9kIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMKKyAgICAgKiB7QGNvZGUgd3JhcChhcnJheSwgMCwgYXJyYXkubGVuZ3RoKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyIGFycmF5IHdoaWNoIHRoZSBuZXcgYnVmZmVyIHdpbGwgYmUgYmFzZWQgb24uCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCBjaGFyIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIENoYXJCdWZmZXIgd3JhcChjaGFyW10gYXJyYXkpIHsKKyAgICAgICAgcmV0dXJuIHdyYXAoYXJyYXksIDAsIGFycmF5Lmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBjaGFyIGJ1ZmZlciBieSB3cmFwcGluZyB0aGUgZ2l2ZW4gY2hhciBhcnJheS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbmV3IGJ1ZmZlcidzIHBvc2l0aW9uIHdpbGwgYmUge0Bjb2RlIHN0YXJ0fSwgbGltaXQgd2lsbCBiZQorICAgICAqIHtAY29kZSBzdGFydCArIGNoYXJDb3VudH0sIGNhcGFjaXR5IHdpbGwgYmUgdGhlIGxlbmd0aCBvZiB0aGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyIGFycmF5IHdoaWNoIHRoZSBuZXcgYnVmZmVyIHdpbGwgYmUgYmFzZWQgb24uCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgaW5kZXgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgICAgICB7QGNvZGUgYXJyYXkubGVuZ3RofS4KKyAgICAgKiBAcGFyYW0gY2hhckNvdW50CisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoLCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBhbmQgbm90IGdyZWF0ZXIgdGhhbgorICAgICAqICAgICAgICAgICAge0Bjb2RlIGFycmF5Lmxlbmd0aCAtIHN0YXJ0fS4KKyAgICAgKiBAcmV0dXJuIHRoZSBjcmVhdGVkIGNoYXIgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGVpdGhlciB7QGNvZGUgc3RhcnR9IG9yIHtAY29kZSBjaGFyQ291bnR9IGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDaGFyQnVmZmVyIHdyYXAoY2hhcltdIGFycmF5LCBpbnQgc3RhcnQsIGludCBjaGFyQ291bnQpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYXJyYXkubGVuZ3RoLCBzdGFydCwgY2hhckNvdW50KTsKKyAgICAgICAgQ2hhckJ1ZmZlciBidWYgPSBuZXcgUmVhZFdyaXRlQ2hhckFycmF5QnVmZmVyKGFycmF5KTsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gc3RhcnQ7CisgICAgICAgIGJ1Zi5saW1pdCA9IHN0YXJ0ICsgY2hhckNvdW50OworICAgICAgICByZXR1cm4gYnVmOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgY2hhciBidWZmZXIgYnkgd3JhcHBpbmcgdGhlIGdpdmVuIGNoYXIgc2VxdWVuY2UuCisgICAgICogPHA+CisgICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzCisgICAgICoge0Bjb2RlIHdyYXAoY2hzZXEsIDAsIGNoc2VxLmxlbmd0aCgpKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hzZXEKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyIHNlcXVlbmNlIHdoaWNoIHRoZSBuZXcgYnVmZmVyIHdpbGwgYmUgYmFzZWQgb24uCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCBjaGFyIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIENoYXJCdWZmZXIgd3JhcChDaGFyU2VxdWVuY2UgY2hzZXEpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBDaGFyU2VxdWVuY2VBZGFwdGVyKGNoc2VxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGNoYXIgYnVmZmVyIGJ5IHdyYXBwaW5nIHRoZSBnaXZlbiBjaGFyIHNlcXVlbmNlLgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyJ3MgcG9zaXRpb24gd2lsbCBiZSB7QGNvZGUgc3RhcnR9LCBsaW1pdCB3aWxsIGJlCisgICAgICoge0Bjb2RlIGVuZH0sIGNhcGFjaXR5IHdpbGwgYmUgdGhlIGxlbmd0aCBvZiB0aGUgY2hhciBzZXF1ZW5jZS4gVGhlIG5ldworICAgICAqIGJ1ZmZlciBpcyByZWFkLW9ubHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyIHNlcXVlbmNlIHdoaWNoIHRoZSBuZXcgYnVmZmVyIHdpbGwgYmUgYmFzZWQgb24uCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgaW5kZXgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgICAgICB7QGNvZGUgY3MubGVuZ3RoKCl9LgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmQgaW5kZXgsIG11c3QgYmUgbm8gbGVzcyB0aGFuIHtAY29kZSBzdGFydH0gYW5kIG5vCisgICAgICogICAgICAgICAgICBncmVhdGVyIHRoYW4ge0Bjb2RlIGNzLmxlbmd0aCgpfS4KKyAgICAgKiBAcmV0dXJuIHRoZSBjcmVhdGVkIGNoYXIgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGVpdGhlciB7QGNvZGUgc3RhcnR9IG9yIHtAY29kZSBlbmR9IGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDaGFyQnVmZmVyIHdyYXAoQ2hhclNlcXVlbmNlIGNzLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgaWYgKHN0YXJ0IDwgMCB8fCBlbmQgPCBzdGFydCB8fCBlbmQgPiBjcy5sZW5ndGgoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oImNzLmxlbmd0aCgpPSIgKyBjcy5sZW5ndGgoKSArICIsIHN0YXJ0PSIgKyBzdGFydCArICIsIGVuZD0iICsgZW5kKTsKKyAgICAgICAgfQorICAgICAgICBDaGFyQnVmZmVyIHJlc3VsdCA9IG5ldyBDaGFyU2VxdWVuY2VBZGFwdGVyKGNzKTsKKyAgICAgICAgcmVzdWx0LnBvc2l0aW9uID0gc3RhcnQ7CisgICAgICAgIHJlc3VsdC5saW1pdCA9IGVuZDsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBDaGFyQnVmZmVyKGludCBjYXBhY2l0eSkgeworICAgICAgICBzdXBlcigxLCBjYXBhY2l0eSwgbnVsbCk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIGNoYXJbXSBhcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIHByb3RlY3RlZEFycmF5KCk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIGludCBhcnJheU9mZnNldCgpIHsKKyAgICAgICAgcmV0dXJuIHByb3RlY3RlZEFycmF5T2Zmc2V0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHJlYWQtb25seSBidWZmZXIgdGhhdCBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcmV0dXJuZWQgYnVmZmVyIGlzIGd1YXJhbnRlZWQgdG8gYmUgYSBuZXcgaW5zdGFuY2UsIGV2ZW4gaWYgdGhpcworICAgICAqIGJ1ZmZlciBpcyByZWFkLW9ubHkgaXRzZWxmLiBUaGUgbmV3IGJ1ZmZlcidzIHBvc2l0aW9uLCBsaW1pdCwgY2FwYWNpdHkKKyAgICAgKiBhbmQgbWFyayBhcmUgdGhlIHNhbWUgYXMgdGhpcyBidWZmZXIncy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbmV3IGJ1ZmZlciBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlciwgd2hpY2ggbWVhbnMgdGhpcworICAgICAqIGJ1ZmZlcidzIGNoYW5nZSBvZiBjb250ZW50IHdpbGwgYmUgdmlzaWJsZSB0byB0aGUgbmV3IGJ1ZmZlci4gVGhlIHR3bworICAgICAqIGJ1ZmZlcidzIHBvc2l0aW9uLCBsaW1pdCBhbmQgbWFyayBhcmUgaW5kZXBlbmRlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcmVhZC1vbmx5IHZlcnNpb24gb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENoYXJCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2hhcmFjdGVyIGxvY2F0ZWQgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBpbiB0aGUgYnVmZmVyLiBUaGUKKyAgICAgKiBpbmRleCB2YWx1ZSBpcyByZWZlcmVuY2VkIGZyb20gdGhlIGN1cnJlbnQgYnVmZmVyIHBvc2l0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggcmVmZXJlbmNlZCBmcm9tIHRoZSBjdXJyZW50IGJ1ZmZlciBwb3NpdGlvbi4gSXQgbXVzdAorICAgICAqICAgICAgICAgICAgbm90IGJlIGxlc3MgdGhhbiB6ZXJvIGJ1dCBsZXNzIHRoYW4gdGhlIHZhbHVlIG9idGFpbmVkIGZyb20gYQorICAgICAqICAgICAgICAgICAgY2FsbCB0byB7QGNvZGUgcmVtYWluaW5nKCl9LgorICAgICAqIEByZXR1cm4gdGhlIGNoYXJhY3RlciBsb2NhdGVkIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggKHJlZmVyZW5jZWQgZnJvbSB0aGUKKyAgICAgKiAgICAgICAgIGN1cnJlbnQgcG9zaXRpb24pIGluIHRoZSBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIGluZGV4IGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGNoYXIgY2hhckF0KGludCBpbmRleCkgeworICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IHJlbWFpbmluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiaW5kZXg9IiArIGluZGV4ICsgIiwgcmVtYWluaW5nKCk9IiArIHJlbWFpbmluZygpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0KHBvc2l0aW9uICsgaW5kZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhY3RzIHRoaXMgY2hhciBidWZmZXIuCisgICAgICogPHA+CisgICAgICogVGhlIHJlbWFpbmluZyBjaGFycyB3aWxsIGJlIG1vdmVkIHRvIHRoZSBoZWFkIG9mIHRoZSBidWZmZXIsCisgICAgICogc3RhcnRpbmcgZnJvbSBwb3NpdGlvbiB6ZXJvLiBUaGVuIHRoZSBwb3NpdGlvbiBpcyBzZXQgdG8KKyAgICAgKiB7QGNvZGUgcmVtYWluaW5nKCl9OyB0aGUgbGltaXQgaXMgc2V0IHRvIGNhcGFjaXR5OyB0aGUgbWFyayBpcyBjbGVhcmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENoYXJCdWZmZXIgY29tcGFjdCgpOworCisgICAgLyoqCisgICAgICogQ29tcGFyZSB0aGUgcmVtYWluaW5nIGNoYXJzIG9mIHRoaXMgYnVmZmVyIHRvIGFub3RoZXIgY2hhcgorICAgICAqIGJ1ZmZlcidzIHJlbWFpbmluZyBjaGFycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdGhlckJ1ZmZlcgorICAgICAqICAgICAgICAgICAgYW5vdGhlciBjaGFyIGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIGEgbmVnYXRpdmUgdmFsdWUgaWYgdGhpcyBpcyBsZXNzIHRoYW4ge0Bjb2RlIG90aGVyQnVmZmVyfTsgMCBpZgorICAgICAqICAgICAgICAgdGhpcyBlcXVhbHMgdG8ge0Bjb2RlIG90aGVyQnVmZmVyfTsgYSBwb3NpdGl2ZSB2YWx1ZSBpZiB0aGlzIGlzCisgICAgICogICAgICAgICBncmVhdGVyIHRoYW4ge0Bjb2RlIG90aGVyQnVmZmVyfS4KKyAgICAgKiBAZXhjZXB0aW9uIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBvdGhlckJ1ZmZlcn0gaXMgbm90IGEgY2hhciBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGludCBjb21wYXJlVG8oQ2hhckJ1ZmZlciBvdGhlckJ1ZmZlcikgeworICAgICAgICBpbnQgY29tcGFyZVJlbWFpbmluZyA9IChyZW1haW5pbmcoKSA8IG90aGVyQnVmZmVyLnJlbWFpbmluZygpKSA/IHJlbWFpbmluZygpCisgICAgICAgICAgICAgICAgOiBvdGhlckJ1ZmZlci5yZW1haW5pbmcoKTsKKyAgICAgICAgaW50IHRoaXNQb3MgPSBwb3NpdGlvbjsKKyAgICAgICAgaW50IG90aGVyUG9zID0gb3RoZXJCdWZmZXIucG9zaXRpb247CisgICAgICAgIGNoYXIgdGhpc0J5dGUsIG90aGVyQnl0ZTsKKyAgICAgICAgd2hpbGUgKGNvbXBhcmVSZW1haW5pbmcgPiAwKSB7CisgICAgICAgICAgICB0aGlzQnl0ZSA9IGdldCh0aGlzUG9zKTsKKyAgICAgICAgICAgIG90aGVyQnl0ZSA9IG90aGVyQnVmZmVyLmdldChvdGhlclBvcyk7CisgICAgICAgICAgICBpZiAodGhpc0J5dGUgIT0gb3RoZXJCeXRlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXNCeXRlIDwgb3RoZXJCeXRlID8gLTEgOiAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpc1BvcysrOworICAgICAgICAgICAgb3RoZXJQb3MrKzsKKyAgICAgICAgICAgIGNvbXBhcmVSZW1haW5pbmctLTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVtYWluaW5nKCkgLSBvdGhlckJ1ZmZlci5yZW1haW5pbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgZHVwbGljYXRlZCBidWZmZXIgdGhhdCBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZHVwbGljYXRlZCBidWZmZXIncyBpbml0aWFsIHBvc2l0aW9uLCBsaW1pdCwgY2FwYWNpdHkgYW5kIG1hcmsgYXJlCisgICAgICogdGhlIHNhbWUgYXMgdGhpcyBidWZmZXIncy4gVGhlIGR1cGxpY2F0ZWQgYnVmZmVyJ3MgcmVhZC1vbmx5IHByb3BlcnR5IGFuZAorICAgICAqIGJ5dGUgb3JkZXIgYXJlIHRoZSBzYW1lIGFzIHRoaXMgYnVmZmVyJ3MsIHRvby4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbmV3IGJ1ZmZlciBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlciwgd2hpY2ggbWVhbnMgZWl0aGVyCisgICAgICogYnVmZmVyJ3MgY2hhbmdlIG9mIGNvbnRlbnQgd2lsbCBiZSB2aXNpYmxlIHRvIHRoZSBvdGhlci4gVGhlIHR3byBidWZmZXIncworICAgICAqIHBvc2l0aW9uLCBsaW1pdCBhbmQgbWFyayBhcmUgaW5kZXBlbmRlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgZHVwbGljYXRlZCBidWZmZXIgdGhhdCBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQ2hhckJ1ZmZlciBkdXBsaWNhdGUoKTsKKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIHRoaXMgY2hhciBidWZmZXIgaXMgZXF1YWwgdG8gYW5vdGhlciBvYmplY3QuCisgICAgICogPHA+CisgICAgICogSWYge0Bjb2RlIG90aGVyfSBpcyBub3QgYSBjaGFyIGJ1ZmZlciB0aGVuIHtAY29kZSBmYWxzZX0gaXMgcmV0dXJuZWQuIFR3bworICAgICAqIGNoYXIgYnVmZmVycyBhcmUgZXF1YWwgaWYgYW5kIG9ubHkgaWYgdGhlaXIgcmVtYWluaW5nIGNoYXJzIGFyZSBleGFjdGx5CisgICAgICogdGhlIHNhbWUuIFBvc2l0aW9uLCBsaW1pdCwgY2FwYWNpdHkgYW5kIG1hcmsgYXJlIG5vdCBjb25zaWRlcmVkLgorICAgICAqCisgICAgICogQHBhcmFtIG90aGVyCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUgd2l0aCB0aGlzIGNoYXIgYnVmZmVyLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgY2hhciBidWZmZXIgaXMgZXF1YWwgdG8ge0Bjb2RlIG90aGVyfSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKKyAgICAgICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBDaGFyQnVmZmVyKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIENoYXJCdWZmZXIgb3RoZXJCdWZmZXIgPSAoQ2hhckJ1ZmZlcikgb3RoZXI7CisKKyAgICAgICAgaWYgKHJlbWFpbmluZygpICE9IG90aGVyQnVmZmVyLnJlbWFpbmluZygpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBpbnQgbXlQb3NpdGlvbiA9IHBvc2l0aW9uOworICAgICAgICBpbnQgb3RoZXJQb3NpdGlvbiA9IG90aGVyQnVmZmVyLnBvc2l0aW9uOworICAgICAgICBib29sZWFuIGVxdWFsU29GYXIgPSB0cnVlOworICAgICAgICB3aGlsZSAoZXF1YWxTb0ZhciAmJiAobXlQb3NpdGlvbiA8IGxpbWl0KSkgeworICAgICAgICAgICAgZXF1YWxTb0ZhciA9IGdldChteVBvc2l0aW9uKyspID09IG90aGVyQnVmZmVyLmdldChvdGhlclBvc2l0aW9uKyspOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGVxdWFsU29GYXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2hhciBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQgaW5jcmVhc2VzIHRoZSBwb3NpdGlvbiBieSAxLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2hhciBhdCB0aGUgY3VycmVudCBwb3NpdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSBwb3NpdGlvbiBpcyBlcXVhbCBvciBncmVhdGVyIHRoYW4gbGltaXQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGNoYXIgZ2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBjaGFycyBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uIGludG8gdGhlIHNwZWNpZmllZCBjaGFyIGFycmF5IGFuZAorICAgICAqIGluY3JlYXNlcyB0aGUgcG9zaXRpb24gYnkgdGhlIG51bWJlciBvZiBjaGFycyByZWFkLgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcworICAgICAqIHtAY29kZSBnZXQoZHN0LCAwLCBkc3QubGVuZ3RoKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gY2hhciBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGRzdC5sZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgcmVtYWluaW5nKCl9LgorICAgICAqLworICAgIHB1YmxpYyBDaGFyQnVmZmVyIGdldChjaGFyW10gZHN0KSB7CisgICAgICAgIHJldHVybiBnZXQoZHN0LCAwLCBkc3QubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBjaGFycyBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uIGludG8gdGhlIHNwZWNpZmllZCBjaGFyIGFycmF5LAorICAgICAqIHN0YXJ0aW5nIGZyb20gdGhlIHNwZWNpZmllZCBvZmZzZXQsIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IHRoZQorICAgICAqIG51bWJlciBvZiBjaGFycyByZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBjaGFyIGFycmF5LgorICAgICAqIEBwYXJhbSBkc3RPZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgb2YgdGhlIGNoYXIgYXJyYXksIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QKKyAgICAgKiAgICAgICAgICAgIGdyZWF0ZXIgdGhhbiB7QGNvZGUgZHN0Lmxlbmd0aH0uCisgICAgICogQHBhcmFtIGNoYXJDb3VudAorICAgICAqICAgICAgICAgICAgVGhlIG51bWJlciBvZiBjaGFycyB0byByZWFkLCBtdXN0IGJlIG5vIGxlc3MgdGhhbiB6ZXJvIGFuZCBubworICAgICAqICAgICAgICAgICAgZ3JlYXRlciB0aGFuIHtAY29kZSBkc3QubGVuZ3RoIC0gZHN0T2Zmc2V0fS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGVpdGhlciB7QGNvZGUgZHN0T2Zmc2V0fSBvciB7QGNvZGUgY2hhckNvdW50fSBpcyBpbnZhbGlkLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGNoYXJDb3VudH0gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSByZW1haW5pbmcoKX0uCisgICAgICovCisgICAgcHVibGljIENoYXJCdWZmZXIgZ2V0KGNoYXJbXSBkc3QsIGludCBkc3RPZmZzZXQsIGludCBjaGFyQ291bnQpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoZHN0Lmxlbmd0aCwgZHN0T2Zmc2V0LCBjaGFyQ291bnQpOworICAgICAgICBpZiAoY2hhckNvdW50ID4gcmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gZHN0T2Zmc2V0OyBpIDwgZHN0T2Zmc2V0ICsgY2hhckNvdW50OyArK2kpIHsKKyAgICAgICAgICAgIGRzdFtpXSA9IGdldCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjaGFyIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXg7IHRoZSBwb3NpdGlvbiBpcyBub3QgY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBhbmQgbGVzcyB0aGFuIGxpbWl0LgorICAgICAqIEByZXR1cm4gYSBjaGFyIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgaW5kZXggaXMgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgY2hhciBnZXQoaW50IGluZGV4KTsKKworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc0FycmF5KCkgeworICAgICAgICByZXR1cm4gcHJvdGVjdGVkSGFzQXJyYXkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxjdWxhdGVzIHRoaXMgYnVmZmVyJ3MgaGFzaCBjb2RlIGZyb20gdGhlIHJlbWFpbmluZyBjaGFycy4gVGhlCisgICAgICogcG9zaXRpb24sIGxpbWl0LCBjYXBhY2l0eSBhbmQgbWFyayBkb24ndCBhZmZlY3QgdGhlIGhhc2ggY29kZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZSBjYWxjdWxhdGVkIGZyb20gdGhlIHJlbWFpbmluZyBjaGFycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBpbnQgbXlQb3NpdGlvbiA9IHBvc2l0aW9uOworICAgICAgICBpbnQgaGFzaCA9IDA7CisgICAgICAgIHdoaWxlIChteVBvc2l0aW9uIDwgbGltaXQpIHsKKyAgICAgICAgICAgIGhhc2ggPSBoYXNoICsgZ2V0KG15UG9zaXRpb24rKyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGhhc2g7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBidWZmZXIgaXMgZGlyZWN0LiBBIGRpcmVjdCBidWZmZXIgd2lsbCB0cnkgaXRzCisgICAgICogYmVzdCB0byB0YWtlIGFkdmFudGFnZSBvZiBuYXRpdmUgbWVtb3J5IEFQSXMgYW5kIGl0IG1heSBub3Qgc3RheSBpbiB0aGUKKyAgICAgKiBKYXZhIGhlYXAsIHNvIGl0IGlzIG5vdCBhZmZlY3RlZCBieSBnYXJiYWdlIGNvbGxlY3Rpb24uCisgICAgICogPHA+CisgICAgICogQSBjaGFyIGJ1ZmZlciBpcyBkaXJlY3QgaWYgaXQgaXMgYmFzZWQgb24gYSBieXRlIGJ1ZmZlciBhbmQgdGhlIGJ5dGUKKyAgICAgKiBidWZmZXIgaXMgZGlyZWN0LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBidWZmZXIgaXMgZGlyZWN0LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc0RpcmVjdCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHJlbWFpbmluZyBjaGFycy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiByZW1haW5pbmcgY2hhcnMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBsZW5ndGgoKSB7CisgICAgICAgIHJldHVybiByZW1haW5pbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBieXRlIG9yZGVyIHVzZWQgYnkgdGhpcyBidWZmZXIgd2hlbiBjb252ZXJ0aW5nIGNoYXJzIGZyb20vdG8KKyAgICAgKiBieXRlcy4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIGJ1ZmZlciBpcyBub3QgYmFzZWQgb24gYSBieXRlIGJ1ZmZlciwgdGhlbiB0aGlzIGFsd2F5cyByZXR1cm5zCisgICAgICogdGhlIHBsYXRmb3JtJ3MgbmF0aXZlIGJ5dGUgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBieXRlIG9yZGVyIHVzZWQgYnkgdGhpcyBidWZmZXIgd2hlbiBjb252ZXJ0aW5nIGNoYXJzIGZyb20vdG8KKyAgICAgKiAgICAgICAgIGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCeXRlT3JkZXIgb3JkZXIoKTsKKworICAgIC8qKgorICAgICAqIENoaWxkIGNsYXNzIGltcGxlbWVudHMgdGhpcyBtZXRob2QgdG8gcmVhbGl6ZSB7QGNvZGUgYXJyYXkoKX0uCisgICAgICoKKyAgICAgKiBAc2VlICNhcnJheSgpCisgICAgICovCisgICAgYWJzdHJhY3QgY2hhcltdIHByb3RlY3RlZEFycmF5KCk7CisKKyAgICAvKioKKyAgICAgKiBDaGlsZCBjbGFzcyBpbXBsZW1lbnRzIHRoaXMgbWV0aG9kIHRvIHJlYWxpemUge0Bjb2RlIGFycmF5T2Zmc2V0KCl9LgorICAgICAqCisgICAgICogQHNlZSAjYXJyYXlPZmZzZXQoKQorICAgICAqLworICAgIGFic3RyYWN0IGludCBwcm90ZWN0ZWRBcnJheU9mZnNldCgpOworCisgICAgLyoqCisgICAgICogQ2hpbGQgY2xhc3MgaW1wbGVtZW50cyB0aGlzIG1ldGhvZCB0byByZWFsaXplIHtAY29kZSBoYXNBcnJheSgpfS4KKyAgICAgKgorICAgICAqIEBzZWUgI2hhc0FycmF5KCkKKyAgICAgKi8KKyAgICBhYnN0cmFjdCBib29sZWFuIHByb3RlY3RlZEhhc0FycmF5KCk7CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGdpdmVuIGNoYXIgdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gYW5kIGluY3JlYXNlcyB0aGUgcG9zaXRpb24KKyAgICAgKiBieSAxLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyIHRvIHdyaXRlLgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHBvc2l0aW9uIGlzIGVxdWFsIG9yIGdyZWF0ZXIgdGhhbiBsaW1pdC4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENoYXJCdWZmZXIgcHV0KGNoYXIgYyk7CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgY2hhcnMgZnJvbSB0aGUgZ2l2ZW4gY2hhciBhcnJheSB0byB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQKKyAgICAgKiBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IHRoZSBudW1iZXIgb2YgY2hhcnMgd3JpdHRlbi4KKyAgICAgKiA8cD4KKyAgICAgKiBDYWxsaW5nIHRoaXMgbWV0aG9kIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMKKyAgICAgKiB7QGNvZGUgcHV0KHNyYywgMCwgc3JjLmxlbmd0aCl9LgorICAgICAqCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBjaGFyIGFycmF5LgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSByZW1haW5pbmcoKX0gaXMgbGVzcyB0aGFuIHtAY29kZSBzcmMubGVuZ3RofS4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENoYXJCdWZmZXIgcHV0KGNoYXJbXSBzcmMpIHsKKyAgICAgICAgcmV0dXJuIHB1dChzcmMsIDAsIHNyYy5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBjaGFycyBmcm9tIHRoZSBnaXZlbiBjaGFyIGFycmF5LCBzdGFydGluZyBmcm9tIHRoZSBzcGVjaWZpZWQgb2Zmc2V0LAorICAgICAqIHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IHRoZSBudW1iZXIgb2YgY2hhcnMKKyAgICAgKiB3cml0dGVuLgorICAgICAqCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBjaGFyIGFycmF5LgorICAgICAqIEBwYXJhbSBzcmNPZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgb2YgY2hhciBhcnJheSwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIG5vdCBncmVhdGVyCisgICAgICogICAgICAgICAgICB0aGFuIHtAY29kZSBzcmMubGVuZ3RofS4KKyAgICAgKiBAcGFyYW0gY2hhckNvdW50CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNoYXJzIHRvIHdyaXRlLCBtdXN0IGJlIG5vIGxlc3MgdGhhbiB6ZXJvIGFuZCBubworICAgICAqICAgICAgICAgICAgZ3JlYXRlciB0aGFuIHtAY29kZSBzcmMubGVuZ3RoIC0gc3JjT2Zmc2V0fS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgcmVtYWluaW5nKCl9IGlzIGxlc3MgdGhhbiB7QGNvZGUgY2hhckNvdW50fS4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBlaXRoZXIge0Bjb2RlIHNyY09mZnNldH0gb3Ige0Bjb2RlIGNoYXJDb3VudH0gaXMgaW52YWxpZC4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIENoYXJCdWZmZXIgcHV0KGNoYXJbXSBzcmMsIGludCBzcmNPZmZzZXQsIGludCBjaGFyQ291bnQpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoc3JjLmxlbmd0aCwgc3JjT2Zmc2V0LCBjaGFyQ291bnQpOworICAgICAgICBpZiAoY2hhckNvdW50ID4gcmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSBzcmNPZmZzZXQ7IGkgPCBzcmNPZmZzZXQgKyBjaGFyQ291bnQ7ICsraSkgeworICAgICAgICAgICAgcHV0KHNyY1tpXSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGFsbCB0aGUgcmVtYWluaW5nIGNoYXJzIG9mIHRoZSB7QGNvZGUgc3JjfSBjaGFyIGJ1ZmZlciB0byB0aGlzCisgICAgICogYnVmZmVyJ3MgY3VycmVudCBwb3NpdGlvbiwgYW5kIGluY3JlYXNlcyBib3RoIGJ1ZmZlcnMnIHBvc2l0aW9uIGJ5IHRoZQorICAgICAqIG51bWJlciBvZiBjaGFycyBjb3BpZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGNoYXIgYnVmZmVyLgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzcmMucmVtYWluaW5nKCl9IGlzIGdyZWF0ZXIgdGhhbiB0aGlzIGJ1ZmZlcidzCisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIHJlbWFpbmluZygpfS4KKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzcmN9IGlzIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2hhckJ1ZmZlciBwdXQoQ2hhckJ1ZmZlciBzcmMpIHsKKyAgICAgICAgaWYgKHNyYyA9PSB0aGlzKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNyYy5yZW1haW5pbmcoKSA+IHJlbWFpbmluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGNoYXJbXSBjb250ZW50cyA9IG5ldyBjaGFyW3NyYy5yZW1haW5pbmcoKV07CisgICAgICAgIHNyYy5nZXQoY29udGVudHMpOworICAgICAgICBwdXQoY29udGVudHMpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBjaGFyIHRvIHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyBidWZmZXI7IHRoZSBwb3NpdGlvbiBpcyBub3QKKyAgICAgKiBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgsIG11c3QgYmUgbm8gbGVzcyB0aGFuIHplcm8gYW5kIGxlc3MgdGhhbiB0aGUgbGltaXQuCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyIHRvIHdyaXRlLgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgaW5kZXggaXMgaW52YWxpZC4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENoYXJCdWZmZXIgcHV0KGludCBpbmRleCwgY2hhciBjKTsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhbGwgY2hhcnMgb2YgdGhlIGdpdmVuIHN0cmluZyB0byB0aGUgY3VycmVudCBwb3NpdGlvbiBvZiB0aGlzCisgICAgICogYnVmZmVyLCBhbmQgaW5jcmVhc2VzIHRoZSBwb3NpdGlvbiBieSB0aGUgbGVuZ3RoIG9mIHN0cmluZy4KKyAgICAgKiA8cD4KKyAgICAgKiBDYWxsaW5nIHRoaXMgbWV0aG9kIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMKKyAgICAgKiB7QGNvZGUgcHV0KHN0ciwgMCwgc3RyLmxlbmd0aCgpKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHdyaXRlLgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSByZW1haW5pbmcoKX0gaXMgbGVzcyB0aGFuIHRoZSBsZW5ndGggb2Ygc3RyaW5nLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQ2hhckJ1ZmZlciBwdXQoU3RyaW5nIHN0cikgeworICAgICAgICByZXR1cm4gcHV0KHN0ciwgMCwgc3RyLmxlbmd0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgY2hhcnMgb2YgdGhlIGdpdmVuIHN0cmluZyB0byB0aGUgY3VycmVudCBwb3NpdGlvbiBvZiB0aGlzIGJ1ZmZlciwKKyAgICAgKiBhbmQgaW5jcmVhc2VzIHRoZSBwb3NpdGlvbiBieSB0aGUgbnVtYmVyIG9mIGNoYXJzIHdyaXR0ZW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IGNoYXIgdG8gd3JpdGUsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QgZ3JlYXRlcgorICAgICAqICAgICAgICAgICAgdGhhbiB7QGNvZGUgc3RyLmxlbmd0aCgpfS4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgbGFzdCBjaGFyIHRvIHdyaXRlIChleGNsdWRpbmcpLCBtdXN0IGJlIGxlc3MgdGhhbgorICAgICAqICAgICAgICAgICAge0Bjb2RlIHN0YXJ0fSBhbmQgbm90IGdyZWF0ZXIgdGhhbiB7QGNvZGUgc3RyLmxlbmd0aCgpfS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgcmVtYWluaW5nKCl9IGlzIGxlc3MgdGhhbiB7QGNvZGUgZW5kIC0gc3RhcnR9LgorICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGVpdGhlciB7QGNvZGUgc3RhcnR9IG9yIHtAY29kZSBlbmR9IGlzIGludmFsaWQuCisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBDaGFyQnVmZmVyIHB1dChTdHJpbmcgc3RyLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgaWYgKHN0YXJ0IDwgMCB8fCBlbmQgPCBzdGFydCB8fCBlbmQgPiBzdHIubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJzdHIubGVuZ3RoKCk9IiArIHN0ci5sZW5ndGgoKSArCisgICAgICAgICAgICAgICAgICAgICIsIHN0YXJ0PSIgKyBzdGFydCArICIsIGVuZD0iICsgZW5kKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZW5kIC0gc3RhcnQgPiByZW1haW5pbmcoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHsKKyAgICAgICAgICAgIHB1dChzdHIuY2hhckF0KGkpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc2xpY2VkIGJ1ZmZlciB0aGF0IHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBzbGljZWQgYnVmZmVyJ3MgY2FwYWNpdHkgd2lsbCBiZSB0aGlzIGJ1ZmZlcidzIHtAY29kZSByZW1haW5pbmcoKX0sCisgICAgICogYW5kIGl0cyB6ZXJvIHBvc2l0aW9uIHdpbGwgY29ycmVzcG9uZCB0byB0aGlzIGJ1ZmZlcidzIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogVGhlIG5ldyBidWZmZXIncyBwb3NpdGlvbiB3aWxsIGJlIDAsIGxpbWl0IHdpbGwgYmUgaXRzIGNhcGFjaXR5LCBhbmQgaXRzCisgICAgICogbWFyayBpcyBjbGVhcmVkLiBUaGUgbmV3IGJ1ZmZlcidzIHJlYWQtb25seSBwcm9wZXJ0eSBhbmQgYnl0ZSBvcmRlciBhcmUKKyAgICAgKiBzYW1lIGFzIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyIHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLCB3aGljaCBtZWFucyBlaXRoZXIKKyAgICAgKiBidWZmZXIncyBjaGFuZ2Ugb2YgY29udGVudCB3aWxsIGJlIHZpc2libGUgdG8gdGhlIG90aGVyLiBUaGUgdHdvIGJ1ZmZlcidzCisgICAgICogcG9zaXRpb24sIGxpbWl0IGFuZCBtYXJrIGFyZSBpbmRlcGVuZGVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzbGljZWQgYnVmZmVyIHRoYXQgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENoYXJCdWZmZXIgc2xpY2UoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgY2hhciBidWZmZXIgcmVwcmVzZW50aW5nIGEgc3ViLXNlcXVlbmNlIG9mIHRoaXMgYnVmZmVyJ3MKKyAgICAgKiBjdXJyZW50IHJlbWFpbmluZyBjb250ZW50LgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyJ3MgcG9zaXRpb24gd2lsbCBiZSB7QGNvZGUgcG9zaXRpb24oKSArIHN0YXJ0fSwgbGltaXQgd2lsbAorICAgICAqIGJlIHtAY29kZSBwb3NpdGlvbigpICsgZW5kfSwgY2FwYWNpdHkgd2lsbCBiZSB0aGUgc2FtZSBhcyB0aGlzIGJ1ZmZlci4KKyAgICAgKiBUaGUgbmV3IGJ1ZmZlcidzIHJlYWQtb25seSBwcm9wZXJ0eSBhbmQgYnl0ZSBvcmRlciBhcmUgdGhlIHNhbWUgYXMgdGhpcworICAgICAqIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbmV3IGJ1ZmZlciBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlciwgd2hpY2ggbWVhbnMgZWl0aGVyCisgICAgICogYnVmZmVyJ3MgY2hhbmdlIG9mIGNvbnRlbnQgd2lsbCBiZSB2aXNpYmxlIHRvIHRoZSBvdGhlci4gVGhlIHR3byBidWZmZXIncworICAgICAqIHBvc2l0aW9uLCBsaW1pdCBhbmQgbWFyayBhcmUgaW5kZXBlbmRlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBpbmRleCBvZiB0aGUgc3ViLXNlcXVlbmNlLCByZWZlcmVuY2VkIGZyb20gdGhlCisgICAgICogICAgICAgICAgICBjdXJyZW50IGJ1ZmZlciBwb3NpdGlvbi4gTXVzdCBub3QgYmUgbGVzcyB0aGFuIHplcm8gYW5kIG5vdAorICAgICAqICAgICAgICAgICAgZ3JlYXRlciB0aGFuIHRoZSB2YWx1ZSBvYnRhaW5lZCBmcm9tIGEgY2FsbCB0bworICAgICAqICAgICAgICAgICAge0Bjb2RlIHJlbWFpbmluZygpfS4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgZW5kIGluZGV4IG9mIHRoZSBzdWItc2VxdWVuY2UsIHJlZmVyZW5jZWQgZnJvbSB0aGUgY3VycmVudAorICAgICAqICAgICAgICAgICAgYnVmZmVyIHBvc2l0aW9uLiBNdXN0IG5vdCBiZSBsZXNzIHRoYW4ge0Bjb2RlIHN0YXJ0fSBhbmQgbm90CisgICAgICogICAgICAgICAgICBiZSBncmVhdGVyIHRoYW4gdGhlIHZhbHVlIG9idGFpbmVkIGZyb20gYSBjYWxsIHRvCisgICAgICogICAgICAgICAgICB7QGNvZGUgcmVtYWluaW5nKCl9LgorICAgICAqIEByZXR1cm4gYSBuZXcgY2hhciBidWZmZXIgcmVwcmVzZW50cyBhIHN1Yi1zZXF1ZW5jZSBvZiB0aGlzIGJ1ZmZlcidzCisgICAgICogICAgICAgICBjdXJyZW50IHJlbWFpbmluZyBjb250ZW50LgorICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGVpdGhlciB7QGNvZGUgc3RhcnR9IG9yIHtAY29kZSBlbmR9IGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENoYXJTZXF1ZW5jZSBzdWJTZXF1ZW5jZShpbnQgc3RhcnQsIGludCBlbmQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGN1cnJlbnQgcmVtYWluaW5nIGNoYXJzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIobGltaXQgLSBwb3NpdGlvbik7CisgICAgICAgIGZvciAoaW50IGkgPSBwb3NpdGlvbjsgaSA8IGxpbWl0OyBpKyspIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoZ2V0KGkpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBnaXZlbiBjaGFyIHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uCisgICAgICogYnkgMS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY2hhciB0byB3cml0ZS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBwb3NpdGlvbiBpcyBlcXVhbCBvciBncmVhdGVyIHRoYW4gbGltaXQuCisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBDaGFyQnVmZmVyIGFwcGVuZChjaGFyIGMpIHsKKyAgICAgICAgcmV0dXJuIHB1dChjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYWxsIGNoYXJzIG9mIHRoZSBnaXZlbiBjaGFyYWN0ZXIgc2VxdWVuY2Uge0Bjb2RlIGNzcX0gdG8gdGhlCisgICAgICogY3VycmVudCBwb3NpdGlvbiBvZiB0aGlzIGJ1ZmZlciwgYW5kIGluY3JlYXNlcyB0aGUgcG9zaXRpb24gYnkgdGhlIGxlbmd0aAorICAgICAqIG9mIHRoZSBjc3EuCisgICAgICogPHA+CisgICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIHtAY29kZSBhcHBlbmQoY3NxLnRvU3RyaW5nKCkpfS4KKyAgICAgKiBJZiB0aGUge0Bjb2RlIENoYXJTZXF1ZW5jZX0gaXMge0Bjb2RlIG51bGx9IHRoZSBzdHJpbmcgIm51bGwiIHdpbGwgYmUKKyAgICAgKiB3cml0dGVuIHRvIHRoZSBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY3NxCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIENoYXJTZXF1ZW5jZX0gdG8gd3JpdGUuCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHJlbWFpbmluZygpfSBpcyBsZXNzIHRoYW4gdGhlIGxlbmd0aCBvZiBjc3EuCisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBDaGFyQnVmZmVyIGFwcGVuZChDaGFyU2VxdWVuY2UgY3NxKSB7CisgICAgICAgIGlmIChjc3EgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHB1dChjc3EudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHB1dCgibnVsbCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBjaGFycyBvZiB0aGUgZ2l2ZW4ge0Bjb2RlIENoYXJTZXF1ZW5jZX0gdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gb2YKKyAgICAgKiB0aGlzIGJ1ZmZlciwgYW5kIGluY3JlYXNlcyB0aGUgcG9zaXRpb24gYnkgdGhlIG51bWJlciBvZiBjaGFycyB3cml0dGVuLgorICAgICAqCisgICAgICogQHBhcmFtIGNzcQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDaGFyU2VxdWVuY2V9IHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IGNoYXIgdG8gd3JpdGUsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QgZ3JlYXRlcgorICAgICAqICAgICAgICAgICAgdGhhbiB7QGNvZGUgY3NxLmxlbmd0aCgpfS4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgbGFzdCBjaGFyIHRvIHdyaXRlIChleGNsdWRpbmcpLCBtdXN0IGJlIGxlc3MgdGhhbgorICAgICAqICAgICAgICAgICAge0Bjb2RlIHN0YXJ0fSBhbmQgbm90IGdyZWF0ZXIgdGhhbiB7QGNvZGUgY3NxLmxlbmd0aCgpfS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgcmVtYWluaW5nKCl9IGlzIGxlc3MgdGhhbiB7QGNvZGUgZW5kIC0gc3RhcnR9LgorICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGVpdGhlciB7QGNvZGUgc3RhcnR9IG9yIHtAY29kZSBlbmR9IGlzIGludmFsaWQuCisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBDaGFyQnVmZmVyIGFwcGVuZChDaGFyU2VxdWVuY2UgY3NxLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgaWYgKGNzcSA9PSBudWxsKSB7CisgICAgICAgICAgICBjc3EgPSAibnVsbCI7CisgICAgICAgIH0KKyAgICAgICAgQ2hhclNlcXVlbmNlIGNzID0gY3NxLnN1YlNlcXVlbmNlKHN0YXJ0LCBlbmQpOworICAgICAgICBpZiAoY3MubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICByZXR1cm4gcHV0KGNzLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGNoYXJhY3RlcnMgZnJvbSB0aGlzIGJ1ZmZlciBhbmQgcHV0cyB0aGVtIGludG8ge0Bjb2RlIHRhcmdldH0uIFRoZQorICAgICAqIG51bWJlciBvZiBjaGFycyB0aGF0IGFyZSBjb3BpZWQgaXMgZWl0aGVyIHRoZSBudW1iZXIgb2YgcmVtYWluaW5nIGNoYXJzCisgICAgICogaW4gdGhpcyBidWZmZXIgb3IgdGhlIG51bWJlciBvZiByZW1haW5pbmcgY2hhcnMgaW4ge0Bjb2RlIHRhcmdldH0sCisgICAgICogd2hpY2hldmVyIGlzIHNtYWxsZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGFyZ2V0CisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IGNoYXIgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHRhcmdldH0gaXMgdGhpcyBidWZmZXIuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHRocm93cyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHtAY29kZSB0YXJnZXR9LgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBjaGFycyBjb3BpZWQgb3IgLTEgaWYgdGhlcmUgYXJlIG5vIGNoYXJzIGxlZnQgdG8gYmUKKyAgICAgKiAgICAgICAgIHJlYWQgZnJvbSB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHJlYWQoQ2hhckJ1ZmZlciB0YXJnZXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByZW1haW5pbmcgPSByZW1haW5pbmcoKTsKKyAgICAgICAgaWYgKHRhcmdldCA9PSB0aGlzKSB7CisgICAgICAgICAgICBpZiAocmVtYWluaW5nID09IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJlbWFpbmluZyA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbGltaXQgPiAwICYmIHRhcmdldC5yZW1haW5pbmcoKSA9PSAwID8gMCA6IC0xOworICAgICAgICB9CisgICAgICAgIHJlbWFpbmluZyA9IE1hdGgubWluKHRhcmdldC5yZW1haW5pbmcoKSwgcmVtYWluaW5nKTsKKyAgICAgICAgaWYgKHJlbWFpbmluZyA+IDApIHsKKyAgICAgICAgICAgIGNoYXJbXSBjaGFycyA9IG5ldyBjaGFyW3JlbWFpbmluZ107CisgICAgICAgICAgICBnZXQoY2hhcnMpOworICAgICAgICAgICAgdGFyZ2V0LnB1dChjaGFycyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlbWFpbmluZzsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vQ2hhclNlcXVlbmNlQWRhcHRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0NoYXJTZXF1ZW5jZUFkYXB0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYmVkMDk2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0NoYXJTZXF1ZW5jZUFkYXB0ZXIuamF2YQpAQCAtMCwwICsxLDE1MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogVGhpcyBjbGFzcyB3cmFwcyBhIGNoYXIgc2VxdWVuY2UgdG8gYmUgYSBjaGFyIGJ1ZmZlci4KKyAqIDxwPgorICogSW1wbGVtZW50YXRpb24gbm90aWNlOgorICogPHVsPgorICogPGxpPkNoYXIgc2VxdWVuY2UgYmFzZWQgYnVmZmVyIGlzIGFsd2F5cyByZWFkb25seS48L2xpPgorICogPC91bD4KKyAqIDwvcD4KKyAqCisgKi8KK2ZpbmFsIGNsYXNzIENoYXJTZXF1ZW5jZUFkYXB0ZXIgZXh0ZW5kcyBDaGFyQnVmZmVyIHsKKworICAgIHN0YXRpYyBDaGFyU2VxdWVuY2VBZGFwdGVyIGNvcHkoQ2hhclNlcXVlbmNlQWRhcHRlciBvdGhlcikgeworICAgICAgICBDaGFyU2VxdWVuY2VBZGFwdGVyIGJ1ZiA9IG5ldyBDaGFyU2VxdWVuY2VBZGFwdGVyKG90aGVyLnNlcXVlbmNlKTsKKyAgICAgICAgYnVmLmxpbWl0ID0gb3RoZXIubGltaXQ7CisgICAgICAgIGJ1Zi5wb3NpdGlvbiA9IG90aGVyLnBvc2l0aW9uOworICAgICAgICBidWYubWFyayA9IG90aGVyLm1hcms7CisgICAgICAgIHJldHVybiBidWY7CisgICAgfQorCisgICAgZmluYWwgQ2hhclNlcXVlbmNlIHNlcXVlbmNlOworCisgICAgQ2hhclNlcXVlbmNlQWRhcHRlcihDaGFyU2VxdWVuY2UgY2hzZXEpIHsKKyAgICAgICAgc3VwZXIoY2hzZXEubGVuZ3RoKCkpOworICAgICAgICBzZXF1ZW5jZSA9IGNoc2VxOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDaGFyQnVmZmVyIGFzUmVhZE9ubHlCdWZmZXIoKSB7CisgICAgICAgIHJldHVybiBkdXBsaWNhdGUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ2hhckJ1ZmZlciBjb21wYWN0KCkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ2hhckJ1ZmZlciBkdXBsaWNhdGUoKSB7CisgICAgICAgIHJldHVybiBjb3B5KHRoaXMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBjaGFyIGdldCgpIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNlcXVlbmNlLmNoYXJBdChwb3NpdGlvbisrKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgY2hhciBnZXQoaW50IGluZGV4KSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICByZXR1cm4gc2VxdWVuY2UuY2hhckF0KGluZGV4KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgQ2hhckJ1ZmZlciBnZXQoY2hhcltdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGNoYXJDb3VudCkgeworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChkc3QubGVuZ3RoLCBkc3RPZmZzZXQsIGNoYXJDb3VudCk7CisgICAgICAgIGlmIChjaGFyQ291bnQgPiByZW1haW5pbmcoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGludCBuZXdQb3NpdGlvbiA9IHBvc2l0aW9uICsgY2hhckNvdW50OworICAgICAgICBzZXF1ZW5jZS50b1N0cmluZygpLmdldENoYXJzKHBvc2l0aW9uLCBuZXdQb3NpdGlvbiwgZHN0LCBkc3RPZmZzZXQpOworICAgICAgICBwb3NpdGlvbiA9IG5ld1Bvc2l0aW9uOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdCgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzUmVhZE9ubHkoKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlT3JkZXIgb3JkZXIoKSB7CisgICAgICAgIHJldHVybiBCeXRlT3JkZXIubmF0aXZlT3JkZXIoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgY2hhcltdIHByb3RlY3RlZEFycmF5KCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IHByb3RlY3RlZEFycmF5T2Zmc2V0KCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwcm90ZWN0ZWRIYXNBcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDaGFyQnVmZmVyIHB1dChjaGFyIGMpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENoYXJCdWZmZXIgcHV0KGludCBpbmRleCwgY2hhciBjKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBDaGFyQnVmZmVyIHB1dChjaGFyW10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgY2hhckNvdW50KSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDaGFyQnVmZmVyIHB1dChTdHJpbmcgc3JjLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENoYXJCdWZmZXIgc2xpY2UoKSB7CisgICAgICAgIHJldHVybiBuZXcgQ2hhclNlcXVlbmNlQWRhcHRlcihzZXF1ZW5jZS5zdWJTZXF1ZW5jZShwb3NpdGlvbiwgbGltaXQpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ2hhclNlcXVlbmNlIHN1YlNlcXVlbmNlKGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBjaGVja1N0YXJ0RW5kUmVtYWluaW5nKHN0YXJ0LCBlbmQpOworICAgICAgICBDaGFyU2VxdWVuY2VBZGFwdGVyIHJlc3VsdCA9IGNvcHkodGhpcyk7CisgICAgICAgIHJlc3VsdC5wb3NpdGlvbiA9IHBvc2l0aW9uICsgc3RhcnQ7CisgICAgICAgIHJlc3VsdC5saW1pdCA9IHBvc2l0aW9uICsgZW5kOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9DaGFyVG9CeXRlQnVmZmVyQWRhcHRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0NoYXJUb0J5dGVCdWZmZXJBZGFwdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTI3MTI3NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9DaGFyVG9CeXRlQnVmZmVyQWRhcHRlci5qYXZhCkBAIC0wLDAgKzEsMTkwIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCitpbXBvcnQgbGliY29yZS5pby5TaXplT2Y7CisKKy8qKgorICogVGhpcyBjbGFzcyB3cmFwcyBhIGJ5dGUgYnVmZmVyIHRvIGJlIGEgY2hhciBidWZmZXIuCisgKiA8cD4KKyAqIEltcGxlbWVudGF0aW9uIG5vdGljZToKKyAqIDx1bD4KKyAqIDxsaT5BZnRlciBhIGJ5dGUgYnVmZmVyIGluc3RhbmNlIGlzIHdyYXBwZWQsIGl0IGJlY29tZXMgcHJpdmF0ZWx5IG93bmVkIGJ5CisgKiB0aGUgYWRhcHRlci4gSXQgbXVzdCBOT1QgYmUgYWNjZXNzZWQgb3V0c2lkZSB0aGUgYWRhcHRlciBhbnkgbW9yZS48L2xpPgorICogPGxpPlRoZSBieXRlIGJ1ZmZlcidzIHBvc2l0aW9uIGFuZCBsaW1pdCBhcmUgTk9UIGxpbmtlZCB3aXRoIHRoZSBhZGFwdGVyLgorICogVGhlIGFkYXB0ZXIgZXh0ZW5kcyBCdWZmZXIsIHRodXMgaGFzIGl0cyBvd24gcG9zaXRpb24gYW5kIGxpbWl0LjwvbGk+CisgKiA8L3VsPgorICogPC9wPgorICoKKyAqLworZmluYWwgY2xhc3MgQ2hhclRvQnl0ZUJ1ZmZlckFkYXB0ZXIgZXh0ZW5kcyBDaGFyQnVmZmVyIHsKKworICAgIHByaXZhdGUgZmluYWwgQnl0ZUJ1ZmZlciBieXRlQnVmZmVyOworCisgICAgc3RhdGljIENoYXJCdWZmZXIgYXNDaGFyQnVmZmVyKEJ5dGVCdWZmZXIgYnl0ZUJ1ZmZlcikgeworICAgICAgICBCeXRlQnVmZmVyIHNsaWNlID0gYnl0ZUJ1ZmZlci5zbGljZSgpOworICAgICAgICBzbGljZS5vcmRlcihieXRlQnVmZmVyLm9yZGVyKCkpOworICAgICAgICByZXR1cm4gbmV3IENoYXJUb0J5dGVCdWZmZXJBZGFwdGVyKHNsaWNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIENoYXJUb0J5dGVCdWZmZXJBZGFwdGVyKEJ5dGVCdWZmZXIgYnl0ZUJ1ZmZlcikgeworICAgICAgICBzdXBlcihieXRlQnVmZmVyLmNhcGFjaXR5KCkgLyBTaXplT2YuQ0hBUik7CisgICAgICAgIHRoaXMuYnl0ZUJ1ZmZlciA9IGJ5dGVCdWZmZXI7CisgICAgICAgIHRoaXMuYnl0ZUJ1ZmZlci5jbGVhcigpOworICAgICAgICB0aGlzLmVmZmVjdGl2ZURpcmVjdEFkZHJlc3MgPSBieXRlQnVmZmVyLmVmZmVjdGl2ZURpcmVjdEFkZHJlc3M7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENoYXJCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpIHsKKyAgICAgICAgQ2hhclRvQnl0ZUJ1ZmZlckFkYXB0ZXIgYnVmID0gbmV3IENoYXJUb0J5dGVCdWZmZXJBZGFwdGVyKGJ5dGVCdWZmZXIuYXNSZWFkT25seUJ1ZmZlcigpKTsKKyAgICAgICAgYnVmLmxpbWl0ID0gbGltaXQ7CisgICAgICAgIGJ1Zi5wb3NpdGlvbiA9IHBvc2l0aW9uOworICAgICAgICBidWYubWFyayA9IG1hcms7CisgICAgICAgIGJ1Zi5ieXRlQnVmZmVyLm9yZGVyID0gYnl0ZUJ1ZmZlci5vcmRlcjsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ2hhckJ1ZmZlciBjb21wYWN0KCkgeworICAgICAgICBpZiAoYnl0ZUJ1ZmZlci5pc1JlYWRPbmx5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGJ5dGVCdWZmZXIubGltaXQobGltaXQgKiBTaXplT2YuQ0hBUik7CisgICAgICAgIGJ5dGVCdWZmZXIucG9zaXRpb24ocG9zaXRpb24gKiBTaXplT2YuQ0hBUik7CisgICAgICAgIGJ5dGVCdWZmZXIuY29tcGFjdCgpOworICAgICAgICBieXRlQnVmZmVyLmNsZWFyKCk7CisgICAgICAgIHBvc2l0aW9uID0gbGltaXQgLSBwb3NpdGlvbjsKKyAgICAgICAgbGltaXQgPSBjYXBhY2l0eTsKKyAgICAgICAgbWFyayA9IFVOU0VUX01BUks7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDaGFyQnVmZmVyIGR1cGxpY2F0ZSgpIHsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYiA9IGJ5dGVCdWZmZXIuZHVwbGljYXRlKCkub3JkZXIoYnl0ZUJ1ZmZlci5vcmRlcigpKTsKKyAgICAgICAgQ2hhclRvQnl0ZUJ1ZmZlckFkYXB0ZXIgYnVmID0gbmV3IENoYXJUb0J5dGVCdWZmZXJBZGFwdGVyKGJiKTsKKyAgICAgICAgYnVmLmxpbWl0ID0gbGltaXQ7CisgICAgICAgIGJ1Zi5wb3NpdGlvbiA9IHBvc2l0aW9uOworICAgICAgICBidWYubWFyayA9IG1hcms7CisgICAgICAgIHJldHVybiBidWY7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGNoYXIgZ2V0KCkgeworICAgICAgICBpZiAocG9zaXRpb24gPT0gbGltaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnl0ZUJ1ZmZlci5nZXRDaGFyKHBvc2l0aW9uKysgKiBTaXplT2YuQ0hBUik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGNoYXIgZ2V0KGludCBpbmRleCkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4KTsKKyAgICAgICAgcmV0dXJuIGJ5dGVCdWZmZXIuZ2V0Q2hhcihpbmRleCAqIFNpemVPZi5DSEFSKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ2hhckJ1ZmZlciBnZXQoY2hhcltdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGNoYXJDb3VudCkgeworICAgICAgICBieXRlQnVmZmVyLmxpbWl0KGxpbWl0ICogU2l6ZU9mLkNIQVIpOworICAgICAgICBieXRlQnVmZmVyLnBvc2l0aW9uKHBvc2l0aW9uICogU2l6ZU9mLkNIQVIpOworICAgICAgICBpZiAoYnl0ZUJ1ZmZlciBpbnN0YW5jZW9mIERpcmVjdEJ5dGVCdWZmZXIpIHsKKyAgICAgICAgICAgICgoRGlyZWN0Qnl0ZUJ1ZmZlcikgYnl0ZUJ1ZmZlcikuZ2V0KGRzdCwgZHN0T2Zmc2V0LCBjaGFyQ291bnQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgKChIZWFwQnl0ZUJ1ZmZlcikgYnl0ZUJ1ZmZlcikuZ2V0KGRzdCwgZHN0T2Zmc2V0LCBjaGFyQ291bnQpOworICAgICAgICB9CisgICAgICAgIHRoaXMucG9zaXRpb24gKz0gY2hhckNvdW50OworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdCgpIHsKKyAgICAgICAgcmV0dXJuIGJ5dGVCdWZmZXIuaXNEaXJlY3QoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1JlYWRPbmx5KCkgeworICAgICAgICByZXR1cm4gYnl0ZUJ1ZmZlci5pc1JlYWRPbmx5KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVPcmRlciBvcmRlcigpIHsKKyAgICAgICAgcmV0dXJuIGJ5dGVCdWZmZXIub3JkZXIoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgY2hhcltdIHByb3RlY3RlZEFycmF5KCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IHByb3RlY3RlZEFycmF5T2Zmc2V0KCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwcm90ZWN0ZWRIYXNBcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDaGFyQnVmZmVyIHB1dChjaGFyIGMpIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBieXRlQnVmZmVyLnB1dENoYXIocG9zaXRpb24rKyAqIFNpemVPZi5DSEFSLCBjKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENoYXJCdWZmZXIgcHV0KGludCBpbmRleCwgY2hhciBjKSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICBieXRlQnVmZmVyLnB1dENoYXIoaW5kZXggKiBTaXplT2YuQ0hBUiwgYyk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDaGFyQnVmZmVyIHB1dChjaGFyW10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgY2hhckNvdW50KSB7CisgICAgICAgIGJ5dGVCdWZmZXIubGltaXQobGltaXQgKiBTaXplT2YuQ0hBUik7CisgICAgICAgIGJ5dGVCdWZmZXIucG9zaXRpb24ocG9zaXRpb24gKiBTaXplT2YuQ0hBUik7CisgICAgICAgIGlmIChieXRlQnVmZmVyIGluc3RhbmNlb2YgUmVhZFdyaXRlRGlyZWN0Qnl0ZUJ1ZmZlcikgeworICAgICAgICAgICAgKChSZWFkV3JpdGVEaXJlY3RCeXRlQnVmZmVyKSBieXRlQnVmZmVyKS5wdXQoc3JjLCBzcmNPZmZzZXQsIGNoYXJDb3VudCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAoKFJlYWRXcml0ZUhlYXBCeXRlQnVmZmVyKSBieXRlQnVmZmVyKS5wdXQoc3JjLCBzcmNPZmZzZXQsIGNoYXJDb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5wb3NpdGlvbiArPSBjaGFyQ291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDaGFyQnVmZmVyIHNsaWNlKCkgeworICAgICAgICBieXRlQnVmZmVyLmxpbWl0KGxpbWl0ICogU2l6ZU9mLkNIQVIpOworICAgICAgICBieXRlQnVmZmVyLnBvc2l0aW9uKHBvc2l0aW9uICogU2l6ZU9mLkNIQVIpOworICAgICAgICBCeXRlQnVmZmVyIGJiID0gYnl0ZUJ1ZmZlci5zbGljZSgpLm9yZGVyKGJ5dGVCdWZmZXIub3JkZXIoKSk7CisgICAgICAgIENoYXJCdWZmZXIgcmVzdWx0ID0gbmV3IENoYXJUb0J5dGVCdWZmZXJBZGFwdGVyKGJiKTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5jbGVhcigpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDaGFyU2VxdWVuY2Ugc3ViU2VxdWVuY2UoaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIGNoZWNrU3RhcnRFbmRSZW1haW5pbmcoc3RhcnQsIGVuZCk7CisgICAgICAgIENoYXJCdWZmZXIgcmVzdWx0ID0gZHVwbGljYXRlKCk7CisgICAgICAgIHJlc3VsdC5saW1pdChwb3NpdGlvbiArIGVuZCk7CisgICAgICAgIHJlc3VsdC5wb3NpdGlvbihwb3NpdGlvbiArIHN0YXJ0KTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vRGF0YWdyYW1DaGFubmVsSW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0RhdGFncmFtQ2hhbm5lbEltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMGUwNjRkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0RhdGFncmFtQ2hhbm5lbEltcGwuamF2YQpAQCAtMCwwICsxLDU5OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworaW1wb3J0IGphdmEuaW8uRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkludGVycnVwdGVkSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuQ29ubmVjdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5EYXRhZ3JhbVBhY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldEltcGw7CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuUGxhaW5EYXRhZ3JhbVNvY2tldEltcGw7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuQWxyZWFkeUNvbm5lY3RlZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5DbG9zZWRDaGFubmVsRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkRhdGFncmFtQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5JbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLk5vdFlldENvbm5lY3RlZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5zcGkuU2VsZWN0b3JQcm92aWRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGxpYmNvcmUuaW8uRXJybm9FeGNlcHRpb247CitpbXBvcnQgbGliY29yZS5pby5Jb0JyaWRnZTsKK2ltcG9ydCBsaWJjb3JlLmlvLklvVXRpbHM7CitpbXBvcnQgbGliY29yZS5pby5MaWJjb3JlOworaW1wb3J0IGxpYmNvcmUudXRpbC5FbXB0eUFycmF5OworCisvKgorICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gY2xhc3Mgb2YgamF2YS5uaW8uY2hhbm5lbHMuRGF0YWdyYW1DaGFubmVsLgorICovCitjbGFzcyBEYXRhZ3JhbUNoYW5uZWxJbXBsIGV4dGVuZHMgRGF0YWdyYW1DaGFubmVsIGltcGxlbWVudHMgRmlsZURlc2NyaXB0b3JDaGFubmVsIHsKKyAgICAvLyBUaGUgZmQgdG8gaW50ZXJhY3Qgd2l0aCBuYXRpdmUgY29kZQorICAgIHByaXZhdGUgZmluYWwgRmlsZURlc2NyaXB0b3IgZmQ7CisKKyAgICAvLyBPdXIgaW50ZXJuYWwgRGF0YWdyYW1Tb2NrZXQuCisgICAgcHJpdmF0ZSBEYXRhZ3JhbVNvY2tldCBzb2NrZXQgPSBudWxsOworCisgICAgLy8gVGhlIGFkZHJlc3MgdG8gYmUgY29ubmVjdGVkLgorICAgIEluZXRTb2NrZXRBZGRyZXNzIGNvbm5lY3RBZGRyZXNzID0gbnVsbDsKKworICAgIC8vIGxvY2FsIHBvcnQKKyAgICBwcml2YXRlIGludCBsb2NhbFBvcnQ7CisKKyAgICAvLyBBdCBmaXJzdCwgdW5pbml0aWFsaXplZC4KKyAgICBib29sZWFuIGNvbm5lY3RlZCA9IGZhbHNlOworCisgICAgLy8gd2hldGhlciB0aGUgc29ja2V0IGlzIGJvdW5kCisgICAgYm9vbGVhbiBpc0JvdW5kID0gZmFsc2U7CisKKyAgICBwcml2YXRlIGZpbmFsIE9iamVjdCByZWFkTG9jayA9IG5ldyBPYmplY3QoKTsKKyAgICBwcml2YXRlIGZpbmFsIE9iamVjdCB3cml0ZUxvY2sgPSBuZXcgT2JqZWN0KCk7CisKKyAgICAvKgorICAgICAqIENvbnN0cnVjdG9yCisgICAgICovCisgICAgcHJvdGVjdGVkIERhdGFncmFtQ2hhbm5lbEltcGwoU2VsZWN0b3JQcm92aWRlciBzZWxlY3RvclByb3ZpZGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihzZWxlY3RvclByb3ZpZGVyKTsKKyAgICAgICAgZmQgPSBJb0JyaWRnZS5zb2NrZXQoZmFsc2UpOworICAgIH0KKworICAgIC8qCisgICAgICogZm9yIG5hdGl2ZSBjYWxsCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgICAgcHJpdmF0ZSBEYXRhZ3JhbUNoYW5uZWxJbXBsKCkgeworICAgICAgICBzdXBlcihTZWxlY3RvclByb3ZpZGVyLnByb3ZpZGVyKCkpOworICAgICAgICBmZCA9IG5ldyBGaWxlRGVzY3JpcHRvcigpOworICAgICAgICBjb25uZWN0QWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcygwKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEdldHRpbmcgdGhlIGludGVybmFsIERhdGFncmFtU29ja2V0IElmIHdlIGhhdmUgbm90IHRoZSBzb2NrZXQsIHdlIGNyZWF0ZQorICAgICAqIGEgbmV3IG9uZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBzeW5jaHJvbml6ZWQgcHVibGljIERhdGFncmFtU29ja2V0IHNvY2tldCgpIHsKKyAgICAgICAgaWYgKHNvY2tldCA9PSBudWxsKSB7CisgICAgICAgICAgICBzb2NrZXQgPSBuZXcgRGF0YWdyYW1Tb2NrZXRBZGFwdGVyKG5ldyBQbGFpbkRhdGFncmFtU29ja2V0SW1wbChmZCwgbG9jYWxQb3J0KSwgdGhpcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNvY2tldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBhZGRyZXNzIHRvIHdoaWNoIHRoZSBzb2NrZXQgaXMgYm91bmQuCisgICAgICovCisgICAgSW5ldEFkZHJlc3MgZ2V0TG9jYWxBZGRyZXNzKCkgeworICAgICAgICByZXR1cm4gSW9CcmlkZ2UuZ2V0U29ja2V0TG9jYWxBZGRyZXNzKGZkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEubmlvLmNoYW5uZWxzLkRhdGFncmFtQ2hhbm5lbCNpc0Nvbm5lY3RlZCgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgc3luY2hyb25pemVkIHB1YmxpYyBib29sZWFuIGlzQ29ubmVjdGVkKCkgeworICAgICAgICByZXR1cm4gY29ubmVjdGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5uaW8uY2hhbm5lbHMuRGF0YWdyYW1DaGFubmVsI2Nvbm5lY3QoamF2YS5uZXQuU29ja2V0QWRkcmVzcykKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBzeW5jaHJvbml6ZWQgcHVibGljIERhdGFncmFtQ2hhbm5lbCBjb25uZWN0KFNvY2tldEFkZHJlc3MgYWRkcmVzcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gbXVzdCBvcGVuCisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICAvLyBzdGF0dXMgbXVzdCBiZSB1bi1jb25uZWN0ZWQuCisgICAgICAgIGlmIChjb25uZWN0ZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNoZWNrIHRoZSBhZGRyZXNzCisgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIGluZXRTb2NrZXRBZGRyZXNzID0gU29ja2V0Q2hhbm5lbEltcGwudmFsaWRhdGVBZGRyZXNzKGFkZHJlc3MpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmVnaW4oKTsKKyAgICAgICAgICAgIElvQnJpZGdlLmNvbm5lY3QoZmQsIGluZXRTb2NrZXRBZGRyZXNzLmdldEFkZHJlc3MoKSwgaW5ldFNvY2tldEFkZHJlc3MuZ2V0UG9ydCgpKTsKKyAgICAgICAgfSBjYXRjaCAoQ29ubmVjdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb25uZWN0RXhjZXB0aW9uIG1lYW5zIGNvbm5lY3QgZmFpbCwgbm90IGV4Y2VwdGlvbgorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZW5kKHRydWUpOworICAgICAgICB9CisKKyAgICAgICAgLy8gc2V0IHRoZSBjb25uZWN0ZWQgYWRkcmVzcy4KKyAgICAgICAgY29ubmVjdEFkZHJlc3MgPSBpbmV0U29ja2V0QWRkcmVzczsKKyAgICAgICAgY29ubmVjdGVkID0gdHJ1ZTsKKyAgICAgICAgaXNCb3VuZCA9IHRydWU7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5uaW8uY2hhbm5lbHMuRGF0YWdyYW1DaGFubmVsI2Rpc2Nvbm5lY3QoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHN5bmNocm9uaXplZCBwdWJsaWMgRGF0YWdyYW1DaGFubmVsIGRpc2Nvbm5lY3QoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIWlzQ29ubmVjdGVkKCkgfHwgIWlzT3BlbigpKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgfQorICAgICAgICBjb25uZWN0ZWQgPSBmYWxzZTsKKyAgICAgICAgY29ubmVjdEFkZHJlc3MgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgTGliY29yZS5vcy5jb25uZWN0KGZkLCBJbmV0QWRkcmVzcy5VTlNQRUNJRklFRCwgMCk7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyBlcnJub0V4Y2VwdGlvbi5yZXRocm93QXNJT0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChzb2NrZXQgIT0gbnVsbCkgeworICAgICAgICAgICAgc29ja2V0LmRpc2Nvbm5lY3QoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU29ja2V0QWRkcmVzcyByZWNlaXZlKEJ5dGVCdWZmZXIgdGFyZ2V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0YXJnZXQuY2hlY2tXcml0YWJsZSgpOworICAgICAgICBjaGVja09wZW4oKTsKKworICAgICAgICBpZiAoIWlzQm91bmQpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgU29ja2V0QWRkcmVzcyByZXRBZGRyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJlZ2luKCk7CisKKyAgICAgICAgICAgIC8vIHJlY2VpdmUgcmVhbCBkYXRhIHBhY2tldCwgKG5vdCBwZWVrKQorICAgICAgICAgICAgc3luY2hyb25pemVkIChyZWFkTG9jaykgeworICAgICAgICAgICAgICAgIGJvb2xlYW4gbG9vcCA9IGlzQmxvY2tpbmcoKTsKKyAgICAgICAgICAgICAgICBpZiAoIXRhcmdldC5pc0RpcmVjdCgpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldEFkZHIgPSByZWNlaXZlSW1wbCh0YXJnZXQsIGxvb3ApOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHJldEFkZHIgPSByZWNlaXZlRGlyZWN0SW1wbCh0YXJnZXQsIGxvb3ApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyB0aGlzIGxpbmUgdXNlZCBpbiBMaW51eAorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBlbmQocmV0QWRkciAhPSBudWxsKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmV0QWRkcjsKKyAgICB9CisKKyAgICBwcml2YXRlIFNvY2tldEFkZHJlc3MgcmVjZWl2ZUltcGwoQnl0ZUJ1ZmZlciB0YXJnZXQsIGJvb2xlYW4gbG9vcCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU29ja2V0QWRkcmVzcyByZXRBZGRyID0gbnVsbDsKKyAgICAgICAgRGF0YWdyYW1QYWNrZXQgcmVjZWl2ZVBhY2tldDsKKyAgICAgICAgaW50IG9sZHBvc2l0aW9uID0gdGFyZ2V0LnBvc2l0aW9uKCk7CisgICAgICAgIGludCByZWNlaXZlZCA9IDA7CisgICAgICAgIC8vIFRPRE86IGRpc2FsbG93IG1hcHBlZCBidWZmZXJzIGFuZCBsb3NlIHRoaXMgY29uZGl0aW9uYWw/CisgICAgICAgIGlmICh0YXJnZXQuaGFzQXJyYXkoKSkgeworICAgICAgICAgICAgcmVjZWl2ZVBhY2tldCA9IG5ldyBEYXRhZ3JhbVBhY2tldCh0YXJnZXQuYXJyYXkoKSwgdGFyZ2V0LnBvc2l0aW9uKCkgKyB0YXJnZXQuYXJyYXlPZmZzZXQoKSwgdGFyZ2V0LnJlbWFpbmluZygpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlY2VpdmVQYWNrZXQgPSBuZXcgRGF0YWdyYW1QYWNrZXQobmV3IGJ5dGVbdGFyZ2V0LnJlbWFpbmluZygpXSwgdGFyZ2V0LnJlbWFpbmluZygpKTsKKyAgICAgICAgfQorICAgICAgICBkbyB7CisgICAgICAgICAgICByZWNlaXZlZCA9IElvQnJpZGdlLnJlY3Zmcm9tKGZhbHNlLCBmZCwgcmVjZWl2ZVBhY2tldC5nZXREYXRhKCksIHJlY2VpdmVQYWNrZXQuZ2V0T2Zmc2V0KCksIHJlY2VpdmVQYWNrZXQuZ2V0TGVuZ3RoKCksIDAsIHJlY2VpdmVQYWNrZXQsIGlzQ29ubmVjdGVkKCkpOworICAgICAgICAgICAgaWYgKHJlY2VpdmVQYWNrZXQgIT0gbnVsbCAmJiByZWNlaXZlUGFja2V0LmdldEFkZHJlc3MoKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWYgKHJlY2VpdmVkID4gMCkgeworICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0Lmhhc0FycmF5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldC5wb3NpdGlvbihvbGRwb3NpdGlvbiArIHJlY2VpdmVkKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvcHkgdGhlIGRhdGEgb2YgcmVjZWl2ZWQgcGFja2V0CisgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQucHV0KHJlY2VpdmVQYWNrZXQuZ2V0RGF0YSgpLCAwLCByZWNlaXZlZCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0QWRkciA9IHJlY2VpdmVQYWNrZXQuZ2V0U29ja2V0QWRkcmVzcygpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9IHdoaWxlIChsb29wKTsKKyAgICAgICAgcmV0dXJuIHJldEFkZHI7CisgICAgfQorCisgICAgcHJpdmF0ZSBTb2NrZXRBZGRyZXNzIHJlY2VpdmVEaXJlY3RJbXBsKEJ5dGVCdWZmZXIgdGFyZ2V0LCBib29sZWFuIGxvb3ApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFNvY2tldEFkZHJlc3MgcmV0QWRkciA9IG51bGw7CisgICAgICAgIERhdGFncmFtUGFja2V0IHJlY2VpdmVQYWNrZXQgPSBuZXcgRGF0YWdyYW1QYWNrZXQoRW1wdHlBcnJheS5CWVRFLCAwKTsKKyAgICAgICAgaW50IG9sZHBvc2l0aW9uID0gdGFyZ2V0LnBvc2l0aW9uKCk7CisgICAgICAgIGludCByZWNlaXZlZCA9IDA7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIHJlY2VpdmVkID0gSW9CcmlkZ2UucmVjdmZyb20oZmFsc2UsIGZkLCB0YXJnZXQsIDAsIHJlY2VpdmVQYWNrZXQsIGlzQ29ubmVjdGVkKCkpOworICAgICAgICAgICAgaWYgKHJlY2VpdmVQYWNrZXQgIT0gbnVsbCAmJiByZWNlaXZlUGFja2V0LmdldEFkZHJlc3MoKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgLy8gY29weSB0aGUgZGF0YSBvZiByZWNlaXZlZCBwYWNrZXQKKyAgICAgICAgICAgICAgICBpZiAocmVjZWl2ZWQgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIHRhcmdldC5wb3NpdGlvbihvbGRwb3NpdGlvbiArIHJlY2VpdmVkKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0QWRkciA9IHJlY2VpdmVQYWNrZXQuZ2V0U29ja2V0QWRkcmVzcygpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9IHdoaWxlIChsb29wKTsKKyAgICAgICAgcmV0dXJuIHJldEFkZHI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBzZW5kKEJ5dGVCdWZmZXIgc291cmNlLCBTb2NrZXRBZGRyZXNzIHNvY2tldEFkZHJlc3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrTm90TnVsbChzb3VyY2UpOworICAgICAgICBjaGVja09wZW4oKTsKKworICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBpc2EgPSAoSW5ldFNvY2tldEFkZHJlc3MpIHNvY2tldEFkZHJlc3M7CisgICAgICAgIGlmIChpc2EuZ2V0QWRkcmVzcygpID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGlzQ29ubmVjdGVkKCkgJiYgIWNvbm5lY3RBZGRyZXNzLmVxdWFscyhpc2EpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBzeW5jaHJvbml6ZWQgKHdyaXRlTG9jaykgeworICAgICAgICAgICAgaW50IHNlbmRDb3VudCA9IDA7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGJlZ2luKCk7CisgICAgICAgICAgICAgICAgaW50IG9sZFBvc2l0aW9uID0gc291cmNlLnBvc2l0aW9uKCk7CisgICAgICAgICAgICAgICAgc2VuZENvdW50ID0gSW9CcmlkZ2Uuc2VuZHRvKGZkLCBzb3VyY2UsIDAsIGlzYS5nZXRBZGRyZXNzKCksIGlzYS5nZXRQb3J0KCkpOworICAgICAgICAgICAgICAgIGlmIChzZW5kQ291bnQgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIHNvdXJjZS5wb3NpdGlvbihvbGRQb3NpdGlvbiArIHNlbmRDb3VudCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBlbmQoc2VuZENvdW50ID49IDApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHNlbmRDb3VudDsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChCeXRlQnVmZmVyIHRhcmdldCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGFyZ2V0LmNoZWNrV3JpdGFibGUoKTsKKyAgICAgICAgY2hlY2tPcGVuQ29ubmVjdGVkKCk7CisKKyAgICAgICAgaWYgKCF0YXJnZXQuaGFzUmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgaW50IHJlYWRDb3VudCA9IDA7CisgICAgICAgIGlmICh0YXJnZXQuaXNEaXJlY3QoKSB8fCB0YXJnZXQuaGFzQXJyYXkoKSkgeworICAgICAgICAgICAgcmVhZENvdW50ID0gcmVhZEltcGwodGFyZ2V0KTsKKyAgICAgICAgICAgIGlmIChyZWFkQ291bnQgPiAwKSB7CisgICAgICAgICAgICAgICAgdGFyZ2V0LnBvc2l0aW9uKHRhcmdldC5wb3NpdGlvbigpICsgcmVhZENvdW50KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYnl0ZVtdIHJlYWRBcnJheSA9IG5ldyBieXRlW3RhcmdldC5yZW1haW5pbmcoKV07CisgICAgICAgICAgICBCeXRlQnVmZmVyIHJlYWRCdWZmZXIgPSBCeXRlQnVmZmVyLndyYXAocmVhZEFycmF5KTsKKyAgICAgICAgICAgIHJlYWRDb3VudCA9IHJlYWRJbXBsKHJlYWRCdWZmZXIpOworICAgICAgICAgICAgaWYgKHJlYWRDb3VudCA+IDApIHsKKyAgICAgICAgICAgICAgICB0YXJnZXQucHV0KHJlYWRBcnJheSwgMCwgcmVhZENvdW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVhZENvdW50OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIHJlYWQoQnl0ZUJ1ZmZlcltdIHRhcmdldHMsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KHRhcmdldHMubGVuZ3RoLCBvZmZzZXQsIGxlbmd0aCk7CisKKyAgICAgICAgLy8gc3RhdHVzIG11c3QgYmUgb3BlbiBhbmQgY29ubmVjdGVkCisgICAgICAgIGNoZWNrT3BlbkNvbm5lY3RlZCgpOworICAgICAgICBpbnQgdG90YWxDb3VudCA9IEZpbGVDaGFubmVsSW1wbC5jYWxjdWxhdGVUb3RhbFJlbWFpbmluZyh0YXJnZXRzLCBvZmZzZXQsIGxlbmd0aCwgdHJ1ZSk7CisgICAgICAgIGlmICh0b3RhbENvdW50ID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgLy8gcmVhZCBkYXRhIHRvIHJlYWRCdWZmZXIsIGFuZCB0aGVuIHRyYW5zZmVyIGRhdGEgZnJvbSByZWFkQnVmZmVyIHRvCisgICAgICAgIC8vIHRhcmdldHMuCisgICAgICAgIEJ5dGVCdWZmZXIgcmVhZEJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUodG90YWxDb3VudCk7CisgICAgICAgIGludCByZWFkQ291bnQ7CisgICAgICAgIHJlYWRDb3VudCA9IHJlYWRJbXBsKHJlYWRCdWZmZXIpOworICAgICAgICBpbnQgbGVmdCA9IHJlYWRDb3VudDsKKyAgICAgICAgaW50IGluZGV4ID0gb2Zmc2V0OworICAgICAgICAvLyB0cmFuc2ZlciBkYXRhIGZyb20gcmVhZEJ1ZmZlciB0byB0YXJnZXRzCisgICAgICAgIGJ5dGVbXSByZWFkQXJyYXkgPSByZWFkQnVmZmVyLmFycmF5KCk7CisgICAgICAgIHdoaWxlIChsZWZ0ID4gMCkgeworICAgICAgICAgICAgaW50IHB1dExlbmd0aCA9IE1hdGgubWluKHRhcmdldHNbaW5kZXhdLnJlbWFpbmluZygpLCBsZWZ0KTsKKyAgICAgICAgICAgIHRhcmdldHNbaW5kZXhdLnB1dChyZWFkQXJyYXksIHJlYWRDb3VudCAtIGxlZnQsIHB1dExlbmd0aCk7CisgICAgICAgICAgICBpbmRleCsrOworICAgICAgICAgICAgbGVmdCAtPSBwdXRMZW5ndGg7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlYWRDb3VudDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIHJlYWQgZnJvbSBjaGFubmVsLCBhbmQgc3RvcmUgdGhlIHJlc3VsdCBpbiB0aGUgdGFyZ2V0LgorICAgICAqLworICAgIHByaXZhdGUgaW50IHJlYWRJbXBsKEJ5dGVCdWZmZXIgZHN0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKHJlYWRMb2NrKSB7CisgICAgICAgICAgICBpbnQgcmVhZENvdW50ID0gMDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYmVnaW4oKTsKKyAgICAgICAgICAgICAgICByZWFkQ291bnQgPSBJb0JyaWRnZS5yZWN2ZnJvbShmYWxzZSwgZmQsIGRzdCwgMCwgbnVsbCwgaXNDb25uZWN0ZWQoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBJbnRlcnJ1cHRlZElPRXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duIHdoZW4gdGltZW91dC4KKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgZW5kKHJlYWRDb3VudCA+IDApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJlYWRDb3VudDsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHdyaXRlKEJ5dGVCdWZmZXIgc3JjKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja05vdE51bGwoc3JjKTsKKyAgICAgICAgY2hlY2tPcGVuQ29ubmVjdGVkKCk7CisgICAgICAgIGlmICghc3JjLmhhc1JlbWFpbmluZygpKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIGludCB3cml0ZUNvdW50ID0gd3JpdGVJbXBsKHNyYyk7CisgICAgICAgIGlmICh3cml0ZUNvdW50ID4gMCkgeworICAgICAgICAgICAgc3JjLnBvc2l0aW9uKHNyYy5wb3NpdGlvbigpICsgd3JpdGVDb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHdyaXRlQ291bnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLm5pby5jaGFubmVscy5EYXRhZ3JhbUNoYW5uZWwjd3JpdGUoamF2YS5uaW8uQnl0ZUJ1ZmZlcltdLCBpbnQsCisgICAgICogICAgICBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgd3JpdGUoQnl0ZUJ1ZmZlcltdIHNvdXJjZXMsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KHNvdXJjZXMubGVuZ3RoLCBvZmZzZXQsIGxlbmd0aCk7CisKKyAgICAgICAgLy8gc3RhdHVzIG11c3QgYmUgb3BlbiBhbmQgY29ubmVjdGVkCisgICAgICAgIGNoZWNrT3BlbkNvbm5lY3RlZCgpOworICAgICAgICBpbnQgY291bnQgPSBGaWxlQ2hhbm5lbEltcGwuY2FsY3VsYXRlVG90YWxSZW1haW5pbmcoc291cmNlcywgb2Zmc2V0LCBsZW5ndGgsIGZhbHNlKTsKKyAgICAgICAgaWYgKGNvdW50ID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIEJ5dGVCdWZmZXIgd3JpdGVCdWYgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKGNvdW50KTsKKyAgICAgICAgZm9yIChpbnQgdmFsID0gb2Zmc2V0OyB2YWwgPCBsZW5ndGggKyBvZmZzZXQ7IHZhbCsrKSB7CisgICAgICAgICAgICBCeXRlQnVmZmVyIHNvdXJjZSA9IHNvdXJjZXNbdmFsXTsKKyAgICAgICAgICAgIGludCBvbGRQb3NpdGlvbiA9IHNvdXJjZS5wb3NpdGlvbigpOworICAgICAgICAgICAgd3JpdGVCdWYucHV0KHNvdXJjZSk7CisgICAgICAgICAgICBzb3VyY2UucG9zaXRpb24ob2xkUG9zaXRpb24pOworICAgICAgICB9CisgICAgICAgIHdyaXRlQnVmLmZsaXAoKTsKKyAgICAgICAgaW50IHJlc3VsdCA9IHdyaXRlSW1wbCh3cml0ZUJ1Zik7CisgICAgICAgIGludCB2YWwgPSBvZmZzZXQ7CisgICAgICAgIGludCB3cml0dGVuID0gcmVzdWx0OworICAgICAgICB3aGlsZSAocmVzdWx0ID4gMCkgeworICAgICAgICAgICAgQnl0ZUJ1ZmZlciBzb3VyY2UgPSBzb3VyY2VzW3ZhbF07CisgICAgICAgICAgICBpbnQgZ2FwID0gTWF0aC5taW4ocmVzdWx0LCBzb3VyY2UucmVtYWluaW5nKCkpOworICAgICAgICAgICAgc291cmNlLnBvc2l0aW9uKHNvdXJjZS5wb3NpdGlvbigpICsgZ2FwKTsKKyAgICAgICAgICAgIHZhbCsrOworICAgICAgICAgICAgcmVzdWx0IC09IGdhcDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gd3JpdHRlbjsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCB3cml0ZUltcGwoQnl0ZUJ1ZmZlciBidWYpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAod3JpdGVMb2NrKSB7CisgICAgICAgICAgICBpbnQgcmVzdWx0ID0gMDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYmVnaW4oKTsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSBJb0JyaWRnZS5zZW5kdG8oZmQsIGJ1ZiwgMCwgbnVsbCwgMCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGVuZChyZXN1bHQgPiAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIGltcGxDbG9zZVNlbGVjdGFibGVDaGFubmVsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY29ubmVjdGVkID0gZmFsc2U7CisgICAgICAgIGlmIChzb2NrZXQgIT0gbnVsbCAmJiAhc29ja2V0LmlzQ2xvc2VkKCkpIHsKKyAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgSW9CcmlkZ2UuY2xvc2VTb2NrZXQoZmQpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGltcGxDb25maWd1cmVCbG9ja2luZyhib29sZWFuIGJsb2NraW5nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGJsb2NraW5nTG9jaygpKSB7CisgICAgICAgICAgICBJb1V0aWxzLnNldEJsb2NraW5nKGZkLCBibG9ja2luZyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFN0YXR1cyBjaGVjaywgbXVzdCBiZSBvcGVuLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjaGVja09wZW4oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIWlzT3BlbigpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBTdGF0dXMgY2hlY2ssIG11c3QgYmUgb3BlbiBhbmQgY29ubmVjdGVkLCBmb3IgcmVhZCBhbmQgd3JpdGUuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrT3BlbkNvbm5lY3RlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBpZiAoIWlzQ29ubmVjdGVkKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb3RZZXRDb25uZWN0ZWRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQnVmZmVyIGNoZWNrLCBtdXN0IG5vdCBudWxsCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrTm90TnVsbChCeXRlQnVmZmVyIHNvdXJjZSkgeworICAgICAgICBpZiAoc291cmNlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBHZXQgdGhlIGZkIGZvciBpbnRlcm5hbCB1c2UuCisgICAgICovCisgICAgcHVibGljIEZpbGVEZXNjcmlwdG9yIGdldEZEKCkgeworICAgICAgICByZXR1cm4gZmQ7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUaGUgYWRhcHRlciBjbGFzcyBvZiBEYXRhZ3JhbVNvY2tldAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIERhdGFncmFtU29ja2V0QWRhcHRlciBleHRlbmRzIERhdGFncmFtU29ja2V0IHsKKworICAgICAgICAvKgorICAgICAgICAgKiBUaGUgaW50ZXJuYWwgZGF0YWdyYW1DaGFubmVsSW1wbC4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgRGF0YWdyYW1DaGFubmVsSW1wbCBjaGFubmVsSW1wbDsKKworICAgICAgICAvKgorICAgICAgICAgKiBDb25zdHJ1Y3RvciBpbml0aWFsaXplIHRoZSBkYXRhZ3JhbVNvY2tldEltcGwgYW5kIGRhdGFncmFtQ2hhbm5lbEltcGwKKyAgICAgICAgICovCisgICAgICAgIERhdGFncmFtU29ja2V0QWRhcHRlcihEYXRhZ3JhbVNvY2tldEltcGwgc29ja2V0aW1wbCwKKyAgICAgICAgICAgICAgICBEYXRhZ3JhbUNoYW5uZWxJbXBsIGNoYW5uZWxJbXBsKSB7CisgICAgICAgICAgICBzdXBlcihzb2NrZXRpbXBsKTsKKyAgICAgICAgICAgIHRoaXMuY2hhbm5lbEltcGwgPSBjaGFubmVsSW1wbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIEdldCB0aGUgaW50ZXJuYWwgZGF0YWdyYW1DaGFubmVsSW1wbAorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBEYXRhZ3JhbUNoYW5uZWwgZ2V0Q2hhbm5lbCgpIHsKKyAgICAgICAgICAgIHJldHVybiBjaGFubmVsSW1wbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBAc2VlIGphdmEubmV0LkRhdGFncmFtU29ja2V0I2lzQm91bmQoKQorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzQm91bmQoKSB7CisgICAgICAgICAgICByZXR1cm4gY2hhbm5lbEltcGwuaXNCb3VuZDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBAc2VlIGphdmEubmV0LkRhdGFncmFtU29ja2V0I2lzQ29ubmVjdGVkKCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0Nvbm5lY3RlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBjaGFubmVsSW1wbC5pc0Nvbm5lY3RlZCgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEBzZWUgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQjZ2V0SW5ldEFkZHJlc3MoKQorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBJbmV0QWRkcmVzcyBnZXRJbmV0QWRkcmVzcygpIHsKKyAgICAgICAgICAgIGlmIChjaGFubmVsSW1wbC5jb25uZWN0QWRkcmVzcyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gY2hhbm5lbEltcGwuY29ubmVjdEFkZHJlc3MuZ2V0QWRkcmVzcygpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEBzZWUgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQjZ2V0TG9jYWxBZGRyZXNzKCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgSW5ldEFkZHJlc3MgZ2V0TG9jYWxBZGRyZXNzKCkgeworICAgICAgICAgICAgcmV0dXJuIGNoYW5uZWxJbXBsLmdldExvY2FsQWRkcmVzcygpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEBzZWUgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQjZ2V0UG9ydCgpCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBnZXRQb3J0KCkgeworICAgICAgICAgICAgaWYgKGNoYW5uZWxJbXBsLmNvbm5lY3RBZGRyZXNzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gY2hhbm5lbEltcGwuY29ubmVjdEFkZHJlc3MuZ2V0UG9ydCgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEBzZWUgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQjYmluZChqYXZhLm5ldC5Tb2NrZXRBZGRyZXNzKQorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGJpbmQoU29ja2V0QWRkcmVzcyBsb2NhbEFkZHIpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKGNoYW5uZWxJbXBsLmlzQ29ubmVjdGVkKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWxyZWFkeUNvbm5lY3RlZEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3VwZXIuYmluZChsb2NhbEFkZHIpOworICAgICAgICAgICAgY2hhbm5lbEltcGwuaXNCb3VuZCA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQHNlZSBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldCNyZWNlaXZlKGphdmEubmV0LkRhdGFncmFtUGFja2V0KQorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHJlY2VpdmUoRGF0YWdyYW1QYWNrZXQgcGFja2V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaWYgKCFjaGFubmVsSW1wbC5pc0Jsb2NraW5nKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3VwZXIucmVjZWl2ZShwYWNrZXQpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEBzZWUgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQjc2VuZChqYXZhLm5ldC5EYXRhZ3JhbVBhY2tldCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZW5kKERhdGFncmFtUGFja2V0IHBhY2tldCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmICghY2hhbm5lbEltcGwuaXNCbG9ja2luZygpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHN1cGVyLnNlbmQocGFja2V0KTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBAc2VlIGphdmEubmV0LkRhdGFncmFtU29ja2V0I2Nsb3NlKCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoY2hhbm5lbEltcGwpIHsKKyAgICAgICAgICAgICAgICBpZiAoY2hhbm5lbEltcGwuaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbXBsLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIElnbm9yZQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHN1cGVyLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQHNlZSBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldCNkaXNjb25uZWN0KCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBkaXNjb25uZWN0KCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjaGFubmVsSW1wbC5kaXNjb25uZWN0KCk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gSWdub3JlCisgICAgICAgICAgICB9CisgICAgICAgICAgICBzdXBlci5kaXNjb25uZWN0KCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vRGlyZWN0Qnl0ZUJ1ZmZlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0RpcmVjdEJ5dGVCdWZmZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jY2M1YzZiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0RpcmVjdEJ5dGVCdWZmZXIuamF2YQpAQCAtMCwwICsxLDIyNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworaW1wb3J0IGxpYmNvcmUuaW8uU2l6ZU9mOworCithYnN0cmFjdCBjbGFzcyBEaXJlY3RCeXRlQnVmZmVyIGV4dGVuZHMgQmFzZUJ5dGVCdWZmZXIgeworICAgIC8vIFRoaXMgaXMgdGhlIG9mZnNldCBpbnRvIHtAY29kZSBCdWZmZXIuYmxvY2t9IGF0IHdoaWNoIHRoaXMgYnVmZmVyIGxvZ2ljYWxseSBzdGFydHMuCisgICAgLy8gVE9ETzogcmV3cml0ZSB0aGlzIHNvIHdlIHNldCAnYmxvY2snIHRvIGFuIE9mZnNldE1lbW9yeUJsb2NrPworICAgIHByb3RlY3RlZCBmaW5hbCBpbnQgb2Zmc2V0OworCisgICAgcHJvdGVjdGVkIERpcmVjdEJ5dGVCdWZmZXIoTWVtb3J5QmxvY2sgYmxvY2ssIGludCBjYXBhY2l0eSwgaW50IG9mZnNldCkgeworICAgICAgICBzdXBlcihjYXBhY2l0eSwgYmxvY2spOworCisgICAgICAgIGxvbmcgYmFzZVNpemUgPSBibG9jay5nZXRTaXplKCk7CisgICAgICAgIGlmIChiYXNlU2l6ZSA+PSAwICYmIChjYXBhY2l0eSArIG9mZnNldCkgPiBiYXNlU2l6ZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiY2FwYWNpdHkgKyBvZmZzZXQgPiBiYXNlU2l6ZSIpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7CisgICAgICAgIHRoaXMuZWZmZWN0aXZlRGlyZWN0QWRkcmVzcyA9IGJsb2NrLnRvSW50KCkgKyBvZmZzZXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIEJ5dGVCdWZmZXIgZ2V0KGJ5dGVbXSBkc3QsIGludCBkc3RPZmZzZXQsIGludCBieXRlQ291bnQpIHsKKyAgICAgICAgY2hlY2tHZXRCb3VuZHMoMSwgZHN0Lmxlbmd0aCwgZHN0T2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICB0aGlzLmJsb2NrLnBlZWtCeXRlQXJyYXkob2Zmc2V0ICsgcG9zaXRpb24sIGRzdCwgZHN0T2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICBwb3NpdGlvbiArPSBieXRlQ291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIGZpbmFsIHZvaWQgZ2V0KGNoYXJbXSBkc3QsIGludCBkc3RPZmZzZXQsIGludCBjaGFyQ291bnQpIHsKKyAgICAgICAgaW50IGJ5dGVDb3VudCA9IGNoZWNrR2V0Qm91bmRzKFNpemVPZi5DSEFSLCBkc3QubGVuZ3RoLCBkc3RPZmZzZXQsIGNoYXJDb3VudCk7CisgICAgICAgIHRoaXMuYmxvY2sucGVla0NoYXJBcnJheShvZmZzZXQgKyBwb3NpdGlvbiwgZHN0LCBkc3RPZmZzZXQsIGNoYXJDb3VudCwgb3JkZXIubmVlZHNTd2FwKTsKKyAgICAgICAgcG9zaXRpb24gKz0gYnl0ZUNvdW50OworICAgIH0KKworICAgIGZpbmFsIHZvaWQgZ2V0KGRvdWJsZVtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGRvdWJsZUNvdW50KSB7CisgICAgICAgIGludCBieXRlQ291bnQgPSBjaGVja0dldEJvdW5kcyhTaXplT2YuRE9VQkxFLCBkc3QubGVuZ3RoLCBkc3RPZmZzZXQsIGRvdWJsZUNvdW50KTsKKyAgICAgICAgdGhpcy5ibG9jay5wZWVrRG91YmxlQXJyYXkob2Zmc2V0ICsgcG9zaXRpb24sIGRzdCwgZHN0T2Zmc2V0LCBkb3VibGVDb3VudCwgb3JkZXIubmVlZHNTd2FwKTsKKyAgICAgICAgcG9zaXRpb24gKz0gYnl0ZUNvdW50OworICAgIH0KKworICAgIGZpbmFsIHZvaWQgZ2V0KGZsb2F0W10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgZmxvYXRDb3VudCkgeworICAgICAgICBpbnQgYnl0ZUNvdW50ID0gY2hlY2tHZXRCb3VuZHMoU2l6ZU9mLkZMT0FULCBkc3QubGVuZ3RoLCBkc3RPZmZzZXQsIGZsb2F0Q291bnQpOworICAgICAgICB0aGlzLmJsb2NrLnBlZWtGbG9hdEFycmF5KG9mZnNldCArIHBvc2l0aW9uLCBkc3QsIGRzdE9mZnNldCwgZmxvYXRDb3VudCwgb3JkZXIubmVlZHNTd2FwKTsKKyAgICAgICAgcG9zaXRpb24gKz0gYnl0ZUNvdW50OworICAgIH0KKworICAgIGZpbmFsIHZvaWQgZ2V0KGludFtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGludENvdW50KSB7CisgICAgICAgIGludCBieXRlQ291bnQgPSBjaGVja0dldEJvdW5kcyhTaXplT2YuSU5ULCBkc3QubGVuZ3RoLCBkc3RPZmZzZXQsIGludENvdW50KTsKKyAgICAgICAgdGhpcy5ibG9jay5wZWVrSW50QXJyYXkob2Zmc2V0ICsgcG9zaXRpb24sIGRzdCwgZHN0T2Zmc2V0LCBpbnRDb3VudCwgb3JkZXIubmVlZHNTd2FwKTsKKyAgICAgICAgcG9zaXRpb24gKz0gYnl0ZUNvdW50OworICAgIH0KKworICAgIGZpbmFsIHZvaWQgZ2V0KGxvbmdbXSBkc3QsIGludCBkc3RPZmZzZXQsIGludCBsb25nQ291bnQpIHsKKyAgICAgICAgaW50IGJ5dGVDb3VudCA9IGNoZWNrR2V0Qm91bmRzKFNpemVPZi5MT05HLCBkc3QubGVuZ3RoLCBkc3RPZmZzZXQsIGxvbmdDb3VudCk7CisgICAgICAgIHRoaXMuYmxvY2sucGVla0xvbmdBcnJheShvZmZzZXQgKyBwb3NpdGlvbiwgZHN0LCBkc3RPZmZzZXQsIGxvbmdDb3VudCwgb3JkZXIubmVlZHNTd2FwKTsKKyAgICAgICAgcG9zaXRpb24gKz0gYnl0ZUNvdW50OworICAgIH0KKworICAgIGZpbmFsIHZvaWQgZ2V0KHNob3J0W10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgc2hvcnRDb3VudCkgeworICAgICAgICBpbnQgYnl0ZUNvdW50ID0gY2hlY2tHZXRCb3VuZHMoU2l6ZU9mLlNIT1JULCBkc3QubGVuZ3RoLCBkc3RPZmZzZXQsIHNob3J0Q291bnQpOworICAgICAgICB0aGlzLmJsb2NrLnBlZWtTaG9ydEFycmF5KG9mZnNldCArIHBvc2l0aW9uLCBkc3QsIGRzdE9mZnNldCwgc2hvcnRDb3VudCwgb3JkZXIubmVlZHNTd2FwKTsKKyAgICAgICAgcG9zaXRpb24gKz0gYnl0ZUNvdW50OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBieXRlIGdldCgpIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXMuYmxvY2sucGVla0J5dGUob2Zmc2V0ICsgcG9zaXRpb24rKyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGJ5dGUgZ2V0KGludCBpbmRleCkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4KTsKKyAgICAgICAgcmV0dXJuIHRoaXMuYmxvY2sucGVla0J5dGUob2Zmc2V0ICsgaW5kZXgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBjaGFyIGdldENoYXIoKSB7CisgICAgICAgIGludCBuZXdQb3NpdGlvbiA9IHBvc2l0aW9uICsgU2l6ZU9mLkNIQVI7CisgICAgICAgIGlmIChuZXdQb3NpdGlvbiA+IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgY2hhciByZXN1bHQgPSAoY2hhcikgdGhpcy5ibG9jay5wZWVrU2hvcnQob2Zmc2V0ICsgcG9zaXRpb24sIG9yZGVyKTsKKyAgICAgICAgcG9zaXRpb24gPSBuZXdQb3NpdGlvbjsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgY2hhciBnZXRDaGFyKGludCBpbmRleCkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4LCBTaXplT2YuQ0hBUik7CisgICAgICAgIHJldHVybiAoY2hhcikgdGhpcy5ibG9jay5wZWVrU2hvcnQob2Zmc2V0ICsgaW5kZXgsIG9yZGVyKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgZG91YmxlIGdldERvdWJsZSgpIHsKKyAgICAgICAgaW50IG5ld1Bvc2l0aW9uID0gcG9zaXRpb24gKyBTaXplT2YuRE9VQkxFOworICAgICAgICBpZiAobmV3UG9zaXRpb24gPiBsaW1pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGRvdWJsZSByZXN1bHQgPSBEb3VibGUubG9uZ0JpdHNUb0RvdWJsZSh0aGlzLmJsb2NrLnBlZWtMb25nKG9mZnNldCArIHBvc2l0aW9uLCBvcmRlcikpOworICAgICAgICBwb3NpdGlvbiA9IG5ld1Bvc2l0aW9uOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBkb3VibGUgZ2V0RG91YmxlKGludCBpbmRleCkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4LCBTaXplT2YuRE9VQkxFKTsKKyAgICAgICAgcmV0dXJuIERvdWJsZS5sb25nQml0c1RvRG91YmxlKHRoaXMuYmxvY2sucGVla0xvbmcob2Zmc2V0ICsgaW5kZXgsIG9yZGVyKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGZsb2F0IGdldEZsb2F0KCkgeworICAgICAgICBpbnQgbmV3UG9zaXRpb24gPSBwb3NpdGlvbiArIFNpemVPZi5GTE9BVDsKKyAgICAgICAgaWYgKG5ld1Bvc2l0aW9uID4gbGltaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBmbG9hdCByZXN1bHQgPSBGbG9hdC5pbnRCaXRzVG9GbG9hdCh0aGlzLmJsb2NrLnBlZWtJbnQob2Zmc2V0ICsgcG9zaXRpb24sIG9yZGVyKSk7CisgICAgICAgIHBvc2l0aW9uID0gbmV3UG9zaXRpb247CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGZsb2F0IGdldEZsb2F0KGludCBpbmRleCkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4LCBTaXplT2YuRkxPQVQpOworICAgICAgICByZXR1cm4gRmxvYXQuaW50Qml0c1RvRmxvYXQodGhpcy5ibG9jay5wZWVrSW50KG9mZnNldCArIGluZGV4LCBvcmRlcikpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0SW50KCkgeworICAgICAgICBpbnQgbmV3UG9zaXRpb24gPSBwb3NpdGlvbiArIFNpemVPZi5JTlQ7CisgICAgICAgIGlmIChuZXdQb3NpdGlvbiA+IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IHJlc3VsdCA9IHRoaXMuYmxvY2sucGVla0ludChvZmZzZXQgKyBwb3NpdGlvbiwgb3JkZXIpOworICAgICAgICBwb3NpdGlvbiA9IG5ld1Bvc2l0aW9uOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0SW50KGludCBpbmRleCkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4LCBTaXplT2YuSU5UKTsKKyAgICAgICAgcmV0dXJuIHRoaXMuYmxvY2sucGVla0ludChvZmZzZXQgKyBpbmRleCwgb3JkZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBsb25nIGdldExvbmcoKSB7CisgICAgICAgIGludCBuZXdQb3NpdGlvbiA9IHBvc2l0aW9uICsgU2l6ZU9mLkxPTkc7CisgICAgICAgIGlmIChuZXdQb3NpdGlvbiA+IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgbG9uZyByZXN1bHQgPSB0aGlzLmJsb2NrLnBlZWtMb25nKG9mZnNldCArIHBvc2l0aW9uLCBvcmRlcik7CisgICAgICAgIHBvc2l0aW9uID0gbmV3UG9zaXRpb247CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGxvbmcgZ2V0TG9uZyhpbnQgaW5kZXgpIHsKKyAgICAgICAgY2hlY2tJbmRleChpbmRleCwgU2l6ZU9mLkxPTkcpOworICAgICAgICByZXR1cm4gdGhpcy5ibG9jay5wZWVrTG9uZyhvZmZzZXQgKyBpbmRleCwgb3JkZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBzaG9ydCBnZXRTaG9ydCgpIHsKKyAgICAgICAgaW50IG5ld1Bvc2l0aW9uID0gcG9zaXRpb24gKyBTaXplT2YuU0hPUlQ7CisgICAgICAgIGlmIChuZXdQb3NpdGlvbiA+IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgc2hvcnQgcmVzdWx0ID0gdGhpcy5ibG9jay5wZWVrU2hvcnQob2Zmc2V0ICsgcG9zaXRpb24sIG9yZGVyKTsKKyAgICAgICAgcG9zaXRpb24gPSBuZXdQb3NpdGlvbjsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgc2hvcnQgZ2V0U2hvcnQoaW50IGluZGV4KSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgsIFNpemVPZi5TSE9SVCk7CisgICAgICAgIHJldHVybiB0aGlzLmJsb2NrLnBlZWtTaG9ydChvZmZzZXQgKyBpbmRleCwgb3JkZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzRGlyZWN0KCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBmcmVlKCkgeworICAgICAgICBibG9jay5mcmVlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBieXRlW10gcHJvdGVjdGVkQXJyYXkoKSB7CisgICAgICAgIGJ5dGVbXSBhcnJheSA9IHRoaXMuYmxvY2suYXJyYXkoKTsKKyAgICAgICAgaWYgKGFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBhcnJheTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIGludCBwcm90ZWN0ZWRBcnJheU9mZnNldCgpIHsKKyAgICAgICAgcHJvdGVjdGVkQXJyYXkoKTsgLy8gQ2hlY2sgd2UgaGF2ZSBhbiBhcnJheS4KKyAgICAgICAgcmV0dXJuIG9mZnNldDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIGJvb2xlYW4gcHJvdGVjdGVkSGFzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBwcm90ZWN0ZWRBcnJheSgpICE9IG51bGw7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0RvdWJsZUFycmF5QnVmZmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vRG91YmxlQXJyYXlCdWZmZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYzMyYTgwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0RvdWJsZUFycmF5QnVmZmVyLmphdmEKQEAgLTAsMCArMSw4NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworLyoqCisgKiBEb3VibGVBcnJheUJ1ZmZlciwgUmVhZFdyaXRlRG91YmxlQXJyYXlCdWZmZXIgYW5kIFJlYWRPbmx5RG91YmxlQXJyYXlCdWZmZXIKKyAqIGNvbXBvc2UgdGhlIGltcGxlbWVudGF0aW9uIG9mIGFycmF5IGJhc2VkIGRvdWJsZSBidWZmZXJzLgorICogPHA+CisgKiBEb3VibGVBcnJheUJ1ZmZlciBpbXBsZW1lbnRzIGFsbCB0aGUgc2hhcmVkIHJlYWRvbmx5IG1ldGhvZHMgYW5kIGlzIGV4dGVuZGVkCisgKiBieSB0aGUgb3RoZXIgdHdvIGNsYXNzZXMuCisgKiA8L3A+CisgKiA8cD4KKyAqIEFsbCBtZXRob2RzIGFyZSBtYXJrZWQgZmluYWwgZm9yIHJ1bnRpbWUgcGVyZm9ybWFuY2UuCisgKiA8L3A+CisgKgorICovCithYnN0cmFjdCBjbGFzcyBEb3VibGVBcnJheUJ1ZmZlciBleHRlbmRzIERvdWJsZUJ1ZmZlciB7CisKKyAgICBwcm90ZWN0ZWQgZmluYWwgZG91YmxlW10gYmFja2luZ0FycmF5OworCisgICAgcHJvdGVjdGVkIGZpbmFsIGludCBvZmZzZXQ7CisKKyAgICBEb3VibGVBcnJheUJ1ZmZlcihkb3VibGVbXSBhcnJheSkgeworICAgICAgICB0aGlzKGFycmF5Lmxlbmd0aCwgYXJyYXksIDApOworICAgIH0KKworICAgIERvdWJsZUFycmF5QnVmZmVyKGludCBjYXBhY2l0eSkgeworICAgICAgICB0aGlzKGNhcGFjaXR5LCBuZXcgZG91YmxlW2NhcGFjaXR5XSwgMCk7CisgICAgfQorCisgICAgRG91YmxlQXJyYXlCdWZmZXIoaW50IGNhcGFjaXR5LCBkb3VibGVbXSBiYWNraW5nQXJyYXksIGludCBvZmZzZXQpIHsKKyAgICAgICAgc3VwZXIoY2FwYWNpdHkpOworICAgICAgICB0aGlzLmJhY2tpbmdBcnJheSA9IGJhY2tpbmdBcnJheTsKKyAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGRvdWJsZSBnZXQoKSB7CisgICAgICAgIGlmIChwb3NpdGlvbiA9PSBsaW1pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBiYWNraW5nQXJyYXlbb2Zmc2V0ICsgcG9zaXRpb24rK107CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGRvdWJsZSBnZXQoaW50IGluZGV4KSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICByZXR1cm4gYmFja2luZ0FycmF5W29mZnNldCArIGluZGV4XTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgRG91YmxlQnVmZmVyIGdldChkb3VibGVbXSBkc3QsIGludCBkc3RPZmZzZXQsIGludCBkb3VibGVDb3VudCkgeworICAgICAgICBpZiAoZG91YmxlQ291bnQgPiByZW1haW5pbmcoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbiwgZHN0LCBkc3RPZmZzZXQsIGRvdWJsZUNvdW50KTsKKyAgICAgICAgcG9zaXRpb24gKz0gZG91YmxlQ291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzRGlyZWN0KCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIEJ5dGVPcmRlciBvcmRlcigpIHsKKyAgICAgICAgcmV0dXJuIEJ5dGVPcmRlci5uYXRpdmVPcmRlcigpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0RvdWJsZUJ1ZmZlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0RvdWJsZUJ1ZmZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM0OTU1OTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vRG91YmxlQnVmZmVyLmphdmEKQEAgLTAsMCArMSw0ODQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW87CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIEEgYnVmZmVyIG9mIGRvdWJsZXMuCisgKiA8cD4KKyAqIEEgZG91YmxlIGJ1ZmZlciBjYW4gYmUgY3JlYXRlZCBpbiBlaXRoZXIgb25lIG9mIHRoZSBmb2xsb3dpbmcgd2F5czoKKyAqIDx1bD4KKyAqIDxsaT57QGxpbmsgI2FsbG9jYXRlKGludCkgQWxsb2NhdGV9IGEgbmV3IGRvdWJsZSBhcnJheSBhbmQgY3JlYXRlIGEgYnVmZmVyCisgKiBiYXNlZCBvbiBpdDs8L2xpPgorICogPGxpPntAbGluayAjd3JhcChkb3VibGVbXSkgV3JhcH0gYW4gZXhpc3RpbmcgZG91YmxlIGFycmF5IHRvIGNyZWF0ZSBhIG5ldworICogYnVmZmVyOzwvbGk+CisgKiA8bGk+VXNlCisgKiB7QGxpbmsgamF2YS5uaW8uQnl0ZUJ1ZmZlciNhc0RvdWJsZUJ1ZmZlcigpIEJ5dGVCdWZmZXIuYXNEb3VibGVCdWZmZXJ9IHRvCisgKiBjcmVhdGUgYSBkb3VibGUgYnVmZmVyIGJhc2VkIG9uIGEgYnl0ZSBidWZmZXIuPC9saT4KKyAqIDwvdWw+CisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBEb3VibGVCdWZmZXIgZXh0ZW5kcyBCdWZmZXIgaW1wbGVtZW50cworICAgICAgICBDb21wYXJhYmxlPERvdWJsZUJ1ZmZlcj4geworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGRvdWJsZSBidWZmZXIgYmFzZWQgb24gYSBuZXdseSBhbGxvY2F0ZWQgZG91YmxlIGFycmF5LgorICAgICAqCisgICAgICogQHBhcmFtIGNhcGFjaXR5CisgICAgICogICAgICAgICAgICB0aGUgY2FwYWNpdHkgb2YgdGhlIG5ldyBidWZmZXIuCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCBkb3VibGUgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGNhcGFjaXR5fSBpcyBsZXNzIHRoYW4gemVyby4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIERvdWJsZUJ1ZmZlciBhbGxvY2F0ZShpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgaWYgKGNhcGFjaXR5IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgUmVhZFdyaXRlRG91YmxlQXJyYXlCdWZmZXIoY2FwYWNpdHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgZG91YmxlIGJ1ZmZlciBieSB3cmFwcGluZyB0aGUgZ2l2ZW4gZG91YmxlIGFycmF5LgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcworICAgICAqIHtAY29kZSB3cmFwKGFycmF5LCAwLCBhcnJheS5sZW5ndGgpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGRvdWJsZSBhcnJheSB3aGljaCB0aGUgbmV3IGJ1ZmZlciB3aWxsIGJlIGJhc2VkIG9uLgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgZG91YmxlIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIERvdWJsZUJ1ZmZlciB3cmFwKGRvdWJsZVtdIGFycmF5KSB7CisgICAgICAgIHJldHVybiB3cmFwKGFycmF5LCAwLCBhcnJheS5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgZG91YmxlIGJ1ZmZlciBieSB3cmFwcGluZyB0aGUgZ2l2ZW4gZG91YmxlIGFycmF5LgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyJ3MgcG9zaXRpb24gd2lsbCBiZSB7QGNvZGUgc3RhcnR9LCBsaW1pdCB3aWxsIGJlCisgICAgICoge0Bjb2RlIHN0YXJ0ICsgZG91YmxlQ291bnR9LCBjYXBhY2l0eSB3aWxsIGJlIHRoZSBsZW5ndGggb2YgdGhlIGFycmF5LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUgZG91YmxlIGFycmF5IHdoaWNoIHRoZSBuZXcgYnVmZmVyIHdpbGwgYmUgYmFzZWQgb24uCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgaW5kZXgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgICAgICB7QGNvZGUgYXJyYXkubGVuZ3RofS4KKyAgICAgKiBAcGFyYW0gZG91YmxlQ291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgICAgICB7QGNvZGUgYXJyYXkubGVuZ3RoIC0gc3RhcnR9LgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgZG91YmxlIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBlaXRoZXIge0Bjb2RlIHN0YXJ0fSBvciB7QGNvZGUgZG91YmxlQ291bnR9IGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBEb3VibGVCdWZmZXIgd3JhcChkb3VibGVbXSBhcnJheSwgaW50IHN0YXJ0LCBpbnQgZG91YmxlQ291bnQpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYXJyYXkubGVuZ3RoLCBzdGFydCwgZG91YmxlQ291bnQpOworICAgICAgICBEb3VibGVCdWZmZXIgYnVmID0gbmV3IFJlYWRXcml0ZURvdWJsZUFycmF5QnVmZmVyKGFycmF5KTsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gc3RhcnQ7CisgICAgICAgIGJ1Zi5saW1pdCA9IHN0YXJ0ICsgZG91YmxlQ291bnQ7CisgICAgICAgIHJldHVybiBidWY7CisgICAgfQorCisgICAgRG91YmxlQnVmZmVyKGludCBjYXBhY2l0eSkgeworICAgICAgICBzdXBlcigzLCBjYXBhY2l0eSwgbnVsbCk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIGRvdWJsZVtdIGFycmF5KCkgeworICAgICAgICByZXR1cm4gcHJvdGVjdGVkQXJyYXkoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgaW50IGFycmF5T2Zmc2V0KCkgeworICAgICAgICByZXR1cm4gcHJvdGVjdGVkQXJyYXlPZmZzZXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcmVhZC1vbmx5IGJ1ZmZlciB0aGF0IHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSByZXR1cm5lZCBidWZmZXIgaXMgZ3VhcmFudGVlZCB0byBiZSBhIG5ldyBpbnN0YW5jZSwgZXZlbiBpZiB0aGlzCisgICAgICogYnVmZmVyIGlzIHJlYWQtb25seSBpdHNlbGYuIFRoZSBuZXcgYnVmZmVyJ3MgcG9zaXRpb24sIGxpbWl0LCBjYXBhY2l0eQorICAgICAqIGFuZCBtYXJrIGFyZSB0aGUgc2FtZSBhcyB0aGlzIGJ1ZmZlcidzLgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyIHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLCB3aGljaCBtZWFucyB0aGF0IHRoaXMKKyAgICAgKiBidWZmZXIncyBjaGFuZ2Ugb2YgY29udGVudCB3aWxsIGJlIHZpc2libGUgdG8gdGhlIG5ldyBidWZmZXIuIFRoZSB0d28KKyAgICAgKiBidWZmZXIncyBwb3NpdGlvbiwgbGltaXQgYW5kIG1hcmsgYXJlIGluZGVwZW5kZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIHJlYWQtb25seSB2ZXJzaW9uIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBEb3VibGVCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpOworCisgICAgLyoqCisgICAgICogQ29tcGFjdHMgdGhpcyBkb3VibGUgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSByZW1haW5pbmcgZG91YmxlcyB3aWxsIGJlIG1vdmVkIHRvIHRoZSBoZWFkIG9mIHRoZSBidWZmZXIsIHN0YXJpbmcKKyAgICAgKiBmcm9tIHBvc2l0aW9uIHplcm8uIFRoZW4gdGhlIHBvc2l0aW9uIGlzIHNldCB0byB7QGNvZGUgcmVtYWluaW5nKCl9OyB0aGUKKyAgICAgKiBsaW1pdCBpcyBzZXQgdG8gY2FwYWNpdHk7IHRoZSBtYXJrIGlzIGNsZWFyZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRG91YmxlQnVmZmVyIGNvbXBhY3QoKTsKKworICAgIC8qKgorICAgICAqIENvbXBhcmUgdGhlIHJlbWFpbmluZyBkb3VibGVzIG9mIHRoaXMgYnVmZmVyIHRvIGFub3RoZXIgZG91YmxlIGJ1ZmZlcidzCisgICAgICogcmVtYWluaW5nIGRvdWJsZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3RoZXJCdWZmZXIKKyAgICAgKiAgICAgICAgICAgIGFub3RoZXIgZG91YmxlIGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIGEgbmVnYXRpdmUgdmFsdWUgaWYgdGhpcyBpcyBsZXNzIHRoYW4ge0Bjb2RlIG90aGVyfTsgMCBpZiB0aGlzCisgICAgICogICAgICAgICBlcXVhbHMgdG8ge0Bjb2RlIG90aGVyfTsgYSBwb3NpdGl2ZSB2YWx1ZSBpZiB0aGlzIGlzIGdyZWF0ZXIKKyAgICAgKiAgICAgICAgIHRoYW4ge0Bjb2RlIG90aGVyfS4KKyAgICAgKiBAZXhjZXB0aW9uIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBvdGhlcn0gaXMgbm90IGEgZG91YmxlIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhEb3VibGVCdWZmZXIgb3RoZXJCdWZmZXIpIHsKKyAgICAgICAgaW50IGNvbXBhcmVSZW1haW5pbmcgPSAocmVtYWluaW5nKCkgPCBvdGhlckJ1ZmZlci5yZW1haW5pbmcoKSkgPyByZW1haW5pbmcoKQorICAgICAgICAgICAgICAgIDogb3RoZXJCdWZmZXIucmVtYWluaW5nKCk7CisgICAgICAgIGludCB0aGlzUG9zID0gcG9zaXRpb247CisgICAgICAgIGludCBvdGhlclBvcyA9IG90aGVyQnVmZmVyLnBvc2l0aW9uOworICAgICAgICBkb3VibGUgdGhpc0RvdWJsZSwgb3RoZXJEb3VibGU7CisgICAgICAgIHdoaWxlIChjb21wYXJlUmVtYWluaW5nID4gMCkgeworICAgICAgICAgICAgdGhpc0RvdWJsZSA9IGdldCh0aGlzUG9zKTsKKyAgICAgICAgICAgIG90aGVyRG91YmxlID0gb3RoZXJCdWZmZXIuZ2V0KG90aGVyUG9zKTsKKyAgICAgICAgICAgIC8vIGNoZWNrcyBmb3IgZG91YmxlIGFuZCBOYU4gaW5lcXVhbGl0eQorICAgICAgICAgICAgaWYgKCh0aGlzRG91YmxlICE9IG90aGVyRG91YmxlKQorICAgICAgICAgICAgICAgICAgICAmJiAoKHRoaXNEb3VibGUgPT0gdGhpc0RvdWJsZSkgfHwgKG90aGVyRG91YmxlID09IG90aGVyRG91YmxlKSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdGhpc0RvdWJsZSA8IG90aGVyRG91YmxlID8gLTEgOiAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpc1BvcysrOworICAgICAgICAgICAgb3RoZXJQb3MrKzsKKyAgICAgICAgICAgIGNvbXBhcmVSZW1haW5pbmctLTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVtYWluaW5nKCkgLSBvdGhlckJ1ZmZlci5yZW1haW5pbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgZHVwbGljYXRlZCBidWZmZXIgdGhhdCBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZHVwbGljYXRlZCBidWZmZXIncyBwb3NpdGlvbiwgbGltaXQsIGNhcGFjaXR5IGFuZCBtYXJrIGFyZSB0aGUgc2FtZQorICAgICAqIGFzIHRoaXMgYnVmZmVyJ3MuIFRoZSBkdXBsaWNhdGVkIGJ1ZmZlcidzIHJlYWQtb25seSBwcm9wZXJ0eSBhbmQgYnl0ZQorICAgICAqIG9yZGVyIGFyZSB0aGUgc2FtZSBhcyB0aGlzIGJ1ZmZlcidzLCB0b28uCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIsIHdoaWNoIG1lYW5zIGVpdGhlcgorICAgICAqIGJ1ZmZlcidzIGNoYW5nZSBvZiBjb250ZW50IHdpbGwgYmUgdmlzaWJsZSB0byB0aGUgb3RoZXIuIFRoZSB0d28gYnVmZmVyJ3MKKyAgICAgKiBwb3NpdGlvbiwgbGltaXQgYW5kIG1hcmsgYXJlIGluZGVwZW5kZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIGR1cGxpY2F0ZWQgYnVmZmVyIHRoYXQgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IERvdWJsZUJ1ZmZlciBkdXBsaWNhdGUoKTsKKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIHRoaXMgZG91YmxlIGJ1ZmZlciBpcyBlcXVhbCB0byBhbm90aGVyIG9iamVjdC4gSWYge0Bjb2RlCisgICAgICogb3RoZXJ9IGlzIG5vdCBhIHtAY29kZSBEb3VibGVCdWZmZXJ9IHRoZW4ge0Bjb2RlIGZhbHNlfSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIDxwPlR3byBkb3VibGUgYnVmZmVycyBhcmUgZXF1YWwgaWYgdGhlaXIgcmVtYWluaW5nIGRvdWJsZXMgYXJlIGVxdWFsLgorICAgICAqIFBvc2l0aW9uLCBsaW1pdCwgY2FwYWNpdHkgYW5kIG1hcmsgYXJlIG5vdCBjb25zaWRlcmVkLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgY29uc2lkZXJzIHR3byBkb3VibGVzIHtAY29kZSBhfSBhbmQge0Bjb2RlIGJ9IHRvIGJlIGVxdWFsCisgICAgICogaWYge0Bjb2RlIGEgPT0gYn0gb3IgaWYge0Bjb2RlIGF9IGFuZCB7QGNvZGUgYn0gYXJlIGJvdGgge0Bjb2RlIE5hTn0uCisgICAgICogVW5saWtlIHtAbGluayBEb3VibGUjZXF1YWxzfSwgdGhpcyBtZXRob2QgY29uc2lkZXJzIHtAY29kZSAtMC4wfSBhbmQKKyAgICAgKiB7QGNvZGUgKzAuMH0gdG8gYmUgZXF1YWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3RoZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB3aXRoIHRoaXMgZG91YmxlIGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGRvdWJsZSBidWZmZXIgaXMgZXF1YWwgdG8ge0Bjb2RlIG90aGVyfSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKKyAgICAgICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBEb3VibGVCdWZmZXIpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgRG91YmxlQnVmZmVyIG90aGVyQnVmZmVyID0gKERvdWJsZUJ1ZmZlcikgb3RoZXI7CisKKyAgICAgICAgaWYgKHJlbWFpbmluZygpICE9IG90aGVyQnVmZmVyLnJlbWFpbmluZygpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBpbnQgbXlQb3NpdGlvbiA9IHBvc2l0aW9uOworICAgICAgICBpbnQgb3RoZXJQb3NpdGlvbiA9IG90aGVyQnVmZmVyLnBvc2l0aW9uOworICAgICAgICBib29sZWFuIGVxdWFsU29GYXIgPSB0cnVlOworICAgICAgICB3aGlsZSAoZXF1YWxTb0ZhciAmJiAobXlQb3NpdGlvbiA8IGxpbWl0KSkgeworICAgICAgICAgICAgZG91YmxlIGEgPSBnZXQobXlQb3NpdGlvbisrKTsKKyAgICAgICAgICAgIGRvdWJsZSBiID0gb3RoZXJCdWZmZXIuZ2V0KG90aGVyUG9zaXRpb24rKyk7CisgICAgICAgICAgICBlcXVhbFNvRmFyID0gYSA9PSBiIHx8IChhICE9IGEgJiYgYiAhPSBiKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBlcXVhbFNvRmFyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRvdWJsZSBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQgaW5jcmVhc2VzIHRoZSBwb3NpdGlvbiBieQorICAgICAqIDEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkb3VibGUgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgcG9zaXRpb24gaXMgZXF1YWwgb3IgZ3JlYXRlciB0aGFuIGxpbWl0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBkb3VibGUgZ2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBkb3VibGVzIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24gaW50byB0aGUgc3BlY2lmaWVkIGRvdWJsZSBhcnJheQorICAgICAqIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IHRoZSBudW1iZXIgb2YgZG91YmxlcyByZWFkLgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcworICAgICAqIHtAY29kZSBnZXQoZHN0LCAwLCBkc3QubGVuZ3RoKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gZG91YmxlIGFycmF5LgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgZHN0Lmxlbmd0aH0gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSByZW1haW5pbmcoKX0uCisgICAgICovCisgICAgcHVibGljIERvdWJsZUJ1ZmZlciBnZXQoZG91YmxlW10gZHN0KSB7CisgICAgICAgIHJldHVybiBnZXQoZHN0LCAwLCBkc3QubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBkb3VibGVzIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24gaW50byB0aGUgc3BlY2lmaWVkIGRvdWJsZSBhcnJheSwKKyAgICAgKiBzdGFydGluZyBmcm9tIHRoZSBzcGVjaWZpZWQgb2Zmc2V0LCBhbmQgaW5jcmVhc2VzIHRoZSBwb3NpdGlvbiBieSB0aGUKKyAgICAgKiBudW1iZXIgb2YgZG91YmxlcyByZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBkb3VibGUgYXJyYXkuCisgICAgICogQHBhcmFtIGRzdE9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvZiB0aGUgZG91YmxlIGFycmF5LCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBhbmQgbm90CisgICAgICogICAgICAgICAgICBncmVhdGVyIHRoYW4ge0Bjb2RlIGRzdC5sZW5ndGh9LgorICAgICAqIEBwYXJhbSBkb3VibGVDb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBkb3VibGVzIHRvIHJlYWQsIG11c3QgYmUgbm8gbGVzcyB0aGFuIHplcm8gYW5kCisgICAgICogICAgICAgICAgICBub3QgZ3JlYXRlciB0aGFuIHtAY29kZSBkc3QubGVuZ3RoIC0gZHN0T2Zmc2V0fS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGVpdGhlciB7QGNvZGUgZHN0T2Zmc2V0fSBvciB7QGNvZGUgZG91YmxlQ291bnR9IGlzIGludmFsaWQuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgZG91YmxlQ291bnR9IGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgcmVtYWluaW5nKCl9LgorICAgICAqLworICAgIHB1YmxpYyBEb3VibGVCdWZmZXIgZ2V0KGRvdWJsZVtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGRvdWJsZUNvdW50KSB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGRzdC5sZW5ndGgsIGRzdE9mZnNldCwgZG91YmxlQ291bnQpOworICAgICAgICBpZiAoZG91YmxlQ291bnQgPiByZW1haW5pbmcoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSBkc3RPZmZzZXQ7IGkgPCBkc3RPZmZzZXQgKyBkb3VibGVDb3VudDsgKytpKSB7CisgICAgICAgICAgICBkc3RbaV0gPSBnZXQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgZG91YmxlIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXg7IHRoZSBwb3NpdGlvbiBpcyBub3QgY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBhbmQgbGVzcyB0aGFuIGxpbWl0LgorICAgICAqIEByZXR1cm4gYSBkb3VibGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBpbmRleCBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBkb3VibGUgZ2V0KGludCBpbmRleCk7CisKKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNBcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIHByb3RlY3RlZEhhc0FycmF5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsY3VsYXRlcyB0aGlzIGJ1ZmZlcidzIGhhc2ggY29kZSBmcm9tIHRoZSByZW1haW5pbmcgY2hhcnMuIFRoZQorICAgICAqIHBvc2l0aW9uLCBsaW1pdCwgY2FwYWNpdHkgYW5kIG1hcmsgZG9uJ3QgYWZmZWN0IHRoZSBoYXNoIGNvZGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUgY2FsY3VsYXRlZCBmcm9tIHRoZSByZW1haW5pbmcgY2hhcnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IG15UG9zaXRpb24gPSBwb3NpdGlvbjsKKyAgICAgICAgaW50IGhhc2ggPSAwOworICAgICAgICBsb25nIGw7CisgICAgICAgIHdoaWxlIChteVBvc2l0aW9uIDwgbGltaXQpIHsKKyAgICAgICAgICAgIGwgPSBEb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXQobXlQb3NpdGlvbisrKSk7CisgICAgICAgICAgICBoYXNoID0gaGFzaCArICgoaW50KSBsKSBeICgoaW50KSAobCA+PiAzMikpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBoYXNoOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgYnVmZmVyIGlzIGRpcmVjdC4gQSBkaXJlY3QgYnVmZmVyIHdpbGwgdHJ5IGl0cworICAgICAqIGJlc3QgdG8gdGFrZSBhZHZhbnRhZ2Ugb2YgbmF0aXZlIG1lbW9yeSBBUElzIGFuZCBpdCBtYXkgbm90IHN0YXkgaW4gdGhlCisgICAgICogSmF2YSBoZWFwLCBzbyBpdCBpcyBub3QgYWZmZWN0ZWQgYnkgZ2FyYmFnZSBjb2xsZWN0aW9uLgorICAgICAqIDxwPgorICAgICAqIEEgZG91YmxlIGJ1ZmZlciBpcyBkaXJlY3QgaWYgaXQgaXMgYmFzZWQgb24gYSBieXRlIGJ1ZmZlciBhbmQgdGhlIGJ5dGUKKyAgICAgKiBidWZmZXIgaXMgZGlyZWN0LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBidWZmZXIgaXMgZGlyZWN0LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc0RpcmVjdCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYnl0ZSBvcmRlciB1c2VkIGJ5IHRoaXMgYnVmZmVyIHdoZW4gY29udmVydGluZyBkb3VibGVzCisgICAgICogZnJvbS90byBieXRlcy4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIGJ1ZmZlciBpcyBub3QgYmFzZWQgb24gYSBieXRlIGJ1ZmZlciwgdGhlbiB0aGlzIGFsd2F5cyByZXR1cm5zCisgICAgICogdGhlIHBsYXRmb3JtJ3MgbmF0aXZlIGJ5dGUgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBieXRlIG9yZGVyIHVzZWQgYnkgdGhpcyBidWZmZXIgd2hlbiBjb252ZXJ0aW5nIGRvdWJsZXMKKyAgICAgKiAgICAgICAgIGZyb20vdG8gYnl0ZXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ5dGVPcmRlciBvcmRlcigpOworCisgICAgLyoqCisgICAgICogQ2hpbGQgY2xhc3MgaW1wbGVtZW50cyB0aGlzIG1ldGhvZCB0byByZWFsaXplIHtAY29kZSBhcnJheSgpfS4KKyAgICAgKgorICAgICAqIEBzZWUgI2FycmF5KCkKKyAgICAgKi8KKyAgICBhYnN0cmFjdCBkb3VibGVbXSBwcm90ZWN0ZWRBcnJheSgpOworCisgICAgLyoqCisgICAgICogQ2hpbGQgY2xhc3MgaW1wbGVtZW50cyB0aGlzIG1ldGhvZCB0byByZWFsaXplIHtAY29kZSBhcnJheU9mZnNldCgpfS4KKyAgICAgKgorICAgICAqIEBzZWUgI2FycmF5T2Zmc2V0KCkKKyAgICAgKi8KKyAgICBhYnN0cmFjdCBpbnQgcHJvdGVjdGVkQXJyYXlPZmZzZXQoKTsKKworICAgIC8qKgorICAgICAqIENoaWxkIGNsYXNzIGltcGxlbWVudHMgdGhpcyBtZXRob2QgdG8gcmVhbGl6ZSB7QGNvZGUgaGFzQXJyYXkoKX0uCisgICAgICoKKyAgICAgKiBAc2VlICNoYXNBcnJheSgpCisgICAgICovCisgICAgYWJzdHJhY3QgYm9vbGVhbiBwcm90ZWN0ZWRIYXNBcnJheSgpOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBnaXZlbiBkb3VibGUgdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gYW5kIGluY3JlYXNlcyB0aGUKKyAgICAgKiBwb3NpdGlvbiBieSAxLgorICAgICAqCisgICAgICogQHBhcmFtIGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb3VibGUgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcG9zaXRpb24gaXMgZXF1YWwgb3IgZ3JlYXRlciB0aGFuIGxpbWl0LgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRG91YmxlQnVmZmVyIHB1dChkb3VibGUgZCk7CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgZG91YmxlcyBmcm9tIHRoZSBnaXZlbiBkb3VibGUgYXJyYXkgdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gYW5kCisgICAgICogaW5jcmVhc2VzIHRoZSBwb3NpdGlvbiBieSB0aGUgbnVtYmVyIG9mIGRvdWJsZXMgd3JpdHRlbi4KKyAgICAgKiA8cD4KKyAgICAgKiBDYWxsaW5nIHRoaXMgbWV0aG9kIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMKKyAgICAgKiB7QGNvZGUgcHV0KHNyYywgMCwgc3JjLmxlbmd0aCl9LgorICAgICAqCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBkb3VibGUgYXJyYXkuCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHJlbWFpbmluZygpfSBpcyBsZXNzIHRoYW4ge0Bjb2RlIHNyYy5sZW5ndGh9LgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgRG91YmxlQnVmZmVyIHB1dChkb3VibGVbXSBzcmMpIHsKKyAgICAgICAgcmV0dXJuIHB1dChzcmMsIDAsIHNyYy5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBkb3VibGVzIGZyb20gdGhlIGdpdmVuIGRvdWJsZSBhcnJheSwgc3RhcnRpbmcgZnJvbSB0aGUgc3BlY2lmaWVkCisgICAgICogb2Zmc2V0LCB0byB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQgaW5jcmVhc2VzIHRoZSBwb3NpdGlvbiBieSB0aGUgbnVtYmVyCisgICAgICogb2YgZG91YmxlcyB3cml0dGVuLgorICAgICAqCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBkb3VibGUgYXJyYXkuCisgICAgICogQHBhcmFtIHNyY09mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvZiBkb3VibGUgYXJyYXksIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QKKyAgICAgKiAgICAgICAgICAgIGdyZWF0ZXIgdGhhbiB7QGNvZGUgc3JjLmxlbmd0aH0uCisgICAgICogQHBhcmFtIGRvdWJsZUNvdW50CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGRvdWJsZXMgdG8gd3JpdGUsIG11c3QgYmUgbm8gbGVzcyB0aGFuIHplcm8gYW5kCisgICAgICogICAgICAgICAgICBub3QgZ3JlYXRlciB0aGFuIHtAY29kZSBzcmMubGVuZ3RoIC0gc3JjT2Zmc2V0fS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgcmVtYWluaW5nKCl9IGlzIGxlc3MgdGhhbiB7QGNvZGUgZG91YmxlQ291bnR9LgorICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGVpdGhlciB7QGNvZGUgc3JjT2Zmc2V0fSBvciB7QGNvZGUgZG91YmxlQ291bnR9IGlzIGludmFsaWQuCisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBEb3VibGVCdWZmZXIgcHV0KGRvdWJsZVtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGRvdWJsZUNvdW50KSB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KHNyYy5sZW5ndGgsIHNyY09mZnNldCwgZG91YmxlQ291bnQpOworICAgICAgICBpZiAoZG91YmxlQ291bnQgPiByZW1haW5pbmcoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IHNyY09mZnNldDsgaSA8IHNyY09mZnNldCArIGRvdWJsZUNvdW50OyArK2kpIHsKKyAgICAgICAgICAgIHB1dChzcmNbaV0pOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhbGwgdGhlIHJlbWFpbmluZyBkb3VibGVzIG9mIHRoZSB7QGNvZGUgc3JjfSBkb3VibGUgYnVmZmVyIHRvIHRoaXMKKyAgICAgKiBidWZmZXIncyBjdXJyZW50IHBvc2l0aW9uLCBhbmQgaW5jcmVhc2VzIGJvdGggYnVmZmVycycgcG9zaXRpb24gYnkgdGhlCisgICAgICogbnVtYmVyIG9mIGRvdWJsZXMgY29waWVkLgorICAgICAqCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBkb3VibGUgYnVmZmVyLgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzcmMucmVtYWluaW5nKCl9IGlzIGdyZWF0ZXIgdGhhbiB0aGlzIGJ1ZmZlcidzCisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIHJlbWFpbmluZygpfS4KKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzcmN9IGlzIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgRG91YmxlQnVmZmVyIHB1dChEb3VibGVCdWZmZXIgc3JjKSB7CisgICAgICAgIGlmIChzcmMgPT0gdGhpcykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChzcmMucmVtYWluaW5nKCkgPiByZW1haW5pbmcoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgZG91YmxlW10gZG91YmxlcyA9IG5ldyBkb3VibGVbc3JjLnJlbWFpbmluZygpXTsKKyAgICAgICAgc3JjLmdldChkb3VibGVzKTsKKyAgICAgICAgcHV0KGRvdWJsZXMpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhIGRvdWJsZSB0byB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgYnVmZmVyIGFuZCB0aGUgcG9zaXRpb24gaXMKKyAgICAgKiBub3QgY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBhbmQgbGVzcyB0aGFuIHRoZSBsaW1pdC4KKyAgICAgKiBAcGFyYW0gZAorICAgICAqICAgICAgICAgICAgdGhlIGRvdWJsZSB0byB3cml0ZS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGluZGV4IGlzIGludmFsaWQuCisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBEb3VibGVCdWZmZXIgcHV0KGludCBpbmRleCwgZG91YmxlIGQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNsaWNlZCBidWZmZXIgdGhhdCBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgc2xpY2VkIGJ1ZmZlcidzIGNhcGFjaXR5IHdpbGwgYmUgdGhpcyBidWZmZXIncyB7QGNvZGUgcmVtYWluaW5nKCl9LAorICAgICAqIGFuZCBpdHMgemVybyBwb3NpdGlvbiB3aWxsIGNvcnJlc3BvbmQgdG8gdGhpcyBidWZmZXIncyBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqIFRoZSBuZXcgYnVmZmVyJ3MgcG9zaXRpb24gd2lsbCBiZSAwLCBsaW1pdCB3aWxsIGJlIGl0cyBjYXBhY2l0eSwgYW5kIGl0cworICAgICAqIG1hcmsgaXMgY2xlYXJlZC4gVGhlIG5ldyBidWZmZXIncyByZWFkLW9ubHkgcHJvcGVydHkgYW5kIGJ5dGUgb3JkZXIgYXJlCisgICAgICogdGhlIHNhbWUgYXMgdGhpcyBidWZmZXIncy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbmV3IGJ1ZmZlciBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlciwgd2hpY2ggbWVhbnMgZWl0aGVyCisgICAgICogYnVmZmVyJ3MgY2hhbmdlIG9mIGNvbnRlbnQgd2lsbCBiZSB2aXNpYmxlIHRvIHRoZSBvdGhlci4gVGhlIHR3byBidWZmZXIncworICAgICAqIHBvc2l0aW9uLCBsaW1pdCBhbmQgbWFyayBhcmUgaW5kZXBlbmRlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc2xpY2VkIGJ1ZmZlciB0aGF0IHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBEb3VibGVCdWZmZXIgc2xpY2UoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9Eb3VibGVUb0J5dGVCdWZmZXJBZGFwdGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vRG91YmxlVG9CeXRlQnVmZmVyQWRhcHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmN2RkYTcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vRG91YmxlVG9CeXRlQnVmZmVyQWRhcHRlci5qYXZhCkBAIC0wLDAgKzEsMTgyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCitpbXBvcnQgbGliY29yZS5pby5TaXplT2Y7CisKKy8qKgorICogVGhpcyBjbGFzcyB3cmFwcyBhIGJ5dGUgYnVmZmVyIHRvIGJlIGEgZG91YmxlIGJ1ZmZlci4KKyAqIDxwPgorICogSW1wbGVtZW50YXRpb24gbm90aWNlOgorICogPHVsPgorICogPGxpPkFmdGVyIGEgYnl0ZSBidWZmZXIgaW5zdGFuY2UgaXMgd3JhcHBlZCwgaXQgYmVjb21lcyBwcml2YXRlbHkgb3duZWQgYnkKKyAqIHRoZSBhZGFwdGVyLiBJdCBtdXN0IE5PVCBiZSBhY2Nlc3NlZCBvdXRzaWRlIHRoZSBhZGFwdGVyIGFueSBtb3JlLjwvbGk+CisgKiA8bGk+VGhlIGJ5dGUgYnVmZmVyJ3MgcG9zaXRpb24gYW5kIGxpbWl0IGFyZSBOT1QgbGlua2VkIHdpdGggdGhlIGFkYXB0ZXIuCisgKiBUaGUgYWRhcHRlciBleHRlbmRzIEJ1ZmZlciwgdGh1cyBoYXMgaXRzIG93biBwb3NpdGlvbiBhbmQgbGltaXQuPC9saT4KKyAqIDwvdWw+CisgKiA8L3A+CisgKgorICovCitmaW5hbCBjbGFzcyBEb3VibGVUb0J5dGVCdWZmZXJBZGFwdGVyIGV4dGVuZHMgRG91YmxlQnVmZmVyIHsKKworICAgIHByaXZhdGUgZmluYWwgQnl0ZUJ1ZmZlciBieXRlQnVmZmVyOworCisgICAgc3RhdGljIERvdWJsZUJ1ZmZlciBhc0RvdWJsZUJ1ZmZlcihCeXRlQnVmZmVyIGJ5dGVCdWZmZXIpIHsKKyAgICAgICAgQnl0ZUJ1ZmZlciBzbGljZSA9IGJ5dGVCdWZmZXIuc2xpY2UoKTsKKyAgICAgICAgc2xpY2Uub3JkZXIoYnl0ZUJ1ZmZlci5vcmRlcigpKTsKKyAgICAgICAgcmV0dXJuIG5ldyBEb3VibGVUb0J5dGVCdWZmZXJBZGFwdGVyKHNsaWNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIERvdWJsZVRvQnl0ZUJ1ZmZlckFkYXB0ZXIoQnl0ZUJ1ZmZlciBieXRlQnVmZmVyKSB7CisgICAgICAgIHN1cGVyKGJ5dGVCdWZmZXIuY2FwYWNpdHkoKSAvIFNpemVPZi5ET1VCTEUpOworICAgICAgICB0aGlzLmJ5dGVCdWZmZXIgPSBieXRlQnVmZmVyOworICAgICAgICB0aGlzLmJ5dGVCdWZmZXIuY2xlYXIoKTsKKyAgICAgICAgdGhpcy5lZmZlY3RpdmVEaXJlY3RBZGRyZXNzID0gYnl0ZUJ1ZmZlci5lZmZlY3RpdmVEaXJlY3RBZGRyZXNzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEb3VibGVCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpIHsKKyAgICAgICAgRG91YmxlVG9CeXRlQnVmZmVyQWRhcHRlciBidWYgPSBuZXcgRG91YmxlVG9CeXRlQnVmZmVyQWRhcHRlcihieXRlQnVmZmVyLmFzUmVhZE9ubHlCdWZmZXIoKSk7CisgICAgICAgIGJ1Zi5saW1pdCA9IGxpbWl0OworICAgICAgICBidWYucG9zaXRpb24gPSBwb3NpdGlvbjsKKyAgICAgICAgYnVmLm1hcmsgPSBtYXJrOworICAgICAgICBidWYuYnl0ZUJ1ZmZlci5vcmRlciA9IGJ5dGVCdWZmZXIub3JkZXI7CisgICAgICAgIHJldHVybiBidWY7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERvdWJsZUJ1ZmZlciBjb21wYWN0KCkgeworICAgICAgICBpZiAoYnl0ZUJ1ZmZlci5pc1JlYWRPbmx5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGJ5dGVCdWZmZXIubGltaXQobGltaXQgKiBTaXplT2YuRE9VQkxFKTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5wb3NpdGlvbihwb3NpdGlvbiAqIFNpemVPZi5ET1VCTEUpOworICAgICAgICBieXRlQnVmZmVyLmNvbXBhY3QoKTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5jbGVhcigpOworICAgICAgICBwb3NpdGlvbiA9IGxpbWl0IC0gcG9zaXRpb247CisgICAgICAgIGxpbWl0ID0gY2FwYWNpdHk7CisgICAgICAgIG1hcmsgPSBVTlNFVF9NQVJLOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRG91YmxlQnVmZmVyIGR1cGxpY2F0ZSgpIHsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYiA9IGJ5dGVCdWZmZXIuZHVwbGljYXRlKCkub3JkZXIoYnl0ZUJ1ZmZlci5vcmRlcigpKTsKKyAgICAgICAgRG91YmxlVG9CeXRlQnVmZmVyQWRhcHRlciBidWYgPSBuZXcgRG91YmxlVG9CeXRlQnVmZmVyQWRhcHRlcihiYik7CisgICAgICAgIGJ1Zi5saW1pdCA9IGxpbWl0OworICAgICAgICBidWYucG9zaXRpb24gPSBwb3NpdGlvbjsKKyAgICAgICAgYnVmLm1hcmsgPSBtYXJrOworICAgICAgICByZXR1cm4gYnVmOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkb3VibGUgZ2V0KCkgeworICAgICAgICBpZiAocG9zaXRpb24gPT0gbGltaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnl0ZUJ1ZmZlci5nZXREb3VibGUocG9zaXRpb24rKyAqIFNpemVPZi5ET1VCTEUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkb3VibGUgZ2V0KGludCBpbmRleCkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4KTsKKyAgICAgICAgcmV0dXJuIGJ5dGVCdWZmZXIuZ2V0RG91YmxlKGluZGV4ICogU2l6ZU9mLkRPVUJMRSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERvdWJsZUJ1ZmZlciBnZXQoZG91YmxlW10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgZG91YmxlQ291bnQpIHsKKyAgICAgICAgYnl0ZUJ1ZmZlci5saW1pdChsaW1pdCAqIFNpemVPZi5ET1VCTEUpOworICAgICAgICBieXRlQnVmZmVyLnBvc2l0aW9uKHBvc2l0aW9uICogU2l6ZU9mLkRPVUJMRSk7CisgICAgICAgIGlmIChieXRlQnVmZmVyIGluc3RhbmNlb2YgRGlyZWN0Qnl0ZUJ1ZmZlcikgeworICAgICAgICAgICAgKChEaXJlY3RCeXRlQnVmZmVyKSBieXRlQnVmZmVyKS5nZXQoZHN0LCBkc3RPZmZzZXQsIGRvdWJsZUNvdW50KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICgoSGVhcEJ5dGVCdWZmZXIpIGJ5dGVCdWZmZXIpLmdldChkc3QsIGRzdE9mZnNldCwgZG91YmxlQ291bnQpOworICAgICAgICB9CisgICAgICAgIHRoaXMucG9zaXRpb24gKz0gZG91YmxlQ291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzRGlyZWN0KCkgeworICAgICAgICByZXR1cm4gYnl0ZUJ1ZmZlci5pc0RpcmVjdCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzUmVhZE9ubHkoKSB7CisgICAgICAgIHJldHVybiBieXRlQnVmZmVyLmlzUmVhZE9ubHkoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZU9yZGVyIG9yZGVyKCkgeworICAgICAgICByZXR1cm4gYnl0ZUJ1ZmZlci5vcmRlcigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBkb3VibGVbXSBwcm90ZWN0ZWRBcnJheSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBwcm90ZWN0ZWRBcnJheU9mZnNldCgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcHJvdGVjdGVkSGFzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRG91YmxlQnVmZmVyIHB1dChkb3VibGUgYykgeworICAgICAgICBpZiAocG9zaXRpb24gPT0gbGltaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGJ5dGVCdWZmZXIucHV0RG91YmxlKHBvc2l0aW9uKysgKiBTaXplT2YuRE9VQkxFLCBjKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERvdWJsZUJ1ZmZlciBwdXQoaW50IGluZGV4LCBkb3VibGUgYykgeworICAgICAgICBjaGVja0luZGV4KGluZGV4KTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5wdXREb3VibGUoaW5kZXggKiBTaXplT2YuRE9VQkxFLCBjKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERvdWJsZUJ1ZmZlciBwdXQoZG91YmxlW10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgZG91YmxlQ291bnQpIHsKKyAgICAgICAgYnl0ZUJ1ZmZlci5saW1pdChsaW1pdCAqIFNpemVPZi5ET1VCTEUpOworICAgICAgICBieXRlQnVmZmVyLnBvc2l0aW9uKHBvc2l0aW9uICogU2l6ZU9mLkRPVUJMRSk7CisgICAgICAgIGlmIChieXRlQnVmZmVyIGluc3RhbmNlb2YgUmVhZFdyaXRlRGlyZWN0Qnl0ZUJ1ZmZlcikgeworICAgICAgICAgICAgKChSZWFkV3JpdGVEaXJlY3RCeXRlQnVmZmVyKSBieXRlQnVmZmVyKS5wdXQoc3JjLCBzcmNPZmZzZXQsIGRvdWJsZUNvdW50KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICgoUmVhZFdyaXRlSGVhcEJ5dGVCdWZmZXIpIGJ5dGVCdWZmZXIpLnB1dChzcmMsIHNyY09mZnNldCwgZG91YmxlQ291bnQpOworICAgICAgICB9CisgICAgICAgIHRoaXMucG9zaXRpb24gKz0gZG91YmxlQ291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEb3VibGVCdWZmZXIgc2xpY2UoKSB7CisgICAgICAgIGJ5dGVCdWZmZXIubGltaXQobGltaXQgKiBTaXplT2YuRE9VQkxFKTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5wb3NpdGlvbihwb3NpdGlvbiAqIFNpemVPZi5ET1VCTEUpOworICAgICAgICBCeXRlQnVmZmVyIGJiID0gYnl0ZUJ1ZmZlci5zbGljZSgpLm9yZGVyKGJ5dGVCdWZmZXIub3JkZXIoKSk7CisgICAgICAgIERvdWJsZUJ1ZmZlciByZXN1bHQgPSBuZXcgRG91YmxlVG9CeXRlQnVmZmVyQWRhcHRlcihiYik7CisgICAgICAgIGJ5dGVCdWZmZXIuY2xlYXIoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9GaWxlQ2hhbm5lbEltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9GaWxlQ2hhbm5lbEltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NmJhZDUxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0ZpbGVDaGFubmVsSW1wbC5qYXZhCkBAIC0wLDAgKzEsNTU1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkNsb3NlZENoYW5uZWxFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUxvY2s7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuTm9uUmVhZGFibGVDaGFubmVsRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLk5vbldyaXRhYmxlQ2hhbm5lbEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5PdmVybGFwcGluZ0ZpbGVMb2NrRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlJlYWRhYmxlQnl0ZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuV3JpdGFibGVCeXRlQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db21wYXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5Tb3J0ZWRTZXQ7CitpbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7CitpbXBvcnQgbGliY29yZS5pby5FcnJub0V4Y2VwdGlvbjsKK2ltcG9ydCBsaWJjb3JlLmlvLklvVXRpbHM7CitpbXBvcnQgbGliY29yZS5pby5MaWJjb3JlOworaW1wb3J0IGxpYmNvcmUuaW8uU3RydWN0RmxvY2s7CitpbXBvcnQgbGliY29yZS51dGlsLk11dGFibGVMb25nOworaW1wb3J0IHN0YXRpYyBsaWJjb3JlLmlvLk9zQ29uc3RhbnRzLio7CisKKy8qKgorICogT3VyIGNvbmNyZXRlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBhYnN0cmFjdCBGaWxlQ2hhbm5lbCBjbGFzcy4KKyAqLworZmluYWwgY2xhc3MgRmlsZUNoYW5uZWxJbXBsIGV4dGVuZHMgRmlsZUNoYW5uZWwgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbXBhcmF0b3I8RmlsZUxvY2s+IExPQ0tfQ09NUEFSQVRPUiA9IG5ldyBDb21wYXJhdG9yPEZpbGVMb2NrPigpIHsKKyAgICAgICAgcHVibGljIGludCBjb21wYXJlKEZpbGVMb2NrIGxvY2sxLCBGaWxlTG9jayBsb2NrMikgeworICAgICAgICAgICAgbG9uZyBwb3NpdGlvbjEgPSBsb2NrMS5wb3NpdGlvbigpOworICAgICAgICAgICAgbG9uZyBwb3NpdGlvbjIgPSBsb2NrMi5wb3NpdGlvbigpOworICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uMSA+IHBvc2l0aW9uMiA/IDEgOiAocG9zaXRpb24xIDwgcG9zaXRpb24yID8gLTEgOiAwKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBwcml2YXRlIGZpbmFsIE9iamVjdCBzdHJlYW07CisgICAgcHJpdmF0ZSBmaW5hbCBGaWxlRGVzY3JpcHRvciBmZDsKKyAgICBwcml2YXRlIGZpbmFsIGludCBtb2RlOworCisgICAgLy8gVGhlIHNldCBvZiBhY3F1aXJlZCBhbmQgcGVuZGluZyBsb2Nrcy4KKyAgICBwcml2YXRlIGZpbmFsIFNvcnRlZFNldDxGaWxlTG9jaz4gbG9ja3MgPSBuZXcgVHJlZVNldDxGaWxlTG9jaz4oTE9DS19DT01QQVJBVE9SKTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBmaWxlIGNoYW5uZWwgaW1wbGVtZW50YXRpb24gY2xhc3MgdGhhdCB3cmFwcyB0aGUgZ2l2ZW4KKyAgICAgKiBmZCBhbmQgb3BlcmF0ZXMgaW4gdGhlIHNwZWNpZmllZCBtb2RlLgorICAgICAqLworICAgIHB1YmxpYyBGaWxlQ2hhbm5lbEltcGwoT2JqZWN0IHN0cmVhbSwgRmlsZURlc2NyaXB0b3IgZmQsIGludCBtb2RlKSB7CisgICAgICAgIHRoaXMuZmQgPSBmZDsKKyAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07CisgICAgICAgIHRoaXMubW9kZSA9IG1vZGU7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrT3BlbigpIHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc09wZW4oKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENsb3NlZENoYW5uZWxFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja1JlYWRhYmxlKCkgeworICAgICAgICBpZiAoKG1vZGUgJiBPX0FDQ01PREUpID09IE9fV1JPTkxZKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9uUmVhZGFibGVDaGFubmVsRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tXcml0YWJsZSgpIHsKKyAgICAgICAgaWYgKChtb2RlICYgT19BQ0NNT0RFKSA9PSBPX1JET05MWSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vbldyaXRhYmxlQ2hhbm5lbEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgaW1wbENsb3NlQ2hhbm5lbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzdHJlYW0gaW5zdGFuY2VvZiBDbG9zZWFibGUpIHsKKyAgICAgICAgICAgICgoQ2xvc2VhYmxlKSBzdHJlYW0pLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIEZpbGVMb2NrIGJhc2ljTG9jayhsb25nIHBvc2l0aW9uLCBsb25nIHNpemUsIGJvb2xlYW4gc2hhcmVkLCBib29sZWFuIHdhaXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBhY2Nlc3NNb2RlID0gKG1vZGUgJiBPX0FDQ01PREUpOworICAgICAgICBpZiAoYWNjZXNzTW9kZSA9PSBPX1JET05MWSkgeworICAgICAgICAgICAgaWYgKCFzaGFyZWQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9uV3JpdGFibGVDaGFubmVsRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAoYWNjZXNzTW9kZSA9PSBPX1dST05MWSkgeworICAgICAgICAgICAgaWYgKHNoYXJlZCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb25SZWFkYWJsZUNoYW5uZWxFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChwb3NpdGlvbiA8IDAgfHwgc2l6ZSA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInBvc2l0aW9uPSIgKyBwb3NpdGlvbiArICIgc2l6ZT0iICsgc2l6ZSk7CisgICAgICAgIH0KKworICAgICAgICBGaWxlTG9jayBwZW5kaW5nTG9jayA9IG5ldyBGaWxlTG9ja0ltcGwodGhpcywgcG9zaXRpb24sIHNpemUsIHNoYXJlZCk7CisgICAgICAgIGFkZExvY2socGVuZGluZ0xvY2spOworCisgICAgICAgIFN0cnVjdEZsb2NrIGZsb2NrID0gbmV3IFN0cnVjdEZsb2NrKCk7CisgICAgICAgIGZsb2NrLmxfdHlwZSA9IChzaG9ydCkgKHNoYXJlZCA/IEZfUkRMQ0sgOiBGX1dSTENLKTsKKyAgICAgICAgZmxvY2subF93aGVuY2UgPSAoc2hvcnQpIFNFRUtfU0VUOworICAgICAgICBmbG9jay5sX3N0YXJ0ID0gcG9zaXRpb247CisgICAgICAgIGZsb2NrLmxfbGVuID0gdHJhbnNsYXRlTG9ja0xlbmd0aChzaXplKTsKKworICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoTGliY29yZS5vcy5mY250bEZsb2NrKGZkLCB3YWl0ID8gRl9TRVRMS1c2NCA6IEZfU0VUTEs2NCwgZmxvY2spICE9IC0xKTsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRocm93IGVycm5vRXhjZXB0aW9uLnJldGhyb3dBc0lPRXhjZXB0aW9uKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoIXN1Y2Nlc3MpIHsKKyAgICAgICAgICAgICAgICByZW1vdmVMb2NrKHBlbmRpbmdMb2NrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3VjY2VzcyA/IHBlbmRpbmdMb2NrIDogbnVsbDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBsb25nIHRyYW5zbGF0ZUxvY2tMZW5ndGgobG9uZyBieXRlQ291bnQpIHsKKyAgICAgICAgLy8gRmlsZUNoYW5uZWwgdXNlcyBMb25nLk1BWF9WQUxVRSB0byBtZWFuICJsb2NrIHRoZSB3aG9sZSBmaWxlIiB3aGVyZSBQT1NJWCB1c2VzIDAuCisgICAgICAgIHJldHVybiAoYnl0ZUNvdW50ID09IExvbmcuTUFYX1ZBTFVFKSA/IDAgOiBieXRlQ291bnQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmlsZUxvY2tJbXBsIGV4dGVuZHMgRmlsZUxvY2sgeworICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNSZWxlYXNlZCA9IGZhbHNlOworCisgICAgICAgIHB1YmxpYyBGaWxlTG9ja0ltcGwoRmlsZUNoYW5uZWwgY2hhbm5lbCwgbG9uZyBwb3NpdGlvbiwgbG9uZyBzaXplLCBib29sZWFuIHNoYXJlZCkgeworICAgICAgICAgICAgc3VwZXIoY2hhbm5lbCwgcG9zaXRpb24sIHNpemUsIHNoYXJlZCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1ZhbGlkKCkgeworICAgICAgICAgICAgcmV0dXJuICFpc1JlbGVhc2VkICYmIGNoYW5uZWwoKS5pc09wZW4oKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbGVhc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaWYgKCFjaGFubmVsKCkuaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFpc1JlbGVhc2VkKSB7CisgICAgICAgICAgICAgICAgKChGaWxlQ2hhbm5lbEltcGwpIGNoYW5uZWwoKSkucmVsZWFzZSh0aGlzKTsKKyAgICAgICAgICAgICAgICBpc1JlbGVhc2VkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBGaWxlTG9jayBsb2NrKGxvbmcgcG9zaXRpb24sIGxvbmcgc2l6ZSwgYm9vbGVhbiBzaGFyZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBGaWxlTG9jayByZXN1bHRMb2NrID0gbnVsbDsKKyAgICAgICAgeworICAgICAgICAgICAgYm9vbGVhbiBjb21wbGV0ZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYmVnaW4oKTsKKyAgICAgICAgICAgICAgICByZXN1bHRMb2NrID0gYmFzaWNMb2NrKHBvc2l0aW9uLCBzaXplLCBzaGFyZWQsIHRydWUpOworICAgICAgICAgICAgICAgIGNvbXBsZXRlZCA9IHRydWU7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGVuZChjb21wbGV0ZWQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHRMb2NrOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBGaWxlTG9jayB0cnlMb2NrKGxvbmcgcG9zaXRpb24sIGxvbmcgc2l6ZSwgYm9vbGVhbiBzaGFyZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICByZXR1cm4gYmFzaWNMb2NrKHBvc2l0aW9uLCBzaXplLCBzaGFyZWQsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb24tQVBJIG1ldGhvZCB0byByZWxlYXNlIGEgZ2l2ZW4gbG9jayBvbiBhIGZpbGUgY2hhbm5lbC4gQXNzdW1lcyB0aGF0CisgICAgICogdGhlIGxvY2sgd2lsbCBtYXJrIGl0c2VsZiBpbnZhbGlkIGFmdGVyIHN1Y2Nlc3NmdWwgdW5sb2NraW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbGVhc2UoRmlsZUxvY2sgbG9jaykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisKKyAgICAgICAgU3RydWN0RmxvY2sgZmxvY2sgPSBuZXcgU3RydWN0RmxvY2soKTsKKyAgICAgICAgZmxvY2subF90eXBlID0gKHNob3J0KSBGX1VOTENLOworICAgICAgICBmbG9jay5sX3doZW5jZSA9IChzaG9ydCkgU0VFS19TRVQ7CisgICAgICAgIGZsb2NrLmxfc3RhcnQgPSBsb2NrLnBvc2l0aW9uKCk7CisgICAgICAgIGZsb2NrLmxfbGVuID0gdHJhbnNsYXRlTG9ja0xlbmd0aChsb2NrLnNpemUoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMaWJjb3JlLm9zLmZjbnRsRmxvY2soZmQsIEZfU0VUTEtXNjQsIGZsb2NrKTsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRocm93IGVycm5vRXhjZXB0aW9uLnJldGhyb3dBc0lPRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICByZW1vdmVMb2NrKGxvY2spOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGZvcmNlKGJvb2xlYW4gbWV0YWRhdGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBpZiAoKG1vZGUgJiBPX0FDQ01PREUpICE9IE9fUkRPTkxZKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmIChtZXRhZGF0YSkgeworICAgICAgICAgICAgICAgICAgICBMaWJjb3JlLm9zLmZzeW5jKGZkKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBMaWJjb3JlLm9zLmZkYXRhc3luYyhmZCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBlcnJub0V4Y2VwdGlvbi5yZXRocm93QXNJT0V4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIE1hcHBlZEJ5dGVCdWZmZXIgbWFwKE1hcE1vZGUgbWFwTW9kZSwgbG9uZyBwb3NpdGlvbiwgbG9uZyBzaXplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgaWYgKG1hcE1vZGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXBNb2RlID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocG9zaXRpb24gPCAwIHx8IHNpemUgPCAwIHx8IHNpemUgPiBJbnRlZ2VyLk1BWF9WQUxVRSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicG9zaXRpb249IiArIHBvc2l0aW9uICsgIiBzaXplPSIgKyBzaXplKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgYWNjZXNzTW9kZSA9IChtb2RlICYgT19BQ0NNT0RFKTsKKyAgICAgICAgaWYgKGFjY2Vzc01vZGUgPT0gT19SRE9OTFkpIHsKKyAgICAgICAgICAgIGlmIChtYXBNb2RlICE9IE1hcE1vZGUuUkVBRF9PTkxZKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vbldyaXRhYmxlQ2hhbm5lbEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKGFjY2Vzc01vZGUgPT0gT19XUk9OTFkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb25SZWFkYWJsZUNoYW5uZWxFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocG9zaXRpb24gKyBzaXplID4gc2l6ZSgpKSB7CisgICAgICAgICAgICAvLyBXZSBjYW4ndCBkZWZlciB0byBGaWxlQ2hhbm5lbC50cnVuY2F0ZSBiZWNhdXNlIHRoYXQgd2lsbCBvbmx5IG1ha2UgYSBmaWxlIHNob3J0ZXIsCisgICAgICAgICAgICAvLyBhbmQgd2Ugb25seSBjYXJlIGFib3V0IG1ha2luZyBvdXIgYmFja2luZyBmaWxlIGxvbmdlciBoZXJlLgorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBMaWJjb3JlLm9zLmZ0cnVuY2F0ZShmZCwgcG9zaXRpb24gKyBzaXplKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzSU9FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBsb25nIGFsaWdubWVudCA9IHBvc2l0aW9uIC0gcG9zaXRpb24gJSBMaWJjb3JlLm9zLnN5c2NvbmYoX1NDX1BBR0VfU0laRSk7CisgICAgICAgIGludCBvZmZzZXQgPSAoaW50KSAocG9zaXRpb24gLSBhbGlnbm1lbnQpOworICAgICAgICBNZW1vcnlCbG9jayBibG9jayA9IE1lbW9yeUJsb2NrLm1tYXAoZmQsIGFsaWdubWVudCwgc2l6ZSArIG9mZnNldCwgbWFwTW9kZSk7CisgICAgICAgIHJldHVybiBuZXcgTWFwcGVkQnl0ZUJ1ZmZlckFkYXB0ZXIoYmxvY2ssIChpbnQpIHNpemUsIG9mZnNldCwgbWFwTW9kZSk7CisgICAgfQorCisgICAgcHVibGljIGxvbmcgcG9zaXRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBMaWJjb3JlLm9zLmxzZWVrKGZkLCAwTCwgU0VFS19DVVIpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzSU9FeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBGaWxlQ2hhbm5lbCBwb3NpdGlvbihsb25nIG5ld1Bvc2l0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgaWYgKG5ld1Bvc2l0aW9uIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicG9zaXRpb246ICIgKyBuZXdQb3NpdGlvbik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIExpYmNvcmUub3MubHNlZWsoZmQsIG5ld1Bvc2l0aW9uLCBTRUVLX1NFVCk7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyBlcnJub0V4Y2VwdGlvbi5yZXRocm93QXNJT0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgcmVhZChCeXRlQnVmZmVyIGJ1ZmZlciwgbG9uZyBwb3NpdGlvbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicG9zaXRpb246ICIgKyBwb3NpdGlvbik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlYWRJbXBsKGJ1ZmZlciwgcG9zaXRpb24pOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgcmVhZChCeXRlQnVmZmVyIGJ1ZmZlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHJlYWRJbXBsKGJ1ZmZlciwgLTEpOworICAgIH0KKworICAgIHByaXZhdGUgaW50IHJlYWRJbXBsKEJ5dGVCdWZmZXIgYnVmZmVyLCBsb25nIHBvc2l0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBidWZmZXIuY2hlY2tXcml0YWJsZSgpOworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgY2hlY2tSZWFkYWJsZSgpOworICAgICAgICBpZiAoIWJ1ZmZlci5oYXNSZW1haW5pbmcoKSkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgaW50IGJ5dGVzUmVhZCA9IDA7CisgICAgICAgIGJvb2xlYW4gY29tcGxldGVkID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiZWdpbigpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWFkID0gTGliY29yZS5vcy5yZWFkKGZkLCBidWZmZXIpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVhZCA9IExpYmNvcmUub3MucHJlYWQoZmQsIGJ1ZmZlciwgcG9zaXRpb24pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoYnl0ZXNSZWFkID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgYnl0ZXNSZWFkID0gLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICBpZiAoZXJybm9FeGNlcHRpb24uZXJybm8gPT0gRUFHQUlOKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFdlIGRvbid0IHRocm93IGlmIHdlIHRyeSB0byByZWFkIGZyb20gYW4gZW1wdHkgbm9uLWJsb2NraW5nIHBpcGUuCisgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVhZCA9IDA7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzSU9FeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb21wbGV0ZWQgPSB0cnVlOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZW5kKGNvbXBsZXRlZCAmJiBieXRlc1JlYWQgPj0gMCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJ5dGVzUmVhZCA+IDApIHsKKyAgICAgICAgICAgIGJ1ZmZlci5wb3NpdGlvbihidWZmZXIucG9zaXRpb24oKSArIGJ5dGVzUmVhZCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ5dGVzUmVhZDsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCB0cmFuc2ZlcklvVmVjKElvVmVjIGlvVmVjKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaW9WZWMuaW5pdCgpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGludCBieXRlc1RyYW5zZmVycmVkID0gMDsKKyAgICAgICAgYm9vbGVhbiBjb21wbGV0ZWQgPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJlZ2luKCk7CisgICAgICAgICAgICBieXRlc1RyYW5zZmVycmVkID0gaW9WZWMuZG9UcmFuc2ZlcihmZCk7CisgICAgICAgICAgICBjb21wbGV0ZWQgPSB0cnVlOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZW5kKGNvbXBsZXRlZCk7CisgICAgICAgIH0KKyAgICAgICAgaW9WZWMuZGlkVHJhbnNmZXIoYnl0ZXNUcmFuc2ZlcnJlZCk7CisgICAgICAgIHJldHVybiBieXRlc1RyYW5zZmVycmVkOworICAgIH0KKworICAgIHB1YmxpYyBsb25nIHJlYWQoQnl0ZUJ1ZmZlcltdIGJ1ZmZlcnMsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGJ1ZmZlcnMubGVuZ3RoLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBjaGVja1JlYWRhYmxlKCk7CisgICAgICAgIHJldHVybiB0cmFuc2ZlcklvVmVjKG5ldyBJb1ZlYyhidWZmZXJzLCBvZmZzZXQsIGxlbmd0aCwgSW9WZWMuRGlyZWN0aW9uLlJFQURWKSk7CisgICAgfQorCisgICAgcHVibGljIGxvbmcgc2l6ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIExpYmNvcmUub3MuZnN0YXQoZmQpLnN0X3NpemU7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyBlcnJub0V4Y2VwdGlvbi5yZXRocm93QXNJT0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGxvbmcgdHJhbnNmZXJGcm9tKFJlYWRhYmxlQnl0ZUNoYW5uZWwgc3JjLCBsb25nIHBvc2l0aW9uLCBsb25nIGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgaWYgKCFzcmMuaXNPcGVuKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tXcml0YWJsZSgpOworICAgICAgICBpZiAocG9zaXRpb24gPCAwIHx8IGNvdW50IDwgMCB8fCBjb3VudCA+IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJwb3NpdGlvbj0iICsgcG9zaXRpb24gKyAiIGNvdW50PSIgKyBjb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBvc2l0aW9uID4gc2l6ZSgpKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEFsdGhvdWdoIHNlbmRmaWxlKDIpIG9yaWdpbmFsbHkgc3VwcG9ydGVkIHdyaXRpbmcgdG8gYSByZWd1bGFyIGZpbGUuCisgICAgICAgIC8vIEluIExpbnV4IDIuNiBhbmQgbGF0ZXIsIGl0IG9ubHkgc3VwcG9ydHMgd3JpdGluZyB0byBzb2NrZXRzLgorCisgICAgICAgIC8vIElmIG91ciBzb3VyY2UgaXMgYSByZWd1bGFyIGZpbGUsIG1tYXAoMikgcmF0aGVyIHRoYW4gcmVhZGluZy4KKyAgICAgICAgLy8gQ2FsbGVycyBzaG91bGQgb25seSBiZSB1c2luZyB0cmFuc2ZlckZyb20gZm9yIGxhcmdlIHRyYW5zZmVycywKKyAgICAgICAgLy8gc28gdGhlIG1tYXAoMikgb3ZlcmhlYWQgaXNuJ3QgYSBjb25jZXJuLgorICAgICAgICBpZiAoc3JjIGluc3RhbmNlb2YgRmlsZUNoYW5uZWwpIHsKKyAgICAgICAgICAgIEZpbGVDaGFubmVsIGZpbGVTcmMgPSAoRmlsZUNoYW5uZWwpIHNyYzsKKyAgICAgICAgICAgIGxvbmcgc2l6ZSA9IGZpbGVTcmMuc2l6ZSgpOworICAgICAgICAgICAgbG9uZyBmaWxlUG9zaXRpb24gPSBmaWxlU3JjLnBvc2l0aW9uKCk7CisgICAgICAgICAgICBjb3VudCA9IE1hdGgubWluKGNvdW50LCBzaXplIC0gZmlsZVBvc2l0aW9uKTsKKyAgICAgICAgICAgIEJ5dGVCdWZmZXIgYnVmZmVyID0gZmlsZVNyYy5tYXAoTWFwTW9kZS5SRUFEX09OTFksIGZpbGVQb3NpdGlvbiwgY291bnQpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmaWxlU3JjLnBvc2l0aW9uKGZpbGVQb3NpdGlvbiArIGNvdW50KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gd3JpdGUoYnVmZmVyLCBwb3NpdGlvbik7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIE5pb1V0aWxzLmZyZWVEaXJlY3RCdWZmZXIoYnVmZmVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIEZvciBub24tZmlsZSBjaGFubmVscywgYWxsIHdlIGNhbiBkbyBpcyByZWFkIGFuZCB3cml0ZSB2aWEgdXNlcnNwYWNlLgorICAgICAgICBCeXRlQnVmZmVyIGJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoKGludCkgY291bnQpOworICAgICAgICBzcmMucmVhZChidWZmZXIpOworICAgICAgICBidWZmZXIuZmxpcCgpOworICAgICAgICByZXR1cm4gd3JpdGUoYnVmZmVyLCBwb3NpdGlvbik7CisgICAgfQorCisgICAgcHVibGljIGxvbmcgdHJhbnNmZXJUbyhsb25nIHBvc2l0aW9uLCBsb25nIGNvdW50LCBXcml0YWJsZUJ5dGVDaGFubmVsIHRhcmdldCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIGlmICghdGFyZ2V0LmlzT3BlbigpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGNoZWNrUmVhZGFibGUoKTsKKyAgICAgICAgaWYgKHRhcmdldCBpbnN0YW5jZW9mIEZpbGVDaGFubmVsSW1wbCkgeworICAgICAgICAgICAgKChGaWxlQ2hhbm5lbEltcGwpIHRhcmdldCkuY2hlY2tXcml0YWJsZSgpOworICAgICAgICB9CisgICAgICAgIGlmIChwb3NpdGlvbiA8IDAgfHwgY291bnQgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJwb3NpdGlvbj0iICsgcG9zaXRpb24gKyAiIGNvdW50PSIgKyBjb3VudCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoY291bnQgPT0gMCB8fCBwb3NpdGlvbiA+PSBzaXplKCkpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGNvdW50ID0gTWF0aC5taW4oY291bnQsIHNpemUoKSAtIHBvc2l0aW9uKTsKKworICAgICAgICAvLyBUcnkgc2VuZGZpbGUoMikgZmlyc3QuLi4KKyAgICAgICAgYm9vbGVhbiBjb21wbGV0ZWQgPSBmYWxzZTsKKyAgICAgICAgaWYgKHRhcmdldCBpbnN0YW5jZW9mIFNvY2tldENoYW5uZWxJbXBsKSB7CisgICAgICAgICAgICBGaWxlRGVzY3JpcHRvciBvdXRGZCA9ICgoU29ja2V0Q2hhbm5lbEltcGwpIHRhcmdldCkuZ2V0RkQoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYmVnaW4oKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBNdXRhYmxlTG9uZyBvZmZzZXQgPSBuZXcgTXV0YWJsZUxvbmcocG9zaXRpb24pOworICAgICAgICAgICAgICAgICAgICBsb25nIHJjID0gTGliY29yZS5vcy5zZW5kZmlsZShvdXRGZCwgZmQsIG9mZnNldCwgY291bnQpOworICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmM7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIE9TIGRvZXNuJ3Qgc3VwcG9ydCB3aGF0IHdlIGFza2VkIGZvciwgd2Ugd2FudCB0byBmYWxsIHRocm91Z2ggYW5kCisgICAgICAgICAgICAgICAgICAgIC8vIHRyeSBhIGRpZmZlcmVudCBhcHByb2FjaC4gSWYgaXQgZG9lcyBzdXBwb3J0IGl0LCBidXQgaXQgZmFpbGVkLCB3ZSdyZSBkb25lLgorICAgICAgICAgICAgICAgICAgICBpZiAoZXJybm9FeGNlcHRpb24uZXJybm8gIT0gRU5PU1lTICYmIGVycm5vRXhjZXB0aW9uLmVycm5vICE9IEVJTlZBTCkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzSU9FeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgZW5kKGNvbXBsZXRlZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gLi4uZmFsbCBiYWNrIHRvIHdyaXRlKDIpLgorICAgICAgICBCeXRlQnVmZmVyIGJ1ZmZlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidWZmZXIgPSBtYXAoTWFwTW9kZS5SRUFEX09OTFksIHBvc2l0aW9uLCBjb3VudCk7CisgICAgICAgICAgICByZXR1cm4gdGFyZ2V0LndyaXRlKGJ1ZmZlcik7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBOaW9VdGlscy5mcmVlRGlyZWN0QnVmZmVyKGJ1ZmZlcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgRmlsZUNoYW5uZWwgdHJ1bmNhdGUobG9uZyBzaXplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgaWYgKHNpemUgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzaXplOiAiICsgc2l6ZSk7CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tXcml0YWJsZSgpOworICAgICAgICBpZiAoc2l6ZSA8IHNpemUoKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBMaWJjb3JlLm9zLmZ0cnVuY2F0ZShmZCwgc2l6ZSk7CisgICAgICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgIHRocm93IGVycm5vRXhjZXB0aW9uLnJldGhyb3dBc0lPRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIGludCB3cml0ZShCeXRlQnVmZmVyIGJ1ZmZlciwgbG9uZyBwb3NpdGlvbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicG9zaXRpb246ICIgKyBwb3NpdGlvbik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHdyaXRlSW1wbChidWZmZXIsIHBvc2l0aW9uKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IHdyaXRlKEJ5dGVCdWZmZXIgYnVmZmVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gd3JpdGVJbXBsKGJ1ZmZlciwgLTEpOworICAgIH0KKworICAgIHByaXZhdGUgaW50IHdyaXRlSW1wbChCeXRlQnVmZmVyIGJ1ZmZlciwgbG9uZyBwb3NpdGlvbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIGNoZWNrV3JpdGFibGUoKTsKKyAgICAgICAgaWYgKGJ1ZmZlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImJ1ZmZlciA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFidWZmZXIuaGFzUmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGludCBieXRlc1dyaXR0ZW4gPSAwOworICAgICAgICBib29sZWFuIGNvbXBsZXRlZCA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmVnaW4oKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVzV3JpdHRlbiA9IExpYmNvcmUub3Mud3JpdGUoZmQsIGJ1ZmZlcik7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYnl0ZXNXcml0dGVuID0gTGliY29yZS5vcy5wd3JpdGUoZmQsIGJ1ZmZlciwgcG9zaXRpb24pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzSU9FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvbXBsZXRlZCA9IHRydWU7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBlbmQoY29tcGxldGVkKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYnl0ZXNXcml0dGVuID4gMCkgeworICAgICAgICAgICAgYnVmZmVyLnBvc2l0aW9uKGJ1ZmZlci5wb3NpdGlvbigpICsgYnl0ZXNXcml0dGVuKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnl0ZXNXcml0dGVuOworICAgIH0KKworICAgIHB1YmxpYyBsb25nIHdyaXRlKEJ5dGVCdWZmZXJbXSBidWZmZXJzLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXJzLmxlbmd0aCwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgY2hlY2tXcml0YWJsZSgpOworICAgICAgICByZXR1cm4gdHJhbnNmZXJJb1ZlYyhuZXcgSW9WZWMoYnVmZmVycywgb2Zmc2V0LCBsZW5ndGgsIElvVmVjLkRpcmVjdGlvbi5XUklURVYpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gY29weWluZ0luIHRydWUgaWYgd2UncmUgY29weWluZyBkYXRhIGludG8gdGhlIGJ1ZmZlcnMgKHR5cGljYWxseQorICAgICAqIGJlY2F1c2UgdGhlIGNhbGxlciBpcyBhIGZpbGUvbmV0d29yayByZWFkIG9wZXJhdGlvbiksIGZhbHNlIGlmIHdlJ3JlCisgICAgICogY29weWluZyBkYXRhIG91dCBvZiB0aGUgYnVmZmVycyAoZm9yIGEgZmlsZS9uZXR3b3JrIHdyaXRlIG9wZXJhdGlvbikuCisgICAgICovCisgICAgc3RhdGljIGludCBjYWxjdWxhdGVUb3RhbFJlbWFpbmluZyhCeXRlQnVmZmVyW10gYnVmZmVycywgaW50IG9mZnNldCwgaW50IGxlbmd0aCwgYm9vbGVhbiBjb3B5aW5nSW4pIHsKKyAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IG9mZnNldDsgaSA8IG9mZnNldCArIGxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICBjb3VudCArPSBidWZmZXJzW2ldLnJlbWFpbmluZygpOworICAgICAgICAgICAgaWYgKGNvcHlpbmdJbikgeworICAgICAgICAgICAgICAgIGJ1ZmZlcnNbaV0uY2hlY2tXcml0YWJsZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBjb3VudDsKKyAgICB9CisKKyAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3IgZ2V0RkQoKSB7CisgICAgICAgIHJldHVybiBmZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQgYSBuZXcgcGVuZGluZyBsb2NrIHRvIHRoZSBtYW5hZ2VyLiBUaHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoZSBsb2NrCisgICAgICogd291bGQgb3ZlcmxhcCBhbiBleGlzdGluZyBsb2NrLiBPbmNlIHRoZSBsb2NrIGlzIGFjcXVpcmVkIGl0IHJlbWFpbnMgaW4KKyAgICAgKiB0aGlzIHNldCBhcyBhbiBhY3F1aXJlZCBsb2NrLgorICAgICAqLworICAgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgYWRkTG9jayhGaWxlTG9jayBsb2NrKSB0aHJvd3MgT3ZlcmxhcHBpbmdGaWxlTG9ja0V4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgbG9ja0VuZCA9IGxvY2sucG9zaXRpb24oKSArIGxvY2suc2l6ZSgpOworICAgICAgICBmb3IgKEZpbGVMb2NrIGV4aXN0aW5nTG9jayA6IGxvY2tzKSB7CisgICAgICAgICAgICBpZiAoZXhpc3RpbmdMb2NrLnBvc2l0aW9uKCkgPiBsb2NrRW5kKSB7CisgICAgICAgICAgICAgICAgLy8gVGhpcywgYW5kIGFsbCByZW1haW5pbmcgbG9ja3MsIHN0YXJ0IGJleW9uZCBvdXIgZW5kIChzbworICAgICAgICAgICAgICAgIC8vIGNhbm5vdCBvdmVybGFwKS4KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChleGlzdGluZ0xvY2sub3ZlcmxhcHMobG9jay5wb3NpdGlvbigpLCBsb2NrLnNpemUoKSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgT3ZlcmxhcHBpbmdGaWxlTG9ja0V4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGxvY2tzLmFkZChsb2NrKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGFuIGFjcXVpcmVkIGxvY2sgZnJvbSB0aGUgbG9jayBtYW5hZ2VyLiBJZiB0aGUgbG9jayBkaWQgbm90IGV4aXN0CisgICAgICogaW4gdGhlIGxvY2sgbWFuYWdlciB0aGUgb3BlcmF0aW9uIGlzIGEgbm8tb3AuCisgICAgICovCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCByZW1vdmVMb2NrKEZpbGVMb2NrIGxvY2spIHsKKyAgICAgICAgbG9ja3MucmVtb3ZlKGxvY2spOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9GaWxlRGVzY3JpcHRvckNoYW5uZWwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9GaWxlRGVzY3JpcHRvckNoYW5uZWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40Zjg5OTNlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0ZpbGVEZXNjcmlwdG9yQ2hhbm5lbC5qYXZhCkBAIC0wLDAgKzEsMjYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKKworLyoqCisgKiBBbGxvd3MgYWNjZXNzIHRvIHRoZSBGaWxlRGVzY3JpcHRvciB1bmRlcmx5aW5nIGEgQ2hhbm5lbC4KKyAqLworaW50ZXJmYWNlIEZpbGVEZXNjcmlwdG9yQ2hhbm5lbCB7CisgICAgcHVibGljIEZpbGVEZXNjcmlwdG9yIGdldEZEKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vRmxvYXRBcnJheUJ1ZmZlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0Zsb2F0QXJyYXlCdWZmZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNDdlZTIxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0Zsb2F0QXJyYXlCdWZmZXIuamF2YQpAQCAtMCwwICsxLDg2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCisvKioKKyAqIEZsb2F0QXJyYXlCdWZmZXIsIFJlYWRXcml0ZUZsb2F0QXJyYXlCdWZmZXIgYW5kIFJlYWRPbmx5RmxvYXRBcnJheUJ1ZmZlcgorICogY29tcG9zZSB0aGUgaW1wbGVtZW50YXRpb24gb2YgYXJyYXkgYmFzZWQgZmxvYXQgYnVmZmVycy4KKyAqIDxwPgorICogRmxvYXRBcnJheUJ1ZmZlciBpbXBsZW1lbnRzIGFsbCB0aGUgc2hhcmVkIHJlYWRvbmx5IG1ldGhvZHMgYW5kIGlzIGV4dGVuZGVkCisgKiBieSB0aGUgb3RoZXIgdHdvIGNsYXNzZXMuCisgKiA8L3A+CisgKiA8cD4KKyAqIEFsbCBtZXRob2RzIGFyZSBtYXJrZWQgZmluYWwgZm9yIHJ1bnRpbWUgcGVyZm9ybWFuY2UuCisgKiA8L3A+CisgKgorICovCithYnN0cmFjdCBjbGFzcyBGbG9hdEFycmF5QnVmZmVyIGV4dGVuZHMgRmxvYXRCdWZmZXIgeworCisgICAgcHJvdGVjdGVkIGZpbmFsIGZsb2F0W10gYmFja2luZ0FycmF5OworCisgICAgcHJvdGVjdGVkIGZpbmFsIGludCBvZmZzZXQ7CisKKyAgICBGbG9hdEFycmF5QnVmZmVyKGZsb2F0W10gYXJyYXkpIHsKKyAgICAgICAgdGhpcyhhcnJheS5sZW5ndGgsIGFycmF5LCAwKTsKKyAgICB9CisKKyAgICBGbG9hdEFycmF5QnVmZmVyKGludCBjYXBhY2l0eSkgeworICAgICAgICB0aGlzKGNhcGFjaXR5LCBuZXcgZmxvYXRbY2FwYWNpdHldLCAwKTsKKyAgICB9CisKKyAgICBGbG9hdEFycmF5QnVmZmVyKGludCBjYXBhY2l0eSwgZmxvYXRbXSBiYWNraW5nQXJyYXksIGludCBvZmZzZXQpIHsKKyAgICAgICAgc3VwZXIoY2FwYWNpdHkpOworICAgICAgICB0aGlzLmJhY2tpbmdBcnJheSA9IGJhY2tpbmdBcnJheTsKKyAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGZsb2F0IGdldCgpIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJhY2tpbmdBcnJheVtvZmZzZXQgKyBwb3NpdGlvbisrXTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgZmxvYXQgZ2V0KGludCBpbmRleCkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4KTsKKyAgICAgICAgcmV0dXJuIGJhY2tpbmdBcnJheVtvZmZzZXQgKyBpbmRleF07CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIEZsb2F0QnVmZmVyIGdldChmbG9hdFtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGZsb2F0Q291bnQpIHsKKyAgICAgICAgaWYgKGZsb2F0Q291bnQgPiByZW1haW5pbmcoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbiwgZHN0LCBkc3RPZmZzZXQsIGZsb2F0Q291bnQpOworICAgICAgICBwb3NpdGlvbiArPSBmbG9hdENvdW50OworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0RpcmVjdCgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBCeXRlT3JkZXIgb3JkZXIoKSB7CisgICAgICAgIHJldHVybiBCeXRlT3JkZXIubmF0aXZlT3JkZXIoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9GbG9hdEJ1ZmZlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0Zsb2F0QnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWMzNjFkNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9GbG9hdEJ1ZmZlci5qYXZhCkBAIC0wLDAgKzEsNDgzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBBIGJ1ZmZlciBvZiBmbG9hdHMuCisgKiA8cD4KKyAqIEEgZmxvYXQgYnVmZmVyIGNhbiBiZSBjcmVhdGVkIGluIGVpdGhlciBvZiB0aGUgZm9sbG93aW5nIHdheXM6CisgKiA8dWw+CisgKiA8bGk+e0BsaW5rICNhbGxvY2F0ZShpbnQpIEFsbG9jYXRlfSBhIG5ldyBmbG9hdCBhcnJheSBhbmQgY3JlYXRlIGEgYnVmZmVyCisgKiBiYXNlZCBvbiBpdDs8L2xpPgorICogPGxpPntAbGluayAjd3JhcChmbG9hdFtdKSBXcmFwfSBhbiBleGlzdGluZyBmbG9hdCBhcnJheSB0byBjcmVhdGUgYSBuZXcKKyAqIGJ1ZmZlcjs8L2xpPgorICogPGxpPlVzZSB7QGxpbmsgamF2YS5uaW8uQnl0ZUJ1ZmZlciNhc0Zsb2F0QnVmZmVyKCkgQnl0ZUJ1ZmZlci5hc0Zsb2F0QnVmZmVyfQorICogdG8gY3JlYXRlIGEgZmxvYXQgYnVmZmVyIGJhc2VkIG9uIGEgYnl0ZSBidWZmZXIuPC9saT4KKyAqIDwvdWw+CisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBGbG9hdEJ1ZmZlciBleHRlbmRzIEJ1ZmZlciBpbXBsZW1lbnRzCisgICAgICAgIENvbXBhcmFibGU8RmxvYXRCdWZmZXI+IHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBmbG9hdCBidWZmZXIgYmFzZWQgb24gYSBuZXdseSBhbGxvY2F0ZWQgZmxvYXQgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2FwYWNpdHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYXBhY2l0eSBvZiB0aGUgbmV3IGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBjcmVhdGVkIGZsb2F0IGJ1ZmZlci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBjYXBhY2l0eX0gaXMgbGVzcyB0aGFuIHplcm8uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBGbG9hdEJ1ZmZlciBhbGxvY2F0ZShpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgaWYgKGNhcGFjaXR5IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgUmVhZFdyaXRlRmxvYXRBcnJheUJ1ZmZlcihjYXBhY2l0eSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBmbG9hdCBidWZmZXIgYnkgd3JhcHBpbmcgdGhlIGdpdmVuIGZsb2F0IGFycmF5LgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcworICAgICAqIHtAY29kZSB3cmFwKGFycmF5LCAwLCBhcnJheS5sZW5ndGgpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IGFycmF5IHdoaWNoIHRoZSBuZXcgYnVmZmVyIHdpbGwgYmUgYmFzZWQgb24uCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCBmbG9hdCBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBGbG9hdEJ1ZmZlciB3cmFwKGZsb2F0W10gYXJyYXkpIHsKKyAgICAgICAgcmV0dXJuIHdyYXAoYXJyYXksIDAsIGFycmF5Lmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBmbG9hdCBidWZmZXIgYnkgd3JhcHBpbmcgdGhlIGdpdmVuIGZsb2F0IGFycmF5LgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyJ3MgcG9zaXRpb24gd2lsbCBiZSB7QGNvZGUgc3RhcnR9LCBsaW1pdCB3aWxsIGJlCisgICAgICoge0Bjb2RlIHN0YXJ0ICsgZmxvYXRDb3VudH0sIGNhcGFjaXR5IHdpbGwgYmUgdGhlIGxlbmd0aCBvZiB0aGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBmbG9hdCBhcnJheSB3aGljaCB0aGUgbmV3IGJ1ZmZlciB3aWxsIGJlIGJhc2VkIG9uLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IGluZGV4LCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBhbmQgbm90IGdyZWF0ZXIgdGhhbgorICAgICAqICAgICAgICAgICAge0Bjb2RlIGFycmF5Lmxlbmd0aH0uCisgICAgICogQHBhcmFtIGZsb2F0Q291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgICAgICB7QGNvZGUgYXJyYXkubGVuZ3RoIC0gc3RhcnR9LgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgZmxvYXQgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGVpdGhlciB7QGNvZGUgc3RhcnR9IG9yIHtAY29kZSBmbG9hdENvdW50fSBpcyBpbnZhbGlkLgorICAgICAqIEBleGNlcHRpb24gTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgYXJyYXl9IGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBGbG9hdEJ1ZmZlciB3cmFwKGZsb2F0W10gYXJyYXksIGludCBzdGFydCwgaW50IGZsb2F0Q291bnQpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYXJyYXkubGVuZ3RoLCBzdGFydCwgZmxvYXRDb3VudCk7CisgICAgICAgIEZsb2F0QnVmZmVyIGJ1ZiA9IG5ldyBSZWFkV3JpdGVGbG9hdEFycmF5QnVmZmVyKGFycmF5KTsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gc3RhcnQ7CisgICAgICAgIGJ1Zi5saW1pdCA9IHN0YXJ0ICsgZmxvYXRDb3VudDsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICBGbG9hdEJ1ZmZlcihpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgc3VwZXIoMiwgY2FwYWNpdHksIG51bGwpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBmbG9hdFtdIGFycmF5KCkgeworICAgICAgICByZXR1cm4gcHJvdGVjdGVkQXJyYXkoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgaW50IGFycmF5T2Zmc2V0KCkgeworICAgICAgICByZXR1cm4gcHJvdGVjdGVkQXJyYXlPZmZzZXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcmVhZC1vbmx5IGJ1ZmZlciB0aGF0IHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSByZXR1cm5lZCBidWZmZXIgaXMgZ3VhcmFudGVlZCB0byBiZSBhIG5ldyBpbnN0YW5jZSwgZXZlbiBpZiB0aGlzCisgICAgICogYnVmZmVyIGlzIHJlYWQtb25seSBpdHNlbGYuIFRoZSBuZXcgYnVmZmVyJ3MgcG9zaXRpb24sIGxpbWl0LCBjYXBhY2l0eQorICAgICAqIGFuZCBtYXJrIGFyZSB0aGUgc2FtZSBhcyB0aGlzIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbmV3IGJ1ZmZlciBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlciwgd2hpY2ggbWVhbnMgdGhpcworICAgICAqIGJ1ZmZlcidzIGNoYW5nZSBvZiBjb250ZW50IHdpbGwgYmUgdmlzaWJsZSB0byB0aGUgbmV3IGJ1ZmZlci4gVGhlIHR3bworICAgICAqIGJ1ZmZlcidzIHBvc2l0aW9uLCBsaW1pdCBhbmQgbWFyayBhcmUgaW5kZXBlbmRlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcmVhZC1vbmx5IHZlcnNpb24gb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEZsb2F0QnVmZmVyIGFzUmVhZE9ubHlCdWZmZXIoKTsKKworICAgIC8qKgorICAgICAqIENvbXBhY3RzIHRoaXMgZmxvYXQgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSByZW1haW5pbmcgZmxvYXRzIHdpbGwgYmUgbW92ZWQgdG8gdGhlIGhlYWQgb2YgdGhlIGJ1ZmZlciwgc3RhcnRpbmcKKyAgICAgKiBmcm9tIHBvc2l0aW9uIHplcm8uIFRoZW4gdGhlIHBvc2l0aW9uIGlzIHNldCB0byB7QGNvZGUgcmVtYWluaW5nKCl9OyB0aGUKKyAgICAgKiBsaW1pdCBpcyBzZXQgdG8gY2FwYWNpdHk7IHRoZSBtYXJrIGlzIGNsZWFyZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRmxvYXRCdWZmZXIgY29tcGFjdCgpOworCisgICAgLyoqCisgICAgICogQ29tcGFyZSB0aGUgcmVtYWluaW5nIGZsb2F0cyBvZiB0aGlzIGJ1ZmZlciB0byBhbm90aGVyIGZsb2F0IGJ1ZmZlcidzCisgICAgICogcmVtYWluaW5nIGZsb2F0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdGhlckJ1ZmZlcgorICAgICAqICAgICAgICAgICAgYW5vdGhlciBmbG9hdCBidWZmZXIuCisgICAgICogQHJldHVybiBhIG5lZ2F0aXZlIHZhbHVlIGlmIHRoaXMgaXMgbGVzcyB0aGFuIHtAY29kZSBvdGhlckJ1ZmZlcn07IDAgaWYKKyAgICAgKiAgICAgICAgIHRoaXMgZXF1YWxzIHRvIHtAY29kZSBvdGhlckJ1ZmZlcn07IGEgcG9zaXRpdmUgdmFsdWUgaWYgdGhpcyBpcworICAgICAqICAgICAgICAgZ3JlYXRlciB0aGFuIHtAY29kZSBvdGhlckJ1ZmZlcn0uCisgICAgICogQGV4Y2VwdGlvbiBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgb3RoZXJCdWZmZXJ9IGlzIG5vdCBhIGZsb2F0IGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhGbG9hdEJ1ZmZlciBvdGhlckJ1ZmZlcikgeworICAgICAgICBpbnQgY29tcGFyZVJlbWFpbmluZyA9IChyZW1haW5pbmcoKSA8IG90aGVyQnVmZmVyLnJlbWFpbmluZygpKSA/IHJlbWFpbmluZygpCisgICAgICAgICAgICAgICAgOiBvdGhlckJ1ZmZlci5yZW1haW5pbmcoKTsKKyAgICAgICAgaW50IHRoaXNQb3MgPSBwb3NpdGlvbjsKKyAgICAgICAgaW50IG90aGVyUG9zID0gb3RoZXJCdWZmZXIucG9zaXRpb247CisgICAgICAgIGZsb2F0IHRoaXNGbG9hdCwgb3RoZXJGbG9hdDsKKyAgICAgICAgd2hpbGUgKGNvbXBhcmVSZW1haW5pbmcgPiAwKSB7CisgICAgICAgICAgICB0aGlzRmxvYXQgPSBnZXQodGhpc1Bvcyk7CisgICAgICAgICAgICBvdGhlckZsb2F0ID0gb3RoZXJCdWZmZXIuZ2V0KG90aGVyUG9zKTsKKyAgICAgICAgICAgIC8vIGNoZWNrcyBmb3IgZmxvYXQgYW5kIE5hTiBpbmVxdWFsaXR5CisgICAgICAgICAgICBpZiAoKHRoaXNGbG9hdCAhPSBvdGhlckZsb2F0KQorICAgICAgICAgICAgICAgICAgICAmJiAoKHRoaXNGbG9hdCA9PSB0aGlzRmxvYXQpIHx8IChvdGhlckZsb2F0ID09IG90aGVyRmxvYXQpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0aGlzRmxvYXQgPCBvdGhlckZsb2F0ID8gLTEgOiAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpc1BvcysrOworICAgICAgICAgICAgb3RoZXJQb3MrKzsKKyAgICAgICAgICAgIGNvbXBhcmVSZW1haW5pbmctLTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVtYWluaW5nKCkgLSBvdGhlckJ1ZmZlci5yZW1haW5pbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgZHVwbGljYXRlZCBidWZmZXIgdGhhdCBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZHVwbGljYXRlZCBidWZmZXIncyBwb3NpdGlvbiwgbGltaXQsIGNhcGFjaXR5IGFuZCBtYXJrIGFyZSB0aGUgc2FtZQorICAgICAqIGFzIHRoaXMgYnVmZmVyLiBUaGUgZHVwbGljYXRlZCBidWZmZXIncyByZWFkLW9ubHkgcHJvcGVydHkgYW5kIGJ5dGUgb3JkZXIKKyAgICAgKiBhcmUgc2FtZSBhcyB0aGlzIGJ1ZmZlciB0b28uCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIsIHdoaWNoIG1lYW5zIGVpdGhlcgorICAgICAqIGJ1ZmZlcidzIGNoYW5nZSBvZiBjb250ZW50IHdpbGwgYmUgdmlzaWJsZSB0byB0aGUgb3RoZXIuIFRoZSB0d28gYnVmZmVyJ3MKKyAgICAgKiBwb3NpdGlvbiwgbGltaXQgYW5kIG1hcmsgYXJlIGluZGVwZW5kZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIGR1cGxpY2F0ZWQgYnVmZmVyIHRoYXQgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEZsb2F0QnVmZmVyIGR1cGxpY2F0ZSgpOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhpcyBmbG9hdCBidWZmZXIgaXMgZXF1YWwgdG8gYW5vdGhlciBvYmplY3QuIElmIHtAY29kZQorICAgICAqIG90aGVyfSBpcyBub3QgYSB7QGNvZGUgRmxvYXRCdWZmZXJ9IHRoZW4ge0Bjb2RlIGZhbHNlfSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIDxwPlR3byBmbG9hdCBidWZmZXJzIGFyZSBlcXVhbCBpZiB0aGVpciByZW1haW5pbmcgZmxvYXRzIGFyZSBlcXVhbC4KKyAgICAgKiBQb3NpdGlvbiwgbGltaXQsIGNhcGFjaXR5IGFuZCBtYXJrIGFyZSBub3QgY29uc2lkZXJlZC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGNvbnNpZGVycyB0d28gZmxvYXRzIHtAY29kZSBhfSBhbmQge0Bjb2RlIGJ9IHRvIGJlIGVxdWFsCisgICAgICogaWYge0Bjb2RlIGEgPT0gYn0gb3IgaWYge0Bjb2RlIGF9IGFuZCB7QGNvZGUgYn0gYXJlIGJvdGgge0Bjb2RlIE5hTn0uCisgICAgICogVW5saWtlIHtAbGluayBGbG9hdCNlcXVhbHN9LCB0aGlzIG1ldGhvZCBjb25zaWRlcnMge0Bjb2RlIC0wLjB9IGFuZAorICAgICAqIHtAY29kZSArMC4wfSB0byBiZSBlcXVhbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdGhlcgorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHdpdGggdGhpcyBmbG9hdCBidWZmZXIuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBmbG9hdCBidWZmZXIgaXMgZXF1YWwgdG8ge0Bjb2RlIG90aGVyfSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKKyAgICAgICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBGbG9hdEJ1ZmZlcikpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBGbG9hdEJ1ZmZlciBvdGhlckJ1ZmZlciA9IChGbG9hdEJ1ZmZlcikgb3RoZXI7CisKKyAgICAgICAgaWYgKHJlbWFpbmluZygpICE9IG90aGVyQnVmZmVyLnJlbWFpbmluZygpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBpbnQgbXlQb3NpdGlvbiA9IHBvc2l0aW9uOworICAgICAgICBpbnQgb3RoZXJQb3NpdGlvbiA9IG90aGVyQnVmZmVyLnBvc2l0aW9uOworICAgICAgICBib29sZWFuIGVxdWFsU29GYXIgPSB0cnVlOworICAgICAgICB3aGlsZSAoZXF1YWxTb0ZhciAmJiAobXlQb3NpdGlvbiA8IGxpbWl0KSkgeworICAgICAgICAgICAgZmxvYXQgYSA9IGdldChteVBvc2l0aW9uKyspOworICAgICAgICAgICAgZmxvYXQgYiA9IG90aGVyQnVmZmVyLmdldChvdGhlclBvc2l0aW9uKyspOworICAgICAgICAgICAgZXF1YWxTb0ZhciA9IGEgPT0gYiB8fCAoYSAhPSBhICYmIGIgIT0gYik7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZXF1YWxTb0ZhcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBmbG9hdCBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQgaW5jcmVhc2VzIHRoZSBwb3NpdGlvbiBieQorICAgICAqIDEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBmbG9hdCBhdCB0aGUgY3VycmVudCBwb3NpdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSBwb3NpdGlvbiBpcyBlcXVhbCBvciBncmVhdGVyIHRoYW4gbGltaXQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGZsb2F0IGdldCgpOworCisgICAgLyoqCisgICAgICogUmVhZHMgZmxvYXRzIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24gaW50byB0aGUgc3BlY2lmaWVkIGZsb2F0IGFycmF5IGFuZAorICAgICAqIGluY3JlYXNlcyB0aGUgcG9zaXRpb24gYnkgdGhlIG51bWJlciBvZiBmbG9hdHMgcmVhZC4KKyAgICAgKiA8cD4KKyAgICAgKiBDYWxsaW5nIHRoaXMgbWV0aG9kIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMKKyAgICAgKiB7QGNvZGUgZ2V0KGRzdCwgMCwgZHN0Lmxlbmd0aCl9LgorICAgICAqCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIGRlc3RpbmF0aW9uIGZsb2F0IGFycmF5LgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgZHN0Lmxlbmd0aH0gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSByZW1haW5pbmcoKX0uCisgICAgICovCisgICAgcHVibGljIEZsb2F0QnVmZmVyIGdldChmbG9hdFtdIGRzdCkgeworICAgICAgICByZXR1cm4gZ2V0KGRzdCwgMCwgZHN0Lmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgZmxvYXRzIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24gaW50byB0aGUgc3BlY2lmaWVkIGZsb2F0IGFycmF5LAorICAgICAqIHN0YXJ0aW5nIGZyb20gdGhlIHNwZWNpZmllZCBvZmZzZXQsIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IHRoZQorICAgICAqIG51bWJlciBvZiBmbG9hdHMgcmVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgZmxvYXQgYXJyYXkuCisgICAgICogQHBhcmFtIGRzdE9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvZiB0aGUgZmxvYXQgYXJyYXksIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBubworICAgICAqICAgICAgICAgICAgZ3JlYXRlciB0aGFuIHtAY29kZSBkc3QubGVuZ3RofS4KKyAgICAgKiBAcGFyYW0gZmxvYXRDb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBmbG9hdHMgdG8gcmVhZCwgbXVzdCBiZSBubyBsZXNzIHRoYW4gemVybyBhbmQgbm8KKyAgICAgKiAgICAgICAgICAgIGdyZWF0ZXIgdGhhbiB7QGNvZGUgZHN0Lmxlbmd0aCAtIGRzdE9mZnNldH0uCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBlaXRoZXIge0Bjb2RlIGRzdE9mZnNldH0gb3Ige0Bjb2RlIGZsb2F0Q291bnR9IGlzIGludmFsaWQuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgZmxvYXRDb3VudH0gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSByZW1haW5pbmcoKX0uCisgICAgICovCisgICAgcHVibGljIEZsb2F0QnVmZmVyIGdldChmbG9hdFtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGZsb2F0Q291bnQpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoZHN0Lmxlbmd0aCwgZHN0T2Zmc2V0LCBmbG9hdENvdW50KTsKKyAgICAgICAgaWYgKGZsb2F0Q291bnQgPiByZW1haW5pbmcoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSBkc3RPZmZzZXQ7IGkgPCBkc3RPZmZzZXQgKyBmbG9hdENvdW50OyArK2kpIHsKKyAgICAgICAgICAgIGRzdFtpXSA9IGdldCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBmbG9hdCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4OyB0aGUgcG9zaXRpb24gaXMgbm90IGNoYW5nZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIGxlc3MgdGhhbiBsaW1pdC4KKyAgICAgKiBAcmV0dXJuIGEgZmxvYXQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBpbmRleCBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBmbG9hdCBnZXQoaW50IGluZGV4KTsKKworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc0FycmF5KCkgeworICAgICAgICByZXR1cm4gcHJvdGVjdGVkSGFzQXJyYXkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxjdWxhdGVzIHRoaXMgYnVmZmVyJ3MgaGFzaCBjb2RlIGZyb20gdGhlIHJlbWFpbmluZyBjaGFycy4gVGhlCisgICAgICogcG9zaXRpb24sIGxpbWl0LCBjYXBhY2l0eSBhbmQgbWFyayBkb24ndCBhZmZlY3QgdGhlIGhhc2ggY29kZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZSBjYWxjdWxhdGVkIGZyb20gdGhlIHJlbWFpbmluZyBmbG9hdHMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IG15UG9zaXRpb24gPSBwb3NpdGlvbjsKKyAgICAgICAgaW50IGhhc2ggPSAwOworICAgICAgICB3aGlsZSAobXlQb3NpdGlvbiA8IGxpbWl0KSB7CisgICAgICAgICAgICBoYXNoID0gaGFzaCArIEZsb2F0LmZsb2F0VG9JbnRCaXRzKGdldChteVBvc2l0aW9uKyspKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIGJ1ZmZlciBpcyBkaXJlY3QuIEEgZGlyZWN0IGJ1ZmZlciB3aWxsIHRyeSBpdHMKKyAgICAgKiBiZXN0IHRvIHRha2UgYWR2YW50YWdlIG9mIG5hdGl2ZSBtZW1vcnkgQVBJcyBhbmQgaXQgbWF5IG5vdCBzdGF5IGluIHRoZQorICAgICAqIEphdmEgaGVhcCwgc28gaXQgaXMgbm90IGFmZmVjdGVkIGJ5IGdhcmJhZ2UgY29sbGVjdGlvbi4KKyAgICAgKiA8cD4KKyAgICAgKiBBIGZsb2F0IGJ1ZmZlciBpcyBkaXJlY3QgaWYgaXQgaXMgYmFzZWQgb24gYSBieXRlIGJ1ZmZlciBhbmQgdGhlIGJ5dGUKKyAgICAgKiBidWZmZXIgaXMgZGlyZWN0LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBidWZmZXIgaXMgZGlyZWN0LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc0RpcmVjdCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYnl0ZSBvcmRlciB1c2VkIGJ5IHRoaXMgYnVmZmVyIHdoZW4gY29udmVydGluZyBmbG9hdHMgZnJvbS90bworICAgICAqIGJ5dGVzLgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgYnVmZmVyIGlzIG5vdCBiYXNlZCBvbiBhIGJ5dGUgYnVmZmVyLCB0aGVuIGFsd2F5cyByZXR1cm4gdGhlCisgICAgICogcGxhdGZvcm0ncyBuYXRpdmUgYnl0ZSBvcmRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgb3JkZXIgdXNlZCBieSB0aGlzIGJ1ZmZlciB3aGVuIGNvbnZlcnRpbmcgZmxvYXRzIGZyb20vdG8KKyAgICAgKiAgICAgICAgIGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCeXRlT3JkZXIgb3JkZXIoKTsKKworICAgIC8qKgorICAgICAqIENoaWxkIGNsYXNzIGltcGxlbWVudHMgdGhpcyBtZXRob2QgdG8gcmVhbGl6ZSB7QGNvZGUgYXJyYXkoKX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHNlZSB7QGNvZGUgYXJyYXkoKX0KKyAgICAgKi8KKyAgICBhYnN0cmFjdCBmbG9hdFtdIHByb3RlY3RlZEFycmF5KCk7CisKKyAgICAvKioKKyAgICAgKiBDaGlsZCBjbGFzcyBpbXBsZW1lbnRzIHRoaXMgbWV0aG9kIHRvIHJlYWxpemUge0Bjb2RlIGFycmF5T2Zmc2V0KCl9LgorICAgICAqCisgICAgICogQHJldHVybiBzZWUge0Bjb2RlIGFycmF5T2Zmc2V0KCl9CisgICAgICovCisgICAgYWJzdHJhY3QgaW50IHByb3RlY3RlZEFycmF5T2Zmc2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBDaGlsZCBjbGFzcyBpbXBsZW1lbnRzIHRoaXMgbWV0aG9kIHRvIHJlYWxpemUge0Bjb2RlIGhhc0FycmF5KCl9LgorICAgICAqCisgICAgICogQHJldHVybiBzZWUge0Bjb2RlIGhhc0FycmF5KCl9CisgICAgICovCisgICAgYWJzdHJhY3QgYm9vbGVhbiBwcm90ZWN0ZWRIYXNBcnJheSgpOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBnaXZlbiBmbG9hdCB0byB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQgaW5jcmVhc2VzIHRoZSBwb3NpdGlvbgorICAgICAqIGJ5IDEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZgorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IHRvIHdyaXRlLgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHBvc2l0aW9uIGlzIGVxdWFsIG9yIGdyZWF0ZXIgdGhhbiBsaW1pdC4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEZsb2F0QnVmZmVyIHB1dChmbG9hdCBmKTsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyBmbG9hdHMgZnJvbSB0aGUgZ2l2ZW4gZmxvYXQgYXJyYXkgdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gYW5kCisgICAgICogaW5jcmVhc2VzIHRoZSBwb3NpdGlvbiBieSB0aGUgbnVtYmVyIG9mIGZsb2F0cyB3cml0dGVuLgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcworICAgICAqIHtAY29kZSBwdXQoc3JjLCAwLCBzcmMubGVuZ3RoKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGZsb2F0IGFycmF5LgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSByZW1haW5pbmcoKX0gaXMgbGVzcyB0aGFuIHtAY29kZSBzcmMubGVuZ3RofS4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEZsb2F0QnVmZmVyIHB1dChmbG9hdFtdIHNyYykgeworICAgICAgICByZXR1cm4gcHV0KHNyYywgMCwgc3JjLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGZsb2F0cyBmcm9tIHRoZSBnaXZlbiBmbG9hdCBhcnJheSwgc3RhcnRpbmcgZnJvbSB0aGUgc3BlY2lmaWVkCisgICAgICogb2Zmc2V0LCB0byB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQgaW5jcmVhc2VzIHRoZSBwb3NpdGlvbiBieSB0aGUgbnVtYmVyCisgICAgICogb2YgZmxvYXRzIHdyaXR0ZW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGZsb2F0IGFycmF5LgorICAgICAqIEBwYXJhbSBzcmNPZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgb2YgZmxvYXQgYXJyYXksIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QKKyAgICAgKiAgICAgICAgICAgIGdyZWF0ZXIgdGhhbiB7QGNvZGUgc3JjLmxlbmd0aH0uCisgICAgICogQHBhcmFtIGZsb2F0Q291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgZmxvYXRzIHRvIHdyaXRlLCBtdXN0IGJlIG5vIGxlc3MgdGhhbiB6ZXJvIGFuZAorICAgICAqICAgICAgICAgICAgbm8gZ3JlYXRlciB0aGFuIHtAY29kZSBzcmMubGVuZ3RoIC0gc3JjT2Zmc2V0fS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgcmVtYWluaW5nKCl9IGlzIGxlc3MgdGhhbiB7QGNvZGUgZmxvYXRDb3VudH0uCisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgZWl0aGVyIHtAY29kZSBzcmNPZmZzZXR9IG9yIHtAY29kZSBmbG9hdENvdW50fSBpcyBpbnZhbGlkLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmxvYXRCdWZmZXIgcHV0KGZsb2F0W10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgZmxvYXRDb3VudCkgeworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChzcmMubGVuZ3RoLCBzcmNPZmZzZXQsIGZsb2F0Q291bnQpOworICAgICAgICBpZiAoZmxvYXRDb3VudCA+IHJlbWFpbmluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gc3JjT2Zmc2V0OyBpIDwgc3JjT2Zmc2V0ICsgZmxvYXRDb3VudDsgKytpKSB7CisgICAgICAgICAgICBwdXQoc3JjW2ldKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYWxsIHRoZSByZW1haW5pbmcgZmxvYXRzIG9mIHRoZSB7QGNvZGUgc3JjfSBmbG9hdCBidWZmZXIgdG8gdGhpcworICAgICAqIGJ1ZmZlcidzIGN1cnJlbnQgcG9zaXRpb24sIGFuZCBpbmNyZWFzZXMgYm90aCBidWZmZXJzJyBwb3NpdGlvbiBieSB0aGUKKyAgICAgKiBudW1iZXIgb2YgZmxvYXRzIGNvcGllZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgZmxvYXQgYnVmZmVyLgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzcmMucmVtYWluaW5nKCl9IGlzIGdyZWF0ZXIgdGhhbiB0aGlzIGJ1ZmZlcidzCisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIHJlbWFpbmluZygpfS4KKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzcmN9IGlzIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmxvYXRCdWZmZXIgcHV0KEZsb2F0QnVmZmVyIHNyYykgeworICAgICAgICBpZiAoc3JjID09IHRoaXMpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3JjLnJlbWFpbmluZygpID4gcmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGZsb2F0W10gY29udGVudHMgPSBuZXcgZmxvYXRbc3JjLnJlbWFpbmluZygpXTsKKyAgICAgICAgc3JjLmdldChjb250ZW50cyk7CisgICAgICAgIHB1dChjb250ZW50cyk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGZsb2F0IHRvIHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyBidWZmZXI7IHRoZSBwb3NpdGlvbiBpcyBub3QKKyAgICAgKiBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBsZXNzIHRoYW4gdGhlIGxpbWl0LgorICAgICAqIEBwYXJhbSBmCisgICAgICogICAgICAgICAgICB0aGUgZmxvYXQgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBpbmRleCBpcyBpbnZhbGlkLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRmxvYXRCdWZmZXIgcHV0KGludCBpbmRleCwgZmxvYXQgZik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc2xpY2VkIGJ1ZmZlciB0aGF0IHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBzbGljZWQgYnVmZmVyJ3MgY2FwYWNpdHkgd2lsbCBiZSB0aGlzIGJ1ZmZlcidzIHtAY29kZSByZW1haW5pbmcoKX0sCisgICAgICogYW5kIGl0cyB6ZXJvIHBvc2l0aW9uIHdpbGwgY29ycmVzcG9uZCB0byB0aGlzIGJ1ZmZlcidzIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogVGhlIG5ldyBidWZmZXIncyBwb3NpdGlvbiB3aWxsIGJlIDAsIGxpbWl0IHdpbGwgYmUgaXRzIGNhcGFjaXR5LCBhbmQgaXRzCisgICAgICogbWFyayBpcyBjbGVhcmVkLiBUaGUgbmV3IGJ1ZmZlcidzIHJlYWQtb25seSBwcm9wZXJ0eSBhbmQgYnl0ZSBvcmRlciBhcmUKKyAgICAgKiBzYW1lIGFzIHRoaXMgYnVmZmVyJ3MuCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIsIHdoaWNoIG1lYW5zIGVpdGhlcgorICAgICAqIGJ1ZmZlcidzIGNoYW5nZSBvZiBjb250ZW50IHdpbGwgYmUgdmlzaWJsZSB0byB0aGUgb3RoZXIuIFRoZSB0d28gYnVmZmVyJ3MKKyAgICAgKiBwb3NpdGlvbiwgbGltaXQgYW5kIG1hcmsgYXJlIGluZGVwZW5kZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIHNsaWNlZCBidWZmZXIgdGhhdCBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRmxvYXRCdWZmZXIgc2xpY2UoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9GbG9hdFRvQnl0ZUJ1ZmZlckFkYXB0ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9GbG9hdFRvQnl0ZUJ1ZmZlckFkYXB0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNjc0ZmUzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0Zsb2F0VG9CeXRlQnVmZmVyQWRhcHRlci5qYXZhCkBAIC0wLDAgKzEsMTgxIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCitpbXBvcnQgbGliY29yZS5pby5TaXplT2Y7CisKKy8qKgorICogVGhpcyBjbGFzcyB3cmFwcyBhIGJ5dGUgYnVmZmVyIHRvIGJlIGEgZmxvYXQgYnVmZmVyLgorICogPHA+CisgKiBJbXBsZW1lbnRhdGlvbiBub3RpY2U6CisgKiA8dWw+CisgKiA8bGk+QWZ0ZXIgYSBieXRlIGJ1ZmZlciBpbnN0YW5jZSBpcyB3cmFwcGVkLCBpdCBiZWNvbWVzIHByaXZhdGVseSBvd25lZCBieQorICogdGhlIGFkYXB0ZXIuIEl0IG11c3QgTk9UIGJlIGFjY2Vzc2VkIG91dHNpZGUgdGhlIGFkYXB0ZXIgYW55IG1vcmUuPC9saT4KKyAqIDxsaT5UaGUgYnl0ZSBidWZmZXIncyBwb3NpdGlvbiBhbmQgbGltaXQgYXJlIE5PVCBsaW5rZWQgd2l0aCB0aGUgYWRhcHRlci4KKyAqIFRoZSBhZGFwdGVyIGV4dGVuZHMgQnVmZmVyLCB0aHVzIGhhcyBpdHMgb3duIHBvc2l0aW9uIGFuZCBsaW1pdC48L2xpPgorICogPC91bD4KKyAqIDwvcD4KKyAqLworZmluYWwgY2xhc3MgRmxvYXRUb0J5dGVCdWZmZXJBZGFwdGVyIGV4dGVuZHMgRmxvYXRCdWZmZXIgeworCisgICAgcHJpdmF0ZSBmaW5hbCBCeXRlQnVmZmVyIGJ5dGVCdWZmZXI7CisKKyAgICBzdGF0aWMgRmxvYXRCdWZmZXIgYXNGbG9hdEJ1ZmZlcihCeXRlQnVmZmVyIGJ5dGVCdWZmZXIpIHsKKyAgICAgICAgQnl0ZUJ1ZmZlciBzbGljZSA9IGJ5dGVCdWZmZXIuc2xpY2UoKTsKKyAgICAgICAgc2xpY2Uub3JkZXIoYnl0ZUJ1ZmZlci5vcmRlcigpKTsKKyAgICAgICAgcmV0dXJuIG5ldyBGbG9hdFRvQnl0ZUJ1ZmZlckFkYXB0ZXIoc2xpY2UpOworICAgIH0KKworICAgIEZsb2F0VG9CeXRlQnVmZmVyQWRhcHRlcihCeXRlQnVmZmVyIGJ5dGVCdWZmZXIpIHsKKyAgICAgICAgc3VwZXIoYnl0ZUJ1ZmZlci5jYXBhY2l0eSgpIC8gU2l6ZU9mLkZMT0FUKTsKKyAgICAgICAgdGhpcy5ieXRlQnVmZmVyID0gYnl0ZUJ1ZmZlcjsKKyAgICAgICAgdGhpcy5ieXRlQnVmZmVyLmNsZWFyKCk7CisgICAgICAgIHRoaXMuZWZmZWN0aXZlRGlyZWN0QWRkcmVzcyA9IGJ5dGVCdWZmZXIuZWZmZWN0aXZlRGlyZWN0QWRkcmVzczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRmxvYXRCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpIHsKKyAgICAgICAgRmxvYXRUb0J5dGVCdWZmZXJBZGFwdGVyIGJ1ZiA9IG5ldyBGbG9hdFRvQnl0ZUJ1ZmZlckFkYXB0ZXIoYnl0ZUJ1ZmZlci5hc1JlYWRPbmx5QnVmZmVyKCkpOworICAgICAgICBidWYubGltaXQgPSBsaW1pdDsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gcG9zaXRpb247CisgICAgICAgIGJ1Zi5tYXJrID0gbWFyazsKKyAgICAgICAgYnVmLmJ5dGVCdWZmZXIub3JkZXIgPSBieXRlQnVmZmVyLm9yZGVyOworICAgICAgICByZXR1cm4gYnVmOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGbG9hdEJ1ZmZlciBjb21wYWN0KCkgeworICAgICAgICBpZiAoYnl0ZUJ1ZmZlci5pc1JlYWRPbmx5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGJ5dGVCdWZmZXIubGltaXQobGltaXQgKiBTaXplT2YuRkxPQVQpOworICAgICAgICBieXRlQnVmZmVyLnBvc2l0aW9uKHBvc2l0aW9uICogU2l6ZU9mLkZMT0FUKTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5jb21wYWN0KCk7CisgICAgICAgIGJ5dGVCdWZmZXIuY2xlYXIoKTsKKyAgICAgICAgcG9zaXRpb24gPSBsaW1pdCAtIHBvc2l0aW9uOworICAgICAgICBsaW1pdCA9IGNhcGFjaXR5OworICAgICAgICBtYXJrID0gVU5TRVRfTUFSSzsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZsb2F0QnVmZmVyIGR1cGxpY2F0ZSgpIHsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYiA9IGJ5dGVCdWZmZXIuZHVwbGljYXRlKCkub3JkZXIoYnl0ZUJ1ZmZlci5vcmRlcigpKTsKKyAgICAgICAgRmxvYXRUb0J5dGVCdWZmZXJBZGFwdGVyIGJ1ZiA9IG5ldyBGbG9hdFRvQnl0ZUJ1ZmZlckFkYXB0ZXIoYmIpOworICAgICAgICBidWYubGltaXQgPSBsaW1pdDsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gcG9zaXRpb247CisgICAgICAgIGJ1Zi5tYXJrID0gbWFyazsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXQgZ2V0KCkgeworICAgICAgICBpZiAocG9zaXRpb24gPT0gbGltaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnl0ZUJ1ZmZlci5nZXRGbG9hdChwb3NpdGlvbisrICogU2l6ZU9mLkZMT0FUKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXQgZ2V0KGludCBpbmRleCkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4KTsKKyAgICAgICAgcmV0dXJuIGJ5dGVCdWZmZXIuZ2V0RmxvYXQoaW5kZXggKiBTaXplT2YuRkxPQVQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGbG9hdEJ1ZmZlciBnZXQoZmxvYXRbXSBkc3QsIGludCBkc3RPZmZzZXQsIGludCBmbG9hdENvdW50KSB7CisgICAgICAgIGJ5dGVCdWZmZXIubGltaXQobGltaXQgKiBTaXplT2YuRkxPQVQpOworICAgICAgICBieXRlQnVmZmVyLnBvc2l0aW9uKHBvc2l0aW9uICogU2l6ZU9mLkZMT0FUKTsKKyAgICAgICAgaWYgKGJ5dGVCdWZmZXIgaW5zdGFuY2VvZiBEaXJlY3RCeXRlQnVmZmVyKSB7CisgICAgICAgICAgICAoKERpcmVjdEJ5dGVCdWZmZXIpIGJ5dGVCdWZmZXIpLmdldChkc3QsIGRzdE9mZnNldCwgZmxvYXRDb3VudCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAoKEhlYXBCeXRlQnVmZmVyKSBieXRlQnVmZmVyKS5nZXQoZHN0LCBkc3RPZmZzZXQsIGZsb2F0Q291bnQpOworICAgICAgICB9CisgICAgICAgIHRoaXMucG9zaXRpb24gKz0gZmxvYXRDb3VudDsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNEaXJlY3QoKSB7CisgICAgICAgIHJldHVybiBieXRlQnVmZmVyLmlzRGlyZWN0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNSZWFkT25seSgpIHsKKyAgICAgICAgcmV0dXJuIGJ5dGVCdWZmZXIuaXNSZWFkT25seSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlT3JkZXIgb3JkZXIoKSB7CisgICAgICAgIHJldHVybiBieXRlQnVmZmVyLm9yZGVyKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGZsb2F0W10gcHJvdGVjdGVkQXJyYXkoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgcHJvdGVjdGVkQXJyYXlPZmZzZXQoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBib29sZWFuIHByb3RlY3RlZEhhc0FycmF5KCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZsb2F0QnVmZmVyIHB1dChmbG9hdCBjKSB7CisgICAgICAgIGlmIChwb3NpdGlvbiA9PSBsaW1pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZUJ1ZmZlci5wdXRGbG9hdChwb3NpdGlvbisrICogU2l6ZU9mLkZMT0FULCBjKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZsb2F0QnVmZmVyIHB1dChpbnQgaW5kZXgsIGZsb2F0IGMpIHsKKyAgICAgICAgY2hlY2tJbmRleChpbmRleCk7CisgICAgICAgIGJ5dGVCdWZmZXIucHV0RmxvYXQoaW5kZXggKiBTaXplT2YuRkxPQVQsIGMpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRmxvYXRCdWZmZXIgcHV0KGZsb2F0W10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgZmxvYXRDb3VudCkgeworICAgICAgICBieXRlQnVmZmVyLmxpbWl0KGxpbWl0ICogU2l6ZU9mLkZMT0FUKTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5wb3NpdGlvbihwb3NpdGlvbiAqIFNpemVPZi5GTE9BVCk7CisgICAgICAgIGlmIChieXRlQnVmZmVyIGluc3RhbmNlb2YgUmVhZFdyaXRlRGlyZWN0Qnl0ZUJ1ZmZlcikgeworICAgICAgICAgICAgKChSZWFkV3JpdGVEaXJlY3RCeXRlQnVmZmVyKSBieXRlQnVmZmVyKS5wdXQoc3JjLCBzcmNPZmZzZXQsIGZsb2F0Q291bnQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgKChSZWFkV3JpdGVIZWFwQnl0ZUJ1ZmZlcikgYnl0ZUJ1ZmZlcikucHV0KHNyYywgc3JjT2Zmc2V0LCBmbG9hdENvdW50KTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnBvc2l0aW9uICs9IGZsb2F0Q291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGbG9hdEJ1ZmZlciBzbGljZSgpIHsKKyAgICAgICAgYnl0ZUJ1ZmZlci5saW1pdChsaW1pdCAqIFNpemVPZi5GTE9BVCk7CisgICAgICAgIGJ5dGVCdWZmZXIucG9zaXRpb24ocG9zaXRpb24gKiBTaXplT2YuRkxPQVQpOworICAgICAgICBCeXRlQnVmZmVyIGJiID0gYnl0ZUJ1ZmZlci5zbGljZSgpLm9yZGVyKGJ5dGVCdWZmZXIub3JkZXIoKSk7CisgICAgICAgIEZsb2F0QnVmZmVyIHJlc3VsdCA9IG5ldyBGbG9hdFRvQnl0ZUJ1ZmZlckFkYXB0ZXIoYmIpOworICAgICAgICBieXRlQnVmZmVyLmNsZWFyKCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vSGVhcEJ5dGVCdWZmZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9IZWFwQnl0ZUJ1ZmZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZiNjVlYzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vSGVhcEJ5dGVCdWZmZXIuamF2YQpAQCAtMCwwICsxLDIxMSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworaW1wb3J0IGxpYmNvcmUuaW8uU2l6ZU9mOworaW1wb3J0IGxpYmNvcmUuaW8uTWVtb3J5OworCisvKioKKyAqIEhlYXBCeXRlQnVmZmVyLCBSZWFkV3JpdGVIZWFwQnl0ZUJ1ZmZlciBhbmQgUmVhZE9ubHlIZWFwQnl0ZUJ1ZmZlciBjb21wb3NlCisgKiB0aGUgaW1wbGVtZW50YXRpb24gb2YgYXJyYXkgYmFzZWQgYnl0ZSBidWZmZXJzLgorICogPHA+CisgKiBIZWFwQnl0ZUJ1ZmZlciBpbXBsZW1lbnRzIGFsbCB0aGUgc2hhcmVkIHJlYWRvbmx5IG1ldGhvZHMgYW5kIGlzIGV4dGVuZGVkIGJ5CisgKiB0aGUgb3RoZXIgdHdvIGNsYXNzZXMuCisgKiA8L3A+CisgKiA8cD4KKyAqIEFsbCBtZXRob2RzIGFyZSBtYXJrZWQgZmluYWwgZm9yIHJ1bnRpbWUgcGVyZm9ybWFuY2UuCisgKiA8L3A+CisgKgorICovCithYnN0cmFjdCBjbGFzcyBIZWFwQnl0ZUJ1ZmZlciBleHRlbmRzIEJhc2VCeXRlQnVmZmVyIHsKKworICAgIC8qKgorICAgICAqIFRoZXNlIGZpZWxkcyBhcmUgbm9uLXByaXZhdGUgZm9yIE5pb1V0aWxzLnVuc2FmZUFycmF5LgorICAgICAqLworICAgIGZpbmFsIGJ5dGVbXSBiYWNraW5nQXJyYXk7CisgICAgZmluYWwgaW50IG9mZnNldDsKKworICAgIEhlYXBCeXRlQnVmZmVyKGJ5dGVbXSBiYWNraW5nQXJyYXkpIHsKKyAgICAgICAgdGhpcyhiYWNraW5nQXJyYXksIGJhY2tpbmdBcnJheS5sZW5ndGgsIDApOworICAgIH0KKworICAgIEhlYXBCeXRlQnVmZmVyKGludCBjYXBhY2l0eSkgeworICAgICAgICB0aGlzKG5ldyBieXRlW2NhcGFjaXR5XSwgY2FwYWNpdHksIDApOworICAgIH0KKworICAgIEhlYXBCeXRlQnVmZmVyKGJ5dGVbXSBiYWNraW5nQXJyYXksIGludCBjYXBhY2l0eSwgaW50IG9mZnNldCkgeworICAgICAgICBzdXBlcihjYXBhY2l0eSwgbnVsbCk7CisgICAgICAgIHRoaXMuYmFja2luZ0FycmF5ID0gYmFja2luZ0FycmF5OworICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDsKKyAgICAgICAgaWYgKG9mZnNldCArIGNhcGFjaXR5ID4gYmFja2luZ0FycmF5Lmxlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oImJhY2tpbmdBcnJheS5sZW5ndGg9IiArIGJhY2tpbmdBcnJheS5sZW5ndGggKworICAgICAgICAgICAgICAgICAgICAiLCBjYXBhY2l0eT0iICsgY2FwYWNpdHkgKyAiLCBvZmZzZXQ9IiArIG9mZnNldCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgQnl0ZUJ1ZmZlciBnZXQoYnl0ZVtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGJ5dGVDb3VudCkgeworICAgICAgICBjaGVja0dldEJvdW5kcygxLCBkc3QubGVuZ3RoLCBkc3RPZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbiwgZHN0LCBkc3RPZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIHBvc2l0aW9uICs9IGJ5dGVDb3VudDsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgZmluYWwgdm9pZCBnZXQoY2hhcltdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGNoYXJDb3VudCkgeworICAgICAgICBpbnQgYnl0ZUNvdW50ID0gY2hlY2tHZXRCb3VuZHMoU2l6ZU9mLkNIQVIsIGRzdC5sZW5ndGgsIGRzdE9mZnNldCwgY2hhckNvdW50KTsKKyAgICAgICAgTWVtb3J5LnVuc2FmZUJ1bGtHZXQoZHN0LCBkc3RPZmZzZXQsIGJ5dGVDb3VudCwgYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbiwgU2l6ZU9mLkNIQVIsIG9yZGVyLm5lZWRzU3dhcCk7CisgICAgICAgIHBvc2l0aW9uICs9IGJ5dGVDb3VudDsKKyAgICB9CisKKyAgICBmaW5hbCB2b2lkIGdldChkb3VibGVbXSBkc3QsIGludCBkc3RPZmZzZXQsIGludCBkb3VibGVDb3VudCkgeworICAgICAgICBpbnQgYnl0ZUNvdW50ID0gY2hlY2tHZXRCb3VuZHMoU2l6ZU9mLkRPVUJMRSwgZHN0Lmxlbmd0aCwgZHN0T2Zmc2V0LCBkb3VibGVDb3VudCk7CisgICAgICAgIE1lbW9yeS51bnNhZmVCdWxrR2V0KGRzdCwgZHN0T2Zmc2V0LCBieXRlQ291bnQsIGJhY2tpbmdBcnJheSwgb2Zmc2V0ICsgcG9zaXRpb24sIFNpemVPZi5ET1VCTEUsIG9yZGVyLm5lZWRzU3dhcCk7CisgICAgICAgIHBvc2l0aW9uICs9IGJ5dGVDb3VudDsKKyAgICB9CisKKyAgICBmaW5hbCB2b2lkIGdldChmbG9hdFtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGZsb2F0Q291bnQpIHsKKyAgICAgICAgaW50IGJ5dGVDb3VudCA9IGNoZWNrR2V0Qm91bmRzKFNpemVPZi5GTE9BVCwgZHN0Lmxlbmd0aCwgZHN0T2Zmc2V0LCBmbG9hdENvdW50KTsKKyAgICAgICAgTWVtb3J5LnVuc2FmZUJ1bGtHZXQoZHN0LCBkc3RPZmZzZXQsIGJ5dGVDb3VudCwgYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbiwgU2l6ZU9mLkZMT0FULCBvcmRlci5uZWVkc1N3YXApOworICAgICAgICBwb3NpdGlvbiArPSBieXRlQ291bnQ7CisgICAgfQorCisgICAgZmluYWwgdm9pZCBnZXQoaW50W10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgaW50Q291bnQpIHsKKyAgICAgICAgaW50IGJ5dGVDb3VudCA9IGNoZWNrR2V0Qm91bmRzKFNpemVPZi5JTlQsIGRzdC5sZW5ndGgsIGRzdE9mZnNldCwgaW50Q291bnQpOworICAgICAgICBNZW1vcnkudW5zYWZlQnVsa0dldChkc3QsIGRzdE9mZnNldCwgYnl0ZUNvdW50LCBiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uLCBTaXplT2YuSU5ULCBvcmRlci5uZWVkc1N3YXApOworICAgICAgICBwb3NpdGlvbiArPSBieXRlQ291bnQ7CisgICAgfQorCisgICAgZmluYWwgdm9pZCBnZXQobG9uZ1tdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGxvbmdDb3VudCkgeworICAgICAgICBpbnQgYnl0ZUNvdW50ID0gY2hlY2tHZXRCb3VuZHMoU2l6ZU9mLkxPTkcsIGRzdC5sZW5ndGgsIGRzdE9mZnNldCwgbG9uZ0NvdW50KTsKKyAgICAgICAgTWVtb3J5LnVuc2FmZUJ1bGtHZXQoZHN0LCBkc3RPZmZzZXQsIGJ5dGVDb3VudCwgYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbiwgU2l6ZU9mLkxPTkcsIG9yZGVyLm5lZWRzU3dhcCk7CisgICAgICAgIHBvc2l0aW9uICs9IGJ5dGVDb3VudDsKKyAgICB9CisKKyAgICBmaW5hbCB2b2lkIGdldChzaG9ydFtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IHNob3J0Q291bnQpIHsKKyAgICAgICAgaW50IGJ5dGVDb3VudCA9IGNoZWNrR2V0Qm91bmRzKFNpemVPZi5TSE9SVCwgZHN0Lmxlbmd0aCwgZHN0T2Zmc2V0LCBzaG9ydENvdW50KTsKKyAgICAgICAgTWVtb3J5LnVuc2FmZUJ1bGtHZXQoZHN0LCBkc3RPZmZzZXQsIGJ5dGVDb3VudCwgYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbiwgU2l6ZU9mLlNIT1JULCBvcmRlci5uZWVkc1N3YXApOworICAgICAgICBwb3NpdGlvbiArPSBieXRlQ291bnQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGJ5dGUgZ2V0KCkgeworICAgICAgICBpZiAocG9zaXRpb24gPT0gbGltaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYmFja2luZ0FycmF5W29mZnNldCArIHBvc2l0aW9uKytdOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBieXRlIGdldChpbnQgaW5kZXgpIHsKKyAgICAgICAgY2hlY2tJbmRleChpbmRleCk7CisgICAgICAgIHJldHVybiBiYWNraW5nQXJyYXlbb2Zmc2V0ICsgaW5kZXhdOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBjaGFyIGdldENoYXIoKSB7CisgICAgICAgIGludCBuZXdQb3NpdGlvbiA9IHBvc2l0aW9uICsgU2l6ZU9mLkNIQVI7CisgICAgICAgIGlmIChuZXdQb3NpdGlvbiA+IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgY2hhciByZXN1bHQgPSAoY2hhcikgTWVtb3J5LnBlZWtTaG9ydChiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uLCBvcmRlcik7CisgICAgICAgIHBvc2l0aW9uID0gbmV3UG9zaXRpb247CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGNoYXIgZ2V0Q2hhcihpbnQgaW5kZXgpIHsKKyAgICAgICAgY2hlY2tJbmRleChpbmRleCwgU2l6ZU9mLkNIQVIpOworICAgICAgICByZXR1cm4gKGNoYXIpIE1lbW9yeS5wZWVrU2hvcnQoYmFja2luZ0FycmF5LCBvZmZzZXQgKyBpbmRleCwgb3JkZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBkb3VibGUgZ2V0RG91YmxlKCkgeworICAgICAgICByZXR1cm4gRG91YmxlLmxvbmdCaXRzVG9Eb3VibGUoZ2V0TG9uZygpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgZG91YmxlIGdldERvdWJsZShpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIERvdWJsZS5sb25nQml0c1RvRG91YmxlKGdldExvbmcoaW5kZXgpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgZmxvYXQgZ2V0RmxvYXQoKSB7CisgICAgICAgIHJldHVybiBGbG9hdC5pbnRCaXRzVG9GbG9hdChnZXRJbnQoKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGZsb2F0IGdldEZsb2F0KGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gRmxvYXQuaW50Qml0c1RvRmxvYXQoZ2V0SW50KGluZGV4KSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGludCBnZXRJbnQoKSB7CisgICAgICAgIGludCBuZXdQb3NpdGlvbiA9IHBvc2l0aW9uICsgU2l6ZU9mLklOVDsKKyAgICAgICAgaWYgKG5ld1Bvc2l0aW9uID4gbGltaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgcmVzdWx0ID0gTWVtb3J5LnBlZWtJbnQoYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbiwgb3JkZXIpOworICAgICAgICBwb3NpdGlvbiA9IG5ld1Bvc2l0aW9uOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0SW50KGludCBpbmRleCkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4LCBTaXplT2YuSU5UKTsKKyAgICAgICAgcmV0dXJuIE1lbW9yeS5wZWVrSW50KGJhY2tpbmdBcnJheSwgb2Zmc2V0ICsgaW5kZXgsIG9yZGVyKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgbG9uZyBnZXRMb25nKCkgeworICAgICAgICBpbnQgbmV3UG9zaXRpb24gPSBwb3NpdGlvbiArIFNpemVPZi5MT05HOworICAgICAgICBpZiAobmV3UG9zaXRpb24gPiBsaW1pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGxvbmcgcmVzdWx0ID0gTWVtb3J5LnBlZWtMb25nKGJhY2tpbmdBcnJheSwgb2Zmc2V0ICsgcG9zaXRpb24sIG9yZGVyKTsKKyAgICAgICAgcG9zaXRpb24gPSBuZXdQb3NpdGlvbjsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgbG9uZyBnZXRMb25nKGludCBpbmRleCkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4LCBTaXplT2YuTE9ORyk7CisgICAgICAgIHJldHVybiBNZW1vcnkucGVla0xvbmcoYmFja2luZ0FycmF5LCBvZmZzZXQgKyBpbmRleCwgb3JkZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBzaG9ydCBnZXRTaG9ydCgpIHsKKyAgICAgICAgaW50IG5ld1Bvc2l0aW9uID0gcG9zaXRpb24gKyBTaXplT2YuU0hPUlQ7CisgICAgICAgIGlmIChuZXdQb3NpdGlvbiA+IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgc2hvcnQgcmVzdWx0ID0gTWVtb3J5LnBlZWtTaG9ydChiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uLCBvcmRlcik7CisgICAgICAgIHBvc2l0aW9uID0gbmV3UG9zaXRpb247CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIHNob3J0IGdldFNob3J0KGludCBpbmRleCkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4LCBTaXplT2YuU0hPUlQpOworICAgICAgICByZXR1cm4gTWVtb3J5LnBlZWtTaG9ydChiYWNraW5nQXJyYXksIG9mZnNldCArIGluZGV4LCBvcmRlcik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNEaXJlY3QoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vSW50QXJyYXlCdWZmZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9JbnRBcnJheUJ1ZmZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQwMzE0MTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vSW50QXJyYXlCdWZmZXIuamF2YQpAQCAtMCwwICsxLDg2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCisvKioKKyAqIEludEFycmF5QnVmZmVyLCBSZWFkV3JpdGVJbnRBcnJheUJ1ZmZlciBhbmQgUmVhZE9ubHlJbnRBcnJheUJ1ZmZlciBjb21wb3NlCisgKiB0aGUgaW1wbGVtZW50YXRpb24gb2YgYXJyYXkgYmFzZWQgaW50IGJ1ZmZlcnMuCisgKiA8cD4KKyAqIEludEFycmF5QnVmZmVyIGltcGxlbWVudHMgYWxsIHRoZSBzaGFyZWQgcmVhZG9ubHkgbWV0aG9kcyBhbmQgaXMgZXh0ZW5kZWQgYnkKKyAqIHRoZSBvdGhlciB0d28gY2xhc3Nlcy4KKyAqIDwvcD4KKyAqIDxwPgorICogQWxsIG1ldGhvZHMgYXJlIG1hcmtlZCBmaW5hbCBmb3IgcnVudGltZSBwZXJmb3JtYW5jZS4KKyAqIDwvcD4KKyAqCisgKi8KK2Fic3RyYWN0IGNsYXNzIEludEFycmF5QnVmZmVyIGV4dGVuZHMgSW50QnVmZmVyIHsKKworICAgIHByb3RlY3RlZCBmaW5hbCBpbnRbXSBiYWNraW5nQXJyYXk7CisKKyAgICBwcm90ZWN0ZWQgZmluYWwgaW50IG9mZnNldDsKKworICAgIEludEFycmF5QnVmZmVyKGludFtdIGFycmF5KSB7CisgICAgICAgIHRoaXMoYXJyYXkubGVuZ3RoLCBhcnJheSwgMCk7CisgICAgfQorCisgICAgSW50QXJyYXlCdWZmZXIoaW50IGNhcGFjaXR5KSB7CisgICAgICAgIHRoaXMoY2FwYWNpdHksIG5ldyBpbnRbY2FwYWNpdHldLCAwKTsKKyAgICB9CisKKyAgICBJbnRBcnJheUJ1ZmZlcihpbnQgY2FwYWNpdHksIGludFtdIGJhY2tpbmdBcnJheSwgaW50IG9mZnNldCkgeworICAgICAgICBzdXBlcihjYXBhY2l0eSk7CisgICAgICAgIHRoaXMuYmFja2luZ0FycmF5ID0gYmFja2luZ0FycmF5OworICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgaW50IGdldCgpIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJhY2tpbmdBcnJheVtvZmZzZXQgKyBwb3NpdGlvbisrXTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgaW50IGdldChpbnQgaW5kZXgpIHsKKyAgICAgICAgY2hlY2tJbmRleChpbmRleCk7CisgICAgICAgIHJldHVybiBiYWNraW5nQXJyYXlbb2Zmc2V0ICsgaW5kZXhdOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBJbnRCdWZmZXIgZ2V0KGludFtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGludENvdW50KSB7CisgICAgICAgIGlmIChpbnRDb3VudCA+IHJlbWFpbmluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uLCBkc3QsIGRzdE9mZnNldCwgaW50Q291bnQpOworICAgICAgICBwb3NpdGlvbiArPSBpbnRDb3VudDsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNEaXJlY3QoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgQnl0ZU9yZGVyIG9yZGVyKCkgeworICAgICAgICByZXR1cm4gQnl0ZU9yZGVyLm5hdGl2ZU9yZGVyKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vSW50QnVmZmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vSW50QnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWNjMDVmZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9JbnRCdWZmZXIuamF2YQpAQCAtMCwwICsxLDQ2OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogQSBidWZmZXIgb2YgaW50cy4KKyAqIDxwPgorICogQSBpbnQgYnVmZmVyIGNhbiBiZSBjcmVhdGVkIGluIGVpdGhlciBvZiB0aGUgZm9sbG93aW5nIHdheXM6CisgKiA8dWw+CisgKiA8bGk+e0BsaW5rICNhbGxvY2F0ZShpbnQpIEFsbG9jYXRlfSBhIG5ldyBpbnQgYXJyYXkgYW5kIGNyZWF0ZSBhIGJ1ZmZlcgorICogYmFzZWQgb24gaXQ7PC9saT4KKyAqIDxsaT57QGxpbmsgI3dyYXAoaW50W10pIFdyYXB9IGFuIGV4aXN0aW5nIGludCBhcnJheSB0byBjcmVhdGUgYSBuZXcgYnVmZmVyOzwvbGk+CisgKiA8bGk+VXNlIHtAbGluayBqYXZhLm5pby5CeXRlQnVmZmVyI2FzSW50QnVmZmVyKCkgQnl0ZUJ1ZmZlci5hc0ludEJ1ZmZlcn0gdG8KKyAqIGNyZWF0ZSBhIGludCBidWZmZXIgYmFzZWQgb24gYSBieXRlIGJ1ZmZlci48L2xpPgorICogPC91bD4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEludEJ1ZmZlciBleHRlbmRzIEJ1ZmZlciBpbXBsZW1lbnRzIENvbXBhcmFibGU8SW50QnVmZmVyPiB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGludCBidWZmZXIgYmFzZWQgb24gYSBuZXdseSBhbGxvY2F0ZWQgaW50IGFycmF5LgorICAgICAqCisgICAgICogQHBhcmFtIGNhcGFjaXR5CisgICAgICogICAgICAgICAgICB0aGUgY2FwYWNpdHkgb2YgdGhlIG5ldyBidWZmZXIuCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCBpbnQgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGNhcGFjaXR5fSBpcyBsZXNzIHRoYW4gemVyby4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEludEJ1ZmZlciBhbGxvY2F0ZShpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgaWYgKGNhcGFjaXR5IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgUmVhZFdyaXRlSW50QXJyYXlCdWZmZXIoY2FwYWNpdHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgaW50IGJ1ZmZlciBieSB3cmFwcGluZyB0aGUgZ2l2ZW4gaW50IGFycmF5LgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcworICAgICAqIHtAY29kZSB3cmFwKGFycmF5LCAwLCBhcnJheS5sZW5ndGgpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGludCBhcnJheSB3aGljaCB0aGUgbmV3IGJ1ZmZlciB3aWxsIGJlIGJhc2VkIG9uLgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgaW50IGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEludEJ1ZmZlciB3cmFwKGludFtdIGFycmF5KSB7CisgICAgICAgIHJldHVybiB3cmFwKGFycmF5LCAwLCBhcnJheS5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgaW50IGJ1ZmZlciBieSB3cmFwcGluZyB0aGUgZ2l2ZW4gaW50IGFycmF5LgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyJ3MgcG9zaXRpb24gd2lsbCBiZSB7QGNvZGUgc3RhcnR9LCBsaW1pdCB3aWxsIGJlCisgICAgICoge0Bjb2RlIHN0YXJ0ICsgaW50Q291bnR9LCBjYXBhY2l0eSB3aWxsIGJlIHRoZSBsZW5ndGggb2YgdGhlIGFycmF5LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUgaW50IGFycmF5IHdoaWNoIHRoZSBuZXcgYnVmZmVyIHdpbGwgYmUgYmFzZWQgb24uCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgaW5kZXgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgICAgICB7QGNvZGUgYXJyYXkubGVuZ3RofQorICAgICAqIEBwYXJhbSBpbnRDb3VudAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIG5vdCBncmVhdGVyIHRoYW4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBhcnJheS5sZW5ndGggLSBzdGFydH0uCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCBpbnQgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGVpdGhlciB7QGNvZGUgc3RhcnR9IG9yIHtAY29kZSBpbnRDb3VudH0gaXMgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEludEJ1ZmZlciB3cmFwKGludFtdIGFycmF5LCBpbnQgc3RhcnQsIGludCBpbnRDb3VudCkgeworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChhcnJheS5sZW5ndGgsIHN0YXJ0LCBpbnRDb3VudCk7CisgICAgICAgIEludEJ1ZmZlciBidWYgPSBuZXcgUmVhZFdyaXRlSW50QXJyYXlCdWZmZXIoYXJyYXkpOworICAgICAgICBidWYucG9zaXRpb24gPSBzdGFydDsKKyAgICAgICAgYnVmLmxpbWl0ID0gc3RhcnQgKyBpbnRDb3VudDsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICBJbnRCdWZmZXIoaW50IGNhcGFjaXR5KSB7CisgICAgICAgIHN1cGVyKDIsIGNhcGFjaXR5LCBudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgaW50W10gYXJyYXkoKSB7CisgICAgICAgIHJldHVybiBwcm90ZWN0ZWRBcnJheSgpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBpbnQgYXJyYXlPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBwcm90ZWN0ZWRBcnJheU9mZnNldCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSByZWFkLW9ubHkgYnVmZmVyIHRoYXQgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIuCisgICAgICogPHA+CisgICAgICogVGhlIHJldHVybmVkIGJ1ZmZlciBpcyBndWFyYW50ZWVkIHRvIGJlIGEgbmV3IGluc3RhbmNlLCBldmVuIHRoaXMgYnVmZmVyCisgICAgICogaXMgcmVhZC1vbmx5IGl0c2VsZi4gVGhlIG5ldyBidWZmZXIncyBwb3NpdGlvbiwgbGltaXQsIGNhcGFjaXR5IGFuZCBtYXJrCisgICAgICogYXJlIHRoZSBzYW1lIGFzIHRoaXMgYnVmZmVyJ3MuCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIsIHdoaWNoIG1lYW5zIHRoaXMKKyAgICAgKiBidWZmZXIncyBjaGFuZ2Ugb2YgY29udGVudCB3aWxsIGJlIHZpc2libGUgdG8gdGhlIG5ldyBidWZmZXIuIFRoZSB0d28KKyAgICAgKiBidWZmZXIncyBwb3NpdGlvbiwgbGltaXQgYW5kIG1hcmsgYXJlIGluZGVwZW5kZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIHJlYWQtb25seSB2ZXJzaW9uIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBJbnRCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpOworCisgICAgLyoqCisgICAgICogQ29tcGFjdHMgdGhpcyBpbnQgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSByZW1haW5pbmcgaW50cyB3aWxsIGJlIG1vdmVkIHRvIHRoZSBoZWFkIG9mIHRoZSBidWZmZXIsIHN0YXJ0aW5nIGZyb20KKyAgICAgKiBwb3NpdGlvbiB6ZXJvLiBUaGVuIHRoZSBwb3NpdGlvbiBpcyBzZXQgdG8ge0Bjb2RlIHJlbWFpbmluZygpfTsgdGhlCisgICAgICogbGltaXQgaXMgc2V0IHRvIGNhcGFjaXR5OyB0aGUgbWFyayBpcyBjbGVhcmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEludEJ1ZmZlciBjb21wYWN0KCk7CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgcmVtYWluaW5nIGludHMgb2YgdGhpcyBidWZmZXIgdG8gYW5vdGhlciBpbnQgYnVmZmVyJ3MKKyAgICAgKiByZW1haW5pbmcgaW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdGhlckJ1ZmZlcgorICAgICAqICAgICAgICAgICAgYW5vdGhlciBpbnQgYnVmZmVyLgorICAgICAqIEByZXR1cm4gYSBuZWdhdGl2ZSB2YWx1ZSBpZiB0aGlzIGlzIGxlc3MgdGhhbiB7QGNvZGUgb3RoZXJ9OyAwIGlmIHRoaXMKKyAgICAgKiAgICAgICAgIGVxdWFscyB0byB7QGNvZGUgb3RoZXJ9OyBhIHBvc2l0aXZlIHZhbHVlIGlmIHRoaXMgaXMgZ3JlYXRlcgorICAgICAqICAgICAgICAgdGhhbiB7QGNvZGUgb3RoZXJ9LgorICAgICAqIEBleGNlcHRpb24gQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIG90aGVyfSBpcyBub3QgYW4gaW50IGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhJbnRCdWZmZXIgb3RoZXJCdWZmZXIpIHsKKyAgICAgICAgaW50IGNvbXBhcmVSZW1haW5pbmcgPSAocmVtYWluaW5nKCkgPCBvdGhlckJ1ZmZlci5yZW1haW5pbmcoKSkgPyByZW1haW5pbmcoKQorICAgICAgICAgICAgICAgIDogb3RoZXJCdWZmZXIucmVtYWluaW5nKCk7CisgICAgICAgIGludCB0aGlzUG9zID0gcG9zaXRpb247CisgICAgICAgIGludCBvdGhlclBvcyA9IG90aGVyQnVmZmVyLnBvc2l0aW9uOworICAgICAgICBpbnQgdGhpc0ludCwgb3RoZXJJbnQ7CisgICAgICAgIHdoaWxlIChjb21wYXJlUmVtYWluaW5nID4gMCkgeworICAgICAgICAgICAgdGhpc0ludCA9IGdldCh0aGlzUG9zKTsKKyAgICAgICAgICAgIG90aGVySW50ID0gb3RoZXJCdWZmZXIuZ2V0KG90aGVyUG9zKTsKKyAgICAgICAgICAgIGlmICh0aGlzSW50ICE9IG90aGVySW50KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXNJbnQgPCBvdGhlckludCA/IC0xIDogMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXNQb3MrKzsKKyAgICAgICAgICAgIG90aGVyUG9zKys7CisgICAgICAgICAgICBjb21wYXJlUmVtYWluaW5nLS07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlbWFpbmluZygpIC0gb3RoZXJCdWZmZXIucmVtYWluaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGR1cGxpY2F0ZWQgYnVmZmVyIHRoYXQgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIuCisgICAgICogPHA+CisgICAgICogVGhlIGR1cGxpY2F0ZWQgYnVmZmVyJ3MgcG9zaXRpb24sIGxpbWl0LCBjYXBhY2l0eSBhbmQgbWFyayBhcmUgdGhlIHNhbWUKKyAgICAgKiBhcyB0aGlzIGJ1ZmZlci4gVGhlIGR1cGxpY2F0ZWQgYnVmZmVyJ3MgcmVhZC1vbmx5IHByb3BlcnR5IGFuZCBieXRlIG9yZGVyCisgICAgICogYXJlIHRoZSBzYW1lIGFzIHRoaXMgYnVmZmVyJ3MuCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIsIHdoaWNoIG1lYW5zIGVpdGhlcgorICAgICAqIGJ1ZmZlcidzIGNoYW5nZSBvZiBjb250ZW50IHdpbGwgYmUgdmlzaWJsZSB0byB0aGUgb3RoZXIuIFRoZSB0d28gYnVmZmVyJ3MKKyAgICAgKiBwb3NpdGlvbiwgbGltaXQgYW5kIG1hcmsgYXJlIGluZGVwZW5kZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIGR1cGxpY2F0ZWQgYnVmZmVyIHRoYXQgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEludEJ1ZmZlciBkdXBsaWNhdGUoKTsKKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIHRoaXMgaW50IGJ1ZmZlciBpcyBlcXVhbCB0byBhbm90aGVyIG9iamVjdC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB7QGNvZGUgb3RoZXJ9IGlzIG5vdCBhIGludCBidWZmZXIgdGhlbiB7QGNvZGUgZmFsc2V9IGlzIHJldHVybmVkLiBUd28KKyAgICAgKiBpbnQgYnVmZmVycyBhcmUgZXF1YWwgaWYgYW5kIG9ubHkgaWYgdGhlaXIgcmVtYWluaW5nIGludHMgYXJlIGV4YWN0bHkgdGhlCisgICAgICogc2FtZS4gUG9zaXRpb24sIGxpbWl0LCBjYXBhY2l0eSBhbmQgbWFyayBhcmUgbm90IGNvbnNpZGVyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3RoZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB3aXRoIHRoaXMgaW50IGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGludCBidWZmZXIgaXMgZXF1YWwgdG8ge0Bjb2RlIG90aGVyfSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKKyAgICAgICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBJbnRCdWZmZXIpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgSW50QnVmZmVyIG90aGVyQnVmZmVyID0gKEludEJ1ZmZlcikgb3RoZXI7CisKKyAgICAgICAgaWYgKHJlbWFpbmluZygpICE9IG90aGVyQnVmZmVyLnJlbWFpbmluZygpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBpbnQgbXlQb3NpdGlvbiA9IHBvc2l0aW9uOworICAgICAgICBpbnQgb3RoZXJQb3NpdGlvbiA9IG90aGVyQnVmZmVyLnBvc2l0aW9uOworICAgICAgICBib29sZWFuIGVxdWFsU29GYXIgPSB0cnVlOworICAgICAgICB3aGlsZSAoZXF1YWxTb0ZhciAmJiAobXlQb3NpdGlvbiA8IGxpbWl0KSkgeworICAgICAgICAgICAgZXF1YWxTb0ZhciA9IGdldChteVBvc2l0aW9uKyspID09IG90aGVyQnVmZmVyLmdldChvdGhlclBvc2l0aW9uKyspOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGVxdWFsU29GYXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW50IGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IDEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbnQgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgcG9zaXRpb24gaXMgZXF1YWwgb3IgZ3JlYXRlciB0aGFuIGxpbWl0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBpbnRzIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24gaW50byB0aGUgc3BlY2lmaWVkIGludCBhcnJheSBhbmQKKyAgICAgKiBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IHRoZSBudW1iZXIgb2YgaW50cyByZWFkLgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcworICAgICAqIHtAY29kZSBnZXQoZHN0LCAwLCBkc3QubGVuZ3RoKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gaW50IGFycmF5LgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgZHN0Lmxlbmd0aH0gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSByZW1haW5pbmcoKX0uCisgICAgICovCisgICAgcHVibGljIEludEJ1ZmZlciBnZXQoaW50W10gZHN0KSB7CisgICAgICAgIHJldHVybiBnZXQoZHN0LCAwLCBkc3QubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBpbnRzIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24gaW50byB0aGUgc3BlY2lmaWVkIGludCBhcnJheSwKKyAgICAgKiBzdGFydGluZyBmcm9tIHRoZSBzcGVjaWZpZWQgb2Zmc2V0LCBhbmQgaW5jcmVhc2VzIHRoZSBwb3NpdGlvbiBieSB0aGUKKyAgICAgKiBudW1iZXIgb2YgaW50cyByZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBpbnQgYXJyYXkuCisgICAgICogQHBhcmFtIGRzdE9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvZiB0aGUgaW50IGFycmF5LCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBhbmQgbm90CisgICAgICogICAgICAgICAgICBncmVhdGVyIHRoYW4ge0Bjb2RlIGRzdC5sZW5ndGh9LgorICAgICAqIEBwYXJhbSBpbnRDb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBpbnRzIHRvIHJlYWQsIG11c3QgYmUgbm8gbGVzcyB0aGFuIHplcm8gYW5kIG5vdAorICAgICAqICAgICAgICAgICAgZ3JlYXRlciB0aGFuIHtAY29kZSBkc3QubGVuZ3RoIC0gZHN0T2Zmc2V0fS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGVpdGhlciB7QGNvZGUgZHN0T2Zmc2V0fSBvciB7QGNvZGUgaW50Q291bnR9IGlzIGludmFsaWQuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgaW50Q291bnR9IGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgcmVtYWluaW5nKCl9LgorICAgICAqLworICAgIHB1YmxpYyBJbnRCdWZmZXIgZ2V0KGludFtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGludENvdW50KSB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGRzdC5sZW5ndGgsIGRzdE9mZnNldCwgaW50Q291bnQpOworICAgICAgICBpZiAoaW50Q291bnQgPiByZW1haW5pbmcoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSBkc3RPZmZzZXQ7IGkgPCBkc3RPZmZzZXQgKyBpbnRDb3VudDsgKytpKSB7CisgICAgICAgICAgICBkc3RbaV0gPSBnZXQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGludCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4OyB0aGUgcG9zaXRpb24gaXMgbm90IGNoYW5nZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIGxlc3MgdGhhbiBsaW1pdC4KKyAgICAgKiBAcmV0dXJuIGFuIGludCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgorICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGluZGV4IGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXQoaW50IGluZGV4KTsKKworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc0FycmF5KCkgeworICAgICAgICByZXR1cm4gcHJvdGVjdGVkSGFzQXJyYXkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxjdWxhdGVzIHRoaXMgYnVmZmVyJ3MgaGFzaCBjb2RlIGZyb20gdGhlIHJlbWFpbmluZyBjaGFycy4gVGhlCisgICAgICogcG9zaXRpb24sIGxpbWl0LCBjYXBhY2l0eSBhbmQgbWFyayBkb24ndCBhZmZlY3QgdGhlIGhhc2ggY29kZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZSBjYWxjdWxhdGVkIGZyb20gdGhlIHJlbWFpbmluZyBpbnRzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGludCBteVBvc2l0aW9uID0gcG9zaXRpb247CisgICAgICAgIGludCBoYXNoID0gMDsKKyAgICAgICAgd2hpbGUgKG15UG9zaXRpb24gPCBsaW1pdCkgeworICAgICAgICAgICAgaGFzaCA9IGhhc2ggKyBnZXQobXlQb3NpdGlvbisrKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIGJ1ZmZlciBpcyBkaXJlY3QuIEEgZGlyZWN0IGJ1ZmZlciB3aWxsIHRyeSBpdHMKKyAgICAgKiBiZXN0IHRvIHRha2UgYWR2YW50YWdlIG9mIG5hdGl2ZSBtZW1vcnkgQVBJcyBhbmQgaXQgbWF5IG5vdCBzdGF5IGluIHRoZQorICAgICAqIEphdmEgaGVhcCwgc28gaXQgaXMgbm90IGFmZmVjdGVkIGJ5IGdhcmJhZ2UgY29sbGVjdGlvbi4KKyAgICAgKiA8cD4KKyAgICAgKiBBbiBpbnQgYnVmZmVyIGlzIGRpcmVjdCBpZiBpdCBpcyBiYXNlZCBvbiBhIGJ5dGUgYnVmZmVyIGFuZCB0aGUgYnl0ZQorICAgICAqIGJ1ZmZlciBpcyBkaXJlY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGJ1ZmZlciBpcyBkaXJlY3QsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzRGlyZWN0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBieXRlIG9yZGVyIHVzZWQgYnkgdGhpcyBidWZmZXIgd2hlbiBjb252ZXJ0aW5nIGludHMgZnJvbS90bworICAgICAqIGJ5dGVzLgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgYnVmZmVyIGlzIG5vdCBiYXNlZCBvbiBhIGJ5dGUgYnVmZmVyLCB0aGVuIGFsd2F5cyByZXR1cm4gdGhlCisgICAgICogcGxhdGZvcm0ncyBuYXRpdmUgYnl0ZSBvcmRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgb3JkZXIgdXNlZCBieSB0aGlzIGJ1ZmZlciB3aGVuIGNvbnZlcnRpbmcgaW50cyBmcm9tL3RvCisgICAgICogICAgICAgICBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnl0ZU9yZGVyIG9yZGVyKCk7CisKKyAgICAvKioKKyAgICAgKiBDaGlsZCBjbGFzcyBpbXBsZW1lbnRzIHRoaXMgbWV0aG9kIHRvIHJlYWxpemUge0Bjb2RlIGFycmF5KCl9LgorICAgICAqCisgICAgICogQHJldHVybiBzZWUge0Bjb2RlIGFycmF5KCl9CisgICAgICovCisgICAgYWJzdHJhY3QgaW50W10gcHJvdGVjdGVkQXJyYXkoKTsKKworICAgIC8qKgorICAgICAqIENoaWxkIGNsYXNzIGltcGxlbWVudHMgdGhpcyBtZXRob2QgdG8gcmVhbGl6ZSB7QGNvZGUgYXJyYXlPZmZzZXQoKX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHNlZSB7QGNvZGUgYXJyYXlPZmZzZXQoKX0KKyAgICAgKi8KKyAgICBhYnN0cmFjdCBpbnQgcHJvdGVjdGVkQXJyYXlPZmZzZXQoKTsKKworICAgIC8qKgorICAgICAqIENoaWxkIGNsYXNzIGltcGxlbWVudHMgdGhpcyBtZXRob2QgdG8gcmVhbGl6ZSB7QGNvZGUgaGFzQXJyYXkoKX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHNlZSB7QGNvZGUgaGFzQXJyYXkoKX0KKyAgICAgKi8KKyAgICBhYnN0cmFjdCBib29sZWFuIHByb3RlY3RlZEhhc0FycmF5KCk7CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGdpdmVuIGludCB0byB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQgaW5jcmVhc2VzIHRoZSBwb3NpdGlvbgorICAgICAqIGJ5IDEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaQorICAgICAqICAgICAgICAgICAgdGhlIGludCB0byB3cml0ZS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBwb3NpdGlvbiBpcyBlcXVhbCBvciBncmVhdGVyIHRoYW4gbGltaXQuCisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBJbnRCdWZmZXIgcHV0KGludCBpKTsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyBpbnRzIGZyb20gdGhlIGdpdmVuIGludCBhcnJheSB0byB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQKKyAgICAgKiBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IHRoZSBudW1iZXIgb2YgaW50cyB3cml0dGVuLgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcworICAgICAqIHtAY29kZSBwdXQoc3JjLCAwLCBzcmMubGVuZ3RoKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGludCBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgcmVtYWluaW5nKCl9IGlzIGxlc3MgdGhhbiB7QGNvZGUgc3JjLmxlbmd0aH0uCisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBJbnRCdWZmZXIgcHV0KGludFtdIHNyYykgeworICAgICAgICByZXR1cm4gcHV0KHNyYywgMCwgc3JjLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGludHMgZnJvbSB0aGUgZ2l2ZW4gaW50IGFycmF5LCBzdGFydGluZyBmcm9tIHRoZSBzcGVjaWZpZWQgb2Zmc2V0LAorICAgICAqIHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IHRoZSBudW1iZXIgb2YgaW50cworICAgICAqIHdyaXR0ZW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGludCBhcnJheS4KKyAgICAgKiBAcGFyYW0gc3JjT2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIGludCBhcnJheSwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIG5vdCBncmVhdGVyCisgICAgICogICAgICAgICAgICB0aGFuIHtAY29kZSBzcmMubGVuZ3RofS4KKyAgICAgKiBAcGFyYW0gaW50Q291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgaW50cyB0byB3cml0ZSwgbXVzdCBiZSBubyBsZXNzIHRoYW4gemVybyBhbmQgbm90CisgICAgICogICAgICAgICAgICBncmVhdGVyIHRoYW4ge0Bjb2RlIHNyYy5sZW5ndGggLSBzcmNPZmZzZXR9LgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSByZW1haW5pbmcoKX0gaXMgbGVzcyB0aGFuIHtAY29kZSBpbnRDb3VudH0uCisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgZWl0aGVyIHtAY29kZSBzcmNPZmZzZXR9IG9yIHtAY29kZSBpbnRDb3VudH0gaXMgaW52YWxpZC4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIEludEJ1ZmZlciBwdXQoaW50W10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgaW50Q291bnQpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoc3JjLmxlbmd0aCwgc3JjT2Zmc2V0LCBpbnRDb3VudCk7CisgICAgICAgIGlmIChpbnRDb3VudCA+IHJlbWFpbmluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gc3JjT2Zmc2V0OyBpIDwgc3JjT2Zmc2V0ICsgaW50Q291bnQ7ICsraSkgeworICAgICAgICAgICAgcHV0KHNyY1tpXSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGFsbCB0aGUgcmVtYWluaW5nIGludHMgb2YgdGhlIHtAY29kZSBzcmN9IGludCBidWZmZXIgdG8gdGhpcworICAgICAqIGJ1ZmZlcidzIGN1cnJlbnQgcG9zaXRpb24sIGFuZCBpbmNyZWFzZXMgYm90aCBidWZmZXJzJyBwb3NpdGlvbiBieSB0aGUKKyAgICAgKiBudW1iZXIgb2YgaW50cyBjb3BpZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGludCBidWZmZXIuCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHNyYy5yZW1haW5pbmcoKX0gaXMgZ3JlYXRlciB0aGFuIHRoaXMgYnVmZmVyJ3MKKyAgICAgKiAgICAgICAgICAgICAgICB7QGNvZGUgcmVtYWluaW5nKCl9LgorICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHNyY30gaXMgdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBJbnRCdWZmZXIgcHV0KEludEJ1ZmZlciBzcmMpIHsKKyAgICAgICAgaWYgKHNyYyA9PSB0aGlzKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNyYy5yZW1haW5pbmcoKSA+IHJlbWFpbmluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbnRbXSBjb250ZW50cyA9IG5ldyBpbnRbc3JjLnJlbWFpbmluZygpXTsKKyAgICAgICAgc3JjLmdldChjb250ZW50cyk7CisgICAgICAgIHB1dChjb250ZW50cyk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIGEgaW50IHRvIHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyBidWZmZXI7IHRoZSBwb3NpdGlvbiBpcyBub3QKKyAgICAgKiBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBsZXNzIHRoYW4gdGhlIGxpbWl0LgorICAgICAqIEBwYXJhbSBpCisgICAgICogICAgICAgICAgICB0aGUgaW50IHRvIHdyaXRlLgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgaW5kZXggaXMgaW52YWxpZC4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEludEJ1ZmZlciBwdXQoaW50IGluZGV4LCBpbnQgaSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc2xpY2VkIGJ1ZmZlciB0aGF0IHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBzbGljZWQgYnVmZmVyJ3MgY2FwYWNpdHkgd2lsbCBiZSB0aGlzIGJ1ZmZlcidzIHtAY29kZSByZW1haW5pbmcoKX0sCisgICAgICogYW5kIGl0cyB6ZXJvIHBvc2l0aW9uIHdpbGwgY29ycmVzcG9uZCB0byB0aGlzIGJ1ZmZlcidzIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogVGhlIG5ldyBidWZmZXIncyBwb3NpdGlvbiB3aWxsIGJlIDAsIGxpbWl0IHdpbGwgYmUgaXRzIGNhcGFjaXR5LCBhbmQgaXRzCisgICAgICogbWFyayBpcyBjbGVhcmVkLiBUaGUgbmV3IGJ1ZmZlcidzIHJlYWQtb25seSBwcm9wZXJ0eSBhbmQgYnl0ZSBvcmRlciBhcmUKKyAgICAgKiBzYW1lIGFzIHRoaXMgYnVmZmVyJ3MuCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIsIHdoaWNoIG1lYW5zIGVpdGhlcgorICAgICAqIGJ1ZmZlcidzIGNoYW5nZSBvZiBjb250ZW50IHdpbGwgYmUgdmlzaWJsZSB0byB0aGUgb3RoZXIuIFRoZSB0d28gYnVmZmVyJ3MKKyAgICAgKiBwb3NpdGlvbiwgbGltaXQgYW5kIG1hcmsgYXJlIGluZGVwZW5kZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIHNsaWNlZCBidWZmZXIgdGhhdCBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgSW50QnVmZmVyIHNsaWNlKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vSW50VG9CeXRlQnVmZmVyQWRhcHRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0ludFRvQnl0ZUJ1ZmZlckFkYXB0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNjk0ZTc3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0ludFRvQnl0ZUJ1ZmZlckFkYXB0ZXIuamF2YQpAQCAtMCwwICsxLDE4MiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworaW1wb3J0IGxpYmNvcmUuaW8uU2l6ZU9mOworCisvKioKKyAqIFRoaXMgY2xhc3Mgd3JhcHMgYSBieXRlIGJ1ZmZlciB0byBiZSBhIGludCBidWZmZXIuCisgKiA8cD4KKyAqIEltcGxlbWVudGF0aW9uIG5vdGljZToKKyAqIDx1bD4KKyAqIDxsaT5BZnRlciBhIGJ5dGUgYnVmZmVyIGluc3RhbmNlIGlzIHdyYXBwZWQsIGl0IGJlY29tZXMgcHJpdmF0ZWx5IG93bmVkIGJ5CisgKiB0aGUgYWRhcHRlci4gSXQgbXVzdCBOT1QgYmUgYWNjZXNzZWQgb3V0c2lkZSB0aGUgYWRhcHRlciBhbnkgbW9yZS48L2xpPgorICogPGxpPlRoZSBieXRlIGJ1ZmZlcidzIHBvc2l0aW9uIGFuZCBsaW1pdCBhcmUgTk9UIGxpbmtlZCB3aXRoIHRoZSBhZGFwdGVyLgorICogVGhlIGFkYXB0ZXIgZXh0ZW5kcyBCdWZmZXIsIHRodXMgaGFzIGl0cyBvd24gcG9zaXRpb24gYW5kIGxpbWl0LjwvbGk+CisgKiA8L3VsPgorICogPC9wPgorICoKKyAqLworZmluYWwgY2xhc3MgSW50VG9CeXRlQnVmZmVyQWRhcHRlciBleHRlbmRzIEludEJ1ZmZlciB7CisKKyAgICBwcml2YXRlIGZpbmFsIEJ5dGVCdWZmZXIgYnl0ZUJ1ZmZlcjsKKworICAgIHN0YXRpYyBJbnRCdWZmZXIgYXNJbnRCdWZmZXIoQnl0ZUJ1ZmZlciBieXRlQnVmZmVyKSB7CisgICAgICAgIEJ5dGVCdWZmZXIgc2xpY2UgPSBieXRlQnVmZmVyLnNsaWNlKCk7CisgICAgICAgIHNsaWNlLm9yZGVyKGJ5dGVCdWZmZXIub3JkZXIoKSk7CisgICAgICAgIHJldHVybiBuZXcgSW50VG9CeXRlQnVmZmVyQWRhcHRlcihzbGljZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBJbnRUb0J5dGVCdWZmZXJBZGFwdGVyKEJ5dGVCdWZmZXIgYnl0ZUJ1ZmZlcikgeworICAgICAgICBzdXBlcihieXRlQnVmZmVyLmNhcGFjaXR5KCkgLyBTaXplT2YuSU5UKTsKKyAgICAgICAgdGhpcy5ieXRlQnVmZmVyID0gYnl0ZUJ1ZmZlcjsKKyAgICAgICAgdGhpcy5ieXRlQnVmZmVyLmNsZWFyKCk7CisgICAgICAgIHRoaXMuZWZmZWN0aXZlRGlyZWN0QWRkcmVzcyA9IGJ5dGVCdWZmZXIuZWZmZWN0aXZlRGlyZWN0QWRkcmVzczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW50QnVmZmVyIGFzUmVhZE9ubHlCdWZmZXIoKSB7CisgICAgICAgIEludFRvQnl0ZUJ1ZmZlckFkYXB0ZXIgYnVmID0gbmV3IEludFRvQnl0ZUJ1ZmZlckFkYXB0ZXIoYnl0ZUJ1ZmZlci5hc1JlYWRPbmx5QnVmZmVyKCkpOworICAgICAgICBidWYubGltaXQgPSBsaW1pdDsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gcG9zaXRpb247CisgICAgICAgIGJ1Zi5tYXJrID0gbWFyazsKKyAgICAgICAgYnVmLmJ5dGVCdWZmZXIub3JkZXIgPSBieXRlQnVmZmVyLm9yZGVyOworICAgICAgICByZXR1cm4gYnVmOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnRCdWZmZXIgY29tcGFjdCgpIHsKKyAgICAgICAgaWYgKGJ5dGVCdWZmZXIuaXNSZWFkT25seSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBieXRlQnVmZmVyLmxpbWl0KGxpbWl0ICogU2l6ZU9mLklOVCk7CisgICAgICAgIGJ5dGVCdWZmZXIucG9zaXRpb24ocG9zaXRpb24gKiBTaXplT2YuSU5UKTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5jb21wYWN0KCk7CisgICAgICAgIGJ5dGVCdWZmZXIuY2xlYXIoKTsKKyAgICAgICAgcG9zaXRpb24gPSBsaW1pdCAtIHBvc2l0aW9uOworICAgICAgICBsaW1pdCA9IGNhcGFjaXR5OworICAgICAgICBtYXJrID0gVU5TRVRfTUFSSzsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEludEJ1ZmZlciBkdXBsaWNhdGUoKSB7CisgICAgICAgIEJ5dGVCdWZmZXIgYmIgPSBieXRlQnVmZmVyLmR1cGxpY2F0ZSgpLm9yZGVyKGJ5dGVCdWZmZXIub3JkZXIoKSk7CisgICAgICAgIEludFRvQnl0ZUJ1ZmZlckFkYXB0ZXIgYnVmID0gbmV3IEludFRvQnl0ZUJ1ZmZlckFkYXB0ZXIoYmIpOworICAgICAgICBidWYubGltaXQgPSBsaW1pdDsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gcG9zaXRpb247CisgICAgICAgIGJ1Zi5tYXJrID0gbWFyazsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldCgpIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ5dGVCdWZmZXIuZ2V0SW50KHBvc2l0aW9uKysgKiBTaXplT2YuSU5UKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldChpbnQgaW5kZXgpIHsKKyAgICAgICAgY2hlY2tJbmRleChpbmRleCk7CisgICAgICAgIHJldHVybiBieXRlQnVmZmVyLmdldEludChpbmRleCAqIFNpemVPZi5JTlQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnRCdWZmZXIgZ2V0KGludFtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGludENvdW50KSB7CisgICAgICAgIGJ5dGVCdWZmZXIubGltaXQobGltaXQgKiBTaXplT2YuSU5UKTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5wb3NpdGlvbihwb3NpdGlvbiAqIFNpemVPZi5JTlQpOworICAgICAgICBpZiAoYnl0ZUJ1ZmZlciBpbnN0YW5jZW9mIERpcmVjdEJ5dGVCdWZmZXIpIHsKKyAgICAgICAgICAgICgoRGlyZWN0Qnl0ZUJ1ZmZlcikgYnl0ZUJ1ZmZlcikuZ2V0KGRzdCwgZHN0T2Zmc2V0LCBpbnRDb3VudCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAoKEhlYXBCeXRlQnVmZmVyKSBieXRlQnVmZmVyKS5nZXQoZHN0LCBkc3RPZmZzZXQsIGludENvdW50KTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnBvc2l0aW9uICs9IGludENvdW50OworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdCgpIHsKKyAgICAgICAgcmV0dXJuIGJ5dGVCdWZmZXIuaXNEaXJlY3QoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1JlYWRPbmx5KCkgeworICAgICAgICByZXR1cm4gYnl0ZUJ1ZmZlci5pc1JlYWRPbmx5KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVPcmRlciBvcmRlcigpIHsKKyAgICAgICAgcmV0dXJuIGJ5dGVCdWZmZXIub3JkZXIoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50W10gcHJvdGVjdGVkQXJyYXkoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgcHJvdGVjdGVkQXJyYXlPZmZzZXQoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBib29sZWFuIHByb3RlY3RlZEhhc0FycmF5KCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEludEJ1ZmZlciBwdXQoaW50IGMpIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBieXRlQnVmZmVyLnB1dEludChwb3NpdGlvbisrICogU2l6ZU9mLklOVCwgYyk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnRCdWZmZXIgcHV0KGludCBpbmRleCwgaW50IGMpIHsKKyAgICAgICAgY2hlY2tJbmRleChpbmRleCk7CisgICAgICAgIGJ5dGVCdWZmZXIucHV0SW50KGluZGV4ICogU2l6ZU9mLklOVCwgYyk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnRCdWZmZXIgcHV0KGludFtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGludENvdW50KSB7CisgICAgICAgIGJ5dGVCdWZmZXIubGltaXQobGltaXQgKiBTaXplT2YuSU5UKTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5wb3NpdGlvbihwb3NpdGlvbiAqIFNpemVPZi5JTlQpOworICAgICAgICBpZiAoYnl0ZUJ1ZmZlciBpbnN0YW5jZW9mIFJlYWRXcml0ZURpcmVjdEJ5dGVCdWZmZXIpIHsKKyAgICAgICAgICAgICgoUmVhZFdyaXRlRGlyZWN0Qnl0ZUJ1ZmZlcikgYnl0ZUJ1ZmZlcikucHV0KHNyYywgc3JjT2Zmc2V0LCBpbnRDb3VudCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAoKFJlYWRXcml0ZUhlYXBCeXRlQnVmZmVyKSBieXRlQnVmZmVyKS5wdXQoc3JjLCBzcmNPZmZzZXQsIGludENvdW50KTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnBvc2l0aW9uICs9IGludENvdW50OworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW50QnVmZmVyIHNsaWNlKCkgeworICAgICAgICBieXRlQnVmZmVyLmxpbWl0KGxpbWl0ICogU2l6ZU9mLklOVCk7CisgICAgICAgIGJ5dGVCdWZmZXIucG9zaXRpb24ocG9zaXRpb24gKiBTaXplT2YuSU5UKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYiA9IGJ5dGVCdWZmZXIuc2xpY2UoKS5vcmRlcihieXRlQnVmZmVyLm9yZGVyKCkpOworICAgICAgICBJbnRCdWZmZXIgcmVzdWx0ID0gbmV3IEludFRvQnl0ZUJ1ZmZlckFkYXB0ZXIoYmIpOworICAgICAgICBieXRlQnVmZmVyLmNsZWFyKCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vSW52YWxpZE1hcmtFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9JbnZhbGlkTWFya0V4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM0OWNmM2EKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vSW52YWxpZE1hcmtFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQwIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCisvKioKKyAqIEFuIHtAY29kZSBJbnZhbGlkTWFya0V4Y2VwdGlvbn0gaXMgdGhyb3duIHdoZW4ge0Bjb2RlIHJlc2V0KCl9IGlzIGNhbGxlZCBvbiBhCisgKiBidWZmZXIsIGJ1dCBubyBtYXJrIGhhcyBiZWVuIHNldCBwcmV2aW91c2x5LgorICovCitwdWJsaWMgY2xhc3MgSW52YWxpZE1hcmtFeGNlcHRpb24gZXh0ZW5kcyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTY5ODMyOTcxMDQzODUxMDc3NEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIHtAY29kZSBJbnZhbGlkTWFya0V4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIEludmFsaWRNYXJrRXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4ge0Bjb2RlIEludmFsaWRNYXJrRXhjZXB0aW9ufSB3aXRoIHRoZSBnaXZlbiBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIHB1YmxpYyBJbnZhbGlkTWFya0V4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vSW9WZWMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9Jb1ZlYy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYxNGY0ZjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vSW9WZWMuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW87CisKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgbGliY29yZS5pby5MaWJjb3JlOworaW1wb3J0IGxpYmNvcmUuaW8uRXJybm9FeGNlcHRpb247CisKKy8qKgorICogVXNlZCB0byBpbXBsZW1lbnQgamF2YS5uaW8gcmVhZChCeXRlQnVmZmVyW10pL3dyaXRlKEJ5dGVCdWZmZXJbXSkgb3BlcmF0aW9ucyBhcyBQT1NJWCByZWFkdigyKQorICogYW5kIHdyaXRldigyKSBjYWxscy4KKyAqLworZmluYWwgY2xhc3MgSW9WZWMgeworICAgIGVudW0gRGlyZWN0aW9uIHsgUkVBRFYsIFdSSVRFViB9OworCisgICAgcHJpdmF0ZSBmaW5hbCBCeXRlQnVmZmVyW10gYnl0ZUJ1ZmZlcnM7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgb2Zmc2V0OworICAgIHByaXZhdGUgZmluYWwgaW50IGJ1ZmZlckNvdW50OworCisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3RbXSBpb0J1ZmZlcnM7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnRbXSBvZmZzZXRzOworICAgIHByaXZhdGUgZmluYWwgaW50W10gYnl0ZUNvdW50czsKKworICAgIHByaXZhdGUgZmluYWwgRGlyZWN0aW9uIGRpcmVjdGlvbjsKKworICAgIElvVmVjKEJ5dGVCdWZmZXJbXSBieXRlQnVmZmVycywgaW50IG9mZnNldCwgaW50IGJ1ZmZlckNvdW50LCBEaXJlY3Rpb24gZGlyZWN0aW9uKSB7CisgICAgICAgIHRoaXMuYnl0ZUJ1ZmZlcnMgPSBieXRlQnVmZmVyczsKKyAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7CisgICAgICAgIHRoaXMuYnVmZmVyQ291bnQgPSBidWZmZXJDb3VudDsKKyAgICAgICAgdGhpcy5kaXJlY3Rpb24gPSBkaXJlY3Rpb247CisgICAgICAgIHRoaXMuaW9CdWZmZXJzID0gbmV3IE9iamVjdFtidWZmZXJDb3VudF07CisgICAgICAgIHRoaXMub2Zmc2V0cyA9IG5ldyBpbnRbYnVmZmVyQ291bnRdOworICAgICAgICB0aGlzLmJ5dGVDb3VudHMgPSBuZXcgaW50W2J1ZmZlckNvdW50XTsKKyAgICB9CisKKyAgICBpbnQgaW5pdCgpIHsKKyAgICAgICAgaW50IHRvdGFsUmVtYWluaW5nID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBidWZmZXJDb3VudDsgKytpKSB7CisgICAgICAgICAgICBCeXRlQnVmZmVyIGIgPSBieXRlQnVmZmVyc1tpICsgb2Zmc2V0XTsKKyAgICAgICAgICAgIGlmIChkaXJlY3Rpb24gPT0gRGlyZWN0aW9uLlJFQURWKSB7CisgICAgICAgICAgICAgICAgYi5jaGVja1dyaXRhYmxlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgcmVtYWluaW5nID0gYi5yZW1haW5pbmcoKTsKKyAgICAgICAgICAgIGlmIChiLmlzRGlyZWN0KCkpIHsKKyAgICAgICAgICAgICAgICBpb0J1ZmZlcnNbaV0gPSBiOworICAgICAgICAgICAgICAgIG9mZnNldHNbaV0gPSBiLnBvc2l0aW9uKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlvQnVmZmVyc1tpXSA9IE5pb1V0aWxzLnVuc2FmZUFycmF5KGIpOworICAgICAgICAgICAgICAgIG9mZnNldHNbaV0gPSBOaW9VdGlscy51bnNhZmVBcnJheU9mZnNldChiKSArIGIucG9zaXRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ5dGVDb3VudHNbaV0gPSByZW1haW5pbmc7CisgICAgICAgICAgICB0b3RhbFJlbWFpbmluZyArPSByZW1haW5pbmc7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRvdGFsUmVtYWluaW5nOworICAgIH0KKworICAgIGludCBkb1RyYW5zZmVyKEZpbGVEZXNjcmlwdG9yIGZkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGRpcmVjdGlvbiA9PSBEaXJlY3Rpb24uUkVBRFYpIHsKKyAgICAgICAgICAgICAgICBpbnQgcmVzdWx0ID0gTGliY29yZS5vcy5yZWFkdihmZCwgaW9CdWZmZXJzLCBvZmZzZXRzLCBieXRlQ291bnRzKTsKKyAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBMaWJjb3JlLm9zLndyaXRldihmZCwgaW9CdWZmZXJzLCBvZmZzZXRzLCBieXRlQ291bnRzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRocm93IGVycm5vRXhjZXB0aW9uLnJldGhyb3dBc0lPRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICB2b2lkIGRpZFRyYW5zZmVyKGludCBieXRlQ291bnQpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGJ5dGVDb3VudCA+IDAgJiYgaSA8IGJ1ZmZlckNvdW50OyArK2kpIHsKKyAgICAgICAgICAgIEJ5dGVCdWZmZXIgYiA9IGJ5dGVCdWZmZXJzW2kgKyBvZmZzZXRdOworICAgICAgICAgICAgaWYgKGJ5dGVDb3VudHNbaV0gPCBieXRlQ291bnQpIHsKKyAgICAgICAgICAgICAgICBiLnBvc2l0aW9uKGIubGltaXQoKSk7CisgICAgICAgICAgICAgICAgYnl0ZUNvdW50IC09IGJ5dGVDb3VudHNbaV07CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGIucG9zaXRpb24oKGRpcmVjdGlvbiA9PSBEaXJlY3Rpb24uV1JJVEVWID8gYi5wb3NpdGlvbigpIDogMCkgKyBieXRlQ291bnQpOworICAgICAgICAgICAgICAgIGJ5dGVDb3VudCA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vTG9uZ0FycmF5QnVmZmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vTG9uZ0FycmF5QnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGRkMGNmYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9Mb25nQXJyYXlCdWZmZXIuamF2YQpAQCAtMCwwICsxLDg2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCisvKioKKyAqIExvbmdBcnJheUJ1ZmZlciwgUmVhZFdyaXRlTG9uZ0FycmF5QnVmZmVyIGFuZCBSZWFkT25seUxvbmdBcnJheUJ1ZmZlciBjb21wb3NlCisgKiB0aGUgaW1wbGVtZW50YXRpb24gb2YgYXJyYXkgYmFzZWQgbG9uZyBidWZmZXJzLgorICogPHA+CisgKiBMb25nQXJyYXlCdWZmZXIgaW1wbGVtZW50cyBhbGwgdGhlIHNoYXJlZCByZWFkb25seSBtZXRob2RzIGFuZCBpcyBleHRlbmRlZCBieQorICogdGhlIG90aGVyIHR3byBjbGFzc2VzLgorICogPC9wPgorICogPHA+CisgKiBBbGwgbWV0aG9kcyBhcmUgbWFya2VkIGZpbmFsIGZvciBydW50aW1lIHBlcmZvcm1hbmNlLgorICogPC9wPgorICoKKyAqLworYWJzdHJhY3QgY2xhc3MgTG9uZ0FycmF5QnVmZmVyIGV4dGVuZHMgTG9uZ0J1ZmZlciB7CisKKyAgICBwcm90ZWN0ZWQgZmluYWwgbG9uZ1tdIGJhY2tpbmdBcnJheTsKKworICAgIHByb3RlY3RlZCBmaW5hbCBpbnQgb2Zmc2V0OworCisgICAgTG9uZ0FycmF5QnVmZmVyKGxvbmdbXSBhcnJheSkgeworICAgICAgICB0aGlzKGFycmF5Lmxlbmd0aCwgYXJyYXksIDApOworICAgIH0KKworICAgIExvbmdBcnJheUJ1ZmZlcihpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgdGhpcyhjYXBhY2l0eSwgbmV3IGxvbmdbY2FwYWNpdHldLCAwKTsKKyAgICB9CisKKyAgICBMb25nQXJyYXlCdWZmZXIoaW50IGNhcGFjaXR5LCBsb25nW10gYmFja2luZ0FycmF5LCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIHN1cGVyKGNhcGFjaXR5KTsKKyAgICAgICAgdGhpcy5iYWNraW5nQXJyYXkgPSBiYWNraW5nQXJyYXk7CisgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBsb25nIGdldCgpIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJhY2tpbmdBcnJheVtvZmZzZXQgKyBwb3NpdGlvbisrXTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgbG9uZyBnZXQoaW50IGluZGV4KSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICByZXR1cm4gYmFja2luZ0FycmF5W29mZnNldCArIGluZGV4XTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgTG9uZ0J1ZmZlciBnZXQobG9uZ1tdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGxvbmdDb3VudCkgeworICAgICAgICBpZiAobG9uZ0NvdW50ID4gcmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJhY2tpbmdBcnJheSwgb2Zmc2V0ICsgcG9zaXRpb24sIGRzdCwgZHN0T2Zmc2V0LCBsb25nQ291bnQpOworICAgICAgICBwb3NpdGlvbiArPSBsb25nQ291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzRGlyZWN0KCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIEJ5dGVPcmRlciBvcmRlcigpIHsKKyAgICAgICAgcmV0dXJuIEJ5dGVPcmRlci5uYXRpdmVPcmRlcigpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0xvbmdCdWZmZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9Mb25nQnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjdlZGQyZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9Mb25nQnVmZmVyLmphdmEKQEAgLTAsMCArMSw0NzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW87CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIEEgYnVmZmVyIG9mIGxvbmdzLgorICogPHA+CisgKiBBIGxvbmcgYnVmZmVyIGNhbiBiZSBjcmVhdGVkIGluIGVpdGhlciBvZiB0aGUgZm9sbG93aW5nIHdheXM6CisgKiA8dWw+CisgKiA8bGk+e0BsaW5rICNhbGxvY2F0ZShpbnQpIEFsbG9jYXRlfSBhIG5ldyBsb25nIGFycmF5IGFuZCBjcmVhdGUgYSBidWZmZXIKKyAqIGJhc2VkIG9uIGl0OzwvbGk+CisgKiA8bGk+e0BsaW5rICN3cmFwKGxvbmdbXSkgV3JhcH0gYW4gZXhpc3RpbmcgbG9uZyBhcnJheSB0byBjcmVhdGUgYSBuZXcKKyAqIGJ1ZmZlcjs8L2xpPgorICogPGxpPlVzZSB7QGxpbmsgamF2YS5uaW8uQnl0ZUJ1ZmZlciNhc0xvbmdCdWZmZXIoKSBCeXRlQnVmZmVyLmFzTG9uZ0J1ZmZlcn0KKyAqIHRvIGNyZWF0ZSBhIGxvbmcgYnVmZmVyIGJhc2VkIG9uIGEgYnl0ZSBidWZmZXIuPC9saT4KKyAqIDwvdWw+CisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBMb25nQnVmZmVyIGV4dGVuZHMgQnVmZmVyIGltcGxlbWVudHMKKyAgICAgICAgQ29tcGFyYWJsZTxMb25nQnVmZmVyPiB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbG9uZyBidWZmZXIgYmFzZWQgb24gYSBuZXdseSBhbGxvY2F0ZWQgbG9uZyBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXBhY2l0eQorICAgICAqICAgICAgICAgICAgdGhlIGNhcGFjaXR5IG9mIHRoZSBuZXcgYnVmZmVyLgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgbG9uZyBidWZmZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY2FwYWNpdHl9IGlzIGxlc3MgdGhhbiB6ZXJvLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTG9uZ0J1ZmZlciBhbGxvY2F0ZShpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgaWYgKGNhcGFjaXR5IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgUmVhZFdyaXRlTG9uZ0FycmF5QnVmZmVyKGNhcGFjaXR5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGxvbmcgYnVmZmVyIGJ5IHdyYXBwaW5nIHRoZSBnaXZlbiBsb25nIGFycmF5LgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcworICAgICAqIHtAY29kZSB3cmFwKGFycmF5LCAwLCBhcnJheS5sZW5ndGgpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGxvbmcgYXJyYXkgd2hpY2ggdGhlIG5ldyBidWZmZXIgd2lsbCBiZSBiYXNlZCBvbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBjcmVhdGVkIGxvbmcgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTG9uZ0J1ZmZlciB3cmFwKGxvbmdbXSBhcnJheSkgeworICAgICAgICByZXR1cm4gd3JhcChhcnJheSwgMCwgYXJyYXkubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGxvbmcgYnVmZmVyIGJ5IHdyYXBwaW5nIHRoZSBnaXZlbiBsb25nIGFycmF5LgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyJ3MgcG9zaXRpb24gd2lsbCBiZSB7QGNvZGUgc3RhcnR9LCBsaW1pdCB3aWxsIGJlCisgICAgICoge0Bjb2RlIHN0YXJ0ICsgbG9uZ0NvdW50fSwgY2FwYWNpdHkgd2lsbCBiZSB0aGUgbGVuZ3RoIG9mIHRoZSBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGxvbmcgYXJyYXkgd2hpY2ggdGhlIG5ldyBidWZmZXIgd2lsbCBiZSBiYXNlZCBvbi4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBpbmRleCwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIG5vdCBncmVhdGVyIHRoYW4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBhcnJheS5sZW5ndGh9LgorICAgICAqIEBwYXJhbSBsb25nQ291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgICAgICB7QGNvZGUgYXJyYXkubGVuZ3RoIC0gc3RhcnR9LgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgbG9uZyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgZWl0aGVyIHtAY29kZSBzdGFydH0gb3Ige0Bjb2RlIGxvbmdDb3VudH0gaXMgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIExvbmdCdWZmZXIgd3JhcChsb25nW10gYXJyYXksIGludCBzdGFydCwgaW50IGxvbmdDb3VudCkgeworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChhcnJheS5sZW5ndGgsIHN0YXJ0LCBsb25nQ291bnQpOworICAgICAgICBMb25nQnVmZmVyIGJ1ZiA9IG5ldyBSZWFkV3JpdGVMb25nQXJyYXlCdWZmZXIoYXJyYXkpOworICAgICAgICBidWYucG9zaXRpb24gPSBzdGFydDsKKyAgICAgICAgYnVmLmxpbWl0ID0gc3RhcnQgKyBsb25nQ291bnQ7CisgICAgICAgIHJldHVybiBidWY7CisgICAgfQorCisgICAgTG9uZ0J1ZmZlcihpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgc3VwZXIoMywgY2FwYWNpdHksIG51bGwpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBsb25nW10gYXJyYXkoKSB7CisgICAgICAgIHJldHVybiBwcm90ZWN0ZWRBcnJheSgpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBpbnQgYXJyYXlPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBwcm90ZWN0ZWRBcnJheU9mZnNldCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSByZWFkLW9ubHkgYnVmZmVyIHRoYXQgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIuCisgICAgICogPHA+CisgICAgICogVGhlIHJldHVybmVkIGJ1ZmZlciBpcyBndWFyYW50ZWVkIHRvIGJlIGEgbmV3IGluc3RhbmNlLCBldmVuIGlmIHRoaXMKKyAgICAgKiBidWZmZXIgaXMgcmVhZC1vbmx5IGl0c2VsZi4gVGhlIG5ldyBidWZmZXIncyBwb3NpdGlvbiwgbGltaXQsIGNhcGFjaXR5CisgICAgICogYW5kIG1hcmsgYXJlIHRoZSBzYW1lIGFzIHRoaXMgYnVmZmVyJ3MuCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIsIHdoaWNoIG1lYW5zIHRoaXMKKyAgICAgKiBidWZmZXIncyBjaGFuZ2Ugb2YgY29udGVudCB3aWxsIGJlIHZpc2libGUgdG8gdGhlIG5ldyBidWZmZXIuIFRoZSB0d28KKyAgICAgKiBidWZmZXIncyBwb3NpdGlvbiwgbGltaXQgYW5kIG1hcmsgYXJlIGluZGVwZW5kZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIHJlYWQtb25seSB2ZXJzaW9uIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBMb25nQnVmZmVyIGFzUmVhZE9ubHlCdWZmZXIoKTsKKworICAgIC8qKgorICAgICAqIENvbXBhY3RzIHRoaXMgbG9uZyBidWZmZXIuCisgICAgICogPHA+CisgICAgICogVGhlIHJlbWFpbmluZyBsb25ncyB3aWxsIGJlIG1vdmVkIHRvIHRoZSBoZWFkIG9mIHRoZSBidWZmZXIsIHN0YXJpbmcgZnJvbQorICAgICAqIHBvc2l0aW9uIHplcm8uIFRoZW4gdGhlIHBvc2l0aW9uIGlzIHNldCB0byB7QGNvZGUgcmVtYWluaW5nKCl9OyB0aGUKKyAgICAgKiBsaW1pdCBpcyBzZXQgdG8gY2FwYWNpdHk7IHRoZSBtYXJrIGlzIGNsZWFyZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgTG9uZ0J1ZmZlciBjb21wYWN0KCk7CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlIHRoZSByZW1haW5pbmcgbG9uZ3Mgb2YgdGhpcyBidWZmZXIgdG8gYW5vdGhlciBsb25nIGJ1ZmZlcidzCisgICAgICogcmVtYWluaW5nIGxvbmdzLgorICAgICAqCisgICAgICogQHBhcmFtIG90aGVyQnVmZmVyCisgICAgICogICAgICAgICAgICBhbm90aGVyIGxvbmcgYnVmZmVyLgorICAgICAqIEByZXR1cm4gYSBuZWdhdGl2ZSB2YWx1ZSBpZiB0aGlzIGlzIGxlc3MgdGhhbiB7QGNvZGUgb3RoZXJCdWZmZXJ9OyAwIGlmCisgICAgICogICAgICAgICB0aGlzIGVxdWFscyB0byB7QGNvZGUgb3RoZXJCdWZmZXJ9OyBhIHBvc2l0aXZlIHZhbHVlIGlmIHRoaXMgaXMKKyAgICAgKiAgICAgICAgIGdyZWF0ZXIgdGhhbiB7QGNvZGUgb3RoZXJCdWZmZXJ9CisgICAgICogQGV4Y2VwdGlvbiBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgb3RoZXJCdWZmZXJ9IGlzIG5vdCBhIGxvbmcgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKExvbmdCdWZmZXIgb3RoZXJCdWZmZXIpIHsKKyAgICAgICAgaW50IGNvbXBhcmVSZW1haW5pbmcgPSAocmVtYWluaW5nKCkgPCBvdGhlckJ1ZmZlci5yZW1haW5pbmcoKSkgPyByZW1haW5pbmcoKQorICAgICAgICAgICAgICAgIDogb3RoZXJCdWZmZXIucmVtYWluaW5nKCk7CisgICAgICAgIGludCB0aGlzUG9zID0gcG9zaXRpb247CisgICAgICAgIGludCBvdGhlclBvcyA9IG90aGVyQnVmZmVyLnBvc2l0aW9uOworICAgICAgICBsb25nIHRoaXNMb25nLCBvdGhlckxvbmc7CisgICAgICAgIHdoaWxlIChjb21wYXJlUmVtYWluaW5nID4gMCkgeworICAgICAgICAgICAgdGhpc0xvbmcgPSBnZXQodGhpc1Bvcyk7CisgICAgICAgICAgICBvdGhlckxvbmcgPSBvdGhlckJ1ZmZlci5nZXQob3RoZXJQb3MpOworICAgICAgICAgICAgaWYgKHRoaXNMb25nICE9IG90aGVyTG9uZykgeworICAgICAgICAgICAgICAgIHJldHVybiB0aGlzTG9uZyA8IG90aGVyTG9uZyA/IC0xIDogMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXNQb3MrKzsKKyAgICAgICAgICAgIG90aGVyUG9zKys7CisgICAgICAgICAgICBjb21wYXJlUmVtYWluaW5nLS07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlbWFpbmluZygpIC0gb3RoZXJCdWZmZXIucmVtYWluaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGR1cGxpY2F0ZWQgYnVmZmVyIHRoYXQgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIuCisgICAgICogPHA+CisgICAgICogVGhlIGR1cGxpY2F0ZWQgYnVmZmVyJ3MgcG9zaXRpb24sIGxpbWl0LCBjYXBhY2l0eSBhbmQgbWFyayBhcmUgdGhlIHNhbWUKKyAgICAgKiBhcyB0aGlzIGJ1ZmZlci4gVGhlIGR1cGxpY2F0ZWQgYnVmZmVyJ3MgcmVhZC1vbmx5IHByb3BlcnR5IGFuZCBieXRlIG9yZGVyCisgICAgICogYXJlIHNhbWUgYXMgdGhpcyBidWZmZXIncywgdG9vLgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyIHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLCB3aGljaCBtZWFucyBlaXRoZXIKKyAgICAgKiBidWZmZXIncyBjaGFuZ2Ugb2YgY29udGVudCB3aWxsIGJlIHZpc2libGUgdG8gdGhlIG90aGVyLiBUaGUgdHdvIGJ1ZmZlcidzCisgICAgICogcG9zaXRpb24sIGxpbWl0IGFuZCBtYXJrIGFyZSBpbmRlcGVuZGVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBkdXBsaWNhdGVkIGJ1ZmZlciB0aGF0IHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBMb25nQnVmZmVyIGR1cGxpY2F0ZSgpOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhpcyBsb25nIGJ1ZmZlciBpcyBlcXVhbCB0byBhbm90aGVyIG9iamVjdC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB7QGNvZGUgb3RoZXJ9IGlzIG5vdCBhIGxvbmcgYnVmZmVyIHRoZW4ge0Bjb2RlIGZhbHNlfSBpcyByZXR1cm5lZC4gVHdvCisgICAgICogbG9uZyBidWZmZXJzIGFyZSBlcXVhbCBpZiBhbmQgb25seSBpZiB0aGVpciByZW1haW5pbmcgbG9uZ3MgYXJlIGV4YWN0bHkKKyAgICAgKiB0aGUgc2FtZS4gUG9zaXRpb24sIGxpbWl0LCBjYXBhY2l0eSBhbmQgbWFyayBhcmUgbm90IGNvbnNpZGVyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3RoZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB3aXRoIHRoaXMgbG9uZyBidWZmZXIuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBsb25nIGJ1ZmZlciBpcyBlcXVhbCB0byB7QGNvZGUgb3RoZXJ9LAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgeworICAgICAgICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIExvbmdCdWZmZXIpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgTG9uZ0J1ZmZlciBvdGhlckJ1ZmZlciA9IChMb25nQnVmZmVyKSBvdGhlcjsKKworICAgICAgICBpZiAocmVtYWluaW5nKCkgIT0gb3RoZXJCdWZmZXIucmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBteVBvc2l0aW9uID0gcG9zaXRpb247CisgICAgICAgIGludCBvdGhlclBvc2l0aW9uID0gb3RoZXJCdWZmZXIucG9zaXRpb247CisgICAgICAgIGJvb2xlYW4gZXF1YWxTb0ZhciA9IHRydWU7CisgICAgICAgIHdoaWxlIChlcXVhbFNvRmFyICYmIChteVBvc2l0aW9uIDwgbGltaXQpKSB7CisgICAgICAgICAgICBlcXVhbFNvRmFyID0gZ2V0KG15UG9zaXRpb24rKykgPT0gb3RoZXJCdWZmZXIuZ2V0KG90aGVyUG9zaXRpb24rKyk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZXF1YWxTb0ZhcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb25nIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBpbmNyZWFzZSB0aGUgcG9zaXRpb24gYnkgMS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxvbmcgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgcG9zaXRpb24gaXMgZXF1YWwgb3IgZ3JlYXRlciB0aGFuIGxpbWl0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBsb25nIGdldCgpOworCisgICAgLyoqCisgICAgICogUmVhZHMgbG9uZ3MgZnJvbSB0aGUgY3VycmVudCBwb3NpdGlvbiBpbnRvIHRoZSBzcGVjaWZpZWQgbG9uZyBhcnJheSBhbmQKKyAgICAgKiBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IHRoZSBudW1iZXIgb2YgbG9uZ3MgcmVhZC4KKyAgICAgKiA8cD4KKyAgICAgKiBDYWxsaW5nIHRoaXMgbWV0aG9kIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMKKyAgICAgKiB7QGNvZGUgZ2V0KGRzdCwgMCwgZHN0Lmxlbmd0aCl9LgorICAgICAqCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIGRlc3RpbmF0aW9uIGxvbmcgYXJyYXkuCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBkc3QubGVuZ3RofSBpcyBncmVhdGVyIHRoYW4ge0Bjb2RlIHJlbWFpbmluZygpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTG9uZ0J1ZmZlciBnZXQobG9uZ1tdIGRzdCkgeworICAgICAgICByZXR1cm4gZ2V0KGRzdCwgMCwgZHN0Lmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgbG9uZ3MgZnJvbSB0aGUgY3VycmVudCBwb3NpdGlvbiBpbnRvIHRoZSBzcGVjaWZpZWQgbG9uZyBhcnJheSwKKyAgICAgKiBzdGFydGluZyBmcm9tIHRoZSBzcGVjaWZpZWQgb2Zmc2V0LCBhbmQgaW5jcmVhc2UgdGhlIHBvc2l0aW9uIGJ5IHRoZQorICAgICAqIG51bWJlciBvZiBsb25ncyByZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBsb25nIGFycmF5LgorICAgICAqIEBwYXJhbSBkc3RPZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgb2YgdGhlIGxvbmcgYXJyYXksIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QKKyAgICAgKiAgICAgICAgICAgIGdyZWF0ZXIgdGhhbiB7QGNvZGUgZHN0Lmxlbmd0aH0uCisgICAgICogQHBhcmFtIGxvbmdDb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBsb25ncyB0byByZWFkLCBtdXN0IGJlIG5vIGxlc3MgdGhhbiB6ZXJvIGFuZCBub3QKKyAgICAgKiAgICAgICAgICAgIGdyZWF0ZXIgdGhhbiB7QGNvZGUgZHN0Lmxlbmd0aCAtIGRzdE9mZnNldH0uCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBlaXRoZXIge0Bjb2RlIGRzdE9mZnNldH0gb3Ige0Bjb2RlIGxvbmdDb3VudH0gaXMgaW52YWxpZC4KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBsb25nQ291bnR9IGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgcmVtYWluaW5nKCl9LgorICAgICAqLworICAgIHB1YmxpYyBMb25nQnVmZmVyIGdldChsb25nW10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgbG9uZ0NvdW50KSB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGRzdC5sZW5ndGgsIGRzdE9mZnNldCwgbG9uZ0NvdW50KTsKKyAgICAgICAgaWYgKGxvbmdDb3VudCA+IHJlbWFpbmluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IGRzdE9mZnNldDsgaSA8IGRzdE9mZnNldCArIGxvbmdDb3VudDsgKytpKSB7CisgICAgICAgICAgICBkc3RbaV0gPSBnZXQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb25nIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXg7IHRoZSBwb3NpdGlvbiBpcyBub3QgY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBhbmQgbGVzcyB0aGFuIGxpbWl0LgorICAgICAqIEByZXR1cm4gdGhlIGxvbmcgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBpbmRleCBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBsb25nIGdldChpbnQgaW5kZXgpOworCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaGFzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBwcm90ZWN0ZWRIYXNBcnJheSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGN1bGF0ZXMgdGhpcyBidWZmZXIncyBoYXNoIGNvZGUgZnJvbSB0aGUgcmVtYWluaW5nIGNoYXJzLiBUaGUKKyAgICAgKiBwb3NpdGlvbiwgbGltaXQsIGNhcGFjaXR5IGFuZCBtYXJrIGRvbid0IGFmZmVjdCB0aGUgaGFzaCBjb2RlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIGNhbGN1bGF0ZWQgZnJvbSB0aGUgcmVtYWluaW5nIGxvbmdzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGludCBteVBvc2l0aW9uID0gcG9zaXRpb247CisgICAgICAgIGludCBoYXNoID0gMDsKKyAgICAgICAgbG9uZyBsOworICAgICAgICB3aGlsZSAobXlQb3NpdGlvbiA8IGxpbWl0KSB7CisgICAgICAgICAgICBsID0gZ2V0KG15UG9zaXRpb24rKyk7CisgICAgICAgICAgICBoYXNoID0gaGFzaCArICgoaW50KSBsKSBeICgoaW50KSAobCA+PiAzMikpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBoYXNoOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgYnVmZmVyIGlzIGRpcmVjdC4gQSBkaXJlY3QgYnVmZmVyIHdpbGwgdHJ5IGl0cworICAgICAqIGJlc3QgdG8gdGFrZSBhZHZhbnRhZ2Ugb2YgbmF0aXZlIG1lbW9yeSBBUElzIGFuZCBpdCBtYXkgbm90IHN0YXkgaW4gdGhlCisgICAgICogSmF2YSBoZWFwLCBzbyBpdCBpcyBub3QgYWZmZWN0ZWQgYnkgZ2FyYmFnZSBjb2xsZWN0aW9uLgorICAgICAqIDxwPgorICAgICAqIEEgbG9uZyBidWZmZXIgaXMgZGlyZWN0IGlmIGl0IGlzIGJhc2VkIG9uIGEgYnl0ZSBidWZmZXIgYW5kIHRoZSBieXRlCisgICAgICogYnVmZmVyIGlzIGRpcmVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgYnVmZmVyIGlzIGRpcmVjdCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNEaXJlY3QoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGJ5dGUgb3JkZXIgdXNlZCBieSB0aGlzIGJ1ZmZlciB3aGVuIGNvbnZlcnRpbmcgbG9uZ3MgZnJvbS90bworICAgICAqIGJ5dGVzLgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgYnVmZmVyIGlzIG5vdCBiYXNlZCBvbiBhIGJ5dGUgYnVmZmVyLCB0aGVuIGFsd2F5cyByZXR1cm4gdGhlCisgICAgICogcGxhdGZvcm0ncyBuYXRpdmUgYnl0ZSBvcmRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgb3JkZXIgdXNlZCBieSB0aGlzIGJ1ZmZlciB3aGVuIGNvbnZlcnRpbmcgbG9uZ3MgZnJvbS90bworICAgICAqICAgICAgICAgYnl0ZXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ5dGVPcmRlciBvcmRlcigpOworCisgICAgLyoqCisgICAgICogQ2hpbGQgY2xhc3MgaW1wbGVtZW50cyB0aGlzIG1ldGhvZCB0byByZWFsaXplIHtAY29kZSBhcnJheSgpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gc2VlIHtAY29kZSBhcnJheSgpfQorICAgICAqLworICAgIGFic3RyYWN0IGxvbmdbXSBwcm90ZWN0ZWRBcnJheSgpOworCisgICAgLyoqCisgICAgICogQ2hpbGQgY2xhc3MgaW1wbGVtZW50cyB0aGlzIG1ldGhvZCB0byByZWFsaXplIHtAY29kZSBhcnJheU9mZnNldCgpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gc2VlIHtAY29kZSBhcnJheU9mZnNldCgpfQorICAgICAqLworICAgIGFic3RyYWN0IGludCBwcm90ZWN0ZWRBcnJheU9mZnNldCgpOworCisgICAgLyoqCisgICAgICogQ2hpbGQgY2xhc3MgaW1wbGVtZW50cyB0aGlzIG1ldGhvZCB0byByZWFsaXplIHtAY29kZSBoYXNBcnJheSgpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gc2VlIHtAY29kZSBoYXNBcnJheSgpfQorICAgICAqLworICAgIGFic3RyYWN0IGJvb2xlYW4gcHJvdGVjdGVkSGFzQXJyYXkoKTsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgZ2l2ZW4gbG9uZyB0byB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQgaW5jcmVhc2VzIHRoZSBwb3NpdGlvbgorICAgICAqIGJ5IDEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIGxvbmcgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcG9zaXRpb24gaXMgZXF1YWwgb3IgZ3JlYXRlciB0aGFuIGxpbWl0LgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgTG9uZ0J1ZmZlciBwdXQobG9uZyBsKTsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyBsb25ncyBmcm9tIHRoZSBnaXZlbiBsb25nIGFycmF5IHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZAorICAgICAqIGluY3JlYXNlcyB0aGUgcG9zaXRpb24gYnkgdGhlIG51bWJlciBvZiBsb25ncyB3cml0dGVuLgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcworICAgICAqIHtAY29kZSBwdXQoc3JjLCAwLCBzcmMubGVuZ3RoKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGxvbmcgYXJyYXkuCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHJlbWFpbmluZygpfSBpcyBsZXNzIHRoYW4ge0Bjb2RlIHNyYy5sZW5ndGh9LgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgTG9uZ0J1ZmZlciBwdXQobG9uZ1tdIHNyYykgeworICAgICAgICByZXR1cm4gcHV0KHNyYywgMCwgc3JjLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGxvbmdzIGZyb20gdGhlIGdpdmVuIGxvbmcgYXJyYXksIHN0YXJ0aW5nIGZyb20gdGhlIHNwZWNpZmllZAorICAgICAqIG9mZnNldCwgdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gYW5kIGluY3JlYXNlcyB0aGUgcG9zaXRpb24gYnkgdGhlIG51bWJlcgorICAgICAqIG9mIGxvbmdzIHdyaXR0ZW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGxvbmcgYXJyYXkuCisgICAgICogQHBhcmFtIHNyY09mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvZiBsb25nIGFycmF5LCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBhbmQgbm90IGdyZWF0ZXIKKyAgICAgKiAgICAgICAgICAgIHRoYW4ge0Bjb2RlIHNyYy5sZW5ndGh9LgorICAgICAqIEBwYXJhbSBsb25nQ291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgbG9uZ3MgdG8gd3JpdGUsIG11c3QgYmUgbm8gbGVzcyB0aGFuIHplcm8gYW5kCisgICAgICogICAgICAgICAgICBub3QgZ3JlYXRlciB0aGFuIHtAY29kZSBzcmMubGVuZ3RoIC0gc3JjT2Zmc2V0fS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgcmVtYWluaW5nKCl9IGlzIGxlc3MgdGhhbiB7QGNvZGUgbG9uZ0NvdW50fS4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBlaXRoZXIge0Bjb2RlIHNyY09mZnNldH0gb3Ige0Bjb2RlIGxvbmdDb3VudH0gaXMgaW52YWxpZC4KKyAgICAgKiBAZXhjZXB0aW9uIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbm8gY2hhbmdlcyBtYXkgYmUgbWFkZSB0byB0aGUgY29udGVudHMgb2YgdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIExvbmdCdWZmZXIgcHV0KGxvbmdbXSBzcmMsIGludCBzcmNPZmZzZXQsIGludCBsb25nQ291bnQpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoc3JjLmxlbmd0aCwgc3JjT2Zmc2V0LCBsb25nQ291bnQpOworICAgICAgICBpZiAobG9uZ0NvdW50ID4gcmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSBzcmNPZmZzZXQ7IGkgPCBzcmNPZmZzZXQgKyBsb25nQ291bnQ7ICsraSkgeworICAgICAgICAgICAgcHV0KHNyY1tpXSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGFsbCB0aGUgcmVtYWluaW5nIGxvbmdzIG9mIHRoZSB7QGNvZGUgc3JjfSBsb25nIGJ1ZmZlciB0byB0aGlzCisgICAgICogYnVmZmVyJ3MgY3VycmVudCBwb3NpdGlvbiwgYW5kIGluY3JlYXNlcyBib3RoIGJ1ZmZlcnMnIHBvc2l0aW9uIGJ5IHRoZQorICAgICAqIG51bWJlciBvZiBsb25ncyBjb3BpZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGxvbmcgYnVmZmVyLgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzcmMucmVtYWluaW5nKCl9IGlzIGdyZWF0ZXIgdGhhbiB0aGlzIGJ1ZmZlcidzCisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIHJlbWFpbmluZygpfS4KKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzcmN9IGlzIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgTG9uZ0J1ZmZlciBwdXQoTG9uZ0J1ZmZlciBzcmMpIHsKKyAgICAgICAgaWYgKHNyYyA9PSB0aGlzKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNyYy5yZW1haW5pbmcoKSA+IHJlbWFpbmluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBsb25nW10gY29udGVudHMgPSBuZXcgbG9uZ1tzcmMucmVtYWluaW5nKCldOworICAgICAgICBzcmMuZ2V0KGNvbnRlbnRzKTsKKyAgICAgICAgcHV0KGNvbnRlbnRzKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgbG9uZyB0byB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgYnVmZmVyOyB0aGUgcG9zaXRpb24gaXMgbm90CisgICAgICogY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4LCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSBhbmQgbGVzcyB0aGFuIHRoZSBsaW1pdC4KKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIGxvbmcgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBpbmRleCBpcyBpbnZhbGlkLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgTG9uZ0J1ZmZlciBwdXQoaW50IGluZGV4LCBsb25nIGwpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNsaWNlZCBidWZmZXIgdGhhdCBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgc2xpY2VkIGJ1ZmZlcidzIGNhcGFjaXR5IHdpbGwgYmUgdGhpcyBidWZmZXIncyB7QGNvZGUgcmVtYWluaW5nKCl9LAorICAgICAqIGFuZCBpdHMgemVybyBwb3NpdGlvbiB3aWxsIGNvcnJlc3BvbmQgdG8gdGhpcyBidWZmZXIncyBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqIFRoZSBuZXcgYnVmZmVyJ3MgcG9zaXRpb24gd2lsbCBiZSAwLCBsaW1pdCB3aWxsIGJlIGl0cyBjYXBhY2l0eSwgYW5kIGl0cworICAgICAqIG1hcmsgaXMgY2xlYXJlZC4gVGhlIG5ldyBidWZmZXIncyByZWFkLW9ubHkgcHJvcGVydHkgYW5kIGJ5dGUgb3JkZXIgYXJlCisgICAgICogc2FtZSBhcyB0aGlzIGJ1ZmZlcidzLgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyIHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLCB3aGljaCBtZWFucyBlaXRoZXIKKyAgICAgKiBidWZmZXIncyBjaGFuZ2Ugb2YgY29udGVudCB3aWxsIGJlIHZpc2libGUgdG8gdGhlIG90aGVyLiBUaGUgdHdvIGJ1ZmZlcidzCisgICAgICogcG9zaXRpb24sIGxpbWl0IGFuZCBtYXJrIGFyZSBpbmRlcGVuZGVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzbGljZWQgYnVmZmVyIHRoYXQgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IExvbmdCdWZmZXIgc2xpY2UoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9Mb25nVG9CeXRlQnVmZmVyQWRhcHRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL0xvbmdUb0J5dGVCdWZmZXJBZGFwdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWY1MWQ5NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9Mb25nVG9CeXRlQnVmZmVyQWRhcHRlci5qYXZhCkBAIC0wLDAgKzEsMTgyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCitpbXBvcnQgbGliY29yZS5pby5TaXplT2Y7CisKKy8qKgorICogVGhpcyBjbGFzcyB3cmFwcyBhIGJ5dGUgYnVmZmVyIHRvIGJlIGEgbG9uZyBidWZmZXIuCisgKiA8cD4KKyAqIEltcGxlbWVudGF0aW9uIG5vdGljZToKKyAqIDx1bD4KKyAqIDxsaT5BZnRlciBhIGJ5dGUgYnVmZmVyIGluc3RhbmNlIGlzIHdyYXBwZWQsIGl0IGJlY29tZXMgcHJpdmF0ZWx5IG93bmVkIGJ5CisgKiB0aGUgYWRhcHRlci4gSXQgbXVzdCBOT1QgYmUgYWNjZXNzZWQgb3V0c2lkZSB0aGUgYWRhcHRlciBhbnkgbW9yZS48L2xpPgorICogPGxpPlRoZSBieXRlIGJ1ZmZlcidzIHBvc2l0aW9uIGFuZCBsaW1pdCBhcmUgTk9UIGxpbmtlZCB3aXRoIHRoZSBhZGFwdGVyLgorICogVGhlIGFkYXB0ZXIgZXh0ZW5kcyBCdWZmZXIsIHRodXMgaGFzIGl0cyBvd24gcG9zaXRpb24gYW5kIGxpbWl0LjwvbGk+CisgKiA8L3VsPgorICogPC9wPgorICoKKyAqLworZmluYWwgY2xhc3MgTG9uZ1RvQnl0ZUJ1ZmZlckFkYXB0ZXIgZXh0ZW5kcyBMb25nQnVmZmVyIHsKKworICAgIHByaXZhdGUgZmluYWwgQnl0ZUJ1ZmZlciBieXRlQnVmZmVyOworCisgICAgc3RhdGljIExvbmdCdWZmZXIgYXNMb25nQnVmZmVyKEJ5dGVCdWZmZXIgYnl0ZUJ1ZmZlcikgeworICAgICAgICBCeXRlQnVmZmVyIHNsaWNlID0gYnl0ZUJ1ZmZlci5zbGljZSgpOworICAgICAgICBzbGljZS5vcmRlcihieXRlQnVmZmVyLm9yZGVyKCkpOworICAgICAgICByZXR1cm4gbmV3IExvbmdUb0J5dGVCdWZmZXJBZGFwdGVyKHNsaWNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIExvbmdUb0J5dGVCdWZmZXJBZGFwdGVyKEJ5dGVCdWZmZXIgYnl0ZUJ1ZmZlcikgeworICAgICAgICBzdXBlcihieXRlQnVmZmVyLmNhcGFjaXR5KCkgLyBTaXplT2YuTE9ORyk7CisgICAgICAgIHRoaXMuYnl0ZUJ1ZmZlciA9IGJ5dGVCdWZmZXI7CisgICAgICAgIHRoaXMuYnl0ZUJ1ZmZlci5jbGVhcigpOworICAgICAgICB0aGlzLmVmZmVjdGl2ZURpcmVjdEFkZHJlc3MgPSBieXRlQnVmZmVyLmVmZmVjdGl2ZURpcmVjdEFkZHJlc3M7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIExvbmdCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpIHsKKyAgICAgICAgTG9uZ1RvQnl0ZUJ1ZmZlckFkYXB0ZXIgYnVmID0gbmV3IExvbmdUb0J5dGVCdWZmZXJBZGFwdGVyKGJ5dGVCdWZmZXIuYXNSZWFkT25seUJ1ZmZlcigpKTsKKyAgICAgICAgYnVmLmxpbWl0ID0gbGltaXQ7CisgICAgICAgIGJ1Zi5wb3NpdGlvbiA9IHBvc2l0aW9uOworICAgICAgICBidWYubWFyayA9IG1hcms7CisgICAgICAgIGJ1Zi5ieXRlQnVmZmVyLm9yZGVyID0gYnl0ZUJ1ZmZlci5vcmRlcjsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTG9uZ0J1ZmZlciBjb21wYWN0KCkgeworICAgICAgICBpZiAoYnl0ZUJ1ZmZlci5pc1JlYWRPbmx5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGJ5dGVCdWZmZXIubGltaXQobGltaXQgKiBTaXplT2YuTE9ORyk7CisgICAgICAgIGJ5dGVCdWZmZXIucG9zaXRpb24ocG9zaXRpb24gKiBTaXplT2YuTE9ORyk7CisgICAgICAgIGJ5dGVCdWZmZXIuY29tcGFjdCgpOworICAgICAgICBieXRlQnVmZmVyLmNsZWFyKCk7CisgICAgICAgIHBvc2l0aW9uID0gbGltaXQgLSBwb3NpdGlvbjsKKyAgICAgICAgbGltaXQgPSBjYXBhY2l0eTsKKyAgICAgICAgbWFyayA9IFVOU0VUX01BUks7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBMb25nQnVmZmVyIGR1cGxpY2F0ZSgpIHsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYiA9IGJ5dGVCdWZmZXIuZHVwbGljYXRlKCkub3JkZXIoYnl0ZUJ1ZmZlci5vcmRlcigpKTsKKyAgICAgICAgTG9uZ1RvQnl0ZUJ1ZmZlckFkYXB0ZXIgYnVmID0gbmV3IExvbmdUb0J5dGVCdWZmZXJBZGFwdGVyKGJiKTsKKyAgICAgICAgYnVmLmxpbWl0ID0gbGltaXQ7CisgICAgICAgIGJ1Zi5wb3NpdGlvbiA9IHBvc2l0aW9uOworICAgICAgICBidWYubWFyayA9IG1hcms7CisgICAgICAgIHJldHVybiBidWY7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0KCkgeworICAgICAgICBpZiAocG9zaXRpb24gPT0gbGltaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnl0ZUJ1ZmZlci5nZXRMb25nKHBvc2l0aW9uKysgKiBTaXplT2YuTE9ORyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0KGludCBpbmRleCkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4KTsKKyAgICAgICAgcmV0dXJuIGJ5dGVCdWZmZXIuZ2V0TG9uZyhpbmRleCAqIFNpemVPZi5MT05HKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTG9uZ0J1ZmZlciBnZXQobG9uZ1tdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGxvbmdDb3VudCkgeworICAgICAgICBieXRlQnVmZmVyLmxpbWl0KGxpbWl0ICogU2l6ZU9mLkxPTkcpOworICAgICAgICBieXRlQnVmZmVyLnBvc2l0aW9uKHBvc2l0aW9uICogU2l6ZU9mLkxPTkcpOworICAgICAgICBpZiAoYnl0ZUJ1ZmZlciBpbnN0YW5jZW9mIERpcmVjdEJ5dGVCdWZmZXIpIHsKKyAgICAgICAgICAgICgoRGlyZWN0Qnl0ZUJ1ZmZlcikgYnl0ZUJ1ZmZlcikuZ2V0KGRzdCwgZHN0T2Zmc2V0LCBsb25nQ291bnQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgKChIZWFwQnl0ZUJ1ZmZlcikgYnl0ZUJ1ZmZlcikuZ2V0KGRzdCwgZHN0T2Zmc2V0LCBsb25nQ291bnQpOworICAgICAgICB9CisgICAgICAgIHRoaXMucG9zaXRpb24gKz0gbG9uZ0NvdW50OworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdCgpIHsKKyAgICAgICAgcmV0dXJuIGJ5dGVCdWZmZXIuaXNEaXJlY3QoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1JlYWRPbmx5KCkgeworICAgICAgICByZXR1cm4gYnl0ZUJ1ZmZlci5pc1JlYWRPbmx5KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVPcmRlciBvcmRlcigpIHsKKyAgICAgICAgcmV0dXJuIGJ5dGVCdWZmZXIub3JkZXIoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgbG9uZ1tdIHByb3RlY3RlZEFycmF5KCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IHByb3RlY3RlZEFycmF5T2Zmc2V0KCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwcm90ZWN0ZWRIYXNBcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBMb25nQnVmZmVyIHB1dChsb25nIGMpIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBieXRlQnVmZmVyLnB1dExvbmcocG9zaXRpb24rKyAqIFNpemVPZi5MT05HLCBjKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIExvbmdCdWZmZXIgcHV0KGludCBpbmRleCwgbG9uZyBjKSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICBieXRlQnVmZmVyLnB1dExvbmcoaW5kZXggKiBTaXplT2YuTE9ORywgYyk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBMb25nQnVmZmVyIHB1dChsb25nW10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgbG9uZ0NvdW50KSB7CisgICAgICAgIGJ5dGVCdWZmZXIubGltaXQobGltaXQgKiBTaXplT2YuTE9ORyk7CisgICAgICAgIGJ5dGVCdWZmZXIucG9zaXRpb24ocG9zaXRpb24gKiBTaXplT2YuTE9ORyk7CisgICAgICAgIGlmIChieXRlQnVmZmVyIGluc3RhbmNlb2YgUmVhZFdyaXRlRGlyZWN0Qnl0ZUJ1ZmZlcikgeworICAgICAgICAgICAgKChSZWFkV3JpdGVEaXJlY3RCeXRlQnVmZmVyKSBieXRlQnVmZmVyKS5wdXQoc3JjLCBzcmNPZmZzZXQsIGxvbmdDb3VudCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAoKFJlYWRXcml0ZUhlYXBCeXRlQnVmZmVyKSBieXRlQnVmZmVyKS5wdXQoc3JjLCBzcmNPZmZzZXQsIGxvbmdDb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5wb3NpdGlvbiArPSBsb25nQ291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBMb25nQnVmZmVyIHNsaWNlKCkgeworICAgICAgICBieXRlQnVmZmVyLmxpbWl0KGxpbWl0ICogU2l6ZU9mLkxPTkcpOworICAgICAgICBieXRlQnVmZmVyLnBvc2l0aW9uKHBvc2l0aW9uICogU2l6ZU9mLkxPTkcpOworICAgICAgICBCeXRlQnVmZmVyIGJiID0gYnl0ZUJ1ZmZlci5zbGljZSgpLm9yZGVyKGJ5dGVCdWZmZXIub3JkZXIoKSk7CisgICAgICAgIExvbmdCdWZmZXIgcmVzdWx0ID0gbmV3IExvbmdUb0J5dGVCdWZmZXJBZGFwdGVyKGJiKTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5jbGVhcigpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL01hcHBlZEJ5dGVCdWZmZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9NYXBwZWRCeXRlQnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzljNDk4NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9NYXBwZWRCeXRlQnVmZmVyLmphdmEKQEAgLTAsMCArMSwxMjggQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW87CisKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5GaWxlQ2hhbm5lbC5NYXBNb2RlOworaW1wb3J0IGxpYmNvcmUuaW8uRXJybm9FeGNlcHRpb247CitpbXBvcnQgbGliY29yZS5pby5MaWJjb3JlOworaW1wb3J0IGxpYmNvcmUuaW8uTWVtb3J5OworaW1wb3J0IHN0YXRpYyBsaWJjb3JlLmlvLk9zQ29uc3RhbnRzLio7CisKKy8qKgorICoge0Bjb2RlIE1hcHBlZEJ5dGVCdWZmZXJ9IGlzIGEgc3BlY2lhbCBraW5kIG9mIGRpcmVjdCBieXRlIGJ1ZmZlciB3aGljaCBtYXBzIGEKKyAqIHJlZ2lvbiBvZiBmaWxlIHRvIG1lbW9yeS4KKyAqIDxwPgorICoge0Bjb2RlIE1hcHBlZEJ5dGVCdWZmZXJ9IGNhbiBiZSBjcmVhdGVkIGJ5IGNhbGxpbmcKKyAqIHtAbGluayBqYXZhLm5pby5jaGFubmVscy5GaWxlQ2hhbm5lbCNtYXAoamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWwuTWFwTW9kZSwgbG9uZywgbG9uZykgRmlsZUNoYW5uZWwubWFwfS4KKyAqIE9uY2UgY3JlYXRlZCwgdGhlIG1hcHBpbmcgYmV0d2VlbiB0aGUgYnl0ZSBidWZmZXIgYW5kIHRoZSBmaWxlIHJlZ2lvbiByZW1haW5zCisgKiB2YWxpZCB1bnRpbCB0aGUgYnl0ZSBidWZmZXIgaXMgZ2FyYmFnZSBjb2xsZWN0ZWQuCisgKiA8cD4KKyAqIEFsbCBvciBwYXJ0IG9mIGEge0Bjb2RlIE1hcHBlZEJ5dGVCdWZmZXJ9J3MgY29udGVudCBtYXkgY2hhbmdlIG9yIGJlY29tZQorICogaW5hY2Nlc3NpYmxlIGF0IGFueSB0aW1lLCBzaW5jZSB0aGUgbWFwcGVkIGZpbGUgcmVnaW9uIGNhbiBiZSBtb2RpZmllZCBieQorICogYW5vdGhlciB0aHJlYWQgb3IgcHJvY2VzcyBhdCBhbnkgdGltZS4gSWYgdGhpcyBoYXBwZW5zLCB0aGUgYmVoYXZpb3Igb2YgdGhlCisgKiB7QGNvZGUgTWFwcGVkQnl0ZUJ1ZmZlcn0gaXMgdW5kZWZpbmVkLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTWFwcGVkQnl0ZUJ1ZmZlciBleHRlbmRzIEJ5dGVCdWZmZXIgeworCisgICAgZmluYWwgRGlyZWN0Qnl0ZUJ1ZmZlciB3cmFwcGVkOworCisgICAgcHJpdmF0ZSBmaW5hbCBNYXBNb2RlIG1hcE1vZGU7CisKKyAgICBNYXBwZWRCeXRlQnVmZmVyKEJ5dGVCdWZmZXIgZGlyZWN0QnVmZmVyKSB7CisgICAgICAgIHN1cGVyKGRpcmVjdEJ1ZmZlci5jYXBhY2l0eSwgZGlyZWN0QnVmZmVyLmJsb2NrKTsKKyAgICAgICAgaWYgKCFkaXJlY3RCdWZmZXIuaXNEaXJlY3QoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMud3JhcHBlZCA9IChEaXJlY3RCeXRlQnVmZmVyKSBkaXJlY3RCdWZmZXI7CisgICAgICAgIHRoaXMubWFwTW9kZSA9IG51bGw7CisgICAgfQorCisgICAgTWFwcGVkQnl0ZUJ1ZmZlcihNZW1vcnlCbG9jayBibG9jaywgaW50IGNhcGFjaXR5LCBpbnQgb2Zmc2V0LCBNYXBNb2RlIG1hcE1vZGUpIHsKKyAgICAgICAgc3VwZXIoY2FwYWNpdHksIGJsb2NrKTsKKyAgICAgICAgdGhpcy5tYXBNb2RlID0gbWFwTW9kZTsKKyAgICAgICAgaWYgKG1hcE1vZGUgPT0gTWFwTW9kZS5SRUFEX09OTFkpIHsKKyAgICAgICAgICAgIHdyYXBwZWQgPSBuZXcgUmVhZE9ubHlEaXJlY3RCeXRlQnVmZmVyKGJsb2NrLCBjYXBhY2l0eSwgb2Zmc2V0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHdyYXBwZWQgPSBuZXcgUmVhZFdyaXRlRGlyZWN0Qnl0ZUJ1ZmZlcihibG9jaywgY2FwYWNpdHksIG9mZnNldCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlcmUgaXMgYSBoaWdoIHByb2JhYmlsaXR5IHRoYXQgZXZlcnkgcGFnZSBvZiB0aGlzIGJ1ZmZlciBpcyBjdXJyZW50bHkKKyAgICAgKiBsb2FkZWQgaW4gUkFNLCBtZWFuaW5nIHRoYXQgYWNjZXNzZXMgd2lsbCBub3QgY2F1c2UgYSBwYWdlIGZhdWx0LiBJdCBpcyBpbXBvc3NpYmxlIHRvIGdpdmUKKyAgICAgKiBhIHN0cm9uZyBndWFyYW50ZWUgc2luY2UgdGhpcyBpcyBvbmx5IGEgc25hcHNob3Qgb2YgYSBkeW5hbWljIHNpdHVhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0xvYWRlZCgpIHsKKyAgICAgICAgbG9uZyBhZGRyZXNzID0gYmxvY2sudG9JbnQoKTsKKyAgICAgICAgbG9uZyBzaXplID0gYmxvY2suZ2V0U2l6ZSgpOworICAgICAgICBpZiAoc2l6ZSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgcGFnZVNpemUgPSAoaW50KSBMaWJjb3JlLm9zLnN5c2NvbmYoX1NDX1BBR0VfU0laRSk7CisgICAgICAgICAgICBpbnQgcGFnZU9mZnNldCA9IChpbnQpIChhZGRyZXNzICUgcGFnZVNpemUpOworICAgICAgICAgICAgYWRkcmVzcyAtPSBwYWdlT2Zmc2V0OworICAgICAgICAgICAgc2l6ZSArPSBwYWdlT2Zmc2V0OworICAgICAgICAgICAgaW50IHBhZ2VDb3VudCA9IChpbnQpICgoc2l6ZSArIHBhZ2VTaXplIC0gMSkgLyBwYWdlU2l6ZSk7CisgICAgICAgICAgICBieXRlW10gdmVjdG9yID0gbmV3IGJ5dGVbcGFnZUNvdW50XTsKKyAgICAgICAgICAgIExpYmNvcmUub3MubWluY29yZShhZGRyZXNzLCBzaXplLCB2ZWN0b3IpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2ZWN0b3IubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICBpZiAoKHZlY3RvcltpXSAmIDEpICE9IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gbG9hZCBldmVyeSBwYWdlIG9mIHRoaXMgYnVmZmVyIGludG8gUkFNLiBTZWUge0BsaW5rICNpc0xvYWRlZH0uCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgTWFwcGVkQnl0ZUJ1ZmZlciBsb2FkKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgTGliY29yZS5vcy5tbG9jayhibG9jay50b0ludCgpLCBibG9jay5nZXRTaXplKCkpOworICAgICAgICAgICAgTGliY29yZS5vcy5tdW5sb2NrKGJsb2NrLnRvSW50KCksIGJsb2NrLmdldFNpemUoKSk7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYWxsIGNoYW5nZXMgb2YgdGhlIGJ1ZmZlciB0byB0aGUgbWFwcGVkIGZpbGUuIElmIHRoZSBtYXBwZWQgZmlsZQorICAgICAqIGlzIHN0b3JlZCBvbiBhIGxvY2FsIGRldmljZSwgaXQgaXMgZ3VhcmFudGVlZCB0aGF0IHRoZSBjaGFuZ2VzIGFyZQorICAgICAqIHdyaXR0ZW4gdG8gdGhlIGZpbGUuIE5vIHN1Y2ggZ3VhcmFudGVlIGlzIGdpdmVuIGlmIHRoZSBmaWxlIGlzIGxvY2F0ZWQgb24KKyAgICAgKiBhIHJlbW90ZSBkZXZpY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBNYXBwZWRCeXRlQnVmZmVyIGZvcmNlKCkgeworICAgICAgICBpZiAobWFwTW9kZSA9PSBNYXBNb2RlLlJFQURfV1JJVEUpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTGliY29yZS5vcy5tc3luYyhibG9jay50b0ludCgpLCBibG9jay5nZXRTaXplKCksIE1TX1NZTkMpOworICAgICAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAvLyBUaGUgUkkgZG9lc24ndCB0aHJvdywgcHJlc3VtYWJseSBvbiB0aGUgYXNzdW1wdGlvbiB0aGF0IHlvdSBjYW4ndCBnZXQgaW50bworICAgICAgICAgICAgICAgIC8vIGEgc3RhdGUgd2hlcmUgbXN5bmMoMikgY291bGQgcmV0dXJuIGFuIGVycm9yLgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlcnJub0V4Y2VwdGlvbik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL01hcHBlZEJ5dGVCdWZmZXJBZGFwdGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vTWFwcGVkQnl0ZUJ1ZmZlckFkYXB0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43M2IyOTkxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL01hcHBlZEJ5dGVCdWZmZXJBZGFwdGVyLmphdmEKQEAgLTAsMCArMSwzODEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW87CisKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5GaWxlQ2hhbm5lbC5NYXBNb2RlOworaW1wb3J0IGxpYmNvcmUuaW8uU2l6ZU9mOworCisvKioKKyAqIFJhdGhlciB0aGFuIGR1cGxpY2F0ZSBhbGwgdGhlIGNvZGUgZnJvbSBSZWFkT25seURpcmVjdEJ5dGVCdWZmZXIgYW5kCisgKiBSZWFkV3JpdGVEaXJlY3RCeXRlQnVmZmVyIChhbmQgdGhlaXIgc3VwZXJjbGFzc2VzKSwgd2UgZGVsZWdhdGUgdG8gb25lIG9yIHRoZSBvdGhlci4KKyAqIFRoZSB0cmlja3kgcGFydCBpcyB0aGF0IHdlIG5lZWQgdG8ga2VlcCBvdXIgZmllbGRzIGluIHN5bmMgd2l0aCBvdXIgZGVsZWdhdGUncyBmaWVsZHMuCisgKiBUaGVyZSBhcmUgbG90cyBvZiBtZXRob2RzIHRoYXQgYWNjZXNzIHRoZSBmaWVsZHMgZGlyZWN0bHkuCisgKgorICogVGhlIG1haW4gY29uc2VxdWVuY2VzIG9mIHRoaXMgaW1wbGVtZW50YXRpb24gYXJlOgorICoKKyAqIDEuIHdlIG5lZWQgdG8gZXhwbGljaXRseSBjYWxsIHdyYXBwZWQucG9zaXRpb24oaW50KSBiZWZvcmUgYW55IG9wZXJhdGlvbiBvbiBvdXIgZGVsZWdhdGUKKyAqIHRoYXQgbWFrZXMgdXNlIG9mIHRoZSBpbXBsaWNpdCBwb3NpdGlvbi4KKyAqCisgKiAyLiB3ZSBuZWVkIHRvIGV4cGxpY2l0bHkgdXBkYXRlIHBvc2l0aW9uIGFmdGVyIGFueSBvcGVyYXRpb24gb24gb3VyIGRlbGVnYXRlIHRoYXQgbWFrZXMKKyAqIHVzZSBvZiB0aGUgaW1wbGljaXQgcG9zaXRpb24uCisgKgorICogVGhpcyBtZWFucyB0aGF0LCBldmVuIG1vcmUgdGhhbiB1c3VhbCwgdGhlIGltcGxpY2l0IGl0ZXJhdGlvbgorICogb3BlcmF0aW9ucyBhcmUgbW9yZSBleHBlbnNpdmUgdGhhbiB0aGUgaW5kZXhlZCBvcGVyYXRpb25zLgorICoKKyAqIEJ1dCB3ZSBzYXZlIGEgdG9uIG9mIGNvZGUsIGZvciBjbGFzc2VzIHRoYXQgbm8tb25lIHJlYWxseSB1c2VzIGJlY2F1c2UgdGhlIEFQSSdzIGJyb2tlbgorICogYnkgZGVzaWduIChkaXNhbGxvd2luZyBtdW5tYXAoMikgY2FsbHMpLiBJbnRlcm5hbGx5LCB3ZSBjYW4gdXNlIGxpYmNvcmUuaW8uTWVtb3J5TWFwcGVkRmlsZQorICogYXMgYSBoaWdoLXBlcmZvcm1hbmNlIGFuZCBtb3JlIHVzYWJsZSByZXBsYWNlbWVudCBmb3IgTWFwcGVkQnl0ZUJ1ZmZlci4KKyAqCisgKiBGSVhNRTogaGFybW9ueSBjaGFuZ2VkIHRoZWlyIGltcGxlbWVudGF0aW9uIGFmdGVyIHdlIGRpdmVyZ2VkLCBzd2l0Y2hpbmcgdG8gYSBzY2hlbWUKKyAqIHdoZXJlIERpcmVjdEJ5dGVCdWZmZXIgZXh0ZW5kcyBNYXBwZWRCeXRlQnVmZmVyIGFuZCB0aGlzIGNsYXNzIGRvZXNuJ3QgZXhpc3QuIFRoYXQncworICogbXVjaCBiZXR0ZXIgdGhhbiB0aGVpciBvcmlnaW5hbCBpbXBsZW1lbnRhdGlvbiwgZm9zc2lsaXplZCBoZXJlLgorICovCitmaW5hbCBjbGFzcyBNYXBwZWRCeXRlQnVmZmVyQWRhcHRlciBleHRlbmRzIE1hcHBlZEJ5dGVCdWZmZXIgeworICAgIHByaXZhdGUgTWFwcGVkQnl0ZUJ1ZmZlckFkYXB0ZXIoQnl0ZUJ1ZmZlciBidWZmZXIpIHsKKyAgICAgICAgc3VwZXIoYnVmZmVyKTsKKyAgICAgICAgZWZmZWN0aXZlRGlyZWN0QWRkcmVzcyA9IHdyYXBwZWQuZWZmZWN0aXZlRGlyZWN0QWRkcmVzczsKKyAgICB9CisKKyAgICBwdWJsaWMgTWFwcGVkQnl0ZUJ1ZmZlckFkYXB0ZXIoTWVtb3J5QmxvY2sgYmxvY2ssIGludCBjYXBhY2l0eSwgaW50IG9mZnNldCwgTWFwTW9kZSBtb2RlKSB7CisgICAgICAgIHN1cGVyKGJsb2NrLCBjYXBhY2l0eSwgb2Zmc2V0LCBtb2RlKTsKKyAgICAgICAgZWZmZWN0aXZlRGlyZWN0QWRkcmVzcyA9IHdyYXBwZWQuZWZmZWN0aXZlRGlyZWN0QWRkcmVzczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgdm9pZCBsaW1pdEltcGwoaW50IG5ld0xpbWl0KSB7CisgICAgICAgIHN1cGVyLmxpbWl0SW1wbChuZXdMaW1pdCk7CisgICAgICAgIHdyYXBwZWQubGltaXQobmV3TGltaXQpOworICAgIH0KKworICAgIEBPdmVycmlkZSB2b2lkIHBvc2l0aW9uSW1wbChpbnQgbmV3UG9zaXRpb24pIHsKKyAgICAgICAgc3VwZXIucG9zaXRpb25JbXBsKG5ld1Bvc2l0aW9uKTsKKyAgICAgICAgd3JhcHBlZC5wb3NpdGlvbihuZXdQb3NpdGlvbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENoYXJCdWZmZXIgYXNDaGFyQnVmZmVyKCkgeworICAgICAgICByZXR1cm4gd3JhcHBlZC5hc0NoYXJCdWZmZXIoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRG91YmxlQnVmZmVyIGFzRG91YmxlQnVmZmVyKCkgeworICAgICAgICByZXR1cm4gd3JhcHBlZC5hc0RvdWJsZUJ1ZmZlcigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGbG9hdEJ1ZmZlciBhc0Zsb2F0QnVmZmVyKCkgeworICAgICAgICByZXR1cm4gd3JhcHBlZC5hc0Zsb2F0QnVmZmVyKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEludEJ1ZmZlciBhc0ludEJ1ZmZlcigpIHsKKyAgICAgICAgcmV0dXJuIHdyYXBwZWQuYXNJbnRCdWZmZXIoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTG9uZ0J1ZmZlciBhc0xvbmdCdWZmZXIoKSB7CisgICAgICAgIHJldHVybiB3cmFwcGVkLmFzTG9uZ0J1ZmZlcigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIGFzUmVhZE9ubHlCdWZmZXIoKSB7CisgICAgICAgIE1hcHBlZEJ5dGVCdWZmZXJBZGFwdGVyIHJlc3VsdCA9IG5ldyBNYXBwZWRCeXRlQnVmZmVyQWRhcHRlcih3cmFwcGVkLmFzUmVhZE9ubHlCdWZmZXIoKSk7CisgICAgICAgIHJlc3VsdC5saW1pdChsaW1pdCk7CisgICAgICAgIHJlc3VsdC5wb3NpdGlvbihwb3NpdGlvbik7CisgICAgICAgIHJlc3VsdC5tYXJrID0gbWFyazsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2hvcnRCdWZmZXIgYXNTaG9ydEJ1ZmZlcigpIHsKKyAgICAgICAgcmV0dXJuIHdyYXBwZWQuYXNTaG9ydEJ1ZmZlcigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIGNvbXBhY3QoKSB7CisgICAgICAgIGlmICh3cmFwcGVkLmlzUmVhZE9ubHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgd3JhcHBlZC5jb21wYWN0KCk7CisgICAgICAgIGxpbWl0KGNhcGFjaXR5KTsKKyAgICAgICAgcG9zaXRpb24od3JhcHBlZC5wb3NpdGlvbigpKTsKKyAgICAgICAgdGhpcy5tYXJrID0gVU5TRVRfTUFSSzsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgZHVwbGljYXRlKCkgeworICAgICAgICBNYXBwZWRCeXRlQnVmZmVyQWRhcHRlciByZXN1bHQgPSBuZXcgTWFwcGVkQnl0ZUJ1ZmZlckFkYXB0ZXIod3JhcHBlZC5kdXBsaWNhdGUoKSk7CisgICAgICAgIHJlc3VsdC5saW1pdChsaW1pdCk7CisgICAgICAgIHJlc3VsdC5wb3NpdGlvbihwb3NpdGlvbik7CisgICAgICAgIHJlc3VsdC5tYXJrID0gbWFyazsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZSBnZXQoKSB7CisgICAgICAgIHdyYXBwZWQucG9zaXRpb24ocG9zaXRpb24pOworICAgICAgICBieXRlIHJlc3VsdCA9IHdyYXBwZWQuZ2V0KCk7CisgICAgICAgICsrcG9zaXRpb247CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGUgZ2V0KGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gd3JhcHBlZC5nZXQoaW5kZXgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIGdldChieXRlW10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB7CisgICAgICAgIEJ5dGVCdWZmZXIgcmVzdWx0ID0gd3JhcHBlZC5nZXQoZHN0LCBkc3RPZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIHBvc2l0aW9uICs9IGJ5dGVDb3VudDsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgY2hhciBnZXRDaGFyKCkgeworICAgICAgICB3cmFwcGVkLnBvc2l0aW9uKHBvc2l0aW9uKTsKKyAgICAgICAgY2hhciByZXN1bHQgPSB3cmFwcGVkLmdldENoYXIoKTsKKyAgICAgICAgcG9zaXRpb24gKz0gU2l6ZU9mLkNIQVI7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGNoYXIgZ2V0Q2hhcihpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIHdyYXBwZWQuZ2V0Q2hhcihpbmRleCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGRvdWJsZSBnZXREb3VibGUoKSB7CisgICAgICAgIHdyYXBwZWQucG9zaXRpb24ocG9zaXRpb24pOworICAgICAgICBkb3VibGUgcmVzdWx0ID0gd3JhcHBlZC5nZXREb3VibGUoKTsKKyAgICAgICAgcG9zaXRpb24gKz0gU2l6ZU9mLkRPVUJMRTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZG91YmxlIGdldERvdWJsZShpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIHdyYXBwZWQuZ2V0RG91YmxlKGluZGV4KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXQgZ2V0RmxvYXQoKSB7CisgICAgICAgIHdyYXBwZWQucG9zaXRpb24ocG9zaXRpb24pOworICAgICAgICBmbG9hdCByZXN1bHQgPSB3cmFwcGVkLmdldEZsb2F0KCk7CisgICAgICAgIHBvc2l0aW9uICs9IFNpemVPZi5GTE9BVDsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmxvYXQgZ2V0RmxvYXQoaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiB3cmFwcGVkLmdldEZsb2F0KGluZGV4KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldEludCgpIHsKKyAgICAgICAgd3JhcHBlZC5wb3NpdGlvbihwb3NpdGlvbik7CisgICAgICAgIGludCByZXN1bHQgPSB3cmFwcGVkLmdldEludCgpOworICAgICAgICBwb3NpdGlvbiArPSBTaXplT2YuSU5UOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0SW50KGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gd3JhcHBlZC5nZXRJbnQoaW5kZXgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIGdldExvbmcoKSB7CisgICAgICAgIHdyYXBwZWQucG9zaXRpb24ocG9zaXRpb24pOworICAgICAgICBsb25nIHJlc3VsdCA9IHdyYXBwZWQuZ2V0TG9uZygpOworICAgICAgICBwb3NpdGlvbiArPSBTaXplT2YuTE9ORzsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRMb25nKGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gd3JhcHBlZC5nZXRMb25nKGluZGV4KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc2hvcnQgZ2V0U2hvcnQoKSB7CisgICAgICAgIHdyYXBwZWQucG9zaXRpb24ocG9zaXRpb24pOworICAgICAgICBzaG9ydCByZXN1bHQgPSB3cmFwcGVkLmdldFNob3J0KCk7CisgICAgICAgIHBvc2l0aW9uICs9IFNpemVPZi5TSE9SVDsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc2hvcnQgZ2V0U2hvcnQoaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiB3cmFwcGVkLmdldFNob3J0KGluZGV4KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdCgpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNSZWFkT25seSgpIHsKKyAgICAgICAgcmV0dXJuIHdyYXBwZWQuaXNSZWFkT25seSgpOworICAgIH0KKworICAgIEBPdmVycmlkZSB2b2lkIG9yZGVySW1wbChCeXRlT3JkZXIgYnl0ZU9yZGVyKSB7CisgICAgICAgIHN1cGVyLm9yZGVySW1wbChieXRlT3JkZXIpOworICAgICAgICB3cmFwcGVkLm9yZGVyKGJ5dGVPcmRlcik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0KGJ5dGUgYikgeworICAgICAgICB3cmFwcGVkLnBvc2l0aW9uKHRoaXMucG9zaXRpb24pOworICAgICAgICB3cmFwcGVkLnB1dChiKTsKKyAgICAgICAgdGhpcy5wb3NpdGlvbisrOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXQoYnl0ZVtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGJ5dGVDb3VudCkgeworICAgICAgICB3cmFwcGVkLnBvc2l0aW9uKHRoaXMucG9zaXRpb24pOworICAgICAgICB3cmFwcGVkLnB1dChzcmMsIHNyY09mZnNldCwgYnl0ZUNvdW50KTsKKyAgICAgICAgdGhpcy5wb3NpdGlvbiArPSBieXRlQ291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dChpbnQgaW5kZXgsIGJ5dGUgYikgeworICAgICAgICB3cmFwcGVkLnBvc2l0aW9uKHRoaXMucG9zaXRpb24pOworICAgICAgICB3cmFwcGVkLnB1dChpbmRleCwgYik7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dENoYXIoY2hhciB2YWx1ZSkgeworICAgICAgICB3cmFwcGVkLnBvc2l0aW9uKHRoaXMucG9zaXRpb24pOworICAgICAgICB3cmFwcGVkLnB1dENoYXIodmFsdWUpOworICAgICAgICB0aGlzLnBvc2l0aW9uICs9IFNpemVPZi5DSEFSOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRDaGFyKGludCBpbmRleCwgY2hhciB2YWx1ZSkgeworICAgICAgICB3cmFwcGVkLnBvc2l0aW9uKHRoaXMucG9zaXRpb24pOworICAgICAgICB3cmFwcGVkLnB1dENoYXIoaW5kZXgsIHZhbHVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0RG91YmxlKGRvdWJsZSB2YWx1ZSkgeworICAgICAgICB3cmFwcGVkLnBvc2l0aW9uKHRoaXMucG9zaXRpb24pOworICAgICAgICB3cmFwcGVkLnB1dERvdWJsZSh2YWx1ZSk7CisgICAgICAgIHRoaXMucG9zaXRpb24gKz0gU2l6ZU9mLkRPVUJMRTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0RG91YmxlKGludCBpbmRleCwgZG91YmxlIHZhbHVlKSB7CisgICAgICAgIHdyYXBwZWQucG9zaXRpb24odGhpcy5wb3NpdGlvbik7CisgICAgICAgIHdyYXBwZWQucHV0RG91YmxlKGluZGV4LCB2YWx1ZSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dEZsb2F0KGZsb2F0IHZhbHVlKSB7CisgICAgICAgIHdyYXBwZWQucG9zaXRpb24odGhpcy5wb3NpdGlvbik7CisgICAgICAgIHdyYXBwZWQucHV0RmxvYXQodmFsdWUpOworICAgICAgICB0aGlzLnBvc2l0aW9uICs9IFNpemVPZi5GTE9BVDsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0RmxvYXQoaW50IGluZGV4LCBmbG9hdCB2YWx1ZSkgeworICAgICAgICB3cmFwcGVkLnBvc2l0aW9uKHRoaXMucG9zaXRpb24pOworICAgICAgICB3cmFwcGVkLnB1dEZsb2F0KGluZGV4LCB2YWx1ZSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dEludChpbnQgaW5kZXgsIGludCB2YWx1ZSkgeworICAgICAgICB3cmFwcGVkLnBvc2l0aW9uKHRoaXMucG9zaXRpb24pOworICAgICAgICB3cmFwcGVkLnB1dEludChpbmRleCwgdmFsdWUpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRJbnQoaW50IHZhbHVlKSB7CisgICAgICAgIHdyYXBwZWQucG9zaXRpb24odGhpcy5wb3NpdGlvbik7CisgICAgICAgIHdyYXBwZWQucHV0SW50KHZhbHVlKTsKKyAgICAgICAgdGhpcy5wb3NpdGlvbiArPSBTaXplT2YuSU5UOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRMb25nKGludCBpbmRleCwgbG9uZyB2YWx1ZSkgeworICAgICAgICB3cmFwcGVkLnBvc2l0aW9uKHRoaXMucG9zaXRpb24pOworICAgICAgICB3cmFwcGVkLnB1dExvbmcoaW5kZXgsIHZhbHVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0TG9uZyhsb25nIHZhbHVlKSB7CisgICAgICAgIHdyYXBwZWQucG9zaXRpb24odGhpcy5wb3NpdGlvbik7CisgICAgICAgIHdyYXBwZWQucHV0TG9uZyh2YWx1ZSk7CisgICAgICAgIHRoaXMucG9zaXRpb24gKz0gU2l6ZU9mLkxPTkc7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dFNob3J0KGludCBpbmRleCwgc2hvcnQgdmFsdWUpIHsKKyAgICAgICAgd3JhcHBlZC5wb3NpdGlvbih0aGlzLnBvc2l0aW9uKTsKKyAgICAgICAgd3JhcHBlZC5wdXRTaG9ydChpbmRleCwgdmFsdWUpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRTaG9ydChzaG9ydCB2YWx1ZSkgeworICAgICAgICB3cmFwcGVkLnBvc2l0aW9uKHRoaXMucG9zaXRpb24pOworICAgICAgICB3cmFwcGVkLnB1dFNob3J0KHZhbHVlKTsKKyAgICAgICAgdGhpcy5wb3NpdGlvbiArPSBTaXplT2YuU0hPUlQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHNsaWNlKCkgeworICAgICAgICB3cmFwcGVkLnBvc2l0aW9uKHRoaXMucG9zaXRpb24pOworICAgICAgICBNYXBwZWRCeXRlQnVmZmVyQWRhcHRlciByZXN1bHQgPSBuZXcgTWFwcGVkQnl0ZUJ1ZmZlckFkYXB0ZXIod3JhcHBlZC5zbGljZSgpKTsKKyAgICAgICAgd3JhcHBlZC5jbGVhcigpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIGJ5dGVbXSBwcm90ZWN0ZWRBcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIHdyYXBwZWQucHJvdGVjdGVkQXJyYXkoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBpbnQgcHJvdGVjdGVkQXJyYXlPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiB3cmFwcGVkLnByb3RlY3RlZEFycmF5T2Zmc2V0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgYm9vbGVhbiBwcm90ZWN0ZWRIYXNBcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIHdyYXBwZWQucHJvdGVjdGVkSGFzQXJyYXkoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBmcmVlKCkgeworICAgICAgICB3cmFwcGVkLmZyZWUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vTWVtb3J5QmxvY2suamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9NZW1vcnlCbG9jay5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFkZDY5YzUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vTWVtb3J5QmxvY2suamF2YQpAQCAtMCwwICsxLDI0NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworaW1wb3J0IGRhbHZpay5zeXN0ZW0uVk1SdW50aW1lOworaW1wb3J0IGphdmEuaW8uRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5GaWxlQ2hhbm5lbC5NYXBNb2RlOworaW1wb3J0IGxpYmNvcmUuaW8uRXJybm9FeGNlcHRpb247CitpbXBvcnQgbGliY29yZS5pby5MaWJjb3JlOworaW1wb3J0IGxpYmNvcmUuaW8uTWVtb3J5OworaW1wb3J0IHN0YXRpYyBsaWJjb3JlLmlvLk9zQ29uc3RhbnRzLio7CisKK2NsYXNzIE1lbW9yeUJsb2NrIHsKKyAgICAvKioKKyAgICAgKiBIYW5kbGVzIGNhbGxpbmcgbXVubWFwKDIpIG9uIGEgbWVtb3J5LW1hcHBlZCByZWdpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTWVtb3J5TWFwcGVkQmxvY2sgZXh0ZW5kcyBNZW1vcnlCbG9jayB7CisgICAgICAgIHByaXZhdGUgTWVtb3J5TWFwcGVkQmxvY2soaW50IGFkZHJlc3MsIGxvbmcgYnl0ZUNvdW50KSB7CisgICAgICAgICAgICBzdXBlcihhZGRyZXNzLCBieXRlQ291bnQpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGZyZWUoKSB7CisgICAgICAgICAgICBpZiAoYWRkcmVzcyAhPSAwKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgTGliY29yZS5vcy5tdW5tYXAoYWRkcmVzcywgc2l6ZSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gVGhlIFJJIGRvZXNuJ3QgdGhyb3csIHByZXN1bWFibHkgb24gdGhlIGFzc3VtcHRpb24gdGhhdCB5b3UgY2FuJ3QgZ2V0IGludG8KKyAgICAgICAgICAgICAgICAgICAgLy8gYSBzdGF0ZSB3aGVyZSBtdW5tYXAoMikgY291bGQgcmV0dXJuIGFuIGVycm9yLgorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZXJybm9FeGNlcHRpb24pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhZGRyZXNzID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICAgICAgZnJlZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTm9uLW1vdmFibGUgaGVhcCBibG9ja3MgYXJlIGJ5dGUgYXJyYXlzIG9uIHRoZSBKYXZhIGhlYXAgdGhhdCB0aGUgR0MKKyAgICAgKiBndWFyYW50ZWVzIG5vdCB0byBtb3ZlLiBVc2VkIHRvIGltcGxlbWVudCBEaXJlY3RCeXRlQnVmZmVyLgorICAgICAqCisgICAgICogTG9zaW5nIHRoZSBzdHJvbmcgcmVmZXJlbmNlIHRvIHRoZSBhcnJheSBpcyBzdWZmaWNpZW50CisgICAgICogdG8gYWxsb3cgdGhlIEdDIHRvIHJlY2xhaW0gdGhlIHN0b3JhZ2UuIE5vIGZpbmFsaXplciBuZWVkZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTm9uTW92YWJsZUhlYXBCbG9jayBleHRlbmRzIE1lbW9yeUJsb2NrIHsKKyAgICAgICAgcHJpdmF0ZSBieXRlW10gYXJyYXk7CisKKyAgICAgICAgcHJpdmF0ZSBOb25Nb3ZhYmxlSGVhcEJsb2NrKGJ5dGVbXSBhcnJheSwgaW50IGFkZHJlc3MsIGxvbmcgYnl0ZUNvdW50KSB7CisgICAgICAgICAgICBzdXBlcihhZGRyZXNzLCBieXRlQ291bnQpOworICAgICAgICAgICAgdGhpcy5hcnJheSA9IGFycmF5OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBieXRlW10gYXJyYXkoKSB7CisgICAgICAgICAgICByZXR1cm4gYXJyYXk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZnJlZSgpIHsKKyAgICAgICAgICAgIGFycmF5ID0gbnVsbDsKKyAgICAgICAgICAgIGFkZHJlc3MgPSAwOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwcmVzZW50cyBhIGJsb2NrIG9mIG1lbW9yeSB3ZSBkb24ndCBvd24uIChXZSBkb24ndCB0YWtlIG93bmVyc2hpcCBvZiBtZW1vcnkgY29ycmVzcG9uZGluZworICAgICAqIHRvIGRpcmVjdCBidWZmZXJzIGNyZWF0ZWQgYnkgdGhlIEpOSSBOZXdEaXJlY3RCeXRlQnVmZmVyIGZ1bmN0aW9uLikKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBVbm1hbmFnZWRCbG9jayBleHRlbmRzIE1lbW9yeUJsb2NrIHsKKyAgICAgICAgcHJpdmF0ZSBVbm1hbmFnZWRCbG9jayhpbnQgYWRkcmVzcywgbG9uZyBieXRlQ291bnQpIHsKKyAgICAgICAgICAgIHN1cGVyKGFkZHJlc3MsIGJ5dGVDb3VudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBUT0RPOiBzaG91bGQgYmUgbG9uZyBvbiA2NC1iaXQgZGV2aWNlczsgaW50IGZvciBwZXJmb3JtYW5jZS4KKyAgICBwcm90ZWN0ZWQgaW50IGFkZHJlc3M7CisgICAgcHJvdGVjdGVkIGZpbmFsIGxvbmcgc2l6ZTsKKworICAgIHB1YmxpYyBzdGF0aWMgTWVtb3J5QmxvY2sgbW1hcChGaWxlRGVzY3JpcHRvciBmZCwgbG9uZyBvZmZzZXQsIGxvbmcgc2l6ZSwgTWFwTW9kZSBtYXBNb2RlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoc2l6ZSA9PSAwKSB7CisgICAgICAgICAgICAvLyBZb3UgY2FuJ3QgbW1hcCgyKSBhIHplcm8tbGVuZ3RoIHJlZ2lvbiwgYnV0IEphdmEgYWxsb3dzIGl0LgorICAgICAgICAgICAgcmV0dXJuIG5ldyBNZW1vcnlCbG9jaygwLCAwKTsKKyAgICAgICAgfQorICAgICAgICAvLyBDaGVjayBqdXN0IHRob3NlIGVycm9ycyBtbWFwKDIpIHdvbid0IGRldGVjdC4KKyAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgc2l6ZSA8IDAgfHwgb2Zmc2V0ID4gSW50ZWdlci5NQVhfVkFMVUUgfHwgc2l6ZSA+IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJvZmZzZXQ9IiArIG9mZnNldCArICIgc2l6ZT0iICsgc2l6ZSk7CisgICAgICAgIH0KKyAgICAgICAgaW50IHByb3Q7CisgICAgICAgIGludCBmbGFnczsKKyAgICAgICAgaWYgKG1hcE1vZGUgPT0gTWFwTW9kZS5QUklWQVRFKSB7CisgICAgICAgICAgICBwcm90ID0gUFJPVF9SRUFEfFBST1RfV1JJVEU7CisgICAgICAgICAgICBmbGFncyA9IE1BUF9QUklWQVRFOworICAgICAgICB9IGVsc2UgaWYgKG1hcE1vZGUgPT0gTWFwTW9kZS5SRUFEX09OTFkpIHsKKyAgICAgICAgICAgIHByb3QgPSBQUk9UX1JFQUQ7CisgICAgICAgICAgICBmbGFncyA9IE1BUF9TSEFSRUQ7CisgICAgICAgIH0gZWxzZSB7IC8vIG1hcE1vZGUgPT0gTWFwTW9kZS5SRUFEX1dSSVRFCisgICAgICAgICAgICBwcm90ID0gUFJPVF9SRUFEfFBST1RfV1JJVEU7CisgICAgICAgICAgICBmbGFncyA9IE1BUF9TSEFSRUQ7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBhZGRyZXNzID0gKGludCkgTGliY29yZS5vcy5tbWFwKDBMLCBzaXplLCBwcm90LCBmbGFncywgZmQsIG9mZnNldCk7CisgICAgICAgICAgICByZXR1cm4gbmV3IE1lbW9yeU1hcHBlZEJsb2NrKGFkZHJlc3MsIHNpemUpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzSU9FeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgTWVtb3J5QmxvY2sgYWxsb2NhdGUoaW50IGJ5dGVDb3VudCkgeworICAgICAgICBWTVJ1bnRpbWUgcnVudGltZSA9IFZNUnVudGltZS5nZXRSdW50aW1lKCk7CisgICAgICAgIGJ5dGVbXSBhcnJheSA9IChieXRlW10pIHJ1bnRpbWUubmV3Tm9uTW92YWJsZUFycmF5KGJ5dGUuY2xhc3MsIGJ5dGVDb3VudCk7CisgICAgICAgIGludCBhZGRyZXNzID0gKGludCkgcnVudGltZS5hZGRyZXNzT2YoYXJyYXkpOworICAgICAgICByZXR1cm4gbmV3IE5vbk1vdmFibGVIZWFwQmxvY2soYXJyYXksIGFkZHJlc3MsIGJ5dGVDb3VudCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBNZW1vcnlCbG9jayB3cmFwRnJvbUpuaShpbnQgYWRkcmVzcywgbG9uZyBieXRlQ291bnQpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBVbm1hbmFnZWRCbG9jayhhZGRyZXNzLCBieXRlQ291bnQpOworICAgIH0KKworICAgIHByaXZhdGUgTWVtb3J5QmxvY2soaW50IGFkZHJlc3MsIGxvbmcgc2l6ZSkgeworICAgICAgICB0aGlzLmFkZHJlc3MgPSBhZGRyZXNzOworICAgICAgICB0aGlzLnNpemUgPSBzaXplOworICAgIH0KKworICAgIC8vIFVzZWQgdG8gc3VwcG9ydCBhcnJheS9hcnJheU9mZnNldC9oYXNBcnJheSBmb3IgZGlyZWN0IGJ1ZmZlcnMuCisgICAgcHVibGljIGJ5dGVbXSBhcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZnJlZSgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBwb2tlQnl0ZShpbnQgb2Zmc2V0LCBieXRlIHZhbHVlKSB7CisgICAgICAgIE1lbW9yeS5wb2tlQnl0ZShhZGRyZXNzICsgb2Zmc2V0LCB2YWx1ZSk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHZvaWQgcG9rZUJ5dGVBcnJheShpbnQgb2Zmc2V0LCBieXRlW10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB7CisgICAgICAgIE1lbW9yeS5wb2tlQnl0ZUFycmF5KGFkZHJlc3MgKyBvZmZzZXQsIHNyYywgc3JjT2Zmc2V0LCBieXRlQ291bnQpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHBva2VDaGFyQXJyYXkoaW50IG9mZnNldCwgY2hhcltdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGNoYXJDb3VudCwgYm9vbGVhbiBzd2FwKSB7CisgICAgICAgIE1lbW9yeS5wb2tlQ2hhckFycmF5KGFkZHJlc3MgKyBvZmZzZXQsIHNyYywgc3JjT2Zmc2V0LCBjaGFyQ291bnQsIHN3YXApOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHBva2VEb3VibGVBcnJheShpbnQgb2Zmc2V0LCBkb3VibGVbXSBzcmMsIGludCBzcmNPZmZzZXQsIGludCBkb3VibGVDb3VudCwgYm9vbGVhbiBzd2FwKSB7CisgICAgICAgIE1lbW9yeS5wb2tlRG91YmxlQXJyYXkoYWRkcmVzcyArIG9mZnNldCwgc3JjLCBzcmNPZmZzZXQsIGRvdWJsZUNvdW50LCBzd2FwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBwb2tlRmxvYXRBcnJheShpbnQgb2Zmc2V0LCBmbG9hdFtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGZsb2F0Q291bnQsIGJvb2xlYW4gc3dhcCkgeworICAgICAgICBNZW1vcnkucG9rZUZsb2F0QXJyYXkoYWRkcmVzcyArIG9mZnNldCwgc3JjLCBzcmNPZmZzZXQsIGZsb2F0Q291bnQsIHN3YXApOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHBva2VJbnRBcnJheShpbnQgb2Zmc2V0LCBpbnRbXSBzcmMsIGludCBzcmNPZmZzZXQsIGludCBpbnRDb3VudCwgYm9vbGVhbiBzd2FwKSB7CisgICAgICAgIE1lbW9yeS5wb2tlSW50QXJyYXkoYWRkcmVzcyArIG9mZnNldCwgc3JjLCBzcmNPZmZzZXQsIGludENvdW50LCBzd2FwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBwb2tlTG9uZ0FycmF5KGludCBvZmZzZXQsIGxvbmdbXSBzcmMsIGludCBzcmNPZmZzZXQsIGludCBsb25nQ291bnQsIGJvb2xlYW4gc3dhcCkgeworICAgICAgICBNZW1vcnkucG9rZUxvbmdBcnJheShhZGRyZXNzICsgb2Zmc2V0LCBzcmMsIHNyY09mZnNldCwgbG9uZ0NvdW50LCBzd2FwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBwb2tlU2hvcnRBcnJheShpbnQgb2Zmc2V0LCBzaG9ydFtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IHNob3J0Q291bnQsIGJvb2xlYW4gc3dhcCkgeworICAgICAgICBNZW1vcnkucG9rZVNob3J0QXJyYXkoYWRkcmVzcyArIG9mZnNldCwgc3JjLCBzcmNPZmZzZXQsIHNob3J0Q291bnQsIHN3YXApOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBieXRlIHBlZWtCeXRlKGludCBvZmZzZXQpIHsKKyAgICAgICAgcmV0dXJuIE1lbW9yeS5wZWVrQnl0ZShhZGRyZXNzICsgb2Zmc2V0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBwZWVrQnl0ZUFycmF5KGludCBvZmZzZXQsIGJ5dGVbXSBkc3QsIGludCBkc3RPZmZzZXQsIGludCBieXRlQ291bnQpIHsKKyAgICAgICAgTWVtb3J5LnBlZWtCeXRlQXJyYXkoYWRkcmVzcyArIG9mZnNldCwgZHN0LCBkc3RPZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHZvaWQgcGVla0NoYXJBcnJheShpbnQgb2Zmc2V0LCBjaGFyW10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgY2hhckNvdW50LCBib29sZWFuIHN3YXApIHsKKyAgICAgICAgTWVtb3J5LnBlZWtDaGFyQXJyYXkoYWRkcmVzcyArIG9mZnNldCwgZHN0LCBkc3RPZmZzZXQsIGNoYXJDb3VudCwgc3dhcCk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHZvaWQgcGVla0RvdWJsZUFycmF5KGludCBvZmZzZXQsIGRvdWJsZVtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGRvdWJsZUNvdW50LCBib29sZWFuIHN3YXApIHsKKyAgICAgICAgTWVtb3J5LnBlZWtEb3VibGVBcnJheShhZGRyZXNzICsgb2Zmc2V0LCBkc3QsIGRzdE9mZnNldCwgZG91YmxlQ291bnQsIHN3YXApOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHBlZWtGbG9hdEFycmF5KGludCBvZmZzZXQsIGZsb2F0W10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgZmxvYXRDb3VudCwgYm9vbGVhbiBzd2FwKSB7CisgICAgICAgIE1lbW9yeS5wZWVrRmxvYXRBcnJheShhZGRyZXNzICsgb2Zmc2V0LCBkc3QsIGRzdE9mZnNldCwgZmxvYXRDb3VudCwgc3dhcCk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHZvaWQgcGVla0ludEFycmF5KGludCBvZmZzZXQsIGludFtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGludENvdW50LCBib29sZWFuIHN3YXApIHsKKyAgICAgICAgTWVtb3J5LnBlZWtJbnRBcnJheShhZGRyZXNzICsgb2Zmc2V0LCBkc3QsIGRzdE9mZnNldCwgaW50Q291bnQsIHN3YXApOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHBlZWtMb25nQXJyYXkoaW50IG9mZnNldCwgbG9uZ1tdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGxvbmdDb3VudCwgYm9vbGVhbiBzd2FwKSB7CisgICAgICAgIE1lbW9yeS5wZWVrTG9uZ0FycmF5KGFkZHJlc3MgKyBvZmZzZXQsIGRzdCwgZHN0T2Zmc2V0LCBsb25nQ291bnQsIHN3YXApOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHBlZWtTaG9ydEFycmF5KGludCBvZmZzZXQsIHNob3J0W10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgc2hvcnRDb3VudCwgYm9vbGVhbiBzd2FwKSB7CisgICAgICAgIE1lbW9yeS5wZWVrU2hvcnRBcnJheShhZGRyZXNzICsgb2Zmc2V0LCBkc3QsIGRzdE9mZnNldCwgc2hvcnRDb3VudCwgc3dhcCk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHZvaWQgcG9rZVNob3J0KGludCBvZmZzZXQsIHNob3J0IHZhbHVlLCBCeXRlT3JkZXIgb3JkZXIpIHsKKyAgICAgICAgTWVtb3J5LnBva2VTaG9ydChhZGRyZXNzICsgb2Zmc2V0LCB2YWx1ZSwgb3JkZXIubmVlZHNTd2FwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgc2hvcnQgcGVla1Nob3J0KGludCBvZmZzZXQsIEJ5dGVPcmRlciBvcmRlcikgeworICAgICAgICByZXR1cm4gTWVtb3J5LnBlZWtTaG9ydChhZGRyZXNzICsgb2Zmc2V0LCBvcmRlci5uZWVkc1N3YXApOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHBva2VJbnQoaW50IG9mZnNldCwgaW50IHZhbHVlLCBCeXRlT3JkZXIgb3JkZXIpIHsKKyAgICAgICAgTWVtb3J5LnBva2VJbnQoYWRkcmVzcyArIG9mZnNldCwgdmFsdWUsIG9yZGVyLm5lZWRzU3dhcCk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIGludCBwZWVrSW50KGludCBvZmZzZXQsIEJ5dGVPcmRlciBvcmRlcikgeworICAgICAgICByZXR1cm4gTWVtb3J5LnBlZWtJbnQoYWRkcmVzcyArIG9mZnNldCwgb3JkZXIubmVlZHNTd2FwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBwb2tlTG9uZyhpbnQgb2Zmc2V0LCBsb25nIHZhbHVlLCBCeXRlT3JkZXIgb3JkZXIpIHsKKyAgICAgICAgTWVtb3J5LnBva2VMb25nKGFkZHJlc3MgKyBvZmZzZXQsIHZhbHVlLCBvcmRlci5uZWVkc1N3YXApOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBsb25nIHBlZWtMb25nKGludCBvZmZzZXQsIEJ5dGVPcmRlciBvcmRlcikgeworICAgICAgICByZXR1cm4gTWVtb3J5LnBlZWtMb25nKGFkZHJlc3MgKyBvZmZzZXQsIG9yZGVyLm5lZWRzU3dhcCk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIGludCB0b0ludCgpIHsKKyAgICAgICAgcmV0dXJuIGFkZHJlc3M7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIGdldENsYXNzKCkuZ2V0TmFtZSgpICsgIlsiICsgYWRkcmVzcyArICJdIjsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgbG9uZyBnZXRTaXplKCkgeworICAgICAgICByZXR1cm4gc2l6ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vTklPQWNjZXNzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vTklPQWNjZXNzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzYxYTM3ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9OSU9BY2Nlc3MuamF2YQpAQCAtMCwwICsxLDY3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIHVzZWQgdmlhIEpOSSBieSBjb2RlIGluIGZyYW1ld29ya3MvYmFzZS8uCisgKi8KK2ZpbmFsIGNsYXNzIE5JT0FjY2VzcyB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB1bmRlcmx5aW5nIG5hdGl2ZSBwb2ludGVyIHRvIHRoZSBkYXRhIG9mIHRoZSBnaXZlbgorICAgICAqIEJ1ZmZlciBzdGFydGluZyBhdCB0aGUgQnVmZmVyJ3MgY3VycmVudCBwb3NpdGlvbiwgb3IgMCBpZiB0aGUKKyAgICAgKiBCdWZmZXIgaXMgbm90IGJhY2tlZCBieSBuYXRpdmUgaGVhcCBzdG9yYWdlLiBOb3RlIHRoYXQgdGhpcyBpcworICAgICAqIGRpZmZlcmVudCB0aGFuIHdoYXQgdGhlIEhhcm1vbnkgaW1wbGVtZW50YXRpb24gY2FsbHMgYSAiYmFzZQorICAgICAqIGFkZHJlc3MuIgorICAgICAqCisgICAgICogQHBhcmFtIEJ1ZmZlciBiIHRoZSBCdWZmZXIgdG8gYmUgcXVlcmllZAorICAgICAqIEByZXR1cm4gdGhlIG5hdGl2ZSBwb2ludGVyIHRvIHRoZSBCdWZmZXIncyBkYXRhIGF0IGl0cyBjdXJyZW50CisgICAgICogcG9zaXRpb24sIG9yIDAgaWYgdGhlcmUgaXMgbm9uZQorICAgICAqLworICAgIHN0YXRpYyBsb25nIGdldEJhc2VQb2ludGVyKEJ1ZmZlciBiKSB7CisgICAgICAgIGludCBhZGRyZXNzID0gYi5lZmZlY3RpdmVEaXJlY3RBZGRyZXNzOworICAgICAgICBpZiAoYWRkcmVzcyA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gMEw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGFkZHJlc3MgKyAoYi5wb3NpdGlvbiA8PCBiLl9lbGVtZW50U2l6ZVNoaWZ0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB1bmRlcmx5aW5nIEphdmEgYXJyYXkgY29udGFpbmluZyB0aGUgZGF0YSBvZiB0aGUKKyAgICAgKiBnaXZlbiBCdWZmZXIsIG9yIG51bGwgaWYgdGhlIEJ1ZmZlciBpcyBub3QgYmFja2VkIGJ5IGEgSmF2YSBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBCdWZmZXIgYiB0aGUgQnVmZmVyIHRvIGJlIHF1ZXJpZWQKKyAgICAgKiBAcmV0dXJuIHRoZSBKYXZhIGFycmF5IGNvbnRhaW5pbmcgdGhlIEJ1ZmZlcidzIGRhdGEsIG9yIG51bGwgaWYKKyAgICAgKiB0aGVyZSBpcyBub25lCisgICAgICovCisgICAgc3RhdGljIE9iamVjdCBnZXRCYXNlQXJyYXkoQnVmZmVyIGIpIHsKKyAgICAgICAgcmV0dXJuIGIuaGFzQXJyYXkoKSA/IGIuYXJyYXkoKSA6IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgb2Zmc2V0IGluIGJ5dGVzIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB1bmRlcmx5aW5nCisgICAgICogSmF2YSBhcnJheSBvYmplY3QgY29udGFpbmluZyB0aGUgZGF0YSBvZiB0aGUgZ2l2ZW4gQnVmZmVyIHRvCisgICAgICogdGhlIGFjdHVhbCBzdGFydCBvZiB0aGUgZGF0YS4gVGhpcyBtZXRob2QgaXMgb25seSBtZWFuaW5nZnVsIGlmCisgICAgICogZ2V0QmFzZUFycmF5KCkgcmV0dXJucyBub24tbnVsbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBCdWZmZXIgYiB0aGUgQnVmZmVyIHRvIGJlIHF1ZXJpZWQKKyAgICAgKiBAcmV0dXJuIHRoZSBkYXRhIG9mZnNldCBpbiBieXRlcyB0byB0aGUgc3RhcnQgb2YgdGhpcyBCdWZmZXIncyBkYXRhCisgICAgICovCisgICAgc3RhdGljIGludCBnZXRCYXNlQXJyYXlPZmZzZXQoQnVmZmVyIGIpIHsKKyAgICAgICAgcmV0dXJuIGIuaGFzQXJyYXkoKSA/IChiLmFycmF5T2Zmc2V0KCkgPDwgYi5fZWxlbWVudFNpemVTaGlmdCkgOiAwOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9OaW9VdGlscy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL05pb1V0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTZiOGI4YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9OaW9VdGlscy5qYXZhCkBAIC0wLDAgKzEsOTAgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW87CisKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkZpbGVDaGFubmVsOworCisvKioKKyAqIEBoaWRlIGludGVybmFsIHVzZSBvbmx5CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBOaW9VdGlscyB7CisgICAgcHJpdmF0ZSBOaW9VdGlscygpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzdGFydCBhZGRyZXNzIG9mIGEgZGlyZWN0IGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBjb3JyZXNwb25kcyB0byB0aGUgSk5JIGZ1bmN0aW9uOgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiAgICB2b2lkKiBHZXREaXJlY3RCdWZmZXJBZGRyZXNzKEpOSUVudiogZW52LCBqb2JqZWN0IGJ1Zik7CisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmCisgICAgICogICAgICAgICAgICB0aGUgZGlyZWN0IGJ1ZmZlciB3aG9zZSBhZGRyZXNzIHNoYWxsIGJlIHJldHVybmVkIG11c3Qgbm90IGJlCisgICAgICogICAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKiBAcmV0dXJuIHRoZSBhZGRyZXNzIG9mIHRoZSBidWZmZXIgZ2l2ZW4sIG9yIHplcm8gaWYgdGhlIGJ1ZmZlciBpcyBub3QgYQorICAgICAqICAgICAgICAgZGlyZWN0IEJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBnZXREaXJlY3RCdWZmZXJBZGRyZXNzKEJ1ZmZlciBidWZmZXIpIHsKKyAgICAgICAgcmV0dXJuIGJ1ZmZlci5lZmZlY3RpdmVEaXJlY3RBZGRyZXNzOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBmcmVlRGlyZWN0QnVmZmVyKEJ5dGVCdWZmZXIgYnVmZmVyKSB7CisgICAgICAgIGlmIChidWZmZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGlmIChidWZmZXIgaW5zdGFuY2VvZiBEaXJlY3RCeXRlQnVmZmVyKSB7CisgICAgICAgICAgICAoKERpcmVjdEJ5dGVCdWZmZXIpIGJ1ZmZlcikuZnJlZSgpOworICAgICAgICB9IGVsc2UgaWYgKGJ1ZmZlciBpbnN0YW5jZW9mIE1hcHBlZEJ5dGVCdWZmZXIpIHsKKyAgICAgICAgICAgICgoTWFwcGVkQnl0ZUJ1ZmZlckFkYXB0ZXIpIGJ1ZmZlcikuZnJlZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbnQgZmlsZSBkZXNjcmlwdG9yIGZyb20gd2l0aGluIHRoZSBnaXZlbiBGaWxlQ2hhbm5lbCAnZmMnLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgRmlsZURlc2NyaXB0b3IgZ2V0RkQoRmlsZUNoYW5uZWwgZmMpIHsKKyAgICAgICAgcmV0dXJuICgoRmlsZUNoYW5uZWxJbXBsKSBmYykuZ2V0RkQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBIZWxwcyBicmlkZ2UgYmV0d2VlbiBpbyBhbmQgbmlvLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgRmlsZUNoYW5uZWwgbmV3RmlsZUNoYW5uZWwoT2JqZWN0IHN0cmVhbSwgRmlsZURlc2NyaXB0b3IgZmQsIGludCBtb2RlKSB7CisgICAgICAgIHJldHVybiBuZXcgRmlsZUNoYW5uZWxJbXBsKHN0cmVhbSwgZmQsIG1vZGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4cG9zZXMgdGhlIGFycmF5IGJhY2tpbmcgYSBub24tZGlyZWN0IEJ5dGVCdWZmZXIsIGV2ZW4gaWYgdGhlIEJ5dGVCdWZmZXIgaXMgcmVhZC1vbmx5LgorICAgICAqIE5vcm1hbGx5LCBhdHRlbXB0aW5nIHRvIGFjY2VzcyB0aGUgYXJyYXkgYmFja2luZyBhIHJlYWQtb25seSBidWZmZXIgdGhyb3dzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIHVuc2FmZUFycmF5KEJ5dGVCdWZmZXIgYikgeworICAgICAgICByZXR1cm4gKChIZWFwQnl0ZUJ1ZmZlcikgYikuYmFja2luZ0FycmF5OworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4cG9zZXMgdGhlIGFycmF5IG9mZnNldCBmb3IgdGhlIGFycmF5IGJhY2tpbmcgYSBub24tZGlyZWN0IEJ5dGVCdWZmZXIsCisgICAgICogZXZlbiBpZiB0aGUgQnl0ZUJ1ZmZlciBpcyByZWFkLW9ubHkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgdW5zYWZlQXJyYXlPZmZzZXQoQnl0ZUJ1ZmZlciBiKSB7CisgICAgICAgIHJldHVybiAoKEhlYXBCeXRlQnVmZmVyKSBiKS5vZmZzZXQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1BpcGVJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUGlwZUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MDAyOGY0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1BpcGVJbXBsLmphdmEKQEAgLTAsMCArMSwxMzkgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW87CisKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuUGlwZTsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5zcGkuU2VsZWN0b3JQcm92aWRlcjsKK2ltcG9ydCBsaWJjb3JlLmlvLkVycm5vRXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKK2ltcG9ydCBsaWJjb3JlLmlvLkxpYmNvcmU7CitpbXBvcnQgc3RhdGljIGxpYmNvcmUuaW8uT3NDb25zdGFudHMuKjsKKworLyoKKyAqIEltcGxlbWVudHMge0BsaW5rIGphdmEubmlvLmNoYW5uZWxzLlBpcGV9LgorICovCitmaW5hbCBjbGFzcyBQaXBlSW1wbCBleHRlbmRzIFBpcGUgeworICAgIHByaXZhdGUgZmluYWwgUGlwZVNpbmtDaGFubmVsIHNpbms7CisgICAgcHJpdmF0ZSBmaW5hbCBQaXBlU291cmNlQ2hhbm5lbCBzb3VyY2U7CisKKyAgICBwdWJsaWMgUGlwZUltcGwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JbXSBmZHMgPSBMaWJjb3JlLm9zLnBpcGUoKTsKKyAgICAgICAgICAgIC8vIFdoaWNoIGZkIGlzIHVzZWQgZm9yIHdoaWNoIGNoYW5uZWwgaXMgaW1wb3J0YW50LiBVbml4IHBpcGVzIGFyZSBvbmx5IGd1YXJhbnRlZWQgdG8gYmUKKyAgICAgICAgICAgIC8vIHVuaWRpcmVjdGlvbmFsLCBhbmQgaW5kZWVkIGFyZSBvbmx5IHVuaWRpcmVjdGlvbmFsIG9uIExpbnV4LgorICAgICAgICAgICAgdGhpcy5zaW5rID0gbmV3IFBpcGVTaW5rQ2hhbm5lbChmZHNbMV0pOworICAgICAgICAgICAgdGhpcy5zb3VyY2UgPSBuZXcgUGlwZVNvdXJjZUNoYW5uZWwoZmRzWzBdKTsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRocm93IGVycm5vRXhjZXB0aW9uLnJldGhyb3dBc0lPRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFNpbmtDaGFubmVsIHNpbmsoKSB7CisgICAgICAgIHJldHVybiBzaW5rOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU291cmNlQ2hhbm5lbCBzb3VyY2UoKSB7CisgICAgICAgIHJldHVybiBzb3VyY2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsZUNoYW5uZWxJbXBsIGRvZXNuJ3QgY2xvc2UgaXRzIGZkIGl0c2VsZjsgaXQgY2FsbHMgY2xvc2Ugb24gdGhlIG9iamVjdCBpdCdzIGdpdmVuLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEZkQ2xvc2VyIGltcGxlbWVudHMgQ2xvc2VhYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBGaWxlRGVzY3JpcHRvciBmZDsKKyAgICAgICAgcHJpdmF0ZSBGZENsb3NlcihGaWxlRGVzY3JpcHRvciBmZCkgeworICAgICAgICAgICAgdGhpcy5mZCA9IGZkOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIElvVXRpbHMuY2xvc2UoZmQpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBQaXBlU291cmNlQ2hhbm5lbCBleHRlbmRzIFBpcGUuU291cmNlQ2hhbm5lbCBpbXBsZW1lbnRzIEZpbGVEZXNjcmlwdG9yQ2hhbm5lbCB7CisgICAgICAgIHByaXZhdGUgZmluYWwgRmlsZURlc2NyaXB0b3IgZmQ7CisgICAgICAgIHByaXZhdGUgZmluYWwgRmlsZUNoYW5uZWwgY2hhbm5lbDsKKworICAgICAgICBwcml2YXRlIFBpcGVTb3VyY2VDaGFubmVsKEZpbGVEZXNjcmlwdG9yIGZkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIoU2VsZWN0b3JQcm92aWRlci5wcm92aWRlcigpKTsKKyAgICAgICAgICAgIHRoaXMuZmQgPSBmZDsKKyAgICAgICAgICAgIHRoaXMuY2hhbm5lbCA9IE5pb1V0aWxzLm5ld0ZpbGVDaGFubmVsKG5ldyBGZENsb3NlcihmZCksIGZkLCBPX1JET05MWSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgaW1wbENsb3NlU2VsZWN0YWJsZUNoYW5uZWwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgY2hhbm5lbC5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGltcGxDb25maWd1cmVCbG9ja2luZyhib29sZWFuIGJsb2NraW5nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgSW9VdGlscy5zZXRCbG9ja2luZyhnZXRGRCgpLCBibG9ja2luZyk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IHJlYWQoQnl0ZUJ1ZmZlciBidWZmZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gY2hhbm5lbC5yZWFkKGJ1ZmZlcik7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgbG9uZyByZWFkKEJ5dGVCdWZmZXJbXSBidWZmZXJzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIGNoYW5uZWwucmVhZChidWZmZXJzKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBsb25nIHJlYWQoQnl0ZUJ1ZmZlcltdIGJ1ZmZlcnMsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gY2hhbm5lbC5yZWFkKGJ1ZmZlcnMsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBGaWxlRGVzY3JpcHRvciBnZXRGRCgpIHsKKyAgICAgICAgICAgIHJldHVybiBmZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgUGlwZVNpbmtDaGFubmVsIGV4dGVuZHMgUGlwZS5TaW5rQ2hhbm5lbCBpbXBsZW1lbnRzIEZpbGVEZXNjcmlwdG9yQ2hhbm5lbCB7CisgICAgICAgIHByaXZhdGUgZmluYWwgRmlsZURlc2NyaXB0b3IgZmQ7CisgICAgICAgIHByaXZhdGUgZmluYWwgRmlsZUNoYW5uZWwgY2hhbm5lbDsKKworICAgICAgICBwcml2YXRlIFBpcGVTaW5rQ2hhbm5lbChGaWxlRGVzY3JpcHRvciBmZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyKFNlbGVjdG9yUHJvdmlkZXIucHJvdmlkZXIoKSk7CisgICAgICAgICAgICB0aGlzLmZkID0gZmQ7CisgICAgICAgICAgICB0aGlzLmNoYW5uZWwgPSBOaW9VdGlscy5uZXdGaWxlQ2hhbm5lbChuZXcgRmRDbG9zZXIoZmQpLCBmZCwgT19XUk9OTFkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGltcGxDbG9zZVNlbGVjdGFibGVDaGFubmVsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBpbXBsQ29uZmlndXJlQmxvY2tpbmcoYm9vbGVhbiBibG9ja2luZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIElvVXRpbHMuc2V0QmxvY2tpbmcoZ2V0RkQoKSwgYmxvY2tpbmcpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCB3cml0ZShCeXRlQnVmZmVyIGJ1ZmZlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBjaGFubmVsLndyaXRlKGJ1ZmZlcik7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgbG9uZyB3cml0ZShCeXRlQnVmZmVyW10gYnVmZmVycykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBjaGFubmVsLndyaXRlKGJ1ZmZlcnMpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGxvbmcgd3JpdGUoQnl0ZUJ1ZmZlcltdIGJ1ZmZlcnMsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gY2hhbm5lbC53cml0ZShidWZmZXJzLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3IgZ2V0RkQoKSB7CisgICAgICAgICAgICByZXR1cm4gZmQ7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkT25seUJ1ZmZlckV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFlMzEwZjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDMyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCisvKioKKyAqIEEge0Bjb2RlIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9ufSBpcyB0aHJvd24gd2hlbiBzb21lIHdyaXRlIG9wZXJhdGlvbiBpcworICogY2FsbGVkIG9uIGEgcmVhZC1vbmx5IGJ1ZmZlci4KKyAqLworcHVibGljIGNsYXNzIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uIGV4dGVuZHMgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTEyMTAwNjM5NzY0OTYyMzQwOTBMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkT25seUNoYXJBcnJheUJ1ZmZlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1JlYWRPbmx5Q2hhckFycmF5QnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmYzMGRiYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkT25seUNoYXJBcnJheUJ1ZmZlci5qYXZhCkBAIC0wLDAgKzEsMTExIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCisvKioKKyAqIENoYXJBcnJheUJ1ZmZlciwgUmVhZFdyaXRlQ2hhckFycmF5QnVmZmVyIGFuZCBSZWFkT25seUNoYXJBcnJheUJ1ZmZlciBjb21wb3NlCisgKiB0aGUgaW1wbGVtZW50YXRpb24gb2YgYXJyYXkgYmFzZWQgY2hhciBidWZmZXJzLgorICogPHA+CisgKiBSZWFkT25seUNoYXJBcnJheUJ1ZmZlciBleHRlbmRzIENoYXJBcnJheUJ1ZmZlciB3aXRoIGFsbCB0aGUgd3JpdGUgbWV0aG9kcworICogdGhyb3dpbmcgcmVhZCBvbmx5IGV4Y2VwdGlvbi4KKyAqIDwvcD4KKyAqIDxwPgorICogVGhpcyBjbGFzcyBpcyBtYXJrZWQgZmluYWwgZm9yIHJ1bnRpbWUgcGVyZm9ybWFuY2UuCisgKiA8L3A+CisgKgorICovCitmaW5hbCBjbGFzcyBSZWFkT25seUNoYXJBcnJheUJ1ZmZlciBleHRlbmRzIENoYXJBcnJheUJ1ZmZlciB7CisKKyAgICBzdGF0aWMgUmVhZE9ubHlDaGFyQXJyYXlCdWZmZXIgY29weShDaGFyQXJyYXlCdWZmZXIgb3RoZXIsIGludCBtYXJrT2ZPdGhlcikgeworICAgICAgICBSZWFkT25seUNoYXJBcnJheUJ1ZmZlciBidWYgPQorICAgICAgICAgICAgICAgIG5ldyBSZWFkT25seUNoYXJBcnJheUJ1ZmZlcihvdGhlci5jYXBhY2l0eSgpLCBvdGhlci5iYWNraW5nQXJyYXksIG90aGVyLm9mZnNldCk7CisgICAgICAgIGJ1Zi5saW1pdCA9IG90aGVyLmxpbWl0OworICAgICAgICBidWYucG9zaXRpb24gPSBvdGhlci5wb3NpdGlvbigpOworICAgICAgICBidWYubWFyayA9IG1hcmtPZk90aGVyOworICAgICAgICByZXR1cm4gYnVmOworICAgIH0KKworICAgIFJlYWRPbmx5Q2hhckFycmF5QnVmZmVyKGludCBjYXBhY2l0eSwgY2hhcltdIGJhY2tpbmdBcnJheSwgaW50IGFycmF5T2Zmc2V0KSB7CisgICAgICAgIHN1cGVyKGNhcGFjaXR5LCBiYWNraW5nQXJyYXksIGFycmF5T2Zmc2V0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ2hhckJ1ZmZlciBhc1JlYWRPbmx5QnVmZmVyKCkgeworICAgICAgICByZXR1cm4gZHVwbGljYXRlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENoYXJCdWZmZXIgY29tcGFjdCgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENoYXJCdWZmZXIgZHVwbGljYXRlKCkgeworICAgICAgICByZXR1cm4gY29weSh0aGlzLCBtYXJrKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1JlYWRPbmx5KCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgY2hhcltdIHByb3RlY3RlZEFycmF5KCkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IHByb3RlY3RlZEFycmF5T2Zmc2V0KCkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwcm90ZWN0ZWRIYXNBcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDaGFyQnVmZmVyIHB1dChjaGFyIGMpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENoYXJCdWZmZXIgcHV0KGludCBpbmRleCwgY2hhciBjKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBDaGFyQnVmZmVyIHB1dChjaGFyW10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgY2hhckNvdW50KSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBDaGFyQnVmZmVyIHB1dChDaGFyQnVmZmVyIHNyYykgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ2hhckJ1ZmZlciBwdXQoU3RyaW5nIHNyYywgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDaGFyQnVmZmVyIHNsaWNlKCkgeworICAgICAgICByZXR1cm4gbmV3IFJlYWRPbmx5Q2hhckFycmF5QnVmZmVyKHJlbWFpbmluZygpLCBiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZE9ubHlEaXJlY3RCeXRlQnVmZmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZE9ubHlEaXJlY3RCeXRlQnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGQ2MTc5NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkT25seURpcmVjdEJ5dGVCdWZmZXIuamF2YQpAQCAtMCwwICsxLDE1MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworLyoqCisgKiBEaXJlY3RCeXRlQnVmZmVyLCBSZWFkV3JpdGVEaXJlY3RCeXRlQnVmZmVyIGFuZCBSZWFkT25seURpcmVjdEJ5dGVCdWZmZXIKKyAqIGNvbXBvc2UgdGhlIGltcGxlbWVudGF0aW9uIG9mIHBsYXRmb3JtIG1lbW9yeSBiYXNlZCBieXRlIGJ1ZmZlcnMuCisgKiA8cD4KKyAqIFJlYWRPbmx5RGlyZWN0Qnl0ZUJ1ZmZlciBleHRlbmRzIERpcmVjdEJ5dGVCdWZmZXIgd2l0aCBhbGwgdGhlIHdyaXRlIG1ldGhvZHMKKyAqIHRocm93aW5nIHJlYWQgb25seSBleGNlcHRpb24uCisgKiA8L3A+CisgKiA8cD4KKyAqIFRoaXMgY2xhc3MgaXMgbWFya2VkIGZpbmFsIGZvciBydW50aW1lIHBlcmZvcm1hbmNlLgorICogPC9wPgorICovCitmaW5hbCBjbGFzcyBSZWFkT25seURpcmVjdEJ5dGVCdWZmZXIgZXh0ZW5kcyBEaXJlY3RCeXRlQnVmZmVyIHsKKyAgICBzdGF0aWMgUmVhZE9ubHlEaXJlY3RCeXRlQnVmZmVyIGNvcHkoRGlyZWN0Qnl0ZUJ1ZmZlciBvdGhlciwgaW50IG1hcmtPZk90aGVyKSB7CisgICAgICAgIFJlYWRPbmx5RGlyZWN0Qnl0ZUJ1ZmZlciBidWYgPSBuZXcgUmVhZE9ubHlEaXJlY3RCeXRlQnVmZmVyKG90aGVyLmJsb2NrLCBvdGhlci5jYXBhY2l0eSgpLCBvdGhlci5vZmZzZXQpOworICAgICAgICBidWYubGltaXQgPSBvdGhlci5saW1pdDsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gb3RoZXIucG9zaXRpb24oKTsKKyAgICAgICAgYnVmLm1hcmsgPSBtYXJrT2ZPdGhlcjsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgUmVhZE9ubHlEaXJlY3RCeXRlQnVmZmVyKE1lbW9yeUJsb2NrIGJsb2NrLCBpbnQgY2FwYWNpdHksIGludCBvZmZzZXQpIHsKKyAgICAgICAgc3VwZXIoYmxvY2ssIGNhcGFjaXR5LCBvZmZzZXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIGFzUmVhZE9ubHlCdWZmZXIoKSB7CisgICAgICAgIHJldHVybiBjb3B5KHRoaXMsIG1hcmspOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIGNvbXBhY3QoKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIGR1cGxpY2F0ZSgpIHsKKyAgICAgICAgcmV0dXJuIGNvcHkodGhpcywgbWFyayk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNSZWFkT25seSgpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0KGJ5dGUgdmFsdWUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0KGludCBpbmRleCwgYnl0ZSB2YWx1ZSkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXQoYnl0ZVtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGJ5dGVDb3VudCkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXREb3VibGUoZG91YmxlIHZhbHVlKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dERvdWJsZShpbnQgaW5kZXgsIGRvdWJsZSB2YWx1ZSkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRGbG9hdChmbG9hdCB2YWx1ZSkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRGbG9hdChpbnQgaW5kZXgsIGZsb2F0IHZhbHVlKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dEludChpbnQgdmFsdWUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0SW50KGludCBpbmRleCwgaW50IHZhbHVlKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dExvbmcoaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dExvbmcobG9uZyB2YWx1ZSkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRTaG9ydChpbnQgaW5kZXgsIHNob3J0IHZhbHVlKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dFNob3J0KHNob3J0IHZhbHVlKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dChCeXRlQnVmZmVyIGJ1ZikgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBzbGljZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBSZWFkT25seURpcmVjdEJ5dGVCdWZmZXIoYmxvY2ssIHJlbWFpbmluZygpLCBvZmZzZXQgKyBwb3NpdGlvbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBieXRlW10gcHJvdGVjdGVkQXJyYXkoKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgaW50IHByb3RlY3RlZEFycmF5T2Zmc2V0KCkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIGJvb2xlYW4gcHJvdGVjdGVkSGFzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZE9ubHlEb3VibGVBcnJheUJ1ZmZlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1JlYWRPbmx5RG91YmxlQXJyYXlCdWZmZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NjBiYmY0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1JlYWRPbmx5RG91YmxlQXJyYXlCdWZmZXIuamF2YQpAQCAtMCwwICsxLDEwNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworLyoqCisgKiBEb3VibGVBcnJheUJ1ZmZlciwgUmVhZFdyaXRlRG91YmxlQXJyYXlCdWZmZXIgYW5kIFJlYWRPbmx5RG91YmxlQXJyYXlCdWZmZXIKKyAqIGNvbXBvc2UgdGhlIGltcGxlbWVudGF0aW9uIG9mIGFycmF5IGJhc2VkIGRvdWJsZSBidWZmZXJzLgorICogPHA+CisgKiBSZWFkT25seURvdWJsZUFycmF5QnVmZmVyIGV4dGVuZHMgRG91YmxlQXJyYXlCdWZmZXIgd2l0aCBhbGwgdGhlIHdyaXRlCisgKiBtZXRob2RzIHRocm93aW5nIHJlYWQgb25seSBleGNlcHRpb24uCisgKiA8L3A+CisgKiA8cD4KKyAqIFRoaXMgY2xhc3MgaXMgbWFya2VkIGZpbmFsIGZvciBydW50aW1lIHBlcmZvcm1hbmNlLgorICogPC9wPgorICoKKyAqLworZmluYWwgY2xhc3MgUmVhZE9ubHlEb3VibGVBcnJheUJ1ZmZlciBleHRlbmRzIERvdWJsZUFycmF5QnVmZmVyIHsKKworICAgIHN0YXRpYyBSZWFkT25seURvdWJsZUFycmF5QnVmZmVyIGNvcHkoRG91YmxlQXJyYXlCdWZmZXIgb3RoZXIsIGludCBtYXJrT2ZPdGhlcikgeworICAgICAgICBSZWFkT25seURvdWJsZUFycmF5QnVmZmVyIGJ1ZiA9CisgICAgICAgICAgICAgICAgbmV3IFJlYWRPbmx5RG91YmxlQXJyYXlCdWZmZXIob3RoZXIuY2FwYWNpdHkoKSwgb3RoZXIuYmFja2luZ0FycmF5LCBvdGhlci5vZmZzZXQpOworICAgICAgICBidWYubGltaXQgPSBvdGhlci5saW1pdDsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gb3RoZXIucG9zaXRpb24oKTsKKyAgICAgICAgYnVmLm1hcmsgPSBtYXJrT2ZPdGhlcjsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICBSZWFkT25seURvdWJsZUFycmF5QnVmZmVyKGludCBjYXBhY2l0eSwgZG91YmxlW10gYmFja2luZ0FycmF5LCBpbnQgYXJyYXlPZmZzZXQpIHsKKyAgICAgICAgc3VwZXIoY2FwYWNpdHksIGJhY2tpbmdBcnJheSwgYXJyYXlPZmZzZXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEb3VibGVCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpIHsKKyAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEb3VibGVCdWZmZXIgY29tcGFjdCgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERvdWJsZUJ1ZmZlciBkdXBsaWNhdGUoKSB7CisgICAgICAgIHJldHVybiBjb3B5KHRoaXMsIG1hcmspOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzUmVhZE9ubHkoKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBkb3VibGVbXSBwcm90ZWN0ZWRBcnJheSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBwcm90ZWN0ZWRBcnJheU9mZnNldCgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcHJvdGVjdGVkSGFzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRG91YmxlQnVmZmVyIHB1dChkb3VibGUgYykgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRG91YmxlQnVmZmVyIHB1dChpbnQgaW5kZXgsIGRvdWJsZSBjKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBEb3VibGVCdWZmZXIgcHV0KGRvdWJsZVtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGJ5dGVDb3VudCkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgRG91YmxlQnVmZmVyIHB1dChEb3VibGVCdWZmZXIgYnVmKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEb3VibGVCdWZmZXIgc2xpY2UoKSB7CisgICAgICAgIHJldHVybiBuZXcgUmVhZE9ubHlEb3VibGVBcnJheUJ1ZmZlcihyZW1haW5pbmcoKSwgYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZE9ubHlGbG9hdEFycmF5QnVmZmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZE9ubHlGbG9hdEFycmF5QnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzc1ZTFkOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkT25seUZsb2F0QXJyYXlCdWZmZXIuamF2YQpAQCAtMCwwICsxLDEwNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworLyoqCisgKiBGbG9hdEFycmF5QnVmZmVyLCBSZWFkV3JpdGVGbG9hdEFycmF5QnVmZmVyIGFuZCBSZWFkT25seUZsb2F0QXJyYXlCdWZmZXIKKyAqIGNvbXBvc2UgdGhlIGltcGxlbWVudGF0aW9uIG9mIGFycmF5IGJhc2VkIGZsb2F0IGJ1ZmZlcnMuCisgKiA8cD4KKyAqIFJlYWRPbmx5RmxvYXRBcnJheUJ1ZmZlciBleHRlbmRzIEZsb2F0QXJyYXlCdWZmZXIgd2l0aCBhbGwgdGhlIHdyaXRlIG1ldGhvZHMKKyAqIHRocm93aW5nIHJlYWQgb25seSBleGNlcHRpb24uCisgKiA8L3A+CisgKiA8cD4KKyAqIFRoaXMgY2xhc3MgaXMgbWFya2VkIGZpbmFsIGZvciBydW50aW1lIHBlcmZvcm1hbmNlLgorICogPC9wPgorICoKKyAqLworZmluYWwgY2xhc3MgUmVhZE9ubHlGbG9hdEFycmF5QnVmZmVyIGV4dGVuZHMgRmxvYXRBcnJheUJ1ZmZlciB7CisKKyAgICBzdGF0aWMgUmVhZE9ubHlGbG9hdEFycmF5QnVmZmVyIGNvcHkoRmxvYXRBcnJheUJ1ZmZlciBvdGhlciwgaW50IG1hcmtPZk90aGVyKSB7CisgICAgICAgIFJlYWRPbmx5RmxvYXRBcnJheUJ1ZmZlciBidWYgPQorICAgICAgICAgICAgICAgIG5ldyBSZWFkT25seUZsb2F0QXJyYXlCdWZmZXIob3RoZXIuY2FwYWNpdHkoKSwgb3RoZXIuYmFja2luZ0FycmF5LCBvdGhlci5vZmZzZXQpOworICAgICAgICBidWYubGltaXQgPSBvdGhlci5saW1pdDsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gb3RoZXIucG9zaXRpb24oKTsKKyAgICAgICAgYnVmLm1hcmsgPSBtYXJrT2ZPdGhlcjsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICBSZWFkT25seUZsb2F0QXJyYXlCdWZmZXIoaW50IGNhcGFjaXR5LCBmbG9hdFtdIGJhY2tpbmdBcnJheSwgaW50IGFycmF5T2Zmc2V0KSB7CisgICAgICAgIHN1cGVyKGNhcGFjaXR5LCBiYWNraW5nQXJyYXksIGFycmF5T2Zmc2V0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRmxvYXRCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpIHsKKyAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGbG9hdEJ1ZmZlciBjb21wYWN0KCkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRmxvYXRCdWZmZXIgZHVwbGljYXRlKCkgeworICAgICAgICByZXR1cm4gY29weSh0aGlzLCBtYXJrKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1JlYWRPbmx5KCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgZmxvYXRbXSBwcm90ZWN0ZWRBcnJheSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBwcm90ZWN0ZWRBcnJheU9mZnNldCgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcHJvdGVjdGVkSGFzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRmxvYXRCdWZmZXIgcHV0KGZsb2F0IGMpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZsb2F0QnVmZmVyIHB1dChpbnQgaW5kZXgsIGZsb2F0IGMpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZsb2F0QnVmZmVyIHB1dChGbG9hdEJ1ZmZlciBidWYpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIEZsb2F0QnVmZmVyIHB1dChmbG9hdFtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGJ5dGVDb3VudCkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRmxvYXRCdWZmZXIgc2xpY2UoKSB7CisgICAgICAgIHJldHVybiBuZXcgUmVhZE9ubHlGbG9hdEFycmF5QnVmZmVyKHJlbWFpbmluZygpLCBiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkT25seUhlYXBCeXRlQnVmZmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZE9ubHlIZWFwQnl0ZUJ1ZmZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM4Mjc5NGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZE9ubHlIZWFwQnl0ZUJ1ZmZlci5qYXZhCkBAIC0wLDAgKzEsMTU2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCisvKioKKyAqIEhlYXBCeXRlQnVmZmVyLCBSZWFkV3JpdGVIZWFwQnl0ZUJ1ZmZlciBhbmQgUmVhZE9ubHlIZWFwQnl0ZUJ1ZmZlciBjb21wb3NlCisgKiB0aGUgaW1wbGVtZW50YXRpb24gb2YgYXJyYXkgYmFzZWQgYnl0ZSBidWZmZXJzLgorICogPHA+CisgKiBSZWFkT25seUhlYXBCeXRlQnVmZmVyIGV4dGVuZHMgSGVhcEJ5dGVCdWZmZXIgd2l0aCBhbGwgdGhlIHdyaXRlIG1ldGhvZHMKKyAqIHRocm93aW5nIHJlYWQgb25seSBleGNlcHRpb24uCisgKiA8L3A+CisgKiA8cD4KKyAqIFRoaXMgY2xhc3MgaXMgbWFya2VkIGZpbmFsIGZvciBydW50aW1lIHBlcmZvcm1hbmNlLgorICogPC9wPgorICoKKyAqLworZmluYWwgY2xhc3MgUmVhZE9ubHlIZWFwQnl0ZUJ1ZmZlciBleHRlbmRzIEhlYXBCeXRlQnVmZmVyIHsKKworICAgIHN0YXRpYyBSZWFkT25seUhlYXBCeXRlQnVmZmVyIGNvcHkoSGVhcEJ5dGVCdWZmZXIgb3RoZXIsIGludCBtYXJrT2ZPdGhlcikgeworICAgICAgICBSZWFkT25seUhlYXBCeXRlQnVmZmVyIGJ1ZiA9CisgICAgICAgICAgICAgICAgbmV3IFJlYWRPbmx5SGVhcEJ5dGVCdWZmZXIob3RoZXIuYmFja2luZ0FycmF5LCBvdGhlci5jYXBhY2l0eSgpLCBvdGhlci5vZmZzZXQpOworICAgICAgICBidWYubGltaXQgPSBvdGhlci5saW1pdDsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gb3RoZXIucG9zaXRpb24oKTsKKyAgICAgICAgYnVmLm1hcmsgPSBtYXJrT2ZPdGhlcjsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICBSZWFkT25seUhlYXBCeXRlQnVmZmVyKGJ5dGVbXSBiYWNraW5nQXJyYXksIGludCBjYXBhY2l0eSwgaW50IGFycmF5T2Zmc2V0KSB7CisgICAgICAgIHN1cGVyKGJhY2tpbmdBcnJheSwgY2FwYWNpdHksIGFycmF5T2Zmc2V0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBhc1JlYWRPbmx5QnVmZmVyKCkgeworICAgICAgICByZXR1cm4gUmVhZE9ubHlIZWFwQnl0ZUJ1ZmZlci5jb3B5KHRoaXMsIG1hcmspOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIGNvbXBhY3QoKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIGR1cGxpY2F0ZSgpIHsKKyAgICAgICAgcmV0dXJuIGNvcHkodGhpcywgbWFyayk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNSZWFkT25seSgpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBwcm90ZWN0ZWRBcnJheSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBwcm90ZWN0ZWRBcnJheU9mZnNldCgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcHJvdGVjdGVkSGFzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXQoYnl0ZSBiKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dChpbnQgaW5kZXgsIGJ5dGUgYikgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXQoYnl0ZVtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGJ5dGVDb3VudCkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXREb3VibGUoZG91YmxlIHZhbHVlKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dERvdWJsZShpbnQgaW5kZXgsIGRvdWJsZSB2YWx1ZSkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRGbG9hdChmbG9hdCB2YWx1ZSkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRGbG9hdChpbnQgaW5kZXgsIGZsb2F0IHZhbHVlKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dEludChpbnQgdmFsdWUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0SW50KGludCBpbmRleCwgaW50IHZhbHVlKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dExvbmcoaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dExvbmcobG9uZyB2YWx1ZSkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRTaG9ydChpbnQgaW5kZXgsIHNob3J0IHZhbHVlKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dFNob3J0KHNob3J0IHZhbHVlKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dChCeXRlQnVmZmVyIGJ1ZikgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBzbGljZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBSZWFkT25seUhlYXBCeXRlQnVmZmVyKGJhY2tpbmdBcnJheSwgcmVtYWluaW5nKCksIG9mZnNldCArIHBvc2l0aW9uKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZE9ubHlJbnRBcnJheUJ1ZmZlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1JlYWRPbmx5SW50QXJyYXlCdWZmZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMTM3YjNiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1JlYWRPbmx5SW50QXJyYXlCdWZmZXIuamF2YQpAQCAtMCwwICsxLDEwNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworLyoqCisgKiBJbnRBcnJheUJ1ZmZlciwgUmVhZFdyaXRlSW50QXJyYXlCdWZmZXIgYW5kIFJlYWRPbmx5SW50QXJyYXlCdWZmZXIgY29tcG9zZQorICogdGhlIGltcGxlbWVudGF0aW9uIG9mIGFycmF5IGJhc2VkIGludCBidWZmZXJzLgorICogPHA+CisgKiBSZWFkT25seUludEFycmF5QnVmZmVyIGV4dGVuZHMgSW50QXJyYXlCdWZmZXIgd2l0aCBhbGwgdGhlIHdyaXRlIG1ldGhvZHMKKyAqIHRocm93aW5nIHJlYWQgb25seSBleGNlcHRpb24uCisgKiA8L3A+CisgKiA8cD4KKyAqIFRoaXMgY2xhc3MgaXMgbWFya2VkIGZpbmFsIGZvciBydW50aW1lIHBlcmZvcm1hbmNlLgorICogPC9wPgorICoKKyAqLworZmluYWwgY2xhc3MgUmVhZE9ubHlJbnRBcnJheUJ1ZmZlciBleHRlbmRzIEludEFycmF5QnVmZmVyIHsKKworICAgIHN0YXRpYyBSZWFkT25seUludEFycmF5QnVmZmVyIGNvcHkoSW50QXJyYXlCdWZmZXIgb3RoZXIsIGludCBtYXJrT2ZPdGhlcikgeworICAgICAgICBSZWFkT25seUludEFycmF5QnVmZmVyIGJ1ZiA9CisgICAgICAgICAgICAgICAgbmV3IFJlYWRPbmx5SW50QXJyYXlCdWZmZXIob3RoZXIuY2FwYWNpdHkoKSwgb3RoZXIuYmFja2luZ0FycmF5LCBvdGhlci5vZmZzZXQpOworICAgICAgICBidWYubGltaXQgPSBvdGhlci5saW1pdDsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gb3RoZXIucG9zaXRpb24oKTsKKyAgICAgICAgYnVmLm1hcmsgPSBtYXJrT2ZPdGhlcjsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICBSZWFkT25seUludEFycmF5QnVmZmVyKGludCBjYXBhY2l0eSwgaW50W10gYmFja2luZ0FycmF5LCBpbnQgYXJyYXlPZmZzZXQpIHsKKyAgICAgICAgc3VwZXIoY2FwYWNpdHksIGJhY2tpbmdBcnJheSwgYXJyYXlPZmZzZXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnRCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpIHsKKyAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnRCdWZmZXIgY29tcGFjdCgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEludEJ1ZmZlciBkdXBsaWNhdGUoKSB7CisgICAgICAgIHJldHVybiBjb3B5KHRoaXMsIG1hcmspOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzUmVhZE9ubHkoKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnRbXSBwcm90ZWN0ZWRBcnJheSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBwcm90ZWN0ZWRBcnJheU9mZnNldCgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcHJvdGVjdGVkSGFzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW50QnVmZmVyIHB1dChpbnQgYykgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW50QnVmZmVyIHB1dChpbnQgaW5kZXgsIGludCBjKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnRCdWZmZXIgcHV0KEludEJ1ZmZlciBidWYpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIEludEJ1ZmZlciBwdXQoaW50W10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgaW50Q291bnQpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEludEJ1ZmZlciBzbGljZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBSZWFkT25seUludEFycmF5QnVmZmVyKHJlbWFpbmluZygpLCBiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkT25seUxvbmdBcnJheUJ1ZmZlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1JlYWRPbmx5TG9uZ0FycmF5QnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODdiMGM4OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkT25seUxvbmdBcnJheUJ1ZmZlci5qYXZhCkBAIC0wLDAgKzEsMTA3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCisvKioKKyAqIExvbmdBcnJheUJ1ZmZlciwgUmVhZFdyaXRlTG9uZ0FycmF5QnVmZmVyIGFuZCBSZWFkT25seUxvbmdBcnJheUJ1ZmZlciBjb21wb3NlCisgKiB0aGUgaW1wbGVtZW50YXRpb24gb2YgYXJyYXkgYmFzZWQgbG9uZyBidWZmZXJzLgorICogPHA+CisgKiBSZWFkT25seUxvbmdBcnJheUJ1ZmZlciBleHRlbmRzIExvbmdBcnJheUJ1ZmZlciB3aXRoIGFsbCB0aGUgd3JpdGUgbWV0aG9kcworICogdGhyb3dpbmcgcmVhZCBvbmx5IGV4Y2VwdGlvbi4KKyAqIDwvcD4KKyAqIDxwPgorICogVGhpcyBjbGFzcyBpcyBtYXJrZWQgZmluYWwgZm9yIHJ1bnRpbWUgcGVyZm9ybWFuY2UuCisgKiA8L3A+CisgKgorICovCitmaW5hbCBjbGFzcyBSZWFkT25seUxvbmdBcnJheUJ1ZmZlciBleHRlbmRzIExvbmdBcnJheUJ1ZmZlciB7CisKKyAgICBzdGF0aWMgUmVhZE9ubHlMb25nQXJyYXlCdWZmZXIgY29weShMb25nQXJyYXlCdWZmZXIgb3RoZXIsIGludCBtYXJrT2ZPdGhlcikgeworICAgICAgICBSZWFkT25seUxvbmdBcnJheUJ1ZmZlciBidWYgPQorICAgICAgICAgICAgICAgIG5ldyBSZWFkT25seUxvbmdBcnJheUJ1ZmZlcihvdGhlci5jYXBhY2l0eSgpLCBvdGhlci5iYWNraW5nQXJyYXksIG90aGVyLm9mZnNldCk7CisgICAgICAgIGJ1Zi5saW1pdCA9IG90aGVyLmxpbWl0OworICAgICAgICBidWYucG9zaXRpb24gPSBvdGhlci5wb3NpdGlvbigpOworICAgICAgICBidWYubWFyayA9IG1hcmtPZk90aGVyOworICAgICAgICByZXR1cm4gYnVmOworICAgIH0KKworICAgIFJlYWRPbmx5TG9uZ0FycmF5QnVmZmVyKGludCBjYXBhY2l0eSwgbG9uZ1tdIGJhY2tpbmdBcnJheSwgaW50IGFycmF5T2Zmc2V0KSB7CisgICAgICAgIHN1cGVyKGNhcGFjaXR5LCBiYWNraW5nQXJyYXksIGFycmF5T2Zmc2V0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTG9uZ0J1ZmZlciBhc1JlYWRPbmx5QnVmZmVyKCkgeworICAgICAgICByZXR1cm4gZHVwbGljYXRlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIExvbmdCdWZmZXIgY29tcGFjdCgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIExvbmdCdWZmZXIgZHVwbGljYXRlKCkgeworICAgICAgICByZXR1cm4gY29weSh0aGlzLCBtYXJrKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1JlYWRPbmx5KCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgbG9uZ1tdIHByb3RlY3RlZEFycmF5KCkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IHByb3RlY3RlZEFycmF5T2Zmc2V0KCkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwcm90ZWN0ZWRIYXNBcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBMb25nQnVmZmVyIHB1dChsb25nIGMpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIExvbmdCdWZmZXIgcHV0KGludCBpbmRleCwgbG9uZyBjKSB7CisgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBMb25nQnVmZmVyIHB1dChMb25nQnVmZmVyIGJ1ZikgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgTG9uZ0J1ZmZlciBwdXQobG9uZ1tdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGxvbmdDb3VudCkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTG9uZ0J1ZmZlciBzbGljZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBSZWFkT25seUxvbmdBcnJheUJ1ZmZlcihyZW1haW5pbmcoKSwgYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZE9ubHlTaG9ydEFycmF5QnVmZmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZE9ubHlTaG9ydEFycmF5QnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDdiOWM5MAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkT25seVNob3J0QXJyYXlCdWZmZXIuamF2YQpAQCAtMCwwICsxLDEwNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworLyoqCisgKiBTaG9ydEFycmF5QnVmZmVyLCBSZWFkV3JpdGVTaG9ydEFycmF5QnVmZmVyIGFuZCBSZWFkT25seVNob3J0QXJyYXlCdWZmZXIKKyAqIGNvbXBvc2UgdGhlIGltcGxlbWVudGF0aW9uIG9mIGFycmF5IGJhc2VkIHNob3J0IGJ1ZmZlcnMuCisgKiA8cD4KKyAqIFJlYWRPbmx5U2hvcnRBcnJheUJ1ZmZlciBleHRlbmRzIFNob3J0QXJyYXlCdWZmZXIgd2l0aCBhbGwgdGhlIHdyaXRlIG1ldGhvZHMKKyAqIHRocm93aW5nIHJlYWQgb25seSBleGNlcHRpb24uCisgKiA8L3A+CisgKiA8cD4KKyAqIFRoaXMgY2xhc3MgaXMgbWFya2VkIGZpbmFsIGZvciBydW50aW1lIHBlcmZvcm1hbmNlLgorICogPC9wPgorICoKKyAqLworZmluYWwgY2xhc3MgUmVhZE9ubHlTaG9ydEFycmF5QnVmZmVyIGV4dGVuZHMgU2hvcnRBcnJheUJ1ZmZlciB7CisKKyAgICBzdGF0aWMgUmVhZE9ubHlTaG9ydEFycmF5QnVmZmVyIGNvcHkoU2hvcnRBcnJheUJ1ZmZlciBvdGhlciwgaW50IG1hcmtPZk90aGVyKSB7CisgICAgICAgIFJlYWRPbmx5U2hvcnRBcnJheUJ1ZmZlciBidWYgPQorICAgICAgICAgICAgICAgIG5ldyBSZWFkT25seVNob3J0QXJyYXlCdWZmZXIob3RoZXIuY2FwYWNpdHkoKSwgb3RoZXIuYmFja2luZ0FycmF5LCBvdGhlci5vZmZzZXQpOworICAgICAgICBidWYubGltaXQgPSBvdGhlci5saW1pdDsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gb3RoZXIucG9zaXRpb24oKTsKKyAgICAgICAgYnVmLm1hcmsgPSBtYXJrT2ZPdGhlcjsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICBSZWFkT25seVNob3J0QXJyYXlCdWZmZXIoaW50IGNhcGFjaXR5LCBzaG9ydFtdIGJhY2tpbmdBcnJheSwgaW50IGFycmF5T2Zmc2V0KSB7CisgICAgICAgIHN1cGVyKGNhcGFjaXR5LCBiYWNraW5nQXJyYXksIGFycmF5T2Zmc2V0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2hvcnRCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpIHsKKyAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTaG9ydEJ1ZmZlciBjb21wYWN0KCkgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2hvcnRCdWZmZXIgZHVwbGljYXRlKCkgeworICAgICAgICByZXR1cm4gY29weSh0aGlzLCBtYXJrKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1JlYWRPbmx5KCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgc2hvcnRbXSBwcm90ZWN0ZWRBcnJheSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBwcm90ZWN0ZWRBcnJheU9mZnNldCgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcHJvdGVjdGVkSGFzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2hvcnRCdWZmZXIgcHV0KFNob3J0QnVmZmVyIGJ1ZikgeworICAgICAgICB0aHJvdyBuZXcgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2hvcnRCdWZmZXIgcHV0KHNob3J0IGMpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNob3J0QnVmZmVyIHB1dChpbnQgaW5kZXgsIHNob3J0IGMpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIFNob3J0QnVmZmVyIHB1dChzaG9ydFtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IHNob3J0Q291bnQpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNob3J0QnVmZmVyIHNsaWNlKCkgeworICAgICAgICByZXR1cm4gbmV3IFJlYWRPbmx5U2hvcnRBcnJheUJ1ZmZlcihyZW1haW5pbmcoKSwgYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZFdyaXRlQ2hhckFycmF5QnVmZmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZFdyaXRlQ2hhckFycmF5QnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGYxMjViMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkV3JpdGVDaGFyQXJyYXlCdWZmZXIuamF2YQpAQCAtMCwwICsxLDEyNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworLyoqCisgKiBDaGFyQXJyYXlCdWZmZXIsIFJlYWRXcml0ZUNoYXJBcnJheUJ1ZmZlciBhbmQgUmVhZE9ubHlDaGFyQXJyYXlCdWZmZXIgY29tcG9zZQorICogdGhlIGltcGxlbWVudGF0aW9uIG9mIGFycmF5IGJhc2VkIGNoYXIgYnVmZmVycy4KKyAqIDxwPgorICogUmVhZFdyaXRlQ2hhckFycmF5QnVmZmVyIGV4dGVuZHMgQ2hhckFycmF5QnVmZmVyIHdpdGggYWxsIHRoZSB3cml0ZSBtZXRob2RzLgorICogPC9wPgorICogPHA+CisgKiBUaGlzIGNsYXNzIGlzIG1hcmtlZCBmaW5hbCBmb3IgcnVudGltZSBwZXJmb3JtYW5jZS4KKyAqIDwvcD4KKyAqCisgKi8KK2ZpbmFsIGNsYXNzIFJlYWRXcml0ZUNoYXJBcnJheUJ1ZmZlciBleHRlbmRzIENoYXJBcnJheUJ1ZmZlciB7CisKKyAgICBzdGF0aWMgUmVhZFdyaXRlQ2hhckFycmF5QnVmZmVyIGNvcHkoQ2hhckFycmF5QnVmZmVyIG90aGVyLCBpbnQgbWFya09mT3RoZXIpIHsKKyAgICAgICAgUmVhZFdyaXRlQ2hhckFycmF5QnVmZmVyIGJ1ZiA9CisgICAgICAgICAgICAgICAgbmV3IFJlYWRXcml0ZUNoYXJBcnJheUJ1ZmZlcihvdGhlci5jYXBhY2l0eSgpLCBvdGhlci5iYWNraW5nQXJyYXksIG90aGVyLm9mZnNldCk7CisgICAgICAgIGJ1Zi5saW1pdCA9IG90aGVyLmxpbWl0OworICAgICAgICBidWYucG9zaXRpb24gPSBvdGhlci5wb3NpdGlvbigpOworICAgICAgICBidWYubWFyayA9IG1hcmtPZk90aGVyOworICAgICAgICByZXR1cm4gYnVmOworICAgIH0KKworICAgIFJlYWRXcml0ZUNoYXJBcnJheUJ1ZmZlcihjaGFyW10gYXJyYXkpIHsKKyAgICAgICAgc3VwZXIoYXJyYXkpOworICAgIH0KKworICAgIFJlYWRXcml0ZUNoYXJBcnJheUJ1ZmZlcihpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgc3VwZXIoY2FwYWNpdHkpOworICAgIH0KKworICAgIFJlYWRXcml0ZUNoYXJBcnJheUJ1ZmZlcihpbnQgY2FwYWNpdHksIGNoYXJbXSBiYWNraW5nQXJyYXksIGludCBhcnJheU9mZnNldCkgeworICAgICAgICBzdXBlcihjYXBhY2l0eSwgYmFja2luZ0FycmF5LCBhcnJheU9mZnNldCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENoYXJCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpIHsKKyAgICAgICAgcmV0dXJuIFJlYWRPbmx5Q2hhckFycmF5QnVmZmVyLmNvcHkodGhpcywgbWFyayk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENoYXJCdWZmZXIgY29tcGFjdCgpIHsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShiYWNraW5nQXJyYXksIHBvc2l0aW9uICsgb2Zmc2V0LCBiYWNraW5nQXJyYXksIG9mZnNldCwgcmVtYWluaW5nKCkpOworICAgICAgICBwb3NpdGlvbiA9IGxpbWl0IC0gcG9zaXRpb247CisgICAgICAgIGxpbWl0ID0gY2FwYWNpdHk7CisgICAgICAgIG1hcmsgPSBVTlNFVF9NQVJLOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ2hhckJ1ZmZlciBkdXBsaWNhdGUoKSB7CisgICAgICAgIHJldHVybiBjb3B5KHRoaXMsIG1hcmspOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzUmVhZE9ubHkoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgY2hhcltdIHByb3RlY3RlZEFycmF5KCkgeworICAgICAgICByZXR1cm4gYmFja2luZ0FycmF5OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgcHJvdGVjdGVkQXJyYXlPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBvZmZzZXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcHJvdGVjdGVkSGFzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDaGFyQnVmZmVyIHB1dChjaGFyIGMpIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBiYWNraW5nQXJyYXlbb2Zmc2V0ICsgcG9zaXRpb24rK10gPSBjOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ2hhckJ1ZmZlciBwdXQoaW50IGluZGV4LCBjaGFyIGMpIHsKKyAgICAgICAgY2hlY2tJbmRleChpbmRleCk7CisgICAgICAgIGJhY2tpbmdBcnJheVtvZmZzZXQgKyBpbmRleF0gPSBjOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ2hhckJ1ZmZlciBwdXQoY2hhcltdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGNoYXJDb3VudCkgeworICAgICAgICBpZiAoY2hhckNvdW50ID4gcmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc3JjLCBzcmNPZmZzZXQsIGJhY2tpbmdBcnJheSwgb2Zmc2V0ICsgcG9zaXRpb24sIGNoYXJDb3VudCk7CisgICAgICAgIHBvc2l0aW9uICs9IGNoYXJDb3VudDsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENoYXJCdWZmZXIgc2xpY2UoKSB7CisgICAgICAgIHJldHVybiBuZXcgUmVhZFdyaXRlQ2hhckFycmF5QnVmZmVyKHJlbWFpbmluZygpLCBiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkV3JpdGVEaXJlY3RCeXRlQnVmZmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZFdyaXRlRGlyZWN0Qnl0ZUJ1ZmZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVlZGNlMzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZFdyaXRlRGlyZWN0Qnl0ZUJ1ZmZlci5qYXZhCkBAIC0wLDAgKzEsMjU1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCitpbXBvcnQgbGliY29yZS5pby5TaXplT2Y7CitpbXBvcnQgbGliY29yZS5pby5NZW1vcnk7CisKKy8qKgorICogRGlyZWN0Qnl0ZUJ1ZmZlciwgUmVhZFdyaXRlRGlyZWN0Qnl0ZUJ1ZmZlciBhbmQgUmVhZE9ubHlEaXJlY3RCeXRlQnVmZmVyCisgKiBjb21wb3NlIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBwbGF0Zm9ybSBtZW1vcnkgYmFzZWQgYnl0ZSBidWZmZXJzLgorICogPHA+CisgKiBSZWFkV3JpdGVEaXJlY3RCeXRlQnVmZmVyIGV4dGVuZHMgRGlyZWN0Qnl0ZUJ1ZmZlciB3aXRoIGFsbCB0aGUgd3JpdGUKKyAqIG1ldGhvZHMuCisgKiA8L3A+CisgKiA8cD4KKyAqIFRoaXMgY2xhc3MgaXMgbWFya2VkIGZpbmFsIGZvciBydW50aW1lIHBlcmZvcm1hbmNlLgorICogPC9wPgorICovCitmaW5hbCBjbGFzcyBSZWFkV3JpdGVEaXJlY3RCeXRlQnVmZmVyIGV4dGVuZHMgRGlyZWN0Qnl0ZUJ1ZmZlciB7CisgICAgc3RhdGljIFJlYWRXcml0ZURpcmVjdEJ5dGVCdWZmZXIgY29weShEaXJlY3RCeXRlQnVmZmVyIG90aGVyLCBpbnQgbWFya09mT3RoZXIpIHsKKyAgICAgICAgUmVhZFdyaXRlRGlyZWN0Qnl0ZUJ1ZmZlciBidWYgPQorICAgICAgICAgICAgICAgIG5ldyBSZWFkV3JpdGVEaXJlY3RCeXRlQnVmZmVyKG90aGVyLmJsb2NrLCBvdGhlci5jYXBhY2l0eSgpLCBvdGhlci5vZmZzZXQpOworICAgICAgICBidWYubGltaXQgPSBvdGhlci5saW1pdDsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gb3RoZXIucG9zaXRpb24oKTsKKyAgICAgICAgYnVmLm1hcmsgPSBtYXJrT2ZPdGhlcjsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICAvLyBVc2VkIGJ5IEJ5dGVCdWZmZXIuYWxsb2NhdGVEaXJlY3QuCisgICAgUmVhZFdyaXRlRGlyZWN0Qnl0ZUJ1ZmZlcihpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgc3VwZXIoTWVtb3J5QmxvY2suYWxsb2NhdGUoY2FwYWNpdHkpLCBjYXBhY2l0eSwgMCk7CisgICAgfQorCisgICAgLy8gVXNlZCBieSB0aGUgSk5JIE5ld0RpcmVjdEJ5dGVCdWZmZXIgZnVuY3Rpb24uCisgICAgUmVhZFdyaXRlRGlyZWN0Qnl0ZUJ1ZmZlcihpbnQgYWRkcmVzcywgaW50IGNhcGFjaXR5KSB7CisgICAgICAgIHN1cGVyKE1lbW9yeUJsb2NrLndyYXBGcm9tSm5pKGFkZHJlc3MsIGNhcGFjaXR5KSwgY2FwYWNpdHksIDApOworICAgIH0KKworICAgIFJlYWRXcml0ZURpcmVjdEJ5dGVCdWZmZXIoTWVtb3J5QmxvY2sgYmxvY2ssIGludCBjYXBhY2l0eSwgaW50IG9mZnNldCkgeworICAgICAgICBzdXBlcihibG9jaywgY2FwYWNpdHksIG9mZnNldCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpIHsKKyAgICAgICAgcmV0dXJuIFJlYWRPbmx5RGlyZWN0Qnl0ZUJ1ZmZlci5jb3B5KHRoaXMsIG1hcmspOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIGNvbXBhY3QoKSB7CisgICAgICAgIE1lbW9yeS5tZW1tb3ZlKHRoaXMsIDAsIHRoaXMsIHBvc2l0aW9uLCByZW1haW5pbmcoKSk7CisgICAgICAgIHBvc2l0aW9uID0gbGltaXQgLSBwb3NpdGlvbjsKKyAgICAgICAgbGltaXQgPSBjYXBhY2l0eTsKKyAgICAgICAgbWFyayA9IFVOU0VUX01BUks7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIGR1cGxpY2F0ZSgpIHsKKyAgICAgICAgcmV0dXJuIGNvcHkodGhpcywgbWFyayk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNSZWFkT25seSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dChieXRlIHZhbHVlKSB7CisgICAgICAgIGlmIChwb3NpdGlvbiA9PSBsaW1pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5ibG9jay5wb2tlQnl0ZShvZmZzZXQgKyBwb3NpdGlvbisrLCB2YWx1ZSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dChpbnQgaW5kZXgsIGJ5dGUgdmFsdWUpIHsKKyAgICAgICAgY2hlY2tJbmRleChpbmRleCk7CisgICAgICAgIHRoaXMuYmxvY2sucG9rZUJ5dGUob2Zmc2V0ICsgaW5kZXgsIHZhbHVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0KGJ5dGVbXSBzcmMsIGludCBzcmNPZmZzZXQsIGludCBieXRlQ291bnQpIHsKKyAgICAgICAgY2hlY2tQdXRCb3VuZHMoMSwgc3JjLmxlbmd0aCwgc3JjT2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICB0aGlzLmJsb2NrLnBva2VCeXRlQXJyYXkob2Zmc2V0ICsgcG9zaXRpb24sIHNyYywgc3JjT2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICBwb3NpdGlvbiArPSBieXRlQ291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIGZpbmFsIHZvaWQgcHV0KGNoYXJbXSBzcmMsIGludCBzcmNPZmZzZXQsIGludCBjaGFyQ291bnQpIHsKKyAgICAgICAgaW50IGJ5dGVDb3VudCA9IGNoZWNrUHV0Qm91bmRzKFNpemVPZi5DSEFSLCBzcmMubGVuZ3RoLCBzcmNPZmZzZXQsIGNoYXJDb3VudCk7CisgICAgICAgIHRoaXMuYmxvY2sucG9rZUNoYXJBcnJheShvZmZzZXQgKyBwb3NpdGlvbiwgc3JjLCBzcmNPZmZzZXQsIGNoYXJDb3VudCwgb3JkZXIubmVlZHNTd2FwKTsKKyAgICAgICAgcG9zaXRpb24gKz0gYnl0ZUNvdW50OworICAgIH0KKworICAgIGZpbmFsIHZvaWQgcHV0KGRvdWJsZVtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGRvdWJsZUNvdW50KSB7CisgICAgICAgIGludCBieXRlQ291bnQgPSBjaGVja1B1dEJvdW5kcyhTaXplT2YuRE9VQkxFLCBzcmMubGVuZ3RoLCBzcmNPZmZzZXQsIGRvdWJsZUNvdW50KTsKKyAgICAgICAgdGhpcy5ibG9jay5wb2tlRG91YmxlQXJyYXkob2Zmc2V0ICsgcG9zaXRpb24sIHNyYywgc3JjT2Zmc2V0LCBkb3VibGVDb3VudCwgb3JkZXIubmVlZHNTd2FwKTsKKyAgICAgICAgcG9zaXRpb24gKz0gYnl0ZUNvdW50OworICAgIH0KKworICAgIGZpbmFsIHZvaWQgcHV0KGZsb2F0W10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgZmxvYXRDb3VudCkgeworICAgICAgICBpbnQgYnl0ZUNvdW50ID0gY2hlY2tQdXRCb3VuZHMoU2l6ZU9mLkZMT0FULCBzcmMubGVuZ3RoLCBzcmNPZmZzZXQsIGZsb2F0Q291bnQpOworICAgICAgICB0aGlzLmJsb2NrLnBva2VGbG9hdEFycmF5KG9mZnNldCArIHBvc2l0aW9uLCBzcmMsIHNyY09mZnNldCwgZmxvYXRDb3VudCwgb3JkZXIubmVlZHNTd2FwKTsKKyAgICAgICAgcG9zaXRpb24gKz0gYnl0ZUNvdW50OworICAgIH0KKworICAgIGZpbmFsIHZvaWQgcHV0KGludFtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGludENvdW50KSB7CisgICAgICAgIGludCBieXRlQ291bnQgPSBjaGVja1B1dEJvdW5kcyhTaXplT2YuSU5ULCBzcmMubGVuZ3RoLCBzcmNPZmZzZXQsIGludENvdW50KTsKKyAgICAgICAgdGhpcy5ibG9jay5wb2tlSW50QXJyYXkob2Zmc2V0ICsgcG9zaXRpb24sIHNyYywgc3JjT2Zmc2V0LCBpbnRDb3VudCwgb3JkZXIubmVlZHNTd2FwKTsKKyAgICAgICAgcG9zaXRpb24gKz0gYnl0ZUNvdW50OworICAgIH0KKworICAgIGZpbmFsIHZvaWQgcHV0KGxvbmdbXSBzcmMsIGludCBzcmNPZmZzZXQsIGludCBsb25nQ291bnQpIHsKKyAgICAgICAgaW50IGJ5dGVDb3VudCA9IGNoZWNrUHV0Qm91bmRzKFNpemVPZi5MT05HLCBzcmMubGVuZ3RoLCBzcmNPZmZzZXQsIGxvbmdDb3VudCk7CisgICAgICAgIHRoaXMuYmxvY2sucG9rZUxvbmdBcnJheShvZmZzZXQgKyBwb3NpdGlvbiwgc3JjLCBzcmNPZmZzZXQsIGxvbmdDb3VudCwgb3JkZXIubmVlZHNTd2FwKTsKKyAgICAgICAgcG9zaXRpb24gKz0gYnl0ZUNvdW50OworICAgIH0KKworICAgIGZpbmFsIHZvaWQgcHV0KHNob3J0W10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgc2hvcnRDb3VudCkgeworICAgICAgICBpbnQgYnl0ZUNvdW50ID0gY2hlY2tQdXRCb3VuZHMoU2l6ZU9mLlNIT1JULCBzcmMubGVuZ3RoLCBzcmNPZmZzZXQsIHNob3J0Q291bnQpOworICAgICAgICB0aGlzLmJsb2NrLnBva2VTaG9ydEFycmF5KG9mZnNldCArIHBvc2l0aW9uLCBzcmMsIHNyY09mZnNldCwgc2hvcnRDb3VudCwgb3JkZXIubmVlZHNTd2FwKTsKKyAgICAgICAgcG9zaXRpb24gKz0gYnl0ZUNvdW50OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dENoYXIoY2hhciB2YWx1ZSkgeworICAgICAgICBpbnQgbmV3UG9zaXRpb24gPSBwb3NpdGlvbiArIFNpemVPZi5DSEFSOworICAgICAgICBpZiAobmV3UG9zaXRpb24gPiBsaW1pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5ibG9jay5wb2tlU2hvcnQob2Zmc2V0ICsgcG9zaXRpb24sIChzaG9ydCkgdmFsdWUsIG9yZGVyKTsKKyAgICAgICAgcG9zaXRpb24gPSBuZXdQb3NpdGlvbjsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0Q2hhcihpbnQgaW5kZXgsIGNoYXIgdmFsdWUpIHsKKyAgICAgICAgY2hlY2tJbmRleChpbmRleCwgU2l6ZU9mLkNIQVIpOworICAgICAgICB0aGlzLmJsb2NrLnBva2VTaG9ydChvZmZzZXQgKyBpbmRleCwgKHNob3J0KSB2YWx1ZSwgb3JkZXIpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXREb3VibGUoZG91YmxlIHZhbHVlKSB7CisgICAgICAgIGludCBuZXdQb3NpdGlvbiA9IHBvc2l0aW9uICsgU2l6ZU9mLkRPVUJMRTsKKyAgICAgICAgaWYgKG5ld1Bvc2l0aW9uID4gbGltaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMuYmxvY2sucG9rZUxvbmcob2Zmc2V0ICsgcG9zaXRpb24sIERvdWJsZS5kb3VibGVUb1Jhd0xvbmdCaXRzKHZhbHVlKSwgb3JkZXIpOworICAgICAgICBwb3NpdGlvbiA9IG5ld1Bvc2l0aW9uOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXREb3VibGUoaW50IGluZGV4LCBkb3VibGUgdmFsdWUpIHsKKyAgICAgICAgY2hlY2tJbmRleChpbmRleCwgU2l6ZU9mLkRPVUJMRSk7CisgICAgICAgIHRoaXMuYmxvY2sucG9rZUxvbmcob2Zmc2V0ICsgaW5kZXgsIERvdWJsZS5kb3VibGVUb1Jhd0xvbmdCaXRzKHZhbHVlKSwgb3JkZXIpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRGbG9hdChmbG9hdCB2YWx1ZSkgeworICAgICAgICBpbnQgbmV3UG9zaXRpb24gPSBwb3NpdGlvbiArIFNpemVPZi5GTE9BVDsKKyAgICAgICAgaWYgKG5ld1Bvc2l0aW9uID4gbGltaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMuYmxvY2sucG9rZUludChvZmZzZXQgKyBwb3NpdGlvbiwgRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHModmFsdWUpLCBvcmRlcik7CisgICAgICAgIHBvc2l0aW9uID0gbmV3UG9zaXRpb247CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dEZsb2F0KGludCBpbmRleCwgZmxvYXQgdmFsdWUpIHsKKyAgICAgICAgY2hlY2tJbmRleChpbmRleCwgU2l6ZU9mLkZMT0FUKTsKKyAgICAgICAgdGhpcy5ibG9jay5wb2tlSW50KG9mZnNldCArIGluZGV4LCBGbG9hdC5mbG9hdFRvUmF3SW50Qml0cyh2YWx1ZSksIG9yZGVyKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0SW50KGludCB2YWx1ZSkgeworICAgICAgICBpbnQgbmV3UG9zaXRpb24gPSBwb3NpdGlvbiArIFNpemVPZi5JTlQ7CisgICAgICAgIGlmIChuZXdQb3NpdGlvbiA+IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmJsb2NrLnBva2VJbnQob2Zmc2V0ICsgcG9zaXRpb24sIHZhbHVlLCBvcmRlcik7CisgICAgICAgIHBvc2l0aW9uID0gbmV3UG9zaXRpb247CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dEludChpbnQgaW5kZXgsIGludCB2YWx1ZSkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4LCBTaXplT2YuSU5UKTsKKyAgICAgICAgdGhpcy5ibG9jay5wb2tlSW50KG9mZnNldCArIGluZGV4LCB2YWx1ZSwgb3JkZXIpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRMb25nKGxvbmcgdmFsdWUpIHsKKyAgICAgICAgaW50IG5ld1Bvc2l0aW9uID0gcG9zaXRpb24gKyBTaXplT2YuTE9ORzsKKyAgICAgICAgaWYgKG5ld1Bvc2l0aW9uID4gbGltaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMuYmxvY2sucG9rZUxvbmcob2Zmc2V0ICsgcG9zaXRpb24sIHZhbHVlLCBvcmRlcik7CisgICAgICAgIHBvc2l0aW9uID0gbmV3UG9zaXRpb247CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dExvbmcoaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgsIFNpemVPZi5MT05HKTsKKyAgICAgICAgdGhpcy5ibG9jay5wb2tlTG9uZyhvZmZzZXQgKyBpbmRleCwgdmFsdWUsIG9yZGVyKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0U2hvcnQoc2hvcnQgdmFsdWUpIHsKKyAgICAgICAgaW50IG5ld1Bvc2l0aW9uID0gcG9zaXRpb24gKyBTaXplT2YuU0hPUlQ7CisgICAgICAgIGlmIChuZXdQb3NpdGlvbiA+IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmJsb2NrLnBva2VTaG9ydChvZmZzZXQgKyBwb3NpdGlvbiwgdmFsdWUsIG9yZGVyKTsKKyAgICAgICAgcG9zaXRpb24gPSBuZXdQb3NpdGlvbjsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0U2hvcnQoaW50IGluZGV4LCBzaG9ydCB2YWx1ZSkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4LCBTaXplT2YuU0hPUlQpOworICAgICAgICB0aGlzLmJsb2NrLnBva2VTaG9ydChvZmZzZXQgKyBpbmRleCwgdmFsdWUsIG9yZGVyKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgc2xpY2UoKSB7CisgICAgICAgIHJldHVybiBuZXcgUmVhZFdyaXRlRGlyZWN0Qnl0ZUJ1ZmZlcihibG9jaywgcmVtYWluaW5nKCksIG9mZnNldCArIHBvc2l0aW9uKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkV3JpdGVEb3VibGVBcnJheUJ1ZmZlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1JlYWRXcml0ZURvdWJsZUFycmF5QnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTI5MTNhZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkV3JpdGVEb3VibGVBcnJheUJ1ZmZlci5qYXZhCkBAIC0wLDAgKzEsMTI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCisvKioKKyAqIERvdWJsZUFycmF5QnVmZmVyLCBSZWFkV3JpdGVEb3VibGVBcnJheUJ1ZmZlciBhbmQgUmVhZE9ubHlEb3VibGVBcnJheUJ1ZmZlcgorICogY29tcG9zZSB0aGUgaW1wbGVtZW50YXRpb24gb2YgYXJyYXkgYmFzZWQgZG91YmxlIGJ1ZmZlcnMuCisgKiA8cD4KKyAqIFJlYWRXcml0ZURvdWJsZUFycmF5QnVmZmVyIGV4dGVuZHMgRG91YmxlQXJyYXlCdWZmZXIgd2l0aCBhbGwgdGhlIHdyaXRlCisgKiBtZXRob2RzLgorICogPC9wPgorICogPHA+CisgKiBUaGlzIGNsYXNzIGlzIG1hcmtlZCBmaW5hbCBmb3IgcnVudGltZSBwZXJmb3JtYW5jZS4KKyAqIDwvcD4KKyAqCisgKi8KK2ZpbmFsIGNsYXNzIFJlYWRXcml0ZURvdWJsZUFycmF5QnVmZmVyIGV4dGVuZHMgRG91YmxlQXJyYXlCdWZmZXIgeworCisgICAgc3RhdGljIFJlYWRXcml0ZURvdWJsZUFycmF5QnVmZmVyIGNvcHkoRG91YmxlQXJyYXlCdWZmZXIgb3RoZXIsIGludCBtYXJrT2ZPdGhlcikgeworICAgICAgICBSZWFkV3JpdGVEb3VibGVBcnJheUJ1ZmZlciBidWYgPQorICAgICAgICAgICAgICAgIG5ldyBSZWFkV3JpdGVEb3VibGVBcnJheUJ1ZmZlcihvdGhlci5jYXBhY2l0eSgpLCBvdGhlci5iYWNraW5nQXJyYXksIG90aGVyLm9mZnNldCk7CisgICAgICAgIGJ1Zi5saW1pdCA9IG90aGVyLmxpbWl0OworICAgICAgICBidWYucG9zaXRpb24gPSBvdGhlci5wb3NpdGlvbigpOworICAgICAgICBidWYubWFyayA9IG1hcmtPZk90aGVyOworICAgICAgICByZXR1cm4gYnVmOworICAgIH0KKworICAgIFJlYWRXcml0ZURvdWJsZUFycmF5QnVmZmVyKGRvdWJsZVtdIGFycmF5KSB7CisgICAgICAgIHN1cGVyKGFycmF5KTsKKyAgICB9CisKKyAgICBSZWFkV3JpdGVEb3VibGVBcnJheUJ1ZmZlcihpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgc3VwZXIoY2FwYWNpdHkpOworICAgIH0KKworICAgIFJlYWRXcml0ZURvdWJsZUFycmF5QnVmZmVyKGludCBjYXBhY2l0eSwgZG91YmxlW10gYmFja2luZ0FycmF5LCBpbnQgYXJyYXlPZmZzZXQpIHsKKyAgICAgICAgc3VwZXIoY2FwYWNpdHksIGJhY2tpbmdBcnJheSwgYXJyYXlPZmZzZXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEb3VibGVCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpIHsKKyAgICAgICAgcmV0dXJuIFJlYWRPbmx5RG91YmxlQXJyYXlCdWZmZXIuY29weSh0aGlzLCBtYXJrKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRG91YmxlQnVmZmVyIGNvbXBhY3QoKSB7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYmFja2luZ0FycmF5LCBwb3NpdGlvbiArIG9mZnNldCwgYmFja2luZ0FycmF5LCBvZmZzZXQsIHJlbWFpbmluZygpKTsKKyAgICAgICAgcG9zaXRpb24gPSBsaW1pdCAtIHBvc2l0aW9uOworICAgICAgICBsaW1pdCA9IGNhcGFjaXR5OworICAgICAgICBtYXJrID0gVU5TRVRfTUFSSzsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERvdWJsZUJ1ZmZlciBkdXBsaWNhdGUoKSB7CisgICAgICAgIHJldHVybiBjb3B5KHRoaXMsIG1hcmspOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzUmVhZE9ubHkoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgZG91YmxlW10gcHJvdGVjdGVkQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBiYWNraW5nQXJyYXk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBwcm90ZWN0ZWRBcnJheU9mZnNldCgpIHsKKyAgICAgICAgcmV0dXJuIG9mZnNldDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwcm90ZWN0ZWRIYXNBcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERvdWJsZUJ1ZmZlciBwdXQoZG91YmxlIGMpIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBiYWNraW5nQXJyYXlbb2Zmc2V0ICsgcG9zaXRpb24rK10gPSBjOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRG91YmxlQnVmZmVyIHB1dChpbnQgaW5kZXgsIGRvdWJsZSBjKSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICBiYWNraW5nQXJyYXlbb2Zmc2V0ICsgaW5kZXhdID0gYzsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERvdWJsZUJ1ZmZlciBwdXQoZG91YmxlW10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgZG91YmxlQ291bnQpIHsKKyAgICAgICAgaWYgKGRvdWJsZUNvdW50ID4gcmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc3JjLCBzcmNPZmZzZXQsIGJhY2tpbmdBcnJheSwgb2Zmc2V0ICsgcG9zaXRpb24sIGRvdWJsZUNvdW50KTsKKyAgICAgICAgcG9zaXRpb24gKz0gZG91YmxlQ291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEb3VibGVCdWZmZXIgc2xpY2UoKSB7CisgICAgICAgIHJldHVybiBuZXcgUmVhZFdyaXRlRG91YmxlQXJyYXlCdWZmZXIocmVtYWluaW5nKCksIGJhY2tpbmdBcnJheSwgb2Zmc2V0ICsgcG9zaXRpb24pOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1JlYWRXcml0ZUZsb2F0QXJyYXlCdWZmZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkV3JpdGVGbG9hdEFycmF5QnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGExZTQwNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkV3JpdGVGbG9hdEFycmF5QnVmZmVyLmphdmEKQEAgLTAsMCArMSwxMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW87CisKKy8qKgorICogRmxvYXRBcnJheUJ1ZmZlciwgUmVhZFdyaXRlRmxvYXRBcnJheUJ1ZmZlciBhbmQgUmVhZE9ubHlGbG9hdEFycmF5QnVmZmVyCisgKiBjb21wb3NlIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBhcnJheSBiYXNlZCBmbG9hdCBidWZmZXJzLgorICogPHA+CisgKiBSZWFkV3JpdGVGbG9hdEFycmF5QnVmZmVyIGV4dGVuZHMgRmxvYXRBcnJheUJ1ZmZlciB3aXRoIGFsbCB0aGUgd3JpdGUKKyAqIG1ldGhvZHMuCisgKiA8L3A+CisgKiA8cD4KKyAqIFRoaXMgY2xhc3MgaXMgbWFya2VkIGZpbmFsIGZvciBydW50aW1lIHBlcmZvcm1hbmNlLgorICogPC9wPgorICoKKyAqLworZmluYWwgY2xhc3MgUmVhZFdyaXRlRmxvYXRBcnJheUJ1ZmZlciBleHRlbmRzIEZsb2F0QXJyYXlCdWZmZXIgeworCisgICAgc3RhdGljIFJlYWRXcml0ZUZsb2F0QXJyYXlCdWZmZXIgY29weShGbG9hdEFycmF5QnVmZmVyIG90aGVyLCBpbnQgbWFya09mT3RoZXIpIHsKKyAgICAgICAgUmVhZFdyaXRlRmxvYXRBcnJheUJ1ZmZlciBidWYgPQorICAgICAgICAgICAgICAgIG5ldyBSZWFkV3JpdGVGbG9hdEFycmF5QnVmZmVyKG90aGVyLmNhcGFjaXR5KCksIG90aGVyLmJhY2tpbmdBcnJheSwgb3RoZXIub2Zmc2V0KTsKKyAgICAgICAgYnVmLmxpbWl0ID0gb3RoZXIubGltaXQ7CisgICAgICAgIGJ1Zi5wb3NpdGlvbiA9IG90aGVyLnBvc2l0aW9uKCk7CisgICAgICAgIGJ1Zi5tYXJrID0gbWFya09mT3RoZXI7CisgICAgICAgIHJldHVybiBidWY7CisgICAgfQorCisgICAgUmVhZFdyaXRlRmxvYXRBcnJheUJ1ZmZlcihmbG9hdFtdIGFycmF5KSB7CisgICAgICAgIHN1cGVyKGFycmF5KTsKKyAgICB9CisKKyAgICBSZWFkV3JpdGVGbG9hdEFycmF5QnVmZmVyKGludCBjYXBhY2l0eSkgeworICAgICAgICBzdXBlcihjYXBhY2l0eSk7CisgICAgfQorCisgICAgUmVhZFdyaXRlRmxvYXRBcnJheUJ1ZmZlcihpbnQgY2FwYWNpdHksIGZsb2F0W10gYmFja2luZ0FycmF5LCBpbnQgYXJyYXlPZmZzZXQpIHsKKyAgICAgICAgc3VwZXIoY2FwYWNpdHksIGJhY2tpbmdBcnJheSwgYXJyYXlPZmZzZXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGbG9hdEJ1ZmZlciBhc1JlYWRPbmx5QnVmZmVyKCkgeworICAgICAgICByZXR1cm4gUmVhZE9ubHlGbG9hdEFycmF5QnVmZmVyLmNvcHkodGhpcywgbWFyayk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZsb2F0QnVmZmVyIGNvbXBhY3QoKSB7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYmFja2luZ0FycmF5LCBwb3NpdGlvbiArIG9mZnNldCwgYmFja2luZ0FycmF5LCBvZmZzZXQsIHJlbWFpbmluZygpKTsKKyAgICAgICAgcG9zaXRpb24gPSBsaW1pdCAtIHBvc2l0aW9uOworICAgICAgICBsaW1pdCA9IGNhcGFjaXR5OworICAgICAgICBtYXJrID0gVU5TRVRfTUFSSzsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZsb2F0QnVmZmVyIGR1cGxpY2F0ZSgpIHsKKyAgICAgICAgcmV0dXJuIGNvcHkodGhpcywgbWFyayk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNSZWFkT25seSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBmbG9hdFtdIHByb3RlY3RlZEFycmF5KCkgeworICAgICAgICByZXR1cm4gYmFja2luZ0FycmF5OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgcHJvdGVjdGVkQXJyYXlPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBvZmZzZXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcHJvdGVjdGVkSGFzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGbG9hdEJ1ZmZlciBwdXQoZmxvYXQgYykgeworICAgICAgICBpZiAocG9zaXRpb24gPT0gbGltaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGJhY2tpbmdBcnJheVtvZmZzZXQgKyBwb3NpdGlvbisrXSA9IGM7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGbG9hdEJ1ZmZlciBwdXQoaW50IGluZGV4LCBmbG9hdCBjKSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICBiYWNraW5nQXJyYXlbb2Zmc2V0ICsgaW5kZXhdID0gYzsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZsb2F0QnVmZmVyIHB1dChmbG9hdFtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGZsb2F0Q291bnQpIHsKKyAgICAgICAgaWYgKGZsb2F0Q291bnQgPiByZW1haW5pbmcoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzcmMsIHNyY09mZnNldCwgYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbiwgZmxvYXRDb3VudCk7CisgICAgICAgIHBvc2l0aW9uICs9IGZsb2F0Q291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGbG9hdEJ1ZmZlciBzbGljZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBSZWFkV3JpdGVGbG9hdEFycmF5QnVmZmVyKHJlbWFpbmluZygpLCBiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkV3JpdGVIZWFwQnl0ZUJ1ZmZlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1JlYWRXcml0ZUhlYXBCeXRlQnVmZmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTM1OGExMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkV3JpdGVIZWFwQnl0ZUJ1ZmZlci5qYXZhCkBAIC0wLDAgKzEsMjUxIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCitpbXBvcnQgbGliY29yZS5pby5NZW1vcnk7CitpbXBvcnQgbGliY29yZS5pby5TaXplT2Y7CisKKy8qKgorICogSGVhcEJ5dGVCdWZmZXIsIFJlYWRXcml0ZUhlYXBCeXRlQnVmZmVyIGFuZCBSZWFkT25seUhlYXBCeXRlQnVmZmVyIGNvbXBvc2UKKyAqIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBhcnJheSBiYXNlZCBieXRlIGJ1ZmZlcnMuCisgKiA8cD4KKyAqIFJlYWRXcml0ZUhlYXBCeXRlQnVmZmVyIGV4dGVuZHMgSGVhcEJ5dGVCdWZmZXIgd2l0aCBhbGwgdGhlIHdyaXRlIG1ldGhvZHMuCisgKiA8L3A+CisgKiA8cD4KKyAqIFRoaXMgY2xhc3MgaXMgbWFya2VkIGZpbmFsIGZvciBydW50aW1lIHBlcmZvcm1hbmNlLgorICogPC9wPgorICoKKyAqLworZmluYWwgY2xhc3MgUmVhZFdyaXRlSGVhcEJ5dGVCdWZmZXIgZXh0ZW5kcyBIZWFwQnl0ZUJ1ZmZlciB7CisKKyAgICBzdGF0aWMgUmVhZFdyaXRlSGVhcEJ5dGVCdWZmZXIgY29weShIZWFwQnl0ZUJ1ZmZlciBvdGhlciwgaW50IG1hcmtPZk90aGVyKSB7CisgICAgICAgIFJlYWRXcml0ZUhlYXBCeXRlQnVmZmVyIGJ1ZiA9CisgICAgICAgICAgICAgICAgbmV3IFJlYWRXcml0ZUhlYXBCeXRlQnVmZmVyKG90aGVyLmJhY2tpbmdBcnJheSwgb3RoZXIuY2FwYWNpdHkoKSwgb3RoZXIub2Zmc2V0KTsKKyAgICAgICAgYnVmLmxpbWl0ID0gb3RoZXIubGltaXQ7CisgICAgICAgIGJ1Zi5wb3NpdGlvbiA9IG90aGVyLnBvc2l0aW9uKCk7CisgICAgICAgIGJ1Zi5tYXJrID0gbWFya09mT3RoZXI7CisgICAgICAgIHJldHVybiBidWY7CisgICAgfQorCisgICAgUmVhZFdyaXRlSGVhcEJ5dGVCdWZmZXIoYnl0ZVtdIGJhY2tpbmdBcnJheSkgeworICAgICAgICBzdXBlcihiYWNraW5nQXJyYXkpOworICAgIH0KKworICAgIFJlYWRXcml0ZUhlYXBCeXRlQnVmZmVyKGludCBjYXBhY2l0eSkgeworICAgICAgICBzdXBlcihjYXBhY2l0eSk7CisgICAgfQorCisgICAgUmVhZFdyaXRlSGVhcEJ5dGVCdWZmZXIoYnl0ZVtdIGJhY2tpbmdBcnJheSwgaW50IGNhcGFjaXR5LCBpbnQgYXJyYXlPZmZzZXQpIHsKKyAgICAgICAgc3VwZXIoYmFja2luZ0FycmF5LCBjYXBhY2l0eSwgYXJyYXlPZmZzZXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIGFzUmVhZE9ubHlCdWZmZXIoKSB7CisgICAgICAgIHJldHVybiBSZWFkT25seUhlYXBCeXRlQnVmZmVyLmNvcHkodGhpcywgbWFyayk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgY29tcGFjdCgpIHsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShiYWNraW5nQXJyYXksIHBvc2l0aW9uICsgb2Zmc2V0LCBiYWNraW5nQXJyYXksIG9mZnNldCwgcmVtYWluaW5nKCkpOworICAgICAgICBwb3NpdGlvbiA9IGxpbWl0IC0gcG9zaXRpb247CisgICAgICAgIGxpbWl0ID0gY2FwYWNpdHk7CisgICAgICAgIG1hcmsgPSBVTlNFVF9NQVJLOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBkdXBsaWNhdGUoKSB7CisgICAgICAgIHJldHVybiBjb3B5KHRoaXMsIG1hcmspOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzUmVhZE9ubHkoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIHByb3RlY3RlZEFycmF5KCkgeworICAgICAgICByZXR1cm4gYmFja2luZ0FycmF5OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgcHJvdGVjdGVkQXJyYXlPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBvZmZzZXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcHJvdGVjdGVkSGFzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dChieXRlIGIpIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBiYWNraW5nQXJyYXlbb2Zmc2V0ICsgcG9zaXRpb24rK10gPSBiOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXQoaW50IGluZGV4LCBieXRlIGIpIHsKKyAgICAgICAgY2hlY2tJbmRleChpbmRleCk7CisgICAgICAgIGJhY2tpbmdBcnJheVtvZmZzZXQgKyBpbmRleF0gPSBiOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXQoYnl0ZVtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGJ5dGVDb3VudCkgeworICAgICAgICBjaGVja1B1dEJvdW5kcygxLCBzcmMubGVuZ3RoLCBzcmNPZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc3JjLCBzcmNPZmZzZXQsIGJhY2tpbmdBcnJheSwgb2Zmc2V0ICsgcG9zaXRpb24sIGJ5dGVDb3VudCk7CisgICAgICAgIHBvc2l0aW9uICs9IGJ5dGVDb3VudDsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgZmluYWwgdm9pZCBwdXQoY2hhcltdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGNoYXJDb3VudCkgeworICAgICAgICBpbnQgYnl0ZUNvdW50ID0gY2hlY2tQdXRCb3VuZHMoU2l6ZU9mLkNIQVIsIHNyYy5sZW5ndGgsIHNyY09mZnNldCwgY2hhckNvdW50KTsKKyAgICAgICAgTWVtb3J5LnVuc2FmZUJ1bGtQdXQoYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbiwgYnl0ZUNvdW50LCBzcmMsIHNyY09mZnNldCwgU2l6ZU9mLkNIQVIsIG9yZGVyLm5lZWRzU3dhcCk7CisgICAgICAgIHBvc2l0aW9uICs9IGJ5dGVDb3VudDsKKyAgICB9CisKKyAgICBmaW5hbCB2b2lkIHB1dChkb3VibGVbXSBzcmMsIGludCBzcmNPZmZzZXQsIGludCBkb3VibGVDb3VudCkgeworICAgICAgICBpbnQgYnl0ZUNvdW50ID0gY2hlY2tQdXRCb3VuZHMoU2l6ZU9mLkRPVUJMRSwgc3JjLmxlbmd0aCwgc3JjT2Zmc2V0LCBkb3VibGVDb3VudCk7CisgICAgICAgIE1lbW9yeS51bnNhZmVCdWxrUHV0KGJhY2tpbmdBcnJheSwgb2Zmc2V0ICsgcG9zaXRpb24sIGJ5dGVDb3VudCwgc3JjLCBzcmNPZmZzZXQsIFNpemVPZi5ET1VCTEUsIG9yZGVyLm5lZWRzU3dhcCk7CisgICAgICAgIHBvc2l0aW9uICs9IGJ5dGVDb3VudDsKKyAgICB9CisKKyAgICBmaW5hbCB2b2lkIHB1dChmbG9hdFtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGZsb2F0Q291bnQpIHsKKyAgICAgICAgaW50IGJ5dGVDb3VudCA9IGNoZWNrUHV0Qm91bmRzKFNpemVPZi5GTE9BVCwgc3JjLmxlbmd0aCwgc3JjT2Zmc2V0LCBmbG9hdENvdW50KTsKKyAgICAgICAgTWVtb3J5LnVuc2FmZUJ1bGtQdXQoYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbiwgYnl0ZUNvdW50LCBzcmMsIHNyY09mZnNldCwgU2l6ZU9mLkZMT0FULCBvcmRlci5uZWVkc1N3YXApOworICAgICAgICBwb3NpdGlvbiArPSBieXRlQ291bnQ7CisgICAgfQorCisgICAgZmluYWwgdm9pZCBwdXQoaW50W10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgaW50Q291bnQpIHsKKyAgICAgICAgaW50IGJ5dGVDb3VudCA9IGNoZWNrUHV0Qm91bmRzKFNpemVPZi5JTlQsIHNyYy5sZW5ndGgsIHNyY09mZnNldCwgaW50Q291bnQpOworICAgICAgICBNZW1vcnkudW5zYWZlQnVsa1B1dChiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uLCBieXRlQ291bnQsIHNyYywgc3JjT2Zmc2V0LCBTaXplT2YuSU5ULCBvcmRlci5uZWVkc1N3YXApOworICAgICAgICBwb3NpdGlvbiArPSBieXRlQ291bnQ7CisgICAgfQorCisgICAgZmluYWwgdm9pZCBwdXQobG9uZ1tdIHNyYywgaW50IHNyY09mZnNldCwgaW50IGxvbmdDb3VudCkgeworICAgICAgICBpbnQgYnl0ZUNvdW50ID0gY2hlY2tQdXRCb3VuZHMoU2l6ZU9mLkxPTkcsIHNyYy5sZW5ndGgsIHNyY09mZnNldCwgbG9uZ0NvdW50KTsKKyAgICAgICAgTWVtb3J5LnVuc2FmZUJ1bGtQdXQoYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbiwgYnl0ZUNvdW50LCBzcmMsIHNyY09mZnNldCwgU2l6ZU9mLkxPTkcsIG9yZGVyLm5lZWRzU3dhcCk7CisgICAgICAgIHBvc2l0aW9uICs9IGJ5dGVDb3VudDsKKyAgICB9CisKKyAgICBmaW5hbCB2b2lkIHB1dChzaG9ydFtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IHNob3J0Q291bnQpIHsKKyAgICAgICAgaW50IGJ5dGVDb3VudCA9IGNoZWNrUHV0Qm91bmRzKFNpemVPZi5TSE9SVCwgc3JjLmxlbmd0aCwgc3JjT2Zmc2V0LCBzaG9ydENvdW50KTsKKyAgICAgICAgTWVtb3J5LnVuc2FmZUJ1bGtQdXQoYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbiwgYnl0ZUNvdW50LCBzcmMsIHNyY09mZnNldCwgU2l6ZU9mLlNIT1JULCBvcmRlci5uZWVkc1N3YXApOworICAgICAgICBwb3NpdGlvbiArPSBieXRlQ291bnQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0Q2hhcihpbnQgaW5kZXgsIGNoYXIgdmFsdWUpIHsKKyAgICAgICAgY2hlY2tJbmRleChpbmRleCwgU2l6ZU9mLkNIQVIpOworICAgICAgICBNZW1vcnkucG9rZVNob3J0KGJhY2tpbmdBcnJheSwgb2Zmc2V0ICsgaW5kZXgsIChzaG9ydCkgdmFsdWUsIG9yZGVyKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0Q2hhcihjaGFyIHZhbHVlKSB7CisgICAgICAgIGludCBuZXdQb3NpdGlvbiA9IHBvc2l0aW9uICsgU2l6ZU9mLkNIQVI7CisgICAgICAgIGlmIChuZXdQb3NpdGlvbiA+IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBNZW1vcnkucG9rZVNob3J0KGJhY2tpbmdBcnJheSwgb2Zmc2V0ICsgcG9zaXRpb24sIChzaG9ydCkgdmFsdWUsIG9yZGVyKTsKKyAgICAgICAgcG9zaXRpb24gPSBuZXdQb3NpdGlvbjsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0RG91YmxlKGRvdWJsZSB2YWx1ZSkgeworICAgICAgICByZXR1cm4gcHV0TG9uZyhEb3VibGUuZG91YmxlVG9SYXdMb25nQml0cyh2YWx1ZSkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dERvdWJsZShpbnQgaW5kZXgsIGRvdWJsZSB2YWx1ZSkgeworICAgICAgICByZXR1cm4gcHV0TG9uZyhpbmRleCwgRG91YmxlLmRvdWJsZVRvUmF3TG9uZ0JpdHModmFsdWUpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRGbG9hdChmbG9hdCB2YWx1ZSkgeworICAgICAgICByZXR1cm4gcHV0SW50KEZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKHZhbHVlKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0RmxvYXQoaW50IGluZGV4LCBmbG9hdCB2YWx1ZSkgeworICAgICAgICByZXR1cm4gcHV0SW50KGluZGV4LCBGbG9hdC5mbG9hdFRvUmF3SW50Qml0cyh2YWx1ZSkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHB1dEludChpbnQgdmFsdWUpIHsKKyAgICAgICAgaW50IG5ld1Bvc2l0aW9uID0gcG9zaXRpb24gKyBTaXplT2YuSU5UOworICAgICAgICBpZiAobmV3UG9zaXRpb24gPiBsaW1pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgTWVtb3J5LnBva2VJbnQoYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbiwgdmFsdWUsIG9yZGVyKTsKKyAgICAgICAgcG9zaXRpb24gPSBuZXdQb3NpdGlvbjsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0SW50KGludCBpbmRleCwgaW50IHZhbHVlKSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgsIFNpemVPZi5JTlQpOworICAgICAgICBNZW1vcnkucG9rZUludChiYWNraW5nQXJyYXksIG9mZnNldCArIGluZGV4LCB2YWx1ZSwgb3JkZXIpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRMb25nKGludCBpbmRleCwgbG9uZyB2YWx1ZSkgeworICAgICAgICBjaGVja0luZGV4KGluZGV4LCBTaXplT2YuTE9ORyk7CisgICAgICAgIE1lbW9yeS5wb2tlTG9uZyhiYWNraW5nQXJyYXksIG9mZnNldCArIGluZGV4LCB2YWx1ZSwgb3JkZXIpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRMb25nKGxvbmcgdmFsdWUpIHsKKyAgICAgICAgaW50IG5ld1Bvc2l0aW9uID0gcG9zaXRpb24gKyBTaXplT2YuTE9ORzsKKyAgICAgICAgaWYgKG5ld1Bvc2l0aW9uID4gbGltaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIE1lbW9yeS5wb2tlTG9uZyhiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uLCB2YWx1ZSwgb3JkZXIpOworICAgICAgICBwb3NpdGlvbiA9IG5ld1Bvc2l0aW9uOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBwdXRTaG9ydChpbnQgaW5kZXgsIHNob3J0IHZhbHVlKSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgsIFNpemVPZi5TSE9SVCk7CisgICAgICAgIE1lbW9yeS5wb2tlU2hvcnQoYmFja2luZ0FycmF5LCBvZmZzZXQgKyBpbmRleCwgdmFsdWUsIG9yZGVyKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVCdWZmZXIgcHV0U2hvcnQoc2hvcnQgdmFsdWUpIHsKKyAgICAgICAgaW50IG5ld1Bvc2l0aW9uID0gcG9zaXRpb24gKyBTaXplT2YuU0hPUlQ7CisgICAgICAgIGlmIChuZXdQb3NpdGlvbiA+IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBNZW1vcnkucG9rZVNob3J0KGJhY2tpbmdBcnJheSwgb2Zmc2V0ICsgcG9zaXRpb24sIHZhbHVlLCBvcmRlcik7CisgICAgICAgIHBvc2l0aW9uID0gbmV3UG9zaXRpb247CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCeXRlQnVmZmVyIHNsaWNlKCkgeworICAgICAgICByZXR1cm4gbmV3IFJlYWRXcml0ZUhlYXBCeXRlQnVmZmVyKGJhY2tpbmdBcnJheSwgcmVtYWluaW5nKCksIG9mZnNldCArIHBvc2l0aW9uKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZFdyaXRlSW50QXJyYXlCdWZmZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9SZWFkV3JpdGVJbnRBcnJheUJ1ZmZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhlYzYwYzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZFdyaXRlSW50QXJyYXlCdWZmZXIuamF2YQpAQCAtMCwwICsxLDEyNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworLyoqCisgKiBJbnRBcnJheUJ1ZmZlciwgUmVhZFdyaXRlSW50QXJyYXlCdWZmZXIgYW5kIFJlYWRPbmx5SW50QXJyYXlCdWZmZXIgY29tcG9zZQorICogdGhlIGltcGxlbWVudGF0aW9uIG9mIGFycmF5IGJhc2VkIGludCBidWZmZXJzLgorICogPHA+CisgKiBSZWFkV3JpdGVJbnRBcnJheUJ1ZmZlciBleHRlbmRzIEludEFycmF5QnVmZmVyIHdpdGggYWxsIHRoZSB3cml0ZSBtZXRob2RzLgorICogPC9wPgorICogPHA+CisgKiBUaGlzIGNsYXNzIGlzIG1hcmtlZCBmaW5hbCBmb3IgcnVudGltZSBwZXJmb3JtYW5jZS4KKyAqIDwvcD4KKyAqCisgKi8KK2ZpbmFsIGNsYXNzIFJlYWRXcml0ZUludEFycmF5QnVmZmVyIGV4dGVuZHMgSW50QXJyYXlCdWZmZXIgeworCisgICAgc3RhdGljIFJlYWRXcml0ZUludEFycmF5QnVmZmVyIGNvcHkoSW50QXJyYXlCdWZmZXIgb3RoZXIsIGludCBtYXJrT2ZPdGhlcikgeworICAgICAgICBSZWFkV3JpdGVJbnRBcnJheUJ1ZmZlciBidWYgPQorICAgICAgICAgICAgICAgIG5ldyBSZWFkV3JpdGVJbnRBcnJheUJ1ZmZlcihvdGhlci5jYXBhY2l0eSgpLCBvdGhlci5iYWNraW5nQXJyYXksIG90aGVyLm9mZnNldCk7CisgICAgICAgIGJ1Zi5saW1pdCA9IG90aGVyLmxpbWl0OworICAgICAgICBidWYucG9zaXRpb24gPSBvdGhlci5wb3NpdGlvbigpOworICAgICAgICBidWYubWFyayA9IG1hcmtPZk90aGVyOworICAgICAgICByZXR1cm4gYnVmOworICAgIH0KKworICAgIFJlYWRXcml0ZUludEFycmF5QnVmZmVyKGludFtdIGFycmF5KSB7CisgICAgICAgIHN1cGVyKGFycmF5KTsKKyAgICB9CisKKyAgICBSZWFkV3JpdGVJbnRBcnJheUJ1ZmZlcihpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgc3VwZXIoY2FwYWNpdHkpOworICAgIH0KKworICAgIFJlYWRXcml0ZUludEFycmF5QnVmZmVyKGludCBjYXBhY2l0eSwgaW50W10gYmFja2luZ0FycmF5LCBpbnQgYXJyYXlPZmZzZXQpIHsKKyAgICAgICAgc3VwZXIoY2FwYWNpdHksIGJhY2tpbmdBcnJheSwgYXJyYXlPZmZzZXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnRCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpIHsKKyAgICAgICAgcmV0dXJuIFJlYWRPbmx5SW50QXJyYXlCdWZmZXIuY29weSh0aGlzLCBtYXJrKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW50QnVmZmVyIGNvbXBhY3QoKSB7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYmFja2luZ0FycmF5LCBwb3NpdGlvbiArIG9mZnNldCwgYmFja2luZ0FycmF5LCBvZmZzZXQsIHJlbWFpbmluZygpKTsKKyAgICAgICAgcG9zaXRpb24gPSBsaW1pdCAtIHBvc2l0aW9uOworICAgICAgICBsaW1pdCA9IGNhcGFjaXR5OworICAgICAgICBtYXJrID0gVU5TRVRfTUFSSzsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEludEJ1ZmZlciBkdXBsaWNhdGUoKSB7CisgICAgICAgIHJldHVybiBjb3B5KHRoaXMsIG1hcmspOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzUmVhZE9ubHkoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50W10gcHJvdGVjdGVkQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBiYWNraW5nQXJyYXk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBwcm90ZWN0ZWRBcnJheU9mZnNldCgpIHsKKyAgICAgICAgcmV0dXJuIG9mZnNldDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwcm90ZWN0ZWRIYXNBcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEludEJ1ZmZlciBwdXQoaW50IGMpIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBiYWNraW5nQXJyYXlbb2Zmc2V0ICsgcG9zaXRpb24rK10gPSBjOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW50QnVmZmVyIHB1dChpbnQgaW5kZXgsIGludCBjKSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICBiYWNraW5nQXJyYXlbb2Zmc2V0ICsgaW5kZXhdID0gYzsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEludEJ1ZmZlciBwdXQoaW50W10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgaW50Q291bnQpIHsKKyAgICAgICAgaWYgKGludENvdW50ID4gcmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc3JjLCBzcmNPZmZzZXQsIGJhY2tpbmdBcnJheSwgb2Zmc2V0ICsgcG9zaXRpb24sIGludENvdW50KTsKKyAgICAgICAgcG9zaXRpb24gKz0gaW50Q291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnRCdWZmZXIgc2xpY2UoKSB7CisgICAgICAgIHJldHVybiBuZXcgUmVhZFdyaXRlSW50QXJyYXlCdWZmZXIocmVtYWluaW5nKCksIGJhY2tpbmdBcnJheSwgb2Zmc2V0ICsgcG9zaXRpb24pOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1JlYWRXcml0ZUxvbmdBcnJheUJ1ZmZlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1JlYWRXcml0ZUxvbmdBcnJheUJ1ZmZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQwMmVjNTcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZFdyaXRlTG9uZ0FycmF5QnVmZmVyLmphdmEKQEAgLTAsMCArMSwxMjQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW87CisKKy8qKgorICogTG9uZ0FycmF5QnVmZmVyLCBSZWFkV3JpdGVMb25nQXJyYXlCdWZmZXIgYW5kIFJlYWRPbmx5TG9uZ0FycmF5QnVmZmVyIGNvbXBvc2UKKyAqIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBhcnJheSBiYXNlZCBsb25nIGJ1ZmZlcnMuCisgKiA8cD4KKyAqIFJlYWRXcml0ZUxvbmdBcnJheUJ1ZmZlciBleHRlbmRzIExvbmdBcnJheUJ1ZmZlciB3aXRoIGFsbCB0aGUgd3JpdGUgbWV0aG9kcy4KKyAqIDwvcD4KKyAqIDxwPgorICogVGhpcyBjbGFzcyBpcyBtYXJrZWQgZmluYWwgZm9yIHJ1bnRpbWUgcGVyZm9ybWFuY2UuCisgKiA8L3A+CisgKgorICovCitmaW5hbCBjbGFzcyBSZWFkV3JpdGVMb25nQXJyYXlCdWZmZXIgZXh0ZW5kcyBMb25nQXJyYXlCdWZmZXIgeworCisgICAgc3RhdGljIFJlYWRXcml0ZUxvbmdBcnJheUJ1ZmZlciBjb3B5KExvbmdBcnJheUJ1ZmZlciBvdGhlciwgaW50IG1hcmtPZk90aGVyKSB7CisgICAgICAgIFJlYWRXcml0ZUxvbmdBcnJheUJ1ZmZlciBidWYgPQorICAgICAgICAgICAgICAgIG5ldyBSZWFkV3JpdGVMb25nQXJyYXlCdWZmZXIob3RoZXIuY2FwYWNpdHkoKSwgb3RoZXIuYmFja2luZ0FycmF5LCBvdGhlci5vZmZzZXQpOworICAgICAgICBidWYubGltaXQgPSBvdGhlci5saW1pdDsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gb3RoZXIucG9zaXRpb24oKTsKKyAgICAgICAgYnVmLm1hcmsgPSBtYXJrT2ZPdGhlcjsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICBSZWFkV3JpdGVMb25nQXJyYXlCdWZmZXIobG9uZ1tdIGFycmF5KSB7CisgICAgICAgIHN1cGVyKGFycmF5KTsKKyAgICB9CisKKyAgICBSZWFkV3JpdGVMb25nQXJyYXlCdWZmZXIoaW50IGNhcGFjaXR5KSB7CisgICAgICAgIHN1cGVyKGNhcGFjaXR5KTsKKyAgICB9CisKKyAgICBSZWFkV3JpdGVMb25nQXJyYXlCdWZmZXIoaW50IGNhcGFjaXR5LCBsb25nW10gYmFja2luZ0FycmF5LCBpbnQgYXJyYXlPZmZzZXQpIHsKKyAgICAgICAgc3VwZXIoY2FwYWNpdHksIGJhY2tpbmdBcnJheSwgYXJyYXlPZmZzZXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBMb25nQnVmZmVyIGFzUmVhZE9ubHlCdWZmZXIoKSB7CisgICAgICAgIHJldHVybiBSZWFkT25seUxvbmdBcnJheUJ1ZmZlci5jb3B5KHRoaXMsIG1hcmspOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBMb25nQnVmZmVyIGNvbXBhY3QoKSB7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYmFja2luZ0FycmF5LCBwb3NpdGlvbiArIG9mZnNldCwgYmFja2luZ0FycmF5LCBvZmZzZXQsIHJlbWFpbmluZygpKTsKKyAgICAgICAgcG9zaXRpb24gPSBsaW1pdCAtIHBvc2l0aW9uOworICAgICAgICBsaW1pdCA9IGNhcGFjaXR5OworICAgICAgICBtYXJrID0gVU5TRVRfTUFSSzsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIExvbmdCdWZmZXIgZHVwbGljYXRlKCkgeworICAgICAgICByZXR1cm4gY29weSh0aGlzLCBtYXJrKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1JlYWRPbmx5KCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGxvbmdbXSBwcm90ZWN0ZWRBcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIGJhY2tpbmdBcnJheTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IHByb3RlY3RlZEFycmF5T2Zmc2V0KCkgeworICAgICAgICByZXR1cm4gb2Zmc2V0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBib29sZWFuIHByb3RlY3RlZEhhc0FycmF5KCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTG9uZ0J1ZmZlciBwdXQobG9uZyBjKSB7CisgICAgICAgIGlmIChwb3NpdGlvbiA9PSBsaW1pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgYmFja2luZ0FycmF5W29mZnNldCArIHBvc2l0aW9uKytdID0gYzsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIExvbmdCdWZmZXIgcHV0KGludCBpbmRleCwgbG9uZyBjKSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICBiYWNraW5nQXJyYXlbb2Zmc2V0ICsgaW5kZXhdID0gYzsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIExvbmdCdWZmZXIgcHV0KGxvbmdbXSBzcmMsIGludCBzcmNPZmZzZXQsIGludCBsb25nQ291bnQpIHsKKyAgICAgICAgaWYgKGxvbmdDb3VudCA+IHJlbWFpbmluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHNyYywgc3JjT2Zmc2V0LCBiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uLCBsb25nQ291bnQpOworICAgICAgICBwb3NpdGlvbiArPSBsb25nQ291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBMb25nQnVmZmVyIHNsaWNlKCkgeworICAgICAgICByZXR1cm4gbmV3IFJlYWRXcml0ZUxvbmdBcnJheUJ1ZmZlcihyZW1haW5pbmcoKSwgYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vUmVhZFdyaXRlU2hvcnRBcnJheUJ1ZmZlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1JlYWRXcml0ZVNob3J0QXJyYXlCdWZmZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZjE2ZGFlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1JlYWRXcml0ZVNob3J0QXJyYXlCdWZmZXIuamF2YQpAQCAtMCwwICsxLDEyNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pbzsKKworLyoqCisgKiBTaG9ydEFycmF5QnVmZmVyLCBSZWFkV3JpdGVTaG9ydEFycmF5QnVmZmVyIGFuZCBSZWFkT25seVNob3J0QXJyYXlCdWZmZXIKKyAqIGNvbXBvc2UgdGhlIGltcGxlbWVudGF0aW9uIG9mIGFycmF5IGJhc2VkIHNob3J0IGJ1ZmZlcnMuCisgKiA8cD4KKyAqIFJlYWRXcml0ZVNob3J0QXJyYXlCdWZmZXIgZXh0ZW5kcyBTaG9ydEFycmF5QnVmZmVyIHdpdGggYWxsIHRoZSB3cml0ZQorICogbWV0aG9kcy4KKyAqIDwvcD4KKyAqIDxwPgorICogVGhpcyBjbGFzcyBpcyBtYXJrZWQgZmluYWwgZm9yIHJ1bnRpbWUgcGVyZm9ybWFuY2UuCisgKiA8L3A+CisgKgorICovCitmaW5hbCBjbGFzcyBSZWFkV3JpdGVTaG9ydEFycmF5QnVmZmVyIGV4dGVuZHMgU2hvcnRBcnJheUJ1ZmZlciB7CisKKyAgICBzdGF0aWMgUmVhZFdyaXRlU2hvcnRBcnJheUJ1ZmZlciBjb3B5KFNob3J0QXJyYXlCdWZmZXIgb3RoZXIsIGludCBtYXJrT2ZPdGhlcikgeworICAgICAgICBSZWFkV3JpdGVTaG9ydEFycmF5QnVmZmVyIGJ1ZiA9CisgICAgICAgICAgICAgICAgbmV3IFJlYWRXcml0ZVNob3J0QXJyYXlCdWZmZXIob3RoZXIuY2FwYWNpdHkoKSwgb3RoZXIuYmFja2luZ0FycmF5LCBvdGhlci5vZmZzZXQpOworICAgICAgICBidWYubGltaXQgPSBvdGhlci5saW1pdDsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gb3RoZXIucG9zaXRpb24oKTsKKyAgICAgICAgYnVmLm1hcmsgPSBtYXJrT2ZPdGhlcjsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICBSZWFkV3JpdGVTaG9ydEFycmF5QnVmZmVyKHNob3J0W10gYXJyYXkpIHsKKyAgICAgICAgc3VwZXIoYXJyYXkpOworICAgIH0KKworICAgIFJlYWRXcml0ZVNob3J0QXJyYXlCdWZmZXIoaW50IGNhcGFjaXR5KSB7CisgICAgICAgIHN1cGVyKGNhcGFjaXR5KTsKKyAgICB9CisKKyAgICBSZWFkV3JpdGVTaG9ydEFycmF5QnVmZmVyKGludCBjYXBhY2l0eSwgc2hvcnRbXSBiYWNraW5nQXJyYXksCisgICAgICAgICAgICBpbnQgYXJyYXlPZmZzZXQpIHsKKyAgICAgICAgc3VwZXIoY2FwYWNpdHksIGJhY2tpbmdBcnJheSwgYXJyYXlPZmZzZXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTaG9ydEJ1ZmZlciBhc1JlYWRPbmx5QnVmZmVyKCkgeworICAgICAgICByZXR1cm4gUmVhZE9ubHlTaG9ydEFycmF5QnVmZmVyLmNvcHkodGhpcywgbWFyayk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNob3J0QnVmZmVyIGNvbXBhY3QoKSB7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYmFja2luZ0FycmF5LCBwb3NpdGlvbiArIG9mZnNldCwgYmFja2luZ0FycmF5LCBvZmZzZXQsIHJlbWFpbmluZygpKTsKKyAgICAgICAgcG9zaXRpb24gPSBsaW1pdCAtIHBvc2l0aW9uOworICAgICAgICBsaW1pdCA9IGNhcGFjaXR5OworICAgICAgICBtYXJrID0gVU5TRVRfTUFSSzsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNob3J0QnVmZmVyIGR1cGxpY2F0ZSgpIHsKKyAgICAgICAgcmV0dXJuIGNvcHkodGhpcywgbWFyayk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNSZWFkT25seSgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBzaG9ydFtdIHByb3RlY3RlZEFycmF5KCkgeworICAgICAgICByZXR1cm4gYmFja2luZ0FycmF5OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgcHJvdGVjdGVkQXJyYXlPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBvZmZzZXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcHJvdGVjdGVkSGFzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTaG9ydEJ1ZmZlciBwdXQoc2hvcnQgYykgeworICAgICAgICBpZiAocG9zaXRpb24gPT0gbGltaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGJhY2tpbmdBcnJheVtvZmZzZXQgKyBwb3NpdGlvbisrXSA9IGM7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTaG9ydEJ1ZmZlciBwdXQoaW50IGluZGV4LCBzaG9ydCBjKSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICBiYWNraW5nQXJyYXlbb2Zmc2V0ICsgaW5kZXhdID0gYzsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNob3J0QnVmZmVyIHB1dChzaG9ydFtdIHNyYywgaW50IHNyY09mZnNldCwgaW50IHNob3J0Q291bnQpIHsKKyAgICAgICAgaWYgKHNob3J0Q291bnQgPiByZW1haW5pbmcoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzcmMsIHNyY09mZnNldCwgYmFja2luZ0FycmF5LCBvZmZzZXQgKyBwb3NpdGlvbiwgc2hvcnRDb3VudCk7CisgICAgICAgIHBvc2l0aW9uICs9IHNob3J0Q291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTaG9ydEJ1ZmZlciBzbGljZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBSZWFkV3JpdGVTaG9ydEFycmF5QnVmZmVyKHJlbWFpbmluZygpLCBiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9TZWxlY3Rpb25LZXlJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vU2VsZWN0aW9uS2V5SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5NDc3MGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vU2VsZWN0aW9uS2V5SW1wbC5qYXZhCkBAIC0wLDAgKzEsMTEwIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuQ2FuY2VsbGVkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlbGVjdGFibGVDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlbGVjdGlvbktleTsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5TZWxlY3RvcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5Tb2NrZXRDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLnNwaS5BYnN0cmFjdFNlbGVjdGFibGVDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLnNwaS5BYnN0cmFjdFNlbGVjdGlvbktleTsKKworLyoqCisgKiBEZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIFNlbGVjdGlvbktleQorICovCitmaW5hbCBjbGFzcyBTZWxlY3Rpb25LZXlJbXBsIGV4dGVuZHMgQWJzdHJhY3RTZWxlY3Rpb25LZXkgeworCisgICAgcHJpdmF0ZSBBYnN0cmFjdFNlbGVjdGFibGVDaGFubmVsIGNoYW5uZWw7CisKKyAgICBwcml2YXRlIGludCBpbnRlcmVzdE9wczsKKworICAgIHByaXZhdGUgaW50IHJlYWR5T3BzOworCisgICAgcHJpdmF0ZSBTZWxlY3RvckltcGwgc2VsZWN0b3I7CisKKyAgICBwdWJsaWMgU2VsZWN0aW9uS2V5SW1wbChBYnN0cmFjdFNlbGVjdGFibGVDaGFubmVsIGNoYW5uZWwsIGludCBvcGVyYXRpb25zLAorICAgICAgICAgICAgT2JqZWN0IGF0dGFjaG1lbnQsIFNlbGVjdG9ySW1wbCBzZWxlY3RvcikgeworICAgICAgICB0aGlzLmNoYW5uZWwgPSBjaGFubmVsOworICAgICAgICBpbnRlcmVzdE9wcyA9IG9wZXJhdGlvbnM7CisgICAgICAgIHRoaXMuc2VsZWN0b3IgPSBzZWxlY3RvcjsKKyAgICAgICAgYXR0YWNoKGF0dGFjaG1lbnQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTZWxlY3RhYmxlQ2hhbm5lbCBjaGFubmVsKCkgeworICAgICAgICByZXR1cm4gY2hhbm5lbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGludGVyZXN0T3BzKCkgeworICAgICAgICBjaGVja1ZhbGlkKCk7CisgICAgICAgIHN5bmNocm9uaXplZCAoc2VsZWN0b3Iua2V5c0xvY2spIHsKKyAgICAgICAgICAgIHJldHVybiBpbnRlcmVzdE9wczsKKyAgICAgICAgfQorICAgIH0KKworICAgIGludCBpbnRlcmVzdE9wc05vQ2hlY2soKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoc2VsZWN0b3Iua2V5c0xvY2spIHsKKyAgICAgICAgICAgIHJldHVybiBpbnRlcmVzdE9wczsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTZWxlY3Rpb25LZXkgaW50ZXJlc3RPcHMoaW50IG9wZXJhdGlvbnMpIHsKKyAgICAgICAgY2hlY2tWYWxpZCgpOworICAgICAgICBpZiAoKG9wZXJhdGlvbnMgJiB+KGNoYW5uZWwoKS52YWxpZE9wcygpKSkgIT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHN5bmNocm9uaXplZCAoc2VsZWN0b3Iua2V5c0xvY2spIHsKKyAgICAgICAgICAgIGludGVyZXN0T3BzID0gb3BlcmF0aW9uczsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWR5T3BzKCkgeworICAgICAgICBjaGVja1ZhbGlkKCk7CisgICAgICAgIHJldHVybiByZWFkeU9wczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2VsZWN0b3Igc2VsZWN0b3IoKSB7CisgICAgICAgIHJldHVybiBzZWxlY3RvcjsKKyAgICB9CisKKyAgICAvKgorICAgICAqIHBhY2thZ2UgcHJpdmF0ZSBtZXRob2QgZm9yIHNldHRpbmcgdGhlIHJlYWR5IG9wZXJhdGlvbiBieSBzZWxlY3RvcgorICAgICAqLworICAgIHZvaWQgc2V0UmVhZHlPcHMoaW50IHJlYWR5T3BzKSB7CisgICAgICAgIHRoaXMucmVhZHlPcHMgPSByZWFkeU9wczsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tWYWxpZCgpIHsKKyAgICAgICAgaWYgKCFpc1ZhbGlkKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDYW5jZWxsZWRLZXlFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY2hhbm5lbCBmb3IgdGhpcyBrZXkgaXMgY29ubmVjdGVkLiBJZiB0aGUgY2hhbm5lbAorICAgICAqIGRvZXMgbm90IG5lZWQgY29ubmVjdGluZywgdGhpcyBhbHdheXMgcmV0dXJuIHRydWUuCisgICAgICovCisgICAgYm9vbGVhbiBpc0Nvbm5lY3RlZCgpIHsKKyAgICAgICAgcmV0dXJuICEoY2hhbm5lbCBpbnN0YW5jZW9mIFNvY2tldENoYW5uZWwpIHx8ICgoU29ja2V0Q2hhbm5lbCkgY2hhbm5lbCkuaXNDb25uZWN0ZWQoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vU2VsZWN0b3JJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vU2VsZWN0b3JJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzg2ZTA1ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9TZWxlY3RvckltcGwuamF2YQpAQCAtMCwwICsxLDM5MCBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgamF2YS5uaW87CisKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuQ2xvc2VkU2VsZWN0b3JFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuSWxsZWdhbFNlbGVjdG9yRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlbGVjdGFibGVDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlbGVjdGlvbktleTsKK2ltcG9ydCBzdGF0aWMgamF2YS5uaW8uY2hhbm5lbHMuU2VsZWN0aW9uS2V5Lio7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU2VsZWN0b3I7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU29ja2V0Q2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5zcGkuQWJzdHJhY3RTZWxlY3RhYmxlQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5zcGkuQWJzdHJhY3RTZWxlY3Rpb25LZXk7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuc3BpLkFic3RyYWN0U2VsZWN0b3I7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuc3BpLlNlbGVjdG9yUHJvdmlkZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlVuc2FmZUFycmF5TGlzdDsKK2ltcG9ydCBsaWJjb3JlLmlvLkVycm5vRXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUuaW8uSW9CcmlkZ2U7CitpbXBvcnQgbGliY29yZS5pby5Jb1V0aWxzOworaW1wb3J0IGxpYmNvcmUuaW8uTGliY29yZTsKK2ltcG9ydCBsaWJjb3JlLmlvLlN0cnVjdFBvbGxmZDsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuRW1wdHlBcnJheTsKK2ltcG9ydCBzdGF0aWMgbGliY29yZS5pby5Pc0NvbnN0YW50cy4qOworCisvKgorICogRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiBqYXZhLm5pby5jaGFubmVscy5TZWxlY3RvcgorICovCitmaW5hbCBjbGFzcyBTZWxlY3RvckltcGwgZXh0ZW5kcyBBYnN0cmFjdFNlbGVjdG9yIHsKKworICAgIC8qKgorICAgICAqIFVzZWQgdG8gc3luY2hyb25pemUgd2hlbiBhIGtleSdzIGludGVyZXN0IG9wcyBjaGFuZ2UuCisgICAgICovCisgICAgZmluYWwgT2JqZWN0IGtleXNMb2NrID0gbmV3IE9iamVjdCgpOworCisgICAgcHJpdmF0ZSBmaW5hbCBTZXQ8U2VsZWN0aW9uS2V5SW1wbD4gbXV0YWJsZUtleXMgPSBuZXcgSGFzaFNldDxTZWxlY3Rpb25LZXlJbXBsPigpOworCisgICAgLyoqCisgICAgICogVGhlIHVubW9kaWZpYWJsZSBzZXQgb2Yga2V5cyBhcyBleHBvc2VkIHRvIHRoZSB1c2VyLiBUaGlzIG9iamVjdCBpcyB1c2VkCisgICAgICogZm9yIHN5bmNocm9uaXphdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFNldDxTZWxlY3Rpb25LZXk+IHVubW9kaWZpYWJsZUtleXMgPSBDb2xsZWN0aW9ucworICAgICAgICAgICAgLjxTZWxlY3Rpb25LZXk+dW5tb2RpZmlhYmxlU2V0KG11dGFibGVLZXlzKTsKKworICAgIHByaXZhdGUgZmluYWwgU2V0PFNlbGVjdGlvbktleT4gbXV0YWJsZVNlbGVjdGVkS2V5cyA9IG5ldyBIYXNoU2V0PFNlbGVjdGlvbktleT4oKTsKKworICAgIC8qKgorICAgICAqIFRoZSB1bm1vZGlmaWFibGUgc2V0IG9mIHNlbGVjdGFibGUga2V5cyBhcyBzZWVuIGJ5IHRoZSB1c2VyLiBUaGlzIG9iamVjdAorICAgICAqIGlzIHVzZWQgZm9yIHN5bmNocm9uaXphdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFNldDxTZWxlY3Rpb25LZXk+IHNlbGVjdGVkS2V5cworICAgICAgICAgICAgPSBuZXcgVW5hZGRhYmxlU2V0PFNlbGVjdGlvbktleT4obXV0YWJsZVNlbGVjdGVkS2V5cyk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgd2FrZXVwIHBpcGUuIFRvIHRyaWdnZXIgYSB3YWtldXAsIHdyaXRlIGEgYnl0ZSB0byB3YWtldXBPdXQuIEVhY2gKKyAgICAgKiB0aW1lIHNlbGVjdCByZXR1cm5zLCB3YWtldXBJbiBpcyBkcmFpbmVkLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgRmlsZURlc2NyaXB0b3Igd2FrZXVwSW47CisgICAgcHJpdmF0ZSBmaW5hbCBGaWxlRGVzY3JpcHRvciB3YWtldXBPdXQ7CisKKyAgICBwcml2YXRlIGZpbmFsIFVuc2FmZUFycmF5TGlzdDxTdHJ1Y3RQb2xsZmQ+IHBvbGxGZHMgPSBuZXcgVW5zYWZlQXJyYXlMaXN0PFN0cnVjdFBvbGxmZD4oU3RydWN0UG9sbGZkLmNsYXNzLCA4KTsKKworICAgIHB1YmxpYyBTZWxlY3RvckltcGwoU2VsZWN0b3JQcm92aWRlciBzZWxlY3RvclByb3ZpZGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihzZWxlY3RvclByb3ZpZGVyKTsKKworICAgICAgICAvKgorICAgICAgICAgKiBDcmVhdGUgYSBwaXBlcyB0byB0cmlnZ2VyIHdha2V1cC4gV2UgY2FuJ3QgdXNlIGEgTklPIHBpcGUgYmVjYXVzZSBpdAorICAgICAgICAgKiB3b3VsZCBiZSBjbG9zZWQgaWYgdGhlIHNlbGVjdGluZyB0aHJlYWQgaXMgaW50ZXJydXB0ZWQuIEFsc28KKyAgICAgICAgICogY29uZmlndXJlIHRoZSBwaXBlIHNvIHdlIGNhbiBmdWxseSBkcmFpbiBpdCB3aXRob3V0IGJsb2NraW5nLgorICAgICAgICAgKi8KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yW10gcGlwZUZkcyA9IExpYmNvcmUub3MucGlwZSgpOworICAgICAgICAgICAgd2FrZXVwSW4gPSBwaXBlRmRzWzBdOworICAgICAgICAgICAgd2FrZXVwT3V0ID0gcGlwZUZkc1sxXTsKKyAgICAgICAgICAgIElvVXRpbHMuc2V0QmxvY2tpbmcod2FrZXVwSW4sIGZhbHNlKTsKKyAgICAgICAgICAgIHBvbGxGZHMuYWRkKG5ldyBTdHJ1Y3RQb2xsZmQoKSk7CisgICAgICAgICAgICBzZXRQb2xsRmQoMCwgd2FrZXVwSW4sIFBPTExJTiwgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyBlcnJub0V4Y2VwdGlvbi5yZXRocm93QXNJT0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGltcGxDbG9zZVNlbGVjdG9yKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd2FrZXVwKCk7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgc3luY2hyb25pemVkICh1bm1vZGlmaWFibGVLZXlzKSB7CisgICAgICAgICAgICAgICAgc3luY2hyb25pemVkIChzZWxlY3RlZEtleXMpIHsKKyAgICAgICAgICAgICAgICAgICAgSW9VdGlscy5jbG9zZSh3YWtldXBJbik7CisgICAgICAgICAgICAgICAgICAgIElvVXRpbHMuY2xvc2Uod2FrZXVwT3V0KTsKKyAgICAgICAgICAgICAgICAgICAgZG9DYW5jZWwoKTsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChTZWxlY3Rpb25LZXkgc2sgOiBtdXRhYmxlS2V5cykgeworICAgICAgICAgICAgICAgICAgICAgICAgZGVyZWdpc3RlcigoQWJzdHJhY3RTZWxlY3Rpb25LZXkpIHNrKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgU2VsZWN0aW9uS2V5IHJlZ2lzdGVyKEFic3RyYWN0U2VsZWN0YWJsZUNoYW5uZWwgY2hhbm5lbCwKKyAgICAgICAgICAgIGludCBvcGVyYXRpb25zLCBPYmplY3QgYXR0YWNobWVudCkgeworICAgICAgICBpZiAoIXByb3ZpZGVyKCkuZXF1YWxzKGNoYW5uZWwucHJvdmlkZXIoKSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU2VsZWN0b3JFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAodW5tb2RpZmlhYmxlS2V5cykgeworICAgICAgICAgICAgICAgIFNlbGVjdGlvbktleUltcGwgc2VsZWN0aW9uS2V5ID0gbmV3IFNlbGVjdGlvbktleUltcGwoY2hhbm5lbCwgb3BlcmF0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgIGF0dGFjaG1lbnQsIHRoaXMpOworICAgICAgICAgICAgICAgIG11dGFibGVLZXlzLmFkZChzZWxlY3Rpb25LZXkpOworICAgICAgICAgICAgICAgIGVuc3VyZVBvbGxGZHNDYXBhY2l0eSgpOworICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3Rpb25LZXk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHN5bmNocm9uaXplZCBTZXQ8U2VsZWN0aW9uS2V5PiBrZXlzKCkgeworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICByZXR1cm4gdW5tb2RpZmlhYmxlS2V5czsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tDbG9zZWQoKSB7CisgICAgICAgIGlmICghaXNPcGVuKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDbG9zZWRTZWxlY3RvckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgc2VsZWN0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQmxvY2tzIHVudGlsIHNvbWUgZmQgaXMgcmVhZHkuCisgICAgICAgIHJldHVybiBzZWxlY3RJbnRlcm5hbCgtMSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgc2VsZWN0KGxvbmcgdGltZW91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRpbWVvdXQgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgLy8gT3VyIHRpbWVvdXQgaXMgaW50ZXJwcmV0ZWQgZGlmZmVyZW50bHkgdG8gVW5peCdzIC0tLSAwIG1lYW5zIGJsb2NrLiBTZWUgc2VsZWN0Tm93LgorICAgICAgICByZXR1cm4gc2VsZWN0SW50ZXJuYWwoKHRpbWVvdXQgPT0gMCkgPyAtMSA6IHRpbWVvdXQpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHNlbGVjdE5vdygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzZWxlY3RJbnRlcm5hbCgwKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBzZWxlY3RJbnRlcm5hbChsb25nIHRpbWVvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrQ2xvc2VkKCk7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgc3luY2hyb25pemVkICh1bm1vZGlmaWFibGVLZXlzKSB7CisgICAgICAgICAgICAgICAgc3luY2hyb25pemVkIChzZWxlY3RlZEtleXMpIHsKKyAgICAgICAgICAgICAgICAgICAgZG9DYW5jZWwoKTsKKyAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpc0Jsb2NrID0gKHRpbWVvdXQgIT0gMCk7CisgICAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoa2V5c0xvY2spIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHByZXBhcmVQb2xsRmRzKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaW50IHJjOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQmxvY2spIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWdpbigpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByYyA9IExpYmNvcmUub3MucG9sbChwb2xsRmRzLmFycmF5KCksIChpbnQpIHRpbWVvdXQpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnJub0V4Y2VwdGlvbi5yZXRocm93QXNJT0V4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQmxvY2spIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGludCByZWFkeUNvdW50ID0gKHJjID4gMCkgPyBwcm9jZXNzUG9sbEZkcygpIDogMDsKKyAgICAgICAgICAgICAgICAgICAgcmVhZHlDb3VudCAtPSBkb0NhbmNlbCgpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVhZHlDb3VudDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc2V0UG9sbEZkKGludCBpLCBGaWxlRGVzY3JpcHRvciBmZCwgaW50IGV2ZW50cywgT2JqZWN0IG9iamVjdCkgeworICAgICAgICBTdHJ1Y3RQb2xsZmQgcG9sbEZkID0gcG9sbEZkcy5nZXQoaSk7CisgICAgICAgIHBvbGxGZC5mZCA9IGZkOworICAgICAgICBwb2xsRmQuZXZlbnRzID0gKHNob3J0KSBldmVudHM7CisgICAgICAgIHBvbGxGZC51c2VyRGF0YSA9IG9iamVjdDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcHJlcGFyZVBvbGxGZHMoKSB7CisgICAgICAgIGludCBpID0gMTsgLy8gT3VyIHdha2V1cCBwaXBlIGNvbWVzIGJlZm9yZSBhbGwgdGhlIHVzZXIncyBmZHMuCisgICAgICAgIGZvciAoU2VsZWN0aW9uS2V5SW1wbCBrZXkgOiBtdXRhYmxlS2V5cykgeworICAgICAgICAgICAgaW50IGludGVyZXN0T3BzID0ga2V5LmludGVyZXN0T3BzTm9DaGVjaygpOworICAgICAgICAgICAgc2hvcnQgZXZlbnRNYXNrID0gMDsKKyAgICAgICAgICAgIGlmICgoKE9QX0FDQ0VQVCB8IE9QX1JFQUQpICYgaW50ZXJlc3RPcHMpICE9IDApIHsKKyAgICAgICAgICAgICAgICBldmVudE1hc2sgfD0gUE9MTElOOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCgoT1BfQ09OTkVDVCB8IE9QX1dSSVRFKSAmIGludGVyZXN0T3BzKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgZXZlbnRNYXNrIHw9IFBPTExPVVQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZXZlbnRNYXNrICE9IDApIHsKKyAgICAgICAgICAgICAgICBzZXRQb2xsRmQoaSsrLCAoKEZpbGVEZXNjcmlwdG9yQ2hhbm5lbCkga2V5LmNoYW5uZWwoKSkuZ2V0RkQoKSwgZXZlbnRNYXNrLCBrZXkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBvbGxGZHNDYXBhY2l0eSgpIHsKKyAgICAgICAgLy8gV2UgbmVlZCBvbmUgc2xvdCBmb3IgZWFjaCBlbGVtZW50IG9mIG11dGFibGVLZXlzLCBwbHVzIG9uZSBmb3IgdGhlIHdha2V1cCBwaXBlLgorICAgICAgICB3aGlsZSAocG9sbEZkcy5zaXplKCkgPCBtdXRhYmxlS2V5cy5zaXplKCkgKyAxKSB7CisgICAgICAgICAgICBwb2xsRmRzLmFkZChuZXcgU3RydWN0UG9sbGZkKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUga2V5IHJlYWR5IG9wcyBhbmQgc2VsZWN0ZWQga2V5IHNldC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBwcm9jZXNzUG9sbEZkcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwb2xsRmRzLmdldCgwKS5yZXZlbnRzID09IFBPTExJTikgeworICAgICAgICAgICAgLy8gUmVhZCBieXRlcyBmcm9tIHRoZSB3YWtldXAgcGlwZSB1bnRpbCB0aGUgcGlwZSBpcyBlbXB0eS4KKyAgICAgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVs4XTsKKyAgICAgICAgICAgIHdoaWxlIChJb0JyaWRnZS5yZWFkKHdha2V1cEluLCBidWZmZXIsIDAsIDEpID4gMCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaW50IHJlYWR5S2V5Q291bnQgPSAwOworICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IHBvbGxGZHMuc2l6ZSgpOyArK2kpIHsKKyAgICAgICAgICAgIFN0cnVjdFBvbGxmZCBwb2xsRmQgPSBwb2xsRmRzLmdldChpKTsKKyAgICAgICAgICAgIGlmIChwb2xsRmQucmV2ZW50cyA9PSAwKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocG9sbEZkLmZkID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU2VsZWN0aW9uS2V5SW1wbCBrZXkgPSAoU2VsZWN0aW9uS2V5SW1wbCkgcG9sbEZkLnVzZXJEYXRhOworCisgICAgICAgICAgICBwb2xsRmQuZmQgPSBudWxsOworICAgICAgICAgICAgcG9sbEZkLnVzZXJEYXRhID0gbnVsbDsKKworICAgICAgICAgICAgaW50IG9wcyA9IGtleS5pbnRlcmVzdE9wc05vQ2hlY2soKTsKKyAgICAgICAgICAgIGludCBzZWxlY3RlZE9wID0gMDsKKyAgICAgICAgICAgIGlmICgocG9sbEZkLnJldmVudHMgJiBQT0xMSU4pICE9IDApIHsKKyAgICAgICAgICAgICAgICBzZWxlY3RlZE9wID0gb3BzICYgKE9QX0FDQ0VQVCB8IE9QX1JFQUQpOworICAgICAgICAgICAgfSBlbHNlIGlmICgocG9sbEZkLnJldmVudHMgJiBQT0xMT1VUKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgaWYgKGtleS5pc0Nvbm5lY3RlZCgpKSB7CisgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkT3AgPSBvcHMgJiBPUF9XUklURTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZE9wID0gb3BzICYgT1BfQ09OTkVDVDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChzZWxlY3RlZE9wICE9IDApIHsKKyAgICAgICAgICAgICAgICBib29sZWFuIHdhc1NlbGVjdGVkID0gbXV0YWJsZVNlbGVjdGVkS2V5cy5jb250YWlucyhrZXkpOworICAgICAgICAgICAgICAgIGlmICh3YXNTZWxlY3RlZCAmJiBrZXkucmVhZHlPcHMoKSAhPSBzZWxlY3RlZE9wKSB7CisgICAgICAgICAgICAgICAgICAgIGtleS5zZXRSZWFkeU9wcyhrZXkucmVhZHlPcHMoKSB8IHNlbGVjdGVkT3ApOworICAgICAgICAgICAgICAgICAgICArK3JlYWR5S2V5Q291bnQ7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghd2FzU2VsZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAga2V5LnNldFJlYWR5T3BzKHNlbGVjdGVkT3ApOworICAgICAgICAgICAgICAgICAgICBtdXRhYmxlU2VsZWN0ZWRLZXlzLmFkZChrZXkpOworICAgICAgICAgICAgICAgICAgICArK3JlYWR5S2V5Q291bnQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHJlYWR5S2V5Q291bnQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBzeW5jaHJvbml6ZWQgU2V0PFNlbGVjdGlvbktleT4gc2VsZWN0ZWRLZXlzKCkgeworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICByZXR1cm4gc2VsZWN0ZWRLZXlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgY2FuY2VsbGVkIGtleXMgZnJvbSB0aGUga2V5IHNldCBhbmQgc2VsZWN0ZWQga2V5IHNldCwgYW5kCisgICAgICogZGVyZWdpc3RlcnMgdGhlIGNvcnJlc3BvbmRpbmcgY2hhbm5lbHMuIFJldHVybnMgdGhlIG51bWJlciBvZiBrZXlzCisgICAgICogcmVtb3ZlZCBmcm9tIHRoZSBzZWxlY3RlZCBrZXkgc2V0LgorICAgICAqLworICAgIHByaXZhdGUgaW50IGRvQ2FuY2VsKCkgeworICAgICAgICBpbnQgZGVzZWxlY3RlZCA9IDA7CisKKyAgICAgICAgU2V0PFNlbGVjdGlvbktleT4gY2FuY2VsbGVkS2V5cyA9IGNhbmNlbGxlZEtleXMoKTsKKyAgICAgICAgc3luY2hyb25pemVkIChjYW5jZWxsZWRLZXlzKSB7CisgICAgICAgICAgICBpZiAoY2FuY2VsbGVkS2V5cy5zaXplKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgZm9yIChTZWxlY3Rpb25LZXkgY3VycmVudEtleSA6IGNhbmNlbGxlZEtleXMpIHsKKyAgICAgICAgICAgICAgICAgICAgbXV0YWJsZUtleXMucmVtb3ZlKGN1cnJlbnRLZXkpOworICAgICAgICAgICAgICAgICAgICBkZXJlZ2lzdGVyKChBYnN0cmFjdFNlbGVjdGlvbktleSkgY3VycmVudEtleSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChtdXRhYmxlU2VsZWN0ZWRLZXlzLnJlbW92ZShjdXJyZW50S2V5KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZGVzZWxlY3RlZCsrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNhbmNlbGxlZEtleXMuY2xlYXIoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBkZXNlbGVjdGVkOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU2VsZWN0b3Igd2FrZXVwKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgTGliY29yZS5vcy53cml0ZSh3YWtldXBPdXQsIG5ldyBieXRlW10geyAxIH0sIDAsIDEpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgVW5hZGRhYmxlU2V0PEU+IGltcGxlbWVudHMgU2V0PEU+IHsKKworICAgICAgICBwcml2YXRlIGZpbmFsIFNldDxFPiBzZXQ7CisKKyAgICAgICAgVW5hZGRhYmxlU2V0KFNldDxFPiBzZXQpIHsKKyAgICAgICAgICAgIHRoaXMuc2V0ID0gc2V0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gc2V0LmVxdWFscyhvYmplY3QpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICByZXR1cm4gc2V0Lmhhc2hDb2RlKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBhZGQoRSBvYmplY3QpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gYWRkQWxsKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGMpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICBzZXQuY2xlYXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIHJldHVybiBzZXQuY29udGFpbnMob2JqZWN0KTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQWxsKENvbGxlY3Rpb248Pz4gYykgeworICAgICAgICAgICAgcmV0dXJuIHNldC5jb250YWluc0FsbChjKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICByZXR1cm4gc2V0LmlzRW1wdHkoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBJdGVyYXRvcjxFPiBpdGVyYXRvcigpIHsKKyAgICAgICAgICAgIHJldHVybiBzZXQuaXRlcmF0b3IoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gc2V0LnJlbW92ZShvYmplY3QpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlQWxsKENvbGxlY3Rpb248Pz4gYykgeworICAgICAgICAgICAgcmV0dXJuIHNldC5yZW1vdmVBbGwoYyk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiByZXRhaW5BbGwoQ29sbGVjdGlvbjw/PiBjKSB7CisgICAgICAgICAgICByZXR1cm4gc2V0LnJldGFpbkFsbChjKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBzZXQuc2l6ZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSB7CisgICAgICAgICAgICByZXR1cm4gc2V0LnRvQXJyYXkoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyA8VD4gVFtdIHRvQXJyYXkoVFtdIGEpIHsKKyAgICAgICAgICAgIHJldHVybiBzZXQudG9BcnJheShhKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9TZWxlY3RvclByb3ZpZGVySW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1NlbGVjdG9yUHJvdmlkZXJJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDMwMDNmZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9TZWxlY3RvclByb3ZpZGVySW1wbC5qYXZhCkBAIC0wLDAgKzEsNTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkRhdGFncmFtQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5QaXBlOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlcnZlclNvY2tldENoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU29ja2V0Q2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5zcGkuQWJzdHJhY3RTZWxlY3RvcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5zcGkuU2VsZWN0b3JQcm92aWRlcjsKKworLyoqCisgKiBAaGlkZSBmb3IgamF2YS5uaW8uY2hhbm5lbHMuc3BpLlNlbGVjdG9yUHJvdmlkZXIgb25seS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFNlbGVjdG9yUHJvdmlkZXJJbXBsIGV4dGVuZHMgU2VsZWN0b3JQcm92aWRlciB7CisgICAgcHVibGljIERhdGFncmFtQ2hhbm5lbCBvcGVuRGF0YWdyYW1DaGFubmVsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBEYXRhZ3JhbUNoYW5uZWxJbXBsKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBQaXBlIG9wZW5QaXBlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBQaXBlSW1wbCgpOworICAgIH0KKworICAgIHB1YmxpYyBBYnN0cmFjdFNlbGVjdG9yIG9wZW5TZWxlY3RvcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgU2VsZWN0b3JJbXBsKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBTZXJ2ZXJTb2NrZXRDaGFubmVsIG9wZW5TZXJ2ZXJTb2NrZXRDaGFubmVsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTZXJ2ZXJTb2NrZXRDaGFubmVsSW1wbCh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU29ja2V0Q2hhbm5lbCBvcGVuU29ja2V0Q2hhbm5lbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgU29ja2V0Q2hhbm5lbEltcGwodGhpcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1NlcnZlclNvY2tldENoYW5uZWxJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vU2VydmVyU29ja2V0Q2hhbm5lbEltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MzMxMTU4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1NlcnZlclNvY2tldENoYW5uZWxJbXBsLmphdmEKQEAgLTAsMCArMSwxNzIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW87CisKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuUGxhaW5TZXJ2ZXJTb2NrZXRJbXBsOworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRJbXBsOworaW1wb3J0IGphdmEubmV0LlNvY2tldFRpbWVvdXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5JbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLk5vdFlldEJvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlcnZlclNvY2tldENoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU29ja2V0Q2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5zcGkuU2VsZWN0b3JQcm92aWRlcjsKK2ltcG9ydCBsaWJjb3JlLmlvLklvVXRpbHM7CisKKy8qKgorICogVGhlIGRlZmF1bHQgU2VydmVyU29ja2V0Q2hhbm5lbC4KKyAqLworZmluYWwgY2xhc3MgU2VydmVyU29ja2V0Q2hhbm5lbEltcGwgZXh0ZW5kcyBTZXJ2ZXJTb2NrZXRDaGFubmVsIGltcGxlbWVudHMgRmlsZURlc2NyaXB0b3JDaGFubmVsIHsKKworICAgIHByaXZhdGUgZmluYWwgU2VydmVyU29ja2V0QWRhcHRlciBzb2NrZXQ7CisgICAgcHJpdmF0ZSBmaW5hbCBTb2NrZXRJbXBsIGltcGw7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNCb3VuZCA9IGZhbHNlOworCisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgYWNjZXB0TG9jayA9IG5ldyBPYmplY3QoKTsKKworICAgIHB1YmxpYyBTZXJ2ZXJTb2NrZXRDaGFubmVsSW1wbChTZWxlY3RvclByb3ZpZGVyIHNwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihzcCk7CisgICAgICAgIHRoaXMuc29ja2V0ID0gbmV3IFNlcnZlclNvY2tldEFkYXB0ZXIodGhpcyk7CisgICAgICAgIHRoaXMuaW1wbCA9IHNvY2tldC5nZXRJbXBsJCgpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU2VydmVyU29ja2V0IHNvY2tldCgpIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFNvY2tldENoYW5uZWwgYWNjZXB0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc09wZW4oKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENsb3NlZENoYW5uZWxFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIWlzQm91bmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb3RZZXRCb3VuZEV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ3JlYXRlIGFuIGVtcHR5IHNvY2tldCBjaGFubmVsLiBUaGlzIHdpbGwgYmUgcG9wdWxhdGVkIGJ5IFNlcnZlclNvY2tldEFkYXB0ZXIuYWNjZXB0LgorICAgICAgICBTb2NrZXRDaGFubmVsSW1wbCByZXN1bHQgPSBuZXcgU29ja2V0Q2hhbm5lbEltcGwocHJvdmlkZXIoKSwgZmFsc2UpOworICAgICAgICBib29sZWFuIGNvbm5lY3RlZCA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmVnaW4oKTsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoYWNjZXB0TG9jaykgeworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoYmxvY2tpbmdMb2NrKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb2NrZXQuaW1wbEFjY2VwdChyZXN1bHQpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlbGVjdCBzdWNjZXNzZnVsbHksIGJyZWFrIG91dCBpbW1lZGlhdGVseS4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNvY2tldFRpbWVvdXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnRpbnVlIHRvIGFjY2VwdCBpZiB0aGUgY2hhbm5lbCBpcyBpbiBibG9ja2luZyBtb2RlLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IGRvZXMgdGhpcyBtYWtlIHNlbnNlPyB3aHkgZG9lcyBibG9ja2luZyBpbXBseSBubyB0aW1lb3V0cz8KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoaXNCbG9ja2luZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBlbmQocmVzdWx0LnNvY2tldCgpLmlzQ29ubmVjdGVkKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQuc29ja2V0KCkuaXNDb25uZWN0ZWQoKSA/IHJlc3VsdCA6IG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGltcGxDb25maWd1cmVCbG9ja2luZyhib29sZWFuIGJsb2NraW5nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGJsb2NraW5nTG9jaygpKSB7CisgICAgICAgICAgICBJb1V0aWxzLnNldEJsb2NraW5nKGltcGwuZ2V0RkQkKCksIGJsb2NraW5nKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN5bmNocm9uaXplZCBwcm90ZWN0ZWQgdm9pZCBpbXBsQ2xvc2VTZWxlY3RhYmxlQ2hhbm5lbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghc29ja2V0LmlzQ2xvc2VkKCkpIHsKKyAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIEZpbGVEZXNjcmlwdG9yIGdldEZEKCkgeworICAgICAgICByZXR1cm4gaW1wbC5nZXRGRCQoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTZXJ2ZXJTb2NrZXRBZGFwdGVyIGV4dGVuZHMgU2VydmVyU29ja2V0IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTZXJ2ZXJTb2NrZXRDaGFubmVsSW1wbCBjaGFubmVsSW1wbDsKKworICAgICAgICBTZXJ2ZXJTb2NrZXRBZGFwdGVyKFNlcnZlclNvY2tldENoYW5uZWxJbXBsIGFDaGFubmVsSW1wbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRoaXMuY2hhbm5lbEltcGwgPSBhQ2hhbm5lbEltcGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgYmluZChTb2NrZXRBZGRyZXNzIGxvY2FsQWRkcmVzcywgaW50IGJhY2tsb2cpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlci5iaW5kKGxvY2FsQWRkcmVzcywgYmFja2xvZyk7CisgICAgICAgICAgICBjaGFubmVsSW1wbC5pc0JvdW5kID0gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU29ja2V0IGFjY2VwdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoIWNoYW5uZWxJbXBsLmlzQm91bmQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU29ja2V0Q2hhbm5lbCBzYyA9IGNoYW5uZWxJbXBsLmFjY2VwdCgpOworICAgICAgICAgICAgaWYgKHNjID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHNjLnNvY2tldCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFNvY2tldCBpbXBsQWNjZXB0KFNvY2tldENoYW5uZWxJbXBsIGNsaWVudFNvY2tldENoYW5uZWwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBTb2NrZXQgY2xpZW50U29ja2V0ID0gY2xpZW50U29ja2V0Q2hhbm5lbC5zb2NrZXQoKTsKKyAgICAgICAgICAgIGJvb2xlYW4gY29ubmVjdE9LID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgICAgICAgICBzdXBlci5pbXBsQWNjZXB0KGNsaWVudFNvY2tldCk7CisgICAgICAgICAgICAgICAgICAgIGNsaWVudFNvY2tldENoYW5uZWwuc2V0Q29ubmVjdGVkKCk7CisgICAgICAgICAgICAgICAgICAgIGNsaWVudFNvY2tldENoYW5uZWwuc2V0Qm91bmQodHJ1ZSk7CisgICAgICAgICAgICAgICAgICAgIGNsaWVudFNvY2tldENoYW5uZWwuZmluaXNoQWNjZXB0KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvbm5lY3RPSyA9IHRydWU7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGlmICghY29ubmVjdE9LKSB7CisgICAgICAgICAgICAgICAgICAgIGNsaWVudFNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBjbGllbnRTb2NrZXQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFNlcnZlclNvY2tldENoYW5uZWwgZ2V0Q2hhbm5lbCgpIHsKKyAgICAgICAgICAgIHJldHVybiBjaGFubmVsSW1wbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc0JvdW5kKCkgeworICAgICAgICAgICAgcmV0dXJuIGNoYW5uZWxJbXBsLmlzQm91bmQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgYmluZChTb2NrZXRBZGRyZXNzIGxvY2FsQWRkcmVzcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyLmJpbmQobG9jYWxBZGRyZXNzKTsKKyAgICAgICAgICAgIGNoYW5uZWxJbXBsLmlzQm91bmQgPSB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoY2hhbm5lbEltcGwpIHsKKyAgICAgICAgICAgICAgICBpZiAoY2hhbm5lbEltcGwuaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEltcGwuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBzdXBlci5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9TaG9ydEFycmF5QnVmZmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vU2hvcnRBcnJheUJ1ZmZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJmNmY3NTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vU2hvcnRBcnJheUJ1ZmZlci5qYXZhCkBAIC0wLDAgKzEsODYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW87CisKKy8qKgorICogU2hvcnRBcnJheUJ1ZmZlciwgUmVhZFdyaXRlU2hvcnRBcnJheUJ1ZmZlciBhbmQgUmVhZE9ubHlTaG9ydEFycmF5QnVmZmVyCisgKiBjb21wb3NlIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBhcnJheSBiYXNlZCBzaG9ydCBidWZmZXJzLgorICogPHA+CisgKiBTaG9ydEFycmF5QnVmZmVyIGltcGxlbWVudHMgYWxsIHRoZSBzaGFyZWQgcmVhZG9ubHkgbWV0aG9kcyBhbmQgaXMgZXh0ZW5kZWQKKyAqIGJ5IHRoZSBvdGhlciB0d28gY2xhc3Nlcy4KKyAqIDwvcD4KKyAqIDxwPgorICogQWxsIG1ldGhvZHMgYXJlIG1hcmtlZCBmaW5hbCBmb3IgcnVudGltZSBwZXJmb3JtYW5jZS4KKyAqIDwvcD4KKyAqCisgKi8KK2Fic3RyYWN0IGNsYXNzIFNob3J0QXJyYXlCdWZmZXIgZXh0ZW5kcyBTaG9ydEJ1ZmZlciB7CisKKyAgICBwcm90ZWN0ZWQgZmluYWwgc2hvcnRbXSBiYWNraW5nQXJyYXk7CisKKyAgICBwcm90ZWN0ZWQgZmluYWwgaW50IG9mZnNldDsKKworICAgIFNob3J0QXJyYXlCdWZmZXIoc2hvcnRbXSBhcnJheSkgeworICAgICAgICB0aGlzKGFycmF5Lmxlbmd0aCwgYXJyYXksIDApOworICAgIH0KKworICAgIFNob3J0QXJyYXlCdWZmZXIoaW50IGNhcGFjaXR5KSB7CisgICAgICAgIHRoaXMoY2FwYWNpdHksIG5ldyBzaG9ydFtjYXBhY2l0eV0sIDApOworICAgIH0KKworICAgIFNob3J0QXJyYXlCdWZmZXIoaW50IGNhcGFjaXR5LCBzaG9ydFtdIGJhY2tpbmdBcnJheSwgaW50IG9mZnNldCkgeworICAgICAgICBzdXBlcihjYXBhY2l0eSk7CisgICAgICAgIHRoaXMuYmFja2luZ0FycmF5ID0gYmFja2luZ0FycmF5OworICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgc2hvcnQgZ2V0KCkgeworICAgICAgICBpZiAocG9zaXRpb24gPT0gbGltaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYmFja2luZ0FycmF5W29mZnNldCArIHBvc2l0aW9uKytdOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBzaG9ydCBnZXQoaW50IGluZGV4KSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICByZXR1cm4gYmFja2luZ0FycmF5W29mZnNldCArIGluZGV4XTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgU2hvcnRCdWZmZXIgZ2V0KHNob3J0W10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgc2hvcnRDb3VudCkgeworICAgICAgICBpZiAoc2hvcnRDb3VudCA+IHJlbWFpbmluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShiYWNraW5nQXJyYXksIG9mZnNldCArIHBvc2l0aW9uLCBkc3QsIGRzdE9mZnNldCwgc2hvcnRDb3VudCk7CisgICAgICAgIHBvc2l0aW9uICs9IHNob3J0Q291bnQ7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzRGlyZWN0KCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIEJ5dGVPcmRlciBvcmRlcigpIHsKKyAgICAgICAgcmV0dXJuIEJ5dGVPcmRlci5uYXRpdmVPcmRlcigpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1Nob3J0QnVmZmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vU2hvcnRCdWZmZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNTJjZjZiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1Nob3J0QnVmZmVyLmphdmEKQEAgLTAsMCArMSw0NzIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW87CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIEEgYnVmZmVyIG9mIHNob3J0cy4KKyAqIDxwPgorICogQSBzaG9ydCBidWZmZXIgY2FuIGJlIGNyZWF0ZWQgaW4gZWl0aGVyIG9mIHRoZSBmb2xsb3dpbmcgd2F5czoKKyAqIDx1bD4KKyAqIDxsaT57QGxpbmsgI2FsbG9jYXRlKGludCkgQWxsb2NhdGV9IGEgbmV3IHNob3J0IGFycmF5IGFuZCBjcmVhdGUgYSBidWZmZXIKKyAqIGJhc2VkIG9uIGl0OzwvbGk+CisgKiA8bGk+e0BsaW5rICN3cmFwKHNob3J0W10pIFdyYXB9IGFuIGV4aXN0aW5nIHNob3J0IGFycmF5IHRvIGNyZWF0ZSBhIG5ldworICogYnVmZmVyOzwvbGk+CisgKiA8bGk+VXNlIHtAbGluayBqYXZhLm5pby5CeXRlQnVmZmVyI2FzU2hvcnRCdWZmZXIoKSBCeXRlQnVmZmVyLmFzU2hvcnRCdWZmZXJ9CisgKiB0byBjcmVhdGUgYSBzaG9ydCBidWZmZXIgYmFzZWQgb24gYSBieXRlIGJ1ZmZlci48L2xpPgorICogPC91bD4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFNob3J0QnVmZmVyIGV4dGVuZHMgQnVmZmVyIGltcGxlbWVudHMKKyAgICAgICAgQ29tcGFyYWJsZTxTaG9ydEJ1ZmZlcj4geworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHNob3J0IGJ1ZmZlciBiYXNlZCBvbiBhIG5ld2x5IGFsbG9jYXRlZCBzaG9ydCBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXBhY2l0eQorICAgICAqICAgICAgICAgICAgdGhlIGNhcGFjaXR5IG9mIHRoZSBuZXcgYnVmZmVyLgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgc2hvcnQgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGNhcGFjaXR5fSBpcyBsZXNzIHRoYW4gemVyby4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNob3J0QnVmZmVyIGFsbG9jYXRlKGludCBjYXBhY2l0eSkgeworICAgICAgICBpZiAoY2FwYWNpdHkgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBSZWFkV3JpdGVTaG9ydEFycmF5QnVmZmVyKGNhcGFjaXR5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHNob3J0IGJ1ZmZlciBieSB3cmFwcGluZyB0aGUgZ2l2ZW4gc2hvcnQgYXJyYXkuCisgICAgICogPHA+CisgICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzCisgICAgICoge0Bjb2RlIHdyYXAoYXJyYXksIDAsIGFycmF5Lmxlbmd0aCl9LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUgc2hvcnQgYXJyYXkgd2hpY2ggdGhlIG5ldyBidWZmZXIgd2lsbCBiZSBiYXNlZCBvbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBjcmVhdGVkIHNob3J0IGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNob3J0QnVmZmVyIHdyYXAoc2hvcnRbXSBhcnJheSkgeworICAgICAgICByZXR1cm4gd3JhcChhcnJheSwgMCwgYXJyYXkubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHNob3J0IGJ1ZmZlciBieSB3cmFwcGluZyB0aGUgZ2l2ZW4gc2hvcnQgYXJyYXkuCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIncyBwb3NpdGlvbiB3aWxsIGJlIHtAY29kZSBzdGFydH0sIGxpbWl0IHdpbGwgYmUKKyAgICAgKiB7QGNvZGUgc3RhcnQgKyBzaG9ydENvdW50fSwgY2FwYWNpdHkgd2lsbCBiZSB0aGUgbGVuZ3RoIG9mIHRoZSBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHNob3J0IGFycmF5IHdoaWNoIHRoZSBuZXcgYnVmZmVyIHdpbGwgYmUgYmFzZWQgb24uCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgaW5kZXgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBub3QgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgICAgICB7QGNvZGUgYXJyYXkubGVuZ3RofS4KKyAgICAgKiBAcGFyYW0gc2hvcnRDb3VudAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIG5vdCBncmVhdGVyIHRoYW4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBhcnJheS5sZW5ndGggLSBzdGFydH0uCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCBzaG9ydCBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgZWl0aGVyIHtAY29kZSBzdGFydH0gb3Ige0Bjb2RlIHNob3J0Q291bnR9IGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTaG9ydEJ1ZmZlciB3cmFwKHNob3J0W10gYXJyYXksIGludCBzdGFydCwgaW50IHNob3J0Q291bnQpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYXJyYXkubGVuZ3RoLCBzdGFydCwgc2hvcnRDb3VudCk7CisgICAgICAgIFNob3J0QnVmZmVyIGJ1ZiA9IG5ldyBSZWFkV3JpdGVTaG9ydEFycmF5QnVmZmVyKGFycmF5KTsKKyAgICAgICAgYnVmLnBvc2l0aW9uID0gc3RhcnQ7CisgICAgICAgIGJ1Zi5saW1pdCA9IHN0YXJ0ICsgc2hvcnRDb3VudDsKKyAgICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICBTaG9ydEJ1ZmZlcihpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgc3VwZXIoMSwgY2FwYWNpdHksIG51bGwpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBzaG9ydFtdIGFycmF5KCkgeworICAgICAgICByZXR1cm4gcHJvdGVjdGVkQXJyYXkoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgaW50IGFycmF5T2Zmc2V0KCkgeworICAgICAgICByZXR1cm4gcHJvdGVjdGVkQXJyYXlPZmZzZXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcmVhZC1vbmx5IGJ1ZmZlciB0aGF0IHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSByZXR1cm5lZCBidWZmZXIgaXMgZ3VhcmFudGVlZCB0byBiZSBhIG5ldyBpbnN0YW5jZSwgZXZlbiBpZiB0aGlzCisgICAgICogYnVmZmVyIGlzIHJlYWQtb25seSBpdHNlbGYuIFRoZSBuZXcgYnVmZmVyJ3MgcG9zaXRpb24sIGxpbWl0LCBjYXBhY2l0eQorICAgICAqIGFuZCBtYXJrIGFyZSB0aGUgc2FtZSBhcyB0aGlzIGJ1ZmZlcidzLgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXcgYnVmZmVyIHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLCB3aGljaCBtZWFucyB0aGlzCisgICAgICogYnVmZmVyJ3MgY2hhbmdlIG9mIGNvbnRlbnQgd2lsbCBiZSB2aXNpYmxlIHRvIHRoZSBuZXcgYnVmZmVyLiBUaGUgdHdvCisgICAgICogYnVmZmVyJ3MgcG9zaXRpb24sIGxpbWl0IGFuZCBtYXJrIGFyZSBpbmRlcGVuZGVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSByZWFkLW9ubHkgdmVyc2lvbiBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2hvcnRCdWZmZXIgYXNSZWFkT25seUJ1ZmZlcigpOworCisgICAgLyoqCisgICAgICogQ29tcGFjdHMgdGhpcyBzaG9ydCBidWZmZXIuCisgICAgICogPHA+CisgICAgICogVGhlIHJlbWFpbmluZyBzaG9ydHMgd2lsbCBiZSBtb3ZlZCB0byB0aGUgaGVhZCBvZiB0aGUgYnVmZmVyLCBzdGFydGluZworICAgICAqIGZyb20gcG9zaXRpb24gemVyby4gVGhlbiB0aGUgcG9zaXRpb24gaXMgc2V0IHRvIHtAY29kZSByZW1haW5pbmcoKX07IHRoZQorICAgICAqIGxpbWl0IGlzIHNldCB0byBjYXBhY2l0eTsgdGhlIG1hcmsgaXMgY2xlYXJlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIGNoYW5nZXMgbWF5IGJlIG1hZGUgdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTaG9ydEJ1ZmZlciBjb21wYWN0KCk7CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlIHRoZSByZW1haW5pbmcgc2hvcnRzIG9mIHRoaXMgYnVmZmVyIHRvIGFub3RoZXIgc2hvcnQgYnVmZmVyJ3MKKyAgICAgKiByZW1haW5pbmcgc2hvcnRzLgorICAgICAqCisgICAgICogQHBhcmFtIG90aGVyQnVmZmVyCisgICAgICogICAgICAgICAgICBhbm90aGVyIHNob3J0IGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIGEgbmVnYXRpdmUgdmFsdWUgaWYgdGhpcyBpcyBsZXNzIHRoYW4ge0Bjb2RlIG90aGVyQnVmZmVyfTsgMCBpZgorICAgICAqICAgICAgICAgdGhpcyBlcXVhbHMgdG8ge0Bjb2RlIG90aGVyQnVmZmVyfTsgYSBwb3NpdGl2ZSB2YWx1ZSBpZiB0aGlzIGlzCisgICAgICogICAgICAgICBncmVhdGVyIHRoYW4ge0Bjb2RlIG90aGVyQnVmZmVyfS4KKyAgICAgKiBAZXhjZXB0aW9uIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBvdGhlckJ1ZmZlcn0gaXMgbm90IGEgc2hvcnQgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKFNob3J0QnVmZmVyIG90aGVyQnVmZmVyKSB7CisgICAgICAgIGludCBjb21wYXJlUmVtYWluaW5nID0gKHJlbWFpbmluZygpIDwgb3RoZXJCdWZmZXIucmVtYWluaW5nKCkpID8gcmVtYWluaW5nKCkKKyAgICAgICAgICAgICAgICA6IG90aGVyQnVmZmVyLnJlbWFpbmluZygpOworICAgICAgICBpbnQgdGhpc1BvcyA9IHBvc2l0aW9uOworICAgICAgICBpbnQgb3RoZXJQb3MgPSBvdGhlckJ1ZmZlci5wb3NpdGlvbjsKKyAgICAgICAgc2hvcnQgdGhpc0J5dGUsIG90aGVyQnl0ZTsKKyAgICAgICAgd2hpbGUgKGNvbXBhcmVSZW1haW5pbmcgPiAwKSB7CisgICAgICAgICAgICB0aGlzQnl0ZSA9IGdldCh0aGlzUG9zKTsKKyAgICAgICAgICAgIG90aGVyQnl0ZSA9IG90aGVyQnVmZmVyLmdldChvdGhlclBvcyk7CisgICAgICAgICAgICBpZiAodGhpc0J5dGUgIT0gb3RoZXJCeXRlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXNCeXRlIDwgb3RoZXJCeXRlID8gLTEgOiAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpc1BvcysrOworICAgICAgICAgICAgb3RoZXJQb3MrKzsKKyAgICAgICAgICAgIGNvbXBhcmVSZW1haW5pbmctLTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVtYWluaW5nKCkgLSBvdGhlckJ1ZmZlci5yZW1haW5pbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgZHVwbGljYXRlZCBidWZmZXIgdGhhdCBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZHVwbGljYXRlZCBidWZmZXIncyBwb3NpdGlvbiwgbGltaXQsIGNhcGFjaXR5IGFuZCBtYXJrIGFyZSB0aGUgc2FtZQorICAgICAqIGFzIHRoaXMgYnVmZmVyLiBUaGUgZHVwbGljYXRlZCBidWZmZXIncyByZWFkLW9ubHkgcHJvcGVydHkgYW5kIGJ5dGUgb3JkZXIKKyAgICAgKiBhcmUgdGhlIHNhbWUgYXMgdGhpcyBidWZmZXIncy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbmV3IGJ1ZmZlciBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlciwgd2hpY2ggbWVhbnMgZWl0aGVyCisgICAgICogYnVmZmVyJ3MgY2hhbmdlIG9mIGNvbnRlbnQgd2lsbCBiZSB2aXNpYmxlIHRvIHRoZSBvdGhlci4gVGhlIHR3byBidWZmZXIncworICAgICAqIHBvc2l0aW9uLCBsaW1pdCBhbmQgbWFyayBhcmUgaW5kZXBlbmRlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgZHVwbGljYXRlZCBidWZmZXIgdGhhdCBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2hvcnRCdWZmZXIgZHVwbGljYXRlKCk7CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciB0aGlzIHNob3J0IGJ1ZmZlciBpcyBlcXVhbCB0byBhbm90aGVyIG9iamVjdC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB7QGNvZGUgb3RoZXJ9IGlzIG5vdCBhIHNob3J0IGJ1ZmZlciB0aGVuIHtAY29kZSBmYWxzZX0gaXMgcmV0dXJuZWQuCisgICAgICogVHdvIHNob3J0IGJ1ZmZlcnMgYXJlIGVxdWFsIGlmIGFuZCBvbmx5IGlmIHRoZWlyIHJlbWFpbmluZyBzaG9ydHMgYXJlCisgICAgICogZXhhY3RseSB0aGUgc2FtZS4gUG9zaXRpb24sIGxpbWl0LCBjYXBhY2l0eSBhbmQgbWFyayBhcmUgbm90IGNvbnNpZGVyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3RoZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB3aXRoIHRoaXMgc2hvcnQgYnVmZmVyLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgc2hvcnQgYnVmZmVyIGlzIGVxdWFsIHRvIHtAY29kZSBvdGhlcn0sCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG90aGVyKSB7CisgICAgICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgU2hvcnRCdWZmZXIpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgU2hvcnRCdWZmZXIgb3RoZXJCdWZmZXIgPSAoU2hvcnRCdWZmZXIpIG90aGVyOworCisgICAgICAgIGlmIChyZW1haW5pbmcoKSAhPSBvdGhlckJ1ZmZlci5yZW1haW5pbmcoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgaW50IG15UG9zaXRpb24gPSBwb3NpdGlvbjsKKyAgICAgICAgaW50IG90aGVyUG9zaXRpb24gPSBvdGhlckJ1ZmZlci5wb3NpdGlvbjsKKyAgICAgICAgYm9vbGVhbiBlcXVhbFNvRmFyID0gdHJ1ZTsKKyAgICAgICAgd2hpbGUgKGVxdWFsU29GYXIgJiYgKG15UG9zaXRpb24gPCBsaW1pdCkpIHsKKyAgICAgICAgICAgIGVxdWFsU29GYXIgPSBnZXQobXlQb3NpdGlvbisrKSA9PSBvdGhlckJ1ZmZlci5nZXQob3RoZXJQb3NpdGlvbisrKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBlcXVhbFNvRmFyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNob3J0IGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5CisgICAgICogMS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNob3J0IGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHBvc2l0aW9uIGlzIGVxdWFsIG9yIGdyZWF0ZXIgdGhhbiBsaW1pdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgc2hvcnQgZ2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBzaG9ydHMgZnJvbSB0aGUgY3VycmVudCBwb3NpdGlvbiBpbnRvIHRoZSBzcGVjaWZpZWQgc2hvcnQgYXJyYXkgYW5kCisgICAgICogaW5jcmVhc2VzIHRoZSBwb3NpdGlvbiBieSB0aGUgbnVtYmVyIG9mIHNob3J0cyByZWFkLgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcworICAgICAqIHtAY29kZSBnZXQoZHN0LCAwLCBkc3QubGVuZ3RoKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gc2hvcnQgYXJyYXkuCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBkc3QubGVuZ3RofSBpcyBncmVhdGVyIHRoYW4ge0Bjb2RlIHJlbWFpbmluZygpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2hvcnRCdWZmZXIgZ2V0KHNob3J0W10gZHN0KSB7CisgICAgICAgIHJldHVybiBnZXQoZHN0LCAwLCBkc3QubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBzaG9ydHMgZnJvbSB0aGUgY3VycmVudCBwb3NpdGlvbiBpbnRvIHRoZSBzcGVjaWZpZWQgc2hvcnQgYXJyYXksCisgICAgICogc3RhcnRpbmcgZnJvbSB0aGUgc3BlY2lmaWVkIG9mZnNldCwgYW5kIGluY3JlYXNlcyB0aGUgcG9zaXRpb24gYnkgdGhlCisgICAgICogbnVtYmVyIG9mIHNob3J0cyByZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBzaG9ydCBhcnJheS4KKyAgICAgKiBAcGFyYW0gZHN0T2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIHRoZSBzaG9ydCBhcnJheSwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIG5vdAorICAgICAqICAgICAgICAgICAgZ3JlYXRlciB0aGFuIHtAY29kZSBkc3QubGVuZ3RofS4KKyAgICAgKiBAcGFyYW0gc2hvcnRDb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBzaG9ydHMgdG8gcmVhZCwgbXVzdCBiZSBubyBsZXNzIHRoYW4gemVybyBhbmQKKyAgICAgKiAgICAgICAgICAgIG5vdCBncmVhdGVyIHRoYW4ge0Bjb2RlIGRzdC5sZW5ndGggLSBkc3RPZmZzZXR9LgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgZWl0aGVyIHtAY29kZSBkc3RPZmZzZXR9IG9yIHtAY29kZSBzaG9ydENvdW50fSBpcyBpbnZhbGlkLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHNob3J0Q291bnR9IGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgcmVtYWluaW5nKCl9LgorICAgICAqLworICAgIHB1YmxpYyBTaG9ydEJ1ZmZlciBnZXQoc2hvcnRbXSBkc3QsIGludCBkc3RPZmZzZXQsIGludCBzaG9ydENvdW50KSB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGRzdC5sZW5ndGgsIGRzdE9mZnNldCwgc2hvcnRDb3VudCk7CisgICAgICAgIGlmIChzaG9ydENvdW50ID4gcmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gZHN0T2Zmc2V0OyBpIDwgZHN0T2Zmc2V0ICsgc2hvcnRDb3VudDsgKytpKSB7CisgICAgICAgICAgICBkc3RbaV0gPSBnZXQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzaG9ydCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4OyB0aGUgcG9zaXRpb24gaXMgbm90IGNoYW5nZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIGxlc3MgdGhhbiBsaW1pdC4KKyAgICAgKiBAcmV0dXJuIGEgc2hvcnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBpbmRleCBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBzaG9ydCBnZXQoaW50IGluZGV4KTsKKworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc0FycmF5KCkgeworICAgICAgICByZXR1cm4gcHJvdGVjdGVkSGFzQXJyYXkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxjdWxhdGVzIHRoaXMgYnVmZmVyJ3MgaGFzaCBjb2RlIGZyb20gdGhlIHJlbWFpbmluZyBjaGFycy4gVGhlCisgICAgICogcG9zaXRpb24sIGxpbWl0LCBjYXBhY2l0eSBhbmQgbWFyayBkb24ndCBhZmZlY3QgdGhlIGhhc2ggY29kZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZSBjYWxjdWxhdGVkIGZyb20gdGhlIHJlbWFpbmluZyBzaG9ydHMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IG15UG9zaXRpb24gPSBwb3NpdGlvbjsKKyAgICAgICAgaW50IGhhc2ggPSAwOworICAgICAgICB3aGlsZSAobXlQb3NpdGlvbiA8IGxpbWl0KSB7CisgICAgICAgICAgICBoYXNoID0gaGFzaCArIGdldChteVBvc2l0aW9uKyspOworICAgICAgICB9CisgICAgICAgIHJldHVybiBoYXNoOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgYnVmZmVyIGlzIGRpcmVjdC4gQSBkaXJlY3QgYnVmZmVyIHdpbGwgdHJ5IGl0cworICAgICAqIGJlc3QgdG8gdGFrZSBhZHZhbnRhZ2Ugb2YgbmF0aXZlIG1lbW9yeSBBUElzIGFuZCBpdCBtYXkgbm90IHN0YXkgaW4gdGhlCisgICAgICogSmF2YSBoZWFwLCBzbyBpdCBpcyBub3QgYWZmZWN0ZWQgYnkgZ2FyYmFnZSBjb2xsZWN0aW9uLgorICAgICAqIDxwPgorICAgICAqIEEgc2hvcnQgYnVmZmVyIGlzIGRpcmVjdCBpZiBpdCBpcyBiYXNlZCBvbiBhIGJ5dGUgYnVmZmVyIGFuZCB0aGUgYnl0ZQorICAgICAqIGJ1ZmZlciBpcyBkaXJlY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGJ1ZmZlciBpcyBkaXJlY3QsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzRGlyZWN0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBieXRlIG9yZGVyIHVzZWQgYnkgdGhpcyBidWZmZXIgd2hlbiBjb252ZXJ0aW5nIHNob3J0cyBmcm9tL3RvCisgICAgICogYnl0ZXMuCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBidWZmZXIgaXMgbm90IGJhc2VkIG9uIGEgYnl0ZSBidWZmZXIsIHRoZW4gYWx3YXlzIHJldHVybiB0aGUKKyAgICAgKiBwbGF0Zm9ybSdzIG5hdGl2ZSBieXRlIG9yZGVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYnl0ZSBvcmRlciB1c2VkIGJ5IHRoaXMgYnVmZmVyIHdoZW4gY29udmVydGluZyBzaG9ydHMgZnJvbS90bworICAgICAqICAgICAgICAgYnl0ZXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ5dGVPcmRlciBvcmRlcigpOworCisgICAgLyoqCisgICAgICogQ2hpbGQgY2xhc3MgaW1wbGVtZW50cyB0aGlzIG1ldGhvZCB0byByZWFsaXplIHtAY29kZSBhcnJheSgpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gc2VlIHtAY29kZSBhcnJheSgpfQorICAgICAqLworICAgIGFic3RyYWN0IHNob3J0W10gcHJvdGVjdGVkQXJyYXkoKTsKKworICAgIC8qKgorICAgICAqIENoaWxkIGNsYXNzIGltcGxlbWVudHMgdGhpcyBtZXRob2QgdG8gcmVhbGl6ZSB7QGNvZGUgYXJyYXlPZmZzZXQoKX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHNlZSB7QGNvZGUgYXJyYXlPZmZzZXQoKX0KKyAgICAgKi8KKyAgICBhYnN0cmFjdCBpbnQgcHJvdGVjdGVkQXJyYXlPZmZzZXQoKTsKKworICAgIC8qKgorICAgICAqIENoaWxkIGNsYXNzIGltcGxlbWVudHMgdGhpcyBtZXRob2QgdG8gcmVhbGl6ZSB7QGNvZGUgaGFzQXJyYXkoKX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHNlZSB7QGNvZGUgaGFzQXJyYXkoKX0KKyAgICAgKi8KKyAgICBhYnN0cmFjdCBib29sZWFuIHByb3RlY3RlZEhhc0FycmF5KCk7CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGdpdmVuIHNob3J0IHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uCisgICAgICogYnkgMS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgc2hvcnQgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcG9zaXRpb24gaXMgZXF1YWwgb3IgZ3JlYXRlciB0aGFuIGxpbWl0LgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2hvcnRCdWZmZXIgcHV0KHNob3J0IHMpOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHNob3J0cyBmcm9tIHRoZSBnaXZlbiBzaG9ydCBhcnJheSB0byB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQKKyAgICAgKiBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IHRoZSBudW1iZXIgb2Ygc2hvcnRzIHdyaXR0ZW4uCisgICAgICogPHA+CisgICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzCisgICAgICoge0Bjb2RlIHB1dChzcmMsIDAsIHNyYy5sZW5ndGgpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2Ugc2hvcnQgYXJyYXkuCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHJlbWFpbmluZygpfSBpcyBsZXNzIHRoYW4ge0Bjb2RlIHNyYy5sZW5ndGh9LgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU2hvcnRCdWZmZXIgcHV0KHNob3J0W10gc3JjKSB7CisgICAgICAgIHJldHVybiBwdXQoc3JjLCAwLCBzcmMubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgc2hvcnRzIGZyb20gdGhlIGdpdmVuIHNob3J0IGFycmF5LCBzdGFydGluZyBmcm9tIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBvZmZzZXQsIHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBpbmNyZWFzZXMgdGhlIHBvc2l0aW9uIGJ5IHRoZSBudW1iZXIKKyAgICAgKiBvZiBzaG9ydHMgd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2Ugc2hvcnQgYXJyYXkuCisgICAgICogQHBhcmFtIHNyY09mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBvZiBzaG9ydCBhcnJheSwgbXVzdCBub3QgYmUgbmVnYXRpdmUgYW5kIG5vdAorICAgICAqICAgICAgICAgICAgZ3JlYXRlciB0aGFuIHtAY29kZSBzcmMubGVuZ3RofS4KKyAgICAgKiBAcGFyYW0gc2hvcnRDb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBzaG9ydHMgdG8gd3JpdGUsIG11c3QgYmUgbm8gbGVzcyB0aGFuIHplcm8gYW5kCisgICAgICogICAgICAgICAgICBub3QgZ3JlYXRlciB0aGFuIHtAY29kZSBzcmMubGVuZ3RoIC0gc3JjT2Zmc2V0fS4KKyAgICAgKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgcmVtYWluaW5nKCl9IGlzIGxlc3MgdGhhbiB7QGNvZGUgc2hvcnRDb3VudH0uCisgICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgZWl0aGVyIHtAY29kZSBzcmNPZmZzZXR9IG9yIHtAY29kZSBzaG9ydENvdW50fSBpcyBpbnZhbGlkLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2hvcnRCdWZmZXIgcHV0KHNob3J0W10gc3JjLCBpbnQgc3JjT2Zmc2V0LCBpbnQgc2hvcnRDb3VudCkgeworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChzcmMubGVuZ3RoLCBzcmNPZmZzZXQsIHNob3J0Q291bnQpOworICAgICAgICBpZiAoc2hvcnRDb3VudCA+IHJlbWFpbmluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gc3JjT2Zmc2V0OyBpIDwgc3JjT2Zmc2V0ICsgc2hvcnRDb3VudDsgKytpKSB7CisgICAgICAgICAgICBwdXQoc3JjW2ldKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYWxsIHRoZSByZW1haW5pbmcgc2hvcnRzIG9mIHRoZSB7QGNvZGUgc3JjfSBzaG9ydCBidWZmZXIgdG8gdGhpcworICAgICAqIGJ1ZmZlcidzIGN1cnJlbnQgcG9zaXRpb24sIGFuZCBpbmNyZWFzZXMgYm90aCBidWZmZXJzJyBwb3NpdGlvbiBieSB0aGUKKyAgICAgKiBudW1iZXIgb2Ygc2hvcnRzIGNvcGllZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2Ugc2hvcnQgYnVmZmVyLgorICAgICAqIEByZXR1cm4gdGhpcyBidWZmZXIuCisgICAgICogQGV4Y2VwdGlvbiBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzcmMucmVtYWluaW5nKCl9IGlzIGdyZWF0ZXIgdGhhbiB0aGlzIGJ1ZmZlcidzCisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIHJlbWFpbmluZygpfS4KKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzcmN9IGlzIHRoaXMgYnVmZmVyLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2hvcnRCdWZmZXIgcHV0KFNob3J0QnVmZmVyIHNyYykgeworICAgICAgICBpZiAoc3JjID09IHRoaXMpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3JjLnJlbWFpbmluZygpID4gcmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHNob3J0W10gY29udGVudHMgPSBuZXcgc2hvcnRbc3JjLnJlbWFpbmluZygpXTsKKyAgICAgICAgc3JjLmdldChjb250ZW50cyk7CisgICAgICAgIHB1dChjb250ZW50cyk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIHNob3J0IHRvIHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyBidWZmZXI7IHRoZSBwb3NpdGlvbiBpcyBub3QKKyAgICAgKiBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXgsIG11c3Qgbm90IGJlIG5lZ2F0aXZlIGFuZCBsZXNzIHRoYW4gdGhlIGxpbWl0LgorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgc2hvcnQgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB0aGlzIGJ1ZmZlci4KKyAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBpbmRleCBpcyBpbnZhbGlkLgorICAgICAqIEBleGNlcHRpb24gUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyBjaGFuZ2VzIG1heSBiZSBtYWRlIHRvIHRoZSBjb250ZW50cyBvZiB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2hvcnRCdWZmZXIgcHV0KGludCBpbmRleCwgc2hvcnQgcyk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc2xpY2VkIGJ1ZmZlciB0aGF0IHNoYXJlcyBpdHMgY29udGVudCB3aXRoIHRoaXMgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBzbGljZWQgYnVmZmVyJ3MgY2FwYWNpdHkgd2lsbCBiZSB0aGlzIGJ1ZmZlcidzIHtAY29kZSByZW1haW5pbmcoKX0sCisgICAgICogYW5kIGl0cyB6ZXJvIHBvc2l0aW9uIHdpbGwgY29ycmVzcG9uZCB0byB0aGlzIGJ1ZmZlcidzIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogVGhlIG5ldyBidWZmZXIncyBwb3NpdGlvbiB3aWxsIGJlIDAsIGxpbWl0IHdpbGwgYmUgaXRzIGNhcGFjaXR5LCBhbmQgaXRzCisgICAgICogbWFyayBpcyBjbGVhcmVkLiBUaGUgbmV3IGJ1ZmZlcidzIHJlYWQtb25seSBwcm9wZXJ0eSBhbmQgYnl0ZSBvcmRlciBhcmUKKyAgICAgKiBzYW1lIGFzIHRoaXMgYnVmZmVyJ3MuCisgICAgICogPHA+CisgICAgICogVGhlIG5ldyBidWZmZXIgc2hhcmVzIGl0cyBjb250ZW50IHdpdGggdGhpcyBidWZmZXIsIHdoaWNoIG1lYW5zIGVpdGhlcgorICAgICAqIGJ1ZmZlcidzIGNoYW5nZSBvZiBjb250ZW50IHdpbGwgYmUgdmlzaWJsZSB0byB0aGUgb3RoZXIuIFRoZSB0d28gYnVmZmVyJ3MKKyAgICAgKiBwb3NpdGlvbiwgbGltaXQgYW5kIG1hcmsgYXJlIGluZGVwZW5kZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIHNsaWNlZCBidWZmZXIgdGhhdCBzaGFyZXMgaXRzIGNvbnRlbnQgd2l0aCB0aGlzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2hvcnRCdWZmZXIgc2xpY2UoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9TaG9ydFRvQnl0ZUJ1ZmZlckFkYXB0ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9TaG9ydFRvQnl0ZUJ1ZmZlckFkYXB0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZmEyYTYzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1Nob3J0VG9CeXRlQnVmZmVyQWRhcHRlci5qYXZhCkBAIC0wLDAgKzEsMTgxIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCitpbXBvcnQgbGliY29yZS5pby5TaXplT2Y7CisKKy8qKgorICogVGhpcyBjbGFzcyB3cmFwcyBhIGJ5dGUgYnVmZmVyIHRvIGJlIGEgc2hvcnQgYnVmZmVyLgorICogPHA+CisgKiBJbXBsZW1lbnRhdGlvbiBub3RpY2U6CisgKiA8dWw+CisgKiA8bGk+QWZ0ZXIgYSBieXRlIGJ1ZmZlciBpbnN0YW5jZSBpcyB3cmFwcGVkLCBpdCBiZWNvbWVzIHByaXZhdGVseSBvd25lZCBieQorICogdGhlIGFkYXB0ZXIuIEl0IG11c3QgTk9UIGJlIGFjY2Vzc2VkIG91dHNpZGUgdGhlIGFkYXB0ZXIgYW55IG1vcmUuPC9saT4KKyAqIDxsaT5UaGUgYnl0ZSBidWZmZXIncyBwb3NpdGlvbiBhbmQgbGltaXQgYXJlIE5PVCBsaW5rZWQgd2l0aCB0aGUgYWRhcHRlci4KKyAqIFRoZSBhZGFwdGVyIGV4dGVuZHMgQnVmZmVyLCB0aHVzIGhhcyBpdHMgb3duIHBvc2l0aW9uIGFuZCBsaW1pdC48L2xpPgorICogPC91bD4KKyAqIDwvcD4KKyAqLworZmluYWwgY2xhc3MgU2hvcnRUb0J5dGVCdWZmZXJBZGFwdGVyIGV4dGVuZHMgU2hvcnRCdWZmZXIgeworCisgICAgcHJpdmF0ZSBmaW5hbCBCeXRlQnVmZmVyIGJ5dGVCdWZmZXI7CisKKyAgICBzdGF0aWMgU2hvcnRCdWZmZXIgYXNTaG9ydEJ1ZmZlcihCeXRlQnVmZmVyIGJ5dGVCdWZmZXIpIHsKKyAgICAgICAgQnl0ZUJ1ZmZlciBzbGljZSA9IGJ5dGVCdWZmZXIuc2xpY2UoKTsKKyAgICAgICAgc2xpY2Uub3JkZXIoYnl0ZUJ1ZmZlci5vcmRlcigpKTsKKyAgICAgICAgcmV0dXJuIG5ldyBTaG9ydFRvQnl0ZUJ1ZmZlckFkYXB0ZXIoc2xpY2UpOworICAgIH0KKworICAgIHByaXZhdGUgU2hvcnRUb0J5dGVCdWZmZXJBZGFwdGVyKEJ5dGVCdWZmZXIgYnl0ZUJ1ZmZlcikgeworICAgICAgICBzdXBlcihieXRlQnVmZmVyLmNhcGFjaXR5KCkgLyBTaXplT2YuU0hPUlQpOworICAgICAgICB0aGlzLmJ5dGVCdWZmZXIgPSBieXRlQnVmZmVyOworICAgICAgICB0aGlzLmJ5dGVCdWZmZXIuY2xlYXIoKTsKKyAgICAgICAgdGhpcy5lZmZlY3RpdmVEaXJlY3RBZGRyZXNzID0gYnl0ZUJ1ZmZlci5lZmZlY3RpdmVEaXJlY3RBZGRyZXNzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTaG9ydEJ1ZmZlciBhc1JlYWRPbmx5QnVmZmVyKCkgeworICAgICAgICBTaG9ydFRvQnl0ZUJ1ZmZlckFkYXB0ZXIgYnVmID0gbmV3IFNob3J0VG9CeXRlQnVmZmVyQWRhcHRlcihieXRlQnVmZmVyLmFzUmVhZE9ubHlCdWZmZXIoKSk7CisgICAgICAgIGJ1Zi5saW1pdCA9IGxpbWl0OworICAgICAgICBidWYucG9zaXRpb24gPSBwb3NpdGlvbjsKKyAgICAgICAgYnVmLm1hcmsgPSBtYXJrOworICAgICAgICBidWYuYnl0ZUJ1ZmZlci5vcmRlciA9IGJ5dGVCdWZmZXIub3JkZXI7CisgICAgICAgIHJldHVybiBidWY7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNob3J0QnVmZmVyIGNvbXBhY3QoKSB7CisgICAgICAgIGlmIChieXRlQnVmZmVyLmlzUmVhZE9ubHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZUJ1ZmZlci5saW1pdChsaW1pdCAqIFNpemVPZi5TSE9SVCk7CisgICAgICAgIGJ5dGVCdWZmZXIucG9zaXRpb24ocG9zaXRpb24gKiBTaXplT2YuU0hPUlQpOworICAgICAgICBieXRlQnVmZmVyLmNvbXBhY3QoKTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5jbGVhcigpOworICAgICAgICBwb3NpdGlvbiA9IGxpbWl0IC0gcG9zaXRpb247CisgICAgICAgIGxpbWl0ID0gY2FwYWNpdHk7CisgICAgICAgIG1hcmsgPSBVTlNFVF9NQVJLOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2hvcnRCdWZmZXIgZHVwbGljYXRlKCkgeworICAgICAgICBCeXRlQnVmZmVyIGJiID0gYnl0ZUJ1ZmZlci5kdXBsaWNhdGUoKS5vcmRlcihieXRlQnVmZmVyLm9yZGVyKCkpOworICAgICAgICBTaG9ydFRvQnl0ZUJ1ZmZlckFkYXB0ZXIgYnVmID0gbmV3IFNob3J0VG9CeXRlQnVmZmVyQWRhcHRlcihiYik7CisgICAgICAgIGJ1Zi5saW1pdCA9IGxpbWl0OworICAgICAgICBidWYucG9zaXRpb24gPSBwb3NpdGlvbjsKKyAgICAgICAgYnVmLm1hcmsgPSBtYXJrOworICAgICAgICByZXR1cm4gYnVmOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzaG9ydCBnZXQoKSB7CisgICAgICAgIGlmIChwb3NpdGlvbiA9PSBsaW1pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBieXRlQnVmZmVyLmdldFNob3J0KHBvc2l0aW9uKysgKiBTaXplT2YuU0hPUlQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzaG9ydCBnZXQoaW50IGluZGV4KSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICByZXR1cm4gYnl0ZUJ1ZmZlci5nZXRTaG9ydChpbmRleCAqIFNpemVPZi5TSE9SVCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNob3J0QnVmZmVyIGdldChzaG9ydFtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IHNob3J0Q291bnQpIHsKKyAgICAgICAgYnl0ZUJ1ZmZlci5saW1pdChsaW1pdCAqIFNpemVPZi5TSE9SVCk7CisgICAgICAgIGJ5dGVCdWZmZXIucG9zaXRpb24ocG9zaXRpb24gKiBTaXplT2YuU0hPUlQpOworICAgICAgICBpZiAoYnl0ZUJ1ZmZlciBpbnN0YW5jZW9mIERpcmVjdEJ5dGVCdWZmZXIpIHsKKyAgICAgICAgICAgICgoRGlyZWN0Qnl0ZUJ1ZmZlcikgYnl0ZUJ1ZmZlcikuZ2V0KGRzdCwgZHN0T2Zmc2V0LCBzaG9ydENvdW50KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICgoSGVhcEJ5dGVCdWZmZXIpIGJ5dGVCdWZmZXIpLmdldChkc3QsIGRzdE9mZnNldCwgc2hvcnRDb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5wb3NpdGlvbiArPSBzaG9ydENvdW50OworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdCgpIHsKKyAgICAgICAgcmV0dXJuIGJ5dGVCdWZmZXIuaXNEaXJlY3QoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1JlYWRPbmx5KCkgeworICAgICAgICByZXR1cm4gYnl0ZUJ1ZmZlci5pc1JlYWRPbmx5KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVPcmRlciBvcmRlcigpIHsKKyAgICAgICAgcmV0dXJuIGJ5dGVCdWZmZXIub3JkZXIoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgc2hvcnRbXSBwcm90ZWN0ZWRBcnJheSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBwcm90ZWN0ZWRBcnJheU9mZnNldCgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcHJvdGVjdGVkSGFzQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2hvcnRCdWZmZXIgcHV0KHNob3J0IGMpIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IGxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBieXRlQnVmZmVyLnB1dFNob3J0KHBvc2l0aW9uKysgKiBTaXplT2YuU0hPUlQsIGMpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2hvcnRCdWZmZXIgcHV0KGludCBpbmRleCwgc2hvcnQgYykgeworICAgICAgICBjaGVja0luZGV4KGluZGV4KTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5wdXRTaG9ydChpbmRleCAqIFNpemVPZi5TSE9SVCwgYyk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTaG9ydEJ1ZmZlciBwdXQoc2hvcnRbXSBzcmMsIGludCBzcmNPZmZzZXQsIGludCBzaG9ydENvdW50KSB7CisgICAgICAgIGJ5dGVCdWZmZXIubGltaXQobGltaXQgKiBTaXplT2YuU0hPUlQpOworICAgICAgICBieXRlQnVmZmVyLnBvc2l0aW9uKHBvc2l0aW9uICogU2l6ZU9mLlNIT1JUKTsKKyAgICAgICAgaWYgKGJ5dGVCdWZmZXIgaW5zdGFuY2VvZiBSZWFkV3JpdGVEaXJlY3RCeXRlQnVmZmVyKSB7CisgICAgICAgICAgICAoKFJlYWRXcml0ZURpcmVjdEJ5dGVCdWZmZXIpIGJ5dGVCdWZmZXIpLnB1dChzcmMsIHNyY09mZnNldCwgc2hvcnRDb3VudCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAoKFJlYWRXcml0ZUhlYXBCeXRlQnVmZmVyKSBieXRlQnVmZmVyKS5wdXQoc3JjLCBzcmNPZmZzZXQsIHNob3J0Q291bnQpOworICAgICAgICB9CisgICAgICAgIHRoaXMucG9zaXRpb24gKz0gc2hvcnRDb3VudDsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNob3J0QnVmZmVyIHNsaWNlKCkgeworICAgICAgICBieXRlQnVmZmVyLmxpbWl0KGxpbWl0ICogU2l6ZU9mLlNIT1JUKTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5wb3NpdGlvbihwb3NpdGlvbiAqIFNpemVPZi5TSE9SVCk7CisgICAgICAgIEJ5dGVCdWZmZXIgYmIgPSBieXRlQnVmZmVyLnNsaWNlKCkub3JkZXIoYnl0ZUJ1ZmZlci5vcmRlcigpKTsKKyAgICAgICAgU2hvcnRCdWZmZXIgcmVzdWx0ID0gbmV3IFNob3J0VG9CeXRlQnVmZmVyQWRhcHRlcihiYik7CisgICAgICAgIGJ5dGVCdWZmZXIuY2xlYXIoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9Tb2NrZXRDaGFubmVsSW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL1NvY2tldENoYW5uZWxJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWIyNjgxMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9Tb2NrZXRDaGFubmVsSW1wbC5qYXZhCkBAIC0wLDAgKzEsNjYxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvOworCitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuQ29ubmVjdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0NEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuUGxhaW5Tb2NrZXRJbXBsOworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNvY2tldEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRVdGlsczsKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5BbHJlYWR5Q29ubmVjdGVkRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkNsb3NlZENoYW5uZWxFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuQ29ubmVjdGlvblBlbmRpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5Ob0Nvbm5lY3Rpb25QZW5kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLk5vdFlldENvbm5lY3RlZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5Tb2NrZXRDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlVucmVzb2x2ZWRBZGRyZXNzRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlVuc3VwcG9ydGVkQWRkcmVzc1R5cGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuc3BpLlNlbGVjdG9yUHJvdmlkZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBsaWJjb3JlLmlvLkVycm5vRXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUuaW8uTGliY29yZTsKK2ltcG9ydCBsaWJjb3JlLmlvLklvQnJpZGdlOworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKK2ltcG9ydCBzdGF0aWMgbGliY29yZS5pby5Pc0NvbnN0YW50cy4qOworCisvKgorICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gY2xhc3Mgb2YgamF2YS5uaW8uY2hhbm5lbHMuU29ja2V0Q2hhbm5lbC4KKyAqLworY2xhc3MgU29ja2V0Q2hhbm5lbEltcGwgZXh0ZW5kcyBTb2NrZXRDaGFubmVsIGltcGxlbWVudHMgRmlsZURlc2NyaXB0b3JDaGFubmVsIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU09DS0VUX1NUQVRVU19VTklOSVRJQUxJWkVEID0gLTE7CisKKyAgICAvLyBTdGF0dXMgYmVmb3JlIGNvbm5lY3QuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNPQ0tFVF9TVEFUVVNfVU5DT05ORUNURUQgPSAwOworCisgICAgLy8gU3RhdHVzIGNvbm5lY3Rpb24gcGVuZGluZy4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU09DS0VUX1NUQVRVU19QRU5ESU5HID0gMTsKKworICAgIC8vIFN0YXR1cyBhZnRlciBjb25uZWN0aW9uIHN1Y2Nlc3MuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNPQ0tFVF9TVEFUVVNfQ09OTkVDVEVEID0gMjsKKworICAgIC8vIFN0YXR1cyBjbG9zZWQuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNPQ0tFVF9TVEFUVVNfQ0xPU0VEID0gMzsKKworICAgIHByaXZhdGUgZmluYWwgRmlsZURlc2NyaXB0b3IgZmQ7CisKKyAgICAvLyBPdXIgaW50ZXJuYWwgU29ja2V0LgorICAgIHByaXZhdGUgU29ja2V0QWRhcHRlciBzb2NrZXQgPSBudWxsOworCisgICAgLy8gVGhlIGFkZHJlc3MgdG8gYmUgY29ubmVjdGVkLgorICAgIHByaXZhdGUgSW5ldFNvY2tldEFkZHJlc3MgY29ubmVjdEFkZHJlc3MgPSBudWxsOworCisgICAgcHJpdmF0ZSBJbmV0QWRkcmVzcyBsb2NhbEFkZHJlc3MgPSBudWxsOworICAgIHByaXZhdGUgaW50IGxvY2FsUG9ydDsKKworICAgIHByaXZhdGUgaW50IHN0YXR1cyA9IFNPQ0tFVF9TVEFUVVNfVU5JTklUSUFMSVpFRDsKKworICAgIC8vIFdoZXRoZXIgdGhlIHNvY2tldCBpcyBib3VuZC4KKyAgICBwcml2YXRlIHZvbGF0aWxlIGJvb2xlYW4gaXNCb3VuZCA9IGZhbHNlOworCisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgcmVhZExvY2sgPSBuZXcgT2JqZWN0KCk7CisKKyAgICBwcml2YXRlIGZpbmFsIE9iamVjdCB3cml0ZUxvY2sgPSBuZXcgT2JqZWN0KCk7CisKKyAgICAvKgorICAgICAqIENvbnN0cnVjdG9yIGZvciBjcmVhdGluZyBhIGNvbm5lY3RlZCBzb2NrZXQgY2hhbm5lbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU29ja2V0Q2hhbm5lbEltcGwoU2VsZWN0b3JQcm92aWRlciBzZWxlY3RvclByb3ZpZGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKHNlbGVjdG9yUHJvdmlkZXIsIHRydWUpOworICAgIH0KKworICAgIC8qCisgICAgICogQ29uc3RydWN0b3IgZm9yIGNyZWF0aW5nIGFuIG9wdGlvbmFsbHkgY29ubmVjdGVkIHNvY2tldCBjaGFubmVsLgorICAgICAqLworICAgIHB1YmxpYyBTb2NrZXRDaGFubmVsSW1wbChTZWxlY3RvclByb3ZpZGVyIHNlbGVjdG9yUHJvdmlkZXIsIGJvb2xlYW4gY29ubmVjdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoc2VsZWN0b3JQcm92aWRlcik7CisgICAgICAgIHN0YXR1cyA9IFNPQ0tFVF9TVEFUVVNfVU5DT05ORUNURUQ7CisgICAgICAgIGZkID0gKGNvbm5lY3QgPyBJb0JyaWRnZS5zb2NrZXQodHJ1ZSkgOiBuZXcgRmlsZURlc2NyaXB0b3IoKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBHZXR0aW5nIHRoZSBpbnRlcm5hbCBTb2NrZXQgSWYgd2UgaGF2ZSBub3QgdGhlIHNvY2tldCwgd2UgY3JlYXRlIGEgbmV3CisgICAgICogb25lLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHN5bmNocm9uaXplZCBwdWJsaWMgU29ja2V0IHNvY2tldCgpIHsKKyAgICAgICAgaWYgKHNvY2tldCA9PSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEluZXRBZGRyZXNzIGFkZHIgPSBudWxsOworICAgICAgICAgICAgICAgIGludCBwb3J0ID0gMDsKKyAgICAgICAgICAgICAgICBpZiAoY29ubmVjdEFkZHJlc3MgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBhZGRyID0gY29ubmVjdEFkZHJlc3MuZ2V0QWRkcmVzcygpOworICAgICAgICAgICAgICAgICAgICBwb3J0ID0gY29ubmVjdEFkZHJlc3MuZ2V0UG9ydCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzb2NrZXQgPSBuZXcgU29ja2V0QWRhcHRlcihuZXcgUGxhaW5Tb2NrZXRJbXBsKGZkLCBsb2NhbFBvcnQsIGFkZHIsIHBvcnQpLCB0aGlzKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNvY2tldDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBzeW5jaHJvbml6ZWQgcHVibGljIGJvb2xlYW4gaXNDb25uZWN0ZWQoKSB7CisgICAgICAgIHJldHVybiBzdGF0dXMgPT0gU09DS0VUX1NUQVRVU19DT05ORUNURUQ7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBTdGF0dXMgc2V0dGluZyB1c2VkIGJ5IG90aGVyIGNsYXNzLgorICAgICAqLworICAgIHN5bmNocm9uaXplZCB2b2lkIHNldENvbm5lY3RlZCgpIHsKKyAgICAgICAgc3RhdHVzID0gU09DS0VUX1NUQVRVU19DT05ORUNURUQ7CisgICAgfQorCisgICAgdm9pZCBzZXRCb3VuZChib29sZWFuIGZsYWcpIHsKKyAgICAgICAgaXNCb3VuZCA9IGZsYWc7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgc3luY2hyb25pemVkIHB1YmxpYyBib29sZWFuIGlzQ29ubmVjdGlvblBlbmRpbmcoKSB7CisgICAgICAgIHJldHVybiBzdGF0dXMgPT0gU09DS0VUX1NUQVRVU19QRU5ESU5HOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGNvbm5lY3QoU29ja2V0QWRkcmVzcyBzb2NrZXRBZGRyZXNzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBzdGF0dXMgbXVzdCBiZSBvcGVuIGFuZCB1bmNvbm5lY3RlZAorICAgICAgICBjaGVja1VuY29ubmVjdGVkKCk7CisKKyAgICAgICAgLy8gY2hlY2sgdGhlIGFkZHJlc3MKKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgaW5ldFNvY2tldEFkZHJlc3MgPSB2YWxpZGF0ZUFkZHJlc3Moc29ja2V0QWRkcmVzcyk7CisgICAgICAgIEluZXRBZGRyZXNzIG5vcm1hbEFkZHIgPSBpbmV0U29ja2V0QWRkcmVzcy5nZXRBZGRyZXNzKCk7CisgICAgICAgIGludCBwb3J0ID0gaW5ldFNvY2tldEFkZHJlc3MuZ2V0UG9ydCgpOworCisgICAgICAgIC8vIFdoZW4gY29ubmVjdGluZywgbWFwIEFOWSBhZGRyZXNzIHRvIGxvY2FsaG9zdAorICAgICAgICBpZiAobm9ybWFsQWRkci5pc0FueUxvY2FsQWRkcmVzcygpKSB7CisgICAgICAgICAgICBub3JtYWxBZGRyID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCk7CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIGZpbmlzaGVkID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoaXNCbG9ja2luZygpKSB7CisgICAgICAgICAgICAgICAgYmVnaW4oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpbmlzaGVkID0gSW9CcmlkZ2UuY29ubmVjdChmZCwgbm9ybWFsQWRkciwgcG9ydCk7CisgICAgICAgICAgICBpc0JvdW5kID0gZmluaXNoZWQ7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgQ29ubmVjdEV4Y2VwdGlvbiAmJiAhaXNCbG9ja2luZygpKSB7CisgICAgICAgICAgICAgICAgc3RhdHVzID0gU09DS0VUX1NUQVRVU19QRU5ESU5HOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAoaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgZmluaXNoZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGlzQmxvY2tpbmcoKSkgeworICAgICAgICAgICAgICAgIGVuZChmaW5pc2hlZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpbml0TG9jYWxBZGRyZXNzQW5kUG9ydCgpOworICAgICAgICBjb25uZWN0QWRkcmVzcyA9IGluZXRTb2NrZXRBZGRyZXNzOworICAgICAgICBpZiAoc29ja2V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNvY2tldC5zb2NrZXRJbXBsKCkuaW5pdFJlbW90ZUFkZHJlc3NBbmRQb3J0KGNvbm5lY3RBZGRyZXNzLmdldEFkZHJlc3MoKSwKKyAgICAgICAgICAgICAgICAgICAgY29ubmVjdEFkZHJlc3MuZ2V0UG9ydCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgaWYgKGlzQmxvY2tpbmcoKSkgeworICAgICAgICAgICAgICAgIHN0YXR1cyA9IChmaW5pc2hlZCA/IFNPQ0tFVF9TVEFUVVNfQ09OTkVDVEVEIDogU09DS0VUX1NUQVRVU19VTkNPTk5FQ1RFRCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHN0YXR1cyA9IFNPQ0tFVF9TVEFUVVNfUEVORElORzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmluaXNoZWQ7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGluaXRMb2NhbEFkZHJlc3NBbmRQb3J0KCkgeworICAgICAgICBTb2NrZXRBZGRyZXNzIHNhOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2EgPSBMaWJjb3JlLm9zLmdldHNvY2tuYW1lKGZkKTsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlcnJub0V4Y2VwdGlvbik7CisgICAgICAgIH0KKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgaXNhID0gKEluZXRTb2NrZXRBZGRyZXNzKSBzYTsKKyAgICAgICAgbG9jYWxBZGRyZXNzID0gaXNhLmdldEFkZHJlc3MoKTsKKyAgICAgICAgbG9jYWxQb3J0ID0gaXNhLmdldFBvcnQoKTsKKyAgICAgICAgaWYgKHNvY2tldCAhPSBudWxsKSB7CisgICAgICAgICAgICBzb2NrZXQuc29ja2V0SW1wbCgpLmluaXRMb2NhbFBvcnQobG9jYWxQb3J0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGZpbmlzaENvbm5lY3QoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGlmICghaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSBTT0NLRVRfU1RBVFVTX0NPTk5FQ1RFRCkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSBTT0NLRVRfU1RBVFVTX1BFTkRJTkcpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9Db25uZWN0aW9uUGVuZGluZ0V4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBmaW5pc2hlZCA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmVnaW4oKTsKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIGluZXRBZGRyZXNzID0gY29ubmVjdEFkZHJlc3MuZ2V0QWRkcmVzcygpOworICAgICAgICAgICAgaW50IHBvcnQgPSBjb25uZWN0QWRkcmVzcy5nZXRQb3J0KCk7CisgICAgICAgICAgICBmaW5pc2hlZCA9IElvQnJpZGdlLmlzQ29ubmVjdGVkKGZkLCBpbmV0QWRkcmVzcywgcG9ydCwgMCwgMCk7IC8vIFJldHVybiBpbW1lZGlhdGVseS4KKyAgICAgICAgICAgIGlzQm91bmQgPSBmaW5pc2hlZDsKKyAgICAgICAgfSBjYXRjaCAoQ29ubmVjdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAoaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICBjbG9zZSgpOworICAgICAgICAgICAgICAgIGZpbmlzaGVkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBlbmQoZmluaXNoZWQpOworICAgICAgICB9CisKKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICBzdGF0dXMgPSAoZmluaXNoZWQgPyBTT0NLRVRfU1RBVFVTX0NPTk5FQ1RFRCA6IHN0YXR1cyk7CisgICAgICAgICAgICBpc0JvdW5kID0gZmluaXNoZWQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZpbmlzaGVkOworICAgIH0KKworICAgIHZvaWQgZmluaXNoQWNjZXB0KCkgeworICAgICAgICBpbml0TG9jYWxBZGRyZXNzQW5kUG9ydCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChCeXRlQnVmZmVyIGRzdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZHN0LmNoZWNrV3JpdGFibGUoKTsKKyAgICAgICAgY2hlY2tPcGVuQ29ubmVjdGVkKCk7CisgICAgICAgIGlmICghZHN0Lmhhc1JlbWFpbmluZygpKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVhZEltcGwoZHN0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyByZWFkKEJ5dGVCdWZmZXJbXSB0YXJnZXRzLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudCh0YXJnZXRzLmxlbmd0aCwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICBjaGVja09wZW5Db25uZWN0ZWQoKTsKKyAgICAgICAgaW50IHRvdGFsQ291bnQgPSBGaWxlQ2hhbm5lbEltcGwuY2FsY3VsYXRlVG90YWxSZW1haW5pbmcodGFyZ2V0cywgb2Zmc2V0LCBsZW5ndGgsIHRydWUpOworICAgICAgICBpZiAodG90YWxDb3VudCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gcmVhZEFycmF5ID0gbmV3IGJ5dGVbdG90YWxDb3VudF07CisgICAgICAgIEJ5dGVCdWZmZXIgcmVhZEJ1ZmZlciA9IEJ5dGVCdWZmZXIud3JhcChyZWFkQXJyYXkpOworICAgICAgICBpbnQgcmVhZENvdW50OworICAgICAgICAvLyByZWFkIGRhdGEgdG8gcmVhZEJ1ZmZlciwgYW5kIHRoZW4gdHJhbnNmZXIgZGF0YSBmcm9tIHJlYWRCdWZmZXIgdG8gdGFyZ2V0cy4KKyAgICAgICAgcmVhZENvdW50ID0gcmVhZEltcGwocmVhZEJ1ZmZlcik7CisgICAgICAgIHJlYWRCdWZmZXIuZmxpcCgpOworICAgICAgICBpZiAocmVhZENvdW50ID4gMCkgeworICAgICAgICAgICAgaW50IGxlZnQgPSByZWFkQ291bnQ7CisgICAgICAgICAgICBpbnQgaW5kZXggPSBvZmZzZXQ7CisgICAgICAgICAgICAvLyB0cmFuc2ZlciBkYXRhIGZyb20gcmVhZEFycmF5IHRvIHRhcmdldHMKKyAgICAgICAgICAgIHdoaWxlIChsZWZ0ID4gMCkgeworICAgICAgICAgICAgICAgIGludCBwdXRMZW5ndGggPSBNYXRoLm1pbih0YXJnZXRzW2luZGV4XS5yZW1haW5pbmcoKSwgbGVmdCk7CisgICAgICAgICAgICAgICAgdGFyZ2V0c1tpbmRleF0ucHV0KHJlYWRBcnJheSwgcmVhZENvdW50IC0gbGVmdCwgcHV0TGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBpbmRleCsrOworICAgICAgICAgICAgICAgIGxlZnQgLT0gcHV0TGVuZ3RoOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZWFkQ291bnQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgcmVhZEltcGwoQnl0ZUJ1ZmZlciBkc3QpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAocmVhZExvY2spIHsKKyAgICAgICAgICAgIGludCByZWFkQ291bnQgPSAwOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAoaXNCbG9ja2luZygpKSB7CisgICAgICAgICAgICAgICAgICAgIGJlZ2luKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJlYWRDb3VudCA9IElvQnJpZGdlLnJlY3Zmcm9tKHRydWUsIGZkLCBkc3QsIDAsIG51bGwsIGZhbHNlKTsKKyAgICAgICAgICAgICAgICBpZiAocmVhZENvdW50ID4gMCkgeworICAgICAgICAgICAgICAgICAgICBkc3QucG9zaXRpb24oZHN0LnBvc2l0aW9uKCkgKyByZWFkQ291bnQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgaWYgKGlzQmxvY2tpbmcoKSkgeworICAgICAgICAgICAgICAgICAgICBlbmQocmVhZENvdW50ID4gMCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJlYWRDb3VudDsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgd3JpdGUoQnl0ZUJ1ZmZlciBzcmMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzcmMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tPcGVuQ29ubmVjdGVkKCk7CisgICAgICAgIGlmICghc3JjLmhhc1JlbWFpbmluZygpKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gd3JpdGVJbXBsKHNyYyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgd3JpdGUoQnl0ZUJ1ZmZlcltdIHNvdXJjZXMsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KHNvdXJjZXMubGVuZ3RoLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIGNoZWNrT3BlbkNvbm5lY3RlZCgpOworICAgICAgICBpbnQgY291bnQgPSBGaWxlQ2hhbm5lbEltcGwuY2FsY3VsYXRlVG90YWxSZW1haW5pbmcoc291cmNlcywgb2Zmc2V0LCBsZW5ndGgsIGZhbHNlKTsKKyAgICAgICAgaWYgKGNvdW50ID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIEJ5dGVCdWZmZXIgd3JpdGVCdWYgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKGNvdW50KTsKKyAgICAgICAgZm9yIChpbnQgdmFsID0gb2Zmc2V0OyB2YWwgPCBsZW5ndGggKyBvZmZzZXQ7IHZhbCsrKSB7CisgICAgICAgICAgICBCeXRlQnVmZmVyIHNvdXJjZSA9IHNvdXJjZXNbdmFsXTsKKyAgICAgICAgICAgIGludCBvbGRQb3NpdGlvbiA9IHNvdXJjZS5wb3NpdGlvbigpOworICAgICAgICAgICAgd3JpdGVCdWYucHV0KHNvdXJjZSk7CisgICAgICAgICAgICBzb3VyY2UucG9zaXRpb24ob2xkUG9zaXRpb24pOworICAgICAgICB9CisgICAgICAgIHdyaXRlQnVmLmZsaXAoKTsKKyAgICAgICAgaW50IHJlc3VsdCA9IHdyaXRlSW1wbCh3cml0ZUJ1Zik7CisgICAgICAgIGludCB2YWwgPSBvZmZzZXQ7CisgICAgICAgIGludCB3cml0dGVuID0gcmVzdWx0OworICAgICAgICB3aGlsZSAocmVzdWx0ID4gMCkgeworICAgICAgICAgICAgQnl0ZUJ1ZmZlciBzb3VyY2UgPSBzb3VyY2VzW3ZhbF07CisgICAgICAgICAgICBpbnQgZ2FwID0gTWF0aC5taW4ocmVzdWx0LCBzb3VyY2UucmVtYWluaW5nKCkpOworICAgICAgICAgICAgc291cmNlLnBvc2l0aW9uKHNvdXJjZS5wb3NpdGlvbigpICsgZ2FwKTsKKyAgICAgICAgICAgIHZhbCsrOworICAgICAgICAgICAgcmVzdWx0IC09IGdhcDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gd3JpdHRlbjsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCB3cml0ZUltcGwoQnl0ZUJ1ZmZlciBzcmMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAod3JpdGVMb2NrKSB7CisgICAgICAgICAgICBpZiAoIXNyYy5oYXNSZW1haW5pbmcoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHdyaXRlQ291bnQgPSAwOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAoaXNCbG9ja2luZygpKSB7CisgICAgICAgICAgICAgICAgICAgIGJlZ2luKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHdyaXRlQ291bnQgPSBJb0JyaWRnZS5zZW5kdG8oZmQsIHNyYywgMCwgbnVsbCwgMCk7CisgICAgICAgICAgICAgICAgaWYgKHdyaXRlQ291bnQgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIHNyYy5wb3NpdGlvbihzcmMucG9zaXRpb24oKSArIHdyaXRlQ291bnQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgaWYgKGlzQmxvY2tpbmcoKSkgeworICAgICAgICAgICAgICAgICAgICBlbmQod3JpdGVDb3VudCA+PSAwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gd3JpdGVDb3VudDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogU3RhdHVzIGNoZWNrLCBvcGVuIGFuZCAiY29ubmVjdGVkIiwgd2hlbiByZWFkIGFuZCB3cml0ZS4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgcHJpdmF0ZSB2b2lkIGNoZWNrT3BlbkNvbm5lY3RlZCgpIHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc09wZW4oKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENsb3NlZENoYW5uZWxFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIWlzQ29ubmVjdGVkKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb3RZZXRDb25uZWN0ZWRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogU3RhdHVzIGNoZWNrLCBvcGVuIGFuZCAidW5jb25uZWN0ZWQiLCBiZWZvcmUgY29ubmVjdGlvbi4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgcHJpdmF0ZSB2b2lkIGNoZWNrVW5jb25uZWN0ZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIWlzT3BlbigpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChzdGF0dXMgPT0gU09DS0VUX1NUQVRVU19DT05ORUNURUQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBbHJlYWR5Q29ubmVjdGVkRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHN0YXR1cyA9PSBTT0NLRVRfU1RBVFVTX1BFTkRJTkcpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDb25uZWN0aW9uUGVuZGluZ0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBTaGFyZWQgYnkgdGhpcyBjbGFzcyBhbmQgRGF0YWdyYW1DaGFubmVsSW1wbCwgdG8gZG8gdGhlIGFkZHJlc3MgdHJhbnNmZXIKKyAgICAgKiBhbmQgY2hlY2suCisgICAgICovCisgICAgc3RhdGljIEluZXRTb2NrZXRBZGRyZXNzIHZhbGlkYXRlQWRkcmVzcyhTb2NrZXRBZGRyZXNzIHNvY2tldEFkZHJlc3MpIHsKKyAgICAgICAgaWYgKHNvY2tldEFkZHJlc3MgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmICghKHNvY2tldEFkZHJlc3MgaW5zdGFuY2VvZiBJbmV0U29ja2V0QWRkcmVzcykpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEFkZHJlc3NUeXBlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgaW5ldFNvY2tldEFkZHJlc3MgPSAoSW5ldFNvY2tldEFkZHJlc3MpIHNvY2tldEFkZHJlc3M7CisgICAgICAgIGlmIChpbmV0U29ja2V0QWRkcmVzcy5pc1VucmVzb2x2ZWQoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVucmVzb2x2ZWRBZGRyZXNzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGluZXRTb2NrZXRBZGRyZXNzOworICAgIH0KKworICAgIC8qCisgICAgICogR2V0IGxvY2FsIGFkZHJlc3MuCisgICAgICovCisgICAgcHVibGljIEluZXRBZGRyZXNzIGdldExvY2FsQWRkcmVzcygpIHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBpc0JvdW5kID8gbG9jYWxBZGRyZXNzIDogSW5ldDRBZGRyZXNzLkFOWTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIERvIHJlYWxseSBjbG9zaW5nIGFjdGlvbiBoZXJlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBzeW5jaHJvbml6ZWQgdm9pZCBpbXBsQ2xvc2VTZWxlY3RhYmxlQ2hhbm5lbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzdGF0dXMgIT0gU09DS0VUX1NUQVRVU19DTE9TRUQpIHsKKyAgICAgICAgICAgIHN0YXR1cyA9IFNPQ0tFVF9TVEFUVVNfQ0xPU0VEOworICAgICAgICAgICAgaWYgKHNvY2tldCAhPSBudWxsICYmICFzb2NrZXQuaXNDbG9zZWQoKSkgeworICAgICAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBJb0JyaWRnZS5jbG9zZVNvY2tldChmZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgaW1wbENvbmZpZ3VyZUJsb2NraW5nKGJvb2xlYW4gYmxvY2tpbmcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAoYmxvY2tpbmdMb2NrKCkpIHsKKyAgICAgICAgICAgIElvVXRpbHMuc2V0QmxvY2tpbmcoZmQsIGJsb2NraW5nKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogR2V0IHRoZSBmZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3IgZ2V0RkQoKSB7CisgICAgICAgIHJldHVybiBmZDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEFkYXB0ZXIgY2xhc3NlcyBmb3IgaW50ZXJuYWwgc29ja2V0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFNvY2tldEFkYXB0ZXIgZXh0ZW5kcyBTb2NrZXQgeworICAgICAgICBwcml2YXRlIGZpbmFsIFNvY2tldENoYW5uZWxJbXBsIGNoYW5uZWw7CisgICAgICAgIHByaXZhdGUgZmluYWwgUGxhaW5Tb2NrZXRJbXBsIHNvY2tldEltcGw7CisKKyAgICAgICAgU29ja2V0QWRhcHRlcihQbGFpblNvY2tldEltcGwgc29ja2V0SW1wbCwgU29ja2V0Q2hhbm5lbEltcGwgY2hhbm5lbCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcihzb2NrZXRJbXBsKTsKKyAgICAgICAgICAgIHRoaXMuc29ja2V0SW1wbCA9IHNvY2tldEltcGw7CisgICAgICAgICAgICB0aGlzLmNoYW5uZWwgPSBjaGFubmVsOworICAgICAgICAgICAgU29ja2V0VXRpbHMuc2V0Q3JlYXRlZCh0aGlzKTsKKyAgICAgICAgfQorCisgICAgICAgIFBsYWluU29ja2V0SW1wbCBzb2NrZXRJbXBsKCkgeworICAgICAgICAgICAgcmV0dXJuIHNvY2tldEltcGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFNvY2tldENoYW5uZWwgZ2V0Q2hhbm5lbCgpIHsKKyAgICAgICAgICAgIHJldHVybiBjaGFubmVsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzQm91bmQoKSB7CisgICAgICAgICAgICByZXR1cm4gY2hhbm5lbC5pc0JvdW5kOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzQ29ubmVjdGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIGNoYW5uZWwuaXNDb25uZWN0ZWQoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgSW5ldEFkZHJlc3MgZ2V0TG9jYWxBZGRyZXNzKCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY2hhbm5lbC5nZXRMb2NhbEFkZHJlc3MoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFVua25vd25Ib3N0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjb25uZWN0KFNvY2tldEFkZHJlc3MgcmVtb3RlQWRkciwgaW50IHRpbWVvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoIWNoYW5uZWwuaXNCbG9ja2luZygpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RlZCgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFscmVhZHlDb25uZWN0ZWRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHN1cGVyLmNvbm5lY3QocmVtb3RlQWRkciwgdGltZW91dCk7CisgICAgICAgICAgICBjaGFubmVsLmluaXRMb2NhbEFkZHJlc3NBbmRQb3J0KCk7CisgICAgICAgICAgICBpZiAoc3VwZXIuaXNDb25uZWN0ZWQoKSkgeworICAgICAgICAgICAgICAgIGNoYW5uZWwuc2V0Q29ubmVjdGVkKCk7CisgICAgICAgICAgICAgICAgY2hhbm5lbC5pc0JvdW5kID0gc3VwZXIuaXNCb3VuZCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGJpbmQoU29ja2V0QWRkcmVzcyBsb2NhbEFkZHIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoY2hhbm5lbC5pc0Nvbm5lY3RlZCgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFscmVhZHlDb25uZWN0ZWRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChTb2NrZXRDaGFubmVsSW1wbC5TT0NLRVRfU1RBVFVTX1BFTkRJTkcgPT0gY2hhbm5lbC5zdGF0dXMpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29ubmVjdGlvblBlbmRpbmdFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHN1cGVyLmJpbmQobG9jYWxBZGRyKTsKKyAgICAgICAgICAgIGNoYW5uZWwuaW5pdExvY2FsQWRkcmVzc0FuZFBvcnQoKTsKKyAgICAgICAgICAgIGNoYW5uZWwuaXNCb3VuZCA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgc3luY2hyb25pemVkIChjaGFubmVsKSB7CisgICAgICAgICAgICAgICAgaWYgKGNoYW5uZWwuaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgY2hhbm5lbC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHN1cGVyLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNoYW5uZWwuc3RhdHVzID0gU29ja2V0Q2hhbm5lbEltcGwuU09DS0VUX1NUQVRVU19DTE9TRUQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgY2hlY2tPcGVuQW5kQ29ubmVjdGVkKCk7CisgICAgICAgICAgICBpZiAoaXNPdXRwdXRTaHV0ZG93bigpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbigiU29ja2V0IG91dHB1dCBpcyBzaHV0ZG93biIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBTb2NrZXRDaGFubmVsT3V0cHV0U3RyZWFtKGNoYW5uZWwpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBjaGVja09wZW5BbmRDb25uZWN0ZWQoKTsKKyAgICAgICAgICAgIGlmIChpc0lucHV0U2h1dGRvd24oKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oIlNvY2tldCBpbnB1dCBpcyBzaHV0ZG93biIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBTb2NrZXRDaGFubmVsSW5wdXRTdHJlYW0oY2hhbm5lbCk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgY2hlY2tPcGVuQW5kQ29ubmVjdGVkKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoIWNoYW5uZWwuaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKCJTb2NrZXQgaXMgY2xvc2VkIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIWNoYW5uZWwuaXNDb25uZWN0ZWQoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oIlNvY2tldCBpcyBub3QgY29ubmVjdGVkIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIEZpbGVEZXNjcmlwdG9yIGdldEZpbGVEZXNjcmlwdG9yJCgpIHsKKyAgICAgICAgICAgIHJldHVybiBzb2NrZXRJbXBsLmdldEZEJCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUaGlzIG91dHB1dCBzdHJlYW0gZGVsZWdhdGVzIGFsbCBvcGVyYXRpb25zIHRvIHRoZSBhc3NvY2lhdGVkIGNoYW5uZWwuCisgICAgICogVGhyb3dzIGFuIElsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb24gaWYgdGhlIGNoYW5uZWwgaXMgaW4gbm9uLWJsb2NraW5nCisgICAgICogbW9kZSB3aGVuIHBlcmZvcm1pbmcgd3JpdGUgb3BlcmF0aW9ucy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTb2NrZXRDaGFubmVsT3V0cHV0U3RyZWFtIGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTb2NrZXRDaGFubmVsIGNoYW5uZWw7CisKKyAgICAgICAgcHVibGljIFNvY2tldENoYW5uZWxPdXRwdXRTdHJlYW0oU29ja2V0Q2hhbm5lbCBjaGFubmVsKSB7CisgICAgICAgICAgICB0aGlzLmNoYW5uZWwgPSBjaGFubmVsOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogQ2xvc2VzIHRoaXMgc3RyZWFtIGFuZCBjaGFubmVsLgorICAgICAgICAgKgorICAgICAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uIHRocm93biBpZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIHRoZSBjbG9zZQorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICAgICAgQnl0ZUJ1ZmZlciBidWYgPSBCeXRlQnVmZmVyLndyYXAoYnVmZmVyLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgICAgICBpZiAoIWNoYW5uZWwuaXNCbG9ja2luZygpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNoYW5uZWwud3JpdGUoYnVmKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgb25lQnl0ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmICghY2hhbm5lbC5pc0Jsb2NraW5nKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQnl0ZUJ1ZmZlciBidWZmZXIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEpOworICAgICAgICAgICAgYnVmZmVyLnB1dCgwLCAoYnl0ZSkgKG9uZUJ5dGUgJiAweEZGKSk7CisgICAgICAgICAgICBjaGFubmVsLndyaXRlKGJ1ZmZlcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFRoaXMgaW5wdXQgc3RyZWFtIGRlbGVnYXRlcyBhbGwgb3BlcmF0aW9ucyB0byB0aGUgYXNzb2NpYXRlZCBjaGFubmVsLgorICAgICAqIFRocm93cyBhbiBJbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uIGlmIHRoZSBjaGFubmVsIGlzIGluIG5vbi1ibG9ja2luZworICAgICAqIG1vZGUgd2hlbiBwZXJmb3JtaW5nIHJlYWQgb3BlcmF0aW9ucy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTb2NrZXRDaGFubmVsSW5wdXRTdHJlYW0gZXh0ZW5kcyBJbnB1dFN0cmVhbSB7CisgICAgICAgIHByaXZhdGUgZmluYWwgU29ja2V0Q2hhbm5lbCBjaGFubmVsOworCisgICAgICAgIHB1YmxpYyBTb2NrZXRDaGFubmVsSW5wdXRTdHJlYW0oU29ja2V0Q2hhbm5lbCBjaGFubmVsKSB7CisgICAgICAgICAgICB0aGlzLmNoYW5uZWwgPSBjaGFubmVsOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogQ2xvc2VzIHRoaXMgc3RyZWFtIGFuZCBjaGFubmVsLgorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaWYgKCFjaGFubmVsLmlzQmxvY2tpbmcoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBCeXRlQnVmZmVyIGJ1ZiA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMSk7CisgICAgICAgICAgICBpbnQgcmVzdWx0ID0gY2hhbm5lbC5yZWFkKGJ1Zik7CisgICAgICAgICAgICByZXR1cm4gKHJlc3VsdCA9PSAtMSkgPyByZXN1bHQgOiAoYnVmLmdldCgwKSAmIDB4ZmYpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICAgICAgaWYgKCFjaGFubmVsLmlzQmxvY2tpbmcoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBCeXRlQnVmZmVyIGJ1ZiA9IEJ5dGVCdWZmZXIud3JhcChidWZmZXIsIG9mZnNldCwgYnl0ZUNvdW50KTsKKyAgICAgICAgICAgIHJldHVybiBjaGFubmVsLnJlYWQoYnVmKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9BbHJlYWR5Q29ubmVjdGVkRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvQWxyZWFkeUNvbm5lY3RlZEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRmYTVhZjgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvQWxyZWFkeUNvbm5lY3RlZEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzIgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhbm5lbHM7CisKKy8qKgorICogQW4ge0Bjb2RlIEFscmVhZHlDb25uZWN0ZWRFeGNlcHRpb259IGlzIHRocm93biB3aGVuIGFuIGF0dGVtcHQgaXMgbWFkZSB0bworICogY29ubmVjdCBhIFNvY2tldENoYW5uZWwgdGhhdCBpcyBhbHJlYWR5IGNvbm5lY3RlZC4KKyAqLworcHVibGljIGNsYXNzIEFscmVhZHlDb25uZWN0ZWRFeGNlcHRpb24gZXh0ZW5kcyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTczMzE4OTUyNDUwNTM3NzMzNTdMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiB7QGNvZGUgQWxyZWFkeUNvbm5lY3RlZEV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIEFscmVhZHlDb25uZWN0ZWRFeGNlcHRpb24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0FzeW5jaHJvbm91c0Nsb3NlRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NmFhZTBiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0FzeW5jaHJvbm91c0Nsb3NlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzMiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFubmVsczsKKworLyoqCisgKiBBbiB7QGNvZGUgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb259IGlzIHRocm93biB3aGVuIHRoZSB1bmRlcmx5aW5nIGNoYW5uZWwKKyAqIGZvciBhbiBJL08gb3BlcmF0aW9uIGlzIGNsb3NlZCBieSBhbm90aGVyIHRocmVhZC4KKyAqLworcHVibGljIGNsYXNzIEFzeW5jaHJvbm91c0Nsb3NlRXhjZXB0aW9uIGV4dGVuZHMgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA2ODkxMTc4MzEyNDMyMzEzOTY2TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4ge0Bjb2RlIEFzeW5jaHJvbm91c0Nsb3NlRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0J5dGVDaGFubmVsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvQnl0ZUNoYW5uZWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MzI2OTVkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0J5dGVDaGFubmVsLmphdmEKQEAgLTAsMCArMSwzMCBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFubmVsczsKKworLyoqCisgKiBBIEJ5dGVDaGFubmVsIGlzIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLgorICogPHA+CisgKiBUaGUgbWV0aG9kcyBmb3IgdGhlIGJ5dGUgY2hhbm5lbCBhcmUgcHJlY2lzZWx5IHRob3NlIGRlZmluZWQgYnkgcmVhZGFibGUgYW5kCisgKiB3cml0YWJsZSBieXRlIGNoYW5uZWxzLgorICoKKyAqIEBzZWUgUmVhZGFibGVCeXRlQ2hhbm5lbAorICogQHNlZSBXcml0YWJsZUJ5dGVDaGFubmVsCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQnl0ZUNoYW5uZWwgZXh0ZW5kcyBSZWFkYWJsZUJ5dGVDaGFubmVsLCBXcml0YWJsZUJ5dGVDaGFubmVsIHsKKyAgICAvLyBObyBtZXRob2RzIGRlZmluZWQuCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvQ2FuY2VsbGVkS2V5RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvQ2FuY2VsbGVkS2V5RXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGNhMmQ5NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9DYW5jZWxsZWRLZXlFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDM1IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYW5uZWxzOworCisvKioKKyAqIEEge0Bjb2RlIENhbmNlbGxlZEtleUV4Y2VwdGlvbn0gaXMgdGhyb3duIHdoZW4gYW4gaW52YWxpZCBzZWxlY3Rpb24ga2V5IGlzCisgKiB1c2VkLgorICovCitwdWJsaWMgY2xhc3MgQ2FuY2VsbGVkS2V5RXhjZXB0aW9uIGV4dGVuZHMgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHsKKworICAgIC8qKgorICAgICAqIFZlcnNpb24gSUQgZm9yIHNlcmlhbGl6YXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTg0MzgwMzIxMzgwMjg4MTQyNjhMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBDYW5jZWxsZWRLZXlFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBDYW5jZWxsZWRLZXlFeGNlcHRpb24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0NoYW5uZWwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9DaGFubmVsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTJjMTNiNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9DaGFubmVsLmphdmEKQEAgLTAsMCArMSw1NyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFubmVsczsKKworaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogQSBjaGFubmVsIGlzIGEgY29uZHVpdCB0byBJL08gc2VydmljZXMgY292ZXJpbmcgc3VjaCBpdGVtcyBhcyBmaWxlcywgc29ja2V0cywKKyAqIGhhcmR3YXJlIGRldmljZXMsIEkvTyBwb3J0cyBvciBzb21lIHNvZnR3YXJlIGNvbXBvbmVudC4KKyAqIDxwPgorICogQ2hhbm5lbHMgYXJlIG9wZW4gdXBvbiBjcmVhdGlvbiwgYW5kIGNhbiBiZSBjbG9zZWQgZXhwbGljaXRseS4gT25jZSBhIGNoYW5uZWwKKyAqIGlzIGNsb3NlZCBpdCBjYW5ub3QgYmUgcmUtb3BlbmVkLCBhbmQgYW55IGF0dGVtcHRzIHRvIHBlcmZvcm0gSS9PIG9wZXJhdGlvbnMKKyAqIG9uIHRoZSBjbG9zZWQgY2hhbm5lbCByZXN1bHQgaW4gYSA8Y29kZT5DbG9zZWRDaGFubmVsRXhjZXB0aW9uPC9jb2RlPi4KKyAqIDxwPgorICogUGFydGljdWxhciBpbXBsZW1lbnRhdGlvbnMgb3Igc3ViLWludGVyZmFjZXMgb2Yge0Bjb2RlIENoYW5uZWx9IGRpY3RhdGUKKyAqIHdoZXRoZXIgdGhleSBhcmUgdGhyZWFkLXNhZmUgb3Igbm90LgorICovCitwdWJsaWMgaW50ZXJmYWNlIENoYW5uZWwgZXh0ZW5kcyBDbG9zZWFibGUgeworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgY2hhbm5lbCBpcyBvcGVuLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzT3BlbigpOworCisgICAgLyoqCisgICAgICogQ2xvc2VzIGFuIG9wZW4gY2hhbm5lbC4gSWYgdGhlIGNoYW5uZWwgaXMgYWxyZWFkeSBjbG9zZWQgdGhlbiB0aGlzIG1ldGhvZAorICAgICAqIGhhcyBubyBlZmZlY3QuIElmIHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIGNsb3NpbmcgdGhlIGNoYW5uZWwgdGhlbiB0aGUKKyAgICAgKiBtZXRob2QgdGhyb3dzIGFuIElPRXhjZXB0aW9uIGFuZCB0aGUgZXhjZXB0aW9uIGNvbnRhaW5zIHJlYXNvbnMgZm9yIHRoZQorICAgICAqIGZhaWx1cmUuCisgICAgICogPHA+CisgICAgICogSWYgYW4gYXR0ZW1wdCBpcyBtYWRlIHRvIHBlcmZvcm0gYW4gb3BlcmF0aW9uIG9uIGEgY2xvc2VkIGNoYW5uZWwgdGhlbiBhCisgICAgICoge0BsaW5rIENsb3NlZENoYW5uZWxFeGNlcHRpb259IHdpbGwgYmUgdGhyb3duIG9uIHRoYXQgYXR0ZW1wdC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiBtdWx0aXBsZSB0aHJlYWRzIGF0dGVtcHQgdG8gc2ltdWx0YW5lb3VzbHkgY2xvc2UgYSBjaGFubmVsLCB0aGVuIG9ubHkKKyAgICAgKiBvbmUgdGhyZWFkIHdpbGwgcnVuIHRoZSBjbG9zdXJlIGNvZGUsIGFuZCBvdGhlcnMgd2lsbCBiZSBibG9ja2VkIHVudGlsCisgICAgICogdGhlIGZpcnN0IHJldHVybnMuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycyBjbG9zaW5nIHRoZSBjaGFubmVsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0NoYW5uZWxzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvQ2hhbm5lbHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYWYxNDY1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0NoYW5uZWxzLmphdmEKQEAgLTAsMCArMSwzNjAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhbm5lbHM7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLlJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLldyaXRlcjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLnNwaS5BYnN0cmFjdEludGVycnVwdGlibGVDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXREZWNvZGVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldEVuY29kZXI7CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworCisvKioKKyAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgc2V2ZXJhbCB1dGlsaXRpZXMgdG8gZ2V0IEkvTyBzdHJlYW1zIGZyb20gY2hhbm5lbHMuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBDaGFubmVscyB7CisKKyAgICBwcml2YXRlIENoYW5uZWxzKCkge30KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5wdXQgc3RyZWFtIG9uIHRoZSBnaXZlbiBjaGFubmVsLiBUaGUgcmVzdWx0aW5nIHN0cmVhbSBoYXMKKyAgICAgKiB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT5JZiB0aGUgc3RyZWFtIGlzIGNsb3NlZCwgdGhlbiB0aGUgdW5kZXJseWluZyBjaGFubmVsIGlzIGNsb3NlZCBhcworICAgICAqIHdlbGwuPC9saT4KKyAgICAgKiA8bGk+SXQgaXMgdGhyZWFkIHNhZmUuPC9saT4KKyAgICAgKiA8bGk+SXQgdGhyb3dzIGFuIHtAbGluayBJbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9ufSBpZiB0aGUgY2hhbm5lbCBpcworICAgICAqIGluIG5vbi1ibG9ja2luZyBtb2RlIGFuZCB7QGNvZGUgcmVhZH0gaXMgY2FsbGVkLjwvbGk+CisgICAgICogPGxpPk5laXRoZXIge0Bjb2RlIG1hcmt9IG5vciB7QGNvZGUgcmVzZXR9IGlzIHN1cHBvcnRlZC48L2xpPgorICAgICAqIDxsaT5JdCBpcyBub3QgYnVmZmVyZWQuPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIGNoYW5uZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFubmVsIHRvIGJlIHdyYXBwZWQgYnkgYW4gSW5wdXRTdHJlYW0uCisgICAgICogQHJldHVybiBhbiBJbnB1dFN0cmVhbSB0aGF0IHRha2VzIGJ5dGVzIGZyb20gdGhlIGdpdmVuIGJ5dGUgY2hhbm5lbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIElucHV0U3RyZWFtIG5ld0lucHV0U3RyZWFtKFJlYWRhYmxlQnl0ZUNoYW5uZWwgY2hhbm5lbCkgeworICAgICAgICByZXR1cm4gbmV3IENoYW5uZWxJbnB1dFN0cmVhbShjaGFubmVsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIG91dHB1dCBzdHJlYW0gb24gdGhlIGdpdmVuIGNoYW5uZWwuIFRoZSByZXN1bHRpbmcgc3RyZWFtIGhhcworICAgICAqIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPklmIHRoZSBzdHJlYW0gaXMgY2xvc2VkLCB0aGVuIHRoZSB1bmRlcmx5aW5nIGNoYW5uZWwgaXMgY2xvc2VkIGFzCisgICAgICogd2VsbC48L2xpPgorICAgICAqIDxsaT5JdCBpcyB0aHJlYWQgc2FmZS48L2xpPgorICAgICAqIDxsaT5JdCB0aHJvd3MgYW4ge0BsaW5rIElsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb259IGlmIHRoZSBjaGFubmVsIGlzCisgICAgICogaW4gbm9uLWJsb2NraW5nIG1vZGUgYW5kIHtAY29kZSB3cml0ZX0gaXMgY2FsbGVkLjwvbGk+CisgICAgICogPGxpPkl0IGlzIG5vdCBidWZmZXJlZC48L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhbm5lbAorICAgICAqICAgICAgICAgICAgdGhlIGNoYW5uZWwgdG8gYmUgd3JhcHBlZCBieSBhbiBPdXRwdXRTdHJlYW0uCisgICAgICogQHJldHVybiBhbiBPdXRwdXRTdHJlYW0gdGhhdCBwdXRzIGJ5dGVzIG9udG8gdGhlIGdpdmVuIGJ5dGUgY2hhbm5lbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIE91dHB1dFN0cmVhbSBuZXdPdXRwdXRTdHJlYW0oV3JpdGFibGVCeXRlQ2hhbm5lbCBjaGFubmVsKSB7CisgICAgICAgIHJldHVybiBuZXcgQ2hhbm5lbE91dHB1dFN0cmVhbShjaGFubmVsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcmVhZGFibGUgY2hhbm5lbCBvbiB0aGUgZ2l2ZW4gaW5wdXQgc3RyZWFtLiBUaGUgcmVzdWx0aW5nCisgICAgICogY2hhbm5lbCBoYXMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+SWYgdGhlIGNoYW5uZWwgaXMgY2xvc2VkLCB0aGVuIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBpcyBjbG9zZWQgYXMKKyAgICAgKiB3ZWxsLjwvbGk+CisgICAgICogPGxpPkl0IGlzIG5vdCBidWZmZXJlZC48L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXRTdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJlYW0gdG8gYmUgd3JhcHBlZCBieSBhIGJ5dGUgY2hhbm5lbC4KKyAgICAgKiBAcmV0dXJuIGEgYnl0ZSBjaGFubmVsIHRoYXQgcmVhZHMgYnl0ZXMgZnJvbSB0aGUgaW5wdXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUmVhZGFibGVCeXRlQ2hhbm5lbCBuZXdDaGFubmVsKElucHV0U3RyZWFtIGlucHV0U3RyZWFtKSB7CisgICAgICAgIHJldHVybiBuZXcgSW5wdXRTdHJlYW1DaGFubmVsKGlucHV0U3RyZWFtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgd3JpdGFibGUgY2hhbm5lbCBvbiB0aGUgZ2l2ZW4gb3V0cHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIFRoZSByZXN1bHRpbmcgY2hhbm5lbCBoYXMgZm9sbG93aW5nIHByb3BlcnRpZXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT5JZiB0aGUgY2hhbm5lbCBpcyBjbG9zZWQsIHRoZW4gdGhlIHVuZGVybHlpbmcgc3RyZWFtIGlzIGNsb3NlZCBhcworICAgICAqIHdlbGwuPC9saT4KKyAgICAgKiA8bGk+SXQgaXMgbm90IGJ1ZmZlcmVkLjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXRwdXRTdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJlYW0gdG8gYmUgd3JhcHBlZCBieSBhIGJ5dGUgY2hhbm5lbC4KKyAgICAgKiBAcmV0dXJuIGEgYnl0ZSBjaGFubmVsIHRoYXQgd3JpdGVzIGJ5dGVzIHRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgV3JpdGFibGVCeXRlQ2hhbm5lbCBuZXdDaGFubmVsKE91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0pIHsKKyAgICAgICAgcmV0dXJuIG5ldyBPdXRwdXRTdHJlYW1DaGFubmVsKG91dHB1dFN0cmVhbSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHJlYWRlciB0aGF0IGRlY29kZXMgYnl0ZXMgZnJvbSBhIGNoYW5uZWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhbm5lbAorICAgICAqICAgICAgICAgICAgdGhlIENoYW5uZWwgdG8gYmUgcmVhZC4KKyAgICAgKiBAcGFyYW0gZGVjb2RlcgorICAgICAqICAgICAgICAgICAgdGhlIENoYXJzZXQgZGVjb2RlciB0byBiZSB1c2VkLgorICAgICAqIEBwYXJhbSBtaW5CdWZmZXJDYXBhY2l0eQorICAgICAqICAgICAgICAgICAgVGhlIG1pbmltdW0gc2l6ZSBvZiB0aGUgYnl0ZSBidWZmZXIsIC0xIG1lYW5zIHRvIHVzZSB0aGUKKyAgICAgKiAgICAgICAgICAgIGRlZmF1bHQgc2l6ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSByZWFkZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBSZWFkZXIgbmV3UmVhZGVyKFJlYWRhYmxlQnl0ZUNoYW5uZWwgY2hhbm5lbCwKKyAgICAgICAgICAgIENoYXJzZXREZWNvZGVyIGRlY29kZXIsIGludCBtaW5CdWZmZXJDYXBhY2l0eSkgeworICAgICAgICAvKgorICAgICAgICAgKiBUaGlzIG1ldGhvZCBkb2Vzbid0IGhvbm9yIG1pbkJ1ZmZlckNhcGFjaXR5LiBJZ25vcmluZyB0aGF0IHBhcmFtZXRlcgorICAgICAgICAgKiBzYXZlcyB1cyBmcm9tIGhhdmluZyB0byBhZGQgYSBoaWRkZW4gY29uc3RydWN0b3IgdG8gSW5wdXRTdHJlYW1SZWFkZXIuCisgICAgICAgICAqLworICAgICAgICByZXR1cm4gbmV3IElucHV0U3RyZWFtUmVhZGVyKG5ldyBDaGFubmVsSW5wdXRTdHJlYW0oY2hhbm5lbCksIGRlY29kZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSByZWFkZXIgdGhhdCBkZWNvZGVzIGJ5dGVzIGZyb20gYSBjaGFubmVsLiBUaGlzIG1ldGhvZCBjcmVhdGVzIGEKKyAgICAgKiByZWFkZXIgd2l0aCBhIGJ1ZmZlciBvZiBkZWZhdWx0IHNpemUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhbm5lbAorICAgICAqICAgICAgICAgICAgdGhlIENoYW5uZWwgdG8gYmUgcmVhZC4KKyAgICAgKiBAcGFyYW0gY2hhcnNldE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjaGFyc2V0LgorICAgICAqIEByZXR1cm4gdGhlIHJlYWRlci4KKyAgICAgKiBAdGhyb3dzIGphdmEubmlvLmNoYXJzZXQuVW5zdXBwb3J0ZWRDaGFyc2V0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIGNoYXJzZXQgbmFtZSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUmVhZGVyIG5ld1JlYWRlcihSZWFkYWJsZUJ5dGVDaGFubmVsIGNoYW5uZWwsCisgICAgICAgICAgICBTdHJpbmcgY2hhcnNldE5hbWUpIHsKKyAgICAgICAgaWYgKGNoYXJzZXROYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXdSZWFkZXIoY2hhbm5lbCwgQ2hhcnNldC5mb3JOYW1lKGNoYXJzZXROYW1lKS5uZXdEZWNvZGVyKCksIC0xKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgd3JpdGVyIHRoYXQgZW5jb2RlcyBjaGFyYWN0ZXJzIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIHtAY29kZSBlbmNvZGVyfSBhbmQgc2VuZHMgdGhlIGJ5dGVzIHRvIHRoZSBzcGVjaWZpZWQgY2hhbm5lbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaGFubmVsCisgICAgICogICAgICAgICAgICB0aGUgQ2hhbm5lbCB0byB3cml0ZSB0by4KKyAgICAgKiBAcGFyYW0gZW5jb2RlcgorICAgICAqICAgICAgICAgICAgdGhlIENoYXJzZXRFbmNvZGVyIHRvIGJlIHVzZWQuCisgICAgICogQHBhcmFtIG1pbkJ1ZmZlckNhcGFjaXR5CisgICAgICogICAgICAgICAgICB0aGUgbWluaW11bSBzaXplIG9mIHRoZSBieXRlIGJ1ZmZlciwgLTEgbWVhbnMgdG8gdXNlIHRoZQorICAgICAqICAgICAgICAgICAgZGVmYXVsdCBzaXplLgorICAgICAqIEByZXR1cm4gdGhlIHdyaXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFdyaXRlciBuZXdXcml0ZXIoV3JpdGFibGVCeXRlQ2hhbm5lbCBjaGFubmVsLAorICAgICAgICAgICAgQ2hhcnNldEVuY29kZXIgZW5jb2RlciwgaW50IG1pbkJ1ZmZlckNhcGFjaXR5KSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFRoaXMgbWV0aG9kIGRvZXNuJ3QgaG9ub3IgbWluQnVmZmVyQ2FwYWNpdHkuIElnbm9yaW5nIHRoYXQgcGFyYW1ldGVyCisgICAgICAgICAqIHNhdmVzIHVzIGZyb20gaGF2aW5nIHRvIGFkZCBhIGhpZGRlbiBjb25zdHJ1Y3RvciB0byBPdXRwdXRTdHJlYW1Xcml0ZXIuCisgICAgICAgICAqLworICAgICAgICByZXR1cm4gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihuZXcgQ2hhbm5lbE91dHB1dFN0cmVhbShjaGFubmVsKSwgZW5jb2Rlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHdyaXRlciB0aGF0IGVuY29kZXMgY2hhcmFjdGVycyB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB7QGNvZGUgZW5jb2Rlcn0gYW5kIHNlbmRzIHRoZSBieXRlcyB0byB0aGUgc3BlY2lmaWVkIGNoYW5uZWwuIFRoaXMgbWV0aG9kCisgICAgICogY3JlYXRlcyBhIHdyaXRlciB3aXRoIGEgYnVmZmVyIG9mIGRlZmF1bHQgc2l6ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaGFubmVsCisgICAgICogICAgICAgICAgICB0aGUgQ2hhbm5lbCB0byBiZSB3cml0dGVuIHRvLgorICAgICAqIEBwYXJhbSBjaGFyc2V0TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNoYXJzZXQuCisgICAgICogQHJldHVybiB0aGUgd3JpdGVyLgorICAgICAqIEB0aHJvd3MgamF2YS5uaW8uY2hhcnNldC5VbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2l2ZW4gY2hhcnNldCBuYW1lIGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBXcml0ZXIgbmV3V3JpdGVyKFdyaXRhYmxlQnl0ZUNoYW5uZWwgY2hhbm5lbCwKKyAgICAgICAgICAgIFN0cmluZyBjaGFyc2V0TmFtZSkgeworICAgICAgICBpZiAoY2hhcnNldE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ld1dyaXRlcihjaGFubmVsLCBDaGFyc2V0LmZvck5hbWUoY2hhcnNldE5hbWUpLm5ld0VuY29kZXIoKSwgLTEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFuIGlucHV0IHN0cmVhbSB0aGF0IGRlbGVnYXRlcyB0byBhIHJlYWRhYmxlIGNoYW5uZWwuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQ2hhbm5lbElucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworCisgICAgICAgIHByaXZhdGUgZmluYWwgUmVhZGFibGVCeXRlQ2hhbm5lbCBjaGFubmVsOworCisgICAgICAgIENoYW5uZWxJbnB1dFN0cmVhbShSZWFkYWJsZUJ5dGVDaGFubmVsIGNoYW5uZWwpIHsKKyAgICAgICAgICAgIGlmIChjaGFubmVsID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHN5bmNocm9uaXplZCBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gU3RyZWFtcy5yZWFkU2luZ2xlQnl0ZSh0aGlzKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgc3luY2hyb25pemVkIGludCByZWFkKGJ5dGVbXSB0YXJnZXQsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBCeXRlQnVmZmVyIGJ1ZmZlciA9IEJ5dGVCdWZmZXIud3JhcCh0YXJnZXQsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgICAgIGNoZWNrQmxvY2tpbmcoY2hhbm5lbCk7CisgICAgICAgICAgICByZXR1cm4gY2hhbm5lbC5yZWFkKGJ1ZmZlcik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaWYgKGNoYW5uZWwgaW5zdGFuY2VvZiBGaWxlQ2hhbm5lbCkgeworICAgICAgICAgICAgICAgIEZpbGVDaGFubmVsIGZpbGVDaGFubmVsID0gKEZpbGVDaGFubmVsKSBjaGFubmVsOworICAgICAgICAgICAgICAgIGxvbmcgcmVzdWx0ID0gZmlsZUNoYW5uZWwuc2l6ZSgpIC0gZmlsZUNoYW5uZWwucG9zaXRpb24oKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID4gSW50ZWdlci5NQVhfVkFMVUUgPyBJbnRlZ2VyLk1BWF9WQUxVRSA6IChpbnQpIHJlc3VsdDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmF2YWlsYWJsZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBjaGFubmVsLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbiBvdXRwdXQgc3RyZWFtIHRoYXQgZGVsZWdhdGVzIHRvIGEgd3JpdGFibGUgY2hhbm5lbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBDaGFubmVsT3V0cHV0U3RyZWFtIGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKworICAgICAgICBwcml2YXRlIGZpbmFsIFdyaXRhYmxlQnl0ZUNoYW5uZWwgY2hhbm5lbDsKKworICAgICAgICBDaGFubmVsT3V0cHV0U3RyZWFtKFdyaXRhYmxlQnl0ZUNoYW5uZWwgY2hhbm5lbCkgeworICAgICAgICAgICAgaWYgKGNoYW5uZWwgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgd3JpdGUoaW50IG9uZUJ5dGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBieXRlW10gd3JhcHBlZEJ5dGUgPSB7IChieXRlKSBvbmVCeXRlIH07CisgICAgICAgICAgICB3cml0ZSh3cmFwcGVkQnl0ZSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHdyaXRlKGJ5dGVbXSBzb3VyY2UsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBCeXRlQnVmZmVyIGJ1ZmZlciA9IEJ5dGVCdWZmZXIud3JhcChzb3VyY2UsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgICAgIGNoZWNrQmxvY2tpbmcoY2hhbm5lbCk7CisgICAgICAgICAgICBpbnQgdG90YWwgPSAwOworICAgICAgICAgICAgd2hpbGUgKHRvdGFsIDwgbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgdG90YWwgKz0gY2hhbm5lbC53cml0ZShidWZmZXIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBjaGFubmVsLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBjaGVja0Jsb2NraW5nKENoYW5uZWwgY2hhbm5lbCkgeworICAgICAgICBpZiAoY2hhbm5lbCBpbnN0YW5jZW9mIFNlbGVjdGFibGVDaGFubmVsICYmICEoKFNlbGVjdGFibGVDaGFubmVsKSBjaGFubmVsKS5pc0Jsb2NraW5nKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBIHJlYWRhYmxlIGNoYW5uZWwgdGhhdCBkZWxlZ2F0ZXMgdG8gYW4gaW5wdXQgc3RyZWFtLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIElucHV0U3RyZWFtQ2hhbm5lbCBleHRlbmRzIEFic3RyYWN0SW50ZXJydXB0aWJsZUNoYW5uZWwKKyAgICAgICAgICAgIGltcGxlbWVudHMgUmVhZGFibGVCeXRlQ2hhbm5lbCB7CisgICAgICAgIHByaXZhdGUgZmluYWwgSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW07CisKKyAgICAgICAgSW5wdXRTdHJlYW1DaGFubmVsKElucHV0U3RyZWFtIGlucHV0U3RyZWFtKSB7CisgICAgICAgICAgICBpZiAoaW5wdXRTdHJlYW0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy5pbnB1dFN0cmVhbSA9IGlucHV0U3RyZWFtOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgcmVhZChCeXRlQnVmZmVyIHRhcmdldCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmICghaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IGJ5dGVzUmVtYWluID0gdGFyZ2V0LnJlbWFpbmluZygpOworICAgICAgICAgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbYnl0ZXNSZW1haW5dOworICAgICAgICAgICAgaW50IHJlYWRDb3VudCA9IDA7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGJlZ2luKCk7CisgICAgICAgICAgICAgICAgcmVhZENvdW50ID0gaW5wdXRTdHJlYW0ucmVhZChieXRlcyk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGVuZChyZWFkQ291bnQgPj0gMCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocmVhZENvdW50ID4gMCkgeworICAgICAgICAgICAgICAgIHRhcmdldC5wdXQoYnl0ZXMsIDAsIHJlYWRDb3VudCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVhZENvdW50OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGltcGxDbG9zZUNoYW5uZWwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaW5wdXRTdHJlYW0uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEEgd3JpdGFibGUgY2hhbm5lbCB0aGF0IGRlbGVnYXRlcyB0byBhbiBvdXRwdXQgc3RyZWFtLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIE91dHB1dFN0cmVhbUNoYW5uZWwgZXh0ZW5kcyBBYnN0cmFjdEludGVycnVwdGlibGVDaGFubmVsCisgICAgICAgICAgICBpbXBsZW1lbnRzIFdyaXRhYmxlQnl0ZUNoYW5uZWwgeworICAgICAgICBwcml2YXRlIGZpbmFsIE91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW07CisKKyAgICAgICAgT3V0cHV0U3RyZWFtQ2hhbm5lbChPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtKSB7CisgICAgICAgICAgICBpZiAob3V0cHV0U3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMub3V0cHV0U3RyZWFtID0gb3V0cHV0U3RyZWFtOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgd3JpdGUoQnl0ZUJ1ZmZlciBzb3VyY2UpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoIWlzT3BlbigpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb3NlZENoYW5uZWxFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBieXRlc1JlbWFpbiA9IHNvdXJjZS5yZW1haW5pbmcoKTsKKyAgICAgICAgICAgIGlmIChieXRlc1JlbWFpbiA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbYnl0ZXNSZW1haW5dOworICAgICAgICAgICAgc291cmNlLmdldChidWYpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBiZWdpbigpOworICAgICAgICAgICAgICAgIG91dHB1dFN0cmVhbS53cml0ZShidWYsIDAsIGJ5dGVzUmVtYWluKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgZW5kKGJ5dGVzUmVtYWluID49IDApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGJ5dGVzUmVtYWluOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGltcGxDbG9zZUNoYW5uZWwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgb3V0cHV0U3RyZWFtLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9DbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJkNjU5NmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDM2IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYW5uZWxzOworCisvKioKKyAqIEEge0Bjb2RlIENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9ufSBpcyB0aHJvd24gd2hlbiBhIHRocmVhZCBpcyBpbnRlcnJ1cHRlZAorICogaW4gYSBibG9ja2luZyBJL08gb3BlcmF0aW9uLgorICogPHA+CisgKiBXaGVuIHRoZSB0aHJlYWQgaXMgaW50ZXJydXB0ZWQgYnkgYSBjYWxsIHRvIHtAY29kZSBpbnRlcnJ1cHQoKX0sIGl0IGNsb3NlcworICogdGhlIGNoYW5uZWwsIHNldHMgdGhlIGludGVycnVwdCBzdGF0dXMgb2YgdGhlIHRocmVhZCB0byB7QGNvZGUgdHJ1ZX0gYW5kCisgKiB0aHJvd3MgYSB7QGNvZGUgQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb259LgorICovCitwdWJsaWMgY2xhc3MgQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24gZXh0ZW5kcyBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDQ4ODE5MTU0MzUzNDI4Njc1MEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0Nsb3NlZENoYW5uZWxFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9DbG9zZWRDaGFubmVsRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmQ3Y2QxOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9DbG9zZWRDaGFubmVsRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFubmVsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogQSB7QGNvZGUgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbn0gaXMgdGhyb3duIHdoZW4gYSBjaGFubmVsIGlzIGNsb3NlZCBmb3IgdGhlCisgKiB0eXBlIG9mIG9wZXJhdGlvbiBhdHRlbXB0ZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODgyNzc3MTg1NDMzNTUzODU3TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIENsb3NlZENoYW5uZWxFeGNlcHRpb24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0Nsb3NlZFNlbGVjdG9yRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvQ2xvc2VkU2VsZWN0b3JFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOTJlM2FmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0Nsb3NlZFNlbGVjdG9yRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzMiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFubmVsczsKKworLyoqCisgKiBBIHtAY29kZSBDbG9zZWRTZWxlY3RvckV4Y2VwdGlvbn0gaXMgdGhyb3duIHdoZW4gYSB7QGxpbmsgU2VsZWN0b3Igc2VsZWN0b3J9CisgKiBpcyBjbG9zZWQgYW5kIGFuIEkvTyBvcGVyYXRpb24gaXMgYXR0ZW1wdGVkLgorICovCitwdWJsaWMgY2xhc3MgQ2xvc2VkU2VsZWN0b3JFeGNlcHRpb24gZXh0ZW5kcyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjQ2NjI5NzEyMjMxNzg0NzgzNUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIENsb3NlZFNlbGVjdG9yRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xvc2VkU2VsZWN0b3JFeGNlcHRpb24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0Nvbm5lY3Rpb25QZW5kaW5nRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvQ29ubmVjdGlvblBlbmRpbmdFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZjY4NTg1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0Nvbm5lY3Rpb25QZW5kaW5nRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzMyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFubmVsczsKKworLyoqCisgKiBBIHtAY29kZSBDb25uZWN0aW9uUGVuZGluZ0V4Y2VwdGlvbn0gaXMgdGhyb3duIHdoZW4gYW4gYXR0ZW1wdCBpcyBtYWRlIHRvCisgKiBjb25uZWN0IGEge0BsaW5rIFNvY2tldENoYW5uZWx9IHRoYXQgaGFzIGEgbm9uLWJsb2NraW5nIGNvbm5lY3Rpb24gYWxyZWFkeQorICogdW5kZXJ3YXkuCisgKi8KK3B1YmxpYyBjbGFzcyBDb25uZWN0aW9uUGVuZGluZ0V4Y2VwdGlvbiBleHRlbmRzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAyMDA4MzkzMzY2NTAxNzYwODc5TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgQ29ubmVjdGlvblBlbmRpbmdFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBDb25uZWN0aW9uUGVuZGluZ0V4Y2VwdGlvbigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvRGF0YWdyYW1DaGFubmVsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvRGF0YWdyYW1DaGFubmVsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDg2YjE2OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9EYXRhZ3JhbUNoYW5uZWwuamF2YQpAQCAtMCwwICsxLDQyNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFubmVsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLnNwaS5BYnN0cmFjdFNlbGVjdGFibGVDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLnNwaS5TZWxlY3RvclByb3ZpZGVyOworCisvKioKKyAqIEEge0Bjb2RlIERhdGFncmFtQ2hhbm5lbH0gaXMgYSBzZWxlY3RhYmxlIGNoYW5uZWwgdGhhdCByZXByZXNlbnRzIGEgcGFydGlhbAorICogYWJzdHJhY3Rpb24gb2YgYSBkYXRhZ3JhbSBzb2NrZXQuIFRoZSB7QGNvZGUgc29ja2V0fSBtZXRob2Qgb2YgdGhpcyBjbGFzcyBjYW4KKyAqIHJldHVybiB0aGUgcmVsYXRlZCB7QGNvZGUgRGF0YWdyYW1Tb2NrZXR9IGluc3RhbmNlLCB3aGljaCBjYW4gaGFuZGxlIHRoZQorICogc29ja2V0LgorICogPHA+CisgKiBBIGRhdGFncmFtIGNoYW5uZWwgaXMgb3BlbiBidXQgbm90IGNvbm5lY3RlZCB3aGVuIGNyZWF0ZWQgd2l0aCB0aGUKKyAqIHtAY29kZSBvcGVuKCl9IG1ldGhvZC4gQWZ0ZXIgaXQgaXMgY29ubmVjdGVkLCBpdCB3aWxsIGtlZXAgdGhlIGNvbm5lY3RlZAorICogc3RhdHVzIHVudGlsIGl0IGlzIGRpc2Nvbm5lY3RlZCBvciBjbG9zZWQuIFRoZSBiZW5lZml0IG9mIGEgY29ubmVjdGVkIGNoYW5uZWwKKyAqIGlzIHRoZSByZWR1Y2VkIGVmZm9ydCBvZiBzZWN1cml0eSBjaGVja3MgZHVyaW5nIHNlbmQgYW5kIHJlY2VpdmUuIFdoZW4KKyAqIGludm9raW5nIHtAY29kZSByZWFkfSBvciB7QGNvZGUgd3JpdGV9LCBhIGNvbm5lY3RlZCBjaGFubmVsIGlzIHJlcXVpcmVkLgorICogPHA+CisgKiBEYXRhZ3JhbSBjaGFubmVscyBhcmUgdGhyZWFkLXNhZmU7IG9ubHkgb25lIHRocmVhZCBjYW4gcmVhZCBvciB3cml0ZSBhdCB0aGUKKyAqIHNhbWUgdGltZS4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIERhdGFncmFtQ2hhbm5lbCBleHRlbmRzIEFic3RyYWN0U2VsZWN0YWJsZUNoYW5uZWwKKyAgICAgICAgaW1wbGVtZW50cyBCeXRlQ2hhbm5lbCwgU2NhdHRlcmluZ0J5dGVDaGFubmVsLCBHYXRoZXJpbmdCeXRlQ2hhbm5lbCB7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBEYXRhZ3JhbUNoYW5uZWx9LgorICAgICAqCisgICAgICogQHBhcmFtIHNlbGVjdG9yUHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIGFuIGluc3RhbmNlIG9mIFNlbGVjdG9yUHJvdmlkZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIERhdGFncmFtQ2hhbm5lbChTZWxlY3RvclByb3ZpZGVyIHNlbGVjdG9yUHJvdmlkZXIpIHsKKyAgICAgICAgc3VwZXIoc2VsZWN0b3JQcm92aWRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBvcGVuZWQgYW5kIG5vdC1jb25uZWN0ZWQgZGF0YWdyYW0gY2hhbm5lbC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIGNoYW5uZWwgaXMgY3JlYXRlZCBieSBjYWxsaW5nIHRoZSA8Y29kZT5vcGVuRGF0YWdyYW1DaGFubmVsPC9jb2RlPgorICAgICAqIG1ldGhvZCBvZiB0aGUgZGVmYXVsdCB7QGxpbmsgU2VsZWN0b3JQcm92aWRlcn0gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgY2hhbm5lbCB3aGljaCBpcyBvcGVuIGJ1dCBub3QgY29ubmVjdGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBzb21lIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBEYXRhZ3JhbUNoYW5uZWwgb3BlbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBTZWxlY3RvclByb3ZpZGVyLnByb3ZpZGVyKCkub3BlbkRhdGFncmFtQ2hhbm5lbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbGlkIG9wZXJhdGlvbnMgb2YgdGhpcyBjaGFubmVsLiBEYXRhZ3JhbSBjaGFubmVscyBzdXBwb3J0IHJlYWQKKyAgICAgKiBhbmQgd3JpdGUgb3BlcmF0aW9ucywgc28gdGhpcyBtZXRob2QgcmV0dXJucyAoCisgICAgICogPGNvZGU+U2VsZWN0aW9uS2V5Lk9QX1JFQUQ8L2NvZGU+IHwgPGNvZGU+U2VsZWN0aW9uS2V5Lk9QX1dSSVRFPC9jb2RlPiApLgorICAgICAqCisgICAgICogQHNlZSBqYXZhLm5pby5jaGFubmVscy5TZWxlY3RhYmxlQ2hhbm5lbCN2YWxpZE9wcygpCisgICAgICogQHJldHVybiB2YWxpZCBvcGVyYXRpb25zIGluIGJpdC1zZXQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGludCB2YWxpZE9wcygpIHsKKyAgICAgICAgcmV0dXJuIChTZWxlY3Rpb25LZXkuT1BfUkVBRCB8IFNlbGVjdGlvbktleS5PUF9XUklURSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmVsYXRlZCBkYXRhZ3JhbSBzb2NrZXQgb2YgdGhpcyBjaGFubmVsLCB3aGljaCBkb2VzIG5vdAorICAgICAqIGRlZmluZSBhZGRpdGlvbmFsIHB1YmxpYyBtZXRob2RzIHRvIHRob3NlIGRlZmluZWQgYnkKKyAgICAgKiB7QGxpbmsgRGF0YWdyYW1Tb2NrZXR9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVsYXRlZCBEYXRhZ3JhbVNvY2tldCBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRGF0YWdyYW1Tb2NrZXQgc29ja2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBjaGFubmVsJ3Mgc29ja2V0IGlzIGNvbm5lY3RlZCBvciBub3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoaXMgY2hhbm5lbCdzIHNvY2tldCBpcyBjb25uZWN0ZWQ7CisgICAgICogICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzQ29ubmVjdGVkKCk7CisKKyAgICAvKioKKyAgICAgKiBDb25uZWN0cyB0aGUgc29ja2V0IG9mIHRoaXMgY2hhbm5lbCB0byBhIHJlbW90ZSBhZGRyZXNzLCB3aGljaCBpcyB0aGUKKyAgICAgKiBvbmx5IGNvbW11bmljYXRpb24gcGVlciBmb3IgZ2V0dGluZyBhbmQgc2VuZGluZyBkYXRhZ3JhbXMgYWZ0ZXIgYmVpbmcKKyAgICAgKiBjb25uZWN0ZWQuCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIGNhbGxlZCBhdCBhbnkgdGltZSB3aXRob3V0IGFmZmVjdGluZyB0aGUgcmVhZCBhbmQKKyAgICAgKiB3cml0ZSBvcGVyYXRpb25zIGJlaW5nIHByb2Nlc3NlZCBhdCB0aGUgdGltZSB0aGUgbWV0aG9kIGlzIGNhbGxlZC4gVGhlCisgICAgICogY29ubmVjdGlvbiBzdGF0dXMgZG9lcyBub3QgY2hhbmdlIHVudGlsIHRoZSBjaGFubmVsIGlzIGRpc2Nvbm5lY3RlZCBvcgorICAgICAqIGNsb3NlZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBleGVjdXRlcyB0aGUgc2FtZSBzZWN1cml0eSBjaGVja3MgYXMgdGhlIGNvbm5lY3QgbWV0aG9kIG9mCisgICAgICogdGhlIHtAbGluayBEYXRhZ3JhbVNvY2tldH0gY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWRkcmVzcworICAgICAqICAgICAgICAgICAgdGhlIGFkZHJlc3MgdG8gYmUgY29ubmVjdGVkIHRvLgorICAgICAqIEByZXR1cm4gdGhpcyBjaGFubmVsLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIGlzIGFscmVhZHkgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBpcyBjbG9zZWQgYnkgYW5vdGhlciB0aHJlYWQgd2hpbGUgdGhpcyBtZXRob2QKKyAgICAgKiAgICAgICAgICAgICBpcyBpbiBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgdGhyZWFkIGludGVycnVwdHMgdGhlIGNhbGxpbmcgdGhyZWFkIHdoaWxlIHRoZQorICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcy4gVGhlIGNhbGxpbmcgdGhyZWFkIHdpbGwgaGF2ZSB0aGUKKyAgICAgKiAgICAgICAgICAgICBpbnRlcnJ1cHQgc3RhdGUgc2V0IGFuZCB0aGUgY2hhbm5lbCB3aWxsIGJlIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgc29tZSBvdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBEYXRhZ3JhbUNoYW5uZWwgY29ubmVjdChTb2NrZXRBZGRyZXNzIGFkZHJlc3MpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEaXNjb25uZWN0cyB0aGUgc29ja2V0IG9mIHRoaXMgY2hhbm5lbCwgd2hpY2ggaGFzIGJlZW4gY29ubmVjdGVkIGJlZm9yZQorICAgICAqIGluIG9yZGVyIHRvIHNlbmQgYW5kIHJlY2VpdmUgZGF0YWdyYW1zLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSBjYWxsZWQgYXQgYW55IHRpbWUgd2l0aG91dCBhZmZlY3RpbmcgdGhlIHJlYWQgYW5kCisgICAgICogd3JpdGUgb3BlcmF0aW9ucyBiZWluZyB1bmRlcndheS4gSXQgZG9lcyBub3QgaGF2ZSBhbnkgZWZmZWN0IGlmIHRoZQorICAgICAqIHNvY2tldCBpcyBub3QgY29ubmVjdGVkIG9yIHRoZSBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBjaGFubmVsLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBzb21lIG90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IERhdGFncmFtQ2hhbm5lbCBkaXNjb25uZWN0KCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyBhIGRhdGFncmFtIGZyb20gdGhpcyBjaGFubmVsLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIHRyYW5zZmVycyBhIGRhdGFncmFtIGZyb20gdGhlIGNoYW5uZWwgaW50byB0aGUgdGFyZ2V0IGJ5dGUKKyAgICAgKiBidWZmZXIuIElmIHRoaXMgY2hhbm5lbCBpcyBpbiBibG9ja2luZyBtb2RlLCBpdCB3YWl0cyBmb3IgdGhlIGRhdGFncmFtCisgICAgICogYW5kIHJldHVybnMgaXRzIGFkZHJlc3Mgd2hlbiBpdCBpcyBhdmFpbGFibGUuIElmIHRoaXMgY2hhbm5lbCBpcyBpbgorICAgICAqIG5vbi1ibG9ja2luZyBtb2RlIGFuZCBubyBkYXRhZ3JhbSBpcyBhdmFpbGFibGUsIGl0IHJldHVybnMge0Bjb2RlIG51bGx9CisgICAgICogaW1tZWRpYXRlbHkuIFRoZSB0cmFuc2ZlciBzdGFydHMgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24gb2YgdGhlIGJ1ZmZlciwKKyAgICAgKiBhbmQgaWYgdGhlcmUgaXMgbm90IGVub3VnaCBzcGFjZSByZW1haW5pbmcgaW4gdGhlIGJ1ZmZlciB0byBzdG9yZSB0aGUKKyAgICAgKiBkYXRhZ3JhbSB0aGVuIHRoZSBwYXJ0IG9mIHRoZSBkYXRhZ3JhbSB0aGF0IGRvZXMgbm90IGZpdCBpcyBkaXNjYXJkZWQuCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIGNhbGxlZCBhdCBhbnkgdGltZSBhbmQgaXQgd2lsbCBibG9jayBpZiB0aGVyZSBpcworICAgICAqIGFub3RoZXIgdGhyZWFkIHRoYXQgaGFzIHN0YXJ0ZWQgYSByZWFkIG9wZXJhdGlvbiBvbiB0aGUgY2hhbm5lbC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBleGVjdXRlcyB0aGUgc2FtZSBzZWN1cml0eSBjaGVja3MgYXMgdGhlIHJlY2VpdmUgbWV0aG9kIG9mCisgICAgICogdGhlIHtAbGluayBEYXRhZ3JhbVNvY2tldH0gY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGFyZ2V0CisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSBidWZmZXIgdG8gc3RvcmUgdGhlIHJlY2VpdmVkIGRhdGFncmFtLgorICAgICAqIEByZXR1cm4gdGhlIGFkZHJlc3Mgb2YgdGhlIGRhdGFncmFtIGlmIHRoZSB0cmFuc2ZlciBpcyBwZXJmb3JtZWQsIG9yIG51bGwKKyAgICAgKiAgICAgICAgIGlmIHRoZSBjaGFubmVsIGlzIGluIG5vbi1ibG9ja2luZyBtb2RlIGFuZCBubyBkYXRhZ3JhbSBpcworICAgICAqICAgICAgICAgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIGlzIGFscmVhZHkgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBpcyBjbG9zZWQgYnkgYW5vdGhlciB0aHJlYWQgd2hpbGUgdGhpcyBtZXRob2QKKyAgICAgKiAgICAgICAgICAgICBpcyBpbiBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgdGhyZWFkIGludGVycnVwdHMgdGhlIGNhbGxpbmcgdGhyZWFkIHdoaWxlIHRoZQorICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcy4gVGhlIGNhbGxpbmcgdGhyZWFkIHdpbGwgaGF2ZSB0aGUKKyAgICAgKiAgICAgICAgICAgICBpbnRlcnJ1cHQgc3RhdGUgc2V0IGFuZCB0aGUgY2hhbm5lbCB3aWxsIGJlIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgc29tZSBvdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTb2NrZXRBZGRyZXNzIHJlY2VpdmUoQnl0ZUJ1ZmZlciB0YXJnZXQpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNlbmRzIGEgZGF0YWdyYW0gdGhyb3VnaCB0aGlzIGNoYW5uZWwuIFRoZSBkYXRhZ3JhbSBjb25zaXN0cyBvZiB0aGUKKyAgICAgKiByZW1haW5pbmcgYnl0ZXMgaW4ge0Bjb2RlIHNvdXJjZX0uCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBjaGFubmVsIGlzIGluIGJsb2NraW5nIG1vZGUgdGhlbiB0aGUgZGF0YWdyYW0gaXMgc2VudCBhcyBzb29uIGFzCisgICAgICogdGhlcmUgaXMgZW5vdWdoIHNwYWNlIGluIHRoZSB1bmRlcmx5aW5nIG91dHB1dCBidWZmZXIuIElmIHRoaXMgY2hhbm5lbCBpcworICAgICAqIGluIG5vbi1ibG9ja2luZyBtb2RlIHRoZW4gdGhlIGRhdGFncmFtIGlzIG9ubHkgc2VudCBpZiB0aGVyZSBpcyBlbm91Z2gKKyAgICAgKiBzcGFjZSBpbiB0aGUgdW5kZXJseWluZyBvdXRwdXQgYnVmZmVyIGF0IHRoYXQgbW9tZW50LiBUaGUgdHJhbnNmZXIgYWN0aW9uCisgICAgICogaXMganVzdCBsaWtlIGEgcmVndWxhciB3cml0ZSBvcGVyYXRpb24uCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIGNhbGxlZCBhdCBhbnkgdGltZSBhbmQgaXQgd2lsbCBibG9jayBpZiBhbm90aGVyIHRocmVhZAorICAgICAqIGhhcyBzdGFydGVkIGEgc2VuZCBvcGVyYXRpb24gb24gdGhpcyBjaGFubmVsLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIGV4ZWN1dGVzIHRoZSBzYW1lIHNlY3VyaXR5IGNoZWNrcyBhcyB0aGUgc2VuZCBtZXRob2Qgb2YgdGhlCisgICAgICoge0BsaW5rIERhdGFncmFtU29ja2V0fSBjbGFzcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzb3VyY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGJ1ZmZlciB3aXRoIHRoZSBkYXRhZ3JhbSB0byBiZSBzZW50LgorICAgICAqIEBwYXJhbSBhZGRyZXNzCisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gYWRkcmVzcyBmb3IgdGhlIGRhdGFncmFtLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBzZW50LiBUaGlzIGlzIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVtYWluaW5nCisgICAgICogICAgICAgICBpbiB7QGNvZGUgc291cmNlfSBvciB6ZXJvIGlmIHRoZSBjaGFubmVsIGlzIGluIG5vbi1ibG9ja2luZyBtb2RlCisgICAgICogICAgICAgICBhbmQgdGhlcmUgaXMgbm90IGVub3VnaCBzcGFjZSBmb3IgdGhlIGRhdGFncmFtIGluIHRoZSB1bmRlcmx5aW5nCisgICAgICogICAgICAgICBvdXRwdXQgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIGlzIGFscmVhZHkgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBpcyBjbG9zZWQgYnkgYW5vdGhlciB0aHJlYWQgd2hpbGUgdGhpcyBtZXRob2QKKyAgICAgKiAgICAgICAgICAgICBpcyBpbiBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgdGhyZWFkIGludGVycnVwdHMgdGhlIGNhbGxpbmcgdGhyZWFkIHdoaWxlIHRoZQorICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcy4gVGhlIGNhbGxpbmcgdGhyZWFkIHdpbGwgaGF2ZSB0aGUKKyAgICAgKiAgICAgICAgICAgICBpbnRlcnJ1cHQgc3RhdGUgc2V0IGFuZCB0aGUgY2hhbm5lbCB3aWxsIGJlIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgc29tZSBvdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgc2VuZChCeXRlQnVmZmVyIHNvdXJjZSwgU29ja2V0QWRkcmVzcyBhZGRyZXNzKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGRhdGFncmFtIGZyb20gdGhpcyBjaGFubmVsIGludG8gdGhlIGJ5dGUgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBwcmVjb25kaXRpb24gZm9yIGNhbGxpbmcgdGhpcyBtZXRob2QgaXMgdGhhdCB0aGUgY2hhbm5lbCBpcyBjb25uZWN0ZWQKKyAgICAgKiBhbmQgdGhlIGluY29taW5nIGRhdGFncmFtIGlzIGZyb20gdGhlIGNvbm5lY3RlZCBhZGRyZXNzLiBJZiB0aGUgYnVmZmVyIGlzCisgICAgICogbm90IGJpZyBlbm91Z2ggdG8gc3RvcmUgdGhlIGRhdGFncmFtLCB0aGUgcGFydCBvZiB0aGUgZGF0YWdyYW0gdGhhdCBkb2VzCisgICAgICogbm90IGZpdCBpbiB0aGUgYnVmZmVyIGlzIGRpc2NhcmRlZC4gT3RoZXJ3aXNlLCB0aGlzIG1ldGhvZCBoYXMgdGhlIHNhbWUKKyAgICAgKiBiZWhhdmlvciBhcyB0aGUge0Bjb2RlIHJlYWR9IG1ldGhvZCBpbiB0aGUge0BsaW5rIFJlYWRhYmxlQnl0ZUNoYW5uZWx9CisgICAgICogaW50ZXJmYWNlLgorICAgICAqCisgICAgICogQHNlZSBqYXZhLm5pby5jaGFubmVscy5SZWFkYWJsZUJ5dGVDaGFubmVsI3JlYWQoamF2YS5uaW8uQnl0ZUJ1ZmZlcikKKyAgICAgKiBAcGFyYW0gdGFyZ2V0CisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSBidWZmZXIgdG8gc3RvcmUgdGhlIHJlY2VpdmVkIGRhdGFncmFtLgorICAgICAqIEByZXR1cm4gYSBub24tbmVnYXRpdmUgbnVtYmVyIGFzIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZCwgb3IgLTEgYXMgdGhlCisgICAgICogICAgICAgICByZWFkIG9wZXJhdGlvbiByZWFjaGVzIHRoZSBlbmQgb2Ygc3RyZWFtLgorICAgICAqIEB0aHJvd3MgTm90WWV0Q29ubmVjdGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaXMgbm90IGNvbm5lY3RlZCB5ZXQuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaXMgYWxyZWFkeSBjbG9zZWQuCisgICAgICogQHRocm93cyBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIGlzIGNsb3NlZCBieSBhbm90aGVyIHRocmVhZCB3aGlsZSB0aGlzIG1ldGhvZAorICAgICAqICAgICAgICAgICAgIGlzIGluIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciB0aHJlYWQgaW50ZXJydXB0cyB0aGUgY2FsbGluZyB0aHJlYWQgd2hpbGUgdGhlCisgICAgICogICAgICAgICAgICAgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLiBUaGUgY2FsbGluZyB0aHJlYWQgd2lsbCBoYXZlIHRoZQorICAgICAqICAgICAgICAgICAgIGludGVycnVwdCBzdGF0ZSBzZXQgYW5kIHRoZSBjaGFubmVsIHdpbGwgYmUgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBzb21lIG90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCByZWFkKEJ5dGVCdWZmZXIgdGFyZ2V0KSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGRhdGFncmFtIGZyb20gdGhpcyBjaGFubmVsIGludG8gYW4gYXJyYXkgb2YgYnl0ZSBidWZmZXJzLgorICAgICAqIDxwPgorICAgICAqIFRoZSBwcmVjb25kaXRpb24gZm9yIGNhbGxpbmcgdGhpcyBtZXRob2QgaXMgdGhhdCB0aGUgY2hhbm5lbCBpcyBjb25uZWN0ZWQKKyAgICAgKiBhbmQgdGhlIGluY29taW5nIGRhdGFncmFtIGlzIGZyb20gdGhlIGNvbm5lY3RlZCBhZGRyZXNzLiBJZiB0aGUgYnVmZmVycworICAgICAqIGRvIG5vdCBoYXZlIGVub3VnaCByZW1haW5pbmcgc3BhY2UgdG8gc3RvcmUgdGhlIGRhdGFncmFtLCB0aGUgcGFydCBvZiB0aGUKKyAgICAgKiBkYXRhZ3JhbSB0aGF0IGRvZXMgbm90IGZpdCBpbiB0aGUgYnVmZmVycyBpcyBkaXNjYXJkZWQuIE90aGVyd2lzZSwgdGhpcworICAgICAqIG1ldGhvZCBoYXMgdGhlIHNhbWUgYmVoYXZpb3IgYXMgdGhlIHtAY29kZSByZWFkfSBtZXRob2QgaW4gdGhlCisgICAgICoge0BsaW5rIFNjYXR0ZXJpbmdCeXRlQ2hhbm5lbH0gaW50ZXJmYWNlLgorICAgICAqCisgICAgICogQHNlZSBqYXZhLm5pby5jaGFubmVscy5TY2F0dGVyaW5nQnl0ZUNoYW5uZWwjcmVhZChqYXZhLm5pby5CeXRlQnVmZmVyW10sCisgICAgICogICAgICBpbnQsIGludCkKKyAgICAgKiBAcGFyYW0gdGFyZ2V0cworICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYnVmZmVycyB0byBzdG9yZSB0aGUgcmVjZWl2ZWQgZGF0YWdyYW0uCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgYSBub24tbmVnYXRpdmUgb2Zmc2V0IGluIHRoZSBhcnJheSBvZiBidWZmZXJzLCBwb2ludGluZyB0byB0aGUKKyAgICAgKiAgICAgICAgICAgIHN0YXJ0aW5nIGJ1ZmZlciB0byBzdG9yZSB0aGUgYnl0ZXMgdHJhbnNmZXJyZWQsIG11c3Qgbm90IGJlCisgICAgICogICAgICAgICAgICBiaWdnZXIgdGhhbiB7QGNvZGUgdGFyZ2V0cy5sZW5ndGh9LgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIGEgbm9uLW5lZ2F0aXZlIGxlbmd0aCB0byBpbmRpY2F0ZSB0aGUgbWF4aW11bSBudW1iZXIgb2YKKyAgICAgKiAgICAgICAgICAgIGJ1ZmZlcnMgdG8gYmUgZmlsbGVkLCBtdXN0IG5vdCBiZSBiaWdnZXIgdGhhbgorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRhcmdldHMubGVuZ3RoIC0gb2Zmc2V0fS4KKyAgICAgKiBAcmV0dXJuIGEgbm9uLW5lZ2F0aXZlIG51bWJlciBhcyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQsIG9yIC0xIGlmIHRoZQorICAgICAqICAgICAgICAgcmVhZCBvcGVyYXRpb24gcmVhY2hlcyB0aGUgZW5kIG9mIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIE5vdFlldENvbm5lY3RlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIGlzIG5vdCBjb25uZWN0ZWQgeWV0LgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIGlzIGFscmVhZHkgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBpcyBjbG9zZWQgYnkgYW5vdGhlciB0aHJlYWQgd2hpbGUgdGhpcyBtZXRob2QKKyAgICAgKiAgICAgICAgICAgICBpcyBpbiBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgdGhyZWFkIGludGVycnVwdHMgdGhlIGNhbGxpbmcgdGhyZWFkIHdoaWxlIHRoZQorICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcy4gVGhlIGNhbGxpbmcgdGhyZWFkIHdpbGwgaGF2ZSB0aGUKKyAgICAgKiAgICAgICAgICAgICBpbnRlcnJ1cHQgc3RhdGUgc2V0IGFuZCB0aGUgY2hhbm5lbCB3aWxsIGJlIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgc29tZSBvdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBsb25nIHJlYWQoQnl0ZUJ1ZmZlcltdIHRhcmdldHMsIGludCBvZmZzZXQsIGludCBsZW5ndGgpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIGRhdGFncmFtIGZyb20gdGhpcyBjaGFubmVsIGludG8gYW4gYXJyYXkgb2YgYnl0ZSBidWZmZXJzLgorICAgICAqIDxwPgorICAgICAqIFRoZSBwcmVjb25kaXRpb24gZm9yIGNhbGxpbmcgdGhpcyBtZXRob2QgaXMgdGhhdCB0aGUgY2hhbm5lbCBpcyBjb25uZWN0ZWQKKyAgICAgKiBhbmQgdGhlIGluY29taW5nIGRhdGFncmFtIGlzIGZyb20gdGhlIGNvbm5lY3RlZCBhZGRyZXNzLiBJZiB0aGUgYnVmZmVycworICAgICAqIGRvIG5vdCBoYXZlIGVub3VnaCByZW1haW5pbmcgc3BhY2UgdG8gc3RvcmUgdGhlIGRhdGFncmFtLCB0aGUgcGFydCBvZiB0aGUKKyAgICAgKiBkYXRhZ3JhbSB0aGF0IGRvZXMgbm90IGZpdCBpbiB0aGUgYnVmZmVycyBpcyBkaXNjYXJkZWQuIE90aGVyd2lzZSwgdGhpcworICAgICAqIG1ldGhvZCBoYXMgdGhlIHNhbWUgYmVoYXZpb3IgYXMgdGhlIHtAY29kZSByZWFkfSBtZXRob2QgaW4gdGhlCisgICAgICoge0BsaW5rIFNjYXR0ZXJpbmdCeXRlQ2hhbm5lbH0gaW50ZXJmYWNlLgorICAgICAqCisgICAgICogQHNlZSBqYXZhLm5pby5jaGFubmVscy5TY2F0dGVyaW5nQnl0ZUNoYW5uZWwjcmVhZChqYXZhLm5pby5CeXRlQnVmZmVyW10pCisgICAgICogQHBhcmFtIHRhcmdldHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGJ1ZmZlcnMgdG8gc3RvcmUgdGhlIHJlY2VpdmVkIGRhdGFncmFtLgorICAgICAqIEByZXR1cm4gYSBub24tbmVnYXRpdmUgbnVtYmVyIGFzIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZCwgb3IgLTEgaWYgdGhlCisgICAgICogICAgICAgICByZWFkIG9wZXJhdGlvbiByZWFjaGVzIHRoZSBlbmQgb2Ygc3RyZWFtLgorICAgICAqIEB0aHJvd3MgTm90WWV0Q29ubmVjdGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaXMgbm90IGNvbm5lY3RlZCB5ZXQuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaXMgYWxyZWFkeSBjbG9zZWQuCisgICAgICogQHRocm93cyBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIGlzIGNsb3NlZCBieSBhbm90aGVyIHRocmVhZCB3aGlsZSB0aGlzIG1ldGhvZAorICAgICAqICAgICAgICAgICAgIGlzIGluIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciB0aHJlYWQgaW50ZXJydXB0cyB0aGUgY2FsbGluZyB0aHJlYWQgd2hpbGUgdGhlCisgICAgICogICAgICAgICAgICAgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLiBUaGUgY2FsbGluZyB0aHJlYWQgd2lsbCBoYXZlIHRoZQorICAgICAqICAgICAgICAgICAgIGludGVycnVwdCBzdGF0ZSBzZXQgYW5kIHRoZSBjaGFubmVsIHdpbGwgYmUgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBzb21lIG90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBmaW5hbCBsb25nIHJlYWQoQnl0ZUJ1ZmZlcltdIHRhcmdldHMpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcmVhZCh0YXJnZXRzLCAwLCB0YXJnZXRzLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgZGF0YWdyYW0gZnJvbSB0aGUgYnl0ZSBidWZmZXIgdG8gdGhpcyBjaGFubmVsLgorICAgICAqIDxwPgorICAgICAqIFRoZSBwcmVjb25kaXRpb24gb2YgY2FsbGluZyB0aGlzIG1ldGhvZCBpcyB0aGF0IHRoZSBjaGFubmVsIGlzIGNvbm5lY3RlZAorICAgICAqIGFuZCB0aGUgZGF0YWdyYW0gaXMgc2VudCB0byB0aGUgY29ubmVjdGVkIGFkZHJlc3MuIE90aGVyd2lzZSwgdGhpcyBtZXRob2QKKyAgICAgKiBoYXMgdGhlIHNhbWUgYmVoYXZpb3IgYXMgdGhlIHtAY29kZSB3cml0ZX0gbWV0aG9kIGluIHRoZQorICAgICAqIHtAbGluayBXcml0YWJsZUJ5dGVDaGFubmVsfSBpbnRlcmZhY2UuCisgICAgICoKKyAgICAgKiBAc2VlIGphdmEubmlvLmNoYW5uZWxzLldyaXRhYmxlQnl0ZUNoYW5uZWwjd3JpdGUoamF2YS5uaW8uQnl0ZUJ1ZmZlcikKKyAgICAgKiBAcGFyYW0gc291cmNlCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSBidWZmZXIgYXMgdGhlIHNvdXJjZSBvZiB0aGUgZGF0YWdyYW0uCisgICAgICogQHJldHVybiBhIG5vbi1uZWdhdGl2ZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbi4KKyAgICAgKiBAdGhyb3dzIE5vdFlldENvbm5lY3RlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIGlzIG5vdCBjb25uZWN0ZWQgeWV0LgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIGlzIGFscmVhZHkgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBpcyBjbG9zZWQgYnkgYW5vdGhlciB0aHJlYWQgd2hpbGUgdGhpcyBtZXRob2QKKyAgICAgKiAgICAgICAgICAgICBpcyBpbiBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgdGhyZWFkIGludGVycnVwdHMgdGhlIGNhbGxpbmcgdGhyZWFkIHdoaWxlIHRoZQorICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcy4gVGhlIGNhbGxpbmcgdGhyZWFkIHdpbGwgaGF2ZSB0aGUKKyAgICAgKiAgICAgICAgICAgICBpbnRlcnJ1cHQgc3RhdGUgc2V0IGFuZCB0aGUgY2hhbm5lbCB3aWxsIGJlIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgc29tZSBvdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgd3JpdGUoQnl0ZUJ1ZmZlciBzb3VyY2UpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGRhdGFncmFtIGZyb20gdGhlIGJ5dGUgYnVmZmVycyB0byB0aGlzIGNoYW5uZWwuCisgICAgICogPHA+CisgICAgICogVGhlIHByZWNvbmRpdGlvbiBvZiBjYWxsaW5nIHRoaXMgbWV0aG9kIGlzIHRoYXQgdGhlIGNoYW5uZWwgaXMgY29ubmVjdGVkCisgICAgICogYW5kIHRoZSBkYXRhZ3JhbSBpcyBzZW50IHRvIHRoZSBjb25uZWN0ZWQgYWRkcmVzcy4gT3RoZXJ3aXNlLCB0aGlzIG1ldGhvZAorICAgICAqIGhhcyB0aGUgc2FtZSBiZWhhdmlvciBhcyB0aGUge0Bjb2RlIHdyaXRlfSBtZXRob2QgaW4gdGhlCisgICAgICoge0BsaW5rIEdhdGhlcmluZ0J5dGVDaGFubmVsfSBpbnRlcmZhY2UuCisgICAgICoKKyAgICAgKiBAc2VlIGphdmEubmlvLmNoYW5uZWxzLkdhdGhlcmluZ0J5dGVDaGFubmVsI3dyaXRlKGphdmEubmlvLkJ5dGVCdWZmZXJbXSwKKyAgICAgKiAgICAgIGludCwgaW50KQorICAgICAqIEBwYXJhbSBzb3VyY2VzCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSBidWZmZXJzIGFzIHRoZSBzb3VyY2Ugb2YgdGhlIGRhdGFncmFtLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIGEgbm9uLW5lZ2F0aXZlIG9mZnNldCBpbiB0aGUgYXJyYXkgb2YgYnVmZmVycywgcG9pbnRpbmcgdG8gdGhlCisgICAgICogICAgICAgICAgICBzdGFydGluZyBidWZmZXIgdG8gYmUgcmV0cmlldmVkLCBtdXN0IGJlIG5vIGxhcmdlciB0aGFuCisgICAgICogICAgICAgICAgICB7QGNvZGUgc291cmNlcy5sZW5ndGh9LgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIGEgbm9uLW5lZ2F0aXZlIGxlbmd0aCB0byBpbmRpY2F0ZSB0aGUgbWF4aW11bSBudW1iZXIgb2YKKyAgICAgKiAgICAgICAgICAgIGJ1ZmZlcnMgdG8gYmUgc3VibWl0dGVkLCBtdXN0IGJlIG5vIGJpZ2dlciB0aGFuCisgICAgICogICAgICAgICAgICB7QGNvZGUgc291cmNlcy5sZW5ndGggLSBvZmZzZXR9LgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuLiBJZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQsIGl0IHJldHVybnMKKyAgICAgKiAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3aGVyZSByZW1haW5pbmcgaW4gdGhlIGJ5dGUgYnVmZmVycy4gSWYKKyAgICAgKiAgICAgICAgIHRoZSBjaGFubmVsIGlzIGluIG5vbi1ibG9ja2luZyBtb2RlIGFuZCB0aGVyZSB3YXMgbm90IGVub3VnaAorICAgICAqICAgICAgICAgc3BhY2UgZm9yIHRoZSBkYXRhZ3JhbSBpbiB0aGUgYnVmZmVyLCBpdCBtYXkgcmV0dXJuIHplcm8uCisgICAgICogQHRocm93cyBOb3RZZXRDb25uZWN0ZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBpcyBub3QgY29ubmVjdGVkIHlldC4KKyAgICAgKiBAdGhyb3dzIENsb3NlZENoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBpcyBhbHJlYWR5IGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIEFzeW5jaHJvbm91c0Nsb3NlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaXMgY2xvc2VkIGJ5IGFub3RoZXIgdGhyZWFkIHdoaWxlIHRoaXMgbWV0aG9kCisgICAgICogICAgICAgICAgICAgaXMgaW4gb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIHRocmVhZCBpbnRlcnJ1cHRzIHRoZSBjYWxsaW5nIHRocmVhZCB3aGlsZSB0aGUKKyAgICAgKiAgICAgICAgICAgICBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MuIFRoZSBjYWxsaW5nIHRocmVhZCB3aWxsIGhhdmUgdGhlCisgICAgICogICAgICAgICAgICAgaW50ZXJydXB0IHN0YXRlIHNldCBhbmQgdGhlIGNoYW5uZWwgd2lsbCBiZSBjbG9zZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHNvbWUgb3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgbG9uZyB3cml0ZShCeXRlQnVmZmVyW10gc291cmNlcywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGRhdGFncmFtIGZyb20gdGhlIGJ5dGUgYnVmZmVycyB0byB0aGlzIGNoYW5uZWwuCisgICAgICogPHA+CisgICAgICogVGhlIHByZWNvbmRpdGlvbiBvZiBjYWxsaW5nIHRoaXMgbWV0aG9kIGlzIHRoYXQgdGhlIGNoYW5uZWwgaXMgY29ubmVjdGVkCisgICAgICogYW5kIHRoZSBkYXRhZ3JhbSBpcyBzZW50IHRvIHRoZSBjb25uZWN0ZWQgYWRkcmVzcy4gT3RoZXJ3aXNlLCB0aGlzIG1ldGhvZAorICAgICAqIGhhcyB0aGUgc2FtZSBiZWhhdmlvciBhcyB0aGUgd3JpdGUgbWV0aG9kIGluIHRoZQorICAgICAqIHtAbGluayBHYXRoZXJpbmdCeXRlQ2hhbm5lbH0gaW50ZXJmYWNlLgorICAgICAqCisgICAgICogQHNlZSBqYXZhLm5pby5jaGFubmVscy5HYXRoZXJpbmdCeXRlQ2hhbm5lbCN3cml0ZShqYXZhLm5pby5CeXRlQnVmZmVyW10pCisgICAgICogQHBhcmFtIHNvdXJjZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGJ1ZmZlcnMgYXMgdGhlIHNvdXJjZSBvZiB0aGUgZGF0YWdyYW0uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4uIElmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCwgaXQgcmV0dXJucworICAgICAqICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdoZXJlIHJlbWFpbmluZyBpbiB0aGUgYnl0ZSBidWZmZXIuIElmCisgICAgICogICAgICAgICB0aGUgY2hhbm5lbCBpcyBpbiBub24tYmxvY2tpbmcgbW9kZSBhbmQgdGhlcmUgd2FzIG5vdCBlbm91Z2gKKyAgICAgKiAgICAgICAgIHNwYWNlIGZvciB0aGUgZGF0YWdyYW0gaW4gdGhlIGJ1ZmZlciwgaXQgbWF5IHJldHVybiB6ZXJvLgorICAgICAqIEB0aHJvd3MgTm90WWV0Q29ubmVjdGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaXMgbm90IGNvbm5lY3RlZCB5ZXQuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaXMgYWxyZWFkeSBjbG9zZWQuCisgICAgICogQHRocm93cyBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIGlzIGNsb3NlZCBieSBhbm90aGVyIHRocmVhZCB3aGlsZSB0aGlzIG1ldGhvZAorICAgICAqICAgICAgICAgICAgIGlzIGluIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciB0aHJlYWQgaW50ZXJydXB0cyB0aGUgY2FsbGluZyB0aHJlYWQgd2hpbGUgdGhlCisgICAgICogICAgICAgICAgICAgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLiBUaGUgY2FsbGluZyB0aHJlYWQgd2lsbCBoYXZlIHRoZQorICAgICAqICAgICAgICAgICAgIGludGVycnVwdCBzdGF0ZSBzZXQgYW5kIHRoZSBjaGFubmVsIHdpbGwgYmUgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBzb21lIG90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBmaW5hbCBsb25nIHdyaXRlKEJ5dGVCdWZmZXJbXSBzb3VyY2VzKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHdyaXRlKHNvdXJjZXMsIDAsIHNvdXJjZXMubGVuZ3RoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvRmlsZUNoYW5uZWwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9GaWxlQ2hhbm5lbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI5OGVhOGIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvRmlsZUNoYW5uZWwuamF2YQpAQCAtMCwwICsxLDc1NyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFubmVsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5NYXBwZWRCeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLnNwaS5BYnN0cmFjdEludGVycnVwdGlibGVDaGFubmVsOworCisvKioKKyAqIEFuIGFic3RyYWN0IGNoYW5uZWwgdHlwZSBmb3IgaW50ZXJhY3Rpb24gd2l0aCBhIHBsYXRmb3JtIGZpbGUuCisgKiA8cD4KKyAqIEEge0Bjb2RlIEZpbGVDaGFubmVsfSBkZWZpbmVzIHRoZSBtZXRob2RzIGZvciByZWFkaW5nLCB3cml0aW5nLCBtZW1vcnkKKyAqIG1hcHBpbmcsIGFuZCBtYW5pcHVsYXRpbmcgdGhlIGxvZ2ljYWwgc3RhdGUgb2YgYSBwbGF0Zm9ybSBmaWxlLiBUaGlzIHR5cGUKKyAqIGRvZXMgbm90IGhhdmUgYSBtZXRob2QgZm9yIG9wZW5pbmcgZmlsZXMsIHNpbmNlIHRoaXMgYmVoYXZpb3IgaGFzIGJlZW4KKyAqIGRlbGVnYXRlZCB0byB0aGUge0BsaW5rIGphdmEuaW8uRmlsZUlucHV0U3RyZWFtfSwKKyAqIHtAbGluayBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW19IGFuZCB7QGxpbmsgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlfSB0eXBlcy4KKyAqIDxwPgorICogRmlsZUNoYW5uZWxzIGNyZWF0ZWQgZnJvbSBhIHtAY29kZSBGaWxlSW5wdXRTdHJlYW19IG9yIGEKKyAqIHtAY29kZSBSYW5kb21BY2Nlc3NGaWxlfSBjcmVhdGVkIGluIG1vZGUgInIiLCBhcmUgcmVhZC1vbmx5LiBGaWxlQ2hhbm5lbHMKKyAqIGNyZWF0ZWQgZnJvbSBhIHtAY29kZSBGaWxlT3V0cHV0U3RyZWFtfSBhcmUgd3JpdGUtb25seS4gRmlsZUNoYW5uZWxzIGNyZWF0ZWQKKyAqIGZyb20gYSB7QGNvZGUgUmFuZG9tQWNjZXNzRmlsZX0gY3JlYXRlZCBpbiBtb2RlICJydyIgYXJlIHJlYWQvd3JpdGUuCisgKiBGaWxlQ2hhbm5lbHMgY3JlYXRlZCBmcm9tIGEge0Bjb2RlIFJhbmRvbUFjY2Vzc0ZpbGV9IHRoYXQgd2FzIG9wZW5lZCBpbgorICogYXBwZW5kLW1vZGUgd2lsbCBhbHNvIGJlIGluIGFwcGVuZC1tb2RlIC0tIG1lYW5pbmcgdGhhdCBlYWNoIHdyaXRlIHdpbGwgYmUKKyAqIHByb2NlZWRlZCBieSBhIHNlZWsgdG8gdGhlIGVuZCBvZiBmaWxlLgorICogPHA+CisgKiBGaWxlQ2hhbm5lbHMgaGF2ZSBhIHZpcnR1YWwgcG9pbnRlciBpbnRvIHRoZSBmaWxlIHdoaWNoIGlzIHJlZmVycmVkIHRvIGFzIGEKKyAqIGZpbGUgPGVtPnBvc2l0aW9uPC9lbT4uIFRoZSBwb3NpdGlvbiBjYW4gYmUgbWFuaXB1bGF0ZWQgYnkgbW92aW5nIGl0CisgKiB3aXRoaW4gdGhlIGZpbGUsIGFuZCB0aGUgY3VycmVudCBwb3NpdGlvbiBjYW4gYmUgcXVlcmllZC4KKyAqIDxwPgorICogRmlsZUNoYW5uZWxzIGFsc28gaGF2ZSBhbiBhc3NvY2lhdGVkIDxlbT5zaXplPC9lbT4uIFRoZSBzaXplIG9mIHRoZSBmaWxlCisgKiBpcyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgaXQgY3VycmVudGx5IGNvbnRhaW5zLiBUaGUgc2l6ZSBjYW4gYmUKKyAqIG1hbmlwdWxhdGVkIGJ5IGFkZGluZyBtb3JlIGJ5dGVzIHRvIHRoZSBlbmQgb2YgdGhlIGZpbGUgKHdoaWNoIGluY3JlYXNlcyB0aGUKKyAqIHNpemUpIG9yIHRydW5jYXRpbmcgdGhlIGZpbGUgKHdoaWNoIGRlY3JlYXNlcyB0aGUgc2l6ZSkuIFRoZSBjdXJyZW50IHNpemUgY2FuCisgKiBhbHNvIGJlIHF1ZXJpZWQuCisgKiA8cD4KKyAqIEZpbGVDaGFubmVscyBoYXZlIG9wZXJhdGlvbnMgYmV5b25kIHRoZSBzaW1wbGUgcmVhZCwgd3JpdGUsIGFuZCBjbG9zZS4gVGhleQorICogY2FuIGFsc286CisgKiA8dWw+CisgKiA8bGk+cmVxdWVzdCB0aGF0IGNhY2hlZCBkYXRhIGJlIGZvcmNlZCBvbnRvIHRoZSBkaXNrLDwvbGk+CisgKiA8bGk+bG9jayByYW5nZXMgb2YgYnl0ZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBmaWxlLDwvbGk+CisgKiA8bGk+dHJhbnNmZXIgZGF0YSBkaXJlY3RseSB0byBhbm90aGVyIGNoYW5uZWwgaW4gYSBtYW5uZXIgdGhhdCBoYXMgdGhlCisgKiBwb3RlbnRpYWwgdG8gYmUgb3B0aW1pemVkIGJ5IHRoZSBwbGF0Zm9ybSw8L2xpPgorICogPGxpPm1lbW9yeS1tYXBwaW5nIGZpbGVzIGludG8gTklPIGJ1ZmZlcnMgdG8gcHJvdmlkZSBlZmZpY2llbnQgbWFuaXB1bGF0aW9uCisgKiBvZiBmaWxlIGRhdGEsPC9saT4KKyAqIDxsaT5yZWFkIGFuZCB3cml0ZSB0byB0aGUgZmlsZSBhdCBhYnNvbHV0ZSBieXRlIG9mZnNldHMgaW4gYSBmYXNoaW9uIHRoYXQKKyAqIGRvZXMgbm90IG1vZGlmeSB0aGUgY3VycmVudCBwb3NpdGlvbi48L2xpPgorICogPC91bD4KKyAqIDxwPgorICogRmlsZUNoYW5uZWxzIGFyZSB0aHJlYWQtc2FmZS4gT25seSBvbmUgb3BlcmF0aW9uIGludm9sdmluZyBtYW5pcHVsYXRpb24gb2YKKyAqIHRoZSBmaWxlIHBvc2l0aW9uIG1heSBiZSBleGVjdXRlZCBhdCB0aGUgc2FtZSB0aW1lLiBTdWJzZXF1ZW50IGNhbGxzIHRvIHN1Y2gKKyAqIG9wZXJhdGlvbnMgd2lsbCBibG9jaywgYW5kIG9uZSBvZiB0aG9zZSBibG9ja2VkIHdpbGwgYmUgZnJlZWQgdG8gY29udGludWUKKyAqIHdoZW4gdGhlIGZpcnN0IG9wZXJhdGlvbiBoYXMgY29tcGxldGVkLiBUaGVyZSBpcyBubyBvcmRlcmVkIHF1ZXVlIG9yIGZhaXJuZXNzCisgKiBhcHBsaWVkIHRvIHRoZSBibG9ja2VkIHRocmVhZHMuCisgKiA8cD4KKyAqIEl0IGlzIHVuZGVmaW5lZCB3aGV0aGVyIG9wZXJhdGlvbnMgdGhhdCBkbyBub3QgbWFuaXB1bGF0ZSB0aGUgZmlsZSBwb3NpdGlvbgorICogd2lsbCBhbHNvIGJsb2NrIHdoZW4gdGhlcmUgYXJlIGFueSBvdGhlciBvcGVyYXRpb25zIGluLWZsaWdodC4KKyAqIDxwPgorICogVGhlIGxvZ2ljYWwgdmlldyBvZiB0aGUgdW5kZXJseWluZyBmaWxlIGlzIGNvbnNpc3RlbnQgYWNyb3NzIGFsbCBGaWxlQ2hhbm5lbHMKKyAqIGFuZCBJL08gc3RyZWFtcyBvcGVuZWQgb24gdGhlIHNhbWUgZmlsZSBieSB0aGUgc2FtZSBWTS4KKyAqIFRoZXJlZm9yZSwgbW9kaWZpY2F0aW9ucyBwZXJmb3JtZWQgdmlhIGEgY2hhbm5lbCB3aWxsIGJlIHZpc2libGUgdG8gdGhlCisgKiBzdHJlYW0gYW5kIHZpY2UgdmVyc2E7IHRoaXMgaW5jbHVkZXMgbW9kaWZpY2F0aW9ucyB0byB0aGUgZmlsZSBwb3NpdGlvbiwKKyAqIGNvbnRlbnQsIHNpemUsIGV0Yy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEZpbGVDaGFubmVsIGV4dGVuZHMgQWJzdHJhY3RJbnRlcnJ1cHRpYmxlQ2hhbm5lbAorICAgICAgICBpbXBsZW1lbnRzIEdhdGhlcmluZ0J5dGVDaGFubmVsLCBTY2F0dGVyaW5nQnl0ZUNoYW5uZWwsIEJ5dGVDaGFubmVsIHsKKworICAgIC8qKgorICAgICAqIHtAY29kZSBNYXBNb2RlfSBkZWZpbmVzIGZpbGUgbWFwcGluZyBtb2RlIGNvbnN0YW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE1hcE1vZGUgeworICAgICAgICAvKioKKyAgICAgICAgICogUHJpdmF0ZSBtYXBwaW5nIG1vZGUgKGVxdWl2YWxlbnQgdG8gY29weSBvbiB3cml0ZSkuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcE1vZGUgUFJJVkFURSA9IG5ldyBNYXBNb2RlKCJQUklWQVRFIik7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJlYWQtb25seSBtYXBwaW5nIG1vZGUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcE1vZGUgUkVBRF9PTkxZID0gbmV3IE1hcE1vZGUoIlJFQURfT05MWSIpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZWFkLXdyaXRlIG1hcHBpbmcgbW9kZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwTW9kZSBSRUFEX1dSSVRFID0gbmV3IE1hcE1vZGUoIlJFQURfV1JJVEUiKTsKKworICAgICAgICAvLyBUaGUgc3RyaW5nIHVzZWQgdG8gZGlzcGxheSB0aGUgbWFwcGluZyBtb2RlLgorICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBkaXNwbGF5TmFtZTsKKworICAgICAgICAvKgorICAgICAgICAgKiBQcml2YXRlIGNvbnN0cnVjdG9yIHByZXZlbnRzIG90aGVycyBjcmVhdGluZyBuZXcgbW9kZXMuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIE1hcE1vZGUoU3RyaW5nIGRpc3BsYXlOYW1lKSB7CisgICAgICAgICAgICB0aGlzLmRpc3BsYXlOYW1lID0gZGlzcGxheU5hbWU7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyBhIHN0cmluZyB2ZXJzaW9uIG9mIHRoZSBtYXBwaW5nIG1vZGUuCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gdGhpcyBtYXAgbW9kZSBhcyBzdHJpbmcuCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBkaXNwbGF5TmFtZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFByb3RlY3RlZCBkZWZhdWx0IGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIHByb3RlY3RlZCBGaWxlQ2hhbm5lbCgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXF1ZXN0cyB0aGF0IGFsbCB1cGRhdGVzIHRvIHRoaXMgY2hhbm5lbCBhcmUgY29tbWl0dGVkIHRvIHRoZSBzdG9yYWdlCisgICAgICogZGV2aWNlLgorICAgICAqIDxwPgorICAgICAqIFdoZW4gdGhpcyBtZXRob2QgcmV0dXJucywgYWxsIG1vZGlmaWNhdGlvbnMgbWFkZSB0byB0aGUgcGxhdGZvcm0gZmlsZQorICAgICAqIHVuZGVybHlpbmcgdGhpcyBjaGFubmVsIGhhdmUgYmVlbiBjb21taXR0ZWQgaWYgdGhlIGZpbGUgcmVzaWRlcyBvbiBhCisgICAgICogbG9jYWwgc3RvcmFnZSBkZXZpY2UuIElmIHRoZSBmaWxlIGlzIG5vdCBob3N0ZWQgbG9jYWxseSwgZm9yIGV4YW1wbGUgb24gYQorICAgICAqIG5ldHdvcmtlZCBmaWxlIHN5c3RlbSwgdGhlbiBhcHBsaWNhdGlvbnMgY2Fubm90IGJlIGNlcnRhaW4gdGhhdCB0aGUKKyAgICAgKiBtb2RpZmljYXRpb25zIGhhdmUgYmVlbiBjb21taXR0ZWQuCisgICAgICogPHA+CisgICAgICogVGhlcmUgYXJlIG5vIGFzc3VyYW5jZXMgZ2l2ZW4gdGhhdCBjaGFuZ2VzIG1hZGUgdG8gdGhlIGZpbGUgdXNpbmcgbWV0aG9kcworICAgICAqIGRlZmluZWQgZWxzZXdoZXJlIHdpbGwgYmUgY29tbWl0dGVkLiBGb3IgZXhhbXBsZSwgY2hhbmdlcyBtYWRlIHZpYSBhCisgICAgICogbWFwcGVkIGJ5dGUgYnVmZmVyIG1heSBub3QgYmUgY29tbWl0dGVkLgorICAgICAqIDxwPgorICAgICAqIFRoZSA8Y29kZT5tZXRhZGF0YTwvY29kZT4gcGFyYW1ldGVyIGluZGljYXRlcyB3aGV0aGVyIHRoZSB1cGRhdGUgc2hvdWxkCisgICAgICogaW5jbHVkZSB0aGUgZmlsZSdzIG1ldGFkYXRhIHN1Y2ggYXMgbGFzdCBtb2RpZmljYXRpb24gdGltZSwgbGFzdCBhY2Nlc3MKKyAgICAgKiB0aW1lLCBldGMuIE5vdGUgdGhhdCBwYXNzaW5nIDxjb2RlPnRydWU8L2NvZGU+IG1heSBpbnZva2UgYW4gdW5kZXJseWluZworICAgICAqIHdyaXRlIHRvIHRoZSBvcGVyYXRpbmcgc3lzdGVtIChpZiB0aGUgcGxhdGZvcm0gaXMgbWFpbnRhaW5pbmcgbWV0YWRhdGEKKyAgICAgKiBzdWNoIGFzIGxhc3QgYWNjZXNzIHRpbWUpLCBldmVuIGlmIHRoZSBjaGFubmVsIGlzIG9wZW5lZCByZWFkLW9ubHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWV0YWRhdGEKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSB0cnVlfSBpZiB0aGUgZmlsZSBtZXRhZGF0YSBzaG91bGQgYmUgZmx1c2hlZCBpbgorICAgICAqICAgICAgICAgICAgYWRkaXRpb24gdG8gdGhlIGZpbGUgY29udGVudCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIGFscmVhZHkgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZm9yY2UoYm9vbGVhbiBtZXRhZGF0YSkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogT2J0YWlucyBhbiBleGNsdXNpdmUgbG9jayBvbiB0aGlzIGZpbGUuCisgICAgICogPHA+CisgICAgICogVGhpcyBpcyBhIGNvbnZlbmllbmNlIG1ldGhvZCBmb3IgYWNxdWlyaW5nIGEgbWF4aW11bSBsZW5ndGggbG9jayBvbiBhCisgICAgICogZmlsZS4gSXQgaXMgZXF1aXZhbGVudCB0bzoKKyAgICAgKiB7QGNvZGUgZmlsZUNoYW5uZWwubG9jaygwTCwgTG9uZy5NQVhfVkFMVUUsIGZhbHNlKTt9CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsb2NrIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIGxvY2tlZCBmaWxlIGFyZWEuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgdGhlIGZpbGUgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBOb25Xcml0YWJsZUNoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aGlzIGNoYW5uZWwgd2FzIG5vdCBvcGVuZWQgZm9yIHdyaXRpbmcuCisgICAgICogQHRocm93cyBPdmVybGFwcGluZ0ZpbGVMb2NrRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgZWl0aGVyIGEgbG9jayBpcyBhbHJlYWR5IGhlbGQgdGhhdCBvdmVybGFwcyB0aGlzIGxvY2sKKyAgICAgKiAgICAgICAgICAgICByZXF1ZXN0LCBvciBhbm90aGVyIHRocmVhZCBpcyB3YWl0aW5nIHRvIGFjcXVpcmUgYSBsb2NrIHRoYXQKKyAgICAgKiAgICAgICAgICAgICB3aWxsIG92ZXJsYXAgd2l0aCB0aGlzIHJlcXVlc3QuCisgICAgICogQHRocm93cyBGaWxlTG9ja0ludGVycnVwdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHRoZSBjYWxsaW5nIHRocmVhZCB3YXMgaW50ZXJydXB0ZWQgd2hpbGUgd2FpdGluZyB0byBhY3F1aXJlCisgICAgICogICAgICAgICAgICAgdGhlIGxvY2suCisgICAgICogQHRocm93cyBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHRoZSBjaGFubmVsIHdhcyBjbG9zZWQgd2hpbGUgdGhlIGNhbGxpbmcgdGhyZWFkIHdhcyB3YWl0aW5nCisgICAgICogICAgICAgICAgICAgdG8gYWNxdWlyZSB0aGUgbG9jay4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIG9idGFpbmluZyB0aGUgcmVxdWVzdGVkCisgICAgICogICAgICAgICAgICAgbG9jay4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgRmlsZUxvY2sgbG9jaygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBsb2NrKDBMLCBMb25nLk1BWF9WQUxVRSwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE9idGFpbnMgYSBsb2NrIG9uIGEgc3BlY2lmaWVkIHJlZ2lvbiBvZiB0aGUgZmlsZS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIGlzIHRoZSBibG9ja2luZyB2ZXJzaW9uIG9mIGxvY2sgYWNxdWlzaXRpb24sIHNlZSBhbHNvIHRoZQorICAgICAqIDxjb2RlPnRyeUxvY2soKTwvY29kZT4gbWV0aG9kcy4KKyAgICAgKiA8cD4KKyAgICAgKiBBdHRlbXB0cyB0byBhY3F1aXJlIGFuIG92ZXJsYXBwaW5nIGxvY2sgcmVnaW9uIHdpbGwgZmFpbC4gVGhlIGF0dGVtcHQKKyAgICAgKiB3aWxsIGZhaWwgaWYgdGhlIG92ZXJsYXBwaW5nIGxvY2sgaGFzIGFscmVhZHkgYmVlbiBvYnRhaW5lZCwgb3IgaWYKKyAgICAgKiBhbm90aGVyIHRocmVhZCBpcyBjdXJyZW50bHkgd2FpdGluZyB0byBhY3F1aXJlIHRoZSBvdmVybGFwcGluZyBsb2NrLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSByZXF1ZXN0IGlzIG5vdCBmb3IgYW4gb3ZlcmxhcHBpbmcgbG9jaywgdGhlIHRocmVhZCBjYWxsaW5nIHRoaXMKKyAgICAgKiBtZXRob2Qgd2lsbCBibG9jayB1bnRpbCB0aGUgbG9jayBpcyBvYnRhaW5lZCAobGlrZWx5IGJ5IG5vIGNvbnRlbnRpb24gb3IKKyAgICAgKiBhbm90aGVyIHByb2Nlc3MgcmVsZWFzaW5nIGEgbG9jayksIG9yIHVudGlsIHRoaXMgdGhyZWFkIGlzIGludGVycnVwdGVkIG9yCisgICAgICogdGhlIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBsb2NrIGlzIG9idGFpbmVkIHN1Y2Nlc3NmdWxseSB0aGVuIHRoZSB7QGxpbmsgRmlsZUxvY2t9IG9iamVjdAorICAgICAqIHJldHVybmVkIHJlcHJlc2VudHMgdGhlIGxvY2sgZm9yIHN1YnNlcXVlbnQgb3BlcmF0aW9ucyBvbiB0aGUgbG9ja2VkCisgICAgICogcmVnaW9uLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSB0aHJlYWQgaXMgaW50ZXJydXB0ZWQgd2hpbGUgd2FpdGluZyBmb3IgdGhlIGxvY2ssIHRoZSB0aHJlYWQgaXMKKyAgICAgKiBzZXQgdG8gdGhlIGludGVycnVwdGVkIHN0YXRlIGFuZCB0aHJvd3MgYQorICAgICAqIHtAbGluayBGaWxlTG9ja0ludGVycnVwdGlvbkV4Y2VwdGlvbn0uIElmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQgd2hpbGUKKyAgICAgKiB0aGUgdGhyZWFkIGlzIHdhaXRpbmcgdG8gb2J0YWluIHRoZSBsb2NrIHRoZW4gdGhlIHRocmVhZCB0aHJvd3MgYQorICAgICAqIHtAbGluayBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbn0uCisgICAgICogPHA+CisgICAgICogVGhlcmUgaXMgbm8gcmVxdWlyZW1lbnQgZm9yIHRoZSBwb3NpdGlvbiBhbmQgc2l6ZSB0byBiZSB3aXRoaW4gdGhlCisgICAgICogY3VycmVudCBzdGFydCBhbmQgbGVuZ3RoIG9mIHRoZSBmaWxlLgorICAgICAqIDxwPgorICAgICAqIFNvbWUgcGxhdGZvcm1zIGRvIG5vdCBzdXBwb3J0IHNoYXJlZCBsb2NrcywgYW5kIGlmIGEgcmVxdWVzdCBpcyBtYWRlIGZvcgorICAgICAqIGEgc2hhcmVkIGxvY2sgb24gc3VjaCBhIHBsYXRmb3JtLCB0aGlzIG1ldGhvZCB3aWxsIGF0dGVtcHQgdG8gYWNxdWlyZSBhbgorICAgICAqIGV4Y2x1c2l2ZSBsb2NrIGluc3RlYWQuIEl0IGlzIHVuZGVmaW5lZCB3aGV0aGVyIHRoZSBsb2NrIG9idGFpbmVkIGlzCisgICAgICogYWR2aXNvcnkgb3IgbWFuZGF0b3J5LgorICAgICAqCisgICAgICogQHBhcmFtIHBvc2l0aW9uCisgICAgICogICAgICAgICAgICB0aGUgc3RhcnRpbmcgcG9zaXRpb24gZm9yIHRoZSBsb2NrZWQgcmVnaW9uLgorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBsb2NrZWQgcmVnaW9uIGluIGJ5dGVzLgorICAgICAqIEBwYXJhbSBzaGFyZWQKKyAgICAgKiAgICAgICAgICAgIGEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgYW4gYXR0ZW1wdCBzaG91bGQgYmUgbWFkZSB0byBhY3F1aXJlCisgICAgICogICAgICAgICAgICBhIHNoYXJlZCBsb2NrLgorICAgICAqIEByZXR1cm4gdGhlIGZpbGUgbG9jayBvYmplY3QuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcG9zaXRpb259IG9yIHtAY29kZSBzaXplfSBpcyBuZWdhdGl2ZS4KKyAgICAgKiBAdGhyb3dzIENsb3NlZENoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgT3ZlcmxhcHBpbmdGaWxlTG9ja0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSByZXF1ZXN0ZWQgcmVnaW9uIG92ZXJsYXBzIGFuIGV4aXN0aW5nIGxvY2sgb3IgcGVuZGluZworICAgICAqICAgICAgICAgICAgIGxvY2sgcmVxdWVzdC4KKyAgICAgKiBAdGhyb3dzIE5vblJlYWRhYmxlQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIGlzIG5vdCBvcGVuZWQgaW4gcmVhZC1tb2RlIGJ1dCBzaGFyZWQgaXMgdHJ1ZS4KKyAgICAgKiBAdGhyb3dzIE5vbldyaXRhYmxlQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIGlzIG5vdCBvcGVuZWQgaW4gd3JpdGUgbW9kZSBidXQgc2hhcmVkIGlzCisgICAgICogICAgICAgICAgICAgZmFsc2UuCisgICAgICogQHRocm93cyBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQgYnkgYW5vdGhlciB0aHJlYWQgd2hpbGUgdGhpcyBtZXRob2QKKyAgICAgKiAgICAgICAgICAgICBpcyBleGVjdXRpbmcuCisgICAgICogQHRocm93cyBGaWxlTG9ja0ludGVycnVwdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB0aHJlYWQgaXMgaW50ZXJydXB0ZWQgd2hpbGUgaW4gdGhlIHN0YXRlIG9mIHdhaXRpbmcgb24KKyAgICAgKiAgICAgICAgICAgICB0aGUgZGVzaXJlZCBmaWxlIGxvY2suCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRmlsZUxvY2sgbG9jayhsb25nIHBvc2l0aW9uLCBsb25nIHNpemUsIGJvb2xlYW4gc2hhcmVkKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogTWFwcyB0aGUgZmlsZSBpbnRvIG1lbW9yeS4gVGhlcmUgY2FuIGJlIHRocmVlIG1vZGVzOiByZWFkLW9ubHksCisgICAgICogcmVhZC93cml0ZSBhbmQgcHJpdmF0ZS4gQWZ0ZXIgbWFwcGluZywgY2hhbmdlcyBtYWRlIHRvIG1lbW9yeSBvciB0aGUgZmlsZQorICAgICAqIGNoYW5uZWwgZG8gbm90IGFmZmVjdCB0aGUgb3RoZXIgc3RvcmFnZSBwbGFjZS4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlOiBtYXBwaW5nIGEgZmlsZSBpbnRvIG1lbW9yeSBpcyB1c3VhbGx5IGV4cGVuc2l2ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb2RlCisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIHRocmVlIG1hcHBpbmcgbW9kZXMuCisgICAgICogQHBhcmFtIHBvc2l0aW9uCisgICAgICogICAgICAgICAgICB0aGUgc3RhcnRpbmcgcG9zaXRpb24gb2YgdGhlIGZpbGUuCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaXplIG9mIHRoZSByZWdpb24gdG8gbWFwIGludG8gbWVtb3J5LgorICAgICAqIEByZXR1cm4gdGhlIG1hcHBlZCBieXRlIGJ1ZmZlci4KKyAgICAgKiBAdGhyb3dzIE5vblJlYWRhYmxlQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBGaWxlQ2hhbm5lbCBpcyBub3Qgb3BlbmVkIGZvciByZWFkaW5nIGJ1dCB0aGUgZ2l2ZW4KKyAgICAgKiAgICAgICAgICAgICBtb2RlIGlzICJSRUFEX09OTFkiLgorICAgICAqIEB0aHJvd3MgTm9uV3JpdGFibGVDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIEZpbGVDaGFubmVsIGlzIG5vdCBvcGVuZWQgZm9yIHdyaXRpbmcgYnV0IHRoZSBnaXZlbgorICAgICAqICAgICAgICAgICAgIG1vZGUgaXMgbm90ICJSRUFEX09OTFkiLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIHBhcmFtZXRlcnMgb2YgcG9zaXRpb24gYW5kIHNpemUgYXJlIG5vdCBjb3JyZWN0LgorICAgICAqICAgICAgICAgICAgIEJvdGggbXVzdCBiZSBub24gbmVnYXRpdmUuIHtAY29kZSBzaXplfSBhbHNvIG11c3Qgbm90IGJlCisgICAgICogICAgICAgICAgICAgYmlnZ2VyIHRoYW4gbWF4IGludGVnZXIuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBNYXBwZWRCeXRlQnVmZmVyIG1hcChGaWxlQ2hhbm5lbC5NYXBNb2RlIG1vZGUsCisgICAgICAgICAgICBsb25nIHBvc2l0aW9uLCBsb25nIHNpemUpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGZpbGUgcG9zaXRpb24gcG9pbnRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgcG9zaXRpb24gYXMgYSBwb3NpdGl2ZSBpbnRlZ2VyIG51bWJlciBvZiBieXRlcyBmcm9tCisgICAgICogICAgICAgICB0aGUgc3RhcnQgb2YgdGhlIGZpbGUuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBsb25nIHBvc2l0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZmlsZSBwb3NpdGlvbiBwb2ludGVyIHRvIGEgbmV3IHZhbHVlLgorICAgICAqIDxwPgorICAgICAqIFRoZSBhcmd1bWVudCBpcyB0aGUgbnVtYmVyIG9mIGJ5dGVzIGNvdW50ZWQgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIGZpbGUuCisgICAgICogVGhlIHBvc2l0aW9uIGNhbm5vdCBiZSBzZXQgdG8gYSB2YWx1ZSB0aGF0IGlzIG5lZ2F0aXZlLiBUaGUgbmV3IHBvc2l0aW9uCisgICAgICogY2FuIGJlIHNldCBiZXlvbmQgdGhlIGN1cnJlbnQgZmlsZSBzaXplLiBJZiBzZXQgYmV5b25kIHRoZSBjdXJyZW50IGZpbGUKKyAgICAgKiBzaXplLCBhdHRlbXB0cyB0byByZWFkIHdpbGwgcmV0dXJuIGVuZCBvZiBmaWxlLiBXcml0ZSBvcGVyYXRpb25zIHdpbGwKKyAgICAgKiBzdWNjZWVkIGJ1dCB0aGV5IHdpbGwgZmlsbCB0aGUgYnl0ZXMgYmV0d2VlbiB0aGUgY3VycmVudCBlbmQgb2YgZmlsZSBhbmQKKyAgICAgKiB0aGUgbmV3IHBvc2l0aW9uIHdpdGggdGhlIHJlcXVpcmVkIG51bWJlciBvZiAodW5zcGVjaWZpZWQpIGJ5dGUgdmFsdWVzLgorICAgICAqCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBmaWxlIHBvc2l0aW9uLCBpbiBieXRlcy4KKyAgICAgKiBAcmV0dXJuIHRoZSByZWNlaXZlci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBuZXcgcG9zaXRpb24gaXMgbmVnYXRpdmUuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBGaWxlQ2hhbm5lbCBwb3NpdGlvbihsb25nIG9mZnNldCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgYnl0ZXMgZnJvbSB0aGlzIGZpbGUgY2hhbm5lbCBpbnRvIHRoZSBnaXZlbiBidWZmZXIuCisgICAgICogPHA+CisgICAgICogVGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHRoYXQgd2lsbCBiZSByZWFkIGlzIHRoZSByZW1haW5pbmcgbnVtYmVyIG9mCisgICAgICogYnl0ZXMgaW4gdGhlIGJ1ZmZlciB3aGVuIHRoZSBtZXRob2QgaXMgaW52b2tlZC4gVGhlIGJ5dGVzIHdpbGwgYmUgY29waWVkCisgICAgICogaW50byB0aGUgYnVmZmVyIHN0YXJ0aW5nIGF0IHRoZSBidWZmZXIncyBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqIDxwPgorICAgICAqIFRoZSBjYWxsIG1heSBibG9jayBpZiBvdGhlciB0aHJlYWRzIGFyZSBhbHNvIGF0dGVtcHRpbmcgdG8gcmVhZCBmcm9tIHRoaXMKKyAgICAgKiBjaGFubmVsLgorICAgICAqIDxwPgorICAgICAqIFVwb24gY29tcGxldGlvbiwgdGhlIGJ1ZmZlcidzIHBvc2l0aW9uIGlzIHNldCB0byB0aGUgZW5kIG9mIHRoZSBieXRlcworICAgICAqIHRoYXQgaGF2ZSBiZWVuIHJlYWQuIFRoZSBidWZmZXIncyBsaW1pdCBpcyBub3QgY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGJ1ZmZlciB0byByZWNlaXZlIHRoZSBieXRlcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgcmVhZC4KKyAgICAgKiBAdGhyb3dzIEFzeW5jaHJvbm91c0Nsb3NlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciB0aHJlYWQgY2xvc2VzIHRoZSBjaGFubmVsIGR1cmluZyB0aGUgcmVhZC4KKyAgICAgKiBAdGhyb3dzIENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciB0aHJlYWQgaW50ZXJydXB0cyB0aGUgY2FsbGluZyB0aHJlYWQgZHVyaW5nIHRoZQorICAgICAqICAgICAgICAgICAgIHJlYWQuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLCBkZXRhaWxzIGFyZSBpbiB0aGUgbWVzc2FnZS4KKyAgICAgKiBAdGhyb3dzIE5vblJlYWRhYmxlQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIGhhcyBub3QgYmVlbiBvcGVuZWQgaW4gYSBtb2RlIHRoYXQgcGVybWl0cworICAgICAqICAgICAgICAgICAgIHJlYWRpbmcuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCByZWFkKEJ5dGVCdWZmZXIgYnVmZmVyKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBieXRlcyBmcm9tIHRoaXMgZmlsZSBjaGFubmVsIGludG8gdGhlIGdpdmVuIGJ1ZmZlciBzdGFydGluZyBmcm9tCisgICAgICogdGhlIHNwZWNpZmllZCBmaWxlIHBvc2l0aW9uLgorICAgICAqIDxwPgorICAgICAqIFRoZSBieXRlcyBhcmUgcmVhZCBzdGFydGluZyBhdCB0aGUgZ2l2ZW4gZmlsZSBwb3NpdGlvbiAodXAgdG8gdGhlCisgICAgICogcmVtYWluaW5nIG51bWJlciBvZiBieXRlcyBpbiB0aGUgYnVmZmVyKS4gVGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseQorICAgICAqIHJlYWQgaXMgcmV0dXJuZWQuCisgICAgICogPHA+CisgICAgICogSWYge0Bjb2RlIHBvc2l0aW9ufSBpcyBiZXlvbmQgdGhlIGN1cnJlbnQgZW5kIG9mIGZpbGUsIHRoZW4gbm8gYnl0ZXMgYXJlCisgICAgICogcmVhZC4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlIHRoYXQgdGhlIGZpbGUgcG9zaXRpb24gaXMgdW5tb2RpZmllZCBieSB0aGlzIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXIgdG8gcmVjZWl2ZSB0aGUgYnl0ZXMuCisgICAgICogQHBhcmFtIHBvc2l0aW9uCisgICAgICogICAgICAgICAgICB0aGUgKG5vbi1uZWdhdGl2ZSkgcG9zaXRpb24gYXQgd2hpY2ggdG8gcmVhZCB0aGUgYnl0ZXMuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHJlYWQuCisgICAgICogQHRocm93cyBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQgYnkgYW5vdGhlciB0aHJlYWQgd2hpbGUgdGhpcyBtZXRob2QKKyAgICAgKiAgICAgICAgICAgICBpcyBleGVjdXRpbmcuCisgICAgICogQHRocm93cyBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgdGhyZWFkIGludGVycnVwdHMgdGhlIGNhbGxpbmcgdGhyZWFkIHdoaWxlIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MuIFRoZSBjYWxsaW5nIHRocmVhZCB3aWxsIGhhdmUgdGhlCisgICAgICogICAgICAgICAgICAgaW50ZXJydXB0IHN0YXRlIHNldCwgYW5kIHRoZSBjaGFubmVsIHdpbGwgYmUgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiA8Y29kZT5wb3NpdGlvbjwvY29kZT4gaXMgbGVzcyB0aGFuIDAuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAdGhyb3dzIE5vblJlYWRhYmxlQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIGhhcyBub3QgYmVlbiBvcGVuZWQgaW4gYSBtb2RlIHRoYXQgcGVybWl0cworICAgICAqICAgICAgICAgICAgIHJlYWRpbmcuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCByZWFkKEJ5dGVCdWZmZXIgYnVmZmVyLCBsb25nIHBvc2l0aW9uKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgYnl0ZXMgZnJvbSB0aGlzIGZpbGUgY2hhbm5lbCBhbmQgc3RvcmVzIHRoZW0gaW4gdGhlIHNwZWNpZmllZCBhcnJheQorICAgICAqIG9mIGJ1ZmZlcnMuIFRoaXMgbWV0aG9kIGF0dGVtcHRzIHRvIHJlYWQgYXMgbWFueSBieXRlcyBhcyBjYW4gYmUgc3RvcmVkCisgICAgICogaW4gdGhlIGJ1ZmZlciBhcnJheSBmcm9tIHRoaXMgY2hhbm5lbCBhbmQgcmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzCisgICAgICogYWN0dWFsbHkgcmVhZC4gSXQgYWxzbyBpbmNyZWFzZXMgdGhlIGZpbGUgcG9zaXRpb24gYnkgdGhlIG51bWJlciBvZiBieXRlcworICAgICAqIHJlYWQuCisgICAgICogPHA+CisgICAgICogSWYgYSByZWFkIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcywgc3Vic2VxdWVudCB0aHJlYWRzIHdpbGwgYmxvY2sgdW50aWwKKyAgICAgKiB0aGUgcmVhZCBpcyBjb21wbGV0ZWQgYW5kIHdpbGwgdGhlbiBjb250ZW5kIGZvciB0aGUgYWJpbGl0eSB0byByZWFkLgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byBjYWxsaW5nCisgICAgICoge0Bjb2RlIHJlYWQoYnVmZmVycywgMCwgYnVmZmVycy5sZW5ndGgpO30KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXJzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgYnl0ZSBidWZmZXJzIGludG8gd2hpY2ggdGhlIGJ5dGVzIHdpbGwgYmUgY29waWVkLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSByZWFkLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgY2xvc2VkIGJ5IGFub3RoZXIgdGhyZWFkIGR1cmluZyB0aGlzIHJlYWQKKyAgICAgKiAgICAgICAgICAgICBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB0aHJlYWQgaXMgaW50ZXJydXB0ZWQgYnkgYW5vdGhlciB0aHJlYWQgZHVyaW5nIHRoaXMKKyAgICAgKiAgICAgICAgICAgICByZWFkIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIENsb3NlZENoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnM7IGRldGFpbHMgYXJlIGluIHRoZSBtZXNzYWdlLgorICAgICAqIEB0aHJvd3MgTm9uUmVhZGFibGVDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaGFzIG5vdCBiZWVuIG9wZW5lZCBpbiBhIG1vZGUgdGhhdCBwZXJtaXRzCisgICAgICogICAgICAgICAgICAgcmVhZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgbG9uZyByZWFkKEJ5dGVCdWZmZXJbXSBidWZmZXJzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcmVhZChidWZmZXJzLCAwLCBidWZmZXJzLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYnl0ZXMgZnJvbSB0aGlzIGZpbGUgY2hhbm5lbCBpbnRvIGEgc3Vic2V0IG9mIHRoZSBnaXZlbiBidWZmZXJzLgorICAgICAqIFRoaXMgbWV0aG9kIGF0dGVtcHRzIHRvIHJlYWQgYWxsIHtAY29kZSByZW1haW5pbmcoKX0gYnl0ZXMgZnJvbSB7QGNvZGUKKyAgICAgKiBsZW5ndGh9IGJ5dGUgYnVmZmVycywgaW4gb3JkZXIsIHN0YXJ0aW5nIGF0IHtAY29kZSB0YXJnZXRzW29mZnNldF19LiBJdAorICAgICAqIGluY3JlYXNlcyB0aGUgZmlsZSBwb3NpdGlvbiBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHJlYWQuIFRoZQorICAgICAqIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSByZWFkIGlzIHJldHVybmVkLgorICAgICAqIDxwPgorICAgICAqIElmIGEgcmVhZCBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MsIHN1YnNlcXVlbnQgdGhyZWFkcyB3aWxsIGJsb2NrIHVudGlsCisgICAgICogdGhlIHJlYWQgaXMgY29tcGxldGVkIGFuZCB3aWxsIHRoZW4gY29udGVuZCBmb3IgdGhlIGFiaWxpdHkgdG8gcmVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXJzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgYnl0ZSBidWZmZXJzIGludG8gd2hpY2ggdGhlIGJ5dGVzIHdpbGwgYmUgY29waWVkLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBidWZmZXIgdG8gc3RvcmUgYnl0ZXMgaW4uCisgICAgICogQHBhcmFtIG51bWJlcgorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gbnVtYmVyIG9mIGJ1ZmZlcnMgdG8gc3RvcmUgYnl0ZXMgaW4uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHJlYWQuCisgICAgICogQHRocm93cyBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQgYnkgYW5vdGhlciB0aHJlYWQgZHVyaW5nIHRoaXMgcmVhZAorICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHRocmVhZCBpcyBpbnRlcnJ1cHRlZCBieSBhbm90aGVyIHRocmVhZCBkdXJpbmcgdGhpcworICAgICAqICAgICAgICAgICAgIHJlYWQgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0IDwgMH0gb3Ige0Bjb2RlIG51bWJlciA8IDB9LCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBzdGFydCArIG51bWJlcn0gaXMgZ3JlYXRlciB0aGFuIHRoZSBzaXplIG9mCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGJ1ZmZlcnN9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnM7IGRldGFpbHMgYXJlIGluIHRoZSBtZXNzYWdlLgorICAgICAqIEB0aHJvd3MgTm9uUmVhZGFibGVDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaGFzIG5vdCBiZWVuIG9wZW5lZCBpbiBhIG1vZGUgdGhhdCBwZXJtaXRzCisgICAgICogICAgICAgICAgICAgcmVhZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgbG9uZyByZWFkKEJ5dGVCdWZmZXJbXSBidWZmZXJzLCBpbnQgc3RhcnQsIGludCBudW1iZXIpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzaXplIG9mIHRoZSBmaWxlIHVuZGVybHlpbmcgdGhpcyBjaGFubmVsIGluIGJ5dGVzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc2l6ZSBvZiB0aGUgZmlsZSBpbiBieXRlcy4KKyAgICAgKiBAdGhyb3dzIENsb3NlZENoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIGdldHRpbmcgdGhlIHNpemUgb2YgdGhlIGZpbGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGxvbmcgc2l6ZSgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIHVwIHRvIHtAY29kZSBjb3VudH0gYnl0ZXMgZnJvbSB7QGNvZGUgc3JjfSBhbmQgc3RvcmVzIHRoZW0gaW4gdGhpcworICAgICAqIGNoYW5uZWwncyBmaWxlIHN0YXJ0aW5nIGF0IHtAY29kZSBwb3NpdGlvbn0uIE5vIGJ5dGVzIGFyZSB0cmFuc2ZlcnJlZCBpZgorICAgICAqIHtAY29kZSBwb3NpdGlvbn0gaXMgbGFyZ2VyIHRoYW4gdGhlIHNpemUgb2YgdGhpcyBjaGFubmVsJ3MgZmlsZS4gTGVzcworICAgICAqIHRoYW4ge0Bjb2RlIGNvdW50fSBieXRlcyBhcmUgdHJhbnNmZXJyZWQgaWYgdGhlcmUgYXJlIGxlc3MgYnl0ZXMKKyAgICAgKiByZW1haW5pbmcgaW4gdGhlIHNvdXJjZSBjaGFubmVsIG9yIGlmIHRoZSBzb3VyY2UgY2hhbm5lbCBpcyBub24tYmxvY2tpbmcKKyAgICAgKiBhbmQgaGFzIGxlc3MgdGhhbiB7QGNvZGUgY291bnR9IGJ5dGVzIGltbWVkaWF0ZWx5IGF2YWlsYWJsZSBpbiBpdHMgb3V0cHV0CisgICAgICogYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIE5vdGUgdGhhdCB0aGlzIGNoYW5uZWwncyBwb3NpdGlvbiBpcyBub3QgbW9kaWZpZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGNoYW5uZWwgdG8gcmVhZCBieXRlcyBmcm9tLgorICAgICAqIEBwYXJhbSBwb3NpdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIG5vbi1uZWdhdGl2ZSBzdGFydCBwb3NpdGlvbi4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBub24tbmVnYXRpdmUgbnVtYmVyIG9mIGJ5dGVzIHRvIHRyYW5zZmVyLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IGFyZSB0cmFuc2ZlcnJlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYXJhbWV0ZXJzIGFyZSBpbnZhbGlkLgorICAgICAqIEB0aHJvd3MgTm9uUmVhZGFibGVDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNvdXJjZSBjaGFubmVsIGlzIG5vdCByZWFkYWJsZS4KKyAgICAgKiBAdGhyb3dzIE5vbldyaXRhYmxlQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBub3Qgd3JpdGFibGUuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZWl0aGVyIGNoYW5uZWwgaGFzIGFscmVhZHkgYmVlbiBjbG9zZWQuCisgICAgICogQHRocm93cyBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVpdGhlciBjaGFubmVsIGlzIGNsb3NlZCBieSBvdGhlciB0aHJlYWRzIGR1cmluZyB0aGlzCisgICAgICogICAgICAgICAgICAgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgdGhyZWFkIGlzIGludGVycnVwdGVkIGR1cmluZyB0aGlzIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGxvbmcgdHJhbnNmZXJGcm9tKFJlYWRhYmxlQnl0ZUNoYW5uZWwgc3JjLCBsb25nIHBvc2l0aW9uLAorICAgICAgICAgICAgbG9uZyBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgdXAgdG8ge0Bjb2RlIGNvdW50fSBieXRlcyBmcm9tIHRoaXMgY2hhbm5lbCdzIGZpbGUgc3RhcnRpbmcgYXQKKyAgICAgKiB7QGNvZGUgcG9zaXRpb259IGFuZCB3cml0ZXMgdGhlbSB0byB7QGNvZGUgdGFyZ2V0fS4gTm8gYnl0ZXMgYXJlCisgICAgICogdHJhbnNmZXJyZWQgaWYge0Bjb2RlIHBvc2l0aW9ufSBpcyBsYXJnZXIgdGhhbiB0aGUgc2l6ZSBvZiB0aGlzIGNoYW5uZWwncworICAgICAqIGZpbGUuIExlc3MgdGhhbiB7QGNvZGUgY291bnR9IGJ5dGVzIGFyZSB0cmFuc2ZlcnJlZCBpZiB0aGVyZSBsZXNzIGJ5dGVzCisgICAgICogYXZhaWxhYmxlIGZyb20gdGhpcyBjaGFubmVsJ3MgZmlsZSBvciBpZiB0aGUgdGFyZ2V0IGNoYW5uZWwgaXMKKyAgICAgKiBub24tYmxvY2tpbmcgYW5kIGhhcyBsZXNzIHRoYW4ge0Bjb2RlIGNvdW50fSBieXRlcyBmcmVlIGluIGl0cyBpbnB1dAorICAgICAqIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlIHRoYXQgdGhpcyBjaGFubmVsJ3MgcG9zaXRpb24gaXMgbm90IG1vZGlmaWVkLgorICAgICAqCisgICAgICogQHBhcmFtIHBvc2l0aW9uCisgICAgICogICAgICAgICAgICB0aGUgbm9uLW5lZ2F0aXZlIHBvc2l0aW9uIHRvIGJlZ2luLgorICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG5vbi1uZWdhdGl2ZSBudW1iZXIgb2YgYnl0ZXMgdG8gdHJhbnNmZXIuCisgICAgICogQHBhcmFtIHRhcmdldAorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBjaGFubmVsIHRvIHdyaXRlIHRvLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHdlcmUgdHJhbnNmZXJyZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFyYW1ldGVycyBhcmUgaW52YWxpZC4KKyAgICAgKiBAdGhyb3dzIE5vblJlYWRhYmxlQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBub3QgcmVhZGFibGUuCisgICAgICogQHRocm93cyBOb25Xcml0YWJsZUNoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgdGFyZ2V0IGNoYW5uZWwgaXMgbm90IHdyaXRhYmxlLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVpdGhlciBjaGFubmVsIGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBlaXRoZXIgY2hhbm5lbCBpcyBjbG9zZWQgYnkgb3RoZXIgdGhyZWFkcyBkdXJpbmcgdGhpcworICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHRocmVhZCBpcyBpbnRlcnJ1cHRlZCBkdXJpbmcgdGhpcyBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBsb25nIHRyYW5zZmVyVG8obG9uZyBwb3NpdGlvbiwgbG9uZyBjb3VudCwKKyAgICAgICAgICAgIFdyaXRhYmxlQnl0ZUNoYW5uZWwgdGFyZ2V0KSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBUcnVuY2F0ZXMgdGhlIGZpbGUgdW5kZXJseWluZyB0aGlzIGNoYW5uZWwgdG8gYSBnaXZlbiBzaXplLiBBbnkgYnl0ZXMKKyAgICAgKiBiZXlvbmQgdGhlIGdpdmVuIHNpemUgYXJlIHJlbW92ZWQgZnJvbSB0aGUgZmlsZS4gSWYgdGhlcmUgYXJlIG5vIGJ5dGVzCisgICAgICogYmV5b25kIHRoZSBnaXZlbiBzaXplIHRoZW4gdGhlIGZpbGUgY29udGVudHMgYXJlIHVubW9kaWZpZWQuCisgICAgICogPHA+CisgICAgICogSWYgdGhlIGZpbGUgcG9zaXRpb24gaXMgY3VycmVudGx5IGdyZWF0ZXIgdGhhbiB0aGUgZ2l2ZW4gc2l6ZSwgdGhlbiBpdCBpcworICAgICAqIHNldCB0byB0aGUgbmV3IHNpemUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gc2l6ZSBvZiB0aGUgdW5kZXJseWluZyBmaWxlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHJlcXVlc3RlZCBzaXplIGlzIG5lZ2F0aXZlLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBOb25Xcml0YWJsZUNoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBjYW5ub3QgYmUgd3JpdHRlbiB0by4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEByZXR1cm4gdGhpcyBjaGFubmVsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBGaWxlQ2hhbm5lbCB0cnVuY2F0ZShsb25nIHNpemUpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEF0dGVtcHRzIHRvIGFjcXVpcmUgYW4gZXhjbHVzaXZlIGxvY2sgb24gdGhpcyBmaWxlIHdpdGhvdXQgYmxvY2tpbmcuCisgICAgICogPHA+CisgICAgICogVGhpcyBpcyBhIGNvbnZlbmllbmNlIG1ldGhvZCBmb3IgYXR0ZW1wdGluZyB0byBhY3F1aXJlIGEgbWF4aW11bSBsZW5ndGgKKyAgICAgKiBsb2NrIG9uIHRoZSBmaWxlLiBJdCBpcyBlcXVpdmFsZW50IHRvOgorICAgICAqIHtAY29kZSBmaWxlQ2hhbm5lbC50cnlMb2NrKDBMLCBMb25nLk1BWF9WQUxVRSwgZmFsc2UpO30KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbWV0aG9kIHJldHVybnMge0Bjb2RlIG51bGx9IGlmIHRoZSBhY3F1aXNpdGlvbiB3b3VsZCByZXN1bHQgaW4gYW4KKyAgICAgKiBvdmVybGFwcGVkIGxvY2sgd2l0aCBhbm90aGVyIE9TIHByb2Nlc3MuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBmaWxlIGxvY2sgb2JqZWN0LCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIGxvY2sgd291bGQgb3ZlcmxhcAorICAgICAqICAgICAgICAgd2l0aCBhbiBleGlzdGluZyBleGNsdXNpdmUgbG9jayBpbiBhbm90aGVyIE9TIHByb2Nlc3MuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGZpbGUgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBPdmVybGFwcGluZ0ZpbGVMb2NrRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBsb2NrIGFscmVhZHkgZXhpc3RzIHRoYXQgb3ZlcmxhcHMgdGhpcyBsb2NrIHJlcXVlc3Qgb3IKKyAgICAgKiAgICAgICAgICAgICBhbm90aGVyIHRocmVhZCBpcyB3YWl0aW5nIHRvIGFjcXVpcmUgYSBsb2NrIHRoYXQgd2lsbCBvdmVybGFwCisgICAgICogICAgICAgICAgICAgd2l0aCB0aGlzIHJlcXVlc3QuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBGaWxlTG9jayB0cnlMb2NrKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHRyeUxvY2soMEwsIExvbmcuTUFYX1ZBTFVFLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gYWNxdWlyZSBhbiBleGNsdXNpdmUgbG9jayBvbiB0aGlzIGZpbGUgd2l0aG91dCBibG9ja2luZy4gVGhlCisgICAgICogbWV0aG9kIHJldHVybnMge0Bjb2RlIG51bGx9IGlmIHRoZSBhY3F1aXNpdGlvbiB3b3VsZCByZXN1bHQgaW4gYW4KKyAgICAgKiBvdmVybGFwcGVkIGxvY2sgd2l0aCBhbm90aGVyIE9TIHByb2Nlc3MuCisgICAgICogPHA+CisgICAgICogSXQgaXMgcG9zc2libGUgdG8gYWNxdWlyZSBhIGxvY2sgZm9yIGFueSByZWdpb24gZXZlbiBpZiBpdCdzIGNvbXBsZXRlbHkKKyAgICAgKiBvdXRzaWRlIG9mIHRoZSBmaWxlJ3Mgc2l6ZS4gVGhlIHNpemUgb2YgdGhlIGxvY2sgaXMgZml4ZWQuIElmIHRoZSBmaWxlCisgICAgICogZ3Jvd3Mgb3V0c2lkZSBvZiB0aGUgbG9jayB0aGF0IHJlZ2lvbiBvZiB0aGUgZmlsZSB3b24ndCBiZSBsb2NrZWQgYnkgdGhpcworICAgICAqIGxvY2suCisgICAgICoKKyAgICAgKiBAcGFyYW0gcG9zaXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydGluZyBwb3NpdGlvbi4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIHNpemUgb2YgZmlsZSB0byBsb2NrLgorICAgICAqIEBwYXJhbSBzaGFyZWQKKyAgICAgKiAgICAgICAgICAgIHRydWUgaWYgdGhlIGxvY2sgaXMgc2hhcmVkLgorICAgICAqIEByZXR1cm4gdGhlIGZpbGUgbG9jayBvYmplY3QsIG9yIHtAY29kZSBudWxsfSBpZiB0aGUgbG9jayB3b3VsZCBvdmVybGFwCisgICAgICogICAgICAgICB3aXRoIGFuIGV4aXN0aW5nIGV4Y2x1c2l2ZSBsb2NrIGluIGFub3RoZXIgT1MgcHJvY2Vzcy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBwYXJhbWV0ZXJzIGFyZSBpbnZhbGlkLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBmaWxlIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgT3ZlcmxhcHBpbmdGaWxlTG9ja0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgbG9jayBpcyBhbHJlYWR5IGhlbGQgdGhhdCBvdmVybGFwcyB0aGlzIGxvY2sgcmVxdWVzdCBvcgorICAgICAqICAgICAgICAgICAgIGFub3RoZXIgdGhyZWFkIGlzIHdhaXRpbmcgdG8gYWNxdWlyZSBhIGxvY2sgdGhhdCB3aWxsIG92ZXJsYXAKKyAgICAgKiAgICAgICAgICAgICB3aXRoIHRoaXMgcmVxdWVzdC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEZpbGVMb2NrIHRyeUxvY2sobG9uZyBwb3NpdGlvbiwgbG9uZyBzaXplLCBib29sZWFuIHNoYXJlZCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyBieXRlcyBmcm9tIHRoZSBnaXZlbiBieXRlIGJ1ZmZlciB0byB0aGlzIGZpbGUgY2hhbm5lbC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgYnl0ZXMgYXJlIHdyaXR0ZW4gc3RhcnRpbmcgYXQgdGhlIGN1cnJlbnQgZmlsZSBwb3NpdGlvbiwgYW5kIGFmdGVyCisgICAgICogc29tZSBudW1iZXIgb2YgYnl0ZXMgYXJlIHdyaXR0ZW4gKHVwIHRvIHRoZSByZW1haW5pbmcgbnVtYmVyIG9mIGJ5dGVzIGluCisgICAgICogdGhlIGJ1ZmZlcikgdGhlIGZpbGUgcG9zaXRpb24gaXMgaW5jcmVhc2VkIGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXMKKyAgICAgKiBhY3R1YWxseSB3cml0dGVuLgorICAgICAqCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIGJ5dGVzIHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHdyaXR0ZW4uCisgICAgICogQHRocm93cyBOb25Xcml0YWJsZUNoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCB3YXMgbm90IG9wZW5lZCBmb3Igd3JpdGluZy4KKyAgICAgKiBAdGhyb3dzIENsb3NlZENoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCB3YXMgYWxyZWFkeSBjbG9zZWQuCisgICAgICogQHRocm93cyBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgdGhyZWFkIGNsb3NlcyB0aGUgY2hhbm5lbCBkdXJpbmcgdGhlIHdyaXRlLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIHRocmVhZCBpbnRlcnJ1cHRzIHRoZSBjYWxsaW5nIHRocmVhZCB3aGlsZSB0aGlzCisgICAgICogICAgICAgICAgICAgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLiBUaGUgaW50ZXJydXB0IHN0YXRlIG9mIHRoZSBjYWxsaW5nCisgICAgICogICAgICAgICAgICAgdGhyZWFkIGlzIHNldCBhbmQgdGhlIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMsIGRldGFpbHMgYXJlIGluIHRoZSBtZXNzYWdlLgorICAgICAqIEBzZWUgamF2YS5uaW8uY2hhbm5lbHMuV3JpdGFibGVCeXRlQ2hhbm5lbCN3cml0ZShqYXZhLm5pby5CeXRlQnVmZmVyKQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgd3JpdGUoQnl0ZUJ1ZmZlciBzcmMpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyBieXRlcyBmcm9tIHRoZSBnaXZlbiBidWZmZXIgdG8gdGhpcyBmaWxlIGNoYW5uZWwgc3RhcnRpbmcgYXQgdGhlCisgICAgICogZ2l2ZW4gZmlsZSBwb3NpdGlvbi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgYnl0ZXMgYXJlIHdyaXR0ZW4gc3RhcnRpbmcgYXQgdGhlIGdpdmVuIGZpbGUgcG9zaXRpb24gKHVwIHRvIHRoZQorICAgICAqIHJlbWFpbmluZyBudW1iZXIgb2YgYnl0ZXMgaW4gdGhlIGJ1ZmZlcikuIFRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkKKyAgICAgKiB3cml0dGVuIGlzIHJldHVybmVkLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBwb3NpdGlvbiBpcyBiZXlvbmQgdGhlIGN1cnJlbnQgZW5kIG9mIGZpbGUsIHRoZW4gdGhlIGZpbGUgaXMgZmlyc3QKKyAgICAgKiBleHRlbmRlZCB1cCB0byB0aGUgZ2l2ZW4gcG9zaXRpb24gYnkgdGhlIHJlcXVpcmVkIG51bWJlciBvZiB1bnNwZWNpZmllZAorICAgICAqIGJ5dGUgdmFsdWVzLgorICAgICAqIDxwPgorICAgICAqIE5vdGUgdGhhdCB0aGUgZmlsZSBwb3NpdGlvbiBpcyBub3QgbW9kaWZpZWQgYnkgdGhpcyBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIGJ5dGVzIHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHBhcmFtIHBvc2l0aW9uCisgICAgICogICAgICAgICAgICB0aGUgKG5vbi1uZWdhdGl2ZSkgcG9zaXRpb24gYXQgd2hpY2ggdG8gd3JpdGUgdGhlIGJ5dGVzLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSB3cml0dGVuLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgPGNvZGU+cG9zaXRpb248L2NvZGU+IGlzIGxlc3MgdGhhbiAwLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBOb25Xcml0YWJsZUNoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCB3YXMgbm90IG9wZW5lZCBpbiB3cml0ZS1tb2RlLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgY2xvc2VkIGJ5IGFub3RoZXIgdGhyZWFkIHdoaWxlIHRoaXMgbWV0aG9kCisgICAgICogICAgICAgICAgICAgaXMgZXhlY3V0aW5nLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIHRocmVhZCBpbnRlcnJ1cHRzIHRoZSBjYWxsaW5nIHRocmVhZCB3aGlsZSB0aGlzCisgICAgICogICAgICAgICAgICAgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLiBUaGUgaW50ZXJydXB0IHN0YXRlIG9mIHRoZSBjYWxsaW5nCisgICAgICogICAgICAgICAgICAgdGhyZWFkIGlzIHNldCBhbmQgdGhlIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCB3cml0ZShCeXRlQnVmZmVyIGJ1ZmZlciwgbG9uZyBwb3NpdGlvbikKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyBieXRlcyBmcm9tIGFsbCB0aGUgZ2l2ZW4gYnl0ZSBidWZmZXJzIHRvIHRoaXMgZmlsZSBjaGFubmVsLgorICAgICAqIDxwPgorICAgICAqIFRoZSBieXRlcyBhcmUgd3JpdHRlbiBzdGFydGluZyBhdCB0aGUgY3VycmVudCBmaWxlIHBvc2l0aW9uLCBhbmQgYWZ0ZXIKKyAgICAgKiB0aGUgYnl0ZXMgYXJlIHdyaXR0ZW4gKHVwIHRvIHRoZSByZW1haW5pbmcgbnVtYmVyIG9mIGJ5dGVzIGluIGFsbCB0aGUKKyAgICAgKiBidWZmZXJzKSwgdGhlIGZpbGUgcG9zaXRpb24gaXMgaW5jcmVhc2VkIGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkKKyAgICAgKiB3cml0dGVuLgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byBjYWxsaW5nCisgICAgICoge0Bjb2RlIHdyaXRlKGJ1ZmZlcnMsIDAsIGJ1ZmZlcnMubGVuZ3RoKTt9CisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVycworICAgICAqICAgICAgICAgICAgdGhlIGJ1ZmZlcnMgY29udGFpbmluZyBieXRlcyB0byB3cml0ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgd3JpdHRlbi4KKyAgICAgKiBAdGhyb3dzIEFzeW5jaHJvbm91c0Nsb3NlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIGNsb3NlZCBieSBhbm90aGVyIHRocmVhZCBkdXJpbmcgdGhpcyB3cml0ZQorICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciB0aHJlYWQgaW50ZXJydXB0cyB0aGUgY2FsbGluZyB0aHJlYWQgd2hpbGUgdGhpcworICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcy4gVGhlIGludGVycnVwdCBzdGF0ZSBvZiB0aGUgY2FsbGluZworICAgICAqICAgICAgICAgICAgIHRocmVhZCBpcyBzZXQgYW5kIHRoZSBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIENsb3NlZENoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnM7IGRldGFpbHMgYXJlIGluIHRoZSBtZXNzYWdlLgorICAgICAqIEB0aHJvd3MgTm9uV3JpdGFibGVDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIHdhcyBub3Qgb3BlbmVkIGZvciB3cml0aW5nLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBsb25nIHdyaXRlKEJ5dGVCdWZmZXJbXSBidWZmZXJzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gd3JpdGUoYnVmZmVycywgMCwgYnVmZmVycy5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0dGVtcHRzIHRvIHdyaXRlIGEgc3Vic2V0IG9mIHRoZSBnaXZlbiBieXRlcyBmcm9tIHRoZSBidWZmZXJzIHRvIHRoaXMKKyAgICAgKiBmaWxlIGNoYW5uZWwuIFRoaXMgbWV0aG9kIGF0dGVtcHRzIHRvIHdyaXRlIGFsbCB7QGNvZGUgcmVtYWluaW5nKCl9CisgICAgICogYnl0ZXMgZnJvbSB7QGNvZGUgbGVuZ3RofSBieXRlIGJ1ZmZlcnMsIGluIG9yZGVyLCBzdGFydGluZyBhdCB7QGNvZGUKKyAgICAgKiBzb3VyY2VzW29mZnNldF19LiBUaGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHdyaXR0ZW4gaXMgcmV0dXJuZWQuCisgICAgICogPHA+CisgICAgICogSWYgYSB3cml0ZSBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MsIHN1YnNlcXVlbnQgdGhyZWFkcyB3aWxsIGJsb2NrIHVudGlsCisgICAgICogdGhlIHdyaXRlIGlzIGNvbXBsZXRlZCBhbmQgdGhlbiBjb250ZW5kIGZvciB0aGUgYWJpbGl0eSB0byB3cml0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXJzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgYnl0ZSBidWZmZXJzIHRoYXQgaXMgdGhlIHNvdXJjZSBmb3IgYnl0ZXMgd3JpdHRlbgorICAgICAqICAgICAgICAgICAgdG8gdGhpcyBjaGFubmVsLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgYnVmZmVyIGluIHtAY29kZSBidWZmZXJzIH10byBnZXQgYnl0ZXMKKyAgICAgKiAgICAgICAgICAgIGZyb20uCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBidWZmZXJzIHRvIGdldCBieXRlcyBmcm9tLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSB3cml0dGVuIHRvIHRoaXMgY2hhbm5lbC4KKyAgICAgKiBAdGhyb3dzIEFzeW5jaHJvbm91c0Nsb3NlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIGNsb3NlZCBieSBhbm90aGVyIHRocmVhZCBkdXJpbmcgdGhpcyB3cml0ZQorICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciB0aHJlYWQgaW50ZXJydXB0cyB0aGUgY2FsbGluZyB0aHJlYWQgd2hpbGUgdGhpcworICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcy4gVGhlIGludGVycnVwdCBzdGF0ZSBvZiB0aGUgY2FsbGluZworICAgICAqICAgICAgICAgICAgIHRocmVhZCBpcyBzZXQgYW5kIHRoZSBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIENsb3NlZENoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwfSBvciB7QGNvZGUgbGVuZ3RoIDwgMH0sIG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIG9mZnNldCArIGxlbmd0aH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBzaXplIG9mCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGJ1ZmZlcnN9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnM7IGRldGFpbHMgYXJlIGluIHRoZSBtZXNzYWdlLgorICAgICAqIEB0aHJvd3MgTm9uV3JpdGFibGVDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIHdhcyBub3Qgb3BlbmVkIGZvciB3cml0aW5nLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBsb25nIHdyaXRlKEJ5dGVCdWZmZXJbXSBidWZmZXJzLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0ZpbGVMb2NrLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvRmlsZUxvY2suamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wOTE2YmUwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0ZpbGVMb2NrLmphdmEKQEAgLTAsMCArMSwxOTcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhbm5lbHM7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIEEge0Bjb2RlIEZpbGVMb2NrfSByZXByZXNlbnRzIGEgbG9ja2VkIHJlZ2lvbiBvZiBhIGZpbGUuCisgKiA8cD4KKyAqIExvY2tzIGhhdmUgY2VydGFpbiBwcm9wZXJ0aWVzIHRoYXQgZW5hYmxlIGNvbGxhYm9yYXRpbmcgcHJvY2Vzc2VzIHRvIGF2b2lkCisgKiB0aGUgbG9zdCB1cGRhdGUgcHJvYmxlbSBvciByZWFkaW5nIGluY29uc2lzdGVudCBkYXRhLiBMb2dpY2FsbHksIGEgZmlsZSBsb2NrCisgKiBjYW4gYmUgPGVtPmV4Y2x1c2l2ZTwvZW0+IG9yIDxlbT5zaGFyZWQ8L2VtPi4gTXVsdGlwbGUgcHJvY2Vzc2VzIGNhbiBob2xkCisgKiBzaGFyZWQgbG9ja3Mgb24gdGhlIHNhbWUgcmVnaW9uIG9mIGEgZmlsZSwgYnV0IG9ubHkgYSBzaW5nbGUgcHJvY2VzcyBjYW4gaG9sZAorICogYW4gZXhjbHVzaXZlIGxvY2sgb24gYSBnaXZlbiByZWdpb24gb2YgYSBmaWxlIGFuZCBubyBvdGhlciBwcm9jZXNzIGNhbgorICogc2ltdWx0YW5lb3VzbHkgaG9sZCBhIHNoYXJlZCBsb2NrIG92ZXJsYXBwaW5nIHRoZSBleGNsdXNpdmUgbG9jay4gQW4KKyAqIGFwcGxpY2F0aW9uIGNhbiBkZXRlcm1pbmUgd2hldGhlciBhIHtAY29kZSBGaWxlTG9ja30gaXMgc2hhcmVkIG9yIGV4Y2x1c2l2ZQorICogdmlhIHRoZSB7QGNvZGUgaXNTaGFyZWQoKX0gbWV0aG9kLgorICogPHA+CisgKiBMb2NrcyBoZWxkIGJ5IGEgcGFydGljdWxhciBwcm9jZXNzIGNhbm5vdCBvdmVybGFwIG9uZSBhbm90aGVyLiBBcHBsaWNhdGlvbnMKKyAqIGNhbiBkZXRlcm1pbmUgd2hldGhlciBhIHByb3Bvc2VkIGxvY2sgd2lsbCBvdmVybGFwIGJ5IHVzaW5nIHRoZSB7QGNvZGUKKyAqIG92ZXJsYXBzKGxvbmcsIGxvbmcpfSkgbWV0aG9kLiBMb2NrcyBoZWxkIGluIG90aGVyIHByb2Nlc3NlcyBtYXkgb3ZlcmxhcAorICogbG9ja3MgaGVsZCBpbiB0aGlzIHByb2Nlc3MuIExvY2tzIGFyZSBzaGFyZWQgYW1vbmdzdCBhbGwgdGhyZWFkcyBpbiB0aGUKKyAqIGFjcXVpcmluZyBwcm9jZXNzLCBhbmQgYXJlIHRoZXJlZm9yZSB1bnN1aXRhYmxlIGZvciBpbnRyYS1wcm9jZXNzCisgKiBzeW5jaHJvbml6YXRpb24uCisgKiA8cD4KKyAqIE9uY2UgYSBsb2NrIGlzIGFjcXVpcmVkLCBpdCBpcyBpbW11dGFibGUgaW4gYWxsIGl0cyBzdGF0ZSBleGNlcHQge0Bjb2RlCisgKiBpc1ZhbGlkKCl9LiBUaGUgbG9jayB3aWxsIGluaXRpYWxseSBiZSB2YWxpZCwgYnV0IG1heSBiZSByZW5kZXJlZCBpbnZhbGlkIGJ5CisgKiBleHBsaWNpdCByZW1vdmFsIG9mIHRoZSBsb2NrLCB1c2luZyB7QGNvZGUgcmVsZWFzZSgpfSwgb3IgaW1wbGljaXRseSBieQorICogY2xvc2luZyB0aGUgY2hhbm5lbCBvciBleGl0aW5nIHRoZSBwcm9jZXNzICh0ZXJtaW5hdGluZyB0aGUgVk0pLgorICogPGgzPlBsYXRmb3JtIGRlcGVuZGVuY2llczwvaDM+CisgKiA8cD4KKyAqIExvY2tzIGFyZSBpbnRlbmRlZCB0byBiZSB0cnVlIHBsYXRmb3JtIG9wZXJhdGluZyBzeXN0ZW0gZmlsZSBsb2NrcywgYW5kCisgKiB0aGVyZWZvcmUgbG9ja3MgaGVsZCBieSB0aGUgVk0gd2lsbCBiZSB2aXNpYmxlIHRvIG90aGVyCisgKiBvcGVyYXRpbmcgc3lzdGVtIHByb2Nlc3Nlcy4KKyAqIDxwPgorICogVGhlIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgdW5kZXJseWluZyBvcGVyYXRpbmcgc3lzdGVtIGxvY2tzIHdpbGwgc2hvdworICogdGhyb3VnaCBpbiB0aGUgSmF2YSBpbXBsZW1lbnRhdGlvbi4gRm9yIGV4YW1wbGUsIHNvbWUgcGxhdGZvcm1zJyBsb2NrcyBhcmUKKyAqICdtYW5kYXRvcnknIC0tIG1lYW5pbmcgdGhlIG9wZXJhdGluZyBzeXN0ZW0gZW5mb3JjZXMgdGhlIGxvY2tzIG9uIHByb2Nlc3NlcworICogdGhhdCBhdHRlbXB0IHRvIGFjY2VzcyBsb2NrZWQgcmVnaW9ucyBvZiBmaWxlczsgd2hlcmVhcyBvdGhlciBwbGF0Zm9ybXMnCisgKiBsb2NrcyBhcmUgb25seSAnYWR2aXNvcnknIC0tIG1lYW5pbmcgdGhhdCBwcm9jZXNzZXMgYXJlIHJlcXVpcmVkIHRvCisgKiBjb2xsYWJvcmF0ZSB0byBlbnN1cmUgbG9ja3MgYXJlIGFjcXVpcmVkIGFuZCB0aGVyZSBpcyBhIHBvdGVudGlhbCBmb3IKKyAqIHByb2Nlc3NlcyB0byBub3QgcGxheSB3ZWxsLiBUbyBiZSBvbiB0aGUgc2FmZSBzaWRlLCBpdCBpcyBiZXN0IHRvIGFzc3VtZSB0aGF0CisgKiB0aGUgcGxhdGZvcm0gaXMgYWRvcHRpbmcgYWR2aXNvcnkgbG9ja3MgYW5kIGFsd2F5cyBhY3F1aXJlIHNoYXJlZCBsb2NrcyB3aGVuCisgKiByZWFkaW5nIGEgcmVnaW9uIG9mIGEgZmlsZS4KKyAqIDxwPgorICogT24gc29tZSBwbGF0Zm9ybXMsIHRoZSBwcmVzZW5jZSBvZiBhIGxvY2sgd2lsbCBwcmV2ZW50IHRoZSBmaWxlIGZyb20gYmVpbmcKKyAqIG1lbW9yeS1tYXBwZWQuIE9uIHNvbWUgcGxhdGZvcm1zLCBjbG9zaW5nIGEgY2hhbm5lbCBvbiBhIGdpdmVuIGZpbGUgaGFuZGxlCisgKiB3aWxsIHJlbGVhc2UgYWxsIHRoZSBsb2NrcyBoZWxkIG9uIHRoYXQgZmlsZSAtLSBldmVuIGlmIHRoZXJlIGFyZSBvdGhlcgorICogY2hhbm5lbHMgb3BlbiBvbiB0aGUgc2FtZSBmaWxlOyB0aGVpciBsb2NrcyB3aWxsIGFsc28gYmUgcmVsZWFzZWQuIFRoZSBzYWZlCisgKiBvcHRpb24gaGVyZSBpcyB0byBlbnN1cmUgdGhhdCB5b3Ugb25seSBhY3F1aXJlIGxvY2tzIG9uIGEgc2luZ2xlIGNoYW5uZWwgZm9yCisgKiBhIHBhcnRpY3VsYXIgZmlsZSBhbmQgdGhhdCBiZWNvbWVzIHRoZSBzeW5jaHJvbml6YXRpb24gcG9pbnQuCisgKiA8cD4KKyAqIEZ1cnRoZXIgY2FyZSBzaG91bGQgYmUgZXhlcmNpc2VkIHdoZW4gbG9ja2luZyBmaWxlcyBtYWludGFpbmVkIG9uIG5ldHdvcmsKKyAqIGZpbGUgc3lzdGVtcywgc2luY2UgdGhleSBvZnRlbiBoYXZlIGZ1cnRoZXIgbGltaXRhdGlvbnMuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBGaWxlTG9jayB7CisKKyAgICAvLyBUaGUgdW5kZXJseWluZyBmaWxlIGNoYW5uZWwuCisgICAgcHJpdmF0ZSBmaW5hbCBGaWxlQ2hhbm5lbCBjaGFubmVsOworCisgICAgLy8gVGhlIGxvY2sgc3RhcnRpbmcgcG9zaXRpb24uCisgICAgcHJpdmF0ZSBmaW5hbCBsb25nIHBvc2l0aW9uOworCisgICAgLy8gVGhlIGxvY2sgbGVuZ3RoIGluIGJ5dGVzCisgICAgcHJpdmF0ZSBmaW5hbCBsb25nIHNpemU7CisKKyAgICAvLyBJZiB0cnVlIHRoZW4gc2hhcmVkLCBpZiBmYWxzZSB0aGVuIGV4Y2x1c2l2ZQorICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBzaGFyZWQ7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGZpbGUgbG9jayBpbnN0YW5jZSBmb3IgYSBnaXZlbiBjaGFubmVsLiBUaGUgY29uc3RydWN0b3IKKyAgICAgKiBlbmZvcmNlcyB0aGUgc3RhcnRpbmcgcG9zaXRpb24sIGxlbmd0aCBhbmQgc2hhcmluZyBtb2RlIG9mIHRoZSBsb2NrLgorICAgICAqCisgICAgICogQHBhcmFtIGNoYW5uZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSB1bmRlcmx5aW5nIGZpbGUgY2hhbm5lbCB0aGF0IGhvbGRzIHRoZSBsb2NrLgorICAgICAqIEBwYXJhbSBwb3NpdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIHBvaW50IGZvciB0aGUgbG9jay4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgbG9jayBpbiBudW1iZXIgb2YgYnl0ZXMuCisgICAgICogQHBhcmFtIHNoYXJlZAorICAgICAqICAgICAgICAgICAgdGhlIGxvY2sncyBzaGFyaW5nIG1vZGUgb2YgbG9jazsge0Bjb2RlIHRydWV9IGlzIHNoYXJlZCwKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBmYWxzZX0gaXMgZXhjbHVzaXZlLgorICAgICAqLworICAgIHByb3RlY3RlZCBGaWxlTG9jayhGaWxlQ2hhbm5lbCBjaGFubmVsLCBsb25nIHBvc2l0aW9uLCBsb25nIHNpemUsIGJvb2xlYW4gc2hhcmVkKSB7CisgICAgICAgIGlmIChwb3NpdGlvbiA8IDAgfHwgc2l6ZSA8IDAgfHwgcG9zaXRpb24gKyBzaXplIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWw7CisgICAgICAgIHRoaXMucG9zaXRpb24gPSBwb3NpdGlvbjsKKyAgICAgICAgdGhpcy5zaXplID0gc2l6ZTsKKyAgICAgICAgdGhpcy5zaGFyZWQgPSBzaGFyZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbG9jaydzIHtAbGluayBGaWxlQ2hhbm5lbH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFubmVsLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBGaWxlQ2hhbm5lbCBjaGFubmVsKCkgeworICAgICAgICByZXR1cm4gY2hhbm5lbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb2NrJ3Mgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGZpbGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsb2NrIHBvc2l0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBsb25nIHBvc2l0aW9uKCkgeworICAgICAgICByZXR1cm4gcG9zaXRpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBmaWxlIGxvY2sgaW4gYnl0ZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzaXplIG9mIHRoZSBmaWxlIGxvY2sgaW4gYnl0ZXMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgc2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIHNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIGlmIHRoZSBmaWxlIGxvY2sgaXMgc2hhcmVkIHdpdGggb3RoZXIgcHJvY2Vzc2VzIG9yIGlmIGl0IGlzCisgICAgICogZXhjbHVzaXZlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGxvY2sgaXMgYSBzaGFyZWQgbG9jaywge0Bjb2RlIGZhbHNlfSBpZiBpdCBpcworICAgICAqICAgICAgICAgZXhjbHVzaXZlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzU2hhcmVkKCkgeworICAgICAgICByZXR1cm4gc2hhcmVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyBpZiB0aGUgcmVjZWl2ZXIncyBsb2NrIHJlZ2lvbiBvdmVybGFwcyB0aGUgcmVnaW9uIGRlc2NyaWJlZAorICAgICAqIGluIHRoZSBwYXJhbWV0ZXIgbGlzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0aW5nIHBvc2l0aW9uIGZvciB0aGUgY29tcGFyYXRpdmUgbG9jay4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBjb21wYXJhdGl2ZSBsb2NrLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZXJlIGlzIGFuIG92ZXJsYXAsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIG92ZXJsYXBzKGxvbmcgc3RhcnQsIGxvbmcgbGVuZ3RoKSB7CisgICAgICAgIGZpbmFsIGxvbmcgZW5kID0gcG9zaXRpb24gKyBzaXplIC0gMTsKKyAgICAgICAgZmluYWwgbG9uZyBuZXdFbmQgPSBzdGFydCArIGxlbmd0aCAtIDE7CisgICAgICAgIGlmIChlbmQgPCBzdGFydCB8fCBwb3NpdGlvbiA+IG5ld0VuZCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgbG9jayBpcyBhIHZhbGlkIGZpbGUgbG9jay4gVGhlIGxvY2sgaXMKKyAgICAgKiB2YWxpZCB1bmxlc3MgdGhlIHVuZGVybHlpbmcgY2hhbm5lbCBoYXMgYmVlbiBjbG9zZWQgb3IgaXQgaGFzIGJlZW4KKyAgICAgKiBleHBsaWNpdGx5IHJlbGVhc2VkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGxvY2sgaXMgdmFsaWQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzVmFsaWQoKTsKKworICAgIC8qKgorICAgICAqIFJlbGVhc2VzIHRoaXMgcGFydGljdWxhciBsb2NrIG9uIHRoZSBmaWxlLiBJZiB0aGUgbG9jayBpcyBpbnZhbGlkIHRoZW4KKyAgICAgKiB0aGlzIG1ldGhvZCBoYXMgbm8gZWZmZWN0LiBPbmNlIHJlbGVhc2VkLCB0aGUgbG9jayBiZWNvbWVzIGludmFsaWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIENsb3NlZENoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBpcyBhbHJlYWR5IGNsb3NlZCB3aGVuIGFuIGF0dGVtcHQgdG8gcmVsZWFzZQorICAgICAqICAgICAgICAgICAgIHRoZSBsb2NrIGlzIG1hZGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCByZWxlYXNlKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyB0aGF0IHNob3dzIHRoZSBkZXRhaWxzIG9mIHRoZSBsb2NrIHN1aXRhYmxlIGZvciBkaXNwbGF5CisgICAgICogdG8gYW4gZW5kIHVzZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkaXNwbGF5IHN0cmluZy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gIkZpbGVMb2NrW3Bvc2l0aW9uPSIgKyBwb3NpdGlvbiArICIsIHNpemU9IiArIHNpemUgKyAiLCBzaGFyZWQ9IiArIHNoYXJlZCArICJdIjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvRmlsZUxvY2tJbnRlcnJ1cHRpb25FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9GaWxlTG9ja0ludGVycnVwdGlvbkV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFhNDA5NzcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvRmlsZUxvY2tJbnRlcnJ1cHRpb25FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDM2IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYW5uZWxzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBBIHtAY29kZSBGaWxlTG9ja0ludGVycnVwdGlvbkV4Y2VwdGlvbn0gaXMgdGhyb3duIHdoZW4gYSB0aHJlYWQgaXMKKyAqIGludGVycnVwdGVkIHdoaWxlIHdhaXRpbmcgdG8gYWNxdWlyZSBhIGZpbGUgbG9jay4KKyAqIDxwPgorICogTm90ZSB0aGF0IHRoZSB0aHJlYWQgd2lsbCBhbHNvIGJlIGluIHRoZSAnaW50ZXJydXB0ZWQnIHN0YXRlLgorICovCitwdWJsaWMgY2xhc3MgRmlsZUxvY2tJbnRlcnJ1cHRpb25FeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3MTA0MDgwNjQzNjUzNTMyMzgzTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgRmlsZUxvY2tJbnRlcnJ1cHRpb25FeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBGaWxlTG9ja0ludGVycnVwdGlvbkV4Y2VwdGlvbigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvR2F0aGVyaW5nQnl0ZUNoYW5uZWwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9HYXRoZXJpbmdCeXRlQ2hhbm5lbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkxMmI4YmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvR2F0aGVyaW5nQnl0ZUNoYW5uZWwuamF2YQpAQCAtMCwwICsxLDk1IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYW5uZWxzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworCisvKioKKyAqIFRoZSBpbnRlcmZhY2UgZm9yIGNoYW5uZWxzIHRoYXQgY2FuIHdyaXRlIGEgc2V0IG9mIGJ1ZmZlcnMgaW4gYSBzaW5nbGUKKyAqIG9wZXJhdGlvbi4gVGhlIGNvcnJlc3BvbmRpbmcgaW50ZXJmYWNlIGZvciByZWFkIG9wZXJhdGlvbnMgaXMKKyAqIHtAbGluayBTY2F0dGVyaW5nQnl0ZUNoYW5uZWx9LgorICovCitwdWJsaWMgaW50ZXJmYWNlIEdhdGhlcmluZ0J5dGVDaGFubmVsIGV4dGVuZHMgV3JpdGFibGVCeXRlQ2hhbm5lbCB7CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYnl0ZXMgZnJvbSBhbGwgdGhlIGdpdmVuIGJ1ZmZlcnMgdG8gYSBjaGFubmVsLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG86IHtAY29kZSB3cml0ZShidWZmZXJzLCAwLCBidWZmZXJzLmxlbmd0aCk7fQorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXJzIGNvbnRhaW5pbmcgYnl0ZXMgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgd3JpdHRlbi4KKyAgICAgKiBAdGhyb3dzIEFzeW5jaHJvbm91c0Nsb3NlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaXMgY2xvc2VkIGJ5IGFub3RoZXIgdGhyZWFkIGR1cmluZyB0aGlzIHdyaXRlCisgICAgICogICAgICAgICAgICAgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIHRocmVhZCBpbnRlcnJ1cHRzIHRoZSBjYWxsaW5nIHRocmVhZCB3aGlsZSB0aGUKKyAgICAgKiAgICAgICAgICAgICBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MuIFRoZSBpbnRlcnJ1cHQgc3RhdGUgb2YgdGhlIGNhbGxpbmcKKyAgICAgKiAgICAgICAgICAgICB0aHJlYWQgaXMgc2V0IGFuZCB0aGUgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXQgPCAwfSBvciB7QGNvZGUgbGVuZ3RoIDwgMH0sIG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIG9mZnNldCArIGxlbmd0aH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBzaXplIG9mCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGJ1ZmZlcnN9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnM7IGRldGFpbHMgYXJlIGluIHRoZSBtZXNzYWdlLgorICAgICAqIEB0aHJvd3MgTm9uV3JpdGFibGVDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaGFzIG5vdCBiZWVuIG9wZW5lZCBpbiBhIG1vZGUgdGhhdCBwZXJtaXRzCisgICAgICogICAgICAgICAgICAgd3JpdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyB3cml0ZShCeXRlQnVmZmVyW10gYnVmZmVycykgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gd3JpdGUgYWxsIDxjb2RlPnJlbWFpbmluZygpPC9jb2RlPiBieXRlcyBmcm9tIHtAY29kZSBsZW5ndGh9CisgICAgICogYnl0ZSBidWZmZXJzLCBpbiBvcmRlciwgc3RhcnRpbmcgYXQge0Bjb2RlIGJ1ZmZlcnNbb2Zmc2V0XX0uIFRoZSBudW1iZXIKKyAgICAgKiBvZiBieXRlcyBhY3R1YWxseSB3cml0dGVuIGlzIHJldHVybmVkLgorICAgICAqIDxwPgorICAgICAqIElmIGEgd3JpdGUgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLCBzdWJzZXF1ZW50IHRocmVhZHMgd2lsbCBibG9jayB1bnRpbAorICAgICAqIHRoZSB3cml0ZSBpcyBjb21wbGV0ZWQgYW5kIHRoZW4gY29udGVuZCBmb3IgdGhlIGFiaWxpdHkgdG8gd3JpdGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVycworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIGJ5dGUgYnVmZmVycyB0aGF0IGlzIHRoZSBzb3VyY2UgZm9yIGJ5dGVzIHdyaXR0ZW4KKyAgICAgKiAgICAgICAgICAgIHRvIHRoZSBjaGFubmVsLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgYnVmZmVyIGluIHtAY29kZSBidWZmZXJzIH10byBnZXQgYnl0ZXMKKyAgICAgKiAgICAgICAgICAgIGZyb20uCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBidWZmZXJzIHRvIGdldCBieXRlcyBmcm9tLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSB3cml0dGVuLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBpcyBjbG9zZWQgYnkgYW5vdGhlciB0aHJlYWQgZHVyaW5nIHRoaXMgd3JpdGUKKyAgICAgKiAgICAgICAgICAgICBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgdGhyZWFkIGludGVycnVwdHMgdGhlIGNhbGxpbmcgdGhyZWFkIHdoaWxlIHRoZQorICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcy4gVGhlIGludGVycnVwdCBzdGF0ZSBvZiB0aGUgY2FsbGluZworICAgICAqICAgICAgICAgICAgIHRocmVhZCBpcyBzZXQgYW5kIHRoZSBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIENsb3NlZENoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBsZW5ndGggPCAwfSwgb3IgaWYKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgb2Zmc2V0ICsgbGVuZ3RofSBpcyBncmVhdGVyIHRoYW4gdGhlIHNpemUgb2YKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgYnVmZmVyc30uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgSS9PIGVycm9yIG9jY3VyczsgZGV0YWlscyBhcmUgaW4gdGhlIG1lc3NhZ2UuCisgICAgICogQHRocm93cyBOb25Xcml0YWJsZUNoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCB3YXMgbm90IG9wZW5lZCBmb3Igd3JpdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyB3cml0ZShCeXRlQnVmZmVyW10gYnVmZmVycywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9JbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU1NGRmNTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzMgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhbm5lbHM7CisKKy8qKgorICogQW4ge0Bjb2RlIElsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb259IGlzIHRocm93biB3aGVuIGFuIG9wZXJhdGlvbiB0aGF0CisgKiByZXF1aXJlcyBhIHNwZWNpZmljIGJsb2NraW5nIG1vZGUgaXMgaW52b2tlZCBvbiBhIGNoYW5uZWwgdGhhdCBpcyBpbiBhCisgKiBkaWZmZXJlbnQgYmxvY2tpbmcgbW9kZS4KKyAqLworcHVibGljIGNsYXNzIElsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb24gZXh0ZW5kcyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTMzMzU3NzQ5NjE4NTU1OTA0NzRMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBJbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvSWxsZWdhbFNlbGVjdG9yRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvSWxsZWdhbFNlbGVjdG9yRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmZiNjkwZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9JbGxlZ2FsU2VsZWN0b3JFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDMyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYW5uZWxzOworCisvKioKKyAqIEFuIHtAY29kZSBJbGxlZ2FsU2VsZWN0b3JFeGNlcHRpb259IGlzIHRocm93biB3aGVuIGEgY2FsbCBpcyBtYWRlIHRvIHJlZ2lzdGVyCisgKiBhIGNoYW5uZWwgb24gYSBzZWxlY3RvciB0aGF0IGhhcyBiZWVuIGNyZWF0ZWQgYnkgYSBkaWZmZXJlbnQgcHJvdmlkZXIuCisgKi8KK3B1YmxpYyBjbGFzcyBJbGxlZ2FsU2VsZWN0b3JFeGNlcHRpb24gZXh0ZW5kcyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTg0MDYzMjMzNDcyNTMzMjA5ODdMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBJbGxlZ2FsU2VsZWN0b3JFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBJbGxlZ2FsU2VsZWN0b3JFeGNlcHRpb24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0ludGVycnVwdGlibGVDaGFubmVsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvSW50ZXJydXB0aWJsZUNoYW5uZWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNWVhNWQ0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL0ludGVycnVwdGlibGVDaGFubmVsLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFubmVsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogQ2hhbm5lbHMgdGhhdCBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UgY2FuIGJlIGFzeW5jaHJvbm91c2x5IGNsb3NlZCBhbmQKKyAqIGludGVycnVwdGVkLgorICogPHA+CisgKiBBIGNoYW5uZWwgdGhhdCBjYW4gYmUgYXN5bmNocm9ub3VzbHkgY2xvc2VkIHBlcm1pdHMgdGhhdCBhIHRocmVhZCBibG9ja2VkIG9uCisgKiBhbiBJL08gb3BlcmF0aW9uICh0aGUgSS9PIHRocmVhZCkgY2FuIGJlIHJlbGVhc2VkIGJ5IGFub3RoZXIgdGhyZWFkIGNhbGxpbmcKKyAqIHRoZSBjaGFubmVsJ3Mge0BsaW5rICNjbG9zZSgpfSBtZXRob2QuIFRoZSBJL08gdGhyZWFkIHdpbGwgdGhyb3cgYW4KKyAqIHtAbGluayBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbn0gYW5kIHRoZSBjaGFubmVsIHdpbGwgYmUgY2xvc2VkLgorICogPHA+CisgKiBBIGNoYW5uZWwgdGhhdCBpcyBpbnRlcnJ1cHRpYmxlIHBlcm1pdHMgYSB0aHJlYWQgYmxvY2tlZCBvbiBhbiBJL08gb3BlcmF0aW9uCisgKiAodGhlIEkvTyB0aHJlYWQpIHRvIGJlIGludGVycnVwdGVkIGJ5IGFub3RoZXIgdGhyZWFkIChieSBpbnZva2luZworICoge0BsaW5rIFRocmVhZCNpbnRlcnJ1cHQoKX0gb24gdGhlIEkvTyB0aHJlYWQpLiBXaGVuIHRoZSBJL08gdGhyZWFkIGlzCisgKiBpbnRlcnJ1cHRlZCBpdCB3aWxsIHRocm93IGEge0BsaW5rIENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9ufSwgaXQgd2lsbCBoYXZlCisgKiBpdHMgaW50ZXJydXB0ZWQgc3RhdHVzIHNldCBhbmQgdGhlIGNoYW5uZWwgd2lsbCBiZSBjbG9zZWQuIElmIHRoZSBJL08gdGhyZWFkCisgKiBhdHRlbXB0cyB0byBtYWtlIGFuIEkvTyBjYWxsIHdpdGggdGhlIGludGVycnVwdCBzdGF0dXMgc2V0IHRoZSBjYWxsIHdpbGwKKyAqIGltbWVkaWF0ZWx5IGZhaWwgd2l0aCBhIHtAbGluayBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbn0uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSW50ZXJydXB0aWJsZUNoYW5uZWwgZXh0ZW5kcyBDaGFubmVsIHsKKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGUgY2hhbm5lbC4KKyAgICAgKiA8cD4KKyAgICAgKiBBbnkgdGhyZWFkcyB0aGF0IGFyZSBibG9ja2VkIG9uIEkvTyBvcGVyYXRpb25zIG9uIHRoaXMgY2hhbm5lbCB3aWxsIGJlCisgICAgICogaW50ZXJydXB0ZWQgd2l0aCBhbiB7QGxpbmsgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb259LiBPdGhlcndpc2UsIHRoaXMKKyAgICAgKiBtZXRob2QgYmVoYXZlcyB0aGUgc2FtZSBhcyBkZWZpbmVkIGluIHRoZSB7QGNvZGUgQ2hhbm5lbH0gaW50ZXJmYWNlLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMgd2hpbGUgY2xvc2luZyB0aGUgY2hhbm5lbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9Ob0Nvbm5lY3Rpb25QZW5kaW5nRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvTm9Db25uZWN0aW9uUGVuZGluZ0V4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhYjE4YTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvTm9Db25uZWN0aW9uUGVuZGluZ0V4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzUgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhbm5lbHM7CisKKy8qKgorICogQSB7QGNvZGUgTm9Db25uZWN0aW9uUGVuZGluZ0V4Y2VwdGlvbn0gaXMgdGhyb3duIGlmIHtAY29kZSBTb2NrZXRDaGFubmVsfSdzCisgKiB7QGxpbmsgU29ja2V0Q2hhbm5lbCNmaW5pc2hDb25uZWN0KCkgZmluaXNoQ29ubmVjdH0gbWV0aG9kIGlzIGNhbGxlZCBiZWZvcmUKKyAqIHRoZSB7QGNvZGUgU29ja2V0Q2hhbm5lbH0ncyB7QGxpbmsKKyAqIFNvY2tldENoYW5uZWwjY29ubmVjdChqYXZhLm5ldC5Tb2NrZXRBZGRyZXNzKX0gY29ubmVjdH0gbWV0aG9kIGNvbXBsZXRlZAorICogd2l0aG91dCBlcnJvci4KKyAqLworcHVibGljIGNsYXNzIE5vQ29ubmVjdGlvblBlbmRpbmdFeGNlcHRpb24gZXh0ZW5kcyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTgyOTY1NjExODM2MzMxMzQ3NDNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBOb0Nvbm5lY3Rpb25QZW5kaW5nRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9Db25uZWN0aW9uUGVuZGluZ0V4Y2VwdGlvbigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvTm9uUmVhZGFibGVDaGFubmVsRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvTm9uUmVhZGFibGVDaGFubmVsRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGQ2MzQ4NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9Ob25SZWFkYWJsZUNoYW5uZWxFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDMyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYW5uZWxzOworCisvKioKKyAqIEEge0Bjb2RlIE5vblJlYWRhYmxlQ2hhbm5lbEV4Y2VwdGlvbn0gaXMgdGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byByZWFkIGZyb20KKyAqIGEgY2hhbm5lbCB0aGF0IGlzIG5vdCBvcGVuIGZvciByZWFkaW5nLgorICovCitwdWJsaWMgY2xhc3MgTm9uUmVhZGFibGVDaGFubmVsRXhjZXB0aW9uIGV4dGVuZHMgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0zMjAwOTE1Njc5Mjk0OTkzNTE0TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgTm9uUmVhZGFibGVDaGFubmVsRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9uUmVhZGFibGVDaGFubmVsRXhjZXB0aW9uKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9Ob25Xcml0YWJsZUNoYW5uZWxFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9Ob25Xcml0YWJsZUNoYW5uZWxFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZDU0M2RjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL05vbldyaXRhYmxlQ2hhbm5lbEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzIgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhbm5lbHM7CisKKy8qKgorICogQSB7QGNvZGUgTm9uV3JpdGFibGVDaGFubmVsRXhjZXB0aW9ufSBpcyB0aHJvd24gd2hlbiBhdHRlbXB0aW5nIHRvIHdyaXRlIHRvIGEKKyAqIGNoYW5uZWwgdGhhdCBpcyBub3Qgb3BlbiBmb3Igd3JpdGluZy4KKyAqLworcHVibGljIGNsYXNzIE5vbldyaXRhYmxlQ2hhbm5lbEV4Y2VwdGlvbiBleHRlbmRzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNzA3MTIzMDQ4ODI3OTAxMTYyMUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIE5vbldyaXRhYmxlQ2hhbm5lbEV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIE5vbldyaXRhYmxlQ2hhbm5lbEV4Y2VwdGlvbigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvTm90WWV0Qm91bmRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9Ob3RZZXRCb3VuZEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU3MjU0YzQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvTm90WWV0Qm91bmRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDMyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYW5uZWxzOworCisvKioKKyAqIEEge0Bjb2RlIE5vdFlldEJvdW5kRXhjZXB0aW9ufSBpcyB0aHJvd24gaWYgdGhlIHNlcnZlciBzb2NrZXQgY2hhbm5lbCBpcyBub3QKKyAqIGJvdW5kIGJlZm9yZSBhbiBJL08gb3BlcmF0aW9uIGlzIG1hZGUuCisgKi8KK3B1YmxpYyBjbGFzcyBOb3RZZXRCb3VuZEV4Y2VwdGlvbiBleHRlbmRzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0NjQwOTk5MzAzOTUwMjAyMjQyTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgTm90WWV0Qm91bmRFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBOb3RZZXRCb3VuZEV4Y2VwdGlvbigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvTm90WWV0Q29ubmVjdGVkRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvTm90WWV0Q29ubmVjdGVkRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2E3NmVmMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9Ob3RZZXRDb25uZWN0ZWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDMyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYW5uZWxzOworCisvKioKKyAqIEEge0Bjb2RlIE5vdFlldENvbm5lY3RlZEV4Y2VwdGlvbn0gaXMgdGhyb3duIGlmIHRoZSBzb2NrZXQgY2hhbm5lbCBpcyBub3QKKyAqIGNvbm5lY3RlZCBiZWZvcmUgYW4gSS9PIG9wZXJhdGlvbiBpcyBpbnZva2VkLgorICovCitwdWJsaWMgY2xhc3MgTm90WWV0Q29ubmVjdGVkRXhjZXB0aW9uIGV4dGVuZHMgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDQ2OTczMTY1NTE5MDk1MTM0NjRMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBOb3RZZXRDb25uZWN0ZWRFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBOb3RZZXRDb25uZWN0ZWRFeGNlcHRpb24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL092ZXJsYXBwaW5nRmlsZUxvY2tFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9PdmVybGFwcGluZ0ZpbGVMb2NrRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzQxOTQ2MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9PdmVybGFwcGluZ0ZpbGVMb2NrRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzMiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFubmVsczsKKworLyoqCisgKiBBbiB7QGNvZGUgT3ZlcmxhcHBpbmdGaWxlTG9ja0V4Y2VwdGlvbn0gaXMgdGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byBhY3F1aXJlCisgKiBhIGxvY2sgdGhhdCBvdmVybGFwcyBhbiBleGlzdGluZyBvciBwZW5kaW5nIGxvY2sgaGVsZCBieSB0aGlzIHByb2Nlc3MuCisgKi8KK3B1YmxpYyBjbGFzcyBPdmVybGFwcGluZ0ZpbGVMb2NrRXhjZXB0aW9uIGV4dGVuZHMgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDIwNDc4MTIxMzgxNjMwNjg0MzNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBPdmVybGFwcGluZ0ZpbGVMb2NrRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgT3ZlcmxhcHBpbmdGaWxlTG9ja0V4Y2VwdGlvbigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvUGlwZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL1BpcGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZDU2YTBiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL1BpcGUuamF2YQpAQCAtMCwwICsxLDExMSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFubmVsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuc3BpLkFic3RyYWN0U2VsZWN0YWJsZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuc3BpLlNlbGVjdG9yUHJvdmlkZXI7CisKKy8qKgorICogQSBwaXBlIGNvbnRhaW5zIHR3byBjaGFubmVscywgZm9ybWluZyBhIHVuaWRpcmVjdGlvbmFsIHBpcGUuIE9uZSBpcyB0aGUgd3JpdGFibGUgc2luayBjaGFubmVsLAorICogYW5kIHRoZSBvdGhlciBpcyB0aGUgcmVhZGFibGUgc291cmNlIGNoYW5uZWwuIFdoZW4gYnl0ZXMgYXJlIHdyaXR0ZW4gaW50byB0aGUgd3JpdGFibGUKKyAqIGNoYW5uZWwgdGhleSBjYW4gYmUgcmVhZCBmcm9tIHRoZSByZWFkYWJsZSBjaGFubmVsLiBCeXRlcyBhcmUgcmVhZCBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleQorICogd2VyZSB3cml0dGVuLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgUGlwZSB7CisgICAgLyoqCisgICAgICogV3JpdGFibGUgc2luayBjaGFubmVsIHVzZWQgdG8gd3JpdGUgdG8gYSBwaXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgU2lua0NoYW5uZWwgZXh0ZW5kcyBBYnN0cmFjdFNlbGVjdGFibGVDaGFubmVsCisgICAgICAgICAgICBpbXBsZW1lbnRzIFdyaXRhYmxlQnl0ZUNoYW5uZWwsIEdhdGhlcmluZ0J5dGVDaGFubmVsIHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFNpbmtDaGFubmVsfS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHByb3ZpZGVyIG9mIHRoZSBjaGFubmVsLgorICAgICAgICAgKi8KKyAgICAgICAgcHJvdGVjdGVkIFNpbmtDaGFubmVsKFNlbGVjdG9yUHJvdmlkZXIgcHJvdmlkZXIpIHsKKyAgICAgICAgICAgIHN1cGVyKHByb3ZpZGVyKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGlzIGNoYW5uZWwgb25seSBzdXBwb3J0cyB3cml0aW5nLgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIGEgc3RhdGljIHZhbHVlIG9mIE9QX1dSSVRFLgorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBmaW5hbCBpbnQgdmFsaWRPcHMoKSB7CisgICAgICAgICAgICByZXR1cm4gU2VsZWN0aW9uS2V5Lk9QX1dSSVRFOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZGFibGUgc291cmNlIGNoYW5uZWwgdXNlZCB0byByZWFkIGZyb20gYSBwaXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgU291cmNlQ2hhbm5lbCBleHRlbmRzCisgICAgICAgICAgICBBYnN0cmFjdFNlbGVjdGFibGVDaGFubmVsIGltcGxlbWVudHMgUmVhZGFibGVCeXRlQ2hhbm5lbCwgU2NhdHRlcmluZ0J5dGVDaGFubmVsIHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFNvdXJjZUNoYW5uZWx9LgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgcHJvdmlkZXIgb2YgdGhlIGNoYW5uZWwuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgU291cmNlQ2hhbm5lbChTZWxlY3RvclByb3ZpZGVyIHByb3ZpZGVyKSB7CisgICAgICAgICAgICBzdXBlcihwcm92aWRlcik7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogSW5kaWNhdGVzIHRoYXQgdGhpcyBjaGFubmVsIG9ubHkgc3VwcG9ydHMgcmVhZGluZy4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiBhIHN0YXRpYyB2YWx1ZSBvZiBPUF9SRUFELgorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBmaW5hbCBpbnQgdmFsaWRPcHMoKSB7CisgICAgICAgICAgICByZXR1cm4gU2VsZWN0aW9uS2V5Lk9QX1JFQUQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHBpcGUgZnJvbSB0aGUgZGVmYXVsdCB7QHNlZSBqYXZhLm5pby5jaGFubmVscy5zcGkuU2VsZWN0b3JQcm92aWRlcn0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFBpcGUgb3BlbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBTZWxlY3RvclByb3ZpZGVyLnByb3ZpZGVyKCkub3BlblBpcGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgcHJvdGVjdGVkIGRlZmF1bHQgY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHJvdGVjdGVkIFBpcGUoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2luayBjaGFubmVsIG9mIHRoZSBwaXBlLgorICAgICAqCisgICAgICogQHJldHVybiBhIHdyaXRhYmxlIHNpbmsgY2hhbm5lbCBvZiB0aGUgcGlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2lua0NoYW5uZWwgc2luaygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc291cmNlIGNoYW5uZWwgb2YgdGhlIHBpcGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcmVhZGFibGUgc291cmNlIGNoYW5uZWwgb2YgdGhlIHBpcGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFNvdXJjZUNoYW5uZWwgc291cmNlKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvUmVhZGFibGVCeXRlQ2hhbm5lbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL1JlYWRhYmxlQnl0ZUNoYW5uZWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMTNhZGI0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL1JlYWRhYmxlQnl0ZUNoYW5uZWwuamF2YQpAQCAtMCwwICsxLDY2IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYW5uZWxzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworCisvKioKKyAqIEEge0Bjb2RlIFJlYWRhYmxlQnl0ZUNoYW5uZWx9IGlzIGEgdHlwZSBvZiB7QGxpbmsgQ2hhbm5lbH0gdGhhdCBjYW4gcmVhZAorICogYnl0ZXMuCisgKiA8cD4KKyAqIFJlYWQgb3BlcmF0aW9ucyBhcmUgc3luY2hyb25vdXMgb24gYSB7QGNvZGUgUmVhZGFibGVCeXRlQ2hhbm5lbH0sIHRoYXQgaXMsCisgKiBpZiBhIHJlYWQgaXMgYWxyZWFkeSBpbiBwcm9ncmVzcyBvbiB0aGUgY2hhbm5lbCB0aGVuIHN1YnNlcXVlbnQgcmVhZHMgd2lsbAorICogYmxvY2sgdW50aWwgdGhlIGZpcnN0IHJlYWQgY29tcGxldGVzLiBJdCBpcyB1bmRlZmluZWQgd2hldGhlciBub24tcmVhZAorICogb3BlcmF0aW9ucyB3aWxsIGJsb2NrLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFJlYWRhYmxlQnl0ZUNoYW5uZWwgZXh0ZW5kcyBDaGFubmVsIHsKKworICAgIC8qKgorICAgICAqIFJlYWRzIGJ5dGVzIGZyb20gdGhlIGNoYW5uZWwgaW50byB0aGUgZ2l2ZW4gYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0aGF0IHdpbGwgYmUgcmVhZCBpcyB0aGUKKyAgICAgKiB7QGxpbmsgamF2YS5uaW8uQnVmZmVyI3JlbWFpbmluZygpIHJlbWFpbmluZ30gbnVtYmVyIG9mIGJ5dGVzIGluIHRoZQorICAgICAqIGJ1ZmZlciB3aGVuIHRoZSBtZXRob2QgaXMgaW52b2tlZC4gVGhlIGJ5dGVzIHdpbGwgYmUgcmVhZCBpbnRvIHRoZSBidWZmZXIKKyAgICAgKiBzdGFydGluZyBhdCB0aGUgYnVmZmVyJ3MgY3VycmVudAorICAgICAqIHtAbGluayBqYXZhLm5pby5CdWZmZXIjcG9zaXRpb24oKSBwb3NpdGlvbn0uCisgICAgICogPHA+CisgICAgICogVGhlIGNhbGwgbWF5IGJsb2NrIGlmIG90aGVyIHRocmVhZHMgYXJlIGFsc28gYXR0ZW1wdGluZyB0byByZWFkIGZyb20gdGhlCisgICAgICogc2FtZSBjaGFubmVsLgorICAgICAqIDxwPgorICAgICAqIFVwb24gY29tcGxldGlvbiwgdGhlIGJ1ZmZlcidzIHtAY29kZSBwb3NpdGlvbn0gaXMgdXBkYXRlZCB0byB0aGUgZW5kIG9mCisgICAgICogdGhlIGJ5dGVzIHRoYXQgd2VyZSByZWFkLiBUaGUgYnVmZmVyJ3MKKyAgICAgKiB7QGxpbmsgamF2YS5uaW8uQnVmZmVyI2xpbWl0KCkgbGltaXR9IGlzIG5vdCBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYnVmZmVyIHRvIHJlY2VpdmUgdGhlIGJ5dGVzLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSByZWFkLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIHRocmVhZCBjbG9zZXMgdGhlIGNoYW5uZWwgZHVyaW5nIHRoZSByZWFkLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIHRocmVhZCBpbnRlcnJ1cHRzIHRoZSBjYWxsaW5nIHRocmVhZCB3aGlsZSB0aGUKKyAgICAgKiAgICAgICAgICAgICBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MuIFRoZSBpbnRlcnJ1cHQgc3RhdGUgb2YgdGhlIGNhbGxpbmcKKyAgICAgKiAgICAgICAgICAgICB0aHJlYWQgaXMgc2V0IGFuZCB0aGUgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMsIGRldGFpbHMgYXJlIGluIHRoZSBtZXNzYWdlLgorICAgICAqIEB0aHJvd3MgTm9uUmVhZGFibGVDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgd2FzIG5vdCBvcGVuZWQgZm9yIHJlYWRpbmcuCisgICAgICovCisgICAgcHVibGljIGludCByZWFkKEJ5dGVCdWZmZXIgYnVmZmVyKSB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvU2NhdHRlcmluZ0J5dGVDaGFubmVsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvU2NhdHRlcmluZ0J5dGVDaGFubmVsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWE4NTI5OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9TY2F0dGVyaW5nQnl0ZUNoYW5uZWwuamF2YQpAQCAtMCwwICsxLDkwIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYW5uZWxzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworCisvKioKKyAqIFRoZSBpbnRlcmZhY2UgZm9yIGNoYW5uZWxzIHRoYXQgY2FuIHJlYWQgZGF0YSBpbnRvIGEgc2V0IG9mIGJ1ZmZlcnMgaW4gYQorICogc2luZ2xlIG9wZXJhdGlvbi4gVGhlIGNvcnJlc3BvbmRpbmcgaW50ZXJmYWNlIGZvciB3cml0ZXMgaXMKKyAqIHtAbGluayBHYXRoZXJpbmdCeXRlQ2hhbm5lbH0uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgU2NhdHRlcmluZ0J5dGVDaGFubmVsIGV4dGVuZHMgUmVhZGFibGVCeXRlQ2hhbm5lbCB7CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBieXRlcyBmcm9tIHRoaXMgY2hhbm5lbCBpbnRvIHRoZSBzcGVjaWZpZWQgYXJyYXkgb2YgYnVmZmVycy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAY29kZSByZWFkKGJ1ZmZlcnMsIDAsIGJ1ZmZlcnMubGVuZ3RoKTt9CisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVycworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIGJ5dGUgYnVmZmVycyB0byBzdG9yZSB0aGUgYnl0ZXMgYmVpbmcgcmVhZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgcmVhZC4KKyAgICAgKiBAdGhyb3dzIEFzeW5jaHJvbm91c0Nsb3NlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaXMgY2xvc2VkIGJ5IGFub3RoZXIgdGhyZWFkIGR1cmluZyB0aGlzIHJlYWQKKyAgICAgKiAgICAgICAgICAgICBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgdGhyZWFkIGludGVycnVwdHMgdGhlIGNhbGxpbmcgdGhyZWFkIHdoaWxlIHRoZQorICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcy4gVGhlIGludGVycnVwdCBzdGF0ZSBvZiB0aGUgY2FsbGluZworICAgICAqICAgICAgICAgICAgIHRocmVhZCBpcyBzZXQgYW5kIHRoZSBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIENsb3NlZENoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgSS9PIGVycm9yIG9jY3VyczsgZGV0YWlscyBhcmUgaW4gdGhlIG1lc3NhZ2UuCisgICAgICogQHRocm93cyBOb25Xcml0YWJsZUNoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBoYXMgbm90IGJlZW4gb3BlbmVkIGluIGEgbW9kZSB0aGF0IHBlcm1pdHMKKyAgICAgKiAgICAgICAgICAgICByZWFkaW5nLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIHJlYWQoQnl0ZUJ1ZmZlcltdIGJ1ZmZlcnMpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEF0dGVtcHRzIHRvIHJlYWQgYWxsIHtAY29kZSByZW1haW5pbmcoKX0gYnl0ZXMgZnJvbSB7QGNvZGUgbGVuZ3RofSBieXRlCisgICAgICogYnVmZmVycywgaW4gb3JkZXIsIHN0YXJ0aW5nIGF0IHtAY29kZSBidWZmZXJzW29mZnNldF19LiBUaGUgbnVtYmVyIG9mCisgICAgICogYnl0ZXMgYWN0dWFsbHkgcmVhZCBpcyByZXR1cm5lZC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiBhIHJlYWQgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLCBzdWJzZXF1ZW50IHRocmVhZHMgd2lsbCBibG9jayB1bnRpbAorICAgICAqIHRoZSByZWFkIGlzIGNvbXBsZXRlZCBhbmQgd2lsbCB0aGVuIGNvbnRlbmQgZm9yIHRoZSBhYmlsaXR5IHRvIHJlYWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVycworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIGJ5dGUgYnVmZmVycyBpbnRvIHdoaWNoIHRoZSBieXRlcyB3aWxsIGJlIGNvcGllZC4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGJ1ZmZlciB0byBzdG9yZSBieXRlcyBpbi4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnVmZmVycyB0byBzdG9yZSBieXRlcyBpbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgcmVhZC4KKyAgICAgKiBAdGhyb3dzIEFzeW5jaHJvbm91c0Nsb3NlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaXMgY2xvc2VkIGJ5IGFub3RoZXIgdGhyZWFkIGR1cmluZyB0aGlzIHJlYWQKKyAgICAgKiAgICAgICAgICAgICBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgdGhyZWFkIGludGVycnVwdHMgdGhlIGNhbGxpbmcgdGhyZWFkIHdoaWxlIHRoZQorICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcy4gVGhlIGludGVycnVwdCBzdGF0ZSBvZiB0aGUgY2FsbGluZworICAgICAqICAgICAgICAgICAgIHRocmVhZCBpcyBzZXQgYW5kIHRoZSBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIENsb3NlZENoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBsZW5ndGggPCAwfSwgb3IgaWYKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgb2Zmc2V0ICsgbGVuZ3RofSBpcyBncmVhdGVyIHRoYW4gdGhlIHNpemUgb2YKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgYnVmZmVyc30uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgSS9PIGVycm9yIG9jY3VyczsgZGV0YWlscyBhcmUgaW4gdGhlIG1lc3NhZ2UuCisgICAgICogQHRocm93cyBOb25Xcml0YWJsZUNoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBoYXMgbm90IGJlZW4gb3BlbmVkIGluIGEgbW9kZSB0aGF0IHBlcm1pdHMKKyAgICAgKiAgICAgICAgICAgICByZWFkaW5nLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIHJlYWQoQnl0ZUJ1ZmZlcltdIGJ1ZmZlcnMsIGludCBvZmZzZXQsIGludCBsZW5ndGgpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvU2VsZWN0YWJsZUNoYW5uZWwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9TZWxlY3RhYmxlQ2hhbm5lbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFlZjQ2ZjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvU2VsZWN0YWJsZUNoYW5uZWwuamF2YQpAQCAtMCwwICsxLDE4OSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFubmVsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuc3BpLkFic3RyYWN0SW50ZXJydXB0aWJsZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuc3BpLlNlbGVjdG9yUHJvdmlkZXI7CisKKy8qKgorICogQSBjaGFubmVsIHRoYXQgY2FuIGJlIHVzZWQgd2l0aCBhIHtAbGluayBTZWxlY3Rvcn0uIFRoZSBjaGFubmVsIG11c3QgYmUKKyAqIHJlZ2lzdGVyZWQgd2l0aCBhIHNlbGVjdG9yIGJ5IGNhbGxpbmcgb25lIG9mIHRoZSB7QGNvZGUgcmVnaXN0ZXJ9IG1ldGhvZHMsCisgKiB3aGljaCByZXR1cm4gYSB7QGxpbmsgU2VsZWN0aW9uS2V5fSBvYmplY3QuIEluIG9yZGVyIHRvIGRlcmVnaXN0ZXIgYSBjaGFubmVsCisgKiBmcm9tIGEgc2VsZWN0b3IsIGl0cyBzZWxlY3Rpb24ga2V5IG11c3QgYmUgY2FuY2VsZWQuIFRoaXMgY2FuIGJlIGRvbmUKKyAqIGV4cGxpY2l0bHkgYnkgY2FsbGluZyB0aGUge0BsaW5rIFNlbGVjdGlvbktleSNjYW5jZWwoKX0gbWV0aG9kIGJ1dCBpdCBpcyBhbHNvCisgKiBkb25lIGltcGxpY2l0bHkgd2hlbiB0aGUgY2hhbm5lbCBvciB0aGUgc2VsZWN0b3IgaXMgY2xvc2VkLgorICogPHA+CisgKiBBIGNoYW5uZWwgbWF5IGJlIHJlZ2lzdGVyZWQgd2l0aCBzZXZlcmFsIHNlbGVjdG9ycyBhdCB0aGUgc2FtZSB0aW1lIGJ1dCBvbmx5CisgKiBvbmNlIGZvciBhbnkgZ2l2ZW4gc2VsZWN0b3IuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTZWxlY3RhYmxlQ2hhbm5lbCBleHRlbmRzIEFic3RyYWN0SW50ZXJydXB0aWJsZUNoYW5uZWwKKyAgICAgICAgaW1wbGVtZW50cyBDaGFubmVsIHsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFNlbGVjdGFibGVDaGFubmVsfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU2VsZWN0YWJsZUNoYW5uZWwoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYmxvY2tpbmcgbG9jayB3aGljaCBzeW5jaHJvbml6ZXMgdGhlIHtAY29kZSBjb25maWd1cmVCbG9ja2luZ30KKyAgICAgKiBhbmQge0Bjb2RlIHJlZ2lzdGVyfSBtZXRob2RzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYmxvY2tpbmcgb2JqZWN0IGFzIGxvY2suCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IE9iamVjdCBibG9ja2luZ0xvY2soKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGJsb2NraW5nIG1vZGUgb2YgdGhpcyBjaGFubmVsLiBBIGNhbGwgdG8gdGhpcyBtZXRob2QgYmxvY2tzIGlmCisgICAgICogb3RoZXIgY2FsbHMgdG8gdGhpcyBtZXRob2Qgb3IgdG8gYSB7QGNvZGUgcmVnaXN0ZXJ9IG1ldGhvZCBhcmUgZXhlY3V0aW5nLgorICAgICAqIFRoZSBuZXcgYmxvY2tpbmcgbW9kZSBpcyB2YWxpZCBmb3IgY2FsbHMgdG8gb3RoZXIgbWV0aG9kcyB0aGF0IGFyZQorICAgICAqIGludm9rZWQgYWZ0ZXIgdGhlIGNhbGwgdG8gdGhpcyBtZXRob2QuIElmIG90aGVyIG1ldGhvZHMgYXJlIGFscmVhZHkKKyAgICAgKiBleGVjdXRpbmcgd2hlbiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQsIHRoZXkgc3RpbGwgaGF2ZSB0aGUgb2xkIG1vZGUgYW5kCisgICAgICogdGhlIGNhbGwgdG8gdGhpcyBtZXRob2QgbWlnaHQgYmxvY2sgZGVwZW5kaW5nIG9uIHRoZSBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBibG9jaworICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGZvciBzZXR0aW5nIHRoaXMgY2hhbm5lbCdzIG1vZGUgdG8gYmxvY2tpbmcsCisgICAgICogICAgICAgICAgICB7QGNvZGUgZmFsc2V9IHRvIHNldCBpdCB0byBub24tYmxvY2tpbmcuCisgICAgICogQHJldHVybiB0aGlzIGNoYW5uZWwuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYmxvY2t9IGlzIHtAY29kZSB0cnVlfSBhbmQgdGhpcyBjaGFubmVsIGhhcyBiZWVuCisgICAgICogICAgICAgICAgICAgcmVnaXN0ZXJlZCB3aXRoIGF0IGxlYXN0IG9uZSBzZWxlY3Rvci4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2VsZWN0YWJsZUNoYW5uZWwgY29uZmlndXJlQmxvY2tpbmcoYm9vbGVhbiBibG9jaykKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgY2hhbm5lbCBpcyBpbiBibG9ja2luZyBtb2RlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBjaGFubmVsIGlzIGJsb2NraW5nLCB1bmRlZmluZWQgaWYgdGhpcworICAgICAqICAgICAgICAgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNCbG9ja2luZygpOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBjaGFubmVsIGlzIHJlZ2lzdGVyZWQgd2l0aCBhdCBsZWFzdCBvbmUgc2VsZWN0b3IuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGNoYW5uZWwgaXMgcmVnaXN0ZXJlZCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzUmVnaXN0ZXJlZCgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGlzIGNoYW5uZWwncyBzZWxlY3Rpb24ga2V5IGZvciB0aGUgc3BlY2lmaWVkIHNlbGVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIHNlbAorICAgICAqICAgICAgICAgICAgdGhlIHNlbGVjdG9yIHdpdGggd2hpY2ggdGhpcyBjaGFubmVsIGhhcyBiZWVuIHJlZ2lzdGVyZWQuCisgICAgICogQHJldHVybiB0aGUgc2VsZWN0aW9uIGtleSBmb3IgdGhlIGNoYW5uZWwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoaXMgY2hhbm5lbAorICAgICAqICAgICAgICAgaGFzIG5vdCBiZWVuIHJlZ2lzdGVyZWQgd2l0aCB7QGNvZGUgc2VsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2VsZWN0aW9uS2V5IGtleUZvcihTZWxlY3RvciBzZWwpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcHJvdmlkZXIgb2YgdGhpcyBjaGFubmVsLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJvdmlkZXIgb2YgdGhpcyBjaGFubmVsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTZWxlY3RvclByb3ZpZGVyIHByb3ZpZGVyKCk7CisKKyAgICAvKioKKyAgICAgKiBSZWdpc3RlcnMgdGhpcyBjaGFubmVsIHdpdGggdGhlIHNwZWNpZmllZCBzZWxlY3RvciBmb3IgdGhlIHNwZWNpZmllZAorICAgICAqIGludGVyZXN0IHNldC4gSWYgdGhlIGNoYW5uZWwgaXMgYWxyZWFkeSByZWdpc3RlcmVkIHdpdGggdGhlIHNlbGVjdG9yLCB0aGUKKyAgICAgKiBjb3JyZXNwb25kaW5nIHNlbGVjdGlvbiBrZXkgaXMgcmV0dXJuZWQgYnV0IHRoZQorICAgICAqIHtAbGluayBTZWxlY3Rpb25LZXkgaW50ZXJlc3Qgc2V0fSBpcyB1cGRhdGVkIHRvIHtAY29kZSBvcGVyYXRpb25zfS4gVGhlCisgICAgICogcmV0dXJuZWQga2V5IGlzIGNhbmNlbGVkIGlmIHRoZSBjaGFubmVsIGlzIGNsb3NlZCB3aGlsZSByZWdpc3RlcmluZyBpcyBpbgorICAgICAqIHByb2dyZXNzLgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaXMgdmFsaWQgYXQgYW55IHRpbWUuIElmIGFub3RoZXIgdGhyZWFkIGV4ZWN1dGVzIHRoaXMKKyAgICAgKiBtZXRob2Qgb3IgdGhlIHtAY29kZSBjb25maWd1cmVCbG9ja2luZyhib29sZWFufSBtZXRob2QgdGhlbiB0aGlzIGNhbGwgaXMKKyAgICAgKiBibG9ja2VkIHVudGlsIHRoZSBvdGhlciBjYWxsIGZpbmlzaGVzLiBBZnRlciB0aGF0LCBpdCB3aWxsIHN5bmNocm9uaXplIG9uCisgICAgICogdGhlIGtleSBzZXQgb2YgdGhlIHNlbGVjdG9yIGFuZCB0aHVzIG1heSBhZ2FpbiBibG9jayBpZiBvdGhlciB0aHJlYWRzCisgICAgICogYWxzbyBob2xkIGxvY2tzIG9uIHRoZSBrZXkgc2V0IG9mIHRoZSBzYW1lIHNlbGVjdG9yLgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byBjYWxsaW5nCisgICAgICoge0Bjb2RlIHJlZ2lzdGVyKHNlbGVjdG9yLCBvcGVyYXRpb25zLCBudWxsKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2VsZWN0b3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWxlY3RvciB3aXRoIHdoaWNoIHRvIHJlZ2lzdGVyIHRoaXMgY2hhbm5lbC4KKyAgICAgKiBAcGFyYW0gb3BlcmF0aW9ucworICAgICAqICAgICAgICAgICAgdGhpcyBjaGFubmVsJ3Mge0BsaW5rIFNlbGVjdGlvbktleSBpbnRlcmVzdCBzZXR9LgorICAgICAqIEByZXR1cm4gdGhlIHNlbGVjdGlvbiBrZXkgZm9yIHRoaXMgcmVnaXN0cmF0aW9uLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhbm5lbCBpcyBpbiBibG9ja2luZyBtb2RlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFNlbGVjdG9yRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGRvZXMgbm90IGhhdmUgdGhlIHNhbWUgcHJvdmlkZXIgYXMgdGhlIGdpdmVuCisgICAgICogICAgICAgICAgICAgc2VsZWN0b3IuCisgICAgICogQHRocm93cyBDYW5jZWxsZWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgcmVnaXN0ZXJlZCBidXQgaXRzIGtleSBoYXMgYmVlbiBjYW5jZWxlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBvcGVyYXRpb24gZ2l2ZW4gaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIGNoYW5uZWwuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFNlbGVjdGlvbktleSByZWdpc3RlcihTZWxlY3RvciBzZWxlY3RvciwgaW50IG9wZXJhdGlvbnMpCisgICAgICAgICAgICB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByZWdpc3RlcihzZWxlY3Rvciwgb3BlcmF0aW9ucywgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVnaXN0ZXJzIHRoaXMgY2hhbm5lbCB3aXRoIHRoZSBzcGVjaWZpZWQgc2VsZWN0b3IgZm9yIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBpbnRlcmVzdCBzZXQgYW5kIGFuIG9iamVjdCB0byBhdHRhY2guIElmIHRoZSBjaGFubmVsIGlzIGFscmVhZHkKKyAgICAgKiByZWdpc3RlcmVkIHdpdGggdGhlIHNlbGVjdG9yLCB0aGUgY29ycmVzcG9uZGluZyBzZWxlY3Rpb24ga2V5IGlzIHJldHVybmVkCisgICAgICogYnV0IGl0cyB7QGxpbmsgU2VsZWN0aW9uS2V5IGludGVyZXN0IHNldH0gaXMgdXBkYXRlZCB0byB7QGNvZGUgb3BzfSBhbmQKKyAgICAgKiB0aGUgYXR0YWNoZWQgb2JqZWN0IGlzIHVwZGF0ZWQgdG8ge0Bjb2RlIGF0dH0uIFRoZSByZXR1cm5lZCBrZXkgaXMKKyAgICAgKiBjYW5jZWxlZCBpZiB0aGUgY2hhbm5lbCBpcyBjbG9zZWQgd2hpbGUgcmVnaXN0ZXJpbmcgaXMgaW4gcHJvZ3Jlc3MuCisgICAgICogPHA+CisgICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCBpcyB2YWxpZCBhdCBhbnkgdGltZS4gSWYgYW5vdGhlciB0aHJlYWQgZXhlY3V0ZXMgdGhpcworICAgICAqIG1ldGhvZCBvciB0aGUge0Bjb2RlIGNvbmZpZ3VyZUJsb2NraW5nKGJvb2xlYW4pfSBtZXRob2QgdGhlbiB0aGlzIGNhbGwgaXMKKyAgICAgKiBibG9ja2VkIHVudGlsIHRoZSBvdGhlciBjYWxsIGZpbmlzaGVzLiBBZnRlciB0aGF0LCBpdCB3aWxsIHN5bmNocm9uaXplIG9uCisgICAgICogdGhlIGtleSBzZXQgb2YgdGhlIHNlbGVjdG9yIGFuZCB0aHVzIG1heSBhZ2FpbiBibG9jayBpZiBvdGhlciB0aHJlYWRzCisgICAgICogYWxzbyBob2xkIGxvY2tzIG9uIHRoZSBrZXkgc2V0IG9mIHRoZSBzYW1lIHNlbGVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIHNlbAorICAgICAqICAgICAgICAgICAgdGhlIHNlbGVjdG9yIHdpdGggd2hpY2ggdG8gcmVnaXN0ZXIgdGhpcyBjaGFubmVsLgorICAgICAqIEBwYXJhbSBvcHMKKyAgICAgKiAgICAgICAgICAgIHRoaXMgY2hhbm5lbCdzIHtAbGluayBTZWxlY3Rpb25LZXkgaW50ZXJlc3Qgc2V0fS4KKyAgICAgKiBAcGFyYW0gYXR0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGF0dGFjaCwgY2FuIGJlIHtAY29kZSBudWxsfS4KKyAgICAgKiBAcmV0dXJuIHRoZSBzZWxlY3Rpb24ga2V5IGZvciB0aGlzIHJlZ2lzdHJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIENsb3NlZENoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9wc30gaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIGNoYW5uZWwuCisgICAgICogQHRocm93cyBJbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIGluIGJsb2NraW5nIG1vZGUuCisgICAgICogQHRocm93cyBJbGxlZ2FsU2VsZWN0b3JFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgZG9lcyBub3QgaGF2ZSB0aGUgc2FtZSBwcm92aWRlciBhcyB0aGUgZ2l2ZW4KKyAgICAgKiAgICAgICAgICAgICBzZWxlY3Rvci4KKyAgICAgKiBAdGhyb3dzIENhbmNlbGxlZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyByZWdpc3RlcmVkIGJ1dCBpdHMga2V5IGhhcyBiZWVuIGNhbmNlbGVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTZWxlY3Rpb25LZXkgcmVnaXN0ZXIoU2VsZWN0b3Igc2VsLCBpbnQgb3BzLCBPYmplY3QgYXR0KQorICAgICAgICAgICAgdGhyb3dzIENsb3NlZENoYW5uZWxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzZXQgb2YgdmFsaWQge0BsaW5rIFNlbGVjdGlvbktleSBvcGVyYXRpb25zfSBvZiB0aGlzIGNoYW5uZWwuCisgICAgICogSW5zdGFuY2VzIG9mIGEgY29uY3JldGUgY2hhbm5lbCBjbGFzcyBhbHdheXMgcmV0dXJuIHRoZSBzYW1lIHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc2V0IG9mIG9wZXJhdGlvbnMgdGhhdCB0aGlzIGNoYW5uZWwgc3VwcG9ydHMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCB2YWxpZE9wcygpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL1NlbGVjdGlvbktleS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL1NlbGVjdGlvbktleS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZkMzkyNmQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvU2VsZWN0aW9uS2V5LmphdmEKQEAgLTAsMCArMSwyMTggQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhbm5lbHM7CisKKy8qKgorICogQSB7QGNvZGUgU2VsZWN0aW9uS2V5fSByZXByZXNlbnRzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBhIGNoYW5uZWwgYW5kIGEKKyAqIHNlbGVjdG9yIGZvciB3aGljaCB0aGUgY2hhbm5lbCBpcyByZWdpc3RlcmVkLgorICogPGgzPk9wZXJhdGlvbiBzZXQ8L2gzPgorICogQW4gb3BlcmF0aW9uIHNldCBpcyByZXByZXNlbnRlZCBieSBhbiBpbnRlZ2VyIHZhbHVlLiBUaGUgYml0cyBvZiBhbiBvcGVyYXRpb24KKyAqIHNldCByZXByZXNlbnQgY2F0ZWdvcmllcyBvZiBvcGVyYXRpb25zIGZvciBhIGtleSdzIGNoYW5uZWw6IEFjY2VwdGluZyBzb2NrZXQKKyAqIGNvbm5lY3Rpb25zICh7QGNvZGUgT1BfQUNDRVBUfSksIGNvbm5lY3Rpbmcgd2l0aCBhIHNvY2tldCAoe0Bjb2RlIE9QX0NPTk5FQ1R9KSwKKyAqIHJlYWRpbmcgKHtAY29kZSBPUF9SRUFEfSkgYW5kIHdyaXRpbmcgKHtAY29kZSBPUF9XUklURX0pLgorICogPGg0PkludGVyZXN0IHNldDwvaDQ+CisgKiBUaGUgaW50ZXJlc3Qgc2V0IGlzIGFuIG9wZXJhdGlvbiBzZXQgdGhhdCBkZWZpbmVzIHRoZSBvcGVyYXRpb25zIHRoYXQgYQorICoge0BsaW5rIFNlbGVjdGFibGVDaGFubmVsIGNoYW5uZWx9IGlzIGludGVyZXN0ZWQgaW4gcGVyZm9ybWluZy4KKyAqIDxoND5SZWFkeSBzZXQ8L2g0PgorICogVGhlIHJlYWR5IHNldCBpcyBhbiBvcGVyYXRpb24gc2V0IHRoYXQgc2hvd3MgdGhlIG9wZXJhdGlvbnMgdGhhdCBhCisgKiB7QGNvZGUgY2hhbm5lbH0gaXMgcmVhZHkgdG8gZXhlY3V0ZS4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFNlbGVjdGlvbktleSB7CisKKyAgICAvKioKKyAgICAgKiBJbnRlcmVzdCBzZXQgbWFzayBiaXQgZm9yIHNvY2tldC1hY2NlcHQgb3BlcmF0aW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9BQ0NFUFQgPSAxNjsKKworICAgIC8qKgorICAgICAqIEludGVyZXN0IHNldCBtYXNrIGJpdCBmb3Igc29ja2V0LWNvbm5lY3Qgb3BlcmF0aW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9DT05ORUNUID0gODsKKworICAgIC8qKgorICAgICAqIEludGVyZXN0aW5nIG9wZXJhdGlvbiBtYXNrIGJpdCBmb3IgcmVhZCBvcGVyYXRpb25zLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX1JFQUQgPSAxOworCisgICAgLyoqCisgICAgICogSW50ZXJlc3Qgc2V0IG1hc2sgYml0IGZvciB3cml0ZSBvcGVyYXRpb25zLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX1dSSVRFID0gNDsKKworICAgIHByaXZhdGUgdm9sYXRpbGUgT2JqZWN0IGF0dGFjaG1lbnQgPSBudWxsOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgU2VsZWN0aW9uS2V5fS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU2VsZWN0aW9uS2V5KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0dGFjaGVzIGFuIG9iamVjdCB0byB0aGlzIGtleS4gSXQgaXMgYWNjZXB0YWJsZSB0byBhdHRhY2gge0Bjb2RlIG51bGx9LAorICAgICAqIHRoaXMgZGlzY2FyZHMgdGhlIG9sZCBhdHRhY2htZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGFuT2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGF0dGFjaCwgb3Ige0Bjb2RlIG51bGx9IHRvIGRpc2NhcmQgdGhlIGN1cnJlbnQKKyAgICAgKiAgICAgICAgICAgIGF0dGFjaG1lbnQuCisgICAgICogQHJldHVybiB0aGUgbGFzdCBhdHRhY2hlZCBvYmplY3Qgb3Ige0Bjb2RlIG51bGx9IGlmIG5vIG9iamVjdCBoYXMgYmVlbgorICAgICAqICAgICAgICAgYXR0YWNoZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIE9iamVjdCBhdHRhY2goT2JqZWN0IGFuT2JqZWN0KSB7CisgICAgICAgIE9iamVjdCBvbGRBdHRhY2htZW50ID0gYXR0YWNobWVudDsKKyAgICAgICAgYXR0YWNobWVudCA9IGFuT2JqZWN0OworICAgICAgICByZXR1cm4gb2xkQXR0YWNobWVudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhdHRhY2hlZCBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBhdHRhY2hlZCBvYmplY3Qgb3Ige0Bjb2RlIG51bGx9IGlmIG5vIG9iamVjdCBoYXMgYmVlbgorICAgICAqICAgICAgICAgYXR0YWNoZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIE9iamVjdCBhdHRhY2htZW50KCkgeworICAgICAgICByZXR1cm4gYXR0YWNobWVudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYW5jZWxzIHRoaXMga2V5LgorICAgICAqIDxwPgorICAgICAqIEEga2V5IHRoYXQgaGFzIGJlZW4gY2FuY2VsZWQgaXMgbm8gbG9uZ2VyIHZhbGlkLiBDYWxsaW5nIHRoaXMgbWV0aG9kIG9uCisgICAgICogYW4gYWxyZWFkeSBjYW5jZWxlZCBrZXkgZG9lcyBub3RoaW5nLgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaXMgc2FmZSBhdCBhbnkgdGltZS4gVGhlIGNhbGwgbWlnaHQgYmxvY2sgdW50aWwKKyAgICAgKiBhbm90aGVyIG9uZ29pbmcgY2FsbCB0byBhIG1ldGhvZCBvZiB0aGlzIHNlbGVjdG9yIGhhcyBmaW5pc2hlZC4gVGhlCisgICAgICogcmVhc29uIGlzIHRoYXQgaXQgaXMgc3luY2hyb25pemluZyBvbiB0aGUga2V5IHNldCBvZiB0aGUgc2VsZWN0b3IuIEFmdGVyCisgICAgICogdGhpcyBjYWxsIGZpbmlzaGVzLCB0aGUga2V5IHdpbGwgaGF2ZSBiZWVuIGFkZGVkIHRvIHRoZSBzZWxlY3RvcnMKKyAgICAgKiBjYW5jZWxlZC1rZXlzIHNldCBhbmQgd2lsbCBub3QgYmUgaW5jbHVkZWQgaW4gYW55IGZ1dHVyZSBzZWxlY3RzIG9mIHRoaXMKKyAgICAgKiBzZWxlY3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBjYW5jZWwoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNoYW5uZWwgb2YgdGhpcyBrZXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFubmVsIG9mIHRoaXMga2V5LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTZWxlY3RhYmxlQ2hhbm5lbCBjaGFubmVsKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoaXMga2V5J3Mge0BsaW5rIFNlbGVjdGlvbktleSBpbnRlcmVzdCBzZXR9LiBUaGUgcmV0dXJuZWQgc2V0IGhhcworICAgICAqIG9ubHkgdGhvc2UgYml0cyBzZXQgdGhhdCBhcmUgdmFsaWQgZm9yIHRoaXMga2V5J3MgY2hhbm5lbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGludGVyZXN0IHNldCBvZiB0aGlzIGtleS4KKyAgICAgKiBAdGhyb3dzIENhbmNlbGxlZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBrZXkgaGFzIGFscmVhZHkgYmVlbiBjYW5jZWxlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGludGVyZXN0T3BzKCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB7QGxpbmsgU2VsZWN0aW9uS2V5IGludGVyZXN0IHNldH0gZm9yIHRoaXMga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIG9wZXJhdGlvbnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgaW50ZXJlc3Qgc2V0LgorICAgICAqIEByZXR1cm4gdGhpcyBrZXkuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGJpdCBpbiB7QGNvZGUgb3BlcmF0aW9uc30gaXMgbm90IGluIHRoZSBzZXQgb2YKKyAgICAgKiAgICAgICAgICAgICB7QGxpbmsgU2VsZWN0YWJsZUNoYW5uZWwjdmFsaWRPcHMoKSB2YWxpZCBvcGVyYXRpb25zfSBvZiB0aGlzCisgICAgICogICAgICAgICAgICAga2V5J3MgY2hhbm5lbC4KKyAgICAgKiBAdGhyb3dzIENhbmNlbGxlZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBrZXkgaGFzIGFscmVhZHkgYmVlbiBjYW5jZWxlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2VsZWN0aW9uS2V5IGludGVyZXN0T3BzKGludCBvcGVyYXRpb25zKTsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMga2V5J3MgY2hhbm5lbCBpcyBpbnRlcmVzdGVkIGluIHRoZSBhY2NlcHQKKyAgICAgKiBvcGVyYXRpb24gYW5kIGlzIHJlYWR5IHRvIGFjY2VwdCBuZXcgY29ubmVjdGlvbnMuIEEgY2FsbCB0byB0aGlzIG1ldGhvZAorICAgICAqIGlzIGVxdWFsIHRvIGV4ZWN1dGluZyB7QGNvZGUgKHJlYWR5T3BzKCkgJiBPUF9BQ0NFUFQpID09IE9QX0FDQ0VQVH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgY2hhbm5lbCBpcyBpbnRlcmVzdGVkIGluIHRoZSBhY2NlcHQgb3BlcmF0aW9uCisgICAgICogICAgICAgICBhbmQgaXMgcmVhZHkgdG8gYWNjZXB0IG5ldyBjb25uZWN0aW9ucywge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBDYW5jZWxsZWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUga2V5IGhhcyBhbHJlYWR5IGJlZW4gY2FuY2VsZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNBY2NlcHRhYmxlKCkgeworICAgICAgICByZXR1cm4gKHJlYWR5T3BzKCkgJiBPUF9BQ0NFUFQpID09IE9QX0FDQ0VQVDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIGtleSdzIGNoYW5uZWwgaXMgaW50ZXJlc3RlZCBpbiB0aGUgY29ubmVjdAorICAgICAqIG9wZXJhdGlvbiBhbmQgaXMgcmVhZHkgdG8gY29ubmVjdC4gQSBjYWxsIHRvIHRoaXMgbWV0aG9kIGlzIGVxdWFsIHRvCisgICAgICogZXhlY3V0aW5nIHtAY29kZSAocmVhZHlPcHMoKSAmIE9QX0NPTk5FQ1QpID09IE9QX0NPTk5FQ1R9LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGNoYW5uZWwgaXMgaW50ZXJlc3RlZCBpbiB0aGUgY29ubmVjdAorICAgICAqICAgICAgICAgb3BlcmF0aW9uIGFuZCBpcyByZWFkeSB0byBjb25uZWN0LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIENhbmNlbGxlZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBrZXkgaGFzIGFscmVhZHkgYmVlbiBjYW5jZWxlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0Nvbm5lY3RhYmxlKCkgeworICAgICAgICByZXR1cm4gKHJlYWR5T3BzKCkgJiBPUF9DT05ORUNUKSA9PSBPUF9DT05ORUNUOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMga2V5J3MgY2hhbm5lbCBpcyBpbnRlcmVzdGVkIGluIHRoZSByZWFkIG9wZXJhdGlvbgorICAgICAqIGFuZCBpcyByZWFkeSB0byByZWFkLiBBIGNhbGwgdG8gdGhpcyBtZXRob2QgaXMgZXF1YWwgdG8gZXhlY3V0aW5nCisgICAgICoge0Bjb2RlIChyZWFkeU9wcygpICYgT1BfUkVBRCkgPT0gT1BfUkVBRH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgY2hhbm5lbCBpcyBpbnRlcmVzdGVkIGluIHRoZSByZWFkIG9wZXJhdGlvbgorICAgICAqICAgICAgICAgYW5kIGlzIHJlYWR5IHRvIHJlYWQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgQ2FuY2VsbGVkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGtleSBoYXMgYWxyZWFkeSBiZWVuIGNhbmNlbGVkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzUmVhZGFibGUoKSB7CisgICAgICAgIHJldHVybiAocmVhZHlPcHMoKSAmIE9QX1JFQUQpID09IE9QX1JFQUQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBrZXkgaXMgdmFsaWQuIEEga2V5IGlzIHZhbGlkIGFzIGxvbmcgYXMgaXQgaGFzIG5vdAorICAgICAqIGJlZW4gY2FuY2VsZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGtleSBoYXMgbm90IGJlZW4gY2FuY2VsZWQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc1ZhbGlkKCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIGtleSdzIGNoYW5uZWwgaXMgaW50ZXJlc3RlZCBpbiB0aGUgd3JpdGUgb3BlcmF0aW9uCisgICAgICogYW5kIGlzIHJlYWR5IHRvIHdyaXRlLiBBIGNhbGwgdG8gdGhpcyBtZXRob2QgaXMgZXF1YWwgdG8gZXhlY3V0aW5nCisgICAgICoge0Bjb2RlIChyZWFkeU9wcygpICYgT1BfV1JJVEUpID09IE9QX1dSSVRFfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBjaGFubmVsIGlzIGludGVyZXN0ZWQgaW4gdGhlIHdyaXRlIG9wZXJhdGlvbgorICAgICAqICAgICAgICAgYW5kIGlzIHJlYWR5IHRvIHdyaXRlLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIENhbmNlbGxlZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBrZXkgaGFzIGFscmVhZHkgYmVlbiBjYW5jZWxlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc1dyaXRhYmxlKCkgeworICAgICAgICByZXR1cm4gKHJlYWR5T3BzKCkgJiBPUF9XUklURSkgPT0gT1BfV1JJVEU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2V0IG9mIG9wZXJhdGlvbnMgdGhhdCBhcmUgcmVhZHkuIFRoZSByZXR1cm5lZCBzZXQgaGFzIG9ubHkKKyAgICAgKiB0aG9zZSBiaXRzIHNldCB0aGF0IGFyZSB2YWxpZCBmb3IgdGhpcyBrZXkncyBjaGFubmVsLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgb3BlcmF0aW9ucyBmb3Igd2hpY2ggdGhpcyBrZXkncyBjaGFubmVsIGlzIHJlYWR5LgorICAgICAqIEB0aHJvd3MgQ2FuY2VsbGVkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGtleSBoYXMgYWxyZWFkeSBiZWVuIGNhbmNlbGVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgcmVhZHlPcHMoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNlbGVjdG9yIGZvciB3aGljaCB0aGlzIGtleSdzIGNoYW5uZWwgaXMgcmVnaXN0ZXJlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJlbGF0ZWQgc2VsZWN0b3IuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFNlbGVjdG9yIHNlbGVjdG9yKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvU2VsZWN0b3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9TZWxlY3Rvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFhYWMxNGIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvU2VsZWN0b3IuamF2YQpAQCAtMCwwICsxLDE2NyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFubmVsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuc3BpLlNlbGVjdG9yUHJvdmlkZXI7CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworLyoqCisgKiBBIGNvbnRyb2xsZXIgZm9yIHRoZSBzZWxlY3Rpb24gb2Yge0BsaW5rIFNlbGVjdGFibGVDaGFubmVsfSBvYmplY3RzLgorICogU2VsZWN0YWJsZSBjaGFubmVscyBjYW4gYmUgcmVnaXN0ZXJlZCB3aXRoIGEgc2VsZWN0b3IgYW5kIGdldCBhCisgKiB7QGxpbmsgU2VsZWN0aW9uS2V5fSB0aGF0IHJlcHJlc2VudHMgdGhlIHJlZ2lzdHJhdGlvbi4gVGhlIGtleXMgYXJlIGFsc28KKyAqIGFkZGVkIHRvIHRoZSBzZWxlY3RvcidzIGtleSBzZXQuIFNlbGVjdGlvbiBrZXlzIGNhbiBiZSBjYW5jZWxlZCBzbyB0aGF0IHRoZQorICogY29ycmVzcG9uZGluZyBjaGFubmVsIGlzIG5vIGxvbmdlciByZWdpc3RlcmVkIHdpdGggdGhlIHNlbGVjdG9yLgorICogPHA+CisgKiBCeSBpbnZva2luZyB0aGUge0Bjb2RlIHNlbGVjdH0gbWV0aG9kLCB0aGUga2V5IHNldCBpcyBjaGVja2VkIGFuZCBhbGwga2V5cworICogdGhhdCBoYXZlIGJlZW4gY2FuY2VsZWQgc2luY2UgbGFzdCBzZWxlY3Qgb3BlcmF0aW9uIGFyZSBtb3ZlZCB0byB0aGUgc2V0IG9mCisgKiBjYW5jZWxlZCBrZXlzLiBEdXJpbmcgdGhlIHNlbGVjdCBvcGVyYXRpb24sIHRoZSBjaGFubmVscyByZWdpc3RlcmVkIHdpdGggdGhpcworICogc2VsZWN0b3IgYXJlIGNoZWNrZWQgdG8gc2VlIHdoZXRoZXIgdGhleSBhcmUgcmVhZHkgZm9yIG9wZXJhdGlvbiBhY2NvcmRpbmcgdG8KKyAqIHRoZWlyIHtAbGluayBTZWxlY3Rpb25LZXkgaW50ZXJlc3Qgc2V0fS4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFNlbGVjdG9yIHsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzZWxlY3RvciByZXR1cm5lZCBieSB7QGxpbmsgU2VsZWN0b3JQcm92aWRlciNwcm92aWRlcn0ncworICAgICAqIHtAbGluayBTZWxlY3RvclByb3ZpZGVyI29wZW5TZWxlY3Rvcn0gbWV0aG9kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTZWxlY3RvciBvcGVuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIFNlbGVjdG9yUHJvdmlkZXIucHJvdmlkZXIoKS5vcGVuU2VsZWN0b3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBTZWxlY3Rvcn0uCisgICAgICovCisgICAgcHJvdGVjdGVkIFNlbGVjdG9yKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGlzIHNlbGVjdG9yLiBPbmdvaW5nIGNhbGxzIHRvIHRoZSB7QGNvZGUgc2VsZWN0fSBtZXRob2RzIG9mIHRoaXMKKyAgICAgKiBzZWxlY3RvciB3aWxsIGdldCBpbnRlcnJ1cHRlZC4gVGhpcyBpbnRlcnJ1cHRpb24gYmVoYXZlcyBhcyBpZiB0aGUKKyAgICAgKiB7QGxpbmsgI3dha2V1cCgpfSBtZXRob2Qgb2YgdGhpcyBzZWxlY3RvciBpcyBjYWxsZWQuIEFmdGVyIHRoaXMsIGFsbCBrZXlzCisgICAgICogdGhhdCBhcmUgc3RpbGwgdmFsaWQgYXJlIGludmFsaWRhdGVkIGFuZCB0aGVpciBjaGFubmVscyBhcmUgdW5yZWdpc3RlcmVkLgorICAgICAqIEFsbCByZXNvdXJjZXMgaGVsZCBieSB0aGlzIHNlbGVjdG9yIGFyZSByZWxlYXNlZC4KKyAgICAgKiA8cD4KKyAgICAgKiBBbnkgZnVydGhlciBhdHRlbXB0IG9mIHVzaW5nIHRoaXMgc2VsZWN0b3IgYWZ0ZXIgdGhpcyBtZXRob2QgaGFzIGJlZW4KKyAgICAgKiBjYWxsZWQgKGV4Y2VwdCBjYWxsaW5nIHtAbGluayAjY2xvc2UoKX0gb3Ige0BsaW5rICN3YWtldXAoKX0pIHJlc3VsdHMgaW4KKyAgICAgKiBhIHtAbGluayBDbG9zZWRTZWxlY3RvckV4Y2VwdGlvbn0gYmVpbmcgdGhyb3duLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIHNlbGVjdG9yIGlzIG9wZW4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHNlbGVjdG9yIGlzIG5vdCBjbG9zZWQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc09wZW4oKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNldCBvZiByZWdpc3RlcmVkIGtleXMuIFRoZSBzZXQgaXMgaW1tdXRhYmxlIGFuZCBpcyBub3QgdGhyZWFkLQorICAgICAqIHNhZmUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzZXQgb2YgcmVnaXN0ZXJlZCBrZXlzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTZXQ8U2VsZWN0aW9uS2V5PiBrZXlzKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBwcm92aWRlciBvZiB0aGlzIHNlbGVjdG9yLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJvdmlkZXIgb2YgdGhpcyBzZWxlY3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2VsZWN0b3JQcm92aWRlciBwcm92aWRlcigpOworCisgICAgLyoqCisgICAgICogRGV0ZWN0cyBpZiBhbnkgb2YgdGhlIHJlZ2lzdGVyZWQgY2hhbm5lbHMgaXMgcmVhZHkgZm9yIEkvTyBvcGVyYXRpb25zCisgICAgICogYWNjb3JkaW5nIHRvIGl0cyB7QGxpbmsgU2VsZWN0aW9uS2V5IGludGVyZXN0IHNldH0uIFRoaXMgbWV0aG9kIGRvZXMgbm90CisgICAgICogcmV0dXJuIHVudGlsIGF0IGxlYXN0IG9uZSBjaGFubmVsIGlzIHJlYWR5LCB7QGxpbmsgI3dha2V1cCgpfSBpcworICAgICAqIGludm9rZWQgb3IgdGhlIGNhbGxpbmcgdGhyZWFkIGlzIGludGVycnVwdGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzIHRoYXQgYXJlIHJlYWR5IGZvciBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHRocm93cyBDbG9zZWRTZWxlY3RvckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzZWxlY3RvciBpcyBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBzZWxlY3QoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlY3RzIGlmIGFueSBvZiB0aGUgcmVnaXN0ZXJlZCBjaGFubmVscyBpcyByZWFkeSBmb3IgSS9PIG9wZXJhdGlvbnMKKyAgICAgKiBhY2NvcmRpbmcgdG8gaXRzIHtAbGluayBTZWxlY3Rpb25LZXkgaW50ZXJlc3Qgc2V0fS4gVGhpcyBtZXRob2QgZG9lcyBub3QKKyAgICAgKiByZXR1cm4gdW50aWwgYXQgbGVhc3Qgb25lIGNoYW5uZWwgaXMgcmVhZHksIHtAbGluayAjd2FrZXVwKCl9IGlzIGludm9rZWQsCisgICAgICogdGhlIGNhbGxpbmcgdGhyZWFkIGlzIGludGVycnVwdGVkIG9yIHRoZSBzcGVjaWZpZWQge0Bjb2RlIHRpbWVvdXR9CisgICAgICogZXhwaXJlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aW1lb3V0CisgICAgICogICAgICAgICAgICB0aGUgbm9uLW5lZ2F0aXZlIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmQ7IDAgd2lsbCBibG9jayBmb3JldmVyCisgICAgICogICAgICAgICAgICBpZiBubyBjaGFubmVscyBnZXQgcmVhZHkuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzIHRoYXQgYXJlIHJlYWR5IGZvciBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBDbG9zZWRTZWxlY3RvckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzZWxlY3RvciBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2l2ZW4gdGltZW91dCBhcmd1bWVudCBpcyBsZXNzIHRoYW4gemVyby4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IHNlbGVjdChsb25nIHRpbWVvdXQpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNlbGVjdGlvbiBrZXlzIHdob3NlIGNoYW5uZWxzIGFyZSByZWFkeSBmb3Igb3BlcmF0aW9uLiBUaGUgc2V0CisgICAgICogaXMgbm90IHRocmVhZC1zYWZlIGFuZCBubyBrZXlzIG1heSBiZSBhZGRlZCB0byBpdC4gUmVtb3Zpbmcga2V5cyBpcworICAgICAqIGFsbG93ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzZWxlY3Rpb24ga2V5cyB3aG9zZSBjaGFubmVscyBhcmUgcmVhZHkgZm9yIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIENsb3NlZFNlbGVjdG9yRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNlbGVjdG9yIGlzIGNsb3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2V0PFNlbGVjdGlvbktleT4gc2VsZWN0ZWRLZXlzKCk7CisKKyAgICAvKioKKyAgICAgKiBEZXRlY3RzIGlmIGFueSBvZiB0aGUgcmVnaXN0ZXJlZCBjaGFubmVscyBpcyByZWFkeSBmb3IgSS9PIG9wZXJhdGlvbnMKKyAgICAgKiBhY2NvcmRpbmcgdG8gaXRzIHtAbGluayBTZWxlY3Rpb25LZXkgaW50ZXJlc3Qgc2V0fS4gVGhpcyBvcGVyYXRpb24gd2lsbAorICAgICAqIHJldHVybiBpbW1lZGlhdGVseS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBjaGFubmVscyB0aGF0IGFyZSByZWFkeSBmb3Igb3BlcmF0aW9uLCAwIGlmIG5vbmUgaXMKKyAgICAgKiAgICAgICAgIHJlYWR5LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJycy4KKyAgICAgKiBAdGhyb3dzIENsb3NlZFNlbGVjdG9yRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNlbGVjdG9yIGlzIGNsb3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IHNlbGVjdE5vdygpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEZvcmNlcyBibG9ja2VkIHtAY29kZSBzZWxlY3R9IG9wZXJhdGlvbnMgdG8gcmV0dXJuIGltbWVkaWF0ZWx5LgorICAgICAqIDxwPgorICAgICAqIElmIG5vIHtAY29kZSBzZWxlY3R9IG9wZXJhdGlvbiBpcyBibG9ja2VkIHdoZW4ge0Bjb2RlIHdha2V1cCgpfSBpcyBjYWxsZWQKKyAgICAgKiB0aGVuIHRoZSBuZXh0IHtAY29kZSBzZWxlY3R9IG9wZXJhdGlvbiB3aWxsIHJldHVybiBpbW1lZGlhdGVseS4gVGhpcyBjYW4KKyAgICAgKiBiZSB1bmRvbmUgYnkgYSBjYWxsIHRvIHtAY29kZSBzZWxlY3ROb3coKX07IGFmdGVyIGNhbGxpbmcKKyAgICAgKiB7QGNvZGUgc2VsZWN0Tm93KCl9LCBhIHN1YnNlcXVlbnQgY2FsbCBvZiB7QGNvZGUgc2VsZWN0fSBjYW4gYmxvY2sKKyAgICAgKiBhZ2Fpbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBzZWxlY3Rvci4KKyAgICAgKiBAdGhyb3dzIENsb3NlZFNlbGVjdG9yRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNlbGVjdG9yIGlzIGNsb3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2VsZWN0b3Igd2FrZXVwKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvU2VydmVyU29ja2V0Q2hhbm5lbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL1NlcnZlclNvY2tldENoYW5uZWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mM2MzMzkwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL1NlcnZlclNvY2tldENoYW5uZWwuamF2YQpAQCAtMCwwICsxLDExMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFubmVsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuU2VydmVyU29ja2V0OworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLnNwaS5BYnN0cmFjdFNlbGVjdGFibGVDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLnNwaS5TZWxlY3RvclByb3ZpZGVyOworCisvKioKKyAqIEEge0Bjb2RlIFNlcnZlclNvY2tldENoYW5uZWx9IGlzIGEgcGFydGlhbCBhYnN0cmFjdGlvbiBvZiBhIHNlbGVjdGFibGUsCisgKiBzdHJlYW0tb3JpZW50ZWQgbGlzdGVuaW5nIHNvY2tldC4gQmluZGluZyBhbmQgbWFuaXB1bGF0aW9uIG9mIHNvY2tldCBvcHRpb25zCisgKiBjYW4gb25seSBiZSBkb25lIHRocm91Z2ggdGhlIGFzc29jaWF0ZWQge0BsaW5rIFNlcnZlclNvY2tldH0gb2JqZWN0LCByZXR1cm5lZAorICogYnkgY2FsbGluZyB7QGNvZGUgc29ja2V0KCl9LiBTZXJ2ZXJTb2NrZXRDaGFubmVscyBjYW4gbm90IGJlIGNvbnN0cnVjdGVkIGZvcgorICogYW4gYWxyZWFkeSBleGlzdGluZyBzZXJ2ZXItc29ja2V0LCBub3IgY2FuIGEge0BsaW5rIGphdmEubmV0LlNvY2tldEltcGx9IGJlIGFzc2lnbmVkLgorICogPHA+CisgKiBBIHNlcnZlci1zb2NrZXQgY2hhbm5lbCBpcyBvcGVuIGJ1dCBub3QgYm91bmQgd2hlbiBjcmVhdGVkIGJ5IHRoZSB7QGNvZGUKKyAqIG9wZW4oKX0gbWV0aG9kLiBDYWxsaW5nIHtAY29kZSBhY2NlcHR9IGJlZm9yZSBib3VuZCB3aWxsIGNhdXNlIGEKKyAqIHtAbGluayBOb3RZZXRCb3VuZEV4Y2VwdGlvbn0uIEl0IGNhbiBiZSBib3VuZCBieSBjYWxsaW5nIHRoZSBiaW5kIG1ldGhvZCBvZiBhCisgKiByZWxhdGVkIHtAY29kZSBTZXJ2ZXJTb2NrZXR9IGluc3RhbmNlLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU2VydmVyU29ja2V0Q2hhbm5lbCBleHRlbmRzIEFic3RyYWN0U2VsZWN0YWJsZUNoYW5uZWwgeworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGxpbmsgU2VydmVyU29ja2V0Q2hhbm5lbH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2VsZWN0b3JQcm92aWRlcgorICAgICAqICAgICAgICAgICAgYW4gaW5zdGFuY2Ugb2YgU2VsZWN0b3JQcm92aWRlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU2VydmVyU29ja2V0Q2hhbm5lbChTZWxlY3RvclByb3ZpZGVyIHNlbGVjdG9yUHJvdmlkZXIpIHsKKyAgICAgICAgc3VwZXIoc2VsZWN0b3JQcm92aWRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBvcGVuIGFuZCB1bmJvdW5kIHNlcnZlci1zb2NrZXQgY2hhbm5lbC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIGNoYW5uZWwgaXMgY3JlYXRlZCBieSBjYWxsaW5nIHtAY29kZSBvcGVuU2VydmVyU29ja2V0Q2hhbm5lbH0gbWV0aG9kCisgICAgICogb2YgdGhlIGRlZmF1bHQge0Bjb2RlIFNlbGVjdG9yUHJvdmlkZXJ9IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV3IGNoYW5uZWwgd2hpY2ggaXMgb3BlbiBidXQgdW5ib3VuZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNlcnZlclNvY2tldENoYW5uZWwgb3BlbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBTZWxlY3RvclByb3ZpZGVyLnByb3ZpZGVyKCkub3BlblNlcnZlclNvY2tldENoYW5uZWwoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWxpZCBvcGVyYXRpb25zIG9mIHRoaXMgY2hhbm5lbC4gU2VydmVyLXNvY2tldCBjaGFubmVscyBzdXBwb3J0CisgICAgICogYWNjZXB0aW5nIG9wZXJhdGlvbiwgc28gdGhpcyBtZXRob2QgcmV0dXJucyB7QGNvZGUKKyAgICAgKiBTZWxlY3Rpb25LZXkuT1BfQUNDRVBUfS4KKyAgICAgKgorICAgICAqIEBzZWUgamF2YS5uaW8uY2hhbm5lbHMuU2VsZWN0YWJsZUNoYW5uZWwjdmFsaWRPcHMoKQorICAgICAqIEByZXR1cm4gdGhlIG9wZXJhdGlvbnMgc3VwcG9ydGVkIGJ5IHRoaXMgY2hhbm5lbC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgaW50IHZhbGlkT3BzKCkgeworICAgICAgICByZXR1cm4gU2VsZWN0aW9uS2V5Lk9QX0FDQ0VQVDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHNlcnZlci1zb2NrZXQgYXNzaWduZWQgdGhpcyBjaGFubmVsLCB3aGljaCBkb2VzIG5vdCBkZWNsYXJlCisgICAgICogYW55IHB1YmxpYyBtZXRob2RzIHRoYXQgYXJlIG5vdCBkZWNsYXJlZCBpbiB7QGNvZGUgU2VydmVyU29ja2V0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNlcnZlci1zb2NrZXQgYXNzaWduZWQgdG8gdGhpcyBjaGFubmVsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTZXJ2ZXJTb2NrZXQgc29ja2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBBY2NlcHRzIGEgY29ubmVjdGlvbiB0byB0aGlzIHNlcnZlci1zb2NrZXQgY2hhbm5lbC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIHtAY29kZSBudWxsfSB3aGVuIHRoaXMgY2hhbm5lbCBpcyBub24tYmxvY2tpbmcgYW5kIG5vCisgICAgICogY29ubmVjdGlvbiBpcyBhdmFpbGFibGUsIG90aGVyd2lzZSBpdCBibG9ja3MgdW50aWwgYSBuZXcgY29ubmVjdGlvbiBpcworICAgICAqIGF2YWlsYWJsZSBvciBhbiBJL08gZXJyb3Igb2NjdXJzLiBUaGUgc29ja2V0IGNoYW5uZWwgcmV0dXJuZWQgYnkgdGhpcworICAgICAqIG1ldGhvZCB3aWxsIGFsd2F5cyBiZSBpbiBibG9ja2luZyBtb2RlLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIGp1c3QgZXhlY3V0ZXMgdGhlIHNhbWUgc2VjdXJpdHkgY2hlY2tzIGFzIHRoZSB7QGNvZGUKKyAgICAgKiBhY2NlcHQoKX0gbWV0aG9kIG9mIHRoZSB7QGxpbmsgU2VydmVyU29ja2V0fSBjbGFzcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGFjY2VwdGVkIHtAY29kZSBTb2NrZXRDaGFubmVsfSBpbnN0YW5jZSwgb3Ige0Bjb2RlIG51bGx9IGlmCisgICAgICogICAgICAgICB0aGUgY2hhbm5lbCBpcyBub24tYmxvY2tpbmcgYW5kIG5vIGNvbm5lY3Rpb24gaXMgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgY2xvc2VkIGJ5IGFub3RoZXIgdGhyZWFkIHdoaWxlIHRoaXMgbWV0aG9kCisgICAgICogICAgICAgICAgICAgaXMgaW4gb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIHRocmVhZCBpbnRlcnJ1cHRzIHRoZSBjYWxsaW5nIHRocmVhZCB3aGlsZSB0aGlzCisgICAgICogICAgICAgICAgICAgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLiBUaGUgaW50ZXJydXB0IHN0YXRlIG9mIHRoZSBjYWxsaW5nCisgICAgICogICAgICAgICAgICAgdGhyZWFkIGlzIHNldCBhbmQgdGhlIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAdGhyb3dzIE5vdFlldEJvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNvY2tldCBoYXMgbm90IHlldCBiZWVuIGJvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTb2NrZXRDaGFubmVsIGFjY2VwdCgpIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9Tb2NrZXRDaGFubmVsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvU29ja2V0Q2hhbm5lbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc1M2M4OGYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvU29ja2V0Q2hhbm5lbC5qYXZhCkBAIC0wLDAgKzEsNDI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYW5uZWxzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLnNwaS5BYnN0cmFjdFNlbGVjdGFibGVDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLnNwaS5TZWxlY3RvclByb3ZpZGVyOworCisvKioKKyAqIEEge0Bjb2RlIFNvY2tldENoYW5uZWx9IGlzIGEgc2VsZWN0YWJsZSBjaGFubmVsIHRoYXQgcHJvdmlkZXMgYSBwYXJ0aWFsCisgKiBhYnN0cmFjdGlvbiBvZiBzdHJlYW0gY29ubmVjdGluZyBzb2NrZXQuIHtAY29kZSBzb2NrZXQoKX0gcmV0dXJucyB0aGUgcmVsYXRlZAorICoge0BsaW5rIFNvY2tldH0gaW5zdGFuY2Ugd2hpY2ggY2FuIGhhbmRsZSB0aGUgc29ja2V0LgorICogPHA+CisgKiBBIHNvY2tldCBjaGFubmVsIGlzIG9wZW4gYnV0IG5vdCBjb25uZWN0ZWQgd2hlbiBjcmVhdGVkIGJ5IHtAY29kZSBvcGVuKCl9LgorICogQWZ0ZXIgY29ubmVjdGluZyBpdCBieSBjYWxsaW5nIHtAY29kZSBjb25uZWN0KFNvY2tldEFkZHJlc3MpfSwgaXQgd2lsbCByZW1haW4KKyAqIGNvbm5lY3RlZCB1bnRpbCBpdCBnZXRzIGNsb3NlZC4gSWYgdGhlIGNvbm5lY3Rpb24gaXMgbm9uLWJsb2NraW5nIHRoZW4KKyAqIHtAY29kZSBjb25uZWN0KFNvY2tldEFkZHJlc3MpfSBpcyB1c2VkIHRvIGluaXRpYXRlIHRoZSBjb25uZWN0aW9uLCBmb2xsb3dlZAorICogYnkgYSBjYWxsIG9mIHtAY29kZSBmaW5pc2hDb25uZWN0KCl9IHRvIHBlcmZvcm0gdGhlIGZpbmFsIHN0ZXBzIG9mCisgKiBjb25uZWN0aW5nLiB7QGNvZGUgaXNDb25uZWN0aW9uUGVuZGluZygpfSBpbmRpY2F0ZXMgaWYgdGhlIGNvbm5lY3Rpb24gaXMKKyAqIGJsb2NrZWQgb3Igbm90OyB7QGNvZGUgaXNDb25uZWN0ZWQoKX0gaW5kaWNhdGVzIGlmIHRoZSBzb2NrZXQgaXMgZmluYWxseQorICogY29ubmVjdGVkIG9yIG5vdC4KKyAqIDxwPgorICogVGhlIGlucHV0IGFuZCBvdXRwdXQgc2lkZXMgb2YgYSBjaGFubmVsIGNhbiBiZSBzaHV0IGRvd24gaW5kZXBlbmRlbnRseSBhbmQKKyAqIGFzeW5jaHJvbm91c2x5IHdpdGhvdXQgY2xvc2luZyB0aGUgY2hhbm5lbC4gVGhlIHtAY29kZSBzaHV0ZG93bklucHV0fSBtZXRob2QKKyAqIGlzIHVzZWQgZm9yIHRoZSBpbnB1dCBzaWRlIG9mIGEgY2hhbm5lbCBhbmQgc3Vic2VxdWVudCByZWFkIG9wZXJhdGlvbnMgcmV0dXJuCisgKiAtMSwgd2hpY2ggbWVhbnMgZW5kIG9mIHN0cmVhbS4gSWYgYW5vdGhlciB0aHJlYWQgaXMgYmxvY2tlZCBpbiBhIHJlYWQKKyAqIG9wZXJhdGlvbiB3aGVuIHRoZSBzaHV0ZG93biBvY2N1cnMsIHRoZSByZWFkIHdpbGwgZW5kIHdpdGhvdXQgZWZmZWN0IGFuZAorICogcmV0dXJuIGVuZCBvZiBzdHJlYW0uIFRoZSB7QGNvZGUgc2h1dGRvd25PdXRwdXR9IG1ldGhvZCBpcyB1c2VkIGZvciB0aGUKKyAqIG91dHB1dCBzaWRlIG9mIHRoZSBjaGFubmVsOyBzdWJzZXF1ZW50IHdyaXRlIG9wZXJhdGlvbnMgdGhyb3cgYQorICoge0BsaW5rIENsb3NlZENoYW5uZWxFeGNlcHRpb259LiBJZiB0aGUgb3V0cHV0IGlzIHNodXQgZG93biBhbmQgYW5vdGhlciB0aHJlYWQKKyAqIGlzIGJsb2NrZWQgaW4gYSB3cml0ZSBvcGVyYXRpb24sIGFuIHtAbGluayBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbn0gd2lsbAorICogYmUgdGhyb3duIHRvIHRoZSBwZW5kaW5nIHRocmVhZC4KKyAqIDxwPgorICogU29ja2V0IGNoYW5uZWxzIGFyZSB0aHJlYWQtc2FmZSwgbm8gbW9yZSB0aGFuIG9uZSB0aHJlYWQgY2FuIHJlYWQgb3Igd3JpdGUgYXQKKyAqIGFueSBnaXZlbiB0aW1lLiBUaGUge0Bjb2RlIGNvbm5lY3QoU29ja2V0QWRkcmVzcyl9IGFuZCB7QGNvZGUKKyAqIGZpbmlzaENvbm5lY3QoKX0gbWV0aG9kcyBhcmUgc3luY2hyb25pemVkIGFnYWluc3QgZWFjaCBvdGhlcjsgd2hlbiB0aGV5IGFyZQorICogcHJvY2Vzc2luZywgY2FsbHMgdG8ge0Bjb2RlIHJlYWR9IGFuZCB7QGNvZGUgd3JpdGV9IHdpbGwgYmxvY2suCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTb2NrZXRDaGFubmVsIGV4dGVuZHMgQWJzdHJhY3RTZWxlY3RhYmxlQ2hhbm5lbCBpbXBsZW1lbnRzCisgICAgICAgIEJ5dGVDaGFubmVsLCBTY2F0dGVyaW5nQnl0ZUNoYW5uZWwsIEdhdGhlcmluZ0J5dGVDaGFubmVsIHsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFNvY2tldENoYW5uZWx9LgorICAgICAqCisgICAgICogQHBhcmFtIHNlbGVjdG9yUHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIGFuIGluc3RhbmNlIG9mIFNlbGVjdG9yUHJvdmlkZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNvY2tldENoYW5uZWwoU2VsZWN0b3JQcm92aWRlciBzZWxlY3RvclByb3ZpZGVyKSB7CisgICAgICAgIHN1cGVyKHNlbGVjdG9yUHJvdmlkZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gb3BlbiBhbmQgdW5jb25uZWN0ZWQgc29ja2V0IGNoYW5uZWwuCisgICAgICogPHA+CisgICAgICogVGhpcyBjaGFubmVsIGlzIGNyZWF0ZWQgYnkgY2FsbGluZyB7QGNvZGUgb3BlblNvY2tldENoYW5uZWwoKX0gb2YgdGhlCisgICAgICogZGVmYXVsdCB7QGxpbmsgU2VsZWN0b3JQcm92aWRlcn0gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgY2hhbm5lbCB3aGljaCBpcyBvcGVuIGJ1dCB1bmNvbm5lY3RlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNvY2tldENoYW5uZWwgb3BlbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBTZWxlY3RvclByb3ZpZGVyLnByb3ZpZGVyKCkub3BlblNvY2tldENoYW5uZWwoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgc29ja2V0IGNoYW5uZWwgYW5kIGNvbm5lY3RzIGl0IHRvIGEgc29ja2V0IGFkZHJlc3MuCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgcGVyZm9ybXMgYSBjYWxsIHRvIHtAY29kZSBvcGVuKCl9IGZvbGxvd2VkIGJ5IGEgY2FsbCB0bworICAgICAqIHtAY29kZSBjb25uZWN0KFNvY2tldEFkZHJlc3MpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhZGRyZXNzCisgICAgICogICAgICAgICAgICB0aGUgc29ja2V0IGFkZHJlc3MgdG8gYmUgY29ubmVjdGVkIHRvLgorICAgICAqIEByZXR1cm4gdGhlIG5ldyBjb25uZWN0ZWQgY2hhbm5lbC4KKyAgICAgKiBAdGhyb3dzIEFzeW5jaHJvbm91c0Nsb3NlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIGNsb3NlZCBieSBhbm90aGVyIHRocmVhZCB3aGlsZSB0aGlzIG1ldGhvZAorICAgICAqICAgICAgICAgICAgIGlzIGV4ZWN1dGluZy4KKyAgICAgKiBAdGhyb3dzIENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciB0aHJlYWQgaW50ZXJydXB0cyB0aGUgY2FsbGluZyB0aHJlYWQgd2hpbGUgdGhpcworICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbiBpcyBleGVjdXRpbmcuIFRoZSBjYWxsaW5nIHRocmVhZCB3aWxsIGhhdmUgdGhlCisgICAgICogICAgICAgICAgICAgaW50ZXJydXB0IHN0YXRlIHNldCBhbmQgdGhlIGNoYW5uZWwgd2lsbCBiZSBjbG9zZWQuCisgICAgICogQHRocm93cyBVbnJlc29sdmVkQWRkcmVzc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhZGRyZXNzIGlzIG5vdCByZXNvbHZlZC4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkQWRkcmVzc1R5cGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgYWRkcmVzcyB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTb2NrZXRDaGFubmVsIG9wZW4oU29ja2V0QWRkcmVzcyBhZGRyZXNzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTb2NrZXRDaGFubmVsIHNvY2tldENoYW5uZWwgPSBvcGVuKCk7CisgICAgICAgIGlmIChzb2NrZXRDaGFubmVsICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNvY2tldENoYW5uZWwuY29ubmVjdChhZGRyZXNzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc29ja2V0Q2hhbm5lbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWxpZCBvcGVyYXRpb25zIG9mIHRoaXMgY2hhbm5lbC4gU29ja2V0IGNoYW5uZWxzIHN1cHBvcnQKKyAgICAgKiBjb25uZWN0LCByZWFkIGFuZCB3cml0ZSBvcGVyYXRpb24sIHNvIHRoaXMgbWV0aG9kIHJldHVybnMKKyAgICAgKiB7QGNvZGUgU2VsZWN0aW9uS2V5Lk9QX0NPTk5FQ1QgfCBTZWxlY3Rpb25LZXkuT1BfUkVBRCB8IFNlbGVjdGlvbktleS5PUF9XUklURX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBvcGVyYXRpb25zIHN1cHBvcnRlZCBieSB0aGlzIGNoYW5uZWwuCisgICAgICogQHNlZSBqYXZhLm5pby5jaGFubmVscy5TZWxlY3RhYmxlQ2hhbm5lbCN2YWxpZE9wcygpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGludCB2YWxpZE9wcygpIHsKKyAgICAgICAgcmV0dXJuIChTZWxlY3Rpb25LZXkuT1BfQ09OTkVDVCB8IFNlbGVjdGlvbktleS5PUF9SRUFEIHwgU2VsZWN0aW9uS2V5Lk9QX1dSSVRFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzb2NrZXQgYXNzaWduZWQgdG8gdGhpcyBjaGFubmVsLCB3aGljaCBkb2VzIG5vdCBkZWNsYXJlIGFueSBwdWJsaWMKKyAgICAgKiBtZXRob2RzIHRoYXQgYXJlIG5vdCBkZWNsYXJlZCBpbiB7QGNvZGUgU29ja2V0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNvY2tldCBhc3NpZ25lZCB0byB0aGlzIGNoYW5uZWwuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFNvY2tldCBzb2NrZXQoKTsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgY2hhbm5lbCdzIHNvY2tldCBpcyBjb25uZWN0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGNoYW5uZWwncyBzb2NrZXQgaXMgY29ubmVjdGVkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNDb25uZWN0ZWQoKTsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgY2hhbm5lbCdzIHNvY2tldCBpcyBzdGlsbCB0cnlpbmcgdG8gY29ubmVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBjb25uZWN0aW9uIGlzIGluaXRpYXRlZCBidXQgbm90IGZpbmlzaGVkOworICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNDb25uZWN0aW9uUGVuZGluZygpOworCisgICAgLyoqCisgICAgICogQ29ubmVjdHMgdGhpcyBjaGFubmVsJ3Mgc29ja2V0IHdpdGggYSByZW1vdGUgYWRkcmVzcy4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGlzIGNoYW5uZWwgaXMgYmxvY2tpbmcsIHRoaXMgbWV0aG9kIHdpbGwgc3VzcGVuZCB1bnRpbCBjb25uZWN0aW5nIGlzCisgICAgICogZmluaXNoZWQgb3IgYW4gSS9PIGV4Y2VwdGlvbiBvY2N1cnMuIElmIHRoZSBjaGFubmVsIGlzIG5vbi1ibG9ja2luZywKKyAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGNvbm5lY3Rpb24gaXMgZmluaXNoZWQgYXQKKyAgICAgKiBvbmNlIG9yIHJldHVybiB7QGNvZGUgZmFsc2V9IHdoZW4gdGhlIGNvbm5lY3Rpb24gbXVzdCBiZSBmaW5pc2hlZCBsYXRlcgorICAgICAqIGJ5IGNhbGxpbmcge0Bjb2RlIGZpbmlzaENvbm5lY3QoKX0uCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIGNhbGxlZCBhdCBhbnkgbW9tZW50IGFuZCBjYW4gYmxvY2sgb3RoZXIgcmVhZCBhbmQKKyAgICAgKiB3cml0ZSBvcGVyYXRpb25zIHdoaWxlIGNvbm5lY3RpbmcuIEl0IGV4ZWN1dGVzIHRoZSBzYW1lIHNlY3VyaXR5IGNoZWNrcworICAgICAqIGFzIHRoZSBjb25uZWN0IG1ldGhvZCBvZiB0aGUge0Bjb2RlIFNvY2tldH0gY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWRkcmVzcworICAgICAqICAgICAgICAgICAgdGhlIGFkZHJlc3MgdG8gY29ubmVjdCB3aXRoLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBjb25uZWN0aW9uIGlzIGZpbmlzaGVkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBBbHJlYWR5Q29ubmVjdGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaXMgYWxyZWFkeSBjb25uZWN0ZWQuCisgICAgICogQHRocm93cyBDb25uZWN0aW9uUGVuZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgbm9uLWJsb2NraW5nIGNvbm5lY3Rpbmcgb3BlcmF0aW9uIGlzIGFscmVhZHkgZXhlY3V0aW5nIG9uCisgICAgICogICAgICAgICAgICAgdGhpcyBjaGFubmVsLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQgYnkgYW5vdGhlciB0aHJlYWQgd2hpbGUgdGhpcyBtZXRob2QKKyAgICAgKiAgICAgICAgICAgICBpcyBleGVjdXRpbmcuCisgICAgICogQHRocm93cyBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgdGhyZWFkIGludGVycnVwdHMgdGhlIGNhbGxpbmcgdGhyZWFkIHdoaWxlIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MuIFRoZSBjYWxsaW5nIHRocmVhZCB3aWxsIGhhdmUgdGhlCisgICAgICogICAgICAgICAgICAgaW50ZXJydXB0IHN0YXRlIHNldCBhbmQgdGhpcyBjaGFubmVsIHdpbGwgYmUgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgVW5yZXNvbHZlZEFkZHJlc3NFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgYWRkcmVzcyBpcyBub3QgcmVzb2x2ZWQuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZEFkZHJlc3NUeXBlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGFkZHJlc3MgdHlwZSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGNvbm5lY3QoU29ja2V0QWRkcmVzcyBhZGRyZXNzKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDb21wbGV0ZXMgdGhlIGNvbm5lY3Rpb24gcHJvY2VzcyBpbml0aWF0ZWQgYnkgYSBjYWxsIG9mIHtAY29kZQorICAgICAqIGNvbm5lY3QoU29ja2V0QWRkcmVzcyl9LgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoZSBjb25uZWN0aW9uIGlzIGZpbmlzaGVkIGFscmVhZHkKKyAgICAgKiBhbmQgcmV0dXJucyB7QGNvZGUgZmFsc2V9IGlmIHRoZSBjaGFubmVsIGlzIG5vbi1ibG9ja2luZyBhbmQgdGhlCisgICAgICogY29ubmVjdGlvbiBpcyBub3QgZmluaXNoZWQgeWV0LgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgY2hhbm5lbCBpcyBpbiBibG9ja2luZyBtb2RlLCB0aGlzIG1ldGhvZCB3aWxsIHN1c3BlbmQgYW5kIHJldHVybgorICAgICAqIHtAY29kZSB0cnVlfSB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGZpbmlzaGVkLiBJdCBjbG9zZXMgdGhpcyBjaGFubmVsIGFuZAorICAgICAqIHRocm93cyBhbiBleGNlcHRpb24gaWYgdGhlIGNvbm5lY3Rpb24gZmFpbHMuCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIGNhbGxlZCBhdCBhbnkgbW9tZW50IGFuZCBpdCBjYW4gYmxvY2sgb3RoZXIge0Bjb2RlCisgICAgICogcmVhZH0gYW5kIHtAY29kZSB3cml0ZX0gb3BlcmF0aW9ucyB3aGlsZSBjb25uZWN0aW5nLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bGx5IGZpbmlzaGVkLCB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBOb0Nvbm5lY3Rpb25QZW5kaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgaXMgbm90IGNvbm5lY3RlZCBhbmQgdGhlIGNvbm5lY3Rpb24gcHJvY2VzcworICAgICAqICAgICAgICAgICAgIGhhcyBub3QgYmVlbiBpbml0aWF0ZWQuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIEFzeW5jaHJvbm91c0Nsb3NlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIGNsb3NlZCBieSBhbm90aGVyIHRocmVhZCB3aGlsZSB0aGlzIG1ldGhvZAorICAgICAqICAgICAgICAgICAgIGlzIGV4ZWN1dGluZy4KKyAgICAgKiBAdGhyb3dzIENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciB0aHJlYWQgaW50ZXJydXB0cyB0aGUgY2FsbGluZyB0aHJlYWQgd2hpbGUgdGhpcworICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcy4gVGhlIGNhbGxpbmcgdGhyZWFkIGhhcyB0aGUKKyAgICAgKiAgICAgICAgICAgICBpbnRlcnJ1cHQgc3RhdGUgc2V0LCBhbmQgdGhpcyBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBmaW5pc2hDb25uZWN0KCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgYnl0ZXMgZnJvbSB0aGlzIHNvY2tldCBjaGFubmVsIGludG8gdGhlIGdpdmVuIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3aWxsIGJlIHJlYWQgaXMgdGhlIHJlbWFpbmluZyBudW1iZXIgb2YKKyAgICAgKiBieXRlcyBpbiB0aGUgYnVmZmVyIHdoZW4gdGhlIG1ldGhvZCBpcyBpbnZva2VkLiBUaGUgYnl0ZXMgd2lsbCBiZSBjb3BpZWQKKyAgICAgKiBpbnRvIHRoZSBidWZmZXIgc3RhcnRpbmcgYXQgdGhlIGJ1ZmZlcidzIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogPHA+CisgICAgICogVGhlIGNhbGwgbWF5IGJsb2NrIGlmIG90aGVyIHRocmVhZHMgYXJlIGFsc28gYXR0ZW1wdGluZyB0byByZWFkIGZyb20gdGhpcworICAgICAqIGNoYW5uZWwuCisgICAgICogPHA+CisgICAgICogVXBvbiBjb21wbGV0aW9uLCB0aGUgYnVmZmVyJ3MgcG9zaXRpb24gaXMgc2V0IHRvIHRoZSBlbmQgb2YgdGhlIGJ5dGVzCisgICAgICogdGhhdCBoYXZlIGJlZW4gcmVhZC4gVGhlIGJ1ZmZlcidzIGxpbWl0IGlzIG5vdCBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIHRhcmdldAorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYnVmZmVyIHRvIHJlY2VpdmUgdGhlIGJ5dGVzLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSByZWFkLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIHRocmVhZCBjbG9zZXMgdGhlIGNoYW5uZWwgZHVyaW5nIHRoZSByZWFkLgorICAgICAqIEB0aHJvd3MgTm90WWV0Q29ubmVjdGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIG5vdCB5ZXQgY29ubmVjdGVkLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIHRocmVhZCBpbnRlcnJ1cHRzIHRoZSBjYWxsaW5nIHRocmVhZCB3aGlsZSB0aGlzCisgICAgICogICAgICAgICAgICAgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLiBUaGUgaW50ZXJydXB0IHN0YXRlIG9mIHRoZSBjYWxsaW5nCisgICAgICogICAgICAgICAgICAgdGhyZWFkIGlzIHNldCBhbmQgdGhlIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlIGphdmEubmlvLmNoYW5uZWxzLlJlYWRhYmxlQnl0ZUNoYW5uZWwjcmVhZChqYXZhLm5pby5CeXRlQnVmZmVyKQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgcmVhZChCeXRlQnVmZmVyIHRhcmdldCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgYnl0ZXMgZnJvbSB0aGlzIHNvY2tldCBjaGFubmVsIGludG8gYSBzdWJzZXQgb2YgdGhlIGdpdmVuIGJ1ZmZlcnMuCisgICAgICogVGhpcyBtZXRob2QgYXR0ZW1wdHMgdG8gcmVhZCBhbGwge0Bjb2RlIHJlbWFpbmluZygpfSBieXRlcyBmcm9tIHtAY29kZQorICAgICAqIGxlbmd0aH0gYnl0ZSBidWZmZXJzLCBpbiBvcmRlciwgc3RhcnRpbmcgYXQge0Bjb2RlIHRhcmdldHNbb2Zmc2V0XX0uIFRoZQorICAgICAqIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSByZWFkIGlzIHJldHVybmVkLgorICAgICAqIDxwPgorICAgICAqIElmIGEgcmVhZCBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MsIHN1YnNlcXVlbnQgdGhyZWFkcyB3aWxsIGJsb2NrIHVudGlsCisgICAgICogdGhlIHJlYWQgaXMgY29tcGxldGVkIGFuZCB3aWxsIHRoZW4gY29udGVuZCBmb3IgdGhlIGFiaWxpdHkgdG8gcmVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YXJnZXRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgYnl0ZSBidWZmZXJzIGludG8gd2hpY2ggdGhlIGJ5dGVzIHdpbGwgYmUgY29waWVkLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgYnVmZmVyIHRvIHN0b3JlIGJ5dGVzIGluLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBidWZmZXJzIHRvIHN0b3JlIGJ5dGVzIGluLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSByZWFkLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgY2xvc2VkIGJ5IGFub3RoZXIgdGhyZWFkIGR1cmluZyB0aGlzIHJlYWQKKyAgICAgKiAgICAgICAgICAgICBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgdGhyZWFkIGludGVycnVwdHMgdGhlIGNhbGxpbmcgdGhyZWFkIHdoaWxlIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MuIFRoZSBpbnRlcnJ1cHQgc3RhdGUgb2YgdGhlIGNhbGxpbmcKKyAgICAgKiAgICAgICAgICAgICB0aHJlYWQgaXMgc2V0IGFuZCB0aGUgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0IDwgMH0gb3Ige0Bjb2RlIGxlbmd0aCA8IDB9LCBvciBpZiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBvZmZzZXQgKyBsZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgc2l6ZSBvZiB7QGNvZGUgdGFyZ2V0c30uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAdGhyb3dzIE5vdFlldENvbm5lY3RlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBub3QgeWV0IGNvbm5lY3RlZC4KKyAgICAgKiBAc2VlIGphdmEubmlvLmNoYW5uZWxzLlNjYXR0ZXJpbmdCeXRlQ2hhbm5lbCNyZWFkKGphdmEubmlvLkJ5dGVCdWZmZXJbXSwKKyAgICAgKiAgICAgIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBsb25nIHJlYWQoQnl0ZUJ1ZmZlcltdIHRhcmdldHMsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIGJ5dGVzIGZyb20gdGhpcyBzb2NrZXQgY2hhbm5lbCBhbmQgc3RvcmVzIHRoZW0gaW4gdGhlIHNwZWNpZmllZAorICAgICAqIGFycmF5IG9mIGJ1ZmZlcnMuIFRoaXMgbWV0aG9kIGF0dGVtcHRzIHRvIHJlYWQgYXMgbWFueSBieXRlcyBhcyBjYW4gYmUKKyAgICAgKiBzdG9yZWQgaW4gdGhlIGJ1ZmZlciBhcnJheSBmcm9tIHRoaXMgY2hhbm5lbCBhbmQgcmV0dXJucyB0aGUgbnVtYmVyIG9mCisgICAgICogYnl0ZXMgYWN0dWFsbHkgcmVhZC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiBhIHJlYWQgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLCBzdWJzZXF1ZW50IHRocmVhZHMgd2lsbCBibG9jayB1bnRpbAorICAgICAqIHRoZSByZWFkIGlzIGNvbXBsZXRlZCBhbmQgd2lsbCB0aGVuIGNvbnRlbmQgZm9yIHRoZSBhYmlsaXR5IHRvIHJlYWQuCisgICAgICogPHA+CisgICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIGNhbGxpbmcge0Bjb2RlIHJlYWQodGFyZ2V0cywgMCwKKyAgICAgKiB0YXJnZXRzLmxlbmd0aCk7fQorICAgICAqCisgICAgICogQHBhcmFtIHRhcmdldHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBieXRlIGJ1ZmZlcnMgaW50byB3aGljaCB0aGUgYnl0ZXMgd2lsbCBiZSBjb3BpZWQuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHJlYWQuCisgICAgICogQHRocm93cyBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQgYnkgYW5vdGhlciB0aHJlYWQgZHVyaW5nIHRoaXMgcmVhZAorICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciB0aHJlYWQgaW50ZXJydXB0cyB0aGUgY2FsbGluZyB0aHJlYWQgd2hpbGUgdGhpcworICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcy4gVGhlIGludGVycnVwdCBzdGF0ZSBvZiB0aGUgY2FsbGluZworICAgICAqICAgICAgICAgICAgIHRocmVhZCBpcyBzZXQgYW5kIHRoZSBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIENsb3NlZENoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHRocm93cyBOb3RZZXRDb25uZWN0ZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgbm90IHlldCBjb25uZWN0ZWQuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBmaW5hbCBsb25nIHJlYWQoQnl0ZUJ1ZmZlcltdIHRhcmdldHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByZWFkKHRhcmdldHMsIDAsIHRhcmdldHMubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYnl0ZXMgZnJvbSB0aGUgZ2l2ZW4gYnl0ZSBidWZmZXIgdG8gdGhpcyBzb2NrZXQgY2hhbm5lbC4gVGhlCisgICAgICogbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBhcmUgd3JpdHRlbiBpcyB0aGUgcmVtYWluaW5nIG51bWJlciBvZiBieXRlcworICAgICAqIGluIHRoZSBidWZmZXIgd2hlbiB0aGlzIG1ldGhvZCBpcyBpbnZva2VkLiBUaGUgYnl0ZXMgYXJlIHRha2VuIGZyb20gdGhlCisgICAgICogYnVmZmVyIHN0YXJ0aW5nIGF0IHRoZSBidWZmZXIncyBwb3NpdGlvbi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgY2FsbCBtYXkgYmxvY2sgaWYgb3RoZXIgdGhyZWFkcyBhcmUgYWxzbyBhdHRlbXB0aW5nIHRvIHdyaXRlIHRvIHRoZQorICAgICAqIHNhbWUgY2hhbm5lbC4KKyAgICAgKiA8cD4KKyAgICAgKiBVcG9uIGNvbXBsZXRpb24sIHRoZSBidWZmZXIncyBwb3NpdGlvbiBpcyB1cGRhdGVkIHRvIHRoZSBlbmQgb2YgdGhlIGJ5dGVzCisgICAgICogdGhhdCBoYXZlIGJlZW4gd3JpdHRlbi4gVGhlIGJ1ZmZlcidzIGxpbWl0IGlzIG5vdCBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIGJ5dGVzIHRvIGJlIHdyaXR0ZW4uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHdyaXR0ZW4uCisgICAgICogQHRocm93cyBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgdGhyZWFkIGNsb3NlcyB0aGUgY2hhbm5lbCBkdXJpbmcgdGhlIHdyaXRlLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIHRocmVhZCBpbnRlcnJ1cHRzIHRoZSBjYWxsaW5nIHRocmVhZCB3aGlsZSB0aGlzCisgICAgICogICAgICAgICAgICAgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLiBUaGUgaW50ZXJydXB0IHN0YXRlIG9mIHRoZSBjYWxsaW5nCisgICAgICogICAgICAgICAgICAgdGhyZWFkIGlzIHNldCBhbmQgdGhlIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFubmVsIHdhcyBhbHJlYWR5IGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEB0aHJvd3MgTm90WWV0Q29ubmVjdGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIG5vdCBjb25uZWN0ZWQgeWV0LgorICAgICAqIEBzZWUgamF2YS5uaW8uY2hhbm5lbHMuV3JpdGFibGVCeXRlQ2hhbm5lbCN3cml0ZShqYXZhLm5pby5CeXRlQnVmZmVyKQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgd3JpdGUoQnl0ZUJ1ZmZlciBzb3VyY2UpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEF0dGVtcHRzIHRvIHdyaXRlIGEgc3Vic2V0IG9mIHRoZSBnaXZlbiBieXRlcyBmcm9tIHRoZSBidWZmZXJzIHRvIHRoaXMKKyAgICAgKiBzb2NrZXQgY2hhbm5lbC4gVGhpcyBtZXRob2QgYXR0ZW1wdHMgdG8gd3JpdGUgYWxsIHtAY29kZSByZW1haW5pbmcoKX0KKyAgICAgKiBieXRlcyBmcm9tIHtAY29kZSBsZW5ndGh9IGJ5dGUgYnVmZmVycywgaW4gb3JkZXIsIHN0YXJ0aW5nIGF0IHtAY29kZQorICAgICAqIHNvdXJjZXNbb2Zmc2V0XX0uIFRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgd3JpdHRlbiBpcyByZXR1cm5lZC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiBhIHdyaXRlIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcywgc3Vic2VxdWVudCB0aHJlYWRzIHdpbGwgYmxvY2sgdW50aWwKKyAgICAgKiB0aGUgd3JpdGUgaXMgY29tcGxldGVkIGFuZCB0aGVuIGNvbnRlbmQgZm9yIHRoZSBhYmlsaXR5IHRvIHdyaXRlLgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBieXRlIGJ1ZmZlcnMgdGhhdCBpcyB0aGUgc291cmNlIGZvciBieXRlcyB3cml0dGVuCisgICAgICogICAgICAgICAgICB0byB0aGlzIGNoYW5uZWwuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBidWZmZXIgaW4ge0Bjb2RlIGJ1ZmZlcnMgfXRvIGdldCBieXRlcworICAgICAqICAgICAgICAgICAgZnJvbS4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ1ZmZlcnMgdG8gZ2V0IGJ5dGVzIGZyb20uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHdyaXR0ZW4gdG8gdGhpcyBjaGFubmVsLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgY2xvc2VkIGJ5IGFub3RoZXIgdGhyZWFkIGR1cmluZyB0aGlzIHdyaXRlCisgICAgICogICAgICAgICAgICAgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIHRocmVhZCBpbnRlcnJ1cHRzIHRoZSBjYWxsaW5nIHRocmVhZCB3aGlsZSB0aGlzCisgICAgICogICAgICAgICAgICAgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLiBUaGUgaW50ZXJydXB0IHN0YXRlIG9mIHRoZSBjYWxsaW5nCisgICAgICogICAgICAgICAgICAgdGhyZWFkIGlzIHNldCBhbmQgdGhlIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldCA8IDB9IG9yIHtAY29kZSBsZW5ndGggPCAwfSwgb3IgaWYge0Bjb2RlCisgICAgICogICAgICAgICAgICAgb2Zmc2V0ICsgbGVuZ3RofSBpcyBncmVhdGVyIHRoYW4gdGhlIHNpemUgb2Yge0Bjb2RlIHNvdXJjZXN9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHRocm93cyBOb3RZZXRDb25uZWN0ZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgbm90IHlldCBjb25uZWN0ZWQuCisgICAgICogQHNlZSBqYXZhLm5pby5jaGFubmVscy5HYXRoZXJpbmdCeXRlQ2hhbm5lbCN3cml0ZShqYXZhLm5pby5CeXRlQnVmZmVyW10sCisgICAgICogICAgICBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgbG9uZyB3cml0ZShCeXRlQnVmZmVyW10gc291cmNlcywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIGJ5dGVzIGZyb20gYWxsIHRoZSBnaXZlbiBieXRlIGJ1ZmZlcnMgdG8gdGhpcyBzb2NrZXQgY2hhbm5lbC4KKyAgICAgKiA8cD4KKyAgICAgKiBDYWxsaW5nIHRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8gY2FsbGluZyB7QGNvZGUgd3JpdGUoc291cmNlcywgMCwKKyAgICAgKiBzb3VyY2VzLmxlbmd0aCk7fQorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXJzIGNvbnRhaW5pbmcgYnl0ZXMgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHdyaXR0ZW4uCisgICAgICogQHRocm93cyBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQgYnkgYW5vdGhlciB0aHJlYWQgZHVyaW5nIHRoaXMgd3JpdGUKKyAgICAgKiAgICAgICAgICAgICBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFub3RoZXIgdGhyZWFkIGludGVycnVwdHMgdGhlIGNhbGxpbmcgdGhyZWFkIHdoaWxlIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MuIFRoZSBpbnRlcnJ1cHQgc3RhdGUgb2YgdGhlIGNhbGxpbmcKKyAgICAgKiAgICAgICAgICAgICB0aHJlYWQgaXMgc2V0IGFuZCB0aGUgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEB0aHJvd3MgTm90WWV0Q29ubmVjdGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGlzIG5vdCB5ZXQgY29ubmVjdGVkLgorICAgICAqIEBzZWUgamF2YS5uaW8uY2hhbm5lbHMuR2F0aGVyaW5nQnl0ZUNoYW5uZWwjd3JpdGUoamF2YS5uaW8uQnl0ZUJ1ZmZlcltdKQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgZmluYWwgbG9uZyB3cml0ZShCeXRlQnVmZmVyW10gc291cmNlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHdyaXRlKHNvdXJjZXMsIDAsIHNvdXJjZXMubGVuZ3RoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvVW5yZXNvbHZlZEFkZHJlc3NFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9VbnJlc29sdmVkQWRkcmVzc0V4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMzNTZmYWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvVW5yZXNvbHZlZEFkZHJlc3NFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDMyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYW5uZWxzOworCisvKioKKyAqIEFuIHtAY29kZSBVbnJlc29sdmVkQWRkcmVzc0V4Y2VwdGlvbn0gaXMgdGhyb3duIHdoZW4gdHJ5aW5nIHRvIHVzZSBhbgorICogdW5yZXNvbHZlZCBuZXR3b3JrIGFkZHJlc3MgaW4gYSBuZXR3b3JrIG9wZXJhdGlvbi4KKyAqLworcHVibGljIGNsYXNzIFVucmVzb2x2ZWRBZGRyZXNzRXhjZXB0aW9uIGV4dGVuZHMgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDYxMzY5NTkwOTM2MjA3OTQxNDhMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiB7QGNvZGUgVW5yZXNvbHZlZEFkZHJlc3NFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBVbnJlc29sdmVkQWRkcmVzc0V4Y2VwdGlvbigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvVW5zdXBwb3J0ZWRBZGRyZXNzVHlwZUV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL1Vuc3VwcG9ydGVkQWRkcmVzc1R5cGVFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YmNhNDAxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL1Vuc3VwcG9ydGVkQWRkcmVzc1R5cGVFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDMyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYW5uZWxzOworCisvKioKKyAqIEFuIHtAY29kZSBVbnN1cHBvcnRlZEFkZHJlc3NUeXBlRXhjZXB0aW9ufSBpcyB0aHJvd24gd2hlbiBjb25uZWN0aW5nIG9yCisgKiBiaW5kaW5nIHRvIGFuIHVuc3VwcG9ydGVkIGFkZHJlc3MgdHlwZS4KKyAqLworcHVibGljIGNsYXNzIFVuc3VwcG9ydGVkQWRkcmVzc1R5cGVFeGNlcHRpb24gZXh0ZW5kcyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTI5NjQzMjM4NDI4Mjk3MDA0OTNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiB7QGNvZGUgVW5zdXBwb3J0ZWRBZGRyZXNzVHlwZUV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIFVuc3VwcG9ydGVkQWRkcmVzc1R5cGVFeGNlcHRpb24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL1dyaXRhYmxlQnl0ZUNoYW5uZWwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9Xcml0YWJsZUJ5dGVDaGFubmVsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2JmMDY2NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9Xcml0YWJsZUJ5dGVDaGFubmVsLmphdmEKQEAgLTAsMCArMSw2NCBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFubmVsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKKworLyoqCisgKiBBIHtAY29kZSBXcml0YWJsZUJ5dGVDaGFubmVsfSBpcyBhIHR5cGUgb2Yge0BsaW5rIENoYW5uZWx9IHRoYXQgY2FuIHdyaXRlCisgKiBieXRlcy4KKyAqIDxwPgorICogV3JpdGUgb3BlcmF0aW9ucyBhcmUgc3luY2hyb25vdXMgb24gYSB7QGNvZGUgV3JpdGFibGVCeXRlQ2hhbm5lbH0sIHRoYXQgaXMsCisgKiBpZiBhIHdyaXRlIGlzIGFscmVhZHkgaW4gcHJvZ3Jlc3Mgb24gdGhlIGNoYW5uZWwgdGhlbiBzdWJzZXF1ZW50IHdyaXRlcyB3aWxsCisgKiBibG9jayB1bnRpbCB0aGUgZmlyc3Qgd3JpdGUgY29tcGxldGVzLiBJdCBpcyB1bmRlZmluZWQgd2hldGhlciBub24td3JpdGUKKyAqIG9wZXJhdGlvbnMgd2lsbCBibG9jay4KKyAqLworcHVibGljIGludGVyZmFjZSBXcml0YWJsZUJ5dGVDaGFubmVsIGV4dGVuZHMgQ2hhbm5lbCB7CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYnl0ZXMgZnJvbSB0aGUgZ2l2ZW4gYnVmZmVyIHRvIHRoZSBjaGFubmVsLgorICAgICAqIDxwPgorICAgICAqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0aGF0IHdpbGwgYmUgd3JpdHRlbiBpcyB0aGUKKyAgICAgKiA8Y29kZT5yZW1haW5pbmcoKTwvY29kZT4gbnVtYmVyIG9mIGJ5dGVzIGluIHRoZSBidWZmZXIgd2hlbiB0aGUgbWV0aG9kCisgICAgICogaW52b2tlZC4gVGhlIGJ5dGVzIHdpbGwgYmUgd3JpdHRlbiBmcm9tIHRoZSBidWZmZXIgc3RhcnRpbmcgYXQgdGhlCisgICAgICogYnVmZmVyJ3MgPGNvZGU+cG9zaXRpb248L2NvZGU+LgorICAgICAqIDxwPgorICAgICAqIFRoZSBjYWxsIG1heSBibG9jayBpZiBvdGhlciB0aHJlYWRzIGFyZSBhbHNvIGF0dGVtcHRpbmcgdG8gd3JpdGUgb24gdGhlCisgICAgICogc2FtZSBjaGFubmVsLgorICAgICAqIDxwPgorICAgICAqIFVwb24gY29tcGxldGlvbiwgdGhlIGJ1ZmZlcidzIDxjb2RlPnBvc2l0aW9uKCk8L2NvZGU+IGlzIHVwZGF0ZWQgdG8gdGhlCisgICAgICogZW5kIG9mIHRoZSBieXRlcyB0aGF0IHdlcmUgd3JpdHRlbi4gVGhlIGJ1ZmZlcidzIDxjb2RlPmxpbWl0KCk8L2NvZGU+CisgICAgICogaXMgdW5tb2RpZmllZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGJ1ZmZlciBjb250YWluaW5nIHRoZSBieXRlcyB0byBiZSB3cml0dGVuLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSB3cml0dGVuLgorICAgICAqIEB0aHJvd3MgTm9uV3JpdGFibGVDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgd2FzIG5vdCBvcGVuZWQgZm9yIHdyaXRpbmcuCisgICAgICogQHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNoYW5uZWwgd2FzIGFscmVhZHkgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIHRocmVhZCBjbG9zZXMgdGhlIGNoYW5uZWwgZHVyaW5nIHRoZSB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciB0aHJlYWQgaW50ZXJydXB0IHRoZSBjYWxsaW5nIHRocmVhZCBkdXJpbmcgdGhlCisgICAgICogICAgICAgICAgICAgd3JpdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGFub3RoZXIgSU8gZXhjZXB0aW9uIG9jY3VycywgZGV0YWlscyBhcmUgaW4gdGhlIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIGludCB3cml0ZShCeXRlQnVmZmVyIGJ1ZmZlcikgdGhyb3dzIElPRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL3NwaS9BYnN0cmFjdEludGVycnVwdGlibGVDaGFubmVsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvc3BpL0Fic3RyYWN0SW50ZXJydXB0aWJsZUNoYW5uZWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOTQ4NzQyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL3NwaS9BYnN0cmFjdEludGVycnVwdGlibGVDaGFubmVsLmphdmEKQEAgLTAsMCArMSwxMzUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhbm5lbHMuc3BpOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5Bc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5DaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkNsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkludGVycnVwdGlibGVDaGFubmVsOworCisvKioKKyAqIHtAY29kZSBBYnN0cmFjdEludGVycnVwdGlibGVDaGFubmVsfSBpcyB0aGUgcm9vdCBjbGFzcyBmb3IgaW50ZXJydXB0aWJsZQorICogY2hhbm5lbHMuCisgKiA8cD4KKyAqIFRoZSBiYXNpYyB1c2FnZSBwYXR0ZXJuIGZvciBhbiBpbnRlcnJ1cHRpYmxlIGNoYW5uZWwgaXMgdG8gaW52b2tlCisgKiB7QGNvZGUgYmVnaW4oKX0gYmVmb3JlIGFueSBJL08gb3BlcmF0aW9uIHRoYXQgcG90ZW50aWFsbHkgYmxvY2tzCisgKiBpbmRlZmluaXRlbHksIHRoZW4ge0Bjb2RlIGVuZChib29sZWFuKX0gYWZ0ZXIgY29tcGxldGluZyB0aGUgb3BlcmF0aW9uLiBUaGUKKyAqIGFyZ3VtZW50IHRvIHRoZSB7QGNvZGUgZW5kfSBtZXRob2Qgc2hvdWxkIGluZGljYXRlIGlmIHRoZSBJL08gb3BlcmF0aW9uIGhhcworICogYWN0dWFsbHkgY29tcGxldGVkIHNvIHRoYXQgYW55IGNoYW5nZSBtYXkgYmUgdmlzaWJsZSB0byB0aGUgaW52b2tlci4KKyovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RJbnRlcnJ1cHRpYmxlQ2hhbm5lbCBpbXBsZW1lbnRzIENoYW5uZWwsIEludGVycnVwdGlibGVDaGFubmVsIHsKKworICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiBjbG9zZWQgPSBmYWxzZTsKKworICAgIHZvbGF0aWxlIGJvb2xlYW4gaW50ZXJydXB0ZWQgPSBmYWxzZTsKKworICAgIHByaXZhdGUgZmluYWwgUnVubmFibGUgaW50ZXJydXB0QW5kQ2xvc2VSdW5uYWJsZSA9IG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaW50ZXJydXB0ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIEFic3RyYWN0SW50ZXJydXB0aWJsZUNoYW5uZWwudGhpcy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfTsKKworICAgIHByb3RlY3RlZCBBYnN0cmFjdEludGVycnVwdGlibGVDaGFubmVsKCkgeworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgc3luY2hyb25pemVkIGZpbmFsIGJvb2xlYW4gaXNPcGVuKCkgeworICAgICAgICByZXR1cm4gIWNsb3NlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgYW4gb3BlbiBjaGFubmVsLiBJZiB0aGUgY2hhbm5lbCBpcyBhbHJlYWR5IGNsb3NlZCB0aGVuIHRoaXMgbWV0aG9kCisgICAgICogaGFzIG5vIGVmZmVjdCwgb3RoZXJ3aXNlIGl0IGNsb3NlcyB0aGUgcmVjZWl2ZXIgdmlhIHRoZQorICAgICAqIHtAY29kZSBpbXBsQ2xvc2VDaGFubmVsfSBtZXRob2QuCisgICAgICogPHA+CisgICAgICogSWYgYW4gYXR0ZW1wdCBpcyBtYWRlIHRvIHBlcmZvcm0gYW4gb3BlcmF0aW9uIG9uIGEgY2xvc2VkIGNoYW5uZWwgdGhlbiBhCisgICAgICoge0BsaW5rIGphdmEubmlvLmNoYW5uZWxzLkNsb3NlZENoYW5uZWxFeGNlcHRpb259IGlzIHRocm93bi4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiBtdWx0aXBsZSB0aHJlYWRzIGF0dGVtcHQgdG8gc2ltdWx0YW5lb3VzbHkgY2xvc2UgYSBjaGFubmVsLCB0aGVuIG9ubHkKKyAgICAgKiBvbmUgdGhyZWFkIHdpbGwgcnVuIHRoZSBjbG9zdXJlIGNvZGUgYW5kIHRoZSBvdGhlcnMgd2lsbCBiZSBibG9ja2VkIHVudGlsCisgICAgICogdGhlIGZpcnN0IG9uZSBjb21wbGV0ZXMuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycyB3aGlsZSBjbG9zaW5nIHRoaXMgY2hhbm5lbC4KKyAgICAgKiBAc2VlIGphdmEubmlvLmNoYW5uZWxzLkNoYW5uZWwjY2xvc2UoKQorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgZmluYWwgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghY2xvc2VkKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgICAgICBpZiAoIWNsb3NlZCkgeworICAgICAgICAgICAgICAgICAgICBjbG9zZWQgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICBpbXBsQ2xvc2VDaGFubmVsKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoZSBiZWdpbm5pbmcgb2YgYSBjb2RlIHNlY3Rpb24gdGhhdCBpbmNsdWRlcyBhbiBJL08gb3BlcmF0aW9uCisgICAgICogdGhhdCBpcyBwb3RlbnRpYWxseSBibG9ja2luZy4gQWZ0ZXIgdGhpcyBvcGVyYXRpb24sIHRoZSBhcHBsaWNhdGlvbgorICAgICAqIHNob3VsZCBpbnZva2UgdGhlIGNvcnJlc3BvbmRpbmcge0Bjb2RlIGVuZChib29sZWFuKX0gbWV0aG9kLgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGJlZ2luKCkgeworICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLnB1c2hJbnRlcnJ1cHRBY3Rpb24kKGludGVycnVwdEFuZENsb3NlUnVubmFibGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB0aGUgZW5kIG9mIGEgY29kZSBzZWN0aW9uIHRoYXQgaGFzIGJlZW4gc3RhcnRlZCB3aXRoCisgICAgICoge0Bjb2RlIGJlZ2luKCl9IGFuZCB0aGF0IGluY2x1ZGVzIGEgcG90ZW50aWFsbHkgYmxvY2tpbmcgSS9PIG9wZXJhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdWNjZXNzCisgICAgICogICAgICAgICAgICBwYXNzIHtAY29kZSB0cnVlfSBpZiB0aGUgYmxvY2tpbmcgb3BlcmF0aW9uIGhhcyBzdWNjZWVkZWQgYW5kCisgICAgICogICAgICAgICAgICBoYXMgaGFkIGEgbm90aWNlYWJsZSBlZmZlY3Q7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgY2xvc2VkIGJ5IGFub3RoZXIgdGhyZWFkIHdoaWxlIHRoaXMgbWV0aG9kCisgICAgICogICAgICAgICAgICAgaXMgZXhlY3V0aW5nLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIHRocmVhZCBpbnRlcnJ1cHRzIHRoZSBjYWxsaW5nIHRocmVhZCB3aGlsZSB0aGlzCisgICAgICogICAgICAgICAgICAgbWV0aG9kIGlzIGV4ZWN1dGluZy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBlbmQoYm9vbGVhbiBzdWNjZXNzKSB0aHJvd3MgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb24geworICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLnBvcEludGVycnVwdEFjdGlvbiQoaW50ZXJydXB0QW5kQ2xvc2VSdW5uYWJsZSk7CisgICAgICAgIGlmIChpbnRlcnJ1cHRlZCkgeworICAgICAgICAgICAgaW50ZXJydXB0ZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIHRocm93IG5ldyBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmICghc3VjY2VzcyAmJiBjbG9zZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW1wbGVtZW50cyB0aGUgY2hhbm5lbCBjbG9zaW5nIGJlaGF2aW9yLgorICAgICAqIDxwPgorICAgICAqIENsb3NlcyB0aGUgY2hhbm5lbCB3aXRoIGEgZ3VhcmFudGVlIHRoYXQgdGhlIGNoYW5uZWwgaXMgbm90IGN1cnJlbnRseQorICAgICAqIGNsb3NlZCB0aHJvdWdoIGFub3RoZXIgaW52b2NhdGlvbiBvZiB7QGNvZGUgY2xvc2UoKX0gYW5kIHRoYXQgdGhlIG1ldGhvZAorICAgICAqIGlzIHRocmVhZC1zYWZlLgorICAgICAqIDxwPgorICAgICAqIEFueSBvdXRzdGFuZGluZyB0aHJlYWRzIGJsb2NrZWQgb24gSS9PIG9wZXJhdGlvbnMgb24gdGhpcyBjaGFubmVsIG11c3QgYmUKKyAgICAgKiByZWxlYXNlZCB3aXRoIGVpdGhlciBhIG5vcm1hbCByZXR1cm4gY29kZSwgb3IgYnkgdGhyb3dpbmcgYW4KKyAgICAgKiB7QGNvZGUgQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb259LgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnMgd2hpbGUgY2xvc2luZyB0aGUgY2hhbm5lbC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBpbXBsQ2xvc2VDaGFubmVsKCkgdGhyb3dzIElPRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL3NwaS9BYnN0cmFjdFNlbGVjdGFibGVDaGFubmVsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvc3BpL0Fic3RyYWN0U2VsZWN0YWJsZUNoYW5uZWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYjc2ZThlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL3NwaS9BYnN0cmFjdFNlbGVjdGFibGVDaGFubmVsLmphdmEKQEAgLTAsMCArMSwyODIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhbm5lbHMuc3BpOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5DYW5jZWxsZWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5JbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLklsbGVnYWxTZWxlY3RvckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5TZWxlY3RhYmxlQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5TZWxlY3Rpb25LZXk7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU2VsZWN0b3I7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiB7QGNvZGUgQWJzdHJhY3RTZWxlY3RhYmxlQ2hhbm5lbH0gaXMgdGhlIGJhc2UgaW1wbGVtZW50YXRpb24gY2xhc3MgZm9yCisgKiBzZWxlY3RhYmxlIGNoYW5uZWxzLiBJdCBkZWNsYXJlcyBtZXRob2RzIGZvciByZWdpc3RlcmluZywgdW5yZWdpc3RlcmluZyBhbmQKKyAqIGNsb3Npbmcgc2VsZWN0YWJsZSBjaGFubmVscy4gSXQgaXMgdGhyZWFkLXNhZmUuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdFNlbGVjdGFibGVDaGFubmVsIGV4dGVuZHMgU2VsZWN0YWJsZUNoYW5uZWwgeworCisgICAgcHJpdmF0ZSBmaW5hbCBTZWxlY3RvclByb3ZpZGVyIHByb3ZpZGVyOworCisgICAgLyoKKyAgICAgKiBUaGUgY29sbGVjdGlvbiBvZiBrZXkuCisgICAgICovCisgICAgcHJpdmF0ZSBMaXN0PFNlbGVjdGlvbktleT4ga2V5TGlzdCA9IG5ldyBBcnJheUxpc3Q8U2VsZWN0aW9uS2V5PigpOworCisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgYmxvY2tpbmdMb2NrID0gbmV3IE9iamVjdCgpOworCisgICAgYm9vbGVhbiBpc0Jsb2NraW5nID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEFic3RyYWN0U2VsZWN0YWJsZUNoYW5uZWx9LgorICAgICAqCisgICAgICogQHBhcmFtIHNlbGVjdG9yUHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWxlY3RvciBwcm92aWRlciB0aGF0IGNyZWF0ZXMgdGhpcyBjaGFubmVsLgorICAgICAqLworICAgIHByb3RlY3RlZCBBYnN0cmFjdFNlbGVjdGFibGVDaGFubmVsKFNlbGVjdG9yUHJvdmlkZXIgc2VsZWN0b3JQcm92aWRlcikgeworICAgICAgICBwcm92aWRlciA9IHNlbGVjdG9yUHJvdmlkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2VsZWN0b3IgcHJvdmlkZXIgdGhhdCBoYXMgY3JlYXRlZCB0aGlzIGNoYW5uZWwuCisgICAgICoKKyAgICAgKiBAc2VlIGphdmEubmlvLmNoYW5uZWxzLlNlbGVjdGFibGVDaGFubmVsI3Byb3ZpZGVyKCkKKyAgICAgKiBAcmV0dXJuIHRoaXMgY2hhbm5lbCdzIHNlbGVjdG9yIHByb3ZpZGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBTZWxlY3RvclByb3ZpZGVyIHByb3ZpZGVyKCkgeworICAgICAgICByZXR1cm4gcHJvdmlkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBjaGFubmVsIGlzIHJlZ2lzdGVyZWQgd2l0aCBvbmUgb3IgbW9yZSBzZWxlY3RvcnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGNoYW5uZWwgaXMgcmVnaXN0ZXJlZCB3aXRoIGEgc2VsZWN0b3IsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBzeW5jaHJvbml6ZWQgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNSZWdpc3RlcmVkKCkgeworICAgICAgICByZXR1cm4gIWtleUxpc3QuaXNFbXB0eSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhpcyBjaGFubmVsJ3Mgc2VsZWN0aW9uIGtleSBmb3IgdGhlIHNwZWNpZmllZCBzZWxlY3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzZWxlY3RvcgorICAgICAqICAgICAgICAgICAgdGhlIHNlbGVjdG9yIHdpdGggd2hpY2ggdGhpcyBjaGFubmVsIGhhcyBiZWVuIHJlZ2lzdGVyZWQuCisgICAgICogQHJldHVybiB0aGUgc2VsZWN0aW9uIGtleSBmb3IgdGhlIGNoYW5uZWwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoaXMgY2hhbm5lbAorICAgICAqICAgICAgICAgaGFzIG5vdCBiZWVuIHJlZ2lzdGVyZWQgd2l0aCB7QGNvZGUgc2VsZWN0b3J9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHN5bmNocm9uaXplZCBwdWJsaWMgZmluYWwgU2VsZWN0aW9uS2V5IGtleUZvcihTZWxlY3RvciBzZWxlY3RvcikgeworICAgICAgICBmb3IgKFNlbGVjdGlvbktleSBrZXkgOiBrZXlMaXN0KSB7CisgICAgICAgICAgICBpZiAoa2V5ICE9IG51bGwgJiYga2V5LnNlbGVjdG9yKCkgPT0gc2VsZWN0b3IpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4ga2V5OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlZ2lzdGVycyB0aGlzIGNoYW5uZWwgd2l0aCB0aGUgc3BlY2lmaWVkIHNlbGVjdG9yIGZvciB0aGUgc3BlY2lmaWVkCisgICAgICogaW50ZXJlc3Qgc2V0LiBJZiB0aGUgY2hhbm5lbCBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQgd2l0aCB0aGUgc2VsZWN0b3IsIHRoZQorICAgICAqIHtAbGluayBTZWxlY3Rpb25LZXkgaW50ZXJlc3Qgc2V0fSBpcyB1cGRhdGVkIHRvIHtAY29kZSBpbnRlcmVzdFNldH0gYW5kCisgICAgICogdGhlIGNvcnJlc3BvbmRpbmcgc2VsZWN0aW9uIGtleSBpcyByZXR1cm5lZC4gSWYgdGhlIGNoYW5uZWwgaXMgbm90IHlldAorICAgICAqIHJlZ2lzdGVyZWQsIHRoaXMgbWV0aG9kIGNhbGxzIHRoZSB7QGNvZGUgcmVnaXN0ZXJ9IG1ldGhvZCBvZgorICAgICAqIHtAY29kZSBzZWxlY3Rvcn0gYW5kIGFkZHMgdGhlIHNlbGVjdGlvbiBrZXkgdG8gdGhpcyBjaGFubmVsJ3Mga2V5IHNldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzZWxlY3RvcgorICAgICAqICAgICAgICAgICAgdGhlIHNlbGVjdG9yIHdpdGggd2hpY2ggdG8gcmVnaXN0ZXIgdGhpcyBjaGFubmVsLgorICAgICAqIEBwYXJhbSBpbnRlcmVzdFNldAorICAgICAqICAgICAgICAgICAgdGhpcyBjaGFubmVsJ3Mge0BsaW5rIFNlbGVjdGlvbktleSBpbnRlcmVzdCBzZXR9LgorICAgICAqIEBwYXJhbSBhdHRhY2htZW50CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGF0dGFjaCwgY2FuIGJlIHtAY29kZSBudWxsfS4KKyAgICAgKiBAcmV0dXJuIHRoZSBzZWxlY3Rpb24ga2V5IGZvciB0aGlzIHJlZ2lzdHJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIENhbmNlbGxlZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyByZWdpc3RlcmVkIGJ1dCBpdHMga2V5IGhhcyBiZWVuIGNhbmNlbGVkLgorICAgICAqIEB0aHJvd3MgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW50ZXJlc3RTZXR9IGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBjaGFubmVsLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2hhbm5lbCBpcyBpbiBibG9ja2luZyBtb2RlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFNlbGVjdG9yRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaGFubmVsIGRvZXMgbm90IGhhdmUgdGhlIHNhbWUgcHJvdmlkZXIgYXMgdGhlIGdpdmVuCisgICAgICogICAgICAgICAgICAgc2VsZWN0b3IuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIFNlbGVjdGlvbktleSByZWdpc3RlcihTZWxlY3RvciBzZWxlY3RvciwgaW50IGludGVyZXN0U2V0LAorICAgICAgICAgICAgT2JqZWN0IGF0dGFjaG1lbnQpIHRocm93cyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc09wZW4oKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENsb3NlZENoYW5uZWxFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoISgoaW50ZXJlc3RTZXQgJiB+dmFsaWRPcHMoKSkgPT0gMCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHN5bmNocm9uaXplZCAoYmxvY2tpbmdMb2NrKSB7CisgICAgICAgICAgICBpZiAoaXNCbG9ja2luZykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIXNlbGVjdG9yLmlzT3BlbigpKSB7CisgICAgICAgICAgICAgICAgaWYgKGludGVyZXN0U2V0ID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gdGhyb3cgSVNFIGV4YWN0bHkgdG8ga2VlcCBjb25zaXN0ZW5jeQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFNlbGVjdG9yRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIHRocm93IE5QRSBleGFjdGx5IHRvIGtlZXAgY29uc2lzdGVuY3kKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFNlbGVjdGlvbktleSBrZXkgPSBrZXlGb3Ioc2VsZWN0b3IpOworICAgICAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAga2V5ID0gKChBYnN0cmFjdFNlbGVjdG9yKSBzZWxlY3RvcikucmVnaXN0ZXIodGhpcywgaW50ZXJlc3RTZXQsIGF0dGFjaG1lbnQpOworICAgICAgICAgICAgICAgIGtleUxpc3QuYWRkKGtleSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmICgha2V5LmlzVmFsaWQoKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2FuY2VsbGVkS2V5RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGtleS5pbnRlcmVzdE9wcyhpbnRlcmVzdFNldCk7CisgICAgICAgICAgICAgICAga2V5LmF0dGFjaChhdHRhY2htZW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBrZXk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbXBsZW1lbnRzIHRoZSBjaGFubmVsIGNsb3NpbmcgYmVoYXZpb3IuIENhbGxzCisgICAgICoge0Bjb2RlIGltcGxDbG9zZVNlbGVjdGFibGVDaGFubmVsKCl9IGZpcnN0LCB0aGVuIGxvb3BzIHRocm91Z2ggdGhlIGxpc3QKKyAgICAgKiBvZiBzZWxlY3Rpb24ga2V5cyBhbmQgY2FuY2VscyB0aGVtLCB3aGljaCB1bnJlZ2lzdGVycyB0aGlzIGNoYW5uZWwgZnJvbQorICAgICAqIGFsbCBzZWxlY3RvcnMgaXQgaXMgcmVnaXN0ZXJlZCB3aXRoLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnMgd2hpbGUgY2xvc2luZyB0aGUgY2hhbm5lbC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBzeW5jaHJvbml6ZWQgcHJvdGVjdGVkIGZpbmFsIHZvaWQgaW1wbENsb3NlQ2hhbm5lbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGltcGxDbG9zZVNlbGVjdGFibGVDaGFubmVsKCk7CisgICAgICAgIGZvciAoU2VsZWN0aW9uS2V5IGtleSA6IGtleUxpc3QpIHsKKyAgICAgICAgICAgIGlmIChrZXkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGtleS5jYW5jZWwoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEltcGxlbWVudHMgdGhlIGNsb3NpbmcgZnVuY3Rpb24gb2YgdGhlIFNlbGVjdGFibGVDaGFubmVsLiBUaGlzIG1ldGhvZCBpcworICAgICAqIGNhbGxlZCBmcm9tIHtAY29kZSBpbXBsQ2xvc2VDaGFubmVsKCl9LgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBleGNlcHRpb24gb2NjdXJzLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGltcGxDbG9zZVNlbGVjdGFibGVDaGFubmVsKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBjaGFubmVsIGlzIGluIGJsb2NraW5nIG1vZGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGNoYW5uZWwgaXMgYmxvY2tpbmcsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0Jsb2NraW5nKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGJsb2NraW5nTG9jaykgeworICAgICAgICAgICAgcmV0dXJuIGlzQmxvY2tpbmc7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBvYmplY3QgdXNlZCBmb3IgdGhlIHN5bmNocm9uaXphdGlvbiBvZiB7QGNvZGUgcmVnaXN0ZXJ9IGFuZAorICAgICAqIHtAY29kZSBjb25maWd1cmVCbG9ja2luZ30uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzeW5jaHJvbml6YXRpb24gb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBPYmplY3QgYmxvY2tpbmdMb2NrKCkgeworICAgICAgICByZXR1cm4gYmxvY2tpbmdMb2NrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGJsb2NraW5nIG1vZGUgb2YgdGhpcyBjaGFubmVsLiBBIGNhbGwgdG8gdGhpcyBtZXRob2QgYmxvY2tzIGlmCisgICAgICogb3RoZXIgY2FsbHMgdG8gdGhpcyBtZXRob2Qgb3IgdG8ge0Bjb2RlIHJlZ2lzdGVyfSBhcmUgZXhlY3V0aW5nLiBUaGUKKyAgICAgKiBhY3R1YWwgc2V0dGluZyBvZiB0aGUgbW9kZSBpcyBkb25lIGJ5IGNhbGxpbmcKKyAgICAgKiB7QGNvZGUgaW1wbENvbmZpZ3VyZUJsb2NraW5nKGJvb2xlYW4pfS4KKyAgICAgKgorICAgICAqIEBzZWUgamF2YS5uaW8uY2hhbm5lbHMuU2VsZWN0YWJsZUNoYW5uZWwjY29uZmlndXJlQmxvY2tpbmcoYm9vbGVhbikKKyAgICAgKiBAcGFyYW0gYmxvY2tpbmdNb2RlCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gZm9yIHNldHRpbmcgdGhpcyBjaGFubmVsJ3MgbW9kZSB0byBibG9ja2luZywKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBmYWxzZX0gdG8gc2V0IGl0IHRvIG5vbi1ibG9ja2luZy4KKyAgICAgKiBAcmV0dXJuIHRoaXMgY2hhbm5lbC4KKyAgICAgKiBAdGhyb3dzIENsb3NlZENoYW5uZWxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNoYW5uZWwgaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBibG9ja30gaXMge0Bjb2RlIHRydWV9IGFuZCB0aGlzIGNoYW5uZWwgaGFzIGJlZW4KKyAgICAgKiAgICAgICAgICAgICByZWdpc3RlcmVkIHdpdGggYXQgbGVhc3Qgb25lIHNlbGVjdG9yLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBTZWxlY3RhYmxlQ2hhbm5lbCBjb25maWd1cmVCbG9ja2luZyhib29sZWFuIGJsb2NraW5nTW9kZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc09wZW4oKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENsb3NlZENoYW5uZWxFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBzeW5jaHJvbml6ZWQgKGJsb2NraW5nTG9jaykgeworICAgICAgICAgICAgaWYgKGlzQmxvY2tpbmcgPT0gYmxvY2tpbmdNb2RlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYmxvY2tpbmdNb2RlICYmIGNvbnRhaW5zVmFsaWRLZXlzKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW1wbENvbmZpZ3VyZUJsb2NraW5nKGJsb2NraW5nTW9kZSk7CisgICAgICAgICAgICBpc0Jsb2NraW5nID0gYmxvY2tpbmdNb2RlOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEltcGxlbWVudHMgdGhlIGNvbmZpZ3VyYXRpb24gb2YgYmxvY2tpbmcvbm9uLWJsb2NraW5nIG1vZGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYmxvY2tpbmcgdHJ1ZSBmb3IgYmxvY2tpbmcsIGZhbHNlIGZvciBub24tYmxvY2tpbmcuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgaW1wbENvbmZpZ3VyZUJsb2NraW5nKGJvb2xlYW4gYmxvY2tpbmcpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qCisgICAgICogcGFja2FnZSBwcml2YXRlIGZvciBkZXJlZ2lzdGVyIG1ldGhvZCBpbiBBYnN0cmFjdFNlbGVjdG9yLgorICAgICAqLworICAgIHN5bmNocm9uaXplZCB2b2lkIGRlcmVnaXN0ZXIoU2VsZWN0aW9uS2V5IGspIHsKKyAgICAgICAgaWYgKGtleUxpc3QgIT0gbnVsbCkgeworICAgICAgICAgICAga2V5TGlzdC5yZW1vdmUoayk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGtleUxpc3QgY29udGFpbnMgYXQgbGVhc3QgMSB2YWxpZCBrZXkgYW5kIGZhbHNlCisgICAgICogb3RoZXJ3aXNlLgorICAgICAqLworICAgIHByaXZhdGUgc3luY2hyb25pemVkIGJvb2xlYW4gY29udGFpbnNWYWxpZEtleXMoKSB7CisgICAgICAgIGZvciAoU2VsZWN0aW9uS2V5IGtleSA6IGtleUxpc3QpIHsKKyAgICAgICAgICAgIGlmIChrZXkgIT0gbnVsbCAmJiBrZXkuaXNWYWxpZCgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9zcGkvQWJzdHJhY3RTZWxlY3Rpb25LZXkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9zcGkvQWJzdHJhY3RTZWxlY3Rpb25LZXkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZTc2NDEyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL3NwaS9BYnN0cmFjdFNlbGVjdGlvbktleS5qYXZhCkBAIC0wLDAgKzEsNjMgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhbm5lbHMuc3BpOworCitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU2VsZWN0aW9uS2V5OworCisvKioKKyAqIHtAY29kZSBBYnN0cmFjdFNlbGVjdGlvbktleX0gaXMgdGhlIGJhc2UgaW1wbGVtZW50YXRpb24gY2xhc3MgZm9yIHNlbGVjdGlvbiBrZXlzLgorICogSXQgaW1wbGVtZW50cyB2YWxpZGF0aW9uIGFuZCBjYW5jZWxsYXRpb24gbWV0aG9kcy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0U2VsZWN0aW9uS2V5IGV4dGVuZHMgU2VsZWN0aW9uS2V5IHsKKworICAgIC8qCisgICAgICogcGFja2FnZSBwcml2YXRlIGZvciBkZXJlZ2lzdGVyIG1ldGhvZCBpbiBBYnN0cmFjdFNlbGVjdG9yLgorICAgICAqLworICAgIGJvb2xlYW4gaXNWYWxpZCA9IHRydWU7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBBYnN0cmFjdFNlbGVjdGlvbktleX0uCisgICAgICovCisgICAgcHJvdGVjdGVkIEFic3RyYWN0U2VsZWN0aW9uS2V5KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMga2V5IGlzIHZhbGlkLiBBIGtleSBpcyB2YWxpZCBhcyBsb25nIGFzIGl0IGhhcyBub3QKKyAgICAgKiBiZWVuIGNhbmNlbGVkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBrZXkgaGFzIG5vdCBiZWVuIGNhbmNlbGVkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNWYWxpZCgpIHsKKyAgICAgICAgcmV0dXJuIGlzVmFsaWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FuY2VscyB0aGlzIGtleS4KKyAgICAgKiA8cD4KKyAgICAgKiBBIGtleSB0aGF0IGhhcyBiZWVuIGNhbmNlbGVkIGlzIG5vIGxvbmdlciB2YWxpZC4gQ2FsbGluZyB0aGlzIG1ldGhvZCBvbgorICAgICAqIGFuIGFscmVhZHkgY2FuY2VsZWQga2V5IGRvZXMgbm90aGluZy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBjYW5jZWwoKSB7CisgICAgICAgIGlmIChpc1ZhbGlkKSB7CisgICAgICAgICAgICBpc1ZhbGlkID0gZmFsc2U7CisgICAgICAgICAgICAoKEFic3RyYWN0U2VsZWN0b3IpIHNlbGVjdG9yKCkpLmNhbmNlbCh0aGlzKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9zcGkvQWJzdHJhY3RTZWxlY3Rvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL3NwaS9BYnN0cmFjdFNlbGVjdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmZkMWVjMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFubmVscy9zcGkvQWJzdHJhY3RTZWxlY3Rvci5qYXZhCkBAIC0wLDAgKzEsMTMxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYW5uZWxzLnNwaTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU2VsZWN0aW9uS2V5OworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlbGVjdG9yOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0Jvb2xlYW47CisKKy8qKgorICoge0Bjb2RlIEFic3RyYWN0U2VsZWN0b3J9IGlzIHRoZSBiYXNlIGltcGxlbWVudGF0aW9uIGNsYXNzIGZvciBzZWxlY3RvcnMuCisgKiBJdCByZWFsaXplcyB0aGUgaW50ZXJydXB0aW9uIG9mIHNlbGVjdGlvbiBieSB7QGNvZGUgYmVnaW59IGFuZAorICoge0Bjb2RlIGVuZH0uIEl0IGFsc28gaG9sZHMgdGhlIGNhbmNlbGxhdGlvbiBhbmQgdGhlIGRlbGV0aW9uIG9mIHRoZSBrZXkKKyAqIHNldC4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0U2VsZWN0b3IgZXh0ZW5kcyBTZWxlY3RvciB7CisgICAgcHJpdmF0ZSBmaW5hbCBBdG9taWNCb29sZWFuIGlzT3BlbiA9IG5ldyBBdG9taWNCb29sZWFuKHRydWUpOworCisgICAgcHJpdmF0ZSBTZWxlY3RvclByb3ZpZGVyIHByb3ZpZGVyID0gbnVsbDsKKworICAgIHByaXZhdGUgZmluYWwgU2V0PFNlbGVjdGlvbktleT4gY2FuY2VsbGVkS2V5c1NldCA9IG5ldyBIYXNoU2V0PFNlbGVjdGlvbktleT4oKTsKKworICAgIHByaXZhdGUgZmluYWwgUnVubmFibGUgd2FrZXVwUnVubmFibGUgPSBuZXcgUnVubmFibGUoKSB7CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICB3YWtldXAoKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBwcm90ZWN0ZWQgQWJzdHJhY3RTZWxlY3RvcihTZWxlY3RvclByb3ZpZGVyIHNlbGVjdG9yUHJvdmlkZXIpIHsKKyAgICAgICAgcHJvdmlkZXIgPSBzZWxlY3RvclByb3ZpZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGlzIHNlbGVjdG9yLiBUaGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcgaWYgdGhpcyBzZWxlY3RvciBpcworICAgICAqIGFscmVhZHkgY2xvc2VkLiBUaGUgYWN0dWFsIGNsb3NpbmcgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBzdWJjbGFzc2VzIGluCisgICAgICoge0Bjb2RlIGltcGxDbG9zZVNlbGVjdG9yKCl9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzT3Blbi5nZXRBbmRTZXQoZmFsc2UpKSB7CisgICAgICAgICAgICBpbXBsQ2xvc2VTZWxlY3RvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW1wbGVtZW50cyB0aGUgY2xvc2luZyBvZiB0aGlzIGNoYW5uZWwuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgaW1wbENsb3NlU2VsZWN0b3IoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBzZWxlY3RvciBpcyBvcGVuLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzT3BlbigpIHsKKyAgICAgICAgcmV0dXJuIGlzT3Blbi5nZXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgc2VsZWN0b3IncyBwcm92aWRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgU2VsZWN0b3JQcm92aWRlciBwcm92aWRlcigpIHsKKyAgICAgICAgcmV0dXJuIHByb3ZpZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBjaGFubmVsJ3Mgc2V0IG9mIGNhbmNlbGVkIHNlbGVjdGlvbiBrZXlzLgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBTZXQ8U2VsZWN0aW9uS2V5PiBjYW5jZWxsZWRLZXlzKCkgeworICAgICAgICByZXR1cm4gY2FuY2VsbGVkS2V5c1NldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWdpc3RlcnMge0Bjb2RlIGNoYW5uZWx9IHdpdGggdGhpcyBzZWxlY3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcGVyYXRpb25zIHRoZSB7QGxpbmsgU2VsZWN0aW9uS2V5IGludGVyZXN0IHNldH0gb2Yge0Bjb2RlCisgICAgICogICAgIGNoYW5uZWx9LgorICAgICAqIEBwYXJhbSBhdHRhY2htZW50IHRoZSBhdHRhY2htZW50IGZvciB0aGUgc2VsZWN0aW9uIGtleS4KKyAgICAgKiBAcmV0dXJuIHRoZSBrZXkgcmVsYXRlZCB0byB0aGUgY2hhbm5lbCBhbmQgdGhpcyBzZWxlY3Rvci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgU2VsZWN0aW9uS2V5IHJlZ2lzdGVyKEFic3RyYWN0U2VsZWN0YWJsZUNoYW5uZWwgY2hhbm5lbCwKKyAgICAgICAgICAgIGludCBvcGVyYXRpb25zLCBPYmplY3QgYXR0YWNobWVudCk7CisKKyAgICAvKioKKyAgICAgKiBEZWxldGVzIHRoZSBrZXkgZnJvbSB0aGUgY2hhbm5lbCdzIGtleSBzZXQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgZGVyZWdpc3RlcihBYnN0cmFjdFNlbGVjdGlvbktleSBrZXkpIHsKKyAgICAgICAgKChBYnN0cmFjdFNlbGVjdGFibGVDaGFubmVsKSBrZXkuY2hhbm5lbCgpKS5kZXJlZ2lzdGVyKGtleSk7CisgICAgICAgIGtleS5pc1ZhbGlkID0gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoZSBiZWdpbm5pbmcgb2YgYSBjb2RlIHNlY3Rpb24gdGhhdCBpbmNsdWRlcyBhbiBJL08gb3BlcmF0aW9uCisgICAgICogdGhhdCBpcyBwb3RlbnRpYWxseSBibG9ja2luZy4gQWZ0ZXIgdGhpcyBvcGVyYXRpb24sIHRoZSBhcHBsaWNhdGlvbgorICAgICAqIHNob3VsZCBpbnZva2UgdGhlIGNvcnJlc3BvbmRpbmcge0Bjb2RlIGVuZChib29sZWFuKX0gbWV0aG9kLgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGJlZ2luKCkgeworICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLnB1c2hJbnRlcnJ1cHRBY3Rpb24kKHdha2V1cFJ1bm5hYmxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhlIGVuZCBvZiBhIGNvZGUgc2VjdGlvbiB0aGF0IGhhcyBiZWVuIHN0YXJ0ZWQgd2l0aAorICAgICAqIHtAY29kZSBiZWdpbigpfSBhbmQgdGhhdCBpbmNsdWRlcyBhIHBvdGVudGlhbGx5IGJsb2NraW5nIEkvTyBvcGVyYXRpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgZW5kKCkgeworICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLnBvcEludGVycnVwdEFjdGlvbiQod2FrZXVwUnVubmFibGUpOworICAgIH0KKworICAgIHZvaWQgY2FuY2VsKFNlbGVjdGlvbktleSBrZXkpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChjYW5jZWxsZWRLZXlzU2V0KSB7CisgICAgICAgICAgICBjYW5jZWxsZWRLZXlzU2V0LmFkZChrZXkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL3NwaS9TZWxlY3RvclByb3ZpZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhbm5lbHMvc3BpL1NlbGVjdG9yUHJvdmlkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YzIwNDE0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYW5uZWxzL3NwaS9TZWxlY3RvclByb3ZpZGVyLmphdmEKQEAgLTAsMCArMSwxNDQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhbm5lbHMuc3BpOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5TZWxlY3RvclByb3ZpZGVySW1wbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5DaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkRhdGFncmFtQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5QaXBlOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlcnZlclNvY2tldENoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU29ja2V0Q2hhbm5lbDsKK2ltcG9ydCBqYXZhLnV0aWwuU2VydmljZUxvYWRlcjsKKworLyoqCisgKiB7QGNvZGUgU2VsZWN0b3JQcm92aWRlcn0gaXMgYW4gYWJzdHJhY3QgYmFzZSBjbGFzcyB0aGF0IGRlY2xhcmVzIG1ldGhvZHMgZm9yCisgKiBwcm92aWRpbmcgaW5zdGFuY2VzIG9mIHtAbGluayBEYXRhZ3JhbUNoYW5uZWx9LCB7QGxpbmsgUGlwZX0sCisgKiB7QGxpbmsgamF2YS5uaW8uY2hhbm5lbHMuU2VsZWN0b3J9ICwge0BsaW5rIFNlcnZlclNvY2tldENoYW5uZWx9LCBhbmQKKyAqIHtAbGluayBTb2NrZXRDaGFubmVsfS4gQWxsIHRoZSBtZXRob2RzIG9mIHRoaXMgY2xhc3MgYXJlIHRocmVhZC1zYWZlLgorICoKKyAqIDxwPkEgcHJvdmlkZXIgaW5zdGFuY2UgY2FuIGJlIHJldHJpZXZlZCB0aHJvdWdoIGEgc3lzdGVtIHByb3BlcnR5IG9yIHRoZQorICogY29uZmlndXJhdGlvbiBmaWxlIGluIGEgamFyIGZpbGU7IGlmIG5vIHByb3ZpZGVyIGlzIGF2YWlsYWJsZSB0aGF0IHdheSB0aGVuCisgKiB0aGUgc3lzdGVtIGRlZmF1bHQgcHJvdmlkZXIgaXMgcmV0dXJuZWQuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTZWxlY3RvclByb3ZpZGVyIHsKKworICAgIHByaXZhdGUgc3RhdGljIFNlbGVjdG9yUHJvdmlkZXIgcHJvdmlkZXIgPSBudWxsOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgU2VsZWN0b3JQcm92aWRlcn0uCisgICAgICovCisgICAgcHJvdGVjdGVkIFNlbGVjdG9yUHJvdmlkZXIoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIHByb3ZpZGVyIGluc3RhbmNlIGJ5IGV4ZWN1dGluZyB0aGUgZm9sbG93aW5nIHN0ZXBzIHdoZW4gY2FsbGVkIGZvcgorICAgICAqIHRoZSBmaXJzdCB0aW1lOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+IGlmIHRoZSBzeXN0ZW0gcHJvcGVydHkgImphdmEubmlvLmNoYW5uZWxzLnNwaS5TZWxlY3RvclByb3ZpZGVyIiBpcworICAgICAqIHNldCwgdGhlIHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgaXMgdGhlIGNsYXNzIG5hbWUgb2YgdGhlIHByb3ZpZGVyCisgICAgICogcmV0dXJuZWQ7IDwvbGk+CisgICAgICogPGxpPmlmIHRoZXJlIGlzIGEgcHJvdmlkZXItY29uZmlndXJhdGlvbiBmaWxlIG5hbWVkCisgICAgICogImphdmEubmlvLmNoYW5uZWxzLnNwaS5TZWxlY3RvclByb3ZpZGVyIiBpbiBNRVRBLUlORi9zZXJ2aWNlcyBvZiBhIGphcgorICAgICAqIGZpbGUgdmFsaWQgaW4gdGhlIHN5c3RlbSBjbGFzcyBsb2FkZXIsIHRoZSBmaXJzdCBjbGFzcyBuYW1lIGlzIHRoZQorICAgICAqIHByb3ZpZGVyJ3MgY2xhc3MgbmFtZTsgPC9saT4KKyAgICAgKiA8bGk+IG90aGVyd2lzZSwgYSBzeXN0ZW0gZGVmYXVsdCBwcm92aWRlciB3aWxsIGJlIHJldHVybmVkLjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByb3ZpZGVyLgorICAgICAqLworICAgIHN5bmNocm9uaXplZCBwdWJsaWMgc3RhdGljIFNlbGVjdG9yUHJvdmlkZXIgcHJvdmlkZXIoKSB7CisgICAgICAgIGlmIChwcm92aWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICBwcm92aWRlciA9IFNlcnZpY2VMb2FkZXIubG9hZEZyb21TeXN0ZW1Qcm9wZXJ0eShTZWxlY3RvclByb3ZpZGVyLmNsYXNzKTsKKyAgICAgICAgICAgIGlmIChwcm92aWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcHJvdmlkZXIgPSBsb2FkUHJvdmlkZXJCeUphcigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBwcm92aWRlciA9IG5ldyBTZWxlY3RvclByb3ZpZGVySW1wbCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBwcm92aWRlcjsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTZWxlY3RvclByb3ZpZGVyIGxvYWRQcm92aWRlckJ5SmFyKCkgeworICAgICAgICBmb3IgKFNlbGVjdG9yUHJvdmlkZXIgcHJvdmlkZXIgOiBTZXJ2aWNlTG9hZGVyLmxvYWQoU2VsZWN0b3JQcm92aWRlci5jbGFzcykpIHsKKyAgICAgICAgICAgIHJldHVybiBwcm92aWRlcjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IG9wZW4ge0Bjb2RlIERhdGFncmFtQ2hhbm5lbH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgY2hhbm5lbC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRGF0YWdyYW1DaGFubmVsIG9wZW5EYXRhZ3JhbUNoYW5uZWwoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBQaXBlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5ldyBwaXBlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBQaXBlIG9wZW5QaXBlKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBzZWxlY3Rvci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5ldyBzZWxlY3Rvci4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQWJzdHJhY3RTZWxlY3RvciBvcGVuU2VsZWN0b3IoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IG9wZW4ge0Bjb2RlIFNlcnZlclNvY2tldENoYW5uZWx9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV3IGNoYW5uZWwuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFNlcnZlclNvY2tldENoYW5uZWwgb3BlblNlcnZlclNvY2tldENoYW5uZWwoKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IG9wZW4ge0Bjb2RlIFNvY2tldENoYW5uZWx9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV3IGNoYW5uZWwuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFNvY2tldENoYW5uZWwgb3BlblNvY2tldENoYW5uZWwoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjaGFubmVsIGluaGVyaXRlZCBmcm9tIHRoZSBwcm9jZXNzIHRoYXQgY3JlYXRlZCB0aGlzIFZNLgorICAgICAqIE9uIEFuZHJvaWQsIHRoaXMgbWV0aG9kIGFsd2F5cyByZXR1cm5zIG51bGwgYmVjYXVzZSBzdGRpbiBhbmQgc3Rkb3V0IGFyZQorICAgICAqIG5ldmVyIGNvbm5lY3RlZCB0byBhIHNvY2tldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNoYW5uZWwuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIENoYW5uZWwgaW5oZXJpdGVkQ2hhbm5lbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIEFuZHJvaWQgbmV2ZXIgaGFzIHN0ZGluL3N0ZG91dCBjb25uZWN0ZWQgdG8gYSBzb2NrZXQuCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L0NoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGQ0YTEzOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L0NoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhcnNldDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogQSB7QGNvZGUgQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9ufSBpcyB0aHJvd24gd2hlbiBhbiBlbmNvZGluZyBvciBkZWNvZGluZworICogZXJyb3Igb2NjdXJzLgorICovCitwdWJsaWMgY2xhc3MgQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworCisgICAgLyoKKyAgICAgKiBUaGlzIGNvbnN0YW50IGlzIHVzZWQgZHVyaW5nIGRlc2VyaWFsaXphdGlvbiB0byBjaGVjayB0aGUgdmVyc2lvbgorICAgICAqIHdoaWNoIGNyZWF0ZWQgdGhlIHNlcmlhbGl6ZWQgb2JqZWN0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDg0MjE1MzIyMzIxNTQ2Mjc3ODNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L0NoYXJzZXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L0NoYXJzZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MDBhYThiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldC5qYXZhCkBAIC0wLDAgKzEsNTc0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYXJzZXQ7CisKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5DaGFyQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuc3BpLkNoYXJzZXRQcm92aWRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLlNlcnZpY2VMb2FkZXI7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOworaW1wb3J0IGxpYmNvcmUuaWN1Lk5hdGl2ZUNvbnZlcnRlcjsKKworLyoqCisgKiBBIGNoYXJzZXQgaXMgYSBuYW1lZCBtYXBwaW5nIGJldHdlZW4gVW5pY29kZSBjaGFyYWN0ZXJzIGFuZCBieXRlIHNlcXVlbmNlcy4gRXZlcnkKKyAqIHtAY29kZSBDaGFyc2V0fSBjYW4gPGk+ZGVjb2RlPC9pPiwgY29udmVydGluZyBhIGJ5dGUgc2VxdWVuY2UgaW50byBhIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMsCisgKiBhbmQgc29tZSBjYW4gYWxzbyA8aT5lbmNvZGU8L2k+LCBjb252ZXJ0aW5nIGEgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyBpbnRvIGEgYnl0ZSBzZXF1ZW5jZS4KKyAqIFVzZSB0aGUgbWV0aG9kIHtAbGluayAjY2FuRW5jb2RlfSB0byBmaW5kIG91dCB3aGV0aGVyIGEgY2hhcnNldCBzdXBwb3J0cyBib3RoLgorICoKKyAqIDxoND5DaGFyYWN0ZXJzPC9oND4KKyAqIDxwPkluIHRoZSBjb250ZXh0IG9mIHRoaXMgY2xhc3MsIDxpPmNoYXJhY3RlcjwvaT4gYWx3YXlzIHJlZmVycyB0byBhIEphdmEgY2hhcmFjdGVyOiBhIFVuaWNvZGUKKyAqIGNvZGUgcG9pbnQgaW4gdGhlIHJhbmdlIFUrMDAwMCB0byBVK0ZGRkYuIChKYXZhIHJlcHJlc2VudHMgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIHVzaW5nIHN1cnJvZ2F0ZXMuKQorICogTm90IGFsbCBieXRlIHNlcXVlbmNlcyB3aWxsIHJlcHJlc2VudCBhIGNoYXJhY3RlciwgYW5kIG5vdAorICogYWxsIGNoYXJhY3RlcnMgY2FuIG5lY2Vzc2FyaWx5IGJlIHJlcHJlc2VudGVkIGJ5IGEgZ2l2ZW4gY2hhcnNldC4gVGhlIG1ldGhvZCB7QGxpbmsgI2NvbnRhaW5zfQorICogY2FuIGJlIHVzZWQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgZXZlcnkgY2hhcmFjdGVyIHJlcHJlc2VudGFibGUgYnkgb25lIGNoYXJzZXQgY2FuIGFsc28gYmUKKyAqIHJlcHJlc2VudGVkIGJ5IGFub3RoZXIgKG1lYW5pbmcgdGhhdCBhIGxvc3NsZXNzIHRyYW5zZm9ybWF0aW9uIGlzIHBvc3NpYmxlIGZyb20gdGhlIGNvbnRhaW5lZAorICogdG8gdGhlIGNvbnRhaW5lcikuCisgKgorICogPGg0PkVuY29kaW5nczwvaDQ+CisgKiA8cD5UaGVyZSBhcmUgbWFueSBwb3NzaWJsZSB3YXlzIHRvIHJlcHJlc2VudCBVbmljb2RlIGNoYXJhY3RlcnMgYXMgYnl0ZSBzZXF1ZW5jZXMuCisgKiBTZWUgPGEgaHJlZj0iaHR0cDovL3d3dy51bmljb2RlLm9yZy9yZXBvcnRzL3RyMTcvIj5VVFIjMTc6IFVuaWNvZGUgQ2hhcmFjdGVyIEVuY29kaW5nIE1vZGVsPC9hPgorICogZm9yIGRldGFpbGVkIGRpc2N1c3Npb24uCisgKgorICogPHA+VGhlIG1vc3QgaW1wb3J0YW50IG1hcHBpbmdzIGNhcGFibGUgb2YgcmVwcmVzZW50aW5nIGV2ZXJ5IGNoYXJhY3RlciBhcmUgdGhlIFVuaWNvZGUKKyAqIFRyYW5zZm9ybWF0aW9uIEZvcm1hdCAoVVRGKSBjaGFyc2V0cy4gT2YgdGhvc2UsIFVURi04IGFuZCB0aGUgVVRGLTE2IGZhbWlseSBhcmUgdGhlIG1vc3QKKyAqIGNvbW1vbi4gVVRGLTggKGRlc2NyaWJlZCBpbiA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzNjI5LnR4dCI+UkZDIDM2Mjk8L2E+KQorICogZW5jb2RlcyBhIGNoYXJhY3RlciB1c2luZyAxIHRvIDQgYnl0ZXMuIFVURi0xNiB1c2VzIGV4YWN0bHkgMiBieXRlcyBwZXIgY2hhcmFjdGVyIChwb3RlbnRpYWxseQorICogd2FzdGluZyBzcGFjZSwgYnV0IGFsbG93aW5nIGVmZmljaWVudCByYW5kb20gYWNjZXNzIGludG8gQk1QIHRleHQpLCBhbmQgVVRGLTMyIHVzZXMKKyAqIGV4YWN0bHkgNCBieXRlcyBwZXIgY2hhcmFjdGVyICh0cmFkaW5nIG9mZiBldmVuIG1vcmUgc3BhY2UgZm9yIGVmZmljaWVudCByYW5kb20gYWNjZXNzIGludG8gdGV4dAorICogdGhhdCBpbmNsdWRlcyBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcnMpLgorICoKKyAqIDxwPlVURi0xNiBhbmQgVVRGLTMyIGVuY29kZSBjaGFyYWN0ZXJzIGRpcmVjdGx5LCB1c2luZyB0aGVpciBjb2RlIHBvaW50IGFzIGEgdHdvLSBvciBmb3VyLWJ5dGUKKyAqIGludGVnZXIuIFRoaXMgbWVhbnMgdGhhdCBhbnkgZ2l2ZW4gVVRGLTE2IG9yIFVURi0zMiBieXRlIHNlcXVlbmNlIGlzIGVpdGhlciBiaWctIG9yCisgKiBsaXR0bGUtZW5kaWFuLiBUbyBhc3Npc3QgZGVjb2RlcnMsIFVuaWNvZGUgaW5jbHVkZXMgYSBzcGVjaWFsIDxpPmJ5dGUgb3JkZXIgbWFyazwvaT4gKEJPTSkKKyAqIGNoYXJhY3RlciBVK0ZFRkYgdXNlZCB0byBkZXRlcm1pbmUgdGhlIGVuZGlhbm5lc3Mgb2YgYSBzZXF1ZW5jZS4gVGhlIGNvcnJlc3BvbmRpbmcgYnl0ZS1zd2FwcGVkCisgKiBjb2RlIHBvaW50IFUrRkZGRSBpcyBndWFyYW50ZWVkIG5ldmVyIHRvIGJlIGFzc2lnbmVkLiBJZiBhIFVURi0xNiBkZWNvZGVyIHNlZXMKKyAqIHtAY29kZSAweGZlLCAweGZmfSwgZm9yIGV4YW1wbGUsIGl0IGtub3dzIGl0J3MgcmVhZGluZyBhIGJpZy1lbmRpYW4gYnl0ZSBzZXF1ZW5jZSwgd2hpbGUKKyAqIHtAY29kZSAweGZmLCAweGZlfSwgd291bGQgaW5kaWNhdGUgYSBsaXR0bGUtZW5kaWFuIGJ5dGUgc2VxdWVuY2UuCisgKgorICogPHA+VVRGLTggY2FuIGNvbnRhaW4gYSBCT00sIGJ1dCBzaW5jZSB0aGUgVVRGLTggZW5jb2Rpbmcgb2YgYSBjaGFyYWN0ZXIgYWx3YXlzIHVzZXMgdGhlIHNhbWUKKyAqIGJ5dGUgc2VxdWVuY2UsIHRoZXJlIGlzIG5vIGluZm9ybWF0aW9uIGFib3V0IGVuZGlhbm5lc3MgdG8gY29udmV5LiBTZWVpbmcgdGhlIGJ5dGVzCisgKiBjb3JyZXNwb25kaW5nIHRvIHRoZSBVVEYtOCBlbmNvZGluZyBvZiBVK0ZFRkYgKHtAY29kZSAweGVmLCAweGJiLCAweGJmfSkgd291bGQgb25seSBzZXJ2ZSB0bworICogc3VnZ2VzdCB0aGF0IHlvdSdyZSByZWFkaW5nIFVURi04LiBOb3RlIHRoYXQgQk9NcyBhcmUgZGVjb2RlZCBhcyB0aGUgVStGRUZGIGNoYXJhY3RlciwgYW5kCisgKiB3aWxsIGFwcGVhciBpbiB0aGUgb3V0cHV0IGNoYXJhY3RlciBzZXF1ZW5jZS4gVGhpcyBtZWFucyB0aGF0IGEgZGlzYWR2YW50YWdlIHRvIGluY2x1ZGluZyBhIEJPTQorICogaW4gVVRGLTggaXMgdGhhdCBtb3N0IGFwcGxpY2F0aW9ucyB0aGF0IHVzZSBVVEYtOCBkbyBub3QgZXhwZWN0IHRvIHNlZSBhIEJPTS4gKFRoaXMgaXMgYWxzbyBhCisgKiByZWFzb24gdG8gcHJlZmVyIFVURi04OiBpdCdzIG9uZSBsZXNzIGNvbXBsaWNhdGlvbiB0byB3b3JyeSBhYm91dC4pCisgKgorICogPHA+QmVjYXVzZSBhIEJPTSBpbmRpY2F0ZXMgaG93IHRoZSBkYXRhIHRoYXQgZm9sbG93cyBzaG91bGQgYmUgaW50ZXJwcmV0ZWQsIGEgQk9NIHNob3VsZCBvY2N1cgorICogYXMgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiBhIGNoYXJhY3RlciBzZXF1ZW5jZS4KKyAqCisgKiA8cD5TZWUgdGhlIDxhIGhyZWY9Imh0dHA6Ly91bmljb2RlLm9yZy9mYXEvdXRmX2JvbS5odG1sI0JPTSI+Qnl0ZSBPcmRlciBNYXJrIChCT00pIEZBUTwvYT4gZm9yCisgKiBtb3JlIGFib3V0IGRlYWxpbmcgd2l0aCBCT01zLgorICoKKyAqIDxoND5FbmRpYW5uZXNzIGFuZCBCT00gYmVoYXZpb3I8L2g0PgorICoKKyAqIDxwPlRoZSBmb2xsb3dpbmcgdGFibGVzIHNob3cgdGhlIGVuZGlhbm5lc3MgYW5kIEJPTSBiZWhhdmlvciBvZiB0aGUgVVRGLTE2IHZhcmlhbnRzLgorICoKKyAqIDxwPlRoaXMgdGFibGUgc2hvd3Mgd2hhdCB0aGUgZW5jb2RlciB3cml0ZXMuICJCRSIgbWVhbnMgdGhhdCB0aGUgYnl0ZSBzZXF1ZW5jZSBpcyBiaWctZW5kaWFuLAorICogIkxFIiBtZWFucyBsaXR0bGUtZW5kaWFuLiAiQkUgQk9NIiBtZWFucyBhIGJpZy1lbmRpYW4gQk9NICh0aGF0IGlzLCB7QGNvZGUgMHhmZSwgMHhmZn0pLgorICogPHA+PHRhYmxlIHdpZHRoPSIxMDAlIj4KKyAqIDx0cj4gPHRoPkNoYXJzZXQ8L3RoPiAgPHRoPkVuY29kZXIgd3JpdGVzPC90aD4gIDwvdHI+CisgKiA8dHI+IDx0ZD5VVEYtMTZCRTwvdGQ+IDx0ZD5CRSwgbm8gQk9NPC90ZD4gICAgICA8L3RyPgorICogPHRyPiA8dGQ+VVRGLTE2TEU8L3RkPiA8dGQ+TEUsIG5vIEJPTTwvdGQ+ICAgICAgPC90cj4KKyAqIDx0cj4gPHRkPlVURi0xNjwvdGQ+ICAgPHRkPkJFLCB3aXRoIEJFIEJPTTwvdGQ+IDwvdHI+CisgKiA8L3RhYmxlPgorICoKKyAqIDxwPlRoZSBuZXh0IHRhYmxlIHNob3dzIGhvdyBlYWNoIHZhcmlhbnQncyBkZWNvZGVyIGJlaGF2ZXMgd2hlbiByZWFkaW5nIGEgYnl0ZSBzZXF1ZW5jZS4KKyAqIFRoZSBleGFjdCBtZWFuaW5nIG9mICJmYWlsdXJlIiBpbiB0aGUgdGFibGUgaXMgZGVwZW5kZW50IG9uIHRoZQorICoge0BsaW5rIENvZGluZ0Vycm9yQWN0aW9ufSBzdXBwbGllZCB0byB7QGxpbmsgQ2hhcnNldERlY29kZXIjbWFsZm9ybWVkSW5wdXRBY3Rpb259LCBzbworICogIkJFLCBmYWlsdXJlIiBtZWFucyAidGhlIGJ5dGUgc2VxdWVuY2UgaXMgdHJlYXRlZCBhcyBiaWctZW5kaWFuLCBhbmQgYSBsaXR0bGUtZW5kaWFuIEJPTQorICogdHJpZ2dlcnMgdGhlIG1hbGZvcm1lZElucHV0QWN0aW9uIi4KKyAqCisgKiA8cD5UaGUgcGhyYXNlICJpbmNsdWRlcyBCT00iIG1lYW5zIHRoYXQgdGhlIG91dHB1dCBpbmNsdWRlcyB0aGUgVStGRUZGIGJ5dGUgb3JkZXIgbWFyayBjaGFyYWN0ZXIuCisgKgorICogPHA+PHRhYmxlIHdpZHRoPSIxMDAlIj4KKyAqIDx0cj4gPHRoPkNoYXJzZXQ8L3RoPiAgPHRoPkJFIEJPTTwvdGg+ICAgICAgICAgICA8dGg+TEUgQk9NPC90aD4gICAgICAgICAgIDx0aD5ObyBCT008L3RoPiA8L3RyPgorICogPHRyPiA8dGQ+VVRGLTE2QkU8L3RkPiA8dGQ+QkUsIGluY2x1ZGVzIEJPTTwvdGQ+IDx0ZD5CRSwgZmFpbHVyZTwvdGQ+ICAgICAgPHRkPkJFPC90ZD4gICAgIDwvdHI+CisgKiA8dHI+IDx0ZD5VVEYtMTZMRTwvdGQ+IDx0ZD5MRSwgZmFpbHVyZTwvdGQ+ICAgICAgPHRkPkxFLCBpbmNsdWRlcyBCT008L3RkPiA8dGQ+TEU8L3RkPiAgICAgPC90cj4KKyAqIDx0cj4gPHRkPlVURi0xNjwvdGQ+ICAgPHRkPkJFPC90ZD4gICAgICAgICAgICAgICA8dGQ+TEU8L3RkPiAgICAgICAgICAgICAgIDx0ZD5CRTwvdGQ+ICAgICA8L3RyPgorICogPC90YWJsZT4KKyAqCisgKiA8aDQ+Q2hhcnNldCBuYW1lczwvaDQ+CisgKiA8cD5BIGNoYXJzZXQgaGFzIGEgY2Fub25pY2FsIG5hbWUsIHJldHVybmVkIGJ5IHtAbGluayAjbmFtZX0uIE1vc3QgY2hhcnNldHMgd2lsbAorICogYWxzbyBoYXZlIG9uZSBvciBtb3JlIGFsaWFzZXMsIHJldHVybmVkIGJ5IHtAbGluayAjYWxpYXNlc30uIEEgY2hhcnNldCBjYW4gYmUgbG9va2VkIHVwCisgKiBieSBjYW5vbmljYWwgbmFtZSBvciBhbnkgb2YgaXRzIGFsaWFzZXMgdXNpbmcge0BsaW5rICNmb3JOYW1lfS4KKyAqCisgKiA8aDQ+R3VhcmFudGVlZC1hdmFpbGFibGUgY2hhcnNldHM8L2g0PgorICogPHA+VGhlIGZvbGxvd2luZyBjaGFyc2V0cyBhcmUgYXZhaWxhYmxlIG9uIGV2ZXJ5IEphdmEgaW1wbGVtZW50YXRpb246CisgKiA8dWw+CisgKiA8bGk+SVNPLTg4NTktMQorICogPGxpPlVTLUFTQ0lJCisgKiA8bGk+VVRGLTE2CisgKiA8bGk+VVRGLTE2QkUKKyAqIDxsaT5VVEYtMTZMRQorICogPGxpPlVURi04CisgKiA8L3VsPgorICogPHA+QWxsIG9mIHRoZXNlIGNoYXJzZXRzIHN1cHBvcnQgYm90aCBkZWNvZGluZyBhbmQgZW5jb2RpbmcuIFRoZSBjaGFyc2V0cyB3aG9zZSBuYW1lcyBiZWdpbgorICogIlVURiIgY2FuIHJlcHJlc2VudCBhbGwgY2hhcmFjdGVycywgYXMgbWVudGlvbmVkIGFib3ZlLiBUaGUgIklTTy04ODU5LTEiIGFuZCAiVVMtQVNDSUkiIGNoYXJzZXRzCisgKiBjYW4gb25seSByZXByZXNlbnQgc21hbGwgc3Vic2V0cyBvZiB0aGVzZSBjaGFyYWN0ZXJzLiBFeGNlcHQgd2hlbiByZXF1aXJlZCB0byBkbyBvdGhlcndpc2UgZm9yCisgKiBjb21wYXRpYmlsaXR5LCBuZXcgY29kZSBzaG91bGQgdXNlIG9uZSBvZiB0aGUgVVRGIGNoYXJzZXRzIGxpc3RlZCBhYm92ZS4gVGhlIHBsYXRmb3JtJ3MgZGVmYXVsdAorICogY2hhcnNldCBpcyBVVEYtOC4gKFRoaXMgaXMgaW4gY29udHJhc3QgdG8gc29tZSBvbGRlciBpbXBsZW1lbnRhdGlvbnMsIHdoZXJlIHRoZSBkZWZhdWx0IGNoYXJzZXQKKyAqIGRlcGVuZGVkIG9uIHRoZSB1c2VyJ3MgbG9jYWxlLikKKyAqCisgKiA8cD5Nb3N0IGltcGxlbWVudGF0aW9ucyB3aWxsIHN1cHBvcnQgaHVuZHJlZHMgb2YgY2hhcnNldHMuIFVzZSB7QGxpbmsgI2F2YWlsYWJsZUNoYXJzZXRzfSBvcgorICoge0BsaW5rICNpc1N1cHBvcnRlZH0gdG8gc2VlIHdoYXQncyBhdmFpbGFibGUuIElmIHlvdSBpbnRlbmQgdG8gdXNlIHRoZSBjaGFyc2V0IGlmIGl0J3MKKyAqIGF2YWlsYWJsZSwganVzdCBjYWxsIHtAbGluayAjZm9yTmFtZX0gYW5kIGNhdGNoIHRoZSBleGNlcHRpb25zIGl0IHRocm93cyBpZiB0aGUgY2hhcnNldCBpc24ndAorICogYXZhaWxhYmxlLgorICoKKyAqIDxwPkFkZGl0aW9uYWwgY2hhcnNldHMgY2FuIGJlIG1hZGUgYXZhaWxhYmxlIGJ5IGNvbmZpZ3VyaW5nIG9uZSBvciBtb3JlIGNoYXJzZXQKKyAqIHByb3ZpZGVycyB0aHJvdWdoIHByb3ZpZGVyIGNvbmZpZ3VyYXRpb24gZmlsZXMuIFN1Y2ggZmlsZXMgYXJlIGFsd2F5cyBuYW1lZAorICogYXMgImphdmEubmlvLmNoYXJzZXQuc3BpLkNoYXJzZXRQcm92aWRlciIgYW5kIGxvY2F0ZWQgaW4gdGhlCisgKiAiTUVUQS1JTkYvc2VydmljZXMiIGRpcmVjdG9yeSBvZiBvbmUgb3IgbW9yZSBjbGFzc3BhdGhzLiBUaGUgZmlsZXMgc2hvdWxkIGJlCisgKiBlbmNvZGVkIGluICJVVEYtOCIuIEVhY2ggbGluZSBvZiB0aGVpciBjb250ZW50IHNwZWNpZmllcyB0aGUgY2xhc3MgbmFtZSBvZiBhCisgKiBjaGFyc2V0IHByb3ZpZGVyIHdoaWNoIGV4dGVuZHMge0BsaW5rIGphdmEubmlvLmNoYXJzZXQuc3BpLkNoYXJzZXRQcm92aWRlcn0uCisgKiBBIGxpbmUgc2hvdWxkIGVuZCB3aXRoICdccicsICdcbicgb3IgJ1xyXG4nLiBMZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlCisgKiBpcyB0cmltbWVkLiBCbGFuayBsaW5lcywgYW5kIGxpbmVzIChhZnRlciB0cmltbWluZykgc3RhcnRpbmcgd2l0aCAiIyIgd2hpY2ggYXJlCisgKiByZWdhcmRlZCBhcyBjb21tZW50cywgYXJlIGJvdGggaWdub3JlZC4gRHVwbGljYXRlcyBvZiBuYW1lcyBhbHJlYWR5IGZvdW5kIGFyZSBhbHNvCisgKiBpZ25vcmVkLiBCb3RoIHRoZSBjb25maWd1cmF0aW9uIGZpbGVzIGFuZCB0aGUgcHJvdmlkZXIgY2xhc3NlcyB3aWxsIGJlIGxvYWRlZAorICogdXNpbmcgdGhlIHRocmVhZCBjb250ZXh0IGNsYXNzIGxvYWRlci4KKyAqCisgKiA8cD5BbHRob3VnaCBjbGFzcyBpcyB0aHJlYWQtc2FmZSwgdGhlIHtAbGluayBDaGFyc2V0RGVjb2Rlcn0gYW5kIHtAbGluayBDaGFyc2V0RW5jb2Rlcn0gaW5zdGFuY2VzCisgKiBpdCByZXR1cm5zIGFyZSBpbmhlcmVudGx5IHN0YXRlZnVsLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ2hhcnNldCBpbXBsZW1lbnRzIENvbXBhcmFibGU8Q2hhcnNldD4geworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEhhc2hNYXA8U3RyaW5nLCBDaGFyc2V0PiBDQUNIRURfQ0hBUlNFVFMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIENoYXJzZXQ+KCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDaGFyc2V0IERFRkFVTFRfQ0hBUlNFVCA9IGdldERlZmF1bHRDaGFyc2V0KCk7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBjYW5vbmljYWxOYW1lOworCisgICAgcHJpdmF0ZSBmaW5hbCBIYXNoU2V0PFN0cmluZz4gYWxpYXNlc1NldDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSA8Y29kZT5DaGFyc2V0PC9jb2RlPiBvYmplY3QuIER1cGxpY2F0ZWQgYWxpYXNlcyBhcmUKKyAgICAgKiBpZ25vcmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGNhbm9uaWNhbE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYW5vbmljYWwgbmFtZSBvZiB0aGUgY2hhcnNldC4KKyAgICAgKiBAcGFyYW0gYWxpYXNlcworICAgICAqICAgICAgICAgICAgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgYWxpYXNlcyBvZiB0aGUgY2hhcnNldC4gTWF5IGJlIG51bGwuCisgICAgICogQHRocm93cyBJbGxlZ2FsQ2hhcnNldE5hbWVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBvbiBhbiBpbGxlZ2FsIHZhbHVlIGJlaW5nIHN1cHBsaWVkIGZvciBlaXRoZXIKKyAgICAgKiAgICAgICAgICAgICA8Y29kZT5jYW5vbmljYWxOYW1lPC9jb2RlPiBvciBmb3IgYW55IGVsZW1lbnQgb2YKKyAgICAgKiAgICAgICAgICAgICA8Y29kZT5hbGlhc2VzPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ2hhcnNldChTdHJpbmcgY2Fub25pY2FsTmFtZSwgU3RyaW5nW10gYWxpYXNlcykgeworICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoZSBnaXZlbiBjYW5vbmljYWwgbmFtZSBpcyBsZWdhbAorICAgICAgICBjaGVja0NoYXJzZXROYW1lKGNhbm9uaWNhbE5hbWUpOworICAgICAgICB0aGlzLmNhbm9uaWNhbE5hbWUgPSBjYW5vbmljYWxOYW1lOworICAgICAgICAvLyBjaGVjayBlYWNoIGFsaWFzIGFuZCBwdXQgaW50byBhIHNldAorICAgICAgICB0aGlzLmFsaWFzZXNTZXQgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7CisgICAgICAgIGlmIChhbGlhc2VzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIGFsaWFzIDogYWxpYXNlcykgeworICAgICAgICAgICAgICAgIGNoZWNrQ2hhcnNldE5hbWUoYWxpYXMpOworICAgICAgICAgICAgICAgIHRoaXMuYWxpYXNlc1NldC5hZGQoYWxpYXMpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja0NoYXJzZXROYW1lKFN0cmluZyBuYW1lKSB7CisgICAgICAgIGlmIChuYW1lLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxDaGFyc2V0TmFtZUV4Y2VwdGlvbihuYW1lKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgbGVuZ3RoID0gbmFtZS5sZW5ndGgoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgeworICAgICAgICAgICAgaWYgKCFpc1ZhbGlkQ2hhcnNldE5hbWVDaGFyYWN0ZXIobmFtZS5jaGFyQXQoaSkpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxDaGFyc2V0TmFtZUV4Y2VwdGlvbihuYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNWYWxpZENoYXJzZXROYW1lQ2hhcmFjdGVyKGNoYXIgYykgeworICAgICAgICByZXR1cm4gKGMgPj0gJ0EnICYmIGMgPD0gJ1onKSB8fCAoYyA+PSAnYScgJiYgYyA8PSAneicpIHx8IChjID49ICcwJyAmJiBjIDw9ICc5JykgfHwKKyAgICAgICAgICAgICAgICBjID09ICctJyB8fCBjID09ICcuJyB8fCBjID09ICc6JyB8fCBjID09ICdfJzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGltbXV0YWJsZSBjYXNlLWluc2Vuc2l0aXZlIG1hcCBmcm9tIGNhbm9uaWNhbCBuYW1lcyB0byB7QGNvZGUgQ2hhcnNldH0gaW5zdGFuY2VzLgorICAgICAqIElmIG11bHRpcGxlIGNoYXJzZXRzIGhhdmUgdGhlIHNhbWUgY2Fub25pY2FsIG5hbWUsIGl0IGlzIHVuc3BlY2lmaWVkIHdoaWNoIGlzIHJldHVybmVkIGluCisgICAgICogdGhlIG1hcC4gVGhpcyBtZXRob2QgbWF5IGJlIHNsb3cuIElmIHlvdSBrbm93IHdoaWNoIGNoYXJzZXQgeW91J3JlIGxvb2tpbmcgZm9yLCB1c2UKKyAgICAgKiB7QGxpbmsgI2Zvck5hbWV9LgorICAgICAqIEByZXR1cm4gYW4gaW1tdXRhYmxlIGNhc2UtaW5zZW5zaXRpdmUgbWFwIGZyb20gY2Fub25pY2FsIG5hbWVzIHRvIHtAY29kZSBDaGFyc2V0fSBpbnN0YW5jZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNvcnRlZE1hcDxTdHJpbmcsIENoYXJzZXQ+IGF2YWlsYWJsZUNoYXJzZXRzKCkgeworICAgICAgICAvLyBTdGFydCB3aXRoIGEgY29weSBvZiB0aGUgYnVpbHQtaW4gY2hhcnNldHMuLi4KKyAgICAgICAgVHJlZU1hcDxTdHJpbmcsIENoYXJzZXQ+IGNoYXJzZXRzID0gbmV3IFRyZWVNYXA8U3RyaW5nLCBDaGFyc2V0PihTdHJpbmcuQ0FTRV9JTlNFTlNJVElWRV9PUkRFUik7CisgICAgICAgIGZvciAoU3RyaW5nIGNoYXJzZXROYW1lIDogTmF0aXZlQ29udmVydGVyLmdldEF2YWlsYWJsZUNoYXJzZXROYW1lcygpKSB7CisgICAgICAgICAgICBDaGFyc2V0IGNoYXJzZXQgPSBOYXRpdmVDb252ZXJ0ZXIuY2hhcnNldEZvck5hbWUoY2hhcnNldE5hbWUpOworICAgICAgICAgICAgY2hhcnNldHMucHV0KGNoYXJzZXQubmFtZSgpLCBjaGFyc2V0KTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEFkZCBhbGwgY2hhcnNldHMgcHJvdmlkZWQgYnkgYWxsIGNoYXJzZXQgcHJvdmlkZXJzLi4uCisgICAgICAgIGZvciAoQ2hhcnNldFByb3ZpZGVyIGNoYXJzZXRQcm92aWRlciA6IFNlcnZpY2VMb2FkZXIubG9hZChDaGFyc2V0UHJvdmlkZXIuY2xhc3MpKSB7CisgICAgICAgICAgICBJdGVyYXRvcjxDaGFyc2V0PiBpdCA9IGNoYXJzZXRQcm92aWRlci5jaGFyc2V0cygpOworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIENoYXJzZXQgY3MgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgLy8gQSBDaGFyc2V0UHJvdmlkZXIgY2FuJ3Qgb3ZlcnJpZGUgYSBidWlsdC1pbiBDaGFyc2V0LgorICAgICAgICAgICAgICAgIGlmICghY2hhcnNldHMuY29udGFpbnNLZXkoY3MubmFtZSgpKSkgeworICAgICAgICAgICAgICAgICAgICBjaGFyc2V0cy5wdXQoY3MubmFtZSgpLCBjcyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNvcnRlZE1hcChjaGFyc2V0cyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgQ2hhcnNldCBjYWNoZUNoYXJzZXQoU3RyaW5nIGNoYXJzZXROYW1lLCBDaGFyc2V0IGNzKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoQ0FDSEVEX0NIQVJTRVRTKSB7CisgICAgICAgICAgICAvLyBHZXQgdGhlIGNhbm9uaWNhbCBuYW1lIGZvciB0aGlzIGNoYXJzZXQsIGFuZCB0aGUgY2Fub25pY2FsIGluc3RhbmNlIGZyb20gdGhlIHRhYmxlLgorICAgICAgICAgICAgU3RyaW5nIGNhbm9uaWNhbE5hbWUgPSBjcy5uYW1lKCk7CisgICAgICAgICAgICBDaGFyc2V0IGNhbm9uaWNhbENoYXJzZXQgPSBDQUNIRURfQ0hBUlNFVFMuZ2V0KGNhbm9uaWNhbE5hbWUpOworICAgICAgICAgICAgaWYgKGNhbm9uaWNhbENoYXJzZXQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGNhbm9uaWNhbENoYXJzZXQgPSBjczsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gQ2FjaGUgdGhlIGNoYXJzZXQgYnkgaXRzIGNhbm9uaWNhbCBuYW1lLi4uCisgICAgICAgICAgICBDQUNIRURfQ0hBUlNFVFMucHV0KGNhbm9uaWNhbE5hbWUsIGNhbm9uaWNhbENoYXJzZXQpOworCisgICAgICAgICAgICAvLyBBbmQgdGhlIG5hbWUgdGhlIHVzZXIgdXNlZC4uLiAoU2VjdGlvbiAxLjQgb2YgaHR0cDovL3VuaWNvZGUub3JnL3JlcG9ydHMvdHIyMi8gbWVhbnMKKyAgICAgICAgICAgIC8vIHRoYXQgbWFueSBub24tYWxpYXMsIG5vbi1jYW5vbmljYWwgbmFtZXMgYXJlIHZhbGlkLiBGb3IgZXhhbXBsZSwgInV0ZjgiIGlzbid0IGFuCisgICAgICAgICAgICAvLyBhbGlhcyBvZiB0aGUgY2Fub25pY2FsIG5hbWUgIlVURi04IiwgYnV0IHdlIHNob3VsZG4ndCBwZW5hbGl6ZSBjb25zaXN0ZW50IHVzZXJzIG9mCisgICAgICAgICAgICAvLyBzdWNoIG5hbWVzIHVuZHVseS4pCisgICAgICAgICAgICBDQUNIRURfQ0hBUlNFVFMucHV0KGNoYXJzZXROYW1lLCBjYW5vbmljYWxDaGFyc2V0KTsKKworICAgICAgICAgICAgLy8gQW5kIGFsbCBpdHMgYWxpYXNlcy4uLgorICAgICAgICAgICAgZm9yIChTdHJpbmcgYWxpYXMgOiBjcy5hbGlhc2VzU2V0KSB7CisgICAgICAgICAgICAgICAgQ0FDSEVEX0NIQVJTRVRTLnB1dChhbGlhcywgY2Fub25pY2FsQ2hhcnNldCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBjYW5vbmljYWxDaGFyc2V0OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBDaGFyc2V0fSBpbnN0YW5jZSBmb3IgdGhlIG5hbWVkIGNoYXJzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhcnNldE5hbWUgYSBjaGFyc2V0IG5hbWUgKGVpdGhlciBjYW5vbmljYWwgb3IgYW4gYWxpYXMpCisgICAgICogQHRocm93cyBJbGxlZ2FsQ2hhcnNldE5hbWVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGNoYXJzZXQgbmFtZSBpcyBpbGxlZ2FsLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRDaGFyc2V0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGRlc2lyZWQgY2hhcnNldCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgcnVudGltZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIENoYXJzZXQgZm9yTmFtZShTdHJpbmcgY2hhcnNldE5hbWUpIHsKKyAgICAgICAgLy8gSXMgdGhpcyBjaGFyc2V0IGluIG91ciBjYWNoZT8KKyAgICAgICAgQ2hhcnNldCBjczsKKyAgICAgICAgc3luY2hyb25pemVkIChDQUNIRURfQ0hBUlNFVFMpIHsKKyAgICAgICAgICAgIGNzID0gQ0FDSEVEX0NIQVJTRVRTLmdldChjaGFyc2V0TmFtZSk7CisgICAgICAgICAgICBpZiAoY3MgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChjaGFyc2V0TmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbENoYXJzZXROYW1lRXhjZXB0aW9uKG51bGwpOworICAgICAgICB9CisKKyAgICAgICAgLy8gSXMgdGhpcyBhIGJ1aWx0LWluIGNoYXJzZXQgc3VwcG9ydGVkIGJ5IElDVT8KKyAgICAgICAgY2hlY2tDaGFyc2V0TmFtZShjaGFyc2V0TmFtZSk7CisgICAgICAgIGNzID0gTmF0aXZlQ29udmVydGVyLmNoYXJzZXRGb3JOYW1lKGNoYXJzZXROYW1lKTsKKyAgICAgICAgaWYgKGNzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBjYWNoZUNoYXJzZXQoY2hhcnNldE5hbWUsIGNzKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIERvZXMgYSBjb25maWd1cmVkIENoYXJzZXRQcm92aWRlciBoYXZlIHRoaXMgY2hhcnNldD8KKyAgICAgICAgZm9yIChDaGFyc2V0UHJvdmlkZXIgY2hhcnNldFByb3ZpZGVyIDogU2VydmljZUxvYWRlci5sb2FkKENoYXJzZXRQcm92aWRlci5jbGFzcykpIHsKKyAgICAgICAgICAgIGNzID0gY2hhcnNldFByb3ZpZGVyLmNoYXJzZXRGb3JOYW1lKGNoYXJzZXROYW1lKTsKKyAgICAgICAgICAgIGlmIChjcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNhY2hlQ2hhcnNldChjaGFyc2V0TmFtZSwgY3MpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkQ2hhcnNldEV4Y2VwdGlvbihjaGFyc2V0TmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgZm9yTmFtZX0gYnV0IG9ubHkgdGhyb3dzIHtAY29kZSBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9ufSwKKyAgICAgKiB3aGljaCBpcyBhbGwgcHJlLW5pbyBjb2RlIGNsYWltcyB0byB0aHJvdy4KKyAgICAgKgorICAgICAqIEBoaWRlIGludGVybmFsIHVzZSBvbmx5CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDaGFyc2V0IGZvck5hbWVVRUUoU3RyaW5nIGNoYXJzZXROYW1lKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gQ2hhcnNldC5mb3JOYW1lKGNoYXJzZXROYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGNhdXNlKSB7CisgICAgICAgICAgICBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGV4ID0gbmV3IFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24oY2hhcnNldE5hbWUpOworICAgICAgICAgICAgZXguaW5pdENhdXNlKGNhdXNlKTsKKyAgICAgICAgICAgIHRocm93IGV4OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY2hhcnNldCBpcyBzdXBwb3J0ZWQgYnkgdGhpcyBydW50aW1lLgorICAgICAqCisgICAgICogQHBhcmFtIGNoYXJzZXROYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY2hhcnNldC4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHNwZWNpZmllZCBjaGFyc2V0IGlzIHN1cHBvcnRlZCwgb3RoZXJ3aXNlIGZhbHNlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbENoYXJzZXROYW1lRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBjaGFyc2V0IG5hbWUgaXMgaWxsZWdhbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNTdXBwb3J0ZWQoU3RyaW5nIGNoYXJzZXROYW1lKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3JOYW1lKGNoYXJzZXROYW1lKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGlzIGNoYXJzZXQgaXMgYSBzdXBlcnNldCBvZiB0aGUgZ2l2ZW4gY2hhcnNldC4gQSBjaGFyc2V0IEMxIGNvbnRhaW5zCisgICAgICogY2hhcnNldCBDMiBpZiBldmVyeSBjaGFyYWN0ZXIgcmVwcmVzZW50YWJsZSBieSBDMiBpcyBhbHNvIHJlcHJlc2VudGFibGUgYnkgQzEuIFRoaXMgbWVhbnMKKyAgICAgKiB0aGF0IGxvc3NsZXNzIGNvbnZlcnNpb24gaXMgcG9zc2libGUgZnJvbSBDMiB0byBDMSAoYnV0IG5vdCBuZWNlc3NhcmlseSB0aGUgb3RoZXIgd2F5CisgICAgICogcm91bmQpLiBJdCBkb2VzIDxpPm5vdDwvaT4gaW1wbHkgdGhhdCB0aGUgdHdvIGNoYXJzZXRzIHVzZSB0aGUgc2FtZSBieXRlIHNlcXVlbmNlcyBmb3IgdGhlCisgICAgICogY2hhcmFjdGVycyB0aGV5IHNoYXJlLgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IHRoaXMgbWV0aG9kIGlzIGFsbG93ZWQgdG8gYmUgY29uc2VydmF0aXZlLCBhbmQgc29tZSBpbXBsZW1lbnRhdGlvbnMgbWF5IHJldHVybgorICAgICAqIGZhbHNlIHdoZW4gdGhpcyBjaGFyc2V0IGRvZXMgY29udGFpbiB0aGUgb3RoZXIgY2hhcnNldC4gQW5kcm9pZCdzIGltcGxlbWVudGF0aW9uIGlzIHByZWNpc2UsCisgICAgICogYW5kIHdpbGwgYWx3YXlzIHJldHVybiB0cnVlIGluIHN1Y2ggY2FzZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhcnNldAorICAgICAqICAgICAgICAgICAgYSBnaXZlbiBjaGFyc2V0LgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGNoYXJzZXQgaXMgYSBzdXBlciBzZXQgb2YgdGhlIGdpdmVuIGNoYXJzZXQsCisgICAgICogICAgICAgICBmYWxzZSBpZiBpdCdzIHVua25vd24gb3IgdGhpcyBjaGFyc2V0IGlzIG5vdCBhIHN1cGVyc2V0IG9mCisgICAgICogICAgICAgICB0aGUgZ2l2ZW4gY2hhcnNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBjb250YWlucyhDaGFyc2V0IGNoYXJzZXQpOworCisgICAgLyoqCisgICAgICogR2V0cyBhIG5ldyBpbnN0YW5jZSBvZiBhbiBlbmNvZGVyIGZvciB0aGlzIGNoYXJzZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgbmV3IGluc3RhbmNlIG9mIGFuIGVuY29kZXIgZm9yIHRoaXMgY2hhcnNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQ2hhcnNldEVuY29kZXIgbmV3RW5jb2RlcigpOworCisgICAgLyoqCisgICAgICogR2V0cyBhIG5ldyBpbnN0YW5jZSBvZiBhIGRlY29kZXIgZm9yIHRoaXMgY2hhcnNldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2YgYSBkZWNvZGVyIGZvciB0aGlzIGNoYXJzZXQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENoYXJzZXREZWNvZGVyIG5ld0RlY29kZXIoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNhbm9uaWNhbCBuYW1lIG9mIHRoaXMgY2hhcnNldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBjaGFyc2V0J3MgbmFtZSBpbiBjYW5vbmljYWwgZm9ybS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIG5hbWUoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmNhbm9uaWNhbE5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2V0IG9mIHRoaXMgY2hhcnNldCdzIGFsaWFzZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIHVubW9kaWZpYWJsZSBzZXQgb2YgdGhpcyBjaGFyc2V0J3MgYWxpYXNlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU2V0PFN0cmluZz4gYWxpYXNlcygpIHsKKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNldCh0aGlzLmFsaWFzZXNTZXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWUgb2YgdGhpcyBjaGFyc2V0IGZvciB0aGUgZGVmYXVsdCBsb2NhbGUuCisgICAgICoKKyAgICAgKiA8cD5UaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHRoZSBjYW5vbmljYWwgbmFtZSBvZiB0aGlzIGNoYXJzZXQuCisgICAgICogU3ViY2xhc3NlcyBtYXkgcmV0dXJuIGEgbG9jYWxpemVkIGRpc3BsYXkgbmFtZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhpcyBjaGFyc2V0IGZvciB0aGUgZGVmYXVsdCBsb2NhbGUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBkaXNwbGF5TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuY2Fub25pY2FsTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBuYW1lIG9mIHRoaXMgY2hhcnNldCBmb3IgdGhlIHNwZWNpZmllZCBsb2NhbGUuCisgICAgICoKKyAgICAgKiA8cD5UaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHRoZSBjYW5vbmljYWwgbmFtZSBvZiB0aGlzIGNoYXJzZXQuCisgICAgICogU3ViY2xhc3NlcyBtYXkgcmV0dXJuIGEgbG9jYWxpemVkIGRpc3BsYXkgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICBhIGNlcnRhaW4gbG9jYWxlCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGlzIGNoYXJzZXQgZm9yIHRoZSBzcGVjaWZpZWQgbG9jYWxlCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBkaXNwbGF5TmFtZShMb2NhbGUgbCkgeworICAgICAgICByZXR1cm4gdGhpcy5jYW5vbmljYWxOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgY2hhcnNldCBpcyBrbm93biB0byBiZSByZWdpc3RlcmVkIGluIHRoZSBJQU5BCisgICAgICogQ2hhcnNldCBSZWdpc3RyeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY2hhcnNldCBpcyBrbm93biB0byBiZSByZWdpc3RlcmVkLCBvdGhlcndpc2UgcmV0dXJucworICAgICAqICAgICAgICAgZmFsc2UuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNSZWdpc3RlcmVkKCkgeworICAgICAgICByZXR1cm4gIWNhbm9uaWNhbE5hbWUuc3RhcnRzV2l0aCgieC0iKSAmJiAhY2Fub25pY2FsTmFtZS5zdGFydHNXaXRoKCJYLSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGNoYXJzZXQgc3VwcG9ydHMgZW5jb2RpbmcsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGNoYXJzZXQgc3VwcG9ydHMgZW5jb2RpbmcsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjYW5FbmNvZGUoKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJ5dGVCdWZmZXJ9IGNvbnRhaW5pbmcgdGhlIGJ5dGVzIGVuY29kaW5nIHRoZSBjaGFyYWN0ZXJzIGZyb20KKyAgICAgKiB7QGNvZGUgYnVmZmVyfS4KKyAgICAgKiBUaGlzIG1ldGhvZCB1c2VzIHtAY29kZSBDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFfS4KKyAgICAgKgorICAgICAqIDxwPkFwcGxpY2F0aW9ucyBzaG91bGQgZ2VuZXJhbGx5IGNyZWF0ZSBhIHtAbGluayBDaGFyc2V0RW5jb2Rlcn0gdXNpbmcge0BsaW5rICNuZXdFbmNvZGVyfQorICAgICAqIGZvciBwZXJmb3JtYW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIGNvbnRlbnQgdG8gYmUgZW5jb2RlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIGVuY29kaW5nLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBCeXRlQnVmZmVyIGVuY29kZShDaGFyQnVmZmVyIGJ1ZmZlcikgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIG5ld0VuY29kZXIoKQorICAgICAgICAgICAgICAgICAgICAub25NYWxmb3JtZWRJbnB1dChDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFKQorICAgICAgICAgICAgICAgICAgICAub25Vbm1hcHBhYmxlQ2hhcmFjdGVyKENvZGluZ0Vycm9yQWN0aW9uLlJFUExBQ0UpLmVuY29kZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIpOworICAgICAgICB9IGNhdGNoIChDaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleC5nZXRNZXNzYWdlKCksIGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJ5dGVCdWZmZXJ9IGNvbnRhaW5pbmcgdGhlIGJ5dGVzIGVuY29kaW5nIHRoZSBjaGFyYWN0ZXJzIGZyb20ge0Bjb2RlIHN9LgorICAgICAqIFRoaXMgbWV0aG9kIHVzZXMge0Bjb2RlIENvZGluZ0Vycm9yQWN0aW9uLlJFUExBQ0V9LgorICAgICAqCisgICAgICogPHA+QXBwbGljYXRpb25zIHNob3VsZCBnZW5lcmFsbHkgY3JlYXRlIGEge0BsaW5rIENoYXJzZXRFbmNvZGVyfSB1c2luZyB7QGxpbmsgI25ld0VuY29kZXJ9CisgICAgICogZm9yIHBlcmZvcm1hbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIHMgdGhlIHN0cmluZyB0byBiZSBlbmNvZGVkLgorICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiB0aGUgZW5jb2RpbmcuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEJ5dGVCdWZmZXIgZW5jb2RlKFN0cmluZyBzKSB7CisgICAgICAgIHJldHVybiBlbmNvZGUoQ2hhckJ1ZmZlci53cmFwKHMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBDaGFyQnVmZmVyfSBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXJzIGRlY29kZWQgZnJvbSB7QGNvZGUgYnVmZmVyfS4KKyAgICAgKiBUaGlzIG1ldGhvZCB1c2VzIHtAY29kZSBDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFfS4KKyAgICAgKgorICAgICAqIDxwPkFwcGxpY2F0aW9ucyBzaG91bGQgZ2VuZXJhbGx5IGNyZWF0ZSBhIHtAbGluayBDaGFyc2V0RGVjb2Rlcn0gdXNpbmcge0BsaW5rICNuZXdEZWNvZGVyfQorICAgICAqIGZvciBwZXJmb3JtYW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGJ1ZmZlciBjb250YWluaW5nIHRoZSBjb250ZW50IHRvIGJlIGRlY29kZWQuCisgICAgICogQHJldHVybiBhIGNoYXJhY3RlciBidWZmZXIgY29udGFpbmluZyB0aGUgb3V0cHV0IG9mIHRoZSBkZWNvZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQ2hhckJ1ZmZlciBkZWNvZGUoQnl0ZUJ1ZmZlciBidWZmZXIpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBuZXdEZWNvZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLm9uTWFsZm9ybWVkSW5wdXQoQ29kaW5nRXJyb3JBY3Rpb24uUkVQTEFDRSkKKyAgICAgICAgICAgICAgICAgICAgLm9uVW5tYXBwYWJsZUNoYXJhY3RlcihDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFKS5kZWNvZGUoYnVmZmVyKTsKKyAgICAgICAgfSBjYXRjaCAoQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXguZ2V0TWVzc2FnZSgpLCBleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAgKiBNZXRob2RzIGltcGxlbWVudGluZyBwYXJlbnQgaW50ZXJmYWNlIENvbXBhcmFibGUKKyAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIGNoYXJzZXQgd2l0aCB0aGUgZ2l2ZW4gY2hhcnNldC4gVGhpcyBjb21wYXJpc29uIGlzCisgICAgICogYmFzZWQgb24gdGhlIGNhc2UgaW5zZW5zaXRpdmUgY2Fub25pY2FsIG5hbWVzIG9mIHRoZSBjaGFyc2V0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaGFyc2V0CisgICAgICogICAgICAgICAgICB0aGUgZ2l2ZW4gb2JqZWN0IHRvIGJlIGNvbXBhcmVkIHdpdGguCisgICAgICogQHJldHVybiBhIG5lZ2F0aXZlIGludGVnZXIgaWYgbGVzcyB0aGFuIHRoZSBnaXZlbiBvYmplY3QsIGEgcG9zaXRpdmUKKyAgICAgKiAgICAgICAgIGludGVnZXIgaWYgbGFyZ2VyIHRoYW4gaXQsIG9yIDAgaWYgZXF1YWwgdG8gaXQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBjb21wYXJlVG8oQ2hhcnNldCBjaGFyc2V0KSB7CisgICAgICAgIHJldHVybiB0aGlzLmNhbm9uaWNhbE5hbWUuY29tcGFyZVRvSWdub3JlQ2FzZShjaGFyc2V0LmNhbm9uaWNhbE5hbWUpOworICAgIH0KKworICAgIC8qCisgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAqIE1ldGhvZHMgb3ZlcnJpZGluZyBwYXJlbnQgY2xhc3MgT2JqZWN0CisgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAqLworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoaXMgY2hhcnNldCBlcXVhbHMgdG8gdGhlIGdpdmVuIG9iamVjdC4gVGhleSBhcmUKKyAgICAgKiBjb25zaWRlcmVkIHRvIGJlIGVxdWFsIGlmIHRoZXkgaGF2ZSB0aGUgc2FtZSBjYW5vbmljYWwgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSBnaXZlbiBvYmplY3QgdG8gYmUgY29tcGFyZWQgd2l0aC4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhleSBoYXZlIHRoZSBzYW1lIGNhbm9uaWNhbCBuYW1lLCBvdGhlcndpc2UgZmFsc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIENoYXJzZXQpIHsKKyAgICAgICAgICAgIENoYXJzZXQgdGhhdCA9IChDaGFyc2V0KSBvYmo7CisgICAgICAgICAgICByZXR1cm4gdGhpcy5jYW5vbmljYWxOYW1lLmVxdWFscyh0aGF0LmNhbm9uaWNhbE5hbWUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBoYXNoIGNvZGUgb2YgdGhpcyBjaGFyc2V0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIG9mIHRoaXMgY2hhcnNldC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gdGhpcy5jYW5vbmljYWxOYW1lLmhhc2hDb2RlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGNoYXJzZXQuIFVzdWFsbHkgdGhpcyBjb250YWlucyB0aGUKKyAgICAgKiBjYW5vbmljYWwgbmFtZSBvZiB0aGUgY2hhcnNldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBjaGFyc2V0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBnZXRDbGFzcygpLmdldE5hbWUoKSArICJbIiArIHRoaXMuY2Fub25pY2FsTmFtZSArICJdIjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzeXN0ZW0ncyBkZWZhdWx0IGNoYXJzZXQuIFRoaXMgaXMgZGV0ZXJtaW5lZCBkdXJpbmcgVk0gc3RhcnR1cCwgYW5kIHdpbGwgbm90CisgICAgICogY2hhbmdlIHRoZXJlYWZ0ZXIuIE9uIEFuZHJvaWQsIHRoZSBkZWZhdWx0IGNoYXJzZXQgaXMgVVRGLTguCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDaGFyc2V0IGRlZmF1bHRDaGFyc2V0KCkgeworICAgICAgICByZXR1cm4gREVGQVVMVF9DSEFSU0VUOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIENoYXJzZXQgZ2V0RGVmYXVsdENoYXJzZXQoKSB7CisgICAgICAgIFN0cmluZyBlbmNvZGluZyA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiZmlsZS5lbmNvZGluZyIsICJVVEYtOCIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIENoYXJzZXQuZm9yTmFtZShlbmNvZGluZyk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkQ2hhcnNldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gQ2hhcnNldC5mb3JOYW1lKCJVVEYtOCIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldERlY29kZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L0NoYXJzZXREZWNvZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjY3ZGJiYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L0NoYXJzZXREZWNvZGVyLmphdmEKQEAgLTAsMCArMSw2ODEgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhcnNldDsKKworaW1wb3J0IGphdmEubmlvLkJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLkNoYXJCdWZmZXI7CisKKy8qKgorICogQSBjb252ZXJ0ZXIgdGhhdCBjYW4gY29udmVydCBhIGJ5dGUgc2VxdWVuY2UgZnJvbSBhIGNoYXJzZXQgaW50byBhIDE2LWJpdAorICogVW5pY29kZSBjaGFyYWN0ZXIgc2VxdWVuY2UuCisgKiA8cD4KKyAqIFRoZSBpbnB1dCBieXRlIHNlcXVlbmNlIGlzIHdyYXBwZWQgYnkgYQorICoge0BsaW5rIGphdmEubmlvLkJ5dGVCdWZmZXIgQnl0ZUJ1ZmZlcn0gYW5kIHRoZSBvdXRwdXQgY2hhcmFjdGVyIHNlcXVlbmNlIGlzIGEKKyAqIHtAbGluayBqYXZhLm5pby5DaGFyQnVmZmVyIENoYXJCdWZmZXJ9LiBBIGRlY29kZXIgaW5zdGFuY2Ugc2hvdWxkIGJlIHVzZWQgaW4KKyAqIHRoZSBmb2xsb3dpbmcgc2VxdWVuY2UsIHdoaWNoIGlzIHJlZmVycmVkIHRvIGFzIGEgZGVjb2Rpbmcgb3BlcmF0aW9uOgorICogPG9sPgorICogPGxpPmludm9raW5nIHRoZSB7QGxpbmsgI3Jlc2V0KCkgcmVzZXR9IG1ldGhvZCB0byByZXNldCB0aGUgZGVjb2RlciBpZiB0aGUKKyAqIGRlY29kZXIgaGFzIGJlZW4gdXNlZDs8L2xpPgorICogPGxpPmludm9raW5nIHRoZSB7QGxpbmsgI2RlY29kZShCeXRlQnVmZmVyLCBDaGFyQnVmZmVyLCBib29sZWFuKSBkZWNvZGV9CisgKiBtZXRob2QgdW50aWwgdGhlIGFkZGl0aW9uYWwgaW5wdXQgaXMgbm90IG5lZWRlZCwgdGhlIDxjb2RlPmVuZE9mSW5wdXQ8L2NvZGU+CisgKiBwYXJhbWV0ZXIgbXVzdCBiZSBzZXQgdG8gZmFsc2UsIHRoZSBpbnB1dCBidWZmZXIgbXVzdCBiZSBmaWxsZWQgYW5kIHRoZQorICogb3V0cHV0IGJ1ZmZlciBtdXN0IGJlIGZsdXNoZWQgYmV0d2VlbiBpbnZvY2F0aW9uczs8L2xpPgorICogPGxpPmludm9raW5nIHRoZSB7QGxpbmsgI2RlY29kZShCeXRlQnVmZmVyLCBDaGFyQnVmZmVyLCBib29sZWFuKSBkZWNvZGV9CisgKiBtZXRob2QgZm9yIHRoZSBsYXN0IHRpbWUsIGFuZCB0aGVuIHRoZSA8Y29kZT5lbmRPZklucHV0PC9jb2RlPiBwYXJhbWV0ZXIKKyAqIG11c3QgYmUgc2V0IHRvIHRydWU7PC9saT4KKyAqIDxsaT5pbnZva2luZyB0aGUge0BsaW5rICNmbHVzaChDaGFyQnVmZmVyKSBmbHVzaH0gbWV0aG9kIHRvIGZsdXNoIHRoZQorICogb3V0cHV0LjwvbGk+CisgKiA8L29sPgorICogPHA+CisgKiBUaGUge0BsaW5rICNkZWNvZGUoQnl0ZUJ1ZmZlciwgQ2hhckJ1ZmZlciwgYm9vbGVhbikgZGVjb2RlfSBtZXRob2Qgd2lsbAorICogY29udmVydCBhcyBtYW55IGJ5dGVzIGFzIHBvc3NpYmxlLCBhbmQgdGhlIHByb2Nlc3Mgd29uJ3Qgc3RvcCB1bnRpbCB0aGUgaW5wdXQKKyAqIGJ5dGVzIGhhdmUgcnVuIG91dCwgdGhlIG91dHB1dCBidWZmZXIgaGFzIGJlZW4gZmlsbGVkIG9yIHNvbWUgZXJyb3IgaGFzCisgKiBoYXBwZW5lZC4gQSB7QGxpbmsgQ29kZXJSZXN1bHQgQ29kZXJSZXN1bHR9IGluc3RhbmNlIHdpbGwgYmUgcmV0dXJuZWQgdG8KKyAqIGluZGljYXRlIHRoZSBzdG9wIHJlYXNvbiwgYW5kIHRoZSBpbnZva2VyIGNhbiBpZGVudGlmeSB0aGUgcmVzdWx0IGFuZCBjaG9vc2UKKyAqIGZ1cnRoZXIgYWN0aW9uLCB3aGljaCBpbmNsdWRlcyBmaWxsaW5nIHRoZSBpbnB1dCBidWZmZXIsIGZsdXNoaW5nIHRoZSBvdXRwdXQKKyAqIGJ1ZmZlciBvciByZWNvdmVyaW5nIGZyb20gYW4gZXJyb3IgYW5kIHRyeWluZyBhZ2Fpbi4KKyAqIDxwPgorICogVGhlcmUgYXJlIHR3byBjb21tb24gZGVjb2RpbmcgZXJyb3JzLiBPbmUgaXMgbmFtZWQgbWFsZm9ybWVkIGFuZCBpdCBpcworICogcmV0dXJuZWQgd2hlbiB0aGUgaW5wdXQgYnl0ZSBzZXF1ZW5jZSBpcyBpbGxlZ2FsIGZvciB0aGUgY3VycmVudCBzcGVjaWZpYworICogY2hhcnNldCwgdGhlIG90aGVyIGlzIG5hbWVkIHVubWFwcGFibGUgY2hhcmFjdGVyIGFuZCBpdCBpcyByZXR1cm5lZCB3aGVuIGEKKyAqIHByb2JsZW0gb2NjdXJzIG1hcHBpbmcgYSBsZWdhbCBpbnB1dCBieXRlIHNlcXVlbmNlIHRvIGl0cyBVbmljb2RlIGNoYXJhY3RlcgorICogZXF1aXZhbGVudC4KKyAqIDxwPgorICogQm90aCBlcnJvcnMgY2FuIGJlIGhhbmRsZWQgaW4gdGhyZWUgd2F5cywgdGhlIGRlZmF1bHQgb25lIGlzIHRvIHJlcG9ydCB0aGUKKyAqIGVycm9yIHRvIHRoZSBpbnZva2VyIGJ5IGEge0BsaW5rIENvZGVyUmVzdWx0IENvZGVyUmVzdWx0fSBpbnN0YW5jZSwgYW5kIHRoZQorICogYWx0ZXJuYXRpdmVzIGFyZSB0byBpZ25vcmUgaXQgb3IgdG8gcmVwbGFjZSB0aGUgZXJyb25lb3VzIGlucHV0IHdpdGggdGhlCisgKiByZXBsYWNlbWVudCBzdHJpbmcuIFRoZSByZXBsYWNlbWVudCBzdHJpbmcgaXMgIlx1RkZGRCIgYnkgZGVmYXVsdCBhbmQgY2FuIGJlCisgKiBjaGFuZ2VkIGJ5IGludm9raW5nIHtAbGluayAjcmVwbGFjZVdpdGgoU3RyaW5nKSByZXBsYWNlV2l0aH0gbWV0aG9kLiBUaGUKKyAqIGludm9rZXIgb2YgdGhpcyBkZWNvZGVyIGNhbiBjaG9vc2Ugb25lIHdheSBieSBzcGVjaWZ5aW5nIGEKKyAqIHtAbGluayBDb2RpbmdFcnJvckFjdGlvbiBDb2RpbmdFcnJvckFjdGlvbn0gaW5zdGFuY2UgZm9yIGVhY2ggZXJyb3IgdHlwZSB2aWEKKyAqIHtAbGluayAjb25NYWxmb3JtZWRJbnB1dChDb2RpbmdFcnJvckFjdGlvbikgb25NYWxmb3JtZWRJbnB1dH0gbWV0aG9kIGFuZAorICoge0BsaW5rICNvblVubWFwcGFibGVDaGFyYWN0ZXIoQ29kaW5nRXJyb3JBY3Rpb24pIG9uVW5tYXBwYWJsZUNoYXJhY3Rlcn0KKyAqIG1ldGhvZC4KKyAqIDxwPgorICogVGhpcyBpcyBhbiBhYnN0cmFjdCBjbGFzcyBhbmQgZW5jYXBzdWxhdGVzIG1hbnkgY29tbW9uIG9wZXJhdGlvbnMgb2YgdGhlCisgKiBkZWNvZGluZyBwcm9jZXNzIGZvciBhbGwgY2hhcnNldHMuIERlY29kZXJzIGZvciBhIHNwZWNpZmljIGNoYXJzZXQgc2hvdWxkCisgKiBleHRlbmQgdGhpcyBjbGFzcyBhbmQgbmVlZCBvbmx5IHRvIGltcGxlbWVudCB0aGUKKyAqIHtAbGluayAjZGVjb2RlTG9vcChCeXRlQnVmZmVyLCBDaGFyQnVmZmVyKSBkZWNvZGVMb29wfSBtZXRob2QgZm9yIHRoZSBiYXNpYworICogZGVjb2RpbmcuIElmIGEgc3ViY2xhc3MgbWFpbnRhaW5zIGFuIGludGVybmFsIHN0YXRlLCBpdCBzaG91bGQgb3ZlcnJpZGUgdGhlCisgKiB7QGxpbmsgI2ltcGxGbHVzaChDaGFyQnVmZmVyKSBpbXBsRmx1c2h9IG1ldGhvZCBhbmQgdGhlCisgKiB7QGxpbmsgI2ltcGxSZXNldCgpIGltcGxSZXNldH0gbWV0aG9kIGluIGFkZGl0aW9uLgorICogPHA+CisgKiBUaGlzIGNsYXNzIGlzIG5vdCB0aHJlYWQtc2FmZS4KKyAqCisgKiBAc2VlIGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldAorICogQHNlZSBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRFbmNvZGVyCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBDaGFyc2V0RGVjb2RlciB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOSVQgPSAwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBPTkdPSU5HID0gMTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRU5EID0gMjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRkxVU0ggPSAzOworCisgICAgcHJpdmF0ZSBmaW5hbCBmbG9hdCBhdmVyYWdlQ2hhcnNQZXJCeXRlOworICAgIHByaXZhdGUgZmluYWwgZmxvYXQgbWF4Q2hhcnNQZXJCeXRlOworCisgICAgcHJpdmF0ZSBmaW5hbCBDaGFyc2V0IGNzOworCisgICAgcHJpdmF0ZSBDb2RpbmdFcnJvckFjdGlvbiBtYWxmb3JtZWRJbnB1dEFjdGlvbjsKKyAgICBwcml2YXRlIENvZGluZ0Vycm9yQWN0aW9uIHVubWFwcGFibGVDaGFyYWN0ZXJBY3Rpb247CisKKyAgICBwcml2YXRlIFN0cmluZyByZXBsYWNlbWVudENoYXJzOworCisgICAgcHJpdmF0ZSBpbnQgc3RhdHVzOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyA8Y29kZT5DaGFyc2V0RGVjb2RlcjwvY29kZT4gdXNpbmcgdGhlIGdpdmVuCisgICAgICogPGNvZGU+Q2hhcnNldDwvY29kZT4sIGF2ZXJhZ2UgbnVtYmVyIGFuZCBtYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzCisgICAgICogY3JlYXRlZCBieSB0aGlzIGRlY29kZXIgZm9yIG9uZSBpbnB1dCBieXRlLCBhbmQgdGhlIGRlZmF1bHQgcmVwbGFjZW1lbnQKKyAgICAgKiBzdHJpbmcgIlx1RkZGRCIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhcnNldAorICAgICAqICAgICAgICAgICAgdGhlIDxjb2RlPkNoYXJzZXQ8L2NvZGU+IHRvIGJlIHVzZWQgYnkgdGhpcyBkZWNvZGVyLgorICAgICAqIEBwYXJhbSBhdmVyYWdlQ2hhcnNQZXJCeXRlCisgICAgICogICAgICAgICAgICB0aGUgYXZlcmFnZSBudW1iZXIgb2YgY2hhcmFjdGVycyBjcmVhdGVkIGJ5IHRoaXMgZGVjb2RlciBmb3IKKyAgICAgKiAgICAgICAgICAgIG9uZSBpbnB1dCBieXRlLCBtdXN0IGJlIHBvc2l0aXZlLgorICAgICAqIEBwYXJhbSBtYXhDaGFyc1BlckJ5dGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIGNyZWF0ZWQgYnkgdGhpcyBkZWNvZGVyIGZvcgorICAgICAqICAgICAgICAgICAgb25lIGlucHV0IGJ5dGUsIG11c3QgYmUgcG9zaXRpdmUuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiA8Y29kZT5hdmVyYWdlQ2hhcnNQZXJCeXRlPC9jb2RlPiBvcgorICAgICAqICAgICAgICAgICAgIDxjb2RlPm1heENoYXJzUGVyQnl0ZTwvY29kZT4gaXMgbmVnYXRpdmUuCisgICAgICovCisgICAgcHJvdGVjdGVkIENoYXJzZXREZWNvZGVyKENoYXJzZXQgY2hhcnNldCwgZmxvYXQgYXZlcmFnZUNoYXJzUGVyQnl0ZSwgZmxvYXQgbWF4Q2hhcnNQZXJCeXRlKSB7CisgICAgICAgIGlmIChhdmVyYWdlQ2hhcnNQZXJCeXRlIDw9IDAgfHwgbWF4Q2hhcnNQZXJCeXRlIDw9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImF2ZXJhZ2VDaGFyc1BlckJ5dGUgYW5kIG1heENoYXJzUGVyQnl0ZSBtdXN0IGJlIHBvc2l0aXZlIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGF2ZXJhZ2VDaGFyc1BlckJ5dGUgPiBtYXhDaGFyc1BlckJ5dGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImF2ZXJhZ2VDaGFyc1BlckJ5dGUgaXMgZ3JlYXRlciB0aGFuIG1heENoYXJzUGVyQnl0ZSIpOworICAgICAgICB9CisgICAgICAgIHRoaXMuYXZlcmFnZUNoYXJzUGVyQnl0ZSA9IGF2ZXJhZ2VDaGFyc1BlckJ5dGU7CisgICAgICAgIHRoaXMubWF4Q2hhcnNQZXJCeXRlID0gbWF4Q2hhcnNQZXJCeXRlOworICAgICAgICBjcyA9IGNoYXJzZXQ7CisgICAgICAgIHN0YXR1cyA9IElOSVQ7CisgICAgICAgIG1hbGZvcm1lZElucHV0QWN0aW9uID0gQ29kaW5nRXJyb3JBY3Rpb24uUkVQT1JUOworICAgICAgICB1bm1hcHBhYmxlQ2hhcmFjdGVyQWN0aW9uID0gQ29kaW5nRXJyb3JBY3Rpb24uUkVQT1JUOworICAgICAgICByZXBsYWNlbWVudENoYXJzID0gIlx1ZmZmZCI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXZlcmFnZSBudW1iZXIgb2YgY2hhcmFjdGVycyBjcmVhdGVkIGJ5IHRoaXMgZGVjb2RlciBmb3IgYQorICAgICAqIHNpbmdsZSBpbnB1dCBieXRlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBmbG9hdCBhdmVyYWdlQ2hhcnNQZXJCeXRlKCkgeworICAgICAgICByZXR1cm4gYXZlcmFnZUNoYXJzUGVyQnl0ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGxpbmsgQ2hhcnNldH0gd2hpY2ggdGhpcyBkZWNvZGVyIHVzZXMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENoYXJzZXQgY2hhcnNldCgpIHsKKyAgICAgICAgcmV0dXJuIGNzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgaXMgYSBmYWNhZGUgbWV0aG9kIGZvciB0aGUgZGVjb2Rpbmcgb3BlcmF0aW9uLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIGRlY29kZXMgdGhlIHJlbWFpbmluZyBieXRlIHNlcXVlbmNlIG9mIHRoZSBnaXZlbiBieXRlIGJ1ZmZlcgorICAgICAqIGludG8gYSBuZXcgY2hhcmFjdGVyIGJ1ZmZlci4gVGhpcyBtZXRob2QgcGVyZm9ybXMgYSBjb21wbGV0ZSBkZWNvZGluZworICAgICAqIG9wZXJhdGlvbiwgcmVzZXRzIGF0IGZpcnN0LCB0aGVuIGRlY29kZXMsIGFuZCBmbHVzaGVzIGF0IGxhc3QuCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZSBpbnZva2VkIHdoaWxlIGFub3RoZXIge0Bjb2RlIGRlY29kZX0gb3BlcmF0aW9uCisgICAgICogaXMgb25nb2luZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbgorICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIGEgbmV3IDxjb2RlPkNoYXJCdWZmZXI8L2NvZGU+IGNvbnRhaW5pbmcgdGhlIHRoZSBjaGFyYWN0ZXJzCisgICAgICogICAgICAgICBwcm9kdWNlZCBieSB0aGlzIGRlY29kaW5nIG9wZXJhdGlvbi4gVGhlIGJ1ZmZlcidzIGxpbWl0IHdpbGwgYmUKKyAgICAgKiAgICAgICAgIHRoZSBwb3NpdGlvbiBvZiB0aGUgbGFzdCBjaGFyYWN0ZXIgaW4gdGhlIGJ1ZmZlciwgYW5kIHRoZQorICAgICAqICAgICAgICAgcG9zaXRpb24gd2lsbCBiZSB6ZXJvLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciBkZWNvZGluZyBvcGVyYXRpb24gaXMgb25nb2luZy4KKyAgICAgKiBAdGhyb3dzIE1hbGZvcm1lZElucHV0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gaWxsZWdhbCBpbnB1dCBieXRlIHNlcXVlbmNlIGZvciB0aGlzIGNoYXJzZXQgd2FzCisgICAgICogICAgICAgICAgICAgZW5jb3VudGVyZWQsIGFuZCB0aGUgYWN0aW9uIGZvciBtYWxmb3JtZWQgZXJyb3IgaXMKKyAgICAgKiAgICAgICAgICAgICB7QGxpbmsgQ29kaW5nRXJyb3JBY3Rpb24jUkVQT1JUIENvZGluZ0Vycm9yQWN0aW9uLlJFUE9SVH0KKyAgICAgKiBAdGhyb3dzIFVubWFwcGFibGVDaGFyYWN0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGxlZ2FsIGJ1dCB1bm1hcHBhYmxlIGlucHV0IGJ5dGUgc2VxdWVuY2UgZm9yIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBjaGFyc2V0IHdhcyBlbmNvdW50ZXJlZCwgYW5kIHRoZSBhY3Rpb24gZm9yIHVubWFwcGFibGUKKyAgICAgKiAgICAgICAgICAgICBjaGFyYWN0ZXIgZXJyb3IgaXMKKyAgICAgKiAgICAgICAgICAgICB7QGxpbmsgQ29kaW5nRXJyb3JBY3Rpb24jUkVQT1JUIENvZGluZ0Vycm9yQWN0aW9uLlJFUE9SVH0uCisgICAgICogICAgICAgICAgICAgVW5tYXBwYWJsZSBtZWFucyB0aGUgYnl0ZSBzZXF1ZW5jZSBhdCB0aGUgaW5wdXQgYnVmZmVyJ3MKKyAgICAgKiAgICAgICAgICAgICBjdXJyZW50IHBvc2l0aW9uIGNhbm5vdCBiZSBtYXBwZWQgdG8gYSBVbmljb2RlIGNoYXJhY3RlcgorICAgICAqICAgICAgICAgICAgIHNlcXVlbmNlLgorICAgICAqIEB0aHJvd3MgQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciBleGNlcHRpb24gaGFwcGVuZWQgZHVyaW5nIHRoZSBkZWNvZGUgb3BlcmF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBDaGFyQnVmZmVyIGRlY29kZShCeXRlQnVmZmVyIGluKSB0aHJvd3MgQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgcmVzZXQoKTsKKyAgICAgICAgaW50IGxlbmd0aCA9IChpbnQpIChpbi5yZW1haW5pbmcoKSAqIGF2ZXJhZ2VDaGFyc1BlckJ5dGUpOworICAgICAgICBDaGFyQnVmZmVyIG91dHB1dCA9IENoYXJCdWZmZXIuYWxsb2NhdGUobGVuZ3RoKTsKKyAgICAgICAgQ29kZXJSZXN1bHQgcmVzdWx0ID0gbnVsbDsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IGRlY29kZShpbiwgb3V0cHV0LCBmYWxzZSk7CisgICAgICAgICAgICBjaGVja0NvZGVyUmVzdWx0KHJlc3VsdCk7CisgICAgICAgICAgICBpZiAocmVzdWx0LmlzVW5kZXJmbG93KCkpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzdWx0LmlzT3ZlcmZsb3coKSkgeworICAgICAgICAgICAgICAgIG91dHB1dCA9IGFsbG9jYXRlTW9yZShvdXRwdXQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJlc3VsdCA9IGRlY29kZShpbiwgb3V0cHV0LCB0cnVlKTsKKyAgICAgICAgY2hlY2tDb2RlclJlc3VsdChyZXN1bHQpOworCisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICByZXN1bHQgPSBmbHVzaChvdXRwdXQpOworICAgICAgICAgICAgY2hlY2tDb2RlclJlc3VsdChyZXN1bHQpOworICAgICAgICAgICAgaWYgKHJlc3VsdC5pc092ZXJmbG93KCkpIHsKKyAgICAgICAgICAgICAgICBvdXRwdXQgPSBhbGxvY2F0ZU1vcmUob3V0cHV0KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBvdXRwdXQuZmxpcCgpOworICAgICAgICBzdGF0dXMgPSBGTFVTSDsKKyAgICAgICAgcmV0dXJuIG91dHB1dDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNoZWNrcyB0aGUgcmVzdWx0IHdoZXRoZXIgaXQgbmVlZHMgdG8gdGhyb3cgQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjaGVja0NvZGVyUmVzdWx0KENvZGVyUmVzdWx0IHJlc3VsdCkgdGhyb3dzIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChyZXN1bHQuaXNNYWxmb3JtZWQoKSAmJiBtYWxmb3JtZWRJbnB1dEFjdGlvbiA9PSBDb2RpbmdFcnJvckFjdGlvbi5SRVBPUlQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRJbnB1dEV4Y2VwdGlvbihyZXN1bHQubGVuZ3RoKCkpOworICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdC5pc1VubWFwcGFibGUoKSAmJiB1bm1hcHBhYmxlQ2hhcmFjdGVyQWN0aW9uID09IENvZGluZ0Vycm9yQWN0aW9uLlJFUE9SVCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVubWFwcGFibGVDaGFyYWN0ZXJFeGNlcHRpb24ocmVzdWx0Lmxlbmd0aCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogb3JpZ2luYWwgb3V0cHV0IGlzIGZ1bGwgYW5kIGRvZXNuJ3QgaGF2ZSByZW1haW5pbmcuIGFsbG9jYXRlIG1vcmUgc3BhY2UKKyAgICAgKiB0byBuZXcgQ2hhckJ1ZmZlciBhbmQgcmV0dXJuIGl0LCB0aGUgY29udGVudHMgaW4gdGhlIGdpdmVuIGJ1ZmZlciB3aWxsIGJlCisgICAgICogY29waWVkIGludG8gdGhlIG5ldyBidWZmZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBDaGFyQnVmZmVyIGFsbG9jYXRlTW9yZShDaGFyQnVmZmVyIG91dHB1dCkgeworICAgICAgICBpZiAob3V0cHV0LmNhcGFjaXR5KCkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIENoYXJCdWZmZXIuYWxsb2NhdGUoMSk7CisgICAgICAgIH0KKyAgICAgICAgQ2hhckJ1ZmZlciByZXN1bHQgPSBDaGFyQnVmZmVyLmFsbG9jYXRlKG91dHB1dC5jYXBhY2l0eSgpICogMik7CisgICAgICAgIG91dHB1dC5mbGlwKCk7CisgICAgICAgIHJlc3VsdC5wdXQob3V0cHV0KTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvZGVzIGJ5dGVzIHN0YXJ0aW5nIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZSBnaXZlbiBpbnB1dCBidWZmZXIsCisgICAgICogYW5kIHdyaXRlcyB0aGUgZXF1aXZhbGVudCBjaGFyYWN0ZXIgc2VxdWVuY2UgaW50byB0aGUgZ2l2ZW4gb3V0cHV0IGJ1ZmZlcgorICAgICAqIGZyb20gaXRzIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogPHA+CisgICAgICogVGhlIGJ1ZmZlcnMnIHBvc2l0aW9uIHdpbGwgYmUgY2hhbmdlZCB3aXRoIHRoZSByZWFkaW5nIGFuZCB3cml0aW5nCisgICAgICogb3BlcmF0aW9uLCBidXQgdGhlaXIgbGltaXRzIGFuZCBtYXJrcyB3aWxsIGJlIGtlcHQgaW50YWN0LgorICAgICAqIDxwPgorICAgICAqIEEgPGNvZGU+Q29kZXJSZXN1bHQ8L2NvZGU+IGluc3RhbmNlIHdpbGwgYmUgcmV0dXJuZWQgYWNjb3JkaW5nIHRvCisgICAgICogZm9sbG93aW5nIHJ1bGVzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0BsaW5rIENvZGVyUmVzdWx0I09WRVJGTE9XIENvZGVyUmVzdWx0Lk9WRVJGTE9XfSBpbmRpY2F0ZXMgdGhhdAorICAgICAqIGV2ZW4gdGhvdWdoIG5vdCBhbGwgb2YgdGhlIGlucHV0IGhhcyBiZWVuIHByb2Nlc3NlZCwgdGhlIGJ1ZmZlciB0aGUKKyAgICAgKiBvdXRwdXQgaXMgYmVpbmcgd3JpdHRlbiB0byBoYXMgcmVhY2hlZCBpdHMgY2FwYWNpdHkuIEluIHRoZSBldmVudCBvZiB0aGlzCisgICAgICogY29kZSBiZWluZyByZXR1cm5lZCB0aGlzIG1ldGhvZCBzaG91bGQgYmUgY2FsbGVkIG9uY2UgbW9yZSB3aXRoIGFuCisgICAgICogPGNvZGU+b3V0PC9jb2RlPiBhcmd1bWVudCB0aGF0IGhhcyBub3QgYWxyZWFkeSBiZWVuIGZpbGxlZC48L2xpPgorICAgICAqIDxsaT57QGxpbmsgQ29kZXJSZXN1bHQjVU5ERVJGTE9XIENvZGVyUmVzdWx0LlVOREVSRkxPV30gaW5kaWNhdGVzIHRoYXQKKyAgICAgKiBhcyBtYW55IGJ5dGVzIGFzIHBvc3NpYmxlIGluIHRoZSBpbnB1dCBidWZmZXIgaGF2ZSBiZWVuIGRlY29kZWQuIElmIHRoZXJlCisgICAgICogaXMgbm8gZnVydGhlciBpbnB1dCBhbmQgbm8gcmVtYWluaW5nIGJ5dGVzIGluIHRoZSBpbnB1dCBidWZmZXIgdGhlbiB0aGlzCisgICAgICogb3BlcmF0aW9uIG1heSBiZSByZWdhcmRlZCBhcyBjb21wbGV0ZS4gT3RoZXJ3aXNlLCB0aGlzIG1ldGhvZCBzaG91bGQgYmUKKyAgICAgKiBjYWxsZWQgb25jZSBtb3JlIHdpdGggYWRkaXRpb25hbCBpbnB1dC48L2xpPgorICAgICAqIDxsaT5BIHtAbGluayBDb2RlclJlc3VsdCNtYWxmb3JtZWRGb3JMZW5ndGgoaW50KSBtYWxmb3JtZWQgaW5wdXR9IHJlc3VsdAorICAgICAqIGluZGljYXRlcyB0aGF0IHNvbWUgbWFsZm9ybWVkIGlucHV0IGVycm9yIGhhcyBiZWVuIGVuY291bnRlcmVkLCBhbmQgdGhlCisgICAgICogZXJyb25lb3VzIGJ5dGVzIHN0YXJ0IGF0IHRoZSBpbnB1dCBidWZmZXIncyBwb3NpdGlvbiBhbmQgdGhlaXIgbnVtYmVyIGNhbgorICAgICAqIGJlIGdvdCBieSByZXN1bHQncyB7QGxpbmsgQ29kZXJSZXN1bHQjbGVuZ3RoKCkgbGVuZ3RofS4gVGhpcyBraW5kIG9mCisgICAgICogcmVzdWx0IGNhbiBiZSByZXR1cm5lZCBvbmx5IGlmIHRoZSBtYWxmb3JtZWQgYWN0aW9uIGlzCisgICAgICoge0BsaW5rIENvZGluZ0Vycm9yQWN0aW9uI1JFUE9SVCBDb2RpbmdFcnJvckFjdGlvbi5SRVBPUlR9LiA8L2xpPgorICAgICAqIDxsaT5BIHtAbGluayBDb2RlclJlc3VsdCN1bm1hcHBhYmxlRm9yTGVuZ3RoKGludCkgdW5tYXBwYWJsZSBjaGFyYWN0ZXJ9CisgICAgICogcmVzdWx0IGluZGljYXRlcyB0aGF0IHNvbWUgdW5tYXBwYWJsZSBjaGFyYWN0ZXIgZXJyb3IgaGFzIGJlZW4KKyAgICAgKiBlbmNvdW50ZXJlZCwgYW5kIHRoZSBlcnJvbmVvdXMgYnl0ZXMgc3RhcnQgYXQgdGhlIGlucHV0IGJ1ZmZlcidzIHBvc2l0aW9uCisgICAgICogYW5kIHRoZWlyIG51bWJlciBjYW4gYmUgZ290IGJ5IHJlc3VsdCdzCisgICAgICoge0BsaW5rIENvZGVyUmVzdWx0I2xlbmd0aCgpIGxlbmd0aH0uIFRoaXMga2luZCBvZiByZXN1bHQgY2FuIGJlIHJldHVybmVkCisgICAgICogb25seSBpZiB0aGUgdW5tYXBwYWJsZSBjaGFyYWN0ZXIgYWN0aW9uIGlzCisgICAgICoge0BsaW5rIENvZGluZ0Vycm9yQWN0aW9uI1JFUE9SVCBDb2RpbmdFcnJvckFjdGlvbi5SRVBPUlR9LiA8L2xpPgorICAgICAqIDwvdWw+CisgICAgICogPHA+CisgICAgICogVGhlIDxjb2RlPmVuZE9mSW5wdXQ8L2NvZGU+IHBhcmFtZXRlciBpbmRpY2F0ZXMgdGhhdCB0aGUgaW52b2tlciBjYW5ub3QKKyAgICAgKiBwcm92aWRlIGZ1cnRoZXIgaW5wdXQuIFRoaXMgcGFyYW1ldGVyIGlzIHRydWUgaWYgYW5kIG9ubHkgaWYgdGhlIGJ5dGVzIGluCisgICAgICogY3VycmVudCBpbnB1dCBidWZmZXIgYXJlIGFsbCBpbnB1dHMgZm9yIHRoaXMgZGVjb2Rpbmcgb3BlcmF0aW9uLiBOb3RlCisgICAgICogdGhhdCBpdCBpcyBjb21tb24gYW5kIHdvbid0IGNhdXNlIGFuIGVycm9yIGlmIHRoZSBpbnZva2VyIHNldHMgZmFsc2UgYW5kCisgICAgICogdGhlbiBjYW4ndCBwcm92aWRlIG1vcmUgaW5wdXQsIHdoaWxlIGl0IG1heSBjYXVzZSBhbiBlcnJvciBpZiB0aGUgaW52b2tlcgorICAgICAqIGFsd2F5cyBzZXRzIHRydWUgaW4gc2V2ZXJhbCBjb25zZWN1dGl2ZSBpbnZvY2F0aW9ucy4gVGhpcyB3b3VsZCBtYWtlIHRoZQorICAgICAqIHJlbWFpbmluZyBpbnB1dCB0byBiZSB0cmVhdGVkIGFzIG1hbGZvcm1lZCBpbnB1dC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBpbnZva2VzIHRoZQorICAgICAqIHtAbGluayAjZGVjb2RlTG9vcChCeXRlQnVmZmVyLCBDaGFyQnVmZmVyKSBkZWNvZGVMb29wfSBtZXRob2QgdG8KKyAgICAgKiBpbXBsZW1lbnQgdGhlIGJhc2ljIGRlY29kZSBsb2dpYyBmb3IgYSBzcGVjaWZpYyBjaGFyc2V0LgorICAgICAqCisgICAgICogQHBhcmFtIGluCisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgYnVmZmVyLgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdXRwdXQgYnVmZmVyLgorICAgICAqIEBwYXJhbSBlbmRPZklucHV0CisgICAgICogICAgICAgICAgICB0cnVlIGlmIGFsbCB0aGUgaW5wdXQgY2hhcmFjdGVycyBoYXZlIGJlZW4gcHJvdmlkZWQuCisgICAgICogQHJldHVybiBhIDxjb2RlPkNvZGVyUmVzdWx0PC9jb2RlPiBpbnN0YW5jZSB3aGljaCBpbmRpY2F0ZXMgdGhlIHJlYXNvbgorICAgICAqICAgICAgICAgb2YgdGVybWluYXRpb24uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBkZWNvZGluZyBoYXMgc3RhcnRlZCBvciBubyBtb3JlIGlucHV0IGlzIG5lZWRlZCBpbiB0aGlzCisgICAgICogICAgICAgICAgICAgZGVjb2RpbmcgcHJvZ3Jlc3MuCisgICAgICogQHRocm93cyBDb2Rlck1hbGZ1bmN0aW9uRXJyb3IKKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0BsaW5rICNkZWNvZGVMb29wKEJ5dGVCdWZmZXIsIENoYXJCdWZmZXIpIGRlY29kZUxvb3B9CisgICAgICogICAgICAgICAgICAgbWV0aG9kIHRocmV3IGFuIDxjb2RlPkJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbjwvY29kZT4gb3IKKyAgICAgKiAgICAgICAgICAgICA8Y29kZT5CdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbjwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENvZGVyUmVzdWx0IGRlY29kZShCeXRlQnVmZmVyIGluLCBDaGFyQnVmZmVyIG91dCwKKyAgICAgICAgICAgIGJvb2xlYW4gZW5kT2ZJbnB1dCkgeworICAgICAgICAvKgorICAgICAgICAgKiBzdGF0dXMgY2hlY2sKKyAgICAgICAgICovCisgICAgICAgIGlmICgoc3RhdHVzID09IEZMVVNIKSB8fCAoIWVuZE9mSW5wdXQgJiYgc3RhdHVzID09IEVORCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIENvZGVyUmVzdWx0IHJlc3VsdCA9IG51bGw7CisKKyAgICAgICAgLy8gYmVnaW4gdG8gZGVjb2RlCisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBDb2RpbmdFcnJvckFjdGlvbiBhY3Rpb24gPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSBkZWNvZGVMb29wKGluLCBvdXQpOworICAgICAgICAgICAgfSBjYXRjaCAoQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAvLyB1bmV4cGVjdGVkIGV4Y2VwdGlvbgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb2Rlck1hbGZ1bmN0aW9uRXJyb3IoZXgpOworICAgICAgICAgICAgfSBjYXRjaCAoQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgLy8gdW5leHBlY3RlZCBleGNlcHRpb24KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29kZXJNYWxmdW5jdGlvbkVycm9yKGV4KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIHJlc3VsdCBoYW5kbGluZworICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAocmVzdWx0LmlzVW5kZXJmbG93KCkpIHsKKyAgICAgICAgICAgICAgICBpbnQgcmVtYWluaW5nID0gaW4ucmVtYWluaW5nKCk7CisgICAgICAgICAgICAgICAgc3RhdHVzID0gZW5kT2ZJbnB1dCA/IEVORCA6IE9OR09JTkc7CisgICAgICAgICAgICAgICAgaWYgKGVuZE9mSW5wdXQgJiYgcmVtYWluaW5nID4gMCkgeworICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBDb2RlclJlc3VsdC5tYWxmb3JtZWRGb3JMZW5ndGgocmVtYWluaW5nKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChyZXN1bHQuaXNPdmVyZmxvdygpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIHNldCBjb2RpbmcgZXJyb3IgaGFuZGxlIGFjdGlvbgorICAgICAgICAgICAgYWN0aW9uID0gbWFsZm9ybWVkSW5wdXRBY3Rpb247CisgICAgICAgICAgICBpZiAocmVzdWx0LmlzVW5tYXBwYWJsZSgpKSB7CisgICAgICAgICAgICAgICAgYWN0aW9uID0gdW5tYXBwYWJsZUNoYXJhY3RlckFjdGlvbjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIElmIHRoZSBhY3Rpb24gaXMgSUdOT1JFIG9yIFJFUExBQ0UsIHdlIHNob3VsZCBjb250aW51ZSBkZWNvZGluZy4KKyAgICAgICAgICAgIGlmIChhY3Rpb24gPT0gQ29kaW5nRXJyb3JBY3Rpb24uUkVQTEFDRSkgeworICAgICAgICAgICAgICAgIGlmIChvdXQucmVtYWluaW5nKCkgPCByZXBsYWNlbWVudENoYXJzLmxlbmd0aCgpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBDb2RlclJlc3VsdC5PVkVSRkxPVzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgb3V0LnB1dChyZXBsYWNlbWVudENoYXJzKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKGFjdGlvbiAhPSBDb2RpbmdFcnJvckFjdGlvbi5JR05PUkUpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbi5wb3NpdGlvbihpbi5wb3NpdGlvbigpICsgcmVzdWx0Lmxlbmd0aCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIERlY29kZXMgYnl0ZXMgaW50byBjaGFyYWN0ZXJzLiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlCisgICAgICoge0BsaW5rICNkZWNvZGUoQnl0ZUJ1ZmZlciwgQ2hhckJ1ZmZlciwgYm9vbGVhbikgZGVjb2RlfSBtZXRob2QuCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2Qgd2lsbCBpbXBsZW1lbnQgdGhlIGVzc2VudGlhbCBkZWNvZGluZyBvcGVyYXRpb24sIGFuZCBpdCB3b24ndAorICAgICAqIHN0b3AgZGVjb2RpbmcgdW50aWwgZWl0aGVyIGFsbCB0aGUgaW5wdXQgYnl0ZXMgYXJlIHJlYWQsIHRoZSBvdXRwdXQKKyAgICAgKiBidWZmZXIgaXMgZmlsbGVkLCBvciBzb21lIGV4Y2VwdGlvbiBpcyBlbmNvdW50ZXJlZC4gVGhlbiBpdCB3aWxsIHJldHVybiBhCisgICAgICogPGNvZGU+Q29kZXJSZXN1bHQ8L2NvZGU+IG9iamVjdCBpbmRpY2F0aW5nIHRoZSByZXN1bHQgb2YgY3VycmVudAorICAgICAqIGRlY29kaW5nIG9wZXJhdGlvbi4gVGhlIHJ1bGVzIHRvIGNvbnN0cnVjdCB0aGUgPGNvZGU+Q29kZXJSZXN1bHQ8L2NvZGU+CisgICAgICogYXJlIHRoZSBzYW1lIGFzIGZvcgorICAgICAqIHtAbGluayAjZGVjb2RlKEJ5dGVCdWZmZXIsIENoYXJCdWZmZXIsIGJvb2xlYW4pIGRlY29kZX0uIFdoZW4gYW4KKyAgICAgKiBleGNlcHRpb24gaXMgZW5jb3VudGVyZWQgaW4gdGhlIGRlY29kaW5nIG9wZXJhdGlvbiwgbW9zdCBpbXBsZW1lbnRhdGlvbnMKKyAgICAgKiBvZiB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiBhIHJlbGV2YW50IHJlc3VsdCBvYmplY3QgdG8gdGhlCisgICAgICoge0BsaW5rICNkZWNvZGUoQnl0ZUJ1ZmZlciwgQ2hhckJ1ZmZlciwgYm9vbGVhbikgZGVjb2RlfSBtZXRob2QsIGFuZCBzb21lCisgICAgICogcGVyZm9ybWFuY2Ugb3B0aW1pemVkIGltcGxlbWVudGF0aW9uIG1heSBoYW5kbGUgdGhlIGV4Y2VwdGlvbiBhbmQKKyAgICAgKiBpbXBsZW1lbnQgdGhlIGVycm9yIGFjdGlvbiBpdHNlbGYuCisgICAgICogPHA+CisgICAgICogVGhlIGJ1ZmZlcnMgYXJlIHNjYW5uZWQgZnJvbSB0aGVpciBjdXJyZW50IHBvc2l0aW9ucywgYW5kIHRoZWlyIHBvc2l0aW9ucworICAgICAqIHdpbGwgYmUgbW9kaWZpZWQgYWNjb3JkaW5nbHksIHdoaWxlIHRoZWlyIG1hcmtzIGFuZCBsaW1pdHMgd2lsbCBiZQorICAgICAqIGludGFjdC4gQXQgbW9zdCB7QGxpbmsgQnl0ZUJ1ZmZlciNyZW1haW5pbmcoKSBpbi5yZW1haW5pbmcoKX0gY2hhcmFjdGVycworICAgICAqIHdpbGwgYmUgcmVhZCwgYW5kIHtAbGluayBDaGFyQnVmZmVyI3JlbWFpbmluZygpIG91dC5yZW1haW5pbmcoKX0gYnl0ZXMKKyAgICAgKiB3aWxsIGJlIHdyaXR0ZW4uCisgICAgICogPHA+CisgICAgICogTm90ZSB0aGF0IHNvbWUgaW1wbGVtZW50YXRpb25zIG1heSBwcmUtc2NhbiB0aGUgaW5wdXQgYnVmZmVyIGFuZCByZXR1cm4gYQorICAgICAqIDxjb2RlPkNvZGVyUmVzdWx0LlVOREVSRkxPVzwvY29kZT4gdW50aWwgaXQgcmVjZWl2ZXMgc3VmZmljaWVudCBpbnB1dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbgorICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IGJ1ZmZlci4KKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIGEgPGNvZGU+Q29kZXJSZXN1bHQ8L2NvZGU+IGluc3RhbmNlIGluZGljYXRpbmcgdGhlIHJlc3VsdC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgQ29kZXJSZXN1bHQgZGVjb2RlTG9vcChCeXRlQnVmZmVyIGluLCBDaGFyQnVmZmVyIG91dCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjaGFyc2V0IGRldGVjdGVkIGJ5IHRoaXMgZGVjb2RlcjsgdGhpcyBtZXRob2QgaXMgb3B0aW9uYWwuCisgICAgICogPHA+CisgICAgICogSWYgaW1wbGVtZW50aW5nIGFuIGF1dG8tZGV0ZWN0aW5nIGNoYXJzZXQsIHRoZW4gdGhpcyBkZWNvZGVyIHJldHVybnMgdGhlCisgICAgICogZGV0ZWN0ZWQgY2hhcnNldCBmcm9tIHRoaXMgbWV0aG9kIHdoZW4gaXQgaXMgYXZhaWxhYmxlLiBUaGUgcmV0dXJuZWQKKyAgICAgKiBjaGFyc2V0IHdpbGwgYmUgdGhlIHNhbWUgZm9yIHRoZSByZXN0IG9mIHRoZSBkZWNvZGUgb3BlcmF0aW9uLgorICAgICAqIDxwPgorICAgICAqIElmIGluc3VmZmljaWVudCBieXRlcyBoYXZlIGJlZW4gcmVhZCB0byBkZXRlcm1pbmUgdGhlIGNoYXJzZXQsIGFuCisgICAgICogPGNvZGU+SWxsZWdhbFN0YXRlRXhjZXB0aW9uPC9jb2RlPiB3aWxsIGJlIHRocm93bi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBhbHdheXMgdGhyb3dzCisgICAgICogPGNvZGU+VW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb248L2NvZGU+LCBzbyBpdCBzaG91bGQgYmUgb3ZlcnJpZGRlbgorICAgICAqIGJ5IGEgc3ViY2xhc3MgaWYgbmVlZGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2hhcnNldCBkZXRlY3RlZCBieSB0aGlzIGRlY29kZXIsIG9yIG51bGwgaWYgaXQgaXMgbm90IHlldAorICAgICAqICAgICAgICAgZGV0ZXJtaW5lZC4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBkZWNvZGVyIGRvZXMgbm90IGltcGxlbWVudCBhbiBhdXRvLWRldGVjdGluZyBjaGFyc2V0LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgaW5zdWZmaWNpZW50IGJ5dGVzIGhhdmUgYmVlbiByZWFkIHRvIGRldGVybWluZSB0aGUKKyAgICAgKiAgICAgICAgICAgICBjaGFyc2V0LgorICAgICAqLworICAgIHB1YmxpYyBDaGFyc2V0IGRldGVjdGVkQ2hhcnNldCgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmx1c2hlcyB0aGlzIGRlY29kZXIuCisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGNhbGwge0BsaW5rICNpbXBsRmx1c2goQ2hhckJ1ZmZlcikgaW1wbEZsdXNofS4gU29tZQorICAgICAqIGRlY29kZXJzIG1heSBuZWVkIHRvIHdyaXRlIHNvbWUgY2hhcmFjdGVycyB0byB0aGUgb3V0cHV0IGJ1ZmZlciB3aGVuIHRoZXkKKyAgICAgKiBoYXZlIHJlYWQgYWxsIGlucHV0IGJ5dGVzOyBzdWJjbGFzc2VzIGNhbiBvdmVycmlkZQorICAgICAqIHtAbGluayAjaW1wbEZsdXNoKENoYXJCdWZmZXIpIGltcGxGbHVzaH0gdG8gcGVyZm9ybSB0aGUgd3JpdGluZyBvcGVyYXRpb24uCisgICAgICogPHA+CisgICAgICogVGhlIG1heGltdW0gbnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXMgd29uJ3QgYmUgbGFyZ2VyIHRoYW4KKyAgICAgKiB7QGxpbmsgQ2hhckJ1ZmZlciNyZW1haW5pbmcoKSBvdXQucmVtYWluaW5nKCl9LiBJZiBzb21lIGRlY29kZXIgd2FudHMgdG8KKyAgICAgKiB3cml0ZSBtb3JlIGJ5dGVzIHRoYW4gYW4gb3V0cHV0IGJ1ZmZlcidzIHJlbWFpbmluZyBzcGFjZSBhbGxvd3MsIHRoZW4gYQorICAgICAqIDxjb2RlPkNvZGVyUmVzdWx0Lk9WRVJGTE9XPC9jb2RlPiB3aWxsIGJlIHJldHVybmVkLCBhbmQgdGhpcyBtZXRob2QKKyAgICAgKiBtdXN0IGJlIGNhbGxlZCBhZ2FpbiB3aXRoIGEgY2hhcmFjdGVyIGJ1ZmZlciB0aGF0IGhhcyBtb3JlIHJlbWFpbmluZworICAgICAqIHNwYWNlLiBPdGhlcndpc2UgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4KKyAgICAgKiA8Y29kZT5Db2RlclJlc3VsdC5VTkRFUkZMT1c8L2NvZGU+LCB3aGljaCBtZWFucyBvbmUgZGVjb2RpbmcgcHJvY2VzcworICAgICAqIGhhcyBiZWVuIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkuCisgICAgICogPHA+CisgICAgICogRHVyaW5nIHRoZSBmbHVzaCwgdGhlIG91dHB1dCBidWZmZXIncyBwb3NpdGlvbiB3aWxsIGJlIGNoYW5nZWQKKyAgICAgKiBhY2NvcmRpbmdseSwgd2hpbGUgaXRzIG1hcmsgYW5kIGxpbWl0IHdpbGwgYmUgaW50YWN0LgorICAgICAqCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgdGhlIGdpdmVuIG91dHB1dCBidWZmZXIuCisgICAgICogQHJldHVybiA8Y29kZT5Db2RlclJlc3VsdC5VTkRFUkZMT1c8L2NvZGU+IG9yCisgICAgICogICAgICAgICA8Y29kZT5Db2RlclJlc3VsdC5PVkVSRkxPVzwvY29kZT4uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGRlY29kZXIgaGFzbid0IHJlYWQgYWxsIGlucHV0IGJ5dGVzIGR1cmluZyBvbmUKKyAgICAgKiAgICAgICAgICAgICBkZWNvZGluZyBwcm9jZXNzLCB3aGljaCBtZWFucyBuZWl0aGVyIGFmdGVyIGNhbGxpbmcKKyAgICAgKiAgICAgICAgICAgICB7QGxpbmsgI2RlY29kZShCeXRlQnVmZmVyKSBkZWNvZGUoQnl0ZUJ1ZmZlcil9IG5vciBhZnRlcgorICAgICAqICAgICAgICAgICAgIGNhbGxpbmcge0BsaW5rICNkZWNvZGUoQnl0ZUJ1ZmZlciwgQ2hhckJ1ZmZlciwgYm9vbGVhbikKKyAgICAgKiAgICAgICAgICAgICBkZWNvZGUoQnl0ZUJ1ZmZlciwgQ2hhckJ1ZmZlciwgYm9vbGVhbil9IHdpdGggdHJ1ZSBhcyB2YWx1ZQorICAgICAqICAgICAgICAgICAgIGZvciB0aGUgbGFzdCBib29sZWFuIHBhcmFtZXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQ29kZXJSZXN1bHQgZmx1c2goQ2hhckJ1ZmZlciBvdXQpIHsKKyAgICAgICAgaWYgKHN0YXR1cyAhPSBFTkQgJiYgc3RhdHVzICE9IElOSVQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBDb2RlclJlc3VsdCByZXN1bHQgPSBpbXBsRmx1c2gob3V0KTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBDb2RlclJlc3VsdC5VTkRFUkZMT1cpIHsKKyAgICAgICAgICAgIHN0YXR1cyA9IEZMVVNIOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmx1c2hlcyB0aGlzIGRlY29kZXIuIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZyBhbmQgYWx3YXlzCisgICAgICogcmV0dXJucyA8Y29kZT5Db2RlclJlc3VsdC5VTkRFUkZMT1c8L2NvZGU+OyB0aGlzIG1ldGhvZCBjYW4gYmUKKyAgICAgKiBvdmVycmlkZGVuIGlmIG5lZWRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdXRwdXQgYnVmZmVyLgorICAgICAqIEByZXR1cm4gPGNvZGU+Q29kZXJSZXN1bHQuVU5ERVJGTE9XPC9jb2RlPiBvcgorICAgICAqICAgICAgICAgPGNvZGU+Q29kZXJSZXN1bHQuT1ZFUkZMT1c8L2NvZGU+LgorICAgICAqLworICAgIHByb3RlY3RlZCBDb2RlclJlc3VsdCBpbXBsRmx1c2goQ2hhckJ1ZmZlciBvdXQpIHsKKyAgICAgICAgcmV0dXJuIENvZGVyUmVzdWx0LlVOREVSRkxPVzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGF0IHRoaXMgZGVjb2RlcidzIDxjb2RlPkNvZGluZ0Vycm9yQWN0aW9uPC9jb2RlPiBzcGVjaWZpZWQKKyAgICAgKiBmb3IgbWFsZm9ybWVkIGlucHV0IGVycm9yIGhhcyBiZWVuIGNoYW5nZWQuIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uCisgICAgICogZG9lcyBub3RoaW5nOyB0aGlzIG1ldGhvZCBjYW4gYmUgb3ZlcnJpZGRlbiBpZiBuZWVkZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3QWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgbmV3IGFjdGlvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBpbXBsT25NYWxmb3JtZWRJbnB1dChDb2RpbmdFcnJvckFjdGlvbiBuZXdBY3Rpb24pIHsKKyAgICAgICAgLy8gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyBlbXB0eQorICAgIH0KKworICAgIC8qKgorICAgICAqIE5vdGlmaWVzIHRoYXQgdGhpcyBkZWNvZGVyJ3MgPGNvZGU+Q29kaW5nRXJyb3JBY3Rpb248L2NvZGU+IHNwZWNpZmllZAorICAgICAqIGZvciB1bm1hcHBhYmxlIGNoYXJhY3RlciBlcnJvciBoYXMgYmVlbiBjaGFuZ2VkLiBUaGUgZGVmYXVsdAorICAgICAqIGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZzsgdGhpcyBtZXRob2QgY2FuIGJlIG92ZXJyaWRkZW4gaWYgbmVlZGVkLgorICAgICAqCisgICAgICogQHBhcmFtIG5ld0FjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBhY3Rpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgaW1wbE9uVW5tYXBwYWJsZUNoYXJhY3RlcihDb2RpbmdFcnJvckFjdGlvbiBuZXdBY3Rpb24pIHsKKyAgICAgICAgLy8gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyBlbXB0eQorICAgIH0KKworICAgIC8qKgorICAgICAqIE5vdGlmaWVzIHRoYXQgdGhpcyBkZWNvZGVyJ3MgcmVwbGFjZW1lbnQgaGFzIGJlZW4gY2hhbmdlZC4gVGhlIGRlZmF1bHQKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdGhpbmc7IHRoaXMgbWV0aG9kIGNhbiBiZSBvdmVycmlkZGVuIGlmIG5lZWRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdSZXBsYWNlbWVudAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyByZXBsYWNlbWVudCBzdHJpbmcuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgaW1wbFJlcGxhY2VXaXRoKFN0cmluZyBuZXdSZXBsYWNlbWVudCkgeworICAgICAgICAvLyBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGlzIGVtcHR5CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzZXQgdGhpcyBkZWNvZGVyJ3MgY2hhcnNldCByZWxhdGVkIHN0YXRlLiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbgorICAgICAqIGRvZXMgbm90aGluZzsgdGhpcyBtZXRob2QgY2FuIGJlIG92ZXJyaWRkZW4gaWYgbmVlZGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGltcGxSZXNldCgpIHsKKyAgICAgICAgLy8gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyBlbXB0eQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgZGVjb2RlciBpbXBsZW1lbnRzIGFuIGF1dG8tZGV0ZWN0aW5nIGNoYXJzZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoaXMgZGVjb2RlciBpbXBsZW1lbnRzIGFuIGF1dG8tZGV0ZWN0aW5nCisgICAgICogICAgICAgICBjaGFyc2V0LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQXV0b0RldGVjdGluZygpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgZGVjb2RlciBoYXMgZGV0ZWN0ZWQgYSBjaGFyc2V0OyB0aGlzIG1ldGhvZCBpcworICAgICAqIG9wdGlvbmFsLgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgZGVjb2RlciBpbXBsZW1lbnRzIGFuIGF1dG8tZGV0ZWN0aW5nIGNoYXJzZXQsIHRoZW4gdGhpcyBtZXRob2QKKyAgICAgKiBtYXkgc3RhcnQgdG8gcmV0dXJuIHRydWUgZHVyaW5nIGRlY29kaW5nIG9wZXJhdGlvbiB0byBpbmRpY2F0ZSB0aGF0IGEKKyAgICAgKiBjaGFyc2V0IGhhcyBiZWVuIGRldGVjdGVkIGluIHRoZSBpbnB1dCBieXRlcyBhbmQgdGhhdCB0aGUgY2hhcnNldCBjYW4gYmUKKyAgICAgKiByZXRyaWV2ZWQgYnkgaW52b2tpbmcgdGhlIHtAbGluayAjZGV0ZWN0ZWRDaGFyc2V0KCkgZGV0ZWN0ZWRDaGFyc2V0fQorICAgICAqIG1ldGhvZC4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlIHRoYXQgYSBkZWNvZGVyIHRoYXQgaW1wbGVtZW50cyBhbiBhdXRvLWRldGVjdGluZyBjaGFyc2V0IG1heSBzdGlsbAorICAgICAqIHN1Y2NlZWQgaW4gZGVjb2RpbmcgYSBwb3J0aW9uIG9mIHRoZSBnaXZlbiBpbnB1dCBldmVuIHdoZW4gaXQgaXMgdW5hYmxlCisgICAgICogdG8gZGV0ZWN0IHRoZSBjaGFyc2V0LiBGb3IgdGhpcyByZWFzb24gdXNlcnMgc2hvdWxkIGJlIGF3YXJlIHRoYXQgYQorICAgICAqIDxjb2RlPmZhbHNlPC9jb2RlPiByZXR1cm4gdmFsdWUgZG9lcyBub3QgaW5kaWNhdGUgdGhhdCBubyBkZWNvZGluZyB0b29rCisgICAgICogcGxhY2UuCisgICAgICogPHA+CisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gYWx3YXlzIHRocm93cyBhbgorICAgICAqIDxjb2RlPlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uPC9jb2RlPjsgaXQgc2hvdWxkIGJlIG92ZXJyaWRkZW4gYnkKKyAgICAgKiBhIHN1YmNsYXNzIGlmIG5lZWRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhpcyBkZWNvZGVyIGhhcyBkZXRlY3RlZCBhIGNoYXJzZXQuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgZGVjb2RlciBkb2Vzbid0IGltcGxlbWVudCBhbiBhdXRvLWRldGVjdGluZyBjaGFyc2V0LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQ2hhcnNldERldGVjdGVkKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgZGVjb2RlcidzIDxjb2RlPkNvZGluZ0Vycm9yQWN0aW9uPC9jb2RlPiB3aGVuIG1hbGZvcm1lZCBpbnB1dAorICAgICAqIG9jY3VycmVkIGR1cmluZyB0aGUgZGVjb2RpbmcgcHJvY2Vzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29kaW5nRXJyb3JBY3Rpb24gbWFsZm9ybWVkSW5wdXRBY3Rpb24oKSB7CisgICAgICAgIHJldHVybiBtYWxmb3JtZWRJbnB1dEFjdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIHdoaWNoIGNhbiBiZSBjcmVhdGVkIGJ5IHRoaXMKKyAgICAgKiBkZWNvZGVyIGZvciBvbmUgaW5wdXQgYnl0ZSwgbXVzdCBiZSBwb3NpdGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgZmxvYXQgbWF4Q2hhcnNQZXJCeXRlKCkgeworICAgICAgICByZXR1cm4gbWF4Q2hhcnNQZXJCeXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhpcyBkZWNvZGVyJ3MgYWN0aW9uIG9uIG1hbGZvcm1lZCBpbnB1dCBlcnJvcnMuCisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGNhbGwgdGhlCisgICAgICoge0BsaW5rICNpbXBsT25NYWxmb3JtZWRJbnB1dChDb2RpbmdFcnJvckFjdGlvbikgaW1wbE9uTWFsZm9ybWVkSW5wdXR9CisgICAgICogbWV0aG9kIHdpdGggdGhlIGdpdmVuIG5ldyBhY3Rpb24gYXMgYXJndW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3QWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgbmV3IGFjdGlvbiBvbiBtYWxmb3JtZWQgaW5wdXQgZXJyb3IuCisgICAgICogQHJldHVybiB0aGlzIGRlY29kZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbmV3QWN0aW9ufSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENoYXJzZXREZWNvZGVyIG9uTWFsZm9ybWVkSW5wdXQoQ29kaW5nRXJyb3JBY3Rpb24gbmV3QWN0aW9uKSB7CisgICAgICAgIGlmIChuZXdBY3Rpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIG1hbGZvcm1lZElucHV0QWN0aW9uID0gbmV3QWN0aW9uOworICAgICAgICBpbXBsT25NYWxmb3JtZWRJbnB1dChuZXdBY3Rpb24pOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoaXMgZGVjb2RlcidzIGFjdGlvbiBvbiB1bm1hcHBhYmxlIGNoYXJhY3RlciBlcnJvcnMuCisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGNhbGwgdGhlCisgICAgICoge0BsaW5rICNpbXBsT25Vbm1hcHBhYmxlQ2hhcmFjdGVyKENvZGluZ0Vycm9yQWN0aW9uKSBpbXBsT25Vbm1hcHBhYmxlQ2hhcmFjdGVyfQorICAgICAqIG1ldGhvZCB3aXRoIHRoZSBnaXZlbiBuZXcgYWN0aW9uIGFzIGFyZ3VtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIG5ld0FjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBhY3Rpb24gb24gdW5tYXBwYWJsZSBjaGFyYWN0ZXIgZXJyb3IuCisgICAgICogQHJldHVybiB0aGlzIGRlY29kZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbmV3QWN0aW9ufSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENoYXJzZXREZWNvZGVyIG9uVW5tYXBwYWJsZUNoYXJhY3RlcihDb2RpbmdFcnJvckFjdGlvbiBuZXdBY3Rpb24pIHsKKyAgICAgICAgaWYgKG5ld0FjdGlvbiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdW5tYXBwYWJsZUNoYXJhY3RlckFjdGlvbiA9IG5ld0FjdGlvbjsKKyAgICAgICAgaW1wbE9uVW5tYXBwYWJsZUNoYXJhY3RlcihuZXdBY3Rpb24pOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByZXBsYWNlbWVudCBzdHJpbmcsIHdoaWNoIGlzIG5ldmVyIG51bGwgb3IgZW1wdHkuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyByZXBsYWNlbWVudCgpIHsKKyAgICAgICAgcmV0dXJuIHJlcGxhY2VtZW50Q2hhcnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmV3IHJlcGxhY2VtZW50IHN0cmluZy4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIGZpcnN0IGNoZWNrcyB0aGUgZ2l2ZW4gcmVwbGFjZW1lbnQncyB2YWxpZGl0eSwgdGhlbiBjaGFuZ2VzCisgICAgICogdGhlIHJlcGxhY2VtZW50IHZhbHVlLCBhbmQgYXQgbGFzdCBjYWxscyB0aGUKKyAgICAgKiB7QGxpbmsgI2ltcGxSZXBsYWNlV2l0aChTdHJpbmcpIGltcGxSZXBsYWNlV2l0aH0gbWV0aG9kIHdpdGggdGhlIGdpdmVuCisgICAgICogbmV3IHJlcGxhY2VtZW50IGFzIGFyZ3VtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHJlcGxhY2VtZW50CisgICAgICogICAgICAgICAgICB0aGUgcmVwbGFjZW1lbnQgc3RyaW5nLCBjYW5ub3QgYmUgbnVsbCBvciBlbXB0eS4gSXRzIGxlbmd0aAorICAgICAqICAgICAgICAgICAgY2Fubm90IGJlIGxhcmdlciB0aGFuIHtAbGluayAjbWF4Q2hhcnNQZXJCeXRlKCl9LgorICAgICAqIEByZXR1cm4gdGhpcyBkZWNvZGVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIHJlcGxhY2VtZW50IGNhbm5vdCBzYXRpc2Z5IHRoZSByZXF1aXJlbWVudAorICAgICAqICAgICAgICAgICAgIG1lbnRpb25lZCBhYm92ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQ2hhcnNldERlY29kZXIgcmVwbGFjZVdpdGgoU3RyaW5nIHJlcGxhY2VtZW50KSB7CisgICAgICAgIGlmIChyZXBsYWNlbWVudCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJyZXBsYWNlbWVudCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJlcGxhY2VtZW50LmlzRW1wdHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicmVwbGFjZW1lbnQuaXNFbXB0eSgpIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJlcGxhY2VtZW50Lmxlbmd0aCgpID4gbWF4Q2hhcnNQZXJCeXRlKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInJlcGxhY2VtZW50IGxlbmd0aCA+IG1heENoYXJzUGVyQnl0ZTogIiArCisgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50Lmxlbmd0aCgpICsgIiA+ICIgKyBtYXhDaGFyc1BlckJ5dGUoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmVwbGFjZW1lbnRDaGFycyA9IHJlcGxhY2VtZW50OworICAgICAgICBpbXBsUmVwbGFjZVdpdGgocmVwbGFjZW1lbnQpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhpcyBkZWNvZGVyLiBUaGlzIG1ldGhvZCB3aWxsIHJlc2V0IHRoZSBpbnRlcm5hbCBzdGF0dXMsIGFuZCB0aGVuCisgICAgICogY2FsbHMgPGNvZGU+aW1wbFJlc2V0KCk8L2NvZGU+IHRvIHJlc2V0IGFueSBzdGF0dXMgcmVsYXRlZCB0byB0aGUKKyAgICAgKiBzcGVjaWZpYyBjaGFyc2V0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIGRlY29kZXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENoYXJzZXREZWNvZGVyIHJlc2V0KCkgeworICAgICAgICBzdGF0dXMgPSBJTklUOworICAgICAgICBpbXBsUmVzZXQoKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIGRlY29kZXIncyA8Y29kZT5Db2RpbmdFcnJvckFjdGlvbjwvY29kZT4gd2hlbiBhbiB1bm1hcHBhYmxlCisgICAgICogY2hhcmFjdGVyIGVycm9yIG9jY3VycmVkIGR1cmluZyB0aGUgZGVjb2RpbmcgcHJvY2Vzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29kaW5nRXJyb3JBY3Rpb24gdW5tYXBwYWJsZUNoYXJhY3RlckFjdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIHVubWFwcGFibGVDaGFyYWN0ZXJBY3Rpb247CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldERlY29kZXJJQ1UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L0NoYXJzZXREZWNvZGVySUNVLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2FkNDZkNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L0NoYXJzZXREZWNvZGVySUNVLmphdmEKQEAgLTAsMCArMSwyMjEgQEAKKy8qKgorKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorKiBDb3B5cmlnaHQgKEMpIDE5OTYtMjAwNiwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgICAgKgorKiBvdGhlcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgorKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorKgorKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorKi8KKyAvKioKKyAgKiBBIEpOSSBpbnRlcmZhY2UgZm9yIElDVSBjb252ZXJ0ZXJzLgorICAqCisgICoKKyAgKiBAYXV0aG9yIFJhbSBWaXN3YW5hZGhhLCBJQk0KKyAgKi8KK3BhY2thZ2UgamF2YS5uaW8uY2hhcnNldDsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uQ2hhckJ1ZmZlcjsKK2ltcG9ydCBsaWJjb3JlLmljdS5FcnJvckNvZGU7CitpbXBvcnQgbGliY29yZS5pY3UuTmF0aXZlQ29udmVydGVyOworaW1wb3J0IGxpYmNvcmUudXRpbC5FbXB0eUFycmF5OworCitmaW5hbCBjbGFzcyBDaGFyc2V0RGVjb2RlcklDVSBleHRlbmRzIENoYXJzZXREZWNvZGVyIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0NIQVJTX1BFUl9CWVRFID0gMjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTlBVVF9PRkZTRVQgPSAwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBPVVRQVVRfT0ZGU0VUID0gMTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5WQUxJRF9CWVRFUyA9IDI7CisgICAgLyoKKyAgICAgKiBkYXRhW0lOUFVUX09GRlNFVF0gICA9IG9uIGlucHV0IGNvbnRhaW5zIHRoZSBzdGFydCBvZiBpbnB1dCBhbmQgb24gb3V0cHV0IHRoZSBudW1iZXIgb2YgaW5wdXQgYnl0ZXMgY29uc3VtZWQKKyAgICAgKiBkYXRhW09VVFBVVF9PRkZTRVRdICA9IG9uIGlucHV0IGNvbnRhaW5zIHRoZSBzdGFydCBvZiBvdXRwdXQgYW5kIG9uIG91dHB1dCB0aGUgbnVtYmVyIG9mIG91dHB1dCBjaGFycyB3cml0dGVuCisgICAgICogZGF0YVtJTlZBTElEX0JZVEVTXSAgPSBudW1iZXIgb2YgaW52YWxpZCBieXRlcworICAgICAqLworICAgIHByaXZhdGUgaW50W10gZGF0YSA9IG5ldyBpbnRbM107CisKKyAgICAvKiBoYW5kbGUgdG8gdGhlIElDVSBjb252ZXJ0ZXIgdGhhdCBpcyBvcGVuZWQgKi8KKyAgICBwcml2YXRlIGxvbmcgY29udmVydGVySGFuZGxlID0gMDsKKworICAgIHByaXZhdGUgYnl0ZVtdIGlucHV0ID0gbnVsbDsKKyAgICBwcml2YXRlIGNoYXJbXSBvdXRwdXQ9IG51bGw7CisKKyAgICBwcml2YXRlIGJ5dGVbXSBhbGxvY2F0ZWRJbnB1dCA9IG51bGw7CisgICAgcHJpdmF0ZSBjaGFyW10gYWxsb2NhdGVkT3V0cHV0ID0gbnVsbDsKKworICAgIC8vIFRoZXNlIGluc3RhbmNlIHZhcmlhYmxlcyBhcmUgYWx3YXlzIGFzc2lnbmVkIGluIHRoZSBtZXRob2RzIGJlZm9yZSBiZWluZyB1c2VkLiBUaGlzIGNsYXNzCisgICAgLy8gaXMgaW5oZXJlbnRseSB0aHJlYWQtdW5zYWZlIHNvIHdlIGRvbid0IGhhdmUgdG8gd29ycnkgYWJvdXQgc3luY2hyb25pemF0aW9uLgorICAgIHByaXZhdGUgaW50IGluRW5kOworICAgIHByaXZhdGUgaW50IG91dEVuZDsKKyAgICBwcml2YXRlIGludCBlYzsKKworICAgIHB1YmxpYyBzdGF0aWMgQ2hhcnNldERlY29kZXJJQ1UgbmV3SW5zdGFuY2UoQ2hhcnNldCBjcywgU3RyaW5nIGljdUNhbm9uaWNhbE5hbWUpIHsKKyAgICAgICAgLy8gVGhpcyBjb21wbGV4aXR5IGlzIG5lY2Vzc2FyeSB0byBlbnN1cmUgdGhhdCBldmVuIGlmIHRoZSBjb25zdHJ1Y3Rvciwgc3VwZXJjbGFzcworICAgICAgICAvLyBjb25zdHJ1Y3Rvciwgb3IgY2FsbCB0byB1cGRhdGVDYWxsYmFjayB0aHJvdywgd2Ugc3RpbGwgZnJlZSB0aGUgbmF0aXZlIHBlZXIuCisgICAgICAgIGxvbmcgYWRkcmVzcyA9IDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGRyZXNzID0gTmF0aXZlQ29udmVydGVyLm9wZW5Db252ZXJ0ZXIoaWN1Q2Fub25pY2FsTmFtZSk7CisgICAgICAgICAgICBmbG9hdCBhdmVyYWdlQ2hhcnNQZXJCeXRlID0gTmF0aXZlQ29udmVydGVyLmdldEF2ZUNoYXJzUGVyQnl0ZShhZGRyZXNzKTsKKyAgICAgICAgICAgIENoYXJzZXREZWNvZGVySUNVIHJlc3VsdCA9IG5ldyBDaGFyc2V0RGVjb2RlcklDVShjcywgYXZlcmFnZUNoYXJzUGVyQnl0ZSwgYWRkcmVzcyk7CisgICAgICAgICAgICBhZGRyZXNzID0gMDsgLy8gQ2hhcnNldERlY29kZXJJQ1UgaGFzIHRha2VuIG93bmVyc2hpcDsgaXRzIGZpbmFsaXplciB3aWxsIGRvIHRoZSBmcmVlLgorICAgICAgICAgICAgcmVzdWx0LnVwZGF0ZUNhbGxiYWNrKCk7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGFkZHJlc3MgIT0gMCkgeworICAgICAgICAgICAgICAgIE5hdGl2ZUNvbnZlcnRlci5jbG9zZUNvbnZlcnRlcihhZGRyZXNzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgQ2hhcnNldERlY29kZXJJQ1UoQ2hhcnNldCBjcywgZmxvYXQgYXZlcmFnZUNoYXJzUGVyQnl0ZSwgbG9uZyBhZGRyZXNzKSB7CisgICAgICAgIHN1cGVyKGNzLCBhdmVyYWdlQ2hhcnNQZXJCeXRlLCBNQVhfQ0hBUlNfUEVSX0JZVEUpOworICAgICAgICB0aGlzLmNvbnZlcnRlckhhbmRsZSA9IGFkZHJlc3M7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGltcGxSZXBsYWNlV2l0aChTdHJpbmcgbmV3UmVwbGFjZW1lbnQpIHsKKyAgICAgICAgdXBkYXRlQ2FsbGJhY2soKTsKKyAgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBmaW5hbCB2b2lkIGltcGxPbk1hbGZvcm1lZElucHV0KENvZGluZ0Vycm9yQWN0aW9uIG5ld0FjdGlvbikgeworICAgICAgICB1cGRhdGVDYWxsYmFjaygpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgZmluYWwgdm9pZCBpbXBsT25Vbm1hcHBhYmxlQ2hhcmFjdGVyKENvZGluZ0Vycm9yQWN0aW9uIG5ld0FjdGlvbikgeworICAgICAgICB1cGRhdGVDYWxsYmFjaygpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB1cGRhdGVDYWxsYmFjaygpIHsKKyAgICAgICAgZWMgPSBOYXRpdmVDb252ZXJ0ZXIuc2V0Q2FsbGJhY2tEZWNvZGUoY29udmVydGVySGFuZGxlLCB0aGlzKTsKKyAgICAgICAgaWYgKEVycm9yQ29kZS5pc0ZhaWx1cmUoZWMpKSB7CisgICAgICAgICAgICB0aHJvdyBFcnJvckNvZGUudGhyb3dFeGNlcHRpb24oZWMpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGltcGxSZXNldCgpIHsKKyAgICAgICAgTmF0aXZlQ29udmVydGVyLnJlc2V0Qnl0ZVRvQ2hhcihjb252ZXJ0ZXJIYW5kbGUpOworICAgICAgICBkYXRhW0lOUFVUX09GRlNFVF0gPSAwOworICAgICAgICBkYXRhW09VVFBVVF9PRkZTRVRdID0gMDsKKyAgICAgICAgZGF0YVtJTlZBTElEX0JZVEVTXSA9IDA7CisgICAgICAgIG91dHB1dCA9IG51bGw7CisgICAgICAgIGlucHV0ID0gbnVsbDsKKyAgICAgICAgYWxsb2NhdGVkSW5wdXQgPSBudWxsOworICAgICAgICBhbGxvY2F0ZWRPdXRwdXQgPSBudWxsOworICAgICAgICBlYyA9IDA7CisgICAgICAgIGluRW5kID0gMDsKKyAgICAgICAgb3V0RW5kID0gMDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIGZpbmFsIENvZGVyUmVzdWx0IGltcGxGbHVzaChDaGFyQnVmZmVyIG91dCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gSUNVIG5lZWRzIHRvIHNlZSBhbiBlbXB0eSBpbnB1dC4KKyAgICAgICAgICAgIGlucHV0ID0gRW1wdHlBcnJheS5CWVRFOworICAgICAgICAgICAgaW5FbmQgPSAwOworICAgICAgICAgICAgZGF0YVtJTlBVVF9PRkZTRVRdID0gMDsKKworICAgICAgICAgICAgZGF0YVtPVVRQVVRfT0ZGU0VUXSA9IGdldEFycmF5KG91dCk7CisgICAgICAgICAgICBkYXRhW0lOVkFMSURfQllURVNdID0gMDsgLy8gTWFrZSBzdXJlIHdlIGRvbid0IHNlZSBlYXJsaWVyIGVycm9ycy4KKworICAgICAgICAgICAgZWMgPSBOYXRpdmVDb252ZXJ0ZXIuZGVjb2RlKGNvbnZlcnRlckhhbmRsZSwgaW5wdXQsIGluRW5kLCBvdXRwdXQsIG91dEVuZCwgZGF0YSwgdHJ1ZSk7CisgICAgICAgICAgICBpZiAoRXJyb3JDb2RlLmlzRmFpbHVyZShlYykpIHsKKyAgICAgICAgICAgICAgICBpZiAoZWMgPT0gRXJyb3JDb2RlLlVfQlVGRkVSX09WRVJGTE9XX0VSUk9SKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBDb2RlclJlc3VsdC5PVkVSRkxPVzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVjID09IEVycm9yQ29kZS5VX1RSVU5DQVRFRF9DSEFSX0ZPVU5EKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhW0lOUFVUX09GRlNFVF0gPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29kZXJSZXN1bHQubWFsZm9ybWVkRm9yTGVuZ3RoKGRhdGFbSU5QVVRfT0ZGU0VUXSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvckNvZGUudGhyb3dFeGNlcHRpb24oZWMpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBDb2RlclJlc3VsdC5VTkRFUkZMT1c7CisgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHNldFBvc2l0aW9uKG91dCk7CisgICAgICAgICAgICBpbXBsUmVzZXQoKTsKKyAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBDb2RlclJlc3VsdCBkZWNvZGVMb29wKEJ5dGVCdWZmZXIgaW4sIENoYXJCdWZmZXIgb3V0KSB7CisgICAgICAgIGlmICghaW4uaGFzUmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBDb2RlclJlc3VsdC5VTkRFUkZMT1c7CisgICAgICAgIH0KKworICAgICAgICBkYXRhW0lOUFVUX09GRlNFVF0gPSBnZXRBcnJheShpbik7CisgICAgICAgIGRhdGFbT1VUUFVUX09GRlNFVF09IGdldEFycmF5KG91dCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVjID0gTmF0aXZlQ29udmVydGVyLmRlY29kZShjb252ZXJ0ZXJIYW5kbGUsIGlucHV0LCBpbkVuZCwgb3V0cHV0LCBvdXRFbmQsIGRhdGEsIGZhbHNlKTsKKyAgICAgICAgICAgIGlmIChlYyA9PSBFcnJvckNvZGUuVV9CVUZGRVJfT1ZFUkZMT1dfRVJST1IpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gQ29kZXJSZXN1bHQuT1ZFUkZMT1c7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGVjID09IEVycm9yQ29kZS5VX0lOVkFMSURfQ0hBUl9GT1VORCkgeworICAgICAgICAgICAgICAgIHJldHVybiBDb2RlclJlc3VsdC51bm1hcHBhYmxlRm9yTGVuZ3RoKGRhdGFbSU5WQUxJRF9CWVRFU10pOworICAgICAgICAgICAgfSBlbHNlIGlmIChlYyA9PSBFcnJvckNvZGUuVV9JTExFR0FMX0NIQVJfRk9VTkQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gQ29kZXJSZXN1bHQubWFsZm9ybWVkRm9yTGVuZ3RoKGRhdGFbSU5WQUxJRF9CWVRFU10pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gRGVjb2Rpbmcgc3VjY2VlZGVkOiBnaXZlIHVzIG1vcmUgZGF0YS4KKyAgICAgICAgICAgIHJldHVybiBDb2RlclJlc3VsdC5VTkRFUkZMT1c7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzZXRQb3NpdGlvbihpbik7CisgICAgICAgICAgICBzZXRQb3NpdGlvbihvdXQpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOYXRpdmVDb252ZXJ0ZXIuY2xvc2VDb252ZXJ0ZXIoY29udmVydGVySGFuZGxlKTsKKyAgICAgICAgICAgIGNvbnZlcnRlckhhbmRsZSA9IDA7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzdXBlci5maW5hbGl6ZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgZ2V0QXJyYXkoQ2hhckJ1ZmZlciBvdXQpIHsKKyAgICAgICAgaWYgKG91dC5oYXNBcnJheSgpKSB7CisgICAgICAgICAgICBvdXRwdXQgPSBvdXQuYXJyYXkoKTsKKyAgICAgICAgICAgIG91dEVuZCA9IG91dC5hcnJheU9mZnNldCgpICsgb3V0LmxpbWl0KCk7CisgICAgICAgICAgICByZXR1cm4gb3V0LmFycmF5T2Zmc2V0KCkgKyBvdXQucG9zaXRpb24oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG91dEVuZCA9IG91dC5yZW1haW5pbmcoKTsKKyAgICAgICAgICAgIGlmIChhbGxvY2F0ZWRPdXRwdXQgPT0gbnVsbCB8fCBvdXRFbmQgPiBhbGxvY2F0ZWRPdXRwdXQubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgYWxsb2NhdGVkT3V0cHV0ID0gbmV3IGNoYXJbb3V0RW5kXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIFRoZSBhcnJheSdzIHN0YXJ0IHBvc2l0aW9uIGlzIDAuCisgICAgICAgICAgICBvdXRwdXQgPSBhbGxvY2F0ZWRPdXRwdXQ7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgIGludCBnZXRBcnJheShCeXRlQnVmZmVyIGluKSB7CisgICAgICAgIGlmIChpbi5oYXNBcnJheSgpKSB7CisgICAgICAgICAgICBpbnB1dCA9IGluLmFycmF5KCk7CisgICAgICAgICAgICBpbkVuZCA9IGluLmFycmF5T2Zmc2V0KCkgKyBpbi5saW1pdCgpOworICAgICAgICAgICAgcmV0dXJuIGluLmFycmF5T2Zmc2V0KCkgKyBpbi5wb3NpdGlvbigpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW5FbmQgPSBpbi5yZW1haW5pbmcoKTsKKyAgICAgICAgICAgIGlmIChhbGxvY2F0ZWRJbnB1dCA9PSBudWxsIHx8IGluRW5kID4gYWxsb2NhdGVkSW5wdXQubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgYWxsb2NhdGVkSW5wdXQgPSBuZXcgYnl0ZVtpbkVuZF07CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBDb3B5IHRoZSBpbnB1dCBidWZmZXIgaW50byB0aGUgYWxsb2NhdGVkIGFycmF5LgorICAgICAgICAgICAgaW50IHBvcyA9IGluLnBvc2l0aW9uKCk7CisgICAgICAgICAgICBpbi5nZXQoYWxsb2NhdGVkSW5wdXQsIDAsIGluRW5kKTsKKyAgICAgICAgICAgIGluLnBvc2l0aW9uKHBvcyk7CisgICAgICAgICAgICAvLyBUaGUgYXJyYXkncyBzdGFydCBwb3NpdGlvbiBpcyAwLgorICAgICAgICAgICAgaW5wdXQgPSBhbGxvY2F0ZWRJbnB1dDsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNldFBvc2l0aW9uKENoYXJCdWZmZXIgb3V0KSB7CisgICAgICAgIGlmIChvdXQuaGFzQXJyYXkoKSkgeworICAgICAgICAgICAgb3V0LnBvc2l0aW9uKG91dC5wb3NpdGlvbigpICsgZGF0YVtPVVRQVVRfT0ZGU0VUXSAtIG91dC5hcnJheU9mZnNldCgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG91dC5wdXQob3V0cHV0LCAwLCBkYXRhW09VVFBVVF9PRkZTRVRdKTsKKyAgICAgICAgfQorICAgICAgICAvLyByZWxlYXNlIHJlZmVyZW5jZSB0byBvdXRwdXQgYXJyYXksIHdoaWNoIG1heSBub3QgYmUgb3VycworICAgICAgICBvdXRwdXQgPSBudWxsOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzZXRQb3NpdGlvbihCeXRlQnVmZmVyIGluKSB7CisgICAgICAgIGluLnBvc2l0aW9uKGluLnBvc2l0aW9uKCkgKyBkYXRhW0lOUFVUX09GRlNFVF0pOworICAgICAgICAvLyByZWxlYXNlIHJlZmVyZW5jZSB0byBpbnB1dCBhcnJheSwgd2hpY2ggbWF5IG5vdCBiZSBvdXJzCisgICAgICAgIGlucHV0ID0gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0RW5jb2Rlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldEVuY29kZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOGIyY2I4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldEVuY29kZXIuamF2YQpAQCAtMCwwICsxLDc0MSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFyc2V0OworCitpbXBvcnQgamF2YS5uaW8uQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uQ2hhckJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIFRyYW5zZm9ybXMgYSBzZXF1ZW5jZSBvZiAxNi1iaXQgSmF2YSBjaGFyYWN0ZXJzIHRvIGEgYnl0ZSBzZXF1ZW5jZSBpbiBzb21lIGVuY29kaW5nLgorICoKKyAqIDxwPlRoZSBpbnB1dCBjaGFyYWN0ZXIgc2VxdWVuY2UgaXMgYSB7QGxpbmsgamF2YS5uaW8uQ2hhckJ1ZmZlciBDaGFyQnVmZmVyfSBhbmQgdGhlCisgKiBvdXRwdXQgYnl0ZSBzZXF1ZW5jZSBpcyBhIHtAbGluayBqYXZhLm5pby5CeXRlQnVmZmVyIEJ5dGVCdWZmZXJ9LgorICoKKyAqIDxwPlVzZSB7QGxpbmsgI2VuY29kZShDaGFyQnVmZmVyKX0gdG8gZW5jb2RlIGFuIGVudGlyZSB7QGNvZGUgQ2hhckJ1ZmZlcn0gdG8gYQorICogbmV3IHtAY29kZSBCeXRlQnVmZmVyfSwgb3Ige0BsaW5rICNlbmNvZGUoQ2hhckJ1ZmZlciwgQnl0ZUJ1ZmZlciwgYm9vbGVhbil9IGZvciBtb3JlCisgKiBjb250cm9sLiBXaGVuIHVzaW5nIHRoZSBsYXR0ZXIgbWV0aG9kLCB0aGUgZW50aXJlIG9wZXJhdGlvbiBwcm9jZWVkcyBhcyBmb2xsb3dzOgorICogPG9sPgorICogPGxpPkludm9rZSB7QGxpbmsgI3Jlc2V0KCl9IHRvIHJlc2V0IHRoZSBlbmNvZGVyIGlmIHRoaXMgaW5zdGFuY2UgaGFzIGJlZW4gdXNlZCBiZWZvcmUuPC9saT4KKyAqIDxsaT5JbnZva2Uge0BsaW5rICNlbmNvZGUoQ2hhckJ1ZmZlciwgQnl0ZUJ1ZmZlciwgYm9vbGVhbikgZW5jb2RlfSB3aXRoIHRoZSB7QGNvZGUgZW5kT2ZJbnB1dH0KKyAqIHBhcmFtZXRlciBzZXQgdG8gZmFsc2UgdW50aWwgYWRkaXRpb25hbCBpbnB1dCBpcyBub3QgbmVlZGVkIChhcyBzaWduYWxlZCBieSB0aGUgcmV0dXJuIHZhbHVlKS4KKyAqIFRoZSBpbnB1dCBidWZmZXIgbXVzdCBiZSBmaWxsZWQgYW5kIHRoZSBvdXRwdXQgYnVmZmVyIG11c3QgYmUgZmx1c2hlZCBiZXR3ZWVuIGludm9jYXRpb25zLgorICogPHA+VGhlIHtAbGluayAjZW5jb2RlKENoYXJCdWZmZXIsIEJ5dGVCdWZmZXIsIGJvb2xlYW4pIGVuY29kZX0gbWV0aG9kIHdpbGwKKyAqIGNvbnZlcnQgYXMgbWFueSBjaGFyYWN0ZXJzIGFzIHBvc3NpYmxlLCBhbmQgdGhlIHByb2Nlc3Mgd29uJ3Qgc3RvcCB1bnRpbCB0aGUKKyAqIGlucHV0IGJ1ZmZlciBoYXMgYmVlbiBleGhhdXN0ZWQsIHRoZSBvdXRwdXQgYnVmZmVyIGhhcyBiZWVuIGZpbGxlZCwgb3IgYW4KKyAqIGVycm9yIGhhcyBvY2N1cnJlZC4gQSB7QGxpbmsgQ29kZXJSZXN1bHQgQ29kZXJSZXN1bHR9IGluc3RhbmNlIHdpbGwgYmUKKyAqIHJldHVybmVkIHRvIGluZGljYXRlIHRoZSBjdXJyZW50IHN0YXRlLiBUaGUgY2FsbGVyIHNob3VsZCBmaWxsIHRoZSBpbnB1dCBidWZmZXIsIGZsdXNoCisgKiB0aGUgb3V0cHV0IGJ1ZmZlciwgb3IgcmVjb3ZlcmluZyBmcm9tIGFuIGVycm9yIGFuZCB0cnkgYWdhaW4sIGFjY29yZGluZ2x5LgorICogPC9saT4KKyAqIDxsaT5JbnZva2Uge0BsaW5rICNlbmNvZGUoQ2hhckJ1ZmZlciwgQnl0ZUJ1ZmZlciwgYm9vbGVhbikgZW5jb2RlfSBmb3IgdGhlIGxhc3QgdGltZSB3aXRoCisgKiB7QGNvZGUgZW5kT2ZJbnB1dH0gc2V0IHRvIHRydWUuPC9saT4KKyAqIDxsaT5JbnZva2Uge0BsaW5rICNmbHVzaChCeXRlQnVmZmVyKX0gdG8gZmx1c2ggcmVtYWluaW5nIG91dHB1dC48L2xpPgorICogPC9vbD4KKyAqCisgKiA8cD5UaGVyZSBhcmUgdHdvIGNsYXNzZXMgb2YgZW5jb2RpbmcgZXJyb3I6IDxpPm1hbGZvcm1lZCBpbnB1dDwvaT4KKyAqIHNpZ25pZmllcyB0aGF0IHRoZSBpbnB1dCBjaGFyYWN0ZXIgc2VxdWVuY2UgaXMgbm90IGxlZ2FsLCB3aGlsZSA8aT51bm1hcHBhYmxlIGNoYXJhY3RlcjwvaT4KKyAqIHNpZ25pZmllcyB0aGF0IHRoZSBpbnB1dCBpcyBsZWdhbCBidXQgY2Fubm90IGJlIG1hcHBlZCB0byBhIGJ5dGUgc2VxdWVuY2UgKGJlY2F1c2UgdGhlIGNoYXJzZXQKKyAqIGNhbm5vdCByZXByZXNlbnQgdGhlIGNoYXJhY3RlciwgZm9yIGV4YW1wbGUpLgorICoKKyAqIDxwPkVycm9ycyBjYW4gYmUgaGFuZGxlZCBpbiB0aHJlZSB3YXlzLiBUaGUgZGVmYXVsdCBpcyB0bworICoge0BsaW5rIENvZGluZ0Vycm9yQWN0aW9uI1JFUE9SVCByZXBvcnR9IHRoZSBlcnJvciB0byB0aGUgY2FsbGVyLiBUaGUgYWx0ZXJuYXRpdmVzIGFyZSB0bworICoge0BsaW5rIENvZGluZ0Vycm9yQWN0aW9uI0lHTk9SRSBpZ25vcmV9IHRoZSBlcnJvciBvciB7QGxpbmsgQ29kaW5nRXJyb3JBY3Rpb24jUkVQTEFDRSByZXBsYWNlfQorICogdGhlIHByb2JsZW1hdGljIGlucHV0IHdpdGggdGhlIGJ5dGUgc2VxdWVuY2UgcmV0dXJuZWQgYnkge0BsaW5rICNyZXBsYWNlbWVudH0uIFRoZSBkaXNwb3NpdGlvbgorICogZm9yIGVhY2ggb2YgdGhlIHR3byBraW5kcyBvZiBlcnJvciBjYW4gYmUgc2V0IGluZGVwZW5kZW50bHkgdXNpbmcgdGhlIHtAbGluayAjb25NYWxmb3JtZWRJbnB1dH0KKyAqIGFuZCB7QGxpbmsgI29uVW5tYXBwYWJsZUNoYXJhY3Rlcn0gbWV0aG9kcy4KKyAqCisgKiA8cD5UaGUgZGVmYXVsdCByZXBsYWNlbWVudCBieXRlcyBkZXBlbmQgb24gdGhlIGNoYXJzZXQgYnV0IGNhbiBiZSBvdmVycmlkZGVuIHVzaW5nIHRoZQorICoge0BsaW5rICNyZXBsYWNlV2l0aH0gbWV0aG9kLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgaXMgYWJzdHJhY3QgYW5kIGVuY2Fwc3VsYXRlcyBtYW55IGNvbW1vbiBvcGVyYXRpb25zIG9mIHRoZQorICogZW5jb2RpbmcgcHJvY2VzcyBmb3IgYWxsIGNoYXJzZXRzLiBFbmNvZGVycyBmb3IgYSBzcGVjaWZpYyBjaGFyc2V0IHNob3VsZAorICogZXh0ZW5kIHRoaXMgY2xhc3MgYW5kIG5lZWQgb25seSB0byBpbXBsZW1lbnQgdGhlCisgKiB7QGxpbmsgI2VuY29kZUxvb3AoQ2hhckJ1ZmZlciwgQnl0ZUJ1ZmZlcikgZW5jb2RlTG9vcH0gbWV0aG9kIGZvciBiYXNpYworICogZW5jb2RpbmcuIElmIGEgc3ViY2xhc3MgbWFpbnRhaW5zIGludGVybmFsIHN0YXRlLCBpdCBzaG91bGQgYWxzbyBvdmVycmlkZSB0aGUKKyAqIHtAbGluayAjaW1wbEZsdXNoKEJ5dGVCdWZmZXIpIGltcGxGbHVzaH0gYW5kIHtAbGluayAjaW1wbFJlc2V0KCkgaW1wbFJlc2V0fSBtZXRob2RzLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgaXMgbm90IHRocmVhZC1zYWZlLgorICoKKyAqIEBzZWUgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0CisgKiBAc2VlIGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldERlY29kZXIKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIENoYXJzZXRFbmNvZGVyIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUkVBRFkgPSAwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBPTkdPSU5HID0gMTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRU5EID0gMjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRkxVU0ggPSAzOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTklUID0gNDsKKworICAgIHByaXZhdGUgZmluYWwgQ2hhcnNldCBjczsKKworICAgIHByaXZhdGUgZmluYWwgZmxvYXQgYXZlcmFnZUJ5dGVzUGVyQ2hhcjsKKyAgICBwcml2YXRlIGZpbmFsIGZsb2F0IG1heEJ5dGVzUGVyQ2hhcjsKKworICAgIHByaXZhdGUgYnl0ZVtdIHJlcGxhY2VtZW50Qnl0ZXM7CisKKyAgICBwcml2YXRlIGludCBzdGF0dXM7CisgICAgLy8gaW50ZXJuYWwgc3RhdHVzIGluZGljYXRlcyBlbmNvZGUoQ2hhckJ1ZmZlcikgb3BlcmF0aW9uIGlzIGZpbmlzaGVkCisgICAgcHJpdmF0ZSBib29sZWFuIGZpbmlzaGVkOworCisgICAgcHJpdmF0ZSBDb2RpbmdFcnJvckFjdGlvbiBtYWxmb3JtZWRJbnB1dEFjdGlvbjsKKyAgICBwcml2YXRlIENvZGluZ0Vycm9yQWN0aW9uIHVubWFwcGFibGVDaGFyYWN0ZXJBY3Rpb247CisKKyAgICAvLyBkZWNvZGVyIGluc3RhbmNlIGZvciB0aGlzIGVuY29kZXIncyBjaGFyc2V0LCB1c2VkIGZvciByZXBsYWNlbWVudCB2YWx1ZSBjaGVja2luZworICAgIHByaXZhdGUgQ2hhcnNldERlY29kZXIgZGVjb2RlcjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIENoYXJzZXRFbmNvZGVyfSB1c2luZyB0aGUgZ2l2ZW4gcGFyYW1ldGVycyBhbmQKKyAgICAgKiB0aGUgcmVwbGFjZW1lbnQgYnl0ZSBhcnJheSB7QGNvZGUgeyAoYnl0ZSkgJz8nIH19LgorICAgICAqLworICAgIHByb3RlY3RlZCBDaGFyc2V0RW5jb2RlcihDaGFyc2V0IGNzLCBmbG9hdCBhdmVyYWdlQnl0ZXNQZXJDaGFyLCBmbG9hdCBtYXhCeXRlc1BlckNoYXIpIHsKKyAgICAgICAgdGhpcyhjcywgYXZlcmFnZUJ5dGVzUGVyQ2hhciwgbWF4Qnl0ZXNQZXJDaGFyLCBuZXcgYnl0ZVtdIHsgKGJ5dGUpICc/JyB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IDxjb2RlPkNoYXJzZXRFbmNvZGVyPC9jb2RlPiB1c2luZyB0aGUgZ2l2ZW4KKyAgICAgKiA8Y29kZT5DaGFyc2V0PC9jb2RlPiwgcmVwbGFjZW1lbnQgYnl0ZSBhcnJheSwgYXZlcmFnZSBudW1iZXIgYW5kCisgICAgICogbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgY3JlYXRlZCBieSB0aGlzIGVuY29kZXIgZm9yIG9uZSBpbnB1dCBjaGFyYWN0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY3MKKyAgICAgKiAgICAgICAgICAgIHRoZSA8Y29kZT5DaGFyc2V0PC9jb2RlPiB0byBiZSB1c2VkIGJ5IHRoaXMgZW5jb2Rlci4KKyAgICAgKiBAcGFyYW0gYXZlcmFnZUJ5dGVzUGVyQ2hhcgorICAgICAqICAgICAgICAgICAgYXZlcmFnZSBudW1iZXIgb2YgYnl0ZXMgY3JlYXRlZCBieSB0aGlzIGVuY29kZXIgZm9yIG9uZSBzaW5nbGUKKyAgICAgKiAgICAgICAgICAgIGlucHV0IGNoYXJhY3RlciwgbXVzdCBiZSBwb3NpdGl2ZS4KKyAgICAgKiBAcGFyYW0gbWF4Qnl0ZXNQZXJDaGFyCisgICAgICogICAgICAgICAgICBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB3aGljaCBjYW4gYmUgY3JlYXRlZCBieSB0aGlzIGVuY29kZXIKKyAgICAgKiAgICAgICAgICAgIGZvciBvbmUgc2luZ2xlIGlucHV0IGNoYXJhY3RlciwgbXVzdCBiZSBwb3NpdGl2ZS4KKyAgICAgKiBAcGFyYW0gcmVwbGFjZW1lbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXBsYWNlbWVudCBieXRlIGFycmF5LCBjYW5ub3QgYmUgbnVsbCBvciBlbXB0eSwgaXRzCisgICAgICogICAgICAgICAgICBsZW5ndGggY2Fubm90IGJlIGxhcmdlciB0aGFuIDxjb2RlPm1heEJ5dGVzUGVyQ2hhcjwvY29kZT4sCisgICAgICogICAgICAgICAgICBhbmQgbXVzdCBiZSBhIGxlZ2FsIHJlcGxhY2VtZW50LCB3aGljaCBjYW4gYmUganVzdGlmaWVkIGJ5CisgICAgICogICAgICAgICAgICB7QGxpbmsgI2lzTGVnYWxSZXBsYWNlbWVudChieXRlW10pIGlzTGVnYWxSZXBsYWNlbWVudH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgcGFyYW1ldGVycyBhcmUgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ2hhcnNldEVuY29kZXIoQ2hhcnNldCBjcywgZmxvYXQgYXZlcmFnZUJ5dGVzUGVyQ2hhciwgZmxvYXQgbWF4Qnl0ZXNQZXJDaGFyLCBieXRlW10gcmVwbGFjZW1lbnQpIHsKKyAgICAgICAgdGhpcyhjcywgYXZlcmFnZUJ5dGVzUGVyQ2hhciwgbWF4Qnl0ZXNQZXJDaGFyLCByZXBsYWNlbWVudCwgZmFsc2UpOworICAgIH0KKworICAgIENoYXJzZXRFbmNvZGVyKENoYXJzZXQgY3MsIGZsb2F0IGF2ZXJhZ2VCeXRlc1BlckNoYXIsIGZsb2F0IG1heEJ5dGVzUGVyQ2hhciwgYnl0ZVtdIHJlcGxhY2VtZW50LCBib29sZWFuIHRydXN0ZWQpIHsKKyAgICAgICAgaWYgKGF2ZXJhZ2VCeXRlc1BlckNoYXIgPD0gMCB8fCBtYXhCeXRlc1BlckNoYXIgPD0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiYXZlcmFnZUJ5dGVzUGVyQ2hhciBhbmQgbWF4Qnl0ZXNQZXJDaGFyIG11c3QgYm90aCBiZSBwb3NpdGl2ZSIpOworICAgICAgICB9CisgICAgICAgIGlmIChhdmVyYWdlQnl0ZXNQZXJDaGFyID4gbWF4Qnl0ZXNQZXJDaGFyKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJhdmVyYWdlQnl0ZXNQZXJDaGFyIGlzIGdyZWF0ZXIgdGhhbiBtYXhCeXRlc1BlckNoYXIiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmNzID0gY3M7CisgICAgICAgIHRoaXMuYXZlcmFnZUJ5dGVzUGVyQ2hhciA9IGF2ZXJhZ2VCeXRlc1BlckNoYXI7CisgICAgICAgIHRoaXMubWF4Qnl0ZXNQZXJDaGFyID0gbWF4Qnl0ZXNQZXJDaGFyOworICAgICAgICBzdGF0dXMgPSBJTklUOworICAgICAgICBtYWxmb3JtZWRJbnB1dEFjdGlvbiA9IENvZGluZ0Vycm9yQWN0aW9uLlJFUE9SVDsKKyAgICAgICAgdW5tYXBwYWJsZUNoYXJhY3RlckFjdGlvbiA9IENvZGluZ0Vycm9yQWN0aW9uLlJFUE9SVDsKKyAgICAgICAgaWYgKHRydXN0ZWQpIHsKKyAgICAgICAgICAgIC8vIFRoZSBSSSBlbmZvcmNlcyB1bm5lY2Vzc2FyeSByZXN0cmljdGlvbnMgb24gdGhlIHJlcGxhY2VtZW50IGJ5dGVzLiBXZSB0cnVzdCBJQ1UgdG8KKyAgICAgICAgICAgIC8vIGtub3cgd2hhdCBpdCdzIGRvaW5nLiBEb2luZyBzbyBsZXRzIHVzIHN1cHBvcnQgSUNVJ3MgRVVDLUpQLCBTQ1NVLCBhbmQgU2hpZnRfSklTLgorICAgICAgICAgICAgdGhpcy5yZXBsYWNlbWVudEJ5dGVzID0gcmVwbGFjZW1lbnQ7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXBsYWNlV2l0aChyZXBsYWNlbWVudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhdmVyYWdlIG51bWJlciBvZiBieXRlcyBjcmVhdGVkIGJ5IHRoaXMgZW5jb2RlciBmb3IgYSBzaW5nbGUKKyAgICAgKiBpbnB1dCBjaGFyYWN0ZXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGZsb2F0IGF2ZXJhZ2VCeXRlc1BlckNoYXIoKSB7CisgICAgICAgIHJldHVybiBhdmVyYWdlQnl0ZXNQZXJDaGFyOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGNhbiBiZSBlbmNvZGVkIGJ5IHRoaXMgZW5jb2Rlci4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgY2FuIGNoYW5nZSB0aGUgaW50ZXJuYWwgc3RhdHVzIG9mIHRoaXMgZW5jb2Rlciwgc28KKyAgICAgKiBpdCBzaG91bGQgbm90IGJlIGNhbGxlZCB3aGVuIGFub3RoZXIgZW5jb2RpbmcgcHJvY2VzcyBpcyBvbmdvaW5nLAorICAgICAqIG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGFuIDxjb2RlPklsbGVnYWxTdGF0ZUV4Y2VwdGlvbjwvY29kZT4uCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIG92ZXJyaWRkZW4gZm9yIHBlcmZvcm1hbmNlIGltcHJvdmVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBnaXZlbiBlbmNvZGVyLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBnaXZlbiBjaGFyYWN0ZXIgY2FuIGJlIGVuY29kZWQgYnkgdGhpcyBlbmNvZGVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciBlbmNvZGUgcHJvY2VzcyBpcyBvbmdvaW5nIHNvIHRoYXQgdGhlIGN1cnJlbnQKKyAgICAgKiAgICAgICAgICAgICBpbnRlcm5hbCBzdGF0dXMgaXMgbmVpdGhlciBSRVNFVCBvciBGTFVTSC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjYW5FbmNvZGUoY2hhciBjKSB7CisgICAgICAgIHJldHVybiBpbXBsQ2FuRW5jb2RlKENoYXJCdWZmZXIud3JhcChuZXcgY2hhcltdIHsgYyB9KSk7CisgICAgfQorCisgICAgLy8gaW1wbGVtZW50YXRpb24gb2YgY2FuRW5jb2RlCisgICAgcHJpdmF0ZSBib29sZWFuIGltcGxDYW5FbmNvZGUoQ2hhckJ1ZmZlciBjYikgeworICAgICAgICBpZiAoc3RhdHVzID09IEZMVVNIIHx8IHN0YXR1cyA9PSBJTklUKSB7CisgICAgICAgICAgICBzdGF0dXMgPSBSRUFEWTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3RhdHVzICE9IFJFQURZKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJlbmNvZGluZyBhbHJlYWR5IGluIHByb2dyZXNzIik7CisgICAgICAgIH0KKyAgICAgICAgQ29kaW5nRXJyb3JBY3Rpb24gbWFsZm9ybUJhayA9IG1hbGZvcm1lZElucHV0QWN0aW9uOworICAgICAgICBDb2RpbmdFcnJvckFjdGlvbiB1bm1hcEJhayA9IHVubWFwcGFibGVDaGFyYWN0ZXJBY3Rpb247CisgICAgICAgIG9uTWFsZm9ybWVkSW5wdXQoQ29kaW5nRXJyb3JBY3Rpb24uUkVQT1JUKTsKKyAgICAgICAgb25Vbm1hcHBhYmxlQ2hhcmFjdGVyKENvZGluZ0Vycm9yQWN0aW9uLlJFUE9SVCk7CisgICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoaXMuZW5jb2RlKGNiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IGZhbHNlOworICAgICAgICB9CisgICAgICAgIG9uTWFsZm9ybWVkSW5wdXQobWFsZm9ybUJhayk7CisgICAgICAgIG9uVW5tYXBwYWJsZUNoYXJhY3Rlcih1bm1hcEJhayk7CisgICAgICAgIHJlc2V0KCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIGEgZ2l2ZW4gPGNvZGU+Q2hhclNlcXVlbmNlPC9jb2RlPiBjYW4gYmUgZW5jb2RlZCBieSB0aGlzCisgICAgICogZW5jb2Rlci4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCB0aGlzIG1ldGhvZCBjYW4gY2hhbmdlIHRoZSBpbnRlcm5hbCBzdGF0dXMgb2YgdGhpcyBlbmNvZGVyLCBzbworICAgICAqIGl0IHNob3VsZCBub3QgYmUgY2FsbGVkIHdoZW4gYW5vdGhlciBlbmNvZGUgcHJvY2VzcyBpcyBvbmdvaW5nLCBvdGhlcndpc2UKKyAgICAgKiBpdCB3aWxsIHRocm93IGFuIDxjb2RlPklsbGVnYWxTdGF0ZUV4Y2VwdGlvbjwvY29kZT4uCisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgb3ZlcnJpZGRlbiBmb3IgcGVyZm9ybWFuY2UgaW1wcm92ZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2VxdWVuY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBnaXZlbiA8Y29kZT5DaGFyU2VxdWVuY2U8L2NvZGU+LgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gPGNvZGU+Q2hhclNlcXVlbmNlPC9jb2RlPiBjYW4gYmUgZW5jb2RlZCBieQorICAgICAqICAgICAgICAgdGhpcyBlbmNvZGVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgY3VycmVudCBpbnRlcm5hbCBzdGF0dXMgaXMgbmVpdGhlciBSRVNFVCBvciBGTFVTSC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjYW5FbmNvZGUoQ2hhclNlcXVlbmNlIHNlcXVlbmNlKSB7CisgICAgICAgIENoYXJCdWZmZXIgY2I7CisgICAgICAgIGlmIChzZXF1ZW5jZSBpbnN0YW5jZW9mIENoYXJCdWZmZXIpIHsKKyAgICAgICAgICAgIGNiID0gKChDaGFyQnVmZmVyKSBzZXF1ZW5jZSkuZHVwbGljYXRlKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjYiA9IENoYXJCdWZmZXIud3JhcChzZXF1ZW5jZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGltcGxDYW5FbmNvZGUoY2IpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAbGluayBDaGFyc2V0fSB3aGljaCB0aGlzIGVuY29kZXIgdXNlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQ2hhcnNldCBjaGFyc2V0KCkgeworICAgICAgICByZXR1cm4gY3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBpcyBhIGZhY2FkZSBtZXRob2QgZm9yIHRoZSBlbmNvZGluZyBvcGVyYXRpb24uCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgZW5jb2RlcyB0aGUgcmVtYWluaW5nIGNoYXJhY3RlciBzZXF1ZW5jZSBvZiB0aGUgZ2l2ZW4KKyAgICAgKiBjaGFyYWN0ZXIgYnVmZmVyIGludG8gYSBuZXcgYnl0ZSBidWZmZXIuIFRoaXMgbWV0aG9kIHBlcmZvcm1zIGEgY29tcGxldGUKKyAgICAgKiBlbmNvZGluZyBvcGVyYXRpb24sIHJlc2V0cyBhdCBmaXJzdCwgdGhlbiBlbmNvZGVzLCBhbmQgZmx1c2hlcyBhdCBsYXN0LgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIHNob3VsZCBub3QgYmUgaW52b2tlZCBpZiBhbm90aGVyIGVuY29kZSBvcGVyYXRpb24gaXMgb25nb2luZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbgorICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIGEgbmV3IDxjb2RlPkJ5dGVCdWZmZXI8L2NvZGU+IGNvbnRhaW5pbmcgdGhlIGJ5dGVzIHByb2R1Y2VkIGJ5CisgICAgICogICAgICAgICB0aGlzIGVuY29kaW5nIG9wZXJhdGlvbi4gVGhlIGJ1ZmZlcidzIGxpbWl0IHdpbGwgYmUgdGhlIHBvc2l0aW9uCisgICAgICogICAgICAgICBvZiB0aGUgbGFzdCBieXRlIGluIHRoZSBidWZmZXIsIGFuZCB0aGUgcG9zaXRpb24gd2lsbCBiZSB6ZXJvLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW5vdGhlciBlbmNvZGluZyBvcGVyYXRpb24gaXMgb25nb2luZy4KKyAgICAgKiBAdGhyb3dzIE1hbGZvcm1lZElucHV0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gaWxsZWdhbCBpbnB1dCBjaGFyYWN0ZXIgc2VxdWVuY2UgZm9yIHRoaXMgY2hhcnNldCBpcworICAgICAqICAgICAgICAgICAgIGVuY291bnRlcmVkLCBhbmQgdGhlIGFjdGlvbiBmb3IgbWFsZm9ybWVkIGVycm9yIGlzCisgICAgICogICAgICAgICAgICAge0BsaW5rIENvZGluZ0Vycm9yQWN0aW9uI1JFUE9SVCBDb2RpbmdFcnJvckFjdGlvbi5SRVBPUlR9CisgICAgICogQHRocm93cyBVbm1hcHBhYmxlQ2hhcmFjdGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBsZWdhbCBidXQgdW5tYXBwYWJsZSBpbnB1dCBjaGFyYWN0ZXIgc2VxdWVuY2UgZm9yIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBjaGFyc2V0IGlzIGVuY291bnRlcmVkLCBhbmQgdGhlIGFjdGlvbiBmb3IgdW5tYXBwYWJsZQorICAgICAqICAgICAgICAgICAgIGNoYXJhY3RlciBlcnJvciBpcworICAgICAqICAgICAgICAgICAgIHtAbGluayBDb2RpbmdFcnJvckFjdGlvbiNSRVBPUlQgQ29kaW5nRXJyb3JBY3Rpb24uUkVQT1JUfS4KKyAgICAgKiAgICAgICAgICAgICBVbm1hcHBhYmxlIG1lYW5zIHRoZSBVbmljb2RlIGNoYXJhY3RlciBzZXF1ZW5jZSBhdCB0aGUgaW5wdXQKKyAgICAgKiAgICAgICAgICAgICBidWZmZXIncyBjdXJyZW50IHBvc2l0aW9uIGNhbm5vdCBiZSBtYXBwZWQgdG8gYSBlcXVpdmFsZW50CisgICAgICogICAgICAgICAgICAgYnl0ZSBzZXF1ZW5jZS4KKyAgICAgKiBAdGhyb3dzIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG90aGVyIGV4Y2VwdGlvbiBoYXBwZW5lZCBkdXJpbmcgdGhlIGVuY29kZSBvcGVyYXRpb24uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEJ5dGVCdWZmZXIgZW5jb2RlKENoYXJCdWZmZXIgaW4pIHRocm93cyBDaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb24geworICAgICAgICBpZiAoaW4ucmVtYWluaW5nKCkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIuYWxsb2NhdGUoMCk7CisgICAgICAgIH0KKyAgICAgICAgcmVzZXQoKTsKKyAgICAgICAgaW50IGxlbmd0aCA9IChpbnQpIChpbi5yZW1haW5pbmcoKSAqIGF2ZXJhZ2VCeXRlc1BlckNoYXIpOworICAgICAgICBCeXRlQnVmZmVyIG91dHB1dCA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUobGVuZ3RoKTsKKyAgICAgICAgQ29kZXJSZXN1bHQgcmVzdWx0ID0gbnVsbDsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IGVuY29kZShpbiwgb3V0cHV0LCBmYWxzZSk7CisgICAgICAgICAgICBpZiAocmVzdWx0PT1Db2RlclJlc3VsdC5VTkRFUkZMT1cpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzdWx0PT1Db2RlclJlc3VsdC5PVkVSRkxPVykgeworICAgICAgICAgICAgICAgIG91dHB1dCA9IGFsbG9jYXRlTW9yZShvdXRwdXQpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2hlY2tDb2RlclJlc3VsdChyZXN1bHQpOworICAgICAgICB9CisgICAgICAgIHJlc3VsdCA9IGVuY29kZShpbiwgb3V0cHV0LCB0cnVlKTsKKyAgICAgICAgY2hlY2tDb2RlclJlc3VsdChyZXN1bHQpOworCisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICByZXN1bHQgPSBmbHVzaChvdXRwdXQpOworICAgICAgICAgICAgaWYgKHJlc3VsdD09Q29kZXJSZXN1bHQuVU5ERVJGTE9XKSB7CisgICAgICAgICAgICAgICAgb3V0cHV0LmZsaXAoKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzdWx0PT1Db2RlclJlc3VsdC5PVkVSRkxPVykgeworICAgICAgICAgICAgICAgIG91dHB1dCA9IGFsbG9jYXRlTW9yZShvdXRwdXQpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2hlY2tDb2RlclJlc3VsdChyZXN1bHQpOworICAgICAgICAgICAgb3V0cHV0LmZsaXAoKTsKKyAgICAgICAgICAgIGlmIChyZXN1bHQuaXNNYWxmb3JtZWQoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRJbnB1dEV4Y2VwdGlvbihyZXN1bHQubGVuZ3RoKCkpOworICAgICAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQuaXNVbm1hcHBhYmxlKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5tYXBwYWJsZUNoYXJhY3RlckV4Y2VwdGlvbihyZXN1bHQubGVuZ3RoKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3RhdHVzID0gUkVBRFk7CisgICAgICAgIGZpbmlzaGVkID0gdHJ1ZTsKKyAgICAgICAgcmV0dXJuIG91dHB1dDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNoZWNrcyB0aGUgcmVzdWx0IHdoZXRoZXIgaXQgbmVlZHMgdG8gdGhyb3cgQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjaGVja0NvZGVyUmVzdWx0KENvZGVyUmVzdWx0IHJlc3VsdCkgdGhyb3dzIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChtYWxmb3JtZWRJbnB1dEFjdGlvbiA9PSBDb2RpbmdFcnJvckFjdGlvbi5SRVBPUlQgJiYgcmVzdWx0LmlzTWFsZm9ybWVkKCkgKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkSW5wdXRFeGNlcHRpb24ocmVzdWx0Lmxlbmd0aCgpKTsKKyAgICAgICAgfSBlbHNlIGlmICh1bm1hcHBhYmxlQ2hhcmFjdGVyQWN0aW9uID09IENvZGluZ0Vycm9yQWN0aW9uLlJFUE9SVCAmJiByZXN1bHQuaXNVbm1hcHBhYmxlKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbm1hcHBhYmxlQ2hhcmFjdGVyRXhjZXB0aW9uKHJlc3VsdC5sZW5ndGgoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBhbGxvY2F0ZSBtb3JlIHNwYWNlcyB0byB0aGUgZ2l2ZW4gQnl0ZUJ1ZmZlcgorICAgIHByaXZhdGUgQnl0ZUJ1ZmZlciBhbGxvY2F0ZU1vcmUoQnl0ZUJ1ZmZlciBvdXRwdXQpIHsKKyAgICAgICAgaWYgKG91dHB1dC5jYXBhY2l0eSgpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBCeXRlQnVmZmVyLmFsbG9jYXRlKDEpOworICAgICAgICB9CisgICAgICAgIEJ5dGVCdWZmZXIgcmVzdWx0ID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShvdXRwdXQuY2FwYWNpdHkoKSAqIDIpOworICAgICAgICBvdXRwdXQuZmxpcCgpOworICAgICAgICByZXN1bHQucHV0KG91dHB1dCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlcyBjaGFyYWN0ZXJzIHN0YXJ0aW5nIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZSBnaXZlbiBpbnB1dAorICAgICAqIGJ1ZmZlciwgYW5kIHdyaXRlcyB0aGUgZXF1aXZhbGVudCBieXRlIHNlcXVlbmNlIGludG8gdGhlIGdpdmVuIG91dHB1dAorICAgICAqIGJ1ZmZlciBmcm9tIGl0cyBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqIDxwPgorICAgICAqIFRoZSBidWZmZXJzJyBwb3NpdGlvbiB3aWxsIGJlIGNoYW5nZWQgd2l0aCB0aGUgcmVhZGluZyBhbmQgd3JpdGluZworICAgICAqIG9wZXJhdGlvbiwgYnV0IHRoZWlyIGxpbWl0cyBhbmQgbWFya3Mgd2lsbCBiZSBrZXB0IGludGFjdC4KKyAgICAgKiA8cD4KKyAgICAgKiBBIDxjb2RlPkNvZGVyUmVzdWx0PC9jb2RlPiBpbnN0YW5jZSB3aWxsIGJlIHJldHVybmVkIGFjY29yZGluZyB0bworICAgICAqIGZvbGxvd2luZyBydWxlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPkEge0BsaW5rIENvZGVyUmVzdWx0I21hbGZvcm1lZEZvckxlbmd0aChpbnQpIG1hbGZvcm1lZCBpbnB1dH0gcmVzdWx0CisgICAgICogaW5kaWNhdGVzIHRoYXQgc29tZSBtYWxmb3JtZWQgaW5wdXQgZXJyb3Igd2FzIGVuY291bnRlcmVkLCBhbmQgdGhlCisgICAgICogZXJyb25lb3VzIGNoYXJhY3RlcnMgc3RhcnQgYXQgdGhlIGlucHV0IGJ1ZmZlcidzIHBvc2l0aW9uIGFuZCB0aGVpcgorICAgICAqIG51bWJlciBjYW4gYmUgZ290IGJ5IHJlc3VsdCdzIHtAbGluayBDb2RlclJlc3VsdCNsZW5ndGgoKSBsZW5ndGh9LiBUaGlzCisgICAgICoga2luZCBvZiByZXN1bHQgY2FuIGJlIHJldHVybmVkIG9ubHkgaWYgdGhlIG1hbGZvcm1lZCBhY3Rpb24gaXMKKyAgICAgKiB7QGxpbmsgQ29kaW5nRXJyb3JBY3Rpb24jUkVQT1JUIENvZGluZ0Vycm9yQWN0aW9uLlJFUE9SVH0uPC9saT4KKyAgICAgKiA8bGk+e0BsaW5rIENvZGVyUmVzdWx0I1VOREVSRkxPVyBDb2RlclJlc3VsdC5VTkRFUkZMT1d9IGluZGljYXRlcyB0aGF0CisgICAgICogYXMgbWFueSBjaGFyYWN0ZXJzIGFzIHBvc3NpYmxlIGluIHRoZSBpbnB1dCBidWZmZXIgaGF2ZSBiZWVuIGVuY29kZWQuIElmCisgICAgICogdGhlcmUgaXMgbm8gZnVydGhlciBpbnB1dCBhbmQgbm8gY2hhcmFjdGVycyBsZWZ0IGluIHRoZSBpbnB1dCBidWZmZXIgdGhlbgorICAgICAqIHRoaXMgdGFzayBpcyBjb21wbGV0ZS4gSWYgdGhpcyBpcyBub3QgdGhlIGNhc2UgdGhlbiB0aGUgY2xpZW50IHNob3VsZAorICAgICAqIGNhbGwgdGhpcyBtZXRob2QgYWdhaW4gc3VwcGx5aW5nIHNvbWUgbW9yZSBpbnB1dCBjaGFyYWN0ZXJzLjwvbGk+CisgICAgICogPGxpPntAbGluayBDb2RlclJlc3VsdCNPVkVSRkxPVyBDb2RlclJlc3VsdC5PVkVSRkxPV30gaW5kaWNhdGVzIHRoYXQgdGhlCisgICAgICogb3V0cHV0IGJ1ZmZlciBoYXMgYmVlbiBmaWxsZWQsIHdoaWxlIHRoZXJlIGFyZSBzdGlsbCBzb21lIGNoYXJhY3RlcnMKKyAgICAgKiByZW1haW5pbmcgaW4gdGhlIGlucHV0IGJ1ZmZlci4gVGhpcyBtZXRob2Qgc2hvdWxkIGJlIGludm9rZWQgYWdhaW4gd2l0aCBhCisgICAgICogbm9uLWZ1bGwgb3V0cHV0IGJ1ZmZlci48L2xpPgorICAgICAqIDxsaT5BIHtAbGluayBDb2RlclJlc3VsdCN1bm1hcHBhYmxlRm9yTGVuZ3RoKGludCkgdW5tYXBwYWJsZSBjaGFyYWN0ZXJ9CisgICAgICogcmVzdWx0IGluZGljYXRlcyB0aGF0IHNvbWUgdW5tYXBwYWJsZSBjaGFyYWN0ZXIgZXJyb3Igd2FzIGVuY291bnRlcmVkLAorICAgICAqIGFuZCB0aGUgZXJyb25lb3VzIGNoYXJhY3RlcnMgc3RhcnQgYXQgdGhlIGlucHV0IGJ1ZmZlcidzIHBvc2l0aW9uIGFuZAorICAgICAqIHRoZWlyIG51bWJlciBjYW4gYmUgZ290IGJ5IHJlc3VsdCdzIHtAbGluayBDb2RlclJlc3VsdCNsZW5ndGgoKSBsZW5ndGh9LgorICAgICAqIFRoaXMga2luZCBvZiByZXN1bHQgY2FuIGJlIHJldHVybmVkIG9ubHkgb24KKyAgICAgKiB7QGxpbmsgQ29kaW5nRXJyb3JBY3Rpb24jUkVQT1JUIENvZGluZ0Vycm9yQWN0aW9uLlJFUE9SVH0uPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqIDxwPgorICAgICAqIFRoZSA8Y29kZT5lbmRPZklucHV0PC9jb2RlPiBwYXJhbWV0ZXIgaW5kaWNhdGVzIGlmIHRoZSBpbnZva2VyIGNhbgorICAgICAqIHByb3ZpZGVyIGZ1cnRoZXIgaW5wdXQuIFRoaXMgcGFyYW1ldGVyIGlzIHRydWUgaWYgYW5kIG9ubHkgaWYgdGhlCisgICAgICogY2hhcmFjdGVycyBpbiB0aGUgY3VycmVudCBpbnB1dCBidWZmZXIgYXJlIGFsbCBpbnB1dHMgZm9yIHRoaXMgZW5jb2RpbmcKKyAgICAgKiBvcGVyYXRpb24uIE5vdGUgdGhhdCBpdCBpcyBjb21tb24gYW5kIHdvbid0IGNhdXNlIGFuIGVycm9yIGlmIHRoZSBpbnZva2VyCisgICAgICogc2V0cyBmYWxzZSBhbmQgdGhlbiBoYXMgbm8gbW9yZSBpbnB1dCBhdmFpbGFibGUsIHdoaWxlIGl0IG1heSBjYXVzZSBhbgorICAgICAqIGVycm9yIGlmIHRoZSBpbnZva2VyIGFsd2F5cyBzZXRzIHRydWUgaW4gc2V2ZXJhbCBjb25zZWN1dGl2ZSBpbnZvY2F0aW9ucy4KKyAgICAgKiBUaGlzIHdvdWxkIG1ha2UgdGhlIHJlbWFpbmluZyBpbnB1dCB0byBiZSB0cmVhdGVkIGFzIG1hbGZvcm1lZCBpbnB1dC4KKyAgICAgKiBpbnB1dC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBpbnZva2VzIHRoZQorICAgICAqIHtAbGluayAjZW5jb2RlTG9vcChDaGFyQnVmZmVyLCBCeXRlQnVmZmVyKSBlbmNvZGVMb29wfSBtZXRob2QgdG8KKyAgICAgKiBpbXBsZW1lbnQgdGhlIGJhc2ljIGVuY29kZSBsb2dpYyBmb3IgYSBzcGVjaWZpYyBjaGFyc2V0LgorICAgICAqCisgICAgICogQHBhcmFtIGluCisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgYnVmZmVyLgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdXRwdXQgYnVmZmVyLgorICAgICAqIEBwYXJhbSBlbmRPZklucHV0CisgICAgICogICAgICAgICAgICB0cnVlIGlmIGFsbCB0aGUgaW5wdXQgY2hhcmFjdGVycyBoYXZlIGJlZW4gcHJvdmlkZWQuCisgICAgICogQHJldHVybiBhIDxjb2RlPkNvZGVyUmVzdWx0PC9jb2RlPiBpbnN0YW5jZSBpbmRpY2F0aW5nIHRoZSByZXN1bHQuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZW5jb2Rpbmcgb3BlcmF0aW9uIGhhcyBhbHJlYWR5IHN0YXJ0ZWQgb3Igbm8gbW9yZQorICAgICAqICAgICAgICAgICAgIGlucHV0IGlzIG5lZWRlZCBpbiB0aGlzIGVuY29kaW5nIHByb2Nlc3MuCisgICAgICogQHRocm93cyBDb2Rlck1hbGZ1bmN0aW9uRXJyb3IKKyAgICAgKiAgICAgICAgICAgICBJZiB0aGUge0BsaW5rICNlbmNvZGVMb29wKENoYXJCdWZmZXIsIEJ5dGVCdWZmZXIpIGVuY29kZUxvb3B9CisgICAgICogICAgICAgICAgICAgbWV0aG9kIHRocmV3IGFuIDxjb2RlPkJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbjwvY29kZT4gb3IKKyAgICAgKiAgICAgICAgICAgICA8Y29kZT5CdWZmZXJVbmRlcmZsb3dFeGNlcHRpb248L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBDb2RlclJlc3VsdCBlbmNvZGUoQ2hhckJ1ZmZlciBpbiwgQnl0ZUJ1ZmZlciBvdXQsIGJvb2xlYW4gZW5kT2ZJbnB1dCkgeworICAgICAgICAvLyBJZiB0aGUgcHJldmlvdXMgc3RlcCBpcyBlbmNvZGUoQ2hhckJ1ZmZlciksIHRoZW4gbm8gbW9yZSBpbnB1dCBpcyBuZWVkZWQKKyAgICAgICAgLy8gdGh1cyBlbmRPZklucHV0IHNob3VsZCBub3QgYmUgZmFsc2UKKyAgICAgICAgaWYgKHN0YXR1cyA9PSBSRUFEWSAmJiBmaW5pc2hlZCAmJiAhZW5kT2ZJbnB1dCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmICgoc3RhdHVzID09IEZMVVNIKSB8fCAoIWVuZE9mSW5wdXQgJiYgc3RhdHVzID09IEVORCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIENvZGVyUmVzdWx0IHJlc3VsdDsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gZW5jb2RlTG9vcChpbiwgb3V0KTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29kZXJNYWxmdW5jdGlvbkVycm9yKGUpOworICAgICAgICAgICAgfSBjYXRjaCAoQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29kZXJNYWxmdW5jdGlvbkVycm9yKGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHJlc3VsdD09Q29kZXJSZXN1bHQuVU5ERVJGTE9XKSB7CisgICAgICAgICAgICAgICAgc3RhdHVzID0gZW5kT2ZJbnB1dCA/IEVORCA6IE9OR09JTkc7CisgICAgICAgICAgICAgICAgaWYgKGVuZE9mSW5wdXQpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHJlbWFpbmluZyA9IGluLnJlbWFpbmluZygpOworICAgICAgICAgICAgICAgICAgICBpZiAocmVtYWluaW5nID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gQ29kZXJSZXN1bHQubWFsZm9ybWVkRm9yTGVuZ3RoKHJlbWFpbmluZyk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdD09Q29kZXJSZXN1bHQuT1ZFUkZMT1cpIHsKKyAgICAgICAgICAgICAgICBzdGF0dXMgPSBlbmRPZklucHV0ID8gRU5EIDogT05HT0lORzsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgQ29kaW5nRXJyb3JBY3Rpb24gYWN0aW9uID0gbWFsZm9ybWVkSW5wdXRBY3Rpb247CisgICAgICAgICAgICBpZiAocmVzdWx0LmlzVW5tYXBwYWJsZSgpKSB7CisgICAgICAgICAgICAgICAgYWN0aW9uID0gdW5tYXBwYWJsZUNoYXJhY3RlckFjdGlvbjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIElmIHRoZSBhY3Rpb24gaXMgSUdOT1JFIG9yIFJFUExBQ0UsIHdlIHNob3VsZCBjb250aW51ZQorICAgICAgICAgICAgLy8gZW5jb2RpbmcuCisgICAgICAgICAgICBpZiAoYWN0aW9uID09IENvZGluZ0Vycm9yQWN0aW9uLlJFUExBQ0UpIHsKKyAgICAgICAgICAgICAgICBpZiAob3V0LnJlbWFpbmluZygpIDwgcmVwbGFjZW1lbnRCeXRlcy5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvZGVyUmVzdWx0Lk9WRVJGTE9XOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBvdXQucHV0KHJlcGxhY2VtZW50Qnl0ZXMpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAoYWN0aW9uICE9IENvZGluZ0Vycm9yQWN0aW9uLklHTk9SRSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGluLnBvc2l0aW9uKGluLnBvc2l0aW9uKCkgKyByZXN1bHQubGVuZ3RoKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlcyBjaGFyYWN0ZXJzIGludG8gYnl0ZXMuIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieQorICAgICAqIHtAbGluayAjZW5jb2RlKENoYXJCdWZmZXIsIEJ5dGVCdWZmZXIsIGJvb2xlYW4pIGVuY29kZX0uCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2Qgd2lsbCBpbXBsZW1lbnQgdGhlIGVzc2VudGlhbCBlbmNvZGluZyBvcGVyYXRpb24sIGFuZCBpdCB3b24ndAorICAgICAqIHN0b3AgZW5jb2RpbmcgdW50aWwgZWl0aGVyIGFsbCB0aGUgaW5wdXQgY2hhcmFjdGVycyBhcmUgcmVhZCwgdGhlIG91dHB1dAorICAgICAqIGJ1ZmZlciBpcyBmaWxsZWQsIG9yIHNvbWUgZXhjZXB0aW9uIGlzIGVuY291bnRlcmVkLiBUaGVuIGl0IHdpbGwKKyAgICAgKiByZXR1cm4gYSA8Y29kZT5Db2RlclJlc3VsdDwvY29kZT4gb2JqZWN0IGluZGljYXRpbmcgdGhlIHJlc3VsdCBvZiB0aGUKKyAgICAgKiBjdXJyZW50IGVuY29kaW5nIG9wZXJhdGlvbi4gVGhlIHJ1bGUgdG8gY29uc3RydWN0IHRoZQorICAgICAqIDxjb2RlPkNvZGVyUmVzdWx0PC9jb2RlPiBpcyB0aGUgc2FtZSBhcyBmb3IKKyAgICAgKiB7QGxpbmsgI2VuY29kZShDaGFyQnVmZmVyLCBCeXRlQnVmZmVyLCBib29sZWFuKSBlbmNvZGV9LiBXaGVuIGFuCisgICAgICogZXhjZXB0aW9uIGlzIGVuY291bnRlcmVkIGluIHRoZSBlbmNvZGluZyBvcGVyYXRpb24sIG1vc3QgaW1wbGVtZW50YXRpb25zCisgICAgICogb2YgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gYSByZWxldmFudCByZXN1bHQgb2JqZWN0IHRvIHRoZQorICAgICAqIHtAbGluayAjZW5jb2RlKENoYXJCdWZmZXIsIEJ5dGVCdWZmZXIsIGJvb2xlYW4pIGVuY29kZX0gbWV0aG9kLCBhbmQgc29tZQorICAgICAqIHBlcmZvcm1hbmNlIG9wdGltaXplZCBpbXBsZW1lbnRhdGlvbiBtYXkgaGFuZGxlIHRoZSBleGNlcHRpb24gYW5kCisgICAgICogaW1wbGVtZW50IHRoZSBlcnJvciBhY3Rpb24gaXRzZWxmLgorICAgICAqIDxwPgorICAgICAqIFRoZSBidWZmZXJzIGFyZSBzY2FubmVkIGZyb20gdGhlaXIgY3VycmVudCBwb3NpdGlvbnMsIGFuZCB0aGVpciBwb3NpdGlvbnMKKyAgICAgKiB3aWxsIGJlIG1vZGlmaWVkIGFjY29yZGluZ2x5LCB3aGlsZSB0aGVpciBtYXJrcyBhbmQgbGltaXRzIHdpbGwgYmUKKyAgICAgKiBpbnRhY3QuIEF0IG1vc3Qge0BsaW5rIENoYXJCdWZmZXIjcmVtYWluaW5nKCkgaW4ucmVtYWluaW5nKCl9IGNoYXJhY3RlcnMKKyAgICAgKiB3aWxsIGJlIHJlYWQsIGFuZCB7QGxpbmsgQnl0ZUJ1ZmZlciNyZW1haW5pbmcoKSBvdXQucmVtYWluaW5nKCl9IGJ5dGVzCisgICAgICogd2lsbCBiZSB3cml0dGVuLgorICAgICAqIDxwPgorICAgICAqIE5vdGUgdGhhdCBzb21lIGltcGxlbWVudGF0aW9ucyBtYXkgcHJlLXNjYW4gdGhlIGlucHV0IGJ1ZmZlciBhbmQgcmV0dXJuCisgICAgICogPGNvZGU+Q29kZXJSZXN1bHQuVU5ERVJGTE9XPC9jb2RlPiB1bnRpbCBpdCByZWNlaXZlcyBzdWZmaWNpZW50IGlucHV0LgorICAgICAqIDxwPgorICAgICAqIEBwYXJhbSBpbgorICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IGJ1ZmZlci4KKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIGEgPGNvZGU+Q29kZXJSZXN1bHQ8L2NvZGU+IGluc3RhbmNlIGluZGljYXRpbmcgdGhlIHJlc3VsdC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgQ29kZXJSZXN1bHQgZW5jb2RlTG9vcChDaGFyQnVmZmVyIGluLCBCeXRlQnVmZmVyIG91dCk7CisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIHRoaXMgZW5jb2Rlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGNhbGwge0BsaW5rICNpbXBsRmx1c2goQnl0ZUJ1ZmZlcikgaW1wbEZsdXNofS4gU29tZQorICAgICAqIGVuY29kZXJzIG1heSBuZWVkIHRvIHdyaXRlIHNvbWUgYnl0ZXMgdG8gdGhlIG91dHB1dCBidWZmZXIgd2hlbiB0aGV5IGhhdmUKKyAgICAgKiByZWFkIGFsbCBpbnB1dCBjaGFyYWN0ZXJzLCBzdWJjbGFzc2VzIGNhbiBvdmVycmlkZGVuCisgICAgICoge0BsaW5rICNpbXBsRmx1c2goQnl0ZUJ1ZmZlcikgaW1wbEZsdXNofSB0byBwZXJmb3JtIHdyaXRpbmcgYWN0aW9uLgorICAgICAqIDxwPgorICAgICAqIFRoZSBtYXhpbXVtIG51bWJlciBvZiB3cml0dGVuIGJ5dGVzIHdvbid0IGxhcmdlciB0aGFuCisgICAgICoge0BsaW5rIEJ5dGVCdWZmZXIjcmVtYWluaW5nKCkgb3V0LnJlbWFpbmluZygpfS4gSWYgc29tZSBlbmNvZGVyIHdhbnRzIHRvCisgICAgICogd3JpdGUgbW9yZSBieXRlcyB0aGFuIHRoZSBvdXRwdXQgYnVmZmVyJ3MgYXZhaWxhYmxlIHJlbWFpbmluZyBzcGFjZSwgdGhlbgorICAgICAqIDxjb2RlPkNvZGVyUmVzdWx0Lk9WRVJGTE9XPC9jb2RlPiB3aWxsIGJlIHJldHVybmVkLCBhbmQgdGhpcyBtZXRob2QKKyAgICAgKiBtdXN0IGJlIGNhbGxlZCBhZ2FpbiB3aXRoIGEgYnl0ZSBidWZmZXIgdGhhdCBoYXMgZnJlZSBzcGFjZS4gT3RoZXJ3aXNlCisgICAgICogdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gPGNvZGU+Q29kZXJSZXN1bHQuVU5ERVJGTE9XPC9jb2RlPiwgd2hpY2gKKyAgICAgKiBtZWFucyBvbmUgZW5jb2RpbmcgcHJvY2VzcyBoYXMgYmVlbiBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5LgorICAgICAqIDxwPgorICAgICAqIER1cmluZyB0aGUgZmx1c2gsIHRoZSBvdXRwdXQgYnVmZmVyJ3MgcG9zaXRpb24gd2lsbCBiZSBjaGFuZ2VkCisgICAgICogYWNjb3JkaW5nbHksIHdoaWxlIGl0cyBtYXJrIGFuZCBsaW1pdCB3aWxsIGJlIGludGFjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBnaXZlbiBvdXRwdXQgYnVmZmVyLgorICAgICAqIEByZXR1cm4gPGNvZGU+Q29kZXJSZXN1bHQuVU5ERVJGTE9XPC9jb2RlPiBvcgorICAgICAqICAgICAgICAgPGNvZGU+Q29kZXJSZXN1bHQuT1ZFUkZMT1c8L2NvZGU+LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBlbmNvZGVyIGhhc24ndCByZWFkIGFsbCBpbnB1dCBjaGFyYWN0ZXJzIGR1cmluZyBvbmUKKyAgICAgKiAgICAgICAgICAgICBlbmNvZGluZyBwcm9jZXNzLCB3aGljaCBtZWFucyBuZWl0aGVyIGFmdGVyIGNhbGxpbmcKKyAgICAgKiAgICAgICAgICAgICB7QGxpbmsgI2VuY29kZShDaGFyQnVmZmVyKSBlbmNvZGUoQ2hhckJ1ZmZlcil9IG5vciBhZnRlcgorICAgICAqICAgICAgICAgICAgIGNhbGxpbmcge0BsaW5rICNlbmNvZGUoQ2hhckJ1ZmZlciwgQnl0ZUJ1ZmZlciwgYm9vbGVhbikKKyAgICAgKiAgICAgICAgICAgICBlbmNvZGUoQ2hhckJ1ZmZlciwgQnl0ZUJ1ZmZlciwgYm9vbGVhbil9IHdpdGgge0Bjb2RlIHRydWV9CisgICAgICogICAgICAgICAgICAgZm9yIHRoZSBsYXN0IGJvb2xlYW4gcGFyYW1ldGVyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBDb2RlclJlc3VsdCBmbHVzaChCeXRlQnVmZmVyIG91dCkgeworICAgICAgICBpZiAoc3RhdHVzICE9IEVORCAmJiBzdGF0dXMgIT0gUkVBRFkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBDb2RlclJlc3VsdCByZXN1bHQgPSBpbXBsRmx1c2gob3V0KTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBDb2RlclJlc3VsdC5VTkRFUkZMT1cpIHsKKyAgICAgICAgICAgIHN0YXR1cyA9IEZMVVNIOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmx1c2hlcyB0aGlzIGVuY29kZXIuIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZyBhbmQgYWx3YXlzCisgICAgICogcmV0dXJucyA8Y29kZT5Db2RlclJlc3VsdC5VTkRFUkZMT1c8L2NvZGU+OyB0aGlzIG1ldGhvZCBjYW4gYmUKKyAgICAgKiBvdmVycmlkZGVuIGlmIG5lZWRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdXRwdXQgYnVmZmVyLgorICAgICAqIEByZXR1cm4gPGNvZGU+Q29kZXJSZXN1bHQuVU5ERVJGTE9XPC9jb2RlPiBvcgorICAgICAqICAgICAgICAgPGNvZGU+Q29kZXJSZXN1bHQuT1ZFUkZMT1c8L2NvZGU+LgorICAgICAqLworICAgIHByb3RlY3RlZCBDb2RlclJlc3VsdCBpbXBsRmx1c2goQnl0ZUJ1ZmZlciBvdXQpIHsKKyAgICAgICAgcmV0dXJuIENvZGVyUmVzdWx0LlVOREVSRkxPVzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGF0IHRoaXMgZW5jb2RlcidzIDxjb2RlPkNvZGluZ0Vycm9yQWN0aW9uPC9jb2RlPiBzcGVjaWZpZWQKKyAgICAgKiBmb3IgbWFsZm9ybWVkIGlucHV0IGVycm9yIGhhcyBiZWVuIGNoYW5nZWQuIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uCisgICAgICogZG9lcyBub3RoaW5nOyB0aGlzIG1ldGhvZCBjYW4gYmUgb3ZlcnJpZGRlbiBpZiBuZWVkZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3QWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgbmV3IGFjdGlvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBpbXBsT25NYWxmb3JtZWRJbnB1dChDb2RpbmdFcnJvckFjdGlvbiBuZXdBY3Rpb24pIHsKKyAgICAgICAgLy8gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyBlbXB0eQorICAgIH0KKworICAgIC8qKgorICAgICAqIE5vdGlmaWVzIHRoYXQgdGhpcyBlbmNvZGVyJ3MgPGNvZGU+Q29kaW5nRXJyb3JBY3Rpb248L2NvZGU+IHNwZWNpZmllZAorICAgICAqIGZvciB1bm1hcHBhYmxlIGNoYXJhY3RlciBlcnJvciBoYXMgYmVlbiBjaGFuZ2VkLiBUaGUgZGVmYXVsdAorICAgICAqIGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZzsgdGhpcyBtZXRob2QgY2FuIGJlIG92ZXJyaWRkZW4gaWYgbmVlZGVkLgorICAgICAqCisgICAgICogQHBhcmFtIG5ld0FjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBhY3Rpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgaW1wbE9uVW5tYXBwYWJsZUNoYXJhY3RlcihDb2RpbmdFcnJvckFjdGlvbiBuZXdBY3Rpb24pIHsKKyAgICAgICAgLy8gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyBlbXB0eQorICAgIH0KKworICAgIC8qKgorICAgICAqIE5vdGlmaWVzIHRoYXQgdGhpcyBlbmNvZGVyJ3MgcmVwbGFjZW1lbnQgaGFzIGJlZW4gY2hhbmdlZC4gVGhlIGRlZmF1bHQKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdGhpbmc7IHRoaXMgbWV0aG9kIGNhbiBiZSBvdmVycmlkZGVuIGlmIG5lZWRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdSZXBsYWNlbWVudAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyByZXBsYWNlbWVudCBzdHJpbmcuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgaW1wbFJlcGxhY2VXaXRoKGJ5dGVbXSBuZXdSZXBsYWNlbWVudCkgeworICAgICAgICAvLyBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGlzIGVtcHR5CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzZXRzIHRoaXMgZW5jb2RlcidzIGNoYXJzZXQgcmVsYXRlZCBzdGF0ZS4gVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24KKyAgICAgKiBkb2VzIG5vdGhpbmc7IHRoaXMgbWV0aG9kIGNhbiBiZSBvdmVycmlkZGVuIGlmIG5lZWRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBpbXBsUmVzZXQoKSB7CisgICAgICAgIC8vIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gaXMgZW1wdHkKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhlIGdpdmVuIGFyZ3VtZW50IGlzIGxlZ2FsIGFzIHRoaXMgZW5jb2RlcidzIHJlcGxhY2VtZW50IGJ5dGUKKyAgICAgKiBhcnJheS4KKyAgICAgKgorICAgICAqIFRoZSBnaXZlbiBieXRlIGFycmF5IGlzIGxlZ2FsIGlmIGFuZCBvbmx5IGlmIGl0IGNhbiBiZSBkZWNvZGUgaW50bworICAgICAqIHNpeHRlZW4gYml0cyBVbmljb2RlIGNoYXJhY3RlcnMuCisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgb3ZlcnJpZGRlbiBmb3IgcGVyZm9ybWFuY2UgaW1wcm92ZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVwbGFjZW1lbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBnaXZlbiBieXRlIGFycmF5IHRvIGJlIGNoZWNrZWQuCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSB0aGUgZ2l2ZW4gYXJndW1lbnQgaXMgbGVnYWwgYXMgdGhpcyBlbmNvZGVyJ3MKKyAgICAgKiAgICAgICAgIHJlcGxhY2VtZW50IGJ5dGUgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNMZWdhbFJlcGxhY2VtZW50KGJ5dGVbXSByZXBsYWNlbWVudCkgeworICAgICAgICBpZiAoZGVjb2RlciA9PSBudWxsKSB7CisgICAgICAgICAgICBkZWNvZGVyID0gY3MubmV3RGVjb2RlcigpOworICAgICAgICAgICAgZGVjb2Rlci5vbk1hbGZvcm1lZElucHV0KENvZGluZ0Vycm9yQWN0aW9uLlJFUE9SVCk7CisgICAgICAgICAgICBkZWNvZGVyLm9uVW5tYXBwYWJsZUNoYXJhY3RlcihDb2RpbmdFcnJvckFjdGlvbi5SRVBPUlQpOworICAgICAgICB9CisgICAgICAgIEJ5dGVCdWZmZXIgaW4gPSBCeXRlQnVmZmVyLndyYXAocmVwbGFjZW1lbnQpOworICAgICAgICBDaGFyQnVmZmVyIG91dCA9IENoYXJCdWZmZXIuYWxsb2NhdGUoKGludCkgKHJlcGxhY2VtZW50Lmxlbmd0aCAqIGRlY29kZXIubWF4Q2hhcnNQZXJCeXRlKCkpKTsKKyAgICAgICAgQ29kZXJSZXN1bHQgcmVzdWx0ID0gZGVjb2Rlci5kZWNvZGUoaW4sIG91dCwgdHJ1ZSk7CisgICAgICAgIHJldHVybiAhcmVzdWx0LmlzRXJyb3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgZW5jb2RlcidzIDxjb2RlPkNvZGluZ0Vycm9yQWN0aW9uPC9jb2RlPiB3aGVuIGEgbWFsZm9ybWVkCisgICAgICogaW5wdXQgZXJyb3Igb2NjdXJyZWQgZHVyaW5nIHRoZSBlbmNvZGluZyBwcm9jZXNzLgorICAgICAqLworICAgIHB1YmxpYyBDb2RpbmdFcnJvckFjdGlvbiBtYWxmb3JtZWRJbnB1dEFjdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIG1hbGZvcm1lZElucHV0QWN0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHdoaWNoIGNhbiBiZSBjcmVhdGVkIGJ5IHRoaXMgZW5jb2RlciBmb3IKKyAgICAgKiBvbmUgaW5wdXQgY2hhcmFjdGVyLCBtdXN0IGJlIHBvc2l0aXZlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBmbG9hdCBtYXhCeXRlc1BlckNoYXIoKSB7CisgICAgICAgIHJldHVybiBtYXhCeXRlc1BlckNoYXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGlzIGVuY29kZXIncyBhY3Rpb24gb24gbWFsZm9ybWVkIGlucHV0IGVycm9yLgorICAgICAqCisgICAgICogVGhpcyBtZXRob2Qgd2lsbCBjYWxsIHRoZQorICAgICAqIHtAbGluayAjaW1wbE9uTWFsZm9ybWVkSW5wdXQoQ29kaW5nRXJyb3JBY3Rpb24pIGltcGxPbk1hbGZvcm1lZElucHV0fQorICAgICAqIG1ldGhvZCB3aXRoIHRoZSBnaXZlbiBuZXcgYWN0aW9uIGFzIGFyZ3VtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIG5ld0FjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBhY3Rpb24gb24gbWFsZm9ybWVkIGlucHV0IGVycm9yLgorICAgICAqIEByZXR1cm4gdGhpcyBlbmNvZGVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIG5ld0FjdGlvbiBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBDaGFyc2V0RW5jb2RlciBvbk1hbGZvcm1lZElucHV0KENvZGluZ0Vycm9yQWN0aW9uIG5ld0FjdGlvbikgeworICAgICAgICBpZiAobmV3QWN0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm5ld0FjdGlvbiA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgbWFsZm9ybWVkSW5wdXRBY3Rpb24gPSBuZXdBY3Rpb247CisgICAgICAgIGltcGxPbk1hbGZvcm1lZElucHV0KG5ld0FjdGlvbik7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhpcyBlbmNvZGVyJ3MgYWN0aW9uIG9uIHVubWFwcGFibGUgY2hhcmFjdGVyIGVycm9yLgorICAgICAqCisgICAgICogVGhpcyBtZXRob2Qgd2lsbCBjYWxsIHRoZQorICAgICAqIHtAbGluayAjaW1wbE9uVW5tYXBwYWJsZUNoYXJhY3RlcihDb2RpbmdFcnJvckFjdGlvbikgaW1wbE9uVW5tYXBwYWJsZUNoYXJhY3Rlcn0KKyAgICAgKiBtZXRob2Qgd2l0aCB0aGUgZ2l2ZW4gbmV3IGFjdGlvbiBhcyBhcmd1bWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdBY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgYWN0aW9uIG9uIHVubWFwcGFibGUgY2hhcmFjdGVyIGVycm9yLgorICAgICAqIEByZXR1cm4gdGhpcyBlbmNvZGVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIG5ld0FjdGlvbiBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBDaGFyc2V0RW5jb2RlciBvblVubWFwcGFibGVDaGFyYWN0ZXIoQ29kaW5nRXJyb3JBY3Rpb24gbmV3QWN0aW9uKSB7CisgICAgICAgIGlmIChuZXdBY3Rpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibmV3QWN0aW9uID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB1bm1hcHBhYmxlQ2hhcmFjdGVyQWN0aW9uID0gbmV3QWN0aW9uOworICAgICAgICBpbXBsT25Vbm1hcHBhYmxlQ2hhcmFjdGVyKG5ld0FjdGlvbik7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHJlcGxhY2VtZW50IGJ5dGUgYXJyYXksIHdoaWNoIGlzIG5ldmVyIG51bGwgb3IgZW1wdHkuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJ5dGVbXSByZXBsYWNlbWVudCgpIHsKKyAgICAgICAgcmV0dXJuIHJlcGxhY2VtZW50Qnl0ZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmV3IHJlcGxhY2VtZW50IHZhbHVlLgorICAgICAqCisgICAgICogVGhpcyBtZXRob2QgZmlyc3QgY2hlY2tzIHRoZSBnaXZlbiByZXBsYWNlbWVudCdzIHZhbGlkaXR5LCB0aGVuIGNoYW5nZXMKKyAgICAgKiB0aGUgcmVwbGFjZW1lbnQgdmFsdWUgYW5kIGZpbmFsbHkgY2FsbHMgdGhlCisgICAgICoge0BsaW5rICNpbXBsUmVwbGFjZVdpdGgoYnl0ZVtdKSBpbXBsUmVwbGFjZVdpdGh9IG1ldGhvZCB3aXRoIHRoZSBnaXZlbgorICAgICAqIG5ldyByZXBsYWNlbWVudCBhcyBhcmd1bWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZXBsYWNlbWVudAorICAgICAqICAgICAgICAgICAgdGhlIHJlcGxhY2VtZW50IGJ5dGUgYXJyYXksIGNhbm5vdCBiZSBudWxsIG9yIGVtcHR5LCBpdHMKKyAgICAgKiAgICAgICAgICAgIGxlbmd0aCBjYW5ub3QgYmUgbGFyZ2VyIHRoYW4gPGNvZGU+bWF4Qnl0ZXNQZXJDaGFyPC9jb2RlPiwKKyAgICAgKiAgICAgICAgICAgIGFuZCBpdCBtdXN0IGJlIGxlZ2FsIHJlcGxhY2VtZW50LCB3aGljaCBjYW4gYmUganVzdGlmaWVkIGJ5CisgICAgICogICAgICAgICAgICBjYWxsaW5nIDxjb2RlPmlzTGVnYWxSZXBsYWNlbWVudChieXRlW10gcmVwbGFjZW1lbnQpPC9jb2RlPi4KKyAgICAgKiBAcmV0dXJuIHRoaXMgZW5jb2Rlci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBnaXZlbiByZXBsYWNlbWVudCBjYW5ub3Qgc2F0aXNmeSB0aGUgcmVxdWlyZW1lbnQKKyAgICAgKiAgICAgICAgICAgICBtZW50aW9uZWQgYWJvdmUuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENoYXJzZXRFbmNvZGVyIHJlcGxhY2VXaXRoKGJ5dGVbXSByZXBsYWNlbWVudCkgeworICAgICAgICBpZiAocmVwbGFjZW1lbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicmVwbGFjZW1lbnQgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChyZXBsYWNlbWVudC5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicmVwbGFjZW1lbnQubGVuZ3RoID09IDAiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocmVwbGFjZW1lbnQubGVuZ3RoID4gbWF4Qnl0ZXNQZXJDaGFyKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInJlcGxhY2VtZW50IGxlbmd0aCA+IG1heEJ5dGVzUGVyQ2hhcjogIiArCisgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50Lmxlbmd0aCArICIgPiAiICsgbWF4Qnl0ZXNQZXJDaGFyKCkpOworICAgICAgICB9CisgICAgICAgIGlmICghaXNMZWdhbFJlcGxhY2VtZW50KHJlcGxhY2VtZW50KSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiYmFkIHJlcGxhY2VtZW50OiAiICsgQXJyYXlzLnRvU3RyaW5nKHJlcGxhY2VtZW50KSk7CisgICAgICAgIH0KKyAgICAgICAgLy8gSXQgc2VlbXMgbGlrZSBhIGJ1ZywgYnV0IHRoZSBSSSBkb2Vzbid0IGNsb25lLCBhbmQgd2UgaGF2ZSB0ZXN0cyB0aGF0IGNoZWNrIHdlIGRvbid0LgorICAgICAgICB0aGlzLnJlcGxhY2VtZW50Qnl0ZXMgPSByZXBsYWNlbWVudDsKKyAgICAgICAgaW1wbFJlcGxhY2VXaXRoKHJlcGxhY2VtZW50Qnl0ZXMpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhpcyBlbmNvZGVyLiBUaGlzIG1ldGhvZCB3aWxsIHJlc2V0IHRoZSBpbnRlcm5hbCBzdGF0dXMgYW5kIHRoZW4KKyAgICAgKiBjYWxscyA8Y29kZT5pbXBsUmVzZXQoKTwvY29kZT4gdG8gcmVzZXQgYW55IHN0YXR1cyByZWxhdGVkIHRvIHRoZQorICAgICAqIHNwZWNpZmljIGNoYXJzZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgZW5jb2Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQ2hhcnNldEVuY29kZXIgcmVzZXQoKSB7CisgICAgICAgIHN0YXR1cyA9IElOSVQ7CisgICAgICAgIGltcGxSZXNldCgpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgZW5jb2RlcidzIDxjb2RlPkNvZGluZ0Vycm9yQWN0aW9uPC9jb2RlPiB3aGVuIHVubWFwcGFibGUKKyAgICAgKiBjaGFyYWN0ZXIgb2NjdXJyZWQgZHVyaW5nIGVuY29kaW5nIHByb2Nlc3MuCisgICAgICovCisgICAgcHVibGljIENvZGluZ0Vycm9yQWN0aW9uIHVubWFwcGFibGVDaGFyYWN0ZXJBY3Rpb24oKSB7CisgICAgICAgIHJldHVybiB1bm1hcHBhYmxlQ2hhcmFjdGVyQWN0aW9uOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L0NoYXJzZXRFbmNvZGVySUNVLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0RW5jb2RlcklDVS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNmMDcxY2EKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0RW5jb2RlcklDVS5qYXZhCkBAIC0wLDAgKzEsMjYyIEBACisvKioKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyogQ29weXJpZ2h0IChDKSAxOTk2LTIwMDYsIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kICAgICoKKyogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgorKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorKgorKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorKi8KKy8qKgorICogQSBKTkkgaW50ZXJmYWNlIGZvciBJQ1UgY29udmVydGVycy4KKyAqCisgKgorICogQGF1dGhvciBSYW0gVmlzd2FuYWRoYSwgSUJNCisgKi8KK3BhY2thZ2UgamF2YS5uaW8uY2hhcnNldDsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uQ2hhckJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGxpYmNvcmUuaWN1LkVycm9yQ29kZTsKK2ltcG9ydCBsaWJjb3JlLmljdS5OYXRpdmVDb252ZXJ0ZXI7CitpbXBvcnQgbGliY29yZS51dGlsLkVtcHR5QXJyYXk7CisKK2ZpbmFsIGNsYXNzIENoYXJzZXRFbmNvZGVySUNVIGV4dGVuZHMgQ2hhcnNldEVuY29kZXIgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsIGJ5dGVbXT4gREVGQVVMVF9SRVBMQUNFTUVOVFMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIGJ5dGVbXT4oKTsKKyAgICBzdGF0aWMgeworICAgICAgICAvLyBJQ1UgaGFzIGRpZmZlcmVudCBkZWZhdWx0IHJlcGxhY2VtZW50cyB0byB0aGUgUkkgaW4gc29tZSBjYXNlcy4gVGhlcmUgYXJlIG1hbnkKKyAgICAgICAgLy8gYWRkaXRpb25hbCBjYXNlcywgYnV0IHRoaXMgY292ZXJzIGFsbCB0aGUgY2hhcnNldHMgdGhhdCBKYXZhIGd1YXJhbnRlZXMgd2lsbCBiZQorICAgICAgICAvLyBhdmFpbGFibGUsIHdoaWNoIGlzIHdoZXJlIGNvbXBhdGliaWxpdHkgc2VlbXMgbW9zdCBpbXBvcnRhbnQuIChUaGUgUkkgZXZlbiB1c2VzCisgICAgICAgIC8vIHRoZSBieXRlIGNvcnJlc3BvbmRpbmcgdG8gJz8nIGluIEFTQ0lJIGFzIHRoZSByZXBsYWNlbWVudCBieXRlIGZvciBjaGFyc2V0cyB3aGVyZSB0aGF0CisgICAgICAgIC8vIGJ5dGUgY29ycmVzcG9uZHMgdG8gYW4gZW50aXJlbHkgZGlmZmVyZW50IGNoYXJhY3Rlci4pCisgICAgICAgIC8vIEl0J3Mgb2RkIHRoYXQgVVRGLTggZG9lc24ndCB1c2UgVStGRkZELCBnaXZlbiB0aGF0ICh1bmxpa2UgSVNPLTg4NTktMSBhbmQgVVMtQVNDSUkpIGl0CisgICAgICAgIC8vIGNhbiByZXByZXNlbnQgaXQsIGJ1dCB0aGlzIGlzIHdoYXQgdGhlIFJJIGRvZXMuLi4KKyAgICAgICAgYnl0ZVtdIHF1ZXN0aW9uTWFyayA9IG5ldyBieXRlW10geyAoYnl0ZSkgJz8nIH07CisgICAgICAgIERFRkFVTFRfUkVQTEFDRU1FTlRTLnB1dCgiVVRGLTgiLCAgICAgIHF1ZXN0aW9uTWFyayk7CisgICAgICAgIERFRkFVTFRfUkVQTEFDRU1FTlRTLnB1dCgiSVNPLTg4NTktMSIsIHF1ZXN0aW9uTWFyayk7CisgICAgICAgIERFRkFVTFRfUkVQTEFDRU1FTlRTLnB1dCgiVVMtQVNDSUkiLCAgIHF1ZXN0aW9uTWFyayk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOUFVUX09GRlNFVCA9IDA7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE9VVFBVVF9PRkZTRVQgPSAxOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTlZBTElEX0NIQVJTID0gMjsKKyAgICAvKgorICAgICAqIGRhdGFbSU5QVVRfT0ZGU0VUXSAgID0gb24gaW5wdXQgY29udGFpbnMgdGhlIHN0YXJ0IG9mIGlucHV0IGFuZCBvbiBvdXRwdXQgdGhlIG51bWJlciBvZiBpbnB1dCBjaGFycyBjb25zdW1lZAorICAgICAqIGRhdGFbT1VUUFVUX09GRlNFVF0gID0gb24gaW5wdXQgY29udGFpbnMgdGhlIHN0YXJ0IG9mIG91dHB1dCBhbmQgb24gb3V0cHV0IHRoZSBudW1iZXIgb2Ygb3V0cHV0IGJ5dGVzIHdyaXR0ZW4KKyAgICAgKiBkYXRhW0lOVkFMSURfQ0hBUlNdICA9IG51bWJlciBvZiBpbnZhbGlkIGNoYXJzCisgICAgICovCisgICAgcHJpdmF0ZSBpbnRbXSBkYXRhID0gbmV3IGludFszXTsKKworICAgIC8qIGhhbmRsZSB0byB0aGUgSUNVIGNvbnZlcnRlciB0aGF0IGlzIG9wZW5lZCAqLworICAgIHByaXZhdGUgbG9uZyBjb252ZXJ0ZXJIYW5kbGU9MDsKKworICAgIHByaXZhdGUgY2hhcltdIGlucHV0ID0gbnVsbDsKKyAgICBwcml2YXRlIGJ5dGVbXSBvdXRwdXQgPSBudWxsOworCisgICAgcHJpdmF0ZSBjaGFyW10gYWxsb2NhdGVkSW5wdXQgPSBudWxsOworICAgIHByaXZhdGUgYnl0ZVtdIGFsbG9jYXRlZE91dHB1dCA9IG51bGw7CisKKyAgICAvLyBUaGVzZSBpbnN0YW5jZSB2YXJpYWJsZXMgYXJlIGFsd2F5cyBhc3NpZ25lZCBpbiB0aGUgbWV0aG9kcyBiZWZvcmUgYmVpbmcgdXNlZC4gVGhpcyBjbGFzcworICAgIC8vIGlzIGluaGVyZW50bHkgdGhyZWFkLXVuc2FmZSBzbyB3ZSBkb24ndCBoYXZlIHRvIHdvcnJ5IGFib3V0IHN5bmNocm9uaXphdGlvbi4KKyAgICBwcml2YXRlIGludCBpbkVuZDsKKyAgICBwcml2YXRlIGludCBvdXRFbmQ7CisgICAgcHJpdmF0ZSBpbnQgZWM7CisKKyAgICBwdWJsaWMgc3RhdGljIENoYXJzZXRFbmNvZGVySUNVIG5ld0luc3RhbmNlKENoYXJzZXQgY3MsIFN0cmluZyBpY3VDYW5vbmljYWxOYW1lKSB7CisgICAgICAgIC8vIFRoaXMgY29tcGxleGl0eSBpcyBuZWNlc3NhcnkgdG8gZW5zdXJlIHRoYXQgZXZlbiBpZiB0aGUgY29uc3RydWN0b3IsIHN1cGVyY2xhc3MKKyAgICAgICAgLy8gY29uc3RydWN0b3IsIG9yIGNhbGwgdG8gdXBkYXRlQ2FsbGJhY2sgdGhyb3csIHdlIHN0aWxsIGZyZWUgdGhlIG5hdGl2ZSBwZWVyLgorICAgICAgICBsb25nIGFkZHJlc3MgPSAwOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWRkcmVzcyA9IE5hdGl2ZUNvbnZlcnRlci5vcGVuQ29udmVydGVyKGljdUNhbm9uaWNhbE5hbWUpOworICAgICAgICAgICAgZmxvYXQgYXZlcmFnZUJ5dGVzUGVyQ2hhciA9IE5hdGl2ZUNvbnZlcnRlci5nZXRBdmVCeXRlc1BlckNoYXIoYWRkcmVzcyk7CisgICAgICAgICAgICBmbG9hdCBtYXhCeXRlc1BlckNoYXIgPSBOYXRpdmVDb252ZXJ0ZXIuZ2V0TWF4Qnl0ZXNQZXJDaGFyKGFkZHJlc3MpOworICAgICAgICAgICAgYnl0ZVtdIHJlcGxhY2VtZW50ID0gbWFrZVJlcGxhY2VtZW50KGljdUNhbm9uaWNhbE5hbWUsIGFkZHJlc3MpOworICAgICAgICAgICAgQ2hhcnNldEVuY29kZXJJQ1UgcmVzdWx0ID0gbmV3IENoYXJzZXRFbmNvZGVySUNVKGNzLCBhdmVyYWdlQnl0ZXNQZXJDaGFyLCBtYXhCeXRlc1BlckNoYXIsIHJlcGxhY2VtZW50LCBhZGRyZXNzKTsKKyAgICAgICAgICAgIGFkZHJlc3MgPSAwOyAvLyBDaGFyc2V0RW5jb2RlcklDVSBoYXMgdGFrZW4gb3duZXJzaGlwOyBpdHMgZmluYWxpemVyIHdpbGwgZG8gdGhlIGZyZWUuCisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGFkZHJlc3MgIT0gMCkgeworICAgICAgICAgICAgICAgIE5hdGl2ZUNvbnZlcnRlci5jbG9zZUNvbnZlcnRlcihhZGRyZXNzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBtYWtlUmVwbGFjZW1lbnQoU3RyaW5nIGljdUNhbm9uaWNhbE5hbWUsIGxvbmcgYWRkcmVzcykgeworICAgICAgICAvLyBXZSBoYXZlIG91ciBvd24gbWFwIG9mIFJJLWNvbXBhdGlibGUgZGVmYXVsdCByZXBsYWNlbWVudHMgKHdoZXJlIElDVSBkaXNhZ3JlZXMpLi4uCisgICAgICAgIGJ5dGVbXSByZXBsYWNlbWVudCA9IERFRkFVTFRfUkVQTEFDRU1FTlRTLmdldChpY3VDYW5vbmljYWxOYW1lKTsKKyAgICAgICAgaWYgKHJlcGxhY2VtZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiByZXBsYWNlbWVudC5jbG9uZSgpOworICAgICAgICB9CisgICAgICAgIC8vIC4uLmJ1dCBmYWxsIGJhY2sgdG8gYXNraW5nIElDVS4KKyAgICAgICAgcmV0dXJuIE5hdGl2ZUNvbnZlcnRlci5nZXRTdWJzdGl0dXRpb25CeXRlcyhhZGRyZXNzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIENoYXJzZXRFbmNvZGVySUNVKENoYXJzZXQgY3MsIGZsb2F0IGF2ZXJhZ2VCeXRlc1BlckNoYXIsIGZsb2F0IG1heEJ5dGVzUGVyQ2hhciwgYnl0ZVtdIHJlcGxhY2VtZW50LCBsb25nIGFkZHJlc3MpIHsKKyAgICAgICAgc3VwZXIoY3MsIGF2ZXJhZ2VCeXRlc1BlckNoYXIsIG1heEJ5dGVzUGVyQ2hhciwgcmVwbGFjZW1lbnQsIHRydWUpOworICAgICAgICAvLyBPdXIgbmF0aXZlIHBlZXIgbmVlZHMgdG8ga25vdyB3aGF0IGp1c3QgaGFwcGVuZWQuLi4KKyAgICAgICAgdGhpcy5jb252ZXJ0ZXJIYW5kbGUgPSBhZGRyZXNzOworICAgICAgICB1cGRhdGVDYWxsYmFjaygpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBpbXBsUmVwbGFjZVdpdGgoYnl0ZVtdIG5ld1JlcGxhY2VtZW50KSB7CisgICAgICAgIHVwZGF0ZUNhbGxiYWNrKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGltcGxPbk1hbGZvcm1lZElucHV0KENvZGluZ0Vycm9yQWN0aW9uIG5ld0FjdGlvbikgeworICAgICAgICB1cGRhdGVDYWxsYmFjaygpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBpbXBsT25Vbm1hcHBhYmxlQ2hhcmFjdGVyKENvZGluZ0Vycm9yQWN0aW9uIG5ld0FjdGlvbikgeworICAgICAgICB1cGRhdGVDYWxsYmFjaygpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB1cGRhdGVDYWxsYmFjaygpIHsKKyAgICAgICAgZWMgPSBOYXRpdmVDb252ZXJ0ZXIuc2V0Q2FsbGJhY2tFbmNvZGUoY29udmVydGVySGFuZGxlLCB0aGlzKTsKKyAgICAgICAgaWYgKEVycm9yQ29kZS5pc0ZhaWx1cmUoZWMpKSB7CisgICAgICAgICAgICB0aHJvdyBFcnJvckNvZGUudGhyb3dFeGNlcHRpb24oZWMpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGltcGxSZXNldCgpIHsKKyAgICAgICAgTmF0aXZlQ29udmVydGVyLnJlc2V0Q2hhclRvQnl0ZShjb252ZXJ0ZXJIYW5kbGUpOworICAgICAgICBkYXRhW0lOUFVUX09GRlNFVF0gPSAwOworICAgICAgICBkYXRhW09VVFBVVF9PRkZTRVRdID0gMDsKKyAgICAgICAgZGF0YVtJTlZBTElEX0NIQVJTXSA9IDA7CisgICAgICAgIG91dHB1dCA9IG51bGw7CisgICAgICAgIGlucHV0ID0gbnVsbDsKKyAgICAgICAgYWxsb2NhdGVkSW5wdXQgPSBudWxsOworICAgICAgICBhbGxvY2F0ZWRPdXRwdXQgPSBudWxsOworICAgICAgICBlYyA9IDA7CisgICAgICAgIGluRW5kID0gMDsKKyAgICAgICAgb3V0RW5kID0gMDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIENvZGVyUmVzdWx0IGltcGxGbHVzaChCeXRlQnVmZmVyIG91dCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gSUNVIG5lZWRzIHRvIHNlZSBhbiBlbXB0eSBpbnB1dC4KKyAgICAgICAgICAgIGlucHV0ID0gRW1wdHlBcnJheS5DSEFSOworICAgICAgICAgICAgaW5FbmQgPSAwOworICAgICAgICAgICAgZGF0YVtJTlBVVF9PRkZTRVRdID0gMDsKKworICAgICAgICAgICAgZGF0YVtPVVRQVVRfT0ZGU0VUXSA9IGdldEFycmF5KG91dCk7CisgICAgICAgICAgICBkYXRhW0lOVkFMSURfQ0hBUlNdID0gMDsgLy8gTWFrZSBzdXJlIHdlIGRvbid0IHNlZSBlYXJsaWVyIGVycm9ycy4KKworICAgICAgICAgICAgZWMgPSBOYXRpdmVDb252ZXJ0ZXIuZW5jb2RlKGNvbnZlcnRlckhhbmRsZSwgaW5wdXQsIGluRW5kLCBvdXRwdXQsIG91dEVuZCwgZGF0YSwgdHJ1ZSk7CisgICAgICAgICAgICBpZiAoRXJyb3JDb2RlLmlzRmFpbHVyZShlYykpIHsKKyAgICAgICAgICAgICAgICBpZiAoZWMgPT0gRXJyb3JDb2RlLlVfQlVGRkVSX09WRVJGTE9XX0VSUk9SKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBDb2RlclJlc3VsdC5PVkVSRkxPVzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVjID09IEVycm9yQ29kZS5VX1RSVU5DQVRFRF9DSEFSX0ZPVU5EKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhW0lOUFVUX09GRlNFVF0gPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29kZXJSZXN1bHQubWFsZm9ybWVkRm9yTGVuZ3RoKGRhdGFbSU5QVVRfT0ZGU0VUXSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvckNvZGUudGhyb3dFeGNlcHRpb24oZWMpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBDb2RlclJlc3VsdC5VTkRFUkZMT1c7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzZXRQb3NpdGlvbihvdXQpOworICAgICAgICAgICAgaW1wbFJlc2V0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIENvZGVyUmVzdWx0IGVuY29kZUxvb3AoQ2hhckJ1ZmZlciBpbiwgQnl0ZUJ1ZmZlciBvdXQpIHsKKyAgICAgICAgaWYgKCFpbi5oYXNSZW1haW5pbmcoKSkgeworICAgICAgICAgICAgcmV0dXJuIENvZGVyUmVzdWx0LlVOREVSRkxPVzsKKyAgICAgICAgfQorCisgICAgICAgIGRhdGFbSU5QVVRfT0ZGU0VUXSA9IGdldEFycmF5KGluKTsKKyAgICAgICAgZGF0YVtPVVRQVVRfT0ZGU0VUXT0gZ2V0QXJyYXkob3V0KTsKKyAgICAgICAgZGF0YVtJTlZBTElEX0NIQVJTXSA9IDA7IC8vIE1ha2Ugc3VyZSB3ZSBkb24ndCBzZWUgZWFybGllciBlcnJvcnMuCisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVjID0gTmF0aXZlQ29udmVydGVyLmVuY29kZShjb252ZXJ0ZXJIYW5kbGUsIGlucHV0LCBpbkVuZCwgb3V0cHV0LCBvdXRFbmQsIGRhdGEsIGZhbHNlKTsKKyAgICAgICAgICAgIGlmIChFcnJvckNvZGUuaXNGYWlsdXJlKGVjKSkgeworICAgICAgICAgICAgICAgIGlmIChlYyA9PSBFcnJvckNvZGUuVV9CVUZGRVJfT1ZFUkZMT1dfRVJST1IpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvZGVyUmVzdWx0Lk9WRVJGTE9XOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZWMgPT0gRXJyb3JDb2RlLlVfSU5WQUxJRF9DSEFSX0ZPVU5EKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBDb2RlclJlc3VsdC51bm1hcHBhYmxlRm9yTGVuZ3RoKGRhdGFbSU5WQUxJRF9DSEFSU10pOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZWMgPT0gRXJyb3JDb2RlLlVfSUxMRUdBTF9DSEFSX0ZPVU5EKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBDb2RlclJlc3VsdC5tYWxmb3JtZWRGb3JMZW5ndGgoZGF0YVtJTlZBTElEX0NIQVJTXSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJ1bmV4cGVjdGVkIGZhaWx1cmU6ICIgKyBlYyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gRGVjb2Rpbmcgc3VjY2VlZGVkOiBnaXZlIHVzIG1vcmUgZGF0YS4KKyAgICAgICAgICAgIHJldHVybiBDb2RlclJlc3VsdC5VTkRFUkZMT1c7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzZXRQb3NpdGlvbihpbik7CisgICAgICAgICAgICBzZXRQb3NpdGlvbihvdXQpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gY2FuRW5jb2RlKGNoYXIgYykgeworICAgICAgICByZXR1cm4gY2FuRW5jb2RlKChpbnQpIGMpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNhbkVuY29kZShpbnQgY29kZVBvaW50KSB7CisgICAgICAgIHJldHVybiBOYXRpdmVDb252ZXJ0ZXIuY2FuRW5jb2RlKGNvbnZlcnRlckhhbmRsZSwgY29kZVBvaW50KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNvbnZlcnRlci5jbG9zZUNvbnZlcnRlcihjb252ZXJ0ZXJIYW5kbGUpOworICAgICAgICAgICAgY29udmVydGVySGFuZGxlPTA7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzdXBlci5maW5hbGl6ZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgZ2V0QXJyYXkoQnl0ZUJ1ZmZlciBvdXQpIHsKKyAgICAgICAgaWYgKG91dC5oYXNBcnJheSgpKSB7CisgICAgICAgICAgICBvdXRwdXQgPSBvdXQuYXJyYXkoKTsKKyAgICAgICAgICAgIG91dEVuZCA9IG91dC5hcnJheU9mZnNldCgpICsgb3V0LmxpbWl0KCk7CisgICAgICAgICAgICByZXR1cm4gb3V0LmFycmF5T2Zmc2V0KCkgKyBvdXQucG9zaXRpb24oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG91dEVuZCA9IG91dC5yZW1haW5pbmcoKTsKKyAgICAgICAgICAgIGlmIChhbGxvY2F0ZWRPdXRwdXQgPT0gbnVsbCB8fCBvdXRFbmQgPiBhbGxvY2F0ZWRPdXRwdXQubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgYWxsb2NhdGVkT3V0cHV0ID0gbmV3IGJ5dGVbb3V0RW5kXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIFRoZSBhcnJheSdzIHN0YXJ0IHBvc2l0aW9uIGlzIDAKKyAgICAgICAgICAgIG91dHB1dCA9IGFsbG9jYXRlZE91dHB1dDsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgZ2V0QXJyYXkoQ2hhckJ1ZmZlciBpbikgeworICAgICAgICBpZiAoaW4uaGFzQXJyYXkoKSkgeworICAgICAgICAgICAgaW5wdXQgPSBpbi5hcnJheSgpOworICAgICAgICAgICAgaW5FbmQgPSBpbi5hcnJheU9mZnNldCgpICsgaW4ubGltaXQoKTsKKyAgICAgICAgICAgIHJldHVybiBpbi5hcnJheU9mZnNldCgpICsgaW4ucG9zaXRpb24oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGluRW5kID0gaW4ucmVtYWluaW5nKCk7CisgICAgICAgICAgICBpZiAoYWxsb2NhdGVkSW5wdXQgPT0gbnVsbCB8fCBpbkVuZCA+IGFsbG9jYXRlZElucHV0Lmxlbmd0aCkgeworICAgICAgICAgICAgICAgIGFsbG9jYXRlZElucHV0ID0gbmV3IGNoYXJbaW5FbmRdOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gQ29weSB0aGUgaW5wdXQgYnVmZmVyIGludG8gdGhlIGFsbG9jYXRlZCBhcnJheS4KKyAgICAgICAgICAgIGludCBwb3MgPSBpbi5wb3NpdGlvbigpOworICAgICAgICAgICAgaW4uZ2V0KGFsbG9jYXRlZElucHV0LCAwLCBpbkVuZCk7CisgICAgICAgICAgICBpbi5wb3NpdGlvbihwb3MpOworICAgICAgICAgICAgLy8gVGhlIGFycmF5J3Mgc3RhcnQgcG9zaXRpb24gaXMgMAorICAgICAgICAgICAgaW5wdXQgPSBhbGxvY2F0ZWRJbnB1dDsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNldFBvc2l0aW9uKEJ5dGVCdWZmZXIgb3V0KSB7CisgICAgICAgIGlmIChvdXQuaGFzQXJyYXkoKSkgeworICAgICAgICAgICAgb3V0LnBvc2l0aW9uKG91dC5wb3NpdGlvbigpICsgZGF0YVtPVVRQVVRfT0ZGU0VUXSAtIG91dC5hcnJheU9mZnNldCgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG91dC5wdXQob3V0cHV0LCAwLCBkYXRhW09VVFBVVF9PRkZTRVRdKTsKKyAgICAgICAgfQorICAgICAgICAvLyByZWxlYXNlIHJlZmVyZW5jZSB0byBvdXRwdXQgYXJyYXksIHdoaWNoIG1heSBub3QgYmUgb3VycworICAgICAgICBvdXRwdXQgPSBudWxsOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzZXRQb3NpdGlvbihDaGFyQnVmZmVyIGluKSB7CisgICAgICAgIGluLnBvc2l0aW9uKGluLnBvc2l0aW9uKCkgKyBkYXRhW0lOUFVUX09GRlNFVF0gLSBkYXRhW0lOVkFMSURfQ0hBUlNdKTsKKyAgICAgICAgLy8gcmVsZWFzZSByZWZlcmVuY2UgdG8gaW5wdXQgYXJyYXksIHdoaWNoIG1heSBub3QgYmUgb3VycworICAgICAgICBpbnB1dCA9IG51bGw7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldElDVS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldElDVS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYzZTNmZTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0SUNVLmphdmEKQEAgLTAsMCArMSwzOCBAQAorLyoqCisqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisqIENvcHlyaWdodCAoQykgMTk5Ni0yMDA1LCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZCAgICAqCisqIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCisqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisqCisqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisqLworCitwYWNrYWdlIGphdmEubmlvLmNoYXJzZXQ7CisKK2ltcG9ydCBsaWJjb3JlLmljdS5OYXRpdmVDb252ZXJ0ZXI7CisKK2ZpbmFsIGNsYXNzIENoYXJzZXRJQ1UgZXh0ZW5kcyBDaGFyc2V0IHsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBpY3VDYW5vbmljYWxOYW1lOworCisgICAgcHJvdGVjdGVkIENoYXJzZXRJQ1UoU3RyaW5nIGNhbm9uaWNhbE5hbWUsIFN0cmluZyBpY3VDYW5vbk5hbWUsIFN0cmluZ1tdIGFsaWFzZXMpIHsKKyAgICAgICAgIHN1cGVyKGNhbm9uaWNhbE5hbWUsIGFsaWFzZXMpOworICAgICAgICAgaWN1Q2Fub25pY2FsTmFtZSA9IGljdUNhbm9uTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgQ2hhcnNldERlY29kZXIgbmV3RGVjb2RlcigpIHsKKyAgICAgICAgcmV0dXJuIENoYXJzZXREZWNvZGVySUNVLm5ld0luc3RhbmNlKHRoaXMsIGljdUNhbm9uaWNhbE5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyBDaGFyc2V0RW5jb2RlciBuZXdFbmNvZGVyKCkgeworICAgICAgICByZXR1cm4gQ2hhcnNldEVuY29kZXJJQ1UubmV3SW5zdGFuY2UodGhpcywgaWN1Q2Fub25pY2FsTmFtZSk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoQ2hhcnNldCBjcykgeworICAgICAgICBpZiAoY3MgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZXF1YWxzKGNzKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIE5hdGl2ZUNvbnZlcnRlci5jb250YWlucyh0aGlzLm5hbWUoKSwgY3MubmFtZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0cy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYzI0MjVhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldHMuamF2YQpAQCAtMCwwICsxLDk5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFyc2V0OworCisvKioKKyAqIFByb3ZpZGVzIGNvbnZlbmllbnQgYWNjZXNzIHRvIHRoZSBtb3N0IGltcG9ydGFudCBidWlsdC1pbiBjaGFyc2V0cy4gU2F2ZXMgYSBoYXNoIGxvb2t1cCBhbmQKKyAqIHVubmVjZXNzYXJ5IGhhbmRsaW5nIG9mIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gYXQgY2FsbCBzaXRlcywgY29tcGFyZWQgdG8gdXNpbmcgdGhlCisgKiBjaGFyc2V0J3MgbmFtZS4KKyAqCisgKiBBbHNvIHZhcmlvdXMgc3BlY2lhbC1jYXNlIGNoYXJzZXQgY29udmVyc2lvbnMgKGZvciBwZXJmb3JtYW5jZSkuCisgKgorICogQGhpZGUgaW50ZXJuYWwgdXNlIG9ubHkKKyAqLworcHVibGljIGNsYXNzIENoYXJzZXRzIHsKKyAgICAvKioKKyAgICAgKiBBIGNoZWFwIGFuZCB0eXBlLXNhZmUgY29uc3RhbnQgZm9yIHRoZSBJU08tODg1OS0xIENoYXJzZXQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDaGFyc2V0IElTT184ODU5XzEgPSBDaGFyc2V0LmZvck5hbWUoIklTTy04ODU5LTEiKTsKKworICAgIC8qKgorICAgICAqIEEgY2hlYXAgYW5kIHR5cGUtc2FmZSBjb25zdGFudCBmb3IgdGhlIFVTLUFTQ0lJIENoYXJzZXQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDaGFyc2V0IFVTX0FTQ0lJID0gQ2hhcnNldC5mb3JOYW1lKCJVUy1BU0NJSSIpOworCisgICAgLyoqCisgICAgICogQSBjaGVhcCBhbmQgdHlwZS1zYWZlIGNvbnN0YW50IGZvciB0aGUgVVRGLTggQ2hhcnNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENoYXJzZXQgVVRGXzggPSBDaGFyc2V0LmZvck5hbWUoIlVURi04Iik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGJ5dGUgYXJyYXkgY29udGFpbmluZyB0aGUgYnl0ZXMgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gY2hhcmFjdGVycywKKyAgICAgKiBlbmNvZGVkIGluIFVTLUFTQ0lJLiBVbnJlcHJlc2VudGFibGUgY2hhcmFjdGVycyBhcmUgcmVwbGFjZWQgYnkgKGJ5dGUpICc/Jy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBieXRlW10gdG9Bc2NpaUJ5dGVzKGNoYXJbXSBjaGFycywgaW50IG9mZnNldCwgaW50IGxlbmd0aCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGJ5dGUgYXJyYXkgY29udGFpbmluZyB0aGUgYnl0ZXMgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gY2hhcmFjdGVycywKKyAgICAgKiBlbmNvZGVkIGluIElTTy04ODU5LTEuIFVucmVwcmVzZW50YWJsZSBjaGFyYWN0ZXJzIGFyZSByZXBsYWNlZCBieSAoYnl0ZSkgJz8nLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJ5dGVbXSB0b0lzb0xhdGluMUJ5dGVzKGNoYXJbXSBjaGFycywgaW50IG9mZnNldCwgaW50IGxlbmd0aCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGJ5dGUgYXJyYXkgY29udGFpbmluZyB0aGUgYnl0ZXMgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gY2hhcmFjdGVycywKKyAgICAgKiBlbmNvZGVkIGluIFVURi04LiBBbGwgY2hhcmFjdGVycyBhcmUgcmVwcmVzZW50YWJsZSBpbiBVVEYtOC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBieXRlW10gdG9VdGY4Qnl0ZXMoY2hhcltdIGNoYXJzLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgYnl0ZSBhcnJheSBjb250YWluaW5nIHRoZSBieXRlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbiBjaGFyYWN0ZXJzLAorICAgICAqIGVuY29kZWQgaW4gVVRGLTE2QkUuIEFsbCBjaGFyYWN0ZXJzIGFyZSByZXByZXNlbnRhYmxlIGluIFVURi0xNkJFLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIHRvQmlnRW5kaWFuVXRmMTZCeXRlcyhjaGFyW10gY2hhcnMsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW2xlbmd0aCAqIDJdOworICAgICAgICBpbnQgZW5kID0gb2Zmc2V0ICsgbGVuZ3RoOworICAgICAgICBpbnQgcmVzdWx0SW5kZXggPSAwOworICAgICAgICBmb3IgKGludCBpID0gb2Zmc2V0OyBpIDwgZW5kOyArK2kpIHsKKyAgICAgICAgICAgIGNoYXIgY2ggPSBjaGFyc1tpXTsKKyAgICAgICAgICAgIHJlc3VsdFtyZXN1bHRJbmRleCsrXSA9IChieXRlKSAoY2ggPj4gOCk7CisgICAgICAgICAgICByZXN1bHRbcmVzdWx0SW5kZXgrK10gPSAoYnl0ZSkgY2g7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvZGVzIHRoZSBnaXZlbiBVUy1BU0NJSSBieXRlcyBpbnRvIHRoZSBnaXZlbiBjaGFyW10uIEVxdWl2YWxlbnQgdG8gYnV0IGZhc3RlciB0aGFuOgorICAgICAqCisgICAgICogZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7CisgICAgICogICAgIGNoYXIgY2ggPSAoY2hhcikgKGRhdGFbc3RhcnQrK10gJiAweGZmKTsKKyAgICAgKiAgICAgdmFsdWVbaV0gPSAoY2ggPD0gMHg3ZikgPyBjaCA6IFJFUExBQ0VNRU5UX0NIQVI7CisgICAgICogfQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgYXNjaWlCeXRlc1RvQ2hhcnMoYnl0ZVtdIGJ5dGVzLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoLCBjaGFyW10gY2hhcnMpOworCisgICAgLyoqCisgICAgICogRGVjb2RlcyB0aGUgZ2l2ZW4gSVNPLTg4NTktMSBieXRlcyBpbnRvIHRoZSBnaXZlbiBjaGFyW10uIEVxdWl2YWxlbnQgdG8gYnV0IGZhc3RlciB0aGFuOgorICAgICAqCisgICAgICogZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7CisgICAgICogICAgIHZhbHVlW2ldID0gKGNoYXIpIChkYXRhW3N0YXJ0KytdICYgMHhmZik7CisgICAgICogfQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgaXNvTGF0aW4xQnl0ZXNUb0NoYXJzKGJ5dGVbXSBieXRlcywgaW50IG9mZnNldCwgaW50IGxlbmd0aCwgY2hhcltdIGNoYXJzKTsKKworICAgIHByaXZhdGUgQ2hhcnNldHMoKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvQ29kZXJNYWxmdW5jdGlvbkVycm9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhcnNldC9Db2Rlck1hbGZ1bmN0aW9uRXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNzA0ZjU4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvQ29kZXJNYWxmdW5jdGlvbkVycm9yLmphdmEKQEAgLTAsMCArMSw0MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFyc2V0OworCisvKioKKyAqIEEge0Bjb2RlIENvZGVyTWFsZnVuY3Rpb25FcnJvcn0gaXMgdGhyb3duIHdoZW4gdGhlIGVuY29kZXIvZGVjb2RlciBpcworICogbWFsZnVuY3Rpb25pbmcuCisgKi8KK3B1YmxpYyBjbGFzcyBDb2Rlck1hbGZ1bmN0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7CisKKyAgICAvKgorICAgICAqIFRoaXMgY29uc3RhbnQgaXMgdXNlZCBkdXJpbmcgZGVzZXJpYWxpemF0aW9uIHRvIGNoZWNrIHRoZSB2ZXJzaW9uCisgICAgICogd2hpY2ggY3JlYXRlZCB0aGUgc2VyaWFsaXplZCBvYmplY3QuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTExNTE0MTIzNDgwNTc3OTQzMDFMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQ29kZXJNYWxmdW5jdGlvbkVycm9yfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleAorICAgICAqICAgICAgICAgICAgdGhlIG9yaWdpbmFsIGV4Y2VwdGlvbiB0aHJvd24gYnkgdGhlIGVuY29kZXIvZGVjb2Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29kZXJNYWxmdW5jdGlvbkVycm9yKEV4Y2VwdGlvbiBleCkgeworICAgICAgICBzdXBlcihleCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvQ29kZXJSZXN1bHQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L0NvZGVyUmVzdWx0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjIxY2IzMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L0NvZGVyUmVzdWx0LmphdmEKQEAgLTAsMCArMSwyNzggQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhcnNldDsKKworaW1wb3J0IGphdmEubmlvLkJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuV2Vha0hhc2hNYXA7CisKKy8qKgorICogVXNlZCB0byBpbmRpY2F0ZSB0aGUgcmVzdWx0IG9mIGVuY29kaW5nL2RlY29kaW5nLiBUaGVyZSBhcmUgZm91ciB0eXBlcyBvZgorICogcmVzdWx0czoKKyAqIDxvbD4KKyAqIDxsaT5VTkRFUkZMT1cgaW5kaWNhdGVzIHRoYXQgYWxsIGlucHV0IGhhcyBiZWVuIHByb2Nlc3NlZCBidXQgbW9yZSBpbnB1dCBpcworICogcmVxdWlyZWQuIEl0IGlzIHJlcHJlc2VudGVkIGJ5IHRoZSB1bmlxdWUgb2JqZWN0CisgKiA8Y29kZT5Db2RlclJlc3VsdC5VTkRFUkZMT1c8L2NvZGU+LgorICogPGxpPk9WRVJGTE9XIGluZGljYXRlcyBhbiBpbnN1ZmZpY2llbnQgb3V0cHV0IGJ1ZmZlciBzaXplLiBJdCBpcyByZXByZXNlbnRlZAorICogYnkgdGhlIHVuaXF1ZSBvYmplY3QgPGNvZGU+Q29kZXJSZXN1bHQuT1ZFUkZMT1c8L2NvZGU+LgorICogPGxpPkEgbWFsZm9ybWVkLWlucHV0IGVycm9yIGluZGljYXRlcyB0aGF0IGFuIHVucmVjb2duaXphYmxlIHNlcXVlbmNlIG9mCisgKiBpbnB1dCB1bml0cyBoYXMgYmVlbiBlbmNvdW50ZXJlZC4gR2V0IGFuIGluc3RhbmNlIG9mIHRoaXMgdHlwZSBvZiByZXN1bHQgYnkKKyAqIGNhbGxpbmcgPGNvZGU+Q29kZXJSZXN1bHQubWFsZm9ybWVkRm9yTGVuZ3RoKGludCk8L2NvZGU+IHdpdGggdGhlIGxlbmd0aCBvZgorICogdGhlIG1hbGZvcm1lZC1pbnB1dC4KKyAqIDxsaT5BbiB1bm1hcHBhYmxlLWNoYXJhY3RlciBlcnJvciBpbmRpY2F0ZXMgdGhhdCBhIHNlcXVlbmNlIG9mIGlucHV0IHVuaXRzCisgKiBjYW4gbm90IGJlIG1hcHBlZCB0byB0aGUgb3V0cHV0IGNoYXJzZXQuIEdldCBhbiBpbnN0YW5jZSBvZiB0aGlzIHR5cGUgb2YKKyAqIHJlc3VsdCBieSBjYWxsaW5nIDxjb2RlPkNvZGVyUmVzdWx0LnVubWFwcGFibGVGb3JMZW5ndGgoaW50KTwvY29kZT4gd2l0aAorICogdGhlIGlucHV0IHNlcXVlbmNlIHNpemUgaW5kaWNhdGluZyB0aGUgaWRlbnRpdHkgb2YgdGhlIHVubWFwcGFibGUgY2hhcmFjdGVyLgorICogPC9vbD4KKyAqLworcHVibGljIGNsYXNzIENvZGVyUmVzdWx0IHsKKworICAgIC8vIGluZGljYXRpbmcgdW5kZXJmbG93IGVycm9yIHR5cGUKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9VTkRFUkZMT1cgPSAxOworCisgICAgLy8gaW5kaWNhdGluZyBvdmVyZmxvdyBlcnJvciB0eXBlCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRZUEVfT1ZFUkZMT1cgPSAyOworCisgICAgLy8gaW5kaWNhdGluZyBtYWxmb3JtZWQtaW5wdXQgZXJyb3IgdHlwZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUWVBFX01BTEZPUk1FRF9JTlBVVCA9IDM7CisKKyAgICAvLyBpbmRpY2F0aW5nIHVubWFwcGFibGUgY2hhcmFjdGVyIGVycm9yIHR5cGUKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9VTk1BUFBBQkxFX0NIQVIgPSA0OworCisgICAgLyoqCisgICAgICogUmVzdWx0IG9iamVjdCBpbmRpY2F0aW5nIHRoYXQgdGhlcmUgaXMgaW5zdWZmaWNpZW50IGRhdGEgaW4gdGhlCisgICAgICogZW5jb2RpbmcvZGVjb2RpbmcgYnVmZmVyIG9yIHRoYXQgYWRkaXRpb25hbCBkYXRhIGlzIHJlcXVpcmVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29kZXJSZXN1bHQgVU5ERVJGTE9XID0gbmV3IENvZGVyUmVzdWx0KFRZUEVfVU5ERVJGTE9XLAorICAgICAgICAgICAgMCk7CisKKyAgICAvKioKKyAgICAgKiBSZXN1bHQgb2JqZWN0IHVzZWQgdG8gaW5kaWNhdGUgdGhhdCB0aGUgb3V0cHV0IGJ1ZmZlciBkb2VzIG5vdCBoYXZlCisgICAgICogZW5vdWdoIHNwYWNlIGF2YWlsYWJsZSB0byBzdG9yZSB0aGUgcmVzdWx0IG9mIHRoZSBlbmNvZGluZy9kZWNvZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvZGVyUmVzdWx0IE9WRVJGTE9XID0gbmV3IENvZGVyUmVzdWx0KFRZUEVfT1ZFUkZMT1csIDApOworCisgICAgLyoKKyAgICAgKiBTdG9yZXMgdW5pcXVlIHJlc3VsdCBvYmplY3RzIGZvciBlYWNoIG1hbGZvcm1lZC1pbnB1dCBlcnJvciBvZiBhIGNlcnRhaW4KKyAgICAgKiBsZW5ndGgKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBXZWFrSGFzaE1hcDxJbnRlZ2VyLCBDb2RlclJlc3VsdD4gX21hbGZvcm1lZEVycm9ycyA9IG5ldyBXZWFrSGFzaE1hcDxJbnRlZ2VyLCBDb2RlclJlc3VsdD4oKTsKKworICAgIC8qCisgICAgICogU3RvcmVzIHVuaXF1ZSByZXN1bHQgb2JqZWN0cyBmb3IgZWFjaCB1bm1hcHBhYmxlLWNoYXJhY3RlciBlcnJvciBvZiBhCisgICAgICogY2VydGFpbiBsZW5ndGgKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBXZWFrSGFzaE1hcDxJbnRlZ2VyLCBDb2RlclJlc3VsdD4gX3VubWFwcGFibGVFcnJvcnMgPSBuZXcgV2Vha0hhc2hNYXA8SW50ZWdlciwgQ29kZXJSZXN1bHQ+KCk7CisKKyAgICAvLyB0aGUgdHlwZSBvZiB0aGlzIHJlc3VsdAorICAgIHByaXZhdGUgZmluYWwgaW50IHR5cGU7CisKKyAgICAvLyB0aGUgbGVuZ3RoIG9mIHRoZSBlcnJvbmVvdXMgaW5wdXQKKyAgICBwcml2YXRlIGZpbmFsIGludCBsZW5ndGg7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgPGNvZGU+Q29kZXJSZXN1bHQ8L2NvZGU+IG9iamVjdCB3aXRoIGl0cyB0ZXh0IGRlc2NyaXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoaXMgcmVzdWx0CisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgZXJyb25lb3VzIGlucHV0CisgICAgICovCisgICAgcHJpdmF0ZSBDb2RlclJlc3VsdChpbnQgdHlwZSwgaW50IGxlbmd0aCkgeworICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgICAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgPGNvZGU+Q29kZXJSZXN1bHQ8L2NvZGU+IG9iamVjdCBpbmRpY2F0aW5nIGEgbWFsZm9ybWVkLWlucHV0CisgICAgICogZXJyb3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBtYWxmb3JtZWQtaW5wdXQuCisgICAgICogQHJldHVybiBhIDxjb2RlPkNvZGVyUmVzdWx0PC9jb2RlPiBvYmplY3QgaW5kaWNhdGluZyBhIG1hbGZvcm1lZC1pbnB1dAorICAgICAqICAgICAgICAgZXJyb3IuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiA8Y29kZT5sZW5ndGg8L2NvZGU+IGlzIG5vbi1wb3NpdGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBDb2RlclJlc3VsdCBtYWxmb3JtZWRGb3JMZW5ndGgoaW50IGxlbmd0aCkKKyAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBpZiAobGVuZ3RoID4gMCkgeworICAgICAgICAgICAgSW50ZWdlciBrZXkgPSBJbnRlZ2VyLnZhbHVlT2YobGVuZ3RoKTsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoX21hbGZvcm1lZEVycm9ycykgeworICAgICAgICAgICAgICAgIENvZGVyUmVzdWx0IHIgPSBfbWFsZm9ybWVkRXJyb3JzLmdldChrZXkpOworICAgICAgICAgICAgICAgIGlmIChyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgciA9IG5ldyBDb2RlclJlc3VsdChUWVBFX01BTEZPUk1FRF9JTlBVVCwgbGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgX21hbGZvcm1lZEVycm9ycy5wdXQoa2V5LCByKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHI7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTGVuZ3RoIG11c3QgYmUgZ3JlYXRlciB0aGFuIDA7IHdhcyAiICsgbGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgPGNvZGU+Q29kZXJSZXN1bHQ8L2NvZGU+IG9iamVjdCBpbmRpY2F0aW5nIGFuIHVubWFwcGFibGUKKyAgICAgKiBjaGFyYWN0ZXIgZXJyb3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBpbnB1dCB1bml0IHNlcXVlbmNlIGRlbm90aW5nIHRoZSB1bm1hcHBhYmxlCisgICAgICogICAgICAgICAgICBjaGFyYWN0ZXIuCisgICAgICogQHJldHVybiBhIDxjb2RlPkNvZGVyUmVzdWx0PC9jb2RlPiBvYmplY3QgaW5kaWNhdGluZyBhbiB1bm1hcHBhYmxlCisgICAgICogICAgICAgICBjaGFyYWN0ZXIgZXJyb3IuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiA8Y29kZT5sZW5ndGg8L2NvZGU+IGlzIG5vbi1wb3NpdGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBDb2RlclJlc3VsdCB1bm1hcHBhYmxlRm9yTGVuZ3RoKGludCBsZW5ndGgpCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgIEludGVnZXIga2V5ID0gSW50ZWdlci52YWx1ZU9mKGxlbmd0aCk7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKF91bm1hcHBhYmxlRXJyb3JzKSB7CisgICAgICAgICAgICAgICAgQ29kZXJSZXN1bHQgciA9IF91bm1hcHBhYmxlRXJyb3JzLmdldChrZXkpOworICAgICAgICAgICAgICAgIGlmIChyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgciA9IG5ldyBDb2RlclJlc3VsdChUWVBFX1VOTUFQUEFCTEVfQ0hBUiwgbGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgX3VubWFwcGFibGVFcnJvcnMucHV0KGtleSwgcik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiByOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkxlbmd0aCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwOyB3YXMgIiArIGxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgcmVzdWx0IGlzIGFuIHVuZGVyZmxvdyBjb25kaXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgYW4gdW5kZXJmbG93LCBvdGhlcndpc2UgZmFsc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNVbmRlcmZsb3coKSB7CisgICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT0gVFlQRV9VTkRFUkZMT1c7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgcmVzdWx0IHJlcHJlc2VudHMgYSBtYWxmb3JtZWQtaW5wdXQgZXJyb3Igb3IgYW4KKyAgICAgKiB1bm1hcHBhYmxlLWNoYXJhY3RlciBlcnJvci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIGEgbWFsZm9ybWVkLWlucHV0IGVycm9yIG9yIGFuCisgICAgICogICAgICAgICB1bm1hcHBhYmxlLWNoYXJhY3RlciBlcnJvciwgb3RoZXJ3aXNlIGZhbHNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRXJyb3IoKSB7CisgICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT0gVFlQRV9NQUxGT1JNRURfSU5QVVQKKyAgICAgICAgICAgICAgICB8fCB0aGlzLnR5cGUgPT0gVFlQRV9VTk1BUFBBQkxFX0NIQVI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgcmVzdWx0IHJlcHJlc2VudHMgYSBtYWxmb3JtZWQtaW5wdXQgZXJyb3IuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIG1hbGZvcm1lZC1pbnB1dCBlcnJvciwgb3RoZXJ3aXNlIGZhbHNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzTWFsZm9ybWVkKCkgeworICAgICAgICByZXR1cm4gdGhpcy50eXBlID09IFRZUEVfTUFMRk9STUVEX0lOUFVUOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHJlc3VsdCBpcyBhbiBvdmVyZmxvdyBjb25kaXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhbiBvdmVyZmxvdywgb3RoZXJ3aXNlIGZhbHNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzT3ZlcmZsb3coKSB7CisgICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT0gVFlQRV9PVkVSRkxPVzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyByZXN1bHQgcmVwcmVzZW50cyBhbiB1bm1hcHBhYmxlLWNoYXJhY3RlciBlcnJvci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIGFuIHVubWFwcGFibGUtY2hhcmFjdGVyIGVycm9yLCBvdGhlcndpc2UgZmFsc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNVbm1hcHBhYmxlKCkgeworICAgICAgICByZXR1cm4gdGhpcy50eXBlID09IFRZUEVfVU5NQVBQQUJMRV9DSEFSOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxlbmd0aCBvZiB0aGUgZXJyb25lb3VzIGlucHV0LiBUaGUgbGVuZ3RoIGlzIG9ubHkgbWVhbmluZ2Z1bCB0bworICAgICAqIGEgbWFsZm9ybWVkLWlucHV0IGVycm9yIG9yIGFuIHVubWFwcGFibGUgY2hhcmFjdGVyIGVycm9yLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGVuZ3RoLCBhcyBhbiBpbnRlZ2VyLCBvZiB0aGlzIG9iamVjdCdzIGVycm9uZW91cyBpbnB1dC4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyByZXN1bHQgaXMgYW4gb3ZlcmZsb3cgb3IgdW5kZXJmbG93LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgbGVuZ3RoKCkgdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRoaXMudHlwZSA9PSBUWVBFX01BTEZPUk1FRF9JTlBVVCB8fCB0aGlzLnR5cGUgPT0gVFlQRV9VTk1BUFBBQkxFX0NIQVIpIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzLmxlbmd0aDsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oImxlbmd0aCBtZWFuaW5nbGVzcyBmb3IgIiArIHRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRocm93cyBhbiBleGNlcHRpb24gY29ycmVzcG9uZGluZyB0byB0aGlzIGNvZGVyIHJlc3VsdC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaW4gY2FzZSB0aGlzIGlzIGFuIHVuZGVyZmxvdy4KKyAgICAgKiBAdGhyb3dzIEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaW4gY2FzZSB0aGlzIGlzIGFuIG92ZXJmbG93LgorICAgICAqIEB0aHJvd3MgVW5tYXBwYWJsZUNoYXJhY3RlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGluIGNhc2UgdGhpcyBpcyBhbiB1bm1hcHBhYmxlLWNoYXJhY3RlciBlcnJvci4KKyAgICAgKiBAdGhyb3dzIE1hbGZvcm1lZElucHV0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaW4gY2FzZSB0aGlzIGlzIGEgbWFsZm9ybWVkLWlucHV0IGVycm9yLgorICAgICAqIEB0aHJvd3MgQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgdGhlIGRlZmF1bHQgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRocm93RXhjZXB0aW9uKCkgdGhyb3dzIEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uLCBVbm1hcHBhYmxlQ2hhcmFjdGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgTWFsZm9ybWVkSW5wdXRFeGNlcHRpb24sIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHN3aXRjaCAodGhpcy50eXBlKSB7CisgICAgICAgICAgICBjYXNlIFRZUEVfVU5ERVJGTE9XOgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGNhc2UgVFlQRV9PVkVSRkxPVzoKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGNhc2UgVFlQRV9VTk1BUFBBQkxFX0NIQVI6CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVubWFwcGFibGVDaGFyYWN0ZXJFeGNlcHRpb24odGhpcy5sZW5ndGgpOworICAgICAgICAgICAgY2FzZSBUWVBFX01BTEZPUk1FRF9JTlBVVDoKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkSW5wdXRFeGNlcHRpb24odGhpcy5sZW5ndGgpOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgdGV4dCBkZXNjcmlwdGlvbiBvZiB0aGlzIHJlc3VsdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSB0ZXh0IGRlc2NyaXB0aW9uIG9mIHRoaXMgcmVzdWx0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZyBkc2MgPSBudWxsOworICAgICAgICBzd2l0Y2ggKHRoaXMudHlwZSkgeworICAgICAgICAgICAgY2FzZSBUWVBFX1VOREVSRkxPVzoKKyAgICAgICAgICAgICAgICBkc2MgPSAiVU5ERVJGTE9XIGVycm9yIjsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgVFlQRV9PVkVSRkxPVzoKKyAgICAgICAgICAgICAgICBkc2MgPSAiT1ZFUkZMT1cgZXJyb3IiOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBUWVBFX1VOTUFQUEFCTEVfQ0hBUjoKKyAgICAgICAgICAgICAgICBkc2MgPSAiVW5tYXBwYWJsZS1jaGFyYWN0ZXIgZXJyb3Igd2l0aCBlcnJvbmVvdXMgaW5wdXQgbGVuZ3RoICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgdGhpcy5sZW5ndGg7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFRZUEVfTUFMRk9STUVEX0lOUFVUOgorICAgICAgICAgICAgICAgIGRzYyA9ICJNYWxmb3JtZWQtaW5wdXQgZXJyb3Igd2l0aCBlcnJvbmVvdXMgaW5wdXQgbGVuZ3RoICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgdGhpcy5sZW5ndGg7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIGRzYyA9ICIiOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRDbGFzcygpLmdldE5hbWUoKSArICJbIiArIGRzYyArICJdIjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhcnNldC9Db2RpbmdFcnJvckFjdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvQ29kaW5nRXJyb3JBY3Rpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kN2ZiNzI3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvQ29kaW5nRXJyb3JBY3Rpb24uamF2YQpAQCAtMCwwICsxLDY2IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYXJzZXQ7CisKKy8qKgorICogVXNlZCB0byBpbmRpY2F0ZSB3aGF0IGtpbmQgb2YgYWN0aW9ucyB0byB0YWtlIGluIGNhc2Ugb2YgZW5jb2RpbmcvZGVjb2RpbmcKKyAqIGVycm9ycy4gQ3VycmVudGx5IHRocmVlIGFjdGlvbnMgYXJlIGRlZmluZWQ6IHtAY29kZSBJR05PUkV9LCB7QGNvZGUgUkVQTEFDRX0KKyAqIGFuZCB7QGNvZGUgUkVQT1JUfS4KKyAqLworcHVibGljIGNsYXNzIENvZGluZ0Vycm9yQWN0aW9uIHsKKworICAgIC8qKgorICAgICAqIERlbm90ZXMgdGhlIGFjdGlvbiB0byBpZ25vcmUgYW55IGVycm9ycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvZGluZ0Vycm9yQWN0aW9uIElHTk9SRSA9IG5ldyBDb2RpbmdFcnJvckFjdGlvbigKKyAgICAgICAgICAgICJJR05PUkUiKTsKKworICAgIC8qKgorICAgICAqIERlbm90ZXMgdGhlIGFjdGlvbiB0byBmaWxsIGluIHRoZSBvdXRwdXQgd2l0aCBhIHJlcGxhY2VtZW50IGNoYXJhY3RlcgorICAgICAqIHdoZW4gbWFsZm9ybWVkIGlucHV0IG9yIGFuIHVubWFwcGFibGUgY2hhcmFjdGVyIGlzIGVuY291bnRlcmVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29kaW5nRXJyb3JBY3Rpb24gUkVQTEFDRSA9IG5ldyBDb2RpbmdFcnJvckFjdGlvbigKKyAgICAgICAgICAgICJSRVBMQUNFIik7CisKKyAgICAvKioKKyAgICAgKiBEZW5vdGVzIHRoZSBhY3Rpb24gdG8gcmVwb3J0IHRoZSBlbmNvdW50ZXJlZCBlcnJvciBpbiBhbiBhcHByb3ByaWF0ZQorICAgICAqIG1hbm5lciwgZm9yIGV4YW1wbGUgdG8gdGhyb3cgYW4gZXhjZXB0aW9uIG9yIHJldHVybiBhbiBpbmZvcm1hdGl2ZQorICAgICAqIHJlc3VsdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvZGluZ0Vycm9yQWN0aW9uIFJFUE9SVCA9IG5ldyBDb2RpbmdFcnJvckFjdGlvbigKKyAgICAgICAgICAgICJSRVBPUlQiKTsKKworICAgIC8vIFRoZSBuYW1lIG9mIHRoaXMgYWN0aW9uCisgICAgcHJpdmF0ZSBTdHJpbmcgYWN0aW9uOworCisgICAgLyoKKyAgICAgKiBDYW4ndCBpbnN0YW50aWF0ZSBvdXRzaWRlLgorICAgICAqLworICAgIHByaXZhdGUgQ29kaW5nRXJyb3JBY3Rpb24oU3RyaW5nIGFjdGlvbikgeworICAgICAgICB0aGlzLmFjdGlvbiA9IGFjdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgdGV4dCBkZXNjcmlwdGlvbiBvZiB0aGlzIGFjdGlvbiBpbmRpY2F0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBhIHRleHQgZGVzY3JpcHRpb24gb2YgdGhpcyBhY3Rpb24gaW5kaWNhdGlvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gIkFjdGlvbjogIiArIHRoaXMuYWN0aW9uOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L0lsbGVnYWxDaGFyc2V0TmFtZUV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvSWxsZWdhbENoYXJzZXROYW1lRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODVlN2VlMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L0lsbGVnYWxDaGFyc2V0TmFtZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhcnNldDsKKworLyoqCisgKiBBbiB7QGNvZGUgSWxsZWdhbENoYXJzZXROYW1lRXhjZXB0aW9ufSBpcyB0aHJvd24gd2hlbiBhbiBpbGxlZ2FsIGNoYXJzZXQgbmFtZQorICogaXMgZW5jb3VudGVyZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBJbGxlZ2FsQ2hhcnNldE5hbWVFeGNlcHRpb24gZXh0ZW5kcyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworCisgICAgLyoKKyAgICAgKiBUaGlzIGNvbnN0YW50IGlzIHVzZWQgZHVyaW5nIGRlc2VyaWFsaXphdGlvbiB0byBjaGVjayB0aGUgdmVyc2lvbgorICAgICAqIHdoaWNoIGNyZWF0ZWQgdGhlIHNlcmlhbGl6ZWQgb2JqZWN0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDE0NTc1MjUzNTg0NzAwMDI5ODlMOworCisgICAgLy8gVGhlIGlsbGVnYWwgY2hhcnNldCBuYW1lCisgICAgcHJpdmF0ZSBTdHJpbmcgY2hhcnNldE5hbWU7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJbGxlZ2FsQ2hhcnNldE5hbWVFeGNlcHRpb259IHdpdGggdGhlIHN1cHBsaWVkCisgICAgICogY2hhcnNldCBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIGNoYXJzZXROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZW5jb3VudGVyZWQgaWxsZWdhbCBjaGFyc2V0IG5hbWUuCisgICAgICovCisgICAgcHVibGljIElsbGVnYWxDaGFyc2V0TmFtZUV4Y2VwdGlvbihTdHJpbmcgY2hhcnNldE5hbWUpIHsKKyAgICAgICAgc3VwZXIoKGNoYXJzZXROYW1lICE9IG51bGwpID8gY2hhcnNldE5hbWUgOiAibnVsbCIpOworICAgICAgICB0aGlzLmNoYXJzZXROYW1lID0gY2hhcnNldE5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5jb3VudGVyZWQgaWxsZWdhbCBjaGFyc2V0IG5hbWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDaGFyc2V0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIGNoYXJzZXROYW1lOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L01hbGZvcm1lZElucHV0RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhcnNldC9NYWxmb3JtZWRJbnB1dEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhZTdiNzgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhcnNldC9NYWxmb3JtZWRJbnB1dEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhcnNldDsKKworLyoqCisgKiBBIHtAY29kZSBNYWxmb3JtZWRJbnB1dEV4Y2VwdGlvbn0gaXMgdGhyb3duIHdoZW4gYSBtYWxmb3JtZWQgaW5wdXQgaXMKKyAqIGVuY291bnRlcmVkLCBmb3IgZXhhbXBsZSBpZiBhIGJ5dGUgc2VxdWVuY2UgaXMgaWxsZWdhbCBmb3IgdGhlIGdpdmVuIGNoYXJzZXQuCisgKi8KK3B1YmxpYyBjbGFzcyBNYWxmb3JtZWRJbnB1dEV4Y2VwdGlvbiBleHRlbmRzIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiB7CisKKyAgICAvKgorICAgICAqIFRoaXMgY29uc3RhbnQgaXMgdXNlZCBkdXJpbmcgZGVzZXJpYWxpemF0aW9uIHRvIGNoZWNrIHRoZSB2ZXJzaW9uCisgICAgICogd2hpY2ggY3JlYXRlZCB0aGUgc2VyaWFsaXplZCBvYmplY3QuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTM0Mzg4MjMzOTk4MzQ4MDYxOTRMOworCisgICAgLy8gdGhlIGxlbmd0aCBvZiB0aGUgbWFsZm9ybWVkIGlucHV0CisgICAgcHJpdmF0ZSBpbnQgaW5wdXRMZW5ndGg7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBNYWxmb3JtZWRJbnB1dEV4Y2VwdGlvbn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBtYWxmb3JtZWQgaW5wdXQuCisgICAgICovCisgICAgcHVibGljIE1hbGZvcm1lZElucHV0RXhjZXB0aW9uKGludCBsZW5ndGgpIHsKKyAgICAgICAgdGhpcy5pbnB1dExlbmd0aCA9IGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsZW5ndGggb2YgdGhlIG1hbGZvcm1lZCBpbnB1dC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgbWFsZm9ybWVkIGlucHV0LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SW5wdXRMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmlucHV0TGVuZ3RoOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKyAgICAgICAgcmV0dXJuICJMZW5ndGg6ICIgKyBpbnB1dExlbmd0aDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhcnNldC9Nb2RpZmllZFV0ZjguamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L01vZGlmaWVkVXRmOC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAxOTk5MmQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhcnNldC9Nb2RpZmllZFV0ZjguamF2YQpAQCAtMCwwICsxLDEyOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFyc2V0OworCitpbXBvcnQgamF2YS5pby5VVEZEYXRhRm9ybWF0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ5dGVPcmRlcjsKK2ltcG9ydCBsaWJjb3JlLmlvLk1lbW9yeTsKK2ltcG9ydCBsaWJjb3JlLmlvLlNpemVPZjsKKworLyoqCisgKiBAaGlkZSBpbnRlcm5hbCB1c2Ugb25seQorICovCitwdWJsaWMgY2xhc3MgTW9kaWZpZWRVdGY4IHsKKyAgICAvKioKKyAgICAgKiBEZWNvZGVzIGEgYnl0ZSBhcnJheSBjb250YWluaW5nIDxpPm1vZGlmaWVkIFVURi04PC9pPiBieXRlcyBpbnRvIGEgc3RyaW5nLgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IGFsdGhvdWdoIHRoaXMgbWV0aG9kIGRlY29kZXMgdGhlIChzdXBwb3NlZGx5IGltcG9zc2libGUpIHplcm8gYnl0ZSB0byBVKzAwMDAsCisgICAgICogdGhhdCdzIHdoYXQgdGhlIFJJIGRvZXMgdG9vLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGRlY29kZShieXRlW10gaW4sIGNoYXJbXSBvdXQsIGludCBvZmZzZXQsIGludCB1dGZTaXplKSB0aHJvd3MgVVRGRGF0YUZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBjb3VudCA9IDAsIHMgPSAwLCBhOworICAgICAgICB3aGlsZSAoY291bnQgPCB1dGZTaXplKSB7CisgICAgICAgICAgICBpZiAoKG91dFtzXSA9IChjaGFyKSBpbltvZmZzZXQgKyBjb3VudCsrXSkgPCAnXHUwMDgwJykgeworICAgICAgICAgICAgICAgIHMrKzsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoKChhID0gb3V0W3NdKSAmIDB4ZTApID09IDB4YzApIHsKKyAgICAgICAgICAgICAgICBpZiAoY291bnQgPj0gdXRmU2l6ZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVVRGRGF0YUZvcm1hdEV4Y2VwdGlvbigiYmFkIHNlY29uZCBieXRlIGF0ICIgKyBjb3VudCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGludCBiID0gaW5bb2Zmc2V0ICsgY291bnQrK107CisgICAgICAgICAgICAgICAgaWYgKChiICYgMHhDMCkgIT0gMHg4MCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVVRGRGF0YUZvcm1hdEV4Y2VwdGlvbigiYmFkIHNlY29uZCBieXRlIGF0ICIgKyAoY291bnQgLSAxKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG91dFtzKytdID0gKGNoYXIpICgoKGEgJiAweDFGKSA8PCA2KSB8IChiICYgMHgzRikpOworICAgICAgICAgICAgfSBlbHNlIGlmICgoYSAmIDB4ZjApID09IDB4ZTApIHsKKyAgICAgICAgICAgICAgICBpZiAoY291bnQgKyAxID49IHV0ZlNpemUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVURkRhdGFGb3JtYXRFeGNlcHRpb24oImJhZCB0aGlyZCBieXRlIGF0ICIgKyAoY291bnQgKyAxKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGludCBiID0gaW5bb2Zmc2V0ICsgY291bnQrK107CisgICAgICAgICAgICAgICAgaW50IGMgPSBpbltvZmZzZXQgKyBjb3VudCsrXTsKKyAgICAgICAgICAgICAgICBpZiAoKChiICYgMHhDMCkgIT0gMHg4MCkgfHwgKChjICYgMHhDMCkgIT0gMHg4MCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVURkRhdGFGb3JtYXRFeGNlcHRpb24oImJhZCBzZWNvbmQgb3IgdGhpcmQgYnl0ZSBhdCAiICsgKGNvdW50IC0gMikpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBvdXRbcysrXSA9IChjaGFyKSAoKChhICYgMHgwRikgPDwgMTIpIHwgKChiICYgMHgzRikgPDwgNikgfCAoYyAmIDB4M0YpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVURkRhdGFGb3JtYXRFeGNlcHRpb24oImJhZCBieXRlIGF0ICIgKyAoY291bnQgLSAxKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcob3V0LCAwLCBzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhlIG1vZGlmaWVkIFVURi04IHJlcHJlc2VudGF0aW9uIG9mICdzJyB3b3VsZCB0YWtlLiBOb3RlCisgICAgICogdGhhdCB0aGlzIGlzIGp1c3QgdGhlIHNwYWNlIGZvciB0aGUgYnl0ZXMgcmVwcmVzZW50aW5nIHRoZSBjaGFyYWN0ZXJzLCBub3QgdGhlIGxlbmd0aAorICAgICAqIHdoaWNoIHByZWNlZGVzIHRob3NlIGJ5dGVzLCBiZWNhdXNlIGRpZmZlcmVudCBjYWxsZXJzIHJlcHJlc2VudCB0aGUgbGVuZ3RoIGRpZmZlcmVudGx5LAorICAgICAqIGFzIHR3bywgZm91ciwgb3IgZXZlbiBlaWdodCBieXRlcy4gSWYge0Bjb2RlIHNob3J0TGVuZ3RofSBpcyB0cnVlLCB3ZSdsbCB0aHJvdyBhbgorICAgICAqIGV4Y2VwdGlvbiBpZiB0aGUgc3RyaW5nIGlzIHRvbyBsb25nIGZvciBpdHMgbGVuZ3RoIHRvIGJlIHJlcHJlc2VudGVkIGJ5IGEgc2hvcnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBsb25nIGNvdW50Qnl0ZXMoU3RyaW5nIHMsIGJvb2xlYW4gc2hvcnRMZW5ndGgpIHRocm93cyBVVEZEYXRhRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgbG9uZyByZXN1bHQgPSAwOworICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gcy5sZW5ndGgoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgeworICAgICAgICAgICAgY2hhciBjaCA9IHMuY2hhckF0KGkpOworICAgICAgICAgICAgaWYgKGNoICE9IDAgJiYgY2ggPD0gMTI3KSB7IC8vIFUrMDAwMCB1c2VzIHR3byBieXRlcy4KKyAgICAgICAgICAgICAgICArK3Jlc3VsdDsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPD0gMjA0NykgeworICAgICAgICAgICAgICAgIHJlc3VsdCArPSAyOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXN1bHQgKz0gMzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzaG9ydExlbmd0aCAmJiByZXN1bHQgPiA2NTUzNSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBVVEZEYXRhRm9ybWF0RXhjZXB0aW9uKCJTdHJpbmcgbW9yZSB0aGFuIDY1NTM1IFVURiBieXRlcyBsb25nIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmNvZGVzIHRoZSA8aT5tb2RpZmllZCBVVEYtODwvaT4gYnl0ZXMgY29ycmVzcG9uZGluZyB0byBzdHJpbmcge0Bjb2RlIHN9IGludG8gdGhlCisgICAgICogYnl0ZSBhcnJheSB7QGNvZGUgZHN0fSwgc3RhcnRpbmcgYXQgdGhlIGdpdmVuIHtAY29kZSBvZmZzZXR9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBlbmNvZGUoYnl0ZVtdIGRzdCwgaW50IG9mZnNldCwgU3RyaW5nIHMpIHsKKyAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IHMubGVuZ3RoKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNoYXIgY2ggPSBzLmNoYXJBdChpKTsKKyAgICAgICAgICAgIGlmIChjaCAhPSAwICYmIGNoIDw9IDEyNykgeyAvLyBVKzAwMDAgdXNlcyB0d28gYnl0ZXMuCisgICAgICAgICAgICAgICAgZHN0W29mZnNldCsrXSA9IChieXRlKSBjaDsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPD0gMjA0NykgeworICAgICAgICAgICAgICAgIGRzdFtvZmZzZXQrK10gPSAoYnl0ZSkgKDB4YzAgfCAoMHgxZiAmIChjaCA+PiA2KSkpOworICAgICAgICAgICAgICAgIGRzdFtvZmZzZXQrK10gPSAoYnl0ZSkgKDB4ODAgfCAoMHgzZiAmIGNoKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGRzdFtvZmZzZXQrK10gPSAoYnl0ZSkgKDB4ZTAgfCAoMHgwZiAmIChjaCA+PiAxMikpKTsKKyAgICAgICAgICAgICAgICBkc3Rbb2Zmc2V0KytdID0gKGJ5dGUpICgweDgwIHwgKDB4M2YgJiAoY2ggPj4gNikpKTsKKyAgICAgICAgICAgICAgICBkc3Rbb2Zmc2V0KytdID0gKGJ5dGUpICgweDgwIHwgKDB4M2YgJiBjaCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIHRoZSA8aT5tb2RpZmllZCBVVEYtODwvaT4gZm9ybSBvZiB7QGNvZGUgc30sIHVzaW5nIGEKKyAgICAgKiBiaWctZW5kaWFuIDE2LWJpdCBsZW5ndGguIFRocm93cyBVVEZEYXRhRm9ybWF0RXhjZXB0aW9uIGlmIHtAY29kZSBzfSBpcyB0b28gbG9uZworICAgICAqIGZvciBhIHR3by1ieXRlIGxlbmd0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBlbmNvZGUoU3RyaW5nIHMpIHRocm93cyBVVEZEYXRhRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHV0ZkNvdW50ID0gKGludCkgTW9kaWZpZWRVdGY4LmNvdW50Qnl0ZXMocywgdHJ1ZSk7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtTaXplT2YuU0hPUlQgKyB1dGZDb3VudF07CisgICAgICAgIE1lbW9yeS5wb2tlU2hvcnQocmVzdWx0LCAwLCAoc2hvcnQpIHV0ZkNvdW50LCBCeXRlT3JkZXIuQklHX0VORElBTik7CisgICAgICAgIE1vZGlmaWVkVXRmOC5lbmNvZGUocmVzdWx0LCBTaXplT2YuU0hPUlQsIHMpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgTW9kaWZpZWRVdGY4KCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L1VubWFwcGFibGVDaGFyYWN0ZXJFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L1VubWFwcGFibGVDaGFyYWN0ZXJFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MzE4N2I1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvVW5tYXBwYWJsZUNoYXJhY3RlckV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5uaW8uY2hhcnNldDsKKworLyoqCisgKiBBbiB7QGNvZGUgVW5tYXBwYWJsZUNoYXJhY3RlckV4Y2VwdGlvbn0gaXMgdGhyb3duIHdoZW4gYW4gdW5tYXBwYWJsZQorICogY2hhcmFjdGVyIGZvciB0aGUgZ2l2ZW4gY2hhcnNldCBpcyBlbmNvdW50ZXJlZC4KKyAqLworcHVibGljIGNsYXNzIFVubWFwcGFibGVDaGFyYWN0ZXJFeGNlcHRpb24gZXh0ZW5kcyBDaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb24geworCisgICAgLyoKKyAgICAgKiBUaGlzIGNvbnN0YW50IGlzIHVzZWQgZHVyaW5nIGRlc2VyaWFsaXphdGlvbiB0byBjaGVjayB0aGUgdmVyc2lvbgorICAgICAqIHdoaWNoIGNyZWF0ZWQgdGhlIHNlcmlhbGl6ZWQgb2JqZWN0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03MDI2OTYyMzcxNTM3NzA2MTIzTDsKKworICAgIC8vIFRoZSBsZW5ndGggb2YgdGhlIHVubWFwcGFibGUgY2hhcmFjdGVyCisgICAgcHJpdmF0ZSBpbnQgaW5wdXRMZW5ndGg7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBVbm1hcHBhYmxlQ2hhcmFjdGVyRXhjZXB0aW9ufS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhlIHVubWFwcGFibGUgY2hhcmFjdGVyLgorICAgICAqLworICAgIHB1YmxpYyBVbm1hcHBhYmxlQ2hhcmFjdGVyRXhjZXB0aW9uKGludCBsZW5ndGgpIHsKKyAgICAgICAgdGhpcy5pbnB1dExlbmd0aCA9IGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhlIHVubWFwcGFibGUgY2hhcmFjdGVyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SW5wdXRMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmlucHV0TGVuZ3RoOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKyAgICAgICAgcmV0dXJuICJMZW5ndGg6ICIgKyBpbnB1dExlbmd0aDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhcnNldC9VbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL25pby9jaGFyc2V0L1Vuc3VwcG9ydGVkQ2hhcnNldEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVkM2JmYWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhcnNldC9VbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDU1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEubmlvLmNoYXJzZXQ7CisKKy8qKgorICogQW4ge0Bjb2RlIFVuc3VwcG9ydGVkQ2hhcnNldEV4Y2VwdGlvbn0gaXMgdGhyb3duIHdoZW4gYW4gdW5zdXBwb3J0ZWQgY2hhcnNldAorICogbmFtZSBpcyBlbmNvdW50ZXJlZC4KKyAqLworcHVibGljIGNsYXNzIFVuc3VwcG9ydGVkQ2hhcnNldEV4Y2VwdGlvbiBleHRlbmRzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisKKyAgICAvKgorICAgICAqIFRoaXMgY29uc3RhbnQgaXMgdXNlZCBkdXJpbmcgZGVzZXJpYWxpemF0aW9uIHRvIGNoZWNrIHRoZSB2ZXJzaW9uCisgICAgICogd2hpY2ggY3JlYXRlZCB0aGUgc2VyaWFsaXplZCBvYmplY3QuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTQ5MDc2NTUyNDcyNzM4NjM2N0w7CisKKyAgICAvLyB0aGUgdW5zdXBwb3J0ZWQgY2hhcnNldCBuYW1lCisgICAgcHJpdmF0ZSBTdHJpbmcgY2hhcnNldE5hbWU7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBVbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb259IHdpdGggdGhlIHN1cHBsaWVkCisgICAgICogY2hhcnNldCBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIGNoYXJzZXROYW1lCisgICAgICogICAgICAgICAgICB0aGUgZW5jb3VudGVyZWQgdW5zdXBwb3J0ZWQgY2hhcnNldCBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyBVbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb24oU3RyaW5nIGNoYXJzZXROYW1lKSB7CisgICAgICAgIHN1cGVyKChjaGFyc2V0TmFtZSAhPSBudWxsKSA/IGNoYXJzZXROYW1lIDogIm51bGwiKTsKKyAgICAgICAgdGhpcy5jaGFyc2V0TmFtZSA9IGNoYXJzZXROYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGVuY291bnRlcmVkIHVuc3VwcG9ydGVkIGNoYXJzZXQgbmFtZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVuY291bnRlcmVkIHVuc3VwcG9ydGVkIGNoYXJzZXQgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENoYXJzZXROYW1lKCkgeworICAgICAgICByZXR1cm4gY2hhcnNldE5hbWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvc3BpL0NoYXJzZXRQcm92aWRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvbmlvL2NoYXJzZXQvc3BpL0NoYXJzZXRQcm92aWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMzZWQzYzgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9uaW8vY2hhcnNldC9zcGkvQ2hhcnNldFByb3ZpZGVyLmphdmEKQEAgLTAsMCArMSw1MCBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLm5pby5jaGFyc2V0LnNwaTsKKworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CisKKy8qKgorICogVGhlIHNlcnZpY2UgcHJvdmlkZXIgY2xhc3MgZm9yIGNoYXJhY3RlciBzZXRzLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ2hhcnNldFByb3ZpZGVyIHsKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBmb3Igc3ViY2xhc3Npbmcgd2l0aCBjb25jcmV0ZSB0eXBlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ2hhcnNldFByb3ZpZGVyKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igb3ZlciBhbGwgdGhlIGF2YWlsYWJsZSBjaGFyc2V0cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGl0ZXJhdG9yLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBJdGVyYXRvcjxDaGFyc2V0PiBjaGFyc2V0cygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZWQgY2hhcnNldC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgY2hhcnNldCBpcyB1bmF2YWlsYWJsZSB0aGUgbWV0aG9kIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGNoYXJzZXROYW1lCisgICAgICogICAgICAgICAgICB0aGUgY2Fub25pY2FsIG9yIGFsaWFzIG5hbWUgb2YgYSBjaGFyYWN0ZXIgc2V0LgorICAgICAqIEByZXR1cm4gdGhlIGNoYXJzZXQsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHVuYXZhaWxhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBDaGFyc2V0IGNoYXJzZXRGb3JOYW1lKFN0cmluZyBjaGFyc2V0TmFtZSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9BY2Nlc3NDb250cm9sQ29udGV4dC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQWNjZXNzQ29udHJvbENvbnRleHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NzYyYzQxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQWNjZXNzQ29udHJvbENvbnRleHQuamF2YQpAQCAtMCwwICsxLDQ3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBBY2Nlc3NDb250cm9sQ29udGV4dCB7CisgICAgcHVibGljIEFjY2Vzc0NvbnRyb2xDb250ZXh0KEFjY2Vzc0NvbnRyb2xDb250ZXh0IGFjYywgRG9tYWluQ29tYmluZXIgY29tYmluZXIpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgQWNjZXNzQ29udHJvbENvbnRleHQoUHJvdGVjdGlvbkRvbWFpbltdIGNvbnRleHQpIHsgfQorCisgICAgcHVibGljIHZvaWQgY2hlY2tQZXJtaXNzaW9uKFBlcm1pc3Npb24gcGVybSkgdGhyb3dzIEFjY2Vzc0NvbnRyb2xFeGNlcHRpb24geyB9CisKKyAgICBwdWJsaWMgRG9tYWluQ29tYmluZXIgZ2V0RG9tYWluQ29tYmluZXIoKSB7IHJldHVybiBudWxsOyB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9BY2Nlc3NDb250cm9sRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9BY2Nlc3NDb250cm9sRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWUyM2FiMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0FjY2Vzc0NvbnRyb2xFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDY0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKKy8qKgorICoge0Bjb2RlIEFjY2Vzc0NvbnRyb2xFeGNlcHRpb259IGlzIHRocm93biBpZiB0aGUgYWNjZXNzIGNvbnRyb2wgaW5mcmFzdHJ1Y3R1cmUKKyAqIGRlbmllcyBwcm90ZWN0ZWQgYWNjZXNzIGR1ZSB0byBtaXNzaW5nIHBlcm1pc3Npb25zLgorICovCitwdWJsaWMgY2xhc3MgQWNjZXNzQ29udHJvbEV4Y2VwdGlvbiBleHRlbmRzIFNlY3VyaXR5RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDUxMzgyMjU2ODQwOTY5ODg1MzVMOworCisgICAgcHJpdmF0ZSBQZXJtaXNzaW9uIHBlcm07IC8vIE5hbWVkIGFzIGRlbWFuZGVkIGJ5IFNlcmlhbGl6ZWQgRm9ybS4KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEFjY2Vzc0NvbnRyb2xFeGNlcHRpb259IHdpdGggdGhlCisgICAgICogZ2l2ZW4gbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBBY2Nlc3NDb250cm9sRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEFjY2Vzc0NvbnRyb2xFeGNlcHRpb259IHdpdGggdGhlCisgICAgICogZ2l2ZW4gbWVzc2FnZSBhbmQgdGhlIHJlcXVlc3RlZCB7QGNvZGUgUGVybWlzc2lvbn0gd2hpY2ggd2FzIG5vdCBncmFudGVkLgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gcGVybQorICAgICAqICAgICAgICAgICAgdGhlIHJlcXVlc3RlZCB7QGNvZGUgUGVybWlzc2lvbn0gd2hpY2ggd2FzIG5vdCBncmFudGVkLgorICAgICAqLworICAgIHB1YmxpYyBBY2Nlc3NDb250cm9sRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBQZXJtaXNzaW9uIHBlcm0pIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSk7CisgICAgICAgIHRoaXMucGVybSA9IHBlcm07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmVxdWVzdGVkIHBlcm1pc3Npb24gdGhhdCBjYXVzZWQgdGhpcyBFeGNlcHRpb24gb3Ige0Bjb2RlCisgICAgICogbnVsbH0gaWYgdGhlcmUgaXMgbm8gY29ycmVzcG9uZGluZyB7QGNvZGUgUGVybWlzc2lvbn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0ZWQgcGVybWlzc2lvbiB0aGF0IGNhdXNlZCB0aGlzIEV4Y2VwdGlvbiwgbWF5YmUge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBQZXJtaXNzaW9uIGdldFBlcm1pc3Npb24oKSB7CisgICAgICAgIHJldHVybiBwZXJtOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0FjY2Vzc0NvbnRyb2xsZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0FjY2Vzc0NvbnRyb2xsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMWY2YmY5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQWNjZXNzQ29udHJvbGxlci5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworLyoqCisgKiBMZWdhY3kgc2VjdXJpdHkgY29kZTsgZG8gbm90IHVzZS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEFjY2Vzc0NvbnRyb2xsZXIgeworICAgIHByaXZhdGUgQWNjZXNzQ29udHJvbGxlcigpIHsgfQorCisgICAgLyoqCisgICAgICogQ2FsbHMge0Bjb2RlIGFjdGlvbi5ydW4oKX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8VD4gVCBkb1ByaXZpbGVnZWQoUHJpdmlsZWdlZEFjdGlvbjxUPiBhY3Rpb24pIHsKKyAgICAgICAgcmV0dXJuIGFjdGlvbi5ydW4oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxscyB7QGNvZGUgYWN0aW9uLnJ1bigpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUPiBUIGRvUHJpdmlsZWdlZChQcml2aWxlZ2VkQWN0aW9uPFQ+IGFjdGlvbiwgQWNjZXNzQ29udHJvbENvbnRleHQgY29udGV4dCkgeworICAgICAgICByZXR1cm4gYWN0aW9uLnJ1bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGxzIHtAY29kZSBhY3Rpb24ucnVuKCl9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFQ+IFQgZG9Qcml2aWxlZ2VkKFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb248VD4gYWN0aW9uKSB0aHJvd3MgUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gYWN0aW9uLnJ1bigpOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IGU7IC8vIHNvIHdlIGRvbid0IHdyYXAgUnVudGltZUV4Y2VwdGlvbnMgd2l0aCBQcml2aWxlZ2VkQWN0aW9uRXhjZXB0aW9uCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGxzIHtAY29kZSBhY3Rpb24ucnVuKCl9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFQ+IFQgZG9Qcml2aWxlZ2VkKFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb248VD4gYWN0aW9uLCBBY2Nlc3NDb250cm9sQ29udGV4dCBjb250ZXh0KSB0aHJvd3MgUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBkb1ByaXZpbGVnZWQoYWN0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxscyB7QGNvZGUgYWN0aW9uLnJ1bigpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUPiBUIGRvUHJpdmlsZWdlZFdpdGhDb21iaW5lcihQcml2aWxlZ2VkQWN0aW9uPFQ+IGFjdGlvbikgeworICAgICAgICByZXR1cm4gYWN0aW9uLnJ1bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGxzIHtAY29kZSBhY3Rpb24ucnVuKCl9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFQ+IFQgZG9Qcml2aWxlZ2VkV2l0aENvbWJpbmVyKFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb248VD4gYWN0aW9uKSB0aHJvd3MgUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBkb1ByaXZpbGVnZWQoYWN0aW9uKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgY2hlY2tQZXJtaXNzaW9uKFBlcm1pc3Npb24gcGVybWlzc2lvbikgdGhyb3dzIEFjY2Vzc0NvbnRyb2xFeGNlcHRpb24geyB9CisKKyAgICBwdWJsaWMgc3RhdGljIEFjY2Vzc0NvbnRyb2xDb250ZXh0IGdldENvbnRleHQoKSB7IHJldHVybiBuZXcgQWNjZXNzQ29udHJvbENvbnRleHQobnVsbCk7IH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGFlZmEzYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvci5qYXZhCkBAIC0wLDAgKzEsMjM2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuZm9ydHJlc3MuRW5naW5lOworCisvKioKKyAqIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3J9IGlzIGFuIGVuZ2luZSBjbGFzcyB3aGljaCBpcyBjYXBhYmxlIG9mCisgKiBnZW5lcmF0aW5nIHBhcmFtZXRlcnMgZm9yIHRoZSBhbGdvcml0aG0gaXQgd2FzIGluaXRpYWxpemVkIHdpdGguCisgKi8KK3B1YmxpYyBjbGFzcyBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IgeworCisgICAgLy8gU3RvcmUgc3BpIHNlcnZpY2UgbmFtZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRVJWSUNFID0gIkFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvciI7CisKKyAgICAvLyBVc2VkIHRvIGFjY2VzcyBjb21tb24gZW5naW5lIGZ1bmN0aW9uYWxpdHkKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFbmdpbmUgRU5HSU5FID0gbmV3IEVuZ2luZShTRVJWSUNFKTsKKworICAgIC8vIFN0b3JlIFNlY3VyZVJhbmRvbQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFNlY3VyZVJhbmRvbSBSQU5ET00gPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisKKyAgICAvLyBTdG9yZSB1c2VkIHByb3ZpZGVyCisgICAgcHJpdmF0ZSBmaW5hbCBQcm92aWRlciBwcm92aWRlcjsKKworICAgIC8vIFN0b3JlIHVzZWQgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yU3BpIGltcGxlbWVudGF0aW9uCisgICAgcHJpdmF0ZSBmaW5hbCBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JTcGkgc3BpSW1wbDsKKworICAgIC8vU3RvcmUgdXNlZCBhbGdvcml0aG0KKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBhbGdvcml0aG07CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3J9IHdpdGggdGhlCisgICAgICogZ2l2ZW4gYXJndW1lbnRzLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtR2VuU3BpCisgICAgICogICAgICAgICAgICBhIGNvbmNyZXRlIGltcGxlbWVudGF0aW9uLCB0aGlzIGVuZ2luZSBpbnN0YW5jZSBkZWxlZ2F0ZXMgdG8uCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgcHJvdmlkZXIuCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yKAorICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yU3BpIHBhcmFtR2VuU3BpLCBQcm92aWRlciBwcm92aWRlciwKKyAgICAgICAgICAgIFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgdGhpcy5wcm92aWRlciA9IHByb3ZpZGVyOworICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICAgICAgdGhpcy5zcGlJbXBsID0gcGFyYW1HZW5TcGk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICByZXR1cm4gYWxnb3JpdGhtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcn0gZm9yIHRoZQorICAgICAqIHNwZWNpZmllZCBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtIHRvIHVzZS4KKyAgICAgKiBAcmV0dXJuIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3J9IGZvciB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobSBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYWxnb3JpdGhtfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIEVuZ2luZS5TcGlBbmRQcm92aWRlciBzYXAgPSBFTkdJTkUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBudWxsKTsKKyAgICAgICAgcmV0dXJuIG5ldyBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IoKEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaSkgc2FwLnNwaSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FwLnByb3ZpZGVyLCBhbGdvcml0aG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcn0gZnJvbSB0aGUKKyAgICAgKiBzcGVjaWZpZWQgcHJvdmlkZXIgZm9yIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobSB0byB1c2UuCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICBuYW1lIG9mIHRoZSBwcm92aWRlciBvZiB0aGUge0Bjb2RlCisgICAgICogICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3J9LgorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcn0gZm9yIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIGFsZ29yaXRobS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgcHJvdmlkZXIgPT0gbnVsbCB8fCBwcm92aWRlci5pc0VtcHR5KCl9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhbGdvcml0aG19IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvciBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLAorICAgICAgICAgICAgU3RyaW5nIHByb3ZpZGVyKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCB8fCBwcm92aWRlci5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBpbXBQcm92aWRlciA9IFNlY3VyaXR5LmdldFByb3ZpZGVyKHByb3ZpZGVyKTsKKyAgICAgICAgaWYgKGltcFByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbihwcm92aWRlcik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEluc3RhbmNlKGFsZ29yaXRobSwgaW1wUHJvdmlkZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcn0gZnJvbSB0aGUKKyAgICAgKiBzcGVjaWZpZWQgcHJvdmlkZXIgZm9yIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobSB0byB1c2UuCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgcHJvdmlkZXIgb2YgdGhlIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3J9LgorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcn0gZm9yIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIGFsZ29yaXRobS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhbGdvcml0aG19IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgcHJvdmlkZXIgPT0gbnVsbH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvciBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLAorICAgICAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChhbGdvcml0aG0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgT2JqZWN0IHNwaSA9IEVOR0lORS5nZXRJbnN0YW5jZShhbGdvcml0aG0sIHByb3ZpZGVyLCBudWxsKTsKKyAgICAgICAgcmV0dXJuIG5ldyBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IoKEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaSkgc3BpLCBwcm92aWRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxnb3JpdGhtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcm92aWRlciBhc3NvY2lhdGVkIHdpdGggdGhpcyB7QGNvZGUKKyAgICAgKiBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3J9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJvdmlkZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMge0Bjb2RlCisgICAgICogICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3J9LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBQcm92aWRlciBnZXRQcm92aWRlcigpIHsKKyAgICAgICAgcmV0dXJuIHByb3ZpZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcn0gd2l0aCB0aGUgZ2l2ZW4gc2l6ZS4KKyAgICAgKiBUaGUgZGVmYXVsdCBwYXJhbWV0ZXIgc2V0IGFuZCBhIGRlZmF1bHQge0Bjb2RlIFNlY3VyZVJhbmRvbX0gaW5zdGFuY2UKKyAgICAgKiB3aWxsIGJlIHVzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIHNpemUgKGluIG51bWJlciBvZiBiaXRzKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBpbml0KGludCBzaXplKSB7CisgICAgICAgIHNwaUltcGwuZW5naW5lSW5pdChzaXplLCBSQU5ET00pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcn0gd2l0aCB0aGUgZ2l2ZW4gc2l6ZQorICAgICAqIGFuZCB0aGUgZ2l2ZW4ge0Bjb2RlIFNlY3VyZVJhbmRvbX0uIFRoZSBkZWZhdWx0IHBhcmFtZXRlciBzZXQgd2lsbCBiZQorICAgICAqIHVzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIHNpemUgKGluIG51bWJlciBvZiBiaXRzKS4KKyAgICAgKiBAcGFyYW0gcmFuZG9tCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIG9mIHJhbmRvbW5lc3MuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdChpbnQgc2l6ZSwgU2VjdXJlUmFuZG9tIHJhbmRvbSkgeworICAgICAgICBzcGlJbXBsLmVuZ2luZUluaXQoc2l6ZSwgcmFuZG9tKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3J9IHdpdGggdGhlIGdpdmVuIHtAY29kZQorICAgICAqIEFsZ29yaXRobVBhcmFtZXRlclNwZWN9LiBBIGRlZmF1bHQge0Bjb2RlIFNlY3VyZVJhbmRvbX0gaW5zdGFuY2Ugd2lsbCBiZQorICAgICAqIHVzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZ2VuUGFyYW1TcGVjCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVycyB0byB1c2UuCisgICAgICogQHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzIGFyZSBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGluaXQoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBnZW5QYXJhbVNwZWMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIHNwaUltcGwuZW5naW5lSW5pdChnZW5QYXJhbVNwZWMsIFJBTkRPTSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yfSB3aXRoIHRoZSBnaXZlbgorICAgICAqIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjfSBhbmQgdGhlIGdpdmVuIHtAY29kZSBTZWN1cmVSYW5kb219LgorICAgICAqCisgICAgICogQHBhcmFtIGdlblBhcmFtU3BlYworICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlcnMgdG8gdXNlLgorICAgICAqIEBwYXJhbSByYW5kb20KKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2Ugb2YgcmFuZG9tbmVzcy4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMgYXJlIG5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdChBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIGdlblBhcmFtU3BlYywKKyAgICAgICAgICAgIFNlY3VyZVJhbmRvbSByYW5kb20pIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgc3BpSW1wbC5lbmdpbmVJbml0KGdlblBhcmFtU3BlYywgcmFuZG9tKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlcyBhbmQgcmV0dXJucyB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30gZm9yIHRoaXMgZ2VuZXJhdG9yJ3MKKyAgICAgKiBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJzfSBmb3IgdGhpcyBnZW5lcmF0b3IncyBhbGdvcml0aG0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEFsZ29yaXRobVBhcmFtZXRlcnMgZ2VuZXJhdGVQYXJhbWV0ZXJzKCkgeworICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVHZW5lcmF0ZVBhcmFtZXRlcnMoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JTcGkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQwNDE4YmMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JTcGkuamF2YQpAQCAtMCwwICsxLDY5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKKworLyoqCisgKiB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yU3BpfSBpcyB0aGUgU2VydmljZSBQcm92aWRlciBJbnRlcmZhY2UKKyAqIChTUEkpIGRlZmluaXRpb24gZm9yIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3J9LgorICoKKyAqIEBzZWUgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JTcGkgeworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yU3BpfSAuCisgICAgICovCisgICAgcHVibGljIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JTcGl9IHdpdGggdGhlIGdpdmVuCisgICAgICogc2l6ZSBhbmQgdGhlIGdpdmVuIHtAY29kZSBTZWN1cmVSYW5kb219LiBUaGUgZGVmYXVsdCBwYXJhbWV0ZXIgc2V0CisgICAgICogd2lsbCBiZSB1c2VkLgorICAgICAqCisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaXplIChpbiBudW1iZXIgb2YgYml0cykuCisgICAgICogQHBhcmFtIHJhbmRvbQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBvZiByYW5kb21uZXNzLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGVuZ2luZUluaXQoaW50IHNpemUsIFNlY3VyZVJhbmRvbSByYW5kb20pOworCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yU3BpfSB3aXRoIHRoZSBnaXZlbgorICAgICAqIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjfSBhbmQgdGhlIGdpdmVuIHtAY29kZSBTZWN1cmVSYW5kb219LgorICAgICAqCisgICAgICogQHBhcmFtIGdlblBhcmFtU3BlYworICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlcnMgdG8gdXNlLgorICAgICAqIEBwYXJhbSByYW5kb20KKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2Ugb2YgcmFuZG9tbmVzcy4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMgYXJlIG5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgZW5naW5lSW5pdChBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIGdlblBhcmFtU3BlYywKKyAgICAgICAgICAgIFNlY3VyZVJhbmRvbSByYW5kb20pIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ29tcHV0ZXMgYW5kIHJldHVybnMge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlcnN9IGZvciB0aGlzIGdlbmVyYXRvcidzCisgICAgICogYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30gZm9yIHRoaXMgZ2VuZXJhdG9yJ3MgYWxnb3JpdGhtLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBBbGdvcml0aG1QYXJhbWV0ZXJzIGVuZ2luZUdlbmVyYXRlUGFyYW1ldGVycygpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQWxnb3JpdGhtUGFyYW1ldGVycy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQWxnb3JpdGhtUGFyYW1ldGVycy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhiYmJlMWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9BbGdvcml0aG1QYXJhbWV0ZXJzLmphdmEKQEAgLTAsMCArMSwzMDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5mb3J0cmVzcy5FbmdpbmU7CisKKworLyoqCisgKiB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30gaXMgYW4gZW5naW5lIGNsYXNzIHdoaWNoIHByb3ZpZGVzIGFsZ29yaXRobQorICogcGFyYW1ldGVycy4KKyAqLworcHVibGljIGNsYXNzIEFsZ29yaXRobVBhcmFtZXRlcnMgeworICAgIC8qKgorICAgICAqIFRoZSBzZXJ2aWNlIG5hbWUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNFVklDRSA9ICJBbGdvcml0aG1QYXJhbWV0ZXJzIjsKKworICAgIC8qKgorICAgICAqIFVzZWQgdG8gYWNjZXNzIGNvbW1vbiBlbmdpbmUgZnVuY3Rpb25hbGl0eS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFbmdpbmUgRU5HSU5FID0gbmV3IEVuZ2luZShTRVZJQ0UpOworCisgICAgLyoqCisgICAgICogVGhlIHNlY3VyaXR5IHByb3ZpZGVyLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgUHJvdmlkZXIgcHJvdmlkZXI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgU1BJIGltcGxlbWVudGF0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgQWxnb3JpdGhtUGFyYW1ldGVyc1NwaSBzcGlJbXBsOworCisgICAgLyoqCisgICAgICogVGhlIHNlY3VyaXR5IGFsZ29yaXRobS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBhbGdvcml0aG07CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW5pdGlhbGl6YXRpb24gc3RhdGUuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGluaXRpYWxpemVkOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30gd2l0aCB0aGUgZ2l2ZW4KKyAgICAgKiBhcmd1bWVudHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnUHJhbVNwaQorICAgICAqICAgICAgICAgICAgdGhlIGNvbmNyZXRlIGltcGxlbWVudGF0aW9uLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHNlY3VyaXR5IHByb3ZpZGVyLgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0uCisgICAgICovCisgICAgcHJvdGVjdGVkIEFsZ29yaXRobVBhcmFtZXRlcnMoQWxnb3JpdGhtUGFyYW1ldGVyc1NwaSBhbGdQcmFtU3BpLAorICAgICAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIsIFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgdGhpcy5wcm92aWRlciA9IHByb3ZpZGVyOworICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICAgICAgdGhpcy5zcGlJbXBsID0gYWxnUHJhbVNwaTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJzfSBmb3IgdGhlIHNwZWNpZmllZAorICAgICAqIGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0gdG8gdXNlLgorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlcnN9IGZvciB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobSBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYWxnb3JpdGhtfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBBbGdvcml0aG1QYXJhbWV0ZXJzIGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFsZ29yaXRobSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBFbmdpbmUuU3BpQW5kUHJvdmlkZXIgc2FwID0gRU5HSU5FLmdldEluc3RhbmNlKGFsZ29yaXRobSwgbnVsbCk7CisgICAgICAgIHJldHVybiBuZXcgQWxnb3JpdGhtUGFyYW1ldGVycygoQWxnb3JpdGhtUGFyYW1ldGVyc1NwaSkgc2FwLnNwaSwgc2FwLnByb3ZpZGVyLCBhbGdvcml0aG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlcnN9IGZyb20gdGhlIHNwZWNpZmllZAorICAgICAqIHByb3ZpZGVyIGZvciB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0gdG8gdXNlLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgbmFtZSBvZiB0aGUgcHJvdmlkZXIgb2YgdGhlIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJzfS4KKyAgICAgKiBAcmV0dXJuIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJzfSBmb3IgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBwcm92aWRlciA9PSBudWxsIHx8IHByb3ZpZGVyLmlzRW1wdHkoKX0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFsZ29yaXRobX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQWxnb3JpdGhtUGFyYW1ldGVycyBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLAorICAgICAgICAgICAgU3RyaW5nIHByb3ZpZGVyKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCB8fCBwcm92aWRlci5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBwID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXIocHJvdmlkZXIpOworICAgICAgICBpZiAocCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24ocHJvdmlkZXIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRJbnN0YW5jZShhbGdvcml0aG0sIHApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlcnN9IGZyb20gdGhlIHNwZWNpZmllZAorICAgICAqIHByb3ZpZGVyIGZvciB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0gdG8gdXNlLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHByb3ZpZGVyIG9mIHRoZSB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30uCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30gZm9yIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIGFsZ29yaXRobS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhbGdvcml0aG19IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgcHJvdmlkZXIgPT0gbnVsbH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEFsZ29yaXRobVBhcmFtZXRlcnMgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwKKyAgICAgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIE9iamVjdCBzcGkgPSBFTkdJTkUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBwcm92aWRlciwgbnVsbCk7CisgICAgICAgIHJldHVybiBuZXcgQWxnb3JpdGhtUGFyYW1ldGVycygoQWxnb3JpdGhtUGFyYW1ldGVyc1NwaSkgc3BpLCBwcm92aWRlciwgYWxnb3JpdGhtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcm92aWRlciBhc3NvY2lhdGVkIHdpdGggdGhpcyB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcm92aWRlciBhc3NvY2lhdGVkIHdpdGggdGhpcyB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFByb3ZpZGVyIGdldFByb3ZpZGVyKCkgeworICAgICAgICByZXR1cm4gcHJvdmlkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICByZXR1cm4gYWxnb3JpdGhtOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlcnN9IHdpdGggdGhlIHNwZWNpZmllZCB7QGNvZGUKKyAgICAgKiBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbVNwZWMKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgc3BlY2lmaWNhdGlvbi4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30gaGFzIGFscmVhZHkgYmVlbgorICAgICAqICAgICAgICAgICAgIGluaXRpYWxpemVkIG9yIHRoZSBnaXZlbiB7QGNvZGUgcGFyYW1TcGVjfSBpcyBub3QgYXBwcm9wcmlhdGUKKyAgICAgKiAgICAgICAgICAgICBmb3IgaW5pdGlhbGl6aW5nIHRoaXMge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlcnN9LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGluaXQoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbVNwZWMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24geworICAgICAgICBpZiAoaW5pdGlhbGl6ZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbigiUGFyYW1ldGVyIGhhcyBhbHJlYWR5IGJlZW4gaW5pdGlhbGl6ZWQiKTsKKyAgICAgICAgfQorICAgICAgICBzcGlJbXBsLmVuZ2luZUluaXQocGFyYW1TcGVjKTsKKyAgICAgICAgaW5pdGlhbGl6ZWQgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlcnN9IHdpdGggdGhlIHNwZWNpZmllZCB7QGNvZGUKKyAgICAgKiBieXRlW119IHVzaW5nIHRoZSBkZWZhdWx0IGRlY29kaW5nIGZvcm1hdCBmb3IgcGFyYW1ldGVycy4gVGhlIGRlZmF1bHQKKyAgICAgKiBlbmNvZGluZyBmb3JtYXQgaXMgQVNOLjEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1zCisgICAgICogICAgICAgICAgICB0aGUgZW5jb2RlZCBwYXJhbWV0ZXJzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJzfSBoYXMgYWxyZWFkeSBiZWVuCisgICAgICogICAgICAgICAgICAgaW5pdGlhbGl6ZWQsIG9yIHRoZSBwYXJhbWV0ZXIgY291bGQgbm90IGJlIGVuY29kZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdChieXRlW10gcGFyYW1zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaW5pdGlhbGl6ZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUGFyYW1ldGVyIGhhcyBhbHJlYWR5IGJlZW4gaW5pdGlhbGl6ZWQiKTsKKyAgICAgICAgfQorICAgICAgICBzcGlJbXBsLmVuZ2luZUluaXQocGFyYW1zKTsKKyAgICAgICAgaW5pdGlhbGl6ZWQgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlcnN9IHdpdGggdGhlIHNwZWNpZmllZCB7QGNvZGUKKyAgICAgKiBieXRlW119IHVzaW5nIHRoZSBzcGVjaWZpZWQgZGVjb2RpbmcgZm9ybWF0LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIGVuY29kZWQgcGFyYW1ldGVycy4KKyAgICAgKiBAcGFyYW0gZm9ybWF0CisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZGVjb2RpbmcgZm9ybWF0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJzfSBoYXMgYWxyZWFkeSBiZWVuCisgICAgICogICAgICAgICAgICAgaW5pdGlhbGl6ZWQsIG9yIHRoZSBwYXJhbWV0ZXIgY291bGQgbm90IGJlIGVuY29kZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdChieXRlW10gcGFyYW1zLCBTdHJpbmcgZm9ybWF0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaW5pdGlhbGl6ZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUGFyYW1ldGVyIGhhcyBhbHJlYWR5IGJlZW4gaW5pdGlhbGl6ZWQiKTsKKyAgICAgICAgfQorICAgICAgICBzcGlJbXBsLmVuZ2luZUluaXQocGFyYW1zLCBmb3JtYXQpOworICAgICAgICBpbml0aWFsaXplZCA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlclNwZWN9IGZvciB0aGlzIHtAY29kZQorICAgICAqIEFsZ29yaXRobVBhcmFtZXRlcnN9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtU3BlYworICAgICAqICAgICAgICAgICAgdGhlIHR5cGUgb2YgdGhlIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uIGluIHdoaWNoIHRoaXMKKyAgICAgKiAgICAgICAgICAgIHBhcmFtZXRlcnMgc2hvdWxkIGJlIGNvbnZlcnRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyU3BlY30gZm9yIHRoaXMge0Bjb2RlCisgICAgICogICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzfS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30gaGFzIGFscmVhZHkgYmVlbgorICAgICAqICAgICAgICAgICAgIGluaXRpYWxpemVkLCBvciBpZiB0aGlzIHBhcmFtZXRlcnMgY291bGQgbm90IGJlIGNvbnZlcnRlZCB0bworICAgICAqICAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIDxUIGV4dGVuZHMgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYz4gVCBnZXRQYXJhbWV0ZXJTcGVjKENsYXNzPFQ+IHBhcmFtU3BlYykKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaW5pdGlhbGl6ZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbigiUGFyYW1ldGVyIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZUdldFBhcmFtZXRlclNwZWMocGFyYW1TcGVjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlcnN9IGluIHRoZWlyIGRlZmF1bHQgZW5jb2RpbmcKKyAgICAgKiBmb3JtYXQuIFRoZSBkZWZhdWx0IGVuY29kaW5nIGZvcm1hdCBpcyBBU04uMS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVuY29kZWQgcGFyYW1ldGVycy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30gaGFzIGFscmVhZHkgYmVlbgorICAgICAqICAgICAgICAgICAgIGluaXRpYWxpemVkLCBvciBpZiB0aGlzIHBhcmFtZXRlcnMgY291bGQgbm90IGJlIGVuY29kZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJ5dGVbXSBnZXRFbmNvZGVkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpbml0aWFsaXplZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJQYXJhbWV0ZXIgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lR2V0RW5jb2RlZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30gaW4gdGhlIHNwZWNpZmllZCBlbmNvZGluZworICAgICAqIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmb3JtYXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBlbmNvZGluZyBmb3JtYXQuCisgICAgICogQHJldHVybiB0aGUgZW5jb2RlZCBwYXJhbWV0ZXJzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJzfSBoYXMgYWxyZWFkeSBiZWVuCisgICAgICogICAgICAgICAgICAgaW5pdGlhbGl6ZWQsIG9yIGlmIHRoaXMgcGFyYW1ldGVycyBjb3VsZCBub3QgYmUgZW5jb2RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYnl0ZVtdIGdldEVuY29kZWQoU3RyaW5nIGZvcm1hdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpbml0aWFsaXplZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJQYXJhbWV0ZXIgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lR2V0RW5jb2RlZChmb3JtYXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIGNvbmNpc2UsIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIG9mIHRoaXMKKyAgICAgKiB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcHJpbnRhYmxlIHJlcHJlc2VudGF0aW9uIGZvciB0aGlzIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJzfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBpZiAoIWluaXRpYWxpemVkKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVUb1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlcnNTcGkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlcnNTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZTQzYjU4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQWxnb3JpdGhtUGFyYW1ldGVyc1NwaS5qYXZhCkBAIC0wLDAgKzEsMTI0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5JbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbjsKKworLyoqCisgKiB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc1NwaX0gaXMgdGhlIFNlcnZpY2UgUHJvdmlkZXIgSW50ZXJmYWNlIChTUEkpCisgKiBkZWZpbml0aW9uIGZvciB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30uCisgKgorICogQHNlZSBBbGdvcml0aG1QYXJhbWV0ZXJzCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBBbGdvcml0aG1QYXJhbWV0ZXJzU3BpIHsKKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlcnNTcGl9IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbVNwZWMKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgc3BlY2lmaWNhdGlvbi4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc1NwaX0gaGFzIGFscmVhZHkgYmVlbgorICAgICAqICAgICAgICAgICAgIGluaXRpYWxpemVkIG9yIHRoZSBnaXZlbiB7QGNvZGUgcGFyYW1TcGVjfSBpcyBub3QgYXBwcm9wcmlhdGUKKyAgICAgKiAgICAgICAgICAgICBmb3IgaW5pdGlhbGl6aW5nIHRoaXMge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlcnNTcGl9LgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGVuZ2luZUluaXQoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbVNwZWMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJzU3BpfSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB7QGNvZGUgYnl0ZVtdfSB1c2luZyB0aGUgZGVmYXVsdCBkZWNvZGluZyBmb3JtYXQgZm9yIHBhcmFtZXRlcnMuIFRoZQorICAgICAqIGRlZmF1bHQgZW5jb2RpbmcgZm9ybWF0IGlzIEFTTi4xLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIGVuY29kZWQgcGFyYW1ldGVycy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc1NwaX0gaGFzIGFscmVhZHkgYmVlbgorICAgICAqICAgICAgICAgICAgIGluaXRpYWxpemVkLCBvciB0aGUgcGFyYW1ldGVyIGNvdWxkIG5vdCBiZSBlbmNvZGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGVuZ2luZUluaXQoYnl0ZVtdIHBhcmFtcykgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc1NwaX0gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICoge0Bjb2RlIGJ5dGVbXX0gdXNpbmcgdGhlIHNwZWNpZmllZCBkZWNvZGluZyBmb3JtYXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1zCisgICAgICogICAgICAgICAgICB0aGUgZW5jb2RlZCBwYXJhbWV0ZXJzLgorICAgICAqIEBwYXJhbSBmb3JtYXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBkZWNvZGluZyBmb3JtYXQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlcnNTcGl9IGhhcyBhbHJlYWR5IGJlZW4KKyAgICAgKiAgICAgICAgICAgICBpbml0aWFsaXplZCwgb3IgdGhlIHBhcmFtZXRlciBjb3VsZCBub3QgYmUgZW5jb2RlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBlbmdpbmVJbml0KGJ5dGVbXSBwYXJhbXMsIFN0cmluZyBmb3JtYXQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyU3BlY30gZm9yIHRoaXMge0Bjb2RlCisgICAgICogQWxnb3JpdGhtUGFyYW1ldGVyc1NwaX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1TcGVjCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgcGFyYW1ldGVyIHNwZWNpZmljYXRpb24gaW4gd2hpY2ggdGhpcworICAgICAqICAgICAgICAgICAgcGFyYW1ldGVycyBzaG91bGQgYmUgY29udmVydGVkLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjfSBmb3IgdGhpcyB7QGNvZGUKKyAgICAgKiAgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlcnNTcGl9LgorICAgICAqIEB0aHJvd3MgSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJzU3BpfSBoYXMgYWxyZWFkeSBiZWVuCisgICAgICogICAgICAgICAgICAgaW5pdGlhbGl6ZWQsIG9yIGlmIHRoaXMgcGFyYW1ldGVycyBjb3VsZCBub3QgYmUgY29udmVydGVkIHRvCisgICAgICogICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBjbGFzcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgPFQgZXh0ZW5kcyBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjPiBUIGVuZ2luZUdldFBhcmFtZXRlclNwZWMoCisgICAgICAgICAgICBDbGFzczxUPiBwYXJhbVNwZWMpIHRocm93cyBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHBhcmFtZXRlcnMgaW4gdGhlaXIgZGVmYXVsdCBlbmNvZGluZyBmb3JtYXQuIFRoZSBkZWZhdWx0CisgICAgICogZW5jb2RpbmcgZm9ybWF0IGlzIEFTTi4xLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZW5jb2RlZCBwYXJhbWV0ZXJzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJzU3BpfSBoYXMgYWxyZWFkeSBiZWVuCisgICAgICogICAgICAgICAgICAgaW5pdGlhbGl6ZWQsIG9yIGlmIHRoaXMgcGFyYW1ldGVycyBjb3VsZCBub3QgYmUgZW5jb2RlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgYnl0ZVtdIGVuZ2luZUdldEVuY29kZWQoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwYXJhbWV0ZXJzIGluIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmcgZm9ybWF0LgorICAgICAqCisgICAgICogQHBhcmFtIGZvcm1hdAorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGVuY29kaW5nIGZvcm1hdC4KKyAgICAgKiBAcmV0dXJuIHRoZSBlbmNvZGVkIHBhcmFtZXRlcnMuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIEFsZ29yaXRobVBhcmFtZXRlcnNTcGl9IGhhcyBhbHJlYWR5IGJlZW4KKyAgICAgKiAgICAgICAgICAgICBpbml0aWFsaXplZCwgb3IgaWYgdGhpcyBwYXJhbWV0ZXJzIGNvdWxkIG5vdCBiZSBlbmNvZGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBieXRlW10gZW5naW5lR2V0RW5jb2RlZChTdHJpbmcgZm9ybWF0KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhpcworICAgICAqIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJzU3BpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBwcmludGFibGUgcmVwcmVzZW50YXRpb24gZm9yIHRoaXMge0Bjb2RlCisgICAgICogICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzU3BpfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgU3RyaW5nIGVuZ2luZVRvU3RyaW5nKCk7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0FsbFBlcm1pc3Npb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0FsbFBlcm1pc3Npb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZjU0ZTc4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQWxsUGVybWlzc2lvbi5qYXZhCkBAIC0wLDAgKzEsMzEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworLyoqCisgKiBMZWdhY3kgc2VjdXJpdHkgY29kZTsgZG8gbm90IHVzZS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEFsbFBlcm1pc3Npb24gZXh0ZW5kcyBQZXJtaXNzaW9uIHsKKyAgICBwdWJsaWMgQWxsUGVybWlzc2lvbihTdHJpbmcgbmFtZSwgU3RyaW5nIGFjdGlvbnMpIHsgc3VwZXIoIiIpOyB9CisKKyAgICBwdWJsaWMgQWxsUGVybWlzc2lvbigpIHsgc3VwZXIoIiIpOyB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyBnZXRBY3Rpb25zKCkgeyByZXR1cm4gbnVsbDsgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGltcGxpZXMoUGVybWlzc2lvbiBwZXJtaXNzaW9uKSB7IHJldHVybiB0cnVlOyB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9BbGxQZXJtaXNzaW9uQ29sbGVjdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQWxsUGVybWlzc2lvbkNvbGxlY3Rpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZTliNzJjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQWxsUGVybWlzc2lvbkNvbGxlY3Rpb24uamF2YQpAQCAtMCwwICsxLDMxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKi8KK2ZpbmFsIGNsYXNzIEFsbFBlcm1pc3Npb25Db2xsZWN0aW9uIGV4dGVuZHMgUGVybWlzc2lvbkNvbGxlY3Rpb24geworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBhZGQoUGVybWlzc2lvbiBwZXJtaXNzaW9uKSB7IH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgRW51bWVyYXRpb248UGVybWlzc2lvbj4gZWxlbWVudHMoKSB7IHJldHVybiBudWxsOyB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaW1wbGllcyhQZXJtaXNzaW9uIHBlcm1pc3Npb24pIHsgcmV0dXJuIHRydWU7IH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0F1dGhQcm92aWRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQXV0aFByb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzZkOTc0NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0F1dGhQcm92aWRlci5qYXZhCkBAIC0wLDAgKzEsMzUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGguU3ViamVjdDsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLmNhbGxiYWNrLkNhbGxiYWNrSGFuZGxlcjsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLmxvZ2luLkxvZ2luRXhjZXB0aW9uOworCisvKioKKyAqIExlZ2FjeSBzZWN1cml0eSBjb2RlOyBkbyBub3QgdXNlLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQXV0aFByb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXIgeworICAgIHByb3RlY3RlZCBBdXRoUHJvdmlkZXIoU3RyaW5nIG5hbWUsIGRvdWJsZSB2ZXJzaW9uLCBTdHJpbmcgaW5mbykgeyBzdXBlcihuYW1lLCB2ZXJzaW9uLCBpbmZvKTsgfQorCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgbG9naW4oU3ViamVjdCBzdWJqZWN0LCBDYWxsYmFja0hhbmRsZXIgaGFuZGxlcikgdGhyb3dzIExvZ2luRXhjZXB0aW9uOworCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgbG9nb3V0KCkgdGhyb3dzIExvZ2luRXhjZXB0aW9uOworCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0Q2FsbGJhY2tIYW5kbGVyKENhbGxiYWNrSGFuZGxlciBoYW5kbGVyKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0Jhc2ljUGVybWlzc2lvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQmFzaWNQZXJtaXNzaW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzhlZTc1NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0Jhc2ljUGVybWlzc2lvbi5qYXZhCkBAIC0wLDAgKzEsMzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCisvKioKKyAqIExlZ2FjeSBzZWN1cml0eSBjb2RlOyBkbyBub3QgdXNlLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQmFzaWNQZXJtaXNzaW9uIGV4dGVuZHMgUGVybWlzc2lvbiBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisgICAgcHVibGljIEJhc2ljUGVybWlzc2lvbihTdHJpbmcgbmFtZSkgeyBzdXBlcigiIik7IH0KKworICAgIHB1YmxpYyBCYXNpY1Blcm1pc3Npb24oU3RyaW5nIG5hbWUsIFN0cmluZyBhY3Rpb24pIHsgc3VwZXIoIiIpOyB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyBnZXRBY3Rpb25zKCkgeyByZXR1cm4gbnVsbDsgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGltcGxpZXMoUGVybWlzc2lvbiBwZXJtaXNzaW9uKSB7IHJldHVybiB0cnVlOyB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9DZXJ0aWZpY2F0ZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQ2VydGlmaWNhdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZmVjMGQzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQ2VydGlmaWNhdGUuamF2YQpAQCAtMCwwICsxLDExMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCisvKioKKyAqIHtAY29kZSBDZXJ0aWZpY2F0ZX0gcmVwcmVzZW50cyBhbiBpZGVudGl0eSBjZXJ0aWZpY2F0ZSwgc3VjaCBhcyBYLjUwOSBvciBQR1AuCisgKiBOb3RlOiBBIHtAY29kZSBDZXJ0aWZpY2F0ZX0gaW5zdGFuY2VzIGRvZXMgbm90IG1ha2UgYW55IHN0YXRlbWVudCBhYm91dCB0aGUKKyAqIHZhbGlkaXR5IG9mIGl0c2VsZi4gSXQncyBpbiB0aGUgcmVzcG9uc2liaWxpdHkgb2YgdGhlIGFwcGxpY2F0aW9uIHRvIHZlcmlmeQorICogdGhlIHZhbGlkaXR5IG9mIGl0cyBjZXJ0aWZpY2F0ZXMuCisgKgorICogQGRlcHJlY2F0ZWQgUmVwbGFjZWQgYnkgYmVoYXZpb3IgaW4ge0BsaW5rIGphdmEuc2VjdXJpdHkuY2VydH0KKyAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlCisgKi8KK0BEZXByZWNhdGVkCitwdWJsaWMgaW50ZXJmYWNlIENlcnRpZmljYXRlIHsKKworICAgIC8qKgorICAgICAqIERlY29kZXMgYSBjZXJ0aWZpY2F0ZSBmcm9tIHRoZSBnaXZlbiB7QGNvZGUgSW5wdXRTdHJlYW19LiBUaGUgZm9ybWF0IG9mCisgICAgICogdGhlIGRhdGEgdG8gZW5jb2RlIG11c3QgYmUgdGhhdCBpZGVudGlmaWVkIGJ5IHtAbGluayAjZ2V0Rm9ybWF0KCl9IGFuZAorICAgICAqIGVuY29kZWQgYnkge0BsaW5rICNlbmNvZGUoT3V0cHV0U3RyZWFtKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyZWFtCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIElucHV0U3RyZWFtfSB0byByZWFkIGZyb20uCisgICAgICogQHRocm93cyBLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBjZXJ0aWZpY2F0ZSBpbmZvcm1hdGlvbiBpcyBpbmNvbXBsZXRlIG9yIGluY29ycmVjdC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXhjZXB0aW9uIGlzIHRocm93biBieSBhY2Nlc3NpbmcgdGhlIHByb3ZpZGVkIHN0cmVhbS4KKyAgICAgKiBAc2VlICNlbmNvZGUoT3V0cHV0U3RyZWFtKQorICAgICAqIEBzZWUgI2dldEZvcm1hdCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgZGVjb2RlKElucHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIEtleUV4Y2VwdGlvbiwgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBFbmNvZGVzIHRoaXMgY2VydGlmaWNhdGUgdG8gYW4gb3V0cHV0IHN0cmVhbS4gVGhlCisgICAgICoge0BsaW5rICNkZWNvZGUoSW5wdXRTdHJlYW0pfSBtZXRob2QgbXVzdCBiZSBhYmxlIHRvIGRlY29kZSB0aGUgZm9ybWF0CisgICAgICogd3JpdHRlbiBieSB0aGlzIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT3V0cHV0U3RyZWFtfSB0byBlbmNvZGUgdGhpcyBjZXJ0aWZpY2F0ZSB0by4KKyAgICAgKiBAdGhyb3dzIEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGNlcnRpZmljYXRlIGluZm9ybWF0aW9uIGlzIGluY29tcGxldGUgb3IgaW5jb3JyZWN0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBleGNlcHRpb24gaXMgdGhyb3duIGJ5IGFjY2Vzc2luZyB0aGUgcHJvdmlkZWQgc3RyZWFtLgorICAgICAqIEBzZWUgI2RlY29kZShJbnB1dFN0cmVhbSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlbmNvZGUoT3V0cHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIEtleUV4Y2VwdGlvbiwgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGlkZW50aWZ5aW5nIHRoZSBmb3JtYXQgb2YgdGhpcyBjZXJ0aWZpY2F0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgaWRlbnRpZnlpbmcgdGhlIGZvcm1hdCBvZiB0aGlzIGNlcnRpZmljYXRlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBndWFyYW50b3Igb2YgdGhpcyBjZXJ0aWZpY2F0ZS4gVGhhdCBndWFyYW50b3IgZ3VhcmFudGVlcywKKyAgICAgKiB0aGF0IHRoZSBwdWJsaWMga2V5IG9mIHRoaXMgY2VydGlmaWNhdGUgaXMgZnJvbSB0aGUgcHJpbmNpcGFsIHJldHVybmVkIGJ5CisgICAgICoge0BsaW5rICNnZXRQcmluY2lwYWwoKX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBndWFyYW50b3Igb2YgdGhpcyBjZXJ0aWZpY2F0ZS4KKyAgICAgKiBAc2VlICNnZXRQcmluY2lwYWwoKQorICAgICAqLworICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0R3VhcmFudG9yKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcmluY2lwYWwgb2YgdGhpcyBjZXJ0aWZpY2F0ZS4gVGhlIHByaW5jaXBhbCBpcyBndWFyYW50ZWVkIGJ5CisgICAgICogdGhlIGd1YXJhbnRvciByZXR1cm5lZCBieSB7QGxpbmsgI2dldEd1YXJhbnRvcigpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByaW5jaXBhbCBvZiB0aGlzIGNlcnRpZmljYXRlLgorICAgICAqIEBzZWUgI2dldEd1YXJhbnRvcigpCisgICAgICovCisgICAgcHVibGljIFByaW5jaXBhbCBnZXRQcmluY2lwYWwoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHB1YmxpYyBrZXkgb2YgdGhpcyBjZXJ0aWZpY2F0ZS4gVGhlIHB1YmxpYyBrZXkgaXMgZ3VhcmFudGVlZAorICAgICAqIGJ5IHRoZSBndWFyYW50b3IgdG8gYmVsb25nIHRvIHRoZSBwcmluY2lwYWwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwdWJsaWMga2V5IG9mIHRoaXMgY2VydGlmaWNhdGUuCisgICAgICogQHNlZSAjZ2V0R3VhcmFudG9yKCkKKyAgICAgKiBAc2VlIENlcnRpZmljYXRlI2dldFByaW5jaXBhbCgpCisgICAgICovCisgICAgcHVibGljIFB1YmxpY0tleSBnZXRQdWJsaWNLZXkoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIGNvbmNpc2UsIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIG9mIHRoZQorICAgICAqIHRoaXMge0Bjb2RlIENlcnRpZmljYXRlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxlZAorICAgICAqICAgICAgICAgICAgd2hldGhlciBvciBub3QgdGhpcyBtZXRob2Qgc2hvdWxkIHJldHVybiBkZXRhaWxlZCBpbmZvcm1hdGlvbi4KKyAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgY2VydGlmaWNhdGUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZyhib29sZWFuIGRldGFpbGVkKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0NvZGVTaWduZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0NvZGVTaWduZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Zjg4ODRiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQ29kZVNpZ25lci5qYXZhCkBAIC0wLDAgKzEsMTQxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGg7CisKKy8qKgorICoge0Bjb2RlIENvZGVTaWduZXJ9IHJlcHJlc2VudHMgYSBzaWduZXIgb2YgY29kZS4gSW5zdGFuY2VzIGFyZSBpbW11dGFibGUuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBDb2RlU2lnbmVyIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDY4MTkyODgxMDUxOTM5Mzc1ODFMOworCisgICAgcHJpdmF0ZSBDZXJ0UGF0aCBzaWduZXJDZXJ0UGF0aDsKKworICAgIHByaXZhdGUgVGltZXN0YW1wIHRpbWVzdGFtcDsKKworICAgIC8vIENhY2hlZCBoYXNoIGNvZGUgdmFsdWUKKyAgICBwcml2YXRlIHRyYW5zaWVudCBpbnQgaGFzaDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIENvZGVTaWduZXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIHNpZ25lckNlcnRQYXRoCisgICAgICogICAgICAgICAgICB0aGUgY2VydGlmaWNhdGUgcGF0aCBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb2RlIHNpZ25lci4KKyAgICAgKiBAcGFyYW0gdGltZXN0YW1wCisgICAgICogICAgICAgICAgICB0aGUgdGltZSBzdGFtcCBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb2RlIHNpZ25lciwgbWF5YmUge0Bjb2RlCisgICAgICogICAgICAgICAgICBudWxsfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHNpZ25lckNlcnRQYXRofSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIENvZGVTaWduZXIoQ2VydFBhdGggc2lnbmVyQ2VydFBhdGgsIFRpbWVzdGFtcCB0aW1lc3RhbXApIHsKKyAgICAgICAgaWYgKHNpZ25lckNlcnRQYXRoID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigic2lnbmVyQ2VydFBhdGggPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRoaXMuc2lnbmVyQ2VydFBhdGggPSBzaWduZXJDZXJ0UGF0aDsKKyAgICAgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBvYmplY3Qgd2l0aCB0aGlzIHtAY29kZSBDb2RlU2lnbmVyfSBmb3IgZXF1YWxpdHkuCisgICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgYWxzbyBhbiBpbnN0YW5jZSBvZgorICAgICAqIHtAY29kZSBDb2RlU2lnbmVyfSwgdGhlIHR3byB7QGNvZGUgQ29kZVNpZ25lcn0gZW5jYXBzdWxhdGUgdGhlIHNhbWUKKyAgICAgKiBjZXJ0aWZpY2F0ZSBwYXRoIGFuZCB0aGUgc2FtZSB0aW1lIHN0YW1wLCBpZiBwcmVzZW50IGluIGJvdGguCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICBvYmplY3QgdG8gYmUgY29tcGFyZWQgZm9yIGVxdWFsaXR5IHdpdGggdGhpcyB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIENvZGVTaWduZXJ9LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMge0Bjb2RlCisgICAgICogICAgICAgICBDb2RlU2lnbmVyfSwgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgQ29kZVNpZ25lcikgeworICAgICAgICAgICAgQ29kZVNpZ25lciB0aGF0ID0gKENvZGVTaWduZXIpIG9iajsKKyAgICAgICAgICAgIGlmICghc2lnbmVyQ2VydFBhdGguZXF1YWxzKHRoYXQuc2lnbmVyQ2VydFBhdGgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHRpbWVzdGFtcCA9PSBudWxsID8gdGhhdC50aW1lc3RhbXAgPT0gbnVsbCA6IHRpbWVzdGFtcAorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKHRoYXQudGltZXN0YW1wKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2VydGlmaWNhdGUgcGF0aCBhc3NvY2lhdGVkIHdpdGggdGhpcyB7QGNvZGUgQ29kZVNpZ25lcn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjZXJ0aWZpY2F0ZSBwYXRoIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHtAY29kZSBDb2RlU2lnbmVyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydFBhdGggZ2V0U2lnbmVyQ2VydFBhdGgoKSB7CisgICAgICAgIHJldHVybiBzaWduZXJDZXJ0UGF0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0aW1lIHN0YW1wIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHtAY29kZSBDb2RlU2lnbmVyfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHRpbWUgc3RhbXAgYXNzb2NpYXRlZCB3aXRoIHRoaXMge0Bjb2RlIENvZGVTaWduZXJ9LCBtYXliZQorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBUaW1lc3RhbXAgZ2V0VGltZXN0YW1wKCkgeworICAgICAgICByZXR1cm4gdGltZXN0YW1wOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhhc2ggY29kZSB2YWx1ZSBmb3IgdGhpcyB7QGNvZGUgQ29kZVNpZ25lcn0uIFJldHVybnMgdGhlIHNhbWUKKyAgICAgKiBoYXNoIGNvZGUgZm9yIHtAY29kZSBDb2RlU2lnbmVyfXMgdGhhdCBhcmUgZXF1YWwgdG8gZWFjaCBvdGhlciBhcworICAgICAqIHJlcXVpcmVkIGJ5IHRoZSBnZW5lcmFsIGNvbnRyYWN0IG9mIHtAbGluayBPYmplY3QjaGFzaENvZGV9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIHZhbHVlIGZvciB0aGlzIHtAY29kZSBDb2RlU2lnbmVyfS4KKyAgICAgKiBAc2VlIE9iamVjdCNlcXVhbHMoT2JqZWN0KQorICAgICAqIEBzZWUgQ29kZVNpZ25lciNlcXVhbHMoT2JqZWN0KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGlmIChoYXNoID09IDApIHsKKyAgICAgICAgICAgIGhhc2ggPSBzaWduZXJDZXJ0UGF0aC5oYXNoQ29kZSgpCisgICAgICAgICAgICAgICAgICAgIF4gKHRpbWVzdGFtcCA9PSBudWxsID8gMCA6IHRpbWVzdGFtcC5oYXNoQ29kZSgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUKKyAgICAgKiB0aGlzIHtAY29kZSBDb2RlU2lnbmVyfSBpbmNsdWRpbmcgaXRzIGZpcnN0IGNlcnRpZmljYXRlIGFuZCBpdHMgdGltZQorICAgICAqIHN0YW1wLCBpZiBwcmVzZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIHByaW50YWJsZSByZXByZXNlbnRhdGlvbiBmb3IgdGhpcyB7QGNvZGUgQ29kZVNpZ25lcn0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgLy8gVGhlcmUgaXMgbm8gYW55IHNwZWNpYWwgcmVhc29uIGZvciAnMjU2JyBoZXJlLCBpdCdzIHRha2VuIGFicnVwdGx5CisgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoMjU2KTsKKyAgICAgICAgLy8gVGhlIGphdmFkb2Mgc2F5cyBub3RoaW5nLCBhbmQgdGhlIG90aGVycyBpbXBsZW1lbnRhdGlvbnMgYmVoYXZpb3Igc2VlbXMgYXMKKyAgICAgICAgLy8gZHVtcGluZyBvbmx5IHRoZSBmaXJzdCBjZXJ0aWZpY2F0ZS4gV2VsbCwgbGV0J3MgZG8gdGhlIHNhbWUuCisgICAgICAgIGJ1Zi5hcHBlbmQoIkNvZGVTaWduZXIgWyIpLmFwcGVuZChzaWduZXJDZXJ0UGF0aC5nZXRDZXJ0aWZpY2F0ZXMoKS5nZXQoMCkpOworICAgICAgICBpZiggdGltZXN0YW1wICE9IG51bGwgKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKCI7ICIpLmFwcGVuZCh0aW1lc3RhbXApOworICAgICAgICB9CisgICAgICAgIGJ1Zi5hcHBlbmQoIl0iKTsKKyAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0NvZGVTb3VyY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0NvZGVTb3VyY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZjFhMmZhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvQ29kZVNvdXJjZS5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKi8KK3B1YmxpYyBjbGFzcyBDb2RlU291cmNlIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKyAgICBwdWJsaWMgQ29kZVNvdXJjZShVUkwgbG9jYXRpb24sIENlcnRpZmljYXRlW10gY2VydHMpIHsgfQorCisgICAgcHVibGljIENvZGVTb3VyY2UoVVJMIGxvY2F0aW9uLCBDb2RlU2lnbmVyW10gc2lnbmVycykgeyB9CisKKyAgICBwdWJsaWMgZmluYWwgQ2VydGlmaWNhdGVbXSBnZXRDZXJ0aWZpY2F0ZXMoKSB7IHJldHVybiBudWxsOyB9CisKKyAgICBwdWJsaWMgZmluYWwgQ29kZVNpZ25lcltdIGdldENvZGVTaWduZXJzKCkgeyByZXR1cm4gbnVsbDsgfQorCisgICAgcHVibGljIGZpbmFsIFVSTCBnZXRMb2NhdGlvbigpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIHB1YmxpYyBib29sZWFuIGltcGxpZXMoQ29kZVNvdXJjZSBjcykgeyByZXR1cm4gdHJ1ZTsgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvRGlnZXN0RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9EaWdlc3RFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZDBhMWVlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvRGlnZXN0RXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw2NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCisvKioKKyAqe0Bjb2RlIERpZ2VzdEV4Y2VwdGlvbn0gaXMgYSBnZW5lcmFsIG1lc3NhZ2UgZGlnZXN0IGV4Y2VwdGlvbi4KKyAqLworcHVibGljIGNsYXNzIERpZ2VzdEV4Y2VwdGlvbiBleHRlbmRzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1ODIxNDUwMzAzMDkzNjUyNTE1TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIERpZ2VzdEV4Y2VwdGlvbn0gd2l0aCB0aGUKKyAgICAgKiBnaXZlbiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGlnZXN0RXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKKyAgICAgICAgc3VwZXIobXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBEaWdlc3RFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBEaWdlc3RFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgRGlnZXN0RXhjZXB0aW9ufSB3aXRoIHRoZQorICAgICAqIGdpdmVuIG1lc3NhZ2UgYW5kIHRoZSBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGV4Y2VwdGlvbiB3aGljaCBpcyB0aGUgY2F1c2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBEaWdlc3RFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgRGlnZXN0RXhjZXB0aW9ufSB3aXRoIHRoZQorICAgICAqIGNhdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgZXhjZXB0aW9uIHdoaWNoIGlzIHRoZSBjYXVzZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIERpZ2VzdEV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0RpZ2VzdElucHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9EaWdlc3RJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU3ZDk3Y2EKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9EaWdlc3RJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMTU0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworLyoqCisgKiB7QGNvZGUgRGlnZXN0SW5wdXRTdHJlYW19IGlzIGEge0Bjb2RlIEZpbHRlcklucHV0U3RyZWFtfSB3aGljaCBtYWludGFpbnMgYW4KKyAqIGFzc29jaWF0ZWQgbWVzc2FnZSBkaWdlc3QuCisgKi8KK3B1YmxpYyBjbGFzcyBEaWdlc3RJbnB1dFN0cmVhbSBleHRlbmRzIEZpbHRlcklucHV0U3RyZWFtIHsKKworICAgIC8qKgorICAgICAqIFRoZSBtZXNzYWdlIGRpZ2VzdCBmb3IgdGhpcyBzdHJlYW0uCisgICAgICovCisgICAgcHJvdGVjdGVkIE1lc3NhZ2VEaWdlc3QgZGlnZXN0OworCisgICAgLy8gSW5kaWNhdGVzIHdoZXRoZXIgZGlnZXN0IGZ1bmN0aW9uYWxpdHkgaXMgb24gb3Igb2ZmCisgICAgcHJpdmF0ZSBib29sZWFuIGlzT24gPSB0cnVlOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIHtAY29kZSBEaWdlc3RJbnB1dFN0cmVhbX0sIHVzaW5nIHRoZQorICAgICAqIGdpdmVuIHtAY29kZSBzdHJlYW19IGFuZCB0aGUge0Bjb2RlIGRpZ2VzdH0uCisgICAgICoKKyAgICAgKiA8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IHBhc3NpbmcgYSBudWxsIHNvdXJjZSBjcmVhdGVzIGFuIGludmFsaWQKKyAgICAgKiB7QGNvZGUgRGlnZXN0SW5wdXRTdHJlYW19LiBBbGwgb3BlcmF0aW9ucyBvbiBzdWNoIGEgc3RyZWFtIHdpbGwgZmFpbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBzdHJlYW0uCisgICAgICogQHBhcmFtIGRpZ2VzdAorICAgICAqICAgICAgICAgICAgdGhlIG1lc3NhZ2UgZGlnZXN0LgorICAgICAqLworICAgIHB1YmxpYyBEaWdlc3RJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBzdHJlYW0sIE1lc3NhZ2VEaWdlc3QgZGlnZXN0KSB7CisgICAgICAgIHN1cGVyKHN0cmVhbSk7CisgICAgICAgIHRoaXMuZGlnZXN0ID0gZGlnZXN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1lc3NhZ2UgZGlnZXN0IGZvciB0aGlzIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1lc3NhZ2UgZGlnZXN0IGZvciB0aGlzIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWVzc2FnZURpZ2VzdCBnZXRNZXNzYWdlRGlnZXN0KCkgeworICAgICAgICByZXR1cm4gZGlnZXN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG1lc3NhZ2UgZGlnZXN0IHdoaWNoIHRoaXMgc3RyZWFtIHdpbGwgdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIGRpZ2VzdAorICAgICAqICAgICAgICAgICAgdGhlIG1lc3NhZ2UgZGlnZXN0IHdoaWNoIHRoaXMgc3RyZWFtIHdpbGwgdXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1lc3NhZ2VEaWdlc3QoTWVzc2FnZURpZ2VzdCBkaWdlc3QpIHsKKyAgICAgICAgdGhpcy5kaWdlc3QgPSBkaWdlc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIG5leHQgYnl0ZSBhbmQgcmV0dXJucyBpdCBhcyBhbiB7QGNvZGUgaW50fS4gVXBkYXRlcyB0aGUgZGlnZXN0CisgICAgICogZm9yIHRoZSBieXRlIGlmIHRoaXMgZnVuY3Rpb24gaXMge0BsaW5rICNvbihib29sZWFuKX0uCisgICAgICogPHA+CisgICAgICogVGhpcyBvcGVyYXRpb24gaXMgYmxvY2tpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBieXRlIHdoaWNoIHdhcyByZWFkIG9yIC0xIGF0IGVuZCBvZiBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHJlYWRpbmcgdGhlIHNvdXJjZSBzdHJlYW0gY2F1c2VzIGFuIHtAY29kZSBJT0V4Y2VwdGlvbn0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gcmVhZCB0aGUgbmV4dCBieXRlCisgICAgICAgIGludCBieXRlUmVhZCA9IGluLnJlYWQoKTsKKyAgICAgICAgLy8gdXBkYXRlIGRpZ2VzdCBvbmx5IGlmCisgICAgICAgIC8vIC0gZGlnZXN0IGZ1bmN0aW9uYWxpdHkgaXMgb24KKyAgICAgICAgLy8gLSBlb3MgaGFzIG5vdCBiZWVuIHJlYWNoZWQKKyAgICAgICAgaWYgKGlzT24gJiYgKGJ5dGVSZWFkICE9IC0xKSkgeworICAgICAgICAgICAgZGlnZXN0LnVwZGF0ZSgoYnl0ZSlieXRlUmVhZCk7CisgICAgICAgIH0KKyAgICAgICAgLy8gcmV0dXJuIGJ5dGUgcmVhZAorICAgICAgICByZXR1cm4gYnl0ZVJlYWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMge0Bjb2RlIGxlbn0gYnl0ZXMgaW50byB0aGUgc3BlY2lmaWVkIHtAY29kZSBieXRlW119LCBzdGFydGluZyBmcm9tCisgICAgICogdGhlIHNwZWNpZmllZCBvZmZzZXQuIFVwZGF0ZXMgdGhlIGRpZ2VzdCBpZiB0aGlzIGZ1bmN0aW9uIGlzCisgICAgICoge0BsaW5rICNvbihib29sZWFuKX0uCisgICAgICogPHA+CisgICAgICogVGhpcyBvcGVyYXRpb24gaXMgYmxvY2tpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYXJyYXkgaW4gd2hpY2ggdG8gc3RvcmUgdGhlIGJ5dGVzCisgICAgICogQHBhcmFtIG9mZgorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgcG9zaXRpb24gaW4ge0Bjb2RlIGJ9IHRvIHN0b3JlIHRoZSBieXRlcyByZWFkIGZyb20KKyAgICAgKiAgICAgICAgICAgIHRoaXMgc3RyZWFtCisgICAgICogQHBhcmFtIGxlbgorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHRvIHN0b3JlIGluIHtAY29kZSBifQorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSByZWFkIG9yIC0xIGlmIHRoZSBlbmQgb2YgdGhlCisgICAgICogICAgICAgICBmaWx0ZXJlZCBzdHJlYW0gaGFzIGJlZW4gcmVhY2hlZCB3aGlsZSByZWFkaW5nCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHJlYWRpbmcgdGhlIHNvdXJjZSBzdHJlYW0gY2F1c2VzIGFuIHtAY29kZSBJT0V4Y2VwdGlvbn0KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIHJlYWQgbmV4dCB1cCB0byBsZW4gYnl0ZXMKKyAgICAgICAgaW50IGJ5dGVzUmVhZCA9IGluLnJlYWQoYiwgb2ZmLCBsZW4pOworICAgICAgICAvLyB1cGRhdGUgZGlnZXN0IG9ubHkgaWYKKyAgICAgICAgLy8gLSBkaWdlc3QgZnVuY3Rpb25hbGl0eSBpcyBvbgorICAgICAgICAvLyAtIGVvcyBoYXMgbm90IGJlZW4gcmVhY2hlZAorICAgICAgICBpZiAoaXNPbiAmJiAoYnl0ZXNSZWFkICE9IC0xKSkgeworICAgICAgICAgICAgZGlnZXN0LnVwZGF0ZShiLCBvZmYsIGJ5dGVzUmVhZCk7CisgICAgICAgIH0KKyAgICAgICAgLy8gcmV0dXJuIG51bWJlciBvZiBieXRlcyByZWFkCisgICAgICAgIHJldHVybiBieXRlc1JlYWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5hYmxlcyBvciBkaXNhYmxlcyB0aGUgZGlnZXN0IGZ1bmN0aW9uIChkZWZhdWx0IGlzIG9uKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvbgorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGlmIHRoZSBkaWdlc3Qgc2hvdWxkIGJlIGNvbXB1dGVkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHNlZSBNZXNzYWdlRGlnZXN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgb24oYm9vbGVhbiBvbikgeworICAgICAgICBpc09uID0gb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhpcworICAgICAqIHtAY29kZSBEaWdlc3RJbnB1dFN0cmVhbX0gaW5jbHVkaW5nIHRoZSBkaWdlc3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcHJpbnRhYmxlIHJlcHJlc2VudGF0aW9uIGZvciB0aGlzIHtAY29kZSBEaWdlc3RJbnB1dFN0cmVhbX0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCkgKyAiLCAiICsgZGlnZXN0LnRvU3RyaW5nKCkgKworICAgICAgICAgICAgKGlzT24gPyAiLCBpcyBvbiIgOiAiLCBpcyBvZmYiKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9EaWdlc3RPdXRwdXRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0RpZ2VzdE91dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU1ODdlNjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9EaWdlc3RPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDEzNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5pby5GaWx0ZXJPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworLyoqCisgKiB7QGNvZGUgRGlnZXN0T3V0cHV0U3RyZWFtfSBpcyBhIHtAY29kZSBGaWx0ZXJPdXRwdXRTdHJlYW19IHdoaWNoIG1haW50YWlucyBhbgorICogYXNzb2NpYXRlZCBtZXNzYWdlIGRpZ2VzdC4KKyAqLworcHVibGljIGNsYXNzIERpZ2VzdE91dHB1dFN0cmVhbSBleHRlbmRzIEZpbHRlck91dHB1dFN0cmVhbSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWVzc2FnZSBkaWdlc3QgZm9yIHRoaXMgc3RyZWFtLgorICAgICAqLworICAgIHByb3RlY3RlZCBNZXNzYWdlRGlnZXN0IGRpZ2VzdDsKKworICAgIC8vIEluZGljYXRlcyB3aGV0aGVyIGRpZ2VzdCBmdW5jdGlvbmFsaXR5IGlzIG9uIG9yIG9mZgorICAgIHByaXZhdGUgYm9vbGVhbiBpc09uID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyB7QGNvZGUgRGlnZXN0T3V0cHV0U3RyZWFtfSwgdXNpbmcgdGhlCisgICAgICogZ2l2ZW4ge0Bjb2RlIHN0cmVhbX0gYW5kIHRoZSB7QGNvZGUgZGlnZXN0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqIEBwYXJhbSBkaWdlc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBtZXNzYWdlIGRpZ2VzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGlnZXN0T3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBzdHJlYW0sIE1lc3NhZ2VEaWdlc3QgZGlnZXN0KSB7CisgICAgICAgIHN1cGVyKHN0cmVhbSk7CisgICAgICAgIHRoaXMuZGlnZXN0ID0gZGlnZXN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1lc3NhZ2UgZGlnZXN0IGZvciB0aGlzIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1lc3NhZ2UgZGlnZXN0IGZvciB0aGlzIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWVzc2FnZURpZ2VzdCBnZXRNZXNzYWdlRGlnZXN0KCkgeworICAgICAgICByZXR1cm4gZGlnZXN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG1lc3NhZ2UgZGlnZXN0IHdoaWNoIHRoaXMgc3RyZWFtIHdpbGwgdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIGRpZ2VzdAorICAgICAqICAgICAgICAgICAgdGhlIG1lc3NhZ2UgZGlnZXN0IHdoaWNoIHRoaXMgc3RyZWFtIHdpbGwgdXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1lc3NhZ2VEaWdlc3QoTWVzc2FnZURpZ2VzdCBkaWdlc3QpIHsKKyAgICAgICAgdGhpcy5kaWdlc3QgPSBkaWdlc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBzcGVjaWZpZWQge0Bjb2RlIGludH0gdG8gdGhlIHN0cmVhbS4gVXBkYXRlcyB0aGUgZGlnZXN0IGlmCisgICAgICogdGhpcyBmdW5jdGlvbiBpcyB7QGxpbmsgI29uKGJvb2xlYW4pfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSB0byBiZSB3cml0dGVuLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB3cml0aW5nIHRvIHRoZSBzdHJlYW0gY2F1c2VzIGEge0Bjb2RlIElPRXhjZXB0aW9ufQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyB1cGRhdGUgZGlnZXN0IG9ubHkgaWYgZGlnZXN0IGZ1bmN0aW9uYWxpdHkgaXMgb24KKyAgICAgICAgaWYgKGlzT24pIHsKKyAgICAgICAgICAgIGRpZ2VzdC51cGRhdGUoKGJ5dGUpYik7CisgICAgICAgIH0KKyAgICAgICAgLy8gd3JpdGUgdGhlIGJ5dGUKKyAgICAgICAgb3V0LndyaXRlKGIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB7QGNvZGUgbGVufSBieXRlcyBpbnRvIHRoZSBzdHJlYW0sIHN0YXJ0aW5nIGZyb20gdGhlIHNwZWNpZmllZAorICAgICAqIG9mZnNldC4gVXBkYXRlcyB0aGUgZGlnZXN0IGlmIHRoaXMgZnVuY3Rpb24gaXMge0BsaW5rICNvbihib29sZWFuKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJ1ZmZlciB0byB3cml0ZSB0by4KKyAgICAgKiBAcGFyYW0gb2ZmCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGJ5dGUgaW4ge0Bjb2RlIGJ9IHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBsZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4ge0Bjb2RlIGJ9IHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB3cml0aW5nIHRvIHRoZSBzdHJlYW0gY2F1c2VzIGFuIHtAY29kZSBJT0V4Y2VwdGlvbn0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIHVwZGF0ZSBkaWdlc3Qgb25seSBpZiBkaWdlc3QgZnVuY3Rpb25hbGl0eSBpcyBvbgorICAgICAgICBpZiAoaXNPbikgeworICAgICAgICAgICAgZGlnZXN0LnVwZGF0ZShiLCBvZmYsIGxlbik7CisgICAgICAgIH0KKyAgICAgICAgLy8gd3JpdGUgbGVuIGJ5dGVzCisgICAgICAgIG91dC53cml0ZShiLCBvZmYsIGxlbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5hYmxlcyBvciBkaXNhYmxlcyB0aGUgZGlnZXN0IGZ1bmN0aW9uIChkZWZhdWx0IGlzIG9uKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvbgorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGlmIHRoZSBkaWdlc3Qgc2hvdWxkIGJlIGNvbXB1dGVkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHNlZSBNZXNzYWdlRGlnZXN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgb24oYm9vbGVhbiBvbikgeworICAgICAgICBpc09uID0gb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhpcworICAgICAqIHtAY29kZSBEaWdlc3RPdXRwdXRTdHJlYW19IGluY2x1ZGluZyB0aGUgZGlnZXN0LgorICAgICAqCisgICAgICogQHJldHVybiBhIHByaW50YWJsZSByZXByZXNlbnRhdGlvbiBmb3IgdGhpcyB7QGNvZGUgRGlnZXN0T3V0cHV0U3RyZWFtfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKSArICIsICIgKyBkaWdlc3QudG9TdHJpbmcoKSArCisgICAgICAgICAgICAoaXNPbiA/ICIsIGlzIG9uIiA6ICIsIGlzIG9mZiIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0RvbWFpbkNvbWJpbmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9Eb21haW5Db21iaW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdiMGU1NzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9Eb21haW5Db21iaW5lci5qYXZhCkBAIC0wLDAgKzEsMzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworLyoqCisgKiBMZWdhY3kgc2VjdXJpdHkgY29kZTsgZG8gbm90IHVzZS4KKyAqLworcHVibGljIGludGVyZmFjZSBEb21haW5Db21iaW5lciB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29tYmluYXRpb24gb2YgdGhlIHR3byBwcm92aWRlZCB7QGNvZGUgUHJvdGVjdGlvbkRvbWFpbn0KKyAgICAgKiBhcnJheXMuIEltcGxlbWVudGVycyBjYW4gc2ltcGx5IG1lcmdlIHRoZSB0d28gYXJyYXlzIGludG8gb25lLCByZW1vdmUKKyAgICAgKiBkdXBsaWNhdGVzIGFuZCBwZXJmb3JtIG90aGVyIG9wdGltaXphdGlvbnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY3VycmVudAorICAgICAqICAgICAgICAgICAgdGhlIHByb3RlY3Rpb24gZG9tYWlucyBvZiB0aGUgY3VycmVudCBleGVjdXRpb24gdGhyZWFkCisgICAgICogQHBhcmFtIGFzc2lnbmVkCisgICAgICogICAgICAgICAgICB0aGUgcHJvdGVjdGlvbiBkb21haW5zIG9mIHRoZSBwYXJlbnQgdGhyZWFkLCBtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqIEByZXR1cm4gYSBzaW5nbGUge0Bjb2RlIFByb3RlY3Rpb25Eb21haW59IGFycmF5IGNvbXB1dGVkIGZyb20gdGhlIHR3bworICAgICAqICAgICAgICAgcHJvdmlkZWQgYXJyYXlzLgorICAgICAqLworICAgIFByb3RlY3Rpb25Eb21haW5bXSBjb21iaW5lKFByb3RlY3Rpb25Eb21haW5bXSBjdXJyZW50LCBQcm90ZWN0aW9uRG9tYWluW10gYXNzaWduZWQpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OGZjYTI5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw2OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCisvKioKKyAqIHtAY29kZSBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb259IGlzIGEgZ2VuZXJhbCBzZWN1cml0eSBleGNlcHRpb24gYW5kIHRoZQorICogc3VwZXJjbGFzcyBmb3IgYWxsIHNlY3VyaXR5IHNwZWNpZmljIGV4Y2VwdGlvbnMuCisgKi8KK3B1YmxpYyBjbGFzcyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODk0Nzk4MTIyMDUzNTM5MjM3TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbn0gd2l0aCB0aGUKKyAgICAgKiBnaXZlbiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKKyAgICAgICAgc3VwZXIobXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9ufSB3aXRoIHRoZQorICAgICAqIGdpdmVuIG1lc3NhZ2UgYW5kIHRoZSBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGV4Y2VwdGlvbiB3aGljaCBpcyB0aGUgY2F1c2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9ufSB3aXRoIHRoZQorICAgICAqIGNhdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgZXhjZXB0aW9uIHdoaWNoIGlzIHRoZSBjYXVzZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0d1YXJkLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9HdWFyZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2NTIwNTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9HdWFyZC5qYXZhCkBAIC0wLDAgKzEsMzYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworLyoqCisgKiB7QGNvZGUgR3VhcmR9IGltcGxlbWVudG9ycyBwcm90ZWN0IGFjY2VzcyB0byBvdGhlciBvYmplY3RzLgorICovCitwdWJsaWMgaW50ZXJmYWNlIEd1YXJkIHsKKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIGFjY2VzcyB0byB0aGUgc3BlY2lmaWVkIHtAY29kZSBPYmplY3R9IHNob3VsZCBiZSBncmFudGVkLgorICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgc2lsZW50bHkgaWYgYWNjZXNzIGlzIGdyYW50ZWQsIG90aGVyd2lzZSBhIHtAY29kZQorICAgICAqIFNlY3VyaXR5RXhjZXB0aW9ufSBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGJlIHByb3RlY3RlZCBieSB0aGlzIHtAY29kZSBHdWFyZH0uCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFjY2VzcyBpcyBub3QgZ3JhbnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjaGVja0d1YXJkKE9iamVjdCBvYmplY3QpIHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0d1YXJkZWRPYmplY3QuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0d1YXJkZWRPYmplY3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNGE1MTEzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvR3VhcmRlZE9iamVjdC5qYXZhCkBAIC0wLDAgKzEsNzYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKKy8qKgorICoge0Bjb2RlIEd1YXJkZWRPYmplY3R9IGNvbnRyb2xzIGFjY2VzcyB0byBhbiBvYmplY3QsIGJ5IGNoZWNraW5nIGFsbCByZXF1ZXN0cworICogZm9yIHRoZSBvYmplY3Qgd2l0aCBhIHtAY29kZSBHdWFyZH0uCisgKi8KK3B1YmxpYyBjbGFzcyBHdWFyZGVkT2JqZWN0IGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC01MjQwNDUwMDk2MjI3ODM0MzA4TDsKKworICAgIHByaXZhdGUgZmluYWwgT2JqZWN0IG9iamVjdDsKKworICAgIHByaXZhdGUgZmluYWwgR3VhcmQgZ3VhcmQ7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBHdWFyZGVkT2JqZWN0fSB3aGljaCBwcm90ZWN0cyBhY2Nlc3MKKyAgICAgKiB0byB0aGUgc3BlY2lmaWVkIHtAY29kZSBPYmplY3R9IHVzaW5nIHRoZSBzcGVjaWZpZWQge0Bjb2RlIEd1YXJkfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT2JqZWN0fSB0byBwcm90ZWN0LgorICAgICAqIEBwYXJhbSBndWFyZAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBHdWFyZH0gd2hpY2ggcHJvdGVjdHMgdGhlIHNwZWNpZmllZCB7QGNvZGUgT2JqZWN0fSwKKyAgICAgKiAgICAgICAgICAgIG1heWJlIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgR3VhcmRlZE9iamVjdChPYmplY3Qgb2JqZWN0LCBHdWFyZCBndWFyZCkgeworICAgICAgICB0aGlzLm9iamVjdCA9IG9iamVjdDsKKyAgICAgICAgdGhpcy5ndWFyZCA9IGd1YXJkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGd1YXJkZWQge0Bjb2RlIE9iamVjdH0gaWYgdGhlIGFzc29jaWF0ZWQge0Bjb2RlIEd1YXJkfQorICAgICAqIHBlcm1pdHMgYWNjZXNzLiBJZiBhY2Nlc3MgaXMgbm90IGdyYW50ZWQsIHRoZW4gYSB7QGNvZGUKKyAgICAgKiBTZWN1cml0eUV4Y2VwdGlvbn0gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZ3VhcmRlZCBvYmplY3QuCisgICAgICogQGV4Y2VwdGlvbiBTZWN1cml0eUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGFjY2VzcyBpcyBub3QgZ3JhbnRlZCB0byB0aGUgZ3VhcmRlZCBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRPYmplY3QoKSB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24geworICAgICAgICBpZiAoZ3VhcmQgIT0gbnVsbCkgeworICAgICAgICAgICAgZ3VhcmQuY2hlY2tHdWFyZChvYmplY3QpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBvYmplY3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHRoZSBndWFyZCAoaWYgdGhlcmUgaXMgb25lKSBiZWZvcmUgcGVyZm9ybWluZyBhIGRlZmF1bHQKKyAgICAgKiBzZXJpYWxpemF0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChndWFyZCAhPSBudWxsKSB7CisgICAgICAgICAgICBndWFyZC5jaGVja0d1YXJkKG9iamVjdCk7CisgICAgICAgIH0KKyAgICAgICAgb3V0LmRlZmF1bHRXcml0ZU9iamVjdCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0lkZW50aXR5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9JZGVudGl0eS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZlNWI4YTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9JZGVudGl0eS5qYXZhCkBAIC0wLDAgKzEsMzU0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CitpbXBvcnQgbGliY29yZS51dGlsLk9iamVjdHM7CisKKy8qKgorICoge0Bjb2RlIElkZW50aXR5fSByZXByZXNlbnRzIGFuIGlkZW50aXR5IGxpa2UgYSBwZXJzb24gb3IgYSBjb21wYW55LgorICoKKyAqIEBkZXByZWNhdGVkIFRoZSBmdW5jdGlvbmFsaXR5IG9mIHRoaXMgY2xhc3MgaGFzIGJlZW4gcmVwbGFjZSBieQorICogICAgICAgICAgICAge0BsaW5rIFByaW5jaXBhbH0sIHtAbGluayBLZXlTdG9yZX0gYW5kIHRoZSB7QGNvZGUKKyAqICAgICAgICAgICAgIGphdmEuc2VjdXJpdHkuY2VydH0gcGFja2FnZS4KKyAqLworQERlcHJlY2F0ZWQKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBJZGVudGl0eSBpbXBsZW1lbnRzIFByaW5jaXBhbCwgU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzNjA5OTIyMDA3ODI2NjAwNjU5TDsKKworICAgIHByaXZhdGUgU3RyaW5nIG5hbWU7CisKKyAgICBwcml2YXRlIFB1YmxpY0tleSBwdWJsaWNLZXk7CisKKyAgICBwcml2YXRlIFN0cmluZyBpbmZvID0gIm5vIGFkZGl0aW9uYWwgaW5mbyI7CisKKyAgICBwcml2YXRlIElkZW50aXR5U2NvcGUgc2NvcGU7CisKKyAgICBwcml2YXRlIFZlY3RvcjxDZXJ0aWZpY2F0ZT4gY2VydGlmaWNhdGVzOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgSWRlbnRpdHl9LgorICAgICAqLworICAgIHByb3RlY3RlZCBJZGVudGl0eSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBJZGVudGl0eX0gd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhpcyB7QGNvZGUgSWRlbnRpdHl9LgorICAgICAqLworICAgIHB1YmxpYyBJZGVudGl0eShTdHJpbmcgbmFtZSkgeworICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIElkZW50aXR5fSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBhbmQKKyAgICAgKiB0aGUgc2NvcGUgb2YgdGhpcyB7QGNvZGUgSWRlbnRpdHl9LgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoaXMge0Bjb2RlIElkZW50aXR5fS4KKyAgICAgKiBAcGFyYW0gc2NvcGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgSWRlbnRpdHlTY29wZX0gb2YgdGhpcyB7QGNvZGUgSWRlbnRpdHl9LgorICAgICAqIEB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIHtAY29kZSBJZGVudGl0eX0gd2l0aCB0aGUgc2FtZSBuYW1lIGlzIGFscmVhZHkgcHJlc2VudAorICAgICAqICAgICAgICAgICAgIGluIHRoZSBzcGVjaWZpZWQgc2NvcGUuCisgICAgICovCisgICAgcHVibGljIElkZW50aXR5KFN0cmluZyBuYW1lLCBJZGVudGl0eVNjb3BlIHNjb3BlKQorICAgICAgICAgICAgdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24geworICAgICAgICB0aGlzKG5hbWUpOworICAgICAgICBpZiAoc2NvcGUgIT0gbnVsbCkgeworICAgICAgICAgICAgc2NvcGUuYWRkSWRlbnRpdHkodGhpcyk7CisgICAgICAgICAgICB0aGlzLnNjb3BlID0gc2NvcGU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGEge0Bjb2RlIENlcnRpZmljYXRlfSB0byB0aGlzIHtAY29kZSBJZGVudGl0eX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2VydGlmaWNhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2VydGlmaWNhdGV9IHRvIGJlIGFkZGVkIHRvIHRoaXMge0Bjb2RlIElkZW50aXR5fS4KKyAgICAgKiBAdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2VydGlmaWNhdGUgaXMgbm90IHZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZENlcnRpZmljYXRlKENlcnRpZmljYXRlIGNlcnRpZmljYXRlKSB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiB7CisgICAgICAgIFB1YmxpY0tleSBjZXJ0UEsgPSBjZXJ0aWZpY2F0ZS5nZXRQdWJsaWNLZXkoKTsKKyAgICAgICAgaWYgKHB1YmxpY0tleSAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoIWNoZWNrS2V5c0VxdWFsKHB1YmxpY0tleSwgY2VydFBLKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uKCJDZXJ0J3MgcHVibGljIGtleSBkb2VzIG5vdCBtYXRjaCBJZGVudGl0eSdzIHB1YmxpYyBrZXkiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHB1YmxpY0tleSA9IGNlcnRQSzsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2VydGlmaWNhdGVzID09IG51bGwpIHsKKyAgICAgICAgICAgIGNlcnRpZmljYXRlcyA9IG5ldyBWZWN0b3I8Q2VydGlmaWNhdGU+KCk7CisgICAgICAgIH0KKyAgICAgICAgY2VydGlmaWNhdGVzLmFkZChjZXJ0aWZpY2F0ZSk7CisgICAgfQorCisKKworCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBjaGVja0tleXNFcXVhbChQdWJsaWNLZXkgcGsxLCBQdWJsaWNLZXkgcGsyKSB7CisgICAgICAgIC8vIGZpcnN0LCB0aGV5IHNob3VsZCBoYXZlIHRoZSBzYW1lIGZvcm1hdAorICAgICAgICAvLyBzZWNvbmQsIHRoZWlyIGVuY29kZWQgZm9ybSBtdXN0IGJlIHRoZSBzYW1lCisKKyAgICAgICAgLy8gYXNzZXJ0KHBrMSAhPSBudWxsKTsKKyAgICAgICAgLy8gYXNzZXJ0KHBrMiAhPSBudWxsKTsKKworICAgICAgICBTdHJpbmcgZm9ybWF0MSA9IHBrMS5nZXRGb3JtYXQoKTsKKyAgICAgICAgU3RyaW5nIGZvcm1hdDI7CisgICAgICAgIGlmICgocGsyID09IG51bGwpCisgICAgICAgICAgICAgICAgfHwgKCgoZm9ybWF0MiA9IHBrMi5nZXRGb3JtYXQoKSkgIT0gbnVsbCkgXiAoZm9ybWF0MSAhPSBudWxsKSkKKyAgICAgICAgICAgICAgICB8fCAoKGZvcm1hdDEgIT0gbnVsbCkgJiYgIWZvcm1hdDEuZXF1YWxzKGZvcm1hdDIpKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMocGsxLmdldEVuY29kZWQoKSwgcGsyLmdldEVuY29kZWQoKSk7CisgICAgfQorCisKKworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIHtAY29kZSBDZXJ0aWZpY2F0ZX0gZnJvbSB0aGlzIHtAY29kZSBJZGVudGl0eX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2VydGlmaWNhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2VydGlmaWNhdGV9IHRvIGJlIHJlbW92ZWQuCisgICAgICogQHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNlcnRpZmljYXRlIGlzIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVDZXJ0aWZpY2F0ZShDZXJ0aWZpY2F0ZSBjZXJ0aWZpY2F0ZSkgdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24geworICAgICAgICBpZiAoY2VydGlmaWNhdGVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmICghY2VydGlmaWNhdGVzLmNvbnRhaW5zKGNlcnRpZmljYXRlKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uKCJDZXJ0aWZpY2F0ZSBub3QgZm91bmQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNlcnRpZmljYXRlcy5yZW1vdmVFbGVtZW50KGNlcnRpZmljYXRlKTsKKyAgICAgICAgfQorICAgIH0KKworCisKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNlcnRpZmljYXRlcyBmb3IgdGhpcyB7QGNvZGUgSWRlbnRpdHl9LiBFeHRlcm5hbAorICAgICAqIG1vZGlmaWNhdGlvbnMgb2YgdGhlIHJldHVybmVkIGFycmF5IGhhcyBubyBpbXBhY3Qgb24gdGhpcyB7QGNvZGUKKyAgICAgKiBJZGVudGl0eX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgQ2VydGlmaWNhdGVzfSBmb3IgdGhpcyB7QGNvZGUgSWRlbnRpdHl9CisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlW10gY2VydGlmaWNhdGVzKCkgeworICAgICAgICBpZiAoY2VydGlmaWNhdGVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQ2VydGlmaWNhdGVbMF07CisgICAgICAgIH0KKyAgICAgICAgQ2VydGlmaWNhdGVbXSByZXQgPSBuZXcgQ2VydGlmaWNhdGVbY2VydGlmaWNhdGVzLnNpemUoKV07CisgICAgICAgIGNlcnRpZmljYXRlcy5jb3B5SW50byhyZXQpOworICAgICAgICByZXR1cm4gcmV0OworICAgIH0KKworCisKKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQge0Bjb2RlIElkZW50aXR5fSB3aXRoIHRoaXMge0Bjb2RlIElkZW50aXR5fSBmb3IKKyAgICAgKiBlcXVhbGl0eSBhbmQgcmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgZXF1YWwsCisgICAgICoge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogPHA+CisgICAgICogVG8gYmUgZXF1YWwsIHR3byB7QGNvZGUgSWRlbnRpdHl9IG9iamVjdHMgbmVlZCB0byBoYXZlIHRoZSBzYW1lIG5hbWUgYW5kCisgICAgICogdGhlIHNhbWUgcHVibGljIGtleXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaWRlbnRpdHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpZGVudGl0eSB0byBjaGVjayBmb3IgZXF1YWxpdHkuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHtAY29kZSBJZGVudGl0eX0gb2JqZWN0cyBhcmUgZXF1YWwsIHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpZGVudGl0eUVxdWFscyhJZGVudGl0eSBpZGVudGl0eSkgeworICAgICAgICBpZiAoIW5hbWUuZXF1YWxzKGlkZW50aXR5Lm5hbWUpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBpZiAocHVibGljS2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAoaWRlbnRpdHkucHVibGljS2V5ID09IG51bGwpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGNoZWNrS2V5c0VxdWFsKHB1YmxpY0tleSwgaWRlbnRpdHkucHVibGljS2V5KTsKKyAgICB9CisKKworCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUKKyAgICAgKiB0aGlzIHtAY29kZSBJZGVudGl0eX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsZWQKKyAgICAgKiAgICAgICAgICAgIHdoZXRoZXIgb3Igbm90IHRoaXMgbWV0aG9kIHNob3VsZCByZXR1cm4gZGV0YWlsZWQgaW5mb3JtYXRpb24uCisgICAgICogQHJldHVybiBhIHByaW50YWJsZSByZXByZXNlbnRhdGlvbiBmb3IgdGhpcyB7QGNvZGUgUGVybWlzc2lvbn0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZyhib29sZWFuIGRldGFpbGVkKSB7CisgICAgICAgIFN0cmluZyBzID0gdG9TdHJpbmcoKTsKKyAgICAgICAgaWYgKGRldGFpbGVkKSB7CisgICAgICAgICAgICBzICs9ICIgIiArIGluZm87CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHM7CisgICAgfQorCisKKworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIElkZW50aXR5U2NvcGV9IG9mIHRoaXMge0Bjb2RlIElkZW50aXR5fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBJZGVudGl0eVNjb3BlfSBvZiB0aGlzIHtAY29kZSBJZGVudGl0eX0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIElkZW50aXR5U2NvcGUgZ2V0U2NvcGUoKSB7CisgICAgICAgIHJldHVybiBzY29wZTsKKyAgICB9CisKKworCisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzcGVjaWZpZWQge0Bjb2RlIFB1YmxpY0tleX0gdG8gdGhpcyB7QGNvZGUgSWRlbnRpdHl9LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBQdWJsaWNLZXl9IHRvIGJlIHNldC4KKyAgICAgKiBAdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbm90aGVyIHtAY29kZSBJZGVudGl0eX0gaW4gdGhlIHNhbWUgc2NvcGUgYXMgdGhpcyB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBJZGVudGl0eX0gYWxyZWFkeSBoYXMgdGhlIHNhbWUge0Bjb2RlIFB1YmxpY0tleX0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UHVibGljS2V5KFB1YmxpY0tleSBrZXkpIHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgLy8gdGhpcyBjaGVjayBkb2VzIG5vdCBhbHdheXMgd29yaworICAgICAgICBpZiAoKHNjb3BlICE9IG51bGwpICYmIChrZXkgIT0gbnVsbCkpIHsKKyAgICAgICAgICAgIElkZW50aXR5IGkgPSBzY29wZS5nZXRJZGVudGl0eShrZXkpOworICAgICAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oIiMjI0RFQlVHIyMgSWRlbnRpdHk6ICIraSk7CisgICAgICAgICAgICBpZiAoKGkgIT0gbnVsbCkgJiYgKGkgIT0gdGhpcykpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbigia2V5IGFscmVhZHkgdXNlZCBpbiBzY29wZSIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRoaXMucHVibGljS2V5ID0ga2V5OworICAgICAgICBjZXJ0aWZpY2F0ZXMgPSBudWxsOworICAgIH0KKworCisKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBQdWJsaWNLZXl9IGFzc29jaWF0ZWQgd2l0aCB0aGlzIHtAY29kZSBJZGVudGl0eX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgUHVibGljS2V5fSBhc3NvY2lhdGVkIHdpdGggdGhpcyB7QGNvZGUgSWRlbnRpdHl9LgorICAgICAqLworICAgIHB1YmxpYyBQdWJsaWNLZXkgZ2V0UHVibGljS2V5KCkgeworICAgICAgICByZXR1cm4gcHVibGljS2V5OworICAgIH0KKworCisKKworICAgIC8qKgorICAgICAqIFNldHMgYW4gaW5mb3JtYXRpb24gc3RyaW5nIGZvciB0aGlzIHtAY29kZSBJZGVudGl0eX0uCisgICAgICogQHBhcmFtIGluZm8KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmZvcm1hdGlvbiB0byBiZSBzZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SW5mbyhTdHJpbmcgaW5mbykgeworICAgICAgICB0aGlzLmluZm8gPSBpbmZvOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGluZm9ybWF0aW9uIHN0cmluZyBvZiB0aGlzIHtAY29kZSBJZGVudGl0eX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbmZvcm1hdGlvbiBzdHJpbmcgb2YgdGhpcyB7QGNvZGUgSWRlbnRpdHl9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0SW5mbygpIHsKKyAgICAgICAgcmV0dXJuIGluZm87CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBvYmplY3Qgd2l0aCB0aGlzIHtAY29kZSBJZGVudGl0eX0gZm9yIGVxdWFsaXR5IGFuZAorICAgICAqIHJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsLCB7QGNvZGUgZmFsc2V9CisgICAgICogb3RoZXJ3aXNlLiB7QGNvZGUgSWRlbnRpdHl9IG9iamVjdHMgYXJlIGNvbnNpZGVyZWQgZXF1YWwsIGlmIHRoZXkgaGF2ZQorICAgICAqIHRoZSBzYW1lIG5hbWUgYW5kIGFyZSBpbiB0aGUgc2FtZSBzY29wZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIG9iamVjdCB0byBiZSBjb21wYXJlZCBmb3IgZXF1YWxpdHkgd2l0aCB0aGlzIHtAY29kZQorICAgICAqICAgICAgICAgICAgSWRlbnRpdHl9LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMge0Bjb2RlCisgICAgICogICAgICAgICBJZGVudGl0eX0sIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgIGlmICh0aGlzID09IG9iaikgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgSWRlbnRpdHkpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgSWRlbnRpdHkgaSA9IChJZGVudGl0eSkgb2JqOworICAgICAgICBpZiAoT2JqZWN0cy5lcXVhbChuYW1lLCBpLm5hbWUpICYmIChPYmplY3RzLmVxdWFsKHNjb3BlLCBpLnNjb3BlKSkpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpZGVudGl0eUVxdWFscyhpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoaXMge0Bjb2RlIElkZW50aXR5fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhpcyB7QGNvZGUgSWRlbnRpdHl9LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaGFzaCBjb2RlIHZhbHVlIGZvciB0aGlzIHtAY29kZSBJZGVudGl0eX0uIFJldHVybnMgdGhlIHNhbWUKKyAgICAgKiBoYXNoIGNvZGUgZm9yIHtAY29kZSBJZGVudGl0eX1zIHRoYXQgYXJlIGVxdWFsIHRvIGVhY2ggb3RoZXIgYXMgcmVxdWlyZWQKKyAgICAgKiBieSB0aGUgZ2VuZXJhbCBjb250cmFjdCBvZiB7QGxpbmsgT2JqZWN0I2hhc2hDb2RlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZSB2YWx1ZSBmb3IgdGhpcyB7QGNvZGUgSWRlbnRpdHl9LgorICAgICAqIEBzZWUgT2JqZWN0I2VxdWFscyhPYmplY3QpCisgICAgICogQHNlZSBJZGVudGl0eSNlcXVhbHMoT2JqZWN0KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGludCBoYXNoID0gMDsKKyAgICAgICAgaWYgKG5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgaGFzaCArPSBuYW1lLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNjb3BlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGhhc2ggKz0gc2NvcGUuaGFzaENvZGUoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUKKyAgICAgKiB0aGlzIHtAY29kZSBJZGVudGl0eX0gaW5jbHVkaW5nIGl0cyBuYW1lIGFuZCBpdHMgc2NvcGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcHJpbnRhYmxlIHJlcHJlc2VudGF0aW9uIGZvciB0aGlzIHtAY29kZSBJZGVudGl0eX0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nIHMgPSAodGhpcy5uYW1lID09IG51bGwgPyAiIiA6IHRoaXMubmFtZSk7CisgICAgICAgIGlmIChzY29wZSAhPSBudWxsKSB7CisgICAgICAgICAgICBzICs9ICIgWyIgKyBzY29wZS5nZXROYW1lKCkgKyAiXSI7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvSWRlbnRpdHlTY29wZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvSWRlbnRpdHlTY29wZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFlMzQ0ZmQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9JZGVudGl0eVNjb3BlLmphdmEKQEAgLTAsMCArMSwxOTMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKKworCisvKioKKyAqIHtAY29kZSBJZGVudGl0eVNjb3BlfSByZXByZXNlbnRzIGEgc2NvcGUgZm9yIHtAbGluayBJZGVudGl0eX0gb2JqZWN0cy4KKyAqCisgKiBAZGVwcmVjYXRlZCBUaGUgZnVuY3Rpb25hbGl0eSBvZiB0aGlzIGNsYXNzIGhhcyBiZWVuIHJlcGxhY2UgYnkKKyAqICAgICAgICAgICAgIHtAbGluayBQcmluY2lwYWx9LCB7QGxpbmsgS2V5U3RvcmV9IGFuZCB0aGUge0Bjb2RlCisgKiAgICAgICAgICAgICBqYXZhLnNlY3VyaXR5LmNlcnR9IHBhY2thZ2UuCisgKi8KK0BEZXByZWNhdGVkCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgSWRlbnRpdHlTY29wZSBleHRlbmRzIElkZW50aXR5IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yMzM3MzQ2MjgxMTg5NzczMzEwTDsKKworICAgIC8vIHN5c3RlbVNjb3BlIGhvbGRzIHJlZmVyZW5jZSB0byB0aGUgY3VycmVudCBzeXN0ZW0gc2NvcGUKKyAgICBwcml2YXRlIHN0YXRpYyBJZGVudGl0eVNjb3BlIHN5c3RlbVNjb3BlOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgSWRlbnRpdHlTY29wZX0uCisgICAgICovCisgICAgcHJvdGVjdGVkIElkZW50aXR5U2NvcGUoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgSWRlbnRpdHlTY29wZX0gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGlzIHtAY29kZSBJZGVudGl0eVNjb3BlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSWRlbnRpdHlTY29wZShTdHJpbmcgbmFtZSkgeworICAgICAgICBzdXBlcihuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBJZGVudGl0eVNjb3BlfSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBuYW1lIGFuZCB0aGUgc3BlY2lmaWVkIHNjb3BlLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoaXMge0Bjb2RlIElkZW50aXR5U2NvcGV9LgorICAgICAqIEBwYXJhbSBzY29wZQorICAgICAqICAgICAgICAgICAgdGhlIHNjb3BlIG9mIHRoaXMge0Bjb2RlIElkZW50aXR5U2NvcGV9LgorICAgICAqIEB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGlkZW50aXR5IHdpdGggdGhlIHNhbWUga2V5IGFscmVhZHkgZXhpc3RzLgorICAgICAqLworICAgIHB1YmxpYyBJZGVudGl0eVNjb3BlKFN0cmluZyBuYW1lLCBJZGVudGl0eVNjb3BlIHNjb3BlKQorICAgICAgICAgICAgdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24geworICAgICAgICBzdXBlcihuYW1lLCBzY29wZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3lzdGVtJ3Mgc2NvcGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzeXN0ZW0ncyBzY29wZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIElkZW50aXR5U2NvcGUgZ2V0U3lzdGVtU2NvcGUoKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFRlc3Qgc2hvd3MgdGhhdCB0aGUgaW1wbGVtZW50YXRpb24gY2xhc3MgbmFtZSBpcyByZWFkIGZyb20gc2VjdXJpdHkgcHJvcGVydHkKKyAgICAgICAgICogInN5c3RlbS5zY29wZSIsIGFuZCB0aGUgY2xhc3MgaXMgb25seSBsb2FkZWQgZnJvbSBib290IGNsYXNzcGF0aC4gTm8gZGVmYXVsdAorICAgICAgICAgKiBpbXBsZW1lbnRhdGlvbiBhcyBmYWxsYmFjaywgaS5lLiwgcmV0dXJuIG51bGwgaWYgZmFpbHMgdG8gaW5pdCBhbiBpbnN0YW5jZS4KKyAgICAgICAgICovCisgICAgICAgIGlmIChzeXN0ZW1TY29wZSA9PSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lID0gU2VjdXJpdHkuZ2V0UHJvcGVydHkoInN5c3RlbS5zY29wZSIpOworICAgICAgICAgICAgaWYoY2xhc3NOYW1lICE9IG51bGwpeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN5c3RlbVNjb3BlID0gKElkZW50aXR5U2NvcGUpIENsYXNzLmZvck5hbWUoY2xhc3NOYW1lKS5uZXdJbnN0YW5jZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBzeXN0ZW1TY29wZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzeXN0ZW0ncyBzY29wZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzY29wZQorICAgICAqICAgICAgICAgICAgdGhlIHNjb3BlIHRvIHNldC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIHZvaWQgc2V0U3lzdGVtU2NvcGUoSWRlbnRpdHlTY29wZSBzY29wZSkgeworICAgICAgICBzeXN0ZW1TY29wZSA9IHNjb3BlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiB7QGNvZGUgSWRlbnRpdHl9IG9iamVjdHMgaW4gdGhpcyBzY29wZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiB7QGNvZGUgSWRlbnRpdHl9IG9iamVjdHMgaW4gdGhpcyBzY29wZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IHNpemUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBJZGVudGl0eX0gd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgb3Ige0Bjb2RlIG51bGx9IGlmCisgICAgICogbm8ge0Bjb2RlIElkZW50aXR5fSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBpcyBwcmVzZW50IGluIHRoaXMgc2NvcGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHtAY29kZSBJZGVudGl0eX0gdG8gYmUgcmV0dXJuZWQuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIElkZW50aXR5fSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBvciB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiAgICAgICAgIG5vdCBwcmVzZW50LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBJZGVudGl0eSBnZXRJZGVudGl0eShTdHJpbmcgbmFtZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgSWRlbnRpdHl9IHdpdGggdGhlIG5hbWUgb2YgdGhlIHNwZWNpZmllZCBwcmluY2lwYWwgb3IKKyAgICAgKiB7QGNvZGUgbnVsbH0gaWYgbm8ge0Bjb2RlIElkZW50aXR5fSB3aXRoIHRoZSBuYW1lIG9mIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBwcmluY2lwYWwgaXMgcHJlc2VudCBpbiB0aGlzIHNjb3BlLgorICAgICAqCisgICAgICogQHBhcmFtIHByaW5jaXBhbAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBQcmluY2lwYWx9IHdob3NlIG5hbWUgaXMgdXNlZCB0byBsb29rdXAgdGhlIHtAY29kZQorICAgICAqICAgICAgICAgICAgSWRlbnRpdHl9IHRvIGJlIHJldHVybmVkLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBJZGVudGl0eX0gd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgb3Ige0Bjb2RlIG51bGx9IGlmCisgICAgICogICAgICAgICBub3QgcHJlc2VudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSWRlbnRpdHkgZ2V0SWRlbnRpdHkoUHJpbmNpcGFsIHByaW5jaXBhbCkgeworICAgICAgICByZXR1cm4gZ2V0SWRlbnRpdHkocHJpbmNpcGFsLmdldE5hbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIElkZW50aXR5fSB3aGljaCBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBrZXkKKyAgICAgKiBvciB7QGNvZGUgbnVsbH0gaWYgbm8ge0Bjb2RlIElkZW50aXR5fSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBrZXkKKyAgICAgKiBpcyBwcmVzZW50IGluIHRoaXMgc2NvcGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIFB1YmxpY0tleX0gb2YgdGhlIHtAY29kZSBJZGVudGl0eX0gdG8gYmUgcmV0dXJuZWQuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIElkZW50aXR5fSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBrZXkgb3Ige0Bjb2RlCisgICAgICogICAgICAgICBudWxsfSBpZiBub3QgcHJlc2VudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgSWRlbnRpdHkgZ2V0SWRlbnRpdHkoUHVibGljS2V5IGtleSk7CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGFuIHtAY29kZSBJZGVudGl0eX0gdG8gdGhpcyB7QGNvZGUgSWRlbnRpdHlTY29wZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaWRlbnRpdHkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgSWRlbnRpdHl9IHRvIGJlIGFkZGVkLgorICAgICAqIEB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQge0Bjb2RlIElkZW50aXR5fSBpcyBpbnZhbGlkIG9yIGFuIGlkZW50aXR5CisgICAgICogICAgICAgICAgICAgd2l0aCB0aGUgc2FtZSBrZXkgYWxyZWFkeSBleGlzdHMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgYWRkSWRlbnRpdHkoSWRlbnRpdHkgaWRlbnRpdHkpCisgICAgICAgICAgICB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYW4ge0Bjb2RlIElkZW50aXR5fSBmcm9tIHRoaXMge0Bjb2RlIElkZW50aXR5U2NvcGV9LgorICAgICAqCisgICAgICogQHBhcmFtIGlkZW50aXR5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIElkZW50aXR5fSB0byBiZSByZW1vdmVkLgorICAgICAqIEB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgSWRlbnRpdHl9IGlzIG5vdCBwcmVzZW50IGluIHRoaXMgc2NvcGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcmVtb3ZlSWRlbnRpdHkoSWRlbnRpdHkgaWRlbnRpdHkpCisgICAgICAgICAgICB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4ge0Bjb2RlIEVudW1lcmF0aW9ufSBvdmVyIHRoZSB7QGNvZGUgSWRlbnRpdHl9IG9iamVjdHMgaW4gdGhpcworICAgICAqIHtAY29kZSBJZGVudGl0eVNjb3BlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIEVudW1lcmF0aW9ufSBvdmVyIHRoZSB7QGNvZGUgSWRlbnRpdHl9IG9iamVjdHMgaW4gdGhpcworICAgICAqICAgICAgICAge0Bjb2RlIElkZW50aXR5U2NvcGV9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBFbnVtZXJhdGlvbjxJZGVudGl0eT4gaWRlbnRpdGllcygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhpcworICAgICAqIHtAY29kZSBJZGVudGl0eVNjb3BlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBwcmludGFibGUgcmVwcmVzZW50YXRpb24gZm9yIHRoaXMge0Bjb2RlIElkZW50aXR5U2NvcGV9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nQnVpbGRlcihzdXBlci50b1N0cmluZygpKQorICAgICAgICAgICAgICAgIC5hcHBlbmQoIlsiKS5hcHBlbmQoc2l6ZSgpKS5hcHBlbmQoIl0iKS50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0ludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0ludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNmQ5Zjk3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworLyoqCisgKiB7QGNvZGUgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbn0gaW5kaWNhdGVzIHRoZSBvY2N1cnJlbmNlIG9mCisgKiBpbnZhbGlkIGFsZ29yaXRobSBwYXJhbWV0ZXJzLgorICovCitwdWJsaWMgY2xhc3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBleHRlbmRzCisgICAgICAgIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjg2NDY3MjI5NzQ5OTQ3MTQ3Mkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9ufQorICAgICAqIHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKKyAgICAgICAgc3VwZXIobXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9ufSB3aXRoIHRoZQorICAgICAqIGdpdmVuIG1lc3NhZ2UgYW5kIHRoZSBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGV4Y2VwdGlvbiB3aGljaCBpcyB0aGUgY2F1c2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb259CisgICAgICogd2l0aCB0aGUgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNlcHRpb24gd2hpY2ggaXMgdGhlIGNhdXNlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0ludmFsaWRLZXlFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0ludmFsaWRLZXlFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMDhmYzUxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvSW52YWxpZEtleUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworLyoqCisgKiB7QGNvZGUgSW52YWxpZEtleUV4Y2VwdGlvbn0gaW5kaWNhdGVzIGV4Y2VwdGlvbmFsIGNvbmRpdGlvbnMsIGNhdXNlZCBieSBhbgorICogaW52YWxpZCBrZXkuCisgKi8KK3B1YmxpYyBjbGFzcyBJbnZhbGlkS2V5RXhjZXB0aW9uIGV4dGVuZHMgS2V5RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDU2OTg0Nzk5MjA1OTMzNTk4MTZMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgSW52YWxpZEtleUV4Y2VwdGlvbn0gd2l0aCB0aGUgZ2l2ZW4KKyAgICAgKiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW52YWxpZEtleUV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgSW52YWxpZEtleUV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIEludmFsaWRLZXlFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgSW52YWxpZEtleUV4Y2VwdGlvbn0gd2l0aCB0aGUgZ2l2ZW4KKyAgICAgKiBtZXNzYWdlIGFuZCB0aGUgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNlcHRpb24gd2hpY2ggaXMgdGhlIGNhdXNlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW52YWxpZEtleUV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UsIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBJbnZhbGlkS2V5RXhjZXB0aW9ufSB3aXRoIHRoZSBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGV4Y2VwdGlvbiB3aGljaCBpcyB0aGUgY2F1c2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBJbnZhbGlkS2V5RXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZhZDQ2NDUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9JbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCisvKioKKyAqIHtAY29kZSBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9ufSBpbmRpY2F0ZXMgZXhjZXB0aW9uYWwgY29uZGl0aW9ucywgY2F1c2VkIGJ5CisgKiBpbnZhbGlkIHBhcmFtZXRlcnMuCisgKi8KK3B1YmxpYyBjbGFzcyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIGV4dGVuZHMgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04NTc5Njg1MzY5MzU2Njc4MDhMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbn0gd2l0aCB0aGUKKyAgICAgKiBnaXZlbiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvS2V5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9LZXkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZmY0NjI5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvS2V5LmphdmEKQEAgLTAsMCArMSw2MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKKy8qKgorICoge0Bjb2RlIEtleX0gaXMgdGhlIGNvbW1vbiBpbnRlcmZhY2UgZm9yIGFsbCBrZXlzLgorICoKKyAqIEBzZWUgUHVibGljS2V5CisgKiBAc2VlIFByaXZhdGVLZXkKKyAqLworcHVibGljIGludGVyZmFjZSBLZXkgZXh0ZW5kcyBTZXJpYWxpemFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIHtAY29kZSBzZXJpYWxWZXJzaW9uVUlEfSB0byBiZSBjb21wYXRpYmxlIHdpdGggSkRLMS4xLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjYwMzM4NDE1Mjc0OTU2NzY1NEw7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0gb2YgdGhpcyBrZXkuIElmIHRoZSBhbGdvcml0aG0gaXMKKyAgICAgKiB1bmtub3duLCB7QGNvZGUgbnVsbH0gaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0gb2YgdGhpcyBrZXkgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqICAgICAgICAgYWxnb3JpdGhtIGlzIHVua25vd24uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGZvcm1hdCB1c2VkIHRvIGVuY29kZSB0aGlzIGtleSwgb3Ige0Bjb2RlIG51bGx9CisgICAgICogaWYgaXQgY2FuIG5vdCBiZSBlbmNvZGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgZm9ybWF0IHVzZWQgdG8gZW5jb2RlIHRoaXMga2V5LCBvciB7QGNvZGUgbnVsbH0KKyAgICAgKiAgICAgICAgIGlmIGl0IGNhbiBub3QgYmUgZW5jb2RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5jb2RlZCBmb3JtIG9mIHRoaXMga2V5LCBvciB7QGNvZGUgbnVsbH0gaWYgZW5jb2RpbmcgaXMgbm90CisgICAgICogc3VwcG9ydGVkIGJ5IHRoaXMga2V5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZW5jb2RlZCBmb3JtIG9mIHRoaXMga2V5LCBvciB7QGNvZGUgbnVsbH0gaWYgZW5jb2RpbmcgaXMgbm90CisgICAgICogICAgICAgICBzdXBwb3J0ZWQgYnkgdGhpcyBrZXkuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9LZXlFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0tleUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcyMWM4OTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9LZXlFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDY1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKKy8qKgorICoge0Bjb2RlIEtleUV4Y2VwdGlvbn0gaXMgdGhlIGNvbW1vbiBzdXBlcmNsYXNzIG9mIGFsbCBrZXkgcmVsYXRlZCBleGNlcHRpb25zLgorICovCitwdWJsaWMgY2xhc3MgS2V5RXhjZXB0aW9uIGV4dGVuZHMgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03NDgzNjc2OTQyODEyNDMyMTA4TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEtleUV4Y2VwdGlvbn0gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIEtleUV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgS2V5RXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgS2V5RXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEtleUV4Y2VwdGlvbn0gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZQorICAgICAqIGFuZCB0aGUgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNlcHRpb24gd2hpY2ggaXMgdGhlIGNhdXNlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgS2V5RXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEtleUV4Y2VwdGlvbn0gd2l0aCB0aGUgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNlcHRpb24gd2hpY2ggaXMgdGhlIGNhdXNlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgS2V5RXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvS2V5RmFjdG9yeS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvS2V5RmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU1NDg4NWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9LZXlGYWN0b3J5LmphdmEKQEAgLTAsMCArMSwyMjEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5JbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuS2V5U3BlYzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuZm9ydHJlc3MuRW5naW5lOworCisvKioKKyAqIHtAY29kZSBLZXlGYWN0b3J5fSBpcyBhbiBlbmdpbmUgY2xhc3MgdGhhdCBjYW4gYmUgdXNlZCB0byB0cmFuc2xhdGUgYmV0d2VlbgorICogcHVibGljIGFuZCBwcml2YXRlIGtleSBvYmplY3RzIGFuZCBjb252ZXJ0IGtleXMgYmV0d2VlbiB0aGVpciBleHRlcm5hbAorICogcmVwcmVzZW50YXRpb24sIHRoYXQgY2FuIGJlIGVhc2lseSB0cmFuc3BvcnRlZCBhbmQgdGhlaXIgaW50ZXJuYWwKKyAqIHJlcHJlc2VudGF0aW9uLgorICovCitwdWJsaWMgY2xhc3MgS2V5RmFjdG9yeSB7CisgICAgLy8gVGhlIHNlcnZpY2UgbmFtZS4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VSVklDRSA9ICJLZXlGYWN0b3J5IjsKKworICAgIC8vIFVzZWQgdG8gYWNjZXNzIGNvbW1vbiBlbmdpbmUgZnVuY3Rpb25hbGl0eQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEVuZ2luZSBFTkdJTkUgPSBuZXcgRW5naW5lKFNFUlZJQ0UpOworCisgICAgLy8gVGhlIHByb3ZpZGVyCisgICAgcHJpdmF0ZSBmaW5hbCBQcm92aWRlciBwcm92aWRlcjsKKworICAgIC8vIFRoZSBTUEkgaW1wbGVtZW50YXRpb24uCisgICAgcHJpdmF0ZSBmaW5hbCBLZXlGYWN0b3J5U3BpIHNwaUltcGw7CisKKyAgICAvLyBUaGUgYWxnb3JpdGhtLgorICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGFsZ29yaXRobTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEtleUZhY3Rvcnl9IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIGFyZ3VtZW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXlGYWNTcGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb25jcmV0ZSBrZXkgZmFjdG9yeSBzZXJ2aWNlLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHByb3ZpZGVyLgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGdvcml0aG0gdG8gdXNlLgorICAgICAqLworICAgIHByb3RlY3RlZCBLZXlGYWN0b3J5KEtleUZhY3RvcnlTcGkga2V5RmFjU3BpLAorICAgICAgICAgICAgICAgICAgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgdGhpcy5wcm92aWRlciA9IHByb3ZpZGVyOworICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICAgICAgdGhpcy5zcGlJbXBsID0ga2V5RmFjU3BpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEtleUZhY3Rvcnl9IHRoYXQgdXRpbGl6ZXMgdGhlIHNwZWNpZmllZAorICAgICAqIGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0uCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgS2V5RmFjdG9yeX0gdGhhdCB1dGlsaXplcyB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBwcm92aWRlciBwcm92aWRlcyB0aGUgcmVxdWVzdGVkIGFsZ29yaXRobS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEtleUZhY3RvcnkgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIEVuZ2luZS5TcGlBbmRQcm92aWRlciBzYXAgPSBFTkdJTkUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBudWxsKTsKKyAgICAgICAgcmV0dXJuIG5ldyBLZXlGYWN0b3J5KChLZXlGYWN0b3J5U3BpKSBzYXAuc3BpLCBzYXAucHJvdmlkZXIsIGFsZ29yaXRobSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgS2V5RmFjdG9yeX0gdGhhdCB1dGlsaXplcyB0aGUgc3BlY2lmaWVkCisgICAgICogYWxnb3JpdGhtIGZyb20gdGhlIHNwZWNpZmllZCBwcm92aWRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0uCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcHJvdmlkZXIuCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgS2V5RmFjdG9yeX0gdGhhdCB1dGlsaXplcyB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBhbGdvcml0aG0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHByb3ZpZGVyIGRvZXMgbm90IHByb3ZpZGUgdGhlIHJlcXVlc3RlZCBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSByZXF1ZXN0ZWQgcHJvdmlkZXIgaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgcHJvdmlkZXIgPT0gbnVsbCB8fCBwcm92aWRlci5pc0VtcHR5KCl9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBLZXlGYWN0b3J5IGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcikKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwgfHwgcHJvdmlkZXIuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgUHJvdmlkZXIgcCA9IFNlY3VyaXR5LmdldFByb3ZpZGVyKHByb3ZpZGVyKTsKKyAgICAgICAgaWYgKHAgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uKHByb3ZpZGVyKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBLZXlGYWN0b3J5fSB0aGF0IHV0aWxpemVzIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBhbGdvcml0aG0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobS4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWN1cml0eSBwcm92aWRlci4KKyAgICAgKiBAcmV0dXJuIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBLZXlGYWN0b3J5fSB0aGF0IHV0aWxpemVzIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIGFsZ29yaXRobSBmcm9tIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIuCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcHJvdmlkZXIgZG9lcyBub3QgcHJvdmlkZSB0aGUgcmVxdWVzdGVkIGFsZ29yaXRobS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgcHJvdmlkZXIgPT0gbnVsbH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEtleUZhY3RvcnkgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgUHJvdmlkZXIgcHJvdmlkZXIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIE9iamVjdCBzcGkgPSBFTkdJTkUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBwcm92aWRlciwgbnVsbCk7CisgICAgICAgIHJldHVybiBuZXcgS2V5RmFjdG9yeSgoS2V5RmFjdG9yeVNwaSkgc3BpLCBwcm92aWRlciwgYWxnb3JpdGhtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcm92aWRlciBhc3NvY2lhdGVkIHdpdGggdGhpcyB7QGNvZGUgS2V5RmFjdG9yeX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcm92aWRlciBhc3NvY2lhdGVkIHdpdGggdGhpcyB7QGNvZGUgS2V5RmFjdG9yeX0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFByb3ZpZGVyIGdldFByb3ZpZGVyKCkgeworICAgICAgICByZXR1cm4gcHJvdmlkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHtAY29kZQorICAgICAqIEtleUZhY3Rvcnl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHtAY29kZQorICAgICAqICAgICAgICAgS2V5RmFjdG9yeX0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiBhbGdvcml0aG07CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGEgaW5zdGFuY2Ugb2Yge0Bjb2RlIFB1YmxpY0tleX0gZnJvbSB0aGUgZ2l2ZW4ga2V5CisgICAgICogc3BlY2lmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXlTcGVjCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWNhdGlvbiBvZiB0aGUgcHVibGljIGtleQorICAgICAqIEByZXR1cm4gdGhlIHB1YmxpYyBrZXkKKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCB7QGNvZGUga2V5U3BlY30gaXMgaW52YWxpZAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBQdWJsaWNLZXkgZ2VuZXJhdGVQdWJsaWMoS2V5U3BlYyBrZXlTcGVjKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVHZW5lcmF0ZVB1YmxpYyhrZXlTcGVjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgYSBpbnN0YW5jZSBvZiB7QGNvZGUgUHJpdmF0ZUtleX0gZnJvbSB0aGUgZ2l2ZW4ga2V5CisgICAgICogc3BlY2lmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXlTcGVjCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWNhdGlvbiBvZiB0aGUgcHJpdmF0ZSBrZXkuCisgICAgICogQHJldHVybiB0aGUgcHJpdmF0ZSBrZXkuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQge0Bjb2RlIGtleVNwZWN9IGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFByaXZhdGVLZXkgZ2VuZXJhdGVQcml2YXRlKEtleVNwZWMga2V5U3BlYykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lR2VuZXJhdGVQcml2YXRlKGtleVNwZWMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGtleSBzcGVjaWZpY2F0aW9uIGZvciB0aGUgc3BlY2lmaWVkIGtleS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgZnJvbSB3aGljaCB0aGUgc3BlY2lmaWNhdGlvbiBpcyByZXF1ZXN0ZWQuCisgICAgICogQHBhcmFtIGtleVNwZWMKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSByZXF1ZXN0ZWQge0Bjb2RlIEtleVNwZWN9LgorICAgICAqIEByZXR1cm4gdGhlIGtleSBzcGVjaWZpY2F0aW9uIGZvciB0aGUgc3BlY2lmaWVkIGtleS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGtleSBjYW4gbm90IGJlIHByb2Nlc3NlZCwgb3IgdGhlIHJlcXVlc3RlZCByZXF1ZXN0ZWQKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgS2V5U3BlY30gaXMgaW5hcHByb3ByaWF0ZSBmb3IgdGhlIGdpdmVuIGtleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgPFQgZXh0ZW5kcyBLZXlTcGVjPiBUIGdldEtleVNwZWMoS2V5IGtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzPFQ+IGtleVNwZWMpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lR2V0S2V5U3BlYyhrZXksIGtleVNwZWMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyYW5zbGF0ZXMgdGhlIGdpdmVuIGtleSBpbnRvIGEga2V5IGZyb20gdGhpcyBrZXkgZmFjdG9yeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgdG8gdHJhbnNsYXRlLgorICAgICAqIEByZXR1cm4gdGhlIHRyYW5zbGF0ZWQga2V5LgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbiBub3QgYmUgdHJhbnNsYXRlZCBieSB0aGlzIGtleQorICAgICAqICAgICAgICAgICAgIGZhY3RvcnkuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEtleSB0cmFuc2xhdGVLZXkoS2V5IGtleSkKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lVHJhbnNsYXRlS2V5KGtleSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvS2V5RmFjdG9yeVNwaS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvS2V5RmFjdG9yeVNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMxYmRmYjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9LZXlGYWN0b3J5U3BpLmphdmEKQEAgLTAsMCArMSw4NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkludmFsaWRLZXlTcGVjRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5LZXlTcGVjOworCisvKioKKyAqIHtAY29kZSBLZXlGYWN0b3J5U3BpfSBpcyB0aGUgU2VydmljZSBQcm92aWRlciBJbnRlcmZhY2UgKFNQSSkgZGVmaW5pdGlvbiBmb3IKKyAqIHtAbGluayBLZXlGYWN0b3J5fS4KKyAqCisgKiBAc2VlIEtleUZhY3RvcnkKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEtleUZhY3RvcnlTcGkgeworCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGEgaW5zdGFuY2Ugb2Yge0Bjb2RlIFB1YmxpY0tleX0gZnJvbSB0aGUgZ2l2ZW4ga2V5CisgICAgICogc3BlY2lmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXlTcGVjCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWNhdGlvbiBvZiB0aGUgcHVibGljIGtleS4KKyAgICAgKiBAcmV0dXJuIHRoZSBwdWJsaWMga2V5LgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHtAY29kZSBrZXlTcGVjfSBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBQdWJsaWNLZXkgZW5naW5lR2VuZXJhdGVQdWJsaWMoS2V5U3BlYyBrZXlTcGVjKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGEgaW5zdGFuY2Ugb2Yge0Bjb2RlIFByaXZhdGVLZXl9IGZyb20gdGhlIGdpdmVuIGtleQorICAgICAqIHNwZWNpZmljYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5U3BlYworICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmljYXRpb24gb2YgdGhlIHByaXZhdGUga2V5LgorICAgICAqIEByZXR1cm4gdGhlIHByaXZhdGUga2V5LgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHtAY29kZSBrZXlTcGVjfSBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBQcml2YXRlS2V5IGVuZ2luZUdlbmVyYXRlUHJpdmF0ZShLZXlTcGVjIGtleVNwZWMpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBrZXkgc3BlY2lmaWNhdGlvbiBmb3IgdGhlIHNwZWNpZmllZCBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IGZyb20gd2hpY2ggdGhlIHNwZWNpZmljYXRpb24gaXMgcmVxdWVzdGVkLgorICAgICAqIEBwYXJhbSBrZXlTcGVjCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgcmVxdWVzdGVkIHtAY29kZSBLZXlTcGVjfS4KKyAgICAgKiBAcmV0dXJuIHRoZSBrZXkgc3BlY2lmaWNhdGlvbiBmb3IgdGhlIHNwZWNpZmllZCBrZXkuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBrZXkgY2FuIG5vdCBiZSBwcm9jZXNzZWQsIG9yIHRoZSByZXF1ZXN0ZWQgcmVxdWVzdGVkCisgICAgICogICAgICAgICAgICAge0Bjb2RlIEtleVNwZWN9IGlzIGluYXBwcm9wcmlhdGUgZm9yIHRoZSBnaXZlbiBrZXkuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IDxUIGV4dGVuZHMgS2V5U3BlYz4gVCBlbmdpbmVHZXRLZXlTcGVjKEtleSBrZXksIENsYXNzPFQ+IGtleVNwZWMpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb247CisgICAgLy9GSVhNRSAxLjUgc2lnbmF0dXJlOiBwcm90ZWN0ZWQgYWJzdHJhY3QgPFQgZXh0ZW5kcyBLZXlTcGVjPiBUIGVuZ2luZUdldEtleVNwZWMoS2V5IGtleSwgQ2xhc3M8VD4ga2V5U3BlYykgdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisKKyAgICAvKioKKyAgICAgKiBUcmFuc2xhdGVzIHRoZSBnaXZlbiBrZXkgaW50byBhIGtleSBmcm9tIHRoaXMga2V5IGZhY3RvcnkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IHRvIHRyYW5zbGF0ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSB0cmFuc2xhdGVkIGtleS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGtleSBjYW4gbm90IGJlIHRyYW5zbGF0ZWQgYnkgdGhpcyBrZXkKKyAgICAgKiAgICAgICAgICAgICBmYWN0b3J5LgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBLZXkgZW5naW5lVHJhbnNsYXRlS2V5KEtleSBrZXkpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9LZXlNYW5hZ2VtZW50RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9LZXlNYW5hZ2VtZW50RXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDBhNWIzYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0tleU1hbmFnZW1lbnRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDY5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKKy8qKgorICoge0Bjb2RlIEtleU1hbmFnZW1lbnRFeGNlcHRpb259IGlzIGEgZ2VuZXJhbCBleGNlcHRpb24sIHRocm93biB0byBpbmRpY2F0ZSBhbgorICogZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nIGFuIG9wZXJhdGlvbiBjb25jZXJuaW5nIGtleSBtYW5hZ2VtZW50LgorICovCitwdWJsaWMgY2xhc3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiBleHRlbmRzIEtleUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA5NDc2NzQyMTYxNTcwNjI2OTVMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbn0gd2l0aCB0aGUKKyAgICAgKiBnaXZlbiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIEtleU1hbmFnZW1lbnRFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbn0gd2l0aCB0aGUKKyAgICAgKiBnaXZlbiBtZXNzYWdlIGFuZCB0aGUgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNlcHRpb24gd2hpY2ggaXMgdGhlIGNhdXNlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UsIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBLZXlNYW5hZ2VtZW50RXhjZXB0aW9ufSB3aXRoIHRoZQorICAgICAqIGNhdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgZXhjZXB0aW9uIHdoaWNoIGlzIHRoZSBjYXVzZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIEtleU1hbmFnZW1lbnRFeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGNhdXNlKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0tleVBhaXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0tleVBhaXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZjZlYmQyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvS2V5UGFpci5qYXZhCkBAIC0wLDAgKzEsNjYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCisvKioKKyAqIHtAY29kZSBLZXlQYWlyfSBpcyBhIGNvbnRhaW5lciBmb3IgYSBwdWJsaWMga2V5IGFuZCBhIHByaXZhdGUga2V5LiBTaW5jZSB0aGUKKyAqIHByaXZhdGUga2V5IGNhbiBiZSBhY2Nlc3NlZCwgaW5zdGFuY2VzIG11c3QgYmUgdHJlYXRlZCBsaWtlIGEgcHJpdmF0ZSBrZXkuCisgKgorICogQHNlZSBQcml2YXRlS2V5CisgKiBAc2VlIFB1YmxpY0tleQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgS2V5UGFpciBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNzU2NTE4OTUwMjI2ODAwOTgzN0w7CisgICAgcHJpdmF0ZSBmaW5hbCBQcml2YXRlS2V5IHByaXZhdGVLZXk7CisgICAgcHJpdmF0ZSBmaW5hbCBQdWJsaWNLZXkgcHVibGljS2V5OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgS2V5UGFpcn0gd2l0aCBhIHB1YmxpYyBrZXkgYW5kIHRoZQorICAgICAqIGNvcnJlc3BvbmRpbmcgcHJpdmF0ZSBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHVibGljS2V5CisgICAgICogICAgICAgICAgICB0aGUgcHVibGljIGtleS4KKyAgICAgKiBAcGFyYW0gcHJpdmF0ZUtleQorICAgICAqICAgICAgICAgICAgdGhlIHByaXZhdGUga2V5LgorICAgICAqLworICAgIHB1YmxpYyBLZXlQYWlyKFB1YmxpY0tleSBwdWJsaWNLZXksIFByaXZhdGVLZXkgcHJpdmF0ZUtleSkgeworICAgICAgICB0aGlzLnByaXZhdGVLZXkgPSBwcml2YXRlS2V5OworICAgICAgICB0aGlzLnB1YmxpY0tleSA9IHB1YmxpY0tleTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcml2YXRlIGtleS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByaXZhdGUga2V5LgorICAgICAqLworICAgIHB1YmxpYyBQcml2YXRlS2V5IGdldFByaXZhdGUoKSB7CisgICAgICAgIHJldHVybiBwcml2YXRlS2V5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHB1YmxpYyBrZXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwdWJsaWMga2V5LgorICAgICAqLworICAgIHB1YmxpYyBQdWJsaWNLZXkgZ2V0UHVibGljKCkgeworICAgICAgICByZXR1cm4gcHVibGljS2V5OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0tleVBhaXJHZW5lcmF0b3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0tleVBhaXJHZW5lcmF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNTg1MWZhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvS2V5UGFpckdlbmVyYXRvci5qYXZhCkBAIC0wLDAgKzEsMjg4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuZm9ydHJlc3MuRW5naW5lOworCisKKy8qKgorICoge0Bjb2RlIEtleVBhaXJHZW5lcmF0b3J9IGlzIGFuIGVuZ2luZSBjbGFzcyB3aGljaCBpcyBjYXBhYmxlIG9mIGdlbmVyYXRpbmcgYQorICogcHJpdmF0ZSBrZXkgYW5kIGl0cyByZWxhdGVkIHB1YmxpYyBrZXkgdXRpbGl6aW5nIHRoZSBhbGdvcml0aG0gaXQgd2FzCisgKiBpbml0aWFsaXplZCB3aXRoLgorICoKKyAqIEBzZWUgS2V5UGFpckdlbmVyYXRvclNwaQorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgS2V5UGFpckdlbmVyYXRvciBleHRlbmRzIEtleVBhaXJHZW5lcmF0b3JTcGkgeworCisgICAgLy8gU3RvcmUgS2V5UGFpckdlbmVyYXRvciBTRVJWSUNFIG5hbWUKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VSVklDRSA9ICJLZXlQYWlyR2VuZXJhdG9yIjsKKworICAgIC8vIFVzZWQgdG8gYWNjZXNzIGNvbW1vbiBlbmdpbmUgZnVuY3Rpb25hbGl0eQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEVuZ2luZSBFTkdJTkUgPSBuZXcgRW5naW5lKFNFUlZJQ0UpOworCisgICAgLy8gU3RvcmUgU2VjdXJlUmFuZG9tCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2VjdXJlUmFuZG9tIFJBTkRPTSA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKworICAgIC8vIFN0b3JlIHVzZWQgcHJvdmlkZXIKKyAgICBwcml2YXRlIFByb3ZpZGVyIHByb3ZpZGVyOworCisgICAgLy8gU3RvcmUgdXNlZCBhbGdvcml0aG0KKyAgICBwcml2YXRlIFN0cmluZyBhbGdvcml0aG07CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBLZXlQYWlyR2VuZXJhdG9yfSB3aXRoIHRoZSBuYW1lIG9mCisgICAgICogdGhlIGFsZ29yaXRobSB0byB1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiBhbGdvcml0aG0gdG8gdXNlCisgICAgICovCisgICAgcHJvdGVjdGVkIEtleVBhaXJHZW5lcmF0b3IoU3RyaW5nIGFsZ29yaXRobSkgeworICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0gb2YgdGhpcyB7QGNvZGUgS2V5UGFpckdlbmVyYXRvcn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0gb2YgdGhpcyB7QGNvZGUgS2V5UGFpckdlbmVyYXRvcn0KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgcmV0dXJuIGFsZ29yaXRobTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBLZXlQYWlyR2VuZXJhdG9yfSB0aGF0IHV0aWxpemVzIHRoZQorICAgICAqIHNwZWNpZmllZCBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtIHRvIHVzZQorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEtleVBhaXJHZW5lcmF0b3J9IHRoYXQgdXRpbGl6ZXMgdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgYWxnb3JpdGhtCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYWxnb3JpdGhtfSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEtleVBhaXJHZW5lcmF0b3IgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIEVuZ2luZS5TcGlBbmRQcm92aWRlciBzYXAgPSBFTkdJTkUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBudWxsKTsKKyAgICAgICAgT2JqZWN0IHNwaSA9IHNhcC5zcGk7CisgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyID0gc2FwLnByb3ZpZGVyOworICAgICAgICBpZiAoc3BpIGluc3RhbmNlb2YgS2V5UGFpckdlbmVyYXRvcikgeworICAgICAgICAgICAgS2V5UGFpckdlbmVyYXRvciByZXN1bHQgPSAoS2V5UGFpckdlbmVyYXRvcikgc3BpOworICAgICAgICAgICAgcmVzdWx0LmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICAgICAgICAgIHJlc3VsdC5wcm92aWRlciA9IHByb3ZpZGVyOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEtleVBhaXJHZW5lcmF0b3JJbXBsKChLZXlQYWlyR2VuZXJhdG9yU3BpKSBzcGksIHByb3ZpZGVyLCBhbGdvcml0aG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEtleVBhaXJHZW5lcmF0b3J9IHRoYXQgdXRpbGl6ZXMgdGhlCisgICAgICogc3BlY2lmaWVkIGFsZ29yaXRobSBmcm9tIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtIHRvIHVzZQorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgS2V5UGFpckdlbmVyYXRvcn0gdGhhdCB1dGlsaXplcyB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBhbGdvcml0aG0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZQorICAgICAqIEB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBpcyBub3QgYXZhaWxhYmxlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhbGdvcml0aG19IGlzIHtAY29kZSBudWxsfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBwcm92aWRlciA9PSBudWxsIHx8IHByb3ZpZGVyLmlzRW1wdHkoKX0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEtleVBhaXJHZW5lcmF0b3IgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCB8fCBwcm92aWRlci5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBpbXBQcm92aWRlciA9IFNlY3VyaXR5LmdldFByb3ZpZGVyKHByb3ZpZGVyKTsKKyAgICAgICAgaWYgKGltcFByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbihwcm92aWRlcik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEluc3RhbmNlKGFsZ29yaXRobSwgaW1wUHJvdmlkZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEtleVBhaXJHZW5lcmF0b3J9IHRoYXQgdXRpbGl6ZXMgdGhlCisgICAgICogc3BlY2lmaWVkIGFsZ29yaXRobSBmcm9tIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtIHRvIHVzZQorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHByb3ZpZGVyCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgS2V5UGFpckdlbmVyYXRvcn0gdGhhdCB1dGlsaXplcyB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBhbGdvcml0aG0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYWxnb3JpdGhtfSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgcHJvdmlkZXIgPT0gbnVsbH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEtleVBhaXJHZW5lcmF0b3IgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwKKyAgICAgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIE9iamVjdCBzcGkgPSBFTkdJTkUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBwcm92aWRlciwgbnVsbCk7CisgICAgICAgIGlmIChzcGkgaW5zdGFuY2VvZiBLZXlQYWlyR2VuZXJhdG9yKSB7CisgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIHJlc3VsdCA9IChLZXlQYWlyR2VuZXJhdG9yKSBzcGk7CisgICAgICAgICAgICByZXN1bHQuYWxnb3JpdGhtID0gYWxnb3JpdGhtOworICAgICAgICAgICAgcmVzdWx0LnByb3ZpZGVyID0gcHJvdmlkZXI7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgS2V5UGFpckdlbmVyYXRvckltcGwoKEtleVBhaXJHZW5lcmF0b3JTcGkpIHNwaSwgcHJvdmlkZXIsIGFsZ29yaXRobSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJvdmlkZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMge0Bjb2RlIEtleVBhaXJHZW5lcmF0b3J9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJvdmlkZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMge0Bjb2RlIEtleVBhaXJHZW5lcmF0b3J9CisgICAgICovCisgICAgcHVibGljIGZpbmFsIFByb3ZpZGVyIGdldFByb3ZpZGVyKCkgeworICAgICAgICByZXR1cm4gcHJvdmlkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyB7QGNvZGUgS2V5UGFpckdlbmVyYXRvcn0gd2l0aCB0aGUgZ2l2ZW4ga2V5IHNpemUuIFRoZQorICAgICAqIGRlZmF1bHQgcGFyYW1ldGVyIHNldCBhbmQgYSBkZWZhdWx0IHtAY29kZSBTZWN1cmVSYW5kb219IGluc3RhbmNlIHdpbGwgYmUKKyAgICAgKiB1c2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGtleXNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaXplIG9mIHRoZSBrZXkgKG51bWJlciBvZiBiaXRzKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGluaXRpYWxpemUoaW50IGtleXNpemUpIHsKKyAgICAgICAgaW5pdGlhbGl6ZShrZXlzaXplLCBSQU5ET00pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEtleVBhaXJHZW5lcmF0b3J9IHdpdGggdGhlIGdpdmVuIHtAY29kZQorICAgICAqIEFsZ29yaXRobVBhcmFtZXRlclNwZWN9LiBBIGRlZmF1bHQge0Bjb2RlIFNlY3VyZVJhbmRvbX0gaW5zdGFuY2Ugd2lsbCBiZQorICAgICAqIHVzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXJzIHRvIHVzZQorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycyBhcmUgbm90IHN1cHBvcnRlZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGluaXRpYWxpemUoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaW5pdGlhbGl6ZShwYXJhbSwgUkFORE9NKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlcyBhbmQgcmV0dXJucyBhIG5ldyB1bmlxdWUge0Bjb2RlIEtleVBhaXJ9IGVhY2ggdGltZSB0aGlzIG1ldGhvZAorICAgICAqIGlzIGNhbGxlZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIGRvZXMgZXhhY3RseSB0aGUgc2FtZSBhcyB7QGxpbmsgI2dlbmVyYXRlS2V5UGFpcigpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBuZXcgdW5pcXVlIHtAY29kZSBLZXlQYWlyfSBlYWNoIHRpbWUgdGhpcyBtZXRob2QgaXMgY2FsbGVkCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEtleVBhaXIgZ2VuS2V5UGFpcigpIHsKKyAgICAgICAgcmV0dXJuIGdlbmVyYXRlS2V5UGFpcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGVzIGFuZCByZXR1cm5zIGEgbmV3IHVuaXF1ZSB7QGNvZGUgS2V5UGFpcn0gZWFjaCB0aW1lIHRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgZG9lcyBleGFjdGx5IHRoZSBzYW1lIGFzIHtAbGluayAjZ2VuS2V5UGFpcigpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBuZXcgdW5pcXVlIHtAY29kZSBLZXlQYWlyfSBlYWNoIHRpbWUgdGhpcyBtZXRob2QgaXMgY2FsbGVkCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEtleVBhaXIgZ2VuZXJhdGVLZXlQYWlyKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBLZXlQYWlyR2VuZXJhdG9yfSB3aXRoIHRoZSBnaXZlbiBrZXkgc2l6ZSBhbmQgdGhlCisgICAgICogZ2l2ZW4ge0Bjb2RlIFNlY3VyZVJhbmRvbX0uIFRoZSBkZWZhdWx0IHBhcmFtZXRlciBzZXQgd2lsbCBiZSB1c2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGtleXNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgc2l6ZQorICAgICAqIEBwYXJhbSByYW5kb20KKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2Ugb2YgcmFuZG9tbmVzcworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGluaXRpYWxpemUoaW50IGtleXNpemUsIFNlY3VyZVJhbmRvbSByYW5kb20pIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBLZXlQYWlyR2VuZXJhdG9yfSB3aXRoIHRoZSBnaXZlbiB7QGNvZGUKKyAgICAgKiBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjfSBhbmQgdGhlIGdpdmVuIHtAY29kZSBTZWN1cmVSYW5kb219LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVycyB0byB1c2UKKyAgICAgKiBAcGFyYW0gcmFuZG9tCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIG9mIHJhbmRvbW5lc3MKKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMgYXJlIG5vdCBzdXBwb3J0ZWQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBpbml0aWFsaXplKEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW0sIFNlY3VyZVJhbmRvbSByYW5kb20pCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgfQorCisgICAgLyoqCisgICAgICoKKyAgICAgKiBJbnRlcm5hbCBjbGFzczogS2V5UGFpckdlbmVyYXRvciBpbXBsZW1lbnRhdGlvbgorICAgICAqCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgS2V5UGFpckdlbmVyYXRvckltcGwgZXh0ZW5kcyBLZXlQYWlyR2VuZXJhdG9yIHsKKyAgICAgICAgLy8gU2F2ZSBLZXlQYWlyR2VuZXJhdG9yU3BpCisgICAgICAgIHByaXZhdGUgS2V5UGFpckdlbmVyYXRvclNwaSBzcGlJbXBsOworCisgICAgICAgIHByaXZhdGUgS2V5UGFpckdlbmVyYXRvckltcGwoS2V5UGFpckdlbmVyYXRvclNwaSBrZXlQYWlyR2VuZXJhdG9yU3BpLAorICAgICAgICAgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyLCBTdHJpbmcgYWxnb3JpdGhtKSB7CisgICAgICAgICAgICBzdXBlcihhbGdvcml0aG0pOworICAgICAgICAgICAgc3VwZXIucHJvdmlkZXIgPSBwcm92aWRlcjsKKyAgICAgICAgICAgIHNwaUltcGwgPSBrZXlQYWlyR2VuZXJhdG9yU3BpOworICAgICAgICB9CisKKyAgICAgICAgLy8gaW1wbGVtZW50YXRpb24gb2YgaW5pdGlhbGl6ZShpbnQga2V5c2l6ZSwgU2VjdXJlUmFuZG9tIHJhbmRvbSkKKyAgICAgICAgLy8gdXNpbmcgY29ycmVzcG9uZGluZyBzcGkgaW5pdGlhbGl6ZSgpIG1ldGhvZAorICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgaW5pdGlhbGl6ZShpbnQga2V5c2l6ZSwgU2VjdXJlUmFuZG9tIHJhbmRvbSkgeworICAgICAgICAgICAgc3BpSW1wbC5pbml0aWFsaXplKGtleXNpemUsIHJhbmRvbSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBpbXBsZW1lbnRhdGlvbiBvZiBnZW5lcmF0ZUtleVBhaXIoKQorICAgICAgICAvLyB1c2luZyBjb3JyZXNwb25kaW5nIHNwaSBnZW5lcmF0ZUtleVBhaXIoKSBtZXRob2QKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBLZXlQYWlyIGdlbmVyYXRlS2V5UGFpcigpIHsKKyAgICAgICAgICAgIHJldHVybiBzcGlJbXBsLmdlbmVyYXRlS2V5UGFpcigpOworICAgICAgICB9CisKKyAgICAgICAgLy8gaW1wbGVtZW50YXRpb24gb2YgaW5pdGlhbGl6ZShpbnQga2V5c2l6ZSwgU2VjdXJlUmFuZG9tIHJhbmRvbSkKKyAgICAgICAgLy8gdXNpbmcgY29ycmVzcG9uZGluZyBzcGkgaW5pdGlhbGl6ZSgpIG1ldGhvZAorICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgaW5pdGlhbGl6ZShBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtLCBTZWN1cmVSYW5kb20gcmFuZG9tKQorICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHNwaUltcGwuaW5pdGlhbGl6ZShwYXJhbSwgcmFuZG9tKTsKKyAgICAgICAgfQorCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9LZXlQYWlyR2VuZXJhdG9yU3BpLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9LZXlQYWlyR2VuZXJhdG9yU3BpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTIxNjFjNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0tleVBhaXJHZW5lcmF0b3JTcGkuamF2YQpAQCAtMCwwICsxLDY5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKKworLyoqCisgKiB7QGNvZGUgS2V5UGFpckdlbmVyYXRvclNwaX0gaXMgdGhlIFNlcnZpY2UgUHJvdmlkZXIgSW50ZXJmYWNlIChTUEkpCisgKiBkZWZpbml0aW9uIGZvciB7QGxpbmsgS2V5UGFpckdlbmVyYXRvcn0uCisgKgorICogQHNlZSBLZXlQYWlyR2VuZXJhdG9yCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBLZXlQYWlyR2VuZXJhdG9yU3BpIHsKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBLZXlQYWlyR2VuZXJhdG9yU3BpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgS2V5UGFpckdlbmVyYXRvclNwaSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlcyBhbmQgcmV0dXJucyBhIG5ldyB1bmlxdWUge0Bjb2RlIEtleVBhaXJ9IGVhY2ggdGltZSB0aGlzIG1ldGhvZAorICAgICAqIGlzIGNhbGxlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBuZXcgdW5pcXVlIHtAY29kZSBLZXlQYWlyfSBlYWNoIHRpbWUgdGhpcyBtZXRob2QgaXMgY2FsbGVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBLZXlQYWlyIGdlbmVyYXRlS2V5UGFpcigpOworCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyB7QGNvZGUgS2V5UGFpckdlbmVyYXRvclNwaX0gd2l0aCB0aGUgZ2l2ZW4ga2V5IHNpemUgYW5kCisgICAgICogdGhlIGdpdmVuIHtAY29kZSBTZWN1cmVSYW5kb219LiBUaGUgZGVmYXVsdCBwYXJhbWV0ZXIgc2V0IHdpbGwgYmUgdXNlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXlzaXplCisgICAgICogICAgICAgICAgICB0aGUga2V5IHNpemUgKG51bWJlciBvZiBiaXRzKS4KKyAgICAgKiBAcGFyYW0gcmFuZG9tCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIG9mIHJhbmRvbW5lc3MuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgaW5pdGlhbGl6ZShpbnQga2V5c2l6ZSwgU2VjdXJlUmFuZG9tIHJhbmRvbSk7CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBLZXlQYWlyR2VuZXJhdG9yU3BpfSB3aXRoIHRoZSBnaXZlbiB7QGNvZGUKKyAgICAgKiBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjfSBhbmQgdGhlIGdpdmVuIHtAY29kZSBTZWN1cmVSYW5kb219LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlcnMgdG8gdXNlLgorICAgICAqIEBwYXJhbSByYW5kb20KKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2Ugb2YgcmFuZG9tbmVzcy4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMgYXJlIG5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgaW5pdGlhbGl6ZShBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtcywgU2VjdXJlUmFuZG9tIHJhbmRvbSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvS2V5UmVwLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9LZXlSZXAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYzViNzJlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvS2V5UmVwLmphdmEKQEAgLTAsMCArMSwxNzEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5Ob3RTZXJpYWxpemFibGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuSW52YWxpZEtleVNwZWNFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLlBLQ1M4RW5jb2RlZEtleVNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLlg1MDlFbmNvZGVkS2V5U3BlYzsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5TZWNyZXRLZXlTcGVjOworCisvKioKKyAqIHtAY29kZSBLZXlSZXB9IGlzIGEgc3RhbmRhcmRpemVkIHJlcHJlc2VudGF0aW9uIGZvciBzZXJpYWxpemVkIHtAbGluayBLZXl9CisgKiBvYmplY3RzLgorICovCitwdWJsaWMgY2xhc3MgS2V5UmVwIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00NzU3NjgzODk4ODMwNjQxODUzTDsKKyAgICAvLyBLZXkgdHlwZQorICAgIHByaXZhdGUgZmluYWwgVHlwZSB0eXBlOworICAgIC8vIEtleSBhbGdvcml0aG0gbmFtZQorICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGFsZ29yaXRobTsKKyAgICAvLyBLZXkgZW5jb2RpbmcgZm9ybWF0CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZm9ybWF0OworICAgIC8vIEtleSBlbmNvZGluZworICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kZWQ7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBLZXlSZXB9IHdpdGggdGhlIHNwZWNpZmllZCBhcmd1bWVudHMuCisgICAgICogVGhlIGFyZ3VtZW50cyBzaG91bGQgYmUgb2J0YWluZWQgZnJvbSB0aGUge0Bjb2RlIEtleX0gb2JqZWN0IHRoYXQgaGFzIHRvCisgICAgICogYmUgc2VyaWFsaXplZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUga2V5LgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGdvcml0aG0gKG9idGFpbmVkIGJ5IHtAbGluayBLZXkjZ2V0QWxnb3JpdGhtKCl9KS4KKyAgICAgKiBAcGFyYW0gZm9ybWF0CisgICAgICogICAgICAgICAgICB0aGUgZm9ybWF0IG9mIHRoZSBrZXkgKG9idGFpbmVkIGJ5IHtAbGluayBLZXkjZ2V0Rm9ybWF0KCl9KS4KKyAgICAgKiBAcGFyYW0gZW5jb2RlZAorICAgICAqICAgICAgICAgICAgdGhlIGVuY29kZWQge0Bjb2RlIGJ5dGVbXX0gKG9idGFpbmVkIGJ5CisgICAgICogICAgICAgICAgICB7QGxpbmsgS2V5I2dldEVuY29kZWQoKX0pLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgdHlwZSwgYWxnb3JpdGhtLCBmb3JtYXQgb3IgZW5jb2RlZH0gaXMge0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICAgICAgLgorICAgICAqLworICAgIHB1YmxpYyBLZXlSZXAoVHlwZSB0eXBlLCBTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgZm9ybWF0LCBieXRlW10gZW5jb2RlZCkgeworICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICAgICAgdGhpcy5mb3JtYXQgPSBmb3JtYXQ7CisgICAgICAgIHRoaXMuZW5jb2RlZCA9IGVuY29kZWQ7CisgICAgICAgIGlmKHRoaXMudHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInR5cGUgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmKHRoaXMuYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiYWxnb3JpdGhtID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZih0aGlzLmZvcm1hdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImZvcm1hdCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYodGhpcy5lbmNvZGVkID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiZW5jb2RlZCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNvbHZlcyBhbmQgcmV0dXJucyB0aGUge0Bjb2RlIEtleX0gb2JqZWN0LiBUaHJlZSB7QGxpbmsgVHlwZX18Zm9ybWF0CisgICAgICogY29tYmluYXRpb25zIGFyZSBzdXBwb3J0ZWQ6CisgICAgICogPHVsPgorICAgICAqIDxsaT4ge0Bjb2RlIFR5cGUuUFJJVkFURX0gfCAiUEtDUyM4IiA6IHJldHVybnMgYSB7QGxpbmsgUHJpdmF0ZUtleX0KKyAgICAgKiBpbnN0YW5jZSwgZ2VuZXJhdGVkIGZyb20gYSBrZXkgZmFjdG9yeSAoc3VpdGFibGUgZm9yIHRoZSBhbGdvcml0aG0pIHRoYXQKKyAgICAgKiBpcyBpbml0aWFsaXplZCB3aXRoIGEge0BsaW5rIFBLQ1M4RW5jb2RlZEtleVNwZWN9IHVzaW5nIHRoZSBlbmNvZGVkIGtleQorICAgICAqIGJ5dGVzLgorICAgICAqIDxsaT4ge0Bjb2RlIFR5cGUuU0VDUkVUfSB8ICJSQVciIDogcmV0dXJucyBhIHtAbGluayBTZWNyZXRLZXlTcGVjfQorICAgICAqIGluc3RhbmNlLCBjcmVhdGVkIHdpdGggdGhlIGVuY29kZWQga2V5IGJ5dGVzIGFuZCB0aGUgYWxnb3JpdGhtLgorICAgICAqIDxsaT4ge0Bjb2RlIFR5cGUuUFVCTElDfSB8ICJYLjUwOSI6IHJldHVybnMgYSB7QGxpbmsgUHVibGljS2V5fSBpbnN0YW5jZSwKKyAgICAgKiBnZW5lcmF0ZWQgZnJvbSBhIGtleSBmYWN0b3J5IChzdWl0YWJsZSBmb3IgdGhlIGFsZ29yaXRobSkgdGhhdCBpcworICAgICAqIGluaXRpYWxpemVkIHdpdGggYSB7QGxpbmsgWDUwOUVuY29kZWRLZXlTcGVjfSB1c2luZyB0aGUgZW5jb2RlZCBrZXkKKyAgICAgKiBieXRlcy4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVzb2x2ZWQge0Bjb2RlIEtleX0gb2JqZWN0LgorICAgICAqIEB0aHJvd3MgT2JqZWN0U3RyZWFtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBUeXBlfXxmb3JtYXQgY29tYmluYXRpb24gaXMgbm90IHJlY29nbml6ZWQsIG9yCisgICAgICogICAgICAgICAgICAgdGhlIHJlc29sdXRpb24gb2YgYW55IGtleSBwYXJhbWV0ZXIgZmFpbHMuCisgICAgICovCisgICAgcHJvdGVjdGVkIE9iamVjdCByZWFkUmVzb2x2ZSgpIHRocm93cyBPYmplY3RTdHJlYW1FeGNlcHRpb24geworICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgICAgY2FzZSBTRUNSRVQ6CisgICAgICAgICAgICBpZiAoIlJBVyIuZXF1YWxzKGZvcm1hdCkpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNlY3JldEtleVNwZWMoZW5jb2RlZCwgYWxnb3JpdGhtKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uKCJDb3VsZCBub3QgY3JlYXRlIFNlY3JldEtleVNwZWM6ICIgKyBlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aHJvdyBuZXcgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uKCJ1bnJlY29nbml6ZWQgdHlwZS9mb3JtYXQgY29tYmluYXRpb246ICIgKyB0eXBlICsgIi8iICsgZm9ybWF0KTsKKyAgICAgICAgY2FzZSBQVUJMSUM6CisgICAgICAgICAgICBpZiAoIlguNTA5Ii5lcXVhbHMoZm9ybWF0KSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIEtleUZhY3Rvcnkga2YgPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBrZi5nZW5lcmF0ZVB1YmxpYyhuZXcgWDUwOUVuY29kZWRLZXlTcGVjKGVuY29kZWQpKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uKCJDb3VsZCBub3QgcmVzb2x2ZSBrZXk6ICIgKyBlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY2F0Y2ggKEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbigiQ291bGQgbm90IHJlc29sdmUga2V5OiAiICsgZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IE5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbigidW5yZWNvZ25pemVkIHR5cGUvZm9ybWF0IGNvbWJpbmF0aW9uOiAiICsgdHlwZSArICIvIiArIGZvcm1hdCk7CisgICAgICAgIGNhc2UgUFJJVkFURToKKyAgICAgICAgICAgIGlmICgiUEtDUyM4Ii5lcXVhbHMoZm9ybWF0KSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIEtleUZhY3Rvcnkga2YgPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBrZi5nZW5lcmF0ZVByaXZhdGUobmV3IFBLQ1M4RW5jb2RlZEtleVNwZWMoZW5jb2RlZCkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb3RTZXJpYWxpemFibGVFeGNlcHRpb24oIkNvdWxkIG5vdCByZXNvbHZlIGtleTogIiArIGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjYXRjaCAoSW52YWxpZEtleVNwZWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uKCJDb3VsZCBub3QgcmVzb2x2ZSBrZXk6ICIgKyBlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aHJvdyBuZXcgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uKCJ1bnJlY29nbml6ZWQgdHlwZS9mb3JtYXQgY29tYmluYXRpb246ICIgKyB0eXBlICsgIi8iICsgZm9ybWF0KTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uKCJ1bnJlY29nbml6ZWQga2V5IHR5cGU6ICIgKyB0eXBlKTsKKyAgICB9CisKKyAgICAvLyBNYWtlcyBkZWZlbnNpdmUgY29weSBvZiBrZXkgZW5jb2RpbmcKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpcykKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgaXMuZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgYnl0ZVtdIG5ld19lbmNvZGVkID0gbmV3IGJ5dGVbZW5jb2RlZC5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVuY29kZWQsIDAsIG5ld19lbmNvZGVkLCAwLCBuZXdfZW5jb2RlZC5sZW5ndGgpOworICAgICAgICBlbmNvZGVkID0gbmV3X2VuY29kZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bjb2RlIFR5cGV9IGVudW1lcmF0ZXMgdGhlIHN1cHBvcnRlZCBrZXkgdHlwZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBlbnVtIFR5cGUgeworICAgICAgICAvKioKKyAgICAgICAgICogVHlwZSBmb3Igc2VjcmV0IGtleXMuCisgICAgICAgICAqLworICAgICAgICBTRUNSRVQsCisgICAgICAgIC8qKgorICAgICAgICAgKiBUeXBlIGZvciBwdWJsaWMga2V5cy4KKyAgICAgICAgICovCisgICAgICAgIFBVQkxJQywKKyAgICAgICAgLyoqCisgICAgICAgICAqIFR5cGUgZm9yIHByaXZhdGUga2V5cy4KKyAgICAgICAgICovCisgICAgICAgIFBSSVZBVEUKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9LZXlTdG9yZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvS2V5U3RvcmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMjMzYTViCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvS2V5U3RvcmUuamF2YQpAQCAtMCwwICsxLDEzODcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmF4LmNyeXB0by5TZWNyZXRLZXk7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC5EZXN0cm95RmFpbGVkRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGguRGVzdHJveWFibGU7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC5jYWxsYmFjay5DYWxsYmFja0hhbmRsZXI7CitpbXBvcnQgbGliY29yZS5pby5Jb1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5mb3J0cmVzcy5FbmdpbmU7CisKKy8qKgorICoge0Bjb2RlIEtleVN0b3JlfSBpcyByZXNwb25zaWJsZSBmb3IgbWFpbnRhaW5pbmcgY3J5cHRvZ3JhcGhpYyBrZXlzIGFuZCB0aGVpcgorICogb3duZXJzLgorICogPHA+CisgKiBUaGUgdHlwZSBvZiB0aGUgc3lzdGVtIGtleSBzdG9yZSBjYW4gYmUgY2hhbmdlZCBieSBzZXR0aW5nIHRoZSB7QGNvZGUKKyAqICdrZXlzdG9yZS50eXBlJ30gcHJvcGVydHkgaW4gdGhlIGZpbGUgbmFtZWQge0Bjb2RlCisgKiBKQVZBX0hPTUUvbGliL3NlY3VyaXR5L2phdmEuc2VjdXJpdHl9LgorICoKKyAqIEBzZWUgQ2VydGlmaWNhdGUKKyAqIEBzZWUgUHJpdmF0ZUtleQorICovCitwdWJsaWMgY2xhc3MgS2V5U3RvcmUgeworCisgICAgLy8gU3RvcmUgS2V5U3RvcmUgU0VSVklDRSBuYW1lCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNFUlZJQ0UgPSAiS2V5U3RvcmUiOworCisgICAgLy8gVXNlZCB0byBhY2Nlc3MgY29tbW9uIGVuZ2luZSBmdW5jdGlvbmFsaXR5CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRW5naW5lIEVOR0lORSA9IG5ldyBFbmdpbmUoU0VSVklDRSk7CisKKyAgICAvLyAgU3RvcmUgS2V5U3RvcmUgcHJvcGVydHkgbmFtZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QRVJUWU5BTUUgPSAia2V5c3RvcmUudHlwZSI7CisKKyAgICAvLyAgU3RvcmUgZGVmYXVsdCBLZXlTdG9yZSB0eXBlCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfS0VZU1RPUkVfVFlQRSA9ICJqa3MiOworCisgICAgLy8gU3RvcmUgS2V5U3RvcmUgc3RhdGUgKGluaXRpYWxpemVkIG9yIG5vdCkKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNJbml0OworCisgICAgLy8gU3RvcmUgdXNlZCBLZXlTdG9yZVNwaQorICAgIHByaXZhdGUgZmluYWwgS2V5U3RvcmVTcGkgaW1wbFNwaTsKKworICAgIC8vIFN0b3JlIHVzZWQgcHJvdmlkZXIKKyAgICBwcml2YXRlIGZpbmFsIFByb3ZpZGVyIHByb3ZpZGVyOworCisgICAgLy8gU3RvcmUgdXNlZCB0eXBlCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgdHlwZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEtleVN0b3JlfSB3aXRoIHRoZSBnaXZlbiBhcmd1bWVudHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5U3RvcmVTcGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb25jcmV0ZSBrZXkgc3RvcmUuCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgcHJvdmlkZXIuCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSB7QGNvZGUgS2V5U3RvcmV9IHRvIGJlIGNvbnN0cnVjdGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBLZXlTdG9yZShLZXlTdG9yZVNwaSBrZXlTdG9yZVNwaSwgUHJvdmlkZXIgcHJvdmlkZXIsIFN0cmluZyB0eXBlKSB7CisgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgICAgIHRoaXMucHJvdmlkZXIgPSBwcm92aWRlcjsKKyAgICAgICAgdGhpcy5pbXBsU3BpID0ga2V5U3RvcmVTcGk7CisgICAgICAgIGlzSW5pdCA9IGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRocm93cyB0aGUgc3RhbmRhcmQgImtleXN0b3JlIG5vdCBpbml0aWFsaXplZCIgZXhjZXB0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdGhyb3dOb3RJbml0aWFsaXplZCgpIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBLZXlTdG9yZUV4Y2VwdGlvbigiS2V5U3RvcmUgd2FzIG5vdCBpbml0aWFsaXplZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEtleVN0b3JlfSB3aXRoIHRoZSBzcGVjaWZpZWQgdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgcmV0dXJuZWQge0Bjb2RlIEtleVN0b3JlfS4KKyAgICAgKiBAcmV0dXJuIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBLZXlTdG9yZX0gd2l0aCB0aGUgc3BlY2lmaWVkIHR5cGUuCisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycmVkIGR1cmluZyB0aGUgY3JlYXRpb24gb2YgdGhlIG5ldyB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBLZXlTdG9yZX0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgdHlwZSA9PSBudWxsfQorICAgICAqIEBzZWUgI2dldERlZmF1bHRUeXBlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBLZXlTdG9yZSBnZXRJbnN0YW5jZShTdHJpbmcgdHlwZSkgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHR5cGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVuZ2luZS5TcGlBbmRQcm92aWRlciBzYXAgPSBFTkdJTkUuZ2V0SW5zdGFuY2UodHlwZSwgbnVsbCk7CisgICAgICAgICAgICByZXR1cm4gbmV3IEtleVN0b3JlKChLZXlTdG9yZVNwaSkgc2FwLnNwaSwgc2FwLnByb3ZpZGVyLCB0eXBlKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBLZXlTdG9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEtleVN0b3JlfSBmcm9tIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIKKyAgICAgKiB3aXRoIHRoZSBnaXZlbiB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSByZXR1cm5lZCB7QGNvZGUgS2V5U3RvcmV9LgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgbmFtZSBvZiB0aGUgcHJvdmlkZXIgb2YgdGhlIHtAY29kZSBLZXlTdG9yZX0uCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgS2V5U3RvcmV9IGZyb20gdGhlIHNwZWNpZmllZCBwcm92aWRlcgorICAgICAqICAgICAgICAgd2l0aCB0aGUgZ2l2ZW4gdHlwZS4KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJyZWQgZHVyaW5nIHRoZSBjcmVhdGlvbiBvZiB0aGUgbmV3IHtAY29kZQorICAgICAqICAgICAgICAgICAgIEtleVN0b3JlfS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBwcm92aWRlciA9PSBudWxsIHx8IHByb3ZpZGVyLmlzRW1wdHkoKX0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHR5cGV9IGlzIHtAY29kZSBudWxsfSAoaW5zdGVhZCBvZgorICAgICAqICAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbikgYXMgaW4gMS40IHJlbGVhc2UKKyAgICAgKiBAc2VlICNnZXREZWZhdWx0VHlwZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgS2V5U3RvcmUgZ2V0SW5zdGFuY2UoU3RyaW5nIHR5cGUsIFN0cmluZyBwcm92aWRlcikKKyAgICAgICAgICAgIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCB8fCBwcm92aWRlci5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBpbXBQcm92aWRlciA9IFNlY3VyaXR5LmdldFByb3ZpZGVyKHByb3ZpZGVyKTsKKyAgICAgICAgaWYgKGltcFByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbihwcm92aWRlcik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBnZXRJbnN0YW5jZSh0eXBlLCBpbXBQcm92aWRlcik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgS2V5U3RvcmVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBLZXlTdG9yZX0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyCisgICAgICogd2l0aCB0aGUgZ2l2ZW4gdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgcmV0dXJuZWQge0Bjb2RlIEtleVN0b3JlfS4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm92aWRlciBvZiB0aGUge0Bjb2RlIEtleVN0b3JlfS4KKyAgICAgKiBAcmV0dXJuIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBLZXlTdG9yZX0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyCisgICAgICogICAgICAgICB3aXRoIHRoZSBnaXZlbiB0eXBlLgorICAgICAqIEB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnJlZCBkdXJpbmcgdGhlIGNyZWF0aW9uIG9mIHRoZSBuZXcge0Bjb2RlCisgICAgICogICAgICAgICAgICAgS2V5U3RvcmV9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHByb3ZpZGVyfSBpcyB7QGNvZGUgbnVsbH0gb3IgdGhlIGVtcHR5IHN0cmluZy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSB0eXBlID09IG51bGx9IChpbnN0ZWFkIG9mCisgICAgICogICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKSBhcyBpbiAxLjQgcmVsZWFzZQorICAgICAqIEBzZWUgI2dldERlZmF1bHRUeXBlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBLZXlTdG9yZSBnZXRJbnN0YW5jZShTdHJpbmcgdHlwZSwgUHJvdmlkZXIgcHJvdmlkZXIpIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIC8vIGNoZWNrIHBhcmFtZXRlcnMKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICAvLyByZXR1cm4gS2V5U3RvcmUgaW5zdGFuY2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE9iamVjdCBzcGkgPSBFTkdJTkUuZ2V0SW5zdGFuY2UodHlwZSwgcHJvdmlkZXIsIG51bGwpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBLZXlTdG9yZSgoS2V5U3RvcmVTcGkpIHNwaSwgcHJvdmlkZXIsIHR5cGUpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb3ZlcnJpZGUgZXhjZXB0aW9uCisgICAgICAgICAgICB0aHJvdyBuZXcgS2V5U3RvcmVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHR5cGUgZm9yIHtAY29kZSBLZXlTdG9yZX0gaW5zdGFuY2VzLgorICAgICAqCisgICAgICogPHA+VGhlIGRlZmF1bHQgaXMgc3BlY2lmaWVkIGluIHRoZSB7QGNvZGUgJ2tleXN0b3JlLnR5cGUnfSBwcm9wZXJ0eSBpbiB0aGUKKyAgICAgKiBmaWxlIG5hbWVkIHtAY29kZSBqYXZhLnNlY3VyaXR5fSBwcm9wZXJ0aWVzIGZpbGUuIElmIHRoaXMgcHJvcGVydHkKKyAgICAgKiBpcyBub3Qgc2V0LCB7QGNvZGUgImprcyJ9IHdpbGwgYmUgdXNlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGRlZmF1bHQgdHlwZSBmb3Ige0Bjb2RlIEtleVN0b3JlfSBpbnN0YW5jZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBnZXREZWZhdWx0VHlwZSgpIHsKKyAgICAgICAgU3RyaW5nIGR0ID0gU2VjdXJpdHkuZ2V0UHJvcGVydHkoUFJPUEVSVFlOQU1FKTsKKyAgICAgICAgcmV0dXJuIChkdCA9PSBudWxsID8gREVGQVVMVF9LRVlTVE9SRV9UWVBFIDogZHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByb3ZpZGVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHtAY29kZSBLZXlTdG9yZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcm92aWRlciBhc3NvY2lhdGVkIHdpdGggdGhpcyB7QGNvZGUgS2V5U3RvcmV9LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBQcm92aWRlciBnZXRQcm92aWRlcigpIHsKKyAgICAgICAgcmV0dXJuIHByb3ZpZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgdGhpcyB7QGNvZGUgS2V5U3RvcmV9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdHlwZSBvZiB0aGlzIHtAY29kZSBLZXlTdG9yZX0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRUeXBlKCkgeworICAgICAgICByZXR1cm4gdHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBrZXkgd2l0aCB0aGUgZ2l2ZW4gYWxpYXMsIHVzaW5nIHRoZSBwYXNzd29yZCB0byByZWNvdmVyIHRoZQorICAgICAqIGtleSBmcm9tIHRoZSBzdG9yZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGlhcworICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIGZvciB0aGUgZW50cnkuCisgICAgICogQHBhcmFtIHBhc3N3b3JkCisgICAgICogICAgICAgICAgICB0aGUgcGFzc3dvcmQgdXNlZCB0byByZWNvdmVyIHRoZSBrZXkuCisgICAgICogQHJldHVybiB0aGUga2V5IHdpdGggdGhlIHNwZWNpZmllZCBhbGlhcywgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIGFsaWFzIGlzIG5vdCBib3VuZCB0byBhbiBlbnRyeS4KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgS2V5U3RvcmV9IGlzIG5vdCBpbml0aWFsaXplZC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhbGdvcml0aG0gZm9yIHJlY292ZXJpbmcgdGhlIGtleSBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBrZXkgY2FuIG5vdCBiZSByZWNvdmVyZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEtleSBnZXRLZXkoU3RyaW5nIGFsaWFzLCBjaGFyW10gcGFzc3dvcmQpCisgICAgICAgICAgICB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24geworICAgICAgICBpZiAoIWlzSW5pdCkgeworICAgICAgICAgICAgdGhyb3dOb3RJbml0aWFsaXplZCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpbXBsU3BpLmVuZ2luZUdldEtleShhbGlhcywgcGFzc3dvcmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNlcnRpZmljYXRlIGNoYWluIGZvciB0aGUgZW50cnkgd2l0aCB0aGUgZ2l2ZW4gYWxpYXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxpYXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGlhcyBmb3IgdGhlIGVudHJ5LgorICAgICAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRlIGNoYWluIGZvciB0aGUgZW50cnkgd2l0aCB0aGUgZ2l2ZW4gYWxpYXMsIG9yCisgICAgICogICAgICAgICB7QGNvZGUgbnVsbH0gaWYgdGhlIHNwZWNpZmllZCBhbGlhcyBpcyBub3QgYm91bmQgdG8gYW4gZW50cnkuCisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIEtleVN0b3JlfSBpcyBub3QgaW5pdGlhbGl6ZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENlcnRpZmljYXRlW10gZ2V0Q2VydGlmaWNhdGVDaGFpbihTdHJpbmcgYWxpYXMpIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaXNJbml0KSB7CisgICAgICAgICAgICB0aHJvd05vdEluaXRpYWxpemVkKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGltcGxTcGkuZW5naW5lR2V0Q2VydGlmaWNhdGVDaGFpbihhbGlhcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdHJ1c3RlZCBjZXJ0aWZpY2F0ZSBmb3IgdGhlIGVudHJ5IHdpdGggdGhlIGdpdmVuIGFsaWFzLgorICAgICAqCisgICAgICogQHBhcmFtIGFsaWFzCisgICAgICogICAgICAgICAgICB0aGUgYWxpYXMgZm9yIHRoZSBlbnRyeS4KKyAgICAgKiBAcmV0dXJuIHRoZSB0cnVzdGVkIGNlcnRpZmljYXRlIGZvciB0aGUgZW50cnkgd2l0aCB0aGUgZ2l2ZW4gYWxpYXMsIG9yCisgICAgICogICAgICAgICB7QGNvZGUgbnVsbH0gaWYgdGhlIHNwZWNpZmllZCBhbGlhcyBpcyBub3QgYm91bmQgdG8gYW4gZW50cnkuCisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIEtleVN0b3JlfSBpcyBub3QgaW5pdGlhbGl6ZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENlcnRpZmljYXRlIGdldENlcnRpZmljYXRlKFN0cmluZyBhbGlhcykgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc0luaXQpIHsKKyAgICAgICAgICAgIHRocm93Tm90SW5pdGlhbGl6ZWQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW1wbFNwaS5lbmdpbmVHZXRDZXJ0aWZpY2F0ZShhbGlhcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3JlYXRpb24gZGF0ZSBvZiB0aGUgZW50cnkgd2l0aCB0aGUgZ2l2ZW4gYWxpYXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxpYXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGlhcyBmb3IgdGhlIGVudHJ5LgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0aW9uIGRhdGUsIG9yIHtAY29kZSBudWxsfSBpZiB0aGUgc3BlY2lmaWVkIGFsaWFzIGlzIG5vdAorICAgICAqICAgICAgICAgYm91bmQgdG8gYW4gZW50cnkuCisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIEtleVN0b3JlfSBpcyBub3QgaW5pdGlhbGl6ZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIERhdGUgZ2V0Q3JlYXRpb25EYXRlKFN0cmluZyBhbGlhcykgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc0luaXQpIHsKKyAgICAgICAgICAgIHRocm93Tm90SW5pdGlhbGl6ZWQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW1wbFNwaS5lbmdpbmVHZXRDcmVhdGlvbkRhdGUoYWxpYXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFzc29jaWF0ZXMgdGhlIGdpdmVuIGFsaWFzIHdpdGggdGhlIGtleSwgcGFzc3dvcmQgYW5kIGNlcnRpZmljYXRlIGNoYWluLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBzcGVjaWZpZWQgYWxpYXMgYWxyZWFkeSBleGlzdHMsIGl0IHdpbGwgYmUgcmVhc3NpZ25lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGlhcworICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIGZvciB0aGUga2V5LgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkuCisgICAgICogQHBhcmFtIHBhc3N3b3JkCisgICAgICogICAgICAgICAgICB0aGUgcGFzc3dvcmQuCisgICAgICogQHBhcmFtIGNoYWluCisgICAgICogICAgICAgICAgICB0aGUgY2VydGlmaWNhdGUgY2hhaW4uCisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIEtleVN0b3JlfSBpcyBub3QgaW5pdGlhbGl6ZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUga2V5fSBpcyBhIHtAY29kZSBQcml2YXRlS2V5fSBhbmQge0Bjb2RlIGNoYWlufSBkb2VzCisgICAgICogICAgICAgICAgICAgbm90IGNvbnRhaW4gYW55IGNlcnRpZmljYXRlcy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFsaWFzfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgc2V0S2V5RW50cnkoU3RyaW5nIGFsaWFzLCBLZXkga2V5LCBjaGFyW10gcGFzc3dvcmQsCisgICAgICAgICAgICBDZXJ0aWZpY2F0ZVtdIGNoYWluKSB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICBpZiAoIWlzSW5pdCkgeworICAgICAgICAgICAgdGhyb3dOb3RJbml0aWFsaXplZCgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ2VydGlmaWNhdGUgY2hhaW4gaXMgcmVxdWlyZWQgZm9yIFByaXZhdGVLZXkKKyAgICAgICAgaWYgKGtleSAhPSBudWxsICYmIGtleSBpbnN0YW5jZW9mIFByaXZhdGVLZXkgJiYgKGNoYWluID09IG51bGwgfHwgY2hhaW4ubGVuZ3RoID09IDApKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJDZXJ0aWZpY2F0ZSBjaGFpbiBpcyBub3QgZGVmaW5lZCBmb3IgUHJpdmF0ZSBrZXkiKTsKKyAgICAgICAgfQorICAgICAgICBpbXBsU3BpLmVuZ2luZVNldEtleUVudHJ5KGFsaWFzLCBrZXksIHBhc3N3b3JkLCBjaGFpbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzb2NpYXRlcyB0aGUgZ2l2ZW4gYWxpYXMgd2l0aCBhIGtleSBhbmQgYSBjZXJ0aWZpY2F0ZSBjaGFpbi4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgc3BlY2lmaWVkIGFsaWFzIGFscmVhZHkgZXhpc3RzLCBpdCB3aWxsIGJlIHJlYXNzaWduZWQuCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyB7QGNvZGUgS2V5U3RvcmV9IGlzIG9mIHR5cGUge0Bjb2RlICJqa3MifSwge0Bjb2RlIGtleX0gbXVzdCBiZQorICAgICAqIGVuY29kZWQgY29uZm9ybSB0byB0aGUgUEtTIzggc3RhbmRhcmQgYXMgYW4KKyAgICAgKiB7QGxpbmsgamF2YXguY3J5cHRvLkVuY3J5cHRlZFByaXZhdGVLZXlJbmZvfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGlhcworICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIGZvciB0aGUga2V5LgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgaW4gYW4gZW5jb2RlZCBmb3JtYXQuCisgICAgICogQHBhcmFtIGNoYWluCisgICAgICogICAgICAgICAgICB0aGUgY2VydGlmaWNhdGUgY2hhaW4uCisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIEtleVN0b3JlfSBpcyBub3QgaW5pdGlhbGl6ZWQgb3IgaWYge0Bjb2RlIGtleX0KKyAgICAgKiAgICAgICAgICAgICBpcyBudWxsLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGtleX0gaXMgYSB7QGNvZGUgUHJpdmF0ZUtleX0gYW5kIHtAY29kZSBjaGFpbn0KKyAgICAgKiAgICAgICAgICAgICBkb2VzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYWxpYXN9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRLZXlFbnRyeShTdHJpbmcgYWxpYXMsIGJ5dGVbXSBrZXksIENlcnRpZmljYXRlW10gY2hhaW4pCisgICAgICAgICAgICB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICBpZiAoIWlzSW5pdCkgeworICAgICAgICAgICAgdGhyb3dOb3RJbml0aWFsaXplZCgpOworICAgICAgICB9CisgICAgICAgIGltcGxTcGkuZW5naW5lU2V0S2V5RW50cnkoYWxpYXMsIGtleSwgY2hhaW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFzc29jaWF0ZXMgdGhlIGdpdmVuIGFsaWFzIHdpdGggYSBjZXJ0aWZpY2F0ZS4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgc3BlY2lmaWVkIGFsaWFzIGFscmVhZHkgZXhpc3RzLCBpdCB3aWxsIGJlIHJlYXNzaWduZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxpYXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGlhcyBmb3IgdGhlIGNlcnRpZmljYXRlLgorICAgICAqIEBwYXJhbSBjZXJ0CisgICAgICogICAgICAgICAgICB0aGUgY2VydGlmaWNhdGUuCisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIEtleVN0b3JlfSBpcyBub3QgaW5pdGlhbGl6ZWQsIG9yIGFuIGV4aXN0aW5nCisgICAgICogICAgICAgICAgICAgYWxpYXMgaXMgbm90IGFzc29jaWF0ZWQgdG8gYW4gZW50cnkgY29udGFpbmluZyBhIHRydXN0ZWQKKyAgICAgKiAgICAgICAgICAgICBjZXJ0aWZpY2F0ZSwgb3IgdGhpcyBtZXRob2QgZmFpbHMgZm9yIGFueSBvdGhlciByZWFzb24uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhbGlhc30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldENlcnRpZmljYXRlRW50cnkoU3RyaW5nIGFsaWFzLCBDZXJ0aWZpY2F0ZSBjZXJ0KSB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICBpZiAoIWlzSW5pdCkgeworICAgICAgICAgICAgdGhyb3dOb3RJbml0aWFsaXplZCgpOworICAgICAgICB9CisgICAgICAgIGltcGxTcGkuZW5naW5lU2V0Q2VydGlmaWNhdGVFbnRyeShhbGlhcywgY2VydCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVsZXRlcyB0aGUgZW50cnkgaWRlbnRpZmllZCB3aXRoIHRoZSBnaXZlbiBhbGlhcyBmcm9tIHRoaXMge0Bjb2RlCisgICAgICogS2V5U3RvcmV9LgorICAgICAqCisgICAgICogQHBhcmFtIGFsaWFzCisgICAgICogICAgICAgICAgICB0aGUgYWxpYXMgZm9yIHRoZSBlbnRyeS4KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgS2V5U3RvcmV9IGlzIG5vdCBpbml0aWFsaXplZCwgb3IgaWYgdGhlIGVudHJ5CisgICAgICogICAgICAgICAgICAgY2FuIG5vdCBiZSBkZWxldGVkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGRlbGV0ZUVudHJ5KFN0cmluZyBhbGlhcykgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc0luaXQpIHsKKyAgICAgICAgICAgIHRocm93Tm90SW5pdGlhbGl6ZWQoKTsKKyAgICAgICAgfQorICAgICAgICBpbXBsU3BpLmVuZ2luZURlbGV0ZUVudHJ5KGFsaWFzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIHtAY29kZSBFbnVtZXJhdGlvbn0gb3ZlciBhbGwgYWxpYXMgbmFtZXMgc3RvcmVkIGluIHRoaXMKKyAgICAgKiB7QGNvZGUgS2V5U3RvcmV9LgorICAgICAqCisgICAgICogQHJldHVybiBhbiB7QGNvZGUgRW51bWVyYXRpb259IG92ZXIgYWxsIGFsaWFzIG5hbWVzIHN0b3JlZCBpbiB0aGlzCisgICAgICogICAgICAgICB7QGNvZGUgS2V5U3RvcmV9LgorICAgICAqIEB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBLZXlTdG9yZX0gaXMgbm90IGluaXRpYWxpemVkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBFbnVtZXJhdGlvbjxTdHJpbmc+IGFsaWFzZXMoKSB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICBpZiAoIWlzSW5pdCkgeworICAgICAgICAgICAgdGhyb3dOb3RJbml0aWFsaXplZCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpbXBsU3BpLmVuZ2luZUFsaWFzZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgZ2l2ZW4gYWxpYXMgaXMgcHJlc2VudCBpbiB0aGlzIHtAY29kZSBLZXlTdG9yZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxpYXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGlhcyBvZiBhbiBlbnRyeS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgYWxpYXMgZXhpc3RzLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgS2V5U3RvcmV9IGlzIG5vdCBpbml0aWFsaXplZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBjb250YWluc0FsaWFzKFN0cmluZyBhbGlhcykgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc0luaXQpIHsKKyAgICAgICAgICAgIHRocm93Tm90SW5pdGlhbGl6ZWQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW1wbFNwaS5lbmdpbmVDb250YWluc0FsaWFzKGFsaWFzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZW50cmllcyBzdG9yZWQgaW4gdGhpcyB7QGNvZGUgS2V5U3RvcmV9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGVudHJpZXMgc3RvcmVkIGluIHRoaXMge0Bjb2RlIEtleVN0b3JlfS4KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgS2V5U3RvcmV9IGlzIG5vdCBpbml0aWFsaXplZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IHNpemUoKSB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICBpZiAoIWlzSW5pdCkgeworICAgICAgICAgICAgdGhyb3dOb3RJbml0aWFsaXplZCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpbXBsU3BpLmVuZ2luZVNpemUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGFsaWFzIGlzIGFzc29jaWF0ZWQgd2l0aCBlaXRoZXIgYQorICAgICAqIHtAbGluayBQcml2YXRlS2V5RW50cnl9IG9yIGEge0BsaW5rIFNlY3JldEtleUVudHJ5fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGlhcworICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIG9mIGFuIGVudHJ5LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBnaXZlbiBhbGlhcyBpcyBhc3NvY2lhdGVkIHdpdGggYSBrZXkgZW50cnkuCisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIEtleVN0b3JlfSBpcyBub3QgaW5pdGlhbGl6ZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNLZXlFbnRyeShTdHJpbmcgYWxpYXMpIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaXNJbml0KSB7CisgICAgICAgICAgICB0aHJvd05vdEluaXRpYWxpemVkKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGltcGxTcGkuZW5naW5lSXNLZXlFbnRyeShhbGlhcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBhbGlhcyBpcyBhc3NvY2lhdGVkIHdpdGggYQorICAgICAqIHtAbGluayBUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxpYXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGlhcyBvZiBhbiBlbnRyeS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZ2l2ZW4gYWxpYXMgaXMgYXNzb2NpYXRlZCB3aXRoIGEgY2VydGlmaWNhdGUKKyAgICAgKiAgICAgICAgIGVudHJ5LgorICAgICAqIEB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBLZXlTdG9yZX0gaXMgbm90IGluaXRpYWxpemVkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzQ2VydGlmaWNhdGVFbnRyeShTdHJpbmcgYWxpYXMpIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaXNJbml0KSB7CisgICAgICAgICAgICB0aHJvd05vdEluaXRpYWxpemVkKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGltcGxTcGkuZW5naW5lSXNDZXJ0aWZpY2F0ZUVudHJ5KGFsaWFzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhbGlhcyBhc3NvY2lhdGVkIHdpdGggdGhlIGZpcnN0IGVudHJ5IHdob3NlIGNlcnRpZmljYXRlCisgICAgICogbWF0Y2hlcyB0aGUgc3BlY2lmaWVkIGNlcnRpZmljYXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGNlcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZSB0byBmaW5kIHRoZSBhc3NvY2lhdGVkIGVudHJ5J3MgYWxpYXMgZm9yLgorICAgICAqIEByZXR1cm4gdGhlIGFsaWFzIG9yIHtAY29kZSBudWxsfSBpZiBubyBlbnRyeSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIGNlcnRpZmljYXRlIGNhbiBiZSBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgS2V5U3RvcmV9IGlzIG5vdCBpbml0aWFsaXplZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldENlcnRpZmljYXRlQWxpYXMoQ2VydGlmaWNhdGUgY2VydCkgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc0luaXQpIHsKKyAgICAgICAgICAgIHRocm93Tm90SW5pdGlhbGl6ZWQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW1wbFNwaS5lbmdpbmVHZXRDZXJ0aWZpY2F0ZUFsaWFzKGNlcnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGlzIHtAY29kZSBLZXlTdG9yZX0gdG8gdGhlIHNwZWNpZmllZCB7QGNvZGUgT3V0cHV0U3RyZWFtfS4gVGhlCisgICAgICogZGF0YSB3cml0dGVuIHRvIHRoZSB7QGNvZGUgT3V0cHV0U3RyZWFtfSBpcyBwcm90ZWN0ZWQgYnkgdGhlIHNwZWNpZmllZAorICAgICAqIHBhc3N3b3JkLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBPdXRwdXRTdHJlYW19IHRvIHdyaXRlIHRoZSBzdG9yZSdzIGRhdGEgdG8uCisgICAgICogQHBhcmFtIHBhc3N3b3JkCisgICAgICogICAgICAgICAgICB0aGUgcGFzc3dvcmQgdG8gcHJvdGVjdCB0aGUgZGF0YS4KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgS2V5U3RvcmV9IGlzIG5vdCBpbml0aWFsaXplZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycmVkIHdoaWxlIHdyaXRpbmcgdG8gdGhlIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSByZXF1aXJlZCBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXhjZXB0aW9uIG9jY3VycmVkIHdoaWxlIHN0b3JpbmcgdGhlIGNlcnRpZmljYXRlcyBvZgorICAgICAqICAgICAgICAgICAgIHRoaXMge0Bjb2RlIEtleVN0b3JlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBzdG9yZShPdXRwdXRTdHJlYW0gc3RyZWFtLCBjaGFyW10gcGFzc3dvcmQpCisgICAgICAgICAgICB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24sIElPRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc0luaXQpIHsKKyAgICAgICAgICAgIHRocm93Tm90SW5pdGlhbGl6ZWQoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vSnVzdCBkZWxlZ2F0ZSBzdHJlYW0gYW5kIHBhc3N3b3JkIHRvIGltcGxTcGkKKyAgICAgICAgaW1wbFNwaS5lbmdpbmVTdG9yZShzdHJlYW0sIHBhc3N3b3JkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdG9yZXMgdGhpcyB7QGNvZGUgS2V5U3RvcmV9IHVzaW5nIHRoZSBzcGVjaWZpZWQge0Bjb2RlCisgICAgICogTG9hZFN0b3JlUGFyYW1ldGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBMb2FkU3RvcmVQYXJhbWV0ZXJ9IHRoYXQgc3BlY2lmaWVzIGhvdyB0byBzdG9yZQorICAgICAqICAgICAgICAgICAgdGhpcyB7QGNvZGUgS2V5U3RvcmV9LCBtYXliZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIEtleVN0b3JlfSBpcyBub3QgaW5pdGlhbGl6ZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnJlZCB3aGlsZSB3cml0aW5nIHRvIHRoZSBzdHJlYW0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcmVxdWlyZWQgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGV4Y2VwdGlvbiBvY2N1cnJlZCB3aGlsZSBzdG9yaW5nIHRoZSBjZXJ0aWZpY2F0ZXMgb2YKKyAgICAgKiAgICAgICAgICAgICB0aGlzIHtAY29kZSBLZXlTdG9yZX0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2l2ZW4ge0BsaW5rIExvYWRTdG9yZVBhcmFtZXRlcn0gaXMgbm90IHJlY29nbml6ZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgc3RvcmUoTG9hZFN0b3JlUGFyYW1ldGVyIHBhcmFtKSB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24sCisgICAgICAgICAgICBJT0V4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaXNJbml0KSB7CisgICAgICAgICAgICB0aHJvd05vdEluaXRpYWxpemVkKCk7CisgICAgICAgIH0KKyAgICAgICAgaW1wbFNwaS5lbmdpbmVTdG9yZShwYXJhbSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyB7QGNvZGUgS2V5U3RvcmV9IGZyb20gdGhlIHByb3ZpZGVkIHtAY29kZSBJbnB1dFN0cmVhbX0uCisgICAgICogUGFzcyB7QGNvZGUgbnVsbH0gYXMgdGhlIHtAY29kZSBzdHJlYW19IGFyZ3VtZW50IHRvIGluaXRpYWxpemUgYW4gZW1wdHkKKyAgICAgKiB7QGNvZGUgS2V5U3RvcmV9IG9yIHRvIGluaXRpYWxpemUgYSB7QGNvZGUgS2V5U3RvcmV9IHdoaWNoIGRvZXMgbm90IHJlbHkKKyAgICAgKiBvbiBhbiB7QGNvZGUgSW5wdXRTdHJlYW19LiBUaGlzIHtAY29kZSBLZXlTdG9yZX0gdXRpbGl6ZXMgdGhlIGdpdmVuCisgICAgICogcGFzc3dvcmQgdG8gdmVyaWZ5IHRoZSBzdG9yZWQgZGF0YS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgSW5wdXRTdHJlYW19IHRvIGxvYWQgdGhpcyB7QGNvZGUgS2V5U3RvcmV9J3MgZGF0YQorICAgICAqICAgICAgICAgICAgZnJvbSBvciB7QGNvZGUgbnVsbH0uCisgICAgICogQHBhcmFtIHBhc3N3b3JkCisgICAgICogICAgICAgICAgICB0aGUgcGFzc3dvcmQgdG8gdmVyaWZ5IHRoZSBzdG9yZWQgZGF0YSwgbWF5YmUge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHByb2JsZW0gb2NjdXJyZWQgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzdHJlYW0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcmVxdWlyZWQgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGV4Y2VwdGlvbiBvY2N1cnJlZCB3aGlsZSBsb2FkaW5nIHRoZSBjZXJ0aWZpY2F0ZXMgb2YKKyAgICAgKiAgICAgICAgICAgICB0aGlzIHtAY29kZSBLZXlTdG9yZX0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgbG9hZChJbnB1dFN0cmVhbSBzdHJlYW0sIGNoYXJbXSBwYXNzd29yZCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGltcGxTcGkuZW5naW5lTG9hZChzdHJlYW0sIHBhc3N3b3JkKTsKKyAgICAgICAgaXNJbml0ID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2FkcyB0aGlzIHtAY29kZSBLZXlTdG9yZX0gdXNpbmcgdGhlIHNwZWNpZmllZCB7QGNvZGUKKyAgICAgKiBMb2FkU3RvcmVQYXJhbWV0ZXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIExvYWRTdG9yZVBhcmFtZXRlcn0gdGhhdCBzcGVjaWZpZXMgaG93IHRvIGxvYWQgdGhpcworICAgICAqICAgICAgICAgICAge0Bjb2RlIEtleVN0b3JlfSwgbWF5YmUge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHByb2JsZW0gb2NjdXJyZWQgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzdHJlYW0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcmVxdWlyZWQgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGV4Y2VwdGlvbiBvY2N1cnJlZCB3aGlsZSBsb2FkaW5nIHRoZSBjZXJ0aWZpY2F0ZXMgb2YKKyAgICAgKiAgICAgICAgICAgICB0aGlzIHtAY29kZSBLZXlTdG9yZX0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2l2ZW4ge0BsaW5rIExvYWRTdG9yZVBhcmFtZXRlcn0gaXMgbm90IHJlY29nbml6ZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgbG9hZChMb2FkU3RvcmVQYXJhbWV0ZXIgcGFyYW0pIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBpbXBsU3BpLmVuZ2luZUxvYWQocGFyYW0pOworICAgICAgICBpc0luaXQgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBFbnRyeX0gd2l0aCB0aGUgZ2l2ZW4gYWxpYXMsIHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB7QGNvZGUgUHJvdGVjdGlvblBhcmFtZXRlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxpYXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGlhcyBvZiB0aGUgcmVxdWVzdGVkIGVudHJ5LgorICAgICAqIEBwYXJhbSBwYXJhbQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBQcm90ZWN0aW9uUGFyYW1ldGVyfSB1c2VkIHRvIHByb3RlY3QgdGhlIHJlcXVlc3RlZAorICAgICAqICAgICAgICAgICAgZW50cnksIG1heWJlIHtAY29kZSBudWxsfS4KKyAgICAgKiBAcmV0dXJuIGhlIHtAY29kZSBFbnRyeX0gd2l0aCB0aGUgZ2l2ZW4gYWxpYXMsIHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIHtAY29kZSBQcm90ZWN0aW9uUGFyYW1ldGVyfS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSByZXF1aXJlZCBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgKiBAdGhyb3dzIFVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbnRyeSBjYW4gbm90IGJlIHJlY292ZXJlZC4KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgS2V5U3RvcmV9IGlzIG5vdCBpbml0aWFsaXplZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFsaWFzfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEVudHJ5IGdldEVudHJ5KFN0cmluZyBhbGlhcywgUHJvdGVjdGlvblBhcmFtZXRlciBwYXJhbSkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIFVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvbiwgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICBpZiAoYWxpYXMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJhbGlhcyA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFpc0luaXQpIHsKKyAgICAgICAgICAgIHRocm93Tm90SW5pdGlhbGl6ZWQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW1wbFNwaS5lbmdpbmVHZXRFbnRyeShhbGlhcywgcGFyYW0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0b3JlcyB0aGUgZ2l2ZW4ge0Bjb2RlIEVudHJ5fSBpbiB0aGlzIHtAY29kZSBLZXlTdG9yZX0gYW5kIGFzc29jaWF0ZXMKKyAgICAgKiB0aGUgZW50cnkgd2l0aCB0aGUgZ2l2ZW4ge0Bjb2RlIGFsaWFzfS4gVGhlIGVudHJ5IGlzIHByb3RlY3RlZCBieSB0aGUKKyAgICAgKiBzcGVjaWZpZWQge0Bjb2RlIFByb3RlY3Rpb25QYXJhbWV0ZXJ9LgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBzcGVjaWZpZWQgYWxpYXMgYWxyZWFkeSBleGlzdHMsIGl0IHdpbGwgYmUgcmVhc3NpZ25lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGlhcworICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIGZvciB0aGUgZW50cnkuCisgICAgICogQHBhcmFtIGVudHJ5CisgICAgICogICAgICAgICAgICB0aGUgZW50cnkgdG8gc3RvcmUuCisgICAgICogQHBhcmFtIHBhcmFtCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIFByb3RlY3Rpb25QYXJhbWV0ZXJ9IHRvIHByb3RlY3QgdGhlIGVudHJ5LgorICAgICAqIEB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBLZXlTdG9yZX0gaXMgbm90IGluaXRpYWxpemVkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYWxpYXN9IGlzIHtAY29kZSBudWxsfSBvciB7QGNvZGUgZW50cnl9IGlzIHtAY29kZQorICAgICAqICAgICAgICAgICAgIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldEVudHJ5KFN0cmluZyBhbGlhcywgRW50cnkgZW50cnksCisgICAgICAgICAgICBQcm90ZWN0aW9uUGFyYW1ldGVyIHBhcmFtKSB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICBpZiAoIWlzSW5pdCkgeworICAgICAgICAgICAgdGhyb3dOb3RJbml0aWFsaXplZCgpOworICAgICAgICB9CisgICAgICAgIGlmIChhbGlhcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImFsaWFzID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJlbnRyeSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaW1wbFNwaS5lbmdpbmVTZXRFbnRyeShhbGlhcywgZW50cnksIHBhcmFtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgZW50cnkgZm9yIHRoZSBnaXZlbiBhbGlhcyBpcyBhc3NpZ25hYmxlIHRvIHRoZQorICAgICAqIHByb3ZpZGVkIHtAY29kZSBDbGFzc30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxpYXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGlhcyBmb3IgdGhlIGVudHJ5LgorICAgICAqIEBwYXJhbSBlbnRyeUNsYXNzCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgZW50cnkuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHtAY29kZSBFbnRyeX0gZm9yIHRoZSBhbGlhcyBpcyBhc3NpZ25hYmxlIHRvCisgICAgICogICAgICAgICB0aGUgc3BlY2lmaWVkIHtAY29kZSBlbnRyeUNsYXNzfS4KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgS2V5U3RvcmV9IGlzIG5vdCBpbml0aWFsaXplZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBlbnRyeUluc3RhbmNlT2YoU3RyaW5nIGFsaWFzLAorICAgICAgICAgICAgQ2xhc3M8PyBleHRlbmRzIEtleVN0b3JlLkVudHJ5PiBlbnRyeUNsYXNzKQorICAgICAgICAgICAgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFsaWFzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiYWxpYXMgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChlbnRyeUNsYXNzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiZW50cnlDbGFzcyA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWlzSW5pdCkgeworICAgICAgICAgICAgdGhyb3dOb3RJbml0aWFsaXplZCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpbXBsU3BpLmVuZ2luZUVudHJ5SW5zdGFuY2VPZihhbGlhcywgZW50cnlDbGFzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bjb2RlIEJ1aWxkZXJ9IGlzIHVzZWQgdG8gY29uc3RydWN0IG5ldyBpbnN0YW5jZXMgb2Yge0Bjb2RlIEtleVN0b3JlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIEJ1aWxkZXIgeworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgQnVpbGRlcn0uCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgQnVpbGRlcigpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgS2V5U3RvcmV9IGNyZWF0ZWQgYnkgdGhpcyB7QGNvZGUgQnVpbGRlcn0uCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBLZXlTdG9yZX0gY3JlYXRlZCBieSB0aGlzIHtAY29kZSBCdWlsZGVyfS4KKyAgICAgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnJlZCBkdXJpbmcgY29uc3RydWN0aW9uLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGFic3RyYWN0IEtleVN0b3JlIGdldEtleVN0b3JlKCkgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgUHJvdGVjdGlvblBhcmFtZXRlcn0gdG8gYmUgdXNlZCB3aGVuIGEge0Bjb2RlCisgICAgICAgICAqIEVudHJ5fSB3aXRoIHRoZSBzcGVjaWZpZWQgYWxpYXMgaXMgcmVxdWVzdGVkLiBCZWZvcmUgdGhpcyBtZXRob2QgaXMKKyAgICAgICAgICogaW52b2tlZCwge0BsaW5rICNnZXRLZXlTdG9yZSgpfSBtdXN0IGJlIGNhbGxlZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIGFsaWFzCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIGZvciB0aGUgZW50cnkuCisgICAgICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBQcm90ZWN0aW9uUGFyYW1ldGVyfSB0byBiZSB1c2VkIHdoZW4gYSB7QGNvZGUKKyAgICAgICAgICogICAgICAgICBFbnRyeX0gd2l0aCB0aGUgc3BlY2lmaWVkIGFsaWFzIGlzIHJlcXVlc3RlZC4KKyAgICAgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnJlZCBkdXJpbmcgdGhlIGxvb2t1cCBmb3IgdGhlIHByb3RlY3Rpb24KKyAgICAgICAgICogICAgICAgICAgICAgcGFyYW1ldGVyLgorICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiB7QGxpbmsgI2dldEtleVN0b3JlKCl9IGlzIG5vdCBjYWxsZWQgcHJpb3IgdGhlCisgICAgICAgICAqICAgICAgICAgICAgIGludm9jYXRpb24gb2YgdGhpcyBtZXRob2QuCisgICAgICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFsaWFzfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgYWJzdHJhY3QgUHJvdGVjdGlvblBhcmFtZXRlciBnZXRQcm90ZWN0aW9uUGFyYW1ldGVyKFN0cmluZyBhbGlhcykKKyAgICAgICAgICAgICAgICB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb247CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEJ1aWxkZXJ9IHRoYXQgaG9sZHMgdGhlIGdpdmVuIHtAY29kZSBLZXlTdG9yZX0KKyAgICAgICAgICogYW5kIHRoZSBnaXZlbiB7QGNvZGUgUHJvdGVjdGlvblBhcmFtZXRlcn0uCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBrZXlTdG9yZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgS2V5U3RvcmV9IHRvIGJlIGhlbGQuCisgICAgICAgICAqIEBwYXJhbSBwcm90ZWN0aW9uUGFyYW1ldGVyCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBQcm90ZWN0aW9uUGFyYW1ldGVyfSB0byBiZSBoZWxkLgorICAgICAgICAgKiBAcmV0dXJuIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBCdWlsZGVyfSB0aGF0IGhvbGRzIHRoZSBzcGVjaWZpZWQKKyAgICAgICAgICogICAgICAgICB7QGNvZGUgS2V5U3RvcmV9IGFuZCB0aGUgc3BlY2lmaWVkIHtAY29kZQorICAgICAgICAgKiAgICAgICAgIFByb3RlY3Rpb25QYXJhbWV0ZXJ9LgorICAgICAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBrZXlTdG9yZX0gb3Ige0Bjb2RlIHByb3RlY3Rpb25QYXJhbWV0ZXJ9IGlzCisgICAgICAgICAqICAgICAgICAgICAgIHtAY29kZSBudWxsfS4KKyAgICAgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIHtAY29kZSBLZXlTdG9yZX0gaXMgbm90IGluaXRpYWxpemVkLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0luc3RhbmNlKEtleVN0b3JlIGtleVN0b3JlLAorICAgICAgICAgICAgICAgIFByb3RlY3Rpb25QYXJhbWV0ZXIgcHJvdGVjdGlvblBhcmFtZXRlcikgeworICAgICAgICAgICAgaWYgKGtleVN0b3JlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImtleVN0b3JlID09IG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChwcm90ZWN0aW9uUGFyYW1ldGVyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInByb3RlY3Rpb25QYXJhbWV0ZXIgPT0gbnVsbCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFrZXlTdG9yZS5pc0luaXQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJLZXlTdG9yZSB3YXMgbm90IGluaXRpYWxpemVkIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IEJ1aWxkZXJJbXBsKGtleVN0b3JlLCBwcm90ZWN0aW9uUGFyYW1ldGVyLCBudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBCdWlsZGVyfSB0aGF0IGNyZWF0ZXMgYSBuZXcge0Bjb2RlIEtleVN0b3JlfQorICAgICAgICAgKiBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgYXJndW1lbnRzLgorICAgICAgICAgKiA8cD4KKyAgICAgICAgICogSWYge0Bjb2RlIHByb3ZpZGVyfSBpcyB7QGNvZGUgbnVsbH0sIGFsbCBpbnN0YWxsZWQgcHJvdmlkZXJzIGFyZQorICAgICAgICAgKiBzZWFyY2hlZCwgb3RoZXJ3aXNlIHRoZSBrZXkgc3RvcmUgZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGlzCisgICAgICAgICAqIHVzZWQuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSB0eXBlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHR5cGUgb2YgdGhlIHtAY29kZSBLZXlTdG9yZX0gdG8gYmUgY29uc3RydWN0ZWQuCisgICAgICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBwcm92aWRlciBvZiB0aGUge0Bjb2RlIEtleVN0b3JlfSB0byBiZSBjb25zdHJ1Y3RlZCwKKyAgICAgICAgICogICAgICAgICAgICBtYXliZSB7QGNvZGUgbnVsbH0uCisgICAgICAgICAqIEBwYXJhbSBmaWxlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBGaWxlfSB0aGF0IGNvbnRhaW5zIHRoZSBkYXRhIGZvciB0aGUge0Bjb2RlCisgICAgICAgICAqICAgICAgICAgICAgS2V5U3RvcmV9LgorICAgICAgICAgKiBAcGFyYW0gcHJvdGVjdGlvblBhcmFtZXRlcgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgUHJvdGVjdGlvblBhcmFtZXRlcn0gdXNlZCB0byBwcm90ZWN0IHRoZSBzdG9yZWQKKyAgICAgICAgICogICAgICAgICAgICBrZXlzLgorICAgICAgICAgKiBAcmV0dXJuIGEgbmV3IHtAY29kZSBCdWlsZGVyfSB0aGF0IGNyZWF0ZXMgYSBuZXcge0Bjb2RlIEtleVN0b3JlfQorICAgICAgICAgKiAgICAgICAgIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBhcmd1bWVudHMuCisgICAgICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHR5cGUsIHByb3RlY3Rpb25QYXJhbWV0ZXJ9IG9yIHtAY29kZSBmaWxlfSBpcworICAgICAgICAgKiAgICAgICAgICAgICB7QGNvZGUgbnVsbH0uCisgICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIHtAY29kZSBwcm90ZWN0aW9uUGFyYW1ldGVyfSBub3QgYW4gaW5zdGFuY2Ugb2YgZWl0aGVyCisgICAgICAgICAqICAgICAgICAgICAgIHtAY29kZSBQYXNzd29yZFByb3RlY3Rpb259IG9yIHtAY29kZQorICAgICAgICAgKiAgICAgICAgICAgICBDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9ufSwge0Bjb2RlIGZpbGV9IGlzIG5vdCBhIGZpbGUgb3IKKyAgICAgICAgICogICAgICAgICAgICAgZG9lcyBub3QgZXhpc3QgYXQgYWxsLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0luc3RhbmNlKFN0cmluZyB0eXBlLCBQcm92aWRlciBwcm92aWRlciwKKyAgICAgICAgICAgICAgICBGaWxlIGZpbGUsIFByb3RlY3Rpb25QYXJhbWV0ZXIgcHJvdGVjdGlvblBhcmFtZXRlcikgeworICAgICAgICAgICAgLy8gY2hlY2sgbnVsbCBwYXJhbWV0ZXJzCisgICAgICAgICAgICBpZiAodHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ0eXBlID09IG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChwcm90ZWN0aW9uUGFyYW1ldGVyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInByb3RlY3Rpb25QYXJhbWV0ZXIgPT0gbnVsbCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGZpbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiZmlsZSA9PSBudWxsIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBwcm90ZWN0aW9uIHBhcmFtZXRlciBzaG91bGQgYmUgUGFzc3dvcmRQcm90ZWN0aW9uIG9yCisgICAgICAgICAgICAvLyBDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uCisgICAgICAgICAgICBpZiAoIShwcm90ZWN0aW9uUGFyYW1ldGVyIGluc3RhbmNlb2YgUGFzc3dvcmRQcm90ZWN0aW9uKQorICAgICAgICAgICAgICAgICAgICAmJiAhKHByb3RlY3Rpb25QYXJhbWV0ZXIgaW5zdGFuY2VvZiBDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInByb3RlY3Rpb25QYXJhbWV0ZXIgaXMgbmVpdGhlciAiCisgICAgICAgICAgICAgICAgICAgICAgICArICJQYXNzd29yZFByb3RlY3Rpb24gbm9yIENhbGxiYWNrSGFuZGxlclByb3RlY3Rpb24gaW5zdGFuY2UiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIGNoZWNrIGZpbGUgcGFyYW1ldGVyCisgICAgICAgICAgICBpZiAoIWZpbGUuZXhpc3RzKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWxlIGRvZXMgbm90IGV4aXN0OiAiICsgZmlsZS5nZXROYW1lKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFmaWxlLmlzRmlsZSgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm90IGEgcmVndWxhciBmaWxlOiAiICsgZmlsZS5nZXROYW1lKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gY3JlYXRlIG5ldyBpbnN0YW5jZQorICAgICAgICAgICAgcmV0dXJuIG5ldyBCdWlsZGVySW1wbChudWxsLCBwcm90ZWN0aW9uUGFyYW1ldGVyLCBmaWxlLCB0eXBlLCBwcm92aWRlcik7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQnVpbGRlcn0gdGhhdCBjcmVhdGVzIGEgbmV3IHtAY29kZSBLZXlTdG9yZX0KKyAgICAgICAgICogYmFzZWQgb24gdGhlIHByb3ZpZGVkIGFyZ3VtZW50cy4KKyAgICAgICAgICogPHA+CisgICAgICAgICAqIElmIHtAY29kZSBwcm92aWRlcn0gaXMge0Bjb2RlIG51bGx9LCBhbGwgaW5zdGFsbGVkIHByb3ZpZGVycyBhcmUKKyAgICAgICAgICogc2VhcmNoZWQsIG90aGVyd2lzZSB0aGUga2V5IHN0b3JlIGZyb20gdGhlIHNwZWNpZmllZCBwcm92aWRlciBpcworICAgICAgICAgKiB1c2VkLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gdHlwZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSB7QGNvZGUgS2V5U3RvcmV9IHRvIGJlIGNvbnN0cnVjdGVkLgorICAgICAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgcHJvdmlkZXIgb2YgdGhlIHtAY29kZSBLZXlTdG9yZX0gdG8gYmUgY29uc3RydWN0ZWQsCisgICAgICAgICAqICAgICAgICAgICAgbWF5YmUge0Bjb2RlIG51bGx9LgorICAgICAgICAgKiBAcGFyYW0gcHJvdGVjdGlvblBhcmFtZXRlcgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgUHJvdGVjdGlvblBhcmFtZXRlcn0gdXNlZCB0byBwcm90ZWN0IHRoZSBzdG9yZWQKKyAgICAgICAgICogICAgICAgICAgICBrZXlzLgorICAgICAgICAgKiBAcmV0dXJuIGEgbmV3IHtAY29kZSBCdWlsZGVyfSB0aGF0IGNyZWF0ZXMgYSBuZXcge0Bjb2RlIEtleVN0b3JlfQorICAgICAgICAgKiAgICAgICAgIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBhcmd1bWVudHMuCisgICAgICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHR5cGV9IG9yIHtAY29kZSBwcm90ZWN0aW9uUGFyYW1ldGVyfSBpcyB7QGNvZGUKKyAgICAgICAgICogICAgICAgICAgICAgbnVsbH0uCisgICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIHtAY29kZSBwcm90ZWN0aW9uUGFyYW1ldGVyfSBub3QgYW4gaW5zdGFuY2Ugb2YgZWl0aGVyCisgICAgICAgICAqICAgICAgICAgICAgIHtAY29kZSBQYXNzd29yZFByb3RlY3Rpb259IG9yIHtAY29kZQorICAgICAgICAgKiAgICAgICAgICAgICBDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9ufSwge0Bjb2RlIGZpbGV9IGlzIG5vdCBhIGZpbGUgb3IKKyAgICAgICAgICogICAgICAgICAgICAgZG9lcyBub3QgZXhpc3QgYXQgYWxsLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0luc3RhbmNlKFN0cmluZyB0eXBlLCBQcm92aWRlciBwcm92aWRlciwKKyAgICAgICAgICAgICAgICBQcm90ZWN0aW9uUGFyYW1ldGVyIHByb3RlY3Rpb25QYXJhbWV0ZXIpIHsKKyAgICAgICAgICAgIGlmICh0eXBlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInR5cGUgPT0gbnVsbCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHByb3RlY3Rpb25QYXJhbWV0ZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicHJvdGVjdGlvblBhcmFtZXRlciA9PSBudWxsIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IEJ1aWxkZXJJbXBsKG51bGwsIHByb3RlY3Rpb25QYXJhbWV0ZXIsIG51bGwsIHR5cGUsIHByb3ZpZGVyKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIFRoaXMgY2xhc3MgaXMgaW1wbGVtZW50YXRpb24gb2YgYWJzdHJhY3QgY2xhc3MgS2V5U3RvcmUuQnVpbGRlcgorICAgICAgICAgKgorICAgICAgICAgKiBAYXV0aG9yIFZlcmEgUGV0cmFzaGtvdmEKKyAgICAgICAgICoKKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEJ1aWxkZXJJbXBsIGV4dGVuZHMgQnVpbGRlciB7CisgICAgICAgICAgICAvLyBTdG9yZSB1c2VkIEtleVN0b3JlCisgICAgICAgICAgICBwcml2YXRlIEtleVN0b3JlIGtleVN0b3JlOworCisgICAgICAgICAgICAvLyBTdG9yZSB1c2VkIFByb3RlY3Rpb25QYXJhbWV0ZXIKKyAgICAgICAgICAgIHByaXZhdGUgUHJvdGVjdGlvblBhcmFtZXRlciBwcm90UGFyYW1ldGVyOworCisgICAgICAgICAgICAvLyBTdG9yZSB1c2VkIEtleVN0b3JlIHR5cGUKKyAgICAgICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHR5cGVGb3JLZXlTdG9yZTsKKworICAgICAgICAgICAgLy8gU3RvcmUgdXNlZCBLZXlTdG9yZSBwcm92aWRlcgorICAgICAgICAgICAgcHJpdmF0ZSBmaW5hbCBQcm92aWRlciBwcm92aWRlckZvcktleVN0b3JlOworCisgICAgICAgICAgICAvLyBTdG9yZSB1c2VkIGZpbGUgZm9yIEtleVN0b3JlIGxvYWRpbmcKKyAgICAgICAgICAgIHByaXZhdGUgZmluYWwgRmlsZSBmaWxlRm9yTG9hZDsKKworICAgICAgICAgICAgLy8gU3RvcmUgZ2V0S2V5U3RvcmUgbWV0aG9kIHdhcyBpbnZva2VkIG9yIG5vdCBmb3IgS2V5U3RvcmVCdWlsZGVyCisgICAgICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNHZXRLZXlTdG9yZSA9IGZhbHNlOworCisgICAgICAgICAgICAvLyBTdG9yZSBsYXN0IEV4Y2VwdGlvbiBpbiBnZXRLZXlTdG9yZSgpCisgICAgICAgICAgICBwcml2YXRlIEtleVN0b3JlRXhjZXB0aW9uIGxhc3RFeGNlcHRpb247CisKKyAgICAgICAgICAgIC8qKgorICAgICAgICAgICAgICogQ29uc3RydWN0b3IgQnVpbGRlckltcGwgaW5pdGlhbGl6ZXMgcHJpdmF0ZSBmaWVsZHM6IGtleVN0b3JlLAorICAgICAgICAgICAgICogcHJvdFBhcmFtZXRlciwgdHlwZUZvcktleVN0b3JlIHByb3ZpZGVyRm9yS2V5U3RvcmUgZmlsZUZvckxvYWQsCisgICAgICAgICAgICAgKiBpc0dldEtleVN0b3JlCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIEJ1aWxkZXJJbXBsKEtleVN0b3JlIGtzLCBQcm90ZWN0aW9uUGFyYW1ldGVyIHBwLCBGaWxlIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdHlwZSwgUHJvdmlkZXIgcHJvdmlkZXIpIHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZSA9IGtzOworICAgICAgICAgICAgICAgIHByb3RQYXJhbWV0ZXIgPSBwcDsKKyAgICAgICAgICAgICAgICBmaWxlRm9yTG9hZCA9IGZpbGU7CisgICAgICAgICAgICAgICAgdHlwZUZvcktleVN0b3JlID0gdHlwZTsKKyAgICAgICAgICAgICAgICBwcm92aWRlckZvcktleVN0b3JlID0gcHJvdmlkZXI7CisgICAgICAgICAgICAgICAgaXNHZXRLZXlTdG9yZSA9IGZhbHNlOworICAgICAgICAgICAgICAgIGxhc3RFeGNlcHRpb24gPSBudWxsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgICAqIEltcGxlbWVudGF0aW9uIG9mIGFic3RyYWN0IGdldEtleVN0b3JlKCkgbWV0aG9kIElmCisgICAgICAgICAgICAgKiBLZXlTdG9yZUJ1aWxkZXIgZW5jYXBzdWxhdGVzIEtleVN0b3JlIG9iamVjdCB0aGVuIHRoaXMgb2JqZWN0IGlzCisgICAgICAgICAgICAgKiByZXR1cm5lZAorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIElmIEtleVN0b3JlQnVpbGRlciBlbmNhcHN1bGF0ZXMgS2V5U3RvcmUgdHlwZSBhbmQgcHJvdmlkZXIgdGhlbgorICAgICAgICAgICAgICogS2V5U3RvcmUgaXMgY3JlYXRlZCB1c2luZyB0aGVzZSBwYXJhbWV0ZXJzLiBJZiBLZXlTdG9yZUJ1aWxkZXIKKyAgICAgICAgICAgICAqIGVuY2Fwc3VsYXRlcyBmaWxlIGFuZCBQcm90ZWN0aW9uUGFyYW1ldGVyIHRoZW4gS2V5U3RvcmUgZGF0YSBhcmUKKyAgICAgICAgICAgICAqIGxvYWRlZCBmcm9tIEZpbGVJbnB1dFN0cmVhbSB0aGF0IGlzIGNyZWF0ZWQgb24gZmlsZS4gSWYgZmlsZSBpcworICAgICAgICAgICAgICogbm90IGRlZmluZWQgdGhlbiBLZXlTdG9yZSBvYmplY3QgaXMgaW5pdGlhbGl6ZWQgd2l0aCBudWxsCisgICAgICAgICAgICAgKiBJbnB1dFN0cmVhbSBhbmQgbnVsbCBwYXNzd29yZC4KKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBSZXN1bHQgS2V5U3RvcmUgb2JqZWN0IGlzIHJldHVybmVkLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgS2V5U3RvcmUgZ2V0S2V5U3RvcmUoKSB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICAgICAgICAgIC8vIElmIEtleVN0b3JlIHdhcyBjcmVhdGVkIGJ1dCBpbiBmaW5hbCBibG9jayBzb21lIGV4Y2VwdGlvbiB3YXMKKyAgICAgICAgICAgICAgICAvLyB0aHJvd24KKyAgICAgICAgICAgICAgICAvLyB0aGVuIGl0IHdhcyBzdG9yZWQgaW4gbGFzdEV4Y2VwdGlvbiB2YXJpYWJsZSBhbmQgd2lsbCBiZQorICAgICAgICAgICAgICAgIC8vIHRocm93bgorICAgICAgICAgICAgICAgIC8vIGFsbCBzdWJzZXF1ZW50IGNhbGxzIG9mIHRoaXMgbWV0aG9kLgorICAgICAgICAgICAgICAgIGlmIChsYXN0RXhjZXB0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbGFzdEV4Y2VwdGlvbjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGtleVN0b3JlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaXNHZXRLZXlTdG9yZSA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBrZXlTdG9yZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAvLyBnZXQgS2V5U3RvcmUgaW5zdGFuY2UgdXNpbmcgdHlwZSBvciB0eXBlIGFuZCBwcm92aWRlcgorICAgICAgICAgICAgICAgICAgICBmaW5hbCBLZXlTdG9yZSBrcyA9IChwcm92aWRlckZvcktleVN0b3JlID09IG51bGwgPyBLZXlTdG9yZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZSh0eXBlRm9yS2V5U3RvcmUpIDogS2V5U3RvcmUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2UodHlwZUZvcktleVN0b3JlLCBwcm92aWRlckZvcktleVN0b3JlKSk7CisgICAgICAgICAgICAgICAgICAgIC8vIHByb3RlY3Rpb24gcGFyYW1ldGVyIHNob3VsZCBiZSBQYXNzd29yZFByb3RlY3Rpb24KKyAgICAgICAgICAgICAgICAgICAgLy8gb3IgQ2FsbGJhY2tIYW5kbGVyUHJvdGVjdGlvbgorICAgICAgICAgICAgICAgICAgICBmaW5hbCBjaGFyW10gcGFzc3dkOworICAgICAgICAgICAgICAgICAgICBpZiAocHJvdFBhcmFtZXRlciBpbnN0YW5jZW9mIFBhc3N3b3JkUHJvdGVjdGlvbikgeworICAgICAgICAgICAgICAgICAgICAgICAgcGFzc3dkID0gKChQYXNzd29yZFByb3RlY3Rpb24pIHByb3RQYXJhbWV0ZXIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRQYXNzd29yZCgpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHByb3RQYXJhbWV0ZXIgaW5zdGFuY2VvZiBDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwYXNzd2QgPSBLZXlTdG9yZVNwaQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0UGFzc3dvcmRGcm9tQ2FsbEJhY2socHJvdFBhcmFtZXRlcik7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgS2V5U3RvcmVFeGNlcHRpb24oInByb3RlY3Rpb25QYXJhbWV0ZXIgaXMgbmVpdGhlciAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIlBhc3N3b3JkUHJvdGVjdGlvbiBub3IgQ2FsbGJhY2tIYW5kbGVyUHJvdGVjdGlvbiBpbnN0YW5jZSIpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgLy8gbG9hZCBLZXlTdG9yZSBmcm9tIGZpbGUKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVGb3JMb2FkICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBmaXMgPSBudWxsOworICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGVGb3JMb2FkKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBrcy5sb2FkKGZpcywgcGFzc3dkKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkoZmlzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGtzLmxvYWQobmV3IFRtcExTUGFyYW1ldGVyKHByb3RQYXJhbWV0ZXIpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGlzR2V0S2V5U3RvcmUgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4ga3M7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAvLyBTdG9yZSBleGNlcHRpb24KKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbGFzdEV4Y2VwdGlvbiA9IGU7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gT3ZlcnJpZGUgZXhjZXB0aW9uCisgICAgICAgICAgICAgICAgICAgIHRocm93IGxhc3RFeGNlcHRpb24gPSBuZXcgS2V5U3RvcmVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgICAqIFRoaXMgaXMgaW1wbGVtZW50YXRpb24gb2YgYWJzdHJhY3QgbWV0aG9kCisgICAgICAgICAgICAgKiBnZXRQcm90ZWN0aW9uUGFyYW1ldGVyKFN0cmluZyBhbGlhcykKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBSZXR1cm46IFByb3RlY3Rpb25QYXJhbWV0ZXIgdG8gZ2V0IEVudHJ5IHdoaWNoIHdhcyBzYXZlZCBpbgorICAgICAgICAgICAgICogS2V5U3RvcmUgd2l0aCBkZWZpbmVkIGFsaWFzCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCBQcm90ZWN0aW9uUGFyYW1ldGVyIGdldFByb3RlY3Rpb25QYXJhbWV0ZXIoCisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhbGlhcykgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBpZiAoYWxpYXMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImFsaWFzID09IG51bGwiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKCFpc0dldEtleVN0b3JlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oImdldEtleVN0b3JlKCkgd2FzIG5vdCBpbnZva2VkIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBwcm90UGFyYW1ldGVyOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogSW1wbGVtZW50YXRpb24gb2YgTG9hZFN0b3JlUGFyYW1ldGVyIGludGVyZmFjZQorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgVG1wTFNQYXJhbWV0ZXIgaW1wbGVtZW50cyBMb2FkU3RvcmVQYXJhbWV0ZXIgeworCisgICAgICAgICAgICAvLyBTdG9yZSB1c2VkIHByb3RlY3Rpb24gcGFyYW1ldGVyCisgICAgICAgICAgICBwcml2YXRlIGZpbmFsIFByb3RlY3Rpb25QYXJhbWV0ZXIgcHJvdFBhcjsKKworICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgKiBDcmVhdGVzIFRtcExvYWRTdG9yZVBhcmFtZXRlciBvYmplY3QKKyAgICAgICAgICAgICAqIEBwYXJhbSBwcm90UGFyIHByb3RlY3Rpb24gcGFyYW1ldGVyCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHB1YmxpYyBUbXBMU1BhcmFtZXRlcihQcm90ZWN0aW9uUGFyYW1ldGVyIHByb3RQYXIpIHsKKyAgICAgICAgICAgICAgICB0aGlzLnByb3RQYXIgPSBwcm90UGFyOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgcHJvdGVjdGlvbiBwYXJhbWV0ZXIKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgcHVibGljIFByb3RlY3Rpb25QYXJhbWV0ZXIgZ2V0UHJvdGVjdGlvblBhcmFtZXRlcigpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcHJvdFBhcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHtAY29kZSBDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9ufSBpcyBhIHtAY29kZSBQcm90ZWN0aW9uUGFyYW1ldGVyfSB0aGF0CisgICAgICogZW5jYXBzdWxhdGVzIGEge0BsaW5rIENhbGxiYWNrSGFuZGxlcn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uIGltcGxlbWVudHMKKyAgICAgICAgICAgIFByb3RlY3Rpb25QYXJhbWV0ZXIgeworICAgICAgICAvLyBTdG9yZSBDYWxsYmFja0hhbmRsZXIKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBDYWxsYmFja0hhbmRsZXIgY2FsbGJhY2tIYW5kbGVyOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9ufSB3aXRoCisgICAgICAgICAqIHRoZSB7QGNvZGUgQ2FsbGJhY2tIYW5kbGVyfS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIGhhbmRsZXIKKyAgICAgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIENhbGxiYWNrSGFuZGxlcn0uCisgICAgICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGhhbmRsZXJ9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uKENhbGxiYWNrSGFuZGxlciBoYW5kbGVyKSB7CisgICAgICAgICAgICBpZiAoaGFuZGxlciA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJoYW5kbGVyID09IG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMuY2FsbGJhY2tIYW5kbGVyID0gaGFuZGxlcjsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgQ2FsbGJhY2tIYW5kbGVyfS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUge0Bjb2RlIENhbGxiYWNrSGFuZGxlcn0uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQ2FsbGJhY2tIYW5kbGVyIGdldENhbGxiYWNrSGFuZGxlcigpIHsKKyAgICAgICAgICAgIHJldHVybiBjYWxsYmFja0hhbmRsZXI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGNvZGUgRW50cnl9IGlzIHRoZSBjb21tb24gbWFya2VyIGludGVyZmFjZSBmb3IgYSB7QGNvZGUgS2V5U3RvcmV9CisgICAgICogZW50cnkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnRlcmZhY2UgRW50cnkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAY29kZSBMb2FkU3RvcmVQYXJhbWV0ZXJ9IHJlcHJlc2VudHMgYSBwYXJhbWV0ZXIgdGhhdCBzcGVjaWZpZXMgaG93IGEKKyAgICAgKiB7QGNvZGUgS2V5U3RvcmV9IGNhbiBiZSBsb2FkZWQgYW5kIHN0b3JlZC4KKyAgICAgKgorICAgICAqIEBzZWUgS2V5U3RvcmUjbG9hZChMb2FkU3RvcmVQYXJhbWV0ZXIpCisgICAgICogQHNlZSBLZXlTdG9yZSNzdG9yZShMb2FkU3RvcmVQYXJhbWV0ZXIpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnRlcmZhY2UgTG9hZFN0b3JlUGFyYW1ldGVyIHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBQcm90ZWN0aW9uUGFyYW1ldGVyfSB3aGljaCBpcyB1c2VkIHRvIHByb3RlY3QgZGF0YQorICAgICAgICAgKiBpbiB0aGUge0Bjb2RlIEtleVN0b3JlfS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFByb3RlY3Rpb25QYXJhbWV0ZXJ9IHdoaWNoIGlzIHVzZWQgdG8gcHJvdGVjdCBkYXRhCisgICAgICAgICAqICAgICAgICAgaW4gdGhlIHtAY29kZSBLZXlTdG9yZX0sIG1heWJlIHtAY29kZSBudWxsfS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBQcm90ZWN0aW9uUGFyYW1ldGVyIGdldFByb3RlY3Rpb25QYXJhbWV0ZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGNvZGUgUGFzc3dvcmRQcm90ZWN0aW9ufSBpcyBhIHtAY29kZSBQcm90ZWN0aW9uUGFyYW1ldGVyfSB0aGF0IHByb3RlY3RzCisgICAgICogYSB7QGNvZGUgS2V5U3RvcmV9IHVzaW5nIGEgcGFzc3dvcmQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBQYXNzd29yZFByb3RlY3Rpb24gaW1wbGVtZW50cyBQcm90ZWN0aW9uUGFyYW1ldGVyLAorICAgICAgICAgICAgRGVzdHJveWFibGUgeworCisgICAgICAgIC8vIFN0b3JlIHBhc3N3b3JkCisgICAgICAgIHByaXZhdGUgY2hhcltdIHBhc3N3b3JkOworCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc0Rlc3Ryb3llZCA9IGZhbHNlOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBQYXNzd29yZFByb3RlY3Rpb259IHdpdGggYQorICAgICAgICAgKiBwYXNzd29yZC4gQSBjb3B5IG9mIHRoZSBwYXNzd29yZCBpcyBzdG9yZWQgaW4gdGhlIG5ldyB7QGNvZGUKKyAgICAgICAgICogUGFzc3dvcmRQcm90ZWN0aW9ufSBvYmplY3QuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBwYXNzd29yZAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBwYXNzd29yZCwgbWF5YmUge0Bjb2RlIG51bGx9LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFBhc3N3b3JkUHJvdGVjdGlvbihjaGFyW10gcGFzc3dvcmQpIHsKKyAgICAgICAgICAgIGlmIChwYXNzd29yZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhpcy5wYXNzd29yZCA9IHBhc3N3b3JkLmNsb25lKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgcGFzc3dvcmQuCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gdGhlIHBhc3N3b3JkLgorICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFzc3dvcmQgaGFzIGJlZW4gZGVzdHJveWVkLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCBjaGFyW10gZ2V0UGFzc3dvcmQoKSB7CisgICAgICAgICAgICBpZiAoaXNEZXN0cm95ZWQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJQYXNzd29yZCB3YXMgZGVzdHJveWVkIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcGFzc3dvcmQ7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogRGVzdHJveXMgLyBpbnZhbGlkYXRlcyB0aGUgcGFzc3dvcmQuCisgICAgICAgICAqCisgICAgICAgICAqIEB0aHJvd3MgRGVzdHJveUZhaWxlZEV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFzc3dvcmQgY291bGQgbm90IGJlIGludmFsaWRhdGVkLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGRlc3Ryb3koKSB0aHJvd3MgRGVzdHJveUZhaWxlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpc0Rlc3Ryb3llZCA9IHRydWU7CisgICAgICAgICAgICBpZiAocGFzc3dvcmQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIEFycmF5cy5maWxsKHBhc3N3b3JkLCAnXHUwMDAwJyk7CisgICAgICAgICAgICAgICAgcGFzc3dvcmQgPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBwYXNzd29yZCBpcyBpbnZhbGlkYXRlZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHBhc3N3b3JkIGlzIGludmFsaWRhdGVkLCB7QGNvZGUgZmFsc2V9CisgICAgICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGlzRGVzdHJveWVkKCkgeworICAgICAgICAgICAgcmV0dXJuIGlzRGVzdHJveWVkOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bjb2RlIFByb3RlY3Rpb25QYXJhbWV0ZXJ9IGlzIGEgbWFya2VyIGludGVyZmFjZSBmb3IgcHJvdGVjdGlvbgorICAgICAqIHBhcmFtZXRlcnMuIEEgcHJvdGVjdGlvbiBwYXJhbWV0ZXIgaXMgdXNlZCB0byBwcm90ZWN0IHRoZSBjb250ZW50IG9mIGEKKyAgICAgKiB7QGNvZGUgS2V5U3RvcmV9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50ZXJmYWNlIFByb3RlY3Rpb25QYXJhbWV0ZXIgeworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAY29kZSBQcml2YXRlS2V5RW50cnl9IHJlcHJlc2VudHMgYSB7QGNvZGUgS2V5U3RvcmV9IGVudHJ5IHRoYXQKKyAgICAgKiBob2xkcyBhIHByaXZhdGUga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUHJpdmF0ZUtleUVudHJ5IGltcGxlbWVudHMgRW50cnkgeworICAgICAgICAvLyBTdG9yZSBDZXJ0aWZpY2F0ZSBjaGFpbgorICAgICAgICBwcml2YXRlIENlcnRpZmljYXRlW10gY2hhaW47CisKKyAgICAgICAgLy8gU3RvcmUgUHJpdmF0ZUtleQorICAgICAgICBwcml2YXRlIFByaXZhdGVLZXkgcHJpdmF0ZUtleTsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgUHJpdmF0ZUtleUVudHJ5fSB3aXRoIHRoZSBnaXZlbgorICAgICAgICAgKiB7QGNvZGUgUHJpdmF0ZUtleX0gYW5kIHRoZSBwcm92aWRlZCBjZXJ0aWZpY2F0ZSBjaGFpbi4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIHByaXZhdGVLZXkKKyAgICAgICAgICogICAgICAgICAgICB0aGUgcHJpdmF0ZSBrZXkuCisgICAgICAgICAqIEBwYXJhbSBjaGFpbgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBvcmRlcmVkIGNlcnRpZmljYXRlIGNoYWluIHdpdGggdGhlIGNlcnRpZmljYXRlCisgICAgICAgICAqICAgICAgICAgICAgY29ycmVzcG9uZGluZyB0byB0aGUgcHJpdmF0ZSBrZXkgYXQgaW5kZXggMC4KKyAgICAgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcHJpdmF0ZUtleX0gb3Ige0Bjb2RlIGNoYWlufSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBjaGFpbi5sZW5ndGggPT0gMH0sIHRoZSBhbGdvcml0aG0gb2YgdGhlCisgICAgICAgICAqICAgICAgICAgICAgIHByaXZhdGUga2V5IGRvZXMgbm90IG1hdGNoIHRoZSBhbGdvcml0aG0gb2YgdGhlIHB1YmxpYworICAgICAgICAgKiAgICAgICAgICAgICBrZXkgb2YgdGhlIGZpcnN0IGNlcnRpZmljYXRlIG9yIHRoZSBjZXJ0aWZpY2F0ZXMgYXJlIG5vdAorICAgICAgICAgKiAgICAgICAgICAgICBhbGwgb2YgdGhlIHNhbWUgdHlwZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBQcml2YXRlS2V5RW50cnkoUHJpdmF0ZUtleSBwcml2YXRlS2V5LCBDZXJ0aWZpY2F0ZVtdIGNoYWluKSB7CisgICAgICAgICAgICBpZiAocHJpdmF0ZUtleSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJwcml2YXRlS2V5ID09IG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjaGFpbiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJjaGFpbiA9PSBudWxsIik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChjaGFpbi5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImNoYWluLmxlbmd0aCA9PSAwIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBNYXRjaCBhbGdvcml0aG0gb2YgcHJpdmF0ZSBrZXkgYW5kIGFsZ29yaXRobSBvZiBwdWJsaWMga2V5IGZyb20KKyAgICAgICAgICAgIC8vIHRoZSBlbmQgY2VydGlmaWNhdGUKKyAgICAgICAgICAgIFN0cmluZyBzID0gY2hhaW5bMF0uZ2V0VHlwZSgpOworICAgICAgICAgICAgaWYgKCEoY2hhaW5bMF0uZ2V0UHVibGljS2V5KCkuZ2V0QWxnb3JpdGhtKCkpLmVxdWFscyhwcml2YXRlS2V5LmdldEFsZ29yaXRobSgpKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkFsZ29yaXRobSBvZiBwcml2YXRlIGtleSBkb2VzIG5vdCBtYXRjaCAiCisgICAgICAgICAgICAgICAgICAgICAgICArICJhbGdvcml0aG0gb2YgcHVibGljIGtleSBpbiBlbmQgY2VydGlmaWNhdGUgb2YgZW50cnkgIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAiKHdpdGggaW5kZXggbnVtYmVyOiAwKSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gTWF0Y2ggY2VydGlmaWNhdGUgdHlwZXMKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgY2hhaW4ubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoIXMuZXF1YWxzKGNoYWluW2ldLmdldFR5cGUoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQ2VydGlmaWNhdGVzIGZyb20gdGhlIGdpdmVuIGNoYWluIGhhdmUgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgImRpZmZlcmVudCB0eXBlcyIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIGNsb25lIGNoYWluIC0gdGhpcy5jaGFpbiA9IChDZXJ0aWZpY2F0ZVtdKWNoYWluLmNsb25lKCk7CisgICAgICAgICAgICBib29sZWFuIGlzQWxsWDUwOUNlcnRpZmljYXRlcyA9IHRydWU7CisgICAgICAgICAgICAvLyBhc3NlcnQgY2hhaW4gbGVuZ3RoID4gMAorICAgICAgICAgICAgZm9yIChDZXJ0aWZpY2F0ZSBjZXJ0OiBjaGFpbikgeworICAgICAgICAgICAgICAgIGlmICghKGNlcnQgaW5zdGFuY2VvZiBYNTA5Q2VydGlmaWNhdGUpKSB7CisgICAgICAgICAgICAgICAgICAgIGlzQWxsWDUwOUNlcnRpZmljYXRlcyA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmKGlzQWxsWDUwOUNlcnRpZmljYXRlcyl7CisgICAgICAgICAgICAgICAgdGhpcy5jaGFpbiA9IG5ldyBYNTA5Q2VydGlmaWNhdGVbY2hhaW4ubGVuZ3RoXTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhpcy5jaGFpbiA9IG5ldyBDZXJ0aWZpY2F0ZVtjaGFpbi5sZW5ndGhdOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShjaGFpbiwgMCwgdGhpcy5jaGFpbiwgMCwgY2hhaW4ubGVuZ3RoKTsKKyAgICAgICAgICAgIHRoaXMucHJpdmF0ZUtleSA9IHByaXZhdGVLZXk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgcHJpdmF0ZSBrZXkuCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gdGhlIHByaXZhdGUga2V5LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFByaXZhdGVLZXkgZ2V0UHJpdmF0ZUtleSgpIHsKKyAgICAgICAgICAgIHJldHVybiBwcml2YXRlS2V5OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIGNlcnRpZmljYXRlIGNoYWluLgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBjZXJ0aWZpY2F0ZSBjaGFpbi4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZVtdIGdldENlcnRpZmljYXRlQ2hhaW4oKSB7CisgICAgICAgICAgICByZXR1cm4gY2hhaW4uY2xvbmUoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRoZSBjZXJ0aWZpY2F0ZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcml2YXRlIGtleS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUgY2VydGlmaWNhdGUgY29ycmVzcG9uZGluZyB0byB0aGUgcHJpdmF0ZSBrZXkuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQ2VydGlmaWNhdGUgZ2V0Q2VydGlmaWNhdGUoKSB7CisgICAgICAgICAgICByZXR1cm4gY2hhaW5bMF07CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YKKyAgICAgICAgICogdGhpcyB7QGNvZGUgUHJpdmF0ZUtleUVudHJ5fS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiBhIHByaW50YWJsZSByZXByZXNlbnRhdGlvbiBmb3IgdGhpcyB7QGNvZGUgUHJpdmF0ZUtleUVudHJ5fS4KKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKAorICAgICAgICAgICAgICAgICAgICAiUHJpdmF0ZUtleUVudHJ5OiBudW1iZXIgb2YgZWxlbWVudHMgaW4gY2VydGlmaWNhdGUgY2hhaW4gaXMgIik7CisgICAgICAgICAgICBzYi5hcHBlbmQoSW50ZWdlci50b1N0cmluZyhjaGFpbi5sZW5ndGgpKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiXG4iKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2hhaW4ubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoY2hhaW5baV0udG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCJcbiIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGNvZGUgU2VjcmV0S2V5RW50cnl9IHJlcHJlc2VudHMgYSB7QGNvZGUgS2V5U3RvcmV9IGVudHJ5IHRoYXQKKyAgICAgKiBob2xkcyBhIHNlY3JldCBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBTZWNyZXRLZXlFbnRyeSBpbXBsZW1lbnRzIEVudHJ5IHsKKworICAgICAgICAvLyBTdG9yZSBTZWNyZXRLZXkKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTZWNyZXRLZXkgc2VjcmV0S2V5OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBTZWNyZXRLZXlFbnRyeX0gd2l0aCB0aGUgZ2l2ZW4KKyAgICAgICAgICoge0Bjb2RlIFNlY3JldEtleX0uCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBzZWNyZXRLZXkKKyAgICAgICAgICogICAgICAgICAgICB0aGUgc2VjcmV0IGtleS4KKyAgICAgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc2VjcmV0S2V5fSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgU2VjcmV0S2V5RW50cnkoU2VjcmV0S2V5IHNlY3JldEtleSkgeworICAgICAgICAgICAgaWYgKHNlY3JldEtleSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJzZWNyZXRLZXkgPT0gbnVsbCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy5zZWNyZXRLZXkgPSBzZWNyZXRLZXk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgc2VjcmV0IGtleS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUgc2VjcmV0IGtleS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBTZWNyZXRLZXkgZ2V0U2VjcmV0S2V5KCkgeworICAgICAgICAgICAgcmV0dXJuIHNlY3JldEtleTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZgorICAgICAgICAgKiB0aGlzIHtAY29kZSBTZWNyZXRLZXlFbnRyeX0uCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gYSBwcmludGFibGUgcmVwcmVzZW50YXRpb24gZm9yIHRoaXMge0Bjb2RlCisgICAgICAgICAqICAgICAgICAgU2VjcmV0S2V5RW50cnl9LgorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoIlNlY3JldEtleUVudHJ5OiBhbGdvcml0aG0gLSAiKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZChzZWNyZXRLZXkuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGNvZGUgVHJ1c3RlZENlcnRpZmljYXRlRW50cnl9IHJlcHJlc2VudHMgYSB7QGNvZGUgS2V5U3RvcmV9IGVudHJ5IHRoYXQKKyAgICAgKiBob2xkcyBhIHRydXN0ZWQgY2VydGlmaWNhdGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeSBpbXBsZW1lbnRzIEVudHJ5IHsKKworICAgICAgICAvLyBTdG9yZSB0cnVzdGVkIENlcnRpZmljYXRlCisgICAgICAgIHByaXZhdGUgZmluYWwgQ2VydGlmaWNhdGUgdHJ1c3RDZXJ0aWZpY2F0ZTsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgVHJ1c3RlZENlcnRpZmljYXRlRW50cnl9IHdpdGggdGhlCisgICAgICAgICAqIGdpdmVuIHtAY29kZSBDZXJ0aWZpY2F0ZX0uCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSB0cnVzdENlcnRpZmljYXRlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHRydXN0ZWQgY2VydGlmaWNhdGUuCisgICAgICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHRydXN0Q2VydGlmaWNhdGV9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeShDZXJ0aWZpY2F0ZSB0cnVzdENlcnRpZmljYXRlKSB7CisgICAgICAgICAgICBpZiAodHJ1c3RDZXJ0aWZpY2F0ZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ0cnVzdENlcnRpZmljYXRlID09IG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMudHJ1c3RDZXJ0aWZpY2F0ZSA9IHRydXN0Q2VydGlmaWNhdGU7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgdHJ1c3RlZCBjZXJ0aWZpY2F0ZS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUgdHJ1c3RlZCBjZXJ0aWZpY2F0ZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZSBnZXRUcnVzdGVkQ2VydGlmaWNhdGUoKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1c3RDZXJ0aWZpY2F0ZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZgorICAgICAgICAgKiB0aGlzIHtAY29kZSBUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeX0uCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gYSBwcmludGFibGUgcmVwcmVzZW50YXRpb24gZm9yIHRoaXMge0Bjb2RlCisgICAgICAgICAqICAgICAgICAgVHJ1c3RlZENlcnRpZmljYXRlRW50cnl9LgorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICByZXR1cm4gIlRydXN0ZWQgY2VydGlmaWNhdGUgZW50cnk6XG4iICsgdHJ1c3RDZXJ0aWZpY2F0ZTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0tleVN0b3JlRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9LZXlTdG9yZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVmOTg2OWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9LZXlTdG9yZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworLyoqCisgKiB7QGNvZGUgS2V5U3RvcmVFeGNlcHRpb259IGlzIGEgZ2VuZXJhbCB7QGNvZGUgS2V5U3RvcmV9IGV4Y2VwdGlvbi4KKyAqCisgKiBAc2VlIEtleVN0b3JlCisgKi8KK3B1YmxpYyBjbGFzcyBLZXlTdG9yZUV4Y2VwdGlvbiBleHRlbmRzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTExOTM1MzE3OTMyMjM3NzI2Mkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBLZXlTdG9yZUV4Y2VwdGlvbn0gd2l0aCB0aGUKKyAgICAgKiBnaXZlbiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgS2V5U3RvcmVFeGNlcHRpb24oU3RyaW5nIG1zZykgeworICAgICAgICBzdXBlcihtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEtleVN0b3JlRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgS2V5U3RvcmVFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgS2V5U3RvcmVFeGNlcHRpb259IHdpdGggdGhlCisgICAgICogZ2l2ZW4gbWVzc2FnZSBhbmQgdGhlIGNhdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgZXhjZXB0aW9uIHdoaWNoIGlzIHRoZSBjYXVzZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIEtleVN0b3JlRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEtleVN0b3JlRXhjZXB0aW9ufSB3aXRoIHRoZQorICAgICAqIGNhdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgZXhjZXB0aW9uIHdoaWNoIGlzIHRoZSBjYXVzZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIEtleVN0b3JlRXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvS2V5U3RvcmVTcGkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0tleVN0b3JlU3BpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDE1NjVmNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L0tleVN0b3JlU3BpLmphdmEKQEAgLTAsMCArMSw1MjYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2VjcmV0S2V5OworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suQ2FsbGJhY2tIYW5kbGVyOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suUGFzc3dvcmRDYWxsYmFjazsKKworLyoqCisgKiB7QGNvZGUgS2V5U3RvcmVTcGl9IGlzIHRoZSBTZXJ2aWNlIFByb3ZpZGVyIEludGVyZmFjZSAoU1BJKSBkZWZpbml0aW9uIGZvcgorICoge0BsaW5rIEtleVN0b3JlfS4KKyAqCisgKiBAc2VlIEtleVN0b3JlCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBLZXlTdG9yZVNwaSB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBrZXkgd2l0aCB0aGUgZ2l2ZW4gYWxpYXMsIHVzaW5nIHRoZSBwYXNzd29yZCB0byByZWNvdmVyIHRoZQorICAgICAqIGtleSBmcm9tIHRoZSBzdG9yZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGlhcworICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIGZvciB0aGUgZW50cnkuCisgICAgICogQHBhcmFtIHBhc3N3b3JkCisgICAgICogICAgICAgICAgICB0aGUgcGFzc3dvcmQgdXNlZCB0byByZWNvdmVyIHRoZSBrZXkuCisgICAgICogQHJldHVybiB0aGUga2V5IHdpdGggdGhlIHNwZWNpZmllZCBhbGlhcywgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIGFsaWFzIGlzIG5vdCBib3VuZCB0byBhbiBlbnRyeS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhbGdvcml0aG0gZm9yIHJlY292ZXJpbmcgdGhlIGtleSBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBrZXkgY2FuIG5vdCBiZSByZWNvdmVyZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEtleSBlbmdpbmVHZXRLZXkoU3RyaW5nIGFsaWFzLCBjaGFyW10gcGFzc3dvcmQpCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2VydGlmaWNhdGUgY2hhaW4gZm9yIHRoZSBlbnRyeSB3aXRoIHRoZSBnaXZlbiBhbGlhcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGlhcworICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIGZvciB0aGUgZW50cnkKKyAgICAgKiBAcmV0dXJuIHRoZSBjZXJ0aWZpY2F0ZSBjaGFpbiBmb3IgdGhlIGVudHJ5IHdpdGggdGhlIGdpdmVuIGFsaWFzLCBvcgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlmIHRoZSBzcGVjaWZpZWQgYWxpYXMgaXMgbm90IGJvdW5kIHRvIGFuIGVudHJ5LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBDZXJ0aWZpY2F0ZVtdIGVuZ2luZUdldENlcnRpZmljYXRlQ2hhaW4oU3RyaW5nIGFsaWFzKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRydXN0ZWQgY2VydGlmaWNhdGUgZm9yIHRoZSBlbnRyeSB3aXRoIHRoZSBnaXZlbiBhbGlhcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGlhcworICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIGZvciB0aGUgZW50cnkuCisgICAgICogQHJldHVybiB0aGUgdHJ1c3RlZCBjZXJ0aWZpY2F0ZSBmb3IgdGhlIGVudHJ5IHdpdGggdGhlIGdpdmVuIGFsaWFzLCBvcgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlmIHRoZSBzcGVjaWZpZWQgYWxpYXMgaXMgbm90IGJvdW5kIHRvIGFuIGVudHJ5LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBDZXJ0aWZpY2F0ZSBlbmdpbmVHZXRDZXJ0aWZpY2F0ZShTdHJpbmcgYWxpYXMpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3JlYXRpb24gZGF0ZSBvZiB0aGUgZW50cnkgd2l0aCB0aGUgZ2l2ZW4gYWxpYXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxpYXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGlhcyBmb3IgdGhlIGVudHJ5LgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0aW9uIGRhdGUsIG9yIHtAY29kZSBudWxsfSBpZiB0aGUgc3BlY2lmaWVkIGFsaWFzIGlzIG5vdAorICAgICAqICAgICAgICAgYm91bmQgdG8gYW4gZW50cnkuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IERhdGUgZW5naW5lR2V0Q3JlYXRpb25EYXRlKFN0cmluZyBhbGlhcyk7CisKKyAgICAvKioKKyAgICAgKiBBc3NvY2lhdGVzIHRoZSBnaXZlbiBhbGlhcyB3aXRoIHRoZSBrZXksIHBhc3N3b3JkIGFuZCBjZXJ0aWZpY2F0ZSBjaGFpbi4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgc3BlY2lmaWVkIGFsaWFzIGFscmVhZHkgZXhpc3RzLCBpdCB3aWxsIGJlIHJlYXNzaWduZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxpYXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGlhcyBmb3IgdGhlIGtleS4KKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5LgorICAgICAqIEBwYXJhbSBwYXNzd29yZAorICAgICAqICAgICAgICAgICAgdGhlIHBhc3N3b3JkLgorICAgICAqIEBwYXJhbSBjaGFpbgorICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRlIGNoYWluLgorICAgICAqIEB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGtleSBjYW4gbm90IGJlIHByb3RlY3RlZCwgb3IgaWYgdGhpcworICAgICAqICAgICAgICAgICAgIG9wZXJhdGlvbiBmYWlscyBmb3IgYW5vdGhlciByZWFzb24uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUga2V5fSBpcyBhIHtAY29kZSBQcml2YXRlS2V5fSBhbmQge0Bjb2RlIGNoYWlufSBkb2VzCisgICAgICogICAgICAgICAgICAgbm90IGNvbnRhaW4gYW55IGNlcnRpZmljYXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBlbmdpbmVTZXRLZXlFbnRyeShTdHJpbmcgYWxpYXMsIEtleSBrZXksCisgICAgICAgICAgICBjaGFyW10gcGFzc3dvcmQsIENlcnRpZmljYXRlW10gY2hhaW4pIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEFzc29jaWF0ZXMgdGhlIGdpdmVuIGFsaWFzIHdpdGggYSBrZXkgYW5kIGEgY2VydGlmaWNhdGUgY2hhaW4uCisgICAgICogPHA+CisgICAgICogSWYgdGhlIHNwZWNpZmllZCBhbGlhcyBhbHJlYWR5IGV4aXN0cywgaXQgd2lsbCBiZSByZWFzc2lnbmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGFsaWFzCisgICAgICogICAgICAgICAgICB0aGUgYWxpYXMgZm9yIHRoZSBrZXkuCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBpbiBhbiBlbmNvZGVkIGZvcm1hdC4KKyAgICAgKiBAcGFyYW0gY2hhaW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZSBjaGFpbi4KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBvcGVyYXRpb24gZmFpbHMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUga2V5fSBpcyBhIHtAY29kZSBQcml2YXRlS2V5fSBhbmQge0Bjb2RlIGNoYWlufQorICAgICAqICAgICAgICAgICAgIGRvZXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZW5naW5lU2V0S2V5RW50cnkoU3RyaW5nIGFsaWFzLCBieXRlW10ga2V5LAorICAgICAgICAgICAgQ2VydGlmaWNhdGVbXSBjaGFpbikgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQXNzb2NpYXRlcyB0aGUgZ2l2ZW4gYWxpYXMgd2l0aCBhIGNlcnRpZmljYXRlLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBzcGVjaWZpZWQgYWxpYXMgYWxyZWFkeSBleGlzdHMsIGl0IHdpbGwgYmUgcmVhc3NpZ25lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGlhcworICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIGZvciB0aGUgY2VydGlmaWNhdGUuCisgICAgICogQHBhcmFtIGNlcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZS4KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXhpc3RpbmcgYWxpYXMgaXMgbm90IGFzc29jaWF0ZWQgdG8gYW4gZW50cnkgY29udGFpbmluZworICAgICAqICAgICAgICAgICAgIGEgdHJ1c3RlZCBjZXJ0aWZpY2F0ZSwgb3IgdGhpcyBtZXRob2QgZmFpbHMgZm9yIGFueSBvdGhlcgorICAgICAqICAgICAgICAgICAgIHJlYXNvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBlbmdpbmVTZXRDZXJ0aWZpY2F0ZUVudHJ5KFN0cmluZyBhbGlhcywKKyAgICAgICAgICAgIENlcnRpZmljYXRlIGNlcnQpIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERlbGV0ZXMgdGhlIGVudHJ5IGlkZW50aWZpZWQgd2l0aCB0aGUgZ2l2ZW4gYWxpYXMgZnJvbSB0aGlzIHtAY29kZQorICAgICAqIEtleVN0b3JlU3BpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGlhcworICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIGZvciB0aGUgZW50cnkuCisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbnRyeSBjYW4gbm90IGJlIGRlbGV0ZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZW5naW5lRGVsZXRlRW50cnkoU3RyaW5nIGFsaWFzKQorICAgICAgICAgICAgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiB7QGNvZGUgRW51bWVyYXRpb259IG92ZXIgYWxsIGFsaWFzIG5hbWVzIHN0b3JlZCBpbiB0aGlzCisgICAgICoge0Bjb2RlIEtleVN0b3JlU3BpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIEVudW1lcmF0aW9ufSBvdmVyIGFsbCBhbGlhcyBuYW1lcyBzdG9yZWQgaW4gdGhpcworICAgICAqICAgICAgICAge0Bjb2RlIEtleVN0b3JlU3BpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRW51bWVyYXRpb248U3RyaW5nPiBlbmdpbmVBbGlhc2VzKCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgZ2l2ZW4gYWxpYXMgaXMgcHJlc2VudCBpbiB0aGlzIHtAY29kZSBLZXlTdG9yZVNwaX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxpYXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGlhcyBvZiBhbiBlbnRyeS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgYWxpYXMgZXhpc3RzLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBlbmdpbmVDb250YWluc0FsaWFzKFN0cmluZyBhbGlhcyk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZW50cmllcyBzdG9yZWQgaW4gdGhpcyB7QGNvZGUgS2V5U3RvcmVTcGl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGVudHJpZXMgc3RvcmVkIGluIHRoaXMge0Bjb2RlIEtleVN0b3JlU3BpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGVuZ2luZVNpemUoKTsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgYWxpYXMgaXMgYXNzb2NpYXRlZCB3aXRoIGVpdGhlciBhCisgICAgICoge0BsaW5rIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeX0gb3IgYSB7QGxpbmsgS2V5U3RvcmUuU2VjcmV0S2V5RW50cnl9LgorICAgICAqCisgICAgICogQHBhcmFtIGFsaWFzCisgICAgICogICAgICAgICAgICB0aGUgYWxpYXMgb2YgYW4gZW50cnkuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGdpdmVuIGFsaWFzIGlzIGFzc29jaWF0ZWQgd2l0aCBhIGtleSBlbnRyeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBlbmdpbmVJc0tleUVudHJ5KFN0cmluZyBhbGlhcyk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGFsaWFzIGlzIGFzc29jaWF0ZWQgd2l0aCBhCisgICAgICoge0BsaW5rIEtleVN0b3JlLlRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGlhcworICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIG9mIGFuIGVudHJ5LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBnaXZlbiBhbGlhcyBpcyBhc3NvY2lhdGVkIHdpdGggYSBjZXJ0aWZpY2F0ZQorICAgICAqICAgICAgICAgZW50cnkuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZW5naW5lSXNDZXJ0aWZpY2F0ZUVudHJ5KFN0cmluZyBhbGlhcyk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhbGlhcyBhc3NvY2lhdGVkIHdpdGggdGhlIGZpcnN0IGVudHJ5IHdob3NlIGNlcnRpZmljYXRlCisgICAgICogbWF0Y2hlcyB0aGUgc3BlY2lmaWVkIGNlcnRpZmljYXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGNlcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZSB0byBmaW5kIHRoZSBhc3NvY2lhdGVkIGVudHJ5J3MgYWxpYXMgZm9yLgorICAgICAqIEByZXR1cm4gdGhlIGFsaWFzIG9yIHtAY29kZSBudWxsfSBpZiBubyBlbnRyeSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIGNlcnRpZmljYXRlIGNhbiBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGVuZ2luZUdldENlcnRpZmljYXRlQWxpYXMoQ2VydGlmaWNhdGUgY2VydCk7CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhpcyB7QGNvZGUgS2V5U3RvcmVTcGl9IHRvIHRoZSBzcGVjaWZpZWQge0Bjb2RlIE91dHB1dFN0cmVhbX0uCisgICAgICogVGhlIGRhdGEgd3JpdHRlbiB0byB0aGUge0Bjb2RlIE91dHB1dFN0cmVhbX0gaXMgcHJvdGVjdGVkIGJ5IHRoZQorICAgICAqIHNwZWNpZmllZCBwYXNzd29yZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT3V0cHV0U3RyZWFtfSB0byB3cml0ZSB0aGUgc3RvcmUncyBkYXRhIHRvLgorICAgICAqIEBwYXJhbSBwYXNzd29yZAorICAgICAqICAgICAgICAgICAgdGhlIHBhc3N3b3JkIHRvIHByb3RlY3QgdGhlIGRhdGEuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnJlZCB3aGlsZSB3cml0aW5nIHRvIHRoZSBzdHJlYW0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcmVxdWlyZWQgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhbiBleGNlcHRpb24gb2NjdXJyZWQgd2hpbGUgc3RvcmluZyB0aGUgY2VydGlmaWNhdGVzCisgICAgICogICAgICAgICAgICAgb2YgdGhpcyBjb2RlIHtAY29kZSBLZXlTdG9yZVNwaX0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZW5naW5lU3RvcmUoT3V0cHV0U3RyZWFtIHN0cmVhbSwgY2hhcltdIHBhc3N3b3JkKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIENlcnRpZmljYXRlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU3RvcmVzIHRoaXMge0Bjb2RlIEtleVN0b3JlU3BpfSB1c2luZyB0aGUgc3BlY2lmaWVkIHtAY29kZQorICAgICAqIExvYWRTdG9yZVBhcmFtZXRlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgTG9hZFN0b3JlUGFyYW1ldGVyfSB0aGF0IHNwZWNpZmllcyBob3cgdG8gc3RvcmUKKyAgICAgKiAgICAgICAgICAgIHRoaXMge0Bjb2RlIEtleVN0b3JlU3BpfSwgbWF5YmUge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHByb2JsZW0gb2NjdXJyZWQgd2hpbGUgd3JpdGluZyB0byB0aGUgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHJlcXVpcmVkIGFsZ29yaXRobSBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgYW4gZXhjZXB0aW9uIG9jY3VycmVkIHdoaWxlIHN0b3JpbmcgdGhlIGNlcnRpZmljYXRlcworICAgICAqICAgICAgICAgICAgIG9mIHRoaXMgY29kZSB7QGNvZGUgS2V5U3RvcmVTcGl9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIHtAbGluayBLZXlTdG9yZS5Mb2FkU3RvcmVQYXJhbWV0ZXJ9IGlzIG5vdAorICAgICAqICAgICAgICAgICAgIHJlY29nbml6ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZW5naW5lU3RvcmUoS2V5U3RvcmUuTG9hZFN0b3JlUGFyYW1ldGVyIHBhcmFtKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9hZHMgdGhpcyB7QGNvZGUgS2V5U3RvcmVTcGl9IGZyb20gdGhlIGdpdmVuIHtAY29kZSBJbnB1dFN0cmVhbX0uCisgICAgICogVXRpbGl6ZXMgdGhlIGdpdmVuIHBhc3N3b3JkIHRvIHZlcmlmeSB0aGUgc3RvcmVkIGRhdGEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyZWFtCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIElucHV0U3RyZWFtfSB0byBsb2FkIHRoaXMge0Bjb2RlIEtleVN0b3JlU3BpfSdzCisgICAgICogICAgICAgICAgICBkYXRhIGZyb20uCisgICAgICogQHBhcmFtIHBhc3N3b3JkCisgICAgICogICAgICAgICAgICB0aGUgcGFzc3dvcmQgdG8gdmVyaWZ5IHRoZSBzdG9yZWQgZGF0YSwgbWF5YmUge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHByb2JsZW0gb2NjdXJyZWQgd2hpbGUgcmVhZGluZyBmcm9tIHRoZSBzdHJlYW0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcmVxdWlyZWQgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhbiBleGNlcHRpb24gb2NjdXJyZWQgd2hpbGUgbG9hZGluZyB0aGUgY2VydGlmaWNhdGVzCisgICAgICogICAgICAgICAgICAgb2YgdGhpcyBjb2RlIHtAY29kZSBLZXlTdG9yZVNwaX0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZW5naW5lTG9hZChJbnB1dFN0cmVhbSBzdHJlYW0sIGNoYXJbXSBwYXNzd29yZCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIExvYWRzIHRoaXMge0Bjb2RlIEtleVN0b3JlU3BpfSB1c2luZyB0aGUgc3BlY2lmaWVkIHtAY29kZQorICAgICAqIExvYWRTdG9yZVBhcmFtZXRlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgTG9hZFN0b3JlUGFyYW1ldGVyfSB0aGF0IHNwZWNpZmllcyBob3cgdG8gbG9hZCB0aGlzCisgICAgICogICAgICAgICAgICB7QGNvZGUgS2V5U3RvcmVTcGl9LCBtYXliZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnJlZCB3aGlsZSByZWFkaW5nIGZyb20gdGhlIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSByZXF1aXJlZCBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGFuIGV4Y2VwdGlvbiBvY2N1cnJlZCB3aGlsZSBsb2FkaW5nIHRoZSBjZXJ0aWZpY2F0ZXMKKyAgICAgKiAgICAgICAgICAgICBvZiB0aGlzIGNvZGUge0Bjb2RlIEtleVN0b3JlU3BpfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBnaXZlbiB7QGxpbmsgS2V5U3RvcmUuTG9hZFN0b3JlUGFyYW1ldGVyfSBpcyBub3QKKyAgICAgKiAgICAgICAgICAgICByZWNvZ25pemVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVuZ2luZUxvYWQoS2V5U3RvcmUuTG9hZFN0b3JlUGFyYW1ldGVyIHBhcmFtKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBhcmFtID09IG51bGwpIHsKKyAgICAgICAgICAgIGVuZ2luZUxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgY2hhcltdIHB3ZDsKKyAgICAgICAgS2V5U3RvcmUuUHJvdGVjdGlvblBhcmFtZXRlciBwcCA9IHBhcmFtLmdldFByb3RlY3Rpb25QYXJhbWV0ZXIoKTsKKyAgICAgICAgaWYgKHBwIGluc3RhbmNlb2YgS2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHB3ZCA9ICgoS2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uKSBwcCkuZ2V0UGFzc3dvcmQoKTsKKyAgICAgICAgICAgICAgICBlbmdpbmVMb2FkKG51bGwsIHB3ZCk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChwcCBpbnN0YW5jZW9mIEtleVN0b3JlLkNhbGxiYWNrSGFuZGxlclByb3RlY3Rpb24pIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHdkID0gZ2V0UGFzc3dvcmRGcm9tQ2FsbEJhY2socHApOworICAgICAgICAgICAgICAgIGVuZ2luZUxvYWQobnVsbCwgcHdkKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9IGNhdGNoIChVbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJwcm90ZWN0aW9uUGFyYW1ldGVyIGlzIG5laXRoZXIgUGFzc3dvcmRQcm90ZWN0aW9uICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIm5vciBDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uIGluc3RhbmNlIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIEVudHJ5fSB3aXRoIHRoZSBnaXZlbiBhbGlhcywgdXNpbmcgdGhlIHNwZWNpZmllZAorICAgICAqIHtAY29kZSBQcm90ZWN0aW9uUGFyYW1ldGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGlhcworICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIG9mIHRoZSByZXF1ZXN0ZWQgZW50cnkuCisgICAgICogQHBhcmFtIHByb3RQYXJhbQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBQcm90ZWN0aW9uUGFyYW1ldGVyfSwgdXNlZCB0byBwcm90ZWN0IHRoZSByZXF1ZXN0ZWQKKyAgICAgKiAgICAgICAgICAgIGVudHJ5LCBtYXliZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHJldHVybiBoZSB7QGNvZGUgRW50cnl9IHdpdGggdGhlIGdpdmVuIGFsaWFzLCB1c2luZyB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICB7QGNvZGUgUHJvdGVjdGlvblBhcmFtZXRlcn0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcmVxdWlyZWQgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBVbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZW50cnkgY2FuIG5vdCBiZSByZWNvdmVyZWQuCisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgb3BlcmF0aW9uIGZhaWxzCisgICAgICovCisgICAgcHVibGljIEtleVN0b3JlLkVudHJ5IGVuZ2luZUdldEVudHJ5KFN0cmluZyBhbGlhcywKKyAgICAgICAgICAgIEtleVN0b3JlLlByb3RlY3Rpb25QYXJhbWV0ZXIgcHJvdFBhcmFtKSB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIFVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghZW5naW5lQ29udGFpbnNBbGlhcyhhbGlhcykpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGlmIChlbmdpbmVJc0NlcnRpZmljYXRlRW50cnkoYWxpYXMpKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEtleVN0b3JlLlRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5KAorICAgICAgICAgICAgICAgICAgICBlbmdpbmVHZXRDZXJ0aWZpY2F0ZShhbGlhcykpOworICAgICAgICB9CisgICAgICAgIGNoYXJbXSBwYXNzVyA9IG51bGw7CisgICAgICAgIGlmIChwcm90UGFyYW0gIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKHByb3RQYXJhbSBpbnN0YW5jZW9mIEtleVN0b3JlLlBhc3N3b3JkUHJvdGVjdGlvbikgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHBhc3NXID0gKChLZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb24pIHByb3RQYXJhbSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0UGFzc3dvcmQoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEtleVN0b3JlRXhjZXB0aW9uKCJQYXNzd29yZCB3YXMgZGVzdHJveWVkIiwgZWUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAocHJvdFBhcmFtIGluc3RhbmNlb2YgS2V5U3RvcmUuQ2FsbGJhY2tIYW5kbGVyUHJvdGVjdGlvbikgeworICAgICAgICAgICAgICAgIHBhc3NXID0gZ2V0UGFzc3dvcmRGcm9tQ2FsbEJhY2socHJvdFBhcmFtKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvbigiUHJvdGVjdGlvblBhcmFtZXRlciBvYmplY3QgaXMgbm90ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIlBhc3N3b3JkUHJvdGVjdGlvbjogIiArIHByb3RQYXJhbSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVuZ2luZUlzS2V5RW50cnkoYWxpYXMpKSB7CisgICAgICAgICAgICBLZXkga2V5ID0gZW5naW5lR2V0S2V5KGFsaWFzLCBwYXNzVyk7CisgICAgICAgICAgICBpZiAoa2V5IGluc3RhbmNlb2YgUHJpdmF0ZUtleSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5KChQcml2YXRlS2V5KSBrZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5naW5lR2V0Q2VydGlmaWNhdGVDaGFpbihhbGlhcykpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGtleSBpbnN0YW5jZW9mIFNlY3JldEtleSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgS2V5U3RvcmUuU2VjcmV0S2V5RW50cnkoKFNlY3JldEtleSkga2V5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKCJVbmtub3duIEtleVN0b3JlLkVudHJ5IG9iamVjdCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0b3JlcyB0aGUgZ2l2ZW4ge0Bjb2RlIEVudHJ5fSBpbiB0aGlzIHtAY29kZSBLZXlTdG9yZVNwaX0gYW5kIGFzc29jaWF0ZXMKKyAgICAgKiB0aGUgZW50cnkgd2l0aCB0aGUgZ2l2ZW4ge0Bjb2RlIGFsaWFzfS4gVGhlIGVudHJ5IGlzIHByb3RlY3RlZCBieSB0aGUKKyAgICAgKiBzcGVjaWZpZWQge0Bjb2RlIFByb3RlY3Rpb25QYXJhbWV0ZXJ9LgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBzcGVjaWZpZWQgYWxpYXMgYWxyZWFkeSBleGlzdHMsIGl0IHdpbGwgYmUgcmVhc3NpZ25lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGlhcworICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIGZvciB0aGUgZW50cnkuCisgICAgICogQHBhcmFtIGVudHJ5CisgICAgICogICAgICAgICAgICB0aGUgZW50cnkgdG8gc3RvcmUuCisgICAgICogQHBhcmFtIHByb3RQYXJhbQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBQcm90ZWN0aW9uUGFyYW1ldGVyfSB0byBwcm90ZWN0IHRoZSBlbnRyeS4KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBvcGVyYXRpb24gZmFpbHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZW5naW5lU2V0RW50cnkoU3RyaW5nIGFsaWFzLCBLZXlTdG9yZS5FbnRyeSBlbnRyeSwKKyAgICAgICAgICAgIEtleVN0b3JlLlByb3RlY3Rpb25QYXJhbWV0ZXIgcHJvdFBhcmFtKSB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEtleVN0b3JlRXhjZXB0aW9uKCJlbnRyeSA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZW5naW5lQ29udGFpbnNBbGlhcyhhbGlhcykpIHsKKyAgICAgICAgICAgIGVuZ2luZURlbGV0ZUVudHJ5KGFsaWFzKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIEtleVN0b3JlLlRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5KSB7CisgICAgICAgICAgICBLZXlTdG9yZS5UcnVzdGVkQ2VydGlmaWNhdGVFbnRyeSB0ckUgPSAoS2V5U3RvcmUuVHJ1c3RlZENlcnRpZmljYXRlRW50cnkpIGVudHJ5OworICAgICAgICAgICAgZW5naW5lU2V0Q2VydGlmaWNhdGVFbnRyeShhbGlhcywgdHJFLmdldFRydXN0ZWRDZXJ0aWZpY2F0ZSgpKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGNoYXJbXSBwYXNzVyA9IG51bGw7CisgICAgICAgIGlmIChwcm90UGFyYW0gaW5zdGFuY2VvZiBLZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb24pIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcGFzc1cgPSAoKEtleVN0b3JlLlBhc3N3b3JkUHJvdGVjdGlvbikgcHJvdFBhcmFtKS5nZXRQYXNzd29yZCgpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEtleVN0b3JlRXhjZXB0aW9uKCJQYXNzd29yZCB3YXMgZGVzdHJveWVkIiwgZWUpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKHByb3RQYXJhbSBpbnN0YW5jZW9mIEtleVN0b3JlLkNhbGxiYWNrSGFuZGxlclByb3RlY3Rpb24pIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBwYXNzVyA9IGdldFBhc3N3b3JkRnJvbUNhbGxCYWNrKHByb3RQYXJhbSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEtleVN0b3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEtleVN0b3JlRXhjZXB0aW9uKCJwcm90UGFyYW0gc2hvdWxkIGJlIFBhc3N3b3JkUHJvdGVjdGlvbiBvciAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIkNhbGxiYWNrSGFuZGxlclByb3RlY3Rpb24iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSkgeworICAgICAgICAgICAgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5IHByRSA9IChLZXlTdG9yZS5Qcml2YXRlS2V5RW50cnkpIGVudHJ5OworICAgICAgICAgICAgZW5naW5lU2V0S2V5RW50cnkoYWxpYXMsIHByRS5nZXRQcml2YXRlS2V5KCksIHBhc3NXLCBwckUKKyAgICAgICAgICAgICAgICAgICAgLmdldENlcnRpZmljYXRlQ2hhaW4oKSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBLZXlTdG9yZS5TZWNyZXRLZXlFbnRyeSkgeworICAgICAgICAgICAgS2V5U3RvcmUuU2VjcmV0S2V5RW50cnkgc2tFID0gKEtleVN0b3JlLlNlY3JldEtleUVudHJ5KSBlbnRyeTsKKyAgICAgICAgICAgIGVuZ2luZVNldEtleUVudHJ5KGFsaWFzLCBza0UuZ2V0U2VjcmV0S2V5KCksIHBhc3NXLCBudWxsKTsKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgZW5naW5lU2V0S2V5RW50cnkoYWxpYXMsIHNrRS5nZXRTZWNyZXRLZXkoKS5nZXRFbmNvZGVkKCksIG51bGwpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgdGhyb3cgbmV3IEtleVN0b3JlRXhjZXB0aW9uKCJFbnRyeSBvYmplY3QgaXMgbmVpdGhlciBQcml2YXRlS2V5T2JqZWN0IG5vciBTZWNyZXRLZXlFbnRyeSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJub3IgVHJ1c3RlZENlcnRpZmljYXRlRW50cnk6ICIgKyBlbnRyeSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGVudHJ5IGZvciB0aGUgZ2l2ZW4gYWxpYXMgaXMgYXNzaWduYWJsZSB0byB0aGUKKyAgICAgKiBwcm92aWRlZCB7QGNvZGUgQ2xhc3N9LgorICAgICAqCisgICAgICogQHBhcmFtIGFsaWFzCisgICAgICogICAgICAgICAgICB0aGUgYWxpYXMgZm9yIHRoZSBlbnRyeS4KKyAgICAgKiBAcGFyYW0gZW50cnlDbGFzcworICAgICAqICAgICAgICAgICAgdGhlIHR5cGUgb2YgdGhlIGVudHJ5LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSB7QGNvZGUgRW50cnl9IGZvciB0aGUgYWxpYXMgaXMgYXNzaWduYWJsZSB0bworICAgICAqICAgICAgICAgdGhlIHNwZWNpZmllZCB7QGNvZGUgZW50cnlDbGFzc30uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZW5naW5lRW50cnlJbnN0YW5jZU9mKFN0cmluZyBhbGlhcywKKyAgICAgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBLZXlTdG9yZS5FbnRyeT4gZW50cnlDbGFzcykgeworICAgICAgICBpZiAoIWVuZ2luZUNvbnRhaW5zQWxpYXMoYWxpYXMpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGVuZ2luZUlzQ2VydGlmaWNhdGVFbnRyeShhbGlhcykpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZW50cnlDbGFzcworICAgICAgICAgICAgICAgICAgICAgICAgLmlzQXNzaWduYWJsZUZyb20oQ2xhc3MKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZvck5hbWUoImphdmEuc2VjdXJpdHkuS2V5U3RvcmUkVHJ1c3RlZENlcnRpZmljYXRlRW50cnkiKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChlbmdpbmVJc0tleUVudHJ5KGFsaWFzKSkgeworICAgICAgICAgICAgICAgIGlmIChlbnRyeUNsYXNzLmlzQXNzaWduYWJsZUZyb20oQ2xhc3MKKyAgICAgICAgICAgICAgICAgICAgICAgIC5mb3JOYW1lKCJqYXZhLnNlY3VyaXR5LktleVN0b3JlJFByaXZhdGVLZXlFbnRyeSIpKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW5naW5lR2V0Q2VydGlmaWNhdGUoYWxpYXMpICE9IG51bGw7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGVudHJ5Q2xhc3MuaXNBc3NpZ25hYmxlRnJvbShDbGFzcworICAgICAgICAgICAgICAgICAgICAgICAgLmZvck5hbWUoImphdmEuc2VjdXJpdHkuS2V5U3RvcmUkU2VjcmV0S2V5RW50cnkiKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVuZ2luZUdldENlcnRpZmljYXRlKGFsaWFzKSA9PSBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBpZ25vcmUpIHt9CisKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qCisgICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBwYXNzd29yZCB3aGljaCBpcyBlbmNhcHN1bGF0ZWQgaW4KKyAgICAgKiBDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uIG9iamVjdCBJZiB0aGVyZSBpcyBubyBpbXBsZW1lbnRhdGlvbiBvZgorICAgICAqIENhbGxiYWNrSGFuZGxlciB0aGVuIHRoaXMgbWV0aG9kIHJldHVybnMgbnVsbAorICAgICAqLworICAgIHN0YXRpYyBjaGFyW10gZ2V0UGFzc3dvcmRGcm9tQ2FsbEJhY2soS2V5U3RvcmUuUHJvdGVjdGlvblBhcmFtZXRlciBwcm90UGFyYW0pCisgICAgICAgICAgICB0aHJvd3MgVW5yZWNvdmVyYWJsZUVudHJ5RXhjZXB0aW9uIHsKKworICAgICAgICBpZiAocHJvdFBhcmFtID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCEocHJvdFBhcmFtIGluc3RhbmNlb2YgS2V5U3RvcmUuQ2FsbGJhY2tIYW5kbGVyUHJvdGVjdGlvbikpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb24oIkluY29ycmVjdCBQcm90ZWN0aW9uUGFyYW1ldGVyIik7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgY2xOYW1lID0gU2VjdXJpdHkuZ2V0UHJvcGVydHkoImF1dGgubG9naW4uZGVmYXVsdENhbGxiYWNrSGFuZGxlciIpOworICAgICAgICBpZiAoY2xOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb24oIkRlZmF1bHQgQ2FsbGJhY2tIYW5kbGVyIHdhcyBub3QgZGVmaW5lZCIpOworCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3M8Pz4gY2wgPSBDbGFzcy5mb3JOYW1lKGNsTmFtZSk7CisgICAgICAgICAgICBDYWxsYmFja0hhbmRsZXIgY2JIYW5kID0gKENhbGxiYWNrSGFuZGxlcikgY2wubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgICAgIFBhc3N3b3JkQ2FsbGJhY2tbXSBwd0NiID0geyBuZXcgUGFzc3dvcmRDYWxsYmFjaygicGFzc3dvcmQ6ICIsIHRydWUpIH07CisgICAgICAgICAgICBjYkhhbmQuaGFuZGxlKHB3Q2IpOworICAgICAgICAgICAgcmV0dXJuIHB3Q2JbMF0uZ2V0UGFzc3dvcmQoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb24oZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L01lc3NhZ2VEaWdlc3QuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L01lc3NhZ2VEaWdlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMTU0MDI4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdC5qYXZhCkBAIC0wLDAgKzEsNDMxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5mb3J0cmVzcy5FbmdpbmU7CisKKy8qKgorICogVXNlcyBhIG9uZS13YXkgaGFzaCBmdW5jdGlvbiB0byB0dXJuIGFuIGFyYml0cmFyeSBudW1iZXIgb2YgYnl0ZXMgaW50byBhCisgKiBmaXhlZC1sZW5ndGggYnl0ZSBzZXF1ZW5jZS4gVGhlIG9yaWdpbmFsIGFyYml0cmFyeS1sZW5ndGggc2VxdWVuY2UgaXMgdGhlCisgKiA8aT5tZXNzYWdlPC9pPiwgYW5kIHRoZSBmaXhlZC1sZW5ndGggYnl0ZSBzZXF1ZW5jZSBpcyB0aGUgPGk+ZGlnZXN0PC9pPiBvcgorICogPGk+bWVzc2FnZSBkaWdlc3Q8L2k+LgorICoKKyAqIDxoND5TYW1wbGUgQ29kZTwvaDQ+CisgKiA8cD5UaGUgYmFzaWMgcGF0dGVybiB0byBkaWdlc3QgYW4ge0BsaW5rIGphdmEuaW8uSW5wdXRTdHJlYW19IGxvb2tzIGxpa2UgdGhpczoKKyAqIDxwcmU+CisgKiAgTWVzc2FnZURpZ2VzdCBkaWdlc3RlciA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoIk1ENSIpOworICogIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlWzgxOTJdOworICogIGludCBieXRlQ291bnQ7CisgKiAgd2hpbGUgKChieXRlQ291bnQgPSBpbi5yZWFkKGJ5dGVzKSkgPiAwKSB7CisgKiAgICBkaWdlc3Rlci51cGRhdGUoYnl0ZXMsIDAsIGJ5dGVDb3VudCk7CisgKiAgfQorICogIGJ5dGVbXSBkaWdlc3QgPSBkaWdlc3Rlci5kaWdlc3QoKTsKKyAqIDwvcHJlPgorICoKKyAqIDxwPlRoYXQgaXMsIGFmdGVyIGNyZWF0aW5nIG9yIHJlc2V0dGluZyBhIHtAY29kZSBNZXNzYWdlRGlnZXN0fSB5b3Ugc2hvdWxkCisgKiBjYWxsIHtAbGluayAjdXBkYXRlKGJ5dGVbXSxpbnQsaW50KX0gZm9yIGVhY2ggYmxvY2sgb2YgaW5wdXQgZGF0YSwgYW5kIHRoZW4gY2FsbCB7QGxpbmsgI2RpZ2VzdH0KKyAqIHRvIGdldCB0aGUgZmluYWwgZGlnZXN0LiBOb3RlIHRoYXQgY2FsbGluZyB7QGNvZGUgZGlnZXN0fSByZXNldHMgdGhlIHtAY29kZSBNZXNzYWdlRGlnZXN0fS4KKyAqIEFkdmFuY2VkIHVzZXJzIHdobyB3YW50IHBhcnRpYWwgZGlnZXN0cyBzaG91bGQgY2xvbmUgdGhlaXIge0Bjb2RlIE1lc3NhZ2VEaWdlc3R9IGJlZm9yZQorICogY2FsbGluZyB7QGNvZGUgZGlnZXN0fS4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGlzIG5vdCB0aHJlYWQtc2FmZS4KKyAqCisgKiBAc2VlIE1lc3NhZ2VEaWdlc3RTcGkKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIE1lc3NhZ2VEaWdlc3QgZXh0ZW5kcyBNZXNzYWdlRGlnZXN0U3BpIHsKKworICAgIC8vIFVzZWQgdG8gYWNjZXNzIGNvbW1vbiBlbmdpbmUgZnVuY3Rpb25hbGl0eQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEVuZ2luZSBFTkdJTkUgPSBuZXcgRW5naW5lKCJNZXNzYWdlRGlnZXN0Iik7CisKKyAgICAvLyBUaGUgcHJvdmlkZXIKKyAgICBwcml2YXRlIFByb3ZpZGVyIHByb3ZpZGVyOworCisgICAgLy8gVGhlIGFsZ29yaXRobS4KKyAgICBwcml2YXRlIFN0cmluZyBhbGdvcml0aG07CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBNZXNzYWdlRGlnZXN0fSB3aXRoIHRoZSBuYW1lIG9mCisgICAgICogdGhlIGFsZ29yaXRobSB0byB1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiBhbGdvcml0aG0gdG8gdXNlCisgICAgICovCisgICAgcHJvdGVjdGVkIE1lc3NhZ2VEaWdlc3QoU3RyaW5nIGFsZ29yaXRobSkgeworICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBNZXNzYWdlRGlnZXN0fSB0aGF0IHV0aWxpemVzIHRoZQorICAgICAqIHNwZWNpZmllZCBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtIHRvIHVzZQorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIE1lc3NhZ2VEaWdlc3R9IHRoYXQgdXRpbGl6ZXMgdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgYWxnb3JpdGhtCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobSBpcyBub3QgYXZhaWxhYmxlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhbGdvcml0aG19IGlzIHtAY29kZSBudWxsfQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTWVzc2FnZURpZ2VzdCBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhbGdvcml0aG0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgRW5naW5lLlNwaUFuZFByb3ZpZGVyIHNhcCA9IEVOR0lORS5nZXRJbnN0YW5jZShhbGdvcml0aG0sIG51bGwpOworICAgICAgICBPYmplY3Qgc3BpID0gc2FwLnNwaTsKKyAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIgPSBzYXAucHJvdmlkZXI7CisgICAgICAgIGlmIChzcGkgaW5zdGFuY2VvZiBNZXNzYWdlRGlnZXN0KSB7CisgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IHJlc3VsdCA9IChNZXNzYWdlRGlnZXN0KSBzcGk7CisgICAgICAgICAgICByZXN1bHQuYWxnb3JpdGhtID0gYWxnb3JpdGhtOworICAgICAgICAgICAgcmVzdWx0LnByb3ZpZGVyID0gcHJvdmlkZXI7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgTWVzc2FnZURpZ2VzdEltcGwoKE1lc3NhZ2VEaWdlc3RTcGkpIHNhcC5zcGksIHNhcC5wcm92aWRlciwgYWxnb3JpdGhtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBNZXNzYWdlRGlnZXN0fSB0aGF0IHV0aWxpemVzIHRoZQorICAgICAqIHNwZWNpZmllZCBhbGdvcml0aG0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobSB0byB1c2UKKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBwcm92aWRlcgorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIE1lc3NhZ2VEaWdlc3R9IHRoYXQgdXRpbGl6ZXMgdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgYWxnb3JpdGhtIGZyb20gdGhlIHNwZWNpZmllZCBwcm92aWRlcgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZQorICAgICAqIEB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGlzIG5vdCBhdmFpbGFibGUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFsZ29yaXRobX0gaXMge0Bjb2RlIG51bGx9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHByb3ZpZGVyID09IG51bGwgfHwgcHJvdmlkZXIuaXNFbXB0eSgpfQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTWVzc2FnZURpZ2VzdCBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwcm92aWRlciA9PSBudWxsIHx8IHByb3ZpZGVyLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIFByb3ZpZGVyIHAgPSBTZWN1cml0eS5nZXRQcm92aWRlcihwcm92aWRlcik7CisgICAgICAgIGlmIChwID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbihwcm92aWRlcik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEluc3RhbmNlKGFsZ29yaXRobSwgcCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgTWVzc2FnZURpZ2VzdH0gdGhhdCB1dGlsaXplcyB0aGUKKyAgICAgKiBzcGVjaWZpZWQgYWxnb3JpdGhtIGZyb20gdGhlIHNwZWNpZmllZCBwcm92aWRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0gdG8gdXNlCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgcHJvdmlkZXIKKyAgICAgKiBAcmV0dXJuIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBNZXNzYWdlRGlnZXN0fSB0aGF0IHV0aWxpemVzIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIGFsZ29yaXRobSBmcm9tIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFsZ29yaXRobX0gaXMge0Bjb2RlIG51bGx9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHByb3ZpZGVyID09IG51bGx9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBNZXNzYWdlRGlnZXN0IGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwcm92aWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFsZ29yaXRobSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBPYmplY3Qgc3BpID0gRU5HSU5FLmdldEluc3RhbmNlKGFsZ29yaXRobSwgcHJvdmlkZXIsIG51bGwpOworICAgICAgICBpZiAoc3BpIGluc3RhbmNlb2YgTWVzc2FnZURpZ2VzdCkgeworICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCByZXN1bHQgPSAoTWVzc2FnZURpZ2VzdCkgc3BpOworICAgICAgICAgICAgcmVzdWx0LmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICAgICAgICAgIHJlc3VsdC5wcm92aWRlciA9IHByb3ZpZGVyOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VEaWdlc3RJbXBsKChNZXNzYWdlRGlnZXN0U3BpKSBzcGksIHByb3ZpZGVyLCBhbGdvcml0aG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFB1dHMgdGhpcyB7QGNvZGUgTWVzc2FnZURpZ2VzdH0gYmFjayBpbiBhbiBpbml0aWFsIHN0YXRlLCBzdWNoIHRoYXQgaXQgaXMKKyAgICAgKiByZWFkeSB0byBjb21wdXRlIGEgb25lIHdheSBoYXNoIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgICAgICBlbmdpbmVSZXNldCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhpcyB7QGNvZGUgTWVzc2FnZURpZ2VzdH0gdXNpbmcgdGhlIGdpdmVuIHtAY29kZSBieXRlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmcwCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGJ5dGV9IHRvIHVwZGF0ZSB0aGlzIHtAY29kZSBNZXNzYWdlRGlnZXN0fSB3aXRoCisgICAgICogQHNlZSAjcmVzZXQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZShieXRlIGFyZzApIHsKKyAgICAgICAgZW5naW5lVXBkYXRlKGFyZzApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhpcyB7QGNvZGUgTWVzc2FnZURpZ2VzdH0gdXNpbmcgdGhlIGdpdmVuIHtAY29kZSBieXRlW119LgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGJ5dGV9IGFycmF5CisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBieXRlIGluIHtAY29kZSBpbnB1dH0gdG8gdXBkYXRlIGZyb20KKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIGluIHtAY29kZSBpbnB1dH0gdG8gdXBkYXRlIGZyb20KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXR9IG9yIHtAY29kZSBsZW59IGFyZSBub3QgdmFsaWQgaW4gcmVzcGVjdCB0bworICAgICAqICAgICAgICAgICAgIHtAY29kZSBpbnB1dH0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGUoYnl0ZVtdIGlucHV0LCBpbnQgb2Zmc2V0LCBpbnQgbGVuKSB7CisgICAgICAgIGlmIChpbnB1dCA9PSBudWxsIHx8CisgICAgICAgIC8vIG9mZnNldCA8IDAgfHwgbGVuIDwgMCB8fAorICAgICAgICAgICAgICAgIC8vIGNoZWNrcyBmb3IgbmVnYXRpdmUgdmFsdWVzIGFyZSBjb21tZW50ZWQgb3V0IGludGVudGlvbmFsbHkKKyAgICAgICAgICAgICAgICAvLyBzZWUgSEFSTU9OWS0xMTIwIGZvciBkZXRhaWxzCisgICAgICAgICAgICAgICAgKGxvbmcpIG9mZnNldCArIChsb25nKSBsZW4gPiBpbnB1dC5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBlbmdpbmVVcGRhdGUoaW5wdXQsIG9mZnNldCwgbGVuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoaXMge0Bjb2RlIE1lc3NhZ2VEaWdlc3R9IHVzaW5nIHRoZSBnaXZlbiB7QGNvZGUgYnl0ZVtdfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBieXRlfSBhcnJheQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW5wdXR9IGlzIHtAY29kZSBudWxsfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZShieXRlW10gaW5wdXQpIHsKKyAgICAgICAgaWYgKGlucHV0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGVuZ2luZVVwZGF0ZShpbnB1dCwgMCwgaW5wdXQubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlcyBhbmQgcmV0dXJucyB0aGUgZmluYWwgaGFzaCB2YWx1ZSBmb3IgdGhpcyB7QGxpbmsgTWVzc2FnZURpZ2VzdH0uCisgICAgICogQWZ0ZXIgdGhlIGRpZ2VzdCBpcyBjb21wdXRlZCB0aGUgcmVjZWl2ZXIgaXMgcmVzZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb21wdXRlZCBvbmUgd2F5IGhhc2ggdmFsdWUKKyAgICAgKiBAc2VlICNyZXNldAorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZGlnZXN0KCkgeworICAgICAgICByZXR1cm4gZW5naW5lRGlnZXN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZXMgYW5kIHN0b3JlcyB0aGUgZmluYWwgaGFzaCB2YWx1ZSBmb3IgdGhpcyB7QGxpbmsgTWVzc2FnZURpZ2VzdH0uCisgICAgICogQWZ0ZXIgdGhlIGRpZ2VzdCBpcyBjb21wdXRlZCB0aGUgcmVjZWl2ZXIgaXMgcmVzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHRvIHN0b3JlIHRoZSByZXN1bHQKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGJ5dGUgaW4ge0Bjb2RlIGJ1Zn0gdG8gc3RvcmUKKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFsbG9jYXRlZCBmb3IgdGhlIGRpZ2VzdAorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuIHRvIHtAY29kZSBidWZ9CisgICAgICogQHRocm93cyBEaWdlc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXR9IG9yIHtAY29kZSBsZW59IGFyZSBub3QgdmFsaWQgaW4gcmVzcGVjdCB0bworICAgICAqICAgICAgICAgICAgIHtAY29kZSBidWZ9CisgICAgICogQHNlZSAjcmVzZXQoKQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZGlnZXN0KGJ5dGVbXSBidWYsIGludCBvZmZzZXQsIGludCBsZW4pIHRocm93cyBEaWdlc3RFeGNlcHRpb24geworICAgICAgICBpZiAoYnVmID09IG51bGwgfHwKKyAgICAgICAgLy8gb2Zmc2V0IDwgMCB8fCBsZW4gPCAwIHx8CisgICAgICAgICAgICAgICAgLy8gY2hlY2tzIGZvciBuZWdhdGl2ZSB2YWx1ZXMgYXJlIGNvbW1lbnRlZCBvdXQgaW50ZW50aW9uYWxseQorICAgICAgICAgICAgICAgIC8vIHNlZSBIQVJNT05ZLTExNDggZm9yIGRldGFpbHMKKyAgICAgICAgICAgICAgICAobG9uZykgb2Zmc2V0ICsgKGxvbmcpIGxlbiA+IGJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5naW5lRGlnZXN0KGJ1Ziwgb2Zmc2V0LCBsZW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIHRoZSBmaW5hbCB1cGRhdGUgYW5kIHRoZW4gY29tcHV0ZXMgYW5kIHJldHVybnMgdGhlIGZpbmFsIGhhc2gKKyAgICAgKiB2YWx1ZSBmb3IgdGhpcyB7QGxpbmsgTWVzc2FnZURpZ2VzdH0uIEFmdGVyIHRoZSBkaWdlc3QgaXMgY29tcHV0ZWQgdGhlCisgICAgICogcmVjZWl2ZXIgaXMgcmVzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgYnl0ZX0gYXJyYXkKKyAgICAgKiBAcmV0dXJuIHRoZSBjb21wdXRlZCBvbmUgd2F5IGhhc2ggdmFsdWUKKyAgICAgKiBAc2VlICNyZXNldCgpCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBkaWdlc3QoYnl0ZVtdIGlucHV0KSB7CisgICAgICAgIHVwZGF0ZShpbnB1dCk7CisgICAgICAgIHJldHVybiBkaWdlc3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGlzCisgICAgICoge0Bjb2RlIE1lc3NhZ2VEaWdlc3R9IGluY2x1ZGluZyB0aGUgbmFtZSBvZiBpdHMgYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHJldHVybiBhIHByaW50YWJsZSByZXByZXNlbnRhdGlvbiBmb3IgdGhpcyB7QGNvZGUgTWVzc2FnZURpZ2VzdH0KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gIk1FU1NBR0UgRElHRVNUICIgKyBhbGdvcml0aG07CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdG8gZGlnZXN0IGFyZSBlcXVhbCBieSBwZXJmb3JtaW5nIGEgc2ltcGx5CisgICAgICogYnl0ZS1wZXItYnl0ZSBjb21wYXJlIG9mIHRoZSB0d28gZGlnZXN0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkaWdlc3RhCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgZGlnZXN0IHRvIGJlIGNvbXBhcmVkCisgICAgICogQHBhcmFtIGRpZ2VzdGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgZGlnZXN0IHRvIGJlIGNvbXBhcmVkCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHR3byBoYXNoZXMgYXJlIGVxdWFsLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0VxdWFsKGJ5dGVbXSBkaWdlc3RhLCBieXRlW10gZGlnZXN0YikgeworICAgICAgICBpZiAoZGlnZXN0YS5sZW5ndGggIT0gZGlnZXN0Yi5sZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRpZ2VzdGEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChkaWdlc3RhW2ldICE9IGRpZ2VzdGJbaV0pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtIG9mIHRoaXMge0Bjb2RlIE1lc3NhZ2VEaWdlc3R9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtIG9mIHRoaXMge0Bjb2RlIE1lc3NhZ2VEaWdlc3R9CisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiBhbGdvcml0aG07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJvdmlkZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMge0Bjb2RlIE1lc3NhZ2VEaWdlc3R9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJvdmlkZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMge0Bjb2RlIE1lc3NhZ2VEaWdlc3R9CisgICAgICovCisgICAgcHVibGljIGZpbmFsIFByb3ZpZGVyIGdldFByb3ZpZGVyKCkgeworICAgICAgICByZXR1cm4gcHJvdmlkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5naW5lIGRpZ2VzdCBsZW5ndGggaW4gYnl0ZXMuIElmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdAorICAgICAqIGltcGxlbWVudCB0aGlzIGZ1bmN0aW9uIG9yIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgQ2xvbmVhYmxlfSwKKyAgICAgKiB7QGNvZGUgMH0gaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkaWdlc3QgbGVuZ3RoIGluIGJ5dGVzLCBvciB7QGNvZGUgMH0KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdldERpZ2VzdExlbmd0aCgpIHsKKyAgICAgICAgaW50IGwgPSBlbmdpbmVHZXREaWdlc3RMZW5ndGgoKTsKKyAgICAgICAgaWYgKGwgIT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIENsb25lYWJsZSkpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kID0gKE1lc3NhZ2VEaWdlc3QpIGNsb25lKCk7CisgICAgICAgICAgICByZXR1cm4gbWQuZGlnZXN0KCkubGVuZ3RoOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIENsb25lYWJsZSkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGlzIHtAY29kZSBNZXNzYWdlRGlnZXN0fSB1c2luZyB0aGUgZ2l2ZW4ge0Bjb2RlIGlucHV0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBCeXRlQnVmZmVyfQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHVwZGF0ZShCeXRlQnVmZmVyIGlucHV0KSB7CisgICAgICAgIGVuZ2luZVVwZGF0ZShpbnB1dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICoKKyAgICAgKiBUaGUgaW50ZXJuYWwgTWVzc2FnZURpZ2VzdCBpbXBsZW1lbnRhdGlvbgorICAgICAqCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTWVzc2FnZURpZ2VzdEltcGwgZXh0ZW5kcyBNZXNzYWdlRGlnZXN0IHsKKworICAgICAgICAvLyBNZXNzYWdlRGlnZXN0U3BpIGltcGxlbWVudGF0aW9uCisgICAgICAgIHByaXZhdGUgTWVzc2FnZURpZ2VzdFNwaSBzcGlJbXBsOworCisgICAgICAgIC8vIE1lc3NhZ2VEaWdlc3RJbXBsIGN0b3IKKyAgICAgICAgcHJpdmF0ZSBNZXNzYWdlRGlnZXN0SW1wbChNZXNzYWdlRGlnZXN0U3BpIG1lc3NhZ2VEaWdlc3RTcGksCisgICAgICAgICAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIsIFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgICAgIHN1cGVyKGFsZ29yaXRobSk7CisgICAgICAgICAgICBzdXBlci5wcm92aWRlciA9IHByb3ZpZGVyOworICAgICAgICAgICAgc3BpSW1wbCA9IG1lc3NhZ2VEaWdlc3RTcGk7CisgICAgICAgIH0KKworICAgICAgICAvLyBlbmdpbmVSZXNldCgpIGltcGxlbWVudGF0aW9uCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVSZXNldCgpIHsKKyAgICAgICAgICAgIHNwaUltcGwuZW5naW5lUmVzZXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGVuZ2luZURpZ2VzdCgpIGltcGxlbWVudGF0aW9uCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuZ2luZURpZ2VzdCgpIHsKKyAgICAgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZURpZ2VzdCgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gZW5naW5lR2V0RGlnZXN0TGVuZ3RoKCkgaW1wbGVtZW50YXRpb24KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBpbnQgZW5naW5lR2V0RGlnZXN0TGVuZ3RoKCkgeworICAgICAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lR2V0RGlnZXN0TGVuZ3RoKCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBlbmdpbmVVcGRhdGUoKSBpbXBsZW1lbnRhdGlvbgorICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGUgYXJnMCkgeworICAgICAgICAgICAgc3BpSW1wbC5lbmdpbmVVcGRhdGUoYXJnMCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBlbmdpbmVVcGRhdGUoKSBpbXBsZW1lbnRhdGlvbgorICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGVbXSBhcmcwLCBpbnQgYXJnMSwgaW50IGFyZzIpIHsKKyAgICAgICAgICAgIHNwaUltcGwuZW5naW5lVXBkYXRlKGFyZzAsIGFyZzEsIGFyZzIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gUmV0dXJucyBhIGNsb25lIGlmIHRoZSBzcGlJbXBsIGlzIGNsb25lYWJsZQorICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoc3BpSW1wbCBpbnN0YW5jZW9mIENsb25lYWJsZSkgeworICAgICAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3RTcGkgc3BpID0gKE1lc3NhZ2VEaWdlc3RTcGkpIHNwaUltcGwuY2xvbmUoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VEaWdlc3RJbXBsKHNwaSwgZ2V0UHJvdmlkZXIoKSwgZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L01lc3NhZ2VEaWdlc3RTcGkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L01lc3NhZ2VEaWdlc3RTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNjgyZDg2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdFNwaS5qYXZhCkBAIC0wLDAgKzEsMTUxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworCisvKioKKyAqIHtAY29kZSBNZXNzYWdlRGlnZXN0U3BpfSBpcyB0aGUgU2VydmljZSBQcm92aWRlciBJbnRlcmZhY2UgKFNQSSkgZGVmaW5pdGlvbgorICogZm9yIHtAbGluayBNZXNzYWdlRGlnZXN0fS4gRXhhbXBsZXMgb2YgZGlnZXN0IGFsZ29yaXRobXMgYXJlIE1ENSBhbmQgU0hBLiBBCisgKiBkaWdlc3QgaXMgYSBzZWN1cmUgb25lIHdheSBoYXNoIGZ1bmN0aW9uIGZvciBhIHN0cmVhbSBvZiBieXRlcy4gSXQgYWN0cyBsaWtlCisgKiBhIGZpbmdlcnByaW50IGZvciBhIHN0cmVhbSBvZiBieXRlcy4KKyAqCisgKiBAc2VlIE1lc3NhZ2VEaWdlc3QKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIE1lc3NhZ2VEaWdlc3RTcGkgeworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5naW5lIGRpZ2VzdCBsZW5ndGggaW4gYnl0ZXMuIElmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdAorICAgICAqIGltcGxlbWVudCB0aGlzIGZ1bmN0aW9uIHtAY29kZSAwfSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGRpZ2VzdCBsZW5ndGggaW4gYnl0ZXMsIG9yIHtAY29kZSAwfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGVuZ2luZUdldERpZ2VzdExlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGlzIHtAY29kZSBNZXNzYWdlRGlnZXN0U3BpfSB1c2luZyB0aGUgZ2l2ZW4ge0Bjb2RlIGJ5dGV9LgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGJ5dGV9IHRvIHVwZGF0ZSB0aGlzIHtAY29kZSBNZXNzYWdlRGlnZXN0U3BpfSB3aXRoLgorICAgICAqIEBzZWUgI2VuZ2luZVJlc2V0KCkKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZSBpbnB1dCk7CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoaXMge0Bjb2RlIE1lc3NhZ2VEaWdlc3RTcGl9IHVzaW5nIHRoZSBnaXZlbiB7QGNvZGUgYnl0ZVtdfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBieXRlfSBhcnJheS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGJ5dGUgaW4ge0Bjb2RlIGlucHV0fSB0byB1cGRhdGUgZnJvbS4KKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIGluIHtAY29kZSBpbnB1dH0gdG8gdXBkYXRlIGZyb20uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2Zmc2V0fSBvciB7QGNvZGUgbGVufSBhcmUgbm90IHZhbGlkIGluIHJlc3BlY3QgdG8KKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgaW5wdXR9LgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGVuZ2luZVVwZGF0ZShieXRlW10gaW5wdXQsIGludCBvZmZzZXQsIGludCBsZW4pOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGlzIHtAY29kZSBNZXNzYWdlRGlnZXN0U3BpfSB1c2luZyB0aGUgZ2l2ZW4ge0Bjb2RlIGlucHV0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBCeXRlQnVmZmVyfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVVcGRhdGUoQnl0ZUJ1ZmZlciBpbnB1dCkgeworICAgICAgICBpZiAoIWlucHV0Lmhhc1JlbWFpbmluZygpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIHRtcDsKKyAgICAgICAgaWYgKGlucHV0Lmhhc0FycmF5KCkpIHsKKyAgICAgICAgICAgIHRtcCA9IGlucHV0LmFycmF5KCk7CisgICAgICAgICAgICBpbnQgb2Zmc2V0ID0gaW5wdXQuYXJyYXlPZmZzZXQoKTsKKyAgICAgICAgICAgIGludCBwb3NpdGlvbiA9IGlucHV0LnBvc2l0aW9uKCk7CisgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5saW1pdCgpOworICAgICAgICAgICAgZW5naW5lVXBkYXRlKHRtcCwgb2Zmc2V0K3Bvc2l0aW9uLCBsaW1pdCAtIHBvc2l0aW9uKTsKKyAgICAgICAgICAgIGlucHV0LnBvc2l0aW9uKGxpbWl0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRtcCA9IG5ldyBieXRlW2lucHV0LmxpbWl0KCkgLSBpbnB1dC5wb3NpdGlvbigpXTsKKyAgICAgICAgICAgIGlucHV0LmdldCh0bXApOworICAgICAgICAgICAgZW5naW5lVXBkYXRlKHRtcCwgMCwgdG1wLmxlbmd0aCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlcyBhbmQgcmV0dXJucyB0aGUgZmluYWwgaGFzaCB2YWx1ZSBmb3IgdGhpcworICAgICAqIHtAbGluayBNZXNzYWdlRGlnZXN0U3BpfS4gQWZ0ZXIgdGhlIGRpZ2VzdCBpcyBjb21wdXRlZCB0aGUgcmVjZWl2ZXIgaXMKKyAgICAgKiByZXNldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNvbXB1dGVkIG9uZSB3YXkgaGFzaCB2YWx1ZS4KKyAgICAgKiBAc2VlICNlbmdpbmVSZXNldCgpCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IGJ5dGVbXSBlbmdpbmVEaWdlc3QoKTsKKworICAgIC8qKgorICAgICAqIENvbXB1dGVzIGFuZCBzdG9yZXMgdGhlIGZpbmFsIGhhc2ggdmFsdWUgZm9yIHRoaXMKKyAgICAgKiB7QGxpbmsgTWVzc2FnZURpZ2VzdFNwaX0uIEFmdGVyIHRoZSBkaWdlc3QgaXMgY29tcHV0ZWQgdGhlIHJlY2VpdmVyIGlzCisgICAgICogcmVzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHRvIHN0b3JlIHRoZSByZXN1bHQgaW4uCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBieXRlIGluIHtAY29kZSBidWZ9IHRvIHN0b3JlIGluLgorICAgICAqIEBwYXJhbSBsZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWxsb2NhdGVkIGZvciB0aGUgZGlnZXN0LgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuIHRvIHtAY29kZSBidWZ9LgorICAgICAqIEB0aHJvd3MgRGlnZXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJlcy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXR9IG9yIHtAY29kZSBsZW59IGFyZSBub3QgdmFsaWQgaW4gcmVzcGVjdCB0bworICAgICAqICAgICAgICAgICAgIHtAY29kZSBidWZ9LgorICAgICAqIEBzZWUgI2VuZ2luZVJlc2V0KCkKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGVuZ2luZURpZ2VzdChieXRlW10gYnVmLCBpbnQgb2Zmc2V0LCBpbnQgbGVuKSB0aHJvd3MgRGlnZXN0RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGxlbiA8IGVuZ2luZUdldERpZ2VzdExlbmd0aCgpKSB7CisgICAgICAgICAgICBlbmdpbmVSZXNldCgpOworICAgICAgICAgICAgdGhyb3cgbmV3IERpZ2VzdEV4Y2VwdGlvbigiVGhlIHZhbHVlIG9mIGxlbiBwYXJhbWV0ZXIgaXMgbGVzcyB0aGFuIHRoZSBhY3R1YWwgZGlnZXN0IGxlbmd0aCIpOworICAgICAgICB9CisgICAgICAgIGlmIChvZmZzZXQgPCAwKSB7CisgICAgICAgICAgICBlbmdpbmVSZXNldCgpOworICAgICAgICAgICAgdGhyb3cgbmV3IERpZ2VzdEV4Y2VwdGlvbigib2Zmc2V0IDwgMCIpOworICAgICAgICB9CisgICAgICAgIGlmIChvZmZzZXQgKyBsZW4gPiBidWYubGVuZ3RoKSB7CisgICAgICAgICAgICBlbmdpbmVSZXNldCgpOworICAgICAgICAgICAgdGhyb3cgbmV3IERpZ2VzdEV4Y2VwdGlvbigib2Zmc2V0ICsgbGVuID4gYnVmLmxlbmd0aCIpOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSB0bXAgPSBlbmdpbmVEaWdlc3QoKTsKKyAgICAgICAgaWYgKGxlbiA8IHRtcC5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBEaWdlc3RFeGNlcHRpb24oIlRoZSB2YWx1ZSBvZiBsZW4gcGFyYW1ldGVyIGlzIGxlc3MgdGhhbiB0aGUgYWN0dWFsIGRpZ2VzdCBsZW5ndGgiKTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRtcCwgMCwgYnVmLCBvZmZzZXQsIHRtcC5sZW5ndGgpOworICAgICAgICByZXR1cm4gdG1wLmxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQdXRzIHRoaXMge0Bjb2RlIE1lc3NhZ2VEaWdlc3RTcGl9IGJhY2sgaW4gYW4gaW5pdGlhbCBzdGF0ZSwgc3VjaCB0aGF0IGl0CisgICAgICogaXMgcmVhZHkgdG8gY29tcHV0ZSBhIG9uZSB3YXkgaGFzaCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBlbmdpbmVSZXNldCgpOworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L05vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGVmMmUzZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L05vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworLyoqCisgKiB7QGNvZGUgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9ufSBpbmRpY2F0ZXMgdGhhdCBhIHJlcXVlc3RlZCBhbGdvcml0aG0gY291bGQKKyAqIG5vdCBiZSBmb3VuZC4KKyAqLworcHVibGljIGNsYXNzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBleHRlbmRzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNzQ0Mzk0NzQ4NzIxODM0NjU2Mkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb259IHdpdGggdGhlCisgICAgICogZ2l2ZW4gbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbn0gd2l0aCB0aGUKKyAgICAgKiBnaXZlbiBtZXNzYWdlIGFuZCB0aGUgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNlcHRpb24gd2hpY2ggaXMgdGhlIGNhdXNlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbn0gd2l0aCB0aGUKKyAgICAgKiBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGV4Y2VwdGlvbiB3aGljaCBpcyB0aGUgY2F1c2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41N2NkYTQwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQ0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKKy8qKgorICoge0Bjb2RlIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9ufSBpbmRpY2F0ZXMgdGhhdCBhIHJlcXVlc3RlZCBzZWN1cml0eSBwcm92aWRlcgorICogY291bGQgbm90IGJlIGZvdW5kLgorICovCitwdWJsaWMgY2xhc3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZXh0ZW5kcyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODQ4ODExMTc1NjY4ODUzNDQ3NEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbn0gd2l0aCB0aGUKKyAgICAgKiBnaXZlbiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24oU3RyaW5nIG1zZykgeworICAgICAgICBzdXBlcihtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvUGVybWlzc2lvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvUGVybWlzc2lvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRiN2VmODQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9QZXJtaXNzaW9uLmphdmEKQEAgLTAsMCArMSwzOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBQZXJtaXNzaW9uIGltcGxlbWVudHMgR3VhcmQsIFNlcmlhbGl6YWJsZSB7CisgICAgcHVibGljIFBlcm1pc3Npb24oU3RyaW5nIG5hbWUpIHsgfQorCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXROYW1lKCkgeyByZXR1cm4gbnVsbDsgfQorCisgICAgcHVibGljIHZvaWQgY2hlY2tHdWFyZChPYmplY3Qgb2JqKSB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24geyB9CisKKyAgICBwdWJsaWMgUGVybWlzc2lvbkNvbGxlY3Rpb24gbmV3UGVybWlzc2lvbkNvbGxlY3Rpb24oKSB7CisgICAgICAgIHJldHVybiBuZXcgQWxsUGVybWlzc2lvbkNvbGxlY3Rpb24oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldEFjdGlvbnMoKTsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGltcGxpZXMoUGVybWlzc2lvbiBwZXJtaXNzaW9uKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1Blcm1pc3Npb25Db2xsZWN0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9QZXJtaXNzaW9uQ29sbGVjdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU1N2VlZWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9QZXJtaXNzaW9uQ29sbGVjdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIExlZ2FjeSBzZWN1cml0eSBjb2RlOyBkbyBub3QgdXNlLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgUGVybWlzc2lvbkNvbGxlY3Rpb24gaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgYWRkKFBlcm1pc3Npb24gcGVybWlzc2lvbik7CisKKyAgICBwdWJsaWMgYWJzdHJhY3QgRW51bWVyYXRpb248UGVybWlzc2lvbj4gZWxlbWVudHMoKTsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGltcGxpZXMoUGVybWlzc2lvbiBwZXJtaXNzaW9uKTsKKworICAgIHB1YmxpYyBib29sZWFuIGlzUmVhZE9ubHkoKSB7IHJldHVybiB0cnVlOyB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRSZWFkT25seSgpIHsgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvUGVybWlzc2lvbnMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1Blcm1pc3Npb25zLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjEyMmFhYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1Blcm1pc3Npb25zLmphdmEKQEAgLTAsMCArMSwzMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworCisvKioKKyAqIExlZ2FjeSBzZWN1cml0eSBjb2RlOyBkbyBub3QgdXNlLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUGVybWlzc2lvbnMgZXh0ZW5kcyBQZXJtaXNzaW9uQ29sbGVjdGlvbiBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisgICAgcHVibGljIHZvaWQgYWRkKFBlcm1pc3Npb24gcGVybWlzc2lvbikge30KKworICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxQZXJtaXNzaW9uPiBlbGVtZW50cygpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIHB1YmxpYyBib29sZWFuIGltcGxpZXMoUGVybWlzc2lvbiBwZXJtaXNzaW9uKSB7IHJldHVybiB0cnVlOyB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9QZXJtaXNzaW9uc0hhc2guamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1Blcm1pc3Npb25zSGFzaC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY2NmI3OTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9QZXJtaXNzaW9uc0hhc2guamF2YQpAQCAtMCwwICsxLDc1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKKworLyoqCisgKiBBIGRlZmF1bHQge0Bjb2RlIFBlcm1pc3Npb25Db2xsZWN0aW9ufSBpbXBsZW1lbnRhdGlvbiB0aGF0IHVzZXMgYSBoYXNodGFibGUuCisgKiBFYWNoIGhhc2h0YWJsZSBlbnRyeSBzdG9yZXMgYSBQZXJtaXNzaW9uIG9iamVjdCBhcyBib3RoIHRoZSBrZXkgYW5kIHRoZQorICogdmFsdWUuCisgKiA8cD4KKyAqIFRoaXMge0Bjb2RlIFBlcm1pc3Npb25Db2xsZWN0aW9ufSBpcyBpbnRlbmRlZCBmb3Igc3RvcmluZyAmcXVvdDtuZXV0cmFsJnF1b3Q7CisgKiBwZXJtaXNzaW9ucyB3aGljaCBkbyBub3QgcmVxdWlyZSBzcGVjaWFsIGNvbGxlY3Rpb24uCisgKi8KKworZmluYWwgY2xhc3MgUGVybWlzc2lvbnNIYXNoIGV4dGVuZHMgUGVybWlzc2lvbkNvbGxlY3Rpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTg0OTE5ODgyMjA4MDI5MzM0NDBMOworCisgICAgcHJpdmF0ZSBmaW5hbCBIYXNodGFibGUgcGVybXMgPSBuZXcgSGFzaHRhYmxlKCk7CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBhcmd1bWVudCB0byB0aGUgY29sbGVjdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwZXJtaXNzaW9uCisgICAgICogICAgICAgICAgICB0aGUgcGVybWlzc2lvbiB0byBhZGQgdG8gdGhlIGNvbGxlY3Rpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkKFBlcm1pc3Npb24gcGVybWlzc2lvbikgeworICAgICAgICBwZXJtcy5wdXQocGVybWlzc2lvbiwgcGVybWlzc2lvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBlbnVtZXJhdGlvbiBvZiB0aGUgcGVybWlzc2lvbnMgaW4gdGhlIHJlY2VpdmVyLgorICAgICAqCisgICAgICogQHJldHVybiBFbnVtZXJhdGlvbiB0aGUgcGVybWlzc2lvbnMgaW4gdGhlIHJlY2VpdmVyLgorICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBlbGVtZW50cygpIHsKKyAgICAgICAgcmV0dXJuIHBlcm1zLmVsZW1lbnRzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGFyZ3VtZW50IHBlcm1pc3Npb24gaXMgaW1wbGllZCBieSB0aGUgcGVybWlzc2lvbnMKKyAgICAgKiBjb250YWluZWQgaW4gdGhlIHJlY2VpdmVyLgorICAgICAqCisgICAgICogQHJldHVybiBib29sZWFuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBhcmd1bWVudCBwZXJtaXNzaW9uIGlzIGltcGxpZWQKKyAgICAgKiAgICAgICAgIGJ5IHRoZSBwZXJtaXNzaW9ucyBpbiB0aGUgcmVjZWl2ZXIsIGFuZCA8Y29kZT5mYWxzZTwvY29kZT4gaWYKKyAgICAgKiAgICAgICAgIGl0IGlzIG5vdC4KKyAgICAgKiBAcGFyYW0gcGVybWlzc2lvbgorICAgICAqICAgICAgICAgICAgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uIHRoZSBwZXJtaXNzaW9uIHRvIGNoZWNrCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaW1wbGllcyhQZXJtaXNzaW9uIHBlcm1pc3Npb24pIHsKKyAgICAgICAgZm9yIChFbnVtZXJhdGlvbiBlbGVtZW50cyA9IGVsZW1lbnRzKCk7IGVsZW1lbnRzLmhhc01vcmVFbGVtZW50cygpOykgeworICAgICAgICAgICAgaWYgKCgoUGVybWlzc2lvbillbGVtZW50cy5uZXh0RWxlbWVudCgpKS5pbXBsaWVzKHBlcm1pc3Npb24pKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1BvbGljeS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvUG9saWN5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWM1ODkzNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1BvbGljeS5qYXZhCkBAIC0wLDAgKzEsNTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKKworLyoqCisgKiBMZWdhY3kgc2VjdXJpdHkgY29kZTsgZG8gbm90IHVzZS4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFBvbGljeSB7CisgICAgLyoqCisgICAgICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnRlcmZhY2UgUGFyYW1ldGVycyB7IH0KKworICAgIHB1YmxpYyBQb2xpY3koKSB7IH0KKworICAgIHB1YmxpYyBzdGF0aWMgUG9saWN5IGdldEluc3RhbmNlKFN0cmluZyB0eXBlLCBQb2xpY3kuUGFyYW1ldGVycyBwYXJhbXMpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geyByZXR1cm4gbnVsbDsgfQorCisgICAgcHVibGljIHN0YXRpYyBQb2xpY3kgZ2V0SW5zdGFuY2UoU3RyaW5nIHR5cGUsIFBvbGljeS5QYXJhbWV0ZXJzIHBhcmFtcywgU3RyaW5nIHByb3ZpZGVyKSB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7IHJldHVybiBudWxsOyB9CisKKyAgICBwdWJsaWMgc3RhdGljIFBvbGljeSBnZXRJbnN0YW5jZShTdHJpbmcgdHlwZSwgUG9saWN5LlBhcmFtZXRlcnMgcGFyYW1zLCBQcm92aWRlciBwcm92aWRlcikgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7IHJldHVybiBudWxsOyB9CisKKyAgICBwdWJsaWMgUG9saWN5LlBhcmFtZXRlcnMgZ2V0UGFyYW1ldGVycygpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIHB1YmxpYyBQcm92aWRlciBnZXRQcm92aWRlcigpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSgpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUGVybWlzc2lvbkNvbGxlY3Rpb24gVU5TVVBQT1JURURfRU1QVFlfQ09MTEVDVElPTiA9IG5ldyBBbGxQZXJtaXNzaW9uQ29sbGVjdGlvbigpOworCisgICAgcHVibGljIFBlcm1pc3Npb25Db2xsZWN0aW9uIGdldFBlcm1pc3Npb25zKENvZGVTb3VyY2UgY3MpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIHB1YmxpYyB2b2lkIHJlZnJlc2goKSB7IH0KKworICAgIHB1YmxpYyBQZXJtaXNzaW9uQ29sbGVjdGlvbiBnZXRQZXJtaXNzaW9ucyhQcm90ZWN0aW9uRG9tYWluIGRvbWFpbikgeyByZXR1cm4gbnVsbDsgfQorCisgICAgcHVibGljIGJvb2xlYW4gaW1wbGllcyhQcm90ZWN0aW9uRG9tYWluIGRvbWFpbiwgUGVybWlzc2lvbiBwZXJtaXNzaW9uKSB7IHJldHVybiB0cnVlOyB9CisKKyAgICBwdWJsaWMgc3RhdGljIFBvbGljeSBnZXRQb2xpY3koKSB7IHJldHVybiBudWxsOyB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0UG9saWN5KFBvbGljeSBwb2xpY3kpIHsgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvUG9saWN5U3BpLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9Qb2xpY3lTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hODM5MjJhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvUG9saWN5U3BpLmphdmEKQEAgLTAsMCArMSwxMTAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworLyoqCisgKiBSZXByZXNlbnRzIHRoZSBTZXJ2aWNlIFByb3ZpZGVyIEludGVyZmFjZSAoU1BJKSBmb3IgamF2YS5zZWN1cml0eS5Qb2xpY3kKKyAqIGNsYXNzLgorICoKKyAqIDxwPklmIHRoZXJlIGlzIGFueSBjbGFzcyB0aGF0IHdhbnRzIHRvIHByb3ZpZGUgYSBQb2xpY3kgaW1wbGVtZW50YXRpb24sIGFsbAorICogYWJzdHJhY3QgbWV0aG9kcyBpbiB0aGlzIFNQSSBzaG91bGQgYmUgaW1wbGVtZW50ZWQuCisgKgorICogPHA+VGhlIGRldGFpbGVkIGltcGxlbWVudGF0aW9ucyBzaG91bGQgb2ZmZXIgYSBwdWJsaWMgY29uc3RydWN0b3IsIGluIHdoaWNoIGEKKyAqIFBvbGljeS5QYXJhbXRlcnMgaW1wbGVtZW50YXRpb24gYWN0cyBhcyBhbiBpbnB1dCBwYXJhbWV0ZXIuSWYgdGhlCisgKiBQb2xpY3kuUGFyYW10ZXJzIGlucHV0IGNhbm5vdCBieSB1bmRlcnN0b29kIGJ5IHRoZSBjb25zdHJ1Y3RvciwgYW4KKyAqIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFBvbGljeVNwaSB7CisKKyAgICBwdWJsaWMgUG9saWN5U3BpKCkgeworICAgICAgICAvLyBkZWZhdWx0IGNvbnN0cnVjdG9yCisgICAgfQorCisgICAgLyoqCisgICAgICogQW5zd2VycyBpZiB0aGUgcG9saWN5IGhhcyBncmFudGVkIGEgUGVybWlzc2lvbiB0byBhCisgICAgICogUHJvdGVjdGlvbkRvbWFpbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkb21haW4gLQorICAgICAqICAgICAgICAgICAgdGhlIGRvbWFpbiB0byBjaGVjay4KKyAgICAgKiBAcGFyYW0gcGVybWlzc2lvbiAtCisgICAgICogICAgICAgICAgICBjaGVjayB3aGV0aGVyIHRoaXMgcGVybWlzc2lvbiBpcyBncmFudGVkIHRvIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgICAgIGRvbWFpbi4KKyAgICAgKiBAcmV0dXJuIC0gdHJ1ZSBpZiB0aGUgcGVybWlzc2lvbiBpcyBncmFudGVkIHRvIHRoZSBkb21haW4uCisgICAgICoKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgYm9vbGVhbiBlbmdpbmVJbXBsaWVzKFByb3RlY3Rpb25Eb21haW4gZG9tYWluLAorICAgICAgICAgICAgUGVybWlzc2lvbiBwZXJtaXNzaW9uKTsKKworICAgIC8qKgorICAgICAqIFJlZnJlc2hlcy9yZWxvYWRzIHRoZSBwb2xpY3kgY29uZmlndXJhdGlvbi4gVGhlIGJlaGF2aW9yIG9mIHRoaXMgbWV0aG9kCisgICAgICogZGVwZW5kcyBvbiB0aGUgaW1wbGVtZW50YXRpb24uIEZvciBleGFtcGxlLCBjYWxsaW5nIHJlZnJlc2ggb24gYQorICAgICAqIGZpbGUtYmFzZWQgcG9saWN5IHdpbGwgY2F1c2UgdGhlIGZpbGUgdG8gYmUgcmUtcmVhZC4KKyAgICAgKgorICAgICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kIGRvZXMgbm90aGluZy4gVGhpcyBtZXRob2QKKyAgICAgKiBzaG91bGQgYmUgb3ZlcnJpZGRlbiBpZiBhIHJlZnJlc2ggb3BlcmF0aW9uIGlzIHN1cHBvcnRlZCBieSB0aGUgcG9saWN5CisgICAgICogaW1wbGVtZW50YXRpb24uCisgICAgICoKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVSZWZyZXNoKCkgeworICAgICAgICAvLyBkbyBub3RoaW5nIGluIGRlZmF1bHQgaW1wbGVtZW50YXRpb24KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbnN3ZXJzIGEgUGVybWlzc2lvbkNvbGxlY3Rpb24gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHNldCBvZiBwZXJtaXNzaW9ucworICAgICAqIGdyYW50ZWQgdG8gdGhlIHNwZWNpZmllZCBDb2RlU291cmNlLgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBtZXRob2QgcmV0dXJucworICAgICAqIFBvbGljeS5VTlNVUFBPUlRFRF9FTVBUWV9DT0xMRUNUSU9OIG9iamVjdC4gVGhpcyBtZXRob2QgY2FuIGJlIG92ZXJyaWRkZW4KKyAgICAgKiBpZiB0aGUgcG9saWN5IGltcGxlbWVudGF0aW9uIGNhbiByZXR1cm4gYSBzZXQgb2YgcGVybWlzc2lvbnMgZ3JhbnRlZCB0byBhCisgICAgICogQ29kZVNvdXJjZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2Rlc291cmNlIC0KKyAgICAgKiAgICAgICAgICAgIHRoZSBDb2RlU291cmNlIHRvIHdoaWNoIHRoZSByZXR1cm5lZCBQZXJtaXNzaW9uQ29sbGVjdGlvbiBoYXMKKyAgICAgKiAgICAgICAgICAgIGJlZW4gZ3JhbnRlZC4KKyAgICAgKiBAcmV0dXJuIGEgc2V0IG9mIHBlcm1pc3Npb25zIGdyYW50ZWQgdG8gdGhlIHNwZWNpZmllZCBDb2RlU291cmNlLiBJZiB0aGlzCisgICAgICogICAgICAgICBvcGVyYXRpb24gaXMgc3VwcG9ydGVkLCB0aGUgcmV0dXJuZWQgc2V0IG9mIHBlcm1pc3Npb25zIG11c3QgYmUgYQorICAgICAqICAgICAgICAgbmV3IG11dGFibGUgaW5zdGFuY2UgYW5kIGl0IG11c3Qgc3VwcG9ydCBoZXRlcm9nZW5lb3VzIFBlcm1pc3Npb24KKyAgICAgKiAgICAgICAgIHR5cGVzLiBJZiB0aGlzIG9wZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkLAorICAgICAqICAgICAgICAgUG9saWN5LlVOU1VQUE9SVEVEX0VNUFRZX0NPTExFQ1RJT04gaXMgcmV0dXJuZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIFBlcm1pc3Npb25Db2xsZWN0aW9uIGVuZ2luZUdldFBlcm1pc3Npb25zKENvZGVTb3VyY2UgY29kZXNvdXJjZSkgeworICAgICAgICByZXR1cm4gUG9saWN5LlVOU1VQUE9SVEVEX0VNUFRZX0NPTExFQ1RJT047CisgICAgfQorCisgICAgLyoqCisgICAgICogQW5zd2VycyBhIFBlcm1pc3Npb25Db2xsZWN0aW9uIG9iamVjdCBjb250YWluaW5nIHRoZSBzZXQgb2YgcGVybWlzc2lvbnMKKyAgICAgKiBncmFudGVkIHRvIHRoZSBzcGVjaWZpZWQgUHJvdGVjdGlvbkRvbWFpbi4KKyAgICAgKgorICAgICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kIHJldHVybnMKKyAgICAgKiBQb2xpY3kuVU5TVVBQT1JURURfRU1QVFlfQ09MTEVDVElPTiBvYmplY3QuIFRoaXMgbWV0aG9kIGNhbiBiZSBvdmVycmlkZGVuCisgICAgICogaWYgdGhlIHBvbGljeSBpbXBsZW1lbnRhdGlvbiBjYW4gcmV0dXJuIGEgc2V0IG9mIHBlcm1pc3Npb25zIGdyYW50ZWQgdG8gYQorICAgICAqIFByb3RlY3Rpb25Eb21haW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZG9tYWluIC0KKyAgICAgKiAgICAgICAgICAgIHRoZSBQcm90ZWN0aW9uRG9tYWluIHRvIHdoaWNoIHRoZSByZXR1cm5lZAorICAgICAqICAgICAgICAgICAgUGVybWlzc2lvbkNvbGxlY3Rpb24gaGFzIGJlZW4gZ3JhbnRlZC4KKyAgICAgKiBAcmV0dXJuIGEgc2V0IG9mIHBlcm1pc3Npb25zIGdyYW50ZWQgdG8gdGhlIHNwZWNpZmllZCBQcm90ZWN0aW9uRG9tYWluLgorICAgICAqICAgICAgICAgSWYgdGhpcyBvcGVyYXRpb24gaXMgc3VwcG9ydGVkLCB0aGUgcmV0dXJuZWQgc2V0IG9mIHBlcm1pc3Npb25zCisgICAgICogICAgICAgICBtdXN0IGJlIGEgbmV3IG11dGFibGUgaW5zdGFuY2UgYW5kIGl0IG11c3Qgc3VwcG9ydCBoZXRlcm9nZW5lb3VzCisgICAgICogICAgICAgICBQZXJtaXNzaW9uIHR5cGVzLiBJZiB0aGlzIG9wZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkLAorICAgICAqICAgICAgICAgUG9saWN5LlVOU1VQUE9SVEVEX0VNUFRZX0NPTExFQ1RJT04gaXMgcmV0dXJuZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIFBlcm1pc3Npb25Db2xsZWN0aW9uIGVuZ2luZUdldFBlcm1pc3Npb25zKFByb3RlY3Rpb25Eb21haW4gZG9tYWluKSB7CisgICAgICAgIHJldHVybiBQb2xpY3kuVU5TVVBQT1JURURfRU1QVFlfQ09MTEVDVElPTjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9QcmluY2lwYWwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1ByaW5jaXBhbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4NmJjODcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9QcmluY2lwYWwuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKKworLyoqCisgKiB7QGNvZGUgUHJpbmNpcGFsfXMgYXJlIG9iamVjdHMgd2hpY2ggaGF2ZSBpZGVudGl0aWVzLiBUaGVzZSBjYW4gYmUKKyAqIGluZGl2aWR1YWxzLCBncm91cHMsIGNvcnBvcmF0aW9ucywgdW5pcXVlIHByb2dyYW0gZXhlY3V0aW9ucywgZXRjLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFByaW5jaXBhbCB7CisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBvYmplY3Qgd2l0aCB0aGlzIHtAY29kZSBQcmluY2lwYWx9IGZvciBlcXVhbGl0eQorICAgICAqIGFuZCByZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBlcXVhbCwge0Bjb2RlIGZhbHNlfQorICAgICAqIG90aGVyd2lzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIG9iamVjdCB0byBiZSBjb21wYXJlZCBmb3IgZXF1YWxpdHkgd2l0aCB0aGlzIHtAY29kZQorICAgICAqICAgICAgICAgICAgUHJpbmNpcGFsfS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBlcXVhbCB0byB0aGlzIHtAY29kZQorICAgICAqICAgICAgICAgUHJpbmNpcGFsfSwgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKCBPYmplY3Qgb2JqICk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoaXMge0Bjb2RlIFByaW5jaXBhbH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoaXMge0Bjb2RlIFByaW5jaXBhbH0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgdmFsdWUgZm9yIHRoaXMge0Bjb2RlIFByaW5jaXBhbH0uIFJldHVybnMgdGhlIHNhbWUKKyAgICAgKiBoYXNoIGNvZGUgZm9yIHtAY29kZSBQcmluY2lwYWx9cyB0aGF0IGFyZSBlcXVhbCB0byBlYWNoIG90aGVyIGFzCisgICAgICogcmVxdWlyZWQgYnkgdGhlIGdlbmVyYWwgY29udHJhY3Qgb2Yge0BsaW5rIE9iamVjdCNoYXNoQ29kZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUgdmFsdWUgZm9yIHRoaXMge0Bjb2RlIFByaW5jaXBhbH0uCisgICAgICogQHNlZSBPYmplY3QjZXF1YWxzKE9iamVjdCkKKyAgICAgKiBAc2VlIFByaW5jaXBhbCNlcXVhbHMoT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIGNvbmNpc2UsIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIG9mCisgICAgICogdGhpcyB7QGNvZGUgUHJpbmNpcGFsfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBwcmludGFibGUgcmVwcmVzZW50YXRpb24gZm9yIHRoaXMge0Bjb2RlIFByaW5jaXBhbH0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvUHJpdmF0ZUtleS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvUHJpdmF0ZUtleS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhmYWMxZTkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9Qcml2YXRlS2V5LmphdmEKQEAgLTAsMCArMSwzMSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCisvKioKKyAqIHtAY29kZSBQcml2YXRlS2V5fSBpcyB0aGUgY29tbW9uIGludGVyZmFjZSBmb3IgcHJpdmF0ZSBrZXlzLgorICoKKyAqIEBzZWUgUHVibGljS2V5CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUHJpdmF0ZUtleSBleHRlbmRzIEtleSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUge0Bjb2RlIHNlcmlhbFZlcnNpb25VSUR9IHRvIGJlIGNvbXBhdGlibGUgd2l0aCBKREsxLjEuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA2MDM0MDQ0MzE0NTg5NTEzNDMwTDsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1ByaXZpbGVnZWRBY3Rpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1ByaXZpbGVnZWRBY3Rpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZjY3MTJlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvUHJpdmlsZWdlZEFjdGlvbi5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworLyoqCisgKiBMZWdhY3kgc2VjdXJpdHkgY29kZTsgZG8gbm90IHVzZS4KKyAqLworcHVibGljIGludGVyZmFjZSBQcml2aWxlZ2VkQWN0aW9uPFQ+IHsKKyAgICBwdWJsaWMgVCBydW4oKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1ByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1ByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNDQ0NzliCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworLyoqCisgKiBMZWdhY3kgc2VjdXJpdHkgY29kZTsgZG8gbm90IHVzZS4KKyAqLworcHVibGljIGNsYXNzIFByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNDcyNDA4Njg1MTUzODkwODYwMmw7CisKKyAgICBwdWJsaWMgUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbihFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgc3VwZXIoZXgpOworICAgIH0KKworICAgIHB1YmxpYyBFeGNlcHRpb24gZ2V0RXhjZXB0aW9uKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9Qcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9Qcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjI0ZWZhYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1ByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb24uamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbjxUPiB7CisgICAgVCBydW4oKSB0aHJvd3MgRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvUHJvdGVjdGlvbkRvbWFpbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvUHJvdGVjdGlvbkRvbWFpbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3YjRjZjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9Qcm90ZWN0aW9uRG9tYWluLmphdmEKQEAgLTAsMCArMSwzNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCisvKioKKyAqIExlZ2FjeSBzZWN1cml0eSBjb2RlOyBkbyBub3QgdXNlLgorICovCitwdWJsaWMgY2xhc3MgUHJvdGVjdGlvbkRvbWFpbiB7CisgICAgcHVibGljIFByb3RlY3Rpb25Eb21haW4oQ29kZVNvdXJjZSBjcywgUGVybWlzc2lvbkNvbGxlY3Rpb24gcGVybWlzc2lvbnMpIHsgfQorCisgICAgcHVibGljIFByb3RlY3Rpb25Eb21haW4oQ29kZVNvdXJjZSBjcywgUGVybWlzc2lvbkNvbGxlY3Rpb24gcGVybWlzc2lvbnMsIENsYXNzTG9hZGVyIGNsLCBQcmluY2lwYWxbXSBwcmluY2lwYWxzKSB7IH0KKworICAgIHB1YmxpYyBmaW5hbCBDbGFzc0xvYWRlciBnZXRDbGFzc0xvYWRlcigpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIHB1YmxpYyBmaW5hbCBDb2RlU291cmNlIGdldENvZGVTb3VyY2UoKSB7IHJldHVybiBudWxsOyB9CisKKyAgICBwdWJsaWMgZmluYWwgUGVybWlzc2lvbkNvbGxlY3Rpb24gZ2V0UGVybWlzc2lvbnMoKSB7IHJldHVybiBudWxsOyB9CisKKyAgICBwdWJsaWMgZmluYWwgUHJpbmNpcGFsW10gZ2V0UHJpbmNpcGFscygpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIHB1YmxpYyBib29sZWFuIGltcGxpZXMoUGVybWlzc2lvbiBwZXJtaXNzaW9uKSB7IHJldHVybiB0cnVlOyB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9Qcm92aWRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvUHJvdmlkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZGUzNzUxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvUHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDEwNTQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk5vdEFjdGl2ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnV0aWwuVHdvS2V5SGFzaE1hcDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuZm9ydHJlc3MuU2VydmljZXM7CisKKy8qKgorICoge0Bjb2RlIFByb3ZpZGVyfSBpcyB0aGUgYWJzdHJhY3Qgc3VwZXJjbGFzcyBmb3IgYWxsIHNlY3VyaXR5IHByb3ZpZGVycyBpbiB0aGUKKyAqIEphdmEgc2VjdXJpdHkgaW5mcmFzdHJ1Y3R1cmUuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBQcm92aWRlciBleHRlbmRzIFByb3BlcnRpZXMgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00Mjk4MDAwNTE1NDQ2NDI3NzM5TDsKKworICAgIHByaXZhdGUgU3RyaW5nIG5hbWU7CisKKyAgICBwcml2YXRlIGRvdWJsZSB2ZXJzaW9uOworCisgICAgLy8gU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwcm92aWRlciB2ZXJzaW9uIG51bWJlci4KKyAgICBwcml2YXRlIHRyYW5zaWVudCBTdHJpbmcgdmVyc2lvblN0cmluZzsKKworICAgIHByaXZhdGUgU3RyaW5nIGluZm87CisKKyAgICAvL1RoZSBwcm92aWRlciBwcmVmZXJlbmNlIG9yZGVyIG51bWJlci4KKyAgICAvLyBFcXVhbHMgLTEgZm9yIG5vbiByZWdpc3RlcmVkIHByb3ZpZGVyLgorICAgIHByaXZhdGUgdHJhbnNpZW50IGludCBwcm92aWRlck51bWJlciA9IC0xOworCisgICAgLy8gQ29udGFpbnMgIlNlcnZpY2UuQWxnb3JpdGhtIiBhbmQgUHJvdmlkZXIuU2VydmljZSBjbGFzc2VzIGFkZGVkIHVzaW5nCisgICAgLy8gcHV0U2VydmljZSgpCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgVHdvS2V5SGFzaE1hcDxTdHJpbmcsIFN0cmluZywgU2VydmljZT4gc2VydmljZVRhYmxlOworCisgICAgLy8gQ29udGFpbnMgIlNlcnZpY2UuQWxpYXMiIGFuZCBQcm92aWRlci5TZXJ2aWNlIGNsYXNzZXMgYWRkZWQgdXNpbmcKKyAgICAvLyBwdXRTZXJ2aWNlKCkKKyAgICBwcml2YXRlIHRyYW5zaWVudCBUd29LZXlIYXNoTWFwPFN0cmluZywgU3RyaW5nLCBTZXJ2aWNlPiBhbGlhc1RhYmxlOworCisgICAgLy8gQ29udGFpbnMgIlNlcnZpY2UuQWxnb3JpdGhtIiBhbmQgUHJvdmlkZXIuU2VydmljZSBjbGFzc2VzIGFkZGVkIHVzaW5nCisgICAgLy8gcHV0KCkKKyAgICBwcml2YXRlIHRyYW5zaWVudCBUd29LZXlIYXNoTWFwPFN0cmluZywgU3RyaW5nLCBTZXJ2aWNlPiBwcm9wZXJ0eVNlcnZpY2VUYWJsZTsKKworICAgIC8vIENvbnRhaW5zICJTZXJ2aWNlLkFsaWFzIiBhbmQgUHJvdmlkZXIuU2VydmljZSBjbGFzc2VzIGFkZGVkIHVzaW5nIHB1dCgpCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgVHdvS2V5SGFzaE1hcDxTdHJpbmcsIFN0cmluZywgU2VydmljZT4gcHJvcGVydHlBbGlhc1RhYmxlOworCisgICAgLy8gVGhlIHByb3BlcnRpZXMgY2hhbmdlZCB2aWEgcHV0KCkKKyAgICBwcml2YXRlIHRyYW5zaWVudCBQcm9wZXJ0aWVzIGNoYW5nZWRQcm9wZXJ0aWVzOworCisgICAgLy8gRm9yIGdldFNlcnZpY2UoU3RyaW5nIHR5cGUsIFN0cmluZyBhbGdvcml0aG0pIG9wdGltaXphdGlvbjoKKyAgICAvLyBwcmV2aW91cyByZXN1bHQKKyAgICBwcml2YXRlIHRyYW5zaWVudCBQcm92aWRlci5TZXJ2aWNlIHJldHVybmVkU2VydmljZTsKKyAgICAvLyBwcmV2aW91cyBwYXJhbWV0ZXJzCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgU3RyaW5nIGxhc3RBbGdvcml0aG07CisgICAgLy8gbGFzdCBuYW1lCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgU3RyaW5nIGxhc3RTZXJ2aWNlTmFtZTsKKworICAgIC8vIEZvciBnZXRTZXJ2aWNlcygpIG9wdGltaXphdGlvbjoKKyAgICBwcml2YXRlIHRyYW5zaWVudCBTZXQ8U2VydmljZT4gbGFzdFNlcnZpY2VzU2V0OworCisgICAgLy8gRm9yIGdldFNlcnZpY2UoU3RyaW5nIHR5cGUpIG9wdGltaXphdGlvbjoKKyAgICBwcml2YXRlIHRyYW5zaWVudCBTdHJpbmcgbGFzdFR5cGU7CisgICAgLy8gbGFzdCBTZXJ2aWNlIGZvdW5kIGJ5IHR5cGUKKyAgICBwcml2YXRlIHRyYW5zaWVudCBQcm92aWRlci5TZXJ2aWNlIGxhc3RTZXJ2aWNlc0J5VHlwZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFByb3ZpZGVyfSB3aXRoIGl0cyBuYW1lLCB2ZXJzaW9uIGFuZAorICAgICAqIGRlc2NyaXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBwcm92aWRlci4KKyAgICAgKiBAcGFyYW0gdmVyc2lvbgorICAgICAqICAgICAgICAgICAgdGhlIHZlcnNpb24gb2YgdGhlIHByb3ZpZGVyLgorICAgICAqIEBwYXJhbSBpbmZvCisgICAgICogICAgICAgICAgICBhIGRlc2NyaXB0aW9uIG9mIHRoZSBwcm92aWRlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUHJvdmlkZXIoU3RyaW5nIG5hbWUsIGRvdWJsZSB2ZXJzaW9uLCBTdHJpbmcgaW5mbykgeworICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgICAgICB0aGlzLnZlcnNpb24gPSB2ZXJzaW9uOworICAgICAgICB0aGlzLmluZm8gPSBpbmZvOworICAgICAgICB2ZXJzaW9uU3RyaW5nID0gU3RyaW5nLnZhbHVlT2YodmVyc2lvbik7CisgICAgICAgIHB1dFByb3ZpZGVySW5mbygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhpcyBwcm92aWRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhpcyBwcm92aWRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZlcnNpb24gbnVtYmVyIGZvciB0aGUgc2VydmljZXMgYmVpbmcgcHJvdmlkZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB2ZXJzaW9uIG51bWJlciBmb3IgdGhlIHNlcnZpY2VzIGJlaW5nIHByb3ZpZGVkLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgZ2V0VmVyc2lvbigpIHsKKyAgICAgICAgcmV0dXJuIHZlcnNpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGRlc2NyaXB0aW9uIG9mIHRoZSBzZXJ2aWNlcyBiZWluZyBwcm92aWRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBkZXNjcmlwdGlvbiBvZiB0aGUgc2VydmljZXMgYmVpbmcgcHJvdmlkZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRJbmZvKCkgeworICAgICAgICByZXR1cm4gaW5mbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZgorICAgICAqIHRoaXMge0Bjb2RlIFByb3ZpZGVyfSBpbmNsdWRpbmcgaXRzIG5hbWUgYW5kIGl0cyB2ZXJzaW9uLgorICAgICAqCisgICAgICogQHJldHVybiBhIHByaW50YWJsZSByZXByZXNlbnRhdGlvbiBmb3IgdGhpcyB7QGNvZGUgUHJvdmlkZXJ9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBuYW1lICsgIiB2ZXJzaW9uICIgKyB2ZXJzaW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsZWFycyBhbGwgcHJvcGVydGllcyB1c2VkIHRvIGxvb2sgdXAgc2VydmljZXMgaW1wbGVtZW50ZWQgYnkgdGhpcworICAgICAqIHtAY29kZSBQcm92aWRlcn0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNsZWFyKCkgeworICAgICAgICBzdXBlci5jbGVhcigpOworICAgICAgICBpZiAoc2VydmljZVRhYmxlICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNlcnZpY2VUYWJsZS5jbGVhcigpOworICAgICAgICB9CisgICAgICAgIGlmIChwcm9wZXJ0eVNlcnZpY2VUYWJsZSAhPSBudWxsKSB7CisgICAgICAgICAgICBwcm9wZXJ0eVNlcnZpY2VUYWJsZS5jbGVhcigpOworICAgICAgICB9CisgICAgICAgIGlmIChhbGlhc1RhYmxlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFsaWFzVGFibGUuY2xlYXIoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocHJvcGVydHlBbGlhc1RhYmxlICE9IG51bGwpIHsKKyAgICAgICAgICAgIHByb3BlcnR5QWxpYXNUYWJsZS5jbGVhcigpOworICAgICAgICB9CisgICAgICAgIGNoYW5nZWRQcm9wZXJ0aWVzID0gbnVsbDsKKyAgICAgICAgcHV0UHJvdmlkZXJJbmZvKCk7CisgICAgICAgIGlmIChwcm92aWRlck51bWJlciAhPSAtMSkgeworICAgICAgICAgICAgLy8gaWYgcmVnaXN0ZXJlZCB0aGVuIHJlZnJlc2ggU2VydmljZXMKKyAgICAgICAgICAgIFNlcnZpY2VzLnNldE5lZWRSZWZyZXNoKCk7CisgICAgICAgIH0KKyAgICAgICAgc2VydmljZXNDaGFuZ2VkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGxvYWQoSW5wdXRTdHJlYW0gaW5TdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFByb3BlcnRpZXMgdG1wID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgdG1wLmxvYWQoaW5TdHJlYW0pOworICAgICAgICBteVB1dEFsbCh0bXApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyBhbGwgZnJvbSB0aGUgcHJvdmlkZWQgbWFwIHRvIHRoaXMge0Bjb2RlIFByb3ZpZGVyfS4KKyAgICAgKiBAcGFyYW0gdAorICAgICAqICAgICAgICAgICAgdGhlIG1hcHBpbmdzIHRvIGNvcHkgdG8gdGhpcyBwcm92aWRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcHV0QWxsKE1hcDw/LD8+IHQpIHsKKyAgICAgICAgbXlQdXRBbGwodCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG15UHV0QWxsKE1hcDw/LD8+IHQpIHsKKyAgICAgICAgaWYgKGNoYW5nZWRQcm9wZXJ0aWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIGNoYW5nZWRQcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgfQorICAgICAgICBJdGVyYXRvcjw/IGV4dGVuZHMgTWFwLkVudHJ5PD8sID8+PiBpdCA9IHQuZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICBPYmplY3Qga2V5OworICAgICAgICBPYmplY3QgdmFsdWU7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIE1hcC5FbnRyeTw/LCA/PiBlbnRyeSA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIGtleSA9IGVudHJ5LmdldEtleSgpOworICAgICAgICAgICAgaWYgKGtleSBpbnN0YW5jZW9mIFN0cmluZyAmJiAoKFN0cmluZykga2V5KS5zdGFydHNXaXRoKCJQcm92aWRlci4iKSkgeworICAgICAgICAgICAgICAgIC8vIFByb3ZpZGVyIHNlcnZpY2UgdHlwZSBpcyByZXNlcnZlZAorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdmFsdWUgPSBlbnRyeS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgc3VwZXIucHV0KGtleSwgdmFsdWUpOworICAgICAgICAgICAgaWYgKGNoYW5nZWRQcm9wZXJ0aWVzLnJlbW92ZShrZXkpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZW1vdmVGcm9tUHJvcGVydHlTZXJ2aWNlVGFibGUoa2V5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNoYW5nZWRQcm9wZXJ0aWVzLnB1dChrZXksIHZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocHJvdmlkZXJOdW1iZXIgIT0gLTEpIHsKKyAgICAgICAgICAgIC8vIGlmIHJlZ2lzdGVyZWQgdGhlbiByZWZyZXNoIFNlcnZpY2VzCisgICAgICAgICAgICBTZXJ2aWNlcy5zZXROZWVkUmVmcmVzaCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTZXQ8TWFwLkVudHJ5PE9iamVjdCxPYmplY3Q+PiBlbnRyeVNldCgpIHsKKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNldChzdXBlci5lbnRyeVNldCgpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2V0PE9iamVjdD4ga2V5U2V0KCkgeworICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KHN1cGVyLmtleVNldCgpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ29sbGVjdGlvbjxPYmplY3Q+IHZhbHVlcygpIHsKKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUNvbGxlY3Rpb24oc3VwZXIudmFsdWVzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1hcHMgdGhlIHNwZWNpZmllZCB7QGNvZGUga2V5fSBwcm9wZXJ0eSBuYW1lIHRvIHRoZSBzcGVjaWZpZWQge0Bjb2RlCisgICAgICogdmFsdWV9LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5LgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eS4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSB0aGF0IHdhcyBwcmV2aW91c2x5IG1hcHBlZCB0byB0aGUgc3BlY2lmaWVkIHtAY29kZSBrZXl9CisgICAgICogICAgICAgICAsb3Ige0Bjb2RlIG51bGx9IGlmIGl0IGRpZCBub3QgaGF2ZSBvbmUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBPYmplY3QgcHV0KE9iamVjdCBrZXksIE9iamVjdCB2YWx1ZSkgeworICAgICAgICBpZiAoa2V5IGluc3RhbmNlb2YgU3RyaW5nICYmICgoU3RyaW5nKSBrZXkpLnN0YXJ0c1dpdGgoIlByb3ZpZGVyLiIpKSB7CisgICAgICAgICAgICAvLyBQcm92aWRlciBzZXJ2aWNlIHR5cGUgaXMgcmVzZXJ2ZWQKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGlmIChwcm92aWRlck51bWJlciAhPSAtMSkgeworICAgICAgICAgICAgLy8gaWYgcmVnaXN0ZXJlZCB0aGVuIHJlZnJlc2ggU2VydmljZXMKKyAgICAgICAgICAgIFNlcnZpY2VzLnNldE5lZWRSZWZyZXNoKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNoYW5nZWRQcm9wZXJ0aWVzICE9IG51bGwgJiYgY2hhbmdlZFByb3BlcnRpZXMucmVtb3ZlKGtleSkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmVtb3ZlRnJvbVByb3BlcnR5U2VydmljZVRhYmxlKGtleSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNoYW5nZWRQcm9wZXJ0aWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIGNoYW5nZWRQcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgfQorICAgICAgICBjaGFuZ2VkUHJvcGVydGllcy5wdXQoa2V5LCB2YWx1ZSk7CisgICAgICAgIHJldHVybiBzdXBlci5wdXQoa2V5LCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIHtAY29kZSBrZXl9IGFuZCBpdHMgYXNzb2NpYXRlZCB2YWx1ZSBmcm9tIHRoaXMKKyAgICAgKiB7QGNvZGUgUHJvdmlkZXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5CisgICAgICogQHJldHVybiB0aGUgdmFsdWUgdGhhdCB3YXMgbWFwcGVkIHRvIHRoZSBzcGVjaWZpZWQge0Bjb2RlIGtleX0gLG9yCisgICAgICogICAgICAgICB7QGNvZGUgbnVsbH0gaWYgbm8gbWFwcGluZyB3YXMgcHJlc2VudAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgT2JqZWN0IHJlbW92ZShPYmplY3Qga2V5KSB7CisgICAgICAgIGlmIChrZXkgaW5zdGFuY2VvZiBTdHJpbmcgJiYgKChTdHJpbmcpIGtleSkuc3RhcnRzV2l0aCgiUHJvdmlkZXIuIikpIHsKKyAgICAgICAgICAgIC8vIFByb3ZpZGVyIHNlcnZpY2UgdHlwZSBpcyByZXNlcnZlZAorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHByb3ZpZGVyTnVtYmVyICE9IC0xKSB7CisgICAgICAgICAgICAvLyBpZiByZWdpc3RlcmVkIHRoZW4gcmVmcmVzaCBTZXJ2aWNlcworICAgICAgICAgICAgU2VydmljZXMuc2V0TmVlZFJlZnJlc2goKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2hhbmdlZFByb3BlcnRpZXMgIT0gbnVsbCAmJiBjaGFuZ2VkUHJvcGVydGllcy5yZW1vdmUoa2V5KSA9PSBudWxsKSB7CisgICAgICAgICAgICByZW1vdmVGcm9tUHJvcGVydHlTZXJ2aWNlVGFibGUoa2V5KTsKKyAgICAgICAgICAgIGlmIChjaGFuZ2VkUHJvcGVydGllcy5zaXplKCkgPT0gMCkgeworICAgICAgICAgICAgICAgIGNoYW5nZWRQcm9wZXJ0aWVzID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3VwZXIucmVtb3ZlKGtleSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgcHJvdmlkZXIgaW1wbGVtZW50cyB0aGUgZ2l2ZW4gYWxnb3JpdGhtLiBDYWxsZXIKKyAgICAgKiBtdXN0IHNwZWNpZnkgdGhlIGNyeXB0b2dyYXBoaWMgc2VydmljZSBhbmQgc3BlY2lmeSBjb25zdHJhaW50cyB2aWEgdGhlCisgICAgICogYXR0cmlidXRlIG5hbWUgYW5kIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHNlcnYKKyAgICAgKiAgICAgICAgICAgIENyeXB0byBzZXJ2aWNlLgorICAgICAqIEBwYXJhbSBhbGcKKyAgICAgKiAgICAgICAgICAgIEFsZ29yaXRobSBvciB0eXBlLgorICAgICAqIEBwYXJhbSBhdHRyaWJ1dGUKKyAgICAgKiAgICAgICAgICAgIFRoZSBhdHRyaWJ1dGUgbmFtZSBvciB7QGNvZGUgbnVsbH0uCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgVGhlIGF0dHJpYnV0ZSB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgYm9vbGVhbiBpbXBsZW1lbnRzQWxnKFN0cmluZyBzZXJ2LCBTdHJpbmcgYWxnLCBTdHJpbmcgYXR0cmlidXRlLCBTdHJpbmcgdmFsKSB7CisgICAgICAgIFN0cmluZyBzZXJ2QWxnID0gc2VydiArICIuIiArIGFsZzsKKyAgICAgICAgU3RyaW5nIHByb3AgPSBnZXRQcm9wZXJ0eUlnbm9yZUNhc2Uoc2VydkFsZyk7CisgICAgICAgIGlmIChwcm9wID09IG51bGwpIHsKKyAgICAgICAgICAgIGFsZyA9IGdldFByb3BlcnR5SWdub3JlQ2FzZSgiQWxnLkFsaWFzLiIgKyBzZXJ2QWxnKTsKKyAgICAgICAgICAgIGlmIChhbGcgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlcnZBbGcgPSBzZXJ2ICsgIi4iICsgYWxnOworICAgICAgICAgICAgICAgIHByb3AgPSBnZXRQcm9wZXJ0eUlnbm9yZUNhc2Uoc2VydkFsZyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHByb3AgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gY2hlY2tBdHRyaWJ1dGUoc2VydkFsZywgYXR0cmlidXRlLCB2YWwpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBwcm92aWRlciBoYXMgdGhlIHNhbWUgdmFsdWUgYXMgaXMgZ2l2ZW4gZm9yIHRoZQorICAgICAqIGdpdmVuIGF0dHJpYnV0ZQorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBjaGVja0F0dHJpYnV0ZShTdHJpbmcgc2VydkFsZywgU3RyaW5nIGF0dHJpYnV0ZSwgU3RyaW5nIHZhbCkgeworCisgICAgICAgIFN0cmluZyBhdHRyaWJ1dGVWYWx1ZSA9IGdldFByb3BlcnR5SWdub3JlQ2FzZShzZXJ2QWxnICsgJyAnICsgYXR0cmlidXRlKTsKKyAgICAgICAgaWYgKGF0dHJpYnV0ZVZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChhdHRyaWJ1dGUuZXF1YWxzSWdub3JlQ2FzZSgiS2V5U2l6ZSIpKSB7CisgICAgICAgICAgICAgICAgaWYgKEludGVnZXIucGFyc2VJbnQoYXR0cmlidXRlVmFsdWUpID49IEludGVnZXIucGFyc2VJbnQodmFsKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeyAvLyBvdGhlciBhdHRyaWJ1dGVzCisgICAgICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZVZhbHVlLmVxdWFsc0lnbm9yZUNhc2UodmFsKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqCisgICAgICogU2V0IHRoZSBwcm92aWRlciBwcmVmZXJlbmNlIG9yZGVyIG51bWJlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuCisgICAgICovCisgICAgdm9pZCBzZXRQcm92aWRlck51bWJlcihpbnQgbikgeworICAgICAgICBwcm92aWRlck51bWJlciA9IG47CisgICAgfQorCisgICAgLyoqCisgICAgICoKKyAgICAgKiBHZXQgdGhlIHByb3ZpZGVyIHByZWZlcmVuY2Ugb3JkZXIgbnVtYmVyLgorICAgICAqCisgICAgICogQHJldHVybgorICAgICAqLworICAgIGludCBnZXRQcm92aWRlck51bWJlcigpIHsKKyAgICAgICAgcmV0dXJuIHByb3ZpZGVyTnVtYmVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgc2VydmljZSBvZiB0aGUgc3BlY2lmaWVkIHR5cGUKKyAgICAgKgorICAgICAqLworICAgIHN5bmNocm9uaXplZCBQcm92aWRlci5TZXJ2aWNlIGdldFNlcnZpY2UoU3RyaW5nIHR5cGUpIHsKKyAgICAgICAgdXBkYXRlUHJvcGVydHlTZXJ2aWNlVGFibGUoKTsKKyAgICAgICAgaWYgKGxhc3RTZXJ2aWNlc0J5VHlwZSAhPSBudWxsICYmIHR5cGUuZXF1YWxzKGxhc3RUeXBlKSkgeworICAgICAgICAgICAgcmV0dXJuIGxhc3RTZXJ2aWNlc0J5VHlwZTsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlci5TZXJ2aWNlIHNlcnZpY2U7CisgICAgICAgIGZvciAoSXRlcmF0b3I8U2VydmljZT4gaXQgPSBnZXRTZXJ2aWNlcygpLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTspIHsKKyAgICAgICAgICAgIHNlcnZpY2UgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICBpZiAodHlwZS5lcXVhbHMoc2VydmljZS50eXBlKSkgeworICAgICAgICAgICAgICAgIGxhc3RUeXBlID0gdHlwZTsKKyAgICAgICAgICAgICAgICBsYXN0U2VydmljZXNCeVR5cGUgPSBzZXJ2aWNlOworICAgICAgICAgICAgICAgIHJldHVybiBzZXJ2aWNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNlcnZpY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHtAY29kZSB0eXBlfSBpbXBsZW1lbnRpbmcgdGhlCisgICAgICogc3BlY2lmaWVkIHtAY29kZSBhbGdvcml0aG19LCBvciB7QGNvZGUgbnVsbH0gaWYgbm8gc3VjaCBpbXBsZW1lbnRhdGlvbgorICAgICAqIGV4aXN0cy4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0d28gc2VydmljZXMgbWF0Y2ggdGhlIHJlcXVlc3RlZCB0eXBlIGFuZCBhbGdvcml0aG0sIHRoZSBvbmUgYWRkZWQKKyAgICAgKiB3aXRoIHRoZSB7QGxpbmsgI3B1dFNlcnZpY2UoU2VydmljZSl9IGlzIHJldHVybmVkIChhcyBvcHBvc2VkIHRvIHRoZSBvbmUKKyAgICAgKiBhZGRlZCB2aWEge0BsaW5rICNwdXQoT2JqZWN0LCBPYmplY3QpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgc2VydmljZSAoZm9yIGV4YW1wbGUge0Bjb2RlIEtleVBhaXJHZW5lcmF0b3J9KQorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGdvcml0aG0gbmFtZSAoY2FzZSBpbnNlbnNpdGl2ZSkKKyAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0ZWQgc2VydmljZSwgb3Ige0Bjb2RlIG51bGx9IGlmIG5vIHN1Y2ggaW1wbGVtZW50YXRpb24KKyAgICAgKiAgICAgICAgIGV4aXN0cworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgUHJvdmlkZXIuU2VydmljZSBnZXRTZXJ2aWNlKFN0cmluZyB0eXBlLAorICAgICAgICAgICAgU3RyaW5nIGFsZ29yaXRobSkgeworICAgICAgICBpZiAodHlwZSA9PSBudWxsIHx8IGFsZ29yaXRobSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh0eXBlLmVxdWFscyhsYXN0U2VydmljZU5hbWUpICYmIGFsZ29yaXRobS5lcXVhbHNJZ25vcmVDYXNlKGxhc3RBbGdvcml0aG0pKSB7CisgICAgICAgICAgICByZXR1cm4gcmV0dXJuZWRTZXJ2aWNlOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGFsZyA9IGFsZ29yaXRobS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpOworICAgICAgICBPYmplY3QgbyA9IG51bGw7CisgICAgICAgIGlmIChzZXJ2aWNlVGFibGUgIT0gbnVsbCkgeworICAgICAgICAgICAgbyA9IHNlcnZpY2VUYWJsZS5nZXQodHlwZSwgYWxnKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobyA9PSBudWxsICYmIGFsaWFzVGFibGUgIT0gbnVsbCkgeworICAgICAgICAgICAgbyA9IGFsaWFzVGFibGUuZ2V0KHR5cGUsIGFsZyk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG8gPT0gbnVsbCkgeworICAgICAgICAgICAgdXBkYXRlUHJvcGVydHlTZXJ2aWNlVGFibGUoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobyA9PSBudWxsICYmIHByb3BlcnR5U2VydmljZVRhYmxlICE9IG51bGwpIHsKKyAgICAgICAgICAgIG8gPSBwcm9wZXJ0eVNlcnZpY2VUYWJsZS5nZXQodHlwZSwgYWxnKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobyA9PSBudWxsICYmIHByb3BlcnR5QWxpYXNUYWJsZSAhPSBudWxsKSB7CisgICAgICAgICAgICBvID0gcHJvcGVydHlBbGlhc1RhYmxlLmdldCh0eXBlLCBhbGcpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG8gIT0gbnVsbCkgeworICAgICAgICAgICAgbGFzdFNlcnZpY2VOYW1lID0gdHlwZTsKKyAgICAgICAgICAgIGxhc3RBbGdvcml0aG0gPSBhbGdvcml0aG07CisgICAgICAgICAgICByZXR1cm5lZFNlcnZpY2UgPSAoUHJvdmlkZXIuU2VydmljZSkgbzsKKyAgICAgICAgICAgIHJldHVybiByZXR1cm5lZFNlcnZpY2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiB1bm1vZGlmaWFibGUge0Bjb2RlIFNldH0gb2YgYWxsIHNlcnZpY2VzIHJlZ2lzdGVyZWQgYnkgdGhpcworICAgICAqIHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHJldHVybiBhbiB1bm1vZGlmaWFibGUge0Bjb2RlIFNldH0gb2YgYWxsIHNlcnZpY2VzIHJlZ2lzdGVyZWQgYnkgdGhpcworICAgICAqICAgICAgICAgcHJvdmlkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFNldDxQcm92aWRlci5TZXJ2aWNlPiBnZXRTZXJ2aWNlcygpIHsKKyAgICAgICAgdXBkYXRlUHJvcGVydHlTZXJ2aWNlVGFibGUoKTsKKyAgICAgICAgaWYgKGxhc3RTZXJ2aWNlc1NldCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbGFzdFNlcnZpY2VzU2V0OworICAgICAgICB9CisgICAgICAgIGlmIChzZXJ2aWNlVGFibGUgIT0gbnVsbCkgeworICAgICAgICAgICAgbGFzdFNlcnZpY2VzU2V0ID0gbmV3IEhhc2hTZXQ8U2VydmljZT4oc2VydmljZVRhYmxlLnZhbHVlcygpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGxhc3RTZXJ2aWNlc1NldCA9IG5ldyBIYXNoU2V0PFNlcnZpY2U+KCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHByb3BlcnR5U2VydmljZVRhYmxlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxhc3RTZXJ2aWNlc1NldC5hZGRBbGwocHJvcGVydHlTZXJ2aWNlVGFibGUudmFsdWVzKCkpOworICAgICAgICB9CisgICAgICAgIGxhc3RTZXJ2aWNlc1NldCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNldChsYXN0U2VydmljZXNTZXQpOworICAgICAgICByZXR1cm4gbGFzdFNlcnZpY2VzU2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSB7QGNvZGUgU2VydmljZX0gdG8gdGhpcyB7QGNvZGUgUHJvdmlkZXJ9LiBJZiBhIHNlcnZpY2Ugd2l0aCB0aGUKKyAgICAgKiBzYW1lIG5hbWUgd2FzIHJlZ2lzdGVyZWQgdmlhIHRoaXMgbWV0aG9kLCBpdCBpcyByZXBsYWNlLgorICAgICAqCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgU2VydmljZX0gdG8gcmVnaXN0ZXIKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgcHV0U2VydmljZShQcm92aWRlci5TZXJ2aWNlIHMpIHsKKyAgICAgICAgaWYgKHMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCJQcm92aWRlciIuZXF1YWxzKHMuZ2V0VHlwZSgpKSkgeyAvLyBQcm92aWRlciBzZXJ2aWNlIHR5cGUgY2Fubm90IGJlIGFkZGVkCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgc2VydmljZXNDaGFuZ2VkKCk7CisgICAgICAgIGlmIChzZXJ2aWNlVGFibGUgPT0gbnVsbCkgeworICAgICAgICAgICAgc2VydmljZVRhYmxlID0gbmV3IFR3b0tleUhhc2hNYXA8U3RyaW5nLCBTdHJpbmcsIFNlcnZpY2U+KDEyOCk7CisgICAgICAgIH0KKyAgICAgICAgc2VydmljZVRhYmxlLnB1dChzLnR5cGUsIHMuYWxnb3JpdGhtLnRvVXBwZXJDYXNlKExvY2FsZS5VUyksIHMpOworICAgICAgICBpZiAocy5hbGlhc2VzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChhbGlhc1RhYmxlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhbGlhc1RhYmxlID0gbmV3IFR3b0tleUhhc2hNYXA8U3RyaW5nLCBTdHJpbmcsIFNlcnZpY2U+KDI1Nik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKFN0cmluZyBhbGlhcyA6IHMuZ2V0QWxpYXNlcygpKSB7CisgICAgICAgICAgICAgICAgYWxpYXNUYWJsZS5wdXQocy50eXBlLCBhbGlhcy50b1VwcGVyQ2FzZShMb2NhbGUuVVMpLCBzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzZXJ2aWNlSW5mb1RvUHJvcGVydGllcyhzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGEgcHJldmlvdXNseSByZWdpc3RlcmVkIHtAY29kZSBTZXJ2aWNlfSBmcm9tIHRoaXMge0Bjb2RlCisgICAgICogUHJvdmlkZXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgU2VydmljZX0gdG8gcmVtb3ZlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzfSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgcmVtb3ZlU2VydmljZShQcm92aWRlci5TZXJ2aWNlIHMpIHsKKyAgICAgICAgaWYgKHMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgc2VydmljZXNDaGFuZ2VkKCk7CisgICAgICAgIGlmIChzZXJ2aWNlVGFibGUgIT0gbnVsbCkgeworICAgICAgICAgICAgc2VydmljZVRhYmxlLnJlbW92ZShzLnR5cGUsIHMuYWxnb3JpdGhtLnRvVXBwZXJDYXNlKExvY2FsZS5VUykpOworICAgICAgICB9CisgICAgICAgIGlmIChhbGlhc1RhYmxlICE9IG51bGwgJiYgcy5hbGlhc2VzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIGFsaWFzOiBzLmdldEFsaWFzZXMoKSkgeworICAgICAgICAgICAgICAgIGFsaWFzVGFibGUucmVtb3ZlKHMudHlwZSwgYWxpYXMudG9VcHBlckNhc2UoTG9jYWxlLlVTKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgc2VydmljZUluZm9Gcm9tUHJvcGVydGllcyhzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQgU2VydmljZSBpbmZvcm1hdGlvbiB0byB0aGUgcHJvdmlkZXIncyBwcm9wZXJ0aWVzLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXJ2aWNlSW5mb1RvUHJvcGVydGllcyhQcm92aWRlci5TZXJ2aWNlIHMpIHsKKyAgICAgICAgc3VwZXIucHV0KHMudHlwZSArICIuIiArIHMuYWxnb3JpdGhtLCBzLmNsYXNzTmFtZSk7CisgICAgICAgIGlmIChzLmFsaWFzZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChJdGVyYXRvcjxTdHJpbmc+IGkgPSBzLmFsaWFzZXMuaXRlcmF0b3IoKTsgaS5oYXNOZXh0KCk7KSB7CisgICAgICAgICAgICAgICAgc3VwZXIucHV0KCJBbGcuQWxpYXMuIiArIHMudHlwZSArICIuIiArIGkubmV4dCgpLCBzLmFsZ29yaXRobSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHMuYXR0cmlidXRlcyAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKE1hcC5FbnRyeTxTdHJpbmcsIFN0cmluZz4gZW50cnkgOiBzLmF0dHJpYnV0ZXMuZW50cnlTZXQoKSkgeworICAgICAgICAgICAgICAgIHN1cGVyLnB1dChzLnR5cGUgKyAiLiIgKyBzLmFsZ29yaXRobSArICIgIiArIGVudHJ5LmdldEtleSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgZW50cnkuZ2V0VmFsdWUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHByb3ZpZGVyTnVtYmVyICE9IC0xKSB7CisgICAgICAgICAgICAvLyBpZiByZWdpc3RlcmVkIHRoZW4gcmVmcmVzaCBTZXJ2aWNlcworICAgICAgICAgICAgU2VydmljZXMuc2V0TmVlZFJlZnJlc2goKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSBTZXJ2aWNlIGluZm9ybWF0aW9uIGZyb20gdGhlIHByb3ZpZGVyJ3MgcHJvcGVydGllcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2VydmljZUluZm9Gcm9tUHJvcGVydGllcyhQcm92aWRlci5TZXJ2aWNlIHMpIHsKKyAgICAgICAgc3VwZXIucmVtb3ZlKHMudHlwZSArICIuIiArIHMuYWxnb3JpdGhtKTsKKyAgICAgICAgaWYgKHMuYWxpYXNlcyAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yPFN0cmluZz4gaSA9IHMuYWxpYXNlcy5pdGVyYXRvcigpOyBpLmhhc05leHQoKTspIHsKKyAgICAgICAgICAgICAgICBzdXBlci5yZW1vdmUoIkFsZy5BbGlhcy4iICsgcy50eXBlICsgIi4iICsgaS5uZXh0KCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChzLmF0dHJpYnV0ZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBTdHJpbmc+IGVudHJ5IDogcy5hdHRyaWJ1dGVzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgICAgICBzdXBlci5yZW1vdmUocy50eXBlICsgIi4iICsgcy5hbGdvcml0aG0gKyAiICIgKyBlbnRyeS5nZXRLZXkoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHByb3ZpZGVyTnVtYmVyICE9IC0xKSB7CisgICAgICAgICAgICAvLyBpZiByZWdpc3RlcmVkIHRoZW4gcmVmcmVzaCBTZXJ2aWNlcworICAgICAgICAgICAgU2VydmljZXMuc2V0TmVlZFJlZnJlc2goKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFJlbW92ZSBwcm9wZXJ0eSBpbmZvcm1hdGlvbiBmcm9tIHByb3ZpZGVyIFNlcnZpY2VzCisgICAgcHJpdmF0ZSB2b2lkIHJlbW92ZUZyb21Qcm9wZXJ0eVNlcnZpY2VUYWJsZShPYmplY3Qga2V5KSB7CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCB8fCAhKGtleSBpbnN0YW5jZW9mIFN0cmluZykpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgayA9IChTdHJpbmcpIGtleTsKKyAgICAgICAgaWYgKGsuc3RhcnRzV2l0aCgiUHJvdmlkZXIuIikpIHsgLy8gUHJvdmlkZXIgc2VydmljZSB0eXBlIGlzIHJlc2VydmVkCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgUHJvdmlkZXIuU2VydmljZSBzOworICAgICAgICBTdHJpbmcgc2VydmljZU5hbWU7CisgICAgICAgIFN0cmluZyBhbGdvcml0aG0gPSBudWxsOworICAgICAgICBTdHJpbmcgYXR0cmlidXRlID0gbnVsbDsKKyAgICAgICAgaW50IGk7CisgICAgICAgIGlmIChrLnN0YXJ0c1dpdGgoIkFsZy5BbGlhcy4iKSkgeyAvLyBBbGcuQWxpYXMuPGNyeXB0b19zZXJ2aWNlPi48YWxpYXNOYW1lPj08c3RhbmRhcmROYW1lPgorICAgICAgICAgICAgU3RyaW5nIGFsaWFzTmFtZTsKKyAgICAgICAgICAgIFN0cmluZyBzZXJ2aWNlX2FsaWFzID0gay5zdWJzdHJpbmcoMTApOworICAgICAgICAgICAgaSA9IHNlcnZpY2VfYWxpYXMuaW5kZXhPZignLicpOworICAgICAgICAgICAgc2VydmljZU5hbWUgPSBzZXJ2aWNlX2FsaWFzLnN1YnN0cmluZygwLCBpKTsKKyAgICAgICAgICAgIGFsaWFzTmFtZSA9IHNlcnZpY2VfYWxpYXMuc3Vic3RyaW5nKGkgKyAxKTsKKyAgICAgICAgICAgIGlmIChwcm9wZXJ0eUFsaWFzVGFibGUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHByb3BlcnR5QWxpYXNUYWJsZS5yZW1vdmUoc2VydmljZU5hbWUsIGFsaWFzTmFtZS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChwcm9wZXJ0eVNlcnZpY2VUYWJsZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZm9yIChJdGVyYXRvcjxTZXJ2aWNlPiBpdCA9IHByb3BlcnR5U2VydmljZVRhYmxlLnZhbHVlcygpLml0ZXJhdG9yKCk7IGl0CisgICAgICAgICAgICAgICAgICAgICAgICAuaGFzTmV4dCgpOykgeworICAgICAgICAgICAgICAgICAgICBzID0gaXQubmV4dCgpOworICAgICAgICAgICAgICAgICAgICBpZiAocy5hbGlhc2VzLmNvbnRhaW5zKGFsaWFzTmFtZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHMuYWxpYXNlcy5yZW1vdmUoYWxpYXNOYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpbnQgaiA9IGsuaW5kZXhPZignLicpOworICAgICAgICBpZiAoaiA9PSAtMSkgeyAvLyB1bmtub3duIGZvcm1hdAorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaSA9IGsuaW5kZXhPZignICcpOworICAgICAgICBpZiAoaSA9PSAtMSkgeyAvLyA8Y3J5cHRvX3NlcnZpY2U+LjxhbGdvcml0aG1fb3JfdHlwZT49PGNsYXNzTmFtZT4KKyAgICAgICAgICAgIHNlcnZpY2VOYW1lID0gay5zdWJzdHJpbmcoMCwgaik7CisgICAgICAgICAgICBhbGdvcml0aG0gPSBrLnN1YnN0cmluZyhqICsgMSk7CisgICAgICAgICAgICBpZiAocHJvcGVydHlTZXJ2aWNlVGFibGUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIFByb3ZpZGVyLlNlcnZpY2Ugc2VyID0gcHJvcGVydHlTZXJ2aWNlVGFibGUucmVtb3ZlKHNlcnZpY2VOYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgYWxnb3JpdGhtLnRvVXBwZXJDYXNlKExvY2FsZS5VUykpOworICAgICAgICAgICAgICAgIGlmIChzZXIgIT0gbnVsbCAmJiBwcm9wZXJ0eUFsaWFzVGFibGUgIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgJiYgc2VyLmFsaWFzZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBmb3IgKFN0cmluZyBhbGlhcyA6IHNlci5hbGlhc2VzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eUFsaWFzVGFibGUucmVtb3ZlKHNlcnZpY2VOYW1lLCBhbGlhcy50b1VwcGVyQ2FzZShMb2NhbGUuVVMpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIDxjcnlwdG9fc2VydmljZT4uPGFsZ29yaXRobV9vcl90eXBlPgorICAgICAgICAgICAgLy8gPGF0dHJpYnV0ZV9uYW1lPj08YXR0clZhbHVlPgorICAgICAgICAgICAgYXR0cmlidXRlID0gay5zdWJzdHJpbmcoaSArIDEpOworICAgICAgICAgICAgc2VydmljZU5hbWUgPSBrLnN1YnN0cmluZygwLCBqKTsKKyAgICAgICAgICAgIGFsZ29yaXRobSA9IGsuc3Vic3RyaW5nKGogKyAxLCBpKTsKKyAgICAgICAgICAgIGlmIChwcm9wZXJ0eVNlcnZpY2VUYWJsZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgT2JqZWN0IG8gPSBwcm9wZXJ0eVNlcnZpY2VUYWJsZS5nZXQoc2VydmljZU5hbWUsIGFsZ29yaXRobS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpKTsKKyAgICAgICAgICAgICAgICBpZiAobyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHMgPSAoUHJvdmlkZXIuU2VydmljZSkgbzsKKyAgICAgICAgICAgICAgICAgICAgcy5hdHRyaWJ1dGVzLnJlbW92ZShhdHRyaWJ1dGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFVwZGF0ZSBwcm92aWRlciBTZXJ2aWNlcyBpZiB0aGUgcHJvcGVydGllcyB3YXMgY2hhbmdlZAorICAgIHByaXZhdGUgdm9pZCB1cGRhdGVQcm9wZXJ0eVNlcnZpY2VUYWJsZSgpIHsKKyAgICAgICAgT2JqZWN0IF9rZXk7CisgICAgICAgIE9iamVjdCBfdmFsdWU7CisgICAgICAgIFByb3ZpZGVyLlNlcnZpY2UgczsKKyAgICAgICAgU3RyaW5nIHNlcnZpY2VOYW1lOworICAgICAgICBTdHJpbmcgYWxnb3JpdGhtOworICAgICAgICBpZiAoY2hhbmdlZFByb3BlcnRpZXMgPT0gbnVsbCB8fCBjaGFuZ2VkUHJvcGVydGllcy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmb3IgKEl0ZXJhdG9yPE1hcC5FbnRyeTxPYmplY3QsIE9iamVjdD4+IGl0ID0gY2hhbmdlZFByb3BlcnRpZXMuZW50cnlTZXQoKS5pdGVyYXRvcigpOyBpdAorICAgICAgICAgICAgICAgIC5oYXNOZXh0KCk7KSB7CisgICAgICAgICAgICBNYXAuRW50cnk8T2JqZWN0LCBPYmplY3Q+IGVudHJ5ID0gaXQubmV4dCgpOworICAgICAgICAgICAgX2tleSA9IGVudHJ5LmdldEtleSgpOworICAgICAgICAgICAgX3ZhbHVlID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgIGlmIChfa2V5ID09IG51bGwgfHwgX3ZhbHVlID09IG51bGwgfHwgIShfa2V5IGluc3RhbmNlb2YgU3RyaW5nKQorICAgICAgICAgICAgICAgICAgICB8fCAhKF92YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN0cmluZyBrZXkgPSAoU3RyaW5nKSBfa2V5OworICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gKFN0cmluZykgX3ZhbHVlOworICAgICAgICAgICAgaWYgKGtleS5zdGFydHNXaXRoKCJQcm92aWRlciIpKSB7CisgICAgICAgICAgICAgICAgLy8gUHJvdmlkZXIgc2VydmljZSB0eXBlIGlzIHJlc2VydmVkCisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgaTsKKyAgICAgICAgICAgIGlmIChrZXkuc3RhcnRzV2l0aCgiQWxnLkFsaWFzLiIpKSB7CisgICAgICAgICAgICAgICAgLy8gQWxnLkFsaWFzLjxjcnlwdG9fc2VydmljZT4uPGFsaWFzTmFtZT49PHN0YW5kYXJkTmFtZT4KKyAgICAgICAgICAgICAgICBTdHJpbmcgYWxpYXNOYW1lOworICAgICAgICAgICAgICAgIFN0cmluZyBzZXJ2aWNlX2FsaWFzID0ga2V5LnN1YnN0cmluZygxMCk7CisgICAgICAgICAgICAgICAgaSA9IHNlcnZpY2VfYWxpYXMuaW5kZXhPZignLicpOworICAgICAgICAgICAgICAgIHNlcnZpY2VOYW1lID0gc2VydmljZV9hbGlhcy5zdWJzdHJpbmcoMCwgaSk7CisgICAgICAgICAgICAgICAgYWxpYXNOYW1lID0gc2VydmljZV9hbGlhcy5zdWJzdHJpbmcoaSArIDEpOworICAgICAgICAgICAgICAgIGFsZ29yaXRobSA9IHZhbHVlOworICAgICAgICAgICAgICAgIFN0cmluZyBhbGdVcCA9IGFsZ29yaXRobS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpOworICAgICAgICAgICAgICAgIE9iamVjdCBvID0gbnVsbDsKKyAgICAgICAgICAgICAgICBpZiAocHJvcGVydHlTZXJ2aWNlVGFibGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eVNlcnZpY2VUYWJsZSA9IG5ldyBUd29LZXlIYXNoTWFwPFN0cmluZywgU3RyaW5nLCBTZXJ2aWNlPigxMjgpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIG8gPSBwcm9wZXJ0eVNlcnZpY2VUYWJsZS5nZXQoc2VydmljZU5hbWUsIGFsZ1VwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKG8gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBzID0gKFByb3ZpZGVyLlNlcnZpY2UpIG87CisgICAgICAgICAgICAgICAgICAgIHMuYWRkQWxpYXMoYWxpYXNOYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnR5QWxpYXNUYWJsZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eUFsaWFzVGFibGUgPSBuZXcgVHdvS2V5SGFzaE1hcDxTdHJpbmcsIFN0cmluZywgU2VydmljZT4oMjU2KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eUFsaWFzVGFibGUucHV0KHNlcnZpY2VOYW1lLCBhbGlhc05hbWUudG9VcHBlckNhc2UoTG9jYWxlLlVTKSwgcyk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9IChTdHJpbmcpIGNoYW5nZWRQcm9wZXJ0aWVzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldChzZXJ2aWNlTmFtZSArICIuIiArIGFsZ29yaXRobSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChjbGFzc05hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxTdHJpbmc+IGwgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGwuYWRkKGFsaWFzTmFtZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBzID0gbmV3IFByb3ZpZGVyLlNlcnZpY2UodGhpcywgc2VydmljZU5hbWUsIGFsZ29yaXRobSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLCBsLCBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eVNlcnZpY2VUYWJsZS5wdXQoc2VydmljZU5hbWUsIGFsZ1VwLCBzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0eUFsaWFzVGFibGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5QWxpYXNUYWJsZSA9IG5ldyBUd29LZXlIYXNoTWFwPFN0cmluZywgU3RyaW5nLCBTZXJ2aWNlPigyNTYpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHlBbGlhc1RhYmxlLnB1dChzZXJ2aWNlTmFtZSwgYWxpYXNOYW1lLnRvVXBwZXJDYXNlKExvY2FsZS5VUyksIHMpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IGogPSBrZXkuaW5kZXhPZignLicpOworICAgICAgICAgICAgaWYgKGogPT0gLTEpIHsgLy8gdW5rbm93biBmb3JtYXQKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGkgPSBrZXkuaW5kZXhPZignICcpOworICAgICAgICAgICAgaWYgKGkgPT0gLTEpIHsgLy8gPGNyeXB0b19zZXJ2aWNlPi48YWxnb3JpdGhtX29yX3R5cGU+PTxjbGFzc05hbWU+CisgICAgICAgICAgICAgICAgc2VydmljZU5hbWUgPSBrZXkuc3Vic3RyaW5nKDAsIGopOworICAgICAgICAgICAgICAgIGFsZ29yaXRobSA9IGtleS5zdWJzdHJpbmcoaiArIDEpOworICAgICAgICAgICAgICAgIFN0cmluZyBhbGcgPSBhbGdvcml0aG0udG9VcHBlckNhc2UoTG9jYWxlLlVTKTsKKyAgICAgICAgICAgICAgICBPYmplY3QgbyA9IG51bGw7CisgICAgICAgICAgICAgICAgaWYgKHByb3BlcnR5U2VydmljZVRhYmxlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgbyA9IHByb3BlcnR5U2VydmljZVRhYmxlLmdldChzZXJ2aWNlTmFtZSwgYWxnKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKG8gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBzID0gKFByb3ZpZGVyLlNlcnZpY2UpIG87CisgICAgICAgICAgICAgICAgICAgIHMuY2xhc3NOYW1lID0gdmFsdWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcyA9IG5ldyBQcm92aWRlci5TZXJ2aWNlKHRoaXMsIHNlcnZpY2VOYW1lLCBhbGdvcml0aG0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUsIENvbGxlY3Rpb25zLjxTdHJpbmc+ZW1wdHlMaXN0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGVjdGlvbnMuPFN0cmluZyxTdHJpbmc+ZW1wdHlNYXAoKSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0eVNlcnZpY2VUYWJsZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eVNlcnZpY2VUYWJsZSA9IG5ldyBUd29LZXlIYXNoTWFwPFN0cmluZywgU3RyaW5nLCBTZXJ2aWNlPigxMjgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5U2VydmljZVRhYmxlLnB1dChzZXJ2aWNlTmFtZSwgYWxnLCBzKTsKKworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gPGNyeXB0b19zZXJ2aWNlPi48YWxnb3JpdGhtX29yX3R5cGU+CisgICAgICAgICAgICAgICAgLy8gPGF0dHJpYnV0ZV9uYW1lPj08YXR0clZhbHVlPgorICAgICAgICAgICAgICAgIHNlcnZpY2VOYW1lID0ga2V5LnN1YnN0cmluZygwLCBqKTsKKyAgICAgICAgICAgICAgICBhbGdvcml0aG0gPSBrZXkuc3Vic3RyaW5nKGogKyAxLCBpKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcgYXR0cmlidXRlID0ga2V5LnN1YnN0cmluZyhpICsgMSk7CisgICAgICAgICAgICAgICAgU3RyaW5nIGFsZyA9IGFsZ29yaXRobS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpOworICAgICAgICAgICAgICAgIE9iamVjdCBvID0gbnVsbDsKKyAgICAgICAgICAgICAgICBpZiAocHJvcGVydHlTZXJ2aWNlVGFibGUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBvID0gcHJvcGVydHlTZXJ2aWNlVGFibGUuZ2V0KHNlcnZpY2VOYW1lLCBhbGcpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAobyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHMgPSAoUHJvdmlkZXIuU2VydmljZSkgbzsKKyAgICAgICAgICAgICAgICAgICAgcy5wdXRBdHRyaWJ1dGUoYXR0cmlidXRlLCB2YWx1ZSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9IChTdHJpbmcpIGNoYW5nZWRQcm9wZXJ0aWVzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldChzZXJ2aWNlTmFtZSArICIuIiArIGFsZ29yaXRobSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChjbGFzc05hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZywgU3RyaW5nPiBtID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgICAgICAgICAgICAgICAgICAgICBtLnB1dChhdHRyaWJ1dGUsIHZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBuZXcgUHJvdmlkZXIuU2VydmljZSh0aGlzLCBzZXJ2aWNlTmFtZSwgYWxnb3JpdGhtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWUsIG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpLCBtKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0eVNlcnZpY2VUYWJsZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHlTZXJ2aWNlVGFibGUgPSBuZXcgVHdvS2V5SGFzaE1hcDxTdHJpbmcsIFN0cmluZywgU2VydmljZT4oMTI4KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5U2VydmljZVRhYmxlLnB1dChzZXJ2aWNlTmFtZSwgYWxnLCBzKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzZXJ2aWNlc0NoYW5nZWQoKTsKKyAgICAgICAgY2hhbmdlZFByb3BlcnRpZXMgPSBudWxsOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzZXJ2aWNlc0NoYW5nZWQoKSB7CisgICAgICAgIGxhc3RTZXJ2aWNlc0J5VHlwZSA9IG51bGw7CisgICAgICAgIGxhc3RTZXJ2aWNlTmFtZSA9IG51bGw7CisgICAgICAgIGxhc3RTZXJ2aWNlc1NldCA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlc2UgYXR0cmlidXRlcyBzaG91bGQgYmUgcGxhY2VkIGluIGVhY2ggUHJvdmlkZXIgb2JqZWN0OgorICAgICAqIFByb3ZpZGVyLmlkIG5hbWUsIFByb3ZpZGVyLmlkIHZlcnNpb24sIFByb3ZpZGVyLmlkIGluZm8sCisgICAgICogUHJvdmlkZXIuaWQgY2xhc3NOYW1lCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHB1dFByb3ZpZGVySW5mbygpIHsKKyAgICAgICAgc3VwZXIucHV0KCJQcm92aWRlci5pZCBuYW1lIiwgKG5hbWUgIT0gbnVsbCkgPyBuYW1lIDogIm51bGwiKTsKKyAgICAgICAgc3VwZXIucHV0KCJQcm92aWRlci5pZCB2ZXJzaW9uIiwgdmVyc2lvblN0cmluZyk7CisgICAgICAgIHN1cGVyLnB1dCgiUHJvdmlkZXIuaWQgaW5mbyIsIChpbmZvICE9IG51bGwpID8gaW5mbyA6ICJudWxsIik7CisgICAgICAgIHN1cGVyLnB1dCgiUHJvdmlkZXIuaWQgY2xhc3NOYW1lIiwgdGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJvcGVydHkgd2l0aCB0aGUgc3BlY2lmaWVkIGtleSBpbiB0aGUgcHJvdmlkZXIgcHJvcGVydGllcy4KKyAgICAgKiBUaGUgbmFtZSBpcyBub3QgY2FzZS1zZW5zaXRpdmUuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0UHJvcGVydHlJZ25vcmVDYXNlKFN0cmluZyBrZXkpIHsKKyAgICAgICAgU3RyaW5nIHJlcyA9IGdldFByb3BlcnR5KGtleSk7CisgICAgICAgIGlmIChyZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHJlczsKKyAgICAgICAgfQorICAgICAgICBmb3IgKEVudW1lcmF0aW9uPD8+IGUgPSBwcm9wZXJ0eU5hbWVzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7ICkgeworICAgICAgICAgICAgU3RyaW5nIHByb3BlcnR5TmFtZSA9IChTdHJpbmcpIGUubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGlmIChrZXkuZXF1YWxzSWdub3JlQ2FzZShwcm9wZXJ0eU5hbWUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGdldFByb3BlcnR5KHByb3BlcnR5TmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bjb2RlIFNlcnZpY2V9IHJlcHJlc2VudHMgYSBzZXJ2aWNlIGluIHRoZSBKYXZhIFNlY3VyaXR5IGluZnJhc3RydWN0dXJlLgorICAgICAqIEVhY2ggc2VydmljZSBkZXNjcmliZXMgaXRzIHR5cGUsIHRoZSBhbGdvcml0aG0gaXQgaW1wbGVtZW50cywgdG8gd2hpY2gKKyAgICAgKiBwcm92aWRlciBpdCBiZWxvbmdzIGFuZCBvdGhlciBwcm9wZXJ0aWVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgU2VydmljZSB7CisgICAgICAgIC8vIFRoZSBwcm92aWRlcgorICAgICAgICBwcml2YXRlIFByb3ZpZGVyIHByb3ZpZGVyOworCisgICAgICAgIC8vIFRoZSB0eXBlIG9mIHRoaXMgc2VydmljZQorICAgICAgICBwcml2YXRlIFN0cmluZyB0eXBlOworCisgICAgICAgIC8vIFRoZSBhbGdvcml0aG0gbmFtZQorICAgICAgICBwcml2YXRlIFN0cmluZyBhbGdvcml0aG07CisKKyAgICAgICAgLy8gVGhlIGNsYXNzIGltcGxlbWVudGluZyB0aGlzIHNlcnZpY2UKKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgY2xhc3NOYW1lOworCisgICAgICAgIC8vIFRoZSBhbGlhc2VzCisgICAgICAgIHByaXZhdGUgTGlzdDxTdHJpbmc+IGFsaWFzZXM7CisKKyAgICAgICAgLy8gVGhlIGF0dHJpYnV0ZXMKKyAgICAgICAgcHJpdmF0ZSBNYXA8U3RyaW5nLFN0cmluZz4gYXR0cmlidXRlczsKKworICAgICAgICAvLyBTZXJ2aWNlIGltcGxlbWVudGF0aW9uCisgICAgICAgIHByaXZhdGUgQ2xhc3M8Pz4gaW1wbGVtZW50YXRpb247CisKKyAgICAgICAgLy8gRm9yIG5ld0luc3RhbmNlKCkgb3B0aW1pemF0aW9uCisgICAgICAgIHByaXZhdGUgU3RyaW5nIGxhc3RDbGFzc05hbWU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFNlcnZpY2V9IHdpdGggdGhlIGdpdmVuCisgICAgICAgICAqIGF0dHJpYnV0ZXMuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBwcm92aWRlciB0byB3aGljaCB0aGlzIHNlcnZpY2UgYmVsb25ncy4KKyAgICAgICAgICogQHBhcmFtIHR5cGUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGlzIHNlcnZpY2UgKGZvciBleGFtcGxlIHtAY29kZQorICAgICAgICAgKiAgICAgICAgICAgIEtleVBhaXJHZW5lcmF0b3J9KS4KKyAgICAgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBhbGdvcml0aG0gdGhpcyBzZXJ2aWNlIGltcGxlbWVudHMuCisgICAgICAgICAqIEBwYXJhbSBjbGFzc05hbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgaW1wbGVtZW50aW5nIHRoaXMgc2VydmljZS4KKyAgICAgICAgICogQHBhcmFtIGFsaWFzZXMKKyAgICAgICAgICogICAgICAgICAgICB7QGNvZGUgTGlzdH0gb2YgYWxpYXNlcyBmb3IgdGhlIGFsZ29yaXRobSBuYW1lLCBvciB7QGNvZGUKKyAgICAgICAgICogICAgICAgICAgICBudWxsfSBpZiB0aGUgaW1wbGVtZW50ZWQgYWxnb3JpdGhtIGhhcyBubyBhbGlhc2VzLgorICAgICAgICAgKiBAcGFyYW0gYXR0cmlidXRlcworICAgICAgICAgKiAgICAgICAgICAgIHtAY29kZSBNYXB9IG9mIGFkZGl0aW9uYWwgYXR0cmlidXRlcywgb3Ige0Bjb2RlIG51bGx9IGlmCisgICAgICAgICAqICAgICAgICAgICAgdGhpcyB7QGNvZGUgU2VydmljZX0gaGFzIG5vIGF0dHJpYnV0ZWQuCisgICAgICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHByb3ZpZGVyLCB0eXBlLCBhbGdvcml0aG19IG9yIHtAY29kZSBjbGFzc05hbWV9CisgICAgICAgICAqICAgICAgICAgICAgIGlzIHtAY29kZSBudWxsfS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBTZXJ2aWNlKFByb3ZpZGVyIHByb3ZpZGVyLCBTdHJpbmcgdHlwZSwgU3RyaW5nIGFsZ29yaXRobSwKKyAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lLCBMaXN0PFN0cmluZz4gYWxpYXNlcywgTWFwPFN0cmluZywgU3RyaW5nPiBhdHRyaWJ1dGVzKSB7CisgICAgICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCB8fCB0eXBlID09IG51bGwgfHwgYWxnb3JpdGhtID09IG51bGwKKyAgICAgICAgICAgICAgICAgICAgfHwgY2xhc3NOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMucHJvdmlkZXIgPSBwcm92aWRlcjsKKyAgICAgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICAgICAgICAgIHRoaXMuY2xhc3NOYW1lID0gY2xhc3NOYW1lOworICAgICAgICAgICAgdGhpcy5hbGlhc2VzID0gKChhbGlhc2VzICE9IG51bGwpICYmIChhbGlhc2VzLnNpemUoKSA9PSAwKSkKKyAgICAgICAgICAgICAgICAgICAgPyBDb2xsZWN0aW9ucy48U3RyaW5nPmVtcHR5TGlzdCgpIDogYWxpYXNlczsKKyAgICAgICAgICAgIHRoaXMuYXR0cmlidXRlcyA9CisgICAgICAgICAgICAgICAgICAgICgoYXR0cmlidXRlcyAhPSBudWxsKSAmJiAoYXR0cmlidXRlcy5zaXplKCkgPT0gMCkpCisgICAgICAgICAgICAgICAgICAgID8gQ29sbGVjdGlvbnMuPFN0cmluZyxTdHJpbmc+ZW1wdHlNYXAoKSA6IGF0dHJpYnV0ZXM7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQWRkcyBhbiBhbGlhcy4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIGFsaWFzIHRoZSBhbGlhcyB0byBhZGQKKyAgICAgICAgICovCisgICAgICAgIC8qcGFja2FnZSovIHZvaWQgYWRkQWxpYXMoU3RyaW5nIGFsaWFzKSB7CisgICAgICAgICAgICBpZiAoKGFsaWFzZXMgPT0gbnVsbCkgfHwgKGFsaWFzZXMuc2l6ZSgpID09IDApKSB7CisgICAgICAgICAgICAgICAgYWxpYXNlcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYWxpYXNlcy5hZGQoYWxpYXMpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFB1dHMgYSBuZXcgYXR0cmlidXRlIG1hcHBpbmcuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBuYW1lIHRoZSBhdHRyaWJ1dGUgbmFtZS4KKyAgICAgICAgICogQHBhcmFtIHZhbHVlIHRoZSBhdHRyaWJ1dGUgdmFsdWUuCisgICAgICAgICAqLworICAgICAgICAvKnBhY2thZ2UqLyB2b2lkIHB1dEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgICAgICBpZiAoKGF0dHJpYnV0ZXMgPT0gbnVsbCkgfHwgKGF0dHJpYnV0ZXMuc2l6ZSgpID09IDApKSB7CisgICAgICAgICAgICAgICAgYXR0cmlidXRlcyA9IG5ldyBIYXNoTWFwPFN0cmluZyxTdHJpbmc+KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhdHRyaWJ1dGVzLnB1dChuYW1lLCB2YWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgdHlwZSBvZiB0aGlzIHtAY29kZSBTZXJ2aWNlfS4gRm9yIGV4YW1wbGUge0Bjb2RlCisgICAgICAgICAqIEtleVBhaXJHZW5lcmF0b3J9LgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIG9mIHRoaXMge0Bjb2RlIFNlcnZpY2V9LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRUeXBlKCkgeworICAgICAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtIGltcGxlbWVudGVkIGJ5IHRoaXMge0Bjb2RlCisgICAgICAgICAqIFNlcnZpY2V9LgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0gaW1wbGVtZW50ZWQgYnkgdGhpcyB7QGNvZGUKKyAgICAgICAgICogICAgICAgICBTZXJ2aWNlfS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICAgICAgcmV0dXJuIGFsZ29yaXRobTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgUHJvdmlkZXJ9IHRoaXMge0Bjb2RlIFNlcnZpY2V9IGJlbG9uZ3MgdG8uCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBQcm92aWRlcn0gdGhpcyB7QGNvZGUgU2VydmljZX0gYmVsb25ncyB0by4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmaW5hbCBQcm92aWRlciBnZXRQcm92aWRlcigpIHsKKyAgICAgICAgICAgIHJldHVybiBwcm92aWRlcjsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyBpbXBsZW1lbnRpbmcgdGhpcyB7QGNvZGUgU2VydmljZX0uCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGNsYXNzIGltcGxlbWVudGluZyB0aGlzIHtAY29kZSBTZXJ2aWNlfS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0Q2xhc3NOYW1lKCkgeworICAgICAgICAgICAgcmV0dXJuIGNsYXNzTmFtZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlIHdpdGggdGhlIHNwZWNpZmllZCB7QGNvZGUgbmFtZX0uCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBuYW1lCisgICAgICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KKyAgICAgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSwgb3Ige0Bjb2RlIG51bGx9IGlmIG5vIGF0dHJpYnV0ZQorICAgICAgICAgKiAgICAgICAgIHdpdGggdGhlIGdpdmVuIG5hbWUgaXMgc2V0LgorICAgICAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBuYW1lfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSkgeworICAgICAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXMuZ2V0KG5hbWUpOworICAgICAgICB9CisKKyAgICAgICAgTGlzdDxTdHJpbmc+IGdldEFsaWFzZXMoKSB7CisgICAgICAgICAgICBpZiAoYWxpYXNlcyA9PSBudWxsKXsKKyAgICAgICAgICAgICAgICBhbGlhc2VzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KDApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGFsaWFzZXM7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBhbmQgcmV0dXJucyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgaW1wbGVtZW50YXRpb24gZGVzY3JpYmVkIGJ5CisgICAgICAgICAqIHRoaXMge0Bjb2RlIFNlcnZpY2V9LgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gY29uc3RydWN0b3JQYXJhbWV0ZXIKKyAgICAgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIHRoYXQgaXMgdXNlZCBieSB0aGUgY29uc3RydWN0b3IsIG9yIHtAY29kZQorICAgICAgICAgKiAgICAgICAgICAgIG51bGx9IGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBkZWNsYXJlIGEgY29uc3RydWN0b3IKKyAgICAgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIuCisgICAgICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGltcGxlbWVudGF0aW9uIGRlc2NyaWJlZCBieSB0aGlzCisgICAgICAgICAqICAgICAgICAge0Bjb2RlIFNlcnZpY2V9LgorICAgICAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaW5zdGFuY2UgY291bGQgbm90IGJlIGNvbnN0cnVjdGVkLgorICAgICAgICAgKiBAdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYgdGhlIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgdGhlIHNwZWNpZmllZAorICAgICAgICAgKiAgICAgICAgICAgICB7QGNvZGUgY29uc3RydWN0b3JQYXJhbWV0ZXJ9LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIE9iamVjdCBuZXdJbnN0YW5jZShPYmplY3QgY29uc3RydWN0b3JQYXJhbWV0ZXIpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICAgICAgaWYgKGltcGxlbWVudGF0aW9uID09IG51bGwgfHwgIWNsYXNzTmFtZS5lcXVhbHMobGFzdENsYXNzTmFtZSkpIHsKKyAgICAgICAgICAgICAgICBDbGFzc0xvYWRlciBjbCA9IHByb3ZpZGVyLmdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgICAgICAgICBpZiAoY2wgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBjbCA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGltcGxlbWVudGF0aW9uID0gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUsIHRydWUsIGNsKTsKKyAgICAgICAgICAgICAgICAgICAgbGFzdENsYXNzTmFtZSA9IGNsYXNzTmFtZTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKHR5cGUgKyAiICIgKyBhbGdvcml0aG0gKyAiIGltcGxlbWVudGF0aW9uIG5vdCBmb3VuZDogIiArIGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjb25zdHJ1Y3RvclBhcmFtZXRlciA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltcGxlbWVudGF0aW9uLm5ld0luc3RhbmNlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlICsgIiAiICsgYWxnb3JpdGhtICsgIiBpbXBsZW1lbnRhdGlvbiBub3QgZm91bmQiLCBlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIXN1cHBvcnRzUGFyYW1ldGVyKGNvbnN0cnVjdG9yUGFyYW1ldGVyKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKHR5cGUgKyAiOiBzZXJ2aWNlIGNhbm5vdCB1c2UgdGhlIHBhcmFtZXRlciIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBDbGFzc1tdIHBhcmFtZXRlclR5cGVzID0gbmV3IENsYXNzWzFdOworICAgICAgICAgICAgT2JqZWN0W10gaW5pdGFyZ3MgPSB7IGNvbnN0cnVjdG9yUGFyYW1ldGVyIH07CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmICh0eXBlLmVxdWFsc0lnbm9yZUNhc2UoIkNlcnRTdG9yZSIpKSB7CisgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlclR5cGVzWzBdID0gQ2xhc3MuZm9yTmFtZSgiamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRTdG9yZVBhcmFtZXRlcnMiKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJUeXBlc1swXSA9IGNvbnN0cnVjdG9yUGFyYW1ldGVyLmdldENsYXNzKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBpbXBsZW1lbnRhdGlvbi5nZXRDb25zdHJ1Y3RvcihwYXJhbWV0ZXJUeXBlcykKKyAgICAgICAgICAgICAgICAgICAgICAgIC5uZXdJbnN0YW5jZShpbml0YXJncyk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24odHlwZSArICIgIiArIGFsZ29yaXRobQorICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGltcGxlbWVudGF0aW9uIG5vdCBmb3VuZCIsIGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMge0Bjb2RlIFNlcnZpY2V9IHN1cHBvcnRzIHRoZSBzcGVjaWZpZWQKKyAgICAgICAgICogY29uc3RydWN0b3IgcGFyYW1ldGVyLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gcGFyYW1ldGVyCisgICAgICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciB0byB0ZXN0LgorICAgICAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBTZXJ2aWNlfSBzdXBwb3J0cyB0aGUgc3BlY2lmaWVkCisgICAgICAgICAqICAgICAgICAgY29uc3RydWN0b3IgcGFyYW1ldGVyLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzUGFyYW1ldGVyKE9iamVjdCBwYXJhbWV0ZXIpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIGNvbmNpc2UsIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIG9mCisgICAgICAgICAqIHRoaXMge0Bjb2RlIFNlcnZpY2V9LgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIGEgcHJpbnRhYmxlIHJlcHJlc2VudGF0aW9uIGZvciB0aGlzIHtAY29kZSBTZXJ2aWNlfS4KKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgU3RyaW5nIHJlc3VsdCA9ICJQcm92aWRlciAiICsgcHJvdmlkZXIuZ2V0TmFtZSgpICsgIiBTZXJ2aWNlICIKKyAgICAgICAgICAgICAgICAgICAgKyB0eXBlICsgIi4iICsgYWxnb3JpdGhtICsgIiAiICsgY2xhc3NOYW1lOworICAgICAgICAgICAgaWYgKGFsaWFzZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICJcbkFsaWFzZXMgIiArIGFsaWFzZXMudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAiXG5BdHRyaWJ1dGVzICIgKyBhdHRyaWJ1dGVzLnRvU3RyaW5nKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSBpbikKKyAgICAgICAgICAgIHRocm93cyBOb3RBY3RpdmVFeGNlcHRpb24sIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgaW4uZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgdmVyc2lvblN0cmluZyA9IFN0cmluZy52YWx1ZU9mKHZlcnNpb24pOworICAgICAgICBwcm92aWRlck51bWJlciA9IC0xOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1Byb3ZpZGVyRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9Qcm92aWRlckV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQxZmNkNWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9Qcm92aWRlckV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworLyoqCisgKiB7QGNvZGUgUHJvdmlkZXJFeGNlcHRpb259IGlzIGEgZ2VuZXJhbCBleGNlcHRpb24sIHRocm93biBieSBzZWN1cml0eSB7QGNvZGUKKyAqIFByb3ZpZGVyc30uCisgKgorICogQHNlZSBQcm92aWRlcgorICovCitwdWJsaWMgY2xhc3MgUHJvdmlkZXJFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDUyNTYwMjM1MjY2OTM2NjU2NzRMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgUHJvdmlkZXJFeGNlcHRpb259IHdpdGggdGhlIGdpdmVuCisgICAgICogbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFByb3ZpZGVyRXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKKyAgICAgICAgc3VwZXIobXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBQcm92aWRlckV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIFByb3ZpZGVyRXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFByb3ZpZGVyRXhjZXB0aW9ufSB3aXRoIHRoZSBnaXZlbgorICAgICAqIG1lc3NhZ2UgYW5kIHRoZSBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGV4Y2VwdGlvbiB3aGljaCBpcyB0aGUgY2F1c2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBQcm92aWRlckV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UsIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBQcm92aWRlckV4Y2VwdGlvbn0gd2l0aCB0aGUgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNlcHRpb24gd2hpY2ggaXMgdGhlIGNhdXNlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvdmlkZXJFeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9QdWJsaWNLZXkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1B1YmxpY0tleS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY0Nzc3YWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9QdWJsaWNLZXkuamF2YQpAQCAtMCwwICsxLDMwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKKy8qKgorICoge0Bjb2RlIFB1YmxpY0tleX0gaXMgdGhlIGNvbW1vbiBpbnRlcmZhY2UgZm9yIHB1YmxpYyBrZXlzLgorICoKKyAqIEBzZWUgUHJpdmF0ZUtleQorICovCitwdWJsaWMgaW50ZXJmYWNlIFB1YmxpY0tleSBleHRlbmRzIEtleSB7CisgICAgLyoqCisgICAgICogVGhlIHtAY29kZSBzZXJpYWxWZXJzaW9uVUlEfSB0byBiZSBjb21wYXRpYmxlIHdpdGggSkRLMS4xLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzE4NzM5MjQ3MTE1OTE1MTA3Mkw7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9TZWN1cmVDbGFzc0xvYWRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2VjdXJlQ2xhc3NMb2FkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMzlhNDMwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2VjdXJlQ2xhc3NMb2FkZXIuamF2YQpAQCAtMCwwICsxLDE0NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKKworLyoqCisgKiB7QGNvZGUgU2VjdXJlQ2xhc3NMb2FkZXJ9IHJlcHJlc2VudHMgYSB7QGNvZGUgQ2xhc3NMb2FkZXJ9IHdoaWNoIGFzc29jaWF0ZXMKKyAqIHRoZSBjbGFzc2VzIGl0IGxvYWRzIHdpdGggYSBjb2RlIHNvdXJjZSBhbmQgcHJvdmlkZSBtZWNoYW5pc21zIHRvIGFsbG93IHRoZQorICogcmVsZXZhbnQgcGVybWlzc2lvbnMgdG8gYmUgcmV0cmlldmVkLgorICovCitwdWJsaWMgY2xhc3MgU2VjdXJlQ2xhc3NMb2FkZXIgZXh0ZW5kcyBDbGFzc0xvYWRlciB7CisKKyAgICAvLyBBIGNhY2hlIG9mIFByb3RlY3Rpb25Eb21haW5zIGZvciBhIGdpdmVuIENvZGVTb3VyY2UKKyAgICBwcml2YXRlIEhhc2hNYXA8Q29kZVNvdXJjZSwgUHJvdGVjdGlvbkRvbWFpbj4gcGRzID0gbmV3IEhhc2hNYXA8Q29kZVNvdXJjZSwgUHJvdGVjdGlvbkRvbWFpbj4oKTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFNlY3VyZUNsYXNzTG9hZGVyfS4gVGhlIGRlZmF1bHQKKyAgICAgKiBwYXJlbnQge0Bjb2RlIENsYXNzTG9hZGVyfSBpcyB1c2VkLgorICAgICAqLworICAgIHByb3RlY3RlZCBTZWN1cmVDbGFzc0xvYWRlcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBTZWN1cmVDbGFzc0xvYWRlcn0gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogcGFyZW50IHtAY29kZSBDbGFzc0xvYWRlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyZW50CisgICAgICogICAgICAgICAgICB0aGUgcGFyZW50IHtAY29kZSBDbGFzc0xvYWRlcn0uCisgICAgICovCisgICAgcHJvdGVjdGVkIFNlY3VyZUNsYXNzTG9hZGVyKENsYXNzTG9hZGVyIHBhcmVudCkgeworICAgICAgICBzdXBlcihwYXJlbnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBQZXJtaXNzaW9uQ29sbGVjdGlvbn0gZm9yIHRoZSBzcGVjaWZpZWQge0Bjb2RlCisgICAgICogQ29kZVNvdXJjZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29kZXNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIGNvZGUgc291cmNlLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBQZXJtaXNzaW9uQ29sbGVjdGlvbn0gZm9yIHRoZSBzcGVjaWZpZWQge0Bjb2RlCisgICAgICogICAgICAgICBDb2RlU291cmNlfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUGVybWlzc2lvbkNvbGxlY3Rpb24gZ2V0UGVybWlzc2lvbnMoQ29kZVNvdXJjZSBjb2Rlc291cmNlKSB7CisgICAgICAgIC8vIERvIG5vdGhpbmcgYnkgZGVmYXVsdCwgUHJvdGVjdGlvbkRvbWFpbiB3aWxsIHRha2UgY2FyZSBhYm91dAorICAgICAgICAvLyBwZXJtaXNzaW9ucyBpbiBkeW5hbWljCisgICAgICAgIHJldHVybiBuZXcgUGVybWlzc2lvbnMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGNsYXNzIGZyb20gYW4gYXJyYXkgb2YgYnl0ZXMgY29udGFpbmluZyBhIGNsYXNzCisgICAgICogZGVmaW5pdGlvbiBpbiBjbGFzcyBmaWxlIGZvcm1hdCB3aXRoIGFuIG9wdGlvbmFsIHtAY29kZSBDb2RlU291cmNlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgbmV3IGNsYXNzLgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICBhIG1lbW9yeSBpbWFnZSBvZiBhIGNsYXNzIGZpbGUuCisgICAgICogQHBhcmFtIG9mZgorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IG9mZnNldCBpbiBiIG9mIHRoZSBjbGFzcyBkYXRhLgorICAgICAqIEBwYXJhbSBsZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhlIGNsYXNzIGRhdGEuCisgICAgICogQHBhcmFtIGNzCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIENvZGVTb3VyY2V9LCBvciB7QGNvZGUgbnVsbH0uCisgICAgICogQHJldHVybiBhIG5ldyBjbGFzcy4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb2ZmfSBvciB7QGNvZGUgbGVufSBhcmUgbm90IHZhbGlkIGluIHJlc3BlY3QgdG8KKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgYn0uCisgICAgICogQHRocm93cyBDbGFzc0Zvcm1hdEVycm9yCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBkYXRhIGlzIG5vdCB2YWxpZCBjbGFzcyBkYXRhLgorICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFja2FnZSB0byB3aGljaCB0aGlzIGNsYXNzIGlzIHRvIGJlIGFkZGVkLCBhbHJlYWR5CisgICAgICogICAgICAgICAgICAgY29udGFpbnMgY2xhc3NlcyB3aGljaCB3ZXJlIHNpZ25lZCBieSBkaWZmZXJlbnQgY2VydGlmaWNhdGVzLAorICAgICAqICAgICAgICAgICAgIG9yIGlmIHRoZSBjbGFzcyBuYW1lIGJlZ2lucyB3aXRoICJqYXZhLiIKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgQ2xhc3M8Pz4gZGVmaW5lQ2xhc3MoU3RyaW5nIG5hbWUsIGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuLAorICAgICAgICAgICAgQ29kZVNvdXJjZSBjcykgeworICAgICAgICByZXR1cm4gY3MgPT0gbnVsbCA/IGRlZmluZUNsYXNzKG5hbWUsIGIsIG9mZiwgbGVuKSA6IGRlZmluZUNsYXNzKG5hbWUsCisgICAgICAgICAgICAgICAgYiwgb2ZmLCBsZW4sIGdldFBEKGNzKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBjbGFzcyBmcm9tIGFuIGFycmF5IG9mIGJ5dGVzIGNvbnRhaW5pbmcgYSBjbGFzcworICAgICAqIGRlZmluaXRpb24gaW4gY2xhc3MgZmlsZSBmb3JtYXQgd2l0aCBhbiBvcHRpb25hbCB7QGNvZGUgQ29kZVNvdXJjZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIG5ldyBjbGFzcy4KKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgYSBtZW1vcnkgaW1hZ2Ugb2YgYSBjbGFzcyBmaWxlLgorICAgICAqIEBwYXJhbSBjcworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDb2RlU291cmNlfSwgb3Ige0Bjb2RlIG51bGx9LgorICAgICAqIEByZXR1cm4gYSBuZXcgY2xhc3MuCisgICAgICogQHRocm93cyBDbGFzc0Zvcm1hdEVycm9yCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBkYXRhIGlzIG5vdCB2YWxpZCBjbGFzcyBkYXRhLgorICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFja2FnZSB0byB3aGljaCB0aGlzIGNsYXNzIGlzIHRvIGJlIGFkZGVkLCBhbHJlYWR5CisgICAgICogICAgICAgICAgICAgY29udGFpbnMgY2xhc3NlcyB3aGljaCB3ZXJlIHNpZ25lZCBieSBkaWZmZXJlbnQgY2VydGlmaWNhdGVzLAorICAgICAqICAgICAgICAgICAgIG9yIGlmIHRoZSBjbGFzcyBuYW1lIGJlZ2lucyB3aXRoICJqYXZhLiIKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgQ2xhc3M8Pz4gZGVmaW5lQ2xhc3MoU3RyaW5nIG5hbWUsIEJ5dGVCdWZmZXIgYiwgQ29kZVNvdXJjZSBjcykgeworICAgICAgICAvL0ZJWE1FIDEuNSAtIHJlbW92ZSBiLmFycmF5KCksIGNhbGwgc3VwZXIuZGVmaW5lQ2xhc3MoLEJ5dGVCdWZmZXIsKQorICAgICAgICAvLyBkaXJlY3RseQorICAgICAgICBieXRlW10gZGF0YSA9IGIuYXJyYXkoKTsKKyAgICAgICAgcmV0dXJuIGNzID09IG51bGwgPyBkZWZpbmVDbGFzcyhuYW1lLCBkYXRhLCAwLCBkYXRhLmxlbmd0aCkKKyAgICAgICAgICAgICAgICA6IGRlZmluZUNsYXNzKG5hbWUsIGRhdGEsIDAsIGRhdGEubGVuZ3RoLCBnZXRQRChjcykpOworICAgIH0KKworICAgIC8vIENvbnN0cnVjdHMgYW5kIGNhY2hlcyBQcm90ZWN0aW9uRG9tYWluIGZvciB0aGUgZ2l2ZW4gQ29kZVNvdXJjZQorICAgIC8vIG9iamVjdC48YnI+CisgICAgLy8gSXQgY2FsbHMge0BsaW5rIGdldFBlcm1pc3Npb25zKCl9IHRvIGdldCBhIHNldCBvZiBwZXJtaXNzaW9ucy4KKyAgICAvLworICAgIC8vIEBwYXJhbSBjcyBDb2RlU291cmNlIG9iamVjdAorICAgIC8vIEByZXR1cm4gUHJvdGVjdGlvbkRvbWFpbiBmb3IgdGhlIHBhc3NlZCBDb2RlU291cmNlIG9iamVjdAorICAgIHByaXZhdGUgUHJvdGVjdGlvbkRvbWFpbiBnZXRQRChDb2RlU291cmNlIGNzKSB7CisgICAgICAgIGlmIChjcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICAvLyBuZWVkIHRvIGNhY2hlIFBEcywgb3RoZXJ3aXNlIGV2ZXJ5IGNsYXNzIGZyb20gYSBnaXZlbiBDb2RlU291cmNlCisgICAgICAgIC8vIHdpbGwgaGF2ZSBpdCdzIG93biBQcm90ZWN0aW9uRG9tYWluLCB3aGljaCBkb2VzIG5vdCBsb29rIHJpZ2h0LgorICAgICAgICBQcm90ZWN0aW9uRG9tYWluIHBkOworICAgICAgICBzeW5jaHJvbml6ZWQgKHBkcykgeworICAgICAgICAgICAgaWYgKChwZCA9IHBkcy5nZXQoY3MpKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHBkOworICAgICAgICAgICAgfQorICAgICAgICAgICAgUGVybWlzc2lvbkNvbGxlY3Rpb24gcGVybXMgPSBnZXRQZXJtaXNzaW9ucyhjcyk7CisgICAgICAgICAgICBwZCA9IG5ldyBQcm90ZWN0aW9uRG9tYWluKGNzLCBwZXJtcywgdGhpcywgbnVsbCk7CisgICAgICAgICAgICBwZHMucHV0KGNzLCBwZCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHBkOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1NlY3VyZVJhbmRvbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2VjdXJlUmFuZG9tLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjhhMjkxNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1NlY3VyZVJhbmRvbS5qYXZhCkBAIC0wLDAgKzEsMzM1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLm5pby5CeXRlT3JkZXI7CitpbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKK2ltcG9ydCBsaWJjb3JlLmlvLk1lbW9yeTsKK2ltcG9ydCBsaWJjb3JlLmlvLlNpemVPZjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuZm9ydHJlc3MuRW5naW5lOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5mb3J0cmVzcy5TZXJ2aWNlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkucHJvdmlkZXIuY3J5cHRvLlNIQTFQUk5HX1NlY3VyZVJhbmRvbUltcGw7CisKKy8qKgorICogVGhpcyBjbGFzcyBnZW5lcmF0ZXMgY3J5cHRvZ3JhcGhpY2FsbHkgc2VjdXJlIHBzZXVkby1yYW5kb20gbnVtYmVycy4KKyAqCisgKiA8aDM+U3VwcG9ydGVkIEFsZ29yaXRobXM8L2gzPgorICogPHVsPgorICogICA8bGk+PHN0cm9uZz5TSEExUFJORzwvc3Ryb25nPjogQmFzZWQgb24gPGEKKyAqICAgICBocmVmPSJodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1NIQS0xIj5TSEEtMTwvYT4uIE5vdCBndWFyYW50ZWVkIHRvIGJlCisgKiAgICAgY29tcGF0aWJsZSB3aXRoIHRoZSBTSEExUFJORyBhbGdvcml0aG0gb24gdGhlIHJlZmVyZW5jZQorICogICAgIGltcGxlbWVudGF0aW9uLjwvbGk+CisgKiA8L3VsPgorICoKKyAqIDxwPlRoZSBkZWZhdWx0IGFsZ29yaXRobSBpcyBkZWZpbmVkIGJ5IHRoZSBmaXJzdCB7QGNvZGUgU2VjdXJlUmFuZG9tU3BpfQorICogcHJvdmlkZXIgZm91bmQgaW4gdGhlIFZNJ3MgaW5zdGFsbGVkIHNlY3VyaXR5IHByb3ZpZGVycy4gVXNlIHtAbGluaworICogU2VjdXJpdHl9IHRvIGluc3RhbGwgY3VzdG9tIHtAbGluayBTZWN1cmVSYW5kb21TcGl9IHByb3ZpZGVycy4KKyAqCisgKiA8YSBuYW1lPSJpbnNlY3VyZV9zZWVkIj48aDM+U2VlZGluZyB7QGNvZGUgU2VjdXJlUmFuZG9tfSBtYXkgYmUKKyAqIGluc2VjdXJlPC9oMz48L2E+CisgKiBBIHNlZWQgaXMgYW4gYXJyYXkgb2YgYnl0ZXMgdXNlZCB0byBib290c3RyYXAgcmFuZG9tIG51bWJlciBnZW5lcmF0aW9uLgorICogVG8gcHJvZHVjZSBjcnlwdG9ncmFwaGljYWxseSBzZWN1cmUgcmFuZG9tIG51bWJlcnMsIGJvdGggdGhlIHNlZWQgYW5kIHRoZQorICogYWxnb3JpdGhtIG11c3QgYmUgc2VjdXJlLgorICoKKyAqIDxwPkJ5IGRlZmF1bHQsIGluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIHdpbGwgZ2VuZXJhdGUgYW4gaW5pdGlhbCBzZWVkIHVzaW5nCisgKiBhbiBpbnRlcm5hbCBlbnRyb3B5IHNvdXJjZSwgc3VjaCBhcyB7QGNvZGUgL2Rldi91cmFuZG9tfS4gVGhpcyBzZWVkIGlzCisgKiB1bnByZWRpY3RhYmxlIGFuZCBhcHByb3ByaWF0ZSBmb3Igc2VjdXJlIHVzZS4KKyAqCisgKiA8cD5Zb3UgbWF5IGFsdGVybmF0aXZlbHkgc3BlY2lmeSB0aGUgaW5pdGlhbCBzZWVkIGV4cGxpY2l0bHkgd2l0aCB0aGUKKyAqIHtAbGluayAjU2VjdXJlUmFuZG9tKGJ5dGVbXSkgc2VlZGVkIGNvbnN0cnVjdG9yfSBvciBieSBjYWxsaW5nIHtAbGluaworICogI3NldFNlZWR9IGJlZm9yZSBhbnkgcmFuZG9tIG51bWJlcnMgaGF2ZSBiZWVuIGdlbmVyYXRlZC4gU3BlY2lmeWluZyBhIGZpeGVkCisgKiBzZWVkIHdpbGwgY2F1c2UgdGhlIGluc3RhbmNlIHRvIHJldHVybiBhIHByZWRpY3RhYmxlIHNlcXVlbmNlIG9mIG51bWJlcnMuCisgKiBUaGlzIG1heSBiZSB1c2VmdWwgZm9yIHRlc3RpbmcgYnV0IGl0IGlzIG5vdCBhcHByb3ByaWF0ZSBmb3Igc2VjdXJlIHVzZS4KKyAqCisgKiA8cD5JdCBpcyBkYW5nZXJvdXMgdG8gc2VlZCB7QGNvZGUgU2VjdXJlUmFuZG9tfSB3aXRoIHRoZSBjdXJyZW50IHRpbWUgYmVjYXVzZQorICogdGhhdCB2YWx1ZSBpcyBtb3JlIHByZWRpY3RhYmxlIHRvIGFuIGF0dGFja2VyIHRoYW4gdGhlIGRlZmF1bHQgc2VlZC4KKyAqCisgKiA8cD5DYWxsaW5nIHtAbGluayAjc2V0U2VlZH0gb24gYSB7QGNvZGUgU2VjdXJlUmFuZG9tfSA8aT5hZnRlcjwvaT4gaXQgaGFzCisgKiBiZWVuIHVzZWQgdG8gZ2VuZXJhdGUgcmFuZG9tIG51bWJlcnMgKGllLiBjYWxsaW5nIHtAbGluayAjbmV4dEJ5dGVzfSkgd2lsbAorICogc3VwcGxlbWVudCB0aGUgZXhpc3Rpbmcgc2VlZC4gVGhpcyBkb2VzIG5vdCBjYXVzZSB0aGUgaW5zdGFuY2UgdG8gcmV0dXJuIGEKKyAqIHByZWRpY3RhYmxlIG51bWJlcnMsIG5vciBkb2VzIGl0IGhhcm0gdGhlIHNlY3VyaXR5IG9mIHRoZSBudW1iZXJzIGdlbmVyYXRlZC4KKyAqLworcHVibGljIGNsYXNzIFNlY3VyZVJhbmRvbSBleHRlbmRzIFJhbmRvbSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0OTQwNjcwMDA1NTYyMTg3TDsKKworICAgIC8vIFRoZSBzZXJ2aWNlIG5hbWUuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNFUlZJQ0UgPSAiU2VjdXJlUmFuZG9tIjsKKworICAgIC8vIFVzZWQgdG8gYWNjZXNzIGNvbW1vbiBlbmdpbmUgZnVuY3Rpb25hbGl0eQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEVuZ2luZSBFTkdJTkUgPSBuZXcgRW5naW5lKFNFUlZJQ0UpOworCisgICAgcHJpdmF0ZSBmaW5hbCBQcm92aWRlciBwcm92aWRlcjsKKworICAgIHByaXZhdGUgZmluYWwgU2VjdXJlUmFuZG9tU3BpIHNlY3VyZVJhbmRvbVNwaTsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGFsZ29yaXRobTsKKworICAgIC8vIEludGVybmFsIFNlY3VyZVJhbmRvbSB1c2VkIGZvciBnZXRTZWVkKGludCkKKyAgICBwcml2YXRlIHN0YXRpYyB2b2xhdGlsZSBTZWN1cmVSYW5kb20gaW50ZXJuYWxTZWN1cmVSYW5kb207CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBTZWN1cmVSYW5kb219IHRoYXQgdXNlcyB0aGUgZGVmYXVsdCBhbGdvcml0aG0uCisgICAgICovCisgICAgcHVibGljIFNlY3VyZVJhbmRvbSgpIHsKKyAgICAgICAgc3VwZXIoMCk7CisgICAgICAgIFNlcnZpY2VzLnJlZnJlc2goKTsKKyAgICAgICAgUHJvdmlkZXIuU2VydmljZSBzZXJ2aWNlID0gU2VydmljZXMuZ2V0U2VjdXJlUmFuZG9tU2VydmljZSgpOworICAgICAgICBpZiAoc2VydmljZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aGlzLnByb3ZpZGVyID0gbnVsbDsKKyAgICAgICAgICAgIHRoaXMuc2VjdXJlUmFuZG9tU3BpID0gbmV3IFNIQTFQUk5HX1NlY3VyZVJhbmRvbUltcGwoKTsKKyAgICAgICAgICAgIHRoaXMuYWxnb3JpdGhtID0gIlNIQTFQUk5HIjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdGhpcy5wcm92aWRlciA9IHNlcnZpY2UuZ2V0UHJvdmlkZXIoKTsKKyAgICAgICAgICAgICAgICB0aGlzLnNlY3VyZVJhbmRvbVNwaSA9IChTZWN1cmVSYW5kb21TcGkpc2VydmljZS5uZXdJbnN0YW5jZShudWxsKTsKKyAgICAgICAgICAgICAgICB0aGlzLmFsZ29yaXRobSA9IHNlcnZpY2UuZ2V0QWxnb3JpdGhtKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBzZWVkZWQge0Bjb2RlIFNlY3VyZVJhbmRvbX0gdGhhdCB1c2VzIHRoZSBkZWZhdWx0CisgICAgICogYWxnb3JpdGhtLiA8YSBocmVmPSIjaW5zZWN1cmVfc2VlZCI+U2VlZGluZyB7QGNvZGUgU2VjdXJlUmFuZG9tfSBtYXkgYmUKKyAgICAgKiBpbnNlY3VyZTwvYT4uCisgICAgICovCisgICAgcHVibGljIFNlY3VyZVJhbmRvbShieXRlW10gc2VlZCkgeworICAgICAgICB0aGlzKCk7CisgICAgICAgIHNldFNlZWQoc2VlZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgU2VjdXJlUmFuZG9tfSB1c2luZyB0aGUgZ2l2ZW4KKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBmcm9tIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2VjdXJlUmFuZG9tU3BpCisgICAgICogICAgICAgICAgICB0aGUgaW1wbGVtZW50YXRpb24uCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgc2VjdXJpdHkgcHJvdmlkZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNlY3VyZVJhbmRvbShTZWN1cmVSYW5kb21TcGkgc2VjdXJlUmFuZG9tU3BpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIpIHsKKyAgICAgICAgdGhpcyhzZWN1cmVSYW5kb21TcGksIHByb3ZpZGVyLCAidW5rbm93biIpOworICAgIH0KKworICAgIC8vIENvbnN0cnVjdG9yCisgICAgcHJpdmF0ZSBTZWN1cmVSYW5kb20oU2VjdXJlUmFuZG9tU3BpIHNlY3VyZVJhbmRvbVNwaSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBQcm92aWRlciBwcm92aWRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYWxnb3JpdGhtKSB7CisgICAgICAgIHN1cGVyKDApOworICAgICAgICB0aGlzLnByb3ZpZGVyID0gcHJvdmlkZXI7CisgICAgICAgIHRoaXMuYWxnb3JpdGhtID0gYWxnb3JpdGhtOworICAgICAgICB0aGlzLnNlY3VyZVJhbmRvbVNwaSA9IHNlY3VyZVJhbmRvbVNwaTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBTZWN1cmVSYW5kb219IHRoYXQgdXRpbGl6ZXMgdGhlCisgICAgICogc3BlY2lmaWVkIGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0gdG8gdXNlLgorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFNlY3VyZVJhbmRvbX0gdGhhdCB1dGlsaXplcyB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobSBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYWxnb3JpdGhtfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTZWN1cmVSYW5kb20gZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhbGdvcml0aG0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgRW5naW5lLlNwaUFuZFByb3ZpZGVyIHNhcCA9IEVOR0lORS5nZXRJbnN0YW5jZShhbGdvcml0aG0sIG51bGwpOworICAgICAgICByZXR1cm4gbmV3IFNlY3VyZVJhbmRvbSgoU2VjdXJlUmFuZG9tU3BpKSBzYXAuc3BpLCBzYXAucHJvdmlkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsZ29yaXRobSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgU2VjdXJlUmFuZG9tfSB0aGF0IHV0aWxpemVzIHRoZQorICAgICAqIHNwZWNpZmllZCBhbGdvcml0aG0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobSB0byB1c2UuCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcHJvdmlkZXIuCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgU2VjdXJlUmFuZG9tfSB0aGF0IHV0aWxpemVzIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIGFsZ29yaXRobSBmcm9tIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIuCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobSBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhbGdvcml0aG19IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgcHJvdmlkZXIgPT0gbnVsbCB8fCBwcm92aWRlci5pc0VtcHR5KCl9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTZWN1cmVSYW5kb20gZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwcm92aWRlciA9PSBudWxsIHx8IHByb3ZpZGVyLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIFByb3ZpZGVyIHAgPSBTZWN1cml0eS5nZXRQcm92aWRlcihwcm92aWRlcik7CisgICAgICAgIGlmIChwID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbihwcm92aWRlcik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEluc3RhbmNlKGFsZ29yaXRobSwgcCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgU2VjdXJlUmFuZG9tfSB0aGF0IHV0aWxpemVzIHRoZQorICAgICAqIHNwZWNpZmllZCBhbGdvcml0aG0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobSB0byB1c2UuCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgc2VjdXJpdHkgcHJvdmlkZXIuCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgU2VjdXJlUmFuZG9tfSB0aGF0IHV0aWxpemVzIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIGFsZ29yaXRobSBmcm9tIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIuCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobSBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYWxnb3JpdGhtfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHByb3ZpZGVyID09IG51bGx9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTZWN1cmVSYW5kb20gZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgUHJvdmlkZXIgcHJvdmlkZXIpCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIE9iamVjdCBzcGkgPSBFTkdJTkUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBwcm92aWRlciwgbnVsbCk7CisgICAgICAgIHJldHVybiBuZXcgU2VjdXJlUmFuZG9tKChTZWN1cmVSYW5kb21TcGkpIHNwaSwgcHJvdmlkZXIsIGFsZ29yaXRobSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJvdmlkZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMge0Bjb2RlIFNlY3VyZVJhbmRvbX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcm92aWRlciBhc3NvY2lhdGVkIHdpdGggdGhpcyB7QGNvZGUgU2VjdXJlUmFuZG9tfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgUHJvdmlkZXIgZ2V0UHJvdmlkZXIoKSB7CisgICAgICAgIHJldHVybiBwcm92aWRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0gb2YgdGhpcyB7QGNvZGUgU2VjdXJlUmFuZG9tfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobSBvZiB0aGlzIHtAY29kZSBTZWN1cmVSYW5kb219LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICByZXR1cm4gYWxnb3JpdGhtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlZWRzIHRoaXMge0Bjb2RlIFNlY3VyZVJhbmRvbX0gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHtAY29kZQorICAgICAqIHNlZWR9LiA8YSBocmVmPSIjaW5zZWN1cmVfc2VlZCI+U2VlZGluZyB7QGNvZGUgU2VjdXJlUmFuZG9tfSBtYXkgYmUKKyAgICAgKiBpbnNlY3VyZTwvYT4uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFNlZWQoYnl0ZVtdIHNlZWQpIHsKKyAgICAgICAgc2VjdXJlUmFuZG9tU3BpLmVuZ2luZVNldFNlZWQoc2VlZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VlZHMgdGhpcyB7QGNvZGUgU2VjdXJlUmFuZG9tfSBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgZWlnaHQtYnl0ZQorICAgICAqIHtAY29kZSBzZWVkfS4gPGEgaHJlZj0iI2luc2VjdXJlX3NlZWQiPlNlZWRpbmcge0Bjb2RlIFNlY3VyZVJhbmRvbX0gbWF5CisgICAgICogYmUgaW5zZWN1cmU8L2E+LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFNlZWQobG9uZyBzZWVkKSB7CisgICAgICAgIGlmIChzZWVkID09IDApIHsgICAgLy8gc2tpcCBjYWxsIGZyb20gUmFuZG9tCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIGJ5dGVTZWVkID0gbmV3IGJ5dGVbU2l6ZU9mLkxPTkddOworICAgICAgICBNZW1vcnkucG9rZUxvbmcoYnl0ZVNlZWQsIDAsIHNlZWQsIEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICAgICAgc2V0U2VlZChieXRlU2VlZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGFuZCBzdG9yZXMgcmFuZG9tIGJ5dGVzIGluIHRoZSBnaXZlbiB7QGNvZGUgYnl0ZVtdfSBmb3IgZWFjaAorICAgICAqIGFycmF5IGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnl0ZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgYnl0ZVtdfSB0byBiZSBmaWxsZWQgd2l0aCByYW5kb20gYnl0ZXMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIG5leHRCeXRlcyhieXRlW10gYnl0ZXMpIHsKKyAgICAgICAgc2VjdXJlUmFuZG9tU3BpLmVuZ2luZU5leHRCeXRlcyhieXRlcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGFuZCByZXR1cm5zIGFuIHtAY29kZSBpbnR9IGNvbnRhaW5pbmcgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YKKyAgICAgKiByYW5kb20gYml0cyAocmlnaHQganVzdGlmaWVkLCB3aXRoIGxlYWRpbmcgemVyb3MpLgorICAgICAqCisgICAgICogQHBhcmFtIG51bUJpdHMKKyAgICAgKiAgICAgICAgICAgIG51bWJlciBvZiBiaXRzIHRvIGJlIGdlbmVyYXRlZC4gQW4gaW5wdXQgdmFsdWUgc2hvdWxkIGJlIGluCisgICAgICogICAgICAgICAgICB0aGUgcmFuZ2UgWzAsIDMyXS4KKyAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBpbnR9IGNvbnRhaW5pbmcgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgcmFuZG9tIGJpdHMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGZpbmFsIGludCBuZXh0KGludCBudW1CaXRzKSB7CisgICAgICAgIGlmIChudW1CaXRzIDwgMCkgeworICAgICAgICAgICAgbnVtQml0cyA9IDA7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAobnVtQml0cyA+IDMyKSB7CisgICAgICAgICAgICAgICAgbnVtQml0cyA9IDMyOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGludCBieXRlcyA9IChudW1CaXRzKzcpLzg7CisgICAgICAgIGJ5dGVbXSBuZXh0ID0gbmV3IGJ5dGVbYnl0ZXNdOworICAgICAgICBpbnQgcmV0ID0gMDsKKworICAgICAgICBuZXh0Qnl0ZXMobmV4dCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYnl0ZXM7IGkrKykgeworICAgICAgICAgICAgcmV0ID0gKG5leHRbaV0gJiAweEZGKSB8IChyZXQgPDwgOCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0ID0gcmV0ID4+PiAoYnl0ZXMqOCAtIG51bUJpdHMpOworICAgICAgICByZXR1cm4gcmV0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdlbmVyYXRlcyBhbmQgcmV0dXJucyB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBzZWVkIGJ5dGVzLCBjb21wdXRlZCB1c2luZworICAgICAqIHRoZSBzZWVkIGdlbmVyYXRpb24gYWxnb3JpdGhtIHVzZWQgYnkgdGhpcyB7QGNvZGUgU2VjdXJlUmFuZG9tfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBudW1CeXRlcworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBzZWVkIGJ5dGVzLgorICAgICAqIEByZXR1cm4gdGhlIHNlZWQgYnl0ZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBnZXRTZWVkKGludCBudW1CeXRlcykgeworICAgICAgICBTZWN1cmVSYW5kb20gcmVzdWx0ID0gaW50ZXJuYWxTZWN1cmVSYW5kb207CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gc2luZ2xlLWNoZWNrIGlkaW9tCisgICAgICAgICAgICBpbnRlcm5hbFNlY3VyZVJhbmRvbSA9IHJlc3VsdCA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0LmdlbmVyYXRlU2VlZChudW1CeXRlcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGFuZCByZXR1cm5zIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIHNlZWQgYnl0ZXMsIGNvbXB1dGVkIHVzaW5nCisgICAgICogdGhlIHNlZWQgZ2VuZXJhdGlvbiBhbGdvcml0aG0gdXNlZCBieSB0aGlzIHtAY29kZSBTZWN1cmVSYW5kb219LgorICAgICAqCisgICAgICogQHBhcmFtIG51bUJ5dGVzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIHNlZWQgYnl0ZXMuCisgICAgICogQHJldHVybiB0aGUgc2VlZCBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdlbmVyYXRlU2VlZChpbnQgbnVtQnl0ZXMpIHsKKyAgICAgICAgcmV0dXJuIHNlY3VyZVJhbmRvbVNwaS5lbmdpbmVHZW5lcmF0ZVNlZWQobnVtQnl0ZXMpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2VjdXJlUmFuZG9tU3BpLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9TZWN1cmVSYW5kb21TcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YjA3OWMxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2VjdXJlUmFuZG9tU3BpLmphdmEKQEAgLTAsMCArMSw2MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKKy8qKgorICoge0Bjb2RlIFNlY3VyZVJhbmRvbVNwaX0gaXMgdGhlIDxpPlNlcnZpY2UgUHJvdmlkZXIgSW50ZXJmYWNlPC9pPiAoPGI+U1BJPC9iPikgZGVmaW5pdGlvbgorICogZm9yIHtAbGluayBTZWN1cmVSYW5kb219LgorICoKKyAqIEBzZWUgU2VjdXJlUmFuZG9tCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTZWN1cmVSYW5kb21TcGkgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTI5OTE4NTQxNjEwMDkxOTE4MzBMOworCisgICAgLyoqCisgICAgICogUmVzZWVkcyB0aGlzIHtAY29kZSBTZWN1cmVSYW5kb21TcGl9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCB7QGNvZGUKKyAgICAgKiBzZWVkfS4gVGhlIHNlZWQgb2YgdGhpcyB7QGNvZGUgU2VjdXJlUmFuZG9tU3BpfSBpbnN0YW5jZSBpcyBzdXBwbGVtZW50ZWQsCisgICAgICogbm90IHJlcGxhY2VkLgorICAgICAqCisgICAgICogQHBhcmFtIHNlZWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgc2VlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBlbmdpbmVTZXRTZWVkKGJ5dGVbXSBzZWVkKTsKKworICAgIC8qKgorICAgICAqIEdlbmVyYXRlcyBhbmQgc3RvcmVzIHJhbmRvbSBieXRlcyBpbiB0aGUgZ2l2ZW4ge0Bjb2RlIGJ5dGVbXX0gZm9yIGVhY2gKKyAgICAgKiBhcnJheSBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGJ5dGVzCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGJ5dGVbXX0gdG8gYmUgZmlsbGVkIHdpdGggcmFuZG9tIGJ5dGVzLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGVuZ2luZU5leHRCeXRlcyhieXRlW10gYnl0ZXMpOworCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGFuZCByZXR1cm5zIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIHNlZWQgYnl0ZXMsIGNvbXB1dGVkIHVzaW5nCisgICAgICogdGhlIHNlZWQgZ2VuZXJhdGlvbiBhbGdvcml0aG0gdXNlZCBieSB0aGlzIHtAY29kZSBTZWN1cmVSYW5kb21TcGl9LgorICAgICAqCisgICAgICogQHBhcmFtIG51bUJ5dGVzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIHNlZWQgYnl0ZXMuCisgICAgICogQHJldHVybiB0aGUgc2VlZCBieXRlcworICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBieXRlW10gZW5naW5lR2VuZXJhdGVTZWVkKGludCBudW1CeXRlcyk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9TZWN1cml0eS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2VjdXJpdHkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNGNjNmUxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2VjdXJpdHkuamF2YQpAQCAtMCwwICsxLDQxMSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcC5FbnRyeTsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5mb3J0cmVzcy5FbmdpbmU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmZvcnRyZXNzLlNlY3VyaXR5QWNjZXNzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5mb3J0cmVzcy5TZXJ2aWNlczsKKworLyoqCisgKiB7QGNvZGUgU2VjdXJpdHl9IGlzIHRoZSBjZW50cmFsIGNsYXNzIGluIHRoZSBKYXZhIFNlY3VyaXR5IEFQSS4gSXQgbWFuYWdlcworICogdGhlIGxpc3Qgb2Ygc2VjdXJpdHkge0Bjb2RlIFByb3ZpZGVyfSB0aGF0IGhhdmUgYmVlbiBpbnN0YWxsZWQgaW50byB0aGlzCisgKiBydW50aW1lIGVudmlyb25tZW50LgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU2VjdXJpdHkgeworCisgICAgLy8gU2VjdXJpdHkgcHJvcGVydGllcworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFByb3BlcnRpZXMgc2VjcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCisgICAgLy8gc3RhdGljIGluaXRpYWxpemF0aW9uCisgICAgLy8gLSBsb2FkIHNlY3VyaXR5IHByb3BlcnRpZXMgZmlsZXMKKyAgICAvLyAtIGxvYWQgc3RhdGljYWxseSByZWdpc3RlcmVkIHByb3ZpZGVycworICAgIC8vIC0gaWYgbm8gcHJvdmlkZXIgZGVzY3JpcHRpb24gZmlsZSBmb3VuZCB0aGVuIGxvYWQgZGVmYXVsdCBwcm92aWRlcnMKKyAgICBzdGF0aWMgeworICAgICAgICBib29sZWFuIGxvYWRlZCA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW5wdXRTdHJlYW0gY29uZmlnU3RyZWFtID0gU2VjdXJpdHkuY2xhc3MuZ2V0UmVzb3VyY2VBc1N0cmVhbSgic2VjdXJpdHkucHJvcGVydGllcyIpOworICAgICAgICAgICAgSW5wdXRTdHJlYW0gaW5wdXQgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShjb25maWdTdHJlYW0pOworICAgICAgICAgICAgc2VjcHJvcHMubG9hZChpbnB1dCk7CisgICAgICAgICAgICBsb2FkZWQgPSB0cnVlOworICAgICAgICAgICAgY29uZmlnU3RyZWFtLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgU3lzdGVtLmxvZ0UoIkNvdWxkIG5vdCBsb2FkICdzZWN1cml0eS5wcm9wZXJ0aWVzJyIsIGV4KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIWxvYWRlZCkgeworICAgICAgICAgICAgcmVnaXN0ZXJEZWZhdWx0UHJvdmlkZXJzKCk7CisgICAgICAgIH0KKyAgICAgICAgRW5naW5lLmRvb3IgPSBuZXcgU2VjdXJpdHlEb29yKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBjbGFzcyBjYW4ndCBiZSBpbnN0YW50aWF0ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBTZWN1cml0eSgpIHsKKyAgICB9CisKKyAgICAvLyBSZWdpc3RlciBkZWZhdWx0IHByb3ZpZGVycworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcmVnaXN0ZXJEZWZhdWx0UHJvdmlkZXJzKCkgeworICAgICAgICBzZWNwcm9wcy5wdXQoInNlY3VyaXR5LnByb3ZpZGVyLjEiLCAib3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZS5PcGVuU1NMUHJvdmlkZXIiKTsKKyAgICAgICAgc2VjcHJvcHMucHV0KCJzZWN1cml0eS5wcm92aWRlci4yIiwgIm9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wcm92aWRlci5jZXJ0LkRSTENlcnRGYWN0b3J5Iik7CisgICAgICAgIHNlY3Byb3BzLnB1dCgic2VjdXJpdHkucHJvdmlkZXIuMyIsICJvcmcuYm91bmN5Y2FzdGxlLmpjZS5wcm92aWRlci5Cb3VuY3lDYXN0bGVQcm92aWRlciIpOworICAgICAgICBzZWNwcm9wcy5wdXQoInNlY3VyaXR5LnByb3ZpZGVyLjQiLCAib3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnByb3ZpZGVyLmNyeXB0by5DcnlwdG9Qcm92aWRlciIpOworICAgICAgICBzZWNwcm9wcy5wdXQoInNlY3VyaXR5LnByb3ZpZGVyLjUiLCAib3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZS5KU1NFUHJvdmlkZXIiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtLgorICAgICAqIEBwYXJhbSBwcm9wTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5LgorICAgICAqIEByZXR1cm4gdmFsdWUgb2YgdGhlIHByb3BlcnR5LgorICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgQWxnb3JpdGhtUGFyYW1ldGVyc30gYW5kIHtAbGluayBLZXlGYWN0b3J5fQorICAgICAqICAgICAgICAgICAgIGluc3RlYWQuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRBbGdvcml0aG1Qcm9wZXJ0eShTdHJpbmcgYWxnTmFtZSwgU3RyaW5nIHByb3BOYW1lKSB7CisgICAgICAgIGlmIChhbGdOYW1lID09IG51bGwgfHwgcHJvcE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHByb3AgPSAiQWxnLiIgKyBwcm9wTmFtZSArICIuIiArIGFsZ05hbWU7CisgICAgICAgIFByb3ZpZGVyW10gcHJvdmlkZXJzID0gZ2V0UHJvdmlkZXJzKCk7CisgICAgICAgIGZvciAoUHJvdmlkZXIgcHJvdmlkZXIgOiBwcm92aWRlcnMpIHsKKyAgICAgICAgICAgIGZvciAoRW51bWVyYXRpb24gZSA9IHByb3ZpZGVyLnByb3BlcnR5TmFtZXMoKTsgZS5oYXNNb3JlRWxlbWVudHMoKTsgKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHByb3BlcnR5TmFtZSA9IChTdHJpbmcpIGUubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBpZiAocHJvcGVydHlOYW1lLmVxdWFsc0lnbm9yZUNhc2UocHJvcCkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByb3ZpZGVyLmdldFByb3BlcnR5KHByb3BlcnR5TmFtZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydCB0aGUgZ2l2ZW4ge0Bjb2RlIFByb3ZpZGVyfSBhdCB0aGUgc3BlY2lmaWVkIHtAY29kZSBwb3NpdGlvbn0uIFRoZQorICAgICAqIHBvc2l0aW9ucyBkZWZpbmUgdGhlIHByZWZlcmVuY2Ugb3JkZXIgaW4gd2hpY2ggcHJvdmlkZXJzIGFyZSBzZWFyY2hlZCBmb3IKKyAgICAgKiByZXF1ZXN0ZWQgYWxnb3JpdGhtcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHByb3ZpZGVyIHRvIGluc2VydC4KKyAgICAgKiBAcGFyYW0gcG9zaXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3NpdGlvbiAoc3RhcnRpbmcgZnJvbSAxKS4KKyAgICAgKiBAcmV0dXJuIHRoZSBhY3R1YWwgcG9zaXRpb24gb3Ige0Bjb2RlIC0xfSBpZiB0aGUgZ2l2ZW4ge0Bjb2RlIHByb3ZpZGVyfQorICAgICAqICAgICAgICAgd2FzIGFscmVhZHkgaW4gdGhlIGxpc3QuIFRoZSBhY3R1YWwgcG9zaXRpb24gbWF5IGJlIGRpZmZlcmVudAorICAgICAqICAgICAgICAgZnJvbSB0aGUgZGVzaXJlZCBwb3NpdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBpbnQgaW5zZXJ0UHJvdmlkZXJBdChQcm92aWRlciBwcm92aWRlciwgaW50IHBvc2l0aW9uKSB7CisgICAgICAgIC8vIGNoZWNrIHRoYXQgcHJvdmlkZXIgaXMgbm90IGFscmVhZHkKKyAgICAgICAgLy8gaW5zdGFsbGVkLCBlbHNlIHJldHVybiAtMTsgaWYgKHBvc2l0aW9uIDwxKSBvciAocG9zaXRpb24gPiBtYXgKKyAgICAgICAgLy8gcG9zaXRpb24pIHBvc2l0aW9uID0gbWF4IHBvc2l0aW9uICsgMTsgaW5zZXJ0IHByb3ZpZGVyLCBzaGlmdCB1cAorICAgICAgICAvLyBvbmUgcG9zaXRpb24gZm9yIG5leHQgcHJvdmlkZXJzOyBOb3RlOiBUaGUgcG9zaXRpb24gaXMgMS1iYXNlZAorICAgICAgICBpZiAoZ2V0UHJvdmlkZXIocHJvdmlkZXIuZ2V0TmFtZSgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgaW50IHJlc3VsdCA9IFNlcnZpY2VzLmluc2VydFByb3ZpZGVyQXQocHJvdmlkZXIsIHBvc2l0aW9uKTsKKyAgICAgICAgcmVudW1Qcm92aWRlcnMoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBnaXZlbiB7QGNvZGUgcHJvdmlkZXJ9IHRvIHRoZSBjb2xsZWN0aW9uIG9mIHByb3ZpZGVycyBhdCB0aGUKKyAgICAgKiBuZXh0IGF2YWlsYWJsZSBwb3NpdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHByb3ZpZGVyIHRvIGJlIGFkZGVkLgorICAgICAqIEByZXR1cm4gdGhlIGFjdHVhbCBwb3NpdGlvbiBvciB7QGNvZGUgLTF9IGlmIHRoZSBnaXZlbiB7QGNvZGUgcHJvdmlkZXJ9CisgICAgICogICAgICAgICB3YXMgYWxyZWFkeSBpbiB0aGUgbGlzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBhZGRQcm92aWRlcihQcm92aWRlciBwcm92aWRlcikgeworICAgICAgICByZXR1cm4gaW5zZXJ0UHJvdmlkZXJBdChwcm92aWRlciwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUge0Bjb2RlIFByb3ZpZGVyfSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBmb3JtIHRoZSBjb2xsZWN0aW9uCisgICAgICogb2YgcHJvdmlkZXJzLiBJZiB0aGUgdGhlIHtAY29kZSBQcm92aWRlcn0gd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgaXMKKyAgICAgKiByZW1vdmVkLCBhbGwgcHJvdmlkZXIgYXQgYSBncmVhdGVyIHBvc2l0aW9uIGFyZSBzaGlmdGVkIGRvd24gb25lCisgICAgICogcG9zaXRpb24uCisgICAgICoKKyAgICAgKiA8cD5SZXR1cm5zIHNpbGVudGx5IGlmIHtAY29kZSBuYW1lfSBpcyB7QGNvZGUgbnVsbH0gb3Igbm8gcHJvdmlkZXIgd2l0aCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgbmFtZSBpcyBpbnN0YWxsZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIHRvIHJlbW92ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCB2b2lkIHJlbW92ZVByb3ZpZGVyKFN0cmluZyBuYW1lKSB7CisgICAgICAgIC8vIEl0IGlzIG5vdCBjbGVhciBmcm9tIHNwZWMuOgorICAgICAgICAvLyAxLiBpZiBuYW1lIGlzIG51bGwsIHNob3VsZCB3ZSBjaGVja1NlY3VyaXR5QWNjZXNzIG9yIG5vdD8KKyAgICAgICAgLy8gICAgdGhyb3cgU2VjdXJpdHlFeGNlcHRpb24gb3Igbm90PworICAgICAgICAvLyAyLiBhcyAxIGJ1dCBwcm92aWRlciBpcyBub3QgaW5zdGFsbGVkCisgICAgICAgIC8vIDMuIGJlaGF2aW9yIGlmIG5hbWUgaXMgZW1wdHkgc3RyaW5nPworCisgICAgICAgIFByb3ZpZGVyIHA7CisgICAgICAgIGlmICgobmFtZSA9PSBudWxsKSB8fCAobmFtZS5sZW5ndGgoKSA9PSAwKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHAgPSBnZXRQcm92aWRlcihuYW1lKTsKKyAgICAgICAgaWYgKHAgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFNlcnZpY2VzLnJlbW92ZVByb3ZpZGVyKHAuZ2V0UHJvdmlkZXJOdW1iZXIoKSk7CisgICAgICAgIHJlbnVtUHJvdmlkZXJzKCk7CisgICAgICAgIHAuc2V0UHJvdmlkZXJOdW1iZXIoLTEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgaW5zdGFsbGVkIHByb3ZpZGVycy4gVGhlIHByb3ZpZGVycyBhcmUKKyAgICAgKiBvcmRlcmVkIGFjY29yZGluZyB0aGVpciBwcmVmZXJlbmNlIG9yZGVyLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSBjb250YWluaW5nIGFsbCBpbnN0YWxsZWQgcHJvdmlkZXJzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIFByb3ZpZGVyW10gZ2V0UHJvdmlkZXJzKCkgeworICAgICAgICByZXR1cm4gU2VydmljZXMuZ2V0UHJvdmlkZXJzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIFByb3ZpZGVyfSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS4gUmV0dXJucyB7QGNvZGUKKyAgICAgKiBudWxsfSBpZiBuYW1lIGlzIHtAY29kZSBudWxsfSBvciBubyBwcm92aWRlciB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBpcworICAgICAqIGluc3RhbGxlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcmVxdWVzdGVkIHByb3ZpZGVyLgorICAgICAqIEByZXR1cm4gdGhlIHByb3ZpZGVyIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLCBtYXliZSB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgUHJvdmlkZXIgZ2V0UHJvdmlkZXIoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIFNlcnZpY2VzLmdldFByb3ZpZGVyKG5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFycmF5IG9mIHByb3ZpZGVycyB3aGljaCBtZWV0IHRoZSB1c2VyIHN1cHBsaWVkIHN0cmluZworICAgICAqIGZpbHRlci4gVGhlIHNwZWNpZmllZCBmaWx0ZXIgbXVzdCBiZSBzdXBwbGllZCBpbiBvbmUgb2YgdHdvIGZvcm1hdHM6CisgICAgICogPG5sPgorICAgICAqIDxsaT4gQ1JZUFRPX1NFUlZJQ0VfTkFNRS5BTEdPUklUSE1fT1JfVFlQRQorICAgICAqIDxwPgorICAgICAqIChmb3IgZXhhbXBsZTogIk1lc3NhZ2VEaWdlc3QuU0hBIikKKyAgICAgKiA8bGk+IENSWVBUT19TRVJWSUNFX05BTUUuQUxHT1JJVEhNX09SX1RZUEUKKyAgICAgKiBBVFRSX05BTUU6QVRUUl9WQUxVRQorICAgICAqIDxwPgorICAgICAqIChmb3IgZXhhbXBsZTogIlNpZ25hdHVyZS5NRDJ3aXRoUlNBIEtleVNpemU6NTEyIikKKyAgICAgKiA8L25sPgorICAgICAqCisgICAgICogQHBhcmFtIGZpbHRlcgorICAgICAqICAgICAgICAgICAgY2FzZS1pbnNlbnNpdGl2ZSBmaWx0ZXIuCisgICAgICogQHJldHVybiB0aGUgcHJvdmlkZXJzIHdoaWNoIG1lZXQgdGhlIHVzZXIgc3VwcGxpZWQgc3RyaW5nIGZpbHRlciB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZpbHRlcn0uIEEge0Bjb2RlIG51bGx9IHZhbHVlIHNpZ25pZmllcyB0aGF0IG5vbmUgb2YgdGhlCisgICAgICogICAgICAgICBpbnN0YWxsZWQgcHJvdmlkZXJzIG1lZXRzIHRoZSBmaWx0ZXIgc3BlY2lmaWNhdGlvbi4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiB1bnVzYWJsZSBmaWx0ZXIgaXMgc3VwcGxpZWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBmaWx0ZXJ9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFByb3ZpZGVyW10gZ2V0UHJvdmlkZXJzKFN0cmluZyBmaWx0ZXIpIHsKKyAgICAgICAgaWYgKGZpbHRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZmlsdGVyLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4gaG0gPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgaW50IGkgPSBmaWx0ZXIuaW5kZXhPZignOicpOworICAgICAgICBpZiAoKGkgPT0gZmlsdGVyLmxlbmd0aCgpIC0gMSkgfHwgKGkgPT0gMCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGkgPCAxKSB7CisgICAgICAgICAgICBobS5wdXQoZmlsdGVyLCAiIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBobS5wdXQoZmlsdGVyLnN1YnN0cmluZygwLCBpKSwgZmlsdGVyLnN1YnN0cmluZyhpICsgMSkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRQcm92aWRlcnMoaG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFycmF5IG9mIHByb3ZpZGVycyB3aGljaCBtZWV0IHRoZSB1c2VyIHN1cHBsaWVkIHNldCBvZgorICAgICAqIGZpbHRlcnMuIFRoZSBmaWx0ZXIgbXVzdCBiZSBzdXBwbGllZCBpbiBvbmUgb2YgdHdvIGZvcm1hdHM6CisgICAgICogPG5sPgorICAgICAqIDxsaT4gQ1JZUFRPX1NFUlZJQ0VfTkFNRS5BTEdPUklUSE1fT1JfVFlQRQorICAgICAqIDxwPgorICAgICAqIGZvciBleGFtcGxlOiAiTWVzc2FnZURpZ2VzdC5TSEEiIFRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIGtleSBtdXN0CisgICAgICogYmUgYW4gZW1wdHkgc3RyaW5nLiA8bGk+IENSWVBUT19TRVJWSUNFX05BTUUuQUxHT1JJVEhNX09SX1RZUEUKKyAgICAgKiBBVFRSX05BTUU6QVRUUl9WQUxVRQorICAgICAqIDxwPgorICAgICAqIGZvciBleGFtcGxlOiAiU2lnbmF0dXJlLk1EMndpdGhSU0EgS2V5U2l6ZTo1MTIiIHdoZXJlICJLZXlTaXplOjUxMiIgaXMKKyAgICAgKiB0aGUgdmFsdWUgb2YgdGhlIGZpbHRlciBtYXAgZW50cnkuCisgICAgICogPC9ubD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWx0ZXIKKyAgICAgKiAgICAgICAgICAgIGNhc2UtaW5zZW5zaXRpdmUgZmlsdGVyLgorICAgICAqIEByZXR1cm4gdGhlIHByb3ZpZGVycyB3aGljaCBtZWV0IHRoZSB1c2VyIHN1cHBsaWVkIHN0cmluZyBmaWx0ZXIge0Bjb2RlCisgICAgICogICAgICAgICBmaWx0ZXJ9LiBBIHtAY29kZSBudWxsfSB2YWx1ZSBzaWduaWZpZXMgdGhhdCBub25lIG9mIHRoZQorICAgICAqICAgICAgICAgaW5zdGFsbGVkIHByb3ZpZGVycyBtZWV0cyB0aGUgZmlsdGVyIHNwZWNpZmljYXRpb24uCisgICAgICogQHRocm93cyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gdW51c2FibGUgZmlsdGVyIGlzIHN1cHBsaWVkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZmlsdGVyfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgUHJvdmlkZXJbXSBnZXRQcm92aWRlcnMoTWFwPFN0cmluZyxTdHJpbmc+IGZpbHRlcikgeworICAgICAgICBpZiAoZmlsdGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChmaWx0ZXIuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBqYXZhLnV0aWwuTGlzdDxQcm92aWRlcj4gcmVzdWx0ID0gU2VydmljZXMuZ2V0UHJvdmlkZXJzTGlzdCgpOworICAgICAgICBTZXQ8RW50cnk8U3RyaW5nLCBTdHJpbmc+PiBrZXlzID0gZmlsdGVyLmVudHJ5U2V0KCk7CisgICAgICAgIE1hcC5FbnRyeTxTdHJpbmcsIFN0cmluZz4gZW50cnk7CisgICAgICAgIGZvciAoSXRlcmF0b3I8RW50cnk8U3RyaW5nLCBTdHJpbmc+PiBpdCA9IGtleXMuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOykgeworICAgICAgICAgICAgZW50cnkgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICBTdHJpbmcga2V5ID0gZW50cnkuZ2V0S2V5KCk7CisgICAgICAgICAgICBTdHJpbmcgdmFsID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgIFN0cmluZyBhdHRyaWJ1dGUgPSBudWxsOworICAgICAgICAgICAgaW50IGkgPSBrZXkuaW5kZXhPZignICcpOworICAgICAgICAgICAgaW50IGogPSBrZXkuaW5kZXhPZignLicpOworICAgICAgICAgICAgaWYgKGogPT0gLTEpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGkgPT0gLTEpIHsgLy8gPGNyeXB0b19zZXJ2aWNlPi48YWxnb3JpdGhtX29yX3R5cGU+CisgICAgICAgICAgICAgICAgaWYgKHZhbC5sZW5ndGgoKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsgLy8gPGNyeXB0b19zZXJ2aWNlPi48YWxnb3JpdGhtX29yX3R5cGU+IDxhdHRyaWJ1dGVfbmFtZT4KKyAgICAgICAgICAgICAgICBpZiAodmFsLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXR0cmlidXRlID0ga2V5LnN1YnN0cmluZyhpICsgMSk7CisgICAgICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZS50cmltKCkubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBrZXkgPSBrZXkuc3Vic3RyaW5nKDAsIGkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3RyaW5nIHNlcnYgPSBrZXkuc3Vic3RyaW5nKDAsIGopOworICAgICAgICAgICAgU3RyaW5nIGFsZyA9IGtleS5zdWJzdHJpbmcoaiArIDEpOworICAgICAgICAgICAgaWYgKHNlcnYubGVuZ3RoKCkgPT0gMCB8fCBhbGcubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQcm92aWRlciBwOworICAgICAgICAgICAgZm9yIChpbnQgayA9IDA7IGsgPCByZXN1bHQuc2l6ZSgpOyBrKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBwID0gcmVzdWx0LmdldChrKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICghcC5pbXBsZW1lbnRzQWxnKHNlcnYsIGFsZywgYXR0cmlidXRlLCB2YWwpKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5yZW1vdmUocCk7CisgICAgICAgICAgICAgICAgICAgIGstLTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJlc3VsdC5zaXplKCkgPiAwKSB7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0LnRvQXJyYXkobmV3IFByb3ZpZGVyW3Jlc3VsdC5zaXplKCldKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgc2VjdXJpdHkgcHJvcGVydHkgbmFtZWQgYnkgdGhlIGFyZ3VtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlcXVlc3RlZCBzZWN1cml0eSBwcm9wZXJ0eS4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgc2VjdXJpdHkgcHJvcGVydHkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0UHJvcGVydHkoU3RyaW5nIGtleSkgeworICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigia2V5ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcHJvcGVydHkgPSBzZWNwcm9wcy5nZXRQcm9wZXJ0eShrZXkpOworICAgICAgICBpZiAocHJvcGVydHkgIT0gbnVsbCkgeworICAgICAgICAgICAgcHJvcGVydHkgPSBwcm9wZXJ0eS50cmltKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHByb3BlcnR5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgc2VjdXJpdHkgcHJvcGVydHkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBrZXksIFN0cmluZyB2YWx1ZSkgeworICAgICAgICBzZWNwcm9wcy5wdXQoa2V5LCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBTZXR9IG9mIGFsbCByZWdpc3RlcmVkIGFsZ29yaXRobXMgZm9yIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjcnlwdG9ncmFwaGljIHNlcnZpY2UuIHtAY29kZSAiU2lnbmF0dXJlIn0sIHtAY29kZSAiQ2lwaGVyIn0gYW5kIHtAY29kZQorICAgICAqICJLZXlTdG9yZSJ9IGFyZSBleGFtcGxlcyBmb3Igc3VjaCBraW5kIG9mIHNlcnZpY2VzLgorICAgICAqCisgICAgICogQHBhcmFtIHNlcnZpY2VOYW1lCisgICAgICogICAgICAgICAgICB0aGUgY2FzZS1pbnNlbnNpdGl2ZSBuYW1lIG9mIHRoZSBzZXJ2aWNlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgU2V0fSBvZiBhbGwgcmVnaXN0ZXJlZCBhbGdvcml0aG1zIGZvciB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBjcnlwdG9ncmFwaGljIHNlcnZpY2UsIG9yIGFuIGVtcHR5IHtAY29kZSBTZXR9IGlmIHtAY29kZQorICAgICAqICAgICAgICAgc2VydmljZU5hbWV9IGlzIHtAY29kZSBudWxsfSBvciBpZiBubyByZWdpc3RlcmVkIHByb3ZpZGVyCisgICAgICogICAgICAgICBwcm92aWRlcyB0aGUgcmVxdWVzdGVkIHNlcnZpY2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTZXQ8U3RyaW5nPiBnZXRBbGdvcml0aG1zKFN0cmluZyBzZXJ2aWNlTmFtZSkgeworICAgICAgICBTZXQ8U3RyaW5nPiByZXN1bHQgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7CisgICAgICAgIC8vIGNvbXBhdGliaWxpdHkgd2l0aCBSSQorICAgICAgICBpZiAoc2VydmljZU5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgICAgICBmb3IgKFByb3ZpZGVyIHByb3ZpZGVyIDogZ2V0UHJvdmlkZXJzKCkpIHsKKyAgICAgICAgICAgIGZvciAoUHJvdmlkZXIuU2VydmljZSBzZXJ2aWNlOiBwcm92aWRlci5nZXRTZXJ2aWNlcygpKSB7CisgICAgICAgICAgICAgICAgaWYgKHNlcnZpY2UuZ2V0VHlwZSgpLmVxdWFsc0lnbm9yZUNhc2Uoc2VydmljZU5hbWUpKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQoc2VydmljZS5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICoKKyAgICAgKiBVcGRhdGUgc2VxdWVuY2UgbnVtYmVycyBvZiBhbGwgcHJvdmlkZXJzLgorICAgICAqCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCByZW51bVByb3ZpZGVycygpIHsKKyAgICAgICAgUHJvdmlkZXJbXSBwID0gU2VydmljZXMuZ2V0UHJvdmlkZXJzKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgcFtpXS5zZXRQcm92aWRlck51bWJlcihpICsgMSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTZWN1cml0eURvb3IgaW1wbGVtZW50cyBTZWN1cml0eUFjY2VzcyB7CisgICAgICAgIC8vIEFjY2VzcyB0byBTZWN1cml0eS5yZW51bVByb3ZpZGVycygpCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbnVtUHJvdmlkZXJzKCkgeworICAgICAgICAgICAgU2VjdXJpdHkucmVudW1Qcm92aWRlcnMoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vICBBY2Nlc3MgdG8gU2VjdXJpdHkuZ2V0QWxpYXNlcygpCisgICAgICAgIHB1YmxpYyBMaXN0PFN0cmluZz4gZ2V0QWxpYXNlcyhQcm92aWRlci5TZXJ2aWNlIHMpIHsKKyAgICAgICAgICAgIHJldHVybiBzLmdldEFsaWFzZXMoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEFjY2VzcyB0byBQcm92aWRlci5nZXRTZXJ2aWNlKCkKKyAgICAgICAgcHVibGljIFByb3ZpZGVyLlNlcnZpY2UgZ2V0U2VydmljZShQcm92aWRlciBwLCBTdHJpbmcgdHlwZSkgeworICAgICAgICAgICAgcmV0dXJuIHAuZ2V0U2VydmljZSh0eXBlKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1NlY3VyaXR5UGVybWlzc2lvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2VjdXJpdHlQZXJtaXNzaW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOThhZmNiMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1NlY3VyaXR5UGVybWlzc2lvbi5qYXZhCkBAIC0wLDAgKzEsMzEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworLyoqCisgKiBMZWdhY3kgc2VjdXJpdHkgY29kZTsgZG8gbm90IHVzZS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFNlY3VyaXR5UGVybWlzc2lvbiBleHRlbmRzIEJhc2ljUGVybWlzc2lvbiB7CisgICAgcHVibGljIFNlY3VyaXR5UGVybWlzc2lvbihTdHJpbmcgbmFtZSkgeyBzdXBlcigiIik7IH0KKworICAgIHB1YmxpYyBTZWN1cml0eVBlcm1pc3Npb24oU3RyaW5nIG5hbWUsIFN0cmluZyBhY3Rpb24pIHsgc3VwZXIoIiIsICIiKTsgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgZ2V0QWN0aW9ucygpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpbXBsaWVzKFBlcm1pc3Npb24gcGVybWlzc2lvbikgeyByZXR1cm4gdHJ1ZTsgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2lnbmF0dXJlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9TaWduYXR1cmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOWUxZTQxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2lnbmF0dXJlLmphdmEKQEAgLTAsMCArMSw2NjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmZvcnRyZXNzLkVuZ2luZTsKKworCisvKioKKyAqIHtAY29kZSBTaWduYXR1cmV9IGlzIGFuIGVuZ2luZSBjbGFzcyB3aGljaCBpcyBjYXBhYmxlIG9mIGNyZWF0aW5nIGFuZAorICogdmVyaWZ5aW5nIGRpZ2l0YWwgc2lnbmF0dXJlcywgdXNpbmcgZGlmZmVyZW50IGFsZ29yaXRobXMgdGhhdCBoYXZlIGJlZW4KKyAqIHJlZ2lzdGVyZWQgd2l0aCB0aGUge0BsaW5rIFNlY3VyaXR5fSBjbGFzcy4KKyAqCisgKiBAc2VlIFNpZ25hdHVyZVNwaQorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU2lnbmF0dXJlIGV4dGVuZHMgU2lnbmF0dXJlU3BpIHsKKworICAgIC8vIFRoZSBzZXJ2aWNlIG5hbWUuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNFUlZJQ0UgPSAiU2lnbmF0dXJlIjsKKworICAgIC8vIFVzZWQgdG8gYWNjZXNzIGNvbW1vbiBlbmdpbmUgZnVuY3Rpb25hbGl0eQorICAgIHByaXZhdGUgc3RhdGljIEVuZ2luZSBFTkdJTkUgPSBuZXcgRW5naW5lKFNFUlZJQ0UpOworCisgICAgLy8gVGhlIHByb3ZpZGVyCisgICAgcHJpdmF0ZSBQcm92aWRlciBwcm92aWRlcjsKKworICAgIC8vIFRoZSBhbGdvcml0aG0uCisgICAgcHJpdmF0ZSBTdHJpbmcgYWxnb3JpdGhtOworCisgICAgLyoqCisgICAgICogQ29uc3RhbnQgdGhhdCBpbmRpY2F0ZXMgdGhhdCB0aGlzIHtAY29kZSBTaWduYXR1cmV9IGluc3RhbmNlIGhhcyBub3QgeWV0CisgICAgICogYmVlbiBpbml0aWFsaXplZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBVTklOSVRJQUxJWkVEID0gMDsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IHRoYXQgaW5kaWNhdGVzIHRoYXQgdGhpcyB7QGNvZGUgU2lnbmF0dXJlfSBpbnN0YW5jZSBoYXMgYmVlbgorICAgICAqIGluaXRpYWxpemVkIGZvciBzaWduaW5nLgorICAgICAqLworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFNJR04gPSAyOworCisgICAgLyoqCisgICAgICogQ29uc3RhbnQgdGhhdCBpbmRpY2F0ZXMgdGhhdCB0aGlzIHtAY29kZSBTaWduYXR1cmV9IGluc3RhbmNlIGhhcyBiZWVuCisgICAgICogaW5pdGlhbGl6ZWQgZm9yIHZlcmlmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBWRVJJRlkgPSAzOworCisgICAgLyoqCisgICAgICogUmVwcmVzZW50cyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGlzIHtAY29kZSBTaWduYXR1cmV9LiBUaGUgdGhyZWUKKyAgICAgKiBwb3NzaWJsZSBzdGF0ZXMgYXJlIHtAbGluayAjVU5JTklUSUFMSVpFRH0sIHtAbGluayAjU0lHTn0gb3IKKyAgICAgKiB7QGxpbmsgI1ZFUklGWX0uCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBzdGF0ZSA9IFVOSU5JVElBTElaRUQ7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBTaWduYXR1cmV9IHdpdGggdGhlIG5hbWUgb2YKKyAgICAgKiB0aGUgYWxnb3JpdGhtIHRvIHVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIGFsZ29yaXRobSB0byB1c2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNpZ25hdHVyZShTdHJpbmcgYWxnb3JpdGhtKSB7CisgICAgICAgIHRoaXMuYWxnb3JpdGhtID0gYWxnb3JpdGhtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFNpZ25hdHVyZX0gdGhhdCB1dGlsaXplcyB0aGUgc3BlY2lmaWVkCisgICAgICogYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobSB0byB1c2UuCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgU2lnbmF0dXJlfSB0aGF0IHV0aWxpemVzIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIGFsZ29yaXRobS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhbGdvcml0aG19IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNpZ25hdHVyZSBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhbGdvcml0aG0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgRW5naW5lLlNwaUFuZFByb3ZpZGVyIHNhcCA9IEVOR0lORS5nZXRJbnN0YW5jZShhbGdvcml0aG0sIG51bGwpOworICAgICAgICBPYmplY3Qgc3BpID0gc2FwLnNwaTsKKyAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIgPSBzYXAucHJvdmlkZXI7CisgICAgICAgIGlmIChzcGkgaW5zdGFuY2VvZiBTaWduYXR1cmUpIHsKKyAgICAgICAgICAgIFNpZ25hdHVyZSByZXN1bHQgPSAoU2lnbmF0dXJlKSBzcGk7CisgICAgICAgICAgICByZXN1bHQuYWxnb3JpdGhtID0gYWxnb3JpdGhtOworICAgICAgICAgICAgcmVzdWx0LnByb3ZpZGVyID0gcHJvdmlkZXI7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU2lnbmF0dXJlSW1wbCgoU2lnbmF0dXJlU3BpKSBzcGksIHByb3ZpZGVyLCBhbGdvcml0aG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFNpZ25hdHVyZX0gdGhhdCB1dGlsaXplcyB0aGUgc3BlY2lmaWVkCisgICAgICogYWxnb3JpdGhtIGZyb20gdGhlIHNwZWNpZmllZCBwcm92aWRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0gdG8gdXNlLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyLgorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFNpZ25hdHVyZX0gdGhhdCB1dGlsaXplcyB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBhbGdvcml0aG0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYWxnb3JpdGhtfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHByb3ZpZGVyID09IG51bGwgfHwgcHJvdmlkZXIuaXNFbXB0eSgpfQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU2lnbmF0dXJlIGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcikKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFsZ29yaXRobSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCB8fCBwcm92aWRlci5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBwID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXIocHJvdmlkZXIpOworICAgICAgICBpZiAocCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24ocHJvdmlkZXIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRTaWduYXR1cmVJbnN0YW5jZShhbGdvcml0aG0sIHApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFNpZ25hdHVyZX0gdGhhdCB1dGlsaXplcyB0aGUgc3BlY2lmaWVkCisgICAgICogYWxnb3JpdGhtIGZyb20gdGhlIHNwZWNpZmllZCBwcm92aWRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0gdG8gdXNlLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHNlY3VyaXR5IHByb3ZpZGVyLgorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFNpZ25hdHVyZX0gdGhhdCB1dGlsaXplcyB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBhbGdvcml0aG0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFsZ29yaXRobX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBwcm92aWRlciA9PSBudWxsfQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU2lnbmF0dXJlIGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhbGdvcml0aG0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0U2lnbmF0dXJlSW5zdGFuY2UoYWxnb3JpdGhtLCBwcm92aWRlcik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU2lnbmF0dXJlIGdldFNpZ25hdHVyZUluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sCisgICAgICAgICAgICBQcm92aWRlciBwcm92aWRlcikgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdCBzcGkgPSBFTkdJTkUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBwcm92aWRlciwgbnVsbCk7CisgICAgICAgIGlmIChzcGkgaW5zdGFuY2VvZiBTaWduYXR1cmUpIHsKKyAgICAgICAgICAgIFNpZ25hdHVyZSByZXN1bHQgPSAoU2lnbmF0dXJlKSBzcGk7CisgICAgICAgICAgICByZXN1bHQuYWxnb3JpdGhtID0gYWxnb3JpdGhtOworICAgICAgICAgICAgcmVzdWx0LnByb3ZpZGVyID0gcHJvdmlkZXI7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU2lnbmF0dXJlSW1wbCgoU2lnbmF0dXJlU3BpKSBzcGksIHByb3ZpZGVyLCBhbGdvcml0aG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByb3ZpZGVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHtAY29kZSBTaWduYXR1cmV9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJvdmlkZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMge0Bjb2RlIFNpZ25hdHVyZX0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFByb3ZpZGVyIGdldFByb3ZpZGVyKCkgeworICAgICAgICByZXR1cm4gcHJvdmlkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtIG9mIHRoaXMge0Bjb2RlIFNpZ25hdHVyZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0gb2YgdGhpcyB7QGNvZGUgU2lnbmF0dXJlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgcmV0dXJuIGFsZ29yaXRobTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBTaWduYXR1cmV9IGluc3RhbmNlIGZvciBzaWduYXR1cmUgdmVyaWZpY2F0aW9uLAorICAgICAqIHVzaW5nIHRoZSBwdWJsaWMga2V5IG9mIHRoZSBpZGVudGl0eSB3aG9zZSBzaWduYXR1cmUgaXMgZ29pbmcgdG8gYmUKKyAgICAgKiB2ZXJpZmllZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwdWJsaWNLZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBwdWJsaWMga2V5LgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBwdWJsaWNLZXl9IGlzIG5vdCB2YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBpbml0VmVyaWZ5KFB1YmxpY0tleSBwdWJsaWNLZXkpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIGVuZ2luZUluaXRWZXJpZnkocHVibGljS2V5KTsKKyAgICAgICAgc3RhdGUgPSBWRVJJRlk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyB7QGNvZGUgU2lnbmF0dXJlfSBpbnN0YW5jZSBmb3Igc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiwKKyAgICAgKiB1c2luZyB0aGUgY2VydGlmaWNhdGUgb2YgdGhlIGlkZW50aXR5IHdob3NlIHNpZ25hdHVyZSBpcyBnb2luZyB0byBiZQorICAgICAqIHZlcmlmaWVkLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBnaXZlbiBjZXJ0aWZpY2F0ZSBpcyBhbiBpbnN0YW5jZSBvZiB7QGxpbmsgWDUwOUNlcnRpZmljYXRlfSBhbmQKKyAgICAgKiBoYXMgYSBrZXkgdXNhZ2UgcGFyYW1ldGVyIHRoYXQgaW5kaWNhdGVzLCB0aGF0IHRoaXMgY2VydGlmaWNhdGUgaXMgbm90IHRvCisgICAgICogYmUgdXNlZCBmb3Igc2lnbmluZywgYW4ge0Bjb2RlIEludmFsaWRLZXlFeGNlcHRpb259IGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjZXJ0aWZpY2F0ZQorICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRlIHVzZWQgdG8gdmVyaWZ5IGEgc2lnbmF0dXJlLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwdWJsaWNLZXkgaW4gdGhlIGNlcnRpZmljYXRlIGlzIG5vdCB2YWxpZCBvciBub3QgdG8gYmUKKyAgICAgKiAgICAgICAgICAgICB1c2VkIGZvciBzaWduaW5nLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGluaXRWZXJpZnkoQ2VydGlmaWNhdGUgY2VydGlmaWNhdGUpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjZXJ0aWZpY2F0ZSBpbnN0YW5jZW9mIFg1MDlDZXJ0aWZpY2F0ZSkgeworICAgICAgICAgICAgU2V0IGNlID0gKChYNTA5Q2VydGlmaWNhdGUpIGNlcnRpZmljYXRlKS5nZXRDcml0aWNhbEV4dGVuc2lvbk9JRHMoKTsKKyAgICAgICAgICAgIGJvb2xlYW4gY3JpdGljYWwgPSBmYWxzZTsKKyAgICAgICAgICAgIGlmIChjZSAhPSBudWxsICYmICFjZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yIGkgPSBjZS5pdGVyYXRvcigpOyBpLmhhc05leHQoKTspIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCIyLjUuMjkuMTUiLmVxdWFscyhpLm5leHQoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vS2V5VXNhZ2UgT0lEID0gMi41LjI5LjE1CisgICAgICAgICAgICAgICAgICAgICAgICBjcml0aWNhbCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoY3JpdGljYWwpIHsKKyAgICAgICAgICAgICAgICAgICAgYm9vbGVhbltdIGtleVVzYWdlID0gKChYNTA5Q2VydGlmaWNhdGUpIGNlcnRpZmljYXRlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRLZXlVc2FnZSgpOworICAgICAgICAgICAgICAgICAgICAvLyBBcyBzcGVjaWZpZWQgaW4gUkZDIDMyODAgLQorICAgICAgICAgICAgICAgICAgICAvLyBJbnRlcm5ldCBYLjUwOSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlCisgICAgICAgICAgICAgICAgICAgIC8vIENlcnRpZmljYXRlIGFuZCBDZXJ0aWZpY2F0ZSBSZXZvY2F0aW9uIExpc3QgKENSTCkgUHJvZmlsZS4KKyAgICAgICAgICAgICAgICAgICAgLy8gKGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KQorICAgICAgICAgICAgICAgICAgICAvLworICAgICAgICAgICAgICAgICAgICAvLyBLZXlVc2FnZSA6Oj0gQklUIFNUUklORyB7IGRpZ2l0YWxTaWduYXR1cmUgKDApLCA8c2tpcHBlZD4gfQorICAgICAgICAgICAgICAgICAgICBpZiAoKGtleVVzYWdlICE9IG51bGwpICYmICgha2V5VXNhZ2VbMF0pKSB7IC8vIGRpZ2l0YWxTaWduYXR1cmUKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5RXhjZXB0aW9uKCJUaGUgcHVibGljIGtleSBpbiB0aGUgY2VydGlmaWNhdGUgY2Fubm90IGJlIHVzZWQgZm9yIGRpZ2l0YWwgc2lnbmF0dXJlIHB1cnBvc2VzIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZW5naW5lSW5pdFZlcmlmeShjZXJ0aWZpY2F0ZS5nZXRQdWJsaWNLZXkoKSk7CisgICAgICAgIHN0YXRlID0gVkVSSUZZOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIFNpZ25hdHVyZX0gaW5zdGFuY2UgZm9yIHNpZ25pbmcsIHVzaW5nIHRoZQorICAgICAqIHByaXZhdGUga2V5IG9mIHRoZSBpZGVudGl0eSB3aG9zZSBzaWduYXR1cmUgaXMgZ29pbmcgdG8gYmUgZ2VuZXJhdGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHByaXZhdGVLZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcml2YXRlIGtleS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcHJpdmF0ZUtleX0gaXMgbm90IHZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGluaXRTaWduKFByaXZhdGVLZXkgcHJpdmF0ZUtleSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgZW5naW5lSW5pdFNpZ24ocHJpdmF0ZUtleSk7CisgICAgICAgIHN0YXRlID0gU0lHTjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBTaWduYXR1cmV9IGluc3RhbmNlIGZvciBzaWduaW5nLCB1c2luZyB0aGUKKyAgICAgKiBwcml2YXRlIGtleSBvZiB0aGUgaWRlbnRpdHkgd2hvc2Ugc2lnbmF0dXJlIGlzIGdvaW5nIHRvIGJlIGdlbmVyYXRlZCBhbmQKKyAgICAgKiB0aGUgc3BlY2lmaWVkIHNvdXJjZSBvZiByYW5kb21uZXNzLgorICAgICAqCisgICAgICogQHBhcmFtIHByaXZhdGVLZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcml2YXRlIGtleS4KKyAgICAgKiBAcGFyYW0gcmFuZG9tCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIFNlY3VyZVJhbmRvbX0gdG8gdXNlLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBwcml2YXRlS2V5fSBpcyBub3QgdmFsaWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdFNpZ24oUHJpdmF0ZUtleSBwcml2YXRlS2V5LCBTZWN1cmVSYW5kb20gcmFuZG9tKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICBlbmdpbmVJbml0U2lnbihwcml2YXRlS2V5LCByYW5kb20pOworICAgICAgICBzdGF0ZSA9IFNJR047CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGFuZCByZXR1cm5zIHRoZSBzaWduYXR1cmUgb2YgYWxsIHVwZGF0ZWQgZGF0YS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIHtAY29kZSBTaWduYXR1cmV9IGluc3RhbmNlIGlzIHJlc2V0IHRvIHRoZSBzdGF0ZSBvZiBpdHMgbGFzdAorICAgICAqIGluaXRpYWxpemF0aW9uIGZvciBzaWduaW5nIGFuZCB0aHVzIGNhbiBiZSB1c2VkIGZvciBhbm90aGVyIHNpZ25hdHVyZQorICAgICAqIGZyb20gdGhlIHNhbWUgaWRlbnRpdHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzaWduYXR1cmUgb2YgYWxsIHVwZGF0ZWQgZGF0YS4KKyAgICAgKiBAdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIFNpZ25hdHVyZX0gaW5zdGFuY2UgaXMgbm90IGluaXRpYWxpemVkCisgICAgICogICAgICAgICAgICAgcHJvcGVybHkuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJ5dGVbXSBzaWduKCkgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzdGF0ZSAhPSBTSUdOKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU2lnbmF0dXJlRXhjZXB0aW9uKCJTaWduYXR1cmUgb2JqZWN0IGlzIG5vdCBpbml0aWFsaXplZCBwcm9wZXJseSIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmdpbmVTaWduKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGFuZCBzdG9yZXMgdGhlIHNpZ25hdHVyZSBvZiBhbGwgdXBkYXRlZCBkYXRhIGluIHRoZSBwcm92aWRlZAorICAgICAqIHtAY29kZSBieXRlW119IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGxlbmd0aC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIHtAY29kZSBTaWduYXR1cmV9IGluc3RhbmNlIGlzIHJlc2V0IHRvIHRoZSBzdGF0ZSBvZiBpdHMgbGFzdAorICAgICAqIGluaXRpYWxpemF0aW9uIGZvciBzaWduaW5nIGFuZCB0aHVzIGNhbiBiZSB1c2VkIGZvciBhbm90aGVyIHNpZ25hdHVyZQorICAgICAqIGZyb20gdGhlIHNhbWUgaWRlbnRpdHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0YnVmCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHRvIHN0b3JlIHRoZSBzaWduYXR1cmUuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBieXRlIGluIHtAY29kZSBvdXRidWZ9IHRvIHN0b3JlLgorICAgICAqIEBwYXJhbSBsZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWxsb2NhdGVkIGZvciB0aGUgc2lnbmF0dXJlLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBzdG9yZWQgaW4ge0Bjb2RlIG91dGJ1Zn0uCisgICAgICogQHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBTaWduYXR1cmV9IGluc3RhbmNlIGlzIG5vdCBpbml0aWFsaXplZAorICAgICAqICAgICAgICAgICAgIHByb3Blcmx5LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldH0gb3Ige0Bjb2RlIGxlbn0gYXJlIG5vdCB2YWxpZCBpbiByZXNwZWN0IHRvCisgICAgICogICAgICAgICAgICAge0Bjb2RlIG91dGJ1Zn0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBzaWduKGJ5dGVbXSBvdXRidWYsIGludCBvZmZzZXQsIGludCBsZW4pCisgICAgICAgICAgICB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG91dGJ1ZiA9PSBudWxsIHx8IG9mZnNldCA8IDAgfHwgbGVuIDwgMCB8fAorICAgICAgICAgICAgICAgIG9mZnNldCArIGxlbiA+IG91dGJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3RhdGUgIT0gU0lHTikgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNpZ25hdHVyZUV4Y2VwdGlvbigiU2lnbmF0dXJlIG9iamVjdCBpcyBub3QgaW5pdGlhbGl6ZWQgcHJvcGVybHkiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5naW5lU2lnbihvdXRidWYsIG9mZnNldCwgbGVuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgZ2l2ZW4ge0Bjb2RlIHNpZ25hdHVyZX0gY2FuIGJlIHZlcmlmaWVkIHVzaW5nIHRoZQorICAgICAqIHB1YmxpYyBrZXkgb3IgYSBjZXJ0aWZpY2F0ZSBvZiB0aGUgc2lnbmVyLgorICAgICAqIDxwPgorICAgICAqIFRoaXMge0Bjb2RlIFNpZ25hdHVyZX0gaW5zdGFuY2UgaXMgcmVzZXQgdG8gdGhlIHN0YXRlIG9mIGl0cyBsYXN0CisgICAgICogaW5pdGlhbGl6YXRpb24gZm9yIHZlcmlmeWluZyBhbmQgdGh1cyBjYW4gYmUgdXNlZCB0byB2ZXJpZnkgYW5vdGhlcgorICAgICAqIHNpZ25hdHVyZSBvZiB0aGUgc2FtZSBzaWduZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2lnbmF0dXJlCisgICAgICogICAgICAgICAgICB0aGUgc2lnbmF0dXJlIHRvIHZlcmlmeS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc2lnbmF0dXJlIHdhcyB2ZXJpZmllZCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgU2lnbmF0dXJlfSBpbnN0YW5jZSBpcyBub3QgaW5pdGlhbGl6ZWQKKyAgICAgKiAgICAgICAgICAgICBwcm9wZXJseS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiB2ZXJpZnkoYnl0ZVtdIHNpZ25hdHVyZSkgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzdGF0ZSAhPSBWRVJJRlkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTaWduYXR1cmVFeGNlcHRpb24oIlNpZ25hdHVyZSBvYmplY3QgaXMgbm90IGluaXRpYWxpemVkIHByb3Blcmx5Iik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVuZ2luZVZlcmlmeShzaWduYXR1cmUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBnaXZlbiB7QGNvZGUgc2lnbmF0dXJlfSBzdGFydGluZyBhdCBpbmRleCB7QGNvZGUKKyAgICAgKiBvZmZzZXR9IHdpdGgge0Bjb2RlIGxlbmd0aH0gYnl0ZXMgY2FuIGJlIHZlcmlmaWVkIHVzaW5nIHRoZSBwdWJsaWMga2V5IG9yCisgICAgICogYSBjZXJ0aWZpY2F0ZSBvZiB0aGUgc2lnbmVyLgorICAgICAqIDxwPgorICAgICAqIFRoaXMge0Bjb2RlIFNpZ25hdHVyZX0gaW5zdGFuY2UgaXMgcmVzZXQgdG8gdGhlIHN0YXRlIG9mIGl0cyBsYXN0CisgICAgICogaW5pdGlhbGl6YXRpb24gZm9yIHZlcmlmeWluZyBhbmQgdGh1cyBjYW4gYmUgdXNlZCB0byB2ZXJpZnkgYW5vdGhlcgorICAgICAqIHNpZ25hdHVyZSBvZiB0aGUgc2FtZSBzaWduZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2lnbmF0dXJlCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGJ5dGVbXX0gY29udGFpbmluZyB0aGUgc2lnbmF0dXJlIHRvIHZlcmlmeS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgaW5kZXggaW4ge0Bjb2RlIHNpZ25hdHVyZX0gb2YgdGhlIHNpZ25hdHVyZS4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFsbG9jYXRlZCBmb3IgdGhlIHNpZ25hdHVyZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc2lnbmF0dXJlIHdhcyB2ZXJpZmllZCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgU2lnbmF0dXJlfSBpbnN0YW5jZSBpcyBub3QgaW5pdGlhbGl6ZWQKKyAgICAgKiAgICAgICAgICAgICBwcm9wZXJseS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXR9IG9yIHtAY29kZSBsZW5ndGh9IGFyZSBub3QgdmFsaWQgaW4gcmVzcGVjdAorICAgICAqICAgICAgICAgICAgIHRvIHtAY29kZSBzaWduYXR1cmV9LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIHZlcmlmeShieXRlW10gc2lnbmF0dXJlLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzdGF0ZSAhPSBWRVJJRlkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTaWduYXR1cmVFeGNlcHRpb24oIlNpZ25hdHVyZSBvYmplY3QgaXMgbm90IGluaXRpYWxpemVkIHByb3Blcmx5Iik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNpZ25hdHVyZSA9PSBudWxsIHx8IG9mZnNldCA8IDAgfHwgbGVuZ3RoIDwgMCB8fAorICAgICAgICAgICAgICAgIG9mZnNldCArIGxlbmd0aCA+IHNpZ25hdHVyZS5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5naW5lVmVyaWZ5KHNpZ25hdHVyZSwgb2Zmc2V0LCBsZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhlIGRhdGEgdG8gYmUgdmVyaWZpZWQgb3IgdG8gYmUgc2lnbmVkLCB1c2luZyB0aGUgc3BlY2lmaWVkCisgICAgICoge0Bjb2RlIGJ5dGV9LgorICAgICAqCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIHRvIHVwZGF0ZSB3aXRoLgorICAgICAqIEB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgU2lnbmF0dXJlfSBpbnN0YW5jZSBpcyBub3QgaW5pdGlhbGl6ZWQKKyAgICAgKiAgICAgICAgICAgICBwcm9wZXJseS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB1cGRhdGUoYnl0ZSBiKSB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHN0YXRlID09IFVOSU5JVElBTElaRUQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTaWduYXR1cmVFeGNlcHRpb24oIlNpZ25hdHVyZSBvYmplY3QgaXMgbm90IGluaXRpYWxpemVkIHByb3Blcmx5Iik7CisgICAgICAgIH0KKyAgICAgICAgZW5naW5lVXBkYXRlKGIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhlIGRhdGEgdG8gYmUgdmVyaWZpZWQgb3IgdG8gYmUgc2lnbmVkLCB1c2luZyB0aGUgc3BlY2lmaWVkCisgICAgICoge0Bjb2RlIGJ5dGVbXX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgYXJyYXkgdG8gdXBkYXRlIHdpdGguCisgICAgICogQHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBTaWduYXR1cmV9IGluc3RhbmNlIGlzIG5vdCBpbml0aWFsaXplZAorICAgICAqICAgICAgICAgICAgIHByb3Blcmx5LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHVwZGF0ZShieXRlW10gZGF0YSkgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzdGF0ZSA9PSBVTklOSVRJQUxJWkVEKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU2lnbmF0dXJlRXhjZXB0aW9uKCJTaWduYXR1cmUgb2JqZWN0IGlzIG5vdCBpbml0aWFsaXplZCBwcm9wZXJseSIpOworICAgICAgICB9CisgICAgICAgIGVuZ2luZVVwZGF0ZShkYXRhLCAwLCBkYXRhLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgZGF0YSB0byBiZSB2ZXJpZmllZCBvciB0byBiZSBzaWduZWQsIHVzaW5nIHRoZSBnaXZlbiB7QGNvZGUKKyAgICAgKiBieXRlW119LCBzdGFydGluZyBmb3JtIHRoZSBzcGVjaWZpZWQgaW5kZXggZm9yIHRoZSBzcGVjaWZpZWQgbGVuZ3RoLgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGFycmF5IHRvIHVwZGF0ZSB3aXRoLgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBpbmRleCBpbiB7QGNvZGUgZGF0YX0gb2YgdGhlIGRhdGEuCisgICAgICogQHBhcmFtIGxlbgorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyB0byB1c2UuCisgICAgICogQHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBTaWduYXR1cmV9IGluc3RhbmNlIGlzIG5vdCBpbml0aWFsaXplZAorICAgICAqICAgICAgICAgICAgIHByb3Blcmx5LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHVwZGF0ZShieXRlW10gZGF0YSwgaW50IG9mZiwgaW50IGxlbikKKyAgICAgICAgICAgIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICBpZiAoc3RhdGUgPT0gVU5JTklUSUFMSVpFRCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNpZ25hdHVyZUV4Y2VwdGlvbigiU2lnbmF0dXJlIG9iamVjdCBpcyBub3QgaW5pdGlhbGl6ZWQgcHJvcGVybHkiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZGF0YSA9PSBudWxsIHx8IG9mZiA8IDAgfHwgbGVuIDwgMCB8fAorICAgICAgICAgICAgICAgIG9mZiArIGxlbiA+IGRhdGEubGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgZW5naW5lVXBkYXRlKGRhdGEsIG9mZiwgbGVuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoZSBkYXRhIHRvIGJlIHZlcmlmaWVkIG9yIHRvIGJlIHNpZ25lZCwgdXNpbmcgdGhlIHNwZWNpZmllZAorICAgICAqIHtAY29kZSBCeXRlQnVmZmVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIEJ5dGVCdWZmZXJ9IHRvIHVwZGF0ZSB3aXRoLgorICAgICAqIEB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgU2lnbmF0dXJlfSBpbnN0YW5jZSBpcyBub3QgaW5pdGlhbGl6ZWQKKyAgICAgKiAgICAgICAgICAgICBwcm9wZXJseS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB1cGRhdGUoQnl0ZUJ1ZmZlciBkYXRhKSB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHN0YXRlID09IFVOSU5JVElBTElaRUQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTaWduYXR1cmVFeGNlcHRpb24oIlNpZ25hdHVyZSBvYmplY3QgaXMgbm90IGluaXRpYWxpemVkIHByb3Blcmx5Iik7CisgICAgICAgIH0KKyAgICAgICAgZW5naW5lVXBkYXRlKGRhdGEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIGNvbmNpc2UsIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIG9mIHRoaXMKKyAgICAgKiB7QGNvZGUgU2lnbmF0dXJlfSBpbmNsdWRpbmcgaXRzIGFsZ29yaXRobSBhbmQgaXRzIHN0YXRlLgorICAgICAqCisgICAgICogQHJldHVybiBhIHByaW50YWJsZSByZXByZXNlbnRhdGlvbiBmb3IgdGhpcyB7QGNvZGUgU2lnbmF0dXJlfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gIlNJR05BVFVSRSAiICsgYWxnb3JpdGhtICsgIiBzdGF0ZTogIiArIHN0YXRlVG9TdHJpbmcoc3RhdGUpOworICAgIH0KKworICAgIC8vIENvbnZlcnQgc3RhdGUgdG8gc3RyaW5nCisgICAgcHJpdmF0ZSBTdHJpbmcgc3RhdGVUb1N0cmluZyhpbnQgc3RhdGUpIHsKKyAgICAgICAgc3dpdGNoIChzdGF0ZSkgeworICAgICAgICBjYXNlIFVOSU5JVElBTElaRUQ6CisgICAgICAgICAgICByZXR1cm4gIlVOSU5JVElBTElaRUQiOworICAgICAgICBjYXNlIFNJR046CisgICAgICAgICAgICByZXR1cm4gIlNJR04iOworICAgICAgICBjYXNlIFZFUklGWToKKyAgICAgICAgICAgIHJldHVybiAiVkVSSUZZIjsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gdGhlIGdpdmVuIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciB2YWx1ZS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFyYW1ldGVyIGlzIGludmFsaWQsIGFscmVhZHkgc2V0IG9yIGlzIG5vdCBhbGxvd2VkIHRvCisgICAgICogICAgICAgICAgICAgYmUgY2hhbmdlZC4KKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNzZXRQYXJhbWV0ZXIoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyl9CisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRQYXJhbWV0ZXIoU3RyaW5nIHBhcmFtLCBPYmplY3QgdmFsdWUpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIGVuZ2luZVNldFBhcmFtZXRlcihwYXJhbSwgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHNwZWNpZmllZCB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyU3BlY30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1zCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIHRvIHNldC4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFyYW1ldGVyIGlzIGludmFsaWQsIGFscmVhZHkgc2V0IG9yIGlzIG5vdCBhbGxvd2VkIHRvCisgICAgICogICAgICAgICAgICAgYmUgY2hhbmdlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRQYXJhbWV0ZXIoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIGVuZ2luZVNldFBhcmFtZXRlcihwYXJhbXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJzfSBvZiB0aGlzIHtAbGluayBTaWduYXR1cmV9CisgICAgICogaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30gb2YgdGhpcyB7QGxpbmsgU2lnbmF0dXJlfQorICAgICAqICAgICAgICAgaW5zdGFuY2UsIG1heWJlIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQWxnb3JpdGhtUGFyYW1ldGVycyBnZXRQYXJhbWV0ZXJzKCkgeworICAgICAgICByZXR1cm4gZW5naW5lR2V0UGFyYW1ldGVycygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXF1ZXN0ZWQgcGFyYW1ldGVyIHZhbHVlCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlciB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSwgbWF5YmUge0Bjb2RlCisgICAgICogICAgICAgICBudWxsfS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcGFyYW19IGlzIG5vdCBhIHZhbGlkIHBhcmFtZXRlciBmb3IgdGhpcyB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBTaWduYXR1cmV9IG9yIGFuIG90aGVyIGVycm9yIG9jY3VyZXMuCisgICAgICogQGRlcHJlY2F0ZWQgVGhlcmUgaXMgbm8gZ2VuZXJhbGx5IGFjY2VwdGVkIHBhcmFtZXRlciBuYW1pbmcgY29udmVudGlvbi4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBmaW5hbCBPYmplY3QgZ2V0UGFyYW1ldGVyKFN0cmluZyBwYXJhbSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGVuZ2luZUdldFBhcmFtZXRlcihwYXJhbSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgQ2xvbmVhYmxlKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKgorICAgICAqIEludGVybmFsIFNpZ25hdHVyZSBpbXBsZW1lbnRhdGlvbgorICAgICAqCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgU2lnbmF0dXJlSW1wbCBleHRlbmRzIFNpZ25hdHVyZSB7CisKKyAgICAgICAgcHJpdmF0ZSBTaWduYXR1cmVTcGkgc3BpSW1wbDsKKworICAgICAgICAvLyBDb25zdHJ1Y3RvcgorICAgICAgICBwdWJsaWMgU2lnbmF0dXJlSW1wbChTaWduYXR1cmVTcGkgc2lnbmF0dXJlU3BpLCBQcm92aWRlciBwcm92aWRlciwKKyAgICAgICAgICAgICAgICBTdHJpbmcgYWxnb3JpdGhtKSB7CisgICAgICAgICAgICBzdXBlcihhbGdvcml0aG0pOworICAgICAgICAgICAgc3VwZXIucHJvdmlkZXIgPSBwcm92aWRlcjsKKyAgICAgICAgICAgIHNwaUltcGwgPSBzaWduYXR1cmVTcGk7CisgICAgICAgIH0KKworICAgICAgICAvLyBlbmdpbmVTaWduKCkgaW1wbGVtZW50YXRpb24KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBieXRlW10gZW5naW5lU2lnbigpIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lU2lnbigpOworICAgICAgICB9CisKKyAgICAgICAgLy8gIGVuZ2luZVVwZGF0ZSgpIGltcGxlbWVudGF0aW9uCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZSBhcmcwKSB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHNwaUltcGwuZW5naW5lVXBkYXRlKGFyZzApOworICAgICAgICB9CisKKyAgICAgICAgLy8gZW5naW5lVmVyaWZ5KCkgaW1wbGVtZW50YXRpb24KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBib29sZWFuIGVuZ2luZVZlcmlmeShieXRlW10gYXJnMCkgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVWZXJpZnkoYXJnMCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBlbmdpbmVVcGRhdGUoKSBpbXBsZW1lbnRhdGlvbgorICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGVbXSBhcmcwLCBpbnQgYXJnMSwgaW50IGFyZzIpCisgICAgICAgICAgICAgICAgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzcGlJbXBsLmVuZ2luZVVwZGF0ZShhcmcwLCBhcmcxLCBhcmcyKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGVuZ2luZUluaXRTaWduKCkgaW1wbGVtZW50YXRpb24KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXRTaWduKFByaXZhdGVLZXkgYXJnMCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzcGlJbXBsLmVuZ2luZUluaXRTaWduKGFyZzApOworICAgICAgICB9CisKKyAgICAgICAgLy8gZW5naW5lSW5pdFZlcmlmeSgpIGltcGxlbWVudGF0aW9uCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0VmVyaWZ5KFB1YmxpY0tleSBhcmcwKQorICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHNwaUltcGwuZW5naW5lSW5pdFZlcmlmeShhcmcwKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGVuZ2luZUdldFBhcmFtZXRlcigpIGltcGxlbWVudGF0aW9uCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgT2JqZWN0IGVuZ2luZUdldFBhcmFtZXRlcihTdHJpbmcgYXJnMCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVHZXRQYXJhbWV0ZXIoYXJnMCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBlbmdpbmVTZXRQYXJhbWV0ZXIoKSBpbXBsZW1lbnRhdGlvbgorICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lU2V0UGFyYW1ldGVyKFN0cmluZyBhcmcwLCBPYmplY3QgYXJnMSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzcGlJbXBsLmVuZ2luZVNldFBhcmFtZXRlcihhcmcwLCBhcmcxKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFJldHVybnMgYSBjbG9uZSBpZiB0aGUgc3BpSW1wbCBpcyBjbG9uZWFibGUKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKHNwaUltcGwgaW5zdGFuY2VvZiBDbG9uZWFibGUpIHsKKyAgICAgICAgICAgICAgICBTaWduYXR1cmVTcGkgc3BpID0gKFNpZ25hdHVyZVNwaSkgc3BpSW1wbC5jbG9uZSgpOworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2lnbmF0dXJlSW1wbChzcGksIGdldFByb3ZpZGVyKCksIGdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2lnbmF0dXJlRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9TaWduYXR1cmVFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNmU5MzRmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2lnbmF0dXJlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw2OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCisvKioKKyAqe0Bjb2RlIFNpZ25hdHVyZUV4Y2VwdGlvbn0gaXMgYSBnZW5lcmFsIHtAY29kZSBTaWduYXR1cmV9IGV4Y2VwdGlvbi4KKyAqCisgKiBAc2VlIFNpZ25hdHVyZQorICovCitwdWJsaWMgY2xhc3MgU2lnbmF0dXJlRXhjZXB0aW9uIGV4dGVuZHMgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDc1MDk5ODkzMjQ5NzUxMjQ0MzhMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgU2lnbmF0dXJlRXhjZXB0aW9ufSB3aXRoIHRoZQorICAgICAqIGdpdmVuIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBTaWduYXR1cmVFeGNlcHRpb24oU3RyaW5nIG1zZykgeworICAgICAgICBzdXBlcihtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFNpZ25hdHVyZUV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIFNpZ25hdHVyZUV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBTaWduYXR1cmVFeGNlcHRpb259IHdpdGggdGhlCisgICAgICogZ2l2ZW4gbWVzc2FnZSBhbmQgdGhlIGNhdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24KKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNlcHRpb24gd2hpY2ggaXMgdGhlIGNhdXNlIGZvciB0aGlzIGV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTaWduYXR1cmVFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgU2lnbmF0dXJlRXhjZXB0aW9ufSB3aXRoIHRoZQorICAgICAqIGNhdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgZXhjZXB0aW9uIHdoaWNoIGlzIHRoZSBjYXVzZSBmb3IgdGhpcyBleGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU2lnbmF0dXJlRXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2lnbmF0dXJlU3BpLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9TaWduYXR1cmVTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yN2JlMzBjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2lnbmF0dXJlU3BpLmphdmEKQEAgLTAsMCArMSwzMTUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CisKKy8qKgorICoge0Bjb2RlIFNpZ25hdHVyZVNwaX0gaXMgdGhlIDxpPlNlcnZpY2UgUHJvdmlkZXIgSW50ZXJmYWNlPC9pPiAoPGI+U1BJPC9iPikKKyAqIGRlZmluaXRpb24gZm9yIHtAbGluayBTaWduYXR1cmV9LgorICoKKyAqIEBzZWUgU2lnbmF0dXJlCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTaWduYXR1cmVTcGkgeworCisgICAgLyoqCisgICAgICogSW1wbGVtZW50YXRpb24gc3BlY2lmaWMgc291cmNlIG9mIHJhbmRvbW5lc3MuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNlY3VyZVJhbmRvbSBhcHBSYW5kb207CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBTaWduYXR1cmVTcGl9IGluc3RhbmNlIGZvciBzaWduYXR1cmUKKyAgICAgKiB2ZXJpZmljYXRpb24sIHVzaW5nIHRoZSBwdWJsaWMga2V5IG9mIHRoZSBpZGVudGl0eSB3aG9zZSBzaWduYXR1cmUgaXMKKyAgICAgKiBnb2luZyB0byBiZSB2ZXJpZmllZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwdWJsaWNLZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBwdWJsaWMga2V5LgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBwdWJsaWNLZXl9IGlzIG5vdCB2YWxpZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBlbmdpbmVJbml0VmVyaWZ5KFB1YmxpY0tleSBwdWJsaWNLZXkpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIFNpZ25hdHVyZVNwaX0gaW5zdGFuY2UgZm9yIHNpZ25pbmcsIHVzaW5nIHRoZQorICAgICAqIHByaXZhdGUga2V5IG9mIHRoZSBpZGVudGl0eSB3aG9zZSBzaWduYXR1cmUgaXMgZ29pbmcgdG8gYmUgZ2VuZXJhdGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHByaXZhdGVLZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcml2YXRlIGtleS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcHJpdmF0ZUtleX0gaXMgbm90IHZhbGlkLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGVuZ2luZUluaXRTaWduKFByaXZhdGVLZXkgcHJpdmF0ZUtleSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyB7QGNvZGUgU2lnbmF0dXJlU3BpfSBpbnN0YW5jZSBmb3Igc2lnbmluZywgdXNpbmcgdGhlCisgICAgICogcHJpdmF0ZSBrZXkgb2YgdGhlIGlkZW50aXR5IHdob3NlIHNpZ25hdHVyZSBpcyBnb2luZyB0byBiZSBnZW5lcmF0ZWQgYW5kCisgICAgICogdGhlIHNwZWNpZmllZCBzb3VyY2Ugb2YgcmFuZG9tbmVzcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcml2YXRlS2V5CisgICAgICogICAgICAgICAgICB0aGUgcHJpdmF0ZSBrZXkuCisgICAgICogQHBhcmFtIHJhbmRvbQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBTZWN1cmVSYW5kb219IHRvIHVzZS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcHJpdmF0ZUtleX0gaXMgbm90IHZhbGlkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXRTaWduKFByaXZhdGVLZXkgcHJpdmF0ZUtleSwgU2VjdXJlUmFuZG9tIHJhbmRvbSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgYXBwUmFuZG9tID0gcmFuZG9tOworICAgICAgICBlbmdpbmVJbml0U2lnbihwcml2YXRlS2V5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoZSBkYXRhIHRvIGJlIHZlcmlmaWVkIG9yIHRvIGJlIHNpZ25lZCwgdXNpbmcgdGhlIHNwZWNpZmllZAorICAgICAqIHtAY29kZSBieXRlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSB0byB1cGRhdGUgd2l0aC4KKyAgICAgKiBAdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIFNpZ25hdHVyZVNwaX0gaW5zdGFuY2UgaXMgbm90IGluaXRpYWxpemVkCisgICAgICogICAgICAgICAgICAgcHJvcGVybHkuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgZW5naW5lVXBkYXRlKGJ5dGUgYikgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhlIGRhdGEgdG8gYmUgdmVyaWZpZWQgb3IgdG8gYmUgc2lnbmVkLCB1c2luZyB0aGUgZ2l2ZW4ge0Bjb2RlCisgICAgICogYnl0ZVtdfSwgc3RhcnRpbmcgZm9ybSB0aGUgc3BlY2lmaWVkIGluZGV4IGZvciB0aGUgc3BlY2lmaWVkIGxlbmd0aC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBiCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSBhcnJheSB0byB1cGRhdGUgd2l0aC4KKyAgICAgKiBAcGFyYW0gb2ZmCisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgaW5kZXggaW4ge0Bjb2RlIGJ9IG9mIHRoZSBkYXRhLgorICAgICAqIEBwYXJhbSBsZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gdXNlLgorICAgICAqIEB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgU2lnbmF0dXJlU3BpfSBpbnN0YW5jZSBpcyBub3QgaW5pdGlhbGl6ZWQKKyAgICAgKiAgICAgICAgICAgICBwcm9wZXJseS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pCisgICAgICAgICAgICB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgZGF0YSB0byBiZSB2ZXJpZmllZCBvciB0byBiZSBzaWduZWQsIHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB7QGNvZGUgQnl0ZUJ1ZmZlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQnl0ZUJ1ZmZlcn0gdG8gdXBkYXRlIHdpdGguCisgICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgc2luY2Uge0Bjb2RlIFNpZ25hdHVyZUV4Y2VwdGlvbn0gaXMgbm90IHNwZWNpZmllZCBmb3IgdGhpcworICAgICAqICAgICAgICAgICAgIG1ldGhvZCBpdCB0aHJvd3MgYSB7QGNvZGUgUnVudGltZUV4Y2VwdGlvbn0gaWYgdW5kZXJseWluZworICAgICAqICAgICAgICAgICAgIHtAbGluayAjZW5naW5lVXBkYXRlKGJ5dGVbXSwgaW50LCBpbnQpfSB0aHJvd3Mge0Bjb2RlCisgICAgICogICAgICAgICAgICAgU2lnbmF0dXJlRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVVcGRhdGUoQnl0ZUJ1ZmZlciBpbnB1dCkgeworICAgICAgICBpZiAoIWlucHV0Lmhhc1JlbWFpbmluZygpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIHRtcDsKKyAgICAgICAgaWYgKGlucHV0Lmhhc0FycmF5KCkpIHsKKyAgICAgICAgICAgIHRtcCA9IGlucHV0LmFycmF5KCk7CisgICAgICAgICAgICBpbnQgb2Zmc2V0ID0gaW5wdXQuYXJyYXlPZmZzZXQoKTsKKyAgICAgICAgICAgIGludCBwb3NpdGlvbiA9IGlucHV0LnBvc2l0aW9uKCk7CisgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5saW1pdCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBlbmdpbmVVcGRhdGUodG1wLCBvZmZzZXQgKyBwb3NpdGlvbiwgbGltaXQgLSBwb3NpdGlvbik7CisgICAgICAgICAgICB9IGNhdGNoIChTaWduYXR1cmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOyAvL1dyYXAgU2lnbmF0dXJlRXhjZXB0aW9uCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnB1dC5wb3NpdGlvbihsaW1pdCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0bXAgPSBuZXcgYnl0ZVtpbnB1dC5saW1pdCgpIC0gaW5wdXQucG9zaXRpb24oKV07CisgICAgICAgICAgICBpbnB1dC5nZXQodG1wKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZW5naW5lVXBkYXRlKHRtcCwgMCwgdG1wLmxlbmd0aCk7CisgICAgICAgICAgICB9IGNhdGNoIChTaWduYXR1cmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOyAvL1dyYXAgU2lnbmF0dXJlRXhjZXB0aW9uCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgYW5kIHJldHVybnMgdGhlIHNpZ25hdHVyZSBvZiBhbGwgdXBkYXRlZCBkYXRhLgorICAgICAqIDxwPgorICAgICAqIFRoaXMge0Bjb2RlIFNpZ25hdHVyZVNwaX0gaW5zdGFuY2UgaXMgcmVzZXQgdG8gdGhlIHN0YXRlIG9mIGl0cyBsYXN0CisgICAgICogaW5pdGlhbGl6YXRpb24gZm9yIHNpZ25pbmcgYW5kIHRodXMgY2FuIGJlIHVzZWQgZm9yIGFub3RoZXIgc2lnbmF0dXJlCisgICAgICogZnJvbSB0aGUgc2FtZSBpZGVudGl0eS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNpZ25hdHVyZSBvZiBhbGwgdXBkYXRlZCBkYXRhLgorICAgICAqIEB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgU2lnbmF0dXJlU3BpfSBpbnN0YW5jZSBpcyBub3QgaW5pdGlhbGl6ZWQKKyAgICAgKiAgICAgICAgICAgICBwcm9wZXJseS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgYnl0ZVtdIGVuZ2luZVNpZ24oKSB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGFuZCBzdG9yZXMgdGhlIHNpZ25hdHVyZSBvZiBhbGwgdXBkYXRlZCBkYXRhIGluIHRoZSBwcm92aWRlZAorICAgICAqIHtAY29kZSBieXRlW119IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGxlbmd0aC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIHtAY29kZSBTaWduYXR1cmVTcGl9IGluc3RhbmNlIGlzIHJlc2V0IHRvIHRoZSBzdGF0ZSBvZiBpdHMgbGFzdAorICAgICAqIGluaXRpYWxpemF0aW9uIGZvciBzaWduaW5nIGFuZCB0aHVzIGNhbiBiZSB1c2VkIGZvciBhbm90aGVyIHNpZ25hdHVyZQorICAgICAqIGZyb20gdGhlIHNhbWUgaWRlbnRpdHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0YnVmCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHRvIHN0b3JlIHRoZSBzaWduYXR1cmUuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBieXRlIGluIHtAY29kZSBvdXRidWZ9IHRvIHN0b3JlLgorICAgICAqIEBwYXJhbSBsZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWxsb2NhdGVkIGZvciB0aGUgc2lnbmF0dXJlLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBzdG9yZWQgaW4ge0Bjb2RlIG91dGJ1Zn0uCisgICAgICogQHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBTaWduYXR1cmVTcGl9IGluc3RhbmNlIGlzIG5vdCBpbml0aWFsaXplZAorICAgICAqICAgICAgICAgICAgIHByb3Blcmx5LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldH0gb3Ige0Bjb2RlIGxlbn0gYXJlIG5vdCB2YWxpZCBpbiByZXNwZWN0IHRvCisgICAgICogICAgICAgICAgICAge0Bjb2RlIG91dGJ1Zn0uCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBlbmdpbmVTaWduKGJ5dGVbXSBvdXRidWYsIGludCBvZmZzZXQsIGludCBsZW4pIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICBieXRlW10gdG1wID0gZW5naW5lU2lnbigpOworICAgICAgICBpZiAodG1wID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGlmIChsZW4gPCB0bXAubGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU2lnbmF0dXJlRXhjZXB0aW9uKCJUaGUgdmFsdWUgb2YgbGVuIHBhcmFtZXRlciBpcyBsZXNzIHRoYW4gdGhlIGFjdHVhbCBzaWduYXR1cmUgbGVuZ3RoIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9mZnNldCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTaWduYXR1cmVFeGNlcHRpb24oIm9mZnNldCA8IDAiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2Zmc2V0ICsgbGVuID4gb3V0YnVmLmxlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNpZ25hdHVyZUV4Y2VwdGlvbigib2Zmc2V0ICsgbGVuID4gb3V0YnVmLmxlbmd0aCIpOworICAgICAgICB9CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodG1wLCAwLCBvdXRidWYsIG9mZnNldCwgdG1wLmxlbmd0aCk7CisgICAgICAgIHJldHVybiB0bXAubGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBnaXZlbiB7QGNvZGUgc2lnQnl0ZXN9IGNhbiBiZSB2ZXJpZmllZCB1c2luZyB0aGUKKyAgICAgKiBwdWJsaWMga2V5IG9yIGEgY2VydGlmaWNhdGUgb2YgdGhlIHNpZ25lci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIHtAY29kZSBTaWduYXR1cmVTcGl9IGluc3RhbmNlIGlzIHJlc2V0IHRvIHRoZSBzdGF0ZSBvZiBpdHMgbGFzdAorICAgICAqIGluaXRpYWxpemF0aW9uIGZvciB2ZXJpZnlpbmcgYW5kIHRodXMgY2FuIGJlIHVzZWQgdG8gdmVyaWZ5IGFub3RoZXIKKyAgICAgKiBzaWduYXR1cmUgb2YgdGhlIHNhbWUgc2lnbmVyLgorICAgICAqCisgICAgICogQHBhcmFtIHNpZ0J5dGVzCisgICAgICogICAgICAgICAgICB0aGUgc2lnbmF0dXJlIHRvIHZlcmlmeS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc2lnbmF0dXJlIHdhcyB2ZXJpZmllZCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgU2lnbmF0dXJlU3BpfSBpbnN0YW5jZSBpcyBub3QgaW5pdGlhbGl6ZWQKKyAgICAgKiAgICAgICAgICAgICBwcm9wZXJseS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgYm9vbGVhbiBlbmdpbmVWZXJpZnkoYnl0ZVtdIHNpZ0J5dGVzKQorICAgICAgICAgICAgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBnaXZlbiB7QGNvZGUgc2lnQnl0ZXN9IHN0YXJ0aW5nIGF0IGluZGV4IHtAY29kZQorICAgICAqIG9mZnNldH0gd2l0aCB7QGNvZGUgbGVuZ3RofSBieXRlcyBjYW4gYmUgdmVyaWZpZWQgdXNpbmcgdGhlIHB1YmxpYyBrZXkgb3IKKyAgICAgKiBhIGNlcnRpZmljYXRlIG9mIHRoZSBzaWduZXIuCisgICAgICogPHA+CisgICAgICogVGhpcyB7QGNvZGUgU2lnbmF0dXJlU3BpfSBpbnN0YW5jZSBpcyByZXNldCB0byB0aGUgc3RhdGUgb2YgaXRzIGxhc3QKKyAgICAgKiBpbml0aWFsaXphdGlvbiBmb3IgdmVyaWZ5aW5nIGFuZCB0aHVzIGNhbiBiZSB1c2VkIHRvIHZlcmlmeSBhbm90aGVyCisgICAgICogc2lnbmF0dXJlIG9mIHRoZSBzYW1lIHNpZ25lci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaWdCeXRlcworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBieXRlW119IGNvbnRhaW5pbmcgdGhlIHNpZ25hdHVyZSB0byB2ZXJpZnkuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IGluZGV4IGluIHtAY29kZSBzaWdCeXRlc30gb2YgdGhlIHNpZ25hdHVyZQorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWxsb2NhdGVkIGZvciB0aGUgc2lnbmF0dXJlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzaWduYXR1cmUgd2FzIHZlcmlmaWVkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBTaWduYXR1cmVTcGl9IGluc3RhbmNlIGlzIG5vdCBpbml0aWFsaXplZAorICAgICAqICAgICAgICAgICAgIHByb3Blcmx5LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9mZnNldH0gb3Ige0Bjb2RlIGxlbmd0aH0gYXJlIG5vdCB2YWxpZCBpbiByZXNwZWN0CisgICAgICogICAgICAgICAgICAgdG8ge0Bjb2RlIHNpZ0J5dGVzfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBlbmdpbmVWZXJpZnkoYnl0ZVtdIHNpZ0J5dGVzLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSB0bXAgPSBuZXcgYnl0ZVtsZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHNpZ0J5dGVzLCBvZmZzZXQsIHRtcCwgMCwgbGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIGVuZ2luZVZlcmlmeSh0bXApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gdGhlIGdpdmVuIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciB2YWx1ZS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFyYW1ldGVyIGlzIGludmFsaWQsIGFscmVhZHkgc2V0IG9yIGlzIG5vdCBhbGxvd2VkIHRvCisgICAgICogICAgICAgICAgICAgYmUgY2hhbmdlZC4KKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNlbmdpbmVTZXRQYXJhbWV0ZXIoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyl9CisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBlbmdpbmVTZXRQYXJhbWV0ZXIoU3RyaW5nIHBhcmFtLCBPYmplY3QgdmFsdWUpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHNwZWNpZmllZCB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyU3BlY30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1zCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIHRvIHNldC4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFyYW1ldGVyIGlzIGludmFsaWQsIGFscmVhZHkgc2V0IG9yIGlzIG5vdCBhbGxvd2VkIHRvCisgICAgICogICAgICAgICAgICAgYmUgY2hhbmdlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVTZXRQYXJhbWV0ZXIoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBBbGdvcml0aG1QYXJhbWV0ZXJzfSBvZiB0aGlzIHtAbGluayBTaWduYXR1cmVTcGl9CisgICAgICogaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgQWxnb3JpdGhtUGFyYW1ldGVyc30gb2YgdGhpcyB7QGxpbmsgU2lnbmF0dXJlU3BpfQorICAgICAqICAgICAgICAgaW5zdGFuY2UsIG1heWJlIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQWxnb3JpdGhtUGFyYW1ldGVycyBlbmdpbmVHZXRQYXJhbWV0ZXJzKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcmVxdWVzdGVkIHBhcmFtZXRlciB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLCBtYXliZSB7QGNvZGUKKyAgICAgKiAgICAgICAgIG51bGx9LgorICAgICAqIEB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBwYXJhbX0gaXMgbm90IGEgdmFsaWQgcGFyYW1ldGVyIGZvciB0aGlzIHtAY29kZQorICAgICAqICAgICAgICAgICAgIFNpZ25hdHVyZVNwaX0gb3IgYW4gb3RoZXIgZXJyb3Igb2NjdXJzLgorICAgICAqIEBkZXByZWNhdGVkIFRoZXJlIGlzIG5vIGdlbmVyYWxseSBhY2NlcHRlZCBwYXJhbWV0ZXIgbmFtaW5nIGNvbnZlbnRpb24uCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgT2JqZWN0IGVuZ2luZUdldFBhcmFtZXRlcihTdHJpbmcgcGFyYW0pCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbjsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIENsb25lYWJsZSkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2lnbmVkT2JqZWN0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9TaWduZWRPYmplY3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NTg2N2Y0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2lnbmVkT2JqZWN0LmphdmEKQEAgLTAsMCArMSwxNTcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCisvKioKKyAqIEEge0Bjb2RlIFNpZ25lZE9iamVjdH0gaW5zdGFuY2UgYWN0cyBhcyBhIGNvbnRhaW5lciBmb3IgYW5vdGhlciBvYmplY3QuIFRoZQorICoge0Bjb2RlIFNpZ25lZE9iamVjdH0gY29udGFpbnMgdGhlIHRhcmdldCBpbiBzZXJpYWxpemVkIGZvcm0gYWxvbmcgd2l0aCBhCisgKiBkaWdpdGFsIHNpZ25hdHVyZSBvZiB0aGUgc2VyaWFsaXplZCBkYXRhLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU2lnbmVkT2JqZWN0IGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDcyMDUwMjcyMDQ4NTQ0NzE2N0w7CisKKyAgICBwcml2YXRlIGJ5dGVbXSBjb250ZW50OworCisgICAgcHJpdmF0ZSBieXRlW10gc2lnbmF0dXJlOworCisgICAgcHJpdmF0ZSBTdHJpbmcgdGhlYWxnb3JpdGhtOworCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gcykgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisKKyAgICAgICAgcy5kZWZhdWx0UmVhZE9iamVjdCgpOworICAgICAgICBieXRlW10gdG1wID0gbmV3IGJ5dGVbY29udGVudC5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNvbnRlbnQsIDAsIHRtcCwgMCwgY29udGVudC5sZW5ndGgpOworICAgICAgICBjb250ZW50ID0gdG1wOworICAgICAgICB0bXAgPSBuZXcgYnl0ZVtzaWduYXR1cmUubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzaWduYXR1cmUsIDAsIHRtcCwgMCwgc2lnbmF0dXJlLmxlbmd0aCk7CisgICAgICAgIHNpZ25hdHVyZSA9IHRtcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBTaWduZWRPYmplY3R9IHdpdGggdGhlIHRhcmdldCBvYmplY3QsCisgICAgICogdGhlIHByaXZhdGUga2V5IGFuZCB0aGUgZW5naW5lIHRvIGNvbXB1dGUgdGhlIHNpZ25hdHVyZS4gVGhlIGdpdmVuCisgICAgICoge0Bjb2RlIG9iamVjdH0gaXMgc2lnbmVkIHdpdGggdGhlIHNwZWNpZmllZCBrZXkgYW5kIGVuZ2luZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYmVzIHNpZ25lZC4KKyAgICAgKiBAcGFyYW0gc2lnbmluZ0tleQorICAgICAqICAgICAgICAgICAgdGhlIHByaXZhdGUga2V5LCB1c2VkIHRvIHNpZ24gdGhlIHtAY29kZSBvYmplY3R9LgorICAgICAqIEBwYXJhbSBzaWduaW5nRW5naW5lCisgICAgICogICAgICAgICAgICB0aGUgZW5naW5lIHRoYXQgcGVyZm9ybXMgdGhlIHNpZ25hdHVyZSBnZW5lcmF0aW9uLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHNlcmlhbGl6YXRpb24gZXJyb3Igb2NjdXJzLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwcml2YXRlIGtleSBpcyBub3QgdmFsaWQuCisgICAgICogQHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBzaWduYXR1cmUgZ2VuZXJhdGlvbiBmYWlsZWQuCisgICAgICovCisgICAgcHVibGljIFNpZ25lZE9iamVjdChTZXJpYWxpemFibGUgb2JqZWN0LCBQcml2YXRlS2V5IHNpZ25pbmdLZXksCisgICAgICAgICAgICBTaWduYXR1cmUgc2lnbmluZ0VuZ2luZSkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnZhbGlkS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtIG9vcyA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0oYmFvcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBTZXJpYWxpemUKKyAgICAgICAgICAgIG9vcy53cml0ZU9iamVjdChvYmplY3QpOworICAgICAgICAgICAgb29zLmZsdXNoKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBvb3MuY2xvc2UoKTsKKyAgICAgICAgfQorICAgICAgICBjb250ZW50ID0gYmFvcy50b0J5dGVBcnJheSgpOworICAgICAgICBzaWduaW5nRW5naW5lLmluaXRTaWduKHNpZ25pbmdLZXkpOworICAgICAgICB0aGVhbGdvcml0aG0gPSBzaWduaW5nRW5naW5lLmdldEFsZ29yaXRobSgpOworICAgICAgICBzaWduaW5nRW5naW5lLnVwZGF0ZShjb250ZW50KTsKKyAgICAgICAgc2lnbmF0dXJlID0gc2lnbmluZ0VuZ2luZS5zaWduKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5jYXBzdWxhdGVkIG9iamVjdC4gRWFjaCB0aW1lIHRoaXMgbWV0aG9kIGlzIGludm9rZWQsIHRoZQorICAgICAqIGVuY2Fwc3VsYXRlZCBvYmplY3QgaXMgZGVzZXJpYWxpemVkIGJlZm9yZSBpdCBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVuY2Fwc3VsYXRlZCBvYmplY3QuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGRlc2VyaWFsaXphdGlvbiBmYWlsZWQuCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIHRoZSBlbmNhcHN1bGF0ZWQgb2JqZWN0IGNhbiBub3QgYmUgZm91bmQuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRPYmplY3QoKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICAvLyBkZXNlcmlhbGl6ZSBvdXIgb2JqZWN0CisgICAgICAgIE9iamVjdElucHV0U3RyZWFtIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgY29udGVudCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIG9pcy5yZWFkT2JqZWN0KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNpZ25hdHVyZSBkYXRhIG9mIHRoZSBlbmNhcHN1bGF0ZWQgc2VyaWFsaXplZCBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzaWduYXR1cmUgZGF0YSBvZiB0aGUgZW5jYXBzdWxhdGVkIHNlcmlhbGl6ZWQgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0U2lnbmF0dXJlKCkgeworICAgICAgICBieXRlW10gc2lnID0gbmV3IGJ5dGVbc2lnbmF0dXJlLmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2lnbmF0dXJlLCAwLCBzaWcsIDAsIHNpZ25hdHVyZS5sZW5ndGgpOworICAgICAgICByZXR1cm4gc2lnOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobSBvZiB0aGlzIHtAY29kZSBTaWduZWRPYmplY3R9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtIG9mIHRoaXMge0Bjb2RlIFNpZ25lZE9iamVjdH0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiB0aGVhbGdvcml0aG07CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGNvbnRhaW5lZCBzaWduYXR1cmUgZm9yIHRoZSBlbmNhcHN1bGF0ZWQgb2JqZWN0IGlzCisgICAgICogdmFsaWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmVyaWZpY2F0aW9uS2V5CisgICAgICogICAgICAgICAgICB0aGUgcHVibGljIGtleSB0byB2ZXJpZnkgdGhlIHNpZ25hdHVyZS4KKyAgICAgKiBAcGFyYW0gdmVyaWZpY2F0aW9uRW5naW5lCisgICAgICogICAgICAgICAgICB0aGUgc2lnbmF0dXJlIGVuZ2luZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgY29udGFpbmVkIHNpZ25hdHVyZSBmb3IgdGhlIGVuY2Fwc3VsYXRlZAorICAgICAqICAgICAgICAgb2JqZWN0IGlzIHZhbGlkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcHVibGljIGtleSBpcyBpbnZhbGlkLgorICAgICAqIEB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiBmYWlsZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gdmVyaWZ5KFB1YmxpY0tleSB2ZXJpZmljYXRpb25LZXksCisgICAgICAgICAgICBTaWduYXR1cmUgdmVyaWZpY2F0aW9uRW5naW5lKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisKKyAgICAgICAgdmVyaWZpY2F0aW9uRW5naW5lLmluaXRWZXJpZnkodmVyaWZpY2F0aW9uS2V5KTsKKyAgICAgICAgdmVyaWZpY2F0aW9uRW5naW5lLnVwZGF0ZShjb250ZW50KTsKKyAgICAgICAgcmV0dXJuIHZlcmlmaWNhdGlvbkVuZ2luZS52ZXJpZnkoc2lnbmF0dXJlKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1NpZ25lci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvU2lnbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWU0NDEyYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1NpZ25lci5qYXZhCkBAIC0wLDAgKzEsMTEwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKKy8qKgorICoge0BsaW5rIFNpZ25lcn0gcmVwcmVzZW50cyBhbiBpZGVudGl0eSAoaW5kaXZpZHVhbCBvciBjb3Jwb3JhdGlvbikgdGhhdCBvd25zIGEKKyAqIHByaXZhdGUga2V5IGFuZCB0aGUgY29ycmVzcG9uZGluZyBwdWJsaWMga2V5LgorICoKKyAqIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IGJlaGF2aW9yIGluIHtAbGluayBqYXZhLnNlY3VyaXR5LmNlcnQKKyAqICAgICAgICAgICAgIGphdmEuc2VjdXJpdHkuY2VydH0gcGFja2FnZSBhbmQge0BsaW5rIGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsCisgKiAgICAgICAgICAgICBQcmluY2lwYWx9CisgKi8KK0BEZXByZWNhdGVkCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU2lnbmVyIGV4dGVuZHMgSWRlbnRpdHkgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTE3NjM0NjQxMDIyNjEzNjE0ODBMOworCisgICAgcHJpdmF0ZSBQcml2YXRlS2V5IHByaXZhdGVLZXk7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBTaWduZXJ9LgorICAgICAqLworICAgIHByb3RlY3RlZCBTaWduZXIoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgU2lnbmVyfSB3aXRoIHRoZSBnaXZlbiBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBzaWduZXIuCisgICAgICovCisgICAgcHVibGljIFNpZ25lcihTdHJpbmcgbmFtZSkgeworICAgICAgICBzdXBlcihuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBTaWduZXJ9IHdpdGggdGhlIGdpdmVuIG5hbWUgaW4gdGhlCisgICAgICogZ2l2ZW4gc2NvcGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHNpZ25lci4KKyAgICAgKiBAcGFyYW0gc2NvcGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzY29wZSBvZiB0aGUgc2lnbmVyLgorICAgICAqIEB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgc2lnbmVyIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGFscmVhZHkgZXhpc3RzIGluIHRoZQorICAgICAqICAgICAgICAgICAgIHByb3ZpZGVkIHNjb3BlLgorICAgICAqLworICAgIHB1YmxpYyBTaWduZXIoU3RyaW5nIG5hbWUsIElkZW50aXR5U2NvcGUgc2NvcGUpIHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIobmFtZSwgc2NvcGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByaXZhdGUga2V5IG9mIHRoaXMge0Bjb2RlIFNpZ25lcn0uCisgICAgICovCisgICAgcHVibGljIFByaXZhdGVLZXkgZ2V0UHJpdmF0ZUtleSgpIHsKKyAgICAgICAgcmV0dXJuIHByaXZhdGVLZXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzb2NpYXRlcyB0aGUgc3BlY2lmaWVkIGtleSBwYWlyIHdpdGggdGhpcyB7QGNvZGUgU2lnbmVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYWlyCisgICAgICogICAgICAgICAgICB0aGUga2V5IHBhaXIgdG8gYXNzb2NpYXRlIHdpdGggdGhpcyB7QGNvZGUgU2lnbmVyfS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUga2V5IHBhaXIgaXMgaW52YWxpZC4KKyAgICAgKiBAdGhyb3dzIEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBvdGhlciBrZXkgcmVsYXRlZCBwcm9ibGVtIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRLZXlQYWlyKEtleVBhaXIgcGFpcikgdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24sIEtleUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwYWlyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHBhaXIuZ2V0UHJpdmF0ZSgpID09IG51bGwgfHwgcGFpci5nZXRQdWJsaWMoKSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHNldFB1YmxpY0tleShwYWlyLmdldFB1YmxpYygpKTsKKyAgICAgICAgdGhpcy5wcml2YXRlS2V5ID0gcGFpci5nZXRQcml2YXRlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhpcworICAgICAqIHtAY29kZSBTaWduZXJ9IGluY2x1ZGluZyBpdHMgbmFtZSBhbmQgaXRzIHNjb3BlIGlmIHByZXNlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcHJpbnRhYmxlIHJlcHJlc2VudGF0aW9uIGZvciB0aGlzIHtAY29kZSBTaWduZXJ9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZyBzID0gIltTaWduZXJdIiArIGdldE5hbWUoKTsKKyAgICAgICAgaWYgKGdldFNjb3BlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgcyA9IHMgKyAnWycgKyBnZXRTY29wZSgpLnRvU3RyaW5nKCkgKyAnXSc7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvVGltZXN0YW1wLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9UaW1lc3RhbXAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YmU0MjFkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvVGltZXN0YW1wLmphdmEKQEAgLTAsMCArMSwxMzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aDsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKKworLyoqCisgKiB7QGNvZGUgVGltZXN0YW1wfSByZXByZXNlbnRzIGEgc2lnbmVkIHRpbWUgc3RhbXAuIHtAY29kZSBUaW1lc3RhbXB9IGlzCisgKiBpbW11dGFibGUuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBUaW1lc3RhbXAgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTU1MDI2ODM3MDc4MjE4NTEyOTRMOworCisgICAgcHJpdmF0ZSBEYXRlIHRpbWVzdGFtcDsKKworICAgIHByaXZhdGUgQ2VydFBhdGggc2lnbmVyQ2VydFBhdGg7CisKKyAgICAvLyBDYWNoZWQgaGFzaAorICAgIHByaXZhdGUgdHJhbnNpZW50IGludCBoYXNoOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgVGltZXN0YW1wfSB3aXRoIHRoZSBzcGVjaWZpZWQge0Bjb2RlCisgICAgICogdGltZXN0YW1wfSBhbmQgdGhlIGdpdmVuIGNlcnRpZmljYXRlIHBhdGguCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGltZXN0YW1wCisgICAgICogICAgICAgICAgICBkYXRlIGFuZCB0aW1lLgorICAgICAqIEBwYXJhbSBzaWduZXJDZXJ0UGF0aAorICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRlIHBhdGguCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSB0aW1lc3RhbXB9IGlzIHtAY29kZSBudWxsfSBvciBpZiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBzaWduZXJDZXJ0UGF0aH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBUaW1lc3RhbXAoRGF0ZSB0aW1lc3RhbXAsIENlcnRQYXRoIHNpZ25lckNlcnRQYXRoKSB7CisgICAgICAgIGlmICh0aW1lc3RhbXAgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ0aW1lc3RhbXAgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChzaWduZXJDZXJ0UGF0aCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInNpZ25lckNlcnRQYXRoID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICAvLyBDbG9uZSB0aW1lc3RhbXAgdG8gcHJldmVudCBtb2RpZmljYXRpb25zCisgICAgICAgIHRoaXMudGltZXN0YW1wID0gbmV3IERhdGUodGltZXN0YW1wLmdldFRpbWUoKSk7CisgICAgICAgIHRoaXMuc2lnbmVyQ2VydFBhdGggPSBzaWduZXJDZXJ0UGF0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIG9iamVjdCB3aXRoIHRoaXMge0Bjb2RlIFRpbWVzdGFtcH0gZm9yIGVxdWFsaXR5CisgICAgICogYW5kIHJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsLCB7QGNvZGUgZmFsc2V9CisgICAgICogb3RoZXJ3aXNlLiBUaGUgZ2l2ZW4gb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMge0Bjb2RlIFRpbWVzdGFtcH0sIGlmIGl0IGlzCisgICAgICogYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIFRpbWVzdGFtcH0sIHRoZSB0d28gdGltZXN0YW1wcyBoYXZlIGFuIGVxdWFsIGRhdGUKKyAgICAgKiBhbmQgdGltZSBhbmQgdGhlaXIgY2VydGlmaWNhdGUgcGF0aHMgYXJlIGVxdWFsLgorICAgICAqCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgb2JqZWN0IHRvIGJlIGNvbXBhcmVkIGZvciBlcXVhbGl0eSB3aXRoIHRoaXMge0Bjb2RlCisgICAgICogICAgICAgICAgICBUaW1lc3RhbXB9LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMge0Bjb2RlCisgICAgICogICAgICAgICBUaW1lc3RhbXB9LCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAc2VlICNoYXNoQ29kZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgIGlmIChvYmogPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIFRpbWVzdGFtcCkgeworICAgICAgICAgICAgVGltZXN0YW1wIHRoYXQgPSAoVGltZXN0YW1wKSBvYmo7CisgICAgICAgICAgICByZXR1cm4gdGltZXN0YW1wLmVxdWFscyh0aGF0LnRpbWVzdGFtcCkKKyAgICAgICAgICAgICAgICAgICAgJiYgc2lnbmVyQ2VydFBhdGguZXF1YWxzKHRoYXQuc2lnbmVyQ2VydFBhdGgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjZXJ0aWZpY2F0ZSBwYXRoIG9mIHRoaXMge0Bjb2RlIFRpbWVzdGFtcH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjZXJ0aWZpY2F0ZSBwYXRoIG9mIHRoaXMge0Bjb2RlIFRpbWVzdGFtcH0uCisgICAgICovCisgICAgcHVibGljIENlcnRQYXRoIGdldFNpZ25lckNlcnRQYXRoKCkgeworICAgICAgICByZXR1cm4gc2lnbmVyQ2VydFBhdGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGF0ZSBhbmQgdGltZSBvZiB0aGlzIHtAY29kZSBUaW1lc3RhbXB9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZGF0ZSBhbmQgdGltZSBvZiB0aGlzIHtAY29kZSBUaW1lc3RhbXB9LgorICAgICAqLworICAgIHB1YmxpYyBEYXRlIGdldFRpbWVzdGFtcCgpIHsKKyAgICAgICAgcmV0dXJuIChEYXRlKSB0aW1lc3RhbXAuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgdmFsdWUgZm9yIHRoaXMge0Bjb2RlIFRpbWVzdGFtcH0uIFJldHVybnMgdGhlIHNhbWUKKyAgICAgKiBoYXNoIGNvZGUgZm9yIHtAY29kZSBUaW1lc3RhbXB9cyB0aGF0IGFyZSBlcXVhbCB0byBlYWNoIG90aGVyIGFzCisgICAgICogcmVxdWlyZWQgYnkgdGhlIGdlbmVyYWwgY29udHJhY3Qgb2Yge0BsaW5rIE9iamVjdCNoYXNoQ29kZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUgdmFsdWUgZm9yIHRoaXMge0Bjb2RlIFRpbWVzdGFtcH0uCisgICAgICogQHNlZSBPYmplY3QjZXF1YWxzKE9iamVjdCkKKyAgICAgKiBAc2VlIFRpbWVzdGFtcCNlcXVhbHMoT2JqZWN0KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGlmIChoYXNoID09IDApIHsKKyAgICAgICAgICAgIGhhc2ggPSB0aW1lc3RhbXAuaGFzaENvZGUoKSBeIHNpZ25lckNlcnRQYXRoLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGhhc2g7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhpcworICAgICAqIHtAY29kZSBUaW1lc3RhbXB9LgorICAgICAqCisgICAgICogQHJldHVybiBhIHByaW50YWJsZSByZXByZXNlbnRhdGlvbiBmb3IgdGhpcyB7QGNvZGUgVGltZXN0YW1wfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKDI1Nik7CisgICAgICAgIC8vIER1bXAgb25seSB0aGUgZmlyc3QgY2VydGlmaWNhdGUKKyAgICAgICAgYnVmLmFwcGVuZCgiVGltZXN0YW1wIFsiKS5hcHBlbmQodGltZXN0YW1wKS5hcHBlbmQoIiBjZXJ0UGF0aD0iKTsKKyAgICAgICAgYnVmLmFwcGVuZChzaWduZXJDZXJ0UGF0aC5nZXRDZXJ0aWZpY2F0ZXMoKS5nZXQoMCkpLmFwcGVuZCgiXSIpOworICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvVW5yZWNvdmVyYWJsZUVudHJ5RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9VbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYzJlZDJjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvVW5yZWNvdmVyYWJsZUVudHJ5RXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5OworCisKKy8qKgorICoge0Bjb2RlIFVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvbn0gaW5kaWNhdGVzLCB0aGF0IGEge0Bjb2RlIEtleVN0b3JlLkVudHJ5fQorICogY2Fubm90IGJlIHJlY292ZXJlZCBmcm9tIGEge0Bjb2RlIEtleVN0b3JlfS4KKyAqCisgKiBAc2VlIEtleVN0b3JlCisgKiBAc2VlIEtleVN0b3JlLkVudHJ5CisgKi8KK3B1YmxpYyBjbGFzcyBVbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb24gZXh0ZW5kcyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQ1MjcxNDI5NDUyNDYyODY1MzVMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgVW5yZWNvdmVyYWJsZUVudHJ5RXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5yZWNvdmVyYWJsZUVudHJ5RXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvbn0gd2l0aCB0aGUKKyAgICAgKiBnaXZlbiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5yZWNvdmVyYWJsZUVudHJ5RXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKKyAgICAgICAgc3VwZXIobXNnKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9VbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9VbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjcyNzNjMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L1VucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQ2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKKy8qKgorICoge0Bjb2RlIFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb259IGluZGljYXRlcywgdGhhdCBhIGtleSBjYW5ub3QgYmUgcmVjb3ZlcmVkCisgKiBmcm9tIGEge0Bjb2RlIEtleVN0b3JlfS4KKyAqCisgKiBAc2VlIEtleVN0b3JlCisgKi8KK3B1YmxpYyBjbGFzcyBVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uIGV4dGVuZHMgVW5yZWNvdmVyYWJsZUVudHJ5RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDcyNzUwNjMwNzgxOTAxNTEyNzdMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbn0gd2l0aCB0aGUKKyAgICAgKiBnaXZlbiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKKyAgICAgICAgc3VwZXIobXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9VbnJlc29sdmVkUGVybWlzc2lvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvVW5yZXNvbHZlZFBlcm1pc3Npb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMGZjNmRmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvVW5yZXNvbHZlZFBlcm1pc3Npb24uamF2YQpAQCAtMCwwICsxLDQyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBVbnJlc29sdmVkUGVybWlzc2lvbiBleHRlbmRzIFBlcm1pc3Npb24gaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworICAgIHB1YmxpYyBVbnJlc29sdmVkUGVybWlzc2lvbihTdHJpbmcgdHlwZSwgU3RyaW5nIG5hbWUsIFN0cmluZyBhY3Rpb25zLCBDZXJ0aWZpY2F0ZVtdIGNlcnRzKSB7CisgICAgICAgIHN1cGVyKCIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFVucmVzb2x2ZWROYW1lKCkgeyByZXR1cm4gbnVsbDsgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRVbnJlc29sdmVkQWN0aW9ucygpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VW5yZXNvbHZlZFR5cGUoKSB7IHJldHVybiBudWxsOyB9CisKKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVbXSBnZXRVbnJlc29sdmVkQ2VydHMoKSB7IHJldHVybiBudWxsOyB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyBnZXRBY3Rpb25zKCkgeyByZXR1cm4gbnVsbDsgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGltcGxpZXMoUGVybWlzc2lvbiBwZXJtaXNzaW9uKSB7IHJldHVybiB0cnVlOyB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9hY2wvQWNsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9hY2wvQWNsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTQ2ZTZiZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2FjbC9BY2wuamF2YQpAQCAtMCwwICsxLDE2NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LmFjbDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKKworLyoqCisgKiBUaGUgPGk+QWNjZXNzIENvbnRyb2wgTGlzdDwvaT4gKDxiPkFDTDwvYj4pIGludGVyZmFjZSBkZWZpbml0aW9uLgorICogPHA+CisgKiBBbiBBQ0wgaXMgYSBzZXQgb2Yge0BsaW5rIEFjbEVudHJ5fSBvYmplY3RzLgorICogPHA+CisgKiBBbiB7QGNvZGUgQWNsRW50cnl9IGlzIGEgbGlzdCBvZiB7QGxpbmsgUGVybWlzc2lvbn1zIHRoYXQgYXJlIGdyYW50ZWQKKyAqICg8aT5wb3NpdGl2ZTwvaT4pIG9yIGRlbmllZAorICogKDxpPm5lZ2F0aXZlPC9pPikgdG8gYSB7QGxpbmsgUHJpbmNpcGFsfS4KKyAqIDxwPgorICogQW4ge0Bjb2RlIEFjbH0gaGFzIGEgbGlzdCBvZiBvd25lcnMgKHtAbGluayBPd25lcn0pIHdoaWNoIGFyZSBwcmluY2lwYWxzIGFzCisgKiB3ZWxsIHtAY29kZSBQcmluY2lwYWx9LiBPbmx5IHRob3NlIHByaW5jaXBhbHMgd2hpY2ggYXJlIHRoZSB7QGNvZGUgQWNsfSdzCisgKiBvd25lcnMgYXJlIGFsbG93ZWQgdG8gbW9kaWZ5IHRoZSB7QGNvZGUKKyAqIEFjbH0uCisgKiA8cD4KKyAqIFRoZSA8aT5BQ0w8L2k+IGhhcyB0byBjb25mb3JtIHRvIHRoZSBmb2xsb3dpbmcgcnVsZXM6CisgKiA8dWw+CisgKiA8bGk+Rm9yIGVhY2gge0Bjb2RlIFByaW5jaXBhbH0gdGhlcmUgY2FuIGJlIG9ubHkgb25lIDxpPnBvc2l0aXZlPC9pPiBhbmQgb25lCisgKiA8aT5uZWdhdGl2ZTwvaT4ge0Bjb2RlIEFjbEVudHJ5fS48L2xpPgorICogPGxpPklmIHRoZSB0d28ge0Bjb2RlIEFjbEVudHJ5fSdzICg8aT5wb3NpdGl2ZTwvaT4gYW5kIDxpPm5lZ2F0aXZlPC9pPikgZm9yIGEKKyAqIHNwZWNpZmljIHtAY29kZSBQcmluY2lwYWx9IGdyYW50IGFuZCBkZW55IHRoZSBzYW1lIHtAY29kZSBQZXJtaXNzaW9ufSB0byB0aGF0CisgKiB7QGNvZGUgUHJpbmNpcGFsfSwgdGhlbiB0aGF0IHtAY29kZSBQZXJtaXNzaW9ufSBpcyB0cmVhdGVkIGFzCisgKiBuZWl0aGVyIGdyYW50ZWQgbm9yIGRlbmllZCB0byB0aGF0IHtAY29kZSBQcmluY2lwYWx9LjwvbGk+CisgKiA8bGk+UGVybWlzc2lvbnMgYXNzb2NpYXRlZCB3aXRoIGFuIGluZGl2aWR1YWwge0Bjb2RlIFByaW5jaXBhbH0gYWx3YXlzCisgKiBvdmVycmlkZSBwZXJtaXNzaW9ucyBvZiB0aGUgZ3JvdXAocykgdG8gd2hpY2ggdGhlIGluZGl2aWR1YWwgYmVsb25ncy48L2xpPgorICogPGxpPklmIHRoZXJlIGlzIG5vIHtAY29kZSBBY2xFbnRyeX0gYXNzb2NpYXRlZCB3aXRoIGEgc3BlY2lmaWMge0Bjb2RlCisgKiBQcmluY2lwYWx9LCB0aGVuIGl0IGlzIGludGVycHJldGVkIGFzIGFuIGVtcHR5IGxpc3Qgb2YgcGVybWlzc2lvbnMuPC9saT4KKyAqIDwvdWw+CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQWNsIGV4dGVuZHMgT3duZXIgeworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmFtZSBvZiB0aGlzIDxpPkFDTDwvaT4gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2FsbGVyCisgICAgICogICAgICAgICAgICB0aGUgaW52b2tpbmcge0Bjb2RlIFByaW5jaXBhbH0uCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIHRvIGJlIHNldC4KKyAgICAgKiBAdGhyb3dzIE5vdE93bmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGludm9raW5nIHtAY29kZSBQcmluY2lwYWx9IGlzIG5vdCBhbiBvd25lciBvZiB0aGlzCisgICAgICogICAgICAgICAgICAgPGk+QUNMPC9pPi4KKyAgICAgKi8KKyAgICB2b2lkIHNldE5hbWUoUHJpbmNpcGFsIGNhbGxlciwgU3RyaW5nIG5hbWUpIHRocm93cyBOb3RPd25lckV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhpcyA8aT5BQ0w8L2k+IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGlzIDxpPkFDTDwvaT4gaW5zdGFuY2UuCisgICAgICovCisgICAgU3RyaW5nIGdldE5hbWUoKTsKKworICAgIC8qKgorICAgICAqIEFkZHMgYW4ge0Bjb2RlIEFjbEVudHJ5fSB0byB0aGlzIDxpPkFDTDwvaT4gaW5zdGFuY2UuCisgICAgICogPHA+CisgICAgICogSWYgdGhlIDxpPkFDTDwvaT4gYWxyZWFkeSBoYXMgYW4ge0Bjb2RlIEFjbEVudHJ5fSBvZiB0aGUgc2FtZSB0eXBlICg8aT4KKyAgICAgKiBwb3NpdGl2ZTwvaT4gb3IgPGk+bmVnYXRpdmU8L2k+KSBhbmQgcHJpbmNpcGFsLCB0aGVuIHRoZSBuZXcgZW50cnkgaXMgbm90IGFkZGVkLgorICAgICAqCisgICAgICogQHBhcmFtIGNhbGxlcgorICAgICAqICAgICAgICAgICAgdGhlIGludm9raW5nIHtAY29kZSBQcmluY2lwYWx9LgorICAgICAqIEBwYXJhbSBlbnRyeQorICAgICAqICAgICAgICAgICAgdGhlIEFDTCBlbnRyeSB0byBhZGQuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGVudHJ5IGlzIGFkZGVkLCB7QGNvZGUgZmFsc2V9IGlmIHRoZXJlIGlzCisgICAgICogICAgICAgICAgICAgYWxyZWFkeSBhbiBlbnRyeSBvZiB0aGUgc2FtZSB0eXBlIGZvciB0aGUgc2FtZSBwcmluY2lwYWwKKyAgICAgKiBAdGhyb3dzIE5vdE93bmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGludm9raW5nIHtAY29kZSBQcmluY2lwYWx9IGlzIG5vdCBhbiBvd25lciBvZiB0aGlzCisgICAgICogICAgICAgICAgICAgPGk+QUNMPC9pPi4KKyAgICAgKi8KKyAgICBib29sZWFuIGFkZEVudHJ5KFByaW5jaXBhbCBjYWxsZXIsIEFjbEVudHJ5IGVudHJ5KSB0aHJvd3MgTm90T3duZXJFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGFuIHtAY29kZSBBY2xFbnRyeX0gZnJvbSB0aGlzIDxpPkFDTDwvaT4gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2FsbGVyCisgICAgICogICAgICAgICAgICB0aGUgaW52b2tpbmcge0Bjb2RlIFByaW5jaXBhbH0uCisgICAgICogQHBhcmFtIGVudHJ5CisgICAgICogICAgICAgICAgICB0aGUgQUNMIGVudHJ5IHRvIHJlbW92ZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZW50cnkgaXMgcmVtb3ZlZCwge0Bjb2RlIGZhbHNlfSBpZiB0aGUgZW50cnkKKyAgICAgKiAgICAgICAgICAgIGlzIG5vdCBpbiB0aGlzIDxpPkFDTDwvaT4uCisgICAgICogQHRocm93cyBOb3RPd25lckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBpbnZva2luZyB7QGNvZGUgUHJpbmNpcGFsfSBpcyBub3QgYW4gb3duZXIgb2YgdGhpcworICAgICAqICAgICAgICAgICAgIDxpPkFDTDwvaT4uCisgICAgICovCisgICAgYm9vbGVhbiByZW1vdmVFbnRyeShQcmluY2lwYWwgY2FsbGVyLCBBY2xFbnRyeSBlbnRyeSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgTm90T3duZXJFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzZXQgb2YgYWxsb3dlZCBwZXJtaXNzaW9ucyBmb3IgdGhlIHNwZWNpZmllZCB7QGNvZGUKKyAgICAgKiBQcmluY2lwYWx9LgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBzcGVjaWZpZWQgcHJpbmNpcGFsIGhhcyBubyBlbnRyeSBpbiB0aGlzIEFDTCwgYW4gZW1wdHkgc2V0IGlzCisgICAgICogcmV0dXJuZWQuCisgICAgICogPHA+CisgICAgICogVGhlIGFsbG93ZWQgcGVybWlzc2lvbnMgYXJlIGNvbGxlY3RlZCBhY2NvcmRpbmcgdG8gdGhlIGZvbGxvd2luZyBydWxlczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPlRoZSB0d28gcGVybWlzc2lvbiBsaXN0cyAoPGk+cG9zaXRpdmU8L2k+IGFuZCA8aT5uZWdhdGl2ZTwvaT4pIG9mIHRoZQorICAgICAqIHByaW5jaXBhbCdzIGdyb3VwcyAoe0BsaW5rIEdyb3VwfSkgYXJlIGNvbGxlY3RlZC4gVGhlIHBvc2l0aXZlIChncmFudGVkKQorICAgICAqIHBlcm1pc3Npb25zIGFyZSB0aGUgdW5pb24gb2YgYWxsIGdyb3VwJ3MgcG9zaXRpdmUgcGVybWlzc2lvbnMgdGhhdCB0aGUKKyAgICAgKiBwcmluY2lwYWwgYmVsb25ncyB0bywgdGhlIG5lZ2F0aXZlIChkZW5pZWQpIHBlcm1pc3Npb25zIGFyZSB0aGUgdW5pb24gb2YKKyAgICAgKiBhbGwgZ3JvdXAncyBuZWdhdGl2ZSBwZXJtaXNzaW9ucyB0aGF0IHRoZSBwcmluY2lwYWwgYmVsb25ncyB0by4gSWYgYQorICAgICAqIHNwZWNpZmljIHBlcm1pc3Npb24gaXMgaW4gYm90aCB0aGUgcG9zaXRpdmUgYW5kIHRoZSBuZWdhdGl2ZSBsaXN0LCBpdCBpcworICAgICAqIHJlbW92ZWQgZnJvbSBib3RoIGxpc3RzLjwvbGk+CisgICAgICogPGxpPlRoZSBpbmRpdmlkdWFsIHBlcm1pc3Npb25zICg8aT5wb3NpdGl2ZTwvaT4gYW5kIDxpPm5lZ2F0aXZlPC9pPikgb2YKKyAgICAgKiB0aGUgcHJpbmNpcGFsIG92ZXJyaWRlIHRoZSBncm91cCBwZXJtaXNzaW9ucy4gVGhlIHBvc2l0aXZlIGluZGl2aWR1YWwKKyAgICAgKiBwZXJtaXNzaW9ucyBvdmVycmlkZSB0aGUgZ3JvdXAncyBuZWdhdGl2ZSBwZXJtaXNzaW9ucyBhbmQgdGhlIG5lZ2F0aXZlCisgICAgICogaW5kaXZpZHVhbCBwZXJtaXNzaW9ucyBvdmVycmlkZSB0aGUgZ3JwdXAncyBwb3NpdGl2ZSBwZXJtaXNzaW9ucy48L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gdXNlcgorICAgICAqICAgICAgICAgICAgdGhlIHByaW5jaXBhbCB0byBnZXQgdGhlIGFsbG93ZWQgcGVybWlzc2lvbnMgZm9yLgorICAgICAqIEByZXR1cm4gdGhlIHNldCBvZiBhbGxvd2VkIHBlcm1pc3Npb25zIGZvciB0aGUgc3BlY2lmaWVkIHByaW5jaXBhbC4KKyAgICAgKi8KKyAgICBFbnVtZXJhdGlvbjxQZXJtaXNzaW9uPiBnZXRQZXJtaXNzaW9ucyhQcmluY2lwYWwgdXNlcik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIHtAY29kZSBFbnVtZXJhdGlvbn0gb2YgdGhlIHtAY29kZSBBY2xFbnRyeX0gb2YgdGhpcworICAgICAqIDxpPkFDTDwvaT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBFbnVtZXJhdGlvbn0gb2YgdGhlIHtAY29kZSBBY2xFbnRyeX0gb2YgdGhpcworICAgICAqICAgICAgICAgPGk+QUNMPC9pPi4KKyAgICAgKi8KKyAgICBFbnVtZXJhdGlvbjxBY2xFbnRyeT4gZW50cmllcygpOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBwcmluY2lwYWwgaXMgZ3JhbnRlZCB0aGUgc3BlY2lmaWVkCisgICAgICogcGVybWlzc2lvbi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbGlzdCBvZiBncmFudGVkIHBlcm1pc3Npb25zIGlzIGRldGVybWluZWQgYWNjb3JkaW5nIHRvIHRoZSBydWxlcworICAgICAqIHNwZWNpZmllZCBieSB7QGNvZGUgZ2V0UGVybWlzc2lvbnN9LgorICAgICAqCisgICAgICogQHBhcmFtIHByaW5jaXBhbAorICAgICAqICAgICAgICAgICAgdGhlIHByaW5jaXBhbCB0aGUgY2hlY2sgdGhlIHBlcm1pc3Npb25zIGZvci4KKyAgICAgKiBAcGFyYW0gcGVybWlzc2lvbgorICAgICAqICAgICAgICAgICAgdGhlIHBlcm1pc3Npb24gdG8gY2hlY2sgZm9yIHRoZSBwcmluY2lwYWwuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHByaW5jaXBhbCBpcyBncmFudGVkIHRoZSBwZXJtaXNzaW9uLAorICAgICAqICAgICAgICAgICAgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICogQHNlZSAjZ2V0UGVybWlzc2lvbnMoUHJpbmNpcGFsKQorICAgICAqLworICAgIGJvb2xlYW4gY2hlY2tQZXJtaXNzaW9uKFByaW5jaXBhbCBwcmluY2lwYWwsIFBlcm1pc3Npb24gcGVybWlzc2lvbik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBBQ0wuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBBQ0wuCisgICAgICovCisgICAgU3RyaW5nIHRvU3RyaW5nKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9hY2wvQWNsRW50cnkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2FjbC9BY2xFbnRyeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAyZGFiNzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9hY2wvQWNsRW50cnkuamF2YQpAQCAtMCwwICsxLDExOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LmFjbDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKKworLyoqCisgKiBUaGUgPGk+QWNjZXNzIENvbnRyb2wgTGlzdCBFbnRyeTwvaT4gaW50ZXJmYWNlIGRlZmluaXRpb24uCisgKiA8cD4KKyAqIEFuIHtAY29kZSBBY2xFbnRyeX0gaXMgYSBsaXN0IG9mIHRoZSB7QGxpbmsgUGVybWlzc2lvbn1zIHRoYXQgYXJlCisgKiAgZ3JhbnRlZCAoPGk+cG9zaXRpdmU8L2k+KSBvciBkZW5pZWQgKDxpPm5lZ2F0aXZlPC9pPikgdG8gYSB7QGxpbmsgUHJpbmNpcGFsfS4KKyAqLworcHVibGljIGludGVyZmFjZSBBY2xFbnRyeSBleHRlbmRzIENsb25lYWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHByaW5jaXBhbCBmb3IgdGhpcyBBQ0wgZW50cnkuCisgICAgICogPHA+CisgICAgICogVGhlIHByaW5jaXBhbCBmb3IgYW4gQUNMIGVudHJ5IGNhbiBvbmx5IGJlIHNldCBvbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIHVzZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmluY2lwYWwgZm9yIHRoaXMgQUNMIGVudHJ5LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IG9uIHN1Y2Nlc3MsIHtAY29kZSBmYWxzZX0gaWYgdGhlcmUgaXMgYSBwcmluY2lwYWwgYWxyZWFkeSBzZXQgZm9yCisgICAgICogICAgICAgICB0aGlzIGVudHJ5LgorICAgICAqLworICAgIGJvb2xlYW4gc2V0UHJpbmNpcGFsKFByaW5jaXBhbCB1c2VyKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByaW5jaXBhbCBvZiB0aGlzIEFDTCBlbnRyeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByaW5jaXBhbCBvZiB0aGlzIEFDTCBlbnRyeSwgb3IgbnVsbCBpZiBub25lIGlzIHNldC4KKyAgICAgKi8KKyAgICBQcmluY2lwYWwgZ2V0UHJpbmNpcGFsKCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoaXMgQUNMIGVudHJ5IHRvIGJlIDxpPm5lZ2F0aXZlPC9pPi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcGVybWlzc2lvbnMgaW4gdGhpcyBBQ0wgZW50cnkgd2lsbCBiZSBkZW5pZWQgdG8gdGhlIHByaW5jaXBhbAorICAgICAqIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVudHJ5LgorICAgICAqIDxwPgorICAgICAqIE5vdGU6IEFuIEFDTCBlbnRyeSBpcyA8aT5wb3NpdGl2ZTwvaT4gYnkgZGVmYXVsdCBhbmQgY2FuIG9ubHkgYmVjb21lCisgICAgICogPGk+bmVnYXRpdmU8L2k+IGJ5IGNhbGxpbmcgdGhpcyBtZXRob2QuCisgICAgICovCisgICAgdm9pZCBzZXROZWdhdGl2ZVBlcm1pc3Npb25zKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBBQ0wgZW50cnkgaXMgPGk+bmVnYXRpdmU8L2k+LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBBQ0wgZW50cnkgaXMgbmVnYXRpdmUsIHtAY29kZSBmYWxzZX0gaWYgaXQncyBwb3NpdGl2ZS4KKyAgICAgKi8KKyAgICBib29sZWFuIGlzTmVnYXRpdmUoKTsKKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIHNwZWNpZmllZCBwZXJtaXNzaW9uIHRvIHRoaXMgQUNMIGVudHJ5LgorICAgICAqCisgICAgICogQHBhcmFtIHBlcm1pc3Npb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBwZXJtaXNzaW9uIHRvIGJlIGFkZGVkLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgcGVybWlzc2lvbiBpcyBhZGRlZCwge0Bjb2RlIGZhbHNlfSBpZiB0aGUKKyAgICAgKiAgICAgICAgIHBlcm1pc3Npb24gd2FzIGFscmVhZHkgaW4gdGhpcyBlbnRyeS4KKyAgICAgKi8KKyAgICBib29sZWFuIGFkZFBlcm1pc3Npb24oUGVybWlzc2lvbiBwZXJtaXNzaW9uKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCBwZXJtaXNzaW9uIGZyb20gdGhpcyBBQ0wgZW50cnkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGVybWlzc2lvbgorICAgICAqICAgICAgICAgICAgdGhlIHBlcm1pc3Npb24gdG8gYmUgcmVtb3ZlZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgcGVybWlzc2lvbiBpcyByZW1vdmVkLCB7QGNvZGUgZmFsc2V9IGlmIHRoZSBwZXJtaXNzaW9uIHdhcworICAgICAqICAgICAgICAgbm90IGluIHRoaXMgZW50cnkuCisgICAgICovCisgICAgYm9vbGVhbiByZW1vdmVQZXJtaXNzaW9uKFBlcm1pc3Npb24gcGVybWlzc2lvbik7CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgc3BlY2lmaWVkIHBlcm1pc3Npb24gaXMgaW4gdGhpcyBBQ0wgZW50cnkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGVybWlzc2lvbgorICAgICAqICAgICAgICAgICAgdGhlIHBlcm1pc3Npb24gdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHBlcm1pc3Npb24gaXMgaW4gdGhpcyBlbnRyeSwgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgYm9vbGVhbiBjaGVja1Blcm1pc3Npb24oUGVybWlzc2lvbiBwZXJtaXNzaW9uKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxpc3Qgb2YgcGVybWlzc2lvbnMgb2YgdGhpcyBBQ0wgZW50cnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsaXN0IG9mIHBlcm1pc3Npb25zIG9mIHRoaXMgQUNMIGVudHJ5LAorICAgICAqLworICAgIEVudW1lcmF0aW9uPFBlcm1pc3Npb24+IHBlcm1pc3Npb25zKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBBQ0wgZW50cnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBBQ0wgZW50cnkuCisgICAgICovCisgICAgU3RyaW5nIHRvU3RyaW5nKCk7CisKKyAgICAvKioKKyAgICAgKiBDbG9uZXMgdGhpcyBBQ0wgZW50cnkgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGlzIGVudHJ5LgorICAgICAqLworICAgIE9iamVjdCBjbG9uZSgpOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9hY2wvQWNsTm90Rm91bmRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2FjbC9BY2xOb3RGb3VuZEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5YjkwNDUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9hY2wvQWNsTm90Rm91bmRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDM0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuYWNsOworCisvKioKKyAqIFRoZSBleGNlcHRpb24sIHRoYXQgaXMgdGhyb3duIHdoZW4gYSByZWZlcmVuY2UgdG8gYSBub24tZXhpc3RlbnQgPGk+QWNjZXNzCisgKiBDb250cm9sIExpc3Q8L2k+IChBQ0wpIGlzIG1hZGUuCisgKi8KK3B1YmxpYyBjbGFzcyBBY2xOb3RGb3VuZEV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1Njg0Mjk1MDM0MDkyNjgxNzkxTDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEFjbE5vdEZvdW5kRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQWNsTm90Rm91bmRFeGNlcHRpb24oKSB7CisKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9hY2wvR3JvdXAuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2FjbC9Hcm91cC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIxMTdkNjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9hY2wvR3JvdXAuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuYWNsOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5QcmluY2lwYWw7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworCisvKioKKyAqIEEge0Bjb2RlIFByaW5jaXBhbH0gdGhhdCByZXByZXNlbnRzIGEgZ3JvdXAgb2YgcHJpbmNpcGFscy4KKyAqCisgKiBAc2VlIFByaW5jaXBhbAorICovCitwdWJsaWMgaW50ZXJmYWNlIEdyb3VwIGV4dGVuZHMgUHJpbmNpcGFsIHsKKworICAgIC8qKgorICAgICAqIEFkZHMgYSBtZW1iZXIgdG8gdGhpcyBncm91cC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1c2VyCisgICAgICogICAgICAgICAgICB0aGUgbWVtYmVyIHRvIGFkZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgbWVtYmVyIHdhcyBhZGRlZCwge0Bjb2RlIGZhbHNlfSBpZiBpdCB3YXMgYWxyZWFkeSBhIG1lbWJlci4KKyAgICAgKi8KKyAgICBib29sZWFuIGFkZE1lbWJlcihQcmluY2lwYWwgdXNlcik7CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGEgbWVtYmVyIGZyb20gdGhpcyBncm91cC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1c2VyCisgICAgICogICAgICAgICAgICB0aGUgbWVtYmVyIHRvIHJlbW92ZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgbWVtYmVyIHdhcyByZW1vdmVkLCB7QGNvZGUgZmFsc2V9IGlmIGl0IHdhcyBub3QgYSBtZW1iZXIuCisgICAgICovCisgICAgYm9vbGVhbiByZW1vdmVNZW1iZXIoUHJpbmNpcGFsIHVzZXIpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgcHJpbmNpcGFsIGlzIGEgbWVtYmVyIG9mIHRoaXMgZ3JvdXAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVtYmVyCisgICAgICogICAgICAgICAgICB0aGUgcHJpbmNpcGFsIHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBwcmluY2lwYWwgaXMgYSBtZW1iZXIsIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9LgorICAgICAqLworICAgIGJvb2xlYW4gaXNNZW1iZXIoUHJpbmNpcGFsIG1lbWJlcik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtZW1iZXJzIG9mIHRoaXMgZ3JvdXAuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtZW1iZXJzIG9mIHRoaXMgZ3JvdXAuCisgICAgICovCisgICAgRW51bWVyYXRpb248PyBleHRlbmRzIFByaW5jaXBhbD4gbWVtYmVycygpOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9hY2wvTGFzdE93bmVyRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9hY2wvTGFzdE93bmVyRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjk0N2YyMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2FjbC9MYXN0T3duZXJFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDM1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuYWNsOworCisvKioKKyAqIFRoZSBleGNlcHRpb24gdGhhdCBpcyB0aHJvd24gd2hlbiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gcmVtb3ZlIHRoZQorICogdGhlIGxhc3Qge0Bjb2RlIE93bmVyfSBmcm9tIGFuIHtAY29kZSBPd25lcn0uCisgKgorICogQHNlZSBPd25lcgorICovCitwdWJsaWMgY2xhc3MgTGFzdE93bmVyRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC01MTQxOTk3NTQ4MjExMTQwMzU5TDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIExhc3RPd25lckV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIExhc3RPd25lckV4Y2VwdGlvbigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9hY2wvTm90T3duZXJFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2FjbC9Ob3RPd25lckV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQwNzc3NjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9hY2wvTm90T3duZXJFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDM3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuYWNsOworCisvKioKKyAqIFRoZSBleGNlcHRpb24gdGhhdCBpcyB0aHJvd24gd2hlbiBhbiBhY3Rpb24gdGhhdCByZXF1aXJlcyBvd25lcnNoaXAgaXMKKyAqIGF0dGVtcHRlZCBieSBhIHByaW5jaXBhbCB0aGF0IGlzIG5vdCBhbiBvd25lciBvZiB0aGUgb2JqZWN0IGZvciB3aGljaAorICogb3duZXJzaGlwIGlzIHJlcXVpcmVkLgorICoKKyAqIEBzZWUgQWNsCisgKiBAc2VlIE93bmVyCisgKi8KK3B1YmxpYyBjbGFzcyBOb3RPd25lckV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTU1NTU5NzkxMTE2MzM2MjM5OUw7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBOb3RPd25lckV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIE5vdE93bmVyRXhjZXB0aW9uKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2FjbC9Pd25lci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvYWNsL093bmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjU2ZGIyOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2FjbC9Pd25lci5qYXZhCkBAIC0wLDAgKzEsNjkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5hY2w7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKKworLyoqCisgKiBUaGUgaW50ZXJmYWNlIHRvIG1hbmFnZSBvd25lcnMgb2Ygb2JqZWN0cyB0aGF0IHJlcXVpcmUgb3duZXJzaGlwLgorICoKKyAqIEBzZWUgQWNsCisgKiBAc2VlIFByaW5jaXBhbAorICovCitwdWJsaWMgaW50ZXJmYWNlIE93bmVyIHsKKworICAgIC8qKgorICAgICAqIEFkZHMgYSBwcmluY2lwYWwgdG8gdGhlIGxpc3Qgb2Ygb3duZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGNhbGxlcgorICAgICAqICAgICAgICAgICAgdGhlIGludm9raW5nIHByaW5jaXBhbC4KKyAgICAgKiBAcGFyYW0gb3duZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBvd25lciB0byBhZGRlZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgb3duZXIgd2FzIGFkZGVkLCB7QGNvZGUgZmFsc2V9IGlmIGl0IHdhcyBhbHJlYWR5IGFuIG93bmVyLgorICAgICAqIEB0aHJvd3MgTm90T3duZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaW52b2tpbmcgcHJpbmNpcGFsIGlzIG5vdCBhbiBvd25lci4KKyAgICAgKi8KKyAgICBib29sZWFuIGFkZE93bmVyKFByaW5jaXBhbCBjYWxsZXIsIFByaW5jaXBhbCBvd25lcikKKyAgICAgICAgICAgICAgICAgdGhyb3dzIE5vdE93bmVyRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhIHByaW5jaXBhbCBmcm9tIHRoZSBsaXN0IG9mIG93bmVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYWxsZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnZva2luZyBwcmluY2lwYWwuCisgICAgICogQHBhcmFtIG93bmVyCisgICAgICogICAgICAgICAgICB0aGUgb3duZXIgdG8gYmUgcmVtb3ZlZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgb3duZXIgd2FzIHJlbW92ZWQsIHtAY29kZSBmYWxzZX0gaWYgaXQgd2FzIG5vdCBhbiBvd25lci4KKyAgICAgKiBAdGhyb3dzIE5vdE93bmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGludm9raW5nIHByaW5jaXBhbCBpcyBub3QgYW4gb3duZXIuCisgICAgICogQHRocm93cyBMYXN0T3duZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgb3duZXIgdG8gYmUgcmVtb3ZlZCBpcyB0aGUgbGFzdCBvd25lciBhbmQgaGVuY2UgcmVtb3ZpbmcgaXQKKyAgICAgKiAgICAgICAgICAgICB3b3VsZCBtYWtlIHRoaXMgb2JqZWN0IG93bmVyLWxlc3MuCisgICAgICovCisgICAgYm9vbGVhbiBkZWxldGVPd25lcihQcmluY2lwYWwgY2FsbGVyLCBQcmluY2lwYWwgb3duZXIpCisgICAgICAgICAgICAgICAgdGhyb3dzIE5vdE93bmVyRXhjZXB0aW9uLCBMYXN0T3duZXJFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgc3BlY2lmaWVkIHByaW5jaXBhbCBpcyBhbiBvd25lciBvZiB0aGlzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvd25lcgorICAgICAqICAgICAgICAgICAgdGhlIHByaW5jaXBhbCB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIHByaW5jaXBhbCBpcyBhbiBvd25lciwgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgYm9vbGVhbiBpc093bmVyKFByaW5jaXBhbCBvd25lcik7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9hY2wvUGVybWlzc2lvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvYWNsL1Blcm1pc3Npb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMDM1YTExCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvYWNsL1Blcm1pc3Npb24uamF2YQpAQCAtMCwwICsxLDI2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuYWNsOworCisvKioKKyAqIExlZ2FjeSBzZWN1cml0eSBjb2RlOyBkbyBub3QgdXNlLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFBlcm1pc3Npb24geworICAgIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBhbm90aGVyKTsKKyAgICBTdHJpbmcgdG9TdHJpbmcoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2FjbC9wYWNrYWdlLmh0bWwgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9hY2wvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI4ZWMwNjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9hY2wvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMTQgQEAKKzxodG1sPgorPGhlYWQ+Cis8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD11cy1hc2NpaSI+Cis8L2hlYWQ+Cis8aHRtbD4KKzxib2R5PgorPHA+CitUaGlzIHBhY2thZ2UgcHJvdmlkZXMgdGhlIGNsYXNzZXMgYW5kIHRoZSBpbnRlcmZhY2VzIG5lZWRlZCB0byBidWlsZCBBY2Nlc3MgQ29udHJvbCBMaXN0cy4KK0Z1bmN0aW9uYWxpdHkgZm9yIGdlbmVyYXRpbmcgbmV3IGVudHJpZXMgaW4gYW4gQUNMIHtAbGluayBqYXZhLnNlY3VyaXR5LmFjbC5BY2xFbnRyeX0sCitmb3IgdGhlIGNyZWF0aW9uIG9mIG5ldyBvd25lcnMge0BsaW5rIGphdmEuc2VjdXJpdHkuYWNsLk93bmVyfSwgYW5kIGZvciB0aGUgcmVnaXN0cmF0aW9uIG9mCituZXcgcGVybWlzc2lvbnMge0BsaW5rIGphdmEuc2VjdXJpdHkuYWNsLlBlcm1pc3Npb259IGFyZSBwcm92aWRlZC4KKzwvcD4KKzwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ1JMLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NSTC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM0MGVkYmQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NSTC5qYXZhCkBAIC0wLDAgKzEsNjYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBDZXJ0aWZpY2F0ZSBSZXZvY2F0aW9uIExpc3RzIChDUkxzKSBtYWludGFpbmVkIGJ5IGEKKyAqIGNlcnRpZmljYXRlIGF1dGhvcml0eS4gVGhleSBhcmUgdXNlZCB0byBpbmRpY2F0ZSB0aGF0IGEgZ2l2ZW4gQ2VydGlmaWNhdGUgaGFzCisgKiBleHBpcmVkIGFuZCBjb25zZXF1ZW50bHkgaGFzIGJlY29tZSBpbnZhbGlkLgorICoKKyAqIEBzZWUgQ2VydGlmaWNhdGVGYWN0b3J5CisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBDUkwgeworICAgIC8vIFRoZSBDUkwgdHlwZQorICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHR5cGU7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGNlcnRpZmljYXRlIHJldm9jYXRpb24gbGlzdCBvZiB0aGUgc3BlY2lmaWVkIHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHR5cGUgZm9yIHRoZSBDUkwuCisgICAgICovCisgICAgcHJvdGVjdGVkIENSTChTdHJpbmcgdHlwZSkgeworICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgdGhpcyBDUkwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIG9mIHRoaXMgQ1JMLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0VHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY2VydGlmaWNhdGUgaXMgcmV2b2tlZCBieSB0aGlzIENSTC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjZXJ0CisgICAgICogICAgICAgICAgICB0aGUgY2VydGlmaWNhdGUgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGNlcnRpZmljYXRlIGlzIHJldm9rZWQgYnkgdGhpcyBDUkwsIG90aGVyd2lzZQorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc1Jldm9rZWQoQ2VydGlmaWNhdGUgY2VydCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgdG9TdHJpbmcoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ1JMRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NSTEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA1YWRlN2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NSTEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb247CisKKy8qKgorICogVGhlIGV4Y2VwdGlvbiB0aGF0IGlzIHRocm93biBpZiBlcnJvcnMgb2NjdXIgZHVyaW5nIGhhbmRsaW5nIG9mIHtAY29kZSBDUkx9cy4KKyAqLworcHVibGljIGNsYXNzIENSTEV4Y2VwdGlvbiBleHRlbmRzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjY5NDcyODk0NDA5NDE5NzE0N0w7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDUkxFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ1JMRXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKKyAgICAgICAgc3VwZXIobXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDUkxFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBDUkxFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ1JMRXhjZXB0aW9ufSB3aXRoIHRoZSBzcGVjaWZpZWQgbWVzc2FnZSBhbmQgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYXVzZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIENSTEV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UsIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDUkxFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGNhdXNlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ1JMRXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DUkxTZWxlY3Rvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DUkxTZWxlY3Rvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZmN2VjOTkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NSTFNlbGVjdG9yLmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LmNlcnQ7CisKKy8qKgorICogVGhlIGludGVyZmFjZSBzcGVjaWZpY2F0aW9uIGZvciBkZXRlcm1pbmluZyB3aGV0aGVyIGEgQ1JMIG1lZXRzIHNvbWUgY3JpdGVyaWEKKyAqIHRvIHNlbGVjdCBDUkwgb2JqZWN0cyBhbW9uZyBhIHNldCBvZiB7QGNvZGUgQ1JMfXMuCisgKiA8cD4KKyAqIFRoZSBpbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBpbnRlcmZhY2UgYXJlIHR5cGljYWxseSB1c2VkIHRvIGRlZmluZSB0aGUKKyAqIGNyaXRlcmlhIGZvciBzZWxlY3Rpbmcge0Bjb2RlIENSTH1zIGZyb20gYSB7QGNvZGUgQ2VydFN0b3JlfS4KKyAqCisgKiBAc2VlIENlcnRTdG9yZQorICogQHNlZSBDUkwKKyAqLworcHVibGljIGludGVyZmFjZSBDUkxTZWxlY3RvciBleHRlbmRzIENsb25lYWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBDbG9uZXMgdGhpcyB7QGNvZGUgQ1JMU2VsZWN0b3J9IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2xvbmVkIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKTsKKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBkZWZpbmVkIGNyaXRlcmlhIG9mIHRoaXMgaW5zdGFuY2UgbWF0Y2ggdGhlIHNwZWNpZmllZAorICAgICAqIENSTC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjcmwKKyAgICAgKiAgICAgICAgICAgIHRoZSBDUkwgdG8gYmUgZXZhbHVhdGVkLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBDUkwgbWF0Y2hlcyB0aGUgY3JpdGVyaWEsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChDUkwgY3JsKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGguamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGguamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMjQ3ZDMwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aC5qYXZhCkBAIC0wLDAgKzEsMjMyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5Ob3RTZXJpYWxpemFibGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1GaWVsZDsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKgorICogQW4gaW1tdXRhYmxlIGNlcnRpZmljYXRlIHBhdGggdGhhdCBjYW4gYmUgdmFsaWRhdGVkLiBBbGwgY2VydGlmaWNhdGVzIGluIHRoZQorICogcGF0aCBhcmUgb2YgdGhlIHNhbWUgdHlwZSAoaS5lLiwgWDUwOSkuCisgKiA8cD4KKyAqIEEge0Bjb2RlIENlcnRQYXRofSBjYW4gYmUgcmVwcmVzZW50ZWQgYXMgYSBieXRlIGFycmF5IGluIGF0IGxlYXN0IG9uZQorICogc3VwcG9ydGVkIGVuY29kaW5nIHNjaGVtZSAoaS5lLiBQa2lQYXRoIG9yIFBLQ1M3KSB3aGVuIHNlcmlhbGl6ZWQuCisgKiA8cD4KKyAqIFdoZW4gYSB7QGNvZGUgTGlzdH0gb2YgdGhlIGNlcnRpZmljYXRlcyBpcyBvYnRhaW5lZCBpdCBtdXN0IGJlIGltbXV0YWJsZS4KKyAqIDxwPgorICogQSB7QGNvZGUgQ2VydFBhdGh9IG11c3QgYmUgdGhyZWFkLXNhZmUgd2l0aG91dCByZXF1aXJpbmcgY29vcmRpbmF0ZWQgYWNjZXNzLgorICoKKyAqIEBzZWUgQ2VydGlmaWNhdGUKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIENlcnRQYXRoIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDYwNjg0NzAzMDY2NDkxMzg2ODNMOworICAgIC8vIFN0YW5kYXJkIG5hbWUgb2YgdGhlIHR5cGUgb2YgY2VydGlmaWNhdGVzIGluIHRoaXMgcGF0aAorICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHR5cGU7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0UGF0aH0gaW5zdGFuY2UgZm9yIHRoZSBzcGVjaWZpZWQgY2VydGlmaWNhdGUKKyAgICAgKiB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZSB0eXBlLgorICAgICAqLworICAgIHByb3RlY3RlZCBDZXJ0UGF0aChTdHJpbmcgdHlwZSkgeworICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHR5cGUgb2Yge0Bjb2RlIENlcnRpZmljYXRlfSBpbiB0aGlzIGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2VydGlmaWNhdGUgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoKSB7CisgICAgICAgIHJldHVybiB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBDZXJ0aWZpY2F0ZX1zIGluIHRoZSBsaXN0IGFyZSB0aGUgc2FtZQorICAgICAqIHR5cGUgYW5kIHRoZSBsaXN0cyBhcmUgZXF1YWwgKGFuZCBieSBpbXBsaWNhdGlvbiB0aGUgY2VydGlmaWNhdGVzCisgICAgICogY29udGFpbmVkIHdpdGhpbiBhcmUgdGhlIHNhbWUpLgorICAgICAqCisgICAgICogQHBhcmFtIG90aGVyCisgICAgICogICAgICAgICAgICB7QGNvZGUgQ2VydFBhdGh9IHRvIGJlIGNvbXBhcmVkIGZvciBlcXVhbGl0eS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgb2JqZWN0IGFyZSBlcXVhbCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgeworICAgICAgICBpZiAodGhpcyA9PSBvdGhlcikgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgQ2VydFBhdGgpIHsKKyAgICAgICAgICAgIENlcnRQYXRoIG8gPSAoQ2VydFBhdGgpb3RoZXI7CisgICAgICAgICAgICBpZiAoZ2V0VHlwZSgpLmVxdWFscyhvLmdldFR5cGUoKSkpIHsKKyAgICAgICAgICAgICAgICBpZiAoZ2V0Q2VydGlmaWNhdGVzKCkuZXF1YWxzKG8uZ2V0Q2VydGlmaWNhdGVzKCkpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3ZlcnJpZGVzIHtAY29kZSBPYmplY3QuaGFzaENvZGUoKX0uIFRoZSBmdW5jdGlvbiBpcyBkZWZpbmVkIGFzIGZvbGxvd3M6CisgICAgICogPHByZT4KKyAgICAgKiB7QGNvZGUgaGFzaENvZGUgPSAzMSAqIHBhdGguZ2V0VHlwZSgpLmhhc2hDb2RlKCkgKworICAgICAqIHBhdGguZ2V0Q2VydGlmaWNhdGVzKCkuaGFzaENvZGUoKTt9CisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUgZm9yIHRoaXMgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IGhhc2ggPSBnZXRUeXBlKCkuaGFzaENvZGUoKTsKKyAgICAgICAgaGFzaCA9IGhhc2gqMzEgKyBnZXRDZXJ0aWZpY2F0ZXMoKS5oYXNoQ29kZSgpOworICAgICAgICByZXR1cm4gaGFzaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIFN0cmluZ30gcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgQ2VydFBhdGh9CisgICAgICogaW5zdGFuY2UuIEl0IGlzIHRoZSByZXN1bHQgb2YgY2FsbGluZyB7QGNvZGUgdG9TdHJpbmd9IG9uIGFsbCB7QGNvZGUKKyAgICAgKiBDZXJ0aWZpY2F0ZX1zIGluIHRoZSB7QGNvZGUgTGlzdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKGdldFR5cGUoKSk7CisgICAgICAgIHNiLmFwcGVuZCgiIENlcnQgUGF0aCwgbGVuPSIpOworICAgICAgICBzYi5hcHBlbmQoZ2V0Q2VydGlmaWNhdGVzKCkuc2l6ZSgpKTsKKyAgICAgICAgc2IuYXBwZW5kKCI6IFtcbiIpOworICAgICAgICBpbnQgbj0xOworICAgICAgICBmb3IgKEl0ZXJhdG9yPD8gZXh0ZW5kcyBDZXJ0aWZpY2F0ZT4gaT1nZXRDZXJ0aWZpY2F0ZXMoKS5pdGVyYXRvcigpOyBpLmhhc05leHQoKTsgbisrKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIi0tLS0tLS0tLS0tLS0tLWNlcnRpZmljYXRlICIpOworICAgICAgICAgICAgc2IuYXBwZW5kKG4pOworICAgICAgICAgICAgc2IuYXBwZW5kKCItLS0tLS0tLS0tLS0tLS1cbiIpOworICAgICAgICAgICAgc2IuYXBwZW5kKCgoQ2VydGlmaWNhdGUpaS5uZXh0KCkpLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZCgiXG5dIik7CisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW1tdXRhYmxlIExpc3Qgb2YgdGhlIHtAY29kZSBDZXJ0aWZpY2F0ZX1zIGNvbnRhaW5lZAorICAgICAqIGluIHRoZSB7QGNvZGUgQ2VydFBhdGh9LgorICAgICAqCisgICAgICogQHJldHVybiBhIGxpc3Qgb2Yge0Bjb2RlIENlcnRpZmljYXRlfXMgaW4gdGhlIHtAY29kZSBDZXJ0UGF0aH0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IExpc3Q8PyBleHRlbmRzIENlcnRpZmljYXRlPiBnZXRDZXJ0aWZpY2F0ZXMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gZW5jb2Rpbmcgb2YgdGhlIHtAY29kZSBDZXJ0UGF0aH0gdXNpbmcgdGhlIGRlZmF1bHQgZW5jb2RpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGRlZmF1bHQgZW5jb2Rpbmcgb2YgdGhlIHtAY29kZSBDZXJ0UGF0aH0uCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGVuY29kaW5nIGZhaWxzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBieXRlW10gZ2V0RW5jb2RlZCgpCisgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBlbmNvZGluZyBvZiB0aGUge0Bjb2RlIENlcnRQYXRofSB1c2luZyB0aGUgc3BlY2lmaWVkIGVuY29kaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIGVuY29kaW5nCisgICAgICogICAgICAgICAgICBlbmNvZGluZyB0aGF0IHNob3VsZCBiZSBnZW5lcmF0ZWQuCisgICAgICogQHJldHVybiBkZWZhdWx0IGVuY29kaW5nIG9mIHRoZSB7QGNvZGUgQ2VydFBhdGh9LgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmNvZGluZyBmYWlscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYnl0ZVtdIGdldEVuY29kZWQoU3RyaW5nIGVuY29kaW5nKQorICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4ge0Bjb2RlIEl0ZXJhdG9yfSBvdmVyIHRoZSBzdXBwb3J0ZWQgZW5jb2RpbmdzIGZvciBhCisgICAgICogcmVwcmVzZW50YXRpb24gb2YgdGhlIGNlcnRpZmljYXRlIHBhdGguCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSBJdGVyYXRvcn0gb3ZlciBzdXBwb3J0ZWQgZW5jb2RpbmdzIChhcyB7QGNvZGUgU3RyaW5nfXMpLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBJdGVyYXRvcjxTdHJpbmc+IGdldEVuY29kaW5ncygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhbHRlcm5hdGUgb2JqZWN0IHRvIGJlIHNlcmlhbGl6ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFsdGVybmF0ZSBvYmplY3QgdG8gYmUgc2VyaWFsaXplZC4KKyAgICAgKiBAdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjcmVhdGlvbiBvZiB0aGUgYWx0ZXJuYXRlIG9iamVjdCBmYWlscy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgT2JqZWN0IHdyaXRlUmVwbGFjZSgpIHRocm93cyBPYmplY3RTdHJlYW1FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBDZXJ0UGF0aFJlcChnZXRUeXBlKCksIGdldEVuY29kZWQoKSk7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbigiQ291bGQgbm90IGNyZWF0ZSBzZXJpYWxpemF0aW9uIG9iamVjdDogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGFsdGVybmF0ZSB7QGNvZGUgU2VyaWFsaXphYmxlfSBjbGFzcyB0byBiZSB1c2VkIGZvciBzZXJpYWxpemF0aW9uIGFuZAorICAgICAqIGRlc2VyaWFsaXphdGlvbiBvbiB7QGNvZGUgQ2VydFBhdGh9IG9iamVjdHMuCisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBjbGFzcyBDZXJ0UGF0aFJlcCBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzAxNTYzMzA3MjQyNzkyMDkxNUw7CisgICAgICAgIC8vIFN0YW5kYXJkIG5hbWUgb2YgdGhlIHR5cGUgb2YgY2VydGlmaWNhdGVzIGluIHRoaXMgcGF0aAorICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyB0eXBlOworICAgICAgICAvLyBjZXJ0IHBhdGggZGF0YQorICAgICAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBkYXRhOworCisgICAgICAgIC8vIEZvcmNlIGRlZmF1bHQgc2VyaWFsaXphdGlvbiB0byB1c2Ugd3JpdGVVbnNoYXJlZC9yZWFkVW5zaGFyZWQKKyAgICAgICAgLy8gZm9yIGNlcnQgcGF0aCBkYXRhCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFN0cmVhbUZpZWxkW10gc2VyaWFsUGVyc2lzdGVudEZpZWxkcyA9IHsKKyAgICAgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgidHlwZSIsIFN0cmluZy5jbGFzcyksCisgICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImRhdGEiLCBieXRlW10uY2xhc3MsIHRydWUpLAorICAgICAgICB9OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0UGF0aFJlcH0gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHR5cGUKKyAgICAgICAgICogYW5kIGVuY29kZWQgZGF0YS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIHR5cGUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgY2VydGlmaWNhdGUgdHlwZS4KKyAgICAgICAgICogQHBhcmFtIGRhdGEKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZW5jb2RlZCBkYXRhLgorICAgICAgICAgKi8KKyAgICAgICAgcHJvdGVjdGVkIENlcnRQYXRoUmVwKFN0cmluZyB0eXBlLCBieXRlW10gZGF0YSkgeworICAgICAgICAgICAgdGhpcy50eXBlID0gdHlwZTsKKyAgICAgICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogRGVzZXJpYWxpemVzIGEge0Bjb2RlIENlcnRQYXRofSBmcm9tIGEgc2VyaWFsaXplZCB7QGNvZGUgQ2VydFBhdGhSZXB9CisgICAgICAgICAqIG9iamVjdC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUgZGVzZXJpYWxpemVkIHtAY29kZSBDZXJ0UGF0aH0uCisgICAgICAgICAqIEB0aHJvd3MgT2JqZWN0U3RyZWFtRXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIGRlc2VyaWFsaXphdGlvbiBmYWlscy4KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBPYmplY3QgcmVhZFJlc29sdmUoKSB0aHJvd3MgT2JqZWN0U3RyZWFtRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKHR5cGUpOworICAgICAgICAgICAgICAgIHJldHVybiBjZi5nZW5lcmF0ZUNlcnRQYXRoKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShkYXRhKSk7CisgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb3RTZXJpYWxpemFibGVFeGNlcHRpb24oIkNvdWxkIG5vdCByZXNvbHZlIGNlcnQgcGF0aDogIiArIHQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aEJ1aWxkZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhCdWlsZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWE2NWZlNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhCdWlsZGVyLmphdmEKQEAgLTAsMCArMSwxOTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5mb3J0cmVzcy5FbmdpbmU7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBmdW5jdGlvbmFsaXR5IG9mIGEgYnVpbGRlciBmb3IgYW4gdW52ZXJpZmllZAorICogPGk+Q2VydGlmaWNhdGlvbiBQYXRoPC9pPnMgZnJvbSBhIHNwZWNpZmllZCBjZXJ0aWZpY2F0ZSB0byBhIHRydXN0IGFuY2hvci4KKyAqLworcHVibGljIGNsYXNzIENlcnRQYXRoQnVpbGRlciB7CisKKyAgICAvLyBTdG9yZSBDZXJ0UGF0aEJ1aWxkZXIgc2VydmljZSBuYW1lCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNFUlZJQ0UgPSAiQ2VydFBhdGhCdWlsZGVyIjsKKworICAgIC8vIFVzZWQgdG8gYWNjZXNzIGNvbW1vbiBlbmdpbmUgZnVuY3Rpb25hbGl0eQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEVuZ2luZSBFTkdJTkUgPSBuZXcgRW5naW5lKFNFUlZJQ0UpOworCisgICAgLy8gU3RvcmUgZGVmYXVsdCBwcm9wZXJ0eSBuYW1lCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZTkFNRSA9ICJjZXJ0cGF0aGJ1aWxkZXIudHlwZSI7CisKKyAgICAvLyBEZWZhdWx0IHZhbHVlIG9mIENlcnRQYXRoQnVpbGRlciB0eXBlLiBJdCByZXR1cm5zIGlmIGNlcnRwYXRoYnVpbGQudHlwZQorICAgIC8vIHByb3BlcnR5IGlzIG5vdCBkZWZpbmVkIGluIGphdmEuc2VjdXJpdHkgZmlsZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUUFJPUEVSVFkgPSAiUEtJWCI7CisKKyAgICAvLyBTdG9yZSB1c2VkIHByb3ZpZGVyCisgICAgcHJpdmF0ZSBmaW5hbCBQcm92aWRlciBwcm92aWRlcjsKKworICAgIC8vIFN0b3JlIHNwaSBpbXBsZW1lbnRhdGlvbgorICAgIHByaXZhdGUgZmluYWwgQ2VydFBhdGhCdWlsZGVyU3BpIHNwaUltcGw7CisKKyAgICAvLyBTdG9yZSBhbGdvcml0aG0gbmFtZQorICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGFsZ29yaXRobTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENlcnRQYXRoQnVpbGRlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVpbGRlclNwaQorICAgICAqICAgICAgICAgICAgdGhlIGltcGxlbWVudGF0aW9uIGRlbGVnYXRlLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHByb3ZpZGVyLgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXNpcmVkIGFsZ29yaXRobSBhdmFpbGFibGUgYXQgdGhlIHByb3ZpZGVyLgorICAgICAqLworICAgIHByb3RlY3RlZCBDZXJ0UGF0aEJ1aWxkZXIoQ2VydFBhdGhCdWlsZGVyU3BpIGJ1aWxkZXJTcGksIFByb3ZpZGVyIHByb3ZpZGVyLAorICAgICAgICAgICAgU3RyaW5nIGFsZ29yaXRobSkgeworICAgICAgICB0aGlzLnByb3ZpZGVyID0gcHJvdmlkZXI7CisgICAgICAgIHRoaXMuYWxnb3JpdGhtID0gYWxnb3JpdGhtOworICAgICAgICB0aGlzLnNwaUltcGwgPSBidWlsZGVyU3BpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFsZ29yaXRobSBuYW1lIG9mIHRoaXMgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBhbGdvcml0aG0gbmFtZSBvZiB0aGlzIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICByZXR1cm4gYWxnb3JpdGhtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByb3ZpZGVyIG9mIHRoaXMgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcm92aWRlciBvZiB0aGlzIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBQcm92aWRlciBnZXRQcm92aWRlcigpIHsKKyAgICAgICAgcmV0dXJuIHByb3ZpZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENlcnRQYXRoQnVpbGRlcn0gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobS4KKyAgICAgKiBAcmV0dXJuIGEgYnVpbGRlciBmb3IgdGhlIHJlcXVlc3RlZCBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhbGdvcml0aG0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgbm8gaW5zdGFsbGVkIHByb3ZpZGVyIGNhbiBwcm92aWRlIHRoZSBhbGdvcml0aG0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDZXJ0UGF0aEJ1aWxkZXIgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIEVuZ2luZS5TcGlBbmRQcm92aWRlciBzYXAgPSBFTkdJTkUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBudWxsKTsKKyAgICAgICAgcmV0dXJuIG5ldyBDZXJ0UGF0aEJ1aWxkZXIoKENlcnRQYXRoQnVpbGRlclNwaSkgc2FwLnNwaSwgc2FwLnByb3ZpZGVyLCBhbGdvcml0aG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENlcnRQYXRoQnVpbGRlcn0gaW5zdGFuY2UgZnJvbSB0aGUgc3BlY2lmaWVkCisgICAgICogcHJvdmlkZXIgcHJvdmlkaW5nIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobS4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBwcm92aWRlci4KKyAgICAgKiBAcmV0dXJuIGEgYnVpbGRlciBmb3IgdGhlIHJlcXVlc3RlZCBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGNhbm5vdCBwcm92aWRlIHRoZSBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG5vIHByb3ZpZGVyIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGNhbiBiZSBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYWxnb3JpdGhtIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgcHJvdmlkZXIgPT0gbnVsbCB8fCBwcm92aWRlci5pc0VtcHR5KCl9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDZXJ0UGF0aEJ1aWxkZXIgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCB8fCBwcm92aWRlci5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBpbXBQcm92aWRlciA9IFNlY3VyaXR5LmdldFByb3ZpZGVyKHByb3ZpZGVyKTsKKyAgICAgICAgaWYgKGltcFByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbihwcm92aWRlcik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEluc3RhbmNlKGFsZ29yaXRobSwgaW1wUHJvdmlkZXIpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydFBhdGhCdWlsZGVyfSBpbnN0YW5jZSBmcm9tIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBwcm92aWRlciBwcm92aWRpbmcgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHByb3ZpZGVyLgorICAgICAqIEByZXR1cm4gYSBidWlsZGVyIGZvciB0aGUgcmVxdWVzdGVkIGFsZ29yaXRobQorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBjYW5ub3QgcHJvdmlkZSB0aGUgYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBwcm92aWRlciA9PSBudWxsfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbGdvcml0aG0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ2VydFBhdGhCdWlsZGVyIGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sCisgICAgICAgICAgICBQcm92aWRlciBwcm92aWRlcikgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwcm92aWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFsZ29yaXRobSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBPYmplY3Qgc3BpID0gRU5HSU5FLmdldEluc3RhbmNlKGFsZ29yaXRobSwgcHJvdmlkZXIsIG51bGwpOworICAgICAgICByZXR1cm4gbmV3IENlcnRQYXRoQnVpbGRlcigoQ2VydFBhdGhCdWlsZGVyU3BpKSBzcGksIHByb3ZpZGVyLCBhbGdvcml0aG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEJ1aWxkcyBhIGNlcnRpZmljYXRpb24gcGF0aCB3aXRoIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1zCisgICAgICogICAgICAgICAgICB0aGUgYWxnb3JpdGhtIHBhcmFtZXRlcnMuCisgICAgICogQHJldHVybiB0aGUgYnVpbHQgY2VydGlmaWNhdGlvbiBwYXRoLgorICAgICAqIEB0aHJvd3MgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGJ1aWxkIGZhaWxzLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycyBjYW5ub3QgYmUgdXNlZCB0byBidWlsZCB3aXRoIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBidWlsZGVyLgorICAgICAqIEBzZWUgQ2VydFBhdGhCdWlsZGVyUmVzdWx0CisgICAgICovCisgICAgcHVibGljIGZpbmFsIENlcnRQYXRoQnVpbGRlclJlc3VsdCBidWlsZChDZXJ0UGF0aFBhcmFtZXRlcnMgcGFyYW1zKQorICAgICAgICAgICAgdGhyb3dzIENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZUJ1aWxkKHBhcmFtcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCB7QGNvZGUgQ2VydFBhdGhCdWlsZGVyfSB0eXBlIGZyb20gdGhlIDxpPlNlY3VyaXR5CisgICAgICogUHJvcGVydGllczwvaT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkZWZhdWx0IHtAY29kZSBDZXJ0UGF0aEJ1aWxkZXJ9IHR5cGUgZnJvbSB0aGUgPGk+U2VjdXJpdHkKKyAgICAgKiAgICAgICAgIFByb3BlcnRpZXM8L2k+LCBvciB0aGUgc3RyaW5nICJ7QGNvZGUgUEtJWH0iIGlmIGl0IGNhbm5vdCBiZQorICAgICAqICAgICAgICAgZGV0ZXJtaW5lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBnZXREZWZhdWx0VHlwZSgpIHsKKyAgICAgICAgU3RyaW5nIGRlZmF1bHRUeXBlID0gU2VjdXJpdHkuZ2V0UHJvcGVydHkoUFJPUEVSVFlOQU1FKTsKKyAgICAgICAgcmV0dXJuIChkZWZhdWx0VHlwZSAhPSBudWxsID8gZGVmYXVsdFR5cGUgOiBERUZBVUxUUFJPUEVSVFkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5YjNmOGYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb247CisKKy8qKgorICogVGhlIGV4Y2VwdGlvbiB0aGF0IGlzIHRocm93biB3aGVuIGEge0Bjb2RlIENlcnRQYXRoQnVpbGRlcn0gbWV0aG9kIGZhaWxzLgorICovCitwdWJsaWMgY2xhc3MgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uIGV4dGVuZHMgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDUzMTY0NzE0MjAxNzg3OTQ0MDJMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9ufSB3aXRoIHRoZSBzcGVjaWZpZWQgbWVzc2FnZQorICAgICAqIGFuZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgd2h5IHRoZSBidWlsZGluZyBvZiB0aGUgY2VydGlmaWNhdGlvbiBwYXRoIGZhaWxlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uKFN0cmluZyBtc2csIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtc2csIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgd2h5IHRoZSBidWlsZGluZyBvZiB0aGUgY2VydGlmaWNhdGlvbiBwYXRoIGZhaWxlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9ufSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGUgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24oU3RyaW5nIG1zZykgeworICAgICAgICBzdXBlcihtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoQnVpbGRlclJlc3VsdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aEJ1aWxkZXJSZXN1bHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NWRiNjEyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aEJ1aWxkZXJSZXN1bHQuamF2YQpAQCAtMCwwICsxLDM5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuY2VydDsKKworLyoqCisgKiBUaGUgaW50ZXJmYWNlIGZvciByZXN1bHRzIGdlbmVyYXRlZCBieQorICoge0BsaW5rIENlcnRQYXRoQnVpbGRlciNidWlsZChDZXJ0UGF0aFBhcmFtZXRlcnMpfS4KKyAqLworcHVibGljIGludGVyZmFjZSBDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQgZXh0ZW5kcyBDbG9uZWFibGUgeworCisgICAgLyoqCisgICAgICogQ2xvbmVzIHRoaXMge0Bjb2RlIENlcnRQYXRoQnVpbGRlclJlc3VsdH0gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb3B5IG9mIHRoaXMgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYnVpbHQge0Bjb2RlIENlcnRQYXRofSBpbnN0YW5jZS4gTmV2ZXIgcmV0dXJucyB7QGNvZGUgbnVsbH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBidWlsdCBjZXJ0aWZpY2F0ZSBwYXRoIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0UGF0aCBnZXRDZXJ0UGF0aCgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aEJ1aWxkZXJTcGkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhCdWlsZGVyU3BpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTA2ZDVkOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhCdWlsZGVyU3BpLmphdmEKQEAgLTAsMCArMSw0OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CisKKy8qKgorICogVGhlIDxpPlNlcnZpY2UgUHJvdmlkZXIgSW50ZXJmYWNlPC9pPiAoPGI+U1BJPC9iPikgZm9yIHRoZSB7QGNvZGUKKyAqIENlcnRQYXRoQnVpbGRlcn0gY2xhc3MgdG8gYmUgaW1wbGVtZW50ZWQgYnkgc2VjdXJpdHkgcHJvdmlkZXJzLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ2VydFBhdGhCdWlsZGVyU3BpIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENlcnRQYXRoQnVpbGRlclNwaX0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIENlcnRQYXRoQnVpbGRlclNwaSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBCdWlsZHMgYSBjZXJ0aWZpY2F0aW9uIHBhdGggd2l0aCB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobSBwYXJhbWV0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIGFsZ29yaXRobSBwYXJhbWV0ZXJzLgorICAgICAqIEByZXR1cm4gYSByZXN1bHQgb2YgdGhlIGJ1aWxkLgorICAgICAqIEB0aHJvd3MgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGJ1aWxkIGZhaWxzLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycyBjYW5ub3QgYmUgdXNlZCB0byBidWlsZCB0aGUgcGF0aAorICAgICAqICAgICAgICAgICAgIHdpdGggdGhpcyBidWlsZGVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQgZW5naW5lQnVpbGQoQ2VydFBhdGhQYXJhbWV0ZXJzIHBhcmFtcykKKyAgICAgICAgICAgIHRocm93cyBDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24sIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoUGFyYW1ldGVycy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aFBhcmFtZXRlcnMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYmQ5YjhhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aFBhcmFtZXRlcnMuamF2YQpAQCAtMCwwICsxLDM0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuY2VydDsKKworLyoqCisgKiBUaGUgaW50ZXJmYWNlIHNwZWNpZmljYXRpb24gZm9yIGNlcnRpZmljYXRpb24gcGF0aCBhbGdvcml0aG0gcGFyYW1ldGVycy4KKyAqIDxwPgorICogVGhpcyBpbnRlcmZhY2UgaXMgZm9yIGdyb3VwaW5nIHB1cnBvc2VzIG9mIHtAY29kZSBDZXJ0UGF0aH0gcGFyYW1ldGVyCisgKiBpbXBsZW1lbnRhdGlvbnMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQ2VydFBhdGhQYXJhbWV0ZXJzIGV4dGVuZHMgQ2xvbmVhYmxlIHsKKworICAgIC8qKgorICAgICAqIENsb25lcyB0aGlzIHtAY29kZSBDZXJ0UGF0aFBhcmFtZXRlcnN9IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2xvbmVkIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhWYWxpZGF0b3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhWYWxpZGF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42OWI5Zjk5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aFZhbGlkYXRvci5qYXZhCkBAIC0wLDAgKzEsMjA1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuZm9ydHJlc3MuRW5naW5lOworCisvKioKKyAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgdGhlIGZ1bmN0aW9uYWxpdHkgZm9yIHZhbGlkYXRpbmcgY2VydGlmaWNhdGlvbiBwYXRocworICogKGNlcnRpZmljYXRlIGNoYWlucykgZXN0YWJsaXNoaW5nIGEgdHJ1c3QgY2hhaW4gZnJvbSBhIGNlcnRpZmljYXRlIHRvIGEgdHJ1c3QKKyAqIGFuY2hvci4KKyAqLworcHVibGljIGNsYXNzIENlcnRQYXRoVmFsaWRhdG9yIHsKKyAgICAvLyBTdG9yZSBDZXJ0UGF0aFZhbGlkYXRvciBpbXBsZW1lbnRhdGlvbiBzZXJ2aWNlIG5hbWUKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VSVklDRSA9ICJDZXJ0UGF0aFZhbGlkYXRvciI7CisKKyAgICAvLyBVc2VkIHRvIGFjY2VzcyBjb21tb24gZW5naW5lIGZ1bmN0aW9uYWxpdHkKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFbmdpbmUgRU5HSU5FID0gbmV3IEVuZ2luZShTRVJWSUNFKTsKKworICAgIC8vIFN0b3JlIGRlZmF1bHQgcHJvcGVydHkgbmFtZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QRVJUWU5BTUUgPSAiY2VydHBhdGh2YWxpZGF0b3IudHlwZSI7CisKKyAgICAvLyBEZWZhdWx0IHZhbHVlIG9mIENlcnRQYXRoQnVpbGRlciB0eXBlLiBJdCByZXR1cm5zIGlmIGNlcnRwYXRoYnVpbGQudHlwZQorICAgIC8vIHByb3BlcnR5IGlzIG5vdCBkZWZpbmVkIGluIGphdmEuc2VjdXJpdHkgZmlsZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUUFJPUEVSVFkgPSAiUEtJWCI7CisKKyAgICAvLyBTdG9yZSB1c2VkIHByb3ZpZGVyCisgICAgcHJpdmF0ZSBmaW5hbCBQcm92aWRlciBwcm92aWRlcjsKKworICAgIC8vIFN0b3JlIHVzZWQgc3BpIGltcGxlbWVudGF0aW9uCisgICAgcHJpdmF0ZSBmaW5hbCBDZXJ0UGF0aFZhbGlkYXRvclNwaSBzcGlJbXBsOworCisgICAgLy8gU3RvcmUgdXNlZCBhbGdvcml0aG0gdmFsdWUKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBhbGdvcml0aG07CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0UGF0aFZhbGlkYXRvcn0gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsaWRhdG9yU3BpCisgICAgICogICAgICAgICAgICB0aGUgaW1wbGVtZW50YXRpb24gZGVsZWdhdGUuCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgc2VjdXJpdHkgcHJvdmlkZXIuCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ2VydFBhdGhWYWxpZGF0b3IoQ2VydFBhdGhWYWxpZGF0b3JTcGkgdmFsaWRhdG9yU3BpLAorICAgICAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIsIFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgdGhpcy5wcm92aWRlciA9IHByb3ZpZGVyOworICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICAgICAgdGhpcy5zcGlJbXBsID0gdmFsaWRhdG9yU3BpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNlcnRpZmljYXRpb24gcGF0aCBhbGdvcml0aG0gbmFtZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRpb24gcGF0aCBhbGdvcml0aG0gbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgcmV0dXJuIGFsZ29yaXRobTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzZWN1cml0eSBwcm92aWRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByb3ZpZGVyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBQcm92aWRlciBnZXRQcm92aWRlcigpIHsKKyAgICAgICAgcmV0dXJuIHByb3ZpZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgY2VydGlmaWNhdGlvbiBwYXRoIHZhbGlkYXRvciBmb3IgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgYWxnb3JpdGhtIG5hbWUuCisgICAgICogQHJldHVybiBhIGNlcnRpZmljYXRpb24gcGF0aCB2YWxpZGF0b3IgZm9yIHRoZSByZXF1ZXN0ZWQgYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgbm8gaW5zdGFsbGVkIHByb3ZpZGVyIHByb3ZpZGVzIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbGdvcml0aG0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ2VydFBhdGhWYWxpZGF0b3IgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIEVuZ2luZS5TcGlBbmRQcm92aWRlciBzYXAgPSBFTkdJTkUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBudWxsKTsKKyAgICAgICAgcmV0dXJuIG5ldyBDZXJ0UGF0aFZhbGlkYXRvcigoQ2VydFBhdGhWYWxpZGF0b3JTcGkpIHNhcC5zcGksIHNhcC5wcm92aWRlciwgYWxnb3JpdGhtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGNlcnRpZmljYXRpb24gcGF0aCB2YWxpZGF0b3IgZm9yIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtCisgICAgICogZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIGFsZ29yaXRobSBuYW1lLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHNlY3VyaXR5IHByb3ZpZGVyIG5hbWUuCisgICAgICogQHJldHVybiBhIGNlcnRpZmljYXRpb24gcGF0aCB2YWxpZGF0b3IgZm9yIHRoZSByZXF1ZXN0ZWQgYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBzZWN1cml0eSBwcm92aWRlciBjYW5ub3QgcHJvdmlkZSB0aGUKKyAgICAgKiAgICAgICAgICAgICByZXF1ZXN0ZWQgYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBwcm92aWRlciB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBjYW4gYmUgZm91bmQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFsZ29yaXRobSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHByb3ZpZGVyID09IG51bGwgfHwgcHJvdmlkZXIuaXNFbXB0eSgpfQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ2VydFBhdGhWYWxpZGF0b3IgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwKKyAgICAgICAgICAgIFN0cmluZyBwcm92aWRlcikgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwgfHwgcHJvdmlkZXIuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgUHJvdmlkZXIgaW1wUHJvdmlkZXIgPSBTZWN1cml0eS5nZXRQcm92aWRlcihwcm92aWRlcik7CisgICAgICAgIGlmIChpbXBQcm92aWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24ocHJvdmlkZXIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRJbnN0YW5jZShhbGdvcml0aG0sIGltcFByb3ZpZGVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGNlcnRpZmljYXRpb24gcGF0aCB2YWxpZGF0b3IgZm9yIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtCisgICAgICogZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIGFsZ29yaXRobSBuYW1lLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHNlY3VyaXR5IHByb3ZpZGVyIG5hbWUuCisgICAgICogQHJldHVybiBhIGNlcnRpZmljYXRpb24gcGF0aCB2YWxpZGF0b3IgZm9yIHRoZSByZXF1ZXN0ZWQgYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBjYW5ub3QgcHJvdmlkZSB0aGUgcmVxdWVzdGVkCisgICAgICogICAgICAgICAgICAgYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBwcm92aWRlciA9PSBudWxsfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbGdvcml0aG0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ2VydFBhdGhWYWxpZGF0b3IgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwKKyAgICAgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIE9iamVjdCBzcGkgPSBFTkdJTkUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBwcm92aWRlciwgbnVsbCk7CisgICAgICAgIHJldHVybiBuZXcgQ2VydFBhdGhWYWxpZGF0b3IoKENlcnRQYXRoVmFsaWRhdG9yU3BpKSBzcGksIHByb3ZpZGVyLCBhbGdvcml0aG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFZhbGlkYXRlcyB0aGUge0Bjb2RlIENlcnRQYXRofSB3aXRoIHRoZSBhbGdvcml0aG0gb2YgdGhpcyB7QGNvZGUKKyAgICAgKiBDZXJ0UGF0aFZhbGlkYXRvcn0gdXNpbmcgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0gcGFyYW1ldGVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjZXJ0UGF0aAorICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRpb24gcGF0aCB0byBiZSB2YWxpZGF0ZWQuCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRpb24gcGF0aCB2YWxpZGF0b3IgYWxnb3JpdGhtIHBhcmFtZXRlcnMuCisgICAgICogQHJldHVybiB0aGUgdmFsaWRhdGlvbiByZXN1bHQuCisgICAgICogQHRocm93cyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB2YWxpZGF0aW9uIGZhaWxzLCBvciB0aGUgYWxnb3JpdGhtIG9mIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgICAgICBjZXJ0aWZpY2F0aW9uIHBhdGggY2Fubm90IGJlIHZhbGlkYXRlZCB1c2luZyB0aGUgYWxnb3JpdGhtIG9mCisgICAgICogICAgICAgICAgICAgdGhpcyBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobSBwYXJhbWV0ZXJzIGNhbm5vdCBiZSB1c2VkIHdpdGgKKyAgICAgKiAgICAgICAgICAgICB0aGlzIGFsZ29yaXRobS4KKyAgICAgKiBAc2VlIENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0CisgICAgICovCisgICAgcHVibGljIGZpbmFsIENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0IHZhbGlkYXRlKENlcnRQYXRoIGNlcnRQYXRoLAorICAgICAgICAgICAgQ2VydFBhdGhQYXJhbWV0ZXJzIHBhcmFtcykgdGhyb3dzIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZVZhbGlkYXRlKGNlcnRQYXRoLCBwYXJhbXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQge0Bjb2RlIENlcnRQYXRoVmFsaWRhdG9yfSB0eXBlIGZyb20gdGhlIDxpPlNlY3VyaXR5CisgICAgICogUHJvcGVydGllczwvaT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkZWZhdWx0IHtAY29kZSBDZXJ0UGF0aFZhbGlkYXRvcn0gdHlwZSBmcm9tIHRoZSA8aT5TZWN1cml0eQorICAgICAqICAgICAgICAgUHJvcGVydGllczwvaT4sIG9yIHRoZSBzdHJpbmcge0Bjb2RlICJQS0lYIn0gaWYgaXQgY2Fubm90IGJlCisgICAgICogICAgICAgICBkZXRlcm1pbmVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGdldERlZmF1bHRUeXBlKCkgeworICAgICAgICBTdHJpbmcgZGVmYXVsdFR5cGUgPSBTZWN1cml0eS5nZXRQcm9wZXJ0eShQUk9QRVJUWU5BTUUpOworICAgICAgICByZXR1cm4gKGRlZmF1bHRUeXBlICE9IG51bGwgPyBkZWZhdWx0VHlwZSA6IERFRkFVTFRQUk9QRVJUWSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEyMzA5YjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwxMzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb247CisKKy8qKgorICogVGhlIGV4Y2VwdGlvbiB0aGF0IGlzIHRocm93biB3aGVuIGEgY2VydGlmaWNhdGlvbiBwYXRoIChvciBjZXJ0aWZpY2F0ZSBjaGFpbikKKyAqIGNhbm5vdCBiZSB2YWxpZGF0ZWQuCisgKiA8cD4KKyAqIEEge0Bjb2RlIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9ufSBtYXkgb3B0aW9uYWxseSBpbmNsdWRlIHRoZSBjZXJ0aWZpY2F0aW9uCisgKiBwYXRoIGluc3RhbmNlIHRoYXQgZmFpbGVkIHRoZSB2YWxpZGF0aW9uIGFuZCB0aGUgaW5kZXggb2YgdGhlIGZhaWxlZAorICogY2VydGlmaWNhdGUuCisgKi8KK3B1YmxpYyBjbGFzcyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbiBleHRlbmRzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzA4MzE4MDAxNDk3MTg5MzEzOUw7CisKKyAgICAvKioKKyAgICAgKiB0aGUgY2VydGlmaWNhdGlvbiBwYXRoLgorICAgICAqLworICAgIHByaXZhdGUgQ2VydFBhdGggY2VydFBhdGg7CisKKyAgICAvKioKKyAgICAgKiB0aGUgaW5kZXggb2YgdGhlIGNlcnRpZmljYXRlLgorICAgICAqLworICAgIHByaXZhdGUgaW50IGluZGV4ID0gLTE7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbn0gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogbWVzc2FnZSAsIGNhdXNlLCBjZXJ0aWZpY2F0aW9uIHBhdGggYW5kIGNlcnRpZmljYXRlIGluZGV4IGluIHRoZQorICAgICAqIGNlcnRpZmljYXRpb24gcGF0aC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgY2F1c2UuCisgICAgICogQHBhcmFtIGNlcnRQYXRoCisgICAgICogICAgICAgICAgICB0aGUgY2VydGlmaWNhdGlvbiBwYXRoIHRoYXQgZmFpbGVkIHRoZSB2YWxpZGF0aW9uLgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmYWlsZWQgY2VydGlmaWNhdGUuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY2VydFBhdGh9IGlzIHtAY29kZSBudWxsfSBhbmQgaW5kZXggaXMgbm90IHtAY29kZQorICAgICAqICAgICAgICAgICAgIC0xfS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY2VydFBhdGh9IGlzIG5vdCB7QGNvZGUgbnVsbH0gYW5kIGluZGV4IGlzIG5vdAorICAgICAqICAgICAgICAgICAgIHJlZmVyZW5jaW5nIGFuIGNlcnRpZmljYXRlIGluIHRoZSBjZXJ0aWZpY2F0aW9uIHBhdGguCisgICAgICovCisgICAgcHVibGljIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKFN0cmluZyBtc2csIFRocm93YWJsZSBjYXVzZSwKKyAgICAgICAgICAgIENlcnRQYXRoIGNlcnRQYXRoLCBpbnQgaW5kZXgpIHsKKyAgICAgICAgc3VwZXIobXNnLCBjYXVzZSk7CisgICAgICAgIC8vIGNoZWNrIGNlcnRQYXRoIGFuZCBpbmRleCBwYXJhbWV0ZXJzCisgICAgICAgIGlmICgoY2VydFBhdGggPT0gbnVsbCkgJiYgKGluZGV4ICE9IC0xKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW5kZXggc2hvdWxkIGJlIC0xIHdoZW4gQ2VydFBhdGggaXMgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmICgoY2VydFBhdGggIT0gbnVsbCkgJiYgKChpbmRleCA8IC0xKSB8fCAoaW5kZXggPj0gY2VydFBhdGguZ2V0Q2VydGlmaWNhdGVzKCkuc2l6ZSgpKSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5jZXJ0UGF0aCA9IGNlcnRQYXRoOworICAgICAgICB0aGlzLmluZGV4ID0gaW5kZXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIG1lc3NhZ2UgYW5kIGNhdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYXVzZSB3aHkgdGhlIHBhdGggY291bGQgbm90IGJlIHZhbGlkYXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24oU3RyaW5nIG1zZywgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKG1zZywgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9ufSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGNhdXNlIHdoeSB0aGUgcGF0aCBjb3VsZCBub3QgYmUgdmFsaWRhdGVkLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9ufSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24oU3RyaW5nIG1zZykgeworICAgICAgICBzdXBlcihtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2VydGlmaWNhdGlvbiBwYXRoIHRoYXQgZmFpbGVkIHZhbGlkYXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjZXJ0aWZpY2F0aW9uIHBhdGggdGhhdCBmYWlsZWQgdmFsaWRhdGlvbiwgb3Ige0Bjb2RlIG51bGx9IGlmCisgICAgICogICAgICAgICBub25lIHdhcyBzcGVjaWZpZWQuCisgICAgICovCisgICAgcHVibGljIENlcnRQYXRoIGdldENlcnRQYXRoKCkgeworICAgICAgICByZXR1cm4gY2VydFBhdGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZhaWxlZCBjZXJ0aWZpY2F0ZSBpbiB0aGUgY2VydGlmaWNhdGlvbiBwYXRoLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZhaWxlZCBjZXJ0aWZpY2F0ZSBpbiB0aGUgY2VydGlmaWNhdGlvbiBwYXRoLCBvcgorICAgICAqICAgICAgICAge0Bjb2RlIC0xfSBpZiBub25lIHdhcyBzcGVjaWZpZWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRJbmRleCgpIHsKKyAgICAgICAgcmV0dXJuIGluZGV4OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZTc0Mjg2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aFZhbGlkYXRvclJlc3VsdC5qYXZhCkBAIC0wLDAgKzEsMzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCisvKioKKyAqIFRoZSBpbnRlcmZhY2Ugc3BlY2lmaWNhdGlvbiBmb3IgY2VydGlmaWNhdGlvbiBwYXRoIHZhbGlkYXRpb24gcmVzdWx0cy4KKyAqIDxwPgorICogVGhpcyBpbnRlcmZhY2UgaXMgZm9yIGdyb3VwaW5nIHB1cnBvc2VzIG9mIHZhbGlkYXRpb24gcmVzdWx0IGltcGxlbWVudGF0aW9ucy4KKyAqLworcHVibGljIGludGVyZmFjZSBDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCBleHRlbmRzIENsb25lYWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBDbG9uZXMgdGhpcyB7QGNvZGUgQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHR9IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2xvbmVkIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhWYWxpZGF0b3JTcGkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhWYWxpZGF0b3JTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMTRlOGRkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aFZhbGlkYXRvclNwaS5qYXZhCkBAIC0wLDAgKzEsNTUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworCisvKioKKyAqIFRoZSA8aT5TZXJ2aWNlIFByb3ZpZGVyIEludGVyZmFjZTwvaT4gKDxiPlNQSTwvYj4pIGZvciB0aGUge0Bjb2RlCisgKiBDZXJ0UGF0aFZhbGlkYXRvcn0gY2xhc3MgdG8gYmUgaW1wbGVtZW50ZWQgYnkgc2VjdXJpdHkgcHJvdmlkZXJzLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ2VydFBhdGhWYWxpZGF0b3JTcGkgeworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydFBhdGhWYWxpZGF0b3JTcGl9IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0UGF0aFZhbGlkYXRvclNwaSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWYWxpZGF0ZXMgdGhlIHtAY29kZSBDZXJ0UGF0aH0gd2l0aCB0aGUgYWxnb3JpdGhtIG9mIHRoaXMge0Bjb2RlCisgICAgICogQ2VydFBhdGhWYWxpZGF0b3J9IHVzaW5nIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2VydFBhdGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0aW9uIHBhdGggdG8gYmUgdmFsaWRhdGVkLgorICAgICAqIEBwYXJhbSBwYXJhbXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0aW9uIHBhdGggdmFsaWRhdG9yIGFsZ29yaXRobSBwYXJhbWV0ZXJzLgorICAgICAqIEByZXR1cm4gdGhlIHZhbGlkYXRpb24gcmVzdWx0LgorICAgICAqIEB0aHJvd3MgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgdmFsaWRhdGlvbiBmYWlscywgb3IgdGhlIGFsZ29yaXRobSBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICAgICAgY2VydGlmaWNhdGlvbiBwYXRoIGNhbm5vdCBiZSB2YWxpZGF0ZWQgdXNpbmcgdGhlIGFsZ29yaXRobSBvZgorICAgICAqICAgICAgICAgICAgIHRoaXMgaW5zdGFuY2UuCisgICAgICogQHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0gcGFyYW1ldGVycyBjYW5ub3QgYmUgdXNlZCB3aXRoCisgICAgICogICAgICAgICAgICAgdGhpcyBhbGdvcml0aG0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0IGVuZ2luZVZhbGlkYXRlKENlcnRQYXRoIGNlcnRQYXRoLAorICAgICAgICAgICAgQ2VydFBhdGhQYXJhbWV0ZXJzIHBhcmFtcykgdGhyb3dzIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0U2VsZWN0b3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFNlbGVjdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWI5MWJiOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFNlbGVjdG9yLmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LmNlcnQ7CisKKy8qKgorICogVGhlIGludGVyZmFjZSBzcGVjaWZpY2F0aW9uIHRvIGRldGVybWluZSB3aGV0aGVyIGEge0Bjb2RlCisgKiBDZXJ0aWZpY2F0ZX0gbWVldHMgc29tZSBjcml0ZXJpYS4KKyAqIDxwPgorICogVGhlIGltcGxlbWVudGF0aW9ucyBvZiB0aGlzIGludGVyZmFjZSBhcmUgdHlwaWNhbGx5IHVzZWQgdG8gZGVmaW5lIHRoZQorICogY3JpdGVyaWEgZm9yIHNlbGVjdGluZyB7QGNvZGUgQ2VydGlmaWNhdGV9cyBmcm9tIGEge0Bjb2RlIENlcnRTdG9yZX0uCisgKgorICogQHNlZSBDZXJ0U3RvcmUKKyAqIEBzZWUgQ2VydGlmaWNhdGUKKyAqLworcHVibGljIGludGVyZmFjZSBDZXJ0U2VsZWN0b3IgZXh0ZW5kcyBDbG9uZWFibGUgeworCisgICAgLyoqCisgICAgICogQ2xvbmVzIHRoaXMge0Bjb2RlIENlcnRTZWxlY3Rvcn0gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjbG9uZWQgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGRlZmluZWQgY3JpdGVyaWEgb2YgdGhpcyBpbnN0YW5jZSBtYXRjaCB0aGUgc3BlY2lmaWVkCisgICAgICogY2VydGlmaWNhdGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2VydAorICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRlIHRvIGJlIGV2YWx1YXRlZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgY2VydGlmaWNhdGUgbWF0Y2hlcyB0aGUgY3JpdGVyaWEsIHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChDZXJ0aWZpY2F0ZSBjZXJ0KTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFN0b3JlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRTdG9yZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZjZGFlYTcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRTdG9yZS5qYXZhCkBAIC0wLDAgKzEsMjcyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuZm9ydHJlc3MuRW5naW5lOworCisvKioKKyAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgdGhlIGZ1bmN0aW9uYWxpdHkgdG8gcmV0cmlldmUge0Bjb2RlIENlcnRpZmljYXRlfXMgYW5kCisgKiB7QGNvZGUgQ1JMfXMgZnJvbSBhIHJlYWQtb25seSByZXBvc2l0b3J5LiBUaGlzIHJlcG9zaXRvcnkgbWF5IGJlIHZlcnkgbGFyZ2UKKyAqIGFuZCBtYXkgc3RvcmUgdHJ1c3RlZCBhcyB3ZWxsIGFzIHVudHJ1c3RlZCBjZXJ0aWZpY2F0ZXMuCisgKi8KK3B1YmxpYyBjbGFzcyBDZXJ0U3RvcmUgeworCisgICAgLy8gU3RvcmUgc3BpIGltcGxlbWVudGF0aW9uIHNlcnZpY2UgbmFtZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRVJWSUNFID0gIkNlcnRTdG9yZSI7CisKKyAgICAvLyBVc2VkIHRvIGFjY2VzcyBjb21tb24gZW5naW5lIGZ1bmN0aW9uYWxpdHkKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFbmdpbmUgRU5HSU5FID0gbmV3IEVuZ2luZShTRVJWSUNFKTsKKworICAgIC8vIFN0b3JlIGRlZmF1bHQgcHJvcGVydHkgbmFtZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QRVJUWU5BTUUgPSAiY2VydHN0b3JlLnR5cGUiOworCisgICAgLy8gRGVmYXVsdCB2YWx1ZSBvZiBDZXJ0U3RvcmUgdHlwZS4gSXQgcmV0dXJucyBpZiBjZXJ0cGF0aGJ1aWxkLnR5cGUKKyAgICAvLyBwcm9wZXJ0eSBpcyBub3QgZGVmaW5lZCBpbiBqYXZhLnNlY3VyaXR5IGZpbGUKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVFBST1BFUlRZID0gIkxEQVAiOworCisgICAgLy8gU3RvcmUgdXNlZCBwcm92aWRlcgorICAgIHByaXZhdGUgZmluYWwgUHJvdmlkZXIgcHJvdmlkZXI7CisKKyAgICAvLyBTdG9yZSBDZXJ0U3RvcmVTcGkgaW1wbGVtZW50YXRpb24KKyAgICBwcml2YXRlIGZpbmFsIENlcnRTdG9yZVNwaSBzcGlJbXBsOworCisgICAgLy8gU3RvcmUgdXNlZCB0eXBlCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgdHlwZTsKKworICAgIC8vIFN0b3JlIHVzZWQgcGFyYW1ldGVycworICAgIHByaXZhdGUgZmluYWwgQ2VydFN0b3JlUGFyYW1ldGVycyBjZXJ0U3RvcmVQYXJhbXM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0U3RvcmV9IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIHN0b3JlU3BpCisgICAgICogICAgICAgICAgICB0aGUgaW1wbGVtZW50YXRpb24gZGVsZWdhdGUuCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgc2VjdXJpdHkgcHJvdmlkZXIuCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZSBzdG9yZSB0eXBlLgorICAgICAqIEBwYXJhbSBwYXJhbXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZSBzdG9yZSBwYXJhbWV0ZXJzIChtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHByb3RlY3RlZCBDZXJ0U3RvcmUoQ2VydFN0b3JlU3BpIHN0b3JlU3BpLCBQcm92aWRlciBwcm92aWRlciwgU3RyaW5nIHR5cGUsCisgICAgICAgICAgICBDZXJ0U3RvcmVQYXJhbWV0ZXJzIHBhcmFtcykgeworICAgICAgICB0aGlzLnByb3ZpZGVyID0gcHJvdmlkZXI7CisgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgICAgIHRoaXMuc3BpSW1wbCA9IHN0b3JlU3BpOworICAgICAgICB0aGlzLmNlcnRTdG9yZVBhcmFtcyA9IHBhcmFtczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0U3RvcmV9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCB0eXBlIGFuZAorICAgICAqIGluaXRpYWxpemVkIHdpdGggdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZSBzdG9yZSB0eXBlLgorICAgICAqIEBwYXJhbSBwYXJhbXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZSBzdG9yZSBwYXJhbWV0ZXJzIChtYXkgYmUge0Bjb2RlIG51bGx9KS4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgY2VydGlmaWNhdGUgc3RvcmUgaW5zdGFuY2UuCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBwcm92aWRlciBjYW4gcHJvdmlkZSB0aGUgc3BlY2lmaWVkIGNlcnRpZmljYXRlIHN0b3JlCisgICAgICogICAgICAgICAgICAgdHlwZS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMgY2Fubm90IGJlIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGlzCisgICAgICogICAgICAgICAgICAgY2VydGlmaWNhdGUgc3RvcmUgaW5zdGFuY2UuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgdHlwZSA9PSBudWxsfQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ2VydFN0b3JlIGdldEluc3RhbmNlKFN0cmluZyB0eXBlLCBDZXJ0U3RvcmVQYXJhbWV0ZXJzIHBhcmFtcykKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAodHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgRW5naW5lLlNwaUFuZFByb3ZpZGVyIHNhcCA9IEVOR0lORS5nZXRJbnN0YW5jZSh0eXBlLCBwYXJhbXMpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBDZXJ0U3RvcmUoKENlcnRTdG9yZVNwaSkgc2FwLnNwaSwgc2FwLnByb3ZpZGVyLCB0eXBlLCBwYXJhbXMpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgVGhyb3dhYmxlIHRoID0gZS5nZXRDYXVzZSgpOworICAgICAgICAgICAgaWYgKHRoID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSwgdGgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydFN0b3JlfSBpbnN0YW5jZSBmcm9tIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgd2l0aAorICAgICAqIHRoZSBzcGVjaWZpZWQgdHlwZSBhbmQgaW5pdGlhbGl6ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRlIHN0b3JlIHR5cGUuCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRlIHN0b3JlIHBhcmFtZXRlcnMgKG1heSBiZSB7QGNvZGUgbnVsbH0pLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyLgorICAgICAqIEByZXR1cm4gdGhlIG5ldyBjZXJ0aWZpY2F0ZSBzdG9yZSBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgY2Fubm90IHByb3ZpZGUgdGhlIHJlcXVlc3RlZAorICAgICAqICAgICAgICAgICAgIGNlcnRpZmljYXRlIHN0b3JlIHR5cGUuCisgICAgICogQHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG5vIHByb3ZpZGVyIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGNhbiBiZSBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMgY2Fubm90IGJlIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGlzCisgICAgICogICAgICAgICAgICAgY2VydGlmaWNhdGUgc3RvcmUgaW5zdGFuY2UuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHByb3ZpZGVyID09IG51bGwgfHwgcHJvdmlkZXIuaXNFbXB0eSgpfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgdHlwZX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ2VydFN0b3JlIGdldEluc3RhbmNlKFN0cmluZyB0eXBlLAorICAgICAgICAgICAgQ2VydFN0b3JlUGFyYW1ldGVycyBwYXJhbXMsIFN0cmluZyBwcm92aWRlcikKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwcm92aWRlciA9PSBudWxsIHx8IHByb3ZpZGVyLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIFByb3ZpZGVyIGltcFByb3ZpZGVyID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXIocHJvdmlkZXIpOworICAgICAgICBpZiAoaW1wUHJvdmlkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uKHByb3ZpZGVyKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0SW5zdGFuY2UodHlwZSwgcGFyYW1zLCBpbXBQcm92aWRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydFN0b3JlfSBpbnN0YW5jZSBmcm9tIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgd2l0aAorICAgICAqIHRoZSBzcGVjaWZpZWQgdHlwZSBhbmQgaW5pdGlhbGl6ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMuCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZSBzdG9yZSB0eXBlLgorICAgICAqIEBwYXJhbSBwYXJhbXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZSBzdG9yZSBwYXJhbWV0ZXJzIChtYXkgYmUge0Bjb2RlIG51bGx9KS4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBwcm92aWRlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgY2VydGlmaWNhdGUgc3RvcmUgaW5zdGFuY2UuCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGNhbm5vdCBwcm92aWRlIHRoZSByZXF1ZXN0ZWQKKyAgICAgKiAgICAgICAgICAgICBjZXJ0aWZpY2F0ZSBzdG9yZSB0eXBlLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycyBjYW5ub3QgYmUgdXNlZCB0byBpbml0aWFsaXplIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBjZXJ0aWZpY2F0ZSBzdG9yZSBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgcHJvdmlkZXIgPT0gbnVsbH0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSB0eXBlID09IG51bGx9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDZXJ0U3RvcmUgZ2V0SW5zdGFuY2UoU3RyaW5nIHR5cGUsCisgICAgICAgICAgICBDZXJ0U3RvcmVQYXJhbWV0ZXJzIHBhcmFtcywgUHJvdmlkZXIgcHJvdmlkZXIpCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgT2JqZWN0IHNwaSA9IEVOR0lORS5nZXRJbnN0YW5jZSh0eXBlLCBwcm92aWRlciwgcGFyYW1zKTsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQ2VydFN0b3JlKChDZXJ0U3RvcmVTcGkpIHNwaSwgcHJvdmlkZXIsIHR5cGUsIHBhcmFtcyk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBUaHJvd2FibGUgdGggPSBlLmdldENhdXNlKCk7CisgICAgICAgICAgICBpZiAodGggPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpLCB0aCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjZXJ0aWZpY2F0ZSBzdG9yZSB0eXBlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2VydGlmaWNhdGUgc3RvcmUgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldFR5cGUoKSB7CisgICAgICAgIHJldHVybiB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNlY3VyaXR5IHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc2VjdXJpdHkgcHJvdmlkZXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFByb3ZpZGVyIGdldFByb3ZpZGVyKCkgeworICAgICAgICByZXR1cm4gcHJvdmlkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhlIGNlcnRpZmljYXRlIHN0b3JlIHBhcmFtZXRlcnMgdGhhdCB3ZXJlIHVzZWQgdG8KKyAgICAgKiBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGUgY2VydGlmaWNhdGUgc3RvcmUgcGFyYW1ldGVycyBvciB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiAgICAgICAgIG5vbmUgd2VyZSBzcGVjaWZpZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENlcnRTdG9yZVBhcmFtZXRlcnMgZ2V0Q2VydFN0b3JlUGFyYW1ldGVycygpIHsKKyAgICAgICAgaWYgKGNlcnRTdG9yZVBhcmFtcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiAoQ2VydFN0b3JlUGFyYW1ldGVycykgY2VydFN0b3JlUGFyYW1zLmNsb25lKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIHtAY29kZSBDZXJ0aWZpY2F0ZX1zIGZvciB0aGUgc3BlY2lmaWVkIHtAY29kZQorICAgICAqIENlcnRTZWxlY3Rvcn0gZnJvbSB0aGlzIGNlcnRpZmljYXRlIHN0b3JlLgorICAgICAqCisgICAgICogQHBhcmFtIHNlbGVjdG9yCisgICAgICogICAgICAgICAgICB0aGUgc2VsZWN0b3IgY29udGFpbmluZyB0aGUgY3JpdGVyaWEgdG8gc2VhcmNoIGZvcgorICAgICAqICAgICAgICAgICAgY2VydGlmaWNhdGVzIGluIHRoaXMgY2VydGlmaWNhdGUgc3RvcmUuCisgICAgICogQHJldHVybiB0aGUgbGlzdCBvZiB7QGNvZGUgQ2VydGlmaWNhdGV9cyB0aGF0IG1hdGNoIHRoZSBjcml0ZXJpYSBvZiB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBzZWxlY3Rvci4KKyAgICAgKiBAdGhyb3dzIENlcnRTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVycm9yKHMpIG9jY3VyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDZXJ0aWZpY2F0ZT4gZ2V0Q2VydGlmaWNhdGVzKENlcnRTZWxlY3RvciBzZWxlY3RvcikKKyAgICAgICAgICAgIHRocm93cyBDZXJ0U3RvcmVFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVHZXRDZXJ0aWZpY2F0ZXMoc2VsZWN0b3IpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxpc3Qgb2Yge0Bjb2RlIENSTH1zIGZvciB0aGUgc3BlY2lmaWVkIHtAY29kZSBDUkxTZWxlY3Rvcn0KKyAgICAgKiBmcm9tIHRoaXMgY2VydGlmaWNhdGUgc3RvcmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2VsZWN0b3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWxlY3RvciBjb250YWluaW5nIHRoZSBjcml0ZXJpYSB0byBzZWFyY2ggZm9yIGNlcnRpZmljYXRlCisgICAgICogICAgICAgICAgICByZXZvY2F0aW9uIGxpc3RzIGluIHRoaXMgc3RvcmUuCisgICAgICogQHJldHVybiB0aGUgbGlzdCBvZiB7QGNvZGUgQ1JMfXMgdGhhdCBtYXRjaCB0aGUgY3JpdGVyaWEgb2YgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgc2VsZWN0b3IKKyAgICAgKiBAdGhyb3dzIENlcnRTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVycm9yKHMpIG9jY3VyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDUkw+IGdldENSTHMoQ1JMU2VsZWN0b3Igc2VsZWN0b3IpCisgICAgICAgICAgICB0aHJvd3MgQ2VydFN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lR2V0Q1JMcyhzZWxlY3Rvcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCB7QGNvZGUgQ2VydFN0b3JlfSB0eXBlIGZyb20gdGhlIDxpPlNlY3VyaXR5CisgICAgICogUHJvcGVydGllczwvaT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkZWZhdWx0IHtAY29kZSBDZXJ0U3RvcmV9IHR5cGUgZnJvbSB0aGUgPGk+U2VjdXJpdHkKKyAgICAgKiAgICAgICAgIFByb3BlcnRpZXM8L2k+LCBvciB0aGUgc3RyaW5nIHtAY29kZSAiTERBUCJ9IGlmIGl0IGNhbm5vdCBiZQorICAgICAqICAgICAgICAgZGV0ZXJtaW5lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBnZXREZWZhdWx0VHlwZSgpIHsKKyAgICAgICAgU3RyaW5nIGRlZmF1bHRUeXBlID0gU2VjdXJpdHkuZ2V0UHJvcGVydHkoUFJPUEVSVFlOQU1FKTsKKyAgICAgICAgcmV0dXJuIChkZWZhdWx0VHlwZSA9PSBudWxsID8gREVGQVVMVFBST1BFUlRZIDogZGVmYXVsdFR5cGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFN0b3JlRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRTdG9yZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRmYjU0NDUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRTdG9yZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb247CisKKy8qKgorICogVGhlIGV4Y2VwdGlvbiB0aGF0IGlzIHRocm93biB3aGVuIGFuIGFjY2VzcyB0byBhIHtAY29kZSBDZXJ0U3RvcmV9IGZhaWxzLgorICovCitwdWJsaWMgY2xhc3MgQ2VydFN0b3JlRXhjZXB0aW9uIGV4dGVuZHMgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDIzOTUyOTYxMDc0NzE1NzMyNDVMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydFN0b3JlRXhjZXB0aW9ufSB3aXRoIHRoZSBzcGVjaWZpZWQgbWVzc2FnZSBhbmQKKyAgICAgKiBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgY2F1c2Ugd2h5IHRoZSBhY2Nlc3MgdG8gdGhlIGNlcnRpZmljYXRlIHN0b3JlIGZhaWxlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydFN0b3JlRXhjZXB0aW9uKFN0cmluZyBtc2csIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtc2csIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0U3RvcmVFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGNhdXNlIHdoeSB0aGUgYWNjZXNzIHRvIHRoZSBjZXJ0aWZpY2F0ZSBzdG9yZSBmYWlsZWQuCisgICAgICovCisgICAgcHVibGljIENlcnRTdG9yZUV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENlcnRTdG9yZUV4Y2VwdGlvbn0gd2l0aCB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0U3RvcmVFeGNlcHRpb24oU3RyaW5nIG1zZykgeworICAgICAgICBzdXBlcihtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENlcnRTdG9yZUV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIENlcnRTdG9yZUV4Y2VwdGlvbigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRTdG9yZVBhcmFtZXRlcnMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFN0b3JlUGFyYW1ldGVycy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdhOTlkODMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRTdG9yZVBhcmFtZXRlcnMuamF2YQpAQCAtMCwwICsxLDMyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuY2VydDsKKworLyoqCisgKiBUaGUgbWFya2VyIGludGVyZmFjZSBzcGVjaWZ5aW5nIHRoZSBwYXJhbWV0ZXJzIHVzZWQgdG8gaW5pdGlhbGl6ZSBhIHtAY29kZQorICogQ2VydFN0b3JlfSBpbnN0YW5jZS4KKyAqLworcHVibGljIGludGVyZmFjZSBDZXJ0U3RvcmVQYXJhbWV0ZXJzIGV4dGVuZHMgQ2xvbmVhYmxlIHsKKworICAgIC8qKgorICAgICAqIENsb25lcyB0aGlzIHtAY29kZSBDZXJ0U3RvcmVQYXJhbWV0ZXJzfSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNsb25lZCBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRTdG9yZVNwaS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0U3RvcmVTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xODgwMTM2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0U3RvcmVTcGkuamF2YQpAQCAtMCwwICsxLDcxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKKworLyoqCisgKiBUaGUgPGk+U2VydmljZSBQcm92aWRlciBJbnRlcmZhY2U8L2k+ICg8Yj5TUEk8L2I+KSBkZWZpbml0aW9uIGZvciB0aGUge0Bjb2RlCisgKiBDZXJ0U3RvcmV9IGNsYXNzIHRvIGJlIGltcGxlbWVudGVkIGJ5IHNlY3VyaXR5IHByb3ZpZGVycy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIENlcnRTdG9yZVNwaSB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0U3RvcmVTcGl9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWxpemF0aW9uIHBhcmFtZXRlcnMuCisgICAgICogQHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBpbml0aWFsaXphdGlvbiBwYXJhbWV0ZXJzIGNhbm5vdCBiZSB1c2VkIHRvCisgICAgICogICAgICAgICAgICAgaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0U3RvcmVTcGkoQ2VydFN0b3JlUGFyYW1ldGVycyBwYXJhbXMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGlzdCBvZiB7QGNvZGUgQ2VydGlmaWNhdGV9cyBmb3IgdGhlIHNwZWNpZmllZCB7QGNvZGUKKyAgICAgKiBDZXJ0U2VsZWN0b3J9IGZyb20gdGhpcyBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzZWxlY3RvcgorICAgICAqICAgICAgICAgICAgdGhlIHNlbGVjdG9yIGNvbnRhaW5pbmcgdGhlIGNyaXRlcmlhIHRvIHNlYXJjaCBmb3IKKyAgICAgKiAgICAgICAgICAgIGNlcnRpZmljYXRlcyBpbiB0aGlzIGluc3RhbmNlLgorICAgICAqIEByZXR1cm4gdGhlIGxpc3Qgb2Yge0Bjb2RlIENlcnRpZmljYXRlfXMgdGhhdCBtYXRjaCB0aGUgY3JpdGVyaWEgb2YgdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgc2VsZWN0b3IuCisgICAgICogQHRocm93cyBDZXJ0U3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBlcnJvcihzKSBvY2N1ci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQ29sbGVjdGlvbjw/IGV4dGVuZHMgQ2VydGlmaWNhdGU+IGVuZ2luZUdldENlcnRpZmljYXRlcyhDZXJ0U2VsZWN0b3Igc2VsZWN0b3IpCisgICAgICAgICAgICB0aHJvd3MgQ2VydFN0b3JlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGlzdCBvZiB7QGNvZGUgQ1JMfXMgZm9yIHRoZSBzcGVjaWZpZWQge0Bjb2RlIENSTFNlbGVjdG9yfQorICAgICAqIGZyb20gdGhpcyBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzZWxlY3RvcgorICAgICAqICAgICAgICAgICAgdGhlIHNlbGVjdG9yIGNvbnRhaW5pbmcgdGhlIGNyaXRlcmlhIHRvIHNlYXJjaCBmb3IgY2VydGlmaWNhdGUKKyAgICAgKiAgICAgICAgICAgIHJldm9jYXRpb24gbGlzdHMgaW4gaW5zdGFuY2UuCisgICAgICogQHJldHVybiB0aGUgbGlzdCBvZiB7QGNvZGUgQ1JMfXMgdGhhdCBtYXRjaCB0aGUgY3JpdGVyaWEgb2YgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgc2VsZWN0b3IKKyAgICAgKiBAdGhyb3dzIENlcnRTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVycm9yKHMpIG9jY3VyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDUkw+IGVuZ2luZUdldENSTHMoQ1JMU2VsZWN0b3Igc2VsZWN0b3IpCisgICAgICAgICAgICB0aHJvd3MgQ2VydFN0b3JlRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE1YzFkYmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlLmphdmEKQEAgLTAsMCArMSwyNTMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUZpZWxkOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogQWJzdHJhY3QgY2xhc3MgdG8gcmVwcmVzZW50IGlkZW50aXR5IGNlcnRpZmljYXRlcy4gSXQgcmVwcmVzZW50cyBhIHdheSB0bworICogdmVyaWZ5IHRoZSBiaW5kaW5nIG9mIGEgUHJpbmNpcGFsIGFuZCBpdHMgcHVibGljIGtleS4gRXhhbXBsZXMgYXJlIFguNTA5LAorICogUEdQLCBhbmQgU0RTSS4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIENlcnRpZmljYXRlIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0zNTg1NDQwNjAxNjA1NjY2Mjc3TDsKKworICAgIC8vIFRoZSBzdGFuZGFyZCBuYW1lIG9mIHRoZSBjZXJ0aWZpY2F0ZSB0eXBlCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgdHlwZTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENlcnRpZmljYXRlfSB3aXRoIHRoZSBzcGVjaWZpZWQgdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgIHRoZSBjZXJ0aWZpY2F0ZSB0eXBlLgorICAgICAqLworICAgIHByb3RlY3RlZCBDZXJ0aWZpY2F0ZShTdHJpbmcgdHlwZSkgeworICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNlcnRpZmljYXRlIHR5cGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjZXJ0aWZpY2F0ZSB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0VHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIGFyZ3VtZW50IHRvIHRoZSBjZXJ0aWZpY2F0ZSwgYW5kIHJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoZXkKKyAgICAgKiByZXByZXNlbnQgdGhlIDxlbT5zYW1lPC9lbT4gb2JqZWN0IHVzaW5nIGEgY2xhc3Mgc3BlY2lmaWMgY29tcGFyaXNvbi4gVGhlCisgICAgICogaW1wbGVtZW50YXRpb24gaW4gT2JqZWN0IHJldHVybnMge0Bjb2RlIHRydWV9IG9ubHkgaWYgdGhlIGFyZ3VtZW50IGlzIHRoZQorICAgICAqIGV4YWN0IHNhbWUgb2JqZWN0IGFzIHRoZSBjYWxsZWUgKD09KS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdGhlcgorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHdpdGggdGhpcyBvYmplY3QuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIG9iamVjdCBpcyB0aGUgc2FtZSBhcyB0aGlzIG9iamVjdCwge0Bjb2RlCisgICAgICogICAgICAgICBmYWxzZX0gaWYgaXQgaXMgZGlmZmVyZW50IGZyb20gdGhpcyBvYmplY3QuCisgICAgICogQHNlZSAjaGFzaENvZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG90aGVyKSB7CisgICAgICAgIC8vIG9iaiBlcXVhbCB0byBpdHNlbGYKKyAgICAgICAgaWYgKHRoaXMgPT0gb3RoZXIpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIENlcnRpZmljYXRlKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgZW5jb2RlZCBmb3JtcyBtYXRjaAorICAgICAgICAgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKHRoaXMuZ2V0RW5jb2RlZCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgKChDZXJ0aWZpY2F0ZSlvdGhlcikuZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGludGVnZXIgaGFzaCBjb2RlIGZvciB0aGUgY2VydGlmaWNhdGUuIEFueSB0d28gb2JqZWN0cyB3aGljaAorICAgICAqIHJldHVybiB7QGNvZGUgdHJ1ZX0gd2hlbiBwYXNzZWQgdG8ge0Bjb2RlIGVxdWFsc30gbXVzdCByZXR1cm4gdGhlIHNhbWUKKyAgICAgKiB2YWx1ZSBmb3IgdGhpcyBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjZXJ0aWZpY2F0ZSdzIGhhc2gKKyAgICAgKiBAc2VlICNlcXVhbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnl0ZVtdIGVuY29kZWQgPSBnZXRFbmNvZGVkKCk7CisgICAgICAgICAgICBpbnQgaGFzaCA9IDA7CisgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8ZW5jb2RlZC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGhhc2ggKz0gaSplbmNvZGVkW2ldOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGhhc2g7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBlbmNvZGVkIHJlcHJlc2VudGF0aW9uIGZvciB0aGlzIGNlcnRpZmljYXRlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZW5jb2RlZCByZXByZXNlbnRhdGlvbiBmb3IgdGhpcyBjZXJ0aWZpY2F0ZS4KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZW5jb2RpbmcgZmFpbHMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJ5dGVbXSBnZXRFbmNvZGVkKCkgdGhyb3dzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBWZXJpZmllcyB0aGF0IHRoaXMgY2VydGlmaWNhdGUgd2FzIHNpZ25lZCB3aXRoIHRoZSBnaXZlbiBwdWJsaWMga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgUHVibGljS2V5IHB1YmxpYyBrZXkgZm9yIHdoaWNoIHZlcmlmaWNhdGlvbiBzaG91bGQgYmUKKyAgICAgKiAgICAgICAgICAgIHBlcmZvcm1lZC4KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZW5jb2RpbmcgZXJyb3JzIGFyZSBkZXRlY3RlZC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIHVuc3VwcG9ydGVkIGFsZ29yaXRobSBpcyBkZXRlY3RlZC4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBpbnZhbGlkIGtleSBpcyBkZXRlY3RlZC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgbm8gZGVmYXVsdCBwcm92aWRlci4KKyAgICAgKiBAdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHNpZ25hdHVyZSBlcnJvcnMgYXJlIGRldGVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5KQorICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sCisgICAgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICAgICBJbnZhbGlkS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICAgICBTaWduYXR1cmVFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBWZXJpZmllcyB0aGF0IHRoaXMgY2VydGlmaWNhdGUgd2FzIHNpZ25lZCB3aXRoIHRoZSBnaXZlbiBwdWJsaWMga2V5LiBJdAorICAgICAqIFVzZXMgdGhlIHNpZ25hdHVyZSBhbGdvcml0aG0gZ2l2ZW4gYnkgdGhlIHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgUHVibGljS2V5IHB1YmxpYyBrZXkgZm9yIHdoaWNoIHZlcmlmaWNhdGlvbiBzaG91bGQgYmUKKyAgICAgKiAgICAgICAgICAgIHBlcmZvcm1lZC4KKyAgICAgKiBAcGFyYW0gc2lnUHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIFN0cmluZyB0aGUgbmFtZSBvZiB0aGUgc2lnbmF0dXJlIHByb3ZpZGVyLgorICAgICAqIEBleGNlcHRpb24gQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBlbmNvZGluZyBlcnJvcnMgYXJlIGRldGVjdGVkLgorICAgICAqIEBleGNlcHRpb24gTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW4gdW5zdXBwb3J0ZWQgYWxnb3JpdGhtIGlzIGRldGVjdGVkLgorICAgICAqIEBleGNlcHRpb24gSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGFuIGludmFsaWQga2V5IGlzIGRldGVjdGVkLgorICAgICAqIEBleGNlcHRpb24gTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGRvZXMgbm90IGV4aXN0cy4KKyAgICAgKiBAZXhjZXB0aW9uIFNpZ25hdHVyZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHNpZ25hdHVyZSBlcnJvcnMgYXJlIGRldGVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5LCBTdHJpbmcgc2lnUHJvdmlkZXIpCisgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24sCisgICAgICAgICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgIFNpZ25hdHVyZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIGNvbmNpc2UsIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIG9mIHRoZQorICAgICAqIGNlcnRpZmljYXRlLgorICAgICAqCisgICAgICogQHJldHVybiBhIHByaW50YWJsZSByZXByZXNlbnRhdGlvbiBmb3IgdGhlIGNlcnRpZmljYXRlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgdG9TdHJpbmcoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHB1YmxpYyBrZXkgY29ycmVzcG9uZGluZyB0byB0aGlzIGNlcnRpZmljYXRlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHVibGljIGtleSBjb3JyZXNwb25kaW5nIHRvIHRoaXMgY2VydGlmaWNhdGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFB1YmxpY0tleSBnZXRQdWJsaWNLZXkoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYWx0ZXJuYXRlIG9iamVjdCB0byBiZSBzZXJpYWxpemVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgb2JqZWN0IHRvIHNlcmlhbGl6ZS4KKyAgICAgKiBAdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjcmVhdGlvbiBvZiB0aGUgYWx0ZXJuYXRlIG9iamVjdCBmYWlscy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgT2JqZWN0IHdyaXRlUmVwbGFjZSgpIHRocm93cyBPYmplY3RTdHJlYW1FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBDZXJ0aWZpY2F0ZVJlcChnZXRUeXBlKCksIGdldEVuY29kZWQoKSk7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbigiQ291bGQgbm90IGNyZWF0ZSBzZXJpYWxpemF0aW9uIG9iamVjdDogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGFsdGVybmF0ZSB7QGNvZGUgU2VyaWFsaXphYmxlfSBjbGFzcyB0byBiZSB1c2VkIGZvciBzZXJpYWxpemF0aW9uIGFuZAorICAgICAqIGRlc2VyaWFsaXphdGlvbiBvZiB7QGNvZGUgQ2VydGlmaWNhdGV9IG9iamVjdHMuCisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBjbGFzcyBDZXJ0aWZpY2F0ZVJlcCBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTg1NjM3NTg5NDA0OTU2NjAwMjBMOworICAgICAgICAvLyBUaGUgc3RhbmRhcmQgbmFtZSBvZiB0aGUgY2VydGlmaWNhdGUgdHlwZQorICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyB0eXBlOworICAgICAgICAvLyBUaGUgY2VydGlmaWNhdGUgZGF0YQorICAgICAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBkYXRhOworCisgICAgICAgIC8vIEZvcmNlIGRlZmF1bHQgc2VyaWFsaXphdGlvbiB0byB1c2Ugd3JpdGVVbnNoYXJlZC9yZWFkVW5zaGFyZWQKKyAgICAgICAgLy8gZm9yIHRoZSBjZXJ0aWZpY2F0ZSBkYXRhCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFN0cmVhbUZpZWxkW10gc2VyaWFsUGVyc2lzdGVudEZpZWxkcyA9IHsKKyAgICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInR5cGUiLCBTdHJpbmcuY2xhc3MpLAorICAgICAgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiZGF0YSIsIGJ5dGVbXS5jbGFzcywgdHJ1ZSkKKyAgICAgICAgfTsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydGlmaWNhdGVSZXB9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAgICAgKiBjZXJ0aWZpY2F0ZSB0eXBlIGFuZCBlbmNvZGVkIGRhdGEuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSB0eXBlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRlIHR5cGUuCisgICAgICAgICAqIEBwYXJhbSBkYXRhCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGVuY29kZWQgZGF0YS4KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBDZXJ0aWZpY2F0ZVJlcChTdHJpbmcgdHlwZSwgYnl0ZVtdIGRhdGEpIHsKKyAgICAgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgICAgICAgICB0aGlzLmRhdGEgPSBkYXRhOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIERlc2VyaWFsaXplcyBhIHtAY29kZSBDZXJ0aWZpY2F0ZX0gZnJvbSBhIHNlcmlhbGl6ZWQge0Bjb2RlCisgICAgICAgICAqIENlcnRpZmljYXRlUmVwfSBvYmplY3QuCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gdGhlIGRlc2VyaWFsaXplZCB7QGNvZGUgQ2VydGlmaWNhdGV9LgorICAgICAgICAgKiBAdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiBkZXNlcmlhbGl6YXRpb24gZmFpbHMuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgT2JqZWN0IHJlYWRSZXNvbHZlKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSh0eXBlKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSkpOworICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uKCJDb3VsZCBub3QgcmVzb2x2ZSBjZXJ0aWZpY2F0ZTogIiArIHQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYWJlYmM5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw2OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LmNlcnQ7CisKKy8qKgorICogVGhlIGV4Y2VwdGlvbiB0aGF0IGlzIHRocm93biB3aGVuIGFuIGVycm9yIG9jY3VycyB3aGlsZSBhIHtAY29kZSBDZXJ0aWZpY2F0ZX0KKyAqIGlzIGJlaW5nIGVuY29kZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIGV4dGVuZHMgQ2VydGlmaWNhdGVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjIxOTQ5Mjg1MTU4OTQ0OTE2Mkw7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9ufSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgVGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGUgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKKyAgICAgICAgc3VwZXIobXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9ufSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBtZXNzYWdlIGFuZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24uCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgY2F1c2UuCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbn0gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYXVzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYmYxZTNmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb247CisKKy8qKgorICogVGhlIGJhc2UgY2xhc3MgZm9yIGFsbCB7QGNvZGUgQ2VydGlmaWNhdGV9IHJlbGF0ZWQgZXhjZXB0aW9ucy4KKyAqLworcHVibGljIGNsYXNzIENlcnRpZmljYXRlRXhjZXB0aW9uIGV4dGVuZHMgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDMxOTI1MzUyNTM3OTcxMTk3OThMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydGlmaWNhdGVFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGUgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydGlmaWNhdGVFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbn0gd2l0aCB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UgYW5kCisgICAgICogY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGUgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGNhdXNlLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UsIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbn0gd2l0aCB0aGUgc3BlY2lmaWVkIGNhdXNlLgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgY2F1c2UKKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVFeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMjRiMTcxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuY2VydDsKKworLyoqCisgKiBUaGUgZXhjZXB0aW9uIHRoYXQgaXMgdGhyb3duIHdoZW4gYSB7QGNvZGUgQ2VydGlmaWNhdGV9IGhhcyBleHBpcmVkLgorICovCitwdWJsaWMgY2xhc3MgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uIGV4dGVuZHMgQ2VydGlmaWNhdGVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gOTA3MTAwMTMzOTY5MTUzMzc3MUw7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVGYWN0b3J5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFhYWMxYTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMzA5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5mb3J0cmVzcy5FbmdpbmU7CisKKworLyoqCisgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgdGhlIGZ1bmN0aW9uYWxpdHkgb2YgYSBjZXJ0aWZpY2F0ZSBmYWN0b3J5IGFsZ29yaXRobSwKKyAqIHJlbHlpbmcgb24gcGFyc2luZyBhIHN0cmVhbSBvZiBieXRlcy4KKyAqIDxwPgorICogSXQgZGVmaW5lcyBtZXRob2RzIGZvciBwYXJzaW5nIGNlcnRpZmljYXRlIGNoYWlucyAoY2VydGlmaWNhdGUgcGF0aHMpIGFuZAorICogPGk+Q2VydGlmaWNhdGUgUmV2b2NhdGlvbiBMaXN0czwvaT4gKENSTHMpLgorICovCitwdWJsaWMgY2xhc3MgQ2VydGlmaWNhdGVGYWN0b3J5IHsKKworICAgIC8vIFN0b3JlIENlcnRpZmljYXRlRmFjdG9yeSBzZXJ2aWNlIG5hbWUKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VSVklDRSA9ICJDZXJ0aWZpY2F0ZUZhY3RvcnkiOworCisgICAgLy8gVXNlZCB0byBhY2Nlc3MgY29tbW9uIGVuZ2luZSBmdW5jdGlvbmFsaXR5CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRW5naW5lIEVOR0lORSA9IG5ldyBFbmdpbmUoU0VSVklDRSk7CisKKyAgICAvLyBTdG9yZSB1c2VkIHByb3ZpZGVyCisgICAgcHJpdmF0ZSBmaW5hbCBQcm92aWRlciBwcm92aWRlcjsKKworICAgIC8vIFN0b3JlIHVzZWQgQ2VydGlmaWNhdGVGYWN0b3J5U3BpIGltcGxlbWVudGF0aW9uCisgICAgcHJpdmF0ZSBmaW5hbCBDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkgc3BpSW1wbDsKKworICAgIC8vIFN0b3JlIHVzZWQgdHlwZQorICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHR5cGU7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZUZhY3Rvcnl9IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIGNlcnRGYWNTcGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbXBsZW1lbnRhdGlvbiBkZWxlZ2F0ZS4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBhc3NvY2lhdGVkIHByb3ZpZGVyLgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgY2VydGlmaWNhdGUgdHlwZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ2VydGlmaWNhdGVGYWN0b3J5KENlcnRpZmljYXRlRmFjdG9yeVNwaSBjZXJ0RmFjU3BpLAorICAgICAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIsIFN0cmluZyB0eXBlKSB7CisgICAgICAgIHRoaXMucHJvdmlkZXIgPSBwcm92aWRlcjsKKyAgICAgICAgdGhpcy50eXBlID0gdHlwZTsKKyAgICAgICAgdGhpcy5zcGlJbXBsID0gY2VydEZhY1NwaTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZUZhY3Rvcnl9IGluc3RhbmNlIHRoYXQgcHJvdmlkZXMgdGhlCisgICAgICogcmVxdWVzdGVkIGNlcnRpZmljYXRlIHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRlIHR5cGUuCisgICAgICogQHJldHVybiB0aGUgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZUZhY3Rvcnl9IGluc3RhbmNlLgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGNlcnRpZmljYXRlIHR5cGUgaXMgbm90IGF2YWlsYWJsZSBhdCBhbnkKKyAgICAgKiAgICAgICAgICAgICBpbnN0YWxsZWQgcHJvdmlkZXIuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgdHlwZSA9PSBudWxsfQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2VydGlmaWNhdGVGYWN0b3J5IGdldEluc3RhbmNlKFN0cmluZyB0eXBlKQorICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHR5cGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVuZ2luZS5TcGlBbmRQcm92aWRlciBzYXAgPSBFTkdJTkUuZ2V0SW5zdGFuY2UodHlwZSwgbnVsbCk7CisgICAgICAgICAgICByZXR1cm4gbmV3IENlcnRpZmljYXRlRmFjdG9yeSgoQ2VydGlmaWNhdGVGYWN0b3J5U3BpKSBzYXAuc3BpLCBzYXAucHJvdmlkZXIsIHR5cGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydGlmaWNhdGVGYWN0b3J5fSBpbnN0YW5jZSBmcm9tIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBwcm92aWRlciB0aGF0IHByb3ZpZGVzIHRoZSByZXF1ZXN0ZWQgY2VydGlmaWNhdGUgdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgY2VydGlmaWNhdGUgdHlwZS4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBwcm92aWRlciBwcm92aWRpbmcgY2VydGlmaWNhdGVzIG9mIHRoZQorICAgICAqICAgICAgICAgICAgc3BlY2lmaWVkIHR5cGUuCisgICAgICogQHJldHVybiB0aGUgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZUZhY3Rvcnl9IGluc3RhbmNlLgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGNlcnRpZmljYXRlIHR5cGUgaXMgbm90IGF2YWlsYWJsZSBieSB0aGUKKyAgICAgKiAgICAgICAgICAgICBzcGVjaWZpZWQgcHJvdmlkZXIuCisgICAgICogQHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG5vIHByb3ZpZGVyIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGNhbiBiZSBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgcHJvdmlkZXIgPT0gbnVsbCB8fCBwcm92aWRlci5pc0VtcHR5KCl9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGl0IHtAY29kZSB0eXBlfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDZXJ0aWZpY2F0ZUZhY3RvcnkgZ2V0SW5zdGFuY2UoU3RyaW5nIHR5cGUsCisgICAgICAgICAgICBTdHJpbmcgcHJvdmlkZXIpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwgfHwgcHJvdmlkZXIuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgUHJvdmlkZXIgaW1wUHJvdmlkZXIgPSBTZWN1cml0eS5nZXRQcm92aWRlcihwcm92aWRlcik7CisgICAgICAgIGlmIChpbXBQcm92aWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24ocHJvdmlkZXIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRJbnN0YW5jZSh0eXBlLCBpbXBQcm92aWRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydGlmaWNhdGVGYWN0b3J5fSBpbnN0YW5jZSBmcm9tIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBwcm92aWRlciB0aGF0IHByb3ZpZGVzIHRoZSByZXF1ZXN0ZWQgY2VydGlmaWNhdGUgdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgY2VydGlmaWNhdGUgdHlwZS4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBwcm92aWRlciBwcm92aWRpbmcgY2VydGlmaWNhdGVzIG9mIHRoZQorICAgICAqICAgICAgICAgICAgc3BlY2lmaWVkIHR5cGUuCisgICAgICogQHJldHVybiB0aGUgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZUZhY3Rvcnl9IGluc3RhbmNlLgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGNlcnRpZmljYXRlIHR5cGUgaXMgbm90IGF2YWlsYWJsZSBhdCB0aGUKKyAgICAgKiAgICAgICAgICAgICBzcGVjaWZpZWQgcHJvdmlkZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSB0eXBlID09IG51bGx9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHByb3ZpZGVyID09IG51bGx9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDZXJ0aWZpY2F0ZUZhY3RvcnkgZ2V0SW5zdGFuY2UoU3RyaW5nIHR5cGUsCisgICAgICAgICAgICBQcm92aWRlciBwcm92aWRlcikgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgT2JqZWN0IHNwaSA9IEVOR0lORS5nZXRJbnN0YW5jZSh0eXBlLCBwcm92aWRlciwgbnVsbCk7CisgICAgICAgICAgICByZXR1cm4gbmV3IENlcnRpZmljYXRlRmFjdG9yeSgoQ2VydGlmaWNhdGVGYWN0b3J5U3BpKSBzcGksIHByb3ZpZGVyLCB0eXBlKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBQcm92aWRlcn0gb2YgdGhlIGNlcnRpZmljYXRlIGZhY3RvcnkgcmVwcmVzZW50ZWQgYnkKKyAgICAgKiB0aGUgY2VydGlmaWNhdGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcm92aWRlciBvZiB0aGlzIGNlcnRpZmljYXRlIGZhY3RvcnkuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFByb3ZpZGVyIGdldFByb3ZpZGVyKCkgeworICAgICAgICByZXR1cm4gcHJvdmlkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgQ2VydGlmaWNhdGUgdHlwZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHlwZSBvZiBjZXJ0aWZpY2F0ZSBiZWluZyB1c2VkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0VHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGFuZCBpbml0aWFsaXplcyBhIHtAY29kZSBDZXJ0aWZpY2F0ZX0gZnJvbSB0aGUgcHJvdmlkZWQgaW5wdXQKKyAgICAgKiBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5TdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJlYW0gZnJvbSB3aGVyZSBkYXRhIGlzIHJlYWQgdG8gY3JlYXRlIHRoZSB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIENlcnRpZmljYXRlfS4KKyAgICAgKiBAcmV0dXJuIGFuIGluaXRpYWxpemVkIENlcnRpZmljYXRlLgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBwYXJzaW5nIHByb2JsZW1zIGFyZSBkZXRlY3RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQ2VydGlmaWNhdGUgZ2VuZXJhdGVDZXJ0aWZpY2F0ZShJbnB1dFN0cmVhbSBpblN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZUdlbmVyYXRlQ2VydGlmaWNhdGUoaW5TdHJlYW0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4ge0Bjb2RlIEl0ZXJhdG9yfSBvdmVyIHRoZSBzdXBwb3J0ZWQge0Bjb2RlIENlcnRQYXRofSBlbmNvZGluZ3MKKyAgICAgKiAoYXMgU3RyaW5ncykuIFRoZSBmaXJzdCBlbGVtZW50IGlzIHRoZSBkZWZhdWx0IGVuY29kaW5nIHNjaGVtZSB0byBhcHBseS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gaXRlcmF0b3Igb3ZlciBzdXBwb3J0ZWQge0BsaW5rIENlcnRQYXRofSBlbmNvZGluZ3MgKGFzCisgICAgICogICAgICAgICBTdHJpbmdzKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgSXRlcmF0b3I8U3RyaW5nPiBnZXRDZXJ0UGF0aEVuY29kaW5ncygpIHsKKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lR2V0Q2VydFBhdGhFbmNvZGluZ3MoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgYSB7QGNvZGUgQ2VydFBhdGh9IChhIGNlcnRpZmljYXRlIGNoYWluKSBmcm9tIHRoZSBwcm92aWRlZAorICAgICAqIHtAY29kZSBJbnB1dFN0cmVhbX0uIFRoZSBkZWZhdWx0IGVuY29kaW5nIHNjaGVtZSBpcyBhcHBsaWVkLgorICAgICAqCisgICAgICogQHBhcmFtIGluU3RyZWFtCisgICAgICogICAgICAgICAgICB7QGNvZGUgSW5wdXRTdHJlYW19IHdpdGggZW5jb2RlZCBkYXRhLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgQ2VydFBhdGh9IGluaXRpYWxpemVkIGZyb20gdGhlIHByb3ZpZGVkIGRhdGEuCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHBhcnNpbmcgcHJvYmxlbXMgYXJlIGRldGVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBDZXJ0UGF0aCBnZW5lcmF0ZUNlcnRQYXRoKElucHV0U3RyZWFtIGluU3RyZWFtKSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBJdGVyYXRvcjxTdHJpbmc+IGl0ID0gZ2V0Q2VydFBhdGhFbmNvZGluZ3MoKTsKKyAgICAgICAgaWYgKCFpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigiVGhlcmUgYXJlIG5vIENlcnRQYXRoIGVuY29kaW5ncyIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZUdlbmVyYXRlQ2VydFBhdGgoaW5TdHJlYW0sIGl0Lm5leHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGEge0Bjb2RlIENlcnRQYXRofSAoYSBjZXJ0aWZpY2F0ZSBjaGFpbikgZnJvbSB0aGUgcHJvdmlkZWQKKyAgICAgKiB7QGNvZGUgSW5wdXRTdHJlYW19IGFuZCB0aGUgc3BlY2lmaWVkIGVuY29kaW5nIHNjaGVtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpblN0cmVhbQorICAgICAqICAgICAgICAgICAge0Bjb2RlIElucHV0U3RyZWFtfSBjb250YWluaW5nIGNlcnRpZmljYXRlIHBhdGggZGF0YSBpbgorICAgICAqICAgICAgICAgICAgc3BlY2lmaWVkIGVuY29kaW5nLgorICAgICAqIEBwYXJhbSBlbmNvZGluZworICAgICAqICAgICAgICAgICAgZW5jb2Rpbmcgb2YgdGhlIGRhdGEgaW4gdGhlIGlucHV0IHN0cmVhbS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIENlcnRQYXRofSBpbml0aWFsaXplZCBmcm9tIHRoZSBwcm92aWRlZCBkYXRhLgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBwYXJzaW5nIHByb2JsZW1zIGFyZSBkZXRlY3RlZC4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHByb3ZpZGVyIGRvZXMgbm90IGltcGxlbWVudCB0aGlzIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQ2VydFBhdGggZ2VuZXJhdGVDZXJ0UGF0aChJbnB1dFN0cmVhbSBpblN0cmVhbSwgU3RyaW5nIGVuY29kaW5nKQorICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lR2VuZXJhdGVDZXJ0UGF0aChpblN0cmVhbSwgZW5jb2RpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdlbmVyYXRlcyBhIHtAY29kZSBDZXJ0UGF0aH0gZnJvbSB0aGUgcHJvdmlkZWQgbGlzdCBvZiBjZXJ0aWZpY2F0ZXMuIFRoZQorICAgICAqIGVuY29kaW5nIGlzIHRoZSBkZWZhdWx0IGVuY29kaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIGNlcnRpZmljYXRlcworICAgICAqICAgICAgICAgICAgdGhlIGxpc3QgY29udGFpbmluZyBjZXJ0aWZpY2F0ZXMgaW4gYSBmb3JtYXQgc3VwcG9ydGVkIGJ5IHRoZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIENlcnRpZmljYXRlRmFjdG9yeX0uCisgICAgICogQHJldHVybiBhIHtAY29kZSBDZXJ0UGF0aH0gaW5pdGlhbGl6ZWQgZnJvbSB0aGUgcHJvdmlkZWQgZGF0YS4KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgcGFyc2luZyBwcm9ibGVtcyBhcmUgZGV0ZWN0ZWQuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwcm92aWRlciBkb2VzIG5vdCBpbXBsZW1lbnQgdGhpcyBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENlcnRQYXRoIGdlbmVyYXRlQ2VydFBhdGgoTGlzdDw/IGV4dGVuZHMgQ2VydGlmaWNhdGU+IGNlcnRpZmljYXRlcykKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZUdlbmVyYXRlQ2VydFBhdGgoY2VydGlmaWNhdGVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgYW5kIGluaXRpYWxpemVzIGEgY29sbGVjdGlvbiBvZiAodW5yZWxhdGVkKSBjZXJ0aWZpY2F0ZXMgZnJvbQorICAgICAqIHRoZSBwcm92aWRlZCBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5TdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJlYW0gZnJvbSB3aGljaCB0aGUgZGF0YSBpcyByZWFkIHRvIGNyZWF0ZSB0aGUKKyAgICAgKiAgICAgICAgICAgIGNvbGxlY3Rpb24uCisgICAgICogQHJldHVybiBhbiBpbml0aWFsaXplZCBjb2xsZWN0aW9uIG9mIGNlcnRpZmljYXRlcy4KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgcGFyc2luZyBwcm9ibGVtcyBhcmUgZGV0ZWN0ZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENvbGxlY3Rpb248PyBleHRlbmRzIENlcnRpZmljYXRlPiBnZW5lcmF0ZUNlcnRpZmljYXRlcyhJbnB1dFN0cmVhbSBpblN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZUdlbmVyYXRlQ2VydGlmaWNhdGVzKGluU3RyZWFtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgYW5kIGluaXRpYWxpemVzIGEgPGk+Q2VydGlmaWNhdGUgUmV2b2NhdGlvbiBMaXN0PC9pPiAoQ1JMKSBmcm9tCisgICAgICogdGhlIHByb3ZpZGVkIGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpblN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmVhbSBmcm9tIHdoZXJlIGRhdGEgaXMgcmVhZCB0byBjcmVhdGUgdGhlIENSTC4KKyAgICAgKiBAcmV0dXJuIGFuIGluaXRpYWxpemVkIENSTC4KKyAgICAgKiBAZXhjZXB0aW9uIENSTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHBhcnNpbmcgcHJvYmxlbXMgYXJlIGRldGVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBDUkwgZ2VuZXJhdGVDUkwoSW5wdXRTdHJlYW0gaW5TdHJlYW0pIHRocm93cyBDUkxFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVHZW5lcmF0ZUNSTChpblN0cmVhbSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGFuZCBpbml0aWFsaXplcyBhIGNvbGxlY3Rpb24gb2YgPGk+Q2VydGlmaWNhdGUgUmV2b2NhdGlvbgorICAgICAqIExpc3Q8L2k+IChDUkwpIGZyb20gdGhlIHByb3ZpZGVkIGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpblN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmVhbSBmcm9tIHdoaWNoIHRoZSBkYXRhIGlzIHJlYWQgdG8gY3JlYXRlIHRoZSBDUkxzLgorICAgICAqIEByZXR1cm4gYW4gaW5pdGlhbGl6ZWQgY29sbGVjdGlvbiBvZiBDUkxzLgorICAgICAqIEBleGNlcHRpb24gQ1JMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcGFyc2luZyBwcm9ibGVtcyBhcmUgZGV0ZWN0ZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENvbGxlY3Rpb248PyBleHRlbmRzIENSTD4gZ2VuZXJhdGVDUkxzKElucHV0U3RyZWFtIGluU3RyZWFtKQorICAgICAgICAgICAgdGhyb3dzIENSTEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZUdlbmVyYXRlQ1JMcyhpblN0cmVhbSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUZhY3RvcnlTcGkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVGYWN0b3J5U3BpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzIxYWZhNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVGYWN0b3J5U3BpLmphdmEKQEAgLTAsMCArMSwxNTUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKgorICogVGhpcyBjbGFzcyBkZWZpbmVzIHRoZSA8aT5TZXJ2aWNlIFByb3ZpZGVyIEludGVyZmFjZTwvaT4gKDxiPlNQSTwvYj4pIGZvciB0aGUKKyAqIHtAY29kZSBDZXJ0aWZpY2F0ZUZhY3Rvcnl9IGNsYXNzLiBUaGlzIFNQSSBtdXN0IGJlIGltcGxlbWVudGVkIGZvciBlYWNoCisgKiBjZXJ0aWZpY2F0ZSB0eXBlIGEgc2VjdXJpdHkgcHJvdmlkZXIgd2lzaGVzIHRvIHN1cHBvcnQuCisgKi8KKworcHVibGljIGFic3RyYWN0IGNsYXNzIENlcnRpZmljYXRlRmFjdG9yeVNwaSB7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlRmFjdG9yeVNwaSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgYW5kIGluaXRpYWxpemVzIGEge0Bjb2RlIENlcnRpZmljYXRlfSBmcm9tIHRoZSBwcm92aWRlZCBpbnB1dAorICAgICAqIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpblN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmVhbSBmcm9tIHdoaWNoIHRoZSBkYXRhIGlzIHJlYWQgdG8gY3JlYXRlIHRoZQorICAgICAqICAgICAgICAgICAgY2VydGlmaWNhdGUuCisgICAgICogQHJldHVybiBhbiBpbml0aWFsaXplZCBjZXJ0aWZpY2F0ZS4KKyAgICAgKiBAZXhjZXB0aW9uIENlcnRpZmljYXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcGFyc2luZyBwcm9ibGVtcyBhcmUgZGV0ZWN0ZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENlcnRpZmljYXRlIGVuZ2luZUdlbmVyYXRlQ2VydGlmaWNhdGUoSW5wdXRTdHJlYW0gaW5TdHJlYW0pCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgYW5kIGluaXRpYWxpemVzIGEgY29sbGVjdGlvbiBvZiBjZXJ0aWZpY2F0ZXMgZnJvbSB0aGUgcHJvdmlkZWQKKyAgICAgKiBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5TdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJlYW0gZnJvbSB3aGVyZSBkYXRhIGlzIHJlYWQgdG8gY3JlYXRlIHRoZSBjZXJ0aWZpY2F0ZXMuCisgICAgICogQHJldHVybiBhIGNvbGxlY3Rpb24gb2YgY2VydGlmaWNhdGVzLgorICAgICAqIEBleGNlcHRpb24gQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBwYXJzaW5nIHByb2JsZW1zIGFyZSBkZXRlY3RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQ29sbGVjdGlvbjw/IGV4dGVuZHMgQ2VydGlmaWNhdGU+CisgICAgICAgIGVuZ2luZUdlbmVyYXRlQ2VydGlmaWNhdGVzKElucHV0U3RyZWFtIGluU3RyZWFtKSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgYW5kIGluaXRpYWxpemVzIGEgPGk+Q2VydGlmaWNhdGUgUmV2b2NhdGlvbiBMaXN0PC9pPiAoQ1JMKSBmcm9tCisgICAgICogdGhlIHByb3ZpZGVkIGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpblN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmVhbSBmcm9tIHdoZXJlIGRhdGEgaXMgcmVhZCB0byBjcmVhdGUgdGhlIENSTC4KKyAgICAgKiBAcmV0dXJuIGFuIENSTCBpbnN0YW5jZS4KKyAgICAgKiBAZXhjZXB0aW9uIENSTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHBhcnNpbmcgcHJvYmxlbXMgYXJlIGRldGVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBDUkwgZW5naW5lR2VuZXJhdGVDUkwoSW5wdXRTdHJlYW0gaW5TdHJlYW0pCisgICAgICAgICAgICB0aHJvd3MgQ1JMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGFuZCBpbml0aWFsaXplcyBhIGNvbGxlY3Rpb24gb2YgPGk+Q2VydGlmaWNhdGUgUmV2b2NhdGlvbgorICAgICAqIExpc3Q8L2k+IChDUkwpIGZyb20gdGhlIHByb3ZpZGVkIGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpblN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmVhbSBmcm9tIHdoaWNoIHRoZSBkYXRhIGlzIHJlYWQgdG8gY3JlYXRlIHRoZSBDUkxzLgorICAgICAqIEByZXR1cm4gYSBjb2xsZWN0aW9uIG9mIENSTHMuCisgICAgICogQGV4Y2VwdGlvbiBDUkxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBwYXJzaW5nIHByb2JsZW1zIGFyZSBkZXRlY3RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQ29sbGVjdGlvbjw/IGV4dGVuZHMgQ1JMPgorICAgICAgICBlbmdpbmVHZW5lcmF0ZUNSTHMoSW5wdXRTdHJlYW0gaW5TdHJlYW0pIHRocm93cyBDUkxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgYSB7QGNvZGUgQ2VydFBhdGh9IGZyb20gdGhlIHByb3ZpZGVkIHtAY29kZSBJbnB1dFN0cmVhbX0uIFRoZQorICAgICAqIGRlZmF1bHQgZW5jb2Rpbmcgc2NoZW1lIGlzIGFwcGxpZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5TdHJlYW0KKyAgICAgKiAgICAgICAgICAgIGFuIGlucHV0IHN0cmVhbSB3aXRoIGVuY29kZWQgZGF0YS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIENlcnRQYXRofSBpbml0aWFsaXplZCBmcm9tIHRoZSBwcm92aWRlZCBkYXRhLgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBwYXJzaW5nIHByb2JsZW1zIGFyZSBkZXRlY3RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydFBhdGggZW5naW5lR2VuZXJhdGVDZXJ0UGF0aChJbnB1dFN0cmVhbSBpblN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdlbmVyYXRlcyBhIHtAY29kZSBDZXJ0UGF0aH0gZnJvbSB0aGUgcHJvdmlkZWQge0Bjb2RlCisgICAgICogSW5wdXRTdHJlYW19IGluIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5TdHJlYW0KKyAgICAgKiAgICAgICAgICAgIGFuIGlucHV0IHN0cmVhbSBjb250YWluaW5nIGNlcnRpZmljYXRlIHBhdGggZGF0YSBpbiBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgICAgIGVuY29kaW5nLgorICAgICAqIEBwYXJhbSBlbmNvZGluZworICAgICAqICAgICAgICAgICAgdGhlIGVuY29kaW5nIG9mIHRoZSBkYXRhIGluIHRoZSBpbnB1dCBzdHJlYW0uCisgICAgICogQHJldHVybiBhIHtAY29kZSBDZXJ0UGF0aH0gaW5pdGlhbGl6ZWQgZnJvbSB0aGUgcHJvdmlkZWQgZGF0YQorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBwYXJzaW5nIHByb2JsZW1zIGFyZSBkZXRlY3RlZC4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHByb3ZpZGVyIGRvZXMgbm90IGltcGxlbWVudCB0aGlzIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydFBhdGggZW5naW5lR2VuZXJhdGVDZXJ0UGF0aChJbnB1dFN0cmVhbSBpblN0cmVhbSwgU3RyaW5nIGVuY29kaW5nKQorICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGEge0Bjb2RlIENlcnRQYXRofSBmcm9tIHRoZSBwcm92aWRlZCBsaXN0IG9mIGNlcnRpZmljYXRlcy4gVGhlCisgICAgICogZW5jb2RpbmcgaXMgdGhlIGRlZmF1bHQgZW5jb2RpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2VydGlmaWNhdGVzCisgICAgICogICAgICAgICAgICB0aGUgbGlzdCBjb250YWluaW5nIGNlcnRpZmljYXRlcyBpbiBhIGZvcm1hdCBzdXBwb3J0ZWQgYnkgdGhlCisgICAgICogICAgICAgICAgICB7QGNvZGUgQ2VydGlmaWNhdGVGYWN0b3J5fS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIENlcnRQYXRofSBpbml0aWFsaXplZCBmcm9tIHRoZSBwcm92aWRlZCBkYXRhLgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBwYXJzaW5nIHByb2JsZW1zIGFyZSBkZXRlY3RlZC4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHByb3ZpZGVyIGRvZXMgbm90IGltcGxlbWVudCB0aGlzIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydFBhdGggZW5naW5lR2VuZXJhdGVDZXJ0UGF0aChMaXN0PD8gZXh0ZW5kcyBDZXJ0aWZpY2F0ZT4gIGNlcnRpZmljYXRlcykKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4ge0Bjb2RlIEl0ZXJhdG9yfSBvdmVyIHRoZSBzdXBwb3J0ZWQge0Bjb2RlIENlcnRQYXRofSBlbmNvZGluZ3MKKyAgICAgKiAoYXMgU3RyaW5ncykuIFRoZSBmaXJzdCBlbGVtZW50IGlzIHRoZSBkZWZhdWx0IGVuY29kaW5nLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBpdGVyYXRvciBvdmVyIHN1cHBvcnRlZCB7QGNvZGUgQ2VydFBhdGh9IGVuY29kaW5ncyAoYXMKKyAgICAgKiAgICAgICAgIFN0cmluZ3MpLgorICAgICAqLworICAgIHB1YmxpYyBJdGVyYXRvcjxTdHJpbmc+IGVuZ2luZUdldENlcnRQYXRoRW5jb2RpbmdzKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJiMWRjZDQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQ0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuY2VydDsKKworLyoqCisgKiBUaGUgZXhjZXB0aW9uIHRoYXQgaXMgdGhyb3duIHdoZW4gYSB7QGNvZGUgQ2VydGlmaWNhdGV9IGlzIG5vdCB5ZXQgdmFsaWQgb3IKKyAqIHdpbGwgbm90IHlldCBiZSB2YWxpZCBvbiBhIHNwZWNpZmllZCBkYXRlLgorICovCitwdWJsaWMgY2xhc3MgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbiBleHRlbmRzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDQzNTU5MTk5MDAwNDEwNjQ3MDJMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbn0gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGVmZDE1OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw2NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LmNlcnQ7CisKKy8qKgorICogVGhlIGV4Y2VwdGlvbiB0aGF0IGlzIHRocm93biB3aGVuIGEge0Bjb2RlIENlcnRpZmljYXRlfSBjYW4gbm90IGJlIHBhcnNlZC4KKyAqLworcHVibGljIGNsYXNzIENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbiBleHRlbmRzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03OTg5MjIyNDE2NzkzMzIyMDI5TDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbn0gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKKyAgICAgICAgc3VwZXIobXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9ufSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBtZXNzYWdlIGFuZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24uCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgZXhjZXB0aW9uJ3Mgc291cmNlLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9ufSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGV4Y2VwdGlvbidzIHNvdXJjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9Db2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9Db2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlM2M4NWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0NvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzLmphdmEKQEAgLTAsMCArMSwxMDQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworCisvKioKKyAqIFRoZSBwYXJhbWV0ZXJzIHRvIGluaXRpYWxpemUgYSA8aT5Db2xsZWN0aW9uPC9pPiB0eXBlIHtAY29kZSBDZXJ0U3RvcmV9IGluc3RhbmNlLgorICogPHA+CisgKiBJdCBpcyB1c2VkIHRvIHNwZWNpZnkgdGhlIHtAY29kZSBDb2xsZWN0aW9ufSB3aGVyZSB0aGUge0Bjb2RlIENlcnRTdG9yZX0gd2lsbAorICogcmV0cmlldmUgdGhlIGNlcnRpZmljYXRlcyBhbmQgQ1JMcyBmcm9tLgorICovCitwdWJsaWMgY2xhc3MgQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMgaW1wbGVtZW50cyBDZXJ0U3RvcmVQYXJhbWV0ZXJzIHsKKyAgICAvLyBEZWZhdWx0IGVtcHR5IGFuZCBpbW11dGFibGUgY29sbGVjdGlvbi4KKyAgICAvLyBVc2VkIGlmIDxjb2RlPkNvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzPC9jb2RlPmluc3RhbmNlCisgICAgLy8gY3JlYXRlZCBieSB0aGUgbm8gYXJnIGNvbnN0cnVjdG9yCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29sbGVjdGlvbjw/PiBkZWZhdWx0Q29sbGVjdGlvbiA9IENvbGxlY3Rpb25zLkVNUFRZX1NFVDsKKyAgICAvLyBBIDxjb2RlPkNvbGxlY3Rpb248L2NvZGU+IG9mIDxjb2RlPkNlcnRpZmljYXRlPC9jb2RlPnMKKyAgICAvLyBhbmQgPGNvZGU+Q1JMPC9jb2RlPnMKKyAgICBwcml2YXRlIGZpbmFsIENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzfSB3aXRob3V0IGEgY29sbGVjdGlvbi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZGVmYXVsdCBjb2xsZWN0aW9uIGlzIGFuIGVtcHR5IGFuZCB1bm1vZGlmaWFibGUge0Bjb2RlIENvbGxlY3Rpb259LgorICAgICAqLworICAgIHB1YmxpYyBDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycygpIHsKKyAgICAgICAgdGhpcy5jb2xsZWN0aW9uID0gZGVmYXVsdENvbGxlY3Rpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnN9IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIGNvbGxlY3Rpb24uCisgICAgICogPHA+CisgICAgICogVGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGlzIG5vdCBjb3BpZWQgYW5kIHRoZXJlZm9yZSBtYXkgYmUgbW9kaWZpZWQgYXQKKyAgICAgKiBhbnkgdGltZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2xsZWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgY29sbGVjdGlvbiB3aGVyZSB0aGUge0Bjb2RlIENlcnRpZmljYXRlfXMgYW5kIHtAY29kZSBDUkx9cworICAgICAqICAgICAgICAgICAgd2lsbCBiZSByZXRyaWV2ZWQgZnJvbS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGNvbGxlY3Rpb24gaXMgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbikgeworICAgICAgICB0aGlzLmNvbGxlY3Rpb24gPSBjb2xsZWN0aW9uOworICAgICAgICBpZiAodGhpcy5jb2xsZWN0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvbmVzIHRoaXMge0Bjb2RlIENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzfSBpbnN0YW5jZSwgYnV0IG5vdCB0aGUKKyAgICAgKiB1bmRlcmx5aW5nIGNvbGxlY3Rpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjbG9uZWQgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNvbGxlY3Rpb24gd2hlcmUgdGhlIHtAY29kZSBDZXJ0aWZpY2F0ZX1zIGFuZCB7QGNvZGUgQ1JMfXMKKyAgICAgKiBhcmUgcmV0cmlldmVkIGZyb20uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb2xsZWN0aW9uIHdoZXJlIHRoZSB7QGNvZGUgQ2VydGlmaWNhdGV9cyBhbmQge0Bjb2RlIENSTH1zCisgICAgICogICAgICAgICB3aWxsIGJlIHJldHJpZXZlZCBmcm9tLgorICAgICAqLworICAgIHB1YmxpYyBDb2xsZWN0aW9uPD8+IGdldENvbGxlY3Rpb24oKSB7CisgICAgICAgIHJldHVybiBjb2xsZWN0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9CisgICAgICAgICAgICBuZXcgU3RyaW5nQnVpbGRlcigiQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnM6IFtcbmNvbGxlY3Rpb246ICIpOworICAgICAgICBzYi5hcHBlbmQoZ2V0Q29sbGVjdGlvbigpLnRvU3RyaW5nKCkpOworICAgICAgICBzYi5hcHBlbmQoIlxuXSIpOworICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0xEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L0xEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWIwMWY5MAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvTERBUENlcnRTdG9yZVBhcmFtZXRlcnMuamF2YQpAQCAtMCwwICsxLDEyOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LmNlcnQ7CisKKy8qKgorICogVGhlIHBhcmFtZXRlcnMgdG8gaW5pdGlhbGl6ZSBhIExEQVAge0Bjb2RlIENlcnRTdG9yZX0gaW5zdGFuY2UuCisgKi8KK3B1YmxpYyBjbGFzcyBMREFQQ2VydFN0b3JlUGFyYW1ldGVycyBpbXBsZW1lbnRzIENlcnRTdG9yZVBhcmFtZXRlcnMgeworICAgIC8vIERlZmF1bHQgTERBUCBzZXJ2ZXIgbmFtZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX0xEQVBfU0VSVkVSX05BTUUgPSAibG9jYWxob3N0IjsKKyAgICAvLyBEZWZhdWx0IExEQVAgc2VydmVyIHBvcnQgbnVtYmVyCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfTERBUF9QT1JUICA9IDM4OTsKKworICAgIC8vIExEQVAgc2VydmVyIG5hbWUgZm9yIHRoaXMgY2VydCBzdG9yZQorICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHNlcnZlck5hbWU7CisgICAgLy8gTERBUCBzZXJ2ZXIgcG9ydCBudW1iZXIgZm9yIHRoaXMgY2VydCBzdG9yZQorICAgIHByaXZhdGUgZmluYWwgaW50IHBvcnQ7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBMREFQQ2VydFN0b3JlUGFyYW1ldGVyc30gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogc2VydmVyIG5hbWUgYW5kIHBvcnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2VydmVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIExEQVAgc2VydmVyIG5hbWUuCisgICAgICogQHBhcmFtIHBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpcyB7QGNvZGUgc2VydmVyTmFtZX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBMREFQQ2VydFN0b3JlUGFyYW1ldGVycyhTdHJpbmcgc2VydmVyTmFtZSwgaW50IHBvcnQpIHsKKyAgICAgICAgdGhpcy5wb3J0ID0gcG9ydDsKKyAgICAgICAgdGhpcy5zZXJ2ZXJOYW1lID0gc2VydmVyTmFtZTsKKyAgICAgICAgaWYgKHRoaXMuc2VydmVyTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIExEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzfSBpbnN0YW5jZSB3aXRoIGRlZmF1bHQKKyAgICAgKiBwYXJhbWV0ZXJzLgorICAgICAqIDxwPgorICAgICAqIFRoZSBkZWZhdWx0IHBhcmFtZXRlcnMgYXJlIHNlcnZlciBuYW1lICJsb2NhbGhvc3QiIGFuZCBwb3J0IDM4OS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTERBUENlcnRTdG9yZVBhcmFtZXRlcnMoKSB7CisgICAgICAgIHRoaXMuc2VydmVyTmFtZSA9IERFRkFVTFRfTERBUF9TRVJWRVJfTkFNRTsKKyAgICAgICAgdGhpcy5wb3J0ID0gREVGQVVMVF9MREFQX1BPUlQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgTERBUENlcnRTdG9yZVBhcmFtZXRlcnN9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIHNlcnZlciBuYW1lIGFuZCBkZWZhdWx0IHBvcnQgMzg5LgorICAgICAqCisgICAgICogQHBhcmFtIHNlcnZlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBMREFQIHNlcnZlciBuYW1lLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc2VydmVyTmFtZX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBMREFQQ2VydFN0b3JlUGFyYW1ldGVycyhTdHJpbmcgc2VydmVyTmFtZSkgeworICAgICAgICB0aGlzLnBvcnQgPSBERUZBVUxUX0xEQVBfUE9SVDsKKyAgICAgICAgdGhpcy5zZXJ2ZXJOYW1lID0gc2VydmVyTmFtZTsKKyAgICAgICAgaWYgKHRoaXMuc2VydmVyTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENsb25lcyB0aGlzIHtAY29kZSBMREFQQ2VydFN0b3JlUGFyYW1ldGVyc30gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjbG9uZWQgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIExEQVAgc2VydmVyIHBvcnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBMREFQIHNlcnZlciBwb3J0LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UG9ydCgpIHsKKyAgICAgICAgcmV0dXJuIHBvcnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgTERBUCBzZXJ2ZXIgbmFtZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIExEQVAgc2VydmVyIG5hbWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTZXJ2ZXJOYW1lKCkgeworICAgICAgICByZXR1cm4gc2VydmVyTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgTERBUENlcnRTdG9yZVBhcmFtZXRlcnN9CisgICAgICogaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgTERBUENlcnRTdG9yZVBhcmFtZXRlcnN9CisgICAgICogICAgICAgICBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0KKyAgICAgICAgICAgIG5ldyBTdHJpbmdCdWlsZGVyKCJMREFQQ2VydFN0b3JlUGFyYW1ldGVyczogW1xuIHNlcnZlck5hbWU6ICIpOworICAgICAgICBzYi5hcHBlbmQoZ2V0U2VydmVyTmFtZSgpKTsKKyAgICAgICAgc2IuYXBwZW5kKCJcbiBwb3J0OiAiKTsKKyAgICAgICAgc2IuYXBwZW5kKGdldFBvcnQoKSk7CisgICAgICAgIHNiLmFwcGVuZCgiXG5dIik7CisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1BLSVhCdWlsZGVyUGFyYW1ldGVycy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVhMTY1ZmQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1BLSVhCdWlsZGVyUGFyYW1ldGVycy5qYXZhCkBAIC0wLDAgKzEsMTMwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKKy8qKgorICogVGhlIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uIGZvciBhIFBLSVgge0Bjb2RlIENlcnRQYXRoQnVpbGRlcn0KKyAqIGFsZ29yaXRobSB1c2VkIHRvIHtAbGluayBDZXJ0UGF0aEJ1aWxkZXIjYnVpbGQoQ2VydFBhdGhQYXJhbWV0ZXJzKSBidWlsZH0KKyAqIGNlcnRpZmljYXRlIGNoYWlucyB2YWxpZGF0ZWQgd2l0aCB0aGUgUEtJWCBjZXJ0aWZpY2F0aW9uIHBhdGggdmFsaWRhdGlvbi4KKyAqIDxwPgorICogVGhlIHBhcmFtZXRlcnMgbXVzdCBiZSBjcmVhdGVkIHdpdGggPGk+dHJ1c3RlZDwvaT4gY2VydGlmaWNhdGUgYXV0aG9yaXRpZXMKKyAqIGFuZCBjb25zdHJhaW50cyBmb3IgdGhlIHRhcmdldCBjZXJ0aWZpY2F0ZXMuCisgKgorICogQHNlZSBDZXJ0UGF0aEJ1aWxkZXIKKyAqIEBzZWUgQ2VydFBhdGhQYXJhbWV0ZXJzCisgKi8KK3B1YmxpYyBjbGFzcyBQS0lYQnVpbGRlclBhcmFtZXRlcnMgZXh0ZW5kcyBQS0lYUGFyYW1ldGVycyB7CisgICAgLy8gTWF4aW11bSBjZXJ0aWZpY2F0ZSBwYXRoIGxlbmd0aCAoNSBieSBkZWZhdWx0KQorICAgIHByaXZhdGUgaW50IG1heFBhdGhMZW5ndGggPSA1OworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzfSBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBzZXQgb2Yge0Bjb2RlIFRydXN0QW5jaG9yfSBhbmQgY2VydGlmaWNhdGUgY29uc3RyYWludHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHJ1c3RBbmNob3JzCisgICAgICogICAgICAgICAgICB0aGUgc2V0IG9mIHtAY29kZSBUcnVzdEFuY2hvcnN9LgorICAgICAqIEBwYXJhbSB0YXJnZXRDb25zdHJhaW50cworICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRlIGNvbnN0cmFpbnRzLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSB0cnVzdEFuY2hvcnN9IGlzIGVtcHR5LgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgb25lIG9mIHRoZSBpdGVtcyBpbiB7QGNvZGUgdHJ1c3RBbmNob3JzfSBpcyBub3QgYW4KKyAgICAgKiAgICAgICAgICAgICBpbnN0YW5jZSBvZiB7QGNvZGUgamF2YS5zZWN1cml0eS5jZXJ0LlRydXN0QW5jaG9yfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzKFNldDxUcnVzdEFuY2hvcj4gdHJ1c3RBbmNob3JzLAorICAgICAgICAgICAgQ2VydFNlbGVjdG9yIHRhcmdldENvbnN0cmFpbnRzKQorICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKHRydXN0QW5jaG9ycyk7CisgICAgICAgIHN1cGVyLnNldFRhcmdldENlcnRDb25zdHJhaW50cyh0YXJnZXRDb25zdHJhaW50cyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzfSBpbnN0YW5jZSB3aXRoIHRoZSB0cnVzdGVkCisgICAgICoge0Bjb2RlIFg1MDlDZXJ0aWZpY2F0ZX0gZW50cmllcyBmcm9tIHRoZSBzcGVjaWZpZWQge0Bjb2RlIEtleVN0b3JlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXlTdG9yZQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBzdG9yZSBjb250YWluaW5nIHRydXN0ZWQgY2VydGlmaWNhdGVzLgorICAgICAqIEBwYXJhbSB0YXJnZXRDb25zdHJhaW50cworICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRlIGNvbnN0cmFpbnRzLgorICAgICAqIEB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGtleVN0b3JlfSBpcyBub3QgaW5pdGlhbGl6ZWQuCisgICAgICogQHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGtleVN0b3JlfSBkb2VzIG5vdCBjb250YWluZWQgYW55IHRydXN0ZWQKKyAgICAgKiAgICAgICAgICAgICBjZXJ0aWZpY2F0ZSBlbnRyeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzKEtleVN0b3JlIGtleVN0b3JlLAorICAgICAgICAgICAgQ2VydFNlbGVjdG9yIHRhcmdldENvbnN0cmFpbnRzKQorICAgICAgICB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24sCisgICAgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoa2V5U3RvcmUpOworICAgICAgICBzdXBlci5zZXRUYXJnZXRDZXJ0Q29uc3RyYWludHModGFyZ2V0Q29uc3RyYWludHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGEgY2VydGlmaWNhdGlvbiBwYXRoLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgaXMgdGhlIG1heGltdW0gbnVtYmVyIG9mIG5vbi1zZWxmLXNpZ25lZCBjZXJ0aWZpY2F0ZXMgaW4gYQorICAgICAqIGNlcnRpZmljYXRpb24gcGF0aC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gbGVuZ3RoIG9mIGEgY2VydGlmaWNhdGlvbiBwYXRoLCBvciB7QGNvZGUgLTF9IGlmIGl0CisgICAgICogICAgICAgICBpcyB1bmxpbWl0ZWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNYXhQYXRoTGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gbWF4UGF0aExlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGEgY2VydGlmaWNhdGlvbiBwYXRoLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgaXMgdGhlIG1heGltdW0gbnVtYmVyIG9mIG5vbi1zZWxmLXNpZ25lZCBjZXJ0aWZpY2F0ZXMgaW4gYQorICAgICAqIGNlcnRpZmljYXRpb24gcGF0aC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtYXhQYXRoTGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBsZW5ndGggb2YgYSBjZXJ0aWZpY2F0aW9uIHBhdGguCisgICAgICogQHRocm93cyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG1heFBhdGhMZW5ndGh9IGlzIGxlc3MgdGhhbiB7QGNvZGUgLTF9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1heFBhdGhMZW5ndGgoaW50IG1heFBhdGhMZW5ndGgpIHsKKyAgICAgICAgaWYgKG1heFBhdGhMZW5ndGggPCAtMSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24oIm1heFBhdGhMZW5ndGggPCAtMSIpOworICAgICAgICB9CisgICAgICAgIHRoaXMubWF4UGF0aExlbmd0aCA9IG1heFBhdGhMZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZSBQS0lYQnVpbGRlclBhcmFtZXRlcnN9CisgICAgICogaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMge0Bjb2RlIFBLSVhCdWlsZGVyUGFyYW1ldGVyc30KKyAgICAgKiAgICAgICAgIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiW1xuIik7CisgICAgICAgIHNiLmFwcGVuZChzdXBlci50b1N0cmluZygpKTsKKyAgICAgICAgc2IuYXBwZW5kKCIgTWF4IFBhdGggTGVuZ3RoOiAiKTsKKyAgICAgICAgc2IuYXBwZW5kKG1heFBhdGhMZW5ndGgpOworICAgICAgICBzYi5hcHBlbmQoIlxuXSIpOworICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1BLSVhDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvUEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU4OWNlODIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1BLSVhDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQuamF2YQpAQCAtMCwwICsxLDgxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CisKKy8qKgorICogVGhlIHJlc3VsdCBvZiB0aGUgUEtJWCBjZXJ0aWZpY2F0aW9uIHBhdGggYnVpbGRlciwgcmV0dXJuZWQgYnkKKyAqIHtAbGluayBDZXJ0UGF0aEJ1aWxkZXIjYnVpbGQoQ2VydFBhdGhQYXJhbWV0ZXJzKX0uCisgKi8KK3B1YmxpYyBjbGFzcyBQS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0IGV4dGVuZHMgUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0CisgICAgICAgIGltcGxlbWVudHMgQ2VydFBhdGhCdWlsZGVyUmVzdWx0IHsKKyAgICAvLyBCdWlsdCBhbmQgdmFsaWRhdGVkIGNlcnRpZmljYXRpb24gcGF0aAorICAgIHByaXZhdGUgZmluYWwgQ2VydFBhdGggY2VydFBhdGg7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBQS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0fSBpbnN0YW5jZSB3aXRoIHRoZQorICAgICAqIHNwZWNpZmllZCB2YWxpZGF0ZWQgY2VydGlmaWNhdGlvbiBwYXRoLCB0aGUgdHJ1c3QgYW5jaG9yIG9mIHRoZQorICAgICAqIGNlcnRpZmljYXRpb24gcGF0aCwgdGhlIHBvbGljeSB0cmVlIGFuZCB0aGUgcHVibGljIGtleSBvZiB0aGUgc3ViamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjZXJ0UGF0aAorICAgICAqICAgICAgICAgICAgdGhlIHZhbGlkYXRlZCBjZXJ0aWZpY2F0aW9uIHBhdGguCisgICAgICogQHBhcmFtIHRydXN0QW5jaG9yCisgICAgICogICAgICAgICAgICB0aGUgdHJ1c3QgYW5jaG9yLgorICAgICAqIEBwYXJhbSBwb2xpY3lUcmVlCisgICAgICogICAgICAgICAgICB0aGUgcG9saWN5IHRyZWUgKG9yIHtAY29kZSBudWxsfSBpZiBub3QgdXNlZCkuCisgICAgICogQHBhcmFtIHN1YmplY3RQdWJsaWNLZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBwdWJsaWMga2V5LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGNlclBhdGh9LCB7QGNvZGUgdHJ1c3RBbmNob3J9IG9yIHtAY29kZQorICAgICAqICAgICAgICAgICAgIHN1YmplY3RQb2xpY3lLZXl9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdChDZXJ0UGF0aCBjZXJ0UGF0aCwgVHJ1c3RBbmNob3IgdHJ1c3RBbmNob3IsCisgICAgICAgICAgICBQb2xpY3lOb2RlIHBvbGljeVRyZWUsIFB1YmxpY0tleSBzdWJqZWN0UHVibGljS2V5KSB7CisgICAgICAgIHN1cGVyKHRydXN0QW5jaG9yLCBwb2xpY3lUcmVlLCBzdWJqZWN0UHVibGljS2V5KTsKKyAgICAgICAgdGhpcy5jZXJ0UGF0aCA9IGNlcnRQYXRoOworICAgICAgICBpZiAodGhpcy5jZXJ0UGF0aCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImNlcnRQYXRoID09IG51bGwiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbGlkYXRlZCBjZXJ0aWZpY2F0aW9uIHBhdGguCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWxpZGF0ZWQgY2VydGlmaWNhdGlvbiBwYXRoLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0UGF0aCBnZXRDZXJ0UGF0aCgpIHsKKyAgICAgICAgcmV0dXJuIGNlcnRQYXRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgUEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdH0KKyAgICAgKiBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgUEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdH0KKyAgICAgKiAgICAgICAgIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcihzdXBlci50b1N0cmluZygpKTsKKyAgICAgICAgc2IuYXBwZW5kKCJcbiBDZXJ0aWZpY2F0aW9uIFBhdGg6ICIpOworICAgICAgICBzYi5hcHBlbmQoY2VydFBhdGgudG9TdHJpbmcoKSk7CisgICAgICAgIHNiLmFwcGVuZCgiXG5dIik7CisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvUEtJWENlcnRQYXRoQ2hlY2tlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9QS0lYQ2VydFBhdGhDaGVja2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODY5ZWZiNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvUEtJWENlcnRQYXRoQ2hlY2tlci5qYXZhCkBAIC0wLDAgKzEsMTExIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKKy8qKgorICogVGhlIGNsYXNzIHNwZWNpZnlpbmcgdGhlIGludGVyZmFjZSB0byBleHRlbmQgdGhlIGNlcnRpZmljYXRpb24gcGF0aAorICogdmFsaWRhdGlvbiBhbGdvcml0aG0gYnkgY2hlY2tzIHRvIHBlcmZvcm0gb24gYW4ge0Bjb2RlIFg1MDlDZXJ0aWZpY2F0ZX0uCisgKiA8cD4KKyAqIFRoZSBjaGVja3MgYXJlIGFkZGVkIHRvIGEgY2VydGlmaWNhdGlvbiBwYXRoIHZhbGlkYXRpb24gdXNpbmcgdGhlCisgKiB7QGxpbmsgUEtJWFBhcmFtZXRlcnMjc2V0Q2VydFBhdGhDaGVja2VycyhqYXZhLnV0aWwuTGlzdCkKKyAqIHNldENlcnRQYXRoQ2hlY2tlcnN9IG9yCisgKiB7QGxpbmsgUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzI2FkZENlcnRQYXRoQ2hlY2tlcihQS0lYQ2VydFBhdGhDaGVja2VyKQorICogYWRkQ2VydFBhdGhDaGVja2VyfSBvZiB0aGUge0Bjb2RlIFBLSVhQYXJhbWV0ZXJzfSBhbmQge0Bjb2RlCisgKiBQS0lYQnVpbGRlclBhcmFtZXRlcnN9IGNsYXNzIHJlc3BlY3RpdmVseS4gVGhlCisgKiB7QGxpbmsgI2NoZWNrKENlcnRpZmljYXRlLCBDb2xsZWN0aW9uKSBjaGVja30gbWV0aG9kIHdpbGwgYmUgY2FsbGVkIGZvciBlYWNoCisgKiBjZXJ0aWZpY2F0ZSBwcm9jZXNzZWQgYnkgYSB7QGNvZGUgQ2VydFBhdGhCdWlsZGVyfSBvZiB7QGNvZGUKKyAqIENlcnRQYXRoVmFsaWRhdG9yfS4KKyAqIDxwPgorICogQSB7QGNvZGUgUEtJWENlcnRQYXRoQ2hlY2tlcn0gaW1wbGVtZW50YXRpb24gPHU+bXVzdDwvdT4gc3VwcG9ydCByZXZlcnNlCisgKiBjaGVja2luZyAoZnJvbSB0cnVzdGVkIENBIHRvIHRhcmdldCkgYW5kIDx1Pm1heTwvdT4gc3VwcG9ydCBmb3J3YXJkIGNoZWNraW5nCisgKiAoZnJvbSB0YXJnZXQgdG8gdHJ1c3RlZCBDQSkuIFRoZSByZXR1cm4gdmFsdWUgb2Yge0Bjb2RlCisgKiBpc0ZvcndhcmRDaGVja2luZ1N1cHBvcnRlZH0gaW5kaWNhdGVzIHdoZXRoZXIgZm9yd2FyZCBjaGVja2luZyBpcyBzdXBwb3J0ZWQuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBQS0lYQ2VydFBhdGhDaGVja2VyIGltcGxlbWVudHMgQ2xvbmVhYmxlIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFBLSVhDZXJ0UGF0aENoZWNrZXJ9IGluc3RhbmNlLgorICAgICAqLworICAgIHByb3RlY3RlZCBQS0lYQ2VydFBhdGhDaGVja2VyKCkge30KKworICAgIC8qKgorICAgICAqIENsb25lcyB0aGlzIHtAY29kZSBQS0lYQ2VydFBhdGhDaGVja2VyfSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNsb25lZCBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIFBLSVhDZXJ0UGF0aENoZWNrZXJ9IGluc3RhbmNlIGZvciBzcGVjaWZpZWQKKyAgICAgKiA8aT5jaGVja2luZyBkaXJlY3Rpb248L2k+LgorICAgICAqCisgICAgICogQHBhcmFtIGZvcndhcmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkaXJlY3Rpb24gb2YgdGhlIGNlcnRpZmljYXRpb24gcGF0aCBwcm9jZXNzaW5nLCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIHRydWV9IGlmIHRoZSBjZXJ0aWZpY2F0ZXMgYXJlIHByb2Nlc3NlZCBpbiBmb3J3YXJkIGRpcmVjdGlvbgorICAgICAqICAgICAgICAgICAgKGZyb20gdGFyZ2V0IHRvIHRydXN0ZWQgQ0EpLCB7QGNvZGUgZmFsc2V9IGlmIHByb2Nlc3NlZCBpbgorICAgICAqICAgICAgICAgICAgcmV2ZXJzZSBkaXJlY3Rpb24gKGZyb20gdHJ1c3RlZCBDQSB0byB0YXJnZXQpLgorICAgICAqIEB0aHJvd3MgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBpbml0aWFsaXphdGlvbiBvZiB0aGlzIHtAY29kZSBQS0lYQ2VydFBhdGhDaGVja2VyfQorICAgICAqICAgICAgICAgICAgIGluc3RhbmNlIGZhaWxzLCBvciBpZiBpdCBjYW5ub3QgcHJvY2VzcyBjZXJ0aWZpY2F0ZXMgaW4gdGhlCisgICAgICogICAgICAgICAgICAgc3BlY2lmaWVkIG9yZGVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGluaXQoYm9vbGVhbiBmb3J3YXJkKQorICAgICAgICB0aHJvd3MgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyB7QGNvZGUgUEtJWENlcnRQYXRoQ2hlY2tlcn0gaW5zdGFuY2Ugc3VwcG9ydHMKKyAgICAgKiA8aT5mb3J3YXJkIGNoZWNraW5nPC9pPi4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMge0Bjb2RlIFBLSVhDZXJ0UGF0aENoZWNrZXJ9IGluc3RhbmNlCisgICAgICogICAgICAgICBzdXBwb3J0cyBmb3J3YXJkIGNoZWNraW5nLCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc0ZvcndhcmRDaGVja2luZ1N1cHBvcnRlZCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGlzdCBvZiBleHRlbnNpb25zIG9mIFguNTA5IGNlcnRpZmljYXRlcyB0aGF0IHRoaXMge0Bjb2RlCisgICAgICogUEtJWENlcnRQYXRoQ2hlY2tlcn0gaXMgYWJsZSB0byBwcm9jZXNzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGlzdCBvZiBleHRlbnNpb25zIG9mIFguNTA5IGNlcnRpZmljYXRlcyB0aGF0IHRoaXMge0Bjb2RlCisgICAgICogICAgICAgICBQS0lYQ2VydFBhdGhDaGVja2VyfSBpcyBhYmxlIHRvIHByb2Nlc3MsIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZQorICAgICAqICAgICAgICAgYXJlIG5vbmUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFNldDxTdHJpbmc+IGdldFN1cHBvcnRlZEV4dGVuc2lvbnMoKTsKKworICAgIC8qKgorICAgICAqIENoZWNrcyB0aGUgc3BlY2lmaWVkIGNlcnRpZmljYXRlIGFuZCByZW1vdmVzIHRoZSBwcm9jZXNzZWQgY3JpdGljYWwKKyAgICAgKiBleHRlbnNpb25zIGZyb20gdGhlIHNwZWNpZmllZCBsaXN0IG9mIFguNTA5IGV4dGVuc2lvbiA8aT5PSUQ8L2k+cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjZXJ0CisgICAgICogICAgICAgICAgICB0aGUgY2VydGlmaWNhdGUuCisgICAgICogQHBhcmFtIHVucmVzb2x2ZWRDcml0RXh0cworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgY3JpdGljYWwgWC41MDkgZXh0ZW5zaW9uIE9JRCBzdHJpbmdzLgorICAgICAqIEB0aHJvd3MgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBjaGVjayhzKSBmYWlsIG9uIHRoZSBzcGVjaWZpZWQgY2VydGlmaWNhdGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgY2hlY2soQ2VydGlmaWNhdGUgY2VydCwgQ29sbGVjdGlvbjxTdHJpbmc+IHVucmVzb2x2ZWRDcml0RXh0cykKKyAgICAgICAgdGhyb3dzIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9QS0lYQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTlmMjZhMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0LmphdmEKQEAgLTAsMCArMSwxMjIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CisKKy8qKgorICogVGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZSByZXN1bHQgb2YgdGhlIFBLSVggY2VydGlmaWNhdGlvbiBwYXRoIHZhbGlkYXRpb24uCisgKgorICogQHNlZSBDZXJ0UGF0aFZhbGlkYXRvcgorICogQHNlZSBDZXJ0UGF0aFZhbGlkYXRvciN2YWxpZGF0ZShDZXJ0UGF0aCwgQ2VydFBhdGhQYXJhbWV0ZXJzKQorICovCitwdWJsaWMgY2xhc3MgUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0IGltcGxlbWVudHMgQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHQgeworICAgIC8vIEEgdHJ1c3QgYW5jaG9yIHVzZWQgZHVyaW5nIHZhbGlkYXRpb24gb2YgY2VydGlmaWNhdGlvbiBwYXRoCisgICAgcHJpdmF0ZSBmaW5hbCBUcnVzdEFuY2hvciB0cnVzdEFuY2hvcjsKKyAgICAvLyBWYWxpZCBwb2xpY3kgdHJlZSByZXN1bHRpbmcgZnJvbSBQS0lYCisgICAgLy8gY2VydGlmaWNhdGlvbiBwYXRoIHZhbGlkYXRpb24gYWxnb3JpdGhtCisgICAgcHJpdmF0ZSBmaW5hbCBQb2xpY3lOb2RlIHBvbGljeVRyZWU7CisgICAgLy8gUHVibGljIGtleSBvZiB0aGUgc3ViamVjdCAodGFyZ2V0KSBjZXJ0aWZpY2F0ZQorICAgIHByaXZhdGUgZmluYWwgUHVibGljS2V5IHN1YmplY3RQdWJsaWNLZXk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBQS0lYQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHR9IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIHRydXN0IGFuY2hvciwgdGhlIHZhbGlkIHBvbGljeSB0cmVlIGFuZCB0aGUgc3ViamVjdCBwdWJsaWMga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIHRydXN0QW5jaG9yCisgICAgICogICAgICAgICAgICB0aGUgdHJ1c3QgYW5jaG9yIGRlc2NyaWJpbmcgdGhlIGNlcnRpZmljYXRpb24gYXV0aG9yaXR5IChDQSkKKyAgICAgKiAgICAgICAgICAgIHRoYXQgc2VydmVkIGFzIHRydXN0IGFuY2hvciBmb3IgdGhlIGNlcnRpZmljYXRpb24gcGF0aC4KKyAgICAgKiBAcGFyYW0gcG9saWN5VHJlZQorICAgICAqICAgICAgICAgICAgdGhlIHZhbGlkIHBvbGljeSB0cmVlIGZyb20gdGhlIHZhbGlkYXRpb24uCisgICAgICogQHBhcmFtIHN1YmplY3RQdWJsaWNLZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdWJqZWN0IHB1YmxpYyBrZXkgZnJvbSB0aGUgdmFsaWRhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0KFRydXN0QW5jaG9yIHRydXN0QW5jaG9yLAorICAgICAgICAgICAgUG9saWN5Tm9kZSBwb2xpY3lUcmVlLCBQdWJsaWNLZXkgc3ViamVjdFB1YmxpY0tleSkgeworICAgICAgICB0aGlzLnRydXN0QW5jaG9yID0gdHJ1c3RBbmNob3I7CisgICAgICAgIHRoaXMucG9saWN5VHJlZSA9IHBvbGljeVRyZWU7CisgICAgICAgIHRoaXMuc3ViamVjdFB1YmxpY0tleSA9IHN1YmplY3RQdWJsaWNLZXk7CisgICAgICAgIGlmICh0aGlzLnRydXN0QW5jaG9yID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidHJ1c3RBbmNob3IgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLnN1YmplY3RQdWJsaWNLZXkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJzdWJqZWN0UHVibGljS2V5ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbGlkIHBvbGljeSB0cmVlIGZyb20gdGhlIHZhbGlkYXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWxpZCBwb2xpY3kgdHJlZSBmcm9tIHRoZSB2YWxpZGF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBQb2xpY3lOb2RlIGdldFBvbGljeVRyZWUoKSB7CisgICAgICAgIHJldHVybiBwb2xpY3lUcmVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN1YmplY3QgcHVibGljIGtleSBmcm9tIHRoZSB2YWxpZGF0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3ViamVjdCBwdWJsaWMga2V5IGZyb20gdGhlIHZhbGlkYXRpb24uCisgICAgICovCisgICAgcHVibGljIFB1YmxpY0tleSBnZXRQdWJsaWNLZXkoKSB7CisgICAgICAgIHJldHVybiBzdWJqZWN0UHVibGljS2V5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRydXN0IGFuY2hvciBkZXNjcmliaW5nIHRoZSBjZXJ0aWZpY2F0aW9uIGF1dGhvcml0eSAoQ0EpIHRoYXQKKyAgICAgKiBzZXJ2ZWQgYXMgdHJ1c3QgYW5jaG9yIGZvciB0aGlzIGNlcnRpZmljYXRpb24gcGF0aC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHRydXN0IGFuY2hvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgVHJ1c3RBbmNob3IgZ2V0VHJ1c3RBbmNob3IoKSB7CisgICAgICAgIHJldHVybiB0cnVzdEFuY2hvcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9uZXMgdGhpcyB7QGNvZGUgUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0fSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNsb25lZCBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gZm9yIHRoaXMge0Bjb2RlCisgICAgICogUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0fSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gZm9yIHRoaXMge0Bjb2RlCisgICAgICogICAgICAgICBQS0lYQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHR9IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcihzdXBlci50b1N0cmluZygpKTsKKyAgICAgICAgc2IuYXBwZW5kKCI6IFtcbiBUcnVzdCBBbmNob3I6ICIpOworICAgICAgICBzYi5hcHBlbmQodHJ1c3RBbmNob3IudG9TdHJpbmcoKSk7CisgICAgICAgIHNiLmFwcGVuZCgiXG4gUG9saWN5IFRyZWU6ICIpOworICAgICAgICBzYi5hcHBlbmQocG9saWN5VHJlZSA9PSBudWxsID8gIm5vIHZhbGlkIHBvbGljeSB0cmVlXG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBwb2xpY3lUcmVlLnRvU3RyaW5nKCkpOworICAgICAgICBzYi5hcHBlbmQoIlxuIFN1YmplY3QgUHVibGljIEtleTogIik7CisgICAgICAgIHNiLmFwcGVuZChzdWJqZWN0UHVibGljS2V5LnRvU3RyaW5nKCkpOworICAgICAgICBzYi5hcHBlbmQoIlxuXSIpOworICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1BLSVhQYXJhbWV0ZXJzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1BLSVhQYXJhbWV0ZXJzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGUyNGRmZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvUEtJWFBhcmFtZXRlcnMuamF2YQpAQCAtMCwwICsxLDU5MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworLyoqCisgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgdGhlIHBhcmFtZXRlcnMgZm9yIHRoZSB7QGNvZGUgUEtJWCBDZXJ0UGF0aFZhbGlkYXRvcn0uCisgKiA8cD4KKyAqIFRoZSBwYXJhbWV0ZXJzIG11c3QgYmUgY3JlYXRlZCB3aXRoIDxpPnRydXN0ZWQ8L2k+IGNlcnRpZmljYXRlIGF1dGhvcml0aWVzCisgKiAodHJ1c3QgYW5jaG9ycykuCisgKgorICogQHNlZSBDZXJ0UGF0aFZhbGlkYXRvcgorICogQHNlZSBDZXJ0UGF0aFBhcmFtZXRlcnMKKyAqLworcHVibGljIGNsYXNzIFBLSVhQYXJhbWV0ZXJzIGltcGxlbWVudHMgQ2VydFBhdGhQYXJhbWV0ZXJzIHsKKyAgICAvLyBTZXQgb2YgdHJ1c3QgYW5jaG9ycyAtIG1vc3QgdHJ1c3RlZCBDQXMKKyAgICBwcml2YXRlIFNldDxUcnVzdEFuY2hvcj4gdHJ1c3RBbmNob3JzOworICAgIC8vIFNldCBvZiBhY2NlcHRhYmxlIGluaXRpYWwgcG9saWN5IGlkZW50aWZpZXJzIChPSUQgc3RyaW5ncykKKyAgICBwcml2YXRlIFNldDxTdHJpbmc+IGluaXRpYWxQb2xpY2llczsKKyAgICAvLyBMaXN0IG9mIGNlcnQgc3RvcmVzIHRoYXQgdXNlZCB0byBmaW5kIGNlcnRpZmljYXRlcyBhbmQgQ1JMcworICAgIHByaXZhdGUgTGlzdDxDZXJ0U3RvcmU+IGNlcnRTdG9yZXM7CisgICAgLy8gVGltZSBmb3Igd2hpY2ggdGhlIHZhbGlkaXR5IG9mIHRoZSBjZXJ0aWZpY2F0aW9uCisgICAgLy8gcGF0Y2ggc2hvdWxkIGJlIGRldGVybWluZWQKKyAgICBwcml2YXRlIERhdGUgZGF0ZTsKKyAgICAvLyBMaXN0IG9mIGNlcnRpZmljYXRpb24gcGF0Y2ggY2hlY2tlcnMgKFBLSVhDZXJ0UGF0aENoZWNrZXIpCisgICAgcHJpdmF0ZSBMaXN0PFBLSVhDZXJ0UGF0aENoZWNrZXI+IGNlcnRQYXRoQ2hlY2tlcnM7CisgICAgLy8gUHJlZmVycmVkIHNpZ25hdHVyZSBwcm92aWRlciBuYW1lCisgICAgcHJpdmF0ZSBTdHJpbmcgc2lnUHJvdmlkZXI7CisgICAgLy8gUmVxdWlyZWQgY29uc3RyYWludHMgb24gdGhlIHRhcmdldCBjZXJ0aWZpY2F0ZQorICAgIHByaXZhdGUgQ2VydFNlbGVjdG9yIHRhcmdldENlcnRDb25zdHJhaW50czsKKyAgICAvLyBJbmRpY2F0ZXMgd2hldGhlciBjZXJ0IHJldm9jYXRpb24gaXMgZW5hYmxlZCBvciBub3QKKyAgICBwcml2YXRlIGJvb2xlYW4gcmV2b2NhdGlvbkVuYWJsZWQgPSB0cnVlOworICAgIC8vIEluZGljYXRlcyB3aGV0aGVyIGV4cGxpY2l0IHBvbGljeSByZXF1aXJlZCBvciBub3QKKyAgICBwcml2YXRlIGJvb2xlYW4gZXhwbGljaXRQb2xpY3lSZXF1aXJlZCA9IGZhbHNlOworICAgIC8vIEluZGljYXRlcyB3aGV0aGVyIHBvbGljeSBtYXBwaW5nIGluaGliaXRlZCBvciBub3QKKyAgICBwcml2YXRlIGJvb2xlYW4gcG9saWN5TWFwcGluZ0luaGliaXRlZCA9IGZhbHNlOworICAgIC8vIEluZGljYXRlcyB3aGV0aGVyIGFueSBwb2xpY3kgaW5oaWJpdGVkIG9yIG5vdAorICAgIHByaXZhdGUgYm9vbGVhbiBhbnlQb2xpY3lJbmhpYml0ZWQgPSBmYWxzZTsKKyAgICAvLyBJbmRpY2F0ZXMgd2hldGhlciBjZXJ0aWZpY2F0ZXMgdGhhdCBpbmNsdWRlIHBvbGljeQorICAgIC8vIHF1YWxpZmllcnMgaW4gYSBjZXJ0aWZpY2F0ZSBwb2xpY2llcyBleHRlbnNpb24gdGhhdAorICAgIC8vIGlzIG1hcmtlZCBjcml0aWNhbCBtdXN0IGJlIHJlamVjdGVkIG9yIG5vdAorICAgIHByaXZhdGUgYm9vbGVhbiBwb2xpY3lRdWFsaWZpZXJzUmVqZWN0ZWQgPSB0cnVlOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgUEtJWFBhcmFtZXRlcnN9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBzZXQgb2YKKyAgICAgKiA8aT50cnVzdGVkPC9pPiBjZXJ0aWZpY2F0ZSBhdXRob3JpdGllcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0cnVzdEFuY2hvcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSB0cnVzdGVkIENBcy4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgdHJ1c3RBbmNob3JzfSBpcyBlbXB0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUEtJWFBhcmFtZXRlcnMoU2V0PFRydXN0QW5jaG9yPiB0cnVzdEFuY2hvcnMpCisgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRydXN0QW5jaG9ycyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInRydXN0QW5jaG9ycyA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tUcnVzdEFuY2hvcnModHJ1c3RBbmNob3JzKTsKKyAgICAgICAgdGhpcy50cnVzdEFuY2hvcnMgPSBuZXcgSGFzaFNldDxUcnVzdEFuY2hvcj4odHJ1c3RBbmNob3JzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBQS0lYUGFyYW1ldGVyc30gaW5zdGFuY2Ugd2l0aCB0aGUgdHJ1c3RlZCB7QGNvZGUKKyAgICAgKiBYNTA5Q2VydGlmaWNhdGV9IGVudHJpZXMgZnJvbSB0aGUgc3BlY2lmaWVkIHtAY29kZSBLZXlTdG9yZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5U3RvcmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgc3RvcmUgY29udGFpbmluZyB0cnVzdGVkIGNlcnRpZmljYXRlcy4KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBrZXlTdG9yZX0gaXMgbm90IGluaXRpYWxpemVkLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBrZXlTdG9yZX0gZG9lcyBub3QgY29udGFpbmVkIGFueSB0cnVzdGVkCisgICAgICogICAgICAgICAgICAgY2VydGlmaWNhdGUgZW50cnkuCisgICAgICovCisgICAgcHVibGljIFBLSVhQYXJhbWV0ZXJzKEtleVN0b3JlIGtleVN0b3JlKQorICAgICAgICB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24sCisgICAgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGtleVN0b3JlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigia2V5U3RvcmUgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIC8vIFdpbGwgdGhyb3cgS2V5U3RvcmVFeGNlcHRpb24gaWYKKyAgICAgICAgLy8ga2V5U3RvcmUgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkIChsb2FkZWQpCisgICAgICAgIGlmIChrZXlTdG9yZS5zaXplKCkgPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24oImtleVN0b3JlLnNpemUoKSA9PSAwIik7CisgICAgICAgIH0KKyAgICAgICAgLy8ga2V5U3RvcmUgaXMgbm90IG51bGwgYW5kIGxvYWRlZAorICAgICAgICB0cnVzdEFuY2hvcnMgPSBuZXcgSGFzaFNldDxUcnVzdEFuY2hvcj4oKTsKKyAgICAgICAgZm9yIChFbnVtZXJhdGlvbiBpID0ga2V5U3RvcmUuYWxpYXNlcygpOyBpLmhhc01vcmVFbGVtZW50cygpOykgeworICAgICAgICAgICAgU3RyaW5nIGFsaWFzID0gKFN0cmluZykgaS5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgaWYgKGtleVN0b3JlLmlzQ2VydGlmaWNhdGVFbnRyeShhbGlhcykpIHsKKyAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIHRydXN0ZWQgY2VydGlmaWNhdGUgZW50cnkKKyAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBpdCBpcyBYNTA5Q2VydGlmaWNhdGUKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBjID0ga2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGUoYWxpYXMpOworICAgICAgICAgICAgICAgIC8vIGFkZCBvbmx5IFg1MDlDZXJ0aWZpY2F0ZQorICAgICAgICAgICAgICAgIC8vIGlnbm9yZSBhbGwgb3RoZXIgdHlwZXMKKyAgICAgICAgICAgICAgICBpZiAoYyBpbnN0YW5jZW9mIFg1MDlDZXJ0aWZpY2F0ZSkgeworICAgICAgICAgICAgICAgICAgICB0cnVzdEFuY2hvcnMuYWRkKG5ldyBUcnVzdEFuY2hvcigoWDUwOUNlcnRpZmljYXRlKWMsIG51bGwpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tUcnVzdEFuY2hvcnModHJ1c3RBbmNob3JzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgdW5tb2RpZmlhYmxlIHNldCBvZiB0aGUgPGk+dHJ1c3RlZDwvaT4gY2VydGlmaWNhdGUgYXV0aG9yaXRpZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgdW5tb2RpZmlhYmxlIHNldCBvZiB0aGUgPGk+dHJ1c3RlZDwvaT4gY2VydGlmaWNhdGUgYXV0aG9yaXRpZXMuCisgICAgICovCisgICAgcHVibGljIFNldDxUcnVzdEFuY2hvcj4gZ2V0VHJ1c3RBbmNob3JzKCkgeworICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KHRydXN0QW5jaG9ycyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc2V0IG9mIDxpPnRydXN0ZWQ8L2k+IGNlcnRpZmljYXRlIGF1dGhvcml0aWVzLgorICAgICAqCisgICAgICogQHBhcmFtIHRydXN0QW5jaG9ycworICAgICAqICAgICAgICAgICAgdGhlIHNldCBvZiA8aT50cnVzdGVkPC9pPiBjZXJ0aWZpY2F0ZSBhdXRob3JpdGllcy4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgdHJ1c3RBbmNob3JzfSBpcyBlbXB0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUcnVzdEFuY2hvcnMoU2V0PFRydXN0QW5jaG9yPiB0cnVzdEFuY2hvcnMpCisgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRydXN0QW5jaG9ycyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInRydXN0QW5jaG9ycyA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tUcnVzdEFuY2hvcnModHJ1c3RBbmNob3JzKTsKKyAgICAgICAgLy8gbWFrZSBzaGFsbG93IGNvcHkKKyAgICAgICAgdGhpcy50cnVzdEFuY2hvcnMgPSBuZXcgSGFzaFNldDxUcnVzdEFuY2hvcj4odHJ1c3RBbmNob3JzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIDxpPmFueSBwb2xpY3kgT0lEPC9pPiB3aWxsIGJlIGluaGliaXRlZCBpZiBpdCdzCisgICAgICogaW5jbHVkZWQgaW4gYSBjZXJ0aWZpY2F0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSA8aT5hbnkgcG9saWN5IE9JRDwvaT4gd2lsbCBiZSBpbmhpYml0ZWQsCisgICAgICogICAgICAgICBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0FueVBvbGljeUluaGliaXRlZCgpIHsKKyAgICAgICAgcmV0dXJuIGFueVBvbGljeUluaGliaXRlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHdoZXRoZXIgdGhlIDxpPmFueSBwb2xpY3kgT0lEPC9pPiBzaG91bGQgYmUgaW5oaWJpdGVkIGlmIGl0J3MKKyAgICAgKiBpbmNsdWRlZCBpbiBhIGNlcnRpZmljYXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGFueVBvbGljeUluaGliaXRlZAorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGlmIHRoZSA8aT5hbnkgcG9saWN5IE9JRDwvaT4gc2hvdWxkIGJlIGluaGliaXRlZCwKKyAgICAgKiAgICAgICAgICAgIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEFueVBvbGljeUluaGliaXRlZChib29sZWFuIGFueVBvbGljeUluaGliaXRlZCkgeworICAgICAgICB0aGlzLmFueVBvbGljeUluaGliaXRlZCA9IGFueVBvbGljeUluaGliaXRlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIGNoZWNrZXJzIGZvciB0aGUgY2VydGlmaWNhdGlvbiBwYXRoLgorICAgICAqIDxwPgorICAgICAqIFRoZSBsaXN0IGlzIHVubW9kaWZpYWJsZSBhbmQgdGhlIGVudHJpZXMgaW4gdGhlIGxpc3QgYXJlIGNsb25lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxpc3Qgb2YgY2hlY2tlcnMgZm9yIHRoZSBjZXJ0aWZpY2F0aW9uIHBhdGguCisgICAgICovCisgICAgcHVibGljIExpc3Q8UEtJWENlcnRQYXRoQ2hlY2tlcj4gZ2V0Q2VydFBhdGhDaGVja2VycygpIHsKKyAgICAgICAgaWYgKGNlcnRQYXRoQ2hlY2tlcnMgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gc2V0IHRvIGVtcHR5IExpc3QgaWYgaGFzIG5vdCBiZWVuIHNldCB5ZXQKKyAgICAgICAgICAgIGNlcnRQYXRoQ2hlY2tlcnMgPSBuZXcgQXJyYXlMaXN0PFBLSVhDZXJ0UGF0aENoZWNrZXI+KCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNlcnRQYXRoQ2hlY2tlcnMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAvLyBubyBjb250ZW50IC0gbm8gbmVlZCB0byBjb3B5LAorICAgICAgICAgICAgLy8ganVzdCByZXR1cm4gaW1tdXRhYmxlIHZpZXcgb2YgdGhlIHNhbWUKKyAgICAgICAgICAgIC8vIGVtcHR5IExpc3QgZWFjaCB0aW1lCisgICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChjZXJ0UGF0aENoZWNrZXJzKTsKKyAgICAgICAgfQorICAgICAgICAvLyBMaXN0IGlzIG5vdCBlbXB0eSAtIGRvIGRlZXAgY29weQorICAgICAgICBBcnJheUxpc3Q8UEtJWENlcnRQYXRoQ2hlY2tlcj4gbW9kaWZpYWJsZUxpc3QgPSBuZXcgQXJyYXlMaXN0PFBLSVhDZXJ0UGF0aENoZWNrZXI+KCk7CisgICAgICAgIGZvciAoUEtJWENlcnRQYXRoQ2hlY2tlciBjZXJ0UGF0aENoZWNrZXIgOiBjZXJ0UGF0aENoZWNrZXJzKSB7CisgICAgICAgICAgICBtb2RpZmlhYmxlTGlzdC5hZGQoKFBLSVhDZXJ0UGF0aENoZWNrZXIpIGNlcnRQYXRoQ2hlY2tlci5jbG9uZSgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChtb2RpZmlhYmxlTGlzdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbGlzdCBvZiBjaGVja2VycyBmb3IgdGhlIGNlcnRpZmljYXRpb24gcGF0aC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbGlzdCBpcyBjb3BpZWQgYW5kIHRoZSBlbnRyaWVzIGFyZSBjbG9uZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2VydFBhdGhDaGVja2VycworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgY2hlY2tlcnMgZm9yIHRoZSBjZXJ0aWZpY2F0aW9uIHBhdGgsIG9yIHtAY29kZQorICAgICAqICAgICAgICAgICAgbnVsbH0gdG8gY2xlYXIgdGhlIGNoZWNrZXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENlcnRQYXRoQ2hlY2tlcnMoTGlzdDxQS0lYQ2VydFBhdGhDaGVja2VyPiBjZXJ0UGF0aENoZWNrZXJzKSB7CisgICAgICAgIGlmIChjZXJ0UGF0aENoZWNrZXJzID09IG51bGwgfHwgY2VydFBhdGhDaGVja2Vycy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIC8vIGVtcHR5IGxpc3Qgb3IgbnVsbCBwcm92aWRlZAorICAgICAgICAgICAgaWYgKHRoaXMuY2VydFBhdGhDaGVja2VycyAhPSBudWxsICYmCisgICAgICAgICAgICAgICAhdGhpcy5jZXJ0UGF0aENoZWNrZXJzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIC8vIGRpc2NhcmQgbm9uLWVtcHR5IGxpc3QKKyAgICAgICAgICAgICAgICB0aGlzLmNlcnRQYXRoQ2hlY2tlcnMgPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIC8vIG5vbi1lbXB0eSBsaXN0IHByb3ZpZGVkIC0gZG8gZGVlcCBjb3B5CisgICAgICAgIHRoaXMuY2VydFBhdGhDaGVja2VycyA9IG5ldyBBcnJheUxpc3Q8UEtJWENlcnRQYXRoQ2hlY2tlcj4oKTsKKyAgICAgICAgZm9yIChQS0lYQ2VydFBhdGhDaGVja2VyIGNlcnRQYXRoQ2hlY2tlciA6IGNlcnRQYXRoQ2hlY2tlcnMpIHsKKyAgICAgICAgICAgIHRoaXMuY2VydFBhdGhDaGVja2Vycy5hZGQoKFBLSVhDZXJ0UGF0aENoZWNrZXIpIGNlcnRQYXRoQ2hlY2tlci5jbG9uZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIHNwZWNpZmllZCB7QGNvZGUgUEtJWENlcnRQYXRoQ2hlY2tlcn0gdG8gdGhlIGxpc3Qgb2YKKyAgICAgKiBjZXJ0aWZpY2F0aW9uIHBhdGggY2hlY2tlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hlY2tlcgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBQS0lYQ2VydFBhdGhDaGVja2VyfSB0byBhZGQsIGlmIHtAY29kZSBudWxsfSwgaXQKKyAgICAgKiAgICAgICAgICAgIHdpbGwgYmUgaWdub3JlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRDZXJ0UGF0aENoZWNrZXIoUEtJWENlcnRQYXRoQ2hlY2tlciBjaGVja2VyKSB7CisgICAgICAgIGlmIChjaGVja2VyID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcgaWYgbnVsbCBwcm92aWRlZAorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGlmIChjZXJ0UGF0aENoZWNrZXJzID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIHNldCB0byBlbXB0eSBMaXN0IGlmIGhhcyBub3QgYmVlbiBzZXQgeWV0CisgICAgICAgICAgICBjZXJ0UGF0aENoZWNrZXJzID0gbmV3IEFycmF5TGlzdDxQS0lYQ2VydFBhdGhDaGVja2VyPigpOworICAgICAgICB9CisgICAgICAgIC8vIGFkZCBhIGNvcHkgdG8gYXZvaWQgcG9zc2libGUgbW9kaWZpY2F0aW9ucworICAgICAgICBjZXJ0UGF0aENoZWNrZXJzLmFkZCgoUEtJWENlcnRQYXRoQ2hlY2tlcikgY2hlY2tlci5jbG9uZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIGNlcnRpZmljYXRlIHN0b3JlcyB0aGF0IGFyZSB1c2VkIHRvIGZpbmQgY2VydGlmaWNhdGVzCisgICAgICogYW5kIENSTHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGltbXV0YWJsZSBsaXN0IG9mIGNlcnRpZmljYXRlIHN0b3Jlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxDZXJ0U3RvcmU+IGdldENlcnRTdG9yZXMoKSB7CisgICAgICAgIGlmIChjZXJ0U3RvcmVzID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIHNldCB0byBlbXB0eSBMaXN0IGlmIGhhcyBub3QgYmVlbiBzZXQgeWV0CisgICAgICAgICAgICBjZXJ0U3RvcmVzID0gbmV3IEFycmF5TGlzdDxDZXJ0U3RvcmU+KCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNlcnRTdG9yZXMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAvLyBubyBjb250ZW50IC0gbm8gbmVlZCB0byBjb3B5LAorICAgICAgICAgICAgLy8ganVzdCByZXR1cm4gaW1tdXRhYmxlIHZpZXcgb2YgdGhlIHNhbWUKKyAgICAgICAgICAgIC8vIGVtcHR5IExpc3QgZWFjaCB0aW1lCisgICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChjZXJ0U3RvcmVzKTsKKyAgICAgICAgfQorICAgICAgICAvLyBMaXN0IGlzIG5vdCBlbXB0eSAtIGRvIHNoYWxsb3cgY29weQorICAgICAgICBBcnJheUxpc3Q8Q2VydFN0b3JlPiBtb2RpZmlhYmxlTGlzdAorICAgICAgICAgICAgPSBuZXcgQXJyYXlMaXN0PENlcnRTdG9yZT4oY2VydFN0b3Jlcyk7CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KG1vZGlmaWFibGVMaXN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGUgc3RvcmVzIHRoYXQgYXJlIHVzZWQgdG8gZmluZCBjZXJ0aWZpY2F0ZXMgYW5kCisgICAgICogQ1JMcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjZXJ0U3RvcmVzIHRoZSBsaXN0IG9mIGNlcnRpZmljYXRlIHN0b3Jlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDZXJ0U3RvcmVzKExpc3Q8Q2VydFN0b3JlPiBjZXJ0U3RvcmVzKSB7CisgICAgICAgIGlmIChjZXJ0U3RvcmVzID09IG51bGwgfHwgY2VydFN0b3Jlcy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIC8vIGVtcHR5IGxpc3Qgb3IgbnVsbCBwcm92aWRlZAorICAgICAgICAgICAgaWYgKHRoaXMuY2VydFN0b3JlcyAhPSBudWxsICYmICF0aGlzLmNlcnRTdG9yZXMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgLy8gZGlzY2FyZCBub24tZW1wdHkgbGlzdAorICAgICAgICAgICAgICAgIHRoaXMuY2VydFN0b3JlcyA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgLy8gbm9uLWVtcHR5IGxpc3QgcHJvdmlkZWQgLSBkbyBzaGFsbG93IGNvcHkKKyAgICAgICAgdGhpcy5jZXJ0U3RvcmVzID0gbmV3IEFycmF5TGlzdDxDZXJ0U3RvcmU+KGNlcnRTdG9yZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSBjZXJ0aWZpY2F0ZSBzdG9yZSB0byB0aGUgbGlzdCBvZiBjZXJ0aWZpY2F0ZSBzdG9yZXMgdGhhdCBhcmUgdXNlZAorICAgICAqIHRvIGZpbmQgY2VydGlmaWNhdGVzIGFuZCBDUkxzLgorICAgICAqCisgICAgICogQHBhcmFtIHN0b3JlCisgICAgICogICAgICAgICAgICB0aGUgc3RvcmUgdG8gYWRkLCBpZiB7QGNvZGUgbnVsbH0sIGl0IHdpbGwgYmUgaWdub3JlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRDZXJ0U3RvcmUoQ2VydFN0b3JlIHN0b3JlKSB7CisgICAgICAgIGlmIChzdG9yZSA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBkbyBub3RoaW5nIGlmIG51bGwgcHJvdmlkZWQKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2VydFN0b3JlcyA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBzZXQgdG8gZW1wdHkgTGlzdCBpZiBoYXMgbm90IGJlZW4gc2V0IHlldAorICAgICAgICAgICAgY2VydFN0b3JlcyA9IG5ldyBBcnJheUxpc3Q8Q2VydFN0b3JlPigpOworICAgICAgICB9CisgICAgICAgIC8vIGFkZCBzdG9yZQorICAgICAgICBjZXJ0U3RvcmVzLmFkZChzdG9yZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGltZSBmb3Igd2hpY2ggdGhlIHZhbGlkYXRpb24gb2YgdGhlIGNlcnRpZmljYXRpb24gcGF0aAorICAgICAqIHNob3VsZCBiZSBldmFsdWF0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB0aW1lIGZvciB0aGUgdmFsaWRhdGlvbiwgb3Ige0Bjb2RlIG51bGx9IGZvciB0aGUgY3VycmVudAorICAgICAqICAgICAgICAgdGltZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0ZSBnZXREYXRlKCkgeworICAgICAgICByZXR1cm4gZGF0ZSA9PSBudWxsID8gbnVsbCA6IChEYXRlKWRhdGUuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB0aW1lIGZvciB3aGljaCB0aGUgdmFsaWRhdGlvbiBvZiB0aGUgY2VydGlmaWNhdGlvbiBwYXRoIHNob3VsZCBiZQorICAgICAqIGV2YWx1YXRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRlCisgICAgICogICAgICAgICAgICB0aGUgdGltZSBmb3IgdGhlIHZhbGlkYXRpb24sIG9yIHtAY29kZSBudWxsfSBmb3IgdGhlIGN1cnJlbnQKKyAgICAgKiAgICAgICAgICAgIHRpbWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGF0ZShEYXRlIGRhdGUpIHsKKyAgICAgICAgdGhpcy5kYXRlID0gKGRhdGUgPT0gbnVsbCA/IG51bGwgOiBuZXcgRGF0ZShkYXRlLmdldFRpbWUoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciBhbiBhY2NlcHRhYmxlIHBvbGljeSBuZWVkcyB0byBiZSBleHBsaWNpdCBpZGVudGlmaWVkIGluCisgICAgICogZXZlcnkgY2VydGlmaWNhdGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBhbiBleHBsaWNpdCBwb2xpY3kgaXMgcmVxdWlyZWQsIG90aGVyd2lzZSB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZhbHNlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0V4cGxpY2l0UG9saWN5UmVxdWlyZWQoKSB7CisgICAgICAgIHJldHVybiBleHBsaWNpdFBvbGljeVJlcXVpcmVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgd2hldGhlciBhbiBhbiBhY2NlcHRhYmxlIHBvbGljeSBuZWVkcyB0byBiZSBleHBsaWNpdCBpZGVudGlmaWVkIGluCisgICAgICogZXZlcnkgY2VydGlmaWNhdGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhwbGljaXRQb2xpY3lSZXF1aXJlZAorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGlmIGFuIGV4cGxpY2l0IHBvbGljeSBpcyByZXF1aXJlZCwgb3RoZXJ3aXNlCisgICAgICogICAgICAgICAgICB7QGNvZGUgZmFsc2V9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEV4cGxpY2l0UG9saWN5UmVxdWlyZWQoYm9vbGVhbiBleHBsaWNpdFBvbGljeVJlcXVpcmVkKSB7CisgICAgICAgIHRoaXMuZXhwbGljaXRQb2xpY3lSZXF1aXJlZCA9IGV4cGxpY2l0UG9saWN5UmVxdWlyZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGlzdCBvZiBwb2xpY2llcyAoYXMgT0lEIHN0cmluZ3MpIHRoYXQgd291bGQgYmUgYWNjZXB0YWJsZQorICAgICAqIGZvciB0aGUgcHVycG9zZSBvZiBjZXJ0aWZpY2F0aW9uIHBhdGggcHJvY2Vzc2luZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHVubW9kaWZpYWJsZSBsaXN0IG9mIHBvbGljaWVzLCBvciBhbiBlbXB0eSBzZXQgaWYgYW55IHBvbGljeQorICAgICAqICAgICAgICAgaXMgYWNjZXB0YWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2V0PFN0cmluZz4gZ2V0SW5pdGlhbFBvbGljaWVzKCkgeworICAgICAgICBpZiAoaW5pdGlhbFBvbGljaWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIHNldCB0byBlbXB0eSBTZXQgaWYgaGFzIG5vdCBiZWVuIHNldCB5ZXQKKyAgICAgICAgICAgIGluaXRpYWxQb2xpY2llcyA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5pdGlhbFBvbGljaWVzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgLy8gbm8gY29udGVudCAtIG5vIG5lZWQgdG8gY29weSwKKyAgICAgICAgICAgIC8vIGp1c3QgcmV0dXJuIGltbXV0YWJsZSB2aWV3IG9mIHRoZSBzYW1lCisgICAgICAgICAgICAvLyBlbXB0eSBTZXQgZWFjaCB0aW1lCisgICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KGluaXRpYWxQb2xpY2llcyk7CisgICAgICAgIH0KKyAgICAgICAgLy8gTGlzdCBpcyBub3QgZW1wdHkgLSBkbyBzaGFsbG93IGNvcHkKKyAgICAgICAgSGFzaFNldDxTdHJpbmc+IG1vZGlmaWFibGVTZXQgPSBuZXcgSGFzaFNldDxTdHJpbmc+KGluaXRpYWxQb2xpY2llcyk7CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVTZXQobW9kaWZpYWJsZVNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbGlzdCBvZiBwb2xpY2llcyAoYXMgT0lEIHN0cmluZ3MpIHRoYXQgd291bGQgYmUgYWNjZXB0YWJsZSBmb3IKKyAgICAgKiB0aGUgcHVycG9zZSBvZiBjZXJ0aWZpY2F0aW9uIHBhdGggcHJvY2Vzc2luZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbml0aWFsUG9saWNpZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IG9mIHBvbGljaWVzLCBvciBhbiBlbXB0eSBzZXQgb3Ige0Bjb2RlIG51bGx9IGlmIGFueQorICAgICAqICAgICAgICAgICAgcG9saWN5IGlzIGFjY2VwdGFibGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SW5pdGlhbFBvbGljaWVzKFNldDxTdHJpbmc+IGluaXRpYWxQb2xpY2llcykgeworICAgICAgICBpZiAoaW5pdGlhbFBvbGljaWVzID09IG51bGwgfHwgaW5pdGlhbFBvbGljaWVzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgLy8gZW1wdHkgbGlzdCBvciBudWxsIHByb3ZpZGVkCisgICAgICAgICAgICBpZiAodGhpcy5pbml0aWFsUG9saWNpZXMgIT0gbnVsbCAmJiAhdGhpcy5pbml0aWFsUG9saWNpZXMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgLy8gZGlzY2FyZCBub24tZW1wdHkgbGlzdAorICAgICAgICAgICAgICAgIHRoaXMuaW5pdGlhbFBvbGljaWVzID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICAvLyBub24tZW1wdHkgbGlzdCBwcm92aWRlZCAtIGRvIHNoYWxsb3cgY29weQorICAgICAgICB0aGlzLmluaXRpYWxQb2xpY2llcyA9IG5ldyBIYXNoU2V0PFN0cmluZz4oaW5pdGlhbFBvbGljaWVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgcG9saWN5IG1hcHBpbmcgaXMgaW5oaWJpdGVkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgcG9saWN5IG1hcHBpbmcgaXMgaW5oaWJpdGVkLCBvdGhlcndpc2Uge0Bjb2RlCisgICAgICogICAgICAgICBmYWxzZX0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNQb2xpY3lNYXBwaW5nSW5oaWJpdGVkKCkgeworICAgICAgICByZXR1cm4gcG9saWN5TWFwcGluZ0luaGliaXRlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHdoZXRoZXIgcG9saWN5IG1hcHBpbmcgaXMgdG8gYmUgaW5oaWJpdGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHBvbGljeU1hcHBpbmdJbmhpYml0ZWQKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSB0cnVlfSBpZiBwb2xpY3kgbWFwcGluZyBpcyB0byBiZSBpbmhpYml0ZWQsIG90aGVyd2lzZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIGZhbHNlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQb2xpY3lNYXBwaW5nSW5oaWJpdGVkKGJvb2xlYW4gcG9saWN5TWFwcGluZ0luaGliaXRlZCkgeworICAgICAgICB0aGlzLnBvbGljeU1hcHBpbmdJbmhpYml0ZWQgPSBwb2xpY3lNYXBwaW5nSW5oaWJpdGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciBjZXJ0aWZpY2F0ZXMgYXJlIHJlamVjdGVkIHRoYXQgaW5jbHVkZSBwb2xpY3kKKyAgICAgKiBxdWFsaWZpZXJzIGluIGEgY2VydGlmaWNhdGUgcG9saWN5IGV4dGVuc2lvbiB0aGF0IGlzIG1hcmtlZCBhcyBjcml0aWNhbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBjZXJ0aWZpY2F0ZXMgc2hvdWxkIGJlIHJlamVjdGVkLCBvdGhlcndpc2UKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0UG9saWN5UXVhbGlmaWVyc1JlamVjdGVkKCkgeworICAgICAgICByZXR1cm4gcG9saWN5UXVhbGlmaWVyc1JlamVjdGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgd2hldGhlciBjZXJ0aWZpY2F0ZXMgc2hvdWxkIGJlIHJlamVjdGVkIHRoYXQgaW5jbHVkZSBwb2xpY3kKKyAgICAgKiBxdWFsaWZpZXJzIGluIGEgY2VydGlmaWNhdGUgcG9saWN5IGV4dGVuc2lvbiB0aGF0IGlzIG1hcmtlZCBhcyBjcml0aWNhbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwb2xpY3lRdWFsaWZpZXJzUmVqZWN0ZWQKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSB0cnVlfSBpZiB0aGUgY2VydGlmaWNhdGVzIHNob3VsZCBiZSByZWplY3RlZCwgb3RoZXJ3aXNlCisgICAgICogICAgICAgICAgICB7QGNvZGUgZmFsc2V9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBvbGljeVF1YWxpZmllcnNSZWplY3RlZChib29sZWFuIHBvbGljeVF1YWxpZmllcnNSZWplY3RlZCkgeworICAgICAgICB0aGlzLnBvbGljeVF1YWxpZmllcnNSZWplY3RlZCA9IHBvbGljeVF1YWxpZmllcnNSZWplY3RlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIGRlZmF1bHQgcmV2b2NhdGlvbiBjaGVja2luZyBtZWNoYW5pc20gb2YgdGhlCisgICAgICogdW5kZXJseWluZyBzZXJ2aWNlIHByb3ZpZGVyIGlzIHVzZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZGVmYXVsdCByZXZvY2F0aW9uIGNoZWNraW5nIG1lY2hhbmlzbSBpcworICAgICAqICAgICAgICAgdXNlZCwgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNSZXZvY2F0aW9uRW5hYmxlZCgpIHsKKyAgICAgICAgcmV0dXJuIHJldm9jYXRpb25FbmFibGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgd2hldGhlciB0aGUgZGVmYXVsdCByZXZvY2F0aW9uIGNoZWNraW5nIG1lY2hhbmlzbSBvZiB0aGUgdW5kZXJseWluZworICAgICAqIHNlcnZpY2UgcHJvdmlkZXIgc2hvdWxkIGJlIHVzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmV2b2NhdGlvbkVuYWJsZWQKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSB0cnVlfSBpZCB0aGUgZGVmYXVsdCByZXZvY2F0aW9uIGNoZWNraW5nIG1lY2hhbmlzbQorICAgICAqICAgICAgICAgICAgc2hvdWxkIGJlIHVzZWQsIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFJldm9jYXRpb25FbmFibGVkKGJvb2xlYW4gcmV2b2NhdGlvbkVuYWJsZWQpIHsKKyAgICAgICAgdGhpcy5yZXZvY2F0aW9uRW5hYmxlZCA9IHJldm9jYXRpb25FbmFibGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHNpZ25hdHVyZSBwcm92aWRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIHNpZ25hdHVyZSBwcm92aWRlciwgb3Ige0Bjb2RlIG51bGx9IGlmIG5vbmUgaXMKKyAgICAgKiAgICAgICAgIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFNpZ1Byb3ZpZGVyKCkgeworICAgICAgICByZXR1cm4gc2lnUHJvdmlkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmFtZSBvZiB0aGUgcHJlZmVycmVkIHNpZ25hdHVyZSBwcm92aWRlci4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiBzZXQsIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgd2lsbCBiZSBwcmVmZXJyZWQgZm9yIGNyZWF0aW5nIHNpZ25hdHVyZXMuCisgICAgICogSWYgbm90IHNldCwgdGhlIGZpcnN0IHByb3ZpZGVyIGZvdW5kIHN1cHBvcnRpbmcgY3JlYXRpb24gb2Ygc2lnbmF0dXJlcworICAgICAqIHdpbGwgYmUgdXNlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaWdQcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByZWZlcnJlZCBzaWduYXR1cmUgcHJvdmlkZXIsIG9yIHtAY29kZSBudWxsfQorICAgICAqICAgICAgICAgICAgaWYgbm9uZSBpcyBwcmVmZXJyZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2lnUHJvdmlkZXIoU3RyaW5nIHNpZ1Byb3ZpZGVyKSB7CisgICAgICAgIHRoaXMuc2lnUHJvdmlkZXIgPSBzaWdQcm92aWRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb25zdHJhaW50cyB0aGF0IGFyZSByZXF1aXJlZCBmb3IgdGhlIHRhcmdldCBjZXJ0aWZpY2F0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNvbnN0cmFpbnRzIGZvciB0aGUgdGFyZ2V0IGNlcnRpZmljYXRlLCBvciB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiAgICAgICAgIG5vbmUgYXJlIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydFNlbGVjdG9yIGdldFRhcmdldENlcnRDb25zdHJhaW50cygpIHsKKyAgICAgICAgcmV0dXJuICh0YXJnZXRDZXJ0Q29uc3RyYWludHMgPT0gbnVsbCA/IG51bGwKKyAgICAgICAgICAgICAgICA6KENlcnRTZWxlY3Rvcil0YXJnZXRDZXJ0Q29uc3RyYWludHMuY2xvbmUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY29uc3RyYWludHMgdGhhdCBhcmUgcmVxdWlyZWQgZm9yIHRoZSB0YXJnZXQgY2VydGlmaWNhdGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGFyZ2V0Q2VydENvbnN0cmFpbnRzCisgICAgICogICAgICAgICAgICB0aGUgY29uc3RyYWludHMgZm9yIHRoZSB0YXJnZXQgY2VydGlmaWNhdGUsIG9yIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAgICAgbm9uZSBzaG91bGQgYmUgdXNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUYXJnZXRDZXJ0Q29uc3RyYWludHMoQ2VydFNlbGVjdG9yIHRhcmdldENlcnRDb25zdHJhaW50cykgeworICAgICAgICB0aGlzLnRhcmdldENlcnRDb25zdHJhaW50cyA9ICh0YXJnZXRDZXJ0Q29uc3RyYWludHMgPT0gbnVsbCA/IG51bGwKKyAgICAgICAgICAgICAgICA6IChDZXJ0U2VsZWN0b3IpdGFyZ2V0Q2VydENvbnN0cmFpbnRzLmNsb25lKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb25lcyB0aGlzIHtAY29kZSBQS0lYUGFyYW1ldGVyc30gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjbG9uZWQgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGRvIHNoYWxsb3cgY29weSBmaXJzdAorICAgICAgICAgICAgUEtJWFBhcmFtZXRlcnMgcmV0ID0gKFBLSVhQYXJhbWV0ZXJzKXN1cGVyLmNsb25lKCk7CisgICAgICAgICAgICAvLyBjb3B5IGZpZWxkcyBjb250YWluaW5nIHJlZmVyZW5jZXMgdG8gbXV0YWJsZSBvYmplY3RzCisgICAgICAgICAgICBpZiAodGhpcy5jZXJ0U3RvcmVzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXQuY2VydFN0b3JlcyA9IG5ldyBBcnJheUxpc3Q8Q2VydFN0b3JlPih0aGlzLmNlcnRTdG9yZXMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHRoaXMuY2VydFBhdGhDaGVja2VycyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0LmNlcnRQYXRoQ2hlY2tlcnMgPSBuZXcgQXJyYXlMaXN0PFBLSVhDZXJ0UGF0aENoZWNrZXI+KHRoaXMuY2VydFBhdGhDaGVja2Vycyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmV0OworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMge0Bjb2RlIFBLSVhQYXJhbWV0ZXJzfSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgUEtJWFBhcmFtZXRlcnN9IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPQorICAgICAgICAgICAgbmV3IFN0cmluZ0J1aWxkZXIoIltcbiBUcnVzdCBBbmNob3JzOiAiKTsKKyAgICAgICAgc2IuYXBwZW5kKHRydXN0QW5jaG9ycyk7CisgICAgICAgIHNiLmFwcGVuZCgiXG4gUmV2b2NhdGlvbiBFbmFibGVkOiAiKTsKKyAgICAgICAgc2IuYXBwZW5kKHJldm9jYXRpb25FbmFibGVkKTsKKyAgICAgICAgc2IuYXBwZW5kKCJcbiBFeHBsaWNpdCBQb2xpY3kgUmVxdWlyZWQ6ICIpOworICAgICAgICBzYi5hcHBlbmQoZXhwbGljaXRQb2xpY3lSZXF1aXJlZCk7CisgICAgICAgIHNiLmFwcGVuZCgiXG4gUG9saWN5IE1hcHBpbmcgSW5oaWJpdGVkOiAiKTsKKyAgICAgICAgc2IuYXBwZW5kKHBvbGljeU1hcHBpbmdJbmhpYml0ZWQpOworICAgICAgICBzYi5hcHBlbmQoIlxuIEFueSBQb2xpY3kgSW5oaWJpdGVkOiAiKTsKKyAgICAgICAgc2IuYXBwZW5kKGFueVBvbGljeUluaGliaXRlZCk7CisgICAgICAgIHNiLmFwcGVuZCgiXG4gUG9saWN5IFF1YWxpZmllcnMgUmVqZWN0ZWQ6ICIpOworICAgICAgICBzYi5hcHBlbmQocG9saWN5UXVhbGlmaWVyc1JlamVjdGVkKTsKKyAgICAgICAgc2IuYXBwZW5kKCJcbiBJbml0aWFsIFBvbGljeSBPSURzOiAiKTsKKyAgICAgICAgc2IuYXBwZW5kKChpbml0aWFsUG9saWNpZXMgPT0gbnVsbCB8fCBpbml0aWFsUG9saWNpZXMuaXNFbXB0eSgpKQorICAgICAgICAgICAgICAgID8gImFueSIgOiBpbml0aWFsUG9saWNpZXMudG9TdHJpbmcoKSk7CisgICAgICAgIHNiLmFwcGVuZCgiXG4gQ2VydCBTdG9yZXM6ICIpOworICAgICAgICBzYi5hcHBlbmQoKGNlcnRTdG9yZXM9PW51bGx8fGNlcnRTdG9yZXMuaXNFbXB0eSgpKT8KKyAgICAgICAgICAgICAgICAibm8iOmNlcnRTdG9yZXMudG9TdHJpbmcoKSk7CisgICAgICAgIHNiLmFwcGVuZCgiXG4gVmFsaWRpdHkgRGF0ZTogIik7CisgICAgICAgIHNiLmFwcGVuZChkYXRlKTsKKyAgICAgICAgc2IuYXBwZW5kKCJcbiBDZXJ0IFBhdGggQ2hlY2tlcnM6ICIpOworICAgICAgICBzYi5hcHBlbmQoKGNlcnRQYXRoQ2hlY2tlcnM9PW51bGx8fGNlcnRQYXRoQ2hlY2tlcnMuaXNFbXB0eSgpKT8KKyAgICAgICAgICAgICAgICAibm8iOmNlcnRQYXRoQ2hlY2tlcnMudG9TdHJpbmcoKSk7CisgICAgICAgIHNiLmFwcGVuZCgiXG4gU2lnbmF0dXJlIFByb3ZpZGVyOiAiKTsKKyAgICAgICAgc2IuYXBwZW5kKHNpZ1Byb3ZpZGVyKTsKKyAgICAgICAgc2IuYXBwZW5kKCJcbiBUYXJnZXQgQ2VydGlmaWNhdGUgQ29uc3RyYWludHM6ICIpOworICAgICAgICBzYi5hcHBlbmQodGFyZ2V0Q2VydENvbnN0cmFpbnRzKTsKKyAgICAgICAgc2IuYXBwZW5kKCJcbl0iKTsKKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHRoYXQge0Bjb2RlIHRydXN0QW5jaG9yc30gY29udGFpbnMgb25seSB7QGNvZGUKKyAgICAgKiBUcnVzdEFuY2hvcn0gaW5zdGFuY2VzLgorICAgICAqCisgICAgICogQHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGlmIHRydXN0QW5jaG9ycyBzZXQgaXMgZW1wdHkuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrVHJ1c3RBbmNob3JzKFNldDxUcnVzdEFuY2hvcj4gdHJ1c3RBbmNob3JzKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBpZiAodHJ1c3RBbmNob3JzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24oInRydXN0QW5jaG9ycy5pc0VtcHR5KCkiKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvUG9saWN5Tm9kZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9Qb2xpY3lOb2RlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjUzZTg3MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvUG9saWN5Tm9kZS5qYXZhCkBAIC0wLDAgKzEsODQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKKy8qKgorICogVGhlIGludGVyZmFjZSB0byBhIHZhbGlkIHBvbGljeSB0cmVlIG5vZGUgZm9yIHRoZSBQS0lYIGNlcnRpZmljYXRpb24gcGF0aAorICogdmFsaWRhdGlvbiBhbGdvcml0aG0uCisgKiA8cD4KKyAqIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIGFyZSBvbmUgb2YgdGhlIG91dHB1dHMgb2YgdGhlIFBLSVggY2VydGlmaWNhdGlvbiBwYXRoCisgKiB2YWxpZGF0aW9uIGFsZ29yaXRobS4KKyAqLworcHVibGljIGludGVyZmFjZSBQb2xpY3lOb2RlIHsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxpc3Qgb2YgY2hpbGRyZW4gb2YgdGhpcyBub2RlIGFzIGFuIHtAY29kZSBJdGVyYXRvcn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsaXN0IG9mIGNoaWxkcmVuIG9mIHRoaXMgbm9kZSBhcyBhbiB7QGNvZGUgSXRlcmF0b3J9LgorICAgICAqLworICAgIHB1YmxpYyBJdGVyYXRvcjw/IGV4dGVuZHMgUG9saWN5Tm9kZT4gZ2V0Q2hpbGRyZW4oKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRlcHRoIG9mIHRoaXMgbm9kZSBpbiB0aGUgcG9saWN5IHRyZWUuCisgICAgICogPHA+CisgICAgICogdGhlIGRlcHRoIGlzIHplcm8gYmFzZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkZXB0aCBvZiB0aGlzIG5vZGUgaW4gdGhlIHBvbGljeSB0cmVlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RGVwdGgoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGV4cGVjdGVkIHBvbGljaWVzIGZvciB0aGUgbmV4dCBjZXJ0aWZpY2F0ZSB0byBiZSB2YWxpZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGV4cGVjdGVkIHBvbGljaWVzLgorICAgICAqLworICAgIHB1YmxpYyBTZXQ8U3RyaW5nPiBnZXRFeHBlY3RlZFBvbGljaWVzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwYXJlbnQgcG9saWN5IG5vZGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwYXJlbnQgcG9saWN5IG5vZGUuCisgICAgICovCisgICAgcHVibGljIFBvbGljeU5vZGUgZ2V0UGFyZW50KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwb2xpY3kgcXVhbGlmaWVycyBhc3NvY2lhdGVkIHdpdGggdGhlIHBvbGljeSBvZiB0aGlzIG5vZGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwb2xpY3kgcXVhbGlmaWVycyBhc3NvY2lhdGVkIHdpdGggdGhlIHBvbGljeSBvZiB0aGlzIG5vZGUuCisgICAgICovCisgICAgcHVibGljIFNldDw/IGV4dGVuZHMgUG9saWN5UXVhbGlmaWVySW5mbz4gZ2V0UG9saWN5UXVhbGlmaWVycygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsaWQgcG9saWN5IG9mIHRoaXMgbm9kZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHZhbGlkIHBvbGljeSBvZiB0aGlzIG5vZGUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRWYWxpZFBvbGljeSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBjZXJ0aWZpY2F0ZSBwb2xpY3kgZXh0ZW5zaW9uIG9mIHRoZSBtb3N0IHJlY2VudGx5CisgICAgICogcHJvY2Vzc2VkIGNlcnRpZmljYXRlIGlzIG1hcmtlZCBhcyBjcml0aWNhbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBleHRlbnNpb24gaXMgbWFya2VkIGFzIGNyaXRpY2FsLCBvdGhlcndpc2UKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDcml0aWNhbCgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9Qb2xpY3lRdWFsaWZpZXJJbmZvLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1BvbGljeVF1YWxpZmllckluZm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMTEyNjdkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9Qb2xpY3lRdWFsaWZpZXJJbmZvLmphdmEKQEAgLTAsMCArMSwxMTcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5PYmplY3RJZGVudGlmaWVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS51dGlscy5BcnJheTsKKworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIHBvbGljeSBxdWFsaWZpZXIgYXMgZGVmaW5lZCBieSB0aGUgQVNOLjEKKyAqIHtAY29kZSBQb2xpY3lRdWFsaWZpZXJJbmZvfSBzdHJ1Y3R1cmUuCisgKi8KK3B1YmxpYyBjbGFzcyBQb2xpY3lRdWFsaWZpZXJJbmZvIHsKKyAgICAvLyBUaGlzIFBvbGljeVF1YWxpZmllckluZm8gREVSIGVuY29kaW5nCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gZW5jb2RlZDsKKyAgICAvLyBUaGlzIFBvbGljeVF1YWxpZmllckluZm8gcG9saWN5IHF1YWxpZmllciBpZCAtCisgICAgLy8gT0lEIHJlcHJlc2VudGVkIGFzIFN0cmluZyBjb250YWluaW5nIG5vbi1uZWdhdGl2ZSBpbnRlZ2VycworICAgIC8vIHNlcGFyYXRlZCBieSBwZXJpb2RzCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcG9saWN5UXVhbGlmaWVySWQ7CisgICAgLy8gREVSIGVuY29kaW5nIG9mIHRoZSBwb2xpY3kgcXVhbGlmaWVyIC0gcGFydCBvZiBlbmNvZGVkCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gcG9saWN5UXVhbGlmaWVyOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgUG9saWN5UXVhbGlmaWVySW5mb30gZnJvbSB0aGUgc3BlY2lmaWVkIGVuY29kZWQKKyAgICAgKiBmb3JtLgorICAgICAqCisgICAgICogQHBhcmFtIGVuY29kZWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBERVIgZW5jb2RlZCBwb2xpY3kgcXVhbGlmaWVyLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aGUgcG9saWN5IHF1YWxpZmllciBjYW5ub3QgYmUgZGVjb2RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUG9saWN5UXVhbGlmaWVySW5mbyhieXRlW10gZW5jb2RlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGVuY29kZWQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJlbmNvZGVkID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZW5jb2RlZC5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJlbmNvZGVkLmxlbmd0aCA9PSAwIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5lbmNvZGVkID0gbmV3IGJ5dGVbZW5jb2RlZC5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVuY29kZWQsIDAsIHRoaXMuZW5jb2RlZCwgMCwgdGhpcy5lbmNvZGVkLmxlbmd0aCk7CisKKyAgICAgICAgLy8gREVSIERlY29kaW5nOgorICAgICAgICBPYmplY3RbXSBkZWNvZGVkID0gKE9iamVjdFtdKSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5Qb2xpY3lRdWFsaWZpZXJJbmZvLkFTTjEKKyAgICAgICAgICAgICAgICAuZGVjb2RlKHRoaXMuZW5jb2RlZCk7CisgICAgICAgIHBvbGljeVF1YWxpZmllcklkID0gT2JqZWN0SWRlbnRpZmllci50b1N0cmluZygoaW50W10pIGRlY29kZWRbMF0pOworICAgICAgICBwb2xpY3lRdWFsaWZpZXIgPSAoYnl0ZVtdKSBkZWNvZGVkWzFdOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBBU04uMSBERVIgZW5jb2RlZCBjb3B5IG9mIHBvbGljeSBxdWFsaWZpZXIgaW5mby4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBBU04uMSBERVIgZW5jb2RlZCBjb3B5IG9mIHBvbGljeSBxdWFsaWZpZXIgaW5mby4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGJ5dGVbXSByZXQgPSBuZXcgYnl0ZVtlbmNvZGVkLmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZW5jb2RlZCwgMCwgcmV0LCAwLCBlbmNvZGVkLmxlbmd0aCk7CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaWRlbnRpZmllciAoYW4gT0lEKSBvZiB0aGlzIHBvbGljeSBxdWFsaWZpZXIgaW5mby4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGlkZW50aWZpZXIgb2YgdGhpcyBwb2xpY3kgcXVhbGlmaWVyIGluZm8uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRQb2xpY3lRdWFsaWZpZXJJZCgpIHsKKyAgICAgICAgcmV0dXJuIHBvbGljeVF1YWxpZmllcklkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBBU04uMSBERVIgZW5jb2RlZCBjb3B5IG9mIHRoZSBxdWFsaWZpZXIgb2YgdGhpcyBwb2xpY3kKKyAgICAgKiBxdWFsaWZpZXIgaW5mby4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBBU04uMSBERVIgZW5jb2RlZCBjb3B5IG9mIHRoZSBxdWFsaWZpZXIgb2YgdGhpcyBwb2xpY3kKKyAgICAgKiAgICAgICAgIHF1YWxpZmllciBpbmZvLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBieXRlW10gZ2V0UG9saWN5UXVhbGlmaWVyKCkgeworICAgICAgICBpZiAocG9saWN5UXVhbGlmaWVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSByZXQgPSBuZXcgYnl0ZVtwb2xpY3lRdWFsaWZpZXIubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShwb2xpY3lRdWFsaWZpZXIsIDAsIHJldCwgMCwgcG9saWN5UXVhbGlmaWVyLmxlbmd0aCk7CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZSBQb2xpY3lRdWFsaWZpZXJJbmZvfQorICAgICAqIGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZSBQb2xpY3lRdWFsaWZpZXJJbmZvfQorICAgICAqICAgICAgICAgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9CisgICAgICAgICAgICBuZXcgU3RyaW5nQnVpbGRlcigiUG9saWN5UXVhbGlmaWVySW5mbzogW1xucG9saWN5UXVhbGlmaWVySWQ6ICIpOworICAgICAgICBzYi5hcHBlbmQocG9saWN5UXVhbGlmaWVySWQpOworICAgICAgICBzYi5hcHBlbmQoIlxucG9saWN5UXVhbGlmaWVyOiBcbiIpOworICAgICAgICBzYi5hcHBlbmQoQXJyYXkudG9TdHJpbmcocG9saWN5UXVhbGlmaWVyLCAiICIpKTsKKyAgICAgICAgc2IuYXBwZW5kKCJdIik7CisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvVHJ1c3RBbmNob3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvVHJ1c3RBbmNob3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZmVlZWQ0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9UcnVzdEFuY2hvci5qYXZhCkBAIC0wLDAgKzEsMjc4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnV0aWxzLkFycmF5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5Lk5hbWVDb25zdHJhaW50czsKKworCisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgdHJ1c3QgYW5jaG9yIGZvciB2YWxpZGF0aW9uIG9mIFguNTA5IGNlcnRpZmljYXRpb24KKyAqIHBhdGguCisgKiA8cD4KKyAqIEl0IGlzIGEgPGk+dHJ1c3RlZDwvaT4gY2VydGlmaWNhdGUgYXV0aG9yaXR5IChDQSkgYW5kIGluY2x1ZGVzIHRoZSBwdWJsaWMga2V5CisgKiBvZiB0aGUgQ0EsIHRoZSBDQSdzIG5hbWUgYW5kIHRoZSBjb25zdHJhaW50cyBmb3IgdGhlIHZhbGlkYXRpb24gb2YKKyAqIGNlcnRpZmljYXRpb24gcGF0aHMuIFRoZSBjb25zdHJ1Y3RvciBhbHNvIGFsbG93cyB0byBzcGVjaWZ5IGEgYmluYXJ5CisgKiByZXByZXNlbnRhdGlvbiBvZiBhIHNvIGNhbGxlZCAiTmFtZSBDb25zdHJhaW50cyIgZXh0ZW5zaW9uIGFzIGEgYnl0ZSBhcnJheS4KKyAqLworcHVibGljIGNsYXNzIFRydXN0QW5jaG9yIHsKKyAgICAvLyBNb3N0IHRydXN0ZWQgQ0EgYXMgYSBYNTAwUHJpbmNpcGFsCisgICAgcHJpdmF0ZSBmaW5hbCBYNTAwUHJpbmNpcGFsIGNhUHJpbmNpcGFsOworICAgIC8vIE1vc3QgdHJ1c3RlZCBDQSBuYW1lCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgY2FOYW1lOworICAgIC8vIE1vc3QgdHJ1c3RlZCBDQSBwdWJsaWMga2V5CisgICAgcHJpdmF0ZSBmaW5hbCBQdWJsaWNLZXkgY2FQdWJsaWNLZXk7CisgICAgLy8gTW9zdCB0cnVzdGVkIENBIGNlcnRpZmljYXRlCisgICAgcHJpdmF0ZSBmaW5hbCBYNTA5Q2VydGlmaWNhdGUgdHJ1c3RlZENlcnQ7CisgICAgLy8gTmFtZSBjb25zdHJhaW50cyBleHRlbnNpb24KKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBuYW1lQ29uc3RyYWludHM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBUcnVzdEFuY2hvcn0gd2l0aCB0aGUgc3BlY2lmaWVkIGNlcnRpZmljYXRlIGFuZCBuYW1lCisgICAgICogY29uc3RyYWludHMuCisgICAgICogPHA+CisgICAgICogVGhlIG5hbWUgY29uc3RyYWludHMgd2lsbCBiZSB1c2VkIGFzIGFkZGl0aW9uYWwgY29uc3RyYWludHMgZHVyaW5nIHRoZQorICAgICAqIHZhbGlkYXRpb24gb2YgY2VydGlmaWNhdGlvbiBwYXRocy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0cnVzdGVkQ2VydAorICAgICAqICAgICAgICAgICAgdGhlIHRydXN0ZWQgY2VydGlmaWNhdGUKKyAgICAgKiBAcGFyYW0gbmFtZUNvbnN0cmFpbnRzCisgICAgICogICAgICAgICAgICB0aGUgQVNOLjEgREVSIGVuY29kZWQgZm9ybSBvZiB0aGUgbmFtZSBjb25zdHJhaW50cyBvciB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIG51bGx9IGlmIG5vbmUuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZGVjb2Rpbmcgb2YgdGhlIG5hbWUgY29uc3RyYWludHMgZmFpbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVHJ1c3RBbmNob3IoWDUwOUNlcnRpZmljYXRlIHRydXN0ZWRDZXJ0LCBieXRlW10gbmFtZUNvbnN0cmFpbnRzKSB7CisgICAgICAgIGlmICh0cnVzdGVkQ2VydCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInRydXN0ZWRDZXJ0ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnRydXN0ZWRDZXJ0ID0gdHJ1c3RlZENlcnQ7CisgICAgICAgIC8vIGNvcHkgbmFtZUNvbnN0cmFpbnRzIGlmIG5vdCBudWxsCisgICAgICAgIGlmIChuYW1lQ29uc3RyYWludHMgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhpcy5uYW1lQ29uc3RyYWludHMgPSBuZXcgYnl0ZVtuYW1lQ29uc3RyYWludHMubGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobmFtZUNvbnN0cmFpbnRzLCAwLAorICAgICAgICAgICAgICAgICAgICB0aGlzLm5hbWVDb25zdHJhaW50cywgMCwgdGhpcy5uYW1lQ29uc3RyYWludHMubGVuZ3RoKTsKKyAgICAgICAgICAgIHByb2Nlc3NOYW1lQ29uc3RyYWludHMoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRoaXMubmFtZUNvbnN0cmFpbnRzID0gbnVsbDsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmNhTmFtZSA9IG51bGw7CisgICAgICAgIHRoaXMuY2FQcmluY2lwYWwgPSBudWxsOworICAgICAgICB0aGlzLmNhUHVibGljS2V5ID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBUcnVzdEFuY2hvcn0gd2l0aCB0aGUgc3BlY2lmaWVkIGNlcnRpZmljYXRlCisgICAgICogYXV0aG9yaXR5IG5hbWUsIGl0cyBwdWJsaWMga2V5IGFuZCB0aGUgc3BlY2lmaWVkIG5hbWUgY29uc3RyYWludHMuCisgICAgICogPHA+CisgICAgICogVGhlIG5hbWUgY29uc3RyYWludHMgd2lsbCBiZSB1c2VkIGFzIGFkZGl0aW9uYWwgY29uc3RyYWludHMgZHVyaW5nIHRoZQorICAgICAqIHZhbGlkYXRpb24gb2YgY2VydGlmaWNhdGlvbiBwYXRocy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBYLjUwMCBuYW1lIG9mIHRoZSBjZXJ0aWZpY2F0ZSBhdXRob3JpdHkgaW4gUkZDIDIyNTMKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBTdHJpbmd9IGZvcm1hdC4KKyAgICAgKiBAcGFyYW0gY2FQdWJsaWNLZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBwdWJsaWMga2V5IG9mIHRoZSBjZXJ0aWZpY2F0ZSBhdXRob3JpdHkKKyAgICAgKiBAcGFyYW0gbmFtZUNvbnN0cmFpbnRzCisgICAgICogICAgICAgICAgICB0aGUgQVNOLjEgREVSIGVuY29kZWQgZm9ybSBvZiB0aGUgbmFtZSBjb25zdHJhaW50cyBvciB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIG51bGx9IGlmIG5vbmUuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIGNhTmFtZX0gaXMgZW1wdHkgb3IgaWYgZGVjb2Rpbmcgb2YgdGhlIG5hbWUKKyAgICAgKiAgICAgICAgICAgICBjb25zdHJhaW50cyBmYWlsLgorICAgICAqLworICAgIHB1YmxpYyBUcnVzdEFuY2hvcihTdHJpbmcgY2FOYW1lLCBQdWJsaWNLZXkgY2FQdWJsaWNLZXksCisgICAgICAgICAgICBieXRlW10gbmFtZUNvbnN0cmFpbnRzKSB7CisgICAgICAgIGlmIChjYU5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJjYU5hbWUgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRoaXMuY2FOYW1lID0gY2FOYW1lOworICAgICAgICBpZiAoY2FQdWJsaWNLZXkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJjYVB1YmxpY0tleSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5jYVB1YmxpY0tleSA9IGNhUHVibGljS2V5OworICAgICAgICAvLyBjb3B5IG5hbWVDb25zdHJhaW50cyBpZiBub3QgbnVsbAorICAgICAgICBpZiAobmFtZUNvbnN0cmFpbnRzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMubmFtZUNvbnN0cmFpbnRzID0gbmV3IGJ5dGVbbmFtZUNvbnN0cmFpbnRzLmxlbmd0aF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5hbWVDb25zdHJhaW50cywgMCwKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5uYW1lQ29uc3RyYWludHMsIDAsIHRoaXMubmFtZUNvbnN0cmFpbnRzLmxlbmd0aCk7CisgICAgICAgICAgICBwcm9jZXNzTmFtZUNvbnN0cmFpbnRzKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aGlzLm5hbWVDb25zdHJhaW50cyA9IG51bGw7CisgICAgICAgIH0KKworICAgICAgICB0aGlzLnRydXN0ZWRDZXJ0ID0gbnVsbDsKKworICAgICAgICAvLyBYNTAwUHJpbmNpcGFsIGNoZWNrcyBjYU5hbWUgdmFsaWRpdHkKKyAgICAgICAgaWYgKGNhTmFtZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImNhTmFtZS5pc0VtcHR5KCkiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmNhUHJpbmNpcGFsID0gbmV3IFg1MDBQcmluY2lwYWwodGhpcy5jYU5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFRydXN0QW5jaG9yfSB3aXRoIHRoZSBzcGVjaWZpZWQgY2VydGlmaWNhdGUKKyAgICAgKiBhdXRob3JpdHkgbmFtZSBhcyBwcmluY2lwYWwsIGl0cyBwdWJsaWMga2V5IGFuZCB0aGUgc3BlY2lmaWVkIG5hbWUKKyAgICAgKiBjb25zdHJhaW50cy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbmFtZSBjb25zdHJhaW50cyB3aWxsIGJlIHVzZWQgYXMgYWRkaXRpb25hbCBjb25zdHJhaW50cyBkdXJpbmcgdGhlCisgICAgICogdmFsaWRhdGlvbiBvZiBjZXJ0aWZpY2F0aW9uIHBhdGhzLgorICAgICAqCisgICAgICogQHBhcmFtIGNhUHJpbmNpcGFsCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY2VydGlmaWNhdGUgYXV0aG9yaXR5IGFzIFg1MDAgcHJpbmNpcGFsLgorICAgICAqIEBwYXJhbSBjYVB1YmxpY0tleQorICAgICAqICAgICAgICAgICAgdGhlIHB1YmxpYyBrZXkgb2YgdGhlIGNlcnRpZmljYXRlIGF1dGhvcml0eS4KKyAgICAgKiBAcGFyYW0gbmFtZUNvbnN0cmFpbnRzCisgICAgICogICAgICAgICAgICB0aGUgQVNOLjEgREVSIGVuY29kZWQgZm9ybSBvZiB0aGUgbmFtZSBjb25zdHJhaW50cyBvciB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIG51bGx9IGlmIG5vbmUuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBkZWNvZGluZyBvZiB0aGUgbmFtZSBjb25zdHJhaW50cyBmYWlsLgorICAgICAqLworICAgIHB1YmxpYyBUcnVzdEFuY2hvcihYNTAwUHJpbmNpcGFsIGNhUHJpbmNpcGFsLAorICAgICAgICAgICAgUHVibGljS2V5IGNhUHVibGljS2V5LCBieXRlW10gbmFtZUNvbnN0cmFpbnRzKSB7CisgICAgICAgIGlmIChjYVByaW5jaXBhbCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImNhUHJpbmNpcGFsID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmNhUHJpbmNpcGFsID0gY2FQcmluY2lwYWw7CisgICAgICAgIGlmIChjYVB1YmxpY0tleSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImNhUHVibGljS2V5ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmNhUHVibGljS2V5ID0gY2FQdWJsaWNLZXk7CisgICAgICAgIC8vIGNvcHkgbmFtZUNvbnN0cmFpbnRzIGlmIG5vdCBudWxsCisgICAgICAgIGlmIChuYW1lQ29uc3RyYWludHMgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhpcy5uYW1lQ29uc3RyYWludHMgPSBuZXcgYnl0ZVtuYW1lQ29uc3RyYWludHMubGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobmFtZUNvbnN0cmFpbnRzLCAwLAorICAgICAgICAgICAgICAgICAgICB0aGlzLm5hbWVDb25zdHJhaW50cywgMCwgdGhpcy5uYW1lQ29uc3RyYWludHMubGVuZ3RoKTsKKyAgICAgICAgICAgIHByb2Nlc3NOYW1lQ29uc3RyYWludHMoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRoaXMubmFtZUNvbnN0cmFpbnRzID0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMudHJ1c3RlZENlcnQgPSBudWxsOworICAgICAgICB0aGlzLmNhTmFtZSA9IGNhUHJpbmNpcGFsLmdldE5hbWUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29weSBvZiB0aGUgbmFtZSBjb25zdHJhaW50cyBpbiBBU04uMSBERVIgZW5jb2RlZCBmb3JtLgorICAgICAqCisgICAgICogQHJldHVybiBhIGNvcHkgb2YgdGhlIG5hbWUgY29uc3RyYWludHMgaW4gQVNOLjEgREVSIGVuY29kZWQgZm9ybS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYnl0ZVtdIGdldE5hbWVDb25zdHJhaW50cygpIHsKKyAgICAgICAgaWYgKG5hbWVDb25zdHJhaW50cyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gcmV0ID0gbmV3IGJ5dGVbbmFtZUNvbnN0cmFpbnRzLmxlbmd0aF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5hbWVDb25zdHJhaW50cywgMCwKKyAgICAgICAgICAgICAgICAgICAgcmV0LCAwLCBuYW1lQ29uc3RyYWludHMubGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjZXJ0aWZpY2F0ZSBvZiB0aGlzIDxpPnRydXN0ZWQ8L2k+IGNlcnRpZmljYXRlIGF1dGhvcml0eS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRlIG9mIHRoaXMgQ0Egb3Ige0Bjb2RlIG51bGx9LCBpZiB0aGUgdHJ1c3QgYW5jaG9yCisgICAgICogICAgICAgICBvZiB0aGlzIGluc3RhbmNlIHdhcyBub3QgY3JlYXRlZCB3aXRoIGEgY2VydGlmaWNhdGUuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFg1MDlDZXJ0aWZpY2F0ZSBnZXRUcnVzdGVkQ2VydCgpIHsKKyAgICAgICAgcmV0dXJuIHRydXN0ZWRDZXJ0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGNlcnRpZmljYXRlIGF1dGhvcml0eSBhcyB7QGNvZGUgWDUwMFByaW5jaXBhbH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBjZXJ0aWZpY2F0ZSBhdXRob3JpdHkgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqICAgICAgICAgdHJ1c3QgYW5jaG9yIG9mIHRoaXMgaW5zdGFuY2Ugd2FzIG5vdCBjcmVhdGVkIHdpdGggYSB7QGNvZGUKKyAgICAgKiAgICAgICAgIFg1MDBQcmluY2lwYWx9LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBYNTAwUHJpbmNpcGFsIGdldENBKCkgeworICAgICAgICByZXR1cm4gY2FQcmluY2lwYWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgY2VydGlmaWNhdGUgYXV0aG9yaXR5IGFzIHtAY29kZSBTdHJpbmd9IGluIFJGQworICAgICAqIDIyNTMgZm9ybWF0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgY2VydGlmaWNhdGUgYXV0aG9yaXR5IGFzIHtAY29kZSBTdHJpbmd9IGluIFJGQworICAgICAqICAgICAgICAgMjI1MyBmb3JtYXQgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZSB0cnVzdCBhbmNob3Igb2YgdGhpcyBpbnN0YW5jZQorICAgICAqICAgICAgICAgd2FzIG5vdCBjcmVhdGVkIHdpdGggYSBDQSBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0Q0FOYW1lKCkgeworICAgICAgICByZXR1cm4gY2FOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHB1YmxpYyBrZXkgb2YgdGhlIGNlcnRpZmljYXRlIGF1dGhvcml0eS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHB1YmxpYyBrZXkgb2YgdGhlIGNlcnRpZmljYXRlIGF1dGhvcml0eSBvciB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiAgICAgICAgIHRoZSB0cnVzdCBhbmNob3IgaWYgdGhpcyBpbnN0YW5jZSB3YXMgbm90IGNyZWF0ZWQgd2l0aCBhIHB1YmxpYworICAgICAqICAgICAgICAga2V5LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBQdWJsaWNLZXkgZ2V0Q0FQdWJsaWNLZXkoKSB7CisgICAgICAgIHJldHVybiBjYVB1YmxpY0tleTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMge0Bjb2RlIFRydXN0QW5jaG9yfSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgVHJ1c3RBbmNob3J9IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiVHJ1c3RBbmNob3I6IFtcbiIpOworICAgICAgICBpZiAodHJ1c3RlZENlcnQgIT0gbnVsbCkgeworICAgICAgICAgICAgc2IuYXBwZW5kKCJUcnVzdGVkIENBIGNlcnRpZmljYXRlOiAiKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZCh0cnVzdGVkQ2VydCk7CisgICAgICAgICAgICBzYi5hcHBlbmQoIlxuIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNhUHJpbmNpcGFsICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiVHJ1c3RlZCBDQSBOYW1lOiAiKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZChjYVByaW5jaXBhbCk7CisgICAgICAgICAgICBzYi5hcHBlbmQoIlxuIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNhUHVibGljS2V5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiVHJ1c3RlZCBDQSBQdWJsaWMgS2V5OiAiKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZChjYVB1YmxpY0tleSk7CisgICAgICAgICAgICBzYi5hcHBlbmQoIlxuIik7CisgICAgICAgIH0KKyAgICAgICAgLy8gRklYTUUgaWYgbmVlZGVkOgorICAgICAgICBpZiAobmFtZUNvbnN0cmFpbnRzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiTmFtZSBDb25zdHJhaW50czpcbiIpOworICAgICAgICAgICAgc2IuYXBwZW5kKEFycmF5LnRvU3RyaW5nKG5hbWVDb25zdHJhaW50cywgIiAgICAiKSk7CisgICAgICAgIH0KKyAgICAgICAgc2IuYXBwZW5kKCJcbl0iKTsKKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLy8KKyAgICAvLyBQcml2YXRlIHN0dWZmCisgICAgLy8KKworICAgIC8vIERlY29kZXMgYW5kIGNoZWNrcyBOYW1lQ29uc3RyYWludHMgc3RydWN0dXJlLgorICAgIC8vIFRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgTmFtZUNvbnN0cmFpbnRzCisgICAgLy8gZW5jb2RpbmcgaXMgaW52YWxpZC4KKyAgICBwcml2YXRlIHZvaWQgcHJvY2Vzc05hbWVDb25zdHJhaW50cygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGRlY29kZSBhbmQgY2hlY2sgbmFtZUNvbnN0cmFpbnRzCisgICAgICAgICAgICBOYW1lQ29uc3RyYWludHMuQVNOMS5kZWNvZGUobmFtZUNvbnN0cmFpbnRzKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1g1MDlDUkwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvWDUwOUNSTC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRiYWRkNTkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1g1MDlDUkwuamF2YQpAQCAtMCwwICsxLDI3MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbDsKKworLyoqCisgKiBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBYLjUwOSBjZXJ0aWZpY2F0ZSByZXZvY2F0aW9uIGxpc3RzIChDUkwpLgorICogPHA+CisgKiBNb3JlIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBDUkwgY2FuIGJlIGZvdW5kIGluIFJGQyAyNDU5LAorICogIkludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUgQ2VydGlmaWNhdGUgYW5kIENSTCBQcm9maWxlIiBhdCA8YQorICogaHJlZgorICogPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyNDU5LnR4dCI+aHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjQ1OS50eHQKKyAqIDwvYT4uCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBYNTA5Q1JMIGV4dGVuZHMgQ1JMIGltcGxlbWVudHMgWDUwOUV4dGVuc2lvbiB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBYNTA5Q1JMfSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgWDUwOUNSTCgpIHsKKyAgICAgICAgc3VwZXIoIlguNTA5Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGVxdWFscyB0byB0aGlzIGluc3RhbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIG90aGVyCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgZXF1YWwgdG8gdGhpcywgb3RoZXJ3aXNlCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKKyAgICAgICAgaWYgKG90aGVyID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgWDUwOUNSTCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBYNTA5Q1JMIG9iaiA9IChYNTA5Q1JMKSBvdGhlcjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKGdldEVuY29kZWQoKSwgb2JqLmdldEVuY29kZWQoKSk7CisgICAgICAgIH0gY2F0Y2ggKENSTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBoYXNoY29kZSBvZiB0aGlzIENSTCBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhhc2hjb2RlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgcmVzID0gMDsKKyAgICAgICAgICAgIGJ5dGVbXSBhcnJheSA9IGdldEVuY29kZWQoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxhcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIHJlcyArPSBhcnJheVtpXSAmIDB4RkY7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVzOworICAgICAgICB9IGNhdGNoIChDUkxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgQ1JMIGluIEFTTi4xIERFUiBlbmNvZGVkIGZvcm0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgQ1JMIGluIEFTTi4xIERFUiBlbmNvZGVkIGZvcm0uCisgICAgICogQHRocm93cyBDUkxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBlbmNvZGluZyBmYWlscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYnl0ZVtdIGdldEVuY29kZWQoKSB0aHJvd3MgQ1JMRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBWZXJpZmllcyB0aGlzIENSTCBieSB2ZXJpZnlpbmcgdGhhdCB0aGlzIENSTCB3YXMgc2lnbmVkIHdpdGggdGhlCisgICAgICogY29ycmVzcG9uZGluZyBwcml2YXRlIGtleSB0byB0aGUgc3BlY2lmaWVkIHB1YmxpYyBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUgcHVibGljIGtleSB0byB2ZXJpZnkgdGhpcyBDUkwgd2l0aC4KKyAgICAgKiBAdGhyb3dzIENSTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVuY29kaW5nIG9yIGRlY29kaW5nIGZhaWxzLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBuZWVkZWQgYWxnb3JpdGhtIGlzIG5vdCBwcmVzZW50LgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQga2V5IGlzIGludmFsaWQuCisgICAgICogQHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG5vIHByb3ZpZGVyIGNhbiBiZSBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVycm9ycyBvY2N1ciBvbiBzaWduYXR1cmVzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5KQorICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIENSTEV4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNpZ25hdHVyZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFZlcmlmaWVzIHRoaXMgQ1JMIGJ5IHZlcmlmeWluZyB0aGF0IHRoaXMgQ1JMIHdhcyBzaWduZWQgd2l0aCB0aGUKKyAgICAgKiBjb3JyZXNwb25kaW5nIHByaXZhdGUga2V5IHRvIHRoZSBzcGVjaWZpZWQgcHVibGljIGtleS4gVGhlIHNpZ25hdHVyZQorICAgICAqIHZlcmlmaWNhdGlvbiBlbmdpbmUgb2YgdGhlIHNwZWNpZmllZCBwcm92aWRlciB3aWxsIGJlIHVzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUgcHVibGljIGtleSB0byB2ZXJpZnkgdGhpcyBDUkwgd2l0aC4KKyAgICAgKiBAcGFyYW0gc2lnUHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBwcm92aWRlciBmb3IgdGhlIHNpZ25hdHVyZSBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBDUkxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBlbmNvZGluZyBkZWNvZGluZyBmYWlscy4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgbmVlZGVkIGFsZ29yaXRobSBpcyBub3QgcHJlc2VudC4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGtleSBpcyBpbnZhbGlkLgorICAgICAqIEB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGNhbm5vdCBiZSBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVycm9ycyBvY2N1ciBvbiBzaWduYXR1cmVzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5LCBTdHJpbmcgc2lnUHJvdmlkZXIpCisgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgQ1JMRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW52YWxpZEtleUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2lnbmF0dXJlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhpcyBDUkwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGlzIENSTC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldFZlcnNpb24oKTsKKworICAgIC8qKgorICAgICAqIDxiPkRvIG5vdCB1c2U8L2I+LCB1c2Uge0BsaW5rICNnZXRJc3N1ZXJYNTAwUHJpbmNpcGFsKCl9IGluc3RlYWQuIFJldHVybnMKKyAgICAgKiB0aGUgaXNzdWVyIGFzIGFuIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIFByaW5jaXBhbCBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpc3N1ZXIgZGlzdGluZ3Vpc2hlZCBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBQcmluY2lwYWwgZ2V0SXNzdWVyRE4oKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGlzc3VlciBkaXN0aW5ndWlzaGVkIG5hbWUgb2YgdGhpcyBDUkwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpc3N1ZXIgZGlzdGluZ3Vpc2hlZCBuYW1lIG9mIHRoaXMgQ1JMLgorICAgICAqLworICAgIHB1YmxpYyBYNTAwUHJpbmNpcGFsIGdldElzc3Vlclg1MDBQcmluY2lwYWwoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBUT0RPIGlmIHRoZXJlIGlzIG5vIFguNTA5IGNlcnRpZmljYXRlIHByb3ZpZGVyIGluc3RhbGxlZAorICAgICAgICAgICAgLy8gc2hvdWxkIHdlIHRyeSB0byBhY2Nlc3MgSGFybW9ueSBYNTA5Q1JMSW1wbCB2aWEgY2xhc3NGb3JOYW1lPworICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGZhY3RvcnkgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKCJYLjUwOSIpOworCisgICAgICAgICAgICBYNTA5Q1JMIGNybCA9IChYNTA5Q1JMKSBmYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZW5lcmF0ZUNSTChuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZ2V0RW5jb2RlZCgpKSk7CisKKyAgICAgICAgICAgIHJldHVybiBjcmwuZ2V0SXNzdWVyWDUwMFByaW5jaXBhbCgpOworCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiRmFpbGVkIHRvIGdldCBYNTAwUHJpbmNpcGFsIGlzc3VlciIsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIHRoaXNVcGRhdGV9IHZhbHVlIG9mIHRoaXMgQ1JMLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIHRoaXNVcGRhdGV9IHZhbHVlIG9mIHRoaXMgQ1JMLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBEYXRlIGdldFRoaXNVcGRhdGUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBuZXh0VXBkYXRlfSB2YWx1ZSBvZiB0aGlzIENSTC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBuZXh0VXBkYXRlfSB2YWx1ZSBvZiB0aGlzIENSTCwgb3Ige0Bjb2RlIG51bGx9IGlmIG5vbmUKKyAgICAgKiAgICAgICAgIGlzIHByZXNlbnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IERhdGUgZ2V0TmV4dFVwZGF0ZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgQ1JMIGVudHJ5IHdpdGggdGhlIHNwZWNpZmllZCBjZXJ0aWZpY2F0ZSBzZXJpYWwgbnVtYmVyLgorICAgICAqCisgICAgICogQHBhcmFtIHNlcmlhbE51bWJlcgorICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRlIHNlcmlhbCBudW1iZXIgdG8gc2VhcmNoIGZvciBhIENSTCBlbnRyeS4KKyAgICAgKiBAcmV0dXJuIHRoZSBlbnRyeSBmb3IgdGhlIHNwZWNpZmllZCBjZXJ0aWZpY2F0ZSBzZXJpYWwgbnVtYmVyLCBvciB7QGNvZGUKKyAgICAgKiAgICAgICAgIG51bGx9IGlmIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgWDUwOUNSTEVudHJ5IGdldFJldm9rZWRDZXJ0aWZpY2F0ZShCaWdJbnRlZ2VyIHNlcmlhbE51bWJlcik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBDUkwgZW50cnkgZm9yIHRoZSBzcGVjaWZpZWQgY2VydGlmaWNhdGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2VydGlmaWNhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZSB0byBzZWFyY2ggYSBDUkwgZW50cnkgZm9yLgorICAgICAqIEByZXR1cm4gdGhlIGVudHJ5IGZvciB0aGUgc3BlY2lmaWVkIGNlcnRpZmljYXRlLCBvciB7QGNvZGUgbnVsbH0gaWYgbm90CisgICAgICogICAgICAgICBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgWDUwOUNSTEVudHJ5IGdldFJldm9rZWRDZXJ0aWZpY2F0ZShYNTA5Q2VydGlmaWNhdGUgY2VydGlmaWNhdGUpIHsKKyAgICAgICAgaWYgKGNlcnRpZmljYXRlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRSZXZva2VkQ2VydGlmaWNhdGUoY2VydGlmaWNhdGUuZ2V0U2VyaWFsTnVtYmVyKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNldCBvZiByZXZva2VkIGNlcnRpZmljYXRlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNldCBvZiByZXZva2VkIGNlcnRpZmljYXRlcywgb3Ige0Bjb2RlIG51bGx9IGlmIG5vIHJldm9rZWQKKyAgICAgKiAgICAgICAgIGNlcnRpZmljYXRlcyBhcmUgaW4gdGhpcyBDUkwuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFNldDw/IGV4dGVuZHMgWDUwOUNSTEVudHJ5PiBnZXRSZXZva2VkQ2VydGlmaWNhdGVzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgdGJzQ2VydExpc3R9IGluZm9ybWF0aW9uIG9mIHRoaXMgQ1JMIGluIERFUiBlbmNvZGVkCisgICAgICogZm9ybS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIENSTCBpbmZvcm1hdGlvbiBpbiBERVIgZW5jb2RlZCBmb3JtLgorICAgICAqIEB0aHJvd3MgQ1JMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZW5jb2RpbmcgZmFpbHMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJ5dGVbXSBnZXRUQlNDZXJ0TGlzdCgpIHRocm93cyBDUkxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzaWduYXR1cmUgYnl0ZXMgb2YgdGhpcyBDUkwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzaWduYXR1cmUgYnl0ZXMgb2YgdGhpcyBDUkwuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJ5dGVbXSBnZXRTaWduYXR1cmUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHNpZ25hdHVyZSBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBzaWduYXR1cmUgYWxnb3JpdGhtLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0U2lnQWxnTmFtZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgT0lEIG9mIHRoZSBzaWduYXR1cmUgYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgT0lEIG9mIHRoZSBzaWduYXR1cmUgYWxnb3JpdGhtLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0U2lnQWxnT0lEKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwYXJhbWV0ZXJzIG9mIHRoZSBzaWduYXR1cmUgYWxnb3JpdGhtIGluIERFUiBlbmNvZGVkIGZvcm0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwYXJhbWV0ZXJzIG9mIHRoZSBzaWduYXR1cmUgYWxnb3JpdGhtIGluIERFUiBlbmNvZGVkIGZvcm0sIG9yCisgICAgICogICAgICAgICB7QGNvZGUgbnVsbH0gaWYgbm90IHByZXNlbnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJ5dGVbXSBnZXRTaWdBbGdQYXJhbXMoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvWDUwOUNSTEVudHJ5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1g1MDlDUkxFbnRyeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRiNGMxNWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1g1MDlDUkxFbnRyeS5qYXZhCkBAIC0wLDAgKzEsMTI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CisKKy8qKgorICogQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3IgZW50cmllcyBpbiBhIGNlcnRpZmljYXRlIHJldm9jYXRpb24gbGlzdCAoQ1JMKS4KKyAqCisgKiBAc2VlIFg1MDlDUkwKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFg1MDlDUkxFbnRyeSBpbXBsZW1lbnRzIFg1MDlFeHRlbnNpb24geworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgWDUwOUNSTEVudHJ5fSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgWDUwOUNSTEVudHJ5KCkge30KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgc3BlY2lmaWVkIG9iamVjdCBlcXVhbHMgdG8gdGhpcyBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdGhlcgorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGVxdWFscyB0byB0aGlzIGluc3RhbmNlLAorICAgICAqICAgICAgICAgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgeworICAgICAgICBpZiAob3RoZXIgPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBYNTA5Q1JMRW50cnkpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgWDUwOUNSTEVudHJ5IG9iaiA9IChYNTA5Q1JMRW50cnkpIG90aGVyOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMoZ2V0RW5jb2RlZCgpLCBvYmouZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgfSBjYXRjaCAoQ1JMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhhc2hjb2RlIG9mIHRoaXMgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoY29kZSBvZiB0aGlzIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGludCByZXMgPSAwOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnl0ZVtdIGFycmF5ID0gZ2V0RW5jb2RlZCgpOworICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgcmVzICs9IGFycmF5W2ldICYgMHhGRjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoQ1JMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBlbnRyeSBpbiBBU04uMSBERVIgZW5jb2RlZCBmb3JtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZW5jb2RlZCBmb3JtIG9mIHRoaXMgZW50cnkuCisgICAgICogQHRocm93cyBDUkxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBlbmNvZGluZyBmYWlscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYnl0ZVtdIGdldEVuY29kZWQoKSB0aHJvd3MgQ1JMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2VyaWFsIG51bWJlciBvZiB0aGUgcmV2b2tlZCBjZXJ0aWZpY2F0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNlcmlhbCBudW1iZXIgb2YgdGhlIHJldm9rZWQgY2VydGlmaWNhdGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJpZ0ludGVnZXIgZ2V0U2VyaWFsTnVtYmVyKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpc3N1ZXIgb2YgdGhlIHJldm9rZWQgY2VydGlmaWNhdGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpc3N1ZXIgb2YgdGhlIHJldm9rZWQgY2VydGlmaWNhdGUsIG9yIHtAY29kZSBudWxsfSBpZiB0aGUKKyAgICAgKiAgICAgICAgIGlzc3VlciBpcyBlcXVhbCB0byB0aGUgQ1JMIGlzc3Vlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgWDUwMFByaW5jaXBhbCBnZXRDZXJ0aWZpY2F0ZUlzc3VlcigpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGF0ZSB3aGVuIHRoZSBjZXJ0aWZpY2F0ZSBpcyByZXZva2VkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZGF0ZSB3aGVuIHRoZSBjZXJ0aWZpY2F0ZSBpcyByZXZva2VkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBEYXRlIGdldFJldm9jYXRpb25EYXRlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBDUkwgZW50cnkgaGFzIGV4dGVuc2lvbnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpcyB0aGlzIENSTCBlbnRyeSBoYXMgZXh0ZW5zaW9ucywgb3RoZXJ3aXNlIHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGhhc0V4dGVuc2lvbnMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIHRvU3RyaW5nKCk7Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvWDUwOUNSTFNlbGVjdG9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1g1MDlDUkxTZWxlY3Rvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFiYmUzY2YKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1g1MDlDUkxTZWxlY3Rvci5qYXZhCkBAIC0wLDAgKzEsNDY0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xSW50ZWdlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xT2N0ZXRTdHJpbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDEuTmFtZTsKKworLyoqCisgKiBBIENSTCBzZWxlY3RvciAoe0Bjb2RlIENSTFNlbGVjdG9yfSBmb3Igc2VsZWN0aW5nIHtAY29kZQorICogWDUwOUNSTH1zIHRoYXQgbWF0Y2ggdGhlIHNwZWNpZmllZCBjcml0ZXJpYS4KKyAqIDxwPgorICogV2hlbiBjb25zdHJ1Y3RlZCwgYWxsIGNyaXRlcmlhIGFyZSBzZXQgdG8gZGVmYXVsdCB2YWx1ZXMgdGhhdCB3aWxsIG1hdGNoIGFueQorICoge0Bjb2RlIFg1MDlDUkx9LgorICovCitwdWJsaWMgY2xhc3MgWDUwOUNSTFNlbGVjdG9yIGltcGxlbWVudHMgQ1JMU2VsZWN0b3IgeworCisgICAgLy8gaXNzdWVyTmFtZXMgY3JpdGVyaW9uOgorICAgIC8vIGNvbnRhaW5zIFguNTAwIGRpc3Rpbmd1aXNoZWQgbmFtZXMgaW4gQ0FOT05JQ0FMIGZvcm1hdAorICAgIHByaXZhdGUgQXJyYXlMaXN0PFN0cmluZz4gaXNzdWVyTmFtZXM7CisgICAgLy8gY29udGFpbnMgWDUwMFByaW5jaXBhbCBvYmplY3RzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG5hbWVzCisgICAgLy8gZnJvbSBpc3N1ZXJOYW1lcyBjb2xsZWN0aW9uIChhYm92ZSkKKyAgICBwcml2YXRlIEFycmF5TGlzdDxYNTAwUHJpbmNpcGFsPiBpc3N1ZXJQcmluY2lwYWxzOworICAgIC8vIG1pbkNSTE51bWJlciBjcml0ZXJpb24KKyAgICBwcml2YXRlIEJpZ0ludGVnZXIgbWluQ1JMOworICAgIC8vIG1heENSTE51bWJlciBjcml0ZXJpb24KKyAgICBwcml2YXRlIEJpZ0ludGVnZXIgbWF4Q1JMOworICAgIC8vIGRhdGVBbmRUaW1lIGNyaXRlcmlvbgorICAgIHByaXZhdGUgbG9uZyBkYXRlQW5kVGltZSA9IC0xOworICAgIC8vIHRoZSBjZXJ0aWZpY2F0ZSBiZWluZyBjaGVja2VkCisgICAgcHJpdmF0ZSBYNTA5Q2VydGlmaWNhdGUgY2VydGlmaWNhdGVDaGVja2luZzsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFg1MDlDZXJ0U2VsZWN0b3J9LgorICAgICAqLworICAgIHB1YmxpYyBYNTA5Q1JMU2VsZWN0b3IoKSB7IH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNyaXRlcmlvbiBmb3IgdGhlIGlzc3VlciBkaXN0aW5ndWlzaGVkIG5hbWVzLgorICAgICAqIDxwPgorICAgICAqIFRoZSBDUkwgaXNzdWVyIG11c3QgbWF0Y2ggYXQgbGVhc3Qgb25lIG9mIHRoZSBzcGVjaWZpZWQgZGlzdGluZ3Vpc2hlZAorICAgICAqIG5hbWVzLgorICAgICAqCisgICAgICogQHBhcmFtIGlzc3VlcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IG9mIGlzc3VlciBkaXN0aW5ndWlzaGVkIG5hbWVzIHRvIG1hdGNoLCBvciB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIG51bGx9IGlmIGFueSBpc3N1ZXIgZGlzdGluZ3Vpc2hlZCBuYW1lIHdpbGwgZG8uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SXNzdWVycyhDb2xsZWN0aW9uPFg1MDBQcmluY2lwYWw+IGlzc3VlcnMpIHsKKyAgICAgICAgaWYgKGlzc3VlcnMgPT0gbnVsbCkgeworICAgICAgICAgICAgaXNzdWVyTmFtZXMgPSBudWxsOworICAgICAgICAgICAgaXNzdWVyUHJpbmNpcGFscyA9IG51bGw7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaXNzdWVyTmFtZXMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oaXNzdWVycy5zaXplKCkpOworICAgICAgICBpc3N1ZXJQcmluY2lwYWxzID0gbmV3IEFycmF5TGlzdDxYNTAwUHJpbmNpcGFsPihpc3N1ZXJzKTsKKyAgICAgICAgZm9yIChYNTAwUHJpbmNpcGFsIGlzc3VlcjogaXNzdWVycykgeworICAgICAgICAgICAgaXNzdWVyTmFtZXMuYWRkKGlzc3Vlci5nZXROYW1lKFg1MDBQcmluY2lwYWwuQ0FOT05JQ0FMKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8Yj5EbyBub3QgdXNlOjwvYj4gdXNlIHtAbGluayAjc2V0SXNzdWVycyhDb2xsZWN0aW9uKX0gb3Igb25lIG9mCisgICAgICoge0BsaW5rICNhZGRJc3N1ZXJOYW1lfSBpbnN0ZWFkLiBTZXRzIHRoZSBjcml0ZXJpb24gZm9yIHRoZSBpc3N1ZXIKKyAgICAgKiBkaXN0aW5ndWlzaGVkIG5hbWVzLgorICAgICAqIDxwPgorICAgICAqIFRoZSBDUkwgaXNzdWVyIG11c3QgbWF0Y2ggYXQgbGVhc3Qgb25lIG9mIHRoZSBzcGVjaWZpZWQgZGlzdGluZ3Vpc2hlZAorICAgICAqIG5hbWVzLgorICAgICAqIDxwPgorICAgICAqIFRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIHtAY29kZSBuYW1lc30gaXMgYSBjb2xsZWN0aW9uIHdpdGggYW4gZW50cnkgZm9yCisgICAgICogZWFjaCBuYW1lIHRvIGJlIGluY2x1ZGVkIGluIHRoZSBjcml0ZXJpb24uIFRoZSBuYW1lIGlzIHNwZWNpZmllZCBhcyBhCisgICAgICoge0Bjb2RlIFN0cmluZ30gb3IgYSBieXRlIGFycmF5IHNwZWNpZnlpbmcgdGhlIG5hbWUgKGluIFJGQyAyMjUzIG9yIEFTTi4xCisgICAgICogREVSIGVuY29kZWQgZm9ybSkKKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lcworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgaXNzdWVyIGRpc3Rpbmd1aXNoZWQgbmFtZXMgdG8gbWF0Y2gsIG9yIHtAY29kZQorICAgICAqICAgICAgICAgICAgbnVsbH0gaWYgYW55IGlzc3VlciBkaXN0aW5ndWlzaGVkIG5hbWUgd2lsbCBkby4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgcGFyc2luZyBmYWlscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRJc3N1ZXJOYW1lcyhDb2xsZWN0aW9uPD8+IG5hbWVzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAobmFtZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgaXNzdWVyTmFtZXMgPSBudWxsOworICAgICAgICAgICAgaXNzdWVyUHJpbmNpcGFscyA9IG51bGw7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKG5hbWVzLnNpemUoKSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaXNzdWVyTmFtZXMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4obmFtZXMuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChPYmplY3QgbmFtZTogbmFtZXMpIHsKKyAgICAgICAgICAgIGlmIChuYW1lIGluc3RhbmNlb2YgU3RyaW5nKSB7CisgICAgICAgICAgICAgICAgaXNzdWVyTmFtZXMuYWRkKAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE5hbWUoKFN0cmluZykgbmFtZSkuZ2V0TmFtZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBYNTAwUHJpbmNpcGFsLkNBTk9OSUNBTCkpOworICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lIGluc3RhbmNlb2YgYnl0ZVtdKSB7CisgICAgICAgICAgICAgICAgaXNzdWVyTmFtZXMuYWRkKAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE5hbWUoKGJ5dGVbXSkgbmFtZSkuZ2V0TmFtZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBYNTAwUHJpbmNpcGFsLkNBTk9OSUNBTCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIm5hbWUgbmVpdGhlciBhIFN0cmluZyBub3IgYSBieXRlW10iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYW4gaXNzdWVyIHRvIHRoZSBjcml0ZXJpb24gZm9yIHRoZSBpc3N1ZXIgZGlzdGluZ3Vpc2hlZCBuYW1lcy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgQ1JMIGlzc3VlciBtdXN0IG1hdGNoIGF0IGxlYXN0IG9uZSBvZiB0aGUgc3BlY2lmaWVkIGRpc3Rpbmd1aXNoZWQKKyAgICAgKiBuYW1lcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpc3N1ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBpc3N1ZXIgdG8gYWRkIHRvIHRoZSBjcml0ZXJpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRJc3N1ZXIoWDUwMFByaW5jaXBhbCBpc3N1ZXIpIHsKKyAgICAgICAgaWYgKGlzc3VlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImlzc3VlciA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlzc3Vlck5hbWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIGlzc3Vlck5hbWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIG5hbWUgPSBpc3N1ZXIuZ2V0TmFtZShYNTAwUHJpbmNpcGFsLkNBTk9OSUNBTCk7CisgICAgICAgIGlmICghaXNzdWVyTmFtZXMuY29udGFpbnMobmFtZSkpIHsKKyAgICAgICAgICAgIGlzc3Vlck5hbWVzLmFkZChuYW1lKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaXNzdWVyUHJpbmNpcGFscyA9PSBudWxsKSB7CisgICAgICAgICAgICBpc3N1ZXJQcmluY2lwYWxzID0gbmV3IEFycmF5TGlzdDxYNTAwUHJpbmNpcGFsPihpc3N1ZXJOYW1lcy5zaXplKCkpOworICAgICAgICB9CisgICAgICAgIC8vIGV4dGVuZCB0aGUgbGlzdCBvZiBpc3N1ZXIgUHJpbmNpcGFscworICAgICAgICBpbnQgc2l6ZSA9IGlzc3Vlck5hbWVzLnNpemUoKSAtIDE7CisgICAgICAgIGZvciAoaW50IGk9aXNzdWVyUHJpbmNpcGFscy5zaXplKCk7IGk8c2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBpc3N1ZXJQcmluY2lwYWxzLmFkZChuZXcgWDUwMFByaW5jaXBhbChpc3N1ZXJOYW1lcy5nZXQoaSkpKTsKKyAgICAgICAgfQorICAgICAgICBpc3N1ZXJQcmluY2lwYWxzLmFkZChpc3N1ZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxiPkRvIG5vdCB1c2U6PC9iPiwgdXNlIHtAbGluayAjYWRkSXNzdWVyKFg1MDBQcmluY2lwYWwpfSBvcgorICAgICAqIHtAbGluayAjYWRkSXNzdWVyTmFtZShieXRlW10pfSBpbnN0ZWFkLiBJdCBjYW4gZmFpbCB0byBtYXRjaCBzb21lIENSTHMKKyAgICAgKiBiZWNhdXNlIG9mIGEgbG9zcyBvZiBlbmNvZGluZyBpbmZvcm1hdGlvbiBpbiBhIFJGQyAyMjUzIHN0cmluZy4KKyAgICAgKiA8cD4KKyAgICAgKiBBZGRzIGFuIGlzc3VlciB0byB0aGUgY3JpdGVyaW9uIGZvciB0aGUgaXNzdWVyIGRpc3Rpbmd1aXNoZWQgbmFtZXMuIFRoZQorICAgICAqIENSSyBpc3N1ZXIgbXVzdCBtYXRjaCBhdCBsZWFzdCBvbmUgb2YgdGhlIHNwZWNpZmllZCBkaXN0aW5ndWlzaGVkIG5hbWVzLgorICAgICAqCisgICAgICogQHBhcmFtIGlzc19uYW1lCisgICAgICogICAgICAgICAgICB0aGUgUkZDIDIyNTMgZW5jb2RlZCBuYW1lLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBwYXJzaW5nIGZhaWxzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZElzc3Vlck5hbWUoU3RyaW5nIGlzc19uYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaXNzdWVyTmFtZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgaXNzdWVyTmFtZXMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChpc3NfbmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICBpc3NfbmFtZSA9ICIiOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBuZXcgTmFtZShpc3NfbmFtZSkuZ2V0TmFtZShYNTAwUHJpbmNpcGFsLkNBTk9OSUNBTCk7CisgICAgICAgIGlmICghaXNzdWVyTmFtZXMuY29udGFpbnMobmFtZSkpIHsKKyAgICAgICAgICAgIGlzc3Vlck5hbWVzLmFkZChuYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYW4gaXNzdWVyIHRvIHRoZSBjcml0ZXJpb24gZm9yIHRoZSBpc3N1ZXIgZGlzdGluZ3Vpc2hlZCBuYW1lcy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgQ1JMIGlzc3VlciBtdXN0IG1hdGNoIGF0IGxlYXN0IG9uZSBvZiB0aGUgc3BlY2lmaWVkIGRpc3Rpbmd1aXNoZWQKKyAgICAgKiBuYW1lcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpc3NfbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGlzc3VlciB0byBhZGQgdG8gdGhlIGNyaXRlcmlvbiBpbiBBU04uMSBERVIgZW5jb2RlZCBmb3JtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBwYXJzaW5nIGZhaWxzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZElzc3Vlck5hbWUoYnl0ZVtdIGlzc19uYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaXNzX25hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJpc3NfbmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlzc3Vlck5hbWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIGlzc3Vlck5hbWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIG5hbWUgPSBuZXcgTmFtZShpc3NfbmFtZSkuZ2V0TmFtZShYNTAwUHJpbmNpcGFsLkNBTk9OSUNBTCk7CisgICAgICAgIGlmICghaXNzdWVyTmFtZXMuY29udGFpbnMobmFtZSkpIHsKKyAgICAgICAgICAgIGlzc3Vlck5hbWVzLmFkZChuYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNyaXRlcmlvbiBmb3IgdGhlIG1pbmltdW0gQ1JMIG51bWJlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgQ1JMIG11c3QgaGF2ZSBhIG51bWJlciBleHRlbnNpb24gd2l0aCBhIHZhbHVlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbAorICAgICAqIHRvIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG1pbkNSTAorICAgICAqICAgICAgICAgICAgdGhlIG1pbmltdW0gQ1JMIG51bWJlciBvciBudWxsIHRvIG5vdCBjaGVjayB0aGUgbWluaW11bSBDUkwKKyAgICAgKiAgICAgICAgICAgIG51bWJlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1pbkNSTE51bWJlcihCaWdJbnRlZ2VyIG1pbkNSTCkgeworICAgICAgICB0aGlzLm1pbkNSTCA9IG1pbkNSTDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjcml0ZXJpb24gZm9yIHRoZSBtYXhpbXVtIENSTCBudW1iZXIuCisgICAgICogPHA+CisgICAgICogVGhlIENSTCBtdXN0IGhhdmUgYSBudW1iZXIgZXh0ZW5zaW9uIHdpdGggYSB2YWx1ZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8KKyAgICAgKiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtYXhDUkwKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIENSTCBudW1iZXIgb3IgbnVsbCB0byBub3QgY2hlY2sgdGhlIG1heGltdW0gQ1JMCisgICAgICogICAgICAgICAgICBudW1iZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TWF4Q1JMTnVtYmVyKEJpZ0ludGVnZXIgbWF4Q1JMKSB7CisgICAgICAgIHRoaXMubWF4Q1JMID0gbWF4Q1JMOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNyaXRlcmlvbiBmb3IgdGhlIENSTCB1cGRhdGUgcGVyaW9kLgorICAgICAqIDxwPgorICAgICAqIFRoZSBDUkwncyB7QGNvZGUgdGhpc1VwZGF0ZX0gdmFsdWUgbXVzdCBiZSBlcXVhbCBvciBiZWZvcmUgdGhlIHNwZWNpZmllZAorICAgICAqIGRhdGUgYW5kIHRoZSB7QGNvZGUgbmV4dFVwZGF0ZX0gdmFsdWUgbXVzdCBiZSBhZnRlciB0aGUgc3BlY2lmaWVkIGRhdGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0ZUFuZFRpbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRlIHRvIHNlYXJjaCBmb3IgdmFsaWQgQ1JMJ3Mgb3Ige0Bjb2RlIG51bGx9IHRvIG5vdAorICAgICAqICAgICAgICAgICAgY2hlY2sgdGhlIGRhdGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGF0ZUFuZFRpbWUoRGF0ZSBkYXRlQW5kVGltZSkgeworICAgICAgICBpZiAoZGF0ZUFuZFRpbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhpcy5kYXRlQW5kVGltZSA9IC0xOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHRoaXMuZGF0ZUFuZFRpbWUgPSBkYXRlQW5kVGltZS5nZXRUaW1lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBhIGNlcnRpZmljYXRlIGhpbnQgdG8gZmluZCBDUkxzLiBJdCdzIG5vdCBhIGNyaXRlcmlvbiBidXQgbWF5IGhlbHAKKyAgICAgKiBmaW5kaW5nIHJlbGV2YW50IENSTHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2VydAorICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRlIGhpbnQgb3Ige0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENlcnRpZmljYXRlQ2hlY2tpbmcoWDUwOUNlcnRpZmljYXRlIGNlcnQpIHsKKyAgICAgICAgdGhpcy5jZXJ0aWZpY2F0ZUNoZWNraW5nID0gY2VydDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjcml0ZXJpb24gZm9yIHRoZSBpc3N1ZXIgZGlzdGluZ3Vpc2hlZCBuYW1lcy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgQ1JMIGlzc3VlciBtdXN0IG1hdGNoIGF0IGxlYXN0IG9uZSBvZiB0aGUgZGlzdGluZ3Vpc2hlZCBuYW1lcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHVubW9kaWZpYWJsZSBsaXN0IG9mIGlzc3VlciBkaXN0aW5ndWlzaGVkIG5hbWVzIHRvIG1hdGNoLCBvcgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlmIGFueSBpc3N1ZXIgZGlzdGluZ3Vpc2hlZCBuYW1lIHdpbGwgZG8uCisgICAgICovCisgICAgcHVibGljIENvbGxlY3Rpb248WDUwMFByaW5jaXBhbD4gZ2V0SXNzdWVycygpIHsKKyAgICAgICAgaWYgKGlzc3Vlck5hbWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGlmIChpc3N1ZXJQcmluY2lwYWxzID09IG51bGwpIHsKKyAgICAgICAgICAgIGlzc3VlclByaW5jaXBhbHMgPSBuZXcgQXJyYXlMaXN0PFg1MDBQcmluY2lwYWw+KGlzc3Vlck5hbWVzLnNpemUoKSk7CisgICAgICAgIH0KKyAgICAgICAgaW50IHNpemUgPSBpc3N1ZXJOYW1lcy5zaXplKCk7CisgICAgICAgIC8vIGV4dGVuZCB0aGUgbGlzdCBvZiBpc3N1ZXIgUHJpbmNpcGFscworICAgICAgICBmb3IgKGludCBpPWlzc3VlclByaW5jaXBhbHMuc2l6ZSgpOyBpPHNpemU7IGkrKykgeworICAgICAgICAgICAgaXNzdWVyUHJpbmNpcGFscy5hZGQobmV3IFg1MDBQcmluY2lwYWwoaXNzdWVyTmFtZXMuZ2V0KGkpKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUNvbGxlY3Rpb24oaXNzdWVyUHJpbmNpcGFscyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3JpdGVyaW9uIGZvciB0aGUgaXNzdWVyIGRpc3Rpbmd1aXNoZWQgbmFtZXMuCisgICAgICogPHA+CisgICAgICogVGhlIENSTCBpc3N1ZXIgbXVzdCBtYXRjaCBhdCBsZWFzdCBvbmUgb2YgdGhlIGRpc3Rpbmd1aXNoZWQgbmFtZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGUgbGlzdCBvZiBpc3N1ZXIgZGlzdGluZ3Vpc2hlZCBuYW1lcyB0bworICAgICAqICAgICAgICAgbWF0Y2gsIG9yIHtAY29kZSBudWxsfSBpZiBhbnkgaXNzdWVyIGRpc3Rpbmd1aXNoZWQgbmFtZQorICAgICAqICAgICAgICAgd2lsbCBkby4gVGhlIGVsZW1lbnRzIG1heSBiZSBzdHJpbmdzIG9yIEFTTi4xIERFUgorICAgICAqICAgICAgICAgZW5jb2RlZCBieXRlIGFycmF5cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sbGVjdGlvbjxPYmplY3Q+IGdldElzc3Vlck5hbWVzKCkgeworICAgICAgICBpZiAoaXNzdWVyTmFtZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChDb2xsZWN0aW9uPE9iamVjdD4pIGlzc3Vlck5hbWVzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3JpdGVyaW9uIGZvciB0aGUgbWluaW11bSBDUkwgbnVtYmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBDUkwgbXVzdCBoYXZlIGEgbnVtYmVyIGV4dGVuc2lvbiB3aXRoIGEgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsCisgICAgICogdG8gdGhlIHJldHVybmVkIHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWluaW11bSBDUkwgbnVtYmVyIG9yIHtAY29kZSBudWxsfSBpZiB0aGUgbWluaW11bSBDUkwgbnVtYmVyCisgICAgICogICAgICAgICBpcyBub3QgdG8gYmUgY2hlY2tlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRNaW5DUkwoKSB7CisgICAgICAgIHJldHVybiBtaW5DUkw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3JpdGVyaW9uIGZvciB0aGUgbWF4aW11bSBDUkwgbnVtYmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBDUkwgbXVzdCBoYXZlIGEgbnVtYmVyIGV4dGVuc2lvbiB3aXRoIGEgdmFsdWUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvCisgICAgICogdGhlIHJldHVybmVkIHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBDUkwgbnVtYmVyIG9yIG51bGwgaWYgdGhlIG1heGltdW0gQ1JMIG51bWJlciBpcyBub3QKKyAgICAgKiAgICAgICAgIGNoZWNrZWQuCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0TWF4Q1JMKCkgeworICAgICAgICByZXR1cm4gbWF4Q1JMOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNyaXRlcmlvbiBmb3IgdGhlIENSTCB1cGRhdGUgcGVyaW9kLgorICAgICAqIDxwPgorICAgICAqIFRoZSBDUkwncyB7QGNvZGUgdGhpc1VwZGF0ZX0gdmFsdWUgbXVzdCBiZSBlcXVhbCBvciBiZWZvcmUgdGhlIHJldHVybmVkCisgICAgICogZGF0ZSBhbmQgdGhlIHtAY29kZSBuZXh0VXBkYXRlfSB2YWx1ZSBtdXN0IGJlIGFmdGVyIHRoZSByZXR1cm5lZCBkYXRlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZGF0ZSB0byBzZWFyY2ggZm9yIHZhbGlkIENSTCdzIG9yIHtAY29kZSBudWxsfSBpZiB0aGUgZGF0ZSBpcworICAgICAqICAgICAgICAgbm90IGNoZWNrZWQuCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0RGF0ZUFuZFRpbWUoKSB7CisgICAgICAgIGlmIChkYXRlQW5kVGltZSA9PSAtMSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBEYXRlKGRhdGVBbmRUaW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjZXJ0aWZpY2F0ZSBoaW50IHRvIGZpbmQgQ1JMcy4gSXQncyBub3QgYSBjcml0ZXJpb24gYnV0IG1heQorICAgICAqIGhlbHAgZmluZGluZyByZWxldmFudCBDUkxzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2VydGlmaWNhdGUgaGludCBvciB7QGNvZGUgbnVsbH0gaWYgbm9uZSBzZXQuCisgICAgICovCisgICAgcHVibGljIFg1MDlDZXJ0aWZpY2F0ZSBnZXRDZXJ0aWZpY2F0ZUNoZWNraW5nKCkgeworICAgICAgICByZXR1cm4gY2VydGlmaWNhdGVDaGVja2luZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMge0Bjb2RlIFg1MDlDUkxTZWxlY3Rvcn0gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMge0Bjb2RlIFg1MDlDUkxTZWxlY3Rvcn0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICByZXN1bHQuYXBwZW5kKCJYNTA5Q1JMU2VsZWN0b3I6XG5bIik7CisgICAgICAgIGlmIChpc3N1ZXJOYW1lcyAhPSBudWxsKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJcbiAgSXNzdWVyTmFtZXM6XG4gIFsiKTsKKyAgICAgICAgICAgIGludCBzaXplID0gaXNzdWVyTmFtZXMuc2l6ZSgpOworICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPHNpemU7IGkrKykgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIlxuICAgICIKKyAgICAgICAgICAgICAgICAgICAgKyBpc3N1ZXJOYW1lcy5nZXQoaSkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiXG4gIF0iKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobWluQ1JMICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIlxuICBtaW5DUkw6ICIgKyBtaW5DUkwpOworICAgICAgICB9CisgICAgICAgIGlmIChtYXhDUkwgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiXG4gIG1heENSTDogIiArIG1heENSTCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRhdGVBbmRUaW1lICE9IC0xKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJcbiAgZGF0ZUFuZFRpbWU6ICIgKyAobmV3IERhdGUoZGF0ZUFuZFRpbWUpKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNlcnRpZmljYXRlQ2hlY2tpbmcgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiXG4gIGNlcnRpZmljYXRlQ2hlY2tpbmc6ICIgKyBjZXJ0aWZpY2F0ZUNoZWNraW5nKTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHQuYXBwZW5kKCJcbl0iKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgc3BlY2lmaWVkIENSTCBtYXRjaGVzIGFsbCB0aGUgY3JpdGVyaWEgY29sbGVjdGVkIGluCisgICAgICogdGhpcyBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjcmwKKyAgICAgKiAgICAgICAgICAgIHRoZSBDUkwgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIENSTCBtYXRjaGVzIGFsbCB0aGUgY3JpdGVyaWEsIG90aGVyd2lzZQorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChDUkwgY3JsKSB7CisgICAgICAgIGlmICghKGNybCBpbnN0YW5jZW9mIFg1MDlDUkwpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgWDUwOUNSTCBjcmxpc3QgPSAoWDUwOUNSTCkgY3JsOworICAgICAgICBpZiAoKGlzc3Vlck5hbWVzICE9IG51bGwpICYmCisgICAgICAgICAgICAgICAgLy8gdGhlIHNlYXJjaCBzcGVlZCBkZXBlbmRzIG9uIHRoZSBjbGFzcyBvZiBpc3N1ZXJOYW1lcworICAgICAgICAgICAgICAgICEoaXNzdWVyTmFtZXMuY29udGFpbnMoCisgICAgICAgICAgICAgICAgICAgICAgICBjcmxpc3QuZ2V0SXNzdWVyWDUwMFByaW5jaXBhbCgpLmdldE5hbWUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgWDUwMFByaW5jaXBhbC5DQU5PTklDQUwpKSkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoKG1pbkNSTCAhPSBudWxsKSB8fCAobWF4Q1JMICE9IG51bGwpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIEFzIHNwZWNpZmllZCBpbiByZmMgMzI4MCAoaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpCisgICAgICAgICAgICAgICAgLy8gQ1JMIE51bWJlciBFeHRlbnNpb24ncyBPSUQgaXMgMi41LjI5LjIwIC4KKyAgICAgICAgICAgICAgICBieXRlW10gYnl0ZXMgPSBjcmxpc3QuZ2V0RXh0ZW5zaW9uVmFsdWUoIjIuNS4yOS4yMCIpOworICAgICAgICAgICAgICAgIGJ5dGVzID0gKGJ5dGVbXSkgQVNOMU9jdGV0U3RyaW5nLmdldEluc3RhbmNlKCkuZGVjb2RlKGJ5dGVzKTsKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIGNybE51bWJlciA9IG5ldyBCaWdJbnRlZ2VyKChieXRlW10pCisgICAgICAgICAgICAgICAgICAgICAgICBBU04xSW50ZWdlci5nZXRJbnN0YW5jZSgpLmRlY29kZShieXRlcykpOworICAgICAgICAgICAgICAgIGlmICgobWluQ1JMICE9IG51bGwpICYmIChjcmxOdW1iZXIuY29tcGFyZVRvKG1pbkNSTCkgPCAwKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICgobWF4Q1JMICE9IG51bGwpICYmIChjcmxOdW1iZXIuY29tcGFyZVRvKG1heENSTCkgPiAwKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoZGF0ZUFuZFRpbWUgIT0gLTEpIHsKKyAgICAgICAgICAgIERhdGUgdGhpc1VwID0gY3JsaXN0LmdldFRoaXNVcGRhdGUoKTsKKyAgICAgICAgICAgIERhdGUgbmV4dFVwID0gY3JsaXN0LmdldE5leHRVcGRhdGUoKTsKKyAgICAgICAgICAgIGlmICgodGhpc1VwID09IG51bGwpIHx8IChuZXh0VXAgPT0gbnVsbCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoKGRhdGVBbmRUaW1lIDwgdGhpc1VwLmdldFRpbWUoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKGRhdGVBbmRUaW1lID4gbmV4dFVwLmdldFRpbWUoKSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvbmVzIHRoaXMge0Bjb2RlIFg1MDlDUkx9IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2xvbmVkIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIFg1MDlDUkxTZWxlY3RvciByZXN1bHQ7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlc3VsdCA9IChYNTA5Q1JMU2VsZWN0b3IpIHN1cGVyLmNsb25lKCk7CisgICAgICAgICAgICBpZiAoaXNzdWVyTmFtZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5pc3N1ZXJOYW1lcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPihpc3N1ZXJOYW1lcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1g1MDlDZXJ0U2VsZWN0b3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvWDUwOUNlcnRTZWxlY3Rvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI5ODFmNjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1g1MDlDZXJ0U2VsZWN0b3IuamF2YQpAQCAtMCwwICsxLDEzODUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CitpbXBvcnQgbGliY29yZS51dGlsLkVtcHR5QXJyYXk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMU9jdGV0U3RyaW5nOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS51dGlscy5BcnJheTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5BbGdvcml0aG1JZGVudGlmaWVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LkNlcnRpZmljYXRlUG9saWNpZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuR2VuZXJhbE5hbWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuR2VuZXJhbE5hbWVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5Lk5hbWVDb25zdHJhaW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5Qb2xpY3lJbmZvcm1hdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5Qcml2YXRlS2V5VXNhZ2VQZXJpb2Q7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuU3ViamVjdFB1YmxpY0tleUluZm87CisKKworCisvKioKKyAqIEEgY2VydGlmaWNhdGUgc2VsZWN0b3IgKHtAY29kZSBDZXJ0U2VsZWN0b3J9IGZvciBzZWxlY3Rpbmcge0Bjb2RlCisgKiBYNTA5Q2VydGlmaWNhdGV9cyB0aGF0IG1hdGNoIHRoZSBzcGVjaWZpZWQgY3JpdGVyaWEuCisgKi8KK3B1YmxpYyBjbGFzcyBYNTA5Q2VydFNlbGVjdG9yIGltcGxlbWVudHMgQ2VydFNlbGVjdG9yIHsKKworICAgIC8vIG1hdGNoIGNyaXRlcmlhCisgICAgcHJpdmF0ZSBYNTA5Q2VydGlmaWNhdGUgY2VydGlmaWNhdGVFcXVhbHM7CisgICAgcHJpdmF0ZSBCaWdJbnRlZ2VyIHNlcmlhbE51bWJlcjsKKyAgICBwcml2YXRlIFg1MDBQcmluY2lwYWwgaXNzdWVyOworICAgIHByaXZhdGUgWDUwMFByaW5jaXBhbCBzdWJqZWN0OworICAgIHByaXZhdGUgYnl0ZVtdIHN1YmplY3RLZXlJZGVudGlmaWVyOworICAgIHByaXZhdGUgYnl0ZVtdIGF1dGhvcml0eUtleUlkZW50aWZpZXI7CisgICAgcHJpdmF0ZSBEYXRlIGNlcnRpZmljYXRlVmFsaWQ7CisgICAgcHJpdmF0ZSBTdHJpbmcgc3ViamVjdFB1YmxpY0tleUFsZ0lEOworICAgIHByaXZhdGUgRGF0ZSBwcml2YXRlS2V5VmFsaWQ7CisgICAgcHJpdmF0ZSBieXRlW10gc3ViamVjdFB1YmxpY0tleTsKKyAgICBwcml2YXRlIGJvb2xlYW5bXSBrZXlVc2FnZTsKKyAgICBwcml2YXRlIFNldDxTdHJpbmc+IGV4dGVuZGVkS2V5VXNhZ2U7CisgICAgcHJpdmF0ZSBib29sZWFuIG1hdGNoQWxsTmFtZXMgPSB0cnVlOworICAgIHByaXZhdGUgaW50IHBhdGhMZW4gPSAtMTsKKyAgICBwcml2YXRlIExpc3Q8R2VuZXJhbE5hbWU+W10gc3ViamVjdEFsdE5hbWVzOworICAgIHByaXZhdGUgTmFtZUNvbnN0cmFpbnRzIG5hbWVDb25zdHJhaW50czsKKyAgICBwcml2YXRlIFNldDxTdHJpbmc+IHBvbGljaWVzOworICAgIHByaXZhdGUgQXJyYXlMaXN0PEdlbmVyYWxOYW1lPiBwYXRoVG9OYW1lczsKKworICAgIC8vIG5lZWRlZCB0byBhdm9pZCBuZWVkbGVzcyBlbmNvZGluZy9kZWNvZGluZyB3b3JrCisgICAgcHJpdmF0ZSBQdWJsaWNLZXkgc3ViamVjdFB1YmxpY0tleUltcGw7CisgICAgcHJpdmF0ZSBTdHJpbmcgaXNzdWVyTmFtZTsKKyAgICBwcml2YXRlIGJ5dGVbXSBpc3N1ZXJCeXRlczsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFg1MDlDZXJ0U2VsZWN0b3J9LgorICAgICAqLworICAgIHB1YmxpYyBYNTA5Q2VydFNlbGVjdG9yKCkge30KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNlcnRpZmljYXRlIHRoYXQgYSBtYXRjaGluZyBjZXJ0aWZpY2F0ZSBtdXN0IGJlIGVxdWFsIHRvLgorICAgICAqCisgICAgICogQHBhcmFtIGNlcnRpZmljYXRlCisgICAgICogICAgICAgICAgICB0aGUgY2VydGlmaWNhdGUgdG8gbWF0Y2gsIG9yIG51bGwgdG8gbm90IGNoZWNrIHRoaXMgY3JpdGVyaWEuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q2VydGlmaWNhdGUoWDUwOUNlcnRpZmljYXRlIGNlcnRpZmljYXRlKSB7CisgICAgICAgIGNlcnRpZmljYXRlRXF1YWxzID0gY2VydGlmaWNhdGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2VydGlmaWNhdGUgdGhhdCBhIG1hdGNoaW5nIGNlcnRpZmljYXRlIG11c3QgYmUgZXF1YWwgdG8uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjZXJ0aWZpY2F0ZSB0byBtYXRjaCwgb3IgbnVsbCBpZiB0aGlzIGNyaXRlcmlhIGlzIG5vdAorICAgICAqICAgICAgICAgY2hlY2tlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgWDUwOUNlcnRpZmljYXRlIGdldENlcnRpZmljYXRlKCkgeworICAgICAgICByZXR1cm4gY2VydGlmaWNhdGVFcXVhbHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc2VyaWFsIG51bWJlciB0aGF0IGEgY2VydGlmaWNhdGUgbXVzdCBtYXRjaC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzZXJpYWxOdW1iZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZXJpYWwgbnVtYmVyIHRvIG1hdGNoLCBvciB7QGNvZGUgbnVsbH0gdG8gbm90IGNoZWNrIHRoZQorICAgICAqICAgICAgICAgICAgc2VyaWFsIG51bWJlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTZXJpYWxOdW1iZXIoQmlnSW50ZWdlciBzZXJpYWxOdW1iZXIpIHsKKyAgICAgICAgdGhpcy5zZXJpYWxOdW1iZXIgPSBzZXJpYWxOdW1iZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2VyaWFsIG51bWJlciB0aGF0IGEgY2VydGlmaWNhdGUgbXVzdCBtYXRjaC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNlcmlhbCBudW1iZXIgdG8gbWF0Y2gsIG9yIHtAY29kZSBudWxsfSBpZiB0aGUgc2VyaWFsIG51bWJlcgorICAgICAqICAgICAgICAgaXMgbm90IHRvIGJlIGNoZWNrZWQuCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0U2VyaWFsTnVtYmVyKCkgeworICAgICAgICByZXR1cm4gc2VyaWFsTnVtYmVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGlzc3VlciB0aGF0IGEgY2VydGlmaWNhdGUgbXVzdCBtYXRjaC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpc3N1ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBpc3N1ZXIgdG8gbWF0Y2gsIG9yIHtAY29kZSBudWxsfSBpZiB0aGUgaXNzdWVyIGlzIG5vdCB0bworICAgICAqICAgICAgICAgICAgYmUgY2hlY2tlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRJc3N1ZXIoWDUwMFByaW5jaXBhbCBpc3N1ZXIpIHsKKyAgICAgICAgdGhpcy5pc3N1ZXIgPSBpc3N1ZXI7CisgICAgICAgIHRoaXMuaXNzdWVyTmFtZSA9IG51bGw7CisgICAgICAgIHRoaXMuaXNzdWVyQnl0ZXMgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGlzc3VlciB0aGF0IGEgY2VydGlmaWNhdGUgbXVzdCBtYXRjaC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGlzc3VlciB0aGF0IGEgY2VydGlmaWNhdGUgbXVzdCBtYXRjaCwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqICAgICAgICAgaXNzdWVyIGlzIG5vdCB0byBiZSBjaGVja2VkLgorICAgICAqLworICAgIHB1YmxpYyBYNTAwUHJpbmNpcGFsIGdldElzc3VlcigpIHsKKyAgICAgICAgcmV0dXJuIGlzc3VlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8Yj5EbyBub3QgdXNlPC9iPiwgdXNlIHtAbGluayAjZ2V0SXNzdWVyKCl9IG9yCisgICAgICoge0BsaW5rICNnZXRJc3N1ZXJBc0J5dGVzKCl9IGluc3RlYWQuIFNldHMgdGhlIGlzc3VlciB0aGF0IGEgY2VydGlmaWNhdGUKKyAgICAgKiBtdXN0IG1hdGNoLgorICAgICAqCisgICAgICogQHBhcmFtIGlzc3Vlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBpc3N1ZXIgaW4gYSBSRkMgMjI1MyBmb3JtYXQgc3RyaW5nLCBvciB7QGNvZGUgbnVsbH0gdG8gbm90CisgICAgICogICAgICAgICAgICBjaGVjayB0aGUgaXNzdWVyLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBwYXJzaW5nIHRoZSBpc3N1ZXIgZmFpbHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SXNzdWVyKFN0cmluZyBpc3N1ZXJOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaXNzdWVyTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aGlzLmlzc3VlciA9IG51bGw7CisgICAgICAgICAgICB0aGlzLmlzc3Vlck5hbWUgPSBudWxsOworICAgICAgICAgICAgdGhpcy5pc3N1ZXJCeXRlcyA9IG51bGw7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoaXMuaXNzdWVyID0gbmV3IFg1MDBQcmluY2lwYWwoaXNzdWVyTmFtZSk7CisgICAgICAgICAgICB0aGlzLmlzc3Vlck5hbWUgPSBpc3N1ZXJOYW1lOworICAgICAgICAgICAgdGhpcy5pc3N1ZXJCeXRlcyA9IG51bGw7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogPGI+RG8gbm90IHVzZTwvYj4sIHVzZSB7QGxpbmsgI2dldElzc3VlcigpfSBvcgorICAgICAqIHtAbGluayAjZ2V0SXNzdWVyQXNCeXRlcygpfSBpbnN0ZWFkLiBSZXR1cm5zIHRoZSBpc3N1ZXIgdGhhdCBhCisgICAgICogY2VydGlmaWNhdGUgbXVzdCBtYXRjaCBpbiBhIFJGQyAyMjUzIGZvcm1hdCBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpc3N1ZXIgaW4gYSBSRkMgMjI1MyBmb3JtYXQgc3RyaW5nLCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlCisgICAgICogICAgICAgICBpc3N1ZXIgaXMgbm90IHRvIGJlIGNoZWNrZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRJc3N1ZXJBc1N0cmluZygpIHsKKyAgICAgICAgaWYgKGlzc3VlciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaXNzdWVyTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICBpc3N1ZXJOYW1lID0gaXNzdWVyLmdldE5hbWUoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaXNzdWVyTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBpc3N1ZXIgdGhhdCBhIGNlcnRpZmljYXRlIG11c3QgbWF0Y2guCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXNzdWVyRE4KKyAgICAgKiAgICAgICAgICAgIHRoZSBkaXN0aW5ndWlzaGVkIGlzc3VlciBuYW1lIGluIEFTTi4xIERFUiBlbmNvZGVkIGZvcm1hdCwgb3IKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBudWxsfSB0byBub3QgY2hlY2sgdGhlIGlzc3Vlci4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZGVjb2RpbmcgdGhlIGlzc3VlciBmYWlsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldElzc3VlcihieXRlW10gaXNzdWVyRE4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpc3N1ZXJETiA9PSBudWxsKSB7CisgICAgICAgICAgICBpc3N1ZXIgPSBudWxsOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpc3N1ZXIgPSBuZXcgWDUwMFByaW5jaXBhbChpc3N1ZXJETik7CisgICAgICAgICAgICB0aGlzLmlzc3Vlck5hbWUgPSBudWxsOworICAgICAgICAgICAgdGhpcy5pc3N1ZXJCeXRlcyA9IG5ldyBieXRlW2lzc3VlckROLmxlbmd0aF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGlzc3VlckROLCAwLCB0aGlzLmlzc3VlckJ5dGVzLCAwLCBpc3N1ZXJETi5sZW5ndGgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGlzc3VlciB0aGF0IGEgY2VydGlmaWNhdGUgbXVzdCBtYXRjaC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGRpc3Rpbmd1aXNoZWQgaXNzdWVyIG5hbWUgaW4gQVNOLjEgREVSIGVuY29kZWQgZm9ybWF0LCBvcgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlmIHRoZSBpc3N1ZXIgaXMgbm90IHRvIGJlIGNoZWNrZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVuY29kaW5nIHRoZSBpc3N1ZXIgZmFpbHMuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRJc3N1ZXJBc0J5dGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzc3VlciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaXNzdWVyQnl0ZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgaXNzdWVyQnl0ZXMgPSBpc3N1ZXIuZ2V0RW5jb2RlZCgpOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtpc3N1ZXJCeXRlcy5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGlzc3VlckJ5dGVzLCAwLCByZXN1bHQsIDAsIGlzc3VlckJ5dGVzLmxlbmd0aCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzdWJqZWN0IHRoYXQgYSBjZXJ0aWZpY2F0ZSBtdXN0IG1hdGNoLgorICAgICAqCisgICAgICogQHBhcmFtIHN1YmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdWJqZWN0IGRpc3Rpbmd1aXNoZWQgbmFtZSBvciB7QGNvZGUgbnVsbH0gdG8gbm90IGNoZWNrCisgICAgICogICAgICAgICAgICB0aGUgc3ViamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTdWJqZWN0KFg1MDBQcmluY2lwYWwgc3ViamVjdCkgeworICAgICAgICB0aGlzLnN1YmplY3QgPSBzdWJqZWN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN1YmplY3QgdGhhdCBhIGNlcnRpZmljYXRlIG11c3QgbWF0Y2guCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdWJqZWN0IGRpc3Rpbmd1aXNoZWQgbmFtZSwgb3IgbnVsbCBpZiB0aGUgc3ViamVjdCBpcyBub3QgdG8KKyAgICAgKiAgICAgICAgIGJlIGNoZWNrZWQuCisgICAgICovCisgICAgcHVibGljIFg1MDBQcmluY2lwYWwgZ2V0U3ViamVjdCgpIHsKKyAgICAgICAgcmV0dXJuIHN1YmplY3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogPGI+RG8gbm90IHVzZTwvYj4sIHVzZSB7QGxpbmsgI3NldFN1YmplY3QoYnl0ZVtdKX0gb3IKKyAgICAgKiB7QGxpbmsgI3NldFN1YmplY3QoWDUwMFByaW5jaXBhbCl9IGluc3RlYWQuIFJldHVybnMgdGhlIHN1YmplY3QgdGhhdCBhCisgICAgICogY2VydGlmaWNhdGUgbXVzdCBtYXRjaC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdWJqZWN0RE4KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdWJqZWN0IGRpc3Rpbmd1aXNoZWQgbmFtZSBpbiBSRkMgMjI1MyBmb3JtYXQgb3Ige0Bjb2RlCisgICAgICogICAgICAgICAgICBudWxsfSB0byBub3QgY2hlY2sgdGhlIHN1YmplY3QuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGRlY29kaW5nIHRoZSBzdWJqZWN0IGZhaWxzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN1YmplY3QoU3RyaW5nIHN1YmplY3RETikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHN1YmplY3RETiA9PSBudWxsKSB7CisgICAgICAgICAgICBzdWJqZWN0ID0gbnVsbDsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc3ViamVjdCA9IG5ldyBYNTAwUHJpbmNpcGFsKHN1YmplY3RETik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogPGI+RG8gbm90IHVzZTwvYj4sIHVzZSB7QGxpbmsgI2dldFN1YmplY3QoKX0gb3IKKyAgICAgKiB7QGxpbmsgI2dldFN1YmplY3RBc0J5dGVzKCl9IGluc3RlYWQuIFJldHVybnMgdGhlIHN1YmplY3QgdGhhdCBhCisgICAgICogY2VydGlmaWNhdGUgbXVzdCBtYXRjaC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN1YmplY3QgZGlzdGluZ3Vpc2hlZCBuYW1lIGluIFJGQyAyMjUzIGZvcm1hdCwgb3Ige0Bjb2RlCisgICAgICogICAgICAgICBudWxsfSBpZiB0aGUgc3ViamVjdCBpcyBub3QgdG8gYmUgY2hlY2tlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFN1YmplY3RBc1N0cmluZygpIHsKKyAgICAgICAgaWYgKHN1YmplY3QgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN1YmplY3QuZ2V0TmFtZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHN1YmplY3QgdGhhdCBhIGNlcnRpZmljYXRlIG11c3QgbWF0Y2guCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3ViamVjdEROCisgICAgICogICAgICAgICAgICB0aGUgc3ViamVjdCBkaXN0aW5ndWlzaGVkIG5hbWUgaW4gQVNOLjEgREVSIGZvcm1hdCwgb3Ige0Bjb2RlCisgICAgICogICAgICAgICAgICBudWxsfSB0byBub3QgY2hlY2sgdGhlIHN1YmplY3QuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGRlY29kaW5nIHRoZSBzdWJqZWN0IGZhaWxzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN1YmplY3QoYnl0ZVtdIHN1YmplY3RETikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHN1YmplY3RETiA9PSBudWxsKSB7CisgICAgICAgICAgICBzdWJqZWN0ID0gbnVsbDsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc3ViamVjdCA9IG5ldyBYNTAwUHJpbmNpcGFsKHN1YmplY3RETik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3ViamVjdCB0aGF0IGEgY2VydGlmaWNhdGUgbXVzdCBtYXRjaC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN1YmplY3QgZGlzdGluZ3Vpc2hlZCBuYW1lIGluIEFTTi4xIERFUiBmb3JtYXQsIG9yIHtAY29kZQorICAgICAqICAgICAgICAgbnVsbH0gaWYgdGhlIHN1YmplY3QgaXMgbm90IHRvIGJlIGNoZWNrZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVuY29kaW5nIHRoZSBzdWJqZWN0IGZhaWxzLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0U3ViamVjdEFzQnl0ZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoc3ViamVjdCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3ViamVjdC5nZXRFbmNvZGVkKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY3JpdGVyaW9uIGZvciB0aGUge0BsaXRlcmFsIFN1YmplY3RLZXlJZGVudGlmaWVyfSBleHRlbnNpb24uCisgICAgICogPHA+CisgICAgICogVGhlIHtAY29kZSBzdWJqZWN0S2V5SWRlbnRpZmllcn0gc2hvdWxkIGJlIGEgc2luZ2xlIERFUiBlbmNvZGVkIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHN1YmplY3RLZXlJZGVudGlmaWVyCisgICAgICogICAgICAgICAgICB0aGUgc3ViamVjdCBrZXkgaWRlbnRpZmllciBvciB7QGNvZGUgbnVsbH0gdG8gZGlzYWJsZSB0aGlzCisgICAgICogICAgICAgICAgICBjaGVjay4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTdWJqZWN0S2V5SWRlbnRpZmllcihieXRlW10gc3ViamVjdEtleUlkZW50aWZpZXIpIHsKKyAgICAgICAgaWYgKHN1YmplY3RLZXlJZGVudGlmaWVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMuc3ViamVjdEtleUlkZW50aWZpZXIgPSBudWxsOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHRoaXMuc3ViamVjdEtleUlkZW50aWZpZXIgPSBuZXcgYnl0ZVtzdWJqZWN0S2V5SWRlbnRpZmllci5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHN1YmplY3RLZXlJZGVudGlmaWVyLCAwLCB0aGlzLnN1YmplY3RLZXlJZGVudGlmaWVyLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgIHN1YmplY3RLZXlJZGVudGlmaWVyLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3JpdGVyaW9uIGZvciB0aGUge0BsaXRlcmFsIFN1YmplY3RLZXlJZGVudGlmaWVyfSBleHRlbnNpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdWJqZWN0IGtleSBpZGVudGlmaWVyIG9yIHtAY29kZSBudWxsfSBpZiBpdCBpcyBub3QgdG8gYmUKKyAgICAgKiAgICAgICAgIGNoZWNrZWQuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRTdWJqZWN0S2V5SWRlbnRpZmllcigpIHsKKyAgICAgICAgaWYgKHN1YmplY3RLZXlJZGVudGlmaWVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSByZXMgPSBuZXcgYnl0ZVtzdWJqZWN0S2V5SWRlbnRpZmllci5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHN1YmplY3RLZXlJZGVudGlmaWVyLCAwLCByZXMsIDAsIHJlcy5sZW5ndGgpOworICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNyaXRlcmlvbiBmb3IgdGhlIHtAbGl0ZXJhbCBBdXRob3JpdHlLZXlJZGVudGlmaWVyfSBleHRlbnNpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXV0aG9yaXR5S2V5SWRlbnRpZmllcgorICAgICAqICAgICAgICAgICAgdGhlIGF1dGhvcml0eSBrZXkgaWRlbnRpZmllciwgb3Ige0Bjb2RlIG51bGx9IHRvIGRpc2FibGUgdGhpcworICAgICAqICAgICAgICAgICAgY2hlY2suCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QXV0aG9yaXR5S2V5SWRlbnRpZmllcihieXRlW10gYXV0aG9yaXR5S2V5SWRlbnRpZmllcikgeworICAgICAgICBpZiAoYXV0aG9yaXR5S2V5SWRlbnRpZmllciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aGlzLmF1dGhvcml0eUtleUlkZW50aWZpZXIgPSBudWxsOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHRoaXMuYXV0aG9yaXR5S2V5SWRlbnRpZmllciA9IG5ldyBieXRlW2F1dGhvcml0eUtleUlkZW50aWZpZXIubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShhdXRob3JpdHlLZXlJZGVudGlmaWVyLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXV0aG9yaXR5S2V5SWRlbnRpZmllciwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBhdXRob3JpdHlLZXlJZGVudGlmaWVyLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3JpdGVyaW9uIGZvciB0aGUge0BsaXRlcmFsIEF1dGhvcml0eUtleUlkZW50aWZpZXJ9CisgICAgICogZXh0ZW5zaW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYXV0aG9yaXR5IGtleSBpZGVudGlmaWVyLCBvciB7QGNvZGUgbnVsbH0gaWYgaXQgaXMgbm90IHRvIGJlCisgICAgICogICAgICAgICBjaGVja2VkLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0QXV0aG9yaXR5S2V5SWRlbnRpZmllcigpIHsKKyAgICAgICAgaWYgKGF1dGhvcml0eUtleUlkZW50aWZpZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIHJlcyA9IG5ldyBieXRlW2F1dGhvcml0eUtleUlkZW50aWZpZXIubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShhdXRob3JpdHlLZXlJZGVudGlmaWVyLCAwLCByZXMsIDAsIHJlcy5sZW5ndGgpOworICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNyaXRlcmlvbiBmb3IgdGhlIHZhbGlkaXR5IGRhdGUgb2YgdGhlIGNlcnRpZmljYXRlLgorICAgICAqIDxwPgorICAgICAqIFRoZSBjZXJ0aWZpY2F0ZSBtdXN0IGJlIHZhbGlkIGF0IHRoZSBzcGVjaWZpZWQgZGF0ZS4KKyAgICAgKiBAcGFyYW0gY2VydGlmaWNhdGVWYWxpZAorICAgICAqICAgICAgICAgICAgdGhlIHZhbGlkaXR5IGRhdGUgb3Ige0Bjb2RlIG51bGx9IHRvIG5vdCBjaGVjayB0aGUgZGF0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDZXJ0aWZpY2F0ZVZhbGlkKERhdGUgY2VydGlmaWNhdGVWYWxpZCkgeworICAgICAgICB0aGlzLmNlcnRpZmljYXRlVmFsaWQgPSAoY2VydGlmaWNhdGVWYWxpZCA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IG51bGwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAoRGF0ZSkgY2VydGlmaWNhdGVWYWxpZC5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNyaXRlcmlvbiBmb3IgdGhlIHZhbGlkaXR5IGRhdGUgb2YgdGhlIGNlcnRpZmljYXRlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdmFsaWRpdHkgZGF0ZSBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIGRhdGUgaXMgbm90IHRvIGJlCisgICAgICogICAgICAgICBjaGVja2VkLgorICAgICAqLworICAgIHB1YmxpYyBEYXRlIGdldENlcnRpZmljYXRlVmFsaWQoKSB7CisgICAgICAgIHJldHVybiAoY2VydGlmaWNhdGVWYWxpZCA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IG51bGwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAoRGF0ZSkgY2VydGlmaWNhdGVWYWxpZC5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNyaXRlcmlvbiBmb3IgdGhlIHZhbGlkaXR5IGRhdGUgb2YgdGhlIHByaXZhdGUga2V5LgorICAgICAqIDxwPgorICAgICAqIFRoZSBwcml2YXRlIGtleSBtdXN0IGJlIHZhbGlkIGF0IHRoZSBzcGVjaWZpZWQgZGF0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcml2YXRlS2V5VmFsaWQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWxpZGl0eSBkYXRlIG9yIHtAY29kZSBudWxsfSB0byBub3QgY2hlY2sgdGhlIGRhdGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UHJpdmF0ZUtleVZhbGlkKERhdGUgcHJpdmF0ZUtleVZhbGlkKSB7CisgICAgICAgIGlmIChwcml2YXRlS2V5VmFsaWQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhpcy5wcml2YXRlS2V5VmFsaWQgPSBudWxsOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHRoaXMucHJpdmF0ZUtleVZhbGlkID0gKERhdGUpIHByaXZhdGVLZXlWYWxpZC5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNyaXRlcmlvbiBmb3IgdGhlIHZhbGlkaXR5IGRhdGUgb2YgdGhlIHByaXZhdGUga2V5LgorICAgICAqIDxwPgorICAgICAqIFRoZSBwcml2YXRlIGtleSBtdXN0IGJlIHZhbGlkIGF0IHRoZSBzcGVjaWZpZWQgZGF0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHZhbGlkaXR5IGRhdGUgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZSBkYXRlIGlzIG5vdCB0byBiZQorICAgICAqICAgICAgICAgY2hlY2tlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0ZSBnZXRQcml2YXRlS2V5VmFsaWQoKSB7CisgICAgICAgIGlmIChwcml2YXRlS2V5VmFsaWQgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIChEYXRlKSBwcml2YXRlS2V5VmFsaWQuY2xvbmUoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tPSUQoU3RyaW5nIG9pZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGJlZyA9IDA7CisgICAgICAgIGludCBlbmQgPSBvaWQuaW5kZXhPZignLicsIGJlZyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgY29tcCA9IEludGVnZXIucGFyc2VJbnQob2lkLnN1YnN0cmluZyhiZWcsIGVuZCkpOworICAgICAgICAgICAgYmVnID0gZW5kICsgMTsKKyAgICAgICAgICAgIGlmICgoY29tcCA8IDApIHx8IChjb21wID4gMikpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkJhZCBPSUQ6ICIgKyBvaWQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZW5kID0gb2lkLmluZGV4T2YoJy4nLCBiZWcpOworICAgICAgICAgICAgY29tcCA9IEludGVnZXIucGFyc2VJbnQob2lkLnN1YnN0cmluZyhiZWcsIGVuZCkpOworICAgICAgICAgICAgaWYgKChjb21wIDwgMCkgfHwgKGNvbXAgPiAzOSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkJhZCBPSUQ6ICIgKyBvaWQpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQmFkIE9JRDogIiArIG9pZCk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkJhZCBPSUQ6ICIgKyBvaWQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY3JpdGVyaW9uIGZvciB0aGUgc3ViamVjdCBwdWJsaWMga2V5IHNpZ25hdHVyZSBhbGdvcml0aG0uCisgICAgICogPHA+CisgICAgICogVGhlIGNlcnRpZmljYXRlIG11c3QgY29udGFpbiBhIHN1YmplY3QgcHVibGljIGtleSB3aXRoIHRoZSBhbGdvcml0aG0KKyAgICAgKiBzcGVjaWZpZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2lkCisgICAgICogICAgICAgICAgICB0aGUgT0lEIChvYmplY3QgaWRlbnRpZmllcikgb2YgdGhlIHNpZ25hdHVyZSBhbGdvcml0aG0gb3IKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBudWxsfSB0byBub3QgY2hlY2sgdGhlIE9JRC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaWRlbnRpZmllciBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN1YmplY3RQdWJsaWNLZXlBbGdJRChTdHJpbmcgb2lkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAob2lkID09IG51bGwpIHsKKyAgICAgICAgICAgIHN1YmplY3RQdWJsaWNLZXlBbGdJRCA9IG51bGw7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tPSUQob2lkKTsKKyAgICAgICAgc3ViamVjdFB1YmxpY0tleUFsZ0lEID0gb2lkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNyaXRlcmlvbiBmb3IgdGhlIHN1YmplY3QgcHVibGljIGtleSBzaWduYXR1cmUgYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgT0lEIChvYmplY3QgaWRlbnRpZmllcikgb3IgdGhlIHNpZ25hdHVyZSBhbGdvcml0aG0gb3Ige0Bjb2RlCisgICAgICogICAgICAgICBudWxsfSBpZiBpdCdzIG5vdCB0byBiZSBjaGVja2VkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3ViamVjdFB1YmxpY0tleUFsZ0lEKCkgeworICAgICAgICByZXR1cm4gc3ViamVjdFB1YmxpY0tleUFsZ0lEOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNyaXRlcmlvbiBmb3IgdGhlIHN1YmplY3QgcHVibGljIGtleS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdWJqZWN0IHB1YmxpYyBrZXkgb3Ige0Bjb2RlIG51bGx9IHRvIG5vdCBjaGVjayB0aGUga2V5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN1YmplY3RQdWJsaWNLZXkoUHVibGljS2V5IGtleSkgeworICAgICAgICBzdWJqZWN0UHVibGljS2V5ID0gKGtleSA9PSBudWxsKSA/IG51bGwgOiBrZXkuZ2V0RW5jb2RlZCgpOworICAgICAgICBzdWJqZWN0UHVibGljS2V5SW1wbCA9IGtleTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjcml0ZXJpb24gZm9yIHRoZSBzdWJqZWN0IHB1YmxpYyBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUgc3ViamVjdCBwdWJsaWMga2V5IGluIEFTTi4xIERFUiBlbmNvZGVkIGZvcm1hdCBvciB7QGNvZGUgbnVsbH0gdG8KKyAgICAgKiAgICAgICAgICAgIG5vdCBjaGVjayB0aGUga2V5LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBkZWNvZGluZyB0aGUgdGhlIHB1YmxpYyBrZXkgZmFpbHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3ViamVjdFB1YmxpY0tleShieXRlW10ga2V5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHN1YmplY3RQdWJsaWNLZXkgPSBudWxsOworICAgICAgICAgICAgc3ViamVjdFB1YmxpY0tleUltcGwgPSBudWxsOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHN1YmplY3RQdWJsaWNLZXkgPSBuZXcgYnl0ZVtrZXkubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShrZXksIDAsIHN1YmplY3RQdWJsaWNLZXksIDAsIGtleS5sZW5ndGgpOworICAgICAgICBzdWJqZWN0UHVibGljS2V5SW1wbCA9CisgICAgICAgICAgICAoKFN1YmplY3RQdWJsaWNLZXlJbmZvKSBTdWJqZWN0UHVibGljS2V5SW5mby5BU04xLmRlY29kZShrZXkpKQorICAgICAgICAgICAgLmdldFB1YmxpY0tleSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNyaXRlcmlvbiBmb3IgdGhlIHN1YmplY3QgcHVibGljIGtleS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN1YmplY3QgcHVibGljIGtleSBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIGtleSBpcyBub3QgdG8gYmUKKyAgICAgKiAgICAgICAgIGNoZWNrZWQuCisgICAgICovCisgICAgcHVibGljIFB1YmxpY0tleSBnZXRTdWJqZWN0UHVibGljS2V5KCkgeworICAgICAgICByZXR1cm4gc3ViamVjdFB1YmxpY0tleUltcGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY3JpdGVyaW9uIGZvciB0aGUge0BsaXRlcmFsIEtleVVzYWdlfSBleHRlbnNpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5VXNhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBib29sZWFuIGFycmF5IGluIHRoZSBmb3JtYXQgYXMgcmV0dXJuZWQgYnkKKyAgICAgKiAgICAgICAgICAgIHtAbGluayBYNTA5Q2VydGlmaWNhdGUjZ2V0S2V5VXNhZ2UoKX0sIG9yIHtAY29kZSBudWxsfSB0byBub3QKKyAgICAgKiAgICAgICAgICAgIGNoZWNrIHRoZSBrZXkgdXNhZ2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0S2V5VXNhZ2UoYm9vbGVhbltdIGtleVVzYWdlKSB7CisgICAgICAgIGlmIChrZXlVc2FnZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aGlzLmtleVVzYWdlID0gbnVsbDsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmtleVVzYWdlID0gbmV3IGJvb2xlYW5ba2V5VXNhZ2UubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShrZXlVc2FnZSwgMCwgdGhpcy5rZXlVc2FnZSwgMCwga2V5VXNhZ2UubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjcml0ZXJpb24gZm9yIHRoZSB7QGxpdGVyYWwgS2V5VXNhZ2V9IGV4dGVuc2lvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJvb2xlYW4gYXJyYXkgaW4gdGhlIGZvcm1hdCBhcyByZXR1cm5lZCBieQorICAgICAqICAgICAgICAge0BsaW5rIFg1MDlDZXJ0aWZpY2F0ZSNnZXRLZXlVc2FnZSgpfSwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZSBrZXkKKyAgICAgKiAgICAgICAgIHVzYWdlIGlzIG5vdCB0byBiZSBjaGVja2VkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuW10gZ2V0S2V5VXNhZ2UoKSB7CisgICAgICAgIGlmIChrZXlVc2FnZSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBib29sZWFuW10gcmVzdWx0ID0gbmV3IGJvb2xlYW5ba2V5VXNhZ2UubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShrZXlVc2FnZSwgMCwgcmVzdWx0LCAwLCBrZXlVc2FnZS5sZW5ndGgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNyaXRlcmlvbiBmb3IgdGhlIHtAbGl0ZXJhbCBFeHRlbmRlZEtleVVzYWdlfSBleHRlbnNpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5VXNhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZXQgb2Yga2V5IHVzYWdlIE9JRHMsIG9yIHtAY29kZSBudWxsfSB0byBub3QgY2hlY2sgaXQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG9uZSBvZiB0aGUgT0lEcyBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEV4dGVuZGVkS2V5VXNhZ2UoU2V0PFN0cmluZz4ga2V5VXNhZ2UpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGV4dGVuZGVkS2V5VXNhZ2UgPSBudWxsOworICAgICAgICBpZiAoKGtleVVzYWdlID09IG51bGwpIHx8IChrZXlVc2FnZS5zaXplKCkgPT0gMCkpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBIYXNoU2V0PFN0cmluZz4ga2V5X3UgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7CisgICAgICAgIGZvciAoU3RyaW5nIHVzYWdlIDoga2V5VXNhZ2UpIHsKKyAgICAgICAgICAgIGNoZWNrT0lEKHVzYWdlKTsKKyAgICAgICAgICAgIGtleV91LmFkZCh1c2FnZSk7CisgICAgICAgIH0KKyAgICAgICAgZXh0ZW5kZWRLZXlVc2FnZSA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNldChrZXlfdSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3JpdGVyaW9uIGZvciB0aGUge0BsaXRlcmFsIEV4dGVuZGVkS2V5VXNhZ2V9IGV4dGVuc2lvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNldCBvZiBrZXkgdXNhZ2UgT0lEcywgb3Ige0Bjb2RlIG51bGx9IGlmIGl0J3Mgbm90IHRvIGJlCisgICAgICogICAgICAgICBjaGVja2VkLgorICAgICAqLworICAgIHB1YmxpYyBTZXQ8U3RyaW5nPiBnZXRFeHRlbmRlZEtleVVzYWdlKCkgeworICAgICAgICByZXR1cm4gZXh0ZW5kZWRLZXlVc2FnZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBmbGFnIGZvciB0aGUgbWF0Y2hpbmcgYmVoYXZpb3IgZm9yIHN1YmplY3QgYWx0ZXJuYXRpdmUgbmFtZXMuCisgICAgICogPHA+CisgICAgICogVGhlIGZsYWcgaW5kaWNhdGVzIHdoZXRoZXIgYSBjZXJ0aWZpY2F0ZSBtdXN0IGNvbnRhaW4gYWxsIG9yIGF0IGxlYXN0IG9uZQorICAgICAqIG9mIHRoZSBzdWJqZWN0IGFsdGVybmF0aXZlIG5hbWVzIHNwZWNpZmllZCBieSB7QGxpbmsKKyAgICAgKiAjc2V0U3ViamVjdEFsdGVybmF0aXZlTmFtZXN9IG9yIHtAbGluayAjYWRkU3ViamVjdEFsdGVybmF0aXZlTmFtZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWF0Y2hBbGxOYW1lcworICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGlmIGEgY2VydGlmaWNhdGUgbXVzdCBjb250YWluIGFsbCBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgIHNwZWNpZmllZCBzdWJqZWN0IGFsdGVybmF0aXZlIG5hbWVzLCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRNYXRjaEFsbFN1YmplY3RBbHROYW1lcyhib29sZWFuIG1hdGNoQWxsTmFtZXMpIHsKKyAgICAgICAgdGhpcy5tYXRjaEFsbE5hbWVzID0gbWF0Y2hBbGxOYW1lczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBmbGFnIGZvciB0aGUgbWF0Y2hpbmcgYmVoYXZpb3IgZm9yIHN1YmplY3QgYWx0ZXJuYXRpdmUgbmFtZXMuCisgICAgICogPHA+CisgICAgICogVGhlIGZsYWcgaW5kaWNhdGVzIHdoZXRoZXIgYSBjZXJ0aWZpY2F0ZSBtdXN0IGNvbnRhaW4gYWxsIG9yIGF0IGxlYXN0IG9uZQorICAgICAqIG9mIHRoZSBzdWJqZWN0IGFsdGVybmF0aXZlIG5hbWVzIHNwZWNpZmllZCBieSB7QGxpbmsKKyAgICAgKiAjc2V0U3ViamVjdEFsdGVybmF0aXZlTmFtZXN9IG9yIHtAbGluayAjYWRkU3ViamVjdEFsdGVybmF0aXZlTmFtZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBhIGNlcnRpZmljYXRlIG11c3QgY29udGFpbiBhbGwgb2YgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgc3ViamVjdCBhbHRlcm5hdGl2ZSBuYW1lcywgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0TWF0Y2hBbGxTdWJqZWN0QWx0TmFtZXMoKSB7CisgICAgICAgIHJldHVybiBtYXRjaEFsbE5hbWVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNyaXRlcmlvbiBmb3Igc3ViamVjdCBhbHRlcm5hdGl2ZSBuYW1lcy4KKyAgICAgKiA8cD4KKyAgICAgKiB0aGUgY2VydGlmaWNhdGUgbXVzdCBjb250YWluIGFsbCBvciBhdCBsZWFzdCBvbmUgb2YgdGhlIHNwZWNpZmllZCBzdWJqZWN0CisgICAgICogYWx0ZXJuYXRpdmUgbmFtZXMuIFRoZSBiZWhhdmlvciBpcyBzcGVjaWZpZWQgYnkKKyAgICAgKiB7QGxpbmsgI2dldE1hdGNoQWxsU3ViamVjdEFsdE5hbWVzfS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgc3BlY2lmaWVkIHBhcmFtZXRlciB7QGNvZGUgbmFtZXN9IGlzIGEgY29sbGVjdGlvbiB3aXRoIGFuIGVudHJ5IGZvcgorICAgICAqIGVhY2ggbmFtZSB0byBiZSBpbmNsdWRlZCBpbiB0aGUgY3JpdGVyaW9uLiBUaGUgbmFtZSBpcyBzcGVjaWZpZWQgYXMgYQorICAgICAqIHtAY29kZSBMaXN0fSwgdGhlIGZpcnN0IGVudHJ5IG11c3QgYmUgYW4ge0Bjb2RlIEludGVnZXJ9IHNwZWNpZnlpbmcgdGhlCisgICAgICogbmFtZSB0eXBlICgwLTgpLCB0aGUgc2Vjb25kIGVudHJ5IG11c3QgYmUgYSB7QGNvZGUgU3RyaW5nfSBvciBhIGJ5dGUKKyAgICAgKiBhcnJheSBzcGVjaWZ5aW5nIHRoZSBuYW1lIChpbiBzdHJpbmcgb3IgQVNOLjEgREVSIGVuY29kZWQgZm9ybSkKKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lcworICAgICAqICAgICAgICAgICAgdGhlIG5hbWVzIGNvbGxlY3Rpb24gb3Ige0Bjb2RlIG51bGx9IHRvIG5vdCBwZXJmb3JtIHRoaXMgY2hlY2suCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBkZWNvZGluZyBvZiBhIG5hbWUgZmFpbHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3ViamVjdEFsdGVybmF0aXZlTmFtZXMoQ29sbGVjdGlvbjxMaXN0PD8+PiBuYW1lcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3ViamVjdEFsdE5hbWVzID0gbnVsbDsKKyAgICAgICAgaWYgKChuYW1lcyA9PSBudWxsKSB8fCAobmFtZXMuc2l6ZSgpID09IDApKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZm9yIChMaXN0PD8+IG5hbWUgOiBuYW1lcykgeworICAgICAgICAgICAgaW50IHRhZyA9IChJbnRlZ2VyKSBuYW1lLmdldCgwKTsKKyAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IG5hbWUuZ2V0KDEpOworICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKSB7CisgICAgICAgICAgICAgICAgYWRkU3ViamVjdEFsdGVybmF0aXZlTmFtZSh0YWcsIChTdHJpbmcpIHZhbHVlKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBieXRlW10pIHsKKyAgICAgICAgICAgICAgICBhZGRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lKHRhZywgKGJ5dGVbXSkgdmFsdWUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIm5hbWUgbmVpdGhlciBhIFN0cmluZyBub3IgYSBieXRlW10iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSBzdWJqZWN0IGFsdGVybmF0aXZlIG5hbWUgdG8gdGhlIHJlc3BlY3RpdmUgY3JpdGVyaW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHRhZworICAgICAqICAgICAgICAgICAgdGhlIHR5cGUgb2YgdGhlIG5hbWUKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgaW4gc3RyaW5nIGZvcm1hdC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgcGFyc2luZyB0aGUgbmFtZSBmYWlscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lKGludCB0YWcsIFN0cmluZyBuYW1lKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEdlbmVyYWxOYW1lIGFsdF9uYW1lID0gbmV3IEdlbmVyYWxOYW1lKHRhZywgbmFtZSk7CisgICAgICAgIC8vIGNyZWF0ZSBvbmx5IGlmIHRoZXJlIHdhcyBub3QgYW55IGVycm9ycworICAgICAgICBpZiAoc3ViamVjdEFsdE5hbWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHN1YmplY3RBbHROYW1lcyA9IG5ldyBBcnJheUxpc3RbOV07CisgICAgICAgIH0KKyAgICAgICAgaWYgKHN1YmplY3RBbHROYW1lc1t0YWddID09IG51bGwpIHsKKyAgICAgICAgICAgIHN1YmplY3RBbHROYW1lc1t0YWddID0gbmV3IEFycmF5TGlzdDxHZW5lcmFsTmFtZT4oKTsKKyAgICAgICAgfQorICAgICAgICBzdWJqZWN0QWx0TmFtZXNbdGFnXS5hZGQoYWx0X25hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSBzdWJqZWN0IGFsdGVybmF0aXZlIG5hbWUgdG8gdGhlIHJlc3BlY3RpdmUgY3JpdGVyaW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHRhZworICAgICAqICAgICAgICAgICAgdGhlIHR5cGUgb2YgdGhlIG5hbWUuCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIGluIEFTTi4xIERFUiBlbmNvZGVkIGZvcm0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBkZWNvZGluZyBvZiB0aGUgbmFtZSBmYWlscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lKGludCB0YWcsIGJ5dGVbXSBuYW1lKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBHZW5lcmFsTmFtZSBhbHRfbmFtZSA9IG5ldyBHZW5lcmFsTmFtZSh0YWcsIG5hbWUpOworICAgICAgICAvLyBjcmVhdGUgb25seSBpZiB0aGVyZSB3YXMgbm90IGFueSBlcnJvcnMKKyAgICAgICAgaWYgKHN1YmplY3RBbHROYW1lcyA9PSBudWxsKSB7CisgICAgICAgICAgICBzdWJqZWN0QWx0TmFtZXMgPSBuZXcgQXJyYXlMaXN0WzldOworICAgICAgICB9CisgICAgICAgIGlmIChzdWJqZWN0QWx0TmFtZXNbdGFnXSA9PSBudWxsKSB7CisgICAgICAgICAgICBzdWJqZWN0QWx0TmFtZXNbdGFnXSA9IG5ldyBBcnJheUxpc3Q8R2VuZXJhbE5hbWU+KCk7CisgICAgICAgIH0KKyAgICAgICAgc3ViamVjdEFsdE5hbWVzW3RhZ10uYWRkKGFsdF9uYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjcml0ZXJpb24gZm9yIHN1YmplY3QgYWx0ZXJuYXRpdmUgbmFtZXMuCisgICAgICogPHA+CisgICAgICogdGhlIGNlcnRpZmljYXRlIG11c3QgY29udGFpbiBhbGwgb3IgYXQgbGVhc3Qgb25lIG9mIHRoZSBzcGVjaWZpZWQgc3ViamVjdAorICAgICAqIGFsdGVybmF0aXZlIG5hbWVzLiBUaGUgYmVoYXZpb3IgaXMgc3BlY2lmaWVkIGJ5CisgICAgICoge0BsaW5rICNnZXRNYXRjaEFsbFN1YmplY3RBbHROYW1lc30uCisgICAgICogPHA+CisgICAgICogVGhlIHN1YmplY3QgYWx0ZXJuYXRpdmUgbmFtZXMgaXMgYSBjb2xsZWN0aW9uIHdpdGggYW4gZW50cnkgZm9yIGVhY2ggbmFtZQorICAgICAqIGluY2x1ZGVkIGluIHRoZSBjcml0ZXJpb24uIFRoZSBuYW1lIGlzIHNwZWNpZmllZCBhcyBhIHtAY29kZSBMaXN0fSwgdGhlCisgICAgICogZmlyc3QgZW50cnkgaXMgYW4ge0Bjb2RlIEludGVnZXJ9IHNwZWNpZnlpbmcgdGhlIG5hbWUgdHlwZSAoMC04KSwgdGhlCisgICAgICogc2Vjb25kIGVudHJ5IGlzIGJ5dGUgYXJyYXkgc3BlY2lmeWluZyB0aGUgbmFtZSBpbiBBU04uMSBERVIgZW5jb2RlZCBmb3JtKQorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZXMgY29sbGVjdGlvbiBvciB7QGNvZGUgbnVsbH0gaWYgbm9uZSBzcGVjaWZpZWQuCisgICAgICovCisgICAgcHVibGljIENvbGxlY3Rpb248TGlzdDw/Pj4gZ2V0U3ViamVjdEFsdGVybmF0aXZlTmFtZXMoKSB7CisgICAgICAgIGlmIChzdWJqZWN0QWx0TmFtZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgQXJyYXlMaXN0PExpc3Q8Pz4+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8TGlzdDw/Pj4oKTsKKyAgICAgICAgZm9yIChpbnQgdGFnPTA7IHRhZzw5OyB0YWcrKykgeworICAgICAgICAgICAgaWYgKHN1YmplY3RBbHROYW1lc1t0YWddICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBuYW1lPTA7IG5hbWU8c3ViamVjdEFsdE5hbWVzW3RhZ10uc2l6ZSgpOyBuYW1lKyspIHsKKyAgICAgICAgICAgICAgICAgICAgTGlzdDxPYmplY3Q+IGxpc3QgPSBuZXcgQXJyYXlMaXN0PE9iamVjdD4oMik7CisgICAgICAgICAgICAgICAgICAgIGxpc3QuYWRkKHRhZyk7CisgICAgICAgICAgICAgICAgICAgIGxpc3QuYWRkKHN1YmplY3RBbHROYW1lc1t0YWddLmdldChuYW1lKSk7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQobGlzdCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY3JpdGVyaW9uIGZvciB0aGUgbmFtZSBjb25zdHJhaW50cy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgY2VydGlmaWNhdGUgbXVzdCBjb25zdHJhaW50IHN1YmplY3QgYW5kIHN1YmplY3QgYWx0ZXJuYXRpdmUgbmFtZXMKKyAgICAgKiB0aGF0IG1hdGNoIHRoZSBzcGVjaWZpZWQgbmFtZSBjb25zdHJhaW50cy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbmFtZSBjb25zdHJhaW50cyBpbiBBU04uMToKKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogTmFtZUNvbnN0cmFpbnRzIDo6PSBTRVFVRU5DRSB7CisgICAgICogICAgICAgIHBlcm1pdHRlZFN1YnRyZWVzICAgICAgIFswXSAgICAgR2VuZXJhbFN1YnRyZWVzIE9QVElPTkFMLAorICAgICAqICAgICAgICBleGNsdWRlZFN1YnRyZWVzICAgICAgICBbMV0gICAgIEdlbmVyYWxTdWJ0cmVlcyBPUFRJT05BTCB9CisgICAgICoKKyAgICAgKiBHZW5lcmFsU3VidHJlZXMgOjo9IFNFUVVFTkNFIFNJWkUgKDEuLk1BWCkgT0YgR2VuZXJhbFN1YnRyZWUKKyAgICAgKgorICAgICAqIEdlbmVyYWxTdWJ0cmVlIDo6PSBTRVFVRU5DRSB7CisgICAgICogICAgICAgIGJhc2UgICAgICAgICAgICAgICAgICAgIEdlbmVyYWxOYW1lLAorICAgICAqICAgICAgICBtaW5pbXVtICAgICAgICAgWzBdICAgICBCYXNlRGlzdGFuY2UgREVGQVVMVCAwLAorICAgICAqICAgICAgICBtYXhpbXVtICAgICAgICAgWzFdICAgICBCYXNlRGlzdGFuY2UgT1BUSU9OQUwgfQorICAgICAqCisgICAgICogQmFzZURpc3RhbmNlIDo6PSBJTlRFR0VSICgwLi5NQVgpCisgICAgICoKKyAgICAgKiBHZW5lcmFsTmFtZSA6Oj0gQ0hPSUNFIHsKKyAgICAgKiAgICAgICAgb3RoZXJOYW1lICAgICAgICAgICAgICAgICAgICAgICBbMF0gICAgIE90aGVyTmFtZSwKKyAgICAgKiAgICAgICAgcmZjODIyTmFtZSAgICAgICAgICAgICAgICAgICAgICBbMV0gICAgIElBNVN0cmluZywKKyAgICAgKiAgICAgICAgZE5TTmFtZSAgICAgICAgICAgICAgICAgICAgICAgICBbMl0gICAgIElBNVN0cmluZywKKyAgICAgKiAgICAgICAgeDQwMEFkZHJlc3MgICAgICAgICAgICAgICAgICAgICBbM10gICAgIE9SQWRkcmVzcywKKyAgICAgKiAgICAgICAgZGlyZWN0b3J5TmFtZSAgICAgICAgICAgICAgICAgICBbNF0gICAgIE5hbWUsCisgICAgICogICAgICAgIGVkaVBhcnR5TmFtZSAgICAgICAgICAgICAgICAgICAgWzVdICAgICBFRElQYXJ0eU5hbWUsCisgICAgICogICAgICAgIHVuaWZvcm1SZXNvdXJjZUlkZW50aWZpZXIgICAgICAgWzZdICAgICBJQTVTdHJpbmcsCisgICAgICogICAgICAgIGlQQWRkcmVzcyAgICAgICAgICAgICAgICAgICAgICAgWzddICAgICBPQ1RFVCBTVFJJTkcsCisgICAgICogICAgICAgIHJlZ2lzdGVyZWRJRCAgICAgICAgICAgICAgICAgICAgWzhdICAgICBPQkpFQ1QgSURFTlRJRklFUn0KKyAgICAgKgorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogQHBhcmFtIGJ5dGVzCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBjb25zdHJhaW50cyBpbiBBU04uMSBERVIgZW5jb2RlZCBmb3JtYXQsIG9yIG51bGwgdG8KKyAgICAgKiAgICAgICAgICAgIG5vdCBjaGVjayBhbnkgY29uc3RyYWludHMuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGRlY29kaW5nIHRoZSBuYW1lIGNvbnN0cmFpbnRzIGZhaWwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TmFtZUNvbnN0cmFpbnRzKGJ5dGVbXSBieXRlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5uYW1lQ29uc3RyYWludHMgPSAoYnl0ZXMgPT0gbnVsbCkKKyAgICAgICAgICAgID8gbnVsbAorICAgICAgICAgICAgOiAoTmFtZUNvbnN0cmFpbnRzKSBOYW1lQ29uc3RyYWludHMuQVNOMS5kZWNvZGUoYnl0ZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNyaXRlcmlvbiBmb3IgdGhlIG5hbWUgY29uc3RyYWludHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIGNvbnN0cmFpbnRzIG9yIHtAY29kZSBudWxsfSBpZiBub25lIHNwZWNpZmllZC4KKyAgICAgKiBAc2VlICNzZXROYW1lQ29uc3RyYWludHMKKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldE5hbWVDb25zdHJhaW50cygpIHsKKyAgICAgICAgcmV0dXJuIChuYW1lQ29uc3RyYWludHMgPT0gbnVsbCkKKyAgICAgICAgICAgID8gbnVsbAorICAgICAgICAgICAgOiBuYW1lQ29uc3RyYWludHMuZ2V0RW5jb2RlZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNyaXRlcmlvbiBmb3IgdGhlIGJhc2ljIGNvbnN0cmFpbnRzIGV4dGVuc2lvbi4KKyAgICAgKiA8cD4KKyAgICAgKiBBIHZhbHVlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB6ZXJvIGluZGljYXRlcyB0aGF0IGEgY2VydGlmaWNhdGUgbXVzdAorICAgICAqIGluY2x1ZGUgYSBiYXNpYyBjb25zdHJhaW50cyBleHRlbnNpb24gd2l0aCBhIHBhdGggbGVuZ3RoIG9mIGEgbGVhc3QgdGhhdAorICAgICAqIHZhbHVlLiBBIHZhbHVlIG9mIHtAY29kZSAtMn0gaW5kaWNhdGVzIHRoYXQgb25seSBlbmQtZW50aXR5IGNlcnRpZmljYXRlcworICAgICAqIGFyZSBhY2NlcHRlZC4gQSB2YWx1ZSBvZiB7QGNvZGUgLTF9IGluZGljYXRlcyB0aGF0IG5vIGNoZWNrIGlzIGRvbmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGF0aExlbgorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHNwZWNpZnlpbmcgdGhlIGNyaXRlcmlvbi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBwYXRoTGVufSBpcyBsZXNzIHRoYW4ge0Bjb2RlIC0yfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCYXNpY0NvbnN0cmFpbnRzKGludCBwYXRoTGVuKSB7CisgICAgICAgIGlmIChwYXRoTGVuIDwgLTIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInBhdGhMZW4gPCAtMiIpOworICAgICAgICB9CisgICAgICAgIHRoaXMucGF0aExlbiA9IHBhdGhMZW47CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3JpdGVyaW9uIGZvciB0aGUgYmFzaWMgY29uc3RyYWludHMgZXh0ZW5zaW9uLgorICAgICAqIDxwPgorICAgICAqIEEgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHplcm8gaW5kaWNhdGVzIHRoYXQgYSBjZXJ0aWZpY2F0ZSBtdXN0CisgICAgICogaW5jbHVkZSBhIGJhc2ljIGNvbnN0cmFpbnRzIGV4dGVuc2lvbiB3aXRoIGEgcGF0aCBsZW5ndGggb2YgYSBsZWFzdCB0aGF0CisgICAgICogdmFsdWUuIEEgdmFsdWUgb2Yge0Bjb2RlIC0yfSBpbmRpY2F0ZXMgdGhhdCBvbmx5IGVuZC1lbnRpdHkgY2VydGlmaWNhdGVzCisgICAgICogYXJlIGFjY2VwdGVkLiBBIHZhbHVlIG9mIHtAY29kZSAtMX0gaW5kaWNhdGVzIHRoYXQgbm8gY2hlY2sgaXMgZG9uZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBjcml0ZXJpb24uCisgICAgICovCisgICAgcHVibGljIGludCBnZXRCYXNpY0NvbnN0cmFpbnRzKCkgeworICAgICAgICByZXR1cm4gcGF0aExlbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjcml0ZXJpb24gZm9yIHRoZSBwb2xpY3kgY29uc3RyYWludC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgY2VydGlmaWNhdGUgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBvZiB0aGUgc3BlY2lmaWVkIGNlcnRpZmljYXRlCisgICAgICogcG9saWN5IGV4dGVuc2lvbnMuIEZvciBhbiBlbXB0eSBzZXQgdGhlIGNlcnRpZmljYXRlIG11c3QgaGF2ZSBhdCBsZWFzdAorICAgICAqIHNvbWUgcG9saWNpZXMgaW4gaXRzIHBvbGljeSBleHRlbnNpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcG9saWNpZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZSBwb2xpY3kgT0lEcywgYW4gZW1wdHkgc2V0LCBvciB7QGNvZGUgbnVsbH0gdG8KKyAgICAgKiAgICAgICAgICAgIG5vdCBwZXJmb3JtIHRoaXMgY2hlY2suCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHBhcnNpbmcgdGhlIHNwZWNpZmllZCBPSURzIGZhaWxzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBvbGljeShTZXQ8U3RyaW5nPiBwb2xpY2llcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBvbGljaWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMucG9saWNpZXMgPSBudWxsOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIEhhc2hTZXQ8U3RyaW5nPiBwb2xzID0gbmV3IEhhc2hTZXQ8U3RyaW5nPihwb2xpY2llcy5zaXplKCkpOworICAgICAgICBmb3IgKFN0cmluZyBjZXJ0UG9saWN5SWQgOiBwb2xpY2llcykgeworICAgICAgICAgICAgY2hlY2tPSUQoY2VydFBvbGljeUlkKTsKKyAgICAgICAgICAgIHBvbHMuYWRkKGNlcnRQb2xpY3lJZCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5wb2xpY2llcyA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNldChwb2xzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjcml0ZXJpb24gZm9yIHRoZSBwb2xpY3kgY29uc3RyYWludC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgY2VydGlmaWNhdGUgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBvZiB0aGUgY2VydGlmaWNhdGUgcG9saWN5CisgICAgICogZXh0ZW5zaW9ucy4gRm9yIGFuIGVtcHR5IHNldCB0aGUgY2VydGlmaWNhdGUgbXVzdCBoYXZlIGF0IGxlYXN0IHNvbWUKKyAgICAgKiBwb2xpY2llcyBpbiBpdHMgcG9saWN5IGV4dGVuc2lvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRlIHBvbGljeSBPSURzLCBhbiBlbXB0eSBzZXQsIG9yIHtAY29kZSBudWxsfSBpZiBub3QKKyAgICAgKiAgICAgICAgIHRvIGJlIGNoZWNrZWQuCisgICAgICovCisgICAgcHVibGljIFNldDxTdHJpbmc+IGdldFBvbGljeSgpIHsKKyAgICAgICAgcmV0dXJuIHBvbGljaWVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSB7QGxpdGVyYWwgInBhdGhUb05hbWUifSB0byB0aGUgcmVzcGVjdGl2ZSBjcml0ZXJpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHR5cGUgb2YgdGhlIG5hbWUuCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIGluIHN0cmluZyBmb3JtYXQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHBhcnNpbmcgZmFpbHMuCisgICAgICogQHNlZSAjc2V0UGF0aFRvTmFtZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRQYXRoVG9OYW1lKGludCB0eXBlLCBTdHJpbmcgbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgR2VuZXJhbE5hbWUgcGF0aF9uYW1lID0gbmV3IEdlbmVyYWxOYW1lKHR5cGUsIG5hbWUpOworICAgICAgICAvLyBjcmVhdGUgb25seSBpZiB0aGVyZSB3YXMgbm90IGFueSBlcnJvcnMKKyAgICAgICAgaWYgKHBhdGhUb05hbWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHBhdGhUb05hbWVzID0gbmV3IEFycmF5TGlzdDxHZW5lcmFsTmFtZT4oKTsKKyAgICAgICAgfQorICAgICAgICBwYXRoVG9OYW1lcy5hZGQocGF0aF9uYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjcml0ZXJpb24gZm9yIHRoZSBwYXRoVG9OYW1lcyBjb25zdHJhaW50LgorICAgICAqIDxwPgorICAgICAqIFRoaXMgYWxsb3dzIHRvIHNwZWNpZnkgdGhlIGNvbXBsZXRlIHNldCBvZiBuYW1lcywgYSBjZXJ0aWZpY2F0ZSdzIG5hbWUKKyAgICAgKiBjb25zdHJhaW50cyBtdXN0IHBlcm1pdC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgc3BlY2lmaWVkIHBhcmFtZXRlciB7QGNvZGUgbmFtZXN9IGlzIGEgY29sbGVjdGlvbiB3aXRoIGFuIGVudHJ5IGZvcgorICAgICAqIGVhY2ggbmFtZSB0byBiZSBpbmNsdWRlZCBpbiB0aGUgY3JpdGVyaW9uLiBUaGUgbmFtZSBpcyBzcGVjaWZpZWQgYXMgYQorICAgICAqIHtAY29kZSBMaXN0fSwgdGhlIGZpcnN0IGVudHJ5IG11c3QgYmUgYW4ge0Bjb2RlIEludGVnZXJ9IHNwZWNpZnlpbmcgdGhlCisgICAgICogbmFtZSB0eXBlICgwLTgpLCB0aGUgc2Vjb25kIGVudHJ5IG11c3QgYmUgYSB7QGNvZGUgU3RyaW5nfSBvciBhIGJ5dGUKKyAgICAgKiBhcnJheSBzcGVjaWZ5aW5nIHRoZSBuYW1lIChpbiBzdHJpbmcgb3IgQVNOLjEgREVSIGVuY29kZWQgZm9ybSkKKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lcworICAgICAqICAgICAgICAgICAgdGhlIG5hbWVzIGNvbGxlY3Rpb24gb3Ige0Bjb2RlIG51bGx9IHRvIG5vdCBwZXJmb3JtIHRoaXMKKyAgICAgKiAgICAgICAgICAgIGNoZWNrLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBkZWNvZGluZyBmYWlscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQYXRoVG9OYW1lcyhDb2xsZWN0aW9uPExpc3Q8Pz4+IG5hbWVzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBwYXRoVG9OYW1lcyA9IG51bGw7CisgICAgICAgIGlmICgobmFtZXMgPT0gbnVsbCkgfHwgKG5hbWVzLnNpemUoKSA9PSAwKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGZvciAoTGlzdDw/PiBuYW1lIDogbmFtZXMpIHsKKyAgICAgICAgICAgIGludCB0YWcgPSAoSW50ZWdlcikgbmFtZS5nZXQoMCk7CisgICAgICAgICAgICBPYmplY3QgdmFsdWUgPSBuYW1lLmdldCgxKTsKKyAgICAgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykgeworICAgICAgICAgICAgICAgIGFkZFBhdGhUb05hbWUodGFnLCAoU3RyaW5nKSB2YWx1ZSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgYnl0ZVtdKSB7CisgICAgICAgICAgICAgICAgYWRkUGF0aFRvTmFtZSh0YWcsIChieXRlW10pIHZhbHVlKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJuYW1lIG5laXRoZXIgYSBTdHJpbmcgbm9yIGEgYnl0ZVtdIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGEge0BsaXRlcmFsICJwYXRoVG9OYW1lIn0gdG8gdGhlIHJlc3BlY3RpdmUgY3JpdGVyaW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSBuYW1lCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIGluIEFTTi4xIERFUiBlbmNvZGVkIGZvcm0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGRlY29kaW5nIGZhaWxzLgorICAgICAqIEBzZWUgI3NldFBhdGhUb05hbWVzCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkUGF0aFRvTmFtZShpbnQgdHlwZSwgYnl0ZVtdIG5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEdlbmVyYWxOYW1lIHBhdGhfbmFtZT0gbmV3IEdlbmVyYWxOYW1lKHR5cGUsIG5hbWUpOworICAgICAgICAvLyBjcmVhdGUgb25seSBpZiB0aGVyZSB3YXMgbm90IGFueSBlcnJvcnMKKyAgICAgICAgaWYgKHBhdGhUb05hbWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHBhdGhUb05hbWVzID0gbmV3IEFycmF5TGlzdDxHZW5lcmFsTmFtZT4oKTsKKyAgICAgICAgfQorICAgICAgICBwYXRoVG9OYW1lcy5hZGQocGF0aF9uYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjcml0ZXJpb24gZm9yIHRoZSBwYXRoVG9OYW1lcyBjb25zdHJhaW50LgorICAgICAqIDxwPgorICAgICAqIFRoZSBjb25zdHJhaW50IGlzIGEgY29sbGVjdGlvbiB3aXRoIGFuIGVudHJ5IGZvciBlYWNoIG5hbWUgdG8gYmUgaW5jbHVkZWQKKyAgICAgKiBpbiB0aGUgY3JpdGVyaW9uLiBUaGUgbmFtZSBpcyBzcGVjaWZpZWQgYXMgYSB7QGNvZGUgTGlzdH0sIHRoZSBmaXJzdAorICAgICAqIGVudHJ5IGlzIGFuIHtAY29kZSBJbnRlZ2VyfSBzcGVjaWZ5aW5nIHRoZSBuYW1lIHR5cGUgKDAtOCksIHRoZSBzZWNvbmQKKyAgICAgKiBlbnRyeSBpcyBhIGJ5dGUgYXJyYXkgc3BlY2lmeWluZyB0aGUgbmFtZSBpbiBBU04uMSBERVIgZW5jb2RlZCBmb3JtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcGF0aFRvTmFtZXMgY29uc3RyYWludCBvciB7QGNvZGUgbnVsbH0gaWYgbm9uZSBzcGVjaWZpZWQuCisgICAgICovCisgICAgcHVibGljIENvbGxlY3Rpb248TGlzdDw/Pj4gZ2V0UGF0aFRvTmFtZXMoKSB7CisgICAgICAgIGlmIChwYXRoVG9OYW1lcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBDb2xsZWN0aW9uPExpc3Q8Pz4+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8TGlzdDw/Pj4oKTsKKyAgICAgICAgZm9yIChHZW5lcmFsTmFtZSBuYW1lIDogcGF0aFRvTmFtZXMpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hZGQobmFtZS5nZXRBc0xpc3QoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMge0Bjb2RlIFg1MDlDZXJ0U2VsZWN0b3J9CisgICAgICogaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMge0Bjb2RlIFg1MDlDZXJ0U2VsZWN0b3J9CisgICAgICogICAgICAgICBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAvLyBGb3IgY29udmVuaWVudCByZWFkaW5nIG9mIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24KKyAgICAgICAgLy8gYWxsIG9mIHRoZSBmaWVsZHMgbmFtZWQgYWNjb3JkaW5nIHRvIHRoZSByZmMgMzI4MAorICAgICAgICAvLyAoaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpLgorCisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZCgiWDUwOUNlcnRTZWxlY3RvcjogXG5bIik7CisgICAgICAgIGlmICh0aGlzLmNlcnRpZmljYXRlRXF1YWxzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIlxuICBjZXJ0aWZpY2F0ZUVxdWFsczogIikuYXBwZW5kKGNlcnRpZmljYXRlRXF1YWxzKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodGhpcy5zZXJpYWxOdW1iZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiXG4gIHNlcmlhbE51bWJlcjogIikuYXBwZW5kKHNlcmlhbE51bWJlcik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRoaXMuaXNzdWVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIlxuICBpc3N1ZXI6ICIpLmFwcGVuZChpc3N1ZXIpOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLnN1YmplY3QgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiXG4gIHN1YmplY3Q6ICIpLmFwcGVuZChzdWJqZWN0KTsKKyAgICAgICAgfQorICAgICAgICBpZiAodGhpcy5zdWJqZWN0S2V5SWRlbnRpZmllciAhPSBudWxsKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJcbiAgc3ViamVjdEtleUlkZW50aWZpZXI6ICIpCisgICAgICAgICAgICAgICAgICAgIC5hcHBlbmQoQXJyYXkuZ2V0Qnl0ZXNBc1N0cmluZyhzdWJqZWN0S2V5SWRlbnRpZmllcikpOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLmF1dGhvcml0eUtleUlkZW50aWZpZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiXG4gIGF1dGhvcml0eUtleUlkZW50aWZpZXI6ICIpCisgICAgICAgICAgICAgICAgICAgIC5hcHBlbmQoQXJyYXkuZ2V0Qnl0ZXNBc1N0cmluZyhhdXRob3JpdHlLZXlJZGVudGlmaWVyKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRoaXMuY2VydGlmaWNhdGVWYWxpZCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJcbiAgY2VydGlmaWNhdGVWYWxpZDogIikuYXBwZW5kKGNlcnRpZmljYXRlVmFsaWQpOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLnN1YmplY3RQdWJsaWNLZXlBbGdJRCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJcbiAgc3ViamVjdFB1YmxpY0tleUFsZ0lEOiAiKS5hcHBlbmQoc3ViamVjdFB1YmxpY0tleUFsZ0lEKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodGhpcy5wcml2YXRlS2V5VmFsaWQgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiXG4gIHByaXZhdGVLZXlWYWxpZDogIikuYXBwZW5kKHByaXZhdGVLZXlWYWxpZCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRoaXMuc3ViamVjdFB1YmxpY0tleSAhPSBudWxsKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJcbiAgc3ViamVjdFB1YmxpY0tleTogIikKKyAgICAgICAgICAgICAgICAgICAgLmFwcGVuZChBcnJheS5nZXRCeXRlc0FzU3RyaW5nKHN1YmplY3RQdWJsaWNLZXkpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodGhpcy5rZXlVc2FnZSAhPSBudWxsKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJcbiAga2V5VXNhZ2U6IFxuICBbIik7CisgICAgICAgICAgICBTdHJpbmdbXSBrdU5hbWVzID0gbmV3IFN0cmluZ1tdIHsKKyAgICAgICAgICAgICAgICAiZGlnaXRhbFNpZ25hdHVyZSIsICJub25SZXB1ZGlhdGlvbiIsICJrZXlFbmNpcGhlcm1lbnQiLAorICAgICAgICAgICAgICAgICJkYXRhRW5jaXBoZXJtZW50IiwgImtleUFncmVlbWVudCIsICJrZXlDZXJ0U2lnbiIsICJjUkxTaWduIiwKKyAgICAgICAgICAgICAgICAiZW5jaXBoZXJPbmx5IiwgImRlY2lwaGVyT25seSIKKyAgICAgICAgICAgIH07CisgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8OTsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGtleVVzYWdlW2ldKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIlxuICAgICIpLmFwcGVuZChrdU5hbWVzW2ldKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJcbiAgXSIpOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLmV4dGVuZGVkS2V5VXNhZ2UgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiXG4gIGV4dGVuZGVkS2V5VXNhZ2U6ICIpLmFwcGVuZChleHRlbmRlZEtleVVzYWdlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIHJlc3VsdC5hcHBlbmQoIlxuICBtYXRjaEFsbE5hbWVzOiAiKS5hcHBlbmQobWF0Y2hBbGxOYW1lcyk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQoIlxuICBwYXRoTGVuOiAiKS5hcHBlbmQocGF0aExlbik7CisgICAgICAgIGlmICh0aGlzLnN1YmplY3RBbHROYW1lcyAhPSBudWxsKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJcbiAgc3ViamVjdEFsdE5hbWVzOiAgXG4gIFsiKTsKKyAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTw5OyBpKyspIHsKKyAgICAgICAgICAgICAgICBMaXN0PEdlbmVyYWxOYW1lPiBuYW1lcyA9IHN1YmplY3RBbHROYW1lc1tpXTsKKyAgICAgICAgICAgICAgICBpZiAobmFtZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpbnQgc2l6ZSA9IG5hbWVzLnNpemUoKTsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChHZW5lcmFsTmFtZSBnZW5lcmFsTmFtZSA6IG5hbWVzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJcbiAgICAiKS5hcHBlbmQoZ2VuZXJhbE5hbWUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJcbiAgXSIpOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLm5hbWVDb25zdHJhaW50cyAhPSBudWxsKSB7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRoaXMucG9saWNpZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiXG4gIHBvbGljaWVzOiAiKS5hcHBlbmQocG9saWNpZXMudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRoaXMucGF0aFRvTmFtZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiXG4gIHBhdGhUb05hbWVzOiAgXG4gIFsiKTsKKyAgICAgICAgICAgIGZvciAoR2VuZXJhbE5hbWUgZ2VuZXJhbE5hbWUgOiBwYXRoVG9OYW1lcykgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIlxuICAgICIpLmFwcGVuZChnZW5lcmFsTmFtZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXN1bHQuYXBwZW5kKCJcbl0iKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgIH0KKworICAgIHByaXZhdGUgYnl0ZVtdIGdldEV4dGVuc2lvblZhbHVlKFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0LCBTdHJpbmcgb2lkKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBieXRlW10gYnl0ZXMgPSBjZXJ0LmdldEV4dGVuc2lvblZhbHVlKG9pZCk7CisgICAgICAgICAgICBpZiAoYnl0ZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIChieXRlW10pIEFTTjFPY3RldFN0cmluZy5nZXRJbnN0YW5jZSgpLmRlY29kZShieXRlcyk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY2VydGlmaWNhdGUgbWF0Y2hlcyBhbGwgdGhlIGNyaXRlcmlhCisgICAgICogY29sbGVjdGVkIGluIHRoaXMgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2VydGlmaWNhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZSB0byBjaGVjay4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgY2VydGlmaWNhdGUgbWF0Y2hlcyBhbGwgdGhlIGNyaXRlcmlhLAorICAgICAqICAgICAgICAgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbWF0Y2goQ2VydGlmaWNhdGUgY2VydGlmaWNhdGUpIHsKKyAgICAgICAgaWYgKCEgKGNlcnRpZmljYXRlIGluc3RhbmNlb2YgWDUwOUNlcnRpZmljYXRlKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIGNlcnQgPSAoWDUwOUNlcnRpZmljYXRlKSBjZXJ0aWZpY2F0ZTsKKyAgICAgICAgaWYgKChjZXJ0aWZpY2F0ZUVxdWFscyAhPSBudWxsKSAmJgorICAgICAgICAgICAgIWNlcnRpZmljYXRlRXF1YWxzLmVxdWFscyhjZXJ0KSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmICgoc2VyaWFsTnVtYmVyICE9IG51bGwpICYmCisgICAgICAgICAgICAhc2VyaWFsTnVtYmVyLmVxdWFscyhjZXJ0LmdldFNlcmlhbE51bWJlcigpKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmICgoaXNzdWVyICE9IG51bGwpICYmCisgICAgICAgICAgICAhaXNzdWVyLmVxdWFscyhjZXJ0LmdldElzc3Vlclg1MDBQcmluY2lwYWwoKSkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoKHN1YmplY3QgIT0gbnVsbCkgJiYKKyAgICAgICAgICAgICFzdWJqZWN0LmVxdWFscyhjZXJ0LmdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCkpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChzdWJqZWN0S2V5SWRlbnRpZmllciAhPSBudWxsKSAmJgorICAgICAgICAgICAgIUFycmF5cy5lcXVhbHMoc3ViamVjdEtleUlkZW50aWZpZXIsCisgICAgICAgICAgICAvLyBIZXJlIGFuZCBsYXRlciBhbGwgb2YgdGhlIGV4dGVuc2lvbiBPSURzCisgICAgICAgICAgICAvLyBhcmUgdGFrZW4gZnJvbSByZmMgMzI4MCAoaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRFeHRlbnNpb25WYWx1ZShjZXJ0LCAiMi41LjI5LjE0IikpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChhdXRob3JpdHlLZXlJZGVudGlmaWVyICE9IG51bGwpICYmCisgICAgICAgICAgICAhQXJyYXlzLmVxdWFscyhhdXRob3JpdHlLZXlJZGVudGlmaWVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0RXh0ZW5zaW9uVmFsdWUoY2VydCwgIjIuNS4yOS4zNSIpKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmIChjZXJ0aWZpY2F0ZVZhbGlkICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2VydC5jaGVja1ZhbGlkaXR5KGNlcnRpZmljYXRlVmFsaWQpOworICAgICAgICAgICAgfSBjYXRjaChDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0gY2F0Y2goQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChwcml2YXRlS2V5VmFsaWQgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBieXRlW10gYnl0ZXMgPSBnZXRFeHRlbnNpb25WYWx1ZShjZXJ0LCAiMi41LjI5LjE2Iik7CisgICAgICAgICAgICAgICAgaWYgKGJ5dGVzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBQcml2YXRlS2V5VXNhZ2VQZXJpb2QgcGt1cCA9IChQcml2YXRlS2V5VXNhZ2VQZXJpb2QpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcml2YXRlS2V5VXNhZ2VQZXJpb2QuQVNOMS5kZWNvZGUoYnl0ZXMpOworICAgICAgICAgICAgICAgIERhdGUgbm90QmVmb3JlID0gcGt1cC5nZXROb3RCZWZvcmUoKTsKKyAgICAgICAgICAgICAgICBEYXRlIG5vdEFmdGVyID0gcGt1cC5nZXROb3RBZnRlcigpOworICAgICAgICAgICAgICAgIGlmICgobm90QmVmb3JlID09IG51bGwpICYmIChub3RBZnRlciA9PSBudWxsKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICgobm90QmVmb3JlICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgICYmIG5vdEJlZm9yZS5jb21wYXJlVG8ocHJpdmF0ZUtleVZhbGlkKSA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoKG5vdEFmdGVyICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgICYmIG5vdEFmdGVyLmNvbXBhcmVUbyhwcml2YXRlS2V5VmFsaWQpIDwgMCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoc3ViamVjdFB1YmxpY0tleUFsZ0lEICAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGJ5dGVbXSBlbmNvZGluZyA9IGNlcnQuZ2V0UHVibGljS2V5KCkuZ2V0RW5jb2RlZCgpOworICAgICAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIgYWkgPSAoKFN1YmplY3RQdWJsaWNLZXlJbmZvKQorICAgICAgICAgICAgICAgICAgICAgICAgU3ViamVjdFB1YmxpY0tleUluZm8uQVNOMS5kZWNvZGUoZW5jb2RpbmcpKQorICAgICAgICAgICAgICAgICAgICAgICAgLmdldEFsZ29yaXRobUlkZW50aWZpZXIoKTsKKyAgICAgICAgICAgICAgICBpZiAoIXN1YmplY3RQdWJsaWNLZXlBbGdJRC5lcXVhbHMoYWkuZ2V0QWxnb3JpdGhtKCkpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHN1YmplY3RQdWJsaWNLZXkgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKCFBcnJheXMuZXF1YWxzKHN1YmplY3RQdWJsaWNLZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VydC5nZXRQdWJsaWNLZXkoKS5nZXRFbmNvZGVkKCkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChrZXlVc2FnZSAhPSBudWxsKSB7CisgICAgICAgICAgICBib29sZWFuW10ga3UgPSBjZXJ0LmdldEtleVVzYWdlKCk7CisgICAgICAgICAgICBpZiAoa3UgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgICAgICAgICBpbnQgbWluX2xlbmd0aCA9IChrdS5sZW5ndGggPCBrZXlVc2FnZS5sZW5ndGgpID8ga3UubGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICA6IGtleVVzYWdlLmxlbmd0aDsKKyAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IG1pbl9sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBpZiAoa2V5VXNhZ2VbaV0gJiYgIWt1W2ldKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgc3BlY2lmaWVkIGtleVVzYWdlIGFsbG93cywKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1dCBjZXJ0aWZpY2F0ZSBkb2VzIG5vdC4KKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmb3IgKDsgaTxrZXlVc2FnZS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBpZiAoa2V5VXNhZ2VbaV0pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoZXh0ZW5kZWRLZXlVc2FnZSAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIExpc3Qga2V5VXNhZ2UgPSBjZXJ0LmdldEV4dGVuZGVkS2V5VXNhZ2UoKTsKKyAgICAgICAgICAgICAgICBpZiAoa2V5VXNhZ2UgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoIWtleVVzYWdlLmNvbnRhaW5zQWxsKGV4dGVuZGVkS2V5VXNhZ2UpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAocGF0aExlbiAhPSAtMSkgeworICAgICAgICAgICAgaW50IHBfbGVuID0gY2VydC5nZXRCYXNpY0NvbnN0cmFpbnRzKCk7CisgICAgICAgICAgICBpZiAoKHBhdGhMZW4gPCAwKSAmJiAocF9sZW4gPj0gMCkpIHsKKyAgICAgICAgICAgICAgICAvLyBuZWVkIGVuZC1lbnRpdHkgYnV0IGdvdCBDQQorICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICgocGF0aExlbiA+IDApICYmIChwYXRoTGVuID4gcF9sZW4pKSB7CisgICAgICAgICAgICAgICAgLy8gYWxsb3dlZCBfcGF0aExlbiBpcyBzbWFsbAorICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoc3ViamVjdEFsdE5hbWVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIFBBU1NFRDoKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGJ5dGVzID0gZ2V0RXh0ZW5zaW9uVmFsdWUoY2VydCwgIjIuNS4yOS4xNyIpOworICAgICAgICAgICAgICAgIGlmIChieXRlcyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgTGlzdDxHZW5lcmFsTmFtZT4gc2FucyA9ICgoR2VuZXJhbE5hbWVzKSBHZW5lcmFsTmFtZXMuQVNOMS5kZWNvZGUoYnl0ZXMpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXROYW1lcygpOworICAgICAgICAgICAgICAgIGlmICgoc2FucyA9PSBudWxsKSB8fCAoc2Fucy5zaXplKCkgPT0gMCkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBib29sZWFuW11bXSBtYXAgPSBuZXcgYm9vbGVhbls5XVtdOworICAgICAgICAgICAgICAgIC8vIGluaXRpYWxpemUgdGhlIGNoZWNrIG1hcAorICAgICAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTw5OyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgbWFwW2ldID0gKHN1YmplY3RBbHROYW1lc1tpXSA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gRW1wdHlBcnJheS5CT09MRUFOIDogbmV3IGJvb2xlYW5bc3ViamVjdEFsdE5hbWVzW2ldLnNpemUoKV07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZvciAoR2VuZXJhbE5hbWUgbmFtZSA6IHNhbnMpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHRhZyA9IG5hbWUuZ2V0VGFnKCk7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFwW3RhZ10ubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdWJqZWN0QWx0TmFtZXNbdGFnXS5nZXQoaSkuZXF1YWxzKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRjaEFsbE5hbWVzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIFBBU1NFRDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwW3RhZ11baV0gPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICghbWF0Y2hBbGxOYW1lcykgeworICAgICAgICAgICAgICAgICAgICAvLyB0aGVyZSB3YXMgbm90IGFueSBtYXRjaAorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIGVsc2UgY2hlY2sgdGhlIG1hcAorICAgICAgICAgICAgICAgIGZvciAoaW50IHRhZz0wOyB0YWc8OTsgdGFnKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgbmFtZT0wOyBuYW1lPG1hcFt0YWddLmxlbmd0aDsgbmFtZSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1hcFt0YWddW25hbWVdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChuYW1lQ29uc3RyYWludHMgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKCFuYW1lQ29uc3RyYWludHMuaXNBY2NlcHRhYmxlKGNlcnQpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChwb2xpY2llcyAhPSBudWxsKSB7CisgICAgICAgICAgICBieXRlW10gYnl0ZXMgPSBnZXRFeHRlbnNpb25WYWx1ZShjZXJ0LCAiMi41LjI5LjMyIik7CisgICAgICAgICAgICBpZiAoYnl0ZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChwb2xpY2llcy5zaXplKCkgPT0gMCkgeworICAgICAgICAgICAgICAgIC8vIGlmIGNlcnRpZmljYXRlIGhhcyBzdWNoIGV4dGVuc2lvbiB0aGFuIGl0IGhhcyBhdCBsZWFzdAorICAgICAgICAgICAgICAgIC8vIG9uZSBwb2xpY3kgaW4gaXQuCisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQQVNTRUQ6CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIExpc3Q8UG9saWN5SW5mb3JtYXRpb24+IHBvbGljeUluZm9ybWF0aW9ucworICAgICAgICAgICAgICAgICAgICAgICAgPSAoKENlcnRpZmljYXRlUG9saWNpZXMpIENlcnRpZmljYXRlUG9saWNpZXMuQVNOMS5kZWNvZGUoYnl0ZXMpKQorICAgICAgICAgICAgICAgICAgICAgICAgLmdldFBvbGljeUluZm9ybWF0aW9ucygpOworICAgICAgICAgICAgICAgIGZvciAoUG9saWN5SW5mb3JtYXRpb24gcG9saWN5SW5mb3JtYXRpb24gOiBwb2xpY3lJbmZvcm1hdGlvbnMpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHBvbGljaWVzLmNvbnRhaW5zKHBvbGljeUluZm9ybWF0aW9uLmdldFBvbGljeUlkZW50aWZpZXIoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIFBBU1NFRDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gdGhlIGV4dGVuc2lvbiBpcyBpbnZhbGlkCisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChwYXRoVG9OYW1lcyAhPSBudWxsKSB7CisgICAgICAgICAgICBieXRlW10gYnl0ZXMgPSBnZXRFeHRlbnNpb25WYWx1ZShjZXJ0LCAiMi41LjI5LjMwIik7CisgICAgICAgICAgICBpZiAoYnl0ZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIE5hbWVDb25zdHJhaW50cyBuYW1lQ29uc3RyYWludHM7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgbmFtZUNvbnN0cmFpbnRzID0KKyAgICAgICAgICAgICAgICAgICAgICAgIChOYW1lQ29uc3RyYWludHMpIE5hbWVDb25zdHJhaW50cy5BU04xLmRlY29kZShieXRlcyk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAvLyB0aGUgZXh0ZW5zaW9uIGlzIGludmFsaWQ7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKCFuYW1lQ29uc3RyYWludHMuaXNBY2NlcHRhYmxlKHBhdGhUb05hbWVzKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb25lcyB0aGlzIHtAY29kZSBYNTA5Q2VydFNlbGVjdG9yfSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNsb25lZCBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHJlc3VsdDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzdWx0ID0gKFg1MDlDZXJ0U2VsZWN0b3IpIHN1cGVyLmNsb25lKCk7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHRoaXMuc3ViamVjdEtleUlkZW50aWZpZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LnN1YmplY3RLZXlJZGVudGlmaWVyID0KKyAgICAgICAgICAgICAgICBuZXcgYnl0ZVt0aGlzLnN1YmplY3RLZXlJZGVudGlmaWVyLmxlbmd0aF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRoaXMuc3ViamVjdEtleUlkZW50aWZpZXIsIDAsCisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5zdWJqZWN0S2V5SWRlbnRpZmllciwgMCwKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5zdWJqZWN0S2V5SWRlbnRpZmllci5sZW5ndGgpOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLmF1dGhvcml0eUtleUlkZW50aWZpZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LmF1dGhvcml0eUtleUlkZW50aWZpZXIgPQorICAgICAgICAgICAgICAgIG5ldyBieXRlW3RoaXMuYXV0aG9yaXR5S2V5SWRlbnRpZmllci5sZW5ndGhdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0aGlzLmF1dGhvcml0eUtleUlkZW50aWZpZXIsIDAsCisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hdXRob3JpdHlLZXlJZGVudGlmaWVyLCAwLAorICAgICAgICAgICAgICAgICAgICB0aGlzLmF1dGhvcml0eUtleUlkZW50aWZpZXIubGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodGhpcy5zdWJqZWN0UHVibGljS2V5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlc3VsdC5zdWJqZWN0UHVibGljS2V5ID0gbmV3IGJ5dGVbdGhpcy5zdWJqZWN0UHVibGljS2V5Lmxlbmd0aF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRoaXMuc3ViamVjdFB1YmxpY0tleSwgMCwgcmVzdWx0LnN1YmplY3RQdWJsaWNLZXksCisgICAgICAgICAgICAgICAgICAgIDAsIHRoaXMuc3ViamVjdFB1YmxpY0tleS5sZW5ndGgpOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLmtleVVzYWdlICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlc3VsdC5rZXlVc2FnZSA9IG5ldyBib29sZWFuW3RoaXMua2V5VXNhZ2UubGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodGhpcy5rZXlVc2FnZSwgMCwgcmVzdWx0LmtleVVzYWdlLCAwLAorICAgICAgICAgICAgICAgICAgICB0aGlzLmtleVVzYWdlLmxlbmd0aCk7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0LmV4dGVuZGVkS2V5VXNhZ2UgPSAodGhpcy5leHRlbmRlZEtleVVzYWdlID09IG51bGwpCisgICAgICAgICAgICA/IG51bGwKKyAgICAgICAgICAgIDogbmV3IEhhc2hTZXQ8U3RyaW5nPih0aGlzLmV4dGVuZGVkS2V5VXNhZ2UpOworICAgICAgICBpZiAodGhpcy5zdWJqZWN0QWx0TmFtZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LnN1YmplY3RBbHROYW1lcyA9IG5ldyBBcnJheUxpc3RbOV07CisgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8OTsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKHRoaXMuc3ViamVjdEFsdE5hbWVzW2ldICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnN1YmplY3RBbHROYW1lc1tpXSA9CisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQXJyYXlMaXN0PEdlbmVyYWxOYW1lPih0aGlzLnN1YmplY3RBbHROYW1lc1tpXSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJlc3VsdC5wb2xpY2llcyA9ICh0aGlzLnBvbGljaWVzID09IG51bGwpID8gbnVsbCA6IG5ldyBIYXNoU2V0PFN0cmluZz4odGhpcy5wb2xpY2llcyk7CisgICAgICAgIHJlc3VsdC5wYXRoVG9OYW1lcyA9ICh0aGlzLnBhdGhUb05hbWVzID09IG51bGwpCisgICAgICAgICAgICA/IG51bGwKKyAgICAgICAgICAgIDogbmV3IEFycmF5TGlzdDxHZW5lcmFsTmFtZT4odGhpcy5wYXRoVG9OYW1lcyk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9YNTA5Q2VydGlmaWNhdGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvWDUwOUNlcnRpZmljYXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTA3MzdkNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2NlcnQvWDUwOUNlcnRpZmljYXRlLmphdmEKQEAgLTAsMCArMSw0NDAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbDsKKworLyoqCisgKiBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBYLjUwOSBjZXJ0aWZpY2F0ZXMuCisgKiA8cD4KKyAqIFRoaXMgcmVwcmVzZW50cyBhIHN0YW5kYXJkIHdheSBmb3IgYWNjZXNzaW5nIHRoZSBhdHRyaWJ1dGVzIG9mIFguNTA5CisgKiBjZXJ0aWZpY2F0ZXMuCisgKiA8cD4KKyAqIFRoZSBiYXNpYyBYLjUwOSB2MyBmb3JtYXQgZGVzY3JpYmVkIGluIEFTTi4xOgorICoKKyAqIDxwcmU+CisgKiBDZXJ0aWZpY2F0ZSAgOjo9ICBTRVFVRU5DRSAgeworICogICAgIHRic0NlcnRpZmljYXRlICAgICAgIFRCU0NlcnRpZmljYXRlLAorICogICAgIHNpZ25hdHVyZUFsZ29yaXRobSAgIEFsZ29yaXRobUlkZW50aWZpZXIsCisgKiAgICAgc2lnbmF0dXJlICAgICAgICAgICAgQklUIFNUUklORyAgfQorICoKKyAqIFRCU0NlcnRpZmljYXRlICA6Oj0gIFNFUVVFTkNFICB7CisgKiAgICAgIHZlcnNpb24gICAgICAgICBbMF0gIEVYUExJQ0lUIFZlcnNpb24gREVGQVVMVCB2MSwKKyAqICAgICAgc2VyaWFsTnVtYmVyICAgICAgICAgQ2VydGlmaWNhdGVTZXJpYWxOdW1iZXIsCisgKiAgICAgIHNpZ25hdHVyZSAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIsCisgKiAgICAgIGlzc3VlciAgICAgICAgICAgICAgIE5hbWUsCisgKiAgICAgIHZhbGlkaXR5ICAgICAgICAgICAgIFZhbGlkaXR5LAorICogICAgICBzdWJqZWN0ICAgICAgICAgICAgICBOYW1lLAorICogICAgICBzdWJqZWN0UHVibGljS2V5SW5mbyBTdWJqZWN0UHVibGljS2V5SW5mbywKKyAqICAgICAgaXNzdWVyVW5pcXVlSUQgIFsxXSAgSU1QTElDSVQgVW5pcXVlSWRlbnRpZmllciBPUFRJT05BTCwKKyAqICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0gSWYgcHJlc2VudCwgdmVyc2lvbiBtdXN0IGJlIHYyIG9yIHYzCisgKiAgICAgIHN1YmplY3RVbmlxdWVJRCBbMl0gIElNUExJQ0lUIFVuaXF1ZUlkZW50aWZpZXIgT1BUSU9OQUwsCisgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tIElmIHByZXNlbnQsIHZlcnNpb24gbXVzdCBiZSB2MiBvciB2MworICogICAgICBleHRlbnNpb25zICAgICAgWzNdICBFWFBMSUNJVCBFeHRlbnNpb25zIE9QVElPTkFMCisgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tIElmIHByZXNlbnQsIHZlcnNpb24gbXVzdCBiZSB2MworICogICAgICB9CisgKiA8L3ByZT4KKyAqIDxwPgorICogRm9yIG1vcmUgaW5mb3JtYXRpb24gY29uc3VsdCBSRkMgMjQ1OQorICogIkludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUgQ2VydGlmaWNhdGUgYW5kIENSTCBQcm9maWxlIiBhdCA8YQorICogaHJlZgorICogPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyNDU5LnR4dCI+aHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjQ1OS50eHQKKyAqIDwvYT4gLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgWDUwOUNlcnRpZmljYXRlCisgICAgICAgIGV4dGVuZHMgQ2VydGlmaWNhdGUgaW1wbGVtZW50cyBYNTA5RXh0ZW5zaW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yNDkxMTI3NTg4MTg3MDM4MjE2TDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFg1MDlDZXJ0aWZpY2F0ZX0uCisgICAgICovCisgICAgcHJvdGVjdGVkIFg1MDlDZXJ0aWZpY2F0ZSgpIHsKKyAgICAgICAgc3VwZXIoIlguNTA5Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGNlcnRpZmljYXRlIGlzIGN1cnJlbnRseSB2YWxpZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgdmFsaWRpdHkgZGVmaW5lZCBpbiBBU04uMToKKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogdmFsaWRpdHkgICAgICAgICAgICAgVmFsaWRpdHkKKyAgICAgKgorICAgICAqIFZhbGlkaXR5IDo6PSBTRVFVRU5DRSB7CisgICAgICogICAgICBub3RCZWZvcmUgICAgICAgQ2VydGlmaWNhdGVWYWxpZGl0eURhdGUsCisgICAgICogICAgICBub3RBZnRlciAgICAgICAgQ2VydGlmaWNhdGVWYWxpZGl0eURhdGUgfQorICAgICAqCisgICAgICogQ2VydGlmaWNhdGVWYWxpZGl0eURhdGUgOjo9IENIT0lDRSB7CisgICAgICogICAgICB1dGNUaW1lICAgICAgICAgVVRDVGltZSwKKyAgICAgKiAgICAgIGdlbmVyYWxUaW1lICAgICBHZW5lcmFsaXplZFRpbWUgfQorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2VydGlmaWNhdGUgaGFzIGV4cGlyZWQuCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNlcnRpZmljYXRlIGlzIG5vdCB5ZXQgdmFsaWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgY2hlY2tWYWxpZGl0eSgpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGNlcnRpZmljYXRlIGlzIHZhbGlkIGF0IHRoZSBzcGVjaWZpZWQgZGF0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRlCisgICAgICogICAgICAgICAgICB0aGUgZGF0ZSB0byBjaGVjayB0aGUgdmFsaWRpdHkgYWdhaW5zdC4KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjZXJ0aWZpY2F0ZSBoYXMgZXhwaXJlZC4KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2VydGlmaWNhdGUgaXMgbm90IHlldCB2YWxpZC4KKyAgICAgKiBAc2VlICNjaGVja1ZhbGlkaXR5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBjaGVja1ZhbGlkaXR5KERhdGUgZGF0ZSkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24sIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjZXJ0aWZpY2F0ZXMge0Bjb2RlIHZlcnNpb259ICh2ZXJzaW9uIG51bWJlcikuCisgICAgICogPHA+CisgICAgICogVGhlIHZlcnNpb24gZGVmaW5lZCBpcyBBU04uMToKKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogVmVyc2lvbiA6Oj0gIElOVEVHRVIgIHsgIHYxKDApLCB2MigxKSwgdjMoMikgIH0KKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHZlcnNpb24gbnVtYmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0VmVyc2lvbigpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIHNlcmlhbE51bWJlcn0gb2YgdGhlIGNlcnRpZmljYXRlLgorICAgICAqIDxwPgorICAgICAqIFRoZSBBU04uMSBkZWZpbml0aW9uIG9mIHtAY29kZSBzZXJpYWxOdW1iZXJ9OgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiBDZXJ0aWZpY2F0ZVNlcmlhbE51bWJlciAgOjo9ICBJTlRFR0VSCisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzZXJpYWwgbnVtYmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCaWdJbnRlZ2VyIGdldFNlcmlhbE51bWJlcigpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIGlzc3Vlcn0gKGlzc3VlciBkaXN0aW5ndWlzaGVkIG5hbWUpIGFzIGFuCisgICAgICogaW1wbGVtZW50YXRpb24gc3BlY2lmaWMge0Bjb2RlIFByaW5jaXBhbH0gb2JqZWN0LgorICAgICAqIDxwPgorICAgICAqIFRoZSBBU04uMSBkZWZpbml0aW9uIG9mIHtAY29kZSBpc3N1ZXJ9OgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiAgaXNzdWVyICAgICAgTmFtZQorICAgICAqCisgICAgICogIE5hbWUgOjo9IENIT0lDRSB7CisgICAgICogICAgICBSRE5TZXF1ZW5jZSB9CisgICAgICoKKyAgICAgKiAgICBSRE5TZXF1ZW5jZSA6Oj0gU0VRVUVOQ0UgT0YgUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZQorICAgICAqCisgICAgICogICAgUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZSA6Oj0gU0VUIE9GIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZQorICAgICAqCisgICAgICogICAgQXR0cmlidXRlVHlwZUFuZFZhbHVlIDo6PSBTRVFVRU5DRSB7CisgICAgICogICAgICB0eXBlICAgICBBdHRyaWJ1dGVUeXBlLAorICAgICAqICAgICAgdmFsdWUgICAgQXR0cmlidXRlVmFsdWUgfQorICAgICAqCisgICAgICogICAgQXR0cmlidXRlVHlwZSA6Oj0gT0JKRUNUIElERU5USUZJRVIKKyAgICAgKgorICAgICAqICAgIEF0dHJpYnV0ZVZhbHVlIDo6PSBBTlkgREVGSU5FRCBCWSBBdHRyaWJ1dGVUeXBlCisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiA8Yj5yZXBsYWNlZCBieTo8L2I+IHtAbGluayAjZ2V0SXNzdWVyWDUwMFByaW5jaXBhbCgpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBpc3N1ZXJ9IGFzIGFuIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIHtAY29kZQorICAgICAqICAgICAgICAgUHJpbmNpcGFsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgUHJpbmNpcGFsIGdldElzc3VlckROKCkgOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIGlzc3Vlcn0gKGlzc3VlciBkaXN0aW5ndWlzaGVkIG5hbWUpIGFzIGFuIHtAY29kZQorICAgICAqIFg1MDBQcmluY2lwYWx9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIGlzc3Vlcn0gKGlzc3VlciBkaXN0aW5ndWlzaGVkIG5hbWUpLgorICAgICAqLworICAgIHB1YmxpYyBYNTAwUHJpbmNpcGFsIGdldElzc3Vlclg1MDBQcmluY2lwYWwoKSB7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFRPRE8gaWYgdGhlcmUgaXMgbm8gWC41MDkgY2VydGlmaWNhdGUgcHJvdmlkZXIgaW5zdGFsbGVkCisgICAgICAgICAgICAvLyBzaG91bGQgd2UgdHJ5IHRvIGFjY2VzcyBIYXJtb255IFg1MDlDZXJ0SW1wbCB2aWEgY2xhc3NGb3JOYW1lPworICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGZhY3RvcnkgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKCJYLjUwOSIpOworCisgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydCA9IChYNTA5Q2VydGlmaWNhdGUpIGZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdlbmVyYXRlQ2VydGlmaWNhdGUobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGdldEVuY29kZWQoKSkpOworCisgICAgICAgICAgICByZXR1cm4gY2VydC5nZXRJc3N1ZXJYNTAwUHJpbmNpcGFsKCk7CisKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJGYWlsZWQgdG8gZ2V0IFg1MDBQcmluY2lwYWwgaXNzdWVyIiwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgc3ViamVjdH0gKHN1YmplY3QgZGlzdGluZ3Vpc2hlZCBuYW1lKSBhcyBhbgorICAgICAqIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIHtAY29kZSBQcmluY2lwYWx9IG9iamVjdC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgQVNOLjEgZGVmaW5pdGlvbiBvZiB7QGNvZGUgc3ViamVjdH06CisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqIHN1YmplY3QgICAgICBOYW1lCisgICAgICoKKyAgICAgKiAgTmFtZSA6Oj0gQ0hPSUNFIHsKKyAgICAgKiAgICAgIFJETlNlcXVlbmNlIH0KKyAgICAgKgorICAgICAqICAgIFJETlNlcXVlbmNlIDo6PSBTRVFVRU5DRSBPRiBSZWxhdGl2ZURpc3Rpbmd1aXNoZWROYW1lCisgICAgICoKKyAgICAgKiAgICBSZWxhdGl2ZURpc3Rpbmd1aXNoZWROYW1lIDo6PSBTRVQgT0YgQXR0cmlidXRlVHlwZUFuZFZhbHVlCisgICAgICoKKyAgICAgKiAgICBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgOjo9IFNFUVVFTkNFIHsKKyAgICAgKiAgICAgIHR5cGUgICAgIEF0dHJpYnV0ZVR5cGUsCisgICAgICogICAgICB2YWx1ZSAgICBBdHRyaWJ1dGVWYWx1ZSB9CisgICAgICoKKyAgICAgKiAgICBBdHRyaWJ1dGVUeXBlIDo6PSBPQkpFQ1QgSURFTlRJRklFUgorICAgICAqCisgICAgICogICAgQXR0cmlidXRlVmFsdWUgOjo9IEFOWSBERUZJTkVEIEJZIEF0dHJpYnV0ZVR5cGUKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIDxiPnJlcGxhY2VkIGJ5OjwvYj4ge0BsaW5rICNnZXRTdWJqZWN0WDUwMFByaW5jaXBhbCgpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBzdWJqZWN0fSAoc3ViamVjdCBkaXN0aW5ndWlzaGVkIG5hbWUpLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBQcmluY2lwYWwgZ2V0U3ViamVjdEROKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgc3ViamVjdH0gKHN1YmplY3QgZGlzdGluZ3Vpc2hlZCBuYW1lKSBhcyBhbiB7QGNvZGUKKyAgICAgKiBYNTAwUHJpbmNpcGFsfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBzdWJqZWN0fSAoc3ViamVjdCBkaXN0aW5ndWlzaGVkIG5hbWUpCisgICAgICovCisgICAgcHVibGljIFg1MDBQcmluY2lwYWwgZ2V0U3ViamVjdFg1MDBQcmluY2lwYWwoKSB7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFRPRE8gaWYgdGhlcmUgaXMgbm8gWC41MDkgY2VydGlmaWNhdGUgcHJvdmlkZXIgaW5zdGFsbGVkCisgICAgICAgICAgICAvLyBzaG91bGQgd2UgdHJ5IHRvIGFjY2VzcyBIYXJtb255IFg1MDlDZXJ0SW1wbCB2aWEgY2xhc3NGb3JOYW1lPworICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGZhY3RvcnkgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKCJYLjUwOSIpOworCisgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydCA9IChYNTA5Q2VydGlmaWNhdGUpIGZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdlbmVyYXRlQ2VydGlmaWNhdGUobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGdldEVuY29kZWQoKSkpOworCisgICAgICAgICAgICByZXR1cm4gY2VydC5nZXRTdWJqZWN0WDUwMFByaW5jaXBhbCgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkZhaWxlZCB0byBnZXQgWDUwMFByaW5jaXBhbCBzdWJqZWN0IiwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgbm90QmVmb3JlfSBkYXRlIGZyb20gdGhlIHZhbGlkaXR5IHBlcmlvZCBvZiB0aGUKKyAgICAgKiBjZXJ0aWZpY2F0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN0YXJ0IG9mIHRoZSB2YWxpZGl0eSBwZXJpb2QuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IERhdGUgZ2V0Tm90QmVmb3JlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgbm90QWZ0ZXJ9IGRhdGUgb2YgdGhlIHZhbGlkaXR5IHBlcmlvZCBvZiB0aGUKKyAgICAgKiBjZXJ0aWZpY2F0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVuZCBvZiB0aGUgdmFsaWRpdHkgcGVyaW9kLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBEYXRlIGdldE5vdEFmdGVyKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgdGJzQ2VydGlmaWNhdGV9IGluZm9ybWF0aW9uIGZyb20gdGhpcyBjZXJ0aWZpY2F0ZSBpbgorICAgICAqIERFUi1lbmNvZGVkIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIERFUi1lbmNvZGVkIGNlcnRpZmljYXRlIGluZm9ybWF0aW9uLgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBpbiBlbmNvZGluZworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBieXRlW10gZ2V0VEJTQ2VydGlmaWNhdGUoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByYXcgc2lnbmF0dXJlIGJpdHMgZnJvbSB0aGUgY2VydGlmaWNhdGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByYXcgc2lnbmF0dXJlIGJpdHMgZnJvbSB0aGUgY2VydGlmaWNhdGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJ5dGVbXSBnZXRTaWduYXR1cmUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobSBmb3IgdGhlIGNlcnRpZmljYXRlIHNpZ25hdHVyZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNpZ25hdHVyZSBhbGdvcml0aG0gbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFNpZ0FsZ05hbWUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIE9JRCBvZiB0aGUgc2lnbmF0dXJlIGFsZ29yaXRobSBmcm9tIHRoZSBjZXJ0aWZpY2F0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIE9JRCBvZiB0aGUgc2lnbmF0dXJlIGFsZ29yaXRobS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFNpZ0FsZ09JRCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGFyYW1ldGVycyBvZiB0aGUgc2lnbmF0dXJlIGFsZ29yaXRobSBpbiBERVItZW5jb2RlZCBmb3JtYXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwYXJhbWV0ZXJzIG9mIHRoZSBzaWduYXR1cmUgYWxnb3JpdGhtLCBvciB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiAgICAgICAgIG5vbmUgYXJlIHVzZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJ5dGVbXSBnZXRTaWdBbGdQYXJhbXMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBpc3N1ZXJVbmlxdWVJRH0gZnJvbSB0aGUgY2VydGlmaWNhdGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgaXNzdWVyVW5pcXVlSUR9IG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSdzIG5vbmUgaW4gdGhlCisgICAgICogICAgICAgICBjZXJ0aWZpY2F0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbltdIGdldElzc3VlclVuaXF1ZUlEKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgc3ViamVjdFVuaXF1ZUlEfSBmcm9tIHRoZSBjZXJ0aWZpY2F0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBzdWJqZWN0VW5pcXVlSUR9IG9yIG51bGwgaWYgdGhlcmUncyBub25lIGluIHRoZQorICAgICAqICAgICAgICAgY2VydGlmaWNhdGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW5bXSBnZXRTdWJqZWN0VW5pcXVlSUQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBLZXlVc2FnZX0gZXh0ZW5zaW9uIGFzIGEge0Bjb2RlIGJvb2xlYW59IGFycmF5LgorICAgICAqIDxwPgorICAgICAqIFRoZSBBU04uMSBkZWZpbml0aW9uIG9mIHtAY29kZSBLZXlVc2FnZX06CisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqIEtleVVzYWdlIDo6PSBCSVQgU1RSSU5HIHsKKyAgICAgKiAgICAgIGRpZ2l0YWxTaWduYXR1cmUgICAgICAgICgwKSwKKyAgICAgKiAgICAgIG5vblJlcHVkaWF0aW9uICAgICAgICAgICgxKSwKKyAgICAgKiAgICAgIGtleUVuY2lwaGVybWVudCAgICAgICAgICgyKSwKKyAgICAgKiAgICAgIGRhdGFFbmNpcGhlcm1lbnQgICAgICAgICgzKSwKKyAgICAgKiAgICAgIGtleUFncmVlbWVudCAgICAgICAgICAgICg0KSwKKyAgICAgKiAgICAgIGtleUNlcnRTaWduICAgICAgICAgICAgICg1KSwKKyAgICAgKiAgICAgIGNSTFNpZ24gICAgICAgICAgICAgICAgICg2KSwKKyAgICAgKiAgICAgIGVuY2lwaGVyT25seSAgICAgICAgICAgICg3KSwKKyAgICAgKiAgICAgIGRlY2lwaGVyT25seSAgICAgICAgICAgICg4KSB9CisgICAgICoKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBLZXlVc2FnZX0gZXh0ZW5zaW9uIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSdzIG5vbmUgaW4KKyAgICAgKiAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbltdIGdldEtleVVzYWdlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcmVhZC1vbmx5IGxpc3Qgb2YgT0lEIHN0cmluZ3MgcmVwcmVzZW50aW5nIHRoZSB7QGNvZGUKKyAgICAgKiBFeHRLZXlVc2FnZVN5bnRheH0gZmllbGQgb2YgdGhlIGV4dGVuZGVkIGtleSB1c2FnZSBleHRlbnNpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBleHRlbmRlZCBrZXkgdXNhZ2UgZXh0ZW5zaW9uLCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUncyBub25lCisgICAgICogICAgICAgICBpbiB0aGUgY2VydGlmaWNhdGUuCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZXh0ZW5zaW9uIGRlY29kaW5nIGZhaWxzLgorICAgICAqLworICAgIHB1YmxpYyBMaXN0PFN0cmluZz4gZ2V0RXh0ZW5kZWRLZXlVc2FnZSgpCisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGF0aCBsZW5ndGggb2YgdGhlIGNlcnRpZmljYXRlIGNvbnN0cmFpbnRzIGZyb20gdGhlIHtAY29kZQorICAgICAqIEJhc2ljQ29udHJhaW50c30gZXh0ZW5zaW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcGF0aCBsZW5ndGggb2YgdGhlIGNlcnRpZmljYXRlIGNvbnN0cmFpbnRzIGlmIHRoZSBleHRlbnNpb24KKyAgICAgKiAgICAgICAgIGlzIHByZXNlbnQgb3Ige0Bjb2RlIC0xfSBpZiB0aGUgZXh0ZW5zaW9uIGlzIG5vdCBwcmVzZW50LiB7QGNvZGUKKyAgICAgKiAgICAgICAgIEludGVnZXIuTUFYX1ZBTFVFfSBpZiB0aGVyZSdzIG5vdCBsaW1pdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldEJhc2ljQ29uc3RyYWludHMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSByZWFkLW9ubHkgbGlzdCBvZiB0aGUgc3ViamVjdCBhbHRlcm5hdGl2ZSBuYW1lcyBmcm9tIHRoZQorICAgICAqIHtAY29kZSBTdWJqZWN0QWx0TmFtZX0gZXh0ZW5zaW9uLgorICAgICAqIDxwPgorICAgICAqIFRoZSBBU04uMSBkZWZpbml0aW9uIG9mIHtAY29kZSBTdWJqZWN0QWx0TmFtZX06CisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqIFN1YmplY3RBbHROYW1lIDo6PSBHZW5lcmFsTmFtZXMKKyAgICAgKgorICAgICAqIEdlbmVyYWxOYW1lcyA6Oj0gU0VRVUVOQ0UgU0laRSAoMS4uTUFYKSBPRiBHZW5lcmFsTmFtZQorICAgICAqCisgICAgICogR2VuZXJhbE5hbWUgOjo9IENIT0lDRSB7CisgICAgICogICAgICBvdGhlck5hbWUgICAgICAgICAgICAgICAgICAgICAgIFswXSAgICAgQW5vdGhlck5hbWUsCisgICAgICogICAgICByZmM4MjJOYW1lICAgICAgICAgICAgICAgICAgICAgIFsxXSAgICAgSUE1U3RyaW5nLAorICAgICAqICAgICAgZE5TTmFtZSAgICAgICAgICAgICAgICAgICAgICAgICBbMl0gICAgIElBNVN0cmluZywKKyAgICAgKiAgICAgIHg0MDBBZGRyZXNzICAgICAgICAgICAgICAgICAgICAgWzNdICAgICBPUkFkZHJlc3MsCisgICAgICogICAgICBkaXJlY3RvcnlOYW1lICAgICAgICAgICAgICAgICAgIFs0XSAgICAgTmFtZSwKKyAgICAgKiAgICAgIGVkaVBhcnR5TmFtZSAgICAgICAgICAgICAgICAgICAgWzVdICAgICBFRElQYXJ0eU5hbWUsCisgICAgICogICAgICB1bmlmb3JtUmVzb3VyY2VJZGVudGlmaWVyICAgICAgIFs2XSAgICAgSUE1U3RyaW5nLAorICAgICAqICAgICAgaVBBZGRyZXNzICAgICAgICAgICAgICAgICAgICAgICBbN10gICAgIE9DVEVUIFNUUklORywKKyAgICAgKiAgICAgIHJlZ2lzdGVyZWRJRCAgICAgICAgICAgICAgICAgICAgWzhdICAgICBPQkpFQ1QgSURFTlRJRklFUiB9CisgICAgICoKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN1YmplY3QgYWx0ZXJuYXRpdmUgbmFtZXMgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGFyZSBub25lCisgICAgICogICAgICAgICBpbiB0aGUgY2VydGlmaWNhdGUuCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBkZWNvZGluZyBvZiB0aGUgZXh0ZW5zaW9uIGZhaWxzLgorICAgICAqLworICAgIHB1YmxpYyBDb2xsZWN0aW9uPExpc3Q8Pz4+IGdldFN1YmplY3RBbHRlcm5hdGl2ZU5hbWVzKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24geworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcmVhZC1vbmx5IGxpc3Qgb2YgdGhlIGlzc3VlciBhbHRlcm5hdGl2ZSBuYW1lcyBmcm9tIHRoZSB7QGNvZGUKKyAgICAgKiBJc3N1ZXJBbHROYW1lfSBleHRlbnNpb24uCisgICAgICogPHA+CisgICAgICogVGhlIEFTTi4xIGRlZmluaXRpb24gb2Yge0Bjb2RlIElzc3VlckFsdE5hbWV9OgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiBJc3N1ZXJBbHROYW1lIDo6PSBHZW5lcmFsTmFtZXMKKyAgICAgKgorICAgICAqIEdlbmVyYWxOYW1lcyA6Oj0gU0VRVUVOQ0UgU0laRSAoMS4uTUFYKSBPRiBHZW5lcmFsTmFtZQorICAgICAqCisgICAgICogR2VuZXJhbE5hbWUgOjo9IENIT0lDRSB7CisgICAgICogICAgICBvdGhlck5hbWUgICAgICAgICAgICAgICAgICAgICAgIFswXSAgICAgQW5vdGhlck5hbWUsCisgICAgICogICAgICByZmM4MjJOYW1lICAgICAgICAgICAgICAgICAgICAgIFsxXSAgICAgSUE1U3RyaW5nLAorICAgICAqICAgICAgZE5TTmFtZSAgICAgICAgICAgICAgICAgICAgICAgICBbMl0gICAgIElBNVN0cmluZywKKyAgICAgKiAgICAgIHg0MDBBZGRyZXNzICAgICAgICAgICAgICAgICAgICAgWzNdICAgICBPUkFkZHJlc3MsCisgICAgICogICAgICBkaXJlY3RvcnlOYW1lICAgICAgICAgICAgICAgICAgIFs0XSAgICAgTmFtZSwKKyAgICAgKiAgICAgIGVkaVBhcnR5TmFtZSAgICAgICAgICAgICAgICAgICAgWzVdICAgICBFRElQYXJ0eU5hbWUsCisgICAgICogICAgICB1bmlmb3JtUmVzb3VyY2VJZGVudGlmaWVyICAgICAgIFs2XSAgICAgSUE1U3RyaW5nLAorICAgICAqICAgICAgaVBBZGRyZXNzICAgICAgICAgICAgICAgICAgICAgICBbN10gICAgIE9DVEVUIFNUUklORywKKyAgICAgKiAgICAgIHJlZ2lzdGVyZWRJRCAgICAgICAgICAgICAgICAgICAgWzhdICAgICBPQkpFQ1QgSURFTlRJRklFUiB9CisgICAgICoKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGlzc3VlciBhbHRlcm5hdGl2ZSBuYW1lcyBvZiB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgYXJlIG5vbmUgaW4KKyAgICAgKiAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZS4KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGRlY29kaW5nIG9mIHRoZSBleHRlbnNpb24gZmFpbHMuCisgICAgICovCisgICAgcHVibGljIENvbGxlY3Rpb248TGlzdDw/Pj4gZ2V0SXNzdWVyQWx0ZXJuYXRpdmVOYW1lcygpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9YNTA5RXh0ZW5zaW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L1g1MDlFeHRlbnNpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOTRhOTE1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9YNTA5RXh0ZW5zaW9uLmphdmEKQEAgLTAsMCArMSw2NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCisvKioKKyAqIFRoZSBpbnRlcmZhY2Ugc3BlY2lmeWluZyBhbiBYLjUwOSBDZXJ0aWZpY2F0ZSBvciBDUkwgZXh0ZW5zaW9uLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFg1MDlFeHRlbnNpb24geworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2V0IG9mIE9JRHMgb2YgdGhlIGV4dGVuc2lvbihzKSBtYXJrZWQgYXMgQ1JJVElDQUwsIHRoYXQgdGhpcworICAgICAqIGltcGxlbWVudGF0aW9uIG1hbmFnZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzZXQgb2YgZXh0ZW5zaW9uIE9JRHMgbWFya2VkIGFzIENSSVRJQUwsIGFuIGVtcHR5IHNldCBpZiBub25lCisgICAgICogICAgICAgICBhcmUgbWFya2VkIGFzIENSSVRJQ0FMLCBvciB7QGNvZGUgbnVsbH0gaWYgbm8gZXh0ZW5zaW9ucyBhcmUKKyAgICAgKiAgICAgICAgIHByZXNlbnQuCisgICAgICovCisgICAgcHVibGljIFNldDxTdHJpbmc+IGdldENyaXRpY2FsRXh0ZW5zaW9uT0lEcygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZXh0ZW5zaW9uIHZhbHVlIGFzIERFUi1lbmNvZGVkIE9DVEVUIHN0cmluZyBmb3IgdGhlIHNwZWNpZmllZAorICAgICAqIE9JRC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvaWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgaWRlbnRpZmllciB0byBnZXQgdGhlIGV4dGVuc2lvbiB2YWx1ZSBmb3IuCisgICAgICogQHJldHVybiB0aGUgZXh0ZW5zaW9uIHZhbHVlIGFzIERFUi1lbmNvZGVkIE9DVEVUIHN0cmluZywgb3Ige0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpZiBubyBleHRlbnNpb24gZm9yIHRoZSBzcGVjaWZpZWQgT0lEIGNhbiBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEV4dGVuc2lvblZhbHVlKFN0cmluZyBvaWQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2V0IG9mIE9JRHMgb2YgdGhlIGV4dGVuc2lvbihzKSBtYXJrZWQgYXMgTk9OLUNSSVRJQ0FMLCB0aGF0CisgICAgICogdGhpcyBpbXBsZW1lbnRhdGlvbiBtYW5hZ2VzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc2V0IG9mIGV4dGVuc2lvbiBPSURzIG1hcmtlZCBhcyBOT04tQ1JJVElBTCwgYW4gZW1wdHkgc2V0IGlmCisgICAgICogICAgICAgICBub25lIGFyZSBtYXJrZWQgYXMgTk9OLS5DUklUSUNBTCwgb3Ige0Bjb2RlIG51bGx9IGlmIG5vCisgICAgICogICAgICAgICBleHRlbnNpb25zIGFyZSBwcmVzZW50LgorICAgICAqLworICAgIHB1YmxpYyBTZXQ8U3RyaW5nPiBnZXROb25Dcml0aWNhbEV4dGVuc2lvbk9JRHMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIGluc3RhbmNlIGhhcyBhbiBleHRlbnNpb24gbWFya2VkIGFzIENSSVRJQ0FMIHRoYXQgaXQKKyAgICAgKiBjYW5ub3Qgc3VwcG9ydC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGFuIHVuc3VwcG9ydGVkIENSSVRJQ0FMIGV4dGVuc2lvbiBpcyBwcmVzZW50LAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzVW5zdXBwb3J0ZWRDcml0aWNhbEV4dGVuc2lvbigpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9wYWNrYWdlLmh0bWwgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9jZXJ0L3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMzliMzhmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvY2VydC9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwyMiBAQAorPGh0bWw+Cis8aGVhZD4KKzxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXVzLWFzY2lpIj4KKzwvaGVhZD4KKzxodG1sPgorPGJvZHk+Cis8cD4KK1RoaXMgcGFja2FnZSBwcm92aWRlcyBhbGwgdGhlIGNsYXNzZXMgYW5kIGFsbCB0aGUgaW50ZXJmYWNlcyBuZWVkZWQgdG8gZ2VuZXJhdGUsIGFkbWluaXN0ZXIgYW5kIHZlcmlmeQorWC41MDkgY2VydGlmaWNhdGVzLgorRnVuY3Rpb25hbGl0eSBmb3IgcGFyc2luZyBjZXJ0aWZpY2F0ZSwgZXh0cmFjdGluZyBpbmZvcm1hdGlvbiBmcm9tIHRoZW0sIHZhbGlkYXRpbmcgYW5kCit2ZXJpZnlpbmcgdGhlIGluZm9ybWF0aW9uIHRoZXkgY29udGFpbnMgYXJlIHByb3ZpZGVkLgorRXhjZXB0aW9uIGFyZSBnZW5lcmF0ZWQgbWFpbmx5IGZvciB0aHJlZSByZWFzb25zOjxicj4KKy0gaWYgdGhlIGNlcnRpZmljYXRlJ3MgZW5jb2RpbmcgaXMgYnJva2VuCisoQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbik8YnI+CistIGlmIHRoZSBjZXJ0aWZpY2F0ZSdzIHRpbWUgc3RhbXAgaXMgbm90IHZhbGlkCisoQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uKTxicj4KKy0gb3IgaWYgdGhlIHZhbGlkYXRpb24ncyBwYXRoIGlzIGZhbHNlIChDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbikuCis8L3A+PHA+CitUaGUgZnVuY3Rpb25hbGl0eSB0byBjaGVjayB0aGUgZGlmZmVyZW50IGVudHJpZXMgYW5kIGV4dGVuc2lvbiBmaWVsZHMgb2YgWC41MDkgY2VydGlmaWNhdGVzIGFyZSBhbHNvIHByb3ZpZGVkLgorPC9wPgorPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvaW50ZXJmYWNlcy9EU0FLZXkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvRFNBS2V5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzQwZWYwYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvRFNBS2V5LmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlczsKKworLyoqCisgKiBUaGUgYmFzZSBpbnRlcmZhY2UgZm9yIERpZ2l0YWwgU2lnbmF0dXJlIEFsZ29yaXRobSAoRFNBKSBwdWJsaWMgb3IgcHJpdmF0ZQorICoga2V5cy4KKyAqLworcHVibGljIGludGVyZmFjZSBEU0FLZXkgeworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgRFNBIGtleSBwYXJhbWV0ZXJzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgRFNBIGtleSBwYXJhbWV0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyBEU0FQYXJhbXMgZ2V0UGFyYW1zKCk7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvRFNBS2V5UGFpckdlbmVyYXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvaW50ZXJmYWNlcy9EU0FLZXlQYWlyR2VuZXJhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGUyZjczMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvRFNBS2V5UGFpckdlbmVyYXRvci5qYXZhCkBAIC0wLDAgKzEsNjcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworCisvKioKKyAqIFRoZSBpbnRlcmZhY2UgZm9yIGtleSBnZW5lcmF0b3JzIHRoYXQgY2FuIGdlbmVyYXRlIERTQSBrZXkgcGFpcnMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRFNBS2V5UGFpckdlbmVyYXRvciB7CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIGdlbmVyYXRvciB3aXRoIHRoZSBwcmltZSAoe0Bjb2RlIHB9KSwgc3VicHJpbWUgKHtAY29kZQorICAgICAqIHF9KSwgYW5kIGJhc2UgKHtAY29kZSBnfSkgdmFsdWVzIGZyb20gdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciB2YWx1ZXMuCisgICAgICogQHBhcmFtIHJhbmRvbQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBvZiByYW5kb21uZXNzLgorICAgICAqIEB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIHZhbHVlcyBhcmUge0Bjb2RlIG51bGx9IG9yCisgICAgICogICAgICAgICAgICAgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBpbml0aWFsaXplKERTQVBhcmFtcyBwYXJhbXMsIFNlY3VyZVJhbmRvbSByYW5kb20pCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMgZ2VuZXJhdG9yIGZvciB0aGUgc3BlY2lmaWVkIG1vZHVsdXMgbGVuZ3RoLiBWYWxpZCB2YWx1ZXMKKyAgICAgKiBmb3IgdGhlIG1vZHVsdXMgbGVuZ3RoIGFyZSB0aGUgbXVsdGlwbGVzIG9mIDggYmV0d2VlbiA1MTIgYW5kIDEwMjQuCisgICAgICogPHA+CisgICAgICogVGhlIHBhcmFtZXRlciB7QGNvZGUgZ2VuUGFyYW1zfSBzcGVjaWZpZXMgd2hldGhlciB0aGlzIG1ldGhvZCBzaG91bGQKKyAgICAgKiBnZW5lcmF0ZSBuZXcgcHJpbWUgKHtAY29kZSBwfSksIHN1YnByaW1lICh7QGNvZGUgcX0pLCBhbmQgYmFzZSAoe0Bjb2RlIGd9KQorICAgICAqIHZhbHVlcyBvciB3aGV0aGVyCisgICAgICogaXQgd2lsbCB1c2UgdGhlIHByZS1jYWxjdWxhdGVkIHZhbHVlcyBmb3IgdGhlIHNwZWNpZmllZCBtb2R1bHVzCisgICAgICogbGVuZ3RoLiBEZWZhdWx0IHBhcmFtZXRlcnMgYXJlIGF2YWlsYWJsZSBmb3IgbW9kdWx1cyBsZW5ndGhzIG9mIDUxMiBhbmQgMTAyNAorICAgICAqIGJpdHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbW9kbGVuCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBtb2R1bHVzIGluIGJpdHMuCisgICAgICogQHBhcmFtIGdlblBhcmFtcworICAgICAqICAgICAgICAgICAgd2hldGhlciBuZXcgdmFsdWVzIHNob3VsZCBiZSBnZW5lcmF0ZWQuCisgICAgICogQHBhcmFtIHJhbmRvbQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBvZiByYW5kb21uZXNzLgorICAgICAqIEB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgbW9kdWx1cyBsZW5ndGggaXMgbm90IHZhbGlkLCBvciBpZiB0aGVyZSBhcmUKKyAgICAgKiAgICAgICAgICAgICBubyBwcmUtY2FsY3VsYXRlZCB2YWx1ZXMgYW5kIHtAY29kZSBnZW5QYXJhbXN9IGlzIHtAY29kZQorICAgICAqICAgICAgICAgICAgIGZhbHNlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBpbml0aWFsaXplKGludCBtb2RsZW4sIGJvb2xlYW4gZ2VuUGFyYW1zLCBTZWN1cmVSYW5kb20gcmFuZG9tKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL0RTQVBhcmFtcy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvaW50ZXJmYWNlcy9EU0FQYXJhbXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZDFmY2I1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvaW50ZXJmYWNlcy9EU0FQYXJhbXMuamF2YQpAQCAtMCwwICsxLDQ5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlczsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworCisvKioKKyAqIFRoZSBpbnRlcmZhY2UgZm9yIERpZ2l0YWwgU2lnbmF0dXJlIEFsZ29yaXRobSAoRFNBKSBzcGVjaWZpYyBwYXJhbWV0ZXJzLgorICovCitwdWJsaWMgaW50ZXJmYWNlIERTQVBhcmFtcyB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBiYXNlICh7QGNvZGUgZ30pIHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYmFzZSAoe0Bjb2RlIGd9KSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRHKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcmltZSAoe0Bjb2RlIHB9KSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByaW1lICh7QGNvZGUgcH0pIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFAoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN1YnByaW1lICh7QGNvZGUgcX0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdWJwcmltZSAoe0Bjb2RlIHF9IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFEoKTsKKworfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL0RTQVByaXZhdGVLZXkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvRFNBUHJpdmF0ZUtleS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY3YzU2OTcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL0RTQVByaXZhdGVLZXkuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlczsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKKworLyoqCisgKiBUaGUgaW50ZXJmYWNlIGZvciBhIERpZ2l0YWwgU2lnbmF0dXJlIEFsZ29yaXRobSAoRFNBKSBwcml2YXRlIGtleS4KKyAqLworcHVibGljIGludGVyZmFjZSBEU0FQcml2YXRlS2V5IGV4dGVuZHMgRFNBS2V5LCBQcml2YXRlS2V5IHsKKworICAgIC8qKgorICAgICAqIFRoZSBzZXJpYWwgdmVyc2lvbiBpZGVudGlmaWVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzc3NjQ5NzQ4MjUzMzc5MDI3OUw7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcml2YXRlIGtleSB2YWx1ZSB7QGNvZGUgeH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcml2YXRlIGtleSB2YWx1ZSB7QGNvZGUgeH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0WCgpOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL0RTQVB1YmxpY0tleS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvaW50ZXJmYWNlcy9EU0FQdWJsaWNLZXkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOGY5ZGNlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvaW50ZXJmYWNlcy9EU0FQdWJsaWNLZXkuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlczsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworCisvKioKKyAqIFRoZSBpbnRlcmZhY2UgZm9yIGEgRGlnaXRhbCBTaWduYXR1cmUgQWxnb3JpdGhtIChEU0EpIHB1YmxpYyBrZXkuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRFNBUHVibGljS2V5IGV4dGVuZHMgRFNBS2V5LCBQdWJsaWNLZXkgeworCisgICAgLyoqCisgICAgICogVGhlIHNlcmlhbCB2ZXJzaW9uIGlkZW50aWZpZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxMjM0NTI2MzMyNzc5MDIyMzMyTDsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHB1YmxpYyBrZXkgdmFsdWUge0Bjb2RlIHl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHVibGljIGtleSB2YWx1ZSB7QGNvZGUgeX0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0WSgpOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL0VDS2V5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL0VDS2V5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzFlN2FjMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvRUNLZXkuamF2YQpAQCAtMCwwICsxLDMzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlczsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FQ1BhcmFtZXRlclNwZWM7CisKKy8qKgorICogVGhlIGJhc2UgaW50ZXJmYWNlIGZvciBFbGxpcHRpYyBDdXJ2ZSAoRUMpIHB1YmxpYyBvciBwcml2YXRlIGtleXMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRUNLZXkgeworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgRUMga2V5IHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBFQyBrZXkgcGFyYW1ldGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRUNQYXJhbWV0ZXJTcGVjIGdldFBhcmFtcygpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvaW50ZXJmYWNlcy9FQ1ByaXZhdGVLZXkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvRUNQcml2YXRlS2V5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTQwZGZlYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvRUNQcml2YXRlS2V5LmphdmEKQEAgLTAsMCArMSwzOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXM7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZhdGVLZXk7CisKKy8qKgorICogVGhlIGludGVyZmFjZSBmb3IgYW4gRWxsaXB0aWMgQ3VydmUgKEVDKSBwcml2YXRlIGtleS4KKyAqLworcHVibGljIGludGVyZmFjZSBFQ1ByaXZhdGVLZXkgZXh0ZW5kcyBQcml2YXRlS2V5LCBFQ0tleSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc2VyaWFsIHZlcnNpb24gaWRlbnRpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03ODk2Mzk0OTU2OTI1NjA5MTg0TDsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByaXZhdGUgdmFsdWUge0Bjb2RlIFN9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJpdmF0ZSB2YWx1ZSB7QGNvZGUgU30uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0UygpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvaW50ZXJmYWNlcy9FQ1B1YmxpY0tleS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvaW50ZXJmYWNlcy9FQ1B1YmxpY0tleS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQzZWVlYWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL0VDUHVibGljS2V5LmphdmEKQEAgLTAsMCArMSwzOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXM7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRUNQb2ludDsKKworLyoqCisgKiBUaGUgaW50ZXJmYWNlIGZvciBhbiBFbGxpcHRpYyBDdXJ2ZSAoRUMpIHB1YmxpYyBrZXkuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRUNQdWJsaWNLZXkgZXh0ZW5kcyBQdWJsaWNLZXksIEVDS2V5IHsKKworICAgIC8qKgorICAgICAqIFRoZSBzZXJpYWwgdmVyc2lvbiBpZGVudGlmaWVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTMzMTQ5ODg2Mjk4Nzk2MzI4MjZMOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHVibGljIHBvaW50IHtAY29kZSBXfSBvbiBhbiBlbGxpcHRpYyBjdXJ2ZSAoRUMpLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHVibGljIHBvaW50IHtAY29kZSBXfSBvbiBhbiBlbGxpcHRpYyBjdXJ2ZSAoRUMpLgorICAgICAqLworICAgIHB1YmxpYyBFQ1BvaW50IGdldFcoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvUlNBS2V5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL1JTQUtleS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlkMWNhMDEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL1JTQUtleS5qYXZhCkBAIC0wLDAgKzEsMzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CisKKy8qKgorICogVGhlIGJhc2UgaW50ZXJmYWNlIGZvciBQS0NTIzEgUlNBIHB1YmxpYyBhbmQgcHJpdmF0ZSBrZXlzLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFJTQUtleSB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtb2R1bHVzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbW9kdWx1cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRNb2R1bHVzKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL1JTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL1JTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2I4ODg1ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXkuamF2YQpAQCAtMCwwICsxLDg0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlczsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5SU0FPdGhlclByaW1lSW5mbzsKKworLyoqCisgKiBUaGUgaW50ZXJmYWNlIGZvciBhIE11bHRpLVByaW1lIFJTQSBwcml2YXRlIGtleS4gU3BlY2lmaWVkIGJ5IDxhCisgKiBocmVmPSJodHRwOi8vd3d3LnJzYS5jb20vcnNhbGFicy9ub2RlLmFzcD9pZD0yMTI1Ij5QS0NTICMxIHYyLjAgQW1lbmRtZW50IDE6CisgKiBNdWx0aS1QcmltZSBSU0E8L2E+LgorICovCitwdWJsaWMgaW50ZXJmYWNlIFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5IGV4dGVuZHMgUlNBUHJpdmF0ZUtleSB7CisKKyAgICAvKioKKyAgICAgKiB0aGUgc2VyaWFsIHZlcnNpb24gaWRlbnRpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDYxODA1ODUzMzUzNDYyODAwOEw7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBDUlQgY29lZmZpY2llbnQsIHtAY29kZSBxXi0xIG1vZCBwfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIENSVCBjb2VmZmljaWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRDcnRDb2VmZmljaWVudCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5mb3JtYXRpb24gZm9yIHRoZSBhZGRpdGlvbmFsIHByaW1lcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGluZm9ybWF0aW9uIGZvciB0aGUgYWRkaXRpb25hbCBwcmltZXMsIG9yIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAgdGhlcmUgYXJlIG9ubHkgdGhlIHR3byBwcmltZXMgKHtAY29kZSBwLCBxfSksCisgICAgICovCisgICAgcHVibGljIFJTQU90aGVyUHJpbWVJbmZvW10gZ2V0T3RoZXJQcmltZUluZm8oKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByaW1lIGZhY3RvciB7QGNvZGUgcH0gb2Yge0Bjb2RlIG59LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJpbWUgZmFjdG9yIHtAY29kZSBwfSBvZiB7QGNvZGUgbn0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0UHJpbWVQKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcmltZSBmYWN0b3Ige0Bjb2RlIHF9IG9mIHtAY29kZSBufS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByaW1lIGZhY3RvciB7QGNvZGUgcX0gb2Yge0Bjb2RlIG59LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFByaW1lUSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgQ1JUIGV4cG9uZW50IG9mIHRoZSBwcmltZSB7QGNvZGUgcH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBDUlQgZXhwb25lbnQgb2YgdGhlIHByaW1lIHtAY29kZSBwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQcmltZUV4cG9uZW50UCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgQ1JUIGV4cG9uZW50IG9mIHRoZSBwcmltZSB7QGNvZGUgcX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBDUlQgZXhwb25lbnQgb2YgdGhlIHByaW1lIHtAY29kZSBxfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQcmltZUV4cG9uZW50USgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHVibGljIGV4cG9uZW50IHtAY29kZSBlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHB1YmxpYyBleHBvbmVudCB7QGNvZGUgZX0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0UHVibGljRXhwb25lbnQoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvUlNBUHJpdmF0ZUNydEtleS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvaW50ZXJmYWNlcy9SU0FQcml2YXRlQ3J0S2V5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2U0ZDBhYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvUlNBUHJpdmF0ZUNydEtleS5qYXZhCkBAIC0wLDAgKzEsNzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CisKKy8qKgorICogVGhlIGludGVyZmFjZSBmb3IgYSBQS0NTIzEgUlNBIHByaXZhdGUga2V5IHVzaW5nIENSVCBpbmZvcm1hdGlvbiB2YWx1ZXMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUlNBUHJpdmF0ZUNydEtleSBleHRlbmRzIFJTQVByaXZhdGVLZXkgeworCisgICAgLyoqCisgICAgICogVGhlIHNlcmlhbCB2ZXJzaW9uIGlkZW50aWZpZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTY4MjIxNDI1MzUyNzcwMDM2OEw7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBDUlQgY29lZmZpY2llbnQsIHtAY29kZSBxXi0xIG1vZCBwfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIENSVCBjb2VmZmljaWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRDcnRDb2VmZmljaWVudCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJpbWUgZmFjdG9yIHtAY29kZSBwfSBvZiB7QGNvZGUgbn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmltZSBmYWN0b3Ige0Bjb2RlIHB9IG9mIHtAY29kZSBufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQcmltZVAoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByaW1lIGZhY3RvciB7QGNvZGUgcX0gb2Yge0Bjb2RlIG59LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJpbWUgZmFjdG9yIHtAY29kZSBxfSBvZiB7QGNvZGUgbn0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0UHJpbWVRKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBDUlQgZXhwb25lbnQgb2YgdGhlIHByaW1ldCB7QGNvZGUgcH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBDUlQgZXhwb25lbnQgb2YgdGhlIHByaW1lIHtAY29kZSBwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQcmltZUV4cG9uZW50UCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgQ1JUIGV4cG9uZW50IG9mIHRoZSBwcmltZSB7QGNvZGUgcX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBDUlQgZXhwb25lbnQgb2YgdGhlIHByaW1lIHtAY29kZSBxfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQcmltZUV4cG9uZW50USgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHVibGljIGV4cG9uZW50IHtAY29kZSBlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHB1YmxpYyBleHBvbmVudCB7QGNvZGUgZX0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0UHVibGljRXhwb25lbnQoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvUlNBUHJpdmF0ZUtleS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvaW50ZXJmYWNlcy9SU0FQcml2YXRlS2V5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmMwODU0NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvUlNBUHJpdmF0ZUtleS5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworCisvKioKKyAqIFRoZSBpbnRlcmZhY2UgZm9yIGFuIFBLQ1MjMSBSU0EgcHJpdmF0ZSBrZXkuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUlNBUHJpdmF0ZUtleSBleHRlbmRzIFByaXZhdGVLZXksIFJTQUtleSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc2VyaWFsIHZlcnNpb24gaWRlbnRpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDUxODcxNDQ4MDQ5MzY1OTUwMjJMOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJpdmF0ZSBleHBvbmVudCB7QGNvZGUgZH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcml2YXRlIGV4cG9uZW50IHtAY29kZSBkfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQcml2YXRlRXhwb25lbnQoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvUlNBUHVibGljS2V5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL1JTQVB1YmxpY0tleS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRjODAzODgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL1JTQVB1YmxpY0tleS5qYXZhCkBAIC0wLDAgKzEsNDAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CisKKy8qKgorICogVGhlIGludGVyZmFjZSBmb3IgYSBQS0NTIzEgUlNBIHB1YmxpYyBrZXkuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUlNBUHVibGljS2V5IGV4dGVuZHMgUHVibGljS2V5LCBSU0FLZXkgeworCisgICAgLyoqCisgICAgICogVGhlIHNlcmlhbCB2ZXJzaW9uIGlkZW50aWZpZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODcyNzQzNDA5NjI0MTEwMTE5NEw7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwdWJsaWMgZXhwb25lbnQge0Bjb2RlIGV9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHVibGljIGV4cG9uZW50IHtAY29kZSBlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQdWJsaWNFeHBvbmVudCgpOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL3BhY2thZ2UuaHRtbCBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L2ludGVyZmFjZXMvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRkMjQxOTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9pbnRlcmZhY2VzL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDE0IEBACis8aHRtbD4KKzxoZWFkPgorPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXMtYXNjaWkiPgorPC9oZWFkPgorPGh0bWw+Cis8Ym9keT4KKzxwPgorVGhpcyBwYWNrYWdlIHByb3ZpZGVzIHRoZSBpbnRlcmZhY2VzIG5lZWRlZCB0byBnZW5lcmF0ZToKKygxKSBLZXlzIGZvciB0aGUgUlNBIGFzeW1tZXRyaWMgZW5jcnlwdGlvbiBhbGdvcml0aG0gdXNpbmcgdGhlIFBLQ1MjMSBzdGFuZGFyZDsKKygyKSBLZXlzIGZvciB0aGUgRGlnaXRhbCBTaWduYXR1cmUgQWxnb3JpdGhtIChEU0EpIHNwZWNpZmllZCBieSBGSVBTLTE4NjsKKygzKSBLZXlzIGZvciBhIGdlbmVyaWMgRWxsaXB0aWMgQ3VydmUgYXN5bW1ldHJpYyBlbmNyeXB0aW9uIGFsZ29yaXRobS4KKzwvcD4KKzwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3BhY2thZ2UuaHRtbCBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMmU3ZTA4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMTIgQEAKKzxodG1sPgorPGhlYWQ+Cis8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD11cy1hc2NpaSI+Cis8L2hlYWQ+Cis8aHRtbD4KKzxib2R5PgorPHA+VGhpcyBwYWNrYWdlIGlzIGZvciBjb21wYXRpYmlsaXR5Cit3aXRoIGxlZ2FjeSBjb2RlIG9ubHksIGFuZCBzaG91bGQgbm90IGJlIHVzZWQgb3IgZXhwZWN0ZWQgdG8gZG8KK2FueXRoaW5nIHVzZWZ1bC4KKzwvcD4KKzwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NlY3VyaXR5LnByb3BlcnRpZXMgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zZWN1cml0eS5wcm9wZXJ0aWVzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2MWUyYWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zZWN1cml0eS5wcm9wZXJ0aWVzCkBAIC0wLDAgKzEsNjUgQEAKKyMgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisjIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorIyB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisjIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisjICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisjIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjIAorIyAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjIAorIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCisKKyMKKyMgUHJvdmlkZXJzCisjIFNlZSBhbHNvOiBKMlNFIGRvYy4gIkhvdyB0byBJbXBsZW1lbnQgYSBQcm92aWRlciBmb3IgdGhlIEphdmFUTSBDcnlwdG9ncmFwaHkgQXJjaGl0ZWN0dXJlIgorIworIyBBbmRyb2lkJ3MgcHJvdmlkZXIgb2YgT3BlblNTTCBiYWNrZWQgaW1wbGVtZW50YXRpb25zCitzZWN1cml0eS5wcm92aWRlci4xPW9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2UuT3BlblNTTFByb3ZpZGVyCisjIEZhdm9yIEhhcm1vbnkncyBDZXJ0aWZpY2F0ZUZhY3RvcnkuWDUwOSBvdmVyIEJvdW5jeUNhc3RsZSdzCitzZWN1cml0eS5wcm92aWRlci4yPW9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wcm92aWRlci5jZXJ0LkRSTENlcnRGYWN0b3J5CisjIEFuZHJvaWQncyBzdHJpcHBlZCBkb3duIEJvdW5jeUNhc3RsZSBwcm92aWRlcgorc2VjdXJpdHkucHJvdmlkZXIuMz1jb20uYW5kcm9pZC5vcmcuYm91bmN5Y2FzdGxlLmpjZS5wcm92aWRlci5Cb3VuY3lDYXN0bGVQcm92aWRlcgorIyBSZW1haW5pbmcgSGFybW9ueSBwcm92aWRlcnMKK3NlY3VyaXR5LnByb3ZpZGVyLjQ9b3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnByb3ZpZGVyLmNyeXB0by5DcnlwdG9Qcm92aWRlcgorc2VjdXJpdHkucHJvdmlkZXIuNT1vcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlLkpTU0VQcm92aWRlcgorCisKKworCisKKworCisjIFRoZSBkZWZhdWx0IFNTTFNvY2tldEZhY3RvcnkgYW5kIFNTTFNlcnZlclNvY2tldEZhY3RvcnkgcHJvdmlkZXIgaW1wbGVtZW50YXRpb25zLgorIyBTZWUgc3BlY2lmaWNhdGlvbiBmb3IgCisjIGphdmF4L25ldC9zc2wvU1NMU29ja2V0RmFjdG9yeS5odG1sI2dldERlZmF1bHQoKQorIyBqYXZheC9uZXQvc3NsL1NTTFNlcnZlclNvY2tldEZhY3RvcnkuaHRtbCNnZXREZWZhdWx0KCkKKworIyBGb3IgcmVndWxhciBTU0xTb2NrZXRzLCB3ZSBoYXZlIHR3byBpbXBsZW1lbnRhdGlvbnM6Citzc2wuU29ja2V0RmFjdG9yeS5wcm92aWRlcj1vcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlLk9wZW5TU0xTb2NrZXRGYWN0b3J5SW1wbAorI3NzbC5Tb2NrZXRGYWN0b3J5LnByb3ZpZGVyPW9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2UuU1NMU29ja2V0RmFjdG9yeUltcGwKKworIyBGb3IgU1NMU2VydmVyU29ja2V0cywgdGhlcmUncyBvbmx5IHRoZSBuZXcsIE9wZW5TU0wtYmFzZWQgaW1wbGVtZW50YXRpb246Citzc2wuU2VydmVyU29ja2V0RmFjdG9yeS5wcm92aWRlcj1vcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlLk9wZW5TU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5SW1wbAorCisjIERlZmF1bHQgS2V5U3RvcmUgdHlwZS4KKyMgU2VlIHNwZWNpZmljYXRpb24gZm9yIGphdmEvc2VjdXJpdHkvS2V5U3RvcmUuaHRtbCNnZXREZWZhdWx0VHlwZSgpCitrZXlzdG9yZS50eXBlPUJLUworCisKKyMgRGVmYXVsdCBLZXlNYW5hZ2VyRmFjdG9yeSBhbmQgVHJ1c3RNYW5hZ2VyRmFjdG9yeSBhbGdvcml0aG1zLiAKKyMgU2VlIHNwZWNpZmljYXRpb24gZm9yCisjIGphdmF4L25ldC9zc2wvS2V5TWFuYWdlckZhY3RvcnkuaHRtbCNnZXREZWZhdWx0QWxnb3JpdGhtKCkKKyMgamF2YXgvbmV0L3NzbC9UcnVzdE1hbmFnZXJGYWN0b3J5Lmh0bWwjZ2V0RGVmYXVsdEFsZ29yaXRobSgpCitzc2wuS2V5TWFuYWdlckZhY3RvcnkuYWxnb3JpdGhtPVg1MDkKK3NzbC5UcnVzdE1hbmFnZXJGYWN0b3J5LmFsZ29yaXRobT1YNTA5CisKKyMgc3lzdGVtLnNjb3BlIGlzIHVzZWQgdG8gc3BlY2lmeSBpbXBsZW1lbnRhdGlvbiBjbGFzcyBvZiBJZGVudGl0eVNjb3BlCitzeXN0ZW0uc2NvcGU9b3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LlN5c3RlbVNjb3BlCisKKyMgVGhlIGZvbGxvd2luZyBBbmRyb2lkLW9ubHkgcHJvcGVydHkgY29udHJvbHMgcGVlciBjZXJ0aWZpY2F0ZSB2YWxpZGF0aW9uLgorc3NsLmRpc2FibGVQZWVyQ2VydGlmaWNhdGVDaGFpblZlcmlmaWNhdGlvbj1mYWxzZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9BbGdvcml0aG1QYXJhbWV0ZXJTcGVjLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0FsZ29yaXRobVBhcmFtZXRlclNwZWMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wY2JiYTc2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9BbGdvcml0aG1QYXJhbWV0ZXJTcGVjLmphdmEKQEAgLTAsMCArMSwyNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LnNwZWM7CisKKy8qKgorICogVGhlIG1hcmtlciBpbnRlcmZhY2UgZm9yIGFsZ29yaXRobSBwYXJhbWV0ZXIgc3BlY2lmaWNhdGlvbnMuIFRoZSBwdXJwb3NlIGlzCisgKiB0byBncm91cCBwYXJhbWV0ZXIgc3BlY2lmaWNhdGlvbnMgZm9yIGFsZ29yaXRobXMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyB7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0RTQVBhcmFtZXRlclNwZWMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvRFNBUGFyYW1ldGVyU3BlYy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ0ODQ5MDgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0RTQVBhcmFtZXRlclNwZWMuamF2YQpAQCAtMCwwICsxLDc3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5EU0FQYXJhbXM7CisKKy8qKgorICogVGhlIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uIHVzZWQgd2l0aCB0aGUgRGlnaXRhbCBTaWduYXR1cmUgQWxnb3JpdGhtIChEU0EpLgorICovCitwdWJsaWMgY2xhc3MgRFNBUGFyYW1ldGVyU3BlYyBpbXBsZW1lbnRzIEFsZ29yaXRobVBhcmFtZXRlclNwZWMsIERTQVBhcmFtcyB7CisgICAgLy8gUHJpbWUKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgcDsKKyAgICAvLyBTdWItcHJpbWUKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgcTsKKyAgICAvLyBCYXNlCisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIGc7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBEU0FQYXJhbWV0ZXJTcGVjfSB3aXRoIHRoZSBzcGVjaWZpZWQgcHJpbWUge0Bjb2RlIHB9LAorICAgICAqIHN1Yi1wcmltZSB7QGNvZGUgcX0gYW5kIHRoZSBiYXNlIHtAY29kZSBnfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwCisgICAgICogICAgICAgICAgICB0aGUgcHJpbWUge0Bjb2RlIHB9LgorICAgICAqIEBwYXJhbSBxCisgICAgICogICAgICAgICAgICB0aGUgc3ViLXByaW1lIHtAY29kZSBxfS4KKyAgICAgKiBAcGFyYW0gZworICAgICAqICAgICAgICAgICAgdGhlIGJhc2Uge0Bjb2RlIGd9OworICAgICAqLworICAgIHB1YmxpYyBEU0FQYXJhbWV0ZXJTcGVjKEJpZ0ludGVnZXIgcCwgQmlnSW50ZWdlciBxLCBCaWdJbnRlZ2VyIGcpIHsKKyAgICAgICAgdGhpcy5wID0gcDsKKyAgICAgICAgdGhpcy5xID0gcTsKKyAgICAgICAgdGhpcy5nID0gZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBiYXNlIHtAY29kZSBnfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJhc2Uge0Bjb2RlIGd9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldEcoKSB7CisgICAgICAgIHJldHVybiBnOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByaW1lIHtAY29kZSBwfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByaW1lIHtAY29kZSBwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQKCkgeworICAgICAgICByZXR1cm4gcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdWItcHJpbWUge0Bjb2RlIHF9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3ViLXByaW1lIHtAY29kZSBxfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRRKCkgeworICAgICAgICByZXR1cm4gcTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0RTQVByaXZhdGVLZXlTcGVjLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0RTQVByaXZhdGVLZXlTcGVjLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDM1Yjk4NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvRFNBUHJpdmF0ZUtleVNwZWMuamF2YQpAQCAtMCwwICsxLDkxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworCisvKioKKyAqIFRoZSBwYXJhbWV0ZXJzIHNwZWNpZnlpbmcgYSBEU0EgcHJpdmF0ZSBrZXkuCisgKi8KK3B1YmxpYyBjbGFzcyBEU0FQcml2YXRlS2V5U3BlYyBpbXBsZW1lbnRzIEtleVNwZWMgeworICAgIC8vIFByaXZhdGUga2V5CisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIHg7CisgICAgLy8gUHJpbWUKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgcDsKKyAgICAvLyBTdWItcHJpbWUKKyAgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIHE7CisgICAgLy8gQmFzZQorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBnOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgRFNBUHJpdmF0ZUtleVNwZWN9IHdpdGggdGhlIHNwZWNpZmllZCBwcml2YXRlIGtleSwKKyAgICAgKiBwcmltZSwgc3ViLXByaW1lIGFuZCBiYXNlLgorICAgICAqCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcml2YXRlIGtleSB7QGNvZGUgeH0uCisgICAgICogQHBhcmFtIHAKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmltZSB7QGNvZGUgcH0uCisgICAgICogQHBhcmFtIHEKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdWItcHJpbWUge0Bjb2RlIHF9LgorICAgICAqIEBwYXJhbSBnCisgICAgICogICAgICAgICAgICB0aGUgYmFzZSB7QGNvZGUgZ30uCisgICAgICovCisgICAgcHVibGljIERTQVByaXZhdGVLZXlTcGVjKEJpZ0ludGVnZXIgeCwgQmlnSW50ZWdlciBwLAorICAgICAgICAgICAgQmlnSW50ZWdlciBxLCBCaWdJbnRlZ2VyIGcpIHsKKyAgICAgICAgdGhpcy54ID0geDsKKyAgICAgICAgdGhpcy5wID0gcDsKKyAgICAgICAgdGhpcy5xID0gcTsKKyAgICAgICAgdGhpcy5nID0gZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBiYXNlIHtAY29kZSBnfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJhc2Uge0Bjb2RlIGd9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldEcoKSB7CisgICAgICAgIHJldHVybiBnOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByaW1lIHtAY29kZSBwfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByaW1lIHtAY29kZSBwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQKCkgeworICAgICAgICByZXR1cm4gcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdWItcHJpbWUge0Bjb2RlIHF9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3ViLXByaW1lIHtAY29kZSBxfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRRKCkgeworICAgICAgICByZXR1cm4gcTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcml2YXRlIGtleSB7QGNvZGUgeH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcml2YXRlIGtleSB7QGNvZGUgeH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0WCgpIHsKKyAgICAgICAgcmV0dXJuIHg7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9EU0FQdWJsaWNLZXlTcGVjLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0RTQVB1YmxpY0tleVNwZWMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZWUxMGEyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9EU0FQdWJsaWNLZXlTcGVjLmphdmEKQEAgLTAsMCArMSw5MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LnNwZWM7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKKworLyoqCisgKiBUaGUgcGFyYW1ldGVycyBzcGVjaWZ5aW5nIGEgRFNBIHB1YmxpYyBrZXkuCisgKi8KK3B1YmxpYyBjbGFzcyBEU0FQdWJsaWNLZXlTcGVjIGltcGxlbWVudHMgS2V5U3BlYyB7CisgICAgLy8gUHVibGljIGtleQorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciB5OworICAgIC8vIFByaW1lCisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIHA7CisgICAgLy8gU3ViLXByaW1lCisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIHE7CisgICAgLy8gQmFzZQorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBnOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgRFNBUHVibGljS2V5U3BlY30gd2l0aCB0aGUgc3BlY2lmaWVkIHB1YmxpYyBrZXksCisgICAgICogIHByaW1lLCBzdWItcHJpbWUgYW5kIGJhc2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0geQorICAgICAqICAgICAgICAgICAgdGhlIHB1YmxpYyBrZXkgdmFsdWUge0Bjb2RlIHl9LgorICAgICAqIEBwYXJhbSBwCisgICAgICogICAgICAgICAgICB0aGUgcHJpbWUge0Bjb2RlIHB9LgorICAgICAqIEBwYXJhbSBxCisgICAgICogICAgICAgICAgICB0aGUgc3ViLXByaW1lIHtAY29kZSBxfS4KKyAgICAgKiBAcGFyYW0gZworICAgICAqICAgICAgICAgICAgdGhlIGJhc2Uge0Bjb2RlIGd9LgorICAgICAqLworICAgIHB1YmxpYyBEU0FQdWJsaWNLZXlTcGVjKEJpZ0ludGVnZXIgeSwgQmlnSW50ZWdlciBwLAorICAgICAgICAgICAgQmlnSW50ZWdlciBxLCBCaWdJbnRlZ2VyIGcpIHsKKyAgICAgICAgdGhpcy55ID0geTsKKyAgICAgICAgdGhpcy5wID0gcDsKKyAgICAgICAgdGhpcy5xID0gcTsKKyAgICAgICAgdGhpcy5nID0gZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBiYXNlIHtAY29kZSBnfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJhc2Uge0Bjb2RlIGd9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldEcoKSB7CisgICAgICAgIHJldHVybiBnOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByaW1lIHtAY29kZSBwfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByaW1lIHtAY29kZSBwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQKCkgeworICAgICAgICByZXR1cm4gcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdWItcHJpbWUge0Bjb2RlIHF9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3ViLXByaW1lIHtAY29kZSBxfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRRKCkgeworICAgICAgICByZXR1cm4gcTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwdWJsaWMga2V5IHZhbHVlIHtAY29kZSB5fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHB1YmxpYyBrZXkgdmFsdWUge0Bjb2RlIHl9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFkoKSB7CisgICAgICAgIHJldHVybiB5OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvRUNGaWVsZC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9FQ0ZpZWxkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzVlYjZlNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvRUNGaWVsZC5qYXZhCkBAIC0wLDAgKzEsMzEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5zcGVjOworCisvKioKKyAqIFRoZSBiYXNlIGludGVyZmFjZSBmb3IgYSBGaW5pdGUgRmllbGQgb2YgYW4gRWxsaXB0aWMgQ3VydmUuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRUNGaWVsZCB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzaXplIG9mIHRoZSBmaWVsZCAoaW4gYml0cykuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzaXplIG9mIHRoZSBmaWVsZCAoaW4gYml0cykuCisgICAgICovCisgICAgaW50IGdldEZpZWxkU2l6ZSgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9FQ0ZpZWxkRjJtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0VDRmllbGRGMm0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNGI0MTc4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9FQ0ZpZWxkRjJtLmphdmEKQEAgLTAsMCArMSwyNjQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5zcGVjOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBUaGUgcGFyYW1ldGVycyBzcGVjaWZ5aW5nIGEgPGk+Y2hhcmFjdGVyaXN0aWMgMiBmaW5pdGUgZmllbGQ8L2k+IG9mIGFuCisgKiBlbGxpcHRpYyBjdXJ2ZS4KKyAqLworcHVibGljIGNsYXNzIEVDRmllbGRGMm0gaW1wbGVtZW50cyBFQ0ZpZWxkIHsKKyAgICAvLyBNaWQgdGVybXMgYXJyYXkgbGVuZ3RoIGZvciB0cmlub21pYWwgYmFzaXMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVFBCX01JRF9MRU4gPSAxOworICAgIC8vIE1pZCB0ZXJtcyBhcnJheSBsZW5ndGggZm9yIHBlbnRhbm9taWFsIGJhc2lzCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFBQQl9NSURfTEVOID0gMzsKKyAgICAvLyBBbGwgdGVybXMgbnVtYmVyIGZvciB0cmlub21pYWwgYmFzaXMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVFBCX0xFTiA9IFRQQl9NSURfTEVOICsgMjsKKyAgICAvLyBBbGwgdGVybXMgbnVtYmVyIGZvciBwZW50YW5vbWlhbCBiYXNpcworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBQUEJfTEVOID0gUFBCX01JRF9MRU4gKyAyOworICAgIC8vIG0gdmFsdWUKKyAgICBwcml2YXRlIGZpbmFsIGludCBtOworICAgIC8vIFJlZHVjdGlvbiBwb2x5bm9taWFsCisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIHJwOworICAgIC8vIE1pZCB0ZXJtKHMpIG9mIHJlZHVjdGlvbiBwb2x5bm9taWFsCisgICAgcHJpdmF0ZSBmaW5hbCBpbnRbXSBrczsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEVDRmllbGRGMm19IHdpdGgge0Bjb2RlIDJebX0gZWxlbWVudHMgd2l0aCBhIG5vcm1hbAorICAgICAqIGJhc2lzLgorICAgICAqCisgICAgICogQHBhcmFtIG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBleHBvbmVudCB7QGNvZGUgbX0gZm9yIHRoZSBudW1iZXIgb2YgZWxlbWVudHMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbSA8PSB6ZXJvfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRUNGaWVsZEYybShpbnQgbSkgeworICAgICAgICB0aGlzLm0gPSBtOworICAgICAgICBpZiAodGhpcy5tIDw9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm0gPD0gMCIpOworICAgICAgICB9CisgICAgICAgIHRoaXMucnAgPSBudWxsOworICAgICAgICB0aGlzLmtzID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBFQ0ZpZWxkRjJtfSB3aXRoIHtAY29kZSAyXm19IGVsZW1lbnRzIHdpdGggYSBwb2x5bm9taWFsCisgICAgICogYmFzaXMgYW5kIHRoZSByZWR1Y3Rpb24gcG9seW5vbWlhbCBiYXNlZCBvbiB7QGNvZGUgcnB9LgorICAgICAqIDxwPgorICAgICAqIFRoZSByZWR1Y3Rpb24gcG9seW5vbWlhbCBtdXN0IGJlIGVpdGhlciA8aT50cmlub21pYWw8L2k+IG9yCisgICAgICogPGk+cGVudGFub21pYWw8L2k+LgorICAgICAqCisgICAgICogQHBhcmFtIG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBleHBvbmVudCB7QGNvZGUgbX0gZm9yIHRoZSBudW1iZXIgb2YgZWxlbWVudHMuCisgICAgICogQHBhcmFtIHJwCisgICAgICogICAgICAgICAgICB0aGUgYmFzZSBvZiB0aGUgcmVkdWN0aW9uIHBvbHlub21pYWwgd2l0aCB0aGUgbi10aCBiaXQKKyAgICAgKiAgICAgICAgICAgIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG4tdGggY29lZmZpY2llbnQgb2YgdGhlIHJlZHVjdGlvbgorICAgICAqICAgICAgICAgICAgcG9seW5vbWlhbC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBtIDw9IHplcm99IG9yIHRoZSB7QGNvZGUgcnB9IGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIEVDRmllbGRGMm0oaW50IG0sIEJpZ0ludGVnZXIgcnApIHsKKyAgICAgICAgdGhpcy5tID0gbTsKKyAgICAgICAgaWYgKHRoaXMubSA8PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJtIDw9IDAiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnJwID0gcnA7CisgICAgICAgIGlmICh0aGlzLnJwID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicnAgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIC8vIHRoZSBsZWZ0bW9zdCBiaXQgbXVzdCBiZSAobSsxKS10aCBvbmUsCisgICAgICAgIC8vIHNldCBiaXRzIGNvdW50IG11c3QgYmUgMyBvciA1LAorICAgICAgICAvLyBiaXRzIDAgYW5kIG0gbXVzdCBiZSBzZXQKKyAgICAgICAgaW50IHJwX2JjID0gdGhpcy5ycC5iaXRDb3VudCgpOworICAgICAgICBpZiAoKHRoaXMucnAuYml0TGVuZ3RoKCkgIT0gKG0rMSkpIHx8CisgICAgICAgICAgICAocnBfYmMgIT0gVFBCX0xFTiAmJiBycF9iYyAhPSBQUEJfTEVOKSB8fAorICAgICAgICAgICAgKCF0aGlzLnJwLnRlc3RCaXQoMCkgfHwgIXRoaXMucnAudGVzdEJpdChtKSkgKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJycCBpcyBpbnZhbGlkIik7CisgICAgICAgIH0KKworICAgICAgICAvLyBzZXR1cCBrcyB1c2luZyBycDoKKyAgICAgICAgLy8gYWxsb2NhdGUgZm9yIG1pZCB0ZXJtcyBvbmx5CisgICAgICAgIGtzID0gbmV3IGludFtycF9iYy0yXTsKKyAgICAgICAgLy8gZmluZCBtaWR0ZXJtIG9yZGVycyBhbmQgc2V0IGtzIGFjY29yZGluZ2x5CisgICAgICAgIEJpZ0ludGVnZXIgcnBUbXAgPSBycC5jbGVhckJpdCgwKTsKKyAgICAgICAgZm9yIChpbnQgaT1rcy5sZW5ndGgtMTsgaT49MDsgaS0tICkgeworICAgICAgICAgICAga3NbaV0gPSBycFRtcC5nZXRMb3dlc3RTZXRCaXQoKTsKKyAgICAgICAgICAgIHJwVG1wID0gcnBUbXAuY2xlYXJCaXQoa3NbaV0pOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgRUNGaWVsZEYybX0gd2l0aCB7QGNvZGUgMl5tfSBlbGVtZW50cyB3aXRoCisgICAgICogYSBwb2x5bm9taWFsIGJhc2lzIGFuZCB0aGUgcmVkdWN0aW9uIHBvbHlub21pYWwgYmFzZWQgb24ge0Bjb2RlIGtzfS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcmVkdWN0aW9uIHBvbHlub21pYWwgbXVzdCBiZSBlaXRoZXIgPGk+dHJpbm9taWFsPC9pPiBvcgorICAgICAqIDxpPnBlbnRhbm9taWFsPC9pPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtCisgICAgICogICAgICAgICAgICB0aGUgZXhwb25lbnQge0Bjb2RlIG19IGZvciB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzLgorICAgICAqIEBwYXJhbSBrcworICAgICAqICAgICAgICAgICAgdGhlIGJhc2Ugb2YgdGhlIHJlZHVjdGlvbiBwb2x5bm9taWFsIHdpdGggY29lZmZpY2llbnRzCisgICAgICogICAgICAgICAgICBnaXZlbiBpbiBkZXNjZW5kaW5nIG9yZGVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG0gPD0gemVyb30gb3IgdGhlIHJlZHVjdGlvbiBwb2x5bm9taWFsIGlzIG5vdAorICAgICAqICAgICAgICAgICAgIHZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyBFQ0ZpZWxkRjJtKGludCBtLCBpbnRbXSBrcykgeworICAgICAgICB0aGlzLm0gPSBtOworICAgICAgICBpZiAodGhpcy5tIDw9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm0gPD0gMCIpOworICAgICAgICB9CisgICAgICAgIC8vIERlZmVuc2l2ZWx5IGNvcGllcyBhcnJheSBwYXJhbWV0ZXIKKyAgICAgICAgLy8gdG8gcHJldmVudCBzdWJzZXF1ZW50IG1vZGlmaWNhdGlvbi4KKyAgICAgICAgLy8gTlBFIGFzIHNwZWNpZmllZCBpZiBrcyBpcyBudWxsCisgICAgICAgIHRoaXMua3MgPSBuZXcgaW50W2tzLmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoa3MsIDAsIHRoaXMua3MsIDAsIHRoaXMua3MubGVuZ3RoKTsKKworICAgICAgICAvLyBubyBuZWVkIHRvIGNoZWNrIGZvciBudWxsIGFscmVhZHkKKyAgICAgICAgaWYgKHRoaXMua3MubGVuZ3RoICE9IFRQQl9NSURfTEVOICYmIHRoaXMua3MubGVuZ3RoICE9IFBQQl9NSURfTEVOKSB7CisgICAgICAgICAgICAvLyBtdXN0IGJlIGVpdGhlciB0cmlub21pYWwgb3IgcGVudGFub21pYWwgYmFzaXMKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInRoZSBsZW5ndGggb2Yga3MgaXMgaW52YWxpZCIpOworICAgICAgICB9CisgICAgICAgIC8vIHRyaW5vbWlhbCBiYXNpczoKKyAgICAgICAgLy8gY2hlY2sgdGhhdCBtID4gayA+PSAxLCB3aGVyZSBrIGlzIGtzWzBdCisgICAgICAgIC8vIHBlbnRhbm9taWFsIGJhc2lzOgorICAgICAgICAvLyBjaGVjayB0aGF0IG0gPiBrMyA+IGsyID4gazEgPj0gMQorICAgICAgICAvLyBhbmQga3ggaW4gZGVzY2VuZGluZyBvcmRlciwgd2hlcmUKKyAgICAgICAgLy8gazMgaXMga3NbMF0sIGsyIGlzIGtzWzFdLCBrMSBpcyBrc1syXQorICAgICAgICBib29sZWFuIGNoZWNrRmFpbGVkID0gZmFsc2U7CisgICAgICAgIGludCBwcmV2ID0gdGhpcy5tOworICAgICAgICBmb3IgKGludCBpPTA7IGk8dGhpcy5rcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKHRoaXMua3NbaV0gPCBwcmV2KSB7CisgICAgICAgICAgICAgICAgcHJldiA9IHRoaXMua3NbaV07CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjaGVja0ZhaWxlZCA9IHRydWU7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2hlY2tGYWlsZWQgfHwgcHJldiA8IDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImtzIGlzIGludmFsaWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFNldHVwIHJwIHVzaW5nIGtzOgorICAgICAgICAvLyBiaXRzIDAgYW5kIG0gYWx3YXlzIHNldAorICAgICAgICBCaWdJbnRlZ2VyIHJwVG1wID0gQmlnSW50ZWdlci5PTkUuc2V0Qml0KHRoaXMubSk7CisgICAgICAgIC8vIHNldCByZW1haW5pbmcgYml0cyBhY2NvcmRpbmcgdG8ga3MKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPHRoaXMua3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHJwVG1wID0gcnBUbXAuc2V0Qml0KHRoaXMua3NbaV0pOworICAgICAgICB9CisgICAgICAgIHJwID0gcnBUbXA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGVxdWFscyB0byB0aGlzIGZpbml0ZSBmaWVsZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB0byB0aGlzIGZpbml0ZSBmaWVsZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBlcXVhbCB0byB0aGlzIGZpbml0ZSBmaWVsZCwKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgIC8vIG9iamVjdCBlcXVhbHMgdG8gaXRzZWxmCisgICAgICAgIGlmICh0aGlzID09IG9iaikgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIEVDRmllbGRGMm0pIHsKKyAgICAgICAgICAgIEVDRmllbGRGMm0gbyA9IChFQ0ZpZWxkRjJtKW9iajsKKyAgICAgICAgICAgIC8vIGNoZWNrIG0KKyAgICAgICAgICAgIGlmICh0aGlzLm0gPT0gby5tKSB7CisgICAgICAgICAgICAgICAgLy8gY2hlY2sgcnAKKyAgICAgICAgICAgICAgICBpZiAodGhpcy5ycCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChvLnJwID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpZWxkcyBib3RoIHdpdGggbm9ybWFsIGJhc2lzCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGF0IGxlYXN0IHRoaXMgZmllbGQgd2l0aCBwb2x5bm9taWFsIGJhc2lzCisgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgcnAgbWF0Y2gKKyAgICAgICAgICAgICAgICAgICAgLy8gcmV0dXJuIHRoaXMucnAuZXF1YWxzKG8ucnApOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscyh0aGlzLmtzLCBvLmtzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNpemUgb2YgdGhpcyBmaW5pdGUgZmllbGQgKGluIGJpdHMpLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc2l6ZSBvZiB0aGlzIGZpbml0ZSBmaWVsZCAoaW4gYml0cykuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRGaWVsZFNpemUoKSB7CisgICAgICAgIHJldHVybiBtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGV4cG9uZW50IHtAY29kZSBtfSBmb3IgdGhpcyBmaW5pdGUgZmllbGQsIHdpdGgge0Bjb2RlIDJebX0gYXMKKyAgICAgKiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZXhwb25lbnQge0Bjb2RlIG19IGZvciB0aGlzIGZpbml0ZSBmaWVsZAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TSgpIHsKKyAgICAgICAgcmV0dXJuIG07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhlIGludGVnZXIgYXJyYXkgY29udGFpbmluZyB0aGUgb3JkZXIgb2YgdGhlIG1pZGRsZQorICAgICAqIHRlcm0ocykgb2YgdGhlIHJlZHVjdGlvbiBwb2x5bm9taWFsIGZvciBhIHBvbHlub21pYWwgYmFzaXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGUgaW50ZWdlciBhcnJheSBjb250YWluaW5nIHRoZSBvcmRlciBvZiB0aGUgbWlkZGxlCisgICAgICogICAgICAgICB0ZXJtKHMpIG9mIHRoZSByZWR1Y3Rpb24gcG9seW5vbWlhbCBmb3IgYSBwb2x5bm9taWFsIGJhc2lzIG9yCisgICAgICogICAgICAgICB7QGNvZGUgbnVsbH0gZm9yIGEgbm9ybWFsIGJhc2lzLgorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSBnZXRNaWRUZXJtc09mUmVkdWN0aW9uUG9seW5vbWlhbCgpIHsKKyAgICAgICAgLy8gRGVmZW5zaXZlbHkgY29waWVzIHByaXZhdGUgYXJyYXkKKyAgICAgICAgLy8gdG8gcHJldmVudCBzdWJzZXF1ZW50IG1vZGlmaWNhdGlvbgorICAgICAgICAvLyB3YXM6IHJldHVybiBrcyA9PSBudWxsID8gbnVsbCA6IChpbnRbXSlrcy5jbG9uZSgpOworICAgICAgICBpZiAoa3MgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpbnRbXSByZXQgPSBuZXcgaW50W2tzLmxlbmd0aF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGtzLCAwLCByZXQsIDAsIHJldC5sZW5ndGgpOworICAgICAgICAgICAgcmV0dXJuIHJldDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGJhc2Ugb2YgdGhlIHJlZHVjdGlvbiBwb2x5bm9taWFsIHdpdGggdGhlIG4tdGggYml0CisgICAgICogY29ycmVzcG9uZGluZyB0byB0aGUgbi10aCBjb2VmZmljaWVudCBvZiB0aGUgcmVkdWN0aW9uIHBvbHlub21pYWwgZm9yIGEKKyAgICAgKiBwb2x5bm9taWFsIGJhc2lzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYmFzZSBvZiB0aGUgcmVkdWN0aW9uIHBvbHlub21pYWwgd2l0aCB0aGUgbi10aCBiaXQKKyAgICAgKiAgICAgICAgIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG4tdGggY29lZmZpY2llbnQgb2YgdGhlIHJlZHVjdGlvbiBwb2x5bm9taWFsCisgICAgICogICAgICAgICBmb3IgYSBwb2x5bm9taWFsIGJhc2lzIG9yIHtAY29kZSBudWxsfSBmb3IgYSBub3JtYWwgYmFzaXMuCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0UmVkdWN0aW9uUG9seW5vbWlhbCgpIHsKKyAgICAgICAgcmV0dXJuIHJwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhhc2hjb2RlIHZhbHVlIGZvciB0aGlzIGZpbml0ZSBmaWVsZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhhc2hjb2RlIHZhbHVlIGZvciB0aGlzIGZpbml0ZSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gcnAgPT0gbnVsbCA/IG0gOiBtICsgcnAuaGFzaENvZGUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0VDRmllbGRGcC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9FQ0ZpZWxkRnAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZWM3NTVhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9FQ0ZpZWxkRnAuamF2YQpAQCAtMCwwICsxLDk1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworCisvKioKKyAqIFRoZSBwYXJhbWV0ZXJzIHNwZWNpZnlpbmcgYSA8aT5wcmltZSBmaW5pdGUgZmllbGQ8L2k+IG9mIGFuCisgKiBlbGxpcHRpYyBjdXJ2ZS4KKyAqLworcHVibGljIGNsYXNzIEVDRmllbGRGcCBpbXBsZW1lbnRzIEVDRmllbGQgeworICAgIC8vIFByaW1lCisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIHA7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHByaW1lIGZpbml0ZSBmaWVsZCBvZiBhbiBlbGxpcHRpYyBjdXJ2ZSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBwcmltZSB7QGNvZGUgcH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcAorICAgICAqICAgICAgICAgICAgdGhlIHByaW1lIHZhbHVlIHtAY29kZSBwfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBwIDw9IHplcm99LgorICAgICAqLworICAgIHB1YmxpYyBFQ0ZpZWxkRnAoQmlnSW50ZWdlciBwKSB7CisgICAgICAgIHRoaXMucCA9IHA7CisKKyAgICAgICAgaWYgKHRoaXMucCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInAgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLnAuc2lnbnVtKCkgIT0gMSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicCA8PSAwIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzaXplIG9mIHRoZSBmaW5pdGUgZmllbGQgKGluIGJpdHMpLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc2l6ZSBvZiB0aGUgZmluaXRlIGZpZWxkIChpbiBiaXRzKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEZpZWxkU2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIHAuYml0TGVuZ3RoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJpbWUgdmFsdWUge0Bjb2RlIHB9IGZvciB0aGlzIGZpbml0ZSBmaWVsZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByaW1lIHZhbHVlIHtAY29kZSBwfSBmb3IgdGhpcyBmaW5pdGUgZmllbGQuCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0UCgpIHsKKyAgICAgICAgcmV0dXJuIHA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMgZmluaXRlIGZpZWxkLgorICAgICAqCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHRvIHRoaXMgZmluaXRlIGZpZWxkLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMgZmluaXRlIGZpZWxkLAorICAgICAqICAgICAgICAgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgLy8gb2JqZWN0IGVxdWFscyBpdHNlbGYKKyAgICAgICAgaWYgKHRoaXMgPT0gb2JqKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgRUNGaWVsZEZwKSB7CisgICAgICAgICAgICByZXR1cm4gKHRoaXMucC5lcXVhbHMoKChFQ0ZpZWxkRnApb2JqKS5wKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhhc2hjb2RlIHZhbHVlIGZvciB0aGlzIGZpbml0ZSBmaWVsZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhhc2hjb2RlIHZhbHVlIGZvciB0aGlzIGZpbml0ZSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gcC5oYXNoQ29kZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvRUNHZW5QYXJhbWV0ZXJTcGVjLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0VDR2VuUGFyYW1ldGVyU3BlYy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZlNjZiMWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0VDR2VuUGFyYW1ldGVyU3BlYy5qYXZhCkBAIC0wLDAgKzEsNTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5zcGVjOworCisvKioKKyAqIFRoZSBwYXJhbWV0ZXIgc3BlY2lmaWNhdGlvbiB1c2VkIHRvIGdlbmVyYXRlIGVsbGlwdGljIGN1cnZlIGRvbWFpbiBwYXJhbWV0ZXJzLgorICovCitwdWJsaWMgY2xhc3MgRUNHZW5QYXJhbWV0ZXJTcGVjIGltcGxlbWVudHMgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyB7CisgICAgLy8gU3RhbmRhcmQgKG9yIHByZWRlZmluZWQpIG5hbWUgZm9yIEVDIGRvbWFpbgorICAgIC8vIHBhcmFtZXRlcnMgdG8gYmUgZ2VuZXJhdGVkCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbmFtZTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEVDR2VuUGFyYW1ldGVyU3BlY30gd2l0aCB0aGUgc3BlY2lmaWVkIHN0YW5kYXJkIG9yCisgICAgICogcHJlZGVmaW5lZCBuYW1lIG9mIHRoZSB0by1iZS1nZW5lcmF0ZWQgZG9tYWluIHBhcmFtZXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZWxsaXB0aWMgY3VydmUgZG9tYWluIHBhcmFtZXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgRUNHZW5QYXJhbWV0ZXJTcGVjKFN0cmluZyBuYW1lKSB7CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgIGlmICh0aGlzLm5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIChzdGFuZGFyZCBvciBwcmVkZWZpbmVkKSBvZiB0aGUgdG8tYmUtZ2VuZXJhdGVkIGVsbGlwdGljCisgICAgICogY3VydmUgZG9tYWluIHBhcmFtZXRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvRUNQYXJhbWV0ZXJTcGVjLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0VDUGFyYW1ldGVyU3BlYy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZhMDMzZTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0VDUGFyYW1ldGVyU3BlYy5qYXZhCkBAIC0wLDAgKzEsMTExIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworCisvKioKKyAqIFRoZSBwYXJhbWV0ZXIgc3BlY2lmaWNhdGlvbiB1c2VkIHdpdGggRWxsaXB0aWMgQ3VydmUgQ3J5cHRvZ3JhcGh5IChFQ0MpLgorICovCitwdWJsaWMgY2xhc3MgRUNQYXJhbWV0ZXJTcGVjIGltcGxlbWVudHMgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyB7CisgICAgLy8gRWxsaXB0aWMgY3VydmUgZm9yIHdoaWNoIHRoaXMgaXMgcGFyYW1ldGVyCisgICAgcHJpdmF0ZSBmaW5hbCBFbGxpcHRpY0N1cnZlIGN1cnZlOworICAgIC8vIERpc3Rpbmd1aXNoZWQgcG9pbnQgb24gdGhlIGVsbGlwdGljIGN1cnZlIGNhbGxlZCBnZW5lcmF0b3Igb3IgYmFzZSBwb2ludAorICAgIHByaXZhdGUgZmluYWwgRUNQb2ludCBnZW5lcmF0b3I7CisgICAgLy8gT3JkZXIgb2YgdGhlIGdlbmVyYXRvcgorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBvcmRlcjsKKyAgICAvLyBDb2ZhY3RvcgorICAgIHByaXZhdGUgZmluYWwgaW50IGNvZmFjdG9yOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgRUNQYXJhbWV0ZXJTcGVjfSB3aXRoIHRoZSBzcGVjaWZpZWQgZWxsaXB0aWMgY3VydmUsCisgICAgICogdGhlIGJhc2UgcG9pbnQsIHRoZSBvcmRlciBvZiB0aGUgZ2VuZXJhdG9yIChvciBiYXNlIHBvaW50KSBhbmQgdGhlCisgICAgICogY28tZmFjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGN1cnZlCisgICAgICogICAgICAgICAgICB0aGUgZWxsaXB0aWMgY3VydmUuCisgICAgICogQHBhcmFtIGdlbmVyYXRvcgorICAgICAqICAgICAgICAgICAgdGhlIGdlbmVyYXRvciAob3IgYmFzZSBwb2ludCkuCisgICAgICogQHBhcmFtIG9yZGVyCisgICAgICogICAgICAgICAgICB0aGUgb3JkZXIgb2YgdGhlIGdlbmVyYXRvci4KKyAgICAgKiBAcGFyYW0gY29mYWN0b3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBjby1mYWN0b3IuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb3JkZXIgPD0gemVyb30gb3Ige0Bjb2RlIGNvZmFjdG9yIDw9IHplcm99LgorICAgICAqLworICAgIHB1YmxpYyBFQ1BhcmFtZXRlclNwZWMoRWxsaXB0aWNDdXJ2ZSBjdXJ2ZSwgRUNQb2ludCBnZW5lcmF0b3IsCisgICAgICAgICAgICBCaWdJbnRlZ2VyIG9yZGVyLCBpbnQgY29mYWN0b3IpIHsKKyAgICAgICAgdGhpcy5jdXJ2ZSA9IGN1cnZlOworICAgICAgICB0aGlzLmdlbmVyYXRvciA9IGdlbmVyYXRvcjsKKyAgICAgICAgdGhpcy5vcmRlciA9IG9yZGVyOworICAgICAgICB0aGlzLmNvZmFjdG9yID0gY29mYWN0b3I7CisgICAgICAgIC8vIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGN1cnZlLCBnZW5lcmF0b3Igb3Igb3JkZXIgaXMgbnVsbAorICAgICAgICBpZiAodGhpcy5jdXJ2ZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImN1cnZlID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodGhpcy5nZW5lcmF0b3IgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJnZW5lcmF0b3IgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLm9yZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigib3JkZXIgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIC8vIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBvcmRlciBvciBjb2ZhY3RvciBpcyBub3QgcG9zaXRpdmUKKyAgICAgICAgaWYgKCEodGhpcy5vcmRlci5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSA+IDApKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJvcmRlciA8PSAwIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCEodGhpcy5jb2ZhY3RvciA+IDApKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJjb2ZhY3RvciA8PSAwIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgY29mYWN0b3J9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIGNvZmFjdG9yfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldENvZmFjdG9yKCkgeworICAgICAgICByZXR1cm4gY29mYWN0b3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZWxsaXB0aWMgY3VydmUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBlbGxpcHRpYyBjdXJ2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRWxsaXB0aWNDdXJ2ZSBnZXRDdXJ2ZSgpIHsKKyAgICAgICAgcmV0dXJuIGN1cnZlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGdlbmVyYXRvciAob3IgYmFzZSBwb2ludCkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBnZW5lcmF0b3IgKG9yIGJhc2UgcG9pbnQpLgorICAgICAqLworICAgIHB1YmxpYyBFQ1BvaW50IGdldEdlbmVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIGdlbmVyYXRvcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBvcmRlciBvZiB0aGUgZ2VuZXJhdG9yLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgb3JkZXIgb2YgdGhlIGdlbmVyYXRvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRPcmRlcigpIHsKKyAgICAgICAgcmV0dXJuIG9yZGVyOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvRUNQb2ludC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9FQ1BvaW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWMwYjU3NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvRUNQb2ludC5qYXZhCkBAIC0wLDAgKzEsMTE2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworCisvKioKKyAqIEEgUG9pbnQgb24gYW4gRWxsaXB0aWMgQ3VydmUgaW4gYmFyeWNlbnRyaWMgKG9yIGFmZmluZSkgY29vcmRpbmF0ZXMuCisgKi8KK3B1YmxpYyBjbGFzcyBFQ1BvaW50IHsKKworICAgIC8qKgorICAgICAqIFRoZSBwb2ludCBvbiBhbiBFbGxpcHRpYyBDdXJ2ZSBhdCBpbmZpbml0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEVDUG9pbnQgUE9JTlRfSU5GSU5JVFkgPSBuZXcgRUNQb2ludCgpOworICAgIC8vIGFmZmluZSBYIGNvb3JkaW5hdGUgb2YgdGhpcyBwb2ludAorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBhZmZpbmVYOworICAgIC8vIGFmZmluZSBZIGNvb3JkaW5hdGUgb2YgdGhpcyBwb2ludAorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBhZmZpbmVZOworCisgICAgLy8gUHJpdmF0ZSBjdG9yIGZvciBQT0lOVF9JTkZJTklUWQorICAgIHByaXZhdGUgRUNQb2ludCgpIHsKKyAgICAgICAgYWZmaW5lWCA9IG51bGw7CisgICAgICAgIGFmZmluZVkgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgcG9pbnQgYXQgdGhlIHNwZWNpZmllZCBjb29yZGluYXRlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhZmZpbmVYCisgICAgICogICAgICAgICAgICB0aGUgeC1jb29yZGluYXRlLgorICAgICAqIEBwYXJhbSBhZmZpbmVZCisgICAgICogICAgICAgICAgICB0aGUgeS1jb29yZGluYXRlLgorICAgICAqLworICAgIHB1YmxpYyBFQ1BvaW50KEJpZ0ludGVnZXIgYWZmaW5lWCwgQmlnSW50ZWdlciBhZmZpbmVZKSB7CisgICAgICAgIHRoaXMuYWZmaW5lWCA9IGFmZmluZVg7CisgICAgICAgIGlmICh0aGlzLmFmZmluZVggPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJhZmZpbmVYID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmFmZmluZVkgPSBhZmZpbmVZOworICAgICAgICBpZiAodGhpcy5hZmZpbmVZID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiYWZmaW5lWSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB4LWNvb3JkaW5hdGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB4LWNvb3JkaW5hdGUsIG9yIHtAY29kZSBudWxsfSBmb3IgdGhlIGluZmluaXRlIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldEFmZmluZVgoKSB7CisgICAgICAgIHJldHVybiBhZmZpbmVYOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHktY29vcmRpbmF0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHktY29vcmRpbmF0ZSwgb3Ige0Bjb2RlIG51bGx9IGZvdCB0aGUgaW5maW5pdGUgcG9pbnQuCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0QWZmaW5lWSgpIHsKKyAgICAgICAgcmV0dXJuIGFmZmluZVk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFuZCB0aGlzIGVsbGlwdGljIGN1cnZlIHBvaW50IGFyZQorICAgICAqIGVxdWFsLgorICAgICAqCisgICAgICogQHBhcmFtIG90aGVyCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgYW5kIHRoaXMgZWxsaXB0aWMgY3VydmUKKyAgICAgKiAgICAgICAgIHBvaW50IGFyZSBlcXVhbCwgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgeworICAgICAgICBpZiAodGhpcyA9PSBvdGhlcikgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgRUNQb2ludCkgeworICAgICAgICAgICAgaWYgKHRoaXMuYWZmaW5lWCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgRUNQb2ludCBvdGhlclBvaW50ID0gKEVDUG9pbnQpb3RoZXI7CisgICAgICAgICAgICAgICAgLy8gbm8gbmVlZCB0byBjaGVjayBmb3IgbnVsbCBpbiB0aGlzIGNhc2UKKyAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZmZpbmVYLmVxdWFscyhvdGhlclBvaW50LmFmZmluZVgpICYmCisgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWZmaW5lWS5lcXVhbHMob3RoZXJQb2ludC5hZmZpbmVZKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG90aGVyID09IFBPSU5UX0lORklOSVRZOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBoYXNoY29kZSBvZiB0aGlzIGVsbGlwdGljIGN1cnZlIHBvaW50LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGFzaGNvZGUgb2YgdGhpcyBlbGxpcHRpYyBjdXJ2ZSBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBpZiAodGhpcy5hZmZpbmVYICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBhZmZpbmVYLmhhc2hDb2RlKCkgKiAzMSArIGFmZmluZVkuaGFzaENvZGUoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gMTE7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9FQ1ByaXZhdGVLZXlTcGVjLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0VDUHJpdmF0ZUtleVNwZWMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMjAwZTcwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9FQ1ByaXZhdGVLZXlTcGVjLmphdmEKQEAgLTAsMCArMSw2OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LnNwZWM7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKKworLyoqCisgKiBUaGUgcGFyYW1ldGVycyBzcGVjaWZ5aW5nIGFuIEVsbGlwdGljIEN1cnZlIChFQykgcHJpdmF0ZSBrZXkuCisgKi8KK3B1YmxpYyBjbGFzcyBFQ1ByaXZhdGVLZXlTcGVjIGltcGxlbWVudHMgS2V5U3BlYyB7CisgICAgLy8gUHJpdmF0ZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBrZXkKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgczsKKyAgICAvLyBFbGxpcHRpYyBDdXJ2ZSBkb21haW4gcGFyYW1ldGVycyBhc3NvY2lhdGVkIHdpdGggdGhpcyBrZXkKKyAgICBwcml2YXRlIGZpbmFsIEVDUGFyYW1ldGVyU3BlYyBwYXJhbXM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBFQ1ByaXZhdGVLZXlTcGVjfSB3aXRoIHRoZSBzcGVjaWZpZWQgcHJpdmF0ZSB2YWx1ZQorICAgICAqIHtAY29kZSBTfSBhbmQgcGFyYW1ldGVyIHNwZWNpZmljYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIHByaXZhdGUgdmFsdWUge0Bjb2RlIFN9LgorICAgICAqIEBwYXJhbSBwYXJhbXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb21haW4gcGFyYW1ldGVyIHNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIEVDUHJpdmF0ZUtleVNwZWMoQmlnSW50ZWdlciBzLCBFQ1BhcmFtZXRlclNwZWMgcGFyYW1zKSB7CisgICAgICAgIHRoaXMucyA9IHM7CisgICAgICAgIHRoaXMucGFyYW1zID0gcGFyYW1zOworICAgICAgICAvLyB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBzIG9yIHBhcmFtcyBpcyBudWxsCisgICAgICAgIGlmICh0aGlzLnMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJzID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodGhpcy5wYXJhbXMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJwYXJhbXMgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZG9tYWluIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZG9tYWluIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBFQ1BhcmFtZXRlclNwZWMgZ2V0UGFyYW1zKCkgeworICAgICAgICByZXR1cm4gcGFyYW1zOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByaXZhdGUgdmFsdWUge0Bjb2RlIFN9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJpdmF0ZSB2YWx1ZSB7QGNvZGUgU30uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0UygpIHsKKyAgICAgICAgcmV0dXJuIHM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9FQ1B1YmxpY0tleVNwZWMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvRUNQdWJsaWNLZXlTcGVjLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGE1MzM0YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvRUNQdWJsaWNLZXlTcGVjLmphdmEKQEAgLTAsMCArMSw3MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LnNwZWM7CisKKy8qKgorICogVGhlIHBhcmFtZXRlcnMgc3BlY2lmeWluZyBhbiBFbGxpcHRpYyBDdXJ2ZSAoRUMpIHB1YmxpYyBrZXkuCisgKi8KK3B1YmxpYyBjbGFzcyBFQ1B1YmxpY0tleVNwZWMgaW1wbGVtZW50cyBLZXlTcGVjIHsKKyAgICAvLyBUaGUgcHVibGljIHBvaW50CisgICAgcHJpdmF0ZSBmaW5hbCBFQ1BvaW50IHc7CisgICAgLy8gVGhlIGFzc29jaWF0ZWQgZWxsaXB0aWMgY3VydmUgZG9tYWluIHBhcmFtZXRlcnMKKyAgICBwcml2YXRlIGZpbmFsIEVDUGFyYW1ldGVyU3BlYyBwYXJhbXM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBFQ1B1YmxpY0tleX0gd2l0aCB0aGUgc3BlY2lmaWVkIHB1YmxpYyBlbGxpcHRpYworICAgICAqIGN1cnZlIHBvaW50IGFuZCBwYXJhbWV0ZXIgc3BlY2lmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgICB0aGUgcHVibGljIGVsbGlwdGljIGN1cnZlIHBvaW50IHtAY29kZSBXfS4KKyAgICAgKiBAcGFyYW0gcGFyYW1zCisgICAgICogICAgICAgICAgICB0aGUgZG9tYWluIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwb2ludCB7QGNvZGUgV30gaXMgYXQgaW5maW5pdHkuCisgICAgICovCisgICAgcHVibGljIEVDUHVibGljS2V5U3BlYyhFQ1BvaW50IHcsIEVDUGFyYW1ldGVyU3BlYyBwYXJhbXMpIHsKKyAgICAgICAgdGhpcy53ID0gdzsKKyAgICAgICAgdGhpcy5wYXJhbXMgPSBwYXJhbXM7CisgICAgICAgIC8vIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHcgb3IgcGFyYW1zIGlzIG51bGwKKyAgICAgICAgaWYgKHRoaXMudyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIncgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLnBhcmFtcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInBhcmFtcyA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgLy8gdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHcgaXMgcG9pbnQgYXQgaW5maW5pdHkKKyAgICAgICAgaWYgKHRoaXMudy5lcXVhbHMoRUNQb2ludC5QT0lOVF9JTkZJTklUWSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInRoZSB3IHBhcmFtZXRlciBpcyBwb2ludCBhdCBpbmZpbml0eSIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZG9tYWluIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZG9tYWluIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBFQ1BhcmFtZXRlclNwZWMgZ2V0UGFyYW1zKCkgeworICAgICAgICByZXR1cm4gcGFyYW1zOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHB1YmxpYyBlbGxpcHRpYyBjdXJ2ZSBwb2ludCB7QGNvZGUgV30uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwdWJsaWMgZWxsaXB0aWMgY3VydmUgcG9pbnQge0Bjb2RlIFd9LgorICAgICAqLworICAgIHB1YmxpYyBFQ1BvaW50IGdldFcoKSB7CisgICAgICAgIHJldHVybiB3OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvRWxsaXB0aWNDdXJ2ZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9FbGxpcHRpY0N1cnZlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmVlYjBjNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvRWxsaXB0aWNDdXJ2ZS5qYXZhCkBAIC0wLDAgKzEsMjA2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogQW4gRWxsaXB0aWMgQ3VydmUgd2l0aCBpdHMgbmVjZXNzYXJ5IHZhbHVlcy4KKyAqLworcHVibGljIGNsYXNzIEVsbGlwdGljQ3VydmUgeworCisgICAgLy8gVW5kZXJseWluZyBmaW5pdGUgZmllbGQKKyAgICBwcml2YXRlIGZpbmFsIEVDRmllbGQgZmllbGQ7CisKKyAgICAvLyBUaGUgZmlyc3QgY29lZmZpY2llbnQgb2YgdGhlIGVxdWF0aW9uIGRlZmluaW5nIHRoaXMgZWxsaXB0aWMgY3VydmUKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgYTsKKworICAgIC8vIFRoZSBzZWNvbmQgY29lZmZpY2llbnQgb2YgdGhlIGVxdWF0aW9uIGRlZmluaW5nIHRoaXMgZWxsaXB0aWMgY3VydmUKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgYjsKKworICAgIC8vIEJ5dGVzIHVzZWQgZHVyaW5nIHRoaXMgZWxsaXB0aWMgY3VydmUgZ2VuZXJhdGlvbiwKKyAgICAvLyBpZiBpdCB3YXMgZ2VuZXJhdGVkIHJhbmRvbWx5CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gc2VlZDsKKworICAgIC8vIEhhc2ggY29kZQorICAgIHByaXZhdGUgdm9sYXRpbGUgaW50IGhhc2g7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBFbGxpcHRpY0N1cnZlfSB3aXRoIHRoZSBzcGVjaWZpZWQgZmllbGQsCisgICAgICogY29lZmZpY2llbnRzIGFuZCBzZWVkLgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICB0aGUgZmluaXRlIGZpZWxkIG9mIHRoaXMgZWxsaXB0aWMgY3VydmUuCisgICAgICogQHBhcmFtIGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2VmZmljaWVudCB7QGNvZGUgYX0uCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2VmZmljaWVudCB7QGNvZGUgYn0uCisgICAgICogQHBhcmFtIHNlZWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWVkIHVzZWQgZm9yIHRoZSBnZW5lcmF0aW9uIG9mIHRoZSBjdXJ2ZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgY29lZmZpY2llbnRzIGFyZSBub3QgaW4gdGhlIHNwZWNpZmllZCBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRWxsaXB0aWNDdXJ2ZShFQ0ZpZWxkIGZpZWxkLCBCaWdJbnRlZ2VyIGEsIEJpZ0ludGVnZXIgYiwgYnl0ZVtdIHNlZWQpIHsKKyAgICAgICAgdGhpcy5maWVsZCA9IGZpZWxkOworICAgICAgICBpZiAodGhpcy5maWVsZCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImZpZWxkID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmEgPSBhOworICAgICAgICBpZiAodGhpcy5hID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiYSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5iID0gYjsKKyAgICAgICAgaWYgKHRoaXMuYiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImIgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIC8vIG1ha2UgZGVmZW5zaXZlIGNvcHkKKyAgICAgICAgaWYgKHNlZWQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhpcy5zZWVkID0gbnVsbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRoaXMuc2VlZCA9IG5ldyBieXRlW3NlZWQubGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2VlZCwgMCwgdGhpcy5zZWVkLCAwLCB0aGlzLnNlZWQubGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICAvLyBjaGVjayBwYXJhbWV0ZXJzIGZvciBFQ0ZpZWxkRnAgYW5kIEVDRmllbGRGMm0uCisgICAgICAgIC8vIENoZWNrIGludmFyaWFudDogYSBhbmQgYiBtdXN0IGJlIGluIHRoZSBmaWVsZC4KKyAgICAgICAgLy8gQ2hlY2sgY29uZGl0aW9ucyBmb3IgY3VzdG9tIEVDRmllbGQgYXJlIG5vdCBzcGVjaWZpZWQuCisgICAgICAgIGlmICh0aGlzLmZpZWxkIGluc3RhbmNlb2YgRUNGaWVsZEZwKSB7CisgICAgICAgICAgICBCaWdJbnRlZ2VyIHAgPSAoKEVDRmllbGRGcCkgdGhpcy5maWVsZCkuZ2V0UCgpOworICAgICAgICAgICAgaWYgKHRoaXMuYS5zaWdudW0oKSA8IDAgfHwgdGhpcy5hLmNvbXBhcmVUbyhwKSA+PSAwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigidGhlIGEgaXMgbm90IGluIHRoZSBmaWVsZCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHRoaXMuYi5zaWdudW0oKSA8IDAgfHwgdGhpcy5iLmNvbXBhcmVUbyhwKSA+PSAwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigidGhlIGIgaXMgbm90IGluIHRoZSBmaWVsZCIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZmllbGQgaW5zdGFuY2VvZiBFQ0ZpZWxkRjJtKSB7CisgICAgICAgICAgICBpbnQgZmllbGRTaXplSW5CaXRzID0gdGhpcy5maWVsZC5nZXRGaWVsZFNpemUoKTsKKyAgICAgICAgICAgIGlmICghKHRoaXMuYS5iaXRMZW5ndGgoKSA8PSBmaWVsZFNpemVJbkJpdHMpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigidGhlIGEgaXMgbm90IGluIHRoZSBmaWVsZCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCEodGhpcy5iLmJpdExlbmd0aCgpIDw9IGZpZWxkU2l6ZUluQml0cykpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ0aGUgYiBpcyBub3QgaW4gdGhlIGZpZWxkIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBFbGxpcHRpY0N1cnZlfSB3aXRoIHRoZSBzcGVjaWZpZWQgZmllbGQgYW5kCisgICAgICogY29lZmZpY2llbnRzLgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICB0aGUgZmluaXRlIGZpZWxkIG9mIHRoaXMgZWxsaXB0aWMgY3VydmUuCisgICAgICogQHBhcmFtIGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2VmZmljaWVudCB7QGNvZGUgYX0uCisgICAgICogQHBhcmFtIGIKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2VmZmljaWVudCB7QGNvZGUgYn0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGNvZWZmaWNpZW50cyBhcmUgbm90IGluIHRoZSBzcGVjaWZpZWQgZmllbGQuCisgICAgICovCisgICAgcHVibGljIEVsbGlwdGljQ3VydmUoRUNGaWVsZCBmaWVsZCwgQmlnSW50ZWdlciBhLCBCaWdJbnRlZ2VyIGIpIHsKKyAgICAgICAgdGhpcyhmaWVsZCwgYSwgYiwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29lZmZpY2llbnQge0Bjb2RlIGF9IG9mIHRoaXMgZWxsaXB0aWMgY3VydmUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb2VmZmljaWVudCB7QGNvZGUgYX0gb2YgdGhpcyBlbGxpcHRpYyBjdXJ2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRBKCkgeworICAgICAgICByZXR1cm4gYTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb2VmZmljaWVudCB7QGNvZGUgYn0gb2YgdGhpcyBlbGxpcHRpYyBjdXJ2ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNvZWZmaWNpZW50IHtAY29kZSBifSBvZiB0aGlzIGVsbGlwdGljIGN1cnZlLgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldEIoKSB7CisgICAgICAgIHJldHVybiBiOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZpbml0ZSBmaWVsZCBvZiB0aGlzIGVsbGlwdGljIGN1cnZlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZmluaXRlIGZpZWxkIG9mIHRoaXMgZWxsaXB0aWMgY3VydmUuCisgICAgICovCisgICAgcHVibGljIEVDRmllbGQgZ2V0RmllbGQoKSB7CisgICAgICAgIHJldHVybiBmaWVsZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29weSBvZiB0aGUgc2VlZCB0aGF0IHdhcyB1c2VkIHRvIGdlbmVyYXRlIHRoaXMgZWxsaXB0aWMgY3VydmUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGUgc2VlZCB0aGF0IHdhcyB1c2VkIHRvIGdlbmVyYXRlIHRoaXMgZWxsaXB0aWMgY3VydmUsCisgICAgICogICAgICAgICBvciB7QGNvZGUgbnVsbH0gaWYgbm9uZSBzcGVjaWZpZWQuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRTZWVkKCkgeworICAgICAgICBpZiAoc2VlZCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIHJldHVybiBjb3B5CisgICAgICAgICAgICBieXRlW10gcmV0ID0gbmV3IGJ5dGVbc2VlZC5sZW5ndGhdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzZWVkLCAwLCByZXQsIDAsIHJldC5sZW5ndGgpOworICAgICAgICAgICAgcmV0dXJuIHJldDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgc3BlY2lmaWVkIG9iamVjdCBlcXVhbHMgdG8gdGhpcyBlbGxpcHRpYyBjdXJ2ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdGhlcgorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMgZWxsaXB0aWMKKyAgICAgKiAgICAgICAgIGN1cnZlLCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG90aGVyKSB7CisgICAgICAgIGlmICh0aGlzID09IG90aGVyKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIEVsbGlwdGljQ3VydmUpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgRWxsaXB0aWNDdXJ2ZSBvdGhlckVjID0gKEVsbGlwdGljQ3VydmUpIG90aGVyOworICAgICAgICByZXR1cm4gdGhpcy5maWVsZC5lcXVhbHMob3RoZXJFYy5maWVsZCkgJiYgdGhpcy5hLmVxdWFscyhvdGhlckVjLmEpCisgICAgICAgICAgICAgICAgJiYgdGhpcy5iLmVxdWFscyhvdGhlckVjLmIpCisgICAgICAgICAgICAgICAgJiYgQXJyYXlzLmVxdWFscyh0aGlzLnNlZWQsIG90aGVyRWMuc2VlZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaGFzaGNvZGUgb2YgdGhpcyBlbGxpcHRpYyBjdXJ2ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhhc2hjb2RlIG9mIHRoaXMgZWxsaXB0aWMgY3VydmUuCisgICAgICovCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgLy8gaGFzaCBpbml0IGlzIGRlbGF5ZWQKKyAgICAgICAgaWYgKGhhc2ggPT0gMCkgeworICAgICAgICAgICAgaW50IGhhc2gwID0gMTE7CisgICAgICAgICAgICBoYXNoMCA9IGhhc2gwICogMzEgKyBmaWVsZC5oYXNoQ29kZSgpOworICAgICAgICAgICAgaGFzaDAgPSBoYXNoMCAqIDMxICsgYS5oYXNoQ29kZSgpOworICAgICAgICAgICAgaGFzaDAgPSBoYXNoMCAqIDMxICsgYi5oYXNoQ29kZSgpOworICAgICAgICAgICAgaWYgKHNlZWQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2VlZC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBoYXNoMCA9IGhhc2gwICogMzEgKyBzZWVkW2ldOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaGFzaDAgPSBoYXNoMCAqIDMxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaGFzaCA9IGhhc2gwOworICAgICAgICB9CisgICAgICAgIHJldHVybiBoYXNoOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvRW5jb2RlZEtleVNwZWMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvRW5jb2RlZEtleVNwZWMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MzljNjBiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9FbmNvZGVkS2V5U3BlYy5qYXZhCkBAIC0wLDAgKzEsNjMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5zcGVjOworCisvKioKKyAqIFRoZSBhYnN0cmFjdCBrZXkgc3BlY2lmaWNhdGlvbiBmb3IgYSBwdWJsaWMgb3IgYSBwcml2YXRlIGtleSBpbiBlbmNvZGVkCisgKiBmb3JtYXQuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBFbmNvZGVkS2V5U3BlYyBpbXBsZW1lbnRzIEtleVNwZWMgeworICAgIC8vIEVuY29kZWQga2V5CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gZW5jb2RlZEtleTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEVuY29kZWRLZXlTcGVjfSB3aXRoIHRoZSBzcGVjaWZpZWQgZW5jb2RlZCBrZXkgYnl0ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW5jb2RlZEtleQorICAgICAqICAgICAgICAgICAgdGhlIGVuY29kZWQga2V5IGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBFbmNvZGVkS2V5U3BlYyhieXRlW10gZW5jb2RlZEtleSkgeworICAgICAgICAvLyBEZWZlbnNpdmVseSBjb3BpZXMgcGFyYW1ldGVyCisgICAgICAgIC8vIHRvIHByZXZlbnQgc3Vic2VxdWVudCBtb2RpZmljYXRpb24KKyAgICAgICAgdGhpcy5lbmNvZGVkS2V5ID0gbmV3IGJ5dGVbZW5jb2RlZEtleS5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVuY29kZWRLZXksIDAsCisgICAgICAgICAgICAgICAgdGhpcy5lbmNvZGVkS2V5LCAwLCB0aGlzLmVuY29kZWRLZXkubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBlbmNvZGVkIGtleSBieXRlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVuY29kZWQga2V5IGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgLy8gRGVmZW5zaXZlbHkgY29waWVzIHByaXZhdGUgYXJyYXkKKyAgICAgICAgLy8gdG8gcHJldmVudCBzdWJzZXF1ZW50IG1vZGlmaWNhdGlvbgorICAgICAgICBieXRlW10gcmV0ID0gbmV3IGJ5dGVbZW5jb2RlZEtleS5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVuY29kZWRLZXksIDAsIHJldCwgMCwgcmV0Lmxlbmd0aCk7CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgZW5jb2RpbmcgZm9ybWF0IG9mIHRoaXMgZW5jb2RlZCBrZXkKKyAgICAgKiBzcGVjaWZpY2F0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgZW5jb2RpbmcgZm9ybWF0IG9mIHRoaXMgZW5jb2RlZCBrZXkKKyAgICAgKiAgICAgICAgIHNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRGb3JtYXQoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvSW52YWxpZEtleVNwZWNFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvSW52YWxpZEtleVNwZWNFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNTcyOGY1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9JbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNzEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5zcGVjOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb247CisKKy8qKgorICogVGhlIGV4Y2VwdGlvbiB0aGF0IGlzIHRocm93biB3aGVuIGFuIGludmFsaWQga2V5IHNwZWNpZmljYXRpb24gaXMKKyAqIGVuY291bnRlcmVkLgorICovCitwdWJsaWMgY2xhc3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24gZXh0ZW5kcyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24geworCisgICAgLyoqCisgICAgICogVGhlIHNlcmlhbCB2ZXJzaW9uIGlkZW50aWZpZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzU0NjEzOTI5Mzk5ODgxMDc3OEw7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbn0gd2l0aCB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2Ugb2YgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKKyAgICAgICAgc3VwZXIobXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEludmFsaWRLZXlTcGVjRXhjZXB0aW9ufSB3aXRoIHRoZSBzcGVjaWZpZWQgbWVzc2FnZQorICAgICAqIGFuZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2Ugb2YgdGhpcyBleGNlcHRpb24uCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgY2F1c2Ugb2YgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEludmFsaWRLZXlTcGVjRXhjZXB0aW9ufSB3aXRoIHRoZSBzcGVjaWZpZWQgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYXVzZSBvZiB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW52YWxpZEtleVNwZWNFeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0ludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0ludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjNhODI5NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQ5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uOworCisvKioKKyAqIFRoZSBleGNlcHRpb24gdGhhdCBpcyB0aHJvd24gd2hlbiBhbiBpbnZhbGlkIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uIGlzCisgKiBlbmNvdW50ZXJlZC4KKyAqLworcHVibGljIGNsYXNzIEludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uIGV4dGVuZHMgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHsKKworICAgIC8qKgorICAgICAqIFRoZSBzZXJpYWwgdmVyc2lvbiBpZGVudGlmaWVyLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC05NzA0Njg3Njk1OTMzOTkzNDJMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0tleVNwZWMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvS2V5U3BlYy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZlOGRmMWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL0tleVNwZWMuamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuc3BlYzsKKworLyoqCisgKiBUaGUgbWFya2VyIGludGVyZmFjZSBmb3Iga2V5IHNwZWNpZmljYXRpb25zLiBUaGUgcHVycG9zZSBpcworICogdG8gZ3JvdXAga2V5IHNwZWNpZmljYXRpb25zIGZvciBjcnlwdG9ncmFwaGljIGtleXMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgS2V5U3BlYyB7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL01HRjFQYXJhbWV0ZXJTcGVjLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL01HRjFQYXJhbWV0ZXJTcGVjLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2FiMjk1ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvTUdGMVBhcmFtZXRlclNwZWMuamF2YQpAQCAtMCwwICsxLDgzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuc3BlYzsKKworLyoqCisgKiBUaGUgcGFyYW1ldGVyIHNwZWNpZmljYXRpb24gZm9yIHRoZSBNYXNrIEdlbmVyYXRpb24gRnVuY3Rpb24gKE1HRjEpIGluCisgKiB0aGUgUlNBLVBTUyBTaWduYXR1cmUgYW5kIE9BRVAgUGFkZGluZyBzY2hlbWUuCisgKiA8cD4KKyAqIERlZmluZWQgaW4gdGhlIDxhCisgKiBocmVmPSJodHRwOi8vd3d3LnJzYS5jb20vcnNhbGFicy9wdWJzL1BLQ1MvaHRtbC9wa2NzLTEuaHRtbCI+UEtDUyAjMSB2Mi4xPC9hPgorICogc3RhbmRhcmQKKyAqLworcHVibGljIGNsYXNzIE1HRjFQYXJhbWV0ZXJTcGVjIGltcGxlbWVudHMgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcHJlZGVmaW5lZCBNR0YxIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uIHdpdGggYW4gIlNIQS0xIiBtZXNzYWdlCisgICAgICogZGlnZXN0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTUdGMVBhcmFtZXRlclNwZWMgU0hBMSA9CisgICAgICAgIG5ldyBNR0YxUGFyYW1ldGVyU3BlYygiU0hBLTEiKTsKKworICAgIC8qKgorICAgICAqIFRoZSBwcmVkZWZpbmVkIE1HRjEgcGFyYW1ldGVyIHNwZWNpZmljYXRpb24gd2l0aCBhbiAiU0hBLTI1NiIgbWVzc2FnZQorICAgICAqIGRpZ2VzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1HRjFQYXJhbWV0ZXJTcGVjIFNIQTI1NiA9CisgICAgICAgIG5ldyBNR0YxUGFyYW1ldGVyU3BlYygiU0hBLTI1NiIpOworCisgICAgLyoqCisgICAgICogVGhlIHByZWRlZmluZWQgTUdGMSBwYXJhbWV0ZXIgc3BlY2lmaWNhdGlvbiB3aXRoIGFuICJTSEEtMzg0IiBtZXNzYWdlCisgICAgICogZGlnZXN0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTUdGMVBhcmFtZXRlclNwZWMgU0hBMzg0ID0KKyAgICAgICAgbmV3IE1HRjFQYXJhbWV0ZXJTcGVjKCJTSEEtMzg0Iik7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcHJlZGVmaW5lZCBNR0YxIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uIHdpdGggYW4gIlNIQS01MTIiIG1lc3NhZ2UKKyAgICAgKiBkaWdlc3QuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNR0YxUGFyYW1ldGVyU3BlYyBTSEE1MTIgPQorICAgICAgICBuZXcgTUdGMVBhcmFtZXRlclNwZWMoIlNIQS01MTIiKTsKKworICAgIC8vICBNZXNzYWdlIGRpZ2VzdCBhbGdvcml0aG0gbmFtZQorICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG1kTmFtZTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIE1HRjFQYXJhbWV0ZXJTcGVjfSB3aXRoIHRoZSBzcGVjaWZpZWQgbWVzc2FnZSBkaWdlc3QKKyAgICAgKiBhbGdvcml0aG0gbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBtZXNzYWdlIGRpZ2VzdCBhbGdvcml0aG0uCisgICAgICovCisgICAgcHVibGljIE1HRjFQYXJhbWV0ZXJTcGVjKFN0cmluZyBtZE5hbWUpIHsKKyAgICAgICAgdGhpcy5tZE5hbWUgPSBtZE5hbWU7CisgICAgICAgIGlmICh0aGlzLm1kTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1kTmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBtZXNzYWdlIGRpZ2VzdCBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBtZXNzYWdlIGRpZ2VzdCBhbGdvcml0aG0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXREaWdlc3RBbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiBtZE5hbWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9QS0NTOEVuY29kZWRLZXlTcGVjLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL1BLQ1M4RW5jb2RlZEtleVNwZWMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMGQ2NzE4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9QS0NTOEVuY29kZWRLZXlTcGVjLmphdmEKQEAgLTAsMCArMSw1NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LnNwZWM7CisKKy8qKgorICogVGhlIGtleSBzcGVjaWZpY2F0aW9uIGZvciBhbiBlbmNvZGVkIHByaXZhdGUga2V5IGluIEFTTi4xIGZvcm1hdCBhcyBkZWZpbmVkCisgKiBpbiB0aGUgUEtDUyM4IHN0YW5kYXJkLgorICovCitwdWJsaWMgY2xhc3MgUEtDUzhFbmNvZGVkS2V5U3BlYyBleHRlbmRzIEVuY29kZWRLZXlTcGVjIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFBLQ1M4RW5jb2RlZEtleVNwZWN9IHdpdGggdGhlIHNwZWNpZmllZCBlbmNvZGVkIGtleQorICAgICAqIGJ5dGVzLgorICAgICAqCisgICAgICogQHBhcmFtIGVuY29kZWRLZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmNvZGVkIGtleSBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUEtDUzhFbmNvZGVkS2V5U3BlYyhieXRlW10gZW5jb2RlZEtleSkgeworICAgICAgICAvLyBTdXBlciBjbGFzcycgY3RvciBtYWtlcyBkZWZlbnNpdmUgcGFyYW1ldGVyIGNvcHkKKyAgICAgICAgc3VwZXIoZW5jb2RlZEtleSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhlIGVuY29kZWQga2V5IGJ5dGVzLgorICAgICAqCisgICAgICogQHJldHVybiBhIGNvcHkgb2YgdGhlIGVuY29kZWQga2V5IGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgLy8gU3VwZXIgY2xhc3MnIGdldEVuY29kZWQoKSBhbHdheXMgcmV0dXJucyBhIG5ldyBhcnJheQorICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RW5jb2RlZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGVuY29kaW5nIGZvcm1hdCBvZiB0aGlzIGVuY29kZWQga2V5CisgICAgICogc3BlY2lmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyAiUEtDUyM4Ii4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgcmV0dXJuICJQS0NTIzgiOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvUFNTUGFyYW1ldGVyU3BlYy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9QU1NQYXJhbWV0ZXJTcGVjLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWM1YjRiMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvUFNTUGFyYW1ldGVyU3BlYy5qYXZhCkBAIC0wLDAgKzEsMTU3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuc3BlYzsKKworLyoqCisgKiBUaGUgcGFyYW1ldGVyIHNwZWNpZmljYXRpb24gZm9yIHRoZSBSU0EtUFNTIFNpZ25hdHVyZSBzY2hlbWUuCisgKiA8cD4KKyAqIERlZmluZWQgaW4gdGhlIDxhCisgKiBocmVmPSJodHRwOi8vd3d3LnJzYS5jb20vcnNhbGFicy9wdWJzL1BLQ1MvaHRtbC9wa2NzLTEuaHRtbCI+UEtDUyAjMSB2Mi4xPC9hPgorICogc3RhbmRhcmQuCisgKi8KK3B1YmxpYyBjbGFzcyBQU1NQYXJhbWV0ZXJTcGVjIGltcGxlbWVudHMgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGVmYXVsdCBwYXJhbWV0ZXIgc3BlY2lmaWNhdGlvbi4gSXQgc3BlY2lmaWVzIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVyczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPm1lc3NhZ2UgZGlnZXN0OiB7QGNvZGUgIlNIQS0xIn08L2xpPgorICAgICAqIDxsaT5tYXNrIGdlbmVyYXRpb24gZnVuY3Rpb24gKDxpPm1nZjwvaT4pOiB7QGNvZGUgIk1HRjEifTwvbGk+CisgICAgICogPGxpPnBhcmFtZXRlcnMgZm9yIHRoZSA8aT5tZ2Y8L2k+OiB7QGxpbmsgTUdGMVBhcmFtZXRlclNwZWMjU0hBMX08L2xpPgorICAgICAqIDxsaT5zYWx0IGxlbmd0aDoge0Bjb2RlIDIwfTwvbGk+CisgICAgICogPGxpPnRyYWlsZXIgZmllbGQ6IHtAY29kZSAtMX08L2xpPgorICAgICAqIDwvdWw+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBQU1NQYXJhbWV0ZXJTcGVjIERFRkFVTFQgPSBuZXcgUFNTUGFyYW1ldGVyU3BlYygyMCk7CisKKyAgICAvLyBNZXNzYWdlIGRpZ2VzdCBhbGdvcml0aG0gbmFtZQorICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG1kTmFtZTsKKyAgICAvLyBNYXNrIGdlbmVyYXRpb24gZnVuY3Rpb24gYWxnb3JpdGhtIG5hbWUKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBtZ2ZOYW1lOworICAgIC8vIE1hc2sgZ2VuZXJhdGlvbiBmdW5jdGlvbiBwYXJhbWV0ZXJzCisgICAgcHJpdmF0ZSBmaW5hbCBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIG1nZlNwZWM7CisgICAgLy8gVHJhaWxlciBmaWVsZCB2YWx1ZQorICAgIHByaXZhdGUgZmluYWwgaW50IHRyYWlsZXJGaWVsZDsKKyAgICAvLyBTYWx0IGxlbmd0aCBpbiBiaXRzCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgc2FsdExlbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFBTU1BhcmFtZXRlclNwZWN9IHdpdGggdGhlIHNwZWNpZmllZCBzYWx0IGxlbmd0aAorICAgICAqIGFuZCB0aGUgZGVmYXVsdCB2YWx1ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2FsdExlbgorICAgICAqICAgICAgICAgICAgdGhlIHNhbHQgbGVuZ3RoIChpbiBiaXRzKS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzYWx0TGVufSBpcyBuZWdhdGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUFNTUGFyYW1ldGVyU3BlYyhpbnQgc2FsdExlbikgeworICAgICAgICBpZiAoc2FsdExlbiA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInNhbHRMZW4gPCAwIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zYWx0TGVuID0gc2FsdExlbjsKKyAgICAgICAgdGhpcy5tZE5hbWUgPSAiU0hBLTEiOworICAgICAgICB0aGlzLm1nZk5hbWUgPSAiTUdGMSI7CisgICAgICAgIHRoaXMubWdmU3BlYyA9IE1HRjFQYXJhbWV0ZXJTcGVjLlNIQTE7CisgICAgICAgIHRoaXMudHJhaWxlckZpZWxkID0gMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBQU1NQYXJhbWV0ZXJTcGVjfSB3aXRoIHRoZSBzcGVjaWZpZWQgbWVzc2FnZSBkaWdlc3QKKyAgICAgKiBuYW1lLCBtYXNrIGdlbmVyYXRpb24gZnVuY3Rpb24gbmFtZSwgbWFzayBnZW5lcmF0aW9uIGZ1bmN0aW9uIHBhcmFtZXRlcnMsCisgICAgICogc2FsdCBsZW5ndGgsIGFuZCB0cmFpbGVyIGZpZWxkIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIG1kTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIG1lc3NhZ2UgZGlnZXN0IGFsZ29yaXRobS4KKyAgICAgKiBAcGFyYW0gbWdmTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIG1hc2sgZ2VuZXJhdGlvbiBmdW5jdGlvbiBhbGdvcml0aG0uCisgICAgICogQHBhcmFtIG1nZlNwZWMKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgZm9yIHRoZSBtYXNrIGdlbmVyYXRpb24gZnVuY3Rpb24gYWxnb3JpdGhtLgorICAgICAqIEBwYXJhbSBzYWx0TGVuCisgICAgICogICAgICAgICAgICB0aGUgc2FsdCBsZW5ndGggKGluIGJpdHMpLgorICAgICAqIEBwYXJhbSB0cmFpbGVyRmllbGQKKyAgICAgKiAgICAgICAgICAgIHRoZSB0cmFpbGVyIGZpZWxkIHZhbHVlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHNhbHRMZW59IG9yIHtAY29kZSB0cmFpbGVyRmllbGR9IGlzIG5lZ2F0aXZlLgorICAgICAqLworICAgIHB1YmxpYyBQU1NQYXJhbWV0ZXJTcGVjKFN0cmluZyBtZE5hbWUsIFN0cmluZyBtZ2ZOYW1lLAorICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBtZ2ZTcGVjLCBpbnQgc2FsdExlbiwgaW50IHRyYWlsZXJGaWVsZCkgeworCisgICAgICAgIGlmIChtZE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtZE5hbWUgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChtZ2ZOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWdmTmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNhbHRMZW4gPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzYWx0TGVuIDwgMCIpOworICAgICAgICB9CisgICAgICAgIGlmICh0cmFpbGVyRmllbGQgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ0cmFpbGVyRmllbGQgPCAwIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5tZE5hbWUgPSBtZE5hbWU7CisgICAgICAgIHRoaXMubWdmTmFtZSA9IG1nZk5hbWU7CisgICAgICAgIHRoaXMubWdmU3BlYyA9IG1nZlNwZWM7CisgICAgICAgIHRoaXMuc2FsdExlbiA9IHNhbHRMZW47CisgICAgICAgIHRoaXMudHJhaWxlckZpZWxkID0gdHJhaWxlckZpZWxkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGUgc2FsdCAoaW4gYml0cykuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIHNhbHQgKGluIGJpdHMpLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U2FsdExlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIHNhbHRMZW47CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgbWVzc2FnZSBkaWdlc3QgYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgbWVzc2FnZSBkaWdlc3QgYWxnb3JpdGhtLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGlnZXN0QWxnb3JpdGhtKCkgeworICAgICAgICByZXR1cm4gbWROYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIG1hc2sgZ2VuZXJhdGlvbiBmdW5jdGlvbiBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBtYXNrIGdlbmVyYXRpb24gZnVuY3Rpb24gYWxnb3JpdGhtLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TUdGQWxnb3JpdGhtKCkgeworICAgICAgICByZXR1cm4gbWdmTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwYXJhbWV0ZXIgZm9yIHRoZSBtYXNrIGdlbmVyYXRpb24gZnVuY3Rpb24gYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcGFyYW1ldGVyIGZvciB0aGUgbWFzayBnZW5lcmF0aW9uIGZ1bmN0aW9uIGFsZ29yaXRobSwgb3IKKyAgICAgKiAgICAgICAgIHtAY29kZSBudWxsfSBpZiBub25lIHNwZWNpZmllZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBnZXRNR0ZQYXJhbWV0ZXJzKCkgeworICAgICAgICByZXR1cm4gbWdmU3BlYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0cmFpbGVyIGZpZWxkIHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdHJhaWxlciBmaWVsZCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFRyYWlsZXJGaWVsZCgpIHsKKyAgICAgICAgcmV0dXJuIHRyYWlsZXJGaWVsZDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL1JTQUtleUdlblBhcmFtZXRlclNwZWMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvUlNBS2V5R2VuUGFyYW1ldGVyU3BlYy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE5MDAyMjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL1JTQUtleUdlblBhcmFtZXRlclNwZWMuamF2YQpAQCAtMCwwICsxLDczIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworCisvKioKKyAqIFRoZSBwYXJhbWV0ZXIgc3BlY2lmaWNhdGlvbiBmb3IgZ2VuZXJhdGluZyBhbiBSU0Ega2V5IHBhaXIuCisgKi8KK3B1YmxpYyBjbGFzcyBSU0FLZXlHZW5QYXJhbWV0ZXJTcGVjIGltcGxlbWVudHMgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdmFsdWUgb2YgdGhlIHB1YmxpYyBleHBvbmVudCB7QGNvZGUgRjB9ID0gMy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEJpZ0ludGVnZXIgRjAgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoM0wpOworCisgICAgLyoqCisgICAgICogVGhlIHZhbHVlIG9mIHRoZSBwdWJsaWMgZXhwb25lbnQge0Bjb2RlIEY0fSA9IDY1NTM3LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQmlnSW50ZWdlciBGNCA9IEJpZ0ludGVnZXIudmFsdWVPZig2NTUzN0wpOworCisgICAgLy8gS2V5IHNpemUKKyAgICBwcml2YXRlIGZpbmFsIGludCBrZXlzaXplOworICAgIC8vIFB1YmxpYyBFeHBvbmVudAorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBwdWJsaWNFeHBvbmVudDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFJTQUtleUdlblBhcmFtZXRlclNwZWN9IHdpdGggdGhlIHNwZWNpZmllZCBrZXkgc2l6ZQorICAgICAqIGFuZCBwdWJsaWMgZXhwb25lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5c2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIHNpemUgb2YgdGhlIG1vZHVsdXMgKG51bWJlciBvZiBiaXRzKS4KKyAgICAgKiBAcGFyYW0gcHVibGljRXhwb25lbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSBvZiB0aGUgcHVibGljIGV4cG9uZW50LgorICAgICAqLworICAgIHB1YmxpYyBSU0FLZXlHZW5QYXJhbWV0ZXJTcGVjKGludCBrZXlzaXplLCBCaWdJbnRlZ2VyIHB1YmxpY0V4cG9uZW50KSB7CisgICAgICAgIHRoaXMua2V5c2l6ZSA9IGtleXNpemU7CisgICAgICAgIHRoaXMucHVibGljRXhwb25lbnQgPSBwdWJsaWNFeHBvbmVudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzaXplIG9mIHRoZSBtb2R1bHVzIChudW1iZXIgb2YgYml0cykuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzaXplIG9mIHRoZSBtb2R1bHVzIChudW1iZXIgb2YgYml0cykuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRLZXlzaXplKCkgeworICAgICAgICByZXR1cm4ga2V5c2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgcHVibGljIGV4cG9uZW50LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHB1YmxpYyBleHBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQdWJsaWNFeHBvbmVudCgpIHsKKyAgICAgICAgcmV0dXJuIHB1YmxpY0V4cG9uZW50OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL1JTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhiYTUxOTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL1JTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYy5qYXZhCkBAIC0wLDAgKzEsMjAyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworCisvKioKKyAqIFRoZSBrZXkgc3BlY2lmaWNhdGlvbiBvZiBhIFJTQSBtdWx0aS1wcmltZSBwcml2YXRlIGtleSB3aXRoIHRoZSBDaGluZXNlCisgKiBSZW1haW5kZXIgVGhlb3JlbSAoQ1JUKSBpbmZvcm1hdGlvbiB2YWx1ZXMgdXNlZC4KKyAqIDxwPgorICogRGVmaW5lZCBpbiB0aGUgPGEKKyAqIGhyZWY9Imh0dHA6Ly93d3cucnNhLmNvbS9yc2FsYWJzL3B1YnMvUEtDUy9odG1sL3BrY3MtMS5odG1sIj5QS0NTICMxIHYyLjE8L2E+CisgKiBzdGFuZGFyZC4KKyAqLworcHVibGljIGNsYXNzIFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYyBleHRlbmRzIFJTQVByaXZhdGVLZXlTcGVjIHsKKyAgICAvLyBQdWJsaWMgRXhwb25lbnQKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgcHVibGljRXhwb25lbnQ7CisgICAgLy8gUHJpbWUgUAorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBwcmltZVA7CisgICAgLy8gUHJpbWUgUQorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBwcmltZVE7CisgICAgLy8gUHJpbWUgRXhwb25lbnQgUAorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBwcmltZUV4cG9uZW50UDsKKyAgICAvLyBQcmltZSBFeHBvbmVudCBRCisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIHByaW1lRXhwb25lbnRROworICAgIC8vIENSVCBDb2VmZmljaWVudAorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBjcnRDb2VmZmljaWVudDsKKyAgICAvLyBPdGhlciBQcmltZSBJbmZvCisgICAgcHJpdmF0ZSBmaW5hbCBSU0FPdGhlclByaW1lSW5mb1tdIG90aGVyUHJpbWVJbmZvOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjfSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBtb2R1bHVzLCBwdWJsaWMgZXhwb25lbnQsIHByaXZhdGUgZXhwb25lbnQsIHByaW1lIGZhY3RvcnMsIHByaW1lCisgICAgICogZXhwb25lbnRzLCBjcnQgY29lZmZpY2llbnQsIGFuZCBhZGRpdGlvbmFsIHByaW1lcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb2R1bHVzCisgICAgICogICAgICAgICAgICB0aGUgbW9kdWx1cyB7QGNvZGUgbn0uCisgICAgICogQHBhcmFtIHB1YmxpY0V4cG9uZW50CisgICAgICogICAgICAgICAgICB0aGUgcHVibGljIGV4cG9uZW50IHtAY29kZSBlfS4KKyAgICAgKiBAcGFyYW0gcHJpdmF0ZUV4cG9uZW50CisgICAgICogICAgICAgICAgICB0aGUgcHJpdmF0ZSBleHBvbmVudCB7QGNvZGUgZH0uCisgICAgICogQHBhcmFtIHByaW1lUAorICAgICAqICAgICAgICAgICAgdGhlIHByaW1lIGZhY3RvciB7QGNvZGUgcH0gb2Yge0Bjb2RlIG59LgorICAgICAqIEBwYXJhbSBwcmltZVEKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmltZSBmYWN0b3Ige0Bjb2RlIHF9IG9mIHtAY29kZSBufS4KKyAgICAgKiBAcGFyYW0gcHJpbWVFeHBvbmVudFAKKyAgICAgKiAgICAgICAgICAgIHRoZSBleHBvbmVudCBvZiB0aGUgcHJpbWUge0Bjb2RlIHB9LgorICAgICAqIEBwYXJhbSBwcmltZUV4cG9uZW50UQorICAgICAqICAgICAgICAgICAgdGhlIGV4cG9uZW50IG9mIHRoZSBwcmltZSB7QGNvZGUgcX0uCisgICAgICogQHBhcmFtIGNydENvZWZmaWNpZW50CisgICAgICogICAgICAgICAgICB0aGUgQ1JUIGNvZWZmaWNpZW50IHtAY29kZSBxXi0xIG1vZCBwfS4KKyAgICAgKiBAcGFyYW0gb3RoZXJQcmltZUluZm8KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmZvcm1hdGlvbiBmb3IgdGhlIGFkZGl0aW9uYWwgcHJpbWVzIG9yIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAgICAgdGhlcmUgYXJlIG9ubHkgdGhlIHR3byBwcmltZXMgKHtAY29kZSBwLCBxfSkuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb3RoZXJQcmltZUluZm99IGlzIG5vdCBudWxsIGJ1dCBlbXB0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjKAorICAgICAgICAgICAgQmlnSW50ZWdlciBtb2R1bHVzLAorICAgICAgICAgICAgQmlnSW50ZWdlciBwdWJsaWNFeHBvbmVudCwKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpdmF0ZUV4cG9uZW50LAorICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZVAsCisgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lUSwKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVFeHBvbmVudFAsCisgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lRXhwb25lbnRRLAorICAgICAgICAgICAgQmlnSW50ZWdlciBjcnRDb2VmZmljaWVudCwKKyAgICAgICAgICAgIFJTQU90aGVyUHJpbWVJbmZvW10gb3RoZXJQcmltZUluZm8pIHsKKworICAgICAgICBzdXBlcihtb2R1bHVzLCBwcml2YXRlRXhwb25lbnQpOworCisgICAgICAgIC8vIFBlcmZvcm0gY2hlY2tzIHNwZWNpZmllZAorICAgICAgICBpZiAobW9kdWx1cyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1vZHVsdXMgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChwcml2YXRlRXhwb25lbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJwcml2YXRlRXhwb25lbnQgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChwdWJsaWNFeHBvbmVudCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInB1YmxpY0V4cG9uZW50ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocHJpbWVQID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicHJpbWVQID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocHJpbWVRID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicHJpbWVRID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocHJpbWVFeHBvbmVudFAgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJwcmltZUV4cG9uZW50UCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHByaW1lRXhwb25lbnRRID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicHJpbWVFeHBvbmVudFEgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChjcnRDb2VmZmljaWVudCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImNydENvZWZmaWNpZW50ID09IG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChvdGhlclByaW1lSW5mbyAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAob3RoZXJQcmltZUluZm8ubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJvdGhlclByaW1lSW5mby5sZW5ndGggPT0gMCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gQ2xvbmUgYXJyYXkgdG8gcHJldmVudCBzdWJzZXF1ZW50IG1vZGlmaWNhdGlvbgorICAgICAgICAgICAgdGhpcy5vdGhlclByaW1lSW5mbyA9IG5ldyBSU0FPdGhlclByaW1lSW5mb1tvdGhlclByaW1lSW5mby5sZW5ndGhdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShvdGhlclByaW1lSW5mbywgMCwKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5vdGhlclByaW1lSW5mbywgMCwgdGhpcy5vdGhlclByaW1lSW5mby5sZW5ndGgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhpcy5vdGhlclByaW1lSW5mbyA9IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5wdWJsaWNFeHBvbmVudCA9IHB1YmxpY0V4cG9uZW50OworICAgICAgICB0aGlzLnByaW1lUCA9IHByaW1lUDsKKyAgICAgICAgdGhpcy5wcmltZVEgPSBwcmltZVE7CisgICAgICAgIHRoaXMucHJpbWVFeHBvbmVudFAgPSBwcmltZUV4cG9uZW50UDsKKyAgICAgICAgdGhpcy5wcmltZUV4cG9uZW50USA9IHByaW1lRXhwb25lbnRROworICAgICAgICB0aGlzLmNydENvZWZmaWNpZW50ID0gY3J0Q29lZmZpY2llbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgQ1JUIGNvZWZmaWNpZW50LCB7QGNvZGUgcV4tMSBtb2QgcH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBDUlQgY29lZmZpY2llbnQsIHtAY29kZSBxXi0xIG1vZCBwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRDcnRDb2VmZmljaWVudCgpIHsKKyAgICAgICAgcmV0dXJuIGNydENvZWZmaWNpZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGluZm9ybWF0aW9uIGZvciB0aGUgYWRkaXRpb25hbCBwcmltZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbmZvcm1hdGlvbiBmb3IgdGhlIGFkZGl0aW9uYWwgcHJpbWVzLCBvciB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiAgICAgICAgIHRoZXJlIGFyZSBvbmx5IHRoZSB0d28gcHJpbWVzICh7QGNvZGUgcCwgcX0pLgorICAgICAqLworICAgIHB1YmxpYyBSU0FPdGhlclByaW1lSW5mb1tdIGdldE90aGVyUHJpbWVJbmZvKCkgeworICAgICAgICAvLyBDbG9uZSBhcnJheSAoaWYgbm90IG51bGwpIHRvIHByZXZlbnQgc3Vic2VxdWVudCBtb2RpZmljYXRpb24KKyAgICAgICAgaWYgKG90aGVyUHJpbWVJbmZvID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgUlNBT3RoZXJQcmltZUluZm9bXSByZXQgPQorICAgICAgICAgICAgICAgIG5ldyBSU0FPdGhlclByaW1lSW5mb1tvdGhlclByaW1lSW5mby5sZW5ndGhdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShvdGhlclByaW1lSW5mbywgMCwgcmV0LCAwLCByZXQubGVuZ3RoKTsKKyAgICAgICAgICAgIHJldHVybiByZXQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBleHBvbmVudCBvZiB0aGUgcHJpbWUge0Bjb2RlIHB9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZXhwb25lbnQgb2YgdGhlIHByaW1lIHtAY29kZSBwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQcmltZUV4cG9uZW50UCgpIHsKKyAgICAgICAgcmV0dXJuIHByaW1lRXhwb25lbnRQOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGV4cG9uZW50IG9mIHRoZSBwcmltZSB7QGNvZGUgcX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBleHBvbmVudCBvZiB0aGUgcHJpbWUge0Bjb2RlIHF9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFByaW1lRXhwb25lbnRRKCkgeworICAgICAgICByZXR1cm4gcHJpbWVFeHBvbmVudFE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJpbWUgZmFjdG9yIHtAY29kZSBwfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByaW1lIGZhY3RvciB7QGNvZGUgcH0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0UHJpbWVQKCkgeworICAgICAgICByZXR1cm4gcHJpbWVQOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByaW1lIGZhY3RvciB7QGNvZGUgcX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmltZSBmYWN0b3Ige0Bjb2RlIHF9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFByaW1lUSgpIHsKKyAgICAgICAgcmV0dXJuIHByaW1lUTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwdWJsaWMgZXhwb25lbnQge0Bjb2RlIGV9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHVibGljIGV4cG9uZW50IHtAY29kZSBlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQdWJsaWNFeHBvbmVudCgpIHsKKyAgICAgICAgcmV0dXJuIHB1YmxpY0V4cG9uZW50OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvUlNBT3RoZXJQcmltZUluZm8uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvUlNBT3RoZXJQcmltZUluZm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZmQwMzg0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9SU0FPdGhlclByaW1lSW5mby5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5zcGVjOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CisKKy8qKgorICogVGhlIGFkZGl0aW9uYWwgcHJpbWUgaW5mb3JtYXRpb24gc3BlY2lmaWVkIGFzIHRyaXBsZXQgb2YgcHJpbWVzLCBhIHByaW1lCisgKiBleHBvbmVudCwgYW5kIGEgQ2hpbmVzZSBSZW1haW5kZXIgVGhlb3JlbSAoQ1JUKSBjb2VmZmljaWVudC4KKyAqIDxwPgorICogRGVmaW5lZCBpbiB0aGUgPGEKKyAqIGhyZWY9Imh0dHA6Ly93d3cucnNhLmNvbS9yc2FsYWJzL3B1YnMvUEtDUy9odG1sL3BrY3MtMS5odG1sIj5QS0NTICMxIHYyLjE8L2E+CisgKiBzdGFuZGFyZC4KKyAqLworcHVibGljIGNsYXNzIFJTQU90aGVyUHJpbWVJbmZvIHsKKyAgICAvLyBQcmltZQorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBwcmltZTsKKyAgICAvLyBQcmltZSBFeHBvbmVudAorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBwcmltZUV4cG9uZW50OworICAgIC8vIENSVCBDb2VmZmljaWVudAorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBjcnRDb2VmZmljaWVudDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFJTQU90aGVyUHJpbWVJbmZvfSB3aXRoIHRoZSBzcGVjaWZpZWQgcHJpbWUsCisgICAgICogZXhwb25lbnQsIGFuZCBDUlQgY29lZmZpY2llbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJpbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmltZSBmYWN0b3IuCisgICAgICogQHBhcmFtIHByaW1lRXhwb25lbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmltZSBleHBvbmVudC4KKyAgICAgKiBAcGFyYW0gY3J0Q29lZmZpY2llbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBDUlQgY29lZmZpY2llbnQuCisgICAgICovCisgICAgcHVibGljIFJTQU90aGVyUHJpbWVJbmZvKEJpZ0ludGVnZXIgcHJpbWUsCisgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lRXhwb25lbnQsIEJpZ0ludGVnZXIgY3J0Q29lZmZpY2llbnQpIHsKKyAgICAgICAgaWYgKHByaW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicHJpbWUgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChwcmltZUV4cG9uZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicHJpbWVFeHBvbmVudCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNydENvZWZmaWNpZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiY3J0Q29lZmZpY2llbnQgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRoaXMucHJpbWUgPSBwcmltZTsKKyAgICAgICAgdGhpcy5wcmltZUV4cG9uZW50ID0gcHJpbWVFeHBvbmVudDsKKyAgICAgICAgdGhpcy5jcnRDb2VmZmljaWVudCA9IGNydENvZWZmaWNpZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIENSVCBjb2VmZmljaWVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIENSVCBjb2VmZmljaWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQmlnSW50ZWdlciBnZXRDcnRDb2VmZmljaWVudCgpIHsKKyAgICAgICAgcmV0dXJuIGNydENvZWZmaWNpZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByaW1lIGZhY3Rvci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByaW1lIGZhY3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQmlnSW50ZWdlciBnZXRQcmltZSgpIHsKKyAgICAgICAgcmV0dXJuIHByaW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGV4cG9uZW50LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZXhwb25lbnQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEJpZ0ludGVnZXIgZ2V0RXhwb25lbnQoKSB7CisgICAgICAgIHJldHVybiBwcmltZUV4cG9uZW50OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvUlNBUHJpdmF0ZUNydEtleVNwZWMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvUlNBUHJpdmF0ZUNydEtleVNwZWMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNGYyNmMwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9SU0FQcml2YXRlQ3J0S2V5U3BlYy5qYXZhCkBAIC0wLDAgKzEsMTM4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworCisvKioKKyAqIFRoZSBrZXkgc3BlY2lmaWNhdGlvbiBvZiBhIFJTQSBwcml2YXRlIGtleSB1c2luZyBDaGluZXNlIFJlbWFpbmRlciBUaGVvcmVtCisgKiAoQ1JUKSB2YWx1ZXMuCisgKiA8cD4KKyAqIERlZmluZWQgaW4gdGhlIDxhCisgKiBocmVmPSJodHRwOi8vd3d3LnJzYS5jb20vcnNhbGFicy9wdWJzL1BLQ1MvaHRtbC9wa2NzLTEuaHRtbCI+UEtDUyAjMSB2Mi4xPC9hPgorICogc3RhbmRhcmQuCisgKi8KK3B1YmxpYyBjbGFzcyBSU0FQcml2YXRlQ3J0S2V5U3BlYyBleHRlbmRzIFJTQVByaXZhdGVLZXlTcGVjIHsKKyAgICAvLyBQdWJsaWMgRXhwb25lbnQKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgcHVibGljRXhwb25lbnQ7CisgICAgLy8gUHJpbWUgUAorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBwcmltZVA7CisgICAgLy8gUHJpbWUgUQorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBwcmltZVE7CisgICAgLy8gUHJpbWUgRXhwb25lbnQgUAorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBwcmltZUV4cG9uZW50UDsKKyAgICAvLyBQcmltZSBFeHBvbmVudCBRCisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIHByaW1lRXhwb25lbnRROworICAgIC8vIENSVCBDb2VmZmljaWVudAorICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBjcnRDb2VmZmljaWVudDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlY30gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogbW9kdWx1cywgcHVibGljIGV4cG9uZW50LCBwcml2YXRlIGV4cG9uZW50LCBwcmltZSBmYWN0b3JzLCBwcmltZQorICAgICAqIGV4cG9uZW50cywgY3J0IGNvZWZmaWNpZW50LCBhbmQgYWRkaXRpb25hbCBwcmltZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbW9kdWx1cworICAgICAqICAgICAgICAgICAgdGhlIG1vZHVsdXMge0Bjb2RlIG59LgorICAgICAqIEBwYXJhbSBwdWJsaWNFeHBvbmVudAorICAgICAqICAgICAgICAgICAgdGhlIHB1YmxpYyBleHBvbmVudCB7QGNvZGUgZX0uCisgICAgICogQHBhcmFtIHByaXZhdGVFeHBvbmVudAorICAgICAqICAgICAgICAgICAgdGhlIHByaXZhdGUgZXhwb25lbnQge0Bjb2RlIGR9LgorICAgICAqIEBwYXJhbSBwcmltZVAKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmltZSBmYWN0b3Ige0Bjb2RlIHB9IG9mIHtAY29kZSBufS4KKyAgICAgKiBAcGFyYW0gcHJpbWVRCisgICAgICogICAgICAgICAgICB0aGUgcHJpbWUgZmFjdG9yIHtAY29kZSBxfSBvZiB7QGNvZGUgbn0uCisgICAgICogQHBhcmFtIHByaW1lRXhwb25lbnRQCisgICAgICogICAgICAgICAgICB0aGUgZXhwb25lbnQgb2YgdGhlIHByaW1lIHtAY29kZSBwfS4KKyAgICAgKiBAcGFyYW0gcHJpbWVFeHBvbmVudFEKKyAgICAgKiAgICAgICAgICAgIHRoZSBleHBvbmVudCBvZiB0aGUgcHJpbWUge0Bjb2RlIHF9LgorICAgICAqIEBwYXJhbSBjcnRDb2VmZmljaWVudAorICAgICAqICAgICAgICAgICAgdGhlIENSVCBjb2VmZmljaWVudCB7QGNvZGUgcV4tMSBtb2QgcH0uCisgICAgICovCisgICAgcHVibGljIFJTQVByaXZhdGVDcnRLZXlTcGVjKEJpZ0ludGVnZXIgbW9kdWx1cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwdWJsaWNFeHBvbmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcml2YXRlRXhwb25lbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVQLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lUSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZUV4cG9uZW50UCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZUV4cG9uZW50USwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBjcnRDb2VmZmljaWVudCkgeworCisgICAgICAgIHN1cGVyKG1vZHVsdXMsIHByaXZhdGVFeHBvbmVudCk7CisKKyAgICAgICAgdGhpcy5wdWJsaWNFeHBvbmVudCA9IHB1YmxpY0V4cG9uZW50OworICAgICAgICB0aGlzLnByaW1lUCA9IHByaW1lUDsKKyAgICAgICAgdGhpcy5wcmltZVEgPSBwcmltZVE7CisgICAgICAgIHRoaXMucHJpbWVFeHBvbmVudFAgPSBwcmltZUV4cG9uZW50UDsKKyAgICAgICAgdGhpcy5wcmltZUV4cG9uZW50USA9IHByaW1lRXhwb25lbnRROworICAgICAgICB0aGlzLmNydENvZWZmaWNpZW50ID0gY3J0Q29lZmZpY2llbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgQ1JUIGNvZWZmaWNpZW50LCB7QGNvZGUgcV4tMSBtb2QgcH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBDUlQgY29lZmZpY2llbnQsIHtAY29kZSBxXi0xIG1vZCBwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRDcnRDb2VmZmljaWVudCgpIHsKKyAgICAgICAgcmV0dXJuIGNydENvZWZmaWNpZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGV4cG9uZW50IG9mIHRoZSBwcmltZSB7QGNvZGUgcH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBleHBvbmVudCBvZiB0aGUgcHJpbWUge0Bjb2RlIHB9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFByaW1lRXhwb25lbnRQKCkgeworICAgICAgICByZXR1cm4gcHJpbWVFeHBvbmVudFA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZXhwb25lbnQgb2YgdGhlIHByaW1lIHtAY29kZSBxfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGV4cG9uZW50IG9mIHRoZSBwcmltZSB7QGNvZGUgcX0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0UHJpbWVFeHBvbmVudFEoKSB7CisgICAgICAgIHJldHVybiBwcmltZUV4cG9uZW50UTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcmltZSBmYWN0b3Ige0Bjb2RlIHB9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJpbWUgZmFjdG9yIHtAY29kZSBwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQcmltZVAoKSB7CisgICAgICAgIHJldHVybiBwcmltZVA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJpbWUgZmFjdG9yIHtAY29kZSBxfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByaW1lIGZhY3RvciB7QGNvZGUgcX0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0UHJpbWVRKCkgeworICAgICAgICByZXR1cm4gcHJpbWVROworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHB1YmxpYyBleHBvbmVudCB7QGNvZGUgZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwdWJsaWMgZXhwb25lbnQge0Bjb2RlIGV9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFB1YmxpY0V4cG9uZW50KCkgeworICAgICAgICByZXR1cm4gcHVibGljRXhwb25lbnQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9SU0FQcml2YXRlS2V5U3BlYy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9SU0FQcml2YXRlS2V5U3BlYy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2NjcwNDgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL1JTQVByaXZhdGVLZXlTcGVjLmphdmEKQEAgLTAsMCArMSw2NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LnNwZWM7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKKworLyoqCisgKiBUaGUga2V5IHNwZWNpZmljYXRpb24gb2YgYSBSU0EgcHJpdmF0ZSBrZXkuCisgKiA8cD4KKyAqIERlZmluZWQgaW4gdGhlIDxhCisgKiBocmVmPSJodHRwOi8vd3d3LnJzYS5jb20vcnNhbGFicy9wdWJzL1BLQ1MvaHRtbC9wa2NzLTEuaHRtbCI+UEtDUyAjMSB2Mi4xPC9hPgorICogc3RhbmRhcmQKKyAqLworcHVibGljIGNsYXNzIFJTQVByaXZhdGVLZXlTcGVjIGltcGxlbWVudHMgS2V5U3BlYyB7CisgICAgLy8gTW9kdWx1cworICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBtb2R1bHVzOworICAgIC8vIFByaXZhdGUgRXhwb25lbnQKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgcHJpdmF0ZUV4cG9uZW50OworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgUlNBUHJpdmF0ZUtleVNwZWN9IHdpdGggdGhlIHNwZWNpZmllZCBtb2R1bHVzIGFuZAorICAgICAqIHByaXZhdGUgZXhwb25lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbW9kdWx1cworICAgICAqICAgICAgICAgICAgdGhlIG1vZHVsdXMge0Bjb2RlIG59LgorICAgICAqIEBwYXJhbSBwcml2YXRlRXhwb25lbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcml2YXRlIGV4cG9uZW50IHtAY29kZSBlfQorICAgICAqLworICAgIHB1YmxpYyBSU0FQcml2YXRlS2V5U3BlYyhCaWdJbnRlZ2VyIG1vZHVsdXMsIEJpZ0ludGVnZXIgcHJpdmF0ZUV4cG9uZW50KSB7CisgICAgICAgIHRoaXMubW9kdWx1cyA9IG1vZHVsdXM7CisgICAgICAgIHRoaXMucHJpdmF0ZUV4cG9uZW50ID0gcHJpdmF0ZUV4cG9uZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1vZHVsdXMge0Bjb2RlIG59LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbW9kdWx1cyB7QGNvZGUgbn0uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0TW9kdWx1cygpIHsKKyAgICAgICAgcmV0dXJuIG1vZHVsdXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJpdmF0ZSBleHBvbmVudCB7QGNvZGUgZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcml2YXRlIGV4cG9uZW50IHtAY29kZSBlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQcml2YXRlRXhwb25lbnQoKSB7CisgICAgICAgIHJldHVybiBwcml2YXRlRXhwb25lbnQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9SU0FQdWJsaWNLZXlTcGVjLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL1JTQVB1YmxpY0tleVNwZWMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMjRjYTVjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc2VjdXJpdHkvc3BlYy9SU0FQdWJsaWNLZXlTcGVjLmphdmEKQEAgLTAsMCArMSw2NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNlY3VyaXR5LnNwZWM7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKKworLyoqCisgKiBUaGUga2V5IHNwZWNpZmljYXRpb24gb2YgYSBSU0EgcHVibGljIGtleS4KKyAqIDxwPgorICogRGVmaW5lZCBpbiB0aGUgPGEKKyAqIGhyZWY9Imh0dHA6Ly93d3cucnNhLmNvbS9yc2FsYWJzL3B1YnMvUEtDUy9odG1sL3BrY3MtMS5odG1sIj5QS0NTICMxIHYyLjE8L2E+CisgKiBzdGFuZGFyZC4KKyAqLworcHVibGljIGNsYXNzIFJTQVB1YmxpY0tleVNwZWMgaW1wbGVtZW50cyBLZXlTcGVjIHsKKyAgICAvLyBNb2R1bHVzCisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIG1vZHVsdXM7CisgICAgLy8gUHVibGljIEV4cG9uZW50CisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIHB1YmxpY0V4cG9uZW50OworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgUlNBUHVibGljS2V5U3BlY30gd2l0aCB0aGUgc3BlY2lmaWVkIG1vZHVsdXMgYW5kCisgICAgICogcHVibGljIGV4cG9uZW50LgorICAgICAqCisgICAgICogQHBhcmFtIG1vZHVsdXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBtb2R1bHVzIHtAY29kZSBufS4KKyAgICAgKiBAcGFyYW0gcHVibGljRXhwb25lbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwdWJsaWMgZXhwb25lbnQge0Bjb2RlIGR9LgorICAgICAqLworICAgIHB1YmxpYyBSU0FQdWJsaWNLZXlTcGVjKEJpZ0ludGVnZXIgbW9kdWx1cywgQmlnSW50ZWdlciBwdWJsaWNFeHBvbmVudCkgeworICAgICAgICB0aGlzLm1vZHVsdXMgPSBtb2R1bHVzOworICAgICAgICB0aGlzLnB1YmxpY0V4cG9uZW50ID0gcHVibGljRXhwb25lbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbW9kdWx1cyB7QGNvZGUgbn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtb2R1bHVzIHtAY29kZSBufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRNb2R1bHVzKCkgeworICAgICAgICByZXR1cm4gbW9kdWx1czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwdWJsaWMgZXhwb25lbnQge0Bjb2RlIGR9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHVibGljIGV4cG9uZW50IHtAY29kZSBkfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQdWJsaWNFeHBvbmVudCgpIHsKKyAgICAgICAgcmV0dXJuIHB1YmxpY0V4cG9uZW50OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvWDUwOUVuY29kZWRLZXlTcGVjLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL1g1MDlFbmNvZGVkS2V5U3BlYy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjliNDhlMWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL1g1MDlFbmNvZGVkS2V5U3BlYy5qYXZhCkBAIC0wLDAgKzEsNTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zZWN1cml0eS5zcGVjOworCisvKioKKyAqIFRoZSBrZXkgc3BlY2lmaWNhdGlvbiBvZiBhbiBYLjUwOSBlbmNvZGVkIGtleSBpbiBBU04uMSBmb3JtYXQuCisgKi8KK3B1YmxpYyBjbGFzcyBYNTA5RW5jb2RlZEtleVNwZWMgZXh0ZW5kcyBFbmNvZGVkS2V5U3BlYyB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBYNTA5RW5jb2RlZEtleVNwZWN9IHdpdGggdGhlIHNwZWNpZmllZCBlbmNvZGVkIGtleQorICAgICAqIGJ5dGVzLgorICAgICAqCisgICAgICogQHBhcmFtIGVuY29kZWRLZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmNvZGVkIGtleSBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgWDUwOUVuY29kZWRLZXlTcGVjKGJ5dGVbXSBlbmNvZGVkS2V5KSB7CisgICAgICAgIC8vIFN1cGVyIGNsYXNzJyBjdG9yIG1ha2VzIGRlZmVuc2l2ZSBwYXJhbWV0ZXIgY29weQorICAgICAgICBzdXBlcihlbmNvZGVkS2V5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBlbmNvZGVkIGtleSBieXRlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVuY29kZWQga2V5IGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgLy8gU3VwZXIgY2xhc3MnIGdldEVuY29kZWQoKSBhbHdheXMgcmV0dXJucyBhIG5ldyBhcnJheQorICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RW5jb2RlZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGVuY29kaW5nIGZvcm1hdCBvZiB0aGlzIGVuY29kZWQga2V5CisgICAgICogc3BlY2lmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyAiWC41MDkiLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICByZXR1cm4gIlguNTA5IjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL3BhY2thZ2UuaHRtbCBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NlY3VyaXR5L3NwZWMvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3NWFlZTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zZWN1cml0eS9zcGVjL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDE4IEBACis8aHRtbD4KKzxoZWFkPgorPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXMtYXNjaWkiPgorPC9oZWFkPgorPGh0bWw+Cis8Ym9keT4KKzxwPgorVGhpcyBwYWNrYWdlIHByb3ZpZGVzIHRoZSBjbGFzc2VzIGFuZCBpbnRlcmZhY2VzIG5lZWRlZCB0byBzcGVjaWZ5IGtleXMgYW5kIHBhcmFtZXRlcnMgZm9yCitlbmNyeXB0aW9uIGFuZCBzaWduaW5nIGFsZ29yaXRobXMuIFRoZSBmb2xsb3dpbmcgc3RhbmRhcmRzIGFyZSBzdXBwb3J0ZWQ6CisoMSkgUEtDUyMxIFJTQSBlbmNyeXB0aW9uIHN0YW5kYXJkOworKDIpIEZJUFMtMTg2IERTQSAoc2lnbmF0dXJlKSBzdGFuZGFyZDsKKygzKSBQS0NTIzggcHJpdmF0ZSBrZXkgaW5mb3JtYXRpb24gc3RhbmRhcmQuCitLZXlzIG1heSBiZSBzcGVjaWZpZWQgdmlhIGFsZ29yaXRobSBvciBpbiBhIG1vcmUgYWJzdHJhY3QgYW5kIGdlbmVyYWwgd2F5IHdpdGggQVNOLjEuCitUaGUgcGFyYW1ldGVycyBmb3IgdGhlIEVsbGlwdGljIEN1cnZlIChFQykgZW5jcnlwdGlvbiBhbGdvcml0aG0gYXJlIG9ubHkgc3BlY2lmaWVkIGFzCitpbnB1dCBwYXJhbWV0ZXJzIHRvIHRoZSByZWxldmFudCBFQy1nZW5lcmF0b3IuCis8L3A+Cis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvQXJyYXkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9BcnJheS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJhZDFlYTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvQXJyYXkuamF2YQpAQCAtMCwwICsxLDE3MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zcWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCisvKioKKyAqIEEgSmF2YSByZXByZXNlbnRhdGlvbiBvZiB0aGUgU1FMIHtAY29kZSBBUlJBWX0gdHlwZS4KKyAqLworcHVibGljIGludGVyZmFjZSBBcnJheSB7CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgdGhlIGNvbnRlbnRzIG9mIHRoZSBTUUwge0Bjb2RlIEFSUkFZfSB2YWx1ZSBhcyBhIEphdmEgYXJyYXkKKyAgICAgKiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEgSmF2YSBhcnJheSBjb250YWluaW5nIHRoZSBlbGVtZW50cyBvZiB0aGlzIEFycmF5CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0QXJyYXkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBwYXJ0IG9mIHRoZSBTUUwge0Bjb2RlIEFSUkFZfSBhc3NvY2lhdGVkIHdpdGggdGhpcyBhcnJheSwKKyAgICAgKiBzdGFydGluZyBhdCBhIHBhcnRpY3VsYXIge0Bjb2RlIGluZGV4fSBhbmQgY29tcHJpc2luZyB1cCB0byB7QGNvZGUgY291bnR9CisgICAgICogc3VjY2Vzc2l2ZSBlbGVtZW50cyBvZiB0aGUgU1FMIGFycmF5LgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5IHdoZXJlIHRoZSB2YWx1ZXMgYXJlCisgICAgICogICAgICAgICAgICByZXRyaWV2ZWQuCisgICAgICogQHBhcmFtIGNvdW50CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIHJldHJpZXZlLgorICAgICAqIEByZXR1cm4gQSBKYXZhIGFycmF5IGNvbnRhaW5pbmcgdGhlIGRlc2lyZWQgc2V0IG9mIGVsZW1lbnRzIGZyb20gdGhpcyBBcnJheQorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldEFycmF5KGxvbmcgaW5kZXgsIGludCBjb3VudCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgcGFydCBvZiB0aGUgU1FMIHtAY29kZSBBUlJBWX0gYXNzb2NpYXRlZCB3aXRoIHRoaXMgYXJyYXksCisgICAgICogc3RhcnRpbmcgYXQgYSBwYXJ0aWN1bGFyIHtAY29kZSBpbmRleH0gYW5kIGNvbXByaXNpbmcgdXAgdG8ge0Bjb2RlIGNvdW50fQorICAgICAqIHN1Y2Nlc3NpdmUgZWxlbWVudHMgb2YgdGhlIFNRTCBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheSB3aGVyZSB0aGUgdmFsdWVzIGFyZQorICAgICAqICAgICAgICAgICAgcmV0cmlldmVkLgorICAgICAqIEBwYXJhbSBjb3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBlbGVtZW50cyB0byByZXRyaWV2ZS4KKyAgICAgKiBAcGFyYW0gbWFwCisgICAgICogICAgICAgICAgICB0aGUgbWFwIGRlZmluaW5nIHRoZSBjb3JyZXNwb25kZW5jZSBiZXR3ZWVuIFNRTCB0eXBlIG5hbWVzCisgICAgICogICAgICAgICAgICBhbmQgSmF2YSB0eXBlcy4KKyAgICAgKiBAcmV0dXJuIEEgSmF2YSBhcnJheSBjb250YWluaW5nIHRoZSBkZXNpcmVkIHNldCBvZiBlbGVtZW50cyBmcm9tIHRoaXMgQXJyYXkKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRBcnJheShsb25nIGluZGV4LCBpbnQgY291bnQsIE1hcDxTdHJpbmcsIENsYXNzPD8+PiBtYXApCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGF0YSBmcm9tIHRoZSB1bmRlcmx5aW5nIFNRTCB7QGNvZGUgQVJSQVl9IGFzIGEgSmF2YSBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtYXAKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXAgZGVmaW5pbmcgdGhlIGNvcnJlc3BvbmRlbmNlIGJldHdlZW4gU1FMIHR5cGUgbmFtZXMKKyAgICAgKiAgICAgICAgICAgIGFuZCBKYXZhIHR5cGVzLgorICAgICAqIEByZXR1cm4gQSBKYXZhIGFycmF5IGNvbnRhaW5pbmcgdGhlIGVsZW1lbnRzIG9mIHRoaXMgYXJyYXkKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRBcnJheShNYXA8U3RyaW5nLCBDbGFzczw/Pj4gbWFwKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgSkRCQyB0eXBlIG9mIHRoZSBlbnRyaWVzIGluIHRoaXMgYXJyYXkncyB1bmRlcmx5aW5nCisgICAgICogU1FMIGFycmF5LgorICAgICAqCisgICAgICogQHJldHVybiBBbiBpbnRlZ2VyIGNvbnN0YW50IGZyb20gdGhlIHtAY29kZSBqYXZhLnNxbC5UeXBlc30gY2xhc3MKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRCYXNlVHlwZSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBTUUwgdHlwZSBuYW1lIG9mIHRoZSBlbnRyaWVzIGluIHRoaXMgYXJyYXkncyB1bmRlcmx5aW5nCisgICAgICogU1FMIGFycmF5LgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgZGF0YWJhc2Ugc3BlY2lmaWMgbmFtZSBvciBhIGZ1bGx5LXF1YWxpZmllZCBTUUwgdHlwZSBuYW1lLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRCYXNlVHlwZU5hbWUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIFJlc3VsdFNldCBvYmplY3Qgd2hpY2ggaG9sZHMgdGhlIGVudHJpZXMgb2YgdGhlIFNRTCB7QGNvZGUKKyAgICAgKiBBUlJBWX0gYXNzb2NpYXRlZCB3aXRoIHRoaXMgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBlbGVtZW50cyBvZiB0aGUgYXJyYXkgYXMgYSB7QGNvZGUgUmVzdWx0U2V0fS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIFJlc3VsdFNldCBnZXRSZXN1bHRTZXQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBSZXN1bHRTZXR9IG9iamVjdCB0aGF0IGhvbGRzIHRoZSBlbnRyaWVzIG9mIGEgc3ViYXJyYXksCisgICAgICogYmVnaW5uaW5nIGF0IGEgcGFydGljdWxhciBpbmRleCBhbmQgY29tcHJpc2luZyB1cCB0byB7QGNvZGUgY291bnR9CisgICAgICogc3VjY2Vzc2l2ZSBlbnRyaWVzLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5IHdoZXJlIHRoZSB2YWx1ZXMgYXJlCisgICAgICogICAgICAgICAgICByZXRyaWV2ZWQuCisgICAgICogQHBhcmFtIGNvdW50CisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIHJldHJpZXZlLgorICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnRzIG9mIHRoZSBhcnJheSBhcyBhIHtAY29kZSBSZXN1bHRTZXR9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzdWx0U2V0IGdldFJlc3VsdFNldChsb25nIGluZGV4LCBpbnQgY291bnQpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIFJlc3VsdFNldH0gb2JqZWN0IHRoYXQgaG9sZHMgdGhlIGVudHJpZXMgb2YgYSBzdWJhcnJheSwKKyAgICAgKiBiZWdpbm5pbmcgYXQgYSBwYXJ0aWN1bGFyIGluZGV4IGFuZCBjb21wcmlzaW5nIHVwIHRvIHtAY29kZSBjb3VudH0KKyAgICAgKiBzdWNjZXNzaXZlIGVudHJpZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkgd2hlcmUgdGhlIHZhbHVlcyBhcmUKKyAgICAgKiAgICAgICAgICAgIHJldHJpZXZlZC4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gcmV0cmlldmUuCisgICAgICogQHBhcmFtIG1hcAorICAgICAqICAgICAgICAgICAgdGhlIG1hcCBkZWZpbmluZyB0aGUgY29ycmVzcG9uZGVuY2UgYmV0d2VlbiBTUUwgdHlwZSBuYW1lcworICAgICAqICAgICAgICAgICAgYW5kIEphdmEgdHlwZXMuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFJlc3VsdFNldH0gdGhlIGFycmF5J3MgY3VzdG9tIHR5cGUgdmFsdWVzLiBpZiBhCisgICAgICogICAgICAgICBkYXRhYmFzZSBlcnJvciBoYXMgb2NjdXJyZWQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBSZXN1bHRTZXQgZ2V0UmVzdWx0U2V0KGxvbmcgaW5kZXgsIGludCBjb3VudCwKKyAgICAgICAgICAgIE1hcDxTdHJpbmcsIENsYXNzPD8+PiBtYXApIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIFJlc3VsdFNldH0gb2JqZWN0IHdoaWNoIGhvbGRzIHRoZSBlbnRyaWVzIG9mIHRoZSBTUUwKKyAgICAgKiB7QGNvZGUgQVJSQVl9IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGFycmF5LgorICAgICAqCisgICAgICogQHBhcmFtIG1hcAorICAgICAqICAgICAgICAgICAgdGhlIG1hcCBkZWZpbmluZyB0aGUgY29ycmVzcG9uZGVuY2UgYmV0d2VlbiBTUUwgdHlwZSBuYW1lcworICAgICAqICAgICAgICAgICAgYW5kIEphdmEgdHlwZXMuCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgYXMgYSB7QGNvZGUgUmVzdWx0U2V0fS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIFJlc3VsdFNldCBnZXRSZXN1bHRTZXQoTWFwPFN0cmluZywgQ2xhc3M8Pz4+IG1hcCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBGcmVlcyBhbnkgcmVzb3VyY2VzIGhlbGQgYnkgdGhpcyBhcnJheS4gQWZ0ZXIge0Bjb2RlIGZyZWV9IGlzIGNhbGxlZCwgY2FsbGluZworICAgICAqIG1ldGhvZCBvdGhlciB0aGFuIHtAY29kZSBmcmVlfSB3aWxsIHRocm93IHtAY29kZSBTUUxFeGNlcHRpb259IChjYWxsaW5nIHtAY29kZSBmcmVlfQorICAgICAqIHJlcGVhdGVkbHkgd2lsbCBkbyBub3RoaW5nKS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZyZWUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL0JhdGNoVXBkYXRlRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvQmF0Y2hVcGRhdGVFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNTJhYjZhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL0JhdGNoVXBkYXRlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwyMzMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKKy8qKgorICogVGhpcyBleGNlcHRpb24gaXMgdGhyb3duIGlmIGEgcHJvYmxlbSBvY2N1cnMgZHVyaW5nIGEgYmF0Y2ggdXBkYXRlIG9wZXJhdGlvbi4KKyAqIDxwPgorICogQSB7QGNvZGUgQmF0Y2hVcGRhdGVFeGNlcHRpb259IHByb3ZpZGVzIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gYWJvdXQgdGhlCisgKiBwcm9ibGVtIHRoYXQgb2NjdXJyZWQsIGNvbXBhcmVkIHdpdGggYSBzdGFuZGFyZCB7QGNvZGUgU1FMRXhjZXB0aW9ufS4gSXQKKyAqIHN1cHBsaWVzIHVwZGF0ZSBjb3VudHMgZm9yIHN1Y2Nlc3NmdWwgY29tbWFuZHMgd2hpY2ggd2VyZSBleGVjdXRlZCBiZWZvcmUgdGhlCisgKiBleGNlcHRpb24gd2FzIGVuY291bnRlcmVkLgorICogPHA+CisgKiBUaGUgZWxlbWVudCBvcmRlciBpbiB0aGUgYXJyYXkgb2YgdXBkYXRlIGNvdW50cyBtYXRjaGVzIHRoZSBvcmRlciB0aGF0IHRoZQorICogY29tbWFuZHMgd2VyZSBhZGRlZCB0byB0aGUgYmF0Y2ggb3BlcmF0aW9uLgorICogPHA+CisgKiBPbmNlIGEgYmF0Y2ggdXBkYXRlIGNvbW1hbmQgZmFpbHMgYW5kIGEge0Bjb2RlIEJhdGNoVXBkYXRlRXhjZXB0aW9ufSBpcworICogdGhyb3duLCB0aGUgSkRCQyBkcml2ZXIgbWF5IGNvbnRpbnVlIHByb2Nlc3NpbmcgdGhlIHJlbWFpbmluZyBjb21tYW5kcyBpbiB0aGUKKyAqIGJhdGNoLiBJZiB0aGUgZHJpdmVyIGRvZXMgcHJvY2VzcyBtb3JlIGNvbW1hbmRzIGFmdGVyIHRoZSBwcm9ibGVtIG9jY3VycywgdGhlCisgKiBhcnJheSByZXR1cm5lZCBieSB7QGNvZGUgQmF0Y2hVcGRhdGVFeGNlcHRpb24uZ2V0VXBkYXRlQ291bnRzfSBoYXMgYW4gZWxlbWVudAorICogZm9yIGV2ZXJ5IGNvbW1hbmQgaW4gdGhlIGJhdGNoLCBub3Qgb25seSB0aG9zZSB0aGF0IGV4ZWN1dGVkIHN1Y2Nlc3NmdWxseS4gSW4KKyAqIHRoaXMgY2FzZSwgdGhlIGFycmF5IGVsZW1lbnQgZm9yIGFueSBjb21tYW5kIHdoaWNoIGVuY291bnRlcmVkIGEgcHJvYmxlbSBpcworICogc2V0IHRvIHtAY29kZSBTdGF0ZW1lbnQuRVhFQ1VURV9GQUlMRUR9LgorICovCitwdWJsaWMgY2xhc3MgQmF0Y2hVcGRhdGVFeGNlcHRpb24gZXh0ZW5kcyBTUUxFeGNlcHRpb24gaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTk3NzUyOTg3NzE0NTUyMTc1N0w7CisKKyAgICBwcml2YXRlIGludFtdIHVwZGF0ZUNvdW50cyA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgZGVmYXVsdCB7QGNvZGUgQmF0Y2hVcGRhdGVFeGNlcHRpb259IHdpdGggdGhlIHBhcmFtZXRlcnMKKyAgICAgKiA8aT5yZWFzb248L2k+LCA8aT5TUUxTdGF0ZTwvaT4sIGFuZCA8aT51cGRhdGUgY291bnRzPC9pPiBzZXQgdG8ge0Bjb2RlCisgICAgICogbnVsbH0gYW5kIHRoZSA8aT52ZW5kb3IgY29kZTwvaT4gc2V0IHRvIDAuCisgICAgICovCisgICAgcHVibGljIEJhdGNoVXBkYXRlRXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gQmF0Y2hVcGRhdGVFeGNlcHRpb24gb2JqZWN0LiBUaGUgcmVhc29uIGlzIHNldCB0bworICAgICAqIG51bGwgaWYgY2F1c2UgPT0gbnVsbCBvdGhlcndpc2UgdG8gY2F1c2UudG9TdHJpbmcoKSwgYW5kIHRoZSBjYXVzZQorICAgICAqIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZSBUaHJvd2FibGUgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcyBTUUxFeGNlcHRpb24KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgQmF0Y2hVcGRhdGVFeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHRoaXMobnVsbCwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gQmF0Y2hVcGRhdGVFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8gdGhlCisgICAgICogbnVsbCBpZiBjYXVzZSA9PSBudWxsIG90aGVyd2lzZSB0byBjYXVzZS50b1N0cmluZygpLCBhbmQgdGhlIGNhdXNlCisgICAgICogVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlIFRocm93YWJsZSBvYmplY3QuIFNRTFN0YXRlIGlzCisgICAgICogaW5pdGlhbGl6ZWQgdG8gbnVsbCB3aGlsZSB2ZW5kb3JDb2RlIGlzIHplcm8uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F1c2UgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzIFNRTEV4Y2VwdGlvbgorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBCYXRjaFVwZGF0ZUV4Y2VwdGlvbihpbnRbXSB1cGRhdGVDb3VudHMsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgICAgIHRoaXMudXBkYXRlQ291bnRzID0gdXBkYXRlQ291bnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gQmF0Y2hVcGRhdGVFeGNlcHRpb24gb2JqZWN0LiBUaGUgY2F1c2UgVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQKKyAgICAgKiB0byB0aGUgZ2l2ZW4gY2F1c2UgVGhyb3dhYmxlIG9iamVjdC4gU1FMU3RhdGUgaXMgaW5pdGlhbGl6ZWQgdG8gbnVsbAorICAgICAqIHdoaWxlIHZlbmRvckNvZGUgaXMgemVyby4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZSB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMgU1FMRXhjZXB0aW9uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIEJhdGNoVXBkYXRlRXhjZXB0aW9uKFN0cmluZyByZWFzb24sIGludFtdIHVwZGF0ZUNvdW50cywKKyAgICAgICAgICAgIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihyZWFzb24sIGNhdXNlKTsKKyAgICAgICAgdGhpcy51cGRhdGVDb3VudHMgPSB1cGRhdGVDb3VudHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBCYXRjaFVwZGF0ZUV4Y2VwdGlvbiBvYmplY3QuIFRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldAorICAgICAqIHRvIHRoZSBnaXZlbiBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGFuZCB0aGUgdXBkYXRlQ291bnRzIGFycmF5IHNldCB0byB0aGUKKyAgICAgKiBpbnQgYXJyYXkgcGFyYW1ldGVyLiBTUUxTdGF0ZSBpcyBpbml0aWFsaXplZCB0byBudWxsIHdoaWxlIHZlbmRvckNvZGUgaXMKKyAgICAgKiB6ZXJvLgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcyBTUUxFeGNlcHRpb24KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgQmF0Y2hVcGRhdGVFeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgU3RyaW5nIFNRTFN0YXRlLAorICAgICAgICAgICAgaW50W10gdXBkYXRlQ291bnRzLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBTUUxTdGF0ZSwgY2F1c2UpOworICAgICAgICB0aGlzLnVwZGF0ZUNvdW50cyA9IHVwZGF0ZUNvdW50czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIEJhdGNoVXBkYXRlRXhjZXB0aW9uIG9iamVjdC4gVGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0CisgICAgICogdG8gdGhlIGdpdmVuIGNhdXNlIFRocm93YWJsZSBvYmplY3QgYW5kIHRoZSB1cGRhdGVDb3VudHMgYXJyYXkgc2V0IHRvIHRoZQorICAgICAqIGludCBhcnJheSBwYXJhbWV0ZXIuIFZlbmRvckNvZGUgaXMgc2V0IHRvIHRoZSBnaXZlbiB2ZW5kb3JDb2RlLiBTUUxTdGF0ZQorICAgICAqIGlzIGluaXRpYWxpemVkIHRvIG51bGwgd2hpbGUgdmVuZG9yQ29kZSBpcyB6ZXJvLgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcyBTUUxFeGNlcHRpb24KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgQmF0Y2hVcGRhdGVFeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgU3RyaW5nIFNRTFN0YXRlLCBpbnQgdmVuZG9yQ29kZSwKKyAgICAgICAgICAgIGludFtdIHVwZGF0ZUNvdW50cywgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgU1FMU3RhdGUsIHZlbmRvckNvZGUsIGNhdXNlKTsKKyAgICAgICAgdGhpcy51cGRhdGVDb3VudHMgPSB1cGRhdGVDb3VudHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHtAY29kZSBCYXRjaFVwZGF0ZUV4Y2VwdGlvbn0gd2l0aCB0aGUge0Bjb2RlIHVwZGF0ZUNvdW50c30gc2V0CisgICAgICogdG8gdGhlIHN1cHBsaWVkIHZhbHVlLiBBbGwgb3RoZXIgZmllbGRzIGFyZSBzZXQgdG8gdGhlaXIKKyAgICAgKiBkZWZhdWx0IHZhbHVlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cGRhdGVDb3VudHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiB7QGNvZGUgdXBkYXRlQ291bnRzfSBnaXZpbmcgdGhlIG51bWJlciBvZgorICAgICAqICAgICAgICAgICAgc3VjY2Vzc2Z1bCB1cGRhdGVzIChvciBhbm90aGVyIHN0YXR1cyBjb2RlKSBmb3IgZWFjaCBjb21tYW5kCisgICAgICogICAgICAgICAgICBpbiB0aGUgYmF0Y2ggdGhhdCB3YXMgYXR0ZW1wdGVkLgorICAgICAqLworICAgIHB1YmxpYyBCYXRjaFVwZGF0ZUV4Y2VwdGlvbihpbnRbXSB1cGRhdGVDb3VudHMpIHsKKyAgICAgICAgdGhpcy51cGRhdGVDb3VudHMgPSB1cGRhdGVDb3VudHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHtAY29kZSBCYXRjaFVwZGF0ZUV4Y2VwdGlvbn0gd2l0aCB0aGUge0Bjb2RlIHVwZGF0ZUNvdW50c30gYW5kCisgICAgICoge0Bjb2RlIHJlYXNvbn0gc2V0IHRvIHRoZSBzdXBwbGllZCB2YWx1ZXMuIEFsbCBvdGhlciBmaWVsZHMgYXJlIHNldCB0byB0aGVpcgorICAgICAqIGRlZmF1bHQgdmFsdWVzLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIG1lc3NhZ2UgcHJvdmlkaW5nIGluZm9ybWF0aW9uIGFib3V0IHRoZSBzb3VyY2Ugb2YgdGhpcworICAgICAqICAgICAgICAgICAgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSB1cGRhdGVDb3VudHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiB7QGNvZGUgdXBkYXRlQ291bnRzfSBnaXZpbmcgdGhlIG51bWJlciBvZgorICAgICAqICAgICAgICAgICAgc3VjY2Vzc2Z1bCB1cGRhdGVzIChvciBhbm90aGVyIHN0YXR1cyBjb2RlKSBmb3IgZWFjaCBjb21tYW5kCisgICAgICogICAgICAgICAgICBpbiB0aGUgYmF0Y2ggdGhhdCB3YXMgYXR0ZW1wdGVkLgorICAgICAqLworICAgIHB1YmxpYyBCYXRjaFVwZGF0ZUV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBpbnRbXSB1cGRhdGVDb3VudHMpIHsKKyAgICAgICAgc3VwZXIocmVhc29uKTsKKyAgICAgICAgdGhpcy51cGRhdGVDb3VudHMgPSB1cGRhdGVDb3VudHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHtAY29kZSBCYXRjaFVwZGF0ZUV4Y2VwdGlvbn0gd2l0aCB0aGUge0Bjb2RlIHJlYXNvbn0sIHtAY29kZQorICAgICAqIFNRTFN0YXRlfSBhbmQge0Bjb2RlIHVwZGF0ZUNvdW50c30gc2V0IHRvIHRoZSBzdXBwbGllZCB2YWx1ZXMuIEFsbCBvdGhlcgorICAgICAqIGZpZWxkcyBhcmUgc2V0IHRvIHRoZWlyIGRlZmF1bHQgdmFsdWVzLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIG1lc3NhZ2UgcHJvdmlkaW5nIGluZm9ybWF0aW9uIGFib3V0IHRoZSBzb3VyY2Ugb2YgdGhpcworICAgICAqICAgICAgICAgICAgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBTUUxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIFgvT1BFTiB2YWx1ZSB0byB1c2UgZm9yIHRoZSB7QGNvZGUgU1FMU3RhdGV9CisgICAgICogQHBhcmFtIHVwZGF0ZUNvdW50cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHtAY29kZSB1cGRhdGVDb3VudHN9IGdpdmluZyB0aGUgbnVtYmVyIG9mCisgICAgICogICAgICAgICAgICBzdWNjZXNzZnVsIHVwZGF0ZXMgKG9yIGFub3RoZXIgc3RhdHVzIGNvZGUpIGZvciBlYWNoIGNvbW1hbmQKKyAgICAgKiAgICAgICAgICAgIGluIHRoZSBiYXRjaCB0aGF0IHdhcyBhdHRlbXB0ZWQuCisgICAgICovCisgICAgcHVibGljIEJhdGNoVXBkYXRlRXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBTUUxTdGF0ZSwKKyAgICAgICAgICAgIGludFtdIHVwZGF0ZUNvdW50cykgeworICAgICAgICBzdXBlcihyZWFzb24sIFNRTFN0YXRlKTsKKyAgICAgICAgdGhpcy51cGRhdGVDb3VudHMgPSB1cGRhdGVDb3VudHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHtAY29kZSBCYXRjaFVwZGF0ZUV4Y2VwdGlvbn0gZm9yIHRoZSBjYXNlIHdoZXJlIGFsbCByZWxldmFudAorICAgICAqIGluZm9ybWF0aW9uIGlzIHByb3ZpZGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIG1lc3NhZ2UgcHJvdmlkaW5nIGluZm9ybWF0aW9uIGFib3V0IHRoZSBzb3VyY2Ugb2YgdGhpcworICAgICAqICAgICAgICAgICAgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBTUUxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIFgvT1BFTiB2YWx1ZSB0byB1c2UgZm9yIHRoZSB7QGNvZGUgU1FMU3RhdGV9LgorICAgICAqIEBwYXJhbSB2ZW5kb3JDb2RlCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gdXNlIGZvciB0aGUgdmVuZG9yIGVycm9yIGNvZGUuCisgICAgICogQHBhcmFtIHVwZGF0ZUNvdW50cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHtAY29kZSB1cGRhdGVDb3VudHN9IGdpdmluZyB0aGUgbnVtYmVyIG9mCisgICAgICogICAgICAgICAgICBzdWNjZXNzZnVsIHVwZGF0ZXMgKG9yIGFub3RoZXIgc3RhdHVzIGNvZGUpIGZvciBlYWNoIGNvbW1hbmQKKyAgICAgKiAgICAgICAgICAgIGluIHRoZSBiYXRjaCB0aGF0IHdhcyBhdHRlbXB0ZWQuCisgICAgICovCisgICAgcHVibGljIEJhdGNoVXBkYXRlRXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBTUUxTdGF0ZSwgaW50IHZlbmRvckNvZGUsCisgICAgICAgICAgICBpbnRbXSB1cGRhdGVDb3VudHMpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBTUUxTdGF0ZSwgdmVuZG9yQ29kZSk7CisgICAgICAgIHRoaXMudXBkYXRlQ291bnRzID0gdXBkYXRlQ291bnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIDxpPnVwZGF0ZSBjb3VudDwvaT4gYXJyYXkgZ2l2aW5nIHN0YXR1cyBpbmZvcm1hdGlvbiBmb3IgZXZlcnkKKyAgICAgKiBjb21tYW5kIHRoYXQgd2FzIGF0dGVtcHRlZCBpbiB0aGUgYmF0Y2guCisgICAgICogPHA+CisgICAgICogSWYgYSBiYXRjaCB1cGRhdGUgY29tbWFuZCBmYWlscyBhbmQgYSB7QGNvZGUgQmF0Y2hVcGRhdGVFeGNlcHRpb259IGlzCisgICAgICogdGhyb3duLCB0aGUgSkRCQyBkcml2ZXIgbWF5IGNvbnRpbnVlIHByb2Nlc3NpbmcgdGhlIHJlbWFpbmluZyBjb21tYW5kcyBpbgorICAgICAqIHRoZSBiYXRjaC4gSWYgdGhlIGRyaXZlciBkb2VzIHNvLCB0aGUgYXJyYXkgcmV0dXJuZWQgYnkge0Bjb2RlCisgICAgICogQmF0Y2hVcGRhdGVFeGNlcHRpb24uZ2V0VXBkYXRlQ291bnRzfSBoYXMgYW4gZWxlbWVudCBmb3IgZXZlcnkgY29tbWFuZCBpbgorICAgICAqIHRoZSBiYXRjaCwgbm90IG9ubHkgdGhvc2UgdGhhdCBleGVjdXRlZCBzdWNjZXNzZnVsbHkuIEluIHRoaXMgY2FzZSwgdGhlCisgICAgICogYXJyYXkgZWxlbWVudCBmb3IgYW55IGNvbW1hbmQgd2hpY2ggZW5jb3VudGVyZWQgYSBwcm9ibGVtIGlzIHNldCB0bworICAgICAqIHtAY29kZSBTdGF0ZW1lbnQuRVhFQ1VURV9GQUlMRUR9LgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSB0aGF0IGNvbnRhaW5zIHRoZSBzdWNjZXNzZnVsIHVwZGF0ZSBjb3VudHMsIGJlZm9yZSB0aGlzCisgICAgICogICAgICAgICBleGNlcHRpb24gd2FzIHRocm93bi4gQWx0ZXJuYXRpdmVseSwgaWYgdGhlIGRyaXZlciBjb250aW51ZXMgdG8KKyAgICAgKiAgICAgICAgIHByb2Nlc3MgY29tbWFuZHMgZm9sbG93aW5nIGFuIGVycm9yLCBmb3IgZWFjaCBzdWNjZXNzaXZlIGNvbW1hbmQKKyAgICAgKiAgICAgICAgIHRoZXJlIGlzIGEgY29ycmVzcG9uZGluZyBlbGVtZW50IGluIHRoZSBhcnJheSBnaXZpbmcgb25lIG9mIHRoZQorICAgICAqICAgICAgICAgZm9sbG93aW5nIHN0YXR1cyB2YWx1ZXM6CisgICAgICogICAgICAgICA8b2w+CisgICAgICogICAgICAgICA8bGk+dGhlIG51bWJlciBvZiBzdWNjZXNzZnVsIHVwZGF0ZXM8L2xpPiA8bGk+e0Bjb2RlCisgICAgICogICAgICAgICBTdGF0ZW1lbnQuU1VDQ0VTU19OT19JTkZPfSBpbmRpY2F0aW5nIHRoYXQgdGhlIGNvbW1hbmQgY29tcGxldGVkCisgICAgICogICAgICAgICBzdWNjZXNzZnVsbHksIGJ1dCB0aGUgYW1vdW50IG9mIGFsdGVyZWQgcm93cyBpcyB1bmtub3duLjwvbGk+CisgICAgICogICAgICAgICA8bGk+e0Bjb2RlIFN0YXRlbWVudC5FWEVDVVRFX0ZBSUxFRH0gaW5kaWNhdGluZyB0aGF0IHRoZSBjb21tYW5kCisgICAgICogICAgICAgICB3YXMgdW5zdWNjZXNzZnVsLjwvbGk+CisgICAgICogICAgICAgICA8L29sPgorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSBnZXRVcGRhdGVDb3VudHMoKSB7CisgICAgICAgIHJldHVybiB1cGRhdGVDb3VudHM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL0Jsb2IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9CbG9iLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDQ2NWExZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9CbG9iLmphdmEKQEAgLTAsMCArMSwxOTEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworLyoqCisgKiBBIEphdmEgaW50ZXJmYWNlIHJlcHJlc2VudGluZyB0aGUgU1FMIHtAY29kZSBCTE9CfSB0eXBlLgorICogPHA+CisgKiBBbiBTUUwge0Bjb2RlIEJMT0J9IHR5cGUgc3RvcmVzIGEgbGFyZ2UgYXJyYXkgb2YgYmluYXJ5IGRhdGEgKGJ5dGVzKSBhcyB0aGUKKyAqIHZhbHVlIGluIGEgY29sdW1uIG9mIGEgZGF0YWJhc2UuCisgKiA8cD4KKyAqIFRoZSB7QGNvZGUgamF2YS5zcWwuQmxvYn0gaW50ZXJmYWNlIHByb3ZpZGVzIG1ldGhvZHMgZm9yIHNldHRpbmcgYW5kCisgKiByZXRyaWV2aW5nIGRhdGEgaW4gdGhlIHtAY29kZSBCbG9ifSwgZm9yIHF1ZXJ5aW5nIHtAY29kZSBCbG9ifSBkYXRhIGxlbmd0aCwKKyAqIGFuZCBmb3Igc2VhcmNoaW5nIGZvciBkYXRhIHdpdGhpbiB0aGUge0Bjb2RlIEJsb2J9LgorICovCitwdWJsaWMgaW50ZXJmYWNlIEJsb2IgeworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIHRoaXMge0Bjb2RlIEJsb2J9IG9iamVjdCBhcyBhIGJpbmFyeSBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgYmluYXJ5IHtAY29kZSBJbnB1dFN0cmVhbX0gZ2l2aW5nIGFjY2VzcyB0byB0aGUge0Bjb2RlIEJsb2J9CisgICAgICogICAgICAgICBkYXRhLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUge0Bjb2RlIEJsb2J9LgorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRCaW5hcnlTdHJlYW0oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIHtAY29kZSBsZW5ndGh9IGJ5dGVzIGZyb20gdGhpcyB7QGNvZGUgQmxvYn0sIHN0YXJ0aW5nIGF0IDEtYmFzZWQKKyAgICAgKiBvZmZzZXQge0Bjb2RlIHBvc30sIGFuZCByZXR1cm5zIHRoZW0gYXMgYSBiaW5hcnkgc3RyZWFtLgorICAgICAqCisgICAgICogQHJldHVybiBhIGJpbmFyeSB7QGNvZGUgSW5wdXRTdHJlYW19IGdpdmluZyBhY2Nlc3MgdG8gdGhlIHtAY29kZSBCbG9ifQorICAgICAqICAgICAgICAgZGF0YS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIHtAY29kZSBCbG9ifS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0QmluYXJ5U3RyZWFtKGxvbmcgcG9zLCBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgYSBwb3J0aW9uIG9mIHRoZSB2YWx1ZSBvZiB0aGlzIHtAY29kZSBCbG9ifSBhcyBhbiBhcnJheSBvZiBieXRlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3NpdGlvbiBvZiB0aGUgZmlyc3QgYnl0ZSBpbiB0aGUge0Bjb2RlIEJsb2J9IHRvIGdldCwKKyAgICAgKiAgICAgICAgICAgIHdoZXJlIHRoZSBmaXJzdCBieXRlIGluIHRoZSB7QGNvZGUgQmxvYn0gaGFzIHBvc2l0aW9uIDEuCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyB0byBnZXQuCisgICAgICogQHJldHVybiBhIGJ5dGUgYXJyYXkgY29udGFpbmluZyB0aGUgZGF0YSBmcm9tIHRoZSB7QGNvZGUgQmxvYn0sIHN0YXJ0aW5nCisgICAgICogICAgICAgICBhdCB7QGNvZGUgcG9zfSBhbmQgaXMgdXAgdG8ge0Bjb2RlIGxlbmd0aH0gYnl0ZXMgbG9uZy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIHtAY29kZSBCbG9ifS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEJ5dGVzKGxvbmcgcG9zLCBpbnQgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGJ5dGVzIGluIHRoaXMge0Bjb2RlIEJsb2J9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgbG9uZ30gdmFsdWUgd2l0aCB0aGUgbGVuZ3RoIG9mIHRoZSB7QGNvZGUgQmxvYn0gaW4KKyAgICAgKiAgICAgICAgIGJ5dGVzLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUge0Bjb2RlIEJsb2J9LgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGxlbmd0aCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2ggZm9yIHRoZSBwb3NpdGlvbiBpbiB0aGlzIHtAY29kZSBCbG9ifSBhdCB3aGljaCBhIHNwZWNpZmllZCBwYXR0ZXJuCisgICAgICogYmVnaW5zLCBzdGFydGluZyBhdCBhIHNwZWNpZmllZCBwb3NpdGlvbiB3aXRoaW4gdGhlIHtAY29kZSBCbG9ifS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXR0ZXJuCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBCbG9ifSBjb250YWluaW5nIHRoZSBwYXR0ZXJuIG9mIGRhdGEgdG8gc2VhcmNoIGZvciBpbgorICAgICAqICAgICAgICAgICAgdGhpcyB7QGNvZGUgQmxvYn0uCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgcG9zaXRpb24gd2l0aGluIHRoaXMge0Bjb2RlIEJsb2J9IHRvIHN0YXJ0IHRoZSBzZWFyY2gsCisgICAgICogICAgICAgICAgICB3aGVyZSB0aGUgZmlyc3QgcG9zaXRpb24gaW4gdGhlIHtAY29kZSBCbG9ifSBpcyB7QGNvZGUgMX0uCisgICAgICogQHJldHVybiBhIHtAY29kZSBsb25nfSB2YWx1ZSB3aXRoIHRoZSBwb3NpdGlvbiBhdCB3aGljaCB0aGUgcGF0dGVybgorICAgICAqICAgICAgICAgYmVnaW5zLiBSZXR1cm5zIHtAY29kZSAtMX0gaWYgdGhlIHBhdHRlcm4gaXMgbm90IGZvdW5kIGluIHRoaXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBCbG9ifS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIHtAY29kZSBCbG9ifS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBwb3NpdGlvbihCbG9iIHBhdHRlcm4sIGxvbmcgc3RhcnQpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2ggZm9yIHRoZSBwb3NpdGlvbiBpbiB0aGlzIHtAY29kZSBCbG9ifSBhdCB3aGljaCB0aGUgc3BlY2lmaWVkCisgICAgICogcGF0dGVybiBiZWdpbnMsIHN0YXJ0aW5nIGF0IGEgc3BlY2lmaWVkIHBvc2l0aW9uIHdpdGhpbiB0aGUge0Bjb2RlIEJsb2J9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIGEgYnl0ZSBhcnJheSBjb250YWluaW5nIHRoZSBwYXR0ZXJuIG9mIGRhdGEgdG8gc2VhcmNoIGZvciBpbgorICAgICAqICAgICAgICAgICAgdGhpcyB7QGNvZGUgQmxvYn0uCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgcG9zaXRpb24gd2l0aGluIHRoaXMge0Bjb2RlIEJsb2J9IHRvIHN0YXJ0IHRoZSBzZWFyY2gsCisgICAgICogICAgICAgICAgICB3aGVyZSB0aGUgZmlyc3QgcG9zaXRpb24gaW4gdGhlIHtAY29kZSBCbG9ifSBpcyB7QGNvZGUgMX0uCisgICAgICogQHJldHVybiBhIHtAY29kZSBsb25nfSB2YWx1ZSB3aXRoIHRoZSBwb3NpdGlvbiBhdCB3aGljaCB0aGUgcGF0dGVybgorICAgICAqICAgICAgICAgYmVnaW5zLiBSZXR1cm5zIHtAY29kZSAtMX0gaWYgdGhlIHBhdHRlcm4gaXMgbm90IGZvdW5kIGluIHRoaXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBCbG9ifS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIHtAY29kZSBCbG9ifS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBwb3NpdGlvbihieXRlW10gcGF0dGVybiwgbG9uZyBzdGFydCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgYSBzdHJlYW0gdGhhdCBjYW4gYmUgdXNlZCB0byB3cml0ZSBiaW5hcnkgZGF0YSB0byB0aGlzIHtAY29kZSBCbG9ifS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3NpdGlvbiB3aXRoaW4gdGhpcyB7QGNvZGUgQmxvYn0gYXQgd2hpY2ggdG8gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHdyaXRpbmcsIHdoZXJlIHRoZSBmaXJzdCBwb3NpdGlvbiBpbiB0aGUge0Bjb2RlIEJsb2J9IGlzCisgICAgICogICAgICAgICAgICB7QGNvZGUgMX0uCisgICAgICogQHJldHVybiBhIGJpbmFyeSB7QGNvZGUgSW5wdXRTdHJlYW19IHdoaWNoIGNhbiBiZSB1c2VkIHRvIHdyaXRlIGRhdGEgaW50bworICAgICAqICAgICAgICAgdGhlIHtAY29kZSBCbG9ifSBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUge0Bjb2RlIEJsb2J9LgorICAgICAqLworICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gc2V0QmluYXJ5U3RyZWFtKGxvbmcgcG9zKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgc3BlY2lmaWVkIGFycmF5IG9mIGJ5dGVzIHRvIHRoaXMge0Bjb2RlIEJsb2J9IG9iamVjdCwgc3RhcnRpbmcKKyAgICAgKiBhdCBhIHNwZWNpZmllZCBwb3NpdGlvbi4gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcG9zCisgICAgICogICAgICAgICAgICB0aGUgcG9zaXRpb24gd2l0aGluIHRoaXMge0Bjb2RlIEJsb2J9IGF0IHdoaWNoIHRvIHN0YXJ0CisgICAgICogICAgICAgICAgICB3cml0aW5nLCB3aGVyZSB0aGUgZmlyc3QgcG9zaXRpb24gaW4gdGhlIHtAY29kZSBCbG9ifSBpcworICAgICAqICAgICAgICAgICAge0Bjb2RlIDF9LgorICAgICAqIEBwYXJhbSB0aGVCeXRlcworICAgICAqICAgICAgICAgICAgYW4gYXJyYXkgb2YgYnl0ZXMgdG8gd3JpdGUgaW50byB0aGUge0Bjb2RlIEJsb2J9LgorICAgICAqIEByZXR1cm4gYW4gaW50ZWdlciBjb250YWluaW5nIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiB0byB0aGUge0Bjb2RlCisgICAgICogICAgICAgICBCbG9ifS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIHtAY29kZSBCbG9ifS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNldEJ5dGVzKGxvbmcgcG9zLCBieXRlW10gdGhlQnl0ZXMpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBwb3J0aW9uIG9mIGEgc3BlY2lmaWVkIGJ5dGUgYXJyYXkgdG8gdGhpcyB7QGNvZGUgQmxvYn0uIFJldHVybnMKKyAgICAgKiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcG9zCisgICAgICogICAgICAgICAgICB0aGUgcG9zaXRpb24gd2l0aGluIHRoaXMge0Bjb2RlIEJsb2J9IGF0IHdoaWNoIHRvIHN0YXJ0CisgICAgICogICAgICAgICAgICB3cml0aW5nLCB3aGVyZSB0aGUgZmlyc3QgcG9zaXRpb24gaW4gdGhlIHtAY29kZSBCbG9ifSBpcworICAgICAqICAgICAgICAgICAge0Bjb2RlIDF9LgorICAgICAqIEBwYXJhbSB0aGVCeXRlcworICAgICAqICAgICAgICAgICAgYW4gYXJyYXkgb2YgYnl0ZXMgdG8gd3JpdGUgaW50byB0aGUge0Bjb2RlIEJsb2J9LgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW50byB0aGUgYnl0ZSBhcnJheSBmcm9tIHdoaWNoIHRvIHN0YXJ0IHdyaXRpbmcKKyAgICAgKiAgICAgICAgICAgIGRhdGEgLSB0aGUgZmlyc3QgYnl0ZSBpbiB0aGUgYXJyYXkgaGFzIG9mZnNldCB7QGNvZGUgMH0uCisgICAgICogQHBhcmFtIGxlbgorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiBkYXRhIHRvIHdyaXRlIGluIG51bWJlciBvZiBieXRlcy4KKyAgICAgKiBAcmV0dXJuIGFuIGludGVnZXIgY29udGFpbmluZyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gdG8gdGhlIHtAY29kZQorICAgICAqICAgICAgICAgQmxvYn0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSB7QGNvZGUgQmxvYn0uCisgICAgICovCisgICAgcHVibGljIGludCBzZXRCeXRlcyhsb25nIHBvcywgYnl0ZVtdIHRoZUJ5dGVzLCBpbnQgb2Zmc2V0LCBpbnQgbGVuKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFRydW5jYXRlIHRoZSB2YWx1ZSBvZiB0aGlzIHtAY29kZSBCbG9ifSBvYmplY3QgdG8gYSBzcGVjaWZpZWQgbGVuZ3RoIGluCisgICAgICogYnl0ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIGRhdGEgaW4gYnl0ZXMgYWZ0ZXIgd2hpY2ggdGhpcyB7QGNvZGUgQmxvYn0KKyAgICAgKiAgICAgICAgICAgIGlzIHRvIGJlIHRydW5jYXRlZC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIHtAY29kZSBCbG9ifS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0cnVuY2F0ZShsb25nIGxlbikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEZyZWVzIGFueSByZXNvdXJjZXMgaGVsZCBieSB0aGlzIGJsb2IuIEFmdGVyIHtAY29kZSBmcmVlfSBpcyBjYWxsZWQsIGNhbGxpbmcKKyAgICAgKiBtZXRob2Qgb3RoZXIgdGhhbiB7QGNvZGUgZnJlZX0gd2lsbCB0aHJvdyB7QGNvZGUgU1FMRXhjZXB0aW9ufSAoY2FsbGluZyB7QGNvZGUgZnJlZX0KKyAgICAgKiByZXBlYXRlZGx5IHdpbGwgZG8gbm90aGluZykuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZyZWUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL0NhbGxhYmxlU3RhdGVtZW50LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvQ2FsbGFibGVTdGF0ZW1lbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YmQ5YzUyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL0NhbGxhYmxlU3RhdGVtZW50LmphdmEKQEAgLTAsMCArMSwxNjIyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CitpbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEudXRpbC5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCisvKioKKyAqIEFuIGludGVyZmFjZSB1c2VkIHRvIGNhbGwgPGk+U3RvcmVkIFByb2NlZHVyZXM8L2k+LgorICogPHA+CisgKiBUaGUgSkRCQyBBUEkgcHJvdmlkZXMgYW4gU1FMIGVzY2FwZSBzeW50YXggYWxsb3dpbmcgPGk+U3RvcmVkIFByb2NlZHVyZXM8L2k+CisgKiB0byBiZSBjYWxsZWQgaW4gYSBzdGFuZGFyZCB3YXkgZm9yIGFsbCBkYXRhYmFzZXMuIFRoZSBKREJDIGVzY2FwZSBzeW50YXggaGFzCisgKiB0d28gZm9ybXMuIE9uZSBmb3JtIGluY2x1ZGVzIGEgcmVzdWx0IHBhcmFtZXRlci4gVGhlIHNlY29uZCBmb3JtIGRvZXMgbm90CisgKiBpbmNsdWRlIGEgcmVzdWx0IHBhcmFtZXRlci4gV2hlcmUgdGhlIHJlc3VsdCBwYXJhbWV0ZXIgaXMgdXNlZCwgaXQgbXVzdCBiZQorICogZGVjbGFyZWQgYXMgYW4ge0Bjb2RlIE9VVH0gcGFyYW1ldGVyLiBPdGhlciBwYXJhbWV0ZXJzIGNhbiBiZSBkZWNsYXJlZCBhcworICoge0Bjb2RlIElOfSwge0Bjb2RlIE9VVH0sIG9yIHtAY29kZSBJTk9VVH0uIFBhcmFtZXRlcnMgYXJlIHJlZmVyZW5jZWQgZWl0aGVyIGJ5CisgKiBuYW1lIG9yIGJ5IGEgbnVtZXJpY2FsIGluZGV4IHN0YXJ0aW5nIGF0IDEuCisgKiA8cD4KKyAqIFRoZSBjb3JyZWN0IHN5bnRheCBpczoKKyAqIDxkZD4KKyAqIDxkbD4KKyAqIHsgPz0gY2FsbCAmbHQ7cHJvY2VkdXJlbmFtZSZndDsgWyggW3BhcmFtZXRlcjEscGFyYW1ldGVyMiwuLi5dICldIH0KKyAqIDwvZGw+CisgKiA8ZGw+CisgKiB7IGNhbGwgJmx0O3Byb2NlZHVyZW5hbWUmZ3Q7IFsoIFtwYXJhbWV0ZXIxLHBhcmFtZXRlcjIsLi4uXSApXSB9CisgKiA8L2RsPgorICogPC9jb2RlPjwvZGQ+CisgKiB7QGNvZGUgSU59IHBhcmFtZXRlcnMgYXJlIHNldCBiZWZvcmUgY2FsbGluZyB0aGUgcHJvY2VkdXJlLAorICogdXNpbmcgdGhlIHNldHRlciBtZXRob2RzIHdoaWNoIGFyZSBpbmhlcml0ZWQgZnJvbSB7QGNvZGUgUHJlcGFyZWRTdGF0ZW1lbnR9LgorICogRm9yIHtAY29kZSBPVVR9IHBhcmFtZXRlcnMsIHRoZWlyIHR5cGUgbXVzdCBiZSByZWdpc3RlcmVkIGJlZm9yZSBleGVjdXRpbmcKKyAqIHRoZSBzdG9yZWQgcHJvY2VkdXJlLiBUaGUgdmFsdWVzIGFyZSByZXRyaWV2ZWQgdXNpbmcgdGhlIGdldHRlciBtZXRob2RzCisgKiBkZWZpbmVkIGluIHRoZSB7QGNvZGUgQ2FsbGFibGVTdGF0ZW1lbnR9IGludGVyZmFjZS4KKyAqIDxwPgorICoge0Bjb2RlIENhbGxhYmxlU3RhdGVtZW50fXMgY2FuIHJldHVybiBvbmUgb3IgbW9yZSB7QGNvZGUgUmVzdWx0U2V0c30uIEluIHRoZQorICogZXZlbnQgdGhhdCBtdWx0aXBsZSB7QGNvZGUgUmVzdWx0U2V0c30gYXJlIHJldHVybmVkLCB0aGV5IGFyZSBhY2Nlc3NlZCB1c2luZworICogdGhlIG1ldGhvZHMgaW5oZXJpdGVkIGZyb20gdGhlIHtAY29kZSBTdGF0ZW1lbnR9IGludGVyZmFjZS4KKyAqLworcHVibGljIGludGVyZmFjZSBDYWxsYWJsZVN0YXRlbWVudCBleHRlbmRzIFByZXBhcmVkU3RhdGVtZW50IHsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIEpEQkMge0Bjb2RlIEFSUkFZfSBwYXJhbWV0ZXIgYXMgYQorICAgICAqIHtAY29kZSBqYXZhLnNxbC5BcnJheX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgamF2YS5zcWwuQXJyYXl9IGNvbnRhaW5pbmcgdGhlIHBhcmFtZXRlciB2YWx1ZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBBcnJheSBnZXRBcnJheShpbnQgcGFyYW1ldGVySW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBKREJDIHtAY29kZSBBUlJBWX0gcGFyYW1ldGVyIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuQXJyYXl9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXNpcmVkIHBhcmFtZXRlcidzIG5hbWUuCisgICAgICogQHJldHVybiBhIHtAY29kZSBqYXZhLnNxbC5BcnJheX0gY29udGFpbmluZyB0aGUgcGFyYW1ldGVyJ3MgdmFsdWUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXJyYXkgZ2V0QXJyYXkoU3RyaW5nIHBhcmFtZXRlck5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAbGluayBCaWdEZWNpbWFsfSByZXByZXNlbnRhdGlvbiBvZiB0aGUgSkRCQyB7QGNvZGUKKyAgICAgKiBOVU1FUklDfSBwYXJhbWV0ZXIgc3BlY2lmaWVkIGJ5IHRoZSBpbnB1dCBpbmRleC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXggd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMgaW5kZXgKKyAgICAgKiAgICAgICAgICAgIDEuCisgICAgICogQHJldHVybiBhIHtAY29kZSBqYXZhLm1hdGguQmlnRGVjaW1hbH0gcmVwcmVzZW50aW5nIHRoZSB2YWx1ZSBvZiB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBwYXJhbWV0ZXIuIFRoZSB2YWx1ZSB7QGNvZGUgbnVsbH0gaXMgcmV0dXJuZWQgaWYKKyAgICAgKiAgICAgICAgIHRoZSBwYXJhbWV0ZXIgaW4gcXVlc3Rpb24gaXMgYW4gU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsIGdldEJpZ0RlY2ltYWwoaW50IHBhcmFtZXRlckluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGxpbmsgQmlnRGVjaW1hbH0gcmVwcmVzZW50YXRpb24gb2YgdGhlIEpEQkMge0Bjb2RlCisgICAgICogTlVNRVJJQ30gcGFyYW1ldGVyIHNwZWNpZmllZCBieSB0aGUgaW5wdXQgaW5kZXguIFRoZSBudW1iZXIgb2YgZGlnaXRzCisgICAgICogYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQgaXMgc3BlY2lmaWVkIGJ5IHtAY29kZSBzY2FsZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMS4KKyAgICAgKiBAcGFyYW0gc2NhbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgZGlnaXRzIGFmdGVyIHRoZSBkZWNpbWFsIHBvaW50IHRvIGdldC4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIGphdmEubWF0aC5CaWdEZWNpbWFsfSByZXByZXNlbnRpbmcgdGhlIHZhbHVlIG9mIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIHBhcmFtZXRlci4gVGhlIHZhbHVlIHtAY29kZSBudWxsfSBpcyByZXR1cm5lZCBpZgorICAgICAqICAgICAgICAgdGhlIHBhcmFtZXRlciBpbiBxdWVzdGlvbiBpcyBhbiBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZ2V0QmlnRGVjaW1hbChpbnQpfSBvcgorICAgICAqICAgICAgICAgICAgIHtAbGluayAjZ2V0QmlnRGVjaW1hbChTdHJpbmcpfQorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIEJpZ0RlY2ltYWwgZ2V0QmlnRGVjaW1hbChpbnQgcGFyYW1ldGVySW5kZXgsIGludCBzY2FsZSkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAbGluayBCaWdEZWNpbWFsfSByZXByZXNlbnRhdGlvbiBvZiB0aGUgSkRCQyB7QGNvZGUKKyAgICAgKiBOVU1FUklDfSBwYXJhbWV0ZXIgc3BlY2lmaWVkIGJ5IHRoZSBpbnB1dCBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXNpcmVkIHBhcmFtZXRlcidzIG5hbWUuCisgICAgICogQHJldHVybiBhIHtAY29kZSBqYXZhLm1hdGguQmlnRGVjaW1hbH0gcmVwcmVzZW50aW5nIHRoZSB2YWx1ZSBvZiB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBwYXJhbWV0ZXIuIFRoZSB2YWx1ZSB7QGNvZGUgbnVsbH0gaXMgcmV0dXJuZWQgaWYKKyAgICAgKiAgICAgICAgIHRoZSBwYXJhbWV0ZXIgaW4gcXVlc3Rpb24gaXMgYW4gU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBCaWdEZWNpbWFsIGdldEJpZ0RlY2ltYWwoU3RyaW5nIHBhcmFtZXRlck5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBKREJDIHtAY29kZSBCTE9CfSBwYXJhbWV0ZXIgYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5CbG9ifS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgamF2YS5zcWwuQmxvYn0gcmVwcmVzZW50aW5nIHRoZSB2YWx1ZSBvZiB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBwYXJhbWV0ZXIuIFRoZSB2YWx1ZSB7QGNvZGUgbnVsbH0gaXMgcmV0dXJuZWQgaWYKKyAgICAgKiAgICAgICAgIHRoZSBwYXJhbWV0ZXIgaW4gcXVlc3Rpb24gaXMgYW4gU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBCbG9iIGdldEJsb2IoaW50IHBhcmFtZXRlckluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgSkRCQyB7QGNvZGUgQkxPQn0gcGFyYW1ldGVyIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuQmxvYn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGRlc2lyZWQgcGFyYW1ldGVyJ3MgbmFtZS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIGphdmEuc3FsLkJsb2J9IHJlcHJlc2VudGluZyB0aGUgdmFsdWUgb2YgdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgcGFyYW1ldGVyLiBUaGUgdmFsdWUge0Bjb2RlIG51bGx9IGlzIHJldHVybmVkIGlmCisgICAgICogICAgICAgICB0aGUgcGFyYW1ldGVyIGluIHF1ZXN0aW9uIGlzIGFuIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmxvYiBnZXRCbG9iKFN0cmluZyBwYXJhbWV0ZXJOYW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgSkRCQyB7QGNvZGUgQklUfSBwYXJhbWV0ZXIgYXMgYSBib29sZWFuLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHJldHVybiBhIHtAY29kZSBib29sZWFufSByZXByZXNlbnRpbmcgdGhlIHBhcmFtZXRlciB2YWx1ZS4ge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgICAgaXMgcmV0dXJuZWQgaWYgdGhlIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRCb29sZWFuKGludCBwYXJhbWV0ZXJJbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIEpEQkMge0Bjb2RlIEJJVH0gcGFyYW1ldGVyIGFzIGEge0Bjb2RlCisgICAgICogYm9vbGVhbn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGRlc2lyZWQgcGFyYW1ldGVyJ3MgbmFtZS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIGJvb2xlYW59IHJlcHJlc2VudGF0aW9uIG9mIHRoZSB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBpcyByZXR1cm5lZCBpZiB0aGUgU1FMIHZhbHVlIGlzIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldEJvb2xlYW4oU3RyaW5nIHBhcmFtZXRlck5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBKREJDIHtAY29kZSBUSU5ZSU5UfSBwYXJhbWV0ZXIgYXMgYSB7QGNvZGUKKyAgICAgKiBieXRlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgYnl0ZX0gcmVwcmVzZW50YXRpb24gb2YgdGhlIHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIuCisgICAgICogICAgICAgICAgICB7QGNvZGUgMH0gaXMgcmV0dXJuZWQgaWYgdGhlIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZSBnZXRCeXRlKGludCBwYXJhbWV0ZXJJbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIEpEQkMge0Bjb2RlIFRJTllJTlR9IHBhcmFtZXRlciBhcyBhIEphdmEKKyAgICAgKiB7QGNvZGUgYnl0ZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGRlc2lyZWQgcGFyYW1ldGVyJ3MgbmFtZS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIGJ5dGV9IHJlcHJlc2VudGF0aW9uIG9mIHRoZSB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqICAgICAgICAge0Bjb2RlIDB9IGlzIHJldHVybmVkIGlmIHRoZSBTUUwgdmFsdWUgaXMge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGJ5dGUgZ2V0Qnl0ZShTdHJpbmcgcGFyYW1ldGVyTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBieXRlIGFycmF5IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBpbmRleGVkIEpEQkMge0Bjb2RlIEJJTkFSWX0gb3IKKyAgICAgKiB7QGNvZGUgVkFSQklOQVJZfSBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMS4KKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIGJ5dGVzIGdpdmluZyB0aGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlci4ge0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpcyByZXR1cm5lZCBpZiB0aGUgdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0Qnl0ZXMoaW50IHBhcmFtZXRlckluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGJ5dGUgYXJyYXkgcmVwcmVzZW50YXRpb24gb2YgdGhlIG5hbWVkIEpEQkMge0Bjb2RlIEJJTkFSWX0gb3IKKyAgICAgKiB7QGNvZGUgVkFSQklOQVJZfSBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIGJ5dGVzIGdpdmluZyB0aGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlci4ge0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpcyByZXR1cm5lZCBpZiB0aGUgdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0Qnl0ZXMoU3RyaW5nIHBhcmFtZXRlck5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBKREJDIHtAY29kZSBDTE9CfSBwYXJhbWV0ZXIgYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5DbG9ifS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgamF2YS5zcWwuQ2xvYn0gcmVwcmVzZW50aW5nIHRoZSB2YWx1ZSBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgIHBhcmFtZXRlci4ge0Bjb2RlIG51bGx9IGlzIHJldHVybmVkIGlmIHRoZSB2YWx1ZSBpcyBTUUwKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgQ2xvYgorICAgICAqLworICAgIHB1YmxpYyBDbG9iIGdldENsb2IoaW50IHBhcmFtZXRlckluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgSkRCQyB7QGNvZGUgQ0xPQn0gcGFyYW1ldGVyIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuQ2xvYn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIGphdmEuc3FsLkNsb2J9IHdpdGggdGhlIHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIuIHtAY29kZQorICAgICAqICAgICAgICAgbnVsbH0gaXMgcmV0dXJuZWQgaWYgdGhlIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlIENsb2IKKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xvYiBnZXRDbG9iKFN0cmluZyBwYXJhbWV0ZXJOYW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBKREJDIHtAY29kZSBEQVRFfSBwYXJhbWV0ZXIgYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5EYXRlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBqYXZhLnNxbC5EYXRlfSByZXByZXNlbnRpbmcgdGhlIHBhcmFtZXRlcidzIHZhbHVlLgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlzIHJldHVybmVkIGlmIHRoZSB2YWx1ZSBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSBEYXRlCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0RGF0ZShpbnQgcGFyYW1ldGVySW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIEpEQkMge0Bjb2RlIERBVEV9IHBhcmFtZXRlciBhcyBhIHtAY29kZQorICAgICAqIGphdmEuc3FsLkRhdGV9LCB1c2luZyB0aGUgc3BlY2lmaWVkIHtAY29kZSBDYWxlbmRhcn0gdG8gY29uc3RydWN0IHRoZSBkYXRlLgorICAgICAqCisgICAgICogPHA+VGhlIEpEQkMgZHJpdmVyIHVzZXMgdGhlIGNhbGVuZGFyIHRvIGNyZWF0ZSB0aGUgRGF0ZSB1c2luZyBhIHBhcnRpY3VsYXIKKyAgICAgKiB0aW1lem9uZSBhbmQgbG9jYWxlLiBUaGUgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGUgZHJpdmVyIGlzIHRvIHVzZSB0aGUgVk0gZGVmYXVsdHMuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHBhcmFtIGNhbAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDYWxlbmRhcn0gdG8gdXNlIHRvIGNvbnN0cnVjdCB0aGUgZGF0ZQorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBqYXZhLnNxbC5EYXRlfSBnaXZpbmcgdGhlIHBhcmFtZXRlcidzIHZhbHVlLiB7QGNvZGUgbnVsbH0KKyAgICAgKiAgICAgICAgIGlzIHJldHVybmVkIGlmIHRoZSB2YWx1ZSBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSBEYXRlCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0RGF0ZShpbnQgcGFyYW1ldGVySW5kZXgsIENhbGVuZGFyIGNhbCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgSkRCQyB7QGNvZGUgREFURX0gcGFyYW1ldGVyIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuRGF0ZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGRlc2lyZWQgcGFyYW1ldGVyLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBqYXZhLnNxbC5EYXRlfSBnaXZpbmcgdGhlIHBhcmFtZXRlcidzIHZhbHVlLiB7QGNvZGUgbnVsbH0KKyAgICAgKiAgICAgICAgIGlzIHJldHVybmVkIGlmIHRoZSB2YWx1ZSBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSBEYXRlCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0RGF0ZShTdHJpbmcgcGFyYW1ldGVyTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgSkRCQyB7QGNvZGUgREFURX0gcGFyYW1ldGVyIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuRGF0ZX0sIHVzaW5nIHRoZSBzcGVjaWZpZWQge0Bjb2RlIENhbGVuZGFyfSB0byBjb25zdHJ1Y3QgdGhlIGRhdGUuCisgICAgICoKKyAgICAgKiA8cD5UaGUgSkRCQyBkcml2ZXIgdXNlcyB0aGUgY2FsZW5kYXIgdG8gY3JlYXRlIHRoZSBkYXRlIHVzaW5nIGEgcGFydGljdWxhcgorICAgICAqIHRpbWV6b25lIGFuZCBsb2NhbGUuIFRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIHRoZSBkcml2ZXIgaXMgdG8gdXNlIHRoZSBWTSBkZWZhdWx0cy4KKyAgICAgKiBTZWUgIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGRlc2lyZWQgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbSBjYWwKKyAgICAgKiAgICAgICAgICAgIHVzZWQgZm9yIGNyZWF0aW5nIHRoZSByZXR1cm5lZCB7QGNvZGUgRGF0ZX0uCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIGphdmEuc3FsLkRhdGV9IGdpdmluZyB0aGUgcGFyYW1ldGVyJ3MgdmFsdWUuIHtAY29kZSBudWxsfQorICAgICAqICAgICAgICAgaXMgcmV0dXJuZWQgaWYgdGhlIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlIERhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0ZSBnZXREYXRlKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBDYWxlbmRhciBjYWwpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIEpEQkMge0Bjb2RlIERPVUJMRX0gcGFyYW1ldGVyIGFzIGEKKyAgICAgKiB7QGNvZGUgZG91YmxlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlcidzIHZhbHVlIGFzIGEge0Bjb2RlIGRvdWJsZX0uIHtAY29kZSAwLjB9CisgICAgICogICAgICAgICBpcyByZXR1cm5lZCBpZiB0aGUgdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgZ2V0RG91YmxlKGludCBwYXJhbWV0ZXJJbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgSkRCQyB7QGNvZGUgRE9VQkxFfSBwYXJhbWV0ZXIgYXMgYQorICAgICAqIHtAY29kZSBkb3VibGV9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBkZXNpcmVkIHBhcmFtZXRlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBwYXJhbWV0ZXIncyB2YWx1ZSBhcyBhIHtAY29kZSBkb3VibGV9LiB7QGNvZGUgMC4wfQorICAgICAqICAgICAgICAgaXMgcmV0dXJuZWQgaWYgdGhlIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIGdldERvdWJsZShTdHJpbmcgcGFyYW1ldGVyTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgSkRCQyB7QGNvZGUgRkxPQVR9IHBhcmFtZXRlciBhcyBhIHtAY29kZQorICAgICAqIGZsb2F0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlcidzIHZhbHVlIGFzIGEge0Bjb2RlIGZsb2F0fS4ge0Bjb2RlIDAuMH0KKyAgICAgKiAgICAgICAgIGlzIHJldHVybmVkIGlmIHRoZSB2YWx1ZSBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldEZsb2F0KGludCBwYXJhbWV0ZXJJbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgSkRCQyB7QGNvZGUgRkxPQVR9IHBhcmFtZXRlciBhcyBhIEphdmEKKyAgICAgKiB7QGNvZGUgZmxvYXR9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBkZXNpcmVkIHBhcmFtZXRlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBwYXJhbWV0ZXIncyB2YWx1ZSBhcyBhIHtAY29kZSBmbG9hdH0uIHtAY29kZSAwLjB9CisgICAgICogICAgICAgICBpcyByZXR1cm5lZCBpZiB0aGUgdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdCBnZXRGbG9hdChTdHJpbmcgcGFyYW1ldGVyTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgSkRCQyB7QGNvZGUgSU5URUdFUn0gcGFyYW1ldGVyIGFzIGFuCisgICAgICoge0Bjb2RlIGludH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMS4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgaW50fSBnaXZpbmcgdGhlIHBhcmFtZXRlcidzIHZhbHVlLiB7QGNvZGUgMH0KKyAgICAgKiAgICAgICAgIGlzIHJldHVybmVkIGlmIHRoZSB2YWx1ZSBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRJbnQoaW50IHBhcmFtZXRlckluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBKREJDIHtAY29kZSBJTlRFR0VSfSBwYXJhbWV0ZXIgYXMgYW4KKyAgICAgKiB7QGNvZGUgaW50fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZGVzaXJlZCBwYXJhbWV0ZXIuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIGludH0gZ2l2aW5nIHRoZSBwYXJhbWV0ZXIncyB2YWx1ZS4ge0Bjb2RlIDB9CisgICAgICogICAgICAgICBpcyByZXR1cm5lZCBpZiB0aGUgdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SW50KFN0cmluZyBwYXJhbWV0ZXJOYW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBKREJDIHtAY29kZSBCSUdJTlR9IHBhcmFtZXRlciBhcyBhCisgICAgICoge0Bjb2RlIGxvbmd9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIGxvbmd9IGdpdmluZyB0aGUgcGFyYW1ldGVyJ3MgdmFsdWUuIHtAY29kZSAwfQorICAgICAqICAgICAgICAgaXMgcmV0dXJuZWQgaWYgdGhlIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRMb25nKGludCBwYXJhbWV0ZXJJbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgSkRCQyB7QGNvZGUgQklHSU5UfSBwYXJhbWV0ZXIgYXMgYQorICAgICAqIHtAY29kZSBsb25nfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZGVzaXJlZCBwYXJhbWV0ZXIuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIGxvbmd9IGdpdmluZyB0aGUgcGFyYW1ldGVyJ3MgdmFsdWUuIHtAY29kZSAwfQorICAgICAqICAgICAgICAgaXMgcmV0dXJuZWQgaWYgdGhlIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRMb25nKFN0cmluZyBwYXJhbWV0ZXJOYW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgYXMgYSBKYXZhIHtAY29kZSBPYmplY3R9LgorICAgICAqIDxwPgorICAgICAqIFRoZSBvYmplY3QgdHlwZSByZXR1cm5lZCBpcyB0aGUgSkRCQyB0eXBlIHJlZ2lzdGVyZWQgZm9yIHRoZSBwYXJhbWV0ZXIKKyAgICAgKiB3aXRoIGEge0Bjb2RlIHJlZ2lzdGVyT3V0UGFyYW1ldGVyfSBjYWxsLiBJZiBhIHBhcmFtZXRlciB3YXMgcmVnaXN0ZXJlZAorICAgICAqIGFzIGEge0Bjb2RlIGphdmEuc3FsLlR5cGVzLk9USEVSfSB0aGVuIGl0IG1heSBob2xkIGFic3RyYWN0IHR5cGVzIHRoYXQKKyAgICAgKiBhcmUgcGFydGljdWxhciB0byB0aGUgY29ubmVjdGVkIGRhdGFiYXNlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHJldHVybiBhbiBPYmplY3QgaG9sZGluZyB0aGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0T2JqZWN0KGludCBwYXJhbWV0ZXJJbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGFzIGFuIHtAY29kZSBPYmplY3R9LiBUaGUKKyAgICAgKiB7QGNvZGUgTWFwfSBnaXZlcyB0aGUgY29ycmVzcG9uZGVuY2UgYmV0d2VlbiBTUUwgdHlwZXMgYW5kIEphdmEgY2xhc3Nlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSBtYXAKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgTWFwfSBnaXZpbmcgdGhlIGNvcnJlc3BvbmRlbmNlIGJldHdlZW4gU1FMCisgICAgICogICAgICAgICAgICB0eXBlcyBhbmQgSmF2YSBjbGFzc2VzLgorICAgICAqIEByZXR1cm4gYW4gT2JqZWN0IGhvbGRpbmcgdGhlIHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldE9iamVjdChpbnQgcGFyYW1ldGVySW5kZXgsIE1hcDxTdHJpbmcsIENsYXNzPD8+PiBtYXApCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgYXMgYW4ge0Bjb2RlIE9iamVjdH0uCisgICAgICogPHA+CisgICAgICogVGhlIG9iamVjdCB0eXBlIHJldHVybmVkIGlzIHRoZSBKREJDIHR5cGUgdGhhdCB3YXMgcmVnaXN0ZXJlZCBmb3IKKyAgICAgKiB0aGUgcGFyYW1ldGVyIGJ5IGFuIGVhcmxpZXIgY2FsbCB0byB7QGxpbmsgI3JlZ2lzdGVyT3V0UGFyYW1ldGVyfS4KKyAgICAgKiBJZiBhIHBhcmFtZXRlciB3YXMgcmVnaXN0ZXJlZCBhcyBhIHtAY29kZSBqYXZhLnNxbC5UeXBlcy5PVEhFUn0KKyAgICAgKiB0aGVuIGl0IG1heSBob2xkIGFic3RyYWN0IHR5cGVzIHRoYXQgYXJlIHBhcnRpY3VsYXIgdG8gdGhlCisgICAgICogY29ubmVjdGVkIGRhdGFiYXNlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbmFtZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBKYXZhIHtAY29kZSBPYmplY3R9IHJlcHJlc2VudGF0aW9uIG9mIHRoZSB2YWx1ZSBvZiB0aGUKKyAgICAgKiAgICAgICAgIHBhcmFtZXRlci4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0T2JqZWN0KFN0cmluZyBwYXJhbWV0ZXJOYW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIGFzIGFuIHtAY29kZSBPYmplY3R9LiBUaGUKKyAgICAgKiBhY3R1YWwgcmV0dXJuIHR5cGUgaXMgZGV0ZXJtaW5lZCBieSB0aGUge0Bjb2RlIE1hcH0gcGFyYW1ldGVyIHdoaWNoCisgICAgICogZ2l2ZXMgdGhlIGNvcnJlc3BvbmRlbmNlIGJldHdlZW4gU1FMIHR5cGVzIGFuZCBKYXZhIGNsYXNzZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBuYW1lLgorICAgICAqIEBwYXJhbSBtYXAKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgTWFwfSBvZiBTUUwgdHlwZXMgdG8gdGhlaXIgSmF2YSBjb3VudGVycGFydHMKKyAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBPYmplY3R9IGhvbGRpbmcgdGhlIHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldE9iamVjdChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgTWFwPFN0cmluZywgQ2xhc3M8Pz4+IG1hcCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBTUUwge0Bjb2RlIFJFRig8c3RydWN0dXJlZCB0eXBlPil9CisgICAgICogcGFyYW1ldGVyIGFzIGEge0Bjb2RlIGphdmEuc3FsLlJlZn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIGphdmEuc3FsLlJlZn0gd2l0aCB0aGUgcGFyYW1ldGVyIHZhbHVlLiB7QGNvZGUgbnVsbH0KKyAgICAgKiAgICAgICAgIGlzIHJldHVybmVkIGlmIHRoZSB2YWx1ZSBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIFJlZiBnZXRSZWYoaW50IHBhcmFtZXRlckluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgU1FMIHtAY29kZSBSRUYoPHN0cnVjdHVyZWQgdHlwZT4pfQorICAgICAqIHBhcmFtZXRlciBhcyBhIHtAY29kZSBqYXZhLnNxbC5SZWZ9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXNpcmVkIHBhcmFtZXRlcidzIG5hbWUuCisgICAgICogQHJldHVybiB0aGUgcGFyYW1ldGVyJ3MgdmFsdWUgaW4gdGhlIGZvcm0gb2YgYSB7QGNvZGUKKyAgICAgKiAgICAgICAgIGphdmEuc3FsLlJlZn0uIEEge0Bjb2RlIG51bGx9IHJlZmVyZW5jZSBpcyByZXR1cm5lZCBpZiB0aGUKKyAgICAgKiAgICAgICAgIHBhcmFtZXRlcidzIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKiBAc2VlIFJlZgorICAgICAqLworICAgIHB1YmxpYyBSZWYgZ2V0UmVmKFN0cmluZyBwYXJhbWV0ZXJOYW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgSkRCQyB7QGNvZGUgU01BTExJTlR9IHBhcmFtZXRlciBhcyBhCisgICAgICoge0Bjb2RlIHNob3J0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlcidzIHZhbHVlIGFzIGEge0Bjb2RlIHNob3J0fS4gMCBpcyByZXR1cm5lZAorICAgICAqICAgICAgICAgaWYgdGhlIHBhcmFtZXRlcidzIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2hvcnQgZ2V0U2hvcnQoaW50IHBhcmFtZXRlckluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgSkRCQyB7QGNvZGUgU01BTExJTlR9IHBhcmFtZXRlciBhcyBhCisgICAgICoge0Bjb2RlIHNob3J0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgZGVzaXJlZCBwYXJhbWV0ZXIncyBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlcidzIHZhbHVlIGFzIGEge0Bjb2RlIHNob3J0fS4gMCBpcyByZXR1cm5lZAorICAgICAqICAgICAgICAgaWYgdGhlIHBhcmFtZXRlcidzIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2hvcnQgZ2V0U2hvcnQoU3RyaW5nIHBhcmFtZXRlck5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleGVkIHBhcmFtZXRlcidzIHZhbHVlIGFzIGEge0Bjb2RlIFN0cmluZ30uIFRoZQorICAgICAqIHBhcmFtZXRlciB2YWx1ZSBtdXN0IGJlIG9uZSBvZiB0aGUgSkRCQyB0eXBlcyB7QGNvZGUgQ0hBUn0sCisgICAgICoge0Bjb2RlIFZBUkNIQVJ9IG9yIHtAY29kZSBMT05HVkFSQ0hBUn0uCisgICAgICogPHA+CisgICAgICogVGhlIHtAY29kZSBTdHJpbmd9IGNvcnJlc3BvbmRpbmcgdG8gYSB7QGNvZGUgQ0hBUn0gb2YgZml4ZWQgbGVuZ3RoCisgICAgICogd2lsbCBiZSBvZiBpZGVudGljYWwgbGVuZ3RoIHRvIHRoZSB2YWx1ZSBpbiB0aGUgZGF0YWJhc2UgaW5jbHVzaXZlCisgICAgICogb2YgcGFkZGluZyBjaGFyYWN0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHJldHVybiB0aGUgcGFyYW1ldGVyJ3MgdmFsdWUgYXMgYSB7QGNvZGUgU3RyaW5nfS4ge0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpcyByZXR1cm5lZCBpZiB0aGUgdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nKGludCBwYXJhbWV0ZXJJbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWVkIHBhcmFtZXRlcidzIHZhbHVlIGFzIGEgc3RyaW5nLiBUaGUgcGFyYW1ldGVyIHZhbHVlIG11c3QKKyAgICAgKiBiZSBvbmUgb2YgdGhlIEpEQkMgdHlwZXMge0Bjb2RlIENIQVJ9LCB7QGNvZGUgVkFSQ0hBUn0gb3Ige0Bjb2RlCisgICAgICogTE9OR1ZBUkNIQVJ9LgorICAgICAqIDxwPgorICAgICAqIFRoZSBzdHJpbmcgY29ycmVzcG9uZGluZyB0byBhIHtAY29kZSBDSEFSfSBvZiBmaXhlZCBsZW5ndGggd2lsbCBiZSBvZgorICAgICAqIGlkZW50aWNhbCBsZW5ndGggdG8gdGhlIHZhbHVlIGluIHRoZSBkYXRhYmFzZSBpbmNsdXNpdmUgb2YgcGFkZGluZworICAgICAqIGNoYXJhY3RlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGRlc2lyZWQgcGFyYW1ldGVyJ3MgbmFtZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBwYXJhbWV0ZXIncyB2YWx1ZSBhcyBhIHtAY29kZSBTdHJpbmd9LiB7QGNvZGUgbnVsbH0KKyAgICAgKiAgICAgICAgIGlzIHJldHVybmVkIGlmIHRoZSB2YWx1ZSBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBwcm9ibGVtIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTdHJpbmcoU3RyaW5nIHBhcmFtZXRlck5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBKREJDIHtAY29kZSBUSU1FfSBwYXJhbWV0ZXIgYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5UaW1lfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlcidzIHZhbHVlIGFzIGEge0Bjb2RlIGphdmEuc3FsLlRpbWV9LgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlzIHJldHVybmVkIGlmIHRoZSB2YWx1ZSBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSBUaW1lCisgICAgICovCisgICAgcHVibGljIFRpbWUgZ2V0VGltZShpbnQgcGFyYW1ldGVySW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBKREJDIHtAY29kZSBUSU1FfSBwYXJhbWV0ZXIgYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5UaW1lfSwgdXNpbmcgdGhlIHN1cHBsaWVkIHtAY29kZSBDYWxlbmRhcn0gdG8gY29uc3RydWN0IHRoZQorICAgICAqIHRpbWUuIFRoZSBKREJDIGRyaXZlciB1c2VzIHRoZSBjYWxlbmRhciB0byBoYW5kbGUgc3BlY2lmaWMgdGltZXpvbmVzCisgICAgICogYW5kIGxvY2FsZXMgaW4gb3JkZXIgdG8gZGV0ZXJtaW5lIHtAY29kZSBUaW1lfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSBjYWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYWxlbmRhciB0byB1c2UgaW4gY29uc3RydWN0aW5nIHtAY29kZSBUaW1lfS4KKyAgICAgKiBAcmV0dXJuIHRoZSBwYXJhbWV0ZXIncyB2YWx1ZSBhcyBhIHtAY29kZSBqYXZhLnNxbC5UaW1lfS4KKyAgICAgKiAgICAgICAgIHtAY29kZSBudWxsfSBpcyByZXR1cm5lZCBpZiB0aGUgdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgVGltZQorICAgICAqIEBzZWUgamF2YS51dGlsLkNhbGVuZGFyCisgICAgICovCisgICAgcHVibGljIFRpbWUgZ2V0VGltZShpbnQgcGFyYW1ldGVySW5kZXgsIENhbGVuZGFyIGNhbCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIEpEQkMge0Bjb2RlIFRJTUV9IHBhcmFtZXRlciBhcyBhIHtAY29kZQorICAgICAqIGphdmEuc3FsLlRpbWV9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBkZXNpcmVkIHBhcmFtZXRlci4KKyAgICAgKiBAcmV0dXJuIGEgbmV3IHtAY29kZSBqYXZhLnNxbC5UaW1lfSB3aXRoIHRoZSBwYXJhbWV0ZXIncyB2YWx1ZS4gQSB7QGNvZGUKKyAgICAgKiAgICAgICAgIG51bGx9IHJlZmVyZW5jZSBpcyByZXR1cm5lZCBmb3IgYW4gU1FMIHZhbHVlIG9mIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgVGltZQorICAgICAqLworICAgIHB1YmxpYyBUaW1lIGdldFRpbWUoU3RyaW5nIHBhcmFtZXRlck5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBKREJDIHtAY29kZSBUSU1FfSBwYXJhbWV0ZXIgYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5UaW1lfSwgdXNpbmcgdGhlIHN1cHBsaWVkIHtAY29kZSBDYWxlbmRhcn0gdG8gY29uc3RydWN0CisgICAgICogdGhlIHRpbWUuIFRoZSBKREJDIGRyaXZlciB1c2VzIHRoZSBjYWxlbmRhciB0byBoYW5kbGUgc3BlY2lmaWMKKyAgICAgKiB0aW1lem9uZXMgYW5kIGxvY2FsZXMgd2hlbiBjcmVhdGluZyB7QGNvZGUgVGltZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGRlc2lyZWQgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbSBjYWwKKyAgICAgKiAgICAgICAgICAgIHVzZWQgZm9yIGNyZWF0aW5nIHRoZSByZXR1cm5lZCB7QGNvZGUgVGltZX0KKyAgICAgKiBAcmV0dXJuIGEgbmV3IHtAY29kZSBqYXZhLnNxbC5UaW1lfSB3aXRoIHRoZSBwYXJhbWV0ZXIncyB2YWx1ZS4gQSB7QGNvZGUKKyAgICAgKiAgICAgICAgIG51bGx9IHJlZmVyZW5jZSBpcyByZXR1cm5lZCBmb3IgYW4gU1FMIHZhbHVlIG9mIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgVGltZQorICAgICAqIEBzZWUgamF2YS51dGlsLkNhbGVuZGFyCisgICAgICovCisgICAgcHVibGljIFRpbWUgZ2V0VGltZShTdHJpbmcgcGFyYW1ldGVyTmFtZSwgQ2FsZW5kYXIgY2FsKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXhlZCBwYXJhbWV0ZXIncyB7QGNvZGUgVElNRVNUQU1QfSB2YWx1ZSBhcyBhIHtAY29kZQorICAgICAqIGphdmEuc3FsLlRpbWVzdGFtcH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMQorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlcidzIHZhbHVlIGFzIGEge0Bjb2RlIGphdmEuc3FsLlRpbWVzdGFtcH0uIEEKKyAgICAgKiAgICAgICAgIHtAY29kZSBudWxsfSByZWZlcmVuY2UgaXMgcmV0dXJuZWQgZm9yIGFuIFNRTCB2YWx1ZSBvZiB7QGNvZGUKKyAgICAgKiAgICAgICAgIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSBUaW1lc3RhbXAKKyAgICAgKi8KKyAgICBwdWJsaWMgVGltZXN0YW1wIGdldFRpbWVzdGFtcChpbnQgcGFyYW1ldGVySW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleGVkIHBhcmFtZXRlcidzIHtAY29kZSBUSU1FU1RBTVB9IHZhbHVlIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuVGltZXN0YW1wfS4gVGhlIEpEQkMgZHJpdmVyIHVzZXMgdGhlIHN1cHBsaWVkIHtAY29kZSBDYWxlbmRhcn0KKyAgICAgKiB0byBoYW5kbGUgc3BlY2lmaWMgdGltZXpvbmVzIGFuZCBsb2NhbGVzIHdoZW4gY3JlYXRpbmcgdGhlIHJlc3VsdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxCisgICAgICogQHBhcmFtIGNhbAorICAgICAqICAgICAgICAgICAgdXNlZCBmb3IgY3JlYXRpbmcgdGhlIHJldHVybmVkIHtAY29kZSBUaW1lc3RhbXB9CisgICAgICogQHJldHVybiB0aGUgcGFyYW1ldGVyJ3MgdmFsdWUgYXMgYSB7QGNvZGUgamF2YS5zcWwuVGltZXN0YW1wfS4gQQorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IHJlZmVyZW5jZSBpcyByZXR1cm5lZCBmb3IgYW4gU1FMIHZhbHVlIG9mIHtAY29kZQorICAgICAqICAgICAgICAgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlIFRpbWVzdGFtcAorICAgICAqLworICAgIHB1YmxpYyBUaW1lc3RhbXAgZ2V0VGltZXN0YW1wKGludCBwYXJhbWV0ZXJJbmRleCwgQ2FsZW5kYXIgY2FsKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWVkIHBhcmFtZXRlcidzIHtAY29kZSBUSU1FU1RBTVB9IHZhbHVlIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuVGltZXN0YW1wfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZGVzaXJlZCBwYXJhbWV0ZXIuCisgICAgICogQHJldHVybiB0aGUgcGFyYW1ldGVyJ3MgdmFsdWUgYXMgYSB7QGNvZGUgamF2YS5zcWwuVGltZXN0YW1wfS4gQQorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IHJlZmVyZW5jZSBpcyByZXR1cm5lZCBmb3IgYW4gU1FMIHZhbHVlIG9mIHtAY29kZQorICAgICAqICAgICAgICAgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlIFRpbWVzdGFtcAorICAgICAqLworICAgIHB1YmxpYyBUaW1lc3RhbXAgZ2V0VGltZXN0YW1wKFN0cmluZyBwYXJhbWV0ZXJOYW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXhlZCBwYXJhbWV0ZXIncyB7QGNvZGUgVElNRVNUQU1QfSB2YWx1ZSBhcyBhIHtAY29kZQorICAgICAqIGphdmEuc3FsLlRpbWVzdGFtcH0uIFRoZSBKREJDIGRyaXZlciB1c2VzIHRoZSBzdXBwbGllZCB7QGNvZGUgQ2FsZW5kYXJ9CisgICAgICogdG8gaGFuZGxlIHNwZWNpZmljIHRpbWV6b25lcyBhbmQgbG9jYWxlcyB3aGVuIGNyZWF0aW5nIHRoZSByZXN1bHQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGRlc2lyZWQgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbSBjYWwKKyAgICAgKiAgICAgICAgICAgIHVzZWQgZm9yIGNyZWF0aW5nIHRoZSByZXR1cm5lZCB7QGNvZGUgVGltZXN0YW1wfQorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlcidzIHZhbHVlIGFzIGEge0Bjb2RlIGphdmEuc3FsLlRpbWVzdGFtcH0uIEEKKyAgICAgKiAgICAgICAgIHtAY29kZSBudWxsfSByZWZlcmVuY2UgaXMgcmV0dXJuZWQgZm9yIGFuIFNRTCB2YWx1ZSBvZiB7QGNvZGUKKyAgICAgKiAgICAgICAgIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSBUaW1lc3RhbXAKKyAgICAgKi8KKyAgICBwdWJsaWMgVGltZXN0YW1wIGdldFRpbWVzdGFtcChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgQ2FsZW5kYXIgY2FsKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIEpEQkMge0Bjb2RlIERBVEFMSU5LfSBwYXJhbWV0ZXIgYXMgYQorICAgICAqIHtAY29kZSBqYXZhLm5ldC5VUkx9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHJldHVybiBhIHtAY29kZSBVUkx9IGdpdmluZyB0aGUgcGFyYW1ldGVyJ3MgdmFsdWUuIHtAY29kZSBudWxsfQorICAgICAqICAgICAgICAgaXMgcmV0dXJuZWQgaWYgdGhlIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlIGphdmEubmV0LlVSTAorICAgICAqLworICAgIHB1YmxpYyBVUkwgZ2V0VVJMKGludCBwYXJhbWV0ZXJJbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWVkIHBhcmFtZXRlcidzIEpEQkMge0Bjb2RlIERBVEFMSU5LfSB2YWx1ZSBpbiBhIG5ldyBKYXZhCisgICAgICoge0Bjb2RlIGphdmEubmV0LlVSTH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGRlc2lyZWQgcGFyYW1ldGVyLgorICAgICAqIEByZXR1cm4gYSBuZXcge0Bjb2RlIGphdmEubmV0LlVSTH0gZW5jYXBzdWxhdGluZyB0aGUgcGFyYW1ldGVyIHZhbHVlLiBBCisgICAgICogICAgICAgICB7QGNvZGUgbnVsbH0gcmVmZXJlbmNlIGlzIHJldHVybmVkIGZvciBhbiBTUUwgdmFsdWUgb2Yge0Bjb2RlCisgICAgICogICAgICAgICBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgamF2YS5uZXQuVVJMCisgICAgICovCisgICAgcHVibGljIFVSTCBnZXRVUkwoU3RyaW5nIHBhcmFtZXRlck5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZWZpbmVzIHRoZSB0eXBlIG9mIGEgc3BlY2lmaWVkIHtAY29kZSBPVVR9IHBhcmFtZXRlci4gQWxsIHtAY29kZSBPVVR9CisgICAgICogcGFyYW1ldGVycyBtdXN0IGhhdmUgdGhlaXIgdHlwZSBkZWZpbmVkIGJlZm9yZSBhIHN0b3JlZCBwcm9jZWR1cmUgaXMKKyAgICAgKiBleGVjdXRlZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgdHlwZSBzdXBwbGllZCBpbiB0aGUge0Bjb2RlIHNxbFR5cGV9IHBhcmFtZXRlciBmaXhlcyB0aGUKKyAgICAgKiB0eXBlIHRoYXQgd2lsbCBiZSByZXR1cm5lZCBieSB0aGUgZ2V0dGVyIG1ldGhvZHMgb2YKKyAgICAgKiB7QGNvZGUgQ2FsbGFibGVTdGF0ZW1lbnR9LgorICAgICAqIElmIGEgZGF0YWJhc2Ugc3BlY2lmaWMgdHlwZSBpcyBleHBlY3RlZCBmb3IgYSBwYXJhbWV0ZXIsIHRoZSBUeXBlIHtAY29kZQorICAgICAqIGphdmEuc3FsLlR5cGVzLk9USEVSfSBzaG91bGQgYmUgdXNlZC4gTm90ZSB0aGF0IHRoZXJlIGlzIGFub3RoZXIgdmFyaWFudAorICAgICAqIG9mIHRoaXMgbWV0aG9kIGZvciBVc2VyIERlZmluZWQgVHlwZXMgb3IgYSB7QGNvZGUgUkVGfSB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEKKyAgICAgKiBAcGFyYW0gc3FsVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIEpEQkMgdHlwZSBhcyBkZWZpbmVkIGJ5IHtAY29kZSBqYXZhLnNxbC5UeXBlc30uIFRoZSBKREJDCisgICAgICogICAgICAgICAgICB0eXBlcyB7QGNvZGUgTlVNRVJJQ30gYW5kIHtAY29kZSBERUNJTUFMfSBzaG91bGQgYmUgZGVmaW5lZAorICAgICAqICAgICAgICAgICAgdXNpbmcge0BsaW5rICNyZWdpc3Rlck91dFBhcmFtZXRlcihpbnQsIGludCwgaW50KX0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlIFR5cGVzCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVnaXN0ZXJPdXRQYXJhbWV0ZXIoaW50IHBhcmFtZXRlckluZGV4LCBpbnQgc3FsVHlwZSkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZWZpbmVzIHRoZSBUeXBlIG9mIGEgc3BlY2lmaWVkIHtAY29kZSBPVVR9IHBhcmFtZXRlci4gQWxsIHtAY29kZSBPVVR9CisgICAgICogcGFyYW1ldGVycyBtdXN0IGhhdmUgdGhlaXIgdHlwZSBkZWZpbmVkIGJlZm9yZSBhIHN0b3JlZCBwcm9jZWR1cmUgaXMKKyAgICAgKiBleGVjdXRlZC4gVGhpcyB2ZXJzaW9uIG9mIHRoZSB7QGNvZGUgcmVnaXN0ZXJPdXRQYXJhbWV0ZXJ9IG1ldGhvZCwgd2hpY2gKKyAgICAgKiBoYXMgYSBzY2FsZSBwYXJhbWV0ZXIsIHNob3VsZCBiZSB1c2VkIGZvciB0aGUgSkRCQyB0eXBlcyB7QGNvZGUgTlVNRVJJQ30KKyAgICAgKiBhbmQge0Bjb2RlIERFQ0lNQUx9LCB3aGVyZSB0aGVyZSBpcyBhIG5lZWQgdG8gc3BlY2lmeSB0aGUgbnVtYmVyIG9mCisgICAgICogZGlnaXRzIGV4cGVjdGVkIGFmdGVyIHRoZSBkZWNpbWFsIHBvaW50LgorICAgICAqIDxwPgorICAgICAqIFRoZSB0eXBlIHN1cHBsaWVkIGluIHRoZSB7QGNvZGUgc3FsVHlwZX0gcGFyYW1ldGVyIGZpeGVzIHRoZQorICAgICAqIHR5cGUgdGhhdCB3aWxsIGJlIHJldHVybmVkIGJ5IHRoZSBnZXR0ZXIgbWV0aG9kcyBvZgorICAgICAqIHtAY29kZSBDYWxsYWJsZVN0YXRlbWVudH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMQorICAgICAqIEBwYXJhbSBzcWxUeXBlCisgICAgICogICAgICAgICAgICB0aGUgSkRCQyB0eXBlIGFzIGRlZmluZWQgYnkge0Bjb2RlIGphdmEuc3FsLlR5cGVzfS4KKyAgICAgKiBAcGFyYW0gc2NhbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgZGlnaXRzIGFmdGVyIHRoZSBkZWNpbWFsIHBvaW50LiBNdXN0IGJlIGdyZWF0ZXIKKyAgICAgKiAgICAgICAgICAgIHRoYW4gb3IgZXF1YWwgdG8gMC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgVHlwZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZWdpc3Rlck91dFBhcmFtZXRlcihpbnQgcGFyYW1ldGVySW5kZXgsIGludCBzcWxUeXBlLCBpbnQgc2NhbGUpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUgVHlwZSBvZiBhIHNwZWNpZmllZCB7QGNvZGUgT1VUfSBwYXJhbWV0ZXIuIFRoaXMgdmFyaWFudAorICAgICAqIG9mIHRoZSBtZXRob2QgaXMgZGVzaWduZWQgZm9yIHVzZSB3aXRoIHBhcmFtZXRlcnMgdGhhdCBhcmUKKyAgICAgKiA8aT5Vc2VyIERlZmluZWQgVHlwZXM8L2k+IChVRFQpIG9yIGEge0Bjb2RlIFJFRn0gdHlwZSwgYWx0aG91Z2ggaXQKKyAgICAgKiBjYW4gYmUgdXNlZCBmb3IgYW55IHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSBzcWxUeXBlCisgICAgICogICAgICAgICAgICBhIEpEQkMgdHlwZSBleHByZXNzZWQgYXMgYSBjb25zdGFudCBmcm9tIHtAbGluayBUeXBlc30uCisgICAgICogQHBhcmFtIHR5cGVOYW1lCisgICAgICogICAgICAgICAgICBhbiBTUUwgdHlwZSBuYW1lLiBGb3IgYSB7QGNvZGUgUkVGfSB0eXBlLCB0aGlzIG5hbWUgc2hvdWxkIGJlCisgICAgICogICAgICAgICAgICB0aGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIHJlZmVyZW5jZWQgdHlwZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgUmVmCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVnaXN0ZXJPdXRQYXJhbWV0ZXIoaW50IHBhcmFtSW5kZXgsIGludCBzcWxUeXBlLAorICAgICAgICAgICAgU3RyaW5nIHR5cGVOYW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUgVHlwZSBvZiBhIHNwZWNpZmllZCB7QGNvZGUgT1VUfSBwYXJhbWV0ZXIuIEFsbCBPVVQgcGFyYW1ldGVycworICAgICAqIG11c3QgaGF2ZSB0aGVpciBUeXBlIGRlZmluZWQgYmVmb3JlIGEgc3RvcmVkIHByb2NlZHVyZSBpcyBleGVjdXRlZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgdHlwZSBzdXBwbGllZCBpbiB0aGUge0Bjb2RlIHNxbFR5cGV9IHBhcmFtZXRlciBmaXhlcyB0aGUKKyAgICAgKiB0eXBlIHRoYXQgd2lsbCBiZSByZXR1cm5lZCBieSB0aGUgZ2V0dGVyIG1ldGhvZHMgb2YKKyAgICAgKiB7QGNvZGUgQ2FsbGFibGVTdGF0ZW1lbnR9LgorICAgICAqIElmIGEgZGF0YWJhc2Utc3BlY2lmaWMgdHlwZSBpcyBleHBlY3RlZCBmb3IgYSBwYXJhbWV0ZXIsIHRoZSBUeXBlIHtAY29kZQorICAgICAqIGphdmEuc3FsLlR5cGVzLk9USEVSfSBzaG91bGQgYmUgdXNlZC4gTm90ZSB0aGF0IHRoZXJlIGlzIGFub3RoZXIgdmFyaWFudAorICAgICAqIG9mIHRoaXMgbWV0aG9kIGZvciBVc2VyIERlZmluZWQgVHlwZXMgb3IgYSB7QGNvZGUgUkVGfSB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbmFtZS4KKyAgICAgKiBAcGFyYW0gc3FsVHlwZQorICAgICAqICAgICAgICAgICAgYSBKREJDIHR5cGUgZXhwcmVzc2VkIGFzIGEgY29uc3RhbnQgZnJvbSB7QGxpbmsgVHlwZXN9LiBUeXBlcworICAgICAqICAgICAgICAgICAge0Bjb2RlIE5VTUVSSUN9IGFuZCB7QGNvZGUgREVDSU1BTH0gc2hvdWxkIGJlIGRlZmluZWQgdXNpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YXJpYW50IG9mIHRoaXMgbWV0aG9kIHRoYXQgdGFrZXMgYSB7QGNvZGUgc2NhbGV9CisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZWdpc3Rlck91dFBhcmFtZXRlcihTdHJpbmcgcGFyYW1ldGVyTmFtZSwgaW50IHNxbFR5cGUpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUgVHlwZSBvZiBhIHNwZWNpZmllZCB7QGNvZGUgT1VUfSBwYXJhbWV0ZXIuIEFsbCB7QGNvZGUgT1VUfQorICAgICAqIHBhcmFtZXRlcnMgbXVzdCBoYXZlIHRoZWlyIFR5cGUgZGVmaW5lZCBiZWZvcmUgYSBzdG9yZWQgcHJvY2VkdXJlIGlzCisgICAgICogZXhlY3V0ZWQuIFRoaXMgdmVyc2lvbiBvZiB0aGUge0Bjb2RlIHJlZ2lzdGVyT3V0UGFyYW1ldGVyfSBtZXRob2QsIHdoaWNoCisgICAgICogaGFzIGEgc2NhbGUgcGFyYW1ldGVyLCBzaG91bGQgYmUgdXNlZCBmb3IgdGhlIEpEQkMgdHlwZXMge0Bjb2RlIE5VTUVSSUN9CisgICAgICogYW5kIHtAY29kZSBERUNJTUFMfSwgd2hlcmUgdGhlcmUgaXMgYSBuZWVkIHRvIHNwZWNpZnkgdGhlIG51bWJlciBvZgorICAgICAqIGRpZ2l0cyBleHBlY3RlZCBhZnRlciB0aGUgZGVjaW1hbCBwb2ludC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgdHlwZSBzdXBwbGllZCBpbiB0aGUge0Bjb2RlIHNxbFR5cGV9IHBhcmFtZXRlciBmaXhlcyB0aGUKKyAgICAgKiB0eXBlIHRoYXQgd2lsbCBiZSByZXR1cm5lZCBieSB0aGUgZ2V0dGVyIG1ldGhvZHMgb2YKKyAgICAgKiB7QGNvZGUgQ2FsbGFibGVTdGF0ZW1lbnR9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbmFtZS4KKyAgICAgKiBAcGFyYW0gc3FsVHlwZQorICAgICAqICAgICAgICAgICAgYSBKREJDIHR5cGUgZXhwcmVzc2VkIGFzIGEgY29uc3RhbnQgZnJvbSB7QGxpbmsgVHlwZXN9LgorICAgICAqIEBwYXJhbSBzY2FsZQorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBkaWdpdHMgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQuIE11c3QgYmUgZ3JlYXRlcgorICAgICAqICAgICAgICAgICAgdGhhbiBvciBlcXVhbCB0byAwLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVnaXN0ZXJPdXRQYXJhbWV0ZXIoU3RyaW5nIHBhcmFtZXRlck5hbWUsIGludCBzcWxUeXBlLAorICAgICAgICAgICAgaW50IHNjYWxlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUgVHlwZSBvZiBhIHNwZWNpZmllZCB7QGNvZGUgT1VUfSBwYXJhbWV0ZXIuIFRoaXMgdmFyaWFudCBvZgorICAgICAqIHRoZSBtZXRob2QgaXMgZGVzaWduZWQgZm9yIHVzZSB3aXRoIHBhcmFtZXRlcnMgdGhhdCBhcmUgPGk+VXNlciBEZWZpbmVkCisgICAgICogVHlwZXM8L2k+IChVRFQpIG9yIGEge0Bjb2RlIFJFRn0gdHlwZSwgYWx0aG91Z2ggaXQgY2FuIGJlIHVzZWQgZm9yIGFueQorICAgICAqIHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBuYW1lCisgICAgICogQHBhcmFtIHNxbFR5cGUKKyAgICAgKiAgICAgICAgICAgIGEgSkRCQyB0eXBlIGV4cHJlc3NlZCBhcyBhIGNvbnN0YW50IGZyb20ge0BsaW5rIFR5cGVzfQorICAgICAqIEBwYXJhbSB0eXBlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIGFuIFNRTCBzdHJ1Y3R1cmVkIHR5cGUuIEZvciBhCisgICAgICogICAgICAgICAgICB7QGNvZGUgUkVGfSB0eXBlLCB0aGlzIG5hbWUgc2hvdWxkIGJlIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZQorICAgICAqICAgICAgICAgICAgb2YgdGhlIHJlZmVyZW5jZWQgdHlwZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlZ2lzdGVyT3V0UGFyYW1ldGVyKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBpbnQgc3FsVHlwZSwKKyAgICAgICAgICAgIFN0cmluZyB0eXBlTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB0byB0aGUgY29udGVudCBvZiBhIHN1cHBsaWVkCisgICAgICoge0Bjb2RlIElucHV0U3RyZWFtfSwgd2hpY2ggaGFzIGEgc3BlY2lmaWVkIG51bWJlciBvZiBieXRlcy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIGlzIGEgZ29vZCBtZXRob2QgZm9yIHNldHRpbmcgYW4gU1FMIHtAY29kZSBMT05HVkFSQ0hBUn0gcGFyYW1ldGVyCisgICAgICogd2hlcmUgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YSBpcyBsYXJnZS4gRGF0YSBpcyByZWFkIGZyb20gdGhlIHtAY29kZQorICAgICAqIElucHV0U3RyZWFtfSB1bnRpbCBlbmQtb2YtZmlsZSBpcyByZWFjaGVkIG9yIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mCisgICAgICogYnl0ZXMgaXMgY29waWVkLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbmFtZQorICAgICAqIEBwYXJhbSB0aGVJbnB1dFN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIEFTQ0lJIGlucHV0IHN0cmVhbSBjYXJyeWluZyB0aGUgZGF0YSB0byB1cGRhdGUgdGhlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIgd2l0aC4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIGluIHRoZSB7QGNvZGUgSW5wdXRTdHJlYW19IHRvIGNvcHkgdG8gdGhlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRBc2NpaVN0cmVhbShTdHJpbmcgcGFyYW1ldGVyTmFtZSwKKyAgICAgICAgICAgIElucHV0U3RyZWFtIHRoZUlucHV0U3RyZWFtLCBpbnQgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIGEgc3VwcGxpZWQge0Bjb2RlCisgICAgICogamF2YS5tYXRoLkJpZ0RlY2ltYWx9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBwYXJhbWV0ZXIuCisgICAgICogQHBhcmFtIHRoZUJpZ0RlY2ltYWwKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgamF2YS5tYXRoLkJpZ0ludGVnZXJ9IHZhbHVlIHRvIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJpZ0RlY2ltYWwoU3RyaW5nIHBhcmFtZXRlck5hbWUsIEJpZ0RlY2ltYWwgdGhlQmlnRGVjaW1hbCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gdGhlIGNvbnRlbnQgb2YgYSBzdXBwbGllZAorICAgICAqIGJpbmFyeSB7QGNvZGUgSW5wdXRTdHJlYW19LCB3aGljaCBoYXMgYSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJ5dGVzLgorICAgICAqIDxwPgorICAgICAqIFVzZSB0aGlzIG1ldGhvZCB3aGVuIGEgbGFyZ2UgYW1vdW50IG9mIGRhdGEgbmVlZHMgdG8gYmUgc2V0IGludG8gYQorICAgICAqIHtAY29kZSBMT05HVkFSQklOQVJZfSBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAcGFyYW0gdGhlSW5wdXRTdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBiaW5hcnkge0Bjb2RlIElucHV0U3RyZWFtfSBjYXJyeWluZyB0aGUgZGF0YSB0byB1cGRhdGUgdGhlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIuCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyBpbiB0aGUge0Bjb2RlIElucHV0U3RyZWFtfSB0byBjb3B5IHRvIHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QmluYXJ5U3RyZWFtKFN0cmluZyBwYXJhbWV0ZXJOYW1lLAorICAgICAgICAgICAgSW5wdXRTdHJlYW0gdGhlSW5wdXRTdHJlYW0sIGludCBsZW5ndGgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gYSBzdXBwbGllZCB7QGNvZGUgYm9vbGVhbn0KKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG5hbWUuCisgICAgICogQHBhcmFtIHRoZUJvb2xlYW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgd2l0aCB3aGljaCB0byB1cGRhdGUgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJvb2xlYW4oU3RyaW5nIHBhcmFtZXRlck5hbWUsIGJvb2xlYW4gdGhlQm9vbGVhbikKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gYSBzdXBwbGllZCB7QGNvZGUgYnl0ZX0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBuYW1lLgorICAgICAqIEBwYXJhbSB0aGVCeXRlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIHdpdGggd2hpY2ggdG8gdXBkYXRlIHRoZSBwYXJhbWV0ZXIuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCeXRlKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBieXRlIHRoZUJ5dGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gYSBzdXBwbGllZCBhcnJheSBvZiBieXRlcy4gVGhlCisgICAgICogYXJyYXkgaXMgbWFwcGVkIHRvIHtAY29kZSBWQVJCSU5BUll9IG9yIGVsc2Uge0Bjb2RlIExPTkdWQVJCSU5BUll9IGluIHRoZQorICAgICAqIGNvbm5lY3RlZCBkYXRhYmFzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG5hbWUuCisgICAgICogQHBhcmFtIHRoZUJ5dGVzCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIHdpdGggd2hpY2ggdG8gdXBkYXRlIHRoZSBwYXJhbWV0ZXIuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCeXRlcyhTdHJpbmcgcGFyYW1ldGVyTmFtZSwgYnl0ZVtdIHRoZUJ5dGVzKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB0byB0aGUgY2hhcmFjdGVyIGNvbnRlbnQgb2YgYQorICAgICAqIHtAY29kZSBSZWFkZXJ9IG9iamVjdCwgd2l0aCB0aGUgc3BlY2lmaWVkIGxlbmd0aCBvZiBjaGFyYWN0ZXIgZGF0YS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG5hbWUuCisgICAgICogQHBhcmFtIHJlYWRlcgorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSB3aXRoIHdoaWNoIHRvIHVwZGF0ZSB0aGUgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIGEgY291bnQgb2YgdGhlIGNoYXJhY3RlcnMgY29udGFpbmVkIGluIHtAY29kZSByZWFkZXJ9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q2hhcmFjdGVyU3RyZWFtKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBSZWFkZXIgcmVhZGVyLAorICAgICAgICAgICAgaW50IGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB0byBhIHN1cHBsaWVkIHtAY29kZQorICAgICAqIGphdmEuc3FsLkRhdGV9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbmFtZS4KKyAgICAgKiBAcGFyYW0gdGhlRGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSB3aXRoIHdoaWNoIHRvIHVwZGF0ZSB0aGUgcGFyYW1ldGVyLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGF0ZShTdHJpbmcgcGFyYW1ldGVyTmFtZSwgRGF0ZSB0aGVEYXRlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIGEgc3VwcGxpZWQge0Bjb2RlCisgICAgICogamF2YS5zcWwuRGF0ZX0gdmFsdWUsIHVzaW5nIGEgc3VwcGxpZWQgY2FsZW5kYXIgdG8gbWFwIHRoZSBkYXRlLiBUaGUKKyAgICAgKiBjYWxlbmRhciBhbGxvd3MgdGhlIGFwcGxpY2F0aW9uIHRvIGNvbnRyb2wgdGhlIHRpbWV6b25lIHVzZWQgdG8gY29tcHV0ZQorICAgICAqIHRoZSBTUUwge0Bjb2RlIERBVEV9IGluIHRoZSBkYXRhYmFzZS4gSW4gY2FzZSB0aGF0IG5vIGNhbGVuZGFyIGlzCisgICAgICogc3VwcGxpZWQsIHRoZSBkcml2ZXIgdXNlcyB0aGUgZGVmYXVsdCB0aW1lem9uZSBvZiB0aGUgSmF2YSB2aXJ0dWFsCisgICAgICogbWFjaGluZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG5hbWUuCisgICAgICogQHBhcmFtIHRoZURhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgd2l0aCB3aGljaCB0byB1cGRhdGUgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAcGFyYW0gY2FsCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBDYWxlbmRhcn0gdG8gdXNlIHRvIGNvbnN0cnVjdCB0aGUgU1FMIHtAY29kZSBEQVRFfQorICAgICAqICAgICAgICAgICAgdmFsdWUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlIGphdmEudXRpbC5DYWxlbmRhcgorICAgICAqIEBzZWUgRGF0ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERhdGUoU3RyaW5nIHBhcmFtZXRlck5hbWUsIERhdGUgdGhlRGF0ZSwgQ2FsZW5kYXIgY2FsKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB0byBhIHN1cHBsaWVkIHtAY29kZSBkb3VibGV9CisgICAgICogdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBuYW1lLgorICAgICAqIEBwYXJhbSB0aGVEb3VibGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgd2l0aCB3aGljaCB0byB1cGRhdGUgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERvdWJsZShTdHJpbmcgcGFyYW1ldGVyTmFtZSwgZG91YmxlIHRoZURvdWJsZSkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gdG8gYSBzdXBwbGllZCB7QGNvZGUgZmxvYXR9CisgICAgICogdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBuYW1lLgorICAgICAqIEBwYXJhbSB0aGVGbG9hdAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSB3aXRoIHdoaWNoIHRvIHVwZGF0ZSB0aGUgcGFyYW1ldGVyLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RmxvYXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIGZsb2F0IHRoZUZsb2F0KQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB0byBhIHN1cHBsaWVkIHtAY29kZSBpbnR9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbmFtZS4KKyAgICAgKiBAcGFyYW0gdGhlSW50CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIHdpdGggd2hpY2ggdG8gdXBkYXRlIHRoZSBwYXJhbWV0ZXIuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRJbnQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIGludCB0aGVJbnQpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gYSBzdXBwbGllZCB7QGNvZGUgbG9uZ30gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBuYW1lLgorICAgICAqIEBwYXJhbSB0aGVMb25nCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIHdpdGggd2hpY2ggdG8gdXBkYXRlIHRoZSBwYXJhbWV0ZXIuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMb25nKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBsb25nIHRoZUxvbmcpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gU1FMIHtAY29kZSBOVUxMfS4gRG9uJ3QgdXNlCisgICAgICogdGhpcyB2ZXJzaW9uIG9mIHtAY29kZSBzZXROdWxsfSBmb3IgPGk+VXNlciBEZWZpbmVkIFR5cGVzPC9pPiAoVURUKSBvcgorICAgICAqIGZvciB7QGNvZGUgUkVGfSB0eXBlIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBuYW1lLgorICAgICAqIEBwYXJhbSBzcWxUeXBlCisgICAgICogICAgICAgICAgICBhIEpEQkMgdHlwZSBleHByZXNzZWQgYXMgYSBjb25zdGFudCBmcm9tIHtAbGluayBUeXBlc30uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROdWxsKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBpbnQgc3FsVHlwZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB0byBiZSBTUUwge0Bjb2RlIE5VTEx9IHdoZXJlIHRoZQorICAgICAqIHBhcmFtZXRlciB0eXBlIGlzIGVpdGhlciB7QGNvZGUgUkVGfSBvciB1c2VyIGRlZmluZWQgKGUuZy4ge0Bjb2RlIFNUUlVDVH0KKyAgICAgKiAsIHtAY29kZSBKQVZBX09CSkVDVH0gZXRjKS4KKyAgICAgKiA8cD4KKyAgICAgKiBGb3IgcmVhc29ucyBvZiBwb3J0YWJpbGl0eSwgdGhlIGNhbGxlciBpcyBleHBlY3RlZCB0byBzdXBwbHkgYm90aCB0aGUgU1FMCisgICAgICogdHlwZSBjb2RlIGFuZCB0eXBlIG5hbWUgKHdoaWNoIGlzIGp1c3QgdGhlIHBhcmFtZXRlciBuYW1lIGlmIHRoZSB0eXBlIGlzCisgICAgICogdXNlciBkZWZpbmVkLCByZWZlcnJlZCB0byBhcyBhIHtAY29kZSBVRFR9LCBvciB0aGUgbmFtZSBvZiB0aGUgcmVmZXJlbmNlZAorICAgICAqIHR5cGUgaW4gY2FzZSBvZiBhIHtAY29kZSBSRUZ9IHR5cGUpLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbmFtZS4KKyAgICAgKiBAcGFyYW0gc3FsVHlwZQorICAgICAqICAgICAgICAgICAgYSBKREJDIHR5cGUgZXhwcmVzc2VkIGFzIGEgY29uc3RhbnQgZnJvbSB7QGxpbmsgVHlwZXN9LgorICAgICAqIEBwYXJhbSB0eXBlTmFtZQorICAgICAqICAgICAgICAgICAgaWYgdGhlIHRhcmdldCBwYXJhbWV0ZXIgaXMgYSB1c2VyIGRlZmluZWQgdHlwZSB0aGVuIHRoaXMKKyAgICAgKiAgICAgICAgICAgIHNob3VsZCBjb250YWluIHRoZSBmdWxsIHR5cGUgbmFtZS4gVGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBVRFR9IG9yIHtAY29kZSBSRUZ9IHR5cGUgaXMgaWdub3JlZCBpZiB0aGUgcGFyYW1ldGVyCisgICAgICogICAgICAgICAgICBpcyBub3QgYSB7QGNvZGUgVURUfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgVHlwZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROdWxsKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBpbnQgc3FsVHlwZSwgU3RyaW5nIHR5cGVOYW1lKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB1c2luZyBhIHN1cHBsaWVkIG9iamVjdC4gUHJpb3IgdG8KKyAgICAgKiBpc3N1aW5nIHRoaXMgcmVxdWVzdCB0byB0aGUgY29ubmVjdGVkIGRhdGFiYXNlIHtAY29kZSB0aGVPYmplY3R9IGlzCisgICAgICogdHJhbnNmb3JtZWQgdG8gdGhlIGNvcnJlc3BvbmRpbmcgU1FMIHR5cGUgYWNjb3JkaW5nIHRvIHRoZSBzdGFuZGFyZCBKYXZhCisgICAgICogdG8gU1FMIG1hcHBpbmcgcnVsZXMuCisgICAgICogPHA+CisgICAgICogSWYgdGhlIG9iamVjdCdzIGNsYXNzIGltcGxlbWVudHMgdGhlIGludGVyZmFjZSB7QGNvZGUgU1FMRGF0YX0sIHRoZSBKREJDCisgICAgICogZHJpdmVyIGNhbGxzIHtAY29kZSBTUUxEYXRhLndyaXRlU1FMfSB0byB3cml0ZSBpdCB0byB0aGUgU1FMIGRhdGEgc3RyZWFtLgorICAgICAqIElmIHtAY29kZSB0aGVPYmplY3R9IGltcGxlbWVudHMgYW55IG9mIHRoZSBmb2xsb3dpbmcgaW50ZXJmYWNlcyB0aGVuIHRoZQorICAgICAqIGRyaXZlciBpcyBpbiBjaGFyZ2Ugb2YgbWFwcGluZyB0aGUgdmFsdWUgdG8gdGhlIGFwcHJvcHJpYXRlIFNRTCB0eXBlLgorICAgICAqIDx1bD48bGk+e0BsaW5rIFJlZn08L2xpPgorICAgICAqIDxsaT57QGxpbmsgU3RydWN0fTwvbGk+CisgICAgICogPGxpPntAbGluayBBcnJheX08L2xpPgorICAgICAqIDxsaT57QGxpbmsgQ2xvYn08L2xpPgorICAgICAqIDxsaT57QGxpbmsgQmxvYn08L2xpPiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbmFtZQorICAgICAqIEBwYXJhbSB0aGVPYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgd2l0aCB3aGljaCB0byB1cGRhdGUgdGhlIHBhcmFtZXRlcgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSBTUUxEYXRhCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0T2JqZWN0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdGhlT2JqZWN0KQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB1c2luZyBhIHN1cHBsaWVkIG9iamVjdC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcGFyYW1ldGVyIHtAY29kZSB0aGVPYmplY3R9IGlzIGNvbnZlcnRlZCB0byB0aGUgZ2l2ZW4ge0Bjb2RlCisgICAgICogdGFyZ2V0U3FsVHlwZX0gYmVmb3JlIGl0IGlzIHNlbnQgdG8gdGhlIGRhdGFiYXNlLiBJZiB0aGUgb2JqZWN0IGhhcyBhCisgICAgICogY3VzdG9tIG1hcHBpbmcgKGl0cyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBpbnRlcmZhY2Uge0Bjb2RlIFNRTERhdGF9KSwgdGhlCisgICAgICogSkRCQyBkcml2ZXIgY2FsbHMgdGhlIG1ldGhvZCB7QGNvZGUgU1FMRGF0YS53cml0ZVNRTH0gdG8gd3JpdGUgaXQgdG8gdGhlCisgICAgICogU1FMIGRhdGEgc3RyZWFtLiBJZiB7QGNvZGUgdGhlT2JqZWN0fSBpcyBhbiBpbnN0YW5jZSBvZiBvbmUgb2YgdGhlCisgICAgICogZm9sbG93aW5nIHR5cGVzCisgICAgICogPHVsPgorICAgICAqIDxsaT57QGxpbmsgUmVmfTwvbGk+CisgICAgICogPGxpPntAbGluayBTdHJ1Y3R9PC9saT4KKyAgICAgKiA8bGk+e0BsaW5rIEFycmF5fTwvbGk+CisgICAgICogPGxpPntAbGluayBDbG9ifTwvbGk+CisgICAgICogPGxpPntAbGluayBCbG9ifTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiB0aGVuIHRoZSBkcml2ZXIgaXMgaW4gY2hhcmdlIG9mIG1hcHBpbmcgdGhlIHZhbHVlIHRvIHRoZSBhcHByb3ByaWF0ZQorICAgICAqIFNRTCB0eXBlIGFuZCBkZWxpdmVyIGl0IHRvIHRoZSBkYXRhYmFzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG5hbWUuCisgICAgICogQHBhcmFtIHRoZU9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSB3aXRoIHdoaWNoIHRvIHVwZGF0ZSB0aGUgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbSB0YXJnZXRTcWxUeXBlCisgICAgICogICAgICAgICAgICBhIEpEQkMgdHlwZSBleHByZXNzZWQgYXMgYSBjb25zdGFudCBmcm9tIHtAbGluayBUeXBlc30uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlIFNRTERhdGEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRPYmplY3QoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB0aGVPYmplY3QsCisgICAgICAgICAgICBpbnQgdGFyZ2V0U3FsVHlwZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB1c2luZyBhIHN1cHBsaWVkIG9iamVjdC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgb2JqZWN0IGlzIGNvbnZlcnRlZCB0byB0aGUgZ2l2ZW4ge0Bjb2RlIHRhcmdldFNxbFR5cGV9IGJlZm9yZSBpdCBpcworICAgICAqIHNlbnQgdG8gdGhlIGRhdGFiYXNlLiBJZiB0aGUgb2JqZWN0IGhhcyBhIGN1c3RvbSBtYXBwaW5nIChpdHMgY2xhc3MKKyAgICAgKiBpbXBsZW1lbnRzIHRoZSBpbnRlcmZhY2Uge0Bjb2RlIFNRTERhdGF9KSwgdGhlIEpEQkMgZHJpdmVyIGNhbGxzIHRoZQorICAgICAqIG1ldGhvZCB7QGNvZGUgU1FMRGF0YS53cml0ZVNRTH0gdG8gd3JpdGUgaXQgdG8gdGhlIFNRTCBkYXRhIHN0cmVhbS4gSWYKKyAgICAgKiB7QGNvZGUgdGhlT2JqZWN0fSBpbXBsZW1lbnRzIGFueSBvZiB0aGUgZm9sbG93aW5nIGludGVyZmFjZXMKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAbGluayBSZWZ9PC9saT4KKyAgICAgKiA8bGk+e0BsaW5rIFN0cnVjdH08L2xpPgorICAgICAqIDxsaT57QGxpbmsgQXJyYXl9PC9saT4KKyAgICAgKiA8bGk+e0BsaW5rIENsb2J9PC9saT4KKyAgICAgKiA8bGk+e0BsaW5rIEJsb2J9PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqIHRoZW4gdGhlIGRyaXZlciBpcyBjaGFyZ2Ugb2YgbWFwcGluZyB0aGUgdmFsdWUgdG8gdGhlIGFwcHJvcHJpYXRlCisgICAgICogU1FMIHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBuYW1lLgorICAgICAqIEBwYXJhbSB0aGVPYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgd2l0aCB3aGljaCB0byB1cGRhdGUgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAcGFyYW0gdGFyZ2V0U3FsVHlwZQorICAgICAqICAgICAgICAgICAgYSBKREJDIHR5cGUgZXhwcmVzc2VkIGFzIGEgY29uc3RhbnQgZnJvbSB7QGxpbmsgVHlwZXN9LgorICAgICAqIEBwYXJhbSBzY2FsZQorICAgICAqICAgICAgICAgICAgd2hlcmUgYXBwbGljYWJsZSwgdGhlIG51bWJlciBvZiBkaWdpdHMgYWZ0ZXIgdGhlIGRlY2ltYWwuCisgICAgICogICAgICAgICAgICBwb2ludC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgU1FMRGF0YQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE9iamVjdChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHRoZU9iamVjdCwKKyAgICAgICAgICAgIGludCB0YXJnZXRTcWxUeXBlLCBpbnQgc2NhbGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gYSBzdXBwbGllZCB7QGNvZGUgc2hvcnR9CisgICAgICogdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAcGFyYW0gdGhlU2hvcnQKKyAgICAgKiAgICAgICAgICAgIGEgc2hvcnQgdmFsdWUgdG8gdXBkYXRlIHRoZSBwYXJhbWV0ZXIuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTaG9ydChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgc2hvcnQgdGhlU2hvcnQpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIGEgc3VwcGxpZWQge0Bjb2RlIFN0cmluZ30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAcGFyYW0gdGhlU3RyaW5nCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBTdHJpbmd9IHZhbHVlIHRvIHVwZGF0ZSB0aGUgcGFyYW1ldGVyLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3RyaW5nKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBTdHJpbmcgdGhlU3RyaW5nKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIgbmFtZWQge0Bjb2RlIHBhcmFtZXRlck5hbWV9IHRvIHRoZSB2YWx1ZQorICAgICAqIG9mIHRoZSBzdXBwbGllZCB7QGNvZGUgamF2YS5zcWwuVGltZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBuYW1lLgorICAgICAqIEBwYXJhbSB0aGVUaW1lCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIHdpdGggd2hpY2ggdG8gdXBkYXRlIHRoZSBwYXJhbWV0ZXIuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlIFRpbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBUaW1lIHRoZVRpbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyIG5hbWVkIHtAY29kZSBwYXJhbWV0ZXJOYW1lfSB0byB0aGUgdmFsdWUKKyAgICAgKiBvZiB0aGUgc3VwcGxpZWQge0Bjb2RlIGphdmEuc3FsLlRpbWV9IHVzaW5nIHRoZSBzdXBwbGllZCBjYWxlbmRhci4KKyAgICAgKgorICAgICAqIDxwPlRoZSBkcml2ZXIgdXNlcyB0aGUgc3VwcGxpZWQge0Bjb2RlIENhbGVuZGFyfSB0byBjcmVhdGUgdGhlIFNRTAorICAgICAqIHtAY29kZSBUSU1FfSB2YWx1ZSwgd2hpY2ggYWxsb3dzIGl0IHRvIHVzZSBhIGN1c3RvbSB0aW1lem9uZSAtCisgICAgICogb3RoZXJ3aXNlIHRoZSBkcml2ZXIgdXNlcyB0aGUgVk0gZGVmYXVsdHMuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbmFtZS4KKyAgICAgKiBAcGFyYW0gdGhlVGltZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSB3aXRoIHdoaWNoIHRvIHVwZGF0ZSB0aGUgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbSBjYWwKKyAgICAgKiAgICAgICAgICAgIHVzZWQgZm9yIGNyZWF0aW5nIHRoZSBuZXcgU1FMIHtAY29kZSBUSU1FfSB2YWx1ZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgVGltZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRpbWUoU3RyaW5nIHBhcmFtZXRlck5hbWUsIFRpbWUgdGhlVGltZSwgQ2FsZW5kYXIgY2FsKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB0byBhIHN1cHBsaWVkIHtAY29kZQorICAgICAqIGphdmEuc3FsLlRpbWVzdGFtcH0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBuYW1lLgorICAgICAqIEBwYXJhbSB0aGVUaW1lc3RhbXAKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgd2l0aCB3aGljaCB0byB1cGRhdGUgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgVGltZXN0YW1wCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VGltZXN0YW1wKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBUaW1lc3RhbXAgdGhlVGltZXN0YW1wKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB0byBhIHN1cHBsaWVkIHtAY29kZQorICAgICAqIGphdmEuc3FsLlRpbWVzdGFtcH0gdmFsdWUsIHVzaW5nIHRoZSBzdXBwbGllZCBjYWxlbmRhci4KKyAgICAgKgorICAgICAqIDxwPlRoZSBkcml2ZXIgdXNlcyB0aGUgc3VwcGxpZWQgY2FsZW5kYXIgdG8gY3JlYXRlIHRoZSBTUUwge0Bjb2RlIFRJTUVTVEFNUH0KKyAgICAgKiB2YWx1ZSwgd2hpY2ggYWxsb3dzIGl0IHRvIHVzZSBhIGN1c3RvbSB0aW1lem9uZSAtIG90aGVyd2lzZSB0aGUgZHJpdmVyCisgICAgICogdXNlcyB0aGUgVk0gZGVmYXVsdHMuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbmFtZS4KKyAgICAgKiBAcGFyYW0gdGhlVGltZXN0YW1wCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIHdpdGggd2hpY2ggdG8gdXBkYXRlIHRoZSBwYXJhbWV0ZXIuCisgICAgICogQHBhcmFtIGNhbAorICAgICAqICAgICAgICAgICAgdXNlZCBmb3IgY3JlYXRpbmcgdGhlIG5ldyBTUUwge0Bjb2RlIFRJTUV9IHZhbHVlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSBUaW1lc3RhbXAKKyAgICAgKiBAc2VlIGphdmEudXRpbC5DYWxlbmRhcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRpbWVzdGFtcChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgVGltZXN0YW1wIHRoZVRpbWVzdGFtcCwKKyAgICAgICAgICAgIENhbGVuZGFyIGNhbCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB0byB0aGUgc3VwcGxpZWQge0Bjb2RlCisgICAgICogamF2YS5uZXQuVVJMfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG5hbWUuCisgICAgICogQHBhcmFtIHRoZVVSTAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSB3aXRoIHdoaWNoIHRvIHVwZGF0ZSB0aGUgcGFyYW1ldGVyLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSBqYXZhLm5ldC5VUkwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRVUkwoU3RyaW5nIHBhcmFtZXRlck5hbWUsIFVSTCB0aGVVUkwpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHdoZXRoZXIgdGhlIHZhbHVlIG9mIHRoZSBsYXN0IHtAY29kZSBPVVR9IHBhcmFtZXRlciByZWFkIHdhcyBTUUwKKyAgICAgKiB7QGNvZGUgTlVMTH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGxhc3QgcGFyYW1ldGVyIHdhcyBTUUwge0Bjb2RlIE5VTEx9LCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB3YXNOdWxsKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHtAY29kZSBST1dJRH0gcGFyYW1ldGVyIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuUm93SWR9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUm93SWQgZ2V0Um93SWQoaW50IHBhcmFtZXRlckluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBTUUwgUk9XSUQgcGFyYW1ldGVyIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuUm93SWR9LgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lIHRoZSBwYXJhbWV0ZXIgbmFtZQorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgcHVibGljIFJvd0lkIGdldFJvd0lkKFN0cmluZyBwYXJhbWV0ZXJOYW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmFtZWQgcGFyYW1ldGVyIHRvIHRoZSBnaXZlbiB7QGNvZGUgcm93SWR9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Um93SWQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIFJvd0lkIHJvd0lkKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmFtZWQgcGFyYW1ldGVyIHRvIHRoZSBnaXZlbiB7QGNvZGUgc3RyaW5nfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3VycworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5TdHJpbmcoU3RyaW5nIHBhcmFtZXRlck5hbWUsIFN0cmluZyBzdHJpbmcpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lZCBwYXJhbWV0ZXIgdG8gdGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgZ2l2ZW4ge0Bjb2RlIHJlYWRlcn0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROQ2hhcmFjdGVyU3RyZWFtKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBSZWFkZXIgcmVhZGVyLCBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5hbWVkIHBhcmFtZXRlciB0byB0aGUgZ2l2ZW4ge0Bjb2RlIG5jbG9ifS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3VycworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5DbG9iKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBOQ2xvYiBuY2xvYikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5hbWVkIHBhcmFtZXRlciB0byB0aGUgbmV4dCB7QGNvZGUgbGVuZ3RofSBjaGFyYWN0ZXJzIGZyb20gdGhlIGdpdmVuIHtAY29kZSByZWFkZXJ9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q2xvYihTdHJpbmcgcGFyYW1ldGVyTmFtZSwgUmVhZGVyIHJlYWRlciwgbG9uZyBsZW5ndGgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lZCBwYXJhbWV0ZXIgdG8gdGhlIG5leHQge0Bjb2RlIGxlbmd0aH0gYnl0ZXMgZnJvbSB0aGUgZ2l2ZW4ge0Bjb2RlIGlucHV0U3RyZWFtfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3VycworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJsb2IoU3RyaW5nIHBhcmFtZXRlck5hbWUsIElucHV0U3RyZWFtIGlucHV0U3RyZWFtLCBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5hbWVkIHBhcmFtZXRlciB0byB0aGUgbmV4dCB7QGNvZGUgbGVuZ3RofSBjaGFyYWN0ZXJzIGZyb20gdGhlIGdpdmVuIHtAY29kZSByZWFkZXJ9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TkNsb2IoU3RyaW5nIHBhcmFtZXRlck5hbWUsIFJlYWRlciByZWFkZXIsIGxvbmcgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBTUUwgTkNMT0IgcGFyYW1ldGVyIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuTkNsb2J9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTkNsb2IgZ2V0TkNsb2IoaW50IHBhcmFtZXRlckluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBTUUwgTkNMT0IgcGFyYW1ldGVyIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuTkNsb2J9LgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lIHRoZSBwYXJhbWV0ZXIgbmFtZQorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgcHVibGljIE5DbG9iIGdldE5DbG9iKFN0cmluZyBwYXJhbWV0ZXJOYW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmFtZWQgcGFyYW1ldGVyIHRvIHRoZSBnaXZlbiB7QGNvZGUgc3FsWG1sfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3VycworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNRTFhNTChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgU1FMWE1MIHNxbFhtbCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgU1FMIFhNTCBwYXJhbWV0ZXIgYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5TUUxYTUx9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMWE1MIGdldFNRTFhNTChpbnQgcGFyYW1ldGVySW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIFNRTCBYTUwgcGFyYW1ldGVyIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuU1FMWE1MfS4KKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZSB0aGUgcGFyYW1ldGVyIG5hbWUKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3VycworICAgICAqLworICAgIHB1YmxpYyBTUUxYTUwgZ2V0U1FMWE1MKFN0cmluZyBwYXJhbWV0ZXJOYW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBTUUwgTkNIQVIsIE5WQVJDSEFSLCBvciBMT05HTlZBUkNIQVIgcGFyYW1ldGVyIGFzIGEKKyAgICAgKiB7QGNvZGUgamF2YS5sYW5nLlN0cmluZ30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TlN0cmluZyhpbnQgcGFyYW1ldGVySW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIFNRTCBOQ0hBUiwgTlZBUkNIQVIsIG9yIExPTkdOVkFSQ0hBUiBwYXJhbWV0ZXIgYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLmxhbmcuU3RyaW5nfS4KKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZSB0aGUgcGFyYW1ldGVyIG5hbWUKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3VycworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TlN0cmluZyhTdHJpbmcgcGFyYW1ldGVyTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgU1FMIE5DSEFSLCBOVkFSQ0hBUiwgb3IgTE9OR05WQVJDSEFSIHBhcmFtZXRlcgorICAgICAqIGFzIGEge0BsaW5rIFJlYWRlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBSZWFkZXIgZ2V0TkNoYXJhY3RlclN0cmVhbShpbnQgcGFyYW1ldGVySW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIFNRTCBOQ0hBUiwgTlZBUkNIQVIsIG9yIExPTkdOVkFSQ0hBUiBwYXJhbWV0ZXIgYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLmlvLlJlYWRlcn0uCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUgdGhlIHBhcmFtZXRlciBuYW1lCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVhZGVyIGdldE5DaGFyYWN0ZXJTdHJlYW0oU3RyaW5nIHBhcmFtZXRlck5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBhcyBhIHtAY29kZSBqYXZhLmlvLlJlYWRlcn0uCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVhZGVyIGdldENoYXJhY3RlclN0cmVhbShpbnQgcGFyYW1ldGVySW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBhcyBhIHtAY29kZSBqYXZhLmlvLlJlYWRlcn0uCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUgdGhlIHBhcmFtZXRlciBuYW1lCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVhZGVyIGdldENoYXJhY3RlclN0cmVhbShTdHJpbmcgcGFyYW1ldGVyTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5hbWVkIHBhcmFtZXRlciB0byB0aGUgZ2l2ZW4ge0Bjb2RlIGJsb2J9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QmxvYihTdHJpbmcgcGFyYW1ldGVyTmFtZSwgQmxvYiBibG9iKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmFtZWQgcGFyYW1ldGVyIHRvIHRoZSBnaXZlbiB7QGNvZGUgY2xvYn0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDbG9iKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBDbG9iIGNsb2IpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lZCBwYXJhbWV0ZXIgdG8gdGhlIG5leHQge0Bjb2RlIGxlbmd0aH0gYnl0ZXMgZnJvbSB0aGUgZ2l2ZW4ge0Bjb2RlIGlucHV0U3RyZWFtfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3VycworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEFzY2lpU3RyZWFtKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBJbnB1dFN0cmVhbSB4LCBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5hbWVkIHBhcmFtZXRlciB0byB0aGUgYnl0ZXMgZnJvbSB0aGUgZ2l2ZW4ge0Bjb2RlIHJlYWRlcn0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRBc2NpaVN0cmVhbShTdHJpbmcgcGFyYW1ldGVyTmFtZSwgSW5wdXRTdHJlYW0geCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5hbWVkIHBhcmFtZXRlciB0byB0aGUgbmV4dCB7QGNvZGUgbGVuZ3RofSBieXRlcyBmcm9tIHRoZSBnaXZlbiB7QGNvZGUgaW5wdXRTdHJlYW19LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QmluYXJ5U3RyZWFtKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBJbnB1dFN0cmVhbSB4LCBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5hbWVkIHBhcmFtZXRlciB0byB0aGUgYnl0ZXMgZnJvbSB0aGUgZ2l2ZW4ge0Bjb2RlIHJlYWRlcn0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCaW5hcnlTdHJlYW0oU3RyaW5nIHBhcmFtZXRlck5hbWUsIElucHV0U3RyZWFtIHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lZCBwYXJhbWV0ZXIgdG8gdGhlIG5leHQge0Bjb2RlIGxlbmd0aH0gY2hhcmFjdGVycyBmcm9tIHRoZSBnaXZlbiB7QGNvZGUgcmVhZGVyfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3VycworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENoYXJhY3RlclN0cmVhbShTdHJpbmcgcGFyYW1ldGVyTmFtZSwgUmVhZGVyIHJlYWRlciwgbG9uZyBsZW5ndGgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lZCBwYXJhbWV0ZXIgdG8gdGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgZ2l2ZW4ge0Bjb2RlIHJlYWRlcn0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDaGFyYWN0ZXJTdHJlYW0oU3RyaW5nIHBhcmFtZXRlck5hbWUsIFJlYWRlciByZWFkZXIpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lZCBwYXJhbWV0ZXIgdG8gdGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgZ2l2ZW4ge0Bjb2RlIHJlYWRlcn0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROQ2hhcmFjdGVyU3RyZWFtKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBSZWFkZXIgdmFsdWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lZCBwYXJhbWV0ZXIgdG8gdGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgZ2l2ZW4ge0Bjb2RlIHJlYWRlcn0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDbG9iKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBSZWFkZXIgcmVhZGVyKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmFtZWQgcGFyYW1ldGVyIHRvIHRoZSBieXRlcyBmcm9tIHRoZSBnaXZlbiB7QGNvZGUgaW5wdXRTdHJlYW19LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QmxvYihTdHJpbmcgcGFyYW1ldGVyTmFtZSwgSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0pIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lZCBwYXJhbWV0ZXIgdG8gdGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgZ2l2ZW4ge0Bjb2RlIHJlYWRlcn0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROQ2xvYihTdHJpbmcgcGFyYW1ldGVyTmFtZSwgUmVhZGVyIHJlYWRlcikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9DbGllbnRJbmZvU3RhdHVzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvQ2xpZW50SW5mb1N0YXR1cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI1NGNjMmQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvQ2xpZW50SW5mb1N0YXR1cy5qYXZhCkBAIC0wLDAgKzEsMjggQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCisvKioKKyAqIEFuIGVudW1lcmF0aW9uIHRvIGRlc2NyaWJlIHRoZSByZWFzb24gd2h5IGEgcHJvcGVydHkgY2Fubm90IGJlIHNldCBieSBjYWxsaW5nCisgKiBDb25uZWN0aW9uLnNldENsaWVudEluZm8uCisgKgorICogQHNpbmNlIDEuNgorICovCitwdWJsaWMgZW51bSBDbGllbnRJbmZvU3RhdHVzIHsKKyAgICBSRUFTT05fVU5LTk9XTiwgUkVBU09OX1VOS05PV05fUFJPUEVSVFksIFJFQVNPTl9WQUxVRV9JTlZBTElELCBSRUFTT05fVkFMVUVfVFJVTkNBVEVELAorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9DbG9iLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvQ2xvYi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNmZmI0YjcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvQ2xvYi5qYXZhCkBAIC0wLDAgKzEsMTk0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CitpbXBvcnQgamF2YS5pby5Xcml0ZXI7CisKKy8qKgorICogQSBKYXZhIGludGVyZmFjZSBtYXBwaW5nIGZvciB0aGUgU1FMIENMT0IgdHlwZS4KKyAqIDxwPgorICogQW4gU1FMIHtAY29kZSBDTE9CfSB0eXBlIHN0b3JlcyBhIGxhcmdlIGFycmF5IG9mIGNoYXJhY3RlcnMgYXMgdGhlIHZhbHVlIGluIGEKKyAqIGNvbHVtbiBvZiBhIGRhdGFiYXNlLgorICogPHA+CisgKiBUaGUge0Bjb2RlIGphdmEuc3FsLkNsb2J9IGludGVyZmFjZSBwcm92aWRlcyBtZXRob2RzIGZvciBzZXR0aW5nIGFuZAorICogcmV0cmlldmluZyBkYXRhIGluIHRoZSB7QGNvZGUgQ2xvYn0sIGZvciBxdWVyeWluZyB7QGNvZGUgQ2xvYn0gZGF0YSBsZW5ndGgsCisgKiBmb3Igc2VhcmNoaW5nIGZvciBkYXRhIHdpdGhpbiB0aGUge0Bjb2RlIENsb2J9LgorICovCitwdWJsaWMgaW50ZXJmYWNlIENsb2IgeworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgdGhpcyB7QGNvZGUgQ2xvYn0gb2JqZWN0IGFzIGFuIEFTQ0lJIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gQVNDSUkge0Bjb2RlIElucHV0U3RyZWFtfSBnaXZpbmcgYWNjZXNzIHRvIHRoZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIENsb2J9IGRhdGEuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSB7QGNvZGUgQ2xvYn0uCisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldEFzY2lpU3RyZWFtKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRhdGEgb2YgdGhpcyB7QGNvZGUgQ2xvYn0gb2JqZWN0IGluIGEge0Bjb2RlIGphdmEuaW8uUmVhZGVyfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBjaGFyYWN0ZXIgc3RyZWFtIFJlYWRlciBvYmplY3QgZ2l2aW5nIGFjY2VzcyB0byB0aGUge0Bjb2RlCisgICAgICogICAgICAgICBDbG9ifSBkYXRhLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUge0Bjb2RlIENsb2J9LgorICAgICAqLworICAgIHB1YmxpYyBSZWFkZXIgZ2V0Q2hhcmFjdGVyU3RyZWFtKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgYSBjb3B5IG9mIGEgc3BlY2lmaWVkIHN1YnN0cmluZyBpbiB0aGlzIHtAY29kZSBDbG9ifS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgc3RhcnQgb2YgdGhlIHN1YnN0cmluZyBpbiB0aGUge0Bjb2RlIENsb2J9LgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgdG8gcmV0cmlldmUuCisgICAgICogQHJldHVybiBBIHN0cmluZyBjb250YWluaW5nIHRoZSByZXF1ZXN0ZWQgZGF0YS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIHtAY29kZSBDbG9ifS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFN1YlN0cmluZyhsb25nIHBvcywgaW50IGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gdGhpcyB7QGNvZGUgQ2xvYn0gb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybiBhIGxvbmcgdmFsdWUgd2l0aCB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlciBpbiB0aGlzIHtAY29kZSBDbG9ifS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIHtAY29kZSBDbG9ifS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBsZW5ndGgoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIHRoZSBjaGFyYWN0ZXIgcG9zaXRpb24gYXQgd2hpY2ggYSBzcGVjaWZpZWQge0Bjb2RlIENsb2J9IG9iamVjdAorICAgICAqIGFwcGVhcnMgaW4gdGhpcyB7QGNvZGUgQ2xvYn0gb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHNlYXJjaHN0cgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCB7QGNvZGUgQ2xvYn0gdG8gc2VhcmNoIGZvci4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3NpdGlvbiB3aXRoaW4gdGhpcyB7QGNvZGUgQ2xvYn0gdG8gc3RhcnQgdGhlIHNlYXJjaAorICAgICAqIEByZXR1cm4gYSBsb25nIHZhbHVlIHdpdGggdGhlIHBvc2l0aW9uIGF0IHdoaWNoIHRoZSBzcGVjaWZpZWQge0Bjb2RlCisgICAgICogICAgICAgICBDbG9ifSBvY2N1cnMgd2l0aGluIHRoaXMge0Bjb2RlIENsb2J9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUge0Bjb2RlIENsb2J9LgorICAgICAqLworICAgIHB1YmxpYyBsb25nIHBvc2l0aW9uKENsb2Igc2VhcmNoc3RyLCBsb25nIHN0YXJ0KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIHRoZSBjaGFyYWN0ZXIgcG9zaXRpb24gYXQgd2hpY2ggYSBzcGVjaWZpZWQgc3Vic3RyaW5nIGFwcGVhcnMKKyAgICAgKiBpbiB0aGlzIHtAY29kZSBDbG9ifSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2VhcmNoc3RyCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHNlYXJjaCBmb3IuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgcG9zaXRpb24gYXQgd2hpY2ggdG8gc3RhcnQgdGhlIHNlYXJjaCB3aXRoaW4gdGhpcyB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIENsb2J9LgorICAgICAqIEByZXR1cm4gYSBsb25nIHZhbHVlIHdpdGggdGhlIHBvc2l0aW9uIGF0IHdoaWNoIHRoZSBzcGVjaWZpZWQgc3RyaW5nCisgICAgICogICAgICAgICBvY2N1cnMgd2l0aGluIHRoaXMge0Bjb2RlIENsb2J9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUge0Bjb2RlIENsb2J9LgorICAgICAqLworICAgIHB1YmxpYyBsb25nIHBvc2l0aW9uKFN0cmluZyBzZWFyY2hzdHIsIGxvbmcgc3RhcnQpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYSBzdHJlYW0gd2hpY2ggY2FuIGJlIHVzZWQgdG8gd3JpdGUgQXNjaWkgY2hhcmFjdGVycyB0byB0aGlzCisgICAgICoge0Bjb2RlIENsb2J9IG9iamVjdCwgc3RhcnRpbmcgYXQgc3BlY2lmaWVkIHBvc2l0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHBvcworICAgICAqICAgICAgICAgICAgdGhlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHN0YXJ0IHRoZSB3cml0aW5nLgorICAgICAqIEByZXR1cm4gYW4gT3V0cHV0U3RyZWFtIHdoaWNoIGNhbiBiZSB1c2VkIHRvIHdyaXRlIEFTQ0lJIGNoYXJhY3RlcnMgdG8KKyAgICAgKiAgICAgICAgIHRoaXMge0Bjb2RlIENsb2J9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUge0Bjb2RlIENsb2J9LgorICAgICAqLworICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gc2V0QXNjaWlTdHJlYW0obG9uZyBwb3MpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYSBzdHJlYW0gd2hpY2ggY2FuIGJlIHVzZWQgdG8gd3JpdGUgYSBzdHJlYW0gb2YgdW5pY29kZQorICAgICAqIGNoYXJhY3RlcnMgdG8gdGhpcyB7QGNvZGUgQ2xvYn0gb2JqZWN0LCBhdCBhIHNwZWNpZmllZCBwb3NpdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3NpdGlvbiBhdCB3aGljaCB0byBzdGFydCB0aGUgd3JpdGluZy4KKyAgICAgKiBAcmV0dXJuIGEgV3JpdGVyIHdoaWNoIGNhbiBiZSB1c2VkIHRvIHdyaXRlIHVuaWNvZGUgY2hhcmFjdGVycyB0byB0aGlzCisgICAgICogICAgICAgICB7QGNvZGUgQ2xvYn0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSB7QGNvZGUgQ2xvYn0uCisgICAgICovCisgICAgcHVibGljIFdyaXRlciBzZXRDaGFyYWN0ZXJTdHJlYW0obG9uZyBwb3MpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBnaXZlbiBKYXZhIFN0cmluZyB0byB0aGlzIHtAY29kZSBDbG9ifSBvYmplY3QgYXQgYSBzcGVjaWZpZWQKKyAgICAgKiBwb3NpdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3NpdGlvbiBhdCB3aGljaCB0byBzdGFydCB0aGUgd3JpdGluZy4KKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHdyaXRlLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHdyaXR0ZW4uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSB7QGNvZGUgQ2xvYn0uCisgICAgICovCisgICAgcHVibGljIGludCBzZXRTdHJpbmcobG9uZyBwb3MsIFN0cmluZyBzdHIpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMge0Bjb2RlIGxlbn0gY2hhcmFjdGVycyBvZiBhIHN0cmluZywgc3RhcnRpbmcgYXQgYSBzcGVjaWZpZWQKKyAgICAgKiBjaGFyYWN0ZXIgb2Zmc2V0LCB0byB0aGlzIHtAY29kZSBDbG9ifS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3NpdGlvbiBhdCB3aGljaCB0byBzdGFydCB0aGUgd3JpdGluZy4KKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgU3RyaW5nIHRvIHdyaXRlLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgd2l0aGluIHtAY29kZSBzdHJ9IHRvIHN0YXJ0IHdyaXRpbmcgZnJvbS4KKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gd3JpdGUuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgd3JpdHRlbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIHtAY29kZSBDbG9ifS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNldFN0cmluZyhsb25nIHBvcywgU3RyaW5nIHN0ciwgaW50IG9mZnNldCwgaW50IGxlbikKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBUcnVuY2F0ZXMgdGhpcyB7QGNvZGUgQ2xvYn0gYWZ0ZXIgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgY2hhcmFjdGVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggaW4gY2hhcmFjdGVycyBnaXZpbmcgdGhlIHBsYWNlIHRvCisgICAgICogICAgICAgICAgICB0cnVuY2F0ZSB0aGlzIHtAY29kZSBDbG9ifS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIHtAY29kZSBDbG9ifS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0cnVuY2F0ZShsb25nIGxlbikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEZyZWVzIGFueSByZXNvdXJjZXMgaGVsZCBieSB0aGlzIGNsb2IuIEFmdGVyIHtAY29kZSBmcmVlfSBpcyBjYWxsZWQsIGNhbGxpbmcKKyAgICAgKiBtZXRob2Qgb3RoZXIgdGhhbiB7QGNvZGUgZnJlZX0gd2lsbCB0aHJvdyB7QGNvZGUgU1FMRXhjZXB0aW9ufSAoY2FsbGluZyB7QGNvZGUgZnJlZX0KKyAgICAgKiByZXBlYXRlZGx5IHdpbGwgZG8gbm90aGluZykuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZyZWUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAbGluayBSZWFkZXJ9IHRoYXQgcmVhZHMge0Bjb2RlIGxlbmd0aH0gY2hhcmFjdGVycyBmcm9tIHRoaXMgY2xvYiwgc3RhcnRpbmcKKyAgICAgKiBhdCAxLWJhc2VkIG9mZnNldCB7Y29kZSBwb3N9LgorICAgICAqLworICAgIHB1YmxpYyBSZWFkZXIgZ2V0Q2hhcmFjdGVyU3RyZWFtKGxvbmcgcG9zLCBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9Db25uZWN0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvQ29ubmVjdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM4YjRiNDkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvQ29ubmVjdGlvbi5qYXZhCkBAIC0wLDAgKzEsODQxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKKy8qKgorICogQSBjb25uZWN0aW9uIHJlcHJlc2VudHMgYSBsaW5rIGZyb20gYSBKYXZhIGFwcGxpY2F0aW9uIHRvIGEgZGF0YWJhc2UuIEFsbCBTUUwKKyAqIHN0YXRlbWVudHMgYW5kIHJlc3VsdHMgYXJlIHJldHVybmVkIHdpdGhpbiB0aGUgY29udGV4dCBvZiBhIGNvbm5lY3Rpb24uCisgKiBEYXRhYmFzZSBzdGF0ZW1lbnRzIHRoYXQgYXJlIGV4ZWN1dGVkIHdpdGhpbiB0aGlzIGNvbnRleHQgZm9ybSBhCisgKiBkYXRhYmFzZSBzZXNzaW9uIHdoaWNoIGZvcm1zIG9uZSBvciBtb3JlIGNsb3NlZCB0cmFuc2FjdGlvbnMuIEVzcGVjaWFsbHkgaW4KKyAqIGRpc3RyaWJ1dGVkIGFwcGxpY2F0aW9ucywgbXVsdGlwbGUgY29uY3VycmVudCBjb25uZWN0aW9ucyBtYXkgZXhpc3QgYWNjZXNzaW5nCisgKiB0aGUgc2FtZSB2YWx1ZXMgb2YgdGhlIGRhdGFiYXNlLiB3aGljaCBtYXkgbGVhZCB0byB0aGUgZm9sbG93aW5nIHBoZW5vbWVuYQorICogKHJlZmVycmVkIHRvIGFzIDxpPnRyYW5zYWN0aW9uIGlzb2xhdGlvbiBsZXZlbHM8L2k+KToKKyAqIDx1bD4KKyAqIDxsaT48aT5kaXJ0eSByZWFkczwvaT46PGJyPgorICogcmVhZGluZyB2YWx1ZXMgZnJvbSB0YWJsZSByb3dzIHRoYXQgYXJlIG5vdCBjb21taXR0ZWQuPC9icj48L2xpPgorICogPGxpPjxpPm5vbi1yZXBlYXRhYmxlIHJlYWRzPC9pPjo8YnI+CisgKiByZWFkaW5nIHRhYmxlIHJvd3MgbW9yZSB0aGFuIG9uY2UgaW4gYSB0cmFuc2FjdGlvbiBidXQgZ2V0dGluZyBiYWNrIGRpZmZlcmVudAorICogZGF0YSBiZWNhdXNlIG90aGVyIHRyYW5zYWN0aW9ucyBoYXZlIGFsdGVyZWQgdGhlIHJvd3MgYmV0d2VlbiB0aGUgcmVhZHMuPC9icj48L2xpPgorICogPGxpPjxpPnBoYW50b20gcmVhZHM8L2k+Ojxicj4KKyAqIHJldHJpZXZpbmcgYWRkaXRpb25hbCAicGhhbnRvbSIgcm93cyBpbiB0aGUgY291cnNlIG9mIHJlcGVhdGVkIHRhYmxlIHJlYWRzCisgKiBiZWNhdXNlIG90aGVyIHRyYW5zYWN0aW9ucyBoYXZlIGluc2VydGVkIGFkZGl0aW9uYWwgcm93cyB0aGF0IHNhdGlzZnkgYW4KKyAqIFNRTCB7QGNvZGUgV0hFUkV9IGNsYXVzZTwvYnI+PC9saT4KKyAqIDwvdWw+CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQ29ubmVjdGlvbiBleHRlbmRzIFdyYXBwZXIsIEF1dG9DbG9zZWFibGUgeworCisgICAgLyoqCisgICAgICogQSBjb25zdGFudCBpbmRpY2F0aW5nIHRoYXQgdHJhbnNhY3Rpb25zIGFyZSBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRSQU5TQUNUSU9OX05PTkUgPSAwOworCisgICAgLyoqCisgICAgICogTm8gPGk+ZGlydHkgcmVhZHM8L2k+IGFyZSBwZXJtaXR0ZWQsIHRoZXJlZm9yZSB0cmFuc2FjdGlvbnMgbWF5IG5vdCByZWFkCisgICAgICogYSByb3cgY29udGFpbmluZyB1bmNvbW1pdHRlZCB2YWx1ZXMgLSBidXQgZG9lcyBub3QgcHJldmVudCBhbiBhcHBsaWNhdGlvbgorICAgICAqIGZyb20gPGk+bm9uLXJlcGVhdGFibGUgcmVhZHM8L2k+IGFuZCA8aT5waGFudG9tIHJlYWRzPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUUkFOU0FDVElPTl9SRUFEX0NPTU1JVFRFRCA9IDI7CisKKyAgICAvKioKKyAgICAgKiBJbiB0aGUgY2FzZSB0aGF0IHJlYWRpbmcgdW5jb21taXR0ZWQgdmFsdWVzIGlzIGFsbG93ZWQsIHRoZSBmb2xsb3dpbmcKKyAgICAgKiBpbmNpZGVudHMgbWF5IGhhcHBlbiB3aGljaCBtYXkgbGVhZCB0byBhbiBpbnZhbGlkIHJlc3VsdHM6CisgICAgICogPHVsPgorICAgICAqIDxsaT48aT5kaXJ0eSByZWFkczwvaT48L2xpPgorICAgICAqIDxsaT48aT5ub24tcmVwZWF0YWJsZSByZWFkczwvaT48L2xpPgorICAgICAqIDxsaT48aT5waGFudG9tIHJlYWRzPC9pPjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUUkFOU0FDVElPTl9SRUFEX1VOQ09NTUlUVEVEID0gMTsKKworICAgIC8qKgorICAgICAqIEEgY29uc3RhbnQgaW5kaWNhdGluZyB0aGF0IDxpPmRpcnR5IHJlYWRzPC9pPiBhbmQgPGk+bm9uLXJlcGVhdGFibGUKKyAgICAgKiByZWFkczwvaT4gYXJlIDxiPnByZXZlbnRlZDwvYj4gYnV0IDxpPnBoYW50b20gcmVhZHM8L2k+IGNhbiBvY2N1ci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUUkFOU0FDVElPTl9SRVBFQVRBQkxFX1JFQUQgPSA0OworCisgICAgLyoqCisgICAgICogVGhlIGNvbnN0YW50IHRoYXQgaW5kaWNhdGVzIHRoYXQgdGhlIGZvbGxvd2luZyBpbmNpZGVudHMgYXJlIDxiPmFsbAorICAgICAqIHByZXZlbnRlZDwvYj4gKHRoZSBvcHBvc2l0ZSBvZiB7QGxpbmsgI1RSQU5TQUNUSU9OX1JFQURfVU5DT01NSVRURUR9KToKKyAgICAgKiA8dWw+CisgICAgICogPGxpPjxpPmRpcnR5IHJlYWRzPC9pPjwvbGk+CisgICAgICogPGxpPjxpPm5vbi1yZXBlYXRhYmxlIHJlYWRzPC9pPjwvbGk+CisgICAgICogPGxpPjxpPnBoYW50b20gcmVhZHM8L2k+PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRSQU5TQUNUSU9OX1NFUklBTElaQUJMRSA9IDg7CisKKyAgICAvKioKKyAgICAgKiBEaXNjYXJkcyBhbGwgd2FybmluZ3MgdGhhdCBtYXkgaGF2ZSBhcmlzZW4gZm9yIHRoaXMgY29ubmVjdGlvbi4KKyAgICAgKiBTdWJzZXF1ZW50IGNhbGxzIHRvIHtAbGluayAjZ2V0V2FybmluZ3MoKX0gd2lsbCByZXR1cm4ge0Bjb2RlIG51bGx9CisgICAgICogdXAgdW50aWwgYSBuZXcgd2FybmluZyBjb25kaXRpb24gb2NjdXJzLgorICAgICAqCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbGVhcldhcm5pbmdzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENhdXNlcyB0aGUgaW5zdGFudCByZWxlYXNlIG9mIGFsbCBkYXRhYmFzZSBhbmQgZHJpdmVyIGNvbm5lY3Rpb24KKyAgICAgKiByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgb2JqZWN0LiBBbnkgc3Vic2VxdWVudCBpbnZvY2F0aW9ucyBvZiB0aGlzCisgICAgICogbWV0aG9kIGhhdmUgbm8gZWZmZWN0LgorICAgICAqIDxwPgorICAgICAqIEl0IGlzIHN0cm9uZ2x5IHJlY29tbWVuZGVkIHRoYXQgYWxsIGNvbm5lY3Rpb25zIGFyZSBjbG9zZWQgYmVmb3JlIHRoZXkKKyAgICAgKiBhcmUgZGVyZWZlcmVuY2VkIGJ5IHRoZSBhcHBsaWNhdGlvbiByZWFkeSBmb3IgZ2FyYmFnZSBjb2xsZWN0aW9uLgorICAgICAqIEFsdGhvdWdoIHRoZSB7QGNvZGUgZmluYWxpemV9IG1ldGhvZCBvZiB0aGUgY29ubmVjdGlvbiBjbG9zZXMgdGhlCisgICAgICogY29ubmVjdGlvbiBiZWZvcmUgZ2FyYmFnZSBjb2xsZWN0aW9uIHRha2VzIHBsYWNlLCBpdCBpcyBub3QgYWR2aXNhYmxlIHRvCisgICAgICogbGVhdmUgdGhlIHtAY29kZSBjbG9zZX0gb3BlcmF0aW9uIHRvIHRha2UgcGxhY2UgaW4gdGhpcyB3YXkuIE1haW5seQorICAgICAqIGJlY2F1c2UgdW5kZXNpcmVkIHNpZGUtZWZmZWN0cyBtYXkgYXBwZWFyLgorICAgICAqCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDb21taXRzIGFsbCBvZiB0aGUgY2hhbmdlcyBtYWRlIHNpbmNlIHRoZSBsYXN0IHtAY29kZSBjb21taXR9IG9yCisgICAgICoge0Bjb2RlIHJvbGxiYWNrfSBvZiB0aGUgYXNzb2NpYXRlZCB0cmFuc2FjdGlvbi4gQWxsIGxvY2tzIGluIHRoZSBkYXRhYmFzZQorICAgICAqIGhlbGQgYnkgdGhpcyBjb25uZWN0aW9uIGFyZSBhbHNvIHJlbGlucXVpc2hlZC4gQ2FsbGluZyB0aGlzIG9wZXJhdGlvbiBvbgorICAgICAqIGNvbm5lY3Rpb24gb2JqZWN0cyBpbiB7QGNvZGUgYXV0by1jb21taXR9IG1vZGUgbGVhZHMgdG8gYW4gZXJyb3IuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlIG9yIGlmIHRoZSB0YXJnZXQKKyAgICAgKiAgICAgICAgICAgICBjb25uZWN0aW9uIGluc3RhbmNlIGlzIGluIGF1dG8tY29tbWl0IG1vZGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY29tbWl0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFN0YXRlbWVudH0gZm9yIGlzc3VpbmcgU1FMIGNvbW1hbmRzIHRvCisgICAgICogdGhlIHJlbW90ZSBkYXRhYmFzZS4KKyAgICAgKiA8cD4KKyAgICAgKiB7QGNvZGUgUmVzdWx0U2V0c30gZ2VuZXJhdGVkIGJ5IHRoZSByZXR1cm5lZCBzdGF0ZW1lbnQgd2lsbCBkZWZhdWx0IHRvCisgICAgICogdHlwZSB7QGNvZGUgUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZfSBhbmQgY29uY3VycmVuY3kgbGV2ZWwge0Bjb2RlCisgICAgICogUmVzdWx0U2V0LkNPTkNVUl9SRUFEX09OTFl9LgorICAgICAqCisgICAgICogQHJldHVybiBhIHtAY29kZSBTdGF0ZW1lbnR9IG9iamVjdCB3aXRoIGRlZmF1bHQgc2V0dGluZ3MuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKiBAc2VlIFJlc3VsdFNldAorICAgICAqLworICAgIHB1YmxpYyBTdGF0ZW1lbnQgY3JlYXRlU3RhdGVtZW50KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFN0YXRlbWVudH0gd2hvc2UgYXNzb2NpYXRlZCB7QGNvZGUKKyAgICAgKiBSZXN1bHRTZXR9cyBoYXZlIHRoZSBjaGFyYWN0ZXJpc3RpY3Mgc3BlY2lmaWVkIGluIHRoZSB0eXBlIGFuZAorICAgICAqIGNvbmN1cnJlbmN5IGFyZ3VtZW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZXN1bHRTZXRUeXBlCisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZyB0eXBlIHNwZWNpZmllcnM6CisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNUWVBFX1NDUk9MTF9TRU5TSVRJVkV9IDwvbGk+IDxsaT4KKyAgICAgKiAgICAgICAgICAgIHtAbGluayBSZXN1bHRTZXQjVFlQRV9TQ1JPTExfSU5TRU5TSVRJVkV9IDwvbGk+IDxsaT4KKyAgICAgKiAgICAgICAgICAgIHtAbGluayBSZXN1bHRTZXQjVFlQRV9GT1JXQVJEX09OTFl9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDwvdWw+CisgICAgICogQHBhcmFtIHJlc3VsdFNldENvbmN1cnJlbmN5CisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZyBjb25jdXJyZW5jeSBtb2RlIHNwZWNpZmllcnM6CisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNDT05DVVJfVVBEQVRBQkxFfTwvbGk+IDxsaT4KKyAgICAgKiAgICAgICAgICAgIHtAbGluayBSZXN1bHRTZXQjQ09OQ1VSX1JFQURfT05MWX08L2xpPgorICAgICAqICAgICAgICAgICAgPC91bD4KKyAgICAgKiBAcmV0dXJuIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBTdGF0ZW1lbnR9IGNhcGFibGUgb2YgbWFudWZhY3R1cmluZworICAgICAqICAgICAgICAge0Bjb2RlIFJlc3VsdFNldH1zIHRoYXQgc2F0aXNmeSB0aGUgc3BlY2lmaWVkIHtAY29kZQorICAgICAqICAgICAgICAgcmVzdWx0U2V0VHlwZX0gYW5kIHtAY29kZSByZXN1bHRTZXRDb25jdXJyZW5jeX0gdmFsdWVzLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBwcm9ibGVtIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RhdGVtZW50IGNyZWF0ZVN0YXRlbWVudChpbnQgcmVzdWx0U2V0VHlwZSwgaW50IHJlc3VsdFNldENvbmN1cnJlbmN5KQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFN0YXRlbWVudH0gd2hvc2UgYXNzb2NpYXRlZAorICAgICAqIHtAY29kZSBSZXN1bHRTZXR9cyB3aWxsIGhhdmUgdGhlIGNoYXJhY3RlcmlzdGljcyBzcGVjaWZpZWQgaW4gdGhlCisgICAgICogdHlwZSwgY29uY3VycmVuY3kgYW5kIGhvbGRhYmlsaXR5IGFyZ3VtZW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZXN1bHRTZXRUeXBlCisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZyB0eXBlIHNwZWNpZmllcnM6CisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNUWVBFX1NDUk9MTF9TRU5TSVRJVkV9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I1RZUEVfU0NST0xMX0lOU0VOU0lUSVZFfTwvbGk+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNUWVBFX0ZPUldBUkRfT05MWX08L2xpPgorICAgICAqICAgICAgICAgICAgPC91bD4KKyAgICAgKiBAcGFyYW0gcmVzdWx0U2V0Q29uY3VycmVuY3kKKyAgICAgKiAgICAgICAgICAgIG9uZSBvZiB0aGUgZm9sbG93aW5nIGNvbmN1cnJlbmN5IG1vZGUgc3BlY2lmaWVyczoKKyAgICAgKiAgICAgICAgICAgIDx1bD4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I0NPTkNVUl9VUERBVEFCTEV9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I0NPTkNVUl9SRUFEX09OTFl9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDwvdWw+CisgICAgICogQHBhcmFtIHJlc3VsdFNldEhvbGRhYmlsaXR5CisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZyBob2xkYWJpbGl0eSBtb2RlIHNwZWNpZmllcnM6CisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNIT0xEX0NVUlNPUlNfT1ZFUl9DT01NSVR9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I0NMT1NFX0NVUlNPUlNfQVRfQ09NTUlUfTwvbGk+CisgICAgICogICAgICAgICAgICA8L3VsPgorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFN0YXRlbWVudH0gY2FwYWJsZSBvZgorICAgICAqICAgICAgICAgbWFudWZhY3R1cmluZyB7QGNvZGUgUmVzdWx0U2V0fXMgdGhhdCBzYXRpc2Z5IHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIHtAY29kZSByZXN1bHRTZXRUeXBlfSwKKyAgICAgKiAgICAgICAgIHtAY29kZSByZXN1bHRTZXRDb25jdXJyZW5jeX0gYW5kCisgICAgICogICAgICAgICB7QGNvZGUgcmVzdWx0U2V0SG9sZGFiaWxpdHl9IHZhbHVlcy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBTdGF0ZW1lbnQgY3JlYXRlU3RhdGVtZW50KGludCByZXN1bHRTZXRUeXBlLAorICAgICAgICAgICAgaW50IHJlc3VsdFNldENvbmN1cnJlbmN5LCBpbnQgcmVzdWx0U2V0SG9sZGFiaWxpdHkpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBib29sZWFufSBpbmRpY2F0aW5nIHdoZXRoZXIgb3Igbm90IHRoaXMgY29ubmVjdGlvbiBpcyBpbgorICAgICAqIHRoZSB7QGNvZGUgYXV0by1jb21taXR9IG9wZXJhdGluZyBtb2RlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIGF1dG8tY29tbWl0fSBpcyBvbiwgb3RoZXJ3aXNlIHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBwcm9ibGVtIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0QXV0b0NvbW1pdCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoaXMge0Bjb2RlIENvbm5lY3Rpb259IG9iamVjdCdzIGN1cnJlbnQgY2F0YWxvZyBuYW1lLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2F0YWxvZyBuYW1lLiB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgaXMgbm8gY2F0YWxvZworICAgICAqICAgICAgICAgbmFtZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2F0YWxvZygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBob2xkYWJpbGl0eSBwcm9wZXJ0eSB0aGF0IGFueSB7QGNvZGUgUmVzdWx0U2V0fSBwcm9kdWNlZCBieQorICAgICAqIHRoaXMgaW5zdGFuY2Ugd2lsbCBoYXZlLgorICAgICAqCisgICAgICogQHJldHVybiBvbmUgb2YgdGhlIGZvbGxvd2luZyBob2xkYWJpbGl0eSBtb2RlIHNwZWNpZmllcnM6CisgICAgICogICAgICAgICA8dWw+CisgICAgICogICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNIT0xEX0NVUlNPUlNfT1ZFUl9DT01NSVR9PC9saT4gPGxpPgorICAgICAqICAgICAgICAge0BsaW5rIFJlc3VsdFNldCNDTE9TRV9DVVJTT1JTX0FUX0NPTU1JVH08L2xpPgorICAgICAqICAgICAgICAgPC91bD4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGEgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRIb2xkYWJpbGl0eSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtZXRhZGF0YSBhYm91dCB0aGUgZGF0YWJhc2UgcmVmZXJlbmNlZCBieSB0aGlzIGNvbm5lY3Rpb24uIFRoZQorICAgICAqIHJldHVybmVkIHtAY29kZSBEYXRhYmFzZU1ldGFEYXRhfSBkZXNjcmliZXMgdGhlIGRhdGFiYXNlIHRvcG9ncmFwaHksCisgICAgICogYXZhaWxhYmxlIHN0b3JlZCBwcm9jZWR1cmVzLCBTUUwgc3ludGF4IGFuZCBzbyBvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgRGF0YWJhc2VNZXRhRGF0YX0gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGRhdGFiYXNlCisgICAgICogICAgICAgICBkZXNjcmlwdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGEgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIERhdGFiYXNlTWV0YURhdGEgZ2V0TWV0YURhdGEoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdHJhbnNhY3Rpb24gaXNvbGF0aW9uIGxldmVsIGZvciB0aGlzIGNvbm5lY3Rpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB0cmFuc2FjdGlvbiBpc29sYXRpb24gdmFsdWUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKiBAc2VlICNUUkFOU0FDVElPTl9OT05FCisgICAgICogQHNlZSAjVFJBTlNBQ1RJT05fUkVBRF9DT01NSVRURUQKKyAgICAgKiBAc2VlICNUUkFOU0FDVElPTl9SRUFEX1VOQ09NTUlUVEVECisgICAgICogQHNlZSAjVFJBTlNBQ1RJT05fUkVQRUFUQUJMRV9SRUFECisgICAgICogQHNlZSAjVFJBTlNBQ1RJT05fU0VSSUFMSVpBQkxFCisgICAgICovCisgICAgcHVibGljIGludCBnZXRUcmFuc2FjdGlvbklzb2xhdGlvbigpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIG1hcHBpbmcgYXNzb2NpYXRlZCB3aXRoIHRoaXMge0Bjb2RlIENvbm5lY3Rpb259IG9iamVjdC4KKyAgICAgKiBUaGUgdHlwZSBtYXBwaW5nIG11c3QgYmUgc2V0IG9uIHRoZSBhcHBsaWNhdGlvbiBsZXZlbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIFR5cGUgTWFwIGFzIGEge0Bjb2RlIGphdmEudXRpbC5NYXB9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBwcm9ibGVtIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIE1hcDxTdHJpbmcsIENsYXNzPD8+PiBnZXRUeXBlTWFwKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGZpcnN0IGluc3RhbmNlIG9mIGFueSB7QGNvZGUgU1FMV2FybmluZ30gb2JqZWN0cyB0aGF0IG1heSBoYXZlCisgICAgICogYmVlbiBjcmVhdGVkIGluIHRoZSB1c2Ugb2YgdGhpcyBjb25uZWN0aW9uLiBJZiBhdCBsZWFzdCBvbmUgd2FybmluZyBoYXMKKyAgICAgKiBvY2N1cnJlZCB0aGVuIHRoaXMgb3BlcmF0aW9uIHJldHVybnMgdGhlIGZpcnN0IG9uZSByZXBvcnRlZC4gQSB7QGNvZGUKKyAgICAgKiBudWxsfSBpbmRpY2F0ZXMgdGhhdCBubyB3YXJuaW5ncyBoYXZlIG9jY3VycmVkLgorICAgICAqIDxwPgorICAgICAqIEJ5IGludm9raW5nIHRoZSB7QGxpbmsgU1FMV2FybmluZyNnZXROZXh0V2FybmluZygpfSBtZXRob2Qgb2YgdGhlCisgICAgICogcmV0dXJuZWQge0Bjb2RlIFNRTFdhcm5pbmd9IG9iamVjdCBpdCBpcyBwb3NzaWJsZSB0byBvYnRhaW4gYWxsIG9mCisgICAgICogdGhpcyBjb25uZWN0aW9uJ3Mgd2FybmluZyBvYmplY3RzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZmlyc3Qgd2FybmluZyBhcyBhbiBTUUxXYXJuaW5nIG9iamVjdCAobWF5IGJlIHtAY29kZSBudWxsfSkuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZSBvciBpZiB0aGUgY2FsbAorICAgICAqICAgICAgICAgICAgIGhhcyBiZWVuIG1hZGUgb24gYSBjb25uZWN0aW9uIHdoaWNoIGhhcyBiZWVuIHByZXZpb3VzbHkKKyAgICAgKiAgICAgICAgICAgICBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIFNRTFdhcm5pbmcgZ2V0V2FybmluZ3MoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBib29sZWFufSBpbmRpY2F0aW5nIHdoZXRoZXIgb3Igbm90IHRoaXMgY29ubmVjdGlvbiBpcyBpbgorICAgICAqIHRoZSB7QGNvZGUgY2xvc2VkfSBzdGF0ZS4gVGhlIHtAY29kZSBjbG9zZWR9IHN0YXRlIG1heSBiZSBlbnRlcmVkIGludG8gYXMKKyAgICAgKiBhIGNvbnNlcXVlbmNlIG9mIGEgc3VjY2Vzc2Z1bCBpbnZvY2F0aW9uIG9mIHRoZSB7QGxpbmsgI2Nsb3NlKCl9IG1ldGhvZAorICAgICAqIG9yIGVsc2UgaWYgYW4gZXJyb3IgaGFzIG9jY3VycmVkIHRoYXQgcHJldmVudHMgdGhlIGNvbm5lY3Rpb24gZnJvbQorICAgICAqIGZ1bmN0aW9uaW5nIG5vcm1hbGx5LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgY2xvc2VkLCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQ2xvc2VkKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgYm9vbGVhbn0gaW5kaWNhdGluZyB3aGV0aGVyIG9yIG5vdCB0aGlzIGNvbm5lY3Rpb24gaXMKKyAgICAgKiBjdXJyZW50bHkgaW4gdGhlIHtAY29kZSByZWFkLW9ubHl9IHN0YXRlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgaW4gcmVhZC1vbmx5IHN0YXRlLCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUmVhZE9ubHkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgaW5wdXQgU1FMIHN0YXRlbWVudAorICAgICAqIHtAY29kZSBzcWx9IGV4cHJlc3NlZCBpbiB0aGUgdW5kZXJseWluZyBzeXN0ZW0ncyBuYXRpdmUgU1FMCisgICAgICogc3ludGF4LgorICAgICAqCisgICAgICogQHBhcmFtIHNxbAorICAgICAqICAgICAgICAgICAgdGhlIEpEQkMgZm9ybSBvZiBhbiBTUUwgc3RhdGVtZW50LgorICAgICAqIEByZXR1cm4gdGhlIFNRTCBzdGF0ZW1lbnQgaW4gbmF0aXZlIGRhdGFiYXNlIGZvcm1hdC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBuYXRpdmVTUUwoU3RyaW5nIHNxbCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIENhbGxhYmxlU3RhdGVtZW50fSB0aGF0IG1heSBiZSB1c2VkIGZvcgorICAgICAqIG1ha2luZyBzdG9yZWQgcHJvY2VkdXJlIGNhbGxzIHRvIHRoZSBkYXRhYmFzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBTUUwgc3RhdGVtZW50IHRoYXQgY2FsbHMgdGhlIHN0b3JlZCBmdW5jdGlvbgorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIENhbGxhYmxlU3RhdGVtZW50fSByZXByZXNlbnRpbmcgdGhlIFNRTAorICAgICAqICAgICAgICAgc3RhdGVtZW50LiB7QGNvZGUgUmVzdWx0U2V0fXMgZW1pdHRlZCBmcm9tIHRoaXMge0Bjb2RlCisgICAgICogICAgICAgICBDYWxsYWJsZVN0YXRlbWVudH0gd2lsbCBkZWZhdWx0IHRvIHR5cGUKKyAgICAgKiAgICAgICAgIHtAbGluayBSZXN1bHRTZXQjVFlQRV9GT1JXQVJEX09OTFl9IGFuZCBjb25jdXJyZW5jeQorICAgICAqICAgICAgICAge0BsaW5rIFJlc3VsdFNldCNDT05DVVJfUkVBRF9PTkxZfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2FsbGFibGVTdGF0ZW1lbnQgcHJlcGFyZUNhbGwoU3RyaW5nIHNxbCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIENhbGxhYmxlU3RhdGVtZW50fSB0aGF0IG1heSBiZSB1c2VkIGZvcgorICAgICAqIG1ha2luZyBzdG9yZWQgcHJvY2VkdXJlIGNhbGxzIHRvIHRoZSBkYXRhYmFzZS4ge0Bjb2RlIFJlc3VsdFNldH1zIGVtaXR0ZWQKKyAgICAgKiBmcm9tIHRoaXMge0Bjb2RlIENhbGxhYmxlU3RhdGVtZW50fSB3aWxsIHNhdGlzZnkgdGhlIHNwZWNpZmllZCB7QGNvZGUKKyAgICAgKiByZXN1bHRTZXRUeXBlfSBhbmQge0Bjb2RlIHJlc3VsdFNldENvbmN1cnJlbmN5fSB2YWx1ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3FsCisgICAgICogICAgICAgICAgICB0aGUgU1FMIHN0YXRlbWVudAorICAgICAqIEBwYXJhbSByZXN1bHRTZXRUeXBlCisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZyB0eXBlIHNwZWNpZmllcnM6CisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNUWVBFX1NDUk9MTF9TRU5TSVRJVkV9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I1RZUEVfU0NST0xMX0lOU0VOU0lUSVZFfTwvbGk+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNUWVBFX0ZPUldBUkRfT05MWX08L2xpPgorICAgICAqICAgICAgICAgICAgPC91bD4KKyAgICAgKiBAcGFyYW0gcmVzdWx0U2V0Q29uY3VycmVuY3kKKyAgICAgKiAgICAgICAgICAgIG9uZSBvZiB0aGUgZm9sbG93aW5nIGNvbmN1cnJlbmN5IG1vZGUgc3BlY2lmaWVyczoKKyAgICAgKiAgICAgICAgICAgIDx1bD4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I0NPTkNVUl9SRUFEX09OTFl9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I0NPTkNVUl9VUERBVEFCTEV9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDwvdWw+CisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgQ2FsbGFibGVTdGF0ZW1lbnR9IHJlcHJlc2VudGluZyB0aGUKKyAgICAgKiAgICAgICAgIHByZWNvbXBpbGVkIFNRTCBzdGF0ZW1lbnQuIHtAY29kZSBSZXN1bHRTZXR9cyBlbWl0dGVkIGZyb20gdGhpcworICAgICAqICAgICAgICAge0Bjb2RlIENhbGxhYmxlU3RhdGVtZW50fSB3aWxsIHNhdGlzZnkgdGhlIHNwZWNpZmllZCB7QGNvZGUKKyAgICAgKiAgICAgICAgIHJlc3VsdFNldFR5cGV9IGFuZCB7QGNvZGUgcmVzdWx0U2V0Q29uY3VycmVuY3l9IHZhbHVlcy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZQorICAgICAqLworICAgIHB1YmxpYyBDYWxsYWJsZVN0YXRlbWVudCBwcmVwYXJlQ2FsbChTdHJpbmcgc3FsLCBpbnQgcmVzdWx0U2V0VHlwZSwKKyAgICAgICAgICAgIGludCByZXN1bHRTZXRDb25jdXJyZW5jeSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIENhbGxhYmxlU3RhdGVtZW50fSB0aGF0IG1heSBiZSB1c2VkIGZvcgorICAgICAqIG1ha2luZyBzdG9yZWQgcHJvY2VkdXJlIGNhbGxzIHRvIHRoZSBkYXRhYmFzZS4ge0Bjb2RlIFJlc3VsdFNldH1zIGNyZWF0ZWQKKyAgICAgKiBmcm9tIHRoaXMge0Bjb2RlIENhbGxhYmxlU3RhdGVtZW50fSB3aWxsIGhhdmUgY2hhcmFjdGVyaXN0aWNzIGRldGVybWluZWQKKyAgICAgKiBieSB0aGUgc3BlY2lmaWVkIHR5cGUsIGNvbmN1cnJlbmN5IGFuZCBob2xkYWJpbGl0eSBhcmd1bWVudHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3FsCisgICAgICogICAgICAgICAgICB0aGUgU1FMIHN0YXRlbWVudAorICAgICAqIEBwYXJhbSByZXN1bHRTZXRUeXBlCisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZyB0eXBlIHNwZWNpZmllcnM6CisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNUWVBFX1NDUk9MTF9TRU5TSVRJVkV9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I1RZUEVfU0NST0xMX0lOU0VOU0lUSVZFfTwvbGk+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNUWVBFX0ZPUldBUkRfT05MWX08L2xpPgorICAgICAqICAgICAgICAgICAgPC91bD4KKyAgICAgKiBAcGFyYW0gcmVzdWx0U2V0Q29uY3VycmVuY3kKKyAgICAgKiAgICAgICAgICAgIG9uZSBvZiB0aGUgZm9sbG93aW5nIGNvbmN1cnJlbmN5IG1vZGUgc3BlY2lmaWVyczoKKyAgICAgKiAgICAgICAgICAgIDx1bD4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I0NPTkNVUl9SRUFEX09OTFl9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I0NPTkNVUl9VUERBVEFCTEV9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDwvdWw+CisgICAgICogQHBhcmFtIHJlc3VsdFNldEhvbGRhYmlsaXR5CisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZyBob2xkYWJpbGl0eSBtb2RlIHNwZWNpZmllcnM6CisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNIT0xEX0NVUlNPUlNfT1ZFUl9DT01NSVR9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I0NMT1NFX0NVUlNPUlNfQVRfQ09NTUlUfTwvbGk+CisgICAgICogICAgICAgICAgICA8L3VsPgorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIENhbGxhYmxlU3RhdGVtZW50fSByZXByZXNlbnRpbmcgdGhlCisgICAgICogICAgICAgICBwcmVjb21waWxlZCBTUUwgc3RhdGVtZW50LiB7QGNvZGUgUmVzdWx0U2V0fXMgZW1pdHRlZCBmcm9tIHRoaXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBDYWxsYWJsZVN0YXRlbWVudH0gd2lsbCBzYXRpc2Z5IHRoZSBzcGVjaWZpZWQge0Bjb2RlCisgICAgICogICAgICAgICByZXN1bHRTZXRUeXBlfSwge0Bjb2RlIHJlc3VsdFNldENvbmN1cnJlbmN5fSBhbmQge0Bjb2RlCisgICAgICogICAgICAgICByZXN1bHRTZXRIb2xkYWJpbGl0eX0gdmFsdWVzLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBDYWxsYWJsZVN0YXRlbWVudCBwcmVwYXJlQ2FsbChTdHJpbmcgc3FsLCBpbnQgcmVzdWx0U2V0VHlwZSwKKyAgICAgICAgICAgIGludCByZXN1bHRTZXRDb25jdXJyZW5jeSwgaW50IHJlc3VsdFNldEhvbGRhYmlsaXR5KQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFByZXBhcmVkU3RhdGVtZW50fSB0aGF0IG1heSBiZSB1c2VkIGFueQorICAgICAqIG51bWJlciBvZiB0aW1lcyB0byBleGVjdXRlIHBhcmFtZXRlcml6ZWQgcmVxdWVzdHMgb24gdGhlIGRhdGFiYXNlIHNlcnZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBTdWJqZWN0IHRvIEpEQkMgZHJpdmVyIHN1cHBvcnQsIHRoaXMgb3BlcmF0aW9uIHdpbGwgYXR0ZW1wdCB0byBzZW5kIHRoZQorICAgICAqIHByZWNvbXBpbGVkIHZlcnNpb24gb2YgdGhlIHN0YXRlbWVudCB0byB0aGUgZGF0YWJhc2UuIElmCisgICAgICogdGhlIGRyaXZlciBkb2VzIG5vdCBzdXBwb3J0IHByZWNvbXBpbGVkIHN0YXRlbWVudHMsIHRoZSBzdGF0ZW1lbnQgd2lsbAorICAgICAqIG5vdCByZWFjaCB0aGUgZGF0YWJhc2Ugc2VydmVyIHVudGlsIGl0IGlzIGV4ZWN1dGVkLiBUaGlzIGRpc3RpbmN0aW9uCisgICAgICogZGV0ZXJtaW5lcyB0aGUgbW9tZW50IHdoZW4ge0Bjb2RlIFNRTEV4Y2VwdGlvbn1zIGdldCByYWlzZWQuCisgICAgICogPHA+CisgICAgICogQnkgZGVmYXVsdCwge0Bjb2RlIFJlc3VsdFNldH1zIGZyb20gdGhlIHJldHVybmVkIG9iamVjdCB3aWxsIGJlCisgICAgICoge0BsaW5rIFJlc3VsdFNldCNUWVBFX0ZPUldBUkRfT05MWX0gdHlwZSB3aXRoIGEKKyAgICAgKiB7QGxpbmsgUmVzdWx0U2V0I0NPTkNVUl9SRUFEX09OTFl9IG1vZGUgb2YgY29uY3VycmVuY3kuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3FsCisgICAgICogICAgICAgICAgICB0aGUgU1FMIHN0YXRlbWVudC4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgUHJlcGFyZWRTdGF0ZW1lbnR9IGNvbnRhaW5pbmcgdGhlIHN1cHBsaWVkIFNRTAorICAgICAqICAgICAgICAgc3RhdGVtZW50LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBwcm9ibGVtIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIFByZXBhcmVkU3RhdGVtZW50IHByZXBhcmVTdGF0ZW1lbnQoU3RyaW5nIHNxbCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBkZWZhdWx0IHtAY29kZSBQcmVwYXJlZFN0YXRlbWVudH0gdGhhdCBjYW4gcmV0cmlldmUKKyAgICAgKiBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBrZXlzLiBQYXJhbWV0ZXIge0Bjb2RlIGF1dG9HZW5lcmF0ZWRLZXlzfSBtYXkgYmUKKyAgICAgKiB1c2VkIHRvIHRlbGwgdGhlIGRyaXZlciB3aGV0aGVyIHN1Y2gga2V5cyBzaG91bGQgYmUgbWFkZSBhY2Nlc3NpYmxlLgorICAgICAqIFRoaXMgaXMgb25seSByZWxldmFudCB3aGVuIHRoZSB7QGNvZGUgc3FsfSBzdGF0ZW1lbnQgaXMgYW4ge0Bjb2RlIGluc2VydH0KKyAgICAgKiBzdGF0ZW1lbnQuCisgICAgICogPHA+CisgICAgICogQW4gU1FMIHN0YXRlbWVudCB3aGljaCBtYXkgaGF2ZSB7QGNvZGUgSU59IHBhcmFtZXRlcnMgY2FuIGJlIHN0b3JlZCBhbmQKKyAgICAgKiBwcmVjb21waWxlZCBpbiBhIHtAY29kZSBQcmVwYXJlZFN0YXRlbWVudH0uIFRoZSB7QGNvZGUgUHJlcGFyZWRTdGF0ZW1lbnR9CisgICAgICogY2FuIHRoZW4gYmUgdGhlbiBiZSB1c2VkIHRvIGV4ZWN1dGUgdGhlIHN0YXRlbWVudCBtdWx0aXBsZSB0aW1lcyBpbiBhbgorICAgICAqIGVmZmljaWVudCB3YXkuCisgICAgICogPHA+CisgICAgICogU3ViamVjdCB0byBKREJDIGRyaXZlciBzdXBwb3J0LCB0aGlzIG9wZXJhdGlvbiB3aWxsIGF0dGVtcHQgdG8gc2VuZCB0aGUKKyAgICAgKiBwcmVjb21waWxlZCB2ZXJzaW9uIG9mIHRoZSBzdGF0ZW1lbnQgdG8gdGhlIGRhdGFiYXNlLiBJZgorICAgICAqIHRoZSBkcml2ZXIgZG9lcyBub3Qgc3VwcG9ydCBwcmVjb21waWxlZCBzdGF0ZW1lbnRzLCB0aGUgc3RhdGVtZW50IHdpbGwKKyAgICAgKiBub3QgcmVhY2ggdGhlIGRhdGFiYXNlIHNlcnZlciB1bnRpbCBpdCBpcyBleGVjdXRlZC4gVGhpcyBkaXN0aW5jdGlvbgorICAgICAqIGRldGVybWluZXMgdGhlIG1vbWVudCB3aGVuIHtAY29kZSBTUUxFeGNlcHRpb259cyBnZXQgcmFpc2VkLgorICAgICAqIDxwPgorICAgICAqIEJ5IGRlZmF1bHQsIHtAY29kZSBSZXN1bHRTZXR9cyBmcm9tIHRoZSByZXR1cm5lZCBvYmplY3Qgd2lsbCBiZQorICAgICAqIHtAbGluayBSZXN1bHRTZXQjVFlQRV9GT1JXQVJEX09OTFl9IHR5cGUgd2l0aCBhCisgICAgICoge0BsaW5rIFJlc3VsdFNldCNDT05DVVJfUkVBRF9PTkxZfSBtb2RlIG9mIGNvbmN1cnJlbmN5LgorICAgICAqCisgICAgICogQHBhcmFtIHNxbAorICAgICAqICAgICAgICAgICAgdGhlIFNRTCBzdGF0ZW1lbnQuCisgICAgICogQHBhcmFtIGF1dG9HZW5lcmF0ZWRLZXlzCisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZyBnZW5lcmF0ZWQga2V5IG9wdGlvbnM6CisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFN0YXRlbWVudCNSRVRVUk5fR0VORVJBVEVEX0tFWVN9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgU3RhdGVtZW50I05PX0dFTkVSQVRFRF9LRVlTfTwvbGk+CisgICAgICogICAgICAgICAgICA8L3VsPgorICAgICAqIEByZXR1cm4gYSBuZXcge0Bjb2RlIFByZXBhcmVkU3RhdGVtZW50fSBpbnN0YW5jZSByZXByZXNlbnRpbmcgdGhlIGlucHV0CisgICAgICogICAgICAgICBTUUwgc3RhdGVtZW50LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBwcm9ibGVtIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIFByZXBhcmVkU3RhdGVtZW50IHByZXBhcmVTdGF0ZW1lbnQoU3RyaW5nIHNxbCwgaW50IGF1dG9HZW5lcmF0ZWRLZXlzKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBkZWZhdWx0IHtAY29kZSBQcmVwYXJlZFN0YXRlbWVudH0gdGhhdCBjYW4gcmV0cmlldmUgdGhlCisgICAgICogYXV0by1nZW5lcmF0ZWQga2V5cyBkZXNpZ25hdGVkIGJ5IGEgc3VwcGxpZWQgYXJyYXkuIElmIHtAY29kZSBzcWx9IGlzIGFuCisgICAgICogU1FMIHtAY29kZSBJTlNFUlR9IHN0YXRlbWVudCwgdGhlIHBhcmFtZXRlciB7QGNvZGUgY29sdW1uSW5kZXhlc30gaXMgZXhwZWN0ZWQKKyAgICAgKiB0byBob2xkIHRoZSBpbmRleCB2YWx1ZXMgZm9yIGVhY2ggY29sdW1uIGluIHRoZSBzdGF0ZW1lbnQncyBpbnRlbmRlZAorICAgICAqIGRhdGFiYXNlIHRhYmxlIGNvbnRhaW5pbmcgdGhlIGF1dG9nZW5lcmF0ZWQta2V5cyBvZiBpbnRlcmVzdC4gT3RoZXJ3aXNlCisgICAgICoge0Bjb2RlIGNvbHVtbkluZGV4ZXN9IGlzIGlnbm9yZWQuCisgICAgICogPHA+CisgICAgICogU3ViamVjdCB0byBKREJDIGRyaXZlciBzdXBwb3J0LCB0aGlzIG9wZXJhdGlvbiB3aWxsIGF0dGVtcHQgdG8gc2VuZCB0aGUKKyAgICAgKiBwcmVjb21waWxlZCB2ZXJzaW9uIG9mIHRoZSBzdGF0ZW1lbnQgdG8gdGhlIGRhdGFiYXNlLiBJZgorICAgICAqIHRoZSBkcml2ZXIgZG9lcyBub3Qgc3VwcG9ydCBwcmVjb21waWxlZCBzdGF0ZW1lbnRzLCB0aGUgc3RhdGVtZW50IHdpbGwKKyAgICAgKiBub3QgcmVhY2ggdGhlIGRhdGFiYXNlIHNlcnZlciB1bnRpbCBpdCBpcyBleGVjdXRlZC4gVGhpcyBkaXN0aW5jdGlvbgorICAgICAqIGRldGVybWluZXMgdGhlIG1vbWVudCB3aGVuIHtAY29kZSBTUUxFeGNlcHRpb259cyBnZXQgcmFpc2VkLgorICAgICAqIDxwPgorICAgICAqIEJ5IGRlZmF1bHQsIHtAY29kZSBSZXN1bHRTZXR9cyBmcm9tIHRoZSByZXR1cm5lZCBvYmplY3Qgd2lsbCBiZQorICAgICAqIHtAbGluayBSZXN1bHRTZXQjVFlQRV9GT1JXQVJEX09OTFl9IHR5cGUgd2l0aCBhCisgICAgICoge0BsaW5rIFJlc3VsdFNldCNDT05DVVJfUkVBRF9PTkxZfSBjb25jdXJyZW5jeSBtb2RlLgorICAgICAqCisgICAgICogQHBhcmFtIHNxbAorICAgICAqICAgICAgICAgICAgdGhlIFNRTCBzdGF0ZW1lbnQuCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4ZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleGVzIG9mIHRoZSBjb2x1bW5zIGZvciB3aGljaCBhdXRvLWdlbmVyYXRlZCBrZXlzCisgICAgICogICAgICAgICAgICBzaG91bGQgYmUgbWFkZSBhdmFpbGFibGUuCisgICAgICogQHJldHVybiB0aGUgUHJlcGFyZWRTdGF0ZW1lbnQgY29udGFpbmluZyB0aGUgc3VwcGxpZWQgU1FMIHN0YXRlbWVudC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJlcGFyZWRTdGF0ZW1lbnQgcHJlcGFyZVN0YXRlbWVudChTdHJpbmcgc3FsLCBpbnRbXSBjb2x1bW5JbmRleGVzKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgUHJlcGFyZWRTdGF0ZW1lbnR9IHRoYXQgZ2VuZXJhdGVzIHtAY29kZSBSZXN1bHRTZXR9cworICAgICAqIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZXMgb2Yge0Bjb2RlIHJlc3VsdFNldFR5cGV9IGFuZCB7QGNvZGUKKyAgICAgKiByZXN1bHRTZXRDb25jdXJyZW5jeX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3FsCisgICAgICogICAgICAgICAgICB0aGUgU1FMIHN0YXRlbWVudC4gSXQgY2FuIGNvbnRhaW4gb25lIG9yIG1vcmUge0Bjb2RlICc/J30KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBJTn0gcGFyYW1ldGVyIHBsYWNlaG9sZGVycy4KKyAgICAgKiBAcGFyYW0gcmVzdWx0U2V0VHlwZQorICAgICAqICAgICAgICAgICAgb25lIG9mIHRoZSBmb2xsb3dpbmcgdHlwZSBzcGVjaWZpZXJzOgorICAgICAqICAgICAgICAgICAgPHVsPgorICAgICAqICAgICAgICAgICAgPGxpPntAbGluayBSZXN1bHRTZXQjVFlQRV9TQ1JPTExfU0VOU0lUSVZFfTwvbGk+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNUWVBFX1NDUk9MTF9JTlNFTlNJVElWRX08L2xpPgorICAgICAqICAgICAgICAgICAgPGxpPntAbGluayBSZXN1bHRTZXQjVFlQRV9GT1JXQVJEX09OTFl9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDwvdWw+CisgICAgICogQHBhcmFtIHJlc3VsdFNldENvbmN1cnJlbmN5CisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZyBjb25jdXJyZW5jeSBtb2RlIHNwZWNpZmllcnM6CisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNDT05DVVJfUkVBRF9PTkxZfTwvbGk+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNDT05DVVJfVVBEQVRBQkxFfTwvbGk+CisgICAgICogICAgICAgICAgICA8L3VsPgorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFByZXBhcmVkU3RhdGVtZW50fSBjb250YWluaW5nIHRoZSBTUUwKKyAgICAgKiAgICAgICAgIHN0YXRlbWVudCB7QGNvZGUgc3FsfS4ge0Bjb2RlIFJlc3VsdFNldH1zIGVtaXR0ZWQgZnJvbSB0aGlzCisgICAgICogICAgICAgICB7QGNvZGUgUHJlcGFyZWRTdGF0ZW1lbnR9IHdpbGwgc2F0aXNmeSB0aGUgc3BlY2lmaWVkIHtAY29kZQorICAgICAqICAgICAgICAgcmVzdWx0U2V0VHlwZX0gYW5kIHtAY29kZSByZXN1bHRTZXRDb25jdXJyZW5jeX0gdmFsdWVzLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBQcmVwYXJlZFN0YXRlbWVudCBwcmVwYXJlU3RhdGVtZW50KFN0cmluZyBzcWwsIGludCByZXN1bHRTZXRUeXBlLAorICAgICAgICAgICAgaW50IHJlc3VsdFNldENvbmN1cnJlbmN5KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHtAY29kZSBQcmVwYXJlZFN0YXRlbWVudH0gdGhhdCBnZW5lcmF0ZXMge0Bjb2RlIFJlc3VsdFNldH1zCisgICAgICogd2l0aCB0aGUgc3BlY2lmaWVkIHR5cGUsIGNvbmN1cnJlbmN5IGFuZCBob2xkYWJpbGl0eQorICAgICAqCisgICAgICogQHBhcmFtIHNxbAorICAgICAqICAgICAgICAgICAgdGhlIFNRTCBzdGF0ZW1lbnQuIEl0IGNhbiBjb250YWluIG9uZSBvciBtb3JlIHtAY29kZSAnPycgSU59CisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIgcGxhY2Vob2xkZXJzLgorICAgICAqIEBwYXJhbSByZXN1bHRTZXRUeXBlCisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZyB0eXBlIHNwZWNpZmllcnM6CisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNUWVBFX1NDUk9MTF9TRU5TSVRJVkV9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I1RZUEVfU0NST0xMX0lOU0VOU0lUSVZFfTwvbGk+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNUWVBFX0ZPUldBUkRfT05MWX08L2xpPgorICAgICAqICAgICAgICAgICAgPC91bD4KKyAgICAgKiBAcGFyYW0gcmVzdWx0U2V0Q29uY3VycmVuY3kKKyAgICAgKiAgICAgICAgICAgIG9uZSBvZiB0aGUgZm9sbG93aW5nIGNvbmN1cnJlbmN5IG1vZGUgc3BlY2lmaWVyczoKKyAgICAgKiAgICAgICAgICAgIDx1bD4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I0NPTkNVUl9SRUFEX09OTFl9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I0NPTkNVUl9VUERBVEFCTEV9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDwvdWw+CisgICAgICogQHBhcmFtIHJlc3VsdFNldEhvbGRhYmlsaXR5CisgICAgICogICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZyBob2xkYWJpbGl0eSBtb2RlIHNwZWNpZmllcnM6CisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rIFJlc3VsdFNldCNIT0xEX0NVUlNPUlNfT1ZFUl9DT01NSVR9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I0NMT1NFX0NVUlNPUlNfQVRfQ09NTUlUfTwvbGk+CisgICAgICogICAgICAgICAgICA8L3VsPgorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFByZXBhcmVkU3RhdGVtZW50fSBjb250YWluaW5nIHRoZSBTUUwKKyAgICAgKiAgICAgICAgIHN0YXRlbWVudCB7QGNvZGUgc3FsfS4ge0Bjb2RlIFJlc3VsdFNldH1zIGVtaXR0ZWQgZnJvbSB0aGlzCisgICAgICogICAgICAgICB7QGNvZGUgUHJlcGFyZWRTdGF0ZW1lbnR9IHdpbGwgc2F0aXNmeSB0aGUgc3BlY2lmaWVkIHtAY29kZQorICAgICAqICAgICAgICAgcmVzdWx0U2V0VHlwZX0sIHtAY29kZSByZXN1bHRTZXRDb25jdXJyZW5jeX0gYW5kIHtAY29kZQorICAgICAqICAgICAgICAgcmVzdWx0U2V0SG9sZGFiaWxpdHl9IHZhbHVlcy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJlcGFyZWRTdGF0ZW1lbnQgcHJlcGFyZVN0YXRlbWVudChTdHJpbmcgc3FsLCBpbnQgcmVzdWx0U2V0VHlwZSwKKyAgICAgICAgICAgIGludCByZXN1bHRTZXRDb25jdXJyZW5jeSwgaW50IHJlc3VsdFNldEhvbGRhYmlsaXR5KQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBkZWZhdWx0IHtAY29kZSBQcmVwYXJlZFN0YXRlbWVudH0gdGhhdCBjYW4gcmV0cmlldmUgdGhlCisgICAgICogYXV0by1nZW5lcmF0ZWQga2V5cyBkZXNpZ25hdGVkIGJ5IGEgc3VwcGxpZWQgYXJyYXkuIElmIHtAY29kZSBzcWx9IGlzIGFuCisgICAgICogU1FMIHtAY29kZSBJTlNFUlR9IHN0YXRlbWVudCwge0Bjb2RlIGNvbHVtbk5hbWVzfSBpcyBleHBlY3RlZCB0byBob2xkIHRoZQorICAgICAqIG5hbWVzIG9mIGVhY2ggY29sdW1uIGluIHRoZSBzdGF0ZW1lbnQncyBhc3NvY2lhdGVkIGRhdGFiYXNlIHRhYmxlCisgICAgICogY29udGFpbmluZyB0aGUgYXV0b2dlbmVyYXRlZC1rZXlzIG9mIGludGVyZXN0LiBPdGhlcndpc2Uge0Bjb2RlCisgICAgICogY29sdW1uTmFtZXN9IGlzIGlnbm9yZWQuCisgICAgICogPHA+CisgICAgICogU3ViamVjdCB0byBKREJDIGRyaXZlciBzdXBwb3J0LCB0aGlzIG9wZXJhdGlvbiB3aWxsIGF0dGVtcHQgdG8gc2VuZCB0aGUKKyAgICAgKiBwcmVjb21waWxlZCB2ZXJzaW9uIG9mIHRoZSBzdGF0ZW1lbnQgdG8gdGhlIGRhdGFiYXNlLiBBbHRlcm5hdGl2ZWx5LCBpZgorICAgICAqIHRoZSBkcml2ZXIgaXMgbm90IGNhcGFibGUgb2YgaGFuZGxpbmcgcHJlY29tcGlsZWQgc3RhdGVtZW50cywgdGhlCisgICAgICogc3RhdGVtZW50IHdpbGwgbm90IHJlYWNoIHRoZSBkYXRhYmFzZSBzZXJ2ZXIgdW50aWwgaXQgaXMgZXhlY3V0ZWQuIFRoaXMKKyAgICAgKiB3aWxsIGhhdmUgYSBiZWFyaW5nIG9uIHByZWNpc2VseSA8aT53aGVuPC9pPiB7QGNvZGUgU1FMRXhjZXB0aW9ufQorICAgICAqIGluc3RhbmNlcyBnZXQgcmFpc2VkLgorICAgICAqIDxwPgorICAgICAqIEJ5IGRlZmF1bHQsIFJlc3VsdFNldHMgZnJvbSB0aGUgcmV0dXJuZWQgb2JqZWN0IHdpbGwgYmUKKyAgICAgKiB7QGxpbmsgUmVzdWx0U2V0I1RZUEVfRk9SV0FSRF9PTkxZfSB0eXBlIHdpdGggYQorICAgICAqIHtAbGluayBSZXN1bHRTZXQjQ09OQ1VSX1JFQURfT05MWX0gY29uY3VycmVuY3kgbW9kZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBTUUwgc3RhdGVtZW50LgorICAgICAqIEBwYXJhbSBjb2x1bW5OYW1lcworICAgICAqICAgICAgICAgICAgdGhlIG5hbWVzIG9mIHRoZSBjb2x1bW5zIGZvciB3aGljaCBhdXRvLWdlbmVyYXRlZCBrZXlzIHNob3VsZAorICAgICAqICAgICAgICAgICAgYmUgbWFkZSBhdmFpbGFibGUuCisgICAgICogQHJldHVybiB0aGUgUHJlcGFyZWRTdGF0ZW1lbnQgY29udGFpbmluZyB0aGUgc3VwcGxpZWQgU1FMIHN0YXRlbWVudC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJlcGFyZWRTdGF0ZW1lbnQgcHJlcGFyZVN0YXRlbWVudChTdHJpbmcgc3FsLCBTdHJpbmdbXSBjb2x1bW5OYW1lcykKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWxlYXNlcyB0aGUgc3BlY2lmaWVkIHtAY29kZSBzYXZlcG9pbnR9IGZyb20gdGhlIHByZXNlbnQgdHJhbnNhY3Rpb24uIE9uY2UgcmVtb3ZlZCwKKyAgICAgKiB0aGUge0Bjb2RlIFNhdmVwb2ludH0gaXMgY29uc2lkZXJlZCBpbnZhbGlkIGFuZCBzaG91bGQgbm90IGJlIHJlZmVyZW5jZWQKKyAgICAgKiBmdXJ0aGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHNhdmVwb2ludAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0YXJnZXRlZCBmb3IgcmVtb3ZhbC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2Ugb3IgaWYKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgc2F2ZXBvaW50fSBpcyBjb25zaWRlcmVkIG5vdCB2YWxpZCBpbiB0aGlzCisgICAgICogICAgICAgICAgICAgdHJhbnNhY3Rpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVsZWFzZVNhdmVwb2ludChTYXZlcG9pbnQgc2F2ZXBvaW50KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUm9sbHMgYmFjayBhbGwgdXBkYXRlcyBtYWRlIHNvIGZhciBpbiB0aGlzIHRyYW5zYWN0aW9uIGFuZAorICAgICAqIHJlbGlucXVpc2hlcyBhbGwgYWNxdWlyZWQgZGF0YWJhc2UgbG9ja3MuIEl0IGlzIGFuIGVycm9yIHRvIGludm9rZSB0aGlzCisgICAgICogb3BlcmF0aW9uIHdoZW4gaW4gYXV0by1jb21taXQgbW9kZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhlIGRhdGFiYXNlIG9yIGlmIHRoZSBtZXRob2QgaXMKKyAgICAgKiAgICAgICAgICAgICBjYWxsZWQgd2hpbGUgaW4gYXV0by1jb21taXQgbW9kZSBvZiBvcGVyYXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcm9sbGJhY2soKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVW5kb2VzIGFsbCBjaGFuZ2VzIG1hZGUgYWZ0ZXIgdGhlIHN1cHBsaWVkIHtAY29kZSBTYXZlcG9pbnR9IG9iamVjdCB3YXMKKyAgICAgKiBzZXQuIFRoaXMgbWV0aG9kIHNob3VsZCBvbmx5IGJlIHVzZWQgd2hlbiBhdXRvLWNvbW1pdCBtb2RlIGlzIGRpc2FibGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHNhdmVwb2ludAorICAgICAqICAgICAgICAgICAgdGhlIFNhdmVwb2ludCB0byByb2xsIGJhY2sgdG8KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJvbGxiYWNrKFNhdmVwb2ludCBzYXZlcG9pbnQpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoaXMgY29ubmVjdGlvbidzIGF1dG8tY29tbWl0IG1vZGUge0Bjb2RlIG9ufSBvciB7QGNvZGUgb2ZmfS4KKyAgICAgKiA8cD4KKyAgICAgKiBQdXR0aW5nIGEgQ29ubmVjdGlvbiBpbnRvIGF1dG8tY29tbWl0IG1vZGUgbWVhbnMgdGhhdCBhbGwgYXNzb2NpYXRlZCBTUUwKKyAgICAgKiBzdGF0ZW1lbnRzIGFyZSBydW4gYW5kIGNvbW1pdHRlZCBhcyBzZXBhcmF0ZSB0cmFuc2FjdGlvbnMuCisgICAgICogQnkgY29udHJhc3QsIHNldHRpbmcgYXV0by1jb21taXQgdG8ge0Bjb2RlIG9mZn0gbWVhbnMgdGhhdCBhc3NvY2lhdGVkIFNRTAorICAgICAqIHN0YXRlbWVudHMgZ2V0IGdyb3VwZWQgaW50byB0cmFuc2FjdGlvbnMgdGhhdCBuZWVkIHRvIGJlIGNvbXBsZXRlZCBieQorICAgICAqIGV4cGxpY2l0IGNhbGxzIHRvIGVpdGhlciB0aGUge0BsaW5rICNjb21taXQoKX0gb3Ige0BsaW5rICNyb2xsYmFjaygpfQorICAgICAqIG1ldGhvZHMuCisgICAgICogPHA+CisgICAgICogQXV0by1jb21taXQgaXMgdGhlIGRlZmF1bHQgbW9kZSBmb3IgbmV3IGNvbm5lY3Rpb24gaW5zdGFuY2VzLgorICAgICAqIDxwPgorICAgICAqIFdoZW4gaW4gdGhpcyBtb2RlLCBjb21taXRzIHdpbGwgYXV0b21hdGljYWxseSBvY2N1ciB1cG9uIHN1Y2Nlc3NmdWwgU1FMCisgICAgICogc3RhdGVtZW50IGNvbXBsZXRpb24gb3IgdXBvbiBzdWNjZXNzZnVsIGNvbXBsZXRpb24gb2YgYW4gZXhlY3V0ZS4KKyAgICAgKiBTdGF0ZW1lbnRzIGFyZSBub3QgY29uc2lkZXJlZCBzdWNjZXNzZnVsbHkgY29tcGxldGVkIHVudGlsIGFsbCBhc3NvY2lhdGVkCisgICAgICoge0Bjb2RlIFJlc3VsdFNldH1zIGFuZCBvdXRwdXQgcGFyYW1ldGVycyBoYXZlIGJlZW4gb2J0YWluZWQgb3IgY2xvc2VkLgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBvcGVyYXRpb24gZHVyaW5nIGFuIHVuY29tbWl0dGVkIHRyYW5zYWN0aW9uIHdpbGwgcmVzdWx0IGluCisgICAgICogaXQgYmVpbmcgY29tbWl0dGVkLgorICAgICAqCisgICAgICogQHBhcmFtIGF1dG9Db21taXQKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBib29sZWFufSBpbmRpY2F0aW9uIG9mIHdoZXRoZXIgdG8gcHV0IHRoZSB0YXJnZXQKKyAgICAgKiAgICAgICAgICAgIGNvbm5lY3Rpb24gaW50byBhdXRvLWNvbW1pdCBtb2RlICh7QGNvZGUgdHJ1ZX0pIG9yIG5vdCAoCisgICAgICogICAgICAgICAgICB7QGNvZGUgZmFsc2V9KS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEF1dG9Db21taXQoYm9vbGVhbiBhdXRvQ29tbWl0KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY2F0YWxvZyBuYW1lIGZvciB0aGlzIGNvbm5lY3Rpb24uIFRoaXMgaXMgdXNlZCB0byBzZWxlY3QgYQorICAgICAqIHN1YnNwYWNlIG9mIHRoZSBkYXRhYmFzZSBmb3IgZnV0dXJlIHdvcmsuIElmIHRoZSBkcml2ZXIgZG9lcyBub3Qgc3VwcG9ydAorICAgICAqIGNhdGFsb2cgbmFtZXMsIHRoaXMgbWV0aG9kIGlzIGlnbm9yZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F0YWxvZworICAgICAqICAgICAgICAgICAgdGhlIGNhdGFsb2cgbmFtZSB0byB1c2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDYXRhbG9nKFN0cmluZyBjYXRhbG9nKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgaG9sZGFiaWxpdHkgb2YgdGhlIHtAY29kZSBSZXN1bHRTZXR9cyBjcmVhdGVkIGJ5IHRoaXMgQ29ubmVjdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob2xkYWJpbGl0eQorICAgICAqICAgICAgICAgICAgb25lIG9mIHRoZSBmb2xsb3dpbmcgaG9sZGFiaWxpdHkgbW9kZSBzcGVjaWZpZXJzOgorICAgICAqICAgICAgICAgICAgPHVsPgorICAgICAqICAgICAgICAgICAgPGxpPntAbGluayBSZXN1bHRTZXQjQ0xPU0VfQ1VSU09SU19BVF9DT01NSVR9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgUmVzdWx0U2V0I0hPTERfQ1VSU09SU19PVkVSX0NPTU1JVH08L2xpPgorICAgICAqICAgICAgICAgICAgPGxpPgorICAgICAqICAgICAgICAgICAgPC91bD4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SG9sZGFiaWxpdHkoaW50IGhvbGRhYmlsaXR5KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGlzIGNvbm5lY3Rpb24gdG8gcmVhZC1vbmx5IG1vZGUuCisgICAgICogPHA+CisgICAgICogVGhpcyBzZXJ2ZXMgYXMgYSBoaW50IHRvIHRoZSBkcml2ZXIsIHdoaWNoIGNhbiBlbmFibGUgZGF0YWJhc2UKKyAgICAgKiBvcHRpbWl6YXRpb25zLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYWRPbmx5CisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gdG8gc2V0IHRoZSBDb25uZWN0aW9uIHRvIHJlYWQgb25seSBtb2RlLiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIGZhbHNlfSBkaXNhYmxlcyByZWFkLW9ubHkgbW9kZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFJlYWRPbmx5KGJvb2xlYW4gcmVhZE9ubHkpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIHVubmFtZWQge0Bjb2RlIFNhdmVwb2ludH0gaW4gdGhlIGN1cnJlbnQgdHJhbnNhY3Rpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFNhdmVwb2ludH0gb2JqZWN0IGZvciB0aGlzIHNhdmVwb2ludC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBTYXZlcG9pbnQgc2V0U2F2ZXBvaW50KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuYW1lZCB7QGNvZGUgU2F2ZXBvaW50fSBpbiB0aGUgY3VycmVudCB0cmFuc2FjdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSB0byB1c2UgZm9yIHRoZSBuZXcge0Bjb2RlIFNhdmVwb2ludH0uCisgICAgICogQHJldHVybiBhIHtAY29kZSBTYXZlcG9pbnR9IG9iamVjdCBmb3IgdGhpcyBzYXZlcG9pbnQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2F2ZXBvaW50IHNldFNhdmVwb2ludChTdHJpbmcgbmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHRyYW5zYWN0aW9uIGlzb2xhdGlvbiBsZXZlbCBmb3IgdGhpcyBDb25uZWN0aW9uLgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBkdXJpbmcgYSB0cmFuc2FjdGlvbiwgdGhlIHJlc3VsdHMgYXJlCisgICAgICogaW1wbGVtZW50YXRpb24gZGVmaW5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsZXZlbAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB0cmFuc2FjdGlvbiBpc29sYXRpb24gbGV2ZWwgdG8gdXNlIGZyb20gdGhlIGZvbGxvd2luZworICAgICAqICAgICAgICAgICAgbGlzdCBvZiBwb3NzaWJsZSB2YWx1ZXM6CisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rICNUUkFOU0FDVElPTl9SRUFEX0NPTU1JVFRFRH0KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGxpbmsgI1RSQU5TQUNUSU9OX1JFQURfVU5DT01NSVRURUR9CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rICNUUkFOU0FDVElPTl9SRVBFQVRBQkxFX1JFQUR9CisgICAgICogICAgICAgICAgICA8bGk+e0BsaW5rICNUUkFOU0FDVElPTl9TRVJJQUxJWkFCTEV9CisgICAgICogICAgICAgICAgICA8L3VsPgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhlIGRhdGFiYXNlIG9yIGlmIHRoZSB2YWx1ZSBvZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBsZXZlbH0gaXMgbm90IG9uZSBvZiB0aGUgZXhwZWN0ZWQgY29uc3RhbnQgdmFsdWVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRyYW5zYWN0aW9uSXNvbGF0aW9uKGludCBsZXZlbCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHtAY29kZSBUeXBlTWFwfSBmb3IgdGhpcyBjb25uZWN0aW9uLiBUaGUgaW5wdXQge0Bjb2RlIG1hcH0KKyAgICAgKiBzaG91bGQgY29udGFpbiBtYXBwaW5ncyBiZXR3ZWVuIGNvbXBsZXggSmF2YSBhbmQgU1FMIHR5cGVzLgorICAgICAqCisgICAgICogQHBhcmFtIG1hcAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB0eXBlIG1hcC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlIG9yIGlmIHtAY29kZQorICAgICAqICAgICAgICAgICAgIG1hcH0gaXMgbm90IGFuIGluc3RhbmNlIG9mIHtAbGluayBNYXB9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFR5cGVNYXAoTWFwPFN0cmluZywgQ2xhc3M8Pz4+IG1hcCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgZW1wdHkgQ2xvYi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiB0aGlzIGNvbm5lY3Rpb24gaXMgY2xvc2VkLCBvciB0aGVyZSdzIGEgcHJvYmxlbSBjcmVhdGluZyBhIG5ldyBjbG9iLgorICAgICAqLworICAgIHB1YmxpYyBDbG9iIGNyZWF0ZUNsb2IoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBlbXB0eSBCbG9iLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIHRoaXMgY29ubmVjdGlvbiBpcyBjbG9zZWQsIG9yIHRoZXJlJ3MgYSBwcm9ibGVtIGNyZWF0aW5nIGEgbmV3IGJsb2IuCisgICAgICovCisgICAgcHVibGljIEJsb2IgY3JlYXRlQmxvYigpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGVtcHR5IE5DbG9iLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIHRoaXMgY29ubmVjdGlvbiBpcyBjbG9zZWQsIG9yIHRoZXJlJ3MgYSBwcm9ibGVtIGNyZWF0aW5nIGEgbmV3IG5jbG9iLgorICAgICAqLworICAgIHB1YmxpYyBOQ2xvYiBjcmVhdGVOQ2xvYigpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGVtcHR5IFNRTFhNTC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiB0aGlzIGNvbm5lY3Rpb24gaXMgY2xvc2VkLCBvciB0aGVyZSdzIGEgcHJvYmxlbSBjcmVhdGluZyBhIG5ldyBYTUwuCisgICAgICovCisgICAgcHVibGljIFNRTFhNTCBjcmVhdGVTUUxYTUwoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgY29ubmVjdGlvbiBpcyBzdGlsbCBvcGVuIGFuZCB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEBwYXJhbSB0aW1lb3V0IG51bWJlciBvZiBzZWNvbmRzIHRvIHdhaXQgZm9yIGEgcmVzcG9uc2UgYmVmb3JlIGdpdmluZyB1cCBhbmQgcmV0dXJuaW5nIGZhbHNlLAorICAgICAqIDAgdG8gd2FpdCBmb3JldmVyCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYge0Bjb2RlIHRpbWVvdXQgPCAwfQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzVmFsaWQoaW50IHRpbWVvdXQpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjbGllbnQgaW5mbyBwcm9wZXJ0eSB7QGNvZGUgbmFtZX0gdG8ge0Bjb2RlIHZhbHVlfS4gQSB2YWx1ZSBvZiBudWxsIGNsZWFycyB0aGUKKyAgICAgKiBjbGllbnQgaW5mbyBwcm9wZXJ0eS4KKyAgICAgKiBAdGhyb3dzIFNRTENsaWVudEluZm9FeGNlcHRpb24gaWYgdGhpcyBjb25uZWN0aW9uIGlzIGNsb3NlZCwgb3IgdGhlcmUncyBhIHByb2JsZW0gc2V0dGluZworICAgICAqIHRoZSBwcm9wZXJ0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDbGllbnRJbmZvKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpIHRocm93cyBTUUxDbGllbnRJbmZvRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVwbGFjZXMgYWxsIGNsaWVudCBpbmZvIHByb3BlcnRpZXMgd2l0aCB0aGUgbmFtZS92YWx1ZSBwYWlycyBmcm9tIHtAY29kZSBwcm9wZXJ0aWVzfS4KKyAgICAgKiBBbGwgZXhpc3RpbmcgcHJvcGVydGllcyBhcmUgcmVtb3ZlZC4gSWYgYW4gZXhjZXB0aW9uIGlzIHRocm93biwgdGhlIHJlc3VsdGluZyBzdGF0ZSBvZgorICAgICAqIHRoaXMgY29ubmVjdGlvbidzIGNsaWVudCBpbmZvIHByb3BlcnRpZXMgaXMgdW5kZWZpbmVkLgorICAgICAqIEB0aHJvd3MgU1FMQ2xpZW50SW5mb0V4Y2VwdGlvbiBpZiB0aGlzIGNvbm5lY3Rpb24gaXMgY2xvc2VkLCBvciB0aGVyZSdzIGEgcHJvYmxlbSBzZXR0aW5nCisgICAgICogYSBwcm9wZXJ0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDbGllbnRJbmZvKFByb3BlcnRpZXMgcHJvcGVydGllcykgdGhyb3dzIFNRTENsaWVudEluZm9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbiBjbGllbnQgaW5mbyBwcm9wZXJ0eSwgb3IgbnVsbCBpZiB1bnNldC4KKyAgICAgKiBAdGhyb3dzIFNRTENsaWVudEluZm9FeGNlcHRpb24gaWYgdGhpcyBjb25uZWN0aW9uIGlzIGNsb3NlZCwgb3IgdGhlcmUncyBhIHByb2JsZW0gZ2V0dGluZworICAgICAqIHRoZSBwcm9wZXJ0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENsaWVudEluZm8oU3RyaW5nIG5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0BsaW5rIFByb3BlcnRpZXN9IG9iamVjdCBjb250YWluaW5nIGFsbCBjbGllbnQgaW5mbyBwcm9wZXJ0aWVzLgorICAgICAqIEB0aHJvd3MgU1FMQ2xpZW50SW5mb0V4Y2VwdGlvbiBpZiB0aGlzIGNvbm5lY3Rpb24gaXMgY2xvc2VkLCBvciB0aGVyZSdzIGEgcHJvYmxlbSBnZXR0aW5nCisgICAgICogYSBwcm9wZXJ0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvcGVydGllcyBnZXRDbGllbnRJbmZvKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0BsaW5rIEFycmF5fSBjb250YWluaW5nIHRoZSBnaXZlbiB7QGNvZGUgZWxlbWVudHN9LgorICAgICAqIEBwYXJhbSB0eXBlTmFtZSB0aGUgU1FMIG5hbWUgb2YgdGhlIHR5cGUgb2YgdGhlIGFycmF5IGVsZW1lbnRzCisgICAgICogQHRocm93cyBTUUxDbGllbnRJbmZvRXhjZXB0aW9uIGlmIHRoaXMgY29ubmVjdGlvbiBpcyBjbG9zZWQsIG9yIHRoZXJlJ3MgYSBwcm9ibGVtIGNyZWF0aW5nCisgICAgICogdGhlIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyBBcnJheSBjcmVhdGVBcnJheU9mKFN0cmluZyB0eXBlTmFtZSwgT2JqZWN0W10gZWxlbWVudHMpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAbGluayBTdHJ1Y3R9IGNvbnRhaW5pbmcgdGhlIGdpdmVuIHtAY29kZSBhdHRyaWJ1dGVzfS4KKyAgICAgKiBAcGFyYW0gdHlwZU5hbWUgdGhlIFNRTCBuYW1lIG9mIHRoZSB0eXBlIG9mIHRoZSBzdHJ1Y3QgYXR0cmlidXRlcworICAgICAqIEB0aHJvd3MgU1FMQ2xpZW50SW5mb0V4Y2VwdGlvbiBpZiB0aGlzIGNvbm5lY3Rpb24gaXMgY2xvc2VkLCBvciB0aGVyZSdzIGEgcHJvYmxlbSBjcmVhdGluZworICAgICAqIHRoZSBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RydWN0IGNyZWF0ZVN0cnVjdChTdHJpbmcgdHlwZU5hbWUsIE9iamVjdFtdIGF0dHJpYnV0ZXMpIHRocm93cyBTUUxFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvRGF0YVRydW5jYXRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9EYXRhVHJ1bmNhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIwMTEwMGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvRGF0YVRydW5jYXRpb24uamF2YQpAQCAtMCwwICsxLDE2MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zcWw7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworLyoqCisgKiBBbiBleGNlcHRpb24gd2hpY2ggaXMgdGhyb3duIHdoZW4gYSBKREJDIGRyaXZlciB1bmV4cGVjdGVkbHkgdHJ1bmNhdGVzIGEgZGF0YQorICogdmFsdWUgZWl0aGVyIHdoZW4gcmVhZGluZyAocmVzdWx0aW5nIGluIHdhcm5pbmcpLCBvciB3aGVuIHdyaXRpbmcgZGF0YQorICogKHJlc3VsdGluZyBpbiBhbiBlcnJvcikuIFRoZSB7QGNvZGUgU1FMU3RhdGV9IGVycm9yIGNvZGUgZm9yIHRydW5jYXRlZCBkYXRhCisgKiBpcyB7QGNvZGUgMDEwMDR9LgorICovCitwdWJsaWMgY2xhc3MgRGF0YVRydW5jYXRpb24gZXh0ZW5kcyBTUUxXYXJuaW5nIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDY0NjQyOTg5ODk1MDQwNTk0NzNMOworCisgICAgcHJpdmF0ZSBpbnQgaW5kZXggPSAwOworCisgICAgcHJpdmF0ZSBib29sZWFuIHBhcmFtZXRlciA9IGZhbHNlOworCisgICAgcHJpdmF0ZSBib29sZWFuIHJlYWQgPSBmYWxzZTsKKworICAgIHByaXZhdGUgaW50IGRhdGFTaXplID0gMDsKKworICAgIHByaXZhdGUgaW50IHRyYW5zZmVyU2l6ZSA9IDA7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEhFX1JFQVNPTiA9ICJEYXRhIHRydW5jYXRpb24iOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRIRV9TUUxTVEFURV9SRUFEID0gIjAxMDA0IjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUSEVfU1FMU1RBVEVfV1JJVEUgPSAiMjIwMDEiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRIRV9FUlJPUl9DT0RFID0gMDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIHtAY29kZSBEYXRhVHJ1bmNhdGlvbn0gb2JqZWN0LiBUaGUgcmVhc29uIGlzIHNldCB0byB7QGNvZGUKKyAgICAgKiAiRGF0YSB0cnVuY2F0aW9uIn0sIHRoZSB7QGNvZGUgRXJyb3JDb2RlfSBpcyBzZXQgdG8gdGhlIHtAY29kZQorICAgICAqIFNRTEV4Y2VwdGlvbn0gZGVmYXVsdCB2YWx1ZSwgYW5kIHRoZSBvdGhlciBmaWVsZHMgYXJlIHNldCB0byB0aGUgdmFsdWVzCisgICAgICogc3VwcGxpZWQgYXMgYXJndW1lbnRzLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgSW5kZXggdmFsdWUgb2YgdGhlIGNvbHVtbiB2YWx1ZSBvciBwYXJhbWV0ZXIgdGhhdCB3YXMKKyAgICAgKiAgICAgICAgICAgIHRydW5jYXRlZC4KKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gaWYgaXQgd2FzIGEgcGFyYW1ldGVyIHZhbHVlIHRoYXQgd2FzIHRydW5jYXRlZCwKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEBwYXJhbSByZWFkCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHRydW5jYXRpb24gb2NjdXJyZWQgb24gYSByZWFkIG9wZXJhdGlvbiwKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEBwYXJhbSBkYXRhU2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIG9yaWdpbmFsIHNpemUgb2YgdGhlIHRydW5jYXRlZCBkYXRhLgorICAgICAqIEBwYXJhbSB0cmFuc2ZlclNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaXplIG9mIHRoZSBkYXRhIGFmdGVyIHRydW5jYXRpb24uCisgICAgICovCisgICAgcHVibGljIERhdGFUcnVuY2F0aW9uKGludCBpbmRleCwgYm9vbGVhbiBwYXJhbWV0ZXIsIGJvb2xlYW4gcmVhZCwKKyAgICAgICAgICAgIGludCBkYXRhU2l6ZSwgaW50IHRyYW5zZmVyU2l6ZSkgeworICAgICAgICBzdXBlcihUSEVfUkVBU09OLCBUSEVfU1FMU1RBVEVfUkVBRCwgVEhFX0VSUk9SX0NPREUpOworICAgICAgICB0aGlzLmluZGV4ID0gaW5kZXg7CisgICAgICAgIHRoaXMucGFyYW1ldGVyID0gcGFyYW1ldGVyOworICAgICAgICB0aGlzLnJlYWQgPSByZWFkOworICAgICAgICB0aGlzLmRhdGFTaXplID0gZGF0YVNpemU7CisgICAgICAgIHRoaXMudHJhbnNmZXJTaXplID0gdHJhbnNmZXJTaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBEYXRhVHJ1bmNhdGlvbi4gVGhlIFJlYXNvbiBpcyBzZXQgdG8gIkRhdGEgdHJ1bmNhdGlvbiIsIHRoZQorICAgICAqIEVycm9yQ29kZSBpcyBzZXQgdG8gdGhlIFNRTEV4Y2VwdGlvbiBkZWZhdWx0IHZhbHVlIGFuZCBvdGhlciBmaWVsZHMgYXJlCisgICAgICogc2V0IHRvIHRoZSB2YWx1ZXMgc3VwcGxpZWQgb24gdGhpcyBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBJbmRleCB2YWx1ZSBvZiB0aGUgY29sdW1uIHZhbHVlIG9yIHBhcmFtZXRlciB0aGF0IHdhcworICAgICAqICAgICAgICAgICAgdHJ1bmNhdGVkCisgICAgICogQHBhcmFtIHBhcmFtZXRlcgorICAgICAqICAgICAgICAgICAgdHJ1ZSBpZiBpdCB3YXMgYSBQYXJhbWV0ZXIgdmFsdWUgdGhhdCB3YXMgdHJ1bmNhdGVkLCBmYWxzZQorICAgICAqICAgICAgICAgICAgb3RoZXJ3aXNlCisgICAgICogQHBhcmFtIHJlYWQKKyAgICAgKiAgICAgICAgICAgIHRydWUgaWYgdGhlIHRydW5jYXRpb24gb2NjdXJyZWQgb24gYSByZWFkIG9wZXJhdGlvbiwgZmFsc2UKKyAgICAgKiAgICAgICAgICAgIG90aGVyd2lzZQorICAgICAqIEBwYXJhbSBkYXRhU2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIG9yaWdpbmFsIHNpemUgb2YgdGhlIHRydW5jYXRlZCBkYXRhCisgICAgICogQHBhcmFtIHRyYW5zZmVyU2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIHNpemUgb2YgdGhlIGRhdGEgYWZ0ZXIgdHJ1bmNhdGlvbgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIHJvb3QgcmVhc29uIGZvciB0aGlzIERhdGFUcnVuY2F0aW9uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIERhdGFUcnVuY2F0aW9uKGludCBpbmRleCwgYm9vbGVhbiBwYXJhbWV0ZXIsIGJvb2xlYW4gcmVhZCwKKyAgICAgICAgICAgIGludCBkYXRhU2l6ZSwgaW50IHRyYW5zZmVyU2l6ZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKFRIRV9SRUFTT04sIHJlYWQgPyBUSEVfU1FMU1RBVEVfUkVBRCA6IFRIRV9TUUxTVEFURV9XUklURSwKKyAgICAgICAgICAgICAgICBUSEVfRVJST1JfQ09ERSwgY2F1c2UpOworICAgICAgICB0aGlzLmluZGV4ID0gaW5kZXg7CisgICAgICAgIHRoaXMucGFyYW1ldGVyID0gcGFyYW1ldGVyOworICAgICAgICB0aGlzLnJlYWQgPSByZWFkOworICAgICAgICB0aGlzLmRhdGFTaXplID0gZGF0YVNpemU7CisgICAgICAgIHRoaXMudHJhbnNmZXJTaXplID0gdHJhbnNmZXJTaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBieXRlcyBvZiBkYXRhIHRoYXQgc2hvdWxkIGhhdmUgYmVlbiByZWFkL3dyaXR0ZW4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBzaG91bGQgaGF2ZSBiZWVuIHJlYWQgb3Igd3JpdHRlbi4gVGhlCisgICAgICogICAgICAgICB2YWx1ZSBpcyBzZXQgdG8ge0Bjb2RlIC0xfSBpZiB0aGUgc2l6ZSBpcyB1bmtub3duLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RGF0YVNpemUoKSB7CisgICAgICAgIHJldHVybiBkYXRhU2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBpbmRleCBvZiB0aGUgY29sdW1uIG9yIG9mIHRoZSBwYXJhbWV0ZXIgdGhhdCB3YXMgdHJ1bmNhdGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaW5kZXggbnVtYmVyIG9mIHRoZSBjb2x1bW4gb3Igb2YgdGhlIHBhcmFtZXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEluZGV4KCkgeworICAgICAgICByZXR1cm4gaW5kZXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB3aGV0aGVyIHRoZSB2YWx1ZSB0cnVuY2F0ZWQgd2FzIGEgcGFyYW1ldGVyIHZhbHVlIG9yIGEgY29sdW1uIHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHZhbHVlIHRydW5jYXRlZCB3YXMgYSBwYXJhbWV0ZXIgdmFsdWUsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IGlmIGl0IHdhcyBhIGNvbHVtbiB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRQYXJhbWV0ZXIoKSB7CisgICAgICAgIHJldHVybiBwYXJhbWV0ZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB3aGV0aGVyIHRoZSB2YWx1ZSB3YXMgdHJ1bmNhdGVkIG9uIGEgcmVhZCBvcGVyYXRpb24gb3IgYSB3cml0ZQorICAgICAqIG9wZXJhdGlvbgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHZhbHVlIHdhcyB0cnVuY2F0ZWQgb24gYSByZWFkIG9wZXJhdGlvbiwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldFJlYWQoKSB7CisgICAgICAgIHJldHVybiByZWFkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBieXRlcyBvZiBkYXRhIHRoYXQgd2FzIGFjdHVhbGx5IHJlYWQgb3Igd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSByZWFkL3dyaXR0ZW4uIFRoZSB2YWx1ZSBtYXkgYmUgc2V0CisgICAgICogICAgICAgICB0byB7QGNvZGUgLTF9IGlmIHRoZSBzaXplIGlzIHVua25vd24uCisgICAgICovCisgICAgcHVibGljIGludCBnZXRUcmFuc2ZlclNpemUoKSB7CisgICAgICAgIHJldHVybiB0cmFuc2ZlclNpemU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL0RhdGFiYXNlTWV0YURhdGEuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9EYXRhYmFzZU1ldGFEYXRhLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGRiM2JmZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9EYXRhYmFzZU1ldGFEYXRhLmphdmEKQEAgLTAsMCArMSwzMjM3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworLyoqCisgKiBBbiBpbnRlcmZhY2Ugd2hpY2ggcHJvdmlkZXMgY29tcHJlaGVuc2l2ZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZGF0YWJhc2UKKyAqIG1hbmFnZW1lbnQgc3lzdGVtIGFuZCBpdHMgc3VwcG9ydGVkIGZlYXR1cmVzLgorICogPHA+CisgKiBUaGlzIGludGVyZmFjZSBpcyBpbXBsZW1lbnRlZCBieSBKREJDIGRyaXZlciB2ZW5kb3JzIGluIG9yZGVyIHRvIHByb3ZpZGUKKyAqIGluZm9ybWF0aW9uIGFib3V0IHRoZSB1bmRlcmx5aW5nIGRhdGFiYXNlIGNhcGFiaWxpdGllcyBpbiBhc3NvY2lhdGlvbiB3aXRoCisgKiB0aGUgSkRCQyBkcml2ZXIuCisgKiA8cD4KKyAqIFNvbWUgb2YgdGhlIG1ldGhvZHMgaW4gdGhpcyBpbnRlcmZhY2UgdGFrZSBzdHJpbmcgcGFyYW1ldGVycyB3aGljaCBhcmUKKyAqIHBhdHRlcm5zLiBXaXRoaW4gdGhlc2Ugc3RyaW5nIHBhdHRlcm5zLCB7QGNvZGUgJyUnfSBhbmQge0Bjb2RlICdfJ30KKyAqIGNoYXJhY3RlcnMgaGF2ZSBzcGVjaWFsIG1lYW5pbmdzLiB7QGNvZGUgJyUnfSBtZWFucworICogIm1hdGNoIGFueSBzdWJzdHJpbmcgb2YgMCBvciBtb3JlIGNoYXJhY3RlcnMiLiB7QGNvZGUgJ18nfSBtZWFucworICogIm1hdGNoIGFueSBjaGFyYWN0ZXIiLiBPbmx5IG1ldGFkYXRhIGVudHJpZXMgdGhhdCBtYXRjaCB0aGUgcGF0dGVybiBhcmUKKyAqIHJldHVybmVkLiBJZiBzdWNoIGEgc2VhcmNoIHBhdHRlcm4gc3RyaW5nIGlzIHNldCB0byB7QGNvZGUgbnVsbH0sIHRoYXQKKyAqIGFyZ3VtZW50J3MgY3JpdGVyaWEgYXJlIGRyb3BwZWQgZnJvbSB0aGUgc2VhcmNoLgorICovCitwdWJsaWMgaW50ZXJmYWNlIERhdGFiYXNlTWV0YURhdGEgZXh0ZW5kcyBXcmFwcGVyIHsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IGl0IG1heSBub3QgYmUgcGVybWl0dGVkIHRvIHN0b3JlIHtAY29kZSBOVUxMfSB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBhdHRyaWJ1dGVOb051bGxzID0gMDsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IHtAY29kZSBOVUxMfSB2YWx1ZXMgYXJlIGRlZmluaXRlbHkgcGVybWl0dGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgYXR0cmlidXRlTnVsbGFibGUgPSAxOworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgd2hldGhlciB7QGNvZGUgTlVMTH0gdmFsdWVzIGFyZSBwZXJtaXR0ZWQgaXMgdW5rbm93bi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGF0dHJpYnV0ZU51bGxhYmxlVW5rbm93biA9IDI7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhlIGJlc3Qgcm93IGlkZW50aWZpZXIgaXMgPGVtPk5PVDwvZW0+IGEgcHNldWRvIGNvbHVtbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBiZXN0Um93Tm90UHNldWRvID0gMTsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IHRoZSBiZXN0IHJvdyBpZGVudGlmaWVyIGlzIGEgcHNldWRvIGNvbHVtbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBiZXN0Um93UHNldWRvID0gMjsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IHRoZSByZW1haW5kZXIgb2YgdGhlIGN1cnJlbnQgc2Vzc2lvbiBpcyB1c2VkIGFzIHRoZSBzY29wZSBmb3IKKyAgICAgKiB0aGUgYmVzdCByb3cgaWRlbnRpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBiZXN0Um93U2Vzc2lvbiA9IDI7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCBiZXN0IHJvdyBpZGVudGlmaWVyIHNjb3BlIGxhc3RzIG9ubHkgd2hpbGUgdGhlIHJvdyBpcyBiZWluZworICAgICAqIHVzZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgYmVzdFJvd1RlbXBvcmFyeSA9IDA7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0aGUgcmVtYWluZGVyIG9mIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uIGlzIHVzZWQgYXMgdGhlIHNjb3BlCisgICAgICogZm9yIHRoZSBiZXN0IHJvdyBpZGVudGlmaWVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGJlc3RSb3dUcmFuc2FjdGlvbiA9IDE7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0aGUgYmVzdCByb3cgaWRlbnRpZmllciBtYXkgb3IgbWF5IG5vdCBiZSBhIHBzZXVkbyBjb2x1bW4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgYmVzdFJvd1Vua25vd24gPSAwOworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgdGhlIGNvbHVtbiBtdXN0IG5vdCBhbGxvdyB7QGNvZGUgTlVMTH0gdmFsdWVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGNvbHVtbk5vTnVsbHMgPSAwOworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgdGhlIGNvbHVtbiBkZWZpbml0ZWx5IGFsbG93cyB7QGNvZGUgTlVMTH0gdmFsdWVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGNvbHVtbk51bGxhYmxlID0gMTsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IGl0IGlzIHVua25vd24gd2hldGhlciB0aGUgY29sdW1ucyBtYXkgYmUgbnVsbGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGNvbHVtbk51bGxhYmxlVW5rbm93biA9IDI7CisKKyAgICAvKioKKyAgICAgKiBGb3IgdGhlIGNvbHVtbiB7QGNvZGUgVVBEQVRFX1JVTEV9LCBzdGF0ZXMgdGhhdCB3aGVuIHRoZSBwcmltYXJ5IGtleSBpcworICAgICAqIHVwZGF0ZWQsIHRoZSBmb3JlaWduIGtleSAoaW1wb3J0ZWQga2V5KSBpcyBjaGFuZ2VkIGFjY29yZGluZ2x5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGltcG9ydGVkS2V5Q2FzY2FkZSA9IDA7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0aGUgZXZhbHVhdGlvbiBvZiBmb3JlaWduIGtleSBjb25zdHJhaW50cyBpcyBkZWZlcnJlZCAoZGVsYXllZAorICAgICAqIHVudGlsIGNvbW1pdCkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaW1wb3J0ZWRLZXlJbml0aWFsbHlEZWZlcnJlZCA9IDU7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0aGUgZXZhbHVhdGlvbiBvZiBmb3JlaWduIGtleSBjb25zdHJhaW50IGlzIHtAY29kZSBJTU1FRElBVEV9CisgICAgICogLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGltcG9ydGVkS2V5SW5pdGlhbGx5SW1tZWRpYXRlID0gNjsKKworICAgIC8qKgorICAgICAqIEZvciB0aGUgY29sdW1ucyB7QGNvZGUgVVBEQVRFX1JVTEV9IGFuZCB7QGNvZGUgREVMRVRFX1JVTEV9LCBzdGF0ZXMgdGhhdAorICAgICAqIGlmIHRoZSBwcmltYXJ5IGtleSBoYXMgYmVlbiBpbXBvcnRlZCwgaXQgY2Fubm90IGJlIHVwZGF0ZWQgb3IgZGVsZXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpbXBvcnRlZEtleU5vQWN0aW9uID0gMzsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IHRoZSBldmFsdWF0aW9uIG9mIGZvcmVpZ24ga2V5IGNvbnN0cmFpbnQgbXVzdCBub3QgYmUge0Bjb2RlCisgICAgICogREVGRVJSRUR9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGltcG9ydGVkS2V5Tm90RGVmZXJyYWJsZSA9IDc7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCBhIHByaW1hcnkga2V5IG11c3Qgbm90IGJlIHVwZGF0ZWQgd2hlbiBpbXBvcnRlZCBhcyBhIGZvcmVpZ24KKyAgICAgKiBrZXkgYnkgc29tZSBvdGhlciB0YWJsZS4gVXNlZCBmb3IgdGhlIGNvbHVtbiB7QGNvZGUgVVBEQVRFX1JVTEV9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGltcG9ydGVkS2V5UmVzdHJpY3QgPSAxOworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgd2hlbiB0aGUgcHJpbWFyeSBrZXkgaXMgbW9kaWZpZWQgKHVwZGF0ZWQgb3IgZGVsZXRlZCkgdGhlCisgICAgICogZm9yZWlnbiAoaW1wb3J0ZWQpIGtleSBpcyBjaGFuZ2VkIHRvIGl0cyBkZWZhdWx0IHZhbHVlLiBBcHBsaWVzIHRvIHRoZQorICAgICAqIHtAY29kZSBVUERBVEVfUlVMRX0gYW5kIHtAY29kZSBERUxFVEVfUlVMRX0gY29sdW1ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpbXBvcnRlZEtleVNldERlZmF1bHQgPSA0OworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgd2hlbiB0aGUgcHJpbWFyeSBrZXkgaXMgbW9kaWZpZWQgKHVwZGF0ZWQgb3IgZGVsZXRlZCkgdGhlCisgICAgICogZm9yZWlnbiAoaW1wb3J0ZWQpIGtleSBpcyBjaGFuZ2VkIHRvIHtAY29kZSBOVUxMfS4gQXBwbGllcyB0byB0aGUge0Bjb2RlCisgICAgICogVVBEQVRFX1JVTEV9IGFuZCB7QGNvZGUgREVMRVRFX1JVTEV9IGNvbHVtbnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaW1wb3J0ZWRLZXlTZXROdWxsID0gMjsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IHRoZSBjb2x1bW4gc3RvcmVzIHtAY29kZSBJTn0gdHlwZSBwYXJhbWV0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHByb2NlZHVyZUNvbHVtbkluID0gMTsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IHRoaXMgY29sdW1uIHN0b3JlcyB7QGNvZGUgSU5PVVR9IHR5cGUgcGFyYW1ldGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBwcm9jZWR1cmVDb2x1bW5Jbk91dCA9IDI7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0aGlzIGNvbHVtbiBzdG9yZXMge0Bjb2RlIE9VVH0gdHlwZSBwYXJhbWV0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHByb2NlZHVyZUNvbHVtbk91dCA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0aGUgY29sdW1uIHN0b3JlcyByZXN1bHRzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHByb2NlZHVyZUNvbHVtblJlc3VsdCA9IDM7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0aGUgY29sdW1uIHN0b3JlcyByZXR1cm4gdmFsdWVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHByb2NlZHVyZUNvbHVtblJldHVybiA9IDU7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0eXBlIG9mIHRoZSBjb2x1bW4gaXMgdW5rbm93bi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBwcm9jZWR1cmVDb2x1bW5Vbmtub3duID0gMDsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IHtAY29kZSBOVUxMfSB2YWx1ZXMgYXJlIG5vdCBwZXJtaXR0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgcHJvY2VkdXJlTm9OdWxscyA9IDA7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0aGUgcHJvY2VkdXJlIGRvZXMgbm90IHJldHVybiBhIHJlc3VsdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBwcm9jZWR1cmVOb1Jlc3VsdCA9IDE7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB7QGNvZGUgTlVMTH0gdmFsdWVzIGFyZSBwZXJtaXR0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgcHJvY2VkdXJlTnVsbGFibGUgPSAxOworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgaXQgaXMgdW5rbm93biB3aGV0aGVyIHtAY29kZSBOVUxMfSB2YWx1ZXMgYXJlIHBlcm1pdHRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBwcm9jZWR1cmVOdWxsYWJsZVVua25vd24gPSAyOworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgaXQgaXMgdW5rbm93biB3aGV0aGVyIG9yIG5vdCB0aGUgcHJvY2VkdXJlIHJldHVybnMgYSByZXN1bHQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgcHJvY2VkdXJlUmVzdWx0VW5rbm93biA9IDA7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0aGUgcHJvY2VkdXJlIHJldHVybnMgYSByZXN1bHQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgcHJvY2VkdXJlUmV0dXJuc1Jlc3VsdCA9IDI7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0aGUgdmFsdWUgaXMgYW4gU1FMOTkge0Bjb2RlIFNRTFNUQVRFfSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBzcWxTdGF0ZVNRTDk5ID0gMjsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IHRoZSB2YWx1ZSBpcyBhbiBTUUwge0Bjb2RlIENMSSBTUUxTVEFURX0gdmFsdWUgYXMgZGVmaW5lZCBieQorICAgICAqIHRoZSBYL09wZW4gc3RhbmRhcmQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc3FsU3RhdGVYT3BlbiA9IDE7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0aGlzIHRhYmxlIGluZGV4IGlzIGEgY2x1c3RlcmVkIGluZGV4LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgdGFibGVJbmRleENsdXN0ZXJlZCA9IDE7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0aGlzIHRhYmxlIGluZGV4IGlzIGEgaGFzaGVkIGluZGV4LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgdGFibGVJbmRleEhhc2hlZCA9IDI7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhpcyB0YWJsZSdzIGluZGV4IGlzIG5laXRoZXIgYSBjbHVzdGVyZWQgaW5kZXgsIG5vdCBhIGhhc2hlZAorICAgICAqIGluZGV4LCBhbmQgbm90IGEgdGFibGUgc3RhdGlzdGljcyBpbmRleDsgaS5lLiBpdCBpcyBzb21ldGhpbmcgZWxzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IHRhYmxlSW5kZXhPdGhlciA9IDM7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhpcyBjb2x1bW4gaGFzIHRoZSB0YWJsZSdzIHN0YXRpc3RpY3MsIGFuZCB0aGF0IGl0IGlzIHJldHVybmVkIGluCisgICAgICogY29uanVuY3Rpb24gd2l0aCB0aGUgdGFibGUncyBpbmRleCBkZXNjcmlwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IHRhYmxlSW5kZXhTdGF0aXN0aWMgPSAwOworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgYSB7QGNvZGUgTlVMTH0gdmFsdWUgaXMgPGVtPk5PVDwvZW0+IHBlcm1pdHRlZCBmb3IKKyAgICAgKiB0aGlzIGRhdGEgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCB0eXBlTm9OdWxscyA9IDA7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCBhIHtAY29kZSBOVUxMfSB2YWx1ZSBpcyBwZXJtaXR0ZWQgZm9yIHRoaXMgZGF0YSB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHR5cGVOdWxsYWJsZSA9IDE7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCBpdCBpcyB1bmtub3duIGlmIGEge0Bjb2RlIE5VTEx9IHZhbHVlIGlzIHBlcm1pdHRlZCBmb3IKKyAgICAgKiB0aGlzIGRhdGEgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCB0eXBlTnVsbGFibGVVbmtub3duID0gMjsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IHRoaXMgY29sdW1uIHNoYWxsIG5vdCBiZSB1c2VkIGZvciB7QGNvZGUgV0hFUkV9IHN0YXRlbWVudHMKKyAgICAgKiB3aXRoIGEge0Bjb2RlIExJS0V9IGNsYXVzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCB0eXBlUHJlZEJhc2ljID0gMjsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IHRoaXMgY29sdW1uIGNhbiBvbmx5IGJlIHVzZWQgaW4gYSB7QGNvZGUgV0hFUkUuLi5MSUtFfQorICAgICAqIHN0YXRlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCB0eXBlUHJlZENoYXIgPSAxOworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgdGhpcyBjb2x1bW4gZG9lcyBub3Qgc3VwcG9ydCBzZWFyY2hlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCB0eXBlUHJlZE5vbmUgPSAwOworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgdGhlIGNvbHVtbiBpcyBzZWFyY2hhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHR5cGVTZWFyY2hhYmxlID0gMzsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IHRoZSB2ZXJzaW9uIGNvbHVtbiBpcyBrbm93biB0byBiZSBub3QgYSBwc2V1ZG8gY29sdW1uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHZlcnNpb25Db2x1bW5Ob3RQc2V1ZG8gPSAxOworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgdGhpcyB2ZXJzaW9uIGNvbHVtbiBpcyBrbm93biB0byBiZSBhIHBzZXVkbyBjb2x1bW4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgdmVyc2lvbkNvbHVtblBzZXVkbyA9IDI7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0aGUgdmVyc2lvbiBjb2x1bW4gbWF5IGJlIGEgcHNldWRvIGNvbHVtbiBvciBub3QuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgdmVyc2lvbkNvbHVtblVua25vd24gPSAwOworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgdGhlIG1ldGhvZCBEYXRhYmFzZU1ldGFEYXRhLmdldFNRTFN0YXRlVHlwZSBtYXkgcmV0dXJucyBhbgorICAgICAqIFNRTFNUQVRFIHZhbHVlIG9yIG5vdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBzcWxTdGF0ZVNRTCA9IDI7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0aGUgcGFyYW1ldGVyIG9yIGNvbHVtbiBpcyBhbiBJTiBwYXJhbWV0ZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBmdW5jdGlvbkNvbHVtbkluID0gMTsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IHRoZSBwYXJhbWV0ZXIgb3IgY29sdW1uIGlzIGFuIElOT1VUIHBhcmFtZXRlcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGZ1bmN0aW9uQ29sdW1uSW5PdXQgPSAyOworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgdGhlIHBhcmFtZXRlciBvciBjb2x1bW4gaXMgYW4gT1VUIHBhcmFtZXRlcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGZ1bmN0aW9uQ29sdW1uT3V0ID0gMzsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IHRoZSBwYXJhbWV0ZXIgb3IgY29sdW1uIGlzIGEgcmV0dXJuIHZhbHVlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgZnVuY3Rpb25SZXR1cm4gPSA0OworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgdGhlIHBhcmFtZXRlciBvZiBmdW5jdGlvbiBpcyB1bmtub3duCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgZnVuY3Rpb25Db2x1bW5Vbmtub3duID0gMDsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IHRoZSBwYXJhbWV0ZXIgb3IgY29sdW1uIGlzIGEgY29sdW1uIGluIGEgcmVzdWx0IHNldAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGZ1bmN0aW9uQ29sdW1uUmVzdWx0ID0gNTsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IE5VTEwgdmFsdWVzIGFyZSBub3QgYWxsb3dlZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGZ1bmN0aW9uTm9OdWxscyA9IDA7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCBOVUxMIHZhbHVlcyBhcmUgYWxsb3dlZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGZ1bmN0aW9uTnVsbGFibGUgPSAxOworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgd2hldGhlciBOVUxMIHZhbHVlcyBhcmUgYWxsb3dlZCBpcyB1bmtub3duCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgZnVuY3Rpb25OdWxsYWJsZVVua25vd24gPSAyOworCisgICAgLyoqCisgICAgICogU3RhdGVzIHRoYXQgaXQgaXMgbm90IGtub3duIHdoZXRoZXIgdGhlIGZ1bmN0aW9uIHJldHVybnMgYSByZXN1bHQgb3IgYQorICAgICAqIHRhYmxlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgZnVuY3Rpb25SZXN1bHRVbmtub3duID0gMDsKKworICAgIC8qKgorICAgICAqIFN0YXRlcyB0aGF0IHRoZSBmdW5jdGlvbiBkb2VzIG5vdCByZXR1cm4gYSB0YWJsZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGZ1bmN0aW9uTm9UYWJsZSA9IDE7CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhhdCB0aGUgZnVuY3Rpb24gcmV0dXJucyBhIHRhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGZ1bmN0aW9uUmV0dXJuc1RhYmxlID0gMjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciBhbGwgcHJvY2VkdXJlcyByZXR1cm5lZCBieSB7QGxpbmsgI2dldFByb2NlZHVyZXN9IGNhbiBiZQorICAgICAqIGNhbGxlZCBieSB0aGUgY3VycmVudCB1c2VyLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYWxsIHByb2NlZHVyZXMgY2FuIGJlIGNhbGxlZCBieSB0aGUgY3VycmVudCB1c2VyLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGFsbFByb2NlZHVyZXNBcmVDYWxsYWJsZSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgYWxsIHRoZSB0YWJsZXMgcmV0dXJuZWQgYnkge0Bjb2RlIGdldFRhYmxlc30gY2FuIGJlIHVzZWQKKyAgICAgKiBieSB0aGUgY3VycmVudCB1c2VyIGluIGEge0Bjb2RlIFNFTEVDVH0gc3RhdGVtZW50LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYWxsIHRoZSB0YWJsZXMgY2FuIGJlIHVzZWQse0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBhbGxUYWJsZXNBcmVTZWxlY3RhYmxlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciBhIGRhdGEgZGVmaW5pdGlvbiBzdGF0ZW1lbnQgaW4gYSB0cmFuc2FjdGlvbiBmb3JjZXMgYSB7QGNvZGUKKyAgICAgKiBjb21taXR9IG9mIHRoZSB0cmFuc2FjdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzdGF0ZW1lbnQgZm9yY2VzIGEgY29tbWl0LCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGRhdGFEZWZpbml0aW9uQ2F1c2VzVHJhbnNhY3Rpb25Db21taXQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBkYXRhYmFzZSBpZ25vcmVzIGRhdGEgZGVmaW5pdGlvbiBzdGF0ZW1lbnRzIHdpdGhpbiBhCisgICAgICogdHJhbnNhY3Rpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZGF0YWJhc2UgaWdub3JlcyBhIGRhdGEgZGVmaW5pdGlvbiBzdGF0ZW1lbnQsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZGF0YURlZmluaXRpb25JZ25vcmVkSW5UcmFuc2FjdGlvbnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIGEgdmlzaWJsZSByb3cgZGVsZXRlIGNhbiBiZSBkZXRlY3RlZCBieSBjYWxsaW5nCisgICAgICoge0BsaW5rIFJlc3VsdFNldCNyb3dEZWxldGVkfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUge0Bjb2RlIFJlc3VsdFNldH0gaW52b2x2ZWQ6IHtAY29kZQorICAgICAqICAgICAgICAgICAgUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZfSwge0Bjb2RlCisgICAgICogICAgICAgICAgICBSZXN1bHRTZXQuVFlQRV9TQ1JPTExfSU5TRU5TSVRJVkV9LCBvciB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkV9CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHZpc2libGUgcm93IGRlbGV0ZSBjYW4gYmUgZGV0ZWN0ZWQsIHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZGVsZXRlc0FyZURldGVjdGVkKGludCB0eXBlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSByZXR1cm4gdmFsdWUgb2Yge0Bjb2RlIGdldE1heFJvd1NpemV9IGluY2x1ZGVzIHRoZQorICAgICAqIFNRTCBkYXRhIHR5cGVzIHtAY29kZSBMT05HVkFSQ0hBUn0gYW5kIHtAY29kZSBMT05HVkFSQklOQVJZfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSByZXR1cm4gdmFsdWUgaW5jbHVkZXMge0Bjb2RlIExPTkdWQVJCSU5BUll9CisgICAgICogICAgICAgICBhbmQge0Bjb2RlIExPTkdWQVJDSEFSfSwgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGRvZXNNYXhSb3dTaXplSW5jbHVkZUJsb2JzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgUmVzdWx0U2V0fSBkZXNjcmliaW5nIGEgc3Vic2V0IG9mIHRoZSBhdHRyaWJ1dGVzIG9mIGEKKyAgICAgKiBzcGVjaWZpZWQgU1FMIFVzZXIgRGVmaW5lZCBUeXBlIChVRFQpIGZvciBhIHNwZWNpZmllZCBzY2hlbWEgYW5kIGNhdGFsb2cuCisgICAgICogVGhlIHN1YnNldCBpcyBkZXRlcm1pbmVkIGJ5IHJlc3RyaWN0aW5nIHRvIHRob3NlIGF0dHJpYnV0ZXMgd2hvc2UKKyAgICAgKiBuYW1lIG1hdGNoZXMgdGhlIHtAY29kZSBhdHRyaWJ1dGVOYW1lUGF0dGVybn0gYW5kIHdob3NlIHR5cGUgbmFtZQorICAgICAqIG1hdGNoZXMgdGhlIHtAY29kZSB0eXBlTmFtZVBhdHRlcm59LiBFYWNoIHJvdyBvZiB0aGUge0Bjb2RlIFJlc3VsdFNldH0KKyAgICAgKiBkZXNjcmliZXMgb25lIGF0dHJpYnV0ZSwgYW5kIHRoZSByb3dzIGFyZSBvcmRlcmVkIGJ5IHRoZSBjb2x1bW5zIHtAY29kZSBUWVBFX1NDSEVNfSwKKyAgICAgKiB7QGNvZGUgVFlQRV9OQU1FfSBhbmQge0Bjb2RlIE9SRElOQUxfUE9TSVRJT059LiBJbmhlcml0ZWQgYXR0cmlidXRlcworICAgICAqIGFyZSBub3QgaW5jbHVkZWQuCisgICAgICogPHA+CisgICAgICogVGhlIGNvbHVtbnMgb2YgdGhlIHJldHVybmVkIHtAY29kZSBSZXN1bHRTZXR9IG9iamVjdCBoYXZlIHRoZSBmb2xsb3dpbmcKKyAgICAgKiBuYW1lcyBhbmQgbWVhbmluZ3M6CisgICAgICogPG9sPgorICAgICAqIDxsaT57QGNvZGUgVFlQRV9DQVR9IC0gU3RyaW5nIC0gdGhlIHR5cGUgY2F0YWxvZyBuYW1lIChwb3NzaWJseSB7QGNvZGUKKyAgICAgKiBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgVFlQRV9TQ0hFTX0gLSBTdHJpbmcgLSB0aGUgdHlwZSBzY2hlbWEgbmFtZSAocG9zc2libHkge0Bjb2RlCisgICAgICogbnVsbH0pPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFRZUEVfTkFNRX0gLSBTdHJpbmcgLSB0aGUgdHlwZSBuYW1lPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIEFUVFJfTkFNRX0gLSBTdHJpbmcgLSB0aGUgYXR0cmlidXRlIG5hbWU8L2xpPgorICAgICAqIDxsaT57QGNvZGUgREFUQV9UWVBFfSAtIGludCAtIHRoZSBhdHRyaWJ1dGUgdHlwZSBhcyBkZWZpbmVkIGluIHtAY29kZQorICAgICAqIGphdmEuc3FsLlR5cGVzfTwvbGk+CisgICAgICogPGxpPntAY29kZSBBVFRSX1RZUEVfTkFNRX0gLSBTdHJpbmcgLSB0aGUgYXR0cmlidXRlIHR5cGUgbmFtZS4gVGhpcworICAgICAqIGRlcGVuZHMgb24gdGhlIGRhdGEgc291cmNlLiBGb3IgYSB7QGNvZGUgVURUfSB0aGUgbmFtZSBpcyBmdWxseQorICAgICAqIHF1YWxpZmllZC4gRm9yIGEge0Bjb2RlIFJFRn0gaXQgaXMgYm90aCBmdWxseSBxdWFsaWZpZWQgYW5kIHJlcHJlc2VudHMKKyAgICAgKiB0aGUgdGFyZ2V0IHR5cGUgb2YgdGhlIHJlZmVyZW5jZS48L2xpPgorICAgICAqIDxsaT57QGNvZGUgQVRUUl9TSVpFfSAtIGludCAtIHRoZSBjb2x1bW4gc2l6ZS4gV2hlbiByZWZlcnJpbmcgdG8gY2hhciBhbmQKKyAgICAgKiBkYXRlIHR5cGVzIHRoaXMgdmFsdWUgaXMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMuIFdoZW4gcmVmZXJyaW5nCisgICAgICogdG8gbnVtZXJpYyB0eXBlcyBpcyBpcyB0aGUgcHJlY2lzaW9uLjwvbGk+CisgICAgICogPGxpPntAY29kZSBERUNJTUFMX0RJR0lUU30gLSBpbnQgLSBob3cgbWFueSBmcmFjdGlvbmFsIGRpZ2l0cyBhcmUKKyAgICAgKiBzdXBwb3J0ZWQ8L2xpPgorICAgICAqIDxsaT57QGNvZGUgTlVNX1BSRUNfUkFESVh9IC0gaW50IC0gbnVtZXJpYyB2YWx1ZXMgcmFkaXg8L2xpPgorICAgICAqIDxsaT57QGNvZGUgTlVMTEFCTEV9IC0gaW50IC0gd2hldGhlciB7QGNvZGUgTlVMTH0gaXMgcGVybWl0dGVkOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+RGF0YWJhc2VNZXRhRGF0YS5hdHRyaWJ1dGVOb051bGxzIC0ge0Bjb2RlIE5VTEx9IHZhbHVlcyBub3QgcGVybWl0dGVkPC9saT4KKyAgICAgKiA8bGk+RGF0YWJhc2VNZXRhRGF0YS5hdHRyaWJ1dGVOdWxsYWJsZSAtIHtAY29kZSBOVUxMfSB2YWx1ZXMgZGVmaW5pdGVseQorICAgICAqIHBlcm1pdHRlZDwvbGk+CisgICAgICogPGxpPkRhdGFiYXNlTWV0YURhdGEuYXR0cmlidXRlTnVsbGFibGVVbmtub3duIC0gdW5rbm93bjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT57QGNvZGUgUkVNQVJLU30gLSBTdHJpbmcgLSBhIGNvbW1lbnQgZGVzY3JpYmluZyB0aGUgYXR0cmlidXRlCisgICAgICogKHBvc3NpYmx5IHtAY29kZSBudWxsfSk8L2xpPgorICAgICAqIDxsaT5BVFRSX0RFRiAtIFN0cmluZyAtIERlZmF1bHQgdmFsdWUgZm9yIHRoZSBhdHRyaWJ1dGUgKHBvc3NpYmx5IHtAY29kZQorICAgICAqIG51bGx9KTwvbGk+CisgICAgICogPGxpPntAY29kZSBTUUxfREFUQV9UWVBFfSAtIGludCAtIG5vdCB1c2VkPC9saT4KKyAgICAgKiA8bGk+U1FMX0RBVEVUSU1FX1NVQiAtIGludCAtIG5vdCB1c2VkPC9saT4KKyAgICAgKiA8bGk+Q0hBUl9PQ1RFVF9MRU5HVEggLSBpbnQgLSBmb3Ige0Bjb2RlIENIQVJ9IHR5cGVzLCB0aGUgbWF4IG51bWJlciBvZgorICAgICAqIGJ5dGVzIGluIHRoZSBjb2x1bW48L2xpPgorICAgICAqIDxsaT5PUkRJTkFMX1BPU0lUSU9OIC0gaW50IC0gVGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gaW4gdGhlIHRhYmxlICh3aGVyZQorICAgICAqIHRoZSBjb3VudCBzdGFydHMgZnJvbSAxLCBub3QgMCk8L2xpPgorICAgICAqIDxsaT5JU19OVUxMQUJMRSAtIFN0cmluZyAtIHtAY29kZSAiTk8ifSA9IHRoZSBjb2x1bW4gZG9lcyBub3QgYWxsb3cge0Bjb2RlCisgICAgICogTlVMTH1zLCB7QGNvZGUgIllFUyJ9ID0gdGhlIGNvbHVtbiBhbGxvd3Mge0Bjb2RlIE5VTEx9cywgIiIgPSBzdGF0dXMgdW5rbm93bjwvbGk+CisgICAgICogPGxpPntAY29kZSBTQ09QRV9DQVRBTE9HfSAtIFN0cmluZyAtIGlmIHRoZSB7QGNvZGUgREFUQV9UWVBFfSBpcyB7QGNvZGUgUkVGfSwKKyAgICAgKiB0aGlzIGdpdmVzIHRoZSBjYXRhbG9nIG9mIHRoZSB0YWJsZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBhdHRyaWJ1dGUncyBzY29wZS4KKyAgICAgKiBOVUxMIGlmIHRoZSB7QGNvZGUgREFUQV9UWVBFfSBpcyBub3QgUkVGLjwvbGk+CisgICAgICogPGxpPntAY29kZSBTQ09QRV9TQ0hFTUF9IC0gU3RyaW5nIC0gaWYgdGhlIHtAY29kZSBEQVRBX1RZUEV9IGlzIHtAY29kZSBSRUZ9LAorICAgICAqIHRoaXMgZ2l2ZXMgdGhlIHNjaGVtYSBvZiB0aGUgdGFibGUgY29ycmVzcG9uZGluZyB0byB0aGUgYXR0cmlidXRlJ3Mgc2NvcGUuCisgICAgICogTlVMTCBpZiB0aGUge0Bjb2RlIERBVEFfVFlQRX0gaXMgbm90IFJFRi48L2xpPgorICAgICAqIDxsaT57QGNvZGUgU0NPUEVfVEFCTEV9IC0gU3RyaW5nIC0gaWYgdGhlIHtAY29kZSBEQVRBX1RZUEV9IGlzIHtAY29kZSBSRUZ9LAorICAgICAqIHRoaXMgZ2l2ZXMgdGhlIG5hbWUgb2YgdGhlIHRhYmxlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGF0dHJpYnV0ZSdzIHNjb3BlLgorICAgICAqIE5VTEwgaWYgdGhlIHtAY29kZSBEQVRBX1RZUEV9IGlzIG5vdCBSRUYuPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFNPVVJDRV9EQVRBX1RZUEV9IC0gU3RyaW5nIC0gVGhlIHNvdXJjZSB0eXBlIGZvciBhIHVzZXIKKyAgICAgKiBnZW5lcmF0ZWQgUkVGIHR5cGUgb3IgZm9yIGEgRGlzdGluY3QgdHlwZS4gKHtAY29kZSBOVUxMfSBpZiB7QGNvZGUKKyAgICAgKiBEQVRBX1RZUEV9IGlzIG5vdCBESVNUSU5DVCBvciBhIHVzZXIgZ2VuZXJhdGVkIFJFRik8L2xpPgorICAgICAqIDwvb2w+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F0YWxvZworICAgICAqICAgICAgICAgICAgYSBjYXRhbG9nIG5hbWUuIHtAY29kZSBudWxsfSBpcyB1c2VkIHRvIGltcGx5IG5vIG5hcnJvd2luZyBvZgorICAgICAqICAgICAgICAgICAgdGhlIHNlYXJjaCBieSBjYXRhbG9nIG5hbWUuIE90aGVyd2lzZSwgdGhlIG5hbWUgbXVzdCBtYXRjaCBhCisgICAgICogICAgICAgICAgICBjYXRhbG9nIG5hbWUgaGVsZCBpbiB0aGUgZGF0YWJhc2UsIHdpdGggIiIgdXNlZCB0byByZXRyaWV2ZQorICAgICAqICAgICAgICAgICAgdGhvc2Ugd2l0aG91dCBhIGNhdGFsb2cgbmFtZS4KKyAgICAgKiBAcGFyYW0gc2NoZW1hUGF0dGVybgorICAgICAqICAgICAgICAgICAgYSBzY2hlbWEgbmFtZSBwYXR0ZXJuLiB7QGNvZGUgbnVsbH0gaXMgdXNlZCB0byBpbXBseSBubworICAgICAqICAgICAgICAgICAgbmFycm93aW5nIG9mIHRoZSBzZWFyY2ggYnkgYSBzY2hlbWEgbmFtZS4gT3RoZXJ3aXNlLCB0aGUgbmFtZQorICAgICAqICAgICAgICAgICAgbXVzdCBtYXRjaCBhIHNjaGVtYSBuYW1lIGluIHRoZSBkYXRhYmFzZSwgd2l0aCAiIiB1c2VkIHRvCisgICAgICogICAgICAgICAgICByZXRyaWV2ZSB0aG9zZSB3aXRob3V0IGEgc2NoZW1hIG5hbWUuCisgICAgICogQHBhcmFtIHR5cGVOYW1lUGF0dGVybgorICAgICAqICAgICAgICAgICAgYSB0eXBlIG5hbWUuIFRoaXMgcGF0dGVybiBtdXN0IG1hdGNoIHRoZSB0eXBlIG5hbWUgc3RvcmVkIGluCisgICAgICogICAgICAgICAgICB0aGUgZGF0YWJhc2UuCisgICAgICogQHBhcmFtIGF0dHJpYnV0ZU5hbWVQYXR0ZXJuCisgICAgICogICAgICAgICAgICBhbiBBdHRyaWJ1dGUgbmFtZS4gVGhpcyBwYXR0ZXJuIG11c3QgbWF0Y2ggdGhlIGF0dHJpYnV0ZSBuYW1lIGFzIHN0b3JlZCBpbgorICAgICAqICAgICAgICAgICAgdGhlIGRhdGFiYXNlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgUmVzdWx0U2V0fSwgd2hlcmUgZWFjaCByb3cgaXMgYW4gYXR0cmlidXRlIGRlc2NyaXB0aW9uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzdWx0U2V0IGdldEF0dHJpYnV0ZXMoU3RyaW5nIGNhdGFsb2csIFN0cmluZyBzY2hlbWFQYXR0ZXJuLAorICAgICAgICAgICAgU3RyaW5nIHR5cGVOYW1lUGF0dGVybiwgU3RyaW5nIGF0dHJpYnV0ZU5hbWVQYXR0ZXJuKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGEgdGFibGUncyBvcHRpbWFsIHNldCBvZiBjb2x1bW5zIHRoYXQgdW5pcXVlbHkKKyAgICAgKiBpZGVudGlmeSB0aGUgcm93cy4gVGhlIHJlc3VsdHMgYXJlIG9yZGVyZWQgYnkge0Bjb2RlIFNDT1BFfSAoc2VlIGJlbG93KS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcmVzdWx0cyBhcmUgcmV0dXJuZWQgYXMgYSB0YWJsZSwgd2l0aCBvbmUgZW50cnkgZm9yIGVhY2ggY29sdW1uLCBhcworICAgICAqIGZvbGxvd3M6CisgICAgICogPG9sPgorICAgICAqIDxsaT57QGNvZGUgU0NPUEV9IC0gc2hvcnQgLSB0aGUge0Bjb2RlIFNDT1BFfSBvZiB0aGUgcmVzdWx0LCBhcyBmb2xsb3dzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuYmVzdFJvd1RlbXBvcmFyeX0gLSB0aGUgcmVzdWx0IGlzIHZlcnkgdGVtcG9yYXJ5LAorICAgICAqIG9ubHkgdmFsaWQgd2hpbGUgb24gdGhlIGN1cnJlbnQgcm93PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuYmVzdFJvd1RyYW5zYWN0aW9ufSAtIHRoZSByZXN1bHQgaXMgZ29vZCBmb3IgcmVtYWluZGVyIG9mCisgICAgICogY3VycmVudCB0cmFuc2FjdGlvbjwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmJlc3RSb3dTZXNzaW9ufSAtIHRoZSByZXN1bHQgaXMgZ29vZCBmb3IgcmVtYWluZGVyIG9mCisgICAgICogZGF0YWJhc2Ugc2Vzc2lvbjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT57QGNvZGUgQ09MVU1OX05BTUV9IC0gU3RyaW5nIC0gdGhlIGNvbHVtbiBuYW1lPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERBVEFfVFlQRX0gLSBpbnQgLSB0aGUgVHlwZSBvZiB0aGUgZGF0YSwgYXMgZGVmaW5lZCBpbiB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5UeXBlc308L2xpPgorICAgICAqIDxsaT57QGNvZGUgVFlQRV9OQU1FfSAtIFN0cmluZyAtIHRoZSBOYW1lIG9mIHRoZSB0eXBlIC0gZGF0YWJhc2UgZGVwZW5kZW50LgorICAgICAqIEZvciBVRFQgdHlwZXMgdGhlIG5hbWUgaXMgZnVsbHkgcXVhbGlmaWVkPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIENPTFVNTl9TSVpFfSAtIGludCAtIHRoZSBwcmVjaXNpb24gb2YgdGhlIGRhdGEgaW4gdGhlIGNvbHVtbjwvbGk+CisgICAgICogPGxpPntAY29kZSBCVUZGRVJfTEVOR1RIfSAtIGludCAtIG5vdCB1c2VkPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERFQ0lNQUxfRElHSVRTfSAtIHNob3J0IC0gbnVtYmVyIG9mIGZyYWN0aW9uYWwgZGlnaXRzPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFBTRVVET19DT0xVTU59IC0gc2hvcnQgLSB3aGV0aGVyIHRoaXMgaXMgYSBwc2V1ZG8gY29sdW1uIChlLmcuCisgICAgICogYW4gT3JhY2xlIHtAY29kZSBST1dJRH0pOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuYmVzdFJvd1Vua25vd259IC0gaXQgaXMgbm90IGtub3duIHdoZXRoZXIgdGhpcyBpcworICAgICAqIGEgcHNldWRvIGNvbHVtbjwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmJlc3RSb3dOb3RQc2V1ZG99IC0gdGhlIGNvbHVtbiBpcyBub3QgcHNldWRvPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuYmVzdFJvd1BzZXVkb30gLSB0aGUgY29sdW1uIGlzIGEgcHNldWRvIGNvbHVtbjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiA8L2xpPgorICAgICAqIDwvb2w+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F0YWxvZworICAgICAqICAgICAgICAgICAgYSBjYXRhbG9nIG5hbWUuIHtAY29kZSBudWxsfSBpcyB1c2VkIHRvIGltcGx5IG5vIG5hcnJvd2luZyBvZgorICAgICAqICAgICAgICAgICAgdGhlIHNlYXJjaCBieSBjYXRhbG9nIG5hbWUuIE90aGVyd2lzZSwgdGhlIG5hbWUgbXVzdCBtYXRjaCBhCisgICAgICogICAgICAgICAgICBjYXRhbG9nIG5hbWUgaGVsZCBpbiB0aGUgZGF0YWJhc2UsIHdpdGggIiIgdXNlZCB0byByZXRyaWV2ZQorICAgICAqICAgICAgICAgICAgdGhvc2Ugd2l0aG91dCBhIGNhdGFsb2cgbmFtZS4KKyAgICAgKiBAcGFyYW0gc2NoZW1hCisgICAgICogICAgICAgICAgICBhIHNjaGVtYSBuYW1lIHBhdHRlcm4uIHtAY29kZSBudWxsfSBpcyB1c2VkIHRvIGltcGx5IG5vCisgICAgICogICAgICAgICAgICBuYXJyb3dpbmcgb2YgdGhlIHNlYXJjaCBieSBzY2hlbWEgbmFtZS4gT3RoZXJ3aXNlLCB0aGUgbmFtZQorICAgICAqICAgICAgICAgICAgbXVzdCBtYXRjaCBhIHNjaGVtYSBuYW1lIGluIHRoZSBkYXRhYmFzZSwgd2l0aCAiIiB1c2VkIHRvCisgICAgICogICAgICAgICAgICByZXRyaWV2ZSB0aG9zZSB3aXRob3V0IGEgc2NoZW1hIG5hbWUuCisgICAgICogQHBhcmFtIHRhYmxlCisgICAgICogICAgICAgICAgICB0aGUgdGFibGUgbmFtZS4gVGhpcyBtdXN0IG1hdGNoIHRoZSBuYW1lIG9mIHRoZSB0YWJsZSBhcworICAgICAqICAgICAgICAgICAgZGVjbGFyZWQgaW4gdGhlIGRhdGFiYXNlLgorICAgICAqIEBwYXJhbSBzY29wZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBTQ09QRX0gb2YgaW50ZXJlc3QsIHZhbHVlcyBhcyBkZWZpbmVkIGFib3ZlLgorICAgICAqIEBwYXJhbSBudWxsYWJsZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9ID0gaW5jbHVkZSBjb2x1bW5zIHRoYXQgYXJlIG51bGxhYmxlLCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIGZhbHNlfSA9IGRvIG5vdCBpbmNsdWRlIG51bGxhYmxlIGNvbHVtbnMuCisgICAgICogQHJldHVybiBhIHtAY29kZSBSZXN1bHRTZXR9IHdoZXJlIGVhY2ggcm93IGlzIGEgZGVzY3JpcHRpb24gb2YgYSBjb2x1bW4KKyAgICAgKiAgICAgICAgIGFuZCB0aGUgY29tcGxldGUgc2V0IG9mIHJvd3MgaXMgdGhlIG9wdGltYWwgc2V0IGZvciB0aGlzIHRhYmxlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzdWx0U2V0IGdldEJlc3RSb3dJZGVudGlmaWVyKFN0cmluZyBjYXRhbG9nLCBTdHJpbmcgc2NoZW1hLAorICAgICAgICAgICAgU3RyaW5nIHRhYmxlLCBpbnQgc2NvcGUsIGJvb2xlYW4gbnVsbGFibGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzZXQgb2YgY2F0YWxvZyBuYW1lcyBhdmFpbGFibGUgaW4gdGhpcyBkYXRhYmFzZS4gVGhlIHNldCBpcworICAgICAqIHJldHVybmVkIG9yZGVyZWQgYnkgY2F0YWxvZyBuYW1lLgorICAgICAqCisgICAgICogQHJldHVybiBhIHtAY29kZSBSZXN1bHRTZXR9IGNvbnRhaW5pbmcgdGhlIGNhdGFsb2cgbmFtZXMsIHdpdGggZWFjaCByb3cKKyAgICAgKiAgICAgICAgIGNvbnRhaW5pbmcgb25lIGNhdGFsb2cgbmFtZSAoYXMgYSB7QGNvZGUgU3RyaW5nfSkgaW4gdGhlCisgICAgICogICAgICAgICBzaW5nbGUgY29sdW1uIG5hbWVkIHtAY29kZSBUQUJMRV9DQVR9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzdWx0U2V0IGdldENhdGFsb2dzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNlcGFyYXRvciB0aGF0IHRoaXMgZGF0YWJhc2UgdXNlcyBiZXR3ZWVuIGEgY2F0YWxvZyBuYW1lIGFuZAorICAgICAqIHRhYmxlIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgU3RyaW5nIGNvbnRhaW5pbmcgdGhlIHNlcGFyYXRvci4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDYXRhbG9nU2VwYXJhdG9yKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRlcm0gdGhhdCB0aGUgZGF0YWJhc2UgdmVuZG9yIHByZWZlcnMgdGVybSBmb3IgImNhdGFsb2ciLgorICAgICAqCisgICAgICogQHJldHVybiBhIFN0cmluZyB3aXRoIHRoZSB2ZW5kb3IncyB0ZXJtIGZvciAiY2F0YWxvZyIuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2F0YWxvZ1Rlcm0oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGRlc2NyaXB0aW9uIG9mIGFjY2VzcyByaWdodHMgZm9yIGEgdGFibGUncyBjb2x1bW5zLiBPbmx5IGFjY2VzcworICAgICAqIHJpZ2h0cyBtYXRjaGluZyB0aGUgY3JpdGVyaWEgZm9yIHRoZSBjb2x1bW4gbmFtZSBhcmUgcmV0dXJuZWQuCisgICAgICogPHA+CisgICAgICogVGhlIGRlc2NyaXB0aW9uIGlzIHJldHVybmVkIGFzIGEge0Bjb2RlIFJlc3VsdFNldH0gd2l0aCByb3dzIG9mIGRhdGEgZm9yCisgICAgICogZWFjaCBhY2Nlc3MgcmlnaHQsIHdpdGggY29sdW1ucyBhcyBmb2xsb3dzOgorICAgICAqIDxvbD4KKyAgICAgKiA8bGk+e0Bjb2RlIFRBQkxFX0NBVH0gLSBTdHJpbmcgLSB0aGUgY2F0YWxvZyBuYW1lIChwb3NzaWJseSB7QGNvZGUgbnVsbH0pPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFRBQkxFX1NDSEVNfSAtIFN0cmluZyAtIHRoZSBzY2hlbWEgbmFtZSAocG9zc2libHkge0Bjb2RlIG51bGx9KTwvbGk+CisgICAgICogPGxpPntAY29kZSBUQUJMRV9OQU1FfSAtIFN0cmluZyAtIHRoZSB0YWJsZSBuYW1lPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIENPTFVNTl9OQU1FfSAtIFN0cmluZyAtIHRoZSBDb2x1bW4gbmFtZTwvbGk+CisgICAgICogPGxpPntAY29kZSBHUkFOVE9SfSAtIFN0cmluZyAtIHRoZSBncmFudG9yIG9mIGFjY2VzcyAocG9zc2libHkge0Bjb2RlCisgICAgICogbnVsbH0pPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFBSSVZJTEVHRX0gLSBTdHJpbmcgLSBBY2Nlc3MgcmlnaHQgLSBvbmUgb2YgU0VMRUNULCBJTlNFUlQsCisgICAgICogVVBEQVRFLCBSRUZFUkVOQ0VTLC4uLjwvbGk+CisgICAgICogPGxpPntAY29kZSBJU19HUkFOVEFCTEV9IC0gU3RyaW5nIC0ge0Bjb2RlICJZRVMifSBpbXBsaWVzIHRoYXQgdGhlCisgICAgICogcmVjZWl2ZXIgY2FuIGdyYW50IGFjY2VzcyB0byBvdGhlcnMsIHtAY29kZSAiTk8ifSBpZiB0aGUgcmVjZWl2ZXIgY2Fubm90CisgICAgICogZ3JhbnQgYWNjZXNzIHRvIG90aGVycywge0Bjb2RlIG51bGx9IGlmIHVua25vd24uPC9saT4KKyAgICAgKiA8L29sPgorICAgICAqCisgICAgICogQHBhcmFtIGNhdGFsb2cKKyAgICAgKiAgICAgICAgICAgIGEgY2F0YWxvZyBuYW1lLiB7QGNvZGUgbnVsbH0gaXMgdXNlZCB0byBpbXBseSBubyBuYXJyb3dpbmcgb2YKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWFyY2ggYnkgY2F0YWxvZyBuYW1lLiBPdGhlcndpc2UsIHRoZSBuYW1lIG11c3QgbWF0Y2ggYQorICAgICAqICAgICAgICAgICAgY2F0YWxvZyBuYW1lIGhlbGQgaW4gdGhlIGRhdGFiYXNlLCB3aXRoICIiIHVzZWQgdG8gcmV0cmlldmUKKyAgICAgKiAgICAgICAgICAgIHRob3NlIHdpdGhvdXQgYSBjYXRhbG9nIG5hbWUuCisgICAgICogQHBhcmFtIHNjaGVtYQorICAgICAqICAgICAgICAgICAgYSBzY2hlbWEgbmFtZSBwYXR0ZXJuLiB7QGNvZGUgbnVsbH0gaXMgdXNlZCB0byBpbXBseSBubworICAgICAqICAgICAgICAgICAgbmFycm93aW5nIG9mIHRoZSBzZWFyY2ggYnkgc2NoZW1hIG5hbWUuIE90aGVyd2lzZSwgdGhlIG5hbWUKKyAgICAgKiAgICAgICAgICAgIG11c3QgbWF0Y2ggYSBzY2hlbWEgbmFtZSBpbiB0aGUgZGF0YWJhc2UsIHdpdGggIiIgdXNlZCB0bworICAgICAqICAgICAgICAgICAgcmV0cmlldmUgdGhvc2Ugd2l0aG91dCBhIHNjaGVtYSBuYW1lLgorICAgICAqIEBwYXJhbSB0YWJsZQorICAgICAqICAgICAgICAgICAgdGhlIHRhYmxlIG5hbWUuIFRoaXMgbXVzdCBtYXRjaCB0aGUgbmFtZSBvZiB0aGUgdGFibGUgYXMKKyAgICAgKiAgICAgICAgICAgIGRlY2xhcmVkIGluIHRoZSBkYXRhYmFzZS4KKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZVBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2x1bW4gbmFtZS4gVGhpcyBtdXN0IG1hdGNoIHRoZSBuYW1lIG9mIGEgY29sdW1uIGluIHRoZQorICAgICAqICAgICAgICAgICAgdGFibGUgaW4gdGhlIGRhdGFiYXNlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgUmVzdWx0U2V0fSBjb250YWluaW5nIHRoZSBhY2Nlc3MgcmlnaHRzLCBvbmUgcm93IGZvcgorICAgICAqICAgICAgICAgZWFjaCBwcml2aWxlZ2UgZGVzY3JpcHRpb24uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBSZXN1bHRTZXQgZ2V0Q29sdW1uUHJpdmlsZWdlcyhTdHJpbmcgY2F0YWxvZywgU3RyaW5nIHNjaGVtYSwKKyAgICAgICAgICAgIFN0cmluZyB0YWJsZSwgU3RyaW5nIGNvbHVtbk5hbWVQYXR0ZXJuKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGRlc2NyaXB0aW9uIG9mIHRhYmxlIGNvbHVtbnMgYXZhaWxhYmxlIGluIGEgc3BlY2lmaWVkIGNhdGFsb2cuCisgICAgICogT25seSBkZXNjcmlwdGlvbnMgbWVldGluZyB0aGUgc3BlY2lmaWVkIGNhdGFsb2csIHNjaGVtYSwgdGFibGUsIGFuZCBjb2x1bW4KKyAgICAgKiBuYW1lcyBhcmUgcmV0dXJuZWQuCisgICAgICogPHA+CisgICAgICogVGhlIGRlc2NyaXB0aW9ucyBhcmUgcmV0dXJuZWQgYXMgYSB7QGNvZGUgUmVzdWx0U2V0fSBjb25mb3JtaW5nIHRvIHRoZQorICAgICAqIGZvbGxvd2luZyBkYXRhIGxheW91dCwgd2l0aCBvbmUgcm93IHBlciB0YWJsZSBjb2x1bW46CisgICAgICogPG9sPgorICAgICAqIDxsaT57QGNvZGUgVEFCTEVfQ0FUfSAtIFN0cmluZyAtIHRoZSBjYXRhbG9nIG5hbWUgKHBvc3NpYmx5IHtAY29kZSBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgVEFCTEVfU0NIRU19IC0gU3RyaW5nIC0gdGhlIHNjaGVtYSBuYW1lIChwb3NzaWJseSB7QGNvZGUgbnVsbH0pPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFRBQkxFX05BTUV9IC0gU3RyaW5nIC0gdGhlIHRhYmxlIG5hbWU8L2xpPgorICAgICAqIDxsaT57QGNvZGUgQ09MVU1OX05BTUV9IC0gU3RyaW5nIC0gdGhlIGNvbHVtbiBuYW1lPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERBVEFfVFlQRX0gLSBpbnQgLSB0aGUgU1FMIHR5cGUgYXMgc3BlY2lmaWVkIGluIHtAY29kZQorICAgICAqIGphdmEuc3FsLlR5cGVzfTwvbGk+CisgICAgICogPGxpPntAY29kZSBUWVBFX05BTUV9IC0gU3RyaW5nIC0gdGhlIG5hbWUgb2YgdGhlIGRhdGEgdHlwZSwgKGRhdGFiYXNlLWRlcGVuZGVudCwKKyAgICAgKiBVRFQgbmFtZXMgYXJlIGZ1bGx5IHF1YWxpZmllZCk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgQ09MVU1OX1NJWkV9IC0gaW50IC0gdGhlIGNvbHVtbiBzaXplICh0aGUgcHJlY2lzaW9uIGZvciBudW1lcmljCisgICAgICogdHlwZXMsIG1heCBjaGFyYWN0ZXJzIGZvciB7QGNvZGUgY2hhcn0gYW5kIHtAY29kZSBkYXRlfSB0eXBlcyk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgQlVGRkVSX0xFTkdUSH0gLSBpbnQgLSBOb3QgdXNlZDwvbGk+CisgICAgICogPGxpPntAY29kZSBERUNJTUFMX0RJR0lUU30gLSBpbnQgLSBtYXhpbXVtIG51bWJlciBvZiBmcmFjdGlvbmFsIGRpZ2l0czwvbGk+CisgICAgICogPGxpPntAY29kZSBOVU1fUFJFQ19SQURJWH0gLSBpbnQgLSB0aGUgcmFkaXggZm9yIG51bWVyaWNhbCB0eXBlczwvbGk+CisgICAgICogPGxpPntAY29kZSBOVUxMQUJMRX0gLSBpbnQgLSB3aGV0aGVyIHRoZSBjb2x1bW4gYWxsb3dzIHtAY29kZSBudWxsfXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT5EYXRhYmFzZU1ldGFEYXRhLmNvbHVtbk5vTnVsbHMgPSBtYXkgbm90IGFsbG93IHtAY29kZSBOVUxMfXM8L2xpPgorICAgICAqIDxsaT5EYXRhYmFzZU1ldGFEYXRhLmNvbHVtbk51bGxhYmxlID0gZG9lcyBhbGxvdyB7QGNvZGUgTlVMTH1zPC9saT4KKyAgICAgKiA8bGk+RGF0YWJhc2VNZXRhRGF0YS5jb2x1bW5OdWxsYWJsZVVua25vd24gPSB1bmtub3duIHtAY29kZSBOVUxMfSBzdGF0dXM8L2xpPgorICAgICAqIDwvdWw+CisgICAgICogPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFJFTUFSS1N9IC0gU3RyaW5nIC0gQSBkZXNjcmlwdGlvbiBvZiB0aGUgY29sdW1uIChwb3NzaWJseQorICAgICAqIHtAY29kZSBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgQ09MVU1OX0RFRn0gLSBTdHJpbmcgLSBEZWZhdWx0IHZhbHVlIGZvciB0aGUgY29sdW1uIChwb3NzaWJseQorICAgICAqIHtAY29kZSBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgU1FMX0RBVEFfVFlQRX0gLSBpbnQgLSBub3QgdXNlZDwvbGk+CisgICAgICogPGxpPntAY29kZSBTUUxfREFURVRJTUVfU1VCfSAtIGludCAtIG5vdCB1c2VkPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIENIQVJfT0NURVRfTEVOR1RIfSAtIGludCAtIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIGluIHRoZQorICAgICAqIHtAY29kZSBjaGFyfSB0eXBlIGNvbHVtbnM8L2xpPgorICAgICAqIDxsaT57QGNvZGUgT1JESU5BTF9QT1NJVElPTn0gLSBpbnQgLSB0aGUgY29sdW1uIGluZGV4IGluIHRoZSB0YWJsZSAoMSBiYXNlZCk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgSVNfTlVMTEFCTEV9IC0gU3RyaW5nIC0ge0Bjb2RlICJOTyJ9ID0gY29sdW1uIGRvZXMgbm90IGFsbG93CisgICAgICogTlVMTHMsIHtAY29kZSAiWUVTIn0gPSBjb2x1bW4gYWxsb3dzIE5VTExzLCAiIiA9IHtAY29kZSBOVUxMfSBzdGF0dXMKKyAgICAgKiB1bmtub3duPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFNDT1BFX0NBVEFMT0d9IC0gU3RyaW5nIC0gaWYgdGhlIHtAY29kZSBEQVRBX1RZUEV9IGlzIHtAY29kZSBSRUZ9LAorICAgICAqIHRoaXMgZ2l2ZXMgdGhlIGNhdGFsb2cgb2YgdGhlIHRhYmxlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGF0dHJpYnV0ZSdzIHNjb3BlLgorICAgICAqIE5VTEwgaWYgdGhlIHtAY29kZSBEQVRBX1RZUEV9IGlzIG5vdCBSRUYuPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFNDT1BFX1NDSEVNQX0gLSBTdHJpbmcgLSBpZiB0aGUge0Bjb2RlIERBVEFfVFlQRX0gaXMge0Bjb2RlIFJFRn0sCisgICAgICogdGhpcyBnaXZlcyB0aGUgc2NoZW1hIG9mIHRoZSB0YWJsZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBhdHRyaWJ1dGUncyBzY29wZS4KKyAgICAgKiBOVUxMIGlmIHRoZSB7QGNvZGUgREFUQV9UWVBFfSBpcyBub3QgUkVGLjwvbGk+CisgICAgICogPGxpPntAY29kZSBTQ09QRV9UQUJMRX0gLSBTdHJpbmcgLSBpZiB0aGUge0Bjb2RlIERBVEFfVFlQRX0gaXMge0Bjb2RlIFJFRn0sCisgICAgICogdGhpcyBnaXZlcyB0aGUgbmFtZSBvZiB0aGUgdGFibGUgY29ycmVzcG9uZGluZyB0byB0aGUgYXR0cmlidXRlJ3Mgc2NvcGUuCisgICAgICogTlVMTCBpZiB0aGUge0Bjb2RlIERBVEFfVFlQRX0gaXMgbm90IFJFRi48L2xpPgorICAgICAqIDxsaT57QGNvZGUgU09VUkNFX0RBVEFfVFlQRX0gLSBTdHJpbmcgLSBUaGUgc291cmNlIHR5cGUgZm9yIGEgdXNlcgorICAgICAqIGdlbmVyYXRlZCBSRUYgdHlwZSBvciBmb3IgYSBEaXN0aW5jdCB0eXBlLiAoe0Bjb2RlIE5VTEx9IGlmIHtAY29kZQorICAgICAqIERBVEFfVFlQRX0gaXMgbm90IERJU1RJTkNUIG9yIGEgdXNlciBnZW5lcmF0ZWQgUkVGKTwvbGk+CisgICAgICogPC9vbD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXRhbG9nCisgICAgICogICAgICAgICAgICBhIGNhdGFsb2cgbmFtZS4ge0Bjb2RlIG51bGx9IGlzIHVzZWQgdG8gaW1wbHkgbm8gbmFycm93aW5nIG9mCisgICAgICogICAgICAgICAgICB0aGUgc2VhcmNoIGJ5IGNhdGFsb2cgbmFtZS4gT3RoZXJ3aXNlLCB0aGUgbmFtZSBtdXN0IG1hdGNoIGEKKyAgICAgKiAgICAgICAgICAgIGNhdGFsb2cgbmFtZSBoZWxkIGluIHRoZSBkYXRhYmFzZSwgd2l0aCAiIiB1c2VkIHRvIHJldHJpZXZlCisgICAgICogICAgICAgICAgICB0aG9zZSB3aXRob3V0IGEgY2F0YWxvZyBuYW1lLgorICAgICAqIEBwYXJhbSBzY2hlbWFQYXR0ZXJuCisgICAgICogICAgICAgICAgICBhIHNjaGVtYSBuYW1lIHBhdHRlcm4uIHtAY29kZSBudWxsfSBpcyB1c2VkIHRvIGltcGx5IG5vCisgICAgICogICAgICAgICAgICBuYXJyb3dpbmcgb2YgdGhlIHNlYXJjaCBieSBzY2hlbWEgbmFtZS4gT3RoZXJ3aXNlLCB0aGUgbmFtZQorICAgICAqICAgICAgICAgICAgbXVzdCBtYXRjaCBhIHNjaGVtYSBuYW1lIGluIHRoZSBkYXRhYmFzZSwgd2l0aCAiIiB1c2VkIHRvCisgICAgICogICAgICAgICAgICByZXRyaWV2ZSB0aG9zZSB3aXRob3V0IGEgc2NoZW1hIG5hbWUuCisgICAgICogQHBhcmFtIHRhYmxlTmFtZVBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIHRoZSB0YWJsZSBuYW1lLiBUaGlzIG11c3QgbWF0Y2ggdGhlIG5hbWUgb2YgdGhlIHRhYmxlIGFzCisgICAgICogICAgICAgICAgICBkZWNsYXJlZCBpbiB0aGUgZGF0YWJhc2UuCisgICAgICogQHBhcmFtIGNvbHVtbk5hbWVQYXR0ZXJuCisgICAgICogICAgICAgICAgICB0aGUgY29sdW1uIG5hbWUuIFRoaXMgbXVzdCBtYXRjaCB0aGUgbmFtZSBvZiBhIGNvbHVtbiBpbiB0aGUKKyAgICAgKiAgICAgICAgICAgIHRhYmxlIGluIHRoZSBkYXRhYmFzZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBkZXNjcmlwdGlvbnMgYXMgYSB7QGNvZGUgUmVzdWx0U2V0fSB3aXRoIHJvd3MgaW4gdGhlIGZvcm0KKyAgICAgKiAgICAgICAgIGRlZmluZWQgYWJvdmUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBSZXN1bHRTZXQgZ2V0Q29sdW1ucyhTdHJpbmcgY2F0YWxvZywgU3RyaW5nIHNjaGVtYVBhdHRlcm4sCisgICAgICAgICAgICBTdHJpbmcgdGFibGVOYW1lUGF0dGVybiwgU3RyaW5nIGNvbHVtbk5hbWVQYXR0ZXJuKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRhdGFiYXNlIGNvbm5lY3Rpb24gdGhhdCBjcmVhdGVkIHRoaXMgbWV0YWRhdGEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBkYXRhYmFzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIENvbm5lY3Rpb24gZ2V0Q29ubmVjdGlvbigpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBmb3JlaWduIGtleSBjb2x1bW5zIGluIGEgZ2l2ZW4gZm9yZWlnbiBrZXkgdGFibGUgdGhhdAorICAgICAqIHJlZmVyZW5jZSB0aGUgcHJpbWFyeSBrZXkgY29sdW1ucyBvZiBhIHN1cHBsaWVkIHByaW1hcnkga2V5IHRhYmxlLiBUaGlzCisgICAgICogZGVzY3JpYmVzIGhvdyBvbmUgdGFibGUgaW1wb3J0cyB0aGUga2V5IG9mIGFub3RoZXIgdGFibGUuIEl0IHdvdWxkIGJlCisgICAgICogZXhwZWN0ZWQgdG8gcmV0dXJuIGEgc2luZ2xlIGZvcmVpZ24ga2V5IC0gcHJpbWFyeSBrZXkgcGFpciBpbiBtb3N0IGNhc2VzLgorICAgICAqIDxwPgorICAgICAqIFRoZSBkZXNjcmlwdGlvbnMgYXJlIHJldHVybmVkIGFzIGEge0Bjb2RlIFJlc3VsdFNldH0gd2l0aCBvbmUgcm93IGZvcgorICAgICAqIGVhY2ggZm9yZWlnbiBrZXksIHdpdGggdGhlIGZvbGxvd2luZyBsYXlvdXQ6CisgICAgICogPG9sPgorICAgICAqIDxsaT57QGNvZGUgUEtUQUJMRV9DQVR9IC0gU3RyaW5nIC0gZnJvbSB0aGUgcHJpbWFyeSBrZXkgdGFibGUgOiBDYXRhbG9nCisgICAgICogKHBvc3NpYmx5IHtAY29kZSBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgUEtUQUJMRV9TQ0hFTX0gLSBTdHJpbmcgLSBmcm9tIHRoZSBwcmltYXJ5IGtleSB0YWJsZSA6IFNjaGVtYQorICAgICAqIChwb3NzaWJseSB7QGNvZGUgbnVsbH0pPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFBLVEFCTEVfTkFNRX0gLSBTdHJpbmcgLSBmcm9tIHRoZSBwcmltYXJ5IGtleSB0YWJsZSA6IG5hbWU8L2xpPgorICAgICAqIDxsaT57QGNvZGUgUEtDT0xVTU5fTkFNRX0gLSBTdHJpbmcgLSBmcm9tIHRoZSBwcmltYXJ5IGtleSBjb2x1bW4gOiBuYW1lPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIEZLVEFCTEVfQ0FUfSAtIFN0cmluZyAtIGZyb20gdGhlIGZvcmVpZ24ga2V5IHRhYmxlIDogdGhlCisgICAgICogY2F0YWxvZyBuYW1lIGJlaW5nIGV4cG9ydGVkIChwb3NzaWJseSB7QGNvZGUgbnVsbH0pPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIEZLVEFCTEVfU0NIRU19IC0gU3RyaW5nIC0gZnJvbSB0aGUgZm9yZWlnbiBrZXkgdGFibGUgOiB0aGUgc2NoZW1hIG5hbWUKKyAgICAgKiBiZWluZyBleHBvcnRlZCAocG9zc2libHkge0Bjb2RlIG51bGx9KTwvbGk+CisgICAgICogPGxpPntAY29kZSBGS1RBQkxFX05BTUV9IC0gU3RyaW5nIC0gZnJvbSB0aGUgZm9yZWlnbiBrZXkgdGFibGUgOiB0aGUgbmFtZSBiZWluZworICAgICAqIGV4cG9ydGVkPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIEZLQ09MVU1OX05BTUV9IC0gU3RyaW5nIC0gZnJvbSB0aGUgZm9yZWlnbiBrZXkgY29sdW1uIDogdGhlIG5hbWUgYmVpbmcKKyAgICAgKiBleHBvcnRlZDwvbGk+CisgICAgICogPGxpPntAY29kZSBLRVlfU0VRfSAtIHNob3J0IC0gdGhlIHNlcXVlbmNlIG51bWJlciAoaW4gdGhlIGZvcmVpZ24ga2V5KTwvbGk+CisgICAgICogPGxpPntAY29kZSBVUERBVEVfUlVMRX0gLSBzaG9ydCAtIGEgdmFsdWUgZ2l2aW5nIHRoZSBydWxlIGZvciBob3cgdG8gdHJlYXQgdGhlIGNvcnJlc3BvbmRpbmcgZm9yZWlnbiBrZXkgd2hlbiBhIHByaW1hcnkKKyAgICAgKiBrZXkgaXMgdXBkYXRlZDoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5Tm9BY3Rpb259IC0gZG9uJ3QgYWxsb3cgdGhlCisgICAgICogcHJpbWFyeSBrZXkgdG8gYmUgdXBkYXRlZCBpZiBpdCBpcyBpbXBvcnRlZCBhcyBhIGZvcmVpZ24ga2V5PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuaW1wb3J0ZWRLZXlDYXNjYWRlfSAtIGNoYW5nZSB0aGUgaW1wb3J0ZWQga2V5IHRvCisgICAgICogbWF0Y2ggdGhlIHVwZGF0ZWQgcHJpbWFyeSBrZXk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgRGF0YWJhc2VNZXRhRGF0YS5pbXBvcnRlZEtleVNldE51bGx9IC0gc2V0IHRoZSBpbXBvcnRlZCBrZXkgdG8KKyAgICAgKiB7QGNvZGUgbnVsbH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgRGF0YWJhc2VNZXRhRGF0YS5pbXBvcnRlZEtleVNldERlZmF1bHR9IC0gc2V0IHRoZSBpbXBvcnRlZCBrZXkKKyAgICAgKiB0byBpdHMgZGVmYXVsdCB2YWx1ZTwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5UmVzdHJpY3R9IC0gc2FtZSBhcyB7QGNvZGUKKyAgICAgKiBpbXBvcnRlZEtleU5vQWN0aW9ufTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT57QGNvZGUgREVMRVRFX1JVTEV9IC0gc2hvcnQgLSBhIHZhbHVlIGdpdmluZyB0aGUgcnVsZSBmb3IgaG93IHRvIHRyZWF0IHRoZSBmb3JlaWduIGtleSB3aGVuIHRoZSBjb3JyZXNwb25kaW5nIHByaW1hcnkKKyAgICAgKiBrZXkgaXMgZGVsZXRlZDoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5Tm9BY3Rpb259IC0gZG9uJ3QgYWxsb3cgdGhlCisgICAgICogcHJpbWFyeSBrZXkgdG8gYmUgZGVsZXRlZCBpZiBpdCBpcyBpbXBvcnRlZCBhcyBhIGZvcmVpZ24ga2V5PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuaW1wb3J0ZWRLZXlDYXNjYWRlfSAtIGRlbGV0ZSB0aG9zZSByb3dzIHRoYXQKKyAgICAgKiBpbXBvcnQgYSBkZWxldGVkIGtleTwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5U2V0TnVsbH0gLSBzZXQgdGhlIGltcG9ydGVkIGtleSB0bworICAgICAqIHtAY29kZSBudWxsfTwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5U2V0RGVmYXVsdH0gLSBzZXQgdGhlIGltcG9ydGVkIGtleQorICAgICAqIHRvIGl0cyBkZWZhdWx0IHZhbHVlPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuaW1wb3J0ZWRLZXlSZXN0cmljdH0gLSBzYW1lIGFzCisgICAgICogaW1wb3J0ZWRLZXlOb0FjdGlvbjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT57QGNvZGUgRktfTkFNRX0gLSBTdHJpbmcgLSB0aGUgZm9yZWlnbiBrZXkgbmFtZSAocG9zc2libHkge0Bjb2RlIG51bGx9KTwvbGk+CisgICAgICogPGxpPntAY29kZSBQS19OQU1FfSAtIFN0cmluZyAtIHRoZSBwcmltYXJ5IGtleSBuYW1lIChwb3NzaWJseSB7QGNvZGUgbnVsbH0pPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERFRkVSUkFCSUxJVFl9IC0gc2hvcnQgLSB3aGV0aGVyIGZvcmVpZ24ga2V5IGNvbnN0cmFpbnRzIGNhbiBiZQorICAgICAqIGRlZmVycmVkIHVudGlsIGNvbW1pdCAoc2VlIHRoZSBTUUw5MiBzcGVjaWZpY2F0aW9uIGZvciBkZWZpbml0aW9ucyk6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgRGF0YWJhc2VNZXRhRGF0YS5pbXBvcnRlZEtleUluaXRpYWxseURlZmVycmVkfTwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5SW5pdGlhbGx5SW1tZWRpYXRlfTwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5Tm90RGVmZXJyYWJsZX08L2xpPgorICAgICAqIDwvdWw+CisgICAgICogPC9saT4KKyAgICAgKiA8L29sPgorICAgICAqCisgICAgICogQHBhcmFtIHByaW1hcnlDYXRhbG9nCisgICAgICogICAgICAgICAgICBhIGNhdGFsb2cgbmFtZSBmb3IgdGhlIHByaW1hcnkga2V5IHRhYmxlLiB7QGNvZGUgbnVsbH0gaXMgdXNlZCB0byBpbXBseSBubyBuYXJyb3dpbmcgb2YKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWFyY2ggYnkgY2F0YWxvZyBuYW1lLiBPdGhlcndpc2UsIHRoZSBuYW1lIG11c3QgbWF0Y2ggYQorICAgICAqICAgICAgICAgICAgY2F0YWxvZyBuYW1lIGhlbGQgaW4gdGhlIGRhdGFiYXNlLCB3aXRoICIiIHVzZWQgdG8gcmV0cmlldmUKKyAgICAgKiAgICAgICAgICAgIHRob3NlIHdpdGhvdXQgYSBjYXRhbG9nIG5hbWUuCisgICAgICogQHBhcmFtIHByaW1hcnlTY2hlbWEKKyAgICAgKiAgICAgICAgICAgIGEgc2NoZW1hIG5hbWUgZm9yIHRoZSBwcmltYXJ5IGtleSB0YWJsZS4ge0Bjb2RlIG51bGx9IGlzIHVzZWQgdG8gaW1wbHkgbm8gbmFycm93aW5nIG9mCisgICAgICogICAgICAgICAgICB0aGUgc2VhcmNoIGJ5IHNjaGVtYSBuYW1lLiBPdGhlcndpc2UsIHRoZSBuYW1lIG11c3QgbWF0Y2ggYQorICAgICAqICAgICAgICAgICAgc2NoZW1hIG5hbWUgaW4gdGhlIGRhdGFiYXNlLCB3aXRoICIiIHVzZWQgdG8gcmV0cmlldmUgdGhvc2UKKyAgICAgKiAgICAgICAgICAgIHdpdGhvdXQgYSBzY2hlbWEgbmFtZS4KKyAgICAgKiBAcGFyYW0gcHJpbWFyeVRhYmxlCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgdGFibGUgd2hpY2ggZXhwb3J0cyB0aGUga2V5LiBJdCBtdXN0IG1hdGNoIHRoZQorICAgICAqICAgICAgICAgICAgbmFtZSBvZiB0aGUgdGFibGUgaW4gdGhlIGRhdGFiYXNlLgorICAgICAqIEBwYXJhbSBmb3JlaWduQ2F0YWxvZworICAgICAqICAgICAgICAgICAgYSBjYXRhbG9nIG5hbWUgZm9yIHRoZSBmb3JlaWduIGtleSB0YWJsZS4ge0Bjb2RlIG51bGx9IGlzIHVzZWQgdG8gaW1wbHkgbm8gbmFycm93aW5nIG9mCisgICAgICogICAgICAgICAgICB0aGUgc2VhcmNoIGJ5IGNhdGFsb2cgbmFtZS4gT3RoZXJ3aXNlLCB0aGUgbmFtZSBtdXN0IG1hdGNoIGEKKyAgICAgKiAgICAgICAgICAgIGNhdGFsb2cgbmFtZSBoZWxkIGluIHRoZSBkYXRhYmFzZSwgd2l0aCAiIiB1c2VkIHRvIHJldHJpZXZlCisgICAgICogICAgICAgICAgICB0aG9zZSB3aXRob3V0IGEgY2F0YWxvZyBuYW1lLgorICAgICAqIEBwYXJhbSBmb3JlaWduU2NoZW1hCisgICAgICogICAgICAgICAgICBhIHNjaGVtYSBuYW1lIGZvciB0aGUgZm9yZWlnbiBrZXkgdGFibGUuIHtAY29kZSBudWxsfSBpcyB1c2VkIHRvIGltcGx5IG5vIG5hcnJvd2luZyBvZgorICAgICAqICAgICAgICAgICAgdGhlIHNlYXJjaCBieSBzY2hlbWEgbmFtZS4gT3RoZXJ3aXNlLCB0aGUgbmFtZSBtdXN0IG1hdGNoIGEKKyAgICAgKiAgICAgICAgICAgIHNjaGVtYSBuYW1lIGluIHRoZSBkYXRhYmFzZSwgd2l0aCAiIiB1c2VkIHRvIHJldHJpZXZlIHRob3NlCisgICAgICogICAgICAgICAgICB3aXRob3V0IGEgc2NoZW1hIG5hbWUuCisgICAgICogQHBhcmFtIGZvcmVpZ25UYWJsZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHRhYmxlIGltcG9ydGluZyB0aGUga2V5LiBJdCBtdXN0IG1hdGNoIHRoZQorICAgICAqICAgICAgICAgICAgbmFtZSBvZiB0aGUgdGFibGUgaW4gdGhlIGRhdGFiYXNlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgUmVzdWx0U2V0fSBjb250YWluaW5nIHJvd3Mgd2l0aCB0aGUgZGVzY3JpcHRpb25zIG9mIHRoZQorICAgICAqICAgICAgICAgZm9yZWlnbiBrZXlzIGxhaWQgb3V0IGFjY29yZGluZyB0byB0aGUgZm9ybWF0IGRlZmluZWQgYWJvdmUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBSZXN1bHRTZXQgZ2V0Q3Jvc3NSZWZlcmVuY2UoU3RyaW5nIHByaW1hcnlDYXRhbG9nLAorICAgICAgICAgICAgU3RyaW5nIHByaW1hcnlTY2hlbWEsIFN0cmluZyBwcmltYXJ5VGFibGUsIFN0cmluZyBmb3JlaWduQ2F0YWxvZywKKyAgICAgICAgICAgIFN0cmluZyBmb3JlaWduU2NoZW1hLCBTdHJpbmcgZm9yZWlnblRhYmxlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbWFqb3IgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGRhdGFiYXNlIHNvZnR3YXJlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWFqb3IgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGRhdGFiYXNlIHNvZnR3YXJlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldERhdGFiYXNlTWFqb3JWZXJzaW9uKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1pbm9yIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBkYXRhYmFzZSBzb2Z0d2FyZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1pbm9yIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBkYXRhYmFzZSBzb2Z0d2FyZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXREYXRhYmFzZU1pbm9yVmVyc2lvbigpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBkYXRhYmFzZSBzb2Z0d2FyZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgU3RyaW5nfSB3aXRoIHRoZSBuYW1lIG9mIHRoZSBkYXRhYmFzZSBzb2Z0d2FyZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXREYXRhYmFzZVByb2R1Y3ROYW1lKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoaXMgZGF0YWJhc2Ugc29mdHdhcmUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFN0cmluZ30gd2l0aCB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGRhdGFiYXNlCisgICAgICogICAgICAgICBzb2Z0d2FyZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXREYXRhYmFzZVByb2R1Y3RWZXJzaW9uKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgdHJhbnNhY3Rpb24gaXNvbGF0aW9uIGxldmVsIGZvciB0aGlzIGRhdGFiYXNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZGVmYXVsdCB0cmFuc2FjdGlvbiBpc29sYXRpb24gbGV2ZWwuIE9uZSBvZiB0aGUgZm9sbG93aW5nIHZhbHVlczoKKyAgICAgKiAgICAgICAgIDx1bD4KKyAgICAgKiAgICAgICAgIDxsaT57QGNvZGUgVFJBTlNBQ1RJT05fTk9ORX08L2xpPgorICAgICAqICAgICAgICAgPGxpPntAY29kZSBUUkFOU0FDVElPTl9SRUFEX0NPTU1JVFRFRH08L2xpPgorICAgICAqICAgICAgICAgPGxpPntAY29kZSBUUkFOU0FDVElPTl9SRUFEX1VOQ09NTUlUVEVEfTwvbGk+CisgICAgICogICAgICAgICA8bGk+e0Bjb2RlIFRSQU5TQUNUSU9OX1JFUEVBVEFCTEVfUkVBRH08L2xpPgorICAgICAqICAgICAgICAgPGxpPntAY29kZSBUUkFOU0FDVElPTl9TRVJJQUxJWkFCTEV9PC9saT4KKyAgICAgKiAgICAgICAgIDwvdWw+CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RGVmYXVsdFRyYW5zYWN0aW9uSXNvbGF0aW9uKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIEpEQkMgZHJpdmVyJ3MgbWFqb3IgdmVyc2lvbiBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkcml2ZXIncyBtYWpvciB2ZXJzaW9uIG51bWJlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldERyaXZlck1ham9yVmVyc2lvbigpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgSkRCQyBkcml2ZXIncyBtaW5vciB2ZXJzaW9uIG51bWJlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGRyaXZlcidzIG1pbm9yIHZlcnNpb24gbnVtYmVyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RHJpdmVyTWlub3JWZXJzaW9uKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoaXMgSkRCQyBkcml2ZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFN0cmluZ30gY29udGFpbmluZyB0aGUgbmFtZSBvZiB0aGUgSkRCQyBkcml2ZXIKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXREcml2ZXJOYW1lKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoaXMgSkRCQyBkcml2ZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFN0cmluZ30gY29udGFpbmluZyB0aGUgY29tcGxldGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlCisgICAgICogICAgICAgICBKREJDIGRyaXZlci4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXREcml2ZXJWZXJzaW9uKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBsaXN0IG9mIHRoZSBmb3JlaWduIGtleSBjb2x1bW5zIHRoYXQgcmVmZXJlbmNlIHRoZSBwcmltYXJ5IGtleQorICAgICAqIGNvbHVtbnMgb2YgYSBzcGVjaWZpZWQgdGFibGUgKHRoZSBmb3JlaWduIGtleXMgZXhwb3J0ZWQgYnkgYSB0YWJsZSkuCisgICAgICogPHA+CisgICAgICogVGhlIGxpc3QgaXMgcmV0dXJuZWQgYXMgYSB7QGNvZGUgUmVzdWx0U2V0fSB3aXRoIGEgcm93IGZvciBlYWNoIG9mIHRoZQorICAgICAqIGZvcmVpZ24ga2V5IGNvbHVtbnMsIG9yZGVyZWQgYnkge0Bjb2RlIEZLVEFCTEVfQ0FUfSwge0Bjb2RlCisgICAgICogRktUQUJMRV9TQ0hFTX0sIHtAY29kZSBGS1RBQkxFX05BTUV9LCBhbmQge0Bjb2RlIEtFWV9TRVF9LCB3aXRoIHRoZQorICAgICAqIGZvcm1hdCBmb3IgZWFjaCByb3cgYmVpbmc6CisgICAgICogPG9sPgorICAgICAqIDxsaT57QGNvZGUgUEtUQUJMRV9DQVR9IC0gU3RyaW5nIC0gZnJvbSB0aGUgcHJpbWFyeSBrZXkgdGFibGUgOiB0aGUgY2F0YWxvZyAocG9zc2libHkKKyAgICAgKiB7QGNvZGUgbnVsbH0pPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFBLVEFCTEVfU0NIRU19IC0gU3RyaW5nIC0gZnJvbSB0aGUgcHJpbWFyeSBrZXkgdGFibGUgOiB0aGUgc2NoZW1hIChwb3NzaWJseQorICAgICAqIHtAY29kZSBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgUEtUQUJMRV9OQU1FfSAtIFN0cmluZyAtIGZyb20gdGhlIHByaW1hcnkga2V5IHRhYmxlIDogdGhlIG5hbWU8L2xpPgorICAgICAqIDxsaT57QGNvZGUgUEtDT0xVTU5fTkFNRX0gLSBTdHJpbmcgLSBmcm9tIHRoZSBwcmltYXJ5IGtleSBjb2x1bW4gOiB0aGUgbmFtZTwvbGk+CisgICAgICogPGxpPntAY29kZSBGS1RBQkxFX0NBVH0gLSBTdHJpbmcgLSBmcm9tIHRoZSBmb3JlaWduIGtleSB0YWJsZSA6IHRoZSBjYXRhbG9nIG5hbWUgYmVpbmcKKyAgICAgKiBleHBvcnRlZCAocG9zc2libHkge0Bjb2RlIG51bGx9KTwvbGk+CisgICAgICogPGxpPntAY29kZSBGS1RBQkxFX1NDSEVNfSAtIFN0cmluZyAtIGZyb20gdGhlIGZvcmVpZ24ga2V5IHRhYmxlIDogdGhlIHNjaGVtYSBuYW1lCisgICAgICogYmVpbmcgZXhwb3J0ZWQgKHBvc3NpYmx5IHtAY29kZSBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgRktUQUJMRV9OQU1FfSAtIFN0cmluZyAtIGZyb20gdGhlIGZvcmVpZ24ga2V5IHRhYmxlIDogdGhlIG5hbWUgYmVpbmcKKyAgICAgKiBleHBvcnRlZDwvbGk+CisgICAgICogPGxpPntAY29kZSBGS0NPTFVNTl9OQU1FfSAtIFN0cmluZyAtIGZyb20gdGhlIGZvcmVpZ24ga2V5IGNvbHVtbiA6IHRoZSBuYW1lIGJlaW5nCisgICAgICogZXhwb3J0ZWQ8L2xpPgorICAgICAqIDxsaT57QGNvZGUgS0VZX1NFUX0gLSBzaG9ydCAtIHRoZSBzZXF1ZW5jZSBudW1iZXIgKGluIHRoZSBmb3JlaWduIGtleSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgVVBEQVRFX1JVTEV9IC0gc2hvcnQgLSBhIHZhbHVlIGdpdmluZyB0aGUgcnVsZSBmb3IgaG93IHRvIHRyZWF0IHRoZSBmb3JlaWduIGtleSB3aGVuIHRoZSBjb3JyZXNwb25kaW5nIHByaW1hcnkKKyAgICAgKiBrZXkgaXMgdXBkYXRlZDoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5Tm9BY3Rpb259IC0gZG9uJ3QgYWxsb3cgdGhlCisgICAgICogcHJpbWFyeSBrZXkgdG8gYmUgdXBkYXRlZCBpZiBpdCBpcyBpbXBvcnRlZCBhcyBhIGZvcmVpZ24ga2V5PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuaW1wb3J0ZWRLZXlDYXNjYWRlfSAtIGNoYW5nZSB0aGUgaW1wb3J0ZWQga2V5IHRvCisgICAgICogbWF0Y2ggdGhlIHByaW1hcnkga2V5IHVwZGF0ZTwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5U2V0TnVsbH0gLSBzZXQgdGhlIGltcG9ydGVkIGtleSB0bworICAgICAqIHtAY29kZSBudWxsfTwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5U2V0RGVmYXVsdH0gLSBzZXQgdGhlIGltcG9ydGVkIGtleQorICAgICAqIHRvIGl0cyBkZWZhdWx0IHZhbHVlPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuaW1wb3J0ZWRLZXlSZXN0cmljdH0gLSBzYW1lIGFzCisgICAgICogaW1wb3J0ZWRLZXlOb0FjdGlvbjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT57QGNvZGUgREVMRVRFX1JVTEV9IC0gc2hvcnQgLSBob3cgdG8gdHJlYXQgdGhlIGZvcmVpZ24ga2V5IHdoZW4gdGhlIGNvcnJlc3BvbmRpbmcgcHJpbWFyeQorICAgICAqIGtleSBpcyBkZWxldGVkOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuaW1wb3J0ZWRLZXlOb0FjdGlvbn0gLSBkb24ndCBhbGxvdyB0aGUKKyAgICAgKiBwcmltYXJ5IGtleSB0byBiZSBkZWxldGVkIGlmIGl0IGlzIGltcG9ydGVkIGFzIGEgZm9yZWlnbiBrZXk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgRGF0YWJhc2VNZXRhRGF0YS5pbXBvcnRlZEtleUNhc2NhZGV9IC0gdGhlIGRlbGV0aW9uIHNob3VsZAorICAgICAqIGFsc28gZGVsZXRlIHJvd3MgdGhhdCBpbXBvcnQgYSBkZWxldGVkIGtleTwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5U2V0TnVsbH0gLSB0aGUgZGVsZXRpb24gc2V0cyB0aGUKKyAgICAgKiBpbXBvcnRlZCBrZXkgdG8ge0Bjb2RlIG51bGx9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuaW1wb3J0ZWRLZXlTZXREZWZhdWx0fSAtIHRoZSBkZWxldGlvbiBzZXRzIHRoZQorICAgICAqIGltcG9ydGVkIGtleSB0byBpdHMgZGVmYXVsdCB2YWx1ZTwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5UmVzdHJpY3R9IC0gc2FtZSBhcworICAgICAqIGltcG9ydGVkS2V5Tm9BY3Rpb248L2xpPgorICAgICAqIDwvdWw+CisgICAgICogPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIEZLX05BTUV9IC0gU3RyaW5nIC0gdGhlIGZvcmVpZ24ga2V5IG5hbWUgKHBvc3NpYmx5IHtAY29kZSBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgUEtfTkFNRX0gLSBTdHJpbmcgLSB0aGUgcHJpbWFyeSBrZXkgbmFtZSAocG9zc2libHkge0Bjb2RlIG51bGx9KTwvbGk+CisgICAgICogPGxpPntAY29kZSBERUZFUlJBQklMSVRZfSAtIHNob3J0IC0gZGVmaW5lcyB3aGV0aGVyIHRoZSBmb3JlaWduIGtleQorICAgICAqIGNvbnN0cmFpbnRzIGNhbiBiZSBkZWZlcnJlZCB1bnRpbCBjb21taXQgKHNlZSB0aGUgU1FMOTIgc3BlY2lmaWNhdGlvbiBmb3IKKyAgICAgKiBkZWZpbml0aW9ucyk6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgRGF0YWJhc2VNZXRhRGF0YS5pbXBvcnRlZEtleUluaXRpYWxseURlZmVycmVkfTwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5SW5pdGlhbGx5SW1tZWRpYXRlfTwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5Tm90RGVmZXJyYWJsZX08L2xpPgorICAgICAqIDwvdWw+CisgICAgICogPC9saT4KKyAgICAgKiA8L29sPgorICAgICAqCisgICAgICogQHBhcmFtIGNhdGFsb2cKKyAgICAgKiAgICAgICAgICAgIGEgY2F0YWxvZyBuYW1lLiB7QGNvZGUgbnVsbH0gaXMgdXNlZCB0byBpbXBseSBubyBuYXJyb3dpbmcgb2YKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWFyY2ggYnkgY2F0YWxvZyBuYW1lLiBPdGhlcndpc2UsIHRoZSBuYW1lIG11c3QgbWF0Y2ggYQorICAgICAqICAgICAgICAgICAgY2F0YWxvZyBuYW1lIGhlbGQgaW4gdGhlIGRhdGFiYXNlLCB3aXRoICIiIHVzZWQgdG8gcmV0cmlldmUKKyAgICAgKiAgICAgICAgICAgIHRob3NlIHdpdGhvdXQgYSBjYXRhbG9nIG5hbWUuCisgICAgICogQHBhcmFtIHNjaGVtYQorICAgICAqICAgICAgICAgICAgYSBzY2hlbWEgbmFtZS4ge0Bjb2RlIG51bGx9IGlzIHVzZWQgdG8gaW1wbHkgbm8gbmFycm93aW5nIG9mCisgICAgICogICAgICAgICAgICB0aGUgc2VhcmNoIGJ5IHNjaGVtYSBuYW1lLiBPdGhlcndpc2UsIHRoZSBuYW1lIG11c3QgbWF0Y2ggYQorICAgICAqICAgICAgICAgICAgc2NoZW1hIG5hbWUgaW4gdGhlIGRhdGFiYXNlLCB3aXRoICIiIHVzZWQgdG8gcmV0cmlldmUgdGhvc2UKKyAgICAgKiAgICAgICAgICAgIHdpdGhvdXQgYSBzY2hlbWEgbmFtZS4KKyAgICAgKiBAcGFyYW0gdGFibGUKKyAgICAgKiAgICAgICAgICAgIGEgdGFibGUgbmFtZSwgd2hpY2ggbXVzdCBtYXRjaCB0aGUgbmFtZSBvZiBhIHRhYmxlIGluIHRoZQorICAgICAqICAgICAgICAgICAgZGF0YWJhc2UKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFJlc3VsdFNldH0gY29udGFpbmluZyBhIHJvdyBmb3IgZWFjaCBvZiB0aGUgZm9yZWlnbiBrZXkKKyAgICAgKiAgICAgICAgIGNvbHVtbnMsIGFzIGRlZmluZWQgYWJvdmUKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzdWx0U2V0IGdldEV4cG9ydGVkS2V5cyhTdHJpbmcgY2F0YWxvZywgU3RyaW5nIHNjaGVtYSwgU3RyaW5nIHRhYmxlKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyB0aGF0IG1heSBiZSB1c2VkIGluIHVucXVvdGVkIGlkZW50aWZpZXIKKyAgICAgKiBuYW1lcy4gVGhlIGNoYXJhY3RlcnMge0Bjb2RlIGEten0sIHtAY29kZSBBLVp9LCB7QGNvZGUgMC05fSBhbmQge0Bjb2RlIF99CisgICAgICogYXJlIGFsd2F5cyBwZXJtaXR0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgU3RyaW5nIGNvbnRhaW5pbmcgYWxsIHRoZSBhZGRpdGlvbmFsIHBlcm1pdHRlZCBjaGFyYWN0ZXJzLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEV4dHJhTmFtZUNoYXJhY3RlcnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyaW5nIHVzZWQgdG8gcXVvdGUgU1FMIGlkZW50aWZpZXJzLiBSZXR1cm5zICIgIiAoc3BhY2UpIGlmCisgICAgICogaWRlbnRpZmllciBxdW90aW5nIG5vdCBzdXBwb3J0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBTdHJpbmcgdXNlZCB0byBxdW90ZSBTUUwgaWRlbnRpZmllcnMuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0SWRlbnRpZmllclF1b3RlU3RyaW5nKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBsaXN0IGNvbHVtbnMgaW4gYSB0YWJsZSB0aGF0IGFyZSBib3RoIHByaW1hcnkga2V5cyBhbmQKKyAgICAgKiByZWZlcmVuY2VkIGJ5IHRoZSB0YWJsZSdzIGZvcmVpZ24ga2V5IGNvbHVtbnMgKHRoYXQgaXMsIHRoZSBwcmltYXJ5IGtleXMKKyAgICAgKiBpbXBvcnRlZCBieSBhIHRhYmxlKS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbGlzdCByZXR1cm5lZCBpcyBhIHtAY29kZSBSZXN1bHRTZXR9IHdpdGggYSByb3cgZW50cnkgZm9yIGVhY2gKKyAgICAgKiBwcmltYXJ5IGtleSBjb2x1bW4sIG9yZGVyZWQgYnkge0Bjb2RlIFBLVEFCTEVfQ0FUfSwge0Bjb2RlIFBLVEFCTEVfU0NIRU19LAorICAgICAqIHtAY29kZSBQS1RBQkxFX05BTUV9LCBhbmQge0Bjb2RlIEtFWV9TRVF9LCB3aXRoIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgorICAgICAqIDxvbD4KKyAgICAgKiA8bGk+e0Bjb2RlIFBLVEFCTEVfQ0FUfSAtIFN0cmluZyAtIHByaW1hcnkga2V5IGNhdGFsb2cgbmFtZSBiZWluZworICAgICAqIGltcG9ydGVkIChwb3NzaWJseSB7QGNvZGUgbnVsbH0pPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFBLVEFCTEVfU0NIRU19IC0gU3RyaW5nIC0gcHJpbWFyeSBrZXkgc2NoZW1hIG5hbWUgYmVpbmcKKyAgICAgKiBpbXBvcnRlZCAocG9zc2libHkge0Bjb2RlIG51bGx9KTwvbGk+CisgICAgICogPGxpPntAY29kZSBQS1RBQkxFX05BTUV9IC0gU3RyaW5nIC0gcHJpbWFyeSBrZXkgdGFibGUgbmFtZSBiZWluZyBpbXBvcnRlZAorICAgICAqIDwvbGk+CisgICAgICogPGxpPntAY29kZSBQS0NPTFVNTl9OQU1FfSAtIFN0cmluZyAtIHByaW1hcnkga2V5IGNvbHVtbiBuYW1lIGJlaW5nCisgICAgICogaW1wb3J0ZWQ8L2xpPgorICAgICAqIDxsaT57QGNvZGUgRktUQUJMRV9DQVR9IC0gU3RyaW5nIC0gZm9yZWlnbiBrZXkgdGFibGUgY2F0YWxvZyBuYW1lCisgICAgICogKHBvc3NpYmx5IHtAY29kZSBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgRktUQUJMRV9TQ0hFTX0gLSBTdHJpbmcgLSBmb3JlaWduIGtleSB0YWJsZSBzY2hlbWEgbmFtZQorICAgICAqIChwb3NzaWJseSB7QGNvZGUgbnVsbH0pPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIEZLVEFCTEVfTkFNRX0gLSBTdHJpbmcgLSBmb3JlaWduIGtleSB0YWJsZSBuYW1lPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIEZLQ09MVU1OX05BTUV9IC0gU3RyaW5nIC0gZm9yZWlnbiBrZXkgY29sdW1uIG5hbWU8L2xpPgorICAgICAqIDxsaT57QGNvZGUgS0VZX1NFUX0gLSBzaG9ydCAtIHNlcXVlbmNlIG51bWJlciAoaW4gdGhlIGZvcmVpZ24ga2V5KTwvbGk+CisgICAgICogPGxpPntAY29kZSBVUERBVEVfUlVMRX0gLSBzaG9ydCAtIGhvdyB0byB0cmVhdCB0aGUgZm9yZWlnbiBrZXkgd2hlbiB0aGUgY29ycmVzcG9uZGluZyBwcmltYXJ5CisgICAgICoga2V5IGlzIHVwZGF0ZWQ6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgRGF0YWJhc2VNZXRhRGF0YS5pbXBvcnRlZEtleU5vQWN0aW9ufSAtIGRvbid0IGFsbG93IGFueSB1cGRhdGUgb2YKKyAgICAgKiB0aGUgcHJpbWFyeSBrZXkgaWYgaXQgaXMgaW1wb3J0ZWQgYXMgYSBmb3JlaWduIGtleTwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5Q2FzY2FkZX0gLSBjaGFuZ2UgaW1wb3J0ZWQga2V5IHRvCisgICAgICogbWF0Y2ggdGhlIHByaW1hcnkga2V5IHVwZGF0ZTwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5U2V0TnVsbH0gLSBzZXQgdGhlIGltcG9ydGVkIGtleSB0bworICAgICAqIHtAY29kZSBudWxsfTwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5U2V0RGVmYXVsdH0gLSBzZXQgdGhlIGltcG9ydGVkIGtleQorICAgICAqIHRvIGl0cyBkZWZhdWx0IHZhbHVlPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuaW1wb3J0ZWRLZXlSZXN0cmljdH0gLSBzYW1lIGFzCisgICAgICogaW1wb3J0ZWRLZXlOb0FjdGlvbjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT57QGNvZGUgREVMRVRFX1JVTEV9IC0gc2hvcnQgLSBob3cgdG8gdHJlYXQgdGhlIGZvcmVpZ24ga2V5IHdoZW4gdGhlIGNvcnJlc3BvbmRpbmcgcHJpbWFyeQorICAgICAqIGtleSBpcyBkZWxldGVkOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuaW1wb3J0ZWRLZXlOb0FjdGlvbn0gLSBkb24ndCBhbGxvdyB0aGUgcHJpbWFyeSBrZXkgdG8gYmUgZGVsZXRlZAorICAgICAqIGlmIGl0IGlzIGltcG9ydGVkIGFzIGEgZm9yZWlnbiBrZXk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgRGF0YWJhc2VNZXRhRGF0YS5pbXBvcnRlZEtleUNhc2NhZGV9IC0gZGVsZXRlIHRob3NlIHJvd3MgdGhhdAorICAgICAqIGltcG9ydCBhIGRlbGV0ZWQga2V5PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuaW1wb3J0ZWRLZXlTZXROdWxsfSAtIHNldCB0aGUgaW1wb3J0ZWQga2V5IHRvCisgICAgICoge0Bjb2RlIG51bGx9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuaW1wb3J0ZWRLZXlTZXREZWZhdWx0fSAtIHNldCB0aGUgaW1wb3J0ZWQga2V5CisgICAgICogdG8gaXRzIGRlZmF1bHQgdmFsdWU8L2xpPgorICAgICAqIDxsaT57QGNvZGUgRGF0YWJhc2VNZXRhRGF0YS5pbXBvcnRlZEtleVJlc3RyaWN0fSAtIHNhbWUgYXMge0Bjb2RlCisgICAgICogaW1wb3J0ZWRLZXlOb0FjdGlvbn08L2xpPgorICAgICAqIDwvdWw+CisgICAgICogPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIEZLX05BTUV9IC0gU3RyaW5nIC0gZm9yZWlnbiBrZXkgbmFtZSAocG9zc2libHkge0Bjb2RlIG51bGx9KTwvbGk+CisgICAgICogPGxpPntAY29kZSBQS19OQU1FfSAtIFN0cmluZyAtIHByaW1hcnkga2V5IG5hbWUgKHBvc3NpYmx5IHtAY29kZSBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgREVGRVJSQUJJTElUWX0gLSBzaG9ydCAtIGRlZmluZXMgd2hldGhlciBmb3JlaWduIGtleQorICAgICAqIGNvbnN0cmFpbnRzIGNhbiBiZSBkZWZlcnJlZCB1bnRpbCBjb21taXQgKHNlZSBTUUw5MiBzcGVjaWZpY2F0aW9uIGZvcgorICAgICAqIGRlZmluaXRpb25zKToKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5SW5pdGlhbGx5RGVmZXJyZWR9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuaW1wb3J0ZWRLZXlJbml0aWFsbHlJbW1lZGlhdGV9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuaW1wb3J0ZWRLZXlOb3REZWZlcnJhYmxlfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiA8L2xpPgorICAgICAqIDwvb2w+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F0YWxvZworICAgICAqICAgICAgICAgICAgYSBjYXRhbG9nIG5hbWUuIHtAY29kZSBudWxsfSBpcyB1c2VkIHRvIGltcGx5IG5vIG5hcnJvd2luZyBvZgorICAgICAqICAgICAgICAgICAgdGhlIHNlYXJjaCBieSBjYXRhbG9nIG5hbWUuIE90aGVyd2lzZSwgdGhlIG5hbWUgbXVzdCBtYXRjaCBhCisgICAgICogICAgICAgICAgICBjYXRhbG9nIG5hbWUgaGVsZCBpbiB0aGUgZGF0YWJhc2UsIHdpdGggIiIgdXNlZCB0byByZXRyaWV2ZQorICAgICAqICAgICAgICAgICAgdGhvc2Ugd2l0aG91dCBhIGNhdGFsb2cgbmFtZS4KKyAgICAgKiBAcGFyYW0gc2NoZW1hCisgICAgICogICAgICAgICAgICBhIHNjaGVtYSBuYW1lLiB7QGNvZGUgbnVsbH0gaXMgdXNlZCB0byBpbXBseSBubyBuYXJyb3dpbmcgb2YKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWFyY2ggYnkgc2NoZW1hIG5hbWUuIE90aGVyd2lzZSwgdGhlIG5hbWUgbXVzdCBtYXRjaCBhCisgICAgICogICAgICAgICAgICBzY2hlbWEgbmFtZSBpbiB0aGUgZGF0YWJhc2UsIHdpdGggIiIgdXNlZCB0byByZXRyaWV2ZSB0aG9zZQorICAgICAqICAgICAgICAgICAgd2l0aG91dCBhIHNjaGVtYSBuYW1lLgorICAgICAqIEBwYXJhbSB0YWJsZQorICAgICAqICAgICAgICAgICAgYSB0YWJsZSBuYW1lLCB3aGljaCBtdXN0IG1hdGNoIHRoZSBuYW1lIG9mIGEgdGFibGUgaW4gdGhlCisgICAgICogICAgICAgICAgICBkYXRhYmFzZS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFJlc3VsdFNldH0gY29udGFpbmluZyB0aGUgbGlzdCBvZiBwcmltYXJ5IGtleSBjb2x1bW5zIGFzCisgICAgICogICAgICAgICByb3dzIGluIHRoZSBmb3JtYXQgZGVmaW5lZCBhYm92ZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIFJlc3VsdFNldCBnZXRJbXBvcnRlZEtleXMoU3RyaW5nIGNhdGFsb2csIFN0cmluZyBzY2hlbWEsIFN0cmluZyB0YWJsZSkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBpbmRpY2VzIGFuZCBzdGF0aXN0aWNzIGZvciBhIHNwZWNpZmllZCB0YWJsZS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbGlzdCBpcyByZXR1cm5lZCBhcyBhIHtAY29kZSBSZXN1bHRTZXR9LCB3aXRoIG9uZSByb3cgZm9yIGVhY2ggaW5kZXgKKyAgICAgKiBvciBzdGF0aXN0aWMuIFRoZSBsaXN0IGlzIG9yZGVyZWQgYnkge0Bjb2RlIE5PTl9VTklRVUV9LCB7QGNvZGUgVFlQRX0sCisgICAgICoge0Bjb2RlIElOREVYX05BTUV9LCBhbmQge0Bjb2RlIE9SRElOQUxfUE9TSVRJT059LiBFYWNoIHJvdyBoYXMgdGhlCisgICAgICogZm9sbG93aW5nIGZvcm1hdDoKKyAgICAgKiA8b2w+CisgICAgICogPGxpPntAY29kZSBUQUJMRV9DQVR9IC0gU3RyaW5nIC0gdGFibGUgY2F0YWxvZyBuYW1lIChwb3NzaWJseSB7QGNvZGUKKyAgICAgKiBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgVEFCTEVfU0NIRU19IC0gU3RyaW5nIC0gdGFibGUgc2NoZW1hIG5hbWUgKHBvc3NpYmx5IHtAY29kZQorICAgICAqIG51bGx9KTwvbGk+CisgICAgICogPGxpPntAY29kZSBUQUJMRV9OQU1FfSAtIFN0cmluZyAtIFRoZSB0YWJsZSBuYW1lPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIE5PTl9VTklRVUV9IC0gYm9vbGVhbiAtIHtAY29kZSB0cnVlfSB3aGVuIGluZGV4IHZhbHVlcyBjYW4gYmUKKyAgICAgKiBub24tdW5pcXVlLiBNdXN0IGJlIHtAY29kZSBmYWxzZX0gd2hlbiB0aGUgVFlQRSBpcyB0YWJsZUluZGV4U3RhdGlzdGljPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIElOREVYX1FVQUxJRklFUn0gLSBTdHJpbmcgOiBpbmRleCBjYXRhbG9nIG5hbWUuIHtAY29kZSBudWxsfQorICAgICAqIHdoZW4gdGhlIFRZUEUgaXMgJ3RhYmxlSW5kZXhTdGF0aXN0aWMnPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIElOREVYX05BTUV9IC0gU3RyaW5nIDogaW5kZXggbmFtZS4ge0Bjb2RlIG51bGx9IHdoZW4gVFlQRSBpcworICAgICAqICd0YWJsZUluZGV4U3RhdGlzdGljJzwvbGk+CisgICAgICogPGxpPntAY29kZSBUWVBFfSAtIHNob3J0IC0gdGhlIGluZGV4IHR5cGUuIE9uZSBvZjoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLnRhYmxlSW5kZXhTdGF0aXN0aWN9IC0gdGFibGUgc3RhdGlzdGljcworICAgICAqIHJldHVybmVkIHdpdGggSW5kZXggZGVzY3JpcHRpb25zPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEudGFibGVJbmRleENsdXN0ZXJlZH0gLSBhIGNsdXN0ZXJlZCBJbmRleDwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLnRhYmxlSW5kZXhIYXNoZWR9IC0gYSBoYXNoZWQgSW5kZXg8L2xpPgorICAgICAqIDxsaT57QGNvZGUgRGF0YWJhc2VNZXRhRGF0YS50YWJsZUluZGV4T3RoZXJ9IC0gb3RoZXIgc3R5bGUgb2YgSW5kZXg8L2xpPgorICAgICAqIDwvdWw+CisgICAgICogPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIE9SRElOQUxfUE9TSVRJT059IC0gc2hvcnQgLSBjb2x1bW4gc2VxdWVuY2Ugd2l0aGluIEluZGV4LiAwCisgICAgICogd2hlbiBUWVBFIGlzIHRhYmxlSW5kZXhTdGF0aXN0aWM8L2xpPgorICAgICAqIDxsaT57QGNvZGUgQ09MVU1OX05BTUV9IC0gU3RyaW5nIC0gdGhlIGNvbHVtbiBuYW1lLiB7QGNvZGUgbnVsbH0gd2hlbgorICAgICAqIFRZUEUgaXMgdGFibGVJbmRleFN0YXRpc3RpYzwvbGk+CisgICAgICogPGxpPntAY29kZSBBU0NfT1JfREVTQ30gLSBTdHJpbmcgLSBjb2x1bW4gc29ydCBzZXF1ZW5jZS4ge0Bjb2RlIG51bGx9IGlmCisgICAgICogc2VxdWVuY2luZyBub3Qgc3VwcG9ydGVkIG9yIFRZUEUgaXMgdGFibGVJbmRleFN0YXRpc3RpYzsgb3RoZXJ3aXNlICJBIgorICAgICAqIG1lYW5zIHNvcnQgYXNjZW5kaW5nIGFuZCAiRCIgbWVhbnMgc29ydCBkZXNjZW5kaW5nLjwvbGk+CisgICAgICogPGxpPntAY29kZSBDQVJESU5BTElUWX0gLSBpbnQgLSBOdW1iZXIgb2YgdW5pcXVlIHZhbHVlcyBpbiB0aGUgSW5kZXguIElmCisgICAgICogVFlQRSBpcyB0YWJsZUluZGV4U3RhdGlzdGljLCB0aGlzIGlzIG51bWJlciBvZiByb3dzIGluIHRoZSB0YWJsZS48L2xpPgorICAgICAqIDxsaT57QGNvZGUgUEFHRVN9IC0gaW50IC0gTnVtYmVyIG9mIHBhZ2VzIGZvciBjdXJyZW50IEluZGV4LiBJZiBUWVBFIGlzCisgICAgICogdGFibGVJbmRleFN0YXRpc3RpYywgdGhpcyBpcyBudW1iZXIgb2YgcGFnZXMgdXNlZCBmb3IgdGhlIHRhYmxlLjwvbGk+CisgICAgICogPGxpPntAY29kZSBGSUxURVJfQ09ORElUSU9OfSAtIFN0cmluZyAtIEZpbHRlciBjb25kaXRpb24uIChwb3NzaWJseSBudWxsKQorICAgICAqIDwvbGk+CisgICAgICogPC9vbD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXRhbG9nCisgICAgICogICAgICAgICAgICBhIGNhdGFsb2cgbmFtZS4ge0Bjb2RlIG51bGx9IGlzIHVzZWQgdG8gaW1wbHkgbm8gbmFycm93aW5nIG9mCisgICAgICogICAgICAgICAgICB0aGUgc2VhcmNoIGJ5IGNhdGFsb2cgbmFtZS4gT3RoZXJ3aXNlLCB0aGUgbmFtZSBtdXN0IG1hdGNoIGEKKyAgICAgKiAgICAgICAgICAgIGNhdGFsb2cgbmFtZSBoZWxkIGluIHRoZSBkYXRhYmFzZSwgd2l0aCAiIiB1c2VkIHRvIHJldHJpZXZlCisgICAgICogICAgICAgICAgICB0aG9zZSB3aXRob3V0IGEgY2F0YWxvZyBuYW1lLgorICAgICAqIEBwYXJhbSBzY2hlbWEKKyAgICAgKiAgICAgICAgICAgIGEgc2NoZW1hIG5hbWUuIHtAY29kZSBudWxsfSBpcyB1c2VkIHRvIGltcGx5IG5vIG5hcnJvd2luZyBvZgorICAgICAqICAgICAgICAgICAgdGhlIHNlYXJjaCBieSBzY2hlbWEgbmFtZS4gT3RoZXJ3aXNlLCB0aGUgbmFtZSBtdXN0IG1hdGNoIGEKKyAgICAgKiAgICAgICAgICAgIHNjaGVtYSBuYW1lIGluIHRoZSBkYXRhYmFzZSwgd2l0aCAiIiB1c2VkIHRvIHJldHJpZXZlIHRob3NlCisgICAgICogICAgICAgICAgICB3aXRob3V0IGEgc2NoZW1hIG5hbWUuCisgICAgICogQHBhcmFtIHRhYmxlCisgICAgICogICAgICAgICAgICBhIHRhYmxlIG5hbWUsIHdoaWNoIG11c3QgbWF0Y2ggdGhlIG5hbWUgb2YgYSB0YWJsZSBpbiB0aGUKKyAgICAgKiAgICAgICAgICAgIGRhdGFiYXNlLgorICAgICAqIEBwYXJhbSB1bmlxdWUKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSB0cnVlfSBtZWFucyBvbmx5IHJldHVybiBpbmRpY2VzIGZvciB1bmlxdWUgdmFsdWVzLAorICAgICAqICAgICAgICAgICAge0Bjb2RlIGZhbHNlfSBpbXBsaWVzIHRoYXQgdGhleSBjYW4gYmUgcmV0dXJuZWQgZXZlbiBpZiBub3QKKyAgICAgKiAgICAgICAgICAgIHVuaXF1ZS4KKyAgICAgKiBAcGFyYW0gYXBwcm94aW1hdGUKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSB0cnVlfSBpbXBsaWVzIHRoYXQgdGhlIGxpc3QgY2FuIGNvbnRhaW4gYXBwcm94aW1hdGUgb3IKKyAgICAgKiAgICAgICAgICAgICJvdXQgb2YgZGF0YSIgdmFsdWVzLCB7QGNvZGUgZmFsc2V9IGltcGxpZXMgdGhhdCBhbGwgdmFsdWVzCisgICAgICogICAgICAgICAgICBtdXN0IGJlIHByZWNpc2VseSBhY2N1cmF0ZQorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgUmVzdWx0U2V0fSBjb250YWluaW5nIHRoZSBsaXN0IG9mIGluZGljZXMgYW5kIHN0YXRpc3RpY3MKKyAgICAgKiAgICAgICAgIGZvciB0aGUgdGFibGUsIGluIHRoZSBmb3JtYXQgZGVmaW5lZCBhYm92ZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIFJlc3VsdFNldCBnZXRJbmRleEluZm8oU3RyaW5nIGNhdGFsb2csIFN0cmluZyBzY2hlbWEsIFN0cmluZyB0YWJsZSwKKyAgICAgICAgICAgIGJvb2xlYW4gdW5pcXVlLCBib29sZWFuIGFwcHJveGltYXRlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIGRyaXZlcidzIG1ham9yIEpEQkMgdmVyc2lvbiBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtYWpvciBKREJDIHZlcnNpb24gbnVtYmVyLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEpEQkNNYWpvclZlcnNpb24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbWlub3IgSkRCQyB2ZXJzaW9uIG51bWJlciBmb3IgdGhpcyBkcml2ZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBNaW5vciBKREJDIFZlcnNpb24gTnVtYmVyLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEpEQkNNaW5vclZlcnNpb24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0IHRoZSBtYXhpbXVtIG51bWJlciBvZiBoZXggY2hhcmFjdGVycyBpbiBhbiBpbi1saW5lIGJpbmFyeSBsaXRlcmFsIGZvcgorICAgICAqIHRoaXMgZGF0YWJhc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIG51bWJlciBvZiBoZXggY2hhcmFjdGVycyBpbiBhbiBpbi1saW5lIGJpbmFyeQorICAgICAqICAgICAgICAgbGl0ZXJhbC4gSWYgdGhlIG51bWJlciBpcyB1bmxpbWl0ZWQgdGhlbiB0aGUgcmVzdWx0IGlzIHplcm8uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWF4QmluYXJ5TGl0ZXJhbExlbmd0aCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIHNpemUgb2YgYSBjYXRhbG9nIG5hbWUgaW4gdGhpcyBkYXRhYmFzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gc2l6ZSBpbiBjaGFyYWN0ZXJzIGZvciBhIGNhdGFsb2cgbmFtZS4gSWYgdGhlIGxpbWl0CisgICAgICogICAgICAgICBpcyB1bmtub3duLCBvciB0aGUgdmFsdWUgaXMgdW5saW1pdGVkLCB0aGVuIHRoZSByZXN1bHQgaXMgemVyby4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNYXhDYXRhbG9nTmFtZUxlbmd0aCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIHNpemUgZm9yIGEgY2hhcmFjdGVyIGxpdGVyYWwgaW4gdGhpcyBkYXRhYmFzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gc2l6ZSBpbiBjaGFyYWN0ZXJzIGZvciBhIGNoYXJhY3RlciBsaXRlcmFsLiBJZiB0aGUKKyAgICAgKiAgICAgICAgIGxpbWl0IGlzIHVua25vd24sIG9yIHRoZSB2YWx1ZSBpcyB1bmxpbWl0ZWQsIHRoZW4gdGhlIHJlc3VsdCBpcworICAgICAqICAgICAgICAgemVyby4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNYXhDaGFyTGl0ZXJhbExlbmd0aCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIHNpemUgZm9yIGEgQ29sdW1uIG5hbWUgZm9yIHRoaXMgZGF0YWJhc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIGZvciBhIENvbHVtbiBuYW1lLiBJZiB0aGUgbGltaXQKKyAgICAgKiAgICAgICAgIGlzIHVua25vd24sIG9yIHRoZSB2YWx1ZSBpcyB1bmxpbWl0ZWQsIHRoZW4gdGhlIHJlc3VsdCBpcyB6ZXJvLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1heENvbHVtbk5hbWVMZW5ndGgoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0IHRoZSBtYXhpbXVtIG51bWJlciBvZiBjb2x1bW5zIGluIGEge0Bjb2RlIEdST1VQIEJZfSBjbGF1c2UgZm9yIHRoaXMKKyAgICAgKiBkYXRhYmFzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gbnVtYmVyIG9mIGNvbHVtbnMgaW4gYSB7QGNvZGUgR1JPVVAgQll9IGNsYXVzZS4gSWYKKyAgICAgKiAgICAgICAgIHRoZSBsaW1pdCBpcyB1bmtub3duLCBvciB0aGUgdmFsdWUgaXMgdW5saW1pdGVkLCB0aGVuIHRoZSByZXN1bHQKKyAgICAgKiAgICAgICAgIGlzIHplcm8uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWF4Q29sdW1uc0luR3JvdXBCeSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjb2x1bW5zIGluIGFuIEluZGV4IGZvciB0aGlzIGRhdGFiYXNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBudW1iZXIgb2YgY29sdW1ucyBpbiBhbiBJbmRleC4gSWYgdGhlIGxpbWl0IGlzCisgICAgICogICAgICAgICB1bmtub3duLCBvciB0aGUgdmFsdWUgaXMgdW5saW1pdGVkLCB0aGVuIHRoZSByZXN1bHQgaXMgemVyby4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNYXhDb2x1bW5zSW5JbmRleCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjb2x1bW5zIGluIGFuIHtAY29kZSBPUkRFUiBCWX0gY2xhdXNlIGZvcgorICAgICAqIHRoaXMgZGF0YWJhc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjb2x1bW5zIGluIGFuIHtAY29kZSBPUkRFUiBCWX0gY2xhdXNlLiBJZgorICAgICAqICAgICAgICAgdGhlIGxpbWl0IGlzIHVua25vd24sIG9yIHRoZSB2YWx1ZSBpcyB1bmxpbWl0ZWQsIHRoZW4gdGhlIHJlc3VsdAorICAgICAqICAgICAgICAgaXMgemVyby4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNYXhDb2x1bW5zSW5PcmRlckJ5KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNvbHVtbnMgaW4gYSB7QGNvZGUgU0VMRUNUfSBsaXN0IGZvciB0aGlzCisgICAgICogZGF0YWJhc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjb2x1bW5zIGluIGEge0Bjb2RlIFNFTEVDVH0gbGlzdC4gSWYgdGhlCisgICAgICogICAgICAgICBsaW1pdCBpcyB1bmtub3duLCBvciB0aGUgdmFsdWUgaXMgdW5saW1pdGVkLCB0aGVuIHRoZSByZXN1bHQgaXMKKyAgICAgKiAgICAgICAgIHplcm8uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWF4Q29sdW1uc0luU2VsZWN0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNvbHVtbnMgaW4gYSB0YWJsZSBmb3IgdGhpcyBkYXRhYmFzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gbnVtYmVyIG9mIGNvbHVtbnMgaW4gYSB0YWJsZS4gSWYgdGhlIGxpbWl0IGlzCisgICAgICogICAgICAgICB1bmtub3duLCBvciB0aGUgdmFsdWUgaXMgdW5saW1pdGVkLCB0aGVuIHRoZSByZXN1bHQgaXMgemVyby4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNYXhDb2x1bW5zSW5UYWJsZSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkYXRhYmFzZSdzIG1heGltdW0gbnVtYmVyIG9mIGNvbmN1cnJlbnQgY29ubmVjdGlvbnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjb25uZWN0aW9ucy4gSWYgdGhlIGxpbWl0IGlzIHVua25vd24sIG9yCisgICAgICogICAgICAgICB0aGUgdmFsdWUgaXMgdW5saW1pdGVkLCB0aGVuIHRoZSByZXN1bHQgaXMgemVyby4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNYXhDb25uZWN0aW9ucygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhIGN1cnNvciBuYW1lIGZvciB0aGlzIGRhdGFiYXNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiBhIGN1cnNvciBuYW1lLiBJZiB0aGUgbGltaXQKKyAgICAgKiAgICAgICAgIGlzIHVua25vd24sIG9yIHRoZSB2YWx1ZSBpcyB1bmxpbWl0ZWQsIHRoZW4gdGhlIHJlc3VsdCBpcyB6ZXJvLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1heEN1cnNvck5hbWVMZW5ndGgoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbWF4aW11bSBsZW5ndGggaW4gYnl0ZXMgZm9yIGFuIEluZGV4IGZvciB0aGlzIGRhdGFiYXNlLiBUaGlzCisgICAgICogY292ZXJzIGFsbCB0aGUgcGFydHMgb2YgYSBjb21wb3NpdGUgaW5kZXguCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIGxlbmd0aCBpbiBieXRlcyBmb3IgYW4gSW5kZXguIElmIHRoZSBsaW1pdCBpcworICAgICAqICAgICAgICAgdW5rbm93biwgb3IgdGhlIHZhbHVlIGlzIHVubGltaXRlZCwgdGhlbiB0aGUgcmVzdWx0IGlzIHplcm8uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWF4SW5kZXhMZW5ndGgoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyBmb3IgYSBwcm9jZWR1cmUgbmFtZSBpbiB0aGlzCisgICAgICogZGF0YWJhc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXIgZm9yIGEgcHJvY2VkdXJlIG5hbWUuIElmIHRoZQorICAgICAqICAgICAgICAgbGltaXQgaXMgdW5rbm93biwgb3IgdGhlIHZhbHVlIGlzIHVubGltaXRlZCwgdGhlbiB0aGUgcmVzdWx0IGlzCisgICAgICogICAgICAgICB6ZXJvLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1heFByb2NlZHVyZU5hbWVMZW5ndGgoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgd2l0aGluIGEgc2luZ2xlIHJvdyBmb3IgdGhpcworICAgICAqIGRhdGFiYXNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgZm9yIGEgc2luZ2xlIHJvdy4gSWYgdGhlIGxpbWl0IGlzCisgICAgICogICAgICAgICB1bmtub3duLCBvciB0aGUgdmFsdWUgaXMgdW5saW1pdGVkLCB0aGVuIHRoZSByZXN1bHQgaXMgemVyby4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNYXhSb3dTaXplKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gYSBzY2hlbWEgbmFtZSBmb3IgdGhpcworICAgICAqIGRhdGFiYXNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiBhIHNjaGVtYSBuYW1lLiBJZiB0aGUgbGltaXQKKyAgICAgKiAgICAgICAgIGlzIHVua25vd24sIG9yIHRoZSB2YWx1ZSBpcyB1bmxpbWl0ZWQsIHRoZW4gdGhlIHJlc3VsdCBpcyB6ZXJvLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1heFNjaGVtYU5hbWVMZW5ndGgoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiBhbiBTUUwgc3RhdGVtZW50IGZvciB0aGlzCisgICAgICogZGF0YWJhc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIGFuIFNRTCBzdGF0ZW1lbnQuIElmIHRoZQorICAgICAqICAgICAgICAgbGltaXQgaXMgdW5rbm93biwgb3IgdGhlIHZhbHVlIGlzIHVubGltaXRlZCwgdGhlbiB0aGUgcmVzdWx0IGlzCisgICAgICogICAgICAgICB6ZXJvLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1heFN0YXRlbWVudExlbmd0aCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG1heGltdW0gbnVtYmVyIG9mIHNpbXVsdGFuZW91c2x5IG9wZW4gYWN0aXZlIHN0YXRlbWVudHMgZm9yIHRoaXMKKyAgICAgKiBkYXRhYmFzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gbnVtYmVyIG9mIG9wZW4gYWN0aXZlIHN0YXRlbWVudHMuIElmIHRoZSBsaW1pdCBpcworICAgICAqICAgICAgICAgdW5rbm93biwgb3IgdGhlIHZhbHVlIGlzIHVubGltaXRlZCwgdGhlbiB0aGUgcmVzdWx0IGlzIHplcm8uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWF4U3RhdGVtZW50cygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIHNpemUgZm9yIGEgdGFibGUgbmFtZSBpbiB0aGUgZGF0YWJhc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIHNpemUgaW4gY2hhcmFjdGVycyBmb3IgYSB0YWJsZSBuYW1lLiBJZiB0aGUgbGltaXQgaXMKKyAgICAgKiAgICAgICAgIHVua25vd24sIG9yIHRoZSB2YWx1ZSBpcyB1bmxpbWl0ZWQsIHRoZW4gdGhlIHJlc3VsdCBpcyB6ZXJvLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1heFRhYmxlTmFtZUxlbmd0aCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIG51bWJlciBvZiB0YWJsZXMgcGVybWl0dGVkIGluIGEge0Bjb2RlIFNFTEVDVH0KKyAgICAgKiBzdGF0ZW1lbnQgZm9yIHRoZSBkYXRhYmFzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gbnVtYmVyIG9mIHRhYmxlcyBwZXJtaXR0ZWQgaW4gYSB7QGNvZGUgU0VMRUNUfQorICAgICAqICAgICAgICAgc3RhdGVtZW50LiBJZiB0aGUgbGltaXQgaXMgdW5rbm93biwgb3IgdGhlIHZhbHVlIGlzIHVubGltaXRlZCwKKyAgICAgKiAgICAgICAgIHRoZW4gdGhlIHJlc3VsdCBpcyB6ZXJvLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1heFRhYmxlc0luU2VsZWN0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gYSB1c2VyIG5hbWUgZm9yIHRoZSBkYXRhYmFzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gYSB1c2VyIG5hbWUuIElmIHRoZSBsaW1pdCBpcworICAgICAqICAgICAgICAgdW5rbm93biwgb3IgdGhlIHZhbHVlIGlzIHVubGltaXRlZCwgdGhlbiB0aGUgcmVzdWx0IGlzIHplcm8uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWF4VXNlck5hbWVMZW5ndGgoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGxpc3Qgb2YgdGhlIG1hdGggZnVuY3Rpb25zIGF2YWlsYWJsZSB3aXRoIHRoaXMgZGF0YWJhc2UuIFRoZXNlCisgICAgICogYXJlIHVzZWQgaW4gdGhlIEpEQkMgZnVuY3Rpb24gZXNjYXBlIGNsYXVzZSBhbmQgYXJlIHRoZSBPcGVuIEdyb3VwIENMSQorICAgICAqIG1hdGggZnVuY3Rpb24gbmFtZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgU3RyaW5nIHdoaWNoIGNvbnRhaW5zIHRoZSBsaXN0IG9mIG1hdGggZnVuY3Rpb25zIGFzIGEgY29tbWEKKyAgICAgKiAgICAgICAgIHNlcGFyYXRlZCBsaXN0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE51bWVyaWNGdW5jdGlvbnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGxpc3Qgb2YgdGhlIHByaW1hcnkga2V5IGNvbHVtbnMgb2YgYSBzcGVjaWZpZWQgdGFibGUuCisgICAgICogPHA+CisgICAgICogVGhlIGxpc3QgaXMgcmV0dXJuZWQgYXMgYSB7QGNvZGUgUmVzdWx0U2V0fSB3aXRoIG9uZSByb3cgZm9yIGVhY2ggcHJpbWFyeQorICAgICAqIGtleSBjb2x1bW4sIG9yZGVyZWQgYnkge0Bjb2RlIENPTFVNTl9OQU1FfSwgd2l0aCBlYWNoIHJvdyBoYXZpbmcgdGhlCisgICAgICogc3RydWN0dXJlIGFzIGZvbGxvd3M6CisgICAgICogPG9sPgorICAgICAqIDxsaT57QGNvZGUgVEFCTEVfQ0FUfSAtIFN0cmluZyAtIHRhYmxlIGNhdGFsb2cgbmFtZSAocG9zc2libHkgbnVsbCk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgVEFCTEVfU0NIRU19IC0gU3RyaW5nIC0gdGFibGUgc2NoZW1hIG5hbWUgKHBvc3NpYmx5IG51bGwpPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFRBQkxFX05BTUV9IC0gU3RyaW5nIC0gVGhlIHRhYmxlIG5hbWU8L2xpPgorICAgICAqIDxsaT57QGNvZGUgQ09MVU1OX05BTUV9IC0gU3RyaW5nIC0gVGhlIGNvbHVtbiBuYW1lPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIEtFWV9TRVF9IC0gc2hvcnQgLSB0aGUgc2VxdWVuY2UgbnVtYmVyIGZvciB0aGlzIGNvbHVtbiBpbiB0aGUKKyAgICAgKiBwcmltYXJ5IGtleTwvbGk+CisgICAgICogPGxpPntAY29kZSBQS19OQU1FfSAtIFN0cmluZyAtIHRoZSBwcmltYXJ5IGtleSBuYW1lIChwb3NzaWJseSBudWxsKTwvbGk+CisgICAgICogPC9vbD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXRhbG9nCisgICAgICogICAgICAgICAgICBhIGNhdGFsb2cgbmFtZS4ge0Bjb2RlIG51bGx9IGlzIHVzZWQgdG8gaW1wbHkgbm8gbmFycm93aW5nIG9mCisgICAgICogICAgICAgICAgICB0aGUgc2VhcmNoIGJ5IGNhdGFsb2cgbmFtZS4gT3RoZXJ3aXNlLCB0aGUgbmFtZSBtdXN0IG1hdGNoIGEKKyAgICAgKiAgICAgICAgICAgIGNhdGFsb2cgbmFtZSBoZWxkIGluIHRoZSBkYXRhYmFzZSwgd2l0aCB0aGUgZW1wdHkgc3RyaW5nIHVzZWQKKyAgICAgKiAgICAgICAgICAgIHRvIHJldHJpZXZlIHRob3NlIHdpdGhvdXQgYSBjYXRhbG9nIG5hbWUuCisgICAgICogQHBhcmFtIHNjaGVtYQorICAgICAqICAgICAgICAgICAgYSBzY2hlbWEgbmFtZS4ge0Bjb2RlIG51bGx9IGlzIHVzZWQgdG8gaW1wbHkgbm8gbmFycm93aW5nIG9mCisgICAgICogICAgICAgICAgICB0aGUgc2VhcmNoIGJ5IHNjaGVtYSBuYW1lLiBPdGhlcndpc2UsIHRoZSBuYW1lIG11c3QgbWF0Y2ggYQorICAgICAqICAgICAgICAgICAgc2NoZW1hIG5hbWUgaW4gdGhlIGRhdGFiYXNlLCB3aXRoIHRoZSBlbXB0eSBzdHJpbmcgdXNlZCB0bworICAgICAqICAgICAgICAgICAgcmV0cmlldmUgdGhvc2Ugd2l0aG91dCBhIHNjaGVtYSBuYW1lLgorICAgICAqIEBwYXJhbSB0YWJsZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgYSB0YWJsZSwgd2hpY2ggbXVzdCBtYXRjaCB0aGUgbmFtZSBvZiBhIHRhYmxlIGluCisgICAgICogICAgICAgICAgICB0aGUgZGF0YWJhc2UuCisgICAgICogQHJldHVybiBhIHtAY29kZSBSZXN1bHRTZXR9IGNvbnRhaW5pbmcgdGhlIGxpc3Qgb2Yga2V5cyBpbiB0aGUgZm9ybWF0CisgICAgICogICAgICAgICBkZWZpbmVkIGFib3ZlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzdWx0U2V0IGdldFByaW1hcnlLZXlzKFN0cmluZyBjYXRhbG9nLCBTdHJpbmcgc2NoZW1hLCBTdHJpbmcgdGFibGUpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGxpc3Qgb2YgcGFyYW1ldGVyIGFuZCByZXN1bHQgY29sdW1ucyBmb3IgdGhlIHN0b3JlZCBwcm9jZWR1cmVzCisgICAgICogYmVsb25naW5nIHRvIGEgc3BlY2lmaWVkIGNhdGFsb2cuCisgICAgICogPHA+CisgICAgICogVGhlIGxpc3QgaXMgcmV0dXJuZWQgYXMgYSB7QGNvZGUgUmVzdWx0U2V0fSB3aXRoIG9uZSByb3cgZm9yIGVhY2gKKyAgICAgKiBwYXJhbWV0ZXIgb3IgcmVzdWx0IGNvbHVtbi4gVGhlIGRhdGEgaXMgb3JkZXJlZCBieSB7QGNvZGUKKyAgICAgKiBQUk9DRURVUkVfU0NIRU19IGFuZCB7QGNvZGUgUFJPQ0VEVVJFX05BTUV9LCB3aGlsZSBmb3IgZWFjaCBwcm9jZWR1cmUsCisgICAgICogdGhlIHJldHVybiB2YWx1ZSAoaWYgYW55KSBpcyBmaXJzdCwgZm9sbG93ZWQgYnkgdGhlIHBhcmFtZXRlcnMgaW4gdGhlCisgICAgICogb3JkZXIgdGhleSBhcHBlYXIgaW4gdGhlIHN0b3JlZCBwcm9jZWR1cmUgY2FsbCwgZm9sbG93ZWQgYnkge0Bjb2RlCisgICAgICogUmVzdWx0U2V0fSBjb2x1bW5zIGluIGNvbHVtbiBudW1iZXIgb3JkZXIuIEVhY2ggcm93IGhhcyB0aGUgZm9sbG93aW5nCisgICAgICogc3RydWN0dXJlOgorICAgICAqIDxvbD4KKyAgICAgKiA8bGk+e0Bjb2RlIFBST0NFRFVSRV9DQVR9IC0gU3RyaW5nIC0gdGhlIHByb2NlZHVyZSBjYXRhbG9nIG5hbWU8L2xpPgorICAgICAqIDxsaT57QGNvZGUgUFJPQ0VEVVJFX1NDSEVNfSAtIFN0cmluZyAtIHRoZSBwcm9jZWR1cmUgc2NoZW1hIG5hbWUKKyAgICAgKiAocG9zc2libHkgbnVsbCk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgUFJPQ0VEVVJFX05BTUV9IC0gU3RyaW5nIC0gdGhlIHByb2NlZHVyZSBuYW1lPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIENPTFVNTl9OQU1FfSAtIFN0cmluZyAtIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW48L2xpPgorICAgICAqIDxsaT57QGNvZGUgQ09MVU1OX1RZUEV9IC0gc2hvcnQgLSB0aGUga2luZCBvZiBjb2x1bW4gb3IgcGFyYW1ldGVyLCBhcworICAgICAqIGZvbGxvd3M6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgRGF0YWJhc2VNZXRhRGF0YS5wcm9jZWR1cmVDb2x1bW5Vbmtub3dufSAtIHR5cGUgdW5rbm93bjwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLnByb2NlZHVyZUNvbHVtbklufSAtIGFuIHtAY29kZSBJTn0gcGFyYW1ldGVyPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEucHJvY2VkdXJlQ29sdW1uSW5PdXR9IC0gYW4ge0Bjb2RlIElOT1VUfQorICAgICAqIHBhcmFtZXRlcjwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLnByb2NlZHVyZUNvbHVtbk91dH0gLSBhbiB7QGNvZGUgT1VUfQorICAgICAqIHBhcmFtZXRlcjwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLnByb2NlZHVyZUNvbHVtblJldHVybn0gLSBhIHJldHVybiB2YWx1ZTwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLnByb2NlZHVyZVJldHVybnNSZXN1bHR9IC0gYSByZXN1bHQgY29sdW1uIGluCisgICAgICogYSByZXN1bHQgc2V0PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqIDwvbGk+CisgICAgICogPGxpPntAY29kZSBEQVRBX1RZUEV9IC0gaW50IC0gdGhlIFNRTCB0eXBlIG9mIHRoZSBkYXRhLCBhcyBpbiB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5UeXBlc308L2xpPgorICAgICAqIDxsaT57QGNvZGUgVFlQRV9OQU1FfSAtIFN0cmluZyAtIHRoZSBTUUwgdHlwZSBuYW1lLCBmb3IgYSBVRFQgaXQgaXMgZnVsbHkKKyAgICAgKiBxdWFsaWZpZWQ8L2xpPgorICAgICAqIDxsaT57QGNvZGUgUFJFQ0lTSU9OfSAtIGludCAtIHRoZSBwcmVjaXNpb248L2xpPgorICAgICAqIDxsaT57QGNvZGUgTEVOR1RIfSAtIGludCAtIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgaW4gYnl0ZXM8L2xpPgorICAgICAqIDxsaT57QGNvZGUgU0NBTEV9IC0gc2hvcnQgLSB0aGUgc2NhbGUgZm9yIG51bWVyaWMgdHlwZXM8L2xpPgorICAgICAqIDxsaT57QGNvZGUgUkFESVh9IC0gc2hvcnQgLSB0aGUgUmFkaXggZm9yIG51bWVyaWMgZGF0YSAodHlwaWNhbGx5IDIgb3IKKyAgICAgKiAxMCk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgTlVMTEFCTEV9IC0gc2hvcnQgLSBjYW4gdGhlIGRhdGEgY29udGFpbiB7QGNvZGUgbnVsbH06CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgRGF0YWJhc2VNZXRhRGF0YS5wcm9jZWR1cmVOb051bGxzfSAtIHtAY29kZSBOVUxMfXMgbm90CisgICAgICogcGVybWl0dGVkPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEucHJvY2VkdXJlTnVsbGFibGV9IC0ge0Bjb2RlIE5VTEx9cyBhcmUKKyAgICAgKiBwZXJtaXR0ZWQ8L2xpPgorICAgICAqIDxsaT57QGNvZGUgRGF0YWJhc2VNZXRhRGF0YS5wcm9jZWR1cmVOdWxsYWJsZVVua25vd259IC0ge0Bjb2RlIE5VTEx9CisgICAgICogc3RhdHVzIHVua25vd248L2xpPgorICAgICAqIDwvdWw+CisgICAgICogPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFJFTUFSS1N9IC0gU3RyaW5nIC0gYW4gZXhwbGFuYXRvcnkgY29tbWVudCBhYm91dCB0aGUgZGF0YSBpdGVtCisgICAgICogPC9saT4KKyAgICAgKiA8L29sPgorICAgICAqCisgICAgICogQHBhcmFtIGNhdGFsb2cKKyAgICAgKiAgICAgICAgICAgIGEgY2F0YWxvZyBuYW1lLiB7QGNvZGUgbnVsbH0gaXMgdXNlZCB0byBpbXBseSBubyBuYXJyb3dpbmcgb2YKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWFyY2ggYnkgY2F0YWxvZyBuYW1lLiBPdGhlcndpc2UsIHRoZSBuYW1lIG11c3QgbWF0Y2ggYQorICAgICAqICAgICAgICAgICAgY2F0YWxvZyBuYW1lIGhlbGQgaW4gdGhlIGRhdGFiYXNlLCB3aXRoICIiIHVzZWQgdG8gcmV0cmlldmUKKyAgICAgKiAgICAgICAgICAgIHRob3NlIHdpdGhvdXQgYSBjYXRhbG9nIG5hbWUuCisgICAgICogQHBhcmFtIHNjaGVtYVBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIGEgc2NoZW1hIG5hbWUgcGF0dGVybi4ge0Bjb2RlIG51bGx9IGlzIHVzZWQgdG8gaW1wbHkgbm8KKyAgICAgKiAgICAgICAgICAgIG5hcnJvd2luZyBvZiB0aGUgc2VhcmNoIGJ5IHNjaGVtYSBuYW1lLiBPdGhlcndpc2UsIHRoZSBuYW1lCisgICAgICogICAgICAgICAgICBtdXN0IG1hdGNoIGEgc2NoZW1hIG5hbWUgaW4gdGhlIGRhdGFiYXNlLCB3aXRoICIiIHVzZWQgdG8KKyAgICAgKiAgICAgICAgICAgIHJldHJpZXZlIHRob3NlIHdpdGhvdXQgYSBzY2hlbWEgbmFtZS4KKyAgICAgKiBAcGFyYW0gcHJvY2VkdXJlTmFtZVBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIGEgcGF0dGVybiB0aGF0IG11c3QgbWF0Y2ggdGhlIG5hbWUgb2YgdGhlIHByb2NlZHVyZSBzdG9yZWQgaW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhYmFzZS4KKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZVBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIGEgY29sdW1uIG5hbWUgcGF0dGVybi4gVGhlIG5hbWUgbXVzdCBtYXRjaCB0aGUgY29sdW1uIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHN0b3JlZCBpbiB0aGUgZGF0YWJhc2UuCisgICAgICogQHJldHVybiBhIHtAY29kZSBSZXN1bHRTZXR9IHdpdGggdGhlIGxpc3Qgb2YgcGFyYW1ldGVyIGFuZCByZXN1bHQgY29sdW1ucworICAgICAqICAgICAgICAgaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFib3ZlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzdWx0U2V0IGdldFByb2NlZHVyZUNvbHVtbnMoU3RyaW5nIGNhdGFsb2csIFN0cmluZyBzY2hlbWFQYXR0ZXJuLAorICAgICAgICAgICAgU3RyaW5nIHByb2NlZHVyZU5hbWVQYXR0ZXJuLCBTdHJpbmcgY29sdW1uTmFtZVBhdHRlcm4pCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGxpc3Qgb2YgdGhlIHN0b3JlZCBwcm9jZWR1cmVzIGF2YWlsYWJsZSBpbiBhIHNwZWNpZmllZCBjYXRhbG9nLgorICAgICAqIDxwPgorICAgICAqIFRoZSBsaXN0IGlzIHJldHVybmVkIGFzIGEge0Bjb2RlIFJlc3VsdFNldH0gd2l0aCBvbmUgcm93IGZvciBlYWNoIHN0b3JlZAorICAgICAqIHByb2NlZHVyZSwgb3JkZXJlZCBieSBQUk9DRURVUkVfU0NIRU0gYW5kIFBST0NFRFVSRV9OQU1FLCB3aXRoIHRoZSBkYXRhCisgICAgICogaW4gZWFjaCByb3cgYXMgZm9sbG93czoKKyAgICAgKiA8b2w+CisgICAgICogPGxpPntAY29kZSBQUk9DRURVUkVfQ0FUfSAtIFN0cmluZyA6IHRoZSBwcm9jZWR1cmUgY2F0YWxvZyBuYW1lPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFBST0NFRFVSRV9TQ0hFTX0gLSBTdHJpbmcgOiB0aGUgcHJvY2VkdXJlIHNjaGVtYSBuYW1lCisgICAgICogKHBvc3NpYmx5IHtAY29kZSBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgUFJPQ0VEVVJFX05BTUV9IC0gU3RyaW5nIDogdGhlIHByb2NlZHVyZSBuYW1lPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFJlc2VydmVkfTwvbGk+CisgICAgICogPGxpPntAY29kZSBSZXNlcnZlZH08L2xpPgorICAgICAqIDxsaT57QGNvZGUgUmVzZXJ2ZWR9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFJFTUFSS1N9IC0gU3RyaW5nIC0gaW5mb3JtYXRpb24gYWJvdXQgdGhlIHByb2NlZHVyZTwvbGk+CisgICAgICogPGxpPntAY29kZSBQUk9DRURVUkVfVFlQRX0gLSBzaG9ydCA6IG9uZSBvZjoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLnByb2NlZHVyZVJlc3VsdFVua25vd259IC0gcHJvY2VkdXJlIG1heQorICAgICAqIHJldHVybiBhIHJlc3VsdDwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLnByb2NlZHVyZU5vUmVzdWx0fSAtIHByb2NlZHVyZSBkb2VzIG5vdAorICAgICAqIHJldHVybiBhIHJlc3VsdDwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLnByb2NlZHVyZVJldHVybnNSZXN1bHR9IC0gcHJvY2VkdXJlCisgICAgICogZGVmaW5pdGVseSByZXR1cm5zIGEgcmVzdWx0PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqIDwvbGk+CisgICAgICogPC9vbD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXRhbG9nCisgICAgICogICAgICAgICAgICBhIGNhdGFsb2cgbmFtZS4ge0Bjb2RlIG51bGx9IGlzIHVzZWQgdG8gaW1wbHkgbm8gbmFycm93aW5nIG9mCisgICAgICogICAgICAgICAgICB0aGUgc2VhcmNoIGJ5IGNhdGFsb2cgbmFtZS4gT3RoZXJ3aXNlLCB0aGUgbmFtZSBtdXN0IG1hdGNoIGEKKyAgICAgKiAgICAgICAgICAgIGNhdGFsb2cgbmFtZSBoZWxkIGluIHRoZSBkYXRhYmFzZSwgd2l0aCAiIiB1c2VkIHRvIHJldHJpZXZlCisgICAgICogICAgICAgICAgICB0aG9zZSB3aXRob3V0IGEgY2F0YWxvZyBuYW1lLgorICAgICAqIEBwYXJhbSBzY2hlbWFQYXR0ZXJuCisgICAgICogICAgICAgICAgICBhIHNjaGVtYSBuYW1lIHBhdHRlcm4uIHtAY29kZSBudWxsfSBpcyB1c2VkIHRvIGltcGx5IG5vCisgICAgICogICAgICAgICAgICBuYXJyb3dpbmcgb2YgdGhlIHNlYXJjaCBieSBzY2hlbWEgbmFtZS4gT3RoZXJ3aXNlLCB0aGUgbmFtZQorICAgICAqICAgICAgICAgICAgbXVzdCBtYXRjaCBhIHNjaGVtYSBuYW1lIGluIHRoZSBkYXRhYmFzZSwgd2l0aCAiIiB1c2VkIHRvCisgICAgICogICAgICAgICAgICByZXRyaWV2ZSB0aG9zZSB3aXRob3V0IGEgc2NoZW1hIG5hbWUuCisgICAgICogQHBhcmFtIHByb2NlZHVyZU5hbWVQYXR0ZXJuCisgICAgICogICAgICAgICAgICBhIHByb2NlZHVyZSBuYW1lIHBhdHRlcm4sIHdoaWNoIG11c3QgbWF0Y2ggdGhlIHByb2NlZHVyZSBuYW1lCisgICAgICogICAgICAgICAgICBzdG9yZWQgaW4gdGhlIGRhdGFiYXNlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgUmVzdWx0U2V0fSB3aGVyZSBlYWNoIHJvdyBpcyBhIGRlc2NyaXB0aW9uIG9mIGEgc3RvcmVkCisgICAgICogICAgICAgICBwcm9jZWR1cmUgaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFib3ZlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzdWx0U2V0IGdldFByb2NlZHVyZXMoU3RyaW5nIGNhdGFsb2csIFN0cmluZyBzY2hlbWFQYXR0ZXJuLAorICAgICAgICAgICAgU3RyaW5nIHByb2NlZHVyZU5hbWVQYXR0ZXJuKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGF0YWJhc2UgdmVuZG9yJ3MgcHJlZmVycmVkIG5hbWUgZm9yICJwcm9jZWR1cmUiLgorICAgICAqCisgICAgICogQHJldHVybiBhIFN0cmluZyB3aXRoIHRoZSB2ZW5kb3IncyBwcmVmZXJyZWQgbmFtZSBmb3IgInByb2NlZHVyZSIuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJvY2VkdXJlVGVybSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByZXN1bHQgc2V0J3MgZGVmYXVsdCBob2xkYWJpbGl0eS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gb25lIG9mIHtAY29kZSBSZXN1bHRTZXQuSE9MRF9DVVJTT1JTX09WRVJfQ09NTUlUfSBvciB7QGNvZGUKKyAgICAgKiAgICAgICAgIFJlc3VsdFNldC5DTE9TRV9DVVJTT1JTX0FUX0NPTU1JVH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UmVzdWx0U2V0SG9sZGFiaWxpdHkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGxpc3Qgb2YgdGhlIHNjaGVtYSBuYW1lcyBpbiB0aGUgZGF0YWJhc2UuIFRoZSBsaXN0IGlzIHJldHVybmVkCisgICAgICogYXMgYSB7QGNvZGUgUmVzdWx0U2V0fSwgb3JkZXJlZCBieSB0aGUgc2NoZW1hIG5hbWUsIHdpdGggb25lIHJvdyBwZXIKKyAgICAgKiBzY2hlbWEgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CisgICAgICogPG9sPgorICAgICAqIDxsaT57QGNvZGUgVEFCTEVfU0NIRU19IC0gU3RyaW5nIC0gdGhlIHNjaGVtYSBuYW1lPC9saT4gPGxpPntAY29kZQorICAgICAqIFRBQkxFX0NBVEFMT0d9IC0gU3RyaW5nIC0gdGhlIGNhdGFsb2cgbmFtZSAocG9zc2libHkge0Bjb2RlIG51bGx9KSA8L2xpPgorICAgICAqIDwvb2w+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFJlc3VsdFNldH0gd2l0aCBvbmUgcm93IGZvciBlYWNoIHNjaGVtYSBpbiB0aGUgZm9ybWF0CisgICAgICogICAgICAgICBkZWZpbmVkIGFib3ZlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzdWx0U2V0IGdldFNjaGVtYXMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGF0YWJhc2UgdmVuZG9yJ3MgcHJlZmVycmVkIHRlcm0gZm9yICJzY2hlbWEiLgorICAgICAqCisgICAgICogQHJldHVybiBhIFN0cmluZyB3aGljaCBpcyB0aGUgdmVuZG9yJ3MgcHJlZmVycmVkIHRlcm0gZm9yIHNjaGVtYS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTY2hlbWFUZXJtKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0cmluZyB0aGF0IGlzIHVzZWQgdG8gZXNjYXBlIHdpbGRjYXJkIGNoYXJhY3RlcnMuIFRoaXMKKyAgICAgKiBzdHJpbmcgaXMgdXNlZCB0byBlc2NhcGUgdGhlIHtAY29kZSAnXyd9IGFuZCB7QGNvZGUgJyUnfSB3aWxkY2FyZAorICAgICAqIGNoYXJhY3RlcnMgaW4gY2F0YWxvZyBzZWFyY2ggcGF0dGVybiBzdHJpbmdzLiB7QGNvZGUgJ18nfSBpcyB1c2VkIHRvIHJlcHJlc2VudCBhbnkgc2luZ2xlCisgICAgICogY2hhcmFjdGVyIHdoaWxlIHtAY29kZSAnJSd9IGlzIHVzZWQgZm9yIGEgc2VxdWVuY2Ugb2YgemVybyBvciBtb3JlCisgICAgICogY2hhcmFjdGVycy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBTdHJpbmcgdXNlZCB0byBlc2NhcGUgdGhlIHdpbGRjYXJkIGNoYXJhY3RlcnMuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2VhcmNoU3RyaW5nRXNjYXBlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGFsbCB0aGUgU1FMIGtleXdvcmRzIHRoYXQgYXJlIE5PVCBhbHNvIFNRTDkyIGtleXdvcmRzCisgICAgICogZm9yIHRoZSBkYXRhYmFzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBTdHJpbmcgY29udGFpbmluZyB0aGUgbGlzdCBvZiBTUUwga2V5d29yZHMgaW4gYSBjb21tYSBzZXBhcmF0ZWQKKyAgICAgKiAgICAgICAgIGZvcm1hdC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTUUxLZXl3b3JkcygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZXMgdGhlIHR5cGUgb2Yge0Bjb2RlIFNRTFN0YXRlfSB2YWx1ZSByZXR1cm5lZCBieSB7QGNvZGUKKyAgICAgKiBTUUxFeGNlcHRpb24uZ2V0U1FMU3RhdGV9LiBUaGlzIGNhbiBlaXRoZXIgYmUgdGhlIFgvT3BlbiAobm93IGtub3duIGFzCisgICAgICogT3BlbiBHcm91cCkgU1FMIENMSSBmb3JtIG9yIHRoZSBTUUw5OSBmb3JtLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBpbnRlZ2VyLCB3aGljaCBpcyBlaXRoZXIge0Bjb2RlCisgICAgICogICAgICAgICBEYXRhYmFzZU1ldGFEYXRhLnNxbFN0YXRlU1FMOTl9IG9yIHtAY29kZQorICAgICAqICAgICAgICAgRGF0YWJhc2VNZXRhRGF0YS5zcWxTdGF0ZVhPcGVufS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRTUUxTdGF0ZVR5cGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGxpc3Qgb2Ygc3RyaW5nIGZ1bmN0aW9ucyBhdmFpbGFibGUgd2l0aCB0aGUgZGF0YWJhc2UuIFRoZXNlCisgICAgICogZnVuY3Rpb25zIGFyZSB1c2VkIGluIEpEQkMgZnVuY3Rpb24gZXNjYXBlIGNsYXVzZSBhbmQgZm9sbG93IHRoZSBPcGVuCisgICAgICogR3JvdXAgQ0xJIHN0cmluZyBmdW5jdGlvbiBuYW1lcyBkZWZpbml0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBhIFN0cmluZyBjb250YWluaW5nIHRoZSBsaXN0IG9mIHN0cmluZyBmdW5jdGlvbnMgaW4gY29tbWEKKyAgICAgKiAgICAgICAgIHNlcGFyYXRlZCBmb3JtYXQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nRnVuY3Rpb25zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBsaXN0aW5nIG9mIHRoZSBoaWVyYXJjaGllcyBvZiB0YWJsZXMgaW4gYSBzcGVjaWZpZWQgc2NoZW1hIGluCisgICAgICogdGhlIGRhdGFiYXNlLgorICAgICAqIDxwPgorICAgICAqIFRoZSBsaXN0aW5nIG9ubHkgY29udGFpbnMgZW50cmllcyBmb3IgdGFibGVzIHRoYXQgaGF2ZSBhIHN1cGVyIHRhYmxlLgorICAgICAqIFN1cGVyIHRhYmxlcyBhbmQgY29ycmVzcG9uZGluZyBzdWJ0YWJsZXMgbXVzdCBiZSBkZWZpbmVkIGluIHRoZSBzYW1lIGNhdGFsb2cgYW5kIHNjaGVtYS4gVGhlCisgICAgICogbGlzdCBpcyByZXR1cm5lZCBhcyBhIHtAY29kZSBSZXN1bHRTZXR9LCB3aXRoIG9uZSByb3cgZm9yIGVhY2ggdGFibGUgdGhhdAorICAgICAqIGhhcyBhIHN1cGVyIHRhYmxlLCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKKyAgICAgKiA8b2w+CisgICAgICogPGxpPntAY29kZSBUQUJMRV9DQVR9IC0gU3RyaW5nIC0gdGFibGUgY2F0YWxvZyBuYW1lIChwb3NzaWJseSB7QGNvZGUKKyAgICAgKiBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgVEFCTEVfU0NIRU19IC0gU3RyaW5nIC0gVGFibGUgc2NoZW1hIG5hbWUgKHBvc3NpYmx5IHtAY29kZQorICAgICAqIG51bGx9KTwvbGk+CisgICAgICogPGxpPntAY29kZSBUQUJMRV9OQU1FfSAtIFN0cmluZyAtIFRoZSB0YWJsZSBuYW1lPC9saT4KKyAgICAgKiA8bGk+U1VQRVJ7QGNvZGUgVEFCTEVfTkFNRX0gLSBTdHJpbmcgLSBUaGUgc3VwZXIgdGFibGUgbmFtZTwvbGk+CisgICAgICogPC9vbD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXRhbG9nCisgICAgICogICAgICAgICAgICBhIGNhdGFsb2cgbmFtZS4ge0Bjb2RlIG51bGx9IGlzIHVzZWQgdG8gaW1wbHkgbm8gbmFycm93aW5nIG9mCisgICAgICogICAgICAgICAgICB0aGUgc2VhcmNoIGJ5IGNhdGFsb2cgbmFtZS4gT3RoZXJ3aXNlLCB0aGUgbmFtZSBtdXN0IG1hdGNoIGEKKyAgICAgKiAgICAgICAgICAgIGNhdGFsb2cgbmFtZSBoZWxkIGluIHRoZSBkYXRhYmFzZSwgd2l0aCAiIiB1c2VkIHRvIHJldHJpZXZlCisgICAgICogICAgICAgICAgICB0aG9zZSB3aXRob3V0IGEgY2F0YWxvZyBuYW1lLgorICAgICAqIEBwYXJhbSBzY2hlbWFQYXR0ZXJuCisgICAgICogICAgICAgICAgICBhIHNjaGVtYSBuYW1lIHBhdHRlcm4uIHtAY29kZSBudWxsfSBpcyB1c2VkIHRvIGltcGx5IG5vCisgICAgICogICAgICAgICAgICBuYXJyb3dpbmcgb2YgdGhlIHNlYXJjaCBieSBzY2hlbWEgbmFtZS4gT3RoZXJ3aXNlLCB0aGUgbmFtZQorICAgICAqICAgICAgICAgICAgbXVzdCBtYXRjaCBhIHNjaGVtYSBuYW1lIGluIHRoZSBkYXRhYmFzZSwgd2l0aCAiIiB1c2VkIHRvCisgICAgICogICAgICAgICAgICByZXRyaWV2ZSB0aG9zZSB3aXRob3V0IGEgc2NoZW1hIG5hbWUuCisgICAgICogQHBhcmFtIHRhYmxlTmFtZVBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIGEgdGFibGUgbmFtZSwgd2hpY2ggc2hvdWxkIG1hdGNoIHRoZSB0YWJsZSBuYW1lIGFzIHN0b3JlZCBpbgorICAgICAqICAgICAgICAgICAgdGhlIGRhdGFiYXNlLiBpdCBtYXkgYmUgYSBmdWxseSBxdWFsaWZpZWQgbmFtZS4gSWYgaXQgaXMgZnVsbHkKKyAgICAgKiAgICAgICAgICAgIHF1YWxpZmllZCB0aGUgY2F0YWxvZyBuYW1lIGFuZCBzY2hlbWEgbmFtZSBwYXJhbWV0ZXJzIGFyZQorICAgICAqICAgICAgICAgICAgaWdub3JlZC4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFJlc3VsdFNldH0gd2l0aCBvbmUgcm93IGZvciBlYWNoIHRhYmxlIHdoaWNoIGhhcyBhIHN1cGVyCisgICAgICogICAgICAgICB0YWJsZSwgaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFib3ZlLiBBbiBlbXB0eSB7QGNvZGUgUmVzdWx0U2V0fSBpcworICAgICAqICAgICAgICAgcmV0dXJuZWQgaWYgdGhlIGRhdGFiYXNlIGRvZXMgbm90IHN1cHBvcnQgdGFibGUgaGllcmFyY2hpZXMuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBSZXN1bHRTZXQgZ2V0U3VwZXJUYWJsZXMoU3RyaW5nIGNhdGFsb2csIFN0cmluZyBzY2hlbWFQYXR0ZXJuLAorICAgICAgICAgICAgU3RyaW5nIHRhYmxlTmFtZVBhdHRlcm4pIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBVc2VyIERlZmluZWQgVHlwZSAoVURUKSBoaWVyYXJjaGllcyBmb3IgYSBnaXZlbiBzY2hlbWEuIE9ubHkKKyAgICAgKiB0aGUgaW1tZWRpYXRlIHBhcmVudC9jaGlsZCByZWxhdGlvbnNoaXAgaXMgZGVzY3JpYmVkLiBJZiBhIFVEVCBkb2VzIG5vdAorICAgICAqIGhhdmUgYSBkaXJlY3Qgc3VwZXJ0eXBlLCBpdCBpcyBub3QgbGlzdGVkLgorICAgICAqIDxwPgorICAgICAqIFRoZSBsaXN0aW5nIGlzIHJldHVybmVkIGFzIGEge0Bjb2RlIFJlc3VsdFNldH0gd2hlcmUgdGhlcmUgaXMgb25lIHJvdyBmb3IKKyAgICAgKiBhIHNwZWNpZmljIFVEVCB3aGljaCBkZXNjcmliZXMgaXRzIHN1cGVydHlwZSwgd2l0aCB0aGUgZGF0YSBvcmdhbml6ZWQgaW4KKyAgICAgKiBjb2x1bW5zIGFzIGZvbGxvd3M6CisgICAgICogPG9sPgorICAgICAqIDxsaT57QGNvZGUgVFlQRV9DQVR9IC0gU3RyaW5nIC0gdGhlIFVEVCBjYXRhbG9nIG5hbWUgKHBvc3NpYmx5IHtAY29kZQorICAgICAqIG51bGx9KTwvbGk+CisgICAgICogPGxpPntAY29kZSBUWVBFX1NDSEVNfSAtIFN0cmluZyAtIHRoZSBVRFQgc2NoZW1hIG5hbWUgKHBvc3NpYmx5IHtAY29kZQorICAgICAqIG51bGx9KTwvbGk+CisgICAgICogPGxpPntAY29kZSBUWVBFX05BTUV9IC0gU3RyaW5nIC0gdGhlIFVEVCB0eXBlIG5hbWU8L2xpPgorICAgICAqIDxsaT5TVVBFUntAY29kZSBUWVBFX0NBVH0gLSBTdHJpbmcgLSBkaXJlY3Qgc3VwZXJ0eXBlJ3MgY2F0YWxvZyBuYW1lCisgICAgICogKHBvc3NpYmx5IHtAY29kZSBudWxsfSk8L2xpPgorICAgICAqIDxsaT5TVVBFUntAY29kZSBUWVBFX1NDSEVNfSAtIFN0cmluZyAtIGRpcmVjdCBzdXBlcnR5cGUncyBzY2hlbWEgbmFtZQorICAgICAqIChwb3NzaWJseSB7QGNvZGUgbnVsbH0pPC9saT4KKyAgICAgKiA8bGk+U1VQRVJ7QGNvZGUgVFlQRV9OQU1FfSAtIFN0cmluZyAtIGRpcmVjdCBzdXBlcnR5cGUncyBuYW1lPC9saT4KKyAgICAgKiA8L29sPgorICAgICAqCisgICAgICogQHBhcmFtIGNhdGFsb2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYXRhbG9nIG5hbWUuICIiIG1lYW5zIGdldCB0aGUgVURUcyB3aXRob3V0IGEgY2F0YWxvZy4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBudWxsfSBtZWFucyBkb24ndCB1c2UgdGhlIGNhdGFsb2cgbmFtZSB0byByZXN0cmljdCB0aGUKKyAgICAgKiAgICAgICAgICAgIHNlYXJjaC4KKyAgICAgKiBAcGFyYW0gc2NoZW1hUGF0dGVybgorICAgICAqICAgICAgICAgICAgdGhlIFNjaGVtYSBwYXR0ZXJuIG5hbWUuICIiIG1lYW5zIGdldCB0aGUgVURUJ3Mgd2l0aG91dCBhCisgICAgICogICAgICAgICAgICBzY2hlbWEuCisgICAgICogQHBhcmFtIHR5cGVOYW1lUGF0dGVybgorICAgICAqICAgICAgICAgICAgdGhlIFVEVCBuYW1lIHBhdHRlcm4uIFRoaXMgbWF5IGJlIGEgZnVsbHkgcXVhbGlmaWVkIG5hbWUuIFdoZW4KKyAgICAgKiAgICAgICAgICAgIGEgZnVsbHkgcXVhbGlmaWVkIG5hbWUgaXMgc3BlY2lmaWVkLCB0aGUgY2F0YWxvZyBuYW1lIGFuZAorICAgICAqICAgICAgICAgICAgc2NoZW1hIG5hbWUgcGFyYW1ldGVycyBhcmUgaWdub3JlZC4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFJlc3VsdFNldH0gaW4gd2hpY2ggZWFjaCByb3cgZ2l2ZXMgaW5mb3JtYXRpb24gYWJvdXQgYQorICAgICAqICAgICAgICAgcGFydGljdWxhciBVRFQgaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFib3ZlLiBBbiBlbXB0eSBSZXN1bHRTZXQgaXMKKyAgICAgKiAgICAgICAgIHJldHVybmVkIGZvciBhIGRhdGFiYXNlIHRoYXQgZG9lcyBub3Qgc3VwcG9ydCB0eXBlIGhpZXJhcmNoaWVzLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzdWx0U2V0IGdldFN1cGVyVHlwZXMoU3RyaW5nIGNhdGFsb2csIFN0cmluZyBzY2hlbWFQYXR0ZXJuLAorICAgICAgICAgICAgU3RyaW5nIHR5cGVOYW1lUGF0dGVybikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBsaXN0IG9mIHN5c3RlbSBmdW5jdGlvbnMgYXZhaWxhYmxlIHdpdGggdGhlIGRhdGFiYXNlLiBUaGVzZSBhcmUKKyAgICAgKiBuYW1lcyB1c2VkIGluIHRoZSBKREJDIGZ1bmN0aW9uIGVzY2FwZSBjbGF1c2UgYW5kIGFyZSBPcGVuIEdyb3VwIENMSQorICAgICAqIGZ1bmN0aW9uIG5hbWVzLgorICAgICAqCisgICAgICogQHJldHVybiBhIFN0cmluZyBjb250YWluaW5nIHRoZSBsaXN0IG9mIHN5c3RlbSBmdW5jdGlvbnMgaW4gYSBjb21tYQorICAgICAqICAgICAgICAgc2VwYXJhdGVkIGZvcm1hdC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1GdW5jdGlvbnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGRlc2NyaXB0aW9uIG9mIGFjY2VzcyByaWdodHMgZm9yIGVhY2ggdGFibGUgcHJlc2VudCBpbiBhCisgICAgICogY2F0YWxvZy4gVGFibGUgcHJpdmlsZWdlcyBjYW4gYXBwbHkgdG8gb25lIG9yIG1vcmUgY29sdW1ucyBpbiB0aGUgdGFibGUgLQorICAgICAqIGJ1dCBhcmUgbm90IGd1YXJhbnRlZWQgdG8gYXBwbHkgdG8gYWxsIGNvbHVtbnMuCisgICAgICogPHA+CisgICAgICogVGhlIHByaXZpbGVnZXMgYXJlIHJldHVybmVkIGFzIGEge0Bjb2RlIFJlc3VsdFNldH0sIHdpdGggb25lIHJvdyBmb3IgZWFjaAorICAgICAqIHByaXZpbGVnZSwgb3JkZXJlZCBieSB7QGNvZGUgVEFCTEVfU0NIRU19LCB7QGNvZGUgVEFCTEVfTkFNRX0sIHtAY29kZQorICAgICAqIFBSSVZJTEVHRX0sIGFuZCBlYWNoIHJvdyBoYXMgZGF0YSBhcyBkZWZpbmVkIGluIHRoZSBmb2xsb3dpbmcgY29sdW1uCisgICAgICogZGVmaW5pdGlvbnM6CisgICAgICogPG9sPgorICAgICAqIDxsaT57QGNvZGUgVEFCTEVfQ0FUfSAtIFN0cmluZyAtIHRhYmxlIGNhdGFsb2cgbmFtZSAocG9zc2libHkge0Bjb2RlCisgICAgICogbnVsbH0pPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFRBQkxFX1NDSEVNfSAtIFN0cmluZyAtIFRhYmxlIHNjaGVtYSBuYW1lIChwb3NzaWJseSB7QGNvZGUKKyAgICAgKiBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgVEFCTEVfTkFNRX0gLSBTdHJpbmcgLSBUaGUgdGFibGUgbmFtZTwvbGk+CisgICAgICogPGxpPkdSQU5UT1IgLSBTdHJpbmcgLSB3aG8gZ3JhbnRlZCB0aGUgYWNjZXNzPC9saT4KKyAgICAgKiA8bGk+R1JBTlRFRSAtIFN0cmluZyAtIHdobyByZWNlaXZlZCB0aGUgYWNjZXNzIGdyYW50PC9saT4KKyAgICAgKiA8bGk+UFJJVklMRUdFIC0gU3RyaW5nIC0gdGhlIHR5cGUgb2YgYWNjZXNzIGdyYW50ZWQgLSBvbmUgb2YgU0VMRUNULAorICAgICAqIElOU0VSVCwgVVBEQVRFLCBSRUZFUkVOQ0VTLC4uLjwvbGk+CisgICAgICogPGxpPklTX0dSQU5UQUJMRSAtIFN0cmluZyAtIHtAY29kZSAiWUVTIn0gaW1wbGllcyB0aGUgZ3JhbnRlZSBjYW4gZ3JhbnQKKyAgICAgKiBhY2Nlc3MgdG8gb3RoZXJzLCB7QGNvZGUgIk5PIn0gaW1wbGllcyBndWFyYW50ZWUgY2Fubm90IGdyYW50IGFjY2VzcyB0bworICAgICAqIG90aGVycywge0Bjb2RlIG51bGx9IG1lYW5zIHRoaXMgc3RhdHVzIGlzIHVua25vd248L2xpPgorICAgICAqIDwvb2w+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F0YWxvZworICAgICAqICAgICAgICAgICAgYSBjYXRhbG9nIG5hbWUuIHtAY29kZSBudWxsfSBpcyB1c2VkIHRvIGltcGx5IG5vIG5hcnJvd2luZyBvZgorICAgICAqICAgICAgICAgICAgdGhlIHNlYXJjaCBieSBjYXRhbG9nIG5hbWUuIE90aGVyd2lzZSwgdGhlIG5hbWUgbXVzdCBtYXRjaCBhCisgICAgICogICAgICAgICAgICBjYXRhbG9nIG5hbWUgaGVsZCBpbiB0aGUgZGF0YWJhc2UsIHdpdGggIiIgdXNlZCB0byByZXRyaWV2ZQorICAgICAqICAgICAgICAgICAgdGhvc2Ugd2l0aG91dCBhIGNhdGFsb2cgbmFtZS4KKyAgICAgKiBAcGFyYW0gc2NoZW1hUGF0dGVybgorICAgICAqICAgICAgICAgICAgYSBzY2hlbWEgbmFtZSBwYXR0ZXJuLiB7QGNvZGUgbnVsbH0gaXMgdXNlZCB0byBpbXBseSBubworICAgICAqICAgICAgICAgICAgbmFycm93aW5nIG9mIHRoZSBzZWFyY2ggYnkgc2NoZW1hIG5hbWUuIE90aGVyd2lzZSwgdGhlIG5hbWUKKyAgICAgKiAgICAgICAgICAgIG11c3QgbWF0Y2ggYSBzY2hlbWEgbmFtZSBpbiB0aGUgZGF0YWJhc2UsIHdpdGggIiIgdXNlZCB0bworICAgICAqICAgICAgICAgICAgcmV0cmlldmUgdGhvc2Ugd2l0aG91dCBhIHNjaGVtYSBuYW1lLgorICAgICAqIEBwYXJhbSB0YWJsZU5hbWVQYXR0ZXJuCisgICAgICogICAgICAgICAgICBhIFRhYmxlIE5hbWUsIHdoaWNoIHNob3VsZCBtYXRjaCB0aGUgdGFibGUgbmFtZSBhcyBzdG9yZWQgaW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhYmFzZS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFJlc3VsdFNldH0gY29udGFpbmluZyBhIGxpc3Qgd2l0aCBvbmUgcm93IGZvciBlYWNoIHRhYmxlCisgICAgICogICAgICAgICBpbiB0aGUgZm9ybWF0IGRlZmluZWQgYWJvdmUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBSZXN1bHRTZXQgZ2V0VGFibGVQcml2aWxlZ2VzKFN0cmluZyBjYXRhbG9nLCBTdHJpbmcgc2NoZW1hUGF0dGVybiwKKyAgICAgICAgICAgIFN0cmluZyB0YWJsZU5hbWVQYXR0ZXJuKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGRlc2NyaXB0aW9uIG9mIHRoZSB0YWJsZXMgaW4gYSBzcGVjaWZpZWQgY2F0YWxvZy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZGVzY3JpcHRpb25zIGFyZSByZXR1cm5lZCBhcyByb3dzIGluIGEge0Bjb2RlIFJlc3VsdFNldH0sIG9uZSByb3cgZm9yCisgICAgICogZWFjaCBUYWJsZS4gVGhlIFJlc3VsdFNldCBpcyBvcmRlcmVkIGJ5IHtAY29kZSBUQUJMRV9UWVBFfSwge0Bjb2RlCisgICAgICogVEFCTEVfU0NIRU19IGFuZCB7QGNvZGUgVEFCTEVfTkFNRX0uIEVhY2ggcm93IGluIHRoZSBSZXN1bHRTZXQgY29uc2lzdHMKKyAgICAgKiBvZiBhIHNlcmllcyBvZiBjb2x1bW5zIGFzIGZvbGxvd3M6CisgICAgICogPG9sPgorICAgICAqIDxsaT57QGNvZGUgVEFCTEVfQ0FUfSAtIFN0cmluZyAtIHRhYmxlIGNhdGFsb2cgbmFtZSAocG9zc2libHkge0Bjb2RlCisgICAgICogbnVsbH0pPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFRBQkxFX1NDSEVNfSAtIFN0cmluZyAtIFRhYmxlIHNjaGVtYSBuYW1lIChwb3NzaWJseSB7QGNvZGUKKyAgICAgKiBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgVEFCTEVfTkFNRX0gLSBTdHJpbmcgLSBUaGUgdGFibGUgbmFtZTwvbGk+CisgICAgICogPGxpPntAY29kZSBUQUJMRV9UWVBFfSAtIFN0cmluZyAtIFR5cGljYWwgbmFtZXMgaW5jbHVkZSAiVEFCTEUiLCAiVklFVyIsCisgICAgICogIlNZU1RFTSBUQUJMRSIsICJBTElBUyIsICJTWU5PTllNIiwgIkdMT0JBTCBURU1QT1JBUlkiPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFJFTUFSS1N9IC0gU3RyaW5nIC0gQSBjb21tZW50IGRlc2NyaWJpbmcgdGhlIHRhYmxlPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFRZUEVfQ0FUfSAtIFN0cmluZyAtIHRoZSAnVHlwZXMnIGNhdGFsb2cocG9zc2libHkge0Bjb2RlIG51bGx9CisgICAgICogKTwvbGk+CisgICAgICogPGxpPntAY29kZSBUWVBFX1NDSEVNfSAtIFN0cmluZyAtIHRoZSAnVHlwZXMnIHNjaGVtYShwb3NzaWJseSB7QGNvZGUKKyAgICAgKiBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgVFlQRV9OQU1FfSAtIFN0cmluZyAtIHRoZSAnVHlwZXMnIG5hbWUgKHBvc3NpYmx5IHtAY29kZSBudWxsfSkKKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT57QGNvZGUgU0VMRl9SRUZFUkVOQ0lOR19DT0xfTkFNRX0gLSBTdHJpbmcgLSB0aGUgbmFtZSBvZiBhIGRlc2lnbmF0ZWQKKyAgICAgKiBpZGVudGlmaWVyIGNvbHVtbiBpbiBhIHR5cGVkIHRhYmxlIChwb3NzaWJseSB7QGNvZGUgbnVsbH0pPC9saT4KKyAgICAgKiA8bGk+UkVGX0dFTkVSQVRJT04gLSBTdHJpbmcgLSBvbmUgb2YgdGhlIGZvbGxvd2luZyB2YWx1ZXMgOiAiU1lTVEVNIiB8CisgICAgICogIlVTRVIiIHwgIkRFUklWRUQiIC0gc3BlY2lmaWVzIGhvdyB2YWx1ZXMgaW4gdGhlIHtAY29kZQorICAgICAqIFNFTEZfUkVGRVJFTkNJTkdfQ09MX05BTUV9IGFyZSBjcmVhdGVkIChwb3NzaWJseSB7QGNvZGUgbnVsbH0pPC9saT4KKyAgICAgKiA8L29sPgorICAgICAqCisgICAgICogQHBhcmFtIGNhdGFsb2cKKyAgICAgKiAgICAgICAgICAgIGEgY2F0YWxvZyBuYW1lLiB7QGNvZGUgbnVsbH0gaXMgdXNlZCB0byBpbXBseSBubyBuYXJyb3dpbmcgb2YKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWFyY2ggYnkgY2F0YWxvZyBuYW1lLiBPdGhlcndpc2UsIHRoZSBuYW1lIG11c3QgbWF0Y2ggYQorICAgICAqICAgICAgICAgICAgY2F0YWxvZyBuYW1lIGhlbGQgaW4gdGhlIGRhdGFiYXNlLCB3aXRoICIiIHVzZWQgdG8gcmV0cmlldmUKKyAgICAgKiAgICAgICAgICAgIHRob3NlIHdpdGhvdXQgYSBjYXRhbG9nIG5hbWUuCisgICAgICogQHBhcmFtIHNjaGVtYVBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIGEgc2NoZW1hIG5hbWUgcGF0dGVybi4ge0Bjb2RlIG51bGx9IGlzIHVzZWQgdG8gaW1wbHkgbm8KKyAgICAgKiAgICAgICAgICAgIG5hcnJvd2luZyBvZiB0aGUgc2VhcmNoIGJ5IHNjaGVtYSBuYW1lLiBPdGhlcndpc2UsIHRoZSBuYW1lCisgICAgICogICAgICAgICAgICBtdXN0IG1hdGNoIGEgc2NoZW1hIG5hbWUgaW4gdGhlIGRhdGFiYXNlLCB3aXRoICIiIHVzZWQgdG8KKyAgICAgKiAgICAgICAgICAgIHJldHJpZXZlIHRob3NlIHdpdGhvdXQgYSBzY2hlbWEgbmFtZS4KKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lUGF0dGVybgorICAgICAqICAgICAgICAgICAgYSB0YWJsZSBuYW1lLCB3aGljaCBzaG91bGQgbWF0Y2ggdGhlIHRhYmxlIG5hbWUgYXMgc3RvcmVkIGluCisgICAgICogICAgICAgICAgICB0aGUgZGF0YWJhc2UuCisgICAgICogQHBhcmFtIHR5cGVzCisgICAgICogICAgICAgICAgICBhIGxpc3Qgb2YgdGFibGUgdHlwZXMgdG8gaW5jbHVkZSBpbiB0aGUgbGlzdC4ge0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICAgICBpbXBsaWVzIGxpc3QgYWxsIHR5cGVzLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgUmVzdWx0U2V0fSB3aXRoIG9uZSByb3cgcGVyIHRhYmxlIGluIHRoZSBmb3JtYXQgZGVmaW5lZAorICAgICAqICAgICAgICAgYWJvdmUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBSZXN1bHRTZXQgZ2V0VGFibGVzKFN0cmluZyBjYXRhbG9nLCBTdHJpbmcgc2NoZW1hUGF0dGVybiwKKyAgICAgICAgICAgIFN0cmluZyB0YWJsZU5hbWVQYXR0ZXJuLCBTdHJpbmdbXSB0eXBlcykgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBsaXN0IG9mIHRhYmxlIHR5cGVzIHN1cHBvcnRlZCBieSB0aGUgZGF0YWJhc2UuCisgICAgICogPHA+CisgICAgICogVGhlIGxpc3QgaXMgcmV0dXJuZWQgYXMgYSB7QGNvZGUgUmVzdWx0U2V0fSB3aXRoIG9uZSByb3cgcGVyIHRhYmxlIHR5cGUsCisgICAgICogb3JkZXJlZCBieSB0aGUgdGFibGUgdHlwZS4gVGhlIGluZm9ybWF0aW9uIGluIHRoZSB7QGNvZGUgUmVzdWx0U2V0fSBpcworICAgICAqIHN0cnVjdHVyZWQgaW50byBhIHNpbmdsZSBjb2x1bW4gcGVyIHJvdywgYXMgZm9sbG93czoKKyAgICAgKiA8b2w+CisgICAgICogPGxpPntAY29kZSBUQUJMRV9UWVBFfSAtIFN0cmluZyAtIHRoZSB0YWJsZSB0eXBlLiBUeXBpY2FsIG5hbWVzIGluY2x1ZGUKKyAgICAgKiB7QGNvZGUgIlRBQkxFIn0sIHtAY29kZSAiVklFVyJ9LCAie0Bjb2RlIFNZU1RFTSBUQUJMRSJ9LCB7QGNvZGUgIkFMSUFTIn0sCisgICAgICoge0Bjb2RlICJTWU5PTllNIn0sIHtAY29kZSAiR0xPQkFMIFRFTVBPUkFSWSJ9PC9saT4KKyAgICAgKiA8L29sPgorICAgICAqCisgICAgICogQHJldHVybiBhIHtAY29kZSBSZXN1bHRTZXR9IHdpdGggb25lIHJvdyBwZXIgdGFibGUgdHlwZSBpbiB0aGUgZm9ybWF0CisgICAgICogICAgICAgICBkZWZpbmVkIGFib3ZlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzdWx0U2V0IGdldFRhYmxlVHlwZXMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGxpc3Qgb2YgdGltZSBhbmQgZGF0ZSBmdW5jdGlvbnMgYXZhaWxhYmxlIGZvciB0aGUgZGF0YWJhc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb21tYSBzZXBhcmF0ZWQgbGlzdCBvZiB0aGUgdGltZSBhbmQgZGF0ZQorICAgICAqICAgICAgICAgZnVuY3Rpb25zLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFRpbWVEYXRlRnVuY3Rpb25zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldCBhIGxpc3Qgb2YgdGhlIHN0YW5kYXJkIFNRTCB0eXBlcyBzdXBwb3J0ZWQgYnkgdGhpcyBkYXRhYmFzZS4gVGhlIGxpc3QKKyAgICAgKiBpcyByZXR1cm5lZCBhcyBhIHtAY29kZSBSZXN1bHRTZXR9LCB3aXRoIG9uZSByb3cgZm9yIGVhY2ggdHlwZSwgb3JkZXJlZAorICAgICAqIGJ5IHRoZSB7QGNvZGUgREFUQV9UWVBFfSB2YWx1ZSwgd2hlcmUgdGhlIGRhdGEgaW4gZWFjaCByb3cgaXMgc3RydWN0dXJlZAorICAgICAqIGludG8gdGhlIGZvbGxvd2luZyBjb2x1bW5zOgorICAgICAqIDxvbD4KKyAgICAgKiA8bGk+e0Bjb2RlIFRZUEVfTkFNRX0gLSBTdHJpbmcgOiB0aGUgdHlwZSBuYW1lPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERBVEFfVFlQRX0gLSBpbnQgOiB0aGUgU1FMIGRhdGEgdHlwZSB2YWx1ZSBhcyBkZWZpbmVkIGluCisgICAgICoge0Bjb2RlIGphdmEuc3FsLlR5cGVzfTwvbGk+CisgICAgICogPGxpPntAY29kZSBQUkVDSVNJT059IC0gaW50IC0gdGhlIG1heGltdW0gcHJlY2lzaW9uIG9mIHRoZSB0eXBlPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIExJVEVSQUxfUFJFRklYfSAtIFN0cmluZyA6IHRoZSBwcmVmaXggdG8gYmUgdXNlZCB3aGVuIHF1b3RpbmcKKyAgICAgKiBhIGxpdGVyYWwgdmFsdWUgKHBvc3NpYmx5IHtAY29kZSBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgTElURVJBTF9TVUZGSVh9IC0gU3RyaW5nIDogdGhlIHN1ZmZpeCB0byBiZSB1c2VkIHdoZW4gcXVvdGluZworICAgICAqIGEgbGl0ZXJhbCB2YWx1ZSAocG9zc2libHkge0Bjb2RlIG51bGx9KTwvbGk+CisgICAgICogPGxpPntAY29kZSBDUkVBVEVfUEFSQU1TfSAtIFN0cmluZyA6IHBhcmFtcyB1c2VkIHdoZW4gY3JlYXRpbmcgdGhlIHR5cGUKKyAgICAgKiAocG9zc2libHkge0Bjb2RlIG51bGx9KTwvbGk+CisgICAgICogPGxpPntAY29kZSBOVUxMQUJMRX0gLSBzaG9ydCA6IHNob3dzIGlmIHRoZSB2YWx1ZSBpcyBudWxsYWJsZToKKyAgICAgKiA8dWw+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLnR5cGVOb051bGxzfSA6IHtAY29kZSBOVUxMfXMgbm90IHBlcm1pdHRlZDwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLnR5cGVOdWxsYWJsZX0gOiB7QGNvZGUgTlVMTH1zIGFyZSBwZXJtaXR0ZWQ8L2xpPgorICAgICAqIDxsaT57QGNvZGUgRGF0YWJhc2VNZXRhRGF0YS50eXBlTnVsbGFibGVVbmtub3dufSA6IHtAY29kZSBOVUxMfSBzdGF0dXMKKyAgICAgKiB1bmtub3duPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqIDwvbGk+CisgICAgICogPGxpPntAY29kZSBDQVNFX1NFTlNJVElWRX0gLSBib29sZWFuIDogdHJ1ZSBpZiB0aGUgdHlwZSBpcyBjYXNlIHNlbnNpdGl2ZQorICAgICAqIDwvbGk+CisgICAgICogPGxpPntAY29kZSBTRUFSQ0hBQkxFfSAtIHNob3J0IDogaG93IHRoaXMgdHlwZSBjYW4gYmUgdXNlZCB3aXRoIHtAY29kZSBXSEVSRX0KKyAgICAgKiBjbGF1c2VzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEudHlwZVByZWROb25lfSAtIHtAY29kZSBXSEVSRX0gY2xhdXNlcyBjYW5ub3QgYmUgdXNlZDwvbGk+CisgICAgICogPGxpPntAY29kZSBEYXRhYmFzZU1ldGFEYXRhLnR5cGVQcmVkQ2hhcn0gLSBzdXBwb3J0IGZvciB7QGNvZGUKKyAgICAgKiBXSEVSRS4uLkxJS0V9IG9ubHk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgRGF0YWJhc2VNZXRhRGF0YS50eXBlUHJlZEJhc2ljfSAtIHN1cHBvcnQgZXhjZXB0IGZvciB7QGNvZGUKKyAgICAgKiBXSEVSRS4uLkxJS0V9PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEudHlwZVNlYXJjaGFibGV9IC0gc3VwcG9ydCBmb3IgYWxsIHtAY29kZQorICAgICAqIFdIRVJFfSBjbGF1c2VzPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqIDwvbGk+CisgICAgICogPGxpPntAY29kZSBVTlNJR05FRF9BVFRSSUJVVEV9IC0gYm9vbGVhbiAtIHRoZSB0eXBlIGlzIHVuc2lnbmVkIG9yIG5vdDwvbGk+CisgICAgICogPGxpPntAY29kZSBGSVhFRF9QUkVDX1NDQUxFfSAtIGJvb2xlYW4gLSBmaXhlZCBwcmVjaXNpb24gPSBpdCBjYW4gYmUgdXNlZAorICAgICAqIGFzIGEgbW9uZXkgdmFsdWU8L2xpPgorICAgICAqIDxsaT57QGNvZGUgQVVUT19JTkNSRU1FTlR9IC0gYm9vbGVhbiAtIGNhbiBiZSB1c2VkIGFzIGFuIGF1dG8taW5jcmVtZW50CisgICAgICogdmFsdWU8L2xpPgorICAgICAqIDxsaT57QGNvZGUgTE9DQUxfVFlQRV9OQU1FfSAtIFN0cmluZyAtIGEgbG9jYWxpemVkIHZlcnNpb24gb2YgdGhlIHR5cGUKKyAgICAgKiBuYW1lIChwb3NzaWJseSB7QGNvZGUgbnVsbH0pPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIE1JTklNVU1fU0NBTEV9IC0gc2hvcnQgLSB0aGUgbWluaW11bSBzY2FsZSBzdXBwb3J0ZWQ8L2xpPgorICAgICAqIDxsaT57QGNvZGUgTUFYSU1VTV9TQ0FMRX0gLSBzaG9ydCAtIHRoZSBtYXhpbXVtIHNjYWxlIHN1cHBvcnRlZDwvbGk+CisgICAgICogPGxpPntAY29kZSBTUUxfREFUQV9UWVBFfSAtIGludCAtIG5vdCB1c2VkPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFNRTF9EQVRFVElNRV9TVUJ9IC0gaW50IC0gbm90IHVzZWQ8L2xpPgorICAgICAqIDxsaT57QGNvZGUgTlVNX1BSRUNfUkFESVh9IC0gaW50IC0gbnVtYmVyIHJhZGl4ICh0eXBpY2FsbHkgMiBvciAxMCk8L2xpPgorICAgICAqIDwvb2w+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFJlc3VsdFNldH0gd2hpY2ggaXMgc3RydWN0dXJlZCBhcyBkZXNjcmliZWQgYWJvdmUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBSZXN1bHRTZXQgZ2V0VHlwZUluZm8oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGRlc2NyaXB0aW9uIG9mIHRoZSBVc2VyIERlZmluZWQgVHlwZXMgKFVEVHMpIGRlZmluZWQgaW4gYSBnaXZlbgorICAgICAqIHNjaGVtYSwgd2hpY2ggaW5jbHVkZXMgdGhlIHR5cGVzIHtAY29kZSBESVNUSU5DVH0sIHtAY29kZSBTVFJVQ1R9IGFuZAorICAgICAqIHtAY29kZSBKQVZBX09CSkVDVH0uCisgICAgICogPHA+CisgICAgICogVGhlIHR5cGVzIG1hdGNoaW5nIHRoZSBzdXBwbGllZCB0aGUgc3BlY2lmaWVkIGNhdGFsb2csIHNjaGVtYSwgdHlwZSBuYW1lCisgICAgICogYW5kIHR5cGUgYXJlIHJldHVybmVkIGFzIHJvd3MgaW4gYSB7QGNvZGUgUmVzdWx0U2V0fSB3aXRoIGNvbHVtbnMgb2YKKyAgICAgKiBpbmZvcm1hdGlvbiBhcyBmb2xsb3dzOgorICAgICAqIDxvbD4KKyAgICAgKiA8bGk+e0Bjb2RlIFRBQkxFX0NBVH0gLSBTdHJpbmcgLSBjYXRhbG9nIG5hbWUgKHBvc3NpYmx5IHtAY29kZSBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgVEFCTEVfU0NIRU19IC0gU3RyaW5nIC0gc2NoZW1hIG5hbWUgKHBvc3NpYmx5IHtAY29kZSBudWxsfSk8L2xpPgorICAgICAqIDxsaT57QGNvZGUgVEFCTEVfTkFNRX0gLSBTdHJpbmcgLSBUaGUgdGFibGUgbmFtZTwvbGk+CisgICAgICogPGxpPntAY29kZSBDTEFTU19OQU1FfSAtIFN0cmluZyAtIFRoZSBKYXZhIGNsYXNzIG5hbWU8L2xpPgorICAgICAqIDxsaT57QGNvZGUgREFUQV9UWVBFfSAtIGludCAtIFRoZSBTUUwgdHlwZSBhcyBzcGVjaWZpZWQgaW4ge0Bjb2RlCisgICAgICogamF2YS5zcWwuVHlwZXN9LiBPbmUgb2YgRElTVElOQ1QsIFNUUlVDVCwgYW5kIEpBVkFfT0JKRUNUPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFJFTUFSS1N9IC0gU3RyaW5nIC0gQSBjb21tZW50IHdoaWNoIGRlc2NyaWJlcyB0aGUgdHlwZTwvbGk+CisgICAgICogPGxpPntAY29kZSBCQVNFX1RZUEV9IC0gc2hvcnQgLSBBIHR5cGUgY29kZS4gRm9yIGEgRElTVElOQ1QgdHlwZSwgdGhlCisgICAgICogc291cmNlIHR5cGUuIEZvciBhIHN0cnVjdHVyZWQgdHlwZSB0aGlzIGlzIHRoZSB0eXBlIHRoYXQgaW1wbGVtZW50cyB0aGUKKyAgICAgKiB1c2VyIGdlbmVyYXRlZCByZWZlcmVuY2UgdHlwZSBvZiB0aGUge0Bjb2RlIFNFTEZfUkVGRVJFTkNJTkdfQ09MVU1OfS4KKyAgICAgKiBUaGlzIGlzIGRlZmluZWQgaW4ge0Bjb2RlIGphdmEuc3FsLlR5cGVzfSwgYW5kIHdpbGwgYmUge0Bjb2RlIG51bGx9IGlmCisgICAgICogdGhlIHtAY29kZSBEQVRBX1RZUEV9IGRvZXMgbm90IG1hdGNoIHRoZXNlIGNyaXRlcmlhLjwvbGk+CisgICAgICogPC9vbD4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgZHJpdmVyIGRvZXMgbm90IHN1cHBvcnQgVURUcywgdGhlIHtAY29kZSBSZXN1bHRTZXR9IGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHBhcmFtIGNhdGFsb2cKKyAgICAgKiAgICAgICAgICAgIGEgY2F0YWxvZyBuYW1lLiB7QGNvZGUgbnVsbH0gaXMgdXNlZCB0byBpbXBseSBubyBuYXJyb3dpbmcgb2YKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWFyY2ggYnkgY2F0YWxvZyBuYW1lLiBPdGhlcndpc2UsIHRoZSBuYW1lIG11c3QgbWF0Y2ggYQorICAgICAqICAgICAgICAgICAgY2F0YWxvZyBuYW1lIGhlbGQgaW4gdGhlIGRhdGFiYXNlLCB3aXRoICIiIHVzZWQgdG8gcmV0cmlldmUKKyAgICAgKiAgICAgICAgICAgIHRob3NlIHdpdGhvdXQgYSBjYXRhbG9nIG5hbWUuCisgICAgICogQHBhcmFtIHNjaGVtYVBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIGEgc2NoZW1hIG5hbWUgcGF0dGVybi4ge0Bjb2RlIG51bGx9IGlzIHVzZWQgdG8gaW1wbHkgbm8KKyAgICAgKiAgICAgICAgICAgIG5hcnJvd2luZyBvZiB0aGUgc2VhcmNoIHVzaW5nIHNjaGVtYSBuYW1lLiBPdGhlcndpc2UsIHRoZSBuYW1lCisgICAgICogICAgICAgICAgICBtdXN0IG1hdGNoIGEgc2NoZW1hIG5hbWUgaW4gdGhlIGRhdGFiYXNlLCB3aXRoICIiIHVzZWQgdG8KKyAgICAgKiAgICAgICAgICAgIHJldHJpZXZlIHRob3NlIHdpdGhvdXQgYSBzY2hlbWEgbmFtZS4KKyAgICAgKiBAcGFyYW0gdHlwZU5hbWVQYXR0ZXJuCisgICAgICogICAgICAgICAgICBhIHR5cGUgbmFtZSBwYXR0ZXJuLCB3aGljaCBzaG91bGQgbWF0Y2ggYSB0eXBlIG5hbWUgYXMgc3RvcmVkIGluIHRoZQorICAgICAqICAgICAgICAgICAgZGF0YWJhc2UuIEl0IG1heSBiZSBmdWxseSBxdWFsaWZpZWQuCisgICAgICogQHBhcmFtIHR5cGVzCisgICAgICogICAgICAgICAgICBhIGxpc3Qgb2YgdGhlIFVEVCB0eXBlcyB0byBpbmNsdWRlIGluIHRoZSBsaXN0IC0gb25lIG9mCisgICAgICogICAgICAgICAgICB7QGNvZGUgRElTVElOQ1R9LCB7QGNvZGUgU1RSVUNUfSBvciB7QGNvZGUgSkFWQV9PQkpFQ1R9LgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgUmVzdWx0U2V0fSBpbiB0aGUgZm9ybWF0IGRlc2NyaWJlZCBhYm92ZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIFJlc3VsdFNldCBnZXRVRFRzKFN0cmluZyBjYXRhbG9nLCBTdHJpbmcgc2NoZW1hUGF0dGVybiwKKyAgICAgICAgICAgIFN0cmluZyB0eXBlTmFtZVBhdHRlcm4sIGludFtdIHR5cGVzKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgVVJMIGZvciB0aGlzIGRhdGFiYXNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgVVJMIGZvciB0aGUgZGF0YWJhc2UuIHtAY29kZSBudWxsfSBpZiBpdCBjYW5ub3QgYmUgZ2VuZXJhdGVkLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFVSTCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmUgdGhlIHVzZXIgbmFtZSBhcyBrbm93biBieSB0aGUgZGF0YWJhc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB1c2VyIG5hbWUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VXNlck5hbWUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGljaCBvZiBhIHRhYmxlJ3MgY29sdW1ucyBhcmUgYXV0b21hdGljYWxseSB1cGRhdGVkIHdoZW4gYW55CisgICAgICogdmFsdWUgaW4gYSByb3cgaXMgdXBkYXRlZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcmVzdWx0IGlzIGxhaWQtb3V0IGluIHRoZSBmb2xsb3dpbmcgY29sdW1uczoKKyAgICAgKiA8b2w+CisgICAgICogPGxpPntAY29kZSBTQ09QRX0gLSBzaG9ydCAtIG5vdCB1c2VkPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIENPTFVNTl9OQU1FfSAtIFN0cmluZyAtIENvbHVtbiBuYW1lPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERBVEFfVFlQRX0gLSBpbnQgLSBUaGUgU1FMIGRhdGEgdHlwZSwgYXMgZGVmaW5lZCBpbiB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5UeXBlc308L2xpPgorICAgICAqIDxsaT57QGNvZGUgVFlQRV9OQU1FfSAtIFN0cmluZyAtIFRoZSBTUUwgdHlwZSBuYW1lLCBkYXRhIHNvdXJjZSBkZXBlbmRlbnQKKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT57QGNvZGUgQ09MVU1OX1NJWkV9IC0gaW50IC0gUHJlY2lzaW9uIGZvciBudW1lcmljIHR5cGVzPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIEJVRkZFUl9MRU5HVEh9IC0gaW50IC0gTGVuZ3RoIG9mIGEgY29sdW1uIHZhbHVlIGluIGJ5dGVzPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERFQ0lNQUxfRElHSVRTfSAtIHNob3J0IC0gTnVtYmVyIG9mIGRpZ2l0cyBhZnRlciB0aGUgZGVjaW1hbAorICAgICAqIHBvaW50PC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIFBTRVVET19DT0xVTU59IC0gc2hvcnQgLSBJZiB0aGlzIGlzIGEgcHNldWRvLWNvbHVtbiAoZm9yCisgICAgICogZXhhbXBsZSwgYW4gT3JhY2xlIHtAY29kZSBST1dJRH0pOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuYmVzdFJvd1Vua25vd259IC0gZG9uJ3Qga25vdyB3aGV0aGVyIHRoaXMgaXMKKyAgICAgKiBhIHBzZXVkbyBjb2x1bW48L2xpPgorICAgICAqIDxsaT57QGNvZGUgRGF0YWJhc2VNZXRhRGF0YS5iZXN0Um93Tm90UHNldWRvfSAtIGNvbHVtbiBpcyBub3QgcHNldWRvPC9saT4KKyAgICAgKiA8bGk+e0Bjb2RlIERhdGFiYXNlTWV0YURhdGEuYmVzdFJvd1BzZXVkb30gLSBjb2x1bW4gaXMgYSBwc2V1ZG8gY29sdW1uPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqIDwvbGk+CisgICAgICogPC9vbD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXRhbG9nCisgICAgICogICAgICAgICAgICBhIGNhdGFsb2cgbmFtZS4ge0Bjb2RlIG51bGx9IGlzIHVzZWQgdG8gaW1wbHkgbm8gbmFycm93aW5nIG9mCisgICAgICogICAgICAgICAgICB0aGUgc2VhcmNoIHVzaW5nIGNhdGFsb2cgbmFtZS4gT3RoZXJ3aXNlLCB0aGUgbmFtZSBtdXN0IG1hdGNoCisgICAgICogICAgICAgICAgICBhIGNhdGFsb2cgbmFtZSBoZWxkIGluIHRoZSBkYXRhYmFzZSwgd2l0aCAiIiB1c2VkIHRvIHJldHJpZXZlCisgICAgICogICAgICAgICAgICB0aG9zZSB3aXRob3V0IGEgY2F0YWxvZyBuYW1lLgorICAgICAqIEBwYXJhbSBzY2hlbWEKKyAgICAgKiAgICAgICAgICAgIGEgc2NoZW1hIG5hbWUgcGF0dGVybi4ge0Bjb2RlIG51bGx9IGlzIHVzZWQgdG8gaW1wbHkgbm8KKyAgICAgKiAgICAgICAgICAgIG5hcnJvd2luZyBvZiB0aGUgc2VhcmNoIHVzaW5nIHNjaGVtYSBuYW1lcy4gT3RoZXJ3aXNlLCB0aGUKKyAgICAgKiAgICAgICAgICAgIG5hbWUgbXVzdCBtYXRjaCBhIHNjaGVtYSBuYW1lIGluIHRoZSBkYXRhYmFzZSwgd2l0aCAiIiB1c2VkIHRvCisgICAgICogICAgICAgICAgICByZXRyaWV2ZSB0aG9zZSB3aXRob3V0IGEgc2NoZW1hIG5hbWUuCisgICAgICogQHBhcmFtIHRhYmxlCisgICAgICogICAgICAgICAgICBhIHRhYmxlIG5hbWUuIEl0IG11c3QgbWF0Y2ggdGhlIG5hbWUgb2YgYSB0YWJsZSBpbiB0aGUKKyAgICAgKiAgICAgICAgICAgIGRhdGFiYXNlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgUmVzdWx0U2V0fSBjb250YWluaW5nIHRoZSBkZXNjcmlwdGlvbnMsIG9uZSByb3cgZm9yIGVhY2gKKyAgICAgKiAgICAgICAgIGNvbHVtbiwgaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFib3ZlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzdWx0U2V0IGdldFZlcnNpb25Db2x1bW5zKFN0cmluZyBjYXRhbG9nLCBTdHJpbmcgc2NoZW1hLAorICAgICAgICAgICAgU3RyaW5nIHRhYmxlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgdmlzaWJsZSByb3cgaW5zZXJ0IGNhbiBiZSBkZXRlY3RlZCBieSBjYWxsaW5nIHtAY29kZQorICAgICAqIFJlc3VsdFNldC5yb3dJbnNlcnRlZH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBSZXN1bHRTZXR9IHR5cGUuIFRoaXMgbWF5IGJlIG9uZSBvZiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkV9IG9yIHtAY29kZQorICAgICAqICAgICAgICAgICAgUmVzdWx0U2V0LlRZUEVfU0NST0xMX0lOU0VOU0lUSVZFfSBvciB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFJlc3VsdFNldC5UWVBFX0ZPUldBUkRfT05MWX0sCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIFJlc3VsdFNldC5yb3dJbnNlcnRlZH0gZGV0ZWN0cyBhIHZpc2libGUKKyAgICAgKiAgICAgICAgIHJvdyBpbnNlcnQgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqIEBzZWUgUmVzdWx0U2V0I3Jvd0luc2VydGVkKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpbnNlcnRzQXJlRGV0ZWN0ZWQoaW50IHR5cGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmUgd2hldGhlciBhIGZ1bGx5IHF1YWxpZmllZCB0YWJsZSBuYW1lIGlzIHByZWZpeGVkIG9yIHN1ZmZpeGVkIHRvCisgICAgICogYSBmdWxseSBxdWFsaWZpZWQgdGFibGUgbmFtZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBjYXRhbG9nIGFwcGVhcnMgYXQgdGhlIHN0YXJ0IG9mIGEgZnVsbHkKKyAgICAgKiAgICAgICAgIHF1YWxpZmllZCB0YWJsZSBuYW1lLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDYXRhbG9nQXRTdGFydCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGRhdGFiYXNlIGlzIGluIHJlYWQtb25seSBtb2RlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGRhdGFiYXNlIGlzIGluIHJlYWQtb25seSBtb2RlLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUmVhZE9ubHkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHVwZGF0ZXMgYXJlIG1hZGUgdG8gYSBjb3B5IG9mLCBvciBkaXJlY3RseSBvbiwgTGFyZ2UgT2JqZWN0cworICAgICAqICh7QGNvZGUgTE9CfXMpLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdXBkYXRlcyBhcmUgbWFkZSB0byBhIGNvcHkgb2YgdGhlIExhcmdlIE9iamVjdCwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBsb2NhdG9yc1VwZGF0ZUNvcHkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkYXRhYmFzZSBoYW5kbGVzIGNvbmNhdGVuYXRpb25zIGJldHdlZW4ge0Bjb2RlIE5VTEx9IGFuZAorICAgICAqIG5vbi17QGNvZGUgTlVMTH0gdmFsdWVzIGJ5IHByb2R1Y2luZyBhIHtAY29kZSBOVUxMfSBvdXRwdXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgTlVMTH0gdG8gbm9uLXtAY29kZSBOVUxMfSBjb25jYXRlbmF0aW9ucworICAgICAqICAgICAgICAgcHJvZHVjZSBhIHtAY29kZSBOVUxMfSByZXN1bHQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBudWxsUGx1c05vbk51bGxJc051bGwoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHtAY29kZSBOVUxMfSB2YWx1ZXMgYXJlIGFsd2F5cyBzb3J0ZWQgdG8gdGhlIGVuZCBvZiBzb3J0ZWQKKyAgICAgKiByZXN1bHRzIHJlZ2FyZGxlc3Mgb2YgcmVxdWVzdGVkIHNvcnQgb3JkZXIuIFRoaXMgbWVhbnMgdGhhdCB0aGV5IHdpbGwKKyAgICAgKiBhcHBlYXIgYXQgdGhlIGVuZCBvZiBzb3J0ZWQgbGlzdHMgd2hhdGV2ZXIgb3RoZXIgbm9uLXtAY29kZSBOVUxMfSB2YWx1ZXMKKyAgICAgKiBtYXkgYmUgcHJlc2VudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBOVUxMfSB2YWx1ZXMgYXJlIHNvcnRlZCBhdCB0aGUgZW5kLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG51bGxzQXJlU29ydGVkQXRFbmQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHtAY29kZSBOVUxMfSB2YWx1ZXMgYXJlIGFsd2F5cyBzb3J0ZWQgYXQgdGhlIHN0YXJ0IG9mIHRoZQorICAgICAqIHNvcnRlZCBsaXN0LCBpcnJlc3BlY3RpdmUgb2YgdGhlIHNvcnQgb3JkZXIuIFRoaXMgbWVhbnMgdGhhdCB0aGV5IGFwcGVhcgorICAgICAqIGF0IHRoZSBzdGFydCBvZiBzb3J0ZWQgbGlzdHMsIHdoYXRldmVyIG90aGVyIHZhbHVlcyBtYXkgYmUgcHJlc2VudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBOVUxMfSB2YWx1ZXMgYXJlIHNvcnRlZCBhdCB0aGUgc3RhcnQsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbnVsbHNBcmVTb3J0ZWRBdFN0YXJ0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB7QGNvZGUgTlVMTH0gdmFsdWVzIGFyZSBzb3J0ZWQgaGlnaCAtIGkuZS4gdGhleSBhcmUgc29ydGVkCisgICAgICogYXMgaWYgdGhleSBhcmUgaGlnaGVyIHRoYW4gYW55IG90aGVyIHZhbHVlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBOVUxMfSB2YWx1ZXMgYXJlIHNvcnRlZCBoaWdoLCB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG51bGxzQXJlU29ydGVkSGlnaCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIge0Bjb2RlIE5VTEx9IHZhbHVlcyBhcmUgc29ydGVkIGxvdyAtIGkuZS4gdGhleSBhcmUgc29ydGVkIGFzCisgICAgICogaWYgdGhleSBhcmUgbG93ZXIgdGhhbiBhbnkgb3RoZXIgdmFsdWVzLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIE5VTEx9IHZhbHVlcyBhcmUgc29ydGVkIGxvdywge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBudWxsc0FyZVNvcnRlZExvdygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgZGVsZXRlcyBtYWRlIGJ5IG90aGVycyBhcmUgdmlzaWJsZSwgZm9yIGEgc3BlY2lmaWVkIHtAY29kZQorICAgICAqIFJlc3VsdFNldH0gdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUge0Bjb2RlIFJlc3VsdFNldH0uIEl0IG1heSBiZSBlaXRoZXIge0Bjb2RlCisgICAgICogICAgICAgICAgICBSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFl9IG9yIHtAY29kZQorICAgICAqICAgICAgICAgICAgUmVzdWx0U2V0LlRZUEVfU0NST0xMX0lOU0VOU0lUSVZFfSwgb3Ige0Bjb2RlCisgICAgICogICAgICAgICAgICBSZXN1bHRTZXQuVFlQRV9TQ1JPTExfU0VOU0lUSVZFfSkKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBvdGhlcnMnIGRlbGV0ZXMgYXJlIHZpc2libGUsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gb3RoZXJzRGVsZXRlc0FyZVZpc2libGUoaW50IHR5cGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgaW5zZXJ0cyBtYWRlIGJ5IG90aGVycyBhcmUgdmlzaWJsZSwgZm9yIGEgc3BlY2lmaWVkIHtAY29kZQorICAgICAqIFJlc3VsdFNldH0gdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUge0Bjb2RlIFJlc3VsdFNldH0uIE1heSBiZSB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFJlc3VsdFNldC5UWVBFX0ZPUldBUkRfT05MWX0sIG9yIHtAY29kZQorICAgICAqICAgICAgICAgICAgUmVzdWx0U2V0LlRZUEVfU0NST0xMX0lOU0VOU0lUSVZFfSwgb3Ige0Bjb2RlCisgICAgICogICAgICAgICAgICBSZXN1bHRTZXQuVFlQRV9TQ1JPTExfU0VOU0lUSVZFfQorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIG90aGVycycgaW5zZXJ0cyBhcmUgdmlzaWJsZSwgb3RoZXJ3aXNlIHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBvdGhlcnNJbnNlcnRzQXJlVmlzaWJsZShpbnQgdHlwZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB1cGRhdGVzIG1hZGUgYnkgb3RoZXJzIGFyZSB2aXNpYmxlLCBmb3IgYSBzcGVjaWZpZWQge0Bjb2RlCisgICAgICogUmVzdWx0U2V0fSB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSB7QGNvZGUgUmVzdWx0U2V0fS4gTWF5IGJlIHtAY29kZQorICAgICAqICAgICAgICAgICAgUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZfSwgb3Ige0Bjb2RlCisgICAgICogICAgICAgICAgICBSZXN1bHRTZXQuVFlQRV9TQ1JPTExfSU5TRU5TSVRJVkV9LCBvciB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkV9CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgb3RoZXJzJyBpbnNlcnRzIGFyZSB2aXNpYmxlLCBvdGhlcndpc2Uge0Bjb2RlCisgICAgICogICAgICAgICBmYWxzZX0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG90aGVyc1VwZGF0ZXNBcmVWaXNpYmxlKGludCB0eXBlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEge0Bjb2RlIFJlc3VsdFNldH0gY2FuIHNlZSBpdHMgb3duIGRlbGV0ZXMsIGZvciBhCisgICAgICogc3BlY2lmaWVkIHtAY29kZSBSZXN1bHRTZXR9IHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHR5cGUgb2YgdGhlIHtAY29kZSBSZXN1bHRTZXR9OiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFJlc3VsdFNldC5UWVBFX0ZPUldBUkRfT05MWX0sIHtAY29kZQorICAgICAqICAgICAgICAgICAgUmVzdWx0U2V0LlRZUEVfU0NST0xMX0lOU0VOU0lUSVZFfSwgb3Ige0Bjb2RlCisgICAgICogICAgICAgICAgICBSZXN1bHRTZXQuVFlQRV9TQ1JPTExfU0VOU0lUSVZFfQorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBkZWxldGVzIGFyZSBzZWVuIGJ5IHRoZSB7QGNvZGUKKyAgICAgKiAgICAgICAgIFJlc3VsdFNldH0gaXRzZWxmLCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gb3duRGVsZXRlc0FyZVZpc2libGUoaW50IHR5cGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgYSB7QGNvZGUgUmVzdWx0U2V0fSBjYW4gc2VlIGl0cyBvd24gaW5zZXJ0cywgZm9yIGEKKyAgICAgKiBzcGVjaWZpZWQge0Bjb2RlIFJlc3VsdFNldH0gdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUge0Bjb2RlIFJlc3VsdFNldH06IHtAY29kZQorICAgICAqICAgICAgICAgICAgUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZfSwge0Bjb2RlCisgICAgICogICAgICAgICAgICBSZXN1bHRTZXQuVFlQRV9TQ1JPTExfSU5TRU5TSVRJVkV9LCBvciB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkV9CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGluc2VydHMgYXJlIHNlZW4gYnkgdGhlIHtAY29kZQorICAgICAqICAgICAgICAgUmVzdWx0U2V0fSBpdHNlbGYsIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBvd25JbnNlcnRzQXJlVmlzaWJsZShpbnQgdHlwZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciBhIHtAY29kZSBSZXN1bHRTZXR9IGNhbiBzZWUgaXRzIG93biB1cGRhdGVzLCBmb3IgYQorICAgICAqIHNwZWNpZmllZCB7QGNvZGUgUmVzdWx0U2V0fSB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSB7QGNvZGUgUmVzdWx0U2V0fToge0Bjb2RlCisgICAgICogICAgICAgICAgICBSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFl9LCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFJlc3VsdFNldC5UWVBFX1NDUk9MTF9JTlNFTlNJVElWRX0sIG9yIHtAY29kZQorICAgICAqICAgICAgICAgICAgUmVzdWx0U2V0LlRZUEVfU0NST0xMX1NFTlNJVElWRX0KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgdXBkYXRlcyBhcmUgc2VlbiBieSB0aGUge0Bjb2RlCisgICAgICogICAgICAgICBSZXN1bHRTZXR9IGl0c2VsZiwgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG93blVwZGF0ZXNBcmVWaXNpYmxlKGludCB0eXBlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkYXRhYmFzZSB0cmVhdHMgU1FMIGlkZW50aWZpZXJzIHRoYXQgYXJlIGluIG1peGVkCisgICAgICogY2FzZSAoYW5kIHVucXVvdGVkKSBhcyBjYXNlIGluc2Vuc2l0aXZlLiBJZiB7QGNvZGUgdHJ1ZX0gdGhlbiB0aGUKKyAgICAgKiBkYXRhYmFzZSBzdG9yZXMgdGhlbSBpbiBsb3dlciBjYXNlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdW5xdW90ZWQgU1FMIGlkZW50aWZpZXJzIGFyZSBzdG9yZWQgaW4gbG93ZXIKKyAgICAgKiAgICAgICAgIGNhc2UsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdG9yZXNMb3dlckNhc2VJZGVudGlmaWVycygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGRhdGFiYXNlIGNvbnNpZGVycyBtaXhlZCBjYXNlIHF1b3RlZCBTUUwKKyAgICAgKiBpZGVudGlmaWVycyBhcyBjYXNlIGluc2Vuc2l0aXZlIGFuZCBzdG9yZXMgdGhlbSBpbiBsb3dlciBjYXNlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgcXVvdGVkIFNRTCBpZGVudGlmaWVycyBhcmUgc3RvcmVkIGluIGxvd2VyIGNhc2UsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3RvcmVzTG93ZXJDYXNlUXVvdGVkSWRlbnRpZmllcnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkYXRhYmFzZSBjb25zaWRlcnMgbWl4ZWQgY2FzZSB1bnF1b3RlZCBTUUwKKyAgICAgKiBpZGVudGlmaWVycyBhcyBjYXNlIGluc2Vuc2l0aXZlIGFuZCBzdG9yZXMgdGhlbSBpbiBtaXhlZCBjYXNlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdW5xdW90ZWQgU1FMIGlkZW50aWZpZXJzIGFzIHN0b3JlZCBpbiBtaXhlZCBjYXNlLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN0b3Jlc01peGVkQ2FzZUlkZW50aWZpZXJzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgZGF0YWJhc2UgY29uc2lkZXJzIGlkZW50aWZpZXJzIGFzIGNhc2UgaW5zZW5zaXRpdmUKKyAgICAgKiBpZiB0aGV5IGFyZSBtaXhlZCBjYXNlIHF1b3RlZCBTUUwuIFRoZSBkYXRhYmFzZSBzdG9yZXMgdGhlbSBpbiBtaXhlZAorICAgICAqIGNhc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBxdW90ZWQgU1FMIGlkZW50aWZpZXJzIGFyZSBzdG9yZWQgaW4gbWl4ZWQgY2FzZSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdG9yZXNNaXhlZENhc2VRdW90ZWRJZGVudGlmaWVycygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGRhdGFiYXNlIGNvbnNpZGVycyBtaXhlZCBjYXNlIHVucXVvdGVkIFNRTAorICAgICAqIGlkZW50aWZpZXJzIGFzIGNhc2UgaW5zZW5zaXRpdmUgYW5kIHN0b3JlcyB0aGVtIGluIHVwcGVyIGNhc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB1bnF1b3RlZCBTUUwgaWRlbnRpZmllcnMgYXJlIHN0b3JlZCBpbiB1cHBlcgorICAgICAqICAgICAgICAgY2FzZSwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN0b3Jlc1VwcGVyQ2FzZUlkZW50aWZpZXJzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgZGF0YWJhc2UgY29uc2lkZXJzIG1peGVkIGNhc2UgcXVvdGVkIFNRTAorICAgICAqIGlkZW50aWZpZXJzIGFzIGNhc2UgaW5zZW5zaXRpdmUgYW5kIHN0b3JlcyB0aGVtIGluIHVwcGVyIGNhc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBxdW90ZWQgU1FMIGlkZW50aWZpZXJzIGFyZSBzdG9yZWQgaW4gdXBwZXIgY2FzZSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdG9yZXNVcHBlckNhc2VRdW90ZWRJZGVudGlmaWVycygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGRhdGFiYXNlIHN1cHBvcnRzIHtAY29kZSBBTFRFUiBUQUJMRX0gb3BlcmF0aW9uIHdpdGgKKyAgICAgKiB7QGNvZGUgQUREIENPTFVNTn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgQUxURVIgVEFCTEV9IHdpdGgge0Bjb2RlIEFERCBDT0xVTU59IGlzCisgICAgICogICAgICAgICBzdXBwb3J0ZWQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c0FsdGVyVGFibGVXaXRoQWRkQ29sdW1uKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgZGF0YWJhc2Ugc3VwcG9ydHMge0Bjb2RlIEFMVEVSIFRBQkxFfSBvcGVyYXRpb24gd2l0aAorICAgICAqIHtAY29kZSBEUk9QIENPTFVNTn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgQUxURVIgVEFCTEV9IHdpdGgge0Bjb2RlIERST1AgQ09MVU1OfSBpcworICAgICAqICAgICAgICAgc3VwcG9ydGVkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNBbHRlclRhYmxlV2l0aERyb3BDb2x1bW4oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkYXRhYmFzZSBzdXBwb3J0cyB0aGUgQU5TSTkyIGVudHJ5IGxldmVsIFNRTCBncmFtbWFyLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIEFOU0k5MiBlbnRyeSBsZXZlbCBTUUwgZ3JhbW1hciBpcyBzdXBwb3J0ZWQsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNBTlNJOTJFbnRyeUxldmVsU1FMKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgZGF0YWJhc2Ugc3VwcG9ydHMgdGhlIEFOU0k5MiBmdWxsIFNRTCBncmFtbWFyLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIEFOU0k5MiBmdWxsIFNRTCBncmFtbWFyIGlzIHN1cHBvcnRlZCwge0Bjb2RlCisgICAgICogICAgICAgICBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c0FOU0k5MkZ1bGxTUUwoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkYXRhYmFzZSBzdXBwb3J0cyB0aGUgQU5TSTkyIGludGVybWVkaWF0ZSBTUUwgR3JhbW1hci4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBBTlNJOTIgaW50ZXJtZWRpYXRlIFNRTCBncmFtbWFyIGlzIHN1cHBvcnRlZCwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c0FOU0k5MkludGVybWVkaWF0ZVNRTCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGRhdGFiYXNlIHN1cHBvcnRzIGJhdGNoIHVwZGF0ZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBiYXRjaCB1cGRhdGVzIGFyZSBzdXBwb3J0ZWQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNCYXRjaFVwZGF0ZXMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGNhdGFsb2cgbmFtZXMgbWF5IGJlIHVzZWQgaW4gZGF0YSBtYW5pcHVsYXRpb24KKyAgICAgKiBzdGF0ZW1lbnRzLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgY2F0YWxvZyBuYW1lcyBjYW4gYmUgdXNlZCBpbiBkYXRhIG1hbmlwdWxhdGlvbgorICAgICAqICAgICAgICAgc3RhdGVtZW50cywge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzQ2F0YWxvZ3NJbkRhdGFNYW5pcHVsYXRpb24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGNhdGFsb2cgbmFtZXMgY2FuIGJlIHVzZWQgaW4gaW5kZXggZGVmaW5pdGlvbiBzdGF0ZW1lbnRzLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgY2F0YWxvZyBuYW1lcyBjYW4gYmUgdXNlZCBpbiBpbmRleCBkZWZpbml0aW9uCisgICAgICogICAgICAgICBzdGF0ZW1lbnRzLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNDYXRhbG9nc0luSW5kZXhEZWZpbml0aW9ucygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgY2F0YWxvZyBuYW1lcyBjYW4gYmUgdXNlZCBpbiBwcml2aWxlZ2UgZGVmaW5pdGlvbgorICAgICAqIHN0YXRlbWVudHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBjYXRhbG9nIG5hbWVzIGNhbiBiZSB1c2VkIGluIHByaXZpbGVnZSBkZWZpbml0aW9uCisgICAgICogICAgICAgICBzdGF0ZW1lbnRzLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNDYXRhbG9nc0luUHJpdmlsZWdlRGVmaW5pdGlvbnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGNhdGFsb2cgbmFtZXMgY2FuIGJlIHVzZWQgaW4gcHJvY2VkdXJlIGNhbGwgc3RhdGVtZW50cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGNhdGFsb2cgbmFtZXMgY2FuIGJlIHVzZWQgaW4gcHJvY2VkdXJlIGNhbGwKKyAgICAgKiAgICAgICAgIHN0YXRlbWVudHMuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzQ2F0YWxvZ3NJblByb2NlZHVyZUNhbGxzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciBjYXRhbG9nIG5hbWVzIG1heSBiZSB1c2VkIGluIHRhYmxlIGRlZmluaXRpb24gc3RhdGVtZW50cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGNhdGFsb2cgbmFtZXMgY2FuIGJlIHVzZWQgaW4gZGVmaW5pdGlvbgorICAgICAqICAgICAgICAgc3RhdGVtZW50cywge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzQ2F0YWxvZ3NJblRhYmxlRGVmaW5pdGlvbnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkYXRhYmFzZSBzdXBwb3J0cyBjb2x1bW4gYWxpYXNpbmcuCisgICAgICogPHA+CisgICAgICogSWYgYWxpYXNpbmcgaXMgc3VwcG9ydGVkLCB0aGVuIHRoZSBTUUwgQVMgY2xhdXNlIGlzIHVzZWQgdG8gcHJvdmlkZSBuYW1lcworICAgICAqIGZvciBjb21wdXRlZCBjb2x1bW5zIGFuZCBwcm92aWRlIGFsaWFzIG5hbWVzIGZvciBjb2x1bW5zLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgY29sdW1uIGFsaWFzaW5nIGlzIHN1cHBvcnRlZCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c0NvbHVtbkFsaWFzaW5nKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgZGF0YWJhc2Ugc3VwcG9ydHMgdGhlIHtAY29kZSBDT05WRVJUfSBvcGVyYXRpb24gYmV0d2VlbgorICAgICAqIFNRTCB0eXBlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSB7QGNvZGUgQ09OVkVSVH0gb3BlcmF0aW9uIGlzIHN1cHBvcnRlZCwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c0NvbnZlcnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkYXRhYmFzZSBzdXBwb3J0cyB7QGNvZGUgQ09OVkVSVH0gb3BlcmF0aW9uIGZvciB0d28KKyAgICAgKiBzdXBwbGllZCBTUUwgdHlwZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZnJvbVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBUeXBlIHRvIGNvbnZlcnQgZnJvbSwgYXMgZGVmaW5lZCBieSB7QGNvZGUgamF2YS5zcWwuVHlwZXN9CisgICAgICogQHBhcmFtIHRvVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIFR5cGUgdG8gY29udmVydCB0bywgYXMgZGVmaW5lZCBieSB7QGNvZGUgamF2YS5zcWwuVHlwZXN9CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHtAY29kZSBDT05WRVJUfSBvcGVyYXRpb24gaXMgc3VwcG9ydGVkIGZvcgorICAgICAqICAgICAgICAgdGhlc2UgdHlwZXMsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c0NvbnZlcnQoaW50IGZyb21UeXBlLCBpbnQgdG9UeXBlKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgZGF0YWJhc2Ugc3VwcG9ydHMgdGhlIENvcmUgU1FMIEdyYW1tYXIgZm9yIE9EQkMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgQ29yZSBTUUwgR3JhbW1hciBpcyBzdXBwb3J0ZWQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNDb3JlU1FMR3JhbW1hcigpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGRhdGFiYXNlIHN1cHBvcnRzIGNvcnJlbGF0ZWQgc3ViLXF1ZXJpZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZGF0YWJhc2UgZG9lcyBzdXBwb3J0IGNvcnJlbGF0ZWQgc3ViLXF1ZXJpZXMKKyAgICAgKiAgICAgICAgIGFuZCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNDb3JyZWxhdGVkU3VicXVlcmllcygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGRhdGFiYXNlIGFsbG93cyBib3RoIGRhdGEgZGVmaW5pdGlvbiBhbmQgZGF0YQorICAgICAqIG1hbmlwdWxhdGlvbiBzdGF0ZW1lbnRzIGluc2lkZSBhIHRyYW5zYWN0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYm90aCB0eXBlcyBvZiBzdGF0ZW1lbnQgYXJlIHBlcm1pdHRlZCwge0Bjb2RlCisgICAgICogICAgICAgICBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c0RhdGFEZWZpbml0aW9uQW5kRGF0YU1hbmlwdWxhdGlvblRyYW5zYWN0aW9ucygpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkYXRhYmFzZSBvbmx5IGFsbG93cyBkYXRhIG1hbmlwdWxhdGlvbiBzdGF0ZW1lbnRzIGluc2lkZQorICAgICAqIGEgdHJhbnNhY3Rpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBkYXRhIG1hbmlwdWxhdGlvbiBzdGF0ZW1lbnRzIGFyZSBwZXJtaXR0ZWQgb25seSB3aXRoaW4gYSB0cmFuc2FjdGlvbiwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c0RhdGFNYW5pcHVsYXRpb25UcmFuc2FjdGlvbnNPbmx5KCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGFibGUgY29ycmVsYXRpb24gbmFtZXMgYXJlIHJlcXVpcmVkIHRvIGJlIGRpZmZlcmVudCBmcm9tCisgICAgICogdGhlIG5hbWVzIG9mIHRoZSB0YWJsZXMsIHdoZW4gdGhleSBhcmUgc3VwcG9ydGVkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgY29ycmVsYXRpb24gbmFtZXMgbXVzdCBiZSBkaWZmZXJlbnQgZnJvbSB0YWJsZQorICAgICAqICAgICAgICAgbmFtZXMsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c0RpZmZlcmVudFRhYmxlQ29ycmVsYXRpb25OYW1lcygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgZXhwcmVzc2lvbnMgaW4ge0Bjb2RlIE9SREVSIEJZfSBsaXN0cyBhcmUgc3VwcG9ydGVkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgZXhwcmVzc2lvbnMgaW4ge0Bjb2RlIE9SREVSIEJZfSBsaXN0cyBhcmUKKyAgICAgKiAgICAgICAgIHN1cHBvcnRlZC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNFeHByZXNzaW9uc0luT3JkZXJCeSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIEV4dGVuZGVkIFNRTCBHcmFtbWFyIGZvciBPREJDIGlzIHN1cHBvcnRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBFeHRlbmRlZCBTUUwgR3JhbW1hciBpcyBzdXBwb3J0ZWQsIHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNFeHRlbmRlZFNRTEdyYW1tYXIoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkYXRhYmFzZSBzdXBwb3J0cyBmdWxsIG5lc3RlZCBvdXRlciBqb2lucy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGZ1bGwgbmVzdGVkIG91dGVyIGpvaW5zIGFyZSBzdXBwb3J0ZWQsIHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNGdWxsT3V0ZXJKb2lucygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgYXV0byBnZW5lcmF0ZWQga2V5cyBjYW4gYmUgcmV0dXJuZWQgd2hlbiBhIHN0YXRlbWVudAorICAgICAqIGV4ZWN1dGVzLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYXV0byBnZW5lcmF0ZWQga2V5cyBjYW4gYmUgcmV0dXJuZWQsIHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNHZXRHZW5lcmF0ZWRLZXlzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgZGF0YWJhc2Ugc3VwcG9ydHMge0Bjb2RlIEdST1VQIEJZfSBjbGF1c2VzLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHtAY29kZSBHUk9VUCBCWX0gY2xhdXNlIGlzIHN1cHBvcnRlZCwge0Bjb2RlCisgICAgICogICAgICAgICBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c0dyb3VwQnkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkYXRhYmFzZSBzdXBwb3J0cyB1c2luZyBhIGNvbHVtbiBuYW1lIGluIGEge0Bjb2RlIEdST1VQCisgICAgICogQll9IGNsYXVzZSBub3QgaW5jbHVkZWQgaW4gdGhlIHtAY29kZSBTRUxFQ1R9IHN0YXRlbWVudCBhcyBsb25nIGFzIGFsbCBvZgorICAgICAqIHRoZSBjb2x1bW5zIGluIHRoZSB7QGNvZGUgU0VMRUNUfSBzdGF0ZW1lbnQgYXJlIHVzZWQgaW4gdGhlIHtAY29kZSBHUk9VUAorICAgICAqIEJZfSBjbGF1c2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgR1JPVVAgQll9IGNsYXVzZXMgY2FuIHVzZSBjb2x1bW4gbmFtZXMgaW4KKyAgICAgKiAgICAgICAgIHRoaXMgd2F5LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNHcm91cEJ5QmV5b25kU2VsZWN0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgZGF0YWJhc2Ugc3VwcG9ydHMgdXNpbmcgYSBjb2x1bW4gbmFtZSBpbiBhIHtAY29kZSBHUk9VUAorICAgICAqIEJZfSBjbGF1c2UgdGhhdCBpcyBub3QgaW4gdGhlIHtAY29kZSBTRUxFQ1R9IHN0YXRlbWVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBHUk9VUCBCWX0gY2xhdXNlIGNhbiB1c2UgYSBjb2x1bW4gbmFtZSBub3QKKyAgICAgKiAgICAgICAgIGluIHRoZSB7QGNvZGUgU0VMRUNUfSBzdGF0ZW1lbnQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c0dyb3VwQnlVbnJlbGF0ZWQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkYXRhYmFzZSBzdXBwb3J0cyBTUUwgSW50ZWdyaXR5IEVuaGFuY2VtZW50CisgICAgICogRmFjaWxpdHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgSW50ZWdyaXR5IEVuaGFuY2VtZW50IEZhY2lsaXR5IGlzIHN1cHBvcnRlZCwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c0ludGVncml0eUVuaGFuY2VtZW50RmFjaWxpdHkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkYXRhYmFzZSBzdXBwb3J0cyBhIHtAY29kZSBMSUtFfSBlc2NhcGUgY2xhdXNlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgTElLRSBlc2NhcGUgY2xhdXNlIGlzIHN1cHBvcnRlZCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c0xpa2VFc2NhcGVDbGF1c2UoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkYXRhYmFzZSBwcm92aWRlcyBsaW1pdGVkIHN1cHBvcnQgZm9yIG91dGVyIGpvaW4KKyAgICAgKiBvcGVyYXRpb25zLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlcmUgaXMgbGltaXRlZCBzdXBwb3J0IGZvciBvdXRlciBqb2luCisgICAgICogICAgICAgICBvcGVyYXRpb25zLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4gVGhpcyB3aWxsIGJlIHtAY29kZSB0cnVlfSBpZgorICAgICAqICAgICAgICAge0Bjb2RlIHN1cHBvcnRzRnVsbE91dGVySm9pbnN9IHJldHVybnMge0Bjb2RlIHRydWV9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c0xpbWl0ZWRPdXRlckpvaW5zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgZGF0YWJhc2Ugc3VwcG9ydHMgTWluaW11bSBTUUwgR3JhbW1hciBmb3IgT0RCQy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBNaW5pbXVtIFNRTCBHcmFtbWFyIGlzIHN1cHBvcnRlZCwge0Bjb2RlCisgICAgICogICAgICAgICBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c01pbmltdW1TUUxHcmFtbWFyKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgZGF0YWJhc2UgdHJlYXRzIG1peGVkIGNhc2UgdW5xdW90ZWQgU1FMIGlkZW50aWZpZXJzIGFzCisgICAgICogY2FzZSBzZW5zaXRpdmUgc3RvcmluZyB0aGVtIGluIG1peGVkIGNhc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB1bnF1b3RlZCBTUUwgaWRlbnRpZmllcnMgYXJlIHN0b3JlZCBpbiBtaXhlZAorICAgICAqICAgICAgICAgY2FzZSwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzTWl4ZWRDYXNlSWRlbnRpZmllcnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkYXRhYmFzZSBjb25zaWRlcnMgbWl4ZWQgY2FzZSBxdW90ZWQgU1FMCisgICAgICogaWRlbnRpZmllcnMgYXMgY2FzZSBzZW5zaXRpdmUsIHN0b3JpbmcgdGhlbSBpbiBtaXhlZCBjYXNlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgcXVvdGVkIFNRTCBpZGVudGlmaWVycyBhcmUgc3RvcmVkIGluIG1peGVkIGNhc2UsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNNaXhlZENhc2VRdW90ZWRJZGVudGlmaWVycygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgaXQgaXMgcG9zc2libGUgZm9yIGEgc2luZ2xlIHtAY29kZSBDYWxsYWJsZVN0YXRlbWVudH0gdG8KKyAgICAgKiByZXR1cm4gbXVsdGlwbGUge0Bjb2RlIFJlc3VsdFNldH1zIHNpbXVsdGFuZW91c2x5LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYSBzaW5nbGUge0Bjb2RlIENhbGxhYmxlU3RhdGVtZW50fSBjYW4gcmV0dXJuCisgICAgICogICAgICAgICBtdWx0aXBsZSB7QGNvZGUgUmVzdWx0U2V0fXMgc2ltdWx0YW5lb3VzbHksIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNNdWx0aXBsZU9wZW5SZXN1bHRzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciByZXRyaWV2aW5nIG11bHRpcGxlIHtAY29kZSBSZXN1bHRTZXR9cyBmcm9tIGEgc2luZ2xlCisgICAgICogY2FsbCB0byB0aGUge0Bjb2RlIGV4ZWN1dGV9IG1ldGhvZCBpcyBzdXBwb3J0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBtdWx0aXBsZSB7QGNvZGUgUmVzdWx0U2V0fXMgY2FuIGJlIHJldHJpZXZlZCwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c011bHRpcGxlUmVzdWx0U2V0cygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgbXVsdGlwbGUgc2ltdWx0YW5lb3VzIHRyYW5zYWN0aW9ucyBvbgorICAgICAqIGRpZmZlcmVudCBjb25uZWN0aW9ucyBhcmUgc3VwcG9ydGVkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgbXVsdGlwbGUgb3BlbiB0cmFuc2FjdGlvbnMgYXJlIHN1cHBvcnRlZCwge0Bjb2RlCisgICAgICogICAgICAgICBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c011bHRpcGxlVHJhbnNhY3Rpb25zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciBjYWxsYWJsZSBzdGF0ZW1lbnRzIHdpdGggbmFtZWQgcGFyYW1ldGVycyBpcyBzdXBwb3J0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBuYW1lZCBwYXJhbWV0ZXJzIGNhbiBiZSB1c2VkIHdpdGggY2FsbGFibGUKKyAgICAgKiAgICAgICAgIHN0YXRlbWVudHMsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c05hbWVkUGFyYW1ldGVycygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgY29sdW1ucyBpbiB0aGUgZGF0YWJhc2UgY2FuIGJlIGRlZmluZWQgYXMgbm9uLW51bGxhYmxlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgY29sdW1ucyBjYW4gYmUgZGVmaW5lZCBub24tbnVsbGFibGUsIHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNOb25OdWxsYWJsZUNvbHVtbnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGtlZXBpbmcgY3Vyc29ycyBvcGVuIGFjcm9zcyBjb21taXQgb3BlcmF0aW9ucyBpcworICAgICAqIHN1cHBvcnRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGN1cnNvcnMgY2FuIGJlIGtlcHQgb3BlbiBhY3Jvc3MgY29tbWl0CisgICAgICogICAgICAgICBvcGVyYXRpb25zLCB7QGNvZGUgZmFsc2V9IGlmIHRoZXkgbWlnaHQgZ2V0IGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNPcGVuQ3Vyc29yc0Fjcm9zc0NvbW1pdCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGRhdGFiYXNlIGNhbiBrZWVwIGN1cnNvcnMgb3BlbiBhY3Jvc3Mgcm9sbGJhY2sKKyAgICAgKiBvcGVyYXRpb25zLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgY3Vyc29ycyBjYW4gYmUga2VwdCBvcGVuIGFjcm9zcyByb2xsYmFjaworICAgICAqICAgICAgICAgb3BlcmF0aW9ucywge0Bjb2RlIGZhbHNlfSBpZiB0aGV5IG1pZ2h0IGdldCBjbG9zZWQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzT3BlbkN1cnNvcnNBY3Jvc3NSb2xsYmFjaygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIga2VlcGluZyBzdGF0ZW1lbnRzIG9wZW4gYWNyb3NzIGNvbW1pdCBvcGVyYXRpb25zIGlzCisgICAgICogc3VwcG9ydGVkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgc3RhdGVtZW50cyBjYW4gYmUga2VwdCBvcGVuLCB7QGNvZGUgZmFsc2V9IGlmCisgICAgICogICAgICAgICB0aGV5IG1pZ2h0IG5vdC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNPcGVuU3RhdGVtZW50c0Fjcm9zc0NvbW1pdCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIga2VlcGluZyBzdGF0ZW1lbnRzIG9wZW4gYWNyb3NzIHJvbGxiYWNrIG9wZXJhdGlvbnMgaXMKKyAgICAgKiBzdXBwb3J0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBzdGF0ZW1lbnRzIGNhbiBiZSBrZXB0IG9wZW4sIHtAY29kZSBmYWxzZX0gaWYKKyAgICAgKiAgICAgICAgIHRoZXkgbWlnaHQgbm90LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c09wZW5TdGF0ZW1lbnRzQWNyb3NzUm9sbGJhY2soKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHVzaW5nIGEgY29sdW1uIGluIGFuIHtAY29kZSBPUkRFUiBCWX0gY2xhdXNlIHRoYXQgaXMKKyAgICAgKiBub3QgaW4gdGhlIHtAY29kZSBTRUxFQ1R9IHN0YXRlbWVudCBpcyBzdXBwb3J0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBpdCBpcyBwb3NzaWJsZSB0byB7QGNvZGUgT1JERVJ9IHVzaW5nIGEgY29sdW1uCisgICAgICogICAgICAgICBub3QgaW4gdGhlIHtAY29kZSBTRUxFQ1R9LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNPcmRlckJ5VW5yZWxhdGVkKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciBvdXRlciBqb2luIG9wZXJhdGlvbnMgYXJlIHN1cHBvcnRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIG91dGVyIGpvaW4gb3BlcmF0aW9ucyBhcmUgc3VwcG9ydGVkLCB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzT3V0ZXJKb2lucygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgcG9zaXRpb25lZCB7QGNvZGUgREVMRVRFfSBzdGF0ZW1lbnRzIGFyZSBzdXBwb3J0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZGF0YWJhc2Ugc3VwcG9ydHMgcG9zaXRpb25lZCB7QGNvZGUgREVMRVRFfQorICAgICAqICAgICAgICAgc3RhdGVtZW50cy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNQb3NpdGlvbmVkRGVsZXRlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciBwb3NpdGlvbmVkIHtAY29kZSBVUERBVEV9IHN0YXRlbWVudHMgYXJlIHN1cHBvcnRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBkYXRhYmFzZSBzdXBwb3J0cyBwb3NpdGlvbmVkIHtAY29kZSBVUERBVEV9CisgICAgICogICAgICAgICBzdGF0ZW1lbnRzLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNQb3NpdGlvbmVkVXBkYXRlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGVyZSBpcyBzdXBwb3J0IGZvciBhIGdpdmVuIGNvbmN1cnJlbmN5IHN0eWxlIGZvciB0aGUKKyAgICAgKiBnaXZlbiB7QGNvZGUgUmVzdWx0U2V0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIFJlc3VsdFNldH0gdHlwZSwgYXMgZGVmaW5lZCBpbiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIGphdmEuc3FsLlJlc3VsdFNldH06CisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+e0Bjb2RlIFJlc3VsdFNldC5UWVBFX0ZPUldBUkRfT05MWX08L2xpPgorICAgICAqICAgICAgICAgICAgPGxpPntAY29kZSBSZXN1bHRTZXQuVFlQRV9TQ1JPTExfSU5TRU5TSVRJVkV9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGNvZGUgUmVzdWx0U2V0LlRZUEVfU0NST0xMX1NFTlNJVElWRX08L2xpPgorICAgICAqICAgICAgICAgICAgPC91bD4KKyAgICAgKiBAcGFyYW0gY29uY3VycmVuY3kKKyAgICAgKiAgICAgICAgICAgIGEgY29uY3VycmVuY3kgdHlwZSwgd2hpY2ggbWF5IGJlIG9uZSBvZiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFJlc3VsdFNldC5DT05DVVJfUkVBRF9PTkxZfSBvciB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFJlc3VsdFNldC5DT05DVVJfVVBEQVRBQkxFfS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGF0IGNvbmN1cnJlbmN5IGFuZCB7QGNvZGUgUmVzdWx0U2V0fSB0eXBlCisgICAgICogICAgICAgICBwYWlyaW5nIGlzIHN1cHBvcnRlZCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNSZXN1bHRTZXRDb25jdXJyZW5jeShpbnQgdHlwZSwgaW50IGNvbmN1cnJlbmN5KQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgc3VwcGxpZWQge0Bjb2RlIFJlc3VsdFNldH0gaG9sZGFiaWxpdHkgbW9kZSBpcworICAgICAqIHN1cHBvcnRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob2xkYWJpbGl0eQorICAgICAqICAgICAgICAgICAgYXMgc3BlY2lmaWVkIGluIHtAY29kZSBqYXZhLnNxbC5SZXN1bHRTZXR9OiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFJlc3VsdFNldC5IT0xEX0NVUlNPUlNfT1ZFUl9DT01NSVR9IG9yIHtAY29kZQorICAgICAqICAgICAgICAgICAgUmVzdWx0U2V0LkNMT1NFX0NVUlNPUlNfQVRfQ09NTUlUfQorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBnaXZlbiBSZXN1bHRTZXQgaG9sZGFiaWxpdHkgaXMgc3VwcG9ydGVkIGFuZAorICAgICAqICAgICAgICAgaWYgaXQgaXNuJ3QgdGhlbiB7QGNvZGUgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c1Jlc3VsdFNldEhvbGRhYmlsaXR5KGludCBob2xkYWJpbGl0eSkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHN1cHBsaWVkIHtAY29kZSBSZXN1bHRTZXR9IHR5cGUgaXMgc3VwcG9ydGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgUmVzdWx0U2V0fSB0eXBlIGFzIGRlZmluZWQgaW4ge0Bjb2RlCisgICAgICogICAgICAgICAgICBqYXZhLnNxbC5SZXN1bHRTZXR9OiB7QGNvZGUgUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZfSwKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBSZXN1bHRTZXQuVFlQRV9TQ1JPTExfSU5TRU5TSVRJVkV9LCBvciB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkV9CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHtAY29kZSBSZXN1bHRTZXR9IHR5cGUgaXMgc3VwcG9ydGVkLCB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzUmVzdWx0U2V0VHlwZShpbnQgdHlwZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciBzYXZlcG9pbnRzIGZvciB0cmFuc2FjdGlvbnMgYXJlIHN1cHBvcnRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHNhdmVwb2ludHMgYXJlIHN1cHBvcnRlZCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c1NhdmVwb2ludHMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgc2NoZW1hIG5hbWUgbWF5IGJlIHVzZWQgaW4gYSBkYXRhIG1hbmlwdWxhdGlvbgorICAgICAqIHN0YXRlbWVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGEgc2NoZW1hIG5hbWUgY2FuIGJlIHVzZWQgaW4gYSBkYXRhIG1hbmlwdWxhdGlvbiwKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c1NjaGVtYXNJbkRhdGFNYW5pcHVsYXRpb24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgc2NoZW1hIG5hbWUgbWF5IGJlIHVzZWQgaW4gYW4gaW5kZXggZGVmaW5pdGlvbgorICAgICAqIHN0YXRlbWVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGEgc2NoZW1hIG5hbWUgY2FuIGJlIHVzZWQgaW4gYW4gaW5kZXggZGVmaW5pdGlvbiwKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c1NjaGVtYXNJbkluZGV4RGVmaW5pdGlvbnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgZGF0YWJhc2Ugc2NoZW1hIG5hbWUgY2FuIGJlIHVzZWQgaW4gYSBwcml2aWxlZ2UKKyAgICAgKiBkZWZpbml0aW9uIHN0YXRlbWVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGEgZGF0YWJhc2Ugc2NoZW1hIG5hbWUgbWF5IGJlIHVzZWQgaW4gYSBwcml2aWxlZ2UKKyAgICAgKiAgICAgICAgIGRlZmluaXRpb24sIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzU2NoZW1hc0luUHJpdmlsZWdlRGVmaW5pdGlvbnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgcHJvY2VkdXJlIGNhbGwgc3RhdGVtZW50IG1heSBiZSBjb250YWluIGluIGEgc2NoZW1hIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBhIHNjaGVtYSBuYW1lIGNhbiBiZSB1c2VkIGluIGEgcHJvY2VkdXJlIGNhbGwsCisgICAgICogICAgICAgICBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNTY2hlbWFzSW5Qcm9jZWR1cmVDYWxscygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgYSBzY2hlbWEgbmFtZSBjYW4gYmUgdXNlZCBpbiBhIHRhYmxlIGRlZmluaXRpb24gc3RhdGVtZW50LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYSBzY2hlbWEgbmFtZSBjYW4gYmUgdXNlZCBpbiBhIHRhYmxlIGRlZmluaXRpb24sCisgICAgICogICAgICAgICBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNTY2hlbWFzSW5UYWJsZURlZmluaXRpb25zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUge0Bjb2RlIFNFTEVDVCBGT1IgVVBEQVRFfSBzdGF0ZW1lbnQgaXMgc3VwcG9ydGVkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIFNFTEVDVCBGT1IgVVBEQVRFfSBzdGF0ZW1lbnRzIGFyZQorICAgICAqICAgICAgICAgc3VwcG9ydGVkLCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNTZWxlY3RGb3JVcGRhdGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHN0YXRlbWVudCBwb29saW5nIGlzIHN1cHBvcnRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IG9mIHRoZSBkYXRhYmFzZSBkb2VzIHN1cHBvcnQgc3RhdGVtZW50IHBvb2xpbmcsCisgICAgICogICAgICAgICBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNTdGF0ZW1lbnRQb29saW5nKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciBzdG9yZWQgcHJvY2VkdXJlIGNhbGxzIHVzaW5nIHRoZSBzdG9yZWQgcHJvY2VkdXJlCisgICAgICogZXNjYXBlIHN5bnRheCBpcyBzdXBwb3J0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBzdG9yZWQgcHJvY2VkdXJlIGNhbGxzIHVzaW5nIHRoZSBzdG9yZWQgcHJvY2VkdXJlCisgICAgICogICAgICAgICBlc2NhcGUgc3ludGF4IGFyZSBzdXBwb3J0ZWQsIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c1N0b3JlZFByb2NlZHVyZXMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHN1YnF1ZXJpZXMgaW4gY29tcGFyaXNvbiBleHByZXNzaW9ucyBhcmUgc3VwcG9ydGVkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgc3VicXVlcmllcyBhcmUgc3VwcG9ydGVkIGluIGNvbXBhcmlzb24KKyAgICAgKiAgICAgICAgIGV4cHJlc3Npb25zLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c1N1YnF1ZXJpZXNJbkNvbXBhcmlzb25zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciBzdWJxdWVyaWVzIGluIHtAY29kZSBFWElTVFN9IGV4cHJlc3Npb25zIGFyZSBzdXBwb3J0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBzdWJxdWVyaWVzIGFyZSBzdXBwb3J0ZWQgaW4ge0Bjb2RlIEVYSVNUU30KKyAgICAgKiAgICAgICAgIGV4cHJlc3Npb25zLCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNTdWJxdWVyaWVzSW5FeGlzdHMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHN1YnF1ZXJpZXMgaW4ge0Bjb2RlIElOfSBzdGF0ZW1lbnRzIGFyZSBzdXBwb3J0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBzdWJxdWVyaWVzIGFyZSBzdXBwb3J0ZWQgaW4ge0Bjb2RlIElOfSBzdGF0ZW1lbnRzLAorICAgICAqICAgICAgICAgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzU3VicXVlcmllc0luSW5zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciBzdWJxdWVyaWVzIGluIHF1YW50aWZpZWQgZXhwcmVzc2lvbnMgYXJlIHN1cHBvcnRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHN1YnF1ZXJpZXMgYXJlIHN1cHBvcnRlZCwgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzU3VicXVlcmllc0luUXVhbnRpZmllZHMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBkYXRhYmFzZSBoYXMgdGFibGUgY29ycmVsYXRpb24gbmFtZXMgc3VwcG9ydC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRhYmxlIGNvcnJlbGF0aW9uIG5hbWVzIGFyZSBzdXBwb3J0ZWQsIG90aGVyd2lzZQorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNUYWJsZUNvcnJlbGF0aW9uTmFtZXMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgc3BlY2lmaWVkIHRyYW5zYWN0aW9uIGlzb2xhdGlvbiBsZXZlbCBpcyBzdXBwb3J0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGV2ZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSB0cmFuc2FjdGlvbiBpc29sYXRpb24gbGV2ZWwsIGFzIHNwZWNpZmllZCBpbiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIGphdmEuc3FsLkNvbm5lY3Rpb259OiB7QGNvZGUgVFJBTlNBQ1RJT05fTk9ORX0sIHtAY29kZQorICAgICAqICAgICAgICAgICAgVFJBTlNBQ1RJT05fUkVBRF9DT01NSVRURUR9LCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFRSQU5TQUNUSU9OX1JFQURfVU5DT01NSVRURUR9LCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFRSQU5TQUNUSU9OX1JFUEVBVEFCTEVfUkVBRH0sIHtAY29kZSBUUkFOU0FDVElPTl9TRVJJQUxJWkFCTEV9CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmljIGlzb2xhdGlvbiBsZXZlbCBpcyBzdXBwb3J0ZWQsCisgICAgICogICAgICAgICBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNUcmFuc2FjdGlvbklzb2xhdGlvbkxldmVsKGludCBsZXZlbCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdHJhbnNhY3Rpb25zIGFyZSBzdXBwb3J0ZWQuCisgICAgICogPHA+CisgICAgICogSWYgdHJhbnNhY3Rpb25zIGFyZSBub3Qgc3VwcG9ydGVkLCB0aGVuIHRoZSB7QGNvZGUgY29tbWl0fSBtZXRob2QgZG9lcworICAgICAqIG5vdGhpbmcgYW5kIHRoZSB0cmFuc2FjdGlvbiBpc29sYXRpb24gbGV2ZWwgaXMgYWx3YXlzIHtAY29kZQorICAgICAqIFRSQU5TQUNUSU9OX05PTkV9LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdHJhbnNhY3Rpb25zIGFyZSBzdXBwb3J0ZWQsIG90aGVyd2lzZSB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNUcmFuc2FjdGlvbnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSB7QGNvZGUgU1FMIFVOSU9OfSBvcGVyYXRpb24gaXMgc3VwcG9ydGVkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gb2YgdGhlIGRhdGFiYXNlIGRvZXMgc3VwcG9ydCB7QGNvZGUgVU5JT059LCBvdGhlcndpc2UKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzVW5pb24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSB7QGNvZGUgU1FMIFVOSU9OIEFMTH0gb3BlcmF0aW9uIGlzIHN1cHBvcnRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBkYXRhYmFzZSBkb2VzIHN1cHBvcnQge0Bjb2RlIFVOSU9OIEFMTH0sCisgICAgICogICAgICAgICBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNVbmlvbkFsbCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIG1ldGhvZCB7QGNvZGUgUmVzdWx0U2V0LnJvd1VwZGF0ZWR9IGNhbiBkZXRlY3QgYSB2aXNpYmxlCisgICAgICogcm93IHVwZGF0ZSBmb3IgdGhlIHNwZWNpZmllZCB7QGNvZGUgUmVzdWx0U2V0fSB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBSZXN1bHRTZXR9IHR5cGU6IHtAY29kZSBSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFl9LAorICAgICAqICAgICAgICAgICAge0Bjb2RlIFJlc3VsdFNldC5UWVBFX1NDUk9MTF9JTlNFTlNJVElWRX0sIG9yIHtAY29kZQorICAgICAqICAgICAgICAgICAgUmVzdWx0U2V0LlRZUEVfU0NST0xMX1NFTlNJVElWRX0KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBkZXRlY3RpbmcgY2hhbmdlcyBpcyBwb3NzaWJsZSwgb3RoZXJ3aXNlIHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB1cGRhdGVzQXJlRGV0ZWN0ZWQoaW50IHR5cGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhpcyBkYXRhYmFzZSB1c2VzIGEgZmlsZSBmb3IgZWFjaCB0YWJsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBkYXRhYmFzZSB1c2VzIG9uZSBmaWxlIGZvciBlYWNoIHRhYmxlLAorICAgICAqICAgICAgICAgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBhIGRhdGFiYXNlIGVycm9yIG9jY3VycmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHVzZXNMb2NhbEZpbGVQZXJUYWJsZSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhpcyBkYXRhYmFzZSB1c2VzIGEgbG9jYWwgZmlsZSB0byBzdG9yZSB0YWJsZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZGF0YWJhc2Ugc3RvcmVzIHRhYmxlcyBpbiBhIGxvY2FsIGZpbGUsCisgICAgICogICAgICAgICBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gdXNlc0xvY2FsRmlsZXMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lIGlmIGEgU1FMRXhjZXB0aW9uIHdoaWxlIGF1dG9Db21taXQgaXMgdHJ1ZSBpbmRpY2F0ZXMgdGhhdCBhbGwKKyAgICAgKiBvcGVuIFJlc3VsdFNldHMgYXJlIGNsb3NlZCwgZXZlbiBvbmVzIHRoYXQgYXJlIGhvbGRhYmxlCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgYWxsIG9wZW4gUmVzdWx0U2V0cyBhcmUgY2xvc2VkCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgYm9vbGVhbiBhdXRvQ29tbWl0RmFpbHVyZUNsb3Nlc0FsbFJlc3VsdFNldHMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGxpc3Qgb2YgdGhlIGNsaWVudCBpbmZvIHByb3BlcnRpZXMgb2YgdGhlIGRyaXZlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBsaXN0IG9mIHRoZSBjbGllbnQgaW5mbworICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IGVycm9yIG9jY3VycworICAgICAqLworICAgIFJlc3VsdFNldCBnZXRDbGllbnRJbmZvUHJvcGVydGllcygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgZGVzY3JpcHRpb24gYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBjYXRhbG9nJ3Mgc3lzdGVtIG9yIHVzZXIKKyAgICAgKiBmdW5jdGlvbiBwYXJhbWV0ZXJzIGFuZCByZXR1cm4gdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXRhbG9nCisgICAgICogICAgICAgICAgICB0aGUgZ2l2ZW4gY2F0YWxvbmcKKyAgICAgKiBAcGFyYW0gc2NoZW1hUGF0dGVybgorICAgICAqICAgICAgICAgICAgdGhlIHNjaGVtYSBwYXR0ZXJuCisgICAgICogQHBhcmFtIGZ1bmN0aW9uTmFtZVBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIHRoZSBmdW5jdGlvbiBuYW1lIHBhdHRlcm4KKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZVBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2x1bW4gbmFtZSBwYXR0ZXJuCisgICAgICogQHJldHVybiBhIGRlc2NyaXB0aW9uIG9mIHVzZXIgZnVuY3Rpb25zCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgUmVzdWx0U2V0IGdldEZ1bmN0aW9uQ29sdW1ucyhTdHJpbmcgY2F0YWxvZywgU3RyaW5nIHNjaGVtYVBhdHRlcm4sCisgICAgICAgICAgICBTdHJpbmcgZnVuY3Rpb25OYW1lUGF0dGVybiwgU3RyaW5nIGNvbHVtbk5hbWVQYXR0ZXJuKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBkZXNjcmlwdGlvbiBvZiB0aGUgc3lzdGVtIGFuZCB1c2VyIGZ1bmN0aW9ucyBhdmFpbGFibGUKKyAgICAgKiBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIGNhdGFsb2cuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F0YWxvZworICAgICAqICAgICAgICAgICAgdGhlIGdpdmVuIGNhdGFsb2cKKyAgICAgKiBAcGFyYW0gc2NoZW1hUGF0dGVybgorICAgICAqICAgICAgICAgICAgdGhlIHNjaGVtYSBwYXR0ZXJuCisgICAgICogQHBhcmFtIGZ1bmN0aW9uTmFtZVBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIHRoZSBmdW5jdGlvbiBuYW1lIHBhdHRlcm4KKyAgICAgKiBAcmV0dXJuIHVzZXIgZnVuY3Rpb25zCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgUmVzdWx0U2V0IGdldEZ1bmN0aW9ucyhTdHJpbmcgY2F0YWxvZywgU3RyaW5nIHNjaGVtYVBhdHRlcm4sCisgICAgICAgICAgICBTdHJpbmcgZnVuY3Rpb25OYW1lUGF0dGVybikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxpZmV0aW1lIGZvciB3aGljaCBhIFJvd0lkIG9iamVjdCByZW1haW5zIHZhbGlkIGlmIHRoaXMgZGF0YQorICAgICAqIHNvdXJjZSBzdXBwb3J0cyB0aGUgU1FMIFJPV0lEIHR5cGUKKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHRpbWUgb2YgYSBSb3dJZCBvYmplY3QgdGhhdCByZW1haW5zIHZhbGlkLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IGVycm9yIG9jY3VycworICAgICAqLworICAgIFJvd0lkTGlmZXRpbWUgZ2V0Um93SWRMaWZldGltZSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzY2hlbWEgbmFtZXMgb3JkZXJlZCBieSBUQUJMRV9DQVRBTE9HIGFuZCBUQUJMRV9TQ0hFTUEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F0YWxvZworICAgICAqICAgICAgICAgICAgdGhlIGNhdGFsb2cKKyAgICAgKiBAcGFyYW0gc2NoZW1hUGF0dGVybgorICAgICAqICAgICAgICAgICAgdGhlIHNjaGVtYSBwYXR0ZXJuCisgICAgICogQHJldHVybiB0aGUgc2NoZW1hIG5hbWVzCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgUmVzdWx0U2V0IGdldFNjaGVtYXMoU3RyaW5nIGNhdGFsb2csIFN0cmluZyBzY2hlbWFQYXR0ZXJuKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERldGVybWluZSBpZiB0aGlzIGRhdGFiYXNlIHN1cHBvcnRzIGludm9raW5nIHVzZXItZGVmaW5lZCBvciB2ZW5kb3IKKyAgICAgKiBmdW5jdGlvbnMgdXNpbmcgdGhlIHN0b3JlZCBwcm9jZWR1cmUgZXNjYXBlIHN5bnRheC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGRhdGFiYXNlIHN1cHBvcnRzIGludm9raW5nIHVzZXItZGVmaW5lZCBvciB2ZW5kb3IKKyAgICAgKiAgICAgICAgIGZ1bmN0aW9ucyB1c2luZyB0aGUgc3RvcmVkIHByb2NlZHVyZSBlc2NhcGUgc3ludGF4LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IGVycm9yIG9jY3VycworICAgICAqLworICAgIGJvb2xlYW4gc3VwcG9ydHNTdG9yZWRGdW5jdGlvbnNVc2luZ0NhbGxTeW50YXgoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL0RhdGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9EYXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjQzNGZiZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9EYXRlLmphdmEKQEAgLTAsMCArMSwyNDYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCisvKioKKyAqIEEgY2xhc3Mgd2hpY2ggY2FuIGNvbnN1bWUgYW5kIHByb2R1Y2UgZGF0ZXMgaW4gU1FMIHtAY29kZSBEYXRlfSBmb3JtYXQuCisgKiA8cD4KKyAqIERhdGVzIGFyZSByZXByZXNlbnRlZCBpbiBTUUwgYXMge0Bjb2RlIHl5eXktTU0tZGR9LiBOb3RlIHRoYXQgdGhpcyBkYXRlCisgKiBmb3JtYXQgb25seSBkZWFscyB3aXRoIHllYXIsIG1vbnRoIGFuZCBkYXkgdmFsdWVzLiBUaGVyZSBhcmUgbm8gdmFsdWVzIGZvcgorICogaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMuCisgKiA8cD4KKyAqIFRoaXMgaXMgdW5saWtlIHRoZSBmYW1pbGlhciB7QGNvZGUgamF2YS51dGlsLkRhdGV9IG9iamVjdCwgd2hpY2ggYWxzbyBpbmNsdWRlcworICogdmFsdWVzIGZvciBob3VycywgbWludXRlcywgc2Vjb25kcywgYW5kIG1pbGxpc2Vjb25kcy4KKyAqIDxwPgorICogVGltZSBwb2ludHMgYXJlIGhhbmRsZWQgYXMgbWlsbGlzZWNvbmQgdmFsdWVzIC0gbWlsbGlzZWNvbmRzIHNpbmNlIHRoZSBFcG9jaCwKKyAqIEphbnVhcnkgMXN0IDE5NzAsIDAwOjAwOjAwLjAwMCBHTVQuIFRpbWUgdmFsdWVzIHBhc3NlZCB0byB0aGUge0Bjb2RlCisgKiBqYXZhLnNxbC5EYXRlfSBjbGFzcyBhcmUgIm5vcm1hbGl6ZWQiIHRvIHRoZSB0aW1lIDAwOjAwOjAwLjAwMCBHTVQgb24gdGhlCisgKiBkYXRlIGltcGxpZWQgYnkgdGhlIHRpbWUgdmFsdWUuCisgKi8KK0BGaW5kQnVnc1N1cHByZXNzV2FybmluZ3MoIk5NX1NBTUVfU0lNUExFX05BTUVfQVNfU1VQRVJDTEFTUyIpCitwdWJsaWMgY2xhc3MgRGF0ZSBleHRlbmRzIGphdmEudXRpbC5EYXRlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDE1MTE1OTgwMzg0ODcyMzAxMDNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBEYXRlfSBvYmplY3QgY29ycmVzcG9uZGluZyB0byB0aGUgc3VwcGxpZWQgeWVhciwKKyAgICAgKiBtb250aCBhbmQgZGF5LgorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIHRoZSBjb25zdHJ1Y3RvciB7QGxpbmsgI0RhdGUobG9uZyl9LgorICAgICAqIEBwYXJhbSB0aGVZZWFyCisgICAgICogICAgICAgICAgICB0aGUgeWVhciwgc3BlY2lmaWVkIGFzIHRoZSB5ZWFyIG1pbnVzIDE5MDAuIE11c3QgYmUgaW4gdGhlCisgICAgICogICAgICAgICAgICByYW5nZSB7QGNvZGUgWzAsODA5OV19LgorICAgICAqIEBwYXJhbSB0aGVNb250aAorICAgICAqICAgICAgICAgICAgdGhlIG1vbnRoLCBzcGVjaWZpZWQgYXMgYSBudW1iZXIgd2l0aCAwID0gSmFudWFyeS4gTXVzdCBiZSBpbgorICAgICAqICAgICAgICAgICAgdGhlIHJhbmdlIHtAY29kZSBbMCwxMV19LgorICAgICAqIEBwYXJhbSB0aGVEYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXkgaW4gdGhlIG1vbnRoLiBNdXN0IGJlIGluIHRoZSByYW5nZSB7QGNvZGUgWzEsMzFdfS4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBEYXRlKGludCB0aGVZZWFyLCBpbnQgdGhlTW9udGgsIGludCB0aGVEYXkpIHsKKyAgICAgICAgc3VwZXIodGhlWWVhciwgdGhlTW9udGgsIHRoZURheSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGRhdGUgd2hpY2ggY29ycmVzcG9uZHMgdG8gdGhlIGRheSBkZXRlcm1pbmVkIGJ5IHRoZSBzdXBwbGllZAorICAgICAqIG1pbGxpc2Vjb25kcyB0aW1lIHZhbHVlIHtAY29kZSB0aGVEYXRlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVEYXRlCisgICAgICogICAgICAgICAgICBhIHRpbWUgdmFsdWUgaW4gbWlsbGlzZWNvbmRzIHNpbmNlIHRoZSBlcG9jaCAtIEphbnVhcnkgMSAxOTcwCisgICAgICogICAgICAgICAgICAwMDowMDowMCBHTVQuIFRoZSB0aW1lIHZhbHVlIChob3VycywgbWludXRlcywgc2Vjb25kcywKKyAgICAgKiAgICAgICAgICAgIG1pbGxpc2Vjb25kcykgc3RvcmVkIGluIHRoZSB7QGNvZGUgRGF0ZX0gb2JqZWN0IGlzIGFkanVzdGVkIHRvCisgICAgICogICAgICAgICAgICBjb3JyZXNwb25kIHRvIDAwOjAwOjAwIEdNVCBvbiB0aGUgZGF5IGRldGVybWluZWQgYnkgdGhlIHN1cHBsaWVkCisgICAgICogICAgICAgICAgICB0aW1lIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBEYXRlKGxvbmcgdGhlRGF0ZSkgeworICAgICAgICBzdXBlcihub3JtYWxpemVUaW1lKHRoZURhdGUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBpcyBkZXByZWNhdGVkIGFuZCBtdXN0IG5vdCBiZSB1c2VkLiBTUUwge0Bjb2RlCisgICAgICogICAgICAgICAgICAgRGF0ZX0gdmFsdWVzIGRvIG5vdCBoYXZlIGFuIGhvdXJzIGNvbXBvbmVudC4KKyAgICAgKiBAcmV0dXJuIGRvZXMgbm90IHJldHVybiBhbnl0aGluZy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0SG91cnMoKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBpcyBkZXByZWNhdGVkIGFuZCBtdXN0IG5vdCBiZSB1c2VkLiBTUUwge0Bjb2RlCisgICAgICogICAgICAgICAgICAgRGF0ZX0gdmFsdWVzIGRvIG5vdCBoYXZlIGEgbWludXRlcyBjb21wb25lbnQuCisgICAgICogQHJldHVybiBkb2VzIG5vdCByZXR1cm4gYW55dGhpbmcuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldE1pbnV0ZXMoKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBpcyBkZXByZWNhdGVkIGFuZCBtdXN0IG5vdCBiZSB1c2VkLiBTUUwge0Bjb2RlCisgICAgICogICAgICAgICAgICAgRGF0ZX0gdmFsdWVzIGRvIG5vdCBoYXZlIGEgc2Vjb25kcyBjb21wb25lbnQuCisgICAgICogQHJldHVybiBkb2VzIG5vdCByZXR1cm4gYW55dGhpbmcuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFNlY29uZHMoKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBpcyBkZXByZWNhdGVkIGFuZCBtdXN0IG5vdCBiZSB1c2VkLiBTUUwge0Bjb2RlCisgICAgICogICAgICAgICAgICAgRGF0ZX0gdmFsdWVzIGRvIG5vdCBoYXZlIGFuIGhvdXJzIGNvbXBvbmVudC4KKyAgICAgKiBAcGFyYW0gdGhlSG91cnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgaG91cnMgdG8gc2V0LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0SG91cnMoaW50IHRoZUhvdXJzKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBpcyBkZXByZWNhdGVkIGFuZCBtdXN0IG5vdCBiZSB1c2VkLiBTUUwge0Bjb2RlCisgICAgICogICAgICAgICAgICAgRGF0ZX0gdmFsdWVzIGRvIG5vdCBoYXZlIGEgbWludXRlcyBjb21wb25lbnQuCisgICAgICogQHBhcmFtIHRoZU1pbnV0ZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgbWludXRlcyB0byBzZXQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRNaW51dGVzKGludCB0aGVNaW51dGVzKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBpcyBkZXByZWNhdGVkIGFuZCBtdXN0IG5vdCBiZSB1c2VkLiBTUUwge0Bjb2RlCisgICAgICogICAgICAgICAgICAgRGF0ZX0gdmFsdWVzIGRvIG5vdCBoYXZlIGEgc2Vjb25kcyBjb21wb25lbnQuCisgICAgICogQHBhcmFtIHRoZVNlY29uZHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2Ygc2Vjb25kcyB0byBzZXQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRTZWNvbmRzKGludCB0aGVTZWNvbmRzKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoaXMgZGF0ZSB0byBhIGRhdGUgc3VwcGxpZWQgYXMgYSBtaWxsaXNlY29uZHMgdmFsdWUuIFRoZSBkYXRlIGlzCisgICAgICogc2V0IGJhc2VkIG9uIHRoZSBzdXBwbGllZCB0aW1lIHZhbHVlIGFuZCByb3VuZGVkIHRvIHplcm8gR01UIGZvciB0aGF0IGRheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVUaW1lCisgICAgICogICAgICAgICAgICB0aGUgdGltZSBpbiBtaWxsaXNlY29uZHMgc2luY2UgdGhlIEVwb2NoLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFRpbWUobG9uZyB0aGVUaW1lKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFN0b3JlIHRoZSBEYXRlIGJhc2VkIG9uIHRoZSBzdXBwbGllZCB0aW1lIGFmdGVyIHJlbW92aW5nIGFueSB0aW1lCisgICAgICAgICAqIGVsZW1lbnRzIGZpbmVyIHRoYW4gdGhlIGRheSBiYXNlZCBvbiB6ZXJvIEdNVAorICAgICAgICAgKi8KKyAgICAgICAgc3VwZXIuc2V0VGltZShub3JtYWxpemVUaW1lKHRoZVRpbWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9kdWNlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZGF0ZSBpbiBTUUwgZm9ybWF0CisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkYXRlIGluIFNRTCBmb3JtYXQgLSB7QGNvZGUgInl5eXktTU0tZGQifS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoMTApOworCisgICAgICAgIGZvcm1hdCgoZ2V0WWVhcigpICsgMTkwMCksIDQsIHNiKTsKKyAgICAgICAgc2IuYXBwZW5kKCctJyk7CisgICAgICAgIGZvcm1hdCgoZ2V0TW9udGgoKSArIDEpLCAyLCBzYik7CisgICAgICAgIHNiLmFwcGVuZCgnLScpOworICAgICAgICBmb3JtYXQoZ2V0RGF0ZSgpLCAyLCBzYik7CisKKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBBRERJTkcgPSAiMDAwMCI7CisKKyAgICAvKgorICAgICogUHJpdmF0ZSBtZXRob2QgdG8gZm9ybWF0IHRoZSB0aW1lCisgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZm9ybWF0KGludCBkYXRlLCBpbnQgZGlnaXRzLCBTdHJpbmdCdWlsZGVyIHNiKSB7CisgICAgICAgIFN0cmluZyBzdHIgPSBTdHJpbmcudmFsdWVPZihkYXRlKTsKKyAgICAgICAgaWYgKGRpZ2l0cyAtIHN0ci5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZChQQURESU5HLnN1YnN0cmluZygwLCBkaWdpdHMgLSBzdHIubGVuZ3RoKCkpKTsKKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQoc3RyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIERhdGV9IGZyb20gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBkYXRlIGluIFNRTAorICAgICAqIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRlU3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgZGF0ZSBpbiBTUUwgZm9ybWF0IC0gIiB7QGNvZGUgeXl5eS1NTS1kZH0iLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBEYXRlfSBvYmplY3QuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZm9ybWF0IG9mIHRoZSBzdXBwbGllZCBzdHJpbmcgZG9lcyBub3QgbWF0Y2ggdGhlIFNRTAorICAgICAqICAgICAgICAgICAgIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIERhdGUgdmFsdWVPZihTdHJpbmcgZGF0ZVN0cmluZykgeworICAgICAgICBpZiAoZGF0ZVN0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGZpcnN0SW5kZXggPSBkYXRlU3RyaW5nLmluZGV4T2YoJy0nKTsKKyAgICAgICAgaW50IHNlY29uZEluZGV4ID0gZGF0ZVN0cmluZy5pbmRleE9mKCctJywgZmlyc3RJbmRleCArIDEpOworICAgICAgICAvLyBzZWNvbmRJbmRleCA9PSAtMSBtZWFucyBub25lIG9yIG9ubHkgb25lIHNlcGFyYXRvciAnLScgaGFzIGJlZW4KKyAgICAgICAgLy8gZm91bmQuCisgICAgICAgIC8vIFRoZSBzdHJpbmcgaXMgc2VwYXJhdGVkIGludG8gdGhyZWUgcGFydHMgYnkgdHdvIHNlcGFyYXRvciBjaGFyYWN0ZXJzLAorICAgICAgICAvLyBpZiB0aGUgZmlyc3Qgb3IgdGhlIHRoaXJkIHBhcnQgaXMgbnVsbCBzdHJpbmcsIHdlIHNob3VsZCB0aHJvdworICAgICAgICAvLyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gdG8gZm9sbG93IFJJCisgICAgICAgIGlmIChzZWNvbmRJbmRleCA9PSAtMSB8fCBmaXJzdEluZGV4ID09IDAKKyAgICAgICAgICAgICAgICB8fCBzZWNvbmRJbmRleCArIDEgPT0gZGF0ZVN0cmluZy5sZW5ndGgoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIC8vIHBhcnNlIGVhY2ggcGFydCBvZiB0aGUgc3RyaW5nCisgICAgICAgIGludCB5ZWFyID0gSW50ZWdlci5wYXJzZUludChkYXRlU3RyaW5nLnN1YnN0cmluZygwLCBmaXJzdEluZGV4KSk7CisgICAgICAgIGludCBtb250aCA9IEludGVnZXIucGFyc2VJbnQoZGF0ZVN0cmluZy5zdWJzdHJpbmcoZmlyc3RJbmRleCArIDEsCisgICAgICAgICAgICAgICAgc2Vjb25kSW5kZXgpKTsKKyAgICAgICAgaW50IGRheSA9IEludGVnZXIucGFyc2VJbnQoZGF0ZVN0cmluZy5zdWJzdHJpbmcoc2Vjb25kSW5kZXggKyAxLAorICAgICAgICAgICAgICAgIGRhdGVTdHJpbmcubGVuZ3RoKCkpKTsKKyAgICAgICAgcmV0dXJuIG5ldyBEYXRlKHllYXIgLSAxOTAwLCBtb250aCAtIDEsIGRheSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBQcml2YXRlIG1ldGhvZCB3aGljaCBub3JtYWxpemVzIGEgVGltZSB2YWx1ZSwgcmVtb3ZpbmcgYWxsIGxvdworICAgICAqIHNpZ25pZmljYW5jZSBkaWdpdHMgY29ycmVzcG9uZGluZyB0byBtaWxsaXNlY29uZHMsIHNlY29uZHMsIG1pbnV0ZXMgYW5kCisgICAgICogaG91cnMsIHNvIHRoYXQgdGhlIHJldHVybmVkIFRpbWUgdmFsdWUgY29ycmVzcG9uZHMgdG8gMDA6MDA6MDAgR01UIG9uIGEKKyAgICAgKiBwYXJ0aWN1bGFyIGRheS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBsb25nIG5vcm1hbGl6ZVRpbWUobG9uZyB0aGVUaW1lKSB7CisgICAgICAgIHJldHVybiB0aGVUaW1lOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9Ecml2ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9Ecml2ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MWNhODYzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL0RyaXZlci5qYXZhCkBAIC0wLDAgKzEsMTI1IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworCisvKioKKyAqIEFuIGludGVyZmFjZSB0byBhIEpEQkMgZHJpdmVyLgorICogPHA+CisgKiBUaGUgSkRCQyBkcml2ZXIgdXNlcyBVUkxzIHRvIHNwZWNpZnkgdGhlIGxvY2F0aW9uIG9mIHNwZWNpZmljIGRhdGEuIFVSTAorICogZm9ybWF0IHR5cGljYWxseSB0YWtlcyB0aGUgZm9ybSAiIHtAY29kZSB4eHh4Onl5eXk6U3BlY2lmaWNEYXRhfSIsIHdoZXJlICIKKyAqIHtAY29kZSB4eHh4Onl5eXl9IiBpcyByZWZlcnJlZCB0byBhcyB0aGUgPGk+c3VicHJvdG9jb2w8L2k+IGFuZCBpcyBub3JtYWxseQorICogdGhlIHNhbWUgZm9yIGFsbCBvZiBhIHBhcnRpY3VsYXIgZHJpdmVyLiAiIHtAY29kZSBTcGVjaWZpY0RhdGF9IiBpcyBhIHN0cmluZworICogd2hpY2ggaWRlbnRpZmllcyB0aGUgcGFydGljdWxhciBkYXRhIHNvdXJjZSB0aGF0IHRoZSBkcml2ZXIgc2hvdWxkIHVzZS4KKyAqIDxwPgorICogQSBkcml2ZXIgbmVlZHMgdG8gYmUgcmVnaXN0ZXJlZCB3aXRoIGEge0BsaW5rIERyaXZlck1hbmFnZXJ9LiBJdCBpcworICogcmVnaXN0ZXJlZCBhbmQgaW5zdGFudGlhdGVkIGJ5IGNhbGxpbmcge0Bjb2RlIENsYXNzLmZvck5hbWUoIkRyaXZlclVSTCIpfQorICogd2l0aCB0aGUgVVJMIHN0cmluZyBhcyBhcmd1bWVudC4KKyAqCisgKiBAc2VlIERyaXZlck1hbmFnZXIKKyAqLworcHVibGljIGludGVyZmFjZSBEcml2ZXIgeworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBkcml2ZXIgdGhpbmtzIHRoYXQgaXQgY2FuIG9wZW4gYSBjb25uZWN0aW9uIHRvIHRoZQorICAgICAqIGdpdmVuIFVSTC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmwKKyAgICAgKiAgICAgICAgICAgIHRoZSBVUkwgdG8gY29ubmVjdCB0by4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZHJpdmVyIHRoaW5rcyB0aGF0IGlzIGNhbiBvcGVuIGEgY29ubmVjdGlvbgorICAgICAqICAgICAgICAgdG8gdGhlIHN1cHBsaWVkIFVSTCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuIFR5cGljYWxseSwgdGhlCisgICAgICogICAgICAgICBkcml2ZXIgd2lsbCByZXNwb25kIHtAY29kZSB0cnVlfSBpZiBpdCB0aGlua3MgdGhhdCBpdCBjYW4gaGFuZGxlCisgICAgICogICAgICAgICB0aGUgc3VicHJvdG9jb2wgc3BlY2lmaWVkIGJ5IHRoZSBkcml2ZXIuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHRzVVJMKFN0cmluZyB1cmwpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBBdHRlbXB0cyB0byBtYWtlIGEgZGF0YWJhc2UgY29ubmVjdGlvbiB0byBhIGRhdGEgc291cmNlIHNwZWNpZmllZCBieSBhCisgICAgICogc3VwcGxpZWQgVVJMLgorICAgICAqCisgICAgICogQHBhcmFtIHVybAorICAgICAqICAgICAgICAgICAgdGhlIFVSTCB0byBjb25uZWN0LgorICAgICAqIEBwYXJhbSBpbmZvCisgICAgICogICAgICAgICAgICBzb21lIHByb3BlcnRpZXMgdGhhdCBzaG91bGQgYmUgdXNlZCBpbiBlc3RhYmxpc2hpbmcgdGhlCisgICAgICogICAgICAgICAgICBjb25uZWN0aW9uLiBUaGUgcHJvcGVydGllcyBjb25zaXN0IG9mIG5hbWUvdmFsdWUgcGFpcnMgb2YKKyAgICAgKiAgICAgICAgICAgIHN0cmluZ3MuIE5vcm1hbGx5LCBhIGNvbm5lY3Rpb24gdG8gYSBkYXRhYmFzZSByZXF1aXJlcyBhdAorICAgICAqICAgICAgICAgICAgbGVhc3QgdHdvIHByb3BlcnRpZXMgLSBmb3Ige0Bjb2RlICJ1c2VyIn0gYW5kIHtAY29kZQorICAgICAqICAgICAgICAgICAgInBhc3N3b3JkIn0gaW4gb3JkZXIgdG8gcGFzcyBhdXRoZW50aWNhdGlvbiB0byB0aGUgZGF0YWJhc2UuCisgICAgICogQHJldHVybiB0aGUgY29ubmVjdGlvbiB0byB0aGUgZGF0YWJhc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29ubmVjdGlvbiBjb25uZWN0KFN0cmluZyB1cmwsIFByb3BlcnRpZXMgaW5mbykgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRyaXZlcidzIG1ham9yIHZlcnNpb24gbnVtYmVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWFqb3IgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGRyaXZlciAtIHR5cGljYWxseSBzdGFydHMgYXQgMS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1ham9yVmVyc2lvbigpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZHJpdmVyJ3MgbWlub3IgdmVyc2lvbiBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtaW5vciB2ZXJzaW9uIG51bWJlciBvZiB0aGUgZHJpdmVyIC0gdHlwaWNhbGx5IHN0YXJ0cyBhdCAwLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWlub3JWZXJzaW9uKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGluZm9ybWF0aW9uIGFib3V0IHBvc3NpYmxlIHByb3BlcnRpZXMgZm9yIHRoaXMgZHJpdmVyLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIGlzIGludGVuZGVkIHRvIHByb3ZpZGUgYSBsaXN0aW5nIG9mIHBvc3NpYmxlIHByb3BlcnRpZXMgdGhhdAorICAgICAqIHRoZSBjbGllbnQgb2YgdGhlIGRyaXZlciBtdXN0IHN1cHBseSBpbiBvcmRlciB0byBlc3RhYmxpc2ggYSBjb25uZWN0aW9uCisgICAgICogdG8gYSBkYXRhYmFzZS4gTm90ZSB0aGF0IHRoZSByZXR1cm5lZCBhcnJheSBvZiBwcm9wZXJ0aWVzIG1heSBjaGFuZ2UKKyAgICAgKiBkZXBlbmRpbmcgb24gdGhlIHN1cHBsaWVkIGxpc3Qgb2YgcHJvcGVydHkgdmFsdWVzLgorICAgICAqCisgICAgICogQHBhcmFtIHVybAorICAgICAqICAgICAgICAgICAgdGhlIFVSTCBvZiB0aGUgZGF0YWJhc2UuIEFuIGFwcGxpY2F0aW9uIG1heSBjYWxsIHRoaXMgbWV0aG9kCisgICAgICogICAgICAgICAgICBpdGVyYXRpdmVseSBhcyB0aGUgcHJvcGVydHkgbGlzdCBpcyBidWlsdCB1cCAtIGZvciBleGFtcGxlLAorICAgICAqICAgICAgICAgICAgd2hlbiBkaXNwbGF5aW5nIGEgZGlhbG9nIHRvIGFuIGVuZC11c2VyIGFzIHBhcnQgb2YgdGhlCisgICAgICogICAgICAgICAgICBkYXRhYmFzZSBsb2dpbiBwcm9jZXNzLgorICAgICAqIEBwYXJhbSBpbmZvCisgICAgICogICAgICAgICAgICBhIHNldCBvZiB0YWcvdmFsdWUgcGFpcnMgZ2l2aW5nIGRhdGEgdGhhdCBhIHVzZXIgbWF5IGJlCisgICAgICogICAgICAgICAgICBwcm9tcHRlZCB0byBwcm92aWRlIGluIG9yZGVyIHRvIGNvbm5lY3QgdG8gdGhlIGRhdGFiYXNlLgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2Yge0Bjb2RlIERyaXZlclByb3BlcnR5SW5mb30gcmVjb3JkcyB3aGljaCBwcm92aWRlCisgICAgICogICAgICAgICBkZXRhaWxzIG9uIHdoaWNoIGFkZGl0aW9uYWwgcHJvcGVydGllcyBhcmUgcmVxdWlyZWQgKGluIGFkZGl0aW9uCisgICAgICogICAgICAgICB0byB0aG9zZSBzdXBwbGllZCBpbiB0aGUge0Bjb2RlIGluZm99IHBhcmFtZXRlcikgaW4gb3JkZXIgdG8KKyAgICAgKiAgICAgICAgIGNvbm5lY3QgdG8gdGhlIGRhdGFiYXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIERyaXZlclByb3BlcnR5SW5mb1tdIGdldFByb3BlcnR5SW5mbyhTdHJpbmcgdXJsLCBQcm9wZXJ0aWVzIGluZm8pCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVwb3J0cyB3aGV0aGVyIHRoaXMgZHJpdmVyIGlzIGEgZ2VudWluZSBKREJDIENvbXBsaWFudFRNIGRyaXZlci4gVGhlCisgICAgICogZHJpdmVyIG1heSBvbmx5IHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgaXQgcGFzc2VzIGFsbCB0aGUgSkRCQyBjb21wbGlhbmNlCisgICAgICogdGVzdHMuCisgICAgICogPHA+CisgICAgICogQSBkcml2ZXIgbWF5IG5vdCBiZSBmdWxseSBjb21wbGlhbnQgaWYgdGhlIHVuZGVybHlpbmcgZGF0YWJhc2UgaGFzCisgICAgICogbGltaXRlZCBmdW5jdGlvbmFsaXR5LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGRyaXZlciBpcyBmdWxseSBKREJDIGNvbXBsaWFudCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGpkYmNDb21wbGlhbnQoKTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL0RyaXZlck1hbmFnZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9Ecml2ZXJNYW5hZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGNlZTFmZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9Ecml2ZXJNYW5hZ2VyLmphdmEKQEAgLTAsMCArMSw0MDMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCitpbXBvcnQgZGFsdmlrLnN5c3RlbS5WTVN0YWNrOworaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworCisvKioKKyAqIFByb3ZpZGVzIGZhY2lsaXRpZXMgZm9yIG1hbmFnaW5nIEpEQkMgZHJpdmVycy4KKyAqIDxwPgorICogVGhlIHtAY29kZSBEcml2ZXJNYW5hZ2VyfSBjbGFzcyBsb2FkcyBKREJDIGRyaXZlcnMgZHVyaW5nIGl0cyBpbml0aWFsaXphdGlvbiwKKyAqIGZyb20gdGhlIGxpc3Qgb2YgZHJpdmVycyByZWZlcmVuY2VkIGJ5IHRoZSBzeXN0ZW0gcHJvcGVydHkge0Bjb2RlCisgKiAiamRiYy5kcml2ZXJzIn0uCisgKi8KK3B1YmxpYyBjbGFzcyBEcml2ZXJNYW5hZ2VyIHsKKworICAgIC8qCisgICAgICogRmFjaWxpdGllcyBmb3IgbG9nZ2luZy4gVGhlIFByaW50IFN0cmVhbSBpcyBkZXByZWNhdGVkIGJ1dCBpcyBtYWludGFpbmVkCisgICAgICogaGVyZSBmb3IgY29tcGF0aWJpbGl0eS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBQcmludFN0cmVhbSB0aGVQcmludFN0cmVhbTsKKworICAgIHByaXZhdGUgc3RhdGljIFByaW50V3JpdGVyIHRoZVByaW50V3JpdGVyOworCisgICAgLy8gTG9naW4gdGltZW91dCB2YWx1ZSAtIGJ5IGRlZmF1bHQgc2V0IHRvIDAgLT4gIndhaXQgZm9yZXZlciIKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgbG9naW5UaW1lb3V0ID0gMDsKKworICAgIC8qCisgICAgICogU2V0IHRvIGhvbGQgUmVnaXN0ZXJlZCBEcml2ZXJzIC0gaW5pdGlhbCBjYXBhY2l0eSAxMCBkcml2ZXJzICh3aWxsIGV4cGFuZAorICAgICAqIGF1dG9tYXRpY2FsbHkgaWYgbmVjZXNzYXJ5LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIExpc3Q8RHJpdmVyPiB0aGVEcml2ZXJzID0gbmV3IEFycmF5TGlzdDxEcml2ZXI+KDEwKTsKKworICAgIC8vIFBlcm1pc3Npb24gZm9yIHNldHRpbmcgbG9nCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU1FMUGVybWlzc2lvbiBsb2dQZXJtaXNzaW9uID0gbmV3IFNRTFBlcm1pc3Npb24oInNldExvZyIpOworCisgICAgLyoKKyAgICAgKiBMb2FkIGRyaXZlcnMgb24gaW5pdGlhbGl6YXRpb24KKyAgICAgKi8KKyAgICBzdGF0aWMgeworICAgICAgICBsb2FkSW5pdGlhbERyaXZlcnMoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIExvYWRzIHRoZSBzZXQgb2YgSkRCQyBkcml2ZXJzIGRlZmluZWQgYnkgdGhlIFByb3BlcnR5ICJqZGJjLmRyaXZlcnMiIGlmCisgICAgICogaXQgaXMgZGVmaW5lZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGxvYWRJbml0aWFsRHJpdmVycygpIHsKKyAgICAgICAgU3RyaW5nIHRoZURyaXZlckxpc3QgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImpkYmMuZHJpdmVycyIsIG51bGwpOworICAgICAgICBpZiAodGhlRHJpdmVyTGlzdCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBHZXQgdGhlIG5hbWVzIG9mIHRoZSBkcml2ZXJzIGFzIGFuIGFycmF5IG9mIFN0cmluZ3MgZnJvbSB0aGUgc3lzdGVtCisgICAgICAgICAqIHByb3BlcnR5IGJ5IHNwbGl0dGluZyB0aGUgcHJvcGVydHkgYXQgdGhlIHNlcGFyYXRvciBjaGFyYWN0ZXIgJzonCisgICAgICAgICAqLworICAgICAgICBTdHJpbmdbXSB0aGVEcml2ZXJOYW1lcyA9IHRoZURyaXZlckxpc3Quc3BsaXQoIjoiKTsKKworICAgICAgICBmb3IgKFN0cmluZyBlbGVtZW50IDogdGhlRHJpdmVyTmFtZXMpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgLy8gTG9hZCB0aGUgZHJpdmVyIGNsYXNzCisgICAgICAgICAgICAgICAgQ2xhc3MKKyAgICAgICAgICAgICAgICAgICAgICAgIC5mb3JOYW1lKGVsZW1lbnQsIHRydWUsIENsYXNzTG9hZGVyCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgICAgICAgLy8gSWdub3JlZAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBBIHByaXZhdGUgY29uc3RydWN0b3IgdG8gcHJldmVudCBhbGxvY2F0aW9uCisgICAgICovCisgICAgcHJpdmF0ZSBEcml2ZXJNYW5hZ2VyKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYSBkcml2ZXIgZnJvbSB0aGUge0Bjb2RlIERyaXZlck1hbmFnZXJ9J3MgcmVnaXN0ZXJlZCBkcml2ZXIgbGlzdC4KKyAgICAgKiBUaGlzIHdpbGwgb25seSBzdWNjZWVkIHdoZW4gdGhlIGNhbGxlcidzIGNsYXNzIGxvYWRlciBsb2FkZWQgdGhlIGRyaXZlcgorICAgICAqIHRoYXQgaXMgdG8gYmUgcmVtb3ZlZC4gSWYgdGhlIGRyaXZlciB3YXMgbG9hZGVkIGJ5IGEgZGlmZmVyZW50IGNsYXNzCisgICAgICogbG9hZGVyLCB0aGUgcmVtb3ZhbCBvZiB0aGUgZHJpdmVyIGZhaWxzIHNpbGVudGx5LgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSByZW1vdmFsIHN1Y2NlZWRzLCB0aGUge0Bjb2RlIERyaXZlck1hbmFnZXJ9IHdpbGwgbm90IHVzZSB0aGlzCisgICAgICogZHJpdmVyIGluIHRoZSBmdXR1cmUgd2hlbiBhc2tlZCB0byBnZXQgYSB7QGNvZGUgQ29ubmVjdGlvbn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZHJpdmVyCisgICAgICogICAgICAgICAgICB0aGUgSkRCQyBkcml2ZXIgdG8gcmVtb3ZlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBwcm9ibGVtIGludGVyZmVyaW5nIHdpdGggYWNjZXNzaW5nIHRoZQorICAgICAqICAgICAgICAgICAgIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBkZXJlZ2lzdGVyRHJpdmVyKERyaXZlciBkcml2ZXIpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBpZiAoZHJpdmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBDbGFzc0xvYWRlciBjYWxsZXJDbGFzc0xvYWRlciA9IFZNU3RhY2suZ2V0Q2FsbGluZ0NsYXNzTG9hZGVyKCk7CisgICAgICAgIGlmICghRHJpdmVyTWFuYWdlci5pc0NsYXNzRnJvbUNsYXNzTG9hZGVyKGRyaXZlciwgY2FsbGVyQ2xhc3NMb2FkZXIpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oImNhbGxpbmcgY2xhc3Mgbm90IGF1dGhvcml6ZWQgdG8gZGVyZWdpc3RlciBKREJDIGRyaXZlciIpOworICAgICAgICB9CisgICAgICAgIHN5bmNocm9uaXplZCAodGhlRHJpdmVycykgeworICAgICAgICAgICAgdGhlRHJpdmVycy5yZW1vdmUoZHJpdmVyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEF0dGVtcHRzIHRvIGVzdGFibGlzaCBhIGNvbm5lY3Rpb24gdG8gdGhlIGdpdmVuIGRhdGFiYXNlIFVSTC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmwKKyAgICAgKiAgICAgICAgICAgIGEgVVJMIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGRhdGFiYXNlIHRhcmdldCB0byBjb25uZWN0IHdpdGguCisgICAgICogQHJldHVybiBhIHtAY29kZSBDb25uZWN0aW9ufSB0byB0aGUgZGF0YWJhc2UgaWRlbnRpZmllZCBieSB0aGUgVVJMLgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlmIG5vIGNvbm5lY3Rpb24gY2FuIGJlIGVzdGFibGlzaGVkLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYW4gZXJyb3Igd2hpbGUgYXR0ZW1wdGluZyB0byBjb25uZWN0IHRvIHRoZQorICAgICAqICAgICAgICAgICAgIGRhdGFiYXNlIGlkZW50aWZpZWQgYnkgdGhlIFVSTC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIENvbm5lY3Rpb24gZ2V0Q29ubmVjdGlvbihTdHJpbmcgdXJsKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGdldENvbm5lY3Rpb24odXJsLCBuZXcgUHJvcGVydGllcygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdHRlbXB0cyB0byBlc3RhYmxpc2ggYSBjb25uZWN0aW9uIHRvIHRoZSBnaXZlbiBkYXRhYmFzZSBVUkwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJsCisgICAgICogICAgICAgICAgICBhIFVSTCBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBkYXRhYmFzZSB0YXJnZXQgdG8gY29ubmVjdCB3aXRoCisgICAgICogQHBhcmFtIGluZm8KKyAgICAgKiAgICAgICAgICAgIGEgc2V0IG9mIHByb3BlcnRpZXMgdG8gdXNlIGFzIGFyZ3VtZW50cyB0byBzZXQgdXAgdGhlCisgICAgICogICAgICAgICAgICBjb25uZWN0aW9uLiBQcm9wZXJ0aWVzIGFyZSBhcmJpdHJhcnkgc3RyaW5nL3ZhbHVlIHBhaXJzLgorICAgICAqICAgICAgICAgICAgTm9ybWFsbHksIGF0IGxlYXN0IHRoZSBwcm9wZXJ0aWVzIHtAY29kZSAidXNlciJ9IGFuZCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICJwYXNzd29yZCJ9IHNob3VsZCBiZSBwYXNzZWQsIHdpdGggYXBwcm9wcmlhdGUgc2V0dGluZ3MgZm9yCisgICAgICogICAgICAgICAgICB0aGUgdXNlciBJRCBhbmQgaXRzIGNvcnJlc3BvbmRpbmcgcGFzc3dvcmQgdG8gZ2V0IGFjY2VzcyB0bworICAgICAqICAgICAgICAgICAgdGhlIGNvcnJlc3BvbmRpbmcgZGF0YWJhc2UuCisgICAgICogQHJldHVybiBhIHtAY29kZSBDb25uZWN0aW9ufSB0byB0aGUgZGF0YWJhc2UgaWRlbnRpZmllZCBieSB0aGUgVVJMLgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlmIG5vIGNvbm5lY3Rpb24gY2FuIGJlIGVzdGFibGlzaGVkLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYW4gZXJyb3Igd2hpbGUgYXR0ZW1wdGluZyB0byBjb25uZWN0IHRvIHRoZQorICAgICAqICAgICAgICAgICAgIGRhdGFiYXNlIGlkZW50aWZpZWQgYnkgdGhlIFVSTC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIENvbm5lY3Rpb24gZ2V0Q29ubmVjdGlvbihTdHJpbmcgdXJsLCBQcm9wZXJ0aWVzIGluZm8pIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAvLyAwOCAtIGNvbm5lY3Rpb24gZXhjZXB0aW9uCisgICAgICAgIC8vIDAwMSAtIFNRTC1jbGllbnQgdW5hYmxlIHRvIGVzdGFibGlzaCBTUUwtY29ubmVjdGlvbgorICAgICAgICBTdHJpbmcgc3FsU3RhdGUgPSAiMDgwMDEiOworICAgICAgICBpZiAodXJsID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTUUxFeGNlcHRpb24oIlRoZSB1cmwgY2Fubm90IGJlIG51bGwiLCBzcWxTdGF0ZSk7CisgICAgICAgIH0KKyAgICAgICAgc3luY2hyb25pemVkICh0aGVEcml2ZXJzKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogTG9vcCBvdmVyIHRoZSBkcml2ZXJzIGluIHRoZSBEcml2ZXJTZXQgY2hlY2tpbmcgdG8gc2VlIGlmIG9uZSBjYW4KKyAgICAgICAgICAgICAqIG9wZW4gYSBjb25uZWN0aW9uIHRvIHRoZSBzdXBwbGllZCBVUkwgLSByZXR1cm4gdGhlIGZpcnN0CisgICAgICAgICAgICAgKiBjb25uZWN0aW9uIHdoaWNoIGlzIHJldHVybmVkCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGZvciAoRHJpdmVyIHRoZURyaXZlciA6IHRoZURyaXZlcnMpIHsKKyAgICAgICAgICAgICAgICBDb25uZWN0aW9uIHRoZUNvbm5lY3Rpb24gPSB0aGVEcml2ZXIuY29ubmVjdCh1cmwsIGluZm8pOworICAgICAgICAgICAgICAgIGlmICh0aGVDb25uZWN0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoZUNvbm5lY3Rpb247CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIElmIHdlIGdldCBoZXJlLCBub25lIG9mIHRoZSBkcml2ZXJzIGFyZSBhYmxlIHRvIHJlc29sdmUgdGhlIFVSTAorICAgICAgICB0aHJvdyBuZXcgU1FMRXhjZXB0aW9uKCJObyBzdWl0YWJsZSBkcml2ZXIiLCBzcWxTdGF0ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gZXN0YWJsaXNoIGEgY29ubmVjdGlvbiB0byB0aGUgZ2l2ZW4gZGF0YWJhc2UgVVJMLgorICAgICAqCisgICAgICogQHBhcmFtIHVybAorICAgICAqICAgICAgICAgICAgYSBVUkwgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgZGF0YWJhc2UgdGFyZ2V0IHRvIGNvbm5lY3Qgd2l0aC4KKyAgICAgKiBAcGFyYW0gdXNlcgorICAgICAqICAgICAgICAgICAgYSB1c2VyIElEIHVzZWQgdG8gbG9naW4gdG8gdGhlIGRhdGFiYXNlLgorICAgICAqIEBwYXJhbSBwYXNzd29yZAorICAgICAqICAgICAgICAgICAgYSBwYXNzd29yZCBmb3IgdGhlIHVzZXIgSUQgdG8gbG9naW4gdG8gdGhlIGRhdGFiYXNlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgQ29ubmVjdGlvbn0gdG8gdGhlIGRhdGFiYXNlIGlkZW50aWZpZWQgYnkgdGhlIFVSTC4KKyAgICAgKiAgICAgICAgIHtAY29kZSBudWxsfSBpZiBubyBjb25uZWN0aW9uIGNhbiBiZSBlc3RhYmxpc2hlZC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGFuIGVycm9yIHdoaWxlIGF0dGVtcHRpbmcgdG8gY29ubmVjdCB0byB0aGUKKyAgICAgKiAgICAgICAgICAgICBkYXRhYmFzZSBpZGVudGlmaWVkIGJ5IHRoZSBVUkwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDb25uZWN0aW9uIGdldENvbm5lY3Rpb24oU3RyaW5nIHVybCwgU3RyaW5nIHVzZXIsIFN0cmluZyBwYXNzd29yZCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBQcm9wZXJ0aWVzIHRoZVByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICBpZiAodXNlciAhPSBudWxsKSB7CisgICAgICAgICAgICB0aGVQcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJ1c2VyIiwgdXNlcik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBhc3N3b3JkICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRoZVByb3BlcnRpZXMuc2V0UHJvcGVydHkoInBhc3N3b3JkIiwgcGFzc3dvcmQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRDb25uZWN0aW9uKHVybCwgdGhlUHJvcGVydGllcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJpZXMgdG8gZmluZCBhIGRyaXZlciB0aGF0IGNhbiBpbnRlcnByZXQgdGhlIHN1cHBsaWVkIFVSTC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmwKKyAgICAgKiAgICAgICAgICAgIHRoZSBVUkwgb2YgYSBkYXRhYmFzZS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIERyaXZlcn0gdGhhdCBtYXRjaGVzIHRoZSBwcm92aWRlZCBVUkwuIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAgbm8ge0Bjb2RlIERyaXZlcn0gdW5kZXJzdGFuZHMgdGhlIFVSTAorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYW55IGtpbmQgb2YgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgRHJpdmVyIGdldERyaXZlcihTdHJpbmcgdXJsKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgQ2xhc3NMb2FkZXIgY2FsbGVyQ2xhc3NMb2FkZXIgPSBWTVN0YWNrLmdldENhbGxpbmdDbGFzc0xvYWRlcigpOworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoZURyaXZlcnMpIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBMb29wIG92ZXIgdGhlIGRyaXZlcnMgaW4gdGhlIERyaXZlclNldCBjaGVja2luZyB0byBzZWUgaWYgb25lCisgICAgICAgICAgICAgKiBkb2VzIHVuZGVyc3RhbmQgdGhlIHN1cHBsaWVkIFVSTCAtIHJldHVybiB0aGUgZmlyc3QgZHJpdmVyIHdoaWNoCisgICAgICAgICAgICAgKiBkb2VzIHVuZGVyc3RhbmQgdGhlIFVSTAorICAgICAgICAgICAgICovCisgICAgICAgICAgICBmb3IgKERyaXZlciBkcml2ZXIgOiB0aGVEcml2ZXJzKSB7CisgICAgICAgICAgICAgICAgaWYgKGRyaXZlci5hY2NlcHRzVVJMKHVybCkgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgIERyaXZlck1hbmFnZXIuaXNDbGFzc0Zyb21DbGFzc0xvYWRlcihkcml2ZXIsIGNhbGxlckNsYXNzTG9hZGVyKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZHJpdmVyOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBJZiBubyBkcml2ZXJzIHVuZGVyc3RhbmQgdGhlIFVSTCwgdGhyb3cgYW4gU1FMRXhjZXB0aW9uCisgICAgICAgIC8vIFNRTFN0YXRlOiAwOCAtIGNvbm5lY3Rpb24gZXhjZXB0aW9uCisgICAgICAgIC8vIDAwMSAtIFNRTC1jbGllbnQgdW5hYmxlIHRvIGVzdGFibGlzaCBTUUwtY29ubmVjdGlvbgorICAgICAgICB0aHJvdyBuZXcgU1FMRXhjZXB0aW9uKCJObyBzdWl0YWJsZSBkcml2ZXIiLCAiMDgwMDEiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIHtAY29kZSBFbnVtZXJhdGlvbn0gdGhhdCBjb250YWlucyBhbGwgb2YgdGhlIGxvYWRlZCBKREJDCisgICAgICogZHJpdmVycyB0aGF0IHRoZSBjdXJyZW50IGNhbGxlciBjYW4gYWNjZXNzLgorICAgICAqCisgICAgICogQHJldHVybiBBbiB7QGNvZGUgRW51bWVyYXRpb259IGNvbnRhaW5pbmcgYWxsIHRoZSBjdXJyZW50bHkgbG9hZGVkIEpEQkMKKyAgICAgKiAgICAgICAgIHtAY29kZSBEcml2ZXJzfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEVudW1lcmF0aW9uPERyaXZlcj4gZ2V0RHJpdmVycygpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogU3luY2hyb25pemUgdG8gYXZvaWQgY2xhc2hlcyB3aXRoIGFkZGl0aW9ucyBhbmQgcmVtb3ZhbHMgb2YgZHJpdmVycworICAgICAgICAgKiBpbiB0aGUgRHJpdmVyU2V0CisgICAgICAgICAqLworICAgICAgICBDbGFzc0xvYWRlciBjYWxsZXJDbGFzc0xvYWRlciA9IFZNU3RhY2suZ2V0Q2FsbGluZ0NsYXNzTG9hZGVyKCk7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhlRHJpdmVycykgeworICAgICAgICAgICAgQXJyYXlMaXN0PERyaXZlcj4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxEcml2ZXI+KCk7CisgICAgICAgICAgICBmb3IgKERyaXZlciBkcml2ZXIgOiB0aGVEcml2ZXJzKSB7CisgICAgICAgICAgICAgICAgaWYgKERyaXZlck1hbmFnZXIuaXNDbGFzc0Zyb21DbGFzc0xvYWRlcihkcml2ZXIsIGNhbGxlckNsYXNzTG9hZGVyKSkgeworICAgICAgICAgICAgICAgICAgICByZXN1bHQuYWRkKGRyaXZlcik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVudW1lcmF0aW9uKHJlc3VsdCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb2dpbiB0aW1lb3V0IHdoZW4gY29ubmVjdGluZyB0byBhIGRhdGFiYXNlIGluIHNlY29uZHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsb2dpbiB0aW1lb3V0IGluIHNlY29uZHMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZ2V0TG9naW5UaW1lb3V0KCkgeworICAgICAgICByZXR1cm4gbG9naW5UaW1lb3V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxvZyB7QGNvZGUgUHJpbnRTdHJlYW19IHVzZWQgYnkgdGhlIHtAY29kZSBEcml2ZXJNYW5hZ2VyfSBhbmQKKyAgICAgKiBhbGwgdGhlIEpEQkMgRHJpdmVycy4KKyAgICAgKgorICAgICAqIEBkZXByZWNhdGVkIHVzZSB7QGxpbmsgI2dldExvZ1dyaXRlcigpfSBpbnN0ZWFkLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBQcmludFN0cmVhbX0gdXNlZCBmb3IgbG9nZ2luZyBhY3Rpdml0aWVzLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHN0YXRpYyBQcmludFN0cmVhbSBnZXRMb2dTdHJlYW0oKSB7CisgICAgICAgIHJldHVybiB0aGVQcmludFN0cmVhbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgdGhlIGxvZyB3cml0ZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEge0Bjb2RlIFByaW50V3JpdGVyfSBvYmplY3QgdXNlZCBhcyB0aGUgbG9nIHdyaXRlci4ge0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpZiBubyBsb2cgd3JpdGVyIGlzIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFByaW50V3JpdGVyIGdldExvZ1dyaXRlcigpIHsKKyAgICAgICAgcmV0dXJuIHRoZVByaW50V3JpdGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50cyBhIG1lc3NhZ2UgdG8gdGhlIGN1cnJlbnQgSkRCQyBsb2cgc3RyZWFtLiBUaGlzIGlzIGVpdGhlciB0aGUKKyAgICAgKiB7QGNvZGUgUHJpbnRXcml0ZXJ9IG9yIChkZXByZWNhdGVkKSB0aGUge0Bjb2RlIFByaW50U3RyZWFtfSwgaWYgc2V0LgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBtZXNzYWdlIHRvIHByaW50IHRvIHRoZSBKREJDIGxvZyBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHByaW50bG4oU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICAgICAgaWYgKHRoZVByaW50V3JpdGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRoZVByaW50V3JpdGVyLnByaW50bG4obWVzc2FnZSk7CisgICAgICAgICAgICB0aGVQcmludFdyaXRlci5mbHVzaCgpOworICAgICAgICB9IGVsc2UgaWYgKHRoZVByaW50U3RyZWFtICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRoZVByaW50U3RyZWFtLnByaW50bG4obWVzc2FnZSk7CisgICAgICAgICAgICB0aGVQcmludFN0cmVhbS5mbHVzaCgpOworICAgICAgICB9CisgICAgICAgIC8qCisgICAgICAgICAqIElmIG5laXRoZXIgdGhlIFByaW50V3JpdGVyIG5vdCB0aGUgUHJpbnRTdHJlYW0gYXJlIHNldCwgdGhlbiBzaWxlbnRseQorICAgICAgICAgKiBkbyBub3RoaW5nIHRoZSBtZXNzYWdlIGlzIG5vdCByZWNvcmRlZCBhbmQgbm8gZXhjZXB0aW9uIGlzIGdlbmVyYXRlZC4KKyAgICAgICAgICovCisgICAgfQorCisgICAgLyoqCisgICAgICogUmVnaXN0ZXJzIGEgZ2l2ZW4gSkRCQyBkcml2ZXIgd2l0aCB0aGUge0Bjb2RlIERyaXZlck1hbmFnZXJ9LgorICAgICAqIDxwPgorICAgICAqIEEgbmV3bHkgbG9hZGVkIEpEQkMgZHJpdmVyIGNsYXNzIHNob3VsZCByZWdpc3RlciBpdHNlbGYgd2l0aCB0aGUKKyAgICAgKiB7QGNvZGUgRHJpdmVyTWFuYWdlcn0gYnkgY2FsbGluZyB0aGlzIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkcml2ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgRHJpdmVyfSB0byByZWdpc3RlciB3aXRoIHRoZSB7QGNvZGUgRHJpdmVyTWFuYWdlcn0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGFjY2VzcyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyRHJpdmVyKERyaXZlciBkcml2ZXIpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBpZiAoZHJpdmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHN5bmNocm9uaXplZCAodGhlRHJpdmVycykgeworICAgICAgICAgICAgdGhlRHJpdmVycy5hZGQoZHJpdmVyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGxvZ2luIHRpbWVvdXQgd2hlbiBjb25uZWN0aW5nIHRvIGEgZGF0YWJhc2UgaW4gc2Vjb25kcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzZWNvbmRzCisgICAgICogICAgICAgICAgICBzZWNvbmRzIHVudGlsIHRpbWVvdXQuIDAgaW5kaWNhdGVzIHdhaXQgZm9yZXZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0TG9naW5UaW1lb3V0KGludCBzZWNvbmRzKSB7CisgICAgICAgIGxvZ2luVGltZW91dCA9IHNlY29uZHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcHJpbnQgc3RyZWFtIHRvIHVzZSBmb3IgbG9nZ2luZyBkYXRhIGZyb20gdGhlIHtAY29kZQorICAgICAqIERyaXZlck1hbmFnZXJ9IGFuZCB0aGUgSkRCQyBkcml2ZXJzLgorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjc2V0TG9nV3JpdGVyfSBpbnN0ZWFkLgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgUHJpbnRTdHJlYW19IHRvIHVzZSBmb3IgbG9nZ2luZy4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRMb2dTdHJlYW0oUHJpbnRTdHJlYW0gb3V0KSB7CisgICAgICAgIHRoZVByaW50U3RyZWFtID0gb3V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHtAY29kZSBQcmludFdyaXRlcn0gdGhhdCBpcyB1c2VkIGJ5IGFsbCBsb2FkZWQgZHJpdmVycywgYW5kIGFsc28KKyAgICAgKiB0aGUge0Bjb2RlIERyaXZlck1hbmFnZXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBQcmludFdyaXRlcn0gdG8gYmUgdXNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0TG9nV3JpdGVyKFByaW50V3JpdGVyIG91dCkgeworICAgICAgICB0aGVQcmludFdyaXRlciA9IG91dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHN1cHBsaWVkIG9iamVjdCB3YXMgbG9hZGVkIGJ5IHRoZSBnaXZlbiB7QGNvZGUgQ2xhc3NMb2FkZXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIHRoZU9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjaGVjay4KKyAgICAgKiBAcGFyYW0gdGhlQ2xhc3NMb2FkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2xhc3NMb2FkZXJ9LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBPYmplY3QgZG9lcyBiZWxvbmcgdG8gdGhlIHtAY29kZSBDbGFzc0xvYWRlcn0KKyAgICAgKiAgICAgICAgICwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzQ2xhc3NGcm9tQ2xhc3NMb2FkZXIoT2JqZWN0IHRoZU9iamVjdCwKKyAgICAgICAgICAgIENsYXNzTG9hZGVyIHRoZUNsYXNzTG9hZGVyKSB7CisKKyAgICAgICAgaWYgKCh0aGVPYmplY3QgPT0gbnVsbCkgfHwgKHRoZUNsYXNzTG9hZGVyID09IG51bGwpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBDbGFzczw/PiBvYmplY3RDbGFzcyA9IHRoZU9iamVjdC5nZXRDbGFzcygpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDbGFzczw/PiBjaGVja0NsYXNzID0gQ2xhc3MuZm9yTmFtZShvYmplY3RDbGFzcy5nZXROYW1lKCksIHRydWUsCisgICAgICAgICAgICAgICAgICAgIHRoZUNsYXNzTG9hZGVyKTsKKyAgICAgICAgICAgIGlmIChjaGVja0NsYXNzID09IG9iamVjdENsYXNzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgICAvLyBFbXB0eQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvRHJpdmVyUHJvcGVydHlJbmZvLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvRHJpdmVyUHJvcGVydHlJbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWE2MmYwNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9Ecml2ZXJQcm9wZXJ0eUluZm8uamF2YQpAQCAtMCwwICsxLDczIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworLyoqCisgKiBBIGNsYXNzIGhvbGRpbmcgaW5mb3JtYXRpb24gYWJvdXQgZHJpdmVyIHByb3BlcnRpZXMgb2YgYSBkYXRhYmFzZSBjb25uZWN0aW9uLgorICogVGhpcyBjbGFzcyBpcyByZXR1cm5lZCBieSB0aGUKKyAqIHtAbGluayBEcml2ZXIjZ2V0UHJvcGVydHlJbmZvKFN0cmluZywgamF2YS51dGlsLlByb3BlcnRpZXMpfSBtZXRob2QgYW5kCisgKiBhbGxvd3MgZm9yIHRoZSBhZHZhbmNlZCBjb25uZWN0aW9uIGhhbmRsaW5nLgorICovCitwdWJsaWMgY2xhc3MgRHJpdmVyUHJvcGVydHlJbmZvIHsKKworICAgIC8qKgorICAgICAqIElmIHRoZSB2YWx1ZSBtZW1iZXIgY2FuIGJlIGNob3NlbiBmcm9tIGEgc2V0IG9mIHBvc3NpYmxlIHZhbHVlcywgdGhleSBhcmUKKyAgICAgKiBjb250YWluZWQgaGVyZS4gT3RoZXJ3aXNlIGNob2ljZXMgaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBjaG9pY2VzOworCisgICAgLyoqCisgICAgICogQSBkZXNjcmlwdGlvbiBvZiB0aGUgcHJvcGVydHkuIE1heSBiZSB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBkZXNjcmlwdGlvbjsKKworICAgIC8qKgorICAgICAqIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIG5hbWU7CisKKyAgICAvKioKKyAgICAgKiB7QGNvZGUgdHJ1ZX0gd2hlbiB0aGUgdmFsdWUgbWVtYmVyIG11c3QgYmUgcHJvdmlkZWQgZHVyaW5nIHtAY29kZQorICAgICAqIERyaXZlci5jb25uZWN0fS4ge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVxdWlyZWQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY3VycmVudCB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBwcm9wZXJ0eS4gSXQgaXMgZGVwZW5kaW5nIG9uIHRoZQorICAgICAqIGRhdGEgZ2F0aGVyZWQgYnkgdGhlIHtAY29kZSBnZXRQcm9wZXJ0eUluZm99IG1ldGhvZCwgdGhlIGdlbmVyYWwgSmF2YQorICAgICAqIGVudmlyb25tZW50IGFuZCB0aGUgZHJpdmVyJ3MgZGVmYXVsdCB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB2YWx1ZTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgRHJpdmVyUHJvcGVydHlJbmZvfSBpbnN0YW5jZSB3aXRoIHRoZSBzdXBwbGllZCBuYW1lIGFuZAorICAgICAqIHZhbHVlLiBPdGhlciBjbGFzcyBtZW1iZXJzIHRha2UgdGhlaXIgZGVmYXVsdCB2YWx1ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgVGhlIHByb3BlcnR5IG5hbWUuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICBUaGUgcHJvcGVydHkgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIERyaXZlclByb3BlcnR5SW5mbyhTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICAgICAgdGhpcy5jaG9pY2VzID0gbnVsbDsKKyAgICAgICAgdGhpcy5kZXNjcmlwdGlvbiA9IG51bGw7CisgICAgICAgIHRoaXMucmVxdWlyZWQgPSBmYWxzZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvTkNsb2IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9OQ2xvYi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmExMGI1MGQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvTkNsb2IuamF2YQpAQCAtMCwwICsxLDIxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworcHVibGljIGludGVyZmFjZSBOQ2xvYiBleHRlbmRzIENsb2IgeworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9QYXJhbWV0ZXJNZXRhRGF0YS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1BhcmFtZXRlck1ldGFEYXRhLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDJlODlmZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9QYXJhbWV0ZXJNZXRhRGF0YS5qYXZhCkBAIC0wLDAgKzEsMTg5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworLyoqCisgKiBBbiBpbnRlcmZhY2UgdXNlZCB0byBnZXQgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHR5cGVzIGFuZCBwcm9wZXJ0aWVzIG9mCisgKiBwYXJhbWV0ZXJzIGluIGEge0Bjb2RlIFByZXBhcmVkU3RhdGVtZW50fS4KKyAqLworcHVibGljIGludGVyZmFjZSBQYXJhbWV0ZXJNZXRhRGF0YSBleHRlbmRzIFdyYXBwZXIgeworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoYXQgdGhlIHBhcmFtZXRlciBtb2RlIGlzIHtAY29kZSBJTn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgcGFyYW1ldGVyTW9kZUluID0gMTsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB0aGF0IHRoZSBwYXJhbWV0ZXIgbW9kZSBpcyB7QGNvZGUgSU5PVVR9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHBhcmFtZXRlck1vZGVJbk91dCA9IDI7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgcGFyYW1ldGVyIG1vZGUgaXMge0Bjb2RlIE9VVH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgcGFyYW1ldGVyTW9kZU91dCA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgcGFyYW1ldGVyIG1vZGUgaXMgbm90IGtub3duLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHBhcmFtZXRlck1vZGVVbmtub3duID0gMDsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB0aGF0IGEgcGFyYW1ldGVyIGlzIG5vdCBwZXJtaXR0ZWQgdG8gYmUge0Bjb2RlIE5VTEx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHBhcmFtZXRlck5vTnVsbHMgPSAwOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoYXQgYSBwYXJhbWV0ZXIgaXMgcGVybWl0dGVkIHRvIGJlIHtAY29kZSBOVUxMfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBwYXJhbWV0ZXJOdWxsYWJsZSA9IDE7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhhdCB3aGV0aGVyIGEgcGFyYW1ldGVyIGlzIGFsbG93ZWQgdG8gYmUge0Bjb2RlIG51bGx9IG9yIG5vdAorICAgICAqIGlzIG5vdCBrbm93bi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBwYXJhbWV0ZXJOdWxsYWJsZVVua25vd24gPSAyOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZnVsbHktcXVhbGlmaWVkIG5hbWUgb2YgdGhlIEphdmEgY2xhc3Mgd2hpY2ggc2hvdWxkIGJlIHBhc3NlZCBhcworICAgICAqIGEgcGFyYW1ldGVyIHRvIHRoZSBtZXRob2Qge0Bjb2RlIFByZXBhcmVkU3RhdGVtZW50LnNldE9iamVjdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG51bWJlciBvZiB0aGUgcGFyYW1ldGVyLCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyCisgICAgICogICAgICAgICAgICBoYXMgaW5kZXggMS4KKyAgICAgKiBAcmV0dXJuIHRoZSBmdWxseSBxdWFsaWZpZWQgSmF2YSBjbGFzcyBuYW1lIG9mIHRoZSBwYXJhbWV0ZXIgd2l0aCB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBpbmRleC4gVGhpcyBjbGFzcyBuYW1lIGlzIHVzZWQgZm9yIGN1c3RvbSBtYXBwaW5nCisgICAgICogICAgICAgICBiZXR3ZWVuIFNRTCB0eXBlcyBhbmQgSmF2YSBvYmplY3RzLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGFyYW1ldGVyQ2xhc3NOYW1lKGludCBwYXJhbUluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIHBhcmFtZXRlcnMgaW4gdGhlIHtAY29kZSBQcmVwYXJlZFN0YXRlbWVudH0gZm9yIHdoaWNoCisgICAgICogdGhpcyB7QGNvZGUgUGFyYW1ldGVyTWV0YURhdGF9IGNvbnRhaW5zIGluZm9ybWF0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHBhcmFtZXRlcnMuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRQYXJhbWV0ZXJDb3VudCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtb2RlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyLiBDYW4gYmUgb25lIG9mOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+UGFyYW1ldGVyTWV0YURhdGEucGFyYW1ldGVyTW9kZUluPC9saT4KKyAgICAgKiA8bGk+UGFyYW1ldGVyTWV0YURhdGEucGFyYW1ldGVyTW9kZU91dDwvbGk+CisgICAgICogPGxpPlBhcmFtZXRlck1ldGFEYXRhLnBhcmFtZXRlck1vZGVJbk91dDwvbGk+CisgICAgICogPGxpPlBhcmFtZXRlck1ldGFEYXRhLnBhcmFtZXRlck1vZGVVbmtub3duPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBudW1iZXIgb2YgdGhlIHBhcmFtZXRlciwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlcgorICAgICAqICAgICAgICAgICAgaGFzIGluZGV4IDEuCisgICAgICogQHJldHVybiB0aGUgcGFyYW1ldGVyJ3MgbW9kZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFBhcmFtZXRlck1vZGUoaW50IHBhcmFtSW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBTUUwgdHlwZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG51bWJlciBvZiB0aGUgcGFyYW1ldGVyLCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyCisgICAgICogICAgICAgICAgICBoYXMgaW5kZXggMS4KKyAgICAgKiBAcmV0dXJuIHRoZSBTUUwgdHlwZSBvZiB0aGUgcGFyYW1ldGVyIGFzIGRlZmluZWQgaW4ge0Bjb2RlCisgICAgICogICAgICAgICBqYXZhLnNxbC5UeXBlc30uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRQYXJhbWV0ZXJUeXBlKGludCBwYXJhbUluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGF0YWJhc2Utc3BlY2lmaWMgdHlwZSBuYW1lIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggbnVtYmVyIG9mIHRoZSBwYXJhbWV0ZXIsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIKKyAgICAgKiAgICAgICAgICAgIGhhcyBpbmRleCAxLgorICAgICAqIEByZXR1cm4gdGhlIHR5cGUgbmFtZSBmb3IgdGhlIHBhcmFtZXRlciBhcyB1c2VkIGJ5IHRoZSBkYXRhYmFzZS4gQQorICAgICAqICAgICAgICAgZnVsbHktcXVhbGlmaWVkIG5hbWUgaXMgcmV0dXJuZWQgaWYgdGhlIHBhcmFtZXRlciBpcyBhIDxpPlVzZXIKKyAgICAgKiAgICAgICAgIERlZmluZWQgVHlwZTwvaT4gKFVEVCkuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRQYXJhbWV0ZXJUeXBlTmFtZShpbnQgcGFyYW1JbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBkZWNpbWFsIGRpZ2l0cyBmb3IgYSBzcGVjaWZpZWQgcGFyYW1ldGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBudW1iZXIgb2YgdGhlIHBhcmFtZXRlciwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlcgorICAgICAqICAgICAgICAgICAgaGFzIGluZGV4IDEuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGRlY2ltYWwgZGlnaXRzICgidGhlIHByZWNpc2lvbiIpIGZvciB0aGUgcGFyYW1ldGVyLgorICAgICAqICAgICAgICAge0Bjb2RlIDB9IGlmIHRoZSBwYXJhbWV0ZXIgaXMgbm90IGEgbnVtZXJpYyB0eXBlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UHJlY2lzaW9uKGludCBwYXJhbUluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGRpZ2l0cyBhZnRlciB0aGUgZGVjaW1hbCBwb2ludCBmb3IgYSBzcGVjaWZpZWQKKyAgICAgKiBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG51bWJlciBvZiB0aGUgcGFyYW1ldGVyLCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyCisgICAgICogICAgICAgICAgICBoYXMgaW5kZXggMS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgZGlnaXRzIGFmdGVyIHRoZSBkZWNpbWFsIHBvaW50ICgidGhlIHNjYWxlIikgZm9yCisgICAgICogICAgICAgICB0aGUgcGFyYW1ldGVyLiB7QGNvZGUgMH0gaWYgdGhlIHBhcmFtZXRlciBpcyBub3QgYSBudW1lcmljIHR5cGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRTY2FsZShpbnQgcGFyYW1JbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgd2hldGhlciB7QGNvZGUgbnVsbH0gdmFsdWVzIGFyZSBhbGxvd2VkIGZvciB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlci4KKyAgICAgKiBUaGUgcmV0dXJuZWQgdmFsdWUgaXMgb25lIG9mOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+UGFyYW1ldGVyTWV0YURhdGEucGFyYW1ldGVyTm9OdWxsczwvbGk+CisgICAgICogPGxpPlBhcmFtZXRlck1ldGFEYXRhLnBhcmFtZXRlck51bGxhYmxlPC9saT4KKyAgICAgKiA8bGk+UGFyYW1ldGVyTWV0YURhdGEucGFyYW1ldGVyTnVsbGFibGVVbmtub3duPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBudW1iZXIgb2YgdGhlIHBhcmFtZXRlciwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlcgorICAgICAqICAgICAgICAgICAgaGFzIGluZGV4IDEuCisgICAgICogQHJldHVybiB0aGUgaW50IGNvZGUgaW5kaWNhdGluZyB0aGUgbnVsbGFiaWxpdHkgb2YgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaXMgZW5jb3VudGVyZWQuCisgICAgICovCisgICAgcHVibGljIGludCBpc051bGxhYmxlKGludCBwYXJhbUluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB3aGV0aGVyIHZhbHVlcyBmb3IgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgY2FuIGJlIHNpZ25lZCBudW1iZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBudW1iZXIgb2YgdGhlIHBhcmFtZXRlciwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlcgorICAgICAqICAgICAgICAgICAgaGFzIGluZGV4IDEuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdmFsdWVzIGNhbiBiZSBzaWduZWQgbnVtYmVycyBmb3IgdGhpcyBwYXJhbWV0ZXIsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NpZ25lZChpbnQgcGFyYW1JbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9QcmVwYXJlZFN0YXRlbWVudC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1ByZXBhcmVkU3RhdGVtZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDFmMzc1ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9QcmVwYXJlZFN0YXRlbWVudC5qYXZhCkBAIC0wLDAgKzEsOTE4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CitpbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEudXRpbC5DYWxlbmRhcjsKKworLyoqCisgKiBBbiBpbnRlcmZhY2UgZm9yIGEgcHJlY29tcGlsZWQgU1FMIFN0YXRlbWVudC4KKyAqIDxwPgorICogQW4gU1FMIFN0YXRlbWVudCBpcyBwdXQgaW50byBhIHtAY29kZSBQcmVwYXJlZFN0YXRlbWVudH0gYW5kIGlzIHByZWNvbXBpbGVkCisgKiBzbyB0aGF0IGl0IGNhbiBiZSBleGVjdXRlZCBlZmZpY2llbnRseSBtdWx0aXBsZSB0aW1lcy4KKyAqIDxwPgorICogU2V0dGVyIG1ldGhvZHMgYXJlIHN1cHBsaWVkIGluIHRoZSB7QGNvZGUgUHJlcGFyZWRTdGF0ZW1lbnR9IGludGVyZmFjZSBmb3IKKyAqIHRoZSBzZXR0aW5nIG9mIHtAY29kZSBJTn0gcGFyYW1ldGVycyBmb3IgdGhlIHN0YXRlbWVudC4gVGhlIHNldHRlciBtZXRob2QKKyAqIHVzZWQgZm9yIGVhY2gge0Bjb2RlIElOfSBwYXJhbWV0ZXIgbXVzdCBtYXRjaCB0aGUgcGFyYW1ldGVyJ3MgdHlwZS4KKyAqLworcHVibGljIGludGVyZmFjZSBQcmVwYXJlZFN0YXRlbWVudCBleHRlbmRzIFN0YXRlbWVudCB7CisKKyAgICAvKioKKyAgICAgKiBBZGQgYSBzZXQgb2YgcGFyYW1ldGVycyB0byB0aGUge0Bjb2RlIFByZXBhcmVkU3RhdGVtZW50fSdzIGNvbW1hbmQgYmF0Y2guCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRCYXRjaCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDbGVhciB0aGUgY3VycmVudCBwYXJhbWV0ZXIgdmFsdWVzLgorICAgICAqIDxwPgorICAgICAqIFR5cGljYWxseSwgcGFyYW1ldGVyIHZhbHVlcyBhcmUgcmV0YWluZWQgZm9yIG11bHRpcGxlIGV4ZWN1dGlvbnMgb2YgdGhlCisgICAgICoge0Bjb2RlIFN0YXRlbWVudH0uIFNldHRpbmcgYSBwYXJhbWV0ZXIgdmFsdWUgcmVwbGFjZXMgdGhlIHByZXZpb3VzIHZhbHVlLiBUaGlzCisgICAgICogbWV0aG9kIGNsZWFycyB0aGUgdmFsdWVzIGZvciBhbGwgcGFyYW1ldGVycywgcmVsZWFzaW5nIGFsbCByZXNvdXJjZXMgdXNlZAorICAgICAqIGJ5IHRob3NlIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbGVhclBhcmFtZXRlcnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRXhlY3V0ZXMgdGhlIFNRTCBzdGF0ZW1lbnQgaW4gdGhpcyB7QGNvZGUgUHJlcGFyZWRTdGF0ZW1lbnR9LgorICAgICAqIDxwPgorICAgICAqIEEge0Bjb2RlIFByZXBhcmVkU3RhdGVtZW50fSBtYXkgcmV0dXJuIG11bHRpcGxlIHJlc3VsdHMuIFRoZSBleGVjdXRlCisgICAgICogbWV0aG9kIGV4ZWN1dGVzIHRoZSB7QGNvZGUgUHJlcGFyZWRTdGF0ZW1lbnR9IGFuZCByZXR1cm5zIGEgZmxhZworICAgICAqIGluZGljYXRpbmcgdGhlIGtpbmQgb2YgcmVzdWx0IHByb2R1Y2VkIGJ5IHRoZSBhY3Rpb24uIFRoZSBtZXRob2RzCisgICAgICoge0Bjb2RlIGdldFJlc3VsdFNldH0gb3Ige0Bjb2RlIGdldFVwZGF0ZUNvdW50fSBhcmUgdXNlZCB0byByZXRyaWV2ZQorICAgICAqIHRoZSBmaXJzdCByZXN1bHQsIGFuZCB0aGUgc2Vjb25kIGFuZCBzdWJzZXF1ZW50IHJlc3VsdHMgYXJlCisgICAgICogcmV0cmlldmVkIHdpdGgge0Bjb2RlIGdldE1vcmVSZXN1bHRzfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSByZXN1bHQgb2YgdGhlIGV4ZWN1dGlvbiBpcyBhIHtAY29kZQorICAgICAqICAgICAgICAgUmVzdWx0U2V0fSwge0Bjb2RlIGZhbHNlfSBpZiB0aGVyZSBpcyBubyByZXN1bHQgb3IgaWYgdGhlIHJlc3VsdAorICAgICAqICAgICAgICAgaXMgYW4gdXBkYXRlIGNvdW50LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGV4ZWN1dGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRXhlY3V0ZXMgdGhlIFNRTCBxdWVyeSBpbiB0aGUge0Bjb2RlIFByZXBhcmVkU3RhdGVtZW50fSBhbmQgcmV0dXJucyB0aGUKKyAgICAgKiB7QGNvZGUgUmVzdWx0U2V0fSBnZW5lcmF0ZWQgYnkgdGhlIHF1ZXJ5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFJlc3VsdFNldH0gZ2VuZXJhdGVkIGJ5IHRoZSBxdWVyeSwgbmV2ZXIge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zIG9yIGlmIHRoZSBTUUwgc3RhdGVtZW50IGRvZXMgbm90CisgICAgICogICAgICAgICAgICAgcHJvZHVjZSBhIHtAY29kZSBSZXN1bHRTZXR9LgorICAgICAqLworICAgIHB1YmxpYyBSZXN1bHRTZXQgZXhlY3V0ZVF1ZXJ5KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEludm9rZXMgdGhlIFNRTCBjb21tYW5kIGNvbnRhaW5lZCB3aXRoaW4gdGhlIHByZXBhcmVkIHN0YXRlbWVudC4gVGhpcworICAgICAqIG11c3QgYmUge0Bjb2RlIElOU0VSVH0sIHtAY29kZSBVUERBVEV9LCB7QGNvZGUgREVMRVRFfSwgb3IgYSBjb21tYW5kIHRoYXQKKyAgICAgKiByZXR1cm5zIG5vdGhpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYWZmZWN0ZWQgcm93cyBmb3Ige0Bjb2RlIElOU0VSVH0sIHtAY29kZSBVUERBVEV9IG9yIHtAY29kZQorICAgICAqICAgICAgICAgREVMRVRFfSBzdGF0ZW1lbnRzLCB7QGNvZGUgMH0gZm9yIHN0YXRlbWVudHMgdGhhdCByZXR1cm4gbm90aGluZy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucyBvciBpZiB0aGUgU1FMIHN0YXRlbWVudCByZXR1cm5zIGEKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgUmVzdWx0U2V0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGV4ZWN1dGVVcGRhdGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBSZXN1bHRTZXRNZXRhRGF0YX0gZGVzY3JpYmluZyB0aGUge0Bjb2RlCisgICAgICogUmVzdWx0U2V0fSB0aGF0IHdvdWxkIGJlIHByb2R1Y2VkIGJ5IGV4ZWN1dGlvbiBvZiB0aGUge0Bjb2RlIFByZXBhcmVkU3RhdGVtZW50fS4KKyAgICAgKiA8cD4KKyAgICAgKiBJdCBpcyBwb3NzaWJsZSB0byBrbm93IHRoZSBtZXRhZGF0YSBmb3IgdGhlIHtAY29kZSBSZXN1bHRTZXR9IHdpdGhvdXQKKyAgICAgKiBleGVjdXRpbmcgdGhlIHtAY29kZSBQcmVwYXJlZFN0YXRlbWVudH0sIGJlY2F1c2UgdGhlIHtAY29kZQorICAgICAqIFByZXBhcmVkU3RhdGVtZW50fSBpcyBwcmVjb21waWxlZC4gQXMgYSByZXN1bHQgdGhlIG1ldGFkYXRhIGNhbiBiZQorICAgICAqIHF1ZXJpZWQgYWhlYWQgb2YgdGltZSB3aXRob3V0IGFjdHVhbGx5IGV4ZWN1dGluZyB0aGUgc3RhdGVtZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIHtAY29kZSBSZXN1bHRTZXRNZXRhRGF0YX0gb2JqZWN0IHdpdGggdGhlIGluZm9ybWF0aW9uIGFib3V0IHRoZQorICAgICAqICAgICAgICAgY29sdW1ucyBvZiB0aGUge0Bjb2RlIFJlc3VsdFNldH0sIGlmIHRoZSBkcml2ZXIgY2FuIHJldHVybiBhCisgICAgICogICAgICAgICB7QGNvZGUgUmVzdWx0U2V0TWV0YURhdGF9LiB7QGNvZGUgbnVsbH0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzdWx0U2V0TWV0YURhdGEgZ2V0TWV0YURhdGEoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGFyYW1ldGVycyBvZiB0aGUge0Bjb2RlIFByZXBhcmVkU3RhdGVtZW50fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgUGFyYW1ldGVyTWV0YURhdGF9IG9iamVjdCB3aGljaCBob2xkcyBpbmZvcm1hdGlvbiBhYm91dAorICAgICAqICAgICAgICAgdGhlIG51bWJlciwgdHlwZSwgYW5kIHByb3BlcnRpZXMgb2YgdGhlIHBhcmFtZXRlcnMgb2YgdGhpcyB7QGNvZGUKKyAgICAgKiAgICAgICAgIFByZXBhcmVkU3RhdGVtZW50fS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyYW1ldGVyTWV0YURhdGEgZ2V0UGFyYW1ldGVyTWV0YURhdGEoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIHRoZSBzdXBwbGllZCB7QGNvZGUgQXJyYXl9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHBhcmFtIHRoZUFycmF5CisgICAgICogICAgICAgICAgICBhIHtAY29kZSBqYXZhLnNxbC5BcnJheX0gZ2l2aW5nIHRoZSBuZXcgdmFsdWUgb2YgdGhlIHBhcmFtZXRlciBhdCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIHBhcmFtZXRlckluZGV4fS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKiBAc2VlIEFycmF5CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QXJyYXkoaW50IHBhcmFtZXRlckluZGV4LCBBcnJheSB0aGVBcnJheSkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gdGhlIGNvbnRlbnQgb2YgYSBzdXBwbGllZAorICAgICAqIHtAY29kZSBJbnB1dFN0cmVhbX0sIHdoaWNoIGhhcyBhIHNwZWNpZmllZCBudW1iZXIgb2YgYnl0ZXMuCisgICAgICogPHA+CisgICAgICogVGhpcyBpcyBhIGdvb2QgbWV0aG9kIGZvciBzZXR0aW5nIGFuIFNRTCB7QGNvZGUgTE9OR1ZBUkNIQVJ9IHBhcmFtZXRlcgorICAgICAqIHdoZXJlIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgaXMgbGFyZ2UuIERhdGEgaXMgcmVhZCBmcm9tIHRoZSB7QGNvZGUKKyAgICAgKiBJbnB1dFN0cmVhbX0gdW50aWwgZW5kLW9mLWZpbGUgaXMgcmVhY2hlZCBvciB0aGUgc3BlY2lmaWVkIG51bWJlciBvZgorICAgICAqIGJ5dGVzIGlzIGNvcGllZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVJbnB1dFN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIEFTQ0lJIHtAY29kZSBJbnB1dFN0cmVhbX0gY2FycnlpbmcgdGhlIGRhdGEgdG8gd2hpY2ggdGhlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIgYXQge0Bjb2RlIHBhcmFtZXRlckluZGV4fSBpcyBzZXQuCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyBpbiB0aGUge0Bjb2RlIElucHV0U3RyZWFtfSB0byBjb3B5IHRvIHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEFzY2lpU3RyZWFtKGludCBwYXJhbWV0ZXJJbmRleCwgSW5wdXRTdHJlYW0gdGhlSW5wdXRTdHJlYW0sCisgICAgICAgICAgICBpbnQgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIGEgc3VwcGxpZWQge0Bjb2RlCisgICAgICogamF2YS5tYXRoLkJpZ0RlY2ltYWx9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHBhcmFtIHRoZUJpZ0RlY2ltYWwKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGF0IHtAY29kZSBwYXJhbWV0ZXJJbmRleH0gaXMKKyAgICAgKiAgICAgICAgICAgIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKiBAc2VlIGphdmEubWF0aC5CaWdEZWNpbWFsCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QmlnRGVjaW1hbChpbnQgcGFyYW1ldGVySW5kZXgsIEJpZ0RlY2ltYWwgdGhlQmlnRGVjaW1hbCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gdGhlIGNvbnRlbnQgb2YgYSBzdXBwbGllZAorICAgICAqIGJpbmFyeSB7QGNvZGUgSW5wdXRTdHJlYW19LCB3aGljaCBoYXMgYSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJ5dGVzLgorICAgICAqIDxwPgorICAgICAqIFVzZSB0aGlzIG1ldGhvZCB3aGVuIGEgbGFyZ2UgYW1vdW50IG9mIGRhdGEgbmVlZHMgdG8gYmUgc2V0IGludG8gYQorICAgICAqIHtAY29kZSBMT05HVkFSQklOQVJZfSBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMS4KKyAgICAgKiBAcGFyYW0gdGhlSW5wdXRTdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBiaW5hcnkge0Bjb2RlIElucHV0U3RyZWFtfSBjYXJyeWluZyB0aGUgZGF0YSB0byB1cGRhdGUgdGhlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIuCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyBpbiB0aGUge0Bjb2RlIElucHV0U3RyZWFtfSB0byBjb3B5IHRvIHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJpbmFyeVN0cmVhbShpbnQgcGFyYW1ldGVySW5kZXgsIElucHV0U3RyZWFtIHRoZUlucHV0U3RyZWFtLAorICAgICAgICAgICAgaW50IGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB0byB0aGUgZ2l2ZW4ge0Bjb2RlIEJsb2J9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVCbG9iCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGphdmEuc3FsLkJsb2J9IHRvIHdoaWNoIHRoZSBwYXJhbWV0ZXIgYXQge0Bjb2RlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXJJbmRleH0gaXMgc2V0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqIEBzZWUgQmxvYgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJsb2IoaW50IHBhcmFtZXRlckluZGV4LCBCbG9iIHRoZUJsb2IpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gYSBzdXBwbGllZCB7QGNvZGUgYm9vbGVhbn0KKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVCb29sZWFuCisgICAgICogICAgICAgICAgICB0aGUgYm9vbGVhbiB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGF0IHtAY29kZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVySW5kZXh9IGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCb29sZWFuKGludCBwYXJhbWV0ZXJJbmRleCwgYm9vbGVhbiB0aGVCb29sZWFuKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB0byBhIHN1cHBsaWVkIHtAY29kZSBieXRlfSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVCeXRlCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGF0IHtAY29kZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVySW5kZXh9IGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCeXRlKGludCBwYXJhbWV0ZXJJbmRleCwgYnl0ZSB0aGVCeXRlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIGEgc3VwcGxpZWQgYXJyYXkgb2YgYnl0ZXMuIFRoZQorICAgICAqIGFycmF5IGlzIG1hcHBlZCB0byBhIHtAY29kZSBWQVJCSU5BUll9IG9yIHtAY29kZSBMT05HVkFSQklOQVJZfSBpbiB0aGUKKyAgICAgKiBkYXRhYmFzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVCeXRlcworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIGJ5dGVzIHRvIHdoaWNoIHRoZSBwYXJhbWV0ZXIgYXQge0Bjb2RlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXJJbmRleH0gaXMgc2V0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJ5dGVzKGludCBwYXJhbWV0ZXJJbmRleCwgYnl0ZVtdIHRoZUJ5dGVzKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB0byB0aGUgY2hhcmFjdGVyIGNvbnRlbnQgb2YgYQorICAgICAqIHtAY29kZSBSZWFkZXJ9IG9iamVjdCwgd2l0aCB0aGUgc3BlY2lmaWVkIGxlbmd0aCBvZiBjaGFyYWN0ZXIgZGF0YS4KKyAgICAgKiA8cD4KKyAgICAgKiBEYXRhIGlzIHJlYWQgZnJvbSB0aGUge0Bjb2RlCisgICAgICogUmVhZGVyfSB1bnRpbCBlbmQtb2YtZmlsZSBpcyByZWFjaGVkIG9yIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mCisgICAgICogY2hhcmFjdGVycyBhcmUgY29waWVkLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEKKyAgICAgKiBAcGFyYW0gcmVhZGVyCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGphdmEuaW8uUmVhZGVyfSBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXIgZGF0YS4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gYmUgcmVhZC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDaGFyYWN0ZXJTdHJlYW0oaW50IHBhcmFtZXRlckluZGV4LCBSZWFkZXIgcmVhZGVyLCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB0byB0aGUgZ2l2ZW4ge0Bjb2RlIENsb2J9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVDbG9iCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBqYXZhLnNxbC5DbG9ifSBob2xkaW5nIHRoZSBkYXRhIHRvIHdoaWNoIHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyIGF0IHtAY29kZSBwYXJhbWV0ZXJJbmRleH0gaXMgc2V0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENsb2IoaW50IHBhcmFtZXRlckluZGV4LCBDbG9iIHRoZUNsb2IpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gYSBzdXBwbGllZCB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5EYXRlfSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVEYXRlCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBqYXZhLnNxbC5EYXRlfSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGF0IHtAY29kZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVySW5kZXh9IGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREYXRlKGludCBwYXJhbWV0ZXJJbmRleCwgRGF0ZSB0aGVEYXRlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIGEgc3VwcGxpZWQge0Bjb2RlCisgICAgICogamF2YS5zcWwuRGF0ZX0gdmFsdWUsIHVzaW5nIGEgc3VwcGxpZWQge0Bjb2RlIENhbGVuZGFyfSB0byBtYXAgdGhlIERhdGUuCisgICAgICogVGhlIHtAY29kZSBDYWxlbmRhcn0gYWxsb3dzIHRoZSBhcHBsaWNhdGlvbiB0byBjb250cm9sIHRoZSB0aW1lem9uZSB1c2VkCisgICAgICogdG8gY29tcHV0ZSB0aGUgU1FMIHtAY29kZSBEQVRFfSBpbiB0aGUgZGF0YWJhc2UgLSB3aXRob3V0IHRoZSBzdXBwbGllZAorICAgICAqIHtAY29kZSBDYWxlbmRhcn0sIHRoZSBkcml2ZXIgdXNlcyB0aGUgVk0gZGVmYXVsdHMuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHBhcmFtIHRoZURhdGUKKyAgICAgKiAgICAgICAgICAgIGEge0Bjb2RlIGphdmEuc3FsLkRhdGV9IHRvIHdoaWNoIHRoZSBwYXJhbWV0ZXIgYXQge0Bjb2RlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXJJbmRleH0gaXMgc2V0LgorICAgICAqIEBwYXJhbSBjYWwKKyAgICAgKiAgICAgICAgICAgIGEge0Bjb2RlIENhbGVuZGFyfSB0byB1c2UgdG8gY29uc3RydWN0IHRoZSBTUUwge0Bjb2RlIERBVEV9CisgICAgICogICAgICAgICAgICB2YWx1ZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKiBAc2VlIERhdGUKKyAgICAgKiBAc2VlIGphdmEudXRpbC5DYWxlbmRhcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERhdGUoaW50IHBhcmFtZXRlckluZGV4LCBEYXRlIHRoZURhdGUsIENhbGVuZGFyIGNhbCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gYSBzdXBwbGllZCB7QGNvZGUgZG91YmxlfQorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHBhcmFtIHRoZURvdWJsZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBkb3VibGV9IHZhbHVlIHRvIHdoaWNoIHRoZSBwYXJhbWV0ZXIgYXQge0Bjb2RlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXJJbmRleH0gaXMgc2V0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERvdWJsZShpbnQgcGFyYW1ldGVySW5kZXgsIGRvdWJsZSB0aGVEb3VibGUpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIHRvIGEgc3VwcGxpZWQge0Bjb2RlIGZsb2F0fQorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHBhcmFtIHRoZUZsb2F0CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGZsb2F0fSB2YWx1ZSB0byB1cGRhdGUgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGbG9hdChpbnQgcGFyYW1ldGVySW5kZXgsIGZsb2F0IHRoZUZsb2F0KQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIHBhcmFtZXRlciB0byBhIHN1cHBsaWVkIHtAY29kZSBpbnR9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHBhcmFtIHRoZUludAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBpbnR9IHZhbHVlIHRvIHdoaWNoIHRoZSBwYXJhbWV0ZXIgYXQge0Bjb2RlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXJJbmRleH0gaXMgc2V0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEludChpbnQgcGFyYW1ldGVySW5kZXgsIGludCB0aGVJbnQpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gYSBzdXBwbGllZCB7QGNvZGUgbG9uZ30gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMS4KKyAgICAgKiBAcGFyYW0gdGhlTG9uZworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBsb25nfSB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGF0IHtAY29kZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVySW5kZXh9IGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMb25nKGludCBwYXJhbWV0ZXJJbmRleCwgbG9uZyB0aGVMb25nKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIFNRTCB7QGNvZGUgTlVMTH0uIERvbid0IHVzZQorICAgICAqIHRoaXMgdmVyc2lvbiBvZiB7QGNvZGUgc2V0TnVsbH0gZm9yIDxpPlVzZXIgRGVmaW5lZCBUeXBlczwvaT4gKFVEVCkgb3IKKyAgICAgKiBmb3IgUkVGIHR5cGUgcGFyYW1ldGVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSBzcWxUeXBlCisgICAgICogICAgICAgICAgICB0aGUgU1FMIHR5cGUgb2YgdGhlIHBhcmFtZXRlciwgYXMgZGVmaW5lZCBpbiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIGphdmEuc3FsLlR5cGVzfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROdWxsKGludCBwYXJhbWV0ZXJJbmRleCwgaW50IHNxbFR5cGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gU1FMIHtAY29kZSBOVUxMfS4gVGhpcyB2ZXJzaW9uCisgICAgICogb2Yge0Bjb2RlIHNldE51bGx9IHNob3VsZCBiZSB1c2VkIGZvciA8aT5Vc2VyIERlZmluZWQgVHlwZXM8L2k+IChVRFRzKQorICAgICAqIGFuZCBhbHNvIFJFRiB0eXBlcy4gVURUcyBjYW4gYmUge0Bjb2RlIFNUUlVDVH0sIHtAY29kZSBESVNUSU5DVH0sIHtAY29kZQorICAgICAqIEpBVkFfT0JKRUNUfSBhbmQgbmFtZWQgYXJyYXkgdHlwZXMuCisgICAgICogPHA+CisgICAgICogQXBwbGljYXRpb25zIG11c3QgcHJvdmlkZSB0aGUgU1FMIHR5cGUgY29kZSBhbmQgYWxzbyBhIGZ1bGx5IHF1YWxpZmllZAorICAgICAqIFNRTCB0eXBlIG5hbWUgd2hlbiBzdXBwbHlpbmcgYSB7QGNvZGUgTlVMTH0gVURUIG9yIFJFRi4gRm9yIGEgVURULCB0aGUKKyAgICAgKiB0eXBlIG5hbWUgaXMgdGhlIHR5cGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyIGl0c2VsZiwgYnV0IGZvciBhIFJFRgorICAgICAqIHBhcmFtZXRlciB0aGUgdHlwZSBuYW1lIGlzIHRoZSB0eXBlIG5hbWUgb2YgdGhlIHJlZmVyZW5jZWQgdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbUluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHBhcmFtIHNxbFR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBTUUwgdHlwZSBvZiB0aGUgcGFyYW1ldGVyLCBhcyBkZWZpbmVkIGluIHtAY29kZQorICAgICAqICAgICAgICAgICAgamF2YS5zcWwuVHlwZXN9LgorICAgICAqIEBwYXJhbSB0eXBlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIGEgVURUIG9yIFJFRiB0eXBlIC0gaWdub3JlZCBpZiB0aGUKKyAgICAgKiAgICAgICAgICAgIHBhcmFtZXRlciBpcyBub3QgYSBVRFQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICogQHNlZSBUeXBlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE51bGwoaW50IHBhcmFtSW5kZXgsIGludCBzcWxUeXBlLCBTdHJpbmcgdHlwZU5hbWUpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHVzaW5nIGEgc3VwcGxpZWQgb2JqZWN0LgorICAgICAqIDxwPgorICAgICAqIFRoZXJlIGlzIGEgc3RhbmRhcmQgbWFwcGluZyBmcm9tIEphdmEgdHlwZXMgdG8gU1FMIHR5cGVzLCBkZWZpbmVkIGluIHRoZQorICAgICAqIEpEQkMgc3BlY2lmaWNhdGlvbi4gVGhlIHBhc3NlZCBvYmplY3QgaXMgdGhlbiB0cmFuc2Zvcm1lZCBpbnRvIHRoZQorICAgICAqIGFwcHJvcHJpYXRlIFNRTCB0eXBlLCBhbmQgdGhlbiB0cmFuc2ZlcnJlZCB0byB0aGUgZGF0YWJhc2UuIHtAY29kZQorICAgICAqIHNldE9iamVjdH0gY2FuIGJlIHVzZWQgdG8gcGFzcyBhYnN0cmFjdCBkYXRhIHR5cGVzIHVuaXF1ZSB0byB0aGUKKyAgICAgKiBkYXRhYmFzZSwgYnkgdXNpbmcgYSBKREJDIGRyaXZlciBzcGVjaWZpYyBKYXZhIHR5cGUuIElmIHRoZSBvYmplY3QncworICAgICAqIGNsYXNzIGltcGxlbWVudHMgdGhlIGludGVyZmFjZSB7QGNvZGUgU1FMRGF0YX0sIHRoZSBKREJDIGRyaXZlciBjYWxscworICAgICAqIHtAY29kZSBTUUxEYXRhLndyaXRlU1FMfSB0byB3cml0ZSBpdCB0byB0aGUgU1FMIGRhdGEgc3RyZWFtLiBJZiB0aGUKKyAgICAgKiBvYmplY3QncyBjbGFzcyBpbXBsZW1lbnRzIHtAY29kZSBSZWZ9LCB7QGNvZGUgQmxvYn0sIHtAY29kZSBDbG9ifSwKKyAgICAgKiB7QGNvZGUgU3RydWN0fSwgb3Ige0Bjb2RlIEFycmF5fSwgdGhlIGRyaXZlciBwYXNzZXMgaXQgdG8gdGhlIGRhdGFiYXNlIGFzCisgICAgICogYSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBTUUwgdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVPYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgY29udGFpbmluZyB0aGUgdmFsdWUgdG8gd2hpY2ggdGhlIHBhcmFtZXRlciBhdAorICAgICAqICAgICAgICAgICAge0Bjb2RlIHBhcmFtZXRlckluZGV4fSBpcyBzZXQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0T2JqZWN0KGludCBwYXJhbWV0ZXJJbmRleCwgT2JqZWN0IHRoZU9iamVjdCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdXNpbmcgYSBzdXBwbGllZCBvYmplY3QuCisgICAgICogPHA+CisgICAgICogVGhlIG9iamVjdCBpcyBjb252ZXJ0ZWQgdG8gdGhlIGdpdmVuIHtAY29kZSB0YXJnZXRTcWxUeXBlfSBiZWZvcmUgaXQgaXMKKyAgICAgKiBzZW50IHRvIHRoZSBkYXRhYmFzZS4gSWYgdGhlIG9iamVjdCBoYXMgYSBjdXN0b20gbWFwcGluZyAoaXRzIGNsYXNzCisgICAgICogaW1wbGVtZW50cyB0aGUgaW50ZXJmYWNlIHtAY29kZSBTUUxEYXRhfSksIHRoZSBKREJDIGRyaXZlciB3aWxsIGNhbGwgdGhlIG1ldGhvZAorICAgICAqIHtAY29kZSBTUUxEYXRhLndyaXRlU1FMfSB0byB3cml0ZSBpdCB0byB0aGUgU1FMIGRhdGEgc3RyZWFtLiBJZiB0aGUKKyAgICAgKiBvYmplY3QncyBjbGFzcyBpbXBsZW1lbnRzIHtAY29kZSBSZWZ9LCB7QGNvZGUgQmxvYn0sIHtAY29kZSBDbG9ifSwKKyAgICAgKiB7QGNvZGUgU3RydWN0fSwgb3Ige0Bjb2RlIEFycmF5fSwgdGhlIGRyaXZlciB3aWxsIHBhc3MgaXQgdG8gdGhlIGRhdGFiYXNlCisgICAgICogaW4gdGhlIGZvcm0gb2YgdGhlIHJlbGV2YW50IFNRTCB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcyBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVPYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBPYmplY3QgY29udGFpbmluZyB0aGUgdmFsdWUgdG8gd2hpY2ggdGhlIHBhcmFtZXRlciBhdAorICAgICAqICAgICAgICAgICAge0Bjb2RlIHBhcmFtZXRlckluZGV4fSBpcyBzZXQuCisgICAgICogQHBhcmFtIHRhcmdldFNxbFR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBTUUwgdHlwZSB0byBzZW5kIHRvIHRoZSBkYXRhYmFzZSwgYXMgZGVmaW5lZCBpbiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIGphdmEuc3FsLlR5cGVzfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRPYmplY3QoaW50IHBhcmFtZXRlckluZGV4LCBPYmplY3QgdGhlT2JqZWN0LAorICAgICAgICAgICAgaW50IHRhcmdldFNxbFR5cGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdXNpbmcgYSBzdXBwbGllZCBvYmplY3QuCisgICAgICogPHA+CisgICAgICogVGhlIG9iamVjdCBpcyBjb252ZXJ0ZWQgdG8gdGhlIGdpdmVuIHtAY29kZSB0YXJnZXRTcWxUeXBlfSBiZWZvcmUgaXQgaXMKKyAgICAgKiBzZW50IHRvIHRoZSBkYXRhYmFzZS4gSWYgdGhlIG9iamVjdCBoYXMgYSBjdXN0b20gbWFwcGluZyAoaXRzIGNsYXNzCisgICAgICogaW1wbGVtZW50cyB0aGUgaW50ZXJmYWNlIHtAY29kZSBTUUxEYXRhfSksIHRoZSBKREJDIGRyaXZlciB3aWxsIGNhbGwgdGhlIG1ldGhvZAorICAgICAqIHtAY29kZSBTUUxEYXRhLndyaXRlU1FMfSB0byB3cml0ZSBpdCB0byB0aGUgU1FMIGRhdGEgc3RyZWFtLiBJZiB0aGUKKyAgICAgKiBvYmplY3QncyBjbGFzcyBpbXBsZW1lbnRzIHtAY29kZSBSZWZ9LCB7QGNvZGUgQmxvYn0sIHtAY29kZSBDbG9ifSwKKyAgICAgKiB7QGNvZGUgU3RydWN0fSwgb3Ige0Bjb2RlIEFycmF5fSwgdGhlIGRyaXZlciB3aWxsIHBhc3MgaXQgdG8gdGhlIGRhdGFiYXNlCisgICAgICogaW4gdGhlIGZvcm0gb2YgdGhlIHJlbGV2YW50IFNRTCB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcyBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVPYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBPYmplY3QgY29udGFpbmluZyB0aGUgdmFsdWUgdG8gd2hpY2ggdGhlIHBhcmFtZXRlciBhdAorICAgICAqICAgICAgICAgICAge0Bjb2RlIHBhcmFtZXRlckluZGV4fSBpcyBzZXQuCisgICAgICogQHBhcmFtIHRhcmdldFNxbFR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBTUUwgdHlwZSB0byBzZW5kIHRvIHRoZSBkYXRhYmFzZSwgYXMgZGVmaW5lZCBpbiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIGphdmEuc3FsLlR5cGVzfS4KKyAgICAgKiBAcGFyYW0gc2NhbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgZGlnaXRzIGFmdGVyIHRoZSBkZWNpbWFsIHBvaW50IC0gb25seSBhcHBsaWVzIHRvCisgICAgICogICAgICAgICAgICB0aGUgdHlwZXMge0Bjb2RlIGphdmEuc3FsLlR5cGVzLkRFQ0lNQUx9IGFuZCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIGphdmEuc3FsLlR5cGVzLk5VTUVSSUN9IC0gaWdub3JlZCBmb3IgYWxsIG90aGVyIHR5cGVzLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE9iamVjdChpbnQgcGFyYW1ldGVySW5kZXgsIE9iamVjdCB0aGVPYmplY3QsCisgICAgICAgICAgICBpbnQgdGFyZ2V0U3FsVHlwZSwgaW50IHNjYWxlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIGEgc3VwcGxpZWQge0Bjb2RlCisgICAgICogUkVGKDxzdHJ1Y3R1cmVkLXR5cGU+KX0gdmFsdWUuIFRoaXMgaXMgc3RvcmVkIGFzIGFuIFNRTCB7QGNvZGUgUkVGfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVSZWYKKyAgICAgKiAgICAgICAgICAgIGEge0Bjb2RlIGphdmEuc3FsLlJlZn0gdmFsdWUgdG8gd2hpY2ggdGhlIHBhcmFtZXRlciBhdCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIHBhcmFtZXRlckluZGV4fSBpcyBzZXQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICogQHNlZSBSZWYKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSZWYoaW50IHBhcmFtZXRlckluZGV4LCBSZWYgdGhlUmVmKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIGEgc3VwcGxpZWQge0Bjb2RlIHNob3J0fQorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHBhcmFtIHRoZVNob3J0CisgICAgICogICAgICAgICAgICBhIHtAY29kZSBzaG9ydH0gdmFsdWUgdG8gd2hpY2ggdGhlIHBhcmFtZXRlciBhdCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIHBhcmFtZXRlckluZGV4fSBpcyBzZXQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2hvcnQoaW50IHBhcmFtZXRlckluZGV4LCBzaG9ydCB0aGVTaG9ydCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gYSBzdXBwbGllZCBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMS4KKyAgICAgKiBAcGFyYW0gdGhlU3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gd2hpY2ggdGhlIHBhcmFtZXRlciBhdCB7QGNvZGUgcGFyYW1ldGVySW5kZXh9IGlzCisgICAgICogICAgICAgICAgICBzZXQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3RyaW5nKGludCBwYXJhbWV0ZXJJbmRleCwgU3RyaW5nIHRoZVN0cmluZykKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gYSBzdXBwbGllZCB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5UaW1lfSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVUaW1lCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBqYXZhLnNxbC5UaW1lfSB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGF0CisgICAgICogICAgICAgICAgICB7QGNvZGUgcGFyYW1ldGVySW5kZXh9IGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lKGludCBwYXJhbWV0ZXJJbmRleCwgVGltZSB0aGVUaW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIGEgc3VwcGxpZWQge0Bjb2RlCisgICAgICogamF2YS5zcWwuVGltZX0gdmFsdWUsIHVzaW5nIGEgc3VwcGxpZWQge0Bjb2RlIENhbGVuZGFyfS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZHJpdmVyIHVzZXMgdGhlIHN1cHBsaWVkIHtAY29kZSBDYWxlbmRhcn0gdG8gY3JlYXRlIHRoZSBTUUwge0Bjb2RlCisgICAgICogVElNRX0gdmFsdWUsIHdoaWNoIGFsbG93cyBpdCB0byB1c2UgYSBjdXN0b20gdGltZXpvbmUgLSBvdGhlcndpc2UgdGhlCisgICAgICogZHJpdmVyIHVzZXMgdGhlIFZNIGRlZmF1bHRzLgorICAgICAqIFNlZSAiPGEgaHJlZj0iLi4vdXRpbC9Mb2NhbGUuaHRtbCNkZWZhdWx0X2xvY2FsZSI+QmUgd2FyeSBvZiB0aGUgZGVmYXVsdCBsb2NhbGU8L2E+Ii4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVUaW1lCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBqYXZhLnNxbC5UaW1lfSB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGF0CisgICAgICogICAgICAgICAgICB7QGNvZGUgcGFyYW1ldGVySW5kZXh9IGlzIHNldC4KKyAgICAgKiBAcGFyYW0gY2FsCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBDYWxlbmRhcn0gdG8gdXNlIHRvIGNvbnN0cnVjdCB0aGUgU1FMIHtAY29kZSBUSU1FfQorICAgICAqICAgICAgICAgICAgdmFsdWUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICogQHNlZSBUaW1lCisgICAgICogQHNlZSBqYXZhLnV0aWwuQ2FsZW5kYXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lKGludCBwYXJhbWV0ZXJJbmRleCwgVGltZSB0aGVUaW1lLCBDYWxlbmRhciBjYWwpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIGEgc3VwcGxpZWQgamF2YS5zcWwuVGltZXN0YW1wCisgICAgICogdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMS4KKyAgICAgKiBAcGFyYW0gdGhlVGltZXN0YW1wCisgICAgICogICAgICAgICAgICB0aGUgamF2YS5zcWwuVGltZXN0YW1wIHZhbHVlIHRvIHdoaWNoIHRoZSBwYXJhbWV0ZXIgYXQge0Bjb2RlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXJJbmRleH0gaXMgc2V0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRpbWVzdGFtcChpbnQgcGFyYW1ldGVySW5kZXgsIFRpbWVzdGFtcCB0aGVUaW1lc3RhbXApCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIGEgc3VwcGxpZWQge0Bjb2RlCisgICAgICogamF2YS5zcWwuVGltZXN0YW1wfSB2YWx1ZSwgdXNpbmcgdGhlIHN1cHBsaWVkIHtAY29kZSBDYWxlbmRhcn0uCisgICAgICogPHA+CisgICAgICogVGhlIGRyaXZlciB1c2VzIHRoZSBzdXBwbGllZCB7QGNvZGUgQ2FsZW5kYXJ9IHRvIGNyZWF0ZSB0aGUgU1FMIHtAY29kZQorICAgICAqIFRJTUVTVEFNUH0gdmFsdWUsIHdoaWNoIGFsbG93cyBpdCB0byB1c2UgYSBjdXN0b20gdGltZXpvbmUgLSBvdGhlcndpc2UKKyAgICAgKiB0aGUgZHJpdmVyIHVzZXMgdGhlIFZNIGRlZmF1bHRzLgorICAgICAqIFNlZSAiPGEgaHJlZj0iLi4vdXRpbC9Mb2NhbGUuaHRtbCNkZWZhdWx0X2xvY2FsZSI+QmUgd2FyeSBvZiB0aGUgZGVmYXVsdCBsb2NhbGU8L2E+Ii4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVUaW1lc3RhbXAKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgamF2YS5zcWwuVGltZXN0YW1wfSB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGF0CisgICAgICogICAgICAgICAgICB7QGNvZGUgcGFyYW1ldGVySW5kZXh9IGlzIHNldC4KKyAgICAgKiBAcGFyYW0gY2FsCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBDYWxlbmRhcn0gdG8gdXNlIHRvIGNvbnN0cnVjdCB0aGUgU1FMIHtAY29kZQorICAgICAqICAgICAgICAgICAgVElNRVNUQU1QfSB2YWx1ZQorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqIEBzZWUgVGltZXN0YW1wCisgICAgICogQHNlZSBqYXZhLnV0aWwuQ2FsZW5kYXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lc3RhbXAoaW50IHBhcmFtZXRlckluZGV4LCBUaW1lc3RhbXAgdGhlVGltZXN0YW1wLAorICAgICAgICAgICAgQ2FsZW5kYXIgY2FsKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIHRoZSBjaGFyYWN0ZXJzIGZyb20gYSBzdXBwbGllZAorICAgICAqIHtAY29kZSBJbnB1dFN0cmVhbX0sIHdpdGggYSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJ5dGVzLgorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjc2V0Q2hhcmFjdGVyU3RyZWFtKGludCwgUmVhZGVyLCBpbnQpfQorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVJbnB1dFN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBJbnB1dFN0cmVhbX0gd2l0aCB0aGUgY2hhcmFjdGVyIGRhdGEgdG8gd2hpY2ggdGhlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIgYXQge0Bjb2RlIHBhcmFtZXRlckluZGV4fSBpcyBzZXQuCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyB0byByZWFkIGZyb20gdGhlIHtAY29kZSBJbnB1dFN0cmVhbX0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgdm9pZCBzZXRVbmljb2RlU3RyZWFtKGludCBwYXJhbWV0ZXJJbmRleCwKKyAgICAgICAgICAgIElucHV0U3RyZWFtIHRoZUlucHV0U3RyZWFtLCBpbnQgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIGEgc3VwcGxpZWQge0Bjb2RlCisgICAgICogamF2YS5uZXQuVVJMfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSB0aGVVUkwKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgVVJMfSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGF0IHtAY29kZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVySW5kZXh9IGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKiBAc2VlIFVSTAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFVSTChpbnQgcGFyYW1ldGVySW5kZXgsIFVSTCB0aGVVUkwpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gYSBzdXBwbGllZCB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5Sb3dJZH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMS4KKyAgICAgKiBAcGFyYW0gdGhlUm93SWQKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgUm93SWR9IHRvIHdoaWNoIHRoZSBwYXJhbWV0ZXIgYXQge0Bjb2RlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXJJbmRleH0gaXMgc2V0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSb3dJZChpbnQgcGFyYW1ldGVySW5kZXgsIFJvd0lkIHRoZVJvd0lkKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIGEgc3VwcGxpZWQgc3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHBhcmFtIHRoZVN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBTdHJpbmd9IHRvIHdoaWNoIHRoZSBwYXJhbWV0ZXIgYXQge0Bjb2RlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXJJbmRleH0gaXMgc2V0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROU3RyaW5nKGludCBwYXJhbWV0ZXJJbmRleCwgU3RyaW5nIHRoZVN0cmluZykgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIHRoZSBuZXh0IHtAY29kZSBsZW5ndGh9IGNoYXJhY3RlcnMKKyAgICAgKiBmcm9tIHtAY29kZSByZWFkZXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHBhcmFtIHJlYWRlciB0aGUge0Bjb2RlIFJlYWRlcn0KKyAgICAgKiBAcGFyYW0gbGVuZ3RoIGNoYXJhY3RlciBjb3VudAorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROQ2hhcmFjdGVyU3RyZWFtKGludCBwYXJhbWV0ZXJJbmRleCwgUmVhZGVyIHJlYWRlciwgbG9uZyBsZW5ndGgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciB0byB7QGNvZGUgdmFsdWV9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIE5DbG9ifSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGF0IHtAY29kZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVySW5kZXh9IGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TkNsb2IoaW50IHBhcmFtZXRlckluZGV4LCBOQ2xvYiB2YWx1ZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIHRoZSBuZXh0IHtAY29kZSBsZW5ndGh9IGNoYXJhY3RlcnMKKyAgICAgKiBmcm9tIHtAY29kZSByZWFkZXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHBhcmFtIHJlYWRlciB0aGUge0Bjb2RlIFJlYWRlcn0KKyAgICAgKiBAcGFyYW0gbGVuZ3RoIGNoYXJhY3RlciBjb3VudAorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDbG9iKGludCBwYXJhbWV0ZXJJbmRleCwgUmVhZGVyIHJlYWRlciwgbG9uZyBsZW5ndGgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciB0byB0aGUgbmV4dCB7QGNvZGUgbGVuZ3RofSBieXRlcworICAgICAqIGZyb20ge0Bjb2RlIGlucHV0U3RyZWFtfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSBpbnB1dFN0cmVhbSB0aGUge0Bjb2RlIElucHV0U3RyZWFtfQorICAgICAqIEBwYXJhbSBsZW5ndGggY2hhcmFjdGVyIGNvdW50CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJsb2IoaW50IHBhcmFtZXRlckluZGV4LCBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSwgbG9uZyBsZW5ndGgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciB0byB0aGUgbmV4dCB7QGNvZGUgbGVuZ3RofSBjaGFyYWN0ZXJzCisgICAgICogZnJvbSB7QGNvZGUgcmVhZGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSByZWFkZXIgdGhlIHtAY29kZSBSZWFkZXJ9CisgICAgICogQHBhcmFtIGxlbmd0aCBjaGFyYWN0ZXIgY291bnQKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TkNsb2IoaW50IHBhcmFtZXRlckluZGV4LCBSZWFkZXIgcmVhZGVyLCBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIHRoZSB2YWx1ZSBvZiB7QGNvZGUgeG1sT2JqZWN0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSB4bWxPYmplY3QgdGhlIHtAY29kZSBTUUxYTUx9CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNRTFhNTChpbnQgcGFyYW1ldGVySW5kZXgsIFNRTFhNTCB4bWxPYmplY3QpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciB0byB0aGUgbmV4dCB7QGNvZGUgbGVuZ3RofSBieXRlcworICAgICAqIGZyb20ge0Bjb2RlIGlucHV0U3RyZWFtfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSBpbnB1dFN0cmVhbSB0aGUge0Bjb2RlIElucHV0U3RyZWFtfQorICAgICAqIEBwYXJhbSBsZW5ndGggY2hhcmFjdGVyIGNvdW50CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEFzY2lpU3RyZWFtKGludCBwYXJhbWV0ZXJJbmRleCwgSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0sIGxvbmcgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gdGhlIG5leHQge0Bjb2RlIGxlbmd0aH0gYnl0ZXMKKyAgICAgKiBmcm9tIHtAY29kZSBpbnB1dFN0cmVhbX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMS4KKyAgICAgKiBAcGFyYW0gaW5wdXRTdHJlYW0gdGhlIHtAY29kZSBJbnB1dFN0cmVhbX0KKyAgICAgKiBAcGFyYW0gbGVuZ3RoIGNoYXJhY3RlciBjb3VudAorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCaW5hcnlTdHJlYW0oaW50IHBhcmFtZXRlckluZGV4LCBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSwgbG9uZyBsZW5ndGgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciB0byB0aGUgbmV4dCB7QGNvZGUgbGVuZ3RofSBjaGFyYWN0ZXJzCisgICAgICogZnJvbSB7QGNvZGUgcmVhZGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSByZWFkZXIgdGhlIHtAY29kZSBSZWFkZXJ9CisgICAgICogQHBhcmFtIGxlbmd0aCBjaGFyYWN0ZXIgY291bnQKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q2hhcmFjdGVyU3RyZWFtKGludCBwYXJhbWV0ZXJJbmRleCwgUmVhZGVyIHJlYWRlciwgbG9uZyBsZW5ndGgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciB0byB0aGUgYnl0ZXMKKyAgICAgKiBmcm9tIHtAY29kZSBpbnB1dFN0cmVhbX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMS4KKyAgICAgKiBAcGFyYW0gaW5wdXRTdHJlYW0gdGhlIHtAY29kZSBJbnB1dFN0cmVhbX0KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QXNjaWlTdHJlYW0oaW50IHBhcmFtZXRlckluZGV4LCBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIHRoZSBieXRlcworICAgICAqIGZyb20ge0Bjb2RlIGlucHV0U3RyZWFtfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSBpbnB1dFN0cmVhbSB0aGUge0Bjb2RlIElucHV0U3RyZWFtfQorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCaW5hcnlTdHJlYW0oaW50IHBhcmFtZXRlckluZGV4LCBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIHRoZSBjaGFyYWN0ZXJzCisgICAgICogZnJvbSB7QGNvZGUgcmVhZGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSByZWFkZXIgdGhlIHtAY29kZSBSZWFkZXJ9CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENoYXJhY3RlclN0cmVhbShpbnQgcGFyYW1ldGVySW5kZXgsIFJlYWRlciByZWFkZXIpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciB0byB0aGUgY2hhcmFjdGVycworICAgICAqIGZyb20ge0Bjb2RlIHJlYWRlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgbnVtYmVyIGluZGV4LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggMS4KKyAgICAgKiBAcGFyYW0gcmVhZGVyIHRoZSB7QGNvZGUgUmVhZGVyfQorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROQ2hhcmFjdGVyU3RyZWFtKGludCBwYXJhbWV0ZXJJbmRleCwgUmVhZGVyIHJlYWRlcikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIHRoZSBjaGFyYWN0ZXJzCisgICAgICogZnJvbSB7QGNvZGUgcmVhZGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSByZWFkZXIgdGhlIHtAY29kZSBSZWFkZXJ9CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENsb2IoaW50IHBhcmFtZXRlckluZGV4LCBSZWFkZXIgcmVhZGVyKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgdG8gdGhlIGJ5dGVzCisgICAgICogZnJvbSB7QGNvZGUgaW5wdXRTdHJlYW19LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIG51bWJlciBpbmRleCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4IDEuCisgICAgICogQHBhcmFtIGlucHV0U3RyZWFtIHRoZSB7QGNvZGUgSW5wdXRTdHJlYW19CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJsb2IoaW50IHBhcmFtZXRlckluZGV4LCBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIHRvIHRoZSBjaGFyYWN0ZXJzCisgICAgICogZnJvbSB7QGNvZGUgcmVhZGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBudW1iZXIgaW5kZXgsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCAxLgorICAgICAqIEBwYXJhbSByZWFkZXIgdGhlIHtAY29kZSBSZWFkZXJ9CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5DbG9iKGludCBwYXJhbWV0ZXJJbmRleCwgUmVhZGVyIHJlYWRlcikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9SZWYuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9SZWYuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYTRhYjhiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1JlZi5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBUaGlzIGludGVyZmFjZSByZXByZXNlbnRzIGFuIFNRTCBSZWYgLSBhIGRhdGEgb2JqZWN0IGNvbnRhaW5pbmcgYSBjdXJzb3IKKyAqIG9yIHBvaW50ZXIgdG8gYSByZXN1bHQgdGFibGUuCisgKiA8cD4KKyAqIFRoZSBkYXRhIHN0cnVjdHVyZSBpZGVudGlmaWVkIGJ5IGFuIGluc3RhbmNlIG9mIFJlZiBpcyBoZWxkIGluIHRoZQorICogZGF0YWJhc2UsIHNvIHRoZSBkYXRhIGlzIG5vdCBuZWNlc3NhcmlseSByZWFkIGFuZCBjb252ZXJ0ZWQKKyAqIGludG8gYSBKYXZhIG9iamVjdCB1bnRpbCB7QGNvZGUgZ2V0T2JqZWN0fSBpcyBjYWxsZWQuIEhvd2V2ZXIsIGlmCisgKiB0aGUgZGF0YWJhc2Ugc3VwcG9ydHMgdGhlIHtAY29kZSBSZWZ9IHR5cGUsIGl0IGlzIG5vdCB0eXBpY2FsbHkKKyAqIG5lY2Vzc2FyeSB0byBnZXQgdGhlIHVuZGVybHlpbmcgb2JqZWN0IGJlZm9yZSB1c2luZyBpdCBpbiBhIG1ldGhvZCBjYWxsIC0KKyAqIHRoZSB7QGNvZGUgUmVmfSBvYmplY3QgY2FuIGJlIHVzZWQgaW4gcGxhY2Ugb2YgdGhlIGRhdGEgc3RydWN0dXJlLgorICogPHA+CisgKiBBIHtAY29kZSBSZWZ9IG9iamVjdCBpcyBzdG9yZWQgaW50byB0aGUgZGF0YWJhc2UgdXNpbmcgdGhlCisgKiB7QGxpbmsgUHJlcGFyZWRTdGF0ZW1lbnQjc2V0UmVmKGludCwgUmVmKX0gbWV0aG9kLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFJlZiB7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBmdWxseS1xdWFsaWZpZWQgU1FMIG5hbWUgb2YgdGhlIFNRTCBzdHJ1Y3R1cmVkIHR5cGUgdGhhdCB0aGlzCisgICAgICoge0Bjb2RlIFJlZn0gcmVmZXJlbmNlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBTUUwgc3RydWN0dXJlZCB0eXBlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VUeXBlTmFtZSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBTUUwgc3RydWN0dXJlZCB0eXBlIGluc3RhbmNlIHJlZmVyZW5jZWQgYnkgdGhpcyB7QGNvZGUgUmVmfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBKYXZhIG9iamVjdCB3aG9zZSB0eXBlIGlzIGRlZmluZWQgYnkgdGhlIG1hcHBpbmcgZm9yIHRoZSBTUUwKKyAgICAgKiAgICAgICAgIHN0cnVjdHVyZWQgdHlwZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRPYmplY3QoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXNzb2NpYXRlZCBvYmplY3QgYW5kIHVzZXMgdGhlIHJlbGV2YW50IG1hcHBpbmcgdG8gY29udmVydCBpdAorICAgICAqIHRvIGEgSmF2YSB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIG1hcAorICAgICAqICAgICAgICAgICAgdGhlIG1hcHBpbmcgZm9yIHR5cGUgY29udmVyc2lvbi4KKyAgICAgKiBAcmV0dXJuIGEgSmF2YSBvYmplY3Qgd2hvc2UgdHlwZSBpcyBkZWZpbmVkIGJ5IHRoZSBtYXBwaW5nIGZvciB0aGUgU1FMCisgICAgICogICAgICAgICBzdHJ1Y3R1cmVkIHR5cGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0T2JqZWN0KE1hcDxTdHJpbmcsIENsYXNzPD8+PiBtYXApIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3RydWN0dXJlZCB0eXBlIHRoYXQgdGhpcyB7QGNvZGUgUmVmfSByZWZlcmVuY2VzIHRvCisgICAgICogYSBzdXBwbGllZCBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT2JqZWN0fSByZXByZXNlbnRpbmcgdGhlIG5ldyBTUUwgc3RydWN0dXJlZCB0eXBlCisgICAgICogICAgICAgICAgICB0aGF0IHRoaXMge0Bjb2RlIFJlZn0gcmVmZXJlbmNlcy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0T2JqZWN0KE9iamVjdCB2YWx1ZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9SZXN1bHRTZXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9SZXN1bHRTZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NGVjYjU5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1Jlc3VsdFNldC5qYXZhCkBAIC0wLDAgKzEsMjI3MSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zcWw7CisKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUmVhZGVyOworaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBBbiBpbnRlcmZhY2UgZm9yIGFuIG9iamVjdCB3aGljaCByZXByZXNlbnRzIGEgZGF0YWJhc2UgdGFibGUgZW50cnksIHJldHVybmVkCisgKiBhcyB0aGUgcmVzdWx0IG9mIHRoZSBxdWVyeSB0byB0aGUgZGF0YWJhc2UuCisgKiA8cD4KKyAqIHtAY29kZSBSZXN1bHRTZXR9cyBoYXZlIGEgY3Vyc29yIHdoaWNoIHBvaW50cyB0byB0aGUgY3VycmVudCBkYXRhIHRhYmxlIHJvdy4KKyAqIFdoZW4gdGhlIHtAY29kZSBSZXN1bHRTZXR9IGlzIGNyZWF0ZWQsIHRoZSBjdXJzb3IncyBsb2NhdGlvbiBpcyBvbmUgcG9zaXRpb24KKyAqIGFoZWFkIG9mIHRoZSBmaXJzdCByb3cuIFRvIG1vdmUgdGhlIGN1cnNvciB0byB0aGUgZmlyc3QgYW5kIGNvbnNlY3V0aXZlIHJvd3MsCisgKiB1c2UgdGhlIHtAY29kZSBuZXh0fSBtZXRob2QuIFRoZSB7QGNvZGUgbmV4dH0gbWV0aG9kIHJldHVybnMge0Bjb2RlIHRydWV9IGFzCisgKiBsb25nIGFzIHRoZXJlIGFyZSBtb3JlIHJvd3MgaW4gdGhlIHtAY29kZSBSZXN1bHRTZXR9LCBvdGhlcndpc2UgaXQgcmV0dXJucworICoge0Bjb2RlIGZhbHNlfS4KKyAqIDxwPgorICogVGhlIGRlZmF1bHQgdHlwZSBvZiB7QGNvZGUgUmVzdWx0U2V0fSBjYW4gbm90IGJlIHVwZGF0ZWQgYW5kIGl0cyBjdXJzb3IgY2FuCisgKiBvbmx5IGFkdmFuY2UgZm9yd2FyZCB0aHJvdWdoIHRoZSByb3dzIG9mIGRhdGEuIFRoaXMgbWVhbnMgdGhhdCBpdCBpcyBvbmx5CisgKiBwb3NzaWJsZSB0byByZWFkIHRocm91Z2ggaXQgb25jZS4gSG93ZXZlciwgb3RoZXIga2luZHMgb2Yge0Bjb2RlIFJlc3VsdFNldH0KKyAqIGFyZSBpbXBsZW1lbnRlZDogYW4gPGk+dXBkYXRhYmxlPC9pPiB0eXBlIGFuZCBhbHNvIHR5cGVzIHdoZXJlIHRoZSBjdXJzb3IgY2FuCisgKiBiZSA8aT5zY3JvbGxlZDwvaT4gZm9yd2FyZCBhbmQgYmFja3dhcmQgdGhyb3VnaCB0aGUgcm93cyBvZiBkYXRhLiBIb3cgc3VjaCBhCisgKiB7QGNvZGUgUmVzdWx0U2V0fSBpcyBjcmVhdGVkIGlzIGRlbW9uc3RyYXRlZCBpbiB0aGUgZm9sbG93aW5nIGV4YW1wbGU6CisgKiA8dWw+CisgKiA8ZGQ+CisgKiAgICAgICAgIHtAY29kZSBDb25uZWN0aW9uIGNvbjt9PC9kZD4KKyAqIDxkZD57QGNvZGUgU3RhdGVtZW50IGFTdGF0ZW1lbnQgPSBjb24uY3JlYXRlU3RhdGVtZW50KAorICogUmVzdWx0U2V0LlRZUEVfU0NST0xMX1NFTlNJVElWRSx9e0Bjb2RlIFJlc3VsdFNldC5DT05DVVJfVVBEQVRBQkxFICk7fTwvZGQ+CisgKiA8ZGQ+e0Bjb2RlIFJlc3VsdFNldCB0aGVSZXN1bHRTZXQgPQorICogdGhlU3RhdGVtZW50LmV4ZWN1dGVRdWVyeSgiU0VMRUNUIHByaWNlLCBxdWFudGl0eSBGUk9NIFNUT0NLVEFCTEUiKTt9PC9kZD4KKyAqIDxkZD57QGNvZGUgLy8gdGhlUmVzdWx0U2V0IGlzIGJvdGggc2Nyb2xsYWJsZSBhbmQgdXBkYXRhYmxlfTwvZGQ+IDwvdWw+CisgKiA8cD4KKyAqIFRoZSB7QGNvZGUgUmVzdWx0U2V0fSBpbnRlcmZhY2UgcHJvdmlkZXMgYSBzZXJpZXMgb2YgbWV0aG9kcyBmb3IgcmV0cmlldmluZworICogZGF0YSBmcm9tIGNvbHVtbnMgaW4gdGhlIGN1cnJlbnQgcm93LCBzdWNoIGFzIHtAY29kZSBnZXREYXRlfSBhbmQge0Bjb2RlCisgKiBnZXRGbG9hdH0uIFRoZSBjb2x1bW5zIGFyZSByZXRyaWV2ZWQgZWl0aGVyIGJ5IHRoZWlyIGluZGV4IG51bWJlciAoc3RhcnRpbmcKKyAqIGF0IDEpIG9yIGJ5IHRoZWlyIG5hbWUgLSB0aGVyZSBhcmUgc2VwYXJhdGUgbWV0aG9kcyBmb3IgYm90aCB0ZWNobmlxdWVzIG9mCisgKiBjb2x1bW4gYWRkcmVzc2luZy4gVGhlIGNvbHVtbiBuYW1lcyBhcmUgY2FzZSBpbnNlbnNpdGl2ZS4gSWYgc2V2ZXJhbCBjb2x1bW5zCisgKiBoYXZlIHRoZSBzYW1lIG5hbWUsIHRoZW4gdGhlIGdldHRlciBtZXRob2RzIHVzZSB0aGUgZmlyc3QgbWF0Y2hpbmcgY29sdW1uLgorICogVGhpcyBtZWFucyB0aGF0IGlmIGNvbHVtbiBuYW1lcyBhcmUgdXNlZCwgaXQgaXMgbm90IHBvc3NpYmxlIHRvIGd1YXJhbnRlZQorICogdGhhdCB0aGUgbmFtZSB3aWxsIHJldHJpZXZlIGRhdGEgZnJvbSB0aGUgaW50ZW5kZWQgY29sdW1uIC0gZm9yIGNlcnRhaW50eSBpdAorICogaXMgYmV0dGVyIHRvIHVzZSBjb2x1bW4gaW5kZXhlcy4gSWRlYWxseSB0aGUgY29sdW1ucyBzaG91bGQgYmUgcmVhZAorICogbGVmdC10by1yaWdodCBhbmQgcmVhZCBvbmNlIG9ubHksIHNpbmNlIG5vdCBhbGwgZGF0YWJhc2VzIGFyZSBvcHRpbWl6ZWQgdG8KKyAqIGhhbmRsZSBvdGhlciB0ZWNobmlxdWVzIG9mIHJlYWRpbmcgdGhlIGRhdGEuCisgKiA8cD4KKyAqIFdoZW4gcmVhZGluZyBkYXRhIHZpYSB0aGUgYXBwcm9wcmlhdGUgZ2V0dGVyIG1ldGhvZHMsIHRoZSBKREJDIGRyaXZlciBtYXBzCisgKiB0aGUgU1FMIGRhdGEgcmV0cmlldmVkIGZyb20gdGhlIGRhdGFiYXNlIHRvIHRoZSBKYXZhIHR5cGUgaW1wbGllZCBieSB0aGUKKyAqIG1ldGhvZCBpbnZva2VkIGJ5IHRoZSBhcHBsaWNhdGlvbi4gVGhlIEpEQkMgc3BlY2lmaWNhdGlvbiBoYXMgYSB0YWJsZSBmb3IgdGhlCisgKiBtYXBwaW5ncyBmcm9tIFNRTCB0eXBlcyB0byBKYXZhIHR5cGVzLgorICogPHA+CisgKiBUaGVyZSBhcmUgYWxzbyBtZXRob2RzIGZvciB3cml0aW5nIGRhdGEgaW50byB0aGUge0Bjb2RlIFJlc3VsdFNldH0sIHN1Y2ggYXMKKyAqIHtAY29kZSB1cGRhdGVJbnR9IGFuZCB7QGNvZGUgdXBkYXRlU3RyaW5nfS4gVGhlIHVwZGF0ZSBtZXRob2RzIGNhbiBiZSB1c2VkCisgKiBlaXRoZXIgdG8gbW9kaWZ5IHRoZSBkYXRhIG9mIGFuIGV4aXN0aW5nIHJvdyBvciB0byBpbnNlcnQgbmV3IGRhdGEgcm93cyBpbnRvCisgKiB0aGUge0Bjb2RlIFJlc3VsdFNldH0gLiBNb2RpZmljYXRpb24gb2YgZXhpc3RpbmcgZGF0YSBpbnZvbHZlcyBtb3ZpbmcgdGhlCisgKiBjdXJzb3IgdG8gdGhlIHJvdyB3aGljaCBuZWVkcyBtb2RpZmljYXRpb24gYW5kIHRoZW4gdXNpbmcgdGhlIHVwZGF0ZSBtZXRob2RzCisgKiB0byBtb2RpZnkgdGhlIGRhdGEsIGZvbGxvd2VkIGJ5IGNhbGxpbmcgdGhlIHtAY29kZSBSZXN1bHRTZXQudXBkYXRlUm93fQorICogbWV0aG9kLiBGb3IgaW5zZXJ0aW9uIG9mIG5ldyByb3dzLCB0aGUgY3Vyc29yIGlzIGZpcnN0IG1vdmVkIHRvIGEgc3BlY2lhbCByb3cKKyAqIGNhbGxlZCB0aGUgPGk+SW5zZXJ0IFJvdzwvaT4sIGRhdGEgaXMgYWRkZWQgdXNpbmcgdGhlIHVwZGF0ZSBtZXRob2RzLAorICogZm9sbG93ZWQgYnkgY2FsbGluZyB0aGUge0Bjb2RlIFJlc3VsdFNldC5pbnNlcnRSb3d9IG1ldGhvZC4KKyAqIDxwPgorICogQSB7QGNvZGUgUmVzdWx0U2V0fSBpcyBjbG9zZWQgaWYgdGhlIHN0YXRlbWVudCB3aGljaCBnZW5lcmF0ZWQgaXQgY2xvc2VzLCB0aGUKKyAqIHN0YXRlbWVudCBpcyBleGVjdXRlZCBhZ2Fpbiwgb3IgdGhlIHNhbWUgc3RhdGVtZW50J3MgbmV4dCB7QGNvZGUgUmVzdWx0U2V0fQorICogaXMgcmV0cmlldmVkIChpZiB0aGUgc3RhdGVtZW50IHJldHVybmVkIG9mIG11bHRpcGxlIHJlc3VsdHMpLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFJlc3VsdFNldCBleHRlbmRzIFdyYXBwZXIsIEF1dG9DbG9zZWFibGUgeworCisgICAgLyoqCisgICAgICogQSBjb25zdGFudCB1c2VkIHRvIGluZGljYXRlIHRoYXQgYSB7QGNvZGUgUmVzdWx0U2V0fSBvYmplY3QgbXVzdCBiZQorICAgICAqIGNsb3NlZCB3aGVuIHRoZSBtZXRob2Qge0Bjb2RlIENvbm5lY3Rpb24uY29tbWl0fSBpcyBpbnZva2VkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMT1NFX0NVUlNPUlNfQVRfQ09NTUlUID0gMjsKKworICAgIC8qKgorICAgICAqIEEgY29uc3RhbnQgdXNlZCB0byBpbmRpY2F0ZSB0aGF0IGEge0Bjb2RlIFJlc3VsdFNldH0gb2JqZWN0IG11c3Qgbm90IGJlCisgICAgICogY2xvc2VkIHdoZW4gdGhlIG1ldGhvZCB7QGNvZGUgQ29ubmVjdGlvbi5jb21taXR9IGlzIGludm9rZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSE9MRF9DVVJTT1JTX09WRVJfQ09NTUlUID0gMTsKKworICAgIC8qKgorICAgICAqIEEgY29uc3RhbnQgdXNlZCB0byBpbmRpY2F0ZSB0aGUgY29uY3VycmVuY3kgbW9kZSBmb3IgYSB7QGNvZGUgUmVzdWx0U2V0fQorICAgICAqIG9iamVjdCB0aGF0IGNhbm5vdCBiZSB1cGRhdGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTkNVUl9SRUFEX09OTFkgPSAxMDA3OworCisgICAgLyoqCisgICAgICogQSBjb25zdGFudCB1c2VkIHRvIGluZGljYXRlIHRoZSBjb25jdXJyZW5jeSBtb2RlIGZvciBhIHtAY29kZSBSZXN1bHRTZXR9CisgICAgICogb2JqZWN0IHRoYXQgY2FuIGJlIHVwZGF0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09OQ1VSX1VQREFUQUJMRSA9IDEwMDg7CisKKyAgICAvKioKKyAgICAgKiBBIGNvbnN0YW50IHVzZWQgdG8gaW5kaWNhdGUgcHJvY2Vzc2luZyBvZiB0aGUgcm93cyBvZiBhIHtAY29kZSBSZXN1bHRTZXR9CisgICAgICogaW4gdGhlIGZvcndhcmQgZGlyZWN0aW9uLCBmaXJzdCB0byBsYXN0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZFVENIX0ZPUldBUkQgPSAxMDAwOworCisgICAgLyoqCisgICAgICogQSBjb25zdGFudCB1c2VkIHRvIGluZGljYXRlIHByb2Nlc3Npbmcgb2YgdGhlIHJvd3Mgb2YgYSB7QGNvZGUgUmVzdWx0U2V0fQorICAgICAqIGluIHRoZSByZXZlcnNlIGRpcmVjdGlvbiwgbGFzdCB0byBmaXJzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGRVRDSF9SRVZFUlNFID0gMTAwMTsKKworICAgIC8qKgorICAgICAqIEEgY29uc3RhbnQgdXNlZCB0byBpbmRpY2F0ZSB0aGF0IHRoZSBvcmRlciBvZiBwcm9jZXNzaW5nIG9mIHRoZSByb3dzIG9mIGEKKyAgICAgKiB7QGNvZGUgUmVzdWx0U2V0fSBpcyB1bmtub3duLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZFVENIX1VOS05PV04gPSAxMDAyOworCisgICAgLyoqCisgICAgICogQSBjb25zdGFudCB1c2VkIHRvIGluZGljYXRlIGEge0Bjb2RlIFJlc3VsdFNldH0gb2JqZWN0IHdob3NlIGN1cnNvciBjYW4KKyAgICAgKiBvbmx5IG1vdmUgZm9yd2FyZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0ZPUldBUkRfT05MWSA9IDEwMDM7CisKKyAgICAvKioKKyAgICAgKiBBIGNvbnN0YW50IHVzZWQgdG8gaW5kaWNhdGUgYSB7QGNvZGUgUmVzdWx0U2V0fSBvYmplY3Qgd2hpY2ggaXMKKyAgICAgKiBzY3JvbGxhYmxlIGJ1dCBpcyBpbnNlbnNpdGl2ZSB0byBjaGFuZ2VzIG1hZGUgYnkgb3RoZXJzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfU0NST0xMX0lOU0VOU0lUSVZFID0gMTAwNDsKKworICAgIC8qKgorICAgICAqIEEgY29uc3RhbnQgdXNlZCB0byBpbmRpY2F0ZSBhIHtAY29kZSBSZXN1bHRTZXR9IG9iamVjdCB3aGljaCBpcworICAgICAqIHNjcm9sbGFibGUgYW5kIHNlbnNpdGl2ZSB0byBjaGFuZ2VzIG1hZGUgYnkgb3RoZXJzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfU0NST0xMX1NFTlNJVElWRSA9IDEwMDU7CisKKyAgICAvKioKKyAgICAgKiBNb3ZlcyB0aGUgY3Vyc29yIHRvIGEgc3BlY2lmaWVkIHJvdyBudW1iZXIgaW4gdGhlIHtAY29kZSBSZXN1bHRTZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIHJvdworICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSByb3cgc3RhcnRpbmcgYXQgaW5kZXggMS4gSW5kZXgge0Bjb2RlIC0xfQorICAgICAqICAgICAgICAgICAgcmV0dXJucyB0aGUgbGFzdCByb3cuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIG5ldyBjdXJzb3IgcG9zaXRpb24gaXMgb24gdGhlIHtAY29kZQorICAgICAqICAgICAgICAgUmVzdWx0U2V0fSwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYWJzb2x1dGUoaW50IHJvdykgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIE1vdmVzIHRoZSBjdXJzb3IgdG8gdGhlIGVuZCBvZiB0aGUge0Bjb2RlIFJlc3VsdFNldH0sIGFmdGVyIHRoZSBsYXN0IHJvdy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFmdGVyTGFzdCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBNb3ZlcyB0aGUgY3Vyc29yIHRvIHRoZSBzdGFydCBvZiB0aGUge0Bjb2RlIFJlc3VsdFNldH0sIGJlZm9yZSB0aGUgZmlyc3QKKyAgICAgKiByb3cuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBiZWZvcmVGaXJzdCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDYW5jZWxzIGFueSB1cGRhdGVzIG1hZGUgdG8gdGhlIGN1cnJlbnQgcm93IGluIHRoZSB7QGNvZGUgUmVzdWx0U2V0fS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNhbmNlbFJvd1VwZGF0ZXMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ2xlYXJzIGFsbCB3YXJuaW5ncyByZWxhdGVkIHRvIHRoaXMge0Bjb2RlIFJlc3VsdFNldH0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbGVhcldhcm5pbmdzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlbGVhc2VzIHRoaXMge0Bjb2RlIFJlc3VsdFNldH0ncyBkYXRhYmFzZSBhbmQgSkRCQyByZXNvdXJjZXMuIFlvdSBhcmUKKyAgICAgKiBzdHJvbmdseSBhZHZpc2VkIHRvIHVzZSB0aGlzIG1ldGhvZCByYXRoZXIgdGhhbiByZWx5aW5nIG9uIHRoZSByZWxlYXNlCisgICAgICogYmVpbmcgZG9uZSB3aGVuIHRoZSB7QGNvZGUgUmVzdWx0U2V0fSdzIGZpbmFsaXplIG1ldGhvZCBpcyBjYWxsZWQgZHVyaW5nCisgICAgICogZ2FyYmFnZSBjb2xsZWN0aW9uIHByb2Nlc3MuIE5vdGUgdGhhdCB0aGUge0Bjb2RlIGNsb3NlKCl9IG1ldGhvZCBtaWdodAorICAgICAqIHRha2Ugc29tZSB0aW1lIHRvIGNvbXBsZXRlIHNpbmNlIGl0IGlzIGRlcGVuZGVudCBvbiB0aGUgYmVoYXZpb3Igb2YgdGhlCisgICAgICogY29ubmVjdGlvbiB0byB0aGUgZGF0YWJhc2UgYW5kIHRoZSBkYXRhYmFzZSBpdHNlbGYuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZWxldGVzIHRoZSBjdXJyZW50IHJvdyBmcm9tIHRoZSB7QGNvZGUgUmVzdWx0U2V0fSBhbmQgZnJvbSB0aGUKKyAgICAgKiB1bmRlcmx5aW5nIGRhdGFiYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZGVsZXRlUm93KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGluZGV4IG51bWJlciBmb3IgYSBjb2x1bW4gaW4gdGhlIHtAY29kZSBSZXN1bHRTZXR9IGZyb20gdGhlCisgICAgICogcHJvdmlkZWQgY29sdW1uIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGNvbHVtbiBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIGNvbHVtbidzIGluZGV4IGluIHRoZSB7QGNvZGUgUmVzdWx0U2V0fSBpZGVudGlmaWVkIGJ5IGNvbHVtbgorICAgICAqICAgICAgICAgbmFtZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGZpbmRDb2x1bW4oU3RyaW5nIGNvbHVtbk5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTaGlmdHMgdGhlIGN1cnNvciBwb3NpdGlvbiB0byB0aGUgZmlyc3Qgcm93IGluIHRoZSB7QGNvZGUgUmVzdWx0U2V0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBwb3NpdGlvbiBpcyBpbiBhIGxlZ2l0aW1hdGUgcm93LCB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZhbHNlfSBpZiB0aGUge0Bjb2RlIFJlc3VsdFNldH0gY29udGFpbnMgbm8gcm93cy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBmaXJzdCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjb250ZW50IG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gaW5kZXggaW4gdGhlIGN1cnJlbnQgcm93CisgICAgICogb2YgdGhpcyB7QGNvZGUgUmVzdWx0U2V0fSBhcyBhIHtAY29kZSBqYXZhLnNxbC5BcnJheX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgY29sdW1uIHRvIHJlYWQKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIGphdmEuc3FsLkFycmF5fSB3aXRoIHRoZSBkYXRhIGZyb20gdGhlIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXJyYXkgZ2V0QXJyYXkoaW50IGNvbHVtbkluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGNvbHVtbiBuYW1lIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuQXJyYXl9LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gdG8gcmVhZC4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIGphdmEuc3FsLkFycmF5fSB3aXRoIHRoZSBkYXRhIGZyb20gdGhlIHNwZWNpZmllZCBjb2x1bW4uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIEFycmF5IGdldEFycmF5KFN0cmluZyBjb2xOYW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGNvbHVtbiBpbmRleCBhcyBhbiBBU0NJSQorICAgICAqIGNoYXJhY3RlciBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhbiB7QGNvZGUgSW5wdXRTdHJlYW19IHdpdGggdGhlIGRhdGEgZnJvbSB0aGUgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRBc2NpaVN0cmVhbShpbnQgY29sdW1uSW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIG5hbWUgYXMgYW4gQVNDSUkgY2hhcmFjdGVyCisgICAgICogc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbk5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gdG8gcmVhZAorICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIElucHV0U3RyZWFtfSB3aXRoIHRoZSBkYXRhIGZyb20gdGhlIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0QXNjaWlTdHJlYW0oU3RyaW5nIGNvbHVtbk5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIGluZGV4IGFzIGEge0Bjb2RlCisgICAgICogamF2YS5tYXRoLkJpZ0RlY2ltYWx9LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgQmlnRGVjaW1hbH0gd2l0aCB0aGUgdmFsdWUgb2YgdGhlIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbCBnZXRCaWdEZWNpbWFsKGludCBjb2x1bW5JbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gaW5kZXggYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLm1hdGguQmlnRGVjaW1hbH0uCisgICAgICoKKyAgICAgKiBAZGVwcmVjYXRlZCB1c2Uge0BsaW5rICNnZXRCaWdEZWNpbWFsKGludCl9IG9yCisgICAgICogICAgICAgICAgICAge0BsaW5rICNnZXRCaWdEZWNpbWFsKFN0cmluZyl9CisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEBwYXJhbSBzY2FsZQorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBkaWdpdHMgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIEJpZ0RlY2ltYWx9IHdpdGggdGhlIHZhbHVlIG9mIHRoZSBjb2x1bW4uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgQmlnRGVjaW1hbCBnZXRCaWdEZWNpbWFsKGludCBjb2x1bW5JbmRleCwgaW50IHNjYWxlKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gbmFtZSwgYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLm1hdGguQmlnRGVjaW1hbH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gYSBCaWdEZWNpbWFsIHdpdGggdmFsdWUgb2YgdGhlIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbCBnZXRCaWdEZWNpbWFsKFN0cmluZyBjb2x1bW5OYW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGNvbHVtbiBuYW1lLCBhcyBhIHtAY29kZQorICAgICAqIGphdmEubWF0aC5CaWdEZWNpbWFsfS4KKyAgICAgKgorICAgICAqIEBkZXByZWNhdGVkIHVzZSB7QGxpbmsgI2dldEJpZ0RlY2ltYWwoaW50KX0gb3IKKyAgICAgKiAgICAgICAgICAgICB7QGxpbmsgI2dldEJpZ0RlY2ltYWwoU3RyaW5nKX0KKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEBwYXJhbSBzY2FsZQorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBkaWdpdHMgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQKKyAgICAgKiBAcmV0dXJuIGEgQmlnRGVjaW1hbCB3aXRoIHZhbHVlIG9mIHRoZSBjb2x1bW4uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgQmlnRGVjaW1hbCBnZXRCaWdEZWNpbWFsKFN0cmluZyBjb2x1bW5OYW1lLCBpbnQgc2NhbGUpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGNvbHVtbiBpbmRleCBhcyBhIGJpbmFyeQorICAgICAqIHN0cmVhbS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgdXNlZCB0byByZWFkIHtAY29kZSBMT05HVkFSQklOQVJZfSB2YWx1ZXMuIEFsbCBvZiB0aGUKKyAgICAgKiBkYXRhIGluIHRoZSB7QGNvZGUgSW5wdXRTdHJlYW19IHNob3VsZCBiZSByZWFkIGJlZm9yZSBnZXR0aW5nIGRhdGEgZnJvbQorICAgICAqIGFueSBvdGhlciBjb2x1bW4uIEEgZnVydGhlciBjYWxsIHRvIGEgZ2V0dGVyIG1ldGhvZCB3aWxsIGltcGxpY2l0bHkgY2xvc2UKKyAgICAgKiB0aGUge0Bjb2RlIElucHV0U3RyZWFtfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gcmVhZC4KKyAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBJbnB1dFN0cmVhbX0gd2l0aCB0aGUgZGF0YSBmcm9tIHRoZSBjb2x1bW4uIElmIHRoZQorICAgICAqICAgICAgICAgY29sdW1uIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0sIHtAY29kZSBudWxsfSBpcyByZXR1cm5lZC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0QmluYXJ5U3RyZWFtKGludCBjb2x1bW5JbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gbmFtZSBhcyBhIGJpbmFyeSBzdHJlYW0uCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gcmVhZCB7QGNvZGUgTE9OR1ZBUkJJTkFSWX0gdmFsdWVzLiBBbGwgb2YgdGhlCisgICAgICogZGF0YSBpbiB0aGUge0Bjb2RlIElucHV0U3RyZWFtfSBzaG91bGQgYmUgcmVhZCBiZWZvcmUgZ2V0dGluZyBkYXRhIGZyb20KKyAgICAgKiBhbnkgb3RoZXIgY29sdW1uLiBBIGZ1cnRoZXIgY2FsbCB0byBhIGdldHRlciBtZXRob2Qgd2lsbCBpbXBsaWNpdGx5IGNsb3NlCisgICAgICogdGhlIHtAY29kZSBJbnB1dFN0cmVhbX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIElucHV0U3RyZWFtfSB3aXRoIHRoZSBkYXRhIGZyb20gdGhlIGNvbHVtbiBpZiB0aGUKKyAgICAgKiAgICAgICAgIGNvbHVtbiB2YWx1ZSBpcyBTUUwge0Bjb2RlIE5VTEx9LCB7QGNvZGUgbnVsbH0gaXMgcmV0dXJuZWQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldEJpbmFyeVN0cmVhbShTdHJpbmcgY29sdW1uTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gaW5kZXggYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5CbG9ifSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhIHtAY29kZSBqYXZhLnNxbC5CbG9ifSB3aXRoIHRoZSB2YWx1ZSBvZiB0aGUgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBCbG9iIGdldEJsb2IoaW50IGNvbHVtbkluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGNvbHVtbiBuYW1lLCBhcyBhIHtAY29kZQorICAgICAqIGphdmEuc3FsLkJsb2J9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5OYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhIHtAY29kZSBqYXZhLnNxbC5CbG9ifSB3aXRoIHRoZSB2YWx1ZSBvZiB0aGUgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBCbG9iIGdldEJsb2IoU3RyaW5nIGNvbHVtbk5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIGluZGV4IGFzIGEge0Bjb2RlIGJvb2xlYW59CisgICAgICogLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgYm9vbGVhbn0gdmFsdWUgZnJvbSB0aGUgY29sdW1uLiBJZiB0aGUgY29sdW1uIGlzIFNRTAorICAgICAqICAgICAgICAge0Bjb2RlIE5VTEx9LCB7QGNvZGUgZmFsc2V9IGlzIHJldHVybmVkLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldEJvb2xlYW4oaW50IGNvbHVtbkluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGNvbHVtbiBuYW1lLCBhcyBhIHtAY29kZSBib29sZWFufQorICAgICAqIC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5OYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhIHtAY29kZSBib29sZWFufSB2YWx1ZSBmcm9tIHRoZSBjb2x1bW4uIElmIHRoZSBjb2x1bW4gaXMgU1FMCisgICAgICogICAgICAgICB7QGNvZGUgTlVMTH0sIHtAY29kZSBmYWxzZX0gaXMgcmV0dXJuZWQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0Qm9vbGVhbihTdHJpbmcgY29sdW1uTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gaW5kZXggYXMgYSB7QGNvZGUgYnl0ZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhIHtAY29kZSBieXRlfSBlcXVhbCB0byB0aGUgdmFsdWUgb2YgdGhlIGNvbHVtbi4gMCBpZiB0aGUgdmFsdWUKKyAgICAgKiAgICAgICAgIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIGJ5dGUgZ2V0Qnl0ZShpbnQgY29sdW1uSW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIG5hbWUgYXMgYSB7QGNvZGUgYnl0ZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgYnl0ZX0gZXF1YWwgdG8gdGhlIHZhbHVlIG9mIHRoZSBjb2x1bW4uIDAgaWYgdGhlIHZhbHVlCisgICAgICogICAgICAgICBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBieXRlIGdldEJ5dGUoU3RyaW5nIGNvbHVtbk5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIGluZGV4IGFzIGEgYnl0ZSBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gcmVhZC4KKyAgICAgKiBAcmV0dXJuIGEgYnl0ZSBhcnJheSBjb250YWluaW5nIHRoZSB2YWx1ZSBvZiB0aGUgY29sdW1uLiB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiAgICAgICAgIHRoZSBjb2x1bW4gY29udGFpbnMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEJ5dGVzKGludCBjb2x1bW5JbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gbmFtZSBhcyBhIGJ5dGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gYSBieXRlIGFycmF5IGNvbnRhaW5pbmcgdGhlIHZhbHVlIG9mIHRoZSBjb2x1bW4uIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAgdGhlIGNvbHVtbiBjb250YWlucyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0Qnl0ZXMoU3RyaW5nIGNvbHVtbk5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIGluZGV4IGFzIGEge0Bjb2RlCisgICAgICogamF2YS5pby5SZWFkZXJ9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gcmVhZC4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFJlYWRlcn0gaG9sZGluZyB0aGUgdmFsdWUgb2YgdGhlIGNvbHVtbi4ge0Bjb2RlIG51bGx9IGlmCisgICAgICogICAgICAgICB0aGUgY29sdW1uIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICogQHNlZSBqYXZhLmlvLlJlYWRlcgorICAgICAqLworICAgIHB1YmxpYyBSZWFkZXIgZ2V0Q2hhcmFjdGVyU3RyZWFtKGludCBjb2x1bW5JbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gbmFtZSBhcyBhIHtAY29kZQorICAgICAqIGphdmEuaW8uUmVhZGVyfSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgUmVhZGVyfSBob2xkaW5nIHRoZSB2YWx1ZSBvZiB0aGUgY29sdW1uLiB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiAgICAgICAgIHRoZSBjb2x1bW4gdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVhZGVyIGdldENoYXJhY3RlclN0cmVhbShTdHJpbmcgY29sdW1uTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gaW5kZXggYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5DbG9ifS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gcmVhZC4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIENsb2J9IG9iamVjdCByZXByZXNlbnRpbmcgdGhlIHZhbHVlIGluIHRoZSBjb2x1bW4uCisgICAgICogICAgICAgICB7QGNvZGUgbnVsbH0gaWYgdGhlIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIENsb2IgZ2V0Q2xvYihpbnQgY29sdW1uSW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIG5hbWUgYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5DbG9ifS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2xOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhIHtAY29kZSBDbG9ifSBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSB2YWx1ZSBpbiB0aGUgY29sdW1uLgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlmIHRoZSB2YWx1ZSBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBDbG9iIGdldENsb2IoU3RyaW5nIGNvbE5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjb25jdXJyZW5jeSBtb2RlIG9mIHRoaXMge0Bjb2RlIFJlc3VsdFNldH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb25jdXJyZW5jeSBtb2RlIC0gb25lIG9mOiB7QGNvZGUgUmVzdWx0U2V0LkNPTkNVUl9SRUFEX09OTFl9CisgICAgICogICAgICAgICAsIHtAY29kZSBSZXN1bHRTZXQuQ09OQ1VSX1VQREFUQUJMRX0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRDb25jdXJyZW5jeSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBuYW1lIG9mIHRoZSBTUUwgY3Vyc29yIG9mIHRoaXMge0Bjb2RlIFJlc3VsdFNldH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBTUUwgY3Vyc29yIG5hbWUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDdXJzb3JOYW1lKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gaW5kZXggYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5EYXRlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gcmVhZC4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIGphdmEuc3FsLkRhdGV9IG1hdGNoaW5nIHRoZSBjb2x1bW4gdmFsdWUuIHtAY29kZSBudWxsfQorICAgICAqICAgICAgICAgaWYgdGhlIGNvbHVtbiBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBEYXRlIGdldERhdGUoaW50IGNvbHVtbkluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGNvbHVtbiBpbmRleCBhcyBhIHtAY29kZQorICAgICAqIGphdmEuc3FsLkRhdGV9LiBUaGlzIG1ldGhvZCB1c2VzIGEgc3VwcGxpZWQgY2FsZW5kYXIgdG8gY29tcHV0ZSB0aGUgRGF0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gcmVhZC4KKyAgICAgKiBAcGFyYW0gY2FsCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBqYXZhLnV0aWwuQ2FsZW5kYXJ9IHRvIHVzZSBpbiBjb25zdHJ1Y3RpbmcgdGhlIERhdGUuCisgICAgICogQHJldHVybiBhIHtAY29kZSBqYXZhLnNxbC5EYXRlfSBtYXRjaGluZyB0aGUgY29sdW1uIHZhbHVlLiB7QGNvZGUgbnVsbH0KKyAgICAgKiAgICAgICAgIGlmIHRoZSBjb2x1bW4gaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0ZSBnZXREYXRlKGludCBjb2x1bW5JbmRleCwgQ2FsZW5kYXIgY2FsKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGNvbHVtbiBuYW1lIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuRGF0ZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgamF2YS5zcWwuRGF0ZX0gbWF0Y2hpbmcgdGhlIGNvbHVtbiB2YWx1ZS4ge0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpZiB0aGUgY29sdW1uIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0RGF0ZShTdHJpbmcgY29sdW1uTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gbmFtZSwgYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5EYXRlfSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEBwYXJhbSBjYWwKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBqYXZhLnV0aWwuQ2FsZW5kYXJ9IHRvIHVzZSBpbiBjb25zdHJ1Y3RpbmcgdGhlIERhdGUuCisgICAgICogQHJldHVybiBhIHtAY29kZSBqYXZhLnNxbC5EYXRlfSBtYXRjaGluZyB0aGUgY29sdW1uIHZhbHVlLiB7QGNvZGUgbnVsbH0KKyAgICAgKiAgICAgICAgIGlmIHRoZSBjb2x1bW4gaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0ZSBnZXREYXRlKFN0cmluZyBjb2x1bW5OYW1lLCBDYWxlbmRhciBjYWwpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIGluZGV4IGFzIGEge0Bjb2RlIGRvdWJsZX0KKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gcmVhZC4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIGRvdWJsZX0gZXF1YWwgdG8gdGhlIGNvbHVtbiB2YWx1ZS4ge0Bjb2RlIDAuMH0gaWYgdGhlCisgICAgICogICAgICAgICBjb2x1bW4gaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIGdldERvdWJsZShpbnQgY29sdW1uSW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIG5hbWUgYXMgYSB7QGNvZGUgZG91YmxlfQorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbk5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gdG8gcmVhZC4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIGRvdWJsZX0gZXF1YWwgdG8gdGhlIGNvbHVtbiB2YWx1ZS4ge0Bjb2RlIDAuMH0gaWYgdGhlCisgICAgICogICAgICAgICBjb2x1bW4gaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIGdldERvdWJsZShTdHJpbmcgY29sdW1uTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRpcmVjdGlvbiBpbiB3aGljaCByb3dzIGFyZSBmZXRjaGVkIGZvciB0aGlzIHtAY29kZSBSZXN1bHRTZXR9CisgICAgICogb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZmV0Y2ggZGlyZWN0aW9uLiBXaWxsIGJlIG9uZSBvZjoKKyAgICAgKiAgICAgICAgIDx1bD4KKyAgICAgKiAgICAgICAgIDxsaT5SZXN1bHRTZXQuRkVUQ0hfRk9SV0FSRDwvbGk+PGxpPlJlc3VsdFNldC5GRVRDSF9SRVZFUlNFPC9saT4KKyAgICAgKiAgICAgICAgIDxsaT5SZXN1bHRTZXQuRkVUQ0hfVU5LTk9XTjwvbGk+CisgICAgICogICAgICAgICA8L3VsPgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RmV0Y2hEaXJlY3Rpb24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZmV0Y2ggc2l6ZSAoaW4gbnVtYmVyIG9mIHJvd3MpIGZvciB0aGlzIHtAY29kZSBSZXN1bHRTZXR9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZmV0Y2ggc2l6ZSBhcyBhbiBpbnQKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEZldGNoU2l6ZSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIGluZGV4IGFzIGEge0Bjb2RlIGZsb2F0fQorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgZmxvYXR9IGVxdWFsIHRvIHRoZSBjb2x1bW4gdmFsdWUuIHtAY29kZSAwLjB9IGlmIHRoZQorICAgICAqICAgICAgICAgY29sdW1uIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIGZsb2F0IGdldEZsb2F0KGludCBjb2x1bW5JbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gbmFtZSBhcyBhIHtAY29kZSBmbG9hdH0KKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5OYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhIHtAY29kZSBmbG9hdH0gZXF1YWwgdG8gdGhlIGNvbHVtbiB2YWx1ZS4ge0Bjb2RlIDAuMH0gaWYgdGhlCisgICAgICogICAgICAgICBjb2x1bW4gaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgZ2V0RmxvYXQoU3RyaW5nIGNvbHVtbk5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIGluZGV4IGFzIGFuIHtAY29kZSBpbnR9CisgICAgICogdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhbiB7QGNvZGUgaW50fSBlcXVhbCB0byB0aGUgY29sdW1uIHZhbHVlLiB7QGNvZGUgMH0gaWYgdGhlCisgICAgICogICAgICAgICBjb2x1bW4gaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEludChpbnQgY29sdW1uSW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIG5hbWUsIGFzIGFuIHtAY29kZSBpbnR9CisgICAgICogdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIGludH0gZXF1YWwgdG8gdGhlIGNvbHVtbiB2YWx1ZS4ge0Bjb2RlIDB9IGlmIHRoZQorICAgICAqICAgICAgICAgY29sdW1uIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRJbnQoU3RyaW5nIGNvbHVtbk5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIGluZGV4IGFzIGEge0Bjb2RlIGxvbmd9CisgICAgICogdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhIHtAY29kZSBsb25nfSBlcXVhbCB0byB0aGUgY29sdW1uIHZhbHVlLiB7QGNvZGUgMH0gaWYgdGhlCisgICAgICogICAgICAgICBjb2x1bW4gaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRMb25nKGludCBjb2x1bW5JbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gbmFtZSwgYXMgYSB7QGNvZGUgbG9uZ30KKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5OYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhIHtAY29kZSBsb25nfSBlcXVhbCB0byB0aGUgY29sdW1uIHZhbHVlLiB7QGNvZGUgMH0gaWYgdGhlCisgICAgICogICAgICAgICBjb2x1bW4gaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRMb25nKFN0cmluZyBjb2x1bW5OYW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWV0YWRhdGEgZm9yIHRoaXMge0Bjb2RlIFJlc3VsdFNldH0uIFRoaXMgZGVmaW5lcyB0aGUgbnVtYmVyLAorICAgICAqIHR5cGVzIGFuZCBwcm9wZXJ0aWVzIG9mIHRoZSBjb2x1bW5zIGluIHRoZSB7QGNvZGUgUmVzdWx0U2V0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgUmVzdWx0U2V0TWV0YURhdGF9IG9iamVjdCB3aXRoIGluZm9ybWF0aW9uIGFib3V0IHRoaXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBSZXN1bHRTZXR9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBSZXN1bHRTZXRNZXRhRGF0YSBnZXRNZXRhRGF0YSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBjb2x1bW4gYXMgYSBKYXZhIHtAY29kZSBPYmplY3R9LiBUaGUgdHlwZQorICAgICAqIG9mIHRoZSByZXR1cm5lZCBvYmplY3Qgd2lsbCBiZSB0aGUgZGVmYXVsdCBhY2NvcmRpbmcgdG8gdGhlIGNvbHVtbidzIFNRTAorICAgICAqIHR5cGUsIGZvbGxvd2luZyB0aGUgSkRCQyBzcGVjaWZpY2F0aW9uIGZvciBidWlsdC1pbiB0eXBlcy4KKyAgICAgKiA8cD4KKyAgICAgKiBGb3IgU1FMIFVzZXIgRGVmaW5lZCBUeXBlcywgaWYgYSBjb2x1bW4gdmFsdWUgaXMgU3RydWN0dXJlZCBvciBEaXN0aW5jdCwKKyAgICAgKiB0aGlzIG1ldGhvZCBiZWhhdmVzIHRoZSBzYW1lIGFzIGEgY2FsbCB0bzoge0Bjb2RlCisgICAgICogZ2V0T2JqZWN0KGNvbHVtbkluZGV4LHRoaXMuZ2V0U3RhdGVtZW50KCkuZ2V0Q29ubmVjdGlvbigpLmdldFR5cGVNYXAoKSl9CisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhbiB7QGNvZGUgT2JqZWN0fSBjb250YWluaW5nIHRoZSB2YWx1ZSBvZiB0aGUgY29sdW1uLiB7QGNvZGUKKyAgICAgKiAgICAgICAgIG51bGx9IGlmIHRoZSBjb2x1bW4gdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldE9iamVjdChpbnQgY29sdW1uSW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIGluZGV4IGFzIGEgSmF2YSB7QGNvZGUKKyAgICAgKiBPYmplY3R9LgorICAgICAqIDxwPgorICAgICAqIFRoZSB0eXBlIG9mIHRoZSBKYXZhIG9iamVjdCB3aWxsIGJlIGRldGVybWluZWQgYnkgdGhlIHN1cHBsaWVkIE1hcCB0bworICAgICAqIHBlcmZvcm0gdGhlIG1hcHBpbmcgb2YgU1FMIHtAY29kZSBTdHJ1Y3R9IG9yIERpc3RpbmN0IHR5cGVzIGludG8gSmF2YQorICAgICAqIG9iamVjdHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHBhcmFtIG1hcAorICAgICAqICAgICAgICAgICAgYSB7QGNvZGUgamF2YS51dGlsLk1hcH0gY29udGFpbmluZyBhIG1hcHBpbmcgZnJvbSBTUUwgVHlwZQorICAgICAqICAgICAgICAgICAgbmFtZXMgdG8gSmF2YSBjbGFzc2VzLgorICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIE9iamVjdH0gY29udGFpbmluZyB0aGUgdmFsdWUgb2YgdGhlIGNvbHVtbi4ge0Bjb2RlCisgICAgICogICAgICAgICBudWxsfSBpZiB0aGUgY29sdW1uIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRPYmplY3QoaW50IGNvbHVtbkluZGV4LCBNYXA8U3RyaW5nLCBDbGFzczw/Pj4gbWFwKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIGNvbHVtbiBhcyBhIEphdmEge0Bjb2RlIE9iamVjdH0uIFRoZSB0eXBlCisgICAgICogb2YgdGhlIHJldHVybmVkIG9iamVjdCB3aWxsIGJlIHRoZSBkZWZhdWx0IGFjY29yZGluZyB0byB0aGUgY29sdW1uJ3MgU1FMCisgICAgICogdHlwZSwgZm9sbG93aW5nIHRoZSBKREJDIHNwZWNpZmljYXRpb24gZm9yIGJ1aWx0LWluIHR5cGVzLgorICAgICAqIDxwPgorICAgICAqIEZvciBTUUwgVXNlciBEZWZpbmVkIFR5cGVzLCBpZiBhIGNvbHVtbiB2YWx1ZSBpcyBzdHJ1Y3R1cmVkIG9yIGRpc3RpbmN0LAorICAgICAqIHRoaXMgbWV0aG9kIGJlaGF2ZXMgdGhlIHNhbWUgYXMgYSBjYWxsIHRvOiB7QGNvZGUKKyAgICAgKiBnZXRPYmplY3QoY29sdW1uSW5kZXgsdGhpcy5nZXRTdGF0ZW1lbnQoKS5nZXRDb25uZWN0aW9uKCkuZ2V0VHlwZU1hcCgpKX0KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5OYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhbiB7QGNvZGUgT2JqZWN0fSBjb250YWluaW5nIHRoZSB2YWx1ZSBvZiB0aGUgY29sdW1uLiB7QGNvZGUKKyAgICAgKiAgICAgICAgIG51bGx9IGlmIHRoZSBjb2x1bW4gdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldE9iamVjdChTdHJpbmcgY29sdW1uTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gbmFtZSBhcyBhIEphdmEge0Bjb2RlCisgICAgICogT2JqZWN0fS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgdHlwZSBvZiB0aGUgSmF2YSBvYmplY3Qgd2lsbCBiZSBkZXRlcm1pbmVkIGJ5IHRoZSBzdXBwbGllZCBNYXAgdG8KKyAgICAgKiBwZXJmb3JtIHRoZSBtYXBwaW5nIG9mIFNRTCBTdHJ1Y3Qgb3IgRGlzdGluY3QgdHlwZXMgaW50byBKYXZhIG9iamVjdHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEBwYXJhbSBtYXAKKyAgICAgKiAgICAgICAgICAgIGEge0Bjb2RlIGphdmEudXRpbC5NYXB9IGNvbnRhaW5pbmcgYSBtYXBwaW5nIGZyb20gU1FMIFR5cGUgbmFtZXMgdG8KKyAgICAgKiAgICAgICAgICAgIEphdmEgY2xhc3Nlcy4KKyAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBPYmplY3R9IGNvbnRhaW5pbmcgdGhlIHZhbHVlIG9mIHRoZSBjb2x1bW4uIHtAY29kZQorICAgICAqICAgICAgICAgbnVsbH0gaWYgdGhlIGNvbHVtbiB2YWx1ZSBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0T2JqZWN0KFN0cmluZyBjb2x1bW5OYW1lLCBNYXA8U3RyaW5nLCBDbGFzczw/Pj4gbWFwKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gaW5kZXggYXMgYSBKYXZhIHtAY29kZQorICAgICAqIGphdmEuc3FsLlJlZn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhIFJlZiByZXByZXNlbnRpbmcgdGhlIHZhbHVlIG9mIHRoZSBTUUwgUkVGIGluIHRoZSBjb2x1bW4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVmIGdldFJlZihpbnQgY29sdW1uSW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIG5hbWUgYXMgYSBKYXZhIHtAY29kZQorICAgICAqIGphdmEuc3FsLlJlZn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gYSBSZWYgcmVwcmVzZW50aW5nIHRoZSB2YWx1ZSBvZiB0aGUgU1FMIHtAY29kZSBSRUZ9IGluIHRoZSBjb2x1bW4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVmIGdldFJlZihTdHJpbmcgY29sTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG51bWJlciBvZiB0aGUgY3VycmVudCByb3cgaW4gdGhlIHtAY29kZSBSZXN1bHRTZXR9LiBSb3cgbnVtYmVycworICAgICAqIHN0YXJ0IGF0IDEgZm9yIHRoZSBmaXJzdCByb3cuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBudW1iZXIgb2YgdGhlIGN1cnJlbnQgcm93LiB7QGNvZGUgMH0gaXMgcmV0dXJuZWQgaWYKKyAgICAgKiAgICAgICAgIHRoZXJlIGlzIG5vIGN1cnJlbnQgcm93LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Um93KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gaW5kZXggYXMgYSBzaG9ydCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gcmVhZC4KKyAgICAgKiBAcmV0dXJuIGEgc2hvcnQgdmFsdWUgZXF1YWwgdG8gdGhlIHZhbHVlIG9mIHRoZSBjb2x1bW4uIHtAY29kZSAwfSBpZgorICAgICAqICAgICAgICAgdGhlIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHNob3J0IGdldFNob3J0KGludCBjb2x1bW5JbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gbmFtZSwgYXMgYSBzaG9ydCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5OYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhIHNob3J0IHZhbHVlIGVxdWFsIHRvIHRoZSB2YWx1ZSBvZiB0aGUgY29sdW1uLiB7QGNvZGUgMH0gaWYKKyAgICAgKiAgICAgICAgIHRoZSB2YWx1ZSBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBzaG9ydCBnZXRTaG9ydChTdHJpbmcgY29sdW1uTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHN0YXRlbWVudCB0aGF0IHByb2R1Y2VkIHRoaXMge0Bjb2RlIFJlc3VsdFNldH0uIElmIHRoZSB7QGNvZGUKKyAgICAgKiBSZXN1bHRTZXR9IHdhcyBub3QgY3JlYXRlZCBieSBhIHN0YXRlbWVudCAoaS5lLiBiZWNhdXNlIGl0IHdhcyByZXR1cm5lZAorICAgICAqIGZyb20gb25lIG9mIHRoZSB7QGxpbmsgRGF0YWJhc2VNZXRhRGF0YX0gbWV0aG9kcyksIHtAY29kZSBudWxsfSBpcworICAgICAqIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgU3RhdGVtZW50IHdoaWNoIHByb2R1Y2VkIHRoaXMge0Bjb2RlIFJlc3VsdFNldH0sIG9yIHtAY29kZQorICAgICAqICAgICAgICAgbnVsbH0gaWYgdGhlIHtAY29kZSBSZXN1bHRTZXR9IHdhcyBub3QgY3JlYXRlZCBieSBhIFN0YXRlbWVudC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RhdGVtZW50IGdldFN0YXRlbWVudCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIGluZGV4IGFzIGEgU3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gdGhlIFN0cmluZyByZXByZXNlbnRpbmcgdGhlIHZhbHVlIG9mIHRoZSBjb2x1bW4sIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAgdGhlIGNvbHVtbiBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nKGludCBjb2x1bW5JbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gbmFtZSwgYXMgYSBTdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gdGhlIFN0cmluZyByZXByZXNlbnRpbmcgdGhlIHZhbHVlIG9mIHRoZSBjb2x1bW4sIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAgdGhlIGNvbHVtbiBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nKFN0cmluZyBjb2x1bW5OYW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGNvbHVtbiBpbmRleCBhcyBhIHtAY29kZQorICAgICAqIGphdmEuc3FsLlRpbWV9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gYSBUaW1lIHJlcHJlc2VudGluZyB0aGUgY29sdW1uIHZhbHVlLCB7QGNvZGUgbnVsbH0gaWYgdGhlIGNvbHVtbgorICAgICAqICAgICAgICAgdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGltZSBnZXRUaW1lKGludCBjb2x1bW5JbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gaW5kZXggYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5UaW1lfSB2YWx1ZS4gVGhlIHN1cHBsaWVkIHtAY29kZSBDYWxlbmRhcn0gaXMgdXNlZCB0bworICAgICAqIG1hcCB0aGUgU1FMIHtAY29kZSBUaW1lfSB2YWx1ZSB0byBhIEphdmEgVGltZSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gcmVhZC4KKyAgICAgKiBAcGFyYW0gY2FsCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBDYWxlbmRhcn0gdG8gdXNlIGluIGNyZWF0aW5nIHRoZSBKYXZhIFRpbWUgdmFsdWUuCisgICAgICogQHJldHVybiBhIFRpbWUgcmVwcmVzZW50aW5nIHRoZSBjb2x1bW4gdmFsdWUsIHtAY29kZSBudWxsfSBpZiB0aGUgY29sdW1uCisgICAgICogICAgICAgICB2YWx1ZSBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBUaW1lIGdldFRpbWUoaW50IGNvbHVtbkluZGV4LCBDYWxlbmRhciBjYWwpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIG5hbWUsIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuVGltZX0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gdGhlIGNvbHVtbiB2YWx1ZSwge0Bjb2RlIG51bGx9IGlmIHRoZSBjb2x1bW4gdmFsdWUgaXMgU1FMIHtAY29kZQorICAgICAqICAgICAgICAgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIFRpbWUgZ2V0VGltZShTdHJpbmcgY29sdW1uTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gaW5kZXgsIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuVGltZX0gdmFsdWUuIFRoZSBzdXBwbGllZCB7QGNvZGUgQ2FsZW5kYXJ9IGlzIHVzZWQgdG8KKyAgICAgKiBtYXAgdGhlIFNRTCB7QGNvZGUgVGltZX0gdmFsdWUgdG8gYSBKYXZhIFRpbWUgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEBwYXJhbSBjYWwKKyAgICAgKiAgICAgICAgICAgIGEge0Bjb2RlIENhbGVuZGFyfSB0byB1c2UgaW4gY3JlYXRpbmcgdGhlIEphdmEgdGltZSB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIGEgVGltZSByZXByZXNlbnRpbmcgdGhlIGNvbHVtbiB2YWx1ZSwge0Bjb2RlIG51bGx9IGlmIHRoZSBjb2x1bW4KKyAgICAgKiAgICAgICAgIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIFRpbWUgZ2V0VGltZShTdHJpbmcgY29sdW1uTmFtZSwgQ2FsZW5kYXIgY2FsKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGNvbHVtbiBpbmRleCBhcyBhIHtAY29kZQorICAgICAqIGphdmEuc3FsLlRpbWVzdGFtcH0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhIHRpbWVzdGFtcCByZXByZXNlbnRpbmcgdGhlIGNvbHVtbiB2YWx1ZSwge0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqICAgICAgICAgY29sdW1uIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIFRpbWVzdGFtcCBnZXRUaW1lc3RhbXAoaW50IGNvbHVtbkluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGNvbHVtbiBpbmRleCwgYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5UaW1lc3RhbXB9IHZhbHVlLiBUaGUgc3VwcGxpZWQgQ2FsZW5kYXIgaXMgdXNlZCB3aGVuIG1hcHBpbmcKKyAgICAgKiB0aGUgU1FMIHtAY29kZSBUaW1lc3RhbXB9IHZhbHVlIHRvIGEgSmF2YSB7QGNvZGUgVGltZXN0YW1wfSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gcmVhZC4KKyAgICAgKiBAcGFyYW0gY2FsCisgICAgICogICAgICAgICAgICBDYWxlbmRhciB0byB1c2UgaW4gY3JlYXRpbmcgdGhlIEphdmEgdGltZXN0YW1wIHZhbHVlLgorICAgICAqIEByZXR1cm4gYSB0aW1lc3RhbXAgcmVwcmVzZW50aW5nIHRoZSBjb2x1bW4gdmFsdWUsIHtAY29kZSBudWxsfSBpZiB0aGUKKyAgICAgKiAgICAgICAgIGNvbHVtbiB2YWx1ZSBpcyBTUUwgTlVMTC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGltZXN0YW1wIGdldFRpbWVzdGFtcChpbnQgY29sdW1uSW5kZXgsIENhbGVuZGFyIGNhbCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIG5hbWUsIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuVGltZXN0YW1wfSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5OYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY29sdW1uIHRvIHJlYWQuCisgICAgICogQHJldHVybiBhIHRpbWVzdGFtcCByZXByZXNlbnRpbmcgdGhlIGNvbHVtbiB2YWx1ZSwge0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqICAgICAgICAgY29sdW1uIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIFRpbWVzdGFtcCBnZXRUaW1lc3RhbXAoU3RyaW5nIGNvbHVtbk5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIG5hbWUsIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuVGltZXN0YW1wfSB2YWx1ZS4gVGhlIHN1cHBsaWVkIENhbGVuZGFyIGlzIHVzZWQgd2hlbiBtYXBwaW5nCisgICAgICogdGhlIFNRTCB7QGNvZGUgVGltZXN0YW1wfSB2YWx1ZSB0byBhIEphdmEge0Bjb2RlIFRpbWVzdGFtcH0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEBwYXJhbSBjYWwKKyAgICAgKiAgICAgICAgICAgIENhbGVuZGFyIHRvIHVzZSBpbiBjcmVhdGluZyB0aGUgSmF2YSB7QGNvZGUgVGltZXN0YW1wfSB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIGEgdGltZXN0YW1wIHJlcHJlc2VudGluZyB0aGUgY29sdW1uIHZhbHVlLCB7QGNvZGUgbnVsbH0gaWYgdGhlCisgICAgICogICAgICAgICBjb2x1bW4gdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGltZXN0YW1wIGdldFRpbWVzdGFtcChTdHJpbmcgY29sdW1uTmFtZSwgQ2FsZW5kYXIgY2FsKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHR5cGUgb2YgdGhlIHtAY29kZSBSZXN1bHRTZXR9LgorICAgICAqCisgICAgICogQHJldHVybiBUaGUge0Bjb2RlIFJlc3VsdFNldH0gdHlwZSwgb25lIG9mOgorICAgICAqICAgICAgICAgPHVsPgorICAgICAqICAgICAgICAgPGxpPntAY29kZSBSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFl9PC9saT4gPGxpPntAY29kZQorICAgICAqICAgICAgICAgUmVzdWx0U2V0LlRZUEVfU0NST0xMX0lOU0VOU0lUSVZFfTwvbGk+IDxsaT57QGNvZGUKKyAgICAgKiAgICAgICAgIFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkV9PC9saT4KKyAgICAgKiAgICAgICAgIDwvdWw+CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VHlwZSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiB0aGUgY29sdW1uIGFzIGFuIHtAY29kZSBJbnB1dFN0cmVhbX0gb2YgdW5pY29kZQorICAgICAqIGNoYXJhY3RlcnMuCisgICAgICoKKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNnZXRDaGFyYWN0ZXJTdHJlYW19LgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gcmVhZC4KKyAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBJbnB1dFN0cmVhbX0gaG9sZGluZyB0aGUgdmFsdWUgb2YgdGhlIGNvbHVtbi4ge0Bjb2RlCisgICAgICogICAgICAgICBudWxsfSBpZiB0aGUgY29sdW1uIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0VW5pY29kZVN0cmVhbShpbnQgY29sdW1uSW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiB0aGUgY29sdW1uIGFzIGFuIHtAY29kZSBJbnB1dFN0cmVhbX0gb2YgVW5pY29kZQorICAgICAqIGNoYXJhY3RlcnMuCisgICAgICoKKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNnZXRDaGFyYWN0ZXJTdHJlYW19CisgICAgICogQHBhcmFtIGNvbHVtbk5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gdG8gcmVhZC4KKyAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBJbnB1dFN0cmVhbX0gaG9sZGluZyB0aGUgdmFsdWUgb2YgdGhlIGNvbHVtbi4ge0Bjb2RlCisgICAgICogICAgICAgICBudWxsfSBpZiB0aGUgY29sdW1uIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0VW5pY29kZVN0cmVhbShTdHJpbmcgY29sdW1uTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIGEgY29sdW1uIHNwZWNpZmllZCBieSBjb2x1bW4gaW5kZXggYXMgYSB7QGNvZGUKKyAgICAgKiBqYXZhLm5ldC5VUkx9LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gYSBVUkwuIHtAY29kZSBudWxsfSBpZiB0aGUgY29sdW1uIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIFVSTCBnZXRVUkwoaW50IGNvbHVtbkluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGNvbHVtbiBuYW1lIGFzIGEge0Bjb2RlCisgICAgICogamF2YS5uZXQuVVJMfSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byByZWFkLgorICAgICAqIEByZXR1cm4gdGhlIGNvbHVtbiB2YXVsZSBhcyBhIFVSTC4ge0Bjb2RlIG51bGx9IGlmIHRoZSBjb2x1bW4gdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMIGdldFVSTChTdHJpbmcgY29sdW1uTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGZpcnN0IHdhcm5pbmcgZ2VuZXJhdGVkIGJ5IGNhbGxzIG9uIHRoaXMge0Bjb2RlIFJlc3VsdFNldH0uCisgICAgICogU3Vic2VxdWVudCB3YXJuaW5ncyBvbiB0aGlzIHtAY29kZSBSZXN1bHRTZXR9IGFyZSBjaGFpbmVkIHRvIHRoZSBmaXJzdAorICAgICAqIG9uZS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgd2FybmluZ3MgYXJlIGNsZWFyZWQgd2hlbiBhIG5ldyBSb3cgaXMgcmVhZCBmcm9tIHRoZSB7QGNvZGUKKyAgICAgKiBSZXN1bHRTZXR9LiBUaGUgd2FybmluZ3MgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QgYXJlIG9ubHkgdGhlIHdhcm5pbmdzCisgICAgICogZ2VuZXJhdGVkIGJ5IHtAY29kZSBSZXN1bHRTZXR9IG1ldGhvZCBjYWxscyAtIHdhcm5pbmdzIGdlbmVyYXRlZCBieQorICAgICAqIFN0YXRlbWVudCBtZXRob2RzIGFyZSBoZWxkIGJ5IHRoZSBTdGF0ZW1lbnQuCisgICAgICogPHA+CisgICAgICogQW4ge0Bjb2RlIFNRTEV4Y2VwdGlvbn0gaXMgZ2VuZXJhdGVkIGlmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBvbiBhIGNsb3NlZAorICAgICAqIHtAY29kZSBSZXN1bHRTZXR9LgorICAgICAqCisgICAgICogQHJldHVybiBhbiBTUUxXYXJuaW5nIHdoaWNoIGlzIHRoZSBmaXJzdCB3YXJuaW5nIGZvciB0aGlzIHtAY29kZQorICAgICAqICAgICAgICAgUmVzdWx0U2V0fS4ge0Bjb2RlIG51bGx9IGlmIHRoZXJlIGFyZSBubyB3YXJuaW5ncy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMV2FybmluZyBnZXRXYXJuaW5ncygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnQgdGhlIGluc2VydCByb3cgaW50byB0aGUge0Bjb2RlIFJlc3VsdFNldH0gYW5kIGludG8gdGhlIHVuZGVybHlpbmcKKyAgICAgKiBkYXRhYmFzZS4gVGhlIGN1cnNvciBtdXN0IGJlIHNldCB0byB0aGUgSW5zZXJ0IFJvdyBiZWZvcmUgdGhpcyBtZXRob2QgaXMKKyAgICAgKiBpbnZva2VkLgorICAgICAqCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuIFBhcnRpY3VsYXIgY2FzZXMgaW5jbHVkZSB0aGUKKyAgICAgKiAgICAgICAgICAgICBjdXJzb3Igbm90IGJlaW5nIG9uIHRoZSBJbnNlcnQgUm93IG9yIGlmIGFueSBjb2x1bW5zIGluIHRoZQorICAgICAqICAgICAgICAgICAgIHJvdyBkbyBub3QgaGF2ZSBhIHZhbHVlIHdoZXJlIHRoZSBjb2x1bW4gaXMgZGVjbGFyZWQgYXMKKyAgICAgKiAgICAgICAgICAgICBub3QtbnVsbGFibGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgaW5zZXJ0Um93KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgaWYgdGhlIGN1cnNvciBpcyBhZnRlciB0aGUgbGFzdCByb3cgb2YgdGhlIHtAY29kZSBSZXN1bHRTZXR9LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGN1cnNvciBpcyBhZnRlciB0aGUgbGFzdCByb3cgaW4gdGhlIHtAY29kZQorICAgICAqICAgICAgICAgUmVzdWx0U2V0fSwge0Bjb2RlIGZhbHNlfSBpZiB0aGUgY3Vyc29yIGlzIGF0IGFueSBvdGhlciBwb3NpdGlvbgorICAgICAqICAgICAgICAgaW4gdGhlIHtAY29kZSBSZXN1bHRTZXR9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQWZ0ZXJMYXN0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgaWYgdGhlIGN1cnNvciBpcyBiZWZvcmUgdGhlIGZpcnN0IHJvdyBvZiB0aGUge0Bjb2RlIFJlc3VsdFNldH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgY3Vyc29yIGlzIGJlZm9yZSB0aGUgZmlyc3Qgcm93IGluIHRoZSB7QGNvZGUKKyAgICAgKiAgICAgICAgIFJlc3VsdFNldH0sIHtAY29kZSBmYWxzZX0gaWYgdGhlIGN1cnNvciBpcyBhdCBhbnkgb3RoZXIgcG9zaXRpb24KKyAgICAgKiAgICAgICAgIGluIHRoZSB7QGNvZGUgUmVzdWx0U2V0fS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0JlZm9yZUZpcnN0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgaWYgdGhlIGN1cnNvciBpcyBvbiB0aGUgZmlyc3Qgcm93IG9mIHRoZSB7QGNvZGUgUmVzdWx0U2V0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBjdXJzb3IgaXMgb24gdGhlIGZpcnN0IHJvdyBpbiB0aGUge0Bjb2RlCisgICAgICogICAgICAgICBSZXN1bHRTZXR9LCB7QGNvZGUgZmFsc2V9IGlmIHRoZSBjdXJzb3IgaXMgYXQgYW55IG90aGVyIHBvc2l0aW9uCisgICAgICogICAgICAgICBpbiB0aGUge0Bjb2RlIFJlc3VsdFNldH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNGaXJzdCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGlmIHRoZSBjdXJzb3IgaXMgb24gdGhlIGxhc3Qgcm93IG9mIHRoZSB7QGNvZGUgUmVzdWx0U2V0fQorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGN1cnNvciBpcyBvbiB0aGUgbGFzdCByb3cgaW4gdGhlIHtAY29kZQorICAgICAqICAgICAgICAgUmVzdWx0U2V0fSwge0Bjb2RlIGZhbHNlfSBpZiB0aGUgY3Vyc29yIGlzIGF0IGFueSBvdGhlciBwb3NpdGlvbgorICAgICAqICAgICAgICAgaW4gdGhlIHtAY29kZSBSZXN1bHRTZXR9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzTGFzdCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTaGlmdHMgdGhlIGN1cnNvciBwb3NpdGlvbiB0byB0aGUgbGFzdCByb3cgb2YgdGhlIHtAY29kZSBSZXN1bHRTZXR9LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIG5ldyBwb3NpdGlvbiBpcyBpbiBhIGxlZ2l0aW1hdGUgcm93LCB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZhbHNlfSBpZiB0aGUge0Bjb2RlIFJlc3VsdFNldH0gY29udGFpbnMgbm8gcm93cy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbGFzdCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBNb3ZlcyB0aGUgY3Vyc29yIHRvIHRoZSByZW1lbWJlcmVkIHBvc2l0aW9uLCBuYW1lbHkgdGhlCisgICAgICogcm93IHRoYXQgd2FzIHRoZSBjdXJyZW50IHJvdyBiZWZvcmUgYSBjYWxsIHRvIHtAY29kZSBtb3ZlVG9JbnNlcnRSb3d9LgorICAgICAqIFRoaXMgb25seSBhcHBsaWVzIGlmIHRoZSBjdXJzb3IgaXMgb24gdGhlIEluc2VydCBSb3cuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBtb3ZlVG9DdXJyZW50Um93KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIE1vdmVzIHRoZSBjdXJzb3IgcG9zaXRpb24gdG8gdGhlIEluc2VydCBSb3cuIFRoZSBjdXJyZW50IHBvc2l0aW9uIGlzCisgICAgICogcmVtZW1iZXJlZCBhbmQgdGhlIGN1cnNvciBpcyBwb3NpdGlvbmVkIGF0IHRoZSBJbnNlcnQgUm93LiBUaGUgY29sdW1ucyBpbgorICAgICAqIHRoZSBJbnNlcnQgUm93IHNob3VsZCBiZSBmaWxsZWQgaW4gd2l0aCB0aGUgYXBwcm9wcmlhdGUgdXBkYXRlIG1ldGhvZHMsCisgICAgICogYmVmb3JlIGNhbGxpbmcge0Bjb2RlIGluc2VydFJvd30gdG8gaW5zZXJ0IHRoZSBuZXcgcm93IGludG8gdGhlIGRhdGFiYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgbW92ZVRvSW5zZXJ0Um93KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNoaWZ0cyB0aGUgY3Vyc29yIHBvc2l0aW9uIGRvd24gb25lIHJvdyBpbiB0aGlzIHtAY29kZSBSZXN1bHRTZXR9IG9iamVjdC4KKyAgICAgKiA8cD4KKyAgICAgKiBBbnkgaW5wdXQgc3RyZWFtcyBhc3NvY2lhdGVkIHdpdGggdGhlIGN1cnJlbnQgcm93IGFyZSBjbG9zZWQgYW5kIGFueQorICAgICAqIHdhcm5pbmdzIGFyZSBjbGVhcmVkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHVwZGF0ZWQgY3Vyc29yIHBvc2l0aW9uIGlzIHBvaW50aW5nIHRvIGEKKyAgICAgKiAgICAgICAgIHZhbGlkIHJvdywge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UgKGkuZS4gd2hlbiB0aGUgY3Vyc29yIGlzIGFmdGVyCisgICAgICogICAgICAgICB0aGUgbGFzdCByb3cgaW4gdGhlIHtAY29kZSBSZXN1bHRTZXR9KS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBuZXh0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlbG9jYXRlcyB0aGUgY3Vyc29yIHBvc2l0aW9uIHRvIHRoZSBwcmVjZWRpbmcgcm93IGluIHRoaXMge0Bjb2RlCisgICAgICogUmVzdWx0U2V0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBuZXcgcG9zaXRpb24gaXMgaW4gYSBsZWdpdGltYXRlIHJvdywge0Bjb2RlCisgICAgICogICAgICAgICBmYWxzZX0gaWYgdGhlIGN1cnNvciBpcyBub3cgYmVmb3JlIHRoZSBmaXJzdCByb3cuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcHJldmlvdXMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVmcmVzaGVzIHRoZSBjdXJyZW50IHJvdyB3aXRoIGl0cyBtb3N0IHVwIHRvIGRhdGUgdmFsdWUgaW4gdGhlIGRhdGFiYXNlLgorICAgICAqIE11c3Qgbm90IGJlIGNhbGxlZCB3aGVuIHRoZSBjdXJzb3IgaXMgb24gdGhlIEluc2VydCBSb3cuCisgICAgICogPHA+CisgICAgICogSWYgYW55IGNvbHVtbnMgaW4gdGhlIGN1cnJlbnQgcm93IGhhdmUgYmVlbiB1cGRhdGVkIGJ1dCB0aGUge0Bjb2RlCisgICAgICogdXBkYXRlUm93fSBoYXMgbm90IGJlZW4gY2FsbGVkLCB0aGVuIHRoZSB1cGRhdGVzIGFyZSBsb3N0IHdoZW4gdGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4sIGluY2x1ZGluZyBpZiB0aGUgY3VycmVudCByb3cgaXMKKyAgICAgKiAgICAgICAgICAgICB0aGUgSW5zZXJ0IHJvdy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZWZyZXNoUm93KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIE1vdmVzIHRoZSBjdXJzb3IgcG9zaXRpb24gdXAgb3IgZG93biBieSBhIHNwZWNpZmllZCBudW1iZXIgb2Ygcm93cy4gSWYKKyAgICAgKiB0aGUgbmV3IHBvc2l0aW9uIGlzIGJleW9uZCB0aGUgc3RhcnQgcm93IChvciBlbmQgcm93KSwgdGhlIGN1cnNvciBwb3NpdGlvbiBpcworICAgICAqIHNldCBiZWZvcmUgdGhlIGZpcnN0IHJvdyAob3IsIHJlc3BlY3RpdmVseSwgYWZ0ZXIgdGhlIGxhc3Qgcm93KS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByb3dzCisgICAgICogICAgICAgICAgICBhIG51bWJlciBvZiByb3dzIHRvIG1vdmUgdGhlIGN1cnNvciAtIG1heSBiZSBwb3NpdGl2ZSBvcgorICAgICAqICAgICAgICAgICAgbmVnYXRpdmUKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgbmV3IGN1cnNvciBwb3NpdGlvbiBpcyBvbiBhIHJvdywge0Bjb2RlCisgICAgICogICAgICAgICBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVsYXRpdmUoaW50IHJvd3MpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBhIHJvdyBoYXMgYmVlbiBkZWxldGVkLiBUaGlzIG1ldGhvZCBkZXBlbmRzIG9uIHdoZXRoZXIKKyAgICAgKiB0aGUgSkRCQyBkcml2ZXIgYW5kIGRhdGFiYXNlIGNhbiBkZXRlY3QgZGVsZXRpb25zLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYSByb3cgaGFzIGJlZW4gZGVsZXRlZCBhbmQgaWYgZGVsZXRpb25zIGFyZQorICAgICAqICAgICAgICAgZGV0ZWN0ZWQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJvd0RlbGV0ZWQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGN1cnJlbnQgcm93IGhhcyBoYWQgYW4gaW5zZXJ0aW9uIG9wZXJhdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBkZXBlbmRzIG9uIHdoZXRoZXIgdGhlIEpEQkMgZHJpdmVyIGFuZCBkYXRhYmFzZSBjYW4gZGV0ZWN0CisgICAgICogaW5zZXJ0aW9ucy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGEgcm93IGhhcyBiZWVuIGluc2VydGVkIGFuZCBpZiBpbnNlcnRpb25zIGFyZQorICAgICAqICAgICAgICAgZGV0ZWN0ZWQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJvd0luc2VydGVkKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBjdXJyZW50IHJvdyBoYXMgYmVlbiB1cGRhdGVkLiBUaGlzIG1ldGhvZCBkZXBlbmRzCisgICAgICogb24gd2hldGhlciB0aGUgSkRCQyBkcml2ZXIgYW5kIGRhdGFiYXNlIGNhbiBkZXRlY3QgdXBkYXRlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBjdXJyZW50IHJvdyBoYXMgYmVlbiB1cGRhdGVkIGFuZCBpZiB1cGRhdGVzCisgICAgICogICAgICAgICBjYW4gYmUgZGV0ZWN0ZWQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJvd1VwZGF0ZWQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoaWNoIGRpcmVjdGlvbiAoZm9yd2FyZC9yZXZlcnNlKSB3aWxsIGJlIHVzZWQgdG8gcHJvY2VzcyB0aGUKKyAgICAgKiByb3dzIG9mIHRoaXMge0Bjb2RlIFJlc3VsdFNldH0gb2JqZWN0LiBUaGlzIGlzIHRyZWF0ZWQgYXMgYSBoaW50IGJ5IHRoZQorICAgICAqIEpEQkMgZHJpdmVyLgorICAgICAqCisgICAgICogQHBhcmFtIGRpcmVjdGlvbgorICAgICAqICAgICAgICAgICAgY2FuIGJlIHtAY29kZSBSZXN1bHRTZXQuRkVUQ0hfRk9SV0FSRH0sIHtAY29kZQorICAgICAqICAgICAgICAgICAgUmVzdWx0U2V0LkZFVENIX1JFVkVSU0V9LCBvciB7QGNvZGUgUmVzdWx0U2V0LkZFVENIX1VOS05PV059CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZldGNoRGlyZWN0aW9uKGludCBkaXJlY3Rpb24pIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhlIG51bWJlciBvZiByb3dzIHRvIGZldGNoIGZyb20gdGhlIGRhdGFiYXNlIHdoZW4gZXh0cmEgcm93cworICAgICAqIGFyZSByZXF1aXJlZCBmb3IgdGhpcyB7QGNvZGUgUmVzdWx0U2V0fS4gVGhpcyB1c2VkIGFzIGEgaGludCB0byB0aGUgSkRCQworICAgICAqIGRyaXZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSByb3dzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIHJvd3MgdG8gZmV0Y2guIHtAY29kZSAwfSBpbXBsaWVzIHRoYXQgdGhlIEpEQkMKKyAgICAgKiAgICAgICAgICAgIGRyaXZlciBjYW4gbWFrZSBpdHMgb3duIGRlY2lzaW9uIGFib3V0IHRoZSBmZXRjaCBzaXplLiBUaGUKKyAgICAgKiAgICAgICAgICAgIG51bWJlciBzaG91bGQgbm90IGJlIGdyZWF0ZXIgdGhhbiB0aGUgbWF4aW11bSBudW1iZXIgb2Ygcm93cworICAgICAqICAgICAgICAgICAgZXN0YWJsaXNoZWQgYnkgdGhlIHN0YXRlbWVudCB0aGF0IGdlbmVyYXRlZCB0aGUge0Bjb2RlCisgICAgICogICAgICAgICAgICBSZXN1bHRTZXR9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZldGNoU2l6ZShpbnQgcm93cykgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGEgY29sdW1uIGluZGV4IHdpdGggYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5BcnJheX0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgY29sdW1uIHRvIHVwZGF0ZS4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBjb2x1bW4uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlQXJyYXkoaW50IGNvbHVtbkluZGV4LCBBcnJheSB4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gbmFtZSB3aXRoIGEge0Bjb2RlIGphdmEuc3FsLkFycmF5fQorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbk5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVBcnJheShTdHJpbmcgY29sdW1uTmFtZSwgQXJyYXkgeCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGEgY29sdW1uIGluZGV4IHdpdGggYW4gQVNDSUkgc3RyZWFtIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgdG8gd3JpdGUgZnJvbSB0aGUgc3RyZWFtCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlQXNjaWlTdHJlYW0oaW50IGNvbHVtbkluZGV4LCBJbnB1dFN0cmVhbSB4LCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGEgY29sdW1uIG5hbWUgd2l0aCBhbiBBc2NpaSBzdHJlYW0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgdG8gd3JpdGUgZnJvbSB0aGUgc3RyZWFtCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlQXNjaWlTdHJlYW0oU3RyaW5nIGNvbHVtbk5hbWUsIElucHV0U3RyZWFtIHgsIGludCBsZW5ndGgpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gaW5kZXggd2l0aCBhIHtAY29kZQorICAgICAqIGphdmEuc3FsLkJpZ0RlY2ltYWx9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUJpZ0RlY2ltYWwoaW50IGNvbHVtbkluZGV4LCBCaWdEZWNpbWFsIHgpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gbmFtZSB3aXRoIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuQmlnRGVjaW1hbH0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUJpZ0RlY2ltYWwoU3RyaW5nIGNvbHVtbk5hbWUsIEJpZ0RlY2ltYWwgeCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGEgY29sdW1uIHNwZWNpZmllZCBieSBhIGNvbHVtbiBpbmRleCB3aXRoIGEgYmluYXJ5IHN0cmVhbSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGJlIHJlYWQgZnJvbSB0aGUgdGhlIHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVCaW5hcnlTdHJlYW0oaW50IGNvbHVtbkluZGV4LCBJbnB1dFN0cmVhbSB4LCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGEgY29sdW1uIG5hbWUgd2l0aCBhIGJpbmFyeSBzdHJlYW0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIGhlIG51bWJlciBvZiBieXRlcyB0byBiZSByZWFkIGZyb20gdGhlIHRoZSBzdHJlYW0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlQmluYXJ5U3RyZWFtKFN0cmluZyBjb2x1bW5OYW1lLCBJbnB1dFN0cmVhbSB4LCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGEgY29sdW1uIGluZGV4IHdpdGggYSB7QGNvZGUgamF2YS5zcWwuQmxvYn0KKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVCbG9iKGludCBjb2x1bW5JbmRleCwgQmxvYiB4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gbmFtZSB3aXRoIGEge0Bjb2RlIGphdmEuc3FsLkJsb2J9CisgICAgICogdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUJsb2IoU3RyaW5nIGNvbHVtbk5hbWUsIEJsb2IgeCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGEgY29sdW1uIGluZGV4IHdpdGggYSB7QGNvZGUgYm9vbGVhbn0KKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVCb29sZWFuKGludCBjb2x1bW5JbmRleCwgYm9vbGVhbiB4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gbmFtZSB3aXRoIGEge0Bjb2RlIGJvb2xlYW59IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbk5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVCb29sZWFuKFN0cmluZyBjb2x1bW5OYW1lLCBib29sZWFuIHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGEgY29sdW1uIHNwZWNpZmllZCBieSBhIGNvbHVtbiBpbmRleCB3aXRoIGEge0Bjb2RlIGJ5dGV9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUJ5dGUoaW50IGNvbHVtbkluZGV4LCBieXRlIHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGEgY29sdW1uIHNwZWNpZmllZCBieSBhIGNvbHVtbiBuYW1lIHdpdGggYSB7QGNvZGUgYnl0ZX0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUJ5dGUoU3RyaW5nIGNvbHVtbk5hbWUsIGJ5dGUgeCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGEgY29sdW1uIGluZGV4IHdpdGggYSB7QGNvZGUgYnl0ZX0gYXJyYXkKKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVCeXRlcyhpbnQgY29sdW1uSW5kZXgsIGJ5dGVbXSB4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gbmFtZSB3aXRoIGEgYnl0ZSBhcnJheSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5OYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY29sdW1uIHRvIHVwZGF0ZS4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBjb2x1bW4uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlQnl0ZXMoU3RyaW5nIGNvbHVtbk5hbWUsIGJ5dGVbXSB4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gaW5kZXggd2l0aCBhIGNoYXJhY3RlciBzdHJlYW0KKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIGRhdGEgdG8gd3JpdGUgZnJvbSB0aGUgc3RyZWFtCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlQ2hhcmFjdGVyU3RyZWFtKGludCBjb2x1bW5JbmRleCwgUmVhZGVyIHgsIGludCBsZW5ndGgpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gbmFtZSB3aXRoIGEgY2hhcmFjdGVyIHN0cmVhbQorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbk5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSByZWFkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgZGF0YSB0byB3cml0ZSBmcm9tIHRoZSBSZWFkZXIKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVDaGFyYWN0ZXJTdHJlYW0oU3RyaW5nIGNvbHVtbk5hbWUsIFJlYWRlciByZWFkZXIsCisgICAgICAgICAgICBpbnQgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gaW5kZXggd2l0aCBhIHtAY29kZSBqYXZhLnNxbC5DbG9ifQorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUNsb2IoaW50IGNvbHVtbkluZGV4LCBDbG9iIHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGEgY29sdW1uIHNwZWNpZmllZCBieSBhIGNvbHVtbiBuYW1lIHdpdGggYSB7QGNvZGUgamF2YS5zcWwuQ2xvYn0KKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5OYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY29sdW1uIHRvIHVwZGF0ZS4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBjb2x1bW4uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlQ2xvYihTdHJpbmcgY29sdW1uTmFtZSwgQ2xvYiB4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gaW5kZXggd2l0aCBhIHtAY29kZSBqYXZhLnNxbC5EYXRlfQorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZURhdGUoaW50IGNvbHVtbkluZGV4LCBEYXRlIHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGEgY29sdW1uIHNwZWNpZmllZCBieSBhIGNvbHVtbiBuYW1lIHdpdGggYSB7QGNvZGUgamF2YS5zcWwuRGF0ZX0KKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5OYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY29sdW1uIHRvIHVwZGF0ZS4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBjb2x1bW4uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlRGF0ZShTdHJpbmcgY29sdW1uTmFtZSwgRGF0ZSB4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gaW5kZXggd2l0aCBhIHtAY29kZSBkb3VibGV9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZURvdWJsZShpbnQgY29sdW1uSW5kZXgsIGRvdWJsZSB4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gbmFtZSB3aXRoIGEge0Bjb2RlIGRvdWJsZX0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZURvdWJsZShTdHJpbmcgY29sdW1uTmFtZSwgZG91YmxlIHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGEgY29sdW1uIHNwZWNpZmllZCBieSBhIGNvbHVtbiBpbmRleCB3aXRoIGEge0Bjb2RlIGZsb2F0fSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVGbG9hdChpbnQgY29sdW1uSW5kZXgsIGZsb2F0IHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGEgY29sdW1uIHNwZWNpZmllZCBieSBhIGNvbHVtbiBuYW1lIHdpdGggYSB7QGNvZGUgZmxvYXR9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbk5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVGbG9hdChTdHJpbmcgY29sdW1uTmFtZSwgZmxvYXQgeCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGEgY29sdW1uIGluZGV4IHdpdGggYW4ge0Bjb2RlIGludH0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgY29sdW1uIHRvIHVwZGF0ZS4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBjb2x1bW4uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlSW50KGludCBjb2x1bW5JbmRleCwgaW50IHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGEgY29sdW1uIHNwZWNpZmllZCBieSBhIGNvbHVtbiBuYW1lIHdpdGggYW4ge0Bjb2RlIGludH0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUludChTdHJpbmcgY29sdW1uTmFtZSwgaW50IHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGEgY29sdW1uIHNwZWNpZmllZCBieSBhIGNvbHVtbiBpbmRleCB3aXRoIGEge0Bjb2RlIGxvbmd9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVMb25nKGludCBjb2x1bW5JbmRleCwgbG9uZyB4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gbmFtZSB3aXRoIGEge0Bjb2RlIGxvbmd9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbk5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVMb25nKFN0cmluZyBjb2x1bW5OYW1lLCBsb25nIHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGEgY29sdW1uIHNwZWNpZmllZCBieSBhIGNvbHVtbiBpbmRleCB3aXRoIGEge0Bjb2RlIG51bGx9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlTnVsbChpbnQgY29sdW1uSW5kZXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGEgY29sdW1uIHNwZWNpZmllZCBieSBhIGNvbHVtbiBuYW1lIHdpdGggYSB7QGNvZGUgbnVsbH0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlTnVsbChTdHJpbmcgY29sdW1uTmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGEgY29sdW1uIGluZGV4IHdpdGggYW4ge0Bjb2RlIE9iamVjdH0KKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVPYmplY3QoaW50IGNvbHVtbkluZGV4LCBPYmplY3QgeCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGEgY29sdW1uIGluZGV4IHdpdGggYW4ge0Bjb2RlIE9iamVjdH0KKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAcGFyYW0gc2NhbGUKKyAgICAgKiAgICAgICAgICAgIGZvciB0aGUgdHlwZXMge0Bjb2RlIGphdmEuc3FsLlR5cGVzLkRFQ0lNQUx9IG9yIHtAY29kZQorICAgICAqICAgICAgICAgICAgamF2YS5zcWwuVHlwZXMuTlVNRVJJQ30sIHRoaXMgc3BlY2lmaWVzIHRoZSBudW1iZXIgb2YgZGlnaXRzCisgICAgICogICAgICAgICAgICBhZnRlciB0aGUgZGVjaW1hbCBwb2ludC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVPYmplY3QoaW50IGNvbHVtbkluZGV4LCBPYmplY3QgeCwgaW50IHNjYWxlKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGEgY29sdW1uIG5hbWUgd2l0aCBhbiB7QGNvZGUgT2JqZWN0fSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5OYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY29sdW1uIHRvIHVwZGF0ZS4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBjb2x1bW4uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlT2JqZWN0KFN0cmluZyBjb2x1bW5OYW1lLCBPYmplY3QgeCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGEgY29sdW1uIG5hbWUgd2l0aCBhbiB7QGNvZGUgT2JqZWN0fSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5OYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY29sdW1uIHRvIHVwZGF0ZS4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBjb2x1bW4uCisgICAgICogQHBhcmFtIHNjYWxlCisgICAgICogICAgICAgICAgICBmb3IgdGhlIHR5cGVzIHtAY29kZSBqYXZhLnNxbC5UeXBlcy5ERUNJTUFMfSBvciB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIGphdmEuc3FsLlR5cGVzLk5VTUVSSUN9LCB0aGlzIHNwZWNpZmllcyB0aGUgbnVtYmVyIG9mIGRpZ2l0cworICAgICAqICAgICAgICAgICAgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlT2JqZWN0KFN0cmluZyBjb2x1bW5OYW1lLCBPYmplY3QgeCwgaW50IHNjYWxlKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGEgY29sdW1uIGluZGV4IHdpdGggYSB7QGNvZGUgamF2YS5zcWwuUmVmfQorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiB0byB1cGRhdGUuCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZVJlZihpbnQgY29sdW1uSW5kZXgsIFJlZiB4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gbmFtZSB3aXRoIGEge0Bjb2RlIGphdmEuc3FsLlJlZn0KKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5OYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY29sdW1uIHRvIHVwZGF0ZS4KKyAgICAgKiBAcGFyYW0geAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBjb2x1bW4uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlUmVmKFN0cmluZyBjb2x1bW5OYW1lLCBSZWYgeCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhlIGRhdGFiYXNlIHdpdGggdGhlIG5ldyBjb250ZW50cyBvZiB0aGUgY3VycmVudCByb3cgb2YgdGhpcworICAgICAqIHtAY29kZSBSZXN1bHRTZXR9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBoYXBwZW5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZVJvdygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGEgY29sdW1uIHNwZWNpZmllZCBieSBhIGNvbHVtbiBpbmRleCB3aXRoIGEge0Bjb2RlIHNob3J0fSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVTaG9ydChpbnQgY29sdW1uSW5kZXgsIHNob3J0IHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGEgY29sdW1uIHNwZWNpZmllZCBieSBhIGNvbHVtbiBuYW1lIHdpdGggYSB7QGNvZGUgc2hvcnR9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbk5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVTaG9ydChTdHJpbmcgY29sdW1uTmFtZSwgc2hvcnQgeCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGEgY29sdW1uIGluZGV4IHdpdGggYSB7QGNvZGUgU3RyaW5nfSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVTdHJpbmcoaW50IGNvbHVtbkluZGV4LCBTdHJpbmcgeCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYSBjb2x1bW4gc3BlY2lmaWVkIGJ5IGEgY29sdW1uIG5hbWUgd2l0aCBhIHtAY29kZSBTdHJpbmd9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbk5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVTdHJpbmcoU3RyaW5nIGNvbHVtbk5hbWUsIFN0cmluZyB4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gaW5kZXggd2l0aCBhIHtAY29kZSBUaW1lfSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVUaW1lKGludCBjb2x1bW5JbmRleCwgVGltZSB4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgYSBjb2x1bW4gbmFtZSB3aXRoIGEge0Bjb2RlIFRpbWV9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbk5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVUaW1lKFN0cmluZyBjb2x1bW5OYW1lLCBUaW1lIHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGEgY29sdW1uIHNwZWNpZmllZCBieSBhIGNvbHVtbiBpbmRleCB3aXRoIGEge0Bjb2RlIFRpbWVzdGFtcH0KKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHRpbWVzdGFtcCB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBjb2x1bW4uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlVGltZXN0YW1wKGludCBjb2x1bW5JbmRleCwgVGltZXN0YW1wIHgpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBhIGNvbHVtbiBzcGVjaWZpZWQgYnkgY29sdW1uIG5hbWUgd2l0aCBhIHtAY29kZSBUaW1lc3RhbXB9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbk5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gdG8gdXBkYXRlLgorICAgICAqIEBwYXJhbSB4CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHRpbWVzdGFtcCB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBjb2x1bW4uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIGhhcHBlbnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlVGltZXN0YW1wKFN0cmluZyBjb2x1bW5OYW1lLCBUaW1lc3RhbXAgeCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGxhc3QgY29sdW1uIHJlYWQgZnJvbSB0aGlzIHtAY29kZSBSZXN1bHRTZXR9CisgICAgICogY29udGFpbmVkIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGxhc3QgY29sdW1uIGNvbnRhaW5lZCBTUUwge0Bjb2RlCisgICAgICogICAgICAgICBOVUxMfSwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3IgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB3YXNOdWxsKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgUm93SWR9IGNvcnJlc3BvbmRpbmcgdG8gdGhlIFNRTCBST1dJRCBhdCB0aGUgMS1iYXNlZCB7QGNvZGUgY29sdW1uSW5kZXh9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFJvd0lkIGdldFJvd0lkKGludCBjb2x1bW5JbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgUm93SWR9IGNvcnJlc3BvbmRpbmcgdG8gdGhlIFNRTCBST1dJRCBhdCB0aGUgbmFtZWQgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFJvd0lkIGdldFJvd0lkKFN0cmluZyBjb2x1bW5MYWJlbCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhlIHZhbHVlIGF0IHRoZSAxLWJhc2VkIHtAY29kZSBjb2x1bW5JbmRleH0uCisgICAgICogVGhlIHVuZGVybHlpbmcgZGF0YWJhc2UgaXNuJ3QgY2hhbmdlZCB1bnRpbCB0aGUgbmV4dCByb3cgdXBkYXRlIG9yIGluc2VydCBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVSb3dJZChpbnQgY29sdW1uSW5kZXgsIFJvd0lkIHZhbHVlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgdmFsdWUgaW4gdGhlIG5hbWVkIGNvbHVtbi4KKyAgICAgKiBUaGUgdW5kZXJseWluZyBkYXRhYmFzZSBpc24ndCBjaGFuZ2VkIHVudGlsIHRoZSBuZXh0IHJvdyB1cGRhdGUgb3IgaW5zZXJ0IG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZVJvd0lkKFN0cmluZyBjb2x1bW5MYWJlbCwgUm93SWQgdmFsdWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBob2xkYWJpbGl0eSBvZiB0aGlzIHJlc3VsdCBzZXQ6IHtAbGluayAjSE9MRF9DVVJTT1JTX09WRVJfQ09NTUlUfSBvcgorICAgICAqIHtAbGluayAjQ0xPU0VfQ1VSU09SU19BVF9DT01NSVR9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGludCBnZXRIb2xkYWJpbGl0eSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyByZXN1bHQgc2V0IGhhcyBiZWVuIGNsb3NlZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDbG9zZWQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgdmFsdWUgYXQgdGhlIDEtYmFzZWQge0Bjb2RlIGNvbHVtbkluZGV4fS4KKyAgICAgKiBUaGUgdW5kZXJseWluZyBkYXRhYmFzZSBpc24ndCBjaGFuZ2VkIHVudGlsIHRoZSBuZXh0IHJvdyB1cGRhdGUgb3IgaW5zZXJ0IG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZU5TdHJpbmcoaW50IGNvbHVtbkluZGV4LCBTdHJpbmcgblN0cmluZykgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhlIHZhbHVlIGluIHRoZSBuYW1lZCBjb2x1bW4uCisgICAgICogVGhlIHVuZGVybHlpbmcgZGF0YWJhc2UgaXNuJ3QgY2hhbmdlZCB1bnRpbCB0aGUgbmV4dCByb3cgdXBkYXRlIG9yIGluc2VydCBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVOU3RyaW5nKFN0cmluZyBjb2x1bW5MYWJlbCwgU3RyaW5nIG5TdHJpbmcpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoZSB2YWx1ZSBhdCB0aGUgMS1iYXNlZCB7QGNvZGUgY29sdW1uSW5kZXh9LgorICAgICAqIFRoZSB1bmRlcmx5aW5nIGRhdGFiYXNlIGlzbid0IGNoYW5nZWQgdW50aWwgdGhlIG5leHQgcm93IHVwZGF0ZSBvciBpbnNlcnQgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlTkNsb2IoaW50IGNvbHVtbkluZGV4LCBOQ2xvYiBuQ2xvYikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhlIHZhbHVlIGluIHRoZSBuYW1lZCBjb2x1bW4uCisgICAgICogVGhlIHVuZGVybHlpbmcgZGF0YWJhc2UgaXNuJ3QgY2hhbmdlZCB1bnRpbCB0aGUgbmV4dCByb3cgdXBkYXRlIG9yIGluc2VydCBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVOQ2xvYihTdHJpbmcgY29sdW1uTGFiZWwsIE5DbG9iIG5DbG9iKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiB7QGNvZGUgTkNsb2J9IGNvcnJlc3BvbmRpbmcgdG8gdGhlIHZhbHVlIGF0IHRoZSAxLWJhc2VkIHtAY29kZSBjb2x1bW5JbmRleH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgTkNsb2IgZ2V0TkNsb2IoaW50IGNvbHVtbkluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiB7QGNvZGUgTkNsb2J9IGNvcnJlc3BvbmRpbmcgdG8gdGhlIHZhbHVlIGluIHRoZSBuYW1lZCBjb2x1bW4uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgTkNsb2IgZ2V0TkNsb2IoU3RyaW5nIGNvbHVtbkxhYmVsKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiB7QGNvZGUgU1FMWE1MfSBjb3JyZXNwb25kaW5nIHRvIHRoZSB2YWx1ZSBhdCB0aGUgMS1iYXNlZCB7QGNvZGUgY29sdW1uSW5kZXh9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTFhNTCBnZXRTUUxYTUwoaW50IGNvbHVtbkluZGV4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiB7QGNvZGUgU1FMWE1MfSBjb3JyZXNwb25kaW5nIHRvIHRoZSB2YWx1ZSBpbiB0aGUgbmFtZWQgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTFhNTCBnZXRTUUxYTUwoU3RyaW5nIGNvbHVtbkxhYmVsKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgdmFsdWUgYXQgdGhlIDEtYmFzZWQge0Bjb2RlIGNvbHVtbkluZGV4fS4KKyAgICAgKiBUaGUgdW5kZXJseWluZyBkYXRhYmFzZSBpc24ndCBjaGFuZ2VkIHVudGlsIHRoZSBuZXh0IHJvdyB1cGRhdGUgb3IgaW5zZXJ0IG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZVNRTFhNTChpbnQgY29sdW1uSW5kZXgsIFNRTFhNTCB4bWxPYmplY3QpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoZSB2YWx1ZSBpbiB0aGUgbmFtZWQgY29sdW1uLgorICAgICAqIFRoZSB1bmRlcmx5aW5nIGRhdGFiYXNlIGlzbid0IGNoYW5nZWQgdW50aWwgdGhlIG5leHQgcm93IHVwZGF0ZSBvciBpbnNlcnQgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlU1FMWE1MKFN0cmluZyBjb2x1bW5MYWJlbCwgU1FMWE1MIHhtbE9iamVjdCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgU3RyaW5nfSBjb3JyZXNwb25kaW5nIHRvIHRoZSB2YWx1ZSBhdCB0aGUgMS1iYXNlZCB7QGNvZGUgY29sdW1uSW5kZXh9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROU3RyaW5nKGludCBjb2x1bW5JbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgU3RyaW5nfSBjb3JyZXNwb25kaW5nIHRvIHRoZSB2YWx1ZSBpbiB0aGUgbmFtZWQgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROU3RyaW5nKFN0cmluZyBjb2x1bW5MYWJlbCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgUmVhZGVyfSBjb3JyZXNwb25kaW5nIHRvIHRoZSB2YWx1ZSBhdCB0aGUgMS1iYXNlZCB7QGNvZGUgY29sdW1uSW5kZXh9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFJlYWRlciBnZXROQ2hhcmFjdGVyU3RyZWFtKGludCBjb2x1bW5JbmRleCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgUmVhZGVyfSBjb3JyZXNwb25kaW5nIHRvIHRoZSB2YWx1ZSBpbiB0aGUgbmFtZWQgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFJlYWRlciBnZXROQ2hhcmFjdGVyU3RyZWFtKFN0cmluZyBjb2x1bW5MYWJlbCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhlIHZhbHVlIGF0IHRoZSAxLWJhc2VkIHtAY29kZSBjb2x1bW5JbmRleH0uCisgICAgICogVGhlIHVuZGVybHlpbmcgZGF0YWJhc2UgaXNuJ3QgY2hhbmdlZCB1bnRpbCB0aGUgbmV4dCByb3cgdXBkYXRlIG9yIGluc2VydCBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVOQ2hhcmFjdGVyU3RyZWFtKGludCBjb2x1bW5JbmRleCwgUmVhZGVyIHgsIGxvbmcgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgdmFsdWUgaW4gdGhlIG5hbWVkIGNvbHVtbi4KKyAgICAgKiBUaGUgdW5kZXJseWluZyBkYXRhYmFzZSBpc24ndCBjaGFuZ2VkIHVudGlsIHRoZSBuZXh0IHJvdyB1cGRhdGUgb3IgaW5zZXJ0IG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZU5DaGFyYWN0ZXJTdHJlYW0oU3RyaW5nIGNvbHVtbkxhYmVsLCBSZWFkZXIgcmVhZGVyLCBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhlIHZhbHVlIGF0IHRoZSAxLWJhc2VkIHtAY29kZSBjb2x1bW5JbmRleH0uCisgICAgICogVGhlIHVuZGVybHlpbmcgZGF0YWJhc2UgaXNuJ3QgY2hhbmdlZCB1bnRpbCB0aGUgbmV4dCByb3cgdXBkYXRlIG9yIGluc2VydCBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVBc2NpaVN0cmVhbShpbnQgY29sdW1uSW5kZXgsIElucHV0U3RyZWFtIHgsIGxvbmcgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgdmFsdWUgYXQgdGhlIDEtYmFzZWQge0Bjb2RlIGNvbHVtbkluZGV4fS4KKyAgICAgKiBUaGUgdW5kZXJseWluZyBkYXRhYmFzZSBpc24ndCBjaGFuZ2VkIHVudGlsIHRoZSBuZXh0IHJvdyB1cGRhdGUgb3IgaW5zZXJ0IG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUJpbmFyeVN0cmVhbShpbnQgY29sdW1uSW5kZXgsIElucHV0U3RyZWFtIHgsIGxvbmcgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgdmFsdWUgYXQgdGhlIDEtYmFzZWQge0Bjb2RlIGNvbHVtbkluZGV4fS4KKyAgICAgKiBUaGUgdW5kZXJseWluZyBkYXRhYmFzZSBpc24ndCBjaGFuZ2VkIHVudGlsIHRoZSBuZXh0IHJvdyB1cGRhdGUgb3IgaW5zZXJ0IG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUNoYXJhY3RlclN0cmVhbShpbnQgY29sdW1uSW5kZXgsIFJlYWRlciB4LCBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhlIHZhbHVlIGluIHRoZSBuYW1lZCBjb2x1bW4uCisgICAgICogVGhlIHVuZGVybHlpbmcgZGF0YWJhc2UgaXNuJ3QgY2hhbmdlZCB1bnRpbCB0aGUgbmV4dCByb3cgdXBkYXRlIG9yIGluc2VydCBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVBc2NpaVN0cmVhbShTdHJpbmcgY29sdW1uTGFiZWwsIElucHV0U3RyZWFtIHgsIGxvbmcgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgdmFsdWUgaW4gdGhlIG5hbWVkIGNvbHVtbi4KKyAgICAgKiBUaGUgdW5kZXJseWluZyBkYXRhYmFzZSBpc24ndCBjaGFuZ2VkIHVudGlsIHRoZSBuZXh0IHJvdyB1cGRhdGUgb3IgaW5zZXJ0IG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUJpbmFyeVN0cmVhbShTdHJpbmcgY29sdW1uTGFiZWwsIElucHV0U3RyZWFtIHgsIGxvbmcgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgdmFsdWUgaW4gdGhlIG5hbWVkIGNvbHVtbi4KKyAgICAgKiBUaGUgdW5kZXJseWluZyBkYXRhYmFzZSBpc24ndCBjaGFuZ2VkIHVudGlsIHRoZSBuZXh0IHJvdyB1cGRhdGUgb3IgaW5zZXJ0IG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUNoYXJhY3RlclN0cmVhbShTdHJpbmcgY29sdW1uTGFiZWwsIFJlYWRlciByZWFkZXIsIGxvbmcgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgdmFsdWUgYXQgdGhlIDEtYmFzZWQge0Bjb2RlIGNvbHVtbkluZGV4fS4KKyAgICAgKiBUaGUgdW5kZXJseWluZyBkYXRhYmFzZSBpc24ndCBjaGFuZ2VkIHVudGlsIHRoZSBuZXh0IHJvdyB1cGRhdGUgb3IgaW5zZXJ0IG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUJsb2IoaW50IGNvbHVtbkluZGV4LCBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSwgbG9uZyBsZW5ndGgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoZSB2YWx1ZSBpbiB0aGUgbmFtZWQgY29sdW1uLgorICAgICAqIFRoZSB1bmRlcmx5aW5nIGRhdGFiYXNlIGlzbid0IGNoYW5nZWQgdW50aWwgdGhlIG5leHQgcm93IHVwZGF0ZSBvciBpbnNlcnQgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlQmxvYihTdHJpbmcgY29sdW1uTGFiZWwsIElucHV0U3RyZWFtIGlucHV0U3RyZWFtLCBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhlIHZhbHVlIGF0IHRoZSAxLWJhc2VkIHtAY29kZSBjb2x1bW5JbmRleH0uCisgICAgICogVGhlIHVuZGVybHlpbmcgZGF0YWJhc2UgaXNuJ3QgY2hhbmdlZCB1bnRpbCB0aGUgbmV4dCByb3cgdXBkYXRlIG9yIGluc2VydCBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVDbG9iKGludCBjb2x1bW5JbmRleCwgUmVhZGVyIHJlYWRlciwgbG9uZyBsZW5ndGgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoZSB2YWx1ZSBpbiB0aGUgbmFtZWQgY29sdW1uLgorICAgICAqIFRoZSB1bmRlcmx5aW5nIGRhdGFiYXNlIGlzbid0IGNoYW5nZWQgdW50aWwgdGhlIG5leHQgcm93IHVwZGF0ZSBvciBpbnNlcnQgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlQ2xvYihTdHJpbmcgY29sdW1uTGFiZWwsIFJlYWRlciByZWFkZXIsIGxvbmcgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgdmFsdWUgYXQgdGhlIDEtYmFzZWQge0Bjb2RlIGNvbHVtbkluZGV4fS4KKyAgICAgKiBUaGUgdW5kZXJseWluZyBkYXRhYmFzZSBpc24ndCBjaGFuZ2VkIHVudGlsIHRoZSBuZXh0IHJvdyB1cGRhdGUgb3IgaW5zZXJ0IG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZU5DbG9iKGludCBjb2x1bW5JbmRleCwgUmVhZGVyIHJlYWRlciwgbG9uZyBsZW5ndGgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoZSB2YWx1ZSBpbiB0aGUgbmFtZWQgY29sdW1uLgorICAgICAqIFRoZSB1bmRlcmx5aW5nIGRhdGFiYXNlIGlzbid0IGNoYW5nZWQgdW50aWwgdGhlIG5leHQgcm93IHVwZGF0ZSBvciBpbnNlcnQgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlTkNsb2IoU3RyaW5nIGNvbHVtbkxhYmVsLCBSZWFkZXIgcmVhZGVyLCBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhlIHZhbHVlIGF0IHRoZSAxLWJhc2VkIHtAY29kZSBjb2x1bW5JbmRleH0uCisgICAgICogVGhlIHVuZGVybHlpbmcgZGF0YWJhc2UgaXNuJ3QgY2hhbmdlZCB1bnRpbCB0aGUgbmV4dCByb3cgdXBkYXRlIG9yIGluc2VydCBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVOQ2hhcmFjdGVyU3RyZWFtKGludCBjb2x1bW5JbmRleCwgUmVhZGVyIHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoZSB2YWx1ZSBpbiB0aGUgbmFtZWQgY29sdW1uLgorICAgICAqIFRoZSB1bmRlcmx5aW5nIGRhdGFiYXNlIGlzbid0IGNoYW5nZWQgdW50aWwgdGhlIG5leHQgcm93IHVwZGF0ZSBvciBpbnNlcnQgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlTkNoYXJhY3RlclN0cmVhbShTdHJpbmcgY29sdW1uTGFiZWwsIFJlYWRlciByZWFkZXIpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoZSB2YWx1ZSBhdCB0aGUgMS1iYXNlZCB7QGNvZGUgY29sdW1uSW5kZXh9LgorICAgICAqIFRoZSB1bmRlcmx5aW5nIGRhdGFiYXNlIGlzbid0IGNoYW5nZWQgdW50aWwgdGhlIG5leHQgcm93IHVwZGF0ZSBvciBpbnNlcnQgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlQXNjaWlTdHJlYW0oaW50IGNvbHVtbkluZGV4LCBJbnB1dFN0cmVhbSB4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgdmFsdWUgYXQgdGhlIDEtYmFzZWQge0Bjb2RlIGNvbHVtbkluZGV4fS4KKyAgICAgKiBUaGUgdW5kZXJseWluZyBkYXRhYmFzZSBpc24ndCBjaGFuZ2VkIHVudGlsIHRoZSBuZXh0IHJvdyB1cGRhdGUgb3IgaW5zZXJ0IG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUJpbmFyeVN0cmVhbShpbnQgY29sdW1uSW5kZXgsIElucHV0U3RyZWFtIHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoZSB2YWx1ZSBhdCB0aGUgMS1iYXNlZCB7QGNvZGUgY29sdW1uSW5kZXh9LgorICAgICAqIFRoZSB1bmRlcmx5aW5nIGRhdGFiYXNlIGlzbid0IGNoYW5nZWQgdW50aWwgdGhlIG5leHQgcm93IHVwZGF0ZSBvciBpbnNlcnQgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlQ2hhcmFjdGVyU3RyZWFtKGludCBjb2x1bW5JbmRleCwgUmVhZGVyIHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoZSB2YWx1ZSBpbiB0aGUgbmFtZWQgY29sdW1uLgorICAgICAqIFRoZSB1bmRlcmx5aW5nIGRhdGFiYXNlIGlzbid0IGNoYW5nZWQgdW50aWwgdGhlIG5leHQgcm93IHVwZGF0ZSBvciBpbnNlcnQgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlQXNjaWlTdHJlYW0oU3RyaW5nIGNvbHVtbkxhYmVsLCBJbnB1dFN0cmVhbSB4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgdmFsdWUgaW4gdGhlIG5hbWVkIGNvbHVtbi4KKyAgICAgKiBUaGUgdW5kZXJseWluZyBkYXRhYmFzZSBpc24ndCBjaGFuZ2VkIHVudGlsIHRoZSBuZXh0IHJvdyB1cGRhdGUgb3IgaW5zZXJ0IG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUJpbmFyeVN0cmVhbShTdHJpbmcgY29sdW1uTGFiZWwsIElucHV0U3RyZWFtIHgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoZSB2YWx1ZSBpbiB0aGUgbmFtZWQgY29sdW1uLgorICAgICAqIFRoZSB1bmRlcmx5aW5nIGRhdGFiYXNlIGlzbid0IGNoYW5nZWQgdW50aWwgdGhlIG5leHQgcm93IHVwZGF0ZSBvciBpbnNlcnQgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlQ2hhcmFjdGVyU3RyZWFtKFN0cmluZyBjb2x1bW5MYWJlbCwgUmVhZGVyIHJlYWRlcikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhlIHZhbHVlIGF0IHRoZSAxLWJhc2VkIHtAY29kZSBjb2x1bW5JbmRleH0uCisgICAgICogVGhlIHVuZGVybHlpbmcgZGF0YWJhc2UgaXNuJ3QgY2hhbmdlZCB1bnRpbCB0aGUgbmV4dCByb3cgdXBkYXRlIG9yIGluc2VydCBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVCbG9iKGludCBjb2x1bW5JbmRleCwgSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0pIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoZSB2YWx1ZSBpbiB0aGUgbmFtZWQgY29sdW1uLgorICAgICAqIFRoZSB1bmRlcmx5aW5nIGRhdGFiYXNlIGlzbid0IGNoYW5nZWQgdW50aWwgdGhlIG5leHQgcm93IHVwZGF0ZSBvciBpbnNlcnQgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlQmxvYihTdHJpbmcgY29sdW1uTGFiZWwsIElucHV0U3RyZWFtIGlucHV0U3RyZWFtKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgdmFsdWUgYXQgdGhlIDEtYmFzZWQge0Bjb2RlIGNvbHVtbkluZGV4fS4KKyAgICAgKiBUaGUgdW5kZXJseWluZyBkYXRhYmFzZSBpc24ndCBjaGFuZ2VkIHVudGlsIHRoZSBuZXh0IHJvdyB1cGRhdGUgb3IgaW5zZXJ0IG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUNsb2IoaW50IGNvbHVtbkluZGV4LCBSZWFkZXIgcmVhZGVyKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgdmFsdWUgaW4gdGhlIG5hbWVkIGNvbHVtbi4KKyAgICAgKiBUaGUgdW5kZXJseWluZyBkYXRhYmFzZSBpc24ndCBjaGFuZ2VkIHVudGlsIHRoZSBuZXh0IHJvdyB1cGRhdGUgb3IgaW5zZXJ0IG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZUNsb2IoU3RyaW5nIGNvbHVtbkxhYmVsLCBSZWFkZXIgcmVhZGVyKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgdmFsdWUgYXQgdGhlIDEtYmFzZWQge0Bjb2RlIGNvbHVtbkluZGV4fS4KKyAgICAgKiBUaGUgdW5kZXJseWluZyBkYXRhYmFzZSBpc24ndCBjaGFuZ2VkIHVudGlsIHRoZSBuZXh0IHJvdyB1cGRhdGUgb3IgaW5zZXJ0IG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZU5DbG9iKGludCBjb2x1bW5JbmRleCwgUmVhZGVyIHJlYWRlcikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhlIHZhbHVlIGluIHRoZSBuYW1lZCBjb2x1bW4uCisgICAgICogVGhlIHVuZGVybHlpbmcgZGF0YWJhc2UgaXNuJ3QgY2hhbmdlZCB1bnRpbCB0aGUgbmV4dCByb3cgdXBkYXRlIG9yIGluc2VydCBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGVOQ2xvYihTdHJpbmcgY29sdW1uTGFiZWwsIFJlYWRlciByZWFkZXIpIHRocm93cyBTUUxFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvUmVzdWx0U2V0TWV0YURhdGEuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9SZXN1bHRTZXRNZXRhRGF0YS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhZTc3MzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvUmVzdWx0U2V0TWV0YURhdGEuamF2YQpAQCAtMCwwICsxLDI4MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zcWw7CisKKy8qKgorICogUHJvdmlkZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNvbHVtbnMgcmV0dXJuZWQgaW4gYSB7QGNvZGUgUmVzdWx0U2V0fS4KKyAqLworcHVibGljIGludGVyZmFjZSBSZXN1bHRTZXRNZXRhRGF0YSBleHRlbmRzIFdyYXBwZXIgeworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoYXQgYSBjb2x1bW4gY2Fubm90IGNvbnRhaW4ge0Bjb2RlIE5VTEx9IHZhbHVlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBjb2x1bW5Ob051bGxzID0gMDsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB0aGF0IGEgY29sdW1uIGNhbiBjb250YWluIHtAY29kZSBOVUxMfSB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgY29sdW1uTnVsbGFibGUgPSAxOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoYXQgaXQgaXMgdW5rbm93biB3aGV0aGVyIGEgY29sdW1uIGNhbiBjb250YWluIHtAY29kZSBOVUxMfXMgb3Igbm90LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGNvbHVtbk51bGxhYmxlVW5rbm93biA9IDI7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0aXRsZSBvZiBhbiBpbmRleGVkIGNvbHVtbidzIGNhdGFsb2cuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uCisgICAgICogICAgICAgICAgICB0aGUgY29sdW1uIGluZGV4LCBzdGFydGluZyBhdCAxLgorICAgICAqIEByZXR1cm4gdGhlIGNhdGFsb2cgdGl0bGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2F0YWxvZ05hbWUoaW50IGNvbHVtbikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZ1bGx5LXF1YWxpZmllZCB0eXBlIG9mIHRoZSBjbGFzcyB0aGF0IGlzIHByb2R1Y2VkIHdoZW4KKyAgICAgKiBpbnZva2luZyB7QGNvZGUgUmVzdWx0U2V0LmdldE9iamVjdH0gdG8gcmVjb3ZlciB0aGlzIGNvbHVtbidzIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbHVtbiBpbmRleCwgc3RhcnRpbmcgYXQgMS4KKyAgICAgKiBAcmV0dXJuIHRoZSBmdWxseS1xdWFsaWZpZWQgY2xhc3MgbmFtZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICogQHNlZSBSZXN1bHRTZXQjZ2V0T2JqZWN0CisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb2x1bW5DbGFzc05hbWUoaW50IGNvbHVtbikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgbnVtYmVyIG9mIGNvbHVtbnMgY29udGFpbmVkIGluIHRoZSBhc3NvY2lhdGVkIHJlc3VsdCBzZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb2x1bW4gY291bnQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uQ291bnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXhlZCBjb2x1bW4ncyBzdGFuZGFyZCBtYXhpbXVtIHdpZHRoLCBleHByZXNzZWQgaW4gbnVtYmVyCisgICAgICogb2YgY2hhcmFjdGVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2x1bW4gaW5kZXgsIHN0YXJ0aW5nIGF0IDEuCisgICAgICogQHJldHVybiB0aGUgY29sdW1uJ3MgbWF4IHdpZHRoLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldENvbHVtbkRpc3BsYXlTaXplKGludCBjb2x1bW4pIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcmVjb21tZW5kZWQgdGl0bGUgZm9yIHRoZSBpbmRleGVkIGNvbHVtbiwgdG8gYmUgdXNlZCB3aGVuIHRoZQorICAgICAqIHRpdGxlIG5lZWRzIHRvIGJlIGRpc3BsYXllZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2x1bW4gaW5kZXgsIHN0YXJ0aW5nIGF0IDEuCisgICAgICogQHJldHVybiB0aGUgY29sdW1uJ3MgdGl0bGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29sdW1uTGFiZWwoaW50IGNvbHVtbikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRpdGxlIG9mIHRoZSBpbmRleGVkIGNvbHVtbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2x1bW4gaW5kZXgsIHN0YXJ0aW5nIGF0IDEuCisgICAgICogQHJldHVybiB0aGUgY29sdW1uIHRpdGxlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbHVtbk5hbWUoaW50IGNvbHVtbikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgdGhlIGluZGV4ZWQgY29sdW1uIGFzIFNRTCB0eXBlIGNvZGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uCisgICAgICogICAgICAgICAgICB0aGUgY29sdW1uIGluZGV4LCBzdGFydGluZyBhdCAxLgorICAgICAqIEByZXR1cm4gdGhlIGNvbHVtbiB0eXBlIGNvZGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqIEBzZWUgVHlwZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldENvbHVtblR5cGUoaW50IGNvbHVtbikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHR5cGUgbmFtZSBvZiB0aGUgaW5kZXhlZCBjb2x1bW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uCisgICAgICogICAgICAgICAgICB0aGUgY29sdW1uIGluZGV4LCBzdGFydGluZyBhdCAxLgorICAgICAqIEByZXR1cm4gdGhlIHR5cGUgbmFtZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb2x1bW5UeXBlTmFtZShpbnQgY29sdW1uKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGVjaW1hbCBwcmVjaXNpb24gb2YgdGhlIGluZGV4ZWQgY29sdW1uLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbHVtbiBpbmRleCwgc3RhcnRpbmcgYXQgMS4KKyAgICAgKiBAcmV0dXJuIHRoZSBwcmVjaXNpb24uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UHJlY2lzaW9uKGludCBjb2x1bW4pIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZGlnaXRzIHRvIHRoZSByaWdodCBvZiB0aGUgZGVjaW1hbCBwb2ludCBvZiB0aGUKKyAgICAgKiBpbmRleGVkIGNvbHVtbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2x1bW4gaW5kZXgsIHN0YXJ0aW5nIGF0IDEuCisgICAgICogQHJldHVybiBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXMuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U2NhbGUoaW50IGNvbHVtbikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGluZGV4ZWQgY29sdW1ucyBzY2hlbWEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uCisgICAgICogICAgICAgICAgICB0aGUgY29sdW1uIGluZGV4LCBzdGFydGluZyBhdCAxLgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGNvbHVtbnMgc2NoZW1hLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFNjaGVtYU5hbWUoaW50IGNvbHVtbikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRpdGxlIG9mIHRoZSBpbmRleGVkIGNvbHVtbnMgdGFibGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uCisgICAgICogICAgICAgICAgICB0aGUgY29sdW1uIGluZGV4LCBzdGFydGluZyBhdCAxLgorICAgICAqIEByZXR1cm4gdGhlIHRhYmxlIHRpdGxlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFRhYmxlTmFtZShpbnQgY29sdW1uKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbmRpY2F0aW9uIG9mIHdoZXRoZXIgdGhlIGluZGV4ZWQgY29sdW1uIGlzIGF1dG9tYXRpY2FsbHkKKyAgICAgKiBpbmNyZW1lbnRlZCBhbmQgaXMgdGhlcmVmb3JlIHJlYWQtb25seS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2x1bW4gaW5kZXgsIHN0YXJ0aW5nIGF0IDEuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgaXQgaXMgYXV0b21hdGljYWxseSBudW1iZXJlZCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0F1dG9JbmNyZW1lbnQoaW50IGNvbHVtbikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5kaWNhdGlvbiBvZiB3aGV0aGVyIHRoZSBjYXNlIG9mIHRoZSBpbmRleGVkIGNvbHVtbiBpcworICAgICAqIGltcG9ydGFudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2x1bW4gaW5kZXgsIHN0YXJ0aW5nIGF0IDEuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgY2FzZSBtYXR0ZXJzLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDYXNlU2Vuc2l0aXZlKGludCBjb2x1bW4pIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIGluZGV4ZWQgY29sdW1uIGNvbnRhaW5zIGEgbW9uZXRhcnkgYW1vdW50LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbHVtbiBpbmRleCwgc3RhcnRpbmcgYXQgMS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBpdCBpcyBhIG1vbmV0YXJ5IHZhbHVlLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDdXJyZW5jeShpbnQgY29sdW1uKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbmRpY2F0aW9uIG9mIHdoZXRoZXIgd3JpdGluZyB0byB0aGUgaW5kZXhlZCBjb2x1bW4gaXMKKyAgICAgKiBndWFyYW50ZWVkIHRvIGJlIHN1Y2Nlc3NmdWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uCisgICAgICogICAgICAgICAgICB0aGUgY29sdW1uIGluZGV4LCBzdGFydGluZyBhdCAxLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSB3cml0ZSBpcyBndWFyYW50ZWVkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNEZWZpbml0ZWx5V3JpdGFibGUoaW50IGNvbHVtbikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgaW5kZXhlZCBjb2x1bW4gaXMgbnVsbGFibGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uCisgICAgICogICAgICAgICAgICB0aGUgY29sdW1uIGluZGV4LCBzdGFydGluZyBhdCAxLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGl0IGlzIG51bGxhYmxlLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIGludCBpc051bGxhYmxlKGludCBjb2x1bW4pIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGluZGljYXRpb24gb2Ygd2hldGhlciB3cml0aW5nIHRvIHRoZSBpbmRleGVkIGNvbHVtbiBpcworICAgICAqIGd1YXJhbnRlZWQgdG8gYmUgdW5zdWNjZXNzZnVsLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbHVtbiBpbmRleCwgc3RhcnRpbmcgYXQgMS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgY29sdW1uIGlzIHJlYWQtb25seSwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUmVhZE9ubHkoaW50IGNvbHVtbikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5kaWNhdGlvbiBvZiB3aGV0aGVyIHRoZSBpbmRleGVkIGNvbHVtbiBpcyBzZWFyY2hhYmxlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbHVtbiBpbmRleCwgc3RhcnRpbmcgYXQgMS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgaW5kZXhlZCBjb2x1bW4gaXMgc2VhcmNoYWJsZSwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NlYXJjaGFibGUoaW50IGNvbHVtbikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5kaWNhdGlvbiBvZiB3aGV0aGVyIHRoZSB2YWx1ZXMgY29udGFpbmVkIGluIHRoZSBpbmRleGVkCisgICAgICogY29sdW1uIGFyZSBzaWduZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uCisgICAgICogICAgICAgICAgICB0aGUgY29sdW1uIGluZGV4LCBzdGFydGluZyBhdCAxLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZXkgYXJlIHNpZ25lZCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzU2lnbmVkKGludCBjb2x1bW4pIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGluZGljYXRpb24gb2Ygd2hldGhlciB3cml0aW5nIHRvIHRoZSBpbmRleGVkIGNvbHVtbiBpcworICAgICAqIHBvc3NpYmxlLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbHVtbiBpbmRleCwgc3RhcnRpbmcgYXQgMS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBpdCBpcyBwb3NzaWJsZSB0byB3cml0ZSwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzV3JpdGFibGUoaW50IGNvbHVtbikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9Sb3dJZC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1Jvd0lkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjQ1N2JmNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9Sb3dJZC5qYXZhCkBAIC0wLDAgKzEsMzYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCisvKioKKyAqIE1hcHMgU1FMJ3MgUk9XSUQgdHlwZSBpbnRvIEphdmEuCisgKiBAc2luY2UgMS42CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUm93SWQgeworCisgICAgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGJ5dGVzIHJlcHJlc2VudGluZyB0aGUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgU1FMIFJPV0lELgorICAgICAqLworICAgIGJ5dGVbXSBnZXRCeXRlcygpOworCisgICAgU3RyaW5nIHRvU3RyaW5nKCk7CisKKyAgICBpbnQgaGFzaENvZGUoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9Sb3dJZExpZmV0aW1lLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvUm93SWRMaWZldGltZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFlMzU2NjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvUm93SWRMaWZldGltZS5qYXZhCkBAIC0wLDAgKzEsMjggQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCisvKioKKyAqIEFuIGVudW1lcmF0aW9uIHRvIGRlc2NyaWJlIHRoZSBsaWZlLXRpbWUgb2YgUm93SUQuCisgKgorICogQHNpbmNlIDEuNgorICovCitwdWJsaWMgZW51bSBSb3dJZExpZmV0aW1lIHsKKyAgICBST1dJRF9VTlNVUFBPUlRFRCwgUk9XSURfVkFMSURfT1RIRVIsIFJPV0lEX1ZBTElEX1NFU1NJT04sIFJPV0lEX1ZBTElEX1RSQU5TQUNUSU9OLAorICAgIFJPV0lEX1ZBTElEX0ZPUkVWRVIsCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTENsaWVudEluZm9FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxDbGllbnRJbmZvRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTFhZTdmNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxDbGllbnRJbmZvRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwyMTIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBBbiBleGNlcHRpb24sIHdoaWNoIGlzIHN1YmNsYXNzIG9mIFNRTEV4Y2VwdGlvbiwgaXMgdGhyb3duIHdoZW4gb25lIG9yIG1vcmUKKyAqIGNsaWVudCBpbmZvIHByb3BlcnRpZXMgY291bGQgbm90IGJlIHNldCBvbiBhIENvbm5lY3Rpb24uCisgKi8KK3B1YmxpYyBjbGFzcyBTUUxDbGllbnRJbmZvRXhjZXB0aW9uIGV4dGVuZHMgU1FMRXhjZXB0aW9uIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDMxOTYwNDI1NjgyNDY1NTg4MEw7CisKKyAgICBmaW5hbCBwcml2YXRlIE1hcDxTdHJpbmcsIENsaWVudEluZm9TdGF0dXM+IGZhaWxlZFByb3BlcnRpZXM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTENsaWVudEluZm9FeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8KKyAgICAgKiBudWxsLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byBudWxsIGFuZCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMQ2xpZW50SW5mb0V4Y2VwdGlvbigpIHsKKyAgICAgICAgdGhpcy5mYWlsZWRQcm9wZXJ0aWVzID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTENsaWVudEluZm9FeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8gdGhlCisgICAgICogZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gbnVsbCBhbmQgdGhlIEVycm9yCisgICAgICogQ29kZSBpcyBzZXQgdG8gMCwgYW5kIHRoZSBNYXA8U3RyaW5nLENsaWVudEluZm9TdGF0dXM+IG9iamVjdCBpcyBzZXQgdG8KKyAgICAgKiB0aGUgZmFpbGVkIHByb3BlcnRpZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmFpbGVkUHJvcGVydGllcworICAgICAqICAgICAgICAgICAgdGhlIE1hcDxTdHJpbmcsQ2xpZW50SW5mb1N0YXR1cz4gb2JqZWN0IHRvIHVzZSBhcyB0aGUKKyAgICAgKiAgICAgICAgICAgIHByb3BlcnR5IHZhbHVlcworICAgICAqLworICAgIHB1YmxpYyBTUUxDbGllbnRJbmZvRXhjZXB0aW9uKE1hcDxTdHJpbmcsIENsaWVudEluZm9TdGF0dXM+IGZhaWxlZFByb3BlcnRpZXMpIHsKKyAgICAgICAgdGhpcy5mYWlsZWRQcm9wZXJ0aWVzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBDbGllbnRJbmZvU3RhdHVzPihmYWlsZWRQcm9wZXJ0aWVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTENsaWVudEluZm9FeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8gdGhlCisgICAgICogbnVsbCBpZiBjYXVzZSA9PSBudWxsIG9yIGNhdXNlLnRvU3RyaW5nKCkgaWYgY2F1c2UhPW51bGwsIHRoZSBjYXVzZQorICAgICAqIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZSBUaHJvd2FibGUgb2JqZWN0LCBhbmQgdGhlIE1hcDxTdHJpbmcsQ2xpZW50SW5mb1N0YXR1cz4KKyAgICAgKiBvYmplY3QgaXMgc2V0IHRvIHRoZSBmYWlsZWQgcHJvcGVydGllcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmYWlsZWRQcm9wZXJ0aWVzCisgICAgICogICAgICAgICAgICB0aGUgTWFwPFN0cmluZyxDbGllbnRJbmZvU3RhdHVzPiBvYmplY3QgdG8gdXNlIGFzIHRoZQorICAgICAqICAgICAgICAgICAgcHJvcGVydHkgdmFsdWVzCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxDbGllbnRJbmZvRXhjZXB0aW9uKAorICAgICAgICAgICAgTWFwPFN0cmluZywgQ2xpZW50SW5mb1N0YXR1cz4gZmFpbGVkUHJvcGVydGllcywgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGNhdXNlKTsKKyAgICAgICAgdGhpcy5mYWlsZWRQcm9wZXJ0aWVzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBDbGllbnRJbmZvU3RhdHVzPihmYWlsZWRQcm9wZXJ0aWVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTENsaWVudEluZm9FeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8KKyAgICAgKiByZWFzb24sIGFuZCB0aGUgTWFwPFN0cmluZyxDbGllbnRJbmZvU3RhdHVzPiBvYmplY3QgaXMgc2V0IHRvIHRoZSBmYWlsZWQKKyAgICAgKiBwcm9wZXJ0aWVzLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gZmFpbGVkUHJvcGVydGllcworICAgICAqICAgICAgICAgICAgdGhlIE1hcDxTdHJpbmcsQ2xpZW50SW5mb1N0YXR1cz4gb2JqZWN0IHRvIHVzZSBhcyB0aGUKKyAgICAgKiAgICAgICAgICAgIHByb3BlcnR5IHZhbHVlcworICAgICAqLworICAgIHB1YmxpYyBTUUxDbGllbnRJbmZvRXhjZXB0aW9uKFN0cmluZyByZWFzb24sCisgICAgICAgICAgICBNYXA8U3RyaW5nLCBDbGllbnRJbmZvU3RhdHVzPiBmYWlsZWRQcm9wZXJ0aWVzKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbik7CisgICAgICAgIHRoaXMuZmFpbGVkUHJvcGVydGllcyA9IG5ldyBIYXNoTWFwPFN0cmluZywgQ2xpZW50SW5mb1N0YXR1cz4oZmFpbGVkUHJvcGVydGllcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxDbGllbnRJbmZvRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvCisgICAgICogcmVhc29uLCB0aGUgY2F1c2UgVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlIFRocm93YWJsZQorICAgICAqIG9iamVjdCwgYW5kIHRoZSBNYXA8U3RyaW5nLENsaWVudEluZm9TdGF0dXM+IG9iamVjdCBpcyBzZXQgdG8gdGhlIGZhaWxlZAorICAgICAqIHByb3BlcnRpZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBmYWlsZWRQcm9wZXJ0aWVzCisgICAgICogICAgICAgICAgICB0aGUgTWFwPFN0cmluZyxDbGllbnRJbmZvU3RhdHVzPiBvYmplY3QgdG8gdXNlIGFzIHRoZQorICAgICAqICAgICAgICAgICAgcHJvcGVydHkgdmFsdWVzCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxDbGllbnRJbmZvRXhjZXB0aW9uKFN0cmluZyByZWFzb24sCisgICAgICAgICAgICBNYXA8U3RyaW5nLCBDbGllbnRJbmZvU3RhdHVzPiBmYWlsZWRQcm9wZXJ0aWVzLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBjYXVzZSk7CisgICAgICAgIHRoaXMuZmFpbGVkUHJvcGVydGllcyA9IG5ldyBIYXNoTWFwPFN0cmluZywgQ2xpZW50SW5mb1N0YXR1cz4oZmFpbGVkUHJvcGVydGllcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxDbGllbnRJbmZvRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvCisgICAgICogcmVhc29uLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUgc3FsU3RhdGUsIHRoZSBFcnJvciBDb2RlIGlzIHNldAorICAgICAqIHRvIHRoZSB2ZW5kb3JDb2RlIGFuZCB0aGUgTWFwPFN0cmluZyxDbGllbnRJbmZvU3RhdHVzPiBvYmplY3QgaXMgc2V0IHRvCisgICAgICogdGhlIGZhaWxlZCBwcm9wZXJ0aWVzLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdmVuZG9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZSBlcnJvciBjb2RlCisgICAgICogQHBhcmFtIGZhaWxlZFByb3BlcnRpZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBNYXA8U3RyaW5nLENsaWVudEluZm9TdGF0dXM+IG9iamVjdCB0byB1c2UgYXMgdGhlCisgICAgICogICAgICAgICAgICBwcm9wZXJ0eSB2YWx1ZXMKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBTUUxDbGllbnRJbmZvRXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBzcWxTdGF0ZSwKKyAgICAgICAgICAgIGludCB2ZW5kb3JDb2RlLCBNYXA8U3RyaW5nLCBDbGllbnRJbmZvU3RhdHVzPiBmYWlsZWRQcm9wZXJ0aWVzKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIHZlbmRvckNvZGUpOworICAgICAgICB0aGlzLmZhaWxlZFByb3BlcnRpZXMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIENsaWVudEluZm9TdGF0dXM+KGZhaWxlZFByb3BlcnRpZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMQ2xpZW50SW5mb0V4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0bworICAgICAqIHJlYXNvbiwgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gdGhlIHNxbFN0YXRlLCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQKKyAgICAgKiB0byB0aGUgdmVuZG9yQ29kZSB0aGUgY2F1c2UgVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlCisgICAgICogVGhyb3dhYmxlIG9iamVjdCwgYW5kIHRoZSBNYXA8U3RyaW5nLENsaWVudEluZm9TdGF0dXM+IG9iamVjdCBpcyBzZXQgdG8KKyAgICAgKiB0aGUgZmFpbGVkIHByb3BlcnRpZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqIEBwYXJhbSB2ZW5kb3JDb2RlCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB2YWx1ZSBmb3IgdGhlIGVycm9yIGNvZGUKKyAgICAgKiBAcGFyYW0gZmFpbGVkUHJvcGVydGllcworICAgICAqICAgICAgICAgICAgdGhlIE1hcDxTdHJpbmcsQ2xpZW50SW5mb1N0YXR1cz4gb2JqZWN0IHRvIHVzZSBhcyB0aGUKKyAgICAgKiAgICAgICAgICAgIHByb3BlcnR5IHZhbHVlcworICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMQ2xpZW50SW5mb0V4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsCisgICAgICAgICAgICBpbnQgdmVuZG9yQ29kZSwgTWFwPFN0cmluZywgQ2xpZW50SW5mb1N0YXR1cz4gZmFpbGVkUHJvcGVydGllcywKKyAgICAgICAgICAgIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihyZWFzb24sIHNxbFN0YXRlLCB2ZW5kb3JDb2RlLCBjYXVzZSk7CisgICAgICAgIHRoaXMuZmFpbGVkUHJvcGVydGllcyA9IG5ldyBIYXNoTWFwPFN0cmluZywgQ2xpZW50SW5mb1N0YXR1cz4oZmFpbGVkUHJvcGVydGllcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxDbGllbnRJbmZvRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvCisgICAgICogcmVhc29uLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUgc3FsU3RhdGUsIGFuZCB0aGUgTWFwPFN0cmluZyxDbGllbnRJbmZvU3RhdHVzPgorICAgICAqIG9iamVjdCBpcyBzZXQgdG8gdGhlIGZhaWxlZCBwcm9wZXJ0aWVzLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gZmFpbGVkUHJvcGVydGllcworICAgICAqICAgICAgICAgICAgdGhlIE1hcDxTdHJpbmcsQ2xpZW50SW5mb1N0YXR1cz4gb2JqZWN0IHRvIHVzZSBhcyB0aGUKKyAgICAgKiAgICAgICAgICAgIHByb3BlcnR5IHZhbHVlcworICAgICAqLworICAgIHB1YmxpYyBTUUxDbGllbnRJbmZvRXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBzcWxTdGF0ZSwKKyAgICAgICAgICAgIE1hcDxTdHJpbmcsIENsaWVudEluZm9TdGF0dXM+IGZhaWxlZFByb3BlcnRpZXMpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSk7CisgICAgICAgIHRoaXMuZmFpbGVkUHJvcGVydGllcyA9IG5ldyBIYXNoTWFwPFN0cmluZywgQ2xpZW50SW5mb1N0YXR1cz4oZmFpbGVkUHJvcGVydGllcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxDbGllbnRJbmZvRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvCisgICAgICogcmVhc29uLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUgc3FsU3RhdGUsIHRoZSBFcnJvciBDb2RlIGlzIHNldAorICAgICAqIHRvIHRoZSB2ZW5kb3JDb2RlLCBhbmQgdGhlIE1hcDxTdHJpbmcsQ2xpZW50SW5mb1N0YXR1cz4gb2JqZWN0IGlzIHNldCB0bworICAgICAqIHRoZSBmYWlsZWQgcHJvcGVydGllcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICogQHBhcmFtIHNxbFN0YXRlCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgU1FMU3RhdGUgc3RyaW5nCisgICAgICogQHBhcmFtIGZhaWxlZFByb3BlcnRpZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBNYXA8U3RyaW5nLENsaWVudEluZm9TdGF0dXM+IG9iamVjdCB0byB1c2UgYXMgdGhlCisgICAgICogICAgICAgICAgICBwcm9wZXJ0eSB2YWx1ZXMKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTENsaWVudEluZm9FeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgU3RyaW5nIHNxbFN0YXRlLAorICAgICAgICAgICAgTWFwPFN0cmluZywgQ2xpZW50SW5mb1N0YXR1cz4gZmFpbGVkUHJvcGVydGllcywgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIGNhdXNlKTsKKyAgICAgICAgdGhpcy5mYWlsZWRQcm9wZXJ0aWVzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBDbGllbnRJbmZvU3RhdHVzPihmYWlsZWRQcm9wZXJ0aWVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiByZXR1cm5zIHRoYXQgdGhlIGNsaWVudCBpbmZvIHByb3BlcnRpZXMgd2hpY2ggY291bGQgbm90IGJlIHNldAorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGlzdCBvZiBDbGllbnRJbmZvU3RhdHVzIG9iamVjdHMgaW5kaWNhdGUgY2xpZW50IGluZm8KKyAgICAgKiAgICAgICAgIHByb3BlcnRpZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgTWFwPFN0cmluZywgQ2xpZW50SW5mb1N0YXR1cz4gZ2V0RmFpbGVkUHJvcGVydGllcygpIHsKKyAgICAgICAgcmV0dXJuIGZhaWxlZFByb3BlcnRpZXM7CisgICAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxEYXRhLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMRGF0YS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEyMmMwN2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMRGF0YS5qYXZhCkBAIC0wLDAgKzEsMTE0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworLyoqCisgKiBBbiBpbnRlcmZhY2UgZm9yIHRoZSBjdXN0b20gbWFwcGluZyBvZiBhbiBTUUwgPGk+VXNlciBEZWZpbmVkIFR5cGU8L2k+IChVRFQpCisgKiB0byBhIEphdmEgY2xhc3MuIFRoZSBKYXZhIGNsYXNzIG9iamVjdCBpcyBhZGRlZCB0byB0aGUgY29ubmVjdGlvbidzIHR5cGUgbWFwCisgKiBwYWlyZWQgd2l0aCB0aGUgU1FMIG5hbWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgVURULgorICogPHA+CisgKiBVc3VhbGx5IHdpdGhpbiBhbiBpbXBsZW1lbnRhdGlvbiBvZiB7QGNvZGUgU1FMRGF0YX0sIHRoZXJlIGlzIGEgY29ycmVzcG9uZGluZworICogZmllbGQgZm9yIGV2ZXJ5IGF0dHJpYnV0ZSBvZiBhbiBTUUwgdHlwZSwgYnV0IG9ubHkgb25lIGZpZWxkLCBpZiB0aGUgdHlwZSBpcworICogU1FMIHtAY29kZSBESVNUSU5DVH0uIFdoZW4gdGhlIFVEVCBpcyByZXR1cm5lZCB3aXRoaW4gYSB7QGNvZGUgUmVzdWx0U2V0fSwgaXQKKyAqIGlzIGFjY2Vzc2VkIHdpdGggdGhlIHtAbGluayBSZXN1bHRTZXQjZ2V0T2JqZWN0fSBtZXRob2QgYW5kIGlzIHJldHVybmVkIGFzIGFuCisgKiBvYmplY3Qgd2hpY2ggaXMgYW4gaW5zdGFuY2Ugb2YgdGhlIGNsYXNzIGRlZmluZWQgYnkgdGhlIHtAY29kZSBTUUxEYXRhfQorICogbWFwcGluZy4gVGhlIGFwcGxpY2F0aW9uIGNhbiB1c2UgdGhpcyBvYmplY3QganVzdCBsaWtlIGFueSBvdGhlciBKYXZhIG9iamVjdAorICogYW5kIGNhbiBzdG9yZSBjaGFuZ2VzIGJhY2sgaW50byB0aGUgZGF0YWJhc2UgdXNpbmcgdGhlCisgKiB7QGxpbmsgUHJlcGFyZWRTdGF0ZW1lbnQjc2V0T2JqZWN0fSBtZXRob2Qgd2hpY2ggcGVyZm9ybXMgdGhlIHJldmVyc2UgbWFwcGluZworICogaW50byB0aGUgU1FMIHtAY29kZSBVRFR9LgorICogPHA+CisgKiBOb3JtYWxseSB0aGUgaW1wbGVtZW50YXRpb24gb2YgYSBjdXN0b20gbWFwcGluZyBpcyBnZW5lcmF0ZWQgYnkKKyAqIGEgdG9vbCByZXF1aXJpbmcgdGhlIG5hbWUgb2YgdGhlIFNRTCB7QGNvZGUgVURUfSwgdGhlIG5hbWUKKyAqIG9mIHRoZSBjbGFzcyB3aGljaCBpdCBpcyBnb2luZyB0byBiZSBtYXBwZWQgdG8sIGFuZCB0aGUgZmllbGQgbmFtZXMgdG8gd2hpY2gKKyAqIHRoZSBVRFQgYXR0cmlidXRlcyBhcmUgbWFwcGVkLiBUaGUgdG9vbCBjYW4gdGhlbiBpbXBsZW1lbnQgdGhlIHtAY29kZQorICogU1FMRGF0YX0sIHtAY29kZSByZWFkU1FMfSwgYW5kIHtAY29kZSB3cml0ZVNRTH0gbWV0aG9kcy4ge0Bjb2RlIHJlYWRTUUx9IHJlYWRzCisgKiBhdHRyaWJ1dGVzIGZyb20gYW4ge0Bjb2RlIFNRTElucHV0fSBvYmplY3QsIGFuZCB7QGNvZGUgd3JpdGVTUUx9IHdyaXRlcyB0aGVtLgorICogVGhpcyBpcyBkb25lIHZpYSB7QGNvZGUgU1FMSW5wdXR9IGFuZCB7QGNvZGUgU1FMT3V0cHV0fSBtZXRob2QgY2FsbHMKKyAqIHJlc3BlY3RpdmVseS4KKyAqIDxwPgorICogT3JkaW5hcmlseSBhbiBhcHBsaWNhdGlvbiB3b3VsZCBub3QgY2FsbCB7QGNvZGUgU1FMRGF0YX0gbWV0aG9kcyBkaXJlY3RseS4KKyAqIFNpbWlsYXJseSB7QGNvZGUgU1FMSW5wdXR9IGFuZCB7QGNvZGUgU1FMT3V0cHV0fSBtZXRob2RzIGFyZSBub3QgdXN1YWxseQorICogY2FsbGVkIGRpcmVjdGx5LgorICovCitwdWJsaWMgaW50ZXJmYWNlIFNRTERhdGEgeworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgU1FMIG5hbWUgb2YgdGhlIDxpPlVzZXIgRGVmaW5lZCBUeXBlPC9pPiAoVURUKSB0aGF0IHRoaXMgb2JqZWN0CisgICAgICogcmVwcmVzZW50cy4gVGhpcyBtZXRob2QsIHVzdWFsbHkgaW52b2tlZCBieSB0aGUgSkRCQyBkcml2ZXIsIHJldHJpZXZlcworICAgICAqIHRoZSBuYW1lIG9mIHRoZSBVRFQgaW5zdGFuY2UgYXNzb2NpYXRlZCB3aXRoIHRoaXMge0Bjb2RlIFNRTERhdGF9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgd2l0aCBVRFQgdHlwZSBuYW1lIGZvciB0aGlzIG9iamVjdCBtYXBwaW5nLCBwYXNzZWQgdG8KKyAgICAgKiAgICAgICAgIHtAY29kZSByZWFkU1FMfSB3aGVuIHRoZSBvYmplY3Qgd2FzIGNyZWF0ZWQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFNRTFR5cGVOYW1lKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlYWRzIGRhdGEgZnJvbSB0aGUgZGF0YWJhc2UgaW50byB0aGlzIG9iamVjdC4gVGhpcyBtZXRob2QgZm9sbG93cyB0aGVzZQorICAgICAqIHN0ZXBzOgorICAgICAqIDxwPgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+VXRpbGl6ZSB0aGUgcGFzc2VkIGlucHV0IHN0cmVhbSB0byByZWFkIHRoZSBhdHRyaWJ1dGVzIG9yIGVudHJpZXMgb2YKKyAgICAgKiB0aGUgU1FMIHR5cGU8L2xpPgorICAgICAqIDxsaT5UaGlzIGlzIGNhcnJpZWQgb3V0IGJ5IHJlYWRpbmcgZWFjaCBlbnRyeSBmcm9tIHRoZSBpbnB1dCBzdHJlYW0sCisgICAgICogb3JkZXJlZCBhcyB0aGV5IGFyZSBpbiB0aGUgU1FMIGRlZmluaXRpb24uPC9saT4KKyAgICAgKiA8bGk+QXNzaWduIHRoZSBkYXRhIHRvIHRoZSBhcHByb3ByaWF0ZSBmaWVsZHMgb3IgZWxlbWVudHMuIFRoaXMgaXMgZG9uZQorICAgICAqIGJ5IGNhbGxpbmcgdGhlIHJlbGV2YW50IHJlYWRlciBtZXRob2QgZm9yIHRoZSB0eXBlIGludm9sdmVkIChlLmcuIHtAY29kZQorICAgICAqIFNRTElucHV0LnJlYWRTdHJpbmd9LCB7QGNvZGUgU1FMSW5wdXRyZWFkQmlnRGVjaW1hbH0pLiBJZiB0aGUgdHlwZSBpcworICAgICAqIGRpc3RpbmN0LCB0aGVuIHJlYWQgaXRzIG9ubHkgZGF0YSBlbnRyeS4gRm9yIHN0cnVjdHVyZWQgdHlwZXMsIHJlYWQgZXZlcnkKKyAgICAgKiBlbnRyeS48L2xpPgorICAgICAqIDwvdWw+CisgICAgICogPHA+CisgICAgICogVGhlIHN1cHBsaWVkIGlucHV0IHN0cmVhbSBpcyB0eXBpY2FsbHkgaW5pdGlhbGl6ZWQgYnkgdGhlIGNhbGxpbmcgSkRCQworICAgICAqIGRyaXZlciB3aXRoIHRoZSB0eXBlIG1hcCBiZWZvcmUge0Bjb2RlIHJlYWRTUUx9IGlzIGNhbGxlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgU1FMSW5wdXR9IHN0cmVhbSBmcm9tIHdoaWNoIHRoZSB0eXBlIG1hcCBkYXRhIGlzCisgICAgICogICAgICAgICAgICByZWFkIGZvciB0aGUgY3VzdG9tIG1hcHBpbmcuCisgICAgICogQHBhcmFtIHR5cGVOYW1lCisgICAgICogICAgICAgICAgICB0aGUgU1FMIHR5cGUgbmFtZSBmb3IgdGhlIHR5cGUgd2hpY2ggaXMgYmVpbmcgbWFwcGVkLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSBTUUxJbnB1dAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlYWRTUUwoU1FMSW5wdXQgc3RyZWFtLCBTdHJpbmcgdHlwZU5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIG9iamVjdCB0byBhIHN1cHBsaWVkIHtAY29kZSBTUUxPdXRwdXR9IGRhdGEgc3RyZWFtLCB3cml0aW5nIGl0CisgICAgICogb3V0IGFzIGFuIFNRTCB2YWx1ZSB0byB0aGUgZGF0YSBzb3VyY2UuCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgZm9sbG93cyB0aGUgZm9sbG93aW5nIHN0ZXBzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+V3JpdGUgZWFjaCBhdHRyaWJ1dGUgb2YgdGhlIFNRTCB0eXBlIHRvIHRoZSBvdXRwdXQgc3RyZWFtLjwvbGk+CisgICAgICogPGxpPldyaXRlIGVhY2ggaXRlbSBieSBjYWxsaW5nIGEgbWV0aG9kIG9uIHRoZSBvdXRwdXQgc3RyZWFtLCBpbiB0aGUKKyAgICAgKiBvcmRlciB0aGV5IGFwcGVhciBpbiB0aGUgU1FMIGRlZmluaXRpb24gb2YgdGhlIHR5cGUuIFVzZSB0aGUgYXBwcm9wcmlhdGUKKyAgICAgKiB7QGNvZGUgU1FMT3V0cHV0fSBtZXRob2RzIChlLmcuIHtAY29kZSB3cml0ZUludH0sIHtAY29kZSB3cml0ZVN0cmluZ30pLgorICAgICAqIFdyaXRlIGEgc2luZ2xlIGRhdGEgZWxlbWVudCBmb3IgYSBkaXN0aW5jdCB0eXBlLiBGb3IgYSBzdHJ1Y3R1cmVkIHR5cGUsCisgICAgICogd3JpdGUgYSB2YWx1ZSBmb3IgZWFjaCBhdHRyaWJ1dGUgb2YgdGhlIHRoZSBTUUwgdHlwZS48L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyZWFtCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIFNRTE91dHB1dH0gc3RyZWFtIHRvIHVzZSB0byB3cml0ZSBvdXQgdGhlIGRhdGEgZm9yCisgICAgICogICAgICAgICAgICB0aGUgY3VzdG9tIG1hcHBpbmcuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlIFNRTE91dHB1dAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlU1FMKFNRTE91dHB1dCBzdHJlYW0pIHRocm93cyBTUUxFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMRGF0YUV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTERhdGFFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYWZhYjI1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTERhdGFFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDE0NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zcWw7CisKKy8qKgorICogQW4gZXhjZXB0aW9uLCB3aGljaCBpcyBzdWJjbGFzcyBvZiBTUUxFeGNlcHRpb24sIGlzIHRocm93biB3aGVuIHZhcmlvdXMgZGF0YQorICogZXJyb3JzIGFyaXNlLiBUaGVzZSBlcnJvcnMgaW5jbHVkaW5nIGRpdmlzaW9uIGJ5IDAgYW5kIGludmFsaWQgYXJndW1lbnRzIHRvCisgKiBmdW5jdGlvbnMKKyAqLworcHVibGljIGNsYXNzIFNRTERhdGFFeGNlcHRpb24gZXh0ZW5kcyBTUUxOb25UcmFuc2llbnRFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTY4ODkxMjMyODI2NzA1NDk4MDBMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxEYXRhRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvIG51bGwsIHRoZQorICAgICAqIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gbnVsbCBhbmQgdGhlIEVycm9yIENvZGUgaXMgc2V0IHRvIDAuCisgICAgICovCisgICAgcHVibGljIFNRTERhdGFFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxEYXRhRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbgorICAgICAqIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIG51bGwgYW5kIHRoZSBFcnJvciBDb2RlIGlzCisgICAgICogc2V0IHRvIDAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqLworICAgIHB1YmxpYyBTUUxEYXRhRXhjZXB0aW9uKFN0cmluZyByZWFzb24pIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBudWxsLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTERhdGFFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8gdGhlIGdpdmVuCisgICAgICogcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gdGhlIGdpdmVuIFNRTFN0YXRlIHN0cmluZworICAgICAqIGFuZCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gMC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICogQHBhcmFtIHNxbFN0YXRlCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgU1FMU3RhdGUgc3RyaW5nCisgICAgICovCisgICAgcHVibGljIFNRTERhdGFFeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgU3RyaW5nIHNxbFN0YXRlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMRGF0YUV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4KKyAgICAgKiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4gU1FMU3RhdGUgc3RyaW5nCisgICAgICogYW5kIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byB0aGUgZ2l2ZW4gZXJyb3IgY29kZSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICogQHBhcmFtIHNxbFN0YXRlCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgU1FMU3RhdGUgc3RyaW5nCisgICAgICogQHBhcmFtIHZlbmRvckNvZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlZ2VyIHZhbHVlIGZvciB0aGUgZXJyb3IgY29kZQorICAgICAqLworICAgIHB1YmxpYyBTUUxEYXRhRXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBzcWxTdGF0ZSwgaW50IHZlbmRvckNvZGUpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgdmVuZG9yQ29kZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxEYXRhRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvIHRoZSBudWxsCisgICAgICogaWYgY2F1c2UgPT0gbnVsbCBvciBjYXVzZS50b1N0cmluZygpIGlmIGNhdXNlIT1udWxsLGFuZCB0aGUgY2F1c2UKKyAgICAgKiBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UgVGhyb3dhYmxlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMRGF0YUV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMRGF0YUV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4KKyAgICAgKiBhbmQgdGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZSBUaHJvd2FibGUKKyAgICAgKiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMRGF0YUV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxEYXRhRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbgorICAgICAqIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbiBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBhbmQgdGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZSBUaHJvd2FibGUKKyAgICAgKiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMRGF0YUV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihyZWFzb24sIHNxbFN0YXRlLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxEYXRhRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbgorICAgICAqIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbiBTUUxTdGF0ZSBzdHJpbmcgLAorICAgICAqIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byB0aGUgZ2l2ZW4gZXJyb3IgY29kZSB2YWx1ZSwgYW5kIHRoZSBjYXVzZQorICAgICAqIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZSBUaHJvd2FibGUgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdmVuZG9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZSBlcnJvciBjb2RlCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxEYXRhRXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBzcWxTdGF0ZSwgaW50IHZlbmRvckNvZGUsCisgICAgICAgICAgICBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgdmVuZG9yQ29kZSwgY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYjY1MGRhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMjYwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKKworLyoqCisgKiBBbiBleGNlcHRpb24gdGhhdCBpbmRpY2F0ZXMgYSBmYWlsZWQgSkRCQyBvcGVyYXRpb24uCisgKiBJdCBwcm92aWRlcyB0aGUgZm9sbG93aW5nIGluZm9ybWF0aW9uIGFib3V0IHByb2JsZW1zIGVuY291bnRlcmVkIHdpdGgKKyAqIGRhdGFiYXNlIGFjY2VzczoKKyAqIDx1bD4KKyAqICAgPGxpPkEgbWVzc2FnZSBzdHJpbmcuPC9saT4KKyAqICAgPGxpPkEge0Bjb2RlIFNRTFN0YXRlfSBlcnJvciBkZXNjcmlwdGlvbiBzdHJpbmcgZm9sbG93aW5nIGVpdGhlcgorICogPGEgaHJlZj0iaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TUUw6MTk5OSI+U1FMIDk5PC9hPiBvciBYL09QRU4ge0Bjb2RlIFNRTFN0YXRlfQorICogY29udmVudGlvbnMuIHtAbGluayBEYXRhYmFzZU1ldGFEYXRhI2dldFNRTFN0YXRlVHlwZX0gZXhwb3NlcyB0aGUgc3BlY2lmaWMgY29udmVudGlvbiBpbgorICogdXNlLjwvbGk+CisgKiAgIDxsaT5BIGRhdGFiYXNlLXNwZWNpZmljIGVycm9yIGNvZGUuPC9saT4KKyAqICAgPGxpPlRoZSBuZXh0IGV4Y2VwdGlvbiBpbiB0aGUgY2hhaW4uPC9saT4KKyAqIDwvdWw+CisgKgorICogQHNlZSBEYXRhYmFzZU1ldGFEYXRhCisgKi8KK3B1YmxpYyBjbGFzcyBTUUxFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24gaW1wbGVtZW50cyBTZXJpYWxpemFibGUsIEl0ZXJhYmxlPFRocm93YWJsZT4geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjEzNTI0NDA5NDM5NjMzMTQ4NEw7CisKKyAgICBwcml2YXRlIFN0cmluZyBTUUxTdGF0ZSA9IG51bGw7CisKKyAgICBwcml2YXRlIGludCB2ZW5kb3JDb2RlID0gMDsKKworICAgIHByaXZhdGUgU1FMRXhjZXB0aW9uIG5leHQgPSBudWxsOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiB7QGNvZGUgU1FMRXhjZXB0aW9ufSBvYmplY3QuIFRoZSByZWFzb24gc3RyaW5nIGlzIHNldCB0bworICAgICAqIHtAY29kZSBudWxsfSwgdGhlIHtAY29kZSBTUUxTdGF0ZX0gc3RyaW5nIGlzIHNldCB0byB7QGNvZGUgbnVsbH0gYW5kIHRoZQorICAgICAqIGVycm9yIGNvZGUgaXMgc2V0IHRvIDAuCisgICAgICovCisgICAgcHVibGljIFNRTEV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIHtAY29kZSBTUUxFeGNlcHRpb259IG9iamVjdC4gVGhlIHJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbgorICAgICAqIHJlYXNvbiBzdHJpbmcsIHRoZSB7QGNvZGUgU1FMU3RhdGV9IHN0cmluZyBpcyBzZXQgdG8ge0Bjb2RlIG51bGx9IGFuZCB0aGUgZXJyb3IgY29kZSBpcworICAgICAqIHNldCB0byAwLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZVJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMRXhjZXB0aW9uKFN0cmluZyB0aGVSZWFzb24pIHsKKyAgICAgICAgdGhpcyh0aGVSZWFzb24sIG51bGwsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4ge0Bjb2RlIFNRTEV4Y2VwdGlvbn0gb2JqZWN0LiBUaGUgcmVhc29uIHN0cmluZyBpcyBzZXQgdG8gdGhlCisgICAgICogZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIHtAY29kZSBTUUxTdGF0ZX0gc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4KKyAgICAgKiB7QGNvZGUgU1FMU3RhdGV9IHN0cmluZyBhbmQgdGhlIGVycm9yIGNvZGUgaXMgc2V0IHRvIDAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlUmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgcmVhc29uIHN0cmluZy4KKyAgICAgKiBAcGFyYW0gdGhlU1FMU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSB7QGNvZGUgU1FMU3RhdGV9IHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMRXhjZXB0aW9uKFN0cmluZyB0aGVSZWFzb24sIFN0cmluZyB0aGVTUUxTdGF0ZSkgeworICAgICAgICB0aGlzKHRoZVJlYXNvbiwgdGhlU1FMU3RhdGUsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4ge0Bjb2RlIFNRTEV4Y2VwdGlvbn0gb2JqZWN0LiBUaGUgcmVhc29uIHN0cmluZyBpcyBzZXQgdG8gdGhlCisgICAgICogZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIHtAY29kZSBTUUxTdGF0ZX0gc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4KKyAgICAgKiB7QGNvZGUgU1FMU3RhdGV9IHN0cmluZyBhbmQgdGhlIGVycm9yIGNvZGUgaXMgc2V0IHRvIHRoZSBnaXZlbiBlcnJvciBjb2RlCisgICAgICogdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlUmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgcmVhc29uIHN0cmluZy4KKyAgICAgKiBAcGFyYW0gdGhlU1FMU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSB7QGNvZGUgU1FMU3RhdGV9IHN0cmluZy4KKyAgICAgKiBAcGFyYW0gdGhlRXJyb3JDb2RlCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB2YWx1ZSBmb3IgdGhlIGVycm9yIGNvZGUuCisgICAgICovCisgICAgcHVibGljIFNRTEV4Y2VwdGlvbihTdHJpbmcgdGhlUmVhc29uLCBTdHJpbmcgdGhlU1FMU3RhdGUsIGludCB0aGVFcnJvckNvZGUpIHsKKyAgICAgICAgc3VwZXIodGhlUmVhc29uKTsKKyAgICAgICAgU1FMU3RhdGUgPSB0aGVTUUxTdGF0ZTsKKyAgICAgICAgdmVuZG9yQ29kZSA9IHRoZUVycm9yQ29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTEV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0byB0aGUgbnVsbCBpZgorICAgICAqIGNhdXNlID09IG51bGwgb3IgY2F1c2UudG9TdHJpbmcoKSBpZiBjYXVzZSE9bnVsbCxhbmQgdGhlIGNhdXNlIFRocm93YWJsZQorICAgICAqIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlQ2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIFNRTEV4Y2VwdGlvbihUaHJvd2FibGUgdGhlQ2F1c2UpIHsKKyAgICAgICAgdGhpcyh0aGVDYXVzZSA9PSBudWxsID8gbnVsbCA6IHRoZUNhdXNlLnRvU3RyaW5nKCksIG51bGwsIDAsIHRoZUNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTEV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4gYW5kCisgICAgICogdGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZSBUaHJvd2FibGUgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHRoZVJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdGhlQ2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIFNRTEV4Y2VwdGlvbihTdHJpbmcgdGhlUmVhc29uLCBUaHJvd2FibGUgdGhlQ2F1c2UpIHsKKyAgICAgICAgc3VwZXIodGhlUmVhc29uLCB0aGVDYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8gdGhlIGdpdmVuCisgICAgICogcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gdGhlIGdpdmVuIFNRTFN0YXRlIHN0cmluZworICAgICAqIGFuZCB0aGUgY2F1c2UgVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlIFRocm93YWJsZQorICAgICAqIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVSZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICogQHBhcmFtIHRoZVNRTFN0YXRlCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgU1FMU3RhdGUgc3RyaW5nCisgICAgICogQHBhcmFtIHRoZUNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMRXhjZXB0aW9uKFN0cmluZyB0aGVSZWFzb24sIFN0cmluZyB0aGVTUUxTdGF0ZSwgVGhyb3dhYmxlIHRoZUNhdXNlKSB7CisgICAgICAgIHN1cGVyKHRoZVJlYXNvbiwgdGhlQ2F1c2UpOworICAgICAgICBTUUxTdGF0ZSA9IHRoZVNRTFN0YXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbgorICAgICAqIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbiBTUUxTdGF0ZSBzdHJpbmcgLAorICAgICAqIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byB0aGUgZ2l2ZW4gZXJyb3IgY29kZSB2YWx1ZSwgYW5kIHRoZSBjYXVzZQorICAgICAqIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZSBUaHJvd2FibGUgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHRoZVJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdGhlU1FMU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdGhlRXJyb3JDb2RlCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB2YWx1ZSBmb3IgdGhlIGVycm9yIGNvZGUKKyAgICAgKiBAcGFyYW0gdGhlQ2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBTUUxFeGNlcHRpb24oU3RyaW5nIHRoZVJlYXNvbiwgU3RyaW5nIHRoZVNRTFN0YXRlLCBpbnQgdGhlRXJyb3JDb2RlLAorICAgICAgICAgICAgVGhyb3dhYmxlIHRoZUNhdXNlKSB7CisgICAgICAgIHRoaXModGhlUmVhc29uLCB0aGVTUUxTdGF0ZSwgdGhlQ2F1c2UpOworICAgICAgICB2ZW5kb3JDb2RlID0gdGhlRXJyb3JDb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGludGVnZXIgZXJyb3IgY29kZSBmb3IgdGhpcyB7QGNvZGUgU1FMRXhjZXB0aW9ufS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIGludGVnZXIgZXJyb3IgY29kZSBmb3IgdGhpcyB7QGNvZGUgU1FMRXhjZXB0aW9ufS4gVGhlIG1lYW5pbmcKKyAgICAgKiAgICAgICAgIG9mIHRoZSBjb2RlIGlzIHNwZWNpZmljIHRvIHRoZSB2ZW5kb3Igb2YgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RXJyb3JDb2RlKCkgeworICAgICAgICByZXR1cm4gdmVuZG9yQ29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgdGhlIHtAY29kZSBTUUxFeGNlcHRpb259IGNoYWluZWQgdG8gdGhpcyB7QGNvZGUgU1FMRXhjZXB0aW9ufSwKKyAgICAgKiBpZiBhbnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSB7QGNvZGUgU1FMRXhjZXB0aW9ufSBjaGFpbmVkIHRvIHRoaXMge0Bjb2RlIFNRTEV4Y2VwdGlvbn0uCisgICAgICogICAgICAgICB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgaXMgbm8ge0Bjb2RlIFNRTEV4Y2VwdGlvbn0gY2hhaW5lZCB0byB0aGlzCisgICAgICogICAgICAgICB7QGNvZGUgU1FMRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMRXhjZXB0aW9uIGdldE5leHRFeGNlcHRpb24oKSB7CisgICAgICAgIHJldHVybiBuZXh0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyB0aGUge0Bjb2RlIFNRTFN0YXRlfSBkZXNjcmlwdGlvbiBzdHJpbmcgZm9yIHRoaXMge0Bjb2RlCisgICAgICogU1FMRXhjZXB0aW9ufSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSB7QGNvZGUgU1FMU3RhdGV9IHN0cmluZyBmb3IgdGhpcyB7QGNvZGUgU1FMRXhjZXB0aW9ufSBvYmplY3QuCisgICAgICogICAgICAgICBUaGlzIGlzIGFuIGVycm9yIGRlc2NyaXB0aW9uIHN0cmluZyB3aGljaCBmb2xsb3dzIGVpdGhlciB0aGUgU1FMCisgICAgICogICAgICAgICA5OSBjb252ZW50aW9ucyBvciB0aGUgWC9PUEVOIHtAY29kZSBTUUxzdGF0ZX0gY29udmVudGlvbnMuIFRoZQorICAgICAqICAgICAgICAgcG90ZW50aWFsIHZhbHVlcyBvZiB0aGUge0Bjb2RlIFNRTFN0YXRlfSBzdHJpbmcgYXJlIGRlc2NyaWJlZCBpbgorICAgICAqICAgICAgICAgZWFjaCBvZiB0aGUgc3BlY2lmaWNhdGlvbnMuIFdoaWNoIG9mIHRoZSBjb252ZW50aW9ucyBpcyBiZWluZworICAgICAqICAgICAgICAgdXNlZCBieSB0aGUge0Bjb2RlIFNRTFN0YXRlfSBzdHJpbmcgY2FuIGJlIGRpc2NvdmVyZWQgYnkgdXNpbmcKKyAgICAgKiAgICAgICAgIHRoZSB7QGNvZGUgZ2V0U1FMU3RhdGVUeXBlfSBtZXRob2Qgb2YgdGhlIHtAY29kZQorICAgICAqICAgICAgICAgRGF0YWJhc2VNZXRhRGF0YX0gaW50ZXJmYWNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U1FMU3RhdGUoKSB7CisgICAgICAgIHJldHVybiBTUUxTdGF0ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPYnNvbGV0ZS4gQXBwZW5kcyB7QGNvZGUgZXh9IHRvIHRoZSBlbmQgb2YgdGhpcyBjaGFpbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROZXh0RXhjZXB0aW9uKFNRTEV4Y2VwdGlvbiBleCkgeworICAgICAgICBpZiAobmV4dCAhPSBudWxsKSB7CisgICAgICAgICAgICBuZXh0LnNldE5leHRFeGNlcHRpb24oZXgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbmV4dCA9IGV4OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogT2Jzb2xldGUuIHtAbGluayAjZ2V0Q2F1c2UoKX0gc2hvdWxkIGJlIHVzZWQgaW5zdGVhZCBvZiB0aGlzIGl0ZXJhdG9yLiBSZXR1cm5zIGFuIGl0ZXJhdG9yCisgICAgICogb3ZlciB0aGUgZXhjZXB0aW9ucyBhZGRlZCB3aXRoIHtAbGluayAjc2V0TmV4dEV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIEl0ZXJhdG9yPFRocm93YWJsZT4gaXRlcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBuZXcgSW50ZXJuYWxJdGVyYXRvcih0aGlzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBJbnRlcm5hbEl0ZXJhdG9yIGltcGxlbWVudHMgSXRlcmF0b3I8VGhyb3dhYmxlPiB7CisKKyAgICAgICAgcHJpdmF0ZSBTUUxFeGNlcHRpb24gY3VycmVudDsKKworICAgICAgICBJbnRlcm5hbEl0ZXJhdG9yKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBjdXJyZW50ID0gZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICByZXR1cm4gY3VycmVudCAhPSBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFRocm93YWJsZSBuZXh0KCkgeworICAgICAgICAgICAgaWYgKGN1cnJlbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTUUxFeGNlcHRpb24gcmV0ID0gY3VycmVudDsKKyAgICAgICAgICAgIGN1cnJlbnQgPSBjdXJyZW50Lm5leHQ7CisgICAgICAgICAgICByZXR1cm4gcmV0OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMRmVhdHVyZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTEZlYXR1cmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNWY0ZmU0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTEZlYXR1cmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDE0NyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zcWw7CisKKy8qKgorICogQW4gZXhjZXB0aW9uLCB3aGljaCBpcyBzdWJjbGFzcyBvZiBTUUxOb25UcmFuc2llbnRFeGNlcHRpb24sIGlzIHRocm93biB3aGVuCisgKiB2YXJpb3VzIHRoZSBKREJDIGRyaXZlciBkb2VzIG5vdCBzdXBwb3J0IGFuIG9wdGlvbmFsIEpEQkMgZmVhdHVyZS4KKyAqLworcHVibGljIGNsYXNzIFNRTEZlYXR1cmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZXh0ZW5kcyBTUUxOb25UcmFuc2llbnRFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTEwMjY1MTA4NzAyODIzMTYwNTFMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxGZWF0dXJlTm90U3VwcG9ydGVkRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMKKyAgICAgKiBzZXQgdG8gbnVsbCwgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gbnVsbCBhbmQgdGhlIEVycm9yIENvZGUgaXMgc2V0CisgICAgICogdG8gMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMRmVhdHVyZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTEZlYXR1cmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcworICAgICAqIHNldCB0byB0aGUgZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gbnVsbCBhbmQKKyAgICAgKiB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gMC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICovCisgICAgcHVibGljIFNRTEZlYXR1cmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24oU3RyaW5nIHJlYXNvbikgeworICAgICAgICBzdXBlcihyZWFzb24sIG51bGwsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMRmVhdHVyZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzCisgICAgICogc2V0IHRvIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4KKyAgICAgKiBTUUxTdGF0ZSBzdHJpbmcgYW5kIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byAwLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMRmVhdHVyZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxGZWF0dXJlTm90U3VwcG9ydGVkRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMKKyAgICAgKiBzZXQgdG8gdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbgorICAgICAqIFNRTFN0YXRlIHN0cmluZyBhbmQgdGhlIEVycm9yIENvZGUgaXMgc2V0IHRvIHRoZSBnaXZlbiBlcnJvciBjb2RlIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdmVuZG9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZSBlcnJvciBjb2RlCisgICAgICovCisgICAgcHVibGljIFNRTEZlYXR1cmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgU3RyaW5nIHNxbFN0YXRlLAorICAgICAgICAgICAgaW50IHZlbmRvckNvZGUpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgdmVuZG9yQ29kZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxGZWF0dXJlTm90U3VwcG9ydGVkRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMKKyAgICAgKiBzZXQgdG8gdGhlIG51bGwgaWYgY2F1c2UgPT0gbnVsbCBvciBjYXVzZS50b1N0cmluZygpIGlmIGNhdXNlIT1udWxsLGFuZAorICAgICAqIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UgVGhyb3dhYmxlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMRmVhdHVyZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMRmVhdHVyZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzCisgICAgICogc2V0IHRvIHRoZSBnaXZlbiBhbmQgdGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZQorICAgICAqIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMRmVhdHVyZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxGZWF0dXJlTm90U3VwcG9ydGVkRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMKKyAgICAgKiBzZXQgdG8gdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbgorICAgICAqIFNRTFN0YXRlIHN0cmluZyBhbmQgdGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZQorICAgICAqIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMRmVhdHVyZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsCisgICAgICAgICAgICBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMRmVhdHVyZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzCisgICAgICogc2V0IHRvIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4KKyAgICAgKiBTUUxTdGF0ZSBzdHJpbmcgLCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gdGhlIGdpdmVuIGVycm9yIGNvZGUgdmFsdWUsCisgICAgICogYW5kIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UgVGhyb3dhYmxlCisgICAgICogb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdmVuZG9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZSBlcnJvciBjb2RlCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxGZWF0dXJlTm90U3VwcG9ydGVkRXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBzcWxTdGF0ZSwKKyAgICAgICAgICAgIGludCB2ZW5kb3JDb2RlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgdmVuZG9yQ29kZSwgY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxJbnB1dC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTElucHV0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzQ3YjAzNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxJbnB1dC5qYXZhCkBAIC0wLDAgKzEsMzU4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CitpbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7CitpbXBvcnQgamF2YS5uZXQuVVJMOworCisvKioKKyAqIFRoZSB7QGNvZGUgU1FMSW5wdXR9IGludGVyZmFjZSBkZWZpbmVzIG9wZXJhdGlvbnMgd2hpY2ggYXBwbHkgdG8gYSB0eXBlIG9mCisgKiBpbnB1dCBzdHJlYW0gd2hpY2ggY2FycmllcyBhIHNlcmllcyBvZiB2YWx1ZXMgcmVwcmVzZW50aW5nIGFuIGluc3RhbmNlIG9mCisgKiBhbiBTUUwgc3RydWN0dXJlZCB0eXBlIG9yIFNRTCBkaXN0aW5jdCB0eXBlLgorICogPHA+CisgKiBUaGlzIGludGVyZmFjZSBpcyB1c2VkIHRvIGRlZmluZSBjdXN0b20gbWFwcGluZ3Mgb2YgU1FMIDxpPlVzZXIgRGVmaW5lZAorICogVHlwZXM8L2k+IChVRFRzKSB0byBKYXZhIGNsYXNzZXMuIEl0IGlzIHVzZWQgYnkgSkRCQyBkcml2ZXJzLCB0aGVyZWZvcmUKKyAqIGFwcGxpY2F0aW9uIHByb2dyYW1tZXJzIGRvIG5vdCBub3JtYWxseSB1c2UgdGhlIHtAY29kZSBTUUxJbnB1dH0gbWV0aG9kcworICogZGlyZWN0bHkuIFJlYWRlciBtZXRob2RzIHN1Y2ggYXMge0Bjb2RlIHJlYWRMb25nfSBhbmQge0Bjb2RlIHJlYWRCeXRlc30KKyAqIHByb3ZpZGUgbWVhbnMgdG8gcmVhZCB2YWx1ZXMgZnJvbSBhbiB7QGNvZGUgU1FMSW5wdXR9IHN0cmVhbS4KKyAqIDxwPgorICogV2hlbiB0aGUge0Bjb2RlIGdldE9iamVjdH0gbWV0aG9kIGlzIGNhbGxlZCB3aXRoIGFuIG9iamVjdCB3aGljaCBpbXBsZW1lbnRzCisgKiB0aGUge0Bjb2RlIFNRTERhdGF9IGludGVyZmFjZSwgdGhlIEpEQkMgZHJpdmVyIGRldGVybWluZXMgdGhlIFNRTCB0eXBlIG9mIHRoZQorICogVURUIGJlaW5nIG1hcHBlZCBieSBjYWxsaW5nIHRoZSB7QGNvZGUgU1FMRGF0YS5nZXRTUUxUeXBlfSBtZXRob2QuIFRoZSBkcml2ZXIKKyAqIGNyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgYW4ge0Bjb2RlIFNRTElucHV0fSBzdHJlYW0sIGZpbGxpbmcgdGhlIHN0cmVhbSB3aXRoCisgKiB0aGUgYXR0cmlidXRlcyBvZiB0aGUgVURULiBUaGUge0Bjb2RlIFNRTElucHV0fSBzdHJlYW0gaXMgcGFzc2VkIHRvIHRoZQorICoge0Bjb2RlIFNRTERhdGEucmVhZFNRTH0gbWV0aG9kIHdoaWNoIHRoZW4gY2FsbHMgdGhlIHtAY29kZSBTUUxJbnB1dH0gcmVhZGVyCisgKiBtZXRob2RzIHRvIHJlYWQgdGhlIGF0dHJpYnV0ZXMuCisgKgorICogQHNlZSBTUUxEYXRhCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgU1FMSW5wdXQgeworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBhdHRyaWJ1dGUgaW4gdGhlIHN0cmVhbSBpbiB0aGUgZm9ybSBvZiBhIHtAY29kZSBTdHJpbmd9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBhdHRyaWJ1dGUuIHtAY29kZSBudWxsfSBpZiB0aGUgdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHJlYWRTdHJpbmcoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBhdHRyaWJ1dGUgaW4gdGhlIHN0cmVhbSBpbiB0aGUgZm9ybSBvZiBhIHtAY29kZSBib29sZWFufQorICAgICAqIC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgYXR0cmlidXRlIGFzIGEge0Bjb2RlIGJvb2xlYW59LiB7QGNvZGUgZmFsc2V9IGlmIHRoZQorICAgICAqICAgICAgICAgdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVhZEJvb2xlYW4oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBhdHRyaWJ1dGUgaW4gdGhlIHN0cmVhbSBpbiB0aGUgZm9ybSBvZiBhIHtAY29kZSBieXRlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgYXR0cmlidXRlIGFzIGEge0Bjb2RlIGJ5dGV9LiAwIGlmIHRoZSB2YWx1ZSBpcyBTUUwKKyAgICAgKiAgICAgICAgIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIGJ5dGUgcmVhZEJ5dGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBhdHRyaWJ1dGUgaW4gdGhlIHN0cmVhbSBpbiB0aGUgZm9ybSBvZiBhIHtAY29kZSBzaG9ydH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGF0dHJpYnV0ZSBhcyBhIHtAY29kZSBzaG9ydH0uIDAgaWYgdGhlIHZhbHVlIGlzIFNRTAorICAgICAqICAgICAgICAge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2hvcnQgcmVhZFNob3J0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgYXR0cmlidXRlIGluIHRoZSBzdHJlYW0gaW4gdGhlIGZvcm0gb2YgYW4ge0Bjb2RlIGludH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGF0dHJpYnV0ZSBhcyBhbiB7QGNvZGUgaW50fS4gMCBpZiB0aGUgdmFsdWUgaXMgU1FMCisgICAgICogICAgICAgICB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgcmVhZEludCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGF0dHJpYnV0ZSBpbiB0aGUgc3RyZWFtIGluIHRoZSBmb3JtIG9mIGEge0Bjb2RlIGxvbmd9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBhdHRyaWJ1dGUgYXMgYSB7QGNvZGUgbG9uZ30uIDAgaWYgdGhlIHZhbHVlIGlzIFNRTAorICAgICAqICAgICAgICAge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyByZWFkTG9uZygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGF0dHJpYnV0ZSBpbiB0aGUgc3RyZWFtIGluIHRoZSBmb3JtIG9mIGEge0Bjb2RlIGZsb2F0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgYXR0cmlidXRlIGFzIGEge0Bjb2RlIGZsb2F0fS4gMCBpZiB0aGUgdmFsdWUgaXMgU1FMCisgICAgICogICAgICAgICB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBmbG9hdCByZWFkRmxvYXQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBhdHRyaWJ1dGUgaW4gdGhlIHN0cmVhbSBpbiB0aGUgZm9ybSBvZiBhIHtAY29kZSBkb3VibGV9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBhdHRyaWJ1dGUgYXMgYSB7QGNvZGUgZG91YmxlfS4gMCBpZiB0aGUgdmFsdWUgaXMgU1FMCisgICAgICogICAgICAgICB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgcmVhZERvdWJsZSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGF0dHJpYnV0ZSBpbiB0aGUgc3RyZWFtIGluIHRoZSBmb3JtIG9mIGEge0Bjb2RlCisgICAgICogamF2YS5tYXRoLkJpZ0RlY2ltYWx9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYXR0cmlidXRlIGFzIGEge0Bjb2RlIGphdmEubWF0aC5CaWdEZWNpbWFsfS4ge0Bjb2RlIG51bGx9IGlmCisgICAgICogICAgICAgICB0aGUgcmVhZCByZXR1cm5zIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqIEBzZWUgamF2YS5tYXRoLkJpZ0RlY2ltYWwKKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbCByZWFkQmlnRGVjaW1hbCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGF0dHJpYnV0ZSBpbiB0aGUgc3RyZWFtIGluIHRoZSBmb3JtIG9mIGEgYnl0ZSBhcnJheS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGF0dHJpYnV0ZSBhcyBhIGJ5dGUgYXJyYXkuIHtAY29kZSBudWxsfSBpZiB0aGUgcmVhZCByZXR1cm5zCisgICAgICogICAgICAgICBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIHJlYWRCeXRlcygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGF0dHJpYnV0ZSBpbiB0aGUgc3RyZWFtIGluIHRoZSBmb3JtIG9mIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuRGF0ZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGF0dHJpYnV0ZSBhcyBhIHtAY29kZSBqYXZhLnNxbC5EYXRlfS4ge0Bjb2RlIG51bGx9IGlmCisgICAgICogICAgICAgICB0aGUgdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICogQHNlZSBEYXRlCisgICAgICovCisgICAgcHVibGljIERhdGUgcmVhZERhdGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBhdHRyaWJ1dGUgaW4gdGhlIHN0cmVhbSBpbiB0aGUgZm9ybSBvZiBhIHtAY29kZQorICAgICAqIGphdmEuc3FsLlRpbWV9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYXR0cmlidXRlIGFzIGEge0Bjb2RlIGphdmEuc3FsLlRpbWV9LiB7QGNvZGUgbnVsbH0gaWYgdGhlCisgICAgICogICAgICAgICByZWFkIHJldHVybnMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICogQHNlZSBUaW1lCisgICAgICovCisgICAgcHVibGljIFRpbWUgcmVhZFRpbWUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBhdHRyaWJ1dGUgaW4gdGhlIHN0cmVhbSBpbiB0aGUgZm9ybSBvZiBhIHtAY29kZQorICAgICAqIGphdmEuc3FsLlRpbWVzdGFtcH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBhdHRyaWJ1dGUgYXMgYSB7QGNvZGUgamF2YS5zcWwuVGltZXN0YW1wfS4ge0Bjb2RlIG51bGx9IGlmCisgICAgICogICAgICAgICB0aGUgcmVhZCByZXR1cm5zIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqIEBzZWUgVGltZXN0YW1wCisgICAgICovCisgICAgcHVibGljIFRpbWVzdGFtcCByZWFkVGltZXN0YW1wKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgYXR0cmlidXRlIGluIHRoZSBzdHJlYW0gaW4gdGhlIGZvcm0gb2YgYSBVbmljb2RlCisgICAgICogY2hhcmFjdGVyIHN0cmVhbSBlbWJvZGllZCBhcyBhIHtAY29kZSBqYXZhLmlvLlJlYWRlcn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGF0dHJpYnV0ZSBhcyBhIHtAY29kZSBqYXZhLmlvLlJlYWRlcn0uIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAgdGhlIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqIEBzZWUgamF2YS5pby5SZWFkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVhZGVyIHJlYWRDaGFyYWN0ZXJTdHJlYW0oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBhdHRyaWJ1dGUgaW4gdGhlIHN0cmVhbSBpbiB0aGUgZm9ybSBvZiBhbiBBU0NJSQorICAgICAqIGNoYXJhY3RlciBzdHJlYW0gZW1ib2RpZWQgYXMgYSB7QGNvZGUgamF2YS5pby5JbnB1dFN0cmVhbX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGF0dHJpYnV0ZSBhcyBhIHtAY29kZSBqYXZhLmlvLklucHV0U3RyZWFtfS4ge0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpZiB0aGUgdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICogQHNlZSBqYXZhLmlvLklucHV0U3RyZWFtCisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIHJlYWRBc2NpaVN0cmVhbSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGF0dHJpYnV0ZSBpbiB0aGUgc3RyZWFtIGluIHRoZSBmb3JtIG9mIGEgc3RyZWFtIG9mIGJ5dGVzCisgICAgICogZW1ib2RpZWQgYXMgYSB7QGNvZGUgamF2YS5pby5JbnB1dFN0cmVhbX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGF0dHJpYnV0ZSBhcyBhIHtAY29kZSBqYXZhLmlvLklucHV0U3RyZWFtfS4ge0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpZiB0aGUgdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICogQHNlZSBqYXZhLmlvLklucHV0U3RyZWFtCisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIHJlYWRCaW5hcnlTdHJlYW0oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBhdHRyaWJ1dGUgaW4gdGhlIHN0cmVhbSBpbiB0aGUgZm9ybSBvZiBhIHtAY29kZQorICAgICAqIGphdmEubGFuZy5PYmplY3R9LgorICAgICAqIDxwPgorICAgICAqIFRoZSB0eXBlIG9mIHRoZSB7QGNvZGUgT2JqZWN0fSByZXR1cm5lZCBpcyBkZXRlcm1pbmVkIGJ5IHRoZSB0eXBlIG1hcHBpbmcKKyAgICAgKiBmb3IgdGhpcyBKREJDIGRyaXZlciwgaW5jbHVkaW5nIGFueSBjdXN0b21pemVkIG1hcHBpbmdzLCBpZiBwcmVzZW50LiBBCisgICAgICogdHlwZSBtYXAgaXMgZ2l2ZW4gdG8gdGhlIHtAY29kZSBTUUxJbnB1dH0gYnkgdGhlIEpEQkMgZHJpdmVyIGJlZm9yZSB0aGUKKyAgICAgKiB7QGNvZGUgU1FMSW5wdXR9IGlzIGdpdmVuIHRvIHRoZSBhcHBsaWNhdGlvbi4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgYXR0cmlidXRlIGlzIGFuIFNRTCBzdHJ1Y3R1cmVkIG9yIGRpc3RpbmN0IHR5cGUsIGl0cyBTUUwgdHlwZSBpcworICAgICAqIGRldGVybWluZWQuIElmIHRoZSBzdHJlYW0ncyB0eXBlIG1hcCBjb250YWlucyBhbiBlbGVtZW50IGZvciB0aGF0IFNRTAorICAgICAqIHR5cGUsIHRoZSBkcml2ZXIgY3JlYXRlcyBhbiBvYmplY3QgZm9yIHRoZSByZWxldmFudCB0eXBlIGFuZCBpbnZva2VzIHRoZQorICAgICAqIG1ldGhvZCB7QGNvZGUgU1FMRGF0YS5yZWFkU1FMfSBvbiBpdCwgd2hpY2ggcmVhZHMgc3VwcGxlbWVudGFyeSBkYXRhIGZyb20KKyAgICAgKiB0aGUgc3RyZWFtIHVzaW5nIHdoaWNoZXZlciBwcm90b2NvbCBpcyBkZWZpbmVkIGZvciB0aGF0IG1ldGhvZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgYXR0cmlidXRlIGFzIGFuIE9iamVjdC4ge0Bjb2RlIG51bGx9IGlmIHRoZSB2YWx1ZSBpcyBTUUwKKyAgICAgKiAgICAgICAgIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCByZWFkT2JqZWN0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgYXR0cmlidXRlIGluIHRoZSBzdHJlYW0gaW4gdGhlIGZvcm0gb2YgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5SZWZ9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBhdHRyaWJ1dGUgYXMgYSB7QGNvZGUgamF2YS5zcWwuUmVmfS4ge0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqICAgICAgICAgdmFsdWUgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICogQHNlZSBSZWYKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVmIHJlYWRSZWYoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBhdHRyaWJ1dGUgaW4gdGhlIHN0cmVhbSBpbiB0aGUgZm9ybSBvZiBhIHtAY29kZQorICAgICAqIGphdmEuc3FsLkJsb2J9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBhdHRyaWJ1dGUgYXMgYSB7QGNvZGUgamF2YS5zcWwuQmxvYn0uIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAgdGhlIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBCbG9iIHJlYWRCbG9iKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgYXR0cmlidXRlIGluIHRoZSBzdHJlYW0gaW4gdGhlIGZvcm0gb2YgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5DbG9ifS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgYXR0cmlidXRlIGFzIGEge0Bjb2RlIGphdmEuc3FsLkNsb2J9LiB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiAgICAgICAgIHRoZSB2YWx1ZSBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKiBAc2VlIENsb2IKKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xvYiByZWFkQ2xvYigpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGF0dHJpYnV0ZSBpbiB0aGUgc3RyZWFtIGluIHRoZSBmb3JtIG9mIGEge0Bjb2RlCisgICAgICogamF2YS5zcWwuQXJyYXl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBhdHRyaWJ1dGUgYXMgYW4ge0Bjb2RlIEFycmF5fS4ge0Bjb2RlIG51bGx9IGlmIHRoZSB2YWx1ZQorICAgICAqICAgICAgICAgaXMgU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgZGF0YWJhc2UgZXJyb3IuCisgICAgICogQHNlZSBBcnJheQorICAgICAqLworICAgIHB1YmxpYyBBcnJheSByZWFkQXJyYXkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVwb3J0cyB3aGV0aGVyIHRoZSBsYXN0IHZhbHVlIHJlYWQgd2FzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgbGFzdCB2YWx1ZSByZWFkIHdhcyBTUUwge0Bjb2RlIE5VTEx9LCB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHdhc051bGwoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIG5leHQgYXR0cmlidXRlIGluIHRoZSBzdHJlYW0gKFNRTCBEQVRBTElOSyB2YWx1ZSkgYW5kIHJldHVybnMKKyAgICAgKiBpdCBhcyBhIHtAY29kZSBqYXZhLm5ldC5VUkx9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgYXR0cmlidXRlIGFzIGEge0Bjb2RlIGphdmEubmV0LlVSTH0uIHtAY29kZSBudWxsfSBpZiB0aGUKKyAgICAgKiAgICAgICAgIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqIEBzZWUgamF2YS5uZXQuVVJMCisgICAgICovCisgICAgcHVibGljIFVSTCByZWFkVVJMKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgYXR0cmlidXRlIGluIHRoZSBzdHJlYW0gaW4gdGhlIGZvcm0gb2YgYSB7QGNvZGUKKyAgICAgKiBqYXZhLnNxbC5OQ2xvYn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGF0dHJpYnV0ZSBhcyBhIHtAY29kZSBqYXZhLnNxbC5OQ2xvYn0uIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAgdGhlIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBOQ2xvYiByZWFkTkNsb2IoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBhdHRyaWJ1dGUgaW4gdGhlIHN0cmVhbSBpbiB0aGUgZm9ybSBvZiBhIHtAY29kZQorICAgICAqIGphdmEubGFuZy5TdHJpbmd9LiBVc2VkIGZvciB0aGUgTkNIQVIsIE5WQVJDSEFSIGFuZCBMT05HTlZBUkNIQVIgdHlwZXMuCisgICAgICogU2VlIHtAbGluayAjcmVhZFN0cmluZ30gb3RoZXJ3aXNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBhdHRyaWJ1dGUgYXMgYSB7QGNvZGUgamF2YS5sYW5nLlN0cmluZ30uIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAgdGhlIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgcmVhZE5TdHJpbmcoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBhdHRyaWJ1dGUgaW4gdGhlIHN0cmVhbSBpbiB0aGUgZm9ybSBvZiBhIHtAY29kZQorICAgICAqIGphdmEuc3FsLlNRTFhNTH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGF0dHJpYnV0ZSBhcyBhIHtAY29kZSBqYXZhLnNxbC5TUUxYTUx9LiB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiAgICAgICAgIHRoZSB2YWx1ZSBpcyBTUUwge0Bjb2RlIE5VTEx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBkYXRhYmFzZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMWE1MIHJlYWRTUUxYTUwoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBhdHRyaWJ1dGUgaW4gdGhlIHN0cmVhbSBpbiB0aGUgZm9ybSBvZiBhIHtAY29kZQorICAgICAqIGphdmEuc3FsLlJvd0lkfS4gVXNlZCBmb3IgdGhlIFJPV0lEIHR5cGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGF0dHJpYnV0ZSBhcyBhIHtAY29kZSBqYXZhLnNxbC5Sb3dJZH0uIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAgdGhlIHZhbHVlIGlzIFNRTCB7QGNvZGUgTlVMTH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIGRhdGFiYXNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBSb3dJZCByZWFkUm93SWQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTEludGVncml0eUNvbnN0cmFpbnRWaW9sYXRpb25FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxJbnRlZ3JpdHlDb25zdHJhaW50VmlvbGF0aW9uRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2ViZGNiNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxJbnRlZ3JpdHlDb25zdHJhaW50VmlvbGF0aW9uRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwxNTMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCisvKioKKyAqIEFuIGV4Y2VwdGlvbiwgd2hpY2ggaXMgc3ViY2xhc3Mgb2YgU1FMTm9uVHJhbnNpZW50RXhjZXB0aW9uLCBpcyB0aHJvd24gd2hlbgorICogdmFyaW91cyB0aGUgYW4gaW50ZWdyaXR5IGNvbnN0cmFpbnQgKGZvcmVpZ24ga2V5LCBwcmltYXJ5IGtleSBvciB1bmlxdWUga2V5KQorICogaGFzIGJlZW4gdmlvbGF0ZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBTUUxJbnRlZ3JpdHlDb25zdHJhaW50VmlvbGF0aW9uRXhjZXB0aW9uIGV4dGVuZHMKKyAgICAgICAgU1FMTm9uVHJhbnNpZW50RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDgwMzM0MDUyOTg3NzQ4NDkxNjlMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxJbnRlZ3JpdHlDb25zdHJhaW50VmlvbGF0aW9uRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbgorICAgICAqIHN0cmluZyBpcyBzZXQgdG8gbnVsbCwgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gbnVsbCBhbmQgdGhlIEVycm9yCisgICAgICogQ29kZSBpcyBzZXQgdG8gMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMSW50ZWdyaXR5Q29uc3RyYWludFZpb2xhdGlvbkV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTEludGVncml0eUNvbnN0cmFpbnRWaW9sYXRpb25FeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uCisgICAgICogc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8KKyAgICAgKiBudWxsIGFuZCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gMC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICovCisgICAgcHVibGljIFNRTEludGVncml0eUNvbnN0cmFpbnRWaW9sYXRpb25FeGNlcHRpb24oU3RyaW5nIHJlYXNvbikgeworICAgICAgICBzdXBlcihyZWFzb24sIG51bGwsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMSW50ZWdyaXR5Q29uc3RyYWludFZpb2xhdGlvbkV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24KKyAgICAgKiBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0bworICAgICAqIHRoZSBnaXZlbiBTUUxTdGF0ZSBzdHJpbmcgYW5kIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byAwLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMSW50ZWdyaXR5Q29uc3RyYWludFZpb2xhdGlvbkV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLAorICAgICAgICAgICAgU3RyaW5nIHNxbFN0YXRlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMSW50ZWdyaXR5Q29uc3RyYWludFZpb2xhdGlvbkV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24KKyAgICAgKiBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0bworICAgICAqIHRoZSBnaXZlbiBTUUxTdGF0ZSBzdHJpbmcgYW5kIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byB0aGUgZ2l2ZW4gZXJyb3IKKyAgICAgKiBjb2RlIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdmVuZG9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZSBlcnJvciBjb2RlCisgICAgICovCisgICAgcHVibGljIFNRTEludGVncml0eUNvbnN0cmFpbnRWaW9sYXRpb25FeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwKKyAgICAgICAgICAgIFN0cmluZyBzcWxTdGF0ZSwgaW50IHZlbmRvckNvZGUpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgdmVuZG9yQ29kZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxJbnRlZ3JpdHlDb25zdHJhaW50VmlvbGF0aW9uRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbgorICAgICAqIHN0cmluZyBpcyBzZXQgdG8gdGhlIG51bGwgaWYgY2F1c2UgPT0gbnVsbCBvciBjYXVzZS50b1N0cmluZygpIGlmCisgICAgICogY2F1c2UhPW51bGwsYW5kIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UKKyAgICAgKiBUaHJvd2FibGUgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxJbnRlZ3JpdHlDb25zdHJhaW50VmlvbGF0aW9uRXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxJbnRlZ3JpdHlDb25zdHJhaW50VmlvbGF0aW9uRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbgorICAgICAqIHN0cmluZyBpcyBzZXQgdG8gdGhlIGdpdmVuIGFuZCB0aGUgY2F1c2UgVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlCisgICAgICogZ2l2ZW4gY2F1c2UgVGhyb3dhYmxlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxJbnRlZ3JpdHlDb25zdHJhaW50VmlvbGF0aW9uRXhjZXB0aW9uKFN0cmluZyByZWFzb24sCisgICAgICAgICAgICBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxJbnRlZ3JpdHlDb25zdHJhaW50VmlvbGF0aW9uRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbgorICAgICAqIHN0cmluZyBpcyBzZXQgdG8gdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvCisgICAgICogdGhlIGdpdmVuIFNRTFN0YXRlIHN0cmluZyBhbmQgdGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZQorICAgICAqIGdpdmVuIGNhdXNlIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMSW50ZWdyaXR5Q29uc3RyYWludFZpb2xhdGlvbkV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLAorICAgICAgICAgICAgU3RyaW5nIHNxbFN0YXRlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMSW50ZWdyaXR5Q29uc3RyYWludFZpb2xhdGlvbkV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24KKyAgICAgKiBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0bworICAgICAqIHRoZSBnaXZlbiBTUUxTdGF0ZSBzdHJpbmcgLCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gdGhlIGdpdmVuIGVycm9yIGNvZGUKKyAgICAgKiB2YWx1ZSwgYW5kIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UgVGhyb3dhYmxlCisgICAgICogb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdmVuZG9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZSBlcnJvciBjb2RlCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxJbnRlZ3JpdHlDb25zdHJhaW50VmlvbGF0aW9uRXhjZXB0aW9uKFN0cmluZyByZWFzb24sCisgICAgICAgICAgICBTdHJpbmcgc3FsU3RhdGUsIGludCB2ZW5kb3JDb2RlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgdmVuZG9yQ29kZSwgY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxJbnZhbGlkQXV0aG9yaXphdGlvblNwZWNFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxJbnZhbGlkQXV0aG9yaXphdGlvblNwZWNFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZGU0YTlkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTEludmFsaWRBdXRob3JpemF0aW9uU3BlY0V4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTUxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworLyoqCisgKiBBbiBleGNlcHRpb24sIHdoaWNoIGlzIHN1YmNsYXNzIG9mIFNRTE5vblRyYW5zaWVudEV4Y2VwdGlvbiwgaXMgdGhyb3duIHdoZW4KKyAqIHRoZSBhdXRob3JpemF0aW9uIGNyZWRlbnRpYWxzIHByZXNlbnRlZCBkdXJpbmcgY29ubmVjdGlvbiBlc3RhYmxpc2htZW50IGFyZQorICogbm90IHZhbGlkLgorICovCitwdWJsaWMgY2xhc3MgU1FMSW52YWxpZEF1dGhvcml6YXRpb25TcGVjRXhjZXB0aW9uIGV4dGVuZHMKKyAgICAgICAgU1FMTm9uVHJhbnNpZW50RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC02NDEwNTI1MDQ1MDg5MTQ5OEw7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTEludmFsaWRBdXRob3JpemF0aW9uU3BlY0V4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nCisgICAgICogaXMgc2V0IHRvIG51bGwsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIG51bGwgYW5kIHRoZSBFcnJvciBDb2RlIGlzCisgICAgICogc2V0IHRvIDAuCisgICAgICovCisgICAgcHVibGljIFNRTEludmFsaWRBdXRob3JpemF0aW9uU3BlY0V4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTEludmFsaWRBdXRob3JpemF0aW9uU3BlY0V4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nCisgICAgICogaXMgc2V0IHRvIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byBudWxsIGFuZAorICAgICAqIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byAwLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMSW52YWxpZEF1dGhvcml6YXRpb25TcGVjRXhjZXB0aW9uKFN0cmluZyByZWFzb24pIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBudWxsLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTEludmFsaWRBdXRob3JpemF0aW9uU3BlY0V4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nCisgICAgICogaXMgc2V0IHRvIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUKKyAgICAgKiBnaXZlbiBTUUxTdGF0ZSBzdHJpbmcgYW5kIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byAwLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMSW52YWxpZEF1dGhvcml6YXRpb25TcGVjRXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBzcWxTdGF0ZSkgeworICAgICAgICBzdXBlcihyZWFzb24sIHNxbFN0YXRlLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTEludmFsaWRBdXRob3JpemF0aW9uU3BlY0V4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nCisgICAgICogaXMgc2V0IHRvIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUKKyAgICAgKiBnaXZlbiBTUUxTdGF0ZSBzdHJpbmcgYW5kIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byB0aGUgZ2l2ZW4gZXJyb3IgY29kZQorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdmVuZG9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZSBlcnJvciBjb2RlCisgICAgICovCisgICAgcHVibGljIFNRTEludmFsaWRBdXRob3JpemF0aW9uU3BlY0V4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsCisgICAgICAgICAgICBpbnQgdmVuZG9yQ29kZSkgeworICAgICAgICBzdXBlcihyZWFzb24sIHNxbFN0YXRlLCB2ZW5kb3JDb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTEludmFsaWRBdXRob3JpemF0aW9uU3BlY0V4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nCisgICAgICogaXMgc2V0IHRvIHRoZSBudWxsIGlmIGNhdXNlID09IG51bGwgb3IgY2F1c2UudG9TdHJpbmcoKSBpZgorICAgICAqIGNhdXNlIT1udWxsLGFuZCB0aGUgY2F1c2UgVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlCisgICAgICogVGhyb3dhYmxlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMSW52YWxpZEF1dGhvcml6YXRpb25TcGVjRXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxJbnZhbGlkQXV0aG9yaXphdGlvblNwZWNFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZworICAgICAqIGlzIHNldCB0byB0aGUgZ2l2ZW4gYW5kIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4KKyAgICAgKiBjYXVzZSBUaHJvd2FibGUgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTEludmFsaWRBdXRob3JpemF0aW9uU3BlY0V4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxJbnZhbGlkQXV0aG9yaXphdGlvblNwZWNFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZworICAgICAqIGlzIHNldCB0byB0aGUgZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gdGhlCisgICAgICogZ2l2ZW4gU1FMU3RhdGUgc3RyaW5nIGFuZCB0aGUgY2F1c2UgVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuCisgICAgICogY2F1c2UgVGhyb3dhYmxlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICogQHBhcmFtIHNxbFN0YXRlCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgU1FMU3RhdGUgc3RyaW5nCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxJbnZhbGlkQXV0aG9yaXphdGlvblNwZWNFeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgU3RyaW5nIHNxbFN0YXRlLAorICAgICAgICAgICAgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTEludmFsaWRBdXRob3JpemF0aW9uU3BlY0V4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nCisgICAgICogaXMgc2V0IHRvIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUKKyAgICAgKiBnaXZlbiBTUUxTdGF0ZSBzdHJpbmcgLCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gdGhlIGdpdmVuIGVycm9yIGNvZGUKKyAgICAgKiB2YWx1ZSwgYW5kIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UgVGhyb3dhYmxlCisgICAgICogb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdmVuZG9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZSBlcnJvciBjb2RlCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxJbnZhbGlkQXV0aG9yaXphdGlvblNwZWNFeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgU3RyaW5nIHNxbFN0YXRlLAorICAgICAgICAgICAgaW50IHZlbmRvckNvZGUsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihyZWFzb24sIHNxbFN0YXRlLCB2ZW5kb3JDb2RlLCBjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTE5vblRyYW5zaWVudENvbm5lY3Rpb25FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxOb25UcmFuc2llbnRDb25uZWN0aW9uRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDc5NzA2NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxOb25UcmFuc2llbnRDb25uZWN0aW9uRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwxNTEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCisvKioKKyAqIEFuIGV4Y2VwdGlvbiwgd2hpY2ggaXMgc3ViY2xhc3Mgb2YgU1FMRXhjZXB0aW9uLCBpcyB0aHJvd24gd2hlbiB0aGUKKyAqIGNvbm5lY3Rpb24gb3BlcmF0aW9uIHRoYXQgZmFpbGVkIHdpbGwgbm90IHN1Y2NlZWQgd2hlbiB0aGUgb3BlcmF0aW9uIGlzCisgKiByZXRyaWVkIHdpdGhvdXQgdGhlIGNhdXNlIG9mIHRoZSBmYWlsdXJlIGJlaW5nIGNvcnJlY3RlZC4KKyAqLworcHVibGljIGNsYXNzIFNRTE5vblRyYW5zaWVudENvbm5lY3Rpb25FeGNlcHRpb24gZXh0ZW5kcworICAgICAgICBTUUxOb25UcmFuc2llbnRFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTU4NTIzMTg4NTc0NzQ3ODI4OTJMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxOb25UcmFuc2llbnRDb25uZWN0aW9uRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBpcyBzZXQgdG8gbnVsbCwgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gbnVsbCBhbmQgdGhlIEVycm9yIENvZGUgaXMKKyAgICAgKiBzZXQgdG8gMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMTm9uVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTE5vblRyYW5zaWVudENvbm5lY3Rpb25FeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZworICAgICAqIGlzIHNldCB0byB0aGUgZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gbnVsbCBhbmQKKyAgICAgKiB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gMC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICovCisgICAgcHVibGljIFNRTE5vblRyYW5zaWVudENvbm5lY3Rpb25FeGNlcHRpb24oU3RyaW5nIHJlYXNvbikgeworICAgICAgICBzdXBlcihyZWFzb24sIG51bGwsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMTm9uVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nCisgICAgICogaXMgc2V0IHRvIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUKKyAgICAgKiBnaXZlbiBTUUxTdGF0ZSBzdHJpbmcgYW5kIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byAwLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMTm9uVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxOb25UcmFuc2llbnRDb25uZWN0aW9uRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBpcyBzZXQgdG8gdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZQorICAgICAqIGdpdmVuIFNRTFN0YXRlIHN0cmluZyBhbmQgdGhlIEVycm9yIENvZGUgaXMgc2V0IHRvIHRoZSBnaXZlbiBlcnJvciBjb2RlCisgICAgICogdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqIEBwYXJhbSB2ZW5kb3JDb2RlCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB2YWx1ZSBmb3IgdGhlIGVycm9yIGNvZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMTm9uVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsCisgICAgICAgICAgICBpbnQgdmVuZG9yQ29kZSkgeworICAgICAgICBzdXBlcihyZWFzb24sIHNxbFN0YXRlLCB2ZW5kb3JDb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTE5vblRyYW5zaWVudENvbm5lY3Rpb25FeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZworICAgICAqIGlzIHNldCB0byB0aGUgbnVsbCBpZiBjYXVzZSA9PSBudWxsIG9yIGNhdXNlLnRvU3RyaW5nKCkgaWYKKyAgICAgKiBjYXVzZSE9bnVsbCxhbmQgdGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZQorICAgICAqIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTE5vblRyYW5zaWVudENvbm5lY3Rpb25FeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTE5vblRyYW5zaWVudENvbm5lY3Rpb25FeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZworICAgICAqIGlzIHNldCB0byB0aGUgZ2l2ZW4gYW5kIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4KKyAgICAgKiBjYXVzZSBUaHJvd2FibGUgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTE5vblRyYW5zaWVudENvbm5lY3Rpb25FeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMTm9uVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nCisgICAgICogaXMgc2V0IHRvIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUKKyAgICAgKiBnaXZlbiBTUUxTdGF0ZSBzdHJpbmcgYW5kIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4KKyAgICAgKiBjYXVzZSBUaHJvd2FibGUgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTE5vblRyYW5zaWVudENvbm5lY3Rpb25FeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgU3RyaW5nIHNxbFN0YXRlLAorICAgICAgICAgICAgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTE5vblRyYW5zaWVudENvbm5lY3Rpb25FeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZworICAgICAqIGlzIHNldCB0byB0aGUgZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gdGhlCisgICAgICogZ2l2ZW4gU1FMU3RhdGUgc3RyaW5nICwgdGhlIEVycm9yIENvZGUgaXMgc2V0IHRvIHRoZSBnaXZlbiBlcnJvciBjb2RlCisgICAgICogdmFsdWUsIGFuZCB0aGUgY2F1c2UgVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlIFRocm93YWJsZQorICAgICAqIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICogQHBhcmFtIHNxbFN0YXRlCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgU1FMU3RhdGUgc3RyaW5nCisgICAgICogQHBhcmFtIHZlbmRvckNvZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlZ2VyIHZhbHVlIGZvciB0aGUgZXJyb3IgY29kZQorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMTm9uVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsCisgICAgICAgICAgICBpbnQgdmVuZG9yQ29kZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIHZlbmRvckNvZGUsIGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMTm9uVHJhbnNpZW50RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMTm9uVHJhbnNpZW50RXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzlkZmJjYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxOb25UcmFuc2llbnRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDE0MSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zcWw7CisKK3B1YmxpYyBjbGFzcyBTUUxOb25UcmFuc2llbnRFeGNlcHRpb24gZXh0ZW5kcyBTUUxFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTkxMDQzODI4NDM1MzQ3MTY1NDdMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxOb25UcmFuc2llbnRFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8KKyAgICAgKiBudWxsLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byBudWxsIGFuZCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMTm9uVHJhbnNpZW50RXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMTm9uVHJhbnNpZW50RXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvCisgICAgICogdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIG51bGwgYW5kIHRoZSBFcnJvcgorICAgICAqIENvZGUgaXMgc2V0IHRvIDAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqLworICAgIHB1YmxpYyBTUUxOb25UcmFuc2llbnRFeGNlcHRpb24oU3RyaW5nIHJlYXNvbikgeworICAgICAgICBzdXBlcihyZWFzb24sIG51bGwsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMTm9uVHJhbnNpZW50RXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvCisgICAgICogdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbiBTUUxTdGF0ZQorICAgICAqIHN0cmluZyBhbmQgdGhlIEVycm9yIENvZGUgaXMgc2V0IHRvIDAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqLworICAgIHB1YmxpYyBTUUxOb25UcmFuc2llbnRFeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgU3RyaW5nIHNxbFN0YXRlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMTm9uVHJhbnNpZW50RXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvCisgICAgICogdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbiBTUUxTdGF0ZQorICAgICAqIHN0cmluZyBhbmQgdGhlIEVycm9yIENvZGUgaXMgc2V0IHRvIHRoZSBnaXZlbiBlcnJvciBjb2RlIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdmVuZG9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZSBlcnJvciBjb2RlCisgICAgICovCisgICAgcHVibGljIFNRTE5vblRyYW5zaWVudEV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsCisgICAgICAgICAgICBpbnQgdmVuZG9yQ29kZSkgeworICAgICAgICBzdXBlcihyZWFzb24sIHNxbFN0YXRlLCB2ZW5kb3JDb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTE5vblRyYW5zaWVudEV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0bworICAgICAqIHRoZSBudWxsIGlmIGNhdXNlID09IG51bGwgb3IgY2F1c2UudG9TdHJpbmcoKSBpZiBjYXVzZSE9bnVsbCxhbmQgdGhlCisgICAgICogY2F1c2UgVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTE5vblRyYW5zaWVudEV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMTm9uVHJhbnNpZW50RXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvCisgICAgICogdGhlIGdpdmVuIGFuZCB0aGUgY2F1c2UgVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlCisgICAgICogVGhyb3dhYmxlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxOb25UcmFuc2llbnRFeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMTm9uVHJhbnNpZW50RXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvCisgICAgICogdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbiBTUUxTdGF0ZQorICAgICAqIHN0cmluZyBhbmQgdGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZSBUaHJvd2FibGUKKyAgICAgKiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMTm9uVHJhbnNpZW50RXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBzcWxTdGF0ZSwKKyAgICAgICAgICAgIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihyZWFzb24sIHNxbFN0YXRlLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxOb25UcmFuc2llbnRFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8KKyAgICAgKiB0aGUgZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gdGhlIGdpdmVuIFNRTFN0YXRlCisgICAgICogc3RyaW5nICwgdGhlIEVycm9yIENvZGUgaXMgc2V0IHRvIHRoZSBnaXZlbiBlcnJvciBjb2RlIHZhbHVlLCBhbmQgdGhlCisgICAgICogY2F1c2UgVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqIEBwYXJhbSB2ZW5kb3JDb2RlCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB2YWx1ZSBmb3IgdGhlIGVycm9yIGNvZGUKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTE5vblRyYW5zaWVudEV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsCisgICAgICAgICAgICBpbnQgdmVuZG9yQ29kZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIHZlbmRvckNvZGUsIGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMT3V0cHV0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMT3V0cHV0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWUwMWU3NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxPdXRwdXQuamF2YQpAQCAtMCwwICsxLDMzNCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zcWw7CisKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUmVhZGVyOworaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOworaW1wb3J0IGphdmEubmV0LlVSTDsKKworLyoqCisgKiBUaGUgaW50ZXJmYWNlIGZvciBhbiBvdXRwdXQgc3RyZWFtIHVzZWQgdG8gd3JpdGUgYXR0cmlidXRlcyBvZiBhbiBTUUwgPGk+VXNlcgorICogRGVmaW5lZCBUeXBlPC9pPiAoVURUKSB0byB0aGUgZGF0YWJhc2UuIFRoaXMgaW50ZXJmYWNlIGlzIHVzZWQgZm9yIGN1c3RvbQorICogbWFwcGluZyBvZiB0eXBlcyBhbmQgaXMgY2FsbGVkIGJ5IHRoZSBKREJDIGRyaXZlci4gSXQgaXMgbm90IGludGVuZGVkIHRvIGJlCisgKiB1c2VkIGJ5IGFwcGxpY2F0aW9ucy4KKyAqIDxwPgorICogV2hlbiBhbiBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyB0aGUge0Bjb2RlIFNRTERhdGF9IGludGVyZmFjZSBpcyB1c2VkIGFzIGFuCisgKiBhcmd1bWVudCB0byBhbiBTUUwgc3RhdGVtZW50LCB0aGUgSkRCQyBkcml2ZXIgY2FsbHMgdGhlIG1ldGhvZCB7QGNvZGUKKyAqIFNRTERhdGEuZ2V0U1FMVHlwZX0gdG8gZXN0YWJsaXNoIHRoZSB0eXBlIG9mIHRoZSBTUUwgVURUIHRoYXQgaXMgYmVpbmcKKyAqIHBhc3NlZC4gVGhlIGRyaXZlciB0aGVuIGNyZWF0ZXMgYW4ge0Bjb2RlIFNRTE91dHB1dH0gc3RyZWFtIGFuZCBwYXNzZXMgaXQgdG8KKyAqIHRoZSB7QGNvZGUgU1FMRGF0YS53cml0ZVNRTH0gbWV0aG9kLCB3aGljaCBpbiB0dXJuIHVzZXMgdGhlIGFwcHJvcHJpYXRlCisgKiB7QGNvZGUgU1FMT3V0cHV0fSB3cml0ZXIgbWV0aG9kcyB0byB3cml0ZSB0aGUgZGF0YSBmcm9tIHRoZSB7QGNvZGUgU1FMRGF0YX0KKyAqIG9iamVjdCBpbnRvIHRoZSBzdHJlYW0gYWNjb3JkaW5nIHRvIHRoZSBkZWZpbmVkIG1hcHBpbmcuCisgKgorICogQHNlZSBTUUxEYXRhCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgU1FMT3V0cHV0IHsKKworICAgIC8qKgorICAgICAqIFdyaXRlIGEge0Bjb2RlIFN0cmluZ30gdmFsdWUgaW50byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVTdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgU3RyaW5nfSB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlU3RyaW5nKFN0cmluZyB0aGVTdHJpbmcpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhIHtAY29kZSBib29sZWFufSB2YWx1ZSBpbnRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZUZsYWcKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgYm9vbGVhbn0gdmFsdWUgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZUJvb2xlYW4oYm9vbGVhbiB0aGVGbGFnKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGUgYSB7QGNvZGUgYnl0ZX0gdmFsdWUgaW50byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVCeXRlCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGJ5dGV9IHZhbHVlIHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVCeXRlKGJ5dGUgdGhlQnl0ZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlIGEge0Bjb2RlIHNob3J0fSB2YWx1ZSBpbnRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZVNob3J0CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIHNob3J0fSB2YWx1ZSB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlU2hvcnQoc2hvcnQgdGhlU2hvcnQpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhbiB7QGNvZGUgaW50fSB2YWx1ZSBpbnRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZUludAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBpbnR9IHZhbHVlIHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVJbnQoaW50IHRoZUludCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlIGEge0Bjb2RlIGxvbmd9IHZhbHVlIGludG8gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlTG9uZworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBsb25nfSB2YWx1ZSB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlTG9uZyhsb25nIHRoZUxvbmcpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhIHtAY29kZSBmbG9hdH0gdmFsdWUgaW50byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVGbG9hdAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBmbG9hdH0gdmFsdWUgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZUZsb2F0KGZsb2F0IHRoZUZsb2F0KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGUgYSB7QGNvZGUgZG91YmxlfSB2YWx1ZSBpbnRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZURvdWJsZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBkb3VibGV9IHZhbHVlIHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVEb3VibGUoZG91YmxlIHRoZURvdWJsZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlIGEge0Bjb2RlIGphdmEubWF0aC5CaWdEZWNpbWFsfSB2YWx1ZSBpbnRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZUJpZ0RlY2ltYWwKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQmlnRGVjaW1hbH0gdmFsdWUgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZUJpZ0RlY2ltYWwoQmlnRGVjaW1hbCB0aGVCaWdEZWNpbWFsKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGUgYW4gYXJyYXkgb2YgYnl0ZXMgaW50byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVCeXRlcworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIGJ5dGVzIHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVCeXRlcyhieXRlW10gdGhlQnl0ZXMpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhIHtAY29kZSBqYXZhLnNxbC5EYXRlfSB2YWx1ZSBpbnRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZURhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgRGF0ZX0gdmFsdWUgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlIERhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZURhdGUoRGF0ZSB0aGVEYXRlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGUgYSB7QGNvZGUgamF2YS5zcWwuVGltZX0gdmFsdWUgaW50byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVUaW1lCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIFRpbWV9IHZhbHVlIHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSBUaW1lCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVUaW1lKFRpbWUgdGhlVGltZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlIGEge0Bjb2RlIGphdmEuc3FsLlRpbWVzdGFtcH0gdmFsdWUgaW50byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVUaW1lc3RhbXAKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgVGltZXN0YW1wfSB2YWx1ZSB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgVGltZXN0YW1wCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVUaW1lc3RhbXAoVGltZXN0YW1wIHRoZVRpbWVzdGFtcCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlIGEgc3RyZWFtIG9mIHVuaWNvZGUgY2hhcmFjdGVycyBpbnRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZVN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmVhbSBvZiB1bmljb2RlIGNoYXJhY3RlcnMgdG8gd3JpdGUsIGFzIGEge0Bjb2RlCisgICAgICogICAgICAgICAgICBqYXZhLmlvLlJlYWRlcn0gb2JqZWN0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVDaGFyYWN0ZXJTdHJlYW0oUmVhZGVyIHRoZVN0cmVhbSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlIGEgc3RyZWFtIG9mIEFTQ0lJIGNoYXJhY3RlcnMgaW50byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVTdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJlYW0gb2YgQVNDSUkgY2hhcmFjdGVycyB0byB3cml0ZSwgYXMgYSB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW19IG9iamVjdAorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVBc2NpaVN0cmVhbShJbnB1dFN0cmVhbSB0aGVTdHJlYW0pIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhIHN0cmVhbSBvZiB1bmludGVycHJldGVkIGJ5dGVzIGludG8gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlU3RyZWFtCisgICAgICogICAgICAgICAgICB0aGUgc3RyZWFtIG9mIGJ5dGVzIHRvIHdyaXRlLCBhcyBhIHtAY29kZSBqYXZhLmlvLklucHV0U3RyZWFtfQorICAgICAqICAgICAgICAgICAgb2JqZWN0CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZUJpbmFyeVN0cmVhbShJbnB1dFN0cmVhbSB0aGVTdHJlYW0pIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhbiB7QGNvZGUgU1FMRGF0YX0gb2JqZWN0IGludG8gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICogPHA+CisgICAgICogSWYgdGhlIHtAY29kZSBTUUxEYXRhfSBvYmplY3QgaXMgbnVsbCwgd3JpdGVzIHtAY29kZSBOVUxMfSB0byB0aGUgc3RyZWFtLgorICAgICAqIDxwPgorICAgICAqIE90aGVyd2lzZSwgY2FsbHMgdGhlIHtAY29kZSBTUUxEYXRhLndyaXRlU1FMfSBtZXRob2Qgb2YgdGhlIG9iamVjdCwgd2hpY2gKKyAgICAgKiB3cml0ZXMgdGhlIG9iamVjdCdzIGF0dHJpYnV0ZXMgdG8gdGhlIHN0cmVhbSBieSBjYWxsaW5nIHRoZSBhcHByb3ByaWF0ZQorICAgICAqIFNRTE91dHB1dCB3cml0ZXIgbWV0aG9kcyBmb3IgZWFjaCBhdHRyaWJ1dGUsIGluIG9yZGVyLiBUaGUgb3JkZXIgb2YgdGhlCisgICAgICogYXR0cmlidXRlcyBpcyB0aGUgb3JkZXIgdGhleSBhcmUgbGlzdGVkIGluIHRoZSBTUUwgZGVmaW5pdGlvbiBvZiB0aGUgVXNlcgorICAgICAqIERlZmluZWQgVHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVPYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgU1FMRGF0YX0gb2JqZWN0IHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSBTUUxEYXRhCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVPYmplY3QoU1FMRGF0YSB0aGVPYmplY3QpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhbiBTUUwge0Bjb2RlIFJlZn0gdmFsdWUgaW50byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVSZWYKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgamF2YS5zcWwuUmVmfSBvYmplY3QgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlIFJlZgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlUmVmKFJlZiB0aGVSZWYpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhbiBTUUwge0Bjb2RlIEJsb2J9IHZhbHVlIGludG8gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlQmxvYgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBqYXZhLnNxbC5CbG9ifSBvYmplY3QgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlIEJsb2IKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZUJsb2IoQmxvYiB0aGVCbG9iKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGUgYW4gU1FMIHtAY29kZSBDbG9ifSB2YWx1ZSBpbnRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZUNsb2IKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgamF2YS5zcWwuQ2xvYn0gb2JqZWN0IHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSBDbG9iCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVDbG9iKENsb2IgdGhlQ2xvYikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlIGFuIFNRTCB7QGNvZGUgU3RydWN0fSB2YWx1ZSBpbnRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZVN0cnVjdAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBqYXZhLnNxbC5TdHJ1Y3R9IG9iamVjdCB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgU3RydWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVTdHJ1Y3QoU3RydWN0IHRoZVN0cnVjdCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlIGFuIFNRTCB7QGNvZGUgQXJyYXl9IHZhbHVlIGludG8gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgamF2YS5zcWwuQXJyYXl9IG9iamVjdCB0byB3cml0ZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgQXJyYXkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZUFycmF5KEFycmF5IHRoZUFycmF5KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGUgYSB7QGNvZGUgVVJMfSBpbnRvIHRoZSBvdXRwdXQgc3RyZWFtIGFzIGFuIFNRTCBEQVRBTElOSy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVVUkwKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhbGluayB2YWx1ZSBhcyBhIHtAY29kZSBqYXZhLm5ldC5VUkx9IHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICogQHNlZSBqYXZhLm5ldC5VUkwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVVSTChVUkwgdGhlVVJMKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGUgYSB7QGNvZGUgU3RyaW5nfSBpbnRvIHRoZSBvdXRwdXQgc3RyZWFtIGFzIGFuIFNRTCBOQ0hBUiwgTlZBUkNIQVIsCisgICAgICogb3IgTE9OR05WQVJDSEFSLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZVN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBTdHJpbmd9IHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVOU3RyaW5nKFN0cmluZyB0aGVTdHJpbmcpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhIHtAY29kZSBDbG9ifSBpbnRvIHRoZSBvdXRwdXQgc3RyZWFtIGFzIGFuIFNRTCBOQ0xPQi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVOQ2xvYgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBqYXZhLnNxbC5DbG9ifSBvYmplY3QgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZU5DbG9iKE5DbG9iIHRoZU5DbG9iKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGUgYSB7QGNvZGUgUm93SWR9IGludG8gdGhlIG91dHB1dCBzdHJlYW0gYXMgYW4gU1FMIFJPV0lELgorICAgICAqCisgICAgICogQHBhcmFtIHRoZVJvd0lkCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGphdmEuc3FsLlJvd0lkfSBvYmplY3QgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVJvd0lkKFJvd0lkIHRoZVJvd0lkKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGUgYSB7QGNvZGUgU1FMWE1MfSBpbnRvIHRoZSBvdXRwdXQgc3RyZWFtIGFzIGFuIFNRTCBYTUwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlWG1sCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGphdmEuc3FsLlNRTFhNTH0gb2JqZWN0IHRvIHdyaXRlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVTUUxYTUwoU1FMWE1MIHRoZVhtbCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxQZXJtaXNzaW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMUGVybWlzc2lvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4MDY1YzYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMUGVybWlzc2lvbi5qYXZhCkBAIC0wLDAgKzEsMzYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5CYXNpY1Blcm1pc3Npb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5HdWFyZDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTUUxQZXJtaXNzaW9uIGV4dGVuZHMgQmFzaWNQZXJtaXNzaW9uIGltcGxlbWVudHMgR3VhcmQsIFNlcmlhbGl6YWJsZSB7CisgICAgcHVibGljIFNRTFBlcm1pc3Npb24oU3RyaW5nIG5hbWUpIHsgc3VwZXIoIiIpOyB9CisKKyAgICBwdWJsaWMgU1FMUGVybWlzc2lvbihTdHJpbmcgbmFtZSwgU3RyaW5nIGFjdGlvbnMpIHsgc3VwZXIoIiIsICIiKTsgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgZ2V0QWN0aW9ucygpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpbXBsaWVzKFBlcm1pc3Npb24gcGVybWlzc2lvbikgeyByZXR1cm4gdHJ1ZTsgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTFJlY292ZXJhYmxlRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMUmVjb3ZlcmFibGVFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ODVlM2E2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTFJlY292ZXJhYmxlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwxNDEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCitwdWJsaWMgY2xhc3MgU1FMUmVjb3ZlcmFibGVFeGNlcHRpb24gZXh0ZW5kcyBTUUxFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQxNDQzODY1MDI5MjMxMzE1NzlMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxSZWNvdmVyYWJsZUV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0bworICAgICAqIG51bGwsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIG51bGwgYW5kIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byAwLgorICAgICAqLworICAgIHB1YmxpYyBTUUxSZWNvdmVyYWJsZUV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTFJlY292ZXJhYmxlRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvCisgICAgICogdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIG51bGwgYW5kIHRoZSBFcnJvcgorICAgICAqIENvZGUgaXMgc2V0IHRvIDAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqLworICAgIHB1YmxpYyBTUUxSZWNvdmVyYWJsZUV4Y2VwdGlvbihTdHJpbmcgcmVhc29uKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgbnVsbCwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxSZWNvdmVyYWJsZUV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0bworICAgICAqIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4gU1FMU3RhdGUKKyAgICAgKiBzdHJpbmcgYW5kIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byAwLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMUmVjb3ZlcmFibGVFeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgU3RyaW5nIHNxbFN0YXRlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMUmVjb3ZlcmFibGVFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8KKyAgICAgKiB0aGUgZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gdGhlIGdpdmVuIFNRTFN0YXRlCisgICAgICogc3RyaW5nIGFuZCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gdGhlIGdpdmVuIGVycm9yIGNvZGUgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqIEBwYXJhbSB2ZW5kb3JDb2RlCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB2YWx1ZSBmb3IgdGhlIGVycm9yIGNvZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMUmVjb3ZlcmFibGVFeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgU3RyaW5nIHNxbFN0YXRlLAorICAgICAgICAgICAgaW50IHZlbmRvckNvZGUpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgdmVuZG9yQ29kZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxSZWNvdmVyYWJsZUV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0bworICAgICAqIHRoZSBudWxsIGlmIGNhdXNlID09IG51bGwgb3IgY2F1c2UudG9TdHJpbmcoKSBpZiBjYXVzZSE9bnVsbCxhbmQgdGhlCisgICAgICogY2F1c2UgVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTFJlY292ZXJhYmxlRXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxSZWNvdmVyYWJsZUV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0bworICAgICAqIHRoZSBnaXZlbiBhbmQgdGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZQorICAgICAqIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMUmVjb3ZlcmFibGVFeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMUmVjb3ZlcmFibGVFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8KKyAgICAgKiB0aGUgZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gdGhlIGdpdmVuIFNRTFN0YXRlCisgICAgICogc3RyaW5nIGFuZCB0aGUgY2F1c2UgVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlIFRocm93YWJsZQorICAgICAqIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICogQHBhcmFtIHNxbFN0YXRlCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgU1FMU3RhdGUgc3RyaW5nCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxSZWNvdmVyYWJsZUV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsCisgICAgICAgICAgICBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMUmVjb3ZlcmFibGVFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8KKyAgICAgKiB0aGUgZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gdGhlIGdpdmVuIFNRTFN0YXRlCisgICAgICogc3RyaW5nICwgdGhlIEVycm9yIENvZGUgaXMgc2V0IHRvIHRoZSBnaXZlbiBlcnJvciBjb2RlIHZhbHVlLCBhbmQgdGhlCisgICAgICogY2F1c2UgVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqIEBwYXJhbSB2ZW5kb3JDb2RlCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB2YWx1ZSBmb3IgdGhlIGVycm9yIGNvZGUKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTFJlY292ZXJhYmxlRXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBzcWxTdGF0ZSwKKyAgICAgICAgICAgIGludCB2ZW5kb3JDb2RlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgdmVuZG9yQ29kZSwgY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxTeW50YXhFcnJvckV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTFN5bnRheEVycm9yRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTI1ZTUyMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxTeW50YXhFcnJvckV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTQxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworcHVibGljIGNsYXNzIFNRTFN5bnRheEVycm9yRXhjZXB0aW9uIGV4dGVuZHMgU1FMTm9uVHJhbnNpZW50RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xODQzODMyNjEwNDc3NDk2MDUzTDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMU3ludGF4RXJyb3JFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8KKyAgICAgKiBudWxsLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byBudWxsIGFuZCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMU3ludGF4RXJyb3JFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxTeW50YXhFcnJvckV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0bworICAgICAqIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byBudWxsIGFuZCB0aGUgRXJyb3IKKyAgICAgKiBDb2RlIGlzIHNldCB0byAwLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMU3ludGF4RXJyb3JFeGNlcHRpb24oU3RyaW5nIHJlYXNvbikgeworICAgICAgICBzdXBlcihyZWFzb24sIG51bGwsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMU3ludGF4RXJyb3JFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8KKyAgICAgKiB0aGUgZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gdGhlIGdpdmVuIFNRTFN0YXRlCisgICAgICogc3RyaW5nIGFuZCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gMC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICogQHBhcmFtIHNxbFN0YXRlCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgU1FMU3RhdGUgc3RyaW5nCisgICAgICovCisgICAgcHVibGljIFNRTFN5bnRheEVycm9yRXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBzcWxTdGF0ZSkgeworICAgICAgICBzdXBlcihyZWFzb24sIHNxbFN0YXRlLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTFN5bnRheEVycm9yRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvCisgICAgICogdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbiBTUUxTdGF0ZQorICAgICAqIHN0cmluZyBhbmQgdGhlIEVycm9yIENvZGUgaXMgc2V0IHRvIHRoZSBnaXZlbiBlcnJvciBjb2RlIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdmVuZG9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZSBlcnJvciBjb2RlCisgICAgICovCisgICAgcHVibGljIFNRTFN5bnRheEVycm9yRXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBzcWxTdGF0ZSwKKyAgICAgICAgICAgIGludCB2ZW5kb3JDb2RlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIHZlbmRvckNvZGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMU3ludGF4RXJyb3JFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8KKyAgICAgKiB0aGUgbnVsbCBpZiBjYXVzZSA9PSBudWxsIG9yIGNhdXNlLnRvU3RyaW5nKCkgaWYgY2F1c2UhPW51bGwsYW5kIHRoZQorICAgICAqIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZSBUaHJvd2FibGUgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxTeW50YXhFcnJvckV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMU3ludGF4RXJyb3JFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8KKyAgICAgKiB0aGUgZ2l2ZW4gYW5kIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UKKyAgICAgKiBUaHJvd2FibGUgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTFN5bnRheEVycm9yRXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihyZWFzb24sIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTFN5bnRheEVycm9yRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvCisgICAgICogdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbiBTUUxTdGF0ZQorICAgICAqIHN0cmluZyBhbmQgdGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZSBUaHJvd2FibGUKKyAgICAgKiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMU3ludGF4RXJyb3JFeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgU3RyaW5nIHNxbFN0YXRlLAorICAgICAgICAgICAgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTFN5bnRheEVycm9yRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvCisgICAgICogdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbiBTUUxTdGF0ZQorICAgICAqIHN0cmluZyAsIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byB0aGUgZ2l2ZW4gZXJyb3IgY29kZSB2YWx1ZSwgYW5kIHRoZQorICAgICAqIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZSBUaHJvd2FibGUgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdmVuZG9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZSBlcnJvciBjb2RlCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxTeW50YXhFcnJvckV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsCisgICAgICAgICAgICBpbnQgdmVuZG9yQ29kZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIHZlbmRvckNvZGUsIGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMVGltZW91dEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTFRpbWVvdXRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMzFjNzBlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTFRpbWVvdXRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDEzOSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zcWw7CisKK3B1YmxpYyBjbGFzcyBTUUxUaW1lb3V0RXhjZXB0aW9uIGV4dGVuZHMgU1FMVHJhbnNpZW50RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00NDg3MTcxMjgwNTYyNTIwMjYyTDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMVGltZW91dEV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0byBudWxsLAorICAgICAqIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIG51bGwgYW5kIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byAwLgorICAgICAqLworICAgIHB1YmxpYyBTUUxUaW1lb3V0RXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMVGltZW91dEV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0byB0aGUKKyAgICAgKiBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byBudWxsIGFuZCB0aGUgRXJyb3IKKyAgICAgKiBDb2RlIGlzIHNldCB0byAwLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMVGltZW91dEV4Y2VwdGlvbihTdHJpbmcgcmVhc29uKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgbnVsbCwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxUaW1lb3V0RXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvIHRoZQorICAgICAqIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbiBTUUxTdGF0ZQorICAgICAqIHN0cmluZyBhbmQgdGhlIEVycm9yIENvZGUgaXMgc2V0IHRvIDAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqLworICAgIHB1YmxpYyBTUUxUaW1lb3V0RXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBzcWxTdGF0ZSkgeworICAgICAgICBzdXBlcihyZWFzb24sIHNxbFN0YXRlLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTFRpbWVvdXRFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8gdGhlCisgICAgICogZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gdGhlIGdpdmVuIFNRTFN0YXRlCisgICAgICogc3RyaW5nIGFuZCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gdGhlIGdpdmVuIGVycm9yIGNvZGUgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqIEBwYXJhbSB2ZW5kb3JDb2RlCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB2YWx1ZSBmb3IgdGhlIGVycm9yIGNvZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMVGltZW91dEV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsIGludCB2ZW5kb3JDb2RlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIHZlbmRvckNvZGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMVGltZW91dEV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0byB0aGUKKyAgICAgKiBudWxsIGlmIGNhdXNlID09IG51bGwgb3IgY2F1c2UudG9TdHJpbmcoKSBpZiBjYXVzZSE9bnVsbCxhbmQgdGhlIGNhdXNlCisgICAgICogVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTFRpbWVvdXRFeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTFRpbWVvdXRFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8gdGhlCisgICAgICogZ2l2ZW4gYW5kIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UgVGhyb3dhYmxlCisgICAgICogb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTFRpbWVvdXRFeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMVGltZW91dEV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0byB0aGUKKyAgICAgKiBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4gU1FMU3RhdGUKKyAgICAgKiBzdHJpbmcgYW5kIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UgVGhyb3dhYmxlCisgICAgICogb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTFRpbWVvdXRFeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgU3RyaW5nIHNxbFN0YXRlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMVGltZW91dEV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0byB0aGUKKyAgICAgKiBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4gU1FMU3RhdGUKKyAgICAgKiBzdHJpbmcgLCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gdGhlIGdpdmVuIGVycm9yIGNvZGUgdmFsdWUsIGFuZCB0aGUKKyAgICAgKiBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UgVGhyb3dhYmxlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICogQHBhcmFtIHNxbFN0YXRlCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgU1FMU3RhdGUgc3RyaW5nCisgICAgICogQHBhcmFtIHZlbmRvckNvZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnRlZ2VyIHZhbHVlIGZvciB0aGUgZXJyb3IgY29kZQorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMVGltZW91dEV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsIGludCB2ZW5kb3JDb2RlLAorICAgICAgICAgICAgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIHZlbmRvckNvZGUsIGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMVHJhbnNhY3Rpb25Sb2xsYmFja0V4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTFRyYW5zYWN0aW9uUm9sbGJhY2tFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNTI1Y2Y5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTFRyYW5zYWN0aW9uUm9sbGJhY2tFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDE0MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zcWw7CisKK3B1YmxpYyBjbGFzcyBTUUxUcmFuc2FjdGlvblJvbGxiYWNrRXhjZXB0aW9uIGV4dGVuZHMgU1FMVHJhbnNpZW50RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDUyNDY2ODA4NDExNzA4MzcyMjlMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxUcmFuc2FjdGlvblJvbGxiYWNrRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMKKyAgICAgKiBzZXQgdG8gbnVsbCwgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gbnVsbCBhbmQgdGhlIEVycm9yIENvZGUgaXMgc2V0CisgICAgICogdG8gMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMVHJhbnNhY3Rpb25Sb2xsYmFja0V4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTFRyYW5zYWN0aW9uUm9sbGJhY2tFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcworICAgICAqIHNldCB0byB0aGUgZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gbnVsbCBhbmQKKyAgICAgKiB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gMC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICovCisgICAgcHVibGljIFNRTFRyYW5zYWN0aW9uUm9sbGJhY2tFeGNlcHRpb24oU3RyaW5nIHJlYXNvbikgeworICAgICAgICBzdXBlcihyZWFzb24sIG51bGwsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMVHJhbnNhY3Rpb25Sb2xsYmFja0V4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzCisgICAgICogc2V0IHRvIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4KKyAgICAgKiBTUUxTdGF0ZSBzdHJpbmcgYW5kIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byAwLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMVHJhbnNhY3Rpb25Sb2xsYmFja0V4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxUcmFuc2FjdGlvblJvbGxiYWNrRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMKKyAgICAgKiBzZXQgdG8gdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbgorICAgICAqIFNRTFN0YXRlIHN0cmluZyBhbmQgdGhlIEVycm9yIENvZGUgaXMgc2V0IHRvIHRoZSBnaXZlbiBlcnJvciBjb2RlIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdmVuZG9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZSBlcnJvciBjb2RlCisgICAgICovCisgICAgcHVibGljIFNRTFRyYW5zYWN0aW9uUm9sbGJhY2tFeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgU3RyaW5nIHNxbFN0YXRlLAorICAgICAgICAgICAgaW50IHZlbmRvckNvZGUpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgdmVuZG9yQ29kZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxUcmFuc2FjdGlvblJvbGxiYWNrRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMKKyAgICAgKiBzZXQgdG8gdGhlIG51bGwgaWYgY2F1c2UgPT0gbnVsbCBvciBjYXVzZS50b1N0cmluZygpIGlmIGNhdXNlIT1udWxsLGFuZAorICAgICAqIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UgVGhyb3dhYmxlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMVHJhbnNhY3Rpb25Sb2xsYmFja0V4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMVHJhbnNhY3Rpb25Sb2xsYmFja0V4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzCisgICAgICogc2V0IHRvIHRoZSBnaXZlbiBhbmQgdGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZQorICAgICAqIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMVHJhbnNhY3Rpb25Sb2xsYmFja0V4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxUcmFuc2FjdGlvblJvbGxiYWNrRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMKKyAgICAgKiBzZXQgdG8gdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbgorICAgICAqIFNRTFN0YXRlIHN0cmluZyBhbmQgdGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZQorICAgICAqIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMVHJhbnNhY3Rpb25Sb2xsYmFja0V4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsCisgICAgICAgICAgICBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMVHJhbnNhY3Rpb25Sb2xsYmFja0V4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzCisgICAgICogc2V0IHRvIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4KKyAgICAgKiBTUUxTdGF0ZSBzdHJpbmcgLCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gdGhlIGdpdmVuIGVycm9yIGNvZGUgdmFsdWUsCisgICAgICogYW5kIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UgVGhyb3dhYmxlCisgICAgICogb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdmVuZG9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZSBlcnJvciBjb2RlCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxUcmFuc2FjdGlvblJvbGxiYWNrRXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBzcWxTdGF0ZSwKKyAgICAgICAgICAgIGludCB2ZW5kb3JDb2RlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgdmVuZG9yQ29kZSwgY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxUcmFuc2llbnRDb25uZWN0aW9uRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ4MThmOTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTQzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworcHVibGljIGNsYXNzIFNRTFRyYW5zaWVudENvbm5lY3Rpb25FeGNlcHRpb24gZXh0ZW5kcyBTUUxUcmFuc2llbnRFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTI1MjAxNTU1NTM1NDMzOTEyMDBMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxUcmFuc2llbnRDb25uZWN0aW9uRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMKKyAgICAgKiBzZXQgdG8gbnVsbCwgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gbnVsbCBhbmQgdGhlIEVycm9yIENvZGUgaXMgc2V0CisgICAgICogdG8gMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTFRyYW5zaWVudENvbm5lY3Rpb25FeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcworICAgICAqIHNldCB0byB0aGUgZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gbnVsbCBhbmQKKyAgICAgKiB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gMC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICovCisgICAgcHVibGljIFNRTFRyYW5zaWVudENvbm5lY3Rpb25FeGNlcHRpb24oU3RyaW5nIHJlYXNvbikgeworICAgICAgICBzdXBlcihyZWFzb24sIG51bGwsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzCisgICAgICogc2V0IHRvIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4KKyAgICAgKiBTUUxTdGF0ZSBzdHJpbmcgYW5kIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byAwLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxUcmFuc2llbnRDb25uZWN0aW9uRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMKKyAgICAgKiBzZXQgdG8gdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbgorICAgICAqIFNRTFN0YXRlIHN0cmluZyBhbmQgdGhlIEVycm9yIENvZGUgaXMgc2V0IHRvIHRoZSBnaXZlbiBlcnJvciBjb2RlIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdmVuZG9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZSBlcnJvciBjb2RlCisgICAgICovCisgICAgcHVibGljIFNRTFRyYW5zaWVudENvbm5lY3Rpb25FeGNlcHRpb24oU3RyaW5nIHJlYXNvbiwgU3RyaW5nIHNxbFN0YXRlLAorICAgICAgICAgICAgaW50IHZlbmRvckNvZGUpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgdmVuZG9yQ29kZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxUcmFuc2llbnRDb25uZWN0aW9uRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMKKyAgICAgKiBzZXQgdG8gdGhlIG51bGwgaWYgY2F1c2UgPT0gbnVsbCBvciBjYXVzZS50b1N0cmluZygpIGlmIGNhdXNlIT1udWxsLGFuZAorICAgICAqIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UgVGhyb3dhYmxlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzCisgICAgICogc2V0IHRvIHRoZSBnaXZlbiBhbmQgdGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZQorICAgICAqIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxUcmFuc2llbnRDb25uZWN0aW9uRXhjZXB0aW9uIG9iamVjdC4gVGhlIFJlYXNvbiBzdHJpbmcgaXMKKyAgICAgKiBzZXQgdG8gdGhlIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbgorICAgICAqIFNRTFN0YXRlIHN0cmluZyBhbmQgdGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZQorICAgICAqIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsCisgICAgICAgICAgICBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMVHJhbnNpZW50Q29ubmVjdGlvbkV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzCisgICAgICogc2V0IHRvIHRoZSBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4KKyAgICAgKiBTUUxTdGF0ZSBzdHJpbmcgLCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gdGhlIGdpdmVuIGVycm9yIGNvZGUgdmFsdWUsCisgICAgICogYW5kIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UgVGhyb3dhYmxlCisgICAgICogb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gdmVuZG9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgZm9yIHRoZSBlcnJvciBjb2RlCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxUcmFuc2llbnRDb25uZWN0aW9uRXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBzcWxTdGF0ZSwKKyAgICAgICAgICAgIGludCB2ZW5kb3JDb2RlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgdmVuZG9yQ29kZSwgY2F1c2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxUcmFuc2llbnRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TUUxUcmFuc2llbnRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMGFlYzE3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTFRyYW5zaWVudEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTM5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworcHVibGljIGNsYXNzIFNRTFRyYW5zaWVudEV4Y2VwdGlvbiBleHRlbmRzIFNRTEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtOTA0MjczMzk3ODI2MjI3NDUzOUw7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTFRyYW5zaWVudEV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0bworICAgICAqIG51bGwsIHRoZSBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIG51bGwgYW5kIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byAwLgorICAgICAqLworICAgIHB1YmxpYyBTUUxUcmFuc2llbnRFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxUcmFuc2llbnRFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8gdGhlCisgICAgICogZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gbnVsbCBhbmQgdGhlIEVycm9yCisgICAgICogQ29kZSBpcyBzZXQgdG8gMC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICovCisgICAgcHVibGljIFNRTFRyYW5zaWVudEV4Y2VwdGlvbihTdHJpbmcgcmVhc29uKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgbnVsbCwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxUcmFuc2llbnRFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8gdGhlCisgICAgICogZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gdGhlIGdpdmVuIFNRTFN0YXRlCisgICAgICogc3RyaW5nIGFuZCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gMC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBSZWFzb24gc3RyaW5nCisgICAgICogQHBhcmFtIHNxbFN0YXRlCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgU1FMU3RhdGUgc3RyaW5nCisgICAgICovCisgICAgcHVibGljIFNRTFRyYW5zaWVudEV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxUcmFuc2llbnRFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8gdGhlCisgICAgICogZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gdGhlIGdpdmVuIFNRTFN0YXRlCisgICAgICogc3RyaW5nIGFuZCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gdGhlIGdpdmVuIGVycm9yIGNvZGUgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqIEBwYXJhbSB2ZW5kb3JDb2RlCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB2YWx1ZSBmb3IgdGhlIGVycm9yIGNvZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMVHJhbnNpZW50RXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFN0cmluZyBzcWxTdGF0ZSwgaW50IHZlbmRvckNvZGUpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBzcWxTdGF0ZSwgdmVuZG9yQ29kZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxUcmFuc2llbnRFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8gdGhlCisgICAgICogbnVsbCBpZiBjYXVzZSA9PSBudWxsIG9yIGNhdXNlLnRvU3RyaW5nKCkgaWYgY2F1c2UhPW51bGwsYW5kIHRoZSBjYXVzZQorICAgICAqIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZSBUaHJvd2FibGUgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlCisgICAgICogICAgICAgICAgICB0aGUgVGhyb3dhYmxlIG9iamVjdCBmb3IgdGhlIHVuZGVybHlpbmcgcmVhc29uIHRoaXMKKyAgICAgKiAgICAgICAgICAgIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTUUxUcmFuc2llbnRFeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTFRyYW5zaWVudEV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0byB0aGUKKyAgICAgKiBnaXZlbiBhbmQgdGhlIGNhdXNlIFRocm93YWJsZSBvYmplY3QgaXMgc2V0IHRvIHRoZSBnaXZlbiBjYXVzZSBUaHJvd2FibGUKKyAgICAgKiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIFRocm93YWJsZSBvYmplY3QgZm9yIHRoZSB1bmRlcmx5aW5nIHJlYXNvbiB0aGlzCisgICAgICogICAgICAgICAgICBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMVHJhbnNpZW50RXhjZXB0aW9uKFN0cmluZyByZWFzb24sIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihyZWFzb24sIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTFRyYW5zaWVudEV4Y2VwdGlvbiBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0byB0aGUKKyAgICAgKiBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUgU1FMU3RhdGUgc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4gU1FMU3RhdGUKKyAgICAgKiBzdHJpbmcgYW5kIHRoZSBjYXVzZSBUaHJvd2FibGUgb2JqZWN0IGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UgVGhyb3dhYmxlCisgICAgICogb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFJlYXNvbiBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3FsU3RhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gdXNlIGFzIHRoZSBTUUxTdGF0ZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTFRyYW5zaWVudEV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihyZWFzb24sIHNxbFN0YXRlLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBTUUxUcmFuc2llbnRFeGNlcHRpb24gb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8gdGhlCisgICAgICogZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gdGhlIGdpdmVuIFNRTFN0YXRlCisgICAgICogc3RyaW5nICwgdGhlIEVycm9yIENvZGUgaXMgc2V0IHRvIHRoZSBnaXZlbiBlcnJvciBjb2RlIHZhbHVlLCBhbmQgdGhlCisgICAgICogY2F1c2UgVGhyb3dhYmxlIG9iamVjdCBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlIFRocm93YWJsZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHVzZSBhcyB0aGUgUmVhc29uIHN0cmluZworICAgICAqIEBwYXJhbSBzcWxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIFNRTFN0YXRlIHN0cmluZworICAgICAqIEBwYXJhbSB2ZW5kb3JDb2RlCisgICAgICogICAgICAgICAgICB0aGUgaW50ZWdlciB2YWx1ZSBmb3IgdGhlIGVycm9yIGNvZGUKKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaHJvd2FibGUgb2JqZWN0IGZvciB0aGUgdW5kZXJseWluZyByZWFzb24gdGhpcworICAgICAqICAgICAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNRTFRyYW5zaWVudEV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBTdHJpbmcgc3FsU3RhdGUsCisgICAgICAgICAgICBpbnQgdmVuZG9yQ29kZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgc3FsU3RhdGUsIHZlbmRvckNvZGUsIGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMV2FybmluZy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTFdhcm5pbmcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYWQ1ZDFmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTFdhcm5pbmcuamF2YQpAQCAtMCwwICsxLDE1MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zcWw7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworLyoqCisgKiBBbiBleGNlcHRpb24gY2xhc3MgdGhhdCBob2xkcyBpbmZvcm1hdGlvbiBhYm91dCBEYXRhYmFzZSBhY2Nlc3Mgd2FybmluZ3MuCisgKi8KK3B1YmxpYyBjbGFzcyBTUUxXYXJuaW5nIGV4dGVuZHMgU1FMRXhjZXB0aW9uIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDM5MTczMzY3NzQ2MDQ3ODQ4NTZMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiB7QGNvZGUgU1FMV2FybmluZ30gb2JqZWN0LiBUaGUgcmVhc29uIHN0cmluZyBpcyBzZXQgdG8ge0Bjb2RlCisgICAgICogbnVsbH0sIHRoZSB7QGNvZGUgU1FMU3RhdGV9IHN0cmluZyBpcyBzZXQgdG8ge0Bjb2RlIG51bGx9IGFuZCB0aGUgZXJyb3IKKyAgICAgKiBjb2RlIGlzIHNldCB0byAwLgorICAgICAqLworICAgIHB1YmxpYyBTUUxXYXJuaW5nKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4ge0Bjb2RlIFNRTFdhcm5pbmd9IG9iamVjdC4gVGhlIHJlYXNvbiBzdHJpbmcgaXMgc2V0IHRvIHRoZQorICAgICAqIGdpdmVuIHJlYXNvbiBzdHJpbmcsIHRoZSB7QGNvZGUgU1FMU3RhdGV9IHN0cmluZyBpcyBzZXQgdG8ge0Bjb2RlIG51bGx9CisgICAgICogYW5kIHRoZSBlcnJvciBjb2RlIGlzIHNldCB0byAwLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZVJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIHJlYXNvbiB3aHkgdGhpcyB3YXJuaW5nIGlzIGlzc3VlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMV2FybmluZyhTdHJpbmcgdGhlUmVhc29uKSB7CisgICAgICAgIHN1cGVyKHRoZVJlYXNvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiB7QGNvZGUgU1FMV2FybmluZ30gb2JqZWN0LiBUaGUgcmVhc29uIHN0cmluZyBpcyBzZXQgdG8gdGhlCisgICAgICogZ2l2ZW4gcmVhc29uIHN0cmluZywgdGhlIHtAY29kZSBTUUxTdGF0ZX0gc3RyaW5nIGlzIHNldCB0byB0aGUgZ2l2ZW4KKyAgICAgKiB7QGNvZGUgU1FMU3RhdGV9IHN0cmluZyBhbmQgdGhlIGVycm9yIGNvZGUgaXMgc2V0IHRvIDAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlUmVhc29uCisgICAgICogICAgICAgICAgICB0aGUgcmVhc29uIHdoeSB0aGlzIHdhcm5pbmcgaXMgaXNzdWVkLgorICAgICAqIEBwYXJhbSB0aGVTUUxTdGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byB1c2UgYXMgdGhlIHtAY29kZSBTUUxTdGF0ZX0gc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBTUUxXYXJuaW5nKFN0cmluZyB0aGVSZWFzb24sIFN0cmluZyB0aGVTUUxTdGF0ZSkgeworICAgICAgICBzdXBlcih0aGVSZWFzb24sIHRoZVNRTFN0YXRlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIHtAY29kZSBTUUxXYXJuaW5nfSBvYmplY3QuIFRoZSByZWFzb24gc3RyaW5nIGlzIHNldCB0byB0aGUKKyAgICAgKiBnaXZlbiByZWFzb24gc3RyaW5nLCB0aGUge0Bjb2RlIFNRTFN0YXRlfSBzdHJpbmcgaXMgc2V0IHRvIHRoZSBnaXZlbgorICAgICAqIHtAY29kZSBTUUxTdGF0ZX0gc3RyaW5nIGFuZCB0aGUgZXJyb3IgY29kZSBpcyBzZXQgdG8gdGhlIGdpdmVuIGVycm9yIGNvZGUKKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVSZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSByZWFzb24gd2h5IHRoaXMgd2FybmluZyBpcyBpc3N1ZWQuCisgICAgICogQHBhcmFtIHRoZVNRTFN0YXRlCisgICAgICogICAgICAgICAgICB0aGUgWC9PcGVuIHN0YW5kYXJkIHNwZWNpZmMgZXJyb3IgY29kZS4KKyAgICAgKiBAcGFyYW0gdGhlRXJyb3JDb2RlCisgICAgICogICAgICAgICAgICBhIHZlbmRvciBzcGVjaWZpYyBlcnJvciBjb2RlLgorICAgICAqLworICAgIHB1YmxpYyBTUUxXYXJuaW5nKFN0cmluZyB0aGVSZWFzb24sIFN0cmluZyB0aGVTUUxTdGF0ZSwgaW50IHRoZUVycm9yQ29kZSkgeworICAgICAgICBzdXBlcih0aGVSZWFzb24sIHRoZVNRTFN0YXRlLCB0aGVFcnJvckNvZGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMV2FybmluZyBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0byBudWxsLCB0aGUKKyAgICAgKiBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIG51bGwgYW5kIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0byAwLCBjYXVzZSBpcworICAgICAqIHNldCB0byBjYXVzZS4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMV2FybmluZyhUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMV2FybmluZyBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0byByZWFzb24sIHRoZQorICAgICAqIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gbnVsbCBhbmQgdGhlIEVycm9yIENvZGUgaXMgc2V0IHRvIDAsIGNhdXNlIGlzCisgICAgICogc2V0IHRvIHRoZSBnaXZlbiBjYXVzZQorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBTUUxXYXJuaW5nKFN0cmluZyByZWFzb24sIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihyZWFzb24sIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIFNRTFdhcm5pbmcgb2JqZWN0LiBUaGUgUmVhc29uIHN0cmluZyBpcyBzZXQgdG8gcmVhc29uLCB0aGUKKyAgICAgKiBTUUxTdGF0ZSBzdHJpbmcgaXMgc2V0IHRvIGdpdmVuIFNRTFN0YXRlIGFuZCB0aGUgRXJyb3IgQ29kZSBpcyBzZXQgdG8gMCwKKyAgICAgKiBjYXVzZSBpcyBzZXQgdG8gdGhlIGdpdmVuIGNhdXNlCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIFNRTFdhcm5pbmcoU3RyaW5nIHJlYXNvbiwgU3RyaW5nIFNRTFN0YXRlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBTUUxTdGF0ZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gU1FMV2FybmluZyBvYmplY3QuIFRoZSBSZWFzb24gc3RyaW5nIGlzIHNldCB0byByZWFzb24sIHRoZQorICAgICAqIFNRTFN0YXRlIHN0cmluZyBpcyBzZXQgdG8gZ2l2ZW4gU1FMU3RhdGUgYW5kIHRoZSBFcnJvciBDb2RlIGlzIHNldCB0bworICAgICAqIHZlbmRvckNvZGUsIGNhdXNlIGlzIHNldCB0byB0aGUgZ2l2ZW4gY2F1c2UKKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMV2FybmluZyhTdHJpbmcgcmVhc29uLCBTdHJpbmcgU1FMU3RhdGUsIGludCB2ZW5kb3JDb2RlLAorICAgICAgICAgICAgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbiwgU1FMU3RhdGUsIHZlbmRvckNvZGUsIGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBuZXh0IHtAY29kZSBTUUxXYXJuaW5nfSBjaGFpbmVkIHRvIHRoaXMge0Bjb2RlIFNRTFdhcm5pbmd9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBTUUxXYXJuaW5nfSBjaGFpbmVkIHRvIHRoaXMge0Bjb2RlIFNRTFdhcm5pbmd9LgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlmIG5vIHtAY29kZSBTUUxXYXJuaW5nfSBpcyBjaGFpbmVkIHRvIHRoaXMge0Bjb2RlCisgICAgICogICAgICAgICBTUUxXYXJuaW5nfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMV2FybmluZyBnZXROZXh0V2FybmluZygpIHsKKyAgICAgICAgU1FMRXhjZXB0aW9uIG5leHQgPSBzdXBlci5nZXROZXh0RXhjZXB0aW9uKCk7CisgICAgICAgIGlmIChuZXh0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGlmIChuZXh0IGluc3RhbmNlb2YgU1FMV2FybmluZykgeworICAgICAgICAgICAgcmV0dXJuIChTUUxXYXJuaW5nKSBuZXh0OworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBFcnJvcigiU1FMV2FybmluZyBjaGFpbiBob2xkcyB2YWx1ZSB0aGF0IGlzIG5vdCBhIFNRTFdhcm5pbmciKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGFpbnMgYSBzdXBwbGllZCB7QGNvZGUgU1FMV2FybmluZ30gdG8gdGhpcyB7QGNvZGUgU1FMV2FybmluZ30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBTUUxXYXJuaW5nfSBsaW5rZWQgdG8gdGhpcyB7QGNvZGUgU1FMV2FybmluZ30uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TmV4dFdhcm5pbmcoU1FMV2FybmluZyB3KSB7CisgICAgICAgIHN1cGVyLnNldE5leHRFeGNlcHRpb24odyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTFhNTC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NRTFhNTC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA5NTA5YTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU1FMWE1MLmphdmEKQEAgLTAsMCArMSw4NiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zcWw7CisKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUmVhZGVyOworaW1wb3J0IGphdmEuaW8uV3JpdGVyOworaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OworaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOworCisvKioKKyAqIE1hcHMgU1FMJ3MgWE1MIHR5cGUgaW50byBKYXZhLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFNRTFhNTCB7CisgICAgLyoqCisgICAgICogRnJlZXMgYW55IHJlc291cmNlcyBoZWxkIGJ5IHRoaXMgb2JqZWN0LiBBZnRlciB7QGNvZGUgZnJlZX0gaXMgY2FsbGVkLCBjYWxsaW5nCisgICAgICogbWV0aG9kIG90aGVyIHRoYW4ge0Bjb2RlIGZyZWV9IHdpbGwgdGhyb3cge0Bjb2RlIFNRTEV4Y2VwdGlvbn0gKGNhbGxpbmcge0Bjb2RlIGZyZWV9CisgICAgICogcmVwZWF0ZWRseSB3aWxsIGRvIG5vdGhpbmcpLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgdm9pZCBmcmVlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJlYW0gdGhhdCBjYW4gYmUgdXNlZCB0byByZWFkIGJpbmFyeSBkYXRhIGZyb20gdGhpcyBTUUwge0Bjb2RlIFhNTH0gb2JqZWN0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGEKKyAgICAgKi8KKyAgICBJbnB1dFN0cmVhbSBnZXRCaW5hcnlTdHJlYW0oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmVhbSB0aGF0IGNhbiBiZSB1c2VkIHRvIHdyaXRlIGJpbmFyeSBkYXRhIHRvIHRoaXMgU1FMIHtAY29kZSBYTUx9IG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhCisgICAgICovCisgICAgT3V0cHV0U3RyZWFtIHNldEJpbmFyeVN0cmVhbSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcmVhZGVyIHRoYXQgY2FuIGJlIHVzZWQgdG8gcmVhZCBjaGFyYWN0ZXIgZGF0YSBmcm9tIHRoaXMgU1FMIHtAY29kZSBYTUx9IG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhCisgICAgICovCisgICAgUmVhZGVyIGdldENoYXJhY3RlclN0cmVhbSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgd3JpdGVyIHRoYXQgY2FuIGJlIHVzZWQgdG8gd3JpdGUgY2hhcmFjdGVyIGRhdGEgdG8gdGhpcyBTUUwge0Bjb2RlIFhNTH0gb2JqZWN0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGEKKyAgICAgKi8KKyAgICBXcml0ZXIgc2V0Q2hhcmFjdGVyU3RyZWFtKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBvYmplY3QncyBkYXRhIGFzIGFuIFhNTCBzdHJpbmcuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YQorICAgICAqLworICAgIFN0cmluZyBnZXRTdHJpbmcoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGlzIG9iamVjdCdzIGRhdGEgdG8gdGhlIGdpdmVuIFhNTCBzdHJpbmcuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YQorICAgICAqLworICAgIHZvaWQgc2V0U3RyaW5nKFN0cmluZyB2YWx1ZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGxpbmsgU291cmNlfSBmb3IgcmVhZGluZyB0aGlzIG9iamVjdCdzIGRhdGEuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YQorICAgICAqLworICAgIDxUIGV4dGVuZHMgU291cmNlPiBUIGdldFNvdXJjZShDbGFzczxUPiBzb3VyY2VDbGFzcykgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGxpbmsgUmVzdWx0fSBmb3Igd3JpdGluZyB0aGlzIG9iamVjdCdzIGRhdGEuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YQorICAgICAqLworICAgIDxUIGV4dGVuZHMgUmVzdWx0PiBUIHNldFJlc3VsdChDbGFzczxUPiByZXN1bHRDbGFzcykgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TYXZlcG9pbnQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TYXZlcG9pbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MjU3NGExCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1NhdmVwb2ludC5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCisvKioKKyAqIEEgc2F2ZXBvaW50IGlzIGFuIGluc3RhbnQgZHVyaW5nIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uIHRoYXQgY2FuIGJlIHV0aWxpemVkCisgKiBieSBhIHJvbGxiYWNrIHZpYSB0aGUge0BsaW5rIENvbm5lY3Rpb24jcm9sbGJhY2t9IGNvbW1hbmQuIFJvbGxpbmcgYmFjayB0byBhCisgKiBwYXJ0aWN1bGFyIHNhdmVwb2ludCBtZWFucyB0aGF0IGFsbCBjaGFuZ2VzIHRoYXQgb2NjdXJyZWQgYWZ0ZXIgdGhhdAorICogc2F2ZXBvaW50IGFyZSB1bmRvbmUuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgU2F2ZXBvaW50IHsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNvbnN0cnVjdGVkIElEIGZvciB0aGlzIHNhdmVwb2ludC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIElEIGZvciB0aGlzIHNhdmVwb2ludC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFNhdmVwb2ludElkKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgZm9yIHRoaXMgc2F2ZXBvaW50LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGlzIHNhdmVwb2ludC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFNhdmVwb2ludE5hbWUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1N0YXRlbWVudC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1N0YXRlbWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFmN2UyOTcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU3RhdGVtZW50LmphdmEKQEAgLTAsMCArMSw2NzAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCisvKioKKyAqIEludGVyZmFjZSB1c2VkIGZvciBleGVjdXRpbmcgc3RhdGljIFNRTCBzdGF0ZW1lbnRzIHRvIHJldHJpZXZlIHF1ZXJ5IHJlc3VsdHMuCisgKiBUaGUgcmVzdWx0aW5nIHRhYmxlIHJvd3MgYXJlIHJldHVybmVkIGFzIHtAY29kZSBSZXN1bHRTZXR9cy4gRm9yIGFueSBnaXZlbgorICoge0Bjb2RlIFN0YXRlbWVudH0gb2JqZWN0LCBvbmx5IG9uZSB7QGNvZGUgUmVzdWx0U2V0fSBjYW4gYmUgb3BlbmVkIGF0IG9uZQorICogdGltZS4gQSBjYWxsIHRvIGFueSBvZiB0aGUgZXhlY3V0aW9uIG1ldGhvZHMgb2Yge0Bjb2RlIFN0YXRlbWVudH0gd2lsbCBjYXVzZQorICogYW55IHByZXZpb3VzbHkgY3JlYXRlZCB7QGNvZGUgUmVzdWx0U2V0fSBvYmplY3QgZm9yIHRoYXQge0Bjb2RlIFN0YXRlbWVudH0gdG8KKyAqIGJlIGNsb3NlZCBpbXBsaWNpdGx5LgorICogPHA+CisgKiBUbyBoYXZlIG11bHRpcGxlIHtAY29kZSBSZXN1bHRTZXR9IG9iamVjdHMgb3BlbmVkIGNvbmN1cnJlbnRseSwgbXVsdGlwbGUKKyAqIHtAY29kZSBTdGF0ZW1lbnR9IG9iamVjdHMgbXVzdCBiZSBjcmVhdGVkIGFuZCB0aGVuIGV4ZWN1dGVkLgorICogPHA+CisgKiBUbyBvYnRhaW4gc3VjaCBhbiBleGVjdXRhYmxlIHN0YXRlbWVudCBvbmUgbmVlZHMgdG8gaW52b2tlIHtAY29kZQorICogQ29ubmVjdGlvbiNjcmVhdGVTdGF0ZW1lbnR9LgorICoKKyAqIEBzZWUgUmVzdWx0U2V0CisgKiBAc2VlIENvbm5lY3Rpb24jY3JlYXRlU3RhdGVtZW50CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgU3RhdGVtZW50IGV4dGVuZHMgV3JhcHBlciwgQXV0b0Nsb3NlYWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBQYXNzaW5nIHRoaXMgY29uc3RhbnQgdG8ge0BsaW5rICNnZXRNb3JlUmVzdWx0c30gaW1wbGllcyB0aGF0IGFsbCB7QGNvZGUKKyAgICAgKiBSZXN1bHRTZXR9IG9iamVjdHMgcHJldmlvdXNseSBrZXB0IG9wZW4gc2hvdWxkIGJlIGNsb3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTE9TRV9BTExfUkVTVUxUUyA9IDM7CisKKyAgICAvKioKKyAgICAgKiBQYXNzaW5nIHRoaXMgY29uc3RhbnQgdG8ge0BsaW5rICNnZXRNb3JlUmVzdWx0c30gaW1wbGllcyB0aGF0IHRoZSBjdXJyZW50CisgICAgICoge0Bjb2RlIFJlc3VsdFNldH0gb2JqZWN0IHNob3VsZCBiZSBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xPU0VfQ1VSUkVOVF9SRVNVTFQgPSAxOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoYXQgYW4gZXJyb3Igd2FzIGVuY291bnRlcmVkIGR1cmluZyBleGVjdXRpb24gb2YgYSBiYXRjaAorICAgICAqIHN0YXRlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFWEVDVVRFX0ZBSUxFRCA9IC0zOworCisgICAgLyoqCisgICAgICogUGFzc2luZyB0aGlzIGNvbnN0YW50IHRvIDxpPmdldE1vcmVSZXN1bHRzPC9pPiBpbXBsaWVzIHRoYXQgdGhlIGN1cnJlbnQKKyAgICAgKiB7QGNvZGUgUmVzdWx0U2V0fSBvYmplY3Qgc2hvdWxkIG5vdCBiZSBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgS0VFUF9DVVJSRU5UX1JFU1VMVCA9IDI7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhhdCBnZW5lcmF0ZWQga2V5cyBzaG91bGQgbm90IGJlIGFjY2Vzc2libGUgZm9yIHJldHJpZXZhbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT19HRU5FUkFURURfS0VZUyA9IDI7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhhdCBnZW5lcmF0ZWQga2V5cyBzaG91bGQgYmUgYWNjZXNzaWJsZSBmb3IgcmV0cmlldmFsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFVFVSTl9HRU5FUkFURURfS0VZUyA9IDE7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhhdCBhIGJhdGNoIHN0YXRlbWVudCB3YXMgZXhlY3V0ZWQgd2l0aCBhIHN1Y2Nlc3NmdWwgcmVzdWx0LAorICAgICAqIGJ1dCBhIGNvdW50IG9mIHRoZSBudW1iZXIgb2Ygcm93cyBpdCBhZmZlY3RlZCBpcyB1bmF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVUNDRVNTX05PX0lORk8gPSAtMjsKKworICAgIC8qKgorICAgICAqIEFkZHMgYSBzcGVjaWZpZWQgU1FMIGNvbW1hbmQgdG8gdGhlIGxpc3Qgb2YgY29tbWFuZHMgZm9yIHRoaXMge0Bjb2RlCisgICAgICogU3RhdGVtZW50fS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbGlzdCBvZiBjb21tYW5kcyBpcyBleGVjdXRlZCBieSBpbnZva2luZyB0aGUge0Bjb2RlIGV4ZWN1dGVCYXRjaH0KKyAgICAgKiBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3FsCisgICAgICogICAgICAgICAgICB0aGUgU1FMIGNvbW1hbmQgYXMgYSBTdHJpbmcuIFR5cGljYWxseSBhbiB7QGNvZGUgSU5TRVJUfSBvcgorICAgICAqICAgICAgICAgICAge0Bjb2RlIFVQREFURX0gc3RhdGVtZW50LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2Ugb3IgdGhlIGRhdGFiYXNlCisgICAgICogICAgICAgICAgICAgZG9lcyBub3Qgc3VwcG9ydCBiYXRjaCB1cGRhdGVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZEJhdGNoKFN0cmluZyBzcWwpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDYW5jZWxzIHRoaXMgc3RhdGVtZW50J3MgZXhlY3V0aW9uIGlmIGJvdGggdGhlIGRhdGFiYXNlIGFuZCB0aGUgSkRCQworICAgICAqIGRyaXZlciBzdXBwb3J0IGFib3J0aW5nIGFuIFNRTCBzdGF0ZW1lbnQgaW4gZmxpZ2h0LiBUaGlzIG1ldGhvZCBjYW4gYmUKKyAgICAgKiB1c2VkIGJ5IG9uZSB0aHJlYWQgdG8gc3RvcCBhIHN0YXRlbWVudCB0aGF0IGlzIGV4ZWN1dGVkIG9uIGFub3RoZXIKKyAgICAgKiB0aHJlYWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNhbmNlbCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDbGVhcnMgdGhlIGN1cnJlbnQgbGlzdCBvZiBTUUwgY29tbWFuZHMgZm9yIHRoaXMgc3RhdGVtZW50LgorICAgICAqCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZSBvciB0aGUgZGF0YWJhc2UKKyAgICAgKiAgICAgICAgICAgICBkb2VzIG5vdCBzdXBwb3J0IGJhdGNoIHVwZGF0ZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXJCYXRjaCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDbGVhcnMgYWxsIHtAY29kZSBTUUxXYXJuaW5nc30gZnJvbSB0aGlzIHN0YXRlbWVudC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXJXYXJuaW5ncygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWxlYXNlcyB0aGlzIHN0YXRlbWVudCdzIGRhdGFiYXNlIGFuZCBKREJDIGRyaXZlciByZXNvdXJjZXMuCisgICAgICogPHA+CisgICAgICogVXNpbmcgdGhpcyBtZXRob2QgdG8gcmVsZWFzZSB0aGVzZSByZXNvdXJjZXMgYXMgc29vbiBhcyBwb3NzaWJsZSBpcworICAgICAqIHN0cm9uZ2x5IHJlY29tbWVuZGVkLgorICAgICAqIDxwPgorICAgICAqIE9uZSBzaG91bGQgbm90IHJlbHkgb24gdGhlIHJlc291cmNlcyBiZWluZyBhdXRvbWF0aWNhbGx5IHJlbGVhc2VkIHdoZW4KKyAgICAgKiBmaW5hbGl6ZWQgZHVyaW5nIGdhcmJhZ2UgY29sbGVjdGlvbi4gRG9pbmcgc28gY2FuIHJlc3VsdCBpbiB1bnByZWRpY3RhYmxlCisgICAgICogYmVoYXZpb3IgZm9yIHRoZSBhcHBsaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRXhlY3V0ZXMgYSBzdXBwbGllZCBTUUwgc3RhdGVtZW50LiBUaGlzIG1heSByZXR1cm4gbXVsdGlwbGUge0Bjb2RlCisgICAgICogUmVzdWx0U2V0fXMuCisgICAgICogPHA+CisgICAgICogVXNlIHRoZSB7QGNvZGUgZ2V0UmVzdWx0U2V0fSBvciB7QGNvZGUgZ2V0VXBkYXRlQ291bnR9IG1ldGhvZHMgdG8gZ2V0IHRoZQorICAgICAqIGZpcnN0IHJlc3VsdCBhbmQge0Bjb2RlIGdldE1vcmVSZXN1bHRzfSB0byBnZXQgYW55IHN1YnNlcXVlbnQgcmVzdWx0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBTUUwgc3RhdGVtZW50IHRvIGV4ZWN1dGUKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZmlyc3QgcmVzdWx0IGlzIGEge0Bjb2RlIFJlc3VsdFNldH0sIHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9IGlmIHRoZSBmaXJzdCByZXN1bHQgaXMgYW4gdXBkYXRlIGNvdW50IG9yIGlmIHRoZXJlIGlzIG5vCisgICAgICogICAgICAgICByZXN1bHQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBleGVjdXRlKFN0cmluZyBzcWwpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBFeGVjdXRlcyBhIHN1cHBsaWVkIFNRTCBzdGF0ZW1lbnQuIFRoaXMgbWF5IHJldHVybiBtdWx0aXBsZSB7QGNvZGUKKyAgICAgKiBSZXN1bHRTZXR9cy4gVGhpcyBtZXRob2QgYWxsb3dzIGNvbnRyb2wgb2Ygd2hldGhlciBhdXRvLWdlbmVyYXRlZCBLZXlzCisgICAgICogc2hvdWxkIGJlIG1hZGUgYXZhaWxhYmxlIGZvciByZXRyaWV2YWwsIGlmIHRoZSBTUUwgc3RhdGVtZW50IGlzIGFuCisgICAgICoge0Bjb2RlIElOU0VSVH0gc3RhdGVtZW50LgorICAgICAqIDxwPgorICAgICAqIFVzZSB0aGUge0Bjb2RlIGdldFJlc3VsdFNldH0gb3Ige0Bjb2RlIGdldFVwZGF0ZUNvdW50fSBtZXRob2RzIHRvIGdldCB0aGUKKyAgICAgKiBmaXJzdCByZXN1bHQgYW5kIHtAY29kZSBnZXRNb3JlUmVzdWx0c30gdG8gZ2V0IGFueSBzdWJzZXF1ZW50IHJlc3VsdHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3FsCisgICAgICogICAgICAgICAgICB0aGUgU1FMIHN0YXRlbWVudCB0byBleGVjdXRlLgorICAgICAqIEBwYXJhbSBhdXRvR2VuZXJhdGVkS2V5cworICAgICAqICAgICAgICAgICAgYSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0byBtYWtlIGF1dG8gZ2VuZXJhdGVkIGtleXMKKyAgICAgKiAgICAgICAgICAgIGF2YWlsYWJsZSBmb3IgcmV0cmlldmFsLiBUaGlzIHBhcmFtZXRlciBtdXN0IGJlIG9uZSBvZiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFN0YXRlbWVudC5OT19HRU5FUkFURURfS0VZU30gb3Ige0Bjb2RlCisgICAgICogICAgICAgICAgICBTdGF0ZW1lbnQuUkVUVVJOX0dFTkVSQVRFRF9LRVlTfS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiByZXN1bHRzIGV4aXN0cyBhbmQgdGhlIGZpcnN0IHJlc3VsdCBpcyBhIHtAY29kZQorICAgICAqICAgICAgICAgUmVzdWx0U2V0fSwge0Bjb2RlIGZhbHNlfSBpZiB0aGUgZmlyc3QgcmVzdWx0IGlzIGFuIHVwZGF0ZSBjb3VudAorICAgICAqICAgICAgICAgb3IgaWYgdGhlcmUgaXMgbm8gcmVzdWx0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXhlY3V0ZShTdHJpbmcgc3FsLCBpbnQgYXV0b0dlbmVyYXRlZEtleXMpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRXhlY3V0ZXMgdGhlIHN1cHBsaWVkIFNRTCBzdGF0ZW1lbnQuIFRoaXMgbWF5IHJldHVybiBtdWx0aXBsZSB7QGNvZGUKKyAgICAgKiBSZXN1bHRTZXR9cy4gVGhpcyBtZXRob2QgYWxsb3dzIHJldHJpZXZhbCBvZiBhdXRvIGdlbmVyYXRlZCBrZXlzCisgICAgICogc3BlY2lmaWVkIGJ5IHRoZSBzdXBwbGllZCBhcnJheSBvZiBjb2x1bW4gaW5kZXhlcywgaWYgdGhlIFNRTCBzdGF0ZW1lbnQKKyAgICAgKiBpcyBhbiB7QGNvZGUgSU5TRVJUfSBzdGF0ZW1lbnQuCisgICAgICogPHA+CisgICAgICogVXNlIHRoZSB7QGNvZGUgZ2V0UmVzdWx0U2V0fSBvciB7QGNvZGUgZ2V0VXBkYXRlQ291bnR9IG1ldGhvZHMgdG8gZ2V0IHRoZQorICAgICAqIGZpcnN0IHJlc3VsdCBhbmQge0Bjb2RlIGdldE1vcmVSZXN1bHRzfSB0byBnZXQgYW55IHN1YnNlcXVlbnQgcmVzdWx0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBTUUwgc3RhdGVtZW50IHRvIGV4ZWN1dGUuCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4ZXMKKyAgICAgKiAgICAgICAgICAgIGFuIGFycmF5IG9mIGluZGV4ZXMgb2YgdGhlIGNvbHVtbnMgaW4gdGhlIGluc2VydGVkIHJvdyB3aGljaAorICAgICAqICAgICAgICAgICAgc2hvdWxkIGJlIG1hZGUgYXZhaWxhYmxlIGZvciByZXRyaWV2YWwgdmlhIHRoZSB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIGdldEdlbmVyYXRlZEtleXN9IG1ldGhvZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZmlyc3QgcmVzdWx0IGlzIGEge0Bjb2RlIFJlc3VsdFNldH0sIHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9IGlmIHRoZSBmaXJzdCByZXN1bHQgaXMgYW4gdXBkYXRlIGNvdW50IG9yIGlmIHRoZXJlIGlzIG5vCisgICAgICogICAgICAgICByZXN1bHQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBleGVjdXRlKFN0cmluZyBzcWwsIGludFtdIGNvbHVtbkluZGV4ZXMpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBFeGVjdXRlcyB0aGUgc3VwcGxpZWQgU1FMIHN0YXRlbWVudC4gVGhpcyBtYXkgcmV0dXJuIG11bHRpcGxlIHtAY29kZQorICAgICAqIFJlc3VsdFNldH1zLiBUaGlzIG1ldGhvZCBhbGxvd3MgcmV0cmlldmFsIG9mIGF1dG8gZ2VuZXJhdGVkIGtleXMKKyAgICAgKiBzcGVjaWZpZWQgYnkgdGhlIHN1cHBsaWVkIGFycmF5IG9mIGNvbHVtbiBpbmRleGVzLCBpZiB0aGUgU1FMIHN0YXRlbWVudAorICAgICAqIGlzIGFuIHtAY29kZSBJTlNFUlR9IHN0YXRlbWVudC4KKyAgICAgKiA8cD4KKyAgICAgKiBVc2UgdGhlIHtAY29kZSBnZXRSZXN1bHRTZXR9IG9yIHtAY29kZSBnZXRVcGRhdGVDb3VudH0gbWV0aG9kcyB0byBnZXQgdGhlCisgICAgICogZmlyc3QgcmVzdWx0IGFuZCB7QGNvZGUgZ2V0TW9yZVJlc3VsdHN9IHRvIGdldCBhbnkgc3Vic2VxdWVudCByZXN1bHRzLgorICAgICAqCisgICAgICogQHBhcmFtIHNxbAorICAgICAqICAgICAgICAgICAgdGhlIFNRTCBzdGF0ZW1lbnQgdG8gZXhlY3V0ZS4KKyAgICAgKiBAcGFyYW0gY29sdW1uTmFtZXMKKyAgICAgKiAgICAgICAgICAgIGFuIGFycmF5IG9mIGNvbHVtbiBuYW1lcyBpbiB0aGUgaW5zZXJ0ZWQgcm93IHdoaWNoIHNob3VsZCBiZQorICAgICAqICAgICAgICAgICAgbWFkZSBhdmFpbGFibGUgZm9yIHJldHJpZXZhbCB2aWEgdGhlIHtAY29kZSBnZXRHZW5lcmF0ZWRLZXlzfQorICAgICAqICAgICAgICAgICAgbWV0aG9kLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBmaXJzdCByZXN1bHQgaXMgYSB7QGNvZGUgUmVzdWx0U2V0fSwge0Bjb2RlCisgICAgICogICAgICAgICBmYWxzZX0gaWYgdGhlIGZpcnN0IHJlc3VsdCBpcyBhbiB1cGRhdGUgY291bnQgb3IgaWYgdGhlcmUgaXMgbm8KKyAgICAgKiAgICAgICAgIHJlc3VsdAorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXhlY3V0ZShTdHJpbmcgc3FsLCBTdHJpbmdbXSBjb2x1bW5OYW1lcykKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTdWJtaXRzIGEgYmF0Y2ggb2YgU1FMIGNvbW1hbmRzIHRvIHRoZSBkYXRhYmFzZS4gUmV0dXJucyBhbiBhcnJheSBvZgorICAgICAqIHVwZGF0ZSBjb3VudHMsIGlmIGFsbCB0aGUgY29tbWFuZHMgZXhlY3V0ZSBzdWNjZXNzZnVsbHkuCisgICAgICogPHA+CisgICAgICogSWYgb25lIG9mIHRoZSBjb21tYW5kcyBpbiB0aGUgYmF0Y2ggZmFpbHMsIHRoaXMgbWV0aG9kIGNhbiB0aHJvdyBhCisgICAgICoge0BsaW5rIEJhdGNoVXBkYXRlRXhjZXB0aW9ufSBhbmQgdGhlIEpEQkMgZHJpdmVyIG1heSBvciBtYXkgbm90IHByb2Nlc3MKKyAgICAgKiB0aGUgcmVtYWluaW5nIGNvbW1hbmRzLiBUaGUgSkRCQyBkcml2ZXIgbXVzdCBiZWhhdmUgY29uc2lzdGVudGx5IHdpdGggdGhlCisgICAgICogdW5kZXJseWluZyBkYXRhYmFzZSwgZm9sbG93aW5nIHRoZSAiYWxsIG9yIG5vdGhpbmciIHByaW5jaXBsZS4gSWYgdGhlCisgICAgICogZHJpdmVyIGNvbnRpbnVlcyBwcm9jZXNzaW5nLCB0aGUgYXJyYXkgb2YgcmVzdWx0cyByZXR1cm5lZCBjb250YWlucyB0aGUKKyAgICAgKiBzYW1lIG51bWJlciBvZiBlbGVtZW50cyBhcyB0aGVyZSBhcmUgY29tbWFuZHMgaW4gdGhlIGJhdGNoLCB3aXRoIGEKKyAgICAgKiBtaW5pbXVtIG9mIG9uZSBvZiB0aGUgZWxlbWVudHMgaGF2aW5nIHRoZSB7QGNvZGUgRVhFQ1VURV9GQUlMRUR9IHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiB1cGRhdGUgY291bnRzLCB3aXRoIG9uZSBlbnRyeSBmb3IgZWFjaCBjb21tYW5kIGluIHRoZQorICAgICAqICAgICAgICAgYmF0Y2guIFRoZSBlbGVtZW50cyBhcmUgb3JkZXJlZCBhY2NvcmRpbmcgdG8gdGhlIG9yZGVyIGluIHdoaWNoCisgICAgICogICAgICAgICB0aGUgY29tbWFuZHMgd2VyZSBhZGRlZCB0byB0aGUgYmF0Y2guCisgICAgICogICAgICAgICA8cD4KKyAgICAgKiAgICAgICAgIDxvbD4KKyAgICAgKiAgICAgICAgIDxsaT5JZiB0aGUgdmFsdWUgb2YgYW4gZWxlbWVudCBpcyAmZ2U7IDAsIHRoZSBjb3JyZXNwb25kaW5nCisgICAgICogICAgICAgICBjb21tYW5kIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkgYW5kIHRoZSB2YWx1ZSBpcyB0aGUgPGk+dXBkYXRlCisgICAgICogICAgICAgICBjb3VudDwvaT4gKHRoZSBudW1iZXIgb2Ygcm93cyBpbiB0aGUgZGF0YWJhc2UgYWZmZWN0ZWQgYnkgdGhlCisgICAgICogICAgICAgICBjb21tYW5kKSBmb3IgdGhhdCBjb21tYW5kLjwvbGk+CisgICAgICogICAgICAgICA8bGk+SWYgdGhlIHZhbHVlIGlzIHtAY29kZSBTVUNDRVNTX05PX0lORk99LCB0aGUgY29tbWFuZAorICAgICAqICAgICAgICAgY29tcGxldGVkIHN1Y2Nlc3NmdWxseSBidXQgdGhlIG51bWJlciBvZiByb3dzIGFmZmVjdGVkIGlzCisgICAgICogICAgICAgICB1bmtub3duLgorICAgICAqICAgICAgICAgPGxpPgorICAgICAqICAgICAgICAgPGxpPklmIHRoZSB2YWx1ZSBpcyB7QGNvZGUgRVhFQ1VURV9GQUlMRUR9LCB0aGUgY29tbWFuZCBmYWlsZWQuCisgICAgICogICAgICAgICA8L29sPgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIGludFtdIGV4ZWN1dGVCYXRjaCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBFeGVjdXRlcyBhIHN1cHBsaWVkIFNRTCBzdGF0ZW1lbnQuIFJldHVybnMgYSBzaW5nbGUge0Bjb2RlIFJlc3VsdFNldH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3FsCisgICAgICogICAgICAgICAgICBhbiBTUUwgc3RhdGVtZW50IHRvIGV4ZWN1dGUuIFR5cGljYWxseSBhIHtAY29kZSBTRUxFQ1R9CisgICAgICogICAgICAgICAgICBzdGF0ZW1lbnQKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFJlc3VsdFNldH0gY29udGFpbmluZyB0aGUgZGF0YSBwcm9kdWNlZCBieSB0aGUgU1FMCisgICAgICogICAgICAgICBzdGF0ZW1lbnQuIE5ldmVyIG51bGwuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZSBvciBpZiB0aGUgc3RhdGVtZW50CisgICAgICogICAgICAgICAgICAgcHJvZHVjZXMgYW55dGhpbmcgb3RoZXIgdGhhbiBhIHNpbmdsZSB7QGNvZGUgUmVzdWx0U2V0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzdWx0U2V0IGV4ZWN1dGVRdWVyeShTdHJpbmcgc3FsKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRXhlY3V0ZXMgdGhlIHN1cHBsaWVkIFNRTCBzdGF0ZW1lbnQuIFRoZSBzdGF0ZW1lbnQgbWF5IGJlIGFuIHtAY29kZQorICAgICAqIElOU0VSVH0sIHtAY29kZSBVUERBVEV9IG9yIHtAY29kZSBERUxFVEV9IHN0YXRlbWVudCBvciBhIHN0YXRlbWVudCB3aGljaAorICAgICAqIHJldHVybnMgbm90aGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcWwKKyAgICAgKiAgICAgICAgICAgIGFuIFNRTCBzdGF0ZW1lbnQgdG8gZXhlY3V0ZSAtIGFuIFNRTCB7QGNvZGUgSU5TRVJUfSwge0Bjb2RlCisgICAgICogICAgICAgICAgICBVUERBVEV9LCB7QGNvZGUgREVMRVRFfSBvciBhIHN0YXRlbWVudCB3aGljaCByZXR1cm5zIG5vdGhpbmcKKyAgICAgKiBAcmV0dXJuIHRoZSBjb3VudCBvZiB1cGRhdGVkIHJvd3MsIG9yIDAgZm9yIGEgc3RhdGVtZW50IHRoYXQgcmV0dXJucworICAgICAqICAgICAgICAgbm90aGluZy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlIG9yIGlmIHRoZSBzdGF0ZW1lbnQKKyAgICAgKiAgICAgICAgICAgICBwcm9kdWNlcyBhIHtAY29kZSBSZXN1bHRTZXR9LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZXhlY3V0ZVVwZGF0ZShTdHJpbmcgc3FsKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRXhlY3V0ZXMgdGhlIHN1cHBsaWVkIFNRTCBzdGF0ZW1lbnQuIFRoaXMgbWV0aG9kIGFsbG93cyBjb250cm9sIG9mCisgICAgICogd2hldGhlciBhdXRvLWdlbmVyYXRlZCBLZXlzIHNob3VsZCBiZSBtYWRlIGF2YWlsYWJsZSBmb3IgcmV0cmlldmFsLgorICAgICAqCisgICAgICogQHBhcmFtIHNxbAorICAgICAqICAgICAgICAgICAgYW4gU1FMIHN0YXRlbWVudCB0byBleGVjdXRlIC0gYW4gU1FMIHtAY29kZSBJTlNFUlR9LCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFVQREFURX0sIHtAY29kZSBERUxFVEV9IG9yIGEgc3RhdGVtZW50IHdoaWNoIGRvZXMgbm90IHJldHVybgorICAgICAqICAgICAgICAgICAgYW55dGhpbmcuCisgICAgICogQHBhcmFtIGF1dG9HZW5lcmF0ZWRLZXlzCisgICAgICogICAgICAgICAgICBhIGZsYWcgdGhhdCBpbmRpY2F0ZXMgd2hldGhlciB0byBhbGxvdyByZXRyaWV2YWwgb2YgYXV0bworICAgICAqICAgICAgICAgICAgZ2VuZXJhdGVkIGtleXMuIFBhcmFtZXRlciBtdXN0IGJlIG9uZSBvZiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFN0YXRlbWVudC5SRVRVUk5fR0VORVJBVEVEX0tFWVN9IG9yIHtAY29kZQorICAgICAqICAgICAgICAgICAgU3RhdGVtZW50Lk5PX0dFTkVSQVRFRF9LRVlTfQorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiB1cGRhdGVkIHJvd3MsIG9yIDAgaWYgdGhlIHN0YXRlbWVudCByZXR1cm5zCisgICAgICogICAgICAgICBub3RoaW5nLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2Ugb3IgaWYgdGhlIHN0YXRlbWVudAorICAgICAqICAgICAgICAgICAgIHByb2R1Y2VzIGEge0Bjb2RlIFJlc3VsdFNldH0uCisgICAgICovCisgICAgcHVibGljIGludCBleGVjdXRlVXBkYXRlKFN0cmluZyBzcWwsIGludCBhdXRvR2VuZXJhdGVkS2V5cykKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBFeGVjdXRlcyB0aGUgc3VwcGxpZWQgU1FMIHN0YXRlbWVudC4gVGhpcyBtZXRob2QgYWxsb3dzIHJldHJpZXZhbCBvZiBhdXRvCisgICAgICogZ2VuZXJhdGVkIGtleXMgc3BlY2lmaWVkIGJ5IHRoZSBzdXBwbGllZCBhcnJheSBvZiBjb2x1bW4gaW5kZXhlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcWwKKyAgICAgKiAgICAgICAgICAgIGFuIFNRTCBzdGF0ZW1lbnQgdG8gZXhlY3V0ZSAtIGFuIFNRTCB7QGNvZGUgSU5TRVJUfSwge0Bjb2RlCisgICAgICogICAgICAgICAgICBVUERBVEV9LCB7QGNvZGUgREVMRVRFfSBvciBhIHN0YXRlbWVudCB3aGljaCByZXR1cm5zIG5vdGhpbmcKKyAgICAgKiBAcGFyYW0gY29sdW1uSW5kZXhlcworICAgICAqICAgICAgICAgICAgYW4gYXJyYXkgb2YgaW5kZXhlcyBvZiB0aGUgY29sdW1ucyBpbiB0aGUgaW5zZXJ0ZWQgcm93IHdoaWNoCisgICAgICogICAgICAgICAgICBzaG91bGQgYmUgbWFkZSBhdmFpbGFibGUgZm9yIHJldHJpZXZhbCB2aWEgdGhlIHtAY29kZQorICAgICAqICAgICAgICAgICAgZ2V0R2VuZXJhdGVkS2V5c30gbWV0aG9kLgorICAgICAqIEByZXR1cm4gdGhlIGNvdW50IG9mIHVwZGF0ZWQgcm93cywgb3IgMCBmb3IgYSBzdGF0ZW1lbnQgdGhhdCByZXR1cm5zCisgICAgICogICAgICAgICBub3RoaW5nLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2Ugb3IgaWYgdGhlIHN0YXRlbWVudAorICAgICAqICAgICAgICAgICAgIHByb2R1Y2VzIGEge0Bjb2RlIFJlc3VsdFNldH0uCisgICAgICovCisgICAgcHVibGljIGludCBleGVjdXRlVXBkYXRlKFN0cmluZyBzcWwsIGludFtdIGNvbHVtbkluZGV4ZXMpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRXhlY3V0ZXMgdGhlIHN1cHBsaWVkIFNRTCBzdGF0ZW1lbnQuIFRoaXMgbWV0aG9kIGFsbG93cyByZXRyaWV2YWwgb2YgYXV0bworICAgICAqIGdlbmVyYXRlZCBrZXlzIHNwZWNpZmllZCBieSB0aGUgc3VwcGxpZWQgYXJyYXkgb2YgY29sdW1uIG5hbWVzLgorICAgICAqCisgICAgICogQHBhcmFtIHNxbAorICAgICAqICAgICAgICAgICAgYW4gU1FMIHN0YXRlbWVudCB0byBleGVjdXRlIC0gYW4gU1FMIHtAY29kZSBJTlNFUlR9LCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFVQREFURX0sIHtAY29kZSBERUxFVEV9IG9yIGEgc3RhdGVtZW50IHdoaWNoIHJldHVybnMgbm90aGluZworICAgICAqIEBwYXJhbSBjb2x1bW5OYW1lcworICAgICAqICAgICAgICAgICAgYW4gYXJyYXkgb2YgY29sdW1uIG5hbWVzIGluIHRoZSBpbnNlcnRlZCByb3cgd2hpY2ggc2hvdWxkIGJlCisgICAgICogICAgICAgICAgICBtYWRlIGF2YWlsYWJsZSBmb3IgcmV0cmlldmFsIHZpYSB0aGUge0Bjb2RlIGdldEdlbmVyYXRlZEtleXN9CisgICAgICogICAgICAgICAgICBtZXRob2QuCisgICAgICogQHJldHVybiB0aGUgY291bnQgb2YgdXBkYXRlZCByb3dzLCBvciAwIGZvciBhIHN0YXRlbWVudCB0aGF0IHJldHVybnMKKyAgICAgKiAgICAgICAgIG5vdGhpbmcuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZSBvciBpZiB0aGUgc3RhdGVtZW50CisgICAgICogICAgICAgICAgICAgcHJvZHVjZXMgYSB7QGNvZGUgUmVzdWx0U2V0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGV4ZWN1dGVVcGRhdGUoU3RyaW5nIHNxbCwgU3RyaW5nW10gY29sdW1uTmFtZXMpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUge0Bjb2RlIENvbm5lY3Rpb259IG9iamVjdCB3aGljaCBjcmVhdGVkIHRoaXMgc3RhdGVtZW50LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIENvbm5lY3Rpb259IHRocm91Z2ggd2hpY2ggdGhpcyBzdGF0ZW1lbnQgaXMKKyAgICAgKiAgICAgICAgIHRyYW5zbWl0dGVkIHRvIHRoZSBkYXRhYmFzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBDb25uZWN0aW9uIGdldENvbm5lY3Rpb24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGVmYXVsdCBkaXJlY3Rpb24gZm9yIGZldGNoaW5nIHJvd3MgZm9yIHtAY29kZSBSZXN1bHRTZXR9cworICAgICAqIGdlbmVyYXRlZCBmcm9tIHRoaXMgc3RhdGVtZW50LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZGVmYXVsdCBmZXRjaCBkaXJlY3Rpb24sIG9uZSBvZjoKKyAgICAgKiAgICAgICAgIDx1bD4KKyAgICAgKiAgICAgICAgIDxsaT5SZXN1bHRTZXQuRkVUQ0hfRk9SV0FSRDwvbGk+IDxsaT5SZXN1bHRTZXQuRkVUQ0hfUkVWRVJTRTwvbGk+CisgICAgICogICAgICAgICA8bGk+UmVzdWx0U2V0LkZFVENIX1VOS05PV048L2xpPgorICAgICAqICAgICAgICAgPC91bD4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RmV0Y2hEaXJlY3Rpb24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGVmYXVsdCBudW1iZXIgb2Ygcm93cyBmb3IgYSBmZXRjaCBmb3IgdGhlIHtAY29kZSBSZXN1bHRTZXR9CisgICAgICogb2JqZWN0cyByZXR1cm5lZCBmcm9tIHRoaXMgc3RhdGVtZW50LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZGVmYXVsdCBmZXRjaCBzaXplIGZvciB7QGNvZGUgUmVzdWx0U2V0fXMgcHJvZHVjZWQgYnkgdGhpcworICAgICAqICAgICAgICAgc3RhdGVtZW50LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRGZXRjaFNpemUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhdXRvIGdlbmVyYXRlZCBrZXlzIGNyZWF0ZWQgYnkgZXhlY3V0aW5nIHRoaXMgc3RhdGVtZW50LgorICAgICAqCisgICAgICogQHJldHVybiBhIHtAY29kZSBSZXN1bHRTZXR9IGNvbnRhaW5pbmcgdGhlIGF1dG8gZ2VuZXJhdGVkIGtleXMgLSBlbXB0eSBpZgorICAgICAqICAgICAgICAgbm8ga2V5cyBhcmUgZ2VuZXJhdGVkIGJ5IHRoaXMgc3RhdGVtZW50LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIFJlc3VsdFNldCBnZXRHZW5lcmF0ZWRLZXlzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHdoaWNoIGNhbiBiZSByZXR1cm5lZCBhcyB2YWx1ZXMgZnJvbQorICAgICAqIGNoYXJhY3RlciBhbmQgYmluYXJ5IHR5cGUgY29sdW1ucyBpbiBhIHtAY29kZSBSZXN1bHRTZXR9IGRlcml2ZWQgZnJvbSB0aGlzCisgICAgICogc3RhdGVtZW50LiBUaGlzIGxpbWl0IGFwcGxpZXMgdG8ge0Bjb2RlIEJJTkFSWX0sIHtAY29kZSBWQVJCSU5BUll9LAorICAgICAqIHtAY29kZSBMT05HVkFSQklOQVJZfSwge0Bjb2RlIENIQVJ9LCB7QGNvZGUgVkFSQ0hBUn0sIGFuZCB7QGNvZGUKKyAgICAgKiBMT05HVkFSQ0hBUn0gdHlwZXMuIEFueSBkYXRhIGV4Y2VlZGluZyB0aGUgbWF4aW11bSBzaXplIGlzIGFiYW5kb25lZAorICAgICAqIHdpdGhvdXQgYW5ub3VuY2VtZW50LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY3VycmVudCBzaXplIGxpbWl0LCB3aGVyZSB7QGNvZGUgMH0gbWVhbnMgdGhhdCB0aGVyZSBpcyBubworICAgICAqICAgICAgICAgbGltaXQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1heEZpZWxkU2l6ZSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtYXhpbXVtIG51bWJlciBvZiByb3dzIHRoYXQgYSB7QGNvZGUgUmVzdWx0U2V0fSBjYW4gY29udGFpbiB3aGVuCisgICAgICogcHJvZHVjZWQgZnJvbSB0aGlzIHN0YXRlbWVudC4gSWYgdGhlIGxpbWl0IGlzIGV4Y2VlZGVkLCB0aGUgZXhjZXNzIHJvd3MKKyAgICAgKiBhcmUgZGlzY2FyZGVkIHNpbGVudGx5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY3VycmVudCByb3cgbGltaXQsIHdoZXJlIHtAY29kZSAwfSBtZWFucyB0aGF0IHRoZXJlIGlzIG5vCisgICAgICogICAgICAgICBsaW1pdC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWF4Um93cygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBNb3ZlcyB0byB0aGlzIHN0YXRlbWVudCdzIG5leHQgcmVzdWx0LiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiBpdCBpcyBhCisgICAgICoge0Bjb2RlIFJlc3VsdFNldH0uIEFueSBjdXJyZW50IHtAY29kZSBSZXN1bHRTZXR9IG9iamVjdHMgcHJldmlvdXNseQorICAgICAqIG9idGFpbmVkIHdpdGgge0Bjb2RlIGdldFJlc3VsdFNldCgpfSBhcmUgY2xvc2VkIGltcGxpY2l0bHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgbmV4dCByZXN1bHQgaXMgYSB7QGNvZGUgUmVzdWx0U2V0fSwge0Bjb2RlCisgICAgICogICAgICAgICBmYWxzZX0gaWYgdGhlIG5leHQgcmVzdWx0IGlzIG5vdCBhIHtAY29kZSBSZXN1bHRTZXR9IG9yIGlmIHRoZXJlCisgICAgICogICAgICAgICBhcmUgbm8gbW9yZSByZXN1bHRzLiBOb3RlIHRoYXQgaWYgdGhlcmUgaXMgbm8gbW9yZSBkYXRhLCB0aGlzCisgICAgICogICAgICAgICBtZXRob2Qgd2lsbCByZXR1cm4ge0Bjb2RlIGZhbHNlfSBhbmQge0Bjb2RlIGdldFVwZGF0ZUNvdW50fSB3aWxsCisgICAgICogICAgICAgICByZXR1cm4gLTEuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRNb3JlUmVzdWx0cygpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBNb3ZlcyB0byB0aGlzIHN0YXRlbWVudCdzIG5leHQgcmVzdWx0LiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGUgbmV4dAorICAgICAqIHJlc3VsdCBpcyBhIHtAY29kZSBSZXN1bHRTZXR9LiBBbnkgY3VycmVudCB7QGNvZGUgUmVzdWx0U2V0fSBvYmplY3RzCisgICAgICogcHJldmlvdXNseSBvYnRhaW5lZCB3aXRoIHtAY29kZSBnZXRSZXN1bHRTZXQoKX0gYXJlIGhhbmRsZWQgYXMgaW5kaWNhdGVkCisgICAgICogYnkgYSBzdXBwbGllZCBGbGFnIHBhcmFtZXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjdXJyZW50CisgICAgICogICAgICAgICAgICBhIGZsYWcgaW5kaWNhdGluZyB3aGF0IHRvIGRvIHdpdGggZXhpc3Rpbmcge0Bjb2RlIFJlc3VsdFNldH1zLgorICAgICAqICAgICAgICAgICAgVGhpcyBwYXJhbWV0ZXIgbXVzdCBiZSBvbmUgb2Yge0Bjb2RlCisgICAgICogICAgICAgICAgICBTdGF0ZW1lbnQuQ0xPU0VfQUxMX1JFU1VMVFN9LCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFN0YXRlbWVudC5DTE9TRV9DVVJSRU5UX1JFU1VMVH0gb3Ige0Bjb2RlCisgICAgICogICAgICAgICAgICBTdGF0ZW1lbnQuS0VFUF9DVVJSRU5UX1JFU1VMVH0uCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIG5leHQgcmVzdWx0IGV4aXN0cyBhbmQgaXMgYSB7QGNvZGUgUmVzdWx0U2V0fQorICAgICAqICAgICAgICAgLCB7QGNvZGUgZmFsc2V9IGlmIHRoZSBuZXh0IHJlc3VsdCBpcyBub3QgYSB7QGNvZGUgUmVzdWx0U2V0fSBvcgorICAgICAqICAgICAgICAgaWYgdGhlcmUgYXJlIG5vIG1vcmUgcmVzdWx0cy4gTm90ZSB0aGF0IGlmIHRoZXJlIGlzIG5vIG1vcmUgZGF0YSwKKyAgICAgKiAgICAgICAgIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIHtAY29kZSBmYWxzZX0gYW5kIHtAY29kZSBnZXRVcGRhdGVDb3VudH0KKyAgICAgKiAgICAgICAgIHdpbGwgcmV0dXJuIC0xLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0TW9yZVJlc3VsdHMoaW50IGN1cnJlbnQpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0aW1lb3V0IHZhbHVlIGZvciB0aGUgc3RhdGVtZW50J3MgZXhlY3V0aW9uIHRpbWUuIFRoZSBKREJDCisgICAgICogZHJpdmVyIHdpbGwgd2FpdCB1cCB0byB0aGlzIHZhbHVlIGZvciB0aGUgZXhlY3V0aW9uIHRvIGNvbXBsZXRlIC0gYWZ0ZXIKKyAgICAgKiB0aGUgbGltaXQgaXMgZXhjZWVkZWQgYW4gU1FMIHtAY29kZSBFeGNlcHRpb259IGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgcXVlcnkgdGltZW91dCB2YWx1ZSwgd2hlcmUge0Bjb2RlIDB9IGluZGljYXRlcyB0aGF0CisgICAgICogICAgICAgICB0aGVyZSBpcyBubyBjdXJyZW50IHRpbWVvdXQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFF1ZXJ5VGltZW91dCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHJlc3VsdC4gU2hvdWxkIG9ubHkgYmUgY2FsbGVkIG9uY2UgcGVyIHJlc3VsdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBSZXN1bHRTZXR9IGZvciB0aGUgY3VycmVudCByZXN1bHQuIHtAY29kZSBudWxsfSBpZiB0aGUKKyAgICAgKiAgICAgICAgIHJlc3VsdCBpcyBhbiB1cGRhdGUgY291bnQgb3IgaWYgdGhlcmUgYXJlIG5vIG1vcmUgcmVzdWx0cy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBSZXN1bHRTZXQgZ2V0UmVzdWx0U2V0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNvbmN1cnJlbmN5IHNldHRpbmcgZm9yIHtAY29kZSBSZXN1bHRTZXR9IG9iamVjdHMgZ2VuZXJhdGVkIGJ5CisgICAgICogdGhpcyBzdGF0ZW1lbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSBSZXN1bHRTZXQuQ09OQ1VSX1JFQURfT05MWX0gb3Ige0Bjb2RlCisgICAgICogICAgICAgICBSZXN1bHRTZXQuQ09OQ1VSX1VQREFUQUJMRX0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFJlc3VsdFNldENvbmN1cnJlbmN5KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGN1cnNvciBob2xkIHNldHRpbmcgZm9yIHtAY29kZSBSZXN1bHRTZXR9IG9iamVjdHMgZ2VuZXJhdGVkIGJ5CisgICAgICogdGhpcyBzdGF0ZW1lbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSBSZXN1bHRTZXQuSE9MRF9DVVJTT1JTX09WRVJfQ09NTUlUfSBvciB7QGNvZGUKKyAgICAgKiAgICAgICAgIFJlc3VsdFNldC5DTE9TRV9DVVJTT1JTX0FUX0NPTU1JVH0KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGFuIGVycm9yIHdoaWxlIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSZXN1bHRTZXRIb2xkYWJpbGl0eSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB7QGNvZGUgUmVzdWx0U2V0fSB0eXBlIHNldHRpbmcgZm9yIHtAY29kZSBSZXN1bHRTZXR9cyBkZXJpdmVkCisgICAgICogZnJvbSB0aGlzIHN0YXRlbWVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIFJlc3VsdFNldC5UWVBFX0ZPUldBUkRfT05MWX0gZm9yIGEge0Bjb2RlIFJlc3VsdFNldH0gd2hlcmUKKyAgICAgKiAgICAgICAgIHRoZSBjdXJzb3IgY2FuIG9ubHkgbW92ZSBmb3J3YXJkcywge0Bjb2RlCisgICAgICogICAgICAgICBSZXN1bHRTZXQuVFlQRV9TQ1JPTExfSU5TRU5TSVRJVkV9IGZvciBhIHtAY29kZSBSZXN1bHRTZXR9IHdoaWNoCisgICAgICogICAgICAgICBpcyBzY3JvbGxhYmxlIGJ1dCBpcyBub3Qgc2Vuc2l0aXZlIHRvIGNoYW5nZXMgbWFkZSBieSBvdGhlcnMsCisgICAgICogICAgICAgICB7QGNvZGUgUmVzdWx0U2V0LlRZUEVfU0NST0xMX1NFTlNJVElWRX0gZm9yIGEge0Bjb2RlIFJlc3VsdFNldH0KKyAgICAgKiAgICAgICAgIHdoaWNoIGlzIHNjcm9sbGFibGUgYnV0IGlzIHNlbnNpdGl2ZSB0byBjaGFuZ2VzIG1hZGUgYnkgb3RoZXJzLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYW4gZXJyb3IgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFJlc3VsdFNldFR5cGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyBhbiB1cGRhdGUgY291bnQgZm9yIHRoZSBjdXJyZW50IHJlc3VsdCBpZiBpdCBpcyBub3QgYSB7QGNvZGUKKyAgICAgKiBSZXN1bHRTZXR9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY3VycmVudCByZXN1bHQgYXMgYW4gdXBkYXRlIGNvdW50LiB7QGNvZGUgLTF9IGlmIHRoZSBjdXJyZW50CisgICAgICogICAgICAgICByZXN1bHQgaXMgYSB7QGNvZGUgUmVzdWx0U2V0fSBvciBpZiB0aGVyZSBhcmUgbm8gbW9yZSByZXN1bHRzLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRVcGRhdGVDb3VudCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgdGhlIGZpcnN0IHtAY29kZSBTUUxXYXJuaW5nfSByZXBvcnRlZCBieSBjYWxscyBvbiB0aGlzCisgICAgICogc3RhdGVtZW50LiBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgd2FybmluZ3MsIHN1YnNlcXVlbnQgd2FybmluZ3MgYXJlCisgICAgICogY2hhaW5lZCB0byB0aGUgZmlyc3Qgb25lLiBUaGUgY2hhaW4gb2Ygd2FybmluZ3MgaXMgY2xlYXJlZCBlYWNoIHRpbWUgdGhlCisgICAgICogc3RhdGVtZW50IGlzIGV4ZWN1dGVkLgorICAgICAqIDxwPgorICAgICAqIFdhcm5pbmdzIGFzc29jaWF0ZWQgd2l0aCByZWFkcyBmcm9tIHRoZSB7QGNvZGUgUmVzdWx0U2V0fSByZXR1cm5lZCBmcm9tCisgICAgICogZXhlY3V0aW5nIHRoZSBzdGF0ZW1lbnQgd2lsbCBiZSBhdHRhY2hlZCB0byB0aGUge0Bjb2RlIFJlc3VsdFNldH0sIG5vdCB0aGUKKyAgICAgKiBzdGF0ZW1lbnQgb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybiBhbiBTUUxXYXJuaW5nLCBudWxsIGlmIHRoZXJlIGFyZSBubyB3YXJuaW5ncworICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIFNRTFdhcm5pbmcgZ2V0V2FybmluZ3MoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgU1FMIGN1cnNvciBuYW1lLiBUaGlzIG5hbWUgaXMgdXNlZCBieSBzdWJzZXF1ZW50IHN0YXRlbWVudAorICAgICAqIGV4ZWN1dGUgbWV0aG9kcy4KKyAgICAgKiA8cD4KKyAgICAgKiBDdXJzb3IgbmFtZXMgbXVzdCBiZSB1bmlxdWUgd2l0aGluIG9uZSBDb25uZWN0aW9uLgorICAgICAqIDxwPgorICAgICAqIFdpdGggdGhlIGN1cnNvciBuYW1lIHNldCwgaXQgY2FuIHRoZW4gYmUgdXNlZCBpbiBTUUwgcG9zaXRpb25lZAorICAgICAqIHVwZGF0ZSBvciBkZWxldGUgc3RhdGVtZW50cyB0byBkZXRlcm1pbmUgdGhlIGN1cnJlbnQgcm93IGluIGEge0Bjb2RlCisgICAgICogUmVzdWx0U2V0fSBnZW5lcmF0ZWQgZnJvbSB0aGlzIHN0YXRlbWVudC4gVGhlIHBvc2l0aW9uZWQgdXBkYXRlIG9yIGRlbGV0ZQorICAgICAqIG11c3QgYmUgZG9uZSB3aXRoIGEgZGlmZmVyZW50IHN0YXRlbWVudCB0aGFuIHRoaXMgb25lLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBDdXJzb3IgbmFtZSBhcyBhIHN0cmluZywKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEN1cnNvck5hbWUoU3RyaW5nIG5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIEVzY2FwZSBQcm9jZXNzaW5nIG1vZGUuCisgICAgICogPHA+CisgICAgICogSWYgRXNjYXBlIFByb2Nlc3NpbmcgaXMgb24sIHRoZSBKREJDIGRyaXZlciB3aWxsIGRvIGVzY2FwZSBzdWJzdGl0dXRpb24KKyAgICAgKiBvbiBhbiBTUUwgc3RhdGVtZW50IGJlZm9yZSBzZW5kaW5nIGl0IGZvciBleGVjdXRpb24uIFRoaXMgZG9lcyBub3QgYXBwbHkKKyAgICAgKiB0byB7QGxpbmsgUHJlcGFyZWRTdGF0ZW1lbnR9cyBzaW5jZSB0aGV5IGFyZSBwcm9jZXNzZWQgd2hlbiBjcmVhdGVkLAorICAgICAqIGJlZm9yZSB0aGlzIG1ldGhvZCBjYW4gYmUgY2FsbGVkLgorICAgICAqCisgICAgICogQHBhcmFtIGVuYWJsZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IHRvIHNldCBlc2NhcGUgcHJvY2Vzc2luZyBtb2RlIDxpPm9uPC9pPiwge0Bjb2RlCisgICAgICogICAgICAgICAgICBmYWxzZX0gdG8gdHVybiBpdCA8aT5vZmY8L2k+LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RXNjYXBlUHJvY2Vzc2luZyhib29sZWFuIGVuYWJsZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZldGNoIGRpcmVjdGlvbiAtIGEgaGludCB0byB0aGUgSkRCQyBkcml2ZXIgYWJvdXQgdGhlIGRpcmVjdGlvbgorICAgICAqIG9mIHByb2Nlc3Npbmcgb2Ygcm93cyBpbiB7QGNvZGUgUmVzdWx0U2V0fXMgY3JlYXRlZCBieSB0aGlzIHN0YXRlbWVudC4KKyAgICAgKiBUaGUgZGVmYXVsdCBmZXRjaCBkaXJlY3Rpb24gaXMge0Bjb2RlIEZFVENIX0ZPUldBUkR9LgorICAgICAqCisgICAgICogQHBhcmFtIGRpcmVjdGlvbgorICAgICAqICAgICAgICAgICAgd2hpY2ggZmV0Y2ggZGlyZWN0aW9uIHRvIHVzZS4gVGhpcyBwYXJhbWV0ZXIgc2hvdWxkIGJlIG9uZSBvZgorICAgICAqICAgICAgICAgICAgPHVsPgorICAgICAqICAgICAgICAgICAgPGxpPntAY29kZSBSZXN1bHRTZXQuRkVUQ0hfVU5LTk9XTn08L2xpPgorICAgICAqICAgICAgICAgICAgPGxpPntAY29kZSBSZXN1bHRTZXQuRkVUQ0hfRk9SV0FSRH08L2xpPgorICAgICAqICAgICAgICAgICAgPGxpPntAY29kZSBSZXN1bHRTZXQuRkVUQ0hfUkVWRVJTRX08L2xpPgorICAgICAqICAgICAgICAgICAgPC91bD4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGFuIGVycm9yIHdoaWxlIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2Ugb3IgaWYgdGhlCisgICAgICogICAgICAgICAgICAgZmV0Y2ggZGlyZWN0aW9uIGlzIHVucmVjb2duaXplZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGZXRjaERpcmVjdGlvbihpbnQgZGlyZWN0aW9uKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZmV0Y2ggc2l6ZS4gVGhpcyBpcyBhIGhpbnQgdG8gdGhlIEpEQkMgZHJpdmVyIGFib3V0IGhvdyBtYW55CisgICAgICogcm93cyBzaG91bGQgYmUgZmV0Y2hlZCBmcm9tIHRoZSBkYXRhYmFzZSB3aGVuIG1vcmUgYXJlIHJlcXVpcmVkIGJ5CisgICAgICogYXBwbGljYXRpb24gcHJvY2Vzc2luZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSByb3dzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIHJvd3MgdGhhdCBzaG91bGQgYmUgZmV0Y2hlZC4ge0Bjb2RlIDB9IHRlbGxzIHRoZSBkcml2ZXIKKyAgICAgKiAgICAgICAgICAgIHRvIGlnbm9yZSB0aGUgaGludC4gU2hvdWxkIGJlIGxlc3MgdGhhbiB7QGNvZGUgZ2V0TWF4Um93c30gZm9yCisgICAgICogICAgICAgICAgICB0aGlzIHN0YXRlbWVudC4gU2hvdWxkIG5vdCBiZSBuZWdhdGl2ZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLCBvciBpZiB0aGUgcm93cworICAgICAqICAgICAgICAgICAgIHBhcmFtZXRlciBpcyBvdXQgb2YgcmFuZ2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RmV0Y2hTaXplKGludCByb3dzKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgZm9yIHtAY29kZSBSZXN1bHRTZXR9IGNvbHVtbnMgdGhhdAorICAgICAqIGNvbnRhaW4gY2hhcmFjdGVyIG9yIGJpbmFyeSB2YWx1ZXMuIFRoaXMgYXBwbGllcyB0byB7QGNvZGUgQklOQVJZfSwKKyAgICAgKiB7QGNvZGUgVkFSQklOQVJZfSwge0Bjb2RlIExPTkdWQVJCSU5BUll9LCB7QGNvZGUgQ0hBUn0sIHtAY29kZSBWQVJDSEFSfSwKKyAgICAgKiBhbmQge0Bjb2RlIExPTkdWQVJDSEFSfSBmaWVsZHMuIEFueSBkYXRhIGV4Y2VlZGluZyB0aGUgbWF4aW11bSBzaXplIGlzCisgICAgICogYWJhbmRvbmVkIHdpdGhvdXQgYW5ub3VuY2VtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIG1heAorICAgICAqICAgICAgICAgICAgdGhlIG1heGltdW0gZmllbGQgc2l6ZSBpbiBieXRlcy4ge0Bjb2RlIDB9IG1lYW5zICJubyBsaW1pdCIuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZSBvciB0aGUge0Bjb2RlIG1heH0KKyAgICAgKiAgICAgICAgICAgICB2YWx1ZSBpcyAmbHQ7IHtAY29kZSAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRNYXhGaWVsZFNpemUoaW50IG1heCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG1heGltdW0gbnVtYmVyIG9mIHJvd3MgdGhhdCBhbnkge0Bjb2RlIFJlc3VsdFNldH0gY2FuIGNvbnRhaW4uCisgICAgICogSWYgdGhlIG51bWJlciBvZiByb3dzIGV4Y2VlZHMgdGhpcyB2YWx1ZSwgdGhlIGFkZGl0aW9uYWwgcm93cyBhcmUKKyAgICAgKiBzaWxlbnRseSBkaXNjYXJkZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWF4CisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBudW1iZXIgb2Ygcm93cy4ge0Bjb2RlIDB9IG1lYW5zICJubyBsaW1pdCIuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZSBvciBpZiBtYXggPCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRNYXhSb3dzKGludCBtYXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB0aW1lb3V0LCBpbiBzZWNvbmRzLCBmb3IgcXVlcmllcyAtIGhvdyBsb25nIHRoZSBkcml2ZXIgd2lsbAorICAgICAqIGFsbG93IGZvciBjb21wbGV0aW9uIG9mIGEgc3RhdGVtZW50IGV4ZWN1dGlvbi4gSWYgdGhlIHRpbWVvdXQgaXMKKyAgICAgKiBleGNlZWRlZCwgdGhlIHF1ZXJ5IHdpbGwgdGhyb3cgYW4ge0Bjb2RlIFNRTEV4Y2VwdGlvbn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2Vjb25kcworICAgICAqICAgICAgICAgICAgdGltZW91dCBpbiBzZWNvbmRzLiAwIG1lYW5zIG5vIHRpbWVvdXQgKCJ3YWl0IGZvcmV2ZXIiKQorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2Ugb3IgaWYgc2Vjb25kcyA8CisgICAgICogICAgICAgICAgICAge0Bjb2RlIDB9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFF1ZXJ5VGltZW91dChpbnQgc2Vjb25kcykgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHN0YXRlbWVudCBoYXMgYmVlbiBjbG9zZWQsIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0Nsb3NlZCgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBIaW50cyB3aGV0aGVyIHRoaXMgc3RhdGVtZW50IHNob3VsZCBiZSBwb29sZWQuIERlZmF1bHRzIHRvIGZhbHNlIGZvciB7QGNvZGUgU3RhdGVtZW50fSwKKyAgICAgKiBidXQgdHJ1ZSBmb3Ige0Bjb2RlIENhbGxhYmxlU3RhdGVtZW50fSBhbmQge0Bjb2RlIFByZXBhcmVkU3RhdGVtZW50fS4gUG9vbCBtYW5hZ2VyCisgICAgICogaW1wbGVtZW50YXRpb25zIG1heSBvciBtYXkgbm90IGhvbm9yIHRoaXMgaGludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQb29sYWJsZShib29sZWFuIHBvb2xhYmxlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgc3RhdGVtZW50IGlzIHBvb2xhYmxlLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNQb29sYWJsZSgpIHRocm93cyBTUUxFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU3RydWN0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvU3RydWN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWYwZDhkMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9TdHJ1Y3QuamF2YQpAQCAtMCwwICsxLDY4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnNxbDsKKworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogQW4gaW50ZXJmYWNlIHdoaWNoIHByb3ZpZGVzIGZhY2lsaXRpZXMgZm9yIG1hbmlwdWxhdGluZyBhbiBTUUwgc3RydWN0dXJlZCB0eXBlCisgKiBhcyBhIEphdmEgb2JqZWN0LiBUaGUge0Bjb2RlIFN0cnVjdH0gb2JqZWN0IGhhcyBhIHZhbHVlIGZvciBlYWNoIGF0dHJpYnV0ZSBvZiB0aGUgU1FMIHN0cnVjdHVyZWQKKyAqIHR5cGUuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgU3RydWN0IHsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFNRTCBUeXBlIG5hbWUgb2YgdGhlIFNRTCBzdHJ1Y3R1cmVkIHR5cGUgdGhhdCB0aGlzIHtAY29kZQorICAgICAqIFN0cnVjdH0gcmVwcmVzZW50cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIFNRTCBzdHJ1Y3R1cmVkIHR5cGUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGRhdGFiYXNlIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFNRTFR5cGVOYW1lKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlcyBvZiB0aGUgYXR0cmlidXRlcyBvZiB0aGlzIFNRTCBzdHJ1Y3R1cmVkIHR5cGUuIFRoaXMKKyAgICAgKiBtZXRob2QgdXNlcyB0aGUgdHlwZSBtYXAgYXNzb2NpYXRlZCB3aXRoIHRoZSB7QGxpbmsgQ29ubmVjdGlvbn0gZm9yCisgICAgICogY3VzdG9taXplZCB0eXBlIG1hcHBpbmdzLiBXaGVyZSB0aGVyZSBpcyBubyBlbnRyeSBpbiB0aGUgdHlwZSBtYXBwaW5nCisgICAgICogd2hpY2ggbWF0Y2hlcyB0aGlzIHN0cnVjdHVyZWQgdHlwZSwgdGhlIEpEQkMgZHJpdmVyIHVzZXMgdGhlIHN0YW5kYXJkCisgICAgICogbWFwcGluZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIE9iamVjdH0gYXJyYXkgY29udGFpbmluZyB0aGUgb3JkZXJlZCBhdHRyaWJ1dGVzLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBkYXRhYmFzZSBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIE9iamVjdFtdIGdldEF0dHJpYnV0ZXMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWVzIG9mIHRoZSBhdHRyaWJ1dGVzIG9mIHRoaXMgU1FMIHN0cnVjdHVyZWQgdHlwZS4gVGhpcworICAgICAqIG1ldGhvZCB1c2VzIHRoZSBzdXBwbGllZCB0eXBlIG1hcHBpbmcgdG8gZGV0ZXJtaW5lIGhvdyB0byBtYXAgU1FMIHR5cGVzCisgICAgICogdG8gdGhlaXIgY29ycmVzcG9uZGluZyBKYXZhIG9iamVjdHMuIEluIHRoZQorICAgICAqIGNhc2Ugd2hlcmUgdGhlcmUgaXMgbm8gZW50cnkgaW4gdGhlIHR5cGUgbWFwcGluZyB3aGljaCBtYXRjaGVzIHRoaXMKKyAgICAgKiBzdHJ1Y3R1cmVkIHR5cGUsIHRoZSBKREJDIGRyaXZlciB1c2VzIHRoZSBkZWZhdWx0IG1hcHBpbmcuIFRoZSB7QGNvZGUKKyAgICAgKiBDb25uZWN0aW9ufSB0eXBlIG1hcCBpcyA8aT5uZXZlcjwvaT4gdXRpbGl6ZWQgYnkgdGhpcyBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlTWFwCisgICAgICogICAgICAgICAgICBhIE1hcCBkZXNjcmliaW5nIGhvdyBTUUwgVHlwZSBuYW1lcyBhcmUgbWFwcGVkIHRvIGNsYXNzZXMuCisgICAgICogQHJldHVybiBhbiBPYmplY3QgYXJyYXkgY29udGFpbmluZyB0aGUgb3JkZXJlZCBhdHRyaWJ1dGVzLC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgZGF0YWJhc2UgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3RbXSBnZXRBdHRyaWJ1dGVzKE1hcDxTdHJpbmcsIENsYXNzPD8+PiB0aGVNYXApCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1RpbWUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9UaW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmNjY2U2OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9UaW1lLmphdmEKQEAgLTAsMCArMSwyNDcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCitpbXBvcnQgamF2YS51dGlsLkRhdGU7CisKKy8qKgorICogSmF2YSByZXByZXNlbnRhdGlvbiBvZiBhbiBTUUwge0Bjb2RlIFRJTUV9IHZhbHVlLiBQcm92aWRlcyB1dGlsaXRpZXMgdG8KKyAqIGZvcm1hdCBhbmQgcGFyc2UgdGhlIHRpbWUncyByZXByZXNlbnRhdGlvbiBhcyBhIFN0cmluZyBpbiBKREJDIGVzY2FwZSBmb3JtYXQuCisgKi8KK3B1YmxpYyBjbGFzcyBUaW1lIGV4dGVuZHMgRGF0ZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA4Mzk3MzI0NDAzNTQ4MDEzNjgxTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgVGltZX0gb2JqZWN0IHVzaW5nIHRoZSBzdXBwbGllZCB2YWx1ZXMgZm9yIDxpPkhvdXI8L2k+LAorICAgICAqIDxpPk1pbnV0ZTwvaT4gYW5kIDxpPlNlY29uZDwvaT4uIFRoZSA8aT5ZZWFyPC9pPiwgPGk+TW9udGg8L2k+IGFuZAorICAgICAqIDxpPkRheTwvaT4gZWxlbWVudHMgb2YgdGhlIHtAY29kZSBUaW1lfSBvYmplY3QgYXJlIHNldCB0byB0aGUgZGF0ZQorICAgICAqIG9mIHRoZSBFcG9jaCAoSmFudWFyeSAxLCAxOTcwKS4KKyAgICAgKiA8cD4KKyAgICAgKiBBbnkgYXR0ZW1wdCB0byBhY2Nlc3MgdGhlIDxpPlllYXI8L2k+LCA8aT5Nb250aDwvaT4gb3IgPGk+RGF5PC9pPgorICAgICAqIGVsZW1lbnRzIG9mIGEge0Bjb2RlIFRpbWV9IG9iamVjdCB3aWxsIHJlc3VsdCBpbiBhbiB7QGNvZGUKKyAgICAgKiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259LgorICAgICAqIDxwPgorICAgICAqIFRoZSByZXN1bHQgaXMgdW5kZWZpbmVkIGlmIGFueSBhcmd1bWVudCBpcyBvdXQgb2YgYm91bmRzLgorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIHRoZSBjb25zdHJ1Y3RvciB7QGxpbmsgI1RpbWUobG9uZyl9LgorICAgICAqIEBwYXJhbSB0aGVIb3VyCisgICAgICogICAgICAgICAgICBhIHZhbHVlIGluIHRoZSByYW5nZSB7QGNvZGUgWzAsMjNdfS4KKyAgICAgKiBAcGFyYW0gdGhlTWludXRlCisgICAgICogICAgICAgICAgICBhIHZhbHVlIGluIHRoZSByYW5nZSB7QGNvZGUgWzAsNTldfS4KKyAgICAgKiBAcGFyYW0gdGhlU2Vjb25kCisgICAgICogICAgICAgICAgICBhIHZhbHVlIGluIHRoZSByYW5nZSB7QGNvZGUgWzAsNTldfS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIFRpbWUoaW50IHRoZUhvdXIsIGludCB0aGVNaW51dGUsIGludCB0aGVTZWNvbmQpIHsKKyAgICAgICAgc3VwZXIoNzAsIDAsIDEsIHRoZUhvdXIsIHRoZU1pbnV0ZSwgdGhlU2Vjb25kKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIFRpbWV9IG9iamVjdCB1c2luZyBhIHN1cHBsaWVkIHRpbWUgc3BlY2lmaWVkIGluCisgICAgICogbWlsbGlzZWNvbmRzLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZVRpbWUKKyAgICAgKiAgICAgICAgICAgIGEge0Bjb2RlIFRpbWV9IHNwZWNpZmllZCBpbiBtaWxsaXNlY29uZHMgc2luY2UgdGhlCisgICAgICogICAgICAgICAgICA8aT5FcG9jaDwvaT4gKEphbnVhcnkgMXN0IDE5NzAsIDAwOjAwOjAwLjAwMCkuCisgICAgICovCisgICAgcHVibGljIFRpbWUobG9uZyB0aGVUaW1lKSB7CisgICAgICAgIHN1cGVyKHRoZVRpbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBkZXByZWNhdGVkIFRoaXMgbWV0aG9kIGlzIGRlcHJlY2F0ZWQgYW5kIG11c3Qgbm90IGJlIHVzZWQuIEFuIFNRTAorICAgICAqICAgICAgICAgICAgIHtAY29kZSBUaW1lfSBvYmplY3QgZG9lcyBub3QgaGF2ZSBhIHtAY29kZSBEYXRlfSBjb21wb25lbnQuCisgICAgICogQHJldHVybiBkb2VzIG5vdCByZXR1cm4gYW55dGhpbmcuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBARGVwcmVjYXRlZAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0RGF0ZSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBkZXByZWNhdGVkIFRoaXMgbWV0aG9kIGlzIGRlcHJlY2F0ZWQgYW5kIG11c3Qgbm90IGJlIHVzZWQuIEFuIFNRTAorICAgICAqICAgICAgICAgICAgIHtAY29kZSBUaW1lfSBvYmplY3QgZG9lcyBub3QgaGF2ZSBhIDxpPkRheTwvaT4gY29tcG9uZW50LgorICAgICAqIEByZXR1cm4gZG9lcyBub3QgcmV0dXJuIGFueXRoaW5nLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCisgICAgQERlcHJlY2F0ZWQKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldERheSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBkZXByZWNhdGVkIFRoaXMgbWV0aG9kIGlzIGRlcHJlY2F0ZWQgYW5kIG11c3Qgbm90IGJlIHVzZWQuIEFuIFNRTAorICAgICAqICAgICAgICAgICAgIHtAY29kZSBUaW1lfSBvYmplY3QgZG9lcyBub3QgaGF2ZSBhIDxpPk1vbnRoPC9pPiBjb21wb25lbnQuCisgICAgICogQHJldHVybiBkb2VzIG5vdCByZXR1cm4gYW55dGhpbmcuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBARGVwcmVjYXRlZAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0TW9udGgoKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBpcyBkZXByZWNhdGVkIGFuZCBtdXN0IG5vdCBiZSB1c2VkLiBBbiBTUUwKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgVGltZX0gb2JqZWN0IGRvZXMgbm90IGhhdmUgYSA8aT5ZZWFyPC9pPiBjb21wb25lbnQuCisgICAgICogQHJldHVybiBkb2VzIG5vdCByZXR1cm4gYW55dGhpbmcuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBARGVwcmVjYXRlZAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0WWVhcigpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBkZXByZWNhdGVkIFRoaXMgbWV0aG9kIGlzIGRlcHJlY2F0ZWQgYW5kIG11c3Qgbm90IGJlIHVzZWQuIEFuIFNRTAorICAgICAqICAgICAgICAgICAgIHtAY29kZSBUaW1lfSBvYmplY3QgZG9lcyBub3QgaGF2ZSBhIHtAY29kZSBEYXRlfSBjb21wb25lbnQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBARGVwcmVjYXRlZAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldERhdGUoaW50IGkpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBkZXByZWNhdGVkIFRoaXMgbWV0aG9kIGlzIGRlcHJlY2F0ZWQgYW5kIG11c3Qgbm90IGJlIHVzZWQuIEFuIFNRTAorICAgICAqICAgICAgICAgICAgIHtAY29kZSBUaW1lfSBvYmplY3QgZG9lcyBub3QgaGF2ZSBhIDxpPk1vbnRoPC9pPiBjb21wb25lbnQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBARGVwcmVjYXRlZAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldE1vbnRoKGludCBpKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBpcyBkZXByZWNhdGVkIGFuZCBtdXN0IG5vdCBiZSB1c2VkLiBBbiBTUUwKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgVGltZX0gb2JqZWN0IGRvZXMgbm90IGhhdmUgYSA8aT5ZZWFyPC9pPiBjb21wb25lbnQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBARGVwcmVjYXRlZAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFllYXIoaW50IGkpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHRpbWUgZm9yIHRoaXMge0Bjb2RlIFRpbWV9IG9iamVjdCB0byB0aGUgc3VwcGxpZWQgbWlsbGlzZWNvbmRzCisgICAgICogdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGltZQorICAgICAqICAgICAgICAgICAgQSB0aW1lIHZhbHVlIGV4cHJlc3NlZCBhcyBtaWxsaXNlY29uZHMgc2luY2UgdGhlIDxpPkVwb2NoPC9pPi4KKyAgICAgKiAgICAgICAgICAgIE5lZ2F0aXZlIHZhbHVlcyBhcmUgbWlsbGlzZWNvbmRzIGJlZm9yZSB0aGUgRXBvY2guIFRoZSBFcG9jaAorICAgICAqICAgICAgICAgICAgaXMgSmFudWFyeSAxIDE5NzAsIDAwOjAwOjAwLjAwMC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lKGxvbmcgdGltZSkgeworICAgICAgICBzdXBlci5zZXRUaW1lKHRpbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZvcm1hdHMgdGhlIHtAY29kZSBUaW1lfSBhcyBhIFN0cmluZyBpbiBKREJDIGVzY2FwZSBmb3JtYXQ6IHtAY29kZQorICAgICAqIGhoOm1tOnNzfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQSBTdHJpbmcgcmVwcmVzZW50aW5nIHRoZSB7QGNvZGUgVGltZX0gdmFsdWUgaW4gSkRCQyBlc2NhcGUKKyAgICAgKiAgICAgICAgIGZvcm1hdDoge0Bjb2RlIEhIOm1tOnNzfQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcig4KTsKKworICAgICAgICBmb3JtYXQoZ2V0SG91cnMoKSwgMiwgc2IpOworICAgICAgICBzYi5hcHBlbmQoJzonKTsKKyAgICAgICAgZm9ybWF0KGdldE1pbnV0ZXMoKSwgMiwgc2IpOworICAgICAgICBzYi5hcHBlbmQoJzonKTsKKyAgICAgICAgZm9ybWF0KGdldFNlY29uZHMoKSwgMiwgc2IpOworCisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQQURESU5HID0gIjAwIjsKKworICAgIC8qCisgICAgKiBQcml2YXRlIG1ldGhvZCB0byBmb3JtYXQgdGhlIHRpbWUKKyAgICAqLworICAgIHByaXZhdGUgdm9pZCBmb3JtYXQoaW50IGRhdGUsIGludCBkaWdpdHMsIFN0cmluZ0J1aWxkZXIgc2IpIHsKKyAgICAgICAgU3RyaW5nIHN0ciA9IFN0cmluZy52YWx1ZU9mKGRhdGUpOworICAgICAgICBpZiAoZGlnaXRzIC0gc3RyLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgc2IuYXBwZW5kKFBBRERJTkcuc3Vic3RyaW5nKDAsIGRpZ2l0cyAtIHN0ci5sZW5ndGgoKSkpOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZChzdHIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgVGltZX0gb2JqZWN0IGZyb20gYSBzdHJpbmcgaG9sZGluZyBhIHRpbWUgcmVwcmVzZW50ZWQgaW4KKyAgICAgKiBKREJDIGVzY2FwZSBmb3JtYXQ6IHtAY29kZSBoaDptbTpzc30uCisgICAgICogPHA+CisgICAgICogQW4gZXhjZXB0aW9uIG9jY3VycyBpZiB0aGUgaW5wdXQgc3RyaW5nIGRvZXMgbm90IGNvbXBseSB3aXRoIHRoaXMgZm9ybWF0LgorICAgICAqCisgICAgICogQHBhcmFtIHRpbWVTdHJpbmcKKyAgICAgKiAgICAgICAgICAgIEEgU3RyaW5nIHJlcHJlc2VudGluZyB0aGUgdGltZSB2YWx1ZSBpbiBKREJDIGVzY2FwZSBmb3JtYXQ6CisgICAgICogICAgICAgICAgICB7QGNvZGUgaGg6bW06c3N9LgorICAgICAqIEByZXR1cm4gVGhlIHtAY29kZSBUaW1lfSBvYmplY3Qgc2V0IHRvIGEgdGltZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbgorICAgICAqICAgICAgICAgdGltZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzdXBwbGllZCB0aW1lIHN0cmluZyBpcyBub3QgaW4gSkRCQyBlc2NhcGUgZm9ybWF0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVGltZSB2YWx1ZU9mKFN0cmluZyB0aW1lU3RyaW5nKSB7CisgICAgICAgIGlmICh0aW1lU3RyaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgZmlyc3RJbmRleCA9IHRpbWVTdHJpbmcuaW5kZXhPZignOicpOworICAgICAgICBpbnQgc2Vjb25kSW5kZXggPSB0aW1lU3RyaW5nLmluZGV4T2YoJzonLCBmaXJzdEluZGV4ICsgMSk7CisgICAgICAgIC8vIHNlY29uZEluZGV4ID09IC0xIG1lYW5zIG5vbmUgb3Igb25seSBvbmUgc2VwYXJhdG9yICctJyBoYXMgYmVlbgorICAgICAgICAvLyBmb3VuZC4KKyAgICAgICAgLy8gVGhlIHN0cmluZyBpcyBzZXBhcmF0ZWQgaW50byB0aHJlZSBwYXJ0cyBieSB0d28gc2VwYXJhdG9yIGNoYXJhY3RlcnMsCisgICAgICAgIC8vIGlmIHRoZSBmaXJzdCBvciB0aGUgdGhpcmQgcGFydCBpcyBudWxsIHN0cmluZywgd2Ugc2hvdWxkIHRocm93CisgICAgICAgIC8vIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB0byBmb2xsb3cgUkkKKyAgICAgICAgaWYgKHNlY29uZEluZGV4ID09IC0xIHx8IGZpcnN0SW5kZXggPT0gMAorICAgICAgICAgICAgICAgIHx8IHNlY29uZEluZGV4ICsgMSA9PSB0aW1lU3RyaW5nLmxlbmd0aCgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgLy8gcGFyc2UgZWFjaCBwYXJ0IG9mIHRoZSBzdHJpbmcKKyAgICAgICAgaW50IGhvdXIgPSBJbnRlZ2VyLnBhcnNlSW50KHRpbWVTdHJpbmcuc3Vic3RyaW5nKDAsIGZpcnN0SW5kZXgpKTsKKyAgICAgICAgaW50IG1pbnV0ZSA9IEludGVnZXIucGFyc2VJbnQodGltZVN0cmluZy5zdWJzdHJpbmcoZmlyc3RJbmRleCArIDEsCisgICAgICAgICAgICAgICAgc2Vjb25kSW5kZXgpKTsKKyAgICAgICAgaW50IHNlY29uZCA9IEludGVnZXIucGFyc2VJbnQodGltZVN0cmluZy5zdWJzdHJpbmcoc2Vjb25kSW5kZXggKyAxLAorICAgICAgICAgICAgICAgIHRpbWVTdHJpbmcubGVuZ3RoKCkpKTsKKyAgICAgICAgcmV0dXJuIG5ldyBUaW1lKGhvdXIsIG1pbnV0ZSwgc2Vjb25kKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvVGltZXN0YW1wLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvVGltZXN0YW1wLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDYzZWE4YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9UaW1lc3RhbXAuamF2YQpAQCAtMCwwICsxLDUwOSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS5zcWw7CisKK2ltcG9ydCBqYXZhLnRleHQuUGFyc2VQb3NpdGlvbjsKK2ltcG9ydCBqYXZhLnRleHQuU2ltcGxlRGF0ZUZvcm1hdDsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKKworLyoqCisgKiBBIEphdmEgcmVwcmVzZW50YXRpb24gb2YgdGhlIFNRTCB7QGNvZGUgVElNRVNUQU1QfSB0eXBlLiBJdCBwcm92aWRlcyB0aGUKKyAqIGNhcGFiaWxpdHkgb2YgcmVwcmVzZW50aW5nIHRoZSBTUUwge0Bjb2RlIFRJTUVTVEFNUH0gbmFub3NlY29uZCB2YWx1ZSwgaW4KKyAqIGFkZGl0aW9uIHRvIHRoZSByZWd1bGFyIGRhdGUvdGltZSB2YWx1ZSB3aGljaCBoYXMgbWlsbGlzZWNvbmQgcmVzb2x1dGlvbi4KKyAqIDxwPgorICogVGhlIHtAY29kZSBUaW1lc3RhbXB9IGNsYXNzIGNvbnNpc3RzIG9mIGEgcmVndWxhciBkYXRlL3RpbWUgdmFsdWUsIHdoZXJlIG9ubHkKKyAqIHRoZSBpbnRlZ3JhbCBzZWNvbmRzIHZhbHVlIGlzIHN0b3JlZCwgcGx1cyBhIG5hbm9zZWNvbmRzIHZhbHVlIHdoZXJlIHRoZQorICogZnJhY3Rpb25hbCBzZWNvbmRzIGFyZSBzdG9yZWQuCisgKiA8cD4KKyAqIFRoZSBhZGRpdGlvbiBvZiB0aGUgbmFub3NlY29uZCB2YWx1ZSBmaWVsZCB0byB0aGUge0Bjb2RlIFRpbWVzdGFtcH0gb2JqZWN0CisgKiBtYWtlcyBpdCBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBmcm9tIHRoZSB7QGNvZGUgamF2YS51dGlsLkRhdGV9IG9iamVjdCB3aGljaAorICogaXQgZXh0ZW5kcy4gVXNlcnMgc2hvdWxkIGJlIGF3YXJlIHRoYXQge0Bjb2RlIFRpbWVzdGFtcH0gb2JqZWN0cyBhcmUgbm90CisgKiBpbnRlcmNoYW5nYWJsZSB3aXRoIHtAY29kZSBqYXZhLnV0aWwuRGF0ZX0gb2JqZWN0cyB3aGVuIHVzZWQgb3V0c2lkZSB0aGUKKyAqIGNvbmZpbmVzIG9mIHRoZSB7QGNvZGUgamF2YS5zcWx9IHBhY2thZ2UuCisgKgorICogQHNlZSBEYXRlCisgKiBAc2VlIFRpbWUKKyAqIEBzZWUgamF2YS51dGlsLkRhdGUKKyAqLworcHVibGljIGNsYXNzIFRpbWVzdGFtcCBleHRlbmRzIERhdGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjc0NTE3OTAyNzg3NDc1ODUwMUw7CisKKyAgICAvLyBUaGUgbmFub3NlY29uZHMgdGltZSB2YWx1ZSBvZiB0aGUgVGltZXN0YW1wCisgICAgcHJpdmF0ZSBpbnQgbmFub3M7CisKKyAgICAvLyBUaGUgcmVnZXggcGF0dGVybiBvZiB5eXl5LU1NLWRkIEhIOm1tOnNzCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRJTUVfRk9STUFUX1JFR0VYID0gIlswLTldezR9LVswLTldezJ9LVswLTldezJ9IFswLTldezJ9OlswLTldezJ9OlswLTldezJ9LioiOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBUaW1lc3RhbXB9IGNvcnJlc3BvbmRpbmcgdG8gdGhlIHRpbWUgc3BlY2lmaWVkIGJ5IHRoZQorICAgICAqIHN1cHBsaWVkIHZhbHVlcyBmb3IgPGk+WWVhcjwvaT4sIDxpPk1vbnRoPC9pPiwgPGk+RGF0ZTwvaT4sIDxpPkhvdXI8L2k+LAorICAgICAqIDxpPk1pbnV0ZXM8L2k+LCA8aT5TZWNvbmRzPC9pPiBhbmQgPGk+TmFub3NlY29uZHM8L2k+LgorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgVXNlIHRoZSBjb25zdHJ1Y3RvciB7QGxpbmsgI1RpbWVzdGFtcChsb25nKX0uCisgICAgICogQHBhcmFtIHRoZVllYXIKKyAgICAgKiAgICAgICAgICAgIHNwZWNpZmllZCBhcyB0aGUgeWVhciBtaW51cyAxOTAwLgorICAgICAqIEBwYXJhbSB0aGVNb250aAorICAgICAqICAgICAgICAgICAgc3BlY2lmaWVkIGFzIGFuIGludGVnZXIgaW4gdGhlIHJhbmdlIFswLDExXS4KKyAgICAgKiBAcGFyYW0gdGhlRGF0ZQorICAgICAqICAgICAgICAgICAgc3BlY2lmaWVkIGFzIGFuIGludGVnZXIgaW4gdGhlIHJhbmdlIFsxLDMxXS4KKyAgICAgKiBAcGFyYW0gdGhlSG91cgorICAgICAqICAgICAgICAgICAgc3BlY2lmaWVkIGFzIGFuIGludGVnZXIgaW4gdGhlIHJhbmdlIFswLDIzXS4KKyAgICAgKiBAcGFyYW0gdGhlTWludXRlCisgICAgICogICAgICAgICAgICBzcGVjaWZpZWQgYXMgYW4gaW50ZWdlciBpbiB0aGUgcmFuZ2UgWzAsNTldLgorICAgICAqIEBwYXJhbSB0aGVTZWNvbmQKKyAgICAgKiAgICAgICAgICAgIHNwZWNpZmllZCBhcyBhbiBpbnRlZ2VyIGluIHRoZSByYW5nZSBbMCw1OV0uCisgICAgICogQHBhcmFtIHRoZU5hbm8KKyAgICAgKiAgICAgICAgICAgIHdoaWNoIGRlZmluZXMgdGhlIG5hbm9zZWNvbmQgdmFsdWUgb2YgdGhlIHRpbWVzdGFtcCBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgICAgIGFzIGFuIGludGVnZXIgaW4gdGhlIHJhbmdlIFswLDk5OSc5OTknOTk5XQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IG9mIHRoZSBwYXJhbWV0ZXJzIGlzIG91dCBvZiByYW5nZS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIFRpbWVzdGFtcChpbnQgdGhlWWVhciwgaW50IHRoZU1vbnRoLCBpbnQgdGhlRGF0ZSwgaW50IHRoZUhvdXIsCisgICAgICAgICAgICBpbnQgdGhlTWludXRlLCBpbnQgdGhlU2Vjb25kLCBpbnQgdGhlTmFubykKKyAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBzdXBlcih0aGVZZWFyLCB0aGVNb250aCwgdGhlRGF0ZSwgdGhlSG91ciwgdGhlTWludXRlLCB0aGVTZWNvbmQpOworICAgICAgICBpZiAodGhlTmFubyA8IDAgfHwgdGhlTmFubyA+IDk5OTk5OTk5OSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIG5hbm9zID0gdGhlTmFubzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIFRpbWVzdGFtcH0gb2JqZWN0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIHRpbWUgcmVwcmVzZW50ZWQKKyAgICAgKiBieSBhIHN1cHBsaWVkIHRpbWUgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlVGltZQorICAgICAqICAgICAgICAgICAgYSB0aW1lIHZhbHVlIGluIHRoZSBmb3JtYXQgb2YgbWlsbGlzZWNvbmRzIHNpbmNlIHRoZSBFcG9jaAorICAgICAqICAgICAgICAgICAgKEphbnVhcnkgMSAxOTcwIDAwOjAwOjAwLjAwMCBHTVQpLgorICAgICAqLworICAgIHB1YmxpYyBUaW1lc3RhbXAobG9uZyB0aGVUaW1lKSB7CisgICAgICAgIHN1cGVyKHRoZVRpbWUpOworICAgICAgICAvKgorICAgICAgICAgKiBOb3cgc2V0IHRoZSB0aW1lIGZvciB0aGlzIFRpbWVzdGFtcCBvYmplY3QgLSB3aGljaCBkZWFscyB3aXRoIHRoZQorICAgICAgICAgKiBuYW5vc2Vjb25kIHZhbHVlIGFzIHdlbGwgYXMgdGhlIGJhc2UgdGltZQorICAgICAgICAgKi8KKyAgICAgICAgc2V0VGltZUltcGwodGhlVGltZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB0aW1lc3RhbXAgb2JqZWN0IGlzIGxhdGVyIHRoYW4gdGhlIHN1cHBsaWVkCisgICAgICogdGltZXN0YW1wLCBvdGhlcndpc2UgcmV0dXJucyB7QGNvZGUgZmFsc2V9LgorICAgICAqCisgICAgICogQHBhcmFtIHRoZVRpbWVzdGFtcAorICAgICAqICAgICAgICAgICAgdGhlIHRpbWVzdGFtcCB0byBjb21wYXJlIHdpdGggdGhpcyB0aW1lc3RhbXAgb2JqZWN0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMge0Bjb2RlIFRpbWVzdGFtcH0gb2JqZWN0IGlzIGxhdGVyIHRoYW4gdGhlCisgICAgICogICAgICAgICBzdXBwbGllZCB0aW1lc3RhbXAsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGFmdGVyKFRpbWVzdGFtcCB0aGVUaW1lc3RhbXApIHsKKyAgICAgICAgbG9uZyB0aGlzVGltZSA9IHRoaXMuZ2V0VGltZSgpOworICAgICAgICBsb25nIGNvbXBhcmVUaW1lID0gdGhlVGltZXN0YW1wLmdldFRpbWUoKTsKKworICAgICAgICAvLyBJZiB0aGUgdGltZSB2YWx1ZSBpcyBsYXRlciwgdGhlIHRpbWVzdGFtcCBpcyBsYXRlcgorICAgICAgICBpZiAodGhpc1RpbWUgPiBjb21wYXJlVGltZSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgLy8gSWYgdGhlIHRpbWUgdmFsdWUgaXMgZWFybGllciwgdGhlIHRpbWVzdGFtcCBpcyBub3QgbGF0ZXIKKyAgICAgICAgZWxzZSBpZiAodGhpc1RpbWUgPCBjb21wYXJlVGltZSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIC8qCisgICAgICAgICAqIE90aGVyd2lzZSB0aGUgdGltZSB2YWx1ZXMgYXJlIGVxdWFsIGluIHdoaWNoIGNhc2UgdGhlIG5hbm9zZWNvbmRzCisgICAgICAgICAqIHZhbHVlIGRldGVybWluZXMgd2hldGhlciB0aGlzIHRpbWVzdGFtcCBpcyBsYXRlci4uLgorICAgICAgICAgKi8KKyAgICAgICAgZWxzZSBpZiAodGhpcy5nZXROYW5vcygpID4gdGhlVGltZXN0YW1wLmdldE5hbm9zKCkpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgVGltZXN0YW1wfSBvYmplY3QgaXMgZWFybGllciB0aGFuIHRoZQorICAgICAqIHN1cHBsaWVkIHRpbWVzdGFtcCwgb3RoZXJ3aXNlIHJldHVybnMge0Bjb2RlIGZhbHNlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVUaW1lc3RhbXAKKyAgICAgKiAgICAgICAgICAgIHRoZSB0aW1lc3RhbXAgdG8gY29tcGFyZSB3aXRoIHRoaXMge0Bjb2RlIFRpbWVzdGFtcH0gb2JqZWN0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMge0Bjb2RlIFRpbWVzdGFtcH0gb2JqZWN0IGlzIGVhcmxpZXIgdGhhbiB0aGUKKyAgICAgKiAgICAgICAgIHN1cHBsaWVkIHRpbWVzdGFtcCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYmVmb3JlKFRpbWVzdGFtcCB0aGVUaW1lc3RhbXApIHsKKyAgICAgICAgbG9uZyB0aGlzVGltZSA9IHRoaXMuZ2V0VGltZSgpOworICAgICAgICBsb25nIGNvbXBhcmVUaW1lID0gdGhlVGltZXN0YW1wLmdldFRpbWUoKTsKKworICAgICAgICAvLyBJZiB0aGUgdGltZSB2YWx1ZSBpcyBsYXRlciwgdGhlIHRpbWVzdGFtcCBpcyBsYXRlcgorICAgICAgICBpZiAodGhpc1RpbWUgPCBjb21wYXJlVGltZSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgLy8gSWYgdGhlIHRpbWUgdmFsdWUgaXMgZWFybGllciwgdGhlIHRpbWVzdGFtcCBpcyBub3QgbGF0ZXIKKyAgICAgICAgZWxzZSBpZiAodGhpc1RpbWUgPiBjb21wYXJlVGltZSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIC8qCisgICAgICAgICAqIE90aGVyd2lzZSB0aGUgdGltZSB2YWx1ZXMgYXJlIGVxdWFsIGluIHdoaWNoIGNhc2UgdGhlIG5hbm9zZWNvbmRzCisgICAgICAgICAqIHZhbHVlIGRldGVybWluZXMgd2hldGhlciB0aGlzIHRpbWVzdGFtcCBpcyBsYXRlci4uLgorICAgICAgICAgKi8KKyAgICAgICAgZWxzZSBpZiAodGhpcy5nZXROYW5vcygpIDwgdGhlVGltZXN0YW1wLmdldE5hbm9zKCkpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyB7QGNvZGUgVGltZXN0YW1wfSBvYmplY3Qgd2l0aCBhIHN1cHBsaWVkIHtAY29kZSBUaW1lc3RhbXB9CisgICAgICogb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHRoZU9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIHRpbWVzdGFtcCB0byBjb21wYXJlIHdpdGggdGhpcyB7QGNvZGUgVGltZXN0YW1wfSBvYmplY3QsCisgICAgICogICAgICAgICAgICBwYXNzZWQgYXMgYW4ge0Bjb2RlIE9iamVjdH0uCisgICAgICogQHJldHVybiA8ZGQ+CisgICAgICogICAgICAgICA8ZGw+CisgICAgICogICAgICAgICB7QGNvZGUgMH0gaWYgdGhlIHR3byB7QGNvZGUgVGltZXN0YW1wfSBvYmplY3RzIGFyZSBlcXVhbCBpbiB0aW1lCisgICAgICogICAgICAgICA8L2RsPgorICAgICAqICAgICAgICAgPGRsPgorICAgICAqICAgICAgICAgYSB2YWx1ZSB7QGNvZGUgPCAwfSBpZiB0aGlzIHtAY29kZSBUaW1lc3RhbXB9IG9iamVjdCBpcyBiZWZvcmUKKyAgICAgKiAgICAgICAgIHRoZSBzdXBwbGllZCB7QGNvZGUgVGltZXN0YW1wfSBhbmQgYSB2YWx1ZQorICAgICAqICAgICAgICAgPC9kbD4KKyAgICAgKiAgICAgICAgIDxkbD4KKyAgICAgKiAgICAgICAgIHtAY29kZSA+IDB9IGlmIHRoaXMge0Bjb2RlIFRpbWVzdGFtcH0gb2JqZWN0IGlzIGFmdGVyIHRoZQorICAgICAqICAgICAgICAgc3VwcGxpZWQge0Bjb2RlIFRpbWVzdGFtcH0KKyAgICAgKiAgICAgICAgIDwvZGw+CisgICAgICogICAgICAgICA8L2RkPgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHN1cHBsaWVkIG9iamVjdCBpcyBub3QgYSB7QGNvZGUgVGltZXN0YW1wfSBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBjb21wYXJlVG8oRGF0ZSB0aGVPYmplY3QpIHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24geworICAgICAgICByZXR1cm4gdGhpcy5jb21wYXJlVG8oKFRpbWVzdGFtcCkgdGhlT2JqZWN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIHtAY29kZSBUaW1lc3RhbXB9IG9iamVjdCB3aXRoIGEgc3VwcGxpZWQge0Bjb2RlIFRpbWVzdGFtcH0KKyAgICAgKiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlVGltZXN0YW1wCisgICAgICogICAgICAgICAgICB0aGUgdGltZXN0YW1wIHRvIGNvbXBhcmUgd2l0aCB0aGlzIHtAY29kZSBUaW1lc3RhbXB9IG9iamVjdCwKKyAgICAgKiAgICAgICAgICAgIHBhc3NlZCBpbiBhcyBhIHtAY29kZSBUaW1lc3RhbXB9LgorICAgICAqIEByZXR1cm4gb25lIG9mIHRoZSBmb2xsb3dpbmc6CisgICAgICogICAgICAgICA8dWw+CisgICAgICogICAgICAgICA8bGk+e0Bjb2RlIDB9LCBpZiB0aGUgdHdvIHtAY29kZSBUaW1lc3RhbXB9IG9iamVjdHMgYXJlCisgICAgICogICAgICAgICBlcXVhbCBpbiB0aW1lPC9saT4KKyAgICAgKiAgICAgICAgIDxsaT57QGNvZGUgPCAwfSwgaWYgdGhpcyB7QGNvZGUgVGltZXN0YW1wfSBvYmplY3QgaXMgYmVmb3JlIHRoZQorICAgICAqICAgICAgICAgc3VwcGxpZWQge0Bjb2RlIFRpbWVzdGFtcH08L2xpPgorICAgICAqICAgICAgICAgPGxpPiB7QGNvZGUgPiAwfSwgaWYgdGhpcyB7QGNvZGUgVGltZXN0YW1wfSBvYmplY3QgaXMgYWZ0ZXIgdGhlCisgICAgICogICAgICAgICBzdXBwbGllZCB7QGNvZGUgVGltZXN0YW1wfTwvbGk+CisgICAgICogICAgICAgICA8L3VsPgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKFRpbWVzdGFtcCB0aGVUaW1lc3RhbXApIHsKKyAgICAgICAgaW50IHJlc3VsdCA9IHN1cGVyLmNvbXBhcmVUbyh0aGVUaW1lc3RhbXApOworICAgICAgICBpZiAocmVzdWx0ID09IDApIHsKKyAgICAgICAgICAgIGludCB0aGlzTmFubyA9IHRoaXMuZ2V0TmFub3MoKTsKKyAgICAgICAgICAgIGludCB0aGF0TmFubyA9IHRoZVRpbWVzdGFtcC5nZXROYW5vcygpOworICAgICAgICAgICAgaWYgKHRoaXNOYW5vID4gdGhhdE5hbm8pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpc05hbm8gPT0gdGhhdE5hbm8pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgdG8gc2VlIGlmIHRoaXMgdGltZXN0YW1wIGlzIGVxdWFsIHRvIGEgc3VwcGxpZWQgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHRoZU9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byB3aGljaCB0aGlzIHRpbWVzdGFtcCBpcyBjb21wYXJlZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBUaW1lc3RhbXB9IG9iamVjdCBpcyBlcXVhbCB0byB0aGUKKyAgICAgKiAgICAgICAgIHN1cHBsaWVkIHtAY29kZSBUaW1lc3RhbXB9IG9iamVjdDxicj57QGNvZGUgZmFsc2V9IGlmIHRoZSBvYmplY3QKKyAgICAgKiAgICAgICAgIGlzIG5vdCBhIHtAY29kZSBUaW1lc3RhbXB9IG9iamVjdCBvciBpZiB0aGUgb2JqZWN0IGlzIGEge0Bjb2RlCisgICAgICogICAgICAgICBUaW1lc3RhbXB9IGJ1dCByZXByZXNlbnRzIGEgZGlmZmVyZW50IGluc3RhbnQgaW4gdGltZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoZU9iamVjdCkgeworICAgICAgICBpZiAodGhlT2JqZWN0IGluc3RhbmNlb2YgVGltZXN0YW1wKSB7CisgICAgICAgICAgICByZXR1cm4gZXF1YWxzKChUaW1lc3RhbXApIHRoZU9iamVjdCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHRvIHNlZSBpZiB0aGlzIHRpbWVzdGFtcCBpcyBlcXVhbCB0byBhIHN1cHBsaWVkIHRpbWVzdGFtcC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVUaW1lc3RhbXAKKyAgICAgKiAgICAgICAgICAgIHRoZSB0aW1lc3RhbXAgdG8gY29tcGFyZSB3aXRoIHRoaXMge0Bjb2RlIFRpbWVzdGFtcH0gb2JqZWN0LAorICAgICAqICAgICAgICAgICAgcGFzc2VkIGFzIGFuIHtAY29kZSBPYmplY3R9LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMge0Bjb2RlIFRpbWVzdGFtcH0gb2JqZWN0IGlzIGVxdWFsIHRvIHRoZQorICAgICAqICAgICAgICAgc3VwcGxpZWQge0Bjb2RlIFRpbWVzdGFtcH0gb2JqZWN0LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoVGltZXN0YW1wIHRoZVRpbWVzdGFtcCkgeworICAgICAgICBpZiAodGhlVGltZXN0YW1wID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKHRoaXMuZ2V0VGltZSgpID09IHRoZVRpbWVzdGFtcC5nZXRUaW1lKCkpCisgICAgICAgICAgICAgICAgJiYgKHRoaXMuZ2V0TmFub3MoKSA9PSB0aGVUaW1lc3RhbXAuZ2V0TmFub3MoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGlzIHtAY29kZSBUaW1lc3RhbXB9J3MgbmFub3NlY29uZCB2YWx1ZQorICAgICAqCisgICAgICogQHJldHVybiBUaGUgdGltZXN0YW1wJ3MgbmFub3NlY29uZCB2YWx1ZSwgYW4gaW50ZWdlciBiZXR3ZWVuIDAgYW5kCisgICAgICogICAgICAgICA5OTksOTk5LDk5OS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE5hbm9zKCkgeworICAgICAgICByZXR1cm4gbmFub3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGltZSByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBUaW1lc3RhbXB9IG9iamVjdCwgYXMgYSBsb25nCisgICAgICogdmFsdWUgY29udGFpbmluZyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBzaW5jZSB0aGUgRXBvY2ggKEphbnVhcnkgMQorICAgICAqIDE5NzAsIDAwOjAwOjAwLjAwMCBHTVQpLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgcGFzc2VkIHNpbmNlIEphbnVhcnkgMSAxOTcwLAorICAgICAqICAgICAgICAgMDA6MDA6MDAuMDAwIEdNVC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRUaW1lKCkgeworICAgICAgICBsb25nIHRoZVRpbWUgPSBzdXBlci5nZXRUaW1lKCk7CisgICAgICAgIHRoZVRpbWUgPSB0aGVUaW1lICsgKG5hbm9zIC8gMTAwMDAwMCk7CisgICAgICAgIHJldHVybiB0aGVUaW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5hbm9zZWNvbmQgdmFsdWUgZm9yIHRoaXMge0Bjb2RlIFRpbWVzdGFtcH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbgorICAgICAqICAgICAgICAgICAgbnVtYmVyIG9mIG5hbm9zZWNvbmRzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgbnVtYmVyIG9mIG5hbm9zZWNvbmRzIHNtYWxsZXIgdGhhbiAwIG9yIGdyZWF0ZXIgdGhhbgorICAgICAqICAgICAgICAgICAgIDk5OSw5OTksOTk5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5hbm9zKGludCBuKSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKChuIDwgMCkgfHwgKG4gPiA5OTk5OTk5OTkpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJWYWx1ZSBvdXQgb2YgcmFuZ2UiKTsKKyAgICAgICAgfQorICAgICAgICBuYW5vcyA9IG47CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdGltZSByZXByZXNlbnRlZCBieSB0aGlzIHtAY29kZSBUaW1lc3RhbXB9IG9iamVjdCB0byB0aGUKKyAgICAgKiBzdXBwbGllZCB0aW1lLCBkZWZpbmVkIGFzIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHNpbmNlIHRoZSBFcG9jaAorICAgICAqIChKYW51YXJ5IDEgMTk3MCwgMDA6MDA6MDAuMDAwIEdNVCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlVGltZQorICAgICAqICAgICAgICAgICAgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBzaW5jZSB0aGUgRXBvY2ggKEphbnVhcnkgMSAxOTcwLAorICAgICAqICAgICAgICAgICAgMDA6MDA6MDAuMDAwIEdNVCkuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0VGltZShsb25nIHRoZVRpbWUpIHsKKyAgICAgICAgc2V0VGltZUltcGwodGhlVGltZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNldFRpbWVJbXBsKGxvbmcgdGhlVGltZSkgeworICAgICAgICAvKgorICAgICAgICAgKiBEZWFsIHdpdGggdGhlIG5hbm9zZWNvbmRzIHZhbHVlLiBUaGUgc3VwcGxpZWQgdGltZSBpcyBpbiBtaWxsaXNlY29uZHMgLQorICAgICAgICAgKiBzbyB3ZSBtdXN0IGV4dHJhY3QgdGhlIG1pbGxpc2Vjb25kcyB2YWx1ZSBhbmQgbXVsdGlwbHkgYnkgMTAwMDAwMCB0bworICAgICAgICAgKiBnZXQgbmFub3NlY29uZHMuIFRoaW5ncyBhcmUgbW9yZSBjb21wbGV4IGlmIHRoZVRpbWUgdmFsdWUgaXMKKyAgICAgICAgICogbmVnYXRpdmUsIHNpbmNlIHRoZW4gdGhlIHRpbWUgdmFsdWUgaXMgdGhlIHRpbWUgYmVmb3JlIHRoZSBFcG9jaCBidXQKKyAgICAgICAgICogdGhlIG5hbm9zZWNvbmRzIHZhbHVlIG9mIHRoZSBUaW1lc3RhbXAgbXVzdCBiZSBwb3NpdGl2ZSAtIHNvIHdlIG11c3QKKyAgICAgICAgICogdGFrZSB0aGUgInJhdyIgbWlsbGlzZWNvbmRzIHZhbHVlIGFuZCBzdWJ0cmFjdCBpdCBmcm9tIDEwMDAgdG8gZ2V0IHRvCisgICAgICAgICAqIHRoZSB0cnVlIG5hbm9zZWNvbmRzIHZhbHVlIFNpbXVsdGFuZW91c2x5LCByZWNhbGN1bGF0ZSB0aGUgdGltZSB2YWx1ZQorICAgICAgICAgKiB0byB0aGUgZXhhY3QgbmVhcmVzdCBzZWNvbmQgYW5kIHJlc2V0IHRoZSBEYXRlIHRpbWUgdmFsdWUKKyAgICAgICAgICovCisgICAgICAgIGludCBtaWxsaXNlY29uZHMgPSAoaW50KSAodGhlVGltZSAlIDEwMDApOworICAgICAgICB0aGVUaW1lID0gdGhlVGltZSAtIG1pbGxpc2Vjb25kczsKKyAgICAgICAgaWYgKG1pbGxpc2Vjb25kcyA8IDApIHsKKyAgICAgICAgICAgIHRoZVRpbWUgPSB0aGVUaW1lIC0gMTAwMDsKKyAgICAgICAgICAgIG1pbGxpc2Vjb25kcyA9IDEwMDAgKyBtaWxsaXNlY29uZHM7CisgICAgICAgIH0KKyAgICAgICAgc3VwZXIuc2V0VGltZSh0aGVUaW1lKTsKKyAgICAgICAgc2V0TmFub3MobWlsbGlzZWNvbmRzICogMTAwMDAwMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGltZXN0YW1wIGZvcm1hdHRlZCBhcyBhIFN0cmluZyBpbiB0aGUgSkRCQyBUaW1lc3RhbXAgRXNjYXBlCisgICAgICogZm9ybWF0LCB3aGljaCBpcyB7QGNvZGUgInl5eXktTU0tZGQgSEg6bW06c3Mubm5ubm5ubm5uIn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgaW5zdGFudCBkZWZpbmVkIGJ5IHRoZSB7QGNvZGUKKyAgICAgKiAgICAgICAgIFRpbWVzdGFtcH0sIGluIEpEQkMgVGltZXN0YW1wIGVzY2FwZSBmb3JtYXQuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoMjkpOworCisgICAgICAgIGZvcm1hdCgoZ2V0WWVhcigpICsgMTkwMCksIDQsIHNiKTsKKyAgICAgICAgc2IuYXBwZW5kKCctJyk7CisgICAgICAgIGZvcm1hdCgoZ2V0TW9udGgoKSArIDEpLCAyLCBzYik7CisgICAgICAgIHNiLmFwcGVuZCgnLScpOworICAgICAgICBmb3JtYXQoZ2V0RGF0ZSgpLCAyLCBzYik7CisgICAgICAgIHNiLmFwcGVuZCgnICcpOworICAgICAgICBmb3JtYXQoZ2V0SG91cnMoKSwgMiwgc2IpOworICAgICAgICBzYi5hcHBlbmQoJzonKTsKKyAgICAgICAgZm9ybWF0KGdldE1pbnV0ZXMoKSwgMiwgc2IpOworICAgICAgICBzYi5hcHBlbmQoJzonKTsKKyAgICAgICAgZm9ybWF0KGdldFNlY29uZHMoKSwgMiwgc2IpOworICAgICAgICBzYi5hcHBlbmQoJy4nKTsKKyAgICAgICAgaWYgKG5hbm9zID09IDApIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgnMCcpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZm9ybWF0KG5hbm9zLCA5LCBzYik7CisgICAgICAgICAgICB3aGlsZSAoc2IuY2hhckF0KHNiLmxlbmd0aCgpIC0gMSkgPT0gJzAnKSB7CisgICAgICAgICAgICAgICAgc2Iuc2V0TGVuZ3RoKHNiLmxlbmd0aCgpIC0gMSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUEFERElORyA9ICIwMDAwMDAwMDAiOworCisgICAgLyoKKyAgICAqIFByaXZhdGUgbWV0aG9kIHRvIGZvcm1hdCB0aGUgdGltZQorICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGZvcm1hdChpbnQgZGF0ZSwgaW50IGRpZ2l0cywgU3RyaW5nQnVpbGRlciBzYikgeworICAgICAgICBTdHJpbmcgc3RyID0gU3RyaW5nLnZhbHVlT2YoZGF0ZSk7CisgICAgICAgIGlmIChkaWdpdHMgLSBzdHIubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoUEFERElORy5zdWJzdHJpbmcoMCwgZGlnaXRzIC0gc3RyLmxlbmd0aCgpKSk7CisgICAgICAgIH0KKyAgICAgICAgc2IuYXBwZW5kKHN0cik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHtAY29kZSBUaW1lc3RhbXB9IG9iamVjdCB3aXRoIGEgdGltZSB2YWx1ZSBlcXVhbCB0byB0aGUgdGltZQorICAgICAqIHNwZWNpZmllZCBieSBhIHN1cHBsaWVkIFN0cmluZyBob2xkaW5nIHRoZSB0aW1lIGluIEpEQkMgdGltZXN0YW1wIGVzY2FwZQorICAgICAqIGZvcm1hdCwgd2hpY2ggaXMge0Bjb2RlICJ5eXl5LU1NLWRkIEhIOm1tOnNzLm5ubm5ubm5ubn0iCisgICAgICoKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBTdHJpbmd9IGNvbnRhaW5pbmcgYSB0aW1lIGluIEpEQkMgdGltZXN0YW1wIGVzY2FwZQorICAgICAqICAgICAgICAgICAgZm9ybWF0LgorICAgICAqIEByZXR1cm4gQSB7QGNvZGUgVGltZXN0YW1wfSBvYmplY3Qgd2l0aCB0aW1lIHZhbHVlIGFzIGRlZmluZWQgYnkgdGhlCisgICAgICogICAgICAgICBzdXBwbGllZCB7QGNvZGUgU3RyaW5nfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwcm92aWRlZCBzdHJpbmcgaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVGltZXN0YW1wIHZhbHVlT2YoU3RyaW5nIHMpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBpZiAocyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJBcmd1bWVudCBjYW5ub3QgYmUgbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gb21pdCB0cmFpbGluZyB3aGl0ZXNwYWNlCisgICAgICAgIHMgPSBzLnRyaW0oKTsKKyAgICAgICAgaWYgKCFQYXR0ZXJuLm1hdGNoZXMoVElNRV9GT1JNQVRfUkVHRVgsIHMpKSB7CisgICAgICAgICAgICB0aHJvdyBiYWRUaW1lc3RhbXBTdHJpbmcocyk7CisgICAgICAgIH0KKworICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IGRmID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoInl5eXktTU0tZGQgSEg6bW06c3MiKTsKKyAgICAgICAgUGFyc2VQb3NpdGlvbiBwcCA9IG5ldyBQYXJzZVBvc2l0aW9uKDApOworCisgICAgICAgIC8qCisgICAgICAgICAqIEZpcnN0IHBhcnNlIG91dCB0aGUgeXl5eS1NTS1kZCBISDptbTpzcyBjb21wb25lbnQgb2YgdGhlIFN0cmluZyBpbnRvCisgICAgICAgICAqIGEgRGF0ZSBvYmplY3QgdXNpbmcgdGhlIFNpbXBsZURhdGVGb3JtYXQuIFRoaXMgc2hvdWxkIHN0b3AgYWZ0ZXIgdGhlCisgICAgICAgICAqIHNlY29uZHMgdmFsdWUsIGFjY29yZGluZyB0byB0aGUgZGVmaW5pdGlvbiBvZiBTaW1wbGVEYXRlRm9ybWF0LnBhcnNlLAorICAgICAgICAgKiB3aXRoIHRoZSBQYXJzZVBvc2l0aW9uIGluZGljYXRpbmcgdGhlIGluZGV4IG9mIHRoZSAiLiIgd2hpY2ggc2hvdWxkCisgICAgICAgICAqIHByZWNlZGUgdGhlIG5hbm9zZWNvbmRzIHZhbHVlCisgICAgICAgICAqLworICAgICAgICBEYXRlIHRoZURhdGU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGVEYXRlID0gZGYucGFyc2UocywgcHApOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgYmFkVGltZXN0YW1wU3RyaW5nKHMpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHRoZURhdGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgYmFkVGltZXN0YW1wU3RyaW5nKHMpOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogSWYgd2UgZ2V0IGhlcmUsIHRoZSBEYXRlIHBhcnQgb2YgdGhlIHN0cmluZyB3YXMgT0sgLSBub3cgZm9yIHRoZQorICAgICAgICAgKiBuYW5vc2Vjb25kcyB2YWx1ZS4gU3RyaWN0bHksIHRoaXMgcmVxdWlyZXMgdGhlIHJlbWFpbmluZyBwYXJ0IG9mIHRoZQorICAgICAgICAgKiBTdHJpbmcgdG8gbG9vayBsaWtlICIubm5ubm5ubm5uIi4gSG93ZXZlciwgd2UgYWNjZXB0IGFueXRoaW5nIHdpdGggYQorICAgICAgICAgKiAnLicgZm9sbG93ZWQgYnkgMSB0byA5IGRpZ2l0cyAtIHdlIGFsc28gYWNjZXB0IG5vdGhpbmcgKG5vIGZyYWN0aW9ucworICAgICAgICAgKiBvZiBhIHNlY29uZCkuIEFueXRoaW5nIGVsc2UgaXMgaW50ZXJwcmV0ZWQgYXMgaW5jb3JyZWN0IGZvcm1hdCB3aGljaAorICAgICAgICAgKiB3aWxsIGdlbmVyYXRlIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAgICAgKi8KKyAgICAgICAgaW50IHBvc2l0aW9uID0gcHAuZ2V0SW5kZXgoKTsKKyAgICAgICAgaW50IHJlbWFpbmluZyA9IHMubGVuZ3RoKCkgLSBwb3NpdGlvbjsKKyAgICAgICAgaW50IHRoZU5hbm9zOworCisgICAgICAgIGlmIChyZW1haW5pbmcgPT0gMCkgeworICAgICAgICAgICAgLy8gRmlyc3QsIGFsbG93IGZvciB0aGUgY2FzZSB3aGVyZSBubyBmcmFjdGlvbiBvZiBhIHNlY29uZCBpcyBnaXZlbjoKKyAgICAgICAgICAgIHRoZU5hbm9zID0gMDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBDYXNlIHdoZXJlIGZyYWN0aW9uIG9mIGEgc2Vjb25kIGlzIHNwZWNpZmllZDogUmVxdWlyZSAxIGNoYXJhY3RlcgorICAgICAgICAgICAgICogcGx1cyB0aGUgIi4iIGluIHRoZSByZW1haW5pbmcgcGFydCBvZiB0aGUgc3RyaW5nLi4uCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGlmICgocy5sZW5ndGgoKSAtIHBvc2l0aW9uKSA8ICIubiIubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBiYWRUaW1lc3RhbXBTdHJpbmcocyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBJZiB3ZSdyZSBzdHJpY3QsIHdlIHNob3VsZCBub3QgYWxsb3cgYW55IEVYVFJBIGNoYXJhY3RlcnMgYWZ0ZXIKKyAgICAgICAgICAgICAqIHRoZSA5IGRpZ2l0cworICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAoKHMubGVuZ3RoKCkgLSBwb3NpdGlvbikgPiAiLm5ubm5ubm5ubiIubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBiYWRUaW1lc3RhbXBTdHJpbmcocyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIFJlcXVpcmUgdGhlIG5leHQgY2hhcmFjdGVyIHRvIGJlIGEgIi4iCisgICAgICAgICAgICBpZiAocy5jaGFyQXQocG9zaXRpb24pICE9ICcuJykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oIkJhZCBpbnB1dCBzdHJpbmcgZm9ybWF0OiBleHBlY3RlZCAnLicgbm90ICciICsKKyAgICAgICAgICAgICAgICAgICAgICAgIHMuY2hhckF0KHBvc2l0aW9uKSArICInIGluIFwiIiArIHMgKyAiXCIiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBudW1iZXIgc3RyaW5nIC0gbmVlZCB0byBhY2NvdW50IGZvciB0aGUgJy4nCisgICAgICAgICAgICBpbnQgbmFub0xlbmd0aCA9IHMubGVuZ3RoKCkgLSBwb3NpdGlvbiAtIDE7CisKKyAgICAgICAgICAgIC8vIEdldCB0aGUgOSBjaGFyYWN0ZXJzIGZvbGxvd2luZyB0aGUgIi4iIGFzIGFuIGludGVnZXIKKyAgICAgICAgICAgIFN0cmluZyB0aGVOYW5vU3RyaW5nID0gcy5zdWJzdHJpbmcocG9zaXRpb24gKyAxLCBwb3NpdGlvbiArIDEKKyAgICAgICAgICAgICAgICAgICAgKyBuYW5vTGVuZ3RoKTsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBXZSBtdXN0IGFkanVzdCBmb3IgdGhlIGNhc2VzIHdoZXJlIHRoZSBuYW5vcyBTdHJpbmcgd2FzIG5vdCA5CisgICAgICAgICAgICAgKiBjaGFyYWN0ZXJzIGxvbmcgYnkgcGFkZGluZyBvdXQgd2l0aCB6ZXJvcworICAgICAgICAgICAgICovCisgICAgICAgICAgICB0aGVOYW5vU3RyaW5nID0gdGhlTmFub1N0cmluZyArICIwMDAwMDAwMDAiOworICAgICAgICAgICAgdGhlTmFub1N0cmluZyA9IHRoZU5hbm9TdHJpbmcuc3Vic3RyaW5nKDAsIDkpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRoZU5hbm9zID0gSW50ZWdlci5wYXJzZUludCh0aGVOYW5vU3RyaW5nKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gSWYgd2UgZ2V0IGhlcmUsIHRoZSBzdHJpbmcgd2FzIG5vdCBhIG51bWJlcgorICAgICAgICAgICAgICAgIHRocm93IGJhZFRpbWVzdGFtcFN0cmluZyhzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmICh0aGVOYW5vcyA8IDAgfHwgdGhlTmFub3MgPiA5OTk5OTk5OTkpIHsKKyAgICAgICAgICAgIHRocm93IGJhZFRpbWVzdGFtcFN0cmluZyhzKTsKKyAgICAgICAgfQorCisgICAgICAgIFRpbWVzdGFtcCB0aGVUaW1lc3RhbXAgPSBuZXcgVGltZXN0YW1wKHRoZURhdGUuZ2V0VGltZSgpKTsKKyAgICAgICAgdGhlVGltZXN0YW1wLnNldE5hbm9zKHRoZU5hbm9zKTsKKworICAgICAgICByZXR1cm4gdGhlVGltZXN0YW1wOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBiYWRUaW1lc3RhbXBTdHJpbmcoU3RyaW5nIHMpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVGltZXN0YW1wIGZvcm1hdCBtdXN0IGJlICIgKworICAgICAgICAgICAgICAgICJ5eXl5LU1NLWRkIEhIOm1tOnNzLmZmZmZmZmZmZjsgd2FzICciICsgcyArICInIik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1R5cGVzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvVHlwZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNTNmZTY3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvc3FsL1R5cGVzLmphdmEKQEAgLTAsMCArMSwyMTQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCisvKioKKyAqIEEgY2xhc3Mgd2hpY2ggZGVmaW5lcyBjb25zdGFudHMgdXNlZCB0byBpZGVudGlmeSBnZW5lcmljIFNRTCB0eXBlcywgYWxzbworICogY2FsbGVkIEpEQkMgdHlwZXMuIFRoZSB0eXBlIGNvbnN0YW50IHZhbHVlcyBhcmUgZXF1aXZhbGVudCB0byB0aG9zZSBkZWZpbmVkCisgKiBieSBYL09QRU4uCisgKi8KK3B1YmxpYyBjbGFzcyBUeXBlcyB7CisKKyAgICAvKgorICAgICAqIFByaXZhdGUgY29uc3RydWN0b3IgdG8gcHJldmVudCBpbnN0YW50aWF0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgVHlwZXMoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgY29kZSB0aGF0IGlkZW50aWZpZXMgdGhlIFNRTCB0eXBlIHtAY29kZSBBUlJBWX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVJSQVkgPSAyMDAzOworCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgY29kZSB0aGF0IGlkZW50aWZpZXMgdGhlIFNRTCB0eXBlIHtAY29kZSBCSUdJTlR9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJR0lOVCA9IC01OworCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgY29kZSB0aGF0IGlkZW50aWZpZXMgdGhlIFNRTCB0eXBlIHtAY29kZSBCSU5BUll9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJTkFSWSA9IC0yOworCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgY29kZSB0aGF0IGlkZW50aWZpZXMgdGhlIFNRTCB0eXBlIHtAY29kZSBCSVR9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVCA9IC03OworCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgY29kZSB0aGF0IGlkZW50aWZpZXMgdGhlIFNRTCB0eXBlIHtAY29kZSBCTE9CfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCTE9CID0gMjAwNDsKKworICAgIC8qKgorICAgICAqIFRoZSB0eXBlIGNvZGUgdGhhdCBpZGVudGlmaWVzIHRoZSBTUUwgdHlwZSB7QGNvZGUgQk9PTEVBTn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQk9PTEVBTiA9IDE2OworCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgY29kZSB0aGF0IGlkZW50aWZpZXMgdGhlIFNRTCB0eXBlIHtAY29kZSBDSEFSfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDSEFSID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSB0eXBlIGNvZGUgdGhhdCBpZGVudGlmaWVzIHRoZSBTUUwgdHlwZSB7QGNvZGUgQ0xPQn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xPQiA9IDIwMDU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHlwZSBjb2RlIHRoYXQgaWRlbnRpZmllcyB0aGUgU1FMIHR5cGUge0Bjb2RlIERBVEFMSU5LfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEQVRBTElOSyA9IDcwOworCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgY29kZSB0aGF0IGlkZW50aWZpZXMgdGhlIFNRTCB0eXBlIHtAY29kZSBEQVRFfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEQVRFID0gOTE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHlwZSBjb2RlIHRoYXQgaWRlbnRpZmllcyB0aGUgU1FMIHR5cGUge0Bjb2RlIERFQ0lNQUx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFQ0lNQUwgPSAzOworCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgY29kZSB0aGF0IGlkZW50aWZpZXMgdGhlIFNRTCB0eXBlIHtAY29kZSBESVNUSU5DVH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRElTVElOQ1QgPSAyMDAxOworCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgY29kZSB0aGF0IGlkZW50aWZpZXMgdGhlIFNRTCB0eXBlIHtAY29kZSBET1VCTEV9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERPVUJMRSA9IDg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHlwZSBjb2RlIHRoYXQgaWRlbnRpZmllcyB0aGUgU1FMIHR5cGUge0Bjb2RlIEZMT0FUfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGTE9BVCA9IDY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHlwZSBjb2RlIHRoYXQgaWRlbnRpZmllcyB0aGUgU1FMIHR5cGUge0Bjb2RlIElOVEVHRVJ9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVEVHRVIgPSA0OworCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgY29kZSB0aGF0IGlkZW50aWZpZXMgdGhlIFNRTCB0eXBlIHtAY29kZSBKQVZBX09CSkVDVH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSkFWQV9PQkpFQ1QgPSAyMDAwOworCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgY29kZSB0aGF0IGlkZW50aWZpZXMgdGhlIFNRTCB0eXBlIHtAY29kZSBMT05HVkFSQklOQVJZfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HVkFSQklOQVJZID0gLTQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHlwZSBjb2RlIHRoYXQgaWRlbnRpZmllcyB0aGUgU1FMIHR5cGUge0Bjb2RlIExPTkdWQVJDSEFSfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HVkFSQ0hBUiA9IC0xOworCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgY29kZSB0aGF0IGlkZW50aWZpZXMgdGhlIFNRTCB0eXBlIHtAY29kZSBOVUxMfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOVUxMID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSB0eXBlIGNvZGUgdGhhdCBpZGVudGlmaWVzIHRoZSBTUUwgdHlwZSB7QGNvZGUgTlVNRVJJQ30uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTlVNRVJJQyA9IDI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHlwZSBjb2RlIHRoYXQgaWRlbnRpZmllcyB0aGF0IHRoZSBTUUwgdHlwZSBpcyBkYXRhYmFzZSBzcGVjaWZpYyBhbmQKKyAgICAgKiBpcyBtYXBwZWQgdG8gYSBKYXZhIG9iamVjdCwgYWNjZXNzZWQgdmlhIHRoZSBtZXRob2RzCisgICAgICoge0Bjb2RlIGdldE9iamVjdH0gYW5kIHtAY29kZSBzZXRPYmplY3R9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9USEVSID0gMTExMTsKKworICAgIC8qKgorICAgICAqIFRoZSB0eXBlIGNvZGUgdGhhdCBpZGVudGlmaWVzIHRoZSBTUUwgdHlwZSB7QGNvZGUgUkVBTH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVBTCA9IDc7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHlwZSBjb2RlIHRoYXQgaWRlbnRpZmllcyB0aGUgU1FMIHR5cGUge0Bjb2RlIFJFRn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVGID0gMjAwNjsKKworICAgIC8qKgorICAgICAqIFRoZSB0eXBlIGNvZGUgdGhhdCBpZGVudGlmaWVzIHRoZSBTUUwgdHlwZSB7QGNvZGUgU01BTExJTlR9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNNQUxMSU5UID0gNTsKKworICAgIC8qKgorICAgICAqIFRoZSB0eXBlIGNvZGUgdGhhdCBpZGVudGlmaWVzIHRoZSBTUUwgdHlwZSB7QGNvZGUgU1RSVUNUfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJVQ1QgPSAyMDAyOworCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgY29kZSB0aGF0IGlkZW50aWZpZXMgdGhlIFNRTCB0eXBlIHtAY29kZSBUSU1FfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUSU1FID0gOTI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHlwZSBjb2RlIHRoYXQgaWRlbnRpZmllcyB0aGUgU1FMIHR5cGUge0Bjb2RlIFRJTUVTVEFNUH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVElNRVNUQU1QID0gOTM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHlwZSBjb2RlIHRoYXQgaWRlbnRpZmllcyB0aGUgU1FMIHR5cGUge0Bjb2RlIFRJTllJTlR9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRJTllJTlQgPSAtNjsKKworICAgIC8qKgorICAgICAqIFRoZSB0eXBlIGNvZGUgdGhhdCBpZGVudGlmaWVzIHRoZSBTUUwgdHlwZSB7QGNvZGUgVkFSQklOQVJZfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQVJCSU5BUlkgPSAtMzsKKworICAgIC8qKgorICAgICAqIFRoZSB0eXBlIGNvZGUgdGhhdCBpZGVudGlmaWVzIHRoZSBTUUwgdHlwZSB7QGNvZGUgVkFSQ0hBUn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkFSQ0hBUiA9IDEyOworCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgY29kZSB0aGF0IGlkZW50aWZpZXMgdGhlIFNRTCB0eXBlIFJPV0lELgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJPV0lEID0gLTg7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHlwZSBjb2RlIHRoYXQgaWRlbnRpZmllcyB0aGUgU1FMIHR5cGUgTkNIQVIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkNIQVIgPSAtMTU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHlwZSBjb2RlIHRoYXQgaWRlbnRpZmllcyB0aGUgU1FMIHR5cGUgTlZBUkNIQVIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTlZBUkNIQVIgPSAtOTsKKworICAgIC8qKgorICAgICAqIFRoZSB0eXBlIGNvZGUgdGhhdCBpZGVudGlmaWVzIHRoZSBTUUwgdHlwZSBMT05HTlZBUkNIQVIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR05WQVJDSEFSID0gLTE2OworCisgICAgLyoqCisgICAgICogVGhlIHR5cGUgY29kZSB0aGF0IGlkZW50aWZpZXMgdGhlIFNRTCB0eXBlIE5DTE9CLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5DTE9CID0gMjAxMTsKKworICAgIC8qKgorICAgICAqIFRoZSB0eXBlIGNvZGUgdGhhdCBpZGVudGlmaWVzIHRoZSBTUUwgdHlwZSBTUUxYTUwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1FMWE1MID0gMjAwOTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9XcmFwcGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvV3JhcHBlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEzMDBjNzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvV3JhcHBlci5qYXZhCkBAIC0wLDAgKzEsNTIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEuc3FsOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgYW4gYWN0dWFsIHVzYWdlIG9mIHRoZSB3cmFwcGVyIHBhdHRlcm4gZm9yIEpEQkMgY2xhc3Nlcy4KKyAqIERldmVsb3BlcnMgY2FuIGdldCB0aGUgZGVsZWdhdGUgaW5zdGFuY2Ugd2hlbiB0aGUgaW5zdGFuY2UgbWF5IGJlIGEgcHJveHkKKyAqIGNsYXNzLgorICoKKyAqIEBzaW5jZSAxLjYKKyAqLworcHVibGljIGludGVyZmFjZSBXcmFwcGVyIHsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGUgZ2l2ZW4gaW50ZXJmYWNlLiBJZiB0aGUgY2FsbGVyIGlzCisgICAgICogbm90IGEgd3JhcHBlciwgYSBTUUxFeGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaWZhY2UgLQorICAgICAqICAgICAgICAgICAgdGhlIGNsYXNzIHRoYXQgZGVmaW5lcyB0aGUgaW50ZXJmYWNlCisgICAgICogQHJldHVybiAtIGFuIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlIGludGVyZmFjZQorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIC0KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBubyBvYmplY3QgaW1wbGVtZW50aW5nIHRoZSBzcGVjaWZpYyBpbnRlcmZhY2UKKyAgICAgKi8KKyAgICA8VD4gVCB1bndyYXAoQ2xhc3M8VD4gaWZhY2UpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgY2FsbGVyIGlzIGEgd3JhcHBlciBvZiB0aGUgY2xhc3Mgb3IgaW1wbGVtZW50cyB0aGUgZ2l2ZW4KKyAgICAgKiBpbnRlcmZhY2UsIHRoZSBtZXRob2RzIHJldHVybiBmYWxzZSBhbmQgdmljZSB2ZXJzYS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpZmFjZSAtCisgICAgICogICAgICAgICAgICB0aGUgY2xhc3MgdGhhdCBkZWZpbmVzIHRoZSBpbnRlcmZhY2UKKyAgICAgKiBAcmV0dXJuIC0gdHJ1ZSBpZiB0aGUgaW5zdGFuY2UgaW1wbGVtZW50cyB0aGUgaW50ZXJmYWNlCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gLQorICAgICAqICAgICAgICAgICAgIHdoZW4gYW4gZXJyb3Igb2NjdXJzIHdoZW4ganVkZ2VzIHRoZSBvYmplY3QKKyAgICAgKi8KKyAgICBib29sZWFuIGlzV3JhcHBlckZvcihDbGFzczw/PiBpZmFjZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3NxbC9wYWNrYWdlLmh0bWwgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA3OTliYjcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS9zcWwvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMTAgQEAKKzxodG1sPgorPGJvZHk+Cis8cD5Qcm92aWRlcyBhIGNvbXBhdGliaWxpdHkgaW50ZXJmYWNlIGZvciBhY2Nlc3NpbmcgU1FMLWJhc2VkIGRhdGFiYXNlcy4KK1RoZSA8Y29kZT5hbmRyb2lkLmRhdGFiYXNlPC9jb2RlPiBhbmQgPGNvZGU+YW5kcm9pZC5kYXRhYmFzZS5zcWxpdGU8L2NvZGU+CitwYWNrYWdlcyBvZmZlciBhIGhpZ2hlci1wZXJmb3JtYW5jZSBhbHRlcm5hdGl2ZSB3aGVyZSBzb3VyY2UgY29tcGF0aWJpbGl0eQoraXMgbm90IGFuIGlzc3VlLjwvcD4KKworPHA+Tm90ZSB0aGF0IHlvdSBtdXN0IHByb3ZpZGUgeW91ciBvd24gSkRCQyBkcml2ZXIuPC9wPgorPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9Bbm5vdGF0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0Fubm90YXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MGU5NWZhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9Bbm5vdGF0aW9uLmphdmEKQEAgLTAsMCArMSw2OSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS50ZXh0OworCisvKioKKyAqIFdyYXBwZXIgZm9yIGEgdGV4dCBhdHRyaWJ1dGUgdmFsdWUgd2hpY2ggcmVwcmVzZW50cyBhbiBhbm5vdGF0aW9uLiBBbgorICogYW5ub3RhdGlvbiBoYXMgdHdvIHNwZWNpYWwgYXNwZWN0czoKKyAqIDxvbD4KKyAqIDxsaT5pdCBpcyBjb25uZWN0ZWQgdG8gYSByYW5nZSBvZiBtYWluIHRleHQ7IGlmIHRoaXMgcmFuZ2Ugb3IgdGhlIG1haW4gdGV4dAorICogaXMgY2hhbmdlZCB0aGVuIHRoZSBhbm5vdGF0aW9uIGJlY29tZXMgaW52YWxpZCw8L2xpPgorICogPGxpPml0IGNhbiBub3QgYmUgam9pbmVkIHdpdGggYWRqYWNlbnQgYW5ub3RhdGlvbnMgZXZlbiBpZiB0aGUgdGV4dCBhdHRyaWJ1dGUKKyAqIHZhbHVlIGlzIHRoZSBzYW1lLjwvbGk+CisgKiA8L29sPgorICogPHA+CisgKiBCeSB3cmFwcGluZyB0ZXh0IGF0dHJpYnV0ZSB2YWx1ZXMgaW50byBhbiB7QGNvZGUgQW5ub3RhdGlvbn0sIHRoZXNlIGFzcGVjdHMKKyAqIHdpbGwgYmUgdGFrZW4gaW50byBhY2NvdW50IHdoZW4gaGFuZGxpbmcgYW5ub3RhdGlvbiB0ZXh0IGFuZCB0aGUKKyAqIGNvcnJlc3BvbmRpbmcgbWFpbiB0ZXh0LgorICogPHA+CisgKiBOb3RlOiBUaGVyZSBpcyBubyBzZW1hbnRpYyBjb25uZWN0aW9uIGJldHdlZW4gdGhpcyBhbm5vdGF0aW9uIGNsYXNzIGFuZCB0aGUKKyAqIHtAY29kZSBqYXZhLmxhbmcuYW5ub3RhdGlvbn0gcGFja2FnZS4KKyAqLworcHVibGljIGNsYXNzIEFubm90YXRpb24geworCisgICAgcHJpdmF0ZSBPYmplY3QgdmFsdWU7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBBbm5vdGF0aW9ufS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhdHRyaWJ1dGUgdGhlIGF0dHJpYnV0ZSBhdHRhY2hlZCB0byB0aGlzIGFubm90YXRpb24uIFRoaXMgbWF5IGJlCisgICAgICogICAgICAgIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQW5ub3RhdGlvbihPYmplY3QgYXR0cmlidXRlKSB7CisgICAgICAgIHZhbHVlID0gYXR0cmlidXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoaXMgYW5ub3RhdGlvbi4gVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGlzIGFubm90YXRpb24gb3Ige0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0VmFsdWUoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgYW5ub3RhdGlvbiBpbiBzdHJpbmcgcmVwcmVzZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBhbm5vdGF0aW9uLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBnZXRDbGFzcygpLmdldE5hbWUoKSArICJbdmFsdWU9IiArIHZhbHVlICsgJ10nOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0F0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJhYjhlNmEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0F0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5qYXZhCkBAIC0wLDAgKzEsMjM5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLmlvLkludmFsaWRPYmplY3RFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuRmllbGQ7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXI7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCisvKioKKyAqIEV4dGVuZHMgdGhlCisgKiB7QGxpbmsgQ2hhcmFjdGVySXRlcmF0b3J9IGludGVyZmFjZSwgYWRkaW5nIHN1cHBvcnQgZm9yIGl0ZXJhdGluZyBvdmVyCisgKiBhdHRyaWJ1dGVzIGFuZCBub3Qgb25seSBjaGFyYWN0ZXJzLiBBbgorICoge0Bjb2RlIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcn0gYWxzbyBhbGxvd3MgdGhlIHVzZXIgdG8gZmluZCBydW5zIGFuZAorICogdGhlaXIgbGltaXRzLiBSdW5zIGFyZSBkZWZpbmVkIGFzIHJhbmdlcyBvZiBjaGFyYWN0ZXJzIHRoYXQgYWxsIGhhdmUgdGhlIHNhbWUKKyAqIGF0dHJpYnV0ZXMgd2l0aCB0aGUgc2FtZSB2YWx1ZXMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGV4dGVuZHMgQ2hhcmFjdGVySXRlcmF0b3IgeworCisgICAgLyoqCisgICAgICogRGVmaW5lcyBrZXlzIGZvciB0ZXh0IGF0dHJpYnV0ZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBBdHRyaWJ1dGUgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC05MTQyNzQyNDgzNTEzOTYwNjEyTDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhpcyBhdHRyaWJ1dGUgbWFya3Mgc2VnbWVudHMgZnJvbSBhbiBpbnB1dCBtZXRob2QuIE1vc3QgaW5wdXQKKyAgICAgICAgICogbWV0aG9kcyBjcmVhdGUgdGhlc2Ugc2VnbWVudHMgZm9yIHdvcmRzLgorICAgICAgICAgKgorICAgICAgICAgKiBUaGUgdmFsdWUgb2JqZWN0cyBhcmUgb2YgdGhlIHR5cGUge0Bjb2RlIEFubm90YXRpb259IHdoaWNoIGNvbnRhaW4KKyAgICAgICAgICoge0Bjb2RlIG51bGx9LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBdHRyaWJ1dGUgSU5QVVRfTUVUSE9EX1NFR01FTlQgPSBuZXcgQXR0cmlidXRlKCJpbnB1dF9tZXRob2Rfc2VnbWVudCIpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgYXR0cmlidXRlIGRlc2NyaWJpbmcgdGhlIGxhbmd1YWdlIG9mIGEgY2hhcmFjdGVyLiBUaGUgdmFsdWUKKyAgICAgICAgICogb2JqZWN0cyBhcmUgb2YgdHlwZSB7QGNvZGUgTG9jYWxlfSBvciBhIHN1YnR5cGUgb2YgaXQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEF0dHJpYnV0ZSBMQU5HVUFHRSA9IG5ldyBBdHRyaWJ1dGUoImxhbmd1YWdlIik7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEZvciBsYW5ndWFnZXMgdGhhdCBoYXZlIGRpZmZlcmVudCByZWFkaW5nIGRpcmVjdGlvbnMgb2YgdGV4dCAobGlrZQorICAgICAgICAgKiBKYXBhbmVzZSksIHRoaXMgYXR0cmlidXRlIGFsbG93cyB0byBkZWZpbmUgd2hpY2ggcmVhZGluZyBzaG91bGQgYmUKKyAgICAgICAgICogdXNlZC4gVGhlIHZhbHVlIG9iamVjdHMgYXJlIG9mIHR5cGUge0Bjb2RlIEFubm90YXRpb259IHdoaWNoCisgICAgICAgICAqIGNvbnRhaW4gYSB7QGNvZGUgU3RyaW5nfS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQXR0cmlidXRlIFJFQURJTkcgPSBuZXcgQXR0cmlidXRlKCJyZWFkaW5nIik7CisKKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgbmFtZTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGNvbnN0cnVjdG9yIGZvciBhbiB7QGNvZGUgQXR0cmlidXRlfSB3aXRoIHRoZSBuYW1lIHBhc3NlZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG5hbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgbmV3IHtAY29kZSBBdHRyaWJ1dGV9LgorICAgICAgICAgKi8KKyAgICAgICAgcHJvdGVjdGVkIEF0dHJpYnV0ZShTdHJpbmcgbmFtZSkgeworICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb21wYXJlcyB0aGlzIGF0dHJpYnV0ZSB3aXRoIHRoZSBzcGVjaWZpZWQgb2JqZWN0LiBDaGVja3MgaWYgYm90aAorICAgICAgICAgKiBvYmplY3RzIGFyZSB0aGUgc2FtZSBpbnN0YW5jZS4gSXQgaXMgZGVmaW5lZCBmaW5hbCBzbyBhbGwgc3ViY2xhc3NlcworICAgICAgICAgKiBoYXZlIHRoZSBzYW1lIGJlaGF2aW9yIGZvciB0aGlzIG1ldGhvZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG9iamVjdAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSBhZ2FpbnN0LgorICAgICAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgb2JqZWN0IHBhc3NlZCBpcyBlcXVhbCB0byB0aGlzIGluc3RhbmNlOworICAgICAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gdGhpcyA9PSBvYmplY3Q7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGlzIGF0dHJpYnV0ZS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGlzIGF0dHJpYnV0ZS4KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBuYW1lOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENhbGN1bGF0ZXMgdGhlIGhhc2ggY29kZSBmb3Igb2JqZWN0cyBvZiB0eXBlIHtAY29kZSBBdHRyaWJ1dGV9LiBJdAorICAgICAgICAgKiBpcyBkZWZpbmVkIGZpbmFsIHNvIGFsbCBzdWIgdHlwZXMgY2FsY3VsYXRlIHRoZWlyIGhhc2ggY29kZQorICAgICAgICAgKiBpZGVudGljYWxseS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIGZvciB0aGlzIGluc3RhbmNlIG9mIHtAY29kZSBBdHRyaWJ1dGV9LgorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBmaW5hbCBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuaGFzaENvZGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXNvbHZlcyBhIGRlc2VyaWFsaXplZCBpbnN0YW5jZSB0byB0aGUgY29ycmVjdCBjb25zdGFudCBhdHRyaWJ1dGUuCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBBdHRyaWJ1dGV9IHRoaXMgaW5zdGFuY2UgcmVwcmVzZW50cy4KKyAgICAgICAgICogQHRocm93cyBJbnZhbGlkT2JqZWN0RXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgaW5zdGFuY2UgaXMgbm90IG9mIHR5cGUge0Bjb2RlIEF0dHJpYnV0ZS5jbGFzc30KKyAgICAgICAgICogICAgICAgICAgICAgb3IgaWYgaXQgaXMgbm90IGEga25vd24ge0Bjb2RlIEF0dHJpYnV0ZX0uCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgT2JqZWN0IHJlYWRSZXNvbHZlKCkgdGhyb3dzIEludmFsaWRPYmplY3RFeGNlcHRpb24geworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFRoaXMgY2xhc3MgaXMgdXNlZCBsaWtlIEphdmEgZW51bXMsIHdoZXJlIGFsbCBpbnN0YW5jZXMgYXJlCisgICAgICAgICAgICAgKiBkZWZpbmVkIGFzIGZpZWxkcyBvZiB0aGVpciBvd24gY2xhc3MuIFRvIHByZXNlcnZlIGlkZW50aXR5CisgICAgICAgICAgICAgKiBlcXVhbGl0eSwgcmVzb2x2ZSB0byB0aGUgY2Fub25pY2FsIGluc3RhbmNlIHdoZW4gZGVzZXJpYWxpemVkLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZvciAoRmllbGQgZmllbGQgOiBnZXRDbGFzcygpLmdldEZpZWxkcygpKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZC5nZXRUeXBlKCkgPT0gZ2V0Q2xhc3MoKSAmJiBNb2RpZmllci5pc1N0YXRpYyhmaWVsZC5nZXRNb2RpZmllcnMoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZSBjYW5kaWRhdGUgPSAoQXR0cmlidXRlKSBmaWVsZC5nZXQobnVsbCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmFtZS5lcXVhbHMoY2FuZGlkYXRlLm5hbWUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhbmRpZGF0ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPYmplY3RFeGNlcHRpb24oIkZhaWxlZCB0byByZXNvbHZlICIgKyB0aGlzKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyBmb2xsb3dlZCBieSBhICIoIiwgdGhlIG5hbWUgb2YgdGhlCisgICAgICAgICAqIGF0dHJpYnV0ZSwgYW5kIGEgIikiLgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoaXMgaW5zdGFuY2UuCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRDbGFzcygpLmdldE5hbWUoKSArICcoJyArIGdldE5hbWUoKSArICcpJzsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzZXQgb2YgYXR0cmlidXRlcyBwcmVzZW50IGluIHRoZSB7QGNvZGUKKyAgICAgKiBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3J9LiBBbiBlbXB0eSBzZXQgaXMgcmV0dXJuZWQgaWYgbm8gYXR0cmlidXRlcworICAgICAqIHdlcmUgZGVmaW5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzZXQgb2YgYXR0cmlidXRlIGtleXM7IG1heSBiZSBlbXB0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2V0PEF0dHJpYnV0ZT4gZ2V0QWxsQXR0cmlidXRlS2V5cygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgc3RvcmVkIGluIHRoZSBhdHRyaWJ1dGUgZm9yIHRoZSBjdXJyZW50IGNoYXJhY3Rlci4gSWYKKyAgICAgKiB0aGUgYXR0cmlidXRlIHdhcyBub3QgZGVmaW5lZCB0aGVuIHtAY29kZSBudWxsfSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhdHRyaWJ1dGUgdGhlIGF0dHJpYnV0ZSBmb3Igd2hpY2ggdGhlIHZhbHVlIHNob3VsZCBiZSByZXR1cm5lZC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgcmVxdWVzdGVkIGF0dHJpYnV0ZSBmb3IgdGhlIGN1cnJlbnQgY2hhcmFjdGVyIG9yCisgICAgICogICAgICAgICB7QGNvZGUgbnVsbH0gaWYgaXQgd2FzIG5vdCBkZWZpbmVkLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0QXR0cmlidXRlKEF0dHJpYnV0ZSBhdHRyaWJ1dGUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG1hcCBvZiBhbGwgYXR0cmlidXRlcyBvZiB0aGUgY3VycmVudCBjaGFyYWN0ZXIuIElmIG5vCisgICAgICogYXR0cmlidXRlcyB3ZXJlIGRlZmluZWQgZm9yIHRoZSBjdXJyZW50IGNoYXJhY3RlciB0aGVuIGFuIGVtcHR5IG1hcCBpcworICAgICAqIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiBhIG1hcCBvZiBhbGwgYXR0cmlidXRlcyBmb3IgdGhlIGN1cnJlbnQgY2hhcmFjdGVyIG9yIGFuIGVtcHR5CisgICAgICogICAgICAgICBtYXAuCisgICAgICovCisgICAgcHVibGljIE1hcDxBdHRyaWJ1dGUsIE9iamVjdD4gZ2V0QXR0cmlidXRlcygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGxhc3QgY2hhcmFjdGVyIGluIHRoZSBydW4gaGF2aW5nIHRoZSBzYW1lCisgICAgICogYXR0cmlidXRlcyBhcyB0aGUgY3VycmVudCBjaGFyYWN0ZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBjaGFyYWN0ZXIgb2YgdGhlIGN1cnJlbnQgcnVuLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UnVuTGltaXQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBsYXN0IGNoYXJhY3RlciBpbiB0aGUgcnVuIHRoYXQgaGFzIHRoZSBzYW1lCisgICAgICogYXR0cmlidXRlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gYXR0cmlidXRlIGFzIHRoZSBjdXJyZW50IGNoYXJhY3Rlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhdHRyaWJ1dGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBhdHRyaWJ1dGUgd2hpY2ggdGhlIHJ1biBpcyBiYXNlZCBvbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBjaGFyYWN0ZXIgb2YgdGhlIGN1cnJlbnQgcnVuLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UnVuTGltaXQoQXR0cmlidXRlIGF0dHJpYnV0ZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBjaGFyYWN0ZXIgaW4gdGhlIHJ1biB0aGF0IGhhcyB0aGUgc2FtZQorICAgICAqIGF0dHJpYnV0ZSB2YWx1ZXMgZm9yIHRoZSBhdHRyaWJ1dGVzIGluIHRoZSBzZXQgYXMgdGhlIGN1cnJlbnQgY2hhcmFjdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZXQgb2YgYXR0cmlidXRlcyB3aGljaCB0aGUgcnVuIGlzIGJhc2VkIG9uLgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBsYXN0IGNoYXJhY3RlciBvZiB0aGUgY3VycmVudCBydW4uCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSdW5MaW1pdChTZXQ8PyBleHRlbmRzIEF0dHJpYnV0ZT4gYXR0cmlidXRlcyk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSBydW4gdGhhdCBoYXMgdGhlIHNhbWUKKyAgICAgKiBhdHRyaWJ1dGVzIGFzIHRoZSBjdXJyZW50IGNoYXJhY3Rlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBsYXN0IGNoYXJhY3RlciBvZiB0aGUgY3VycmVudCBydW4uCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSdW5TdGFydCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgcnVuIHRoYXQgaGFzIHRoZSBzYW1lCisgICAgICogYXR0cmlidXRlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gYXR0cmlidXRlIGFzIHRoZSBjdXJyZW50IGNoYXJhY3Rlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhdHRyaWJ1dGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBhdHRyaWJ1dGUgd2hpY2ggdGhlIHJ1biBpcyBiYXNlZCBvbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBjaGFyYWN0ZXIgb2YgdGhlIGN1cnJlbnQgcnVuLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UnVuU3RhcnQoQXR0cmlidXRlIGF0dHJpYnV0ZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSBydW4gdGhhdCBoYXMgdGhlIHNhbWUKKyAgICAgKiBhdHRyaWJ1dGUgdmFsdWVzIGZvciB0aGUgYXR0cmlidXRlcyBpbiB0aGUgc2V0IGFzIHRoZSBjdXJyZW50IGNoYXJhY3Rlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzCisgICAgICogICAgICAgICAgICB0aGUgc2V0IG9mIGF0dHJpYnV0ZXMgd2hpY2ggdGhlIHJ1biBpcyBiYXNlZCBvbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBjaGFyYWN0ZXIgb2YgdGhlIGN1cnJlbnQgcnVuLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UnVuU3RhcnQoU2V0PD8gZXh0ZW5kcyBBdHRyaWJ1dGU+IGF0dHJpYnV0ZXMpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9BdHRyaWJ1dGVkU3RyaW5nLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0F0dHJpYnV0ZWRTdHJpbmcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMzM1MDY3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9BdHRyaWJ1dGVkU3RyaW5nLmphdmEKQEAgLTAsMCArMSw3NjQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQKKyAqIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZQorICogTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKKyAqIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS50ZXh0OworCitpbXBvcnQgamF2YS50ZXh0LkF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdEl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworLyoqCisgKiBIb2xkcyBhIHN0cmluZyB3aXRoIGF0dHJpYnV0ZXMgZGVzY3JpYmluZyB0aGUgY2hhcmFjdGVycyBvZgorICogdGhpcyBzdHJpbmcuCisgKi8KK3B1YmxpYyBjbGFzcyBBdHRyaWJ1dGVkU3RyaW5nIHsKKworICAgIFN0cmluZyB0ZXh0OworCisgICAgTWFwPEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUsIExpc3Q8UmFuZ2U+PiBhdHRyaWJ1dGVNYXA7CisKKyAgICBzdGF0aWMgY2xhc3MgUmFuZ2UgeworICAgICAgICBpbnQgc3RhcnQ7CisKKyAgICAgICAgaW50IGVuZDsKKworICAgICAgICBPYmplY3QgdmFsdWU7CisKKyAgICAgICAgUmFuZ2UoaW50IHMsIGludCBlLCBPYmplY3QgdikgeworICAgICAgICAgICAgc3RhcnQgPSBzOworICAgICAgICAgICAgZW5kID0gZTsKKyAgICAgICAgICAgIHZhbHVlID0gdjsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBBdHRyaWJ1dGVkSXRlcmF0b3IgaW1wbGVtZW50cyBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgeworCisgICAgICAgIHByaXZhdGUgaW50IGJlZ2luLCBlbmQsIG9mZnNldDsKKworICAgICAgICBwcml2YXRlIEF0dHJpYnV0ZWRTdHJpbmcgYXR0clN0cmluZzsKKworICAgICAgICBwcml2YXRlIEhhc2hTZXQ8QXR0cmlidXRlPiBhdHRyaWJ1dGVzQWxsb3dlZDsKKworICAgICAgICBBdHRyaWJ1dGVkSXRlcmF0b3IoQXR0cmlidXRlZFN0cmluZyBhdHRyU3RyaW5nKSB7CisgICAgICAgICAgICB0aGlzLmF0dHJTdHJpbmcgPSBhdHRyU3RyaW5nOworICAgICAgICAgICAgYmVnaW4gPSAwOworICAgICAgICAgICAgZW5kID0gYXR0clN0cmluZy50ZXh0Lmxlbmd0aCgpOworICAgICAgICAgICAgb2Zmc2V0ID0gMDsKKyAgICAgICAgfQorCisgICAgICAgIEF0dHJpYnV0ZWRJdGVyYXRvcihBdHRyaWJ1dGVkU3RyaW5nIGF0dHJTdHJpbmcsCisgICAgICAgICAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZVtdIGF0dHJpYnV0ZXMsIGludCBiZWdpbiwKKyAgICAgICAgICAgICAgICBpbnQgZW5kKSB7CisgICAgICAgICAgICBpZiAoYmVnaW4gPCAwIHx8IGVuZCA+IGF0dHJTdHJpbmcudGV4dC5sZW5ndGgoKSB8fCBiZWdpbiA+IGVuZCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMuYmVnaW4gPSBiZWdpbjsKKyAgICAgICAgICAgIHRoaXMuZW5kID0gZW5kOworICAgICAgICAgICAgb2Zmc2V0ID0gYmVnaW47CisgICAgICAgICAgICB0aGlzLmF0dHJTdHJpbmcgPSBhdHRyU3RyaW5nOworICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIEhhc2hTZXQ8QXR0cmlidXRlPiBzZXQgPSBuZXcgSGFzaFNldDxBdHRyaWJ1dGU+KAorICAgICAgICAgICAgICAgICAgICAgICAgKGF0dHJpYnV0ZXMubGVuZ3RoICogNCAvIDMpICsgMSk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGF0dHJpYnV0ZXMubGVuZ3RoOyAtLWkgPj0gMDspIHsKKyAgICAgICAgICAgICAgICAgICAgc2V0LmFkZChhdHRyaWJ1dGVzW2ldKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXR0cmlidXRlc0FsbG93ZWQgPSBzZXQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQXR0cmlidXRlZEl0ZXJhdG9yfSB3aXRoIHRoZSBzYW1lIHNvdXJjZSBzdHJpbmcsCisgICAgICAgICAqIGJlZ2luLCBlbmQsIGFuZCBjdXJyZW50IGluZGV4IGFzIHRoaXMgYXR0cmlidXRlZCBpdGVyYXRvci4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiBhIHNoYWxsb3cgY29weSBvZiB0aGlzIGF0dHJpYnV0ZWQgaXRlcmF0b3IuCisgICAgICAgICAqIEBzZWUgamF2YS5sYW5nLkNsb25lYWJsZQorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBBdHRyaWJ1dGVkSXRlcmF0b3IgY2xvbmUgPSAoQXR0cmlidXRlZEl0ZXJhdG9yKSBzdXBlci5jbG9uZSgpOworICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzQWxsb3dlZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGNsb25lLmF0dHJpYnV0ZXNBbGxvd2VkID0gKEhhc2hTZXQ8QXR0cmlidXRlPikgYXR0cmlidXRlc0FsbG93ZWQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2xvbmUoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGNsb25lOworICAgICAgICAgICAgfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBjaGFyIGN1cnJlbnQoKSB7CisgICAgICAgICAgICBpZiAob2Zmc2V0ID09IGVuZCkgeworICAgICAgICAgICAgICAgIHJldHVybiBET05FOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGF0dHJTdHJpbmcudGV4dC5jaGFyQXQob2Zmc2V0KTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBjaGFyIGZpcnN0KCkgeworICAgICAgICAgICAgaWYgKGJlZ2luID09IGVuZCkgeworICAgICAgICAgICAgICAgIHJldHVybiBET05FOworICAgICAgICAgICAgfQorICAgICAgICAgICAgb2Zmc2V0ID0gYmVnaW47CisgICAgICAgICAgICByZXR1cm4gYXR0clN0cmluZy50ZXh0LmNoYXJBdChvZmZzZXQpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIGJlZ2luIGluZGV4IGluIHRoZSBzb3VyY2Ugc3RyaW5nLgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIHRvIGl0ZXJhdGUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgaW50IGdldEJlZ2luSW5kZXgoKSB7CisgICAgICAgICAgICByZXR1cm4gYmVnaW47CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgZW5kIGluZGV4IGluIHRoZSBzb3VyY2UgU3RyaW5nLgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvbmUgcGFzdCB0aGUgbGFzdCBjaGFyYWN0ZXIgdG8gaXRlcmF0ZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0RW5kSW5kZXgoKSB7CisgICAgICAgICAgICByZXR1cm4gZW5kOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgaW5kZXggaW4gdGhlIHNvdXJjZSBTdHJpbmcuCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgaW5kZXguCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgaW50IGdldEluZGV4KCkgeworICAgICAgICAgICAgcmV0dXJuIG9mZnNldDsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpblJhbmdlKFJhbmdlIHJhbmdlKSB7CisgICAgICAgICAgICBpZiAoIShyYW5nZS52YWx1ZSBpbnN0YW5jZW9mIEFubm90YXRpb24pKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmFuZ2Uuc3RhcnQgPj0gYmVnaW4gJiYgcmFuZ2Uuc3RhcnQgPCBlbmQKKyAgICAgICAgICAgICAgICAgICAgJiYgcmFuZ2UuZW5kID4gYmVnaW4gJiYgcmFuZ2UuZW5kIDw9IGVuZDsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpblJhbmdlKExpc3Q8UmFuZ2U+IHJhbmdlcykgeworICAgICAgICAgICAgSXRlcmF0b3I8UmFuZ2U+IGl0ID0gcmFuZ2VzLml0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgUmFuZ2UgcmFuZ2UgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgaWYgKHJhbmdlLnN0YXJ0ID49IGJlZ2luICYmIHJhbmdlLnN0YXJ0IDwgZW5kKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAhKHJhbmdlLnZhbHVlIGluc3RhbmNlb2YgQW5ub3RhdGlvbikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAocmFuZ2UuZW5kID4gYmVnaW4gJiYgcmFuZ2UuZW5kIDw9IGVuZCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyYW5nZS5lbmQgPiBiZWdpbiAmJiByYW5nZS5lbmQgPD0gZW5kKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAhKHJhbmdlLnZhbHVlIGluc3RhbmNlb2YgQW5ub3RhdGlvbikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAocmFuZ2Uuc3RhcnQgPj0gYmVnaW4gJiYgcmFuZ2Uuc3RhcnQgPCBlbmQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGEgc2V0IG9mIGF0dHJpYnV0ZXMgcHJlc2VudCBpbiB0aGUge0Bjb2RlIEF0dHJpYnV0ZWRTdHJpbmd9LgorICAgICAgICAgKiBBbiBlbXB0eSBzZXQgcmV0dXJuZWQgaW5kaWNhdGVzIHRoYXQgbm8gYXR0cmlidXRlcyB3aGVyZSBkZWZpbmVkLgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIGEgc2V0IG9mIGF0dHJpYnV0ZSBrZXlzIHRoYXQgbWF5IGJlIGVtcHR5LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFNldDxBdHRyaWJ1dGVkSXRlcmF0b3IuQXR0cmlidXRlPiBnZXRBbGxBdHRyaWJ1dGVLZXlzKCkgeworICAgICAgICAgICAgaWYgKGJlZ2luID09IDAgJiYgZW5kID09IGF0dHJTdHJpbmcudGV4dC5sZW5ndGgoKQorICAgICAgICAgICAgICAgICAgICAmJiBhdHRyaWJ1dGVzQWxsb3dlZCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJTdHJpbmcuYXR0cmlidXRlTWFwLmtleVNldCgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBTZXQ8QXR0cmlidXRlZEl0ZXJhdG9yLkF0dHJpYnV0ZT4gcmVzdWx0ID0gbmV3IEhhc2hTZXQ8QXR0cmlidXRlPigKKyAgICAgICAgICAgICAgICAgICAgKGF0dHJTdHJpbmcuYXR0cmlidXRlTWFwLnNpemUoKSAqIDQgLyAzKSArIDEpOworICAgICAgICAgICAgSXRlcmF0b3I8TWFwLkVudHJ5PEF0dHJpYnV0ZSwgTGlzdDxSYW5nZT4+PiBpdCA9IGF0dHJTdHJpbmcuYXR0cmlidXRlTWFwCisgICAgICAgICAgICAgICAgICAgIC5lbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgTWFwLkVudHJ5PEF0dHJpYnV0ZSwgTGlzdDxSYW5nZT4+IGVudHJ5ID0gaXQubmV4dCgpOworICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzQWxsb3dlZCA9PSBudWxsCisgICAgICAgICAgICAgICAgICAgICAgICB8fCBhdHRyaWJ1dGVzQWxsb3dlZC5jb250YWlucyhlbnRyeS5nZXRLZXkoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgTGlzdDxSYW5nZT4gcmFuZ2VzID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGluUmFuZ2UocmFuZ2VzKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChlbnRyeS5nZXRLZXkoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBPYmplY3QgY3VycmVudFZhbHVlKExpc3Q8UmFuZ2U+IHJhbmdlcykgeworICAgICAgICAgICAgSXRlcmF0b3I8UmFuZ2U+IGl0ID0gcmFuZ2VzLml0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgUmFuZ2UgcmFuZ2UgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgaWYgKG9mZnNldCA+PSByYW5nZS5zdGFydCAmJiBvZmZzZXQgPCByYW5nZS5lbmQpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluUmFuZ2UocmFuZ2UpID8gcmFuZ2UudmFsdWUgOiBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBnZXRBdHRyaWJ1dGUoCisgICAgICAgICAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSBhdHRyaWJ1dGUpIHsKKyAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzQWxsb3dlZCAhPSBudWxsCisgICAgICAgICAgICAgICAgICAgICYmICFhdHRyaWJ1dGVzQWxsb3dlZC5jb250YWlucyhhdHRyaWJ1dGUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBBcnJheUxpc3Q8UmFuZ2U+IHJhbmdlcyA9IChBcnJheUxpc3Q8UmFuZ2U+KSBhdHRyU3RyaW5nLmF0dHJpYnV0ZU1hcAorICAgICAgICAgICAgICAgICAgICAuZ2V0KGF0dHJpYnV0ZSk7CisgICAgICAgICAgICBpZiAocmFuZ2VzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBjdXJyZW50VmFsdWUocmFuZ2VzKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBNYXA8QXR0cmlidXRlLCBPYmplY3Q+IGdldEF0dHJpYnV0ZXMoKSB7CisgICAgICAgICAgICBNYXA8QXR0cmlidXRlLCBPYmplY3Q+IHJlc3VsdCA9IG5ldyBIYXNoTWFwPEF0dHJpYnV0ZSwgT2JqZWN0PigKKyAgICAgICAgICAgICAgICAgICAgKGF0dHJTdHJpbmcuYXR0cmlidXRlTWFwLnNpemUoKSAqIDQgLyAzKSArIDEpOworICAgICAgICAgICAgSXRlcmF0b3I8TWFwLkVudHJ5PEF0dHJpYnV0ZSwgTGlzdDxSYW5nZT4+PiBpdCA9IGF0dHJTdHJpbmcuYXR0cmlidXRlTWFwCisgICAgICAgICAgICAgICAgICAgIC5lbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgTWFwLkVudHJ5PEF0dHJpYnV0ZSwgTGlzdDxSYW5nZT4+IGVudHJ5ID0gaXQubmV4dCgpOworICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzQWxsb3dlZCA9PSBudWxsCisgICAgICAgICAgICAgICAgICAgICAgICB8fCBhdHRyaWJ1dGVzQWxsb3dlZC5jb250YWlucyhlbnRyeS5nZXRLZXkoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gY3VycmVudFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpOworICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1dChlbnRyeS5nZXRLZXkoKSwgdmFsdWUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0UnVuTGltaXQoKSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0UnVuTGltaXQoZ2V0QWxsQXR0cmlidXRlS2V5cygpKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgaW50IHJ1bkxpbWl0KExpc3Q8UmFuZ2U+IHJhbmdlcykgeworICAgICAgICAgICAgaW50IHJlc3VsdCA9IGVuZDsKKyAgICAgICAgICAgIExpc3RJdGVyYXRvcjxSYW5nZT4gaXQgPSByYW5nZXMubGlzdEl0ZXJhdG9yKHJhbmdlcy5zaXplKCkpOworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc1ByZXZpb3VzKCkpIHsKKyAgICAgICAgICAgICAgICBSYW5nZSByYW5nZSA9IGl0LnByZXZpb3VzKCk7CisgICAgICAgICAgICAgICAgaWYgKHJhbmdlLmVuZCA8PSBiZWdpbikgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKG9mZnNldCA+PSByYW5nZS5zdGFydCAmJiBvZmZzZXQgPCByYW5nZS5lbmQpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluUmFuZ2UocmFuZ2UpID8gcmFuZ2UuZW5kIDogcmVzdWx0OworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAob2Zmc2V0ID49IHJhbmdlLmVuZCkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmFuZ2Uuc3RhcnQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXRSdW5MaW1pdChBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlIGF0dHJpYnV0ZSkgeworICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZXNBbGxvd2VkICE9IG51bGwKKyAgICAgICAgICAgICAgICAgICAgJiYgIWF0dHJpYnV0ZXNBbGxvd2VkLmNvbnRhaW5zKGF0dHJpYnV0ZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZW5kOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQXJyYXlMaXN0PFJhbmdlPiByYW5nZXMgPSAoQXJyYXlMaXN0PFJhbmdlPikgYXR0clN0cmluZy5hdHRyaWJ1dGVNYXAKKyAgICAgICAgICAgICAgICAgICAgLmdldChhdHRyaWJ1dGUpOworICAgICAgICAgICAgaWYgKHJhbmdlcyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGVuZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBydW5MaW1pdChyYW5nZXMpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXRSdW5MaW1pdChTZXQ8PyBleHRlbmRzIEF0dHJpYnV0ZT4gYXR0cmlidXRlcykgeworICAgICAgICAgICAgaW50IGxpbWl0ID0gZW5kOworICAgICAgICAgICAgSXRlcmF0b3I8PyBleHRlbmRzIEF0dHJpYnV0ZT4gaXQgPSBhdHRyaWJ1dGVzLml0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSBhdHRyaWJ1dGUgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgaW50IG5ld0xpbWl0ID0gZ2V0UnVuTGltaXQoYXR0cmlidXRlKTsKKyAgICAgICAgICAgICAgICBpZiAobmV3TGltaXQgPCBsaW1pdCkgeworICAgICAgICAgICAgICAgICAgICBsaW1pdCA9IG5ld0xpbWl0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBsaW1pdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0UnVuU3RhcnQoKSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0UnVuU3RhcnQoZ2V0QWxsQXR0cmlidXRlS2V5cygpKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgaW50IHJ1blN0YXJ0KExpc3Q8UmFuZ2U+IHJhbmdlcykgeworICAgICAgICAgICAgaW50IHJlc3VsdCA9IGJlZ2luOworICAgICAgICAgICAgSXRlcmF0b3I8UmFuZ2U+IGl0ID0gcmFuZ2VzLml0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgUmFuZ2UgcmFuZ2UgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgaWYgKHJhbmdlLnN0YXJ0ID49IGVuZCkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKG9mZnNldCA+PSByYW5nZS5zdGFydCAmJiBvZmZzZXQgPCByYW5nZS5lbmQpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluUmFuZ2UocmFuZ2UpID8gcmFuZ2Uuc3RhcnQgOiByZXN1bHQ7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvZmZzZXQgPCByYW5nZS5zdGFydCkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmFuZ2UuZW5kOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0UnVuU3RhcnQoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSBhdHRyaWJ1dGUpIHsKKyAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzQWxsb3dlZCAhPSBudWxsCisgICAgICAgICAgICAgICAgICAgICYmICFhdHRyaWJ1dGVzQWxsb3dlZC5jb250YWlucyhhdHRyaWJ1dGUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGJlZ2luOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQXJyYXlMaXN0PFJhbmdlPiByYW5nZXMgPSAoQXJyYXlMaXN0PFJhbmdlPikgYXR0clN0cmluZy5hdHRyaWJ1dGVNYXAKKyAgICAgICAgICAgICAgICAgICAgLmdldChhdHRyaWJ1dGUpOworICAgICAgICAgICAgaWYgKHJhbmdlcyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGJlZ2luOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJ1blN0YXJ0KHJhbmdlcyk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldFJ1blN0YXJ0KFNldDw/IGV4dGVuZHMgQXR0cmlidXRlPiBhdHRyaWJ1dGVzKSB7CisgICAgICAgICAgICBpbnQgc3RhcnQgPSBiZWdpbjsKKyAgICAgICAgICAgIEl0ZXJhdG9yPD8gZXh0ZW5kcyBBdHRyaWJ1dGU+IGl0ID0gYXR0cmlidXRlcy5pdGVyYXRvcigpOworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUgYXR0cmlidXRlID0gaXQubmV4dCgpOworICAgICAgICAgICAgICAgIGludCBuZXdTdGFydCA9IGdldFJ1blN0YXJ0KGF0dHJpYnV0ZSk7CisgICAgICAgICAgICAgICAgaWYgKG5ld1N0YXJ0ID4gc3RhcnQpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhcnQgPSBuZXdTdGFydDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gc3RhcnQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgY2hhciBsYXN0KCkgeworICAgICAgICAgICAgaWYgKGJlZ2luID09IGVuZCkgeworICAgICAgICAgICAgICAgIHJldHVybiBET05FOworICAgICAgICAgICAgfQorICAgICAgICAgICAgb2Zmc2V0ID0gZW5kIC0gMTsKKyAgICAgICAgICAgIHJldHVybiBhdHRyU3RyaW5nLnRleHQuY2hhckF0KG9mZnNldCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgY2hhciBuZXh0KCkgeworICAgICAgICAgICAgaWYgKG9mZnNldCA+PSAoZW5kIC0gMSkpIHsKKyAgICAgICAgICAgICAgICBvZmZzZXQgPSBlbmQ7CisgICAgICAgICAgICAgICAgcmV0dXJuIERPTkU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gYXR0clN0cmluZy50ZXh0LmNoYXJBdCgrK29mZnNldCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgY2hhciBwcmV2aW91cygpIHsKKyAgICAgICAgICAgIGlmIChvZmZzZXQgPT0gYmVnaW4pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gRE9ORTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBhdHRyU3RyaW5nLnRleHQuY2hhckF0KC0tb2Zmc2V0KTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBjaGFyIHNldEluZGV4KGludCBsb2NhdGlvbikgeworICAgICAgICAgICAgaWYgKGxvY2F0aW9uIDwgYmVnaW4gfHwgbG9jYXRpb24gPiBlbmQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBvZmZzZXQgPSBsb2NhdGlvbjsKKyAgICAgICAgICAgIGlmIChvZmZzZXQgPT0gZW5kKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIERPTkU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gYXR0clN0cmluZy50ZXh0LmNoYXJBdChvZmZzZXQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiB7QGNvZGUgQXR0cmlidXRlZFN0cmluZ30gZnJvbSBhbiB7QGNvZGUKKyAgICAgKiBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3J9LCB3aGljaCByZXByZXNlbnRzIGF0dHJpYnV0ZWQgdGV4dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpdGVyYXRvcgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3J9IHRoYXQgY29udGFpbnMgdGhlIHRleHQKKyAgICAgKiAgICAgICAgICAgIGZvciB0aGlzIGF0dHJpYnV0ZWQgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBBdHRyaWJ1dGVkU3RyaW5nKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBpdGVyYXRvcikgeworICAgICAgICBpZiAoaXRlcmF0b3IuZ2V0QmVnaW5JbmRleCgpID4gaXRlcmF0b3IuZ2V0RW5kSW5kZXgoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBzdWJzdHJpbmcgcmFuZ2UiKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGZvciAoaW50IGkgPSBpdGVyYXRvci5nZXRCZWdpbkluZGV4KCk7IGkgPCBpdGVyYXRvci5nZXRFbmRJbmRleCgpOyBpKyspIHsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoaXRlcmF0b3IuY3VycmVudCgpKTsKKyAgICAgICAgICAgIGl0ZXJhdG9yLm5leHQoKTsKKyAgICAgICAgfQorICAgICAgICB0ZXh0ID0gYnVmZmVyLnRvU3RyaW5nKCk7CisgICAgICAgIFNldDxBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlPiBhdHRyaWJ1dGVzID0gaXRlcmF0b3IKKyAgICAgICAgICAgICAgICAuZ2V0QWxsQXR0cmlidXRlS2V5cygpOworICAgICAgICBpZiAoYXR0cmlidXRlcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgYXR0cmlidXRlTWFwID0gbmV3IEhhc2hNYXA8QXR0cmlidXRlLCBMaXN0PFJhbmdlPj4oCisgICAgICAgICAgICAgICAgKGF0dHJpYnV0ZXMuc2l6ZSgpICogNCAvIDMpICsgMSk7CisKKyAgICAgICAgSXRlcmF0b3I8QXR0cmlidXRlPiBpdCA9IGF0dHJpYnV0ZXMuaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSBhdHRyaWJ1dGUgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICBpdGVyYXRvci5zZXRJbmRleCgwKTsKKyAgICAgICAgICAgIHdoaWxlIChpdGVyYXRvci5jdXJyZW50KCkgIT0gQ2hhcmFjdGVySXRlcmF0b3IuRE9ORSkgeworICAgICAgICAgICAgICAgIGludCBzdGFydCA9IGl0ZXJhdG9yLmdldFJ1blN0YXJ0KGF0dHJpYnV0ZSk7CisgICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaXRlcmF0b3IuZ2V0UnVuTGltaXQoYXR0cmlidXRlKTsKKyAgICAgICAgICAgICAgICBPYmplY3QgdmFsdWUgPSBpdGVyYXRvci5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlKTsKKyAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBhZGRBdHRyaWJ1dGUoYXR0cmlidXRlLCB2YWx1ZSwgc3RhcnQsIGxpbWl0KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaXRlcmF0b3Iuc2V0SW5kZXgobGltaXQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBBdHRyaWJ1dGVkU3RyaW5nKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBpdGVyYXRvciwgaW50IHN0YXJ0LAorICAgICAgICAgICAgaW50IGVuZCwgU2V0PEF0dHJpYnV0ZT4gYXR0cmlidXRlcykgeworICAgICAgICBpZiAoc3RhcnQgPCBpdGVyYXRvci5nZXRCZWdpbkluZGV4KCkgfHwgZW5kID4gaXRlcmF0b3IuZ2V0RW5kSW5kZXgoKQorICAgICAgICAgICAgICAgIHx8IHN0YXJ0ID4gZW5kKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoYXR0cmlidXRlcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGl0ZXJhdG9yLnNldEluZGV4KHN0YXJ0KTsKKyAgICAgICAgd2hpbGUgKGl0ZXJhdG9yLmdldEluZGV4KCkgPCBlbmQpIHsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoaXRlcmF0b3IuY3VycmVudCgpKTsKKyAgICAgICAgICAgIGl0ZXJhdG9yLm5leHQoKTsKKyAgICAgICAgfQorICAgICAgICB0ZXh0ID0gYnVmZmVyLnRvU3RyaW5nKCk7CisgICAgICAgIGF0dHJpYnV0ZU1hcCA9IG5ldyBIYXNoTWFwPEF0dHJpYnV0ZSwgTGlzdDxSYW5nZT4+KAorICAgICAgICAgICAgICAgIChhdHRyaWJ1dGVzLnNpemUoKSAqIDQgLyAzKSArIDEpOworCisgICAgICAgIEl0ZXJhdG9yPEF0dHJpYnV0ZT4gaXQgPSBhdHRyaWJ1dGVzLml0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUgYXR0cmlidXRlID0gaXQubmV4dCgpOworICAgICAgICAgICAgaXRlcmF0b3Iuc2V0SW5kZXgoc3RhcnQpOworICAgICAgICAgICAgd2hpbGUgKGl0ZXJhdG9yLmdldEluZGV4KCkgPCBlbmQpIHsKKyAgICAgICAgICAgICAgICBPYmplY3QgdmFsdWUgPSBpdGVyYXRvci5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlKTsKKyAgICAgICAgICAgICAgICBpbnQgcnVuU3RhcnQgPSBpdGVyYXRvci5nZXRSdW5TdGFydChhdHRyaWJ1dGUpOworICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGl0ZXJhdG9yLmdldFJ1bkxpbWl0KGF0dHJpYnV0ZSk7CisgICAgICAgICAgICAgICAgaWYgKCh2YWx1ZSBpbnN0YW5jZW9mIEFubm90YXRpb24gJiYgcnVuU3RhcnQgPj0gc3RhcnQgJiYgbGltaXQgPD0gZW5kKQorICAgICAgICAgICAgICAgICAgICAgICAgfHwgKHZhbHVlICE9IG51bGwgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIEFubm90YXRpb24pKSkgeworICAgICAgICAgICAgICAgICAgICBhZGRBdHRyaWJ1dGUoYXR0cmlidXRlLCB2YWx1ZSwgKHJ1blN0YXJ0IDwgc3RhcnQgPyBzdGFydAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogcnVuU3RhcnQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBzdGFydCwgKGxpbWl0ID4gZW5kID8gZW5kIDogbGltaXQpIC0gc3RhcnQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpdGVyYXRvci5zZXRJbmRleChsaW1pdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIHtAY29kZSBBdHRyaWJ1dGVkU3RyaW5nfSBmcm9tIGEgcmFuZ2Ugb2YgdGhlIHRleHQgY29udGFpbmVkCisgICAgICogaW4gdGhlIHNwZWNpZmllZCB7QGNvZGUgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yfSwgc3RhcnRpbmcgYXQge0Bjb2RlCisgICAgICogc3RhcnR9IGFuZCBlbmRpbmcgYXQge0Bjb2RlIGVuZH0uIEFsbCBhdHRyaWJ1dGVzIHdpbGwgYmUgY29waWVkIHRvIHRoaXMKKyAgICAgKiBhdHRyaWJ1dGVkIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpdGVyYXRvcgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3J9IHRoYXQgY29udGFpbnMgdGhlIHRleHQKKyAgICAgKiAgICAgICAgICAgIGZvciB0aGlzIGF0dHJpYnV0ZWQgc3RyaW5nLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IGluZGV4IG9mIHRoZSByYW5nZSBvZiB0aGUgY29waWVkIHRleHQuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGVuZCBpbmRleCBvZiB0aGUgcmFuZ2Ugb2YgdGhlIGNvcGllZCB0ZXh0LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0fSBpcyBsZXNzIHRoYW4gZmlyc3QgaW5kZXggb2YKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgaXRlcmF0b3J9LCB7QGNvZGUgZW5kfSBpcyBncmVhdGVyIHRoYW4gdGhlIGxhc3QKKyAgICAgKiAgICAgICAgICAgICBpbmRleCArIDEgaW4ge0Bjb2RlIGl0ZXJhdG9yfSBvciBpZiB7QGNvZGUgc3RhcnQgPiBlbmR9LgorICAgICAqLworICAgIHB1YmxpYyBBdHRyaWJ1dGVkU3RyaW5nKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBpdGVyYXRvciwgaW50IHN0YXJ0LAorICAgICAgICAgICAgaW50IGVuZCkgeworICAgICAgICB0aGlzKGl0ZXJhdG9yLCBzdGFydCwgZW5kLCBpdGVyYXRvci5nZXRBbGxBdHRyaWJ1dGVLZXlzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4ge0Bjb2RlIEF0dHJpYnV0ZWRTdHJpbmd9IGZyb20gYSByYW5nZSBvZiB0aGUgdGV4dCBjb250YWluZWQKKyAgICAgKiBpbiB0aGUgc3BlY2lmaWVkIHtAY29kZSBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3J9LCBzdGFydGluZyBhdCB7QGNvZGUKKyAgICAgKiBzdGFydH0sIGVuZGluZyBhdCB7QGNvZGUgZW5kfSBhbmQgaXQgd2lsbCBjb3B5IHRoZSBhdHRyaWJ1dGVzIGRlZmluZWQgaW4KKyAgICAgKiB0aGUgc3BlY2lmaWVkIHNldC4gSWYgdGhlIHNldCBpcyB7QGNvZGUgbnVsbH0gdGhlbiBhbGwgYXR0cmlidXRlcyBhcmUKKyAgICAgKiBjb3BpZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXRlcmF0b3IKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yfSB0aGF0IGNvbnRhaW5zIHRoZSB0ZXh0CisgICAgICogICAgICAgICAgICBmb3IgdGhpcyBhdHRyaWJ1dGVkIHN0cmluZy4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBpbmRleCBvZiB0aGUgcmFuZ2Ugb2YgdGhlIGNvcGllZCB0ZXh0LgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmQgaW5kZXggb2YgdGhlIHJhbmdlIG9mIHRoZSBjb3BpZWQgdGV4dC4KKyAgICAgKiBAcGFyYW0gYXR0cmlidXRlcworICAgICAqICAgICAgICAgICAgdGhlIHNldCBvZiBhdHRyaWJ1dGVzIHRoYXQgd2lsbCBiZSBjb3BpZWQsIG9yIGFsbCBpZiBpdCBpcworICAgICAqICAgICAgICAgICAge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0fSBpcyBsZXNzIHRoYW4gZmlyc3QgaW5kZXggb2YKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgaXRlcmF0b3J9LCB7QGNvZGUgZW5kfSBpcyBncmVhdGVyIHRoYW4gdGhlIGxhc3QgaW5kZXggKworICAgICAqICAgICAgICAgICAgIDEgaW4ge0Bjb2RlIGl0ZXJhdG9yfSBvciBpZiB7QGNvZGUgc3RhcnQgPiBlbmR9LgorICAgICAqLworICAgIHB1YmxpYyBBdHRyaWJ1dGVkU3RyaW5nKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBpdGVyYXRvciwgaW50IHN0YXJ0LAorICAgICAgICAgICAgaW50IGVuZCwgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZVtdIGF0dHJpYnV0ZXMpIHsKKyAgICAgICAgdGhpcyhpdGVyYXRvciwgc3RhcnQsIGVuZCwgKGF0dHJpYnV0ZXMgPT0gbnVsbAorICAgICAgICAgICAgICAgID8gbmV3IEhhc2hTZXQ8QXR0cmlidXRlPigpCisgICAgICAgICAgICAgICAgOiBuZXcgSGFzaFNldDxBdHRyaWJ1dGU+KEFycmF5cy5hc0xpc3QoYXR0cmlidXRlcykpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiB7QGNvZGUgQXR0cmlidXRlZFN0cmluZ30gZnJvbSB0aGUgZ2l2ZW4gdGV4dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHRleHQgdG8gdGFrZSBhcyBiYXNlIGZvciB0aGlzIGF0dHJpYnV0ZWQgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBBdHRyaWJ1dGVkU3RyaW5nKFN0cmluZyB2YWx1ZSkgeworICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGV4dCA9IHZhbHVlOworICAgICAgICBhdHRyaWJ1dGVNYXAgPSBuZXcgSGFzaE1hcDxBdHRyaWJ1dGUsIExpc3Q8UmFuZ2U+PigxMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiB7QGNvZGUgQXR0cmlidXRlZFN0cmluZ30gZnJvbSB0aGUgZ2l2ZW4gdGV4dCBhbmQgdGhlCisgICAgICogYXR0cmlidXRlcy4gVGhlIHdob2xlIHRleHQgaGFzIHRoZSBnaXZlbiBhdHRyaWJ1dGVzIGFwcGxpZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0ZXh0IHRvIHRha2UgYXMgYmFzZSBmb3IgdGhpcyBhdHRyaWJ1dGVkIHN0cmluZy4KKyAgICAgKiBAcGFyYW0gYXR0cmlidXRlcworICAgICAqICAgICAgICAgICAgdGhlIGF0dHJpYnV0ZXMgdGhhdCB0aGUgdGV4dCBpcyBhc3NvY2lhdGVkIHdpdGguCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbGVuZ3RoIG9mIHtAY29kZSB2YWx1ZX0gaXMgMCBidXQgdGhlIHNpemUgb2Yge0Bjb2RlCisgICAgICogICAgICAgICAgICAgYXR0cmlidXRlc30gaXMgZ3JlYXRlciB0aGFuIDAuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSB2YWx1ZX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBBdHRyaWJ1dGVkU3RyaW5nKFN0cmluZyB2YWx1ZSwKKyAgICAgICAgICAgIE1hcDw/IGV4dGVuZHMgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSwgPz4gYXR0cmlidXRlcykgeworICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCgpID09IDAgJiYgIWF0dHJpYnV0ZXMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJDYW5ub3QgYWRkIGF0dHJpYnV0ZXMgdG8gZW1wdHkgc3RyaW5nIik7CisgICAgICAgIH0KKyAgICAgICAgdGV4dCA9IHZhbHVlOworICAgICAgICBhdHRyaWJ1dGVNYXAgPSBuZXcgSGFzaE1hcDxBdHRyaWJ1dGUsIExpc3Q8UmFuZ2U+PigKKyAgICAgICAgICAgICAgICAoYXR0cmlidXRlcy5zaXplKCkgKiA0IC8gMykgKyAxKTsKKyAgICAgICAgSXRlcmF0b3I8Pz4gaXQgPSBhdHRyaWJ1dGVzLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgTWFwLkVudHJ5PD8sID8+IGVudHJ5ID0gKE1hcC5FbnRyeTw/LCA/PikgaXQubmV4dCgpOworICAgICAgICAgICAgQXJyYXlMaXN0PFJhbmdlPiByYW5nZXMgPSBuZXcgQXJyYXlMaXN0PFJhbmdlPigxKTsKKyAgICAgICAgICAgIHJhbmdlcy5hZGQobmV3IFJhbmdlKDAsIHRleHQubGVuZ3RoKCksIGVudHJ5LmdldFZhbHVlKCkpKTsKKyAgICAgICAgICAgIGF0dHJpYnV0ZU1hcC5wdXQoKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUpIGVudHJ5CisgICAgICAgICAgICAgICAgICAgIC5nZXRLZXkoKSwgcmFuZ2VzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGxpZXMgYSBnaXZlbiBhdHRyaWJ1dGUgdG8gdGhpcyBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXR0cmlidXRlCisgICAgICogICAgICAgICAgICB0aGUgYXR0cmlidXRlIHRoYXQgd2lsbCBiZSBhcHBsaWVkIHRvIHRoaXMgc3RyaW5nLgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgdGhhdCB3aWxsIGJlIGFwcGxpZWQgdG8gdGhpcworICAgICAqICAgICAgICAgICAgc3RyaW5nLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGxlbmd0aCBvZiB0aGlzIGF0dHJpYnV0ZWQgc3RyaW5nIGlzIDAuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhdHRyaWJ1dGV9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRBdHRyaWJ1dGUoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSBhdHRyaWJ1dGUsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICBpZiAoYXR0cmlidXRlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmICh0ZXh0Lmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIExpc3Q8UmFuZ2U+IHJhbmdlcyA9IGF0dHJpYnV0ZU1hcC5nZXQoYXR0cmlidXRlKTsKKyAgICAgICAgaWYgKHJhbmdlcyA9PSBudWxsKSB7CisgICAgICAgICAgICByYW5nZXMgPSBuZXcgQXJyYXlMaXN0PFJhbmdlPigxKTsKKyAgICAgICAgICAgIGF0dHJpYnV0ZU1hcC5wdXQoYXR0cmlidXRlLCByYW5nZXMpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmFuZ2VzLmNsZWFyKCk7CisgICAgICAgIH0KKyAgICAgICAgcmFuZ2VzLmFkZChuZXcgUmFuZ2UoMCwgdGV4dC5sZW5ndGgoKSwgdmFsdWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBsaWVzIGEgZ2l2ZW4gYXR0cmlidXRlIHRvIHRoZSBnaXZlbiByYW5nZSBvZiB0aGlzIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhdHRyaWJ1dGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBhdHRyaWJ1dGUgdGhhdCB3aWxsIGJlIGFwcGxpZWQgdG8gdGhpcyBzdHJpbmcuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSB0aGF0IHdpbGwgYmUgYXBwbGllZCB0byB0aGlzCisgICAgICogICAgICAgICAgICBzdHJpbmcuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgb2YgdGhlIHJhbmdlIHdoZXJlIHRoZSBhdHRyaWJ1dGUgd2lsbCBiZSBhcHBsaWVkLgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmQgb2YgdGhlIHJhbmdlIHdoZXJlIHRoZSBhdHRyaWJ1dGUgd2lsbCBiZSBhcHBsaWVkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0IDwgMH0sIHtAY29kZSBlbmR9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoCisgICAgICogICAgICAgICAgICAgb2YgdGhpcyBzdHJpbmcsIG9yIGlmIHtAY29kZSBzdGFydCA+PSBlbmR9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYXR0cmlidXRlfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUgYXR0cmlidXRlLAorICAgICAgICAgICAgT2JqZWN0IHZhbHVlLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgaWYgKGF0dHJpYnV0ZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3RhcnQgPCAwIHx8IGVuZCA+IHRleHQubGVuZ3RoKCkgfHwgc3RhcnQgPj0gZW5kKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgTGlzdDxSYW5nZT4gcmFuZ2VzID0gYXR0cmlidXRlTWFwLmdldChhdHRyaWJ1dGUpOworICAgICAgICBpZiAocmFuZ2VzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJhbmdlcyA9IG5ldyBBcnJheUxpc3Q8UmFuZ2U+KDEpOworICAgICAgICAgICAgcmFuZ2VzLmFkZChuZXcgUmFuZ2Uoc3RhcnQsIGVuZCwgdmFsdWUpKTsKKyAgICAgICAgICAgIGF0dHJpYnV0ZU1hcC5wdXQoYXR0cmlidXRlLCByYW5nZXMpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIExpc3RJdGVyYXRvcjxSYW5nZT4gaXQgPSByYW5nZXMubGlzdEl0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIFJhbmdlIHJhbmdlID0gaXQubmV4dCgpOworICAgICAgICAgICAgaWYgKGVuZCA8PSByYW5nZS5zdGFydCkgeworICAgICAgICAgICAgICAgIGl0LnByZXZpb3VzKCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXJ0IDwgcmFuZ2UuZW5kCisgICAgICAgICAgICAgICAgICAgIHx8IChzdGFydCA9PSByYW5nZS5lbmQgJiYgdmFsdWUuZXF1YWxzKHJhbmdlLnZhbHVlKSkpIHsKKyAgICAgICAgICAgICAgICBSYW5nZSByMSA9IG51bGwsIHIzOworICAgICAgICAgICAgICAgIGl0LnJlbW92ZSgpOworICAgICAgICAgICAgICAgIHIxID0gbmV3IFJhbmdlKHJhbmdlLnN0YXJ0LCBzdGFydCwgcmFuZ2UudmFsdWUpOworICAgICAgICAgICAgICAgIHIzID0gbmV3IFJhbmdlKGVuZCwgcmFuZ2UuZW5kLCByYW5nZS52YWx1ZSk7CisKKyAgICAgICAgICAgICAgICB3aGlsZSAoZW5kID4gcmFuZ2UuZW5kICYmIGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgICAgICByYW5nZSA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGVuZCA8PSByYW5nZS5lbmQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbmQgPiByYW5nZS5zdGFydAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAoZW5kID09IHJhbmdlLnN0YXJ0ICYmIHZhbHVlLmVxdWFscyhyYW5nZS52YWx1ZSkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQucmVtb3ZlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcjMgPSBuZXcgUmFuZ2UoZW5kLCByYW5nZS5lbmQsIHJhbmdlLnZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGl0LnJlbW92ZSgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmVxdWFscyhyMS52YWx1ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmVxdWFscyhyMy52YWx1ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGl0LmFkZChuZXcgUmFuZ2UocjEuc3RhcnQgPCBzdGFydCA/IHIxLnN0YXJ0IDogc3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHIzLmVuZCA+IGVuZCA/IHIzLmVuZCA6IGVuZCwgcjEudmFsdWUpKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGl0LmFkZChuZXcgUmFuZ2UocjEuc3RhcnQgPCBzdGFydCA/IHIxLnN0YXJ0IDogc3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZCwgcjEudmFsdWUpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyMy5zdGFydCA8IHIzLmVuZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0LmFkZChyMyk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUuZXF1YWxzKHIzLnZhbHVlKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHIxLnN0YXJ0IDwgcjEuZW5kKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQuYWRkKHIxKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGl0LmFkZChuZXcgUmFuZ2Uoc3RhcnQsIHIzLmVuZCA+IGVuZCA/IHIzLmVuZCA6IGVuZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcjMudmFsdWUpKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyMS5zdGFydCA8IHIxLmVuZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0LmFkZChyMSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBpdC5hZGQobmV3IFJhbmdlKHN0YXJ0LCBlbmQsIHZhbHVlKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocjMuc3RhcnQgPCByMy5lbmQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdC5hZGQocjMpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpdC5hZGQobmV3IFJhbmdlKHN0YXJ0LCBlbmQsIHZhbHVlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwbGllcyBhIGdpdmVuIHNldCBvZiBhdHRyaWJ1dGVzIHRvIHRoZSBnaXZlbiByYW5nZSBvZiB0aGUgc3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZXQgb2YgYXR0cmlidXRlcyB0aGF0IHdpbGwgYmUgYXBwbGllZCB0byB0aGlzIHN0cmluZy4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBvZiB0aGUgcmFuZ2Ugd2hlcmUgdGhlIGF0dHJpYnV0ZSB3aWxsIGJlIGFwcGxpZWQuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGVuZCBvZiB0aGUgcmFuZ2Ugd2hlcmUgdGhlIGF0dHJpYnV0ZSB3aWxsIGJlIGFwcGxpZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwfSwge0Bjb2RlIGVuZH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgICBvZiB0aGlzIHN0cmluZywgb3IgaWYge0Bjb2RlIHN0YXJ0ID49IGVuZH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlcygKKyAgICAgICAgICAgIE1hcDw/IGV4dGVuZHMgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSwgPz4gYXR0cmlidXRlcywKKyAgICAgICAgICAgIGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBJdGVyYXRvcjw/PiBpdCA9IGF0dHJpYnV0ZXMuZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBNYXAuRW50cnk8PywgPz4gZW50cnkgPSAoTWFwLkVudHJ5PD8sID8+KSBpdC5uZXh0KCk7CisgICAgICAgICAgICBhZGRBdHRyaWJ1dGUoCisgICAgICAgICAgICAgICAgICAgIChBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlKSBlbnRyeS5nZXRLZXkoKSwKKyAgICAgICAgICAgICAgICAgICAgZW50cnkuZ2V0VmFsdWUoKSwgc3RhcnQsIGVuZCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIHtAY29kZSBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3J9IHRoYXQgZ2l2ZXMgYWNjZXNzIHRvIHRoZQorICAgICAqIGNvbXBsZXRlIGNvbnRlbnQgb2YgdGhpcyBhdHRyaWJ1dGVkIHN0cmluZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5ld2x5IGNyZWF0ZWQge0Bjb2RlIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcn0uCisgICAgICovCisgICAgcHVibGljIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBnZXRJdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGVkSXRlcmF0b3IodGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiB7QGNvZGUgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yfSB0aGF0IGdpdmVzIGFjY2VzcyB0byB0aGUKKyAgICAgKiBjb21wbGV0ZSBjb250ZW50IG9mIHRoaXMgYXR0cmlidXRlZCBzdHJpbmcuIE9ubHkgYXR0cmlidXRlcyBjb250YWluZWQgaW4KKyAgICAgKiB7QGNvZGUgYXR0cmlidXRlc30gYXJlIGF2YWlsYWJsZSBmcm9tIHRoaXMgaXRlcmF0b3IgaWYgdGhleSBhcmUgZGVmaW5lZAorICAgICAqIGZvciB0aGlzIHRleHQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXR0cmlidXRlcworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IGNvbnRhaW5pbmcgYXR0cmlidXRlcyB0aGF0IHdpbGwgYmUgaW4gdGhlIG5ldworICAgICAqICAgICAgICAgICAgaXRlcmF0b3IgaWYgdGhleSBhcmUgZGVmaW5lZCBmb3IgdGhpcyB0ZXh0LgorICAgICAqIEByZXR1cm4gdGhlIG5ld2x5IGNyZWF0ZWQge0Bjb2RlIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcn0uCisgICAgICovCisgICAgcHVibGljIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBnZXRJdGVyYXRvcigKKyAgICAgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGVbXSBhdHRyaWJ1dGVzKSB7CisgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlZEl0ZXJhdG9yKHRoaXMsIGF0dHJpYnV0ZXMsIDAsIHRleHQubGVuZ3RoKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4ge0Bjb2RlIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcn0gdGhhdCBnaXZlcyBhY2Nlc3MgdG8gdGhlCisgICAgICogY29udGVudHMgb2YgdGhpcyBhdHRyaWJ1dGVkIHN0cmluZyBzdGFydGluZyBhdCBpbmRleCB7QGNvZGUgc3RhcnR9IHVwIHRvCisgICAgICogaW5kZXgge0Bjb2RlIGVuZH0uIE9ubHkgYXR0cmlidXRlcyBjb250YWluZWQgaW4ge0Bjb2RlIGF0dHJpYnV0ZXN9IGFyZQorICAgICAqIGF2YWlsYWJsZSBmcm9tIHRoaXMgaXRlcmF0b3IgaWYgdGhleSBhcmUgZGVmaW5lZCBmb3IgdGhpcyB0ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBjb250YWluaW5nIGF0dHJpYnV0ZXMgdGhhdCB3aWxsIGJlIGluIHRoZSBuZXcKKyAgICAgKiAgICAgICAgICAgIGl0ZXJhdG9yIGlmIHRoZXkgYXJlIGRlZmluZWQgZm9yIHRoaXMgdGV4dC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBpbmRleCBvZiB0aGUgaXRlcmF0b3Igb24gdGhlIHVuZGVybHlpbmcgdGV4dC4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgZW5kIGluZGV4IG9mIHRoZSBpdGVyYXRvciBvbiB0aGUgdW5kZXJseWluZyB0ZXh0LgorICAgICAqIEByZXR1cm4gdGhlIG5ld2x5IGNyZWF0ZWQge0Bjb2RlIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcn0uCisgICAgICovCisgICAgcHVibGljIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBnZXRJdGVyYXRvcigKKyAgICAgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGVbXSBhdHRyaWJ1dGVzLCBpbnQgc3RhcnQsCisgICAgICAgICAgICBpbnQgZW5kKSB7CisgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlZEl0ZXJhdG9yKHRoaXMsIGF0dHJpYnV0ZXMsIHN0YXJ0LCBlbmQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvQmlkaS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9CaWRpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTRiMzBlNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvQmlkaS5qYXZhCkBAIC0wLDAgKzEsNjI1IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLmF3dC5mb250Lk51bWVyaWNTaGFwZXI7CitpbXBvcnQgamF2YS5hd3QuZm9udC5UZXh0QXR0cmlidXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBJbXBsZW1lbnRzIHRoZSA8YSBocmVmPSJodHRwOi8vdW5pY29kZS5vcmcvcmVwb3J0cy90cjkvIj5Vbmljb2RlIEJpZGlyZWN0aW9uYWwgQWxnb3JpdGhtPC9hPi4KKyAqCisgKiA8cD5Vc2UgYSB7QGNvZGUgQmlkaX0gb2JqZWN0IHRvIGdldCB0aGUgaW5mb3JtYXRpb24gb24gdGhlIHBvc2l0aW9uIHJlb3JkZXJpbmcgb2YgYQorICogYmlkaXJlY3Rpb25hbCB0ZXh0LCBzdWNoIGFzIEFyYWJpYyBvciBIZWJyZXcuIFRoZSBuYXR1cmFsIGRpc3BsYXkgb3JkZXJpbmcgb2YKKyAqIGhvcml6b250YWwgdGV4dCBpbiB0aGVzZSBsYW5ndWFnZXMgaXMgZnJvbSByaWdodCB0byBsZWZ0LCB3aGlsZSB0aGV5IG9yZGVyCisgKiBudW1iZXJzIGZyb20gbGVmdCB0byByaWdodC4KKyAqCisgKiA8cD5JZiB0aGUgdGV4dCBjb250YWlucyBtdWx0aXBsZSBydW5zLCB0aGUgaW5mb3JtYXRpb24gb2YgZWFjaCBydW4gY2FuIGJlCisgKiBvYnRhaW5lZCBmcm9tIHRoZSBydW4gaW5kZXguIFRoZSBsZXZlbCBvZiBhbnkgcGFydGljdWxhciBydW4gaW5kaWNhdGVzIHRoZQorICogZGlyZWN0aW9uIG9mIHRoZSB0ZXh0IGFzIHdlbGwgYXMgdGhlIG5lc3RpbmcgbGV2ZWwuIExlZnQtdG8tcmlnaHQgcnVucyBoYXZlCisgKiBldmVuIGxldmVscyB3aGlsZSByaWdodC10by1sZWZ0IHJ1bnMgaGF2ZSBvZGQgbGV2ZWxzLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQmlkaSB7CisgICAgLyoqCisgICAgICogQ29uc3RhbnQgdGhhdCBpbmRpY2F0ZXMgdGhlIGRlZmF1bHQgYmFzZSBsZXZlbC4gSWYgdGhlcmUgaXMgbm8gc3Ryb25nCisgICAgICogY2hhcmFjdGVyLCB0aGVuIHNldCB0aGUgcGFyYWdyYXBoIGxldmVsIHRvIDAgKGxlZnQtdG8tcmlnaHQpLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERJUkVDVElPTl9ERUZBVUxUX0xFRlRfVE9fUklHSFQgPSAtMjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IHRoYXQgaW5kaWNhdGVzIHRoZSBkZWZhdWx0IGJhc2UgbGV2ZWwuIElmIHRoZXJlIGlzIG5vIHN0cm9uZworICAgICAqIGNoYXJhY3RlciwgdGhlbiBzZXQgdGhlIHBhcmFncmFwaCBsZXZlbCB0byAxIChyaWdodC10by1sZWZ0KS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBESVJFQ1RJT05fREVGQVVMVF9SSUdIVF9UT19MRUZUID0gLTE7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCB0aGF0IHNwZWNpZmllcyB0aGUgZGVmYXVsdCBiYXNlIGxldmVsIGFzIDAgKGxlZnQtdG8tcmlnaHQpLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERJUkVDVElPTl9MRUZUX1RPX1JJR0hUID0gMDsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IHRoYXQgc3BlY2lmaWVzIHRoZSBkZWZhdWx0IGJhc2UgbGV2ZWwgYXMgMSAocmlnaHQtdG8tbGVmdCkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRElSRUNUSU9OX1JJR0hUX1RPX0xFRlQgPSAxOworCisgICAgLyoqCisgICAgICogVE9ETzogaWYgd2UgY2FyZSBhYm91dCBwZXJmb3JtYW5jZSwgd2UgbWlnaHQganVzdCB3YW50IHRvIHVzZSBhbiBpbnRbXSBpbnN0ZWFkIG9mIGEgUnVuW10uCisgICAgICovCisgICAgc3RhdGljIGNsYXNzIFJ1biB7CisgICAgICAgIHByaXZhdGUgZmluYWwgaW50IHN0YXJ0OworICAgICAgICBwcml2YXRlIGZpbmFsIGludCBsaW1pdDsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbGV2ZWw7CisKKyAgICAgICAgcHVibGljIFJ1bihpbnQgc3RhcnQsIGludCBsaW1pdCwgaW50IGxldmVsKSB7CisgICAgICAgICAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7CisgICAgICAgICAgICB0aGlzLmxpbWl0ID0gbGltaXQ7CisgICAgICAgICAgICB0aGlzLmxldmVsID0gbGV2ZWw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldExldmVsKCkgeworICAgICAgICAgICAgcmV0dXJuIGxldmVsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXRMaW1pdCgpIHsKKyAgICAgICAgICAgIHJldHVybiBsaW1pdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0U3RhcnQoKSB7CisgICAgICAgICAgICByZXR1cm4gc3RhcnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIEJpZGl9IG9iamVjdCBmcm9tIHRoZSB7QGNvZGUKKyAgICAgKiBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3J9IG9mIGEgcGFyYWdyYXBoIHRleHQuIFRoZSBSVU5fRElSRUNUSU9OCisgICAgICogYXR0cmlidXRlIGRldGVybWluZXMgdGhlIGJhc2UgZGlyZWN0aW9uIG9mIHRoZSBiaWRpcmVjdGlvbmFsIHRleHQuIElmIGl0CisgICAgICogaXMgbm90IHNwZWNpZmllZCBleHBsaWNpdGx5LCB0aGUgYWxnb3JpdGhtIHVzZXMKKyAgICAgKiBESVJFQ1RJT05fREVGQVVMVF9MRUZUX1RPX1JJR0hUIGJ5IGRlZmF1bHQuIFRoZSBCSURJX0VNQkVERElORyBhdHRyaWJ1dGUKKyAgICAgKiBzcGVjaWZpZXMgdGhlIGxldmVsIG9mIGVtYmVkZGluZyBmb3IgZWFjaCBjaGFyYWN0ZXIuIFZhbHVlcyBiZXR3ZWVuIC0xCisgICAgICogYW5kIC02MiBkZW5vdGUgb3ZlcnJpZGVzIGF0IHRoZSBsZXZlbCdzIGFic29sdXRlIHZhbHVlLCB2YWx1ZXMgZnJvbSAxIHRvCisgICAgICogNjIgaW5kaWNhdGUgZW1iZWRkaW5ncywgYW5kIHRoZSAwIHZhbHVlIGluZGljYXRlcyB0aGUgbGV2ZWwgaXMgY2FsY3VsYXRlZAorICAgICAqIGJ5IHRoZSBhbGdvcml0aG0gYXV0b21hdGljYWxseS4gRm9yIHRoZSBjaGFyYWN0ZXIgd2l0aCBubyBCSURJX0VNQkVERElORworICAgICAqIGF0dHJpYnV0ZSBvciB3aXRoIGEgaW1wcm9wZXIgYXR0cmlidXRlIHZhbHVlLCBzdWNoIGFzIGEge0Bjb2RlIG51bGx9CisgICAgICogdmFsdWUsIHRoZSBhbGdvcml0aG0gdHJlYXRzIGl0cyBlbWJlZGRpbmcgbGV2ZWwgYXMgMC4gVGhlIE5VTUVSSUNfU0hBUElORworICAgICAqIGF0dHJpYnV0ZSBzcGVjaWZpZXMgdGhlIGluc3RhbmNlIG9mIE51bWVyaWNTaGFwZXIgdXNlZCB0byBjb252ZXJ0CisgICAgICogRXVyb3BlYW4gZGlnaXRzIHRvIG90aGVyIGRlY2ltYWwgZGlnaXRzIGJlZm9yZSBwZXJmb3JtaW5nIHRoZSBiaWRpCisgICAgICogYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFncmFwaAorICAgICAqICAgICAgICAgICAgdGhlIFN0cmluZyBjb250YWluaW5nIHRoZSBwYXJhZ3JhcGggdGV4dCB0byBwZXJmb3JtIHRoZQorICAgICAqICAgICAgICAgICAgYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBwYXJhZ3JhcGggPT0gbnVsbH0KKyAgICAgKiBAc2VlIGphdmEuYXd0LmZvbnQuVGV4dEF0dHJpYnV0ZSNCSURJX0VNQkVERElORworICAgICAqIEBzZWUgamF2YS5hd3QuZm9udC5UZXh0QXR0cmlidXRlI05VTUVSSUNfU0hBUElORworICAgICAqIEBzZWUgamF2YS5hd3QuZm9udC5UZXh0QXR0cmlidXRlI1JVTl9ESVJFQ1RJT04KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlkaShBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgcGFyYWdyYXBoKSB7CisgICAgICAgIGlmIChwYXJhZ3JhcGggPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicGFyYWdyYXBoIGlzIG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBiZWdpbiA9IHBhcmFncmFwaC5nZXRCZWdpbkluZGV4KCk7CisgICAgICAgIGludCBlbmQgPSBwYXJhZ3JhcGguZ2V0RW5kSW5kZXgoKTsKKyAgICAgICAgaW50IGxlbmd0aCA9IGVuZCAtIGJlZ2luOworICAgICAgICBjaGFyW10gdGV4dCA9IG5ldyBjaGFyW2xlbmd0aCArIDFdOyAvLyBPbmUgbW9yZSBjaGFyIGZvciBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuRE9ORQorCisgICAgICAgIGlmIChsZW5ndGggIT0gMCkgeworICAgICAgICAgICAgdGV4dFswXSA9IHBhcmFncmFwaC5maXJzdCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcGFyYWdyYXBoLmZpcnN0KCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBGaXJzdCBjaGVjayB0aGUgUlVOX0RJUkVDVElPTiBhdHRyaWJ1dGUuCisgICAgICAgIGludCBmbGFncyA9IERJUkVDVElPTl9ERUZBVUxUX0xFRlRfVE9fUklHSFQ7CisgICAgICAgIE9iamVjdCBkaXJlY3Rpb24gPSBwYXJhZ3JhcGguZ2V0QXR0cmlidXRlKFRleHRBdHRyaWJ1dGUuUlVOX0RJUkVDVElPTik7CisgICAgICAgIGlmIChkaXJlY3Rpb24gIT0gbnVsbCAmJiBkaXJlY3Rpb24gaW5zdGFuY2VvZiBCb29sZWFuKSB7CisgICAgICAgICAgICBpZiAoZGlyZWN0aW9uLmVxdWFscyhUZXh0QXR0cmlidXRlLlJVTl9ESVJFQ1RJT05fTFRSKSkgeworICAgICAgICAgICAgICAgIGZsYWdzID0gRElSRUNUSU9OX0xFRlRfVE9fUklHSFQ7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZsYWdzID0gRElSRUNUSU9OX1JJR0hUX1RPX0xFRlQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBSZXRyaWV2ZSB0aGUgdGV4dCBhbmQgZ2F0aGVyIEJJRElfRU1CRURESU5HUworICAgICAgICBieXRlW10gZW1iZWRkaW5ncyA9IG51bGw7CisgICAgICAgIGZvciAoaW50IHRleHRMaW1pdCA9IDEsIGkgPSAxOyBpIDwgbGVuZ3RoOyB0ZXh0TGltaXQgPSBwYXJhZ3JhcGgKKyAgICAgICAgICAgICAgICAuZ2V0UnVuTGltaXQoVGV4dEF0dHJpYnV0ZS5CSURJX0VNQkVERElORykKKyAgICAgICAgICAgICAgICAtIGJlZ2luICsgMSkgeworICAgICAgICAgICAgT2JqZWN0IGVtYmVkZGluZyA9IHBhcmFncmFwaC5nZXRBdHRyaWJ1dGUoVGV4dEF0dHJpYnV0ZS5CSURJX0VNQkVERElORyk7CisgICAgICAgICAgICBpZiAoZW1iZWRkaW5nICE9IG51bGwgJiYgZW1iZWRkaW5nIGluc3RhbmNlb2YgSW50ZWdlcikgeworICAgICAgICAgICAgICAgIGludCBlbWJMZXZlbCA9ICgoSW50ZWdlcikgZW1iZWRkaW5nKS5pbnRWYWx1ZSgpOworCisgICAgICAgICAgICAgICAgaWYgKGVtYmVkZGluZ3MgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBlbWJlZGRpbmdzID0gbmV3IGJ5dGVbbGVuZ3RoXTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IHRleHRMaW1pdDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHRleHRbaV0gPSBwYXJhZ3JhcGgubmV4dCgpOworICAgICAgICAgICAgICAgICAgICBlbWJlZGRpbmdzW2kgLSAxXSA9IChieXRlKSBlbWJMZXZlbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgdGV4dExpbWl0OyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgdGV4dFtpXSA9IHBhcmFncmFwaC5uZXh0KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gQXBwbHkgTnVtZXJpY1NoYXBlciB0byB0aGUgdGV4dAorICAgICAgICBPYmplY3QgbnVtZXJpY1NoYXBlciA9IHBhcmFncmFwaC5nZXRBdHRyaWJ1dGUoVGV4dEF0dHJpYnV0ZS5OVU1FUklDX1NIQVBJTkcpOworICAgICAgICBpZiAobnVtZXJpY1NoYXBlciAhPSBudWxsICYmIG51bWVyaWNTaGFwZXIgaW5zdGFuY2VvZiBOdW1lcmljU2hhcGVyKSB7CisgICAgICAgICAgICAoKE51bWVyaWNTaGFwZXIpIG51bWVyaWNTaGFwZXIpLnNoYXBlKHRleHQsIDAsIGxlbmd0aCk7CisgICAgICAgIH0KKworICAgICAgICBsb25nIGJpZGkgPSAwOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmlkaSA9IGNyZWF0ZVVCaURpKHRleHQsIDAsIGVtYmVkZGluZ3MsIDAsIGxlbmd0aCwgZmxhZ3MpOworICAgICAgICAgICAgcmVhZEJpZGlJbmZvKGJpZGkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdWJpZGlfY2xvc2UoYmlkaSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIEJpZGl9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0ZXh0CisgICAgICogICAgICAgICAgICB0aGUgY2hhciBhcnJheSBvZiB0aGUgcGFyYWdyYXBoIHRleHQgdGhhdCBpcyBwcm9jZXNzZWQuCisgICAgICogQHBhcmFtIHRleHRTdGFydAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGluIHtAY29kZSB0ZXh0fSBvZiB0aGUgc3RhcnQgb2YgdGhlIHBhcmFncmFwaC4KKyAgICAgKiBAcGFyYW0gZW1iZWRkaW5ncworICAgICAqICAgICAgICAgICAgdGhlIGVtYmVkZGluZyBsZXZlbCBhcnJheSBvZiB0aGUgcGFyYWdyYXBoIHRleHQsIHNwZWNpZnlpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbWJlZGRpbmcgbGV2ZWwgaW5mb3JtYXRpb24gZm9yIGVhY2ggY2hhcmFjdGVyLiBWYWx1ZXMKKyAgICAgKiAgICAgICAgICAgIGJldHdlZW4gLTEgYW5kIC02MSBkZW5vdGUgb3ZlcnJpZGVzIGF0IHRoZSBsZXZlbCdzIGFic29sdXRlCisgICAgICogICAgICAgICAgICB2YWx1ZSwgdmFsdWVzIGZyb20gMSB0byA2MSBpbmRpY2F0ZSBlbWJlZGRpbmdzLCBhbmQgdGhlIDAKKyAgICAgKiAgICAgICAgICAgIHZhbHVlIGluZGljYXRlcyB0aGUgbGV2ZWwgaXMgY2FsY3VsYXRlZCBieSB0aGUgYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICBhdXRvbWF0aWNhbGx5LgorICAgICAqIEBwYXJhbSBlbWJTdGFydAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGluIHtAY29kZSBlbWJlZGRpbmdzfSBvZiB0aGUgc3RhcnQgb2YgdGhlIHBhcmFncmFwaC4KKyAgICAgKiBAcGFyYW0gcGFyYWdyYXBoTGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSB0ZXh0IHRvIHBlcmZvcm0gdGhlIGFsZ29yaXRobS4KKyAgICAgKiBAcGFyYW0gZmxhZ3MKKyAgICAgKiAgICAgICAgICAgIGluZGljYXRlcyB0aGUgYmFzZSBkaXJlY3Rpb24gb2YgdGhlIGJpZGlyZWN0aW9uYWwgdGV4dC4gSXQgaXMKKyAgICAgKiAgICAgICAgICAgIGV4cGVjdGVkIHRoYXQgdGhpcyB3aWxsIGJlIG9uZSBvZiB0aGUgZGlyZWN0aW9uIGNvbnN0YW50CisgICAgICogICAgICAgICAgICB2YWx1ZXMgZGVmaW5lZCBpbiB0aGlzIGNsYXNzLiBBbiB1bmtub3duIHZhbHVlIGlzIHRyZWF0ZWQgYXMKKyAgICAgKiAgICAgICAgICAgIERJUkVDVElPTl9ERUZBVUxUX0xFRlRfVE9fUklHSFQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgdGV4dFN0YXJ0fSwge0Bjb2RlIGVtYlN0YXJ0fSwgb3Ige0Bjb2RlCisgICAgICogICAgICAgICAgICAgcGFyYWdyYXBoTGVuZ3RofSBpcyBuZWdhdGl2ZTsgaWYKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgdGV4dC5sZW5ndGggPCB0ZXh0U3RhcnQgKyBwYXJhZ3JhcGhMZW5ndGh9IG9yCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGVtYmVkZGluZ3MubGVuZ3RoIDwgZW1iU3RhcnQgKyBwYXJhZ3JhcGhMZW5ndGh9LgorICAgICAqIEBzZWUgI0RJUkVDVElPTl9MRUZUX1RPX1JJR0hUCisgICAgICogQHNlZSAjRElSRUNUSU9OX1JJR0hUX1RPX0xFRlQKKyAgICAgKiBAc2VlICNESVJFQ1RJT05fREVGQVVMVF9SSUdIVF9UT19MRUZUCisgICAgICogQHNlZSAjRElSRUNUSU9OX0RFRkFVTFRfTEVGVF9UT19SSUdIVAorICAgICAqLworICAgIHB1YmxpYyBCaWRpKGNoYXJbXSB0ZXh0LCBpbnQgdGV4dFN0YXJ0LCBieXRlW10gZW1iZWRkaW5ncywgaW50IGVtYlN0YXJ0LAorICAgICAgICAgICAgaW50IHBhcmFncmFwaExlbmd0aCwgaW50IGZsYWdzKSB7CisKKyAgICAgICAgaWYgKHRleHQgPT0gbnVsbCB8fCB0ZXh0Lmxlbmd0aCAtIHRleHRTdGFydCA8IHBhcmFncmFwaExlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGVtYmVkZGluZ3MgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKGVtYmVkZGluZ3MubGVuZ3RoIC0gZW1iU3RhcnQgPCBwYXJhZ3JhcGhMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAodGV4dFN0YXJ0IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTmVnYXRpdmUgdGV4dFN0YXJ0IHZhbHVlICIgKyB0ZXh0U3RhcnQpOworICAgICAgICB9CisgICAgICAgIGlmIChlbWJTdGFydCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5lZ2F0aXZlIGVtYlN0YXJ0IHZhbHVlICIgKyBlbWJTdGFydCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBhcmFncmFwaExlbmd0aCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5lZ2F0aXZlIHBhcmFncmFwaCBsZW5ndGggIiArIHBhcmFncmFwaExlbmd0aCk7CisgICAgICAgIH0KKworICAgICAgICBsb25nIGJpZGkgPSAwOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmlkaSA9IGNyZWF0ZVVCaURpKHRleHQsIHRleHRTdGFydCwgZW1iZWRkaW5ncywgZW1iU3RhcnQsIHBhcmFncmFwaExlbmd0aCwgZmxhZ3MpOworICAgICAgICAgICAgcmVhZEJpZGlJbmZvKGJpZGkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdWJpZGlfY2xvc2UoYmlkaSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIEJpZGl9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhZ3JhcGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgY29udGFpbmluZyB0aGUgcGFyYWdyYXBoIHRleHQgdG8gcGVyZm9ybSB0aGUKKyAgICAgKiAgICAgICAgICAgIGFsZ29yaXRobSBvbi4KKyAgICAgKiBAcGFyYW0gZmxhZ3MKKyAgICAgKiAgICAgICAgICAgIGluZGljYXRlcyB0aGUgYmFzZSBkaXJlY3Rpb24gb2YgdGhlIGJpZGlyZWN0aW9uYWwgdGV4dC4gSXQgaXMKKyAgICAgKiAgICAgICAgICAgIGV4cGVjdGVkIHRoYXQgdGhpcyB3aWxsIGJlIG9uZSBvZiB0aGUgZGlyZWN0aW9uIGNvbnN0YW50CisgICAgICogICAgICAgICAgICB2YWx1ZXMgZGVmaW5lZCBpbiB0aGlzIGNsYXNzLiBBbiB1bmtub3duIHZhbHVlIGlzIHRyZWF0ZWQgYXMKKyAgICAgKiAgICAgICAgICAgIERJUkVDVElPTl9ERUZBVUxUX0xFRlRfVE9fUklHSFQuCisgICAgICogQHNlZSAjRElSRUNUSU9OX0xFRlRfVE9fUklHSFQKKyAgICAgKiBAc2VlICNESVJFQ1RJT05fUklHSFRfVE9fTEVGVAorICAgICAqIEBzZWUgI0RJUkVDVElPTl9ERUZBVUxUX1JJR0hUX1RPX0xFRlQKKyAgICAgKiBAc2VlICNESVJFQ1RJT05fREVGQVVMVF9MRUZUX1RPX1JJR0hUCisgICAgICovCisgICAgcHVibGljIEJpZGkoU3RyaW5nIHBhcmFncmFwaCwgaW50IGZsYWdzKSB7CisgICAgICAgIHRoaXMoKHBhcmFncmFwaCA9PSBudWxsID8gbnVsbCA6IHBhcmFncmFwaC50b0NoYXJBcnJheSgpKSwgMCwgbnVsbCwgMCwKKyAgICAgICAgICAgICAgICAocGFyYWdyYXBoID09IG51bGwgPyAwIDogcGFyYWdyYXBoLmxlbmd0aCgpKSwgZmxhZ3MpOworICAgIH0KKworICAgIC8vIGNyZWF0ZSB0aGUgbmF0aXZlIFVCaURpIHN0cnVjdCwgbmVlZCB0byBiZSBjbG9zZWQgd2l0aCB1YmlkaV9jbG9zZSgpLgorICAgIHByaXZhdGUgc3RhdGljIGxvbmcgY3JlYXRlVUJpRGkoY2hhcltdIHRleHQsIGludCB0ZXh0U3RhcnQsCisgICAgICAgICAgICBieXRlW10gZW1iZWRkaW5ncywgaW50IGVtYlN0YXJ0LCBpbnQgcGFyYWdyYXBoTGVuZ3RoLCBpbnQgZmxhZ3MpIHsKKyAgICAgICAgY2hhcltdIHJlYWxUZXh0ID0gbnVsbDsKKworICAgICAgICBieXRlW10gcmVhbEVtYmVkZGluZ3MgPSBudWxsOworCisgICAgICAgIGlmICh0ZXh0ID09IG51bGwgfHwgdGV4dC5sZW5ndGggLSB0ZXh0U3RhcnQgPCBwYXJhZ3JhcGhMZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZWFsVGV4dCA9IG5ldyBjaGFyW3BhcmFncmFwaExlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodGV4dCwgdGV4dFN0YXJ0LCByZWFsVGV4dCwgMCwgcGFyYWdyYXBoTGVuZ3RoKTsKKworICAgICAgICBpZiAoZW1iZWRkaW5ncyAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoZW1iZWRkaW5ncy5sZW5ndGggLSBlbWJTdGFydCA8IHBhcmFncmFwaExlbmd0aCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChwYXJhZ3JhcGhMZW5ndGggPiAwKSB7CisgICAgICAgICAgICAgICAgQmlkaSB0ZW1wID0gbmV3IEJpZGkodGV4dCwgdGV4dFN0YXJ0LCBudWxsLCAwLCBwYXJhZ3JhcGhMZW5ndGgsIGZsYWdzKTsKKyAgICAgICAgICAgICAgICByZWFsRW1iZWRkaW5ncyA9IG5ldyBieXRlW3BhcmFncmFwaExlbmd0aF07CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0ZW1wLm9mZnNldExldmVsLCAwLCByZWFsRW1iZWRkaW5ncywgMCwgcGFyYWdyYXBoTGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcmFncmFwaExlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGJ5dGUgZSA9IGVtYmVkZGluZ3NbaV07CisgICAgICAgICAgICAgICAgICAgIGlmIChlIDwgMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVhbEVtYmVkZGluZ3NbaV0gPSAoYnl0ZSkgKFVCSURJX0xFVkVMX09WRVJSSURFIC0gZSk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZSA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlYWxFbWJlZGRpbmdzW2ldID0gZTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlYWxFbWJlZGRpbmdzW2ldIHw9IChieXRlKSBVQklESV9MRVZFTF9PVkVSUklERTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChmbGFncyA+IDEgfHwgZmxhZ3MgPCAtMikgeworICAgICAgICAgICAgZmxhZ3MgPSAwOworICAgICAgICB9CisKKyAgICAgICAgbG9uZyBiaWRpID0gMDsKKyAgICAgICAgYm9vbGVhbiBuZWVkc0RlbGV0aW9uID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJpZGkgPSB1YmlkaV9vcGVuKCk7CisgICAgICAgICAgICB1YmlkaV9zZXRQYXJhKGJpZGksIHJlYWxUZXh0LCBwYXJhZ3JhcGhMZW5ndGgsIGZsYWdzLCByZWFsRW1iZWRkaW5ncyk7CisgICAgICAgICAgICBuZWVkc0RlbGV0aW9uID0gZmFsc2U7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAobmVlZHNEZWxldGlvbikgeworICAgICAgICAgICAgICAgIHViaWRpX2Nsb3NlKGJpZGkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBiaWRpOworICAgIH0KKworICAgIC8qIHByaXZhdGUgY29uc3RydWN0b3IgdXNlZCBieSBjcmVhdGVMaW5lQmlkaSgpICovCisgICAgcHJpdmF0ZSBCaWRpKGxvbmcgcEJpZGkpIHsKKyAgICAgICAgcmVhZEJpZGlJbmZvKHBCaWRpKTsKKyAgICB9CisKKyAgICAvLyByZWFkIGluZm8gZnJvbSB0aGUgbmF0aXZlIFVCaURpIHN0cnVjdAorICAgIHByaXZhdGUgdm9pZCByZWFkQmlkaUluZm8obG9uZyBwQmlkaSkgeworICAgICAgICBsZW5ndGggPSB1YmlkaV9nZXRMZW5ndGgocEJpZGkpOworCisgICAgICAgIG9mZnNldExldmVsID0gKGxlbmd0aCA9PSAwKSA/IG51bGwgOiB1YmlkaV9nZXRMZXZlbHMocEJpZGkpOworCisgICAgICAgIGJhc2VMZXZlbCA9IHViaWRpX2dldFBhcmFMZXZlbChwQmlkaSk7CisKKyAgICAgICAgaW50IHJ1bkNvdW50ID0gdWJpZGlfY291bnRSdW5zKHBCaWRpKTsKKyAgICAgICAgaWYgKHJ1bkNvdW50ID09IDApIHsKKyAgICAgICAgICAgIHVuaWRpcmVjdGlvbmFsID0gdHJ1ZTsKKyAgICAgICAgICAgIHJ1bnMgPSBudWxsOworICAgICAgICB9IGVsc2UgaWYgKHJ1bkNvdW50IDwgMCkgeworICAgICAgICAgICAgcnVucyA9IG51bGw7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBydW5zID0gdWJpZGlfZ2V0UnVucyhwQmlkaSk7CisKKyAgICAgICAgICAgIC8vIFNpbXBsaWZpZWQgY2FzZSBmb3Igb25lIHJ1biB3aGljaCBoYXMgdGhlIGJhc2UgbGV2ZWwKKyAgICAgICAgICAgIGlmIChydW5Db3VudCA9PSAxICYmIHJ1bnNbMF0uZ2V0TGV2ZWwoKSA9PSBiYXNlTGV2ZWwpIHsKKyAgICAgICAgICAgICAgICB1bmlkaXJlY3Rpb25hbCA9IHRydWU7CisgICAgICAgICAgICAgICAgcnVucyA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBkaXJlY3Rpb24gPSB1YmlkaV9nZXREaXJlY3Rpb24ocEJpZGkpOworICAgIH0KKworICAgIHByaXZhdGUgaW50IGJhc2VMZXZlbDsKKworICAgIHByaXZhdGUgaW50IGxlbmd0aDsKKworICAgIHByaXZhdGUgYnl0ZVtdIG9mZnNldExldmVsOworCisgICAgcHJpdmF0ZSBSdW5bXSBydW5zOworCisgICAgcHJpdmF0ZSBpbnQgZGlyZWN0aW9uOworCisgICAgcHJpdmF0ZSBib29sZWFuIHVuaWRpcmVjdGlvbmFsOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBiYXNlIGxldmVsIGlzIGZyb20gbGVmdCB0byByaWdodC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgYmFzZSBsZXZlbCBpcyBmcm9tIGxlZnQgdG8gcmlnaHQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYmFzZUlzTGVmdFRvUmlnaHQoKSB7CisgICAgICAgIHJldHVybiBiYXNlTGV2ZWwgJSAyID09IDAgPyB0cnVlIDogZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQmlkaX0gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGluZm9ybWF0aW9uIG9mIG9uZSBsaW5lCisgICAgICogZnJvbSB0aGlzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsaW5lU3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBvZmZzZXQgb2YgdGhlIGxpbmUuCisgICAgICogQHBhcmFtIGxpbmVMaW1pdAorICAgICAqICAgICAgICAgICAgdGhlIGxpbWl0IG9mIHRoZSBsaW5lLgorICAgICAqIEByZXR1cm4gdGhlIG5ldyBsaW5lIEJpZGkgb2JqZWN0LiBJbiB0aGlzIG5ldyBvYmplY3QsIHRoZSBpbmRpY2VzIHdpbGwKKyAgICAgKiAgICAgICAgIHJhbmdlIGZyb20gMCB0byAobGltaXQgLSBzdGFydCAtIDEpLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGxpbmVTdGFydCA8IDB9LCB7QGNvZGUgbGluZUxpbWl0IDwgMH0sIHtAY29kZQorICAgICAqICAgICAgICAgICAgIGxpbmVTdGFydCA+IGxpbmVMaW1pdH0gb3IgaWYge0Bjb2RlIGxpbmVTdGFydH0gaXMgZ3JlYXRlcgorICAgICAqICAgICAgICAgICAgIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzIG9iamVjdCdzIHBhcmFncmFwaCB0ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBCaWRpIGNyZWF0ZUxpbmVCaWRpKGludCBsaW5lU3RhcnQsIGludCBsaW5lTGltaXQpIHsKKyAgICAgICAgaWYgKGxpbmVTdGFydCA8IDAgfHwgbGluZUxpbWl0IDwgMCB8fCBsaW5lTGltaXQgPiBsZW5ndGggfHwgbGluZVN0YXJ0ID4gbGluZUxpbWl0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIHJhbmdlcyAoc3RhcnQ9IiArIGxpbmVTdGFydCArICIsICIgKworICAgICAgICAgICAgICAgICAgICAibGltaXQ9IiArIGxpbmVMaW1pdCArICIsIGxlbmd0aD0iICsgbGVuZ3RoICsgIikiKTsKKyAgICAgICAgfQorCisgICAgICAgIGNoYXJbXSB0ZXh0ID0gbmV3IGNoYXJbdGhpcy5sZW5ndGhdOworICAgICAgICBBcnJheXMuZmlsbCh0ZXh0LCAnYScpOworICAgICAgICBieXRlW10gZW1iZWRkaW5ncyA9IG5ldyBieXRlW3RoaXMubGVuZ3RoXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbWJlZGRpbmdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBlbWJlZGRpbmdzW2ldID0gKGJ5dGUpIC10aGlzLm9mZnNldExldmVsW2ldOworICAgICAgICB9CisKKyAgICAgICAgaW50IGRpciA9IHRoaXMuYmFzZUlzTGVmdFRvUmlnaHQoKQorICAgICAgICAgICAgICAgID8gQmlkaS5ESVJFQ1RJT05fTEVGVF9UT19SSUdIVAorICAgICAgICAgICAgICAgIDogQmlkaS5ESVJFQ1RJT05fUklHSFRfVE9fTEVGVDsKKyAgICAgICAgbG9uZyBwYXJlbnQgPSAwOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFyZW50ID0gY3JlYXRlVUJpRGkodGV4dCwgMCwgZW1iZWRkaW5ncywgMCwgdGhpcy5sZW5ndGgsIGRpcik7CisgICAgICAgICAgICBpZiAobGluZVN0YXJ0ID09IGxpbmVMaW1pdCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVFbXB0eUxpbmVCaWRpKHBhcmVudCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IEJpZGkodWJpZGlfc2V0TGluZShwYXJlbnQsIGxpbmVTdGFydCwgbGluZUxpbWl0KSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB1YmlkaV9jbG9zZShwYXJlbnQpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBCaWRpIGNyZWF0ZUVtcHR5TGluZUJpZGkobG9uZyBwYXJlbnQpIHsKKyAgICAgICAgLy8gSUNVNEMgZG9lc24ndCBhbGxvdyB0aGlzIGNhc2UsIGJ1dCB0aGUgUkkgZG9lcy4KKyAgICAgICAgQmlkaSByZXN1bHQgPSBuZXcgQmlkaShwYXJlbnQpOworICAgICAgICByZXN1bHQubGVuZ3RoID0gMDsKKyAgICAgICAgcmVzdWx0Lm9mZnNldExldmVsID0gbnVsbDsKKyAgICAgICAgcmVzdWx0LnJ1bnMgPSBudWxsOworICAgICAgICByZXN1bHQudW5pZGlyZWN0aW9uYWwgPSB0cnVlOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGJhc2UgbGV2ZWwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBiYXNlIGxldmVsLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0QmFzZUxldmVsKCkgeworICAgICAgICByZXR1cm4gYmFzZUxldmVsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGUgdGV4dCBpbiB0aGUge0Bjb2RlIEJpZGl9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxlbmd0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsZXZlbCBvZiBhIHNwZWNpZmllZCBjaGFyYWN0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IG9mIHRoZSBjaGFyYWN0ZXIuCisgICAgICogQHJldHVybiB0aGUgbGV2ZWwuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRMZXZlbEF0KGludCBvZmZzZXQpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBvZmZzZXRMZXZlbFtvZmZzZXRdICYgflVCSURJX0xFVkVMX09WRVJSSURFOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBiYXNlTGV2ZWw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgcnVucyBpbiB0aGUgYmlkaXJlY3Rpb25hbCB0ZXh0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHJ1bnMsIGF0IGxlYXN0IDEuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSdW5Db3VudCgpIHsKKyAgICAgICAgcmV0dXJuIHVuaWRpcmVjdGlvbmFsID8gMSA6IHJ1bnMubGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxldmVsIG9mIHRoZSBzcGVjaWZpZWQgcnVuLgorICAgICAqCisgICAgICogQHBhcmFtIHJ1bgorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBydW4uCisgICAgICogQHJldHVybiB0aGUgbGV2ZWwgb2YgdGhlIHJ1bi4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFJ1bkxldmVsKGludCBydW4pIHsKKyAgICAgICAgcmV0dXJuIHVuaWRpcmVjdGlvbmFsID8gYmFzZUxldmVsIDogcnVuc1tydW5dLmdldExldmVsKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGltaXQgb2Zmc2V0IG9mIHRoZSBzcGVjaWZpZWQgcnVuLgorICAgICAqCisgICAgICogQHBhcmFtIHJ1bgorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBydW4uCisgICAgICogQHJldHVybiB0aGUgbGltaXQgb2Zmc2V0IG9mIHRoZSBydW4uCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSdW5MaW1pdChpbnQgcnVuKSB7CisgICAgICAgIHJldHVybiB1bmlkaXJlY3Rpb25hbCA/IGxlbmd0aCA6IHJ1bnNbcnVuXS5nZXRMaW1pdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0YXJ0IG9mZnNldCBvZiB0aGUgc3BlY2lmaWVkIHJ1bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBydW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgcnVuLgorICAgICAqIEByZXR1cm4gdGhlIHN0YXJ0IG9mZnNldCBvZiB0aGUgcnVuLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UnVuU3RhcnQoaW50IHJ1bikgeworICAgICAgICByZXR1cm4gdW5pZGlyZWN0aW9uYWwgPyAwIDogcnVuc1tydW5dLmdldFN0YXJ0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHRleHQgaXMgZnJvbSBsZWZ0IHRvIHJpZ2h0LCB0aGF0IGlzLCBib3RoIHRoZSBiYXNlCisgICAgICogZGlyZWN0aW9uIGFuZCB0aGUgdGV4dCBkaXJlY3Rpb24gaXMgZnJvbSBsZWZ0IHRvIHJpZ2h0LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHRleHQgaXMgZnJvbSBsZWZ0IHRvIHJpZ2h0OyB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNMZWZ0VG9SaWdodCgpIHsKKyAgICAgICAgcmV0dXJuIGRpcmVjdGlvbiA9PSBVQmlEaURpcmVjdGlvbl9VQklESV9MVFI7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHRleHQgZGlyZWN0aW9uIGlzIG1peGVkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHRleHQgZGlyZWN0aW9uIGlzIG1peGVkOyB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNNaXhlZCgpIHsKKyAgICAgICAgcmV0dXJuIGRpcmVjdGlvbiA9PSBVQmlEaURpcmVjdGlvbl9VQklESV9NSVhFRDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgdGV4dCBpcyBmcm9tIHJpZ2h0IHRvIGxlZnQsIHRoYXQgaXMsIGJvdGggdGhlIGJhc2UKKyAgICAgKiBkaXJlY3Rpb24gYW5kIHRoZSB0ZXh0IGRpcmVjdGlvbiBpcyBmcm9tIHJpZ2h0IHRvIGxlZnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgdGV4dCBpcyBmcm9tIHJpZ2h0IHRvIGxlZnQ7IHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1JpZ2h0VG9MZWZ0KCkgeworICAgICAgICByZXR1cm4gZGlyZWN0aW9uID09IFVCaURpRGlyZWN0aW9uX1VCSURJX1JUTDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW9yZGVycyBhIHJhbmdlIG9mIG9iamVjdHMgYWNjb3JkaW5nIHRvIHRoZWlyIHNwZWNpZmllZCBsZXZlbHMuIFRoaXMgaXMKKyAgICAgKiBhIGNvbnZlbmllbmNlIGZ1bmN0aW9uIHRoYXQgZG9lcyBub3QgdXNlIGEge0Bjb2RlIEJpZGl9IG9iamVjdC4gVGhlIHJhbmdlCisgICAgICogb2Ygb2JqZWN0cyBhdCB7QGNvZGUgaW5kZXh9IGZyb20ge0Bjb2RlIG9iamVjdFN0YXJ0fSB0byB7QGNvZGUKKyAgICAgKiBvYmplY3RTdGFydCArIGNvdW50fSB3aWxsIGJlIHJlb3JkZXJlZCBhY2NvcmRpbmcgdG8gdGhlIHJhbmdlIG9mIGxldmVscworICAgICAqIGF0IHtAY29kZSBpbmRleH0gZnJvbSB7QGNvZGUgbGV2ZWxTdGFydH0gdG8ge0Bjb2RlIGxldmVsU3RhcnQgKyBjb3VudH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGV2ZWxzCisgICAgICogICAgICAgICAgICB0aGUgbGV2ZWwgYXJyYXksIHdoaWNoIGlzIGFscmVhZHkgZGV0ZXJtaW5lZC4KKyAgICAgKiBAcGFyYW0gbGV2ZWxTdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IG9mZnNldCBvZiB0aGUgcmFuZ2Ugb2YgdGhlIGxldmVscy4KKyAgICAgKiBAcGFyYW0gb2JqZWN0cworICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCBhcnJheSB0byByZW9yZGVyLgorICAgICAqIEBwYXJhbSBvYmplY3RTdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IG9mZnNldCBvZiB0aGUgcmFuZ2Ugb2Ygb2JqZWN0cy4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb3VudCBvZiB0aGUgcmFuZ2Ugb2Ygb2JqZWN0cyB0byByZW9yZGVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGNvdW50fSwge0Bjb2RlIGxldmVsU3RhcnR9IG9yIHtAY29kZSBvYmplY3RTdGFydH0KKyAgICAgKiAgICAgICAgICAgICBpcyBuZWdhdGl2ZTsgaWYge0Bjb2RlIGNvdW50ID4gbGV2ZWxzLmxlbmd0aCAtIGxldmVsU3RhcnR9IG9yCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGNvdW50ID4gb2JqZWN0cy5sZW5ndGggLSBvYmplY3RTdGFydH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHJlb3JkZXJWaXN1YWxseShieXRlW10gbGV2ZWxzLCBpbnQgbGV2ZWxTdGFydCwKKyAgICAgICAgICAgIE9iamVjdFtdIG9iamVjdHMsIGludCBvYmplY3RTdGFydCwgaW50IGNvdW50KSB7CisgICAgICAgIGlmIChjb3VudCA8IDAgfHwgbGV2ZWxTdGFydCA8IDAgfHwgb2JqZWN0U3RhcnQgPCAwCisgICAgICAgICAgICAgICAgfHwgY291bnQgPiBsZXZlbHMubGVuZ3RoIC0gbGV2ZWxTdGFydAorICAgICAgICAgICAgICAgIHx8IGNvdW50ID4gb2JqZWN0cy5sZW5ndGggLSBvYmplY3RTdGFydCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCByYW5nZXMgKGxldmVscz0iICsgbGV2ZWxzLmxlbmd0aCArCisgICAgICAgICAgICAgICAgICAgICIsIGxldmVsU3RhcnQ9IiArIGxldmVsU3RhcnQgKyAiLCBvYmplY3RzPSIgKyBvYmplY3RzLmxlbmd0aCArCisgICAgICAgICAgICAgICAgICAgICIsIG9iamVjdFN0YXJ0PSIgKyBvYmplY3RTdGFydCArICIsIGNvdW50PSIgKyBjb3VudCArICIpIik7CisgICAgICAgIH0KKworICAgICAgICBieXRlW10gcmVhbExldmVscyA9IG5ldyBieXRlW2NvdW50XTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShsZXZlbHMsIGxldmVsU3RhcnQsIHJlYWxMZXZlbHMsIDAsIGNvdW50KTsKKworICAgICAgICBpbnRbXSBpbmRpY2VzID0gdWJpZGlfcmVvcmRlclZpc3VhbChyZWFsTGV2ZWxzLCBjb3VudCk7CisKKyAgICAgICAgQXJyYXlMaXN0PE9iamVjdD4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxPYmplY3Q+KGNvdW50KTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CisgICAgICAgICAgICByZXN1bHQuYWRkKG9iamVjdHNbb2JqZWN0U3RhcnQgKyBpbmRpY2VzW2ldXSk7CisgICAgICAgIH0KKworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHJlc3VsdC50b0FycmF5KCksIDAsIG9iamVjdHMsIG9iamVjdFN0YXJ0LCBjb3VudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgYSByYW5nZSBvZiBjaGFyYWN0ZXJzIG9mIGEgdGV4dCByZXF1aXJlcyBhIHtAY29kZSBCaWRpfQorICAgICAqIG9iamVjdCB0byBkaXNwbGF5IHByb3Blcmx5LgorICAgICAqCisgICAgICogQHBhcmFtIHRleHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyIGFycmF5IG9mIHRoZSB0ZXh0LgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IG9mZnNldCBvZiB0aGUgcmFuZ2Ugb2YgY2hhcmFjdGVycy4KKyAgICAgKiBAcGFyYW0gbGltaXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaW1pdCBvZmZzZXQgb2YgdGhlIHJhbmdlIG9mIGNoYXJhY3RlcnMuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHJhbmdlIG9mIGNoYXJhY3RlcnMgcmVxdWlyZXMgYSB7QGNvZGUgQmlkaX0KKyAgICAgKiAgICAgICAgIG9iamVjdDsge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnR9IG9yIHtAY29kZSBsaW1pdH0gaXMgbmVnYXRpdmU7IHtAY29kZSBzdGFydCA+CisgICAgICogICAgICAgICAgICAgbGltaXR9IG9yIHtAY29kZSBsaW1pdH0gaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YgdGhpcworICAgICAqICAgICAgICAgICAgIG9iamVjdCdzIHBhcmFncmFwaCB0ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiByZXF1aXJlc0JpZGkoY2hhcltdIHRleHQsIGludCBzdGFydCwgaW50IGxpbWl0KSB7CisgICAgICAgIGlmIChsaW1pdCA8IDAgfHwgc3RhcnQgPCAwIHx8IHN0YXJ0ID4gbGltaXQgfHwgbGltaXQgPiB0ZXh0Lmxlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgQmlkaSBiaWRpID0gbmV3IEJpZGkodGV4dCwgc3RhcnQsIG51bGwsIDAsIGxpbWl0IC0gc3RhcnQsIDApOworICAgICAgICByZXR1cm4gIWJpZGkuaXNMZWZ0VG9SaWdodCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBnZXRDbGFzcygpLmdldE5hbWUoKQorICAgICAgICAgICAgICAgICsgIltkaXJlY3Rpb246ICIgKyBkaXJlY3Rpb24gKyAiIGJhc2VMZXZlbDogIiArIGJhc2VMZXZlbAorICAgICAgICAgICAgICAgICsgIiBsZW5ndGg6ICIgKyBsZW5ndGggKyAiIHJ1bnM6ICIgKyBBcnJheXMudG9TdHJpbmcocnVucykgKyAiXSI7CisgICAgfQorCisgICAgLy8gSUNVNEMgY29uc3RhbnRzLgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVQklESV9MRVZFTF9PVkVSUklERSA9IDB4ODA7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVCaURpRGlyZWN0aW9uX1VCSURJX0xUUiA9IDA7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVCaURpRGlyZWN0aW9uX1VCSURJX1JUTCA9IDE7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVCaURpRGlyZWN0aW9uX1VCSURJX01JWEVEID0gMjsKKworICAgIC8vIElDVTRDIGZ1bmN0aW9ucy4KKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgbG9uZyB1YmlkaV9vcGVuKCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIHZvaWQgdWJpZGlfY2xvc2UobG9uZyBwQmlEaSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIHZvaWQgdWJpZGlfc2V0UGFyYShsb25nIHBCaURpLCBjaGFyW10gdGV4dCwgaW50IGxlbmd0aCwgaW50IHBhcmFMZXZlbCwgYnl0ZVtdIGVtYmVkZGluZ0xldmVscyk7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGxvbmcgdWJpZGlfc2V0TGluZShmaW5hbCBsb25nIHBQYXJhQmlEaSwgaW50IHN0YXJ0LCBpbnQgbGltaXQpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgdWJpZGlfZ2V0RGlyZWN0aW9uKGZpbmFsIGxvbmcgcEJpRGkpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgdWJpZGlfZ2V0TGVuZ3RoKGZpbmFsIGxvbmcgcEJpRGkpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBieXRlIHViaWRpX2dldFBhcmFMZXZlbChmaW5hbCBsb25nIHBCaURpKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgYnl0ZVtdIHViaWRpX2dldExldmVscyhsb25nIHBCaURpKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IHViaWRpX2NvdW50UnVucyhsb25nIHBCaURpKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgQmlkaS5SdW5bXSB1YmlkaV9nZXRSdW5zKGxvbmcgcEJpZGkpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnRbXSB1YmlkaV9yZW9yZGVyVmlzdWFsKGJ5dGVbXSBsZXZlbHMsIGludCBsZW5ndGgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9CcmVha0l0ZXJhdG9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0JyZWFrSXRlcmF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YmM3ZjBjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9CcmVha0l0ZXJhdG9yLmphdmEKQEAgLTAsMCArMSw0OTIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudGV4dDsKKworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgbGliY29yZS5pY3UuSUNVOworaW1wb3J0IGxpYmNvcmUuaWN1Lk5hdGl2ZUJyZWFrSXRlcmF0b3I7CisKKy8qKgorICogTG9jYXRlcyBib3VuZGFyaWVzIGluIHRleHQuIFRoaXMgY2xhc3MgZGVmaW5lcyBhIHByb3RvY29sIGZvciBvYmplY3RzIHRoYXQKKyAqIGJyZWFrIHVwIGEgcGllY2Ugb2YgbmF0dXJhbC1sYW5ndWFnZSB0ZXh0IGFjY29yZGluZyB0byBhIHNldCBvZiBjcml0ZXJpYS4KKyAqIEluc3RhbmNlcyBvciBzdWJjbGFzc2VzIG9mIHtAY29kZSBCcmVha0l0ZXJhdG9yfSBjYW4gYmUgcHJvdmlkZWQsIGZvcgorICogZXhhbXBsZSwgdG8gYnJlYWsgYSBwaWVjZSBvZiB0ZXh0IGludG8gd29yZHMsIHNlbnRlbmNlcywgb3IgbG9naWNhbAorICogY2hhcmFjdGVycyBhY2NvcmRpbmcgdG8gdGhlIGNvbnZlbnRpb25zIG9mIHNvbWUgbGFuZ3VhZ2Ugb3IgZ3JvdXAgb2YKKyAqIGxhbmd1YWdlcy4gV2UgcHJvdmlkZSBmb3VyIGJ1aWx0LWluIHR5cGVzIG9mIHtAY29kZSBCcmVha0l0ZXJhdG9yfToKKyAqIDx1bD4KKyAqIDxsaT57QGxpbmsgI2dldFNlbnRlbmNlSW5zdGFuY2UoKX0gcmV0dXJucyBhIHtAY29kZSBCcmVha0l0ZXJhdG9yfSB0aGF0CisgKiBsb2NhdGVzIGJvdW5kYXJpZXMgYmV0d2VlbiBzZW50ZW5jZXMuIFRoaXMgaXMgdXNlZnVsIGZvciB0cmlwbGUtY2xpY2sKKyAqIHNlbGVjdGlvbiwgZm9yIGV4YW1wbGUuPC9saT4KKyAqIDxsaT57QGxpbmsgI2dldFdvcmRJbnN0YW5jZSgpfSByZXR1cm5zIGEge0Bjb2RlIEJyZWFrSXRlcmF0b3J9IHRoYXQgbG9jYXRlcworICogYm91bmRhcmllcyBiZXR3ZWVuIHdvcmRzLiBUaGlzIGlzIHVzZWZ1bCBmb3IgZG91YmxlLWNsaWNrIHNlbGVjdGlvbiBvciAiZmluZAorICogd2hvbGUgd29yZHMiIHNlYXJjaGVzLiBUaGlzIHR5cGUgb2Yge0Bjb2RlIEJyZWFrSXRlcmF0b3J9IG1ha2VzIHN1cmUgdGhlcmUgaXMKKyAqIGEgYm91bmRhcnkgcG9zaXRpb24gYXQgdGhlIGJlZ2lubmluZyBhbmQgZW5kIG9mIGVhY2ggbGVnYWwgd29yZCAobnVtYmVycworICogY291bnQgYXMgd29yZHMsIHRvbykuIFdoaXRlc3BhY2UgYW5kIHB1bmN0dWF0aW9uIGFyZSBrZXB0IHNlcGFyYXRlIGZyb20gcmVhbAorICogd29yZHMuPC9saT4KKyAqIDxsaT57QGNvZGUgZ2V0TGluZUluc3RhbmNlKCl9IHJldHVybnMgYSB7QGNvZGUgQnJlYWtJdGVyYXRvcn0gdGhhdCBsb2NhdGVzCisgKiBwb3NpdGlvbnMgd2hlcmUgaXQgaXMgbGVnYWwgZm9yIGEgdGV4dCBlZGl0b3IgdG8gd3JhcCBsaW5lcy4gVGhpcyBpcyBzaW1pbGFyCisgKiB0byB3b3JkIGJyZWFraW5nLCBidXQgbm90IHRoZSBzYW1lOiBwdW5jdHVhdGlvbiBhbmQgd2hpdGVzcGFjZSBhcmUgZ2VuZXJhbGx5CisgKiBrZXB0IHdpdGggd29yZHMgKHlvdSBkb24ndCB3YW50IGEgbGluZSB0byBzdGFydCB3aXRoIHdoaXRlc3BhY2UsIGZvcgorICogZXhhbXBsZSksIGFuZCBzb21lIHNwZWNpYWwgY2hhcmFjdGVycyBjYW4gZm9yY2UgYSBwb3NpdGlvbiB0byBiZSBjb25zaWRlcmVkIGEKKyAqIGxpbmUgYnJlYWsgcG9zaXRpb24gb3IgcHJldmVudCBhIHBvc2l0aW9uIGZyb20gYmVpbmcgYSBsaW5lIGJyZWFrIHBvc2l0aW9uLjwvbGk+CisgKiA8bGk+e0Bjb2RlIGdldENoYXJhY3Rlckluc3RhbmNlKCl9IHJldHVybnMgYSB7QGNvZGUgQnJlYWtJdGVyYXRvcn0gdGhhdAorICogbG9jYXRlcyBib3VuZGFyaWVzIGJldHdlZW4gbG9naWNhbCBjaGFyYWN0ZXJzLiBCZWNhdXNlIG9mIHRoZSBzdHJ1Y3R1cmUgb2YKKyAqIHRoZSBVbmljb2RlIGVuY29kaW5nLCBhIGxvZ2ljYWwgY2hhcmFjdGVyIG1heSBiZSBzdG9yZWQgaW50ZXJuYWxseSBhcyBtb3JlCisgKiB0aGFuIG9uZSBVbmljb2RlIGNvZGUgcG9pbnQuIChBIHdpdGggYW4gdW1sYXV0IG1heSBiZSBzdG9yZWQgYXMgYW4gYSBmb2xsb3dlZAorICogYnkgYSBzZXBhcmF0ZSBjb21iaW5pbmcgdW1sYXV0IGNoYXJhY3RlciwgZm9yIGV4YW1wbGUsIGJ1dCB0aGUgdXNlciBzdGlsbAorICogdGhpbmtzIG9mIGl0IGFzIG9uZSBjaGFyYWN0ZXIuKSBUaGlzIGl0ZXJhdG9yIGFsbG93cyB2YXJpb3VzIHByb2Nlc3NlcworICogKGVzcGVjaWFsbHkgdGV4dCBlZGl0b3JzKSB0byB0cmVhdCBhcyBjaGFyYWN0ZXJzIHRoZSB1bml0cyBvZiB0ZXh0IHRoYXQgYQorICogdXNlciB3b3VsZCB0aGluayBvZiBhcyBjaGFyYWN0ZXJzLCByYXRoZXIgdGhhbiB0aGUgdW5pdHMgb2YgdGV4dCB0aGF0IHRoZQorICogY29tcHV0ZXIgc2VlcyBhcyAiY2hhcmFjdGVycyIuPC9saT4KKyAqIDwvdWw+IHtAY29kZSBCcmVha0l0ZXJhdG9yfSdzIGludGVyZmFjZSBmb2xsb3dzIGFuICJpdGVyYXRvciIgbW9kZWwgKGhlbmNlCisgKiB0aGUgbmFtZSksIG1lYW5pbmcgaXQgaGFzIGEgY29uY2VwdCBvZiBhICJjdXJyZW50IHBvc2l0aW9uIiBhbmQgbWV0aG9kcyBsaWtlCisgKiB7QGNvZGUgZmlyc3QoKX0sIHtAY29kZSBsYXN0KCl9LCB7QGNvZGUgbmV4dCgpfSwgYW5kIHtAY29kZSBwcmV2aW91cygpfSB0aGF0CisgKiB1cGRhdGUgdGhlIGN1cnJlbnQgcG9zaXRpb24uIEFsbCB7QGNvZGUgQnJlYWtJdGVyYXRvcn1zIHVwaG9sZCB0aGUgZm9sbG93aW5nCisgKiBpbnZhcmlhbnRzOgorICogPHVsPgorICogPGxpPlRoZSBiZWdpbm5pbmcgYW5kIGVuZCBvZiB0aGUgdGV4dCBhcmUgYWx3YXlzIHRyZWF0ZWQgYXMgYm91bmRhcnkKKyAqIHBvc2l0aW9ucy48L2xpPgorICogPGxpPlRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZSBpdGVyYXRvciBpcyBhbHdheXMgYSBib3VuZGFyeSBwb3NpdGlvbgorICogKHJhbmRvbS0gYWNjZXNzIG1ldGhvZHMgbW92ZSB0aGUgaXRlcmF0b3IgdG8gdGhlIG5lYXJlc3QgYm91bmRhcnkgcG9zaXRpb24KKyAqIGJlZm9yZSBvciBhZnRlciB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uLCBub3QgPGk+dG88L2k+IHRoZSBzcGVjaWZpZWQKKyAqIHBvc2l0aW9uKS48L2xpPgorICogPGxpPntAY29kZSBET05FfSBpcyB1c2VkIGFzIGEgZmxhZyB0byBpbmRpY2F0ZSB3aGVuIGl0ZXJhdGlvbiBoYXMgc3RvcHBlZC4KKyAqIHtAY29kZSBET05FfSBpcyBvbmx5IHJldHVybmVkIHdoZW4gdGhlIGN1cnJlbnQgcG9zaXRpb24gaXMgdGhlIGVuZCBvZiB0aGUKKyAqIHRleHQgYW5kIHRoZSB1c2VyIGNhbGxzIHtAY29kZSBuZXh0KCl9LCBvciB3aGVuIHRoZSBjdXJyZW50IHBvc2l0aW9uIGlzIHRoZQorICogYmVnaW5uaW5nIG9mIHRoZSB0ZXh0IGFuZCB0aGUgdXNlciBjYWxscyB7QGNvZGUgcHJldmlvdXMoKX0uPC9saT4KKyAqIDxsaT5CcmVhayBwb3NpdGlvbnMgYXJlIG51bWJlcmVkIGJ5IHRoZSBwb3NpdGlvbnMgb2YgdGhlIGNoYXJhY3RlcnMgdGhhdAorICogZm9sbG93IHRoZW0uIFRodXMsIHVuZGVyIG5vcm1hbCBjaXJjdW1zdGFuY2VzLCB0aGUgcG9zaXRpb24gYmVmb3JlIHRoZSBmaXJzdAorICogY2hhcmFjdGVyIGlzIDAsIHRoZSBwb3NpdGlvbiBhZnRlciB0aGUgZmlyc3QgY2hhcmFjdGVyIGlzIDEsIGFuZCB0aGUgcG9zaXRpb24KKyAqIGFmdGVyIHRoZSBsYXN0IGNoYXJhY3RlciBpcyAxIHBsdXMgdGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nLjwvbGk+CisgKiA8bGk+VGhlIGNsaWVudCBjYW4gY2hhbmdlIHRoZSBwb3NpdGlvbiBvZiBhbiBpdGVyYXRvciwgb3IgdGhlIHRleHQgaXQKKyAqIGFuYWx5emVzLCBhdCB3aWxsLCBidXQgY2Fubm90IGNoYW5nZSB0aGUgYmVoYXZpb3IuIElmIHRoZSB1c2VyIHdhbnRzCisgKiBkaWZmZXJlbnQgYmVoYXZpb3IsIGhlIG11c3QgaW5zdGFudGlhdGUgYSBuZXcgaXRlcmF0b3IuPC9saT4KKyAqIDwvdWw+CisgKiA8cD4KKyAqIHtAY29kZSBCcmVha0l0ZXJhdG9yfSBhY2Nlc3NlcyB0aGUgdGV4dCBpdCBhbmFseXplcyB0aHJvdWdoIGEKKyAqIHtAbGluayBDaGFyYWN0ZXJJdGVyYXRvcn0sIHdoaWNoIG1ha2VzIGl0IHBvc3NpYmxlIHRvIHVzZSB7QGNvZGUKKyAqIEJyZWFrSXRlcmF0b3J9IHRvIGFuYWx5emUgdGV4dCBpbiBhbnkgdGV4dC1zdG9yYWdlIHZlaGljbGUgdGhhdCBwcm92aWRlcyBhCisgKiB7QGNvZGUgQ2hhcmFjdGVySXRlcmF0b3J9IGludGVyZmFjZS4KKyAqIDxwPgorICogPGVtPk5vdGU6PC9lbT4gU29tZSB0eXBlcyBvZiB7QGNvZGUgQnJlYWtJdGVyYXRvcn0gY2FuIHRha2UgYSBsb25nIHRpbWUgdG8KKyAqIGNyZWF0ZSwgYW5kIGluc3RhbmNlcyBvZiB7QGNvZGUgQnJlYWtJdGVyYXRvcn0gYXJlIG5vdCBjdXJyZW50bHkgY2FjaGVkIGJ5CisgKiB0aGUgc3lzdGVtLiBGb3Igb3B0aW1hbCBwZXJmb3JtYW5jZSwga2VlcCBpbnN0YW5jZXMgb2Yge0Bjb2RlIEJyZWFrSXRlcmF0b3J9CisgKiBhcm91bmQgYXMgbG9uZyBhcyBpdCBtYWtlcyBzZW5zZS4gRm9yIGV4YW1wbGUsIHdoZW4gd29yZC13cmFwcGluZyBhIGRvY3VtZW50LAorICogZG9uJ3QgY3JlYXRlIGFuZCBkZXN0cm95IGEgbmV3IHtAY29kZSBCcmVha0l0ZXJhdG9yfSBmb3IgZWFjaCBsaW5lLiBDcmVhdGUKKyAqIG9uZSBicmVhayBpdGVyYXRvciBmb3IgdGhlIHdob2xlIGRvY3VtZW50IChvciB3aGF0ZXZlciBzdHJldGNoIG9mIHRleHQgeW91J3JlCisgKiB3cmFwcGluZykgYW5kIHVzZSBpdCB0byBkbyB0aGUgd2hvbGUgam9iIG9mIHdyYXBwaW5nIHRoZSB0ZXh0LgorICogPHA+CisgKiA8ZW0+RXhhbXBsZXM8L2VtPjoKKyAqIDxwPgorICogQ3JlYXRpbmcgYW5kIHVzaW5nIHRleHQgYm91bmRhcmllczoKKyAqIDxibG9ja3F1b3RlPgorICoKKyAqIDxwcmU+CisgKiBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJnc1tdKSB7CisgKiAgICAgaWYgKGFyZ3MubGVuZ3RoID09IDEpIHsKKyAqICAgICAgICAgU3RyaW5nIHN0cmluZ1RvRXhhbWluZSA9IGFyZ3NbMF07CisgKiAgICAgICAgIC8vcHJpbnQgZWFjaCB3b3JkIGluIG9yZGVyCisgKiAgICAgICAgIEJyZWFrSXRlcmF0b3IgYm91bmRhcnkgPSBCcmVha0l0ZXJhdG9yLmdldFdvcmRJbnN0YW5jZSgpOworICogICAgICAgICBib3VuZGFyeS5zZXRUZXh0KHN0cmluZ1RvRXhhbWluZSk7CisgKiAgICAgICAgIHByaW50RWFjaEZvcndhcmQoYm91bmRhcnksIHN0cmluZ1RvRXhhbWluZSk7CisgKiAgICAgICAgIC8vcHJpbnQgZWFjaCBzZW50ZW5jZSBpbiByZXZlcnNlIG9yZGVyCisgKiAgICAgICAgIGJvdW5kYXJ5ID0gQnJlYWtJdGVyYXRvci5nZXRTZW50ZW5jZUluc3RhbmNlKExvY2FsZS5VUyk7CisgKiAgICAgICAgIGJvdW5kYXJ5LnNldFRleHQoc3RyaW5nVG9FeGFtaW5lKTsKKyAqICAgICAgICAgcHJpbnRFYWNoQmFja3dhcmQoYm91bmRhcnksIHN0cmluZ1RvRXhhbWluZSk7CisgKiAgICAgICAgIHByaW50Rmlyc3QoYm91bmRhcnksIHN0cmluZ1RvRXhhbWluZSk7CisgKiAgICAgICAgIHByaW50TGFzdChib3VuZGFyeSwgc3RyaW5nVG9FeGFtaW5lKTsKKyAqICAgICB9CisgKiB9CisgKiA8L3ByZT4KKyAqCisgKiA8L2Jsb2NrcXVvdGU+CisgKiA8cD4KKyAqIFByaW50IGVhY2ggZWxlbWVudCBpbiBvcmRlcjoKKyAqIDxibG9ja3F1b3RlPgorICoKKyAqIDxwcmU+CisgKiBwdWJsaWMgc3RhdGljIHZvaWQgcHJpbnRFYWNoRm9yd2FyZChCcmVha0l0ZXJhdG9yIGJvdW5kYXJ5LCBTdHJpbmcgc291cmNlKSB7CisgKiAgICAgaW50IHN0YXJ0ID0gYm91bmRhcnkuZmlyc3QoKTsKKyAqICAgICBmb3IgKGludCBlbmQgPSBib3VuZGFyeS5uZXh0KCk7IGVuZCAhPSBCcmVha0l0ZXJhdG9yLkRPTkU7IHN0YXJ0ID0gZW5kLCBlbmQgPSBib3VuZGFyeS5uZXh0KCkpIHsKKyAqICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKHNvdXJjZS5zdWJzdHJpbmcoc3RhcnQsIGVuZCkpOworICogICAgIH0KKyAqIH0KKyAqIDwvcHJlPgorICoKKyAqIDwvYmxvY2txdW90ZT4KKyAqIDxwPgorICogUHJpbnQgZWFjaCBlbGVtZW50IGluIHJldmVyc2Ugb3JkZXI6CisgKiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogcHVibGljIHN0YXRpYyB2b2lkIHByaW50RWFjaEJhY2t3YXJkKEJyZWFrSXRlcmF0b3IgYm91bmRhcnksIFN0cmluZyBzb3VyY2UpIHsKKyAqICAgICBpbnQgZW5kID0gYm91bmRhcnkubGFzdCgpOworICogICAgIGZvciAoaW50IHN0YXJ0ID0gYm91bmRhcnkucHJldmlvdXMoKTsgc3RhcnQgIT0gQnJlYWtJdGVyYXRvci5ET05FOyBlbmQgPSBzdGFydCwgc3RhcnQgPSBib3VuZGFyeQorICogICAgICAgICAgICAgLnByZXZpb3VzKCkpIHsKKyAqICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKHNvdXJjZS5zdWJzdHJpbmcoc3RhcnQsIGVuZCkpOworICogICAgIH0KKyAqIH0KKyAqIDwvcHJlPgorICoKKyAqIDwvYmxvY2txdW90ZT4KKyAqIDxwPgorICogUHJpbnQgdGhlIGZpcnN0IGVsZW1lbnQ6CisgKiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogcHVibGljIHN0YXRpYyB2b2lkIHByaW50Rmlyc3QoQnJlYWtJdGVyYXRvciBib3VuZGFyeSwgU3RyaW5nIHNvdXJjZSkgeworICogICAgIGludCBzdGFydCA9IGJvdW5kYXJ5LmZpcnN0KCk7CisgKiAgICAgaW50IGVuZCA9IGJvdW5kYXJ5Lm5leHQoKTsKKyAqICAgICBTeXN0ZW0ub3V0LnByaW50bG4oc291cmNlLnN1YnN0cmluZyhzdGFydCwgZW5kKSk7CisgKiB9CisgKiA8L3ByZT4KKyAqCisgKiA8L2Jsb2NrcXVvdGU+CisgKiA8cD4KKyAqIFByaW50IHRoZSBsYXN0IGVsZW1lbnQ6CisgKiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogcHVibGljIHN0YXRpYyB2b2lkIHByaW50TGFzdChCcmVha0l0ZXJhdG9yIGJvdW5kYXJ5LCBTdHJpbmcgc291cmNlKSB7CisgKiAgICAgaW50IGVuZCA9IGJvdW5kYXJ5Lmxhc3QoKTsKKyAqICAgICBpbnQgc3RhcnQgPSBib3VuZGFyeS5wcmV2aW91cygpOworICogICAgIFN5c3RlbS5vdXQucHJpbnRsbihzb3VyY2Uuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpKTsKKyAqIH0KKyAqIDwvcHJlPgorICoKKyAqIDwvYmxvY2txdW90ZT4KKyAqIDxwPgorICogUHJpbnQgdGhlIGVsZW1lbnQgYXQgYSBzcGVjaWZpZWQgcG9zaXRpb246CisgKiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogcHVibGljIHN0YXRpYyB2b2lkIHByaW50QXQoQnJlYWtJdGVyYXRvciBib3VuZGFyeSwgaW50IHBvcywgU3RyaW5nIHNvdXJjZSkgeworICogICAgIGludCBlbmQgPSBib3VuZGFyeS5mb2xsb3dpbmcocG9zKTsKKyAqICAgICBpbnQgc3RhcnQgPSBib3VuZGFyeS5wcmV2aW91cygpOworICogICAgIFN5c3RlbS5vdXQucHJpbnRsbihzb3VyY2Uuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpKTsKKyAqIH0KKyAqIDwvcHJlPgorICoKKyAqIDwvYmxvY2txdW90ZT4KKyAqIDxwPgorICogRmluZCB0aGUgbmV4dCB3b3JkOgorICogPGJsb2NrcXVvdGU+CisgKgorICogPHByZT4KKyAqIHB1YmxpYyBzdGF0aWMgaW50IG5leHRXb3JkU3RhcnRBZnRlcihpbnQgcG9zLCBTdHJpbmcgdGV4dCkgeworICogICAgIEJyZWFrSXRlcmF0b3Igd2IgPSBCcmVha0l0ZXJhdG9yLmdldFdvcmRJbnN0YW5jZSgpOworICogICAgIHdiLnNldFRleHQodGV4dCk7CisgKiAgICAgaW50IGxhc3QgPSB3Yi5mb2xsb3dpbmcocG9zKTsKKyAqICAgICBpbnQgY3VycmVudCA9IHdiLm5leHQoKTsKKyAqICAgICB3aGlsZSAoY3VycmVudCAhPSBCcmVha0l0ZXJhdG9yLkRPTkUpIHsKKyAqICAgICAgICAgZm9yIChpbnQgcCA9IGxhc3Q7IHAgJmx0OyBjdXJyZW50OyBwKyspIHsKKyAqICAgICAgICAgICAgIGlmIChDaGFyYWN0ZXIuaXNMZXR0ZXIodGV4dC5jaGFyQXQocCkpKQorICogICAgICAgICAgICAgICAgIHJldHVybiBsYXN0OworICogICAgICAgICB9CisgKiAgICAgICAgIGxhc3QgPSBjdXJyZW50OworICogICAgICAgICBjdXJyZW50ID0gd2IubmV4dCgpOworICogICAgIH0KKyAqICAgICByZXR1cm4gQnJlYWtJdGVyYXRvci5ET05FOworICogfQorICogPC9wcmU+CisgKgorICogPC9ibG9ja3F1b3RlPgorICogPHA+CisgKiBUaGUgaXRlcmF0b3IgcmV0dXJuZWQgYnkge0Bjb2RlIEJyZWFrSXRlcmF0b3IuZ2V0V29yZEluc3RhbmNlKCl9IGlzIHVuaXF1ZSBpbgorICogdGhhdCB0aGUgYnJlYWsgcG9zaXRpb25zIGl0IHJldHVybnMgZG9uJ3QgcmVwcmVzZW50IGJvdGggdGhlIHN0YXJ0IGFuZCBlbmQgb2YKKyAqIHRoZSB0aGluZyBiZWluZyBpdGVyYXRlZCBvdmVyLiBUaGF0IGlzLCBhIHNlbnRlbmNlLWJyZWFrIGl0ZXJhdG9yIHJldHVybnMKKyAqIGJyZWFrcyB0aGF0IGVhY2ggcmVwcmVzZW50IHRoZSBlbmQgb2Ygb25lIHNlbnRlbmNlIGFuZCB0aGUgYmVnaW5uaW5nIG9mIHRoZQorICogbmV4dC4gV2l0aCB0aGUgd29yZC1icmVhayBpdGVyYXRvciwgdGhlIGNoYXJhY3RlcnMgYmV0d2VlbiB0d28gYm91bmRhcmllcworICogbWlnaHQgYmUgYSB3b3JkLCBvciB0aGV5IG1pZ2h0IGJlIHRoZSBwdW5jdHVhdGlvbiBvciB3aGl0ZXNwYWNlIGJldHdlZW4gdHdvCisgKiB3b3Jkcy4gVGhlIGFib3ZlIGNvZGUgdXNlcyBhIHNpbXBsZSBoZXVyaXN0aWMgdG8gZGV0ZXJtaW5lIHdoaWNoIGJvdW5kYXJ5IGlzCisgKiB0aGUgYmVnaW5uaW5nIG9mIGEgd29yZDogSWYgdGhlIGNoYXJhY3RlcnMgYmV0d2VlbiB0aGlzIGJvdW5kYXJ5IGFuZCB0aGUgbmV4dAorICogYm91bmRhcnkgaW5jbHVkZSBhdCBsZWFzdCBvbmUgbGV0dGVyICh0aGlzIGNhbiBiZSBhbiBhbHBoYWJldGljYWwgbGV0dGVyLCBhCisgKiBDSksgaWRlb2dyYXBoLCBhIEhhbmd1bCBzeWxsYWJsZSwgYSBLYW5hIGNoYXJhY3RlciwgZXRjLiksIHRoZW4gdGhlIHRleHQKKyAqIGJldHdlZW4gdGhpcyBib3VuZGFyeSBhbmQgdGhlIG5leHQgaXMgYSB3b3JkOyBvdGhlcndpc2UsIGl0J3MgdGhlIG1hdGVyaWFsCisgKiBiZXR3ZWVuIHdvcmRzLikKKyAqCisgKiBAc2VlIENoYXJhY3Rlckl0ZXJhdG9yCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBCcmVha0l0ZXJhdG9yIGltcGxlbWVudHMgQ2xvbmVhYmxlIHsKKworICAgIC8qKgorICAgICAqIFRoaXMgY29uc3RhbnQgaXMgcmV0dXJuZWQgYnkgaXRlcmF0ZSBtZXRob2RzIGxpa2Uge0Bjb2RlIHByZXZpb3VzKCl9IG9yCisgICAgICoge0Bjb2RlIG5leHQoKX0gaWYgdGhleSBoYXZlIHJldHVybmVkIGFsbCB2YWxpZCBib3VuZGFyaWVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERPTkUgPSAtMTsKKworICAgIC8vIHRoZSB3cmFwcGVkIElDVSBpbXBsZW1lbnRhdGlvbgorICAgIE5hdGl2ZUJyZWFrSXRlcmF0b3Igd3JhcHBlZDsKKworICAgIC8qKgorICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IsIGZvciB1c2UgYnkgc3ViY2xhc3Nlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQnJlYWtJdGVyYXRvcigpIHsKKyAgICB9CisKKyAgICAvKgorICAgICAqIHdyYXBwaW5nIGNvbnN0cnVjdG9yCisgICAgICovCisgICAgQnJlYWtJdGVyYXRvcihOYXRpdmVCcmVha0l0ZXJhdG9yIGl0ZXJhdG9yKSB7CisgICAgICAgIHdyYXBwZWQgPSBpdGVyYXRvcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGxvY2FsZXMgZm9yIHdoaWNoIGN1c3RvbSB7QGNvZGUgQnJlYWtJdGVyYXRvcn0gaW5zdGFuY2VzCisgICAgICogYXJlIGF2YWlsYWJsZS4KKyAgICAgKiA8cD5Ob3RlIHRoYXQgQW5kcm9pZCBkb2VzIG5vdCBzdXBwb3J0IHVzZXItc3VwcGxpZWQgbG9jYWxlIHNlcnZpY2UgcHJvdmlkZXJzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTG9jYWxlW10gZ2V0QXZhaWxhYmxlTG9jYWxlcygpIHsKKyAgICAgICAgcmV0dXJuIElDVS5nZXRBdmFpbGFibGVCcmVha0l0ZXJhdG9yTG9jYWxlcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEJyZWFrSXRlcmF0b3J9IHRvIGl0ZXJhdGUgb3ZlcgorICAgICAqIGNoYXJhY3RlcnMgdXNpbmcgdGhlIHVzZXIncyBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKiBTZWUgIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgQnJlYWtJdGVyYXRvcn0gdXNpbmcgdGhlIGRlZmF1bHQgbG9jYWxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQnJlYWtJdGVyYXRvciBnZXRDaGFyYWN0ZXJJbnN0YW5jZSgpIHsKKyAgICAgICAgcmV0dXJuIGdldENoYXJhY3Rlckluc3RhbmNlKExvY2FsZS5nZXREZWZhdWx0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEJyZWFrSXRlcmF0b3J9IHRvIGl0ZXJhdGUgb3ZlcgorICAgICAqIGNoYXJhY3RlcnMgdXNpbmcgdGhlIGdpdmVuIGxvY2FsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB3aGVyZQorICAgICAqICAgICAgICAgICAgdGhlIGdpdmVuIGxvY2FsZS4KKyAgICAgKiBAcmV0dXJuIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBCcmVha0l0ZXJhdG9yfSB1c2luZyB0aGUgZ2l2ZW4gbG9jYWxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQnJlYWtJdGVyYXRvciBnZXRDaGFyYWN0ZXJJbnN0YW5jZShMb2NhbGUgd2hlcmUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yKE5hdGl2ZUJyZWFrSXRlcmF0b3IuZ2V0Q2hhcmFjdGVySW5zdGFuY2Uod2hlcmUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHt7QGNvZGUgQnJlYWtJdGVyYXRvcn0gdG8gaXRlcmF0ZSBvdmVyCisgICAgICogbGluZSBicmVha3MgdXNpbmcgdGhlIHVzZXIncyBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKiBTZWUgIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgQnJlYWtJdGVyYXRvcn0gdXNpbmcgdGhlIGRlZmF1bHQgbG9jYWxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQnJlYWtJdGVyYXRvciBnZXRMaW5lSW5zdGFuY2UoKSB7CisgICAgICAgIHJldHVybiBnZXRMaW5lSW5zdGFuY2UoTG9jYWxlLmdldERlZmF1bHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgQnJlYWtJdGVyYXRvcn0gdG8gaXRlcmF0ZSBvdmVyCisgICAgICogbGluZSBicmVha3MgdXNpbmcgdGhlIGdpdmVuIGxvY2FsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB3aGVyZQorICAgICAqICAgICAgICAgICAgdGhlIGdpdmVuIGxvY2FsZS4KKyAgICAgKiBAcmV0dXJuIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBCcmVha0l0ZXJhdG9yfSB1c2luZyB0aGUgZ2l2ZW4gbG9jYWxlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIHdoZXJlfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCcmVha0l0ZXJhdG9yIGdldExpbmVJbnN0YW5jZShMb2NhbGUgd2hlcmUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yKE5hdGl2ZUJyZWFrSXRlcmF0b3IuZ2V0TGluZUluc3RhbmNlKHdoZXJlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgQnJlYWtJdGVyYXRvcn0gdG8gaXRlcmF0ZSBvdmVyCisgICAgICogc2VudGVuY2UtYnJlYWtzIHVzaW5nIHRoZSBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKiBTZWUgIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgQnJlYWtJdGVyYXRvcn0gdXNpbmcgdGhlIGRlZmF1bHQgbG9jYWxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQnJlYWtJdGVyYXRvciBnZXRTZW50ZW5jZUluc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gZ2V0U2VudGVuY2VJbnN0YW5jZShMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBCcmVha0l0ZXJhdG9yfSB0byBpdGVyYXRlIG92ZXIKKyAgICAgKiBzZW50ZW5jZS1icmVha3MgdXNpbmcgdGhlIGdpdmVuIGxvY2FsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB3aGVyZQorICAgICAqICAgICAgICAgICAgdGhlIGdpdmVuIGxvY2FsZS4KKyAgICAgKiBAcmV0dXJuIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBCcmVha0l0ZXJhdG9yfSB1c2luZyB0aGUgZ2l2ZW4gbG9jYWxlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIHdoZXJlfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCcmVha0l0ZXJhdG9yIGdldFNlbnRlbmNlSW5zdGFuY2UoTG9jYWxlIHdoZXJlKSB7CisgICAgICAgIHJldHVybiBuZXcgUnVsZUJhc2VkQnJlYWtJdGVyYXRvcihOYXRpdmVCcmVha0l0ZXJhdG9yLmdldFNlbnRlbmNlSW5zdGFuY2Uod2hlcmUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBCcmVha0l0ZXJhdG9yfSB0byBpdGVyYXRlIG92ZXIKKyAgICAgKiB3b3JkLWJyZWFrcyB1c2luZyB0aGUgZGVmYXVsdCBsb2NhbGUuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqIEByZXR1cm4gYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEJyZWFrSXRlcmF0b3J9IHVzaW5nIHRoZSBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEJyZWFrSXRlcmF0b3IgZ2V0V29yZEluc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gZ2V0V29yZEluc3RhbmNlKExvY2FsZS5nZXREZWZhdWx0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEJyZWFrSXRlcmF0b3J9IHRvIGl0ZXJhdGUgb3ZlcgorICAgICAqIHdvcmQtYnJlYWtzIHVzaW5nIHRoZSBnaXZlbiBsb2NhbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gd2hlcmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBnaXZlbiBsb2NhbGUuCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgQnJlYWtJdGVyYXRvcn0gdXNpbmcgdGhlIGdpdmVuIGxvY2FsZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSB3aGVyZX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQnJlYWtJdGVyYXRvciBnZXRXb3JkSW5zdGFuY2UoTG9jYWxlIHdoZXJlKSB7CisgICAgICAgIHJldHVybiBuZXcgUnVsZUJhc2VkQnJlYWtJdGVyYXRvcihOYXRpdmVCcmVha0l0ZXJhdG9yLmdldFdvcmRJbnN0YW5jZSh3aGVyZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBnaXZlbiBvZmZzZXQgaXMgYSBib3VuZGFyeSBwb3NpdGlvbi4gSWYgdGhpcyBtZXRob2QKKyAgICAgKiByZXR1cm5zIHRydWUsIHRoZSBjdXJyZW50IGl0ZXJhdGlvbiBwb3NpdGlvbiBpcyBzZXQgdG8gdGhlIGdpdmVuCisgICAgICogcG9zaXRpb247IGlmIHRoZSBmdW5jdGlvbiByZXR1cm5zIGZhbHNlLCB0aGUgY3VycmVudCBpdGVyYXRpb24gcG9zaXRpb24KKyAgICAgKiBpcyBzZXQgYXMgdGhvdWdoIHtAbGluayAjZm9sbG93aW5nKGludCl9IGhhZCBiZWVuIGNhbGxlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBnaXZlbiBvZmZzZXQgdG8gY2hlY2suCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGdpdmVuIG9mZnNldCBpcyBhIGJvdW5kYXJ5IHBvc2l0aW9uOyB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNCb3VuZGFyeShpbnQgb2Zmc2V0KSB7CisgICAgICAgIHJldHVybiB3cmFwcGVkLmlzQm91bmRhcnkob2Zmc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwb3NpdGlvbiBvZiBsYXN0IGJvdW5kYXJ5IHByZWNlZGluZyB0aGUgZ2l2ZW4gb2Zmc2V0LCBhbmQKKyAgICAgKiBzZXRzIHRoZSBjdXJyZW50IHBvc2l0aW9uIHRvIHRoZSByZXR1cm5lZCB2YWx1ZSwgb3Ige0Bjb2RlIERPTkV9IGlmIHRoZQorICAgICAqIGdpdmVuIG9mZnNldCBzcGVjaWZpZXMgdGhlIHN0YXJ0aW5nIHBvc2l0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGdpdmVuIHN0YXJ0IHBvc2l0aW9uIHRvIGJlIHNlYXJjaGVkIGZvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBwb3NpdGlvbiBvZiB0aGUgbGFzdCBib3VuZGFyeSBwcmVjZWRpbmcgdGhlIGdpdmVuIG9mZnNldC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYgdGhlIG9mZnNldCBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgcHJlY2VkaW5nKGludCBvZmZzZXQpIHsKKyAgICAgICAgcmV0dXJuIHdyYXBwZWQucHJlY2VkaW5nKG9mZnNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmV3IHRleHQgc3RyaW5nIHRvIGJlIGFuYWx5emVkLCB0aGUgY3VycmVudCBwb3NpdGlvbiB3aWxsIGJlCisgICAgICogcmVzZXQgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGlzIG5ldyBzdHJpbmcsIGFuZCB0aGUgb2xkIHN0cmluZyB3aWxsIGJlCisgICAgICogbG9zdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdUZXh0CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHRleHQgc3RyaW5nIHRvIGJlIGFuYWx5emVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRleHQoU3RyaW5nIG5ld1RleHQpIHsKKyAgICAgICAgd3JhcHBlZC5zZXRUZXh0KG5ld1RleHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBpdGVyYXRvcidzIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgaXRlcmF0b3IncyBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgY3VycmVudCgpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGlzIGl0ZXJhdG9yJ3MgY3VycmVudCBwb3NpdGlvbiB0byB0aGUgZmlyc3QgYm91bmRhcnkgYW5kIHJldHVybnMKKyAgICAgKiB0aGF0IHBvc2l0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IGJvdW5kYXJ5LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZmlyc3QoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHBvc2l0aW9uIG9mIHRoZSBmaXJzdCBib3VuZGFyeSB0byB0aGUgb25lIGZvbGxvd2luZyB0aGUgZ2l2ZW4KKyAgICAgKiBvZmZzZXQgYW5kIHJldHVybnMgdGhpcyBwb3NpdGlvbi4gUmV0dXJucyB7QGNvZGUgRE9ORX0gaWYgdGhlcmUgaXMgbm8KKyAgICAgKiBib3VuZGFyeSBhZnRlciB0aGUgZ2l2ZW4gb2Zmc2V0LgorICAgICAqCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGdpdmVuIHBvc2l0aW9uIHRvIGJlIHNlYXJjaGVkIGZvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBwb3NpdGlvbiBvZiB0aGUgZmlyc3QgYm91bmRhcnkgZm9sbG93aW5nIHRoZSBnaXZlbiBvZmZzZXQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIGlmIHRoZSBvZmZzZXQgaXMgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGZvbGxvd2luZyhpbnQgb2Zmc2V0KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgQ2hhcmFjdGVySXRlcmF0b3J9IHdoaWNoIHJlcHJlc2VudHMgdGhlIHRleHQgYmVpbmcKKyAgICAgKiBhbmFseXplZC4gUGxlYXNlIG5vdGUgdGhhdCB0aGUgcmV0dXJuZWQgdmFsdWUgaXMgcHJvYmFibHkgdGhlIGludGVybmFsCisgICAgICogaXRlcmF0b3IgdXNlZCBieSB0aGlzIG9iamVjdC4gSWYgdGhlIGludm9rZXIgd2FudHMgdG8gbW9kaWZ5IHRoZSBzdGF0dXMKKyAgICAgKiBvZiB0aGUgcmV0dXJuZWQgaXRlcmF0b3IsIGl0IGlzIHJlY29tbWVuZGVkIHRvIGZpcnN0IGNyZWF0ZSBhIGNsb25lIG9mCisgICAgICogdGhlIGl0ZXJhdG9yIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiBhIHtAY29kZSBDaGFyYWN0ZXJJdGVyYXRvcn0gd2hpY2ggcmVwcmVzZW50cyB0aGUgdGV4dCBiZWluZworICAgICAqICAgICAgICAgYW5hbHl6ZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENoYXJhY3Rlckl0ZXJhdG9yIGdldFRleHQoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhpcyBpdGVyYXRvcidzIGN1cnJlbnQgcG9zaXRpb24gdG8gdGhlIGxhc3QgYm91bmRhcnkgYW5kIHJldHVybnMKKyAgICAgKiB0aGF0IHBvc2l0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcG9zaXRpb24gb2YgbGFzdCBib3VuZGFyeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGxhc3QoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhpcyBpdGVyYXRvcidzIGN1cnJlbnQgcG9zaXRpb24gdG8gdGhlIG5leHQgYm91bmRhcnkgYWZ0ZXIgdGhlCisgICAgICogY3VycmVudCBwb3NpdGlvbiwgYW5kIHJldHVybnMgdGhpcyBwb3NpdGlvbi4gUmV0dXJucyB7QGNvZGUgRE9ORX0gaWYgbm8KKyAgICAgKiBib3VuZGFyeSB3YXMgZm91bmQgYWZ0ZXIgdGhlIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwb3NpdGlvbiBvZiBsYXN0IGJvdW5kYXJ5LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgbmV4dCgpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGlzIGl0ZXJhdG9yJ3MgY3VycmVudCBwb3NpdGlvbiB0byB0aGUgbmV4dCBib3VuZGFyeSBhZnRlciB0aGUKKyAgICAgKiBnaXZlbiBwb3NpdGlvbiwgYW5kIHJldHVybnMgdGhhdCBwb3NpdGlvbi4gUmV0dXJucyB7QGNvZGUgRE9ORX0gaWYgbm8KKyAgICAgKiBib3VuZGFyeSB3YXMgZm91bmQgYWZ0ZXIgdGhlIGdpdmVuIHBvc2l0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIG4KKyAgICAgKiAgICAgICAgICAgIHRoZSBnaXZlbiBwb3NpdGlvbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBwb3NpdGlvbiBvZiBsYXN0IGJvdW5kYXJ5LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgbmV4dChpbnQgbik7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoaXMgaXRlcmF0b3IncyBjdXJyZW50IHBvc2l0aW9uIHRvIHRoZSBwcmV2aW91cyBib3VuZGFyeSBiZWZvcmUgdGhlCisgICAgICogY3VycmVudCBwb3NpdGlvbiBhbmQgcmV0dXJucyB0aGF0IHBvc2l0aW9uLiBSZXR1cm5zIHtAY29kZSBET05FfSBpZgorICAgICAqIG5vIGJvdW5kYXJ5IHdhcyBmb3VuZCBiZWZvcmUgdGhlIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwb3NpdGlvbiBvZiBsYXN0IGJvdW5kYXJ5LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgcHJldmlvdXMoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5ldyB0ZXh0IHRvIGJlIGFuYWx5emVkIGJ5IHRoZSBnaXZlbiB7QGNvZGUgQ2hhcmFjdGVySXRlcmF0b3J9LgorICAgICAqIFRoZSBwb3NpdGlvbiB3aWxsIGJlIHJlc2V0IHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIG5ldyB0ZXh0LCBhbmQgb3RoZXIKKyAgICAgKiBzdGF0dXMgaW5mb3JtYXRpb24gb2YgdGhpcyBpdGVyYXRvciB3aWxsIGJlIGtlcHQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3VGV4dAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDaGFyYWN0ZXJJdGVyYXRvcn0gcmVmZXJyaW5nIHRvIHRoZSB0ZXh0IHRvIGJlCisgICAgICogICAgICAgICAgICBhbmFseXplZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRUZXh0KENoYXJhY3Rlckl0ZXJhdG9yIG5ld1RleHQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhpcyBpdGVyYXRvci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgQnJlYWtJdGVyYXRvciBjbG9uZWQgPSAoQnJlYWtJdGVyYXRvcikgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgICAgIGNsb25lZC53cmFwcGVkID0gKE5hdGl2ZUJyZWFrSXRlcmF0b3IpIHdyYXBwZWQuY2xvbmUoKTsKKyAgICAgICAgICAgIHJldHVybiBjbG9uZWQ7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvQ2hhcmFjdGVySXRlcmF0b3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvQ2hhcmFjdGVySXRlcmF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOTljMzQ0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9DaGFyYWN0ZXJJdGVyYXRvci5qYXZhCkBAIC0wLDAgKzEsMTE2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnRleHQ7CisKKy8qKgorICogQW4gaW50ZXJmYWNlIGZvciB0aGUgYmlkaXJlY3Rpb25hbCBpdGVyYXRpb24gb3ZlciBhIGdyb3VwIG9mIGNoYXJhY3RlcnMuIFRoZQorICogaXRlcmF0aW9uIHN0YXJ0cyBhdCB0aGUgYmVnaW4gaW5kZXggaW4gdGhlIGdyb3VwIG9mIGNoYXJhY3RlcnMgYW5kIGNvbnRpbnVlcworICogdG8gb25lIGluZGV4IGJlZm9yZSB0aGUgZW5kIGluZGV4LgorICovCitwdWJsaWMgaW50ZXJmYWNlIENoYXJhY3Rlckl0ZXJhdG9yIGV4dGVuZHMgQ2xvbmVhYmxlIHsKKworICAgIC8qKgorICAgICAqIEEgY29uc3RhbnQgd2hpY2ggaW5kaWNhdGVzIHRoYXQgdGhlcmUgaXMgbm8gY2hhcmFjdGVyIGF0IHRoZSBjdXJyZW50CisgICAgICogaW5kZXguCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjaGFyIERPTkUgPSAnXHVmZmZmJzsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIENoYXJhY3Rlckl0ZXJhdG9yfSB3aXRoIHRoZSBzYW1lIHByb3BlcnRpZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc2hhbGxvdyBjb3B5IG9mIHRoaXMgY2hhcmFjdGVyIGl0ZXJhdG9yLgorICAgICAqCisgICAgICogQHNlZSBqYXZhLmxhbmcuQ2xvbmVhYmxlCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2hhcmFjdGVyIGF0IHRoZSBjdXJyZW50IGluZGV4LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY3VycmVudCBjaGFyYWN0ZXIsIG9yIHtAY29kZSBET05FfSBpZiB0aGUgY3VycmVudCBpbmRleCBpcworICAgICAqICAgICAgICAgcGFzdCB0aGUgYmVnaW5uaW5nIG9yIGVuZCBvZiB0aGUgc2VxdWVuY2UuCisgICAgICovCisgICAgcHVibGljIGNoYXIgY3VycmVudCgpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY3VycmVudCBwb3NpdGlvbiB0byB0aGUgYmVnaW4gaW5kZXggYW5kIHJldHVybnMgdGhlIGNoYXJhY3RlciBhdAorICAgICAqIHRoZSBuZXcgcG9zaXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIGJlZ2luIGluZGV4LgorICAgICAqLworICAgIHB1YmxpYyBjaGFyIGZpcnN0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBiZWdpbiBpbmRleC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIGl0ZXJhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEJlZ2luSW5kZXgoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGVuZCBpbmRleC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9uZSBwYXN0IHRoZSBsYXN0IGNoYXJhY3RlciBvZiB0aGUgaXRlcmF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RW5kSW5kZXgoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgaW5kZXguCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IGluZGV4LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXgoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGN1cnJlbnQgcG9zaXRpb24gdG8gdGhlIGVuZCBpbmRleCAtIDEgYW5kIHJldHVybnMgdGhlIGNoYXJhY3RlcgorICAgICAqIGF0IHRoZSBuZXcgcG9zaXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFyYWN0ZXIgYmVmb3JlIHRoZSBlbmQgaW5kZXguCisgICAgICovCisgICAgcHVibGljIGNoYXIgbGFzdCgpOworCisgICAgLyoqCisgICAgICogSW5jcmVtZW50cyB0aGUgY3VycmVudCBpbmRleCBhbmQgcmV0dXJucyB0aGUgY2hhcmFjdGVyIGF0IHRoZSBuZXcgaW5kZXguCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIG5leHQgaW5kZXgsIG9yIHtAY29kZSBET05FfSBpZiB0aGUgbmV4dAorICAgICAqICAgICAgICAgaW5kZXggd291bGQgYmUgcGFzdCB0aGUgZW5kLgorICAgICAqLworICAgIHB1YmxpYyBjaGFyIG5leHQoKTsKKworICAgIC8qKgorICAgICAqIERlY3JlbWVudHMgdGhlIGN1cnJlbnQgaW5kZXggYW5kIHJldHVybnMgdGhlIGNoYXJhY3RlciBhdCB0aGUgbmV3IGluZGV4LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2hhcmFjdGVyIGF0IHRoZSBwcmV2aW91cyBpbmRleCwgb3Ige0Bjb2RlIERPTkV9IGlmIHRoZQorICAgICAqICAgICAgICAgcHJldmlvdXMgaW5kZXggd291bGQgYmUgcGFzdCB0aGUgYmVnaW5uaW5nLgorICAgICAqLworICAgIHB1YmxpYyBjaGFyIHByZXZpb3VzKCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjdXJyZW50IGluZGV4IHRvIGEgbmV3IHBvc2l0aW9uIGFuZCByZXR1cm5zIHRoZSBjaGFyYWN0ZXIgYXQgdGhlCisgICAgICogbmV3IGluZGV4LgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2F0aW9uCisgICAgICogICAgICAgICAgICB0aGUgbmV3IGluZGV4IHRoYXQgdGhpcyBjaGFyYWN0ZXIgaXRlcmF0b3IgaXMgc2V0IHRvLgorICAgICAqIEByZXR1cm4gdGhlIGNoYXJhY3RlciBhdCB0aGUgbmV3IGluZGV4LCBvciB7QGNvZGUgRE9ORX0gaWYgdGhlIGluZGV4IGlzCisgICAgICogICAgICAgICBwYXN0IHRoZSBlbmQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgIGlmIHtAY29kZSBsb2NhdGlvbn0gaXMgbGVzcyB0aGFuIHRoZSBiZWdpbiBpbmRleCBvciBncmVhdGVyIHRoYW4KKyAgICAgKiAgICAgICAgIHRoZSBlbmQgaW5kZXguCisgICAgICovCisgICAgcHVibGljIGNoYXIgc2V0SW5kZXgoaW50IGxvY2F0aW9uKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvQ2hvaWNlRm9ybWF0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0Nob2ljZUZvcm1hdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwYTEyMzkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0Nob2ljZUZvcm1hdC5qYXZhCkBAIC0wLDAgKzEsNDc1IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuRW1wdHlBcnJheTsKKworLyoqCisgKiBSZXR1cm5zIGEgZml4ZWQgc3RyaW5nIGJhc2VkIG9uIGEgbnVtZXJpYyB2YWx1ZS4gVGhlIGNsYXNzIGNhbiBiZSB1c2VkIGluCisgKiBjb25qdW5jdGlvbiB3aXRoIHRoZSB7QGxpbmsgTWVzc2FnZUZvcm1hdH0gY2xhc3MgdG8gaGFuZGxlIHBsdXJhbHMgaW4KKyAqIG1lc3NhZ2VzLiB7QGNvZGUgQ2hvaWNlRm9ybWF0fSBlbmFibGVzIHVzZXJzIHRvIGF0dGFjaCBhIGZvcm1hdCB0byBhIHJhbmdlIG9mCisgKiBudW1iZXJzLiBUaGUgY2hvaWNlIGlzIHNwZWNpZmllZCB3aXRoIGFuIGFzY2VuZGluZyBsaXN0IG9mIGRvdWJsZXMsIHdoZXJlCisgKiBlYWNoIGl0ZW0gc3BlY2lmaWVzIGEgaGFsZi1vcGVuIGludGVydmFsIHVwIHRvIHRoZSBuZXh0IGl0ZW0gYXMgaW4gdGhlCisgKiBmb2xsb3dpbmc6IFggbWF0Y2hlcyBqIGlmIGFuZCBvbmx5IGlmIHtAY29kZSBsaW1pdFtqXSA8PSBYIDwgbGltaXRbaisxXX0uCisgKiA8cD4KKyAqIElmIHRoZXJlIGlzIG5vIG1hdGNoLCB0aGVuIGVpdGhlciB0aGUgZmlyc3Qgb3IgbGFzdCBpbmRleCBpcyB1c2VkLiBUaGUgZmlyc3QKKyAqIG9yIGxhc3QgaW5kZXggaXMgdXNlZCBkZXBlbmRpbmcgb24gd2hldGhlciB0aGUgbnVtYmVyIGlzIHRvbyBsb3cgb3IgdG9vIGhpZ2guCisgKiBUaGUgbGVuZ3RoIG9mIHRoZSBmb3JtYXQgYXJyYXkgbXVzdCBiZSB0aGUgc2FtZSBhcyB0aGUgbGVuZ3RoIG9mIHRoZSBsaW1pdHMKKyAqIGFycmF5LgorICogPGg1PkV4YW1wbGVzOjwvaDU+CisgKiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogZG91YmxlW10gbGltaXRzID0gezEsIDIsIDMsIDQsIDUsIDYsIDd9OworICogU3RyaW5nW10gZm10cyA9IHsiU3VuIiwgIk1vbiIsICJUdWUiLCAiV2VkIiwgIlRodXIiLCAiRnJpIiwgIlNhdCJ9OworICoKKyAqIGRvdWJsZVtdIGxpbWl0czIgPSB7MCwgMSwgQ2hvaWNlRm9ybWF0Lm5leHREb3VibGUoMSl9OworICogU3RyaW5nW10gZm10czIgPSB7Im5vIGZpbGVzIiwgIm9uZSBmaWxlIiwgIm1hbnkgZmlsZXMifTsKKyAqIDwvcHJlPgorICogPC9ibG9ja3F1b3RlPgorICogPHA+CisgKiBDaG9pY2VGb3JtYXQubmV4dERvdWJsZShkb3VibGUpIGFsbG93cyB0byBnZXQgdGhlIGRvdWJsZSBmb2xsb3dpbmcgdGhlIG9uZQorICogcGFzc2VkIHRvIHRoZSBtZXRob2QuIFRoaXMgaXMgdXNlZCB0byBjcmVhdGUgaGFsZiBvcGVuIGludGVydmFscy4KKyAqIDxwPgorICoge0Bjb2RlIENob2ljZUZvcm1hdH0gb2JqZWN0cyBhbHNvIG1heSBiZSBjb252ZXJ0ZWQgdG8gYW5kIGZyb20gcGF0dGVybnMuCisgKiBUaGUgY29udmVyc2lvbiBjYW4gYmUgZG9uZSBwcm9ncmFtbWF0aWNhbGx5LCBhcyBpbiB0aGUgZXhhbXBsZSBhYm92ZSwgb3IKKyAqIGJ5IHVzaW5nIGEgcGF0dGVybiBsaWtlIHRoZSBmb2xsb3dpbmc6CisgKiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogIjEjU3VufDIjTW9ufDMjVHVlfDQjV2VkfDUjVGh1cnw2I0ZyaXw3I1NhdCIKKyAqICIwI2FyZSBubyBmaWxlc3wxI2lzIG9uZSBmaWxlfDEmbHQ7YXJlIG1hbnkgZmlsZXMiCisgKiA8L3ByZT4KKyAqCisgKiA8L2Jsb2NrcXVvdGU+CisgKiA8cD4KKyAqIHdoZXJlOgorICogPHVsPgorICogPGxpPjxudW1iZXI+IiMiPC9udW1iZXI+IHNwZWNpZmllcyBhbiBpbmNsdXNpdmUgbGltaXQgdmFsdWU7PC9saT4KKyAqIDxsaT48bnVtYmVyPiI8IjwvbnVtYmVyPiBzcGVjaWZpZXMgYW4gZXhjbHVzaXZlIGxpbWl0IHZhbHVlLjwvbGk+CisgKiA8L3VsPgorICovCitwdWJsaWMgY2xhc3MgQ2hvaWNlRm9ybWF0IGV4dGVuZHMgTnVtYmVyRm9ybWF0IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDE3OTUxODQ0NDk2NDUwMzI5NjRMOworCisgICAgcHJpdmF0ZSBkb3VibGVbXSBjaG9pY2VMaW1pdHM7CisKKyAgICBwcml2YXRlIFN0cmluZ1tdIGNob2ljZUZvcm1hdHM7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBDaG9pY2VGb3JtYXR9IHdpdGggdGhlIHNwZWNpZmllZCBkb3VibGUgdmFsdWVzCisgICAgICogYW5kIGFzc29jaWF0ZWQgc3RyaW5ncy4gV2hlbiBjYWxsaW5nCisgICAgICoge0BsaW5rICNmb3JtYXQoZG91YmxlLCBTdHJpbmdCdWZmZXIsIEZpZWxkUG9zaXRpb24pIGZvcm1hdH0gd2l0aCBhIGRvdWJsZQorICAgICAqIHZhbHVlIHtAY29kZSBkfSwgdGhlbiB0aGUgZWxlbWVudCB7QGNvZGUgaX0gaW4ge0Bjb2RlIGZvcm1hdHN9IGlzCisgICAgICogc2VsZWN0ZWQgd2hlcmUge0Bjb2RlIGl9IGZ1bGZpbGxzIHtAY29kZSBsaW1pdHNbaV0gPD0gZCA8IGxpbWl0c1tpKzFdfS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbGVuZ3RoIG9mIHRoZSB7QGNvZGUgbGltaXRzfSBhbmQge0Bjb2RlIGZvcm1hdHN9IGFycmF5cyBtdXN0IGJlIHRoZQorICAgICAqIHNhbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGltaXRzCisgICAgICogICAgICAgICAgICBhbiBhcnJheSBvZiBkb3VibGVzIGluIGFzY2VuZGluZyBvcmRlci4gVGhlIGxvd2VzdCBhbmQgaGlnaGVzdAorICAgICAqICAgICAgICAgICAgcG9zc2libGUgdmFsdWVzIGFyZSBuZWdhdGl2ZSBhbmQgcG9zaXRpdmUgaW5maW5pdHkuCisgICAgICogQHBhcmFtIGZvcm1hdHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmdzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmFuZ2VzIGRlZmluZWQgdGhyb3VnaCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIGxpbWl0c30uIFRoZSBsb3dlciBib3VuZCBvZiB0aGUgYXNzb2NpYXRlZCByYW5nZSBpcyBhdCB0aGUKKyAgICAgKiAgICAgICAgICAgIHNhbWUgaW5kZXggYXMgdGhlIHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2hvaWNlRm9ybWF0KGRvdWJsZVtdIGxpbWl0cywgU3RyaW5nW10gZm9ybWF0cykgeworICAgICAgICBzZXRDaG9pY2VzKGxpbWl0cywgZm9ybWF0cyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQ2hvaWNlRm9ybWF0fSB3aXRoIHRoZSBzdHJpbmdzIGFuZCBsaW1pdHMgcGFyc2VkCisgICAgICogZnJvbSB0aGUgc3BlY2lmaWVkIHBhdHRlcm4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGVtcGxhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXR0ZXJuIG9mIHN0cmluZ3MgYW5kIHJhbmdlcy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHBhcnNpbmcgdGhlIHBhdHRlcm4uCisgICAgICovCisgICAgcHVibGljIENob2ljZUZvcm1hdChTdHJpbmcgdGVtcGxhdGUpIHsKKyAgICAgICAgYXBwbHlQYXR0ZXJuKHRlbXBsYXRlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgdGhlIHBhdHRlcm4gdG8gZGV0ZXJtaW5lIG5ldyBzdHJpbmdzIGFuZCByYW5nZXMgZm9yIHRoaXMKKyAgICAgKiB7QGNvZGUgQ2hvaWNlRm9ybWF0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0ZW1wbGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHBhdHRlcm4gb2Ygc3RyaW5ncyBhbmQgcmFuZ2VzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcGFyc2luZyB0aGUgcGF0dGVybi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhcHBseVBhdHRlcm4oU3RyaW5nIHRlbXBsYXRlKSB7CisgICAgICAgIGRvdWJsZVtdIGxpbWl0cyA9IG5ldyBkb3VibGVbNV07CisgICAgICAgIExpc3Q8U3RyaW5nPiBmb3JtYXRzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGludCBsZW5ndGggPSB0ZW1wbGF0ZS5sZW5ndGgoKSwgbGltaXRDb3VudCA9IDAsIGluZGV4ID0gMDsKKyAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgTnVtYmVyRm9ybWF0IGZvcm1hdCA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZShMb2NhbGUuVVMpOworICAgICAgICBQYXJzZVBvc2l0aW9uIHBvc2l0aW9uID0gbmV3IFBhcnNlUG9zaXRpb24oMCk7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBpbmRleCA9IHNraXBXaGl0ZXNwYWNlKHRlbXBsYXRlLCBpbmRleCk7CisgICAgICAgICAgICBpZiAoaW5kZXggPj0gbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgaWYgKGxpbWl0Q291bnQgPT0gbGltaXRzLmxlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICBjaG9pY2VMaW1pdHMgPSBsaW1pdHM7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgY2hvaWNlTGltaXRzID0gbmV3IGRvdWJsZVtsaW1pdENvdW50XTsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShsaW1pdHMsIDAsIGNob2ljZUxpbWl0cywgMCwgbGltaXRDb3VudCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNob2ljZUZvcm1hdHMgPSBuZXcgU3RyaW5nW2Zvcm1hdHMuc2l6ZSgpXTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZvcm1hdHMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgY2hvaWNlRm9ybWF0c1tpXSA9IGZvcm1hdHMuZ2V0KGkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHBvc2l0aW9uLnNldEluZGV4KGluZGV4KTsKKyAgICAgICAgICAgIE51bWJlciB2YWx1ZSA9IGZvcm1hdC5wYXJzZSh0ZW1wbGF0ZSwgcG9zaXRpb24pOworICAgICAgICAgICAgaW5kZXggPSBza2lwV2hpdGVzcGFjZSh0ZW1wbGF0ZSwgcG9zaXRpb24uZ2V0SW5kZXgoKSk7CisgICAgICAgICAgICBpZiAocG9zaXRpb24uZ2V0RXJyb3JJbmRleCgpICE9IC0xIHx8IGluZGV4ID49IGxlbmd0aCkgeworICAgICAgICAgICAgICAgIC8vIEZpeCBIYXJtb255IDU0MAorICAgICAgICAgICAgICAgIGNob2ljZUxpbWl0cyA9IEVtcHR5QXJyYXkuRE9VQkxFOworICAgICAgICAgICAgICAgIGNob2ljZUZvcm1hdHMgPSBFbXB0eUFycmF5LlNUUklORzsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjaGFyIGNoID0gdGVtcGxhdGUuY2hhckF0KGluZGV4KyspOworICAgICAgICAgICAgaWYgKGxpbWl0Q291bnQgPT0gbGltaXRzLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIGRvdWJsZVtdIG5ld0xpbWl0cyA9IG5ldyBkb3VibGVbbGltaXRDb3VudCAqIDJdOworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobGltaXRzLCAwLCBuZXdMaW1pdHMsIDAsIGxpbWl0Q291bnQpOworICAgICAgICAgICAgICAgIGxpbWl0cyA9IG5ld0xpbWl0czsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGRvdWJsZSBuZXh0OworICAgICAgICAgICAgc3dpdGNoIChjaCkgeworICAgICAgICAgICAgICAgIGNhc2UgJyMnOgorICAgICAgICAgICAgICAgIGNhc2UgJ1x1MjI2NCc6CisgICAgICAgICAgICAgICAgICAgIG5leHQgPSB2YWx1ZS5kb3VibGVWYWx1ZSgpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICc8JzoKKyAgICAgICAgICAgICAgICAgICAgbmV4dCA9IG5leHREb3VibGUodmFsdWUuZG91YmxlVmFsdWUoKSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChsaW1pdENvdW50ID4gMCAmJiBuZXh0IDw9IGxpbWl0c1tsaW1pdENvdW50IC0gMV0pIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBidWZmZXIuc2V0TGVuZ3RoKDApOworICAgICAgICAgICAgcG9zaXRpb24uc2V0SW5kZXgoaW5kZXgpOworICAgICAgICAgICAgdXBUbyh0ZW1wbGF0ZSwgcG9zaXRpb24sIGJ1ZmZlciwgJ3wnKTsKKyAgICAgICAgICAgIGluZGV4ID0gcG9zaXRpb24uZ2V0SW5kZXgoKTsKKyAgICAgICAgICAgIGxpbWl0c1tsaW1pdENvdW50KytdID0gbmV4dDsKKyAgICAgICAgICAgIGZvcm1hdHMuYWRkKGJ1ZmZlci50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIENob2ljZUZvcm1hdH0gd2l0aCB0aGUgc2FtZSByYW5nZXMgYW5kCisgICAgICogc3RyaW5ncyBhcyB0aGlzIHtAY29kZSBDaG9pY2VGb3JtYXR9LgorICAgICAqCisgICAgICogQHJldHVybiBhIHNoYWxsb3cgY29weSBvZiB0aGlzIHtAY29kZSBDaG9pY2VGb3JtYXR9LgorICAgICAqCisgICAgICogQHNlZSBqYXZhLmxhbmcuQ2xvbmVhYmxlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgQ2hvaWNlRm9ybWF0IGNsb25lID0gKENob2ljZUZvcm1hdCkgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgY2xvbmUuY2hvaWNlTGltaXRzID0gY2hvaWNlTGltaXRzLmNsb25lKCk7CisgICAgICAgIGNsb25lLmNob2ljZUZvcm1hdHMgPSBjaG9pY2VGb3JtYXRzLmNsb25lKCk7CisgICAgICAgIHJldHVybiBjbG9uZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIG9iamVjdCB3aXRoIHRoaXMge0Bjb2RlIENob2ljZUZvcm1hdH0uIFRoZSBvYmplY3QKKyAgICAgKiBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIHtAY29kZSBDaG9pY2VGb3JtYXR9IGFuZCBoYXZlIHRoZSBzYW1lIGxpbWl0cyBhbmQKKyAgICAgKiBmb3JtYXRzIHRvIGJlIGVxdWFsIHRvIHRoaXMgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUgd2l0aCB0aGlzIGluc3RhbmNlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMgaW5zdGFuY2U7CisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNoYXNoQ29kZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmICh0aGlzID09IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCEob2JqZWN0IGluc3RhbmNlb2YgQ2hvaWNlRm9ybWF0KSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIENob2ljZUZvcm1hdCBjaG9pY2UgPSAoQ2hvaWNlRm9ybWF0KSBvYmplY3Q7CisgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKGNob2ljZUxpbWl0cywgY2hvaWNlLmNob2ljZUxpbWl0cykKKyAgICAgICAgICAgICAgICAmJiBBcnJheXMuZXF1YWxzKGNob2ljZUZvcm1hdHMsIGNob2ljZS5jaG9pY2VGb3JtYXRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHRoZSBzdHJpbmcgYXNzb2NpYXRlZCB3aXRoIHRoZSByYW5nZSBpbiB3aGljaCB0aGUgc3BlY2lmaWVkCisgICAgICogZG91YmxlIHZhbHVlIGZpdHMgdG8gdGhlIHNwZWNpZmllZCBzdHJpbmcgYnVmZmVyLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgZG91YmxlIHRvIGZvcm1hdC4KKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IHN0cmluZyBidWZmZXIgdG8gYXBwZW5kIHRoZSBmb3JtYXR0ZWQgdmFsdWUgdG8uCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBGaWVsZFBvc2l0aW9ufSB3aGljaCBpcyBpZ25vcmVkLgorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyBidWZmZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ0J1ZmZlciBmb3JtYXQoZG91YmxlIHZhbHVlLCBTdHJpbmdCdWZmZXIgYnVmZmVyLAorICAgICAgICAgICAgRmllbGRQb3NpdGlvbiBmaWVsZCkgeworICAgICAgICBmb3IgKGludCBpID0gY2hvaWNlTGltaXRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7CisgICAgICAgICAgICBpZiAoY2hvaWNlTGltaXRzW2ldIDw9IHZhbHVlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlci5hcHBlbmQoY2hvaWNlRm9ybWF0c1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNob2ljZUZvcm1hdHMubGVuZ3RoID09IDAgPyBidWZmZXIgOiBidWZmZXIKKyAgICAgICAgICAgICAgICAuYXBwZW5kKGNob2ljZUZvcm1hdHNbMF0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlIHN0cmluZyBhc3NvY2lhdGVkIHdpdGggdGhlIHJhbmdlIGluIHdoaWNoIHRoZSBzcGVjaWZpZWQgbG9uZworICAgICAqIHZhbHVlIGZpdHMgdG8gdGhlIHNwZWNpZmllZCBzdHJpbmcgYnVmZmVyLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbG9uZyB0byBmb3JtYXQuCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBzdHJpbmcgYnVmZmVyIHRvIGFwcGVuZCB0aGUgZm9ybWF0dGVkIHZhbHVlIHRvLgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgYSB7QGNvZGUgRmllbGRQb3NpdGlvbn0gd2hpY2ggaXMgaWdub3JlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgYnVmZmVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgZm9ybWF0KGxvbmcgdmFsdWUsIFN0cmluZ0J1ZmZlciBidWZmZXIsCisgICAgICAgICAgICBGaWVsZFBvc2l0aW9uIGZpZWxkKSB7CisgICAgICAgIHJldHVybiBmb3JtYXQoKGRvdWJsZSkgdmFsdWUsIGJ1ZmZlciwgZmllbGQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0cmluZ3MgYXNzb2NpYXRlZCB3aXRoIHRoZSByYW5nZXMgb2YgdGhpcyB7QGNvZGUKKyAgICAgKiBDaG9pY2VGb3JtYXR9LgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBmb3JtYXQgc3RyaW5ncy4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0W10gZ2V0Rm9ybWF0cygpIHsKKyAgICAgICAgcmV0dXJuIGNob2ljZUZvcm1hdHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGltaXRzIG9mIHRoaXMge0Bjb2RlIENob2ljZUZvcm1hdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBkb3VibGVzIHdoaWNoIG1ha2UgdXAgdGhlIGxpbWl0cyBvZiB0aGlzIHtAY29kZQorICAgICAqICAgICAgICAgQ2hvaWNlRm9ybWF0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlW10gZ2V0TGltaXRzKCkgeworICAgICAgICByZXR1cm4gY2hvaWNlTGltaXRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW50ZWdlciBoYXNoIGNvZGUgZm9yIHRoZSByZWNlaXZlci4gT2JqZWN0cyB3aGljaCBhcmUgZXF1YWwKKyAgICAgKiByZXR1cm4gdGhlIHNhbWUgdmFsdWUgZm9yIHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBoYXNoLgorICAgICAqCisgICAgICogQHNlZSAjZXF1YWxzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IGhhc2hDb2RlID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaG9pY2VMaW1pdHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGxvbmcgdiA9IERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGNob2ljZUxpbWl0c1tpXSk7CisgICAgICAgICAgICBoYXNoQ29kZSArPSAoaW50KSAodiBeICh2ID4+PiAzMikpICsgY2hvaWNlRm9ybWF0c1tpXS5oYXNoQ29kZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBoYXNoQ29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkb3VibGUgdmFsdWUgd2hpY2ggaXMgY2xvc2VzdCB0byB0aGUgc3BlY2lmaWVkIGRvdWJsZSBidXQKKyAgICAgKiBsYXJnZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIGEgZG91YmxlIHZhbHVlLgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgbGFyZ2VyIGRvdWJsZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGRvdWJsZSBuZXh0RG91YmxlKGRvdWJsZSB2YWx1ZSkgeworICAgICAgICBpZiAodmFsdWUgPT0gRG91YmxlLlBPU0lUSVZFX0lORklOSVRZKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICAgIH0KKyAgICAgICAgbG9uZyBiaXRzOworICAgICAgICAvLyBIYW5kbGUgLTAuMAorICAgICAgICBpZiAodmFsdWUgPT0gMCkgeworICAgICAgICAgICAgYml0cyA9IDA7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBiaXRzID0gRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHModmFsdWUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBEb3VibGUubG9uZ0JpdHNUb0RvdWJsZSh2YWx1ZSA8IDAgPyBiaXRzIC0gMSA6IGJpdHMgKyAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkb3VibGUgdmFsdWUgd2hpY2ggaXMgY2xvc2VzdCB0byB0aGUgc3BlY2lmaWVkIGRvdWJsZSBidXQKKyAgICAgKiBlaXRoZXIgbGFyZ2VyIG9yIHNtYWxsZXIgYXMgc3BlY2lmaWVkLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICBhIGRvdWJsZSB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gaW5jcmVtZW50CisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gdG8gZ2V0IHRoZSBuZXh0IGxhcmdlciB2YWx1ZSwge0Bjb2RlIGZhbHNlfSB0bworICAgICAqICAgICAgICAgICAgZ2V0IHRoZSBwcmV2aW91cyBzbWFsbGVyIHZhbHVlLgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgbGFyZ2VyIG9yIHNtYWxsZXIgZG91YmxlIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIG5leHREb3VibGUoZG91YmxlIHZhbHVlLCBib29sZWFuIGluY3JlbWVudCkgeworICAgICAgICByZXR1cm4gaW5jcmVtZW50ID8gbmV4dERvdWJsZSh2YWx1ZSkgOiBwcmV2aW91c0RvdWJsZSh2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIGEgZG91YmxlIGZyb20gdGhlIHNwZWNpZmllZCBzdHJpbmcgc3RhcnRpbmcgYXQgdGhlIGluZGV4IHNwZWNpZmllZAorICAgICAqIGJ5IHtAY29kZSBwb3NpdGlvbn0uIFRoZSBzdHJpbmcgaXMgY29tcGFyZWQgdG8gdGhlIHN0cmluZ3Mgb2YgdGhpcworICAgICAqIHtAY29kZSBDaG9pY2VGb3JtYXR9IGFuZCBpZiBhIG1hdGNoIG9jY3VycyB0aGVuIHRoZSBsb3dlciBib3VuZCBvZiB0aGUKKyAgICAgKiBjb3JyZXNwb25kaW5nIHJhbmdlIGluIHRoZSBsaW1pdHMgYXJyYXkgaXMgcmV0dXJuZWQuIElmIHRoZSBzdHJpbmcgaXMKKyAgICAgKiBzdWNjZXNzZnVsbHkgcGFyc2VkIHRoZW4gdGhlIGluZGV4IG9mIHRoZSB7QGNvZGUgUGFyc2VQb3NpdGlvbn0gcGFzc2VkIHRvCisgICAgICogdGhpcyBtZXRob2QgaXMgdXBkYXRlZCB0byB0aGUgaW5kZXggZm9sbG93aW5nIHRoZSBwYXJzZWQgdGV4dC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiBvbmUgb2YgdGhlIGZvcm1hdCBzdHJpbmdzIG9mIHRoaXMge0Bjb2RlIENob2ljZUZvcm1hdH0gaW5zdGFuY2UgaXMKKyAgICAgKiBmb3VuZCBpbiB7QGNvZGUgc3RyaW5nfSBzdGFydGluZyBhdCB7QGNvZGUgcG9zaXRpb24uZ2V0SW5kZXgoKX0gdGhlbgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+dGhlIGluZGV4IGluIHtAY29kZSBwb3NpdGlvbn0gaXMgc2V0IHRvIHRoZSBpbmRleCBmb2xsb3dpbmcgdGhlCisgICAgICogcGFyc2VkIHRleHQ7CisgICAgICogPGxpPnRoZSB7QGxpbmsgamF2YS5sYW5nLkRvdWJsZSBEb3VibGV9IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGZvcm1hdAorICAgICAqIHN0cmluZyBpcyByZXR1cm5lZC48L2xpPgorICAgICAqIDwvdWw+CisgICAgICogPHA+CisgICAgICogSWYgbm9uZSBvZiB0aGUgZm9ybWF0IHN0cmluZ3MgaXMgZm91bmQgaW4ge0Bjb2RlIHN0cmluZ30gdGhlbgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+dGhlIGVycm9yIGluZGV4IGluIHtAY29kZSBwb3NpdGlvbn0gaXMgc2V0IHRvIHRoZSBjdXJyZW50IGluZGV4IGluCisgICAgICoge0Bjb2RlIHBvc2l0aW9ufTs8L2xpPgorICAgICAqIDxsaT4ge0BsaW5rIGphdmEubGFuZy5Eb3VibGUjTmFOIERvdWJsZS5OYU59IGlzIHJldHVybmVkLgorICAgICAqIDwvdWw+CisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBzdHJpbmcgdG8gcGFyc2UuCisgICAgICogQHBhcmFtIHBvc2l0aW9uCisgICAgICogICAgICAgICAgICBpbnB1dC9vdXRwdXQgcGFyYW1ldGVyLCBzcGVjaWZpZXMgdGhlIHN0YXJ0IGluZGV4IGluIHtAY29kZQorICAgICAqICAgICAgICAgICAgc3RyaW5nfSBmcm9tIHdoZXJlIHRvIHN0YXJ0IHBhcnNpbmcuIFNlZSB0aGUgPGVtPlJldHVybnM8L2VtPgorICAgICAqICAgICAgICAgICAgc2VjdGlvbiBmb3IgYSBkZXNjcmlwdGlvbiBvZiB0aGUgb3V0cHV0IHZhbHVlcy4KKyAgICAgKiBAcmV0dXJuIGEgRG91YmxlIHJlc3VsdGluZyBmcm9tIHRoZSBwYXJzZSwgb3IgRG91YmxlLk5hTiBpZiB0aGVyZSBpcyBhbgorICAgICAqICAgICAgICAgZXJyb3IKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTnVtYmVyIHBhcnNlKFN0cmluZyBzdHJpbmcsIFBhcnNlUG9zaXRpb24gcG9zaXRpb24pIHsKKyAgICAgICAgaW50IG9mZnNldCA9IHBvc2l0aW9uLmdldEluZGV4KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2hvaWNlRm9ybWF0cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKHN0cmluZy5zdGFydHNXaXRoKGNob2ljZUZvcm1hdHNbaV0sIG9mZnNldCkpIHsKKyAgICAgICAgICAgICAgICBwb3NpdGlvbi5zZXRJbmRleChvZmZzZXQgKyBjaG9pY2VGb3JtYXRzW2ldLmxlbmd0aCgpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IERvdWJsZShjaG9pY2VMaW1pdHNbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHBvc2l0aW9uLnNldEVycm9ySW5kZXgob2Zmc2V0KTsKKyAgICAgICAgcmV0dXJuIG5ldyBEb3VibGUoRG91YmxlLk5hTik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZG91YmxlIHZhbHVlIHdoaWNoIGlzIGNsb3Nlc3QgdG8gdGhlIHNwZWNpZmllZCBkb3VibGUgYnV0CisgICAgICogc21hbGxlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgYSBkb3VibGUgdmFsdWUuCisgICAgICogQHJldHVybiB0aGUgbmV4dCBzbWFsbGVyIGRvdWJsZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGRvdWJsZSBwcmV2aW91c0RvdWJsZShkb3VibGUgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlID09IERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSkgeworICAgICAgICAgICAgcmV0dXJuIHZhbHVlOworICAgICAgICB9CisgICAgICAgIGxvbmcgYml0czsKKyAgICAgICAgLy8gSGFuZGxlIDAuMAorICAgICAgICBpZiAodmFsdWUgPT0gMCkgeworICAgICAgICAgICAgYml0cyA9IDB4ODAwMDAwMDAwMDAwMDAwMEw7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBiaXRzID0gRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHModmFsdWUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBEb3VibGUubG9uZ0JpdHNUb0RvdWJsZSh2YWx1ZSA8PSAwID8gYml0cyArIDEgOiBiaXRzIC0gMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZG91YmxlIHZhbHVlcyBhbmQgYXNzb2NpYXRlZCBzdHJpbmdzIG9mIHRoaXMgQ2hvaWNlRm9ybWF0LiBXaGVuCisgICAgICogY2FsbGluZyB7QGxpbmsgI2Zvcm1hdChkb3VibGUsIFN0cmluZ0J1ZmZlciwgRmllbGRQb3NpdGlvbikgZm9ybWF0fSB3aXRoCisgICAgICogYSBkb3VibGUgdmFsdWUge0Bjb2RlIGR9LCB0aGVuIHRoZSBlbGVtZW50IHtAY29kZSBpfSBpbiB7QGNvZGUgZm9ybWF0c30KKyAgICAgKiBpcyBzZWxlY3RlZCB3aGVyZSB7QGNvZGUgaX0gZnVsZmlsbHMKKyAgICAgKiB7QGNvZGUgbGltaXRzW2ldIDw9IGQgPCBsaW1pdHNbaSsxXX0uCisgICAgICogPHA+CisgICAgICogVGhlIGxlbmd0aCBvZiB0aGUge0Bjb2RlIGxpbWl0c30gYW5kIHtAY29kZSBmb3JtYXRzfSBhcnJheXMgbXVzdCBiZSB0aGUKKyAgICAgKiBzYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIGxpbWl0cworICAgICAqICAgICAgICAgICAgYW4gYXJyYXkgb2YgZG91YmxlcyBpbiBhc2NlbmRpbmcgb3JkZXIuIFRoZSBsb3dlc3QgYW5kIGhpZ2hlc3QKKyAgICAgKiAgICAgICAgICAgIHBvc3NpYmxlIHZhbHVlcyBhcmUgbmVnYXRpdmUgYW5kIHBvc2l0aXZlIGluZmluaXR5LgorICAgICAqIEBwYXJhbSBmb3JtYXRzCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5ncyBhc3NvY2lhdGVkIHdpdGggdGhlIHJhbmdlcyBkZWZpbmVkIHRocm91Z2gge0Bjb2RlCisgICAgICogICAgICAgICAgICBsaW1pdHN9LiBUaGUgbG93ZXIgYm91bmQgb2YgdGhlIGFzc29jaWF0ZWQgcmFuZ2UgaXMgYXQgdGhlCisgICAgICogICAgICAgICAgICBzYW1lIGluZGV4IGFzIHRoZSBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q2hvaWNlcyhkb3VibGVbXSBsaW1pdHMsIFN0cmluZ1tdIGZvcm1hdHMpIHsKKyAgICAgICAgaWYgKGxpbWl0cy5sZW5ndGggIT0gZm9ybWF0cy5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBjaG9pY2VMaW1pdHMgPSBsaW1pdHM7CisgICAgICAgIGNob2ljZUZvcm1hdHMgPSBmb3JtYXRzOworICAgIH0KKworICAgIHByaXZhdGUgaW50IHNraXBXaGl0ZXNwYWNlKFN0cmluZyBzdHJpbmcsIGludCBpbmRleCkgeworICAgICAgICBpbnQgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aCgpOworICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGggJiYgQ2hhcmFjdGVyLmlzV2hpdGVzcGFjZShzdHJpbmcuY2hhckF0KGluZGV4KSkpIHsKKyAgICAgICAgICAgIGluZGV4Kys7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGluZGV4OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHBhdHRlcm4gb2YgdGhpcyB7QGNvZGUgQ2hvaWNlRm9ybWF0fSB3aGljaCBzcGVjaWZpZXMgdGhlCisgICAgICogcmFuZ2VzIGFuZCB0aGVpciBhc3NvY2lhdGVkIHN0cmluZ3MuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwYXR0ZXJuLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9QYXR0ZXJuKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2hvaWNlTGltaXRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoaSAhPSAwKSB7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnfCcpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3RyaW5nIHByZXZpb3VzID0gU3RyaW5nLnZhbHVlT2YocHJldmlvdXNEb3VibGUoY2hvaWNlTGltaXRzW2ldKSk7CisgICAgICAgICAgICBTdHJpbmcgbGltaXQgPSBTdHJpbmcudmFsdWVPZihjaG9pY2VMaW1pdHNbaV0pOworICAgICAgICAgICAgaWYgKHByZXZpb3VzLmxlbmd0aCgpIDwgbGltaXQubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKHByZXZpb3VzKTsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCc8Jyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQobGltaXQpOworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJyMnKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJvb2xlYW4gcXVvdGUgPSAoY2hvaWNlRm9ybWF0c1tpXS5pbmRleE9mKCd8JykgIT0gLTEpOworICAgICAgICAgICAgaWYgKHF1b3RlKSB7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnXCcnKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoY2hvaWNlRm9ybWF0c1tpXSk7CisgICAgICAgICAgICBpZiAocXVvdGUpIHsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCdcJycpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0NvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9Db2xsYXRpb25FbGVtZW50SXRlcmF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZGEzYjY1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9Db2xsYXRpb25FbGVtZW50SXRlcmF0b3IuamF2YQpAQCAtMCwwICsxLDIyMiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS50ZXh0OworCitpbXBvcnQgbGliY29yZS5pY3UuQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9ySUNVOworCisvKioKKyAqIENyZWF0ZWQgYnkgYSB7QGNvZGUgUnVsZUJhc2VkQ29sbGF0b3J9IHRvIGl0ZXJhdGUgdGhyb3VnaCBhIHN0cmluZy4gVGhlCisgKiByZXN1bHQgb2YgZWFjaCBpdGVyYXRpb24gaXMgYSAzMi1iaXQgY29sbGF0aW9uIGVsZW1lbnQgdGhhdCBkZWZpbmVzIHRoZQorICogb3JkZXJpbmcgcHJpb3JpdHkgb2YgdGhlIG5leHQgY2hhcmFjdGVyIG9yIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgaW4gdGhlCisgKiBzb3VyY2Ugc3RyaW5nLgorICogPHA+CisgKiBGb3IgaWxsdXN0cmF0aW9uLCBjb25zaWRlciB0aGUgZm9sbG93aW5nIGluIFNwYW5pc2g6CisgKiA8cD4KKyAqICJjYSI6IHRoZSBmaXJzdCBjb2xsYXRpb24gZWxlbWVudCBpcyBjb2xsYXRpb25fZWxlbWVudCgnYycpIGFuZCBzZWNvbmQKKyAqIGNvbGxhdGlvbiBlbGVtZW50IGlzIGNvbGxhdGlvbl9lbGVtZW50KCdhJykuCisgKiA8cD4KKyAqIFNpbmNlICJjaCIgaW4gU3BhbmlzaCBzb3J0cyBhcyBvbmUgZW50aXR5LCB0aGUgZXhhbXBsZSBiZWxvdyByZXR1cm5zIG9uZQorICogY29sbGF0aW9uIGVsZW1lbnQgZm9yIHRoZSB0d28gY2hhcmFjdGVycyAnYycgYW5kICdoJzoKKyAqIDxwPgorICogImNoYSI6IHRoZSBmaXJzdCBjb2xsYXRpb24gZWxlbWVudCBpcyBjb2xsYXRpb25fZWxlbWVudCgnY2gnKSBhbmQgdGhlIHNlY29uZAorICogb25lIGlzIGNvbGxhdGlvbl9lbGVtZW50KCdhJykuCisgKiA8cD4KKyAqIEluIEdlcm1hbiwgc2luY2UgdGhlIGNoYXJhY3RlciAnJiM5Mjt1MDA4NicgaXMgYSBjb21wb3NlZCBjaGFyYWN0ZXIgb2YgJ2EnCisgKiBhbmQgJ2UnLCB0aGUgaXRlcmF0b3IgcmV0dXJucyB0d28gY29sbGF0aW9uIGVsZW1lbnRzIGZvciB0aGUgc2luZ2xlIGNoYXJhY3RlcgorICogJyYjOTI7dTAwODYnOgorICogPHA+CisgKiAiJiM5Mjt1MDA4NmIiOiB0aGUgZmlyc3QgY29sbGF0aW9uIGVsZW1lbnQgaXMgY29sbGF0aW9uX2VsZW1lbnQoJ2EnKSwgdGhlCisgKiBzZWNvbmQgb25lIGlzIGNvbGxhdGlvbl9lbGVtZW50KCdlJyksIGFuZCB0aGUgdGhpcmQgY29sbGF0aW9uIGVsZW1lbnQgaXMKKyAqIGNvbGxhdGlvbl9lbGVtZW50KCdiJykuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgeworCisgICAgLyoqCisgICAgICogVGhpcyBjb25zdGFudCBpcyByZXR1cm5lZCBieSB0aGUgaXRlcmF0b3IgaW4gdGhlIG1ldGhvZHMKKyAgICAgKiB7QGNvZGUgbmV4dCgpfSBhbmQge0Bjb2RlIHByZXZpb3VzKCl9IHdoZW4gdGhlIGVuZCBvciB0aGUKKyAgICAgKiBiZWdpbm5pbmcgb2YgdGhlIHNvdXJjZSBzdHJpbmcgaGFzIGJlZW4gcmVhY2hlZCwgYW5kIHRoZXJlIGFyZSBubyBtb3JlCisgICAgICogdmFsaWQgY29sbGF0aW9uIGVsZW1lbnRzIHRvIHJldHVybi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOVUxMT1JERVIgPSAtMTsKKworICAgIHByaXZhdGUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9ySUNVIGljdUl0ZXJhdG9yOworCisgICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcklDVSBpdGVyYXRvcikgeworICAgICAgICB0aGlzLmljdUl0ZXJhdG9yID0gaXRlcmF0b3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogT2J0YWlucyB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZSB0aGF0IGVuZHMgd2l0aCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgY29sbGF0aW9uIGVsZW1lbnQuIFJldHVybnMge0Bjb2RlIDF9IGlmIHRoZXJlIGlzIG5vIGV4cGFuc2lvbgorICAgICAqIHdpdGggdGhpcyBjb2xsYXRpb24gZWxlbWVudCBhcyB0aGUgbGFzdCBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIG9yZGVyCisgICAgICogICAgICAgICAgICBhIGNvbGxhdGlvbiBlbGVtZW50IHRoYXQgaGFzIGJlZW4gcHJldmlvdXNseSBvYnRhaW5lZCBmcm9tIGEKKyAgICAgKiAgICAgICAgICAgIGNhbGwgdG8gZWl0aGVyIHRoZSB7QGxpbmsgI25leHQoKX0gb3Ige0BsaW5rICNwcmV2aW91cygpfQorICAgICAqICAgICAgICAgICAgbWV0aG9kLgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFueSBleHBhbnNpb24gc2VxdWVuY2UgZW5kaW5nIHdpdGggdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgY29sbGF0aW9uIGVsZW1lbnQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNYXhFeHBhbnNpb24oaW50IG9yZGVyKSB7CisgICAgICAgIHJldHVybiB0aGlzLmljdUl0ZXJhdG9yLmdldE1heEV4cGFuc2lvbihvcmRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogT2J0YWlucyB0aGUgY2hhcmFjdGVyIG9mZnNldCBpbiB0aGUgc291cmNlIHN0cmluZyBjb3JyZXNwb25kaW5nIHRvIHRoZQorICAgICAqIG5leHQgY29sbGF0aW9uIGVsZW1lbnQuIFRoaXMgdmFsdWUgY291bGQgYmUgYW55IG9mOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+VGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gdGhlIHNvdXJjZSBzdHJpbmcgdGhhdCBtYXRjaGVzCisgICAgICogdGhlIHZhbHVlIG9mIHRoZSBuZXh0IGNvbGxhdGlvbiBlbGVtZW50LiBUaGlzIG1lYW5zIHRoYXQgaWYKKyAgICAgKiB7QGNvZGUgc2V0T2Zmc2V0KG9mZnNldCl9IHNldHMgdGhlIGluZGV4IGluIHRoZSBtaWRkbGUgb2YgYSBjb250cmFjdGlvbiwKKyAgICAgKiB7QGNvZGUgZ2V0T2Zmc2V0KCl9IHJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gdGhlCisgICAgICogY29udHJhY3Rpb24sIHdoaWNoIG1heSBub3QgYmUgZXF1YWwgdG8gdGhlIG9yaWdpbmFsIG9mZnNldCB0aGF0IHdhcyBzZXQuCisgICAgICogSGVuY2UgY2FsbGluZyB7QGNvZGUgZ2V0T2Zmc2V0KCl9IGltbWVkaWF0ZWx5IGFmdGVyCisgICAgICoge0Bjb2RlIHNldE9mZnNldChvZmZzZXQpfSBkb2VzIG5vdCBndWFyYW50ZWUgdGhhdCB0aGUgb3JpZ2luYWwgb2Zmc2V0IHNldAorICAgICAqIHdpbGwgYmUgcmV0dXJuZWQuPC9saT4KKyAgICAgKiA8bGk+SWYgbm9ybWFsaXphdGlvbiBpcyBvbiwgdGhlIGluZGV4IG9mIHRoZSBpbW1lZGlhdGUgc3Vic2VxdWVudAorICAgICAqIGNoYXJhY3Rlciwgb3IgY29tcG9zaXRlIGNoYXJhY3RlciB3aXRoIHRoZSBmaXJzdCBjaGFyYWN0ZXIsIGhhdmluZyBhCisgICAgICogY29tYmluaW5nIGNsYXNzIG9mIDAuPC9saT4KKyAgICAgKiA8bGk+VGhlIGxlbmd0aCBvZiB0aGUgc291cmNlIHN0cmluZywgaWYgaXRlcmF0aW9uIGhhcyByZWFjaGVkIHRoZSBlbmQuCisgICAgICogPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgcG9zaXRpb24gb2YgdGhlIGNvbGxhdGlvbiBlbGVtZW50IGluIHRoZSBzb3VyY2Ugc3RyaW5nIHRoYXQKKyAgICAgKiAgICAgICAgIHdpbGwgYmUgcmV0dXJuZWQgYnkgdGhlIG5leHQgaW52b2NhdGlvbiBvZiB0aGUge0BsaW5rICNuZXh0KCl9CisgICAgICogICAgICAgICBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmljdUl0ZXJhdG9yLmdldE9mZnNldCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE9idGFpbnMgdGhlIG5leHQgY29sbGF0aW9uIGVsZW1lbnQgaW4gdGhlIHNvdXJjZSBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGNvbGxhdGlvbiBlbGVtZW50IG9yIHtAY29kZSBOVUxMT1JERVJ9IGlmIHRoZSBlbmQKKyAgICAgKiAgICAgICAgIG9mIHRoZSBpdGVyYXRpb24gaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IG5leHQoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmljdUl0ZXJhdG9yLm5leHQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPYnRhaW5zIHRoZSBwcmV2aW91cyBjb2xsYXRpb24gZWxlbWVudCBpbiB0aGUgc291cmNlIHN0cmluZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIGNvbGxhdGlvbiBlbGVtZW50LCBvciB7QGNvZGUgTlVMTE9SREVSfSB3aGVuCisgICAgICogICAgICAgICB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbiBoYXMgYmVlbiByZWFjaGVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgcHJldmlvdXMoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmljdUl0ZXJhdG9yLnByZXZpb3VzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT2J0YWlucyB0aGUgcHJpbWFyeSBvcmRlciBvZiB0aGUgc3BlY2lmaWVkIGNvbGxhdGlvbiBlbGVtZW50LCBpLmUuIHRoZQorICAgICAqIGZpcnN0IDE2IGJpdHMuIFRoaXMgdmFsdWUgaXMgdW5zaWduZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3JkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IG9mIHRoZSBjb2xsYXRpb24uCisgICAgICogQHJldHVybiB0aGUgZWxlbWVudCdzIDE2IGJpdCBwcmltYXJ5IG9yZGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHByaW1hcnlPcmRlcihpbnQgb3JkZXIpIHsKKyAgICAgICAgcmV0dXJuIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcklDVS5wcmltYXJ5T3JkZXIob3JkZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcG9zaXRpb25zIHRoZSBjdXJzb3IgdG8gcG9pbnQgYXQgdGhlIGZpcnN0IGVsZW1lbnQgb2YgdGhlIGN1cnJlbnQKKyAgICAgKiBzdHJpbmcuIFRoZSBuZXh0IGNhbGwgdG8ge0BsaW5rICNuZXh0KCl9IG9yIHtAbGluayAjcHJldmlvdXMoKX0gd2lsbAorICAgICAqIHJldHVybiB0aGUgZmlyc3QgYW5kIGxhc3QgY29sbGF0aW9uIGVsZW1lbnQgaW4gdGhlIHN0cmluZywgcmVzcGVjdGl2ZWx5LgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSB7QGNvZGUgUnVsZUJhc2VkQ29sbGF0b3J9IHVzZWQgYnkgdGhpcyBpdGVyYXRvciBoYXMgaGFkIGl0cworICAgICAqIGF0dHJpYnV0ZXMgY2hhbmdlZCwgY2FsbGluZyB7QGNvZGUgcmVzZXQoKX0gcmVpbml0aWFsaXplcyB0aGUgaXRlcmF0b3IgdG8KKyAgICAgKiB1c2UgdGhlIG5ldyBhdHRyaWJ1dGVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgICAgICB0aGlzLmljdUl0ZXJhdG9yLnJlc2V0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT2J0YWlucyB0aGUgc2Vjb25kYXJ5IG9yZGVyIG9mIHRoZSBzcGVjaWZpZWQgY29sbGF0aW9uIGVsZW1lbnQsIGkuZS4gdGhlCisgICAgICogMTZ0aCB0byAyM3RoIGJpdHMsIGluY2x1c2l2ZS4gVGhpcyB2YWx1ZSBpcyB1bnNpZ25lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcmRlcgorICAgICAqICAgICAgICAgICAgdGhlIGVsZW1lbnQgb2YgdGhlIGNvbGxhdG9yLgorICAgICAqIEByZXR1cm4gdGhlIDggYml0IHNlY29uZGFyeSBvcmRlciBvZiB0aGUgZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IHNlY29uZGFyeU9yZGVyKGludCBvcmRlcikgeworICAgICAgICByZXR1cm4gKHNob3J0KSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3JJQ1Uuc2Vjb25kYXJ5T3JkZXIob3JkZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBvaW50cyB0aGUgaXRlcmF0b3IgYXQgdGhlIGNvbGxhdGlvbiBlbGVtZW50IGFzc29jaWF0ZWQgd2l0aCB0aGUKKyAgICAgKiBjaGFyYWN0ZXIgaW4gdGhlIHNvdXJjZSBzdHJpbmcgd2hpY2ggaXMgZm91bmQgYXQgdGhlIHN1cHBsaWVkIG9mZnNldC4KKyAgICAgKiBBZnRlciB0aGlzIGNhbGwgY29tcGxldGVzLCBhbiBpbnZvY2F0aW9uIG9mIHRoZSB7QGxpbmsgI25leHQoKX0gbWV0aG9kCisgICAgICogd2lsbCByZXR1cm4gdGhpcyBjb2xsYXRpb24gZWxlbWVudC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB7QGNvZGUgbmV3T2Zmc2V0fSBjb3JyZXNwb25kcyB0byBhIGNoYXJhY3RlciB3aGljaCBpcyBwYXJ0IG9mIGEKKyAgICAgKiBzZXF1ZW5jZSB0aGF0IG1hcHMgdG8gYSBzaW5nbGUgY29sbGF0aW9uIGVsZW1lbnQgdGhlbiB0aGUgaXRlcmF0b3IgaXMKKyAgICAgKiBhZGp1c3RlZCB0byB0aGUgc3RhcnQgb2YgdGhhdCBzZXF1ZW5jZS4gQXMgYSByZXN1bHQgb2YgdGhpcywgYW55CisgICAgICogc3Vic2VxdWVudCBjYWxsIG1hZGUgdG8ge0Bjb2RlIGdldE9mZnNldCgpfSBtYXkgbm90IHJldHVybiB0aGUgc2FtZSB2YWx1ZQorICAgICAqIHNldCBieSB0aGlzIG1ldGhvZC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgZGVjb21wb3NpdGlvbiBtb2RlIGlzIG9uLCBhbmQgb2Zmc2V0IGlzIGluIHRoZSBtaWRkbGUgb2YgYQorICAgICAqIGRlY29tcG9zYWJsZSByYW5nZSBvZiBzb3VyY2UgdGV4dCwgdGhlIGl0ZXJhdG9yIG1heSBub3QgcmV0dXJuIGEgY29ycmVjdAorICAgICAqIHJlc3VsdCBmb3IgdGhlIG5leHQgZm9yd2FyZHMgb3IgYmFja3dhcmRzIGl0ZXJhdGlvbi4gVGhlIHVzZXIgbXVzdCBlbnN1cmUKKyAgICAgKiB0aGF0IHRoZSBvZmZzZXQgaXMgbm90IGluIHRoZSBtaWRkbGUgb2YgYSBkZWNvbXBvc2FibGUgcmFuZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3T2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVyIG9mZnNldCBpbnRvIHRoZSBvcmlnaW5hbCBzb3VyY2Ugc3RyaW5nIHRvIHNldC4KKyAgICAgKiAgICAgICAgICAgIE5vdGUgdGhhdCB0aGlzIGlzIG5vdCBhbiBvZmZzZXQgaW50byB0aGUgY29ycmVzcG9uZGluZworICAgICAqICAgICAgICAgICAgc2VxdWVuY2Ugb2YgY29sbGF0aW9uIGVsZW1lbnRzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE9mZnNldChpbnQgbmV3T2Zmc2V0KSB7CisgICAgICAgIHRoaXMuaWN1SXRlcmF0b3Iuc2V0T2Zmc2V0KG5ld09mZnNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBhIG5ldyBzb3VyY2Ugc3RyaW5nIGl0ZXJhdG9yIGZvciBpdGVyYXRpb24sIGFuZCByZXNldHMgdGhlIG9mZnNldCB0bworICAgICAqIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRleHQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc291cmNlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IHNvdXJjZSBzdHJpbmcgaXRlcmF0b3IgZm9yIGl0ZXJhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUZXh0KENoYXJhY3Rlckl0ZXJhdG9yIHNvdXJjZSkgeworICAgICAgICB0aGlzLmljdUl0ZXJhdG9yLnNldFRleHQoc291cmNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGEgbmV3IHNvdXJjZSBzdHJpbmcgZm9yIGl0ZXJhdGlvbiwgYW5kIHJlc2V0cyB0aGUgb2Zmc2V0IHRvIHRoZQorICAgICAqIGJlZ2lubmluZyBvZiB0aGUgdGV4dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzb3VyY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgc291cmNlIHN0cmluZyBmb3IgaXRlcmF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRleHQoU3RyaW5nIHNvdXJjZSkgeworICAgICAgICB0aGlzLmljdUl0ZXJhdG9yLnNldFRleHQoc291cmNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPYnRhaW5zIHRoZSB0ZXJ0aWFyeSBvcmRlciBvZiB0aGUgc3BlY2lmaWVkIGNvbGxhdGlvbiBlbGVtZW50LCBpLmUuIHRoZQorICAgICAqIGxhc3QgOCBiaXRzLiBUaGlzIHZhbHVlIGlzIHVuc2lnbmVkLgorICAgICAqCisgICAgICogQHBhcmFtIG9yZGVyCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCBvZiB0aGUgY29sbGF0aW9uLgorICAgICAqIEByZXR1cm4gdGhlIDggYml0IHRlcnRpYXJ5IG9yZGVyIG9mIHRoZSBlbGVtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgdGVydGlhcnlPcmRlcihpbnQgb3JkZXIpIHsKKyAgICAgICAgcmV0dXJuIChzaG9ydCkgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9ySUNVLnRlcnRpYXJ5T3JkZXIob3JkZXIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvQ29sbGF0aW9uS2V5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0NvbGxhdGlvbktleS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdkMDQzZTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0NvbGxhdGlvbktleS5qYXZhCkBAIC0wLDAgKzEsMTEyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnRleHQ7CisKKy8qKgorICogUmVwcmVzZW50cyBhIHN0cmluZyB1bmRlciB0aGUgcnVsZXMgb2YgYSBzcGVjaWZpYyB7QGNvZGUgQ29sbGF0b3J9IG9iamVjdC4KKyAqIENvbXBhcmluZyB0d28ge0Bjb2RlIENvbGxhdGlvbktleX0gaW5zdGFuY2VzIHJldHVybnMgdGhlIHJlbGF0aXZlIG9yZGVyIG9mCisgKiB0aGUgc3RyaW5ncyB0aGV5IHJlcHJlc2VudC4KKyAqIDxwPgorICogU2luY2UgdGhlIHJ1bGUgc2V0IG9mIGNvbGxhdG9ycyBjYW4gZGlmZmVyLCB0aGUgc29ydCBvcmRlcnMgb2YgdGhlIHNhbWUKKyAqIHN0cmluZyB1bmRlciB0d28gZGlmZmVyZW50IHtAY29kZSBDb2xsYXRvcn0gaW5zdGFuY2VzIG1pZ2h0IGRpZmZlci4gSGVuY2UKKyAqIGNvbXBhcmluZyBjb2xsYXRpb24ga2V5cyBnZW5lcmF0ZWQgZnJvbSBkaWZmZXJlbnQge0Bjb2RlIENvbGxhdG9yfSBpbnN0YW5jZXMKKyAqIGNhbiBnaXZlIGluY29ycmVjdCByZXN1bHRzLgorICogPHA+CisgKiBCb3RoIHRoZSBtZXRob2Qge0Bjb2RlIENvbGxhdGlvbktleS5jb21wYXJlVG8oQ29sbGF0aW9uS2V5KX0gYW5kIHRoZSBtZXRob2QKKyAqIHtAY29kZSBDb2xsYXRvci5jb21wYXJlKFN0cmluZywgU3RyaW5nKX0gY29tcGFyZXMgdHdvIHN0cmluZ3MgYW5kIHJldHVybnMKKyAqIHRoZWlyIHJlbGF0aXZlIG9yZGVyLiBUaGUgcGVyZm9ybWFuY2UgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZXNlIHR3byBhcHByb2FjaGVzCisgKiBjYW4gZGlmZmVyLgorICogPHA+CisgKiBEdXJpbmcgdGhlIGNvbnN0cnVjdGlvbiBvZiBhIHtAY29kZSBDb2xsYXRpb25LZXl9LCB0aGUgZW50aXJlIHNvdXJjZSBzdHJpbmcKKyAqIGlzIGV4YW1pbmVkIGFuZCBwcm9jZXNzZWQgaW50byBhIHNlcmllcyBvZiBiaXRzIHRlcm1pbmF0ZWQgYnkgYSBudWxsLCB0aGF0CisgKiBhcmUgc3RvcmVkIGluIHRoZSB7QGNvZGUgQ29sbGF0aW9uS2V5fS4gV2hlbgorICoge0Bjb2RlIENvbGxhdGlvbktleS5jb21wYXJlVG8oQ29sbGF0aW9uS2V5KX0gZXhlY3V0ZXMsIGl0IHBlcmZvcm1zIGJpdHdpc2UKKyAqIGNvbXBhcmlzb24gb24gdGhlIGJpdCBzZXF1ZW5jZXMuIFRoaXMgY2FuIGluY3VyIHN0YXJ0dXAgY29zdCB3aGVuIGNyZWF0aW5nCisgKiB0aGUge0Bjb2RlIENvbGxhdGlvbktleX0sIGJ1dCBvbmNlIHRoZSBrZXkgaXMgY3JlYXRlZCwgYmluYXJ5IGNvbXBhcmlzb25zCisgKiBhcmUgZmFzdC4gVGhpcyBhcHByb2FjaCBpcyByZWNvbW1lbmRlZCB3aGVuIHRoZSBzYW1lIHN0cmluZ3MgYXJlIHRvIGJlCisgKiBjb21wYXJlZCBvdmVyIGFuZCBvdmVyIGFnYWluLgorICogPHA+CisgKiBPbiB0aGUgb3RoZXIgaGFuZCwgaW1wbGVtZW50YXRpb25zIG9mCisgKiB7QGNvZGUgQ29sbGF0b3IuY29tcGFyZShTdHJpbmcsIFN0cmluZyl9IGNhbiBleGFtaW5lIGFuZCBwcm9jZXNzIHRoZSBzdHJpbmdzCisgKiBvbmx5IHVudGlsIHRoZSBmaXJzdCBjaGFyYWN0ZXJzIGRpZmZlciBpbiBvcmRlci4gVGhpcyBhcHByb2FjaCBpcworICogcmVjb21tZW5kZWQgaWYgdGhlIHN0cmluZ3MgYXJlIHRvIGJlIGNvbXBhcmVkIG9ubHkgb25jZS4KKyAqIDxwPgorICogVGhlIGZvbGxvd2luZyBleGFtcGxlIHNob3dzIGhvdyBjb2xsYXRpb24ga2V5cyBjYW4gYmUgdXNlZCB0byBzb3J0IGEKKyAqIGxpc3Qgb2Ygc3RyaW5nczoKKyAqIDxibG9ja3F1b3RlPgorICoKKyAqIDxwcmU+CisgKiAvLyBDcmVhdGUgYW4gYXJyYXkgb2YgQ29sbGF0aW9uS2V5cyBmb3IgdGhlIFN0cmluZ3MgdG8gYmUgc29ydGVkLgorICogQ29sbGF0b3IgbXlDb2xsYXRvciA9IENvbGxhdG9yLmdldEluc3RhbmNlKCk7CisgKiBDb2xsYXRpb25LZXlbXSBrZXlzID0gbmV3IENvbGxhdGlvbktleVszXTsKKyAqIGtleXNbMF0gPSBteUNvbGxhdG9yLmdldENvbGxhdGlvbktleSgmcXVvdDtUb20mcXVvdDspOworICoga2V5c1sxXSA9IG15Q29sbGF0b3IuZ2V0Q29sbGF0aW9uS2V5KCZxdW90O0RpY2smcXVvdDspOworICoga2V5c1syXSA9IG15Q29sbGF0b3IuZ2V0Q29sbGF0aW9uS2V5KCZxdW90O0hhcnJ5JnF1b3Q7KTsKKyAqIHNvcnQoa2V5cyk7CisgKiA8YnI+CisgKiAvLy4uLgorICogPGJyPgorICogLy8gSW5zaWRlIGJvZHkgb2Ygc29ydCByb3V0aW5lLCBjb21wYXJlIGtleXMgdGhpcyB3YXkKKyAqIGlmKCBrZXlzW2ldLmNvbXBhcmVUbygga2V5c1tqXSApICZndDsgMCApCisgKiAgICAvLyBzd2FwIGtleXNbaV0gYW5kIGtleXNbal0KKyAqIDxicj4KKyAqIC8vLi4uCisgKiA8YnI+CisgKiAvLyBGaW5hbGx5LCB3aGVuIHdlJ3ZlIHJldHVybmVkIGZyb20gc29ydC4KKyAqIFN5c3RlbS5vdXQucHJpbnRsbihrZXlzWzBdLmdldFNvdXJjZVN0cmluZygpKTsKKyAqIFN5c3RlbS5vdXQucHJpbnRsbihrZXlzWzFdLmdldFNvdXJjZVN0cmluZygpKTsKKyAqIFN5c3RlbS5vdXQucHJpbnRsbihrZXlzWzJdLmdldFNvdXJjZVN0cmluZygpKTsKKyAqIDwvcHJlPgorICoKKyAqIDwvYmxvY2txdW90ZT4KKyAqCisgKiBAc2VlIENvbGxhdG9yCisgKiBAc2VlIFJ1bGVCYXNlZENvbGxhdG9yCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBDb2xsYXRpb25LZXkgaW1wbGVtZW50cyBDb21wYXJhYmxlPENvbGxhdGlvbktleT4geworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHNvdXJjZTsKKworICAgIHByb3RlY3RlZCBDb2xsYXRpb25LZXkoU3RyaW5nIHNvdXJjZSkgeworICAgICAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIGNvbGxhdGlvbiBrZXkgdG8gdGhlIGdpdmVuIGNvbGxhdGlvbiBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIG90aGVyIGNvbGxhdGlvbiBrZXkuCisgICAgICogQHJldHVybiBhIG5lZ2F0aXZlIHZhbHVlIGlmIHRoaXMga2V5IGlzIGxlc3MgdGhhbiB7QGNvZGUgdmFsdWV9LAorICAgICAqICAgICAgICAgMCBpZiB0aGV5IGFyZSBlcXVhbCwgYW5kIGEgcG9zaXRpdmUgdmFsdWUgaWYgdGhpcyBrZXkgaXMgZ3JlYXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGNvbXBhcmVUbyhDb2xsYXRpb25LZXkgdmFsdWUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyaW5nIGZyb20gd2hpY2ggdGhpcyBjb2xsYXRpb24ga2V5IHdhcyBjcmVhdGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc291cmNlIHN0cmluZyBvZiB0aGlzIGNvbGxhdGlvbiBrZXkuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTb3VyY2VTdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBzb3VyY2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIGNvbGxhdGlvbiBrZXkgYXMgYSBieXRlIGFycmF5LgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYnl0ZVtdIHRvQnl0ZUFycmF5KCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0NvbGxhdG9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0NvbGxhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGZhOGM3MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvQ29sbGF0b3IuamF2YQpAQCAtMCwwICsxLDM5MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS50ZXh0OworCitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBsaWJjb3JlLmljdS5JQ1U7CitpbXBvcnQgbGliY29yZS5pY3UuUnVsZUJhc2VkQ29sbGF0b3JJQ1U7CisKKy8qKgorICogUGVyZm9ybXMgbG9jYWxlLXNlbnNpdGl2ZSBzdHJpbmcgY29tcGFyaXNvbi4gQSBjb25jcmV0ZSBzdWJjbGFzcywKKyAqIHtAbGluayBSdWxlQmFzZWRDb2xsYXRvcn0sIGFsbG93cyBjdXN0b21pemF0aW9uIG9mIHRoZSBjb2xsYXRpb24gb3JkZXJpbmcgYnkKKyAqIHRoZSB1c2Ugb2YgcnVsZSBzZXRzLgorICogPHA+CisgKiBGb2xsb3dpbmcgdGhlIDxhIGhyZWY9aHR0cDovL3d3dy51bmljb2RlLm9yZz5Vbmljb2RlIENvbnNvcnRpdW08L2E+J3MKKyAqIHNwZWNpZmljYXRpb25zIGZvciB0aGUgPGEKKyAqIGhyZWY9Imh0dHA6Ly93d3cudW5pY29kZS5vcmcvdW5pY29kZS9yZXBvcnRzL3RyMTAvIj4gVW5pY29kZSBDb2xsYXRpb24KKyAqIEFsZ29yaXRobSAoVUNBKTwvYT4sIHRoZXJlIGFyZSA0IGRpZmZlcmVudCBsZXZlbHMgb2Ygc3RyZW5ndGggdXNlZCBpbgorICogY29tcGFyaXNvbnM6CisgKiA8dWw+CisgKiA8bGk+UFJJTUFSWSBzdHJlbmd0aDogVHlwaWNhbGx5LCB0aGlzIGlzIHVzZWQgdG8gZGVub3RlIGRpZmZlcmVuY2VzIGJldHdlZW4KKyAqIGJhc2UgY2hhcmFjdGVycyAoZm9yIGV4YW1wbGUsICJhIiAmbHQ7ICJiIikuIEl0IGlzIHRoZSBzdHJvbmdlc3QgZGlmZmVyZW5jZS4KKyAqIEZvciBleGFtcGxlLCBkaWN0aW9uYXJpZXMgYXJlIGRpdmlkZWQgaW50byBkaWZmZXJlbnQgc2VjdGlvbnMgYnkgYmFzZQorICogY2hhcmFjdGVyLgorICogPGxpPlNFQ09OREFSWSBzdHJlbmd0aDogQWNjZW50cyBpbiB0aGUgY2hhcmFjdGVycyBhcmUgY29uc2lkZXJlZCBzZWNvbmRhcnkKKyAqIGRpZmZlcmVuY2VzIChmb3IgZXhhbXBsZSwgImFzIiAmbHQ7ICImYWdyYXZlO3MiICZsdDsgImF0IikuIE90aGVyIGRpZmZlcmVuY2VzCisgKiBiZXR3ZWVuIGxldHRlcnMgY2FuIGFsc28gYmUgY29uc2lkZXJlZCBzZWNvbmRhcnkgZGlmZmVyZW5jZXMsIGRlcGVuZGluZyBvbgorICogdGhlIGxhbmd1YWdlLiBBIHNlY29uZGFyeSBkaWZmZXJlbmNlIGlzIGlnbm9yZWQgd2hlbiB0aGVyZSBpcyBhIHByaW1hcnkKKyAqIGRpZmZlcmVuY2UgYW55d2hlcmUgaW4gdGhlIHN0cmluZ3MuCisgKiA8bGk+VEVSVElBUlkgc3RyZW5ndGg6IFVwcGVyIGFuZCBsb3dlciBjYXNlIGRpZmZlcmVuY2VzIGluIGNoYXJhY3RlcnMgYXJlCisgKiBkaXN0aW5ndWlzaGVkIGF0IHRlcnRpYXJ5IHN0cmVuZ3RoIChmb3IgZXhhbXBsZSwgImFvIiAmbHQ7ICJBbyIgJmx0OworICogImEmb2dyYXZlOyIpLiBJbiBhZGRpdGlvbiwgYSB2YXJpYW50IG9mIGEgbGV0dGVyIGRpZmZlcnMgZnJvbSB0aGUgYmFzZSBmb3JtCisgKiBvbiB0aGUgdGVydGlhcnkgc3RyZW5ndGggKHN1Y2ggYXMgIkEiIGFuZCAiJiM5Mzk4OyIpLiBBbm90aGVyIGV4YW1wbGUgaXMgdGhlCisgKiBkaWZmZXJlbmNlIGJldHdlZW4gbGFyZ2UgYW5kIHNtYWxsIEthbmEuIEEgdGVydGlhcnkgZGlmZmVyZW5jZSBpcyBpZ25vcmVkCisgKiB3aGVuIHRoZXJlIGlzIGEgcHJpbWFyeSBvciBzZWNvbmRhcnkgZGlmZmVyZW5jZSBhbnl3aGVyZSBpbiB0aGUgc3RyaW5ncy4KKyAqIDxsaT5JREVOVElDQUwgc3RyZW5ndGg6IFdoZW4gYWxsIG90aGVyIHN0cmVuZ3RocyBhcmUgZXF1YWwsIHRoZSBJREVOVElDQUwKKyAqIHN0cmVuZ3RoIGlzIHVzZWQgYXMgYSB0aWVicmVha2VyLiBUaGUgVW5pY29kZSBjb2RlIHBvaW50IHZhbHVlcyBvZiB0aGUgTkZECisgKiBmb3JtIG9mIGVhY2ggc3RyaW5nIGFyZSBjb21wYXJlZCwganVzdCBpbiBjYXNlIHRoZXJlIGlzIG5vIGRpZmZlcmVuY2UuIEZvcgorICogZXhhbXBsZSwgSGVicmV3IGNhbnRlbGxhdGlvbiBtYXJrcyBhcmUgb25seSBkaXN0aW5ndWlzaGVkIGF0IHRoaXMgc3RyZW5ndGguCisgKiBUaGlzIHN0cmVuZ3RoIHNob3VsZCBiZSB1c2VkIHNwYXJpbmdseSwgYXMgb25seSBjb2RlIHBvaW50IHZhbHVlIGRpZmZlcmVuY2VzCisgKiBiZXR3ZWVuIHR3byBzdHJpbmdzIGFyZSBhbiBleHRyZW1lbHkgcmFyZSBvY2N1cnJlbmNlLiBVc2luZyB0aGlzIHN0cmVuZ3RoCisgKiBzdWJzdGFudGlhbGx5IGRlY3JlYXNlcyB0aGUgcGVyZm9ybWFuY2UgZm9yIGJvdGggY29tcGFyaXNvbiBhbmQgY29sbGF0aW9uIGtleQorICogZ2VuZXJhdGlvbiBBUElzLiBUaGlzIHN0cmVuZ3RoIGFsc28gaW5jcmVhc2VzIHRoZSBzaXplIG9mIHRoZSBjb2xsYXRpb24ga2V5LgorICogPC91bD4KKyAqIDxwPgorICogVGhpcyB7QGNvZGUgQ29sbGF0b3J9IGRlYWxzIG9ubHkgd2l0aCB0d28gZGVjb21wb3NpdGlvbiBtb2RlcywgdGhlIGNhbm9uaWNhbAorICogZGVjb21wb3NpdGlvbiBtb2RlIGFuZCBvbmUgdGhhdCBkb2VzIG5vdCB1c2UgYW55IGRlY29tcG9zaXRpb24uIFRoZQorICogY29tcGF0aWJpbGl0eSBkZWNvbXBvc2l0aW9uIG1vZGUKKyAqIHtAY29kZSBqYXZhLnRleHQuQ29sbGF0b3IuRlVMTF9ERUNPTVBPU0lUSU9OfSBpcyBub3Qgc3VwcG9ydGVkIGhlcmUuIElmIHRoZQorICogY2Fub25pY2FsIGRlY29tcG9zaXRpb24gbW9kZSBpcyBzZXQsIHtAY29kZSBDb2xsYXRvcn0gaGFuZGxlcyB1bi1ub3JtYWxpemVkCisgKiB0ZXh0IHByb3Blcmx5LCBwcm9kdWNpbmcgdGhlIHNhbWUgcmVzdWx0cyBhcyBpZiB0aGUgdGV4dCB3ZXJlIG5vcm1hbGl6ZWQgaW4KKyAqIE5GRC4gSWYgY2Fub25pY2FsIGRlY29tcG9zaXRpb24gaXMgdHVybmVkIG9mZiwgaXQgaXMgdGhlIHVzZXIncworICogcmVzcG9uc2liaWxpdHkgdG8gZW5zdXJlIHRoYXQgYWxsIHRleHQgaXMgYWxyZWFkeSBpbiB0aGUgYXBwcm9wcmlhdGUgZm9ybQorICogYmVmb3JlIHBlcmZvcm1pbmcgYSBjb21wYXJpc29uIG9yIGJlZm9yZSBnZXR0aW5nIGEge0BsaW5rIENvbGxhdGlvbktleX0uCisgKiA8cD4KKyAqIDxlbT5FeGFtcGxlczo8L2VtPgorICogPGJsb2NrcXVvdGU+CisgKgorICogPHByZT4KKyAqIC8vIEdldCB0aGUgQ29sbGF0b3IgZm9yIFVTIEVuZ2xpc2ggYW5kIHNldCBpdHMgc3RyZW5ndGggdG8gUFJJTUFSWQorICogQ29sbGF0b3IgdXNDb2xsYXRvciA9IENvbGxhdG9yLmdldEluc3RhbmNlKExvY2FsZS5VUyk7CisgKiB1c0NvbGxhdG9yLnNldFN0cmVuZ3RoKENvbGxhdG9yLlBSSU1BUlkpOworICogaWYgKHVzQ29sbGF0b3IuY29tcGFyZSgmcXVvdDthYmMmcXVvdDssICZxdW90O0FCQyZxdW90OykgPT0gMCkgeworICogICAgIFN5c3RlbS5vdXQucHJpbnRsbigmcXVvdDtTdHJpbmdzIGFyZSBlcXVpdmFsZW50JnF1b3Q7KTsKKyAqIH0KKyAqIDwvcHJlPgorICoKKyAqIDwvYmxvY2txdW90ZT4KKyAqIDxwPgorICogVGhlIGZvbGxvd2luZyBleGFtcGxlIHNob3dzIGhvdyB0byBjb21wYXJlIHR3byBzdHJpbmdzIHVzaW5nIHRoZSBjb2xsYXRvciBmb3IKKyAqIHRoZSBkZWZhdWx0IGxvY2FsZS4KKyAqIDxibG9ja3F1b3RlPgorICoKKyAqIDxwcmU+CisgKiAvLyBDb21wYXJlIHR3byBzdHJpbmdzIGluIHRoZSBkZWZhdWx0IGxvY2FsZQorICogQ29sbGF0b3IgbXlDb2xsYXRvciA9IENvbGxhdG9yLmdldEluc3RhbmNlKCk7CisgKiBteUNvbGxhdG9yLnNldERlY29tcG9zaXRpb24oQ29sbGF0b3IuTk9fREVDT01QT1NJVElPTik7CisgKiBpZiAobXlDb2xsYXRvci5jb21wYXJlKCZxdW90O1x1MDBlMFx1MDMyNSZxdW90OywgJnF1b3Q7YVx1MDMyNVx1MDMwMCZxdW90OykgIT0gMCkgeworICogICAgIFN5c3RlbS5vdXQucHJpbnRsbigmcXVvdDtcdTAwZTBcdTAzMjUgaXMgbm90IGVxdWFsIHRvIGFcdTAzMjVcdTAzMDAgd2l0aG91dCBkZWNvbXBvc2l0aW9uJnF1b3Q7KTsKKyAqICAgICBteUNvbGxhdG9yLnNldERlY29tcG9zaXRpb24oQ29sbGF0b3IuQ0FOT05JQ0FMX0RFQ09NUE9TSVRJT04pOworICogICAgIGlmIChteUNvbGxhdG9yLmNvbXBhcmUoJnF1b3Q7XHUwMGUwXHUwMzI1JnF1b3Q7LCAmcXVvdDthXHUwMzI1XHUwMzAwJnF1b3Q7KSAhPSAwKSB7CisgKiAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigmcXVvdDtFcnJvcjogXHUwMGUwXHUwMzI1IHNob3VsZCBiZSBlcXVhbCB0byBhXHUwMzI1XHUwMzAwIHdpdGggZGVjb21wb3NpdGlvbiZxdW90Oyk7CisgKiAgICAgfSBlbHNlIHsKKyAqICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCZxdW90O1x1MDBlMFx1MDMyNSBpcyBlcXVhbCB0byBhXHUwMzI1XHUwMzAwIHdpdGggZGVjb21wb3NpdGlvbiZxdW90Oyk7CisgKiAgICAgfQorICogfSBlbHNlIHsKKyAqICAgICBTeXN0ZW0ub3V0LnByaW50bG4oJnF1b3Q7RXJyb3I6IFx1MDBlMFx1MDMyNSBzaG91bGQgYmUgbm90IGVxdWFsIHRvIGFcdTAzMjVcdTAzMDAgd2l0aG91dCBkZWNvbXBvc2l0aW9uJnF1b3Q7KTsKKyAqIH0KKyAqIDwvcHJlPgorICoKKyAqIDwvYmxvY2txdW90ZT4KKyAqCisgKiBAc2VlIFJ1bGVCYXNlZENvbGxhdG9yCisgKiBAc2VlIENvbGxhdGlvbktleQorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ29sbGF0b3IgaW1wbGVtZW50cyBDb21wYXJhdG9yPE9iamVjdD4sIENsb25lYWJsZSB7CisgICAgLyoqCisgICAgICogQ29uc3RhbnQgdXNlZCB0byBzcGVjaWZ5IHRoZSBkZWNvbXBvc2l0aW9uIHJ1bGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9fREVDT01QT1NJVElPTiA9IDA7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCB1c2VkIHRvIHNwZWNpZnkgdGhlIGRlY29tcG9zaXRpb24gcnVsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDQU5PTklDQUxfREVDT01QT1NJVElPTiA9IDE7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCB1c2VkIHRvIHNwZWNpZnkgdGhlIGRlY29tcG9zaXRpb24gcnVsZS4gVGhpcyB2YWx1ZSBmb3IKKyAgICAgKiBkZWNvbXBvc2l0aW9uIGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVMTF9ERUNPTVBPU0lUSU9OID0gMjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IHVzZWQgdG8gc3BlY2lmeSB0aGUgY29sbGF0aW9uIHN0cmVuZ3RoLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBSSU1BUlkgPSAwOworCisgICAgLyoqCisgICAgICogQ29uc3RhbnQgdXNlZCB0byBzcGVjaWZ5IHRoZSBjb2xsYXRpb24gc3RyZW5ndGguCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VDT05EQVJZID0gMTsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IHVzZWQgdG8gc3BlY2lmeSB0aGUgY29sbGF0aW9uIHN0cmVuZ3RoLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRFUlRJQVJZID0gMjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IHVzZWQgdG8gc3BlY2lmeSB0aGUgY29sbGF0aW9uIHN0cmVuZ3RoLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElERU5USUNBTCA9IDM7CisKKyAgICBSdWxlQmFzZWRDb2xsYXRvcklDVSBpY3VDb2xsOworCisgICAgQ29sbGF0b3IoUnVsZUJhc2VkQ29sbGF0b3JJQ1UgaWN1Q29sbCkgeworICAgICAgICB0aGlzLmljdUNvbGwgPSBpY3VDb2xsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIENvbGxhdG9yfSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ29sbGF0b3IoKSB7CisgICAgICAgIGljdUNvbGwgPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3JJQ1UoTG9jYWxlLmdldERlZmF1bHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBjb2xsYXRvciB3aXRoIHRoZSBzYW1lIGRlY29tcG9zaXRpb24gbW9kZSBhbmQKKyAgICAgKiBzdHJlbmd0aCB2YWx1ZSBhcyB0aGlzIGNvbGxhdG9yLgorICAgICAqCisgICAgICogQHJldHVybiBhIHNoYWxsb3cgY29weSBvZiB0aGlzIGNvbGxhdG9yLgorICAgICAqIEBzZWUgamF2YS5sYW5nLkNsb25lYWJsZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsYXRvciBjbG9uZSA9IChDb2xsYXRvcikgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgICAgIGNsb25lLmljdUNvbGwgPSAoUnVsZUJhc2VkQ29sbGF0b3JJQ1UpIGljdUNvbGwuY2xvbmUoKTsKKyAgICAgICAgICAgIHJldHVybiBjbG9uZTsKKyAgICAgICAgfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdHdvIG9iamVjdHMgdG8gZGV0ZXJtaW5lIHRoZWlyIHJlbGF0aXZlIG9yZGVyLiBUaGUgb2JqZWN0cyBtdXN0CisgICAgICogYmUgc3RyaW5ncy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QxCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3Qgc3RyaW5nIHRvIGNvbXBhcmUuCisgICAgICogQHBhcmFtIG9iamVjdDIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgc3RyaW5nIHRvIGNvbXBhcmUuCisgICAgICogQHJldHVybiBhIG5lZ2F0aXZlIHZhbHVlIGlmIHtAY29kZSBvYmplY3QxfSBpcyBsZXNzIHRoYW4ge0Bjb2RlIG9iamVjdDJ9LAorICAgICAqICAgICAgICAgMCBpZiB0aGV5IGFyZSBlcXVhbCwgYW5kIGEgcG9zaXRpdmUgdmFsdWUgaWYge0Bjb2RlIG9iamVjdDF9IGlzCisgICAgICogICAgICAgICBncmVhdGVyIHRoYW4ge0Bjb2RlIG9iamVjdDJ9LgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICBpZiB7QGNvZGUgb2JqZWN0MX0gb3Ige0Bjb2RlIG9iamVjdDJ9IGlzIG5vdCBhIHtAY29kZSBTdHJpbmd9LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29tcGFyZShPYmplY3Qgb2JqZWN0MSwgT2JqZWN0IG9iamVjdDIpIHsKKyAgICAgICAgcmV0dXJuIGNvbXBhcmUoKFN0cmluZykgb2JqZWN0MSwgKFN0cmluZykgb2JqZWN0Mik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdHdvIHN0cmluZ3MgdG8gZGV0ZXJtaW5lIHRoZWlyIHJlbGF0aXZlIG9yZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZzEKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBzdHJpbmcgdG8gY29tcGFyZS4KKyAgICAgKiBAcGFyYW0gc3RyaW5nMgorICAgICAqICAgICAgICAgICAgdGhlIHNlY29uZCBzdHJpbmcgdG8gY29tcGFyZS4KKyAgICAgKiBAcmV0dXJuIGEgbmVnYXRpdmUgdmFsdWUgaWYge0Bjb2RlIHN0cmluZzF9IGlzIGxlc3MgdGhhbiB7QGNvZGUgc3RyaW5nMn0sCisgICAgICogICAgICAgICAwIGlmIHRoZXkgYXJlIGVxdWFsIGFuZCBhIHBvc2l0aXZlIHZhbHVlIGlmIHtAY29kZSBzdHJpbmcxfSBpcworICAgICAqICAgICAgICAgZ3JlYXRlciB0aGFuIHtAY29kZSBzdHJpbmcyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGNvbXBhcmUoU3RyaW5nIHN0cmluZzEsIFN0cmluZyBzdHJpbmcyKTsKKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoaXMgY29sbGF0b3Igd2l0aCB0aGUgc3BlY2lmaWVkIG9iamVjdCBhbmQgaW5kaWNhdGVzIGlmIHRoZXkKKyAgICAgKiBhcmUgZXF1YWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUgd2l0aCB0aGlzIG9iamVjdC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgb2JqZWN0fSBpcyBhIHtAY29kZSBDb2xsYXRvcn0gb2JqZWN0IGFuZAorICAgICAqICAgICAgICAgaXQgaGFzIHRoZSBzYW1lIHN0cmVuZ3RoIGFuZCBkZWNvbXBvc2l0aW9uIHZhbHVlcyBhcyB0aGlzCisgICAgICogICAgICAgICBjb2xsYXRvcjsge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNlZSAjaGFzaENvZGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBDb2xsYXRvcikpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBDb2xsYXRvciBjb2xsYXRvciA9IChDb2xsYXRvcikgb2JqZWN0OworICAgICAgICByZXR1cm4gaWN1Q29sbCA9PSBudWxsID8gY29sbGF0b3IuaWN1Q29sbCA9PSBudWxsIDogaWN1Q29sbC5lcXVhbHMoY29sbGF0b3IuaWN1Q29sbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdHdvIHN0cmluZ3MgdXNpbmcgdGhlIGNvbGxhdGlvbiBydWxlcyB0byBkZXRlcm1pbmUgaWYgdGhleSBhcmUKKyAgICAgKiBlcXVhbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcxCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3Qgc3RyaW5nIHRvIGNvbXBhcmUuCisgICAgICogQHBhcmFtIHN0cmluZzIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgc3RyaW5nIHRvIGNvbXBhcmUuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIHN0cmluZzF9IGFuZCB7QGNvZGUgc3RyaW5nMn0gYXJlIGVxdWFsCisgICAgICogICAgICAgICB1c2luZyB0aGUgY29sbGF0aW9uIHJ1bGVzLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFN0cmluZyBzdHJpbmcxLCBTdHJpbmcgc3RyaW5nMikgeworICAgICAgICByZXR1cm4gY29tcGFyZShzdHJpbmcxLCBzdHJpbmcyKSA9PSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgbG9jYWxlcyBmb3Igd2hpY2ggY3VzdG9tIHtAY29kZSBDb2xsYXRvcn0gaW5zdGFuY2VzCisgICAgICogYXJlIGF2YWlsYWJsZS4KKyAgICAgKiA8cD5Ob3RlIHRoYXQgQW5kcm9pZCBkb2VzIG5vdCBzdXBwb3J0IHVzZXItc3VwcGxpZWQgbG9jYWxlIHNlcnZpY2UgcHJvdmlkZXJzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTG9jYWxlW10gZ2V0QXZhaWxhYmxlTG9jYWxlcygpIHsKKyAgICAgICAgcmV0dXJuIElDVS5nZXRBdmFpbGFibGVDb2xsYXRvckxvY2FsZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0BsaW5rIENvbGxhdGlvbktleX0gZm9yIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGZvciB0aGlzIGNvbGxhdG9yCisgICAgICogd2l0aCB0aGUgY3VycmVudCBkZWNvbXBvc2l0aW9uIHJ1bGUgYW5kIHN0cmVuZ3RoIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBzdHJpbmcgdGhhdCBpcyBjb252ZXJ0ZWQgaW50byBhIGNvbGxhdGlvbiBrZXkuCisgICAgICogQHJldHVybiB0aGUgY29sbGF0aW9uIGtleSBmb3Ige0Bjb2RlIHN0cmluZ30uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENvbGxhdGlvbktleSBnZXRDb2xsYXRpb25LZXkoU3RyaW5nIHN0cmluZyk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWNvbXBvc2l0aW9uIHJ1bGUgZm9yIHRoaXMgY29sbGF0b3IuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkZWNvbXBvc2l0aW9uIHJ1bGUsIGVpdGhlciB7QGNvZGUgTk9fREVDT01QT1NJVElPTn0gb3IKKyAgICAgKiAgICAgICAgIHtAY29kZSBDQU5PTklDQUxfREVDT01QT1NJVElPTn0uIHtAY29kZSBGVUxMX0RFQ09NUE9TSVRJT059IGlzCisgICAgICogICAgICAgICBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RGVjb21wb3NpdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIGRlY29tcG9zaXRpb25Nb2RlX0lDVV9KYXZhKGljdUNvbGwuZ2V0RGVjb21wb3NpdGlvbigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIENvbGxhdG9yfSBpbnN0YW5jZSB3aGljaCBpcyBhcHByb3ByaWF0ZSBmb3IgdGhlIHVzZXIncyBkZWZhdWx0CisgICAgICoge0Bjb2RlIExvY2FsZX0uCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ29sbGF0b3IgZ2V0SW5zdGFuY2UoKSB7CisgICAgICAgIHJldHVybiBnZXRJbnN0YW5jZShMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIENvbGxhdG9yfSBpbnN0YW5jZSB3aGljaCBpcyBhcHByb3ByaWF0ZSBmb3Ige0Bjb2RlIGxvY2FsZX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDb2xsYXRvciBnZXRJbnN0YW5jZShMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIGlmIChsb2NhbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBSdWxlQmFzZWRDb2xsYXRvcihuZXcgUnVsZUJhc2VkQ29sbGF0b3JJQ1UobG9jYWxlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyZW5ndGggdmFsdWUgZm9yIHRoaXMgY29sbGF0b3IuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJlbmd0aCB2YWx1ZSwgZWl0aGVyIFBSSU1BUlksIFNFQ09OREFSWSwgVEVSVElBUlkgb3IKKyAgICAgKiAgICAgICAgIElERU5USUNBTC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFN0cmVuZ3RoKCkgeworICAgICAgICByZXR1cm4gc3RyZW5ndGhfSUNVX0phdmEoaWN1Q29sbC5nZXRTdHJlbmd0aCgpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGhhc2hDb2RlKCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkZWNvbXBvc2l0aW9uIHJ1bGUgZm9yIHRoaXMgY29sbGF0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZWNvbXBvc2l0aW9uIHJ1bGUsIGVpdGhlciB7QGNvZGUgTk9fREVDT01QT1NJVElPTn0gb3IKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBDQU5PTklDQUxfREVDT01QT1NJVElPTn0uIHtAY29kZSBGVUxMX0RFQ09NUE9TSVRJT059CisgICAgICogICAgICAgICAgICBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICBpZiB0aGUgcHJvdmlkZWQgZGVjb21wb3NpdGlvbiBydWxlIGlzIG5vdCB2YWxpZC4gVGhpcyBpbmNsdWRlcworICAgICAqICAgICAgICAgICAge0Bjb2RlIEZVTExfREVDT01QT1NJVElPTn0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGVjb21wb3NpdGlvbihpbnQgdmFsdWUpIHsKKyAgICAgICAgaWN1Q29sbC5zZXREZWNvbXBvc2l0aW9uKGRlY29tcG9zaXRpb25Nb2RlX0phdmFfSUNVKHZhbHVlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc3RyZW5ndGggdmFsdWUgZm9yIHRoaXMgY29sbGF0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJlbmd0aCB2YWx1ZSwgZWl0aGVyIFBSSU1BUlksIFNFQ09OREFSWSwgVEVSVElBUlksIG9yCisgICAgICogICAgICAgICAgICBJREVOVElDQUwuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIGlmIHRoZSBwcm92aWRlZCBzdHJlbmd0aCB2YWx1ZSBpcyBub3QgdmFsaWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3RyZW5ndGgoaW50IHZhbHVlKSB7CisgICAgICAgIGljdUNvbGwuc2V0U3RyZW5ndGgoc3RyZW5ndGhfSmF2YV9JQ1UodmFsdWUpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBkZWNvbXBvc2l0aW9uTW9kZV9KYXZhX0lDVShpbnQgbW9kZSkgeworICAgICAgICBzd2l0Y2ggKG1vZGUpIHsKKyAgICAgICAgY2FzZSBDb2xsYXRvci5DQU5PTklDQUxfREVDT01QT1NJVElPTjoKKyAgICAgICAgICAgIHJldHVybiBSdWxlQmFzZWRDb2xsYXRvcklDVS5WQUxVRV9PTjsKKyAgICAgICAgY2FzZSBDb2xsYXRvci5OT19ERUNPTVBPU0lUSU9OOgorICAgICAgICAgICAgcmV0dXJuIFJ1bGVCYXNlZENvbGxhdG9ySUNVLlZBTFVFX09GRjsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgZGVjb21wb3NpdGlvbk1vZGVfSUNVX0phdmEoaW50IG1vZGUpIHsKKyAgICAgICAgaW50IGphdmFNb2RlID0gbW9kZTsKKyAgICAgICAgc3dpdGNoIChtb2RlKSB7CisgICAgICAgIGNhc2UgUnVsZUJhc2VkQ29sbGF0b3JJQ1UuVkFMVUVfT0ZGOgorICAgICAgICAgICAgamF2YU1vZGUgPSBDb2xsYXRvci5OT19ERUNPTVBPU0lUSU9OOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgUnVsZUJhc2VkQ29sbGF0b3JJQ1UuVkFMVUVfT046CisgICAgICAgICAgICBqYXZhTW9kZSA9IENvbGxhdG9yLkNBTk9OSUNBTF9ERUNPTVBPU0lUSU9OOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGphdmFNb2RlOworICAgIH0KKworICAgIHByaXZhdGUgaW50IHN0cmVuZ3RoX0phdmFfSUNVKGludCB2YWx1ZSkgeworICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CisgICAgICAgIGNhc2UgQ29sbGF0b3IuUFJJTUFSWToKKyAgICAgICAgICAgIHJldHVybiBSdWxlQmFzZWRDb2xsYXRvcklDVS5WQUxVRV9QUklNQVJZOworICAgICAgICBjYXNlIENvbGxhdG9yLlNFQ09OREFSWToKKyAgICAgICAgICAgIHJldHVybiBSdWxlQmFzZWRDb2xsYXRvcklDVS5WQUxVRV9TRUNPTkRBUlk7CisgICAgICAgIGNhc2UgQ29sbGF0b3IuVEVSVElBUlk6CisgICAgICAgICAgICByZXR1cm4gUnVsZUJhc2VkQ29sbGF0b3JJQ1UuVkFMVUVfVEVSVElBUlk7CisgICAgICAgIGNhc2UgQ29sbGF0b3IuSURFTlRJQ0FMOgorICAgICAgICAgICAgcmV0dXJuIFJ1bGVCYXNlZENvbGxhdG9ySUNVLlZBTFVFX0lERU5USUNBTDsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgc3RyZW5ndGhfSUNVX0phdmEoaW50IHZhbHVlKSB7CisgICAgICAgIGludCBqYXZhVmFsdWUgPSB2YWx1ZTsKKyAgICAgICAgc3dpdGNoICh2YWx1ZSkgeworICAgICAgICBjYXNlIFJ1bGVCYXNlZENvbGxhdG9ySUNVLlZBTFVFX1BSSU1BUlk6CisgICAgICAgICAgICBqYXZhVmFsdWUgPSBDb2xsYXRvci5QUklNQVJZOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgUnVsZUJhc2VkQ29sbGF0b3JJQ1UuVkFMVUVfU0VDT05EQVJZOgorICAgICAgICAgICAgamF2YVZhbHVlID0gQ29sbGF0b3IuU0VDT05EQVJZOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgUnVsZUJhc2VkQ29sbGF0b3JJQ1UuVkFMVUVfVEVSVElBUlk6CisgICAgICAgICAgICBqYXZhVmFsdWUgPSBDb2xsYXRvci5URVJUSUFSWTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFJ1bGVCYXNlZENvbGxhdG9ySUNVLlZBTFVFX0lERU5USUNBTDoKKyAgICAgICAgICAgIGphdmFWYWx1ZSA9IENvbGxhdG9yLklERU5USUNBTDsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHJldHVybiBqYXZhVmFsdWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9EYXRlRm9ybWF0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0RhdGVGb3JtYXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MDU1ZDIwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9EYXRlRm9ybWF0LmphdmEKQEAgLTAsMCArMSw5MDEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudGV4dDsKKworaW1wb3J0IGphdmEuaW8uSW52YWxpZE9iamVjdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5UaW1lWm9uZTsKK2ltcG9ydCBsaWJjb3JlLmljdS5JQ1U7CitpbXBvcnQgbGliY29yZS5pY3UuTG9jYWxlRGF0YTsKKworLyoqCisgKiBBbiBhYnN0cmFjdCBjbGFzcyBmb3IgZGF0ZS90aW1lIGZvcm1hdHRpbmcgc3ViY2xhc3NlcyB3aGljaCBmb3JtYXRzIGFuZAorICogcGFyc2VzIGRhdGVzIG9yIHRpbWUgaW4gYSBsYW5ndWFnZS1pbmRlcGVuZGVudCBtYW5uZXIuIFRoZSBkYXRlL3RpbWUKKyAqIGZvcm1hdHRpbmcgc3ViY2xhc3MsIHN1Y2ggYXMge0BsaW5rIFNpbXBsZURhdGVGb3JtYXR9LCBhbGxvd3MgZm9yIGZvcm1hdHRpbmcKKyAqIChpLmUuLCBkYXRlIC0+IHRleHQpLCBwYXJzaW5nICh0ZXh0IC0+IGRhdGUpLCBhbmQgbm9ybWFsaXphdGlvbi4gVGhlIGRhdGUgaXMKKyAqIHJlcHJlc2VudGVkIGFzIGEge0Bjb2RlIERhdGV9IG9iamVjdCBvciBhcyB0aGUgbWlsbGlzZWNvbmRzIHNpbmNlIEphbnVhcnkgMSwKKyAqIDE5NzAsIDAwOjAwOjAwIEdNVC4KKyAqIDxwPgorICogRGF0ZUZvcm1hdCBwcm92aWRlcyBtYW55IGNsYXNzIG1ldGhvZHMgZm9yIG9idGFpbmluZyBkZWZhdWx0IGRhdGUvdGltZQorICogZm9ybWF0dGVycyBiYXNlZCBvbiB0aGUgZGVmYXVsdCBvciBhIGdpdmVuIGxvY2FsZSBhbmQgYSBudW1iZXIgb2YgZm9ybWF0dGluZworICogc3R5bGVzLiBUaGUgZm9ybWF0dGluZyBzdHlsZXMgaW5jbHVkZSBGVUxMLCBMT05HLCBNRURJVU0sIGFuZCBTSE9SVC4gTW9yZQorICogZGV0YWlscyBhbmQgZXhhbXBsZXMgZm9yIHVzaW5nIHRoZXNlIHN0eWxlcyBhcmUgcHJvdmlkZWQgaW4gdGhlIG1ldGhvZAorICogZGVzY3JpcHRpb25zLgorICogPHA+CisgKiB7QGNvZGUgRGF0ZUZvcm1hdH0gaGVscHMgeW91IHRvIGZvcm1hdCBhbmQgcGFyc2UgZGF0ZXMgZm9yIGFueSBsb2NhbGUuIFlvdXIKKyAqIGNvZGUgY2FuIGJlIGNvbXBsZXRlbHkgaW5kZXBlbmRlbnQgb2YgdGhlIGxvY2FsZSBjb252ZW50aW9ucyBmb3IgbW9udGhzLCBkYXlzCisgKiBvZiB0aGUgd2Vlaywgb3IgZXZlbiB0aGUgY2FsZW5kYXIgZm9ybWF0OiBsdW5hciB2cy4gc29sYXIuCisgKiA8cD4KKyAqIFRvIGZvcm1hdCBhIGRhdGUgZm9yIHRoZSBjdXJyZW50IExvY2FsZSwgdXNlIG9uZSBvZiB0aGUgc3RhdGljIGZhY3RvcnkKKyAqIG1ldGhvZHM6CisgKiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogbXlTdHJpbmcgPSBEYXRlRm9ybWF0LmdldERhdGVJbnN0YW5jZSgpLmZvcm1hdChteURhdGUpOworICogPC9wcmU+CisgKgorICogPC9ibG9ja3F1b3RlPgorICogPHA+CisgKiBJZiB5b3UgYXJlIGZvcm1hdHRpbmcgbXVsdGlwbGUgZGF0ZXMsIGl0IGlzIG1vcmUgZWZmaWNpZW50IHRvIGdldCB0aGUgZm9ybWF0CisgKiBhbmQgdXNlIGl0IG11bHRpcGxlIHRpbWVzIHNvIHRoYXQgdGhlIHN5c3RlbSBkb2Vzbid0IGhhdmUgdG8gZmV0Y2ggdGhlCisgKiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbG9jYWwgbGFuZ3VhZ2UgYW5kIGNvdW50cnkgY29udmVudGlvbnMgbXVsdGlwbGUgdGltZXMuCisgKiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogRGF0ZUZvcm1hdCBkZiA9IERhdGVGb3JtYXQuZ2V0RGF0ZUluc3RhbmNlKCk7CisgKiBmb3IgKGludCBpID0gMDsgaSAmbHQ7IGEubGVuZ3RoOyArK2kpIHsKKyAqICAgICBvdXRwdXQucHJpbnRsbihkZi5mb3JtYXQobXlEYXRlW2ldKSArICZxdW90OzsgJnF1b3Q7KTsKKyAqIH0KKyAqIDwvcHJlPgorICoKKyAqIDwvYmxvY2txdW90ZT4KKyAqIDxwPgorICogVG8gZm9ybWF0IGEgbnVtYmVyIGZvciBhIGRpZmZlcmVudCBsb2NhbGUsIHNwZWNpZnkgaXQgaW4gdGhlIGNhbGwgdG8KKyAqIHtAY29kZSBnZXREYXRlSW5zdGFuY2V9OgorICogPGJsb2NrcXVvdGU+CisgKgorICogPHByZT4KKyAqIERhdGVGb3JtYXQgZGYgPSBEYXRlRm9ybWF0LmdldERhdGVJbnN0YW5jZShEYXRlRm9ybWF0LkxPTkcsIExvY2FsZS5GUkFOQ0UpOworICogPC9wcmU+CisgKgorICogPC9ibG9ja3F1b3RlPgorICogPHA+CisgKiB7QGNvZGUgRGF0ZUZvcm1hdH0gY2FuIGFsc28gYmUgdXNlZCB0byBwYXJzZSBzdHJpbmdzOgorICogPGJsb2NrcXVvdGU+CisgKgorICogPHByZT4KKyAqIG15RGF0ZSA9IGRmLnBhcnNlKG15U3RyaW5nKTsKKyAqIDwvcHJlPgorICoKKyAqIDwvYmxvY2txdW90ZT4KKyAqIDxwPgorICogVXNlIHtAY29kZSBnZXREYXRlSW5zdGFuY2V9IHRvIGdldCB0aGUgbm9ybWFsIGRhdGUgZm9ybWF0IGZvciBhIGNvdW50cnkuCisgKiBPdGhlciBzdGF0aWMgZmFjdG9yeSBtZXRob2RzIGFyZSBhdmFpbGFibGU6IFVzZSB7QGNvZGUgZ2V0VGltZUluc3RhbmNlfSB0bworICogZ2V0IHRoZSB0aW1lIGZvcm1hdCBmb3IgYSBjb3VudHJ5LiBVc2Uge0Bjb2RlIGdldERhdGVUaW1lSW5zdGFuY2V9IHRvIGdldCB0aGUKKyAqIGRhdGUgYW5kIHRpbWUgZm9ybWF0LiBZb3UgY2FuIHBhc3MgaW4gZGlmZmVyZW50IG9wdGlvbnMgdG8gdGhlc2UgZmFjdG9yeQorICogbWV0aG9kcyB0byBjb250cm9sIHRoZSBsZW5ndGggb2YgdGhlIHJlc3VsdDsgZnJvbSBTSE9SVCB0byBNRURJVU0gdG8gTE9ORyB0bworICogRlVMTC4gVGhlIGV4YWN0IHJlc3VsdCBkZXBlbmRzIG9uIHRoZSBsb2NhbGUsIGJ1dCBnZW5lcmFsbHk6CisgKiA8dWw+CisgKiA8bGk+U0hPUlQgaXMgY29tcGxldGVseSBudW1lcmljLCBzdWNoIGFzIDEyLjEzLjUyIG9yIDM6MzBwbQorICogPGxpPk1FRElVTSBpcyBsb25nZXIsIHN1Y2ggYXMgSmFuIDEyLCAxOTUyCisgKiA8bGk+TE9ORyBpcyBsb25nZXIsIHN1Y2ggYXMgSmFudWFyeSAxMiwgMTk1MiBvciAzOjMwOjMycG0KKyAqIDxsaT5GVUxMIGlzIHByZXR0eSBjb21wbGV0ZWx5IHNwZWNpZmllZCwgc3VjaCBhcyBUdWVzZGF5LCBBcHJpbCAxMiwgMTk1MiBBRAorICogb3IgMzozMDo0MnBtIFBTVC4KKyAqIDwvdWw+CisgKiA8cD4KKyAqIElmIG5lZWRlZCwgdGhlIHRpbWUgem9uZSBjYW4gYmUgc2V0IG9uIHRoZSBmb3JtYXQuIEZvciBldmVuIGdyZWF0ZXIgY29udHJvbAorICogb3ZlciB0aGUgZm9ybWF0dGluZyBvciBwYXJzaW5nLCB0cnkgY2FzdGluZyB0aGUge0Bjb2RlIERhdGVGb3JtYXR9IHlvdSBnZXQKKyAqIGZyb20gdGhlIGZhY3RvcnkgbWV0aG9kcyB0byBhIHtAY29kZSBTaW1wbGVEYXRlRm9ybWF0fS4gVGhpcyB3aWxsIHdvcmsgZm9yCisgKiB0aGUgbWFqb3JpdHkgb2YgY291bnRyaWVzOyBqdXN0IHJlbWVtYmVyIHRvIHB1dCBpdCBpbiBhIHRyeSBibG9jayBpbiBjYXNlIHlvdQorICogZW5jb3VudGVyIGFuIHVudXN1YWwgb25lLgorICogPHA+CisgKiBUaGVyZSBhcmUgdmVyc2lvbnMgb2YgdGhlIHBhcnNlIGFuZCBmb3JtYXQgbWV0aG9kcyB3aGljaCB1c2UKKyAqIHtAY29kZSBQYXJzZVBvc2l0aW9ufSBhbmQge0Bjb2RlIEZpZWxkUG9zaXRpb259IHRvIGFsbG93IHlvdSB0bworICogPHVsPgorICogPGxpPnByb2dyZXNzaXZlbHkgcGFyc2UgdGhyb3VnaCBwaWVjZXMgb2YgYSBzdHJpbmc7CisgKiA8bGk+YWxpZ24gYW55IHBhcnRpY3VsYXIgZmllbGQuCisgKiA8L3VsPgorICogPGg0PlN5bmNocm9uaXphdGlvbjwvaDQ+CisgKiA8cD4KKyAqIERhdGUgZm9ybWF0cyBhcmUgbm90IHN5bmNocm9uaXplZC4gSXQgaXMgcmVjb21tZW5kZWQgdG8gY3JlYXRlIHNlcGFyYXRlCisgKiBmb3JtYXQgaW5zdGFuY2VzIGZvciBlYWNoIHRocmVhZC4gSWYgbXVsdGlwbGUgdGhyZWFkcyBhY2Nlc3MgYSBmb3JtYXQKKyAqIGNvbmN1cnJlbnRseSwgaXQgbXVzdCBiZSBzeW5jaHJvbml6ZWQgZXh0ZXJuYWxseS4KKyAqCisgKiBAc2VlIE51bWJlckZvcm1hdAorICogQHNlZSBTaW1wbGVEYXRlRm9ybWF0CisgKiBAc2VlIENhbGVuZGFyCisgKiBAc2VlIFRpbWVab25lCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBEYXRlRm9ybWF0IGV4dGVuZHMgRm9ybWF0IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDcyMTgzMjIzMDY2NDk5NTM3ODhMOworCisgICAgLyoqCisgICAgICogVGhlIGNhbGVuZGFyIHRoYXQgdGhpcyB7QGNvZGUgRGF0ZUZvcm1hdH0gdXNlcyB0byBmb3JtYXQgYSBudW1iZXIKKyAgICAgKiByZXByZXNlbnRpbmcgYSBkYXRlLgorICAgICAqLworICAgIHByb3RlY3RlZCBDYWxlbmRhciBjYWxlbmRhcjsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgZm9ybWF0IHVzZWQgdG8gZm9ybWF0IGEgbnVtYmVyLgorICAgICAqLworICAgIHByb3RlY3RlZCBOdW1iZXJGb3JtYXQgbnVtYmVyRm9ybWF0OworCisgICAgLyoqCisgICAgICogVGhlIGZvcm1hdCBzdHlsZSBjb25zdGFudCBkZWZpbmluZyB0aGUgZGVmYXVsdCBmb3JtYXQgc3R5bGUuIFRoZSBkZWZhdWx0CisgICAgICogaXMgTUVESVVNLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFQgPSAyOworCisgICAgLyoqCisgICAgICogVGhlIGZvcm1hdCBzdHlsZSBjb25zdGFudCBkZWZpbmluZyB0aGUgZnVsbCBzdHlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVUxMID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBmb3JtYXQgc3R5bGUgY29uc3RhbnQgZGVmaW5pbmcgdGhlIGxvbmcgc3R5bGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9ORyA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZm9ybWF0IHN0eWxlIGNvbnN0YW50IGRlZmluaW5nIHRoZSBtZWRpdW0gc3R5bGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUVESVVNID0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSBmb3JtYXQgc3R5bGUgY29uc3RhbnQgZGVmaW5pbmcgdGhlIHNob3J0IHN0eWxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1JUID0gMzsKKworICAgIC8qKgorICAgICAqIFRoZSB7QGNvZGUgRmllbGRQb3NpdGlvbn0gc2VsZWN0b3IgZm9yICdHJyBmaWVsZCBhbGlnbm1lbnQsIGNvcnJlc3BvbmRzCisgICAgICogdG8gdGhlIHtAbGluayBDYWxlbmRhciNFUkF9IGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSQV9GSUVMRCA9IDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUge0Bjb2RlIEZpZWxkUG9zaXRpb259IHNlbGVjdG9yIGZvciAneScgZmllbGQgYWxpZ25tZW50LCBjb3JyZXNwb25kcworICAgICAqIHRvIHRoZSB7QGxpbmsgQ2FsZW5kYXIjWUVBUn0gZmllbGQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgWUVBUl9GSUVMRCA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUge0Bjb2RlIEZpZWxkUG9zaXRpb259IHNlbGVjdG9yIGZvciAnTScgZmllbGQgYWxpZ25tZW50LCBjb3JyZXNwb25kcworICAgICAqIHRvIHRoZSB7QGxpbmsgQ2FsZW5kYXIjTU9OVEh9IGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1PTlRIX0ZJRUxEID0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSB7QGNvZGUgRmllbGRQb3NpdGlvbn0gc2VsZWN0b3IgZm9yICdkJyBmaWVsZCBhbGlnbm1lbnQsIGNvcnJlc3BvbmRzCisgICAgICogdG8gdGhlIHtAbGluayBDYWxlbmRhciNEQVRFfSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEQVRFX0ZJRUxEID0gMzsKKworICAgIC8qKgorICAgICAqIFRoZSB7QGNvZGUgRmllbGRQb3NpdGlvbn0gc2VsZWN0b3IgZm9yICdrJyBmaWVsZCBhbGlnbm1lbnQsIGNvcnJlc3BvbmRzCisgICAgICogdG8gdGhlIHtAbGluayBDYWxlbmRhciNIT1VSX09GX0RBWX0gZmllbGQuIHtAY29kZSBIT1VSX09GX0RBWTFfRklFTER9IGlzCisgICAgICogdXNlZCBmb3IgdGhlIG9uZS1iYXNlZCAyNC1ob3VyIGNsb2NrLiBGb3IgZXhhbXBsZSwgMjM6NTkgKyAwMTowMCByZXN1bHRzCisgICAgICogaW4gMjQ6NTkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSE9VUl9PRl9EQVkxX0ZJRUxEID0gNDsKKworICAgIC8qKgorICAgICAqIFRoZSB7QGNvZGUgRmllbGRQb3NpdGlvbn0gc2VsZWN0b3IgZm9yICdIJyBmaWVsZCBhbGlnbm1lbnQsIGNvcnJlc3BvbmRzCisgICAgICogdG8gdGhlIHtAbGluayBDYWxlbmRhciNIT1VSX09GX0RBWX0gZmllbGQuIHtAY29kZSBIT1VSX09GX0RBWTBfRklFTER9IGlzCisgICAgICogdXNlZCBmb3IgdGhlIHplcm8tYmFzZWQgMjQtaG91ciBjbG9jay4gRm9yIGV4YW1wbGUsIDIzOjU5ICsgMDE6MDAgcmVzdWx0cworICAgICAqIGluIDAwOjU5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhPVVJfT0ZfREFZMF9GSUVMRCA9IDU7CisKKyAgICAvKioKKyAgICAgKiBGaWVsZFBvc2l0aW9uIHNlbGVjdG9yIGZvciAnbScgZmllbGQgYWxpZ25tZW50LCBjb3JyZXNwb25kcyB0byB0aGUKKyAgICAgKiB7QGxpbmsgQ2FsZW5kYXIjTUlOVVRFfSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNSU5VVEVfRklFTEQgPSA2OworCisgICAgLyoqCisgICAgICogRmllbGRQb3NpdGlvbiBzZWxlY3RvciBmb3IgJ3MnIGZpZWxkIGFsaWdubWVudCwgY29ycmVzcG9uZHMgdG8gdGhlCisgICAgICoge0BsaW5rIENhbGVuZGFyI1NFQ09ORH0gZmllbGQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VDT05EX0ZJRUxEID0gNzsKKworICAgIC8qKgorICAgICAqIEZpZWxkUG9zaXRpb24gc2VsZWN0b3IgZm9yICdTJyBmaWVsZCBhbGlnbm1lbnQsIGNvcnJlc3BvbmRzIHRvIHRoZQorICAgICAqIHtAbGluayBDYWxlbmRhciNNSUxMSVNFQ09ORH0gZmllbGQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUlMTElTRUNPTkRfRklFTEQgPSA4OworCisgICAgLyoqCisgICAgICogRmllbGRQb3NpdGlvbiBzZWxlY3RvciBmb3IgJ0UnIGZpZWxkIGFsaWdubWVudCwgY29ycmVzcG9uZHMgdG8gdGhlCisgICAgICoge0BsaW5rIENhbGVuZGFyI0RBWV9PRl9XRUVLfSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEQVlfT0ZfV0VFS19GSUVMRCA9IDk7CisKKyAgICAvKioKKyAgICAgKiBGaWVsZFBvc2l0aW9uIHNlbGVjdG9yIGZvciAnRCcgZmllbGQgYWxpZ25tZW50LCBjb3JyZXNwb25kcyB0byB0aGUKKyAgICAgKiB7QGxpbmsgQ2FsZW5kYXIjREFZX09GX1lFQVJ9IGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERBWV9PRl9ZRUFSX0ZJRUxEID0gMTA7CisKKyAgICAvKioKKyAgICAgKiBGaWVsZFBvc2l0aW9uIHNlbGVjdG9yIGZvciAnRicgZmllbGQgYWxpZ25tZW50LCBjb3JyZXNwb25kcyB0byB0aGUKKyAgICAgKiB7QGxpbmsgQ2FsZW5kYXIjREFZX09GX1dFRUtfSU5fTU9OVEh9IGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERBWV9PRl9XRUVLX0lOX01PTlRIX0ZJRUxEID0gMTE7CisKKyAgICAvKioKKyAgICAgKiBGaWVsZFBvc2l0aW9uIHNlbGVjdG9yIGZvciAndycgZmllbGQgYWxpZ25tZW50LCBjb3JyZXNwb25kcyB0byB0aGUKKyAgICAgKiB7QGxpbmsgQ2FsZW5kYXIjV0VFS19PRl9ZRUFSfSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXRUVLX09GX1lFQVJfRklFTEQgPSAxMjsKKworICAgIC8qKgorICAgICAqIEZpZWxkUG9zaXRpb24gc2VsZWN0b3IgZm9yICdXJyBmaWVsZCBhbGlnbm1lbnQsIGNvcnJlc3BvbmRzIHRvIHRoZQorICAgICAqIHtAbGluayBDYWxlbmRhciNXRUVLX09GX01PTlRIfSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXRUVLX09GX01PTlRIX0ZJRUxEID0gMTM7CisKKyAgICAvKioKKyAgICAgKiBGaWVsZFBvc2l0aW9uIHNlbGVjdG9yIGZvciAnYScgZmllbGQgYWxpZ25tZW50LCBjb3JyZXNwb25kcyB0byB0aGUKKyAgICAgKiB7QGxpbmsgQ2FsZW5kYXIjQU1fUE19IGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFNX1BNX0ZJRUxEID0gMTQ7CisKKyAgICAvKioKKyAgICAgKiBGaWVsZFBvc2l0aW9uIHNlbGVjdG9yIGZvciAnaCcgZmllbGQgYWxpZ25tZW50LCBjb3JyZXNwb25kaW5nIHRvIHRoZQorICAgICAqIHtAbGluayBDYWxlbmRhciNIT1VSfSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIT1VSMV9GSUVMRCA9IDE1OworCisgICAgLyoqCisgICAgICogVGhlIHtAY29kZSBGaWVsZFBvc2l0aW9ufSBzZWxlY3RvciBmb3IgJ0snIGZpZWxkIGFsaWdubWVudCwgY29ycmVzcG9uZGluZyB0byB0aGUKKyAgICAgKiB7QGxpbmsgQ2FsZW5kYXIjSE9VUn0gZmllbGQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSE9VUjBfRklFTEQgPSAxNjsKKworICAgIC8qKgorICAgICAqIFRoZSB7QGNvZGUgRmllbGRQb3NpdGlvbn0gc2VsZWN0b3IgZm9yICd6JyBmaWVsZCBhbGlnbm1lbnQsIGNvcnJlc3BvbmRzCisgICAgICogdG8gdGhlIHtAbGluayBDYWxlbmRhciNaT05FX09GRlNFVH0gYW5kIHtAbGluayBDYWxlbmRhciNEU1RfT0ZGU0VUfQorICAgICAqIGZpZWxkcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUSU1FWk9ORV9GSUVMRCA9IDE3OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgRGF0ZUZvcm1hdH0uCisgICAgICovCisgICAgcHJvdGVjdGVkIERhdGVGb3JtYXQoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgRGF0ZUZvcm1hdH0gd2l0aCB0aGUgc2FtZSBwcm9wZXJ0aWVzLgorICAgICAqCisgICAgICogQHJldHVybiBhIHNoYWxsb3cgY29weSBvZiB0aGlzIHtAY29kZSBEYXRlRm9ybWF0fS4KKyAgICAgKgorICAgICAqIEBzZWUgamF2YS5sYW5nLkNsb25lYWJsZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIERhdGVGb3JtYXQgY2xvbmUgPSAoRGF0ZUZvcm1hdCkgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgY2xvbmUuY2FsZW5kYXIgPSAoQ2FsZW5kYXIpIGNhbGVuZGFyLmNsb25lKCk7CisgICAgICAgIGNsb25lLm51bWJlckZvcm1hdCA9IChOdW1iZXJGb3JtYXQpIG51bWJlckZvcm1hdC5jbG9uZSgpOworICAgICAgICByZXR1cm4gY2xvbmU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhpcyBkYXRlIGZvcm1hdCB3aXRoIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFuZCBpbmRpY2F0ZXMgaWYgdGhleQorICAgICAqIGFyZSBlcXVhbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB3aXRoIHRoaXMgZGF0ZSBmb3JtYXQuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIG9iamVjdH0gaXMgYSB7QGNvZGUgRGF0ZUZvcm1hdH0gb2JqZWN0IGFuZAorICAgICAqICAgICAgICAgaXQgaGFzIHRoZSBzYW1lIHByb3BlcnRpZXMgYXMgdGhpcyBkYXRlIGZvcm1hdDsge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgI2hhc2hDb2RlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgaWYgKHRoaXMgPT0gb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBEYXRlRm9ybWF0KSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIERhdGVGb3JtYXQgZGF0ZUZvcm1hdCA9IChEYXRlRm9ybWF0KSBvYmplY3Q7CisgICAgICAgIHJldHVybiBudW1iZXJGb3JtYXQuZXF1YWxzKGRhdGVGb3JtYXQubnVtYmVyRm9ybWF0KQorICAgICAgICAgICAgICAgICYmIGNhbGVuZGFyLmdldFRpbWVab25lKCkuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgZGF0ZUZvcm1hdC5jYWxlbmRhci5nZXRUaW1lWm9uZSgpKQorICAgICAgICAgICAgICAgICYmIGNhbGVuZGFyLmdldEZpcnN0RGF5T2ZXZWVrKCkgPT0gZGF0ZUZvcm1hdC5jYWxlbmRhcgorICAgICAgICAgICAgICAgICAgICAgICAgLmdldEZpcnN0RGF5T2ZXZWVrKCkKKyAgICAgICAgICAgICAgICAmJiBjYWxlbmRhci5nZXRNaW5pbWFsRGF5c0luRmlyc3RXZWVrKCkgPT0gZGF0ZUZvcm1hdC5jYWxlbmRhcgorICAgICAgICAgICAgICAgICAgICAgICAgLmdldE1pbmltYWxEYXlzSW5GaXJzdFdlZWsoKQorICAgICAgICAgICAgICAgICYmIGNhbGVuZGFyLmlzTGVuaWVudCgpID09IGRhdGVGb3JtYXQuY2FsZW5kYXIuaXNMZW5pZW50KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRm9ybWF0cyB0aGUgc3BlY2lmaWVkIG9iamVjdCBhcyBhIHN0cmluZyB1c2luZyB0aGUgcGF0dGVybiBvZiB0aGlzIGRhdGUKKyAgICAgKiBmb3JtYXQgYW5kIGFwcGVuZHMgdGhlIHN0cmluZyB0byB0aGUgc3BlY2lmaWVkIHN0cmluZyBidWZmZXIuCisgICAgICogPHA+CisgICAgICogSWYgdGhlIHtAY29kZSBmaWVsZH0gbWVtYmVyIG9mIHtAY29kZSBmaWVsZH0gY29udGFpbnMgYSB2YWx1ZSBzcGVjaWZ5aW5nCisgICAgICogYSBmb3JtYXQgZmllbGQsIHRoZW4gaXRzIHtAY29kZSBiZWdpbkluZGV4fSBhbmQge0Bjb2RlIGVuZEluZGV4fSBtZW1iZXJzCisgICAgICogd2lsbCBiZSB1cGRhdGVkIHdpdGggdGhlIHBvc2l0aW9uIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoaXMgZmllbGQKKyAgICAgKiBpbiB0aGUgZm9ybWF0dGVkIHRleHQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIG9iamVjdCB0byBmb3JtYXQsIG11c3QgYmUgYSB7QGNvZGUgRGF0ZX0gb3IgYQorICAgICAqICAgICAgICAgICAge0Bjb2RlIE51bWJlcn0uIElmIHtAY29kZSBvYmplY3R9IGlzIGEgbnVtYmVyIHRoZW4gYSBkYXRlIGlzCisgICAgICogICAgICAgICAgICBjb25zdHJ1Y3RlZCB1c2luZyB0aGUge0Bjb2RlIGxvbmdWYWx1ZSgpfSBvZiB0aGUgbnVtYmVyLgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgc3RyaW5nIGJ1ZmZlciB0byBhcHBlbmQgdGhlIGZvcm1hdHRlZCBkYXRlL3RpbWUgdG8uCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICBvbiBpbnB1dDogYW4gb3B0aW9uYWwgYWxpZ25tZW50IGZpZWxkOyBvbiBvdXRwdXQ6IHRoZSBvZmZzZXRzCisgICAgICogICAgICAgICAgICBvZiB0aGUgYWxpZ25tZW50IGZpZWxkIGluIHRoZSBmb3JtYXR0ZWQgdGV4dC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICBpZiB7QGNvZGUgb2JqZWN0fSBpcyBuZWl0aGVyIGEge0Bjb2RlIERhdGV9IG5vciBhCisgICAgICogICAgICAgICAgICB7QGNvZGUgTnVtYmVyfSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nQnVmZmVyIGZvcm1hdChPYmplY3Qgb2JqZWN0LCBTdHJpbmdCdWZmZXIgYnVmZmVyLAorICAgICAgICAgICAgRmllbGRQb3NpdGlvbiBmaWVsZCkgeworICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgRGF0ZSkgeworICAgICAgICAgICAgcmV0dXJuIGZvcm1hdCgoRGF0ZSkgb2JqZWN0LCBidWZmZXIsIGZpZWxkKTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgTnVtYmVyKSB7CisgICAgICAgICAgICByZXR1cm4gZm9ybWF0KG5ldyBEYXRlKCgoTnVtYmVyKSBvYmplY3QpLmxvbmdWYWx1ZSgpKSwgYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICBmaWVsZCk7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZvcm1hdHMgdGhlIHNwZWNpZmllZCBkYXRlIHVzaW5nIHRoZSBydWxlcyBvZiB0aGlzIGRhdGUgZm9ybWF0LgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRlIHRvIGZvcm1hdC4KKyAgICAgKiBAcmV0dXJuIHRoZSBmb3JtYXR0ZWQgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZm9ybWF0KERhdGUgZGF0ZSkgeworICAgICAgICByZXR1cm4gZm9ybWF0KGRhdGUsIG5ldyBTdHJpbmdCdWZmZXIoKSwgbmV3IEZpZWxkUG9zaXRpb24oMCkpCisgICAgICAgICAgICAgICAgLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRm9ybWF0cyB0aGUgc3BlY2lmaWVkIGRhdGUgYXMgYSBzdHJpbmcgdXNpbmcgdGhlIHBhdHRlcm4gb2YgdGhpcyBkYXRlCisgICAgICogZm9ybWF0IGFuZCBhcHBlbmRzIHRoZSBzdHJpbmcgdG8gdGhlIHNwZWNpZmllZCBzdHJpbmcgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSB7QGNvZGUgZmllbGR9IG1lbWJlciBvZiB7QGNvZGUgZmllbGR9IGNvbnRhaW5zIGEgdmFsdWUgc3BlY2lmeWluZworICAgICAqIGEgZm9ybWF0IGZpZWxkLCB0aGVuIGl0cyB7QGNvZGUgYmVnaW5JbmRleH0gYW5kIHtAY29kZSBlbmRJbmRleH0gbWVtYmVycworICAgICAqIHdpbGwgYmUgdXBkYXRlZCB3aXRoIHRoZSBwb3NpdGlvbiBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGlzIGZpZWxkCisgICAgICogaW4gdGhlIGZvcm1hdHRlZCB0ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRlIHRvIGZvcm1hdC4KKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IHN0cmluZyBidWZmZXIgdG8gYXBwZW5kIHRoZSBmb3JtYXR0ZWQgZGF0ZS90aW1lIHRvLgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgb24gaW5wdXQ6IGFuIG9wdGlvbmFsIGFsaWdubWVudCBmaWVsZDsgb24gb3V0cHV0OiB0aGUgb2Zmc2V0cworICAgICAqICAgICAgICAgICAgb2YgdGhlIGFsaWdubWVudCBmaWVsZCBpbiB0aGUgZm9ybWF0dGVkIHRleHQuCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nQnVmZmVyIGZvcm1hdChEYXRlIGRhdGUsIFN0cmluZ0J1ZmZlciBidWZmZXIsCisgICAgICAgICAgICBGaWVsZFBvc2l0aW9uIGZpZWxkKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgbG9jYWxlcyBmb3Igd2hpY2ggY3VzdG9tIHtAY29kZSBEYXRlRm9ybWF0fSBpbnN0YW5jZXMKKyAgICAgKiBhcmUgYXZhaWxhYmxlLgorICAgICAqIDxwPk5vdGUgdGhhdCBBbmRyb2lkIGRvZXMgbm90IHN1cHBvcnQgdXNlci1zdXBwbGllZCBsb2NhbGUgc2VydmljZSBwcm92aWRlcnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBMb2NhbGVbXSBnZXRBdmFpbGFibGVMb2NhbGVzKCkgeworICAgICAgICByZXR1cm4gSUNVLmdldEF2YWlsYWJsZURhdGVGb3JtYXRMb2NhbGVzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2FsZW5kYXIgdXNlZCBieSB0aGlzIHtAY29kZSBEYXRlRm9ybWF0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNhbGVuZGFyIHVzZWQgYnkgdGhpcyBkYXRlIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2FsZW5kYXIgZ2V0Q2FsZW5kYXIoKSB7CisgICAgICAgIHJldHVybiBjYWxlbmRhcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIERhdGVGb3JtYXR9IGluc3RhbmNlIGZvciBmb3JtYXR0aW5nIGFuZCBwYXJzaW5nIGRhdGVzIGluCisgICAgICogdGhlIERFRkFVTFQgc3R5bGUgZm9yIHRoZSBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBEYXRlRm9ybWF0fSBpbnN0YW5jZSBmb3IgdGhlIGRlZmF1bHQgc3R5bGUgYW5kIGxvY2FsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIERhdGVGb3JtYXQgZ2V0RGF0ZUluc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gZ2V0RGF0ZUluc3RhbmNlKERFRkFVTFQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgRGF0ZUZvcm1hdH0gaW5zdGFuY2UgZm9yIGZvcm1hdHRpbmcgYW5kIHBhcnNpbmcgZGF0ZXMgaW4KKyAgICAgKiB0aGUgc3BlY2lmaWVkIHN0eWxlIGZvciB0aGUgdXNlcidzIGRlZmF1bHQgbG9jYWxlLgorICAgICAqIFNlZSAiPGEgaHJlZj0iLi4vdXRpbC9Mb2NhbGUuaHRtbCNkZWZhdWx0X2xvY2FsZSI+QmUgd2FyeSBvZiB0aGUgZGVmYXVsdCBsb2NhbGU8L2E+Ii4KKyAgICAgKiBAcGFyYW0gc3R5bGUKKyAgICAgKiAgICAgICAgICAgIG9uZSBvZiBTSE9SVCwgTUVESVVNLCBMT05HLCBGVUxMLCBvciBERUZBVUxULgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBEYXRlRm9ybWF0fSBpbnN0YW5jZSBmb3Ige0Bjb2RlIHN0eWxlfSBhbmQgdGhlIGRlZmF1bHQKKyAgICAgKiAgICAgICAgIGxvY2FsZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdHlsZX0gaXMgbm90IG9uZSBvZiBTSE9SVCwgTUVESVVNLCBMT05HLCBGVUxMLCBvcgorICAgICAqICAgICAgICAgICAgIERFRkFVTFQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBEYXRlRm9ybWF0IGdldERhdGVJbnN0YW5jZShpbnQgc3R5bGUpIHsKKyAgICAgICAgY2hlY2tEYXRlU3R5bGUoc3R5bGUpOworICAgICAgICByZXR1cm4gZ2V0RGF0ZUluc3RhbmNlKHN0eWxlLCBMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIERhdGVGb3JtYXR9IGluc3RhbmNlIGZvciBmb3JtYXR0aW5nIGFuZCBwYXJzaW5nIGRhdGVzIGluCisgICAgICogdGhlIHNwZWNpZmllZCBzdHlsZSBmb3IgdGhlIHNwZWNpZmllZCBsb2NhbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3R5bGUKKyAgICAgKiAgICAgICAgICAgIG9uZSBvZiBTSE9SVCwgTUVESVVNLCBMT05HLCBGVUxMLCBvciBERUZBVUxULgorICAgICAqIEBwYXJhbSBsb2NhbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhbGUuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3R5bGV9IGlzIG5vdCBvbmUgb2YgU0hPUlQsIE1FRElVTSwgTE9ORywgRlVMTCwgb3IKKyAgICAgKiAgICAgICAgICAgICBERUZBVUxULgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBEYXRlRm9ybWF0fSBpbnN0YW5jZSBmb3Ige0Bjb2RlIHN0eWxlfSBhbmQKKyAgICAgKiAgICAgICAgIHtAY29kZSBsb2NhbGV9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRGF0ZUZvcm1hdCBnZXREYXRlSW5zdGFuY2UoaW50IHN0eWxlLCBMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIGNoZWNrRGF0ZVN0eWxlKHN0eWxlKTsKKyAgICAgICAgcmV0dXJuIG5ldyBTaW1wbGVEYXRlRm9ybWF0KExvY2FsZURhdGEuZ2V0KGxvY2FsZSkuZ2V0RGF0ZUZvcm1hdChzdHlsZSksIGxvY2FsZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBEYXRlRm9ybWF0fSBpbnN0YW5jZSBmb3IgZm9ybWF0dGluZyBhbmQgcGFyc2luZyBkYXRlcworICAgICAqIGFuZCB0aW1lIHZhbHVlcyBpbiB0aGUgREVGQVVMVCBzdHlsZSBmb3IgdGhlIGRlZmF1bHQgbG9jYWxlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIERhdGVGb3JtYXR9IGluc3RhbmNlIGZvciB0aGUgZGVmYXVsdCBzdHlsZSBhbmQgbG9jYWxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRGF0ZUZvcm1hdCBnZXREYXRlVGltZUluc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gZ2V0RGF0ZVRpbWVJbnN0YW5jZShERUZBVUxULCBERUZBVUxUKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIERhdGVGb3JtYXR9IGluc3RhbmNlIGZvciBmb3JtYXR0aW5nIGFuZCBwYXJzaW5nIG9mIGJvdGgKKyAgICAgKiBkYXRlcyBhbmQgdGltZSB2YWx1ZXMgaW4gdGhlIG1hbm5lciBhcHByb3ByaWF0ZSBmb3IgdGhlIHVzZXIncyBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKiBTZWUgIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuCisgICAgICogQHBhcmFtIGRhdGVTdHlsZQorICAgICAqICAgICAgICAgICAgb25lIG9mIFNIT1JULCBNRURJVU0sIExPTkcsIEZVTEwsIG9yIERFRkFVTFQuCisgICAgICogQHBhcmFtIHRpbWVTdHlsZQorICAgICAqICAgICAgICAgICAgb25lIG9mIFNIT1JULCBNRURJVU0sIExPTkcsIEZVTEwsIG9yIERFRkFVTFQuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIERhdGVGb3JtYXR9IGluc3RhbmNlIGZvciB7QGNvZGUgZGF0ZVN0eWxlfSwKKyAgICAgKiAgICAgICAgIHtAY29kZSB0aW1lU3R5bGV9IGFuZCB0aGUgZGVmYXVsdCBsb2NhbGUuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGF0ZVN0eWxlfSBvciB7QGNvZGUgdGltZVN0eWxlfSBpcyBub3Qgb25lIG9mCisgICAgICogICAgICAgICAgICAgU0hPUlQsIE1FRElVTSwgTE9ORywgRlVMTCwgb3IgREVGQVVMVC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIERhdGVGb3JtYXQgZ2V0RGF0ZVRpbWVJbnN0YW5jZShpbnQgZGF0ZVN0eWxlLCBpbnQgdGltZVN0eWxlKSB7CisgICAgICAgIGNoZWNrVGltZVN0eWxlKHRpbWVTdHlsZSk7CisgICAgICAgIGNoZWNrRGF0ZVN0eWxlKGRhdGVTdHlsZSk7CisgICAgICAgIHJldHVybiBnZXREYXRlVGltZUluc3RhbmNlKGRhdGVTdHlsZSwgdGltZVN0eWxlLCBMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIERhdGVGb3JtYXR9IGluc3RhbmNlIGZvciBmb3JtYXR0aW5nIGFuZCBwYXJzaW5nIGRhdGVzCisgICAgICogYW5kIHRpbWUgdmFsdWVzIGluIHRoZSBzcGVjaWZpZWQgc3R5bGVzIGZvciB0aGUgc3BlY2lmaWVkIGxvY2FsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRlU3R5bGUKKyAgICAgKiAgICAgICAgICAgIG9uZSBvZiBTSE9SVCwgTUVESVVNLCBMT05HLCBGVUxMLCBvciBERUZBVUxULgorICAgICAqIEBwYXJhbSB0aW1lU3R5bGUKKyAgICAgKiAgICAgICAgICAgIG9uZSBvZiBTSE9SVCwgTUVESVVNLCBMT05HLCBGVUxMLCBvciBERUZBVUxULgorICAgICAqIEBwYXJhbSBsb2NhbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhbGUuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIERhdGVGb3JtYXR9IGluc3RhbmNlIGZvciB7QGNvZGUgZGF0ZVN0eWxlfSwKKyAgICAgKiAgICAgICAgIHtAY29kZSB0aW1lU3R5bGV9IGFuZCB7QGNvZGUgbG9jYWxlfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkYXRlU3R5bGV9IG9yIHtAY29kZSB0aW1lU3R5bGV9IGlzIG5vdCBvbmUgb2YKKyAgICAgKiAgICAgICAgICAgICBTSE9SVCwgTUVESVVNLCBMT05HLCBGVUxMLCBvciBERUZBVUxULgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRGF0ZUZvcm1hdCBnZXREYXRlVGltZUluc3RhbmNlKGludCBkYXRlU3R5bGUsIGludCB0aW1lU3R5bGUsIExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgY2hlY2tUaW1lU3R5bGUodGltZVN0eWxlKTsKKyAgICAgICAgY2hlY2tEYXRlU3R5bGUoZGF0ZVN0eWxlKTsKKyAgICAgICAgTG9jYWxlRGF0YSBsb2NhbGVEYXRhID0gTG9jYWxlRGF0YS5nZXQobG9jYWxlKTsKKyAgICAgICAgU3RyaW5nIHBhdHRlcm4gPSBsb2NhbGVEYXRhLmdldERhdGVGb3JtYXQoZGF0ZVN0eWxlKSArICIgIiArIGxvY2FsZURhdGEuZ2V0VGltZUZvcm1hdCh0aW1lU3R5bGUpOworICAgICAgICByZXR1cm4gbmV3IFNpbXBsZURhdGVGb3JtYXQocGF0dGVybiwgbG9jYWxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIERhdGVGb3JtYXR9IGluc3RhbmNlIGZvciBmb3JtYXR0aW5nIGFuZCBwYXJzaW5nIGRhdGVzCisgICAgICogYW5kIHRpbWVzIGluIHRoZSBTSE9SVCBzdHlsZSBmb3IgdGhlIGRlZmF1bHQgbG9jYWxlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIERhdGVGb3JtYXR9IGluc3RhbmNlIGZvciB0aGUgU0hPUlQgc3R5bGUgYW5kIGRlZmF1bHQKKyAgICAgKiAgICAgICAgIGxvY2FsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIERhdGVGb3JtYXQgZ2V0SW5zdGFuY2UoKSB7CisgICAgICAgIHJldHVybiBnZXREYXRlVGltZUluc3RhbmNlKFNIT1JULCBTSE9SVCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIE51bWJlckZvcm1hdH0gdXNlZCBieSB0aGlzIHtAY29kZSBEYXRlRm9ybWF0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBOdW1iZXJGb3JtYXR9IHVzZWQgYnkgdGhpcyBkYXRlIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTnVtYmVyRm9ybWF0IGdldE51bWJlckZvcm1hdCgpIHsKKyAgICAgICAgcmV0dXJuIG51bWJlckZvcm1hdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIERhdGVGb3JtYXR9IGluc3RhbmNlIGZvciBmb3JtYXR0aW5nIGFuZCBwYXJzaW5nIHRpbWUKKyAgICAgKiB2YWx1ZXMgaW4gdGhlIERFRkFVTFQgc3R5bGUgZm9yIHRoZSBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBEYXRlRm9ybWF0fSBpbnN0YW5jZSBmb3IgdGhlIGRlZmF1bHQgc3R5bGUgYW5kIGxvY2FsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIERhdGVGb3JtYXQgZ2V0VGltZUluc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gZ2V0VGltZUluc3RhbmNlKERFRkFVTFQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgRGF0ZUZvcm1hdH0gaW5zdGFuY2UgZm9yIGZvcm1hdHRpbmcgYW5kIHBhcnNpbmcgdGltZQorICAgICAqIHZhbHVlcyBpbiB0aGUgc3BlY2lmaWVkIHN0eWxlIGZvciB0aGUgdXNlcidzIGRlZmF1bHQgbG9jYWxlLgorICAgICAqIFNlZSAiPGEgaHJlZj0iLi4vdXRpbC9Mb2NhbGUuaHRtbCNkZWZhdWx0X2xvY2FsZSI+QmUgd2FyeSBvZiB0aGUgZGVmYXVsdCBsb2NhbGU8L2E+Ii4KKyAgICAgKiBAcGFyYW0gc3R5bGUKKyAgICAgKiAgICAgICAgICAgIG9uZSBvZiBTSE9SVCwgTUVESVVNLCBMT05HLCBGVUxMLCBvciBERUZBVUxULgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBEYXRlRm9ybWF0fSBpbnN0YW5jZSBmb3Ige0Bjb2RlIHN0eWxlfSBhbmQgdGhlIGRlZmF1bHQKKyAgICAgKiAgICAgICAgIGxvY2FsZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzdHlsZX0gaXMgbm90IG9uZSBvZiBTSE9SVCwgTUVESVVNLCBMT05HLCBGVUxMLCBvcgorICAgICAqICAgICAgICAgICAgIERFRkFVTFQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBEYXRlRm9ybWF0IGdldFRpbWVJbnN0YW5jZShpbnQgc3R5bGUpIHsKKyAgICAgICAgY2hlY2tUaW1lU3R5bGUoc3R5bGUpOworICAgICAgICByZXR1cm4gZ2V0VGltZUluc3RhbmNlKHN0eWxlLCBMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIERhdGVGb3JtYXR9IGluc3RhbmNlIGZvciBmb3JtYXR0aW5nIGFuZCBwYXJzaW5nIHRpbWUKKyAgICAgKiB2YWx1ZXMgaW4gdGhlIHNwZWNpZmllZCBzdHlsZSBmb3IgdGhlIHNwZWNpZmllZCBsb2NhbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3R5bGUKKyAgICAgKiAgICAgICAgICAgIG9uZSBvZiBTSE9SVCwgTUVESVVNLCBMT05HLCBGVUxMLCBvciBERUZBVUxULgorICAgICAqIEBwYXJhbSBsb2NhbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhbGUuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3R5bGV9IGlzIG5vdCBvbmUgb2YgU0hPUlQsIE1FRElVTSwgTE9ORywgRlVMTCwgb3IKKyAgICAgKiAgICAgICAgICAgICBERUZBVUxULgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBEYXRlRm9ybWF0fSBpbnN0YW5jZSBmb3Ige0Bjb2RlIHN0eWxlfSBhbmQKKyAgICAgKiAgICAgICAgIHtAY29kZSBsb2NhbGV9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRGF0ZUZvcm1hdCBnZXRUaW1lSW5zdGFuY2UoaW50IHN0eWxlLCBMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIGNoZWNrVGltZVN0eWxlKHN0eWxlKTsKKyAgICAgICAgcmV0dXJuIG5ldyBTaW1wbGVEYXRlRm9ybWF0KExvY2FsZURhdGEuZ2V0KGxvY2FsZSkuZ2V0VGltZUZvcm1hdChzdHlsZSksIGxvY2FsZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGltZSB6b25lIG9mIHRoaXMgZGF0ZSBmb3JtYXQncyBjYWxlbmRhci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHRpbWUgem9uZSBvZiB0aGUgY2FsZW5kYXIgdXNlZCBieSB0aGlzIGRhdGUgZm9ybWF0LgorICAgICAqLworICAgIHB1YmxpYyBUaW1lWm9uZSBnZXRUaW1lWm9uZSgpIHsKKyAgICAgICAgcmV0dXJuIGNhbGVuZGFyLmdldFRpbWVab25lKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIGNhbGVuZGFyLmdldEZpcnN0RGF5T2ZXZWVrKCkKKyAgICAgICAgICAgICAgICArIGNhbGVuZGFyLmdldE1pbmltYWxEYXlzSW5GaXJzdFdlZWsoKQorICAgICAgICAgICAgICAgICsgY2FsZW5kYXIuZ2V0VGltZVpvbmUoKS5oYXNoQ29kZSgpCisgICAgICAgICAgICAgICAgKyAoY2FsZW5kYXIuaXNMZW5pZW50KCkgPyAxMjMxIDogMTIzNykKKyAgICAgICAgICAgICAgICArIG51bWJlckZvcm1hdC5oYXNoQ29kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBjYWxlbmRhciB1c2VkIGJ5IHRoaXMgZGF0ZSBmb3JtYXQgaXMgbGVuaWVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBjYWxlbmRhciBpcyBsZW5pZW50OyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0xlbmllbnQoKSB7CisgICAgICAgIHJldHVybiBjYWxlbmRhci5pc0xlbmllbnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgYSBkYXRlIGZyb20gdGhlIHNwZWNpZmllZCBzdHJpbmcgdXNpbmcgdGhlIHJ1bGVzIG9mIHRoaXMgZGF0ZQorICAgICAqIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gcGFyc2UuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIERhdGV9IHJlc3VsdGluZyBmcm9tIHRoZSBwYXJzaW5nLgorICAgICAqIEB0aHJvd3MgUGFyc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBkdXJpbmcgcGFyc2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0ZSBwYXJzZShTdHJpbmcgc3RyaW5nKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24geworICAgICAgICBQYXJzZVBvc2l0aW9uIHBvc2l0aW9uID0gbmV3IFBhcnNlUG9zaXRpb24oMCk7CisgICAgICAgIERhdGUgZGF0ZSA9IHBhcnNlKHN0cmluZywgcG9zaXRpb24pOworICAgICAgICBpZiAocG9zaXRpb24uZ2V0SW5kZXgoKSA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oIlVucGFyc2VhYmxlIGRhdGU6IFwiIiArIHN0cmluZyArICJcIiIsCisgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uLmdldEVycm9ySW5kZXgoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRhdGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIGEgZGF0ZSBmcm9tIHRoZSBzcGVjaWZpZWQgc3RyaW5nIHN0YXJ0aW5nIGF0IHRoZSBpbmRleCBzcGVjaWZpZWQKKyAgICAgKiBieSB7QGNvZGUgcG9zaXRpb259LiBJZiB0aGUgc3RyaW5nIGlzIHN1Y2Nlc3NmdWxseSBwYXJzZWQgdGhlbiB0aGUgaW5kZXgKKyAgICAgKiBvZiB0aGUge0Bjb2RlIFBhcnNlUG9zaXRpb259IGlzIHVwZGF0ZWQgdG8gdGhlIGluZGV4IGZvbGxvd2luZyB0aGUgcGFyc2VkCisgICAgICogdGV4dC4gT24gZXJyb3IsIHRoZSBpbmRleCBpcyB1bmNoYW5nZWQgYW5kIHRoZSBlcnJvciBpbmRleCBvZiB7QGNvZGUKKyAgICAgKiBQYXJzZVBvc2l0aW9ufSBpcyBzZXQgdG8gdGhlIGluZGV4IHdoZXJlIHRoZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKiA8cD4KKyAgICAgKiBCeSBkZWZhdWx0LCBwYXJzaW5nIGlzIGxlbmllbnQ6IElmIHRoZSBpbnB1dCBpcyBub3QgaW4gdGhlIGZvcm0gdXNlZCBieQorICAgICAqIHRoaXMgb2JqZWN0J3MgZm9ybWF0IG1ldGhvZCBidXQgY2FuIHN0aWxsIGJlIHBhcnNlZCBhcyBhIGRhdGUsIHRoZW4gdGhlCisgICAgICogcGFyc2Ugc3VjY2VlZHMuIENsaWVudHMgbWF5IGluc2lzdCBvbiBzdHJpY3QgYWRoZXJlbmNlIHRvIHRoZSBmb3JtYXQgYnkKKyAgICAgKiBjYWxsaW5nIHtAY29kZSBzZXRMZW5pZW50KGZhbHNlKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHBhcnNlLgorICAgICAqIEBwYXJhbSBwb3NpdGlvbgorICAgICAqICAgICAgICAgICAgaW5wdXQvb3V0cHV0IHBhcmFtZXRlciwgc3BlY2lmaWVzIHRoZSBzdGFydCBpbmRleCBpbiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIHN0cmluZ30gZnJvbSB3aGVyZSB0byBzdGFydCBwYXJzaW5nLiBJZiBwYXJzaW5nIGlzIHN1Y2Nlc3NmdWwsCisgICAgICogICAgICAgICAgICBpdCBpcyB1cGRhdGVkIHdpdGggdGhlIGluZGV4IGZvbGxvd2luZyB0aGUgcGFyc2VkIHRleHQ7IG9uCisgICAgICogICAgICAgICAgICBlcnJvciwgdGhlIGluZGV4IGlzIHVuY2hhbmdlZCBhbmQgdGhlIGVycm9yIGluZGV4IGlzIHNldCB0bworICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHdoZXJlIHRoZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBkYXRlIHJlc3VsdGluZyBmcm9tIHRoZSBwYXJzZSwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIGFuCisgICAgICogICAgICAgICBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRGF0ZSBwYXJzZShTdHJpbmcgc3RyaW5nLCBQYXJzZVBvc2l0aW9uIHBvc2l0aW9uKTsKKworICAgIC8qKgorICAgICAqIFBhcnNlcyBhIGRhdGUgZnJvbSB0aGUgc3BlY2lmaWVkIHN0cmluZyBzdGFydGluZyBhdCB0aGUgaW5kZXggc3BlY2lmaWVkCisgICAgICogYnkge0Bjb2RlIHBvc2l0aW9ufS4gSWYgdGhlIHN0cmluZyBpcyBzdWNjZXNzZnVsbHkgcGFyc2VkIHRoZW4gdGhlIGluZGV4CisgICAgICogb2YgdGhlIHtAY29kZSBQYXJzZVBvc2l0aW9ufSBpcyB1cGRhdGVkIHRvIHRoZSBpbmRleCBmb2xsb3dpbmcgdGhlIHBhcnNlZAorICAgICAqIHRleHQuIE9uIGVycm9yLCB0aGUgaW5kZXggaXMgdW5jaGFuZ2VkIGFuZCB0aGUgZXJyb3IgaW5kZXggb2YKKyAgICAgKiB7QGNvZGUgUGFyc2VQb3NpdGlvbn0gaXMgc2V0IHRvIHRoZSBpbmRleCB3aGVyZSB0aGUgZXJyb3Igb2NjdXJyZWQuCisgICAgICogPHA+CisgICAgICogQnkgZGVmYXVsdCwgcGFyc2luZyBpcyBsZW5pZW50OiBJZiB0aGUgaW5wdXQgaXMgbm90IGluIHRoZSBmb3JtIHVzZWQgYnkKKyAgICAgKiB0aGlzIG9iamVjdCdzIGZvcm1hdCBtZXRob2QgYnV0IGNhbiBzdGlsbCBiZSBwYXJzZWQgYXMgYSBkYXRlLCB0aGVuIHRoZQorICAgICAqIHBhcnNlIHN1Y2NlZWRzLiBDbGllbnRzIG1heSBpbnNpc3Qgb24gc3RyaWN0IGFkaGVyZW5jZSB0byB0aGUgZm9ybWF0IGJ5CisgICAgICogY2FsbGluZyB7QGNvZGUgc2V0TGVuaWVudChmYWxzZSl9LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBwYXJzZS4KKyAgICAgKiBAcGFyYW0gcG9zaXRpb24KKyAgICAgKiAgICAgICAgICAgIGlucHV0L291dHB1dCBwYXJhbWV0ZXIsIHNwZWNpZmllcyB0aGUgc3RhcnQgaW5kZXggaW4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBzdHJpbmd9IGZyb20gd2hlcmUgdG8gc3RhcnQgcGFyc2luZy4gSWYgcGFyc2luZyBpcworICAgICAqICAgICAgICAgICAgc3VjY2Vzc2Z1bCwgaXQgaXMgdXBkYXRlZCB3aXRoIHRoZSBpbmRleCBmb2xsb3dpbmcgdGhlIHBhcnNlZAorICAgICAqICAgICAgICAgICAgdGV4dDsgb24gZXJyb3IsIHRoZSBpbmRleCBpcyB1bmNoYW5nZWQgYW5kIHRoZSBlcnJvciBpbmRleAorICAgICAqICAgICAgICAgICAgaXMgc2V0IHRvIHRoZSBpbmRleCB3aGVyZSB0aGUgZXJyb3Igb2NjdXJyZWQuCisgICAgICogQHJldHVybiB0aGUgZGF0ZSByZXN1bHRpbmcgZnJvbSB0aGUgcGFyc2luZywgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzCisgICAgICogICAgICAgICBhbiBlcnJvci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IHBhcnNlT2JqZWN0KFN0cmluZyBzdHJpbmcsIFBhcnNlUG9zaXRpb24gcG9zaXRpb24pIHsKKyAgICAgICAgcmV0dXJuIHBhcnNlKHN0cmluZywgcG9zaXRpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNhbGVuZGFyIHVzZWQgYnkgdGhpcyBkYXRlIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgY2FsZW5kYXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q2FsZW5kYXIoQ2FsZW5kYXIgY2FsKSB7CisgICAgICAgIGNhbGVuZGFyID0gY2FsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNwZWNpZmllcyB3aGV0aGVyIG9yIG5vdCBkYXRlL3RpbWUgcGFyc2luZyBzaGFsbCBiZSBsZW5pZW50LiBXaXRoIGxlbmllbnQKKyAgICAgKiBwYXJzaW5nLCB0aGUgcGFyc2VyIG1heSB1c2UgaGV1cmlzdGljcyB0byBpbnRlcnByZXQgaW5wdXRzIHRoYXQgZG8gbm90CisgICAgICogcHJlY2lzZWx5IG1hdGNoIHRoaXMgb2JqZWN0J3MgZm9ybWF0LiBXaXRoIHN0cmljdCBwYXJzaW5nLCBpbnB1dHMgbXVzdAorICAgICAqIG1hdGNoIHRoaXMgb2JqZWN0J3MgZm9ybWF0LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gdG8gc2V0IHRoZSBjYWxlbmRhciB0byBiZSBsZW5pZW50LCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TGVuaWVudChib29sZWFuIHZhbHVlKSB7CisgICAgICAgIGNhbGVuZGFyLnNldExlbmllbnQodmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHtAY29kZSBOdW1iZXJGb3JtYXR9IHVzZWQgYnkgdGhpcyBkYXRlIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmb3JtYXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgbnVtYmVyIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROdW1iZXJGb3JtYXQoTnVtYmVyRm9ybWF0IGZvcm1hdCkgeworICAgICAgICBudW1iZXJGb3JtYXQgPSBmb3JtYXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdGltZSB6b25lIG9mIHRoZSBjYWxlbmRhciB1c2VkIGJ5IHRoaXMgZGF0ZSBmb3JtYXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGltZXpvbmUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgdGltZSB6b25lLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRpbWVab25lKFRpbWVab25lIHRpbWV6b25lKSB7CisgICAgICAgIGNhbGVuZGFyLnNldFRpbWVab25lKHRpbWV6b25lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW5zdGFuY2VzIG9mIHRoaXMgaW5uZXIgY2xhc3MgYXJlIHVzZWQgYXMgYXR0cmlidXRlIGtleXMgYW5kIHZhbHVlcworICAgICAqIGluIHtAY29kZSBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3J9IHRoYXQgdGhlCisgICAgICoge0BsaW5rIFNpbXBsZURhdGVGb3JtYXQjZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcihPYmplY3QpfSBtZXRob2QgcmV0dXJucy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGVyZSBpcyBubyBwdWJsaWMgY29uc3RydWN0b3IgaW4gdGhpcyBjbGFzcywgdGhlIG9ubHkgaW5zdGFuY2VzIGFyZSB0aGUKKyAgICAgKiBjb25zdGFudHMgZGVmaW5lZCBoZXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRmllbGQgZXh0ZW5kcyBGb3JtYXQuRmllbGQgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDc0NDEzNTAxMTkzNDk1NDQ3MjBMOworCisgICAgICAgIHByaXZhdGUgc3RhdGljIEhhc2h0YWJsZTxJbnRlZ2VyLCBGaWVsZD4gdGFibGUgPSBuZXcgSGFzaHRhYmxlPEludGVnZXIsIEZpZWxkPigpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBNYXJrcyB0aGUgZXJhIHBhcnQgb2YgYSBkYXRlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWVsZCBFUkEgPSBuZXcgRmllbGQoImVyYSIsIENhbGVuZGFyLkVSQSk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE1hcmtzIHRoZSB5ZWFyIHBhcnQgb2YgYSBkYXRlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWVsZCBZRUFSID0gbmV3IEZpZWxkKCJ5ZWFyIiwgQ2FsZW5kYXIuWUVBUik7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE1hcmtzIHRoZSBtb250aCBwYXJ0IG9mIGEgZGF0ZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgTU9OVEggPSBuZXcgRmllbGQoIm1vbnRoIiwgQ2FsZW5kYXIuTU9OVEgpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBNYXJrcyB0aGUgaG91ciBvZiB0aGUgZGF5IHBhcnQgb2YgYSBkYXRlICgwLTExKS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgSE9VUl9PRl9EQVkwID0gbmV3IEZpZWxkKCJob3VyIG9mIGRheSIsIENhbGVuZGFyLkhPVVJfT0ZfREFZKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogTWFya3MgdGhlIGhvdXIgb2YgdGhlIGRheSBwYXJ0IG9mIGEgZGF0ZSAoMS0xMikuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZpZWxkIEhPVVJfT0ZfREFZMSA9IG5ldyBGaWVsZCgiaG91ciBvZiBkYXkgMSIsIC0xKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogTWFya3MgdGhlIG1pbnV0ZSBwYXJ0IG9mIGEgdGltZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgTUlOVVRFID0gbmV3IEZpZWxkKCJtaW51dGUiLCBDYWxlbmRhci5NSU5VVEUpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBNYXJrcyB0aGUgc2Vjb25kIHBhcnQgb2YgYSB0aW1lLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWVsZCBTRUNPTkQgPSBuZXcgRmllbGQoInNlY29uZCIsIENhbGVuZGFyLlNFQ09ORCk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE1hcmtzIHRoZSBtaWxsaXNlY29uZCBwYXJ0IG9mIGEgdGltZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgTUlMTElTRUNPTkQgPSBuZXcgRmllbGQoIm1pbGxpc2Vjb25kIiwgQ2FsZW5kYXIuTUlMTElTRUNPTkQpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBNYXJrcyB0aGUgZGF5IG9mIHRoZSB3ZWVrIHBhcnQgb2YgYSBkYXRlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWVsZCBEQVlfT0ZfV0VFSyA9IG5ldyBGaWVsZCgiZGF5IG9mIHdlZWsiLCBDYWxlbmRhci5EQVlfT0ZfV0VFSyk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE1hcmtzIHRoZSBkYXkgb2YgdGhlIG1vbnRoIHBhcnQgb2YgYSBkYXRlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWVsZCBEQVlfT0ZfTU9OVEggPSBuZXcgRmllbGQoImRheSBvZiBtb250aCIsIENhbGVuZGFyLkRBWV9PRl9NT05USCk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE1hcmtzIHRoZSBkYXkgb2YgdGhlIHllYXIgcGFydCBvZiBhIGRhdGUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZpZWxkIERBWV9PRl9ZRUFSID0gbmV3IEZpZWxkKCJkYXkgb2YgeWVhciIsIENhbGVuZGFyLkRBWV9PRl9ZRUFSKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogTWFya3MgdGhlIGRheSBvZiB0aGUgd2VlayBpbiB0aGUgbW9udGggcGFydCBvZiBhIGRhdGUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZpZWxkIERBWV9PRl9XRUVLX0lOX01PTlRIID0gbmV3IEZpZWxkKCJkYXkgb2Ygd2VlayBpbiBtb250aCIsCisgICAgICAgICAgICAgICAgQ2FsZW5kYXIuREFZX09GX1dFRUtfSU5fTU9OVEgpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBNYXJrcyB0aGUgd2VlayBvZiB0aGUgeWVhciBwYXJ0IG9mIGEgZGF0ZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgV0VFS19PRl9ZRUFSID0gbmV3IEZpZWxkKCJ3ZWVrIG9mIHllYXIiLAorICAgICAgICAgICAgICAgIENhbGVuZGFyLldFRUtfT0ZfWUVBUik7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE1hcmtzIHRoZSB3ZWVrIG9mIHRoZSBtb250aCBwYXJ0IG9mIGEgZGF0ZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgV0VFS19PRl9NT05USCA9IG5ldyBGaWVsZCgid2VlayBvZiBtb250aCIsCisgICAgICAgICAgICAgICAgQ2FsZW5kYXIuV0VFS19PRl9NT05USCk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE1hcmtzIHRoZSB0aW1lIGluZGljYXRvciBwYXJ0IG9mIGEgZGF0ZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgQU1fUE0gPSBuZXcgRmllbGQoImFtIHBtIiwgQ2FsZW5kYXIuQU1fUE0pOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBNYXJrcyB0aGUgaG91ciBwYXJ0IG9mIGEgZGF0ZSAoMC0xMSkuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZpZWxkIEhPVVIwID0gbmV3IEZpZWxkKCJob3VyIiwgQ2FsZW5kYXIuSE9VUik7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE1hcmtzIHRoZSBob3VyIHBhcnQgb2YgYSBkYXRlICgxLTEyKS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgSE9VUjEgPSBuZXcgRmllbGQoImhvdXIgMSIsIC0xKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogTWFya3MgdGhlIHRpbWUgem9uZSBwYXJ0IG9mIGEgZGF0ZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgVElNRV9aT05FID0gbmV3IEZpZWxkKCJ0aW1lIHpvbmUiLCAtMSk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBjYWxlbmRhciBmaWVsZCB0aGF0IHRoaXMgZmllbGQgcmVwcmVzZW50cy4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgaW50IGNhbGVuZGFyRmllbGQgPSAtMTsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgRGF0ZUZvcm1hdC5GaWVsZH0gd2l0aCB0aGUgZ2l2ZW4KKyAgICAgICAgICogZmllbGROYW1lIGFuZCBjYWxlbmRhciBmaWVsZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIGZpZWxkTmFtZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBmaWVsZCBuYW1lLgorICAgICAgICAgKiBAcGFyYW0gY2FsZW5kYXJGaWVsZAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBjYWxlbmRhciBmaWVsZCB0eXBlIG9mIHRoZSBmaWVsZC4KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBGaWVsZChTdHJpbmcgZmllbGROYW1lLCBpbnQgY2FsZW5kYXJGaWVsZCkgeworICAgICAgICAgICAgc3VwZXIoZmllbGROYW1lKTsKKyAgICAgICAgICAgIHRoaXMuY2FsZW5kYXJGaWVsZCA9IGNhbGVuZGFyRmllbGQ7CisgICAgICAgICAgICBpZiAoY2FsZW5kYXJGaWVsZCAhPSAtMSAmJiB0YWJsZS5nZXQoSW50ZWdlci52YWx1ZU9mKGNhbGVuZGFyRmllbGQpKSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGFibGUucHV0KEludGVnZXIudmFsdWVPZihjYWxlbmRhckZpZWxkKSwgdGhpcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgQ2FsZW5kYXIgZmllbGQgdGhhdCB0aGlzIGZpZWxkIHJlcHJlc2VudHMuCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gdGhlIGNhbGVuZGFyIGZpZWxkLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGludCBnZXRDYWxlbmRhckZpZWxkKCkgeworICAgICAgICAgICAgcmV0dXJuIGNhbGVuZGFyRmllbGQ7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIERhdGVGb3JtYXQuRmllbGR9IGluc3RhbmNlIGZvciB0aGUgZ2l2ZW4gY2FsZW5kYXIKKyAgICAgICAgICogZmllbGQuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBjYWxlbmRhckZpZWxkCisgICAgICAgICAqICAgICAgICAgICAgYSBjYWxlbmRhciBmaWVsZCBjb25zdGFudC4KKyAgICAgICAgICogQHJldHVybiB0aGUge0Bjb2RlIERhdGVGb3JtYXQuRmllbGR9IGNvcnJlc3BvbmRpbmcgdG8KKyAgICAgICAgICogICAgICAgICB7QGNvZGUgY2FsZW5kYXJGaWVsZH0uCisgICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBjYWxlbmRhckZpZWxkfSBpcyBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlCisgICAgICAgICAqICAgICAgICAgICAgIGZpZWxkIGNvdW50IG9mIHtAY29kZSBDYWxlbmRhcn0uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIEZpZWxkIG9mQ2FsZW5kYXJGaWVsZChpbnQgY2FsZW5kYXJGaWVsZCkgeworICAgICAgICAgICAgaWYgKGNhbGVuZGFyRmllbGQgPCAwIHx8IGNhbGVuZGFyRmllbGQgPj0gQ2FsZW5kYXIuRklFTERfQ09VTlQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiB0YWJsZS5nZXQoSW50ZWdlci52YWx1ZU9mKGNhbGVuZGFyRmllbGQpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY2hlY2tEYXRlU3R5bGUoaW50IHN0eWxlKSB7CisgICAgICAgIGlmICghKHN0eWxlID09IFNIT1JUIHx8IHN0eWxlID09IE1FRElVTSB8fCBzdHlsZSA9PSBMT05HCisgICAgICAgICAgICAgICAgfHwgc3R5bGUgPT0gRlVMTCB8fCBzdHlsZSA9PSBERUZBVUxUKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSWxsZWdhbCBkYXRlIHN0eWxlICIgKyBzdHlsZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNoZWNrVGltZVN0eWxlKGludCBzdHlsZSkgeworICAgICAgICBpZiAoIShzdHlsZSA9PSBTSE9SVCB8fCBzdHlsZSA9PSBNRURJVU0gfHwgc3R5bGUgPT0gTE9ORworICAgICAgICAgICAgICAgIHx8IHN0eWxlID09IEZVTEwgfHwgc3R5bGUgPT0gREVGQVVMVCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklsbGVnYWwgdGltZSBzdHlsZSAiICsgc3R5bGUpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9EYXRlRm9ybWF0U3ltYm9scy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9EYXRlRm9ybWF0U3ltYm9scy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNjNDc2OGQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0RhdGVGb3JtYXRTeW1ib2xzLmphdmEKQEAgLTAsMCArMSw0ODQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudGV4dDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgbGliY29yZS5pY3UuSUNVOworaW1wb3J0IGxpYmNvcmUuaWN1LkxvY2FsZURhdGE7CitpbXBvcnQgbGliY29yZS5pY3UuVGltZVpvbmVzOworCisvKioKKyAqIEVuY2Fwc3VsYXRlcyBsb2NhbGl6ZWQgZGF0ZS10aW1lIGZvcm1hdHRpbmcgZGF0YSwgc3VjaCBhcyB0aGUgbmFtZXMgb2YgdGhlCisgKiBtb250aHMsIHRoZSBuYW1lcyBvZiB0aGUgZGF5cyBvZiB0aGUgd2VlaywgYW5kIHRoZSB0aW1lIHpvbmUgZGF0YS4KKyAqIHtAY29kZSBEYXRlRm9ybWF0fSBhbmQge0Bjb2RlIFNpbXBsZURhdGVGb3JtYXR9IGJvdGggdXNlCisgKiB7QGNvZGUgRGF0ZUZvcm1hdFN5bWJvbHN9IHRvIGVuY2Fwc3VsYXRlIHRoaXMgaW5mb3JtYXRpb24uCisgKgorICogPHA+VHlwaWNhbGx5IHlvdSBzaG91bGRuJ3QgdXNlIHtAY29kZSBEYXRlRm9ybWF0U3ltYm9sc30gZGlyZWN0bHkuIFJhdGhlciwgeW91CisgKiBhcmUgZW5jb3VyYWdlZCB0byBjcmVhdGUgYSBkYXRlL3RpbWUgZm9ybWF0dGVyIHdpdGggdGhlIHtAY29kZSBEYXRlRm9ybWF0fQorICogY2xhc3MncyBmYWN0b3J5IG1ldGhvZHM6IHtAY29kZSBnZXRUaW1lSW5zdGFuY2V9LCB7QGNvZGUgZ2V0RGF0ZUluc3RhbmNlfSwKKyAqIG9yIHtAY29kZSBnZXREYXRlVGltZUluc3RhbmNlfS4gVGhlc2UgbWV0aG9kcyBhdXRvbWF0aWNhbGx5IGNyZWF0ZSBhCisgKiB7QGNvZGUgRGF0ZUZvcm1hdFN5bWJvbHN9IGZvciB0aGUgZm9ybWF0dGVyIHNvIHRoYXQgeW91IGRvbid0IGhhdmUgdG8uIEFmdGVyCisgKiB0aGUgZm9ybWF0dGVyIGlzIGNyZWF0ZWQsIHlvdSBtYXkgbW9kaWZ5IGl0cyBmb3JtYXQgcGF0dGVybiB1c2luZyB0aGUKKyAqIHtAY29kZSBzZXRQYXR0ZXJufSBtZXRob2QuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGNyZWF0aW5nIGZvcm1hdHRlcnMKKyAqIHVzaW5nIHtAY29kZSBEYXRlRm9ybWF0fSdzIGZhY3RvcnkgbWV0aG9kcywgc2VlIHtAbGluayBEYXRlRm9ybWF0fS4KKyAqCisgKiA8cD5EaXJlY3QgdXNlIG9mIHtAY29kZSBEYXRlRm9ybWF0U3ltYm9sc30gaXMgbGlrZWx5IHRvIGJlIGxlc3MgZWZmaWNpZW50CisgKiBiZWNhdXNlIHRoZSBpbXBsZW1lbnRhdGlvbiBjYW5ub3QgbWFrZSBhc3N1bXB0aW9ucyBhYm91dCB1c2VyLXN1cHBsaWVkL3VzZXItbW9kaWZpYWJsZSBkYXRhCisgKiB0byB0aGUgc2FtZSBleHRlbnQgdGhhdCBpdCBjYW4gd2l0aCBpdHMgb3duIGJ1aWx0LWluIGRhdGEuCisgKgorICogQHNlZSBEYXRlRm9ybWF0CisgKiBAc2VlIFNpbXBsZURhdGVGb3JtYXQKKyAqLworcHVibGljIGNsYXNzIERhdGVGb3JtYXRTeW1ib2xzIGltcGxlbWVudHMgU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTU5ODc5NzM1NDU1NDk0MjQ3MDJMOworCisgICAgcHJpdmF0ZSBTdHJpbmcgbG9jYWxQYXR0ZXJuQ2hhcnM7CisKKyAgICBTdHJpbmdbXSBhbXBtcywgZXJhcywgbW9udGhzLCBzaG9ydE1vbnRocywgc2hvcnRXZWVrZGF5cywgd2Vla2RheXM7CisKKyAgICAvLyBUaGVzZSBhcmUgdXNlZCB0byBpbXBsZW1lbnQgSUNVL0FuZHJvaWQgZXh0ZW5zaW9ucy4KKyAgICB0cmFuc2llbnQgU3RyaW5nW10gbG9uZ1N0YW5kQWxvbmVNb250aHM7CisgICAgdHJhbnNpZW50IFN0cmluZ1tdIHNob3J0U3RhbmRBbG9uZU1vbnRoczsKKyAgICB0cmFuc2llbnQgU3RyaW5nW10gbG9uZ1N0YW5kQWxvbmVXZWVrZGF5czsKKyAgICB0cmFuc2llbnQgU3RyaW5nW10gc2hvcnRTdGFuZEFsb25lV2Vla2RheXM7CisKKyAgICAvLyBMb2NhbGl6ZWQgZGlzcGxheSBuYW1lcy4KKyAgICBTdHJpbmdbXVtdIHpvbmVTdHJpbmdzOworICAgIC8vIEhhcyB0aGUgdXNlciBjYWxsZWQgc2V0Wm9uZVN0cmluZ3M/CisgICAgdHJhbnNpZW50IGJvb2xlYW4gY3VzdG9tWm9uZVN0cmluZ3M7CisKKyAgICAvKioKKyAgICAgKiBMb2NhbGUsIG5lY2Vzc2FyeSB0byBsYXppbHkgbG9hZCB0aW1lIHpvbmUgc3RyaW5ncy4gV2UgZm9yY2UgdGhlIHRpbWUKKyAgICAgKiB6b25lIG5hbWVzIHRvIGxvYWQgdXBvbiBzZXJpYWxpemF0aW9uLCBzbyB0aGlzIHdpbGwgbmV2ZXIgYmUgbmVlZGVkCisgICAgICogcG9zdCBkZXNlcmlhbGl6YXRpb24uCisgICAgICovCisgICAgdHJhbnNpZW50IGZpbmFsIExvY2FsZSBsb2NhbGU7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHpvbmUgc3RyaW5ncywgaW5pdGlhbGl6aW5nIHRoZW0gaWYgbmVjZXNzYXJ5LiBEb2VzIG5vdCBjcmVhdGUKKyAgICAgKiBhIGRlZmVuc2l2ZSBjb3B5LCBzbyBtYWtlIHN1cmUgeW91IGRvIHNvIGJlZm9yZSBleHBvc2luZyB0aGUgcmV0dXJuZWQKKyAgICAgKiBhcnJheXMgdG8gY2xpZW50cy4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgU3RyaW5nW11bXSBpbnRlcm5hbFpvbmVTdHJpbmdzKCkgeworICAgICAgICBpZiAoem9uZVN0cmluZ3MgPT0gbnVsbCkgeworICAgICAgICAgICAgem9uZVN0cmluZ3MgPSBUaW1lWm9uZXMuZ2V0Wm9uZVN0cmluZ3MobG9jYWxlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gem9uZVN0cmluZ3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRGF0ZUZvcm1hdFN5bWJvbHN9IGluc3RhbmNlIGNvbnRhaW5pbmcgdGhlCisgICAgICogc3ltYm9scyBmb3IgdGhlIHVzZXIncyBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKiBTZWUgIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuCisgICAgICovCisgICAgcHVibGljIERhdGVGb3JtYXRTeW1ib2xzKCkgeworICAgICAgICB0aGlzKExvY2FsZS5nZXREZWZhdWx0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIERhdGVGb3JtYXRTeW1ib2xzfSBpbnN0YW5jZSBjb250YWluaW5nIHRoZQorICAgICAqIHN5bWJvbHMgZm9yIHRoZSBzcGVjaWZpZWQgbG9jYWxlLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2FsZQorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0ZUZvcm1hdFN5bWJvbHMoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICB0aGlzLmxvY2FsZSA9IGxvY2FsZTsKKyAgICAgICAgdGhpcy5sb2NhbFBhdHRlcm5DaGFycyA9IFNpbXBsZURhdGVGb3JtYXQuUEFUVEVSTl9DSEFSUzsKKyAgICAgICAgTG9jYWxlRGF0YSBsb2NhbGVEYXRhID0gTG9jYWxlRGF0YS5nZXQobG9jYWxlKTsKKyAgICAgICAgdGhpcy5hbXBtcyA9IGxvY2FsZURhdGEuYW1QbTsKKyAgICAgICAgdGhpcy5lcmFzID0gbG9jYWxlRGF0YS5lcmFzOworICAgICAgICB0aGlzLm1vbnRocyA9IGxvY2FsZURhdGEubG9uZ01vbnRoTmFtZXM7CisgICAgICAgIHRoaXMuc2hvcnRNb250aHMgPSBsb2NhbGVEYXRhLnNob3J0TW9udGhOYW1lczsKKyAgICAgICAgdGhpcy53ZWVrZGF5cyA9IGxvY2FsZURhdGEubG9uZ1dlZWtkYXlOYW1lczsKKyAgICAgICAgdGhpcy5zaG9ydFdlZWtkYXlzID0gbG9jYWxlRGF0YS5zaG9ydFdlZWtkYXlOYW1lczsKKworICAgICAgICAvLyBJQ1UvQW5kcm9pZCBleHRlbnNpb25zLgorICAgICAgICB0aGlzLmxvbmdTdGFuZEFsb25lTW9udGhzID0gbG9jYWxlRGF0YS5sb25nU3RhbmRBbG9uZU1vbnRoTmFtZXM7CisgICAgICAgIHRoaXMuc2hvcnRTdGFuZEFsb25lTW9udGhzID0gbG9jYWxlRGF0YS5zaG9ydFN0YW5kQWxvbmVNb250aE5hbWVzOworICAgICAgICB0aGlzLmxvbmdTdGFuZEFsb25lV2Vla2RheXMgPSBsb2NhbGVEYXRhLmxvbmdTdGFuZEFsb25lV2Vla2RheU5hbWVzOworICAgICAgICB0aGlzLnNob3J0U3RhbmRBbG9uZVdlZWtkYXlzID0gbG9jYWxlRGF0YS5zaG9ydFN0YW5kQWxvbmVXZWVrZGF5TmFtZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgRGF0ZUZvcm1hdFN5bWJvbHN9IGluc3RhbmNlIGZvciB0aGUgdXNlcidzIGRlZmF1bHQgbG9jYWxlLgorICAgICAqIFNlZSAiPGEgaHJlZj0iLi4vdXRpbC9Mb2NhbGUuaHRtbCNkZWZhdWx0X2xvY2FsZSI+QmUgd2FyeSBvZiB0aGUgZGVmYXVsdCBsb2NhbGU8L2E+Ii4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIERhdGVGb3JtYXRTeW1ib2xzfQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIERhdGVGb3JtYXRTeW1ib2xzIGdldEluc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gZ2V0SW5zdGFuY2UoTG9jYWxlLmdldERlZmF1bHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgRGF0ZUZvcm1hdFN5bWJvbHN9IGZvciB0aGUgZ2l2ZW4gbG9jYWxlLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlCisgICAgICogQHJldHVybiBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgRGF0ZUZvcm1hdFN5bWJvbHN9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgbG9jYWxlID09IG51bGx9CisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRGF0ZUZvcm1hdFN5bWJvbHMgZ2V0SW5zdGFuY2UoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBpZiAobG9jYWxlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgRGF0ZUZvcm1hdFN5bWJvbHMobG9jYWxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGxvY2FsZXMgZm9yIHdoaWNoIGN1c3RvbSB7QGNvZGUgRGF0ZUZvcm1hdFN5bWJvbHN9IGluc3RhbmNlcworICAgICAqIGFyZSBhdmFpbGFibGUuCisgICAgICogPHA+Tm90ZSB0aGF0IEFuZHJvaWQgZG9lcyBub3Qgc3VwcG9ydCB1c2VyLXN1cHBsaWVkIGxvY2FsZSBzZXJ2aWNlIHByb3ZpZGVycy4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBMb2NhbGVbXSBnZXRBdmFpbGFibGVMb2NhbGVzKCkgeworICAgICAgICByZXR1cm4gSUNVLmdldEF2YWlsYWJsZURhdGVGb3JtYXRTeW1ib2xzTG9jYWxlcygpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIG9pcykgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgb2lzLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisKKyAgICAgICAgLy8gVGhlIFJJIGRvZXNuJ3QgaGF2ZSB0aGVzZSBmaWVsZHMsIHNvIHdlJ2xsIGhhdmUgdG8gZmFsbCBiYWNrIGFuZCBkbyB0aGUgYmVzdCB3ZSBjYW4uCisgICAgICAgIGxvbmdTdGFuZEFsb25lTW9udGhzID0gbW9udGhzOworICAgICAgICBzaG9ydFN0YW5kQWxvbmVNb250aHMgPSBzaG9ydE1vbnRoczsKKyAgICAgICAgbG9uZ1N0YW5kQWxvbmVXZWVrZGF5cyA9IHdlZWtkYXlzOworICAgICAgICBzaG9ydFN0YW5kQWxvbmVXZWVrZGF5cyA9IHNob3J0V2Vla2RheXM7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBvb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludGVybmFsWm9uZVN0cmluZ3MoKTsKKyAgICAgICAgb29zLmRlZmF1bHRXcml0ZU9iamVjdCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFuZCBpbmRpY2F0ZXMgaWYgdGhleSBhcmUKKyAgICAgKiBlcXVhbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB3aXRoIHRoaXMgb2JqZWN0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBvYmplY3R9IGlzIGFuIGluc3RhbmNlIG9mCisgICAgICogICAgICAgICB7QGNvZGUgRGF0ZUZvcm1hdFN5bWJvbHN9IGFuZCBoYXMgdGhlIHNhbWUgc3ltYm9scyBhcyB0aGlzCisgICAgICogICAgICAgICBvYmplY3QsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgI2hhc2hDb2RlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgaWYgKHRoaXMgPT0gb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBEYXRlRm9ybWF0U3ltYm9scykpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBEYXRlRm9ybWF0U3ltYm9scyByaHMgPSAoRGF0ZUZvcm1hdFN5bWJvbHMpIG9iamVjdDsKKyAgICAgICAgcmV0dXJuIGxvY2FsUGF0dGVybkNoYXJzLmVxdWFscyhyaHMubG9jYWxQYXR0ZXJuQ2hhcnMpICYmCisgICAgICAgICAgICAgICAgQXJyYXlzLmVxdWFscyhhbXBtcywgcmhzLmFtcG1zKSAmJgorICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMoZXJhcywgcmhzLmVyYXMpICYmCisgICAgICAgICAgICAgICAgQXJyYXlzLmVxdWFscyhtb250aHMsIHJocy5tb250aHMpICYmCisgICAgICAgICAgICAgICAgQXJyYXlzLmVxdWFscyhzaG9ydE1vbnRocywgcmhzLnNob3J0TW9udGhzKSAmJgorICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMoc2hvcnRXZWVrZGF5cywgcmhzLnNob3J0V2Vla2RheXMpICYmCisgICAgICAgICAgICAgICAgQXJyYXlzLmVxdWFscyh3ZWVrZGF5cywgcmhzLndlZWtkYXlzKSAmJgorICAgICAgICAgICAgICAgIHRpbWVab25lU3RyaW5nc0VxdWFsKHRoaXMsIHJocyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiB0aW1lWm9uZVN0cmluZ3NFcXVhbChEYXRlRm9ybWF0U3ltYm9scyBsaHMsIERhdGVGb3JtYXRTeW1ib2xzIHJocykgeworICAgICAgICAvLyBRdWljayBjaGVjayB0aGF0IG1heSBrZWVwIHVzIGZyb20gaGF2aW5nIHRvIGxvYWQgdGhlIHpvbmUgc3RyaW5ncy4KKyAgICAgICAgLy8gTm90ZSB0aGF0IGRpZmZlcmVudCBsb2NhbGVzIG1heSBoYXZlIHRoZSBzYW1lIHN0cmluZ3MsIHNvIHRoZSBvcHBvc2l0ZSBjaGVjayBpc24ndCB2YWxpZC4KKyAgICAgICAgaWYgKGxocy56b25lU3RyaW5ncyA9PSBudWxsICYmIHJocy56b25lU3RyaW5ncyA9PSBudWxsICYmIGxocy5sb2NhbGUuZXF1YWxzKHJocy5sb2NhbGUpKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICAvLyBNYWtlIHN1cmUgem9uZSBzdHJpbmdzIGFyZSBsb2FkZWQsIHRoZW4gY2hlY2suCisgICAgICAgIHJldHVybiBBcnJheXMuZGVlcEVxdWFscyhsaHMuaW50ZXJuYWxab25lU3RyaW5ncygpLCByaHMuaW50ZXJuYWxab25lU3RyaW5ncygpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAvLyAnbG9jYWxlJyBpc24ndCBwYXJ0IG9mIHRoZSBleHRlcm5hbGx5LXZpc2libGUgc3RhdGUuCisgICAgICAgIC8vICd6b25lU3RyaW5ncycgaXMgc28gbGFyZ2UsIHdlIGp1c3QgcHJpbnQgYSByZXByZXNlbnRhdGl2ZSB2YWx1ZS4KKyAgICAgICAgcmV0dXJuIGdldENsYXNzKCkuZ2V0TmFtZSgpICsKKyAgICAgICAgICAgICAgICAiW2FtUG1TdHJpbmdzPSIgKyBBcnJheXMudG9TdHJpbmcoYW1wbXMpICsKKyAgICAgICAgICAgICAgICAiLGN1c3RvbVpvbmVTdHJpbmdzPSIgKyBjdXN0b21ab25lU3RyaW5ncyArCisgICAgICAgICAgICAgICAgIixlcmFzPSIgKyBBcnJheXMudG9TdHJpbmcoZXJhcykgKworICAgICAgICAgICAgICAgICIsbG9jYWxQYXR0ZXJuQ2hhcnM9IiArIGxvY2FsUGF0dGVybkNoYXJzICsKKyAgICAgICAgICAgICAgICAiLG1vbnRocz0iICsgQXJyYXlzLnRvU3RyaW5nKG1vbnRocykgKworICAgICAgICAgICAgICAgICIsc2hvcnRNb250aHM9IiArIEFycmF5cy50b1N0cmluZyhzaG9ydE1vbnRocykgKworICAgICAgICAgICAgICAgICIsc2hvcnRXZWVrZGF5cz0iICsgQXJyYXlzLnRvU3RyaW5nKHNob3J0V2Vla2RheXMpICsKKyAgICAgICAgICAgICAgICAiLHdlZWtkYXlzPSIgKyBBcnJheXMudG9TdHJpbmcod2Vla2RheXMpICsKKyAgICAgICAgICAgICAgICAiLHpvbmVTdHJpbmdzPVsiICsgQXJyYXlzLnRvU3RyaW5nKGludGVybmFsWm9uZVN0cmluZ3MoKVswXSkgKyAiLi4uXSIgKworICAgICAgICAgICAgICAgICJdIjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhcnJheSBvZiBzdHJpbmdzIHdoaWNoIHJlcHJlc2VudCBBTSBhbmQgUE0uIFVzZSB0aGUKKyAgICAgKiB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyfSBjb25zdGFudHMge0Bjb2RlIENhbGVuZGFyLkFNfSBhbmQKKyAgICAgKiB7QGNvZGUgQ2FsZW5kYXIuUE19IGFzIGluZGljZXMgZm9yIHRoZSBhcnJheS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2Ygc3RyaW5ncy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0QW1QbVN0cmluZ3MoKSB7CisgICAgICAgIHJldHVybiBhbXBtcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFycmF5IG9mIHN0cmluZ3Mgd2hpY2ggcmVwcmVzZW50IEJDIGFuZCBBRC4gVXNlIHRoZQorICAgICAqIHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXJ9IGNvbnN0YW50cyB7QGNvZGUgR3JlZ29yaWFuQ2FsZW5kYXIuQkN9IGFuZAorICAgICAqIHtAY29kZSBHcmVnb3JpYW5DYWxlbmRhci5BRH0gYXMgaW5kaWNlcyBmb3IgdGhlIGFycmF5LgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBzdHJpbmdzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRFcmFzKCkgeworICAgICAgICByZXR1cm4gZXJhcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHBhdHRlcm4gY2hhcmFjdGVycyB1c2VkIGJ5IHtAbGluayBTaW1wbGVEYXRlRm9ybWF0fSB0bworICAgICAqIHNwZWNpZnkgZGF0ZSBhbmQgdGltZSBmaWVsZHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHBhdHRlcm4gY2hhcmFjdGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsUGF0dGVybkNoYXJzKCkgeworICAgICAgICByZXR1cm4gbG9jYWxQYXR0ZXJuQ2hhcnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXJyYXkgb2Ygc3RyaW5ncyBjb250YWluaW5nIHRoZSBmdWxsIG5hbWVzIG9mIHRoZSBtb250aHMuIFVzZQorICAgICAqIHRoZSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyfSBjb25zdGFudHMge0Bjb2RlIENhbGVuZGFyLkpBTlVBUll9IGV0Yy4gYXMKKyAgICAgKiBpbmRpY2VzIGZvciB0aGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIHN0cmluZ3MuCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIGdldE1vbnRocygpIHsKKyAgICAgICAgcmV0dXJuIG1vbnRocy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFycmF5IG9mIHN0cmluZ3MgY29udGFpbmluZyB0aGUgYWJicmV2aWF0ZWQgbmFtZXMgb2YgdGhlCisgICAgICogbW9udGhzLiBVc2UgdGhlIHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXJ9IGNvbnN0YW50cworICAgICAqIHtAY29kZSBDYWxlbmRhci5KQU5VQVJZfSBldGMuIGFzIGluZGljZXMgZm9yIHRoZSBhcnJheS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2Ygc3RyaW5ncy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0U2hvcnRNb250aHMoKSB7CisgICAgICAgIHJldHVybiBzaG9ydE1vbnRocy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFycmF5IG9mIHN0cmluZ3MgY29udGFpbmluZyB0aGUgYWJicmV2aWF0ZWQgbmFtZXMgb2YgdGhlIGRheXMKKyAgICAgKiBvZiB0aGUgd2Vlay4gVXNlIHRoZSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyfSBjb25zdGFudHMKKyAgICAgKiB7QGNvZGUgQ2FsZW5kYXIuU1VOREFZfSBldGMuIGFzIGluZGljZXMgZm9yIHRoZSBhcnJheS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2Ygc3RyaW5ncy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0U2hvcnRXZWVrZGF5cygpIHsKKyAgICAgICAgcmV0dXJuIHNob3J0V2Vla2RheXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhcnJheSBvZiBzdHJpbmdzIGNvbnRhaW5pbmcgdGhlIGZ1bGwgbmFtZXMgb2YgdGhlIGRheXMgb2YgdGhlCisgICAgICogd2Vlay4gVXNlIHRoZSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyfSBjb25zdGFudHMKKyAgICAgKiB7QGNvZGUgQ2FsZW5kYXIuU1VOREFZfSBldGMuIGFzIGluZGljZXMgZm9yIHRoZSBhcnJheS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2Ygc3RyaW5ncy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0V2Vla2RheXMoKSB7CisgICAgICAgIHJldHVybiB3ZWVrZGF5cy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHR3by1kaW1lbnNpb25hbCBhcnJheSBvZiBzdHJpbmdzIGNvbnRhaW5pbmcgbG9jYWxpemVkIG5hbWVzIGZvciB0aW1lIHpvbmVzLgorICAgICAqIEVhY2ggcm93IGlzIGFuIGFycmF5IG9mIGZpdmUgc3RyaW5nczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPlRoZSB0aW1lIHpvbmUgSUQsIGZvciBleGFtcGxlICJBbWVyaWNhL0xvc19BbmdlbGVzIi4KKyAgICAgKiAgICAgVGhpcyBpcyBub3QgbG9jYWxpemVkLCBhbmQgaXMgdXNlZCBhcyBhIGtleSBpbnRvIHRoZSB0YWJsZS4KKyAgICAgKiA8bGk+VGhlIGxvbmcgZGlzcGxheSBuYW1lLCBmb3IgZXhhbXBsZSAiUGFjaWZpYyBTdGFuZGFyZCBUaW1lIi4KKyAgICAgKiA8bGk+VGhlIHNob3J0IGRpc3BsYXkgbmFtZSwgZm9yIGV4YW1wbGUgIlBTVCIuCisgICAgICogPGxpPlRoZSBsb25nIGRpc3BsYXkgbmFtZSBmb3IgRFNULCBmb3IgZXhhbXBsZSAiUGFjaWZpYyBEYXlsaWdodCBUaW1lIi4KKyAgICAgKiAgICAgVGhpcyBpcyB0aGUgbm9uLURTVCBsb25nIG5hbWUgZm9yIHpvbmVzIHRoYXQgaGF2ZSBuZXZlciBoYWQgRFNULCBmb3IKKyAgICAgKiAgICAgZXhhbXBsZSAiQ2VudHJhbCBTdGFuZGFyZCBUaW1lIiBmb3IgIkNhbmFkYS9TYXNrYXRjaGV3YW4iLgorICAgICAqIDxsaT5UaGUgc2hvcnQgZGlzcGxheSBuYW1lIGZvciBEU1QsIGZvciBleGFtcGxlICJQRFQiLiBUaGlzIGlzIHRoZQorICAgICAqICAgICBub24tRFNUIHNob3J0IG5hbWUgZm9yIHpvbmVzIHRoYXQgaGF2ZSBuZXZlciBoYWQgRFNULCBmb3IgZXhhbXBsZQorICAgICAqICAgICAiQ1NUIiBmb3IgIkNhbmFkYS9TYXNrYXRjaGV3YW4iLgorICAgICAqIDwvdWw+CisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdW10gZ2V0Wm9uZVN0cmluZ3MoKSB7CisgICAgICAgIHJldHVybiBjbG9uZTJkU3RyaW5nQXJyYXkoaW50ZXJuYWxab25lU3RyaW5ncygpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXVtdIGNsb25lMmRTdHJpbmdBcnJheShTdHJpbmdbXVtdIGFycmF5KSB7CisgICAgICAgIFN0cmluZ1tdW10gcmVzdWx0ID0gbmV3IFN0cmluZ1thcnJheS5sZW5ndGhdW107CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIHJlc3VsdFtpXSA9IGFycmF5W2ldLmNsb25lKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBTdHJpbmdbXVtdIHpvbmVTdHJpbmdzID0gaW50ZXJuYWxab25lU3RyaW5ncygpOworICAgICAgICBpbnQgaGFzaENvZGU7CisgICAgICAgIGhhc2hDb2RlID0gbG9jYWxQYXR0ZXJuQ2hhcnMuaGFzaENvZGUoKTsKKyAgICAgICAgZm9yIChTdHJpbmcgZWxlbWVudCA6IGFtcG1zKSB7CisgICAgICAgICAgICBoYXNoQ29kZSArPSBlbGVtZW50Lmhhc2hDb2RlKCk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChTdHJpbmcgZWxlbWVudCA6IGVyYXMpIHsKKyAgICAgICAgICAgIGhhc2hDb2RlICs9IGVsZW1lbnQuaGFzaENvZGUoKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKFN0cmluZyBlbGVtZW50IDogbW9udGhzKSB7CisgICAgICAgICAgICBoYXNoQ29kZSArPSBlbGVtZW50Lmhhc2hDb2RlKCk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChTdHJpbmcgZWxlbWVudCA6IHNob3J0TW9udGhzKSB7CisgICAgICAgICAgICBoYXNoQ29kZSArPSBlbGVtZW50Lmhhc2hDb2RlKCk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChTdHJpbmcgZWxlbWVudCA6IHNob3J0V2Vla2RheXMpIHsKKyAgICAgICAgICAgIGhhc2hDb2RlICs9IGVsZW1lbnQuaGFzaENvZGUoKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKFN0cmluZyBlbGVtZW50IDogd2Vla2RheXMpIHsKKyAgICAgICAgICAgIGhhc2hDb2RlICs9IGVsZW1lbnQuaGFzaENvZGUoKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKFN0cmluZ1tdIGVsZW1lbnQgOiB6b25lU3RyaW5ncykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBlbGVtZW50Lmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRbal0gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBoYXNoQ29kZSArPSBlbGVtZW50W2pdLmhhc2hDb2RlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBoYXNoQ29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBhcnJheSBvZiBzdHJpbmdzIHdoaWNoIHJlcHJlc2VudCBBTSBhbmQgUE0uIFVzZSB0aGUKKyAgICAgKiB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyfSBjb25zdGFudHMge0Bjb2RlIENhbGVuZGFyLkFNfSBhbmQKKyAgICAgKiB7QGNvZGUgQ2FsZW5kYXIuUE19IGFzIGluZGljZXMgZm9yIHRoZSBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2Ygc3RyaW5ncyBmb3IgQU0gYW5kIFBNLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEFtUG1TdHJpbmdzKFN0cmluZ1tdIGRhdGEpIHsKKyAgICAgICAgYW1wbXMgPSBkYXRhLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgYXJyYXkgb2YgU3RyaW5ncyB3aGljaCByZXByZXNlbnQgQkMgYW5kIEFELiBVc2UgdGhlCisgICAgICoge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhcn0gY29uc3RhbnRzIHtAY29kZSBHcmVnb3JpYW5DYWxlbmRhci5CQ30gYW5kCisgICAgICoge0Bjb2RlIEdyZWdvcmlhbkNhbGVuZGFyLkFEfSBhcyBpbmRpY2VzIGZvciB0aGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHN0cmluZ3MgZm9yIEJDIGFuZCBBRC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRFcmFzKFN0cmluZ1tdIGRhdGEpIHsKKyAgICAgICAgZXJhcyA9IGRhdGEuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwYXR0ZXJuIGNoYXJhY3RlcnMgdXNlZCBieSB7QGxpbmsgU2ltcGxlRGF0ZUZvcm1hdH0gdG8gc3BlY2lmeQorICAgICAqIGRhdGUgYW5kIHRpbWUgZmllbGRzLgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgY29udGFpbmluZyB0aGUgcGF0dGVybiBjaGFyYWN0ZXJzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIGlmIHtAY29kZSBkYXRhfSBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TG9jYWxQYXR0ZXJuQ2hhcnMoU3RyaW5nIGRhdGEpIHsKKyAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgbG9jYWxQYXR0ZXJuQ2hhcnMgPSBkYXRhOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGFycmF5IG9mIHN0cmluZ3MgY29udGFpbmluZyB0aGUgZnVsbCBuYW1lcyBvZiB0aGUgbW9udGhzLiBVc2UKKyAgICAgKiB0aGUge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhcn0gY29uc3RhbnRzIHtAY29kZSBDYWxlbmRhci5KQU5VQVJZfSBldGMuIGFzCisgICAgICogaW5kaWNlcyBmb3IgdGhlIGFycmF5LgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBzdHJpbmdzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1vbnRocyhTdHJpbmdbXSBkYXRhKSB7CisgICAgICAgIG1vbnRocyA9IGRhdGEuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBhcnJheSBvZiBzdHJpbmdzIGNvbnRhaW5pbmcgdGhlIGFiYnJldmlhdGVkIG5hbWVzIG9mIHRoZSBtb250aHMuCisgICAgICogVXNlIHRoZSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyfSBjb25zdGFudHMge0Bjb2RlIENhbGVuZGFyLkpBTlVBUll9CisgICAgICogZXRjLiBhcyBpbmRpY2VzIGZvciB0aGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHN0cmluZ3MuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2hvcnRNb250aHMoU3RyaW5nW10gZGF0YSkgeworICAgICAgICBzaG9ydE1vbnRocyA9IGRhdGEuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBhcnJheSBvZiBzdHJpbmdzIGNvbnRhaW5pbmcgdGhlIGFiYnJldmlhdGVkIG5hbWVzIG9mIHRoZSBkYXlzIG9mCisgICAgICogdGhlIHdlZWsuIFVzZSB0aGUge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhcn0gY29uc3RhbnRzCisgICAgICoge0Bjb2RlIENhbGVuZGFyLlNVTkRBWX0gZXRjLiBhcyBpbmRpY2VzIGZvciB0aGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHN0cmluZ3MuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2hvcnRXZWVrZGF5cyhTdHJpbmdbXSBkYXRhKSB7CisgICAgICAgIHNob3J0V2Vla2RheXMgPSBkYXRhLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgYXJyYXkgb2Ygc3RyaW5ncyBjb250YWluaW5nIHRoZSBmdWxsIG5hbWVzIG9mIHRoZSBkYXlzIG9mIHRoZQorICAgICAqIHdlZWsuIFVzZSB0aGUge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhcn0gY29uc3RhbnRzCisgICAgICoge0Bjb2RlIENhbGVuZGFyLlNVTkRBWX0gZXRjLiBhcyBpbmRpY2VzIGZvciB0aGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHN0cmluZ3MuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0V2Vla2RheXMoU3RyaW5nW10gZGF0YSkgeworICAgICAgICB3ZWVrZGF5cyA9IGRhdGEuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB0d28tZGltZW5zaW9uYWwgYXJyYXkgb2Ygc3RyaW5ncyBjb250YWluaW5nIGxvY2FsaXplZCBuYW1lcyBmb3IgdGltZSB6b25lcy4KKyAgICAgKiBTZWUge0BsaW5rICNnZXRab25lU3RyaW5nc30gZm9yIGRldGFpbHMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYW55IHJvdyBoYXMgZmV3ZXIgdGhhbiA1IGVsZW1lbnRzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIHpvbmVTdHJpbmdzID09IG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFpvbmVTdHJpbmdzKFN0cmluZ1tdW10gem9uZVN0cmluZ3MpIHsKKyAgICAgICAgaWYgKHpvbmVTdHJpbmdzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGZvciAoU3RyaW5nW10gcm93IDogem9uZVN0cmluZ3MpIHsKKyAgICAgICAgICAgIGlmIChyb3cubGVuZ3RoIDwgNSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oQXJyYXlzLnRvU3RyaW5nKHJvdykgKyAiLmxlbmd0aCA8IDUiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0aGlzLnpvbmVTdHJpbmdzID0gY2xvbmUyZFN0cmluZ0FycmF5KHpvbmVTdHJpbmdzKTsKKyAgICAgICAgdGhpcy5jdXN0b21ab25lU3RyaW5ncyA9IHRydWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9EZWNpbWFsRm9ybWF0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0RlY2ltYWxGb3JtYXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMWE0OGRiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9EZWNpbWFsRm9ybWF0LmphdmEKQEAgLTAsMCArMSwxMjU5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1GaWVsZDsKK2ltcG9ydCBqYXZhLm1hdGguQmlnRGVjaW1hbDsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLm1hdGguUm91bmRpbmdNb2RlOworaW1wb3J0IGphdmEudXRpbC5DdXJyZW5jeTsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGxpYmNvcmUuaWN1LkxvY2FsZURhdGE7CitpbXBvcnQgbGliY29yZS5pY3UuTmF0aXZlRGVjaW1hbEZvcm1hdDsKKworLyoqCisgKiBBIGNvbmNyZXRlIHN1YmNsYXNzIG9mIHtAbGluayBOdW1iZXJGb3JtYXR9IHRoYXQgZm9ybWF0cyBkZWNpbWFsIG51bWJlcnMuIEl0CisgKiBoYXMgYSB2YXJpZXR5IG9mIGZlYXR1cmVzIGRlc2lnbmVkIHRvIG1ha2UgaXQgcG9zc2libGUgdG8gcGFyc2UgYW5kIGZvcm1hdAorICogbnVtYmVycyBpbiBhbnkgbG9jYWxlLCBpbmNsdWRpbmcgc3VwcG9ydCBmb3IgV2VzdGVybiwgQXJhYmljLCBvciBJbmRpYworICogZGlnaXRzLiBJdCBhbHNvIHN1cHBvcnRzIGRpZmZlcmVudCBmbGF2b3JzIG9mIG51bWJlcnMsIGluY2x1ZGluZyBpbnRlZ2VycworICogKCIxMjMiKSwgZml4ZWQtcG9pbnQgbnVtYmVycyAoIjEyMy40IiksIHNjaWVudGlmaWMgbm90YXRpb24gKCIxLjIzRTQiKSwKKyAqIHBlcmNlbnRhZ2VzICgiMTIlIiksIGFuZCBjdXJyZW5jeSBhbW91bnRzICgiJDEyMyIpLiBBbGwgb2YgdGhlc2UgZmxhdm9ycyBjYW4KKyAqIGJlIGVhc2lseSBsb2NhbGl6ZWQuCisgKiA8cD4KKyAqIDxzdHJvbmc+VGhpcyBpcyBhbiBlbmhhbmNlZCB2ZXJzaW9uIG9mIHtAY29kZSBEZWNpbWFsRm9ybWF0fSB0aGF0IGlzIGJhc2VkIG9uCisgKiB0aGUgc3RhbmRhcmQgdmVyc2lvbiBpbiB0aGUgUkkuIE5ldyBvciBjaGFuZ2VkIGZ1bmN0aW9uYWxpdHkgaXMgbGFiZWxlZAorICogPHN0cm9uZz48Zm9udCBjb2xvcj0icmVkIj5ORVc8L2ZvbnQ+PC9zdHJvbmc+Ljwvc3Ryb25nPgorICogPHA+CisgKiBUbyBvYnRhaW4gYSB7QGxpbmsgTnVtYmVyRm9ybWF0fSBmb3IgYSBzcGVjaWZpYyBsb2NhbGUgKGluY2x1ZGluZyB0aGUgZGVmYXVsdAorICogbG9jYWxlKSwgY2FsbCBvbmUgb2Yge0Bjb2RlIE51bWJlckZvcm1hdH0ncyBmYWN0b3J5IG1ldGhvZHMgc3VjaCBhcworICoge0Bjb2RlIE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZX0uIERvIG5vdCBjYWxsIHRoZSB7QGNvZGUgRGVjaW1hbEZvcm1hdH0KKyAqIGNvbnN0cnVjdG9ycyBkaXJlY3RseSwgdW5sZXNzIHlvdSBrbm93IHdoYXQgeW91IGFyZSBkb2luZywgc2luY2UgdGhlCisgKiB7QGxpbmsgTnVtYmVyRm9ybWF0fSBmYWN0b3J5IG1ldGhvZHMgbWF5IHJldHVybiBzdWJjbGFzc2VzIG90aGVyIHRoYW4KKyAqIHtAY29kZSBEZWNpbWFsRm9ybWF0fS4gSWYgeW91IG5lZWQgdG8gY3VzdG9taXplIHRoZSBmb3JtYXQgb2JqZWN0LCBkbworICogc29tZXRoaW5nIGxpa2UgdGhpczogPGJsb2NrcXVvdGU+CisgKgorICogPHByZT4KKyAqIE51bWJlckZvcm1hdCBmID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKGxvYyk7CisgKiBpZiAoZiBpbnN0YW5jZW9mIERlY2ltYWxGb3JtYXQpIHsKKyAqICAgICAoKERlY2ltYWxGb3JtYXQpZikuc2V0RGVjaW1hbFNlcGFyYXRvckFsd2F5c1Nob3duKHRydWUpOworICogfQorICogPC9wcmU+CisgKgorICogPC9ibG9ja3F1b3RlPgorICoKKyAqIDxoND5QYXR0ZXJuczwvaDQ+CisgKiA8cD4KKyAqIEEge0Bjb2RlIERlY2ltYWxGb3JtYXR9IGNvbnNpc3RzIG9mIGEgPGVtPnBhdHRlcm48L2VtPiBhbmQgYSBzZXQgb2YKKyAqIDxlbT5zeW1ib2xzPC9lbT4uIFRoZSBwYXR0ZXJuIG1heSBiZSBzZXQgZGlyZWN0bHkgdXNpbmcKKyAqIHtAbGluayAjYXBwbHlQYXR0ZXJuKFN0cmluZyl9LCBvciBpbmRpcmVjdGx5IHVzaW5nIG90aGVyIEFQSSBtZXRob2RzIHdoaWNoCisgKiBtYW5pcHVsYXRlIGFzcGVjdHMgb2YgdGhlIHBhdHRlcm4sIHN1Y2ggYXMgdGhlIG1pbmltdW0gbnVtYmVyIG9mIGludGVnZXIKKyAqIGRpZ2l0cy4gVGhlIHN5bWJvbHMgYXJlIHN0b3JlZCBpbiBhIHtAbGluayBEZWNpbWFsRm9ybWF0U3ltYm9sc30gb2JqZWN0LiBXaGVuCisgKiB1c2luZyB0aGUge0BsaW5rIE51bWJlckZvcm1hdH0gZmFjdG9yeSBtZXRob2RzLCB0aGUgcGF0dGVybiBhbmQgc3ltYm9scyBhcmUKKyAqIHJlYWQgZnJvbSBJQ1UncyBsb2NhbGUgZGF0YS4KKyAqIDxoND5TcGVjaWFsIFBhdHRlcm4gQ2hhcmFjdGVyczwvaDQ+CisgKiA8cD4KKyAqIE1hbnkgY2hhcmFjdGVycyBpbiBhIHBhdHRlcm4gYXJlIHRha2VuIGxpdGVyYWxseTsgdGhleSBhcmUgbWF0Y2hlZCBkdXJpbmcKKyAqIHBhcnNpbmcgYW5kIGFyZSB3cml0dGVuIG91dCB1bmNoYW5nZWQgZHVyaW5nIGZvcm1hdHRpbmcuIE9uIHRoZSBvdGhlciBoYW5kLAorICogc3BlY2lhbCBjaGFyYWN0ZXJzIHN0YW5kIGZvciBvdGhlciBjaGFyYWN0ZXJzLCBzdHJpbmdzLCBvciBjbGFzc2VzIG9mCisgKiBjaGFyYWN0ZXJzLiBGb3IgZXhhbXBsZSwgdGhlICcjJyBjaGFyYWN0ZXIgaXMgcmVwbGFjZWQgYnkgYSBsb2NhbGl6ZWQgZGlnaXQuCisgKiBPZnRlbiB0aGUgcmVwbGFjZW1lbnQgY2hhcmFjdGVyIGlzIHRoZSBzYW1lIGFzIHRoZSBwYXR0ZXJuIGNoYXJhY3RlcjsgaW4gdGhlCisgKiBVLlMuIGxvY2FsZSwgdGhlICcsJyBncm91cGluZyBjaGFyYWN0ZXIgaXMgcmVwbGFjZWQgYnkgJywnLiBIb3dldmVyLCB0aGUKKyAqIHJlcGxhY2VtZW50IGlzIHN0aWxsIGhhcHBlbmluZywgYW5kIGlmIHRoZSBzeW1ib2xzIGFyZSBtb2RpZmllZCwgdGhlIGdyb3VwaW5nCisgKiBjaGFyYWN0ZXIgY2hhbmdlcy4gU29tZSBzcGVjaWFsIGNoYXJhY3RlcnMgYWZmZWN0IHRoZSBiZWhhdmlvciBvZiB0aGUKKyAqIGZvcm1hdHRlciBieSB0aGVpciBwcmVzZW5jZTsgZm9yIGV4YW1wbGUsIGlmIHRoZSBwZXJjZW50IGNoYXJhY3RlciBpcyBzZWVuLAorICogdGhlbiB0aGUgdmFsdWUgaXMgbXVsdGlwbGllZCBieSAxMDAgYmVmb3JlIGJlaW5nIGRpc3BsYXllZC4KKyAqIDxwPgorICogVG8gaW5zZXJ0IGEgc3BlY2lhbCBjaGFyYWN0ZXIgaW4gYSBwYXR0ZXJuIGFzIGEgbGl0ZXJhbCwgdGhhdCBpcywgd2l0aG91dCBhbnkKKyAqIHNwZWNpYWwgbWVhbmluZywgdGhlIGNoYXJhY3RlciBtdXN0IGJlIHF1b3RlZC4gVGhlcmUgYXJlIHNvbWUgZXhjZXB0aW9ucyB0bworICogdGhpcyB3aGljaCBhcmUgbm90ZWQgYmVsb3cuCisgKiA8cD4KKyAqIFRoZSBjaGFyYWN0ZXJzIGxpc3RlZCBoZXJlIGFyZSB1c2VkIGluIG5vbi1sb2NhbGl6ZWQgcGF0dGVybnMuIExvY2FsaXplZAorICogcGF0dGVybnMgdXNlIHRoZSBjb3JyZXNwb25kaW5nIGNoYXJhY3RlcnMgdGFrZW4gZnJvbSB0aGlzIGZvcm1hdHRlcidzCisgKiB7QGxpbmsgRGVjaW1hbEZvcm1hdFN5bWJvbHN9IG9iamVjdCBpbnN0ZWFkLCBhbmQgdGhlc2UgY2hhcmFjdGVycyBsb3NlIHRoZWlyCisgKiBzcGVjaWFsIHN0YXR1cy4gVHdvIGV4Y2VwdGlvbnMgYXJlIHRoZSBjdXJyZW5jeSBzaWduIGFuZCBxdW90ZSwgd2hpY2ggYXJlIG5vdAorICogbG9jYWxpemVkLgorICogPGJsb2NrcXVvdGU+IDx0YWJsZSBib3JkZXI9IjAiIGNlbGxzcGFjaW5nPSIzIiBjZWxscGFkZGluZz0iMCIgc3VtbWFyeT0iQ2hhcnQKKyAqIHNob3dpbmcgc3ltYm9sLCBsb2NhdGlvbiwgbG9jYWxpemVkLCBhbmQgbWVhbmluZy4iPgorICogPHRyIGJnY29sb3I9IiNjY2NjZmYiPgorICogPHRoIGFsaWduPSJsZWZ0Ij5TeW1ib2w8L3RoPgorICogPHRoIGFsaWduPSJsZWZ0Ij5Mb2NhdGlvbjwvdGg+CisgKiA8dGggYWxpZ249ImxlZnQiPkxvY2FsaXplZD88L3RoPgorICogPHRoIGFsaWduPSJsZWZ0Ij5NZWFuaW5nPC90aD4KKyAqIDwvdHI+CisgKiA8dHIgdmFsaWduPSJ0b3AiPgorICogPHRkPntAY29kZSAwfTwvdGQ+CisgKiA8dGQ+TnVtYmVyPC90ZD4KKyAqIDx0ZD5ZZXM8L3RkPgorICogPHRkPkRpZ2l0LjwvdGQ+CisgKiA8L3RyPgorICogPHRyIHZhbGlnbj0idG9wIj4KKyAqIDx0ZD57QGNvZGUgQH08L3RkPgorICogPHRkPk51bWJlcjwvdGQ+CisgKiA8dGQ+Tm88L3RkPgorICogPHRkPjxzdHJvbmc+PGZvbnQgY29sb3I9InJlZCI+TkVXPC9mb250PiZuYnNwOzwvc3Ryb25nPiBTaWduaWZpY2FudAorICogZGlnaXQuPC90ZD4KKyAqIDwvdHI+CisgKiA8dHIgdmFsaWduPSJ0b3AiIGJnY29sb3I9IiNlZWVlZmYiPgorICogPHRkPntAY29kZSAjfTwvdGQ+CisgKiA8dGQ+TnVtYmVyPC90ZD4KKyAqIDx0ZD5ZZXM8L3RkPgorICogPHRkPkRpZ2l0LCBsZWFkaW5nIHplcm9lcyBhcmUgbm90IHNob3duLjwvdGQ+CisgKiA8L3RyPgorICogPHRyIHZhbGlnbj0idG9wIj4KKyAqIDx0ZD57QGNvZGUgLn08L3RkPgorICogPHRkPk51bWJlcjwvdGQ+CisgKiA8dGQ+WWVzPC90ZD4KKyAqIDx0ZD5EZWNpbWFsIHNlcGFyYXRvciBvciBtb25ldGFyeSBkZWNpbWFsIHNlcGFyYXRvci48L3RkPgorICogPC90cj4KKyAqIDx0ciB2YWxpZ249InRvcCIgYmdjb2xvcj0iI2VlZWVmZiI+CisgKiA8dGQ+e0Bjb2RlIC19PC90ZD4KKyAqIDx0ZD5OdW1iZXI8L3RkPgorICogPHRkPlllczwvdGQ+CisgKiA8dGQ+TWludXMgc2lnbi48L3RkPgorICogPC90cj4KKyAqIDx0ciB2YWxpZ249InRvcCI+CisgKiA8dGQ+e0Bjb2RlICx9PC90ZD4KKyAqIDx0ZD5OdW1iZXI8L3RkPgorICogPHRkPlllczwvdGQ+CisgKiA8dGQ+R3JvdXBpbmcgc2VwYXJhdG9yLjwvdGQ+CisgKiA8L3RyPgorICogPHRyIHZhbGlnbj0idG9wIiBiZ2NvbG9yPSIjZWVlZWZmIj4KKyAqIDx0ZD57QGNvZGUgRX08L3RkPgorICogPHRkPk51bWJlcjwvdGQ+CisgKiA8dGQ+WWVzPC90ZD4KKyAqIDx0ZD5TZXBhcmF0ZXMgbWFudGlzc2EgYW5kIGV4cG9uZW50IGluIHNjaWVudGlmaWMgbm90YXRpb24uCisgKiA8ZW0+RG9lcyBub3QgbmVlZCB0byBiZSBxdW90ZWQgaW4gcHJlZml4IG9yIHN1ZmZpeC48L2VtPjwvdGQ+CisgKiA8L3RyPgorICogPHRyIHZhbGlnbj0idG9wIj4KKyAqIDx0ZD57QGNvZGUgK308L3RkPgorICogPHRkPkV4cG9uZW50PC90ZD4KKyAqIDx0ZD5ZZXM8L3RkPgorICogPHRkPjxzdHJvbmc+PGZvbnQgY29sb3I9InJlZCI+TkVXPC9mb250PiZuYnNwOzwvc3Ryb25nPiBQcmVmaXgKKyAqIHBvc2l0aXZlIGV4cG9uZW50cyB3aXRoIGxvY2FsaXplZCBwbHVzIHNpZ24uCisgKiA8ZW0+RG9lcyBub3QgbmVlZCB0byBiZSBxdW90ZWQgaW4gcHJlZml4IG9yIHN1ZmZpeC48L2VtPjwvdGQ+CisgKiA8L3RyPgorICogPHRyIHZhbGlnbj0idG9wIiBiZ2NvbG9yPSIjZWVlZWZmIj4KKyAqIDx0ZD57QGNvZGUgO308L3RkPgorICogPHRkPlN1YnBhdHRlcm4gYm91bmRhcnk8L3RkPgorICogPHRkPlllczwvdGQ+CisgKiA8dGQ+U2VwYXJhdGVzIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBzdWJwYXR0ZXJucy48L3RkPgorICogPC90cj4KKyAqIDx0ciB2YWxpZ249InRvcCI+CisgKiA8dGQ+e0Bjb2RlICV9PC90ZD4KKyAqIDx0ZD5QcmVmaXggb3Igc3VmZml4PC90ZD4KKyAqIDx0ZD5ZZXM8L3RkPgorICogPHRkPk11bHRpcGx5IGJ5IDEwMCBhbmQgc2hvdyBhcyBwZXJjZW50YWdlLjwvdGQ+CisgKiA8L3RyPgorICogPHRyIHZhbGlnbj0idG9wIiBiZ2NvbG9yPSIjZWVlZWZmIj4KKyAqIDx0ZD57QGNvZGUgXHUyMDMwfSAoe0Bjb2RlIFx1MDA1Q3UyMDMwfSk8L3RkPgorICogPHRkPlByZWZpeCBvciBzdWZmaXg8L3RkPgorICogPHRkPlllczwvdGQ+CisgKiA8dGQ+TXVsdGlwbHkgYnkgMTAwMCBhbmQgc2hvdyBhcyBwZXIgbWlsbGUuPC90ZD4KKyAqIDwvdHI+CisgKiA8dHIgdmFsaWduPSJ0b3AiPgorICogPHRkPntAY29kZSBcdTAwQTR9ICh7QGNvZGUgXHUwMDVDdTAwQTR9KTwvdGQ+CisgKiA8dGQ+UHJlZml4IG9yIHN1ZmZpeDwvdGQ+CisgKiA8dGQ+Tm88L3RkPgorICogPHRkPkN1cnJlbmN5IHNpZ24sIHJlcGxhY2VkIGJ5IGN1cnJlbmN5IHN5bWJvbC4gSWYgZG91YmxlZCwgcmVwbGFjZWQgYnkKKyAqIGludGVybmF0aW9uYWwgY3VycmVuY3kgc3ltYm9sLiBJZiBwcmVzZW50IGluIGEgcGF0dGVybiwgdGhlIG1vbmV0YXJ5IGRlY2ltYWwKKyAqIHNlcGFyYXRvciBpcyB1c2VkIGluc3RlYWQgb2YgdGhlIGRlY2ltYWwgc2VwYXJhdG9yLjwvdGQ+CisgKiA8L3RyPgorICogPHRyIHZhbGlnbj0idG9wIiBiZ2NvbG9yPSIjZWVlZWZmIj4KKyAqIDx0ZD57QGNvZGUgJ308L3RkPgorICogPHRkPlByZWZpeCBvciBzdWZmaXg8L3RkPgorICogPHRkPk5vPC90ZD4KKyAqIDx0ZD5Vc2VkIHRvIHF1b3RlIHNwZWNpYWwgY2hhcmFjdGVycyBpbiBhIHByZWZpeCBvciBzdWZmaXgsIGZvciBleGFtcGxlLAorICoge0Bjb2RlICInIycjIn0gZm9ybWF0cyAxMjMgdG8ge0Bjb2RlICIjMTIzIn0uIFRvIGNyZWF0ZSBhIHNpbmdsZSBxdW90ZQorICogaXRzZWxmLCB1c2UgdHdvIGluIGEgcm93OiB7QGNvZGUgIiMgbycnY2xvY2sifS48L3RkPgorICogPC90cj4KKyAqIDx0ciB2YWxpZ249InRvcCI+CisgKiA8dGQ+e0Bjb2RlICp9PC90ZD4KKyAqIDx0ZD5QcmVmaXggb3Igc3VmZml4IGJvdW5kYXJ5PC90ZD4KKyAqIDx0ZD5ZZXM8L3RkPgorICogPHRkPjxzdHJvbmc+PGZvbnQgY29sb3I9InJlZCI+TkVXPC9mb250PiZuYnNwOzwvc3Ryb25nPiBQYWQgZXNjYXBlLAorICogcHJlY2VkZXMgcGFkIGNoYXJhY3Rlci4gPC90ZD4KKyAqIDwvdHI+CisgKiA8L3RhYmxlPiA8L2Jsb2NrcXVvdGU+CisgKiA8cD4KKyAqIEEge0Bjb2RlIERlY2ltYWxGb3JtYXR9IHBhdHRlcm4gY29udGFpbnMgYSBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgc3VicGF0dGVybiwKKyAqIGZvciBleGFtcGxlLCAiIywjIzAuMDA7KCMsIyMwLjAwKSIuIEVhY2ggc3VicGF0dGVybiBoYXMgYSBwcmVmaXgsIGEgbnVtZXJpYworICogcGFydCBhbmQgYSBzdWZmaXguIElmIHRoZXJlIGlzIG5vIGV4cGxpY2l0IG5lZ2F0aXZlIHN1YnBhdHRlcm4sIHRoZSBuZWdhdGl2ZQorICogc3VicGF0dGVybiBpcyB0aGUgbG9jYWxpemVkIG1pbnVzIHNpZ24gcHJlZml4ZWQgdG8gdGhlIHBvc2l0aXZlIHN1YnBhdHRlcm4uCisgKiBUaGF0IGlzLCAiMC4wMCIgYWxvbmUgaXMgZXF1aXZhbGVudCB0byAiMC4wMDstMC4wMCIuIElmIHRoZXJlIGlzIGFuIGV4cGxpY2l0CisgKiBuZWdhdGl2ZSBzdWJwYXR0ZXJuLCBpdCBzZXJ2ZXMgb25seSB0byBzcGVjaWZ5IHRoZSBuZWdhdGl2ZSBwcmVmaXggYW5kCisgKiBzdWZmaXg7IHRoZSBudW1iZXIgb2YgZGlnaXRzLCBtaW5pbWFsIGRpZ2l0cywgYW5kIG90aGVyIGNoYXJhY3RlcmlzdGljcyBhcmUKKyAqIGlnbm9yZWQgaW4gdGhlIG5lZ2F0aXZlIHN1YnBhdHRlcm4uIFRoaXMgbWVhbnMgdGhhdCAiIywjIzAuMCM7KCMpIiBwcm9kdWNlcworICogcHJlY2lzZWx5IHRoZSBzYW1lIHJlc3VsdCBhcyAiIywjIzAuMCM7KCMsIyMwLjAjKSIuCisgKiA8cD4KKyAqIFRoZSBwcmVmaXhlcywgc3VmZml4ZXMsIGFuZCB2YXJpb3VzIHN5bWJvbHMgdXNlZCBmb3IgaW5maW5pdHksIGRpZ2l0cywKKyAqIHRob3VzYW5kcyBzZXBhcmF0b3JzLCBkZWNpbWFsIHNlcGFyYXRvcnMsIGV0Yy4gbWF5IGJlIHNldCB0byBhcmJpdHJhcnkKKyAqIHZhbHVlcywgYW5kIHRoZXkgd2lsbCBhcHBlYXIgcHJvcGVybHkgZHVyaW5nIGZvcm1hdHRpbmcuIEhvd2V2ZXIsIGNhcmUgbXVzdAorICogYmUgdGFrZW4gdGhhdCB0aGUgc3ltYm9scyBhbmQgc3RyaW5ncyBkbyBub3QgY29uZmxpY3QsIG9yIHBhcnNpbmcgd2lsbCBiZQorICogdW5yZWxpYWJsZS4gRm9yIGV4YW1wbGUsIGVpdGhlciB0aGUgcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIHByZWZpeGVzIG9yIHRoZQorICogc3VmZml4ZXMgbXVzdCBiZSBkaXN0aW5jdCBmb3Ige0BsaW5rICNwYXJzZX0gdG8gYmUgYWJsZSB0byBkaXN0aW5ndWlzaAorICogcG9zaXRpdmUgZnJvbSBuZWdhdGl2ZSB2YWx1ZXMuIEFub3RoZXIgZXhhbXBsZSBpcyB0aGF0IHRoZSBkZWNpbWFsIHNlcGFyYXRvcgorICogYW5kIHRob3VzYW5kcyBzZXBhcmF0b3Igc2hvdWxkIGJlIGRpc3RpbmN0IGNoYXJhY3RlcnMsIG9yIHBhcnNpbmcgd2lsbCBiZQorICogaW1wb3NzaWJsZS4KKyAqIDxwPgorICogVGhlIDxlbT5ncm91cGluZyBzZXBhcmF0b3I8L2VtPiBpcyBhIGNoYXJhY3RlciB0aGF0IHNlcGFyYXRlcyBjbHVzdGVycyBvZgorICogaW50ZWdlciBkaWdpdHMgdG8gbWFrZSBsYXJnZSBudW1iZXJzIG1vcmUgbGVnaWJsZS4gSXQgaXMgY29tbW9ubHkgdXNlZCBmb3IKKyAqIHRob3VzYW5kcywgYnV0IGluIHNvbWUgbG9jYWxlcyBpdCBzZXBhcmF0ZXMgdGVuLXRob3VzYW5kcy4gVGhlIDxlbT5ncm91cGluZworICogc2l6ZTwvZW0+CisgKiBpcyB0aGUgbnVtYmVyIG9mIGRpZ2l0cyBiZXR3ZWVuIHRoZSBncm91cGluZyBzZXBhcmF0b3JzLCBzdWNoIGFzIDMgZm9yCisgKiAiMTAwLDAwMCwwMDAiIG9yIDQgZm9yICIxIDAwMDAgMDAwMCIuIFRoZXJlIGFyZSBhY3R1YWxseSB0d28gZGlmZmVyZW50CisgKiBncm91cGluZyBzaXplczogT25lIHVzZWQgZm9yIHRoZSBsZWFzdCBzaWduaWZpY2FudCBpbnRlZ2VyIGRpZ2l0cywgdGhlCisgKiA8ZW0+cHJpbWFyeSBncm91cGluZyBzaXplPC9lbT4sIGFuZCBvbmUgdXNlZCBmb3IgYWxsIG90aGVycywgdGhlCisgKiA8ZW0+c2Vjb25kYXJ5IGdyb3VwaW5nIHNpemU8L2VtPi4gSW4gbW9zdCBsb2NhbGVzIHRoZXNlIGFyZSB0aGUgc2FtZSwgYnV0CisgKiBzb21ldGltZXMgdGhleSBhcmUgZGlmZmVyZW50LiBGb3IgZXhhbXBsZSwgaWYgdGhlIHByaW1hcnkgZ3JvdXBpbmcgaW50ZXJ2YWwKKyAqIGlzIDMsIGFuZCB0aGUgc2Vjb25kYXJ5IGlzIDIsIHRoZW4gdGhpcyBjb3JyZXNwb25kcyB0byB0aGUgcGF0dGVybgorICogIiMsIyMsIyMwIiwgYW5kIHRoZSBudW1iZXIgMTIzNDU2Nzg5IGlzIGZvcm1hdHRlZCBhcyAiMTIsMzQsNTYsNzg5Ii4gSWYgYQorICogcGF0dGVybiBjb250YWlucyBtdWx0aXBsZSBncm91cGluZyBzZXBhcmF0b3JzLCB0aGUgaW50ZXJ2YWwgYmV0d2VlbiB0aGUgbGFzdAorICogb25lIGFuZCB0aGUgZW5kIG9mIHRoZSBpbnRlZ2VyIGRlZmluZXMgdGhlIHByaW1hcnkgZ3JvdXBpbmcgc2l6ZSwgYW5kIHRoZQorICogaW50ZXJ2YWwgYmV0d2VlbiB0aGUgbGFzdCB0d28gZGVmaW5lcyB0aGUgc2Vjb25kYXJ5IGdyb3VwaW5nIHNpemUuIEFsbCBvdGhlcnMKKyAqIGFyZSBpZ25vcmVkLCBzbyAiIywjIywjIyMsIyMjIyIsICIjIyMsIyMjLCMjIyMiIGFuZCAiIyMsIywjIyMsIyMjIyIgcHJvZHVjZQorICogdGhlIHNhbWUgcmVzdWx0LgorICogPHA+CisgKiBJbGxlZ2FsIHBhdHRlcm5zLCBzdWNoIGFzICIjLiMuIyIgb3IgIiMuIyMjLCMjIyIsIHdpbGwgY2F1c2UKKyAqIHtAY29kZSBEZWNpbWFsRm9ybWF0fSB0byB0aHJvdyBhbiB7QGxpbmsgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufSB3aXRoIGEKKyAqIG1lc3NhZ2UgdGhhdCBkZXNjcmliZXMgdGhlIHByb2JsZW0uCisgKiA8aDQ+UGF0dGVybiBCTkY8L2g0PgorICoKKyAqIDxwcmU+CisgKiBwYXR0ZXJuICAgIDo9IHN1YnBhdHRlcm4gKCc7JyBzdWJwYXR0ZXJuKT8KKyAqIHN1YnBhdHRlcm4gOj0gcHJlZml4PyBudW1iZXIgZXhwb25lbnQ/IHN1ZmZpeD8KKyAqIG51bWJlciAgICAgOj0gKGludGVnZXIgKCcuJyBmcmFjdGlvbik/KSB8IHNpZ0RpZ2l0cworICogcHJlZml4ICAgICA6PSAnXFx1MDAwMCcuLidcXHVGRkZEJyAtIHNwZWNpYWxDaGFyYWN0ZXJzCisgKiBzdWZmaXggICAgIDo9ICdcXHUwMDAwJy4uJ1xcdUZGRkQnIC0gc3BlY2lhbENoYXJhY3RlcnMKKyAqIGludGVnZXIgICAgOj0gJyMnKiAnMCcqICcwJworICogZnJhY3Rpb24gICA6PSAnMCcqICcjJyoKKyAqIHNpZ0RpZ2l0cyAgOj0gJyMnKiAnQCcgJ0AnKiAnIycqCisgKiBleHBvbmVudCAgIDo9ICdFJyAnKyc/ICcwJyogJzAnCisgKiBwYWRTcGVjICAgIDo9ICcqJyBwYWRDaGFyCisgKiBwYWRDaGFyICAgIDo9ICdcXHUwMDAwJy4uJ1xcdUZGRkQnIC0gcXVvdGUKKyAqCisgKiBOb3RhdGlvbjoKKyAqICAgWCogICAgICAgMCBvciBtb3JlIGluc3RhbmNlcyBvZiBYCisgKiAgIFg/ICAgICAgIDAgb3IgMSBpbnN0YW5jZXMgb2YgWAorICogICBYfFkgICAgICBlaXRoZXIgWCBvciBZCisgKiAgIEMuLkQgICAgIGFueSBjaGFyYWN0ZXIgZnJvbSBDIHVwIHRvIEQsIGluY2x1c2l2ZQorICogICBTLVQgICAgICBjaGFyYWN0ZXJzIGluIFMsIGV4Y2VwdCB0aG9zZSBpbiBUCisgKiA8L3ByZT4KKyAqCisgKiBUaGUgZmlyc3Qgc3VicGF0dGVybiBpcyBmb3IgcG9zaXRpdmUgbnVtYmVycy4gVGhlIHNlY29uZCAob3B0aW9uYWwpCisgKiBzdWJwYXR0ZXJuIGlzIGZvciBuZWdhdGl2ZSBudW1iZXJzLgorICogPHA+CisgKiBOb3QgaW5kaWNhdGVkIGluIHRoZSBCTkYgc3ludGF4IGFib3ZlOgorICogPHVsPgorICogPGxpPlRoZSBncm91cGluZyBzZXBhcmF0b3IgJywnIGNhbiBvY2N1ciBpbnNpZGUgdGhlIGludGVnZXIgYW5kIHNpZ0RpZ2l0cworICogZWxlbWVudHMsIGJldHdlZW4gYW55IHR3byBwYXR0ZXJuIGNoYXJhY3RlcnMgb2YgdGhhdCBlbGVtZW50LCBhcyBsb25nIGFzIHRoZQorICogaW50ZWdlciBvciBzaWdEaWdpdHMgZWxlbWVudCBpcyBub3QgZm9sbG93ZWQgYnkgdGhlIGV4cG9uZW50IGVsZW1lbnQuCisgKiA8bGk+PGZvbnQgY29sb3I9InJlZCI+PHN0cm9uZz5ORVc8L3N0cm9uZz4mbmJzcDs8L2ZvbnQ+IFR3bworICogZ3JvdXBpbmcgaW50ZXJ2YWxzIGFyZSByZWNvZ25pemVkOiBUaGUgb25lIGJldHdlZW4gdGhlIGRlY2ltYWwgcG9pbnQgYW5kIHRoZQorICogZmlyc3QgZ3JvdXBpbmcgc3ltYm9sIGFuZCB0aGUgb25lIGJldHdlZW4gdGhlIGZpcnN0IGFuZCBzZWNvbmQgZ3JvdXBpbmcKKyAqIHN5bWJvbHMuIFRoZXNlIGludGVydmFscyBhcmUgaWRlbnRpY2FsIGluIG1vc3QgbG9jYWxlcywgYnV0IGluIHNvbWUgbG9jYWxlcworICogdGhleSBkaWZmZXIuIEZvciBleGFtcGxlLCB0aGUgcGF0dGVybiAmcXVvdDsjLCMjLCMjIyZxdW90OyBmb3JtYXRzIHRoZSBudW1iZXIKKyAqIDEyMzQ1Njc4OSBhcyAmcXVvdDsxMiwzNCw1Niw3ODkmcXVvdDsuPC9saT4KKyAqIDxsaT4gPHN0cm9uZz48Zm9udCBjb2xvcj0icmVkIj5ORVc8L2ZvbnQ+Jm5ic3A7PC9zdHJvbmc+IFRoZSBwYWQKKyAqIHNwZWNpZmllciB7QGNvZGUgcGFkU3BlY30gbWF5IGFwcGVhciBiZWZvcmUgdGhlIHByZWZpeCwgYWZ0ZXIgdGhlIHByZWZpeCwKKyAqIGJlZm9yZSB0aGUgc3VmZml4LCBhZnRlciB0aGUgc3VmZml4IG9yIG5vdCBhdCBhbGwuCisgKiA8L3VsPgorICogPGg0PlBhcnNpbmc8L2g0PgorICogPHA+CisgKiB7QGNvZGUgRGVjaW1hbEZvcm1hdH0gcGFyc2VzIGFsbCBVbmljb2RlIGNoYXJhY3RlcnMgdGhhdCByZXByZXNlbnQgZGVjaW1hbAorICogZGlnaXRzLCBhcyBkZWZpbmVkIGJ5IHtAbGluayBDaGFyYWN0ZXIjZGlnaXQoaW50LCBpbnQpfS4gSW4gYWRkaXRpb24sCisgKiB7QGNvZGUgRGVjaW1hbEZvcm1hdH0gYWxzbyByZWNvZ25pemVzIGFzIGRpZ2l0cyB0aGUgdGVuIGNvbnNlY3V0aXZlCisgKiBjaGFyYWN0ZXJzIHN0YXJ0aW5nIHdpdGggdGhlIGxvY2FsaXplZCB6ZXJvIGRpZ2l0IGRlZmluZWQgaW4gdGhlCisgKiB7QGxpbmsgRGVjaW1hbEZvcm1hdFN5bWJvbHN9IG9iamVjdC4gRHVyaW5nIGZvcm1hdHRpbmcsIHRoZQorICoge0BsaW5rIERlY2ltYWxGb3JtYXRTeW1ib2xzfS1iYXNlZCBkaWdpdHMgYXJlIHdyaXR0ZW4gb3V0LgorICogPHA+CisgKiBEdXJpbmcgcGFyc2luZywgZ3JvdXBpbmcgc2VwYXJhdG9ycyBhcmUgaWdub3JlZC4KKyAqIDxwPgorICogSWYge0BsaW5rICNwYXJzZShTdHJpbmcsIFBhcnNlUG9zaXRpb24pfSBmYWlscyB0byBwYXJzZSBhIHN0cmluZywgaXQgcmV0dXJucworICoge0Bjb2RlIG51bGx9IGFuZCBsZWF2ZXMgdGhlIHBhcnNlIHBvc2l0aW9uIHVuY2hhbmdlZC4KKyAqIDxoND5Gb3JtYXR0aW5nPC9oND4KKyAqIDxwPgorICogRm9ybWF0dGluZyBpcyBndWlkZWQgYnkgc2V2ZXJhbCBwYXJhbWV0ZXJzLCBhbGwgb2Ygd2hpY2ggY2FuIGJlIHNwZWNpZmllZAorICogZWl0aGVyIHVzaW5nIGEgcGF0dGVybiBvciB1c2luZyB0aGUgQVBJLiBUaGUgZm9sbG93aW5nIGRlc2NyaXB0aW9uIGFwcGxpZXMgdG8KKyAqIGZvcm1hdHMgdGhhdCBkbyBub3QgdXNlIDxhIGhyZWY9IiNzY2kiPnNjaWVudGlmaWMgbm90YXRpb248L2E+IG9yIDxhCisgKiBocmVmPSIjc2lnZGlnIj5zaWduaWZpY2FudCBkaWdpdHM8L2E+LgorICogPHVsPgorICogPGxpPklmIHRoZSBudW1iZXIgb2YgYWN0dWFsIGludGVnZXIgZGlnaXRzIGV4Y2VlZHMgdGhlCisgKiA8ZW0+bWF4aW11bSBpbnRlZ2VyIGRpZ2l0czwvZW0+LCB0aGVuIG9ubHkgdGhlIGxlYXN0IHNpZ25pZmljYW50IGRpZ2l0cworICogYXJlIHNob3duLiBGb3IgZXhhbXBsZSwgMTk5NyBpcyBmb3JtYXR0ZWQgYXMgIjk3IiBpZiBtYXhpbXVtIGludGVnZXIgZGlnaXRzCisgKiBpcyBzZXQgdG8gMi4KKyAqIDxsaT5JZiB0aGUgbnVtYmVyIG9mIGFjdHVhbCBpbnRlZ2VyIGRpZ2l0cyBpcyBsZXNzIHRoYW4gdGhlCisgKiA8ZW0+bWluaW11bSBpbnRlZ2VyIGRpZ2l0czwvZW0+LCB0aGVuIGxlYWRpbmcgemVyb3MgYXJlIGFkZGVkLiBGb3IKKyAqIGV4YW1wbGUsIDE5OTcgaXMgZm9ybWF0dGVkIGFzICIwMTk5NyIgaWYgbWluaW11bSBpbnRlZ2VyIGRpZ2l0cyBpcyBzZXQgdG8gNS4KKyAqIDxsaT5JZiB0aGUgbnVtYmVyIG9mIGFjdHVhbCBmcmFjdGlvbiBkaWdpdHMgZXhjZWVkcyB0aGUgPGVtPm1heGltdW0KKyAqIGZyYWN0aW9uIGRpZ2l0czwvZW0+LAorICogdGhlbiBoYWxmLWV2ZW4gcm91bmRpbmcgaXMgcGVyZm9ybWVkIHRvIHRoZSBtYXhpbXVtIGZyYWN0aW9uIGRpZ2l0cy4gRm9yCisgKiBleGFtcGxlLCAwLjEyNSBpcyBmb3JtYXR0ZWQgYXMgIjAuMTIiIGlmIHRoZSBtYXhpbXVtIGZyYWN0aW9uIGRpZ2l0cyBpcyAyLgorICogPGxpPklmIHRoZSBudW1iZXIgb2YgYWN0dWFsIGZyYWN0aW9uIGRpZ2l0cyBpcyBsZXNzIHRoYW4gdGhlCisgKiA8ZW0+bWluaW11bSBmcmFjdGlvbiBkaWdpdHM8L2VtPiwgdGhlbiB0cmFpbGluZyB6ZXJvcyBhcmUgYWRkZWQuIEZvcgorICogZXhhbXBsZSwgMC4xMjUgaXMgZm9ybWF0dGVkIGFzICIwLjEyNTAiIGlmIHRoZSBtaW5pbXVtIGZyYWN0aW9uIGRpZ2l0cyBpcyBzZXQKKyAqIHRvIDQuCisgKiA8bGk+VHJhaWxpbmcgZnJhY3Rpb25hbCB6ZXJvcyBhcmUgbm90IGRpc3BsYXllZCBpZiB0aGV5IG9jY3VyIDxlbT5qPC9lbT4KKyAqIHBvc2l0aW9ucyBhZnRlciB0aGUgZGVjaW1hbCwgd2hlcmUgPGVtPmo8L2VtPiBpcyBsZXNzIHRoYW4gdGhlIG1heGltdW0KKyAqIGZyYWN0aW9uIGRpZ2l0cy4gRm9yIGV4YW1wbGUsIDAuMTAwMDQgaXMgZm9ybWF0dGVkIGFzICIwLjEiIGlmIHRoZSBtYXhpbXVtCisgKiBmcmFjdGlvbiBkaWdpdHMgaXMgZm91ciBvciBsZXNzLgorICogPC91bD4KKyAqIDxwPgorICogPHN0cm9uZz5TcGVjaWFsIFZhbHVlczwvc3Ryb25nPgorICogPHA+CisgKiB7QGNvZGUgTmFOfSBpcyByZXByZXNlbnRlZCBhcyBhIHNpbmdsZSBjaGFyYWN0ZXIsIHR5cGljYWxseQorICoge0Bjb2RlIFx1MDA1Y3VGRkZEfS4gVGhpcyBjaGFyYWN0ZXIgaXMgZGV0ZXJtaW5lZCBieSB0aGUKKyAqIHtAbGluayBEZWNpbWFsRm9ybWF0U3ltYm9sc30gb2JqZWN0LiBUaGlzIGlzIHRoZSBvbmx5IHZhbHVlIGZvciB3aGljaCB0aGUKKyAqIHByZWZpeGVzIGFuZCBzdWZmaXhlcyBhcmUgbm90IHVzZWQuCisgKiA8cD4KKyAqIEluZmluaXR5IGlzIHJlcHJlc2VudGVkIGFzIGEgc2luZ2xlIGNoYXJhY3RlciwgdHlwaWNhbGx5IHtAY29kZSBcdTAwNWN1MjIxRX0sCisgKiB3aXRoIHRoZSBwb3NpdGl2ZSBvciBuZWdhdGl2ZSBwcmVmaXhlcyBhbmQgc3VmZml4ZXMgYXBwbGllZC4gVGhlIGluZmluaXR5CisgKiBjaGFyYWN0ZXIgaXMgZGV0ZXJtaW5lZCBieSB0aGUge0BsaW5rIERlY2ltYWxGb3JtYXRTeW1ib2xzfSBvYmplY3QuIDxhCisgKiBuYW1lPSJzY2kiPgorICogPGg0PlNjaWVudGlmaWMgTm90YXRpb248L2g0PgorICogPC9hPgorICogPHA+CisgKiBOdW1iZXJzIGluIHNjaWVudGlmaWMgbm90YXRpb24gYXJlIGV4cHJlc3NlZCBhcyB0aGUgcHJvZHVjdCBvZiBhIG1hbnRpc3NhIGFuZAorICogYSBwb3dlciBvZiB0ZW4sIGZvciBleGFtcGxlLCAxMjM0IGNhbiBiZSBleHByZXNzZWQgYXMgMS4yMzQgeCAxMDxzdXA+Mzwvc3VwPi4KKyAqIFRoZSBtYW50aXNzYSBpcyB0eXBpY2FsbHkgaW4gdGhlIGhhbGYtb3BlbiBpbnRlcnZhbCBbMS4wLCAxMC4wKSBvciBzb21ldGltZXMKKyAqIFswLjAsIDEuMCksIGJ1dCBpdCBkb2VzIG5vdCBuZWVkIHRvIGJlLiB7QGNvZGUgRGVjaW1hbEZvcm1hdH0gc3VwcG9ydHMKKyAqIGFyYml0cmFyeSBtYW50aXNzYXMuIHtAY29kZSBEZWNpbWFsRm9ybWF0fSBjYW4gYmUgaW5zdHJ1Y3RlZCB0byB1c2UKKyAqIHNjaWVudGlmaWMgbm90YXRpb24gdGhyb3VnaCB0aGUgQVBJIG9yIHRocm91Z2ggdGhlIHBhdHRlcm4uIEluIGEgcGF0dGVybiwgdGhlCisgKiBleHBvbmVudCBjaGFyYWN0ZXIgaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgb25lIG9yIG1vcmUgZGlnaXQgY2hhcmFjdGVycworICogaW5kaWNhdGVzIHNjaWVudGlmaWMgbm90YXRpb24uIEV4YW1wbGU6ICIwLiMjI0UwIiBmb3JtYXRzIHRoZSBudW1iZXIgMTIzNCBhcworICogIjEuMjM0RTMiLgorICogPHVsPgorICogPGxpPlRoZSBudW1iZXIgb2YgZGlnaXQgY2hhcmFjdGVycyBhZnRlciB0aGUgZXhwb25lbnQgY2hhcmFjdGVyIGdpdmVzIHRoZQorICogbWluaW11bSBleHBvbmVudCBkaWdpdCBjb3VudC4gVGhlcmUgaXMgbm8gbWF4aW11bS4gTmVnYXRpdmUgZXhwb25lbnRzIGFyZQorICogZm9ybWF0dGVkIHVzaW5nIHRoZSBsb2NhbGl6ZWQgbWludXMgc2lnbiwgPGVtPm5vdDwvZW0+IHRoZSBwcmVmaXggYW5kCisgKiBzdWZmaXggZnJvbSB0aGUgcGF0dGVybi4gVGhpcyBhbGxvd3MgcGF0dGVybnMgc3VjaCBhcyAiMC4jIyNFMCBtL3MiLiBUbworICogcHJlZml4IHBvc2l0aXZlIGV4cG9uZW50cyB3aXRoIGEgbG9jYWxpemVkIHBsdXMgc2lnbiwgc3BlY2lmeSAnKycgYmV0d2VlbiB0aGUKKyAqIGV4cG9uZW50IGFuZCB0aGUgZGlnaXRzOiAiMC4jIyNFKzAiIHdpbGwgcHJvZHVjZSBmb3JtYXRzICIxRSsxIiwgIjFFKzAiLAorICogIjFFLTEiLCBldGMuIChJbiBsb2NhbGl6ZWQgcGF0dGVybnMsIHVzZSB0aGUgbG9jYWxpemVkIHBsdXMgc2lnbiByYXRoZXIgdGhhbgorICogJysnLikKKyAqIDxsaT5UaGUgbWluaW11bSBudW1iZXIgb2YgaW50ZWdlciBkaWdpdHMgaXMgYWNoaWV2ZWQgYnkgYWRqdXN0aW5nIHRoZQorICogZXhwb25lbnQuIEV4YW1wbGU6IDAuMDAxMjMgZm9ybWF0dGVkIHdpdGggIjAwLiMjI0UwIiB5aWVsZHMgIjEyLjNFLTQiLiBUaGlzCisgKiBvbmx5IGhhcHBlbnMgaWYgdGhlcmUgaXMgbm8gbWF4aW11bSBudW1iZXIgb2YgaW50ZWdlciBkaWdpdHMuIElmIHRoZXJlIGlzIGEKKyAqIG1heGltdW0sIHRoZW4gdGhlIG1pbmltdW0gbnVtYmVyIG9mIGludGVnZXIgZGlnaXRzIGlzIGZpeGVkIGF0IG9uZS4KKyAqIDxsaT5UaGUgbWF4aW11bSBudW1iZXIgb2YgaW50ZWdlciBkaWdpdHMsIGlmIHByZXNlbnQsIHNwZWNpZmllcyB0aGUgZXhwb25lbnQKKyAqIGdyb3VwaW5nLiBUaGUgbW9zdCBjb21tb24gdXNlIG9mIHRoaXMgaXMgdG8gZ2VuZXJhdGUgPGVtPmVuZ2luZWVyaW5nCisgKiBub3RhdGlvbjwvZW0+LAorICogaW4gd2hpY2ggdGhlIGV4cG9uZW50IGlzIGEgbXVsdGlwbGUgb2YgdGhyZWUsIGUuZy4sICIjIzAuIyMjRTAiLiBUaGUgbnVtYmVyCisgKiAxMjM0NSBpcyBmb3JtYXR0ZWQgdXNpbmcgIiMjMC4jIyNFMCIgYXMgIjEyLjM0NUUzIi4KKyAqIDxsaT5XaGVuIHVzaW5nIHNjaWVudGlmaWMgbm90YXRpb24sIHRoZSBmb3JtYXR0ZXIgY29udHJvbHMgdGhlIGRpZ2l0IGNvdW50cworICogdXNpbmcgc2lnbmlmaWNhbnQgZGlnaXRzIGxvZ2ljLiBUaGUgbWF4aW11bSBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgZGlnaXRzCisgKiBsaW1pdHMgdGhlIHRvdGFsIG51bWJlciBvZiBpbnRlZ2VyIGFuZCBmcmFjdGlvbiBkaWdpdHMgdGhhdCB3aWxsIGJlIHNob3duIGluCisgKiB0aGUgbWFudGlzc2E7IGl0IGRvZXMgbm90IGFmZmVjdCBwYXJzaW5nLiBGb3IgZXhhbXBsZSwgMTIzNDUgZm9ybWF0dGVkIHdpdGgKKyAqICIjIzAuIyNFMCIgaXMgIjEyLjNFMyIuIFNlZSB0aGUgc2VjdGlvbiBvbiBzaWduaWZpY2FudCBkaWdpdHMgZm9yIG1vcmUKKyAqIGRldGFpbHMuCisgKiA8bGk+VGhlIG51bWJlciBvZiBzaWduaWZpY2FudCBkaWdpdHMgc2hvd24gaXMgZGV0ZXJtaW5lZCBhcyBmb2xsb3dzOiBJZiBubworICogc2lnbmlmaWNhbnQgZGlnaXRzIGFyZSB1c2VkIGluIHRoZSBwYXR0ZXJuIHRoZW4gdGhlIG1pbmltdW0gbnVtYmVyIG9mCisgKiBzaWduaWZpY2FudCBkaWdpdHMgc2hvd24gaXMgb25lLCB0aGUgbWF4aW11bSBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgZGlnaXRzCisgKiBzaG93biBpcyB0aGUgc3VtIG9mIHRoZSA8ZW0+bWluaW11bSBpbnRlZ2VyPC9lbT4gYW5kCisgKiA8ZW0+bWF4aW11bSBmcmFjdGlvbjwvZW0+IGRpZ2l0cywgYW5kIGl0IGlzIHVuYWZmZWN0ZWQgYnkgdGhlIG1heGltdW0KKyAqIGludGVnZXIgZGlnaXRzLiBJZiB0aGlzIHN1bSBpcyB6ZXJvLCB0aGVuIGFsbCBzaWduaWZpY2FudCBkaWdpdHMgYXJlIHNob3duLgorICogSWYgc2lnbmlmaWNhbnQgZGlnaXRzIGFyZSB1c2VkIGluIHRoZSBwYXR0ZXJuIHRoZW4gdGhlIG51bWJlciBvZiBpbnRlZ2VyCisgKiBkaWdpdHMgaXMgZml4ZWQgYXQgb25lIGFuZCB0aGVyZSBpcyBubyBleHBvbmVudCBncm91cGluZy4KKyAqIDxsaT5FeHBvbmVudGlhbCBwYXR0ZXJucyBtYXkgbm90IGNvbnRhaW4gZ3JvdXBpbmcgc2VwYXJhdG9ycy4KKyAqIDwvdWw+CisgKiA8YSBuYW1lPSJzaWdkaWciPgorICogPGg0PiA8c3Ryb25nPjxmb250IGNvbG9yPSJyZWQiPk5FVzwvZm9udD4mbmJzcDs8L3N0cm9uZz4gU2lnbmlmaWNhbnQKKyAqIERpZ2l0czwvaDQ+CisgKiA8cD4KKyAqIDwvYT4ge0Bjb2RlIERlY2ltYWxGb3JtYXR9IGhhcyB0d28gd2F5cyBvZiBjb250cm9sbGluZyBob3cgbWFueSBkaWdpdHMgYXJlCisgKiBzaG93bjogKGEpIHNpZ25pZmljYW50IGRpZ2l0IGNvdW50cyBvciAoYikgaW50ZWdlciBhbmQgZnJhY3Rpb24gZGlnaXQgY291bnRzLgorICogSW50ZWdlciBhbmQgZnJhY3Rpb24gZGlnaXQgY291bnRzIGFyZSBkZXNjcmliZWQgYWJvdmUuIFdoZW4gYSBmb3JtYXR0ZXIgdXNlcworICogc2lnbmlmaWNhbnQgZGlnaXRzIGNvdW50cywgdGhlIG51bWJlciBvZiBpbnRlZ2VyIGFuZCBmcmFjdGlvbiBkaWdpdHMgaXMgbm90CisgKiBzcGVjaWZpZWQgZGlyZWN0bHksIGFuZCB0aGUgZm9ybWF0dGVyIHNldHRpbmdzIGZvciB0aGVzZSBjb3VudHMgYXJlIGlnbm9yZWQuCisgKiBJbnN0ZWFkLCB0aGUgZm9ybWF0dGVyIHVzZXMgYXMgbWFueSBpbnRlZ2VyIGFuZCBmcmFjdGlvbiBkaWdpdHMgYXMgcmVxdWlyZWQKKyAqIHRvIGRpc3BsYXkgdGhlIHNwZWNpZmllZCBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgZGlnaXRzLgorICogPGg1PkV4YW1wbGVzOjwvaDU+CisgKiA8YmxvY2txdW90ZT4gPHRhYmxlIGJvcmRlcj0wIGNlbGxzcGFjaW5nPTMgY2VsbHBhZGRpbmc9MD4KKyAqIDx0ciBiZ2NvbG9yPSIjY2NjY2ZmIj4KKyAqIDx0aCBhbGlnbj0ibGVmdCI+UGF0dGVybjwvdGg+CisgKiA8dGggYWxpZ249ImxlZnQiPk1pbmltdW0gc2lnbmlmaWNhbnQgZGlnaXRzPC90aD4KKyAqIDx0aCBhbGlnbj0ibGVmdCI+TWF4aW11bSBzaWduaWZpY2FudCBkaWdpdHM8L3RoPgorICogPHRoIGFsaWduPSJsZWZ0Ij5OdW1iZXI8L3RoPgorICogPHRoIGFsaWduPSJsZWZ0Ij5PdXRwdXQgb2YgZm9ybWF0KCk8L3RoPgorICogPC90cj4KKyAqIDx0ciB2YWxpZ249InRvcCI+CisgKiA8dGQ+e0Bjb2RlIEBAQH0KKyAqIDx0ZD4zPC90ZD4KKyAqIDx0ZD4zPC90ZD4KKyAqIDx0ZD4xMjM0NTwvdGQ+CisgKiA8dGQ+e0Bjb2RlIDEyMzAwfTwvdGQ+CisgKiA8L3RyPgorICogPHRyIHZhbGlnbj0idG9wIiBiZ2NvbG9yPSIjZWVlZWZmIj4KKyAqIDx0ZD57QGNvZGUgQEBAfTwvdGQ+CisgKiA8dGQ+MzwvdGQ+CisgKiA8dGQ+MzwvdGQ+CisgKiA8dGQ+MC4xMjM0NTwvdGQ+CisgKiA8dGQ+e0Bjb2RlIDAuMTIzfTwvdGQ+CisgKiA8L3RyPgorICogPHRyIHZhbGlnbj0idG9wIj4KKyAqIDx0ZD57QGNvZGUgQEAjI308L3RkPgorICogPHRkPjI8L3RkPgorICogPHRkPjQ8L3RkPgorICogPHRkPjMuMTQxNTk8L3RkPgorICogPHRkPntAY29kZSAzLjE0Mn08L3RkPgorICogPC90cj4KKyAqIDx0ciB2YWxpZ249InRvcCIgYmdjb2xvcj0iI2VlZWVmZiI+CisgKiA8dGQ+e0Bjb2RlIEBAIyN9PC90ZD4KKyAqIDx0ZD4yPC90ZD4KKyAqIDx0ZD40PC90ZD4KKyAqIDx0ZD4xLjIzMDA0PC90ZD4KKyAqIDx0ZD57QGNvZGUgMS4yM308L3RkPgorICogPC90cj4KKyAqIDwvdGFibGU+IDwvYmxvY2txdW90ZT4KKyAqIDx1bD4KKyAqIDxsaT5TaWduaWZpY2FudCBkaWdpdCBjb3VudHMgbWF5IGJlIGV4cHJlc3NlZCB1c2luZyBwYXR0ZXJucyB0aGF0IHNwZWNpZnkgYQorICogbWluaW11bSBhbmQgbWF4aW11bSBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgZGlnaXRzLiBUaGVzZSBhcmUgaW5kaWNhdGVkIGJ5IHRoZQorICoge0Bjb2RlICdAJ30gYW5kIHtAY29kZSAnIyd9IGNoYXJhY3RlcnMuIFRoZSBtaW5pbXVtIG51bWJlciBvZiBzaWduaWZpY2FudAorICogZGlnaXRzIGlzIHRoZSBudW1iZXIgb2Yge0Bjb2RlICdAJ30gY2hhcmFjdGVycy4gVGhlIG1heGltdW0gbnVtYmVyIG9mCisgKiBzaWduaWZpY2FudCBkaWdpdHMgaXMgdGhlIG51bWJlciBvZiB7QGNvZGUgJ0AnfSBjaGFyYWN0ZXJzIHBsdXMgdGhlIG51bWJlciBvZgorICoge0Bjb2RlICcjJ30gY2hhcmFjdGVycyBmb2xsb3dpbmcgb24gdGhlIHJpZ2h0LiBGb3IgZXhhbXBsZSwgdGhlIHBhdHRlcm4KKyAqIHtAY29kZSAiQEBAIn0gaW5kaWNhdGVzIGV4YWN0bHkgMyBzaWduaWZpY2FudCBkaWdpdHMuIFRoZSBwYXR0ZXJuCisgKiB7QGNvZGUgIkAjIyJ9IGluZGljYXRlcyBmcm9tIDEgdG8gMyBzaWduaWZpY2FudCBkaWdpdHMuIFRyYWlsaW5nIHplcm8gZGlnaXRzCisgKiB0byB0aGUgcmlnaHQgb2YgdGhlIGRlY2ltYWwgc2VwYXJhdG9yIGFyZSBzdXBwcmVzc2VkIGFmdGVyIHRoZSBtaW5pbXVtIG51bWJlcgorICogb2Ygc2lnbmlmaWNhbnQgZGlnaXRzIGhhdmUgYmVlbiBzaG93bi4gRm9yIGV4YW1wbGUsIHRoZSBwYXR0ZXJuIHtAY29kZSAiQCMjIn0KKyAqIGZvcm1hdHMgdGhlIG51bWJlciAwLjEyMDMgYXMge0Bjb2RlICIwLjEyIn0uCisgKiA8bGk+SWYgYSBwYXR0ZXJuIHVzZXMgc2lnbmlmaWNhbnQgZGlnaXRzLCBpdCBtYXkgbm90IGNvbnRhaW4gYSBkZWNpbWFsCisgKiBzZXBhcmF0b3IsIG5vciB0aGUge0Bjb2RlICcwJ30gcGF0dGVybiBjaGFyYWN0ZXIuIFBhdHRlcm5zIHN1Y2ggYXMKKyAqIHtAY29kZSAiQDAwIn0gb3Ige0Bjb2RlICJALiMjIyJ9IGFyZSBkaXNhbGxvd2VkLgorICogPGxpPkFueSBudW1iZXIgb2Yge0Bjb2RlICcjJ30gY2hhcmFjdGVycyBtYXkgYmUgcHJlcGVuZGVkIHRvIHRoZSBsZWZ0IG9mIHRoZQorICogbGVmdG1vc3Qge0Bjb2RlICdAJ30gY2hhcmFjdGVyLiBUaGVzZSBoYXZlIG5vIGVmZmVjdCBvbiB0aGUgbWluaW11bSBhbmQKKyAqIG1heGltdW0gc2lnbmlmaWNhbnQgZGlnaXQgY291bnRzLCBidXQgbWF5IGJlIHVzZWQgdG8gcG9zaXRpb24gZ3JvdXBpbmcKKyAqIHNlcGFyYXRvcnMuIEZvciBleGFtcGxlLCB7QGNvZGUgIiMsI0AjIn0gaW5kaWNhdGVzIGEgbWluaW11bSBvZiBvbmUKKyAqIHNpZ25pZmljYW50IGRpZ2l0LCBhIG1heGltdW0gb2YgdHdvIHNpZ25pZmljYW50IGRpZ2l0cywgYW5kIGEgZ3JvdXBpbmcgc2l6ZQorICogb2YgdGhyZWUuCisgKiA8bGk+SW4gb3JkZXIgdG8gZW5hYmxlIHNpZ25pZmljYW50IGRpZ2l0cyBmb3JtYXR0aW5nLCB1c2UgYSBwYXR0ZXJuCisgKiBjb250YWluaW5nIHRoZSB7QGNvZGUgJ0AnfSBwYXR0ZXJuIGNoYXJhY3Rlci4KKyAqIDxsaT5JbiBvcmRlciB0byBkaXNhYmxlIHNpZ25pZmljYW50IGRpZ2l0cyBmb3JtYXR0aW5nLCB1c2UgYSBwYXR0ZXJuIHRoYXQKKyAqIGRvZXMgbm90IGNvbnRhaW4gdGhlIHtAY29kZSAnQCd9IHBhdHRlcm4gY2hhcmFjdGVyLgorICogPGxpPlRoZSBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgZGlnaXRzIGhhcyBubyBlZmZlY3Qgb24gcGFyc2luZy4KKyAqIDxsaT5TaWduaWZpY2FudCBkaWdpdHMgbWF5IGJlIHVzZWQgdG9nZXRoZXIgd2l0aCBleHBvbmVudGlhbCBub3RhdGlvbi4gU3VjaAorICogcGF0dGVybnMgYXJlIGVxdWl2YWxlbnQgdG8gYSBub3JtYWwgZXhwb25lbnRpYWwgcGF0dGVybiB3aXRoIGEgbWluaW11bSBhbmQKKyAqIG1heGltdW0gaW50ZWdlciBkaWdpdCBjb3VudCBvZiBvbmUsIGEgbWluaW11bSBmcmFjdGlvbiBkaWdpdCBjb3VudCBvZiB0aGUKKyAqIG51bWJlciBvZiAnQCcgY2hhcmFjdGVycyBpbiB0aGUgcGF0dGVybiAtIDEsIGFuZCBhIG1heGltdW0gZnJhY3Rpb24gZGlnaXQKKyAqIGNvdW50IG9mIHRoZSBudW1iZXIgb2YgJ0AnIGFuZCAnIycgY2hhcmFjdGVycyBpbiB0aGUgcGF0dGVybiAtIDEuIEZvcgorICogZXhhbXBsZSwgdGhlIHBhdHRlcm4ge0Bjb2RlICJAQCMjI0UwIn0gaXMgZXF1aXZhbGVudCB0byB7QGNvZGUgIjAuMCMjI0UwIn0uCisgKiA8bGk+SWYgc2lnbmlmaWNhbnQgZGlnaXRzIGFyZSBpbiB1c2UgdGhlbiB0aGUgaW50ZWdlciBhbmQgZnJhY3Rpb24gZGlnaXQKKyAqIGNvdW50cywgYXMgc2V0IHZpYSB0aGUgQVBJLCBhcmUgaWdub3JlZC4KKyAqIDwvdWw+CisgKiA8aDQ+IDxzdHJvbmc+PGZvbnQgY29sb3I9InJlZCI+TkVXPC9mb250PiZuYnNwOzwvc3Ryb25nPiBQYWRkaW5nPC9oND4KKyAqIDxwPgorICoge0Bjb2RlIERlY2ltYWxGb3JtYXR9IHN1cHBvcnRzIHBhZGRpbmcgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZm9ybWF0fSB0byBhCisgKiBzcGVjaWZpYyB3aWR0aC4gUGFkZGluZyBtYXkgYmUgc3BlY2lmaWVkIGVpdGhlciB0aHJvdWdoIHRoZSBBUEkgb3IgdGhyb3VnaAorICogdGhlIHBhdHRlcm4gc3ludGF4LiBJbiBhIHBhdHRlcm4sIHRoZSBwYWQgZXNjYXBlIGNoYXJhY3RlciBmb2xsb3dlZCBieSBhCisgKiBzaW5nbGUgcGFkIGNoYXJhY3RlciBjYXVzZXMgcGFkZGluZyB0byBiZSBwYXJzZWQgYW5kIGZvcm1hdHRlZC4gVGhlIHBhZAorICogZXNjYXBlIGNoYXJhY3RlciBpcyAnKicgaW4gdW5sb2NhbGl6ZWQgcGF0dGVybnMuIEZvciBleGFtcGxlLAorICoge0Bjb2RlICIkKngjLCMjMC4wMCJ9IGZvcm1hdHMgMTIzIHRvIHtAY29kZSAiJHh4MTIzLjAwIn0sIGFuZCAxMjM0IHRvCisgKiB7QGNvZGUgIiQxLDIzNC4wMCJ9LgorICogPHVsPgorICogPGxpPldoZW4gcGFkZGluZyBpcyBpbiBlZmZlY3QsIHRoZSB3aWR0aCBvZiB0aGUgcG9zaXRpdmUgc3VicGF0dGVybiwKKyAqIGluY2x1ZGluZyBwcmVmaXggYW5kIHN1ZmZpeCwgZGV0ZXJtaW5lcyB0aGUgZm9ybWF0IHdpZHRoLiBGb3IgZXhhbXBsZSwgaW4gdGhlCisgKiBwYXR0ZXJuIHtAY29kZSAiKiAjMCBvJydjbG9jayJ9LCB0aGUgZm9ybWF0IHdpZHRoIGlzIDEwLjwvbGk+CisgKiA8bGk+VGhlIHdpZHRoIGlzIGNvdW50ZWQgaW4gMTYtYml0IGNvZGUgdW5pdHMgKEphdmEge0Bjb2RlIGNoYXJ9cykuPC9saT4KKyAqIDxsaT5Tb21lIHBhcmFtZXRlcnMgd2hpY2ggdXN1YWxseSBkbyBub3QgbWF0dGVyIGhhdmUgbWVhbmluZyB3aGVuIHBhZGRpbmcgaXMKKyAqIHVzZWQsIGJlY2F1c2UgdGhlIHBhdHRlcm4gd2lkdGggaXMgc2lnbmlmaWNhbnQgd2l0aCBwYWRkaW5nLiBJbiB0aGUgcGF0dGVybiAiKgorICogIyMsIyMsIywjIzAuIyMiLCB0aGUgZm9ybWF0IHdpZHRoIGlzIDE0LiBUaGUgaW5pdGlhbCBjaGFyYWN0ZXJzICIjIywjIywiIGRvCisgKiBub3QgYWZmZWN0IHRoZSBncm91cGluZyBzaXplIG9yIG1heGltdW0gaW50ZWdlciBkaWdpdHMsIGJ1dCB0aGV5IGRvIGFmZmVjdAorICogdGhlIGZvcm1hdCB3aWR0aC48L2xpPgorICogPGxpPlBhZGRpbmcgbWF5IGJlIGluc2VydGVkIGF0IG9uZSBvZiBmb3VyIGxvY2F0aW9uczogYmVmb3JlIHRoZSBwcmVmaXgsCisgKiBhZnRlciB0aGUgcHJlZml4LCBiZWZvcmUgdGhlIHN1ZmZpeCBvciBhZnRlciB0aGUgc3VmZml4LiBJZiBwYWRkaW5nIGlzCisgKiBzcGVjaWZpZWQgaW4gYW55IG90aGVyIGxvY2F0aW9uLCB7QGxpbmsgI2FwcGx5UGF0dGVybn0gdGhyb3dzIGFuIHtAbGluaworICogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufS4gSWYgdGhlcmUgaXMgbm8gcHJlZml4LCBiZWZvcmUgdGhlIHByZWZpeCBhbmQgYWZ0ZXIKKyAqIHRoZSBwcmVmaXggYXJlIGVxdWl2YWxlbnQsIGxpa2V3aXNlIGZvciB0aGUgc3VmZml4LjwvbGk+CisgKiA8bGk+V2hlbiBzcGVjaWZpZWQgaW4gYSBwYXR0ZXJuLCB0aGUgMTYtYml0IHtAY29kZSBjaGFyfSBpbW1lZGlhdGVseQorICogZm9sbG93aW5nIHRoZSBwYWQgZXNjYXBlIGlzIHRoZSBwYWQgY2hhcmFjdGVyLiBUaGlzIG1heSBiZSBhbnkgY2hhcmFjdGVyLAorICogaW5jbHVkaW5nIGEgc3BlY2lhbCBwYXR0ZXJuIGNoYXJhY3Rlci4gVGhhdCBpcywgdGhlIHBhZCBlc2NhcGUKKyAqIDxlbT5lc2NhcGVzPC9lbT4gdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXIuIElmIHRoZXJlIGlzIG5vIGNoYXJhY3RlciBhZnRlcgorICogdGhlIHBhZCBlc2NhcGUsIHRoZW4gdGhlIHBhdHRlcm4gaXMgaWxsZWdhbC48L2xpPgorICogPC91bD4KKyAqIDxoND5TeW5jaHJvbml6YXRpb248L2g0PgorICogPHA+CisgKiB7QGNvZGUgRGVjaW1hbEZvcm1hdH0gb2JqZWN0cyBhcmUgbm90IHN5bmNocm9uaXplZC4gTXVsdGlwbGUgdGhyZWFkcyBzaG91bGQKKyAqIG5vdCBhY2Nlc3Mgb25lIGZvcm1hdHRlciBjb25jdXJyZW50bHkuCisgKgorICogQHNlZSBGb3JtYXQKKyAqIEBzZWUgTnVtYmVyRm9ybWF0CisgKi8KK3B1YmxpYyBjbGFzcyBEZWNpbWFsRm9ybWF0IGV4dGVuZHMgTnVtYmVyRm9ybWF0IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDg2NDQxMzM3NjU1MTQ2NTAxOEw7CisKKyAgICBwcml2YXRlIHRyYW5zaWVudCBEZWNpbWFsRm9ybWF0U3ltYm9scyBzeW1ib2xzOworCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgTmF0aXZlRGVjaW1hbEZvcm1hdCBkZm9ybTsKKyAgICBwcml2YXRlIGZpbmFsIE9iamVjdCBmaW5hbGl6ZXJHdWFyZGlhbiA9IG5ldyBPYmplY3QoKSB7CisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBkZm9ybS5jbG9zZSgpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBzdXBlci5maW5hbGl6ZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfTsKKworICAgIHByaXZhdGUgdHJhbnNpZW50IFJvdW5kaW5nTW9kZSByb3VuZGluZ01vZGUgPSBSb3VuZGluZ01vZGUuSEFMRl9FVkVOOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRGVjaW1hbEZvcm1hdH0gZm9yIGZvcm1hdHRpbmcgYW5kIHBhcnNpbmcgbnVtYmVycworICAgICAqIGZvciB0aGUgdXNlcidzIGRlZmF1bHQgbG9jYWxlLgorICAgICAqIFNlZSAiPGEgaHJlZj0iLi4vdXRpbC9Mb2NhbGUuaHRtbCNkZWZhdWx0X2xvY2FsZSI+QmUgd2FyeSBvZiB0aGUgZGVmYXVsdCBsb2NhbGU8L2E+Ii4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGVjaW1hbEZvcm1hdCgpIHsKKyAgICAgICAgTG9jYWxlIGxvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgICAgIHRoaXMuc3ltYm9scyA9IG5ldyBEZWNpbWFsRm9ybWF0U3ltYm9scyhsb2NhbGUpOworICAgICAgICBpbml0TmF0aXZlKExvY2FsZURhdGEuZ2V0KGxvY2FsZSkubnVtYmVyUGF0dGVybik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRGVjaW1hbEZvcm1hdH0gdXNpbmcgdGhlIHNwZWNpZmllZCBub24tbG9jYWxpemVkCisgICAgICogcGF0dGVybiBhbmQgdGhlIHtAY29kZSBEZWNpbWFsRm9ybWF0U3ltYm9sc30gZm9yIHRoZSB1c2VyJ3MgZGVmYXVsdCBMb2NhbGUuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqIEBwYXJhbSBwYXR0ZXJuCisgICAgICogICAgICAgICAgICB0aGUgbm9uLWxvY2FsaXplZCBwYXR0ZXJuLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICBpZiB0aGUgcGF0dGVybiBjYW5ub3QgYmUgcGFyc2VkLgorICAgICAqLworICAgIHB1YmxpYyBEZWNpbWFsRm9ybWF0KFN0cmluZyBwYXR0ZXJuKSB7CisgICAgICAgIHRoaXMocGF0dGVybiwgTG9jYWxlLmdldERlZmF1bHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRGVjaW1hbEZvcm1hdH0gdXNpbmcgdGhlIHNwZWNpZmllZCBub24tbG9jYWxpemVkCisgICAgICogcGF0dGVybiBhbmQge0Bjb2RlIERlY2ltYWxGb3JtYXRTeW1ib2xzfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXR0ZXJuCisgICAgICogICAgICAgICAgICB0aGUgbm9uLWxvY2FsaXplZCBwYXR0ZXJuLgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIERlY2ltYWxGb3JtYXRTeW1ib2xzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICBpZiB0aGUgcGF0dGVybiBjYW5ub3QgYmUgcGFyc2VkLgorICAgICAqLworICAgIHB1YmxpYyBEZWNpbWFsRm9ybWF0KFN0cmluZyBwYXR0ZXJuLCBEZWNpbWFsRm9ybWF0U3ltYm9scyB2YWx1ZSkgeworICAgICAgICB0aGlzLnN5bWJvbHMgPSAoRGVjaW1hbEZvcm1hdFN5bWJvbHMpIHZhbHVlLmNsb25lKCk7CisgICAgICAgIGluaXROYXRpdmUocGF0dGVybik7CisgICAgfQorCisgICAgLy8gVXNlZCBieSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UgYmVjYXVzZSBjbG9uaW5nIERlY2ltYWxGb3JtYXRTeW1ib2xzIGlzIHNsb3cuCisgICAgRGVjaW1hbEZvcm1hdChTdHJpbmcgcGF0dGVybiwgTG9jYWxlIGxvY2FsZSkgeworICAgICAgICB0aGlzLnN5bWJvbHMgPSBuZXcgRGVjaW1hbEZvcm1hdFN5bWJvbHMobG9jYWxlKTsKKyAgICAgICAgaW5pdE5hdGl2ZShwYXR0ZXJuKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgaW5pdE5hdGl2ZShTdHJpbmcgcGF0dGVybikgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhpcy5kZm9ybSA9IG5ldyBOYXRpdmVEZWNpbWFsRm9ybWF0KHBhdHRlcm4sIHN5bWJvbHMpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ocGF0dGVybik7CisgICAgICAgIH0KKyAgICAgICAgc3VwZXIuc2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKGRmb3JtLmdldE1heGltdW1GcmFjdGlvbkRpZ2l0cygpKTsKKyAgICAgICAgc3VwZXIuc2V0TWF4aW11bUludGVnZXJEaWdpdHMoZGZvcm0uZ2V0TWF4aW11bUludGVnZXJEaWdpdHMoKSk7CisgICAgICAgIHN1cGVyLnNldE1pbmltdW1GcmFjdGlvbkRpZ2l0cyhkZm9ybS5nZXRNaW5pbXVtRnJhY3Rpb25EaWdpdHMoKSk7CisgICAgICAgIHN1cGVyLnNldE1pbmltdW1JbnRlZ2VyRGlnaXRzKGRmb3JtLmdldE1pbmltdW1JbnRlZ2VyRGlnaXRzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoYW5nZXMgdGhlIHBhdHRlcm4gb2YgdGhpcyBkZWNpbWFsIGZvcm1hdCB0byB0aGUgc3BlY2lmaWVkIHBhdHRlcm4gd2hpY2gKKyAgICAgKiB1c2VzIGxvY2FsaXplZCBwYXR0ZXJuIGNoYXJhY3RlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGF0dGVybgorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsaXplZCBwYXR0ZXJuLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICBpZiB0aGUgcGF0dGVybiBjYW5ub3QgYmUgcGFyc2VkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFwcGx5TG9jYWxpemVkUGF0dGVybihTdHJpbmcgcGF0dGVybikgeworICAgICAgICBkZm9ybS5hcHBseUxvY2FsaXplZFBhdHRlcm4ocGF0dGVybik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hhbmdlcyB0aGUgcGF0dGVybiBvZiB0aGlzIGRlY2ltYWwgZm9ybWF0IHRvIHRoZSBzcGVjaWZpZWQgcGF0dGVybiB3aGljaAorICAgICAqIHVzZXMgbm9uLWxvY2FsaXplZCBwYXR0ZXJuIGNoYXJhY3RlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGF0dGVybgorICAgICAqICAgICAgICAgICAgdGhlIG5vbi1sb2NhbGl6ZWQgcGF0dGVybi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYgdGhlIHBhdHRlcm4gY2Fubm90IGJlIHBhcnNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhcHBseVBhdHRlcm4oU3RyaW5nIHBhdHRlcm4pIHsKKyAgICAgICAgZGZvcm0uYXBwbHlQYXR0ZXJuKHBhdHRlcm4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIERlY2ltYWxGb3JtYXR9IHdpdGggdGhlIHNhbWUgcGF0dGVybiBhbmQKKyAgICAgKiBwcm9wZXJ0aWVzIGFzIHRoaXMgZGVjaW1hbCBmb3JtYXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc2hhbGxvdyBjb3B5IG9mIHRoaXMgZGVjaW1hbCBmb3JtYXQuCisgICAgICogQHNlZSBqYXZhLmxhbmcuQ2xvbmVhYmxlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgRGVjaW1hbEZvcm1hdCBjbG9uZSA9IChEZWNpbWFsRm9ybWF0KSBzdXBlci5jbG9uZSgpOworICAgICAgICBjbG9uZS5kZm9ybSA9IChOYXRpdmVEZWNpbWFsRm9ybWF0KSBkZm9ybS5jbG9uZSgpOworICAgICAgICBjbG9uZS5zeW1ib2xzID0gKERlY2ltYWxGb3JtYXRTeW1ib2xzKSBzeW1ib2xzLmNsb25lKCk7CisgICAgICAgIHJldHVybiBjbG9uZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIG9iamVjdCB0byB0aGlzIGRlY2ltYWwgZm9ybWF0IGFuZCBpbmRpY2F0ZXMgaWYKKyAgICAgKiB0aGV5IGFyZSBlcXVhbC4gSW4gb3JkZXIgdG8gYmUgZXF1YWwsIHtAY29kZSBvYmplY3R9IG11c3QgYmUgYW4gaW5zdGFuY2UKKyAgICAgKiBvZiB7QGNvZGUgRGVjaW1hbEZvcm1hdH0gd2l0aCB0aGUgc2FtZSBwYXR0ZXJuIGFuZCBwcm9wZXJ0aWVzLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHdpdGggdGhpcyBvYmplY3QuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgZXF1YWwgdG8gdGhpcyBkZWNpbWFsCisgICAgICogICAgICAgICBmb3JtYXQ7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgI2hhc2hDb2RlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgaWYgKHRoaXMgPT0gb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBEZWNpbWFsRm9ybWF0KSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIERlY2ltYWxGb3JtYXQgb3RoZXIgPSAoRGVjaW1hbEZvcm1hdCkgb2JqZWN0OworICAgICAgICByZXR1cm4gKHRoaXMuZGZvcm0gPT0gbnVsbCA/IG90aGVyLmRmb3JtID09IG51bGwgOiB0aGlzLmRmb3JtLmVxdWFscyhvdGhlci5kZm9ybSkpICYmCisgICAgICAgICAgICAgICAgZ2V0RGVjaW1hbEZvcm1hdFN5bWJvbHMoKS5lcXVhbHMob3RoZXIuZ2V0RGVjaW1hbEZvcm1hdFN5bWJvbHMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRm9ybWF0cyB0aGUgc3BlY2lmaWVkIG9iamVjdCB1c2luZyB0aGUgcnVsZXMgb2YgdGhpcyBkZWNpbWFsIGZvcm1hdCBhbmQKKyAgICAgKiByZXR1cm5zIGFuIHtAY29kZSBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3J9IHdpdGggdGhlIGZvcm1hdHRlZCBudW1iZXIKKyAgICAgKiBhbmQgYXR0cmlidXRlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gZm9ybWF0LgorICAgICAqIEByZXR1cm4gYW4gQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIHdpdGggdGhlIGZvcm1hdHRlZCBudW1iZXIgYW5kCisgICAgICogICAgICAgICBhdHRyaWJ1dGVzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9iamVjdH0gY2Fubm90IGJlIGZvcm1hdHRlZCBieSB0aGlzIGZvcm1hdC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9iamVjdH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcihPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRmb3JtLmZvcm1hdFRvQ2hhcmFjdGVySXRlcmF0b3Iob2JqZWN0KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tCdWZmZXJBbmRGaWVsZFBvc2l0aW9uKFN0cmluZ0J1ZmZlciBidWZmZXIsIEZpZWxkUG9zaXRpb24gcG9zaXRpb24pIHsKKyAgICAgICAgaWYgKGJ1ZmZlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImJ1ZmZlciA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBvc2l0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicG9zaXRpb24gPT0gbnVsbCIpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ0J1ZmZlciBmb3JtYXQoZG91YmxlIHZhbHVlLCBTdHJpbmdCdWZmZXIgYnVmZmVyLCBGaWVsZFBvc2l0aW9uIHBvc2l0aW9uKSB7CisgICAgICAgIGNoZWNrQnVmZmVyQW5kRmllbGRQb3NpdGlvbihidWZmZXIsIHBvc2l0aW9uKTsKKyAgICAgICAgLy8gQWxsIGZsb2F0L2RvdWJsZS9GbG9hdC9Eb3VibGUgZm9ybWF0dGluZyBlbmRzIHVwIGhlcmUuLi4KKyAgICAgICAgaWYgKHJvdW5kaW5nTW9kZSA9PSBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkpIHsKKyAgICAgICAgICAgIC8vIElDVTRDIGRvZXNuJ3Qgc3VwcG9ydCB0aGlzIHJvdW5kaW5nIG1vZGUsIHNvIHdlIGhhdmUgdG8gZmFrZSBpdC4KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2V0Um91bmRpbmdNb2RlKFJvdW5kaW5nTW9kZS5VUCk7CisgICAgICAgICAgICAgICAgU3RyaW5nIHVwUmVzdWx0ID0gZm9ybWF0KHZhbHVlLCBuZXcgU3RyaW5nQnVmZmVyKCksIG5ldyBGaWVsZFBvc2l0aW9uKDApKS50b1N0cmluZygpOworICAgICAgICAgICAgICAgIHNldFJvdW5kaW5nTW9kZShSb3VuZGluZ01vZGUuRE9XTik7CisgICAgICAgICAgICAgICAgU3RyaW5nIGRvd25SZXN1bHQgPSBmb3JtYXQodmFsdWUsIG5ldyBTdHJpbmdCdWZmZXIoKSwgbmV3IEZpZWxkUG9zaXRpb24oMCkpLnRvU3RyaW5nKCk7CisgICAgICAgICAgICAgICAgaWYgKCF1cFJlc3VsdC5lcXVhbHMoZG93blJlc3VsdCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFyaXRobWV0aWNFeGNlcHRpb24oInJvdW5kaW5nIG1vZGUgVU5ORUNFU1NBUlkgYnV0IHJvdW5kaW5nIHJlcXVpcmVkIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBzZXRSb3VuZGluZ01vZGUoUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBidWZmZXIuYXBwZW5kKGRmb3JtLmZvcm1hdERvdWJsZSh2YWx1ZSwgcG9zaXRpb24pKTsKKyAgICAgICAgcmV0dXJuIGJ1ZmZlcjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGZvcm1hdChsb25nIHZhbHVlLCBTdHJpbmdCdWZmZXIgYnVmZmVyLCBGaWVsZFBvc2l0aW9uIHBvc2l0aW9uKSB7CisgICAgICAgIGNoZWNrQnVmZmVyQW5kRmllbGRQb3NpdGlvbihidWZmZXIsIHBvc2l0aW9uKTsKKyAgICAgICAgYnVmZmVyLmFwcGVuZChkZm9ybS5mb3JtYXRMb25nKHZhbHVlLCBwb3NpdGlvbikpOworICAgICAgICByZXR1cm4gYnVmZmVyOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBTdHJpbmdCdWZmZXIgZm9ybWF0KE9iamVjdCBudW1iZXIsIFN0cmluZ0J1ZmZlciBidWZmZXIsIEZpZWxkUG9zaXRpb24gcG9zaXRpb24pIHsKKyAgICAgICAgY2hlY2tCdWZmZXJBbmRGaWVsZFBvc2l0aW9uKGJ1ZmZlciwgcG9zaXRpb24pOworICAgICAgICBpZiAobnVtYmVyIGluc3RhbmNlb2YgQmlnSW50ZWdlcikgeworICAgICAgICAgICAgQmlnSW50ZWdlciBiaWdJbnRlZ2VyID0gKEJpZ0ludGVnZXIpIG51bWJlcjsKKyAgICAgICAgICAgIGNoYXJbXSBjaGFycyA9IChiaWdJbnRlZ2VyLmJpdExlbmd0aCgpIDwgNjQpCisgICAgICAgICAgICAgICAgICAgID8gZGZvcm0uZm9ybWF0TG9uZyhiaWdJbnRlZ2VyLmxvbmdWYWx1ZSgpLCBwb3NpdGlvbikKKyAgICAgICAgICAgICAgICAgICAgOiBkZm9ybS5mb3JtYXRCaWdJbnRlZ2VyKGJpZ0ludGVnZXIsIHBvc2l0aW9uKTsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoY2hhcnMpOworICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlcjsKKyAgICAgICAgfSBlbHNlIGlmIChudW1iZXIgaW5zdGFuY2VvZiBCaWdEZWNpbWFsKSB7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGRmb3JtLmZvcm1hdEJpZ0RlY2ltYWwoKEJpZ0RlY2ltYWwpIG51bWJlciwgcG9zaXRpb24pKTsKKyAgICAgICAgICAgIHJldHVybiBidWZmZXI7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN1cGVyLmZvcm1hdChudW1iZXIsIGJ1ZmZlciwgcG9zaXRpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBEZWNpbWFsRm9ybWF0U3ltYm9sc30gdXNlZCBieSB0aGlzIGRlY2ltYWwgZm9ybWF0LgorICAgICAqCisgICAgICogQHJldHVybiBhIGNvcHkgb2YgdGhlIHtAY29kZSBEZWNpbWFsRm9ybWF0U3ltYm9sc30gdXNlZCBieSB0aGlzIGRlY2ltYWwKKyAgICAgKiAgICAgICAgIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGVjaW1hbEZvcm1hdFN5bWJvbHMgZ2V0RGVjaW1hbEZvcm1hdFN5bWJvbHMoKSB7CisgICAgICAgIHJldHVybiAoRGVjaW1hbEZvcm1hdFN5bWJvbHMpIHN5bWJvbHMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW5jeSB1c2VkIGJ5IHRoaXMgZGVjaW1hbCBmb3JtYXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW5jeSB1c2VkIGJ5IHRoaXMgZGVjaW1hbCBmb3JtYXQuCisgICAgICogQHNlZSBEZWNpbWFsRm9ybWF0U3ltYm9scyNnZXRDdXJyZW5jeSgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEN1cnJlbmN5IGdldEN1cnJlbmN5KCkgeworICAgICAgICByZXR1cm4gc3ltYm9scy5nZXRDdXJyZW5jeSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBkaWdpdHMgZ3JvdXBlZCB0b2dldGhlciBieSB0aGUgZ3JvdXBpbmcgc2VwYXJhdG9yLgorICAgICAqIFRoaXMgb25seSBhbGxvd3MgdG8gZ2V0IHRoZSBwcmltYXJ5IGdyb3VwaW5nIHNpemUuIFRoZXJlIGlzIG5vIEFQSSB0byBnZXQKKyAgICAgKiB0aGUgc2Vjb25kYXJ5IGdyb3VwaW5nIHNpemUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgZGlnaXRzIGdyb3VwZWQgdG9nZXRoZXIuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRHcm91cGluZ1NpemUoKSB7CisgICAgICAgIHJldHVybiBkZm9ybS5nZXRHcm91cGluZ1NpemUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtdWx0aXBsaWVyIHdoaWNoIGlzIGFwcGxpZWQgdG8gdGhlIG51bWJlciBiZWZvcmUgZm9ybWF0dGluZworICAgICAqIG9yIGFmdGVyIHBhcnNpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtdWx0aXBsaWVyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TXVsdGlwbGllcigpIHsKKyAgICAgICAgcmV0dXJuIGRmb3JtLmdldE11bHRpcGxpZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcmVmaXggd2hpY2ggaXMgZm9ybWF0dGVkIG9yIHBhcnNlZCBiZWZvcmUgYSBuZWdhdGl2ZSBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZWdhdGl2ZSBwcmVmaXguCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROZWdhdGl2ZVByZWZpeCgpIHsKKyAgICAgICAgcmV0dXJuIGRmb3JtLmdldE5lZ2F0aXZlUHJlZml4KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3VmZml4IHdoaWNoIGlzIGZvcm1hdHRlZCBvciBwYXJzZWQgYWZ0ZXIgYSBuZWdhdGl2ZSBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZWdhdGl2ZSBzdWZmaXguCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROZWdhdGl2ZVN1ZmZpeCgpIHsKKyAgICAgICAgcmV0dXJuIGRmb3JtLmdldE5lZ2F0aXZlU3VmZml4KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJlZml4IHdoaWNoIGlzIGZvcm1hdHRlZCBvciBwYXJzZWQgYmVmb3JlIGEgcG9zaXRpdmUgbnVtYmVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcG9zaXRpdmUgcHJlZml4LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UG9zaXRpdmVQcmVmaXgoKSB7CisgICAgICAgIHJldHVybiBkZm9ybS5nZXRQb3NpdGl2ZVByZWZpeCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN1ZmZpeCB3aGljaCBpcyBmb3JtYXR0ZWQgb3IgcGFyc2VkIGFmdGVyIGEgcG9zaXRpdmUgbnVtYmVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcG9zaXRpdmUgc3VmZml4LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UG9zaXRpdmVTdWZmaXgoKSB7CisgICAgICAgIHJldHVybiBkZm9ybS5nZXRQb3NpdGl2ZVN1ZmZpeCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiBkZm9ybS5oYXNoQ29kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBkZWNpbWFsIHNlcGFyYXRvciBpcyBzaG93biB3aGVuIHRoZXJlIGFyZSBubworICAgICAqIGZyYWN0aW9uYWwgZGlnaXRzLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGRlY2ltYWwgc2VwYXJhdG9yIHNob3VsZCBhbHdheXMgYmUgZm9ybWF0dGVkOworICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNEZWNpbWFsU2VwYXJhdG9yQWx3YXlzU2hvd24oKSB7CisgICAgICAgIHJldHVybiBkZm9ybS5pc0RlY2ltYWxTZXBhcmF0b3JBbHdheXNTaG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgdmFsdWUgaW5kaWNhdGVzIHdoZXRoZXIgdGhlIHJldHVybiBvYmplY3Qgb2YgdGhlIHBhcnNlIG9wZXJhdGlvbiBpcworICAgICAqIG9mIHR5cGUge0Bjb2RlIEJpZ0RlY2ltYWx9LiBUaGlzIHZhbHVlIGRlZmF1bHRzIHRvIHtAY29kZSBmYWxzZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBwYXJzZSBhbHdheXMgcmV0dXJucyB7QGNvZGUgQmlnRGVjaW1hbHN9LAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBpZiB0aGUgdHlwZSBvZiB0aGUgcmVzdWx0IGlzIHtAY29kZSBMb25nfSBvcgorICAgICAqICAgICAgICAge0Bjb2RlIERvdWJsZX0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNQYXJzZUJpZ0RlY2ltYWwoKSB7CisgICAgICAgIHJldHVybiBkZm9ybS5pc1BhcnNlQmlnRGVjaW1hbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZsYWcgdGhhdCBpbmRpY2F0ZXMgd2hldGhlciBudW1iZXJzIHdpbGwgYmUgcGFyc2VkIGFzIGludGVnZXJzLgorICAgICAqIFdoZW4gdGhpcyBkZWNpbWFsIGZvcm1hdCBpcyB1c2VkIGZvciBwYXJzaW5nIGFuZCB0aGlzIHZhbHVlIGlzIHNldCB0bworICAgICAqIHtAY29kZSB0cnVlfSwgdGhlbiB0aGUgcmVzdWx0aW5nIG51bWJlcnMgd2lsbCBiZSBvZiB0eXBlCisgICAgICoge0Bjb2RlIGphdmEubGFuZy5JbnRlZ2VyfS4gU3BlY2lhbCBjYXNlcyBhcmUgTmFOLCBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUKKyAgICAgKiBpbmZpbml0eSwgd2hpY2ggYXJlIHN0aWxsIHJldHVybmVkIGFzIHtAY29kZSBqYXZhLmxhbmcuRG91YmxlfS4KKyAgICAgKgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gdGhhdCB0aGUgcmVzdWx0aW5nIG51bWJlcnMgb2YgcGFyc2Ugb3BlcmF0aW9ucworICAgICAqICAgICAgICAgICAgd2lsbCBiZSBvZiB0eXBlIHtAY29kZSBqYXZhLmxhbmcuSW50ZWdlcn0gZXhjZXB0IGZvciB0aGUKKyAgICAgKiAgICAgICAgICAgIHNwZWNpYWwgY2FzZXMgZGVzY3JpYmVkIGFib3ZlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlSW50ZWdlck9ubHkoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICAvLyBJbiB0aGlzIGltcGxlbWVudGF0aW9uLCBOYXRpdmVEZWNpbWFsRm9ybWF0IGlzIHdyYXBwZWQgdG8KKyAgICAgICAgLy8gZnVsZmlsbCBtb3N0IG9mIHRoZSBmb3JtYXQgYW5kIHBhcnNlIGZlYXR1cmUuIEFuZCB0aGlzIG1ldGhvZCBpcworICAgICAgICAvLyBkZWxlZ2F0ZWQgdG8gdGhlIHdyYXBwZWQgaW5zdGFuY2Ugb2YgTmF0aXZlRGVjaW1hbEZvcm1hdC4KKyAgICAgICAgZGZvcm0uc2V0UGFyc2VJbnRlZ2VyT25seSh2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgcGFyc2luZyB3aXRoIHRoaXMgZGVjaW1hbCBmb3JtYXQgd2lsbCBvbmx5CisgICAgICogcmV0dXJuIG51bWJlcnMgb2YgdHlwZSB7QGNvZGUgamF2YS5sYW5nLkludGVnZXJ9LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgRGVjaW1hbEZvcm1hdH0ncyBwYXJzZSBtZXRob2Qgb25seQorICAgICAqICAgICAgICAgcmV0dXJucyB7QGNvZGUgamF2YS5sYW5nLkludGVnZXJ9OyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1BhcnNlSW50ZWdlck9ubHkoKSB7CisgICAgICAgIHJldHVybiBkZm9ybS5pc1BhcnNlSW50ZWdlck9ubHkoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBEb3VibGUgTkVHQVRJVkVfWkVST19ET1VCTEUgPSBuZXcgRG91YmxlKC0wLjApOworCisgICAgLyoqCisgICAgICogUGFyc2VzIGEge0Bjb2RlIExvbmd9IG9yIHtAY29kZSBEb3VibGV9IGZyb20gdGhlIHNwZWNpZmllZCBzdHJpbmcKKyAgICAgKiBzdGFydGluZyBhdCB0aGUgaW5kZXggc3BlY2lmaWVkIGJ5IHtAY29kZSBwb3NpdGlvbn0uIElmIHRoZSBzdHJpbmcgaXMKKyAgICAgKiBzdWNjZXNzZnVsbHkgcGFyc2VkIHRoZW4gdGhlIGluZGV4IG9mIHRoZSB7QGNvZGUgUGFyc2VQb3NpdGlvbn0gaXMKKyAgICAgKiB1cGRhdGVkIHRvIHRoZSBpbmRleCBmb2xsb3dpbmcgdGhlIHBhcnNlZCB0ZXh0LiBPbiBlcnJvciwgdGhlIGluZGV4IGlzCisgICAgICogdW5jaGFuZ2VkIGFuZCB0aGUgZXJyb3IgaW5kZXggb2Yge0Bjb2RlIFBhcnNlUG9zaXRpb259IGlzIHNldCB0byB0aGUKKyAgICAgKiBpbmRleCB3aGVyZSB0aGUgZXJyb3Igb2NjdXJyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHBhcnNlLgorICAgICAqIEBwYXJhbSBwb3NpdGlvbgorICAgICAqICAgICAgICAgICAgaW5wdXQvb3V0cHV0IHBhcmFtZXRlciwgc3BlY2lmaWVzIHRoZSBzdGFydCBpbmRleCBpbgorICAgICAqICAgICAgICAgICAge0Bjb2RlIHN0cmluZ30gZnJvbSB3aGVyZSB0byBzdGFydCBwYXJzaW5nLiBJZiBwYXJzaW5nIGlzCisgICAgICogICAgICAgICAgICBzdWNjZXNzZnVsLCBpdCBpcyB1cGRhdGVkIHdpdGggdGhlIGluZGV4IGZvbGxvd2luZyB0aGUgcGFyc2VkCisgICAgICogICAgICAgICAgICB0ZXh0OyBvbiBlcnJvciwgdGhlIGluZGV4IGlzIHVuY2hhbmdlZCBhbmQgdGhlIGVycm9yIGluZGV4IGlzCisgICAgICogICAgICAgICAgICBzZXQgdG8gdGhlIGluZGV4IHdoZXJlIHRoZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIExvbmd9IG9yIHtAY29kZSBEb3VibGV9IHJlc3VsdGluZyBmcm9tIHRoZSBwYXJzZSBvcgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIGFuIGVycm9yLiBUaGUgcmVzdWx0IHdpbGwgYmUgYQorICAgICAqICAgICAgICAge0Bjb2RlIExvbmd9IGlmIHRoZSBwYXJzZWQgbnVtYmVyIGlzIGFuIGludGVnZXIgaW4gdGhlIHJhbmdlIG9mIGEKKyAgICAgKiAgICAgICAgIGxvbmcsIG90aGVyd2lzZSB0aGUgcmVzdWx0IGlzIGEge0Bjb2RlIERvdWJsZX0uIElmCisgICAgICogICAgICAgICB7QGNvZGUgaXNQYXJzZUJpZ0RlY2ltYWx9IGlzIHtAY29kZSB0cnVlfSB0aGVuIGl0IHJldHVybnMgdGhlCisgICAgICogICAgICAgICByZXN1bHQgYXMgYSB7QGNvZGUgQmlnRGVjaW1hbH0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE51bWJlciBwYXJzZShTdHJpbmcgc3RyaW5nLCBQYXJzZVBvc2l0aW9uIHBvc2l0aW9uKSB7CisgICAgICAgIE51bWJlciBudW1iZXIgPSBkZm9ybS5wYXJzZShzdHJpbmcsIHBvc2l0aW9uKTsKKyAgICAgICAgaWYgKG51bWJlciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpZiAodGhpcy5pc1BhcnNlQmlnRGVjaW1hbCgpKSB7CisgICAgICAgICAgICBpZiAobnVtYmVyIGluc3RhbmNlb2YgTG9uZykgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQmlnRGVjaW1hbChudW1iZXIubG9uZ1ZhbHVlKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKChudW1iZXIgaW5zdGFuY2VvZiBEb3VibGUpICYmICEoKERvdWJsZSkgbnVtYmVyKS5pc0luZmluaXRlKCkKKyAgICAgICAgICAgICAgICAgICAgJiYgISgoRG91YmxlKSBudW1iZXIpLmlzTmFOKCkpIHsKKworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQmlnRGVjaW1hbChudW1iZXIudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobnVtYmVyIGluc3RhbmNlb2YgQmlnSW50ZWdlcikgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQmlnRGVjaW1hbChudW1iZXIudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVtYmVyOworICAgICAgICB9CisgICAgICAgIGlmICgobnVtYmVyIGluc3RhbmNlb2YgQmlnRGVjaW1hbCkgfHwgKG51bWJlciBpbnN0YW5jZW9mIEJpZ0ludGVnZXIpKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IERvdWJsZShudW1iZXIuZG91YmxlVmFsdWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRoaXMuaXNQYXJzZUludGVnZXJPbmx5KCkgJiYgbnVtYmVyLmVxdWFscyhORUdBVElWRV9aRVJPX0RPVUJMRSkpIHsKKyAgICAgICAgICAgIHJldHVybiBMb25nLnZhbHVlT2YoMCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bWJlcjsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHtAY29kZSBEZWNpbWFsRm9ybWF0U3ltYm9sc30gdXNlZCBieSB0aGlzIGRlY2ltYWwgZm9ybWF0LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIERlY2ltYWxGb3JtYXRTeW1ib2xzfSB0byBzZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGVjaW1hbEZvcm1hdFN5bWJvbHMoRGVjaW1hbEZvcm1hdFN5bWJvbHMgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vIFRoZSBKYXZhIG9iamVjdCBpcyBjYW5vbmljYWwsIGFuZCB3ZSBjb3B5IGRvd24gdG8gbmF0aXZlIGNvZGUuCisgICAgICAgICAgICB0aGlzLnN5bWJvbHMgPSAoRGVjaW1hbEZvcm1hdFN5bWJvbHMpIHZhbHVlLmNsb25lKCk7CisgICAgICAgICAgICBkZm9ybS5zZXREZWNpbWFsRm9ybWF0U3ltYm9scyh0aGlzLnN5bWJvbHMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY3VycmVuY3kgdXNlZCBieSB0aGlzIGRlY2ltYWwgZm9ybWF0LiBUaGUgbWluIGFuZCBtYXggZnJhY3Rpb24KKyAgICAgKiBkaWdpdHMgcmVtYWluIHRoZSBzYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIGN1cnJlbmN5CisgICAgICogICAgICAgICAgICB0aGUgY3VycmVuY3kgdGhpcyB7QGNvZGUgRGVjaW1hbEZvcm1hdH0gc2hvdWxkIHVzZS4KKyAgICAgKiBAc2VlIERlY2ltYWxGb3JtYXRTeW1ib2xzI3NldEN1cnJlbmN5KEN1cnJlbmN5KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEN1cnJlbmN5KEN1cnJlbmN5IGN1cnJlbmN5KSB7CisgICAgICAgIGRmb3JtLnNldEN1cnJlbmN5KEN1cnJlbmN5LmdldEluc3RhbmNlKGN1cnJlbmN5LmdldEN1cnJlbmN5Q29kZSgpKSk7CisgICAgICAgIHN5bWJvbHMuc2V0Q3VycmVuY3koY3VycmVuY3kpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgd2hldGhlciB0aGUgZGVjaW1hbCBzZXBhcmF0b3IgaXMgc2hvd24gd2hlbiB0aGVyZSBhcmUgbm8gZnJhY3Rpb25hbAorICAgICAqIGRpZ2l0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGlmIHRoZSBkZWNpbWFsIHNlcGFyYXRvciBzaG91bGQgYWx3YXlzIGJlCisgICAgICogICAgICAgICAgICBmb3JtYXR0ZWQ7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERlY2ltYWxTZXBhcmF0b3JBbHdheXNTaG93bihib29sZWFuIHZhbHVlKSB7CisgICAgICAgIGRmb3JtLnNldERlY2ltYWxTZXBhcmF0b3JBbHdheXNTaG93bih2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbnVtYmVyIG9mIGRpZ2l0cyBncm91cGVkIHRvZ2V0aGVyIGJ5IHRoZSBncm91cGluZyBzZXBhcmF0b3IuCisgICAgICogVGhpcyBvbmx5IGFsbG93cyB0byBzZXQgdGhlIHByaW1hcnkgZ3JvdXBpbmcgc2l6ZTsgdGhlIHNlY29uZGFyeSBncm91cGluZworICAgICAqIHNpemUgY2FuIG9ubHkgYmUgc2V0IHdpdGggYSBwYXR0ZXJuLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGRpZ2l0cyBncm91cGVkIHRvZ2V0aGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEdyb3VwaW5nU2l6ZShpbnQgdmFsdWUpIHsKKyAgICAgICAgZGZvcm0uc2V0R3JvdXBpbmdTaXplKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHdoZXRoZXIgb3Igbm90IGdyb3VwaW5nIHdpbGwgYmUgdXNlZCBpbiB0aGlzIGZvcm1hdC4gR3JvdXBpbmcKKyAgICAgKiBhZmZlY3RzIGJvdGggcGFyc2luZyBhbmQgZm9ybWF0dGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGlmIGdyb3VwaW5nIGlzIHVzZWQ7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEdyb3VwaW5nVXNlZChib29sZWFuIHZhbHVlKSB7CisgICAgICAgIGRmb3JtLnNldEdyb3VwaW5nVXNlZCh2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgZ3JvdXBpbmcgd2lsbCBiZSB1c2VkIGluIHRoaXMgZm9ybWF0LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgZ3JvdXBpbmcgaXMgdXNlZDsge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNHcm91cGluZ1VzZWQoKSB7CisgICAgICAgIHJldHVybiBkZm9ybS5pc0dyb3VwaW5nVXNlZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGRpZ2l0cyBhZnRlciB0aGUgZGVjaW1hbCBwb2ludC4KKyAgICAgKiBJZiB0aGUgdmFsdWUgcGFzc2VkIGlzIG5lZ2F0aXZlIHRoZW4gaXQgaXMgcmVwbGFjZWQgYnkgMC4KKyAgICAgKiBSZWdhcmRsZXNzIG9mIHRoaXMgc2V0dGluZywgbm8gbW9yZSB0aGFuIDM0MCBkaWdpdHMgd2lsbCBiZSB1c2VkLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSBtYXhpbXVtIG51bWJlciBvZiBmcmFjdGlvbiBkaWdpdHMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKGludCB2YWx1ZSkgeworICAgICAgICBzdXBlci5zZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHModmFsdWUpOworICAgICAgICBkZm9ybS5zZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoZ2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKCkpOworICAgICAgICAvLyBDaGFuZ2luZyB0aGUgbWF4aW11bSBmcmFjdGlvbiBkaWdpdHMgbmVlZHMgdG8gdXBkYXRlIElDVTRDJ3Mgcm91bmRpbmcgY29uZmlndXJhdGlvbi4KKyAgICAgICAgc2V0Um91bmRpbmdNb2RlKHJvdW5kaW5nTW9kZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbWF4aW11bSBudW1iZXIgb2YgZGlnaXRzIGJlZm9yZSB0aGUgZGVjaW1hbCBwb2ludC4KKyAgICAgKiBJZiB0aGUgdmFsdWUgcGFzc2VkIGlzIG5lZ2F0aXZlIHRoZW4gaXQgaXMgcmVwbGFjZWQgYnkgMC4KKyAgICAgKiBSZWdhcmRsZXNzIG9mIHRoaXMgc2V0dGluZywgbm8gbW9yZSB0aGFuIDMwOSBkaWdpdHMgd2lsbCBiZSB1c2VkLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSBtYXhpbXVtIG51bWJlciBvZiBpbnRlZ2VyIGRpZ2l0cy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRNYXhpbXVtSW50ZWdlckRpZ2l0cyhpbnQgdmFsdWUpIHsKKyAgICAgICAgc3VwZXIuc2V0TWF4aW11bUludGVnZXJEaWdpdHModmFsdWUpOworICAgICAgICBkZm9ybS5zZXRNYXhpbXVtSW50ZWdlckRpZ2l0cyhnZXRNYXhpbXVtSW50ZWdlckRpZ2l0cygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBtaW5pbXVtIG51bWJlciBvZiBkaWdpdHMgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQuCisgICAgICogSWYgdGhlIHZhbHVlIHBhc3NlZCBpcyBuZWdhdGl2ZSB0aGVuIGl0IGlzIHJlcGxhY2VkIGJ5IDAuCisgICAgICogUmVnYXJkbGVzcyBvZiB0aGlzIHNldHRpbmcsIG5vIG1vcmUgdGhhbiAzNDAgZGlnaXRzIHdpbGwgYmUgdXNlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgbWluaW11bSBudW1iZXIgb2YgZnJhY3Rpb24gZGlnaXRzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldE1pbmltdW1GcmFjdGlvbkRpZ2l0cyhpbnQgdmFsdWUpIHsKKyAgICAgICAgc3VwZXIuc2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKHZhbHVlKTsKKyAgICAgICAgZGZvcm0uc2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKGdldE1pbmltdW1GcmFjdGlvbkRpZ2l0cygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBtaW5pbXVtIG51bWJlciBvZiBkaWdpdHMgYmVmb3JlIHRoZSBkZWNpbWFsIHBvaW50LgorICAgICAqIElmIHRoZSB2YWx1ZSBwYXNzZWQgaXMgbmVnYXRpdmUgdGhlbiBpdCBpcyByZXBsYWNlZCBieSAwLgorICAgICAqIFJlZ2FyZGxlc3Mgb2YgdGhpcyBzZXR0aW5nLCBubyBtb3JlIHRoYW4gMzA5IGRpZ2l0cyB3aWxsIGJlIHVzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIG1pbmltdW0gbnVtYmVyIG9mIGludGVnZXIgZGlnaXRzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldE1pbmltdW1JbnRlZ2VyRGlnaXRzKGludCB2YWx1ZSkgeworICAgICAgICBzdXBlci5zZXRNaW5pbXVtSW50ZWdlckRpZ2l0cyh2YWx1ZSk7CisgICAgICAgIGRmb3JtLnNldE1pbmltdW1JbnRlZ2VyRGlnaXRzKGdldE1pbmltdW1JbnRlZ2VyRGlnaXRzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG11bHRpcGxpZXIgd2hpY2ggaXMgYXBwbGllZCB0byB0aGUgbnVtYmVyIGJlZm9yZSBmb3JtYXR0aW5nIG9yCisgICAgICogYWZ0ZXIgcGFyc2luZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG11bHRpcGxpZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TXVsdGlwbGllcihpbnQgdmFsdWUpIHsKKyAgICAgICAgZGZvcm0uc2V0TXVsdGlwbGllcih2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcHJlZml4IHdoaWNoIGlzIGZvcm1hdHRlZCBvciBwYXJzZWQgYmVmb3JlIGEgbmVnYXRpdmUgbnVtYmVyLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmVnYXRpdmUgcHJlZml4LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5lZ2F0aXZlUHJlZml4KFN0cmluZyB2YWx1ZSkgeworICAgICAgICBkZm9ybS5zZXROZWdhdGl2ZVByZWZpeCh2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc3VmZml4IHdoaWNoIGlzIGZvcm1hdHRlZCBvciBwYXJzZWQgYWZ0ZXIgYSBuZWdhdGl2ZSBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZWdhdGl2ZSBzdWZmaXguCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TmVnYXRpdmVTdWZmaXgoU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIGRmb3JtLnNldE5lZ2F0aXZlU3VmZml4KHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwcmVmaXggd2hpY2ggaXMgZm9ybWF0dGVkIG9yIHBhcnNlZCBiZWZvcmUgYSBwb3NpdGl2ZSBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3NpdGl2ZSBwcmVmaXguCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UG9zaXRpdmVQcmVmaXgoU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIGRmb3JtLnNldFBvc2l0aXZlUHJlZml4KHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzdWZmaXggd2hpY2ggaXMgZm9ybWF0dGVkIG9yIHBhcnNlZCBhZnRlciBhIHBvc2l0aXZlIG51bWJlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHBvc2l0aXZlIHN1ZmZpeC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQb3NpdGl2ZVN1ZmZpeChTdHJpbmcgdmFsdWUpIHsKKyAgICAgICAgZGZvcm0uc2V0UG9zaXRpdmVTdWZmaXgodmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGJlaGF2aW9yIG9mIHRoZSBwYXJzZSBtZXRob2QuIElmIHNldCB0byB7QGNvZGUgdHJ1ZX0gdGhlbiBhbGwKKyAgICAgKiB0aGUgcmV0dXJuZWQgb2JqZWN0cyB3aWxsIGJlIG9mIHR5cGUge0Bjb2RlIEJpZ0RlY2ltYWx9LgorICAgICAqCisgICAgICogQHBhcmFtIG5ld1ZhbHVlCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gaWYgYWxsIHRoZSByZXR1cm5lZCBvYmplY3RzIHNob3VsZCBiZSBvZiB0eXBlCisgICAgICogICAgICAgICAgICB7QGNvZGUgQmlnRGVjaW1hbH07IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlQmlnRGVjaW1hbChib29sZWFuIG5ld1ZhbHVlKSB7CisgICAgICAgIGRmb3JtLnNldFBhcnNlQmlnRGVjaW1hbChuZXdWYWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGF0dGVybiBvZiB0aGlzIGRlY2ltYWwgZm9ybWF0IHVzaW5nIGxvY2FsaXplZCBwYXR0ZXJuCisgICAgICogY2hhcmFjdGVycy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxvY2FsaXplZCBwYXR0ZXJuLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9Mb2NhbGl6ZWRQYXR0ZXJuKCkgeworICAgICAgICByZXR1cm4gZGZvcm0udG9Mb2NhbGl6ZWRQYXR0ZXJuKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGF0dGVybiBvZiB0aGlzIGRlY2ltYWwgZm9ybWF0IHVzaW5nIG5vbi1sb2NhbGl6ZWQgcGF0dGVybgorICAgICAqIGNoYXJhY3RlcnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBub24tbG9jYWxpemVkIHBhdHRlcm4uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1BhdHRlcm4oKSB7CisgICAgICAgIHJldHVybiBkZm9ybS50b1BhdHRlcm4oKTsKKyAgICB9CisKKyAgICAvLyB0aGUgZmllbGRzIGxpc3QgdG8gYmUgc2VyaWFsaXplZAorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFN0cmVhbUZpZWxkW10gc2VyaWFsUGVyc2lzdGVudEZpZWxkcyA9IHsKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJwb3NpdGl2ZVByZWZpeCIsIFN0cmluZy5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgicG9zaXRpdmVTdWZmaXgiLCBTdHJpbmcuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoIm5lZ2F0aXZlUHJlZml4IiwgU3RyaW5nLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJuZWdhdGl2ZVN1ZmZpeCIsIFN0cmluZy5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgicG9zUHJlZml4UGF0dGVybiIsIFN0cmluZy5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgicG9zU3VmZml4UGF0dGVybiIsIFN0cmluZy5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgibmVnUHJlZml4UGF0dGVybiIsIFN0cmluZy5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgibmVnU3VmZml4UGF0dGVybiIsIFN0cmluZy5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgibXVsdGlwbGllciIsIGludC5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiZ3JvdXBpbmdTaXplIiwgYnl0ZS5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiZ3JvdXBpbmdVc2VkIiwgYm9vbGVhbi5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiZGVjaW1hbFNlcGFyYXRvckFsd2F5c1Nob3duIiwgYm9vbGVhbi5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgicGFyc2VCaWdEZWNpbWFsIiwgYm9vbGVhbi5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgicm91bmRpbmdNb2RlIiwgUm91bmRpbmdNb2RlLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJzeW1ib2xzIiwgRGVjaW1hbEZvcm1hdFN5bWJvbHMuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInVzZUV4cG9uZW50aWFsTm90YXRpb24iLCBib29sZWFuLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJtaW5FeHBvbmVudERpZ2l0cyIsIGJ5dGUuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoIm1heGltdW1JbnRlZ2VyRGlnaXRzIiwgaW50LmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJtaW5pbXVtSW50ZWdlckRpZ2l0cyIsIGludC5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgibWF4aW11bUZyYWN0aW9uRGlnaXRzIiwgaW50LmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJtaW5pbXVtRnJhY3Rpb25EaWdpdHMiLCBpbnQuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInNlcmlhbFZlcnNpb25PblN0cmVhbSIsIGludC5jbGFzcyksCisgICAgfTsKKworICAgIC8qKgorICAgICAqIFdyaXRlcyBzZXJpYWxpemVkIGZpZWxkcyBmb2xsb3dpbmcgc2VyaWFsaXplZCBmb3JtcyBzcGVjaWZpZWQgYnkgSmF2YQorICAgICAqIHNwZWNpZmljYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyZWFtCisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IHN0cmVhbSB0byB3cml0ZSBzZXJpYWxpemVkIGJ5dGVzCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHNvbWUgSS9PIGVycm9yIG9jY3VycworICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGQgZmllbGRzID0gc3RyZWFtLnB1dEZpZWxkcygpOworICAgICAgICBmaWVsZHMucHV0KCJwb3NpdGl2ZVByZWZpeCIsIGRmb3JtLmdldFBvc2l0aXZlUHJlZml4KCkpOworICAgICAgICBmaWVsZHMucHV0KCJwb3NpdGl2ZVN1ZmZpeCIsIGRmb3JtLmdldFBvc2l0aXZlU3VmZml4KCkpOworICAgICAgICBmaWVsZHMucHV0KCJuZWdhdGl2ZVByZWZpeCIsIGRmb3JtLmdldE5lZ2F0aXZlUHJlZml4KCkpOworICAgICAgICBmaWVsZHMucHV0KCJuZWdhdGl2ZVN1ZmZpeCIsIGRmb3JtLmdldE5lZ2F0aXZlU3VmZml4KCkpOworICAgICAgICBmaWVsZHMucHV0KCJwb3NQcmVmaXhQYXR0ZXJuIiwgKFN0cmluZykgbnVsbCk7CisgICAgICAgIGZpZWxkcy5wdXQoInBvc1N1ZmZpeFBhdHRlcm4iLCAoU3RyaW5nKSBudWxsKTsKKyAgICAgICAgZmllbGRzLnB1dCgibmVnUHJlZml4UGF0dGVybiIsIChTdHJpbmcpIG51bGwpOworICAgICAgICBmaWVsZHMucHV0KCJuZWdTdWZmaXhQYXR0ZXJuIiwgKFN0cmluZykgbnVsbCk7CisgICAgICAgIGZpZWxkcy5wdXQoIm11bHRpcGxpZXIiLCBkZm9ybS5nZXRNdWx0aXBsaWVyKCkpOworICAgICAgICBmaWVsZHMucHV0KCJncm91cGluZ1NpemUiLCAoYnl0ZSkgZGZvcm0uZ2V0R3JvdXBpbmdTaXplKCkpOworICAgICAgICBmaWVsZHMucHV0KCJncm91cGluZ1VzZWQiLCBkZm9ybS5pc0dyb3VwaW5nVXNlZCgpKTsKKyAgICAgICAgZmllbGRzLnB1dCgiZGVjaW1hbFNlcGFyYXRvckFsd2F5c1Nob3duIiwgZGZvcm0uaXNEZWNpbWFsU2VwYXJhdG9yQWx3YXlzU2hvd24oKSk7CisgICAgICAgIGZpZWxkcy5wdXQoInBhcnNlQmlnRGVjaW1hbCIsIGRmb3JtLmlzUGFyc2VCaWdEZWNpbWFsKCkpOworICAgICAgICBmaWVsZHMucHV0KCJyb3VuZGluZ01vZGUiLCByb3VuZGluZ01vZGUpOworICAgICAgICBmaWVsZHMucHV0KCJzeW1ib2xzIiwgc3ltYm9scyk7CisgICAgICAgIGZpZWxkcy5wdXQoInVzZUV4cG9uZW50aWFsTm90YXRpb24iLCBmYWxzZSk7CisgICAgICAgIGZpZWxkcy5wdXQoIm1pbkV4cG9uZW50RGlnaXRzIiwgKGJ5dGUpIDApOworICAgICAgICBmaWVsZHMucHV0KCJtYXhpbXVtSW50ZWdlckRpZ2l0cyIsIGRmb3JtLmdldE1heGltdW1JbnRlZ2VyRGlnaXRzKCkpOworICAgICAgICBmaWVsZHMucHV0KCJtaW5pbXVtSW50ZWdlckRpZ2l0cyIsIGRmb3JtLmdldE1pbmltdW1JbnRlZ2VyRGlnaXRzKCkpOworICAgICAgICBmaWVsZHMucHV0KCJtYXhpbXVtRnJhY3Rpb25EaWdpdHMiLCBkZm9ybS5nZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoKSk7CisgICAgICAgIGZpZWxkcy5wdXQoIm1pbmltdW1GcmFjdGlvbkRpZ2l0cyIsIGRmb3JtLmdldE1pbmltdW1GcmFjdGlvbkRpZ2l0cygpKTsKKyAgICAgICAgZmllbGRzLnB1dCgic2VyaWFsVmVyc2lvbk9uU3RyZWFtIiwgNCk7CisgICAgICAgIHN0cmVhbS53cml0ZUZpZWxkcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHNlcmlhbGl6ZWQgZmllbGRzIGZvbGxvd2luZyBzZXJpYWxpemVkIGZvcm1zIHNwZWNpZmllZCBieSBKYXZhCisgICAgICogc3BlY2lmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBzdHJlYW0gdG8gcmVhZCBzZXJpYWxpemVkIGJ5dGVzCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHNvbWUgSS9PIGVycm9yIG9jY3VycworICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHNvbWUgY2xhc3Mgb2Ygc2VyaWFsaXplZCBvYmplY3RzIG9yIGZpZWxkcyBjYW5ub3QgYmUgZm91bmQKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkIGZpZWxkcyA9IHN0cmVhbS5yZWFkRmllbGRzKCk7CisgICAgICAgIHRoaXMuc3ltYm9scyA9IChEZWNpbWFsRm9ybWF0U3ltYm9scykgZmllbGRzLmdldCgic3ltYm9scyIsIG51bGwpOworCisgICAgICAgIGluaXROYXRpdmUoIiIpOworICAgICAgICBkZm9ybS5zZXRQb3NpdGl2ZVByZWZpeCgoU3RyaW5nKSBmaWVsZHMuZ2V0KCJwb3NpdGl2ZVByZWZpeCIsICIiKSk7CisgICAgICAgIGRmb3JtLnNldFBvc2l0aXZlU3VmZml4KChTdHJpbmcpIGZpZWxkcy5nZXQoInBvc2l0aXZlU3VmZml4IiwgIiIpKTsKKyAgICAgICAgZGZvcm0uc2V0TmVnYXRpdmVQcmVmaXgoKFN0cmluZykgZmllbGRzLmdldCgibmVnYXRpdmVQcmVmaXgiLCAiLSIpKTsKKyAgICAgICAgZGZvcm0uc2V0TmVnYXRpdmVTdWZmaXgoKFN0cmluZykgZmllbGRzLmdldCgibmVnYXRpdmVTdWZmaXgiLCAiIikpOworICAgICAgICBkZm9ybS5zZXRNdWx0aXBsaWVyKGZpZWxkcy5nZXQoIm11bHRpcGxpZXIiLCAxKSk7CisgICAgICAgIGRmb3JtLnNldEdyb3VwaW5nU2l6ZShmaWVsZHMuZ2V0KCJncm91cGluZ1NpemUiLCAoYnl0ZSkgMykpOworICAgICAgICBkZm9ybS5zZXRHcm91cGluZ1VzZWQoZmllbGRzLmdldCgiZ3JvdXBpbmdVc2VkIiwgdHJ1ZSkpOworICAgICAgICBkZm9ybS5zZXREZWNpbWFsU2VwYXJhdG9yQWx3YXlzU2hvd24oZmllbGRzLmdldCgiZGVjaW1hbFNlcGFyYXRvckFsd2F5c1Nob3duIiwgZmFsc2UpKTsKKworICAgICAgICBzZXRSb3VuZGluZ01vZGUoKFJvdW5kaW5nTW9kZSkgZmllbGRzLmdldCgicm91bmRpbmdNb2RlIiwgUm91bmRpbmdNb2RlLkhBTEZfRVZFTikpOworCisgICAgICAgIGZpbmFsIGludCBtYXhpbXVtSW50ZWdlckRpZ2l0cyA9IGZpZWxkcy5nZXQoIm1heGltdW1JbnRlZ2VyRGlnaXRzIiwgMzA5KTsKKyAgICAgICAgZmluYWwgaW50IG1pbmltdW1JbnRlZ2VyRGlnaXRzID0gZmllbGRzLmdldCgibWluaW11bUludGVnZXJEaWdpdHMiLCAzMDkpOworICAgICAgICBmaW5hbCBpbnQgbWF4aW11bUZyYWN0aW9uRGlnaXRzID0gZmllbGRzLmdldCgibWF4aW11bUZyYWN0aW9uRGlnaXRzIiwgMzQwKTsKKyAgICAgICAgZmluYWwgaW50IG1pbmltdW1GcmFjdGlvbkRpZ2l0cyA9IGZpZWxkcy5nZXQoIm1pbmltdW1GcmFjdGlvbkRpZ2l0cyIsIDM0MCk7CisgICAgICAgIC8vIFRlbGwgSUNVIHdoYXQgd2Ugd2FudCwgdGhlbiBhc2sgaXQgd2hhdCB3ZSBjYW4gaGF2ZSwgYW5kIHRoZW4KKyAgICAgICAgLy8gc2V0IHRoYXQgaW4gb3VyIEphdmEgb2JqZWN0LiBUaGlzIGlzbid0IFJJLWNvbXBhdGlibGUsIGJ1dCB0aGVuIHZlcnkgbGl0dGxlIG9mIG91cgorICAgICAgICAvLyBiZWhhdmlvciBpbiB0aGlzIGFyZWEgaXMsIGFuZCBpdCdzIG5vdCBvYnZpb3VzIGhvdyB3ZSBjYW4gc2Vjb25kLWd1ZXNzIElDVSAob3IgdGVsbAorICAgICAgICAvLyBpdCB0byBqdXN0IGRvIGV4YWN0bHkgd2hhdCB3ZSBhc2spLiBXZSBvbmx5IG5lZWQgdG8gZG8gdGhpcyB3aXRoIG1heGltdW1JbnRlZ2VyRGlnaXRzCisgICAgICAgIC8vIGJlY2F1c2UgSUNVIGRvZXNuJ3Qgc2VlbSB0byBoYXZlIGl0cyBvd24gaWRlYXMgYWJvdXQgdGhlIG90aGVyIG9wdGlvbnMuCisgICAgICAgIGRmb3JtLnNldE1heGltdW1JbnRlZ2VyRGlnaXRzKG1heGltdW1JbnRlZ2VyRGlnaXRzKTsKKyAgICAgICAgc3VwZXIuc2V0TWF4aW11bUludGVnZXJEaWdpdHMoZGZvcm0uZ2V0TWF4aW11bUludGVnZXJEaWdpdHMoKSk7CisKKyAgICAgICAgc2V0TWluaW11bUludGVnZXJEaWdpdHMobWluaW11bUludGVnZXJEaWdpdHMpOworICAgICAgICBzZXRNaW5pbXVtRnJhY3Rpb25EaWdpdHMobWluaW11bUZyYWN0aW9uRGlnaXRzKTsKKyAgICAgICAgc2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKG1heGltdW1GcmFjdGlvbkRpZ2l0cyk7CisgICAgICAgIHNldFBhcnNlQmlnRGVjaW1hbChmaWVsZHMuZ2V0KCJwYXJzZUJpZ0RlY2ltYWwiLCBmYWxzZSkpOworCisgICAgICAgIGlmIChmaWVsZHMuZ2V0KCJzZXJpYWxWZXJzaW9uT25TdHJlYW0iLCAwKSA8IDMpIHsKKyAgICAgICAgICAgIHNldE1heGltdW1JbnRlZ2VyRGlnaXRzKHN1cGVyLmdldE1heGltdW1JbnRlZ2VyRGlnaXRzKCkpOworICAgICAgICAgICAgc2V0TWluaW11bUludGVnZXJEaWdpdHMoc3VwZXIuZ2V0TWluaW11bUludGVnZXJEaWdpdHMoKSk7CisgICAgICAgICAgICBzZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoc3VwZXIuZ2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKCkpOworICAgICAgICAgICAgc2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKHN1cGVyLmdldE1pbmltdW1GcmFjdGlvbkRpZ2l0cygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBSb3VuZGluZ01vZGV9IHVzZWQgYnkgdGhpcyB7QGNvZGUgTnVtYmVyRm9ybWF0fS4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIFJvdW5kaW5nTW9kZSBnZXRSb3VuZGluZ01vZGUoKSB7CisgICAgICAgIHJldHVybiByb3VuZGluZ01vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUge0Bjb2RlIFJvdW5kaW5nTW9kZX0gdXNlZCBieSB0aGlzIHtAY29kZSBOdW1iZXJGb3JtYXR9LgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSb3VuZGluZ01vZGUoUm91bmRpbmdNb2RlIHJvdW5kaW5nTW9kZSkgeworICAgICAgICBpZiAocm91bmRpbmdNb2RlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMucm91bmRpbmdNb2RlID0gcm91bmRpbmdNb2RlOworICAgICAgICBpZiAocm91bmRpbmdNb2RlICE9IFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSkgeyAvLyBJQ1U0QyBkb2Vzbid0IHN1cHBvcnQgVU5ORUNFU1NBUlkuCisgICAgICAgICAgICBkb3VibGUgcm91bmRpbmdJbmNyZW1lbnQgPSAxLjAgLyBNYXRoLnBvdygxMCwgTWF0aC5tYXgoMCwgZ2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKCkpKTsKKyAgICAgICAgICAgIGRmb3JtLnNldFJvdW5kaW5nTW9kZShyb3VuZGluZ01vZGUsIHJvdW5kaW5nSW5jcmVtZW50KTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvRGVjaW1hbEZvcm1hdFN5bWJvbHMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvRGVjaW1hbEZvcm1hdFN5bWJvbHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZDJiY2MxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9EZWNpbWFsRm9ybWF0U3ltYm9scy5qYXZhCkBAIC0wLDAgKzEsNjQ3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1GaWVsZDsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQ3VycmVuY3k7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBsaWJjb3JlLmljdS5JQ1U7CitpbXBvcnQgbGliY29yZS5pY3UuTG9jYWxlRGF0YTsKKworLyoqCisgKiBFbmNhcHN1bGF0ZXMgdGhlIHNldCBvZiBzeW1ib2xzIChzdWNoIGFzIHRoZSBkZWNpbWFsIHNlcGFyYXRvciwgdGhlIGdyb3VwaW5nCisgKiBzZXBhcmF0b3IsIGFuZCBzbyBvbikgbmVlZGVkIGJ5IHtAY29kZSBEZWNpbWFsRm9ybWF0fSB0byBmb3JtYXQgbnVtYmVycy4KKyAqIHtAY29kZSBEZWNpbWFsRm9ybWF0fSBpbnRlcm5hbGx5IGNyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YKKyAqIHtAY29kZSBEZWNpbWFsRm9ybWF0U3ltYm9sc30gZnJvbSBpdHMgbG9jYWxlIGRhdGEuIElmIHlvdSBuZWVkIHRvIGNoYW5nZSBhbnkKKyAqIG9mIHRoZXNlIHN5bWJvbHMsIHlvdSBjYW4gZ2V0IHRoZSB7QGNvZGUgRGVjaW1hbEZvcm1hdFN5bWJvbHN9IG9iamVjdCBmcm9tCisgKiB5b3VyIHtAY29kZSBEZWNpbWFsRm9ybWF0fSBhbmQgbW9kaWZ5IGl0LgorICoKKyAqIEBzZWUgamF2YS51dGlsLkxvY2FsZQorICogQHNlZSBEZWNpbWFsRm9ybWF0CisgKi8KK3B1YmxpYyBjbGFzcyBEZWNpbWFsRm9ybWF0U3ltYm9scyBpbXBsZW1lbnRzIENsb25lYWJsZSwgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDU3NzI3OTYyNDMzOTczNTAzMDBMOworCisgICAgcHJpdmF0ZSBjaGFyIHplcm9EaWdpdDsKKyAgICBwcml2YXRlIGNoYXIgZGlnaXQ7CisgICAgcHJpdmF0ZSBjaGFyIGRlY2ltYWxTZXBhcmF0b3I7CisgICAgcHJpdmF0ZSBjaGFyIGdyb3VwaW5nU2VwYXJhdG9yOworICAgIHByaXZhdGUgY2hhciBwYXR0ZXJuU2VwYXJhdG9yOworICAgIHByaXZhdGUgY2hhciBwZXJjZW50OworICAgIHByaXZhdGUgY2hhciBwZXJNaWxsOworICAgIHByaXZhdGUgY2hhciBtb25ldGFyeVNlcGFyYXRvcjsKKyAgICBwcml2YXRlIGNoYXIgbWludXNTaWduOworICAgIHByaXZhdGUgU3RyaW5nIGluZmluaXR5LCBOYU4sIGN1cnJlbmN5U3ltYm9sLCBpbnRsQ3VycmVuY3lTeW1ib2w7CisKKyAgICBwcml2YXRlIHRyYW5zaWVudCBDdXJyZW5jeSBjdXJyZW5jeTsKKyAgICBwcml2YXRlIHRyYW5zaWVudCBMb2NhbGUgbG9jYWxlOworICAgIHByaXZhdGUgdHJhbnNpZW50IFN0cmluZyBleHBvbmVudFNlcGFyYXRvcjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIERlY2ltYWxGb3JtYXRTeW1ib2xzfSBjb250YWluaW5nIHRoZSBzeW1ib2xzIGZvcgorICAgICAqIHRoZSB1c2VyJ3MgZGVmYXVsdCBsb2NhbGUuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqIEJlc3QgcHJhY3RpY2UgaXMgdG8gY3JlYXRlIGEge0Bjb2RlIERlY2ltYWxGb3JtYXR9CisgICAgICogYW5kIHRoZW4gdG8gZ2V0IHRoZSB7QGNvZGUgRGVjaW1hbEZvcm1hdFN5bWJvbHN9IGZyb20gdGhhdCBvYmplY3QgYnkKKyAgICAgKiBjYWxsaW5nIHtAbGluayBEZWNpbWFsRm9ybWF0I2dldERlY2ltYWxGb3JtYXRTeW1ib2xzKCl9LgorICAgICAqLworICAgIHB1YmxpYyBEZWNpbWFsRm9ybWF0U3ltYm9scygpIHsKKyAgICAgICAgdGhpcyhMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IERlY2ltYWxGb3JtYXRTeW1ib2xzIGNvbnRhaW5pbmcgdGhlIHN5bWJvbHMgZm9yIHRoZQorICAgICAqIHNwZWNpZmllZCBMb2NhbGUuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqIEJlc3QgcHJhY3RpY2UgaXMgdG8gY3JlYXRlIGEge0Bjb2RlIERlY2ltYWxGb3JtYXR9CisgICAgICogYW5kIHRoZW4gdG8gZ2V0IHRoZSB7QGNvZGUgRGVjaW1hbEZvcm1hdFN5bWJvbHN9IGZyb20gdGhhdCBvYmplY3QgYnkKKyAgICAgKiBjYWxsaW5nIHtAbGluayBEZWNpbWFsRm9ybWF0I2dldERlY2ltYWxGb3JtYXRTeW1ib2xzKCl9LgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2FsZQorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGVjaW1hbEZvcm1hdFN5bWJvbHMoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBMb2NhbGVEYXRhIGxvY2FsZURhdGEgPSBMb2NhbGVEYXRhLmdldChsb2NhbGUpOworICAgICAgICB0aGlzLnplcm9EaWdpdCA9IGxvY2FsZURhdGEuemVyb0RpZ2l0OworICAgICAgICB0aGlzLmRpZ2l0ID0gJyMnOworICAgICAgICB0aGlzLmRlY2ltYWxTZXBhcmF0b3IgPSBsb2NhbGVEYXRhLmRlY2ltYWxTZXBhcmF0b3I7CisgICAgICAgIHRoaXMuZ3JvdXBpbmdTZXBhcmF0b3IgPSBsb2NhbGVEYXRhLmdyb3VwaW5nU2VwYXJhdG9yOworICAgICAgICB0aGlzLnBhdHRlcm5TZXBhcmF0b3IgPSBsb2NhbGVEYXRhLnBhdHRlcm5TZXBhcmF0b3I7CisgICAgICAgIHRoaXMucGVyY2VudCA9IGxvY2FsZURhdGEucGVyY2VudDsKKyAgICAgICAgdGhpcy5wZXJNaWxsID0gbG9jYWxlRGF0YS5wZXJNaWxsOworICAgICAgICB0aGlzLm1vbmV0YXJ5U2VwYXJhdG9yID0gbG9jYWxlRGF0YS5tb25ldGFyeVNlcGFyYXRvcjsKKyAgICAgICAgdGhpcy5taW51c1NpZ24gPSBsb2NhbGVEYXRhLm1pbnVzU2lnbjsKKyAgICAgICAgdGhpcy5pbmZpbml0eSA9IGxvY2FsZURhdGEuaW5maW5pdHk7CisgICAgICAgIHRoaXMuTmFOID0gbG9jYWxlRGF0YS5OYU47CisgICAgICAgIHRoaXMuZXhwb25lbnRTZXBhcmF0b3IgPSBsb2NhbGVEYXRhLmV4cG9uZW50U2VwYXJhdG9yOworICAgICAgICB0aGlzLmxvY2FsZSA9IGxvY2FsZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGN1cnJlbmN5ID0gQ3VycmVuY3kuZ2V0SW5zdGFuY2UobG9jYWxlKTsKKyAgICAgICAgICAgIGN1cnJlbmN5U3ltYm9sID0gY3VycmVuY3kuZ2V0U3ltYm9sKGxvY2FsZSk7CisgICAgICAgICAgICBpbnRsQ3VycmVuY3lTeW1ib2wgPSBjdXJyZW5jeS5nZXRDdXJyZW5jeUNvZGUoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGN1cnJlbmN5ID0gQ3VycmVuY3kuZ2V0SW5zdGFuY2UoIlhYWCIpOworICAgICAgICAgICAgY3VycmVuY3lTeW1ib2wgPSBsb2NhbGVEYXRhLmN1cnJlbmN5U3ltYm9sOworICAgICAgICAgICAgaW50bEN1cnJlbmN5U3ltYm9sID0gbG9jYWxlRGF0YS5pbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2w7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBEZWNpbWFsRm9ybWF0U3ltYm9sc30gaW5zdGFuY2UgZm9yIHRoZSB1c2VyJ3MgZGVmYXVsdCBsb2NhbGUuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgRGVjaW1hbEZvcm1hdFN5bWJvbHN9CisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgRGVjaW1hbEZvcm1hdFN5bWJvbHMgZ2V0SW5zdGFuY2UoKSB7CisgICAgICAgIHJldHVybiBnZXRJbnN0YW5jZShMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBEZWNpbWFsRm9ybWF0U3ltYm9sc30gZm9yIHRoZSBnaXZlbiBsb2NhbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYWxlIHRoZSBsb2NhbGUKKyAgICAgKiBAcmV0dXJuIGFuIGluc3RhbmNlIG9mIHtAY29kZSBEZWNpbWFsRm9ybWF0U3ltYm9sc30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBsb2NhbGUgPT0gbnVsbH0KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBEZWNpbWFsRm9ybWF0U3ltYm9scyBnZXRJbnN0YW5jZShMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIGlmIChsb2NhbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBEZWNpbWFsRm9ybWF0U3ltYm9scyhsb2NhbGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgbG9jYWxlcyBmb3Igd2hpY2ggY3VzdG9tIHtAY29kZSBEZWNpbWFsRm9ybWF0U3ltYm9sc30gaW5zdGFuY2VzCisgICAgICogYXJlIGF2YWlsYWJsZS4KKyAgICAgKiA8cD5Ob3RlIHRoYXQgQW5kcm9pZCBkb2VzIG5vdCBzdXBwb3J0IHVzZXItc3VwcGxpZWQgbG9jYWxlIHNlcnZpY2UgcHJvdmlkZXJzLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIExvY2FsZVtdIGdldEF2YWlsYWJsZUxvY2FsZXMoKSB7CisgICAgICAgIHJldHVybiBJQ1UuZ2V0QXZhaWxhYmxlRGVjaW1hbEZvcm1hdFN5bWJvbHNMb2NhbGVzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIG9iamVjdCB0byB0aGlzIHtAY29kZSBEZWNpbWFsRm9ybWF0U3ltYm9sc30gYW5kCisgICAgICogaW5kaWNhdGVzIGlmIHRoZXkgYXJlIGVxdWFsLiBJbiBvcmRlciB0byBiZSBlcXVhbCwge0Bjb2RlIG9iamVjdH0gbXVzdCBiZQorICAgICAqIGFuIGluc3RhbmNlIG9mIHtAY29kZSBEZWNpbWFsRm9ybWF0U3ltYm9sc30gYW5kIGNvbnRhaW4gdGhlIHNhbWUgc3ltYm9scy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB3aXRoIHRoaXMgb2JqZWN0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBEZWNpbWFsRm9ybWF0U3ltYm9sc307IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgI2hhc2hDb2RlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgaWYgKHRoaXMgPT0gb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBEZWNpbWFsRm9ybWF0U3ltYm9scykpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBEZWNpbWFsRm9ybWF0U3ltYm9scyBvYmogPSAoRGVjaW1hbEZvcm1hdFN5bWJvbHMpIG9iamVjdDsKKyAgICAgICAgcmV0dXJuIGN1cnJlbmN5LmVxdWFscyhvYmouY3VycmVuY3kpICYmCisgICAgICAgICAgICAgICAgY3VycmVuY3lTeW1ib2wuZXF1YWxzKG9iai5jdXJyZW5jeVN5bWJvbCkgJiYKKyAgICAgICAgICAgICAgICBkZWNpbWFsU2VwYXJhdG9yID09IG9iai5kZWNpbWFsU2VwYXJhdG9yICYmCisgICAgICAgICAgICAgICAgZGlnaXQgPT0gb2JqLmRpZ2l0ICYmCisgICAgICAgICAgICAgICAgZXhwb25lbnRTZXBhcmF0b3IuZXF1YWxzKG9iai5leHBvbmVudFNlcGFyYXRvcikgJiYKKyAgICAgICAgICAgICAgICBncm91cGluZ1NlcGFyYXRvciA9PSBvYmouZ3JvdXBpbmdTZXBhcmF0b3IgJiYKKyAgICAgICAgICAgICAgICBpbmZpbml0eS5lcXVhbHMob2JqLmluZmluaXR5KSAmJgorICAgICAgICAgICAgICAgIGludGxDdXJyZW5jeVN5bWJvbC5lcXVhbHMob2JqLmludGxDdXJyZW5jeVN5bWJvbCkgJiYKKyAgICAgICAgICAgICAgICBtaW51c1NpZ24gPT0gb2JqLm1pbnVzU2lnbiAmJgorICAgICAgICAgICAgICAgIG1vbmV0YXJ5U2VwYXJhdG9yID09IG9iai5tb25ldGFyeVNlcGFyYXRvciAmJgorICAgICAgICAgICAgICAgIE5hTi5lcXVhbHMob2JqLk5hTikgJiYKKyAgICAgICAgICAgICAgICBwYXR0ZXJuU2VwYXJhdG9yID09IG9iai5wYXR0ZXJuU2VwYXJhdG9yICYmCisgICAgICAgICAgICAgICAgcGVyTWlsbCA9PSBvYmoucGVyTWlsbCAmJgorICAgICAgICAgICAgICAgIHBlcmNlbnQgPT0gb2JqLnBlcmNlbnQgJiYKKyAgICAgICAgICAgICAgICB6ZXJvRGlnaXQgPT0gb2JqLnplcm9EaWdpdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKworICAgICAgICAgICAgICAgICJbY3VycmVuY3k9IiArIGN1cnJlbmN5ICsKKyAgICAgICAgICAgICAgICAiLGN1cnJlbmN5U3ltYm9sPSIgKyBjdXJyZW5jeVN5bWJvbCArCisgICAgICAgICAgICAgICAgIixkZWNpbWFsU2VwYXJhdG9yPSIgKyBkZWNpbWFsU2VwYXJhdG9yICsKKyAgICAgICAgICAgICAgICAiLGRpZ2l0PSIgKyBkaWdpdCArCisgICAgICAgICAgICAgICAgIixleHBvbmVudFNlcGFyYXRvcj0iICsgZXhwb25lbnRTZXBhcmF0b3IgKworICAgICAgICAgICAgICAgICIsZ3JvdXBpbmdTZXBhcmF0b3I9IiArIGdyb3VwaW5nU2VwYXJhdG9yICsKKyAgICAgICAgICAgICAgICAiLGluZmluaXR5PSIgKyBpbmZpbml0eSArCisgICAgICAgICAgICAgICAgIixpbnRsQ3VycmVuY3lTeW1ib2w9IiArIGludGxDdXJyZW5jeVN5bWJvbCArCisgICAgICAgICAgICAgICAgIixtaW51c1NpZ249IiArIG1pbnVzU2lnbiArCisgICAgICAgICAgICAgICAgIixtb25ldGFyeVNlcGFyYXRvcj0iICsgbW9uZXRhcnlTZXBhcmF0b3IgKworICAgICAgICAgICAgICAgICIsTmFOPSIgKyBOYU4gKworICAgICAgICAgICAgICAgICIscGF0dGVyblNlcGFyYXRvcj0iICsgcGF0dGVyblNlcGFyYXRvciArCisgICAgICAgICAgICAgICAgIixwZXJNaWxsPSIgKyBwZXJNaWxsICsKKyAgICAgICAgICAgICAgICAiLHBlcmNlbnQ9IiArIHBlcmNlbnQgKworICAgICAgICAgICAgICAgICIsemVyb0RpZ2l0PSIgKyB6ZXJvRGlnaXQgKworICAgICAgICAgICAgICAgICJdIjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW5jeS4KKyAgICAgKiA8cD4KKyAgICAgKiB7QGNvZGUgbnVsbH0gaXMgcmV0dXJuZWQgaWYge0Bjb2RlIHNldEludGVybmF0aW9uYWxDdXJyZW5jeVN5bWJvbCgpfSBoYXMKKyAgICAgKiBiZWVuIHByZXZpb3VzbHkgY2FsbGVkIHdpdGggYSB2YWx1ZSB0aGF0IGlzIG5vdCBhIHZhbGlkIElTTyA0MjE3IGN1cnJlbmN5CisgICAgICogY29kZS4KKyAgICAgKiA8cD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbmN5IHRoYXQgd2FzIHNldCBpbiB0aGUgY29uc3RydWN0b3Igb3IgYnkgY2FsbGluZworICAgICAqICAgICAgICAge0Bjb2RlIHNldEN1cnJlbmN5KCl9IG9yIHtAY29kZSBzZXRJbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2woKX0sCisgICAgICogICAgICAgICBvciB7QGNvZGUgbnVsbH0gaWYgYW4gaW52YWxpZCBjdXJyZW5jeSB3YXMgc2V0LgorICAgICAqIEBzZWUgI3NldEN1cnJlbmN5KEN1cnJlbmN5KQorICAgICAqIEBzZWUgI3NldEludGVybmF0aW9uYWxDdXJyZW5jeVN5bWJvbChTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIEN1cnJlbmN5IGdldEN1cnJlbmN5KCkgeworICAgICAgICByZXR1cm4gY3VycmVuY3k7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW50ZXJuYXRpb25hbCBjdXJyZW5jeSBzeW1ib2wuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbnRlcm5hdGlvbmFsIGN1cnJlbmN5IHN5bWJvbCBhcyBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRJbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2woKSB7CisgICAgICAgIHJldHVybiBpbnRsQ3VycmVuY3lTeW1ib2w7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3VycmVuY3kgc3ltYm9sLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY3VycmVuY3kgc3ltYm9sIGFzIHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEN1cnJlbmN5U3ltYm9sKCkgeworICAgICAgICByZXR1cm4gY3VycmVuY3lTeW1ib2w7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2hhcmFjdGVyIHdoaWNoIHJlcHJlc2VudHMgdGhlIGRlY2ltYWwgcG9pbnQgaW4gYSBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkZWNpbWFsIHNlcGFyYXRvciBjaGFyYWN0ZXIuCisgICAgICovCisgICAgcHVibGljIGNoYXIgZ2V0RGVjaW1hbFNlcGFyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIGRlY2ltYWxTZXBhcmF0b3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2hhcmFjdGVyIHdoaWNoIHJlcHJlc2VudHMgYSBzaW5nbGUgZGlnaXQgaW4gYSBmb3JtYXQKKyAgICAgKiBwYXR0ZXJuLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZGlnaXQgcGF0dGVybiBjaGFyYWN0ZXIuCisgICAgICovCisgICAgcHVibGljIGNoYXIgZ2V0RGlnaXQoKSB7CisgICAgICAgIHJldHVybiBkaWdpdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjaGFyYWN0ZXIgdXNlZCBhcyB0aGUgdGhvdXNhbmRzIHNlcGFyYXRvciBpbiBhIG51bWJlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHRob3VzYW5kcyBzZXBhcmF0b3IgY2hhcmFjdGVyLgorICAgICAqLworICAgIHB1YmxpYyBjaGFyIGdldEdyb3VwaW5nU2VwYXJhdG9yKCkgeworICAgICAgICByZXR1cm4gZ3JvdXBpbmdTZXBhcmF0b3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyaW5nIHdoaWNoIHJlcHJlc2VudHMgaW5maW5pdHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbmZpbml0eSBzeW1ib2wgYXMgYSBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRJbmZpbml0eSgpIHsKKyAgICAgICAgcmV0dXJuIGluZmluaXR5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1pbnVzIHNpZ24gY2hhcmFjdGVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWludXMgc2lnbiBhcyBhIGNoYXJhY3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhciBnZXRNaW51c1NpZ24oKSB7CisgICAgICAgIHJldHVybiBtaW51c1NpZ247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2hhcmFjdGVyIHdoaWNoIHJlcHJlc2VudHMgdGhlIGRlY2ltYWwgcG9pbnQgaW4gYSBtb25ldGFyeQorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbW9uZXRhcnkgZGVjaW1hbCBwb2ludCBhcyBhIGNoYXJhY3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhciBnZXRNb25ldGFyeURlY2ltYWxTZXBhcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBtb25ldGFyeVNlcGFyYXRvcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgd2hpY2ggcmVwcmVzZW50cyBOYU4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzeW1ib2wgTmFOIGFzIGEgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFOKCkgeworICAgICAgICByZXR1cm4gTmFOOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNoYXJhY3RlciB3aGljaCBzZXBhcmF0ZXMgdGhlIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBwYXR0ZXJucworICAgICAqIGluIGEgZm9ybWF0IHBhdHRlcm4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwYXR0ZXJuIHNlcGFyYXRvciBjaGFyYWN0ZXIuCisgICAgICovCisgICAgcHVibGljIGNoYXIgZ2V0UGF0dGVyblNlcGFyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIHBhdHRlcm5TZXBhcmF0b3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGVyY2VudCBjaGFyYWN0ZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwZXJjZW50IGNoYXJhY3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhciBnZXRQZXJjZW50KCkgeworICAgICAgICByZXR1cm4gcGVyY2VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwZXIgbWlsbCBzaWduIGNoYXJhY3Rlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHBlciBtaWxsIHNpZ24gY2hhcmFjdGVyLgorICAgICAqLworICAgIHB1YmxpYyBjaGFyIGdldFBlck1pbGwoKSB7CisgICAgICAgIHJldHVybiBwZXJNaWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNoYXJhY3RlciB3aGljaCByZXByZXNlbnRzIHplcm8uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB6ZXJvIGNoYXJhY3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhciBnZXRaZXJvRGlnaXQoKSB7CisgICAgICAgIHJldHVybiB6ZXJvRGlnaXQ7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgdXNlZCB0byBzZXBhcmF0ZSBtYW50aXNzYSBhbmQgZXhwb25lbnQuIFR5cGljYWxseSAiRSIsIGFzIGluICIxLjJFMyIuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RXhwb25lbnRTZXBhcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBleHBvbmVudFNlcGFyYXRvcjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBpbnQgcmVzdWx0ID0gMTc7CisgICAgICAgIHJlc3VsdCA9IDMxKnJlc3VsdCArIHplcm9EaWdpdDsKKyAgICAgICAgcmVzdWx0ID0gMzEqcmVzdWx0ICsgZGlnaXQ7CisgICAgICAgIHJlc3VsdCA9IDMxKnJlc3VsdCArIGRlY2ltYWxTZXBhcmF0b3I7CisgICAgICAgIHJlc3VsdCA9IDMxKnJlc3VsdCArIGdyb3VwaW5nU2VwYXJhdG9yOworICAgICAgICByZXN1bHQgPSAzMSpyZXN1bHQgKyBwYXR0ZXJuU2VwYXJhdG9yOworICAgICAgICByZXN1bHQgPSAzMSpyZXN1bHQgKyBwZXJjZW50OworICAgICAgICByZXN1bHQgPSAzMSpyZXN1bHQgKyBwZXJNaWxsOworICAgICAgICByZXN1bHQgPSAzMSpyZXN1bHQgKyBtb25ldGFyeVNlcGFyYXRvcjsKKyAgICAgICAgcmVzdWx0ID0gMzEqcmVzdWx0ICsgbWludXNTaWduOworICAgICAgICByZXN1bHQgPSAzMSpyZXN1bHQgKyBleHBvbmVudFNlcGFyYXRvci5oYXNoQ29kZSgpOworICAgICAgICByZXN1bHQgPSAzMSpyZXN1bHQgKyBpbmZpbml0eS5oYXNoQ29kZSgpOworICAgICAgICByZXN1bHQgPSAzMSpyZXN1bHQgKyBOYU4uaGFzaENvZGUoKTsKKyAgICAgICAgcmVzdWx0ID0gMzEqcmVzdWx0ICsgY3VycmVuY3lTeW1ib2wuaGFzaENvZGUoKTsKKyAgICAgICAgcmVzdWx0ID0gMzEqcmVzdWx0ICsgaW50bEN1cnJlbmN5U3ltYm9sLmhhc2hDb2RlKCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY3VycmVuY3kuCisgICAgICogPHA+CisgICAgICogVGhlIGludGVybmF0aW9uYWwgY3VycmVuY3kgc3ltYm9sIGFuZCB0aGUgY3VycmVuY3kgc3ltYm9sIGFyZSB1cGRhdGVkLAorICAgICAqIGJ1dCB0aGUgbWluIGFuZCBtYXggbnVtYmVyIG9mIGZyYWN0aW9uIGRpZ2l0cyBzdGF5cyB0aGUgc2FtZS4KKyAgICAgKiA8cD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjdXJyZW5jeQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBjdXJyZW5jeS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGN1cnJlbmN5fSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q3VycmVuY3koQ3VycmVuY3kgY3VycmVuY3kpIHsKKyAgICAgICAgaWYgKGN1cnJlbmN5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChjdXJyZW5jeSA9PSB0aGlzLmN1cnJlbmN5KSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5jdXJyZW5jeSA9IGN1cnJlbmN5OworICAgICAgICBpbnRsQ3VycmVuY3lTeW1ib2wgPSBjdXJyZW5jeS5nZXRDdXJyZW5jeUNvZGUoKTsKKyAgICAgICAgY3VycmVuY3lTeW1ib2wgPSBjdXJyZW5jeS5nZXRTeW1ib2wobG9jYWxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBpbnRlcm5hdGlvbmFsIGN1cnJlbmN5IHN5bWJvbC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgY3VycmVuY3kgYW5kIGN1cnJlbmN5IHN5bWJvbCBhcmUgYWxzbyB1cGRhdGVkIGlmIHtAY29kZSB2YWx1ZX0gaXMgYQorICAgICAqIHZhbGlkIElTTzQyMTcgY3VycmVuY3kgY29kZS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbWluIGFuZCBtYXggbnVtYmVyIG9mIGZyYWN0aW9uIGRpZ2l0cyBzdGF5IHRoZSBzYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgY3VycmVuY3kgY29kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRJbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2woU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICBjdXJyZW5jeSA9IG51bGw7CisgICAgICAgICAgICBpbnRsQ3VycmVuY3lTeW1ib2wgPSBudWxsOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHZhbHVlLmVxdWFscyhpbnRsQ3VycmVuY3lTeW1ib2wpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY3VycmVuY3kgPSBDdXJyZW5jeS5nZXRJbnN0YW5jZSh2YWx1ZSk7CisgICAgICAgICAgICBjdXJyZW5jeVN5bWJvbCA9IGN1cnJlbmN5LmdldFN5bWJvbChsb2NhbGUpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgY3VycmVuY3kgPSBudWxsOworICAgICAgICB9CisgICAgICAgIGludGxDdXJyZW5jeVN5bWJvbCA9IHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGN1cnJlbmN5IHN5bWJvbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGN1cnJlbmN5IHN5bWJvbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDdXJyZW5jeVN5bWJvbChTdHJpbmcgdmFsdWUpIHsKKyAgICAgICAgdGhpcy5jdXJyZW5jeVN5bWJvbCA9IHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNoYXJhY3RlciB3aGljaCByZXByZXNlbnRzIHRoZSBkZWNpbWFsIHBvaW50IGluIGEgbnVtYmVyLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgZGVjaW1hbCBzZXBhcmF0b3IgY2hhcmFjdGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERlY2ltYWxTZXBhcmF0b3IoY2hhciB2YWx1ZSkgeworICAgICAgICB0aGlzLmRlY2ltYWxTZXBhcmF0b3IgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjaGFyYWN0ZXIgd2hpY2ggcmVwcmVzZW50cyBhIHNpbmdsZSBkaWdpdCBpbiBhIGZvcm1hdCBwYXR0ZXJuLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgZGlnaXQgY2hhcmFjdGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERpZ2l0KGNoYXIgdmFsdWUpIHsKKyAgICAgICAgdGhpcy5kaWdpdCA9IHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNoYXJhY3RlciB1c2VkIGFzIHRoZSB0aG91c2FuZHMgc2VwYXJhdG9yIGluIGEgbnVtYmVyLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgZ3JvdXBpbmcgc2VwYXJhdG9yIGNoYXJhY3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRHcm91cGluZ1NlcGFyYXRvcihjaGFyIHZhbHVlKSB7CisgICAgICAgIHRoaXMuZ3JvdXBpbmdTZXBhcmF0b3IgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzdHJpbmcgd2hpY2ggcmVwcmVzZW50cyBpbmZpbml0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyByZXByZXNlbnRpbmcgaW5maW5pdHkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SW5maW5pdHkoU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIHRoaXMuaW5maW5pdHkgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBtaW51cyBzaWduIGNoYXJhY3Rlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG1pbnVzIHNpZ24gY2hhcmFjdGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1pbnVzU2lnbihjaGFyIHZhbHVlKSB7CisgICAgICAgIHRoaXMubWludXNTaWduID0gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY2hhcmFjdGVyIHdoaWNoIHJlcHJlc2VudHMgdGhlIGRlY2ltYWwgcG9pbnQgaW4gYSBtb25ldGFyeQorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbW9uZXRhcnkgZGVjaW1hbCBzZXBhcmF0b3IgY2hhcmFjdGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1vbmV0YXJ5RGVjaW1hbFNlcGFyYXRvcihjaGFyIHZhbHVlKSB7CisgICAgICAgIHRoaXMubW9uZXRhcnlTZXBhcmF0b3IgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzdHJpbmcgd2hpY2ggcmVwcmVzZW50cyBOYU4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgcmVwcmVzZW50aW5nIE5hTi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROYU4oU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIHRoaXMuTmFOID0gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY2hhcmFjdGVyIHdoaWNoIHNlcGFyYXRlcyB0aGUgcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIHBhdHRlcm5zIGluCisgICAgICogYSBmb3JtYXQgcGF0dGVybi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHBhdHRlcm4gc2VwYXJhdG9yIGNoYXJhY3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQYXR0ZXJuU2VwYXJhdG9yKGNoYXIgdmFsdWUpIHsKKyAgICAgICAgdGhpcy5wYXR0ZXJuU2VwYXJhdG9yID0gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcGVyY2VudCBjaGFyYWN0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwZXJjZW50IGNoYXJhY3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQZXJjZW50KGNoYXIgdmFsdWUpIHsKKyAgICAgICAgdGhpcy5wZXJjZW50ID0gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcGVyIG1pbGwgc2lnbiBjaGFyYWN0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwZXIgbWlsbCBjaGFyYWN0ZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UGVyTWlsbChjaGFyIHZhbHVlKSB7CisgICAgICAgIHRoaXMucGVyTWlsbCA9IHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNoYXJhY3RlciB3aGljaCByZXByZXNlbnRzIHplcm8uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB6ZXJvIGRpZ2l0IGNoYXJhY3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRaZXJvRGlnaXQoY2hhciB2YWx1ZSkgeworICAgICAgICB0aGlzLnplcm9EaWdpdCA9IHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHN0cmluZyB1c2VkIHRvIHNlcGFyYXRlIG1hbnRpc3NhIGFuZCBleHBvbmVudC4gVHlwaWNhbGx5ICJFIiwgYXMgaW4gIjEuMkUzIi4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RXhwb25lbnRTZXBhcmF0b3IoU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmV4cG9uZW50U2VwYXJhdG9yID0gdmFsdWU7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0U3RyZWFtRmllbGRbXSBzZXJpYWxQZXJzaXN0ZW50RmllbGRzID0geworICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImN1cnJlbmN5U3ltYm9sIiwgU3RyaW5nLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJkZWNpbWFsU2VwYXJhdG9yIiwgY2hhci5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiZGlnaXQiLCBjaGFyLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJleHBvbmVudGlhbCIsIGNoYXIuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImV4cG9uZW50aWFsU2VwYXJhdG9yIiwgU3RyaW5nLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJncm91cGluZ1NlcGFyYXRvciIsIGNoYXIuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImluZmluaXR5IiwgU3RyaW5nLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJpbnRsQ3VycmVuY3lTeW1ib2wiLCBTdHJpbmcuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoIm1pbnVzU2lnbiIsIGNoYXIuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoIm1vbmV0YXJ5U2VwYXJhdG9yIiwgY2hhci5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiTmFOIiwgU3RyaW5nLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJwYXR0ZXJuU2VwYXJhdG9yIiwgY2hhci5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgicGVyY2VudCIsIGNoYXIuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInBlck1pbGwiLCBjaGFyLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJzZXJpYWxWZXJzaW9uT25TdHJlYW0iLCBpbnQuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInplcm9EaWdpdCIsIGNoYXIuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImxvY2FsZSIsIExvY2FsZS5jbGFzcyksCisgICAgfTsKKworICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGQgZmllbGRzID0gc3RyZWFtLnB1dEZpZWxkcygpOworICAgICAgICBmaWVsZHMucHV0KCJjdXJyZW5jeVN5bWJvbCIsIGN1cnJlbmN5U3ltYm9sKTsKKyAgICAgICAgZmllbGRzLnB1dCgiZGVjaW1hbFNlcGFyYXRvciIsIGdldERlY2ltYWxTZXBhcmF0b3IoKSk7CisgICAgICAgIGZpZWxkcy5wdXQoImRpZ2l0IiwgZ2V0RGlnaXQoKSk7CisgICAgICAgIGZpZWxkcy5wdXQoImV4cG9uZW50aWFsIiwgZXhwb25lbnRTZXBhcmF0b3IuY2hhckF0KDApKTsKKyAgICAgICAgZmllbGRzLnB1dCgiZXhwb25lbnRpYWxTZXBhcmF0b3IiLCBleHBvbmVudFNlcGFyYXRvcik7CisgICAgICAgIGZpZWxkcy5wdXQoImdyb3VwaW5nU2VwYXJhdG9yIiwgZ2V0R3JvdXBpbmdTZXBhcmF0b3IoKSk7CisgICAgICAgIGZpZWxkcy5wdXQoImluZmluaXR5IiwgaW5maW5pdHkpOworICAgICAgICBmaWVsZHMucHV0KCJpbnRsQ3VycmVuY3lTeW1ib2wiLCBpbnRsQ3VycmVuY3lTeW1ib2wpOworICAgICAgICBmaWVsZHMucHV0KCJtaW51c1NpZ24iLCBnZXRNaW51c1NpZ24oKSk7CisgICAgICAgIGZpZWxkcy5wdXQoIm1vbmV0YXJ5U2VwYXJhdG9yIiwgZ2V0TW9uZXRhcnlEZWNpbWFsU2VwYXJhdG9yKCkpOworICAgICAgICBmaWVsZHMucHV0KCJOYU4iLCBOYU4pOworICAgICAgICBmaWVsZHMucHV0KCJwYXR0ZXJuU2VwYXJhdG9yIiwgZ2V0UGF0dGVyblNlcGFyYXRvcigpKTsKKyAgICAgICAgZmllbGRzLnB1dCgicGVyY2VudCIsIGdldFBlcmNlbnQoKSk7CisgICAgICAgIGZpZWxkcy5wdXQoInBlck1pbGwiLCBnZXRQZXJNaWxsKCkpOworICAgICAgICBmaWVsZHMucHV0KCJzZXJpYWxWZXJzaW9uT25TdHJlYW0iLCAzKTsKKyAgICAgICAgZmllbGRzLnB1dCgiemVyb0RpZ2l0IiwgZ2V0WmVyb0RpZ2l0KCkpOworICAgICAgICBmaWVsZHMucHV0KCJsb2NhbGUiLCBsb2NhbGUpOworICAgICAgICBzdHJlYW0ud3JpdGVGaWVsZHMoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkIGZpZWxkcyA9IHN0cmVhbS5yZWFkRmllbGRzKCk7CisgICAgICAgIGZpbmFsIGludCBzZXJpYWxWZXJzaW9uT25TdHJlYW0gPSBmaWVsZHMuZ2V0KCJzZXJpYWxWZXJzaW9uT25TdHJlYW0iLCAwKTsKKyAgICAgICAgY3VycmVuY3lTeW1ib2wgPSAoU3RyaW5nKSBmaWVsZHMuZ2V0KCJjdXJyZW5jeVN5bWJvbCIsICIiKTsKKyAgICAgICAgc2V0RGVjaW1hbFNlcGFyYXRvcihmaWVsZHMuZ2V0KCJkZWNpbWFsU2VwYXJhdG9yIiwgJy4nKSk7CisgICAgICAgIHNldERpZ2l0KGZpZWxkcy5nZXQoImRpZ2l0IiwgJyMnKSk7CisgICAgICAgIHNldEdyb3VwaW5nU2VwYXJhdG9yKGZpZWxkcy5nZXQoImdyb3VwaW5nU2VwYXJhdG9yIiwgJywnKSk7CisgICAgICAgIGluZmluaXR5ID0gKFN0cmluZykgZmllbGRzLmdldCgiaW5maW5pdHkiLCAiIik7CisgICAgICAgIGludGxDdXJyZW5jeVN5bWJvbCA9IChTdHJpbmcpIGZpZWxkcy5nZXQoImludGxDdXJyZW5jeVN5bWJvbCIsICIiKTsKKyAgICAgICAgc2V0TWludXNTaWduKGZpZWxkcy5nZXQoIm1pbnVzU2lnbiIsICctJykpOworICAgICAgICBOYU4gPSAoU3RyaW5nKSBmaWVsZHMuZ2V0KCJOYU4iLCAiIik7CisgICAgICAgIHNldFBhdHRlcm5TZXBhcmF0b3IoZmllbGRzLmdldCgicGF0dGVyblNlcGFyYXRvciIsICc7JykpOworICAgICAgICBzZXRQZXJjZW50KGZpZWxkcy5nZXQoInBlcmNlbnQiLCAnJScpKTsKKyAgICAgICAgc2V0UGVyTWlsbChmaWVsZHMuZ2V0KCJwZXJNaWxsIiwgJ1x1MjAzMCcpKTsKKyAgICAgICAgc2V0WmVyb0RpZ2l0KGZpZWxkcy5nZXQoInplcm9EaWdpdCIsICcwJykpOworICAgICAgICBsb2NhbGUgPSAoTG9jYWxlKSBmaWVsZHMuZ2V0KCJsb2NhbGUiLCBudWxsKTsKKyAgICAgICAgaWYgKHNlcmlhbFZlcnNpb25PblN0cmVhbSA9PSAwKSB7CisgICAgICAgICAgICBzZXRNb25ldGFyeURlY2ltYWxTZXBhcmF0b3IoZ2V0RGVjaW1hbFNlcGFyYXRvcigpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHNldE1vbmV0YXJ5RGVjaW1hbFNlcGFyYXRvcihmaWVsZHMuZ2V0KCJtb25ldGFyeVNlcGFyYXRvciIsICcuJykpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHNlcmlhbFZlcnNpb25PblN0cmVhbSA9PSAwKSB7CisgICAgICAgICAgICAvLyBQcmlvciB0byBKYXZhIDEuMS42LCB0aGUgZXhwb25lbnQgc2VwYXJhdG9yIHdhc24ndCBjb25maWd1cmFibGUuCisgICAgICAgICAgICBleHBvbmVudFNlcGFyYXRvciA9ICJFIjsKKyAgICAgICAgfSBlbHNlIGlmIChzZXJpYWxWZXJzaW9uT25TdHJlYW0gPCAzKSB7CisgICAgICAgICAgICAvLyBJbiBKYXZhcyAxLjEuNiBhbmQgMS40LCB0aGVyZSB3YXMgYSBjaGFyYWN0ZXIgZmllbGQgImV4cG9uZW50aWFsIi4KKyAgICAgICAgICAgIHNldEV4cG9uZW50U2VwYXJhdG9yKFN0cmluZy52YWx1ZU9mKGZpZWxkcy5nZXQoImV4cG9uZW50aWFsIiwgJ0UnKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gSW4gSmF2YSA2LCB0aGVyZSdzIGEgbmV3ICJleHBvbmVudGlhbFNlcGFyYXRvciIgZmllbGQuCisgICAgICAgICAgICBzZXRFeHBvbmVudFNlcGFyYXRvcigoU3RyaW5nKSBmaWVsZHMuZ2V0KCJleHBvbmVudGlhbFNlcGFyYXRvciIsICJFIikpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGN1cnJlbmN5ID0gQ3VycmVuY3kuZ2V0SW5zdGFuY2UoaW50bEN1cnJlbmN5U3ltYm9sKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGN1cnJlbmN5ID0gbnVsbDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvRmllbGRQb3NpdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9GaWVsZFBvc2l0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDViY2NjNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvRmllbGRQb3NpdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTcyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnRleHQ7CisKKy8qKgorICogSWRlbnRpZmllcyBmaWVsZHMgaW4gZm9ybWF0dGVkIHN0cmluZ3MuIElmIGEge0Bjb2RlIEZpZWxkUG9zaXRpb259IGlzIHBhc3NlZAorICogdG8gdGhlIGZvcm1hdCBtZXRob2Qgd2l0aCBzdWNoIGEgcGFyYW1ldGVyLCB0aGVuIHRoZSBpbmRpY2VzIHdpbGwgYmUgc2V0IHRvCisgKiB0aGUgc3RhcnQgYW5kIGVuZCBpbmRpY2VzIG9mIHRoZSBmaWVsZCBpbiB0aGUgZm9ybWF0dGVkIHN0cmluZy4KKyAqIDxwPgorICogQSB7QGNvZGUgRmllbGRQb3NpdGlvbn0gY2FuIGJlIGNyZWF0ZWQgYnkgdXNpbmcgdGhlIGludGVnZXIgY29uc3RhbnRzIGluIHRoZQorICogdmFyaW91cyBmb3JtYXQgY2xhc3NlcyAoZm9yIGV4YW1wbGUge0Bjb2RlIE51bWJlckZvcm1hdC5JTlRFR0VSX0ZJRUxEfSkgb3IKKyAqIG9uZSBvZiB0aGUgZmllbGRzIG9mIHR5cGUge0Bjb2RlIEZvcm1hdC5GaWVsZH0uCisgKiA8cD4KKyAqIElmIG1vcmUgdGhhbiBvbmUgZmllbGQgaW5mb3JtYXRpb24gaXMgbmVlZGVkLCB0aGUgbWV0aG9kCisgKiB7QGxpbmsgTnVtYmVyRm9ybWF0I2Zvcm1hdFRvQ2hhcmFjdGVySXRlcmF0b3IoT2JqZWN0KX0gc2hvdWxkIGJlIHVzZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBGaWVsZFBvc2l0aW9uIHsKKworICAgIHByaXZhdGUgaW50IG15RmllbGQsIGJlZ2luSW5kZXgsIGVuZEluZGV4OworCisgICAgcHJpdmF0ZSBGb3JtYXQuRmllbGQgbXlBdHRyaWJ1dGU7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBGaWVsZFBvc2l0aW9ufSBmb3IgdGhlIHNwZWNpZmllZCBmaWVsZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgdGhlIGZpZWxkIHRvIGlkZW50aWZ5LgorICAgICAqLworICAgIHB1YmxpYyBGaWVsZFBvc2l0aW9uKGludCBmaWVsZCkgeworICAgICAgICBteUZpZWxkID0gZmllbGQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRmllbGRQb3NpdGlvbn0gZm9yIHRoZSBzcGVjaWZpZWQge0Bjb2RlIEZpZWxkfQorICAgICAqIGF0dHJpYnV0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhdHRyaWJ1dGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWVsZCBhdHRyaWJ1dGUgdG8gaWRlbnRpZnkuCisgICAgICovCisgICAgcHVibGljIEZpZWxkUG9zaXRpb24oRm9ybWF0LkZpZWxkIGF0dHJpYnV0ZSkgeworICAgICAgICBteUF0dHJpYnV0ZSA9IGF0dHJpYnV0ZTsKKyAgICAgICAgbXlGaWVsZCA9IC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEZpZWxkUG9zaXRpb259IGZvciB0aGUgc3BlY2lmaWVkIHtAY29kZSBGaWVsZH0KKyAgICAgKiBhdHRyaWJ1dGUgYW5kIGZpZWxkIGlkLgorICAgICAqCisgICAgICogQHBhcmFtIGF0dHJpYnV0ZQorICAgICAqICAgICAgICAgICAgdGhlIGZpZWxkIGF0dHJpYnV0ZSB0byBpZGVudGlmeS4KKyAgICAgKiBAcGFyYW0gZmllbGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWVsZCB0byBpZGVudGlmeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmllbGRQb3NpdGlvbihGb3JtYXQuRmllbGQgYXR0cmlidXRlLCBpbnQgZmllbGQpIHsKKyAgICAgICAgbXlBdHRyaWJ1dGUgPSBhdHRyaWJ1dGU7CisgICAgICAgIG15RmllbGQgPSBmaWVsZDsKKyAgICB9CisKKyAgICB2b2lkIGNsZWFyKCkgeworICAgICAgICBiZWdpbkluZGV4ID0gZW5kSW5kZXggPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHRvIHRoaXMgZmllbGQgcG9zaXRpb24gYW5kIGluZGljYXRlcyBpZgorICAgICAqIHRoZXkgYXJlIGVxdWFsLiBJbiBvcmRlciB0byBiZSBlcXVhbCwge0Bjb2RlIG9iamVjdH0gbXVzdCBiZSBhbiBpbnN0YW5jZQorICAgICAqIG9mIHtAY29kZSBGaWVsZFBvc2l0aW9ufSB3aXRoIHRoZSBzYW1lIGZpZWxkLCBiZWdpbiBpbmRleCBhbmQgZW5kIGluZGV4LgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHdpdGggdGhpcyBvYmplY3QuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgZXF1YWwgdG8gdGhpcyBmaWVsZAorICAgICAqICAgICAgICAgcG9zaXRpb247IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgI2hhc2hDb2RlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgaWYgKCEob2JqZWN0IGluc3RhbmNlb2YgRmllbGRQb3NpdGlvbikpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBGaWVsZFBvc2l0aW9uIHBvcyA9IChGaWVsZFBvc2l0aW9uKSBvYmplY3Q7CisgICAgICAgIHJldHVybiBteUZpZWxkID09IHBvcy5teUZpZWxkICYmIG15QXR0cmlidXRlID09IHBvcy5teUF0dHJpYnV0ZQorICAgICAgICAgICAgICAgICYmIGJlZ2luSW5kZXggPT0gcG9zLmJlZ2luSW5kZXggJiYgZW5kSW5kZXggPT0gcG9zLmVuZEluZGV4OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGZpZWxkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZmlyc3QgaW5kZXggb2YgdGhlIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0QmVnaW5JbmRleCgpIHsKKyAgICAgICAgcmV0dXJuIGJlZ2luSW5kZXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXggb25lIHBhc3QgdGhlIGVuZCBvZiB0aGUgZmllbGQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIG9uZSBwYXN0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBjaGFyYWN0ZXIgaW4gdGhlIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RW5kSW5kZXgoKSB7CisgICAgICAgIHJldHVybiBlbmRJbmRleDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBmaWVsZCB3aGljaCBpcyBiZWluZyBpZGVudGlmaWVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZmllbGQgY29uc3RhbnQuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRGaWVsZCgpIHsKKyAgICAgICAgcmV0dXJuIG15RmllbGQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXR0cmlidXRlIHdoaWNoIGlzIGJlaW5nIGlkZW50aWZpZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRm9ybWF0LkZpZWxkIGdldEZpZWxkQXR0cmlidXRlKCkgeworICAgICAgICByZXR1cm4gbXlBdHRyaWJ1dGU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IGF0dHJpYnV0ZUhhc2ggPSAobXlBdHRyaWJ1dGUgPT0gbnVsbCkgPyAwIDogbXlBdHRyaWJ1dGUuaGFzaENvZGUoKTsKKyAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZUhhc2ggKyBteUZpZWxkICogMTAgKyBiZWdpbkluZGV4ICogMTAwICsgZW5kSW5kZXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgaW5kZXggb2YgdGhlIGJlZ2lubmluZyBvZiB0aGUgZmllbGQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCZWdpbkluZGV4KGludCBpbmRleCkgeworICAgICAgICBiZWdpbkluZGV4ID0gaW5kZXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgaW5kZXggb2YgdGhlIGVuZCBvZiB0aGUgZmllbGQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIG9uZSBwYXN0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBjaGFyYWN0ZXIgaW4gdGhlIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEVuZEluZGV4KGludCBpbmRleCkgeworICAgICAgICBlbmRJbmRleCA9IGluZGV4OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGZpZWxkIHBvc2l0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgZmllbGQgcG9zaXRpb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIGdldENsYXNzKCkuZ2V0TmFtZSgpICsgIlthdHRyaWJ1dGU9IiArIG15QXR0cmlidXRlICsgIiwgZmllbGQ9IgorICAgICAgICAgICAgICAgICsgbXlGaWVsZCArICIsIGJlZ2luSW5kZXg9IiArIGJlZ2luSW5kZXggKyAiLCBlbmRJbmRleD0iCisgICAgICAgICAgICAgICAgKyBlbmRJbmRleCArICJdIjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L0Zvcm1hdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9Gb3JtYXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ODY3MWZhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9Gb3JtYXQuamF2YQpAQCAtMCwwICsxLDI0NyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS50ZXh0OworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKKy8qKgorICogVGhlIGJhc2UgY2xhc3MgZm9yIGFsbCBmb3JtYXRzLgorICogPHA+CisgKiBUaGlzIGlzIGFuIGFic3RyYWN0IGJhc2UgY2xhc3Mgd2hpY2ggc3BlY2lmaWVzIHRoZSBwcm90b2NvbCBmb3IgY2xhc3NlcyB3aGljaAorICogY29udmVydCBvdGhlciBvYmplY3RzIG9yIHZhbHVlcywgc3VjaCBhcyBudW1lcmljIHZhbHVlcyBhbmQgZGF0ZXMsIGFuZCB0aGVpcgorICogc3RyaW5nIHJlcHJlc2VudGF0aW9ucy4gSW4gc29tZSBjYXNlcyB0aGVzZSByZXByZXNlbnRhdGlvbnMgbWF5IGJlIGxvY2FsaXplZAorICogb3IgY29udGFpbiBsb2NhbGl6ZWQgY2hhcmFjdGVycyBvciBzdHJpbmdzLiBGb3IgZXhhbXBsZSwgYSBudW1lcmljIGZvcm1hdHRlcgorICogc3VjaCBhcyB7QGNvZGUgRGVjaW1hbEZvcm1hdH0gbWF5IGNvbnZlcnQgYSBudW1lcmljIHZhbHVlIHN1Y2ggYXMgMTIzNDUgdG8KKyAqIHRoZSBzdHJpbmcgIiQxMiwzNDUiLiBJdCBtYXkgYWxzbyBwYXJzZSB0aGUgc3RyaW5nIGJhY2sgaW50byBhIG51bWVyaWMgdmFsdWUuCisgKiBBIGRhdGUgYW5kIHRpbWUgZm9ybWF0dGVyIGxpa2Uge0Bjb2RlIFNpbXBsZURhdGVGb3JtYXR9IG1heSByZXByZXNlbnQgYQorICogc3BlY2lmaWMgZGF0ZSwgZW5jb2RlZCBudW1lcmljYWxseSwgYXMgYSBzdHJpbmcgc3VjaCBhcyAiV2VkbmVzZGF5LCBGZWJydWFyeQorICogMjYsIDE5OTcgQUQiLgorICogPHA+CisgKiBNYW55IG9mIHRoZSBjb25jcmV0ZSBzdWJjbGFzc2VzIG9mIHtAY29kZSBGb3JtYXR9IGVtcGxveSB0aGUgbm90aW9uIG9mIGEKKyAqIHBhdHRlcm4uIEEgcGF0dGVybiBpcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcnVsZXMgd2hpY2ggZ292ZXJuIHRoZQorICogY29udmVyc2lvbiBiZXR3ZWVuIHZhbHVlcyBhbmQgc3RyaW5ncy4gRm9yIGV4YW1wbGUsIGEge0Bjb2RlIERlY2ltYWxGb3JtYXR9CisgKiBvYmplY3QgbWF5IGJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgcGF0dGVybiAiJCMsIyMwLjAwOygkIywjIzAuMDApIiwgd2hpY2ggaXMgYQorICogY29tbW9uIFVTIEVuZ2xpc2ggZm9ybWF0IGZvciBjdXJyZW5jeSB2YWx1ZXMsIHlpZWxkaW5nIHN0cmluZ3Mgc3VjaCBhcworICogIiQxLDIzNC40NSIgZm9yIDEyMzQuNDUsIGFuZCAiKCQ5ODcuNjUpIiBmb3IgLTk4Ny42NTQzLiBUaGUgc3BlY2lmaWMgc3ludGF4CisgKiBvZiBhIHBhdHRlcm4gaXMgZGVmaW5lZCBieSBlYWNoIHN1YmNsYXNzLiBFdmVuIHRob3VnaCBtYW55IHN1YmNsYXNzZXMgdXNlCisgKiBwYXR0ZXJucywgdGhlIG5vdGlvbiBvZiBhIHBhdHRlcm4gaXMgbm90IGluaGVyZW50IHRvIHtAY29kZSBGb3JtYXR9IGNsYXNzZXMKKyAqIGluIGdlbmVyYWwsIGFuZCBpcyBub3QgcGFydCBvZiB0aGUgZXhwbGljaXQgYmFzZSBjbGFzcyBwcm90b2NvbC4KKyAqIDxwPgorICogVHdvIGNvbXBsZXggZm9ybWF0dGluZyBjbGFzc2VzIGFyZSB3b3J0aCBtZW50aW9uaW5nOiB7QGNvZGUgTWVzc2FnZUZvcm1hdH0KKyAqIGFuZCB7QGNvZGUgQ2hvaWNlRm9ybWF0fS4ge0Bjb2RlIENob2ljZUZvcm1hdH0gaXMgYSBzdWJjbGFzcyBvZgorICoge0Bjb2RlIE51bWJlckZvcm1hdH0gd2hpY2ggYWxsb3dzIHRoZSB1c2VyIHRvIGZvcm1hdCBkaWZmZXJlbnQgbnVtYmVyIHJhbmdlcworICogYXMgc3RyaW5ncy4gRm9yIGluc3RhbmNlLCAwIG1heSBiZSByZXByZXNlbnRlZCBhcyAibm8gZmlsZXMiLCAxIGFzICJvbmUKKyAqIGZpbGUiLCBhbmQgYW55IG51bWJlciBncmVhdGVyIHRoYW4gMSBhcyAibWFueSBmaWxlcyIuIHtAY29kZSBNZXNzYWdlRm9ybWF0fQorICogaXMgYSBmb3JtYXR0ZXIgd2hpY2ggdXRpbGl6ZXMgb3RoZXIge0Bjb2RlIEZvcm1hdH0gb2JqZWN0cyB0byBmb3JtYXQgYSBzdHJpbmcKKyAqIGNvbnRhaW5pbmcgbXVsdGlwbGUgdmFsdWVzLiBGb3IgaW5zdGFuY2UsIGEge0Bjb2RlIE1lc3NhZ2VGb3JtYXR9IG9iamVjdAorICogbWlnaHQgcHJvZHVjZSB0aGUgc3RyaW5nICJUaGVyZSBhcmUgbm8gZmlsZXMgb24gdGhlIGRpc2sgTXlEaXNrIG9uIEZlYnJ1YXJ5CisgKiAyNywgMTk5Ny4iIGdpdmVuIHRoZSBhcmd1bWVudHMgMCwgIk15RGlzayIsIGFuZCB0aGUgZGF0ZSB2YWx1ZSBvZiAyLzI3Lzk3LgorICogU2VlIHRoZSB7QGxpbmsgQ2hvaWNlRm9ybWF0fSBhbmQge0BsaW5rIE1lc3NhZ2VGb3JtYXR9IGRlc2NyaXB0aW9ucyBmb3IKKyAqIGZ1cnRoZXIgaW5mb3JtYXRpb24uCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBGb3JtYXQgaW1wbGVtZW50cyBTZXJpYWxpemFibGUsIENsb25lYWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjk5MjgyNTg1ODE0NjI0MTg5TDsKKworICAgIC8qKgorICAgICAqIFVzZWQgYnkgc3ViY2xhc3Nlcy4gVGhpcyB3YXMgcHVibGljIGluIEphdmEgNS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRm9ybWF0KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb3B5IG9mIHRoaXMge0Bjb2RlIEZvcm1hdH0gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc2hhbGxvdyBjb3B5IG9mIHRoaXMgZm9ybWF0LgorICAgICAqCisgICAgICogQHNlZSBqYXZhLmxhbmcuQ2xvbmVhYmxlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGb3JtYXRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHVzaW5nIHRoZSBydWxlcyBvZiB0aGlzIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gZm9ybWF0LgorICAgICAqIEByZXR1cm4gdGhlIGZvcm1hdHRlZCBzdHJpbmcuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgIGlmIHRoZSBvYmplY3QgY2Fubm90IGJlIGZvcm1hdHRlZCBieSB0aGlzIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGZvcm1hdChPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIHJldHVybiBmb3JtYXQob2JqZWN0LCBuZXcgU3RyaW5nQnVmZmVyKCksIG5ldyBGaWVsZFBvc2l0aW9uKDApKQorICAgICAgICAgICAgICAgIC50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlIHNwZWNpZmllZCBvYmplY3QgdG8gdGhlIHNwZWNpZmllZCBzdHJpbmcgYnVmZmVyIHVzaW5nIHRoZQorICAgICAqIHJ1bGVzIG9mIHRoaXMgZm9ybWF0LgorICAgICAqIDxwPgorICAgICAqIHtAY29kZSBmaWVsZH0gaXMgYW4gaW5wdXQvb3V0cHV0IHBhcmFtZXRlci4gSWYgaXRzIHtAY29kZSBmaWVsZH0KKyAgICAgKiBtZW1iZXIgY29udGFpbnMgYW4gZW51bSB2YWx1ZSBzcGVjaWZ5aW5nIGEgZmllbGQgb24gaW5wdXQsIHRoZW4gaXRzCisgICAgICoge0Bjb2RlIGJlZ2luSW5kZXh9IGFuZCB7QGNvZGUgZW5kSW5kZXh9IG1lbWJlcnMgd2lsbCBiZSB1cGRhdGVkIHdpdGggdGhlCisgICAgICogdGV4dCBvZmZzZXQgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhpcyBmaWVsZCBpbiB0aGUgZm9ybWF0dGVkIHRleHQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGZvcm1hdC4KKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIGJ1ZmZlciB3aGVyZSB0aGUgZm9ybWF0dGVkIHN0cmluZyBpcyBhcHBlbmRlZCB0by4KKyAgICAgKiBAcGFyYW0gZmllbGQKKyAgICAgKiAgICAgICAgICAgIG9uIGlucHV0OiBhbiBvcHRpb25hbCBhbGlnbm1lbnQgZmllbGQ7IG9uIG91dHB1dDogdGhlIG9mZnNldHMKKyAgICAgKiAgICAgICAgICAgIG9mIHRoZSBhbGlnbm1lbnQgZmllbGQgaW4gdGhlIGZvcm1hdHRlZCB0ZXh0LgorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyBidWZmZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgY2Fubm90IGJlIGZvcm1hdHRlZCBieSB0aGlzIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nQnVmZmVyIGZvcm1hdChPYmplY3Qgb2JqZWN0LCBTdHJpbmdCdWZmZXIgYnVmZmVyLAorICAgICAgICAgICAgRmllbGRQb3NpdGlvbiBmaWVsZCk7CisKKyAgICAvKioKKyAgICAgKiBGb3JtYXRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHVzaW5nIHRoZSBydWxlcyBvZiB0aGlzIGZvcm1hdCBhbmQgcmV0dXJucworICAgICAqIGFuIHtAY29kZSBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3J9IHdpdGggdGhlIGZvcm1hdHRlZCBzdHJpbmcgYW5kIG5vCisgICAgICogYXR0cmlidXRlcy4KKyAgICAgKiA8cD4KKyAgICAgKiBTdWJjbGFzc2VzIHNob3VsZCByZXR1cm4gYW4ge0Bjb2RlIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcn0gd2l0aCB0aGUKKyAgICAgKiBhcHByb3ByaWF0ZSBhdHRyaWJ1dGVzLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBmb3JtYXQuCisgICAgICogQHJldHVybiBhbiB7QGNvZGUgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yfSB3aXRoIHRoZSBmb3JtYXR0ZWQgb2JqZWN0CisgICAgICogICAgICAgICBhbmQgYXR0cmlidXRlcy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBjYW5ub3QgYmUgZm9ybWF0dGVkIGJ5IHRoaXMgZm9ybWF0LgorICAgICAqLworICAgIHB1YmxpYyBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcihPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlZFN0cmluZyhmb3JtYXQob2JqZWN0KSkuZ2V0SXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgdGhlIHNwZWNpZmllZCBzdHJpbmcgdXNpbmcgdGhlIHJ1bGVzIG9mIHRoaXMgZm9ybWF0LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBwYXJzZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBvYmplY3QgcmVzdWx0aW5nIGZyb20gdGhlIHBhcnNlLgorICAgICAqIEB0aHJvd3MgUGFyc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBkdXJpbmcgcGFyc2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IHBhcnNlT2JqZWN0KFN0cmluZyBzdHJpbmcpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgIFBhcnNlUG9zaXRpb24gcG9zaXRpb24gPSBuZXcgUGFyc2VQb3NpdGlvbigwKTsKKyAgICAgICAgT2JqZWN0IHJlc3VsdCA9IHBhcnNlT2JqZWN0KHN0cmluZywgcG9zaXRpb24pOworICAgICAgICBpZiAocG9zaXRpb24uZ2V0SW5kZXgoKSA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oIlBhcnNlIGZhaWx1cmUiLCBwb3NpdGlvbi5nZXRFcnJvckluZGV4KCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIHN0YXJ0aW5nIGF0IHRoZSBpbmRleCBzcGVjaWZpZWQgYnkKKyAgICAgKiB7QGNvZGUgcG9zaXRpb259LiBJZiB0aGUgc3RyaW5nIGlzIHN1Y2Nlc3NmdWxseSBwYXJzZWQgdGhlbiB0aGUgaW5kZXggb2YKKyAgICAgKiB0aGUge0Bjb2RlIFBhcnNlUG9zaXRpb259IGlzIHVwZGF0ZWQgdG8gdGhlIGluZGV4IGZvbGxvd2luZyB0aGUgcGFyc2VkCisgICAgICogdGV4dC4gT24gZXJyb3IsIHRoZSBpbmRleCBpcyB1bmNoYW5nZWQgYW5kIHRoZSBlcnJvciBpbmRleCBvZgorICAgICAqIHtAY29kZSBQYXJzZVBvc2l0aW9ufSBpcyBzZXQgdG8gdGhlIGluZGV4IHdoZXJlIHRoZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gcGFyc2UuCisgICAgICogQHBhcmFtIHBvc2l0aW9uCisgICAgICogICAgICAgICAgICBpbnB1dC9vdXRwdXQgcGFyYW1ldGVyLCBzcGVjaWZpZXMgdGhlIHN0YXJ0IGluZGV4IGluCisgICAgICogICAgICAgICAgICB7QGNvZGUgc3RyaW5nfSBmcm9tIHdoZXJlIHRvIHN0YXJ0IHBhcnNpbmcuIElmIHBhcnNpbmcgaXMKKyAgICAgKiAgICAgICAgICAgIHN1Y2Nlc3NmdWwsIGl0IGlzIHVwZGF0ZWQgd2l0aCB0aGUgaW5kZXggZm9sbG93aW5nIHRoZSBwYXJzZWQKKyAgICAgKiAgICAgICAgICAgIHRleHQ7IG9uIGVycm9yLCB0aGUgaW5kZXggaXMgdW5jaGFuZ2VkIGFuZCB0aGUgZXJyb3IgaW5kZXggaXMKKyAgICAgKiAgICAgICAgICAgIHNldCB0byB0aGUgaW5kZXggd2hlcmUgdGhlIGVycm9yIG9jY3VycmVkLgorICAgICAqIEByZXR1cm4gdGhlIG9iamVjdCByZXN1bHRpbmcgZnJvbSB0aGUgcGFyc2Ugb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzCisgICAgICogICAgICAgICBhbiBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgT2JqZWN0IHBhcnNlT2JqZWN0KFN0cmluZyBzdHJpbmcsIFBhcnNlUG9zaXRpb24gcG9zaXRpb24pOworCisgICAgc3RhdGljIGJvb2xlYW4gdXBUbyhTdHJpbmcgc3RyaW5nLCBQYXJzZVBvc2l0aW9uIHBvc2l0aW9uLAorICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciwgY2hhciBzdG9wKSB7CisgICAgICAgIGludCBpbmRleCA9IHBvc2l0aW9uLmdldEluZGV4KCksIGxlbmd0aCA9IHN0cmluZy5sZW5ndGgoKTsKKyAgICAgICAgYm9vbGVhbiBsYXN0UXVvdGUgPSBmYWxzZSwgcXVvdGUgPSBmYWxzZTsKKyAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7CisgICAgICAgICAgICBjaGFyIGNoID0gc3RyaW5nLmNoYXJBdChpbmRleCsrKTsKKyAgICAgICAgICAgIGlmIChjaCA9PSAnXCcnKSB7CisgICAgICAgICAgICAgICAgaWYgKGxhc3RRdW90ZSkgeworICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCdcJycpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBxdW90ZSA9ICFxdW90ZTsKKyAgICAgICAgICAgICAgICBsYXN0UXVvdGUgPSB0cnVlOworICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PSBzdG9wICYmICFxdW90ZSkgeworICAgICAgICAgICAgICAgIHBvc2l0aW9uLnNldEluZGV4KGluZGV4KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgbGFzdFF1b3RlID0gZmFsc2U7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChjaCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcG9zaXRpb24uc2V0SW5kZXgoaW5kZXgpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgc3RhdGljIGJvb2xlYW4gdXBUb1dpdGhRdW90ZXMoU3RyaW5nIHN0cmluZywgUGFyc2VQb3NpdGlvbiBwb3NpdGlvbiwKKyAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBidWZmZXIsIGNoYXIgc3RvcCwgY2hhciBzdGFydCkgeworICAgICAgICBpbnQgaW5kZXggPSBwb3NpdGlvbi5nZXRJbmRleCgpLCBsZW5ndGggPSBzdHJpbmcubGVuZ3RoKCksIGNvdW50ID0gMTsKKyAgICAgICAgYm9vbGVhbiBxdW90ZSA9IGZhbHNlOworICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHsKKyAgICAgICAgICAgIGNoYXIgY2ggPSBzdHJpbmcuY2hhckF0KGluZGV4KyspOworICAgICAgICAgICAgaWYgKGNoID09ICdcJycpIHsKKyAgICAgICAgICAgICAgICBxdW90ZSA9ICFxdW90ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghcXVvdGUpIHsKKyAgICAgICAgICAgICAgICBpZiAoY2ggPT0gc3RvcCkgeworICAgICAgICAgICAgICAgICAgICBjb3VudC0tOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoY291bnQgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbi5zZXRJbmRleChpbmRleCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoY2ggPT0gc3RhcnQpIHsKKyAgICAgICAgICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGNoKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbm1hdGNoZWQgYnJhY2VzIGluIHRoZSBwYXR0ZXJuIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5uZXIgY2xhc3MgdXNlZCB0byByZXByZXNlbnQge0Bjb2RlIEZvcm1hdH0gYXR0cmlidXRlcyBpbiB0aGUKKyAgICAgKiB7QGNvZGUgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yfSB0aGF0IHRoZQorICAgICAqIHtAY29kZSBmb3JtYXRUb0NoYXJhY3Rlckl0ZXJhdG9yKCl9IG1ldGhvZCByZXR1cm5zIGluIHtAY29kZSBGb3JtYXR9CisgICAgICogc3ViY2xhc3Nlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEZpZWxkIGV4dGVuZHMgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjc2OTY2NjkyMjE3MzYwMjgzTDsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgRmllbGR9IHdpdGggdGhlIGdpdmVuIGZpZWxkIG5hbWUuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBmaWVsZE5hbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZmllbGQgbmFtZS4KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBGaWVsZChTdHJpbmcgZmllbGROYW1lKSB7CisgICAgICAgICAgICBzdXBlcihmaWVsZE5hbWUpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9NZXNzYWdlRm9ybWF0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L01lc3NhZ2VGb3JtYXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOThlNGZkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9NZXNzYWdlRm9ybWF0LmphdmEKQEAgLTAsMCArMSwxMjk4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1GaWVsZDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuRW1wdHlBcnJheTsKKworLyoqCisgKiBQcm9kdWNlcyBjb25jYXRlbmF0ZWQgbWVzc2FnZXMgaW4gbGFuZ3VhZ2UtbmV1dHJhbCB3YXkuIE5ldyBjb2RlCisgKiBzaG91bGQgcHJvYmFibHkgdXNlIHtAbGluayBqYXZhLnV0aWwuRm9ybWF0dGVyfSBpbnN0ZWFkLgorICogPHA+CisgKiB7QGNvZGUgTWVzc2FnZUZvcm1hdH0gdGFrZXMgYSBzZXQgb2Ygb2JqZWN0cywgZm9ybWF0cyB0aGVtIGFuZCB0aGVuCisgKiBpbnNlcnRzIHRoZSBmb3JtYXR0ZWQgc3RyaW5ncyBpbnRvIHRoZSBwYXR0ZXJuIGF0IHRoZSBhcHByb3ByaWF0ZSBwbGFjZXMuCisgKiA8cD4KKyAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4ge0Bjb2RlIE1lc3NhZ2VGb3JtYXR9IGRpZmZlcnMgZnJvbSB0aGUgb3RoZXIKKyAqIHtAY29kZSBGb3JtYXR9IGNsYXNzZXMgaW4gdGhhdCB5b3UgY3JlYXRlIGEge0Bjb2RlIE1lc3NhZ2VGb3JtYXR9CisgKiBvYmplY3Qgd2l0aCBvbmUgb2YgaXRzIGNvbnN0cnVjdG9ycyAobm90IHdpdGggYSB7QGNvZGUgZ2V0SW5zdGFuY2V9CisgKiBzdHlsZSBmYWN0b3J5IG1ldGhvZCkuIFRoZSBmYWN0b3J5IG1ldGhvZHMgYXJlbid0IG5lY2Vzc2FyeSBiZWNhdXNlCisgKiB7QGNvZGUgTWVzc2FnZUZvcm1hdH0gaXRzZWxmIGRvZXNuJ3QgaW1wbGVtZW50IGxvY2FsZS1zcGVjaWZpYworICogYmVoYXZpb3IuIEFueSBsb2NhbGUtc3BlY2lmaWMgYmVoYXZpb3IgaXMgZGVmaW5lZCBieSB0aGUgcGF0dGVybiB0aGF0IHlvdQorICogcHJvdmlkZSBhcyB3ZWxsIGFzIHRoZSBzdWJmb3JtYXRzIHVzZWQgZm9yIGluc2VydGVkIGFyZ3VtZW50cy4KKyAqCisgKiA8aDQ+PGEgbmFtZT0icGF0dGVybnMiPlBhdHRlcm5zIGFuZCB0aGVpciBpbnRlcnByZXRhdGlvbjwvYT48L2g0PgorICoKKyAqIHtAY29kZSBNZXNzYWdlRm9ybWF0fSB1c2VzIHBhdHRlcm5zIG9mIHRoZSBmb2xsb3dpbmcgZm9ybToKKyAqIDxibG9ja3F1b3RlPgorICoKKyAqIDxwcmU+CisgKiA8aT5NZXNzYWdlRm9ybWF0UGF0dGVybjo8L2k+CisgKiAgICAgICAgIDxpPlN0cmluZzwvaT4KKyAqICAgICAgICAgPGk+TWVzc2FnZUZvcm1hdFBhdHRlcm48L2k+IDxpPkZvcm1hdEVsZW1lbnQ8L2k+IDxpPlN0cmluZzwvaT4KKyAqIDxpPkZvcm1hdEVsZW1lbnQ6PC9pPgorICogICAgICAgICB7IDxpPkFyZ3VtZW50SW5kZXg8L2k+IH0KKyAqICAgICAgICAgeyA8aT5Bcmd1bWVudEluZGV4PC9pPiAsIDxpPkZvcm1hdFR5cGU8L2k+IH0KKyAqICAgICAgICAgeyA8aT5Bcmd1bWVudEluZGV4PC9pPiAsIDxpPkZvcm1hdFR5cGU8L2k+ICwgPGk+Rm9ybWF0U3R5bGU8L2k+IH0KKyAqIDxpPkZvcm1hdFR5cGU6IG9uZSBvZiA8L2k+CisgKiAgICAgICAgIG51bWJlciBkYXRlIHRpbWUgY2hvaWNlCisgKiA8aT5Gb3JtYXRTdHlsZTo8L2k+CisgKiAgICAgICAgIHNob3J0CisgKiAgICAgICAgIG1lZGl1bQorICogICAgICAgICBsb25nCisgKiAgICAgICAgIGZ1bGwKKyAqICAgICAgICAgaW50ZWdlcgorICogICAgICAgICBjdXJyZW5jeQorICogICAgICAgICBwZXJjZW50CisgKiAgICAgICAgIDxpPlN1YmZvcm1hdFBhdHRlcm48L2k+CisgKiA8aT5TdHJpbmc6PC9pPgorICogICAgICAgICA8aT5TdHJpbmdQYXJ0Jmx0O3N1YiZndDtvcHQmbHQ7L3N1YiZndDs8L2k+CisgKiAgICAgICAgIDxpPlN0cmluZzwvaT4gPGk+U3RyaW5nUGFydDwvaT4KKyAqIDxpPlN0cmluZ1BhcnQ6PC9pPgorICogICAgICAgICAnJworICogICAgICAgICAnIDxpPlF1b3RlZFN0cmluZzwvaT4gJworICogICAgICAgICA8aT5VbnF1b3RlZFN0cmluZzwvaT4KKyAqIDxpPlN1YmZvcm1hdFBhdHRlcm46PC9pPgorICogICAgICAgICA8aT5TdWJmb3JtYXRQYXR0ZXJuUGFydCZsdDtzdWImZ3Q7b3B0Jmx0Oy9zdWImZ3Q7PC9pPgorICogICAgICAgICA8aT5TdWJmb3JtYXRQYXR0ZXJuPC9pPiA8aT5TdWJmb3JtYXRQYXR0ZXJuUGFydDwvaT4KKyAqIDxpPlN1YkZvcm1hdFBhdHRlcm5QYXJ0OjwvaT4KKyAqICAgICAgICAgJyA8aT5RdW90ZWRQYXR0ZXJuPC9pPiAnCisgKiAgICAgICAgIDxpPlVucXVvdGVkUGF0dGVybjwvaT4KKyAqIDwvcHJlPgorICoKKyAqIDwvYmxvY2txdW90ZT4KKyAqCisgKiA8cD4KKyAqIFdpdGhpbiBhIDxpPlN0cmluZzwvaT4sIHtAY29kZSAiJycifSByZXByZXNlbnRzIGEgc2luZ2xlIHF1b3RlLiBBCisgKiA8aT5RdW90ZWRTdHJpbmc8L2k+IGNhbiBjb250YWluIGFyYml0cmFyeSBjaGFyYWN0ZXJzIGV4Y2VwdCBzaW5nbGUgcXVvdGVzOworICogdGhlIHN1cnJvdW5kaW5nIHNpbmdsZSBxdW90ZXMgYXJlIHJlbW92ZWQuIEFuIDxpPlVucXVvdGVkU3RyaW5nPC9pPiBjYW4KKyAqIGNvbnRhaW4gYXJiaXRyYXJ5IGNoYXJhY3RlcnMgZXhjZXB0IHNpbmdsZSBxdW90ZXMgYW5kIGxlZnQgY3VybHkgYnJhY2tldHMuCisgKiBUaHVzLCBhIHN0cmluZyB0aGF0IHNob3VsZCByZXN1bHQgaW4gdGhlIGZvcm1hdHRlZCBtZXNzYWdlICInezB9JyIgY2FuIGJlCisgKiB3cml0dGVuIGFzIHtAY29kZSAiJycneycwfScnIn0gb3Ige0Bjb2RlICInJyd7MH0nJycifS4KKyAqIDxwPgorICogV2l0aGluIGEgPGk+U3ViZm9ybWF0UGF0dGVybjwvaT4sIGRpZmZlcmVudCBydWxlcyBhcHBseS4gQSA8aT5RdW90ZWRQYXR0ZXJuPC9pPgorICogY2FuIGNvbnRhaW4gYXJiaXRyYXJ5IGNoYXJhY3RlcnMgZXhjZXB0IHNpbmdsZSBxdW90ZXMsIGJ1dCB0aGUgc3Vycm91bmRpbmcKKyAqIHNpbmdsZSBxdW90ZXMgYXJlIDxzdHJvbmc+bm90PC9zdHJvbmc+IHJlbW92ZWQsIHNvIHRoZXkgbWF5IGJlIGludGVycHJldGVkCisgKiBieSB0aGUgc3ViZm9ybWF0LiBGb3IgZXhhbXBsZSwge0Bjb2RlICJ7MSxudW1iZXIsJCcjJywjI30ifSB3aWxsCisgKiBwcm9kdWNlIGEgbnVtYmVyIGZvcm1hdCB3aXRoIHRoZSBoYXNoLXNpZ24gcXVvdGVkLCB3aXRoIGEgcmVzdWx0IHN1Y2ggYXM6CisgKiAiJCMzMSw0NSIuIEFuIDxpPlVucXVvdGVkUGF0dGVybjwvaT4gY2FuIGNvbnRhaW4gYXJiaXRyYXJ5IGNoYXJhY3RlcnMgZXhjZXB0CisgKiBzaW5nbGUgcXVvdGVzLCBidXQgY3VybHkgYnJhY2VzIHdpdGhpbiBpdCBtdXN0IGJlIGJhbGFuY2VkLiBGb3IgZXhhbXBsZSwKKyAqIHtAY29kZSAiYWIgezB9IGRlIn0gYW5kIHtAY29kZSAiYWIgJ30nIGRlIn0gYXJlIHZhbGlkIHN1YmZvcm1hdAorICogcGF0dGVybnMsIGJ1dCB7QGNvZGUgImFiIHswJ30nIGRlIn0gYW5kIHtAY29kZSAiYWIgfSBkZSJ9IGFyZQorICogbm90LgorICogPGRsPgorICogPGR0PjxiPldhcm5pbmc6PC9iPjwvZHQ+CisgKiA8ZGQ+VGhlIHJ1bGVzIGZvciB1c2luZyBxdW90ZXMgd2l0aGluIG1lc3NhZ2UgZm9ybWF0IHBhdHRlcm5zIHVuZm9ydHVuYXRlbHkKKyAqIGhhdmUgc2hvd24gdG8gYmUgc29tZXdoYXQgY29uZnVzaW5nLiBJbiBwYXJ0aWN1bGFyLCBpdCBpc24ndCBhbHdheXMgb2J2aW91cworICogdG8gbG9jYWxpemVycyB3aGV0aGVyIHNpbmdsZSBxdW90ZXMgbmVlZCB0byBiZSBkb3VibGVkIG9yIG5vdC4gTWFrZSBzdXJlIHRvCisgKiBpbmZvcm0gbG9jYWxpemVycyBhYm91dCB0aGUgcnVsZXMsIGFuZCB0ZWxsIHRoZW0gKGZvciBleGFtcGxlLCBieSB1c2luZworICogY29tbWVudHMgaW4gcmVzb3VyY2UgYnVuZGxlIHNvdXJjZSBmaWxlcykgd2hpY2ggc3RyaW5ncyB3aWxsIGJlIHByb2Nlc3NlZCBieQorICoge0Bjb2RlIE1lc3NhZ2VGb3JtYXR9LiBOb3RlIHRoYXQgbG9jYWxpemVycyBtYXkgbmVlZCB0byB1c2Ugc2luZ2xlIHF1b3RlcyBpbgorICogdHJhbnNsYXRlZCBzdHJpbmdzIHdoZXJlIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIGRvZXNuJ3QgaGF2ZSB0aGVtLiA8YnI+CisgKiBOb3RlIGFsc28gdGhhdCB0aGUgc2ltcGxlc3Qgd2F5IHRvIGF2b2lkIHRoZSBwcm9ibGVtIGlzIHRvIHVzZSB0aGUgcmVhbAorICogYXBvc3Ryb3BoZSAoc2luZ2xlIHF1b3RlKSBjaGFyYWN0ZXIgXHUyMDE5ICgnKSBmb3IgaHVtYW4tcmVhZGFibGUgdGV4dCwgYW5kCisgKiB0byB1c2UgdGhlIEFTQ0lJIGFwb3N0cm9waGUgKFx1MDAyNyAnICkgb25seSBpbiBwcm9ncmFtIHN5bnRheCwgbGlrZSBxdW90aW5nCisgKiBpbiB7QGNvZGUgTWVzc2FnZUZvcm1hdH0uIFNlZSB0aGUgYW5ub3RhdGlvbnMgZm9yIFUrMDAyNyBBcG9zdHJvcGhlIGluIFRoZSBVbmljb2RlCisgKiBTdGFuZGFyZC4KKyAqIDwvZGw+CisgKiA8cD4KKyAqIFRoZSA8aT5Bcmd1bWVudEluZGV4PC9pPiB2YWx1ZSBpcyBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyIHdyaXR0ZW4gdXNpbmcgdGhlCisgKiBkaWdpdHMgJzAnIHRocm91Z2ggJzknLCBhbmQgcmVwcmVzZW50cyBhbiBpbmRleCBpbnRvIHRoZQorICoge0Bjb2RlIGFyZ3VtZW50c30gYXJyYXkgcGFzc2VkIHRvIHRoZSB7QGNvZGUgZm9ybWF0fSBtZXRob2RzIG9yCisgKiB0aGUgcmVzdWx0IGFycmF5IHJldHVybmVkIGJ5IHRoZSB7QGNvZGUgcGFyc2V9IG1ldGhvZHMuCisgKiA8cD4KKyAqIFRoZSA8aT5Gb3JtYXRUeXBlPC9pPiBhbmQgPGk+Rm9ybWF0U3R5bGU8L2k+IHZhbHVlcyBhcmUgdXNlZCB0byBjcmVhdGUgYQorICoge0Bjb2RlIEZvcm1hdH0gaW5zdGFuY2UgZm9yIHRoZSBmb3JtYXQgZWxlbWVudC4gVGhlIGZvbGxvd2luZyB0YWJsZQorICogc2hvd3MgaG93IHRoZSB2YWx1ZXMgbWFwIHRvIHtAY29kZSBGb3JtYXR9IGluc3RhbmNlcy4gQ29tYmluYXRpb25zIG5vdCBzaG93biBpbiB0aGUKKyAqIHRhYmxlIGFyZSBpbGxlZ2FsLiBBIDxpPlN1YmZvcm1hdFBhdHRlcm48L2k+IG11c3QgYmUgYSB2YWxpZCBwYXR0ZXJuIHN0cmluZworICogZm9yIHRoZSB7QGNvZGUgRm9ybWF0fSBzdWJjbGFzcyB1c2VkLgorICogPHA+CisgKiA8dGFibGUgYm9yZGVyPTE+CisgKiA8dHI+CisgKiA8dGg+Rm9ybWF0IFR5cGU8L3RoPgorICogPHRoPkZvcm1hdCBTdHlsZTwvdGg+CisgKiA8dGg+U3ViZm9ybWF0IENyZWF0ZWQ8L3RoPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCBjb2xzcGFuPSIyIj48aT4obm9uZSk8L2k+PC90ZD4KKyAqIDx0ZD57QGNvZGUgbnVsbH08L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCByb3dzcGFuPSI1Ij57QGNvZGUgbnVtYmVyfTwvdGQ+CisgKiA8dGQ+PGk+KG5vbmUpPC9pPjwvdGQ+CisgKiA8dGQ+e0Bjb2RlIE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZShnZXRMb2NhbGUoKSl9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQ+e0Bjb2RlIGludGVnZXJ9PC90ZD4KKyAqIDx0ZD57QGNvZGUgTnVtYmVyRm9ybWF0LmdldEludGVnZXJJbnN0YW5jZShnZXRMb2NhbGUoKSl9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQ+e0Bjb2RlIGN1cnJlbmN5fTwvdGQ+CisgKiA8dGQ+e0Bjb2RlIE51bWJlckZvcm1hdC5nZXRDdXJyZW5jeUluc3RhbmNlKGdldExvY2FsZSgpKX08L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZD57QGNvZGUgcGVyY2VudH08L3RkPgorICogPHRkPntAY29kZSBOdW1iZXJGb3JtYXQuZ2V0UGVyY2VudEluc3RhbmNlKGdldExvY2FsZSgpKX08L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZD48aT5TdWJmb3JtYXRQYXR0ZXJuPC9pPjwvdGQ+CisgKiA8dGQ+e0Bjb2RlIG5ldyBEZWNpbWFsRm9ybWF0KHN1YmZvcm1hdFBhdHRlcm4sIG5ldyBEZWNpbWFsRm9ybWF0U3ltYm9scyhnZXRMb2NhbGUoKSkpfTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHJvd3NwYW49IjYiPntAY29kZSBkYXRlfTwvdGQ+CisgKiA8dGQ+PGk+KG5vbmUpPC9pPjwvdGQ+CisgKiA8dGQ+e0Bjb2RlIERhdGVGb3JtYXQuZ2V0RGF0ZUluc3RhbmNlKERhdGVGb3JtYXQuREVGQVVMVCwgZ2V0TG9jYWxlKCkpfTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkPntAY29kZSBzaG9ydH08L3RkPgorICogPHRkPntAY29kZSBEYXRlRm9ybWF0LmdldERhdGVJbnN0YW5jZShEYXRlRm9ybWF0LlNIT1JULCBnZXRMb2NhbGUoKSl9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQ+e0Bjb2RlIG1lZGl1bX08L3RkPgorICogPHRkPntAY29kZSBEYXRlRm9ybWF0LmdldERhdGVJbnN0YW5jZShEYXRlRm9ybWF0LkRFRkFVTFQsIGdldExvY2FsZSgpKX08L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZD57QGNvZGUgbG9uZ308L3RkPgorICogPHRkPntAY29kZSBEYXRlRm9ybWF0LmdldERhdGVJbnN0YW5jZShEYXRlRm9ybWF0LkxPTkcsIGdldExvY2FsZSgpKX08L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZD57QGNvZGUgZnVsbH08L3RkPgorICogPHRkPntAY29kZSBEYXRlRm9ybWF0LmdldERhdGVJbnN0YW5jZShEYXRlRm9ybWF0LkZVTEwsIGdldExvY2FsZSgpKX08L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZD48aT5TdWJmb3JtYXRQYXR0ZXJuPC9pPjwvdGQ+CisgKiA8dGQ+e0Bjb2RlIG5ldyBTaW1wbGVEYXRlRm9ybWF0KHN1YmZvcm1hdFBhdHRlcm4sIGdldExvY2FsZSgpKX08L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCByb3dzcGFuPSI2Ij57QGNvZGUgdGltZX08L3RkPgorICogPHRkPjxpPihub25lKTwvaT48L3RkPgorICogPHRkPntAY29kZSBEYXRlRm9ybWF0LmdldFRpbWVJbnN0YW5jZShEYXRlRm9ybWF0LkRFRkFVTFQsIGdldExvY2FsZSgpKX08L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZD57QGNvZGUgc2hvcnR9PC90ZD4KKyAqIDx0ZD57QGNvZGUgRGF0ZUZvcm1hdC5nZXRUaW1lSW5zdGFuY2UoRGF0ZUZvcm1hdC5TSE9SVCwgZ2V0TG9jYWxlKCkpfTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkPntAY29kZSBtZWRpdW19PC90ZD4KKyAqIDx0ZD57QGNvZGUgRGF0ZUZvcm1hdC5nZXRUaW1lSW5zdGFuY2UoRGF0ZUZvcm1hdC5ERUZBVUxULCBnZXRMb2NhbGUoKSl9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQ+e0Bjb2RlIGxvbmd9PC90ZD4KKyAqIDx0ZD57QGNvZGUgRGF0ZUZvcm1hdC5nZXRUaW1lSW5zdGFuY2UoRGF0ZUZvcm1hdC5MT05HLCBnZXRMb2NhbGUoKSl9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQ+e0Bjb2RlIGZ1bGx9PC90ZD4KKyAqIDx0ZD57QGNvZGUgRGF0ZUZvcm1hdC5nZXRUaW1lSW5zdGFuY2UoRGF0ZUZvcm1hdC5GVUxMLCBnZXRMb2NhbGUoKSl9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQ+PGk+U3ViZm9ybWF0UGF0dGVybjwvaT48L3RkPgorICogPHRkPntAY29kZSBuZXcgU2ltcGxlRGF0ZUZvcm1hdChzdWJmb3JtYXRQYXR0ZXJuLCBnZXRMb2NhbGUoKSl9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQ+e0Bjb2RlIGNob2ljZX08L3RkPgorICogPHRkPjxpPlN1YmZvcm1hdFBhdHRlcm48L2k+PC90ZD4KKyAqIDx0ZD57QGNvZGUgbmV3IENob2ljZUZvcm1hdChzdWJmb3JtYXRQYXR0ZXJuKX08L3RkPgorICogPC90cj4KKyAqIDwvdGFibGU+CisgKgorICogPGg0PlVzYWdlIEluZm9ybWF0aW9uPC9oND4KKyAqIDxwPgorICogSGVyZSBhcmUgc29tZSBleGFtcGxlcyBvZiB1c2FnZTogPGJsb2NrcXVvdGU+CisgKgorICogPHByZT4KKyAqIE9iamVjdFtdIGFyZ3VtZW50cyA9IHsKKyAqICAgICAgICAgSW50ZWdlci52YWx1ZU9mKDcpLCBuZXcgRGF0ZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSksCisgKiAgICAgICAgICJhIGRpc3R1cmJhbmNlIGluIHRoZSBGb3JjZSJ9OworICogU3RyaW5nIHJlc3VsdCA9IE1lc3NhZ2VGb3JtYXQuZm9ybWF0KAorICogICAgICAgICAiQXQgezEsdGltZX0gb24gezEsZGF0ZX0sIHRoZXJlIHdhcyB7Mn0gb24gcGxhbmV0IHswLG51bWJlcixpbnRlZ2VyfS4iLAorICogICAgICAgICBhcmd1bWVudHMpOworICogPGVtPgorICogT3V0cHV0OgorICogPC9lbT4KKyAqIEF0IDEyOjMwIFBNIG9uIEp1bCAzLCAyMDUzLCB0aGVyZSB3YXMgYSBkaXN0dXJiYW5jZSBpbiB0aGUgRm9yY2Ugb24gcGxhbmV0IDcuCisgKiA8L3ByZT4KKyAqCisgKiA8L2Jsb2NrcXVvdGU+CisgKiA8cD4KKyAqIFR5cGljYWxseSwgdGhlIG1lc3NhZ2UgZm9ybWF0IHdpbGwgY29tZSBmcm9tIHJlc291cmNlcywgYW5kIHRoZQorICogYXJndW1lbnRzIHdpbGwgYmUgZHluYW1pY2FsbHkgc2V0IGF0IHJ1bnRpbWUuCisgKiA8cD4KKyAqIEV4YW1wbGUgMjogPGJsb2NrcXVvdGU+CisgKgorICogPHByZT4KKyAqIE9iamVjdFtdIHRlc3RBcmdzID0ge0xvbmcudmFsdWVPZigzKSwgIk15RGlzayJ9OworICogTWVzc2FnZUZvcm1hdCBmb3JtID0gbmV3IE1lc3NhZ2VGb3JtYXQoIlRoZSBkaXNrIFwiezF9XCIgY29udGFpbnMgezB9IGZpbGUocykuIik7CisgKiBTeXN0ZW0ub3V0LnByaW50bG4oZm9ybS5mb3JtYXQodGVzdEFyZ3MpKTsKKyAqIDxlbT4KKyAqIE91dHB1dCB3aXRoIGRpZmZlcmVudCB0ZXN0QXJnczoKKyAqIDwvZW0+CisgKiBUaGUgZGlzayAiTXlEaXNrIiBjb250YWlucyAwIGZpbGUocykuCisgKiBUaGUgZGlzayAiTXlEaXNrIiBjb250YWlucyAxIGZpbGUocykuCisgKiBUaGUgZGlzayAiTXlEaXNrIiBjb250YWlucyAxLDI3MyBmaWxlKHMpLgorICogPC9wcmU+CisgKgorICogPC9ibG9ja3F1b3RlPgorICoKKyAqIDxwPgorICogRm9yIG1vcmUgc29waGlzdGljYXRlZCBwYXR0ZXJucywgeW91IGNhbiB1c2UgYSB7QGNvZGUgQ2hvaWNlRm9ybWF0fSB0bworICogZ2V0IG91dHB1dCBzdWNoIGFzOgorICogPGJsb2NrcXVvdGU+CisgKgorICogPHByZT4KKyAqIE1lc3NhZ2VGb3JtYXQgZm9ybSA9IG5ldyBNZXNzYWdlRm9ybWF0KCJUaGUgZGlzayBcInsxfVwiIGNvbnRhaW5zIHswfS4iKTsKKyAqIGRvdWJsZVtdIGZpbGVsaW1pdHMgPSB7MCwxLDJ9OworICogU3RyaW5nW10gZmlsZXBhcnQgPSB7Im5vIGZpbGVzIiwib25lIGZpbGUiLCJ7MCxudW1iZXJ9IGZpbGVzIn07CisgKiBDaG9pY2VGb3JtYXQgZmlsZWZvcm0gPSBuZXcgQ2hvaWNlRm9ybWF0KGZpbGVsaW1pdHMsIGZpbGVwYXJ0KTsKKyAqIGZvcm0uc2V0Rm9ybWF0QnlBcmd1bWVudEluZGV4KDAsIGZpbGVmb3JtKTsKKyAqIE9iamVjdFtdIHRlc3RBcmdzID0ge0xvbmcudmFsdWVPZigxMjM3MyksICJNeURpc2sifTsKKyAqIFN5c3RlbS5vdXQucHJpbnRsbihmb3JtLmZvcm1hdCh0ZXN0QXJncykpOworICogPGVtPgorICogT3V0cHV0ICh3aXRoIGRpZmZlcmVudCB0ZXN0QXJncyk6CisgKiA8L2VtPgorICogVGhlIGRpc2sgIk15RGlzayIgY29udGFpbnMgbm8gZmlsZXMuCisgKiBUaGUgZGlzayAiTXlEaXNrIiBjb250YWlucyBvbmUgZmlsZS4KKyAqIFRoZSBkaXNrICJNeURpc2siIGNvbnRhaW5zIDEsMjczIGZpbGVzLgorICogPC9wcmU+CisgKgorICogPC9ibG9ja3F1b3RlPiBZb3UgY2FuIGVpdGhlciBkbyB0aGlzIHByb2dyYW1tYXRpY2FsbHksIGFzIGluIHRoZSBhYm92ZQorICogZXhhbXBsZSwgb3IgYnkgdXNpbmcgYSBwYXR0ZXJuIChzZWUge0BsaW5rIENob2ljZUZvcm1hdH0gZm9yIG1vcmUKKyAqIGluZm9ybWF0aW9uKSBhcyBpbjogPGJsb2NrcXVvdGU+CisgKgorICogPHByZT4KKyAqIGZvcm0uYXBwbHlQYXR0ZXJuKCJUaGVyZSB7MCxjaG9pY2UsMCNhcmUgbm8gZmlsZXN8MSNpcyBvbmUgZmlsZXwxJmx0O2FyZSB7MCxudW1iZXIsaW50ZWdlcn0gZmlsZXN9LiIpOworICogPC9wcmU+CisgKgorICogPC9ibG9ja3F1b3RlPgorICogPHA+CisgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IEFzIHdlIHNlZSBhYm92ZSwgdGhlIHN0cmluZyBwcm9kdWNlZCBieSBhCisgKiB7QGNvZGUgQ2hvaWNlRm9ybWF0fSBpbiB7QGNvZGUgTWVzc2FnZUZvcm1hdH0gaXMgdHJlYXRlZAorICogc3BlY2lhbGx5OyBvY2N1cmFuY2VzIG9mICd7JyBhcmUgdXNlZCB0byBpbmRpY2F0ZWQgc3ViZm9ybWF0cywgYW5kIGNhdXNlCisgKiByZWN1cnNpb24uIElmIHlvdSBjcmVhdGUgYm90aCBhIHtAY29kZSBNZXNzYWdlRm9ybWF0fSBhbmQKKyAqIHtAY29kZSBDaG9pY2VGb3JtYXR9IHByb2dyYW1tYXRpY2FsbHkgKGluc3RlYWQgb2YgdXNpbmcgdGhlIHN0cmluZworICogcGF0dGVybnMpLCB0aGVuIGJlIGNhcmVmdWwgbm90IHRvIHByb2R1Y2UgYSBmb3JtYXQgdGhhdCByZWN1cnNlcyBvbiBpdHNlbGYsCisgKiB3aGljaCB3aWxsIGNhdXNlIGFuIGluZmluaXRlIGxvb3AuCisgKiA8cD4KKyAqIFdoZW4gYSBzaW5nbGUgYXJndW1lbnQgaXMgcGFyc2VkIG1vcmUgdGhhbiBvbmNlIGluIHRoZSBzdHJpbmcsIHRoZSBsYXN0IG1hdGNoCisgKiB3aWxsIGJlIHRoZSBmaW5hbCByZXN1bHQgb2YgdGhlIHBhcnNpbmcuIEZvciBleGFtcGxlOgorICogPGJsb2NrcXVvdGU+CisgKiA8cHJlPgorICogTWVzc2FnZUZvcm1hdCBtZiA9IG5ldyBNZXNzYWdlRm9ybWF0KCJ7MCxudW1iZXIsIy4jI30sIHswLG51bWJlciwjLiN9Iik7CisgKiBPYmplY3RbXSBvYmpzID0ge25ldyBEb3VibGUoMy4xNDE1KX07CisgKiBTdHJpbmcgcmVzdWx0ID0gbWYuZm9ybWF0KG9ianMpOworICogLy8gcmVzdWx0IG5vdyBlcXVhbHMgIjMuMTQsIDMuMSIKKyAqIG9ianMgPSBudWxsOworICogb2JqcyA9IG1mLnBhcnNlKHJlc3VsdCwgbmV3IFBhcnNlUG9zaXRpb24oMCkpOworICogLy8gb2JqcyBub3cgZXF1YWxzIHtuZXcgRG91YmxlKDMuMSl9CisgKiA8L3ByZT4KKyAqIDwvYmxvY2txdW90ZT4KKyAqIDxwPgorICogTGlrZXdpc2UsIHBhcnNpbmcgd2l0aCBhIHtAY29kZSBNZXNzYWdlRm9ybWF0fSBvYmplY3QgdXNpbmcgcGF0dGVybnMKKyAqIGNvbnRhaW5pbmcgbXVsdGlwbGUgb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgYXJndW1lbnQgd291bGQgcmV0dXJuIHRoZSBsYXN0CisgKiBtYXRjaC4gRm9yIGV4YW1wbGU6CisgKiA8YmxvY2txdW90ZT4KKyAqIDxwcmU+CisgKiBNZXNzYWdlRm9ybWF0IG1mID0gbmV3IE1lc3NhZ2VGb3JtYXQoInswfSwgezB9LCB7MH0iKTsKKyAqIFN0cmluZyBmb3JQYXJzaW5nID0gIngsIHksIHoiOworICogT2JqZWN0W10gb2JqcyA9IG1mLnBhcnNlKGZvclBhcnNpbmcsIG5ldyBQYXJzZVBvc2l0aW9uKDApKTsKKyAqIC8vIHJlc3VsdCBub3cgZXF1YWxzIHtuZXcgU3RyaW5nKCJ6Iil9CisgKiA8L3ByZT4KKyAqIDwvYmxvY2txdW90ZT4KKyAqIDxoND48YSBuYW1lPSJzeW5jaHJvbml6YXRpb24iPlN5bmNocm9uaXphdGlvbjwvYT48L2g0PgorICogPHA+CisgKiBNZXNzYWdlIGZvcm1hdHMgYXJlIG5vdCBzeW5jaHJvbml6ZWQuIEl0IGlzIHJlY29tbWVuZGVkIHRvIGNyZWF0ZSBzZXBhcmF0ZQorICogZm9ybWF0IGluc3RhbmNlcyBmb3IgZWFjaCB0aHJlYWQuIElmIG11bHRpcGxlIHRocmVhZHMgYWNjZXNzIGEgZm9ybWF0CisgKiBjb25jdXJyZW50bHksIGl0IG11c3QgYmUgc3luY2hyb25pemVkIGV4dGVybmFsbHkuCisgKgorICogQHNlZSBqYXZhLnV0aWwuRm9ybWF0dGVyCisgKi8KK3B1YmxpYyBjbGFzcyBNZXNzYWdlRm9ybWF0IGV4dGVuZHMgRm9ybWF0IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDY0NzkxNTczMDY3ODQwMjI5NTJMOworCisgICAgcHJpdmF0ZSBMb2NhbGUgbG9jYWxlOworCisgICAgdHJhbnNpZW50IHByaXZhdGUgU3RyaW5nW10gc3RyaW5nczsKKworICAgIHByaXZhdGUgaW50W10gYXJndW1lbnROdW1iZXJzOworCisgICAgcHJpdmF0ZSBGb3JtYXRbXSBmb3JtYXRzOworCisgICAgcHJpdmF0ZSBpbnQgbWF4T2Zmc2V0OworCisgICAgdHJhbnNpZW50IHByaXZhdGUgaW50IG1heEFyZ3VtZW50SW5kZXg7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBNZXNzYWdlRm9ybWF0fSB1c2luZyB0aGUgc3BlY2lmaWVkIHBhdHRlcm4gYW5kIHtAY29kZSBsb2NhbGV9LgorICAgICAqCisgICAgICogQHBhcmFtIHRlbXBsYXRlCisgICAgICogICAgICAgICAgICB0aGUgcGF0dGVybi4KKyAgICAgKiBAcGFyYW0gbG9jYWxlCisgICAgICogICAgICAgICAgICB0aGUgbG9jYWxlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICBpZiB0aGUgcGF0dGVybiBjYW5ub3QgYmUgcGFyc2VkLgorICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlRm9ybWF0KFN0cmluZyB0ZW1wbGF0ZSwgTG9jYWxlIGxvY2FsZSkgeworICAgICAgICB0aGlzLmxvY2FsZSA9IGxvY2FsZTsKKyAgICAgICAgYXBwbHlQYXR0ZXJuKHRlbXBsYXRlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBNZXNzYWdlRm9ybWF0fSB1c2luZyB0aGUgc3BlY2lmaWVkIHBhdHRlcm4gYW5kCisgICAgICogdGhlIHVzZXIncyBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKiBTZWUgIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGVtcGxhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXR0ZXJuLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICBpZiB0aGUgcGF0dGVybiBjYW5ub3QgYmUgcGFyc2VkLgorICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlRm9ybWF0KFN0cmluZyB0ZW1wbGF0ZSkgeworICAgICAgICB0aGlzKHRlbXBsYXRlLCBMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGFuZ2VzIHRoaXMge0Bjb2RlIE1lc3NhZ2VGb3JtYXR9IHRvIHVzZSB0aGUgc3BlY2lmaWVkIHBhdHRlcm4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGVtcGxhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgcGF0dGVybi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYgdGhlIHBhdHRlcm4gY2Fubm90IGJlIHBhcnNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhcHBseVBhdHRlcm4oU3RyaW5nIHRlbXBsYXRlKSB7CisgICAgICAgIGludCBsZW5ndGggPSB0ZW1wbGF0ZS5sZW5ndGgoKTsKKyAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgUGFyc2VQb3NpdGlvbiBwb3NpdGlvbiA9IG5ldyBQYXJzZVBvc2l0aW9uKDApOworICAgICAgICBBcnJheUxpc3Q8U3RyaW5nPiBsb2NhbFN0cmluZ3MgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgaW50IGFyZ0NvdW50ID0gMDsKKyAgICAgICAgaW50W10gYXJncyA9IG5ldyBpbnRbMTBdOworICAgICAgICBpbnQgbWF4QXJnID0gLTE7CisgICAgICAgIEFycmF5TGlzdDxGb3JtYXQ+IGxvY2FsRm9ybWF0cyA9IG5ldyBBcnJheUxpc3Q8Rm9ybWF0PigpOworICAgICAgICB3aGlsZSAocG9zaXRpb24uZ2V0SW5kZXgoKSA8IGxlbmd0aCkgeworICAgICAgICAgICAgaWYgKEZvcm1hdC51cFRvKHRlbXBsYXRlLCBwb3NpdGlvbiwgYnVmZmVyLCAneycpKSB7CisgICAgICAgICAgICAgICAgaW50IGFyZyA9IDA7CisgICAgICAgICAgICAgICAgaW50IG9mZnNldCA9IHBvc2l0aW9uLmdldEluZGV4KCk7CisgICAgICAgICAgICAgICAgaWYgKG9mZnNldCA+PSBsZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBhcmd1bWVudCBudW1iZXIiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gR2V0IGFyZ3VtZW50IG51bWJlcgorICAgICAgICAgICAgICAgIGNoYXIgY2g7CisgICAgICAgICAgICAgICAgd2hpbGUgKChjaCA9IHRlbXBsYXRlLmNoYXJBdChvZmZzZXQrKykpICE9ICd9JyAmJiBjaCAhPSAnLCcpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNoIDwgJzAnICYmIGNoID4gJzknKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIGFyZ3VtZW50IG51bWJlciIpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgYXJnID0gYXJnICogMTAgKyAoY2ggLSAnMCcpOworCisgICAgICAgICAgICAgICAgICAgIGlmIChhcmcgPCAwIHx8IG9mZnNldCA+PSBsZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgYXJndW1lbnQgbnVtYmVyIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgb2Zmc2V0LS07CisgICAgICAgICAgICAgICAgcG9zaXRpb24uc2V0SW5kZXgob2Zmc2V0KTsKKyAgICAgICAgICAgICAgICBsb2NhbEZvcm1hdHMuYWRkKHBhcnNlVmFyaWFibGUodGVtcGxhdGUsIHBvc2l0aW9uKSk7CisgICAgICAgICAgICAgICAgaWYgKGFyZ0NvdW50ID49IGFyZ3MubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIGludFtdIG5ld0FyZ3MgPSBuZXcgaW50W2FyZ3MubGVuZ3RoICogMl07CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYXJncywgMCwgbmV3QXJncywgMCwgYXJncy5sZW5ndGgpOworICAgICAgICAgICAgICAgICAgICBhcmdzID0gbmV3QXJnczsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXJnc1thcmdDb3VudCsrXSA9IGFyZzsKKyAgICAgICAgICAgICAgICBpZiAoYXJnID4gbWF4QXJnKSB7CisgICAgICAgICAgICAgICAgICAgIG1heEFyZyA9IGFyZzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsb2NhbFN0cmluZ3MuYWRkKGJ1ZmZlci50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGJ1ZmZlci5zZXRMZW5ndGgoMCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zdHJpbmdzID0gbG9jYWxTdHJpbmdzLnRvQXJyYXkobmV3IFN0cmluZ1tsb2NhbFN0cmluZ3Muc2l6ZSgpXSk7CisgICAgICAgIGFyZ3VtZW50TnVtYmVycyA9IGFyZ3M7CisgICAgICAgIHRoaXMuZm9ybWF0cyA9IGxvY2FsRm9ybWF0cy50b0FycmF5KG5ldyBGb3JtYXRbYXJnQ291bnRdKTsKKyAgICAgICAgbWF4T2Zmc2V0ID0gYXJnQ291bnQgLSAxOworICAgICAgICBtYXhBcmd1bWVudEluZGV4ID0gbWF4QXJnOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIE1lc3NhZ2VGb3JtYXR9IHdpdGggdGhlIHNhbWUgcGF0dGVybiBhbmQKKyAgICAgKiBmb3JtYXRzIGFzIHRoaXMge0Bjb2RlIE1lc3NhZ2VGb3JtYXR9LgorICAgICAqCisgICAgICogQHJldHVybiBhIHNoYWxsb3cgY29weSBvZiB0aGlzIHtAY29kZSBNZXNzYWdlRm9ybWF0fS4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5DbG9uZWFibGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICBNZXNzYWdlRm9ybWF0IGNsb25lID0gKE1lc3NhZ2VGb3JtYXQpIHN1cGVyLmNsb25lKCk7CisgICAgICAgIEZvcm1hdFtdIGFycmF5ID0gbmV3IEZvcm1hdFtmb3JtYXRzLmxlbmd0aF07CisgICAgICAgIGZvciAoaW50IGkgPSBmb3JtYXRzLmxlbmd0aDsgLS1pID49IDA7KSB7CisgICAgICAgICAgICBpZiAoZm9ybWF0c1tpXSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYXJyYXlbaV0gPSAoRm9ybWF0KSBmb3JtYXRzW2ldLmNsb25lKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY2xvbmUuZm9ybWF0cyA9IGFycmF5OworICAgICAgICByZXR1cm4gY2xvbmU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBvYmplY3QgdG8gdGhpcyB7QGNvZGUgTWVzc2FnZUZvcm1hdH0gYW5kIGluZGljYXRlcworICAgICAqIGlmIHRoZXkgYXJlIGVxdWFsLiBJbiBvcmRlciB0byBiZSBlcXVhbCwge0Bjb2RlIG9iamVjdH0gbXVzdCBiZSBhbgorICAgICAqIGluc3RhbmNlIG9mIHtAY29kZSBNZXNzYWdlRm9ybWF0fSBhbmQgaGF2ZSB0aGUgc2FtZSBwYXR0ZXJuLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHdpdGggdGhpcyBvYmplY3QuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgZXF1YWwgdG8gdGhpcworICAgICAqICAgICAgICAge0Bjb2RlIE1lc3NhZ2VGb3JtYXR9OyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNoYXNoQ29kZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmICh0aGlzID09IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCEob2JqZWN0IGluc3RhbmNlb2YgTWVzc2FnZUZvcm1hdCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBNZXNzYWdlRm9ybWF0IGZvcm1hdCA9IChNZXNzYWdlRm9ybWF0KSBvYmplY3Q7CisgICAgICAgIGlmIChtYXhPZmZzZXQgIT0gZm9ybWF0Lm1heE9mZnNldCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIC8vIE11c3QgdXNlIGEgbG9vcCBzaW5jZSB0aGUgbGVuZ3RocyBtYXkgYmUgZGlmZmVyZW50IGR1ZQorICAgICAgICAvLyB0byBzZXJpYWxpemF0aW9uIGNyb3NzLWxvYWRpbmcKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gbWF4T2Zmc2V0OyBpKyspIHsKKyAgICAgICAgICAgIGlmIChhcmd1bWVudE51bWJlcnNbaV0gIT0gZm9ybWF0LmFyZ3VtZW50TnVtYmVyc1tpXSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbG9jYWxlLmVxdWFscyhmb3JtYXQubG9jYWxlKQorICAgICAgICAgICAgICAgICYmIEFycmF5cy5lcXVhbHMoc3RyaW5ncywgZm9ybWF0LnN0cmluZ3MpCisgICAgICAgICAgICAgICAgJiYgQXJyYXlzLmVxdWFscyhmb3JtYXRzLCBmb3JtYXQuZm9ybWF0cyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRm9ybWF0cyB0aGUgc3BlY2lmaWVkIG9iamVjdCB1c2luZyB0aGUgcnVsZXMgb2YgdGhpcyBtZXNzYWdlIGZvcm1hdCBhbmQKKyAgICAgKiByZXR1cm5zIGFuIHtAY29kZSBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3J9IHdpdGggdGhlIGZvcm1hdHRlZCBtZXNzYWdlIGFuZAorICAgICAqIGF0dHJpYnV0ZXMuIFRoZSB7QGNvZGUgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yfSByZXR1cm5lZCBhbHNvIGluY2x1ZGVzIHRoZQorICAgICAqIGF0dHJpYnV0ZXMgZnJvbSB0aGUgZm9ybWF0cyBvZiB0aGlzIG1lc3NhZ2UgZm9ybWF0LgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBmb3JtYXQuCisgICAgICogQHJldHVybiBhbiB7QGNvZGUgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yfSB3aXRoIHRoZSBmb3JtYXR0ZWQgbWVzc2FnZSBhbmQKKyAgICAgKiAgICAgICAgIGF0dHJpYnV0ZXMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIGlmIHRoZSBhcmd1bWVudHMgaW4gdGhlIG9iamVjdCBhcnJheSBjYW5ub3QgYmUgZm9ybWF0dGVkCisgICAgICogICAgICAgICAgICBieSB0aGlzIG1lc3NhZ2UgZm9ybWF0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcihPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBBcnJheUxpc3Q8RmllbGRDb250YWluZXI+IGZpZWxkcyA9IG5ldyBBcnJheUxpc3Q8RmllbGRDb250YWluZXI+KCk7CisKKyAgICAgICAgLy8gZm9ybWF0IHRoZSBtZXNzYWdlLCBhbmQgZmluZCBmaWVsZHMKKyAgICAgICAgZm9ybWF0SW1wbCgoT2JqZWN0W10pIG9iamVjdCwgYnVmZmVyLCBuZXcgRmllbGRQb3NpdGlvbigwKSwgZmllbGRzKTsKKworICAgICAgICAvLyBjcmVhdGUgYW4gQXR0cmlidXRlZFN0cmluZyB3aXRoIHRoZSBmb3JtYXR0ZWQgYnVmZmVyCisgICAgICAgIEF0dHJpYnV0ZWRTdHJpbmcgYXMgPSBuZXcgQXR0cmlidXRlZFN0cmluZyhidWZmZXIudG9TdHJpbmcoKSk7CisKKyAgICAgICAgLy8gYWRkIE1lc3NhZ2VGb3JtYXQgZmllbGQgYXR0cmlidXRlcyBhbmQgdmFsdWVzIHRvIHRoZSBBdHRyaWJ1dGVkU3RyaW5nCisgICAgICAgIGZvciAoRmllbGRDb250YWluZXIgZmMgOiBmaWVsZHMpIHsKKyAgICAgICAgICAgIGFzLmFkZEF0dHJpYnV0ZShmYy5hdHRyaWJ1dGUsIGZjLnZhbHVlLCBmYy5zdGFydCwgZmMuZW5kKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHJldHVybiB0aGUgQ2hhcmFjdGVySXRlcmF0b3IgZnJvbSBBdHRyaWJ1dGVkU3RyaW5nCisgICAgICAgIHJldHVybiBhcy5nZXRJdGVyYXRvcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0cyBpbnRvIGEgc3RyaW5nIHdoaWNoIGl0IGFwcGVuZHMgdG8gdGhlCisgICAgICogc3BlY2lmaWVkIHN0cmluZyBidWZmZXIgdXNpbmcgdGhlIHBhdHRlcm4gb2YgdGhpcyBtZXNzYWdlIGZvcm1hdC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUge0Bjb2RlIGZpZWxkfSBtZW1iZXIgb2YgdGhlIHNwZWNpZmllZCB7QGNvZGUgRmllbGRQb3NpdGlvbn0gaXMKKyAgICAgKiB7QGNvZGUgTWVzc2FnZUZvcm1hdC5GaWVsZC5BUkdVTUVOVH0sIHRoZW4gdGhlIGJlZ2luIGFuZCBlbmQgaW5kZXggb2YKKyAgICAgKiB0aGlzIGZpZWxkIHBvc2l0aW9uIGlzIHNldCB0byB0aGUgbG9jYXRpb24gb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYQorICAgICAqIG1lc3NhZ2UgZm9ybWF0IGFyZ3VtZW50LiBPdGhlcndpc2UsIHRoZSB7QGNvZGUgRmllbGRQb3NpdGlvbn0gaXMgaWdub3JlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3RzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2Ygb2JqZWN0cyB0byBmb3JtYXQuCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBzdHJpbmcgYnVmZmVyIHRvIGFwcGVuZCB0aGUgZm9ybWF0dGVkIG1lc3NhZ2UgdG8uCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICBvbiBpbnB1dDogYW4gb3B0aW9uYWwgYWxpZ25tZW50IGZpZWxkOyBvbiBvdXRwdXQ6IHRoZSBvZmZzZXRzCisgICAgICogICAgICAgICAgICBvZiB0aGUgYWxpZ25tZW50IGZpZWxkIGluIHRoZSBmb3JtYXR0ZWQgdGV4dC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmdCdWZmZXIgZm9ybWF0KE9iamVjdFtdIG9iamVjdHMsIFN0cmluZ0J1ZmZlciBidWZmZXIsCisgICAgICAgICAgICBGaWVsZFBvc2l0aW9uIGZpZWxkKSB7CisgICAgICAgIHJldHVybiBmb3JtYXRJbXBsKG9iamVjdHMsIGJ1ZmZlciwgZmllbGQsIG51bGwpOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nQnVmZmVyIGZvcm1hdEltcGwoT2JqZWN0W10gb2JqZWN0cywgU3RyaW5nQnVmZmVyIGJ1ZmZlciwKKyAgICAgICAgICAgIEZpZWxkUG9zaXRpb24gcG9zaXRpb24sIExpc3Q8RmllbGRDb250YWluZXI+IGZpZWxkcykgeworICAgICAgICBGaWVsZFBvc2l0aW9uIHBhc3NlZEZpZWxkID0gbmV3IEZpZWxkUG9zaXRpb24oMCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IG1heE9mZnNldDsgaSsrKSB7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKHN0cmluZ3NbaV0pOworICAgICAgICAgICAgaW50IGJlZ2luID0gYnVmZmVyLmxlbmd0aCgpOworICAgICAgICAgICAgT2JqZWN0IGFyZzsKKyAgICAgICAgICAgIGlmIChvYmplY3RzICE9IG51bGwgJiYgYXJndW1lbnROdW1iZXJzW2ldIDwgb2JqZWN0cy5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBhcmcgPSBvYmplY3RzW2FyZ3VtZW50TnVtYmVyc1tpXV07CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJ3snKTsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGFyZ3VtZW50TnVtYmVyc1tpXSk7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnfScpOworICAgICAgICAgICAgICAgIGhhbmRsZUFyZ3VtZW50RmllbGQoYmVnaW4sIGJ1ZmZlci5sZW5ndGgoKSwgYXJndW1lbnROdW1iZXJzW2ldLCBwb3NpdGlvbiwgZmllbGRzKTsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEZvcm1hdCBmb3JtYXQgPSBmb3JtYXRzW2ldOworICAgICAgICAgICAgaWYgKGZvcm1hdCA9PSBudWxsIHx8IGFyZyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWYgKGFyZyBpbnN0YW5jZW9mIE51bWJlcikgeworICAgICAgICAgICAgICAgICAgICBmb3JtYXQgPSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFyZyBpbnN0YW5jZW9mIERhdGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZm9ybWF0ID0gRGF0ZUZvcm1hdC5nZXRJbnN0YW5jZSgpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoYXJnKTsKKyAgICAgICAgICAgICAgICAgICAgaGFuZGxlQXJndW1lbnRGaWVsZChiZWdpbiwgYnVmZmVyLmxlbmd0aCgpLCBhcmd1bWVudE51bWJlcnNbaV0sIHBvc2l0aW9uLCBmaWVsZHMpOworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZm9ybWF0IGluc3RhbmNlb2YgQ2hvaWNlRm9ybWF0KSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGZvcm1hdC5mb3JtYXQoYXJnKTsKKyAgICAgICAgICAgICAgICBNZXNzYWdlRm9ybWF0IG1mID0gbmV3IE1lc3NhZ2VGb3JtYXQocmVzdWx0KTsKKyAgICAgICAgICAgICAgICBtZi5zZXRMb2NhbGUobG9jYWxlKTsKKyAgICAgICAgICAgICAgICBtZi5mb3JtYXQob2JqZWN0cywgYnVmZmVyLCBwYXNzZWRGaWVsZCk7CisgICAgICAgICAgICAgICAgaGFuZGxlQXJndW1lbnRGaWVsZChiZWdpbiwgYnVmZmVyLmxlbmd0aCgpLCBhcmd1bWVudE51bWJlcnNbaV0sIHBvc2l0aW9uLCBmaWVsZHMpOworICAgICAgICAgICAgICAgIGhhbmRsZUZvcm1hdChmb3JtYXQsIGFyZywgYmVnaW4sIGZpZWxkcyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZvcm1hdC5mb3JtYXQoYXJnLCBidWZmZXIsIHBhc3NlZEZpZWxkKTsKKyAgICAgICAgICAgICAgICBoYW5kbGVBcmd1bWVudEZpZWxkKGJlZ2luLCBidWZmZXIubGVuZ3RoKCksIGFyZ3VtZW50TnVtYmVyc1tpXSwgcG9zaXRpb24sIGZpZWxkcyk7CisgICAgICAgICAgICAgICAgaGFuZGxlRm9ybWF0KGZvcm1hdCwgYXJnLCBiZWdpbiwgZmllbGRzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAobWF4T2Zmc2V0ICsgMSA8IHN0cmluZ3MubGVuZ3RoKSB7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKHN0cmluZ3NbbWF4T2Zmc2V0ICsgMV0pOworICAgICAgICB9CisgICAgICAgIHJldHVybiBidWZmZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBhIG5ldyBGaWVsZENvbnRhaW5lciB3aXRoIE1lc3NhZ2VGb3JtYXQuRmllbGQuQVJHVU1FTlQgZmllbGQsCisgICAgICogYXJnSW5kZXgsIGJlZ2luIGFuZCBlbmQgaW5kZXggdG8gdGhlIGZpZWxkcyBsaXN0LCBvciBzZXRzIHRoZQorICAgICAqIHBvc2l0aW9uJ3MgYmVnaW4gYW5kIGVuZCBpbmRleCBpZiBpdCBoYXMgTWVzc2FnZUZvcm1hdC5GaWVsZC5BUkdVTUVOVCBhcworICAgICAqIGl0cyBmaWVsZCBhdHRyaWJ1dGUuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGhhbmRsZUFyZ3VtZW50RmllbGQoaW50IGJlZ2luLCBpbnQgZW5kLCBpbnQgYXJnSW5kZXgsCisgICAgICAgICAgICBGaWVsZFBvc2l0aW9uIHBvc2l0aW9uLCBMaXN0PEZpZWxkQ29udGFpbmVyPiBmaWVsZHMpIHsKKyAgICAgICAgaWYgKGZpZWxkcyAhPSBudWxsKSB7CisgICAgICAgICAgICBmaWVsZHMuYWRkKG5ldyBGaWVsZENvbnRhaW5lcihiZWdpbiwgZW5kLCBGaWVsZC5BUkdVTUVOVCwgSW50ZWdlci52YWx1ZU9mKGFyZ0luZGV4KSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKHBvc2l0aW9uICE9IG51bGwKKyAgICAgICAgICAgICAgICAgICAgJiYgcG9zaXRpb24uZ2V0RmllbGRBdHRyaWJ1dGUoKSA9PSBGaWVsZC5BUkdVTUVOVAorICAgICAgICAgICAgICAgICAgICAmJiBwb3NpdGlvbi5nZXRFbmRJbmRleCgpID09IDApIHsKKyAgICAgICAgICAgICAgICBwb3NpdGlvbi5zZXRCZWdpbkluZGV4KGJlZ2luKTsKKyAgICAgICAgICAgICAgICBwb3NpdGlvbi5zZXRFbmRJbmRleChlbmQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQW4gaW5uZXIgY2xhc3MgdG8gc3RvcmUgYXR0cmlidXRlcywgdmFsdWVzLCBzdGFydCBhbmQgZW5kIGluZGljZXMuCisgICAgICogSW5zdGFuY2VzIG9mIHRoaXMgaW5uZXIgY2xhc3MgYXJlIHVzZWQgYXMgZWxlbWVudHMgZm9yIHRoZSBmaWVsZHMgbGlzdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBGaWVsZENvbnRhaW5lciB7CisgICAgICAgIGludCBzdGFydCwgZW5kOworCisgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUgYXR0cmlidXRlOworCisgICAgICAgIE9iamVjdCB2YWx1ZTsKKworICAgICAgICBwdWJsaWMgRmllbGRDb250YWluZXIoaW50IHN0YXJ0LCBpbnQgZW5kLAorICAgICAgICAgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUgYXR0cmlidXRlLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgICAgIHRoaXMuc3RhcnQgPSBzdGFydDsKKyAgICAgICAgICAgIHRoaXMuZW5kID0gZW5kOworICAgICAgICAgICAgdGhpcy5hdHRyaWJ1dGUgPSBhdHRyaWJ1dGU7CisgICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiBmaWVsZHMgbGlzdCBpcyBub3QgbnVsbCwgZmluZCBhbmQgYWRkIHRoZSBmaWVsZHMgb2YgdGhpcyBmb3JtYXQgdG8KKyAgICAgKiB0aGUgZmllbGRzIGxpc3QgYnkgaXRlcmF0aW5nIHRocm91Z2ggaXRzIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcgorICAgICAqCisgICAgICogQHBhcmFtIGZvcm1hdAorICAgICAqICAgICAgICAgICAgdGhlIGZvcm1hdCB0byBmaW5kIGZpZWxkcyBmb3IKKyAgICAgKiBAcGFyYW0gYXJnCisgICAgICogICAgICAgICAgICBvYmplY3QgdG8gZm9ybWF0CisgICAgICogQHBhcmFtIGJlZ2luCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggd2hlcmUgdGhlIHN0cmluZyB0aGlzIGZvcm1hdCBoYXMgZm9ybWF0dGVkIGJlZ2lucworICAgICAqLworICAgIHByaXZhdGUgdm9pZCBoYW5kbGVGb3JtYXQoRm9ybWF0IGZvcm1hdCwgT2JqZWN0IGFyZywgaW50IGJlZ2luLCBMaXN0PEZpZWxkQ29udGFpbmVyPiBmaWVsZHMpIHsKKyAgICAgICAgaWYgKGZpZWxkcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGl0ZXJhdG9yID0gZm9ybWF0LmZvcm1hdFRvQ2hhcmFjdGVySXRlcmF0b3IoYXJnKTsKKyAgICAgICAgd2hpbGUgKGl0ZXJhdG9yLmdldEluZGV4KCkgIT0gaXRlcmF0b3IuZ2V0RW5kSW5kZXgoKSkgeworICAgICAgICAgICAgaW50IHN0YXJ0ID0gaXRlcmF0b3IuZ2V0UnVuU3RhcnQoKTsKKyAgICAgICAgICAgIGludCBlbmQgPSBpdGVyYXRvci5nZXRSdW5MaW1pdCgpOworICAgICAgICAgICAgSXRlcmF0b3I8Pz4gaXQgPSBpdGVyYXRvci5nZXRBdHRyaWJ1dGVzKCkua2V5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlIGF0dHJpYnV0ZSA9CisgICAgICAgICAgICAgICAgICAgICAgICAoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSkgaXQubmV4dCgpOworICAgICAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IGl0ZXJhdG9yLmdldEF0dHJpYnV0ZShhdHRyaWJ1dGUpOworICAgICAgICAgICAgICAgIGZpZWxkcy5hZGQobmV3IEZpZWxkQ29udGFpbmVyKGJlZ2luICsgc3RhcnQsIGJlZ2luICsgZW5kLCBhdHRyaWJ1dGUsIHZhbHVlKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpdGVyYXRvci5zZXRJbmRleChlbmQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhlIHNwZWNpZmllZCBvYmplY3RzIGludG8gYSBzdHJpbmcgd2hpY2ggaXQgYXBwZW5kcyB0byB0aGUKKyAgICAgKiBzcGVjaWZpZWQgc3RyaW5nIGJ1ZmZlciB1c2luZyB0aGUgcGF0dGVybiBvZiB0aGlzIG1lc3NhZ2UgZm9ybWF0LgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSB7QGNvZGUgZmllbGR9IG1lbWJlciBvZiB0aGUgc3BlY2lmaWVkIHtAY29kZSBGaWVsZFBvc2l0aW9ufSBpcworICAgICAqIHtAY29kZSBNZXNzYWdlRm9ybWF0LkZpZWxkLkFSR1VNRU5UfSwgdGhlbiB0aGUgYmVnaW4gYW5kIGVuZCBpbmRleCBvZgorICAgICAqIHRoaXMgZmllbGQgcG9zaXRpb24gaXMgc2V0IHRvIHRoZSBsb2NhdGlvbiBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBhCisgICAgICogbWVzc2FnZSBmb3JtYXQgYXJndW1lbnQuIE90aGVyd2lzZSwgdGhlIHtAY29kZSBGaWVsZFBvc2l0aW9ufSBpcyBpZ25vcmVkLgorICAgICAqIDxwPgorICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byBjYWxsaW5nCisgICAgICogPGJsb2NrcXVvdGU+CisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqIGZvcm1hdCgoT2JqZWN0W10pb2JqZWN0LCBidWZmZXIsIGZpZWxkKQorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogPC9ibG9ja3F1b3RlPgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBmb3JtYXQsIG11c3QgYmUgYW4gYXJyYXkgb2Yge0Bjb2RlIE9iamVjdH0uCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBzdHJpbmcgYnVmZmVyIHRvIGFwcGVuZCB0aGUgZm9ybWF0dGVkIG1lc3NhZ2UgdG8uCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICBvbiBpbnB1dDogYW4gb3B0aW9uYWwgYWxpZ25tZW50IGZpZWxkOyBvbiBvdXRwdXQ6IHRoZSBvZmZzZXRzCisgICAgICogICAgICAgICAgICBvZiB0aGUgYWxpZ25tZW50IGZpZWxkIGluIHRoZSBmb3JtYXR0ZWQgdGV4dC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9iamVjdH0gaXMgbm90IGFuIGFycmF5IG9mIHtAY29kZSBPYmplY3R9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBTdHJpbmdCdWZmZXIgZm9ybWF0KE9iamVjdCBvYmplY3QsIFN0cmluZ0J1ZmZlciBidWZmZXIsCisgICAgICAgICAgICBGaWVsZFBvc2l0aW9uIGZpZWxkKSB7CisgICAgICAgIHJldHVybiBmb3JtYXQoKE9iamVjdFtdKSBvYmplY3QsIGJ1ZmZlciwgZmllbGQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZvcm1hdHMgdGhlIHN1cHBsaWVkIG9iamVjdHMgdXNpbmcgdGhlIHNwZWNpZmllZCBtZXNzYWdlIGZvcm1hdCBwYXR0ZXJuLgorICAgICAqCisgICAgICogQHBhcmFtIGZvcm1hdCB0aGUgZm9ybWF0IHN0cmluZyAoc2VlIHtAbGluayBqYXZhLnV0aWwuRm9ybWF0dGVyI2Zvcm1hdH0pCisgICAgICogQHBhcmFtIGFyZ3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IG9mIGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhlIGZvcm1hdHRlci4gSWYgdGhlcmUgYXJlCisgICAgICogICAgICAgICAgICBtb3JlIGFyZ3VtZW50cyB0aGFuIHJlcXVpcmVkIGJ5IHtAY29kZSBmb3JtYXR9LAorICAgICAqICAgICAgICAgICAgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIGlnbm9yZWQuCisgICAgICogQHJldHVybiB0aGUgZm9ybWF0dGVkIHJlc3VsdC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYgdGhlIHBhdHRlcm4gY2Fubm90IGJlIHBhcnNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBmb3JtYXQoU3RyaW5nIGZvcm1hdCwgT2JqZWN0Li4uIGFyZ3MpIHsKKyAgICAgICAgaWYgKGFyZ3MgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGFyZ3NbaV0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBhcmdzW2ldID0gIm51bGwiOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VGb3JtYXQoZm9ybWF0KS5mb3JtYXQoYXJncyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIEZvcm1hdH0gaW5zdGFuY2VzIHVzZWQgYnkgdGhpcyBtZXNzYWdlIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2Yge0Bjb2RlIEZvcm1hdH0gaW5zdGFuY2VzLgorICAgICAqLworICAgIHB1YmxpYyBGb3JtYXRbXSBnZXRGb3JtYXRzKCkgeworICAgICAgICByZXR1cm4gZm9ybWF0cy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZvcm1hdHMgdXNlZCBmb3IgZWFjaCBhcmd1bWVudCBpbmRleC4gSWYgYW4gYXJndW1lbnQgaXMKKyAgICAgKiBwbGFjZWQgbW9yZSB0aGFuIG9uY2UgaW4gdGhlIHBhdHRlcm4gc3RyaW5nLCB0aGVuIHRoaXMgcmV0dXJucyB0aGUgZm9ybWF0CisgICAgICogb2YgdGhlIGxhc3Qgb25lLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBmb3JtYXRzLCBvcmRlcmVkIGJ5IGFyZ3VtZW50IGluZGV4LgorICAgICAqLworICAgIHB1YmxpYyBGb3JtYXRbXSBnZXRGb3JtYXRzQnlBcmd1bWVudEluZGV4KCkgeworICAgICAgICBGb3JtYXRbXSBhbnN3ZXIgPSBuZXcgRm9ybWF0W21heEFyZ3VtZW50SW5kZXggKyAxXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXhPZmZzZXQgKyAxOyBpKyspIHsKKyAgICAgICAgICAgIGFuc3dlclthcmd1bWVudE51bWJlcnNbaV1dID0gZm9ybWF0c1tpXTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYW5zd2VyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZvcm1hdCB1c2VkIGZvciB0aGUgYXJndW1lbnQgYXQgaW5kZXgge0Bjb2RlIGFyZ0luZGV4fSB0bworICAgICAqIHtAY29kZSBmb3JtYXR9LgorICAgICAqCisgICAgICogQHBhcmFtIGFyZ0luZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGZvcm1hdCB0byBzZXQuCisgICAgICogQHBhcmFtIGZvcm1hdAorICAgICAqICAgICAgICAgICAgdGhlIGZvcm1hdCB0aGF0IHdpbGwgYmUgc2V0IGF0IGluZGV4IHtAY29kZSBhcmdJbmRleH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Rm9ybWF0QnlBcmd1bWVudEluZGV4KGludCBhcmdJbmRleCwgRm9ybWF0IGZvcm1hdCkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1heE9mZnNldCArIDE7IGkrKykgeworICAgICAgICAgICAgaWYgKGFyZ3VtZW50TnVtYmVyc1tpXSA9PSBhcmdJbmRleCkgeworICAgICAgICAgICAgICAgIGZvcm1hdHNbaV0gPSBmb3JtYXQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBmb3JtYXRzIHVzZWQgZm9yIGVhY2ggYXJndW1lbnQuIFRoZSB7QGNvZGUgZm9ybWF0c30gYXJyYXkKKyAgICAgKiBlbGVtZW50cyBzaG91bGQgYmUgaW4gdGhlIG9yZGVyIG9mIHRoZSBhcmd1bWVudCBpbmRpY2VzLgorICAgICAqCisgICAgICogQHBhcmFtIGZvcm1hdHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBmb3JtYXRzIGluIGFuIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZvcm1hdHNCeUFyZ3VtZW50SW5kZXgoRm9ybWF0W10gZm9ybWF0cykgeworICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGZvcm1hdHMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWF4T2Zmc2V0ICsgMTsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGFyZ3VtZW50TnVtYmVyc1tpXSA9PSBqKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMuZm9ybWF0c1tpXSA9IGZvcm1hdHNbal07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbG9jYWxlIHVzZWQgd2hlbiBjcmVhdGluZyBmb3JtYXRzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbG9jYWxlIHVzZWQgdG8gY3JlYXRlIGZvcm1hdHMuCisgICAgICovCisgICAgcHVibGljIExvY2FsZSBnZXRMb2NhbGUoKSB7CisgICAgICAgIHJldHVybiBsb2NhbGU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IGhhc2hDb2RlID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gbWF4T2Zmc2V0OyBpKyspIHsKKyAgICAgICAgICAgIGhhc2hDb2RlICs9IGFyZ3VtZW50TnVtYmVyc1tpXSArIHN0cmluZ3NbaV0uaGFzaENvZGUoKTsKKyAgICAgICAgICAgIGlmIChmb3JtYXRzW2ldICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBoYXNoQ29kZSArPSBmb3JtYXRzW2ldLmhhc2hDb2RlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKG1heE9mZnNldCArIDEgPCBzdHJpbmdzLmxlbmd0aCkgeworICAgICAgICAgICAgaGFzaENvZGUgKz0gc3RyaW5nc1ttYXhPZmZzZXQgKyAxXS5oYXNoQ29kZSgpOworICAgICAgICB9CisgICAgICAgIGlmIChsb2NhbGUgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGhhc2hDb2RlICsgbG9jYWxlLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGhhc2hDb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgbWVzc2FnZSBhcmd1bWVudHMgZnJvbSB0aGUgc3BlY2lmaWVkIHN0cmluZyB1c2luZyB0aGUgcnVsZXMgb2YKKyAgICAgKiB0aGlzIG1lc3NhZ2UgZm9ybWF0LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBwYXJzZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiB7QGNvZGUgT2JqZWN0fSBhcmd1bWVudHMgcmVzdWx0aW5nIGZyb20gdGhlIHBhcnNlLgorICAgICAqIEB0aHJvd3MgUGFyc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBkdXJpbmcgcGFyc2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0W10gcGFyc2UoU3RyaW5nIHN0cmluZykgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgICAgUGFyc2VQb3NpdGlvbiBwb3NpdGlvbiA9IG5ldyBQYXJzZVBvc2l0aW9uKDApOworICAgICAgICBPYmplY3RbXSByZXN1bHQgPSBwYXJzZShzdHJpbmcsIHBvc2l0aW9uKTsKKyAgICAgICAgaWYgKHBvc2l0aW9uLmdldEluZGV4KCkgPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJQYXJzZSBmYWlsdXJlIiwgcG9zaXRpb24uZ2V0RXJyb3JJbmRleCgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgbWVzc2FnZSBhcmd1bWVudCBmcm9tIHRoZSBzcGVjaWZpZWQgc3RyaW5nIHN0YXJ0aW5nIGF0IHRoZQorICAgICAqIGluZGV4IHNwZWNpZmllZCBieSB7QGNvZGUgcG9zaXRpb259LiBJZiB0aGUgc3RyaW5nIGlzIHN1Y2Nlc3NmdWxseQorICAgICAqIHBhcnNlZCB0aGVuIHRoZSBpbmRleCBvZiB0aGUge0Bjb2RlIFBhcnNlUG9zaXRpb259IGlzIHVwZGF0ZWQgdG8gdGhlCisgICAgICogaW5kZXggZm9sbG93aW5nIHRoZSBwYXJzZWQgdGV4dC4gT24gZXJyb3IsIHRoZSBpbmRleCBpcyB1bmNoYW5nZWQgYW5kIHRoZQorICAgICAqIGVycm9yIGluZGV4IG9mIHtAY29kZSBQYXJzZVBvc2l0aW9ufSBpcyBzZXQgdG8gdGhlIGluZGV4IHdoZXJlIHRoZSBlcnJvcgorICAgICAqIG9jY3VycmVkLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBwYXJzZS4KKyAgICAgKiBAcGFyYW0gcG9zaXRpb24KKyAgICAgKiAgICAgICAgICAgIGlucHV0L291dHB1dCBwYXJhbWV0ZXIsIHNwZWNpZmllcyB0aGUgc3RhcnQgaW5kZXggaW4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBzdHJpbmd9IGZyb20gd2hlcmUgdG8gc3RhcnQgcGFyc2luZy4gSWYgcGFyc2luZyBpcworICAgICAqICAgICAgICAgICAgc3VjY2Vzc2Z1bCwgaXQgaXMgdXBkYXRlZCB3aXRoIHRoZSBpbmRleCBmb2xsb3dpbmcgdGhlIHBhcnNlZAorICAgICAqICAgICAgICAgICAgdGV4dDsgb24gZXJyb3IsIHRoZSBpbmRleCBpcyB1bmNoYW5nZWQgYW5kIHRoZSBlcnJvciBpbmRleCBpcworICAgICAqICAgICAgICAgICAgc2V0IHRvIHRoZSBpbmRleCB3aGVyZSB0aGUgZXJyb3Igb2NjdXJyZWQuCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2Ygb2JqZWN0cyByZXN1bHRpbmcgZnJvbSB0aGUgcGFyc2UsIG9yIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAgdGhlcmUgaXMgYW4gZXJyb3IuCisgICAgICovCisgICAgcHVibGljIE9iamVjdFtdIHBhcnNlKFN0cmluZyBzdHJpbmcsIFBhcnNlUG9zaXRpb24gcG9zaXRpb24pIHsKKyAgICAgICAgaWYgKHN0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gRW1wdHlBcnJheS5PQkpFQ1Q7CisgICAgICAgIH0KKyAgICAgICAgUGFyc2VQb3NpdGlvbiBpbnRlcm5hbFBvcyA9IG5ldyBQYXJzZVBvc2l0aW9uKDApOworICAgICAgICBpbnQgb2Zmc2V0ID0gcG9zaXRpb24uZ2V0SW5kZXgoKTsKKyAgICAgICAgT2JqZWN0W10gcmVzdWx0ID0gbmV3IE9iamVjdFttYXhBcmd1bWVudEluZGV4ICsgMV07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IG1heE9mZnNldDsgaSsrKSB7CisgICAgICAgICAgICBTdHJpbmcgc3ViID0gc3RyaW5nc1tpXTsKKyAgICAgICAgICAgIGlmICghc3RyaW5nLnN0YXJ0c1dpdGgoc3ViLCBvZmZzZXQpKSB7CisgICAgICAgICAgICAgICAgcG9zaXRpb24uc2V0RXJyb3JJbmRleChvZmZzZXQpOworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgb2Zmc2V0ICs9IHN1Yi5sZW5ndGgoKTsKKyAgICAgICAgICAgIE9iamVjdCBwYXJzZTsKKyAgICAgICAgICAgIEZvcm1hdCBmb3JtYXQgPSBmb3JtYXRzW2ldOworICAgICAgICAgICAgaWYgKGZvcm1hdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWYgKGkgKyAxIDwgc3RyaW5ncy5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IG5leHQgPSBzdHJpbmcuaW5kZXhPZihzdHJpbmdzW2kgKyAxXSwgb2Zmc2V0KTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uLnNldEVycm9ySW5kZXgob2Zmc2V0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHBhcnNlID0gc3RyaW5nLnN1YnN0cmluZyhvZmZzZXQsIG5leHQpOworICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBuZXh0OworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHBhcnNlID0gc3RyaW5nLnN1YnN0cmluZyhvZmZzZXQpOworICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBzdHJpbmcubGVuZ3RoKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpbnRlcm5hbFBvcy5zZXRJbmRleChvZmZzZXQpOworICAgICAgICAgICAgICAgIHBhcnNlID0gZm9ybWF0LnBhcnNlT2JqZWN0KHN0cmluZywgaW50ZXJuYWxQb3MpOworICAgICAgICAgICAgICAgIGlmIChpbnRlcm5hbFBvcy5nZXRFcnJvckluZGV4KCkgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24uc2V0RXJyb3JJbmRleChvZmZzZXQpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgb2Zmc2V0ID0gaW50ZXJuYWxQb3MuZ2V0SW5kZXgoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdFthcmd1bWVudE51bWJlcnNbaV1dID0gcGFyc2U7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG1heE9mZnNldCArIDEgPCBzdHJpbmdzLmxlbmd0aCkgeworICAgICAgICAgICAgU3RyaW5nIHN1YiA9IHN0cmluZ3NbbWF4T2Zmc2V0ICsgMV07CisgICAgICAgICAgICBpZiAoIXN0cmluZy5zdGFydHNXaXRoKHN1Yiwgb2Zmc2V0KSkgeworICAgICAgICAgICAgICAgIHBvc2l0aW9uLnNldEVycm9ySW5kZXgob2Zmc2V0KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG9mZnNldCArPSBzdWIubGVuZ3RoKCk7CisgICAgICAgIH0KKyAgICAgICAgcG9zaXRpb24uc2V0SW5kZXgob2Zmc2V0KTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgdGhlIG1lc3NhZ2UgYXJndW1lbnQgZnJvbSB0aGUgc3BlY2lmaWVkIHN0cmluZyBzdGFydGluZyBhdCB0aGUKKyAgICAgKiBpbmRleCBzcGVjaWZpZWQgYnkge0Bjb2RlIHBvc2l0aW9ufS4gSWYgdGhlIHN0cmluZyBpcyBzdWNjZXNzZnVsbHkKKyAgICAgKiBwYXJzZWQgdGhlbiB0aGUgaW5kZXggb2YgdGhlIHtAY29kZSBQYXJzZVBvc2l0aW9ufSBpcyB1cGRhdGVkIHRvIHRoZQorICAgICAqIGluZGV4IGZvbGxvd2luZyB0aGUgcGFyc2VkIHRleHQuIE9uIGVycm9yLCB0aGUgaW5kZXggaXMgdW5jaGFuZ2VkIGFuZCB0aGUKKyAgICAgKiBlcnJvciBpbmRleCBvZiB7QGNvZGUgUGFyc2VQb3NpdGlvbn0gaXMgc2V0IHRvIHRoZSBpbmRleCB3aGVyZSB0aGUgZXJyb3IKKyAgICAgKiBvY2N1cnJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gcGFyc2UuCisgICAgICogQHBhcmFtIHBvc2l0aW9uCisgICAgICogICAgICAgICAgICBpbnB1dC9vdXRwdXQgcGFyYW1ldGVyLCBzcGVjaWZpZXMgdGhlIHN0YXJ0IGluZGV4IGluCisgICAgICogICAgICAgICAgICB7QGNvZGUgc3RyaW5nfSBmcm9tIHdoZXJlIHRvIHN0YXJ0IHBhcnNpbmcuIElmIHBhcnNpbmcgaXMKKyAgICAgKiAgICAgICAgICAgIHN1Y2Nlc3NmdWwsIGl0IGlzIHVwZGF0ZWQgd2l0aCB0aGUgaW5kZXggZm9sbG93aW5nIHRoZSBwYXJzZWQKKyAgICAgKiAgICAgICAgICAgIHRleHQ7IG9uIGVycm9yLCB0aGUgaW5kZXggaXMgdW5jaGFuZ2VkIGFuZCB0aGUgZXJyb3IgaW5kZXggaXMKKyAgICAgKiAgICAgICAgICAgIHNldCB0byB0aGUgaW5kZXggd2hlcmUgdGhlIGVycm9yIG9jY3VycmVkLgorICAgICAqIEByZXR1cm4gdGhlIGFycmF5IG9mIG9iamVjdHMgcmVzdWx0aW5nIGZyb20gdGhlIHBhcnNlLCBvciB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiAgICAgICAgIHRoZXJlIGlzIGFuIGVycm9yLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgcGFyc2VPYmplY3QoU3RyaW5nIHN0cmluZywgUGFyc2VQb3NpdGlvbiBwb3NpdGlvbikgeworICAgICAgICByZXR1cm4gcGFyc2Uoc3RyaW5nLCBwb3NpdGlvbik7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgbWF0Y2goU3RyaW5nIHN0cmluZywgUGFyc2VQb3NpdGlvbiBwb3NpdGlvbiwgYm9vbGVhbiBsYXN0LAorICAgICAgICAgICAgU3RyaW5nW10gdG9rZW5zKSB7CisgICAgICAgIGludCBsZW5ndGggPSBzdHJpbmcubGVuZ3RoKCksIG9mZnNldCA9IHBvc2l0aW9uLmdldEluZGV4KCksIHRva2VuID0gLTE7CisgICAgICAgIHdoaWxlIChvZmZzZXQgPCBsZW5ndGggJiYgQ2hhcmFjdGVyLmlzV2hpdGVzcGFjZShzdHJpbmcuY2hhckF0KG9mZnNldCkpKSB7CisgICAgICAgICAgICBvZmZzZXQrKzsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gdG9rZW5zLmxlbmd0aDsgLS1pID49IDA7KSB7CisgICAgICAgICAgICBpZiAoc3RyaW5nLnJlZ2lvbk1hdGNoZXModHJ1ZSwgb2Zmc2V0LCB0b2tlbnNbaV0sIDAsIHRva2Vuc1tpXQorICAgICAgICAgICAgICAgICAgICAubGVuZ3RoKCkpKSB7CisgICAgICAgICAgICAgICAgdG9rZW4gPSBpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmICh0b2tlbiA9PSAtMSkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIG9mZnNldCArPSB0b2tlbnNbdG9rZW5dLmxlbmd0aCgpOworICAgICAgICB3aGlsZSAob2Zmc2V0IDwgbGVuZ3RoICYmIENoYXJhY3Rlci5pc1doaXRlc3BhY2Uoc3RyaW5nLmNoYXJBdChvZmZzZXQpKSkgeworICAgICAgICAgICAgb2Zmc2V0Kys7CisgICAgICAgIH0KKyAgICAgICAgY2hhciBjaDsKKyAgICAgICAgaWYgKG9mZnNldCA8IGxlbmd0aAorICAgICAgICAgICAgICAgICYmICgoY2ggPSBzdHJpbmcuY2hhckF0KG9mZnNldCkpID09ICd9JyB8fCAoIWxhc3QgJiYgY2ggPT0gJywnKSkpIHsKKyAgICAgICAgICAgIHBvc2l0aW9uLnNldEluZGV4KG9mZnNldCArIDEpOworICAgICAgICAgICAgcmV0dXJuIHRva2VuOworICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBwcml2YXRlIEZvcm1hdCBwYXJzZVZhcmlhYmxlKFN0cmluZyBzdHJpbmcsIFBhcnNlUG9zaXRpb24gcG9zaXRpb24pIHsKKyAgICAgICAgaW50IGxlbmd0aCA9IHN0cmluZy5sZW5ndGgoKSwgb2Zmc2V0ID0gcG9zaXRpb24uZ2V0SW5kZXgoKTsKKyAgICAgICAgY2hhciBjaDsKKyAgICAgICAgaWYgKG9mZnNldCA+PSBsZW5ndGggfHwgKChjaCA9IHN0cmluZy5jaGFyQXQob2Zmc2V0KyspKSAhPSAnfScgJiYgY2ggIT0gJywnKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTWlzc2luZyBlbGVtZW50IGZvcm1hdCIpOworICAgICAgICB9CisgICAgICAgIHBvc2l0aW9uLnNldEluZGV4KG9mZnNldCk7CisgICAgICAgIGlmIChjaCA9PSAnfScpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGludCB0eXBlID0gbWF0Y2goc3RyaW5nLCBwb3NpdGlvbiwgZmFsc2UsCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHsgInRpbWUiLCAiZGF0ZSIsICJudW1iZXIiLCAiY2hvaWNlIiB9KTsKKyAgICAgICAgaWYgKHR5cGUgPT0gLTEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlVua25vd24gZWxlbWVudCBmb3JtYXQiKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBjaCA9IHN0cmluZy5jaGFyQXQocG9zaXRpb24uZ2V0SW5kZXgoKSAtIDEpOworICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgICAgICAgIGNhc2UgMDogLy8gdGltZQorICAgICAgICAgICAgY2FzZSAxOiAvLyBkYXRlCisgICAgICAgICAgICAgICAgaWYgKGNoID09ICd9JykgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHlwZSA9PSAxID8gRGF0ZUZvcm1hdC5nZXREYXRlSW5zdGFuY2UoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0ZUZvcm1hdC5ERUZBVUxULCBsb2NhbGUpIDogRGF0ZUZvcm1hdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRUaW1lSW5zdGFuY2UoRGF0ZUZvcm1hdC5ERUZBVUxULCBsb2NhbGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpbnQgZGF0ZVN0eWxlID0gbWF0Y2goc3RyaW5nLCBwb3NpdGlvbiwgdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7ICJmdWxsIiwgImxvbmciLCAibWVkaXVtIiwgInNob3J0IiB9KTsKKyAgICAgICAgICAgICAgICBpZiAoZGF0ZVN0eWxlID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIEZvcm1hdC51cFRvV2l0aFF1b3RlcyhzdHJpbmcsIHBvc2l0aW9uLCBidWZmZXIsICd9JywgJ3snKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTaW1wbGVEYXRlRm9ybWF0KGJ1ZmZlci50b1N0cmluZygpLCBsb2NhbGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzd2l0Y2ggKGRhdGVTdHlsZSkgeworICAgICAgICAgICAgICAgICAgICBjYXNlIDA6CisgICAgICAgICAgICAgICAgICAgICAgICBkYXRlU3R5bGUgPSBEYXRlRm9ybWF0LkZVTEw7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAxOgorICAgICAgICAgICAgICAgICAgICAgICAgZGF0ZVN0eWxlID0gRGF0ZUZvcm1hdC5MT05HOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKKyAgICAgICAgICAgICAgICAgICAgICAgIGRhdGVTdHlsZSA9IERhdGVGb3JtYXQuTUVESVVNOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgMzoKKyAgICAgICAgICAgICAgICAgICAgICAgIGRhdGVTdHlsZSA9IERhdGVGb3JtYXQuU0hPUlQ7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHR5cGUgPT0gMSA/IERhdGVGb3JtYXQKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXREYXRlSW5zdGFuY2UoZGF0ZVN0eWxlLCBsb2NhbGUpIDogRGF0ZUZvcm1hdAorICAgICAgICAgICAgICAgICAgICAgICAgLmdldFRpbWVJbnN0YW5jZShkYXRlU3R5bGUsIGxvY2FsZSk7CisgICAgICAgICAgICBjYXNlIDI6IC8vIG51bWJlcgorICAgICAgICAgICAgICAgIGlmIChjaCA9PSAnfScpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZShsb2NhbGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpbnQgbnVtYmVyU3R5bGUgPSBtYXRjaChzdHJpbmcsIHBvc2l0aW9uLCB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHsgImN1cnJlbmN5IiwgInBlcmNlbnQiLCAiaW50ZWdlciIgfSk7CisgICAgICAgICAgICAgICAgaWYgKG51bWJlclN0eWxlID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIEZvcm1hdC51cFRvV2l0aFF1b3RlcyhzdHJpbmcsIHBvc2l0aW9uLCBidWZmZXIsICd9JywgJ3snKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBEZWNpbWFsRm9ybWF0KGJ1ZmZlci50b1N0cmluZygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBEZWNpbWFsRm9ybWF0U3ltYm9scyhsb2NhbGUpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc3dpdGNoIChudW1iZXJTdHlsZSkgeworICAgICAgICAgICAgICAgICAgICBjYXNlIDA6IC8vIGN1cnJlbmN5CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyRm9ybWF0LmdldEN1cnJlbmN5SW5zdGFuY2UobG9jYWxlKTsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAxOiAvLyBwZXJjZW50CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyRm9ybWF0LmdldFBlcmNlbnRJbnN0YW5jZShsb2NhbGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyRm9ybWF0LmdldEludGVnZXJJbnN0YW5jZShsb2NhbGUpOworICAgICAgICB9CisgICAgICAgIC8vIGNob2ljZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgRm9ybWF0LnVwVG9XaXRoUXVvdGVzKHN0cmluZywgcG9zaXRpb24sIGJ1ZmZlciwgJ30nLCAneycpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gaWdub3JlZAorICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgQ2hvaWNlRm9ybWF0KGJ1ZmZlci50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzcGVjaWZpZWQgZm9ybWF0IHVzZWQgYnkgdGhpcyBtZXNzYWdlIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZm9ybWF0IHRvIGNoYW5nZS4KKyAgICAgKiBAcGFyYW0gZm9ybWF0CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIEZvcm1hdH0gdGhhdCByZXBsYWNlcyB0aGUgb2xkIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGb3JtYXQoaW50IG9mZnNldCwgRm9ybWF0IGZvcm1hdCkgeworICAgICAgICBmb3JtYXRzW29mZnNldF0gPSBmb3JtYXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZm9ybWF0cyB1c2VkIGJ5IHRoaXMgbWVzc2FnZSBmb3JtYXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9ybWF0cworICAgICAqICAgICAgICAgICAgYW4gYXJyYXkgb2Yge0Bjb2RlIEZvcm1hdH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Rm9ybWF0cyhGb3JtYXRbXSBmb3JtYXRzKSB7CisgICAgICAgIGludCBtaW4gPSB0aGlzLmZvcm1hdHMubGVuZ3RoOworICAgICAgICBpZiAoZm9ybWF0cy5sZW5ndGggPCBtaW4pIHsKKyAgICAgICAgICAgIG1pbiA9IGZvcm1hdHMubGVuZ3RoOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWluOyBpKyspIHsKKyAgICAgICAgICAgIHRoaXMuZm9ybWF0c1tpXSA9IGZvcm1hdHNbaV07CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBsb2NhbGUgdG8gdXNlIHdoZW4gY3JlYXRpbmcge0Bjb2RlIEZvcm1hdH0gaW5zdGFuY2VzLiBDaGFuZ2luZworICAgICAqIHRoZSBsb2NhbGUgbWF5IGNoYW5nZSB0aGUgYmVoYXZpb3Igb2Yge0Bjb2RlIGFwcGx5UGF0dGVybn0sCisgICAgICoge0Bjb2RlIHRvUGF0dGVybn0sIHtAY29kZSBmb3JtYXR9IGFuZCB7QGNvZGUgZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYWxlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IGxvY2FsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMb2NhbGUoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICB0aGlzLmxvY2FsZSA9IGxvY2FsZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gbWF4T2Zmc2V0OyBpKyspIHsKKyAgICAgICAgICAgIEZvcm1hdCBmb3JtYXQgPSBmb3JtYXRzW2ldOworICAgICAgICAgICAgLy8gamF2YSBzcGVjaWZpY2F0aW9uIHVuZGVmaW5lZCBmb3IgbnVsbCBhcmd1bWVudCwgY2hhbmdlIGludG8KKyAgICAgICAgICAgIC8vIGEgbW9yZSB0b2xlcmFudCBpbXBsZW1lbnRhdGlvbgorICAgICAgICAgICAgaWYgKGZvcm1hdCBpbnN0YW5jZW9mIERlY2ltYWxGb3JtYXQpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBmb3JtYXRzW2ldID0gbmV3IERlY2ltYWxGb3JtYXQoKChEZWNpbWFsRm9ybWF0KSBmb3JtYXQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRvUGF0dGVybigpLCBuZXcgRGVjaW1hbEZvcm1hdFN5bWJvbHMobG9jYWxlKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKXsKKyAgICAgICAgICAgICAgICAgICAgZm9ybWF0c1tpXSA9IG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmIChmb3JtYXQgaW5zdGFuY2VvZiBTaW1wbGVEYXRlRm9ybWF0KSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZm9ybWF0c1tpXSA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCgoU2ltcGxlRGF0ZUZvcm1hdCkgZm9ybWF0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50b1BhdHRlcm4oKSwgbG9jYWxlKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZm9ybWF0c1tpXSA9IG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgZGVjb2RlRGVjaW1hbEZvcm1hdChTdHJpbmdCdWZmZXIgYnVmZmVyLCBGb3JtYXQgZm9ybWF0KSB7CisgICAgICAgIGJ1ZmZlci5hcHBlbmQoIixudW1iZXIiKTsKKyAgICAgICAgaWYgKGZvcm1hdC5lcXVhbHMoTnVtYmVyRm9ybWF0LmdldE51bWJlckluc3RhbmNlKGxvY2FsZSkpKSB7CisgICAgICAgICAgICAvLyBFbXB0eSBibG9jaworICAgICAgICB9IGVsc2UgaWYgKGZvcm1hdC5lcXVhbHMoTnVtYmVyRm9ybWF0LmdldEludGVnZXJJbnN0YW5jZShsb2NhbGUpKSkgeworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiLGludGVnZXIiKTsKKyAgICAgICAgfSBlbHNlIGlmIChmb3JtYXQuZXF1YWxzKE51bWJlckZvcm1hdC5nZXRDdXJyZW5jeUluc3RhbmNlKGxvY2FsZSkpKSB7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCIsY3VycmVuY3kiKTsKKyAgICAgICAgfSBlbHNlIGlmIChmb3JtYXQuZXF1YWxzKE51bWJlckZvcm1hdC5nZXRQZXJjZW50SW5zdGFuY2UobG9jYWxlKSkpIHsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIixwZXJjZW50Iik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcsJyk7CisgICAgICAgICAgICByZXR1cm4gKChEZWNpbWFsRm9ybWF0KSBmb3JtYXQpLnRvUGF0dGVybigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGRlY29kZVNpbXBsZURhdGVGb3JtYXQoU3RyaW5nQnVmZmVyIGJ1ZmZlciwgRm9ybWF0IGZvcm1hdCkgeworICAgICAgICBpZiAoZm9ybWF0LmVxdWFscyhEYXRlRm9ybWF0LmdldFRpbWVJbnN0YW5jZShEYXRlRm9ybWF0LkRFRkFVTFQsIGxvY2FsZSkpKSB7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCIsdGltZSIpOworICAgICAgICB9IGVsc2UgaWYgKGZvcm1hdC5lcXVhbHMoRGF0ZUZvcm1hdC5nZXREYXRlSW5zdGFuY2UoRGF0ZUZvcm1hdC5ERUZBVUxULAorICAgICAgICAgICAgICAgIGxvY2FsZSkpKSB7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCIsZGF0ZSIpOworICAgICAgICB9IGVsc2UgaWYgKGZvcm1hdC5lcXVhbHMoRGF0ZUZvcm1hdC5nZXRUaW1lSW5zdGFuY2UoRGF0ZUZvcm1hdC5TSE9SVCwKKyAgICAgICAgICAgICAgICBsb2NhbGUpKSkgeworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiLHRpbWUsc2hvcnQiKTsKKyAgICAgICAgfSBlbHNlIGlmIChmb3JtYXQuZXF1YWxzKERhdGVGb3JtYXQuZ2V0RGF0ZUluc3RhbmNlKERhdGVGb3JtYXQuU0hPUlQsCisgICAgICAgICAgICAgICAgbG9jYWxlKSkpIHsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIixkYXRlLHNob3J0Iik7CisgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0LmVxdWFscyhEYXRlRm9ybWF0LmdldFRpbWVJbnN0YW5jZShEYXRlRm9ybWF0LkxPTkcsCisgICAgICAgICAgICAgICAgbG9jYWxlKSkpIHsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIix0aW1lLGxvbmciKTsKKyAgICAgICAgfSBlbHNlIGlmIChmb3JtYXQuZXF1YWxzKERhdGVGb3JtYXQuZ2V0RGF0ZUluc3RhbmNlKERhdGVGb3JtYXQuTE9ORywKKyAgICAgICAgICAgICAgICBsb2NhbGUpKSkgeworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiLGRhdGUsbG9uZyIpOworICAgICAgICB9IGVsc2UgaWYgKGZvcm1hdC5lcXVhbHMoRGF0ZUZvcm1hdC5nZXRUaW1lSW5zdGFuY2UoRGF0ZUZvcm1hdC5GVUxMLAorICAgICAgICAgICAgICAgIGxvY2FsZSkpKSB7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCIsdGltZSxmdWxsIik7CisgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0LmVxdWFscyhEYXRlRm9ybWF0LmdldERhdGVJbnN0YW5jZShEYXRlRm9ybWF0LkZVTEwsCisgICAgICAgICAgICAgICAgbG9jYWxlKSkpIHsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIixkYXRlLGZ1bGwiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIixkYXRlLCIpOworICAgICAgICAgICAgcmV0dXJuICgoU2ltcGxlRGF0ZUZvcm1hdCkgZm9ybWF0KS50b1BhdHRlcm4oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwYXR0ZXJuIG9mIHRoaXMgbWVzc2FnZSBmb3JtYXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwYXR0ZXJuLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9QYXR0ZXJuKCkgeworICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8PSBtYXhPZmZzZXQ7IGkrKykgeworICAgICAgICAgICAgYXBwZW5kUXVvdGVkKGJ1ZmZlciwgc3RyaW5nc1tpXSk7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCd7Jyk7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGFyZ3VtZW50TnVtYmVyc1tpXSk7CisgICAgICAgICAgICBGb3JtYXQgZm9ybWF0ID0gZm9ybWF0c1tpXTsKKyAgICAgICAgICAgIFN0cmluZyBwYXR0ZXJuID0gbnVsbDsKKyAgICAgICAgICAgIGlmIChmb3JtYXQgaW5zdGFuY2VvZiBDaG9pY2VGb3JtYXQpIHsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCIsY2hvaWNlLCIpOworICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAoKENob2ljZUZvcm1hdCkgZm9ybWF0KS50b1BhdHRlcm4oKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0IGluc3RhbmNlb2YgRGVjaW1hbEZvcm1hdCkgeworICAgICAgICAgICAgICAgIHBhdHRlcm4gPSBkZWNvZGVEZWNpbWFsRm9ybWF0KGJ1ZmZlciwgZm9ybWF0KTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0IGluc3RhbmNlb2YgU2ltcGxlRGF0ZUZvcm1hdCkgeworICAgICAgICAgICAgICAgIHBhdHRlcm4gPSBkZWNvZGVTaW1wbGVEYXRlRm9ybWF0KGJ1ZmZlciwgZm9ybWF0KTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbmtub3duIGZvcm1hdCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHBhdHRlcm4gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGJvb2xlYW4gcXVvdGUgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSAwLCBsZW5ndGggPSBwYXR0ZXJuLmxlbmd0aCgpLCBjb3VudCA9IDA7CisgICAgICAgICAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIGNoYXIgY2ggPSBwYXR0ZXJuLmNoYXJBdChpbmRleCsrKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNoID09ICdcJycpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHF1b3RlID0gIXF1b3RlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmICghcXVvdGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaCA9PSAneycpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCsrOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoID09ICd9JykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnQtLTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCInfSIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaCA9ICdcJyc7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoY2gpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJ30nKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobWF4T2Zmc2V0ICsgMSA8IHN0cmluZ3MubGVuZ3RoKSB7CisgICAgICAgICAgICBhcHBlbmRRdW90ZWQoYnVmZmVyLCBzdHJpbmdzW21heE9mZnNldCArIDFdKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFwcGVuZFF1b3RlZChTdHJpbmdCdWZmZXIgYnVmZmVyLCBTdHJpbmcgc3RyaW5nKSB7CisgICAgICAgIGludCBsZW5ndGggPSBzdHJpbmcubGVuZ3RoKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNoYXIgY2ggPSBzdHJpbmcuY2hhckF0KGkpOworICAgICAgICAgICAgaWYgKGNoID09ICd7JyB8fCBjaCA9PSAnfScpIHsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCdcJycpOworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoY2gpOworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJ1wnJyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoY2gpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0U3RyZWFtRmllbGRbXSBzZXJpYWxQZXJzaXN0ZW50RmllbGRzID0geworICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImFyZ3VtZW50TnVtYmVycyIsIGludFtdLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJmb3JtYXRzIiwgRm9ybWF0W10uY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImxvY2FsZSIsIExvY2FsZS5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgibWF4T2Zmc2V0IiwgaW50LmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJvZmZzZXRzIiwgaW50W10uY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInBhdHRlcm4iLCBTdHJpbmcuY2xhc3MpLAorICAgIH07CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtLlB1dEZpZWxkIGZpZWxkcyA9IHN0cmVhbS5wdXRGaWVsZHMoKTsKKyAgICAgICAgZmllbGRzLnB1dCgiYXJndW1lbnROdW1iZXJzIiwgYXJndW1lbnROdW1iZXJzKTsKKyAgICAgICAgRm9ybWF0W10gY29tcGF0aWJsZUZvcm1hdHMgPSBmb3JtYXRzOworICAgICAgICBmaWVsZHMucHV0KCJmb3JtYXRzIiwgY29tcGF0aWJsZUZvcm1hdHMpOworICAgICAgICBmaWVsZHMucHV0KCJsb2NhbGUiLCBsb2NhbGUpOworICAgICAgICBmaWVsZHMucHV0KCJtYXhPZmZzZXQiLCBtYXhPZmZzZXQpOworICAgICAgICBpbnQgb2Zmc2V0ID0gMDsKKyAgICAgICAgaW50IG9mZnNldHNMZW5ndGggPSBtYXhPZmZzZXQgKyAxOworICAgICAgICBpbnRbXSBvZmZzZXRzID0gbmV3IGludFtvZmZzZXRzTGVuZ3RoXTsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBwYXR0ZXJuID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gbWF4T2Zmc2V0OyBpKyspIHsKKyAgICAgICAgICAgIG9mZnNldCArPSBzdHJpbmdzW2ldLmxlbmd0aCgpOworICAgICAgICAgICAgb2Zmc2V0c1tpXSA9IG9mZnNldDsKKyAgICAgICAgICAgIHBhdHRlcm4uYXBwZW5kKHN0cmluZ3NbaV0pOworICAgICAgICB9CisgICAgICAgIGlmIChtYXhPZmZzZXQgKyAxIDwgc3RyaW5ncy5sZW5ndGgpIHsKKyAgICAgICAgICAgIHBhdHRlcm4uYXBwZW5kKHN0cmluZ3NbbWF4T2Zmc2V0ICsgMV0pOworICAgICAgICB9CisgICAgICAgIGZpZWxkcy5wdXQoIm9mZnNldHMiLCBvZmZzZXRzKTsKKyAgICAgICAgZmllbGRzLnB1dCgicGF0dGVybiIsIHBhdHRlcm4udG9TdHJpbmcoKSk7CisgICAgICAgIHN0cmVhbS53cml0ZUZpZWxkcygpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkIGZpZWxkcyA9IHN0cmVhbS5yZWFkRmllbGRzKCk7CisgICAgICAgIGFyZ3VtZW50TnVtYmVycyA9IChpbnRbXSkgZmllbGRzLmdldCgiYXJndW1lbnROdW1iZXJzIiwgbnVsbCk7CisgICAgICAgIGZvcm1hdHMgPSAoRm9ybWF0W10pIGZpZWxkcy5nZXQoImZvcm1hdHMiLCBudWxsKTsKKyAgICAgICAgbG9jYWxlID0gKExvY2FsZSkgZmllbGRzLmdldCgibG9jYWxlIiwgbnVsbCk7CisgICAgICAgIG1heE9mZnNldCA9IGZpZWxkcy5nZXQoIm1heE9mZnNldCIsIDApOworICAgICAgICBpbnRbXSBvZmZzZXRzID0gKGludFtdKSBmaWVsZHMuZ2V0KCJvZmZzZXRzIiwgbnVsbCk7CisgICAgICAgIFN0cmluZyBwYXR0ZXJuID0gKFN0cmluZykgZmllbGRzLmdldCgicGF0dGVybiIsIG51bGwpOworICAgICAgICBpbnQgbGVuZ3RoOworICAgICAgICBpZiAobWF4T2Zmc2V0IDwgMCkgeworICAgICAgICAgICAgbGVuZ3RoID0gcGF0dGVybi5sZW5ndGgoKSA+IDAgPyAxIDogMDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGxlbmd0aCA9IG1heE9mZnNldAorICAgICAgICAgICAgICAgICAgICArIChvZmZzZXRzW21heE9mZnNldF0gPT0gcGF0dGVybi5sZW5ndGgoKSA/IDEgOiAyKTsKKyAgICAgICAgfQorICAgICAgICBzdHJpbmdzID0gbmV3IFN0cmluZ1tsZW5ndGhdOworICAgICAgICBpbnQgbGFzdCA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IG1heE9mZnNldDsgaSsrKSB7CisgICAgICAgICAgICBzdHJpbmdzW2ldID0gcGF0dGVybi5zdWJzdHJpbmcobGFzdCwgb2Zmc2V0c1tpXSk7CisgICAgICAgICAgICBsYXN0ID0gb2Zmc2V0c1tpXTsKKyAgICAgICAgfQorICAgICAgICBpZiAobWF4T2Zmc2V0ICsgMSA8IHN0cmluZ3MubGVuZ3RoKSB7CisgICAgICAgICAgICBzdHJpbmdzW3N0cmluZ3MubGVuZ3RoIC0gMV0gPSBwYXR0ZXJuLnN1YnN0cmluZyhsYXN0LCBwYXR0ZXJuCisgICAgICAgICAgICAgICAgICAgIC5sZW5ndGgoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW5zdGFuY2VzIG9mIHRoaXMgaW5uZXIgY2xhc3MgYXJlIHVzZWQgYXMgYXR0cmlidXRlIGtleXMgaW4KKyAgICAgKiB7QGNvZGUgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yfSB0aGF0IHRoZQorICAgICAqIHtAbGluayBNZXNzYWdlRm9ybWF0I2Zvcm1hdFRvQ2hhcmFjdGVySXRlcmF0b3IoT2JqZWN0KX0gbWV0aG9kIHJldHVybnMuCisgICAgICogPHA+CisgICAgICogVGhlcmUgaXMgbm8gcHVibGljIGNvbnN0cnVjdG9yIGluIHRoaXMgY2xhc3MsIHRoZSBvbmx5IGluc3RhbmNlcyBhcmUgdGhlCisgICAgICogY29uc3RhbnRzIGRlZmluZWQgaGVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEZpZWxkIGV4dGVuZHMgRm9ybWF0LkZpZWxkIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3ODk5OTQzOTU3NjE3MzYwODEwTDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhpcyBjb25zdGFudCBzdGFuZHMgZm9yIHRoZSBtZXNzYWdlIGFyZ3VtZW50LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWVsZCBBUkdVTUVOVCA9IG5ldyBGaWVsZCgibWVzc2FnZSBhcmd1bWVudCBmaWVsZCIpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBNZXNzYWdlRm9ybWF0LkZpZWxkfSB3aXRoIHRoZQorICAgICAgICAgKiBnaXZlbiBmaWVsZCBuYW1lLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gZmllbGROYW1lCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGZpZWxkIG5hbWUuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgRmllbGQoU3RyaW5nIGZpZWxkTmFtZSkgeworICAgICAgICAgICAgc3VwZXIoZmllbGROYW1lKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvTm9ybWFsaXplci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9Ob3JtYWxpemVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmU2NjQ3ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvTm9ybWFsaXplci5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudGV4dDsKKworaW1wb3J0IGxpYmNvcmUuaWN1Lk5hdGl2ZU5vcm1hbGl6ZXI7CisKKy8qKgorICogUHJvdmlkZXMgbm9ybWFsaXphdGlvbiBmdW5jdGlvbnMgYWNjb3JkaW5nIHRvCisgKiA8YSBocmVmPSJodHRwOi8vd3d3LnVuaWNvZGUub3JnL3VuaWNvZGUvcmVwb3J0cy90cjE1L3RyMTUtMjMuaHRtbCI+VW5pY29kZSBTdGFuZGFyZCBBbm5leCAjMTU6CisgKiBVbmljb2RlIE5vcm1hbGl6YXRpb24gRm9ybXM8L2E+LiBOb3JtYWxpemF0aW9uIGNhbiBkZWNvbXBvc2UgYW5kIGNvbXBvc2UKKyAqIGNoYXJhY3RlcnMgZm9yIGVxdWl2YWxlbmN5IGNoZWNraW5nLgorICoKKyAqIEBzaW5jZSAxLjYKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE5vcm1hbGl6ZXIgeworICAgIC8qKgorICAgICAqIFRoZSBub3JtYWxpemF0aW9uIGZvcm1zIHN1cHBvcnRlZCBieSB0aGUgTm9ybWFsaXplci4gVGhlc2UgYXJlIHNwZWNpZmllZCBpbgorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudW5pY29kZS5vcmcvdW5pY29kZS9yZXBvcnRzL3RyMTUvdHIxNS0yMy5odG1sIj5Vbmljb2RlIFN0YW5kYXJkCisgICAgICogQW5uZXggIzE1PC9hPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGVudW0gRm9ybSB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBOb3JtYWxpemF0aW9uIEZvcm0gRCAtIENhbm9uaWNhbCBEZWNvbXBvc2l0aW9uLgorICAgICAgICAgKi8KKyAgICAgICAgTkZELAorCisgICAgICAgIC8qKgorICAgICAgICAgKiBOb3JtYWxpemF0aW9uIEZvcm0gQyAtIENhbm9uaWNhbCBEZWNvbXBvc2l0aW9uLCBmb2xsb3dlZCBieSBDYW5vbmljYWwgQ29tcG9zaXRpb24uCisgICAgICAgICAqLworICAgICAgICBORkMsCisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE5vcm1hbGl6YXRpb24gRm9ybSBLRCAtIENvbXBhdGliaWxpdHkgRGVjb21wb3NpdGlvbi4KKyAgICAgICAgICovCisgICAgICAgIE5GS0QsCisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE5vcm1hbGl6YXRpb24gRm9ybSBLQyAtIENvbXBhdGliaWxpdHkgRGVjb21wb3NpdGlvbiwgZm9sbG93ZWQgYnkgQ2Fub25pY2FsIENvbXBvc2l0aW9uLgorICAgICAgICAgKi8KKyAgICAgICAgTkZLQzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSBnaXZlbiBjaGFyYWN0ZXIgc2VxdWVuY2UgPGNvZGU+c3JjPC9jb2RlPiBpcyBub3JtYWxpemVkCisgICAgICogYWNjb3JkaW5nIHRvIHRoZSBub3JtYWxpemF0aW9uIG1ldGhvZCA8Y29kZT5mb3JtPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcmMgY2hhcmFjdGVyIHNlcXVlbmNlIHRvIGNoZWNrCisgICAgICogQHBhcmFtIGZvcm0gbm9ybWFsaXphdGlvbiBmb3JtIHRvIGNoZWNrIGFnYWluc3QKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgbm9ybWFsaXplZCBhY2NvcmRpbmcgdG8gPGNvZGU+Zm9ybTwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNOb3JtYWxpemVkKENoYXJTZXF1ZW5jZSBzcmMsIEZvcm0gZm9ybSkgeworICAgICAgICByZXR1cm4gTmF0aXZlTm9ybWFsaXplci5pc05vcm1hbGl6ZWQoc3JjLCBmb3JtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3JtYWxpemUgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSA8Y29kZT5zcmM8L2NvZGU+IGFjY29yZGluZyB0byB0aGUKKyAgICAgKiBub3JtYWxpemF0aW9uIG1ldGhvZCA8Y29kZT5mb3JtPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcmMgY2hhcmFjdGVyIHNlcXVlbmNlIHRvIHJlYWQgZm9yIG5vcm1hbGl6YXRpb24KKyAgICAgKiBAcGFyYW0gZm9ybSBub3JtYWxpemF0aW9uIGZvcm0KKyAgICAgKiBAcmV0dXJuIHN0cmluZyBub3JtYWxpemVkIGFjY29yZGluZyB0byA8Y29kZT5mb3JtPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG5vcm1hbGl6ZShDaGFyU2VxdWVuY2Ugc3JjLCBGb3JtIGZvcm0pIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZU5vcm1hbGl6ZXIubm9ybWFsaXplKHNyYywgZm9ybSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBOb3JtYWxpemVyKCkge30KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvTnVtYmVyRm9ybWF0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L051bWJlckZvcm1hdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNiZmY2YWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L051bWJlckZvcm1hdC5qYXZhCkBAIC0wLDAgKzEsODQ0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW52YWxpZE9iamVjdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0U3RyZWFtRmllbGQ7CitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5tYXRoLlJvdW5kaW5nTW9kZTsKK2ltcG9ydCBqYXZhLnV0aWwuQ3VycmVuY3k7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBsaWJjb3JlLmljdS5JQ1U7CitpbXBvcnQgbGliY29yZS5pY3UuTG9jYWxlRGF0YTsKKworLyoqCisgKiBUaGUgYWJzdHJhY3QgYmFzZSBjbGFzcyBmb3IgYWxsIG51bWJlciBmb3JtYXRzLiBUaGlzIGNsYXNzIHByb3ZpZGVzIHRoZQorICogaW50ZXJmYWNlIGZvciBmb3JtYXR0aW5nIGFuZCBwYXJzaW5nIG51bWJlcnMuIHtAY29kZSBOdW1iZXJGb3JtYXR9IGFsc28KKyAqIHByb3ZpZGVzIG1ldGhvZHMgZm9yIGRldGVybWluaW5nIHdoaWNoIGxvY2FsZXMgaGF2ZSBudW1iZXIgZm9ybWF0cywgYW5kIHdoYXQKKyAqIHRoZWlyIG5hbWVzIGFyZS4KKyAqIDxwPgorICoge0Bjb2RlIE51bWJlckZvcm1hdH0gaGVscHMgeW91IHRvIGZvcm1hdCBhbmQgcGFyc2UgbnVtYmVycyBmb3IgYW55IGxvY2FsZS4KKyAqIFlvdXIgY29kZSBjYW4gYmUgY29tcGxldGVseSBpbmRlcGVuZGVudCBvZiB0aGUgbG9jYWxlIGNvbnZlbnRpb25zIGZvciBkZWNpbWFsCisgKiBwb2ludHMsIHRob3VzYW5kcy1zZXBhcmF0b3JzLCBvciBldmVuIHRoZSBwYXJ0aWN1bGFyIGRlY2ltYWwgZGlnaXRzIHVzZWQsIG9yCisgKiB3aGV0aGVyIHRoZSBudW1iZXIgZm9ybWF0IGlzIGV2ZW4gZGVjaW1hbC4KKyAqIDxwPgorICogVG8gZm9ybWF0IGEgbnVtYmVyIGZvciB0aGUgY3VycmVudCBsb2NhbGUsIHVzZSBvbmUgb2YgdGhlIGZhY3RvcnkgY2xhc3MKKyAqIG1ldGhvZHM6CisgKiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogbXlTdHJpbmcgPSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKS5mb3JtYXQobXlOdW1iZXIpOworICogPC9wcmU+CisgKgorICogPC9ibG9ja3F1b3RlPgorICogPHA+CisgKiBJZiB5b3UgYXJlIGZvcm1hdHRpbmcgbXVsdGlwbGUgbnVtYmVycywgaXQgaXMgbW9yZSBlZmZpY2llbnQgdG8gZ2V0IHRoZQorICogZm9ybWF0IGFuZCB1c2UgaXQgbXVsdGlwbGUgdGltZXMgc28gdGhhdCB0aGUgc3lzdGVtIGRvZXNuJ3QgaGF2ZSB0byBmZXRjaCB0aGUKKyAqIGluZm9ybWF0aW9uIGFib3V0IHRoZSBsb2NhbCBsYW5ndWFnZSBhbmQgY291bnRyeSBjb252ZW50aW9ucyBtdWx0aXBsZSB0aW1lcy4KKyAqIDxibG9ja3F1b3RlPgorICoKKyAqIDxwcmU+CisgKiBOdW1iZXJGb3JtYXQgbmYgPSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKTsKKyAqIGZvciAoaW50IGkgPSAwOyBpICZsdDsgYS5sZW5ndGg7ICsraSkgeworICogICAgIG91dHB1dC5wcmludGxuKG5mLmZvcm1hdChteU51bWJlcltpXSkgKyAmcXVvdDs7ICZxdW90Oyk7CisgKiB9CisgKiA8L3ByZT4KKyAqCisgKiA8L2Jsb2NrcXVvdGU+CisgKiA8cD4KKyAqIFRvIGZvcm1hdCBhIG51bWJlciBmb3IgYSBkaWZmZXJlbnQgbG9jYWxlLCBzcGVjaWZ5IGl0IGluIHRoZSBjYWxsIHRvCisgKiB7QGNvZGUgZ2V0SW5zdGFuY2V9LgorICogPGJsb2NrcXVvdGU+CisgKgorICogPHByZT4KKyAqIE51bWJlckZvcm1hdCBuZiA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZShMb2NhbGUuRlJFTkNIKTsKKyAqIDwvcHJlPgorICoKKyAqIDwvYmxvY2txdW90ZT4KKyAqIDxwPgorICogWW91IGNhbiBhbHNvIHVzZSBhIHtAY29kZSBOdW1iZXJGb3JtYXR9IHRvIHBhcnNlIG51bWJlcnM6CisgKiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogbXlOdW1iZXIgPSBuZi5wYXJzZShteVN0cmluZyk7CisgKiA8L3ByZT4KKyAqCisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+VXNlIHtAY29kZSAjZ2V0SW5zdGFuY2V9IG9yIHtAY29kZSAjZ2V0TnVtYmVySW5zdGFuY2V9IHRvIGdldCB0aGUgZGVmYXVsdCBudW1iZXIKKyAqIGZvcm1hdC4gVXNlIHtAbGluayAjZ2V0SW50ZWdlckluc3RhbmNlfSB0byBnZXQgYW4gaW50ZWdlciBudW1iZXIgZm9ybWF0LAorICoge0BsaW5rICNnZXRDdXJyZW5jeUluc3RhbmNlfSB0byBnZXQgdGhlIGN1cnJlbmN5IG51bWJlciBmb3JtYXQsIGFuZAorICoge0BsaW5rICNnZXRQZXJjZW50SW5zdGFuY2V9IHRvIGdldCBhIGZvcm1hdCBmb3IgZGlzcGxheWluZyBwZXJjZW50YWdlcy4KKyAqCisgKiA8cD5Zb3UgY2FuIGFsc28gY29udHJvbCB0aGUgZGlzcGxheSBvZiBudW1iZXJzIHdpdGggbWV0aG9kcyBzdWNoIGFzCisgKiB7QGNvZGUgc2V0TWluaW11bUZyYWN0aW9uRGlnaXRzfS4gSWYgeW91IHdhbnQgZXZlbiBtb3JlIGNvbnRyb2wgb3ZlciB0aGUKKyAqIGZvcm1hdCBvciBwYXJzaW5nLCBvciB3YW50IHRvIGdpdmUgeW91ciB1c2VycyBtb3JlIGNvbnRyb2wsIHlvdSBjYW4gdHJ5CisgKiBjYXN0aW5nIHRoZSB7QGNvZGUgTnVtYmVyRm9ybWF0fSB5b3UgZ2V0IGZyb20gdGhlIGZhY3RvcnkgbWV0aG9kcyB0byBhCisgKiB7QGNvZGUgRGVjaW1hbEZvcm1hdH0uIFRoaXMgd2lsbCB3b3JrIGZvciB0aGUgdmFzdCBtYWpvcml0eSBvZiBsb2NhbGVzOyBqdXN0CisgKiByZW1lbWJlciB0byBwdXQgaXQgaW4gYSB7QGNvZGUgdHJ5fSBibG9jayBpbiBjYXNlIHlvdSBlbmNvdW50ZXIgYW4gdW51c3VhbAorICogb25lLgorICogPHA+CisgKiB7QGNvZGUgTnVtYmVyRm9ybWF0fSBpcyBkZXNpZ25lZCBzdWNoIHRoYXQgc29tZSBjb250cm9scyB3b3JrIGZvciBmb3JtYXR0aW5nCisgKiBhbmQgb3RoZXJzIHdvcmsgZm9yIHBhcnNpbmcuIEZvciBleGFtcGxlLCB7QGNvZGUgc2V0UGFyc2VJbnRlZ2VyT25seX0gb25seQorICogYWZmZWN0cyBwYXJzaW5nOiBJZiBzZXQgdG8ge0Bjb2RlIHRydWV9LCAiMzQ1Ni43OCIgaXMgcGFyc2VkIGFzIDM0NTYgKGFuZAorICogbGVhdmVzIHRoZSBwYXJzZSBwb3NpdGlvbiBqdXN0IGFmdGVyICc2Jyk7IGlmIHNldCB0byB7QGNvZGUgZmFsc2V9LAorICogIjM0NTYuNzgiIGlzIHBhcnNlZCBhcyAzNDU2Ljc4IChhbmQgbGVhdmVzIHRoZSBwYXJzZSBwb3NpdGlvbiBqdXN0IGFmdGVyCisgKiAnOCcpLiBUaGlzIGlzIGluZGVwZW5kZW50IG9mIGZvcm1hdHRpbmcuCisgKiA8cD4KKyAqIFlvdSBjYW4gYWxzbyB1c2UgZm9ybXMgb2YgdGhlIHtAY29kZSBwYXJzZX0gYW5kIHtAY29kZSBmb3JtYXR9IG1ldGhvZHMgd2l0aAorICoge0Bjb2RlIFBhcnNlUG9zaXRpb259IGFuZCB7QGNvZGUgRmllbGRQb3NpdGlvbn0gdG8gYWxsb3cgeW91IHRvOgorICogPHVsPgorICogPGxpPnByb2dyZXNzaXZlbHkgcGFyc2UgdGhyb3VnaCBwaWVjZXMgb2YgYSBzdHJpbmc7PC9saT4KKyAqIDxsaT5hbGlnbiB0aGUgZGVjaW1hbCBwb2ludCBhbmQgb3RoZXIgYXJlYXMuPC9saT4KKyAqIDwvdWw+CisgKiBGb3IgZXhhbXBsZSwgeW91IGNhbiBhbGlnbiBudW1iZXJzIGluIHR3byB3YXlzOgorICogPG9sPgorICogPGxpPiBJZiB5b3UgYXJlIHVzaW5nIGEgbW9ub3NwYWNlZCBmb250IHdpdGggc3BhY2luZyBmb3IgYWxpZ25tZW50LCB5b3UgY2FuCisgKiBwYXNzIHRoZSB7QGNvZGUgRmllbGRQb3NpdGlvbn0gaW4geW91ciBmb3JtYXQgY2FsbCwgd2l0aCB7QGNvZGUgZmllbGR9ID0KKyAqIHtAY29kZSBJTlRFR0VSX0ZJRUxEfS4gT24gb3V0cHV0LCB7QGNvZGUgZ2V0RW5kSW5kZXh9IHdpbGwgYmUgc2V0IHRvIHRoZQorICogb2Zmc2V0IGJldHdlZW4gdGhlIGxhc3QgY2hhcmFjdGVyIG9mIHRoZSBpbnRlZ2VyIGFuZCB0aGUgZGVjaW1hbC4gQWRkCisgKiAoZGVzaXJlZFNwYWNlQ291bnQgLSBnZXRFbmRJbmRleCkgc3BhY2VzIHRvIHRoZSBmcm9udCBvZiB0aGUgc3RyaW5nLjwvbGk+CisgKiA8bGk+IElmIHlvdSBhcmUgdXNpbmcgcHJvcG9ydGlvbmFsIGZvbnRzLCBpbnN0ZWFkIG9mIHBhZGRpbmcgd2l0aCBzcGFjZXMsCisgKiBtZWFzdXJlIHRoZSB3aWR0aCBvZiB0aGUgc3RyaW5nIGluIHBpeGVscyBmcm9tIHRoZSBzdGFydCB0bworICoge0Bjb2RlIGdldEVuZEluZGV4fS4gVGhlbiBtb3ZlIHRoZSBwZW4gYnkgKGRlc2lyZWRQaXhlbFdpZHRoIC0KKyAqIHdpZHRoVG9BbGlnbm1lbnRQb2ludCkgYmVmb3JlIGRyYXdpbmcgdGhlIHRleHQuIFRoaXMgYWxzbyB3b3JrcyB3aGVyZSB0aGVyZQorICogaXMgbm8gZGVjaW1hbCBidXQgcG9zc2libHkgYWRkaXRpb25hbCBjaGFyYWN0ZXJzIGJlZm9yZSBvciBhZnRlciB0aGUgbnVtYmVyLAorICogZm9yIGV4YW1wbGUgd2l0aCBwYXJlbnRoZXNlcyBpbiBuZWdhdGl2ZSBudW1iZXJzOiAiKDEyKSIgZm9yIC0xMi48L2xpPgorICogPC9vbD4KKyAqIDxoND5TeW5jaHJvbml6YXRpb248L2g0PgorICogPHA+CisgKiBOdW1iZXIgZm9ybWF0cyBhcmUgZ2VuZXJhbGx5IG5vdCBzeW5jaHJvbml6ZWQuIEl0IGlzIHJlY29tbWVuZGVkIHRvIGNyZWF0ZQorICogc2VwYXJhdGUgZm9ybWF0IGluc3RhbmNlcyBmb3IgZWFjaCB0aHJlYWQuIElmIG11bHRpcGxlIHRocmVhZHMgYWNjZXNzIGEKKyAqIGZvcm1hdCBjb25jdXJyZW50bHksIGl0IG11c3QgYmUgc3luY2hyb25pemVkIGV4dGVybmFsbHkuCisgKiA8cD4KKyAqIDxoND5EZWNpbWFsRm9ybWF0PC9oND4KKyAqIDxwPgorICoge0Bjb2RlIERlY2ltYWxGb3JtYXR9IGlzIHRoZSBjb25jcmV0ZSBpbXBsZW1lbnRhdGlvbiBvZiB7QGNvZGUgTnVtYmVyRm9ybWF0fSwKKyAqIGFuZCB0aGUge0Bjb2RlIE51bWJlckZvcm1hdH0gQVBJIGlzIGVzc2VudGlhbGx5IGFuIGFic3RyYWN0aW9uIG9mCisgKiB7QGNvZGUgRGVjaW1hbEZvcm1hdCdzfSBBUEkuIFJlZmVyIHRvIHtAY29kZSBEZWNpbWFsRm9ybWF0fSBmb3IgbW9yZQorICogaW5mb3JtYXRpb24gYWJvdXQgdGhpcyBBUEkuCisgKgorICogQHNlZSBEZWNpbWFsRm9ybWF0CisgKiBAc2VlIGphdmEudGV4dC5DaG9pY2VGb3JtYXQKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIE51bWJlckZvcm1hdCBleHRlbmRzIEZvcm1hdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjMwODQ2MDEyNTczMzcxMzk0NEw7CisKKyAgICAvKioKKyAgICAgKiBGaWVsZCBjb25zdGFudCBpZGVudGlmeWluZyB0aGUgaW50ZWdlciBwYXJ0IG9mIGEgbnVtYmVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVEVHRVJfRklFTEQgPSAwOworCisgICAgLyoqCisgICAgICogRmllbGQgY29uc3RhbnQgaWRlbnRpZnlpbmcgdGhlIGZyYWN0aW9uYWwgcGFydCBvZiBhIG51bWJlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGUkFDVElPTl9GSUVMRCA9IDE7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gZ3JvdXBpbmdVc2VkID0gdHJ1ZSwgcGFyc2VJbnRlZ2VyT25seSA9IGZhbHNlOworCisgICAgcHJpdmF0ZSBpbnQgbWF4aW11bUludGVnZXJEaWdpdHMgPSA0MCwgbWluaW11bUludGVnZXJEaWdpdHMgPSAxLAorICAgICAgICAgICAgbWF4aW11bUZyYWN0aW9uRGlnaXRzID0gMywgbWluaW11bUZyYWN0aW9uRGlnaXRzID0gMDsKKworICAgIC8qKgorICAgICAqIFVzZWQgYnkgc3ViY2xhc3Nlcy4gVGhpcyB3YXMgcHVibGljIGluIEphdmEgNS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgTnVtYmVyRm9ybWF0KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIE51bWJlckZvcm1hdH0gd2l0aCB0aGUgc2FtZSBwcm9wZXJ0aWVzIGFzIHRoaXMKKyAgICAgKiB7QGNvZGUgTnVtYmVyRm9ybWF0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzaGFsbG93IGNvcHkgb2YgdGhpcyB7QGNvZGUgTnVtYmVyRm9ybWF0fS4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5DbG9uZWFibGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIG9iamVjdCB0byB0aGlzIG51bWJlciBmb3JtYXQgYW5kIGluZGljYXRlcyBpZgorICAgICAqIHRoZXkgYXJlIGVxdWFsLiBJbiBvcmRlciB0byBiZSBlcXVhbCwge0Bjb2RlIG9iamVjdH0gbXVzdCBiZSBhbiBpbnN0YW5jZQorICAgICAqIG9mIHtAY29kZSBOdW1iZXJGb3JtYXR9IHdpdGggdGhlIHNhbWUgcGF0dGVybiBhbmQgcHJvcGVydGllcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB3aXRoIHRoaXMgb2JqZWN0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMgbnVtYmVyCisgICAgICogICAgICAgICBmb3JtYXQ7IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgI2hhc2hDb2RlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgaWYgKG9iamVjdCA9PSB0aGlzKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBOdW1iZXJGb3JtYXQpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgTnVtYmVyRm9ybWF0IG9iaiA9IChOdW1iZXJGb3JtYXQpIG9iamVjdDsKKyAgICAgICAgcmV0dXJuIGdyb3VwaW5nVXNlZCA9PSBvYmouZ3JvdXBpbmdVc2VkCisgICAgICAgICAgICAgICAgJiYgcGFyc2VJbnRlZ2VyT25seSA9PSBvYmoucGFyc2VJbnRlZ2VyT25seQorICAgICAgICAgICAgICAgICYmIG1heGltdW1GcmFjdGlvbkRpZ2l0cyA9PSBvYmoubWF4aW11bUZyYWN0aW9uRGlnaXRzCisgICAgICAgICAgICAgICAgJiYgbWF4aW11bUludGVnZXJEaWdpdHMgPT0gb2JqLm1heGltdW1JbnRlZ2VyRGlnaXRzCisgICAgICAgICAgICAgICAgJiYgbWluaW11bUZyYWN0aW9uRGlnaXRzID09IG9iai5taW5pbXVtRnJhY3Rpb25EaWdpdHMKKyAgICAgICAgICAgICAgICAmJiBtaW5pbXVtSW50ZWdlckRpZ2l0cyA9PSBvYmoubWluaW11bUludGVnZXJEaWdpdHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogRm9ybWF0cyB0aGUgc3BlY2lmaWVkIGRvdWJsZSB1c2luZyB0aGUgcnVsZXMgb2YgdGhpcyBudW1iZXIgZm9ybWF0LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgZG91YmxlIHRvIGZvcm1hdC4KKyAgICAgKiBAcmV0dXJuIHRoZSBmb3JtYXR0ZWQgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZm9ybWF0KGRvdWJsZSB2YWx1ZSkgeworICAgICAgICByZXR1cm4gZm9ybWF0KHZhbHVlLCBuZXcgU3RyaW5nQnVmZmVyKCksIG5ldyBGaWVsZFBvc2l0aW9uKDApKQorICAgICAgICAgICAgICAgIC50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZvcm1hdHMgdGhlIHNwZWNpZmllZCBkb3VibGUgdmFsdWUgYXMgYSBzdHJpbmcgdXNpbmcgdGhlIHBhdHRlcm4gb2YgdGhpcworICAgICAqIG51bWJlciBmb3JtYXQgYW5kIGFwcGVuZHMgdGhlIHN0cmluZyB0byB0aGUgc3BlY2lmaWVkIHN0cmluZyBidWZmZXIuCisgICAgICogPHA+CisgICAgICogSWYgdGhlIHtAY29kZSBmaWVsZH0gbWVtYmVyIG9mIHtAY29kZSBwb3NpdGlvbn0gY29udGFpbnMgYSB2YWx1ZQorICAgICAqIHNwZWNpZnlpbmcgYSBmb3JtYXQgZmllbGQsIHRoZW4gaXRzIHtAY29kZSBiZWdpbkluZGV4fSBhbmQKKyAgICAgKiB7QGNvZGUgZW5kSW5kZXh9IG1lbWJlcnMgd2lsbCBiZSB1cGRhdGVkIHdpdGggdGhlIHBvc2l0aW9uIG9mIHRoZSBmaXJzdAorICAgICAqIG9jY3VycmVuY2Ugb2YgdGhpcyBmaWVsZCBpbiB0aGUgZm9ybWF0dGVkIHRleHQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkb3VibGUgdG8gZm9ybWF0LgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgc3RyaW5nIGJ1ZmZlciB0byBhcHBlbmQgdGhlIGZvcm1hdHRlZCBkb3VibGUgdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRvLgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgb24gaW5wdXQ6IGFuIG9wdGlvbmFsIGFsaWdubWVudCBmaWVsZDsgb24gb3V0cHV0OiB0aGUgb2Zmc2V0cworICAgICAqICAgICAgICAgICAgb2YgdGhlIGFsaWdubWVudCBmaWVsZCBpbiB0aGUgZm9ybWF0dGVkIHRleHQuCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nQnVmZmVyIGZvcm1hdChkb3VibGUgdmFsdWUsIFN0cmluZ0J1ZmZlciBidWZmZXIsIEZpZWxkUG9zaXRpb24gZmllbGQpOworCisgICAgLyoqCisgICAgICogRm9ybWF0cyB0aGUgc3BlY2lmaWVkIGxvbmcgdXNpbmcgdGhlIHJ1bGVzIG9mIHRoaXMgbnVtYmVyIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGxvbmcgdG8gZm9ybWF0LgorICAgICAqIEByZXR1cm4gdGhlIGZvcm1hdHRlZCBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBmb3JtYXQobG9uZyB2YWx1ZSkgeworICAgICAgICByZXR1cm4gZm9ybWF0KHZhbHVlLCBuZXcgU3RyaW5nQnVmZmVyKCksIG5ldyBGaWVsZFBvc2l0aW9uKDApKQorICAgICAgICAgICAgICAgIC50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZvcm1hdHMgdGhlIHNwZWNpZmllZCBsb25nIHZhbHVlIGFzIGEgc3RyaW5nIHVzaW5nIHRoZSBwYXR0ZXJuIG9mIHRoaXMKKyAgICAgKiBudW1iZXIgZm9ybWF0IGFuZCBhcHBlbmRzIHRoZSBzdHJpbmcgdG8gdGhlIHNwZWNpZmllZCBzdHJpbmcgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSB7QGNvZGUgZmllbGR9IG1lbWJlciBvZiB7QGNvZGUgcG9zaXRpb259IGNvbnRhaW5zIGEgdmFsdWUKKyAgICAgKiBzcGVjaWZ5aW5nIGEgZm9ybWF0IGZpZWxkLCB0aGVuIGl0cyB7QGNvZGUgYmVnaW5JbmRleH0gYW5kCisgICAgICoge0Bjb2RlIGVuZEluZGV4fSBtZW1iZXJzIHdpbGwgYmUgdXBkYXRlZCB3aXRoIHRoZSBwb3NpdGlvbiBvZiB0aGUgZmlyc3QKKyAgICAgKiBvY2N1cnJlbmNlIG9mIHRoaXMgZmllbGQgaW4gdGhlIGZvcm1hdHRlZCB0ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbG9uZyB0byBmb3JtYXQuCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBzdHJpbmcgYnVmZmVyIHRvIGFwcGVuZCB0aGUgZm9ybWF0dGVkIGxvbmcgdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRvLgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgb24gaW5wdXQ6IGFuIG9wdGlvbmFsIGFsaWdubWVudCBmaWVsZDsgb24gb3V0cHV0OiB0aGUgb2Zmc2V0cworICAgICAqICAgICAgICAgICAgb2YgdGhlIGFsaWdubWVudCBmaWVsZCBpbiB0aGUgZm9ybWF0dGVkIHRleHQuCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nQnVmZmVyIGZvcm1hdChsb25nIHZhbHVlLCBTdHJpbmdCdWZmZXIgYnVmZmVyLCBGaWVsZFBvc2l0aW9uIGZpZWxkKTsKKworICAgIC8qKgorICAgICAqIEZvcm1hdHMgYSBudW1iZXIgaW50byBhIHN1cHBsaWVkIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbnVtYmVyIG11c3QgYmUgYSBzdWJjbGFzcyBvZiB7QGNvZGUgTnVtYmVyfS4gSW5zdGFuY2VzIG9mIHtAY29kZSBCeXRlfSwge0Bjb2RlIFNob3J0fSwKKyAgICAgKiB7QGNvZGUgSW50ZWdlcn0sIGFuZCB7QGNvZGUgTG9uZ30gaGF2ZSB7QGNvZGUgTnVtYmVyLmxvbmdWYWx1ZX0gaW52b2tlZCwgYXMgZG8gaW5zdGFuY2VzIG9mCisgICAgICoge0Bjb2RlIEJpZ0ludGVnZXJ9IHdoZXJlIHtAY29kZSBCaWdJbnRlZ2VyLmJpdExlbmd0aH0gcmV0dXJucyA8aT5sZXNzIHRoYW48L2k+IDY0LiBBbGwgb3RoZXIKKyAgICAgKiB2YWx1ZXMgaGF2ZSB7QGNvZGUgTnVtYmVyLmRvdWJsZVZhbHVlfSBpbnZva2VkIGluc3RlYWQuCisgICAgICogPHA+CisgICAgICogSWYgdGhlIHtAY29kZSBmaWVsZH0gbWVtYmVyIG9mIHtAY29kZSBmaWVsZH0gY29udGFpbnMgYSB2YWx1ZSBzcGVjaWZ5aW5nCisgICAgICogYSBmb3JtYXQgZmllbGQsIHRoZW4gaXRzIHtAY29kZSBiZWdpbkluZGV4fSBhbmQge0Bjb2RlIGVuZEluZGV4fSBtZW1iZXJzCisgICAgICogd2lsbCBiZSB1cGRhdGVkIHdpdGggdGhlIHBvc2l0aW9uIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoaXMgZmllbGQKKyAgICAgKiBpbiB0aGUgZm9ybWF0dGVkIHRleHQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGZvcm1hdCwgbXVzdCBiZSBhIHtAY29kZSBOdW1iZXJ9LgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgc3RyaW5nIGJ1ZmZlciB0byBhcHBlbmQgdGhlIGZvcm1hdHRlZCBudW1iZXIgdG8uCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICBvbiBpbnB1dDogYW4gb3B0aW9uYWwgYWxpZ25tZW50IGZpZWxkOyBvbiBvdXRwdXQ6IHRoZSBvZmZzZXRzCisgICAgICogICAgICAgICAgICBvZiB0aGUgYWxpZ25tZW50IGZpZWxkIGluIHRoZSBmb3JtYXR0ZWQgdGV4dC4KKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9iamVjdH0gaXMgbm90IGFuIGluc3RhbmNlIG9mIHtAY29kZSBOdW1iZXJ9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgZm9ybWF0KE9iamVjdCBvYmplY3QsIFN0cmluZ0J1ZmZlciBidWZmZXIsIEZpZWxkUG9zaXRpb24gZmllbGQpIHsKKyAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIEJ5dGUgfHwgb2JqZWN0IGluc3RhbmNlb2YgU2hvcnQgfHwgb2JqZWN0IGluc3RhbmNlb2YgSW50ZWdlciB8fAorICAgICAgICAgICAgICAgIG9iamVjdCBpbnN0YW5jZW9mIExvbmcgfHwKKyAgICAgICAgICAgICAgICAob2JqZWN0IGluc3RhbmNlb2YgQmlnSW50ZWdlciAmJiAoKEJpZ0ludGVnZXIpIG9iamVjdCkuYml0TGVuZ3RoKCkgPCA2NCkpIHsKKyAgICAgICAgICAgIGxvbmcgbHYgPSAoKE51bWJlcikgb2JqZWN0KS5sb25nVmFsdWUoKTsKKyAgICAgICAgICAgIHJldHVybiBmb3JtYXQobHYsIGJ1ZmZlciwgZmllbGQpOworICAgICAgICB9IGVsc2UgaWYgKG9iamVjdCBpbnN0YW5jZW9mIE51bWJlcikgeworICAgICAgICAgICAgZG91YmxlIGR2ID0gKChOdW1iZXIpIG9iamVjdCkuZG91YmxlVmFsdWUoKTsKKyAgICAgICAgICAgIHJldHVybiBmb3JtYXQoZHYsIGJ1ZmZlciwgZmllbGQpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGxvY2FsZXMgZm9yIHdoaWNoIGN1c3RvbSB7QGNvZGUgTnVtYmVyRm9ybWF0fSBpbnN0YW5jZXMKKyAgICAgKiBhcmUgYXZhaWxhYmxlLgorICAgICAqIDxwPk5vdGUgdGhhdCBBbmRyb2lkIGRvZXMgbm90IHN1cHBvcnQgdXNlci1zdXBwbGllZCBsb2NhbGUgc2VydmljZSBwcm92aWRlcnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBMb2NhbGVbXSBnZXRBdmFpbGFibGVMb2NhbGVzKCkgeworICAgICAgICByZXR1cm4gSUNVLmdldEF2YWlsYWJsZU51bWJlckZvcm1hdExvY2FsZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW5jeSB1c2VkIGJ5IHRoaXMgbnVtYmVyIGZvcm1hdC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHRocm93cyB7QGNvZGUgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259LAorICAgICAqIGNvbmNyZXRlIHN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIGlmIHRoZXkgc3VwcG9ydCBjdXJyZW5jeQorICAgICAqIGZvcm1hdHRpbmcuCisgICAgICogPHA+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW5jeSB0aGF0IHdhcyBzZXQgaW4gZ2V0SW5zdGFuY2UoKSBvciBpbiBzZXRDdXJyZW5jeSgpLAorICAgICAqICAgICAgICAgb3Ige0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgQ3VycmVuY3kgZ2V0Q3VycmVuY3koKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgTnVtYmVyRm9ybWF0fSBmb3IgZm9ybWF0dGluZyBhbmQgcGFyc2luZyBjdXJyZW5jeSB2YWx1ZXMKKyAgICAgKiBmb3IgdGhlIHVzZXIncyBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKiBTZWUgIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIE51bWJlckZvcm1hdH0gZm9yIGhhbmRsaW5nIGN1cnJlbmN5IHZhbHVlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE51bWJlckZvcm1hdCBnZXRDdXJyZW5jeUluc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gZ2V0Q3VycmVuY3lJbnN0YW5jZShMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIE51bWJlckZvcm1hdH0gZm9yIGZvcm1hdHRpbmcgYW5kIHBhcnNpbmcgY3VycmVuY3kgdmFsdWVzCisgICAgICogZm9yIHRoZSBzcGVjaWZpZWQgbG9jYWxlLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2FsZQorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsZSB0byB1c2UuCisgICAgICogQHJldHVybiBhIHtAY29kZSBOdW1iZXJGb3JtYXR9IGZvciBoYW5kbGluZyBjdXJyZW5jeSB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBOdW1iZXJGb3JtYXQgZ2V0Q3VycmVuY3lJbnN0YW5jZShMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIHJldHVybiBnZXRJbnN0YW5jZShMb2NhbGVEYXRhLmdldChsb2NhbGUpLmN1cnJlbmN5UGF0dGVybiwgbG9jYWxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIE51bWJlckZvcm1hdH0gZm9yIGZvcm1hdHRpbmcgYW5kIHBhcnNpbmcgaW50ZWdlcnMgZm9yIHRoZQorICAgICAqIHVzZXIncyBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKiBTZWUgIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIE51bWJlckZvcm1hdH0gZm9yIGhhbmRsaW5nIGludGVnZXJzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTnVtYmVyRm9ybWF0IGdldEludGVnZXJJbnN0YW5jZSgpIHsKKyAgICAgICAgcmV0dXJuIGdldEludGVnZXJJbnN0YW5jZShMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIE51bWJlckZvcm1hdH0gZm9yIGZvcm1hdHRpbmcgYW5kIHBhcnNpbmcgaW50ZWdlcnMgZm9yCisgICAgICogdGhlIHNwZWNpZmllZCBsb2NhbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYWxlCisgICAgICogICAgICAgICAgICB0aGUgbG9jYWxlIHRvIHVzZS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIE51bWJlckZvcm1hdH0gZm9yIGhhbmRsaW5nIGludGVnZXJzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTnVtYmVyRm9ybWF0IGdldEludGVnZXJJbnN0YW5jZShMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIE51bWJlckZvcm1hdCByZXN1bHQgPSBnZXRJbnN0YW5jZShMb2NhbGVEYXRhLmdldChsb2NhbGUpLmludGVnZXJQYXR0ZXJuLCBsb2NhbGUpOworICAgICAgICByZXN1bHQuc2V0UGFyc2VJbnRlZ2VyT25seSh0cnVlKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIE51bWJlckZvcm1hdH0gZm9yIGZvcm1hdHRpbmcgYW5kIHBhcnNpbmcgbnVtYmVycyBmb3IgdGhlCisgICAgICogZGVmYXVsdCBsb2NhbGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIE51bWJlckZvcm1hdH0gZm9yIGhhbmRsaW5nIHtAY29kZSBOdW1iZXJ9IG9iamVjdHMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBOdW1iZXJGb3JtYXQgZ2V0SW5zdGFuY2UoKSB7CisgICAgICAgIHJldHVybiBnZXROdW1iZXJJbnN0YW5jZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgTnVtYmVyRm9ybWF0fSBmb3IgZm9ybWF0dGluZyBhbmQgcGFyc2luZyBudW1iZXJzIGZvciB0aGUKKyAgICAgKiBzcGVjaWZpZWQgbG9jYWxlLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2FsZQorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsZSB0byB1c2UuCisgICAgICogQHJldHVybiBhIHtAY29kZSBOdW1iZXJGb3JtYXR9IGZvciBoYW5kbGluZyB7QGNvZGUgTnVtYmVyfSBvYmplY3RzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTnVtYmVyRm9ybWF0IGdldEluc3RhbmNlKExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgcmV0dXJuIGdldE51bWJlckluc3RhbmNlKGxvY2FsZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgTnVtYmVyRm9ybWF0IGdldEluc3RhbmNlKFN0cmluZyBwYXR0ZXJuLCBMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIHJldHVybiBuZXcgRGVjaW1hbEZvcm1hdChwYXR0ZXJuLCBsb2NhbGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGZyYWN0aW9uIGRpZ2l0cyB0aGF0IGFyZSBwcmludGVkIHdoZW4KKyAgICAgKiBmb3JtYXR0aW5nLiBJZiB0aGUgbWF4aW11bSBpcyBsZXNzIHRoYW4gdGhlIG51bWJlciBvZiBmcmFjdGlvbiBkaWdpdHMsCisgICAgICogdGhlIGxlYXN0IHNpZ25pZmljYW50IGRpZ2l0cyBhcmUgdHJ1bmNhdGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBudW1iZXIgb2YgZnJhY3Rpb24gZGlnaXRzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKCkgeworICAgICAgICByZXR1cm4gbWF4aW11bUZyYWN0aW9uRGlnaXRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGludGVnZXIgZGlnaXRzIHRoYXQgYXJlIHByaW50ZWQgd2hlbgorICAgICAqIGZvcm1hdHRpbmcuIElmIHRoZSBtYXhpbXVtIGlzIGxlc3MgdGhhbiB0aGUgbnVtYmVyIG9mIGludGVnZXIgZGlnaXRzLCB0aGUKKyAgICAgKiBtb3N0IHNpZ25pZmljYW50IGRpZ2l0cyBhcmUgdHJ1bmNhdGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWF4aW11bSBudW1iZXIgb2YgaW50ZWdlciBkaWdpdHMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNYXhpbXVtSW50ZWdlckRpZ2l0cygpIHsKKyAgICAgICAgcmV0dXJuIG1heGltdW1JbnRlZ2VyRGlnaXRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1pbmltdW0gbnVtYmVyIG9mIGZyYWN0aW9uIGRpZ2l0cyB0aGF0IGFyZSBwcmludGVkIHdoZW4KKyAgICAgKiBmb3JtYXR0aW5nLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWluaW11bSBudW1iZXIgb2YgZnJhY3Rpb24gZGlnaXRzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKCkgeworICAgICAgICByZXR1cm4gbWluaW11bUZyYWN0aW9uRGlnaXRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1pbmltdW0gbnVtYmVyIG9mIGludGVnZXIgZGlnaXRzIHRoYXQgYXJlIHByaW50ZWQgd2hlbgorICAgICAqIGZvcm1hdHRpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtaW5pbXVtIG51bWJlciBvZiBpbnRlZ2VyIGRpZ2l0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1pbmltdW1JbnRlZ2VyRGlnaXRzKCkgeworICAgICAgICByZXR1cm4gbWluaW11bUludGVnZXJEaWdpdHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBOdW1iZXJGb3JtYXR9IGZvciBmb3JtYXR0aW5nIGFuZCBwYXJzaW5nIG51bWJlcnMgZm9yIHRoZQorICAgICAqIHVzZXIncyBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKiBTZWUgIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIE51bWJlckZvcm1hdH0gZm9yIGhhbmRsaW5nIHtAY29kZSBOdW1iZXJ9IG9iamVjdHMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBOdW1iZXJGb3JtYXQgZ2V0TnVtYmVySW5zdGFuY2UoKSB7CisgICAgICAgIHJldHVybiBnZXROdW1iZXJJbnN0YW5jZShMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIE51bWJlckZvcm1hdH0gZm9yIGZvcm1hdHRpbmcgYW5kIHBhcnNpbmcgbnVtYmVycyBmb3IgdGhlCisgICAgICogc3BlY2lmaWVkIGxvY2FsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhbGUgdG8gdXNlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgTnVtYmVyRm9ybWF0fSBmb3IgaGFuZGxpbmcge0Bjb2RlIE51bWJlcn0gb2JqZWN0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIE51bWJlckZvcm1hdCBnZXROdW1iZXJJbnN0YW5jZShMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIHJldHVybiBnZXRJbnN0YW5jZShMb2NhbGVEYXRhLmdldChsb2NhbGUpLm51bWJlclBhdHRlcm4sIGxvY2FsZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBOdW1iZXJGb3JtYXR9IGZvciBmb3JtYXR0aW5nIGFuZCBwYXJzaW5nIHBlcmNlbnRhZ2UKKyAgICAgKiB2YWx1ZXMgZm9yIHRoZSB1c2VyJ3MgZGVmYXVsdCBsb2NhbGUuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqCisgICAgICogPHA+VGhlIHtAY29kZSBOdW1iZXJGb3JtYXR9IHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIHNob3VsZCBvbmx5IGJlIHVzZWQKKyAgICAgKiB0byBmb3JtYXQgZmxvYXRpbmctcG9pbnQgbnVtYmVycyB0eXBpY2FsbHkgYmV0d2VlbiAwIGFuZCAxICh3aXRoIDEgYmVpbmcgMTAwJSkuCisgICAgICogQSB2YWx1ZSBzdWNoIGFzIDAuNTMgd2lsbCBiZSB0cmVhdGVkIGFzIDUzJSwgYnV0IDUzLjAgKG9yIHRoZSBpbnRlZ2VyIDUzKSB3aWxsIGJlCisgICAgICogdHJlYXRlZCBhcyA1LDMwMCUsIHdoaWNoIGlzIHJhcmVseSB3aGF0IHlvdSBpbnRlbmRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE51bWJlckZvcm1hdCBnZXRQZXJjZW50SW5zdGFuY2UoKSB7CisgICAgICAgIHJldHVybiBnZXRQZXJjZW50SW5zdGFuY2UoTG9jYWxlLmdldERlZmF1bHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBOdW1iZXJGb3JtYXR9IGZvciBmb3JtYXR0aW5nIGFuZCBwYXJzaW5nIHBlcmNlbnRhZ2UKKyAgICAgKiB2YWx1ZXMgZm9yIHRoZSBnaXZlbiB7QGNvZGUgbG9jYWxlfS4KKyAgICAgKgorICAgICAqIDxwPlRoZSB7QGNvZGUgTnVtYmVyRm9ybWF0fSByZXR1cm5lZCBieSB0aGlzIG1ldGhvZCBzaG91bGQgb25seSBiZSB1c2VkCisgICAgICogdG8gZm9ybWF0IGZsb2F0aW5nLXBvaW50IG51bWJlcnMgdHlwaWNhbGx5IGJldHdlZW4gMCBhbmQgMSAod2l0aCAxIGJlaW5nIDEwMCUpLgorICAgICAqIEEgdmFsdWUgc3VjaCBhcyAwLjUzIHdpbGwgYmUgdHJlYXRlZCBhcyA1MyUsIGJ1dCA1My4wIChvciB0aGUgaW50ZWdlciA1Mykgd2lsbCBiZQorICAgICAqIHRyZWF0ZWQgYXMgNSwzMDAlLCB3aGljaCBpcyByYXJlbHkgd2hhdCB5b3UgaW50ZW5kZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBOdW1iZXJGb3JtYXQgZ2V0UGVyY2VudEluc3RhbmNlKExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgcmV0dXJuIGdldEluc3RhbmNlKExvY2FsZURhdGEuZ2V0KGxvY2FsZSkucGVyY2VudFBhdHRlcm4sIGxvY2FsZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIChncm91cGluZ1VzZWQgPyAxMjMxIDogMTIzNykgKyAocGFyc2VJbnRlZ2VyT25seSA/IDEyMzEgOiAxMjM3KQorICAgICAgICAgICAgICAgICsgbWF4aW11bUZyYWN0aW9uRGlnaXRzICsgbWF4aW11bUludGVnZXJEaWdpdHMKKyAgICAgICAgICAgICAgICArIG1pbmltdW1GcmFjdGlvbkRpZ2l0cyArIG1pbmltdW1JbnRlZ2VyRGlnaXRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgbnVtYmVyIGZvcm1hdCBmb3JtYXRzIGFuZCBwYXJzZXMgbnVtYmVycyB1c2luZyBhCisgICAgICogZ3JvdXBpbmcgc2VwYXJhdG9yLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYSBncm91cGluZyBzZXBhcmF0b3IgaXMgdXNlZDsge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzR3JvdXBpbmdVc2VkKCkgeworICAgICAgICByZXR1cm4gZ3JvdXBpbmdVc2VkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgbnVtYmVyIGZvcm1hdCBvbmx5IHBhcnNlcyBpbnRlZ2VyIG51bWJlcnMuIFBhcnNpbmcKKyAgICAgKiBzdG9wcyBpZiBhIGRlY2ltYWwgc2VwYXJhdG9yIGlzIGVuY291bnRlcmVkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBudW1iZXIgZm9ybWF0IG9ubHkgcGFyc2VzIGludGVnZXJzLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBpZiBpZiBwYXJzZXNlIGludGVnZXJzIGFzIHdlbGwgYXMgZnJhY3Rpb25zLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUGFyc2VJbnRlZ2VyT25seSgpIHsKKyAgICAgICAgcmV0dXJuIHBhcnNlSW50ZWdlck9ubHk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIGEge0Bjb2RlIE51bWJlcn0gZnJvbSB0aGUgc3BlY2lmaWVkIHN0cmluZyB1c2luZyB0aGUgcnVsZXMgb2YgdGhpcworICAgICAqIG51bWJlciBmb3JtYXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHBhcnNlLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBOdW1iZXJ9IHJlc3VsdGluZyBmcm9tIHRoZSBwYXJzaW5nLgorICAgICAqIEB0aHJvd3MgUGFyc2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBkdXJpbmcgcGFyc2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTnVtYmVyIHBhcnNlKFN0cmluZyBzdHJpbmcpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgIFBhcnNlUG9zaXRpb24gcG9zID0gbmV3IFBhcnNlUG9zaXRpb24oMCk7CisgICAgICAgIE51bWJlciBudW1iZXIgPSBwYXJzZShzdHJpbmcsIHBvcyk7CisgICAgICAgIGlmIChwb3MuZ2V0SW5kZXgoKSA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oIlVucGFyc2VhYmxlIG51bWJlcjogXCIiICsgc3RyaW5nICsgIlwiIiwgcG9zLmdldEVycm9ySW5kZXgoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bWJlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgYSB7QGNvZGUgTnVtYmVyfSBmcm9tIHRoZSBzcGVjaWZpZWQgc3RyaW5nIHN0YXJ0aW5nIGF0IHRoZSBpbmRleAorICAgICAqIHNwZWNpZmllZCBieSB7QGNvZGUgcG9zaXRpb259LiBJZiB0aGUgc3RyaW5nIGlzIHN1Y2Nlc3NmdWxseSBwYXJzZWQgdGhlbgorICAgICAqIHRoZSBpbmRleCBvZiB0aGUge0Bjb2RlIFBhcnNlUG9zaXRpb259IGlzIHVwZGF0ZWQgdG8gdGhlIGluZGV4IGZvbGxvd2luZworICAgICAqIHRoZSBwYXJzZWQgdGV4dC4gT24gZXJyb3IsIHRoZSBpbmRleCBpcyB1bmNoYW5nZWQgYW5kIHRoZSBlcnJvciBpbmRleCBvZgorICAgICAqIHtAY29kZSBQYXJzZVBvc2l0aW9ufSBpcyBzZXQgdG8gdGhlIGluZGV4IHdoZXJlIHRoZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gcGFyc2UuCisgICAgICogQHBhcmFtIHBvc2l0aW9uCisgICAgICogICAgICAgICAgICBpbnB1dC9vdXRwdXQgcGFyYW1ldGVyLCBzcGVjaWZpZXMgdGhlIHN0YXJ0IGluZGV4IGluCisgICAgICogICAgICAgICAgICB7QGNvZGUgc3RyaW5nfSBmcm9tIHdoZXJlIHRvIHN0YXJ0IHBhcnNpbmcuIElmIHBhcnNpbmcgaXMKKyAgICAgKiAgICAgICAgICAgIHN1Y2Nlc3NmdWwsIGl0IGlzIHVwZGF0ZWQgd2l0aCB0aGUgaW5kZXggZm9sbG93aW5nIHRoZSBwYXJzZWQKKyAgICAgKiAgICAgICAgICAgIHRleHQ7IG9uIGVycm9yLCB0aGUgaW5kZXggaXMgdW5jaGFuZ2VkIGFuZCB0aGUgZXJyb3IgaW5kZXggaXMKKyAgICAgKiAgICAgICAgICAgIHNldCB0byB0aGUgaW5kZXggd2hlcmUgdGhlIGVycm9yIG9jY3VycmVkLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBOdW1iZXJ9IHJlc3VsdGluZyBmcm9tIHRoZSBwYXJzZSBvciB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiAgICAgICAgIHRoZXJlIGlzIGFuIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBOdW1iZXIgcGFyc2UoU3RyaW5nIHN0cmluZywgUGFyc2VQb3NpdGlvbiBwb3NpdGlvbik7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZmluYWwgT2JqZWN0IHBhcnNlT2JqZWN0KFN0cmluZyBzdHJpbmcsIFBhcnNlUG9zaXRpb24gcG9zaXRpb24pIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicG9zaXRpb24gaXMgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gcGFyc2Uoc3RyaW5nLCBwb3NpdGlvbik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGN1cnJlbmN5IHVzZWQgYnkgdGhpcyBudW1iZXIgZm9ybWF0IHdoZW4gZm9ybWF0dGluZyBjdXJyZW5jeQorICAgICAqIHZhbHVlcy4gVGhlIG1pbiBhbmQgbWF4IGZyYWN0aW9uIGRpZ2l0cyByZW1haW4gdGhlIHNhbWUuCisgICAgICogPHA+CisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB0aHJvd3Mge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufSwKKyAgICAgKiBjb25jcmV0ZSBzdWJjbGFzc2VzIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZCBpZiB0aGV5IHN1cHBvcnQgY3VycmVuY3kKKyAgICAgKiBmb3JtYXR0aW5nLgorICAgICAqCisgICAgICogQHBhcmFtIGN1cnJlbmN5CisgICAgICogICAgICAgICAgICB0aGUgbmV3IGN1cnJlbmN5LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDdXJyZW5jeShDdXJyZW5jeSBjdXJyZW5jeSkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHdoZXRoZXIgdGhpcyBudW1iZXIgZm9ybWF0IGZvcm1hdHMgYW5kIHBhcnNlcyBudW1iZXJzIHVzaW5nIGEKKyAgICAgKiBncm91cGluZyBzZXBhcmF0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSB0cnVlfSBpZiBhIGdyb3VwaW5nIHNlcGFyYXRvciBpcyB1c2VkOyB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0R3JvdXBpbmdVc2VkKGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgICAgZ3JvdXBpbmdVc2VkID0gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbWF4aW11bSBudW1iZXIgb2YgZnJhY3Rpb24gZGlnaXRzIHRoYXQgYXJlIHByaW50ZWQgd2hlbgorICAgICAqIGZvcm1hdHRpbmcuIElmIHRoZSBtYXhpbXVtIGlzIGxlc3MgdGhhbiB0aGUgbnVtYmVyIG9mIGZyYWN0aW9uIGRpZ2l0cywKKyAgICAgKiB0aGUgbGVhc3Qgc2lnbmlmaWNhbnQgZGlnaXRzIGFyZSB0cnVuY2F0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBmcmFjdGlvbiBkaWdpdHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKGludCB2YWx1ZSkgeworICAgICAgICBtYXhpbXVtRnJhY3Rpb25EaWdpdHMgPSB2YWx1ZSA8IDAgPyAwIDogdmFsdWU7CisgICAgICAgIGlmIChtYXhpbXVtRnJhY3Rpb25EaWdpdHMgPCBtaW5pbXVtRnJhY3Rpb25EaWdpdHMpIHsKKyAgICAgICAgICAgIG1pbmltdW1GcmFjdGlvbkRpZ2l0cyA9IG1heGltdW1GcmFjdGlvbkRpZ2l0czsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5ldyBtYXhpbXVtIGNvdW50IG9mIGludGVnZXIgZGlnaXRzIHRoYXQgYXJlIHByaW50ZWQgd2hlbgorICAgICAqIGZvcm1hdHRpbmcuIElmIHRoZSBtYXhpbXVtIGlzIGxlc3MgdGhhbiB0aGUgbnVtYmVyIG9mIGludGVnZXIgZGlnaXRzLCB0aGUKKyAgICAgKiBtb3N0IHNpZ25pZmljYW50IGRpZ2l0cyBhcmUgdHJ1bmNhdGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbmV3IG1heGltdW0gbnVtYmVyIG9mIGludGVnZXIgbnVtZXJhbHMgZm9yIGRpc3BsYXkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TWF4aW11bUludGVnZXJEaWdpdHMoaW50IHZhbHVlKSB7CisgICAgICAgIG1heGltdW1JbnRlZ2VyRGlnaXRzID0gdmFsdWUgPCAwID8gMCA6IHZhbHVlOworICAgICAgICBpZiAobWF4aW11bUludGVnZXJEaWdpdHMgPCBtaW5pbXVtSW50ZWdlckRpZ2l0cykgeworICAgICAgICAgICAgbWluaW11bUludGVnZXJEaWdpdHMgPSBtYXhpbXVtSW50ZWdlckRpZ2l0czsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG1pbmltdW0gbnVtYmVyIG9mIGZyYWN0aW9uIGRpZ2l0cyB0aGF0IGFyZSBwcmludGVkIHdoZW4KKyAgICAgKiBmb3JtYXR0aW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbWluaW11bSBudW1iZXIgb2YgZnJhY3Rpb24gZGlnaXRzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1pbmltdW1GcmFjdGlvbkRpZ2l0cyhpbnQgdmFsdWUpIHsKKyAgICAgICAgbWluaW11bUZyYWN0aW9uRGlnaXRzID0gdmFsdWUgPCAwID8gMCA6IHZhbHVlOworICAgICAgICBpZiAobWF4aW11bUZyYWN0aW9uRGlnaXRzIDwgbWluaW11bUZyYWN0aW9uRGlnaXRzKSB7CisgICAgICAgICAgICBtYXhpbXVtRnJhY3Rpb25EaWdpdHMgPSBtaW5pbXVtRnJhY3Rpb25EaWdpdHM7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBtaW5pbXVtIG51bWJlciBvZiBpbnRlZ2VyIGRpZ2l0cyB0aGF0IGFyZSBwcmludGVkIHdoZW4KKyAgICAgKiBmb3JtYXR0aW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbWluaW11bSBudW1iZXIgb2YgaW50ZWdlciBkaWdpdHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TWluaW11bUludGVnZXJEaWdpdHMoaW50IHZhbHVlKSB7CisgICAgICAgIG1pbmltdW1JbnRlZ2VyRGlnaXRzID0gdmFsdWUgPCAwID8gMCA6IHZhbHVlOworICAgICAgICBpZiAobWF4aW11bUludGVnZXJEaWdpdHMgPCBtaW5pbXVtSW50ZWdlckRpZ2l0cykgeworICAgICAgICAgICAgbWF4aW11bUludGVnZXJEaWdpdHMgPSBtaW5pbXVtSW50ZWdlckRpZ2l0czsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNwZWNpZmllcyBpZiB0aGlzIG51bWJlciBmb3JtYXQgc2hvdWxkIHBhcnNlIG51bWJlcnMgb25seSBhcyBpbnRlZ2VycyBvcgorICAgICAqIGVsc2UgYXMgYW55IGtpbmQgb2YgbnVtYmVyLiBJZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgd2l0aCBhIHtAY29kZSB0cnVlfQorICAgICAqIHZhbHVlIHRoZW4gc3Vic2VxdWVudCBwYXJzaW5nIGF0dGVtcHRzIHdpbGwgc3RvcCBpZiBhIGRlY2ltYWwgc2VwYXJhdG9yCisgICAgICogaXMgZW5jb3VudGVyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSB0cnVlfSB0byBvbmx5IHBhcnNlIGludGVnZXJzLCB7QGNvZGUgZmFsc2V9IHRvIHBhcnNlCisgICAgICogICAgICAgICAgICBpbnRlZ2VycyBhcyB3ZWxsIGFzIGZyYWN0aW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQYXJzZUludGVnZXJPbmx5KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgICAgcGFyc2VJbnRlZ2VyT25seSA9IHZhbHVlOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFN0cmVhbUZpZWxkW10gc2VyaWFsUGVyc2lzdGVudEZpZWxkcyA9IHsKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJncm91cGluZ1VzZWQiLCBib29sZWFuLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJtYXhGcmFjdGlvbkRpZ2l0cyIsIGJ5dGUuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoIm1heGltdW1GcmFjdGlvbkRpZ2l0cyIsIGludC5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgibWF4aW11bUludGVnZXJEaWdpdHMiLCBpbnQuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoIm1heEludGVnZXJEaWdpdHMiLCBieXRlLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJtaW5GcmFjdGlvbkRpZ2l0cyIsIGJ5dGUuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoIm1pbmltdW1GcmFjdGlvbkRpZ2l0cyIsIGludC5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgibWluaW11bUludGVnZXJEaWdpdHMiLCBpbnQuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoIm1pbkludGVnZXJEaWdpdHMiLCBieXRlLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJwYXJzZUludGVnZXJPbmx5IiwgYm9vbGVhbi5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgic2VyaWFsVmVyc2lvbk9uU3RyZWFtIiwgaW50LmNsYXNzKSwKKyAgICB9OworCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdE91dHB1dFN0cmVhbS5QdXRGaWVsZCBmaWVsZHMgPSBzdHJlYW0ucHV0RmllbGRzKCk7CisgICAgICAgIGZpZWxkcy5wdXQoImdyb3VwaW5nVXNlZCIsIGdyb3VwaW5nVXNlZCk7CisgICAgICAgIGZpZWxkcy5wdXQoIm1heEZyYWN0aW9uRGlnaXRzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIG1heGltdW1GcmFjdGlvbkRpZ2l0cyA8IEJ5dGUuTUFYX1ZBTFVFID8gKGJ5dGUpIG1heGltdW1GcmFjdGlvbkRpZ2l0cworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IEJ5dGUuTUFYX1ZBTFVFKTsKKyAgICAgICAgZmllbGRzLnB1dCgibWF4aW11bUZyYWN0aW9uRGlnaXRzIiwgbWF4aW11bUZyYWN0aW9uRGlnaXRzKTsKKyAgICAgICAgZmllbGRzLnB1dCgibWF4aW11bUludGVnZXJEaWdpdHMiLCBtYXhpbXVtSW50ZWdlckRpZ2l0cyk7CisgICAgICAgIGZpZWxkcy5wdXQoIm1heEludGVnZXJEaWdpdHMiLAorICAgICAgICAgICAgICAgICAgICAgICAgbWF4aW11bUludGVnZXJEaWdpdHMgPCBCeXRlLk1BWF9WQUxVRSA/IChieXRlKSBtYXhpbXVtSW50ZWdlckRpZ2l0cworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IEJ5dGUuTUFYX1ZBTFVFKTsKKyAgICAgICAgZmllbGRzLnB1dCgibWluRnJhY3Rpb25EaWdpdHMiLAorICAgICAgICAgICAgICAgICAgICAgICAgbWluaW11bUZyYWN0aW9uRGlnaXRzIDwgQnl0ZS5NQVhfVkFMVUUgPyAoYnl0ZSkgbWluaW11bUZyYWN0aW9uRGlnaXRzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogQnl0ZS5NQVhfVkFMVUUpOworICAgICAgICBmaWVsZHMucHV0KCJtaW5pbXVtRnJhY3Rpb25EaWdpdHMiLCBtaW5pbXVtRnJhY3Rpb25EaWdpdHMpOworICAgICAgICBmaWVsZHMucHV0KCJtaW5pbXVtSW50ZWdlckRpZ2l0cyIsIG1pbmltdW1JbnRlZ2VyRGlnaXRzKTsKKyAgICAgICAgZmllbGRzLnB1dCgibWluSW50ZWdlckRpZ2l0cyIsCisgICAgICAgICAgICAgICAgbWluaW11bUludGVnZXJEaWdpdHMgPCBCeXRlLk1BWF9WQUxVRSA/IChieXRlKSBtaW5pbXVtSW50ZWdlckRpZ2l0cyA6IEJ5dGUuTUFYX1ZBTFVFKTsKKyAgICAgICAgZmllbGRzLnB1dCgicGFyc2VJbnRlZ2VyT25seSIsIHBhcnNlSW50ZWdlck9ubHkpOworICAgICAgICBmaWVsZHMucHV0KCJzZXJpYWxWZXJzaW9uT25TdHJlYW0iLCAxKTsKKyAgICAgICAgc3RyZWFtLndyaXRlRmllbGRzKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgICAgICBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0uR2V0RmllbGQgZmllbGRzID0gc3RyZWFtLnJlYWRGaWVsZHMoKTsKKyAgICAgICAgZ3JvdXBpbmdVc2VkID0gZmllbGRzLmdldCgiZ3JvdXBpbmdVc2VkIiwgdHJ1ZSk7CisgICAgICAgIHBhcnNlSW50ZWdlck9ubHkgPSBmaWVsZHMuZ2V0KCJwYXJzZUludGVnZXJPbmx5IiwgZmFsc2UpOworICAgICAgICBpZiAoZmllbGRzLmdldCgic2VyaWFsVmVyc2lvbk9uU3RyZWFtIiwgMCkgPT0gMCkgeworICAgICAgICAgICAgbWF4aW11bUZyYWN0aW9uRGlnaXRzID0gZmllbGRzLmdldCgibWF4RnJhY3Rpb25EaWdpdHMiLCAoYnl0ZSkgMyk7CisgICAgICAgICAgICBtYXhpbXVtSW50ZWdlckRpZ2l0cyA9IGZpZWxkcy5nZXQoIm1heEludGVnZXJEaWdpdHMiLCAoYnl0ZSkgNDApOworICAgICAgICAgICAgbWluaW11bUZyYWN0aW9uRGlnaXRzID0gZmllbGRzLmdldCgibWluRnJhY3Rpb25EaWdpdHMiLCAoYnl0ZSkgMCk7CisgICAgICAgICAgICBtaW5pbXVtSW50ZWdlckRpZ2l0cyA9IGZpZWxkcy5nZXQoIm1pbkludGVnZXJEaWdpdHMiLCAoYnl0ZSkgMSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBtYXhpbXVtRnJhY3Rpb25EaWdpdHMgPSBmaWVsZHMuZ2V0KCJtYXhpbXVtRnJhY3Rpb25EaWdpdHMiLCAzKTsKKyAgICAgICAgICAgIG1heGltdW1JbnRlZ2VyRGlnaXRzID0gZmllbGRzLmdldCgibWF4aW11bUludGVnZXJEaWdpdHMiLCA0MCk7CisgICAgICAgICAgICBtaW5pbXVtRnJhY3Rpb25EaWdpdHMgPSBmaWVsZHMuZ2V0KCJtaW5pbXVtRnJhY3Rpb25EaWdpdHMiLCAwKTsKKyAgICAgICAgICAgIG1pbmltdW1JbnRlZ2VyRGlnaXRzID0gZmllbGRzLmdldCgibWluaW11bUludGVnZXJEaWdpdHMiLCAxKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobWluaW11bUludGVnZXJEaWdpdHMgPiBtYXhpbXVtSW50ZWdlckRpZ2l0cworICAgICAgICAgICAgICAgIHx8IG1pbmltdW1GcmFjdGlvbkRpZ2l0cyA+IG1heGltdW1GcmFjdGlvbkRpZ2l0cykgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPYmplY3RFeGNlcHRpb24oIm1pbiBkaWdpdHMgZ3JlYXRlciB0aGFuIG1heCBkaWdpdHMiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobWluaW11bUludGVnZXJEaWdpdHMgPCAwIHx8IG1heGltdW1JbnRlZ2VyRGlnaXRzIDwgMAorICAgICAgICAgICAgICAgIHx8IG1pbmltdW1GcmFjdGlvbkRpZ2l0cyA8IDAgfHwgbWF4aW11bUZyYWN0aW9uRGlnaXRzIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPYmplY3RFeGNlcHRpb24oIm1pbiBvciBtYXggZGlnaXRzIG5lZ2F0aXZlIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW5zdGFuY2VzIG9mIHRoaXMgaW5uZXIgY2xhc3MgYXJlIHVzZWQgYXMgYXR0cmlidXRlIGtleXMgYW5kIHZhbHVlcworICAgICAqIGluIHtAY29kZSBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3J9IHRoYXQgdGhlCisgICAgICoge0BsaW5rIE51bWJlckZvcm1hdCNmb3JtYXRUb0NoYXJhY3Rlckl0ZXJhdG9yKE9iamVjdCl9IG1ldGhvZCByZXR1cm5zLgorICAgICAqIDxwPgorICAgICAqIFRoZXJlIGlzIG5vIHB1YmxpYyBjb25zdHJ1Y3RvciBpbiB0aGlzIGNsYXNzLCB0aGUgb25seSBpbnN0YW5jZXMgYXJlIHRoZQorICAgICAqIGNvbnN0YW50cyBkZWZpbmVkIGhlcmUuCisgICAgICogPHA+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBGaWVsZCBleHRlbmRzIEZvcm1hdC5GaWVsZCB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzQ5NDcyODg5MjcwMDE2MDg5MEw7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoaXMgY29uc3RhbnQgc3RhbmRzIGZvciB0aGUgbnVtYmVyIHNpZ24uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZpZWxkIFNJR04gPSBuZXcgRmllbGQoInNpZ24iKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhpcyBjb25zdGFudCBzdGFuZHMgZm9yIHRoZSBpbnRlZ2VyIHBhcnQgb2YgdGhlIG51bWJlci4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgSU5URUdFUiA9IG5ldyBGaWVsZCgiaW50ZWdlciIpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGlzIGNvbnN0YW50IHN0YW5kcyBmb3IgdGhlIGZyYWN0aW9uIHBhcnQgb2YgdGhlIG51bWJlci4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgRlJBQ1RJT04gPSBuZXcgRmllbGQoImZyYWN0aW9uIik7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoaXMgY29uc3RhbnQgc3RhbmRzIGZvciB0aGUgZXhwb25lbnQgcGFydCBvZiB0aGUgbnVtYmVyLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWVsZCBFWFBPTkVOVCA9IG5ldyBGaWVsZCgiZXhwb25lbnQiKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhpcyBjb25zdGFudCBzdGFuZHMgZm9yIHRoZSBleHBvbmVudCBzaWduIHN5bWJvbC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgRVhQT05FTlRfU0lHTiA9IG5ldyBGaWVsZCgiZXhwb25lbnQgc2lnbiIpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGlzIGNvbnN0YW50IHN0YW5kcyBmb3IgdGhlIGV4cG9uZW50IHN5bWJvbC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgRVhQT05FTlRfU1lNQk9MID0gbmV3IEZpZWxkKCJleHBvbmVudCBzeW1ib2wiKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhpcyBjb25zdGFudCBzdGFuZHMgZm9yIHRoZSBkZWNpbWFsIHNlcGFyYXRvci4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgREVDSU1BTF9TRVBBUkFUT1IgPSBuZXcgRmllbGQoImRlY2ltYWwgc2VwYXJhdG9yIik7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoaXMgY29uc3RhbnQgc3RhbmRzIGZvciB0aGUgZ3JvdXBpbmcgc2VwYXJhdG9yLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWVsZCBHUk9VUElOR19TRVBBUkFUT1IgPSBuZXcgRmllbGQoImdyb3VwaW5nIHNlcGFyYXRvciIpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGlzIGNvbnN0YW50IHN0YW5kcyBmb3IgdGhlIHBlcmNlbnQgc3ltYm9sLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWVsZCBQRVJDRU5UID0gbmV3IEZpZWxkKCJwZXJjZW50Iik7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoaXMgY29uc3RhbnQgc3RhbmRzIGZvciB0aGUgcGVybWlsbGUgc3ltYm9sLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWVsZCBQRVJNSUxMRSA9IG5ldyBGaWVsZCgicGVyIG1pbGxlIik7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoaXMgY29uc3RhbnQgc3RhbmRzIGZvciB0aGUgY3VycmVuY3kgc3ltYm9sLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWVsZCBDVVJSRU5DWSA9IG5ldyBGaWVsZCgiY3VycmVuY3kiKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgTnVtYmVyRm9ybWF0LkZpZWxkfSB3aXRoIHRoZQorICAgICAgICAgKiBnaXZlbiBmaWVsZCBuYW1lLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gZmllbGROYW1lCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGZpZWxkIG5hbWUuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgRmllbGQoU3RyaW5nIGZpZWxkTmFtZSkgeworICAgICAgICAgICAgc3VwZXIoZmllbGROYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBSb3VuZGluZ01vZGV9IHVzZWQgYnkgdGhpcyB7QGNvZGUgTnVtYmVyRm9ybWF0fS4gVGhlIGRlZmF1bHQKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBpbiB7QGNvZGUgTnVtYmVyRm9ybWF0fSB0aHJvd3Mge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufS4KKyAgICAgKiBTdWJjbGFzc2VzIGZvciB3aGljaCBhIHJvdW5kaW5nIG1vZGUgaXMgbWVhbmluZ2Z1bCBhcmUgZXhwZWN0ZWQgdG8gb3ZlcnJpZGUgdGhpcyBtZXRob2QuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBSb3VuZGluZ01vZGUgZ2V0Um91bmRpbmdNb2RlKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB7QGNvZGUgUm91bmRpbmdNb2RlfSB1c2VkIGJ5IHRoaXMge0Bjb2RlIE51bWJlckZvcm1hdH0uIFRoZSBkZWZhdWx0CisgICAgICogaW1wbGVtZW50YXRpb24gaW4ge0Bjb2RlIE51bWJlckZvcm1hdH0gdGhyb3dzIHtAY29kZSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0uCisgICAgICogU3ViY2xhc3NlcyBmb3Igd2hpY2ggYSByb3VuZGluZyBtb2RlIGlzIG1lYW5pbmdmdWwgYXJlIGV4cGVjdGVkIHRvIG92ZXJyaWRlIHRoaXMgbWV0aG9kLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSb3VuZGluZ01vZGUoUm91bmRpbmdNb2RlIHJvdW5kaW5nTW9kZSkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L1BhcnNlRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L1BhcnNlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTVmYWQzNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvUGFyc2VFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDUxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnRleHQ7CisKKy8qKgorICogVGhyb3duIHdoZW4gdGhlIHN0cmluZyBiZWluZyBwYXJzZWQgaXMgbm90IGluIHRoZSBjb3JyZWN0IGZvcm0uCisgKi8KK3B1YmxpYyBjbGFzcyBQYXJzZUV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAyNzAzMjE4NDQzMzIyNzg3NjM0TDsKKworICAgIHByaXZhdGUgaW50IGVycm9yT2Zmc2V0OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIHdpdGggaXRzIHN0YWNrIHRyYWNlLCBkZXRhaWwKKyAgICAgKiBtZXNzYWdlIGFuZCB0aGUgbG9jYXRpb24gb2YgdGhlIGVycm9yIGZpbGxlZCBpbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBsb2NhdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBwYXJzZSBleGNlcHRpb24gb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIFBhcnNlRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlLCBpbnQgbG9jYXRpb24pIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSArICgiIChhdCBvZmZzZXQgIiArIGxvY2F0aW9uICsgIikiKSk7CisgICAgICAgIGVycm9yT2Zmc2V0ID0gbG9jYXRpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggdGhpcyBwYXJzZSBleGNlcHRpb24gb2NjdXJyZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsb2NhdGlvbiBvZiB0aGlzIGV4Y2VwdGlvbiBpbiB0aGUgcGFyc2VkIHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEVycm9yT2Zmc2V0KCkgeworICAgICAgICByZXR1cm4gZXJyb3JPZmZzZXQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9QYXJzZVBvc2l0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L1BhcnNlUG9zaXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MWNlODY2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9QYXJzZVBvc2l0aW9uLmphdmEKQEAgLTAsMCArMSwxMTQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudGV4dDsKKworLyoqCisgKiBUcmFja3MgdGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gYSBwYXJzZWQgc3RyaW5nLiBJbiBjYXNlIG9mIGFuIGVycm9yIHRoZSBlcnJvcgorICogaW5kZXggY2FuIGJlIHNldCB0byB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIGVycm9yIG9jY3VycmVkIHdpdGhvdXQgaGF2aW5nIHRvCisgKiBjaGFuZ2UgdGhlIHBhcnNlIHBvc2l0aW9uLgorICovCitwdWJsaWMgY2xhc3MgUGFyc2VQb3NpdGlvbiB7CisKKyAgICBwcml2YXRlIGludCBjdXJyZW50UG9zaXRpb24sIGVycm9ySW5kZXggPSAtMTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFBhcnNlUG9zaXRpb259IHdpdGggdGhlIHNwZWNpZmllZCBpbmRleC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHRvIGJlZ2luIHBhcnNpbmcuCisgICAgICovCisgICAgcHVibGljIFBhcnNlUG9zaXRpb24oaW50IGluZGV4KSB7CisgICAgICAgIGN1cnJlbnRQb3NpdGlvbiA9IGluZGV4OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHRvIHRoaXMge0Bjb2RlIFBhcnNlUG9zaXRpb259IGFuZCBpbmRpY2F0ZXMKKyAgICAgKiBpZiB0aGV5IGFyZSBlcXVhbC4gSW4gb3JkZXIgdG8gYmUgZXF1YWwsIHtAY29kZSBvYmplY3R9IG11c3QgYmUgYW4KKyAgICAgKiBpbnN0YW5jZSBvZiB7QGNvZGUgUGFyc2VQb3NpdGlvbn0gYW5kIGl0IG11c3QgaGF2ZSB0aGUgc2FtZSBpbmRleCBhbmQKKyAgICAgKiBlcnJvciBpbmRleC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB3aXRoIHRoaXMgb2JqZWN0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBQYXJzZVBvc2l0aW9ufTsge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNlZSAjaGFzaENvZGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBQYXJzZVBvc2l0aW9uKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIFBhcnNlUG9zaXRpb24gcG9zID0gKFBhcnNlUG9zaXRpb24pIG9iamVjdDsKKyAgICAgICAgcmV0dXJuIGN1cnJlbnRQb3NpdGlvbiA9PSBwb3MuY3VycmVudFBvc2l0aW9uCisgICAgICAgICAgICAgICAgJiYgZXJyb3JJbmRleCA9PSBwb3MuZXJyb3JJbmRleDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgcGFyc2UgY291bGQgbm90IGNvbnRpbnVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIHBhcnNlIGVycm9yIG9yIC0xIGlmIHRoZXJlIGlzIG5vIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RXJyb3JJbmRleCgpIHsKKyAgICAgICAgcmV0dXJuIGVycm9ySW5kZXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3VycmVudCBwYXJzZSBwb3NpdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICovCisgICAgcHVibGljIGludCBnZXRJbmRleCgpIHsKKyAgICAgICAgcmV0dXJuIGN1cnJlbnRQb3NpdGlvbjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gY3VycmVudFBvc2l0aW9uICsgZXJyb3JJbmRleDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgcGFyc2UgY291bGQgbm90IGNvbnRpbnVlLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIHBhcnNlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySW5kZXgoaW50IGluZGV4KSB7CisgICAgICAgIGVycm9ySW5kZXggPSBpbmRleDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjdXJyZW50IHBhcnNlIHBvc2l0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgY3VycmVudCBwYXJzZSBwb3NpdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRJbmRleChpbnQgaW5kZXgpIHsKKyAgICAgICAgY3VycmVudFBvc2l0aW9uID0gaW5kZXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgcGFyc2UgcG9zaXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBwYXJzZSBwb3NpdGlvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiW2luZGV4PSIgKyBjdXJyZW50UG9zaXRpb24KKyAgICAgICAgICAgICAgICArICIsIGVycm9ySW5kZXg9IiArIGVycm9ySW5kZXggKyAiXSI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9SdWxlQmFzZWRCcmVha0l0ZXJhdG9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L1J1bGVCYXNlZEJyZWFrSXRlcmF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NDkwODMzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9SdWxlQmFzZWRCcmVha0l0ZXJhdG9yLmphdmEKQEAgLTAsMCArMSwxMTQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudGV4dDsKKworaW1wb3J0IGxpYmNvcmUuaWN1Lk5hdGl2ZUJyZWFrSXRlcmF0b3I7CisKKy8qCisgKiBEZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIEJyZWFrSXRlcmF0b3IuIFdyYXBzIGxpYmNvcmUuaWN1Lk5hdGl2ZUJyZWFrSXRlcmF0b3IuCisgKiBXZSBuZWVkIHRoaXMgYmVjYXVzZSBCcmVha0l0ZXJhdG9yLmlzQm91bmRhcnkgYW5kIEJyZWFrSXRlcmF0b3IucHJlY2VkaW5nIGFyZSBub24tYWJzdHJhY3QsCisgKiBhbmQgd2UgZG9uJ3QgaGF2ZSBKYXZhIGltcGxlbWVudGF0aW9ucyBvZiB0aG9zZSBtZXRob2RzIChvdGhlciB0aGFuIHRoZSBjdXJyZW50IG9uZXMsIHdoaWNoCisgKiBmb3J3YXJkIHRvIHRoZSB3cmFwcGVkIE5hdGl2ZUJyZWFrSXRlcmF0b3IpLgorICovCitjbGFzcyBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yIGV4dGVuZHMgQnJlYWtJdGVyYXRvciB7CisKKyAgICBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yKE5hdGl2ZUJyZWFrSXRlcmF0b3IgaXRlcmF0b3IpIHsKKyAgICAgICAgc3VwZXIoaXRlcmF0b3IpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGN1cnJlbnQoKSB7CisgICAgICAgIHJldHVybiB3cmFwcGVkLmN1cnJlbnQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCBmaXJzdCgpIHsKKyAgICAgICAgcmV0dXJuIHdyYXBwZWQuZmlyc3QoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCBmb2xsb3dpbmcoaW50IG9mZnNldCkgeworICAgICAgICB2YWxpZGF0ZU9mZnNldChvZmZzZXQpOworICAgICAgICByZXR1cm4gd3JhcHBlZC5mb2xsb3dpbmcob2Zmc2V0KTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIGNoZWNrIHRoZSBvZmZzZXQsIHRocm93IGV4Y2VwdGlvbiBpZiBpdCBpcyBpbnZhbGlkCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHZhbGlkYXRlT2Zmc2V0KGludCBvZmZzZXQpIHsKKyAgICAgICAgQ2hhcmFjdGVySXRlcmF0b3IgaXQgPSB3cmFwcGVkLmdldFRleHQoKTsKKyAgICAgICAgaWYgKG9mZnNldCA8IGl0LmdldEJlZ2luSW5kZXgoKSB8fCBvZmZzZXQgPiBpdC5nZXRFbmRJbmRleCgpKSB7CisgICAgICAgICAgICBTdHJpbmcgbWVzc2FnZSA9ICJWYWxpZCByYW5nZSBpcyBbIiArIGl0LmdldEJlZ2luSW5kZXgoKSArICIgIiArIGl0LmdldEVuZEluZGV4KCkgKyAiXSI7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKG1lc3NhZ2UpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBDaGFyYWN0ZXJJdGVyYXRvciBnZXRUZXh0KCkgeworICAgICAgICByZXR1cm4gd3JhcHBlZC5nZXRUZXh0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgbGFzdCgpIHsKKyAgICAgICAgcmV0dXJuIHdyYXBwZWQubGFzdCgpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IG5leHQoKSB7CisgICAgICAgIHJldHVybiB3cmFwcGVkLm5leHQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCBuZXh0KGludCBuKSB7CisgICAgICAgIHJldHVybiB3cmFwcGVkLm5leHQobik7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgcHJldmlvdXMoKSB7CisgICAgICAgIHJldHVybiB3cmFwcGVkLnByZXZpb3VzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHNldFRleHQoQ2hhcmFjdGVySXRlcmF0b3IgbmV3VGV4dCkgeworICAgICAgICAvLyBjYWxsIGEgbWV0aG9kIHRvIGNoZWNrIGlmIG51bGwgcG9pbnRlcgorICAgICAgICBuZXdUZXh0LmN1cnJlbnQoKTsKKyAgICAgICAgd3JhcHBlZC5zZXRUZXh0KG5ld1RleHQpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc0JvdW5kYXJ5KGludCBvZmZzZXQpIHsKKyAgICAgICAgdmFsaWRhdGVPZmZzZXQob2Zmc2V0KTsKKyAgICAgICAgcmV0dXJuIHdyYXBwZWQuaXNCb3VuZGFyeShvZmZzZXQpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHByZWNlZGluZyhpbnQgb2Zmc2V0KSB7CisgICAgICAgIHZhbGlkYXRlT2Zmc2V0KG9mZnNldCk7CisgICAgICAgIHJldHVybiB3cmFwcGVkLnByZWNlZGluZyhvZmZzZXQpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgaWYgKCEobyBpbnN0YW5jZW9mIFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3IpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHdyYXBwZWQuZXF1YWxzKCgoUnVsZUJhc2VkQnJlYWtJdGVyYXRvcikgbykud3JhcHBlZCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiB3cmFwcGVkLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiB3cmFwcGVkLmhhc2hDb2RlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3IgY2xvbmVkID0gKFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3IpIHN1cGVyLmNsb25lKCk7CisgICAgICAgIGNsb25lZC53cmFwcGVkID0gKE5hdGl2ZUJyZWFrSXRlcmF0b3IpIHdyYXBwZWQuY2xvbmUoKTsKKyAgICAgICAgcmV0dXJuIGNsb25lZDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L1J1bGVCYXNlZENvbGxhdG9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L1J1bGVCYXNlZENvbGxhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGZkODY1MAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvUnVsZUJhc2VkQ29sbGF0b3IuamF2YQpAQCAtMCwwICsxLDQzMCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS50ZXh0OworCitpbXBvcnQgbGliY29yZS5pY3UuUnVsZUJhc2VkQ29sbGF0b3JJQ1U7CisKKy8qKgorICogQSBjb25jcmV0ZSBpbXBsZW1lbnRhdGlvbiBjbGFzcyBmb3Ige0Bjb2RlIENvbGxhdGlvbn0uCisgKiA8cD4KKyAqIHtAY29kZSBSdWxlQmFzZWRDb2xsYXRvcn0gaGFzIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zIGZvciBlZmZpY2llbmN5CisgKiAob3RoZXIgc3ViY2xhc3NlcyBtYXkgYmUgdXNlZCBmb3IgbW9yZSBjb21wbGV4IGxhbmd1YWdlcyk6CisgKiA8b2w+CisgKiA8bGk+IElmIGEgRnJlbmNoIHNlY29uZGFyeSBvcmRlcmluZyBpcyBzcGVjaWZpZWQgaXQgYXBwbGllcyB0byB0aGUgd2hvbGUKKyAqIGNvbGxhdG9yIG9iamVjdC48L2xpPgorICogPGxpPiBBbGwgbm9uLW1lbnRpb25lZCBVbmljb2RlIGNoYXJhY3RlcnMgYXJlIGF0IHRoZSBlbmQgb2YgdGhlIGNvbGxhdGlvbgorICogb3JkZXIuPC9saT4KKyAqIDxsaT4gSWYgYSBjaGFyYWN0ZXIgaXMgbm90IGxvY2F0ZWQgaW4gdGhlIHtAY29kZSBSdWxlQmFzZWRDb2xsYXRvcn0sIHRoZQorICogZGVmYXVsdCBVbmljb2RlIENvbGxhdGlvbiBBbGdvcml0aG0gKFVDQSkgcnVsZS1iYXNlZCB0YWJsZSBpcyBhdXRvbWF0aWNhbGx5CisgKiBzZWFyY2hlZCBhcyBhIGJhY2t1cC48L2xpPgorICogPC9vbD4KKyAqIDxwPgorICogVGhlIGNvbGxhdGlvbiB0YWJsZSBpcyBjb21wb3NlZCBvZiBhIGxpc3Qgb2YgY29sbGF0aW9uIHJ1bGVzLCB3aGVyZSBlYWNoIHJ1bGUKKyAqIGlzIG9mIHRocmVlIGZvcm1zOgorICogPGJsb2NrcXVvdGU+CisgKiA8cHJlPgorICogJmx0O21vZGlmaWVyJmd0OworICogJmx0O3JlbGF0aW9uJmd0OyAmbHQ7dGV4dC1hcmd1bWVudCZndDsKKyAqICZsdDtyZXNldCZndDsgJmx0O3RleHQtYXJndW1lbnQmZ3Q7CisgKiA8L3ByZT4KKyAqIDwvYmxvY2txdW90ZT4KKyAqIDxwPgorICogVGhlIHJ1bGUgZWxlbWVudHMgYXJlIGRlZmluZWQgYXMgZm9sbG93czoKKyAqIDx1bCB0eXBlPSJkaXNjIj4KKyAqIDxsaT48c3Ryb25nPk1vZGlmaWVyPC9zdHJvbmc+OiBUaGVyZSBpcyBhIHNpbmdsZSBtb2RpZmllciB3aGljaCBpcyB1c2VkIHRvCisgKiBzcGVjaWZ5IHRoYXQgYWxsIGFjY2VudHMgKHNlY29uZGFyeSBkaWZmZXJlbmNlcykgYXJlIGJhY2t3YXJkczoKKyAqIDx1bCB0eXBlPXNxdWFyZT4KKyAqIDxsaT4nQCcgOiBJbmRpY2F0ZXMgdGhhdCBhY2NlbnRzIGFyZSBzb3J0ZWQgYmFja3dhcmRzLCBhcyBpbiBGcmVuY2guCisgKiA8L3VsPgorICogPC9saT4KKyAqIDxsaT48c3Ryb25nPlJlbGF0aW9uPC9zdHJvbmc+OiBUaGUgcmVsYXRpb25zIGFyZSB0aGUgZm9sbG93aW5nOgorICogPHVsIHR5cGU9c3F1YXJlPgorICogPGxpPicmbHQ7JyA6IEdyZWF0ZXIsIGFzIGEgbGV0dGVyIGRpZmZlcmVuY2UgKHByaW1hcnkpCisgKiA8bGk+JzsnIDogR3JlYXRlciwgYXMgYW4gYWNjZW50IGRpZmZlcmVuY2UgKHNlY29uZGFyeSkKKyAqIDxsaT4nLCcgOiBHcmVhdGVyLCBhcyBhIGNhc2UgZGlmZmVyZW5jZSAodGVydGlhcnkpCisgKiA8bGk+Jz0nIDogRXF1YWwKKyAqIDwvdWw+CisgKiA8L2xpPgorICogPGxpPjxzdHJvbmc+VGV4dC1Bcmd1bWVudDwvc3Ryb25nPjogQSB0ZXh0LWFyZ3VtZW50IGlzIGFueSBzZXF1ZW5jZSBvZgorICogY2hhcmFjdGVycywgZXhjbHVkaW5nIHNwZWNpYWwgY2hhcmFjdGVycyAodGhhdCBpcywgY29tbW9uIHdoaXRlc3BhY2UKKyAqIGNoYXJhY3RlcnMgWzAwMDktMDAwRCwgMDAyMF0gYW5kIHJ1bGUgc3ludGF4IGNoYXJhY3RlcnMgWzAwMjEtMDAyRiwKKyAqIDAwM0EtMDA0MCwgMDA1Qi0wMDYwLCAwMDdCLTAwN0VdKS4gSWYgdGhvc2UgY2hhcmFjdGVycyBhcmUgZGVzaXJlZCwgeW91IGNhbgorICogcHV0IHRoZW0gaW4gc2luZ2xlIHF1b3RlcyAoZm9yIGV4YW1wbGUsIHVzZSAnJmFtcDsnIGZvciBhbXBlcnNhbmQpLiBOb3RlIHRoYXQKKyAqIHVucXVvdGVkIHdoaXRlIHNwYWNlIGNoYXJhY3RlcnMgYXJlIGlnbm9yZWQ7IGZvciBleGFtcGxlLCB7QGNvZGUgYiBjfSBpcworICogdHJlYXRlZCBhcyB7QGNvZGUgYmN9LjwvbGk+CisgKiA8bGk+PHN0cm9uZz5SZXNldDwvc3Ryb25nPjogVGhlcmUgaXMgYSBzaW5nbGUgcmVzZXQgd2hpY2ggaXMgdXNlZCBwcmltYXJpbHkKKyAqIGZvciBjb250cmFjdGlvbnMgYW5kIGV4cGFuc2lvbnMsIGJ1dCB3aGljaCBjYW4gYWxzbyBiZSB1c2VkIHRvIGFkZCBhCisgKiBtb2RpZmljYXRpb24gYXQgdGhlIGVuZCBvZiBhIHNldCBvZiBydWxlczoKKyAqIDx1bCB0eXBlPXNxdWFyZT4KKyAqIDxsaT4nJmFtcDsnIDogSW5kaWNhdGVzIHRoYXQgdGhlIG5leHQgcnVsZSBmb2xsb3dzIHRoZSBwb3NpdGlvbiB0byB3aGVyZSB0aGUgcmVzZXQKKyAqIHRleHQtYXJndW1lbnQgd291bGQgYmUgc29ydGVkLgorICogPC91bD4KKyAqIDwvbGk+CisgKiA8L3VsPgorICogPHA+CisgKiBUaGlzIHNvdW5kcyBtb3JlIGNvbXBsaWNhdGVkIHRoYW4gaXQgaXMgaW4gcHJhY3RpY2UuIEZvciBleGFtcGxlLCB0aGUKKyAqIGZvbGxvd2luZyBhcmUgZXF1aXZhbGVudCB3YXlzIG9mIGV4cHJlc3NpbmcgdGhlIHNhbWUgdGhpbmc6CisgKiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogYSA8IGIgPCBjCisgKiBhIDwgYiAmIGIgPCBjCisgKiBhIDwgYyAmIGEgPCBiCisgKiA8L3ByZT4KKyAqCisgKiA8L2Jsb2NrcXVvdGU+CisgKiA8cD4KKyAqIE5vdGljZSB0aGF0IHRoZSBvcmRlciBpcyBpbXBvcnRhbnQsIGFzIHRoZSBzdWJzZXF1ZW50IGl0ZW0gZ29lcyBpbW1lZGlhdGVseQorICogYWZ0ZXIgdGhlIHRleHQtYXJndW1lbnQuIFRoZSBmb2xsb3dpbmcgYXJlIG5vdCBlcXVpdmFsZW50OgorICogPGJsb2NrcXVvdGU+CisgKgorICogPHByZT4KKyAqIGEgPCBiICYgYSA8IGMKKyAqIGEgPCBjICYgYSA8IGIKKyAqIDwvcHJlPgorICoKKyAqIDwvYmxvY2txdW90ZT4KKyAqIDxwPgorICogRWl0aGVyIHRoZSB0ZXh0LWFyZ3VtZW50IG11c3QgYWxyZWFkeSBiZSBwcmVzZW50IGluIHRoZSBzZXF1ZW5jZSwgb3Igc29tZQorICogaW5pdGlhbCBzdWJzdHJpbmcgb2YgdGhlIHRleHQtYXJndW1lbnQgbXVzdCBiZSBwcmVzZW50LiBGb3IgZXhhbXBsZQorICoge0Bjb2RlICJhIDwgYiAmIGFlIDwgZSJ9IGlzIHZhbGlkIHNpbmNlICJhIiBpcyBwcmVzZW50IGluIHRoZSBzZXF1ZW5jZSBiZWZvcmUKKyAqICJhZSIgaXMgcmVzZXQuIEluIHRoaXMgbGF0dGVyIGNhc2UsICJhZSIgaXMgbm90IGVudGVyZWQgYW5kIHRyZWF0ZWQgYXMgYQorICogc2luZ2xlIGNoYXJhY3RlcjsgaW5zdGVhZCwgImUiIGlzIHNvcnRlZCBhcyBpZiBpdCB3ZXJlIGV4cGFuZGVkIHRvIHR3bworICogY2hhcmFjdGVyczogImEiIGZvbGxvd2VkIGJ5IGFuICJlIi4gVGhpcyBkaWZmZXJlbmNlIGFwcGVhcnMgaW4gbmF0dXJhbAorICogbGFuZ3VhZ2VzOiBpbiB0cmFkaXRpb25hbCBTcGFuaXNoICJjaCIgaXMgdHJlYXRlZCBhcyBpZiBpdCBjb250cmFjdHMgdG8gYQorICogc2luZ2xlIGNoYXJhY3RlciAoZXhwcmVzc2VkIGFzIHtAY29kZSAiYyA8IGNoIDwgZCJ9KSwgd2hpbGUgaW4gdHJhZGl0aW9uYWwKKyAqIEdlcm1hbiBhLXVtbGF1dCBpcyB0cmVhdGVkIGFzIGlmIGl0IGV4cGFuZHMgdG8gdHdvIGNoYXJhY3RlcnMgKGV4cHJlc3NlZCBhcworICoge0Bjb2RlICJhLEEgPCBiLEIgIC4uLiAmIGFlO1x1MDBlMyAmIEFFO1x1MDBjMyJ9LCB3aGVyZSBcdTAwZTMgYW5kIFx1MDBjMworICogYXJlIHRoZSBlc2NhcGUgc2VxdWVuY2VzIGZvciBhLXVtbGF1dCkuCisgKiA8aDQ+SWdub3JhYmxlIENoYXJhY3RlcnM8L2g0PgorICogPHA+CisgKiBGb3IgaWdub3JhYmxlIGNoYXJhY3RlcnMsIHRoZSBmaXJzdCBydWxlIG11c3Qgc3RhcnQgd2l0aCBhIHJlbGF0aW9uICh0aGUKKyAqIGV4YW1wbGVzIHdlIGhhdmUgdXNlZCBhYm92ZSBhcmUgcmVhbGx5IGZyYWdtZW50czsge0Bjb2RlICJhIDwgYiJ9IHJlYWxseQorICogc2hvdWxkIGJlIHtAY29kZSAiPCBhIDwgYiJ9KS4gSWYsIGhvd2V2ZXIsIHRoZSBmaXJzdCByZWxhdGlvbiBpcyBub3QKKyAqIHtAY29kZSAiPCJ9LCB0aGVuIGFsbCB0ZXh0LWFyZ3VtZW50cyB1cCB0byB0aGUgZmlyc3Qge0Bjb2RlICI8In0gYXJlCisgKiBpZ25vcmFibGUuIEZvciBleGFtcGxlLCB7QGNvZGUgIiwgLSA8IGEgPCBiIn0gbWFrZXMge0Bjb2RlICItIn0gYW4gaWdub3JhYmxlCisgKiBjaGFyYWN0ZXIuCisgKiA8aDQ+Tm9ybWFsaXphdGlvbiBhbmQgQWNjZW50czwvaDQ+CisgKiA8cD4KKyAqIHtAY29kZSBSdWxlQmFzZWRDb2xsYXRvcn0gYXV0b21hdGljYWxseSBwcm9jZXNzZXMgaXRzIHJ1bGUgdGFibGUgdG8gaW5jbHVkZQorICogYm90aCBwcmUtY29tcG9zZWQgYW5kIGNvbWJpbmluZy1jaGFyYWN0ZXIgdmVyc2lvbnMgb2YgYWNjZW50ZWQgY2hhcmFjdGVycy4KKyAqIEV2ZW4gaWYgdGhlIHByb3ZpZGVkIHJ1bGUgc3RyaW5nIGNvbnRhaW5zIG9ubHkgYmFzZSBjaGFyYWN0ZXJzIGFuZCBzZXBhcmF0ZQorICogY29tYmluaW5nIGFjY2VudCBjaGFyYWN0ZXJzLCB0aGUgcHJlLWNvbXBvc2VkIGFjY2VudGVkIGNoYXJhY3RlcnMgbWF0Y2hpbmcKKyAqIGFsbCBjYW5vbmljYWwgY29tYmluYXRpb25zIG9mIGNoYXJhY3RlcnMgZnJvbSB0aGUgcnVsZSBzdHJpbmcgd2lsbCBiZSBlbnRlcmVkCisgKiBpbiB0aGUgdGFibGUuCisgKiA8cD4KKyAqIFRoaXMgYWxsb3dzIHlvdSB0byB1c2UgYSBSdWxlQmFzZWRDb2xsYXRvciB0byBjb21wYXJlIGFjY2VudGVkIHN0cmluZ3MgZXZlbgorICogd2hlbiB0aGUgY29sbGF0b3IgaXMgc2V0IHRvIE5PX0RFQ09NUE9TSVRJT04uIEhvd2V2ZXIsIGlmIHRoZSBzdHJpbmdzIHRvIGJlCisgKiBjb2xsYXRlZCBjb250YWluIGNvbWJpbmluZyBzZXF1ZW5jZXMgdGhhdCBtYXkgbm90IGJlIGluIGNhbm9uaWNhbCBvcmRlciwgeW91CisgKiBzaG91bGQgc2V0IHRoZSBjb2xsYXRvciB0byBDQU5PTklDQUxfREVDT01QT1NJVElPTiB0byBlbmFibGUgc29ydGluZyBvZgorICogY29tYmluaW5nIHNlcXVlbmNlcy4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSA8YQorICogaHJlZj0iaHR0cDovL3d3dy5hdy5jb20vZGV2cHJlc3MiPlRoZSBVbmljb2RlIFN0YW5kYXJkLCBWZXJzaW9uIDMuMDwvYT4uCisgKiA8aDQ+RXJyb3JzPC9oND4KKyAqIDxwPgorICogVGhlIGZvbGxvd2luZyBydWxlcyBhcmUgbm90IHZhbGlkOgorICogPHVsIHR5cGU9ImRpc2MiPgorICogPGxpPkEgdGV4dC1hcmd1bWVudCBjb250YWlucyB1bnF1b3RlZCBwdW5jdHVhdGlvbiBzeW1ib2xzLCBmb3IgZXhhbXBsZQorICoge0Bjb2RlICJhIDwgYi1jIDwgZCJ9LjwvbGk+CisgKiA8bGk+QSByZWxhdGlvbiBvciByZXNldCBjaGFyYWN0ZXIgaXMgbm90IGZvbGxvd2VkIGJ5IGEgdGV4dC1hcmd1bWVudCwgZm9yCisgKiBleGFtcGxlIHtAY29kZSAiYSA8ICwgYiJ9LjwvbGk+CisgKiA8bGk+QSByZXNldCB3aGVyZSB0aGUgdGV4dC1hcmd1bWVudCAob3IgYW4gaW5pdGlhbCBzdWJzdHJpbmcgb2YgdGhlCisgKiB0ZXh0LWFyZ3VtZW50KSBpcyBub3QgYWxyZWFkeSBpbiB0aGUgc2VxdWVuY2Ugb3IgYWxsb2NhdGVkIGluIHRoZSBkZWZhdWx0IFVDQQorICogdGFibGUsIGZvciBleGFtcGxlIHtAY29kZSAiYSA8IGIgJiBlIDwgZiJ9LjwvbGk+CisgKiA8L3VsPgorICogPHA+CisgKiBJZiB5b3UgcHJvZHVjZSBvbmUgb2YgdGhlc2UgZXJyb3JzLCB7QGNvZGUgUnVsZUJhc2VkQ29sbGF0b3J9IHRocm93cyBhCisgKiB7QGNvZGUgUGFyc2VFeGNlcHRpb259LgorICogPGg0PkV4YW1wbGVzPC9oND4KKyAqIDxwPgorICogTm9ybWFsbHksIHRvIGNyZWF0ZSBhIHJ1bGUtYmFzZWQgY29sbGF0b3Igb2JqZWN0LCB5b3Ugd2lsbCB1c2UKKyAqIHtAY29kZSBDb2xsYXRvcn0ncyBmYWN0b3J5IG1ldGhvZCB7QGNvZGUgZ2V0SW5zdGFuY2V9LiBIb3dldmVyLCB0byBjcmVhdGUgYQorICogcnVsZS1iYXNlZCBjb2xsYXRvciBvYmplY3Qgd2l0aCBzcGVjaWFsaXplZCBydWxlcyB0YWlsb3JlZCB0byB5b3VyIG5lZWRzLCB5b3UKKyAqIGNvbnN0cnVjdCB0aGUge0Bjb2RlIFJ1bGVCYXNlZENvbGxhdG9yfSB3aXRoIHRoZSBydWxlcyBjb250YWluZWQgaW4gYQorICoge0Bjb2RlIFN0cmluZ30gb2JqZWN0LiBGb3IgZXhhbXBsZToKKyAqIDxibG9ja3F1b3RlPgorICoKKyAqIDxwcmU+CisgKiBTdHJpbmcgU2ltcGxlID0gIjwgYSA8IGIgPCBjIDwgZCI7CisgKiBSdWxlQmFzZWRDb2xsYXRvciBteVNpbXBsZSA9IG5ldyBSdWxlQmFzZWRDb2xsYXRvcihTaW1wbGUpOworICogPC9wcmU+CisgKgorICogPC9ibG9ja3F1b3RlPgorICogPHA+CisgKiBPcjoKKyAqIDxibG9ja3F1b3RlPgorICoKKyAqIDxwcmU+CisgKiBTdHJpbmcgTm9yd2VnaWFuID0gIjwgYSxBPCBiLEI8IGMsQzwgZCxEPCBlLEU8IGYsRjwgZyxHPCBoLEg8IGksSSIKKyAqICAgICAgICAgKyAiPCBqLEo8IGssSzwgbCxMPCBtLE08IG4sTjwgbyxPPCBwLFA8IHEsUTwgcixSIgorICogICAgICAgICArICI8IHMsUzwgdCxUPCB1LFU8IHYsVjwgdyxXPCB4LFg8IHksWTwgeixaIgorICogICAgICAgICArICI8IFx1MDBFNT1hXHUwMzBBLFx1MDBDNT1BXHUwMzBBIgorICogICAgICAgICArICI7YWEsQUE8IFx1MDBFNixcdTAwQzY8IFx1MDBGOCxcdTAwRDgiOworICogUnVsZUJhc2VkQ29sbGF0b3IgbXlOb3J3ZWdpYW4gPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoTm9yd2VnaWFuKTsKKyAqIDwvcHJlPgorICoKKyAqIDwvYmxvY2txdW90ZT4KKyAqIDxwPgorICogQ29tYmluaW5nIHtAY29kZSBDb2xsYXRvcn1zIGlzIGFzIHNpbXBsZSBhcyBjb25jYXRlbmF0aW5nIHN0cmluZ3MuIEhlcmUgaXMKKyAqIGFuIGV4YW1wbGUgdGhhdCBjb21iaW5lcyB0d28ge0Bjb2RlIENvbGxhdG9yfXMgZnJvbSB0d28gZGlmZmVyZW50IGxvY2FsZXM6CisgKiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogLy8gQ3JlYXRlIGFuIGVuX1VTIENvbGxhdG9yIG9iamVjdAorICogUnVsZUJhc2VkQ29sbGF0b3IgZW5fVVNDb2xsYXRvciA9IChSdWxlQmFzZWRDb2xsYXRvcilDb2xsYXRvcgorICogICAgICAgICAuZ2V0SW5zdGFuY2UobmV3IExvY2FsZSgiZW4iLCAiVVMiLCAiIikpOworICoKKyAqIC8vIENyZWF0ZSBhIGRhX0RLIENvbGxhdG9yIG9iamVjdAorICogUnVsZUJhc2VkQ29sbGF0b3IgZGFfREtDb2xsYXRvciA9IChSdWxlQmFzZWRDb2xsYXRvcilDb2xsYXRvcgorICogICAgICAgICAuZ2V0SW5zdGFuY2UobmV3IExvY2FsZSgiZGEiLCAiREsiLCAiIikpOworICoKKyAqIC8vIENvbWJpbmUgdGhlIHR3byBjb2xsYXRvcnMKKyAqIC8vIEZpcnN0LCBnZXQgdGhlIGNvbGxhdGlvbiBydWxlcyBmcm9tIGVuX1VTQ29sbGF0b3IKKyAqIFN0cmluZyBlbl9VU1J1bGVzID0gZW5fVVNDb2xsYXRvci5nZXRSdWxlcygpOworICoKKyAqIC8vIFNlY29uZCwgZ2V0IHRoZSBjb2xsYXRpb24gcnVsZXMgZnJvbSBkYV9ES0NvbGxhdG9yCisgKiBTdHJpbmcgZGFfREtSdWxlcyA9IGRhX0RLQ29sbGF0b3IuZ2V0UnVsZXMoKTsKKyAqCisgKiBSdWxlQmFzZWRDb2xsYXRvciBuZXdDb2xsYXRvciA9IG5ldyBSdWxlQmFzZWRDb2xsYXRvcihlbl9VU1J1bGVzICsgZGFfREtSdWxlcyk7CisgKiAvLyBuZXdDb2xsYXRvciBoYXMgdGhlIGNvbWJpbmVkIHJ1bGVzCisgKiA8L3ByZT4KKyAqCisgKiA8L2Jsb2NrcXVvdGU+CisgKiA8cD4KKyAqIFRoZSBuZXh0IGV4YW1wbGUgc2hvd3MgdG8gbWFrZSBjaGFuZ2VzIG9uIGFuIGV4aXN0aW5nIHRhYmxlIHRvIGNyZWF0ZSBhIG5ldworICoge0Bjb2RlIENvbGxhdG9yfSBvYmplY3QuIEZvciBleGFtcGxlLCBhZGQge0Bjb2RlICImIEMgPCBjaCwgY0gsIENoLCBDSCJ9IHRvCisgKiB0aGUge0Bjb2RlIGVuX1VTQ29sbGF0b3J9IG9iamVjdCB0byBjcmVhdGUgeW91ciBvd246CisgKiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogLy8gQ3JlYXRlIGEgbmV3IENvbGxhdG9yIG9iamVjdCB3aXRoIGFkZGl0aW9uYWwgcnVsZXMKKyAqIFN0cmluZyBhZGRSdWxlcyA9ICImIEMgPCBjaCwgY0gsIENoLCBDSCI7CisgKgorICogUnVsZUJhc2VkQ29sbGF0b3IgbXlDb2xsYXRvciA9IG5ldyBSdWxlQmFzZWRDb2xsYXRvcihlbl9VU0NvbGxhdG9yICsgYWRkUnVsZXMpOworICogLy8gbXlDb2xsYXRvciBjb250YWlucyB0aGUgbmV3IHJ1bGVzCisgKiA8L3ByZT4KKyAqCisgKiA8L2Jsb2NrcXVvdGU+CisgKiA8cD4KKyAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBkZW1vbnN0cmF0ZXMgaG93IHRvIGNoYW5nZSB0aGUgb3JkZXIgb2Ygbm9uLXNwYWNpbmcKKyAqIGFjY2VudHM6CisgKiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogLy8gb2xkIHJ1bGUKKyAqIFN0cmluZyBvbGRSdWxlcyA9ICI9IFx1MDBhOCA7IFx1MDBhZiA7IFx1MDBiZiIgKyAiPCBhICwgQSA7IGFlLCBBRSA7IFx1MDBlNiAsIFx1MDBjNiIKKyAqICAgICAgICAgKyAiPCBiICwgQiA8IGMsIEMgPCBlLCBFICYgQyA8IGQsIEQiOworICoKKyAqIC8vIGNoYW5nZSB0aGUgb3JkZXIgb2YgYWNjZW50IGNoYXJhY3RlcnMKKyAqIFN0cmluZyBhZGRPbiA9ICImIFx1MDBiZiA7IFx1MDBhZiA7IFx1MDBhODsiOworICoKKyAqIFJ1bGVCYXNlZENvbGxhdG9yIG15Q29sbGF0b3IgPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3Iob2xkUnVsZXMgKyBhZGRPbik7CisgKiA8L3ByZT4KKyAqCisgKiA8L2Jsb2NrcXVvdGU+CisgKiA8cD4KKyAqIFRoZSBsYXN0IGV4YW1wbGUgc2hvd3MgaG93IHRvIHB1dCBuZXcgcHJpbWFyeSBvcmRlcmluZyBpbiBiZWZvcmUgdGhlIGRlZmF1bHQKKyAqIHNldHRpbmcuIEZvciBleGFtcGxlLCBpbiB0aGUgSmFwYW5lc2Uge0Bjb2RlIENvbGxhdG9yfSwgeW91IGNhbiBlaXRoZXIgc29ydAorICogRW5nbGlzaCBjaGFyYWN0ZXJzIGJlZm9yZSBvciBhZnRlciBKYXBhbmVzZSBjaGFyYWN0ZXJzOgorICogPGJsb2NrcXVvdGU+CisgKgorICogPHByZT4KKyAqIC8vIGdldCBlbl9VUyBDb2xsYXRvciBydWxlcworICogUnVsZUJhc2VkQ29sbGF0b3IgZW5fVVNDb2xsYXRvciA9IChSdWxlQmFzZWRDb2xsYXRvcikKKyAqICAgICBDb2xsYXRvci5nZXRJbnN0YW5jZShMb2NhbGUuVVMpOworICoKKyAqIC8vIGFkZCBhIGZldyBKYXBhbmVzZSBjaGFyYWN0ZXIgdG8gc29ydCBiZWZvcmUgRW5nbGlzaCBjaGFyYWN0ZXJzCisgKiAvLyBzdXBwb3NlIHRoZSBsYXN0IGNoYXJhY3RlciBiZWZvcmUgdGhlIGZpcnN0IGJhc2UgbGV0dGVyICdhJyBpbgorICogLy8gdGhlIEVuZ2xpc2ggY29sbGF0aW9uIHJ1bGUgaXMgXHUzMEEyCisgKiBTdHJpbmcgamFTdHJpbmcgPSAiJiBcdTMwQTIgLCBcdTMwRkMgPCBcdTMwQzgiOworICoKKyAqIFJ1bGVCYXNlZENvbGxhdG9yIG15SmFwYW5lc2VDb2xsYXRvciA9CisgKiAgICAgbmV3IFJ1bGVCYXNlZENvbGxhdG9yKGVuX1VTQ29sbGF0b3IuZ2V0UnVsZXMoKSArIGphU3RyaW5nKTsKKyAqIDwvcHJlPgorICoKKyAqIDwvYmxvY2txdW90ZT4KKyAqLworcHVibGljIGNsYXNzIFJ1bGVCYXNlZENvbGxhdG9yIGV4dGVuZHMgQ29sbGF0b3IgeworICAgIFJ1bGVCYXNlZENvbGxhdG9yKFJ1bGVCYXNlZENvbGxhdG9ySUNVIHdyYXBwZXIpIHsKKyAgICAgICAgc3VwZXIod3JhcHBlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgUnVsZUJhc2VkQ29sbGF0b3J9IHVzaW5nIHRoZQorICAgICAqIHNwZWNpZmllZCB7QGNvZGUgcnVsZXN9LiBUaGUge0Bjb2RlIHJ1bGVzfSBhcmUgdXN1YWxseSBlaXRoZXIKKyAgICAgKiBoYW5kLXdyaXR0ZW4gYmFzZWQgb24gdGhlIHtAbGluayBSdWxlQmFzZWRDb2xsYXRvciBjbGFzcyBkZXNjcmlwdGlvbn0gb3IKKyAgICAgKiB0aGUgcmVzdWx0IG9mIGEgZm9ybWVyIHtAbGluayAjZ2V0UnVsZXMoKX0gY2FsbC4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlIHRoYXQgdGhlIHtAY29kZSBydWxlc30gYXJlIGFjdHVhbGx5IGludGVycHJldGVkIGFzIGEgZGVsdGEgdG8gdGhlCisgICAgICogc3RhbmRhcmQgVW5pY29kZSBDb2xsYXRpb24gQWxnb3JpdGhtIChVQ0EpLiBUaGlzIGRpZmZlcnMKKyAgICAgKiBzbGlnaHRseSBmcm9tIG90aGVyIGltcGxlbWVudGF0aW9ucyB3aGljaCB3b3JrIHdpdGggZnVsbCB7QGNvZGUgcnVsZXN9CisgICAgICogc3BlY2lmaWNhdGlvbnMgYW5kIG1heSByZXN1bHQgaW4gZGlmZmVyZW50IGJlaGF2aW9yLgorICAgICAqCisgICAgICogQHBhcmFtIHJ1bGVzCisgICAgICogICAgICAgICAgICB0aGUgY29sbGF0aW9uIHJ1bGVzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcnVsZXMgPT0gbnVsbH0uCisgICAgICogQHRocm93cyBQYXJzZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBydWxlc30gY29udGFpbnMgcnVsZXMgd2l0aCBpbnZhbGlkIGNvbGxhdGlvbiBydWxlCisgICAgICogICAgICAgICAgICAgc3ludGF4LgorICAgICAqLworICAgIHB1YmxpYyBSdWxlQmFzZWRDb2xsYXRvcihTdHJpbmcgcnVsZXMpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChydWxlcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocnVsZXMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oImVtcHR5IHJ1bGVzIiwgMCk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGljdUNvbGwgPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3JJQ1UocnVsZXMpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBQYXJzZUV4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgIHRocm93IChQYXJzZUV4Y2VwdGlvbikgZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiAtMSBtZWFucyBpdCdzIG5vdCBhIFBhcnNlRXhjZXB0aW9uLiBNYXliZSBJT0V4Y2VwdGlvbiB0aHJvd24gd2hlbgorICAgICAgICAgICAgICogYW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgcmVhZGluZyBpbnRlcm5hbCBkYXRhLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCksIC0xKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIE9idGFpbnMgYSB7QGNvZGUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yfSBmb3IgdGhlIGdpdmVuCisgICAgICoge0Bjb2RlIENoYXJhY3Rlckl0ZXJhdG9yfS4gVGhlIHNvdXJjZSBpdGVyYXRvcidzIGludGVncml0eSB3aWxsIGJlCisgICAgICogcHJlc2VydmVkIHNpbmNlIGEgbmV3IGNvcHkgd2lsbCBiZSBjcmVhdGVkIGZvciB1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc291cmNlCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGNoYXJhY3RlciBpdGVyYXRvci4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcn0gZm9yIHtAY29kZSBzb3VyY2V9LgorICAgICAqLworICAgIHB1YmxpYyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgZ2V0Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKENoYXJhY3Rlckl0ZXJhdG9yIHNvdXJjZSkgeworICAgICAgICBpZiAoc291cmNlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGljdUNvbGwuZ2V0Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKHNvdXJjZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE9idGFpbnMgYSB7QGNvZGUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yfSBmb3IgdGhlIGdpdmVuIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzb3VyY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2Ugc3RyaW5nLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3J9IGZvciB7QGNvZGUgc291cmNlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihTdHJpbmcgc291cmNlKSB7CisgICAgICAgIGlmIChzb3VyY2UgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoaWN1Q29sbC5nZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Ioc291cmNlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29sbGF0aW9uIHJ1bGVzIG9mIHRoaXMgY29sbGF0b3IuIFRoZXNlIHtAY29kZSBydWxlc30gY2FuIGJlCisgICAgICogZmVkIGludG8gdGhlIHtAY29kZSBSdWxlQmFzZWRDb2xsYXRvcihTdHJpbmcpfSBjb25zdHJ1Y3Rvci4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlIHRoYXQgdGhlIHtAY29kZSBydWxlc30gYXJlIGFjdHVhbGx5IGludGVycHJldGVkIGFzIGEgZGVsdGEgdG8gdGhlCisgICAgICogc3RhbmRhcmQgVW5pY29kZSBDb2xsYXRpb24gQWxnb3JpdGhtIChVQ0EpLiBIZW5jZSwgYW4gZW1wdHkge0Bjb2RlIHJ1bGVzfQorICAgICAqIHN0cmluZyByZXN1bHRzIGluIHRoZSBkZWZhdWx0IFVDQSBydWxlcyBiZWluZyBhcHBsaWVkLiBUaGlzIGRpZmZlcnMKKyAgICAgKiBzbGlnaHRseSBmcm9tIG90aGVyIGltcGxlbWVudGF0aW9ucyB3aGljaCB3b3JrIHdpdGggZnVsbCB7QGNvZGUgcnVsZXN9CisgICAgICogc3BlY2lmaWNhdGlvbnMgYW5kIG1heSByZXN1bHQgaW4gZGlmZmVyZW50IGJlaGF2aW9yLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29sbGF0aW9uIHJ1bGVzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UnVsZXMoKSB7CisgICAgICAgIHJldHVybiBpY3VDb2xsLmdldFJ1bGVzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBjb2xsYXRvciB3aXRoIHRoZSBzYW1lIGNvbGxhdGlvbiBydWxlcywgZGVjb21wb3NpdGlvbiBtb2RlIGFuZAorICAgICAqIHN0cmVuZ3RoIHZhbHVlIGFzIHRoaXMgY29sbGF0b3IuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc2hhbGxvdyBjb3B5IG9mIHRoaXMgY29sbGF0b3IuCisgICAgICogQHNlZSBqYXZhLmxhbmcuQ2xvbmVhYmxlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgY2xvbmUgPSAoUnVsZUJhc2VkQ29sbGF0b3IpIHN1cGVyLmNsb25lKCk7CisgICAgICAgIHJldHVybiBjbG9uZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUge0Bjb2RlIHNvdXJjZX0gdGV4dCB0byB0aGUge0Bjb2RlIHRhcmdldH0gdGV4dCBhY2NvcmRpbmcgdG8KKyAgICAgKiB0aGUgY29sbGF0aW9uIHJ1bGVzLCBzdHJlbmd0aCBhbmQgZGVjb21wb3NpdGlvbiBtb2RlIGZvciB0aGlzCisgICAgICoge0Bjb2RlIFJ1bGVCYXNlZENvbGxhdG9yfS4gU2VlIHRoZSB7QGNvZGUgQ29sbGF0b3J9IGNsYXNzIGRlc2NyaXB0aW9uCisgICAgICogZm9yIGFuIGV4YW1wbGUgb2YgdXNlLgorICAgICAqIDxwPgorICAgICAqIEdlbmVyYWwgcmVjb21tZW5kYXRpb246IElmIGNvbXBhcmlzb25zIGFyZSB0byBiZSBkb25lIHdpdGggdGhlIHNhbWUgc3RyaW5ncworICAgICAqIG11bHRpcGxlIHRpbWVzLCBpdCBpcyBtb3JlIGVmZmljaWVudCB0byBnZW5lcmF0ZSB7QGNvZGUgQ29sbGF0aW9uS2V5fQorICAgICAqIG9iamVjdHMgZm9yIHRoZSBzdHJpbmdzIGFuZCB1c2UKKyAgICAgKiB7QGNvZGUgQ29sbGF0aW9uS2V5LmNvbXBhcmVUbyhDb2xsYXRpb25LZXkpfSBmb3IgdGhlIGNvbXBhcmlzb25zLiBJZiBlYWNoCisgICAgICogc3RyaW5nIGlzIGNvbXBhcmVkIHRvIG9ubHkgb25jZSwgdXNpbmcKKyAgICAgKiB7QGNvZGUgUnVsZUJhc2VkQ29sbGF0b3IuY29tcGFyZShTdHJpbmcsIFN0cmluZyl9IGhhcyBiZXR0ZXIgcGVyZm9ybWFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc291cmNlCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIHRleHQuCisgICAgICogQHBhcmFtIHRhcmdldAorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCB0ZXh0LgorICAgICAqIEByZXR1cm4gYW4gaW50ZWdlciB3aGljaCBtYXkgYmUgYSBuZWdhdGl2ZSB2YWx1ZSwgemVybywgb3IgZWxzZSBhCisgICAgICogICAgICAgICBwb3NpdGl2ZSB2YWx1ZSBkZXBlbmRpbmcgb24gd2hldGhlciB7QGNvZGUgc291cmNlfSBpcyBsZXNzIHRoYW4sCisgICAgICogICAgICAgICBlcXVpdmFsZW50IHRvLCBvciBncmVhdGVyIHRoYW4ge0Bjb2RlIHRhcmdldH0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBjb21wYXJlKFN0cmluZyBzb3VyY2UsIFN0cmluZyB0YXJnZXQpIHsKKyAgICAgICAgaWYgKHNvdXJjZSA9PSBudWxsIHx8IHRhcmdldCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaWN1Q29sbC5jb21wYXJlKHNvdXJjZSwgdGFyZ2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgQ29sbGF0aW9uS2V5fSBmb3IgdGhlIGdpdmVuIHNvdXJjZSB0ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBzb3VyY2UgdGV4dC4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgQ29sbGF0aW9uS2V5fSBmb3IgdGhlIGdpdmVuIHNvdXJjZSB0ZXh0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDb2xsYXRpb25LZXkgZ2V0Q29sbGF0aW9uS2V5KFN0cmluZyBzb3VyY2UpIHsKKyAgICAgICAgcmV0dXJuIGljdUNvbGwuZ2V0Q29sbGF0aW9uS2V5KHNvdXJjZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIGljdUNvbGwuZ2V0UnVsZXMoKS5oYXNoQ29kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHdpdGggdGhpcyB7QGNvZGUgUnVsZUJhc2VkQ29sbGF0b3J9IGFuZAorICAgICAqIGluZGljYXRlcyBpZiB0aGV5IGFyZSBlcXVhbC4gSW4gb3JkZXIgdG8gYmUgZXF1YWwsIHtAY29kZSBvYmplY3R9IG11c3QgYmUKKyAgICAgKiBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgQ29sbGF0b3J9IHdpdGggdGhlIHNhbWUgY29sbGF0aW9uIHJ1bGVzIGFuZCB0aGUKKyAgICAgKiBzYW1lIGF0dHJpYnV0ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUgd2l0aCB0aGlzIG9iamVjdC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBlcXVhbCB0byB0aGlzCisgICAgICogICAgICAgICB7QGNvZGUgUnVsZUJhc2VkQ29sbGF0b3J9OyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNoYXNoQ29kZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIENvbGxhdG9yKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L1NpbXBsZURhdGVGb3JtYXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvU2ltcGxlRGF0ZUZvcm1hdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFmOWI2OTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L1NpbXBsZURhdGVGb3JtYXQuamF2YQpAQCAtMCwwICsxLDEzMDkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudGV4dDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUZpZWxkOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZTsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CitpbXBvcnQgbGliY29yZS5pY3UuTG9jYWxlRGF0YTsKK2ltcG9ydCBsaWJjb3JlLmljdS5UaW1lWm9uZXM7CisKKy8qKgorICogQSBjb25jcmV0ZSBjbGFzcyBmb3IgZm9ybWF0dGluZyBhbmQgcGFyc2luZyBkYXRlcyBpbiBhIGxvY2FsZS1zZW5zaXRpdmUKKyAqIG1hbm5lci4gRm9ybWF0dGluZyB0dXJucyBhIHtAbGluayBEYXRlfSBpbnRvIGEge0BsaW5rIFN0cmluZ30sIGFuZCBwYXJzaW5nIHR1cm5zIGEKKyAqIHtAY29kZSBTdHJpbmd9IGludG8gYSB7QGNvZGUgRGF0ZX0uCisgKgorICogPGg0PlRpbWUgUGF0dGVybiBTeW50YXg8L2g0PgorICogPHA+WW91IGNhbiBzdXBwbHkgYSBwYXR0ZXJuIGRlc2NyaWJpbmcgd2hhdCBzdHJpbmdzIGFyZSBwcm9kdWNlZC9hY2NlcHRlZCwgYnV0IGFsbW9zdCBhbGwKKyAqIGNhbGxlcnMgc2hvdWxkIHVzZSB7QGxpbmsgRGF0ZUZvcm1hdCNnZXREYXRlSW5zdGFuY2V9LCB7QGxpbmsgRGF0ZUZvcm1hdCNnZXREYXRlVGltZUluc3RhbmNlfSwKKyAqIG9yIHtAbGluayBEYXRlRm9ybWF0I2dldFRpbWVJbnN0YW5jZX0gdG8gZ2V0IGEgcmVhZHktbWFkZSBpbnN0YW5jZSBzdWl0YWJsZSBmb3IgdGhlIHVzZXIncworICogbG9jYWxlLgorICoKKyAqIDxwPlRoZSBtYWluIHJlYXNvbiB5b3UnZCBjcmVhdGUgYW4gaW5zdGFuY2UgdGhpcyBjbGFzcyBkaXJlY3RseSBpcyBiZWNhdXNlIHlvdSBuZWVkIHRvCisgKiBmb3JtYXQvcGFyc2UgYSBzcGVjaWZpYyBtYWNoaW5lLXJlYWRhYmxlIGZvcm1hdCwgaW4gd2hpY2ggY2FzZSB5b3UgYWxtb3N0IGNlcnRhaW5seSB3YW50CisgKiB0byBleHBsaWNpdGx5IGFzayBmb3Ige0BsaW5rIExvY2FsZSNVU30gdG8gZW5zdXJlIHRoYXQgeW91IGdldCBBU0NJSSBkaWdpdHMgKHJhdGhlciB0aGFuLAorICogc2F5LCBBcmFiaWMgZGlnaXRzKS4KKyAqIChTZWUgIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuKQorICogVGhlIG1vc3QgdXNlZnVsIG5vbi1sb2NhbGl6ZWQgcGF0dGVybiBpcyB7QGNvZGUgInl5eXktTU0tZGQgSEg6bW06c3MuU1NTWiJ9LCB3aGljaCBjb3JyZXNwb25kcworICogdG8gdGhlIElTTyA4NjAxIGludGVybmF0aW9uYWwgc3RhbmRhcmQgZGF0ZSBmb3JtYXQuCisgKgorICogPHA+VG8gc3BlY2lmeSB0aGUgdGltZSBmb3JtYXQsIHVzZSBhIDxpPnRpbWUgcGF0dGVybjwvaT4gc3RyaW5nLiBJbiB0aGlzCisgKiBzdHJpbmcsIGFueSBjaGFyYWN0ZXIgZnJvbSB7QGNvZGUgJ0EnfSB0byB7QGNvZGUgJ1onfSBvciB7QGNvZGUgJ2EnfSB0byB7QGNvZGUgJ3onfSBpcworICogdHJlYXRlZCBzcGVjaWFsbHkuIEFsbCBvdGhlciBjaGFyYWN0ZXJzIGFyZSBwYXNzZWQgdGhyb3VnaCB2ZXJiYXRpbS4gVGhlIGludGVycHJldGF0aW9uIG9mIGVhY2gKKyAqIG9mIHRoZSBBU0NJSSBsZXR0ZXJzIGlzIGdpdmVuIGluIHRoZSB0YWJsZSBiZWxvdy4gQVNDSUkgbGV0dGVycyBub3QgYXBwZWFyaW5nIGluIHRoZSB0YWJsZSBhcmUKKyAqIHJlc2VydmVkIGZvciBmdXR1cmUgdXNlLCBhbmQgaXQgaXMgYW4gZXJyb3IgdG8gYXR0ZW1wdCB0byB1c2UgdGhlbS4KKyAqCisgKiA8cD48dGFibGUgQk9SREVSPSIxIiBXSURUSD0iMTAwJSIgQ0VMTFBBRERJTkc9IjMiIENFTExTUEFDSU5HPSIwIiBTVU1NQVJZPSIiPgorICogPHRyIEJHQ09MT1I9IiNDQ0NDRkYiIENMQVNTPSJUYWJsZUhlYWRpbmdDb2xvciI+CisgKiAgICAgIDx0ZD48Qj5TeW1ib2w8L0I+PC90ZD4gPHRkPjxCPk1lYW5pbmc8L0I+PC90ZD4gPHRkPjxCPlByZXNlbnRhdGlvbjwvQj48L3RkPiA8dGQ+PEI+RXhhbXBsZTwvQj48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlIER9PC90ZD4gPHRkPmRheSBpbiB5ZWFyPC90ZD4gICAgICAgICAgICAgPHRkPihOdW1iZXIpPC90ZD4gICAgICA8dGQ+MTg5PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPntAY29kZSBFfTwvdGQ+IDx0ZD5kYXkgb2Ygd2VlazwvdGQ+ICAgICAgICAgICAgIDx0ZD4oVGV4dCk8L3RkPiAgICAgICAgPHRkPlR1ZXNkYXk8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlIEZ9PC90ZD4gPHRkPmRheSBvZiB3ZWVrIGluIG1vbnRoPC90ZD4gICAgPHRkPihOdW1iZXIpPC90ZD4gICAgICA8dGQ+MiA8aT4oMm5kIFdlZCBpbiBKdWx5KTwvaT48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlIEd9PC90ZD4gPHRkPmVyYSBkZXNpZ25hdG9yPC90ZD4gICAgICAgICAgPHRkPihUZXh0KTwvdGQ+ICAgICAgICA8dGQ+QUQ8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlIEh9PC90ZD4gPHRkPmhvdXIgaW4gZGF5ICgwLTIzKTwvdGQ+ICAgICAgPHRkPihOdW1iZXIpPC90ZD4gICAgICA8dGQ+MDwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD57QGNvZGUgS308L3RkPiA8dGQ+aG91ciBpbiBhbS9wbSAoMC0xMSk8L3RkPiAgICA8dGQ+KE51bWJlcik8L3RkPiAgICAgIDx0ZD4wPC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPntAY29kZSBMfTwvdGQ+IDx0ZD5zdGFuZC1hbG9uZSBtb250aDwvdGQ+ICAgICAgIDx0ZD4oVGV4dC9OdW1iZXIpPC90ZD4gPHRkPkp1bHkgLyAwNzwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD57QGNvZGUgTX08L3RkPiA8dGQ+bW9udGggaW4geWVhcjwvdGQ+ICAgICAgICAgICA8dGQ+KFRleHQvTnVtYmVyKTwvdGQ+IDx0ZD5KdWx5IC8gMDc8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlIFN9PC90ZD4gPHRkPmZyYWN0aW9uYWwgc2Vjb25kczwvdGQ+ICAgICAgPHRkPihOdW1iZXIpPC90ZD4gICAgICA8dGQ+OTc4PC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPntAY29kZSBXfTwvdGQ+IDx0ZD53ZWVrIGluIG1vbnRoPC90ZD4gICAgICAgICAgIDx0ZD4oTnVtYmVyKTwvdGQ+ICAgICAgPHRkPjI8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlIFp9PC90ZD4gPHRkPnRpbWUgem9uZSAoUkZDIDgyMik8L3RkPiAgICAgPHRkPihUaW1lem9uZSk8L3RkPiAgICA8dGQ+LTA4MDA8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlIGF9PC90ZD4gPHRkPmFtL3BtIG1hcmtlcjwvdGQ+ICAgICAgICAgICAgPHRkPihUZXh0KTwvdGQ+ICAgICAgICA8dGQ+UE08L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlIGN9PC90ZD4gPHRkPnN0YW5kLWFsb25lIGRheSBvZiB3ZWVrPC90ZD4gPHRkPihUZXh0L051bWJlcik8L3RkPiA8dGQ+VHVlc2RheSAvIDI8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlIGR9PC90ZD4gPHRkPmRheSBpbiBtb250aDwvdGQ+ICAgICAgICAgICAgPHRkPihOdW1iZXIpPC90ZD4gICAgICA8dGQ+MTA8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlIGh9PC90ZD4gPHRkPmhvdXIgaW4gYW0vcG0gKDEtMTIpPC90ZD4gICAgPHRkPihOdW1iZXIpPC90ZD4gICAgICA8dGQ+MTI8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlIGt9PC90ZD4gPHRkPmhvdXIgaW4gZGF5ICgxLTI0KTwvdGQ+ICAgICAgPHRkPihOdW1iZXIpPC90ZD4gICAgICA8dGQ+MjQ8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlIG19PC90ZD4gPHRkPm1pbnV0ZSBpbiBob3VyPC90ZD4gICAgICAgICAgPHRkPihOdW1iZXIpPC90ZD4gICAgICA8dGQ+MzA8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlIHN9PC90ZD4gPHRkPnNlY29uZCBpbiBtaW51dGU8L3RkPiAgICAgICAgPHRkPihOdW1iZXIpPC90ZD4gICAgICA8dGQ+NTU8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlIHd9PC90ZD4gPHRkPndlZWsgaW4geWVhcjwvdGQ+ICAgICAgICAgICAgPHRkPihOdW1iZXIpPC90ZD4gICAgICA8dGQ+Mjc8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlIHl9PC90ZD4gPHRkPnllYXI8L3RkPiAgICAgICAgICAgICAgICAgICAgPHRkPihOdW1iZXIpPC90ZD4gICAgICA8dGQ+MjAxMDwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD57QGNvZGUgen08L3RkPiA8dGQ+dGltZSB6b25lPC90ZD4gICAgICAgICAgICAgICA8dGQ+KFRpbWV6b25lKTwvdGQ+ICAgIDx0ZD5QYWNpZmljIFN0YW5kYXJkIFRpbWU8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+e0Bjb2RlICd9PC90ZD4gPHRkPmVzY2FwZSBmb3IgdGV4dDwvdGQ+ICAgICAgICAgPHRkPihEZWxpbWl0ZXIpPC90ZD4gICA8dGQ+J0RhdGU9JzwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD57QGNvZGUgJyd9PC90ZD4gPHRkPnNpbmdsZSBxdW90ZTwvdGQ+ICAgICAgICAgICA8dGQ+KExpdGVyYWwpPC90ZD4gICAgIDx0ZD4nbycnY2xvY2snPC90ZD4gPC90cj4KKyAqIDwvdGFibGU+CisgKgorICogPHA+VGhlIG51bWJlciBvZiBjb25zZWN1dGl2ZSBjb3BpZXMgKHRoZSAiY291bnQiKSBvZiBhIHBhdHRlcm4gY2hhcmFjdGVyIGZ1cnRoZXIgaW5mbHVlbmNlcworICogdGhlIGZvcm1hdC4KKyAqIDx1bD4KKyAqIDxsaT48Yj5UZXh0PC9iPiBpZiB0aGUgY291bnQgaXMgNCBvciBtb3JlLCB1c2UgdGhlIGZ1bGwgZm9ybTsgb3RoZXJ3aXNlIHVzZSBhIHNob3J0IG9yCisgKiBhYmJyZXZpYXRlZCBmb3JtIGlmIG9uZSBleGlzdHMuIFNvIHtAY29kZSB6enp6fSBtaWdodCBnaXZlIHtAY29kZSBQYWNpZmljIFN0YW5kYXJkIFRpbWV9CisgKiB3aGVyZWFzIHtAY29kZSB6fSBtaWdodCBnaXZlIHtAY29kZSBQU1R9LiBOb3RlIHRoYXQgdGhlIGNvdW50IGRvZXMgPGk+bm90PC9pPiBzcGVjaWZ5IHRoZQorICogZXhhY3Qgd2lkdGggb2YgdGhlIGZpZWxkLgorICoKKyAqIDxsaT48Yj5OdW1iZXI8L2I+IHRoZSBjb3VudCBpcyB0aGUgbWluaW11bSBudW1iZXIgb2YgZGlnaXRzLiBTaG9ydGVyIHZhbHVlcyBhcmUKKyAqIHplcm8tcGFkZGVkIHRvIHRoaXMgd2lkdGgsIGxvbmdlciB2YWx1ZXMgb3ZlcmZsb3cgdGhpcyB3aWR0aC4KKyAqCisgKiA8cD5ZZWFycyBhcmUgaGFuZGxlZCBzcGVjaWFsbHk6IHtAY29kZSB5eX0gdHJ1bmNhdGVzIHRvIHRoZSBsYXN0IDIgZGlnaXRzLCBidXQgYW55CisgKiBvdGhlciBudW1iZXIgb2YgY29uc2VjdXRpdmUge0Bjb2RlIHl9cyBkb2VzIG5vdCB0cnVuY2F0ZS4gU28gd2hlcmUge0Bjb2RlIHl5eXl9IG9yCisgKiB7QGNvZGUgeX0gbWlnaHQgZ2l2ZSB7QGNvZGUgMjAxMH0sIHtAY29kZSB5eX0gd291bGQgZ2l2ZSB7QGNvZGUgMTB9LgorICoKKyAqIDxwPkZyYWN0aW9uYWwgc2Vjb25kcyBhcmUgYWxzbyBoYW5kbGVkIHNwZWNpYWxseTogdGhleSdyZSB6ZXJvLXBhZGRlZCBvbiB0aGUKKyAqIDxpPnJpZ2h0PC9pPi4KKyAqCisgKiA8bGk+PGI+VGV4dC9OdW1iZXI8L2I+OiBpZiB0aGUgY291bnQgaXMgMyBvciBtb3JlLCB1c2UgdGV4dDsgb3RoZXJ3aXNlIHVzZSBhIG51bWJlci4KKyAqIFNvIHtAY29kZSBNTX0gbWlnaHQgZ2l2ZSB7QGNvZGUgMDd9IHdoaWxlIHtAY29kZSBNTU19IGdpdmVzIHtAY29kZSBKdWx5fS4KKyAqIDwvdWw+CisgKgorICogPHA+VGhlIHR3byBwYXR0ZXJuIGNoYXJhY3RlcnMge0Bjb2RlIEx9IGFuZCB7QGNvZGUgY30gYXJlIElDVS1jb21wYXRpYmxlIGV4dGVuc2lvbnMsIG5vdAorICogYXZhaWxhYmxlIGluIHRoZSBSSS4gVGhlc2UgYXJlIG5lY2Vzc2FyeSBmb3IgY29ycmVjdCBsb2NhbGl6YXRpb24gaW4gbGFuZ3VhZ2VzIHN1Y2ggYXMgUnVzc2lhbgorICogdGhhdCBkaXN0aW5ndWlzaCBiZXR3ZWVuLCBzYXksICJKdW5lIiBhbmQgIkp1bmUgMjAxMCIuCisgKgorICogPHA+V2hlbiBudW1lcmljIGZpZWxkcyBhcmUgYWRqYWNlbnQgZGlyZWN0bHksIHdpdGggbm8gaW50ZXJ2ZW5pbmcgZGVsaW1pdGVyCisgKiBjaGFyYWN0ZXJzLCB0aGV5IGNvbnN0aXR1dGUgYSBydW4gb2YgYWRqYWNlbnQgbnVtZXJpYyBmaWVsZHMuIFN1Y2ggcnVucyBhcmUKKyAqIHBhcnNlZCBzcGVjaWFsbHkuIEZvciBleGFtcGxlLCB0aGUgZm9ybWF0ICJISG1tc3MiIHBhcnNlcyB0aGUgaW5wdXQgdGV4dAorICogIjEyMzQ1NiIgdG8gMTI6MzQ6NTYsIHBhcnNlcyB0aGUgaW5wdXQgdGV4dCAiMTIzNDUiIHRvIDE6MjM6NDUsIGFuZCBmYWlscyB0bworICogcGFyc2UgIjEyMzQiLiBJbiBvdGhlciB3b3JkcywgdGhlIGxlZnRtb3N0IGZpZWxkIG9mIHRoZSBydW4gaXMgZmxleGlibGUsCisgKiB3aGlsZSB0aGUgb3RoZXJzIGtlZXAgYSBmaXhlZCB3aWR0aC4gSWYgdGhlIHBhcnNlIGZhaWxzIGFueXdoZXJlIGluIHRoZSBydW4sCisgKiB0aGVuIHRoZSBsZWZ0bW9zdCBmaWVsZCBpcyBzaG9ydGVuZWQgYnkgb25lIGNoYXJhY3RlciwgYW5kIHRoZSBlbnRpcmUgcnVuIGlzCisgKiBwYXJzZWQgYWdhaW4uIFRoaXMgaXMgcmVwZWF0ZWQgdW50aWwgZWl0aGVyIHRoZSBwYXJzZSBzdWNjZWVkcyBvciB0aGUKKyAqIGxlZnRtb3N0IGZpZWxkIGlzIG9uZSBjaGFyYWN0ZXIgaW4gbGVuZ3RoLiBJZiB0aGUgcGFyc2Ugc3RpbGwgZmFpbHMgYXQgdGhhdAorICogcG9pbnQsIHRoZSBwYXJzZSBvZiB0aGUgcnVuIGZhaWxzLgorICoKKyAqIDxwPlNlZSB7QGxpbmsgI3NldDJEaWdpdFllYXJTdGFydH0gZm9yIG1vcmUgYWJvdXQgaGFuZGxpbmcgdHdvLWRpZ2l0IHllYXJzLgorICoKKyAqIDxoND5TYW1wbGUgQ29kZTwvaDQ+CisgKiA8cD5JZiB5b3UncmUgZm9ybWF0dGluZyBmb3IgaHVtYW4gdXNlLCB5b3Ugc2hvdWxkIHVzZSBhbiBpbnN0YW5jZSByZXR1cm5lZCBmcm9tCisgKiB7QGxpbmsgRGF0ZUZvcm1hdH0gYXMgZGVzY3JpYmVkIGFib3ZlLiBUaGlzIGNvZGU6CisgKiA8cHJlPgorICogRGF0ZUZvcm1hdFtdIGZvcm1hdHMgPSBuZXcgRGF0ZUZvcm1hdFtdIHsKKyAqICAgRGF0ZUZvcm1hdC5nZXREYXRlSW5zdGFuY2UoKSwKKyAqICAgRGF0ZUZvcm1hdC5nZXREYXRlVGltZUluc3RhbmNlKCksCisgKiAgIERhdGVGb3JtYXQuZ2V0VGltZUluc3RhbmNlKCksCisgKiB9OworICogZm9yIChEYXRlRm9ybWF0IGRmIDogZm9ybWF0cykgeworICogICBTeXN0ZW0uZXJyLnByaW50bG4oZGYuZm9ybWF0KG5ldyBEYXRlKDApKSk7CisgKiB9CisgKiA8L3ByZT4KKyAqCisgKiA8cD5Qcm9kdWNlcyB0aGlzIG91dHB1dCB3aGVuIHJ1biBvbiBhbiB7QGNvZGUgZW5fVVN9IGRldmljZSBpbiB0aGUgUERUIHRpbWUgem9uZToKKyAqIDxwcmU+CisgKiBEZWMgMzEsIDE5NjkKKyAqIERlYyAzMSwgMTk2OSA0OjAwOjAwIFBNCisgKiA0OjAwOjAwIFBNCisgKiA8L3ByZT4KKyAqIEFuZCB3aWxsIHByb2R1Y2Ugc2ltaWxhcmx5IGFwcHJvcHJpYXRlIGxvY2FsaXplZCBodW1hbi1yZWFkYWJsZSBvdXRwdXQgb24gYW55IHVzZXIncyBzeXN0ZW0uCisgKgorICogPHA+SWYgeW91J3JlIGZvcm1hdHRpbmcgZm9yIG1hY2hpbmUgdXNlLCBjb25zaWRlciB0aGlzIGNvZGU6CisgKiA8cHJlPgorICogU3RyaW5nW10gZm9ybWF0cyA9IG5ldyBTdHJpbmdbXSB7CisgKiAgICJ5eXl5LU1NLWRkIiwKKyAqICAgInl5eXktTU0tZGQgSEg6bW0iLAorICogICAieXl5eS1NTS1kZCBISDptbVoiLAorICogICAieXl5eS1NTS1kZCBISDptbTpzcy5TU1NaIiwKKyAqICAgInl5eXktTU0tZGQnVCdISDptbTpzcy5TU1NaIiwKKyAqIH07CisgKiBmb3IgKFN0cmluZyBmb3JtYXQgOiBmb3JtYXRzKSB7CisgKiAgIFNpbXBsZURhdGVGb3JtYXQgc2RmID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoZm9ybWF0LCBMb2NhbGUuVVMpOworICogICBTeXN0ZW0uZXJyLmZvcm1hdCgiJTMwcyAlc1xuIiwgZm9ybWF0LCBzZGYuZm9ybWF0KG5ldyBEYXRlKDApKSk7CisgKiAgIHNkZi5zZXRUaW1lWm9uZShUaW1lWm9uZS5nZXRUaW1lWm9uZSgiVVRDIikpOworICogICBTeXN0ZW0uZXJyLmZvcm1hdCgiJTMwcyAlc1xuIiwgZm9ybWF0LCBzZGYuZm9ybWF0KG5ldyBEYXRlKDApKSk7CisgKiB9CisgKiA8L3ByZT4KKyAqCisgKiA8cD5XaGljaCBwcm9kdWNlcyB0aGlzIG91dHB1dCB3aGVuIHJ1biBpbiB0aGUgUERUIHRpbWUgem9uZToKKyAqIDxwcmU+CisgKiAgICAgICAgICAgICAgICAgICAgIHl5eXktTU0tZGQgMTk2OS0xMi0zMQorICogICAgICAgICAgICAgICAgICAgICB5eXl5LU1NLWRkIDE5NzAtMDEtMDEKKyAqICAgICAgICAgICAgICAgeXl5eS1NTS1kZCBISDptbSAxOTY5LTEyLTMxIDE2OjAwCisgKiAgICAgICAgICAgICAgIHl5eXktTU0tZGQgSEg6bW0gMTk3MC0wMS0wMSAwMDowMAorICogICAgICAgICAgICAgIHl5eXktTU0tZGQgSEg6bW1aIDE5NjktMTItMzEgMTY6MDAtMDgwMAorICogICAgICAgICAgICAgIHl5eXktTU0tZGQgSEg6bW1aIDE5NzAtMDEtMDEgMDA6MDArMDAwMAorICogICAgICAgeXl5eS1NTS1kZCBISDptbTpzcy5TU1NaIDE5NjktMTItMzEgMTY6MDA6MDAuMDAwLTA4MDAKKyAqICAgICAgIHl5eXktTU0tZGQgSEg6bW06c3MuU1NTWiAxOTcwLTAxLTAxIDAwOjAwOjAwLjAwMCswMDAwCisgKiAgICAgeXl5eS1NTS1kZCdUJ0hIOm1tOnNzLlNTU1ogMTk2OS0xMi0zMVQxNjowMDowMC4wMDAtMDgwMAorICogICAgIHl5eXktTU0tZGQnVCdISDptbTpzcy5TU1NaIDE5NzAtMDEtMDFUMDA6MDA6MDAuMDAwKzAwMDAKKyAqIDwvcHJlPgorICoKKyAqIDxwPkFzIHRoaXMgZXhhbXBsZSBzaG93cywgZWFjaCB7QGNvZGUgU2ltcGxlRGF0ZUZvcm1hdH0gaW5zdGFuY2UgaGFzIGEge0BsaW5rIFRpbWVab25lfS4KKyAqIFRoaXMgaXMgYmVjYXVzZSBpdCdzIGNhbGxlZCB1cG9uIHRvIGZvcm1hdCBpbnN0YW5jZXMgb2Yge0Bjb2RlIERhdGV9LCB3aGljaCByZXByZXNlbnRzIGFuCisgKiBhYnNvbHV0ZSB0aW1lIGluIFVUQy4gVGhhdCBpcywge0Bjb2RlIERhdGV9IGRvZXMgbm90IGNhcnJ5IHRpbWUgem9uZSBpbmZvcm1hdGlvbi4KKyAqIEJ5IGRlZmF1bHQsIHtAY29kZSBTaW1wbGVEYXRlRm9ybWF0fSB3aWxsIHVzZSB0aGUgc3lzdGVtJ3MgZGVmYXVsdCB0aW1lIHpvbmUuIFRoaXMgaXMKKyAqIGFwcHJvcHJpYXRlIGZvciBodW1hbi1yZWFkYWJsZSBvdXRwdXQgKGZvciB3aGljaCwgc2VlIHRoZSBwcmV2aW91cyBzYW1wbGUgaW5zdGVhZCksIGJ1dAorICogZ2VuZXJhbGx5IGluYXBwcm9wcmlhdGUgZm9yIG1hY2hpbmUtcmVhZGFibGUgb3V0cHV0LCB3aGVyZSBhbWJpZ3VpdHkgaXMgYSBwcm9ibGVtLiBOb3RlIHRoYXQKKyAqIGluIHRoaXMgZXhhbXBsZSwgdGhlIG91dHB1dCB0aGF0IGluY2x1ZGVkIGEgdGltZSBidXQgbm8gdGltZSB6b25lIGNhbm5vdCBiZSBwYXJzZWQgYmFjayBpbnRvCisgKiB0aGUgb3JpZ2luYWwge0Bjb2RlIERhdGV9LiBGb3IgdGhpcworICogcmVhc29uIGl0IGlzIGFsbW9zdCBhbHdheXMgbmVjZXNzYXJ5IGFuZCBkZXNpcmFibGUgdG8gaW5jbHVkZSB0aGUgdGltZXpvbmUgaW4gdGhlIG91dHB1dC4KKyAqIEl0IG1heSBhbHNvIGJlIGRlc2lyYWJsZSB0byBzZXQgdGhlIGZvcm1hdHRlcidzIHRpbWUgem9uZSB0byBVVEMgKHRvIGVhc2UgY29tcGFyaXNvbiwgb3IgdG8KKyAqIG1ha2UgbG9ncyBtb3JlIHJlYWRhYmxlLCBmb3IgZXhhbXBsZSkuCisgKgorICogPGg0PlN5bmNocm9uaXphdGlvbjwvaDQ+CisgKiB7QGNvZGUgU2ltcGxlRGF0ZUZvcm1hdH0gaXMgbm90IHRocmVhZC1zYWZlLiBVc2VycyBzaG91bGQgY3JlYXRlIGEgc2VwYXJhdGUgaW5zdGFuY2UgZm9yCisgKiBlYWNoIHRocmVhZC4KKyAqCisgKiBAc2VlIGphdmEudXRpbC5DYWxlbmRhcgorICogQHNlZSBqYXZhLnV0aWwuRGF0ZQorICogQHNlZSBqYXZhLnV0aWwuVGltZVpvbmUKKyAqIEBzZWUgamF2YS50ZXh0LkRhdGVGb3JtYXQKKyAqLworcHVibGljIGNsYXNzIFNpbXBsZURhdGVGb3JtYXQgZXh0ZW5kcyBEYXRlRm9ybWF0IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDQ3NzQ4ODE5NzA1NTg4NzUwMjRMOworCisgICAgLy8gJ0wnIGFuZCAnYycgYXJlIElDVS1jb21wYXRpYmxlIGV4dGVuc2lvbnMgZm9yIHN0YW5kLWFsb25lIG1vbnRoIGFuZCBzdGFuZC1hbG9uZSB3ZWVrZGF5LgorICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgUEFUVEVSTl9DSEFSUyA9ICJHeU1ka0htc1NFREZ3V2FoS3paTGMiOworCisgICAgLy8gVGhlIGluZGV4IG9mICdaJyBpbiB0aGUgUEFUVEVSTl9DSEFSUyBzdHJpbmcuIFRoaXMgcGF0dGVybiBjaGFyYWN0ZXIgaXMgc3VwcG9ydGVkIGJ5IHRoZSBSSSwKKyAgICAvLyBidXQgaGFzIG5vIGNvcnJlc3BvbmRpbmcgcHVibGljIGNvbnN0YW50LgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBSRkNfODIyX1RJTUVaT05FX0ZJRUxEID0gMTg7CisKKyAgICAvLyBUaGUgaW5kZXggb2YgJ0wnIChjZi4gJ00nKSBpbiB0aGUgUEFUVEVSTl9DSEFSUyBzdHJpbmcuIFRoaXMgaXMgYW4gSUNVLWNvbXBhdGlibGUgZXh0ZW5zaW9uCisgICAgLy8gbmVjZXNzYXJ5IGZvciBjb3JyZWN0IGxvY2FsaXphdGlvbiBpbiB2YXJpb3VzIGxhbmd1YWdlcyAoaHR0cDovL2IvMjYzMzQxNCkuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNUQU5EX0FMT05FX01PTlRIX0ZJRUxEID0gMTk7CisgICAgLy8gVGhlIGluZGV4IG9mICdjJyAoY2YuICdFJykgaW4gdGhlIFBBVFRFUk5fQ0hBUlMgc3RyaW5nLiBUaGlzIGlzIGFuIElDVS1jb21wYXRpYmxlIGV4dGVuc2lvbgorICAgIC8vIG5lY2Vzc2FyeSBmb3IgY29ycmVjdCBsb2NhbGl6YXRpb24gaW4gdmFyaW91cyBsYW5ndWFnZXMgKGh0dHA6Ly9iLzI2MzM0MTQpLgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTVEFORF9BTE9ORV9EQVlfT0ZfV0VFS19GSUVMRCA9IDIwOworCisgICAgcHJpdmF0ZSBTdHJpbmcgcGF0dGVybjsKKworICAgIHByaXZhdGUgRGF0ZUZvcm1hdFN5bWJvbHMgZm9ybWF0RGF0YTsKKworICAgIHRyYW5zaWVudCBwcml2YXRlIGludCBjcmVhdGlvblllYXI7CisKKyAgICBwcml2YXRlIERhdGUgZGVmYXVsdENlbnR1cnlTdGFydDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFNpbXBsZURhdGVGb3JtYXR9IGZvciBmb3JtYXR0aW5nIGFuZCBwYXJzaW5nCisgICAgICogZGF0ZXMgYW5kIHRpbWVzIGluIHRoZSB7QGNvZGUgU0hPUlR9IHN0eWxlIGZvciB0aGUgdXNlcidzIGRlZmF1bHQgbG9jYWxlLgorICAgICAqIFNlZSAiPGEgaHJlZj0iLi4vdXRpbC9Mb2NhbGUuaHRtbCNkZWZhdWx0X2xvY2FsZSI+QmUgd2FyeSBvZiB0aGUgZGVmYXVsdCBsb2NhbGU8L2E+Ii4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2ltcGxlRGF0ZUZvcm1hdCgpIHsKKyAgICAgICAgdGhpcyhMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICAgICAgdGhpcy5wYXR0ZXJuID0gZGVmYXVsdFBhdHRlcm4oKTsKKyAgICAgICAgdGhpcy5mb3JtYXREYXRhID0gbmV3IERhdGVGb3JtYXRTeW1ib2xzKExvY2FsZS5nZXREZWZhdWx0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFNpbXBsZURhdGVGb3JtYXR9IHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBub24tbG9jYWxpemVkIHBhdHRlcm4gYW5kIHRoZSB7QGNvZGUgRGF0ZUZvcm1hdFN5bWJvbHN9IGFuZCB7QGNvZGUKKyAgICAgKiBDYWxlbmRhcn0gZm9yIHRoZSB1c2VyJ3MgZGVmYXVsdCBsb2NhbGUuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqCisgICAgICogQHBhcmFtIHBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXR0ZXJuLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIGlmIHRoZSBwYXR0ZXJuIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYge0Bjb2RlIHBhdHRlcm59IGlzIG5vdCBjb25zaWRlcmVkIHRvIGJlIHVzYWJsZSBieSB0aGlzCisgICAgICogICAgICAgICAgICBmb3JtYXR0ZXIuCisgICAgICovCisgICAgcHVibGljIFNpbXBsZURhdGVGb3JtYXQoU3RyaW5nIHBhdHRlcm4pIHsKKyAgICAgICAgdGhpcyhwYXR0ZXJuLCBMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWYWxpZGF0ZXMgdGhlIGZvcm1hdCBjaGFyYWN0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9ybWF0CisgICAgICogICAgICAgICAgICB0aGUgZm9ybWF0IGNoYXJhY3RlcgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHRoZSBmb3JtYXQgY2hhcmFjdGVyIGlzIGludmFsaWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgdmFsaWRhdGVGb3JtYXQoY2hhciBmb3JtYXQpIHsKKyAgICAgICAgaW50IGluZGV4ID0gUEFUVEVSTl9DSEFSUy5pbmRleE9mKGZvcm1hdCk7CisgICAgICAgIGlmIChpbmRleCA9PSAtMSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVW5rbm93biBwYXR0ZXJuIGNoYXJhY3RlciAnIiArIGZvcm1hdCArICInIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWYWxpZGF0ZXMgdGhlIHBhdHRlcm4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGVtcGxhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXR0ZXJuIHRvIHZhbGlkYXRlLgorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYXR0ZXJuIGlzIG51bGwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYXR0ZXJuIGlzIGludmFsaWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgdmFsaWRhdGVQYXR0ZXJuKFN0cmluZyB0ZW1wbGF0ZSkgeworICAgICAgICBib29sZWFuIHF1b3RlID0gZmFsc2U7CisgICAgICAgIGludCBuZXh0LCBsYXN0ID0gLTEsIGNvdW50ID0gMDsKKworICAgICAgICBmaW5hbCBpbnQgcGF0dGVybkxlbmd0aCA9IHRlbXBsYXRlLmxlbmd0aCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhdHRlcm5MZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbmV4dCA9ICh0ZW1wbGF0ZS5jaGFyQXQoaSkpOworICAgICAgICAgICAgaWYgKG5leHQgPT0gJ1wnJykgeworICAgICAgICAgICAgICAgIGlmIChjb3VudCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGVGb3JtYXQoKGNoYXIpIGxhc3QpOworICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChsYXN0ID09IG5leHQpIHsKKyAgICAgICAgICAgICAgICAgICAgbGFzdCA9IC0xOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGxhc3QgPSBuZXh0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBxdW90ZSA9ICFxdW90ZTsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghcXVvdGUKKyAgICAgICAgICAgICAgICAgICAgJiYgKGxhc3QgPT0gbmV4dCB8fCAobmV4dCA+PSAnYScgJiYgbmV4dCA8PSAneicpIHx8IChuZXh0ID49ICdBJyAmJiBuZXh0IDw9ICdaJykpKSB7CisgICAgICAgICAgICAgICAgaWYgKGxhc3QgPT0gbmV4dCkgeworICAgICAgICAgICAgICAgICAgICBjb3VudCsrOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRlRm9ybWF0KChjaGFyKSBsYXN0KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBsYXN0ID0gbmV4dDsKKyAgICAgICAgICAgICAgICAgICAgY291bnQgPSAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKGNvdW50ID4gMCkgeworICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZUZvcm1hdCgoY2hhcikgbGFzdCk7CisgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gMDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbGFzdCA9IC0xOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChjb3VudCA+IDApIHsKKyAgICAgICAgICAgIHZhbGlkYXRlRm9ybWF0KChjaGFyKSBsYXN0KTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChxdW90ZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVW50ZXJtaW5hdGVkIHF1b3RlIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBTaW1wbGVEYXRlRm9ybWF0fSB1c2luZyB0aGUgc3BlY2lmaWVkCisgICAgICogbm9uLWxvY2FsaXplZCBwYXR0ZXJuIGFuZCB7QGNvZGUgRGF0ZUZvcm1hdFN5bWJvbHN9IGFuZCB0aGUge0Bjb2RlCisgICAgICogQ2FsZW5kYXJ9IGZvciB0aGUgdXNlcidzIGRlZmF1bHQgbG9jYWxlLgorICAgICAqIFNlZSAiPGEgaHJlZj0iLi4vdXRpbC9Mb2NhbGUuaHRtbCNkZWZhdWx0X2xvY2FsZSI+QmUgd2FyeSBvZiB0aGUgZGVmYXVsdCBsb2NhbGU8L2E+Ii4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0ZW1wbGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIHBhdHRlcm4uCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgRGF0ZUZvcm1hdFN5bWJvbHMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYgdGhlIHBhdHRlcm4gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICBpZiB0aGUgcGF0dGVybiBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyBTaW1wbGVEYXRlRm9ybWF0KFN0cmluZyB0ZW1wbGF0ZSwgRGF0ZUZvcm1hdFN5bWJvbHMgdmFsdWUpIHsKKyAgICAgICAgdGhpcyhMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICAgICAgdmFsaWRhdGVQYXR0ZXJuKHRlbXBsYXRlKTsKKyAgICAgICAgcGF0dGVybiA9IHRlbXBsYXRlOworICAgICAgICBmb3JtYXREYXRhID0gKERhdGVGb3JtYXRTeW1ib2xzKSB2YWx1ZS5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFNpbXBsZURhdGVGb3JtYXR9IHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBub24tbG9jYWxpemVkIHBhdHRlcm4gYW5kIHRoZSB7QGNvZGUgRGF0ZUZvcm1hdFN5bWJvbHN9IGFuZCB7QGNvZGUKKyAgICAgKiBDYWxlbmRhcn0gZm9yIHRoZSBzcGVjaWZpZWQgbG9jYWxlLgorICAgICAqCisgICAgICogQHBhcmFtIHRlbXBsYXRlCisgICAgICogICAgICAgICAgICB0aGUgcGF0dGVybi4KKyAgICAgKiBAcGFyYW0gbG9jYWxlCisgICAgICogICAgICAgICAgICB0aGUgbG9jYWxlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIGlmIHRoZSBwYXR0ZXJuIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYgdGhlIHBhdHRlcm4gaXMgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2ltcGxlRGF0ZUZvcm1hdChTdHJpbmcgdGVtcGxhdGUsIExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgdGhpcyhsb2NhbGUpOworICAgICAgICB2YWxpZGF0ZVBhdHRlcm4odGVtcGxhdGUpOworICAgICAgICBwYXR0ZXJuID0gdGVtcGxhdGU7CisgICAgICAgIGZvcm1hdERhdGEgPSBuZXcgRGF0ZUZvcm1hdFN5bWJvbHMobG9jYWxlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFNpbXBsZURhdGVGb3JtYXQoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBudW1iZXJGb3JtYXQgPSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UobG9jYWxlKTsKKyAgICAgICAgbnVtYmVyRm9ybWF0LnNldFBhcnNlSW50ZWdlck9ubHkodHJ1ZSk7CisgICAgICAgIG51bWJlckZvcm1hdC5zZXRHcm91cGluZ1VzZWQoZmFsc2UpOworICAgICAgICBjYWxlbmRhciA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcihsb2NhbGUpOworICAgICAgICBjYWxlbmRhci5hZGQoQ2FsZW5kYXIuWUVBUiwgLTgwKTsKKyAgICAgICAgY3JlYXRpb25ZZWFyID0gY2FsZW5kYXIuZ2V0KENhbGVuZGFyLllFQVIpOworICAgICAgICBkZWZhdWx0Q2VudHVyeVN0YXJ0ID0gY2FsZW5kYXIuZ2V0VGltZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoYW5nZXMgdGhlIHBhdHRlcm4gb2YgdGhpcyBzaW1wbGUgZGF0ZSBmb3JtYXQgdG8gdGhlIHNwZWNpZmllZCBwYXR0ZXJuCisgICAgICogd2hpY2ggdXNlcyBsb2NhbGl6ZWQgcGF0dGVybiBjaGFyYWN0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIHRlbXBsYXRlCisgICAgICogICAgICAgICAgICB0aGUgbG9jYWxpemVkIHBhdHRlcm4uCisgICAgICovCisgICAgcHVibGljIHZvaWQgYXBwbHlMb2NhbGl6ZWRQYXR0ZXJuKFN0cmluZyB0ZW1wbGF0ZSkgeworICAgICAgICBwYXR0ZXJuID0gY29udmVydFBhdHRlcm4odGVtcGxhdGUsIGZvcm1hdERhdGEuZ2V0TG9jYWxQYXR0ZXJuQ2hhcnMoKSwgUEFUVEVSTl9DSEFSUywgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hhbmdlcyB0aGUgcGF0dGVybiBvZiB0aGlzIHNpbXBsZSBkYXRlIGZvcm1hdCB0byB0aGUgc3BlY2lmaWVkIHBhdHRlcm4KKyAgICAgKiB3aGljaCB1c2VzIG5vbi1sb2NhbGl6ZWQgcGF0dGVybiBjaGFyYWN0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIHRlbXBsYXRlCisgICAgICogICAgICAgICAgICB0aGUgbm9uLWxvY2FsaXplZCBwYXR0ZXJuLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgcGF0dGVybiBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgcGF0dGVybiBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFwcGx5UGF0dGVybihTdHJpbmcgdGVtcGxhdGUpIHsKKyAgICAgICAgdmFsaWRhdGVQYXR0ZXJuKHRlbXBsYXRlKTsKKyAgICAgICAgcGF0dGVybiA9IHRlbXBsYXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIFNpbXBsZURhdGVGb3JtYXR9IHdpdGggdGhlIHNhbWUgcGF0dGVybiBhbmQKKyAgICAgKiBwcm9wZXJ0aWVzIGFzIHRoaXMgc2ltcGxlIGRhdGUgZm9ybWF0LgorICAgICAqCisgICAgICogQHJldHVybiBhIHNoYWxsb3cgY29weSBvZiB0aGlzIHNpbXBsZSBkYXRlIGZvcm1hdC4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5DbG9uZWFibGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IGNsb25lID0gKFNpbXBsZURhdGVGb3JtYXQpIHN1cGVyLmNsb25lKCk7CisgICAgICAgIGNsb25lLmZvcm1hdERhdGEgPSAoRGF0ZUZvcm1hdFN5bWJvbHMpIGZvcm1hdERhdGEuY2xvbmUoKTsKKyAgICAgICAgY2xvbmUuZGVmYXVsdENlbnR1cnlTdGFydCA9IG5ldyBEYXRlKGRlZmF1bHRDZW50dXJ5U3RhcnQuZ2V0VGltZSgpKTsKKyAgICAgICAgcmV0dXJuIGNsb25lOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZWZhdWx0UGF0dGVybigpIHsKKyAgICAgICAgTG9jYWxlRGF0YSBsb2NhbGVEYXRhID0gTG9jYWxlRGF0YS5nZXQoTG9jYWxlLmdldERlZmF1bHQoKSk7CisgICAgICAgIHJldHVybiBsb2NhbGVEYXRhLmdldERhdGVGb3JtYXQoU0hPUlQpICsgIiAiICsgbG9jYWxlRGF0YS5nZXRUaW1lRm9ybWF0KFNIT1JUKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIG9iamVjdCB3aXRoIHRoaXMgc2ltcGxlIGRhdGUgZm9ybWF0IGFuZCBpbmRpY2F0ZXMKKyAgICAgKiBpZiB0aGV5IGFyZSBlcXVhbC4gSW4gb3JkZXIgdG8gYmUgZXF1YWwsIHtAY29kZSBvYmplY3R9IG11c3QgYmUgYW4KKyAgICAgKiBpbnN0YW5jZSBvZiB7QGNvZGUgU2ltcGxlRGF0ZUZvcm1hdH0gYW5kIGhhdmUgdGhlIHNhbWUge0Bjb2RlIERhdGVGb3JtYXR9CisgICAgICogcHJvcGVydGllcywgcGF0dGVybiwge0Bjb2RlIERhdGVGb3JtYXRTeW1ib2xzfSBhbmQgY3JlYXRpb24geWVhci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB3aXRoIHRoaXMgb2JqZWN0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMgc2ltcGxlIGRhdGUKKyAgICAgKiAgICAgICAgIGZvcm1hdDsge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNlZSAjaGFzaENvZGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBpZiAodGhpcyA9PSBvYmplY3QpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghKG9iamVjdCBpbnN0YW5jZW9mIFNpbXBsZURhdGVGb3JtYXQpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBzaW1wbGUgPSAoU2ltcGxlRGF0ZUZvcm1hdCkgb2JqZWN0OworICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iamVjdCkgJiYgcGF0dGVybi5lcXVhbHMoc2ltcGxlLnBhdHRlcm4pCisgICAgICAgICAgICAgICAgJiYgZm9ybWF0RGF0YS5lcXVhbHMoc2ltcGxlLmZvcm1hdERhdGEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZvcm1hdHMgdGhlIHNwZWNpZmllZCBvYmplY3QgdXNpbmcgdGhlIHJ1bGVzIG9mIHRoaXMgc2ltcGxlIGRhdGUgZm9ybWF0CisgICAgICogYW5kIHJldHVybnMgYW4ge0Bjb2RlIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcn0gd2l0aCB0aGUgZm9ybWF0dGVkCisgICAgICogZGF0ZSBhbmQgYXR0cmlidXRlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gZm9ybWF0LgorICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcn0gd2l0aCB0aGUgZm9ybWF0dGVkIGRhdGUKKyAgICAgKiAgICAgICAgIGFuZCBhdHRyaWJ1dGVzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICBpZiB0aGUgb2JqZWN0IGNhbm5vdCBiZSBmb3JtYXR0ZWQgYnkgdGhpcyBzaW1wbGUgZGF0ZQorICAgICAqICAgICAgICAgICAgZm9ybWF0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcihPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIERhdGUpIHsKKyAgICAgICAgICAgIHJldHVybiBmb3JtYXRUb0NoYXJhY3Rlckl0ZXJhdG9ySW1wbCgoRGF0ZSkgb2JqZWN0KTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgTnVtYmVyKSB7CisgICAgICAgICAgICByZXR1cm4gZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvckltcGwobmV3IERhdGUoKChOdW1iZXIpIG9iamVjdCkubG9uZ1ZhbHVlKCkpKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisKKyAgICB9CisKKyAgICBwcml2YXRlIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBmb3JtYXRUb0NoYXJhY3Rlckl0ZXJhdG9ySW1wbChEYXRlIGRhdGUpIHsKKyAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgQXJyYXlMaXN0PEZpZWxkUG9zaXRpb24+IGZpZWxkcyA9IG5ldyBBcnJheUxpc3Q8RmllbGRQb3NpdGlvbj4oKTsKKworICAgICAgICAvLyBmb3JtYXQgdGhlIGRhdGUsIGFuZCBmaW5kIGZpZWxkcworICAgICAgICBmb3JtYXRJbXBsKGRhdGUsIGJ1ZmZlciwgbnVsbCwgZmllbGRzKTsKKworICAgICAgICAvLyBjcmVhdGUgYW5kIEF0dHJpYnV0ZWRTdHJpbmcgd2l0aCB0aGUgZm9ybWF0dGVkIGJ1ZmZlcgorICAgICAgICBBdHRyaWJ1dGVkU3RyaW5nIGFzID0gbmV3IEF0dHJpYnV0ZWRTdHJpbmcoYnVmZmVyLnRvU3RyaW5nKCkpOworCisgICAgICAgIC8vIGFkZCBEYXRlRm9ybWF0IGZpZWxkIGF0dHJpYnV0ZXMgdG8gdGhlIEF0dHJpYnV0ZWRTdHJpbmcKKyAgICAgICAgZm9yIChGaWVsZFBvc2l0aW9uIHBvcyA6IGZpZWxkcykgeworICAgICAgICAgICAgRm9ybWF0LkZpZWxkIGF0dHJpYnV0ZSA9IHBvcy5nZXRGaWVsZEF0dHJpYnV0ZSgpOworICAgICAgICAgICAgYXMuYWRkQXR0cmlidXRlKGF0dHJpYnV0ZSwgYXR0cmlidXRlLCBwb3MuZ2V0QmVnaW5JbmRleCgpLCBwb3MuZ2V0RW5kSW5kZXgoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyByZXR1cm4gdGhlIENoYXJhY3Rlckl0ZXJhdG9yIGZyb20gQXR0cmlidXRlZFN0cmluZworICAgICAgICByZXR1cm4gYXMuZ2V0SXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGb3JtYXRzIHRoZSBkYXRlLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBGaWVsZFBvc2l0aW9uIHtAY29kZSBmaWVsZH0gaXMgbm90IG51bGwsIGFuZCB0aGUgZmllbGQKKyAgICAgKiBzcGVjaWZpZWQgYnkgdGhpcyBGaWVsZFBvc2l0aW9uIGlzIGZvcm1hdHRlZCwgc2V0IHRoZSBiZWdpbiBhbmQgZW5kIGluZGV4CisgICAgICogb2YgdGhlIGZvcm1hdHRlZCBmaWVsZCBpbiB0aGUgRmllbGRQb3NpdGlvbi4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgbGlzdCB7QGNvZGUgZmllbGRzfSBpcyBub3QgbnVsbCwgZmluZCBmaWVsZHMgb2YgdGhpcworICAgICAqIGRhdGUsIHNldCBGaWVsZFBvc2l0aW9ucyB3aXRoIHRoZXNlIGZpZWxkcywgYW5kIGFkZCB0aGVtIHRvIHRoZSBmaWVsZHMKKyAgICAgKiB2ZWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0ZQorICAgICAqICAgICAgICAgICAgRGF0ZSB0byBGb3JtYXQKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICBTdHJpbmdCdWZmZXIgdG8gc3RvcmUgdGhlIHJlc3VsdGluZyBmb3JtYXR0ZWQgU3RyaW5nCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICBGaWVsZFBvc2l0aW9uIHRvIHNldCBiZWdpbiBhbmQgZW5kIGluZGV4IG9mIHRoZSBmaWVsZAorICAgICAqICAgICAgICAgICAgc3BlY2lmaWVkLCBpZiBpdCBpcyBwYXJ0IG9mIHRoZSBmb3JtYXQgZm9yIHRoaXMgZGF0ZQorICAgICAqIEBwYXJhbSBmaWVsZHMKKyAgICAgKiAgICAgICAgICAgIGxpc3QgdXNlZCB0byBzdG9yZSB0aGUgRmllbGRQb3NpdGlvbnMgZm9yIGVhY2ggZmllbGQgaW4gdGhpcworICAgICAqICAgICAgICAgICAgZGF0ZQorICAgICAqIEByZXR1cm4gdGhlIGZvcm1hdHRlZCBEYXRlCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgY2Fubm90IGJlIGZvcm1hdHRlZCBieSB0aGlzIEZvcm1hdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZ0J1ZmZlciBmb3JtYXRJbXBsKERhdGUgZGF0ZSwgU3RyaW5nQnVmZmVyIGJ1ZmZlciwKKyAgICAgICAgICAgIEZpZWxkUG9zaXRpb24gZmllbGQsIExpc3Q8RmllbGRQb3NpdGlvbj4gZmllbGRzKSB7CisKKyAgICAgICAgYm9vbGVhbiBxdW90ZSA9IGZhbHNlOworICAgICAgICBpbnQgbmV4dCwgbGFzdCA9IC0xLCBjb3VudCA9IDA7CisgICAgICAgIGNhbGVuZGFyLnNldFRpbWUoZGF0ZSk7CisgICAgICAgIGlmIChmaWVsZCAhPSBudWxsKSB7CisgICAgICAgICAgICBmaWVsZC5jbGVhcigpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgaW50IHBhdHRlcm5MZW5ndGggPSBwYXR0ZXJuLmxlbmd0aCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhdHRlcm5MZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbmV4dCA9IChwYXR0ZXJuLmNoYXJBdChpKSk7CisgICAgICAgICAgICBpZiAobmV4dCA9PSAnXCcnKSB7CisgICAgICAgICAgICAgICAgaWYgKGNvdW50ID4gMCkgeworICAgICAgICAgICAgICAgICAgICBhcHBlbmQoYnVmZmVyLCBmaWVsZCwgZmllbGRzLCAoY2hhcikgbGFzdCwgY291bnQpOworICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChsYXN0ID09IG5leHQpIHsKKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnXCcnKTsKKyAgICAgICAgICAgICAgICAgICAgbGFzdCA9IC0xOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGxhc3QgPSBuZXh0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBxdW90ZSA9ICFxdW90ZTsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghcXVvdGUKKyAgICAgICAgICAgICAgICAgICAgJiYgKGxhc3QgPT0gbmV4dCB8fCAobmV4dCA+PSAnYScgJiYgbmV4dCA8PSAneicpIHx8IChuZXh0ID49ICdBJyAmJiBuZXh0IDw9ICdaJykpKSB7CisgICAgICAgICAgICAgICAgaWYgKGxhc3QgPT0gbmV4dCkgeworICAgICAgICAgICAgICAgICAgICBjb3VudCsrOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZChidWZmZXIsIGZpZWxkLCBmaWVsZHMsIChjaGFyKSBsYXN0LCBjb3VudCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgbGFzdCA9IG5leHQ7CisgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmIChjb3VudCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgYXBwZW5kKGJ1ZmZlciwgZmllbGQsIGZpZWxkcywgKGNoYXIpIGxhc3QsIGNvdW50KTsKKyAgICAgICAgICAgICAgICAgICAgY291bnQgPSAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBsYXN0ID0gLTE7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgoY2hhcikgbmV4dCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvdW50ID4gMCkgeworICAgICAgICAgICAgYXBwZW5kKGJ1ZmZlciwgZmllbGQsIGZpZWxkcywgKGNoYXIpIGxhc3QsIGNvdW50KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnVmZmVyOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhcHBlbmQoU3RyaW5nQnVmZmVyIGJ1ZmZlciwgRmllbGRQb3NpdGlvbiBwb3NpdGlvbiwKKyAgICAgICAgICAgIExpc3Q8RmllbGRQb3NpdGlvbj4gZmllbGRzLCBjaGFyIGZvcm1hdCwgaW50IGNvdW50KSB7CisgICAgICAgIGludCBmaWVsZCA9IC0xOworICAgICAgICBpbnQgaW5kZXggPSBQQVRURVJOX0NIQVJTLmluZGV4T2YoZm9ybWF0KTsKKyAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbmtub3duIHBhdHRlcm4gY2hhcmFjdGVyICciICsgZm9ybWF0ICsgIiciKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBiZWdpblBvc2l0aW9uID0gYnVmZmVyLmxlbmd0aCgpOworICAgICAgICBGaWVsZCBkYXRlRm9ybWF0RmllbGQgPSBudWxsOworICAgICAgICBzd2l0Y2ggKGluZGV4KSB7CisgICAgICAgICAgICBjYXNlIEVSQV9GSUVMRDoKKyAgICAgICAgICAgICAgICBkYXRlRm9ybWF0RmllbGQgPSBGaWVsZC5FUkE7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChmb3JtYXREYXRhLmVyYXNbY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkVSQSldKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgWUVBUl9GSUVMRDoKKyAgICAgICAgICAgICAgICBkYXRlRm9ybWF0RmllbGQgPSBGaWVsZC5ZRUFSOworICAgICAgICAgICAgICAgIGludCB5ZWFyID0gY2FsZW5kYXIuZ2V0KENhbGVuZGFyLllFQVIpOworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogRm9yICd5JyBhbmQgJ3l5eScsIHdlJ3JlIGNvbnNpc3RlbnQgd2l0aCBVbmljb2RlIGFuZCBwcmV2aW91cyByZWxlYXNlcworICAgICAgICAgICAgICAgICAqIG9mIEFuZHJvaWQuIEJ1dCB0aGlzIG1lYW5zIHdlJ3JlIGluY29uc2lzdGVudCB3aXRoIHRoZSBSSS4KKyAgICAgICAgICAgICAgICAgKiAgICAgaHR0cDovL3VuaWNvZGUub3JnL3JlcG9ydHMvdHIzNS8KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBpZiAoY291bnQgPT0gMikgeworICAgICAgICAgICAgICAgICAgICBhcHBlbmROdW1iZXIoYnVmZmVyLCAyLCB5ZWFyICUgMTAwKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBhcHBlbmROdW1iZXIoYnVmZmVyLCBjb3VudCwgeWVhcik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBTVEFORF9BTE9ORV9NT05USF9GSUVMRDogLy8gTAorICAgICAgICAgICAgICAgIGRhdGVGb3JtYXRGaWVsZCA9IEZpZWxkLk1PTlRIOworICAgICAgICAgICAgICAgIGFwcGVuZE1vbnRoKGJ1ZmZlciwgY291bnQsIGZvcm1hdERhdGEubG9uZ1N0YW5kQWxvbmVNb250aHMsIGZvcm1hdERhdGEuc2hvcnRTdGFuZEFsb25lTW9udGhzKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgTU9OVEhfRklFTEQ6IC8vIE0KKyAgICAgICAgICAgICAgICBkYXRlRm9ybWF0RmllbGQgPSBGaWVsZC5NT05USDsKKyAgICAgICAgICAgICAgICBhcHBlbmRNb250aChidWZmZXIsIGNvdW50LCBmb3JtYXREYXRhLm1vbnRocywgZm9ybWF0RGF0YS5zaG9ydE1vbnRocyk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERBVEVfRklFTEQ6CisgICAgICAgICAgICAgICAgZGF0ZUZvcm1hdEZpZWxkID0gRmllbGQuREFZX09GX01PTlRIOworICAgICAgICAgICAgICAgIGZpZWxkID0gQ2FsZW5kYXIuREFURTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgSE9VUl9PRl9EQVkxX0ZJRUxEOiAvLyBrCisgICAgICAgICAgICAgICAgZGF0ZUZvcm1hdEZpZWxkID0gRmllbGQuSE9VUl9PRl9EQVkxOworICAgICAgICAgICAgICAgIGludCBob3VyID0gY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkhPVVJfT0ZfREFZKTsKKyAgICAgICAgICAgICAgICBhcHBlbmROdW1iZXIoYnVmZmVyLCBjb3VudCwgaG91ciA9PSAwID8gMjQgOiBob3VyKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgSE9VUl9PRl9EQVkwX0ZJRUxEOiAvLyBICisgICAgICAgICAgICAgICAgZGF0ZUZvcm1hdEZpZWxkID0gRmllbGQuSE9VUl9PRl9EQVkwOworICAgICAgICAgICAgICAgIGZpZWxkID0gQ2FsZW5kYXIuSE9VUl9PRl9EQVk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIE1JTlVURV9GSUVMRDoKKyAgICAgICAgICAgICAgICBkYXRlRm9ybWF0RmllbGQgPSBGaWVsZC5NSU5VVEU7CisgICAgICAgICAgICAgICAgZmllbGQgPSBDYWxlbmRhci5NSU5VVEU7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFNFQ09ORF9GSUVMRDoKKyAgICAgICAgICAgICAgICBkYXRlRm9ybWF0RmllbGQgPSBGaWVsZC5TRUNPTkQ7CisgICAgICAgICAgICAgICAgZmllbGQgPSBDYWxlbmRhci5TRUNPTkQ7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIE1JTExJU0VDT05EX0ZJRUxEOgorICAgICAgICAgICAgICAgIGRhdGVGb3JtYXRGaWVsZCA9IEZpZWxkLk1JTExJU0VDT05EOworICAgICAgICAgICAgICAgIGludCB2YWx1ZSA9IGNhbGVuZGFyLmdldChDYWxlbmRhci5NSUxMSVNFQ09ORCk7CisgICAgICAgICAgICAgICAgYXBwZW5kTnVtYmVyKGJ1ZmZlciwgY291bnQsIHZhbHVlKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgU1RBTkRfQUxPTkVfREFZX09GX1dFRUtfRklFTEQ6CisgICAgICAgICAgICAgICAgZGF0ZUZvcm1hdEZpZWxkID0gRmllbGQuREFZX09GX1dFRUs7CisgICAgICAgICAgICAgICAgYXBwZW5kRGF5T2ZXZWVrKGJ1ZmZlciwgY291bnQsIGZvcm1hdERhdGEubG9uZ1N0YW5kQWxvbmVXZWVrZGF5cywgZm9ybWF0RGF0YS5zaG9ydFN0YW5kQWxvbmVXZWVrZGF5cyk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERBWV9PRl9XRUVLX0ZJRUxEOgorICAgICAgICAgICAgICAgIGRhdGVGb3JtYXRGaWVsZCA9IEZpZWxkLkRBWV9PRl9XRUVLOworICAgICAgICAgICAgICAgIGFwcGVuZERheU9mV2VlayhidWZmZXIsIGNvdW50LCBmb3JtYXREYXRhLndlZWtkYXlzLCBmb3JtYXREYXRhLnNob3J0V2Vla2RheXMpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBEQVlfT0ZfWUVBUl9GSUVMRDoKKyAgICAgICAgICAgICAgICBkYXRlRm9ybWF0RmllbGQgPSBGaWVsZC5EQVlfT0ZfWUVBUjsKKyAgICAgICAgICAgICAgICBmaWVsZCA9IENhbGVuZGFyLkRBWV9PRl9ZRUFSOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBEQVlfT0ZfV0VFS19JTl9NT05USF9GSUVMRDoKKyAgICAgICAgICAgICAgICBkYXRlRm9ybWF0RmllbGQgPSBGaWVsZC5EQVlfT0ZfV0VFS19JTl9NT05USDsKKyAgICAgICAgICAgICAgICBmaWVsZCA9IENhbGVuZGFyLkRBWV9PRl9XRUVLX0lOX01PTlRIOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBXRUVLX09GX1lFQVJfRklFTEQ6CisgICAgICAgICAgICAgICAgZGF0ZUZvcm1hdEZpZWxkID0gRmllbGQuV0VFS19PRl9ZRUFSOworICAgICAgICAgICAgICAgIGZpZWxkID0gQ2FsZW5kYXIuV0VFS19PRl9ZRUFSOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBXRUVLX09GX01PTlRIX0ZJRUxEOgorICAgICAgICAgICAgICAgIGRhdGVGb3JtYXRGaWVsZCA9IEZpZWxkLldFRUtfT0ZfTU9OVEg7CisgICAgICAgICAgICAgICAgZmllbGQgPSBDYWxlbmRhci5XRUVLX09GX01PTlRIOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBBTV9QTV9GSUVMRDoKKyAgICAgICAgICAgICAgICBkYXRlRm9ybWF0RmllbGQgPSBGaWVsZC5BTV9QTTsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGZvcm1hdERhdGEuYW1wbXNbY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkFNX1BNKV0pOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBIT1VSMV9GSUVMRDogLy8gaAorICAgICAgICAgICAgICAgIGRhdGVGb3JtYXRGaWVsZCA9IEZpZWxkLkhPVVIxOworICAgICAgICAgICAgICAgIGhvdXIgPSBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuSE9VUik7CisgICAgICAgICAgICAgICAgYXBwZW5kTnVtYmVyKGJ1ZmZlciwgY291bnQsIGhvdXIgPT0gMCA/IDEyIDogaG91cik7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIEhPVVIwX0ZJRUxEOiAvLyBLCisgICAgICAgICAgICAgICAgZGF0ZUZvcm1hdEZpZWxkID0gRmllbGQuSE9VUjA7CisgICAgICAgICAgICAgICAgZmllbGQgPSBDYWxlbmRhci5IT1VSOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBUSU1FWk9ORV9GSUVMRDogLy8gegorICAgICAgICAgICAgICAgIGRhdGVGb3JtYXRGaWVsZCA9IEZpZWxkLlRJTUVfWk9ORTsKKyAgICAgICAgICAgICAgICBhcHBlbmRUaW1lWm9uZShidWZmZXIsIGNvdW50LCB0cnVlKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgUkZDXzgyMl9USU1FWk9ORV9GSUVMRDogLy8gWgorICAgICAgICAgICAgICAgIGRhdGVGb3JtYXRGaWVsZCA9IEZpZWxkLlRJTUVfWk9ORTsKKyAgICAgICAgICAgICAgICBhcHBlbmROdW1lcmljVGltZVpvbmUoYnVmZmVyLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZpZWxkICE9IC0xKSB7CisgICAgICAgICAgICBhcHBlbmROdW1iZXIoYnVmZmVyLCBjb3VudCwgY2FsZW5kYXIuZ2V0KGZpZWxkKSk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZmllbGRzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHBvc2l0aW9uID0gbmV3IEZpZWxkUG9zaXRpb24oZGF0ZUZvcm1hdEZpZWxkKTsKKyAgICAgICAgICAgIHBvc2l0aW9uLnNldEJlZ2luSW5kZXgoYmVnaW5Qb3NpdGlvbik7CisgICAgICAgICAgICBwb3NpdGlvbi5zZXRFbmRJbmRleChidWZmZXIubGVuZ3RoKCkpOworICAgICAgICAgICAgZmllbGRzLmFkZChwb3NpdGlvbik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBTZXQgdG8gdGhlIGZpcnN0IG9jY3VycmVuY2UKKyAgICAgICAgICAgIGlmICgocG9zaXRpb24uZ2V0RmllbGRBdHRyaWJ1dGUoKSA9PSBkYXRlRm9ybWF0RmllbGQgfHwgKHBvc2l0aW9uCisgICAgICAgICAgICAgICAgICAgIC5nZXRGaWVsZEF0dHJpYnV0ZSgpID09IG51bGwgJiYgcG9zaXRpb24uZ2V0RmllbGQoKSA9PSBpbmRleCkpCisgICAgICAgICAgICAgICAgICAgICYmIHBvc2l0aW9uLmdldEVuZEluZGV4KCkgPT0gMCkgeworICAgICAgICAgICAgICAgIHBvc2l0aW9uLnNldEJlZ2luSW5kZXgoYmVnaW5Qb3NpdGlvbik7CisgICAgICAgICAgICAgICAgcG9zaXRpb24uc2V0RW5kSW5kZXgoYnVmZmVyLmxlbmd0aCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhcHBlbmREYXlPZldlZWsoU3RyaW5nQnVmZmVyIGJ1ZmZlciwgaW50IGNvdW50LCBTdHJpbmdbXSBsb25ncywgU3RyaW5nW10gc2hvcnRzKSB7CisgICAgICAgIGJvb2xlYW4gaXNMb25nID0gKGNvdW50ID4gMyk7CisgICAgICAgIFN0cmluZ1tdIGRheXMgPSBpc0xvbmcgPyBsb25ncyA6IHNob3J0czsKKyAgICAgICAgYnVmZmVyLmFwcGVuZChkYXlzW2NhbGVuZGFyLmdldChDYWxlbmRhci5EQVlfT0ZfV0VFSyldKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXBwZW5kTW9udGgoU3RyaW5nQnVmZmVyIGJ1ZmZlciwgaW50IGNvdW50LCBTdHJpbmdbXSBsb25ncywgU3RyaW5nW10gc2hvcnRzKSB7CisgICAgICAgIGludCBtb250aCA9IGNhbGVuZGFyLmdldChDYWxlbmRhci5NT05USCk7CisgICAgICAgIGlmIChjb3VudCA8PSAyKSB7CisgICAgICAgICAgICBhcHBlbmROdW1iZXIoYnVmZmVyLCBjb3VudCwgbW9udGggKyAxKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gaXNMb25nID0gKGNvdW50ID4gMyk7CisgICAgICAgIFN0cmluZ1tdIG1vbnRocyA9IGlzTG9uZyA/IGxvbmdzIDogc2hvcnRzOworICAgICAgICBidWZmZXIuYXBwZW5kKG1vbnRoc1ttb250aF0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZCBhIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB0aW1lIHpvbmUgb2YgJ2NhbGVuZGFyJyB0byAnYnVmZmVyJy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIHogb3IgWiBjaGFyYWN0ZXJzIGluIHRoZSBmb3JtYXQgc3RyaW5nOyAienp6IiB3b3VsZCBiZSAzLAorICAgICAqIGZvciBleGFtcGxlLgorICAgICAqIEBwYXJhbSBnZW5lcmFsVGltZVpvbmUgdHJ1ZSBpZiB3ZSBzaG91bGQgdXNlIGEgZGlzcGxheSBuYW1lICgiUERUIikgaWYgYXZhaWxhYmxlOworICAgICAqIGZhbHNlIGltcGxpZXMgdGhhdCB3ZSBzaG91bGQgdXNlIFJGQyA4MjIgZm9ybWF0ICgiLTA4MDAiKSBpbnN0ZWFkLiBUaGlzIGNvcnJlc3BvbmRzIHRvICd6JworICAgICAqIHZlcnN1cyAnWicgaW4gdGhlIGZvcm1hdCBzdHJpbmcuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGFwcGVuZFRpbWVab25lKFN0cmluZ0J1ZmZlciBidWZmZXIsIGludCBjb3VudCwgYm9vbGVhbiBnZW5lcmFsVGltZVpvbmUpIHsKKyAgICAgICAgaWYgKGdlbmVyYWxUaW1lWm9uZSkgeworICAgICAgICAgICAgVGltZVpvbmUgdHogPSBjYWxlbmRhci5nZXRUaW1lWm9uZSgpOworICAgICAgICAgICAgYm9vbGVhbiBkYXlsaWdodCA9IChjYWxlbmRhci5nZXQoQ2FsZW5kYXIuRFNUX09GRlNFVCkgIT0gMCk7CisgICAgICAgICAgICBpbnQgc3R5bGUgPSBjb3VudCA8IDQgPyBUaW1lWm9uZS5TSE9SVCA6IFRpbWVab25lLkxPTkc7CisgICAgICAgICAgICBpZiAoIWZvcm1hdERhdGEuY3VzdG9tWm9uZVN0cmluZ3MpIHsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKHR6LmdldERpc3BsYXlOYW1lKGRheWxpZ2h0LCBzdHlsZSwgZm9ybWF0RGF0YS5sb2NhbGUpKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBXZSBjYW4ndCBjYWxsIFRpbWVab25lLmdldERpc3BsYXlOYW1lKCkgYmVjYXVzZSBpdCB3b3VsZCBub3QgdXNlCisgICAgICAgICAgICAvLyB0aGUgY3VzdG9tIERhdGVGb3JtYXRTeW1ib2xzIG9mIHRoaXMgU2ltcGxlRGF0ZUZvcm1hdC4KKyAgICAgICAgICAgIFN0cmluZyBjdXN0b20gPSBUaW1lWm9uZXMuZ2V0RGlzcGxheU5hbWUoZm9ybWF0RGF0YS56b25lU3RyaW5ncywgdHouZ2V0SUQoKSwgZGF5bGlnaHQsIHN0eWxlKTsKKyAgICAgICAgICAgIGlmIChjdXN0b20gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoY3VzdG9tKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gV2UgZGlkbid0IGZpbmQgd2hhdCB3ZSB3ZXJlIGxvb2tpbmcgZm9yLCBzbyBkZWZhdWx0IHRvIGEgbnVtZXJpYyB0aW1lIHpvbmUuCisgICAgICAgIGFwcGVuZE51bWVyaWNUaW1lWm9uZShidWZmZXIsIGdlbmVyYWxUaW1lWm9uZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIGdlbmVyYWxUaW1lWm9uZSAiR01ULTA4OjAwIiByYXRoZXIgdGhhbiAiLTA4MDAiLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhcHBlbmROdW1lcmljVGltZVpvbmUoU3RyaW5nQnVmZmVyIGJ1ZmZlciwgYm9vbGVhbiBnZW5lcmFsVGltZVpvbmUpIHsKKyAgICAgICAgaW50IG9mZnNldCA9IGNhbGVuZGFyLmdldChDYWxlbmRhci5aT05FX09GRlNFVCkgKyBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuRFNUX09GRlNFVCk7CisgICAgICAgIGNoYXIgc2lnbiA9ICcrJzsKKyAgICAgICAgaWYgKG9mZnNldCA8IDApIHsKKyAgICAgICAgICAgIHNpZ24gPSAnLSc7CisgICAgICAgICAgICBvZmZzZXQgPSAtb2Zmc2V0OworICAgICAgICB9CisgICAgICAgIGlmIChnZW5lcmFsVGltZVpvbmUpIHsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIkdNVCIpOworICAgICAgICB9CisgICAgICAgIGJ1ZmZlci5hcHBlbmQoc2lnbik7CisgICAgICAgIGFwcGVuZE51bWJlcihidWZmZXIsIDIsIG9mZnNldCAvIDM2MDAwMDApOworICAgICAgICBpZiAoZ2VuZXJhbFRpbWVab25lKSB7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCc6Jyk7CisgICAgICAgIH0KKyAgICAgICAgYXBwZW5kTnVtYmVyKGJ1ZmZlciwgMiwgKG9mZnNldCAlIDM2MDAwMDApIC8gNjAwMDApOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhcHBlbmROdW1iZXIoU3RyaW5nQnVmZmVyIGJ1ZmZlciwgaW50IGNvdW50LCBpbnQgdmFsdWUpIHsKKyAgICAgICAgLy8gVE9ETzogd2UgY291bGQgYXZvaWQgdXNpbmcgdGhlIE51bWJlckZvcm1hdCBpbiBtb3N0IGNhc2VzIGZvciBhIHNpZ25pZmljYW50IHNwZWVkdXAuCisgICAgICAgIC8vIFRoZSBvbmx5IHByb2JsZW0gaXMgdGhhdCB3ZSBleHBvc2UgdGhlIE51bWJlckZvcm1hdCB0byB0aGlyZC1wYXJ0eSBjb2RlLCBzbyB3ZSdkIGhhdmUKKyAgICAgICAgLy8gc29tZSB3b3JrIHRvIGRvIHRvIHdvcmsgb3V0IHdoZW4gdGhlIG9wdGltaXphdGlvbiBpcyB2YWxpZC4KKyAgICAgICAgaW50IG1pbmltdW1JbnRlZ2VyRGlnaXRzID0gbnVtYmVyRm9ybWF0LmdldE1pbmltdW1JbnRlZ2VyRGlnaXRzKCk7CisgICAgICAgIG51bWJlckZvcm1hdC5zZXRNaW5pbXVtSW50ZWdlckRpZ2l0cyhjb3VudCk7CisgICAgICAgIG51bWJlckZvcm1hdC5mb3JtYXQoSW50ZWdlci52YWx1ZU9mKHZhbHVlKSwgYnVmZmVyLCBuZXcgRmllbGRQb3NpdGlvbigwKSk7CisgICAgICAgIG51bWJlckZvcm1hdC5zZXRNaW5pbXVtSW50ZWdlckRpZ2l0cyhtaW5pbXVtSW50ZWdlckRpZ2l0cyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBEYXRlIGVycm9yKFBhcnNlUG9zaXRpb24gcG9zaXRpb24sIGludCBvZmZzZXQsIFRpbWVab25lIHpvbmUpIHsKKyAgICAgICAgcG9zaXRpb24uc2V0RXJyb3JJbmRleChvZmZzZXQpOworICAgICAgICBjYWxlbmRhci5zZXRUaW1lWm9uZSh6b25lKTsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogRm9ybWF0cyB0aGUgc3BlY2lmaWVkIGRhdGUgYXMgYSBzdHJpbmcgdXNpbmcgdGhlIHBhdHRlcm4gb2YgdGhpcyBkYXRlCisgICAgICogZm9ybWF0IGFuZCBhcHBlbmRzIHRoZSBzdHJpbmcgdG8gdGhlIHNwZWNpZmllZCBzdHJpbmcgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSB7QGNvZGUgZmllbGR9IG1lbWJlciBvZiB7QGNvZGUgZmllbGR9IGNvbnRhaW5zIGEgdmFsdWUgc3BlY2lmeWluZworICAgICAqIGEgZm9ybWF0IGZpZWxkLCB0aGVuIGl0cyB7QGNvZGUgYmVnaW5JbmRleH0gYW5kIHtAY29kZSBlbmRJbmRleH0gbWVtYmVycworICAgICAqIHdpbGwgYmUgdXBkYXRlZCB3aXRoIHRoZSBwb3NpdGlvbiBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGlzIGZpZWxkCisgICAgICogaW4gdGhlIGZvcm1hdHRlZCB0ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRlIHRvIGZvcm1hdC4KKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IHN0cmluZyBidWZmZXIgdG8gYXBwZW5kIHRoZSBmb3JtYXR0ZWQgZGF0ZS90aW1lIHRvLgorICAgICAqIEBwYXJhbSBmaWVsZFBvcworICAgICAqICAgICAgICAgICAgb24gaW5wdXQ6IGFuIG9wdGlvbmFsIGFsaWdubWVudCBmaWVsZDsgb24gb3V0cHV0OiB0aGUgb2Zmc2V0cworICAgICAqICAgICAgICAgICAgb2YgdGhlIGFsaWdubWVudCBmaWVsZCBpbiB0aGUgZm9ybWF0dGVkIHRleHQuCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIGJ1ZmZlci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGFyZSBpbnZhbGlkIGNoYXJhY3RlcnMgaW4gdGhlIHBhdHRlcm4uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ0J1ZmZlciBmb3JtYXQoRGF0ZSBkYXRlLCBTdHJpbmdCdWZmZXIgYnVmZmVyLCBGaWVsZFBvc2l0aW9uIGZpZWxkUG9zKSB7CisgICAgICAgIC8vIEhhcm1vbnkgZGVsZWdhdGVzIHRvIElDVSdzIFNpbXBsZURhdGVGb3JtYXQsIHdlIGltcGxlbWVudCBpdCBkaXJlY3RseQorICAgICAgICByZXR1cm4gZm9ybWF0SW1wbChkYXRlLCBidWZmZXIsIGZpZWxkUG9zLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkYXRlIHdoaWNoIGlzIHRoZSBzdGFydCBvZiB0aGUgb25lIGh1bmRyZWQgeWVhciBwZXJpb2QgZm9yIHR3by1kaWdpdCB5ZWFyIHZhbHVlcy4KKyAgICAgKiBTZWUge0BsaW5rICNzZXQyRGlnaXRZZWFyU3RhcnR9IGZvciBkZXRhaWxzLgorICAgICAqLworICAgIHB1YmxpYyBEYXRlIGdldDJEaWdpdFllYXJTdGFydCgpIHsKKyAgICAgICAgcmV0dXJuIChEYXRlKSBkZWZhdWx0Q2VudHVyeVN0YXJ0LmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIERhdGVGb3JtYXRTeW1ib2xzfSB1c2VkIGJ5IHRoaXMgc2ltcGxlIGRhdGUgZm9ybWF0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIERhdGVGb3JtYXRTeW1ib2xzfSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIERhdGVGb3JtYXRTeW1ib2xzIGdldERhdGVGb3JtYXRTeW1ib2xzKCkgeworICAgICAgICByZXR1cm4gKERhdGVGb3JtYXRTeW1ib2xzKSBmb3JtYXREYXRhLmNsb25lKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmhhc2hDb2RlKCkgKyBwYXR0ZXJuLmhhc2hDb2RlKCkgKyBmb3JtYXREYXRhLmhhc2hDb2RlKCkgKyBjcmVhdGlvblllYXI7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgcGFyc2UoU3RyaW5nIHN0cmluZywgaW50IG9mZnNldCwgY2hhciBmb3JtYXQsIGludCBjb3VudCkgeworICAgICAgICBpbnQgaW5kZXggPSBQQVRURVJOX0NIQVJTLmluZGV4T2YoZm9ybWF0KTsKKyAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbmtub3duIHBhdHRlcm4gY2hhcmFjdGVyICciICsgZm9ybWF0ICsgIiciKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgZmllbGQgPSAtMTsKKyAgICAgICAgLy8gVE9ETzogd2hhdCdzICdhYnNvbHV0ZScgZm9yPyB3aGVuIGlzICdjb3VudCcgbmVnYXRpdmUsIGFuZCB3aHk/CisgICAgICAgIGludCBhYnNvbHV0ZSA9IDA7CisgICAgICAgIGlmIChjb3VudCA8IDApIHsKKyAgICAgICAgICAgIGNvdW50ID0gLWNvdW50OworICAgICAgICAgICAgYWJzb2x1dGUgPSBjb3VudDsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGluZGV4KSB7CisgICAgICAgICAgICBjYXNlIEVSQV9GSUVMRDoKKyAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VUZXh0KHN0cmluZywgb2Zmc2V0LCBmb3JtYXREYXRhLmVyYXMsIENhbGVuZGFyLkVSQSk7CisgICAgICAgICAgICBjYXNlIFlFQVJfRklFTEQ6CisgICAgICAgICAgICAgICAgaWYgKGNvdW50ID49IDMpIHsKKyAgICAgICAgICAgICAgICAgICAgZmllbGQgPSBDYWxlbmRhci5ZRUFSOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIFBhcnNlUG9zaXRpb24gcG9zaXRpb24gPSBuZXcgUGFyc2VQb3NpdGlvbihvZmZzZXQpOworICAgICAgICAgICAgICAgICAgICBOdW1iZXIgcmVzdWx0ID0gcGFyc2VOdW1iZXIoYWJzb2x1dGUsIHN0cmluZywgcG9zaXRpb24pOworICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtcG9zaXRpb24uZ2V0RXJyb3JJbmRleCgpIC0gMTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpbnQgeWVhciA9IHJlc3VsdC5pbnRWYWx1ZSgpOworICAgICAgICAgICAgICAgICAgICAvLyBBIHR3byBkaWdpdCB5ZWFyIG11c3QgYmUgZXhhY3RseSB0d28gZGlnaXRzLCBpLmUuIDAxCisgICAgICAgICAgICAgICAgICAgIGlmICgocG9zaXRpb24uZ2V0SW5kZXgoKSAtIG9mZnNldCkgPT0gMiAmJiB5ZWFyID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHllYXIgKz0gY3JlYXRpb25ZZWFyIC8gMTAwICogMTAwOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHllYXIgPCBjcmVhdGlvblllYXIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyICs9IDEwMDsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBjYWxlbmRhci5zZXQoQ2FsZW5kYXIuWUVBUiwgeWVhcik7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBwb3NpdGlvbi5nZXRJbmRleCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgU1RBTkRfQUxPTkVfTU9OVEhfRklFTEQ6IC8vIEwKKyAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VNb250aChzdHJpbmcsIG9mZnNldCwgY291bnQsIGFic29sdXRlLAorICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0RGF0YS5sb25nU3RhbmRBbG9uZU1vbnRocywgZm9ybWF0RGF0YS5zaG9ydFN0YW5kQWxvbmVNb250aHMpOworICAgICAgICAgICAgY2FzZSBNT05USF9GSUVMRDogLy8gTQorICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZU1vbnRoKHN0cmluZywgb2Zmc2V0LCBjb3VudCwgYWJzb2x1dGUsCisgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXREYXRhLm1vbnRocywgZm9ybWF0RGF0YS5zaG9ydE1vbnRocyk7CisgICAgICAgICAgICBjYXNlIERBVEVfRklFTEQ6CisgICAgICAgICAgICAgICAgZmllbGQgPSBDYWxlbmRhci5EQVRFOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBIT1VSX09GX0RBWTFfRklFTEQ6IC8vIGsKKyAgICAgICAgICAgICAgICBQYXJzZVBvc2l0aW9uIHBvc2l0aW9uID0gbmV3IFBhcnNlUG9zaXRpb24ob2Zmc2V0KTsKKyAgICAgICAgICAgICAgICBOdW1iZXIgcmVzdWx0ID0gcGFyc2VOdW1iZXIoYWJzb2x1dGUsIHN0cmluZywgcG9zaXRpb24pOworICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLXBvc2l0aW9uLmdldEVycm9ySW5kZXgoKSAtIDE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGludCBob3VyID0gcmVzdWx0LmludFZhbHVlKCk7CisgICAgICAgICAgICAgICAgaWYgKGhvdXIgPT0gMjQpIHsKKyAgICAgICAgICAgICAgICAgICAgaG91ciA9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNhbGVuZGFyLnNldChDYWxlbmRhci5IT1VSX09GX0RBWSwgaG91cik7CisgICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uLmdldEluZGV4KCk7CisgICAgICAgICAgICBjYXNlIEhPVVJfT0ZfREFZMF9GSUVMRDogLy8gSAorICAgICAgICAgICAgICAgIGZpZWxkID0gQ2FsZW5kYXIuSE9VUl9PRl9EQVk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIE1JTlVURV9GSUVMRDoKKyAgICAgICAgICAgICAgICBmaWVsZCA9IENhbGVuZGFyLk1JTlVURTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgU0VDT05EX0ZJRUxEOgorICAgICAgICAgICAgICAgIGZpZWxkID0gQ2FsZW5kYXIuU0VDT05EOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBNSUxMSVNFQ09ORF9GSUVMRDoKKyAgICAgICAgICAgICAgICBmaWVsZCA9IENhbGVuZGFyLk1JTExJU0VDT05EOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBTVEFORF9BTE9ORV9EQVlfT0ZfV0VFS19GSUVMRDoKKyAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VEYXlPZldlZWsoc3RyaW5nLCBvZmZzZXQsIGZvcm1hdERhdGEubG9uZ1N0YW5kQWxvbmVXZWVrZGF5cywgZm9ybWF0RGF0YS5zaG9ydFN0YW5kQWxvbmVXZWVrZGF5cyk7CisgICAgICAgICAgICBjYXNlIERBWV9PRl9XRUVLX0ZJRUxEOgorICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZURheU9mV2VlayhzdHJpbmcsIG9mZnNldCwgZm9ybWF0RGF0YS53ZWVrZGF5cywgZm9ybWF0RGF0YS5zaG9ydFdlZWtkYXlzKTsKKyAgICAgICAgICAgIGNhc2UgREFZX09GX1lFQVJfRklFTEQ6CisgICAgICAgICAgICAgICAgZmllbGQgPSBDYWxlbmRhci5EQVlfT0ZfWUVBUjsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgREFZX09GX1dFRUtfSU5fTU9OVEhfRklFTEQ6CisgICAgICAgICAgICAgICAgZmllbGQgPSBDYWxlbmRhci5EQVlfT0ZfV0VFS19JTl9NT05USDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgV0VFS19PRl9ZRUFSX0ZJRUxEOgorICAgICAgICAgICAgICAgIGZpZWxkID0gQ2FsZW5kYXIuV0VFS19PRl9ZRUFSOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBXRUVLX09GX01PTlRIX0ZJRUxEOgorICAgICAgICAgICAgICAgIGZpZWxkID0gQ2FsZW5kYXIuV0VFS19PRl9NT05USDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgQU1fUE1fRklFTEQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlVGV4dChzdHJpbmcsIG9mZnNldCwgZm9ybWF0RGF0YS5hbXBtcywgQ2FsZW5kYXIuQU1fUE0pOworICAgICAgICAgICAgY2FzZSBIT1VSMV9GSUVMRDogLy8gaAorICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gbmV3IFBhcnNlUG9zaXRpb24ob2Zmc2V0KTsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSBwYXJzZU51bWJlcihhYnNvbHV0ZSwgc3RyaW5nLCBwb3NpdGlvbik7CisgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtcG9zaXRpb24uZ2V0RXJyb3JJbmRleCgpIC0gMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaG91ciA9IHJlc3VsdC5pbnRWYWx1ZSgpOworICAgICAgICAgICAgICAgIGlmIChob3VyID09IDEyKSB7CisgICAgICAgICAgICAgICAgICAgIGhvdXIgPSAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjYWxlbmRhci5zZXQoQ2FsZW5kYXIuSE9VUiwgaG91cik7CisgICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uLmdldEluZGV4KCk7CisgICAgICAgICAgICBjYXNlIEhPVVIwX0ZJRUxEOiAvLyBLCisgICAgICAgICAgICAgICAgZmllbGQgPSBDYWxlbmRhci5IT1VSOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBUSU1FWk9ORV9GSUVMRDogLy8gegorICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZVRpbWVab25lKHN0cmluZywgb2Zmc2V0KTsKKyAgICAgICAgICAgIGNhc2UgUkZDXzgyMl9USU1FWk9ORV9GSUVMRDogLy8gWgorICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZVRpbWVab25lKHN0cmluZywgb2Zmc2V0KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZmllbGQgIT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiBwYXJzZU51bWJlcihhYnNvbHV0ZSwgc3RyaW5nLCBvZmZzZXQsIGZpZWxkLCAwKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gb2Zmc2V0OworICAgIH0KKworICAgIHByaXZhdGUgaW50IHBhcnNlRGF5T2ZXZWVrKFN0cmluZyBzdHJpbmcsIGludCBvZmZzZXQsIFN0cmluZ1tdIGxvbmdzLCBTdHJpbmdbXSBzaG9ydHMpIHsKKyAgICAgICAgaW50IGluZGV4ID0gcGFyc2VUZXh0KHN0cmluZywgb2Zmc2V0LCBsb25ncywgQ2FsZW5kYXIuREFZX09GX1dFRUspOworICAgICAgICBpZiAoaW5kZXggPCAwKSB7CisgICAgICAgICAgICBpbmRleCA9IHBhcnNlVGV4dChzdHJpbmcsIG9mZnNldCwgc2hvcnRzLCBDYWxlbmRhci5EQVlfT0ZfV0VFSyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGluZGV4OworICAgIH0KKworICAgIHByaXZhdGUgaW50IHBhcnNlTW9udGgoU3RyaW5nIHN0cmluZywgaW50IG9mZnNldCwgaW50IGNvdW50LCBpbnQgYWJzb2x1dGUsIFN0cmluZ1tdIGxvbmdzLCBTdHJpbmdbXSBzaG9ydHMpIHsKKyAgICAgICAgaWYgKGNvdW50IDw9IDIpIHsKKyAgICAgICAgICAgIHJldHVybiBwYXJzZU51bWJlcihhYnNvbHV0ZSwgc3RyaW5nLCBvZmZzZXQsIENhbGVuZGFyLk1PTlRILCAtMSk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGluZGV4ID0gcGFyc2VUZXh0KHN0cmluZywgb2Zmc2V0LCBsb25ncywgQ2FsZW5kYXIuTU9OVEgpOworICAgICAgICBpZiAoaW5kZXggPCAwKSB7CisgICAgICAgICAgICBpbmRleCA9IHBhcnNlVGV4dChzdHJpbmcsIG9mZnNldCwgc2hvcnRzLCBDYWxlbmRhci5NT05USCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGluZGV4OworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyBhIGRhdGUgZnJvbSB0aGUgc3BlY2lmaWVkIHN0cmluZyBzdGFydGluZyBhdCB0aGUgaW5kZXggc3BlY2lmaWVkCisgICAgICogYnkge0Bjb2RlIHBvc2l0aW9ufS4gSWYgdGhlIHN0cmluZyBpcyBzdWNjZXNzZnVsbHkgcGFyc2VkIHRoZW4gdGhlIGluZGV4CisgICAgICogb2YgdGhlIHtAY29kZSBQYXJzZVBvc2l0aW9ufSBpcyB1cGRhdGVkIHRvIHRoZSBpbmRleCBmb2xsb3dpbmcgdGhlIHBhcnNlZAorICAgICAqIHRleHQuIE9uIGVycm9yLCB0aGUgaW5kZXggaXMgdW5jaGFuZ2VkIGFuZCB0aGUgZXJyb3IgaW5kZXggb2Yge0Bjb2RlCisgICAgICogUGFyc2VQb3NpdGlvbn0gaXMgc2V0IHRvIHRoZSBpbmRleCB3aGVyZSB0aGUgZXJyb3Igb2NjdXJyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIHBhcnNlIHVzaW5nIHRoZSBwYXR0ZXJuIG9mIHRoaXMgc2ltcGxlIGRhdGUKKyAgICAgKiAgICAgICAgICAgIGZvcm1hdC4KKyAgICAgKiBAcGFyYW0gcG9zaXRpb24KKyAgICAgKiAgICAgICAgICAgIGlucHV0L291dHB1dCBwYXJhbWV0ZXIsIHNwZWNpZmllcyB0aGUgc3RhcnQgaW5kZXggaW4ge0Bjb2RlCisgICAgICogICAgICAgICAgICBzdHJpbmd9IGZyb20gd2hlcmUgdG8gc3RhcnQgcGFyc2luZy4gSWYgcGFyc2luZyBpcyBzdWNjZXNzZnVsLAorICAgICAqICAgICAgICAgICAgaXQgaXMgdXBkYXRlZCB3aXRoIHRoZSBpbmRleCBmb2xsb3dpbmcgdGhlIHBhcnNlZCB0ZXh0OyBvbgorICAgICAqICAgICAgICAgICAgZXJyb3IsIHRoZSBpbmRleCBpcyB1bmNoYW5nZWQgYW5kIHRoZSBlcnJvciBpbmRleCBpcyBzZXQgdG8KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCB3aGVyZSB0aGUgZXJyb3Igb2NjdXJyZWQuCisgICAgICogQHJldHVybiB0aGUgZGF0ZSByZXN1bHRpbmcgZnJvbSB0aGUgcGFyc2UsIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSBpcyBhbgorICAgICAqICAgICAgICAgZXJyb3IuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBhcmUgaW52YWxpZCBjaGFyYWN0ZXJzIGluIHRoZSBwYXR0ZXJuLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEYXRlIHBhcnNlKFN0cmluZyBzdHJpbmcsIFBhcnNlUG9zaXRpb24gcG9zaXRpb24pIHsKKyAgICAgICAgLy8gSGFybW9ueSBkZWxlZ2F0ZXMgdG8gSUNVJ3MgU2ltcGxlRGF0ZUZvcm1hdCwgd2UgaW1wbGVtZW50IGl0IGRpcmVjdGx5CisgICAgICAgIGJvb2xlYW4gcXVvdGUgPSBmYWxzZTsKKyAgICAgICAgaW50IG5leHQsIGxhc3QgPSAtMSwgY291bnQgPSAwLCBvZmZzZXQgPSBwb3NpdGlvbi5nZXRJbmRleCgpOworICAgICAgICBpbnQgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aCgpOworICAgICAgICBjYWxlbmRhci5jbGVhcigpOworICAgICAgICBUaW1lWm9uZSB6b25lID0gY2FsZW5kYXIuZ2V0VGltZVpvbmUoKTsKKyAgICAgICAgZmluYWwgaW50IHBhdHRlcm5MZW5ndGggPSBwYXR0ZXJuLmxlbmd0aCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhdHRlcm5MZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbmV4dCA9IHBhdHRlcm4uY2hhckF0KGkpOworICAgICAgICAgICAgaWYgKG5leHQgPT0gJ1wnJykgeworICAgICAgICAgICAgICAgIGlmIChjb3VudCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKChvZmZzZXQgPSBwYXJzZShzdHJpbmcsIG9mZnNldCwgKGNoYXIpIGxhc3QsIGNvdW50KSkgPCAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXJyb3IocG9zaXRpb24sIC1vZmZzZXQgLSAxLCB6b25lKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChsYXN0ID09IG5leHQpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG9mZnNldCA+PSBsZW5ndGggfHwgc3RyaW5nLmNoYXJBdChvZmZzZXQpICE9ICdcJycpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlcnJvcihwb3NpdGlvbiwgb2Zmc2V0LCB6b25lKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBvZmZzZXQrKzsKKyAgICAgICAgICAgICAgICAgICAgbGFzdCA9IC0xOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGxhc3QgPSBuZXh0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBxdW90ZSA9ICFxdW90ZTsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghcXVvdGUKKyAgICAgICAgICAgICAgICAgICAgJiYgKGxhc3QgPT0gbmV4dCB8fCAobmV4dCA+PSAnYScgJiYgbmV4dCA8PSAneicpIHx8IChuZXh0ID49ICdBJyAmJiBuZXh0IDw9ICdaJykpKSB7CisgICAgICAgICAgICAgICAgaWYgKGxhc3QgPT0gbmV4dCkgeworICAgICAgICAgICAgICAgICAgICBjb3VudCsrOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICgob2Zmc2V0ID0gcGFyc2Uoc3RyaW5nLCBvZmZzZXQsIChjaGFyKSBsYXN0LCAtY291bnQpKSA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXJyb3IocG9zaXRpb24sIC1vZmZzZXQgLSAxLCB6b25lKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBsYXN0ID0gbmV4dDsKKyAgICAgICAgICAgICAgICAgICAgY291bnQgPSAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKGNvdW50ID4gMCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoKG9mZnNldCA9IHBhcnNlKHN0cmluZywgb2Zmc2V0LCAoY2hhcikgbGFzdCwgY291bnQpKSA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlcnJvcihwb3NpdGlvbiwgLW9mZnNldCAtIDEsIHpvbmUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gMDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbGFzdCA9IC0xOworICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPj0gbGVuZ3RoIHx8IHN0cmluZy5jaGFyQXQob2Zmc2V0KSAhPSBuZXh0KSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBlcnJvcihwb3NpdGlvbiwgb2Zmc2V0LCB6b25lKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgb2Zmc2V0Kys7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvdW50ID4gMCkgeworICAgICAgICAgICAgaWYgKChvZmZzZXQgPSBwYXJzZShzdHJpbmcsIG9mZnNldCwgKGNoYXIpIGxhc3QsIGNvdW50KSkgPCAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yKHBvc2l0aW9uLCAtb2Zmc2V0IC0gMSwgem9uZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgRGF0ZSBkYXRlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGF0ZSA9IGNhbGVuZGFyLmdldFRpbWUoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBlcnJvcihwb3NpdGlvbiwgb2Zmc2V0LCB6b25lKTsKKyAgICAgICAgfQorICAgICAgICBwb3NpdGlvbi5zZXRJbmRleChvZmZzZXQpOworICAgICAgICBjYWxlbmRhci5zZXRUaW1lWm9uZSh6b25lKTsKKyAgICAgICAgcmV0dXJuIGRhdGU7CisgICAgfQorCisgICAgcHJpdmF0ZSBOdW1iZXIgcGFyc2VOdW1iZXIoaW50IG1heCwgU3RyaW5nIHN0cmluZywgUGFyc2VQb3NpdGlvbiBwb3NpdGlvbikgeworICAgICAgICBpbnQgZGlnaXQsIGxlbmd0aCA9IHN0cmluZy5sZW5ndGgoKSwgcmVzdWx0ID0gMDsKKyAgICAgICAgaW50IGluZGV4ID0gcG9zaXRpb24uZ2V0SW5kZXgoKTsKKyAgICAgICAgaWYgKG1heCA+IDAgJiYgbWF4IDwgbGVuZ3RoIC0gaW5kZXgpIHsKKyAgICAgICAgICAgIGxlbmd0aCA9IGluZGV4ICsgbWF4OworICAgICAgICB9CisgICAgICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aAorICAgICAgICAgICAgICAgICYmIChzdHJpbmcuY2hhckF0KGluZGV4KSA9PSAnICcgfHwgc3RyaW5nLmNoYXJBdChpbmRleCkgPT0gJ1x0JykpIHsKKyAgICAgICAgICAgIGluZGV4Kys7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG1heCA9PSAwKSB7CisgICAgICAgICAgICBwb3NpdGlvbi5zZXRJbmRleChpbmRleCk7CisgICAgICAgICAgICByZXR1cm4gbnVtYmVyRm9ybWF0LnBhcnNlKHN0cmluZywgcG9zaXRpb24pOworICAgICAgICB9CisKKyAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoCisgICAgICAgICAgICAgICAgJiYgKGRpZ2l0ID0gQ2hhcmFjdGVyLmRpZ2l0KHN0cmluZy5jaGFyQXQoaW5kZXgpLCAxMCkpICE9IC0xKSB7CisgICAgICAgICAgICBpbmRleCsrOworICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICogMTAgKyBkaWdpdDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5kZXggPT0gcG9zaXRpb24uZ2V0SW5kZXgoKSkgeworICAgICAgICAgICAgcG9zaXRpb24uc2V0RXJyb3JJbmRleChpbmRleCk7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBwb3NpdGlvbi5zZXRJbmRleChpbmRleCk7CisgICAgICAgIHJldHVybiBJbnRlZ2VyLnZhbHVlT2YocmVzdWx0KTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBwYXJzZU51bWJlcihpbnQgbWF4LCBTdHJpbmcgc3RyaW5nLCBpbnQgb2Zmc2V0LCBpbnQgZmllbGQsIGludCBza2V3KSB7CisgICAgICAgIFBhcnNlUG9zaXRpb24gcG9zaXRpb24gPSBuZXcgUGFyc2VQb3NpdGlvbihvZmZzZXQpOworICAgICAgICBOdW1iZXIgcmVzdWx0ID0gcGFyc2VOdW1iZXIobWF4LCBzdHJpbmcsIHBvc2l0aW9uKTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gLXBvc2l0aW9uLmdldEVycm9ySW5kZXgoKSAtIDE7CisgICAgICAgIH0KKyAgICAgICAgY2FsZW5kYXIuc2V0KGZpZWxkLCByZXN1bHQuaW50VmFsdWUoKSArIHNrZXcpOworICAgICAgICByZXR1cm4gcG9zaXRpb24uZ2V0SW5kZXgoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBwYXJzZVRleHQoU3RyaW5nIHN0cmluZywgaW50IG9mZnNldCwgU3RyaW5nW10gdGV4dCwgaW50IGZpZWxkKSB7CisgICAgICAgIGludCBmb3VuZCA9IC0xOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRleHQubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmICh0ZXh0W2ldLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHN0cmluZy5yZWdpb25NYXRjaGVzKHRydWUsIG9mZnNldCwgdGV4dFtpXSwgMCwgdGV4dFtpXS5sZW5ndGgoKSkpIHsKKyAgICAgICAgICAgICAgICAvLyBTZWFyY2ggZm9yIHRoZSBsb25nZXN0IG1hdGNoLCBpbiBjYXNlIHNvbWUgZmllbGRzIGFyZSBzdWJzZXRzCisgICAgICAgICAgICAgICAgaWYgKGZvdW5kID09IC0xIHx8IHRleHRbaV0ubGVuZ3RoKCkgPiB0ZXh0W2ZvdW5kXS5sZW5ndGgoKSkgeworICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IGk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChmb3VuZCAhPSAtMSkgeworICAgICAgICAgICAgY2FsZW5kYXIuc2V0KGZpZWxkLCBmb3VuZCk7CisgICAgICAgICAgICByZXR1cm4gb2Zmc2V0ICsgdGV4dFtmb3VuZF0ubGVuZ3RoKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC1vZmZzZXQgLSAxOworICAgIH0KKworICAgIHByaXZhdGUgaW50IHBhcnNlVGltZVpvbmUoU3RyaW5nIHN0cmluZywgaW50IG9mZnNldCkgeworICAgICAgICBib29sZWFuIGZvdW5kR01UID0gc3RyaW5nLnJlZ2lvbk1hdGNoZXMob2Zmc2V0LCAiR01UIiwgMCwgMyk7CisgICAgICAgIGlmIChmb3VuZEdNVCkgeworICAgICAgICAgICAgb2Zmc2V0ICs9IDM7CisgICAgICAgIH0KKyAgICAgICAgY2hhciBzaWduOworICAgICAgICBpZiAob2Zmc2V0IDwgc3RyaW5nLmxlbmd0aCgpCisgICAgICAgICAgICAgICAgJiYgKChzaWduID0gc3RyaW5nLmNoYXJBdChvZmZzZXQpKSA9PSAnKycgfHwgc2lnbiA9PSAnLScpKSB7CisgICAgICAgICAgICBQYXJzZVBvc2l0aW9uIHBvc2l0aW9uID0gbmV3IFBhcnNlUG9zaXRpb24ob2Zmc2V0ICsgMSk7CisgICAgICAgICAgICBOdW1iZXIgcmVzdWx0ID0gbnVtYmVyRm9ybWF0LnBhcnNlKHN0cmluZywgcG9zaXRpb24pOworICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC1wb3NpdGlvbi5nZXRFcnJvckluZGV4KCkgLSAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IGhvdXIgPSByZXN1bHQuaW50VmFsdWUoKTsKKyAgICAgICAgICAgIGludCByYXcgPSBob3VyICogMzYwMDAwMDsKKyAgICAgICAgICAgIGludCBpbmRleCA9IHBvc2l0aW9uLmdldEluZGV4KCk7CisgICAgICAgICAgICBpZiAoaW5kZXggPCBzdHJpbmcubGVuZ3RoKCkgJiYgc3RyaW5nLmNoYXJBdChpbmRleCkgPT0gJzonKSB7CisgICAgICAgICAgICAgICAgcG9zaXRpb24uc2V0SW5kZXgoaW5kZXggKyAxKTsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSBudW1iZXJGb3JtYXQucGFyc2Uoc3RyaW5nLCBwb3NpdGlvbik7CisgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtcG9zaXRpb24uZ2V0RXJyb3JJbmRleCgpIC0gMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaW50IG1pbnV0ZSA9IHJlc3VsdC5pbnRWYWx1ZSgpOworICAgICAgICAgICAgICAgIHJhdyArPSBtaW51dGUgKiA2MDAwMDsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoaG91ciA+PSAyNCkgeworICAgICAgICAgICAgICAgIHJhdyA9IChob3VyIC8gMTAwICogMzYwMDAwMCkgKyAoaG91ciAlIDEwMCAqIDYwMDAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzaWduID09ICctJykgeworICAgICAgICAgICAgICAgIHJhdyA9IC1yYXc7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYWxlbmRhci5zZXRUaW1lWm9uZShuZXcgU2ltcGxlVGltZVpvbmUocmF3LCAiIikpOworICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uLmdldEluZGV4KCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZvdW5kR01UKSB7CisgICAgICAgICAgICBjYWxlbmRhci5zZXRUaW1lWm9uZShUaW1lWm9uZS5nZXRUaW1lWm9uZSgiR01UIikpOworICAgICAgICAgICAgcmV0dXJuIG9mZnNldDsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmdbXVtdIHpvbmVzID0gZm9ybWF0RGF0YS5pbnRlcm5hbFpvbmVTdHJpbmdzKCk7CisgICAgICAgIGZvciAoU3RyaW5nW10gZWxlbWVudCA6IHpvbmVzKSB7CisgICAgICAgICAgICBmb3IgKGludCBqID0gVGltZVpvbmVzLkxPTkdfTkFNRTsgaiA8IFRpbWVab25lcy5OQU1FX0NPVU5UOyBqKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoc3RyaW5nLnJlZ2lvbk1hdGNoZXModHJ1ZSwgb2Zmc2V0LCBlbGVtZW50W2pdLCAwLCBlbGVtZW50W2pdLmxlbmd0aCgpKSkgeworICAgICAgICAgICAgICAgICAgICBUaW1lWm9uZSB6b25lID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoZWxlbWVudFtUaW1lWm9uZXMuT0xTT05fTkFNRV0pOworICAgICAgICAgICAgICAgICAgICBpZiAoem9uZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLW9mZnNldCAtIDE7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaW50IHJhdyA9IHpvbmUuZ2V0UmF3T2Zmc2V0KCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChqID09IFRpbWVab25lcy5MT05HX05BTUVfRFNUIHx8IGogPT0gVGltZVpvbmVzLlNIT1JUX05BTUVfRFNUKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAgICAgICAgICogVE9ETywgaHR0cDovL2IvNDcyMzQxMgorICAgICAgICAgICAgICAgICAgICAgICAgICogV2UgY2FuJ3QgdXNlIFRpbWVab25lI2dldERTVFNhdmluZ3MgaGVyZSBiZWNhdXNlIHRoYXQKKyAgICAgICAgICAgICAgICAgICAgICAgICAqIHdpbGwgcmV0dXJuIDAgaWYgdGhlIHpvbmUgbm8gbG9uZ2VyIHVzZXMgRFNULiBXZQorICAgICAgICAgICAgICAgICAgICAgICAgICogc2hvdWxkIGNoYW5nZSB0aGlzIHRvIHVzZSBUaW1lWm9uZS5nZXRPZmZzZXQobG9uZyksCisgICAgICAgICAgICAgICAgICAgICAgICAgKiB3aGljaCByZXF1aXJlcyB0aGUgY29tcGxldGUgZGF0ZSB0byBiZSBwYXJzZWQgZmlyc3QuCisgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgIHJhdyArPSAzNjAwMDAwOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGNhbGVuZGFyLnNldFRpbWVab25lKG5ldyBTaW1wbGVUaW1lWm9uZShyYXcsICIiKSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZmZzZXQgKyBlbGVtZW50W2pdLmxlbmd0aCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLW9mZnNldCAtIDE7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGF0ZSB3aGljaCBpcyB0aGUgc3RhcnQgb2YgdGhlIG9uZSBodW5kcmVkIHllYXIgcGVyaW9kIGZvciB0d28tZGlnaXQgeWVhciB2YWx1ZXMuCisgICAgICoKKyAgICAgKiA8cD5XaGVuIHBhcnNpbmcgYSBkYXRlIHN0cmluZyB1c2luZyB0aGUgYWJicmV2aWF0ZWQgeWVhciBwYXR0ZXJuIHtAY29kZSB5eX0sIHtAY29kZQorICAgICAqIFNpbXBsZURhdGVGb3JtYXR9IG11c3QgaW50ZXJwcmV0IHRoZSBhYmJyZXZpYXRlZCB5ZWFyIHJlbGF0aXZlIHRvIHNvbWUKKyAgICAgKiBjZW50dXJ5LiBJdCBkb2VzIHRoaXMgYnkgYWRqdXN0aW5nIGRhdGVzIHRvIGJlIHdpdGhpbiA4MCB5ZWFycyBiZWZvcmUgYW5kIDIwCisgICAgICogeWVhcnMgYWZ0ZXIgdGhlIHRpbWUgdGhlIHtAY29kZSBTaW1wbGVEYXRlRm9ybWF0fSBpbnN0YW5jZSB3YXMgY3JlYXRlZC4gRm9yCisgICAgICogZXhhbXBsZSwgdXNpbmcgYSBwYXR0ZXJuIG9mIHtAY29kZSBNTS9kZC95eX0sIGFuCisgICAgICogaW5zdGFuY2UgY3JlYXRlZCBvbiBKYW4gMSwgMTk5NyB3b3VsZCBpbnRlcnByZXQgdGhlIHN0cmluZyB7QGNvZGUgIjAxLzExLzEyIn0KKyAgICAgKiBhcyBKYW4gMTEsIDIwMTIgYnV0IGludGVycHJldCB0aGUgc3RyaW5nIHtAY29kZSAiMDUvMDQvNjQifSBhcyBNYXkgNCwgMTk2NC4KKyAgICAgKiBEdXJpbmcgcGFyc2luZywgb25seSBzdHJpbmdzIGNvbnNpc3Rpbmcgb2YgZXhhY3RseSB0d28gZGlnaXRzLCBhcworICAgICAqIGRlZmluZWQgYnkge0BsaW5rIGphdmEubGFuZy5DaGFyYWN0ZXIjaXNEaWdpdChjaGFyKX0sIHdpbGwgYmUgcGFyc2VkIGludG8gdGhlCisgICAgICogZGVmYXVsdCBjZW50dXJ5LiBBbnkgb3RoZXIgbnVtZXJpYyBzdHJpbmcsIHN1Y2ggYXMgYSBvbmUgZGlnaXQgc3RyaW5nLCBhCisgICAgICogdGhyZWUgb3IgbW9yZSBkaWdpdCBzdHJpbmcsIG9yIGEgdHdvIGRpZ2l0IHN0cmluZyB0aGF0IGlzbid0IGFsbCBkaWdpdHMgKGZvcgorICAgICAqIGV4YW1wbGUsIHtAY29kZSAiLTEifSksIGlzIGludGVycHJldGVkIGxpdGVyYWxseS4gU28gdXNpbmcgdGhlIHNhbWUgcGF0dGVybiwgYm90aAorICAgICAqIHtAY29kZSAiMDEvMDIvMyJ9IGFuZCB7QGNvZGUgIjAxLzAyLzAwMyJ9IGFyZSBwYXJzZWQgYXMgSmFuIDIsIDMgQUQuCisgICAgICogU2ltaWxhcmx5LCB7QGNvZGUgIjAxLzAyLy0zIn0gaXMgcGFyc2VkIGFzIEphbiAyLCA0IEJDLgorICAgICAqCisgICAgICogPHA+SWYgdGhlIHllYXIgcGF0dGVybiBkb2VzIG5vdCBoYXZlIGV4YWN0bHkgdHdvICd5JyBjaGFyYWN0ZXJzLCB0aGUgeWVhciBpcworICAgICAqIGludGVycHJldGVkIGxpdGVyYWxseSwgcmVnYXJkbGVzcyBvZiB0aGUgbnVtYmVyIG9mIGRpZ2l0cy4gU28gdXNpbmcgdGhlCisgICAgICogcGF0dGVybiB7QGNvZGUgTU0vZGQveXl5eX0sIHtAY29kZSAiMDEvMTEvMTIifSBpcyBwYXJzZWQgYXMgSmFuIDExLCAxMiBBLkQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0MkRpZ2l0WWVhclN0YXJ0KERhdGUgZGF0ZSkgeworICAgICAgICBkZWZhdWx0Q2VudHVyeVN0YXJ0ID0gKERhdGUpIGRhdGUuY2xvbmUoKTsKKyAgICAgICAgQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKCk7CisgICAgICAgIGNhbC5zZXRUaW1lKGRlZmF1bHRDZW50dXJ5U3RhcnQpOworICAgICAgICBjcmVhdGlvblllYXIgPSBjYWwuZ2V0KENhbGVuZGFyLllFQVIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHtAY29kZSBEYXRlRm9ybWF0U3ltYm9sc30gdXNlZCBieSB0aGlzIHNpbXBsZSBkYXRlIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB7QGNvZGUgRGF0ZUZvcm1hdFN5bWJvbHN9IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREYXRlRm9ybWF0U3ltYm9scyhEYXRlRm9ybWF0U3ltYm9scyB2YWx1ZSkgeworICAgICAgICBmb3JtYXREYXRhID0gKERhdGVGb3JtYXRTeW1ib2xzKSB2YWx1ZS5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHBhdHRlcm4gb2YgdGhpcyBzaW1wbGUgZGF0ZSBmb3JtYXQgdXNpbmcgbG9jYWxpemVkIHBhdHRlcm4KKyAgICAgKiBjaGFyYWN0ZXJzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbG9jYWxpemVkIHBhdHRlcm4uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b0xvY2FsaXplZFBhdHRlcm4oKSB7CisgICAgICAgIHJldHVybiBjb252ZXJ0UGF0dGVybihwYXR0ZXJuLCBQQVRURVJOX0NIQVJTLCBmb3JtYXREYXRhLmdldExvY2FsUGF0dGVybkNoYXJzKCksIGZhbHNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgY29udmVydFBhdHRlcm4oU3RyaW5nIHRlbXBsYXRlLCBTdHJpbmcgZnJvbUNoYXJzLCBTdHJpbmcgdG9DaGFycywgYm9vbGVhbiBjaGVjaykgeworICAgICAgICBpZiAoIWNoZWNrICYmIGZyb21DaGFycy5lcXVhbHModG9DaGFycykpIHsKKyAgICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZTsKKyAgICAgICAgfQorICAgICAgICBib29sZWFuIHF1b3RlID0gZmFsc2U7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgb3V0cHV0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgaW50IGxlbmd0aCA9IHRlbXBsYXRlLmxlbmd0aCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpbnQgaW5kZXg7CisgICAgICAgICAgICBjaGFyIG5leHQgPSB0ZW1wbGF0ZS5jaGFyQXQoaSk7CisgICAgICAgICAgICBpZiAobmV4dCA9PSAnXCcnKSB7CisgICAgICAgICAgICAgICAgcXVvdGUgPSAhcXVvdGU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIXF1b3RlICYmIChpbmRleCA9IGZyb21DaGFycy5pbmRleE9mKG5leHQpKSAhPSAtMSkgeworICAgICAgICAgICAgICAgIG91dHB1dC5hcHBlbmQodG9DaGFycy5jaGFyQXQoaW5kZXgpKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sgJiYgIXF1b3RlICYmICgobmV4dCA+PSAnYScgJiYgbmV4dCA8PSAneicpIHx8IChuZXh0ID49ICdBJyAmJiBuZXh0IDw9ICdaJykpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBwYXR0ZXJuIGNoYXJhY3RlciAnIiArIG5leHQgKyAiJyBpbiAiICsgIiciICsgdGVtcGxhdGUgKyAiJyIpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBvdXRwdXQuYXBwZW5kKG5leHQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChxdW90ZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVW50ZXJtaW5hdGVkIHF1b3RlIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG91dHB1dC50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHBhdHRlcm4gb2YgdGhpcyBzaW1wbGUgZGF0ZSBmb3JtYXQgdXNpbmcgbm9uLWxvY2FsaXplZAorICAgICAqIHBhdHRlcm4gY2hhcmFjdGVycy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5vbi1sb2NhbGl6ZWQgcGF0dGVybi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvUGF0dGVybigpIHsKKyAgICAgICAgcmV0dXJuIHBhdHRlcm47CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0U3RyZWFtRmllbGRbXSBzZXJpYWxQZXJzaXN0ZW50RmllbGRzID0geworICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImRlZmF1bHRDZW50dXJ5U3RhcnQiLCBEYXRlLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJmb3JtYXREYXRhIiwgRGF0ZUZvcm1hdFN5bWJvbHMuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInBhdHRlcm4iLCBTdHJpbmcuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInNlcmlhbFZlcnNpb25PblN0cmVhbSIsIGludC5jbGFzcyksCisgICAgfTsKKworICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGQgZmllbGRzID0gc3RyZWFtLnB1dEZpZWxkcygpOworICAgICAgICBmaWVsZHMucHV0KCJkZWZhdWx0Q2VudHVyeVN0YXJ0IiwgZGVmYXVsdENlbnR1cnlTdGFydCk7CisgICAgICAgIGZpZWxkcy5wdXQoImZvcm1hdERhdGEiLCBmb3JtYXREYXRhKTsKKyAgICAgICAgZmllbGRzLnB1dCgicGF0dGVybiIsIHBhdHRlcm4pOworICAgICAgICBmaWVsZHMucHV0KCJzZXJpYWxWZXJzaW9uT25TdHJlYW0iLCAxKTsKKyAgICAgICAgc3RyZWFtLndyaXRlRmllbGRzKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBPYmplY3RJbnB1dFN0cmVhbS5HZXRGaWVsZCBmaWVsZHMgPSBzdHJlYW0ucmVhZEZpZWxkcygpOworICAgICAgICBpbnQgdmVyc2lvbiA9IGZpZWxkcy5nZXQoInNlcmlhbFZlcnNpb25PblN0cmVhbSIsIDApOworICAgICAgICBEYXRlIGRhdGU7CisgICAgICAgIGlmICh2ZXJzaW9uID4gMCkgeworICAgICAgICAgICAgZGF0ZSA9IChEYXRlKSBmaWVsZHMuZ2V0KCJkZWZhdWx0Q2VudHVyeVN0YXJ0IiwgbmV3IERhdGUoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBkYXRlID0gbmV3IERhdGUoKTsKKyAgICAgICAgfQorICAgICAgICBzZXQyRGlnaXRZZWFyU3RhcnQoZGF0ZSk7CisgICAgICAgIGZvcm1hdERhdGEgPSAoRGF0ZUZvcm1hdFN5bWJvbHMpIGZpZWxkcy5nZXQoImZvcm1hdERhdGEiLCBudWxsKTsKKyAgICAgICAgcGF0dGVybiA9IChTdHJpbmcpIGZpZWxkcy5nZXQoInBhdHRlcm4iLCAiIik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9TdHJpbmdDaGFyYWN0ZXJJdGVyYXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9TdHJpbmdDaGFyYWN0ZXJJdGVyYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4YjExZjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L1N0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yLmphdmEKQEAgLTAsMCArMSwyNjkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudGV4dDsKKworLyoqCisgKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgQ2hhcmFjdGVySXRlcmF0b3J9IGZvciBzdHJpbmdzLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3IgaW1wbGVtZW50cyBDaGFyYWN0ZXJJdGVyYXRvciB7CisKKyAgICBTdHJpbmcgc3RyaW5nOworCisgICAgaW50IHN0YXJ0LCBlbmQsIG9mZnNldDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yfSBvbiB0aGUgc3BlY2lmaWVkIHN0cmluZy4KKyAgICAgKiBUaGUgYmVnaW4gYW5kIGN1cnJlbnQgaW5kaWNlcyBhcmUgc2V0IHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0cmluZywgdGhlCisgICAgICogZW5kIGluZGV4IGlzIHNldCB0byB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGl0ZXJhdGUgb3Zlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3IoU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIHN0cmluZyA9IHZhbHVlOworICAgICAgICBzdGFydCA9IG9mZnNldCA9IDA7CisgICAgICAgIGVuZCA9IHN0cmluZy5sZW5ndGgoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBTdHJpbmdDaGFyYWN0ZXJJdGVyYXRvcn0gb24gdGhlIHNwZWNpZmllZCBzdHJpbmcKKyAgICAgKiB3aXRoIHRoZSBjdXJyZW50IGluZGV4IHNldCB0byB0aGUgc3BlY2lmaWVkIHZhbHVlLiBUaGUgYmVnaW4gaW5kZXggaXMgc2V0CisgICAgICogdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyaW5nLCB0aGUgZW5kIGluZGV4IGlzIHNldCB0byB0aGUgbGVuZ3RoIG9mIHRoZQorICAgICAqIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBzdHJpbmcgdG8gaXRlcmF0ZSBvdmVyLgorICAgICAqIEBwYXJhbSBsb2NhdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGN1cnJlbnQgaW5kZXguCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIGlmIHtAY29kZSBsb2NhdGlvbn0gaXMgbmVnYXRpdmUgb3IgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIG9mIHRoZSBzb3VyY2Ugc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdDaGFyYWN0ZXJJdGVyYXRvcihTdHJpbmcgdmFsdWUsIGludCBsb2NhdGlvbikgeworICAgICAgICBzdHJpbmcgPSB2YWx1ZTsKKyAgICAgICAgc3RhcnQgPSAwOworICAgICAgICBlbmQgPSBzdHJpbmcubGVuZ3RoKCk7CisgICAgICAgIGlmIChsb2NhdGlvbiA8IDAgfHwgbG9jYXRpb24gPiBlbmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBvZmZzZXQgPSBsb2NhdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBTdHJpbmdDaGFyYWN0ZXJJdGVyYXRvcn0gb24gdGhlIHNwZWNpZmllZCBzdHJpbmcKKyAgICAgKiB3aXRoIHRoZSBiZWdpbiwgZW5kIGFuZCBjdXJyZW50IGluZGV4IHNldCB0byB0aGUgc3BlY2lmaWVkIHZhbHVlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBzdHJpbmcgdG8gaXRlcmF0ZSBvdmVyLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgdG8gaXRlcmF0ZS4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb25lIHBhc3QgdGhlIGxhc3QgY2hhcmFjdGVyIHRvIGl0ZXJhdGUuCisgICAgICogQHBhcmFtIGxvY2F0aW9uCisgICAgICogICAgICAgICAgICB0aGUgY3VycmVudCBpbmRleC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0IDwgMH0sIHtAY29kZSBzdGFydCA+IGVuZH0sIHtAY29kZSBsb2NhdGlvbiA8CisgICAgICogICAgICAgICAgICBzdGFydH0sIHtAY29kZSBsb2NhdGlvbiA+IGVuZH0gb3IgaWYge0Bjb2RlIGVuZH0gaXMgZ3JlYXRlcgorICAgICAqICAgICAgICAgICAgdGhhbiB0aGUgbGVuZ3RoIG9mIHtAY29kZSB2YWx1ZX0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yKFN0cmluZyB2YWx1ZSwgaW50IHN0YXJ0LCBpbnQgZW5kLCBpbnQgbG9jYXRpb24pIHsKKyAgICAgICAgc3RyaW5nID0gdmFsdWU7CisgICAgICAgIGlmIChzdGFydCA8IDAgfHwgZW5kID4gc3RyaW5nLmxlbmd0aCgpIHx8IHN0YXJ0ID4gZW5kCisgICAgICAgICAgICAgICAgfHwgbG9jYXRpb24gPCBzdGFydCB8fCBsb2NhdGlvbiA+IGVuZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMuc3RhcnQgPSBzdGFydDsKKyAgICAgICAgdGhpcy5lbmQgPSBlbmQ7CisgICAgICAgIG9mZnNldCA9IGxvY2F0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yfSB3aXRoIHRoZSBzYW1lIHNvdXJjZQorICAgICAqIHN0cmluZywgYmVnaW4sIGVuZCwgYW5kIGN1cnJlbnQgaW5kZXggYXMgdGhpcyBpdGVyYXRvci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzaGFsbG93IGNvcHkgb2YgdGhpcyBpdGVyYXRvci4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5DbG9uZWFibGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNoYXJhY3RlciBhdCB0aGUgY3VycmVudCBpbmRleCBpbiB0aGUgc291cmNlIHN0cmluZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgY2hhcmFjdGVyLCBvciB7QGNvZGUgRE9ORX0gaWYgdGhlIGN1cnJlbnQgaW5kZXggaXMKKyAgICAgKiAgICAgICAgIHBhc3QgdGhlIGVuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhciBjdXJyZW50KCkgeworICAgICAgICBpZiAob2Zmc2V0ID09IGVuZCkgeworICAgICAgICAgICAgcmV0dXJuIERPTkU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN0cmluZy5jaGFyQXQob2Zmc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIG9iamVjdCB3aXRoIHRoaXMge0Bjb2RlIFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yfQorICAgICAqIGFuZCBpbmRpY2F0ZXMgaWYgdGhleSBhcmUgZXF1YWwuIEluIG9yZGVyIHRvIGJlIGVxdWFsLCB7QGNvZGUgb2JqZWN0fQorICAgICAqIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yfSB0aGF0IGl0ZXJhdGVzIG92ZXIKKyAgICAgKiB0aGUgc2FtZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIHdpdGggdGhlIHNhbWUgaW5kZXguCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUgd2l0aCB0aGlzIG9iamVjdC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBlcXVhbCB0byB0aGlzCisgICAgICogICAgICAgICB7QGNvZGUgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3J9OyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNoYXNoQ29kZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmICghKG9iamVjdCBpbnN0YW5jZW9mIFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yIGl0ID0gKFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yKSBvYmplY3Q7CisgICAgICAgIHJldHVybiBzdHJpbmcuZXF1YWxzKGl0LnN0cmluZykgJiYgc3RhcnQgPT0gaXQuc3RhcnQgJiYgZW5kID09IGl0LmVuZAorICAgICAgICAgICAgICAgICYmIG9mZnNldCA9PSBpdC5vZmZzZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY3VycmVudCBwb3NpdGlvbiB0byB0aGUgYmVnaW4gaW5kZXggYW5kIHJldHVybnMgdGhlIGNoYXJhY3RlciBhdAorICAgICAqIHRoZSBuZXcgcG9zaXRpb24gaW4gdGhlIHNvdXJjZSBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIGJlZ2luIGluZGV4IG9yIHtAY29kZSBET05FfSBpZiB0aGUgYmVnaW4KKyAgICAgKiAgICAgICAgIGluZGV4IGlzIGVxdWFsIHRvIHRoZSBlbmQgaW5kZXguCisgICAgICovCisgICAgcHVibGljIGNoYXIgZmlyc3QoKSB7CisgICAgICAgIGlmIChzdGFydCA9PSBlbmQpIHsKKyAgICAgICAgICAgIHJldHVybiBET05FOworICAgICAgICB9CisgICAgICAgIG9mZnNldCA9IHN0YXJ0OworICAgICAgICByZXR1cm4gc3RyaW5nLmNoYXJBdChvZmZzZXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGJlZ2luIGluZGV4IGluIHRoZSBzb3VyY2Ugc3RyaW5nLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgaXRlcmF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0QmVnaW5JbmRleCgpIHsKKyAgICAgICAgcmV0dXJuIHN0YXJ0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGVuZCBpbmRleCBpbiB0aGUgc291cmNlIHN0cmluZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9uZSBwYXN0IHRoZSBsYXN0IGNoYXJhY3RlciBvZiB0aGUgaXRlcmF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RW5kSW5kZXgoKSB7CisgICAgICAgIHJldHVybiBlbmQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3VycmVudCBpbmRleCBpbiB0aGUgc291cmNlIHN0cmluZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgaW5kZXguCisgICAgICovCisgICAgcHVibGljIGludCBnZXRJbmRleCgpIHsKKyAgICAgICAgcmV0dXJuIG9mZnNldDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gc3RyaW5nLmhhc2hDb2RlKCkgKyBzdGFydCArIGVuZCArIG9mZnNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjdXJyZW50IHBvc2l0aW9uIHRvIHRoZSBlbmQgaW5kZXggLSAxIGFuZCByZXR1cm5zIHRoZSBjaGFyYWN0ZXIKKyAgICAgKiBhdCB0aGUgbmV3IHBvc2l0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2hhcmFjdGVyIGJlZm9yZSB0aGUgZW5kIGluZGV4IG9yIHtAY29kZSBET05FfSBpZiB0aGUgYmVnaW4KKyAgICAgKiAgICAgICAgIGluZGV4IGlzIGVxdWFsIHRvIHRoZSBlbmQgaW5kZXguCisgICAgICovCisgICAgcHVibGljIGNoYXIgbGFzdCgpIHsKKyAgICAgICAgaWYgKHN0YXJ0ID09IGVuZCkgeworICAgICAgICAgICAgcmV0dXJuIERPTkU7CisgICAgICAgIH0KKyAgICAgICAgb2Zmc2V0ID0gZW5kIC0gMTsKKyAgICAgICAgcmV0dXJuIHN0cmluZy5jaGFyQXQob2Zmc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmNyZW1lbnRzIHRoZSBjdXJyZW50IGluZGV4IGFuZCByZXR1cm5zIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIG5ldyBpbmRleC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNoYXJhY3RlciBhdCB0aGUgbmV4dCBpbmRleCwgb3Ige0Bjb2RlIERPTkV9IGlmIHRoZSBuZXh0CisgICAgICogICAgICAgICBpbmRleCB3b3VsZCBiZSBwYXN0IHRoZSBlbmQuCisgICAgICovCisgICAgcHVibGljIGNoYXIgbmV4dCgpIHsKKyAgICAgICAgaWYgKG9mZnNldCA+PSAoZW5kIC0gMSkpIHsKKyAgICAgICAgICAgIG9mZnNldCA9IGVuZDsKKyAgICAgICAgICAgIHJldHVybiBET05FOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzdHJpbmcuY2hhckF0KCsrb2Zmc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNyZW1lbnRzIHRoZSBjdXJyZW50IGluZGV4IGFuZCByZXR1cm5zIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIG5ldyBpbmRleC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNoYXJhY3RlciBhdCB0aGUgcHJldmlvdXMgaW5kZXgsIG9yIHtAY29kZSBET05FfSBpZiB0aGUKKyAgICAgKiAgICAgICAgIHByZXZpb3VzIGluZGV4IHdvdWxkIGJlIHBhc3QgdGhlIGJlZ2lubmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhciBwcmV2aW91cygpIHsKKyAgICAgICAgaWYgKG9mZnNldCA9PSBzdGFydCkgeworICAgICAgICAgICAgcmV0dXJuIERPTkU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN0cmluZy5jaGFyQXQoLS1vZmZzZXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGN1cnJlbnQgaW5kZXggaW4gdGhlIHNvdXJjZSBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCB0aGUgY3VycmVudCBwb3NpdGlvbiBpcyBzZXQgdG8uCisgICAgICogQHJldHVybiB0aGUgY2hhcmFjdGVyIGF0IHRoZSBuZXcgaW5kZXgsIG9yIHtAY29kZSBET05FfSBpZgorICAgICAqICAgICAgICAge0Bjb2RlIGxvY2F0aW9ufSBpcyBzZXQgdG8gdGhlIGVuZCBpbmRleC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaWYge0Bjb2RlIGxvY2F0aW9ufSBpcyBzbWFsbGVyIHRoYW4gdGhlIGJlZ2luIGluZGV4IG9yIGdyZWF0ZXIKKyAgICAgKiAgICAgICAgICAgIHRoYW4gdGhlIGVuZCBpbmRleC4KKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhciBzZXRJbmRleChpbnQgbG9jYXRpb24pIHsKKyAgICAgICAgaWYgKGxvY2F0aW9uIDwgc3RhcnQgfHwgbG9jYXRpb24gPiBlbmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBvZmZzZXQgPSBsb2NhdGlvbjsKKyAgICAgICAgaWYgKG9mZnNldCA9PSBlbmQpIHsKKyAgICAgICAgICAgIHJldHVybiBET05FOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzdHJpbmcuY2hhckF0KG9mZnNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc291cmNlIHN0cmluZyB0byBpdGVyYXRlIG92ZXIuIFRoZSBiZWdpbiBhbmQgZW5kIHBvc2l0aW9ucyBhcmUKKyAgICAgKiBzZXQgdG8gdGhlIHN0YXJ0IGFuZCBlbmQgb2YgdGhpcyBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgc291cmNlIHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUZXh0KFN0cmluZyB2YWx1ZSkgeworICAgICAgICBzdHJpbmcgPSB2YWx1ZTsKKyAgICAgICAgc3RhcnQgPSBvZmZzZXQgPSAwOworICAgICAgICBlbmQgPSB2YWx1ZS5sZW5ndGgoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L3NwaS9CcmVha0l0ZXJhdG9yUHJvdmlkZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvc3BpL0JyZWFrSXRlcmF0b3JQcm92aWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEyOGJjNTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L3NwaS9CcmVha0l0ZXJhdG9yUHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDkwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnRleHQuc3BpOworCitpbXBvcnQgamF2YS50ZXh0LkJyZWFrSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuc3BpLkxvY2FsZVNlcnZpY2VQcm92aWRlcjsKKworLyoqCisgKiBUaGlzIGFic3RyYWN0IGNsYXNzIHNob3VsZCBiZSBleHRlbmRlZCBieSBzZXJ2aWNlIHByb3ZpZGVycyB0aGF0IHByb3ZpZGUKKyAqIGluc3RhbmNlcyBvZiB7QGNvZGUgQnJlYWtJdGVyYXRvcn0uCisgKiA8cD5Ob3RlIHRoYXQgQW5kcm9pZCBkb2VzIG5vdCBzdXBwb3J0IHVzZXItc3VwcGxpZWQgbG9jYWxlIHNlcnZpY2UgcHJvdmlkZXJzLgorICogQHNpbmNlIDEuNgorICogQGhpZGUKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEJyZWFrSXRlcmF0b3JQcm92aWRlciBleHRlbmRzIExvY2FsZVNlcnZpY2VQcm92aWRlciB7CisgICAgLyoqCisgICAgICogRGVmYXVsdCBjb25zdHJ1Y3RvciwgZm9yIHVzZSBieSBzdWJjbGFzc2VzLgorICAgICAqLworICAgIHByb3RlY3RlZCBCcmVha0l0ZXJhdG9yUHJvdmlkZXIoKSB7CisgICAgICAgIC8vIERvIG5vdGhpbmcuCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgQnJlYWtJdGVyYXRvcn0gZm9yIHdvcmQgYnJlYWtzIGluIHRoZQorICAgICAqIGdpdmVuIGxvY2FsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZQorICAgICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIEJyZWFrSXRlcmF0b3J9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgbG9jYWxlID09IG51bGx9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBsb2NhbGUgaXNuJ3Qgb25lIG9mIHRoZSBsb2NhbGVzIHJldHVybmVkIGZyb20KKyAgICAgKiAgICAgICAgICAgICBnZXRBdmFpbGFibGVMb2NhbGVzKCkuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJyZWFrSXRlcmF0b3IgZ2V0V29yZEluc3RhbmNlKExvY2FsZSBsb2NhbGUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgQnJlYWtJdGVyYXRvcn0gZm9yIGxpbmUgYnJlYWtzIGluIHRoZQorICAgICAqIGdpdmVuIGxvY2FsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZQorICAgICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIEJyZWFrSXRlcmF0b3J9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgbG9jYWxlID09IG51bGx9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBsb2NhbGUgaXNuJ3Qgb25lIG9mIHRoZSBsb2NhbGVzIHJldHVybmVkIGZyb20KKyAgICAgKiAgICAgICAgICAgICBnZXRBdmFpbGFibGVMb2NhbGVzKCkuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJyZWFrSXRlcmF0b3IgZ2V0TGluZUluc3RhbmNlKExvY2FsZSBsb2NhbGUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgQnJlYWtJdGVyYXRvcn0gZm9yIGNoYXJhY3RlciBicmVha3MgaW4gdGhlCisgICAgICogZ2l2ZW4gbG9jYWxlLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlCisgICAgICogQHJldHVybiBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgQnJlYWtJdGVyYXRvcn0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBsb2NhbGUgPT0gbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGxvY2FsZSBpc24ndCBvbmUgb2YgdGhlIGxvY2FsZXMgcmV0dXJuZWQgZnJvbQorICAgICAqICAgICAgICAgICAgIGdldEF2YWlsYWJsZUxvY2FsZXMoKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnJlYWtJdGVyYXRvciBnZXRDaGFyYWN0ZXJJbnN0YW5jZShMb2NhbGUgbG9jYWxlKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIEJyZWFrSXRlcmF0b3J9IGZvciBzZW50ZW5jZSBicmVha3MgaW4gdGhlCisgICAgICogZ2l2ZW4gbG9jYWxlLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlCisgICAgICogQHJldHVybiBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgQnJlYWtJdGVyYXRvcn0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBsb2NhbGUgPT0gbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGxvY2FsZSBpc24ndCBvbmUgb2YgdGhlIGxvY2FsZXMgcmV0dXJuZWQgZnJvbQorICAgICAqICAgICAgICAgICAgIGdldEF2YWlsYWJsZUxvY2FsZXMoKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnJlYWtJdGVyYXRvciBnZXRTZW50ZW5jZUluc3RhbmNlKExvY2FsZSBsb2NhbGUpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9zcGkvQ29sbGF0b3JQcm92aWRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9zcGkvQ29sbGF0b3JQcm92aWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA4NjI0MzIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L3NwaS9Db2xsYXRvclByb3ZpZGVyLmphdmEKQEAgLTAsMCArMSw1MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS50ZXh0LnNwaTsKKworaW1wb3J0IGphdmEudGV4dC5Db2xsYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5zcGkuTG9jYWxlU2VydmljZVByb3ZpZGVyOworCisvKioKKyAqIFRoaXMgYWJzdHJhY3QgY2xhc3Mgc2hvdWxkIGJlIGV4dGVuZGVkIGJ5IHNlcnZpY2UgcHJvdmlkZXJzIHdoaWNoIHByb3ZpZGUKKyAqIGluc3RhbmNlcyBvZiB7QGNvZGUgQ29sbGF0b3J9LgorICogPHA+Tm90ZSB0aGF0IEFuZHJvaWQgZG9lcyBub3Qgc3VwcG9ydCB1c2VyLXN1cHBsaWVkIGxvY2FsZSBzZXJ2aWNlIHByb3ZpZGVycy4KKyAqIEBzaW5jZSAxLjYKKyAqIEBoaWRlCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBDb2xsYXRvclByb3ZpZGVyIGV4dGVuZHMgTG9jYWxlU2VydmljZVByb3ZpZGVyIHsKKyAgICAvKioKKyAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLCBmb3IgdXNlIGJ5IHN1YmNsYXNzZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIENvbGxhdG9yUHJvdmlkZXIoKSB7CisgICAgICAgIC8vIERvIG5vdGhpbmcuCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgQ29sbGF0b3J9IGZvciB0aGUgZ2l2ZW4gbG9jYWxlLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlCisgICAgICogQHJldHVybiBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgQ29sbGF0b3J9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgbG9jYWxlID09IG51bGx9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBsb2NhbGUgaXNuJ3Qgb25lIG9mIHRoZSBsb2NhbGVzIHJldHVybmVkIGZyb20KKyAgICAgKiAgICAgICAgICAgICBnZXRBdmFpbGFibGVMb2NhbGVzKCkuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENvbGxhdG9yIGdldEluc3RhbmNlKExvY2FsZSBsb2NhbGUpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9zcGkvRGF0ZUZvcm1hdFByb3ZpZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L3NwaS9EYXRlRm9ybWF0UHJvdmlkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OWZlZmVkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9zcGkvRGF0ZUZvcm1hdFByb3ZpZGVyLmphdmEKQEAgLTAsMCArMSw4MSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS50ZXh0LnNwaTsKKworaW1wb3J0IGphdmEudGV4dC5EYXRlRm9ybWF0OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLnNwaS5Mb2NhbGVTZXJ2aWNlUHJvdmlkZXI7CisKKy8qKgorICogVGhpcyBhYnN0cmFjdCBjbGFzcyBzaG91bGQgYmUgZXh0ZW5kZWQgYnkgc2VydmljZSBwcm92aWRlcnMgdGhhdCBwcm92aWRlCisgKiBpbnN0YW5jZXMgb2Yge0Bjb2RlIERhdGVGb3JtYXR9LgorICogPHA+Tm90ZSB0aGF0IEFuZHJvaWQgZG9lcyBub3Qgc3VwcG9ydCB1c2VyLXN1cHBsaWVkIGxvY2FsZSBzZXJ2aWNlIHByb3ZpZGVycy4KKyAqIEBzaW5jZSAxLjYKKyAqIEBoaWRlCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBEYXRlRm9ybWF0UHJvdmlkZXIgZXh0ZW5kcyBMb2NhbGVTZXJ2aWNlUHJvdmlkZXIgeworICAgIC8qKgorICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IsIGZvciB1c2UgYnkgc3ViY2xhc3Nlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRGF0ZUZvcm1hdFByb3ZpZGVyKCkgeworICAgICAgICAvLyBEbyBub3RoaW5nLgorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIERhdGVGb3JtYXR9IHRoYXQgZm9ybWF0cyB0aW1lcworICAgICAqIGluIHRoZSBnaXZlbiBzdHlsZSBmb3IgdGhlIGdpdmVuIGxvY2FsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHlsZSB0aGUgZ2l2ZW4gdGltZSBmb3JtYXR0aW5nIHN0eWxlLgorICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZQorICAgICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIERhdGVGb3JtYXR9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgbG9jYWxlID09IG51bGx9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBsb2NhbGUgaXNuJ3Qgb25lIG9mIHRoZSBsb2NhbGVzIHJldHVybmVkIGZyb20KKyAgICAgKiAgICAgICAgICAgICBnZXRBdmFpbGFibGVMb2NhbGVzKCkuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IERhdGVGb3JtYXQgZ2V0VGltZUluc3RhbmNlKGludCBzdHlsZSwgTG9jYWxlIGxvY2FsZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIHtAY29kZSBEYXRlRm9ybWF0fSB0aGF0IGZvcm1hdHMgZGF0ZXMKKyAgICAgKiBpbiB0aGUgZ2l2ZW4gc3R5bGUgZm9yIHRoZSBnaXZlbiBsb2NhbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3R5bGUgdGhlIGdpdmVuIGRhdGUgZm9ybWF0dGluZyBzdHlsZS4KKyAgICAgKiBAcGFyYW0gbG9jYWxlIHRoZSBsb2NhbGUKKyAgICAgKiBAcmV0dXJuIGFuIGluc3RhbmNlIG9mIHtAY29kZSBEYXRlRm9ybWF0fQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIGxvY2FsZSA9PSBudWxsfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgbG9jYWxlIGlzbid0IG9uZSBvZiB0aGUgbG9jYWxlcyByZXR1cm5lZCBmcm9tCisgICAgICogICAgICAgICAgICAgZ2V0QXZhaWxhYmxlTG9jYWxlcygpLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBEYXRlRm9ybWF0IGdldERhdGVJbnN0YW5jZShpbnQgc3R5bGUsIExvY2FsZSBsb2NhbGUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgRGF0ZUZvcm1hdH0gdGhhdCBmb3JtYXRzIGRhdGVzIGFuZCB0aW1lcworICAgICAqIGluIHRoZSBnaXZlbiBzdHlsZSBmb3IgdGhlIGdpdmVuIGxvY2FsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRlU3R5bGUgdGhlIGdpdmVuIGRhdGUgZm9ybWF0dGluZyBzdHlsZS4KKyAgICAgKiBAcGFyYW0gdGltZVN0eWxlIHRoZSBnaXZlbiB0aW1lIGZvcm1hdHRpbmcgc3R5bGUuCisgICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlCisgICAgICogQHJldHVybiBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgRGF0ZUZvcm1hdH0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBsb2NhbGUgPT0gbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGxvY2FsZSBpc24ndCBvbmUgb2YgdGhlIGxvY2FsZXMgcmV0dXJuZWQgZnJvbQorICAgICAqICAgICAgICAgICAgIGdldEF2YWlsYWJsZUxvY2FsZXMoKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRGF0ZUZvcm1hdCBnZXREYXRlVGltZUluc3RhbmNlKGludCBkYXRlU3R5bGUsIGludCB0aW1lU3R5bGUsIExvY2FsZSBsb2NhbGUpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9zcGkvRGF0ZUZvcm1hdFN5bWJvbHNQcm92aWRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9zcGkvRGF0ZUZvcm1hdFN5bWJvbHNQcm92aWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNiMzRiNzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L3NwaS9EYXRlRm9ybWF0U3ltYm9sc1Byb3ZpZGVyLmphdmEKQEAgLTAsMCArMSw1MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS50ZXh0LnNwaTsKKworaW1wb3J0IGphdmEudGV4dC5EYXRlRm9ybWF0U3ltYm9sczsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5zcGkuTG9jYWxlU2VydmljZVByb3ZpZGVyOworCisvKioKKyAqIFRoaXMgYWJzdHJhY3QgY2xhc3Mgc2hvdWxkIGJlIGV4dGVuZGVkIGJ5IHNlcnZpY2UgcHJvdmlkZXJzIHRoYXQgcHJvdmlkZQorICogaW5zdGFuY2VzIG9mIHtAY29kZSBEYXRlRm9ybWF0U3ltYm9sc30uCisgKiA8cD5Ob3RlIHRoYXQgQW5kcm9pZCBkb2VzIG5vdCBzdXBwb3J0IHVzZXItc3VwcGxpZWQgbG9jYWxlIHNlcnZpY2UgcHJvdmlkZXJzLgorICogQHNpbmNlIDEuNgorICogQGhpZGUKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIERhdGVGb3JtYXRTeW1ib2xzUHJvdmlkZXIgZXh0ZW5kcyBMb2NhbGVTZXJ2aWNlUHJvdmlkZXIgeworICAgIC8qKgorICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IsIGZvciB1c2UgYnkgc3ViY2xhc3Nlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRGF0ZUZvcm1hdFN5bWJvbHNQcm92aWRlcigpIHsKKyAgICAgICAgLy8gRG8gbm90aGluZy4KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIHtAY29kZSBEYXRlRm9ybWF0U3ltYm9sc30gZm9yIHRoZSBnaXZlbiBsb2NhbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYWxlIHRoZSBsb2NhbGUKKyAgICAgKiBAcmV0dXJuIGFuIGluc3RhbmNlIG9mIHtAY29kZSBEYXRlRm9ybWF0U3ltYm9sc30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBsb2NhbGUgPT0gbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGxvY2FsZSBpc24ndCBvbmUgb2YgdGhlIGxvY2FsZXMgcmV0dXJuZWQgZnJvbQorICAgICAqICAgICAgICAgICAgIGdldEF2YWlsYWJsZUxvY2FsZXMoKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRGF0ZUZvcm1hdFN5bWJvbHMgZ2V0SW5zdGFuY2UoTG9jYWxlIGxvY2FsZSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L3NwaS9EZWNpbWFsRm9ybWF0U3ltYm9sc1Byb3ZpZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS90ZXh0L3NwaS9EZWNpbWFsRm9ybWF0U3ltYm9sc1Byb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjlmNWU3ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvc3BpL0RlY2ltYWxGb3JtYXRTeW1ib2xzUHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDUxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnRleHQuc3BpOworCitpbXBvcnQgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXRTeW1ib2xzOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLnNwaS5Mb2NhbGVTZXJ2aWNlUHJvdmlkZXI7CisKKy8qKgorICogVGhpcyBhYnN0cmFjdCBjbGFzcyBzaG91bGQgYmUgZXh0ZW5kZWQgYnkgc2VydmljZSBwcm92aWRlcnMgdGhhdCBwcm92aWRlCisgKiBpbnN0YW5jZXMgb2Yge0Bjb2RlIERlY2ltYWxGb3JtYXRTeW1ib2xzfS4KKyAqIDxwPk5vdGUgdGhhdCBBbmRyb2lkIGRvZXMgbm90IHN1cHBvcnQgdXNlci1zdXBwbGllZCBsb2NhbGUgc2VydmljZSBwcm92aWRlcnMuCisgKiBAc2luY2UgMS42CisgKiBAaGlkZQorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRGVjaW1hbEZvcm1hdFN5bWJvbHNQcm92aWRlciBleHRlbmRzIExvY2FsZVNlcnZpY2VQcm92aWRlciB7CisgICAgLyoqCisgICAgICogRGVmYXVsdCBjb25zdHJ1Y3RvciwgZm9yIHVzZSBieSBzdWJjbGFzc2VzLgorICAgICAqLworICAgIHByb3RlY3RlZCBEZWNpbWFsRm9ybWF0U3ltYm9sc1Byb3ZpZGVyKCkgeworICAgICAgICAvLyBEbyBub3RoaW5nLgorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIERlY2ltYWxGb3JtYXRTeW1ib2xzfSBmb3IgdGhlIGdpdmVuIGxvY2FsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZQorICAgICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIERlY2ltYWxGb3JtYXRTeW1ib2xzfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIGxvY2FsZSA9PSBudWxsfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgbG9jYWxlIGlzbid0IG9uZSBvZiB0aGUgbG9jYWxlcyByZXR1cm5lZCBmcm9tCisgICAgICogICAgICAgICAgICAgZ2V0QXZhaWxhYmxlTG9jYWxlcygpLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBEZWNpbWFsRm9ybWF0U3ltYm9scyBnZXRJbnN0YW5jZShMb2NhbGUgbG9jYWxlKTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdGV4dC9zcGkvTnVtYmVyRm9ybWF0UHJvdmlkZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvc3BpL051bWJlckZvcm1hdFByb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzg4OWY3OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3RleHQvc3BpL051bWJlckZvcm1hdFByb3ZpZGVyLmphdmEKQEAgLTAsMCArMSw5MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS50ZXh0LnNwaTsKKworaW1wb3J0IGphdmEudGV4dC5OdW1iZXJGb3JtYXQ7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuc3BpLkxvY2FsZVNlcnZpY2VQcm92aWRlcjsKKworLyoqCisgKiBUaGlzIGFic3RyYWN0IGNsYXNzIHNob3VsZCBiZSBleHRlbmRlZCBieSBzZXJ2aWNlIHByb3ZpZGVycyB0aGF0IHByb3ZpZGUKKyAqIHtAY29kZSBOdW1iZXJGb3JtYXR9IGluc3RhbmNlcy4KKyAqIDxwPk5vdGUgdGhhdCBBbmRyb2lkIGRvZXMgbm90IHN1cHBvcnQgdXNlci1zdXBwbGllZCBsb2NhbGUgc2VydmljZSBwcm92aWRlcnMuCisgKiBAc2luY2UgMS42CisgKiBAaGlkZQorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTnVtYmVyRm9ybWF0UHJvdmlkZXIgZXh0ZW5kcyBMb2NhbGVTZXJ2aWNlUHJvdmlkZXIgeworICAgIC8qKgorICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IsIGZvciB1c2UgYnkgc3ViY2xhc3Nlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgTnVtYmVyRm9ybWF0UHJvdmlkZXIoKSB7CisgICAgICAgIC8vIERvIG5vdGhpbmcuCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgTnVtYmVyRm9ybWF0fSB0aGF0IGZvcm1hdHMKKyAgICAgKiBtb25ldGFyeSB2YWx1ZXMgZm9yIHRoZSBnaXZlbiBsb2NhbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYWxlIHRoZSBsb2NhbGUKKyAgICAgKiBAcmV0dXJuIGFuIGluc3RhbmNlIG9mIHtAY29kZSBOdW1iZXJGb3JtYXR9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgbG9jYWxlID09IG51bGx9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBsb2NhbGUgaXNuJ3Qgb25lIG9mIHRoZSBsb2NhbGVzIHJldHVybmVkIGZyb20KKyAgICAgKiAgICAgICAgICAgICBnZXRBdmFpbGFibGVMb2NhbGVzKCkuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IE51bWJlckZvcm1hdCBnZXRDdXJyZW5jeUluc3RhbmNlKExvY2FsZSBsb2NhbGUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgTnVtYmVyRm9ybWF0fSB0aGF0IGZvcm1hdHMKKyAgICAgKiBpbnRlZ2VyIHZhbHVlcyBmb3IgdGhlIGdpdmVuIGxvY2FsZS4gVGhlIHJldHVybmVkIHtAY29kZSBOdW1iZXJGb3JtYXR9CisgICAgICogaXMgY29uZmlndXJlZCB0byByb3VuZCBmbG9hdGluZyBwb2ludCBudW1iZXJzIHRvIHRoZSBuZWFyZXN0IGludGVnZXIKKyAgICAgKiB1c2luZyBoYWxmLWV2ZW4gcm91bmRpbmcgbW9kZSBmb3IgZm9ybWF0dGluZywgYW5kIHRvIHBhcnNlIG9ubHkgdGhlCisgICAgICogaW50ZWdlciBwYXJ0IG9mIGFuIGlucHV0IHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZQorICAgICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIE51bWJlckZvcm1hdH0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBsb2NhbGUgPT0gbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGxvY2FsZSBpc24ndCBvbmUgb2YgdGhlIGxvY2FsZXMgcmV0dXJuZWQgZnJvbQorICAgICAqICAgICAgICAgICAgIGdldEF2YWlsYWJsZUxvY2FsZXMoKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgTnVtYmVyRm9ybWF0IGdldEludGVnZXJJbnN0YW5jZShMb2NhbGUgbG9jYWxlKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIE51bWJlckZvcm1hdH0gY2xhc3MgZm9yIGdlbmVyYWwKKyAgICAgKiB1c2UgaW4gdGhlIGdpdmVuIGxvY2FsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZQorICAgICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIE51bWJlckZvcm1hdH0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBsb2NhbGUgPT0gbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGxvY2FsZSBpc24ndCBvbmUgb2YgdGhlIGxvY2FsZXMgcmV0dXJuZWQgZnJvbQorICAgICAqICAgICAgICAgICAgIGdldEF2YWlsYWJsZUxvY2FsZXMoKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgTnVtYmVyRm9ybWF0IGdldE51bWJlckluc3RhbmNlKExvY2FsZSBsb2NhbGUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgTnVtYmVyRm9ybWF0fSBjbGFzcyB0aGF0IGZvcm1hdHMKKyAgICAgKiBwZXJjZW50YWdlIHZhbHVlcyBmb3IgdGhlIGdpdmVuIGxvY2FsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZQorICAgICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIE51bWJlckZvcm1hdH0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBsb2NhbGUgPT0gbnVsbH0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGxvY2FsZSBpc24ndCBvbmUgb2YgdGhlIGxvY2FsZXMgcmV0dXJuZWQgZnJvbQorICAgICAqICAgICAgICAgICAgIGdldEF2YWlsYWJsZUxvY2FsZXMoKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgTnVtYmVyRm9ybWF0IGdldFBlcmNlbnRJbnN0YW5jZShMb2NhbGUgbG9jYWxlKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvQWJzdHJhY3RDb2xsZWN0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0Fic3RyYWN0Q29sbGVjdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdjYmRjYzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0Fic3RyYWN0Q29sbGVjdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzk0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkFycmF5OworCisvKioKKyAqIENsYXNzIHtAY29kZSBBYnN0cmFjdENvbGxlY3Rpb259IGlzIGFuIGFic3RyYWN0IGltcGxlbWVudGF0aW9uIG9mIHRoZSB7QGNvZGUKKyAqIENvbGxlY3Rpb259IGludGVyZmFjZS4gQSBzdWJjbGFzcyBtdXN0IGltcGxlbWVudCB0aGUgYWJzdHJhY3QgbWV0aG9kcyB7QGNvZGUKKyAqIGl0ZXJhdG9yKCl9IGFuZCB7QGNvZGUgc2l6ZSgpfSB0byBjcmVhdGUgYW4gaW1tdXRhYmxlIGNvbGxlY3Rpb24uIFRvIGNyZWF0ZSBhCisgKiBtb2RpZmlhYmxlIGNvbGxlY3Rpb24gaXQncyBuZWNlc3NhcnkgdG8gb3ZlcnJpZGUgdGhlIHtAY29kZSBhZGQoKX0gbWV0aG9kIHRoYXQKKyAqIGN1cnJlbnRseSB0aHJvd3MgYW4ge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufS4KKyAqCisgKiBAc2luY2UgMS4yCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdENvbGxlY3Rpb248RT4gaW1wbGVtZW50cyBDb2xsZWN0aW9uPEU+IHsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBBYnN0cmFjdENvbGxlY3Rpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIEFic3RyYWN0Q29sbGVjdGlvbigpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBhZGQoRSBvYmplY3QpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gYWRkIGFsbCBvZiB0aGUgb2JqZWN0cyBjb250YWluZWQgaW4ge0Bjb2RlIGNvbGxlY3Rpb259CisgICAgICogdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IChvcHRpb25hbCkuIFRoaXMgaW1wbGVtZW50YXRpb24KKyAgICAgKiBpdGVyYXRlcyBvdmVyIHRoZSBnaXZlbiB7QGNvZGUgQ29sbGVjdGlvbn0gYW5kIGNhbGxzIHtAY29kZSBhZGR9IGZvciBlYWNoCisgICAgICogZWxlbWVudC4gSWYgYW55IG9mIHRoZXNlIGNhbGxzIHJldHVybiB7QGNvZGUgdHJ1ZX0sIHRoZW4ge0Bjb2RlIHRydWV9IGlzCisgICAgICogcmV0dXJuZWQgYXMgcmVzdWx0IG9mIHRoaXMgbWV0aG9kIGNhbGwsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLiBJZiB0aGlzCisgICAgICoge0Bjb2RlIENvbGxlY3Rpb259IGRvZXMgbm90IHN1cHBvcnQgYWRkaW5nIGVsZW1lbnRzLCBhbiB7QGNvZGUKKyAgICAgKiBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBwYXNzZWQge0Bjb2RlIENvbGxlY3Rpb259IGlzIGNoYW5nZWQgZHVyaW5nIHRoZSBwcm9jZXNzIG9mIGFkZGluZyBlbGVtZW50cworICAgICAqIHRvIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259LCB0aGUgYmVoYXZpb3IgZGVwZW5kcyBvbiB0aGUgYmVoYXZpb3Igb2YgdGhlIHBhc3NlZAorICAgICAqIHtAY29kZSBDb2xsZWN0aW9ufS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2xsZWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgY29sbGVjdGlvbiBvZiBvYmplY3RzLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IGlzIG1vZGlmaWVkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGFkZGluZyB0byB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIGFuIG9iamVjdCBpcyBpbmFwcHJvcHJpYXRlIGZvciB0aGlzCisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIENvbGxlY3Rpb259LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW4gb2JqZWN0IGNhbm5vdCBiZSBhZGRlZCB0byB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGNvbGxlY3Rpb259IGlzIHtAY29kZSBudWxsfSwgb3IgaWYgaXQgY29udGFpbnMKKyAgICAgKiAgICAgICAgICAgICAgICB7QGNvZGUgbnVsbH0gZWxlbWVudHMgYW5kIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IGRvZXMgbm90IHN1cHBvcnQKKyAgICAgKiAgICAgICAgICAgICAgICBzdWNoIGVsZW1lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGFkZEFsbChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjb2xsZWN0aW9uKSB7CisgICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gZmFsc2U7CisgICAgICAgIEl0ZXJhdG9yPD8gZXh0ZW5kcyBFPiBpdCA9IGNvbGxlY3Rpb24uaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgaWYgKGFkZChpdC5uZXh0KCkpKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIGVsZW1lbnRzIGZyb20gdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0sIGxlYXZpbmcgaXQgZW1wdHkgKG9wdGlvbmFsKS4KKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIGl0ZXJhdGVzIG92ZXIgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gYW5kIGNhbGxzIHRoZSB7QGNvZGUKKyAgICAgKiByZW1vdmV9IG1ldGhvZCBvbiBlYWNoIGVsZW1lbnQuIElmIHRoZSBpdGVyYXRvciBkb2VzIG5vdCBzdXBwb3J0IHJlbW92YWwKKyAgICAgKiBvZiBlbGVtZW50cywgYW4ge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufSBpcyB0aHJvd24uCisgICAgICogPHA+CisgICAgICogQ29uY3JldGUgaW1wbGVtZW50YXRpb25zIHVzdWFsbHkgY2FuIGNsZWFyIGEge0Bjb2RlIENvbGxlY3Rpb259IG1vcmUgZWZmaWNpZW50bHkKKyAgICAgKiBhbmQgc2hvdWxkIHRoZXJlZm9yZSBvdmVyd3JpdGUgdGhpcyBtZXRob2QuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaXQgdGhlIGl0ZXJhdG9yIGRvZXMgbm90IHN1cHBvcnQgcmVtb3ZpbmcgZWxlbWVudHMgZnJvbQorICAgICAqICAgICAgICAgICAgICAgIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259CisgICAgICogQHNlZSAjaXRlcmF0b3IKKyAgICAgKiBAc2VlICNpc0VtcHR5CisgICAgICogQHNlZSAjc2l6ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBJdGVyYXRvcjxFPiBpdCA9IGl0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIGl0Lm5leHQoKTsKKyAgICAgICAgICAgIGl0LnJlbW92ZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgd2hldGhlciB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSBjb250YWlucyB0aGUgc3BlY2lmaWVkIG9iamVjdC4gVGhpcworICAgICAqIGltcGxlbWVudGF0aW9uIGl0ZXJhdGVzIG92ZXIgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gYW5kIHRlc3RzLCB3aGV0aGVyIGFueQorICAgICAqIGVsZW1lbnQgaXMgZXF1YWwgdG8gdGhlIGdpdmVuIG9iamVjdC4gSWYge0Bjb2RlIG9iamVjdCAhPSBudWxsfSB0aGVuCisgICAgICoge0Bjb2RlIG9iamVjdC5lcXVhbHMoZSl9IGlzIGNhbGxlZCBmb3IgZWFjaCBlbGVtZW50IHtAY29kZSBlfSByZXR1cm5lZCBieQorICAgICAqIHRoZSBpdGVyYXRvciB1bnRpbCB0aGUgZWxlbWVudCBpcyBmb3VuZC4gSWYge0Bjb2RlIG9iamVjdCA9PSBudWxsfSB0aGVuCisgICAgICogZWFjaCBlbGVtZW50IHtAY29kZSBlfSByZXR1cm5lZCBieSB0aGUgaXRlcmF0b3IgaXMgY29tcGFyZWQgd2l0aCB0aGUgdGVzdAorICAgICAqIHtAY29kZSBlID09IG51bGx9LgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBzZWFyY2ggZm9yLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIG9iamVjdCBpcyBhbiBlbGVtZW50IG9mIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259LCB7QGNvZGUKKyAgICAgKiAgICAgICAgIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgb2JqZWN0IHRvIGxvb2sgZm9yIGlzbid0IG9mIHRoZSBjb3JyZWN0IHR5cGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgdG8gbG9vayBmb3IgaXMge0Bjb2RlIG51bGx9IGFuZCB0aGlzCisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIENvbGxlY3Rpb259IGRvZXNuJ3Qgc3VwcG9ydCB7QGNvZGUgbnVsbH0gZWxlbWVudHMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBJdGVyYXRvcjxFPiBpdCA9IGl0ZXJhdG9yKCk7CisgICAgICAgIGlmIChvYmplY3QgIT0gbnVsbCkgeworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIGlmIChvYmplY3QuZXF1YWxzKGl0Lm5leHQoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIGlmIChpdC5uZXh0KCkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHdoZXRoZXIgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gY29udGFpbnMgYWxsIG9iamVjdHMgY29udGFpbmVkIGluIHRoZQorICAgICAqIHNwZWNpZmllZCB7QGNvZGUgQ29sbGVjdGlvbn0uIFRoaXMgaW1wbGVtZW50YXRpb24gaXRlcmF0ZXMgb3ZlciB0aGUgc3BlY2lmaWVkCisgICAgICoge0Bjb2RlIENvbGxlY3Rpb259LiBJZiBvbmUgZWxlbWVudCByZXR1cm5lZCBieSB0aGUgaXRlcmF0b3IgaXMgbm90IGNvbnRhaW5lZCBpbgorICAgICAqIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259LCB0aGVuIHtAY29kZSBmYWxzZX0gaXMgcmV0dXJuZWQ7IHtAY29kZSB0cnVlfSBvdGhlcndpc2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cy4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBhbGwgb2JqZWN0cyBpbiB0aGUgc3BlY2lmaWVkIHtAY29kZSBDb2xsZWN0aW9ufSBhcmUKKyAgICAgKiAgICAgICAgIGVsZW1lbnRzIG9mIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG9uZSBvciBtb3JlIGVsZW1lbnRzIG9mIHtAY29kZSBjb2xsZWN0aW9ufSBpc24ndCBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgICAgICBjb3JyZWN0IHR5cGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBjb2xsZWN0aW9ufSBjb250YWlucyBhdCBsZWFzdCBvbmUge0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICAgICAgICAgZWxlbWVudCBhbmQgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gZG9lc24ndCBzdXBwb3J0IHtAY29kZSBudWxsfQorICAgICAqICAgICAgICAgICAgICAgIGVsZW1lbnRzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgY29sbGVjdGlvbn0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQWxsKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbikgeworICAgICAgICBJdGVyYXRvcjw/PiBpdCA9IGNvbGxlY3Rpb24uaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgaWYgKCFjb250YWlucyhpdC5uZXh0KCkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgaWYgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gY29udGFpbnMgbm8gZWxlbWVudHMuIFRoaXMgaW1wbGVtZW50YXRpb24KKyAgICAgKiB0ZXN0cywgd2hldGhlciB7QGNvZGUgc2l6ZX0gcmV0dXJucyAwLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gaGFzIG5vIGVsZW1lbnRzLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICoKKyAgICAgKiBAc2VlICNzaXplCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgcmV0dXJuIHNpemUoKSA9PSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2Yge0BsaW5rIEl0ZXJhdG9yfSB0aGF0IG1heSBiZSB1c2VkIHRvIGFjY2VzcyB0aGUKKyAgICAgKiBvYmplY3RzIGNvbnRhaW5lZCBieSB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufS4gVGhlIG9yZGVyIGluIHdoaWNoIHRoZSBlbGVtZW50cyBhcmUKKyAgICAgKiByZXR1cm5lZCBieSB0aGUge0BsaW5rIEl0ZXJhdG9yfSBpcyBub3QgZGVmaW5lZCB1bmxlc3MgdGhlIGluc3RhbmNlIG9mIHRoZQorICAgICAqIHtAY29kZSBDb2xsZWN0aW9ufSBoYXMgYSBkZWZpbmVkIG9yZGVyLiAgSW4gdGhhdCBjYXNlLCB0aGUgZWxlbWVudHMgYXJlIHJldHVybmVkIGluIHRoYXQgb3JkZXIuCisgICAgICogPHA+CisgICAgICogSW4gdGhpcyBjbGFzcyB0aGlzIG1ldGhvZCBpcyBkZWNsYXJlZCBhYnN0cmFjdCBhbmQgaGFzIHRvIGJlIGltcGxlbWVudGVkCisgICAgICogYnkgY29uY3JldGUge0Bjb2RlIENvbGxlY3Rpb259IGltcGxlbWVudGF0aW9ucy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gaXRlcmF0b3IgZm9yIGFjY2Vzc2luZyB0aGUge0Bjb2RlIENvbGxlY3Rpb259IGNvbnRlbnRzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBJdGVyYXRvcjxFPiBpdGVyYXRvcigpOworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBvbmUgaW5zdGFuY2Ugb2YgdGhlIHNwZWNpZmllZCBvYmplY3QgZnJvbSB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSBpZiBvbmUKKyAgICAgKiBpcyBjb250YWluZWQgKG9wdGlvbmFsKS4gVGhpcyBpbXBsZW1lbnRhdGlvbiBpdGVyYXRlcyBvdmVyIHRoaXMKKyAgICAgKiB7QGNvZGUgQ29sbGVjdGlvbn0gYW5kIHRlc3RzIGZvciBlYWNoIGVsZW1lbnQge0Bjb2RlIGV9IHJldHVybmVkIGJ5IHRoZSBpdGVyYXRvciwKKyAgICAgKiB3aGV0aGVyIHtAY29kZSBlfSBpcyBlcXVhbCB0byB0aGUgZ2l2ZW4gb2JqZWN0LiBJZiB7QGNvZGUgb2JqZWN0ICE9IG51bGx9CisgICAgICogdGhlbiB0aGlzIHRlc3QgaXMgcGVyZm9ybWVkIHVzaW5nIHtAY29kZSBvYmplY3QuZXF1YWxzKGUpfSwgb3RoZXJ3aXNlCisgICAgICogdXNpbmcge0Bjb2RlIG9iamVjdCA9PSBudWxsfS4gSWYgYW4gZWxlbWVudCBlcXVhbCB0byB0aGUgZ2l2ZW4gb2JqZWN0IGlzCisgICAgICogZm91bmQsIHRoZW4gdGhlIHtAY29kZSByZW1vdmV9IG1ldGhvZCBpcyBjYWxsZWQgb24gdGhlIGl0ZXJhdG9yIGFuZAorICAgICAqIHtAY29kZSB0cnVlfSBpcyByZXR1cm5lZCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuIElmIHRoZSBpdGVyYXRvciBkb2VzCisgICAgICogbm90IHN1cHBvcnQgcmVtb3ZpbmcgZWxlbWVudHMsIGFuIHtAY29kZSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0KKyAgICAgKiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIHJlbW92ZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSBpcyBtb2RpZmllZCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiByZW1vdmluZyBmcm9tIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgb2JqZWN0IHBhc3NlZCBpcyBub3Qgb2YgdGhlIGNvcnJlY3QgdHlwZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIG9iamVjdH0gaXMge0Bjb2RlIG51bGx9IGFuZCB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufQorICAgICAqICAgICAgICAgICAgICAgIGRvZXNuJ3Qgc3VwcG9ydCB7QGNvZGUgbnVsbH0gZWxlbWVudHMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgSXRlcmF0b3I8Pz4gaXQgPSBpdGVyYXRvcigpOworICAgICAgICBpZiAob2JqZWN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBpZiAob2JqZWN0LmVxdWFscyhpdC5uZXh0KCkpKSB7CisgICAgICAgICAgICAgICAgICAgIGl0LnJlbW92ZSgpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgaWYgKGl0Lm5leHQoKSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGl0LnJlbW92ZSgpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIG9jY3VycmVuY2VzIGluIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IG9mIGVhY2ggb2JqZWN0IGluIHRoZQorICAgICAqIHNwZWNpZmllZCB7QGNvZGUgQ29sbGVjdGlvbn0gKG9wdGlvbmFsKS4gQWZ0ZXIgdGhpcyBtZXRob2QgcmV0dXJucyBub25lIG9mIHRoZQorICAgICAqIGVsZW1lbnRzIGluIHRoZSBwYXNzZWQge0Bjb2RlIENvbGxlY3Rpb259IGNhbiBiZSBmb3VuZCBpbiB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufQorICAgICAqIGFueW1vcmUuCisgICAgICogPHA+CisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBpdGVyYXRlcyBvdmVyIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IGFuZCB0ZXN0cyBmb3IgZWFjaAorICAgICAqIGVsZW1lbnQge0Bjb2RlIGV9IHJldHVybmVkIGJ5IHRoZSBpdGVyYXRvciwgd2hldGhlciBpdCBpcyBjb250YWluZWQgaW4KKyAgICAgKiB0aGUgc3BlY2lmaWVkIHtAY29kZSBDb2xsZWN0aW9ufS4gSWYgdGhpcyB0ZXN0IGlzIHBvc2l0aXZlLCB0aGVuIHRoZSB7QGNvZGUKKyAgICAgKiByZW1vdmV9IG1ldGhvZCBpcyBjYWxsZWQgb24gdGhlIGl0ZXJhdG9yLiBJZiB0aGUgaXRlcmF0b3IgZG9lcyBub3QKKyAgICAgKiBzdXBwb3J0IHJlbW92aW5nIGVsZW1lbnRzLCBhbiB7QGNvZGUgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259IGlzCisgICAgICogdGhyb3duLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIG9mIG9iamVjdHMgdG8gcmVtb3ZlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IGlzIG1vZGlmaWVkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHJlbW92aW5nIGZyb20gdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG9uZSBvciBtb3JlIGVsZW1lbnRzIG9mIHtAY29kZSBjb2xsZWN0aW9ufSBpc24ndCBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgICAgICBjb3JyZWN0IHR5cGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBjb2xsZWN0aW9ufSBjb250YWlucyBhdCBsZWFzdCBvbmUge0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICAgICAgICAgZWxlbWVudCBhbmQgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gZG9lc24ndCBzdXBwb3J0IHtAY29kZSBudWxsfQorICAgICAqICAgICAgICAgICAgICAgIGVsZW1lbnRzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgY29sbGVjdGlvbn0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZUFsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgYm9vbGVhbiByZXN1bHQgPSBmYWxzZTsKKyAgICAgICAgSXRlcmF0b3I8Pz4gaXQgPSBpdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBpZiAoY29sbGVjdGlvbi5jb250YWlucyhpdC5uZXh0KCkpKSB7CisgICAgICAgICAgICAgICAgaXQucmVtb3ZlKCk7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIG9iamVjdHMgZnJvbSB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSB0aGF0IGFyZSBub3QgYWxzbyBmb3VuZCBpbiB0aGUKKyAgICAgKiB7QGNvZGUgQ29sbGVjdGlvbn0gcGFzc2VkIChvcHRpb25hbCkuIEFmdGVyIHRoaXMgbWV0aG9kIHJldHVybnMgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0KKyAgICAgKiB3aWxsIG9ubHkgY29udGFpbiBlbGVtZW50cyB0aGF0IGFsc28gY2FuIGJlIGZvdW5kIGluIHRoZSB7QGNvZGUgQ29sbGVjdGlvbn0KKyAgICAgKiBwYXNzZWQgdG8gdGhpcyBtZXRob2QuCisgICAgICogPHA+CisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBpdGVyYXRlcyBvdmVyIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IGFuZCB0ZXN0cyBmb3IgZWFjaAorICAgICAqIGVsZW1lbnQge0Bjb2RlIGV9IHJldHVybmVkIGJ5IHRoZSBpdGVyYXRvciwgd2hldGhlciBpdCBpcyBjb250YWluZWQgaW4KKyAgICAgKiB0aGUgc3BlY2lmaWVkIHtAY29kZSBDb2xsZWN0aW9ufS4gSWYgdGhpcyB0ZXN0IGlzIG5lZ2F0aXZlLCB0aGVuIHRoZSB7QGNvZGUKKyAgICAgKiByZW1vdmV9IG1ldGhvZCBpcyBjYWxsZWQgb24gdGhlIGl0ZXJhdG9yLiBJZiB0aGUgaXRlcmF0b3IgZG9lcyBub3QKKyAgICAgKiBzdXBwb3J0IHJlbW92aW5nIGVsZW1lbnRzLCBhbiB7QGNvZGUgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259IGlzCisgICAgICogdGhyb3duLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIG9mIG9iamVjdHMgdG8gcmV0YWluLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IGlzIG1vZGlmaWVkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHJlbW92aW5nIGZyb20gdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG9uZSBvciBtb3JlIGVsZW1lbnRzIG9mIHtAY29kZSBjb2xsZWN0aW9ufQorICAgICAqICAgICAgICAgICAgICAgIGlzbid0IG9mIHRoZSBjb3JyZWN0IHR5cGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBjb2xsZWN0aW9ufSBjb250YWlucyBhdCBsZWFzdCBvbmUKKyAgICAgKiAgICAgICAgICAgICAgICB7QGNvZGUgbnVsbH0gZWxlbWVudCBhbmQgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gZG9lc24ndCBzdXBwb3J0CisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIG51bGx9IGVsZW1lbnRzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgY29sbGVjdGlvbn0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJldGFpbkFsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgYm9vbGVhbiByZXN1bHQgPSBmYWxzZTsKKyAgICAgICAgSXRlcmF0b3I8Pz4gaXQgPSBpdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBpZiAoIWNvbGxlY3Rpb24uY29udGFpbnMoaXQubmV4dCgpKSkgeworICAgICAgICAgICAgICAgIGl0LnJlbW92ZSgpOworICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY291bnQgb2YgaG93IG1hbnkgb2JqZWN0cyB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSBjb250YWlucy4KKyAgICAgKiA8cD4KKyAgICAgKiBJbiB0aGlzIGNsYXNzIHRoaXMgbWV0aG9kIGlzIGRlY2xhcmVkIGFic3RyYWN0IGFuZCBoYXMgdG8gYmUgaW1wbGVtZW50ZWQKKyAgICAgKiBieSBjb25jcmV0ZSB7QGNvZGUgQ29sbGVjdGlvbn0gaW1wbGVtZW50YXRpb25zLgorICAgICAqCisgICAgICogQHJldHVybiBob3cgbWFueSBvYmplY3RzIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IGNvbnRhaW5zLCBvciB7QGNvZGUgSW50ZWdlci5NQVhfVkFMVUV9CisgICAgICogICAgICAgICBpZiB0aGVyZSBhcmUgbW9yZSB0aGFuIHtAY29kZSBJbnRlZ2VyLk1BWF9WQUxVRX0gZWxlbWVudHMgaW4gdGhpcworICAgICAqICAgICAgICAge0Bjb2RlIENvbGxlY3Rpb259LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgc2l6ZSgpOworCisgICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSB7CisgICAgICAgIGludCBzaXplID0gc2l6ZSgpLCBpbmRleCA9IDA7CisgICAgICAgIEl0ZXJhdG9yPD8+IGl0ID0gaXRlcmF0b3IoKTsKKyAgICAgICAgT2JqZWN0W10gYXJyYXkgPSBuZXcgT2JqZWN0W3NpemVdOworICAgICAgICB3aGlsZSAoaW5kZXggPCBzaXplKSB7CisgICAgICAgICAgICBhcnJheVtpbmRleCsrXSA9IGl0Lm5leHQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYXJyYXk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIDxUPiBUW10gdG9BcnJheShUW10gY29udGVudHMpIHsKKyAgICAgICAgaW50IHNpemUgPSBzaXplKCksIGluZGV4ID0gMDsKKyAgICAgICAgaWYgKHNpemUgPiBjb250ZW50cy5sZW5ndGgpIHsKKyAgICAgICAgICAgIENsYXNzPD8+IGN0ID0gY29udGVudHMuZ2V0Q2xhc3MoKS5nZXRDb21wb25lbnRUeXBlKCk7CisgICAgICAgICAgICBjb250ZW50cyA9IChUW10pIEFycmF5Lm5ld0luc3RhbmNlKGN0LCBzaXplKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKEUgZW50cnkgOiB0aGlzKSB7CisgICAgICAgICAgICBjb250ZW50c1tpbmRleCsrXSA9IChUKSBlbnRyeTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5kZXggPCBjb250ZW50cy5sZW5ndGgpIHsKKyAgICAgICAgICAgIGNvbnRlbnRzW2luZGV4XSA9IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvbnRlbnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufS4gVGhlIHByZXNlbnRhdGlvbgorICAgICAqIGhhcyBhIHNwZWNpZmljIGZvcm1hdC4gSXQgaXMgZW5jbG9zZWQgYnkgc3F1YXJlIGJyYWNrZXRzICgiW10iKS4gRWxlbWVudHMKKyAgICAgKiBhcmUgc2VwYXJhdGVkIGJ5ICcsICcgKGNvbW1hIGFuZCBzcGFjZSkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgaWYgKGlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuICJbXSI7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWlsZGVyKHNpemUoKSAqIDE2KTsKKyAgICAgICAgYnVmZmVyLmFwcGVuZCgnWycpOworICAgICAgICBJdGVyYXRvcjw/PiBpdCA9IGl0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIE9iamVjdCBuZXh0ID0gaXQubmV4dCgpOworICAgICAgICAgICAgaWYgKG5leHQgIT0gdGhpcykgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQobmV4dCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIih0aGlzIENvbGxlY3Rpb24pIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiLCAiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBidWZmZXIuYXBwZW5kKCddJyk7CisgICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0Fic3RyYWN0TGlzdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9BYnN0cmFjdExpc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYjUyMmMwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9BYnN0cmFjdExpc3QuamF2YQpAQCAtMCwwICsxLDc0MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKKy8qKgorICoge0Bjb2RlIEFic3RyYWN0TGlzdH0gaXMgYW4gYWJzdHJhY3QgaW1wbGVtZW50YXRpb24gb2YgdGhlIHtAY29kZSBMaXN0fSBpbnRlcmZhY2UsIG9wdGltaXplZAorICogZm9yIGEgYmFja2luZyBzdG9yZSB3aGljaCBzdXBwb3J0cyByYW5kb20gYWNjZXNzLiBUaGlzIGltcGxlbWVudGF0aW9uIGRvZXMKKyAqIG5vdCBzdXBwb3J0IGFkZGluZyBvciByZXBsYWNpbmcuIEEgc3ViY2xhc3MgbXVzdCBpbXBsZW1lbnQgdGhlIGFic3RyYWN0CisgKiBtZXRob2RzIHtAY29kZSBnZXQoKX0gYW5kIHtAY29kZSBzaXplKCl9LCBhbmQgdG8gY3JlYXRlIGEKKyAqIG1vZGlmaWFibGUge0Bjb2RlIExpc3R9IGl0J3MgbmVjZXNzYXJ5IHRvIG92ZXJyaWRlIHRoZSB7QGNvZGUgYWRkKCl9IG1ldGhvZCB0aGF0CisgKiBjdXJyZW50bHkgdGhyb3dzIGFuIHtAY29kZSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0uCisgKgorICogQHNpbmNlIDEuMgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RMaXN0PEU+IGV4dGVuZHMgQWJzdHJhY3RDb2xsZWN0aW9uPEU+IGltcGxlbWVudHMgTGlzdDxFPiB7CisKKyAgICAvKioKKyAgICAgKiBBIGNvdW50ZXIgZm9yIGNoYW5nZXMgdG8gdGhlIGxpc3QuCisgICAgICovCisgICAgcHJvdGVjdGVkIHRyYW5zaWVudCBpbnQgbW9kQ291bnQ7CisKKyAgICBwcml2YXRlIGNsYXNzIFNpbXBsZUxpc3RJdGVyYXRvciBpbXBsZW1lbnRzIEl0ZXJhdG9yPEU+IHsKKyAgICAgICAgaW50IHBvcyA9IC0xOworCisgICAgICAgIGludCBleHBlY3RlZE1vZENvdW50OworCisgICAgICAgIGludCBsYXN0UG9zaXRpb24gPSAtMTsKKworICAgICAgICBTaW1wbGVMaXN0SXRlcmF0b3IoKSB7CisgICAgICAgICAgICBleHBlY3RlZE1vZENvdW50ID0gbW9kQ291bnQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgcmV0dXJuIHBvcyArIDEgPCBzaXplKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgRSBuZXh0KCkgeworICAgICAgICAgICAgaWYgKGV4cGVjdGVkTW9kQ291bnQgPT0gbW9kQ291bnQpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBFIHJlc3VsdCA9IGdldChwb3MgKyAxKTsKKyAgICAgICAgICAgICAgICAgICAgbGFzdFBvc2l0aW9uID0gKytwb3M7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgIGlmICh0aGlzLmxhc3RQb3NpdGlvbiA9PSAtMSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGV4cGVjdGVkTW9kQ291bnQgIT0gbW9kQ291bnQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEFic3RyYWN0TGlzdC50aGlzLnJlbW92ZShsYXN0UG9zaXRpb24pOworICAgICAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZXhwZWN0ZWRNb2RDb3VudCA9IG1vZENvdW50OworICAgICAgICAgICAgaWYgKHBvcyA9PSBsYXN0UG9zaXRpb24pIHsKKyAgICAgICAgICAgICAgICBwb3MtLTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGxhc3RQb3NpdGlvbiA9IC0xOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBGdWxsTGlzdEl0ZXJhdG9yIGV4dGVuZHMgU2ltcGxlTGlzdEl0ZXJhdG9yIGltcGxlbWVudHMgTGlzdEl0ZXJhdG9yPEU+IHsKKyAgICAgICAgRnVsbExpc3RJdGVyYXRvcihpbnQgc3RhcnQpIHsKKyAgICAgICAgICAgIGlmIChzdGFydCA+PSAwICYmIHN0YXJ0IDw9IHNpemUoKSkgeworICAgICAgICAgICAgICAgIHBvcyA9IHN0YXJ0IC0gMTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGFkZChFIG9iamVjdCkgeworICAgICAgICAgICAgaWYgKGV4cGVjdGVkTW9kQ291bnQgPT0gbW9kQ291bnQpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBBYnN0cmFjdExpc3QudGhpcy5hZGQocG9zICsgMSwgb2JqZWN0KTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcG9zKys7CisgICAgICAgICAgICAgICAgbGFzdFBvc2l0aW9uID0gLTE7CisgICAgICAgICAgICAgICAgaWYgKG1vZENvdW50ICE9IGV4cGVjdGVkTW9kQ291bnQpIHsKKyAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWRNb2RDb3VudCA9IG1vZENvdW50OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc1ByZXZpb3VzKCkgeworICAgICAgICAgICAgcmV0dXJuIHBvcyA+PSAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBuZXh0SW5kZXgoKSB7CisgICAgICAgICAgICByZXR1cm4gcG9zICsgMTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFIHByZXZpb3VzKCkgeworICAgICAgICAgICAgaWYgKGV4cGVjdGVkTW9kQ291bnQgPT0gbW9kQ291bnQpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBFIHJlc3VsdCA9IGdldChwb3MpOworICAgICAgICAgICAgICAgICAgICBsYXN0UG9zaXRpb24gPSBwb3M7CisgICAgICAgICAgICAgICAgICAgIHBvcy0tOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IHByZXZpb3VzSW5kZXgoKSB7CisgICAgICAgICAgICByZXR1cm4gcG9zOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0KEUgb2JqZWN0KSB7CisgICAgICAgICAgICBpZiAoZXhwZWN0ZWRNb2RDb3VudCA9PSBtb2RDb3VudCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIEFic3RyYWN0TGlzdC50aGlzLnNldChsYXN0UG9zaXRpb24sIG9iamVjdCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTdWJBYnN0cmFjdExpc3RSYW5kb21BY2Nlc3M8RT4gZXh0ZW5kcworICAgICAgICAgICAgU3ViQWJzdHJhY3RMaXN0PEU+IGltcGxlbWVudHMgUmFuZG9tQWNjZXNzIHsKKyAgICAgICAgU3ViQWJzdHJhY3RMaXN0UmFuZG9tQWNjZXNzKEFic3RyYWN0TGlzdDxFPiBsaXN0LCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgICAgIHN1cGVyKGxpc3QsIHN0YXJ0LCBlbmQpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgU3ViQWJzdHJhY3RMaXN0PEU+IGV4dGVuZHMgQWJzdHJhY3RMaXN0PEU+IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBBYnN0cmFjdExpc3Q8RT4gZnVsbExpc3Q7CisKKyAgICAgICAgcHJpdmF0ZSBpbnQgb2Zmc2V0OworCisgICAgICAgIHByaXZhdGUgaW50IHNpemU7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU3ViQWJzdHJhY3RMaXN0SXRlcmF0b3I8RT4gaW1wbGVtZW50cworICAgICAgICAgICAgICAgIExpc3RJdGVyYXRvcjxFPiB7CisgICAgICAgICAgICBwcml2YXRlIGZpbmFsIFN1YkFic3RyYWN0TGlzdDxFPiBzdWJMaXN0OworCisgICAgICAgICAgICBwcml2YXRlIGZpbmFsIExpc3RJdGVyYXRvcjxFPiBpdGVyYXRvcjsKKworICAgICAgICAgICAgcHJpdmF0ZSBpbnQgc3RhcnQ7CisKKyAgICAgICAgICAgIHByaXZhdGUgaW50IGVuZDsKKworICAgICAgICAgICAgU3ViQWJzdHJhY3RMaXN0SXRlcmF0b3IoTGlzdEl0ZXJhdG9yPEU+IGl0LAorICAgICAgICAgICAgICAgICAgICBTdWJBYnN0cmFjdExpc3Q8RT4gbGlzdCwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgICAgICAgICAgICAgIGl0ZXJhdG9yID0gaXQ7CisgICAgICAgICAgICAgICAgc3ViTGlzdCA9IGxpc3Q7CisgICAgICAgICAgICAgICAgc3RhcnQgPSBvZmZzZXQ7CisgICAgICAgICAgICAgICAgZW5kID0gc3RhcnQgKyBsZW5ndGg7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFkZChFIG9iamVjdCkgeworICAgICAgICAgICAgICAgIGl0ZXJhdG9yLmFkZChvYmplY3QpOworICAgICAgICAgICAgICAgIHN1Ykxpc3Quc2l6ZUNoYW5nZWQodHJ1ZSk7CisgICAgICAgICAgICAgICAgZW5kKys7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yLm5leHRJbmRleCgpIDwgZW5kOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcmV2aW91cygpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3IucHJldmlvdXNJbmRleCgpID49IHN0YXJ0OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgRSBuZXh0KCkgeworICAgICAgICAgICAgICAgIGlmIChpdGVyYXRvci5uZXh0SW5kZXgoKSA8IGVuZCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3IubmV4dCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgaW50IG5leHRJbmRleCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3IubmV4dEluZGV4KCkgLSBzdGFydDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIEUgcHJldmlvdXMoKSB7CisgICAgICAgICAgICAgICAgaWYgKGl0ZXJhdG9yLnByZXZpb3VzSW5kZXgoKSA+PSBzdGFydCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3IucHJldmlvdXMoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIGludCBwcmV2aW91c0luZGV4KCkgeworICAgICAgICAgICAgICAgIGludCBwcmV2aW91cyA9IGl0ZXJhdG9yLnByZXZpb3VzSW5kZXgoKTsKKyAgICAgICAgICAgICAgICBpZiAocHJldmlvdXMgPj0gc3RhcnQpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByZXZpb3VzIC0gc3RhcnQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICAgICAgICAgIGl0ZXJhdG9yLnJlbW92ZSgpOworICAgICAgICAgICAgICAgIHN1Ykxpc3Quc2l6ZUNoYW5nZWQoZmFsc2UpOworICAgICAgICAgICAgICAgIGVuZC0tOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBzZXQoRSBvYmplY3QpIHsKKyAgICAgICAgICAgICAgICBpdGVyYXRvci5zZXQob2JqZWN0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFN1YkFic3RyYWN0TGlzdChBYnN0cmFjdExpc3Q8RT4gbGlzdCwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgICAgICBmdWxsTGlzdCA9IGxpc3Q7CisgICAgICAgICAgICBtb2RDb3VudCA9IGZ1bGxMaXN0Lm1vZENvdW50OworICAgICAgICAgICAgb2Zmc2V0ID0gc3RhcnQ7CisgICAgICAgICAgICBzaXplID0gZW5kIC0gc3RhcnQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgYWRkKGludCBsb2NhdGlvbiwgRSBvYmplY3QpIHsKKyAgICAgICAgICAgIGlmIChtb2RDb3VudCA9PSBmdWxsTGlzdC5tb2RDb3VudCkgeworICAgICAgICAgICAgICAgIGlmIChsb2NhdGlvbiA+PSAwICYmIGxvY2F0aW9uIDw9IHNpemUpIHsKKyAgICAgICAgICAgICAgICAgICAgZnVsbExpc3QuYWRkKGxvY2F0aW9uICsgb2Zmc2V0LCBvYmplY3QpOworICAgICAgICAgICAgICAgICAgICBzaXplKys7CisgICAgICAgICAgICAgICAgICAgIG1vZENvdW50ID0gZnVsbExpc3QubW9kQ291bnQ7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gYWRkQWxsKGludCBsb2NhdGlvbiwgQ29sbGVjdGlvbjw/IGV4dGVuZHMgRT4gY29sbGVjdGlvbikgeworICAgICAgICAgICAgaWYgKG1vZENvdW50ID09IGZ1bGxMaXN0Lm1vZENvdW50KSB7CisgICAgICAgICAgICAgICAgaWYgKGxvY2F0aW9uID49IDAgJiYgbG9jYXRpb24gPD0gc2l6ZSkgeworICAgICAgICAgICAgICAgICAgICBib29sZWFuIHJlc3VsdCA9IGZ1bGxMaXN0LmFkZEFsbChsb2NhdGlvbiArIG9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xsZWN0aW9uKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCkgeworICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSArPSBjb2xsZWN0aW9uLnNpemUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1vZENvdW50ID0gZnVsbExpc3QubW9kQ291bnQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gYWRkQWxsKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIGlmIChtb2RDb3VudCA9PSBmdWxsTGlzdC5tb2RDb3VudCkgeworICAgICAgICAgICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gZnVsbExpc3QuYWRkQWxsKG9mZnNldCArIHNpemUsIGNvbGxlY3Rpb24pOworICAgICAgICAgICAgICAgIGlmIChyZXN1bHQpIHsKKyAgICAgICAgICAgICAgICAgICAgc2l6ZSArPSBjb2xsZWN0aW9uLnNpemUoKTsKKyAgICAgICAgICAgICAgICAgICAgbW9kQ291bnQgPSBmdWxsTGlzdC5tb2RDb3VudDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIEUgZ2V0KGludCBsb2NhdGlvbikgeworICAgICAgICAgICAgaWYgKG1vZENvdW50ID09IGZ1bGxMaXN0Lm1vZENvdW50KSB7CisgICAgICAgICAgICAgICAgaWYgKGxvY2F0aW9uID49IDAgJiYgbG9jYXRpb24gPCBzaXplKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmdWxsTGlzdC5nZXQobG9jYXRpb24gKyBvZmZzZXQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgSXRlcmF0b3I8RT4gaXRlcmF0b3IoKSB7CisgICAgICAgICAgICByZXR1cm4gbGlzdEl0ZXJhdG9yKDApOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBMaXN0SXRlcmF0b3I8RT4gbGlzdEl0ZXJhdG9yKGludCBsb2NhdGlvbikgeworICAgICAgICAgICAgaWYgKG1vZENvdW50ID09IGZ1bGxMaXN0Lm1vZENvdW50KSB7CisgICAgICAgICAgICAgICAgaWYgKGxvY2F0aW9uID49IDAgJiYgbG9jYXRpb24gPD0gc2l6ZSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN1YkFic3RyYWN0TGlzdEl0ZXJhdG9yPEU+KGZ1bGxMaXN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmxpc3RJdGVyYXRvcihsb2NhdGlvbiArIG9mZnNldCksIHRoaXMsIG9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIEUgcmVtb3ZlKGludCBsb2NhdGlvbikgeworICAgICAgICAgICAgaWYgKG1vZENvdW50ID09IGZ1bGxMaXN0Lm1vZENvdW50KSB7CisgICAgICAgICAgICAgICAgaWYgKGxvY2F0aW9uID49IDAgJiYgbG9jYXRpb24gPCBzaXplKSB7CisgICAgICAgICAgICAgICAgICAgIEUgcmVzdWx0ID0gZnVsbExpc3QucmVtb3ZlKGxvY2F0aW9uICsgb2Zmc2V0KTsKKyAgICAgICAgICAgICAgICAgICAgc2l6ZS0tOworICAgICAgICAgICAgICAgICAgICBtb2RDb3VudCA9IGZ1bGxMaXN0Lm1vZENvdW50OworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZW1vdmVSYW5nZShpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgICAgIGlmIChzdGFydCAhPSBlbmQpIHsKKyAgICAgICAgICAgICAgICBpZiAobW9kQ291bnQgPT0gZnVsbExpc3QubW9kQ291bnQpIHsKKyAgICAgICAgICAgICAgICAgICAgZnVsbExpc3QucmVtb3ZlUmFuZ2Uoc3RhcnQgKyBvZmZzZXQsIGVuZCArIG9mZnNldCk7CisgICAgICAgICAgICAgICAgICAgIHNpemUgLT0gZW5kIC0gc3RhcnQ7CisgICAgICAgICAgICAgICAgICAgIG1vZENvdW50ID0gZnVsbExpc3QubW9kQ291bnQ7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIEUgc2V0KGludCBsb2NhdGlvbiwgRSBvYmplY3QpIHsKKyAgICAgICAgICAgIGlmIChtb2RDb3VudCA9PSBmdWxsTGlzdC5tb2RDb3VudCkgeworICAgICAgICAgICAgICAgIGlmIChsb2NhdGlvbiA+PSAwICYmIGxvY2F0aW9uIDwgc2l6ZSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnVsbExpc3Quc2V0KGxvY2F0aW9uICsgb2Zmc2V0LCBvYmplY3QpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICBpZiAobW9kQ291bnQgPT0gZnVsbExpc3QubW9kQ291bnQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc2l6ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICB2b2lkIHNpemVDaGFuZ2VkKGJvb2xlYW4gaW5jcmVtZW50KSB7CisgICAgICAgICAgICBpZiAoaW5jcmVtZW50KSB7CisgICAgICAgICAgICAgICAgc2l6ZSsrOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzaXplLS07CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtb2RDb3VudCA9IGZ1bGxMaXN0Lm1vZENvdW50OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIEFic3RyYWN0TGlzdC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQWJzdHJhY3RMaXN0KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBvYmplY3QgaW50byB0aGlzIExpc3QgYXQgdGhlIHNwZWNpZmllZCBsb2NhdGlvbi4KKyAgICAgKiBUaGUgb2JqZWN0IGlzIGluc2VydGVkIGJlZm9yZSBhbnkgcHJldmlvdXMgZWxlbWVudCBhdCB0aGUgc3BlY2lmaWVkCisgICAgICogbG9jYXRpb24uIElmIHRoZSBsb2NhdGlvbiBpcyBlcXVhbCB0byB0aGUgc2l6ZSBvZiB0aGlzIExpc3QsIHRoZSBvYmplY3QKKyAgICAgKiBpcyBhZGRlZCBhdCB0aGUgZW5kLgorICAgICAqIDxwPgorICAgICAqIENvbmNyZXRlIGltcGxlbWVudGF0aW9ucyB0aGF0IHdvdWxkIGxpa2UgdG8gc3VwcG9ydCB0aGUgYWRkIGZ1bmN0aW9uYWxpdHkKKyAgICAgKiBtdXN0IG92ZXJyaWRlIHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2F0aW9uCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggYXQgd2hpY2ggdG8gaW5zZXJ0LgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYWRkLgorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGFkZGluZyB0byB0aGlzIExpc3QgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSBjbGFzcyBvZiB0aGUgb2JqZWN0IGlzIGluYXBwcm9wcmlhdGUgZm9yIHRoaXMKKyAgICAgKiAgICAgICAgICAgICAgICBMaXN0CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgb2JqZWN0IGNhbm5vdCBiZSBhZGRlZCB0byB0aGlzIExpc3QKKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgbG9jYXRpb24gPCAwIHx8ID49IHNpemUoKX0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGQoaW50IGxvY2F0aW9uLCBFIG9iamVjdCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGF0IHRoZSBlbmQgb2YgdGhpcyBMaXN0LgorICAgICAqCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFkZAorICAgICAqIEByZXR1cm4gdHJ1ZQorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGFkZGluZyB0byB0aGlzIExpc3QgaXMgbm90IHN1cHBvcnRlZAorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIHRoZSBvYmplY3QgaXMgaW5hcHByb3ByaWF0ZSBmb3IgdGhpcworICAgICAqICAgICAgICAgICAgICAgIExpc3QKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgY2Fubm90IGJlIGFkZGVkIHRvIHRoaXMgTGlzdAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGFkZChFIG9iamVjdCkgeworICAgICAgICBhZGQoc2l6ZSgpLCBvYmplY3QpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBvYmplY3RzIGluIHRoZSBzcGVjaWZpZWQgQ29sbGVjdGlvbiBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uCisgICAgICogaW4gdGhpcyBMaXN0LiBUaGUgb2JqZWN0cyBhcmUgYWRkZWQgaW4gdGhlIG9yZGVyIHRoZXkgYXJlIHJldHVybmVkIGZyb20KKyAgICAgKiB0aGUgY29sbGVjdGlvbidzIGl0ZXJhdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2F0aW9uCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggYXQgd2hpY2ggdG8gaW5zZXJ0LgorICAgICAqIEBwYXJhbSBjb2xsZWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgQ29sbGVjdGlvbiBvZiBvYmplY3RzCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBMaXN0IGlzIG1vZGlmaWVkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYWRkaW5nIHRvIHRoaXMgbGlzdCBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIGFuIG9iamVjdCBpcyBpbmFwcHJvcHJpYXRlIGZvciB0aGlzIGxpc3QuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBvYmplY3QgY2Fubm90IGJlIGFkZGVkIHRvIHRoaXMgbGlzdC4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbG9jYXRpb24gPCAwIHx8ID4gc2l6ZSgpfQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGFkZEFsbChpbnQgbG9jYXRpb24sIENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgSXRlcmF0b3I8PyBleHRlbmRzIEU+IGl0ID0gY29sbGVjdGlvbi5pdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBhZGQobG9jYXRpb24rKywgaXQubmV4dCgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gIWNvbGxlY3Rpb24uaXNFbXB0eSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIGVsZW1lbnRzIGZyb20gdGhpcyBsaXN0LCBsZWF2aW5nIGl0IGVtcHR5LgorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHJlbW92aW5nIGZyb20gdGhpcyBsaXN0IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICogQHNlZSBMaXN0I2lzRW1wdHkKKyAgICAgKiBAc2VlIExpc3Qjc2l6ZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICByZW1vdmVSYW5nZSgwLCBzaXplKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHRvIHRoaXMgbGlzdCBhbmQgcmV0dXJuIHRydWUgaWYgdGhleSBhcmUKKyAgICAgKiBlcXVhbC4gVHdvIGxpc3RzIGFyZSBlcXVhbCB3aGVuIHRoZXkgYm90aCBjb250YWluIHRoZSBzYW1lIG9iamVjdHMgaW4gdGhlCisgICAgICogc2FtZSBvcmRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB0byB0aGlzIG9iamVjdC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBlcXVhbCB0byB0aGlzIGxpc3QsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNoYXNoQ29kZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmICh0aGlzID09IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIExpc3QpIHsKKyAgICAgICAgICAgIExpc3Q8Pz4gbGlzdCA9IChMaXN0PD8+KSBvYmplY3Q7CisgICAgICAgICAgICBpZiAobGlzdC5zaXplKCkgIT0gc2l6ZSgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBJdGVyYXRvcjw/PiBpdDEgPSBpdGVyYXRvcigpLCBpdDIgPSBsaXN0Lml0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoaXQxLmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIE9iamVjdCBlMSA9IGl0MS5uZXh0KCksIGUyID0gaXQyLm5leHQoKTsKKyAgICAgICAgICAgICAgICBpZiAoIShlMSA9PSBudWxsID8gZTIgPT0gbnVsbCA6IGUxLmVxdWFscyhlMikpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZWxlbWVudCBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uIGluIHRoaXMgbGlzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KKyAgICAgKiBAcmV0dXJuIHRoZSBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGxvY2F0aW9uIDwgMCB8fCA+PSBzaXplKCl9CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEUgZ2V0KGludCBsb2NhdGlvbik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgb2YgdGhpcyBsaXN0LiBUaGUgaGFzaCBjb2RlIGlzIGNhbGN1bGF0ZWQgYnkgdGFraW5nCisgICAgICogZWFjaCBlbGVtZW50J3MgaGFzaGNvZGUgaW50byBhY2NvdW50LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlLgorICAgICAqIEBzZWUgI2VxdWFscworICAgICAqIEBzZWUgTGlzdCNoYXNoQ29kZSgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IHJlc3VsdCA9IDE7CisgICAgICAgIEl0ZXJhdG9yPD8+IGl0ID0gaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgT2JqZWN0IG9iamVjdCA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIHJlc3VsdCA9ICgzMSAqIHJlc3VsdCkgKyAob2JqZWN0ID09IG51bGwgPyAwIDogb2JqZWN0Lmhhc2hDb2RlKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VhcmNoZXMgdGhpcyBsaXN0IGZvciB0aGUgc3BlY2lmaWVkIG9iamVjdCBhbmQgcmV0dXJucyB0aGUgaW5kZXggb2YgdGhlCisgICAgICogZmlyc3Qgb2NjdXJyZW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gc2VhcmNoIGZvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgb2JqZWN0LCBvciAtMSBpZiBpdCB3YXMKKyAgICAgKiAgICAgICAgIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGluZGV4T2YoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBMaXN0SXRlcmF0b3I8Pz4gaXQgPSBsaXN0SXRlcmF0b3IoKTsKKyAgICAgICAgaWYgKG9iamVjdCAhPSBudWxsKSB7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgaWYgKG9iamVjdC5lcXVhbHMoaXQubmV4dCgpKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXQucHJldmlvdXNJbmRleCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoaXQubmV4dCgpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0LnByZXZpb3VzSW5kZXgoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igb24gdGhlIGVsZW1lbnRzIG9mIHRoaXMgbGlzdC4gVGhlIGVsZW1lbnRzIGFyZQorICAgICAqIGl0ZXJhdGVkIGluIHRoZSBzYW1lIG9yZGVyIGFzIHRoZXkgb2NjdXIgaW4gdGhlIGxpc3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGl0ZXJhdG9yIG9uIHRoZSBlbGVtZW50cyBvZiB0aGlzIGxpc3QuCisgICAgICogQHNlZSBJdGVyYXRvcgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJdGVyYXRvcjxFPiBpdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTaW1wbGVMaXN0SXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyB0aGlzIGxpc3QgZm9yIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFuZCByZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUKKyAgICAgKiBsYXN0IG9jY3VycmVuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIHNlYXJjaCBmb3IuCisgICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUgb2JqZWN0LCBvciAtMSBpZiB0aGUKKyAgICAgKiAgICAgICAgIG9iamVjdCB3YXMgbm90IGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgbGFzdEluZGV4T2YoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBMaXN0SXRlcmF0b3I8Pz4gaXQgPSBsaXN0SXRlcmF0b3Ioc2l6ZSgpKTsKKyAgICAgICAgaWYgKG9iamVjdCAhPSBudWxsKSB7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzUHJldmlvdXMoKSkgeworICAgICAgICAgICAgICAgIGlmIChvYmplY3QuZXF1YWxzKGl0LnByZXZpb3VzKCkpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpdC5uZXh0SW5kZXgoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzUHJldmlvdXMoKSkgeworICAgICAgICAgICAgICAgIGlmIChpdC5wcmV2aW91cygpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0Lm5leHRJbmRleCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIExpc3RJdGVyYXRvciBvbiB0aGUgZWxlbWVudHMgb2YgdGhpcyBsaXN0LiBUaGUgZWxlbWVudHMgYXJlCisgICAgICogaXRlcmF0ZWQgaW4gdGhlIHNhbWUgb3JkZXIgdGhhdCB0aGV5IG9jY3VyIGluIHRoZSBsaXN0LgorICAgICAqCisgICAgICogQHJldHVybiBhIExpc3RJdGVyYXRvciBvbiB0aGUgZWxlbWVudHMgb2YgdGhpcyBsaXN0CisgICAgICogQHNlZSBMaXN0SXRlcmF0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdEl0ZXJhdG9yPEU+IGxpc3RJdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIGxpc3RJdGVyYXRvcigwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbGlzdCBpdGVyYXRvciBvbiB0aGUgZWxlbWVudHMgb2YgdGhpcyBsaXN0LiBUaGUgZWxlbWVudHMgYXJlCisgICAgICogaXRlcmF0ZWQgaW4gdGhlIHNhbWUgb3JkZXIgYXMgdGhleSBvY2N1ciBpbiB0aGUgbGlzdC4gVGhlIGl0ZXJhdGlvbgorICAgICAqIHN0YXJ0cyBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2F0aW9uCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggYXQgd2hpY2ggdG8gc3RhcnQgdGhlIGl0ZXJhdGlvbi4KKyAgICAgKiBAcmV0dXJuIGEgTGlzdEl0ZXJhdG9yIG9uIHRoZSBlbGVtZW50cyBvZiB0aGlzIGxpc3QuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGxvY2F0aW9uIDwgMCB8fCBsb2NhdGlvbiA+IHNpemUoKX0KKyAgICAgKiBAc2VlIExpc3RJdGVyYXRvcgorICAgICAqLworICAgIHB1YmxpYyBMaXN0SXRlcmF0b3I8RT4gbGlzdEl0ZXJhdG9yKGludCBsb2NhdGlvbikgeworICAgICAgICByZXR1cm4gbmV3IEZ1bGxMaXN0SXRlcmF0b3IobG9jYXRpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIG9iamVjdCBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uIGZyb20gdGhpcyBsaXN0LgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2F0aW9uCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIG9iamVjdCB0byByZW1vdmUuCisgICAgICogQHJldHVybiB0aGUgcmVtb3ZlZCBvYmplY3QuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHJlbW92aW5nIGZyb20gdGhpcyBsaXN0IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGxvY2F0aW9uIDwgMCB8fCA+PSBzaXplKCl9CisgICAgICovCisgICAgcHVibGljIEUgcmVtb3ZlKGludCBsb2NhdGlvbikgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBvYmplY3RzIGluIHRoZSBzcGVjaWZpZWQgcmFuZ2UgZnJvbSB0aGUgc3RhcnQgdG8gdGhlIGVuZAorICAgICAqIGluZGV4IG1pbnVzIG9uZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGF0IHdoaWNoIHRvIHN0YXJ0IHJlbW92aW5nLgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhZnRlciB0aGUgbGFzdCBlbGVtZW50IHRvIHJlbW92ZS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgcmVtb3ZpbmcgZnJvbSB0aGlzIGxpc3QgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwfSBvciB7QGNvZGUgc3RhcnQgPj0gc2l6ZSgpfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCByZW1vdmVSYW5nZShpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgSXRlcmF0b3I8Pz4gaXQgPSBsaXN0SXRlcmF0b3Ioc3RhcnQpOworICAgICAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykgeworICAgICAgICAgICAgaXQubmV4dCgpOworICAgICAgICAgICAgaXQucmVtb3ZlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyB0aGUgZWxlbWVudCBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uIGluIHRoaXMgbGlzdCB3aXRoIHRoZQorICAgICAqIHNwZWNpZmllZCBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhdCB3aGljaCB0byBwdXQgdGhlIHNwZWNpZmllZCBvYmplY3QuCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBhZGQuCisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgZWxlbWVudCBhdCB0aGUgaW5kZXguCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHJlcGxhY2luZyBlbGVtZW50cyBpbiB0aGlzIGxpc3QgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjbGFzcyBvZiBhbiBvYmplY3QgaXMgaW5hcHByb3ByaWF0ZSBmb3IgdGhpcyBsaXN0LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gb2JqZWN0IGNhbm5vdCBiZSBhZGRlZCB0byB0aGlzIGxpc3QuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGxvY2F0aW9uIDwgMCB8fCA+PSBzaXplKCl9CisgICAgICovCisgICAgcHVibGljIEUgc2V0KGludCBsb2NhdGlvbiwgRSBvYmplY3QpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHBhcnQgb2YgY29uc2VjdXRpdmUgZWxlbWVudHMgb2YgdGhpcyBsaXN0IGFzIGEgdmlldy4gVGhlCisgICAgICogcmV0dXJuZWQgdmlldyB3aWxsIGJlIG9mIHplcm8gbGVuZ3RoIGlmIHN0YXJ0IGVxdWFscyBlbmQuIEFueSBjaGFuZ2UgdGhhdAorICAgICAqIG9jY3VycyBpbiB0aGUgcmV0dXJuZWQgc3ViTGlzdCB3aWxsIGJlIHJlZmxlY3RlZCB0byB0aGUgb3JpZ2luYWwgbGlzdCwKKyAgICAgKiBhbmQgdmljZS12ZXJzYS4gQWxsIHRoZSBzdXBwb3J0ZWQgb3B0aW9uYWwgb3BlcmF0aW9ucyBieSB0aGUgb3JpZ2luYWwKKyAgICAgKiBsaXN0IHdpbGwgYWxzbyBiZSBzdXBwb3J0ZWQgYnkgdGhpcyBzdWJMaXN0LgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIGFzIGEgaGFuZHkgbWV0aG9kIHRvIGRvIHNvbWUgb3BlcmF0aW9ucyBvbiBhIHN1YgorICAgICAqIHJhbmdlIG9mIHRoZSBvcmlnaW5hbCBsaXN0LCBmb3IgZXhhbXBsZQorICAgICAqIHtAY29kZSBsaXN0LnN1Ykxpc3QoZnJvbSwgdG8pLmNsZWFyKCk7fQorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBvcmlnaW5hbCBsaXN0IGlzIG1vZGlmaWVkIGluIG90aGVyIHdheXMgdGhhbiB0aHJvdWdoIHRoZSByZXR1cm5lZAorICAgICAqIHN1Ykxpc3QsIHRoZSBiZWhhdmlvciBvZiB0aGUgcmV0dXJuZWQgc3ViTGlzdCBiZWNvbWVzIHVuZGVmaW5lZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcmV0dXJuZWQgc3ViTGlzdCBpcyBhIHN1YmNsYXNzIG9mIEFic3RyYWN0TGlzdC4gVGhlIHN1YmNsYXNzIHN0b3JlcworICAgICAqIG9mZnNldCwgc2l6ZSBvZiBpdHNlbGYsIGFuZCBtb2RDb3VudCBvZiB0aGUgb3JpZ2luYWwgbGlzdC4gSWYgdGhlCisgICAgICogb3JpZ2luYWwgbGlzdCBpbXBsZW1lbnRzIFJhbmRvbUFjY2VzcyBpbnRlcmZhY2UsIHRoZSByZXR1cm5lZCBzdWJMaXN0CisgICAgICogYWxzbyBpbXBsZW1lbnRzIFJhbmRvbUFjY2VzcyBpbnRlcmZhY2UuCisgICAgICogPHA+CisgICAgICogVGhlIHN1Ykxpc3QncyBzZXQoaW50LCBPYmplY3QpLCBnZXQoaW50KSwgYWRkKGludCwgT2JqZWN0KSwgcmVtb3ZlKGludCksCisgICAgICogYWRkQWxsKGludCwgQ29sbGVjdGlvbikgYW5kIHJlbW92ZVJhbmdlKGludCwgaW50KSBtZXRob2RzIGZpcnN0IGNoZWNrIHRoZQorICAgICAqIGJvdW5kcywgYWRqdXN0IG9mZnNldHMgYW5kIHRoZW4gY2FsbCB0aGUgY29ycmVzcG9uZGluZyBtZXRob2RzIG9mIHRoZQorICAgICAqIG9yaWdpbmFsIEFic3RyYWN0TGlzdC4gYWRkQWxsKENvbGxlY3Rpb24gYykgbWV0aG9kIG9mIHRoZSByZXR1cm5lZAorICAgICAqIHN1Ykxpc3QgY2FsbHMgdGhlIG9yaWdpbmFsIGFkZEFsbChvZmZzZXQgKyBzaXplLCBjKS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbGlzdEl0ZXJhdG9yKGludCkgbWV0aG9kIG9mIHRoZSBzdWJMaXN0IHdyYXBzIHRoZSBvcmlnaW5hbCBsaXN0CisgICAgICogaXRlcmF0b3IuIFRoZSBpdGVyYXRvcigpIG1ldGhvZCBvZiB0aGUgc3ViTGlzdCBpbnZva2VzIHRoZSBvcmlnaW5hbAorICAgICAqIGxpc3RJdGVyYXRvcigpIG1ldGhvZCwgYW5kIHRoZSBzaXplKCkgbWV0aG9kIG1lcmVseSByZXR1cm5zIHRoZSBzaXplIG9mCisgICAgICogdGhlIHN1Ykxpc3QuCisgICAgICogPHA+CisgICAgICogQWxsIG1ldGhvZHMgd2lsbCB0aHJvdyBhIENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24gaWYgdGhlIG1vZENvdW50CisgICAgICogb2YgdGhlIG9yaWdpbmFsIGxpc3QgaXMgbm90IGVxdWFsIHRvIHRoZSBleHBlY3RlZCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgc3RhcnQgaW5kZXggb2YgdGhlIHN1Ykxpc3QgKGluY2x1c2l2ZSkuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgZW5kIGluZGV4IG9mIHRoZSBzdWJMaXN0LCAoZXhjbHVzaXZlKS4KKyAgICAgKiBAcmV0dXJuIGEgc3ViTGlzdCB2aWV3IG9mIHRoaXMgbGlzdCBzdGFydGluZyBmcm9tIHtAY29kZSBzdGFydH0KKyAgICAgKiAgICAgICAgIChpbmNsdXNpdmUpLCBhbmQgZW5kaW5nIHdpdGgge0Bjb2RlIGVuZH0gKGV4Y2x1c2l2ZSkKKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiAoc3RhcnQgPCAwIHx8IGVuZCA+IHNpemUoKSkKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIChzdGFydCA+IGVuZCkKKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxFPiBzdWJMaXN0KGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBpZiAoc3RhcnQgPj0gMCAmJiBlbmQgPD0gc2l6ZSgpKSB7CisgICAgICAgICAgICBpZiAoc3RhcnQgPD0gZW5kKSB7CisgICAgICAgICAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBSYW5kb21BY2Nlc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdWJBYnN0cmFjdExpc3RSYW5kb21BY2Nlc3M8RT4odGhpcywgc3RhcnQsIGVuZCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3ViQWJzdHJhY3RMaXN0PEU+KHRoaXMsIHN0YXJ0LCBlbmQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9BYnN0cmFjdE1hcC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9BYnN0cmFjdE1hcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjZmFlZmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0Fic3RyYWN0TWFwLmphdmEKQEAgLTAsMCArMSw1MDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKKy8qKgorICogQSBiYXNlIGNsYXNzIGZvciB7QGNvZGUgTWFwfSBpbXBsZW1lbnRhdGlvbnMuCisgKgorICogPHA+U3ViY2xhc3NlcyB0aGF0IHBlcm1pdCBuZXcgbWFwcGluZ3MgdG8gYmUgYWRkZWQgbXVzdCBvdmVycmlkZSB7QGxpbmsKKyAqICNwdXR9LgorICoKKyAqIDxwPlRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9ucyBvZiBtYW55IG1ldGhvZHMgYXJlIGluZWZmaWNpZW50IGZvciBsYXJnZQorICogbWFwcy4gRm9yIGV4YW1wbGUgaW4gdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24sIGVhY2ggY2FsbCB0byB7QGxpbmsgI2dldH0KKyAqIHBlcmZvcm1zIGEgbGluZWFyIGl0ZXJhdGlvbiBvZiB0aGUgZW50cnkgc2V0LiBTdWJjbGFzc2VzIHNob3VsZCBvdmVycmlkZSBzdWNoCisgKiBtZXRob2RzIHRvIGltcHJvdmUgdGhlaXIgcGVyZm9ybWFuY2UuCisgKgorICogQHNpbmNlIDEuMgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RNYXA8SywgVj4gaW1wbGVtZW50cyBNYXA8SywgVj4geworCisgICAgLy8gTGF6aWx5IGluaXRpYWxpemVkIGtleSBzZXQuCisgICAgU2V0PEs+IGtleVNldDsKKworICAgIENvbGxlY3Rpb248Vj4gdmFsdWVzQ29sbGVjdGlvbjsKKworICAgIC8qKgorICAgICAqIEFuIGltbXV0YWJsZSBrZXktdmFsdWUgbWFwcGluZy4gRGVzcGl0ZSB0aGUgbmFtZSwgdGhpcyBjbGFzcyBpcyBub24tZmluYWwKKyAgICAgKiBhbmQgaXRzIHN1YmNsYXNzZXMgbWF5IGJlIG11dGFibGUuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBTaW1wbGVJbW11dGFibGVFbnRyeTxLLCBWPgorICAgICAgICAgICAgaW1wbGVtZW50cyBNYXAuRW50cnk8SywgVj4sIFNlcmlhbGl6YWJsZSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDcxMzgzMjkxNDM5NDkwMjUxNTNMOworCisgICAgICAgIHByaXZhdGUgZmluYWwgSyBrZXk7CisgICAgICAgIHByaXZhdGUgZmluYWwgViB2YWx1ZTsKKworICAgICAgICBwdWJsaWMgU2ltcGxlSW1tdXRhYmxlRW50cnkoSyB0aGVLZXksIFYgdGhlVmFsdWUpIHsKKyAgICAgICAgICAgIGtleSA9IHRoZUtleTsKKyAgICAgICAgICAgIHZhbHVlID0gdGhlVmFsdWU7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0cyBhbiBpbnN0YW5jZSB3aXRoIHRoZSBrZXkgYW5kIHZhbHVlIG9mIHtAY29kZSBjb3B5RnJvbX0uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgU2ltcGxlSW1tdXRhYmxlRW50cnkoTWFwLkVudHJ5PD8gZXh0ZW5kcyBLLCA/IGV4dGVuZHMgVj4gY29weUZyb20pIHsKKyAgICAgICAgICAgIGtleSA9IGNvcHlGcm9tLmdldEtleSgpOworICAgICAgICAgICAgdmFsdWUgPSBjb3B5RnJvbS5nZXRWYWx1ZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEsgZ2V0S2V5KCkgeworICAgICAgICAgICAgcmV0dXJuIGtleTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBWIGdldFZhbHVlKCkgeworICAgICAgICAgICAgcmV0dXJuIHZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoaXMgYmFzZSBpbXBsZW1lbnRhdGlvbiB0aHJvd3Mge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufQorICAgICAgICAgKiBhbHdheXMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgViBzZXRWYWx1ZShWIG9iamVjdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIGlmICh0aGlzID09IG9iamVjdCkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIE1hcC5FbnRyeSkgeworICAgICAgICAgICAgICAgIE1hcC5FbnRyeTw/LCA/PiBlbnRyeSA9IChNYXAuRW50cnk8PywgPz4pIG9iamVjdDsKKyAgICAgICAgICAgICAgICByZXR1cm4gKGtleSA9PSBudWxsID8gZW50cnkuZ2V0S2V5KCkgPT0gbnVsbCA6IGtleS5lcXVhbHMoZW50cnkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRLZXkoKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAmJiAodmFsdWUgPT0gbnVsbCA/IGVudHJ5LmdldFZhbHVlKCkgPT0gbnVsbCA6IHZhbHVlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoZW50cnkuZ2V0VmFsdWUoKSkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICByZXR1cm4gKGtleSA9PSBudWxsID8gMCA6IGtleS5oYXNoQ29kZSgpKQorICAgICAgICAgICAgICAgICAgICBeICh2YWx1ZSA9PSBudWxsID8gMCA6IHZhbHVlLmhhc2hDb2RlKCkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICByZXR1cm4ga2V5ICsgIj0iICsgdmFsdWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBIGtleS12YWx1ZSBtYXBwaW5nIHdpdGggbXV0YWJsZSB2YWx1ZXMuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBTaW1wbGVFbnRyeTxLLCBWPgorICAgICAgICAgICAgaW1wbGVtZW50cyBNYXAuRW50cnk8SywgVj4sIFNlcmlhbGl6YWJsZSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04NDk5NzIxMTQ5MDYxMTAzNTg1TDsKKworICAgICAgICBwcml2YXRlIGZpbmFsIEsga2V5OworICAgICAgICBwcml2YXRlIFYgdmFsdWU7CisKKyAgICAgICAgcHVibGljIFNpbXBsZUVudHJ5KEsgdGhlS2V5LCBWIHRoZVZhbHVlKSB7CisgICAgICAgICAgICBrZXkgPSB0aGVLZXk7CisgICAgICAgICAgICB2YWx1ZSA9IHRoZVZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbnN0cnVjdHMgYW4gaW5zdGFuY2Ugd2l0aCB0aGUga2V5IGFuZCB2YWx1ZSBvZiB7QGNvZGUgY29weUZyb219LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFNpbXBsZUVudHJ5KE1hcC5FbnRyeTw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+IGNvcHlGcm9tKSB7CisgICAgICAgICAgICBrZXkgPSBjb3B5RnJvbS5nZXRLZXkoKTsKKyAgICAgICAgICAgIHZhbHVlID0gY29weUZyb20uZ2V0VmFsdWUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBLIGdldEtleSgpIHsKKyAgICAgICAgICAgIHJldHVybiBrZXk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgViBnZXRWYWx1ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBWIHNldFZhbHVlKFYgb2JqZWN0KSB7CisgICAgICAgICAgICBWIHJlc3VsdCA9IHZhbHVlOworICAgICAgICAgICAgdmFsdWUgPSBvYmplY3Q7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICBpZiAodGhpcyA9PSBvYmplY3QpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBNYXAuRW50cnkpIHsKKyAgICAgICAgICAgICAgICBNYXAuRW50cnk8PywgPz4gZW50cnkgPSAoTWFwLkVudHJ5PD8sID8+KSBvYmplY3Q7CisgICAgICAgICAgICAgICAgcmV0dXJuIChrZXkgPT0gbnVsbCA/IGVudHJ5LmdldEtleSgpID09IG51bGwgOiBrZXkuZXF1YWxzKGVudHJ5CisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0S2V5KCkpKQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgKHZhbHVlID09IG51bGwgPyBlbnRyeS5nZXRWYWx1ZSgpID09IG51bGwgOiB2YWx1ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKGVudHJ5LmdldFZhbHVlKCkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgcmV0dXJuIChrZXkgPT0gbnVsbCA/IDAgOiBrZXkuaGFzaENvZGUoKSkKKyAgICAgICAgICAgICAgICAgICAgXiAodmFsdWUgPT0gbnVsbCA/IDAgOiB2YWx1ZS5oYXNoQ29kZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuIGtleSArICI9IiArIHZhbHVlOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIEFic3RyYWN0TWFwKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGVudHJ5U2V0KCkuY2xlYXIoKX0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgIGVudHJ5U2V0KCkuY2xlYXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiA8cD5UaGlzIGltcGxlbWVudGF0aW9uIGl0ZXJhdGVzIGl0cyBrZXkgc2V0LCBsb29raW5nIGZvciBhIGtleSB0aGF0CisgICAgICoge0Bjb2RlIGtleX0gZXF1YWxzLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrZXkpIHsKKyAgICAgICAgSXRlcmF0b3I8TWFwLkVudHJ5PEssIFY+PiBpdCA9IGVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgICAgaWYgKGtleSAhPSBudWxsKSB7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgaWYgKGtleS5lcXVhbHMoaXQubmV4dCgpLmdldEtleSgpKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgaWYgKGl0Lm5leHQoKS5nZXRLZXkoKSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogPHA+VGhpcyBpbXBsZW1lbnRhdGlvbiBpdGVyYXRlcyBpdHMgZW50cnkgc2V0LCBsb29raW5nIGZvciBhbiBlbnRyeSB3aXRoCisgICAgICogYSB2YWx1ZSB0aGF0IHtAY29kZSB2YWx1ZX0gZXF1YWxzLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVmFsdWUoT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIEl0ZXJhdG9yPE1hcC5FbnRyeTxLLCBWPj4gaXQgPSBlbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmVxdWFscyhpdC5uZXh0KCkuZ2V0VmFsdWUoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIGlmIChpdC5uZXh0KCkuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGFic3RyYWN0IFNldDxNYXAuRW50cnk8SywgVj4+IGVudHJ5U2V0KCk7CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiA8cD5UaGlzIGltcGxlbWVudGF0aW9uIGZpcnN0IGNoZWNrcyB0aGUgc3RydWN0dXJlIG9mIHtAY29kZSBvYmplY3R9LiBJZgorICAgICAqIGl0IGlzIG5vdCBhIG1hcCBvciBvZiBhIGRpZmZlcmVudCBzaXplLCB0aGlzIHJldHVybnMgZmFsc2UuIE90aGVyd2lzZSBpdAorICAgICAqIGl0ZXJhdGVzIGl0cyBvd24gZW50cnkgc2V0LCBsb29raW5nIHVwIGVhY2ggZW50cnkncyBrZXkgaW4ge0Bjb2RlCisgICAgICogb2JqZWN0fS4gSWYgYW55IHZhbHVlIGRvZXMgbm90IGVxdWFsIHRoZSBvdGhlciBtYXAncyB2YWx1ZSBmb3IgdGhlIHNhbWUKKyAgICAgKiBrZXksIHRoaXMgcmV0dXJucyBmYWxzZS4gT3RoZXJ3aXNlIGl0IHJldHVybnMgdHJ1ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgaWYgKHRoaXMgPT0gb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgTWFwKSB7CisgICAgICAgICAgICBNYXA8PywgPz4gbWFwID0gKE1hcDw/LCA/Pikgb2JqZWN0OworICAgICAgICAgICAgaWYgKHNpemUoKSAhPSBtYXAuc2l6ZSgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZvciAoRW50cnk8SywgVj4gZW50cnkgOiBlbnRyeVNldCgpKSB7CisgICAgICAgICAgICAgICAgICAgIEsga2V5ID0gZW50cnkuZ2V0S2V5KCk7CisgICAgICAgICAgICAgICAgICAgIFYgbWluZSA9IGVudHJ5LmdldFZhbHVlKCk7CisgICAgICAgICAgICAgICAgICAgIE9iamVjdCB0aGVpcnMgPSBtYXAuZ2V0KGtleSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChtaW5lID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGVpcnMgIT0gbnVsbCB8fCAhbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIW1pbmUuZXF1YWxzKHRoZWlycykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiA8cD5UaGlzIGltcGxlbWVudGF0aW9uIGl0ZXJhdGVzIGl0cyBlbnRyeSBzZXQsIGxvb2tpbmcgZm9yIGFuIGVudHJ5IHdpdGgKKyAgICAgKiBhIGtleSB0aGF0IHtAY29kZSBrZXl9IGVxdWFscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgViBnZXQoT2JqZWN0IGtleSkgeworICAgICAgICBJdGVyYXRvcjxNYXAuRW50cnk8SywgVj4+IGl0ID0gZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICBpZiAoa2V5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBNYXAuRW50cnk8SywgVj4gZW50cnkgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgaWYgKGtleS5lcXVhbHMoZW50cnkuZ2V0S2V5KCkpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbnRyeS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBNYXAuRW50cnk8SywgVj4gZW50cnkgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgaWYgKGVudHJ5LmdldEtleSgpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVudHJ5LmdldFZhbHVlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gaXRlcmF0ZXMgaXRzIGVudHJ5IHNldCwgc3VtbWluZyB0aGUgaGFzaGNvZGVzIG9mCisgICAgICogaXRzIGVudHJpZXMuCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGludCByZXN1bHQgPSAwOworICAgICAgICBJdGVyYXRvcjxNYXAuRW50cnk8SywgVj4+IGl0ID0gZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICByZXN1bHQgKz0gaXQubmV4dCgpLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiA8cD5UaGlzIGltcGxlbWVudGF0aW9uIGNvbXBhcmVzIHtAY29kZSBzaXplKCl9IHRvIDAuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgcmV0dXJuIHNpemUoKSA9PSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyBhIHZpZXcgdGhhdCBjYWxscyB0aHJvdWdoIHRoaXMgdG8gbWFwLiBJdHMKKyAgICAgKiBpdGVyYXRvciB0cmFuc2Zvcm1zIHRoaXMgbWFwJ3MgZW50cnkgc2V0IGl0ZXJhdG9yIHRvIHJldHVybiBrZXlzLgorICAgICAqLworICAgIHB1YmxpYyBTZXQ8Sz4ga2V5U2V0KCkgeworICAgICAgICBpZiAoa2V5U2V0ID09IG51bGwpIHsKKyAgICAgICAgICAgIGtleVNldCA9IG5ldyBBYnN0cmFjdFNldDxLPigpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udGFpbnNLZXkob2JqZWN0KTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gQWJzdHJhY3RNYXAudGhpcy5zaXplKCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBJdGVyYXRvcjxLPiBpdGVyYXRvcigpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcjxLPigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIEl0ZXJhdG9yPE1hcC5FbnRyeTxLLCBWPj4gc2V0SXRlcmF0b3IgPSBlbnRyeVNldCgpLml0ZXJhdG9yKCk7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNldEl0ZXJhdG9yLmhhc05leHQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIEsgbmV4dCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2V0SXRlcmF0b3IubmV4dCgpLmdldEtleSgpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0SXRlcmF0b3IucmVtb3ZlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4ga2V5U2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIDxwPlRoaXMgYmFzZSBpbXBsZW1lbnRhdGlvbiB0aHJvd3Mge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgViBwdXQoSyBrZXksIFYgdmFsdWUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogPHA+VGhpcyBpbXBsZW1lbnRhdGlvbiBpdGVyYXRlcyB0aHJvdWdoIHtAY29kZSBtYXB9J3MgZW50cnkgc2V0LCBjYWxsaW5nCisgICAgICoge0Bjb2RlIHB1dCgpfSBmb3IgZWFjaC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXRBbGwoTWFwPD8gZXh0ZW5kcyBLLCA/IGV4dGVuZHMgVj4gbWFwKSB7CisgICAgICAgIGZvciAoTWFwLkVudHJ5PD8gZXh0ZW5kcyBLLCA/IGV4dGVuZHMgVj4gZW50cnkgOiBtYXAuZW50cnlTZXQoKSkgeworICAgICAgICAgICAgcHV0KGVudHJ5LmdldEtleSgpLCBlbnRyeS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gaXRlcmF0ZXMgaXRzIGVudHJ5IHNldCwgcmVtb3ZpbmcgdGhlIGVudHJ5IHdpdGgKKyAgICAgKiBhIGtleSB0aGF0IHtAY29kZSBrZXl9IGVxdWFscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgViByZW1vdmUoT2JqZWN0IGtleSkgeworICAgICAgICBJdGVyYXRvcjxNYXAuRW50cnk8SywgVj4+IGl0ID0gZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICBpZiAoa2V5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBNYXAuRW50cnk8SywgVj4gZW50cnkgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgaWYgKGtleS5lcXVhbHMoZW50cnkuZ2V0S2V5KCkpKSB7CisgICAgICAgICAgICAgICAgICAgIGl0LnJlbW92ZSgpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgTWFwLkVudHJ5PEssIFY+IGVudHJ5ID0gaXQubmV4dCgpOworICAgICAgICAgICAgICAgIGlmIChlbnRyeS5nZXRLZXkoKSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGl0LnJlbW92ZSgpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogPHA+VGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIGl0cyBlbnRyeSBzZXQncyBzaXplLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIGVudHJ5U2V0KCkuc2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gY29tcG9zZXMgYSBzdHJpbmcgYnkgaXRlcmF0aW5nIGl0cyBlbnRyeSBzZXQuIElmCisgICAgICogdGhpcyBtYXAgY29udGFpbnMgaXRzZWxmIGFzIGEga2V5IG9yIGEgdmFsdWUsIHRoZSBzdHJpbmcgIih0aGlzIE1hcCkiCisgICAgICogd2lsbCBhcHBlYXIgaW4gaXRzIHBsYWNlLgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBpZiAoaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gInt9IjsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1aWxkZXIoc2l6ZSgpICogMjgpOworICAgICAgICBidWZmZXIuYXBwZW5kKCd7Jyk7CisgICAgICAgIEl0ZXJhdG9yPE1hcC5FbnRyeTxLLCBWPj4gaXQgPSBlbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIE1hcC5FbnRyeTxLLCBWPiBlbnRyeSA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIE9iamVjdCBrZXkgPSBlbnRyeS5nZXRLZXkoKTsKKyAgICAgICAgICAgIGlmIChrZXkgIT0gdGhpcykgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoa2V5KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiKHRoaXMgTWFwKSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnPScpOworICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgIGlmICh2YWx1ZSAhPSB0aGlzKSB7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCh2YWx1ZSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIih0aGlzIE1hcCkiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCIsICIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGJ1ZmZlci5hcHBlbmQoJ30nKTsKKyAgICAgICAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyBhIHZpZXcgdGhhdCBjYWxscyB0aHJvdWdoIHRoaXMgdG8gbWFwLiBJdHMKKyAgICAgKiBpdGVyYXRvciB0cmFuc2Zvcm1zIHRoaXMgbWFwJ3MgZW50cnkgc2V0IGl0ZXJhdG9yIHRvIHJldHVybiB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIENvbGxlY3Rpb248Vj4gdmFsdWVzKCkgeworICAgICAgICBpZiAodmFsdWVzQ29sbGVjdGlvbiA9PSBudWxsKSB7CisgICAgICAgICAgICB2YWx1ZXNDb2xsZWN0aW9uID0gbmV3IEFic3RyYWN0Q29sbGVjdGlvbjxWPigpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gQWJzdHJhY3RNYXAudGhpcy5zaXplKCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRhaW5zVmFsdWUob2JqZWN0KTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEl0ZXJhdG9yPFY+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yPFY+KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgSXRlcmF0b3I8TWFwLkVudHJ5PEssIFY+PiBzZXRJdGVyYXRvciA9IGVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2V0SXRlcmF0b3IuaGFzTmV4dCgpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgViBuZXh0KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzZXRJdGVyYXRvci5uZXh0KCkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldEl0ZXJhdG9yLnJlbW92ZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHZhbHVlc0NvbGxlY3Rpb247CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICBBYnN0cmFjdE1hcDxLLCBWPiByZXN1bHQgPSAoQWJzdHJhY3RNYXA8SywgVj4pIHN1cGVyLmNsb25lKCk7CisgICAgICAgIHJlc3VsdC5rZXlTZXQgPSBudWxsOworICAgICAgICByZXN1bHQudmFsdWVzQ29sbGVjdGlvbiA9IG51bGw7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9BYnN0cmFjdFF1ZXVlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0Fic3RyYWN0UXVldWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMzY4YWM5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9BYnN0cmFjdFF1ZXVlLmphdmEKQEAgLTAsMCArMSwxNjMgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKKy8vIEJFR0lOIGFuZHJvaWQtbm90ZQorLy8gcmVtb3ZlZCBsaW5rIHRvIGNvbGxlY3Rpb25zIGZyYW1ld29yayBkb2NzCisvLyBFTkQgYW5kcm9pZC1ub3RlCisKKy8qKgorICogVGhpcyBjbGFzcyBwcm92aWRlcyBza2VsZXRhbCBpbXBsZW1lbnRhdGlvbnMgb2Ygc29tZSB7QGxpbmsgUXVldWV9CisgKiBvcGVyYXRpb25zLiBUaGUgaW1wbGVtZW50YXRpb25zIGluIHRoaXMgY2xhc3MgYXJlIGFwcHJvcHJpYXRlIHdoZW4KKyAqIHRoZSBiYXNlIGltcGxlbWVudGF0aW9uIGRvZXMgPGVtPm5vdDwvZW0+IGFsbG93IDx0dD5udWxsPC90dD4KKyAqIGVsZW1lbnRzLiAgTWV0aG9kcyB7QGxpbmsgI2FkZCBhZGR9LCB7QGxpbmsgI3JlbW92ZSByZW1vdmV9LCBhbmQKKyAqIHtAbGluayAjZWxlbWVudCBlbGVtZW50fSBhcmUgYmFzZWQgb24ge0BsaW5rICNvZmZlciBvZmZlcn0sIHtAbGluaworICogI3BvbGwgcG9sbH0sIGFuZCB7QGxpbmsgI3BlZWsgcGVla30sIHJlc3BlY3RpdmVseSwgYnV0IHRocm93CisgKiBleGNlcHRpb25zIGluc3RlYWQgb2YgaW5kaWNhdGluZyBmYWlsdXJlIHZpYSA8dHQ+ZmFsc2U8L3R0PiBvcgorICogPHR0Pm51bGw8L3R0PiByZXR1cm5zLgorICoKKyAqIDxwPkEgPHR0PlF1ZXVlPC90dD4gaW1wbGVtZW50YXRpb24gdGhhdCBleHRlbmRzIHRoaXMgY2xhc3MgbXVzdAorICogbWluaW1hbGx5IGRlZmluZSBhIG1ldGhvZCB7QGxpbmsgUXVldWUjb2ZmZXJ9IHdoaWNoIGRvZXMgbm90IHBlcm1pdAorICogaW5zZXJ0aW9uIG9mIDx0dD5udWxsPC90dD4gZWxlbWVudHMsIGFsb25nIHdpdGggbWV0aG9kcyB7QGxpbmsKKyAqIFF1ZXVlI3BlZWt9LCB7QGxpbmsgUXVldWUjcG9sbH0sIHtAbGluayBDb2xsZWN0aW9uI3NpemV9LCBhbmQKKyAqIHtAbGluayBDb2xsZWN0aW9uI2l0ZXJhdG9yfS4gIFR5cGljYWxseSwgYWRkaXRpb25hbCBtZXRob2RzIHdpbGwgYmUKKyAqIG92ZXJyaWRkZW4gYXMgd2VsbC4gIElmIHRoZXNlIHJlcXVpcmVtZW50cyBjYW5ub3QgYmUgbWV0LCBjb25zaWRlcgorICogaW5zdGVhZCBzdWJjbGFzc2luZyB7QGxpbmsgQWJzdHJhY3RDb2xsZWN0aW9ufS4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKiBAcGFyYW0gPEU+IHRoZSB0eXBlIG9mIGVsZW1lbnRzIGhlbGQgaW4gdGhpcyBjb2xsZWN0aW9uCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdFF1ZXVlPEU+CisgICAgZXh0ZW5kcyBBYnN0cmFjdENvbGxlY3Rpb248RT4KKyAgICBpbXBsZW1lbnRzIFF1ZXVlPEU+IHsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIGZvciB1c2UgYnkgc3ViY2xhc3Nlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQWJzdHJhY3RRdWV1ZSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpbnRvIHRoaXMgcXVldWUgaWYgaXQgaXMgcG9zc2libGUgdG8gZG8gc28KKyAgICAgKiBpbW1lZGlhdGVseSB3aXRob3V0IHZpb2xhdGluZyBjYXBhY2l0eSByZXN0cmljdGlvbnMsIHJldHVybmluZworICAgICAqIDx0dD50cnVlPC90dD4gdXBvbiBzdWNjZXNzIGFuZCB0aHJvd2luZyBhbiA8dHQ+SWxsZWdhbFN0YXRlRXhjZXB0aW9uPC90dD4KKyAgICAgKiBpZiBubyBzcGFjZSBpcyBjdXJyZW50bHkgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogPHA+VGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIDx0dD50cnVlPC90dD4gaWYgPHR0Pm9mZmVyPC90dD4gc3VjY2VlZHMsCisgICAgICogZWxzZSB0aHJvd3MgYW4gPHR0PklsbGVnYWxTdGF0ZUV4Y2VwdGlvbjwvdHQ+LgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IChhcyBzcGVjaWZpZWQgYnkge0BsaW5rIENvbGxlY3Rpb24jYWRkfSkKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgZWxlbWVudCBjYW5ub3QgYmUgYWRkZWQgYXQgdGhpcworICAgICAqICAgICAgICAgdGltZSBkdWUgdG8gY2FwYWNpdHkgcmVzdHJpY3Rpb25zCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqICAgICAgICAgcHJldmVudHMgaXQgZnJvbSBiZWluZyBhZGRlZCB0byB0aGlzIHF1ZXVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbCBhbmQKKyAgICAgKiAgICAgICAgIHRoaXMgcXVldWUgZG9lcyBub3QgcGVybWl0IG51bGwgZWxlbWVudHMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBzb21lIHByb3BlcnR5IG9mIHRoaXMgZWxlbWVudAorICAgICAqICAgICAgICAgcHJldmVudHMgaXQgZnJvbSBiZWluZyBhZGRlZCB0byB0aGlzIHF1ZXVlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYWRkKEUgZSkgeworICAgICAgICBpZiAob2ZmZXIoZSkpCisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiUXVldWUgZnVsbCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhbmQgcmVtb3ZlcyB0aGUgaGVhZCBvZiB0aGlzIHF1ZXVlLiAgVGhpcyBtZXRob2QgZGlmZmVycworICAgICAqIGZyb20ge0BsaW5rICNwb2xsIHBvbGx9IG9ubHkgaW4gdGhhdCBpdCB0aHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoaXMKKyAgICAgKiBxdWV1ZSBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyB0aGUgcmVzdWx0IG9mIDx0dD5wb2xsPC90dD4KKyAgICAgKiB1bmxlc3MgdGhlIHF1ZXVlIGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGlzIHF1ZXVlCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGlmIHRoaXMgcXVldWUgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgRSByZW1vdmUoKSB7CisgICAgICAgIEUgeCA9IHBvbGwoKTsKKyAgICAgICAgaWYgKHggIT0gbnVsbCkKKyAgICAgICAgICAgIHJldHVybiB4OworICAgICAgICBlbHNlCisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcywgYnV0IGRvZXMgbm90IHJlbW92ZSwgdGhlIGhlYWQgb2YgdGhpcyBxdWV1ZS4gIFRoaXMgbWV0aG9kCisgICAgICogZGlmZmVycyBmcm9tIHtAbGluayAjcGVlayBwZWVrfSBvbmx5IGluIHRoYXQgaXQgdGhyb3dzIGFuIGV4Y2VwdGlvbiBpZgorICAgICAqIHRoaXMgcXVldWUgaXMgZW1wdHkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMgdGhlIHJlc3VsdCBvZiA8dHQ+cGVlazwvdHQ+CisgICAgICogdW5sZXNzIHRoZSBxdWV1ZSBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhlYWQgb2YgdGhpcyBxdWV1ZQorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBpZiB0aGlzIHF1ZXVlIGlzIGVtcHR5CisgICAgICovCisgICAgcHVibGljIEUgZWxlbWVudCgpIHsKKyAgICAgICAgRSB4ID0gcGVlaygpOworICAgICAgICBpZiAoeCAhPSBudWxsKQorICAgICAgICAgICAgcmV0dXJuIHg7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhbGwgb2YgdGhlIGVsZW1lbnRzIGZyb20gdGhpcyBxdWV1ZS4KKyAgICAgKiBUaGUgcXVldWUgd2lsbCBiZSBlbXB0eSBhZnRlciB0aGlzIGNhbGwgcmV0dXJucy4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gcmVwZWF0ZWRseSBpbnZva2VzIHtAbGluayAjcG9sbCBwb2xsfSB1bnRpbCBpdAorICAgICAqIHJldHVybnMgPHR0Pm51bGw8L3R0Pi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgd2hpbGUgKHBvbGwoKSAhPSBudWxsKQorICAgICAgICAgICAgOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYWxsIG9mIHRoZSBlbGVtZW50cyBpbiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gdG8gdGhpcworICAgICAqIHF1ZXVlLiAgQXR0ZW1wdHMgdG8gYWRkQWxsIG9mIGEgcXVldWUgdG8gaXRzZWxmIHJlc3VsdCBpbgorICAgICAqIDx0dD5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L3R0Pi4gRnVydGhlciwgdGhlIGJlaGF2aW9yIG9mCisgICAgICogdGhpcyBvcGVyYXRpb24gaXMgdW5kZWZpbmVkIGlmIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiBpcworICAgICAqIG1vZGlmaWVkIHdoaWxlIHRoZSBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGltcGxlbWVudGF0aW9uIGl0ZXJhdGVzIG92ZXIgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uLAorICAgICAqIGFuZCBhZGRzIGVhY2ggZWxlbWVudCByZXR1cm5lZCBieSB0aGUgaXRlcmF0b3IgdG8gdGhpcworICAgICAqIHF1ZXVlLCBpbiB0dXJuLiAgQSBydW50aW1lIGV4Y2VwdGlvbiBlbmNvdW50ZXJlZCB3aGlsZQorICAgICAqIHRyeWluZyB0byBhZGQgYW4gZWxlbWVudCAoaW5jbHVkaW5nLCBpbiBwYXJ0aWN1bGFyLCBhCisgICAgICogPHR0Pm51bGw8L3R0PiBlbGVtZW50KSBtYXkgcmVzdWx0IGluIG9ubHkgc29tZSBvZiB0aGUgZWxlbWVudHMKKyAgICAgKiBoYXZpbmcgYmVlbiBzdWNjZXNzZnVsbHkgYWRkZWQgd2hlbiB0aGUgYXNzb2NpYXRlZCBleGNlcHRpb24gaXMKKyAgICAgKiB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYyBjb2xsZWN0aW9uIGNvbnRhaW5pbmcgZWxlbWVudHMgdG8gYmUgYWRkZWQgdG8gdGhpcyBxdWV1ZQorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGlzIHF1ZXVlIGNoYW5nZWQgYXMgYSByZXN1bHQgb2YgdGhlIGNhbGwKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3Mgb2YgYW4gZWxlbWVudCBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBjb2xsZWN0aW9uIHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBxdWV1ZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGNvbnRhaW5zIGEKKyAgICAgKiAgICAgICAgIG51bGwgZWxlbWVudCBhbmQgdGhpcyBxdWV1ZSBkb2VzIG5vdCBwZXJtaXQgbnVsbCBlbGVtZW50cywKKyAgICAgKiAgICAgICAgIG9yIGlmIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc29tZSBwcm9wZXJ0eSBvZiBhbiBlbGVtZW50IG9mIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIGNvbGxlY3Rpb24gcHJldmVudHMgaXQgZnJvbSBiZWluZyBhZGRlZCB0byB0aGlzCisgICAgICogICAgICAgICBxdWV1ZSwgb3IgaWYgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGlzIHRoaXMgcXVldWUKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiBub3QgYWxsIHRoZSBlbGVtZW50cyBjYW4gYmUgYWRkZWQgYXQKKyAgICAgKiAgICAgICAgIHRoaXMgdGltZSBkdWUgdG8gaW5zZXJ0aW9uIHJlc3RyaWN0aW9ucworICAgICAqIEBzZWUgI2FkZChPYmplY3QpCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYWRkQWxsKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGMpIHsKKyAgICAgICAgaWYgKGMgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBpZiAoYyA9PSB0aGlzKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICBib29sZWFuIG1vZGlmaWVkID0gZmFsc2U7CisgICAgICAgIGZvciAoRSBlIDogYykKKyAgICAgICAgICAgIGlmIChhZGQoZSkpCisgICAgICAgICAgICAgICAgbW9kaWZpZWQgPSB0cnVlOworICAgICAgICByZXR1cm4gbW9kaWZpZWQ7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0Fic3RyYWN0U2VxdWVudGlhbExpc3QuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvQWJzdHJhY3RTZXF1ZW50aWFsTGlzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMzODZhNWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0Fic3RyYWN0U2VxdWVudGlhbExpc3QuamF2YQpAQCAtMCwwICsxLDkwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworLyoqCisgKiBBYnN0cmFjdFNlcXVlbnRpYWxMaXN0IGlzIGFuIGFic3RyYWN0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBMaXN0IGludGVyZmFjZS4KKyAqIFRoaXMgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBhZGRpbmcuIEEgc3ViY2xhc3MgbXVzdCBpbXBsZW1lbnQgdGhlCisgKiBhYnN0cmFjdCBtZXRob2QgbGlzdEl0ZXJhdG9yKCkuCisgKgorICogQHNpbmNlIDEuMgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdDxFPiBleHRlbmRzIEFic3RyYWN0TGlzdDxFPiB7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdCgpIHsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhZGQoaW50IGxvY2F0aW9uLCBFIG9iamVjdCkgeworICAgICAgICBsaXN0SXRlcmF0b3IobG9jYXRpb24pLmFkZChvYmplY3QpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGFkZEFsbChpbnQgbG9jYXRpb24sIENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgTGlzdEl0ZXJhdG9yPEU+IGl0ID0gbGlzdEl0ZXJhdG9yKGxvY2F0aW9uKTsKKyAgICAgICAgSXRlcmF0b3I8PyBleHRlbmRzIEU+IGNvbEl0ID0gY29sbGVjdGlvbi5pdGVyYXRvcigpOworICAgICAgICBpbnQgbmV4dCA9IGl0Lm5leHRJbmRleCgpOworICAgICAgICB3aGlsZSAoY29sSXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBpdC5hZGQoY29sSXQubmV4dCgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV4dCAhPSBpdC5uZXh0SW5kZXgoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRSBnZXQoaW50IGxvY2F0aW9uKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gbGlzdEl0ZXJhdG9yKGxvY2F0aW9uKS5uZXh0KCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJdGVyYXRvcjxFPiBpdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIGxpc3RJdGVyYXRvcigwKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYWJzdHJhY3QgTGlzdEl0ZXJhdG9yPEU+IGxpc3RJdGVyYXRvcihpbnQgbG9jYXRpb24pOworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEUgcmVtb3ZlKGludCBsb2NhdGlvbikgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgTGlzdEl0ZXJhdG9yPEU+IGl0ID0gbGlzdEl0ZXJhdG9yKGxvY2F0aW9uKTsKKyAgICAgICAgICAgIEUgcmVzdWx0ID0gaXQubmV4dCgpOworICAgICAgICAgICAgaXQucmVtb3ZlKCk7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRSBzZXQoaW50IGxvY2F0aW9uLCBFIG9iamVjdCkgeworICAgICAgICBMaXN0SXRlcmF0b3I8RT4gaXQgPSBsaXN0SXRlcmF0b3IobG9jYXRpb24pOworICAgICAgICBpZiAoIWl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBFIHJlc3VsdCA9IGl0Lm5leHQoKTsKKyAgICAgICAgaXQuc2V0KG9iamVjdCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9BYnN0cmFjdFNldC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9BYnN0cmFjdFNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEyNDgwZWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0Fic3RyYWN0U2V0LmphdmEKQEAgLTAsMCArMSwxMTUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisvKioKKyAqIEFuIEFic3RyYWN0U2V0IGlzIGFuIGFic3RyYWN0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZXQgaW50ZXJmYWNlLiBUaGlzCisgKiBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IGFkZGluZy4gQSBzdWJjbGFzcyBtdXN0IGltcGxlbWVudCB0aGUKKyAqIGFic3RyYWN0IG1ldGhvZHMgaXRlcmF0b3IoKSBhbmQgc2l6ZSgpLgorICoKKyAqIEBzaW5jZSAxLjIKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0U2V0PEU+IGV4dGVuZHMgQWJzdHJhY3RDb2xsZWN0aW9uPEU+IGltcGxlbWVudHMKKyAgICAgICAgU2V0PEU+IHsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBBYnN0cmFjdFNldC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQWJzdHJhY3RTZXQoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBvYmplY3QgdG8gdGhpcyBTZXQgYW5kIHJldHVybnMgdHJ1ZSBpZiB0aGV5IGFyZQorICAgICAqIGVxdWFsLiBUaGUgb2JqZWN0IG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgU2V0IGFuZCBjb250YWluIHRoZSBzYW1lCisgICAgICogb2JqZWN0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB3aXRoIHRoaXMgc2V0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMgc2V0LAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKiBAc2VlICNoYXNoQ29kZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmICh0aGlzID09IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIFNldCkgeworICAgICAgICAgICAgU2V0PD8+IHMgPSAoU2V0PD8+KSBvYmplY3Q7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHNpemUoKSA9PSBzLnNpemUoKSAmJiBjb250YWluc0FsbChzKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaGFzaCBjb2RlIGZvciB0aGlzIHNldC4gVHdvIHNldCB3aGljaCBhcmUgZXF1YWwgbXVzdCByZXR1cm4KKyAgICAgKiB0aGUgc2FtZSB2YWx1ZS4gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxjdWxhdGVzIHRoZSBoYXNoIGNvZGUgYnkgYWRkaW5nCisgICAgICogZWFjaCBlbGVtZW50J3MgaGFzaCBjb2RlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIG9mIHRoaXMgc2V0LgorICAgICAqIEBzZWUgI2VxdWFscworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGludCByZXN1bHQgPSAwOworICAgICAgICBJdGVyYXRvcjw/PiBpdCA9IGl0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIE9iamVjdCBuZXh0ID0gaXQubmV4dCgpOworICAgICAgICAgICAgcmVzdWx0ICs9IG5leHQgPT0gbnVsbCA/IDAgOiBuZXh0Lmhhc2hDb2RlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGFsbCBvY2N1cnJlbmNlcyBpbiB0aGlzIGNvbGxlY3Rpb24gd2hpY2ggYXJlIGNvbnRhaW5lZCBpbiB0aGUKKyAgICAgKiBzcGVjaWZpZWQgY29sbGVjdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2xsZWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgY29sbGVjdGlvbiBvZiBvYmplY3RzIHRvIHJlbW92ZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGNvbGxlY3Rpb24gd2FzIG1vZGlmaWVkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHJlbW92aW5nIGZyb20gdGhpcyBjb2xsZWN0aW9uIGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlQWxsKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbikgeworICAgICAgICBib29sZWFuIHJlc3VsdCA9IGZhbHNlOworICAgICAgICBpZiAoc2l6ZSgpIDw9IGNvbGxlY3Rpb24uc2l6ZSgpKSB7CisgICAgICAgICAgICBJdGVyYXRvcjw/PiBpdCA9IGl0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgaWYgKGNvbGxlY3Rpb24uY29udGFpbnMoaXQubmV4dCgpKSkgeworICAgICAgICAgICAgICAgICAgICBpdC5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBJdGVyYXRvcjw/PiBpdCA9IGNvbGxlY3Rpb24uaXRlcmF0b3IoKTsKKyAgICAgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSByZW1vdmUoaXQubmV4dCgpKSB8fCByZXN1bHQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0FycmF5RGVxdWUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvQXJyYXlEZXF1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhZmNkYjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0FycmF5RGVxdWUuamF2YQpAQCAtMCwwICsxLDgzOCBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgSm9zaCBCbG9jaCBvZiBHb29nbGUgSW5jLiBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sCisgKiBhcyBleHBsYWluZWQgYXQgaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisvLyBCRUdJTiBhbmRyb2lkLW5vdGUKKy8vIHJlbW92ZWQgbGluayB0byBjb2xsZWN0aW9ucyBmcmFtZXdvcmsgZG9jcworLy8gRU5EIGFuZHJvaWQtbm90ZQorCitpbXBvcnQgamF2YS5pby4qOworCisvKioKKyAqIFJlc2l6YWJsZS1hcnJheSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUge0BsaW5rIERlcXVlfSBpbnRlcmZhY2UuICBBcnJheQorICogZGVxdWVzIGhhdmUgbm8gY2FwYWNpdHkgcmVzdHJpY3Rpb25zOyB0aGV5IGdyb3cgYXMgbmVjZXNzYXJ5IHRvIHN1cHBvcnQKKyAqIHVzYWdlLiAgVGhleSBhcmUgbm90IHRocmVhZC1zYWZlOyBpbiB0aGUgYWJzZW5jZSBvZiBleHRlcm5hbAorICogc3luY2hyb25pemF0aW9uLCB0aGV5IGRvIG5vdCBzdXBwb3J0IGNvbmN1cnJlbnQgYWNjZXNzIGJ5IG11bHRpcGxlIHRocmVhZHMuCisgKiBOdWxsIGVsZW1lbnRzIGFyZSBwcm9oaWJpdGVkLiAgVGhpcyBjbGFzcyBpcyBsaWtlbHkgdG8gYmUgZmFzdGVyIHRoYW4KKyAqIHtAbGluayBTdGFja30gd2hlbiB1c2VkIGFzIGEgc3RhY2ssIGFuZCBmYXN0ZXIgdGhhbiB7QGxpbmsgTGlua2VkTGlzdH0KKyAqIHdoZW4gdXNlZCBhcyBhIHF1ZXVlLgorICoKKyAqIDxwPk1vc3QgPHR0PkFycmF5RGVxdWU8L3R0PiBvcGVyYXRpb25zIHJ1biBpbiBhbW9ydGl6ZWQgY29uc3RhbnQgdGltZS4KKyAqIEV4Y2VwdGlvbnMgaW5jbHVkZSB7QGxpbmsgI3JlbW92ZShPYmplY3QpIHJlbW92ZX0sIHtAbGluaworICogI3JlbW92ZUZpcnN0T2NjdXJyZW5jZSByZW1vdmVGaXJzdE9jY3VycmVuY2V9LCB7QGxpbmsgI3JlbW92ZUxhc3RPY2N1cnJlbmNlCisgKiByZW1vdmVMYXN0T2NjdXJyZW5jZX0sIHtAbGluayAjY29udGFpbnMgY29udGFpbnN9LCB7QGxpbmsgI2l0ZXJhdG9yCisgKiBpdGVyYXRvci5yZW1vdmUoKX0sIGFuZCB0aGUgYnVsayBvcGVyYXRpb25zLCBhbGwgb2Ygd2hpY2ggcnVuIGluIGxpbmVhcgorICogdGltZS4KKyAqCisgKiA8cD5UaGUgaXRlcmF0b3JzIHJldHVybmVkIGJ5IHRoaXMgY2xhc3MncyA8dHQ+aXRlcmF0b3I8L3R0PiBtZXRob2QgYXJlCisgKiA8aT5mYWlsLWZhc3Q8L2k+OiBJZiB0aGUgZGVxdWUgaXMgbW9kaWZpZWQgYXQgYW55IHRpbWUgYWZ0ZXIgdGhlIGl0ZXJhdG9yCisgKiBpcyBjcmVhdGVkLCBpbiBhbnkgd2F5IGV4Y2VwdCB0aHJvdWdoIHRoZSBpdGVyYXRvcidzIG93biA8dHQ+cmVtb3ZlPC90dD4KKyAqIG1ldGhvZCwgdGhlIGl0ZXJhdG9yIHdpbGwgZ2VuZXJhbGx5IHRocm93IGEge0BsaW5rCisgKiBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9ufS4gIFRodXMsIGluIHRoZSBmYWNlIG9mIGNvbmN1cnJlbnQKKyAqIG1vZGlmaWNhdGlvbiwgdGhlIGl0ZXJhdG9yIGZhaWxzIHF1aWNrbHkgYW5kIGNsZWFubHksIHJhdGhlciB0aGFuIHJpc2tpbmcKKyAqIGFyYml0cmFyeSwgbm9uLWRldGVybWluaXN0aWMgYmVoYXZpb3IgYXQgYW4gdW5kZXRlcm1pbmVkIHRpbWUgaW4gdGhlCisgKiBmdXR1cmUuCisgKgorICogPHA+Tm90ZSB0aGF0IHRoZSBmYWlsLWZhc3QgYmVoYXZpb3Igb2YgYW4gaXRlcmF0b3IgY2Fubm90IGJlIGd1YXJhbnRlZWQKKyAqIGFzIGl0IGlzLCBnZW5lcmFsbHkgc3BlYWtpbmcsIGltcG9zc2libGUgdG8gbWFrZSBhbnkgaGFyZCBndWFyYW50ZWVzIGluIHRoZQorICogcHJlc2VuY2Ugb2YgdW5zeW5jaHJvbml6ZWQgY29uY3VycmVudCBtb2RpZmljYXRpb24uICBGYWlsLWZhc3QgaXRlcmF0b3JzCisgKiB0aHJvdyA8dHQ+Q29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbjwvdHQ+IG9uIGEgYmVzdC1lZmZvcnQgYmFzaXMuCisgKiBUaGVyZWZvcmUsIGl0IHdvdWxkIGJlIHdyb25nIHRvIHdyaXRlIGEgcHJvZ3JhbSB0aGF0IGRlcGVuZGVkIG9uIHRoaXMKKyAqIGV4Y2VwdGlvbiBmb3IgaXRzIGNvcnJlY3RuZXNzOiA8aT50aGUgZmFpbC1mYXN0IGJlaGF2aW9yIG9mIGl0ZXJhdG9ycworICogc2hvdWxkIGJlIHVzZWQgb25seSB0byBkZXRlY3QgYnVncy48L2k+CisgKgorICogPHA+VGhpcyBjbGFzcyBhbmQgaXRzIGl0ZXJhdG9yIGltcGxlbWVudCBhbGwgb2YgdGhlCisgKiA8ZW0+b3B0aW9uYWw8L2VtPiBtZXRob2RzIG9mIHRoZSB7QGxpbmsgQ29sbGVjdGlvbn0gYW5kIHtAbGluaworICogSXRlcmF0b3J9IGludGVyZmFjZXMuCisgKgorICogQGF1dGhvciAgSm9zaCBCbG9jaCBhbmQgRG91ZyBMZWEKKyAqIEBzaW5jZSAgIDEuNgorICogQHBhcmFtIDxFPiB0aGUgdHlwZSBvZiBlbGVtZW50cyBoZWxkIGluIHRoaXMgY29sbGVjdGlvbgorICovCitwdWJsaWMgY2xhc3MgQXJyYXlEZXF1ZTxFPiBleHRlbmRzIEFic3RyYWN0Q29sbGVjdGlvbjxFPgorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wbGVtZW50cyBEZXF1ZTxFPiwgQ2xvbmVhYmxlLCBTZXJpYWxpemFibGUKK3sKKyAgICAvKioKKyAgICAgKiBUaGUgYXJyYXkgaW4gd2hpY2ggdGhlIGVsZW1lbnRzIG9mIHRoZSBkZXF1ZSBhcmUgc3RvcmVkLgorICAgICAqIFRoZSBjYXBhY2l0eSBvZiB0aGUgZGVxdWUgaXMgdGhlIGxlbmd0aCBvZiB0aGlzIGFycmF5LCB3aGljaCBpcworICAgICAqIGFsd2F5cyBhIHBvd2VyIG9mIHR3by4gVGhlIGFycmF5IGlzIG5ldmVyIGFsbG93ZWQgdG8gYmVjb21lCisgICAgICogZnVsbCwgZXhjZXB0IHRyYW5zaWVudGx5IHdpdGhpbiBhbiBhZGRYIG1ldGhvZCB3aGVyZSBpdCBpcworICAgICAqIHJlc2l6ZWQgKHNlZSBkb3VibGVDYXBhY2l0eSkgaW1tZWRpYXRlbHkgdXBvbiBiZWNvbWluZyBmdWxsLAorICAgICAqIHRodXMgYXZvaWRpbmcgaGVhZCBhbmQgdGFpbCB3cmFwcGluZyBhcm91bmQgdG8gZXF1YWwgZWFjaAorICAgICAqIG90aGVyLiAgV2UgYWxzbyBndWFyYW50ZWUgdGhhdCBhbGwgYXJyYXkgY2VsbHMgbm90IGhvbGRpbmcKKyAgICAgKiBkZXF1ZSBlbGVtZW50cyBhcmUgYWx3YXlzIG51bGwuCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgRVtdIGVsZW1lbnRzOworCisgICAgLyoqCisgICAgICogVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IGF0IHRoZSBoZWFkIG9mIHRoZSBkZXF1ZSAod2hpY2ggaXMgdGhlCisgICAgICogZWxlbWVudCB0aGF0IHdvdWxkIGJlIHJlbW92ZWQgYnkgcmVtb3ZlKCkgb3IgcG9wKCkpOyBvciBhbgorICAgICAqIGFyYml0cmFyeSBudW1iZXIgZXF1YWwgdG8gdGFpbCBpZiB0aGUgZGVxdWUgaXMgZW1wdHkuCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IGhlYWQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW5kZXggYXQgd2hpY2ggdGhlIG5leHQgZWxlbWVudCB3b3VsZCBiZSBhZGRlZCB0byB0aGUgdGFpbAorICAgICAqIG9mIHRoZSBkZXF1ZSAodmlhIGFkZExhc3QoRSksIGFkZChFKSwgb3IgcHVzaChFKSkuCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IHRhaWw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWluaW11bSBjYXBhY2l0eSB0aGF0IHdlJ2xsIHVzZSBmb3IgYSBuZXdseSBjcmVhdGVkIGRlcXVlLgorICAgICAqIE11c3QgYmUgYSBwb3dlciBvZiAyLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNSU5fSU5JVElBTF9DQVBBQ0lUWSA9IDg7CisKKyAgICAvLyAqKioqKiogIEFycmF5IGFsbG9jYXRpb24gYW5kIHJlc2l6aW5nIHV0aWxpdGllcyAqKioqKioKKworICAgIC8qKgorICAgICAqIEFsbG9jYXRlIGVtcHR5IGFycmF5IHRvIGhvbGQgdGhlIGdpdmVuIG51bWJlciBvZiBlbGVtZW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBudW1FbGVtZW50cyAgdGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBob2xkCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGFsbG9jYXRlRWxlbWVudHMoaW50IG51bUVsZW1lbnRzKSB7CisgICAgICAgIGludCBpbml0aWFsQ2FwYWNpdHkgPSBNSU5fSU5JVElBTF9DQVBBQ0lUWTsKKyAgICAgICAgLy8gRmluZCB0aGUgYmVzdCBwb3dlciBvZiB0d28gdG8gaG9sZCBlbGVtZW50cy4KKyAgICAgICAgLy8gVGVzdHMgIjw9IiBiZWNhdXNlIGFycmF5cyBhcmVuJ3Qga2VwdCBmdWxsLgorICAgICAgICBpZiAobnVtRWxlbWVudHMgPj0gaW5pdGlhbENhcGFjaXR5KSB7CisgICAgICAgICAgICBpbml0aWFsQ2FwYWNpdHkgPSBudW1FbGVtZW50czsKKyAgICAgICAgICAgIGluaXRpYWxDYXBhY2l0eSB8PSAoaW5pdGlhbENhcGFjaXR5ID4+PiAgMSk7CisgICAgICAgICAgICBpbml0aWFsQ2FwYWNpdHkgfD0gKGluaXRpYWxDYXBhY2l0eSA+Pj4gIDIpOworICAgICAgICAgICAgaW5pdGlhbENhcGFjaXR5IHw9IChpbml0aWFsQ2FwYWNpdHkgPj4+ICA0KTsKKyAgICAgICAgICAgIGluaXRpYWxDYXBhY2l0eSB8PSAoaW5pdGlhbENhcGFjaXR5ID4+PiAgOCk7CisgICAgICAgICAgICBpbml0aWFsQ2FwYWNpdHkgfD0gKGluaXRpYWxDYXBhY2l0eSA+Pj4gMTYpOworICAgICAgICAgICAgaW5pdGlhbENhcGFjaXR5Kys7CisKKyAgICAgICAgICAgIGlmIChpbml0aWFsQ2FwYWNpdHkgPCAwKSAgIC8vIFRvbyBtYW55IGVsZW1lbnRzLCBtdXN0IGJhY2sgb2ZmCisgICAgICAgICAgICAgICAgaW5pdGlhbENhcGFjaXR5ID4+Pj0gMTsvLyBHb29kIGx1Y2sgYWxsb2NhdGluZyAyIF4gMzAgZWxlbWVudHMKKyAgICAgICAgfQorICAgICAgICBlbGVtZW50cyA9IChFW10pIG5ldyBPYmplY3RbaW5pdGlhbENhcGFjaXR5XTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb3VibGUgdGhlIGNhcGFjaXR5IG9mIHRoaXMgZGVxdWUuICBDYWxsIG9ubHkgd2hlbiBmdWxsLCBpLmUuLAorICAgICAqIHdoZW4gaGVhZCBhbmQgdGFpbCBoYXZlIHdyYXBwZWQgYXJvdW5kIHRvIGJlY29tZSBlcXVhbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZG91YmxlQ2FwYWNpdHkoKSB7CisgICAgICAgIGFzc2VydCBoZWFkID09IHRhaWw7CisgICAgICAgIGludCBwID0gaGVhZDsKKyAgICAgICAgaW50IG4gPSBlbGVtZW50cy5sZW5ndGg7CisgICAgICAgIGludCByID0gbiAtIHA7IC8vIG51bWJlciBvZiBlbGVtZW50cyB0byB0aGUgcmlnaHQgb2YgcAorICAgICAgICBpbnQgbmV3Q2FwYWNpdHkgPSBuIDw8IDE7CisgICAgICAgIGlmIChuZXdDYXBhY2l0eSA8IDApCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJTb3JyeSwgZGVxdWUgdG9vIGJpZyIpOworICAgICAgICBPYmplY3RbXSBhID0gbmV3IE9iamVjdFtuZXdDYXBhY2l0eV07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZWxlbWVudHMsIHAsIGEsIDAsIHIpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVsZW1lbnRzLCAwLCBhLCByLCBwKTsKKyAgICAgICAgZWxlbWVudHMgPSAoRVtdKWE7CisgICAgICAgIGhlYWQgPSAwOworICAgICAgICB0YWlsID0gbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgdGhlIGVsZW1lbnRzIGZyb20gb3VyIGVsZW1lbnQgYXJyYXkgaW50byB0aGUgc3BlY2lmaWVkIGFycmF5LAorICAgICAqIGluIG9yZGVyIChmcm9tIGZpcnN0IHRvIGxhc3QgZWxlbWVudCBpbiB0aGUgZGVxdWUpLiAgSXQgaXMgYXNzdW1lZAorICAgICAqIHRoYXQgdGhlIGFycmF5IGlzIGxhcmdlIGVub3VnaCB0byBob2xkIGFsbCBlbGVtZW50cyBpbiB0aGUgZGVxdWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGl0cyBhcmd1bWVudAorICAgICAqLworICAgIHByaXZhdGUgPFQ+IFRbXSBjb3B5RWxlbWVudHMoVFtdIGEpIHsKKyAgICAgICAgaWYgKGhlYWQgPCB0YWlsKSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVsZW1lbnRzLCBoZWFkLCBhLCAwLCBzaXplKCkpOworICAgICAgICB9IGVsc2UgaWYgKGhlYWQgPiB0YWlsKSB7CisgICAgICAgICAgICBpbnQgaGVhZFBvcnRpb25MZW4gPSBlbGVtZW50cy5sZW5ndGggLSBoZWFkOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShlbGVtZW50cywgaGVhZCwgYSwgMCwgaGVhZFBvcnRpb25MZW4pOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShlbGVtZW50cywgMCwgYSwgaGVhZFBvcnRpb25MZW4sIHRhaWwpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBhOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gZW1wdHkgYXJyYXkgZGVxdWUgd2l0aCBhbiBpbml0aWFsIGNhcGFjaXR5CisgICAgICogc3VmZmljaWVudCB0byBob2xkIDE2IGVsZW1lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBBcnJheURlcXVlKCkgeworICAgICAgICBlbGVtZW50cyA9IChFW10pIG5ldyBPYmplY3RbMTZdOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gZW1wdHkgYXJyYXkgZGVxdWUgd2l0aCBhbiBpbml0aWFsIGNhcGFjaXR5CisgICAgICogc3VmZmljaWVudCB0byBob2xkIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGVsZW1lbnRzLgorICAgICAqCisgICAgICogQHBhcmFtIG51bUVsZW1lbnRzICBsb3dlciBib3VuZCBvbiBpbml0aWFsIGNhcGFjaXR5IG9mIHRoZSBkZXF1ZQorICAgICAqLworICAgIHB1YmxpYyBBcnJheURlcXVlKGludCBudW1FbGVtZW50cykgeworICAgICAgICBhbGxvY2F0ZUVsZW1lbnRzKG51bUVsZW1lbnRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgZGVxdWUgY29udGFpbmluZyB0aGUgZWxlbWVudHMgb2YgdGhlIHNwZWNpZmllZAorICAgICAqIGNvbGxlY3Rpb24sIGluIHRoZSBvcmRlciB0aGV5IGFyZSByZXR1cm5lZCBieSB0aGUgY29sbGVjdGlvbidzCisgICAgICogaXRlcmF0b3IuICAoVGhlIGZpcnN0IGVsZW1lbnQgcmV0dXJuZWQgYnkgdGhlIGNvbGxlY3Rpb24ncworICAgICAqIGl0ZXJhdG9yIGJlY29tZXMgdGhlIGZpcnN0IGVsZW1lbnQsIG9yIDxpPmZyb250PC9pPiBvZiB0aGUKKyAgICAgKiBkZXF1ZS4pCisgICAgICoKKyAgICAgKiBAcGFyYW0gYyB0aGUgY29sbGVjdGlvbiB3aG9zZSBlbGVtZW50cyBhcmUgdG8gYmUgcGxhY2VkIGludG8gdGhlIGRlcXVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBBcnJheURlcXVlKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGMpIHsKKyAgICAgICAgYWxsb2NhdGVFbGVtZW50cyhjLnNpemUoKSk7CisgICAgICAgIGFkZEFsbChjKTsKKyAgICB9CisKKyAgICAvLyBUaGUgbWFpbiBpbnNlcnRpb24gYW5kIGV4dHJhY3Rpb24gbWV0aG9kcyBhcmUgYWRkRmlyc3QsCisgICAgLy8gYWRkTGFzdCwgcG9sbEZpcnN0LCBwb2xsTGFzdC4gVGhlIG90aGVyIG1ldGhvZHMgYXJlIGRlZmluZWQgaW4KKyAgICAvLyB0ZXJtcyBvZiB0aGVzZS4KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGF0IHRoZSBmcm9udCBvZiB0aGlzIGRlcXVlLgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZEZpcnN0KEUgZSkgeworICAgICAgICBpZiAoZSA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGVsZW1lbnRzW2hlYWQgPSAoaGVhZCAtIDEpICYgKGVsZW1lbnRzLmxlbmd0aCAtIDEpXSA9IGU7CisgICAgICAgIGlmIChoZWFkID09IHRhaWwpCisgICAgICAgICAgICBkb3VibGVDYXBhY2l0eSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGF0IHRoZSBlbmQgb2YgdGhpcyBkZXF1ZS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8ge0BsaW5rICNhZGR9LgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZExhc3QoRSBlKSB7CisgICAgICAgIGlmIChlID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgZWxlbWVudHNbdGFpbF0gPSBlOworICAgICAgICBpZiAoICh0YWlsID0gKHRhaWwgKyAxKSAmIChlbGVtZW50cy5sZW5ndGggLSAxKSkgPT0gaGVhZCkKKyAgICAgICAgICAgIGRvdWJsZUNhcGFjaXR5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgYXQgdGhlIGZyb250IG9mIHRoaXMgZGVxdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byBhZGQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gKGFzIHNwZWNpZmllZCBieSB7QGxpbmsgRGVxdWUjb2ZmZXJGaXJzdH0pCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG9mZmVyRmlyc3QoRSBlKSB7CisgICAgICAgIGFkZEZpcnN0KGUpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBhdCB0aGUgZW5kIG9mIHRoaXMgZGVxdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byBhZGQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gKGFzIHNwZWNpZmllZCBieSB7QGxpbmsgRGVxdWUjb2ZmZXJMYXN0fSkKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gb2ZmZXJMYXN0KEUgZSkgeworICAgICAgICBhZGRMYXN0KGUpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBFIHJlbW92ZUZpcnN0KCkgeworICAgICAgICBFIHggPSBwb2xsRmlyc3QoKTsKKyAgICAgICAgaWYgKHggPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiB4OworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIEUgcmVtb3ZlTGFzdCgpIHsKKyAgICAgICAgRSB4ID0gcG9sbExhc3QoKTsKKyAgICAgICAgaWYgKHggPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiB4OworICAgIH0KKworICAgIHB1YmxpYyBFIHBvbGxGaXJzdCgpIHsKKyAgICAgICAgaW50IGggPSBoZWFkOworICAgICAgICBFIHJlc3VsdCA9IGVsZW1lbnRzW2hdOyAvLyBFbGVtZW50IGlzIG51bGwgaWYgZGVxdWUgZW1wdHkKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIGVsZW1lbnRzW2hdID0gbnVsbDsgICAgIC8vIE11c3QgbnVsbCBvdXQgc2xvdAorICAgICAgICBoZWFkID0gKGggKyAxKSAmIChlbGVtZW50cy5sZW5ndGggLSAxKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgRSBwb2xsTGFzdCgpIHsKKyAgICAgICAgaW50IHQgPSAodGFpbCAtIDEpICYgKGVsZW1lbnRzLmxlbmd0aCAtIDEpOworICAgICAgICBFIHJlc3VsdCA9IGVsZW1lbnRzW3RdOworICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgZWxlbWVudHNbdF0gPSBudWxsOworICAgICAgICB0YWlsID0gdDsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBFIGdldEZpcnN0KCkgeworICAgICAgICBFIHggPSBlbGVtZW50c1toZWFkXTsKKyAgICAgICAgaWYgKHggPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiB4OworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIEUgZ2V0TGFzdCgpIHsKKyAgICAgICAgRSB4ID0gZWxlbWVudHNbKHRhaWwgLSAxKSAmIChlbGVtZW50cy5sZW5ndGggLSAxKV07CisgICAgICAgIGlmICh4ID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICByZXR1cm4geDsKKyAgICB9CisKKyAgICBwdWJsaWMgRSBwZWVrRmlyc3QoKSB7CisgICAgICAgIHJldHVybiBlbGVtZW50c1toZWFkXTsgLy8gZWxlbWVudHNbaGVhZF0gaXMgbnVsbCBpZiBkZXF1ZSBlbXB0eQorICAgIH0KKworICAgIHB1YmxpYyBFIHBlZWtMYXN0KCkgeworICAgICAgICByZXR1cm4gZWxlbWVudHNbKHRhaWwgLSAxKSAmIChlbGVtZW50cy5sZW5ndGggLSAxKV07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaW4gdGhpcworICAgICAqIGRlcXVlICh3aGVuIHRyYXZlcnNpbmcgdGhlIGRlcXVlIGZyb20gaGVhZCB0byB0YWlsKS4KKyAgICAgKiBJZiB0aGUgZGVxdWUgZG9lcyBub3QgY29udGFpbiB0aGUgZWxlbWVudCwgaXQgaXMgdW5jaGFuZ2VkLgorICAgICAqIE1vcmUgZm9ybWFsbHksIHJlbW92ZXMgdGhlIGZpcnN0IGVsZW1lbnQgPHR0PmU8L3R0PiBzdWNoIHRoYXQKKyAgICAgKiA8dHQ+by5lcXVhbHMoZSk8L3R0PiAoaWYgc3VjaCBhbiBlbGVtZW50IGV4aXN0cykuCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgZGVxdWUgY29udGFpbmVkIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqIChvciBlcXVpdmFsZW50bHksIGlmIHRoaXMgZGVxdWUgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBlbGVtZW50IHRvIGJlIHJlbW92ZWQgZnJvbSB0aGlzIGRlcXVlLCBpZiBwcmVzZW50CisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoZSBkZXF1ZSBjb250YWluZWQgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlRmlyc3RPY2N1cnJlbmNlKE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvID09IG51bGwpCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGludCBtYXNrID0gZWxlbWVudHMubGVuZ3RoIC0gMTsKKyAgICAgICAgaW50IGkgPSBoZWFkOworICAgICAgICBFIHg7CisgICAgICAgIHdoaWxlICggKHggPSBlbGVtZW50c1tpXSkgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKG8uZXF1YWxzKHgpKSB7CisgICAgICAgICAgICAgICAgZGVsZXRlKGkpOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaSA9IChpICsgMSkgJiBtYXNrOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50IGluIHRoaXMKKyAgICAgKiBkZXF1ZSAod2hlbiB0cmF2ZXJzaW5nIHRoZSBkZXF1ZSBmcm9tIGhlYWQgdG8gdGFpbCkuCisgICAgICogSWYgdGhlIGRlcXVlIGRvZXMgbm90IGNvbnRhaW4gdGhlIGVsZW1lbnQsIGl0IGlzIHVuY2hhbmdlZC4KKyAgICAgKiBNb3JlIGZvcm1hbGx5LCByZW1vdmVzIHRoZSBsYXN0IGVsZW1lbnQgPHR0PmU8L3R0PiBzdWNoIHRoYXQKKyAgICAgKiA8dHQ+by5lcXVhbHMoZSk8L3R0PiAoaWYgc3VjaCBhbiBlbGVtZW50IGV4aXN0cykuCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgZGVxdWUgY29udGFpbmVkIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqIChvciBlcXVpdmFsZW50bHksIGlmIHRoaXMgZGVxdWUgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBlbGVtZW50IHRvIGJlIHJlbW92ZWQgZnJvbSB0aGlzIGRlcXVlLCBpZiBwcmVzZW50CisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoZSBkZXF1ZSBjb250YWluZWQgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlTGFzdE9jY3VycmVuY2UoT2JqZWN0IG8pIHsKKyAgICAgICAgaWYgKG8gPT0gbnVsbCkKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaW50IG1hc2sgPSBlbGVtZW50cy5sZW5ndGggLSAxOworICAgICAgICBpbnQgaSA9ICh0YWlsIC0gMSkgJiBtYXNrOworICAgICAgICBFIHg7CisgICAgICAgIHdoaWxlICggKHggPSBlbGVtZW50c1tpXSkgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKG8uZXF1YWxzKHgpKSB7CisgICAgICAgICAgICAgICAgZGVsZXRlKGkpOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaSA9IChpIC0gMSkgJiBtYXNrOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvLyAqKiogUXVldWUgbWV0aG9kcyAqKioKKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGF0IHRoZSBlbmQgb2YgdGhpcyBkZXF1ZS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8ge0BsaW5rICNhZGRMYXN0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIHRoZSBlbGVtZW50IHRvIGFkZAorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiAoYXMgc3BlY2lmaWVkIGJ5IHtAbGluayBDb2xsZWN0aW9uI2FkZH0pCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGFkZChFIGUpIHsKKyAgICAgICAgYWRkTGFzdChlKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgYXQgdGhlIGVuZCBvZiB0aGlzIGRlcXVlLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byB7QGxpbmsgI29mZmVyTGFzdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byBhZGQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gKGFzIHNwZWNpZmllZCBieSB7QGxpbmsgUXVldWUjb2ZmZXJ9KQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBvZmZlcihFIGUpIHsKKyAgICAgICAgcmV0dXJuIG9mZmVyTGFzdChlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYW5kIHJlbW92ZXMgdGhlIGhlYWQgb2YgdGhlIHF1ZXVlIHJlcHJlc2VudGVkIGJ5IHRoaXMgZGVxdWUuCisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCBkaWZmZXJzIGZyb20ge0BsaW5rICNwb2xsIHBvbGx9IG9ubHkgaW4gdGhhdCBpdCB0aHJvd3MgYW4KKyAgICAgKiBleGNlcHRpb24gaWYgdGhpcyBkZXF1ZSBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8ge0BsaW5rICNyZW1vdmVGaXJzdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWFkIG9mIHRoZSBxdWV1ZSByZXByZXNlbnRlZCBieSB0aGlzIGRlcXVlCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgRSByZW1vdmUoKSB7CisgICAgICAgIHJldHVybiByZW1vdmVGaXJzdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhbmQgcmVtb3ZlcyB0aGUgaGVhZCBvZiB0aGUgcXVldWUgcmVwcmVzZW50ZWQgYnkgdGhpcyBkZXF1ZQorICAgICAqIChpbiBvdGhlciB3b3JkcywgdGhlIGZpcnN0IGVsZW1lbnQgb2YgdGhpcyBkZXF1ZSksIG9yIHJldHVybnMKKyAgICAgKiA8dHQ+bnVsbDwvdHQ+IGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAbGluayAjcG9sbEZpcnN0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhlYWQgb2YgdGhlIHF1ZXVlIHJlcHJlc2VudGVkIGJ5IHRoaXMgZGVxdWUsIG9yCisgICAgICogICAgICAgICA8dHQ+bnVsbDwvdHQ+IGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgRSBwb2xsKCkgeworICAgICAgICByZXR1cm4gcG9sbEZpcnN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzLCBidXQgZG9lcyBub3QgcmVtb3ZlLCB0aGUgaGVhZCBvZiB0aGUgcXVldWUgcmVwcmVzZW50ZWQgYnkKKyAgICAgKiB0aGlzIGRlcXVlLiAgVGhpcyBtZXRob2QgZGlmZmVycyBmcm9tIHtAbGluayAjcGVlayBwZWVrfSBvbmx5IGluCisgICAgICogdGhhdCBpdCB0aHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAbGluayAjZ2V0Rmlyc3R9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGUgcXVldWUgcmVwcmVzZW50ZWQgYnkgdGhpcyBkZXF1ZQorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIEUgZWxlbWVudCgpIHsKKyAgICAgICAgcmV0dXJuIGdldEZpcnN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzLCBidXQgZG9lcyBub3QgcmVtb3ZlLCB0aGUgaGVhZCBvZiB0aGUgcXVldWUgcmVwcmVzZW50ZWQgYnkKKyAgICAgKiB0aGlzIGRlcXVlLCBvciByZXR1cm5zIDx0dD5udWxsPC90dD4gaWYgdGhpcyBkZXF1ZSBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8ge0BsaW5rICNwZWVrRmlyc3R9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGUgcXVldWUgcmVwcmVzZW50ZWQgYnkgdGhpcyBkZXF1ZSwgb3IKKyAgICAgKiAgICAgICAgIDx0dD5udWxsPC90dD4gaWYgdGhpcyBkZXF1ZSBpcyBlbXB0eQorICAgICAqLworICAgIHB1YmxpYyBFIHBlZWsoKSB7CisgICAgICAgIHJldHVybiBwZWVrRmlyc3QoKTsKKyAgICB9CisKKyAgICAvLyAqKiogU3RhY2sgbWV0aG9kcyAqKioKKworICAgIC8qKgorICAgICAqIFB1c2hlcyBhbiBlbGVtZW50IG9udG8gdGhlIHN0YWNrIHJlcHJlc2VudGVkIGJ5IHRoaXMgZGVxdWUuICBJbiBvdGhlcgorICAgICAqIHdvcmRzLCBpbnNlcnRzIHRoZSBlbGVtZW50IGF0IHRoZSBmcm9udCBvZiB0aGlzIGRlcXVlLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byB7QGxpbmsgI2FkZEZpcnN0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIHRoZSBlbGVtZW50IHRvIHB1c2gKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHVzaChFIGUpIHsKKyAgICAgICAgYWRkRmlyc3QoZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUG9wcyBhbiBlbGVtZW50IGZyb20gdGhlIHN0YWNrIHJlcHJlc2VudGVkIGJ5IHRoaXMgZGVxdWUuICBJbiBvdGhlcgorICAgICAqIHdvcmRzLCByZW1vdmVzIGFuZCByZXR1cm5zIHRoZSBmaXJzdCBlbGVtZW50IG9mIHRoaXMgZGVxdWUuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAbGluayAjcmVtb3ZlRmlyc3QoKX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBlbGVtZW50IGF0IHRoZSBmcm9udCBvZiB0aGlzIGRlcXVlICh3aGljaCBpcyB0aGUgdG9wCisgICAgICogICAgICAgICBvZiB0aGUgc3RhY2sgcmVwcmVzZW50ZWQgYnkgdGhpcyBkZXF1ZSkKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBFIHBvcCgpIHsKKyAgICAgICAgcmV0dXJuIHJlbW92ZUZpcnN0KCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrSW52YXJpYW50cygpIHsKKyAgICAgICAgYXNzZXJ0IGVsZW1lbnRzW3RhaWxdID09IG51bGw7CisgICAgICAgIGFzc2VydCBoZWFkID09IHRhaWwgPyBlbGVtZW50c1toZWFkXSA9PSBudWxsIDoKKyAgICAgICAgICAgIChlbGVtZW50c1toZWFkXSAhPSBudWxsICYmCisgICAgICAgICAgICAgZWxlbWVudHNbKHRhaWwgLSAxKSAmIChlbGVtZW50cy5sZW5ndGggLSAxKV0gIT0gbnVsbCk7CisgICAgICAgIGFzc2VydCBlbGVtZW50c1soaGVhZCAtIDEpICYgKGVsZW1lbnRzLmxlbmd0aCAtIDEpXSA9PSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGVsZW1lbnQgYXQgdGhlIHNwZWNpZmllZCBwb3NpdGlvbiBpbiB0aGUgZWxlbWVudHMgYXJyYXksCisgICAgICogYWRqdXN0aW5nIGhlYWQgYW5kIHRhaWwgYXMgbmVjZXNzYXJ5LiAgVGhpcyBjYW4gcmVzdWx0IGluIG1vdGlvbiBvZgorICAgICAqIGVsZW1lbnRzIGJhY2t3YXJkcyBvciBmb3J3YXJkcyBpbiB0aGUgYXJyYXkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBjYWxsZWQgZGVsZXRlIHJhdGhlciB0aGFuIHJlbW92ZSB0byBlbXBoYXNpemUKKyAgICAgKiB0aGF0IGl0cyBzZW1hbnRpY3MgZGlmZmVyIGZyb20gdGhvc2Ugb2Yge0BsaW5rIExpc3QjcmVtb3ZlKGludCl9LgorICAgICAqCisgICAgICogQHJldHVybiB0cnVlIGlmIGVsZW1lbnRzIG1vdmVkIGJhY2t3YXJkcworICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBkZWxldGUoaW50IGkpIHsKKyAgICAgICAgY2hlY2tJbnZhcmlhbnRzKCk7CisgICAgICAgIGZpbmFsIEVbXSBlbGVtZW50cyA9IHRoaXMuZWxlbWVudHM7CisgICAgICAgIGZpbmFsIGludCBtYXNrID0gZWxlbWVudHMubGVuZ3RoIC0gMTsKKyAgICAgICAgZmluYWwgaW50IGggPSBoZWFkOworICAgICAgICBmaW5hbCBpbnQgdCA9IHRhaWw7CisgICAgICAgIGZpbmFsIGludCBmcm9udCA9IChpIC0gaCkgJiBtYXNrOworICAgICAgICBmaW5hbCBpbnQgYmFjayAgPSAodCAtIGkpICYgbWFzazsKKworICAgICAgICAvLyBJbnZhcmlhbnQ6IGhlYWQgPD0gaSA8IHRhaWwgbW9kIGNpcmN1bGFyaXR5CisgICAgICAgIGlmIChmcm9udCA+PSAoKHQgLSBoKSAmIG1hc2spKQorICAgICAgICAgICAgdGhyb3cgbmV3IENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24oKTsKKworICAgICAgICAvLyBPcHRpbWl6ZSBmb3IgbGVhc3QgZWxlbWVudCBtb3Rpb24KKyAgICAgICAgaWYgKGZyb250IDwgYmFjaykgeworICAgICAgICAgICAgaWYgKGggPD0gaSkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZWxlbWVudHMsIGgsIGVsZW1lbnRzLCBoICsgMSwgZnJvbnQpOworICAgICAgICAgICAgfSBlbHNlIHsgLy8gV3JhcCBhcm91bmQKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVsZW1lbnRzLCAwLCBlbGVtZW50cywgMSwgaSk7CisgICAgICAgICAgICAgICAgZWxlbWVudHNbMF0gPSBlbGVtZW50c1ttYXNrXTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVsZW1lbnRzLCBoLCBlbGVtZW50cywgaCArIDEsIG1hc2sgLSBoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsZW1lbnRzW2hdID0gbnVsbDsKKyAgICAgICAgICAgIGhlYWQgPSAoaCArIDEpICYgbWFzazsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChpIDwgdCkgeyAvLyBDb3B5IHRoZSBudWxsIHRhaWwgYXMgd2VsbAorICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZWxlbWVudHMsIGkgKyAxLCBlbGVtZW50cywgaSwgYmFjayk7CisgICAgICAgICAgICAgICAgdGFpbCA9IHQgLSAxOworICAgICAgICAgICAgfSBlbHNlIHsgLy8gV3JhcCBhcm91bmQKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVsZW1lbnRzLCBpICsgMSwgZWxlbWVudHMsIGksIG1hc2sgLSBpKTsKKyAgICAgICAgICAgICAgICBlbGVtZW50c1ttYXNrXSA9IGVsZW1lbnRzWzBdOworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZWxlbWVudHMsIDEsIGVsZW1lbnRzLCAwLCB0KTsKKyAgICAgICAgICAgICAgICB0YWlsID0gKHQgLSAxKSAmIG1hc2s7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vICoqKiBDb2xsZWN0aW9uIE1ldGhvZHMgKioqCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBkZXF1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIGRlcXVlCisgICAgICovCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICByZXR1cm4gKHRhaWwgLSBoZWFkKSAmIChlbGVtZW50cy5sZW5ndGggLSAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIDx0dD50cnVlPC90dD4gaWYgdGhpcyBkZXF1ZSBjb250YWlucyBubyBlbGVtZW50cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGlzIGRlcXVlIGNvbnRhaW5zIG5vIGVsZW1lbnRzCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgcmV0dXJuIGhlYWQgPT0gdGFpbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzIGluIHRoaXMgZGVxdWUuICBUaGUgZWxlbWVudHMKKyAgICAgKiB3aWxsIGJlIG9yZGVyZWQgZnJvbSBmaXJzdCAoaGVhZCkgdG8gbGFzdCAodGFpbCkuICBUaGlzIGlzIHRoZSBzYW1lCisgICAgICogb3JkZXIgdGhhdCBlbGVtZW50cyB3b3VsZCBiZSBkZXF1ZXVlZCAodmlhIHN1Y2Nlc3NpdmUgY2FsbHMgdG8KKyAgICAgKiB7QGxpbmsgI3JlbW92ZX0gb3IgcG9wcGVkICh2aWEgc3VjY2Vzc2l2ZSBjYWxscyB0byB7QGxpbmsgI3BvcH0pLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cyBpbiB0aGlzIGRlcXVlCisgICAgICovCisgICAgcHVibGljIEl0ZXJhdG9yPEU+IGl0ZXJhdG9yKCkgeworICAgICAgICByZXR1cm4gbmV3IERlcUl0ZXJhdG9yKCk7CisgICAgfQorCisgICAgcHVibGljIEl0ZXJhdG9yPEU+IGRlc2NlbmRpbmdJdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBEZXNjZW5kaW5nSXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIERlcUl0ZXJhdG9yIGltcGxlbWVudHMgSXRlcmF0b3I8RT4geworICAgICAgICAvKioKKyAgICAgICAgICogSW5kZXggb2YgZWxlbWVudCB0byBiZSByZXR1cm5lZCBieSBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dC4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgaW50IGN1cnNvciA9IGhlYWQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRhaWwgcmVjb3JkZWQgYXQgY29uc3RydWN0aW9uIChhbHNvIGluIHJlbW92ZSksIHRvIHN0b3AKKyAgICAgICAgICogaXRlcmF0b3IgYW5kIGFsc28gdG8gY2hlY2sgZm9yIGNvbW9kaWZpY2F0aW9uLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBpbnQgZmVuY2UgPSB0YWlsOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbmRleCBvZiBlbGVtZW50IHJldHVybmVkIGJ5IG1vc3QgcmVjZW50IGNhbGwgdG8gbmV4dC4KKyAgICAgICAgICogUmVzZXQgdG8gLTEgaWYgZWxlbWVudCBpcyBkZWxldGVkIGJ5IGEgY2FsbCB0byByZW1vdmUuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGludCBsYXN0UmV0ID0gLTE7CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiBjdXJzb3IgIT0gZmVuY2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgRSBuZXh0KCkgeworICAgICAgICAgICAgaWYgKGN1cnNvciA9PSBmZW5jZSkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgRSByZXN1bHQgPSBlbGVtZW50c1tjdXJzb3JdOworICAgICAgICAgICAgLy8gVGhpcyBjaGVjayBkb2Vzbid0IGNhdGNoIGFsbCBwb3NzaWJsZSBjb21vZGlmaWNhdGlvbnMsCisgICAgICAgICAgICAvLyBidXQgZG9lcyBjYXRjaCB0aGUgb25lcyB0aGF0IGNvcnJ1cHQgdHJhdmVyc2FsCisgICAgICAgICAgICBpZiAodGFpbCAhPSBmZW5jZSB8fCByZXN1bHQgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgbGFzdFJldCA9IGN1cnNvcjsKKyAgICAgICAgICAgIGN1cnNvciA9IChjdXJzb3IgKyAxKSAmIChlbGVtZW50cy5sZW5ndGggLSAxKTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICBpZiAobGFzdFJldCA8IDApCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgaWYgKGRlbGV0ZShsYXN0UmV0KSkgeyAvLyBpZiBsZWZ0LXNoaWZ0ZWQsIHVuZG8gaW5jcmVtZW50IGluIG5leHQoKQorICAgICAgICAgICAgICAgIGN1cnNvciA9IChjdXJzb3IgLSAxKSAmIChlbGVtZW50cy5sZW5ndGggLSAxKTsKKyAgICAgICAgICAgICAgICBmZW5jZSA9IHRhaWw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsYXN0UmV0ID0gLTE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIERlc2NlbmRpbmdJdGVyYXRvciBpbXBsZW1lbnRzIEl0ZXJhdG9yPEU+IHsKKyAgICAgICAgLyoKKyAgICAgICAgICogVGhpcyBjbGFzcyBpcyBuZWFybHkgYSBtaXJyb3ItaW1hZ2Ugb2YgRGVxSXRlcmF0b3IsIHVzaW5nCisgICAgICAgICAqIHRhaWwgaW5zdGVhZCBvZiBoZWFkIGZvciBpbml0aWFsIGN1cnNvciwgYW5kIGhlYWQgaW5zdGVhZCBvZgorICAgICAgICAgKiB0YWlsIGZvciBmZW5jZS4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgaW50IGN1cnNvciA9IHRhaWw7CisgICAgICAgIHByaXZhdGUgaW50IGZlbmNlID0gaGVhZDsKKyAgICAgICAgcHJpdmF0ZSBpbnQgbGFzdFJldCA9IC0xOworCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICByZXR1cm4gY3Vyc29yICE9IGZlbmNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEUgbmV4dCgpIHsKKyAgICAgICAgICAgIGlmIChjdXJzb3IgPT0gZmVuY2UpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGN1cnNvciA9IChjdXJzb3IgLSAxKSAmIChlbGVtZW50cy5sZW5ndGggLSAxKTsKKyAgICAgICAgICAgIEUgcmVzdWx0ID0gZWxlbWVudHNbY3Vyc29yXTsKKyAgICAgICAgICAgIGlmIChoZWFkICE9IGZlbmNlIHx8IHJlc3VsdCA9PSBudWxsKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBsYXN0UmV0ID0gY3Vyc29yOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgIGlmIChsYXN0UmV0IDwgMCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBpZiAoIWRlbGV0ZShsYXN0UmV0KSkgeworICAgICAgICAgICAgICAgIGN1cnNvciA9IChjdXJzb3IgKyAxKSAmIChlbGVtZW50cy5sZW5ndGggLSAxKTsKKyAgICAgICAgICAgICAgICBmZW5jZSA9IGhlYWQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsYXN0UmV0ID0gLTE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIDx0dD50cnVlPC90dD4gaWYgdGhpcyBkZXF1ZSBjb250YWlucyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuCisgICAgICogTW9yZSBmb3JtYWxseSwgcmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIGFuZCBvbmx5IGlmIHRoaXMgZGVxdWUgY29udGFpbnMKKyAgICAgKiBhdCBsZWFzdCBvbmUgZWxlbWVudCA8dHQ+ZTwvdHQ+IHN1Y2ggdGhhdCA8dHQ+by5lcXVhbHMoZSk8L3R0Pi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvIG9iamVjdCB0byBiZSBjaGVja2VkIGZvciBjb250YWlubWVudCBpbiB0aGlzIGRlcXVlCisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgZGVxdWUgY29udGFpbnMgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG8pIHsKKyAgICAgICAgaWYgKG8gPT0gbnVsbCkKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaW50IG1hc2sgPSBlbGVtZW50cy5sZW5ndGggLSAxOworICAgICAgICBpbnQgaSA9IGhlYWQ7CisgICAgICAgIEUgeDsKKyAgICAgICAgd2hpbGUgKCAoeCA9IGVsZW1lbnRzW2ldKSAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoby5lcXVhbHMoeCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICBpID0gKGkgKyAxKSAmIG1hc2s7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYSBzaW5nbGUgaW5zdGFuY2Ugb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50IGZyb20gdGhpcyBkZXF1ZS4KKyAgICAgKiBJZiB0aGUgZGVxdWUgZG9lcyBub3QgY29udGFpbiB0aGUgZWxlbWVudCwgaXQgaXMgdW5jaGFuZ2VkLgorICAgICAqIE1vcmUgZm9ybWFsbHksIHJlbW92ZXMgdGhlIGZpcnN0IGVsZW1lbnQgPHR0PmU8L3R0PiBzdWNoIHRoYXQKKyAgICAgKiA8dHQ+by5lcXVhbHMoZSk8L3R0PiAoaWYgc3VjaCBhbiBlbGVtZW50IGV4aXN0cykuCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgZGVxdWUgY29udGFpbmVkIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqIChvciBlcXVpdmFsZW50bHksIGlmIHRoaXMgZGVxdWUgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbCkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAbGluayAjcmVtb3ZlRmlyc3RPY2N1cnJlbmNlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvIGVsZW1lbnQgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoaXMgZGVxdWUsIGlmIHByZXNlbnQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBkZXF1ZSBjb250YWluZWQgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvKSB7CisgICAgICAgIHJldHVybiByZW1vdmVGaXJzdE9jY3VycmVuY2Uobyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhbGwgb2YgdGhlIGVsZW1lbnRzIGZyb20gdGhpcyBkZXF1ZS4KKyAgICAgKiBUaGUgZGVxdWUgd2lsbCBiZSBlbXB0eSBhZnRlciB0aGlzIGNhbGwgcmV0dXJucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgaW50IGggPSBoZWFkOworICAgICAgICBpbnQgdCA9IHRhaWw7CisgICAgICAgIGlmIChoICE9IHQpIHsgLy8gY2xlYXIgYWxsIGNlbGxzCisgICAgICAgICAgICBoZWFkID0gdGFpbCA9IDA7CisgICAgICAgICAgICBpbnQgaSA9IGg7CisgICAgICAgICAgICBpbnQgbWFzayA9IGVsZW1lbnRzLmxlbmd0aCAtIDE7CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgZWxlbWVudHNbaV0gPSBudWxsOworICAgICAgICAgICAgICAgIGkgPSAoaSArIDEpICYgbWFzazsKKyAgICAgICAgICAgIH0gd2hpbGUgKGkgIT0gdCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcgYWxsIG9mIHRoZSBlbGVtZW50cyBpbiB0aGlzIGRlcXVlCisgICAgICogaW4gcHJvcGVyIHNlcXVlbmNlIChmcm9tIGZpcnN0IHRvIGxhc3QgZWxlbWVudCkuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQgYXJyYXkgd2lsbCBiZSAic2FmZSIgaW4gdGhhdCBubyByZWZlcmVuY2VzIHRvIGl0IGFyZQorICAgICAqIG1haW50YWluZWQgYnkgdGhpcyBkZXF1ZS4gIChJbiBvdGhlciB3b3JkcywgdGhpcyBtZXRob2QgbXVzdCBhbGxvY2F0ZQorICAgICAqIGEgbmV3IGFycmF5KS4gIFRoZSBjYWxsZXIgaXMgdGh1cyBmcmVlIHRvIG1vZGlmeSB0aGUgcmV0dXJuZWQgYXJyYXkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBhY3RzIGFzIGJyaWRnZSBiZXR3ZWVuIGFycmF5LWJhc2VkIGFuZCBjb2xsZWN0aW9uLWJhc2VkCisgICAgICogQVBJcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoaXMgZGVxdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIGNvcHlFbGVtZW50cyhuZXcgT2JqZWN0W3NpemUoKV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoaXMgZGVxdWUgaW4KKyAgICAgKiBwcm9wZXIgc2VxdWVuY2UgKGZyb20gZmlyc3QgdG8gbGFzdCBlbGVtZW50KTsgdGhlIHJ1bnRpbWUgdHlwZSBvZiB0aGUKKyAgICAgKiByZXR1cm5lZCBhcnJheSBpcyB0aGF0IG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkuICBJZiB0aGUgZGVxdWUgZml0cyBpbgorICAgICAqIHRoZSBzcGVjaWZpZWQgYXJyYXksIGl0IGlzIHJldHVybmVkIHRoZXJlaW4uICBPdGhlcndpc2UsIGEgbmV3IGFycmF5CisgICAgICogaXMgYWxsb2NhdGVkIHdpdGggdGhlIHJ1bnRpbWUgdHlwZSBvZiB0aGUgc3BlY2lmaWVkIGFycmF5IGFuZCB0aGUKKyAgICAgKiBzaXplIG9mIHRoaXMgZGVxdWUuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGlzIGRlcXVlIGZpdHMgaW4gdGhlIHNwZWNpZmllZCBhcnJheSB3aXRoIHJvb20gdG8gc3BhcmUKKyAgICAgKiAoaS5lLiwgdGhlIGFycmF5IGhhcyBtb3JlIGVsZW1lbnRzIHRoYW4gdGhpcyBkZXF1ZSksIHRoZSBlbGVtZW50IGluCisgICAgICogdGhlIGFycmF5IGltbWVkaWF0ZWx5IGZvbGxvd2luZyB0aGUgZW5kIG9mIHRoZSBkZXF1ZSBpcyBzZXQgdG8KKyAgICAgKiA8dHQ+bnVsbDwvdHQ+LgorICAgICAqCisgICAgICogPHA+TGlrZSB0aGUge0BsaW5rICN0b0FycmF5KCl9IG1ldGhvZCwgdGhpcyBtZXRob2QgYWN0cyBhcyBicmlkZ2UgYmV0d2VlbgorICAgICAqIGFycmF5LWJhc2VkIGFuZCBjb2xsZWN0aW9uLWJhc2VkIEFQSXMuICBGdXJ0aGVyLCB0aGlzIG1ldGhvZCBhbGxvd3MKKyAgICAgKiBwcmVjaXNlIGNvbnRyb2wgb3ZlciB0aGUgcnVudGltZSB0eXBlIG9mIHRoZSBvdXRwdXQgYXJyYXksIGFuZCBtYXksCisgICAgICogdW5kZXIgY2VydGFpbiBjaXJjdW1zdGFuY2VzLCBiZSB1c2VkIHRvIHNhdmUgYWxsb2NhdGlvbiBjb3N0cy4KKyAgICAgKgorICAgICAqIDxwPlN1cHBvc2UgPHR0Png8L3R0PiBpcyBhIGRlcXVlIGtub3duIHRvIGNvbnRhaW4gb25seSBzdHJpbmdzLgorICAgICAqIFRoZSBmb2xsb3dpbmcgY29kZSBjYW4gYmUgdXNlZCB0byBkdW1wIHRoZSBkZXF1ZSBpbnRvIGEgbmV3bHkKKyAgICAgKiBhbGxvY2F0ZWQgYXJyYXkgb2YgPHR0PlN0cmluZzwvdHQ+OgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiAgICAgU3RyaW5nW10geSA9IHgudG9BcnJheShuZXcgU3RyaW5nWzBdKTs8L3ByZT4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCA8dHQ+dG9BcnJheShuZXcgT2JqZWN0WzBdKTwvdHQ+IGlzIGlkZW50aWNhbCBpbiBmdW5jdGlvbiB0bworICAgICAqIDx0dD50b0FycmF5KCk8L3R0Pi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSBpbnRvIHdoaWNoIHRoZSBlbGVtZW50cyBvZiB0aGUgZGVxdWUgYXJlIHRvCisgICAgICogICAgICAgICAgYmUgc3RvcmVkLCBpZiBpdCBpcyBiaWcgZW5vdWdoOyBvdGhlcndpc2UsIGEgbmV3IGFycmF5IG9mIHRoZQorICAgICAqICAgICAgICAgIHNhbWUgcnVudGltZSB0eXBlIGlzIGFsbG9jYXRlZCBmb3IgdGhpcyBwdXJwb3NlCisgICAgICogQHJldHVybiBhbiBhcnJheSBjb250YWluaW5nIGFsbCBvZiB0aGUgZWxlbWVudHMgaW4gdGhpcyBkZXF1ZQorICAgICAqIEB0aHJvd3MgQXJyYXlTdG9yZUV4Y2VwdGlvbiBpZiB0aGUgcnVudGltZSB0eXBlIG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkKKyAgICAgKiAgICAgICAgIGlzIG5vdCBhIHN1cGVydHlwZSBvZiB0aGUgcnVudGltZSB0eXBlIG9mIGV2ZXJ5IGVsZW1lbnQgaW4KKyAgICAgKiAgICAgICAgIHRoaXMgZGVxdWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgYXJyYXkgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyA8VD4gVFtdIHRvQXJyYXkoVFtdIGEpIHsKKyAgICAgICAgaW50IHNpemUgPSBzaXplKCk7CisgICAgICAgIGlmIChhLmxlbmd0aCA8IHNpemUpCisgICAgICAgICAgICBhID0gKFRbXSlqYXZhLmxhbmcucmVmbGVjdC5BcnJheS5uZXdJbnN0YW5jZSgKKyAgICAgICAgICAgICAgICAgICAgYS5nZXRDbGFzcygpLmdldENvbXBvbmVudFR5cGUoKSwgc2l6ZSk7CisgICAgICAgIGNvcHlFbGVtZW50cyhhKTsKKyAgICAgICAgaWYgKGEubGVuZ3RoID4gc2l6ZSkKKyAgICAgICAgICAgIGFbc2l6ZV0gPSBudWxsOworICAgICAgICByZXR1cm4gYTsKKyAgICB9CisKKyAgICAvLyAqKiogT2JqZWN0IG1ldGhvZHMgKioqCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29weSBvZiB0aGlzIGRlcXVlLgorICAgICAqCisgICAgICogQHJldHVybiBhIGNvcHkgb2YgdGhpcyBkZXF1ZQorICAgICAqLworICAgIHB1YmxpYyBBcnJheURlcXVlPEU+IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlEZXF1ZTxFPiByZXN1bHQgPSAoQXJyYXlEZXF1ZTxFPikgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgICAgIHJlc3VsdC5lbGVtZW50cyA9IEFycmF5cy5jb3B5T2YoZWxlbWVudHMsIGVsZW1lbnRzLmxlbmd0aCk7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworCisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZWFzZSB0aGUgc2VyaWFsaXphdGlvbiBnb2RzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDIzNDA5ODU3OTgwMzQwMzg5MjNMOworCisgICAgLyoqCisgICAgICogU2VyaWFsaXplIHRoaXMgZGVxdWUuCisgICAgICoKKyAgICAgKiBAc2VyaWFsRGF0YSBUaGUgY3VycmVudCBzaXplICg8dHQ+aW50PC90dD4pIG9mIHRoZSBkZXF1ZSwKKyAgICAgKiBmb2xsb3dlZCBieSBhbGwgb2YgaXRzIGVsZW1lbnRzIChlYWNoIGFuIG9iamVjdCByZWZlcmVuY2UpIGluCisgICAgICogZmlyc3QtdG8tbGFzdCBvcmRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHMuZGVmYXVsdFdyaXRlT2JqZWN0KCk7CisKKyAgICAgICAgLy8gV3JpdGUgb3V0IHNpemUKKyAgICAgICAgcy53cml0ZUludChzaXplKCkpOworCisgICAgICAgIC8vIFdyaXRlIG91dCBlbGVtZW50cyBpbiBvcmRlci4KKyAgICAgICAgaW50IG1hc2sgPSBlbGVtZW50cy5sZW5ndGggLSAxOworICAgICAgICBmb3IgKGludCBpID0gaGVhZDsgaSAhPSB0YWlsOyBpID0gKGkgKyAxKSAmIG1hc2spCisgICAgICAgICAgICBzLndyaXRlT2JqZWN0KGVsZW1lbnRzW2ldKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXNlcmlhbGl6ZSB0aGlzIGRlcXVlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIHMpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBzLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisKKyAgICAgICAgLy8gUmVhZCBpbiBzaXplIGFuZCBhbGxvY2F0ZSBhcnJheQorICAgICAgICBpbnQgc2l6ZSA9IHMucmVhZEludCgpOworICAgICAgICBhbGxvY2F0ZUVsZW1lbnRzKHNpemUpOworICAgICAgICBoZWFkID0gMDsKKyAgICAgICAgdGFpbCA9IHNpemU7CisKKyAgICAgICAgLy8gUmVhZCBpbiBhbGwgZWxlbWVudHMgaW4gdGhlIHByb3BlciBvcmRlci4KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspCisgICAgICAgICAgICBlbGVtZW50c1tpXSA9IChFKXMucmVhZE9iamVjdCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvQXJyYXlMaXN0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0FycmF5TGlzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM3OTdlMTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0FycmF5TGlzdC5qYXZhCkBAIC0wLDAgKzEsNjYwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnZhbGlkT2JqZWN0RXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQXJyYXk7CitpbXBvcnQgbGliY29yZS51dGlsLkVtcHR5QXJyYXk7CisKKy8qKgorICogQXJyYXlMaXN0IGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIHtAbGluayBMaXN0fSwgYmFja2VkIGJ5IGFuIGFycmF5LgorICogQWxsIG9wdGlvbmFsIG9wZXJhdGlvbnMgaW5jbHVkaW5nIGFkZGluZywgcmVtb3ZpbmcsIGFuZCByZXBsYWNpbmcgZWxlbWVudHMgYXJlIHN1cHBvcnRlZC4KKyAqCisgKiA8cD5BbGwgZWxlbWVudHMgYXJlIHBlcm1pdHRlZCwgaW5jbHVkaW5nIG51bGwuCisgKgorICogPHA+VGhpcyBjbGFzcyBpcyBhIGdvb2QgY2hvaWNlIGFzIHlvdXIgZGVmYXVsdCB7QGNvZGUgTGlzdH0gaW1wbGVtZW50YXRpb24uCisgKiB7QGxpbmsgVmVjdG9yfSBzeW5jaHJvbml6ZXMgYWxsIG9wZXJhdGlvbnMsIGJ1dCBub3QgbmVjZXNzYXJpbHkgaW4gYSB3YXkgdGhhdCdzCisgKiBtZWFuaW5nZnVsIHRvIHlvdXIgYXBwbGljYXRpb246IHN5bmNocm9uaXppbmcgZWFjaCBjYWxsIHRvIHtAY29kZSBnZXR9LCBmb3IgZXhhbXBsZSwgaXMgbm90CisgKiBlcXVpdmFsZW50IHRvIHN5bmNocm9uaXppbmcgdGhlIGxpc3QgYW5kIGl0ZXJhdGluZyBvdmVyIGl0ICh3aGljaCBpcyBwcm9iYWJseSB3aGF0IHlvdSBpbnRlbmRlZCkuCisgKiB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29weU9uV3JpdGVBcnJheUxpc3R9IGlzIGludGVuZGVkIGZvciB0aGUgc3BlY2lhbCBjYXNlIG9mIHZlcnkgaGlnaAorICogY29uY3VycmVuY3ksIGZyZXF1ZW50IHRyYXZlcnNhbHMsIGFuZCB2ZXJ5IHJhcmUgbXV0YXRpb25zLgorICoKKyAqIEBwYXJhbSA8RT4gVGhlIGVsZW1lbnQgdHlwZSBvZiB0aGlzIGxpc3QuCisgKiBAc2luY2UgMS4yCisgKi8KK3B1YmxpYyBjbGFzcyBBcnJheUxpc3Q8RT4gZXh0ZW5kcyBBYnN0cmFjdExpc3Q8RT4gaW1wbGVtZW50cyBDbG9uZWFibGUsIFNlcmlhbGl6YWJsZSwgUmFuZG9tQWNjZXNzIHsKKyAgICAvKioKKyAgICAgKiBUaGUgbWluaW11bSBhbW91bnQgYnkgd2hpY2ggdGhlIGNhcGFjaXR5IG9mIGFuIEFycmF5TGlzdCB3aWxsIGluY3JlYXNlLgorICAgICAqIFRoaXMgdHVuaW5nIHBhcmFtZXRlciBjb250cm9scyBhIHRpbWUtc3BhY2UgdHJhZGVvZmYuIFRoaXMgdmFsdWUgKDEyKQorICAgICAqIGdpdmVzIGVtcGlyaWNhbGx5IGdvb2QgcmVzdWx0cyBhbmQgaXMgYXJndWFibHkgY29uc2lzdGVudCB3aXRoIHRoZQorICAgICAqIFJJJ3Mgc3BlY2lmaWVkIGRlZmF1bHQgaW5pdGlhbCBjYXBhY2l0eSBvZiAxMDogaW5zdGVhZCBvZiAxMCwgd2Ugc3RhcnQKKyAgICAgKiB3aXRoIDAgKHNhbnMgYWxsb2NhdGlvbikgYW5kIGp1bXAgdG8gMTIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1JTl9DQVBBQ0lUWV9JTkNSRU1FTlQgPSAxMjsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBsaXN0LgorICAgICAqLworICAgIGludCBzaXplOworCisgICAgLyoqCisgICAgICogVGhlIGVsZW1lbnRzIGluIHRoaXMgbGlzdCwgZm9sbG93ZWQgYnkgbnVsbHMuCisgICAgICovCisgICAgdHJhbnNpZW50IE9iamVjdFtdIGFycmF5OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgQXJyYXlMaXN0fSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBpbml0aWFsIGNhcGFjaXR5LgorICAgICAqCisgICAgICogQHBhcmFtIGNhcGFjaXR5CisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBjYXBhY2l0eSBvZiB0aGlzIHtAY29kZSBBcnJheUxpc3R9LgorICAgICAqLworICAgIHB1YmxpYyBBcnJheUxpc3QoaW50IGNhcGFjaXR5KSB7CisgICAgICAgIGlmIChjYXBhY2l0eSA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBhcnJheSA9IChjYXBhY2l0eSA9PSAwID8gRW1wdHlBcnJheS5PQkpFQ1QgOiBuZXcgT2JqZWN0W2NhcGFjaXR5XSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQXJyYXlMaXN0fSBpbnN0YW5jZSB3aXRoIHplcm8gaW5pdGlhbCBjYXBhY2l0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXJyYXlMaXN0KCkgeworICAgICAgICBhcnJheSA9IEVtcHR5QXJyYXkuT0JKRUNUOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEFycmF5TGlzdH0gY29udGFpbmluZyB0aGUgZWxlbWVudHMgb2YKKyAgICAgKiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbGxlY3Rpb24gb2YgZWxlbWVudHMgdG8gYWRkLgorICAgICAqLworICAgIHB1YmxpYyBBcnJheUxpc3QoQ29sbGVjdGlvbjw/IGV4dGVuZHMgRT4gY29sbGVjdGlvbikgeworICAgICAgICBPYmplY3RbXSBhID0gY29sbGVjdGlvbi50b0FycmF5KCk7CisgICAgICAgIGlmIChhLmdldENsYXNzKCkgIT0gT2JqZWN0W10uY2xhc3MpIHsKKyAgICAgICAgICAgIE9iamVjdFtdIG5ld0FycmF5ID0gbmV3IE9iamVjdFthLmxlbmd0aF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIDAsIG5ld0FycmF5LCAwLCBhLmxlbmd0aCk7CisgICAgICAgICAgICBhID0gbmV3QXJyYXk7CisgICAgICAgIH0KKyAgICAgICAgYXJyYXkgPSBhOworICAgICAgICBzaXplID0gYS5sZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIG9iamVjdCBhdCB0aGUgZW5kIG9mIHRoaXMge0Bjb2RlIEFycmF5TGlzdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFkZC4KKyAgICAgKiBAcmV0dXJuIGFsd2F5cyB0cnVlCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGFkZChFIG9iamVjdCkgeworICAgICAgICBPYmplY3RbXSBhID0gYXJyYXk7CisgICAgICAgIGludCBzID0gc2l6ZTsKKyAgICAgICAgaWYgKHMgPT0gYS5sZW5ndGgpIHsKKyAgICAgICAgICAgIE9iamVjdFtdIG5ld0FycmF5ID0gbmV3IE9iamVjdFtzICsKKyAgICAgICAgICAgICAgICAgICAgKHMgPCAoTUlOX0NBUEFDSVRZX0lOQ1JFTUVOVCAvIDIpID8KKyAgICAgICAgICAgICAgICAgICAgIE1JTl9DQVBBQ0lUWV9JTkNSRU1FTlQgOiBzID4+IDEpXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYSwgMCwgbmV3QXJyYXksIDAsIHMpOworICAgICAgICAgICAgYXJyYXkgPSBhID0gbmV3QXJyYXk7CisgICAgICAgIH0KKyAgICAgICAgYVtzXSA9IG9iamVjdDsKKyAgICAgICAgc2l6ZSA9IHMgKyAxOworICAgICAgICBtb2RDb3VudCsrOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGludG8gdGhpcyB7QGNvZGUgQXJyYXlMaXN0fSBhdCB0aGUgc3BlY2lmaWVkCisgICAgICogbG9jYXRpb24uIFRoZSBvYmplY3QgaXMgaW5zZXJ0ZWQgYmVmb3JlIGFueSBwcmV2aW91cyBlbGVtZW50IGF0IHRoZQorICAgICAqIHNwZWNpZmllZCBsb2NhdGlvbi4gSWYgdGhlIGxvY2F0aW9uIGlzIGVxdWFsIHRvIHRoZSBzaXplIG9mIHRoaXMKKyAgICAgKiB7QGNvZGUgQXJyYXlMaXN0fSwgdGhlIG9iamVjdCBpcyBhZGRlZCBhdCB0aGUgZW5kLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggYXQgd2hpY2ggdG8gaW5zZXJ0IHRoZSBvYmplY3QuCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBhZGQuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiB7QGNvZGUgbG9jYXRpb24gPCAwIHx8ID4gc2l6ZSgpfQorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBhZGQoaW50IGluZGV4LCBFIG9iamVjdCkgeworICAgICAgICBPYmplY3RbXSBhID0gYXJyYXk7CisgICAgICAgIGludCBzID0gc2l6ZTsKKyAgICAgICAgaWYgKGluZGV4ID4gcyB8fCBpbmRleCA8IDApIHsKKyAgICAgICAgICAgIHRocm93SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihpbmRleCwgcyk7CisgICAgICAgIH0KKworICAgICAgICBpZiAocyA8IGEubGVuZ3RoKSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIGluZGV4LCBhLCBpbmRleCArIDEsIHMgLSBpbmRleCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBhc3NlcnQgcyA9PSBhLmxlbmd0aDsKKyAgICAgICAgICAgIE9iamVjdFtdIG5ld0FycmF5ID0gbmV3IE9iamVjdFtuZXdDYXBhY2l0eShzKV07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIDAsIG5ld0FycmF5LCAwLCBpbmRleCk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIGluZGV4LCBuZXdBcnJheSwgaW5kZXggKyAxLCBzIC0gaW5kZXgpOworICAgICAgICAgICAgYXJyYXkgPSBhID0gbmV3QXJyYXk7CisgICAgICAgIH0KKyAgICAgICAgYVtpbmRleF0gPSBvYmplY3Q7CisgICAgICAgIHNpemUgPSBzICsgMTsKKyAgICAgICAgbW9kQ291bnQrKzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBjb250cm9scyB0aGUgZ3Jvd3RoIG9mIEFycmF5TGlzdCBjYXBhY2l0aWVzLiAgSXQgcmVwcmVzZW50cworICAgICAqIGEgdGltZS1zcGFjZSB0cmFkZW9mZjogd2UgZG9uJ3Qgd2FudCB0byBncm93IGxpc3RzIHRvbyBmcmVxdWVudGx5CisgICAgICogKHdoaWNoIHdhc3RlcyB0aW1lIGFuZCBmcmFnbWVudHMgc3RvcmFnZSksIGJ1dCB3ZSBkb24ndCB3YW50IHRvIHdhc3RlCisgICAgICogdG9vIG11Y2ggc3BhY2UgaW4gdW51c2VkIGV4Y2VzcyBjYXBhY2l0eS4KKyAgICAgKgorICAgICAqIE5PVEU6IFRoaXMgbWV0aG9kIGlzIGlubGluZWQgaW50byB7QGxpbmsgI2FkZChPYmplY3QpfSBmb3IgcGVyZm9ybWFuY2UuCisgICAgICogSWYgeW91IGNoYW5nZSB0aGUgbWV0aG9kLCBjaGFuZ2UgaXQgdGhlcmUgdG9vIQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCBuZXdDYXBhY2l0eShpbnQgY3VycmVudENhcGFjaXR5KSB7CisgICAgICAgIGludCBpbmNyZW1lbnQgPSAoY3VycmVudENhcGFjaXR5IDwgKE1JTl9DQVBBQ0lUWV9JTkNSRU1FTlQgLyAyKSA/CisgICAgICAgICAgICAgICAgTUlOX0NBUEFDSVRZX0lOQ1JFTUVOVCA6IGN1cnJlbnRDYXBhY2l0eSA+PiAxKTsKKyAgICAgICAgcmV0dXJuIGN1cnJlbnRDYXBhY2l0eSArIGluY3JlbWVudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBvYmplY3RzIGluIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiB0byB0aGlzIHtAY29kZSBBcnJheUxpc3R9LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIG9mIG9iamVjdHMuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgQXJyYXlMaXN0fSBpcyBtb2RpZmllZCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBhZGRBbGwoQ29sbGVjdGlvbjw/IGV4dGVuZHMgRT4gY29sbGVjdGlvbikgeworICAgICAgICBPYmplY3RbXSBuZXdQYXJ0ID0gY29sbGVjdGlvbi50b0FycmF5KCk7CisgICAgICAgIGludCBuZXdQYXJ0U2l6ZSA9IG5ld1BhcnQubGVuZ3RoOworICAgICAgICBpZiAobmV3UGFydFNpemUgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIE9iamVjdFtdIGEgPSBhcnJheTsKKyAgICAgICAgaW50IHMgPSBzaXplOworICAgICAgICBpbnQgbmV3U2l6ZSA9IHMgKyBuZXdQYXJ0U2l6ZTsgLy8gSWYgYWRkIG92ZXJmbG93cywgYXJyYXljb3B5IHdpbGwgZmFpbAorICAgICAgICBpZiAobmV3U2l6ZSA+IGEubGVuZ3RoKSB7CisgICAgICAgICAgICBpbnQgbmV3Q2FwYWNpdHkgPSBuZXdDYXBhY2l0eShuZXdTaXplIC0gMSk7ICAvLyB+MzMlIGdyb3d0aCByb29tCisgICAgICAgICAgICBPYmplY3RbXSBuZXdBcnJheSA9IG5ldyBPYmplY3RbbmV3Q2FwYWNpdHldOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhLCAwLCBuZXdBcnJheSwgMCwgcyk7CisgICAgICAgICAgICBhcnJheSA9IGEgPSBuZXdBcnJheTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5ld1BhcnQsIDAsIGEsIHMsIG5ld1BhcnRTaXplKTsKKyAgICAgICAgc2l6ZSA9IG5ld1NpemU7CisgICAgICAgIG1vZENvdW50Kys7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIG9iamVjdHMgaW4gdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGF0IHRoZSBzcGVjaWZpZWQgbG9jYXRpb24KKyAgICAgKiBpbiB0aGlzIExpc3QuIFRoZSBvYmplY3RzIGFyZSBhZGRlZCBpbiB0aGUgb3JkZXIgdGhleSBhcmUgcmV0dXJuZWQgZnJvbQorICAgICAqIHRoZSBjb2xsZWN0aW9uJ3MgaXRlcmF0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhdCB3aGljaCB0byBpbnNlcnQuCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIG9mIG9iamVjdHMuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgQXJyYXlMaXN0fSBpcyBtb2RpZmllZCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHdoZW4ge0Bjb2RlIGxvY2F0aW9uIDwgMCB8fCA+IHNpemUoKX0KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBhZGRBbGwoaW50IGluZGV4LCBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjb2xsZWN0aW9uKSB7CisgICAgICAgIGludCBzID0gc2l6ZTsKKyAgICAgICAgaWYgKGluZGV4ID4gcyB8fCBpbmRleCA8IDApIHsKKyAgICAgICAgICAgIHRocm93SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihpbmRleCwgcyk7CisgICAgICAgIH0KKyAgICAgICAgT2JqZWN0W10gbmV3UGFydCA9IGNvbGxlY3Rpb24udG9BcnJheSgpOworICAgICAgICBpbnQgbmV3UGFydFNpemUgPSBuZXdQYXJ0Lmxlbmd0aDsKKyAgICAgICAgaWYgKG5ld1BhcnRTaXplID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBPYmplY3RbXSBhID0gYXJyYXk7CisgICAgICAgIGludCBuZXdTaXplID0gcyArIG5ld1BhcnRTaXplOyAvLyBJZiBhZGQgb3ZlcmZsb3dzLCBhcnJheWNvcHkgd2lsbCBmYWlsCisgICAgICAgIGlmIChuZXdTaXplIDw9IGEubGVuZ3RoKSB7CisgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhLCBpbmRleCwgYSwgaW5kZXggKyBuZXdQYXJ0U2l6ZSwgcyAtIGluZGV4KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGludCBuZXdDYXBhY2l0eSA9IG5ld0NhcGFjaXR5KG5ld1NpemUgLSAxKTsgIC8vIH4zMyUgZ3Jvd3RoIHJvb20KKyAgICAgICAgICAgIE9iamVjdFtdIG5ld0FycmF5ID0gbmV3IE9iamVjdFtuZXdDYXBhY2l0eV07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIDAsIG5ld0FycmF5LCAwLCBpbmRleCk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIGluZGV4LCBuZXdBcnJheSwgaW5kZXggKyBuZXdQYXJ0U2l6ZSwgcy1pbmRleCk7CisgICAgICAgICAgICBhcnJheSA9IGEgPSBuZXdBcnJheTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5ld1BhcnQsIDAsIGEsIGluZGV4LCBuZXdQYXJ0U2l6ZSk7CisgICAgICAgIHNpemUgPSBuZXdTaXplOworICAgICAgICBtb2RDb3VudCsrOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3YXMgZXh0cmFjdGVkIHRvIGVuY291cmFnZSBWTSB0byBpbmxpbmUgY2FsbGVycy4KKyAgICAgKiBUT0RPOiB3aGVuIHdlIGhhdmUgYSBWTSB0aGF0IGNhbiBhY3R1YWxseSBpbmxpbmUsIG1vdmUgdGhlIHRlc3QgaW4gaGVyZSB0b28hCisgICAgICovCisgICAgc3RhdGljIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gdGhyb3dJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKGludCBpbmRleCwgaW50IHNpemUpIHsKKyAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oIkludmFsaWQgaW5kZXggIiArIGluZGV4ICsgIiwgc2l6ZSBpcyAiICsgc2l6ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhbGwgZWxlbWVudHMgZnJvbSB0aGlzIHtAY29kZSBBcnJheUxpc3R9LCBsZWF2aW5nIGl0IGVtcHR5LgorICAgICAqCisgICAgICogQHNlZSAjaXNFbXB0eQorICAgICAqIEBzZWUgI3NpemUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgIGlmIChzaXplICE9IDApIHsKKyAgICAgICAgICAgIEFycmF5cy5maWxsKGFycmF5LCAwLCBzaXplLCBudWxsKTsKKyAgICAgICAgICAgIHNpemUgPSAwOworICAgICAgICAgICAgbW9kQ291bnQrKzsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEFycmF5TGlzdH0gd2l0aCB0aGUgc2FtZSBlbGVtZW50cywgdGhlIHNhbWUgc2l6ZSBhbmQKKyAgICAgKiB0aGUgc2FtZSBjYXBhY2l0eSBhcyB0aGlzIHtAY29kZSBBcnJheUxpc3R9LgorICAgICAqCisgICAgICogQHJldHVybiBhIHNoYWxsb3cgY29weSBvZiB0aGlzIHtAY29kZSBBcnJheUxpc3R9CisgICAgICogQHNlZSBqYXZhLmxhbmcuQ2xvbmVhYmxlCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheUxpc3Q8Pz4gcmVzdWx0ID0gKEFycmF5TGlzdDw/Pikgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgICAgIHJlc3VsdC5hcnJheSA9IGFycmF5LmNsb25lKCk7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5zdXJlcyB0aGF0IGFmdGVyIHRoaXMgb3BlcmF0aW9uIHRoZSB7QGNvZGUgQXJyYXlMaXN0fSBjYW4gaG9sZCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgbnVtYmVyIG9mIGVsZW1lbnRzIHdpdGhvdXQgZnVydGhlciBncm93aW5nLgorICAgICAqCisgICAgICogQHBhcmFtIG1pbmltdW1DYXBhY2l0eQorICAgICAqICAgICAgICAgICAgdGhlIG1pbmltdW0gY2FwYWNpdHkgYXNrZWQgZm9yLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVuc3VyZUNhcGFjaXR5KGludCBtaW5pbXVtQ2FwYWNpdHkpIHsKKyAgICAgICAgT2JqZWN0W10gYSA9IGFycmF5OworICAgICAgICBpZiAoYS5sZW5ndGggPCBtaW5pbXVtQ2FwYWNpdHkpIHsKKyAgICAgICAgICAgIE9iamVjdFtdIG5ld0FycmF5ID0gbmV3IE9iamVjdFttaW5pbXVtQ2FwYWNpdHldOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhLCAwLCBuZXdBcnJheSwgMCwgc2l6ZSk7CisgICAgICAgICAgICBhcnJheSA9IG5ld0FycmF5OworICAgICAgICAgICAgbW9kQ291bnQrKzsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSBAT3ZlcnJpZGUgcHVibGljIEUgZ2V0KGludCBpbmRleCkgeworICAgICAgICBpZiAoaW5kZXggPj0gc2l6ZSkgeworICAgICAgICAgICAgdGhyb3dJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKGluZGV4LCBzaXplKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKEUpIGFycmF5W2luZGV4XTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyB7QGNvZGUgQXJyYXlMaXN0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIHtAY29kZSBBcnJheUxpc3R9LgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgIHJldHVybiBzaXplOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICByZXR1cm4gc2l6ZSA9PSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlYXJjaGVzIHRoaXMge0Bjb2RlIEFycmF5TGlzdH0gZm9yIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBzZWFyY2ggZm9yLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBvYmplY3R9IGlzIGFuIGVsZW1lbnQgb2YgdGhpcworICAgICAqICAgICAgICAge0Bjb2RlIEFycmF5TGlzdH0sIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgT2JqZWN0W10gYSA9IGFycmF5OworICAgICAgICBpbnQgcyA9IHNpemU7CisgICAgICAgIGlmIChvYmplY3QgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAob2JqZWN0LmVxdWFscyhhW2ldKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHM7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChhW2ldID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCBpbmRleE9mKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgT2JqZWN0W10gYSA9IGFycmF5OworICAgICAgICBpbnQgcyA9IHNpemU7CisgICAgICAgIGlmIChvYmplY3QgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAob2JqZWN0LmVxdWFscyhhW2ldKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHM7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChhW2ldID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCBsYXN0SW5kZXhPZihPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIE9iamVjdFtdIGEgPSBhcnJheTsKKyAgICAgICAgaWYgKG9iamVjdCAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gc2l6ZSAtIDE7IGkgPj0gMDsgaS0tKSB7CisgICAgICAgICAgICAgICAgaWYgKG9iamVjdC5lcXVhbHMoYVtpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IHNpemUgLSAxOyBpID49IDA7IGktLSkgeworICAgICAgICAgICAgICAgIGlmIChhW2ldID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBvYmplY3QgYXQgdGhlIHNwZWNpZmllZCBsb2NhdGlvbiBmcm9tIHRoaXMgbGlzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBvYmplY3QgdG8gcmVtb3ZlLgorICAgICAqIEByZXR1cm4gdGhlIHJlbW92ZWQgb2JqZWN0LgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHdoZW4ge0Bjb2RlIGxvY2F0aW9uIDwgMCB8fCA+PSBzaXplKCl9CisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBFIHJlbW92ZShpbnQgaW5kZXgpIHsKKyAgICAgICAgT2JqZWN0W10gYSA9IGFycmF5OworICAgICAgICBpbnQgcyA9IHNpemU7CisgICAgICAgIGlmIChpbmRleCA+PSBzKSB7CisgICAgICAgICAgICB0aHJvd0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oaW5kZXgsIHMpOworICAgICAgICB9CisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSBFIHJlc3VsdCA9IChFKSBhW2luZGV4XTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShhLCBpbmRleCArIDEsIGEsIGluZGV4LCAtLXMgLSBpbmRleCk7CisgICAgICAgIGFbc10gPSBudWxsOyAgLy8gUHJldmVudCBtZW1vcnkgbGVhaworICAgICAgICBzaXplID0gczsKKyAgICAgICAgbW9kQ291bnQrKzsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgT2JqZWN0W10gYSA9IGFycmF5OworICAgICAgICBpbnQgcyA9IHNpemU7CisgICAgICAgIGlmIChvYmplY3QgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAob2JqZWN0LmVxdWFscyhhW2ldKSkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIGkgKyAxLCBhLCBpLCAtLXMgLSBpKTsKKyAgICAgICAgICAgICAgICAgICAgYVtzXSA9IG51bGw7ICAvLyBQcmV2ZW50IG1lbW9yeSBsZWFrCisgICAgICAgICAgICAgICAgICAgIHNpemUgPSBzOworICAgICAgICAgICAgICAgICAgICBtb2RDb3VudCsrOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHM7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChhW2ldID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhLCBpICsgMSwgYSwgaSwgLS1zIC0gaSk7CisgICAgICAgICAgICAgICAgICAgIGFbc10gPSBudWxsOyAgLy8gUHJldmVudCBtZW1vcnkgbGVhaworICAgICAgICAgICAgICAgICAgICBzaXplID0gczsKKyAgICAgICAgICAgICAgICAgICAgbW9kQ291bnQrKzsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgcmVtb3ZlUmFuZ2UoaW50IGZyb21JbmRleCwgaW50IHRvSW5kZXgpIHsKKyAgICAgICAgaWYgKGZyb21JbmRleCA9PSB0b0luZGV4KSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgT2JqZWN0W10gYSA9IGFycmF5OworICAgICAgICBpbnQgcyA9IHNpemU7CisgICAgICAgIGlmIChmcm9tSW5kZXggPj0gcykgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oImZyb21JbmRleCAiICsgZnJvbUluZGV4CisgICAgICAgICAgICAgICAgICAgICsgIiA+PSBzaXplICIgKyBzaXplKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodG9JbmRleCA+IHMpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJ0b0luZGV4ICIgKyB0b0luZGV4CisgICAgICAgICAgICAgICAgICAgICsgIiA+IHNpemUgIiArIHNpemUpOworICAgICAgICB9CisgICAgICAgIGlmIChmcm9tSW5kZXggPiB0b0luZGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiZnJvbUluZGV4ICIgKyBmcm9tSW5kZXgKKyAgICAgICAgICAgICAgICAgICAgKyAiID4gdG9JbmRleCAiICsgdG9JbmRleCk7CisgICAgICAgIH0KKworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIHRvSW5kZXgsIGEsIGZyb21JbmRleCwgcyAtIHRvSW5kZXgpOworICAgICAgICBpbnQgcmFuZ2VTaXplID0gdG9JbmRleCAtIGZyb21JbmRleDsKKyAgICAgICAgQXJyYXlzLmZpbGwoYSwgcyAtIHJhbmdlU2l6ZSwgcywgbnVsbCk7CisgICAgICAgIHNpemUgPSBzIC0gcmFuZ2VTaXplOworICAgICAgICBtb2RDb3VudCsrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2VzIHRoZSBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgbG9jYXRpb24gaW4gdGhpcyB7QGNvZGUgQXJyYXlMaXN0fQorICAgICAqIHdpdGggdGhlIHNwZWNpZmllZCBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhdCB3aGljaCB0byBwdXQgdGhlIHNwZWNpZmllZCBvYmplY3QuCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBhZGQuCisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgZWxlbWVudCBhdCB0aGUgaW5kZXguCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiB7QGNvZGUgbG9jYXRpb24gPCAwIHx8ID49IHNpemUoKX0KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIEUgc2V0KGludCBpbmRleCwgRSBvYmplY3QpIHsKKyAgICAgICAgT2JqZWN0W10gYSA9IGFycmF5OworICAgICAgICBpZiAoaW5kZXggPj0gc2l6ZSkgeworICAgICAgICAgICAgdGhyb3dJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKGluZGV4LCBzaXplKTsKKyAgICAgICAgfQorICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikgRSByZXN1bHQgPSAoRSkgYVtpbmRleF07CisgICAgICAgIGFbaW5kZXhdID0gb2JqZWN0OworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgYXJyYXkgY29udGFpbmluZyBhbGwgZWxlbWVudHMgY29udGFpbmVkIGluIHRoaXMKKyAgICAgKiB7QGNvZGUgQXJyYXlMaXN0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgdGhlIGVsZW1lbnRzIGZyb20gdGhpcyB7QGNvZGUgQXJyYXlMaXN0fQorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKKyAgICAgICAgaW50IHMgPSBzaXplOworICAgICAgICBPYmplY3RbXSByZXN1bHQgPSBuZXcgT2JqZWN0W3NdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFycmF5LCAwLCByZXN1bHQsIDAsIHMpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgZWxlbWVudHMgY29udGFpbmVkIGluIHRoaXMKKyAgICAgKiB7QGNvZGUgQXJyYXlMaXN0fS4gSWYgdGhlIHNwZWNpZmllZCBhcnJheSBpcyBsYXJnZSBlbm91Z2ggdG8gaG9sZCB0aGUKKyAgICAgKiBlbGVtZW50cywgdGhlIHNwZWNpZmllZCBhcnJheSBpcyB1c2VkLCBvdGhlcndpc2UgYW4gYXJyYXkgb2YgdGhlIHNhbWUKKyAgICAgKiB0eXBlIGlzIGNyZWF0ZWQuIElmIHRoZSBzcGVjaWZpZWQgYXJyYXkgaXMgdXNlZCBhbmQgaXMgbGFyZ2VyIHRoYW4gdGhpcworICAgICAqIHtAY29kZSBBcnJheUxpc3R9LCB0aGUgYXJyYXkgZWxlbWVudCBmb2xsb3dpbmcgdGhlIGNvbGxlY3Rpb24gZWxlbWVudHMKKyAgICAgKiBpcyBzZXQgdG8gbnVsbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb250ZW50cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5LgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgdGhlIGVsZW1lbnRzIGZyb20gdGhpcyB7QGNvZGUgQXJyYXlMaXN0fS4KKyAgICAgKiBAdGhyb3dzIEFycmF5U3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHRoZSB0eXBlIG9mIGFuIGVsZW1lbnQgaW4gdGhpcyB7QGNvZGUgQXJyYXlMaXN0fSBjYW5ub3QKKyAgICAgKiAgICAgICAgICAgICBiZSBzdG9yZWQgaW4gdGhlIHR5cGUgb2YgdGhlIHNwZWNpZmllZCBhcnJheS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIDxUPiBUW10gdG9BcnJheShUW10gY29udGVudHMpIHsKKyAgICAgICAgaW50IHMgPSBzaXplOworICAgICAgICBpZiAoY29udGVudHMubGVuZ3RoIDwgcykgeworICAgICAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIFRbXSBuZXdBcnJheQorICAgICAgICAgICAgICAgID0gKFRbXSkgQXJyYXkubmV3SW5zdGFuY2UoY29udGVudHMuZ2V0Q2xhc3MoKS5nZXRDb21wb25lbnRUeXBlKCksIHMpOworICAgICAgICAgICAgY29udGVudHMgPSBuZXdBcnJheTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRoaXMuYXJyYXksIDAsIGNvbnRlbnRzLCAwLCBzKTsKKyAgICAgICAgaWYgKGNvbnRlbnRzLmxlbmd0aCA+IHMpIHsKKyAgICAgICAgICAgIGNvbnRlbnRzW3NdID0gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29udGVudHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY2FwYWNpdHkgb2YgdGhpcyB7QGNvZGUgQXJyYXlMaXN0fSB0byBiZSB0aGUgc2FtZSBhcyB0aGUgY3VycmVudAorICAgICAqIHNpemUuCisgICAgICoKKyAgICAgKiBAc2VlICNzaXplCisgICAgICovCisgICAgcHVibGljIHZvaWQgdHJpbVRvU2l6ZSgpIHsKKyAgICAgICAgaW50IHMgPSBzaXplOworICAgICAgICBpZiAocyA9PSBhcnJheS5sZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAocyA9PSAwKSB7CisgICAgICAgICAgICBhcnJheSA9IEVtcHR5QXJyYXkuT0JKRUNUOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgT2JqZWN0W10gbmV3QXJyYXkgPSBuZXcgT2JqZWN0W3NdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhcnJheSwgMCwgbmV3QXJyYXksIDAsIHMpOworICAgICAgICAgICAgYXJyYXkgPSBuZXdBcnJheTsKKyAgICAgICAgfQorICAgICAgICBtb2RDb3VudCsrOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgSXRlcmF0b3I8RT4gaXRlcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBuZXcgQXJyYXlMaXN0SXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIEFycmF5TGlzdEl0ZXJhdG9yIGltcGxlbWVudHMgSXRlcmF0b3I8RT4geworICAgICAgICAvKiogTnVtYmVyIG9mIGVsZW1lbnRzIHJlbWFpbmluZyBpbiB0aGlzIGl0ZXJhdGlvbiAqLworICAgICAgICBwcml2YXRlIGludCByZW1haW5pbmcgPSBzaXplOworCisgICAgICAgIC8qKiBJbmRleCBvZiBlbGVtZW50IHRoYXQgcmVtb3ZlKCkgd291bGQgcmVtb3ZlLCBvciAtMSBpZiBubyBzdWNoIGVsdCAqLworICAgICAgICBwcml2YXRlIGludCByZW1vdmFsSW5kZXggPSAtMTsKKworICAgICAgICAvKiogVGhlIGV4cGVjdGVkIG1vZENvdW50IHZhbHVlICovCisgICAgICAgIHByaXZhdGUgaW50IGV4cGVjdGVkTW9kQ291bnQgPSBtb2RDb3VudDsKKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgcmV0dXJuIHJlbWFpbmluZyAhPSAwOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIHB1YmxpYyBFIG5leHQoKSB7CisgICAgICAgICAgICBBcnJheUxpc3Q8RT4gb3VyTGlzdCA9IEFycmF5TGlzdC50aGlzOworICAgICAgICAgICAgaW50IHJlbSA9IHJlbWFpbmluZzsKKyAgICAgICAgICAgIGlmIChvdXJMaXN0Lm1vZENvdW50ICE9IGV4cGVjdGVkTW9kQ291bnQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHJlbSA9PSAwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlbWFpbmluZyA9IHJlbSAtIDE7CisgICAgICAgICAgICByZXR1cm4gKEUpIG91ckxpc3QuYXJyYXlbcmVtb3ZhbEluZGV4ID0gb3VyTGlzdC5zaXplIC0gcmVtXTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgIE9iamVjdFtdIGEgPSBhcnJheTsKKyAgICAgICAgICAgIGludCByZW1vdmFsSWR4ID0gcmVtb3ZhbEluZGV4OworICAgICAgICAgICAgaWYgKG1vZENvdW50ICE9IGV4cGVjdGVkTW9kQ291bnQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHJlbW92YWxJZHggPCAwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhLCByZW1vdmFsSWR4ICsgMSwgYSwgcmVtb3ZhbElkeCwgcmVtYWluaW5nKTsKKyAgICAgICAgICAgIGFbLS1zaXplXSA9IG51bGw7ICAvLyBQcmV2ZW50IG1lbW9yeSBsZWFrCisgICAgICAgICAgICByZW1vdmFsSW5kZXggPSAtMTsKKyAgICAgICAgICAgIGV4cGVjdGVkTW9kQ291bnQgPSArK21vZENvdW50OworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIE9iamVjdFtdIGEgPSBhcnJheTsKKyAgICAgICAgaW50IGhhc2hDb2RlID0gMTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDAsIHMgPSBzaXplOyBpIDwgczsgaSsrKSB7CisgICAgICAgICAgICBPYmplY3QgZSA9IGFbaV07CisgICAgICAgICAgICBoYXNoQ29kZSA9IDMxICogaGFzaENvZGUgKyAoZSA9PSBudWxsID8gMCA6IGUuaGFzaENvZGUoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGhhc2hDb2RlOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgaWYgKG8gPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCEobyBpbnN0YW5jZW9mIExpc3QpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgTGlzdDw/PiB0aGF0ID0gKExpc3Q8Pz4pIG87CisgICAgICAgIGludCBzID0gc2l6ZTsKKyAgICAgICAgaWYgKHRoYXQuc2l6ZSgpICE9IHMpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBPYmplY3RbXSBhID0gYXJyYXk7CisgICAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgUmFuZG9tQWNjZXNzKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHM7IGkrKykgeworICAgICAgICAgICAgICAgIE9iamVjdCBlVGhpcyA9IGFbaV07CisgICAgICAgICAgICAgICAgT2JqZWN0IGV0aGF0ID0gdGhhdC5nZXQoaSk7CisgICAgICAgICAgICAgICAgaWYgKGVUaGlzID09IG51bGwgPyBldGhhdCAhPSBudWxsIDogIWVUaGlzLmVxdWFscyhldGhhdCkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsgIC8vIEFyZ3VtZW50IGxpc3QgaXMgbm90IHJhbmRvbSBhY2Nlc3M7IHVzZSBpdHMgaXRlcmF0b3IKKyAgICAgICAgICAgIEl0ZXJhdG9yPD8+IGl0ID0gdGhhdC5pdGVyYXRvcigpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzOyBpKyspIHsKKyAgICAgICAgICAgICAgICBPYmplY3QgZVRoaXMgPSBhW2ldOworICAgICAgICAgICAgICAgIE9iamVjdCBlVGhhdCA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgICAgICBpZiAoZVRoaXMgPT0gbnVsbCA/IGVUaGF0ICE9IG51bGwgOiAhZVRoaXMuZXF1YWxzKGVUaGF0KSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDg2ODM0NTI1ODExMjI4OTIxODlMOworCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN0cmVhbS5kZWZhdWx0V3JpdGVPYmplY3QoKTsKKyAgICAgICAgc3RyZWFtLndyaXRlSW50KGFycmF5Lmxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBzdHJlYW0ud3JpdGVPYmplY3QoYXJyYXlbaV0pOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBzdHJlYW0uZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgaW50IGNhcCA9IHN0cmVhbS5yZWFkSW50KCk7CisgICAgICAgIGlmIChjYXAgPCBzaXplKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9iamVjdEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgIkNhcGFjaXR5OiAiICsgY2FwICsgIiA8IHNpemU6ICIgKyBzaXplKTsKKyAgICAgICAgfQorICAgICAgICBhcnJheSA9IChjYXAgPT0gMCA/IEVtcHR5QXJyYXkuT0JKRUNUIDogbmV3IE9iamVjdFtjYXBdKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgICAgIGFycmF5W2ldID0gc3RyZWFtLnJlYWRPYmplY3QoKTsKKyAgICAgICAgfQorICAgIH0KKyB9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0FycmF5cy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9BcnJheXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZDBmNGE0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9BcnJheXMuamF2YQpAQCAtMCwwICsxLDI5NDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQXJyYXk7CisKKy8qKgorICoge0Bjb2RlIEFycmF5c30gY29udGFpbnMgc3RhdGljIG1ldGhvZHMgd2hpY2ggb3BlcmF0ZSBvbiBhcnJheXMuCisgKgorICogQHNpbmNlIDEuMgorICovCitwdWJsaWMgY2xhc3MgQXJyYXlzIHsKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBBcnJheUxpc3Q8RT4gZXh0ZW5kcyBBYnN0cmFjdExpc3Q8RT4gaW1wbGVtZW50cworICAgICAgICAgICAgTGlzdDxFPiwgU2VyaWFsaXphYmxlLCBSYW5kb21BY2Nlc3MgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yNzY0MDE3NDgxMTA4OTQ1MTk4TDsKKworICAgICAgICBwcml2YXRlIGZpbmFsIEVbXSBhOworCisgICAgICAgIEFycmF5TGlzdChFW10gc3RvcmFnZSkgeworICAgICAgICAgICAgaWYgKHN0b3JhZ2UgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYSA9IHN0b3JhZ2U7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgaWYgKG9iamVjdCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZm9yIChFIGVsZW1lbnQgOiBhKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChvYmplY3QuZXF1YWxzKGVsZW1lbnQpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZm9yIChFIGVsZW1lbnQgOiBhKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBFIGdldChpbnQgbG9jYXRpb24pIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGFbbG9jYXRpb25dOworICAgICAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBqYXZhLnV0aWwuQXJyYXlMaXN0LnRocm93SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihsb2NhdGlvbiwgYS5sZW5ndGgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgaW5kZXhPZihPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICBpZiAob2JqZWN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG9iamVjdC5lcXVhbHMoYVtpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGFbaV0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBsYXN0SW5kZXhPZihPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICBpZiAob2JqZWN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gYS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgeworICAgICAgICAgICAgICAgICAgICBpZiAob2JqZWN0LmVxdWFscyhhW2ldKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChhW2ldID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBFIHNldChpbnQgbG9jYXRpb24sIEUgb2JqZWN0KSB7CisgICAgICAgICAgICBFIHJlc3VsdCA9IGFbbG9jYXRpb25dOworICAgICAgICAgICAgYVtsb2NhdGlvbl0gPSBvYmplY3Q7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBhLmxlbmd0aDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKKyAgICAgICAgICAgIHJldHVybiBhLmNsb25lKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bmNoZWNrZWQiLCAiU3VzcGljaW91c1N5c3RlbUFycmF5Y29weSJ9KQorICAgICAgICBwdWJsaWMgPFQ+IFRbXSB0b0FycmF5KFRbXSBjb250ZW50cykgeworICAgICAgICAgICAgaW50IHNpemUgPSBzaXplKCk7CisgICAgICAgICAgICBpZiAoc2l6ZSA+IGNvbnRlbnRzLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIENsYXNzPD8+IGN0ID0gY29udGVudHMuZ2V0Q2xhc3MoKS5nZXRDb21wb25lbnRUeXBlKCk7CisgICAgICAgICAgICAgICAgY29udGVudHMgPSAoVFtdKSBBcnJheS5uZXdJbnN0YW5jZShjdCwgc2l6ZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIDAsIGNvbnRlbnRzLCAwLCBzaXplKTsKKyAgICAgICAgICAgIGlmIChzaXplIDwgY29udGVudHMubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgY29udGVudHNbc2l6ZV0gPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGNvbnRlbnRzOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBBcnJheXMoKSB7CisgICAgICAgIC8qIGVtcHR5ICovCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBMaXN0fSBvZiB0aGUgb2JqZWN0cyBpbiB0aGUgc3BlY2lmaWVkIGFycmF5LiBUaGUgc2l6ZSBvZiB0aGUKKyAgICAgKiB7QGNvZGUgTGlzdH0gY2Fubm90IGJlIG1vZGlmaWVkLCBpLmUuIGFkZGluZyBhbmQgcmVtb3ZpbmcgYXJlIHVuc3VwcG9ydGVkLCBidXQKKyAgICAgKiB0aGUgZWxlbWVudHMgY2FuIGJlIHNldC4gU2V0dGluZyBhbiBlbGVtZW50IG1vZGlmaWVzIHRoZSB1bmRlcmx5aW5nCisgICAgICogYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIExpc3R9IG9mIHRoZSBlbGVtZW50cyBvZiB0aGUgc3BlY2lmaWVkIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFQ+IExpc3Q8VD4gYXNMaXN0KFQuLi4gYXJyYXkpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBBcnJheUxpc3Q8VD4oYXJyYXkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgYmluYXJ5IHNlYXJjaCBmb3Ige0Bjb2RlIHZhbHVlfSBpbiB0aGUgYXNjZW5kaW5nIHNvcnRlZCBhcnJheSB7QGNvZGUgYXJyYXl9LgorICAgICAqIFNlYXJjaGluZyBpbiBhbiB1bnNvcnRlZCBhcnJheSBoYXMgYW4gdW5kZWZpbmVkIHJlc3VsdC4gSXQncyBhbHNvIHVuZGVmaW5lZCB3aGljaCBlbGVtZW50CisgICAgICogaXMgZm91bmQgaWYgdGhlcmUgYXJlIG11bHRpcGxlIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkgdGhlIHNvcnRlZCBhcnJheSB0byBzZWFyY2guCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSBlbGVtZW50IHRvIGZpbmQuCisgICAgICogQHJldHVybiB0aGUgbm9uLW5lZ2F0aXZlIGluZGV4IG9mIHRoZSBlbGVtZW50LCBvciBhIG5lZ2F0aXZlIGluZGV4IHdoaWNoCisgICAgICogICAgICAgICBpcyB7QGNvZGUgLWluZGV4IC0gMX0gd2hlcmUgdGhlIGVsZW1lbnQgd291bGQgYmUgaW5zZXJ0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgYmluYXJ5U2VhcmNoKGJ5dGVbXSBhcnJheSwgYnl0ZSB2YWx1ZSkgeworICAgICAgICByZXR1cm4gYmluYXJ5U2VhcmNoKGFycmF5LCAwLCBhcnJheS5sZW5ndGgsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggZm9yIHtAY29kZSB2YWx1ZX0gaW4gdGhlIGFzY2VuZGluZyBzb3J0ZWQgYXJyYXkge0Bjb2RlIGFycmF5fSwKKyAgICAgKiBpbiB0aGUgcmFuZ2Ugc3BlY2lmaWVkIGJ5IGZyb21JbmRleCAoaW5jbHVzaXZlKSBhbmQgdG9JbmRleCAoZXhjbHVzaXZlKS4KKyAgICAgKiBTZWFyY2hpbmcgaW4gYW4gdW5zb3J0ZWQgYXJyYXkgaGFzIGFuIHVuZGVmaW5lZCByZXN1bHQuIEl0J3MgYWxzbyB1bmRlZmluZWQgd2hpY2ggZWxlbWVudAorICAgICAqIGlzIGZvdW5kIGlmIHRoZXJlIGFyZSBtdWx0aXBsZSBvY2N1cnJlbmNlcyBvZiB0aGUgc2FtZSBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5IHRoZSBzb3J0ZWQgYXJyYXkgdG8gc2VhcmNoLgorICAgICAqIEBwYXJhbSBzdGFydEluZGV4IHRoZSBpbmNsdXNpdmUgc3RhcnQgaW5kZXguCisgICAgICogQHBhcmFtIGVuZEluZGV4IHRoZSBleGNsdXNpdmUgc3RhcnQgaW5kZXguCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSBlbGVtZW50IHRvIGZpbmQuCisgICAgICogQHJldHVybiB0aGUgbm9uLW5lZ2F0aXZlIGluZGV4IG9mIHRoZSBlbGVtZW50LCBvciBhIG5lZ2F0aXZlIGluZGV4IHdoaWNoCisgICAgICogICAgICAgICBpcyB7QGNvZGUgLWluZGV4IC0gMX0gd2hlcmUgdGhlIGVsZW1lbnQgd291bGQgYmUgaW5zZXJ0ZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHN0YXJ0SW5kZXggPiBlbmRJbmRleH0KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB7QGNvZGUgc3RhcnRJbmRleCA8IDAgfHwgZW5kSW5kZXggPiBhcnJheS5sZW5ndGh9CisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGJpbmFyeVNlYXJjaChieXRlW10gYXJyYXksIGludCBzdGFydEluZGV4LCBpbnQgZW5kSW5kZXgsIGJ5dGUgdmFsdWUpIHsKKyAgICAgICAgY2hlY2tCaW5hcnlTZWFyY2hCb3VuZHMoc3RhcnRJbmRleCwgZW5kSW5kZXgsIGFycmF5Lmxlbmd0aCk7CisgICAgICAgIGludCBsbyA9IHN0YXJ0SW5kZXg7CisgICAgICAgIGludCBoaSA9IGVuZEluZGV4IC0gMTsKKworICAgICAgICB3aGlsZSAobG8gPD0gaGkpIHsKKyAgICAgICAgICAgIGludCBtaWQgPSAobG8gKyBoaSkgPj4+IDE7CisgICAgICAgICAgICBieXRlIG1pZFZhbCA9IGFycmF5W21pZF07CisKKyAgICAgICAgICAgIGlmIChtaWRWYWwgPCB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGxvID0gbWlkICsgMTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAobWlkVmFsID4gdmFsdWUpIHsKKyAgICAgICAgICAgICAgICBoaSA9IG1pZCAtIDE7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBtaWQ7ICAvLyB2YWx1ZSBmb3VuZAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB+bG87ICAvLyB2YWx1ZSBub3QgcHJlc2VudAorICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgYmluYXJ5IHNlYXJjaCBmb3Ige0Bjb2RlIHZhbHVlfSBpbiB0aGUgYXNjZW5kaW5nIHNvcnRlZCBhcnJheSB7QGNvZGUgYXJyYXl9LgorICAgICAqIFNlYXJjaGluZyBpbiBhbiB1bnNvcnRlZCBhcnJheSBoYXMgYW4gdW5kZWZpbmVkIHJlc3VsdC4gSXQncyBhbHNvIHVuZGVmaW5lZCB3aGljaCBlbGVtZW50CisgICAgICogaXMgZm91bmQgaWYgdGhlcmUgYXJlIG11bHRpcGxlIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkgdGhlIHNvcnRlZCBhcnJheSB0byBzZWFyY2guCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSBlbGVtZW50IHRvIGZpbmQuCisgICAgICogQHJldHVybiB0aGUgbm9uLW5lZ2F0aXZlIGluZGV4IG9mIHRoZSBlbGVtZW50LCBvciBhIG5lZ2F0aXZlIGluZGV4IHdoaWNoCisgICAgICogICAgICAgICBpcyB7QGNvZGUgLWluZGV4IC0gMX0gd2hlcmUgdGhlIGVsZW1lbnQgd291bGQgYmUgaW5zZXJ0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgYmluYXJ5U2VhcmNoKGNoYXJbXSBhcnJheSwgY2hhciB2YWx1ZSkgeworICAgICAgICByZXR1cm4gYmluYXJ5U2VhcmNoKGFycmF5LCAwLCBhcnJheS5sZW5ndGgsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggZm9yIHtAY29kZSB2YWx1ZX0gaW4gdGhlIGFzY2VuZGluZyBzb3J0ZWQgYXJyYXkge0Bjb2RlIGFycmF5fSwKKyAgICAgKiBpbiB0aGUgcmFuZ2Ugc3BlY2lmaWVkIGJ5IGZyb21JbmRleCAoaW5jbHVzaXZlKSBhbmQgdG9JbmRleCAoZXhjbHVzaXZlKS4KKyAgICAgKiBTZWFyY2hpbmcgaW4gYW4gdW5zb3J0ZWQgYXJyYXkgaGFzIGFuIHVuZGVmaW5lZCByZXN1bHQuIEl0J3MgYWxzbyB1bmRlZmluZWQgd2hpY2ggZWxlbWVudAorICAgICAqIGlzIGZvdW5kIGlmIHRoZXJlIGFyZSBtdWx0aXBsZSBvY2N1cnJlbmNlcyBvZiB0aGUgc2FtZSBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5IHRoZSBzb3J0ZWQgYXJyYXkgdG8gc2VhcmNoLgorICAgICAqIEBwYXJhbSBzdGFydEluZGV4IHRoZSBpbmNsdXNpdmUgc3RhcnQgaW5kZXguCisgICAgICogQHBhcmFtIGVuZEluZGV4IHRoZSBleGNsdXNpdmUgc3RhcnQgaW5kZXguCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSBlbGVtZW50IHRvIGZpbmQuCisgICAgICogQHJldHVybiB0aGUgbm9uLW5lZ2F0aXZlIGluZGV4IG9mIHRoZSBlbGVtZW50LCBvciBhIG5lZ2F0aXZlIGluZGV4IHdoaWNoCisgICAgICogICAgICAgICBpcyB7QGNvZGUgLWluZGV4IC0gMX0gd2hlcmUgdGhlIGVsZW1lbnQgd291bGQgYmUgaW5zZXJ0ZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHN0YXJ0SW5kZXggPiBlbmRJbmRleH0KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB7QGNvZGUgc3RhcnRJbmRleCA8IDAgfHwgZW5kSW5kZXggPiBhcnJheS5sZW5ndGh9CisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGJpbmFyeVNlYXJjaChjaGFyW10gYXJyYXksIGludCBzdGFydEluZGV4LCBpbnQgZW5kSW5kZXgsIGNoYXIgdmFsdWUpIHsKKyAgICAgICAgY2hlY2tCaW5hcnlTZWFyY2hCb3VuZHMoc3RhcnRJbmRleCwgZW5kSW5kZXgsIGFycmF5Lmxlbmd0aCk7CisgICAgICAgIGludCBsbyA9IHN0YXJ0SW5kZXg7CisgICAgICAgIGludCBoaSA9IGVuZEluZGV4IC0gMTsKKworICAgICAgICB3aGlsZSAobG8gPD0gaGkpIHsKKyAgICAgICAgICAgIGludCBtaWQgPSAobG8gKyBoaSkgPj4+IDE7CisgICAgICAgICAgICBjaGFyIG1pZFZhbCA9IGFycmF5W21pZF07CisKKyAgICAgICAgICAgIGlmIChtaWRWYWwgPCB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGxvID0gbWlkICsgMTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAobWlkVmFsID4gdmFsdWUpIHsKKyAgICAgICAgICAgICAgICBoaSA9IG1pZCAtIDE7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBtaWQ7ICAvLyB2YWx1ZSBmb3VuZAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB+bG87ICAvLyB2YWx1ZSBub3QgcHJlc2VudAorICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgYmluYXJ5IHNlYXJjaCBmb3Ige0Bjb2RlIHZhbHVlfSBpbiB0aGUgYXNjZW5kaW5nIHNvcnRlZCBhcnJheSB7QGNvZGUgYXJyYXl9LgorICAgICAqIFNlYXJjaGluZyBpbiBhbiB1bnNvcnRlZCBhcnJheSBoYXMgYW4gdW5kZWZpbmVkIHJlc3VsdC4gSXQncyBhbHNvIHVuZGVmaW5lZCB3aGljaCBlbGVtZW50CisgICAgICogaXMgZm91bmQgaWYgdGhlcmUgYXJlIG11bHRpcGxlIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkgdGhlIHNvcnRlZCBhcnJheSB0byBzZWFyY2guCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSBlbGVtZW50IHRvIGZpbmQuCisgICAgICogQHJldHVybiB0aGUgbm9uLW5lZ2F0aXZlIGluZGV4IG9mIHRoZSBlbGVtZW50LCBvciBhIG5lZ2F0aXZlIGluZGV4IHdoaWNoCisgICAgICogICAgICAgICBpcyB7QGNvZGUgLWluZGV4IC0gMX0gd2hlcmUgdGhlIGVsZW1lbnQgd291bGQgYmUgaW5zZXJ0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgYmluYXJ5U2VhcmNoKGRvdWJsZVtdIGFycmF5LCBkb3VibGUgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIGJpbmFyeVNlYXJjaChhcnJheSwgMCwgYXJyYXkubGVuZ3RoLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBiaW5hcnkgc2VhcmNoIGZvciB7QGNvZGUgdmFsdWV9IGluIHRoZSBhc2NlbmRpbmcgc29ydGVkIGFycmF5IHtAY29kZSBhcnJheX0sCisgICAgICogaW4gdGhlIHJhbmdlIHNwZWNpZmllZCBieSBmcm9tSW5kZXggKGluY2x1c2l2ZSkgYW5kIHRvSW5kZXggKGV4Y2x1c2l2ZSkuCisgICAgICogU2VhcmNoaW5nIGluIGFuIHVuc29ydGVkIGFycmF5IGhhcyBhbiB1bmRlZmluZWQgcmVzdWx0LiBJdCdzIGFsc28gdW5kZWZpbmVkIHdoaWNoIGVsZW1lbnQKKyAgICAgKiBpcyBmb3VuZCBpZiB0aGVyZSBhcmUgbXVsdGlwbGUgb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgZWxlbWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheSB0aGUgc29ydGVkIGFycmF5IHRvIHNlYXJjaC4KKyAgICAgKiBAcGFyYW0gc3RhcnRJbmRleCB0aGUgaW5jbHVzaXZlIHN0YXJ0IGluZGV4LgorICAgICAqIEBwYXJhbSBlbmRJbmRleCB0aGUgZXhjbHVzaXZlIHN0YXJ0IGluZGV4LgorICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgZWxlbWVudCB0byBmaW5kLgorICAgICAqIEByZXR1cm4gdGhlIG5vbi1uZWdhdGl2ZSBpbmRleCBvZiB0aGUgZWxlbWVudCwgb3IgYSBuZWdhdGl2ZSBpbmRleCB3aGljaAorICAgICAqICAgICAgICAgaXMge0Bjb2RlIC1pbmRleCAtIDF9IHdoZXJlIHRoZSBlbGVtZW50IHdvdWxkIGJlIGluc2VydGVkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydEluZGV4ID4gZW5kSW5kZXh9CisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYge0Bjb2RlIHN0YXJ0SW5kZXggPCAwIHx8IGVuZEluZGV4ID4gYXJyYXkubGVuZ3RofQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBiaW5hcnlTZWFyY2goZG91YmxlW10gYXJyYXksIGludCBzdGFydEluZGV4LCBpbnQgZW5kSW5kZXgsIGRvdWJsZSB2YWx1ZSkgeworICAgICAgICBjaGVja0JpbmFyeVNlYXJjaEJvdW5kcyhzdGFydEluZGV4LCBlbmRJbmRleCwgYXJyYXkubGVuZ3RoKTsKKyAgICAgICAgaW50IGxvID0gc3RhcnRJbmRleDsKKyAgICAgICAgaW50IGhpID0gZW5kSW5kZXggLSAxOworCisgICAgICAgIHdoaWxlIChsbyA8PSBoaSkgeworICAgICAgICAgICAgaW50IG1pZCA9IChsbyArIGhpKSA+Pj4gMTsKKyAgICAgICAgICAgIGRvdWJsZSBtaWRWYWwgPSBhcnJheVttaWRdOworCisgICAgICAgICAgICBpZiAobWlkVmFsIDwgdmFsdWUpIHsKKyAgICAgICAgICAgICAgICBsbyA9IG1pZCArIDE7CisgICAgICAgICAgICB9IGVsc2UgaWYgKG1pZFZhbCA+IHZhbHVlKSB7CisgICAgICAgICAgICAgICAgaGkgPSBtaWQgLSAxOworICAgICAgICAgICAgfSBlbHNlIGlmIChtaWRWYWwgIT0gMCAmJiBtaWRWYWwgPT0gdmFsdWUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbWlkOyAgLy8gdmFsdWUgZm91bmQKKyAgICAgICAgICAgIH0gZWxzZSB7IC8vIEVpdGhlciBtaWRWYWwgYW5kIHZhbHVlIGFyZSA9PSAwIG9yIGF0IGxlYXN0IG9uZSBpcyBOYU4KKyAgICAgICAgICAgICAgICBsb25nIG1pZFZhbEJpdHMgPSBEb3VibGUuZG91YmxlVG9Mb25nQml0cyhtaWRWYWwpOworICAgICAgICAgICAgICAgIGxvbmcgdmFsdWVCaXRzICA9IERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKHZhbHVlKTsKKworICAgICAgICAgICAgICAgIGlmIChtaWRWYWxCaXRzIDwgdmFsdWVCaXRzKSB7CisgICAgICAgICAgICAgICAgICAgIGxvID0gbWlkICsgMTsgLy8gKC0wLjAsIDAuMCkgb3IgKG5vdCBOYU4sIE5hTik7IG1pZFZhbCA8IHZhbAorICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobWlkVmFsQml0cyA+IHZhbHVlQml0cykgeworICAgICAgICAgICAgICAgICAgICBoaSA9IG1pZCAtIDE7IC8vICgwLjAsIC0wLjApIG9yIChOYU4sIG5vdCBOYU4pOyBtaWRWYWwgPiB2YWwKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWlkOyAvLyBiaXQgcGF0dGVybnMgYXJlIGVxdWFsOyB2YWx1ZSBmb3VuZAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gfmxvOyAgLy8gdmFsdWUgbm90IHByZXNlbnQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggZm9yIHtAY29kZSB2YWx1ZX0gaW4gdGhlIGFzY2VuZGluZyBzb3J0ZWQgYXJyYXkge0Bjb2RlIGFycmF5fS4KKyAgICAgKiBTZWFyY2hpbmcgaW4gYW4gdW5zb3J0ZWQgYXJyYXkgaGFzIGFuIHVuZGVmaW5lZCByZXN1bHQuIEl0J3MgYWxzbyB1bmRlZmluZWQgd2hpY2ggZWxlbWVudAorICAgICAqIGlzIGZvdW5kIGlmIHRoZXJlIGFyZSBtdWx0aXBsZSBvY2N1cnJlbmNlcyBvZiB0aGUgc2FtZSBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5IHRoZSBzb3J0ZWQgYXJyYXkgdG8gc2VhcmNoLgorICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgZWxlbWVudCB0byBmaW5kLgorICAgICAqIEByZXR1cm4gdGhlIG5vbi1uZWdhdGl2ZSBpbmRleCBvZiB0aGUgZWxlbWVudCwgb3IgYSBuZWdhdGl2ZSBpbmRleCB3aGljaAorICAgICAqICAgICAgICAgaXMge0Bjb2RlIC1pbmRleCAtIDF9IHdoZXJlIHRoZSBlbGVtZW50IHdvdWxkIGJlIGluc2VydGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGJpbmFyeVNlYXJjaChmbG9hdFtdIGFycmF5LCBmbG9hdCB2YWx1ZSkgeworICAgICAgICByZXR1cm4gYmluYXJ5U2VhcmNoKGFycmF5LCAwLCBhcnJheS5sZW5ndGgsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggZm9yIHtAY29kZSB2YWx1ZX0gaW4gdGhlIGFzY2VuZGluZyBzb3J0ZWQgYXJyYXkge0Bjb2RlIGFycmF5fSwKKyAgICAgKiBpbiB0aGUgcmFuZ2Ugc3BlY2lmaWVkIGJ5IGZyb21JbmRleCAoaW5jbHVzaXZlKSBhbmQgdG9JbmRleCAoZXhjbHVzaXZlKS4KKyAgICAgKiBTZWFyY2hpbmcgaW4gYW4gdW5zb3J0ZWQgYXJyYXkgaGFzIGFuIHVuZGVmaW5lZCByZXN1bHQuIEl0J3MgYWxzbyB1bmRlZmluZWQgd2hpY2ggZWxlbWVudAorICAgICAqIGlzIGZvdW5kIGlmIHRoZXJlIGFyZSBtdWx0aXBsZSBvY2N1cnJlbmNlcyBvZiB0aGUgc2FtZSBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5IHRoZSBzb3J0ZWQgYXJyYXkgdG8gc2VhcmNoLgorICAgICAqIEBwYXJhbSBzdGFydEluZGV4IHRoZSBpbmNsdXNpdmUgc3RhcnQgaW5kZXguCisgICAgICogQHBhcmFtIGVuZEluZGV4IHRoZSBleGNsdXNpdmUgc3RhcnQgaW5kZXguCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSBlbGVtZW50IHRvIGZpbmQuCisgICAgICogQHJldHVybiB0aGUgbm9uLW5lZ2F0aXZlIGluZGV4IG9mIHRoZSBlbGVtZW50LCBvciBhIG5lZ2F0aXZlIGluZGV4IHdoaWNoCisgICAgICogICAgICAgICBpcyB7QGNvZGUgLWluZGV4IC0gMX0gd2hlcmUgdGhlIGVsZW1lbnQgd291bGQgYmUgaW5zZXJ0ZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHN0YXJ0SW5kZXggPiBlbmRJbmRleH0KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB7QGNvZGUgc3RhcnRJbmRleCA8IDAgfHwgZW5kSW5kZXggPiBhcnJheS5sZW5ndGh9CisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGJpbmFyeVNlYXJjaChmbG9hdFtdIGFycmF5LCBpbnQgc3RhcnRJbmRleCwgaW50IGVuZEluZGV4LCBmbG9hdCB2YWx1ZSkgeworICAgICAgICBjaGVja0JpbmFyeVNlYXJjaEJvdW5kcyhzdGFydEluZGV4LCBlbmRJbmRleCwgYXJyYXkubGVuZ3RoKTsKKyAgICAgICAgaW50IGxvID0gc3RhcnRJbmRleDsKKyAgICAgICAgaW50IGhpID0gZW5kSW5kZXggLSAxOworCisgICAgICAgIHdoaWxlIChsbyA8PSBoaSkgeworICAgICAgICAgICAgaW50IG1pZCA9IChsbyArIGhpKSA+Pj4gMTsKKyAgICAgICAgICAgIGZsb2F0IG1pZFZhbCA9IGFycmF5W21pZF07CisKKyAgICAgICAgICAgIGlmIChtaWRWYWwgPCB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGxvID0gbWlkICsgMTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAobWlkVmFsID4gdmFsdWUpIHsKKyAgICAgICAgICAgICAgICBoaSA9IG1pZCAtIDE7CisgICAgICAgICAgICB9IGVsc2UgaWYgKG1pZFZhbCAhPSAwICYmIG1pZFZhbCA9PSB2YWx1ZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBtaWQ7ICAvLyB2YWx1ZSBmb3VuZAorICAgICAgICAgICAgfSBlbHNlIHsgLy8gRWl0aGVyIG1pZFZhbCBhbmQgdmFsdWUgYXJlID09IDAgb3IgYXQgbGVhc3Qgb25lIGlzIE5hTgorICAgICAgICAgICAgICAgIGludCBtaWRWYWxCaXRzID0gRmxvYXQuZmxvYXRUb0ludEJpdHMobWlkVmFsKTsKKyAgICAgICAgICAgICAgICBpbnQgdmFsdWVCaXRzICA9IEZsb2F0LmZsb2F0VG9JbnRCaXRzKHZhbHVlKTsKKworICAgICAgICAgICAgICAgIGlmIChtaWRWYWxCaXRzIDwgdmFsdWVCaXRzKSB7CisgICAgICAgICAgICAgICAgICAgIGxvID0gbWlkICsgMTsgLy8gKC0wLjAsIDAuMCkgb3IgKG5vdCBOYU4sIE5hTik7IG1pZFZhbCA8IHZhbAorICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobWlkVmFsQml0cyA+IHZhbHVlQml0cykgeworICAgICAgICAgICAgICAgICAgICBoaSA9IG1pZCAtIDE7IC8vICgwLjAsIC0wLjApIG9yIChOYU4sIG5vdCBOYU4pOyBtaWRWYWwgPiB2YWwKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWlkOyAvLyBiaXQgcGF0dGVybnMgYXJlIGVxdWFsOyB2YWx1ZSBmb3VuZAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gfmxvOyAgLy8gdmFsdWUgbm90IHByZXNlbnQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggZm9yIHtAY29kZSB2YWx1ZX0gaW4gdGhlIGFzY2VuZGluZyBzb3J0ZWQgYXJyYXkge0Bjb2RlIGFycmF5fS4KKyAgICAgKiBTZWFyY2hpbmcgaW4gYW4gdW5zb3J0ZWQgYXJyYXkgaGFzIGFuIHVuZGVmaW5lZCByZXN1bHQuIEl0J3MgYWxzbyB1bmRlZmluZWQgd2hpY2ggZWxlbWVudAorICAgICAqIGlzIGZvdW5kIGlmIHRoZXJlIGFyZSBtdWx0aXBsZSBvY2N1cnJlbmNlcyBvZiB0aGUgc2FtZSBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5IHRoZSBzb3J0ZWQgYXJyYXkgdG8gc2VhcmNoLgorICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgZWxlbWVudCB0byBmaW5kLgorICAgICAqIEByZXR1cm4gdGhlIG5vbi1uZWdhdGl2ZSBpbmRleCBvZiB0aGUgZWxlbWVudCwgb3IgYSBuZWdhdGl2ZSBpbmRleCB3aGljaAorICAgICAqICAgICAgICAgaXMge0Bjb2RlIC1pbmRleCAtIDF9IHdoZXJlIHRoZSBlbGVtZW50IHdvdWxkIGJlIGluc2VydGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGJpbmFyeVNlYXJjaChpbnRbXSBhcnJheSwgaW50IHZhbHVlKSB7CisgICAgICAgIHJldHVybiBiaW5hcnlTZWFyY2goYXJyYXksIDAsIGFycmF5Lmxlbmd0aCwgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgYmluYXJ5IHNlYXJjaCBmb3Ige0Bjb2RlIHZhbHVlfSBpbiB0aGUgYXNjZW5kaW5nIHNvcnRlZCBhcnJheSB7QGNvZGUgYXJyYXl9LAorICAgICAqIGluIHRoZSByYW5nZSBzcGVjaWZpZWQgYnkgZnJvbUluZGV4IChpbmNsdXNpdmUpIGFuZCB0b0luZGV4IChleGNsdXNpdmUpLgorICAgICAqIFNlYXJjaGluZyBpbiBhbiB1bnNvcnRlZCBhcnJheSBoYXMgYW4gdW5kZWZpbmVkIHJlc3VsdC4gSXQncyBhbHNvIHVuZGVmaW5lZCB3aGljaCBlbGVtZW50CisgICAgICogaXMgZm91bmQgaWYgdGhlcmUgYXJlIG11bHRpcGxlIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkgdGhlIHNvcnRlZCBhcnJheSB0byBzZWFyY2guCisgICAgICogQHBhcmFtIHN0YXJ0SW5kZXggdGhlIGluY2x1c2l2ZSBzdGFydCBpbmRleC4KKyAgICAgKiBAcGFyYW0gZW5kSW5kZXggdGhlIGV4Y2x1c2l2ZSBzdGFydCBpbmRleC4KKyAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIGVsZW1lbnQgdG8gZmluZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBub24tbmVnYXRpdmUgaW5kZXggb2YgdGhlIGVsZW1lbnQsIG9yIGEgbmVnYXRpdmUgaW5kZXggd2hpY2gKKyAgICAgKiAgICAgICAgIGlzIHtAY29kZSAtaW5kZXggLSAxfSB3aGVyZSB0aGUgZWxlbWVudCB3b3VsZCBiZSBpbnNlcnRlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgc3RhcnRJbmRleCA+IGVuZEluZGV4fQorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydEluZGV4IDwgMCB8fCBlbmRJbmRleCA+IGFycmF5Lmxlbmd0aH0KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgYmluYXJ5U2VhcmNoKGludFtdIGFycmF5LCBpbnQgc3RhcnRJbmRleCwgaW50IGVuZEluZGV4LCBpbnQgdmFsdWUpIHsKKyAgICAgICAgY2hlY2tCaW5hcnlTZWFyY2hCb3VuZHMoc3RhcnRJbmRleCwgZW5kSW5kZXgsIGFycmF5Lmxlbmd0aCk7CisgICAgICAgIGludCBsbyA9IHN0YXJ0SW5kZXg7CisgICAgICAgIGludCBoaSA9IGVuZEluZGV4IC0gMTsKKworICAgICAgICB3aGlsZSAobG8gPD0gaGkpIHsKKyAgICAgICAgICAgIGludCBtaWQgPSAobG8gKyBoaSkgPj4+IDE7CisgICAgICAgICAgICBpbnQgbWlkVmFsID0gYXJyYXlbbWlkXTsKKworICAgICAgICAgICAgaWYgKG1pZFZhbCA8IHZhbHVlKSB7CisgICAgICAgICAgICAgICAgbG8gPSBtaWQgKyAxOworICAgICAgICAgICAgfSBlbHNlIGlmIChtaWRWYWwgPiB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGhpID0gbWlkIC0gMTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG1pZDsgIC8vIHZhbHVlIGZvdW5kCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIH5sbzsgIC8vIHZhbHVlIG5vdCBwcmVzZW50CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBiaW5hcnkgc2VhcmNoIGZvciB7QGNvZGUgdmFsdWV9IGluIHRoZSBhc2NlbmRpbmcgc29ydGVkIGFycmF5IHtAY29kZSBhcnJheX0uCisgICAgICogU2VhcmNoaW5nIGluIGFuIHVuc29ydGVkIGFycmF5IGhhcyBhbiB1bmRlZmluZWQgcmVzdWx0LiBJdCdzIGFsc28gdW5kZWZpbmVkIHdoaWNoIGVsZW1lbnQKKyAgICAgKiBpcyBmb3VuZCBpZiB0aGVyZSBhcmUgbXVsdGlwbGUgb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgZWxlbWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheSB0aGUgc29ydGVkIGFycmF5IHRvIHNlYXJjaC4KKyAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIGVsZW1lbnQgdG8gZmluZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBub24tbmVnYXRpdmUgaW5kZXggb2YgdGhlIGVsZW1lbnQsIG9yIGEgbmVnYXRpdmUgaW5kZXggd2hpY2gKKyAgICAgKiAgICAgICAgIGlzIHtAY29kZSAtaW5kZXggLSAxfSB3aGVyZSB0aGUgZWxlbWVudCB3b3VsZCBiZSBpbnNlcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBiaW5hcnlTZWFyY2gobG9uZ1tdIGFycmF5LCBsb25nIHZhbHVlKSB7CisgICAgICAgIHJldHVybiBiaW5hcnlTZWFyY2goYXJyYXksIDAsIGFycmF5Lmxlbmd0aCwgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgYmluYXJ5IHNlYXJjaCBmb3Ige0Bjb2RlIHZhbHVlfSBpbiB0aGUgYXNjZW5kaW5nIHNvcnRlZCBhcnJheSB7QGNvZGUgYXJyYXl9LAorICAgICAqIGluIHRoZSByYW5nZSBzcGVjaWZpZWQgYnkgZnJvbUluZGV4IChpbmNsdXNpdmUpIGFuZCB0b0luZGV4IChleGNsdXNpdmUpLgorICAgICAqIFNlYXJjaGluZyBpbiBhbiB1bnNvcnRlZCBhcnJheSBoYXMgYW4gdW5kZWZpbmVkIHJlc3VsdC4gSXQncyBhbHNvIHVuZGVmaW5lZCB3aGljaCBlbGVtZW50CisgICAgICogaXMgZm91bmQgaWYgdGhlcmUgYXJlIG11bHRpcGxlIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkgdGhlIHNvcnRlZCBhcnJheSB0byBzZWFyY2guCisgICAgICogQHBhcmFtIHN0YXJ0SW5kZXggdGhlIGluY2x1c2l2ZSBzdGFydCBpbmRleC4KKyAgICAgKiBAcGFyYW0gZW5kSW5kZXggdGhlIGV4Y2x1c2l2ZSBzdGFydCBpbmRleC4KKyAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIGVsZW1lbnQgdG8gZmluZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBub24tbmVnYXRpdmUgaW5kZXggb2YgdGhlIGVsZW1lbnQsIG9yIGEgbmVnYXRpdmUgaW5kZXggd2hpY2gKKyAgICAgKiAgICAgICAgIGlzIHtAY29kZSAtaW5kZXggLSAxfSB3aGVyZSB0aGUgZWxlbWVudCB3b3VsZCBiZSBpbnNlcnRlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgc3RhcnRJbmRleCA+IGVuZEluZGV4fQorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydEluZGV4IDwgMCB8fCBlbmRJbmRleCA+IGFycmF5Lmxlbmd0aH0KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgYmluYXJ5U2VhcmNoKGxvbmdbXSBhcnJheSwgaW50IHN0YXJ0SW5kZXgsIGludCBlbmRJbmRleCwgbG9uZyB2YWx1ZSkgeworICAgICAgICBjaGVja0JpbmFyeVNlYXJjaEJvdW5kcyhzdGFydEluZGV4LCBlbmRJbmRleCwgYXJyYXkubGVuZ3RoKTsKKyAgICAgICAgaW50IGxvID0gc3RhcnRJbmRleDsKKyAgICAgICAgaW50IGhpID0gZW5kSW5kZXggLSAxOworCisgICAgICAgIHdoaWxlIChsbyA8PSBoaSkgeworICAgICAgICAgICAgaW50IG1pZCA9IChsbyArIGhpKSA+Pj4gMTsKKyAgICAgICAgICAgIGxvbmcgbWlkVmFsID0gYXJyYXlbbWlkXTsKKworICAgICAgICAgICAgaWYgKG1pZFZhbCA8IHZhbHVlKSB7CisgICAgICAgICAgICAgICAgbG8gPSBtaWQgKyAxOworICAgICAgICAgICAgfSBlbHNlIGlmIChtaWRWYWwgPiB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGhpID0gbWlkIC0gMTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG1pZDsgIC8vIHZhbHVlIGZvdW5kCisgICAgICAgICAgICB9CisgICAgICAgICB9CisgICAgICAgICByZXR1cm4gfmxvOyAgLy8gdmFsdWUgbm90IHByZXNlbnQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggZm9yIHtAY29kZSB2YWx1ZX0gaW4gdGhlIGFzY2VuZGluZyBzb3J0ZWQgYXJyYXkge0Bjb2RlIGFycmF5fS4KKyAgICAgKiBTZWFyY2hpbmcgaW4gYW4gdW5zb3J0ZWQgYXJyYXkgaGFzIGFuIHVuZGVmaW5lZCByZXN1bHQuIEl0J3MgYWxzbyB1bmRlZmluZWQgd2hpY2ggZWxlbWVudAorICAgICAqIGlzIGZvdW5kIGlmIHRoZXJlIGFyZSBtdWx0aXBsZSBvY2N1cnJlbmNlcyBvZiB0aGUgc2FtZSBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5IHRoZSBzb3J0ZWQgYXJyYXkgdG8gc2VhcmNoLgorICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgZWxlbWVudCB0byBmaW5kLgorICAgICAqIEByZXR1cm4gdGhlIG5vbi1uZWdhdGl2ZSBpbmRleCBvZiB0aGUgZWxlbWVudCwgb3IgYSBuZWdhdGl2ZSBpbmRleCB3aGljaAorICAgICAqICAgICAgICAgaXMge0Bjb2RlIC1pbmRleCAtIDF9IHdoZXJlIHRoZSBlbGVtZW50IHdvdWxkIGJlIGluc2VydGVkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICBpZiBhbiBlbGVtZW50IGluIHRoZSBhcnJheSBvciB0aGUgc2VhcmNoIGVsZW1lbnQgZG9lcyBub3QKKyAgICAgKiAgICAgICAgIGltcGxlbWVudCB7QGNvZGUgQ29tcGFyYWJsZX0sIG9yIGNhbm5vdCBiZSBjb21wYXJlZCB0byBlYWNoIG90aGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGJpbmFyeVNlYXJjaChPYmplY3RbXSBhcnJheSwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIHJldHVybiBiaW5hcnlTZWFyY2goYXJyYXksIDAsIGFycmF5Lmxlbmd0aCwgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgYmluYXJ5IHNlYXJjaCBmb3Ige0Bjb2RlIHZhbHVlfSBpbiB0aGUgYXNjZW5kaW5nIHNvcnRlZCBhcnJheSB7QGNvZGUgYXJyYXl9LAorICAgICAqIGluIHRoZSByYW5nZSBzcGVjaWZpZWQgYnkgZnJvbUluZGV4IChpbmNsdXNpdmUpIGFuZCB0b0luZGV4IChleGNsdXNpdmUpLgorICAgICAqIFNlYXJjaGluZyBpbiBhbiB1bnNvcnRlZCBhcnJheSBoYXMgYW4gdW5kZWZpbmVkIHJlc3VsdC4gSXQncyBhbHNvIHVuZGVmaW5lZCB3aGljaCBlbGVtZW50CisgICAgICogaXMgZm91bmQgaWYgdGhlcmUgYXJlIG11bHRpcGxlIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkgdGhlIHNvcnRlZCBhcnJheSB0byBzZWFyY2guCisgICAgICogQHBhcmFtIHN0YXJ0SW5kZXggdGhlIGluY2x1c2l2ZSBzdGFydCBpbmRleC4KKyAgICAgKiBAcGFyYW0gZW5kSW5kZXggdGhlIGV4Y2x1c2l2ZSBzdGFydCBpbmRleC4KKyAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIGVsZW1lbnQgdG8gZmluZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBub24tbmVnYXRpdmUgaW5kZXggb2YgdGhlIGVsZW1lbnQsIG9yIGEgbmVnYXRpdmUgaW5kZXggd2hpY2gKKyAgICAgKiAgICAgICAgIGlzIHtAY29kZSAtaW5kZXggLSAxfSB3aGVyZSB0aGUgZWxlbWVudCB3b3VsZCBiZSBpbnNlcnRlZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgaWYgYW4gZWxlbWVudCBpbiB0aGUgYXJyYXkgb3IgdGhlIHNlYXJjaCBlbGVtZW50IGRvZXMgbm90CisgICAgICogICAgICAgICBpbXBsZW1lbnQge0Bjb2RlIENvbXBhcmFibGV9LCBvciBjYW5ub3QgYmUgY29tcGFyZWQgdG8gZWFjaCBvdGhlci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgc3RhcnRJbmRleCA+IGVuZEluZGV4fQorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydEluZGV4IDwgMCB8fCBlbmRJbmRleCA+IGFycmF5Lmxlbmd0aH0KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgYmluYXJ5U2VhcmNoKE9iamVjdFtdIGFycmF5LCBpbnQgc3RhcnRJbmRleCwgaW50IGVuZEluZGV4LCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgY2hlY2tCaW5hcnlTZWFyY2hCb3VuZHMoc3RhcnRJbmRleCwgZW5kSW5kZXgsIGFycmF5Lmxlbmd0aCk7CisgICAgICAgIGludCBsbyA9IHN0YXJ0SW5kZXg7CisgICAgICAgIGludCBoaSA9IGVuZEluZGV4IC0gMTsKKworICAgICAgICB3aGlsZSAobG8gPD0gaGkpIHsKKyAgICAgICAgICAgIGludCBtaWQgPSAobG8gKyBoaSkgPj4+IDE7CisgICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgICAgIGludCBtaWRWYWxDbXAgPSAoKENvbXBhcmFibGUpIGFycmF5W21pZF0pLmNvbXBhcmVUbyh2YWx1ZSk7CisKKyAgICAgICAgICAgIGlmIChtaWRWYWxDbXAgPCAwKSB7CisgICAgICAgICAgICAgICAgbG8gPSBtaWQgKyAxOworICAgICAgICAgICAgfSBlbHNlIGlmIChtaWRWYWxDbXAgPiAwKSB7CisgICAgICAgICAgICAgICAgaGkgPSBtaWQgLSAxOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbWlkOyAgLy8gdmFsdWUgZm91bmQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gfmxvOyAgLy8gdmFsdWUgbm90IHByZXNlbnQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggZm9yIHtAY29kZSB2YWx1ZX0gaW4gdGhlIGFzY2VuZGluZyBzb3J0ZWQgYXJyYXkge0Bjb2RlIGFycmF5fSwKKyAgICAgKiB1c2luZyB7QGNvZGUgY29tcGFyYXRvcn0gdG8gY29tcGFyZSBlbGVtZW50cy4KKyAgICAgKiBTZWFyY2hpbmcgaW4gYW4gdW5zb3J0ZWQgYXJyYXkgaGFzIGFuIHVuZGVmaW5lZCByZXN1bHQuIEl0J3MgYWxzbyB1bmRlZmluZWQgd2hpY2ggZWxlbWVudAorICAgICAqIGlzIGZvdW5kIGlmIHRoZXJlIGFyZSBtdWx0aXBsZSBvY2N1cnJlbmNlcyBvZiB0aGUgc2FtZSBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5IHRoZSBzb3J0ZWQgYXJyYXkgdG8gc2VhcmNoLgorICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgZWxlbWVudCB0byBmaW5kLgorICAgICAqIEBwYXJhbSBjb21wYXJhdG9yIHRoZSB7QGNvZGUgQ29tcGFyYXRvcn0gdXNlZCB0byBjb21wYXJlIHRoZSBlbGVtZW50cy4KKyAgICAgKiBAcmV0dXJuIHRoZSBub24tbmVnYXRpdmUgaW5kZXggb2YgdGhlIGVsZW1lbnQsIG9yIGEgbmVnYXRpdmUgaW5kZXggd2hpY2gKKyAgICAgKiAgICAgICAgIGlzIHtAY29kZSAtaW5kZXggLSAxfSB3aGVyZSB0aGUgZWxlbWVudCB3b3VsZCBiZSBpbnNlcnRlZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgaWYgYW4gZWxlbWVudCBpbiB0aGUgYXJyYXkgb3IgdGhlIHNlYXJjaCBlbGVtZW50IGRvZXMgbm90CisgICAgICogICAgICAgICBpbXBsZW1lbnQge0Bjb2RlIENvbXBhcmFibGV9LCBvciBjYW5ub3QgYmUgY29tcGFyZWQgdG8gZWFjaCBvdGhlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUPiBpbnQgYmluYXJ5U2VhcmNoKFRbXSBhcnJheSwgVCB2YWx1ZSwgQ29tcGFyYXRvcjw/IHN1cGVyIFQ+IGNvbXBhcmF0b3IpIHsKKyAgICAgICAgcmV0dXJuIGJpbmFyeVNlYXJjaChhcnJheSwgMCwgYXJyYXkubGVuZ3RoLCB2YWx1ZSwgY29tcGFyYXRvcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBiaW5hcnkgc2VhcmNoIGZvciB7QGNvZGUgdmFsdWV9IGluIHRoZSBhc2NlbmRpbmcgc29ydGVkIGFycmF5IHtAY29kZSBhcnJheX0sCisgICAgICogaW4gdGhlIHJhbmdlIHNwZWNpZmllZCBieSBmcm9tSW5kZXggKGluY2x1c2l2ZSkgYW5kIHRvSW5kZXggKGV4Y2x1c2l2ZSksCisgICAgICogdXNpbmcge0Bjb2RlIGNvbXBhcmF0b3J9IHRvIGNvbXBhcmUgZWxlbWVudHMuCisgICAgICogU2VhcmNoaW5nIGluIGFuIHVuc29ydGVkIGFycmF5IGhhcyBhbiB1bmRlZmluZWQgcmVzdWx0LiBJdCdzIGFsc28gdW5kZWZpbmVkIHdoaWNoIGVsZW1lbnQKKyAgICAgKiBpcyBmb3VuZCBpZiB0aGVyZSBhcmUgbXVsdGlwbGUgb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgZWxlbWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheSB0aGUgc29ydGVkIGFycmF5IHRvIHNlYXJjaC4KKyAgICAgKiBAcGFyYW0gc3RhcnRJbmRleCB0aGUgaW5jbHVzaXZlIHN0YXJ0IGluZGV4LgorICAgICAqIEBwYXJhbSBlbmRJbmRleCB0aGUgZXhjbHVzaXZlIHN0YXJ0IGluZGV4LgorICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgZWxlbWVudCB0byBmaW5kLgorICAgICAqIEBwYXJhbSBjb21wYXJhdG9yIHRoZSB7QGNvZGUgQ29tcGFyYXRvcn0gdXNlZCB0byBjb21wYXJlIHRoZSBlbGVtZW50cy4KKyAgICAgKiBAcmV0dXJuIHRoZSBub24tbmVnYXRpdmUgaW5kZXggb2YgdGhlIGVsZW1lbnQsIG9yIGEgbmVnYXRpdmUgaW5kZXggd2hpY2gKKyAgICAgKiAgICAgICAgIGlzIHtAY29kZSAtaW5kZXggLSAxfSB3aGVyZSB0aGUgZWxlbWVudCB3b3VsZCBiZSBpbnNlcnRlZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgaWYgYW4gZWxlbWVudCBpbiB0aGUgYXJyYXkgb3IgdGhlIHNlYXJjaCBlbGVtZW50IGRvZXMgbm90CisgICAgICogICAgICAgICBpbXBsZW1lbnQge0Bjb2RlIENvbXBhcmFibGV9LCBvciBjYW5ub3QgYmUgY29tcGFyZWQgdG8gZWFjaCBvdGhlci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgc3RhcnRJbmRleCA+IGVuZEluZGV4fQorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydEluZGV4IDwgMCB8fCBlbmRJbmRleCA+IGFycmF5Lmxlbmd0aH0KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8VD4gaW50IGJpbmFyeVNlYXJjaChUW10gYXJyYXksIGludCBzdGFydEluZGV4LCBpbnQgZW5kSW5kZXgsIFQgdmFsdWUsCisgICAgICAgICAgICBDb21wYXJhdG9yPD8gc3VwZXIgVD4gY29tcGFyYXRvcikgeworICAgICAgICBpZiAoY29tcGFyYXRvciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gYmluYXJ5U2VhcmNoKGFycmF5LCBzdGFydEluZGV4LCBlbmRJbmRleCwgdmFsdWUpOworICAgICAgICB9CisKKyAgICAgICAgY2hlY2tCaW5hcnlTZWFyY2hCb3VuZHMoc3RhcnRJbmRleCwgZW5kSW5kZXgsIGFycmF5Lmxlbmd0aCk7CisgICAgICAgIGludCBsbyA9IHN0YXJ0SW5kZXg7CisgICAgICAgIGludCBoaSA9IGVuZEluZGV4IC0gMTsKKworICAgICAgICB3aGlsZSAobG8gPD0gaGkpIHsKKyAgICAgICAgICAgIGludCBtaWQgPSAobG8gKyBoaSkgPj4+IDE7CisgICAgICAgICAgICBpbnQgbWlkVmFsQ21wID0gY29tcGFyYXRvci5jb21wYXJlKGFycmF5W21pZF0sIHZhbHVlKTsKKworICAgICAgICAgICAgaWYgKG1pZFZhbENtcCA8IDApIHsKKyAgICAgICAgICAgICAgICBsbyA9IG1pZCArIDE7CisgICAgICAgICAgICB9IGVsc2UgaWYgKG1pZFZhbENtcCA+IDApIHsKKyAgICAgICAgICAgICAgICBoaSA9IG1pZCAtIDE7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBtaWQ7ICAvLyB2YWx1ZSBmb3VuZAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB+bG87ICAvLyB2YWx1ZSBub3QgcHJlc2VudAorICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgYmluYXJ5IHNlYXJjaCBmb3Ige0Bjb2RlIHZhbHVlfSBpbiB0aGUgYXNjZW5kaW5nIHNvcnRlZCBhcnJheSB7QGNvZGUgYXJyYXl9LgorICAgICAqIFNlYXJjaGluZyBpbiBhbiB1bnNvcnRlZCBhcnJheSBoYXMgYW4gdW5kZWZpbmVkIHJlc3VsdC4gSXQncyBhbHNvIHVuZGVmaW5lZCB3aGljaCBlbGVtZW50CisgICAgICogaXMgZm91bmQgaWYgdGhlcmUgYXJlIG11bHRpcGxlIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkgdGhlIHNvcnRlZCBhcnJheSB0byBzZWFyY2guCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSBlbGVtZW50IHRvIGZpbmQuCisgICAgICogQHJldHVybiB0aGUgbm9uLW5lZ2F0aXZlIGluZGV4IG9mIHRoZSBlbGVtZW50LCBvciBhIG5lZ2F0aXZlIGluZGV4IHdoaWNoCisgICAgICogICAgICAgICBpcyB7QGNvZGUgLWluZGV4IC0gMX0gd2hlcmUgdGhlIGVsZW1lbnQgd291bGQgYmUgaW5zZXJ0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgYmluYXJ5U2VhcmNoKHNob3J0W10gYXJyYXksIHNob3J0IHZhbHVlKSB7CisgICAgICAgIHJldHVybiBiaW5hcnlTZWFyY2goYXJyYXksIDAsIGFycmF5Lmxlbmd0aCwgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgYmluYXJ5IHNlYXJjaCBmb3Ige0Bjb2RlIHZhbHVlfSBpbiB0aGUgYXNjZW5kaW5nIHNvcnRlZCBhcnJheSB7QGNvZGUgYXJyYXl9LAorICAgICAqIGluIHRoZSByYW5nZSBzcGVjaWZpZWQgYnkgZnJvbUluZGV4IChpbmNsdXNpdmUpIGFuZCB0b0luZGV4IChleGNsdXNpdmUpLgorICAgICAqIFNlYXJjaGluZyBpbiBhbiB1bnNvcnRlZCBhcnJheSBoYXMgYW4gdW5kZWZpbmVkIHJlc3VsdC4gSXQncyBhbHNvIHVuZGVmaW5lZCB3aGljaCBlbGVtZW50CisgICAgICogaXMgZm91bmQgaWYgdGhlcmUgYXJlIG11bHRpcGxlIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkgdGhlIHNvcnRlZCBhcnJheSB0byBzZWFyY2guCisgICAgICogQHBhcmFtIHN0YXJ0SW5kZXggdGhlIGluY2x1c2l2ZSBzdGFydCBpbmRleC4KKyAgICAgKiBAcGFyYW0gZW5kSW5kZXggdGhlIGV4Y2x1c2l2ZSBzdGFydCBpbmRleC4KKyAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIGVsZW1lbnQgdG8gZmluZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBub24tbmVnYXRpdmUgaW5kZXggb2YgdGhlIGVsZW1lbnQsIG9yIGEgbmVnYXRpdmUgaW5kZXggd2hpY2gKKyAgICAgKiAgICAgICAgIGlzIHtAY29kZSAtaW5kZXggLSAxfSB3aGVyZSB0aGUgZWxlbWVudCB3b3VsZCBiZSBpbnNlcnRlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgc3RhcnRJbmRleCA+IGVuZEluZGV4fQorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydEluZGV4IDwgMCB8fCBlbmRJbmRleCA+IGFycmF5Lmxlbmd0aH0KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgYmluYXJ5U2VhcmNoKHNob3J0W10gYXJyYXksIGludCBzdGFydEluZGV4LCBpbnQgZW5kSW5kZXgsIHNob3J0IHZhbHVlKSB7CisgICAgICAgIGNoZWNrQmluYXJ5U2VhcmNoQm91bmRzKHN0YXJ0SW5kZXgsIGVuZEluZGV4LCBhcnJheS5sZW5ndGgpOworICAgICAgICBpbnQgbG8gPSBzdGFydEluZGV4OworICAgICAgICBpbnQgaGkgPSBlbmRJbmRleCAtIDE7CisKKyAgICAgICAgd2hpbGUgKGxvIDw9IGhpKSB7CisgICAgICAgICAgICBpbnQgbWlkID0gKGxvICsgaGkpID4+PiAxOworICAgICAgICAgICAgc2hvcnQgbWlkVmFsID0gYXJyYXlbbWlkXTsKKworICAgICAgICAgICAgaWYgKG1pZFZhbCA8IHZhbHVlKSB7CisgICAgICAgICAgICAgICAgbG8gPSBtaWQgKyAxOworICAgICAgICAgICAgfSBlbHNlIGlmIChtaWRWYWwgPiB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGhpID0gbWlkIC0gMTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG1pZDsgIC8vIHZhbHVlIGZvdW5kCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIH5sbzsgIC8vIHZhbHVlIG5vdCBwcmVzZW50CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja0JpbmFyeVNlYXJjaEJvdW5kcyhpbnQgc3RhcnRJbmRleCwgaW50IGVuZEluZGV4LCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIGlmIChzdGFydEluZGV4ID4gZW5kSW5kZXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3RhcnRJbmRleCA8IDAgfHwgZW5kSW5kZXggPiBsZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbGxzIHRoZSBzcGVjaWZpZWQgYXJyYXkgd2l0aCB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgYnl0ZX0gYXJyYXkgdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgYnl0ZX0gZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmlsbChieXRlW10gYXJyYXksIGJ5dGUgdmFsdWUpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXJyYXlbaV0gPSB2YWx1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbGxzIHRoZSBzcGVjaWZpZWQgcmFuZ2UgaW4gdGhlIGFycmF5IHdpdGggdGhlIHNwZWNpZmllZCBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGJ5dGV9IGFycmF5IHRvIGZpbGwuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgaW5kZXggdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgbGFzdCArIDEgaW5kZXggdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgYnl0ZX0gZWxlbWVudC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA+IGVuZH0uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwfSBvciB7QGNvZGUgZW5kID4gYXJyYXkubGVuZ3RofS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmlsbChieXRlW10gYXJyYXksIGludCBzdGFydCwgaW50IGVuZCwgYnl0ZSB2YWx1ZSkgeworICAgICAgICBBcnJheXMuY2hlY2tTdGFydEFuZEVuZChhcnJheS5sZW5ndGgsIHN0YXJ0LCBlbmQpOworICAgICAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykgeworICAgICAgICAgICAgYXJyYXlbaV0gPSB2YWx1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbGxzIHRoZSBzcGVjaWZpZWQgYXJyYXkgd2l0aCB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgc2hvcnR9IGFycmF5IHRvIGZpbGwuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIHNob3J0fSBlbGVtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBmaWxsKHNob3J0W10gYXJyYXksIHNob3J0IHZhbHVlKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFycmF5W2ldID0gdmFsdWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaWxscyB0aGUgc3BlY2lmaWVkIHJhbmdlIGluIHRoZSBhcnJheSB3aXRoIHRoZSBzcGVjaWZpZWQgZWxlbWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBzaG9ydH0gYXJyYXkgdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBpbmRleCB0byBmaWxsLgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsYXN0ICsgMSBpbmRleCB0byBmaWxsLgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBzaG9ydH0gZWxlbWVudC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA+IGVuZH0uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwfSBvciB7QGNvZGUgZW5kID4gYXJyYXkubGVuZ3RofS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmlsbChzaG9ydFtdIGFycmF5LCBpbnQgc3RhcnQsIGludCBlbmQsIHNob3J0IHZhbHVlKSB7CisgICAgICAgIEFycmF5cy5jaGVja1N0YXJ0QW5kRW5kKGFycmF5Lmxlbmd0aCwgc3RhcnQsIGVuZCk7CisgICAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7CisgICAgICAgICAgICBhcnJheVtpXSA9IHZhbHVlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsbHMgdGhlIHNwZWNpZmllZCBhcnJheSB3aXRoIHRoZSBzcGVjaWZpZWQgZWxlbWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBjaGFyfSBhcnJheSB0byBmaWxsLgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBjaGFyfSBlbGVtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBmaWxsKGNoYXJbXSBhcnJheSwgY2hhciB2YWx1ZSkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhcnJheVtpXSA9IHZhbHVlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsbHMgdGhlIHNwZWNpZmllZCByYW5nZSBpbiB0aGUgYXJyYXkgd2l0aCB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgY2hhcn0gYXJyYXkgdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBpbmRleCB0byBmaWxsLgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsYXN0ICsgMSBpbmRleCB0byBmaWxsLgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBjaGFyfSBlbGVtZW50LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0ID4gZW5kfS4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA8IDB9IG9yIHtAY29kZSBlbmQgPiBhcnJheS5sZW5ndGh9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBmaWxsKGNoYXJbXSBhcnJheSwgaW50IHN0YXJ0LCBpbnQgZW5kLCBjaGFyIHZhbHVlKSB7CisgICAgICAgIEFycmF5cy5jaGVja1N0YXJ0QW5kRW5kKGFycmF5Lmxlbmd0aCwgc3RhcnQsIGVuZCk7CisgICAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7CisgICAgICAgICAgICBhcnJheVtpXSA9IHZhbHVlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsbHMgdGhlIHNwZWNpZmllZCBhcnJheSB3aXRoIHRoZSBzcGVjaWZpZWQgZWxlbWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBpbnR9IGFycmF5IHRvIGZpbGwuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGludH0gZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmlsbChpbnRbXSBhcnJheSwgaW50IHZhbHVlKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFycmF5W2ldID0gdmFsdWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaWxscyB0aGUgc3BlY2lmaWVkIHJhbmdlIGluIHRoZSBhcnJheSB3aXRoIHRoZSBzcGVjaWZpZWQgZWxlbWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBpbnR9IGFycmF5IHRvIGZpbGwuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgaW5kZXggdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgbGFzdCArIDEgaW5kZXggdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgaW50fSBlbGVtZW50LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0ID4gZW5kfS4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA8IDB9IG9yIHtAY29kZSBlbmQgPiBhcnJheS5sZW5ndGh9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBmaWxsKGludFtdIGFycmF5LCBpbnQgc3RhcnQsIGludCBlbmQsIGludCB2YWx1ZSkgeworICAgICAgICBBcnJheXMuY2hlY2tTdGFydEFuZEVuZChhcnJheS5sZW5ndGgsIHN0YXJ0LCBlbmQpOworICAgICAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykgeworICAgICAgICAgICAgYXJyYXlbaV0gPSB2YWx1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbGxzIHRoZSBzcGVjaWZpZWQgYXJyYXkgd2l0aCB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgbG9uZ30gYXJyYXkgdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgbG9uZ30gZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmlsbChsb25nW10gYXJyYXksIGxvbmcgdmFsdWUpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXJyYXlbaV0gPSB2YWx1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbGxzIHRoZSBzcGVjaWZpZWQgcmFuZ2UgaW4gdGhlIGFycmF5IHdpdGggdGhlIHNwZWNpZmllZCBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGxvbmd9IGFycmF5IHRvIGZpbGwuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgaW5kZXggdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgbGFzdCArIDEgaW5kZXggdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgbG9uZ30gZWxlbWVudC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA+IGVuZH0uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwfSBvciB7QGNvZGUgZW5kID4gYXJyYXkubGVuZ3RofS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmlsbChsb25nW10gYXJyYXksIGludCBzdGFydCwgaW50IGVuZCwgbG9uZyB2YWx1ZSkgeworICAgICAgICBBcnJheXMuY2hlY2tTdGFydEFuZEVuZChhcnJheS5sZW5ndGgsIHN0YXJ0LCBlbmQpOworICAgICAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykgeworICAgICAgICAgICAgYXJyYXlbaV0gPSB2YWx1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbGxzIHRoZSBzcGVjaWZpZWQgYXJyYXkgd2l0aCB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgZmxvYXR9IGFycmF5IHRvIGZpbGwuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGZsb2F0fSBlbGVtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBmaWxsKGZsb2F0W10gYXJyYXksIGZsb2F0IHZhbHVlKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFycmF5W2ldID0gdmFsdWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaWxscyB0aGUgc3BlY2lmaWVkIHJhbmdlIGluIHRoZSBhcnJheSB3aXRoIHRoZSBzcGVjaWZpZWQgZWxlbWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBmbG9hdH0gYXJyYXkgdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBpbmRleCB0byBmaWxsLgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsYXN0ICsgMSBpbmRleCB0byBmaWxsLgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBmbG9hdH0gZWxlbWVudC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA+IGVuZH0uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwfSBvciB7QGNvZGUgZW5kID4gYXJyYXkubGVuZ3RofS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmlsbChmbG9hdFtdIGFycmF5LCBpbnQgc3RhcnQsIGludCBlbmQsIGZsb2F0IHZhbHVlKSB7CisgICAgICAgIEFycmF5cy5jaGVja1N0YXJ0QW5kRW5kKGFycmF5Lmxlbmd0aCwgc3RhcnQsIGVuZCk7CisgICAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7CisgICAgICAgICAgICBhcnJheVtpXSA9IHZhbHVlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsbHMgdGhlIHNwZWNpZmllZCBhcnJheSB3aXRoIHRoZSBzcGVjaWZpZWQgZWxlbWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBkb3VibGV9IGFycmF5IHRvIGZpbGwuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGRvdWJsZX0gZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmlsbChkb3VibGVbXSBhcnJheSwgZG91YmxlIHZhbHVlKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFycmF5W2ldID0gdmFsdWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaWxscyB0aGUgc3BlY2lmaWVkIHJhbmdlIGluIHRoZSBhcnJheSB3aXRoIHRoZSBzcGVjaWZpZWQgZWxlbWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBkb3VibGV9IGFycmF5IHRvIGZpbGwuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgaW5kZXggdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgbGFzdCArIDEgaW5kZXggdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgZG91YmxlfSBlbGVtZW50LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0ID4gZW5kfS4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA8IDB9IG9yIHtAY29kZSBlbmQgPiBhcnJheS5sZW5ndGh9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBmaWxsKGRvdWJsZVtdIGFycmF5LCBpbnQgc3RhcnQsIGludCBlbmQsIGRvdWJsZSB2YWx1ZSkgeworICAgICAgICBBcnJheXMuY2hlY2tTdGFydEFuZEVuZChhcnJheS5sZW5ndGgsIHN0YXJ0LCBlbmQpOworICAgICAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykgeworICAgICAgICAgICAgYXJyYXlbaV0gPSB2YWx1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbGxzIHRoZSBzcGVjaWZpZWQgYXJyYXkgd2l0aCB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgYm9vbGVhbn0gYXJyYXkgdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgYm9vbGVhbn0gZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmlsbChib29sZWFuW10gYXJyYXksIGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXJyYXlbaV0gPSB2YWx1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbGxzIHRoZSBzcGVjaWZpZWQgcmFuZ2UgaW4gdGhlIGFycmF5IHdpdGggdGhlIHNwZWNpZmllZCBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGJvb2xlYW59IGFycmF5IHRvIGZpbGwuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgaW5kZXggdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgbGFzdCArIDEgaW5kZXggdG8gZmlsbC4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgYm9vbGVhbn0gZWxlbWVudC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA+IGVuZH0uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwfSBvciB7QGNvZGUgZW5kID4gYXJyYXkubGVuZ3RofS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmlsbChib29sZWFuW10gYXJyYXksIGludCBzdGFydCwgaW50IGVuZCwgYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICBBcnJheXMuY2hlY2tTdGFydEFuZEVuZChhcnJheS5sZW5ndGgsIHN0YXJ0LCBlbmQpOworICAgICAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykgeworICAgICAgICAgICAgYXJyYXlbaV0gPSB2YWx1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbGxzIHRoZSBzcGVjaWZpZWQgYXJyYXkgd2l0aCB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT2JqZWN0fSBhcnJheSB0byBmaWxsLgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBPYmplY3R9IGVsZW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGZpbGwoT2JqZWN0W10gYXJyYXksIE9iamVjdCB2YWx1ZSkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhcnJheVtpXSA9IHZhbHVlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsbHMgdGhlIHNwZWNpZmllZCByYW5nZSBpbiB0aGUgYXJyYXkgd2l0aCB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT2JqZWN0fSBhcnJheSB0byBmaWxsLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IGluZGV4IHRvIGZpbGwuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGxhc3QgKyAxIGluZGV4IHRvIGZpbGwuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIE9iamVjdH0gZWxlbWVudC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA+IGVuZH0uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwfSBvciB7QGNvZGUgZW5kID4gYXJyYXkubGVuZ3RofS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmlsbChPYmplY3RbXSBhcnJheSwgaW50IHN0YXJ0LCBpbnQgZW5kLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrU3RhcnRBbmRFbmQoYXJyYXkubGVuZ3RoLCBzdGFydCwgZW5kKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHsKKyAgICAgICAgICAgIGFycmF5W2ldID0gdmFsdWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgaGFzaCBjb2RlIGJhc2VkIG9uIHRoZSBjb250ZW50cyBvZiB0aGUgZ2l2ZW4gYXJyYXkuIEZvciBhbnkgdHdvCisgICAgICoge0Bjb2RlIGJvb2xlYW59IGFycmF5cyB7QGNvZGUgYX0gYW5kIHtAY29kZSBifSwgaWYKKyAgICAgKiB7QGNvZGUgQXJyYXlzLmVxdWFscyhhLCBiKX0gcmV0dXJucyB7QGNvZGUgdHJ1ZX0sIGl0IG1lYW5zCisgICAgICogdGhhdCB0aGUgcmV0dXJuIHZhbHVlIG9mIHtAY29kZSBBcnJheXMuaGFzaENvZGUoYSl9IGVxdWFscyB7QGNvZGUgQXJyYXlzLmhhc2hDb2RlKGIpfS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QgaXMgdGhlIHNhbWUgdmFsdWUgYXMgdGhlCisgICAgICoge0BsaW5rIExpc3QjaGFzaENvZGUoKX0gbWV0aG9kIHdoaWNoIGlzIGludm9rZWQgb24gYSB7QGxpbmsgTGlzdH0KKyAgICAgKiBjb250YWluaW5nIGEgc2VxdWVuY2Ugb2Yge0BsaW5rIEJvb2xlYW59IGluc3RhbmNlcyByZXByZXNlbnRpbmcgdGhlCisgICAgICogZWxlbWVudHMgb2YgYXJyYXkgaW4gdGhlIHNhbWUgb3JkZXIuIElmIHRoZSBhcnJheSBpcyB7QGNvZGUgbnVsbH0sIHRoZSByZXR1cm4KKyAgICAgKiB2YWx1ZSBpcyAwLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgd2hvc2UgaGFzaCBjb2RlIHRvIGNvbXB1dGUuCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIGZvciB7QGNvZGUgYXJyYXl9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGhhc2hDb2RlKGJvb2xlYW5bXSBhcnJheSkgeworICAgICAgICBpZiAoYXJyYXkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgaW50IGhhc2hDb2RlID0gMTsKKyAgICAgICAgZm9yIChib29sZWFuIGVsZW1lbnQgOiBhcnJheSkgeworICAgICAgICAgICAgLy8gMTIzMSwgMTIzNyBhcmUgaGFzaCBjb2RlIHZhbHVlcyBmb3IgYm9vbGVhbiB2YWx1ZQorICAgICAgICAgICAgaGFzaENvZGUgPSAzMSAqIGhhc2hDb2RlICsgKGVsZW1lbnQgPyAxMjMxIDogMTIzNyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGhhc2hDb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBoYXNoIGNvZGUgYmFzZWQgb24gdGhlIGNvbnRlbnRzIG9mIHRoZSBnaXZlbiBhcnJheS4gRm9yIGFueSB0d28KKyAgICAgKiBub3QtbnVsbCB7QGNvZGUgaW50fSBhcnJheXMge0Bjb2RlIGF9IGFuZCB7QGNvZGUgYn0sIGlmCisgICAgICoge0Bjb2RlIEFycmF5cy5lcXVhbHMoYSwgYil9IHJldHVybnMge0Bjb2RlIHRydWV9LCBpdCBtZWFucworICAgICAqIHRoYXQgdGhlIHJldHVybiB2YWx1ZSBvZiB7QGNvZGUgQXJyYXlzLmhhc2hDb2RlKGEpfSBlcXVhbHMge0Bjb2RlIEFycmF5cy5oYXNoQ29kZShiKX0uCisgICAgICogPHA+CisgICAgICogVGhlIHZhbHVlIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIGlzIHRoZSBzYW1lIHZhbHVlIGFzIHRoZQorICAgICAqIHtAbGluayBMaXN0I2hhc2hDb2RlKCl9IG1ldGhvZCB3aGljaCBpcyBpbnZva2VkIG9uIGEge0BsaW5rIExpc3R9CisgICAgICogY29udGFpbmluZyBhIHNlcXVlbmNlIG9mIHtAbGluayBJbnRlZ2VyfSBpbnN0YW5jZXMgcmVwcmVzZW50aW5nIHRoZQorICAgICAqIGVsZW1lbnRzIG9mIGFycmF5IGluIHRoZSBzYW1lIG9yZGVyLiBJZiB0aGUgYXJyYXkgaXMge0Bjb2RlIG51bGx9LCB0aGUgcmV0dXJuCisgICAgICogdmFsdWUgaXMgMC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IHdob3NlIGhhc2ggY29kZSB0byBjb21wdXRlLgorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZSBmb3Ige0Bjb2RlIGFycmF5fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBoYXNoQ29kZShpbnRbXSBhcnJheSkgeworICAgICAgICBpZiAoYXJyYXkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgaW50IGhhc2hDb2RlID0gMTsKKyAgICAgICAgZm9yIChpbnQgZWxlbWVudCA6IGFycmF5KSB7CisgICAgICAgICAgICAvLyB0aGUgaGFzaCBjb2RlIHZhbHVlIGZvciBpbnRlZ2VyIHZhbHVlIGlzIGludGVnZXIgdmFsdWUgaXRzZWxmCisgICAgICAgICAgICBoYXNoQ29kZSA9IDMxICogaGFzaENvZGUgKyBlbGVtZW50OworICAgICAgICB9CisgICAgICAgIHJldHVybiBoYXNoQ29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgaGFzaCBjb2RlIGJhc2VkIG9uIHRoZSBjb250ZW50cyBvZiB0aGUgZ2l2ZW4gYXJyYXkuIEZvciBhbnkgdHdvCisgICAgICoge0Bjb2RlIHNob3J0fSBhcnJheXMge0Bjb2RlIGF9IGFuZCB7QGNvZGUgYn0sIGlmCisgICAgICoge0Bjb2RlIEFycmF5cy5lcXVhbHMoYSwgYil9IHJldHVybnMge0Bjb2RlIHRydWV9LCBpdCBtZWFucworICAgICAqIHRoYXQgdGhlIHJldHVybiB2YWx1ZSBvZiB7QGNvZGUgQXJyYXlzLmhhc2hDb2RlKGEpfSBlcXVhbHMge0Bjb2RlIEFycmF5cy5oYXNoQ29kZShiKX0uCisgICAgICogPHA+CisgICAgICogVGhlIHZhbHVlIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIGlzIHRoZSBzYW1lIHZhbHVlIGFzIHRoZQorICAgICAqIHtAbGluayBMaXN0I2hhc2hDb2RlKCl9IG1ldGhvZCB3aGljaCBpcyBpbnZva2VkIG9uIGEge0BsaW5rIExpc3R9CisgICAgICogY29udGFpbmluZyBhIHNlcXVlbmNlIG9mIHtAbGluayBTaG9ydH0gaW5zdGFuY2VzIHJlcHJlc2VudGluZyB0aGUKKyAgICAgKiBlbGVtZW50cyBvZiBhcnJheSBpbiB0aGUgc2FtZSBvcmRlci4gSWYgdGhlIGFycmF5IGlzIHtAY29kZSBudWxsfSwgdGhlIHJldHVybgorICAgICAqIHZhbHVlIGlzIDAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSB3aG9zZSBoYXNoIGNvZGUgdG8gY29tcHV0ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUgZm9yIHtAY29kZSBhcnJheX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgaGFzaENvZGUoc2hvcnRbXSBhcnJheSkgeworICAgICAgICBpZiAoYXJyYXkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgaW50IGhhc2hDb2RlID0gMTsKKyAgICAgICAgZm9yIChzaG9ydCBlbGVtZW50IDogYXJyYXkpIHsKKyAgICAgICAgICAgIC8vIHRoZSBoYXNoIGNvZGUgdmFsdWUgZm9yIHNob3J0IHZhbHVlIGlzIGl0cyBpbnRlZ2VyIHZhbHVlCisgICAgICAgICAgICBoYXNoQ29kZSA9IDMxICogaGFzaENvZGUgKyBlbGVtZW50OworICAgICAgICB9CisgICAgICAgIHJldHVybiBoYXNoQ29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgaGFzaCBjb2RlIGJhc2VkIG9uIHRoZSBjb250ZW50cyBvZiB0aGUgZ2l2ZW4gYXJyYXkuIEZvciBhbnkgdHdvCisgICAgICoge0Bjb2RlIGNoYXJ9IGFycmF5cyB7QGNvZGUgYX0gYW5kIHtAY29kZSBifSwgaWYKKyAgICAgKiB7QGNvZGUgQXJyYXlzLmVxdWFscyhhLCBiKX0gcmV0dXJucyB7QGNvZGUgdHJ1ZX0sIGl0IG1lYW5zCisgICAgICogdGhhdCB0aGUgcmV0dXJuIHZhbHVlIG9mIHtAY29kZSBBcnJheXMuaGFzaENvZGUoYSl9IGVxdWFscyB7QGNvZGUgQXJyYXlzLmhhc2hDb2RlKGIpfS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QgaXMgdGhlIHNhbWUgdmFsdWUgYXMgdGhlCisgICAgICoge0BsaW5rIExpc3QjaGFzaENvZGUoKX0gbWV0aG9kIHdoaWNoIGlzIGludm9rZWQgb24gYSB7QGxpbmsgTGlzdH0KKyAgICAgKiBjb250YWluaW5nIGEgc2VxdWVuY2Ugb2Yge0BsaW5rIENoYXJhY3Rlcn0gaW5zdGFuY2VzIHJlcHJlc2VudGluZyB0aGUKKyAgICAgKiBlbGVtZW50cyBvZiBhcnJheSBpbiB0aGUgc2FtZSBvcmRlci4gSWYgdGhlIGFycmF5IGlzIHtAY29kZSBudWxsfSwgdGhlIHJldHVybgorICAgICAqIHZhbHVlIGlzIDAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSB3aG9zZSBoYXNoIGNvZGUgdG8gY29tcHV0ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUgZm9yIHtAY29kZSBhcnJheX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgaGFzaENvZGUoY2hhcltdIGFycmF5KSB7CisgICAgICAgIGlmIChhcnJheSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICBpbnQgaGFzaENvZGUgPSAxOworICAgICAgICBmb3IgKGNoYXIgZWxlbWVudCA6IGFycmF5KSB7CisgICAgICAgICAgICAvLyB0aGUgaGFzaCBjb2RlIHZhbHVlIGZvciBjaGFyIHZhbHVlIGlzIGl0cyBpbnRlZ2VyIHZhbHVlCisgICAgICAgICAgICBoYXNoQ29kZSA9IDMxICogaGFzaENvZGUgKyBlbGVtZW50OworICAgICAgICB9CisgICAgICAgIHJldHVybiBoYXNoQ29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgaGFzaCBjb2RlIGJhc2VkIG9uIHRoZSBjb250ZW50cyBvZiB0aGUgZ2l2ZW4gYXJyYXkuIEZvciBhbnkgdHdvCisgICAgICoge0Bjb2RlIGJ5dGV9IGFycmF5cyB7QGNvZGUgYX0gYW5kIHtAY29kZSBifSwgaWYKKyAgICAgKiB7QGNvZGUgQXJyYXlzLmVxdWFscyhhLCBiKX0gcmV0dXJucyB7QGNvZGUgdHJ1ZX0sIGl0IG1lYW5zCisgICAgICogdGhhdCB0aGUgcmV0dXJuIHZhbHVlIG9mIHtAY29kZSBBcnJheXMuaGFzaENvZGUoYSl9IGVxdWFscyB7QGNvZGUgQXJyYXlzLmhhc2hDb2RlKGIpfS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QgaXMgdGhlIHNhbWUgdmFsdWUgYXMgdGhlCisgICAgICoge0BsaW5rIExpc3QjaGFzaENvZGUoKX0gbWV0aG9kIHdoaWNoIGlzIGludm9rZWQgb24gYSB7QGxpbmsgTGlzdH0KKyAgICAgKiBjb250YWluaW5nIGEgc2VxdWVuY2Ugb2Yge0BsaW5rIEJ5dGV9IGluc3RhbmNlcyByZXByZXNlbnRpbmcgdGhlCisgICAgICogZWxlbWVudHMgb2YgYXJyYXkgaW4gdGhlIHNhbWUgb3JkZXIuIElmIHRoZSBhcnJheSBpcyB7QGNvZGUgbnVsbH0sIHRoZSByZXR1cm4KKyAgICAgKiB2YWx1ZSBpcyAwLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgd2hvc2UgaGFzaCBjb2RlIHRvIGNvbXB1dGUuCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIGZvciB7QGNvZGUgYXJyYXl9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGhhc2hDb2RlKGJ5dGVbXSBhcnJheSkgeworICAgICAgICBpZiAoYXJyYXkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgaW50IGhhc2hDb2RlID0gMTsKKyAgICAgICAgZm9yIChieXRlIGVsZW1lbnQgOiBhcnJheSkgeworICAgICAgICAgICAgLy8gdGhlIGhhc2ggY29kZSB2YWx1ZSBmb3IgYnl0ZSB2YWx1ZSBpcyBpdHMgaW50ZWdlciB2YWx1ZQorICAgICAgICAgICAgaGFzaENvZGUgPSAzMSAqIGhhc2hDb2RlICsgZWxlbWVudDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzaENvZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGhhc2ggY29kZSBiYXNlZCBvbiB0aGUgY29udGVudHMgb2YgdGhlIGdpdmVuIGFycmF5LiBGb3IgYW55IHR3bworICAgICAqIHtAY29kZSBsb25nfSBhcnJheXMge0Bjb2RlIGF9IGFuZCB7QGNvZGUgYn0sIGlmCisgICAgICoge0Bjb2RlIEFycmF5cy5lcXVhbHMoYSwgYil9IHJldHVybnMge0Bjb2RlIHRydWV9LCBpdCBtZWFucworICAgICAqIHRoYXQgdGhlIHJldHVybiB2YWx1ZSBvZiB7QGNvZGUgQXJyYXlzLmhhc2hDb2RlKGEpfSBlcXVhbHMge0Bjb2RlIEFycmF5cy5oYXNoQ29kZShiKX0uCisgICAgICogPHA+CisgICAgICogVGhlIHZhbHVlIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIGlzIHRoZSBzYW1lIHZhbHVlIGFzIHRoZQorICAgICAqIHtAbGluayBMaXN0I2hhc2hDb2RlKCl9IG1ldGhvZCB3aGljaCBpcyBpbnZva2VkIG9uIGEge0BsaW5rIExpc3R9CisgICAgICogY29udGFpbmluZyBhIHNlcXVlbmNlIG9mIHtAbGluayBMb25nfSBpbnN0YW5jZXMgcmVwcmVzZW50aW5nIHRoZQorICAgICAqIGVsZW1lbnRzIG9mIGFycmF5IGluIHRoZSBzYW1lIG9yZGVyLiBJZiB0aGUgYXJyYXkgaXMge0Bjb2RlIG51bGx9LCB0aGUgcmV0dXJuCisgICAgICogdmFsdWUgaXMgMC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IHdob3NlIGhhc2ggY29kZSB0byBjb21wdXRlLgorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZSBmb3Ige0Bjb2RlIGFycmF5fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBoYXNoQ29kZShsb25nW10gYXJyYXkpIHsKKyAgICAgICAgaWYgKGFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGludCBoYXNoQ29kZSA9IDE7CisgICAgICAgIGZvciAobG9uZyBlbGVtZW50VmFsdWUgOiBhcnJheSkgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIHRoZSBoYXNoIGNvZGUgdmFsdWUgZm9yIGxvbmcgdmFsdWUgaXMgKGludCkgKHZhbHVlIF4gKHZhbHVlID4+PgorICAgICAgICAgICAgICogMzIpKQorICAgICAgICAgICAgICovCisgICAgICAgICAgICBoYXNoQ29kZSA9IDMxICogaGFzaENvZGUKKyAgICAgICAgICAgICAgICAgICAgKyAoaW50KSAoZWxlbWVudFZhbHVlIF4gKGVsZW1lbnRWYWx1ZSA+Pj4gMzIpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzaENvZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGhhc2ggY29kZSBiYXNlZCBvbiB0aGUgY29udGVudHMgb2YgdGhlIGdpdmVuIGFycmF5LiBGb3IgYW55IHR3bworICAgICAqIHtAY29kZSBmbG9hdH0gYXJyYXlzIHtAY29kZSBhfSBhbmQge0Bjb2RlIGJ9LCBpZgorICAgICAqIHtAY29kZSBBcnJheXMuZXF1YWxzKGEsIGIpfSByZXR1cm5zIHtAY29kZSB0cnVlfSwgaXQgbWVhbnMKKyAgICAgKiB0aGF0IHRoZSByZXR1cm4gdmFsdWUgb2Yge0Bjb2RlIEFycmF5cy5oYXNoQ29kZShhKX0gZXF1YWxzIHtAY29kZSBBcnJheXMuaGFzaENvZGUoYil9LgorICAgICAqIDxwPgorICAgICAqIFRoZSB2YWx1ZSByZXR1cm5lZCBieSB0aGlzIG1ldGhvZCBpcyB0aGUgc2FtZSB2YWx1ZSBhcyB0aGUKKyAgICAgKiB7QGxpbmsgTGlzdCNoYXNoQ29kZSgpfSBtZXRob2Qgd2hpY2ggaXMgaW52b2tlZCBvbiBhIHtAbGluayBMaXN0fQorICAgICAqIGNvbnRhaW5pbmcgYSBzZXF1ZW5jZSBvZiB7QGxpbmsgRmxvYXR9IGluc3RhbmNlcyByZXByZXNlbnRpbmcgdGhlCisgICAgICogZWxlbWVudHMgb2YgYXJyYXkgaW4gdGhlIHNhbWUgb3JkZXIuIElmIHRoZSBhcnJheSBpcyB7QGNvZGUgbnVsbH0sIHRoZSByZXR1cm4KKyAgICAgKiB2YWx1ZSBpcyAwLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgd2hvc2UgaGFzaCBjb2RlIHRvIGNvbXB1dGUuCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIGZvciB7QGNvZGUgYXJyYXl9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGhhc2hDb2RlKGZsb2F0W10gYXJyYXkpIHsKKyAgICAgICAgaWYgKGFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGludCBoYXNoQ29kZSA9IDE7CisgICAgICAgIGZvciAoZmxvYXQgZWxlbWVudCA6IGFycmF5KSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogdGhlIGhhc2ggY29kZSB2YWx1ZSBmb3IgZmxvYXQgdmFsdWUgaXMKKyAgICAgICAgICAgICAqIEZsb2F0LmZsb2F0VG9JbnRCaXRzKHZhbHVlKQorICAgICAgICAgICAgICovCisgICAgICAgICAgICBoYXNoQ29kZSA9IDMxICogaGFzaENvZGUgKyBGbG9hdC5mbG9hdFRvSW50Qml0cyhlbGVtZW50KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzaENvZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGhhc2ggY29kZSBiYXNlZCBvbiB0aGUgY29udGVudHMgb2YgdGhlIGdpdmVuIGFycmF5LiBGb3IgYW55IHR3bworICAgICAqIHtAY29kZSBkb3VibGV9IGFycmF5cyB7QGNvZGUgYX0gYW5kIHtAY29kZSBifSwgaWYKKyAgICAgKiB7QGNvZGUgQXJyYXlzLmVxdWFscyhhLCBiKX0gcmV0dXJucyB7QGNvZGUgdHJ1ZX0sIGl0IG1lYW5zCisgICAgICogdGhhdCB0aGUgcmV0dXJuIHZhbHVlIG9mIHtAY29kZSBBcnJheXMuaGFzaENvZGUoYSl9IGVxdWFscyB7QGNvZGUgQXJyYXlzLmhhc2hDb2RlKGIpfS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QgaXMgdGhlIHNhbWUgdmFsdWUgYXMgdGhlCisgICAgICoge0BsaW5rIExpc3QjaGFzaENvZGUoKX0gbWV0aG9kIHdoaWNoIGlzIGludm9rZWQgb24gYSB7QGxpbmsgTGlzdH0KKyAgICAgKiBjb250YWluaW5nIGEgc2VxdWVuY2Ugb2Yge0BsaW5rIERvdWJsZX0gaW5zdGFuY2VzIHJlcHJlc2VudGluZyB0aGUKKyAgICAgKiBlbGVtZW50cyBvZiBhcnJheSBpbiB0aGUgc2FtZSBvcmRlci4gSWYgdGhlIGFycmF5IGlzIHtAY29kZSBudWxsfSwgdGhlIHJldHVybgorICAgICAqIHZhbHVlIGlzIDAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSB3aG9zZSBoYXNoIGNvZGUgdG8gY29tcHV0ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUgZm9yIHtAY29kZSBhcnJheX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgaGFzaENvZGUoZG91YmxlW10gYXJyYXkpIHsKKyAgICAgICAgaWYgKGFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGludCBoYXNoQ29kZSA9IDE7CisKKyAgICAgICAgZm9yIChkb3VibGUgZWxlbWVudCA6IGFycmF5KSB7CisgICAgICAgICAgICBsb25nIHYgPSBEb3VibGUuZG91YmxlVG9Mb25nQml0cyhlbGVtZW50KTsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiB0aGUgaGFzaCBjb2RlIHZhbHVlIGZvciBkb3VibGUgdmFsdWUgaXMgKGludCkgKHYgXiAodiA+Pj4gMzIpKQorICAgICAgICAgICAgICogd2hlcmUgdiA9IERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKHZhbHVlKQorICAgICAgICAgICAgICovCisgICAgICAgICAgICBoYXNoQ29kZSA9IDMxICogaGFzaENvZGUgKyAoaW50KSAodiBeICh2ID4+PiAzMikpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBoYXNoQ29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgaGFzaCBjb2RlIGJhc2VkIG9uIHRoZSBjb250ZW50cyBvZiB0aGUgZ2l2ZW4gYXJyYXkuIElmIHRoZQorICAgICAqIGFycmF5IGNvbnRhaW5zIG90aGVyIGFycmF5cyBhcyBpdHMgZWxlbWVudHMsIHRoZSBoYXNoIGNvZGUgaXMgYmFzZWQgb24KKyAgICAgKiB0aGVpciBpZGVudGl0aWVzIG5vdCB0aGVpciBjb250ZW50cy4gU28gaXQgaXMgYWNjZXB0YWJsZSB0byBpbnZva2UgdGhpcworICAgICAqIG1ldGhvZCBvbiBhbiBhcnJheSB0aGF0IGNvbnRhaW5zIGl0c2VsZiBhcyBhbiBlbGVtZW50LCBlaXRoZXIgZGlyZWN0bHkgb3IKKyAgICAgKiBpbmRpcmVjdGx5LgorICAgICAqIDxwPgorICAgICAqIEZvciBhbnkgdHdvIGFycmF5cyB7QGNvZGUgYX0gYW5kIHtAY29kZSBifSwgaWYKKyAgICAgKiB7QGNvZGUgQXJyYXlzLmVxdWFscyhhLCBiKX0gcmV0dXJucyB7QGNvZGUgdHJ1ZX0sIGl0IG1lYW5zCisgICAgICogdGhhdCB0aGUgcmV0dXJuIHZhbHVlIG9mIHtAY29kZSBBcnJheXMuaGFzaENvZGUoYSl9IGVxdWFscworICAgICAqIHtAY29kZSBBcnJheXMuaGFzaENvZGUoYil9LgorICAgICAqIDxwPgorICAgICAqIFRoZSB2YWx1ZSByZXR1cm5lZCBieSB0aGlzIG1ldGhvZCBpcyB0aGUgc2FtZSB2YWx1ZSBhcyB0aGUgbWV0aG9kCisgICAgICogQXJyYXlzLmFzTGlzdChhcnJheSkuaGFzaENvZGUoKS4gSWYgdGhlIGFycmF5IGlzIHtAY29kZSBudWxsfSwgdGhlIHJldHVybiB2YWx1ZQorICAgICAqIGlzIDAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSB3aG9zZSBoYXNoIGNvZGUgdG8gY29tcHV0ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUgZm9yIHtAY29kZSBhcnJheX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgaGFzaENvZGUoT2JqZWN0W10gYXJyYXkpIHsKKyAgICAgICAgaWYgKGFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGludCBoYXNoQ29kZSA9IDE7CisgICAgICAgIGZvciAoT2JqZWN0IGVsZW1lbnQgOiBhcnJheSkgeworICAgICAgICAgICAgaW50IGVsZW1lbnRIYXNoQ29kZTsKKworICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGVsZW1lbnRIYXNoQ29kZSA9IDA7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGVsZW1lbnRIYXNoQ29kZSA9IChlbGVtZW50KS5oYXNoQ29kZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaGFzaENvZGUgPSAzMSAqIGhhc2hDb2RlICsgZWxlbWVudEhhc2hDb2RlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBoYXNoQ29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgaGFzaCBjb2RlIGJhc2VkIG9uIHRoZSAiZGVlcCBjb250ZW50cyIgb2YgdGhlIGdpdmVuIGFycmF5LiBJZgorICAgICAqIHRoZSBhcnJheSBjb250YWlucyBvdGhlciBhcnJheXMgYXMgaXRzIGVsZW1lbnRzLCB0aGUgaGFzaCBjb2RlIGlzIGJhc2VkCisgICAgICogb24gdGhlaXIgY29udGVudHMgbm90IHRoZWlyIGlkZW50aXRpZXMuIFNvIGl0IGlzIG5vdCBhY2NlcHRhYmxlIHRvIGludm9rZQorICAgICAqIHRoaXMgbWV0aG9kIG9uIGFuIGFycmF5IHRoYXQgY29udGFpbnMgaXRzZWxmIGFzIGFuIGVsZW1lbnQsIGVpdGhlcgorICAgICAqIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkuCisgICAgICogPHA+CisgICAgICogRm9yIGFueSB0d28gYXJyYXlzIHtAY29kZSBhfSBhbmQge0Bjb2RlIGJ9LCBpZgorICAgICAqIHtAY29kZSBBcnJheXMuZGVlcEVxdWFscyhhLCBiKX0gcmV0dXJucyB7QGNvZGUgdHJ1ZX0sIGl0CisgICAgICogbWVhbnMgdGhhdCB0aGUgcmV0dXJuIHZhbHVlIG9mIHtAY29kZSBBcnJheXMuZGVlcEhhc2hDb2RlKGEpfSBlcXVhbHMKKyAgICAgKiB7QGNvZGUgQXJyYXlzLmRlZXBIYXNoQ29kZShiKX0uCisgICAgICogPHA+CisgICAgICogVGhlIGNvbXB1dGF0aW9uIG9mIHRoZSB2YWx1ZSByZXR1cm5lZCBieSB0aGlzIG1ldGhvZCBpcyBzaW1pbGFyIHRvIHRoYXQKKyAgICAgKiBvZiB0aGUgdmFsdWUgcmV0dXJuZWQgYnkge0BsaW5rIExpc3QjaGFzaENvZGUoKX0gaW52b2tlZCBvbiBhCisgICAgICoge0BsaW5rIExpc3R9IGNvbnRhaW5pbmcgYSBzZXF1ZW5jZSBvZiBpbnN0YW5jZXMgcmVwcmVzZW50aW5nIHRoZQorICAgICAqIGVsZW1lbnRzIG9mIGFycmF5IGluIHRoZSBzYW1lIG9yZGVyLiBUaGUgZGlmZmVyZW5jZSBpczogSWYgYW4gZWxlbWVudCBlCisgICAgICogb2YgYXJyYXkgaXMgaXRzZWxmIGFuIGFycmF5LCBpdHMgaGFzaCBjb2RlIGlzIGNvbXB1dGVkIGJ5IGNhbGxpbmcgdGhlCisgICAgICogYXBwcm9wcmlhdGUgb3ZlcmxvYWRpbmcgb2Yge0Bjb2RlIEFycmF5cy5oYXNoQ29kZShlKX0gaWYgZSBpcyBhbiBhcnJheSBvZiBhCisgICAgICogcHJpbWl0aXZlIHR5cGUsIG9yIGJ5IGNhbGxpbmcge0Bjb2RlIEFycmF5cy5kZWVwSGFzaENvZGUoZSl9IHJlY3Vyc2l2ZWx5IGlmIGUgaXMKKyAgICAgKiBhbiBhcnJheSBvZiBhIHJlZmVyZW5jZSB0eXBlLiBUaGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QgaXMgdGhlCisgICAgICogc2FtZSB2YWx1ZSBhcyB0aGUgbWV0aG9kIHtAY29kZSBBcnJheXMuYXNMaXN0KGFycmF5KS5oYXNoQ29kZSgpfS4gSWYgdGhlIGFycmF5IGlzCisgICAgICoge0Bjb2RlIG51bGx9LCB0aGUgcmV0dXJuIHZhbHVlIGlzIDAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSB3aG9zZSBoYXNoIGNvZGUgdG8gY29tcHV0ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUgZm9yIHtAY29kZSBhcnJheX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZGVlcEhhc2hDb2RlKE9iamVjdFtdIGFycmF5KSB7CisgICAgICAgIGlmIChhcnJheSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICBpbnQgaGFzaENvZGUgPSAxOworICAgICAgICBmb3IgKE9iamVjdCBlbGVtZW50IDogYXJyYXkpIHsKKyAgICAgICAgICAgIGludCBlbGVtZW50SGFzaENvZGUgPSBkZWVwSGFzaENvZGVFbGVtZW50KGVsZW1lbnQpOworICAgICAgICAgICAgaGFzaENvZGUgPSAzMSAqIGhhc2hDb2RlICsgZWxlbWVudEhhc2hDb2RlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBoYXNoQ29kZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgZGVlcEhhc2hDb2RlRWxlbWVudChPYmplY3QgZWxlbWVudCkgeworICAgICAgICBDbGFzczw/PiBjbDsKKyAgICAgICAgaWYgKGVsZW1lbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBjbCA9IGVsZW1lbnQuZ2V0Q2xhc3MoKS5nZXRDb21wb25lbnRUeXBlKCk7CisKKyAgICAgICAgaWYgKGNsID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBlbGVtZW50Lmhhc2hDb2RlKCk7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBlbGVtZW50IGlzIGFuIGFycmF5CisgICAgICAgICAqLworICAgICAgICBpZiAoIWNsLmlzUHJpbWl0aXZlKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBkZWVwSGFzaENvZGUoKE9iamVjdFtdKSBlbGVtZW50KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2wuZXF1YWxzKGludC5jbGFzcykpIHsKKyAgICAgICAgICAgIHJldHVybiBoYXNoQ29kZSgoaW50W10pIGVsZW1lbnQpOworICAgICAgICB9CisgICAgICAgIGlmIChjbC5lcXVhbHMoY2hhci5jbGFzcykpIHsKKyAgICAgICAgICAgIHJldHVybiBoYXNoQ29kZSgoY2hhcltdKSBlbGVtZW50KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2wuZXF1YWxzKGJvb2xlYW4uY2xhc3MpKSB7CisgICAgICAgICAgICByZXR1cm4gaGFzaENvZGUoKGJvb2xlYW5bXSkgZWxlbWVudCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNsLmVxdWFscyhieXRlLmNsYXNzKSkgeworICAgICAgICAgICAgcmV0dXJuIGhhc2hDb2RlKChieXRlW10pIGVsZW1lbnQpOworICAgICAgICB9CisgICAgICAgIGlmIChjbC5lcXVhbHMobG9uZy5jbGFzcykpIHsKKyAgICAgICAgICAgIHJldHVybiBoYXNoQ29kZSgobG9uZ1tdKSBlbGVtZW50KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2wuZXF1YWxzKGZsb2F0LmNsYXNzKSkgeworICAgICAgICAgICAgcmV0dXJuIGhhc2hDb2RlKChmbG9hdFtdKSBlbGVtZW50KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2wuZXF1YWxzKGRvdWJsZS5jbGFzcykpIHsKKyAgICAgICAgICAgIHJldHVybiBoYXNoQ29kZSgoZG91YmxlW10pIGVsZW1lbnQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBoYXNoQ29kZSgoc2hvcnRbXSkgZWxlbWVudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHR3byBhcnJheXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkxCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3Qge0Bjb2RlIGJ5dGV9IGFycmF5LgorICAgICAqIEBwYXJhbSBhcnJheTIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQge0Bjb2RlIGJ5dGV9IGFycmF5LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGJvdGggYXJyYXlzIGFyZSB7QGNvZGUgbnVsbH0gb3IgaWYgdGhlIGFycmF5cyBoYXZlIHRoZQorICAgICAqICAgICAgICAgc2FtZSBsZW5ndGggYW5kIHRoZSBlbGVtZW50cyBhdCBlYWNoIGluZGV4IGluIHRoZSB0d28gYXJyYXlzIGFyZQorICAgICAqICAgICAgICAgZXF1YWwsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBlcXVhbHMoYnl0ZVtdIGFycmF5MSwgYnl0ZVtdIGFycmF5MikgeworICAgICAgICBpZiAoYXJyYXkxID09IGFycmF5MikgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFycmF5MSA9PSBudWxsIHx8IGFycmF5MiA9PSBudWxsIHx8IGFycmF5MS5sZW5ndGggIT0gYXJyYXkyLmxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkxLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYXJyYXkxW2ldICE9IGFycmF5MltpXSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgdHdvIGFycmF5cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheTEKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCB7QGNvZGUgc2hvcnR9IGFycmF5LgorICAgICAqIEBwYXJhbSBhcnJheTIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQge0Bjb2RlIHNob3J0fSBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBib3RoIGFycmF5cyBhcmUge0Bjb2RlIG51bGx9IG9yIGlmIHRoZSBhcnJheXMgaGF2ZSB0aGUKKyAgICAgKiAgICAgICAgIHNhbWUgbGVuZ3RoIGFuZCB0aGUgZWxlbWVudHMgYXQgZWFjaCBpbmRleCBpbiB0aGUgdHdvIGFycmF5cyBhcmUKKyAgICAgKiAgICAgICAgIGVxdWFsLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZXF1YWxzKHNob3J0W10gYXJyYXkxLCBzaG9ydFtdIGFycmF5MikgeworICAgICAgICBpZiAoYXJyYXkxID09IGFycmF5MikgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFycmF5MSA9PSBudWxsIHx8IGFycmF5MiA9PSBudWxsIHx8IGFycmF5MS5sZW5ndGggIT0gYXJyYXkyLmxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkxLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYXJyYXkxW2ldICE9IGFycmF5MltpXSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgdHdvIGFycmF5cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheTEKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCB7QGNvZGUgY2hhcn0gYXJyYXkuCisgICAgICogQHBhcmFtIGFycmF5MgorICAgICAqICAgICAgICAgICAgdGhlIHNlY29uZCB7QGNvZGUgY2hhcn0gYXJyYXkuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYm90aCBhcnJheXMgYXJlIHtAY29kZSBudWxsfSBvciBpZiB0aGUgYXJyYXlzIGhhdmUgdGhlCisgICAgICogICAgICAgICBzYW1lIGxlbmd0aCBhbmQgdGhlIGVsZW1lbnRzIGF0IGVhY2ggaW5kZXggaW4gdGhlIHR3byBhcnJheXMgYXJlCisgICAgICogICAgICAgICBlcXVhbCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGVxdWFscyhjaGFyW10gYXJyYXkxLCBjaGFyW10gYXJyYXkyKSB7CisgICAgICAgIGlmIChhcnJheTEgPT0gYXJyYXkyKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYXJyYXkxID09IG51bGwgfHwgYXJyYXkyID09IG51bGwgfHwgYXJyYXkxLmxlbmd0aCAhPSBhcnJheTIubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheTEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChhcnJheTFbaV0gIT0gYXJyYXkyW2ldKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSB0d28gYXJyYXlzLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5MQorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IHtAY29kZSBpbnR9IGFycmF5LgorICAgICAqIEBwYXJhbSBhcnJheTIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQge0Bjb2RlIGludH0gYXJyYXkuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYm90aCBhcnJheXMgYXJlIHtAY29kZSBudWxsfSBvciBpZiB0aGUgYXJyYXlzIGhhdmUgdGhlCisgICAgICogICAgICAgICBzYW1lIGxlbmd0aCBhbmQgdGhlIGVsZW1lbnRzIGF0IGVhY2ggaW5kZXggaW4gdGhlIHR3byBhcnJheXMgYXJlCisgICAgICogICAgICAgICBlcXVhbCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGVxdWFscyhpbnRbXSBhcnJheTEsIGludFtdIGFycmF5MikgeworICAgICAgICBpZiAoYXJyYXkxID09IGFycmF5MikgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFycmF5MSA9PSBudWxsIHx8IGFycmF5MiA9PSBudWxsIHx8IGFycmF5MS5sZW5ndGggIT0gYXJyYXkyLmxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkxLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYXJyYXkxW2ldICE9IGFycmF5MltpXSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgdHdvIGFycmF5cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheTEKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCB7QGNvZGUgbG9uZ30gYXJyYXkuCisgICAgICogQHBhcmFtIGFycmF5MgorICAgICAqICAgICAgICAgICAgdGhlIHNlY29uZCB7QGNvZGUgbG9uZ30gYXJyYXkuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYm90aCBhcnJheXMgYXJlIHtAY29kZSBudWxsfSBvciBpZiB0aGUgYXJyYXlzIGhhdmUgdGhlCisgICAgICogICAgICAgICBzYW1lIGxlbmd0aCBhbmQgdGhlIGVsZW1lbnRzIGF0IGVhY2ggaW5kZXggaW4gdGhlIHR3byBhcnJheXMgYXJlCisgICAgICogICAgICAgICBlcXVhbCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGVxdWFscyhsb25nW10gYXJyYXkxLCBsb25nW10gYXJyYXkyKSB7CisgICAgICAgIGlmIChhcnJheTEgPT0gYXJyYXkyKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYXJyYXkxID09IG51bGwgfHwgYXJyYXkyID09IG51bGwgfHwgYXJyYXkxLmxlbmd0aCAhPSBhcnJheTIubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheTEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChhcnJheTFbaV0gIT0gYXJyYXkyW2ldKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSB0d28gYXJyYXlzLiBUaGUgdmFsdWVzIGFyZSBjb21wYXJlZCBpbiB0aGUgc2FtZSBtYW5uZXIgYXMKKyAgICAgKiB7QGNvZGUgRmxvYXQuZXF1YWxzKCl9LgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5MQorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IHtAY29kZSBmbG9hdH0gYXJyYXkuCisgICAgICogQHBhcmFtIGFycmF5MgorICAgICAqICAgICAgICAgICAgdGhlIHNlY29uZCB7QGNvZGUgZmxvYXR9IGFycmF5LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGJvdGggYXJyYXlzIGFyZSB7QGNvZGUgbnVsbH0gb3IgaWYgdGhlIGFycmF5cyBoYXZlIHRoZQorICAgICAqICAgICAgICAgc2FtZSBsZW5ndGggYW5kIHRoZSBlbGVtZW50cyBhdCBlYWNoIGluZGV4IGluIHRoZSB0d28gYXJyYXlzIGFyZQorICAgICAqICAgICAgICAgZXF1YWwsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgRmxvYXQjZXF1YWxzKE9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZXF1YWxzKGZsb2F0W10gYXJyYXkxLCBmbG9hdFtdIGFycmF5MikgeworICAgICAgICBpZiAoYXJyYXkxID09IGFycmF5MikgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFycmF5MSA9PSBudWxsIHx8IGFycmF5MiA9PSBudWxsIHx8IGFycmF5MS5sZW5ndGggIT0gYXJyYXkyLmxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkxLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoRmxvYXQuZmxvYXRUb0ludEJpdHMoYXJyYXkxW2ldKSAhPSBGbG9hdAorICAgICAgICAgICAgICAgICAgICAuZmxvYXRUb0ludEJpdHMoYXJyYXkyW2ldKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgdHdvIGFycmF5cy4gVGhlIHZhbHVlcyBhcmUgY29tcGFyZWQgaW4gdGhlIHNhbWUgbWFubmVyIGFzCisgICAgICoge0Bjb2RlIERvdWJsZS5lcXVhbHMoKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkxCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3Qge0Bjb2RlIGRvdWJsZX0gYXJyYXkuCisgICAgICogQHBhcmFtIGFycmF5MgorICAgICAqICAgICAgICAgICAgdGhlIHNlY29uZCB7QGNvZGUgZG91YmxlfSBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBib3RoIGFycmF5cyBhcmUge0Bjb2RlIG51bGx9IG9yIGlmIHRoZSBhcnJheXMgaGF2ZSB0aGUKKyAgICAgKiAgICAgICAgIHNhbWUgbGVuZ3RoIGFuZCB0aGUgZWxlbWVudHMgYXQgZWFjaCBpbmRleCBpbiB0aGUgdHdvIGFycmF5cyBhcmUKKyAgICAgKiAgICAgICAgIGVxdWFsLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlIERvdWJsZSNlcXVhbHMoT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBlcXVhbHMoZG91YmxlW10gYXJyYXkxLCBkb3VibGVbXSBhcnJheTIpIHsKKyAgICAgICAgaWYgKGFycmF5MSA9PSBhcnJheTIpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChhcnJheTEgPT0gbnVsbCB8fCBhcnJheTIgPT0gbnVsbCB8fCBhcnJheTEubGVuZ3RoICE9IGFycmF5Mi5sZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFycmF5MS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGFycmF5MVtpXSkgIT0gRG91YmxlCisgICAgICAgICAgICAgICAgICAgIC5kb3VibGVUb0xvbmdCaXRzKGFycmF5MltpXSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHR3byBhcnJheXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkxCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3Qge0Bjb2RlIGJvb2xlYW59IGFycmF5LgorICAgICAqIEBwYXJhbSBhcnJheTIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQge0Bjb2RlIGJvb2xlYW59IGFycmF5LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGJvdGggYXJyYXlzIGFyZSB7QGNvZGUgbnVsbH0gb3IgaWYgdGhlIGFycmF5cyBoYXZlIHRoZQorICAgICAqICAgICAgICAgc2FtZSBsZW5ndGggYW5kIHRoZSBlbGVtZW50cyBhdCBlYWNoIGluZGV4IGluIHRoZSB0d28gYXJyYXlzIGFyZQorICAgICAqICAgICAgICAgZXF1YWwsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBlcXVhbHMoYm9vbGVhbltdIGFycmF5MSwgYm9vbGVhbltdIGFycmF5MikgeworICAgICAgICBpZiAoYXJyYXkxID09IGFycmF5MikgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFycmF5MSA9PSBudWxsIHx8IGFycmF5MiA9PSBudWxsIHx8IGFycmF5MS5sZW5ndGggIT0gYXJyYXkyLmxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkxLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYXJyYXkxW2ldICE9IGFycmF5MltpXSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgdHdvIGFycmF5cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheTEKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCB7QGNvZGUgT2JqZWN0fSBhcnJheS4KKyAgICAgKiBAcGFyYW0gYXJyYXkyCisgICAgICogICAgICAgICAgICB0aGUgc2Vjb25kIHtAY29kZSBPYmplY3R9IGFycmF5LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGJvdGggYXJyYXlzIGFyZSB7QGNvZGUgbnVsbH0gb3IgaWYgdGhlIGFycmF5cyBoYXZlIHRoZQorICAgICAqICAgICAgICAgc2FtZSBsZW5ndGggYW5kIHRoZSBlbGVtZW50cyBhdCBlYWNoIGluZGV4IGluIHRoZSB0d28gYXJyYXlzIGFyZQorICAgICAqICAgICAgICAgZXF1YWwgYWNjb3JkaW5nIHRvIHtAY29kZSBlcXVhbHMoKX0sIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0W10gYXJyYXkxLCBPYmplY3RbXSBhcnJheTIpIHsKKyAgICAgICAgaWYgKGFycmF5MSA9PSBhcnJheTIpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChhcnJheTEgPT0gbnVsbCB8fCBhcnJheTIgPT0gbnVsbCB8fCBhcnJheTEubGVuZ3RoICE9IGFycmF5Mi5sZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFycmF5MS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgT2JqZWN0IGUxID0gYXJyYXkxW2ldLCBlMiA9IGFycmF5MltpXTsKKyAgICAgICAgICAgIGlmICghKGUxID09IG51bGwgPyBlMiA9PSBudWxsIDogZTEuZXF1YWxzKGUyKSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHR3byBnaXZlbiBhcnJheXMgYXJlIGRlZXBseSBlcXVhbCB0byBvbmUgYW5vdGhlci4KKyAgICAgKiBVbmxpa2UgdGhlIG1ldGhvZCB7QGNvZGUgZXF1YWxzKE9iamVjdFtdIGFycmF5MSwgT2JqZWN0W10gYXJyYXkyKX0sIHRoaXMgbWV0aG9kCisgICAgICogaXMgYXBwcm9wcmlhdGUgZm9yIHVzZSBmb3IgbmVzdGVkIGFycmF5cyBvZiBhcmJpdHJhcnkgZGVwdGguCisgICAgICogPHA+CisgICAgICogVHdvIGFycmF5IHJlZmVyZW5jZXMgYXJlIGNvbnNpZGVyZWQgZGVlcGx5IGVxdWFsIGlmIHRoZXkgYXJlIGJvdGgge0Bjb2RlIG51bGx9LAorICAgICAqIG9yIGlmIHRoZXkgcmVmZXIgdG8gYXJyYXlzIHRoYXQgaGF2ZSB0aGUgc2FtZSBsZW5ndGggYW5kIHRoZSBlbGVtZW50cyBhdAorICAgICAqIGVhY2ggaW5kZXggaW4gdGhlIHR3byBhcnJheXMgYXJlIGVxdWFsLgorICAgICAqIDxwPgorICAgICAqIFR3byB7QGNvZGUgbnVsbH0gZWxlbWVudHMge0Bjb2RlIGVsZW1lbnQxfSBhbmQge0Bjb2RlIGVsZW1lbnQyfSBhcmUgcG9zc2libHkgZGVlcGx5IGVxdWFsIGlmIGFueQorICAgICAqIG9mIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBzYXRpc2ZpZWQ6CisgICAgICogPHA+CisgICAgICoge0Bjb2RlIGVsZW1lbnQxfSBhbmQge0Bjb2RlIGVsZW1lbnQyfSBhcmUgYm90aCBhcnJheXMgb2Ygb2JqZWN0IHJlZmVyZW5jZSB0eXBlcywgYW5kCisgICAgICoge0Bjb2RlIEFycmF5cy5kZWVwRXF1YWxzKGVsZW1lbnQxLCBlbGVtZW50Mil9IHdvdWxkIHJldHVybiB7QGNvZGUgdHJ1ZX0uCisgICAgICogPHA+CisgICAgICoge0Bjb2RlIGVsZW1lbnQxfSBhbmQge0Bjb2RlIGVsZW1lbnQyfSBhcmUgYXJyYXlzIG9mIHRoZSBzYW1lIHByaW1pdGl2ZSB0eXBlLCBhbmQgdGhlCisgICAgICogYXBwcm9wcmlhdGUgb3ZlcmxvYWRpbmcgb2Yge0Bjb2RlIEFycmF5cy5lcXVhbHMoZWxlbWVudDEsIGVsZW1lbnQyKX0gd291bGQgcmV0dXJuCisgICAgICoge0Bjb2RlIHRydWV9LgorICAgICAqIDxwPgorICAgICAqIHtAY29kZSBlbGVtZW50MSA9PSBlbGVtZW50Mn0KKyAgICAgKiA8cD4KKyAgICAgKiB7QGNvZGUgZWxlbWVudDEuZXF1YWxzKGVsZW1lbnQyKX0gd291bGQgcmV0dXJuIHtAY29kZSB0cnVlfS4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlIHRoYXQgdGhpcyBkZWZpbml0aW9uIHBlcm1pdHMge0Bjb2RlIG51bGx9IGVsZW1lbnRzIGF0IGFueSBkZXB0aC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiBlaXRoZXIgb2YgdGhlIGdpdmVuIGFycmF5cyBjb250YWluIHRoZW1zZWx2ZXMgYXMgZWxlbWVudHMsIHRoZQorICAgICAqIGJlaGF2aW9yIG9mIHRoaXMgbWV0aG9kIGlzIHVuY2VydGFpbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheTEKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCB7QGNvZGUgT2JqZWN0fSBhcnJheS4KKyAgICAgKiBAcGFyYW0gYXJyYXkyCisgICAgICogICAgICAgICAgICB0aGUgc2Vjb25kIHtAY29kZSBPYmplY3R9IGFycmF5LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGJvdGggYXJyYXlzIGFyZSB7QGNvZGUgbnVsbH0gb3IgaWYgdGhlIGFycmF5cyBoYXZlIHRoZQorICAgICAqICAgICAgICAgc2FtZSBsZW5ndGggYW5kIHRoZSBlbGVtZW50cyBhdCBlYWNoIGluZGV4IGluIHRoZSB0d28gYXJyYXlzIGFyZQorICAgICAqICAgICAgICAgZXF1YWwgYWNjb3JkaW5nIHRvIHtAY29kZSBlcXVhbHMoKX0sIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBkZWVwRXF1YWxzKE9iamVjdFtdIGFycmF5MSwgT2JqZWN0W10gYXJyYXkyKSB7CisgICAgICAgIGlmIChhcnJheTEgPT0gYXJyYXkyKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYXJyYXkxID09IG51bGwgfHwgYXJyYXkyID09IG51bGwgfHwgYXJyYXkxLmxlbmd0aCAhPSBhcnJheTIubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheTEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIE9iamVjdCBlMSA9IGFycmF5MVtpXSwgZTIgPSBhcnJheTJbaV07CisKKyAgICAgICAgICAgIGlmICghZGVlcEVxdWFsc0VsZW1lbnRzKGUxLCBlMikpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBkZWVwRXF1YWxzRWxlbWVudHMoT2JqZWN0IGUxLCBPYmplY3QgZTIpIHsKKyAgICAgICAgQ2xhc3M8Pz4gY2wxLCBjbDI7CisKKyAgICAgICAgaWYgKGUxID09IGUyKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChlMSA9PSBudWxsIHx8IGUyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGNsMSA9IGUxLmdldENsYXNzKCkuZ2V0Q29tcG9uZW50VHlwZSgpOworICAgICAgICBjbDIgPSBlMi5nZXRDbGFzcygpLmdldENvbXBvbmVudFR5cGUoKTsKKworICAgICAgICBpZiAoY2wxICE9IGNsMikgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGNsMSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZTEuZXF1YWxzKGUyKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIGNvbXBhcmUgYXMgYXJyYXlzCisgICAgICAgICAqLworICAgICAgICBpZiAoIWNsMS5pc1ByaW1pdGl2ZSgpKSB7CisgICAgICAgICAgICByZXR1cm4gZGVlcEVxdWFscygoT2JqZWN0W10pIGUxLCAoT2JqZWN0W10pIGUyKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjbDEuZXF1YWxzKGludC5jbGFzcykpIHsKKyAgICAgICAgICAgIHJldHVybiBlcXVhbHMoKGludFtdKSBlMSwgKGludFtdKSBlMik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNsMS5lcXVhbHMoY2hhci5jbGFzcykpIHsKKyAgICAgICAgICAgIHJldHVybiBlcXVhbHMoKGNoYXJbXSkgZTEsIChjaGFyW10pIGUyKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2wxLmVxdWFscyhib29sZWFuLmNsYXNzKSkgeworICAgICAgICAgICAgcmV0dXJuIGVxdWFscygoYm9vbGVhbltdKSBlMSwgKGJvb2xlYW5bXSkgZTIpOworICAgICAgICB9CisgICAgICAgIGlmIChjbDEuZXF1YWxzKGJ5dGUuY2xhc3MpKSB7CisgICAgICAgICAgICByZXR1cm4gZXF1YWxzKChieXRlW10pIGUxLCAoYnl0ZVtdKSBlMik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNsMS5lcXVhbHMobG9uZy5jbGFzcykpIHsKKyAgICAgICAgICAgIHJldHVybiBlcXVhbHMoKGxvbmdbXSkgZTEsIChsb25nW10pIGUyKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2wxLmVxdWFscyhmbG9hdC5jbGFzcykpIHsKKyAgICAgICAgICAgIHJldHVybiBlcXVhbHMoKGZsb2F0W10pIGUxLCAoZmxvYXRbXSkgZTIpOworICAgICAgICB9CisgICAgICAgIGlmIChjbDEuZXF1YWxzKGRvdWJsZS5jbGFzcykpIHsKKyAgICAgICAgICAgIHJldHVybiBlcXVhbHMoKGRvdWJsZVtdKSBlMSwgKGRvdWJsZVtdKSBlMik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVxdWFscygoc2hvcnRbXSkgZTEsIChzaG9ydFtdKSBlMik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCBhcnJheSBpbiBhc2NlbmRpbmcgbnVtZXJpY2FsIG9yZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGJ5dGV9IGFycmF5IHRvIGJlIHNvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc29ydChieXRlW10gYXJyYXkpIHsKKyAgICAgICAgRHVhbFBpdm90UXVpY2tzb3J0LnNvcnQoYXJyYXkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgcmFuZ2UgaW4gdGhlIGFycmF5IGluIGFzY2VuZGluZyBudW1lcmljYWwgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgYnl0ZX0gYXJyYXkgdG8gYmUgc29ydGVkLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IGluZGV4IHRvIHNvcnQuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGxhc3QgKyAxIGluZGV4IHRvIHNvcnQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPiBlbmR9LgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0IDwgMH0gb3Ige0Bjb2RlIGVuZCA+IGFycmF5Lmxlbmd0aH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNvcnQoYnl0ZVtdIGFycmF5LCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgRHVhbFBpdm90UXVpY2tzb3J0LnNvcnQoYXJyYXksIHN0YXJ0LCBlbmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyB0aGF0IHRoZSByYW5nZSBkZXNjcmliZWQgYnkge0Bjb2RlIG9mZnNldH0gYW5kIHtAY29kZSBjb3VudH0gZG9lc24ndCBleGNlZWQKKyAgICAgKiB7QGNvZGUgYXJyYXlMZW5ndGh9LgorICAgICAqCisgICAgICogQGhpZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgY2hlY2tPZmZzZXRBbmRDb3VudChpbnQgYXJyYXlMZW5ndGgsIGludCBvZmZzZXQsIGludCBjb3VudCkgeworICAgICAgICBpZiAoKG9mZnNldCB8IGNvdW50KSA8IDAgfHwgb2Zmc2V0ID4gYXJyYXlMZW5ndGggfHwgYXJyYXlMZW5ndGggLSBvZmZzZXQgPCBjb3VudCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihhcnJheUxlbmd0aCwgb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICBjb3VudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgdGhhdCB0aGUgcmFuZ2UgZGVzY3JpYmVkIGJ5IHtAY29kZSBzdGFydH0gYW5kIHtAY29kZSBlbmR9IGRvZXNuJ3QgZXhjZWVkCisgICAgICoge0Bjb2RlIGxlbn0uCisgICAgICoKKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjaGVja1N0YXJ0QW5kRW5kKGludCBsZW4sIGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBpZiAoc3RhcnQgPCAwIHx8IGVuZCA+IGxlbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigic3RhcnQgPCAwIHx8IGVuZCA+IGxlbi4iCisgICAgICAgICAgICAgICAgICAgICsgIiBzdGFydD0iICsgc3RhcnQgKyAiLCBlbmQ9IiArIGVuZCArICIsIGxlbj0iICsgbGVuKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3RhcnQgPiBlbmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInN0YXJ0ID4gZW5kOiAiICsgc3RhcnQgKyAiID4gIiArIGVuZCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIGFycmF5IGluIGFzY2VuZGluZyBudW1lcmljYWwgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgY2hhcn0gYXJyYXkgdG8gYmUgc29ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzb3J0KGNoYXJbXSBhcnJheSkgeworICAgICAgICBEdWFsUGl2b3RRdWlja3NvcnQuc29ydChhcnJheSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCByYW5nZSBpbiB0aGUgYXJyYXkgaW4gYXNjZW5kaW5nIG51bWVyaWNhbCBvcmRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBjaGFyfSBhcnJheSB0byBiZSBzb3J0ZWQuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgaW5kZXggdG8gc29ydC4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgbGFzdCArIDEgaW5kZXggdG8gc29ydC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA+IGVuZH0uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwfSBvciB7QGNvZGUgZW5kID4gYXJyYXkubGVuZ3RofS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc29ydChjaGFyW10gYXJyYXksIGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBEdWFsUGl2b3RRdWlja3NvcnQuc29ydChhcnJheSwgc3RhcnQsIGVuZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCBhcnJheSBpbiBhc2NlbmRpbmcgbnVtZXJpY2FsIG9yZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGRvdWJsZX0gYXJyYXkgdG8gYmUgc29ydGVkLgorICAgICAqIEBzZWUgI3NvcnQoZG91YmxlW10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzb3J0KGRvdWJsZVtdIGFycmF5KSB7CisgICAgICAgIER1YWxQaXZvdFF1aWNrc29ydC5zb3J0KGFycmF5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIHJhbmdlIGluIHRoZSBhcnJheSBpbiBhc2NlbmRpbmcgbnVtZXJpY2FsIG9yZGVyLiBUaGUKKyAgICAgKiB2YWx1ZXMgYXJlIHNvcnRlZCBhY2NvcmRpbmcgdG8gdGhlIG9yZGVyIGltcG9zZWQgYnkge0Bjb2RlIERvdWJsZS5jb21wYXJlVG8oKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgZG91YmxlfSBhcnJheSB0byBiZSBzb3J0ZWQuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgaW5kZXggdG8gc29ydC4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgbGFzdCArIDEgaW5kZXggdG8gc29ydC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA+IGVuZH0uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPCAwfSBvciB7QGNvZGUgZW5kID4gYXJyYXkubGVuZ3RofS4KKyAgICAgKiBAc2VlIERvdWJsZSNjb21wYXJlVG8oRG91YmxlKQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzb3J0KGRvdWJsZVtdIGFycmF5LCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgRHVhbFBpdm90UXVpY2tzb3J0LnNvcnQoYXJyYXksIHN0YXJ0LCBlbmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgYXJyYXkgaW4gYXNjZW5kaW5nIG51bWVyaWNhbCBvcmRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBmbG9hdH0gYXJyYXkgdG8gYmUgc29ydGVkLgorICAgICAqIEBzZWUgI3NvcnQoZmxvYXRbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNvcnQoZmxvYXRbXSBhcnJheSkgeworICAgICAgICBEdWFsUGl2b3RRdWlja3NvcnQuc29ydChhcnJheSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCByYW5nZSBpbiB0aGUgYXJyYXkgaW4gYXNjZW5kaW5nIG51bWVyaWNhbCBvcmRlci4gVGhlCisgICAgICogdmFsdWVzIGFyZSBzb3J0ZWQgYWNjb3JkaW5nIHRvIHRoZSBvcmRlciBpbXBvc2VkIGJ5IHtAY29kZSBGbG9hdC5jb21wYXJlVG8oKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgZmxvYXR9IGFycmF5IHRvIGJlIHNvcnRlZC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBpbmRleCB0byBzb3J0LgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsYXN0ICsgMSBpbmRleCB0byBzb3J0LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0ID4gZW5kfS4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA8IDB9IG9yIHtAY29kZSBlbmQgPiBhcnJheS5sZW5ndGh9LgorICAgICAqIEBzZWUgRmxvYXQjY29tcGFyZVRvKEZsb2F0KQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzb3J0KGZsb2F0W10gYXJyYXksIGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBEdWFsUGl2b3RRdWlja3NvcnQuc29ydChhcnJheSwgc3RhcnQsIGVuZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCBhcnJheSBpbiBhc2NlbmRpbmcgbnVtZXJpY2FsIG9yZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGludH0gYXJyYXkgdG8gYmUgc29ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzb3J0KGludFtdIGFycmF5KSB7CisgICAgICAgIER1YWxQaXZvdFF1aWNrc29ydC5zb3J0KGFycmF5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIHJhbmdlIGluIHRoZSBhcnJheSBpbiBhc2NlbmRpbmcgbnVtZXJpY2FsIG9yZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGludH0gYXJyYXkgdG8gYmUgc29ydGVkLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IGluZGV4IHRvIHNvcnQuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGxhc3QgKyAxIGluZGV4IHRvIHNvcnQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPiBlbmR9LgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0IDwgMH0gb3Ige0Bjb2RlIGVuZCA+IGFycmF5Lmxlbmd0aH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNvcnQoaW50W10gYXJyYXksIGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBEdWFsUGl2b3RRdWlja3NvcnQuc29ydChhcnJheSwgc3RhcnQsIGVuZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCBhcnJheSBpbiBhc2NlbmRpbmcgbnVtZXJpY2FsIG9yZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGxvbmd9IGFycmF5IHRvIGJlIHNvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc29ydChsb25nW10gYXJyYXkpIHsKKyAgICAgICAgRHVhbFBpdm90UXVpY2tzb3J0LnNvcnQoYXJyYXkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgcmFuZ2UgaW4gdGhlIGFycmF5IGluIGFzY2VuZGluZyBudW1lcmljYWwgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgbG9uZ30gYXJyYXkgdG8gYmUgc29ydGVkLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IGluZGV4IHRvIHNvcnQuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGxhc3QgKyAxIGluZGV4IHRvIHNvcnQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPiBlbmR9LgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0IDwgMH0gb3Ige0Bjb2RlIGVuZCA+IGFycmF5Lmxlbmd0aH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNvcnQobG9uZ1tdIGFycmF5LCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgRHVhbFBpdm90UXVpY2tzb3J0LnNvcnQoYXJyYXksIHN0YXJ0LCBlbmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgYXJyYXkgaW4gYXNjZW5kaW5nIG51bWVyaWNhbCBvcmRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBzaG9ydH0gYXJyYXkgdG8gYmUgc29ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzb3J0KHNob3J0W10gYXJyYXkpIHsKKyAgICAgICAgRHVhbFBpdm90UXVpY2tzb3J0LnNvcnQoYXJyYXkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgcmFuZ2UgaW4gdGhlIGFycmF5IGluIGFzY2VuZGluZyBudW1lcmljYWwgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgc2hvcnR9IGFycmF5IHRvIGJlIHNvcnRlZC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBpbmRleCB0byBzb3J0LgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsYXN0ICsgMSBpbmRleCB0byBzb3J0LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0ID4gZW5kfS4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA8IDB9IG9yIHtAY29kZSBlbmQgPiBhcnJheS5sZW5ndGh9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzb3J0KHNob3J0W10gYXJyYXksIGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBEdWFsUGl2b3RRdWlja3NvcnQuc29ydChhcnJheSwgc3RhcnQsIGVuZCk7CisgICAgfQorCisvLyBCRUdJTiBhbmRyb2lkLW5vdGUKKworICAgIC8qCisgICAgICogPHA+SWYgdGhpcyBwbGF0Zm9ybSBoYXMgYW4gb3B0aW1pemluZyBWTSwgY2hlY2sgd2hldGhlciBDb21wYXJhYmxlVGltU29ydAorICAgICAqIG9mZmVycyBhbnkgcGVyZm9ybWFuY2UgYmVuZWZpdCBvdmVyIFRpbVNvcnQgaW4gY29uanVuY3Rpb24gd2l0aCBhCisgICAgICogY29tcGFyYXRvciB0aGF0IHJldHVybnM6CisgICAgICogICAge0Bjb2RlICgoQ29tcGFyYWJsZSlmaXJzdCkuY29tcGFyZVRvKFNlY29uZCl9LgorICAgICAqIElmIG5vdCwgeW91IGFyZSBiZXR0ZXIgb2ZmIGRlbGV0aW5nIENvbXBhcmFibGVUaW1Tb3J0IHRvIGVsaW1pbmF0ZSB0aGUKKyAgICAgKiBjb2RlIGR1cGxpY2F0aW9uLiAgSW4gb3RoZXIgd29yZHMsIHRoZSBjb21tZW50ZWQgb3V0IGNvZGUgYmVsb3cKKyAgICAgKiBpcyB0aGUgcHJlZmVyYWJsZSBpbXBsZW1lbnRhdGlvbiBmb3Igc29ydGluZyBhcnJheXMgb2YgQ29tcGFyYWJsZXMgaWYgaXQKKyAgICAgKiBvZmZlcnMgc3VmZmljaWVudCBwZXJmb3JtYW5jZS4KKyAgICAgKi8KKworLy8gICAgLyoqCisvLyAgICAgKiBBIGNvbXBhcmF0b3IgdGhhdCBpbXBsZW1lbnRzIHRoZSBuYXR1cmFsIG9yZGVyIG9mIGEgZ3JvdXAgb2YKKy8vICAgICAqIG11dHVhbGx5IGNvbXBhcmFibGUgZWxlbWVudHMuICBVc2luZyB0aGlzIGNvbXBhcmF0b3Igc2F2ZXMgdXMKKy8vICAgICAqIGZyb20gZHVwbGljYXRpbmcgbW9zdCBvZiB0aGUgY29kZSBpbiB0aGlzIGZpbGUgKG9uZSB2ZXJzaW9uIGZvcgorLy8gICAgICogQ29tcGFyYWJsZXMsIG9uZSBmb3IgZXhwbGljaXQgY29tcGFyYXRvcnMpLgorLy8gICAgICovCisvLyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDb21wYXJhdG9yPE9iamVjdD4gTkFUVVJBTF9PUkRFUiA9IG5ldyBDb21wYXJhdG9yPE9iamVjdD4oKSB7CisvLyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisvLyAgICAgICAgcHVibGljIGludCBjb21wYXJlKE9iamVjdCBmaXJzdCwgT2JqZWN0IHNlY29uZCkgeworLy8gICAgICAgICAgICByZXR1cm4gKChDb21wYXJhYmxlPE9iamVjdD4pZmlyc3QpLmNvbXBhcmVUbyhzZWNvbmQpOworLy8gICAgICAgIH0KKy8vICAgIH07CisvLworLy8gICAgcHVibGljIHN0YXRpYyB2b2lkIHNvcnQoT2JqZWN0W10gYSkgeworLy8gICAgICAgIHNvcnQoYSwgMCwgYS5sZW5ndGgsIE5BVFVSQUxfT1JERVIpOworLy8gICAgfQorLy8KKy8vICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzb3J0KE9iamVjdFtdIGEsIGludCBmcm9tSW5kZXgsIGludCB0b0luZGV4KSB7CisvLyAgICAgICAgc29ydChhLCBmcm9tSW5kZXgsIHRvSW5kZXgsIE5BVFVSQUxfT1JERVIpOworLy8gICAgfQorCisvLyBFTkQgYW5kcm9pZC1ub3RlCisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIGFycmF5IGluIGFzY2VuZGluZyBuYXR1cmFsIG9yZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIE9iamVjdH0gYXJyYXkgdG8gYmUgc29ydGVkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW4gZWxlbWVudCBpbiB0aGUgYXJyYXkgZG9lcyBub3QgaW1wbGVtZW50IHtAY29kZSBDb21wYXJhYmxlfQorICAgICAqICAgICAgICAgICAgICAgIG9yIGlmIHNvbWUgZWxlbWVudHMgY2Fubm90IGJlIGNvbXBhcmVkIHRvIGVhY2ggb3RoZXIuCisgICAgICogQHNlZSAjc29ydChPYmplY3RbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNvcnQoT2JqZWN0W10gYXJyYXkpIHsKKyAgICAgICAgQ29tcGFyYWJsZVRpbVNvcnQuc29ydChhcnJheSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCByYW5nZSBpbiB0aGUgYXJyYXkgaW4gYXNjZW5kaW5nIG5hdHVyYWwgb3JkZXIuIEFsbAorICAgICAqIGVsZW1lbnRzIG11c3QgaW1wbGVtZW50IHRoZSB7QGNvZGUgQ29tcGFyYWJsZX0gaW50ZXJmYWNlIGFuZCBtdXN0IGJlCisgICAgICogY29tcGFyYWJsZSB0byBlYWNoIG90aGVyIHdpdGhvdXQgYSB7QGNvZGUgQ2xhc3NDYXN0RXhjZXB0aW9ufSBiZWluZworICAgICAqIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBPYmplY3R9IGFycmF5IHRvIGJlIHNvcnRlZC4KKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBpbmRleCB0byBzb3J0LgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsYXN0ICsgMSBpbmRleCB0byBzb3J0LgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW4gZWxlbWVudCBpbiB0aGUgYXJyYXkgZG9lcyBub3QgaW1wbGVtZW50IHtAY29kZSBDb21wYXJhYmxlfQorICAgICAqICAgICAgICAgICAgICAgIG9yIHNvbWUgZWxlbWVudHMgY2Fubm90IGJlIGNvbXBhcmVkIHRvIGVhY2ggb3RoZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnQgPiBlbmR9LgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0IDwgMH0gb3Ige0Bjb2RlIGVuZCA+IGFycmF5Lmxlbmd0aH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNvcnQoT2JqZWN0W10gYXJyYXksIGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBDb21wYXJhYmxlVGltU29ydC5zb3J0KGFycmF5LCBzdGFydCwgZW5kKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIHJhbmdlIGluIHRoZSBhcnJheSB1c2luZyB0aGUgc3BlY2lmaWVkIHtAY29kZSBDb21wYXJhdG9yfS4KKyAgICAgKiBBbGwgZWxlbWVudHMgbXVzdCBiZSBjb21wYXJhYmxlIHRvIGVhY2ggb3RoZXIgd2l0aG91dCBhCisgICAgICoge0Bjb2RlIENsYXNzQ2FzdEV4Y2VwdGlvbn0gYmVpbmcgdGhyb3duLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIE9iamVjdH0gYXJyYXkgdG8gYmUgc29ydGVkLgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIHN0YXJ0IGluZGV4IHRvIHNvcnQuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGxhc3QgKyAxIGluZGV4IHRvIHNvcnQuCisgICAgICogQHBhcmFtIGNvbXBhcmF0b3IKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ29tcGFyYXRvcn0uCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBlbGVtZW50cyBpbiB0aGUgYXJyYXkgY2Fubm90IGJlIGNvbXBhcmVkIHRvIGVhY2ggb3RoZXIKKyAgICAgKiAgICAgICAgICAgICAgICB1c2luZyB0aGUge0Bjb2RlIENvbXBhcmF0b3J9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0ID4gZW5kfS4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA8IDB9IG9yIHtAY29kZSBlbmQgPiBhcnJheS5sZW5ndGh9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFQ+IHZvaWQgc29ydChUW10gYXJyYXksIGludCBzdGFydCwgaW50IGVuZCwgQ29tcGFyYXRvcjw/IHN1cGVyIFQ+IGNvbXBhcmF0b3IpIHsKKyAgICAgICAgVGltU29ydC5zb3J0KGFycmF5LCBzdGFydCwgZW5kLCBjb21wYXJhdG9yKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIGFycmF5IHVzaW5nIHRoZSBzcGVjaWZpZWQge0Bjb2RlIENvbXBhcmF0b3J9LiBBbGwgZWxlbWVudHMKKyAgICAgKiBtdXN0IGJlIGNvbXBhcmFibGUgdG8gZWFjaCBvdGhlciB3aXRob3V0IGEge0Bjb2RlIENsYXNzQ2FzdEV4Y2VwdGlvbn0gYmVpbmcgdGhyb3duLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIE9iamVjdH0gYXJyYXkgdG8gYmUgc29ydGVkLgorICAgICAqIEBwYXJhbSBjb21wYXJhdG9yCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIENvbXBhcmF0b3J9LgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgZWxlbWVudHMgaW4gdGhlIGFycmF5IGNhbm5vdCBiZSBjb21wYXJlZCB0byBlYWNoIG90aGVyCisgICAgICogICAgICAgICAgICAgICAgdXNpbmcgdGhlIHtAY29kZSBDb21wYXJhdG9yfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUPiB2b2lkIHNvcnQoVFtdIGFycmF5LCBDb21wYXJhdG9yPD8gc3VwZXIgVD4gY29tcGFyYXRvcikgeworICAgICAgICBUaW1Tb3J0LnNvcnQoYXJyYXksIGNvbXBhcmF0b3IpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgU3RyaW5nfSByZXByZXNlbnRhdGlvbiBvZiB0aGUge0Bjb2RlIGJvb2xlYW5bXX0gcGFzc2VkLgorICAgICAqIFRoZSByZXN1bHQgaXMgc3Vycm91bmRlZCBieSBicmFja2V0cyAoe0Bjb2RlICJbXSJ9KSwgZWFjaAorICAgICAqIGVsZW1lbnQgaXMgY29udmVydGVkIHRvIGEge0Bjb2RlIFN0cmluZ30gdmlhIHRoZQorICAgICAqIHtAbGluayBTdHJpbmcjdmFsdWVPZihib29sZWFuKX0gYW5kIHNlcGFyYXRlZCBieSB7QGNvZGUgIiwgIn0uCisgICAgICogSWYgdGhlIGFycmF5IGlzIHtAY29kZSBudWxsfSwgdGhlbiB7QGNvZGUgIm51bGwifSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBib29sZWFufSBhcnJheSB0byBjb252ZXJ0LgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBTdHJpbmd9IHJlcHJlc2VudGF0aW9uIG9mIHtAY29kZSBhcnJheX0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKGJvb2xlYW5bXSBhcnJheSkgeworICAgICAgICBpZiAoYXJyYXkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuICJudWxsIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoYXJyYXkubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAiW10iOworICAgICAgICB9CisgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcihhcnJheS5sZW5ndGggKiA3KTsKKyAgICAgICAgc2IuYXBwZW5kKCdbJyk7CisgICAgICAgIHNiLmFwcGVuZChhcnJheVswXSk7CisgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZChhcnJheVtpXSk7CisgICAgICAgIH0KKyAgICAgICAgc2IuYXBwZW5kKCddJyk7CisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgU3RyaW5nfSByZXByZXNlbnRhdGlvbiBvZiB0aGUge0Bjb2RlIGJ5dGVbXX0gcGFzc2VkLiBUaGUKKyAgICAgKiByZXN1bHQgaXMgc3Vycm91bmRlZCBieSBicmFja2V0cyAoe0Bjb2RlICJbXSJ9KSwgZWFjaCBlbGVtZW50CisgICAgICogaXMgY29udmVydGVkIHRvIGEge0Bjb2RlIFN0cmluZ30gdmlhIHRoZSB7QGxpbmsgU3RyaW5nI3ZhbHVlT2YoaW50KX0gYW5kCisgICAgICogc2VwYXJhdGVkIGJ5IHtAY29kZSAiLCAifS4gSWYgdGhlIGFycmF5IGlzIHtAY29kZSBudWxsfSwgdGhlbgorICAgICAqIHtAY29kZSAibnVsbCJ9IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGJ5dGV9IGFycmF5IHRvIGNvbnZlcnQuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFN0cmluZ30gcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIGFycmF5fS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoYnl0ZVtdIGFycmF5KSB7CisgICAgICAgIGlmIChhcnJheSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gIm51bGwiOworICAgICAgICB9CisgICAgICAgIGlmIChhcnJheS5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuICJbXSI7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKGFycmF5Lmxlbmd0aCAqIDYpOworICAgICAgICBzYi5hcHBlbmQoJ1snKTsKKyAgICAgICAgc2IuYXBwZW5kKGFycmF5WzBdKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc2IuYXBwZW5kKCIsICIpOworICAgICAgICAgICAgc2IuYXBwZW5kKGFycmF5W2ldKTsKKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQoJ10nKTsKKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHtAY29kZSBTdHJpbmd9IHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7QGNvZGUgY2hhcltdfSBwYXNzZWQuIFRoZQorICAgICAqIHJlc3VsdCBpcyBzdXJyb3VuZGVkIGJ5IGJyYWNrZXRzICh7QGNvZGUgIltdIn0pLCBlYWNoIGVsZW1lbnQKKyAgICAgKiBpcyBjb252ZXJ0ZWQgdG8gYSB7QGNvZGUgU3RyaW5nfSB2aWEgdGhlIHtAbGluayBTdHJpbmcjdmFsdWVPZihjaGFyKX0gYW5kCisgICAgICogc2VwYXJhdGVkIGJ5IHtAY29kZSAiLCAifS4gSWYgdGhlIGFycmF5IGlzIHtAY29kZSBudWxsfSwgdGhlbgorICAgICAqIHtAY29kZSAibnVsbCJ9IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIGNoYXJ9IGFycmF5IHRvIGNvbnZlcnQuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFN0cmluZ30gcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIGFycmF5fS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoY2hhcltdIGFycmF5KSB7CisgICAgICAgIGlmIChhcnJheSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gIm51bGwiOworICAgICAgICB9CisgICAgICAgIGlmIChhcnJheS5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuICJbXSI7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKGFycmF5Lmxlbmd0aCAqIDMpOworICAgICAgICBzYi5hcHBlbmQoJ1snKTsKKyAgICAgICAgc2IuYXBwZW5kKGFycmF5WzBdKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc2IuYXBwZW5kKCIsICIpOworICAgICAgICAgICAgc2IuYXBwZW5kKGFycmF5W2ldKTsKKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQoJ10nKTsKKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHtAY29kZSBTdHJpbmd9IHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7QGNvZGUgZG91YmxlW119IHBhc3NlZC4KKyAgICAgKiBUaGUgcmVzdWx0IGlzIHN1cnJvdW5kZWQgYnkgYnJhY2tldHMgKHtAY29kZSAiW10ifSksIGVhY2gKKyAgICAgKiBlbGVtZW50IGlzIGNvbnZlcnRlZCB0byBhIHtAY29kZSBTdHJpbmd9IHZpYSB0aGUKKyAgICAgKiB7QGxpbmsgU3RyaW5nI3ZhbHVlT2YoZG91YmxlKX0gYW5kIHNlcGFyYXRlZCBieSB7QGNvZGUgIiwgIn0uCisgICAgICogSWYgdGhlIGFycmF5IGlzIHtAY29kZSBudWxsfSwgdGhlbiB7QGNvZGUgIm51bGwifSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBkb3VibGV9IGFycmF5IHRvIGNvbnZlcnQuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFN0cmluZ30gcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIGFycmF5fS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoZG91YmxlW10gYXJyYXkpIHsKKyAgICAgICAgaWYgKGFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAibnVsbCI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFycmF5Lmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gIltdIjsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoYXJyYXkubGVuZ3RoICogNyk7CisgICAgICAgIHNiLmFwcGVuZCgnWycpOworICAgICAgICBzYi5hcHBlbmQoYXJyYXlbMF0pOworICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIiwgIik7CisgICAgICAgICAgICBzYi5hcHBlbmQoYXJyYXlbaV0pOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZCgnXScpOworICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIFN0cmluZ30gcmVwcmVzZW50YXRpb24gb2YgdGhlIHtAY29kZSBmbG9hdFtdfSBwYXNzZWQuCisgICAgICogVGhlIHJlc3VsdCBpcyBzdXJyb3VuZGVkIGJ5IGJyYWNrZXRzICh7QGNvZGUgIltdIn0pLCBlYWNoCisgICAgICogZWxlbWVudCBpcyBjb252ZXJ0ZWQgdG8gYSB7QGNvZGUgU3RyaW5nfSB2aWEgdGhlCisgICAgICoge0BsaW5rIFN0cmluZyN2YWx1ZU9mKGZsb2F0KX0gYW5kIHNlcGFyYXRlZCBieSB7QGNvZGUgIiwgIn0uCisgICAgICogSWYgdGhlIGFycmF5IGlzIHtAY29kZSBudWxsfSwgdGhlbiB7QGNvZGUgIm51bGwifSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBmbG9hdH0gYXJyYXkgdG8gY29udmVydC4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgU3RyaW5nfSByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUgYXJyYXl9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b1N0cmluZyhmbG9hdFtdIGFycmF5KSB7CisgICAgICAgIGlmIChhcnJheSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gIm51bGwiOworICAgICAgICB9CisgICAgICAgIGlmIChhcnJheS5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuICJbXSI7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKGFycmF5Lmxlbmd0aCAqIDcpOworICAgICAgICBzYi5hcHBlbmQoJ1snKTsKKyAgICAgICAgc2IuYXBwZW5kKGFycmF5WzBdKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc2IuYXBwZW5kKCIsICIpOworICAgICAgICAgICAgc2IuYXBwZW5kKGFycmF5W2ldKTsKKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQoJ10nKTsKKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHtAY29kZSBTdHJpbmd9IHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7QGNvZGUgaW50W119IHBhc3NlZC4gVGhlCisgICAgICogcmVzdWx0IGlzIHN1cnJvdW5kZWQgYnkgYnJhY2tldHMgKHtAY29kZSAiW10ifSksIGVhY2ggZWxlbWVudAorICAgICAqIGlzIGNvbnZlcnRlZCB0byBhIHtAY29kZSBTdHJpbmd9IHZpYSB0aGUge0BsaW5rIFN0cmluZyN2YWx1ZU9mKGludCl9IGFuZAorICAgICAqIHNlcGFyYXRlZCBieSB7QGNvZGUgIiwgIn0uIElmIHRoZSBhcnJheSBpcyB7QGNvZGUgbnVsbH0sIHRoZW4KKyAgICAgKiB7QGNvZGUgIm51bGwifSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBpbnR9IGFycmF5IHRvIGNvbnZlcnQuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFN0cmluZ30gcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIGFycmF5fS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoaW50W10gYXJyYXkpIHsKKyAgICAgICAgaWYgKGFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAibnVsbCI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFycmF5Lmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gIltdIjsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoYXJyYXkubGVuZ3RoICogNik7CisgICAgICAgIHNiLmFwcGVuZCgnWycpOworICAgICAgICBzYi5hcHBlbmQoYXJyYXlbMF0pOworICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIiwgIik7CisgICAgICAgICAgICBzYi5hcHBlbmQoYXJyYXlbaV0pOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZCgnXScpOworICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIFN0cmluZ30gcmVwcmVzZW50YXRpb24gb2YgdGhlIHtAY29kZSBsb25nW119IHBhc3NlZC4gVGhlCisgICAgICogcmVzdWx0IGlzIHN1cnJvdW5kZWQgYnkgYnJhY2tldHMgKHtAY29kZSAiW10ifSksIGVhY2ggZWxlbWVudAorICAgICAqIGlzIGNvbnZlcnRlZCB0byBhIHtAY29kZSBTdHJpbmd9IHZpYSB0aGUge0BsaW5rIFN0cmluZyN2YWx1ZU9mKGxvbmcpfSBhbmQKKyAgICAgKiBzZXBhcmF0ZWQgYnkge0Bjb2RlICIsICJ9LiBJZiB0aGUgYXJyYXkgaXMge0Bjb2RlIG51bGx9LCB0aGVuCisgICAgICoge0Bjb2RlICJudWxsIn0gaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgbG9uZ30gYXJyYXkgdG8gY29udmVydC4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgU3RyaW5nfSByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUgYXJyYXl9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b1N0cmluZyhsb25nW10gYXJyYXkpIHsKKyAgICAgICAgaWYgKGFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAibnVsbCI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFycmF5Lmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gIltdIjsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoYXJyYXkubGVuZ3RoICogNik7CisgICAgICAgIHNiLmFwcGVuZCgnWycpOworICAgICAgICBzYi5hcHBlbmQoYXJyYXlbMF0pOworICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIiwgIik7CisgICAgICAgICAgICBzYi5hcHBlbmQoYXJyYXlbaV0pOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZCgnXScpOworICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIFN0cmluZ30gcmVwcmVzZW50YXRpb24gb2YgdGhlIHtAY29kZSBzaG9ydFtdfSBwYXNzZWQuCisgICAgICogVGhlIHJlc3VsdCBpcyBzdXJyb3VuZGVkIGJ5IGJyYWNrZXRzICh7QGNvZGUgIltdIn0pLCBlYWNoCisgICAgICogZWxlbWVudCBpcyBjb252ZXJ0ZWQgdG8gYSB7QGNvZGUgU3RyaW5nfSB2aWEgdGhlCisgICAgICoge0BsaW5rIFN0cmluZyN2YWx1ZU9mKGludCl9IGFuZCBzZXBhcmF0ZWQgYnkge0Bjb2RlICIsICJ9LiBJZgorICAgICAqIHRoZSBhcnJheSBpcyB7QGNvZGUgbnVsbH0sIHRoZW4ge0Bjb2RlICJudWxsIn0gaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgc2hvcnR9IGFycmF5IHRvIGNvbnZlcnQuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFN0cmluZ30gcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIGFycmF5fS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoc2hvcnRbXSBhcnJheSkgeworICAgICAgICBpZiAoYXJyYXkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuICJudWxsIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoYXJyYXkubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAiW10iOworICAgICAgICB9CisgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcihhcnJheS5sZW5ndGggKiA2KTsKKyAgICAgICAgc2IuYXBwZW5kKCdbJyk7CisgICAgICAgIHNiLmFwcGVuZChhcnJheVswXSk7CisgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZChhcnJheVtpXSk7CisgICAgICAgIH0KKyAgICAgICAgc2IuYXBwZW5kKCddJyk7CisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgU3RyaW5nfSByZXByZXNlbnRhdGlvbiBvZiB0aGUge0Bjb2RlIE9iamVjdFtdfSBwYXNzZWQuCisgICAgICogVGhlIHJlc3VsdCBpcyBzdXJyb3VuZGVkIGJ5IGJyYWNrZXRzICh7QGNvZGUgIltdIn0pLCBlYWNoCisgICAgICogZWxlbWVudCBpcyBjb252ZXJ0ZWQgdG8gYSB7QGNvZGUgU3RyaW5nfSB2aWEgdGhlCisgICAgICoge0BsaW5rIFN0cmluZyN2YWx1ZU9mKE9iamVjdCl9IGFuZCBzZXBhcmF0ZWQgYnkge0Bjb2RlICIsICJ9LgorICAgICAqIElmIHRoZSBhcnJheSBpcyB7QGNvZGUgbnVsbH0sIHRoZW4ge0Bjb2RlICJudWxsIn0gaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT2JqZWN0fSBhcnJheSB0byBjb252ZXJ0LgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBTdHJpbmd9IHJlcHJlc2VudGF0aW9uIG9mIHtAY29kZSBhcnJheX0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKE9iamVjdFtdIGFycmF5KSB7CisgICAgICAgIGlmIChhcnJheSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gIm51bGwiOworICAgICAgICB9CisgICAgICAgIGlmIChhcnJheS5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuICJbXSI7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKGFycmF5Lmxlbmd0aCAqIDcpOworICAgICAgICBzYi5hcHBlbmQoJ1snKTsKKyAgICAgICAgc2IuYXBwZW5kKGFycmF5WzBdKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc2IuYXBwZW5kKCIsICIpOworICAgICAgICAgICAgc2IuYXBwZW5kKGFycmF5W2ldKTsKKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQoJ10nKTsKKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIDxpPiJkZWVwIjwvaT4ge0Bjb2RlIFN0cmluZ30gcmVwcmVzZW50YXRpb24gb2YgdGhlCisgICAgICoge0Bjb2RlIE9iamVjdFtdfSBwYXNzZWQsIHN1Y2ggdGhhdCBpZiB0aGUgYXJyYXkgY29udGFpbnMgb3RoZXIgYXJyYXlzLAorICAgICAqIHRoZSB7QGNvZGUgU3RyaW5nfSByZXByZXNlbnRhdGlvbiBvZiB0aG9zZSBhcnJheXMgaXMgZ2VuZXJhdGVkIGFzIHdlbGwuCisgICAgICogPHA+CisgICAgICogSWYgYW55IG9mIHRoZSBlbGVtZW50cyBhcmUgcHJpbWl0aXZlIGFycmF5cywgdGhlIGdlbmVyYXRpb24gaXMgZGVsZWdhdGVkCisgICAgICogdG8gdGhlIG90aGVyIHtAY29kZSB0b1N0cmluZ30gbWV0aG9kcyBpbiB0aGlzIGNsYXNzLiBJZiBhbnkgZWxlbWVudAorICAgICAqIGNvbnRhaW5zIGEgcmVmZXJlbmNlIHRvIHRoZSBvcmlnaW5hbCBhcnJheSwgdGhlbiBpdCB3aWxsIGJlIHJlcHJlc2VudGVkCisgICAgICogYXMge0Bjb2RlICJbLi4uXSJ9LiBJZiBhbiBlbGVtZW50IGlzIGFuIHtAY29kZSBPYmplY3RbXX0sIHRoZW4gaXRzCisgICAgICogcmVwcmVzZW50YXRpb24gaXMgZ2VuZXJhdGVkIGJ5IGEgcmVjdXJzaXZlIGNhbGwgdG8gdGhpcyBtZXRob2QuIEFsbCBvdGhlcgorICAgICAqIGVsZW1lbnRzIGFyZSBjb252ZXJ0ZWQgdmlhIHRoZSB7QGxpbmsgU3RyaW5nI3ZhbHVlT2YoT2JqZWN0KX0gbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIE9iamVjdH0gYXJyYXkgdG8gY29udmVydC4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgU3RyaW5nfSByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUgYXJyYXl9LgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBkZWVwVG9TdHJpbmcoT2JqZWN0W10gYXJyYXkpIHsKKyAgICAgICAgLy8gU3BlY2lhbCBjYXNlIG51bGwgdG8gcHJldmVudCBOUEUKKyAgICAgICAgaWYgKGFycmF5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAibnVsbCI7CisgICAgICAgIH0KKyAgICAgICAgLy8gZGVsZWdhdGUgdGhpcyB0byB0aGUgcmVjdXJzaXZlIG1ldGhvZAorICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKGFycmF5Lmxlbmd0aCAqIDkpOworICAgICAgICBkZWVwVG9TdHJpbmdJbXBsKGFycmF5LCBuZXcgT2JqZWN0W10geyBhcnJheSB9LCBidWYpOworICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW1wbGVtZW50YXRpb24gbWV0aG9kIHVzZWQgYnkge0BsaW5rICNkZWVwVG9TdHJpbmcoT2JqZWN0W10pfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBPYmplY3RbXX0gdG8gZGl2ZSBpbnRvLgorICAgICAqIEBwYXJhbSBvcmlnQXJyYXlzCisgICAgICogICAgICAgICAgICB0aGUgb3JpZ2luYWwge0Bjb2RlIE9iamVjdFtdfTsgdXNlZCB0byB0ZXN0IGZvciBzZWxmCisgICAgICogICAgICAgICAgICByZWZlcmVuY2VzLgorICAgICAqIEBwYXJhbSBzYgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBTdHJpbmdCdWlsZGVyfSBpbnN0YW5jZSB0byBhcHBlbmQgdG8gb3IKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBudWxsfSBvbmUgaGFzbid0IGJlZW4gY3JlYXRlZCB5ZXQuCisgICAgICogQHJldHVybiB0aGUgcmVzdWx0LgorICAgICAqIEBzZWUgI2RlZXBUb1N0cmluZyhPYmplY3RbXSkKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGRlZXBUb1N0cmluZ0ltcGwoT2JqZWN0W10gYXJyYXksIE9iamVjdFtdIG9yaWdBcnJheXMsCisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiKSB7CisgICAgICAgIGlmIChhcnJheSA9PSBudWxsKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHNiLmFwcGVuZCgnWycpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChpICE9IDApIHsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIiwgIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBlc3RhYmxpc2ggY3VycmVudCBlbGVtZW50CisgICAgICAgICAgICBPYmplY3QgZWxlbSA9IGFycmF5W2ldOworICAgICAgICAgICAgaWYgKGVsZW0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIGVsZW1lbnQgaXMgbnVsbAorICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIENsYXNzIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQKKyAgICAgICAgICAgICAgICBDbGFzczw/PiBlbGVtQ2xhc3MgPSBlbGVtLmdldENsYXNzKCk7CisgICAgICAgICAgICAgICAgaWYgKGVsZW1DbGFzcy5pc0FycmF5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gZWxlbWVudCBpcyBhbiBhcnJheSB0eXBlCisKKyAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBkZWNsYXJlZCBDbGFzcyBvZiB0aGUgYXJyYXkgKGVsZW1lbnQpCisgICAgICAgICAgICAgICAgICAgIENsYXNzPD8+IGVsZW1FbGVtQ2xhc3MgPSBlbGVtQ2xhc3MuZ2V0Q29tcG9uZW50VHlwZSgpOworICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbUVsZW1DbGFzcy5pc1ByaW1pdGl2ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBlbGVtZW50IGlzIGEgcHJpbWl0aXZlIGFycmF5CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYm9vbGVhbi5jbGFzcy5lcXVhbHMoZWxlbUVsZW1DbGFzcykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQodG9TdHJpbmcoKGJvb2xlYW5bXSkgZWxlbSkpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChieXRlLmNsYXNzLmVxdWFscyhlbGVtRWxlbUNsYXNzKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZCh0b1N0cmluZygoYnl0ZVtdKSBlbGVtKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoYXIuY2xhc3MuZXF1YWxzKGVsZW1FbGVtQ2xhc3MpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKHRvU3RyaW5nKChjaGFyW10pIGVsZW0pKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZG91YmxlLmNsYXNzLmVxdWFscyhlbGVtRWxlbUNsYXNzKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZCh0b1N0cmluZygoZG91YmxlW10pIGVsZW0pKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZmxvYXQuY2xhc3MuZXF1YWxzKGVsZW1FbGVtQ2xhc3MpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKHRvU3RyaW5nKChmbG9hdFtdKSBlbGVtKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGludC5jbGFzcy5lcXVhbHMoZWxlbUVsZW1DbGFzcykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQodG9TdHJpbmcoKGludFtdKSBlbGVtKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGxvbmcuY2xhc3MuZXF1YWxzKGVsZW1FbGVtQ2xhc3MpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKHRvU3RyaW5nKChsb25nW10pIGVsZW0pKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc2hvcnQuY2xhc3MuZXF1YWxzKGVsZW1FbGVtQ2xhc3MpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKHRvU3RyaW5nKChzaG9ydFtdKSBlbGVtKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vIG90aGVyIHBvc3NpYmxlIHByaW1pdGl2ZXMsIHNvIHdlIGFzc2VydCB0aGF0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBlbGVtZW50IGlzIGFuIE9iamVjdFtdLCBzbyB3ZSBhc3NlcnQgdGhhdAorICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0IGVsZW0gaW5zdGFuY2VvZiBPYmplY3RbXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZWVwVG9TdHJpbmdJbXBsQ29udGFpbnMob3JpZ0FycmF5cywgZWxlbSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIlsuLi5dIik7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFtdIG5ld0FycmF5ID0gKE9iamVjdFtdKSBlbGVtOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFtdIG5ld09yaWdBcnJheXMgPSBuZXcgT2JqZWN0W29yaWdBcnJheXMubGVuZ3RoICsgMV07CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShvcmlnQXJyYXlzLCAwLCBuZXdPcmlnQXJyYXlzLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ0FycmF5cy5sZW5ndGgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld09yaWdBcnJheXNbb3JpZ0FycmF5cy5sZW5ndGhdID0gbmV3QXJyYXk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWFrZSB0aGUgcmVjdXJzaXZlIGNhbGwgdG8gdGhpcyBtZXRob2QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWVwVG9TdHJpbmdJbXBsKG5ld0FycmF5LCBuZXdPcmlnQXJyYXlzLCBzYik7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBlbGVtZW50IGlzIE5PVCBhbiBhcnJheSwganVzdCBhbiBPYmplY3QKKyAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKGFycmF5W2ldKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgc2IuYXBwZW5kKCddJyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXRpbGl0eSBtZXRob2QgdXNlZCB0byBhc3Npc3QgdGhlIGltcGxlbWVudGF0aW9uIG9mCisgICAgICoge0BsaW5rICNkZWVwVG9TdHJpbmcoT2JqZWN0W10pfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcmlnQXJyYXlzCisgICAgICogICAgICAgICAgICBBbiBhcnJheSBvZiBPYmplY3RbXSByZWZlcmVuY2VzLgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgQW4gT2JqZWN0W10gcmVmZXJlbmNlIHRvIGxvb2sgZm9yIGluIHtAY29kZSBvcmlnQXJyYXlzfS4KKyAgICAgKiBAcmV0dXJuIEEgdmFsdWUgb2Yge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBhcnJheX0gaXMgYW4KKyAgICAgKiAgICAgICAgIGVsZW1lbnQgaW4ge0Bjb2RlIG9yaWdBcnJheXN9LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gZGVlcFRvU3RyaW5nSW1wbENvbnRhaW5zKE9iamVjdFtdIG9yaWdBcnJheXMsCisgICAgICAgICAgICBPYmplY3QgYXJyYXkpIHsKKyAgICAgICAgaWYgKG9yaWdBcnJheXMgPT0gbnVsbCB8fCBvcmlnQXJyYXlzLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChPYmplY3QgZWxlbWVudCA6IG9yaWdBcnJheXMpIHsKKyAgICAgICAgICAgIGlmIChlbGVtZW50ID09IGFycmF5KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyB7QGNvZGUgbmV3TGVuZ3RofSBlbGVtZW50cyBmcm9tIHtAY29kZSBvcmlnaW5hbH0gaW50byBhIG5ldyBhcnJheS4KKyAgICAgKiBJZiB7QGNvZGUgbmV3TGVuZ3RofSBpcyBncmVhdGVyIHRoYW4ge0Bjb2RlIG9yaWdpbmFsLmxlbmd0aH0sIHRoZSByZXN1bHQgaXMgcGFkZGVkCisgICAgICogd2l0aCB0aGUgdmFsdWUge0Bjb2RlIGZhbHNlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcmlnaW5hbCB0aGUgb3JpZ2luYWwgYXJyYXkKKyAgICAgKiBAcGFyYW0gbmV3TGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIG5ldyBhcnJheQorICAgICAqIEByZXR1cm4gdGhlIG5ldyBhcnJheQorICAgICAqIEB0aHJvd3MgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24gaWYge0Bjb2RlIG5ld0xlbmd0aCA8IDB9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgb3JpZ2luYWwgPT0gbnVsbH0KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuW10gY29weU9mKGJvb2xlYW5bXSBvcmlnaW5hbCwgaW50IG5ld0xlbmd0aCkgeworICAgICAgICBpZiAobmV3TGVuZ3RoIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5lZ2F0aXZlQXJyYXlTaXplRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvcHlPZlJhbmdlKG9yaWdpbmFsLCAwLCBuZXdMZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyB7QGNvZGUgbmV3TGVuZ3RofSBlbGVtZW50cyBmcm9tIHtAY29kZSBvcmlnaW5hbH0gaW50byBhIG5ldyBhcnJheS4KKyAgICAgKiBJZiB7QGNvZGUgbmV3TGVuZ3RofSBpcyBncmVhdGVyIHRoYW4ge0Bjb2RlIG9yaWdpbmFsLmxlbmd0aH0sIHRoZSByZXN1bHQgaXMgcGFkZGVkCisgICAgICogd2l0aCB0aGUgdmFsdWUge0Bjb2RlIChieXRlKSAwfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcmlnaW5hbCB0aGUgb3JpZ2luYWwgYXJyYXkKKyAgICAgKiBAcGFyYW0gbmV3TGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIG5ldyBhcnJheQorICAgICAqIEByZXR1cm4gdGhlIG5ldyBhcnJheQorICAgICAqIEB0aHJvd3MgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24gaWYge0Bjb2RlIG5ld0xlbmd0aCA8IDB9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgb3JpZ2luYWwgPT0gbnVsbH0KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gY29weU9mKGJ5dGVbXSBvcmlnaW5hbCwgaW50IG5ld0xlbmd0aCkgeworICAgICAgICBpZiAobmV3TGVuZ3RoIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5lZ2F0aXZlQXJyYXlTaXplRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvcHlPZlJhbmdlKG9yaWdpbmFsLCAwLCBuZXdMZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyB7QGNvZGUgbmV3TGVuZ3RofSBlbGVtZW50cyBmcm9tIHtAY29kZSBvcmlnaW5hbH0gaW50byBhIG5ldyBhcnJheS4KKyAgICAgKiBJZiB7QGNvZGUgbmV3TGVuZ3RofSBpcyBncmVhdGVyIHRoYW4ge0Bjb2RlIG9yaWdpbmFsLmxlbmd0aH0sIHRoZSByZXN1bHQgaXMgcGFkZGVkCisgICAgICogd2l0aCB0aGUgdmFsdWUge0Bjb2RlICdcXHUwMDAwJ30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3JpZ2luYWwgdGhlIG9yaWdpbmFsIGFycmF5CisgICAgICogQHBhcmFtIG5ld0xlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBuZXcgYXJyYXkKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgYXJyYXkKKyAgICAgKiBAdGhyb3dzIE5lZ2F0aXZlQXJyYXlTaXplRXhjZXB0aW9uIGlmIHtAY29kZSBuZXdMZW5ndGggPCAwfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIG9yaWdpbmFsID09IG51bGx9CisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2hhcltdIGNvcHlPZihjaGFyW10gb3JpZ2luYWwsIGludCBuZXdMZW5ndGgpIHsKKyAgICAgICAgaWYgKG5ld0xlbmd0aCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb3B5T2ZSYW5nZShvcmlnaW5hbCwgMCwgbmV3TGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMge0Bjb2RlIG5ld0xlbmd0aH0gZWxlbWVudHMgZnJvbSB7QGNvZGUgb3JpZ2luYWx9IGludG8gYSBuZXcgYXJyYXkuCisgICAgICogSWYge0Bjb2RlIG5ld0xlbmd0aH0gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSBvcmlnaW5hbC5sZW5ndGh9LCB0aGUgcmVzdWx0IGlzIHBhZGRlZAorICAgICAqIHdpdGggdGhlIHZhbHVlIHtAY29kZSAwLjBkfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcmlnaW5hbCB0aGUgb3JpZ2luYWwgYXJyYXkKKyAgICAgKiBAcGFyYW0gbmV3TGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIG5ldyBhcnJheQorICAgICAqIEByZXR1cm4gdGhlIG5ldyBhcnJheQorICAgICAqIEB0aHJvd3MgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24gaWYge0Bjb2RlIG5ld0xlbmd0aCA8IDB9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgb3JpZ2luYWwgPT0gbnVsbH0KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBkb3VibGVbXSBjb3B5T2YoZG91YmxlW10gb3JpZ2luYWwsIGludCBuZXdMZW5ndGgpIHsKKyAgICAgICAgaWYgKG5ld0xlbmd0aCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb3B5T2ZSYW5nZShvcmlnaW5hbCwgMCwgbmV3TGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMge0Bjb2RlIG5ld0xlbmd0aH0gZWxlbWVudHMgZnJvbSB7QGNvZGUgb3JpZ2luYWx9IGludG8gYSBuZXcgYXJyYXkuCisgICAgICogSWYge0Bjb2RlIG5ld0xlbmd0aH0gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSBvcmlnaW5hbC5sZW5ndGh9LCB0aGUgcmVzdWx0IGlzIHBhZGRlZAorICAgICAqIHdpdGggdGhlIHZhbHVlIHtAY29kZSAwLjBmfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcmlnaW5hbCB0aGUgb3JpZ2luYWwgYXJyYXkKKyAgICAgKiBAcGFyYW0gbmV3TGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIG5ldyBhcnJheQorICAgICAqIEByZXR1cm4gdGhlIG5ldyBhcnJheQorICAgICAqIEB0aHJvd3MgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24gaWYge0Bjb2RlIG5ld0xlbmd0aCA8IDB9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgb3JpZ2luYWwgPT0gbnVsbH0KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmbG9hdFtdIGNvcHlPZihmbG9hdFtdIG9yaWdpbmFsLCBpbnQgbmV3TGVuZ3RoKSB7CisgICAgICAgIGlmIChuZXdMZW5ndGggPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29weU9mUmFuZ2Uob3JpZ2luYWwsIDAsIG5ld0xlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29waWVzIHtAY29kZSBuZXdMZW5ndGh9IGVsZW1lbnRzIGZyb20ge0Bjb2RlIG9yaWdpbmFsfSBpbnRvIGEgbmV3IGFycmF5LgorICAgICAqIElmIHtAY29kZSBuZXdMZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgb3JpZ2luYWwubGVuZ3RofSwgdGhlIHJlc3VsdCBpcyBwYWRkZWQKKyAgICAgKiB3aXRoIHRoZSB2YWx1ZSB7QGNvZGUgMH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3JpZ2luYWwgdGhlIG9yaWdpbmFsIGFycmF5CisgICAgICogQHBhcmFtIG5ld0xlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBuZXcgYXJyYXkKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgYXJyYXkKKyAgICAgKiBAdGhyb3dzIE5lZ2F0aXZlQXJyYXlTaXplRXhjZXB0aW9uIGlmIHtAY29kZSBuZXdMZW5ndGggPCAwfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIG9yaWdpbmFsID09IG51bGx9CisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50W10gY29weU9mKGludFtdIG9yaWdpbmFsLCBpbnQgbmV3TGVuZ3RoKSB7CisgICAgICAgIGlmIChuZXdMZW5ndGggPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29weU9mUmFuZ2Uob3JpZ2luYWwsIDAsIG5ld0xlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29waWVzIHtAY29kZSBuZXdMZW5ndGh9IGVsZW1lbnRzIGZyb20ge0Bjb2RlIG9yaWdpbmFsfSBpbnRvIGEgbmV3IGFycmF5LgorICAgICAqIElmIHtAY29kZSBuZXdMZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgb3JpZ2luYWwubGVuZ3RofSwgdGhlIHJlc3VsdCBpcyBwYWRkZWQKKyAgICAgKiB3aXRoIHRoZSB2YWx1ZSB7QGNvZGUgMEx9LgorICAgICAqCisgICAgICogQHBhcmFtIG9yaWdpbmFsIHRoZSBvcmlnaW5hbCBhcnJheQorICAgICAqIEBwYXJhbSBuZXdMZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgbmV3IGFycmF5CisgICAgICogQHJldHVybiB0aGUgbmV3IGFycmF5CisgICAgICogQHRocm93cyBOZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbiBpZiB7QGNvZGUgbmV3TGVuZ3RoIDwgMH0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBvcmlnaW5hbCA9PSBudWxsfQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmdbXSBjb3B5T2YobG9uZ1tdIG9yaWdpbmFsLCBpbnQgbmV3TGVuZ3RoKSB7CisgICAgICAgIGlmIChuZXdMZW5ndGggPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29weU9mUmFuZ2Uob3JpZ2luYWwsIDAsIG5ld0xlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29waWVzIHtAY29kZSBuZXdMZW5ndGh9IGVsZW1lbnRzIGZyb20ge0Bjb2RlIG9yaWdpbmFsfSBpbnRvIGEgbmV3IGFycmF5LgorICAgICAqIElmIHtAY29kZSBuZXdMZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgb3JpZ2luYWwubGVuZ3RofSwgdGhlIHJlc3VsdCBpcyBwYWRkZWQKKyAgICAgKiB3aXRoIHRoZSB2YWx1ZSB7QGNvZGUgKHNob3J0KSAwfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcmlnaW5hbCB0aGUgb3JpZ2luYWwgYXJyYXkKKyAgICAgKiBAcGFyYW0gbmV3TGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIG5ldyBhcnJheQorICAgICAqIEByZXR1cm4gdGhlIG5ldyBhcnJheQorICAgICAqIEB0aHJvd3MgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24gaWYge0Bjb2RlIG5ld0xlbmd0aCA8IDB9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgb3JpZ2luYWwgPT0gbnVsbH0KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBzaG9ydFtdIGNvcHlPZihzaG9ydFtdIG9yaWdpbmFsLCBpbnQgbmV3TGVuZ3RoKSB7CisgICAgICAgIGlmIChuZXdMZW5ndGggPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29weU9mUmFuZ2Uob3JpZ2luYWwsIDAsIG5ld0xlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29waWVzIHtAY29kZSBuZXdMZW5ndGh9IGVsZW1lbnRzIGZyb20ge0Bjb2RlIG9yaWdpbmFsfSBpbnRvIGEgbmV3IGFycmF5LgorICAgICAqIElmIHtAY29kZSBuZXdMZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgb3JpZ2luYWwubGVuZ3RofSwgdGhlIHJlc3VsdCBpcyBwYWRkZWQKKyAgICAgKiB3aXRoIHRoZSB2YWx1ZSB7QGNvZGUgbnVsbH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3JpZ2luYWwgdGhlIG9yaWdpbmFsIGFycmF5CisgICAgICogQHBhcmFtIG5ld0xlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBuZXcgYXJyYXkKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgYXJyYXkKKyAgICAgKiBAdGhyb3dzIE5lZ2F0aXZlQXJyYXlTaXplRXhjZXB0aW9uIGlmIHtAY29kZSBuZXdMZW5ndGggPCAwfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIG9yaWdpbmFsID09IG51bGx9CisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFQ+IFRbXSBjb3B5T2YoVFtdIG9yaWdpbmFsLCBpbnQgbmV3TGVuZ3RoKSB7CisgICAgICAgIGlmIChvcmlnaW5hbCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobmV3TGVuZ3RoIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5lZ2F0aXZlQXJyYXlTaXplRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvcHlPZlJhbmdlKG9yaWdpbmFsLCAwLCBuZXdMZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyB7QGNvZGUgbmV3TGVuZ3RofSBlbGVtZW50cyBmcm9tIHtAY29kZSBvcmlnaW5hbH0gaW50byBhIG5ldyBhcnJheS4KKyAgICAgKiBJZiB7QGNvZGUgbmV3TGVuZ3RofSBpcyBncmVhdGVyIHRoYW4ge0Bjb2RlIG9yaWdpbmFsLmxlbmd0aH0sIHRoZSByZXN1bHQgaXMgcGFkZGVkCisgICAgICogd2l0aCB0aGUgdmFsdWUge0Bjb2RlIG51bGx9LgorICAgICAqCisgICAgICogQHBhcmFtIG9yaWdpbmFsIHRoZSBvcmlnaW5hbCBhcnJheQorICAgICAqIEBwYXJhbSBuZXdMZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgbmV3IGFycmF5CisgICAgICogQHBhcmFtIG5ld1R5cGUgdGhlIGNsYXNzIG9mIHRoZSBuZXcgYXJyYXkKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgYXJyYXkKKyAgICAgKiBAdGhyb3dzIE5lZ2F0aXZlQXJyYXlTaXplRXhjZXB0aW9uIGlmIHtAY29kZSBuZXdMZW5ndGggPCAwfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIG9yaWdpbmFsID09IG51bGx9CisgICAgICogQHRocm93cyBBcnJheVN0b3JlRXhjZXB0aW9uIGlmIGEgdmFsdWUgaW4ge0Bjb2RlIG9yaWdpbmFsfSBpcyBpbmNvbXBhdGlibGUgd2l0aCBUCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFQsIFU+IFRbXSBjb3B5T2YoVVtdIG9yaWdpbmFsLCBpbnQgbmV3TGVuZ3RoLCBDbGFzczw/IGV4dGVuZHMgVFtdPiBuZXdUeXBlKSB7CisgICAgICAgIC8vIFdlIHVzZSB0aGUgbnVsbCBwb2ludGVyIGNoZWNrIGluIGNvcHlPZlJhbmdlIGZvciBleGNlcHRpb24gcHJpb3JpdHkgY29tcGF0aWJpbGl0eS4KKyAgICAgICAgaWYgKG5ld0xlbmd0aCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb3B5T2ZSYW5nZShvcmlnaW5hbCwgMCwgbmV3TGVuZ3RoLCBuZXdUeXBlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgZWxlbWVudHMgZnJvbSB7QGNvZGUgb3JpZ2luYWx9IGludG8gYSBuZXcgYXJyYXksIGZyb20gaW5kZXhlcyBzdGFydCAoaW5jbHVzaXZlKSB0bworICAgICAqIGVuZCAoZXhjbHVzaXZlKS4gVGhlIG9yaWdpbmFsIG9yZGVyIG9mIGVsZW1lbnRzIGlzIHByZXNlcnZlZC4KKyAgICAgKiBJZiB7QGNvZGUgZW5kfSBpcyBncmVhdGVyIHRoYW4ge0Bjb2RlIG9yaWdpbmFsLmxlbmd0aH0sIHRoZSByZXN1bHQgaXMgcGFkZGVkCisgICAgICogd2l0aCB0aGUgdmFsdWUge0Bjb2RlIGZhbHNlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcmlnaW5hbCB0aGUgb3JpZ2luYWwgYXJyYXkKKyAgICAgKiBAcGFyYW0gc3RhcnQgdGhlIHN0YXJ0IGluZGV4LCBpbmNsdXNpdmUKKyAgICAgKiBAcGFyYW0gZW5kIHRoZSBlbmQgaW5kZXgsIGV4Y2x1c2l2ZQorICAgICAqIEByZXR1cm4gdGhlIG5ldyBhcnJheQorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydCA8IDAgfHwgc3RhcnQgPiBvcmlnaW5hbC5sZW5ndGh9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHN0YXJ0ID4gZW5kfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIG9yaWdpbmFsID09IG51bGx9CisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbltdIGNvcHlPZlJhbmdlKGJvb2xlYW5bXSBvcmlnaW5hbCwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIGlmIChzdGFydCA+IGVuZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGludCBvcmlnaW5hbExlbmd0aCA9IG9yaWdpbmFsLmxlbmd0aDsKKyAgICAgICAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+IG9yaWdpbmFsTGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IHJlc3VsdExlbmd0aCA9IGVuZCAtIHN0YXJ0OworICAgICAgICBpbnQgY29weUxlbmd0aCA9IE1hdGgubWluKHJlc3VsdExlbmd0aCwgb3JpZ2luYWxMZW5ndGggLSBzdGFydCk7CisgICAgICAgIGJvb2xlYW5bXSByZXN1bHQgPSBuZXcgYm9vbGVhbltyZXN1bHRMZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG9yaWdpbmFsLCBzdGFydCwgcmVzdWx0LCAwLCBjb3B5TGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgZWxlbWVudHMgZnJvbSB7QGNvZGUgb3JpZ2luYWx9IGludG8gYSBuZXcgYXJyYXksIGZyb20gaW5kZXhlcyBzdGFydCAoaW5jbHVzaXZlKSB0bworICAgICAqIGVuZCAoZXhjbHVzaXZlKS4gVGhlIG9yaWdpbmFsIG9yZGVyIG9mIGVsZW1lbnRzIGlzIHByZXNlcnZlZC4KKyAgICAgKiBJZiB7QGNvZGUgZW5kfSBpcyBncmVhdGVyIHRoYW4ge0Bjb2RlIG9yaWdpbmFsLmxlbmd0aH0sIHRoZSByZXN1bHQgaXMgcGFkZGVkCisgICAgICogd2l0aCB0aGUgdmFsdWUge0Bjb2RlIChieXRlKSAwfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcmlnaW5hbCB0aGUgb3JpZ2luYWwgYXJyYXkKKyAgICAgKiBAcGFyYW0gc3RhcnQgdGhlIHN0YXJ0IGluZGV4LCBpbmNsdXNpdmUKKyAgICAgKiBAcGFyYW0gZW5kIHRoZSBlbmQgaW5kZXgsIGV4Y2x1c2l2ZQorICAgICAqIEByZXR1cm4gdGhlIG5ldyBhcnJheQorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydCA8IDAgfHwgc3RhcnQgPiBvcmlnaW5hbC5sZW5ndGh9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHN0YXJ0ID4gZW5kfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIG9yaWdpbmFsID09IG51bGx9CisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIGNvcHlPZlJhbmdlKGJ5dGVbXSBvcmlnaW5hbCwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIGlmIChzdGFydCA+IGVuZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGludCBvcmlnaW5hbExlbmd0aCA9IG9yaWdpbmFsLmxlbmd0aDsKKyAgICAgICAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+IG9yaWdpbmFsTGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IHJlc3VsdExlbmd0aCA9IGVuZCAtIHN0YXJ0OworICAgICAgICBpbnQgY29weUxlbmd0aCA9IE1hdGgubWluKHJlc3VsdExlbmd0aCwgb3JpZ2luYWxMZW5ndGggLSBzdGFydCk7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtyZXN1bHRMZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG9yaWdpbmFsLCBzdGFydCwgcmVzdWx0LCAwLCBjb3B5TGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgZWxlbWVudHMgZnJvbSB7QGNvZGUgb3JpZ2luYWx9IGludG8gYSBuZXcgYXJyYXksIGZyb20gaW5kZXhlcyBzdGFydCAoaW5jbHVzaXZlKSB0bworICAgICAqIGVuZCAoZXhjbHVzaXZlKS4gVGhlIG9yaWdpbmFsIG9yZGVyIG9mIGVsZW1lbnRzIGlzIHByZXNlcnZlZC4KKyAgICAgKiBJZiB7QGNvZGUgZW5kfSBpcyBncmVhdGVyIHRoYW4ge0Bjb2RlIG9yaWdpbmFsLmxlbmd0aH0sIHRoZSByZXN1bHQgaXMgcGFkZGVkCisgICAgICogd2l0aCB0aGUgdmFsdWUge0Bjb2RlICdcXHUwMDAwJ30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3JpZ2luYWwgdGhlIG9yaWdpbmFsIGFycmF5CisgICAgICogQHBhcmFtIHN0YXJ0IHRoZSBzdGFydCBpbmRleCwgaW5jbHVzaXZlCisgICAgICogQHBhcmFtIGVuZCB0aGUgZW5kIGluZGV4LCBleGNsdXNpdmUKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgYXJyYXkKKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB7QGNvZGUgc3RhcnQgPCAwIHx8IHN0YXJ0ID4gb3JpZ2luYWwubGVuZ3RofQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydCA+IGVuZH0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBvcmlnaW5hbCA9PSBudWxsfQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNoYXJbXSBjb3B5T2ZSYW5nZShjaGFyW10gb3JpZ2luYWwsIGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBpZiAoc3RhcnQgPiBlbmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgb3JpZ2luYWxMZW5ndGggPSBvcmlnaW5hbC5sZW5ndGg7CisgICAgICAgIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPiBvcmlnaW5hbExlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGludCByZXN1bHRMZW5ndGggPSBlbmQgLSBzdGFydDsKKyAgICAgICAgaW50IGNvcHlMZW5ndGggPSBNYXRoLm1pbihyZXN1bHRMZW5ndGgsIG9yaWdpbmFsTGVuZ3RoIC0gc3RhcnQpOworICAgICAgICBjaGFyW10gcmVzdWx0ID0gbmV3IGNoYXJbcmVzdWx0TGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShvcmlnaW5hbCwgc3RhcnQsIHJlc3VsdCwgMCwgY29weUxlbmd0aCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29waWVzIGVsZW1lbnRzIGZyb20ge0Bjb2RlIG9yaWdpbmFsfSBpbnRvIGEgbmV3IGFycmF5LCBmcm9tIGluZGV4ZXMgc3RhcnQgKGluY2x1c2l2ZSkgdG8KKyAgICAgKiBlbmQgKGV4Y2x1c2l2ZSkuIFRoZSBvcmlnaW5hbCBvcmRlciBvZiBlbGVtZW50cyBpcyBwcmVzZXJ2ZWQuCisgICAgICogSWYge0Bjb2RlIGVuZH0gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSBvcmlnaW5hbC5sZW5ndGh9LCB0aGUgcmVzdWx0IGlzIHBhZGRlZAorICAgICAqIHdpdGggdGhlIHZhbHVlIHtAY29kZSAwLjBkfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcmlnaW5hbCB0aGUgb3JpZ2luYWwgYXJyYXkKKyAgICAgKiBAcGFyYW0gc3RhcnQgdGhlIHN0YXJ0IGluZGV4LCBpbmNsdXNpdmUKKyAgICAgKiBAcGFyYW0gZW5kIHRoZSBlbmQgaW5kZXgsIGV4Y2x1c2l2ZQorICAgICAqIEByZXR1cm4gdGhlIG5ldyBhcnJheQorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydCA8IDAgfHwgc3RhcnQgPiBvcmlnaW5hbC5sZW5ndGh9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHN0YXJ0ID4gZW5kfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIG9yaWdpbmFsID09IG51bGx9CisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlW10gY29weU9mUmFuZ2UoZG91YmxlW10gb3JpZ2luYWwsIGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBpZiAoc3RhcnQgPiBlbmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgb3JpZ2luYWxMZW5ndGggPSBvcmlnaW5hbC5sZW5ndGg7CisgICAgICAgIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPiBvcmlnaW5hbExlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGludCByZXN1bHRMZW5ndGggPSBlbmQgLSBzdGFydDsKKyAgICAgICAgaW50IGNvcHlMZW5ndGggPSBNYXRoLm1pbihyZXN1bHRMZW5ndGgsIG9yaWdpbmFsTGVuZ3RoIC0gc3RhcnQpOworICAgICAgICBkb3VibGVbXSByZXN1bHQgPSBuZXcgZG91YmxlW3Jlc3VsdExlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob3JpZ2luYWwsIHN0YXJ0LCByZXN1bHQsIDAsIGNvcHlMZW5ndGgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyBlbGVtZW50cyBmcm9tIHtAY29kZSBvcmlnaW5hbH0gaW50byBhIG5ldyBhcnJheSwgZnJvbSBpbmRleGVzIHN0YXJ0IChpbmNsdXNpdmUpIHRvCisgICAgICogZW5kIChleGNsdXNpdmUpLiBUaGUgb3JpZ2luYWwgb3JkZXIgb2YgZWxlbWVudHMgaXMgcHJlc2VydmVkLgorICAgICAqIElmIHtAY29kZSBlbmR9IGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgb3JpZ2luYWwubGVuZ3RofSwgdGhlIHJlc3VsdCBpcyBwYWRkZWQKKyAgICAgKiB3aXRoIHRoZSB2YWx1ZSB7QGNvZGUgMC4wZn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3JpZ2luYWwgdGhlIG9yaWdpbmFsIGFycmF5CisgICAgICogQHBhcmFtIHN0YXJ0IHRoZSBzdGFydCBpbmRleCwgaW5jbHVzaXZlCisgICAgICogQHBhcmFtIGVuZCB0aGUgZW5kIGluZGV4LCBleGNsdXNpdmUKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgYXJyYXkKKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB7QGNvZGUgc3RhcnQgPCAwIHx8IHN0YXJ0ID4gb3JpZ2luYWwubGVuZ3RofQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydCA+IGVuZH0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBvcmlnaW5hbCA9PSBudWxsfQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZsb2F0W10gY29weU9mUmFuZ2UoZmxvYXRbXSBvcmlnaW5hbCwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIGlmIChzdGFydCA+IGVuZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGludCBvcmlnaW5hbExlbmd0aCA9IG9yaWdpbmFsLmxlbmd0aDsKKyAgICAgICAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+IG9yaWdpbmFsTGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IHJlc3VsdExlbmd0aCA9IGVuZCAtIHN0YXJ0OworICAgICAgICBpbnQgY29weUxlbmd0aCA9IE1hdGgubWluKHJlc3VsdExlbmd0aCwgb3JpZ2luYWxMZW5ndGggLSBzdGFydCk7CisgICAgICAgIGZsb2F0W10gcmVzdWx0ID0gbmV3IGZsb2F0W3Jlc3VsdExlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob3JpZ2luYWwsIHN0YXJ0LCByZXN1bHQsIDAsIGNvcHlMZW5ndGgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyBlbGVtZW50cyBmcm9tIHtAY29kZSBvcmlnaW5hbH0gaW50byBhIG5ldyBhcnJheSwgZnJvbSBpbmRleGVzIHN0YXJ0IChpbmNsdXNpdmUpIHRvCisgICAgICogZW5kIChleGNsdXNpdmUpLiBUaGUgb3JpZ2luYWwgb3JkZXIgb2YgZWxlbWVudHMgaXMgcHJlc2VydmVkLgorICAgICAqIElmIHtAY29kZSBlbmR9IGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgb3JpZ2luYWwubGVuZ3RofSwgdGhlIHJlc3VsdCBpcyBwYWRkZWQKKyAgICAgKiB3aXRoIHRoZSB2YWx1ZSB7QGNvZGUgMH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3JpZ2luYWwgdGhlIG9yaWdpbmFsIGFycmF5CisgICAgICogQHBhcmFtIHN0YXJ0IHRoZSBzdGFydCBpbmRleCwgaW5jbHVzaXZlCisgICAgICogQHBhcmFtIGVuZCB0aGUgZW5kIGluZGV4LCBleGNsdXNpdmUKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgYXJyYXkKKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB7QGNvZGUgc3RhcnQgPCAwIHx8IHN0YXJ0ID4gb3JpZ2luYWwubGVuZ3RofQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydCA+IGVuZH0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBvcmlnaW5hbCA9PSBudWxsfQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludFtdIGNvcHlPZlJhbmdlKGludFtdIG9yaWdpbmFsLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgaWYgKHN0YXJ0ID4gZW5kKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IG9yaWdpbmFsTGVuZ3RoID0gb3JpZ2luYWwubGVuZ3RoOworICAgICAgICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID4gb3JpZ2luYWxMZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgcmVzdWx0TGVuZ3RoID0gZW5kIC0gc3RhcnQ7CisgICAgICAgIGludCBjb3B5TGVuZ3RoID0gTWF0aC5taW4ocmVzdWx0TGVuZ3RoLCBvcmlnaW5hbExlbmd0aCAtIHN0YXJ0KTsKKyAgICAgICAgaW50W10gcmVzdWx0ID0gbmV3IGludFtyZXN1bHRMZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG9yaWdpbmFsLCBzdGFydCwgcmVzdWx0LCAwLCBjb3B5TGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgZWxlbWVudHMgZnJvbSB7QGNvZGUgb3JpZ2luYWx9IGludG8gYSBuZXcgYXJyYXksIGZyb20gaW5kZXhlcyBzdGFydCAoaW5jbHVzaXZlKSB0bworICAgICAqIGVuZCAoZXhjbHVzaXZlKS4gVGhlIG9yaWdpbmFsIG9yZGVyIG9mIGVsZW1lbnRzIGlzIHByZXNlcnZlZC4KKyAgICAgKiBJZiB7QGNvZGUgZW5kfSBpcyBncmVhdGVyIHRoYW4ge0Bjb2RlIG9yaWdpbmFsLmxlbmd0aH0sIHRoZSByZXN1bHQgaXMgcGFkZGVkCisgICAgICogd2l0aCB0aGUgdmFsdWUge0Bjb2RlIDBMfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcmlnaW5hbCB0aGUgb3JpZ2luYWwgYXJyYXkKKyAgICAgKiBAcGFyYW0gc3RhcnQgdGhlIHN0YXJ0IGluZGV4LCBpbmNsdXNpdmUKKyAgICAgKiBAcGFyYW0gZW5kIHRoZSBlbmQgaW5kZXgsIGV4Y2x1c2l2ZQorICAgICAqIEByZXR1cm4gdGhlIG5ldyBhcnJheQorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydCA8IDAgfHwgc3RhcnQgPiBvcmlnaW5hbC5sZW5ndGh9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHN0YXJ0ID4gZW5kfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIG9yaWdpbmFsID09IG51bGx9CisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbG9uZ1tdIGNvcHlPZlJhbmdlKGxvbmdbXSBvcmlnaW5hbCwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIGlmIChzdGFydCA+IGVuZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGludCBvcmlnaW5hbExlbmd0aCA9IG9yaWdpbmFsLmxlbmd0aDsKKyAgICAgICAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+IG9yaWdpbmFsTGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IHJlc3VsdExlbmd0aCA9IGVuZCAtIHN0YXJ0OworICAgICAgICBpbnQgY29weUxlbmd0aCA9IE1hdGgubWluKHJlc3VsdExlbmd0aCwgb3JpZ2luYWxMZW5ndGggLSBzdGFydCk7CisgICAgICAgIGxvbmdbXSByZXN1bHQgPSBuZXcgbG9uZ1tyZXN1bHRMZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG9yaWdpbmFsLCBzdGFydCwgcmVzdWx0LCAwLCBjb3B5TGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgZWxlbWVudHMgZnJvbSB7QGNvZGUgb3JpZ2luYWx9IGludG8gYSBuZXcgYXJyYXksIGZyb20gaW5kZXhlcyBzdGFydCAoaW5jbHVzaXZlKSB0bworICAgICAqIGVuZCAoZXhjbHVzaXZlKS4gVGhlIG9yaWdpbmFsIG9yZGVyIG9mIGVsZW1lbnRzIGlzIHByZXNlcnZlZC4KKyAgICAgKiBJZiB7QGNvZGUgZW5kfSBpcyBncmVhdGVyIHRoYW4ge0Bjb2RlIG9yaWdpbmFsLmxlbmd0aH0sIHRoZSByZXN1bHQgaXMgcGFkZGVkCisgICAgICogd2l0aCB0aGUgdmFsdWUge0Bjb2RlIChzaG9ydCkgMH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3JpZ2luYWwgdGhlIG9yaWdpbmFsIGFycmF5CisgICAgICogQHBhcmFtIHN0YXJ0IHRoZSBzdGFydCBpbmRleCwgaW5jbHVzaXZlCisgICAgICogQHBhcmFtIGVuZCB0aGUgZW5kIGluZGV4LCBleGNsdXNpdmUKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgYXJyYXkKKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB7QGNvZGUgc3RhcnQgPCAwIHx8IHN0YXJ0ID4gb3JpZ2luYWwubGVuZ3RofQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydCA+IGVuZH0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBvcmlnaW5hbCA9PSBudWxsfQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHNob3J0W10gY29weU9mUmFuZ2Uoc2hvcnRbXSBvcmlnaW5hbCwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgIGlmIChzdGFydCA+IGVuZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGludCBvcmlnaW5hbExlbmd0aCA9IG9yaWdpbmFsLmxlbmd0aDsKKyAgICAgICAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+IG9yaWdpbmFsTGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IHJlc3VsdExlbmd0aCA9IGVuZCAtIHN0YXJ0OworICAgICAgICBpbnQgY29weUxlbmd0aCA9IE1hdGgubWluKHJlc3VsdExlbmd0aCwgb3JpZ2luYWxMZW5ndGggLSBzdGFydCk7CisgICAgICAgIHNob3J0W10gcmVzdWx0ID0gbmV3IHNob3J0W3Jlc3VsdExlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob3JpZ2luYWwsIHN0YXJ0LCByZXN1bHQsIDAsIGNvcHlMZW5ndGgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyBlbGVtZW50cyBmcm9tIHtAY29kZSBvcmlnaW5hbH0gaW50byBhIG5ldyBhcnJheSwgZnJvbSBpbmRleGVzIHN0YXJ0IChpbmNsdXNpdmUpIHRvCisgICAgICogZW5kIChleGNsdXNpdmUpLiBUaGUgb3JpZ2luYWwgb3JkZXIgb2YgZWxlbWVudHMgaXMgcHJlc2VydmVkLgorICAgICAqIElmIHtAY29kZSBlbmR9IGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgb3JpZ2luYWwubGVuZ3RofSwgdGhlIHJlc3VsdCBpcyBwYWRkZWQKKyAgICAgKiB3aXRoIHRoZSB2YWx1ZSB7QGNvZGUgbnVsbH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3JpZ2luYWwgdGhlIG9yaWdpbmFsIGFycmF5CisgICAgICogQHBhcmFtIHN0YXJ0IHRoZSBzdGFydCBpbmRleCwgaW5jbHVzaXZlCisgICAgICogQHBhcmFtIGVuZCB0aGUgZW5kIGluZGV4LCBleGNsdXNpdmUKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgYXJyYXkKKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB7QGNvZGUgc3RhcnQgPCAwIHx8IHN0YXJ0ID4gb3JpZ2luYWwubGVuZ3RofQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydCA+IGVuZH0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBvcmlnaW5hbCA9PSBudWxsfQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgc3RhdGljIDxUPiBUW10gY29weU9mUmFuZ2UoVFtdIG9yaWdpbmFsLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgaW50IG9yaWdpbmFsTGVuZ3RoID0gb3JpZ2luYWwubGVuZ3RoOyAvLyBGb3IgZXhjZXB0aW9uIHByaW9yaXR5IGNvbXBhdGliaWxpdHkuCisgICAgICAgIGlmIChzdGFydCA+IGVuZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPiBvcmlnaW5hbExlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGludCByZXN1bHRMZW5ndGggPSBlbmQgLSBzdGFydDsKKyAgICAgICAgaW50IGNvcHlMZW5ndGggPSBNYXRoLm1pbihyZXN1bHRMZW5ndGgsIG9yaWdpbmFsTGVuZ3RoIC0gc3RhcnQpOworICAgICAgICBUW10gcmVzdWx0ID0gKFRbXSkgQXJyYXkubmV3SW5zdGFuY2Uob3JpZ2luYWwuZ2V0Q2xhc3MoKS5nZXRDb21wb25lbnRUeXBlKCksIHJlc3VsdExlbmd0aCk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob3JpZ2luYWwsIHN0YXJ0LCByZXN1bHQsIDAsIGNvcHlMZW5ndGgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyBlbGVtZW50cyBmcm9tIHtAY29kZSBvcmlnaW5hbH0gaW50byBhIG5ldyBhcnJheSwgZnJvbSBpbmRleGVzIHN0YXJ0IChpbmNsdXNpdmUpIHRvCisgICAgICogZW5kIChleGNsdXNpdmUpLiBUaGUgb3JpZ2luYWwgb3JkZXIgb2YgZWxlbWVudHMgaXMgcHJlc2VydmVkLgorICAgICAqIElmIHtAY29kZSBlbmR9IGlzIGdyZWF0ZXIgdGhhbiB7QGNvZGUgb3JpZ2luYWwubGVuZ3RofSwgdGhlIHJlc3VsdCBpcyBwYWRkZWQKKyAgICAgKiB3aXRoIHRoZSB2YWx1ZSB7QGNvZGUgbnVsbH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3JpZ2luYWwgdGhlIG9yaWdpbmFsIGFycmF5CisgICAgICogQHBhcmFtIHN0YXJ0IHRoZSBzdGFydCBpbmRleCwgaW5jbHVzaXZlCisgICAgICogQHBhcmFtIGVuZCB0aGUgZW5kIGluZGV4LCBleGNsdXNpdmUKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgYXJyYXkKKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB7QGNvZGUgc3RhcnQgPCAwIHx8IHN0YXJ0ID4gb3JpZ2luYWwubGVuZ3RofQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBzdGFydCA+IGVuZH0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBvcmlnaW5hbCA9PSBudWxsfQorICAgICAqIEB0aHJvd3MgQXJyYXlTdG9yZUV4Y2VwdGlvbiBpZiBhIHZhbHVlIGluIHtAY29kZSBvcmlnaW5hbH0gaXMgaW5jb21wYXRpYmxlIHdpdGggVAorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgc3RhdGljIDxULCBVPiBUW10gY29weU9mUmFuZ2UoVVtdIG9yaWdpbmFsLCBpbnQgc3RhcnQsIGludCBlbmQsIENsYXNzPD8gZXh0ZW5kcyBUW10+IG5ld1R5cGUpIHsKKyAgICAgICAgaWYgKHN0YXJ0ID4gZW5kKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IG9yaWdpbmFsTGVuZ3RoID0gb3JpZ2luYWwubGVuZ3RoOworICAgICAgICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID4gb3JpZ2luYWxMZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgcmVzdWx0TGVuZ3RoID0gZW5kIC0gc3RhcnQ7CisgICAgICAgIGludCBjb3B5TGVuZ3RoID0gTWF0aC5taW4ocmVzdWx0TGVuZ3RoLCBvcmlnaW5hbExlbmd0aCAtIHN0YXJ0KTsKKyAgICAgICAgVFtdIHJlc3VsdCA9IChUW10pIEFycmF5Lm5ld0luc3RhbmNlKG5ld1R5cGUuZ2V0Q29tcG9uZW50VHlwZSgpLCByZXN1bHRMZW5ndGgpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG9yaWdpbmFsLCBzdGFydCwgcmVzdWx0LCAwLCBjb3B5TGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0JpdFNldC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9CaXRTZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hODQxMzE1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9CaXRTZXQuamF2YQpAQCAtMCwwICsxLDc1MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlT3JkZXI7CitpbXBvcnQgamF2YS5uaW8uTG9uZ0J1ZmZlcjsKK2ltcG9ydCBsaWJjb3JlLmlvLlNpemVPZjsKKworLyoqCisgKiBUaGUge0Bjb2RlIEJpdFNldH0gY2xhc3MgaW1wbGVtZW50cyBhCisgKiA8YSBocmVmPSJodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0JpdF9hcnJheSI+Yml0IGFycmF5PC9hPi4KKyAqIEVhY2ggZWxlbWVudCBpcyBlaXRoZXIgdHJ1ZSBvciBmYWxzZS4gQSB7QGNvZGUgQml0U2V0fSBpcyBjcmVhdGVkIHdpdGggYSBnaXZlbiBzaXplIGFuZCBncm93cworICogYXV0b21hdGljYWxseSBpZiB0aGlzIHNpemUgaXMgZXhjZWVkZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBCaXRTZXQgaW1wbGVtZW50cyBTZXJpYWxpemFibGUsIENsb25lYWJsZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzk5NzY5ODU4ODk4Njg3ODc1M0w7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIEFMTF9PTkVTID0gfjBMOworCisgICAgLyoqCisgICAgICogVGhlIGJpdHMuIEFjY2VzcyBiaXQgbiB0aHVzOgorICAgICAqCisgICAgICogICBib29sZWFuIGJpdCA9IChiaXRzW24gLyA2NF0gfCAoMSA8PCBuKSkgIT0gMDsKKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCBKYXZhJ3Mgc2hpZnQgb3BlcmF0b3JzIHRydW5jYXRlIHRoZWlyIHJocyB0byB0aGUgbG9nMiBzaXplIG9mIHRoZSBsaHMuCisgICAgICogVGhhdCBpcywgdGhlcmUncyBubyAiJSA2NCIgbmVlZGVkIGJlY2F1c2UgaXQncyBpbXBsaWNpdCBpbiB0aGUgc2hpZnQuCisgICAgICoKKyAgICAgKiBUT0RPOiB3b3VsZCBpbnRbXSBiZSBzaWduaWZpY2FudGx5IG1vcmUgZWZmaWNpZW50IGZvciBBbmRyb2lkIGF0IHRoZSBtb21lbnQ/CisgICAgICovCisgICAgcHJpdmF0ZSBsb25nW10gYml0czsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgb2YgJ2JpdHMnIHRoYXQgYXJlIGFjdHVhbGx5IGluIHVzZSAobm9uLXplcm8pLiBBbW9uZ3N0IG90aGVyCisgICAgICogdGhpbmdzLCB0aGlzIGd1YXJhbnRlZXMgdGhhdCBpc0VtcHR5IGlzIGNoZWFwLCBiZWNhdXNlIHdlIG5ldmVyIGhhdmUgdG8gZXhhbWluZSB0aGUgYXJyYXkuCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IGxvbmdDb3VudDsKKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgJ2xvbmdDb3VudCcgYnkgaW5zcGVjdGluZyAnYml0cycuIEFzc3VtZXMgdGhhdCB0aGUgbmV3IGxvbmdDb3VudCBpcyA8PSB0aGUgY3VycmVudAorICAgICAqIGxvbmdDb3VudCwgdG8gYXZvaWQgc2Nhbm5pbmcgbGFyZ2UgdHJhY3RzIG9mIGVtcHR5IGFycmF5LiBUaGlzIG1lYW5zIGl0J3Mgc2FmZSB0byBjYWxsCisgICAgICogZGlyZWN0bHkgYWZ0ZXIgYSBjbGVhciBvcGVyYXRpb24gdGhhdCBtYXkgaGF2ZSBjbGVhcmVkIHRoZSBoaWdoZXN0IHNldCBiaXQsIGJ1dAorICAgICAqIG5vdCBzYWZlIGFmdGVyIGFuIHhvciBvcGVyYXRpb24gdGhhdCBtYXkgaGF2ZSBjbGVhcmVkIHRoZSBoaWdoZXN0IHNldCBiaXQgb3IKKyAgICAgKiBtYWRlIGEgbmV3IGhpZ2hlc3Qgc2V0IGJpdC4gSW4gdGhhdCBjYXNlLCB5b3UnZCBuZWVkIHRvIHNldCAnbG9uZ0NvdW50JyB0byBhIGNvbnNlcnZhdGl2ZQorICAgICAqIGVzdGltYXRlIGJlZm9yZSBjYWxsaW5nIHRoaXMgbWV0aG9kLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzaHJpbmtTaXplKCkgeworICAgICAgICBpbnQgaSA9IGxvbmdDb3VudCAtIDE7CisgICAgICAgIHdoaWxlIChpID49IDAgJiYgYml0c1tpXSA9PSAwKSB7CisgICAgICAgICAgICAtLWk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5sb25nQ291bnQgPSBpICsgMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBCaXRTZXR9IHdpdGggc2l6ZSBlcXVhbCB0byA2NCBiaXRzLgorICAgICAqLworICAgIHB1YmxpYyBCaXRTZXQoKSB7CisgICAgICAgIHRoaXMobmV3IGxvbmdbMV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEJpdFNldH0gd2l0aCBzaXplIGVxdWFsIHRvIHtAY29kZSBiaXRDb3VudH0sIHJvdW5kZWQgdXAgdG8KKyAgICAgKiBhIG11bHRpcGxlIG9mIDY0LgorICAgICAqCisgICAgICogQHRocm93cyBOZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbiBpZiB7QGNvZGUgYml0Q291bnQgPCAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQml0U2V0KGludCBiaXRDb3VudCkgeworICAgICAgICBpZiAoYml0Q291bnQgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmJpdHMgPSBhcnJheUZvckJpdHMoYml0Q291bnQpOworICAgICAgICB0aGlzLmxvbmdDb3VudCA9IDA7CisgICAgfQorCisgICAgcHJpdmF0ZSBCaXRTZXQobG9uZ1tdIGJpdHMpIHsKKyAgICAgICAgdGhpcy5iaXRzID0gYml0czsKKyAgICAgICAgdGhpcy5sb25nQ291bnQgPSBiaXRzLmxlbmd0aDsKKyAgICAgICAgc2hyaW5rU2l6ZSgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGxvbmdbXSBhcnJheUZvckJpdHMoaW50IGJpdENvdW50KSB7CisgICAgICAgIHJldHVybiBuZXcgbG9uZ1soYml0Q291bnQgKyA2MykvIDY0XTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEJpdFNldCBjbG9uZSA9IChCaXRTZXQpIHN1cGVyLmNsb25lKCk7CisgICAgICAgICAgICBjbG9uZS5iaXRzID0gYml0cy5jbG9uZSgpOworICAgICAgICAgICAgY2xvbmUuc2hyaW5rU2l6ZSgpOworICAgICAgICAgICAgcmV0dXJuIGNsb25lOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgIGlmICh0aGlzID09IG8pIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBCaXRTZXQpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgQml0U2V0IGxocyA9IChCaXRTZXQpIG87CisgICAgICAgIGlmICh0aGlzLmxvbmdDb3VudCAhPSBsaHMubG9uZ0NvdW50KSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsb25nQ291bnQ7ICsraSkgeworICAgICAgICAgICAgaWYgKGJpdHNbaV0gIT0gbGhzLmJpdHNbaV0pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5zdXJlcyB0aGF0IG91ciBsb25nW10gY2FuIGhvbGQgYXQgbGVhc3QgNjQgKiBkZXNpcmVkTG9uZ0NvdW50IGJpdHMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUNhcGFjaXR5KGludCBkZXNpcmVkTG9uZ0NvdW50KSB7CisgICAgICAgIGlmIChkZXNpcmVkTG9uZ0NvdW50IDw9IGJpdHMubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaW50IG5ld0xlbmd0aCA9IE1hdGgubWF4KGRlc2lyZWRMb25nQ291bnQsIGJpdHMubGVuZ3RoICogMik7CisgICAgICAgIGxvbmdbXSBuZXdCaXRzID0gbmV3IGxvbmdbbmV3TGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShiaXRzLCAwLCBuZXdCaXRzLCAwLCBsb25nQ291bnQpOworICAgICAgICB0aGlzLmJpdHMgPSBuZXdCaXRzOworICAgICAgICAvLyAnbG9uZ0NvdW50JyBpcyB1bmNoYW5nZWQgYnkgdGhpcyBvcGVyYXRpb246IHRoZSBsb25nW10gaXMgbGFyZ2VyLAorICAgICAgICAvLyBidXQgeW91J3JlIG5vdCB5ZXQgdXNpbmcgYW55IG1vcmUgb2YgaXQuCisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIC8vIFRoZSBSSSBkb2Vzbid0IHVzZSBBcnJheXMuaGFzaENvZGUsIGFuZCBleHBsaWNpdGx5IHNwZWNpZmllcyB0aGlzIGFsZ29yaXRobS4KKyAgICAgICAgbG9uZyB4ID0gMTIzNDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsb25nQ291bnQ7ICsraSkgeworICAgICAgICAgICAgeCBePSBiaXRzW2ldICogKGkgKyAxKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKGludCkgKCh4ID4+IDMyKSBeIHgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGJpdCBhdCBpbmRleCB7QGNvZGUgaW5kZXh9LiBJbmRleGVzIGdyZWF0ZXIgdGhhbiB0aGUgY3VycmVudCBsZW5ndGggcmV0dXJuIGZhbHNlLgorICAgICAqCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHtAY29kZSBpbmRleCA8IDB9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldChpbnQgaW5kZXgpIHsKKyAgICAgICAgaWYgKGluZGV4IDwgMCkgeyAvLyBUT0RPOiB1bnRpbCB3ZSBoYXZlIGFuIGlubGluaW5nIEpJVC4KKyAgICAgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICB9CisgICAgICAgIGludCBhcnJheUluZGV4ID0gaW5kZXggLyA2NDsKKyAgICAgICAgaWYgKGFycmF5SW5kZXggPj0gbG9uZ0NvdW50KSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChiaXRzW2FycmF5SW5kZXhdICYgKDFMIDw8IGluZGV4KSkgIT0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBiaXQgYXQgaW5kZXgge0Bjb2RlIGluZGV4fSB0byB0cnVlLgorICAgICAqCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHtAY29kZSBpbmRleCA8IDB9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldChpbnQgaW5kZXgpIHsKKyAgICAgICAgaWYgKGluZGV4IDwgMCkgeyAvLyBUT0RPOiB1bnRpbCB3ZSBoYXZlIGFuIGlubGluaW5nIEpJVC4KKyAgICAgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICB9CisgICAgICAgIGludCBhcnJheUluZGV4ID0gaW5kZXggLyA2NDsKKyAgICAgICAgaWYgKGFycmF5SW5kZXggPj0gYml0cy5sZW5ndGgpIHsKKyAgICAgICAgICAgIGVuc3VyZUNhcGFjaXR5KGFycmF5SW5kZXggKyAxKTsKKyAgICAgICAgfQorICAgICAgICBiaXRzW2FycmF5SW5kZXhdIHw9ICgxTCA8PCBpbmRleCk7CisgICAgICAgIGxvbmdDb3VudCA9IE1hdGgubWF4KGxvbmdDb3VudCwgYXJyYXlJbmRleCArIDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsZWFycyB0aGUgYml0IGF0IGluZGV4IHtAY29kZSBpbmRleH0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYge0Bjb2RlIGluZGV4IDwgMH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXIoaW50IGluZGV4KSB7CisgICAgICAgIGlmIChpbmRleCA8IDApIHsgLy8gVE9ETzogdW50aWwgd2UgaGF2ZSBhbiBpbmxpbmluZyBKSVQuCisgICAgICAgICAgICBjaGVja0luZGV4KGluZGV4KTsKKyAgICAgICAgfQorICAgICAgICBpbnQgYXJyYXlJbmRleCA9IGluZGV4IC8gNjQ7CisgICAgICAgIGlmIChhcnJheUluZGV4ID49IGxvbmdDb3VudCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGJpdHNbYXJyYXlJbmRleF0gJj0gfigxTCA8PCBpbmRleCk7CisgICAgICAgIHNocmlua1NpemUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGbGlwcyB0aGUgYml0IGF0IGluZGV4IHtAY29kZSBpbmRleH0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYge0Bjb2RlIGluZGV4IDwgMH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgZmxpcChpbnQgaW5kZXgpIHsKKyAgICAgICAgaWYgKGluZGV4IDwgMCkgeyAvLyBUT0RPOiB1bnRpbCB3ZSBoYXZlIGFuIGlubGluaW5nIEpJVC4KKyAgICAgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICB9CisgICAgICAgIGludCBhcnJheUluZGV4ID0gaW5kZXggLyA2NDsKKyAgICAgICAgaWYgKGFycmF5SW5kZXggPj0gYml0cy5sZW5ndGgpIHsKKyAgICAgICAgICAgIGVuc3VyZUNhcGFjaXR5KGFycmF5SW5kZXggKyAxKTsKKyAgICAgICAgfQorICAgICAgICBiaXRzW2FycmF5SW5kZXhdIF49ICgxTCA8PCBpbmRleCk7CisgICAgICAgIGxvbmdDb3VudCA9IE1hdGgubWF4KGxvbmdDb3VudCwgYXJyYXlJbmRleCArIDEpOworICAgICAgICBzaHJpbmtTaXplKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrSW5kZXgoaW50IGluZGV4KSB7CisgICAgICAgIGlmIChpbmRleCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJpbmRleCA8IDA6ICIgKyBpbmRleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tSYW5nZShpbnQgZnJvbUluZGV4LCBpbnQgdG9JbmRleCkgeworICAgICAgICBpZiAoKGZyb21JbmRleCB8IHRvSW5kZXgpIDwgMCB8fCB0b0luZGV4IDwgZnJvbUluZGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiZnJvbUluZGV4PSIgKyBmcm9tSW5kZXggKyAiIHRvSW5kZXg9IiArIHRvSW5kZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQml0U2V0fSBjb250YWluaW5nIHRoZQorICAgICAqIHJhbmdlIG9mIGJpdHMge0Bjb2RlIFtmcm9tSW5kZXgsIHRvSW5kZXgpfSwgc2hpZnRlZCBkb3duIHNvIHRoYXQgdGhlIGJpdAorICAgICAqIGF0IHtAY29kZSBmcm9tSW5kZXh9IGlzIGF0IGJpdCAwIGluIHRoZSBuZXcge0Bjb2RlIEJpdFNldH0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZnJvbUluZGV4fSBvciB7QGNvZGUgdG9JbmRleH0gaXMgbmVnYXRpdmUsIG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIHRvSW5kZXh9IGlzIHNtYWxsZXIgdGhhbiB7QGNvZGUgZnJvbUluZGV4fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQml0U2V0IGdldChpbnQgZnJvbUluZGV4LCBpbnQgdG9JbmRleCkgeworICAgICAgICBjaGVja1JhbmdlKGZyb21JbmRleCwgdG9JbmRleCk7CisKKyAgICAgICAgaW50IGxhc3QgPSA2NCAqIGxvbmdDb3VudDsKKyAgICAgICAgaWYgKGZyb21JbmRleCA+PSBsYXN0IHx8IGZyb21JbmRleCA9PSB0b0luZGV4KSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEJpdFNldCgwKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodG9JbmRleCA+IGxhc3QpIHsKKyAgICAgICAgICAgIHRvSW5kZXggPSBsYXN0OworICAgICAgICB9CisKKyAgICAgICAgaW50IGZpcnN0QXJyYXlJbmRleCA9IGZyb21JbmRleCAvIDY0OworICAgICAgICBpbnQgbGFzdEFycmF5SW5kZXggPSAodG9JbmRleCAtIDEpIC8gNjQ7CisgICAgICAgIGxvbmcgbG93TWFzayA9IEFMTF9PTkVTIDw8IGZyb21JbmRleDsKKyAgICAgICAgbG9uZyBoaWdoTWFzayA9IEFMTF9PTkVTID4+PiAtdG9JbmRleDsKKworICAgICAgICBpZiAoZmlyc3RBcnJheUluZGV4ID09IGxhc3RBcnJheUluZGV4KSB7CisgICAgICAgICAgICBsb25nIHJlc3VsdCA9IChiaXRzW2ZpcnN0QXJyYXlJbmRleF0gJiAobG93TWFzayAmIGhpZ2hNYXNrKSkgPj4+IGZyb21JbmRleDsKKyAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQml0U2V0KDApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBCaXRTZXQobmV3IGxvbmdbXSB7IHJlc3VsdCB9KTsKKyAgICAgICAgfQorCisgICAgICAgIGxvbmdbXSBuZXdCaXRzID0gbmV3IGxvbmdbbGFzdEFycmF5SW5kZXggLSBmaXJzdEFycmF5SW5kZXggKyAxXTsKKworICAgICAgICAvLyBmaXJzdCBmaWxsIGluIHRoZSBmaXJzdCBhbmQgbGFzdCBpbmRleGVzIGluIHRoZSBuZXcgQml0U2V0CisgICAgICAgIG5ld0JpdHNbMF0gPSBiaXRzW2ZpcnN0QXJyYXlJbmRleF0gJiBsb3dNYXNrOworICAgICAgICBuZXdCaXRzW25ld0JpdHMubGVuZ3RoIC0gMV0gPSBiaXRzW2xhc3RBcnJheUluZGV4XSAmIGhpZ2hNYXNrOworCisgICAgICAgIC8vIGZpbGwgaW4gdGhlIGluIGJldHdlZW4gZWxlbWVudHMgb2YgdGhlIG5ldyBCaXRTZXQKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBsYXN0QXJyYXlJbmRleCAtIGZpcnN0QXJyYXlJbmRleDsgaSsrKSB7CisgICAgICAgICAgICBuZXdCaXRzW2ldID0gYml0c1tmaXJzdEFycmF5SW5kZXggKyBpXTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHNoaWZ0IGFsbCB0aGUgZWxlbWVudHMgaW4gdGhlIG5ldyBCaXRTZXQgdG8gdGhlIHJpZ2h0CisgICAgICAgIGludCBudW1CaXRzVG9TaGlmdCA9IGZyb21JbmRleCAlIDY0OworICAgICAgICBpbnQgYWN0dWFsTGVuID0gbmV3Qml0cy5sZW5ndGg7CisgICAgICAgIGlmIChudW1CaXRzVG9TaGlmdCAhPSAwKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5ld0JpdHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAvLyBzaGlmdCB0aGUgY3VycmVudCBlbGVtZW50IHRvIHRoZSByaWdodCByZWdhcmRsZXNzIG9mCisgICAgICAgICAgICAgICAgLy8gc2lnbgorICAgICAgICAgICAgICAgIG5ld0JpdHNbaV0gPSBuZXdCaXRzW2ldID4+PiAobnVtQml0c1RvU2hpZnQpOworCisgICAgICAgICAgICAgICAgLy8gYXBwbHkgdGhlIGxhc3QgeCBiaXRzIG9mIG5ld0JpdHNbaSsxXSB0byB0aGUgY3VycmVudAorICAgICAgICAgICAgICAgIC8vIGVsZW1lbnQKKyAgICAgICAgICAgICAgICBpZiAoaSAhPSBuZXdCaXRzLmxlbmd0aCAtIDEpIHsKKyAgICAgICAgICAgICAgICAgICAgbmV3Qml0c1tpXSB8PSBuZXdCaXRzW2kgKyAxXSA8PCAtbnVtQml0c1RvU2hpZnQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChuZXdCaXRzW2ldICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgYWN0dWFsTGVuID0gaSArIDE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgQml0U2V0KG5ld0JpdHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGJpdCBhdCBpbmRleCB7QGNvZGUgaW5kZXh9IHRvIHtAY29kZSBzdGF0ZX0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYge0Bjb2RlIGluZGV4IDwgMH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0KGludCBpbmRleCwgYm9vbGVhbiBzdGF0ZSkgeworICAgICAgICBpZiAoc3RhdGUpIHsKKyAgICAgICAgICAgIHNldChpbmRleCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjbGVhcihpbmRleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSByYW5nZSBvZiBiaXRzIHtAY29kZSBbZnJvbUluZGV4LCB0b0luZGV4KX0gdG8ge0Bjb2RlIHN0YXRlfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBmcm9tSW5kZXh9IG9yIHtAY29kZSB0b0luZGV4fSBpcyBuZWdhdGl2ZSwgb3IgaWYKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgdG9JbmRleH0gaXMgc21hbGxlciB0aGFuIHtAY29kZSBmcm9tSW5kZXh9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldChpbnQgZnJvbUluZGV4LCBpbnQgdG9JbmRleCwgYm9vbGVhbiBzdGF0ZSkgeworICAgICAgICBpZiAoc3RhdGUpIHsKKyAgICAgICAgICAgIHNldChmcm9tSW5kZXgsIHRvSW5kZXgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY2xlYXIoZnJvbUluZGV4LCB0b0luZGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENsZWFycyBhbGwgdGhlIGJpdHMgaW4gdGhpcyB7QGNvZGUgQml0U2V0fS4gVGhpcyBtZXRob2QgZG9lcyBub3QgY2hhbmdlIHRoZSBjYXBhY2l0eS4KKyAgICAgKiBVc2Uge0Bjb2RlIGNsZWFyfSBpZiB5b3Ugd2FudCB0byByZXVzZSB0aGlzIHtAY29kZSBCaXRTZXR9IHdpdGggdGhlIHNhbWUgY2FwYWNpdHksIGJ1dAorICAgICAqIGNyZWF0ZSBhIG5ldyB7QGNvZGUgQml0U2V0fSBpZiB5b3UncmUgdHJ5aW5nIHRvIHBvdGVudGlhbGx5IHJlY2xhaW0gbWVtb3J5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBBcnJheXMuZmlsbChiaXRzLCAwLCBsb25nQ291bnQsIDBMKTsKKyAgICAgICAgbG9uZ0NvdW50ID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSByYW5nZSBvZiBiaXRzIHtAY29kZSBbZnJvbUluZGV4LCB0b0luZGV4KX0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZnJvbUluZGV4fSBvciB7QGNvZGUgdG9JbmRleH0gaXMgbmVnYXRpdmUsIG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIHRvSW5kZXh9IGlzIHNtYWxsZXIgdGhhbiB7QGNvZGUgZnJvbUluZGV4fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXQoaW50IGZyb21JbmRleCwgaW50IHRvSW5kZXgpIHsKKyAgICAgICAgY2hlY2tSYW5nZShmcm9tSW5kZXgsIHRvSW5kZXgpOworICAgICAgICBpZiAoZnJvbUluZGV4ID09IHRvSW5kZXgpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpbnQgZmlyc3RBcnJheUluZGV4ID0gZnJvbUluZGV4IC8gNjQ7CisgICAgICAgIGludCBsYXN0QXJyYXlJbmRleCA9ICh0b0luZGV4IC0gMSkgLyA2NDsKKyAgICAgICAgaWYgKGxhc3RBcnJheUluZGV4ID49IGJpdHMubGVuZ3RoKSB7CisgICAgICAgICAgICBlbnN1cmVDYXBhY2l0eShsYXN0QXJyYXlJbmRleCArIDEpOworICAgICAgICB9CisKKyAgICAgICAgbG9uZyBsb3dNYXNrID0gQUxMX09ORVMgPDwgZnJvbUluZGV4OworICAgICAgICBsb25nIGhpZ2hNYXNrID0gQUxMX09ORVMgPj4+IC10b0luZGV4OworICAgICAgICBpZiAoZmlyc3RBcnJheUluZGV4ID09IGxhc3RBcnJheUluZGV4KSB7CisgICAgICAgICAgICBiaXRzW2ZpcnN0QXJyYXlJbmRleF0gfD0gKGxvd01hc2sgJiBoaWdoTWFzayk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpbnQgaSA9IGZpcnN0QXJyYXlJbmRleDsKKyAgICAgICAgICAgIGJpdHNbaSsrXSB8PSBsb3dNYXNrOworICAgICAgICAgICAgd2hpbGUgKGkgPCBsYXN0QXJyYXlJbmRleCkgeworICAgICAgICAgICAgICAgIGJpdHNbaSsrXSB8PSBBTExfT05FUzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJpdHNbaSsrXSB8PSBoaWdoTWFzazsKKyAgICAgICAgfQorICAgICAgICBsb25nQ291bnQgPSBNYXRoLm1heChsb25nQ291bnQsIGxhc3RBcnJheUluZGV4ICsgMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xlYXJzIHRoZSByYW5nZSBvZiBiaXRzIHtAY29kZSBbZnJvbUluZGV4LCB0b0luZGV4KX0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZnJvbUluZGV4fSBvciB7QGNvZGUgdG9JbmRleH0gaXMgbmVnYXRpdmUsIG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIHRvSW5kZXh9IGlzIHNtYWxsZXIgdGhhbiB7QGNvZGUgZnJvbUluZGV4fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbGVhcihpbnQgZnJvbUluZGV4LCBpbnQgdG9JbmRleCkgeworICAgICAgICBjaGVja1JhbmdlKGZyb21JbmRleCwgdG9JbmRleCk7CisgICAgICAgIGlmIChmcm9tSW5kZXggPT0gdG9JbmRleCB8fCBsb25nQ291bnQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGludCBsYXN0ID0gNjQgKiBsb25nQ291bnQ7CisgICAgICAgIGlmIChmcm9tSW5kZXggPj0gbGFzdCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGlmICh0b0luZGV4ID4gbGFzdCkgeworICAgICAgICAgICAgdG9JbmRleCA9IGxhc3Q7CisgICAgICAgIH0KKyAgICAgICAgaW50IGZpcnN0QXJyYXlJbmRleCA9IGZyb21JbmRleCAvIDY0OworICAgICAgICBpbnQgbGFzdEFycmF5SW5kZXggPSAodG9JbmRleCAtIDEpIC8gNjQ7CisKKyAgICAgICAgbG9uZyBsb3dNYXNrID0gQUxMX09ORVMgPDwgZnJvbUluZGV4OworICAgICAgICBsb25nIGhpZ2hNYXNrID0gQUxMX09ORVMgPj4+IC10b0luZGV4OworICAgICAgICBpZiAoZmlyc3RBcnJheUluZGV4ID09IGxhc3RBcnJheUluZGV4KSB7CisgICAgICAgICAgICBiaXRzW2ZpcnN0QXJyYXlJbmRleF0gJj0gfihsb3dNYXNrICYgaGlnaE1hc2spOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW50IGkgPSBmaXJzdEFycmF5SW5kZXg7CisgICAgICAgICAgICBiaXRzW2krK10gJj0gfmxvd01hc2s7CisgICAgICAgICAgICB3aGlsZSAoaSA8IGxhc3RBcnJheUluZGV4KSB7CisgICAgICAgICAgICAgICAgYml0c1tpKytdID0gMEw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBiaXRzW2krK10gJj0gfmhpZ2hNYXNrOworICAgICAgICB9CisgICAgICAgIHNocmlua1NpemUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGbGlwcyB0aGUgcmFuZ2Ugb2YgYml0cyB7QGNvZGUgW2Zyb21JbmRleCwgdG9JbmRleCl9LgorICAgICAqCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGZyb21JbmRleH0gb3Ige0Bjb2RlIHRvSW5kZXh9IGlzIG5lZ2F0aXZlLCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSB0b0luZGV4fSBpcyBzbWFsbGVyIHRoYW4ge0Bjb2RlIGZyb21JbmRleH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgZmxpcChpbnQgZnJvbUluZGV4LCBpbnQgdG9JbmRleCkgeworICAgICAgICBjaGVja1JhbmdlKGZyb21JbmRleCwgdG9JbmRleCk7CisgICAgICAgIGlmIChmcm9tSW5kZXggPT0gdG9JbmRleCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGludCBmaXJzdEFycmF5SW5kZXggPSBmcm9tSW5kZXggLyA2NDsKKyAgICAgICAgaW50IGxhc3RBcnJheUluZGV4ID0gKHRvSW5kZXggLSAxKSAvIDY0OworICAgICAgICBpZiAobGFzdEFycmF5SW5kZXggPj0gYml0cy5sZW5ndGgpIHsKKyAgICAgICAgICAgIGVuc3VyZUNhcGFjaXR5KGxhc3RBcnJheUluZGV4ICsgMSk7CisgICAgICAgIH0KKworICAgICAgICBsb25nIGxvd01hc2sgPSBBTExfT05FUyA8PCBmcm9tSW5kZXg7CisgICAgICAgIGxvbmcgaGlnaE1hc2sgPSBBTExfT05FUyA+Pj4gLXRvSW5kZXg7CisgICAgICAgIGlmIChmaXJzdEFycmF5SW5kZXggPT0gbGFzdEFycmF5SW5kZXgpIHsKKyAgICAgICAgICAgIGJpdHNbZmlyc3RBcnJheUluZGV4XSBePSAobG93TWFzayAmIGhpZ2hNYXNrKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGludCBpID0gZmlyc3RBcnJheUluZGV4OworICAgICAgICAgICAgYml0c1tpKytdIF49IGxvd01hc2s7CisgICAgICAgICAgICB3aGlsZSAoaSA8IGxhc3RBcnJheUluZGV4KSB7CisgICAgICAgICAgICAgICAgYml0c1tpKytdIF49IEFMTF9PTkVTOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYml0c1tpKytdIF49IGhpZ2hNYXNrOworICAgICAgICB9CisgICAgICAgIGxvbmdDb3VudCA9IE1hdGgubWF4KGxvbmdDb3VudCwgbGFzdEFycmF5SW5kZXggKyAxKTsKKyAgICAgICAgc2hyaW5rU2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB7QGNvZGUgdGhpcy5hbmQoYnMpfSBpcyBub24tZW1wdHksIGJ1dCBtYXkgYmUgZmFzdGVyIHRoYW4gY29tcHV0aW5nIHRoYXQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaW50ZXJzZWN0cyhCaXRTZXQgYnMpIHsKKyAgICAgICAgbG9uZ1tdIGJzQml0cyA9IGJzLmJpdHM7CisgICAgICAgIGludCBsZW5ndGggPSBNYXRoLm1pbih0aGlzLmxvbmdDb3VudCwgYnMubG9uZ0NvdW50KTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgeworICAgICAgICAgICAgaWYgKChiaXRzW2ldICYgYnNCaXRzW2ldKSAhPSAwTCkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dpY2FsbHkgYW5kcyB0aGUgYml0cyBvZiB0aGlzIHtAY29kZSBCaXRTZXR9IHdpdGgge0Bjb2RlIGJzfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhbmQoQml0U2V0IGJzKSB7CisgICAgICAgIGludCBtaW5TaXplID0gTWF0aC5taW4odGhpcy5sb25nQ291bnQsIGJzLmxvbmdDb3VudCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWluU2l6ZTsgKytpKSB7CisgICAgICAgICAgICBiaXRzW2ldICY9IGJzLmJpdHNbaV07CisgICAgICAgIH0KKyAgICAgICAgQXJyYXlzLmZpbGwoYml0cywgbWluU2l6ZSwgbG9uZ0NvdW50LCAwTCk7CisgICAgICAgIHNocmlua1NpemUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbGVhcnMgYWxsIGJpdHMgaW4gdGhpcyB7QGNvZGUgQml0U2V0fSB3aGljaCBhcmUgYWxzbyBzZXQgaW4ge0Bjb2RlIGJzfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhbmROb3QoQml0U2V0IGJzKSB7CisgICAgICAgIGludCBtaW5TaXplID0gTWF0aC5taW4odGhpcy5sb25nQ291bnQsIGJzLmxvbmdDb3VudCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWluU2l6ZTsgKytpKSB7CisgICAgICAgICAgICBiaXRzW2ldICY9IH5icy5iaXRzW2ldOworICAgICAgICB9CisgICAgICAgIHNocmlua1NpemUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dpY2FsbHkgb3JzIHRoZSBiaXRzIG9mIHRoaXMge0Bjb2RlIEJpdFNldH0gd2l0aCB7QGNvZGUgYnN9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG9yKEJpdFNldCBicykgeworICAgICAgICBpbnQgbWluU2l6ZSA9IE1hdGgubWluKHRoaXMubG9uZ0NvdW50LCBicy5sb25nQ291bnQpOworICAgICAgICBpbnQgbWF4U2l6ZSA9IE1hdGgubWF4KHRoaXMubG9uZ0NvdW50LCBicy5sb25nQ291bnQpOworICAgICAgICBlbnN1cmVDYXBhY2l0eShtYXhTaXplKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtaW5TaXplOyArK2kpIHsKKyAgICAgICAgICAgIGJpdHNbaV0gfD0gYnMuYml0c1tpXTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYnMubG9uZ0NvdW50ID4gbWluU2l6ZSkgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShicy5iaXRzLCBtaW5TaXplLCBiaXRzLCBtaW5TaXplLCBtYXhTaXplIC0gbWluU2l6ZSk7CisgICAgICAgIH0KKyAgICAgICAgbG9uZ0NvdW50ID0gbWF4U2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dpY2FsbHkgeG9ycyB0aGUgYml0cyBvZiB0aGlzIHtAY29kZSBCaXRTZXR9IHdpdGgge0Bjb2RlIGJzfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB4b3IoQml0U2V0IGJzKSB7CisgICAgICAgIGludCBtaW5TaXplID0gTWF0aC5taW4odGhpcy5sb25nQ291bnQsIGJzLmxvbmdDb3VudCk7CisgICAgICAgIGludCBtYXhTaXplID0gTWF0aC5tYXgodGhpcy5sb25nQ291bnQsIGJzLmxvbmdDb3VudCk7CisgICAgICAgIGVuc3VyZUNhcGFjaXR5KG1heFNpemUpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1pblNpemU7ICsraSkgeworICAgICAgICAgICAgYml0c1tpXSBePSBicy5iaXRzW2ldOworICAgICAgICB9CisgICAgICAgIGlmIChicy5sb25nQ291bnQgPiBtaW5TaXplKSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJzLmJpdHMsIG1pblNpemUsIGJpdHMsIG1pblNpemUsIG1heFNpemUgLSBtaW5TaXplKTsKKyAgICAgICAgfQorICAgICAgICBsb25nQ291bnQgPSBtYXhTaXplOworICAgICAgICBzaHJpbmtTaXplKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2FwYWNpdHkgaW4gYml0cyBvZiB0aGUgYXJyYXkgaW1wbGVtZW50aW5nIHRoaXMge0Bjb2RlIEJpdFNldH0uIFRoaXMgaXMKKyAgICAgKiB1bnJlbGF0ZWQgdG8gdGhlIGxlbmd0aCBvZiB0aGUge0Bjb2RlIEJpdFNldH0sIGFuZCBub3QgZ2VuZXJhbGx5IHVzZWZ1bC4KKyAgICAgKiBVc2Uge0BsaW5rICNuZXh0U2V0Qml0fSB0byBpdGVyYXRlLCBvciB7QGxpbmsgI2xlbmd0aH0gdG8gZmluZCB0aGUgaGlnaGVzdCBzZXQgYml0LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIGJpdHMubGVuZ3RoICogNjQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJpdHMgdXAgdG8gYW5kIGluY2x1ZGluZyB0aGUgaGlnaGVzdCBiaXQgc2V0LiBUaGlzIGlzIHVucmVsYXRlZCB0bworICAgICAqIHRoZSB7QGxpbmsgI3NpemV9IG9mIHRoZSB7QGNvZGUgQml0U2V0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGxlbmd0aCgpIHsKKyAgICAgICAgaWYgKGxvbmdDb3VudCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gNjQgKiAobG9uZ0NvdW50IC0gMSkgKyAoNjQgLSBMb25nLm51bWJlck9mTGVhZGluZ1plcm9zKGJpdHNbbG9uZ0NvdW50IC0gMV0pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUKKyAgICAgKiByZWNlaXZlcjogYSBjb21tYS1kZWxpbWl0ZWQgbGlzdCBvZiB0aGUgaW5kZXhlcyBvZiBhbGwgc2V0IGJpdHMuCisgICAgICogRm9yIGV4YW1wbGU6IHtAY29kZSAiezAsMSw4fSJ9LgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAvL1N5c3RlbS5lcnIucHJpbnRsbigiQml0U2V0W2xvbmdDb3VudD0iICsgbG9uZ0NvdW50ICsgIixiaXRzPSIgKyBBcnJheXMudG9TdHJpbmcoYml0cykgKyAiXSIpOworICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIobG9uZ0NvdW50IC8gMik7CisgICAgICAgIHNiLmFwcGVuZCgneycpOworICAgICAgICBib29sZWFuIGNvbW1hID0gZmFsc2U7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbG9uZ0NvdW50OyArK2kpIHsKKyAgICAgICAgICAgIGlmIChiaXRzW2ldICE9IDApIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IDY0OyArK2opIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKChiaXRzW2ldICYgMUwgPDwgaikgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbW1hKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCIsICIpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYSA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoNjQgKiBpICsgaik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgc2IuYXBwZW5kKCd9Jyk7CisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBiaXQgdGhhdCBpcyBzZXQgb24gb3IgYWZ0ZXIge0Bjb2RlIGluZGV4fSwgb3IgLTEKKyAgICAgKiBpZiBubyBoaWdoZXIgYml0cyBhcmUgc2V0LgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB7QGNvZGUgaW5kZXggPCAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IG5leHRTZXRCaXQoaW50IGluZGV4KSB7CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICBpbnQgYXJyYXlJbmRleCA9IGluZGV4IC8gNjQ7CisgICAgICAgIGlmIChhcnJheUluZGV4ID49IGxvbmdDb3VudCkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGxvbmcgbWFzayA9IEFMTF9PTkVTIDw8IGluZGV4OworICAgICAgICBpZiAoKGJpdHNbYXJyYXlJbmRleF0gJiBtYXNrKSAhPSAwKSB7CisgICAgICAgICAgICByZXR1cm4gNjQgKiBhcnJheUluZGV4ICsgTG9uZy5udW1iZXJPZlRyYWlsaW5nWmVyb3MoYml0c1thcnJheUluZGV4XSAmIG1hc2spOworICAgICAgICB9CisgICAgICAgIHdoaWxlICgrK2FycmF5SW5kZXggPCBsb25nQ291bnQgJiYgYml0c1thcnJheUluZGV4XSA9PSAwKSB7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFycmF5SW5kZXggPT0gbG9uZ0NvdW50KSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDY0ICogYXJyYXlJbmRleCArIExvbmcubnVtYmVyT2ZUcmFpbGluZ1plcm9zKGJpdHNbYXJyYXlJbmRleF0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBiaXQgdGhhdCBpcyBjbGVhciBvbiBvciBhZnRlciB7QGNvZGUgaW5kZXh9LgorICAgICAqIFNpbmNlIGFsbCBiaXRzIHBhc3QgdGhlIGVuZCBhcmUgaW1wbGljaXRseSBjbGVhciwgdGhpcyBuZXZlciByZXR1cm5zIC0xLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB7QGNvZGUgaW5kZXggPCAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IG5leHRDbGVhckJpdChpbnQgaW5kZXgpIHsKKyAgICAgICAgY2hlY2tJbmRleChpbmRleCk7CisgICAgICAgIGludCBhcnJheUluZGV4ID0gaW5kZXggLyA2NDsKKyAgICAgICAgaWYgKGFycmF5SW5kZXggPj0gbG9uZ0NvdW50KSB7CisgICAgICAgICAgICByZXR1cm4gaW5kZXg7CisgICAgICAgIH0KKyAgICAgICAgbG9uZyBtYXNrID0gQUxMX09ORVMgPDwgaW5kZXg7CisgICAgICAgIGlmICgofmJpdHNbYXJyYXlJbmRleF0gJiBtYXNrKSAhPSAwKSB7CisgICAgICAgICAgICByZXR1cm4gNjQgKiBhcnJheUluZGV4ICsgTG9uZy5udW1iZXJPZlRyYWlsaW5nWmVyb3MofmJpdHNbYXJyYXlJbmRleF0gJiBtYXNrKTsKKyAgICAgICAgfQorICAgICAgICB3aGlsZSAoKythcnJheUluZGV4IDwgbG9uZ0NvdW50ICYmIGJpdHNbYXJyYXlJbmRleF0gPT0gQUxMX09ORVMpIHsKKyAgICAgICAgfQorICAgICAgICBpZiAoYXJyYXlJbmRleCA9PSBsb25nQ291bnQpIHsKKyAgICAgICAgICAgIHJldHVybiBzaXplKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDY0ICogYXJyYXlJbmRleCArIExvbmcubnVtYmVyT2ZUcmFpbGluZ1plcm9zKH5iaXRzW2FycmF5SW5kZXhdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgYml0IHRoYXQgaXMgc2V0IG9uIG9yIGJlZm9yZSB7QGNvZGUgaW5kZXh9LCBvciAtMSBpZgorICAgICAqIG5vIGxvd2VyIGJpdHMgYXJlIHNldCBvciB7QGNvZGUgaW5kZXggPT0gLTF9LgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB7QGNvZGUgaW5kZXggPCAtMX0uCisgICAgICogQGhpZGUgMS43CisgICAgICovCisgICAgcHVibGljIGludCBwcmV2aW91c1NldEJpdChpbnQgaW5kZXgpIHsKKyAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tJbmRleChpbmRleCk7CisgICAgICAgIC8vIFRPRE86IG9wdGltaXplIHRoaXMuCisgICAgICAgIGZvciAoaW50IGkgPSBpbmRleDsgaSA+PSAwOyAtLWkpIHsKKyAgICAgICAgICAgIGlmIChnZXQoaSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGJpdCB0aGF0IGlzIGNsZWFyIG9uIG9yIGJlZm9yZSB7QGNvZGUgaW5kZXh9LCBvciAtMSBpZgorICAgICAqIG5vIGxvd2VyIGJpdHMgYXJlIGNsZWFyIG9yIHtAY29kZSBpbmRleCA9PSAtMX0uCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHtAY29kZSBpbmRleCA8IC0xfS4KKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHByZXZpb3VzQ2xlYXJCaXQoaW50IGluZGV4KSB7CisgICAgICAgIGlmIChpbmRleCA9PSAtMSkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGNoZWNrSW5kZXgoaW5kZXgpOworICAgICAgICAvLyBUT0RPOiBvcHRpbWl6ZSB0aGlzLgorICAgICAgICBmb3IgKGludCBpID0gaW5kZXg7IGkgPj0gMDsgLS1pKSB7CisgICAgICAgICAgICBpZiAoIWdldChpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgYWxsIHRoZSBiaXRzIGluIHRoaXMge0Bjb2RlIEJpdFNldH0gYXJlIHNldCB0byBmYWxzZSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgIHJldHVybiAobG9uZ0NvdW50ID09IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBiaXRzIHRoYXQgYXJlIHtAY29kZSB0cnVlfSBpbiB0aGlzIHtAY29kZSBCaXRTZXR9LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY2FyZGluYWxpdHkoKSB7CisgICAgICAgIGludCByZXN1bHQgPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxvbmdDb3VudDsgKytpKSB7CisgICAgICAgICAgICByZXN1bHQgKz0gTG9uZy5iaXRDb3VudChiaXRzW2ldKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8ge0Bjb2RlIEJpdFNldC52YWx1ZU9mKExvbmdCdWZmZXIud3JhcChsb25ncykpfSwgYnV0IGxpa2VseSB0byBiZSBmYXN0ZXIuCisgICAgICogVGhpcyBpcyBsaWtlbHkgdG8gYmUgdGhlIGZhc3Rlc3Qgd2F5IHRvIGNyZWF0ZSBhIHtAY29kZSBCaXRTZXR9IGJlY2F1c2UgaXQncyBjbG9zZXN0CisgICAgICogdG8gdGhlIGludGVybmFsIHJlcHJlc2VudGF0aW9uLgorICAgICAqIEBoaWRlIDEuNworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQml0U2V0IHZhbHVlT2YobG9uZ1tdIGxvbmdzKSB7CisgICAgICAgIHJldHVybiBuZXcgQml0U2V0KGxvbmdzLmNsb25lKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgQml0U2V0fSBjb3JyZXNwb25kaW5nIHRvIHtAY29kZSBsb25nQnVmZmVyfSwgaW50ZXJwcmV0ZWQgYXMgYSBsaXR0bGUtZW5kaWFuCisgICAgICogc2VxdWVuY2Ugb2YgYml0cy4gVGhpcyBtZXRob2QgZG9lcyBub3QgYWx0ZXIgdGhlIHtAY29kZSBMb25nQnVmZmVyfS4KKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEJpdFNldCB2YWx1ZU9mKExvbmdCdWZmZXIgbG9uZ0J1ZmZlcikgeworICAgICAgICAvLyBUaGUgYnVsayBnZXQgd291bGQgbXV0YXRlIExvbmdCdWZmZXIgKGV2ZW4gaWYgd2UgcmVzZXQgcG9zaXRpb24gbGF0ZXIpLCBhbmQgaXQncyBub3QKKyAgICAgICAgLy8gY2xlYXIgdGhhdCdzIGFsbG93ZWQuIE15IGFzc3VtcHRpb24gaXMgdGhhdCBpdCdzIHRoZSBsb25nW10gdmFyaWFudCB0aGF0J3MgdGhlIGNvbW1vbgorICAgICAgICAvLyBjYXNlIGFueXdheSwgc28gY29weSB0aGUgYnVmZmVyIGludG8gYSBsb25nW10uCisgICAgICAgIGxvbmdbXSBsb25ncyA9IG5ldyBsb25nW2xvbmdCdWZmZXIucmVtYWluaW5nKCldOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxvbmdzLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICBsb25nc1tpXSA9IGxvbmdCdWZmZXIuZ2V0KGxvbmdCdWZmZXIucG9zaXRpb24oKSArIGkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBCaXRTZXQudmFsdWVPZihsb25ncyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgQml0U2V0LnZhbHVlT2YoQnl0ZUJ1ZmZlci53cmFwKGJ5dGVzKSl9LgorICAgICAqIEBoaWRlIDEuNworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQml0U2V0IHZhbHVlT2YoYnl0ZVtdIGJ5dGVzKSB7CisgICAgICAgIHJldHVybiBCaXRTZXQudmFsdWVPZihCeXRlQnVmZmVyLndyYXAoYnl0ZXMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIEJpdFNldH0gY29ycmVzcG9uZGluZyB0byB7QGNvZGUgYnl0ZUJ1ZmZlcn0sIGludGVycHJldGVkIGFzIGEgbGl0dGxlLWVuZGlhbgorICAgICAqIHNlcXVlbmNlIG9mIGJpdHMuIFRoaXMgbWV0aG9kIGRvZXMgbm90IGFsdGVyIHRoZSB7QGNvZGUgQnl0ZUJ1ZmZlcn0uCisgICAgICogQGhpZGUgMS43CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCaXRTZXQgdmFsdWVPZihCeXRlQnVmZmVyIGJ5dGVCdWZmZXIpIHsKKyAgICAgICAgYnl0ZUJ1ZmZlciA9IGJ5dGVCdWZmZXIuc2xpY2UoKS5vcmRlcihCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisgICAgICAgIGxvbmdbXSBsb25ncyA9IGFycmF5Rm9yQml0cyhieXRlQnVmZmVyLnJlbWFpbmluZygpICogOCk7CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgd2hpbGUgKGJ5dGVCdWZmZXIucmVtYWluaW5nKCkgPj0gU2l6ZU9mLkxPTkcpIHsKKyAgICAgICAgICAgIGxvbmdzW2krK10gPSBieXRlQnVmZmVyLmdldExvbmcoKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBqID0gMDsgYnl0ZUJ1ZmZlci5oYXNSZW1haW5pbmcoKTsgKytqKSB7CisgICAgICAgICAgICBsb25nc1tpXSB8PSAoKCgobG9uZykgYnl0ZUJ1ZmZlci5nZXQoKSkgJiAweGZmKSA8PCAoOCpqKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIEJpdFNldC52YWx1ZU9mKGxvbmdzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBsb25nW119IGNvbnRhaW5pbmcgYSBsaXR0bGUtZW5kaWFuIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBiaXRzIG9mCisgICAgICogdGhpcyB7QGNvZGUgQml0U2V0fSwgc3VpdGFibGUgZm9yIHBhc3NpbmcgdG8ge0Bjb2RlIHZhbHVlT2Z9IHRvIHJlY29uc3RydWN0CisgICAgICogdGhpcyB7QGNvZGUgQml0U2V0fS4KKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZ1tdIHRvTG9uZ0FycmF5KCkgeworICAgICAgICByZXR1cm4gQXJyYXlzLmNvcHlPZihiaXRzLCBsb25nQ291bnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIGJ5dGVbXX0gY29udGFpbmluZyBhIGxpdHRsZS1lbmRpYW4gcmVwcmVzZW50YXRpb24gdGhlIGJpdHMgb2YKKyAgICAgKiB0aGlzIHtAY29kZSBCaXRTZXR9LCBzdWl0YWJsZSBmb3IgcGFzc2luZyB0byB7QGNvZGUgdmFsdWVPZn0gdG8gcmVjb25zdHJ1Y3QKKyAgICAgKiB0aGlzIHtAY29kZSBCaXRTZXR9LgorICAgICAqIEBoaWRlIDEuNworICAgICAqLworICAgIHB1YmxpYyBieXRlW10gdG9CeXRlQXJyYXkoKSB7CisgICAgICAgIGludCBiaXRDb3VudCA9IGxlbmd0aCgpOworICAgICAgICBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbKGJpdENvdW50ICsgNykvIDhdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlc3VsdC5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgaW50IGxvd0JpdCA9IDggKiBpOworICAgICAgICAgICAgaW50IGFycmF5SW5kZXggPSBsb3dCaXQgLyA2NDsKKyAgICAgICAgICAgIHJlc3VsdFtpXSA9IChieXRlKSAoYml0c1thcnJheUluZGV4XSA+Pj4gbG93Qml0KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIG9pcykgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgb2lzLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisgICAgICAgIC8vIFRoZSBzZXJpYWxpemVkIGZvcm0gZG9lc24ndCBpbmNsdWRlIGEgJ2xvbmdDb3VudCcgZmllbGQsIHNvIHdlJ2xsIGhhdmUgdG8gc2NhbiB0aGUgYXJyYXkuCisgICAgICAgIHRoaXMubG9uZ0NvdW50ID0gdGhpcy5iaXRzLmxlbmd0aDsKKyAgICAgICAgc2hyaW5rU2l6ZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvQ2FsZW5kYXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvQ2FsZW5kYXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZWY2ZTI2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9DYWxlbmRhci5qYXZhCkBAIC0wLDAgKzEsMTU0MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1GaWVsZDsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnRleHQuRGF0ZUZvcm1hdFN5bWJvbHM7CitpbXBvcnQgbGliY29yZS5pY3UuSUNVOworaW1wb3J0IGxpYmNvcmUuaWN1LkxvY2FsZURhdGE7CisKKy8qKgorICoge0Bjb2RlIENhbGVuZGFyfSBpcyBhbiBhYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBjb252ZXJ0aW5nIGJldHdlZW4gYQorICoge0Bjb2RlIERhdGV9IG9iamVjdCBhbmQgYSBzZXQgb2YgaW50ZWdlciBmaWVsZHMgc3VjaCBhcworICoge0Bjb2RlIFlFQVJ9LCB7QGNvZGUgTU9OVEh9LCB7QGNvZGUgREFZfSwKKyAqIHtAY29kZSBIT1VSfSwgYW5kIHNvIG9uLiAoQSB7QGNvZGUgRGF0ZX0gb2JqZWN0IHJlcHJlc2VudHMgYQorICogc3BlY2lmaWMgaW5zdGFudCBpbiB0aW1lIHdpdGggbWlsbGlzZWNvbmQgcHJlY2lzaW9uLiBTZWUge0BsaW5rIERhdGV9IGZvcgorICogaW5mb3JtYXRpb24gYWJvdXQgdGhlIHtAY29kZSBEYXRlfSBjbGFzcy4pCisgKgorICogPHA+CisgKiBTdWJjbGFzc2VzIG9mIHtAY29kZSBDYWxlbmRhcn0gaW50ZXJwcmV0IGEge0Bjb2RlIERhdGV9CisgKiBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIG9mIGEgc3BlY2lmaWMgY2FsZW5kYXIgc3lzdGVtLgorICoKKyAqIDxwPgorICogTGlrZSBvdGhlciBsb2NhbGUtc2Vuc2l0aXZlIGNsYXNzZXMsIHtAY29kZSBDYWxlbmRhcn0gcHJvdmlkZXMgYSBjbGFzcworICogbWV0aG9kLCB7QGNvZGUgZ2V0SW5zdGFuY2V9LCBmb3IgZ2V0dGluZyBhIGRlZmF1bHQgaW5zdGFuY2Ugb2YKKyAqIHRoaXMgY2xhc3MgZm9yIGdlbmVyYWwgdXNlLiB7QGNvZGUgQ2FsZW5kYXJ9J3Mge0Bjb2RlIGdldEluc3RhbmNlfSBtZXRob2QKKyAqIHJldHVybnMgYSBjYWxlbmRhciB3aG9zZSBsb2NhbGUgaXMgYmFzZWQgb24gc3lzdGVtIHNldHRpbmdzIGFuZCB3aG9zZSB0aW1lIGZpZWxkcworICogaGF2ZSBiZWVuIGluaXRpYWxpemVkIHdpdGggdGhlIGN1cnJlbnQgZGF0ZSBhbmQgdGltZTogPGJsb2NrcXVvdGU+CisgKgorICogPHByZT5DYWxlbmRhciByaWdodE5vdyA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk8L3ByZT4KKyAqCisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+CisgKiBBIHtAY29kZSBDYWxlbmRhcn0gb2JqZWN0IGNhbiBwcm9kdWNlIGFsbCB0aGUgdGltZSBmaWVsZCB2YWx1ZXMgbmVlZGVkCisgKiB0byBpbXBsZW1lbnQgdGhlIGRhdGUtdGltZSBmb3JtYXR0aW5nIGZvciBhIHBhcnRpY3VsYXIgbGFuZ3VhZ2UgYW5kIGNhbGVuZGFyCisgKiBzdHlsZSAoZm9yIGV4YW1wbGUsIEphcGFuZXNlLUdyZWdvcmlhbiwgSmFwYW5lc2UtVHJhZGl0aW9uYWwpLgorICoge0Bjb2RlIENhbGVuZGFyfSBkZWZpbmVzIHRoZSByYW5nZSBvZiB2YWx1ZXMgcmV0dXJuZWQgYnkgY2VydGFpbgorICogZmllbGRzLCBhcyB3ZWxsIGFzIHRoZWlyIG1lYW5pbmcuIEZvciBleGFtcGxlLCB0aGUgZmlyc3QgbW9udGggb2YgdGhlIHllYXIKKyAqIGhhcyB2YWx1ZSB7QGNvZGUgTU9OVEh9ID09IHtAY29kZSBKQU5VQVJZfSBmb3IgYWxsIGNhbGVuZGFycy4KKyAqIE90aGVyIHZhbHVlcyBhcmUgZGVmaW5lZCBieSB0aGUgY29uY3JldGUgc3ViY2xhc3MsIHN1Y2ggYXMge0Bjb2RlIEVSQX0KKyAqIGFuZCB7QGNvZGUgWUVBUn0uIFNlZSBpbmRpdmlkdWFsIGZpZWxkIGRvY3VtZW50YXRpb24gYW5kIHN1YmNsYXNzCisgKiBkb2N1bWVudGF0aW9uIGZvciBkZXRhaWxzLgorICoKKyAqIDxwPgorICogV2hlbiBhIHtAY29kZSBDYWxlbmRhcn0gaXMgPGVtPmxlbmllbnQ8L2VtPiwgaXQgYWNjZXB0cyBhIHdpZGVyCisgKiByYW5nZSBvZiBmaWVsZCB2YWx1ZXMgdGhhbiBpdCBwcm9kdWNlcy4gRm9yIGV4YW1wbGUsIGEgbGVuaWVudAorICoge0Bjb2RlIEdyZWdvcmlhbkNhbGVuZGFyfSBpbnRlcnByZXRzIHtAY29kZSBNT05USH0gPT0KKyAqIHtAY29kZSBKQU5VQVJZfSwge0Bjb2RlIERBWV9PRl9NT05USH0gPT0gMzIgYXMgRmVicnVhcnkgMS4gQQorICogbm9uLWxlbmllbnQge0Bjb2RlIEdyZWdvcmlhbkNhbGVuZGFyfSB0aHJvd3MgYW4gZXhjZXB0aW9uIHdoZW4gZ2l2ZW4KKyAqIG91dC1vZi1yYW5nZSBmaWVsZCBzZXR0aW5ncy4gV2hlbiBjYWxlbmRhcnMgcmVjb21wdXRlIGZpZWxkIHZhbHVlcyBmb3IgcmV0dXJuCisgKiBieSB7QGNvZGUgZ2V0KCl9LCB0aGV5IG5vcm1hbGl6ZSB0aGVtLiBGb3IgZXhhbXBsZSwgYQorICoge0Bjb2RlIEdyZWdvcmlhbkNhbGVuZGFyfSBhbHdheXMgcHJvZHVjZXMge0Bjb2RlIERBWV9PRl9NT05USH0KKyAqIHZhbHVlcyBiZXR3ZWVuIDEgYW5kIHRoZSBsZW5ndGggb2YgdGhlIG1vbnRoLgorICoKKyAqIDxwPgorICoge0Bjb2RlIENhbGVuZGFyfSBkZWZpbmVzIGEgbG9jYWxlLXNwZWNpZmljIHNldmVuIGRheSB3ZWVrIHVzaW5nIHR3bworICogcGFyYW1ldGVyczogdGhlIGZpcnN0IGRheSBvZiB0aGUgd2VlayBhbmQgdGhlIG1pbmltYWwgZGF5cyBpbiBmaXJzdCB3ZWVrCisgKiAoZnJvbSAxIHRvIDcpLiBUaGVzZSBudW1iZXJzIGFyZSB0YWtlbiBmcm9tIHRoZSBsb2NhbGUgcmVzb3VyY2UgZGF0YSB3aGVuIGEKKyAqIHtAY29kZSBDYWxlbmRhcn0gaXMgY29uc3RydWN0ZWQuIFRoZXkgbWF5IGFsc28gYmUgc3BlY2lmaWVkIGV4cGxpY2l0bHkKKyAqIHRocm91Z2ggdGhlIEFQSS4KKyAqCisgKiA8cD4KKyAqIFdoZW4gc2V0dGluZyBvciBnZXR0aW5nIHRoZSB7QGNvZGUgV0VFS19PRl9NT05USH0gb3IKKyAqIHtAY29kZSBXRUVLX09GX1lFQVJ9IGZpZWxkcywge0Bjb2RlIENhbGVuZGFyfSBtdXN0IGRldGVybWluZQorICogdGhlIGZpcnN0IHdlZWsgb2YgdGhlIG1vbnRoIG9yIHllYXIgYXMgYSByZWZlcmVuY2UgcG9pbnQuIFRoZSBmaXJzdCB3ZWVrIG9mIGEKKyAqIG1vbnRoIG9yIHllYXIgaXMgZGVmaW5lZCBhcyB0aGUgZWFybGllc3Qgc2V2ZW4gZGF5IHBlcmlvZCBiZWdpbm5pbmcgb24KKyAqIHtAY29kZSBnZXRGaXJzdERheU9mV2VlaygpfSBhbmQgY29udGFpbmluZyBhdCBsZWFzdAorICoge0Bjb2RlIGdldE1pbmltYWxEYXlzSW5GaXJzdFdlZWsoKX0gZGF5cyBvZiB0aGF0IG1vbnRoIG9yIHllYXIuIFdlZWtzCisgKiBudW1iZXJlZCAuLi4sIC0xLCAwIHByZWNlZGUgdGhlIGZpcnN0IHdlZWs7IHdlZWtzIG51bWJlcmVkIDIsIDMsLi4uIGZvbGxvdworICogaXQuIE5vdGUgdGhhdCB0aGUgbm9ybWFsaXplZCBudW1iZXJpbmcgcmV0dXJuZWQgYnkge0Bjb2RlIGdldCgpfSBtYXkKKyAqIGJlIGRpZmZlcmVudC4gRm9yIGV4YW1wbGUsIGEgc3BlY2lmaWMge0Bjb2RlIENhbGVuZGFyfSBzdWJjbGFzcyBtYXkKKyAqIGRlc2lnbmF0ZSB0aGUgd2VlayBiZWZvcmUgd2VlayAxIG9mIGEgeWVhciBhcyB3ZWVrIDxlbT5uPC9lbT4gb2YgdGhlCisgKiBwcmV2aW91cyB5ZWFyLgorICoKKyAqIDxwPgorICogV2hlbiBjb21wdXRpbmcgYSB7QGNvZGUgRGF0ZX0gZnJvbSB0aW1lIGZpZWxkcywgdHdvIHNwZWNpYWwKKyAqIGNpcmN1bXN0YW5jZXMgbWF5IGFyaXNlOiB0aGVyZSBtYXkgYmUgaW5zdWZmaWNpZW50IGluZm9ybWF0aW9uIHRvIGNvbXB1dGUgdGhlCisgKiB7QGNvZGUgRGF0ZX0gKHN1Y2ggYXMgb25seSB5ZWFyIGFuZCBtb250aCBidXQgbm8gZGF5IGluIHRoZSBtb250aCksIG9yCisgKiB0aGVyZSBtYXkgYmUgaW5jb25zaXN0ZW50IGluZm9ybWF0aW9uIChzdWNoIGFzICJUdWVzZGF5LCBKdWx5IDE1LCAxOTk2IiAtLQorICogSnVseSAxNSwgMTk5NiBpcyBhY3R1YWxseSBhIE1vbmRheSkuCisgKgorICogPHA+CisgKiA8c3Ryb25nPkluc3VmZmljaWVudCBpbmZvcm1hdGlvbi48L3N0cm9uZz4gVGhlIGNhbGVuZGFyIHdpbGwgdXNlIGRlZmF1bHQKKyAqIGluZm9ybWF0aW9uIHRvIHNwZWNpZnkgdGhlIG1pc3NpbmcgZmllbGRzLiBUaGlzIG1heSB2YXJ5IGJ5IGNhbGVuZGFyOyBmb3IgdGhlCisgKiBHcmVnb3JpYW4gY2FsZW5kYXIsIHRoZSBkZWZhdWx0IGZvciBhIGZpZWxkIGlzIHRoZSBzYW1lIGFzIHRoYXQgb2YgdGhlIHN0YXJ0CisgKiBvZiB0aGUgZXBvY2g6IGkuZS4sIFlFQVIgPSAxOTcwLCBNT05USCA9IEpBTlVBUlksIERBVEUgPSAxLCBldGMuCisgKgorICogPHA+CisgKiA8c3Ryb25nPkluY29uc2lzdGVudCBpbmZvcm1hdGlvbi48L3N0cm9uZz4gSWYgZmllbGRzIGNvbmZsaWN0LCB0aGUgY2FsZW5kYXIKKyAqIHdpbGwgZ2l2ZSBwcmVmZXJlbmNlIHRvIGZpZWxkcyBzZXQgbW9yZSByZWNlbnRseS4gRm9yIGV4YW1wbGUsIHdoZW4KKyAqIGRldGVybWluaW5nIHRoZSBkYXksIHRoZSBjYWxlbmRhciB3aWxsIGxvb2sgZm9yIG9uZSBvZiB0aGUgZm9sbG93aW5nCisgKiBjb21iaW5hdGlvbnMgb2YgZmllbGRzLiBUaGUgbW9zdCByZWNlbnQgY29tYmluYXRpb24sIGFzIGRldGVybWluZWQgYnkgdGhlCisgKiBtb3N0IHJlY2VudGx5IHNldCBzaW5nbGUgZmllbGQsIHdpbGwgYmUgdXNlZC4KKyAqCisgKiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogTU9OVEggKyBEQVlfT0ZfTU9OVEgKKyAqIE1PTlRIICsgV0VFS19PRl9NT05USCArIERBWV9PRl9XRUVLCisgKiBNT05USCArIERBWV9PRl9XRUVLX0lOX01PTlRIICsgREFZX09GX1dFRUsKKyAqIERBWV9PRl9ZRUFSCisgKiBEQVlfT0ZfV0VFSyArIFdFRUtfT0ZfWUVBUjwvcHJlPgorICoKKyAqIDwvYmxvY2txdW90ZT4KKyAqCisgKiBGb3IgdGhlIHRpbWUgb2YgZGF5OgorICoKKyAqIDxibG9ja3F1b3RlPgorICoKKyAqIDxwcmU+CisgKiBIT1VSX09GX0RBWQorICogQU1fUE0gKyBIT1VSPC9wcmU+CisgKgorICogPC9ibG9ja3F1b3RlPgorICoKKyAqIDxwPgorICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGVyZSBhcmUgY2VydGFpbiBwb3NzaWJsZSBhbWJpZ3VpdGllcyBpbgorICogaW50ZXJwcmV0YXRpb24gb2YgY2VydGFpbiBzaW5ndWxhciB0aW1lcywgd2hpY2ggYXJlIHJlc29sdmVkIGluIHRoZSBmb2xsb3dpbmcKKyAqIHdheXM6CisgKiA8b2w+CisgKiA8bGk+IDI0OjAwOjAwICJiZWxvbmdzIiB0byB0aGUgZm9sbG93aW5nIGRheS4gVGhhdCBpcywgMjM6NTkgb24gRGVjIDMxLCAxOTY5CisgKiAmbHQ7IDI0OjAwIG9uIEphbiAxLCAxOTcwICZsdDsgMjQ6MDE6MDAgb24gSmFuIDEsIDE5NzAgZm9ybSBhIHNlcXVlbmNlIG9mCisgKiB0aHJlZSBjb25zZWN1dGl2ZSBtaW51dGVzIGluIHRpbWUuCisgKgorICogPGxpPiBBbHRob3VnaCBoaXN0b3JpY2FsbHkgbm90IHByZWNpc2UsIG1pZG5pZ2h0IGFsc28gYmVsb25ncyB0byAiYW0iLCBhbmQKKyAqIG5vb24gYmVsb25ncyB0byAicG0iLCBzbyBvbiB0aGUgc2FtZSBkYXksIHdlIGhhdmUgMTI6MDAgYW0gKG1pZG5pZ2h0KSAmbHQ7IDEyOjAxIGFtLAorICogYW5kIDEyOjAwIHBtIChub29uKSAmbHQ7IDEyOjAxIHBtCisgKiA8L29sPgorICoKKyAqIDxwPgorICogVGhlIGRhdGUgb3IgdGltZSBmb3JtYXQgc3RyaW5ncyBhcmUgbm90IHBhcnQgb2YgdGhlIGRlZmluaXRpb24gb2YgYSBjYWxlbmRhciwKKyAqIGFzIHRob3NlIG11c3QgYmUgbW9kaWZpYWJsZSBvciBvdmVycmlkYWJsZSBieSB0aGUgdXNlciBhdCBydW50aW1lLiBVc2UKKyAqIHtAbGluayBqYXZhLnRleHQuRGF0ZUZvcm1hdH0gdG8gZm9ybWF0IGRhdGVzLgorICoKKyAqIDxwPgorICogPHN0cm9uZz5GaWVsZCBtYW5pcHVsYXRpb24gbWV0aG9kczwvc3Ryb25nPgorICoKKyAqIDxwPgorICoge0Bjb2RlIENhbGVuZGFyfSBmaWVsZHMgY2FuIGJlIGNoYW5nZWQgdXNpbmcgdGhyZWUgbWV0aG9kczoKKyAqIHtAY29kZSBzZXQoKX0sIHtAY29kZSBhZGQoKX0sIGFuZCB7QGNvZGUgcm9sbCgpfS4KKyAqCisgKiA8cD4KKyAqIDxzdHJvbmc+e0Bjb2RlIHNldChmLCB2YWx1ZSl9PC9zdHJvbmc+IGNoYW5nZXMgZmllbGQge0Bjb2RlIGZ9CisgKiB0byB7QGNvZGUgdmFsdWV9LiBJbiBhZGRpdGlvbiwgaXQgc2V0cyBhbiBpbnRlcm5hbCBtZW1iZXIgdmFyaWFibGUgdG8KKyAqIGluZGljYXRlIHRoYXQgZmllbGQge0Bjb2RlIGZ9IGhhcyBiZWVuIGNoYW5nZWQuIEFsdGhvdWdoIGZpZWxkCisgKiB7QGNvZGUgZn0gaXMgY2hhbmdlZCBpbW1lZGlhdGVseSwgdGhlIGNhbGVuZGFyJ3MgbWlsbGlzZWNvbmRzIGlzIG5vdAorICogcmVjb21wdXRlZCB1bnRpbCB0aGUgbmV4dCBjYWxsIHRvIHtAY29kZSBnZXQoKX0sCisgKiB7QGNvZGUgZ2V0VGltZSgpfSwgb3Ige0Bjb2RlIGdldFRpbWVJbk1pbGxpcygpfSBpcyBtYWRlLiBUaHVzLAorICogbXVsdGlwbGUgY2FsbHMgdG8ge0Bjb2RlIHNldCgpfSBkbyBub3QgdHJpZ2dlciBtdWx0aXBsZSwgdW5uZWNlc3NhcnkKKyAqIGNvbXB1dGF0aW9ucy4gQXMgYSByZXN1bHQgb2YgY2hhbmdpbmcgYSBmaWVsZCB1c2luZyB7QGNvZGUgc2V0KCl9LAorICogb3RoZXIgZmllbGRzIG1heSBhbHNvIGNoYW5nZSwgZGVwZW5kaW5nIG9uIHRoZSBmaWVsZCwgdGhlIGZpZWxkIHZhbHVlLCBhbmQKKyAqIHRoZSBjYWxlbmRhciBzeXN0ZW0uIEluIGFkZGl0aW9uLCB7QGNvZGUgZ2V0KGYpfSB3aWxsIG5vdCBuZWNlc3NhcmlseQorICogcmV0dXJuIHtAY29kZSB2YWx1ZX0gYWZ0ZXIgdGhlIGZpZWxkcyBoYXZlIGJlZW4gcmVjb21wdXRlZC4gVGhlCisgKiBzcGVjaWZpY3MgYXJlIGRldGVybWluZWQgYnkgdGhlIGNvbmNyZXRlIGNhbGVuZGFyIGNsYXNzLgorICoKKyAqIDxwPgorICogPGVtPkV4YW1wbGU8L2VtPjogQ29uc2lkZXIgYSB7QGNvZGUgR3JlZ29yaWFuQ2FsZW5kYXJ9IG9yaWdpbmFsbHkKKyAqIHNldCB0byBBdWd1c3QgMzEsIDE5OTkuIENhbGxpbmcgPGNvZGU+c2V0KENhbGVuZGFyLk1PTlRILAorICogQ2FsZW5kYXIuU0VQVEVNQkVSKTwvY29kZT4KKyAqIHNldHMgdGhlIGNhbGVuZGFyIHRvIFNlcHRlbWJlciAzMSwgMTk5OS4gVGhpcyBpcyBhIHRlbXBvcmFyeSBpbnRlcm5hbAorICogcmVwcmVzZW50YXRpb24gdGhhdCByZXNvbHZlcyB0byBPY3RvYmVyIDEsIDE5OTkgaWYge0Bjb2RlIGdldFRpbWUoKX1pcworICogdGhlbiBjYWxsZWQuIEhvd2V2ZXIsIGEgY2FsbCB0byB7QGNvZGUgc2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCwgMzApfQorICogYmVmb3JlIHRoZSBjYWxsIHRvIHtAY29kZSBnZXRUaW1lKCl9IHNldHMgdGhlIGNhbGVuZGFyIHRvIFNlcHRlbWJlcgorICogMzAsIDE5OTksIHNpbmNlIG5vIHJlY29tcHV0YXRpb24gb2NjdXJzIGFmdGVyIHtAY29kZSBzZXQoKX0gaXRzZWxmLgorICoKKyAqIDxwPgorICogPHN0cm9uZz57QGNvZGUgYWRkKGYsIGRlbHRhKX08L3N0cm9uZz4gYWRkcyB7QGNvZGUgZGVsdGF9IHRvCisgKiBmaWVsZCB7QGNvZGUgZn0uIFRoaXMgaXMgZXF1aXZhbGVudCB0byBjYWxsaW5nIDxjb2RlPnNldChmLAorICogZ2V0KGYpICsgZGVsdGEpPC9jb2RlPgorICogd2l0aCB0d28gYWRqdXN0bWVudHM6CisgKgorICogPGJsb2NrcXVvdGU+CisgKiA8cD4KKyAqIDxzdHJvbmc+QWRkIHJ1bGUgMTwvc3Ryb25nPi4gVGhlIHZhbHVlIG9mIGZpZWxkIHtAY29kZSBmfSBhZnRlciB0aGUKKyAqIGNhbGwgbWludXMgdGhlIHZhbHVlIG9mIGZpZWxkIHtAY29kZSBmfSBiZWZvcmUgdGhlIGNhbGwgaXMKKyAqIHtAY29kZSBkZWx0YX0sIG1vZHVsbyBhbnkgb3ZlcmZsb3cgdGhhdCBoYXMgb2NjdXJyZWQgaW4gZmllbGQKKyAqIHtAY29kZSBmfS4gT3ZlcmZsb3cgb2NjdXJzIHdoZW4gYSBmaWVsZCB2YWx1ZSBleGNlZWRzIGl0cyByYW5nZSBhbmQsCisgKiBhcyBhIHJlc3VsdCwgdGhlIG5leHQgbGFyZ2VyIGZpZWxkIGlzIGluY3JlbWVudGVkIG9yIGRlY3JlbWVudGVkIGFuZCB0aGUKKyAqIGZpZWxkIHZhbHVlIGlzIGFkanVzdGVkIGJhY2sgaW50byBpdHMgcmFuZ2UuCisgKgorICogPHA+CisgKiA8c3Ryb25nPkFkZCBydWxlIDI8L3N0cm9uZz4uIElmIGEgc21hbGxlciBmaWVsZCBpcyBleHBlY3RlZCB0byBiZSBpbnZhcmlhbnQsCisgKiBidXQgJm5ic3A7IGl0IGlzIGltcG9zc2libGUgZm9yIGl0IHRvIGJlIGVxdWFsIHRvIGl0cyBwcmlvciB2YWx1ZSBiZWNhdXNlIG9mCisgKiBjaGFuZ2VzIGluIGl0cyBtaW5pbXVtIG9yIG1heGltdW0gYWZ0ZXIgZmllbGQge0Bjb2RlIGZ9IGlzIGNoYW5nZWQsCisgKiB0aGVuIGl0cyB2YWx1ZSBpcyBhZGp1c3RlZCB0byBiZSBhcyBjbG9zZSBhcyBwb3NzaWJsZSB0byBpdHMgZXhwZWN0ZWQgdmFsdWUuCisgKiBBIHNtYWxsZXIgZmllbGQgcmVwcmVzZW50cyBhIHNtYWxsZXIgdW5pdCBvZiB0aW1lLiB7QGNvZGUgSE9VUn0gaXMgYQorICogc21hbGxlciBmaWVsZCB0aGFuIHtAY29kZSBEQVlfT0ZfTU9OVEh9LiBObyBhZGp1c3RtZW50IGlzIG1hZGUgdG8KKyAqIHNtYWxsZXIgZmllbGRzIHRoYXQgYXJlIG5vdCBleHBlY3RlZCB0byBiZSBpbnZhcmlhbnQuIFRoZSBjYWxlbmRhciBzeXN0ZW0KKyAqIGRldGVybWluZXMgd2hhdCBmaWVsZHMgYXJlIGV4cGVjdGVkIHRvIGJlIGludmFyaWFudC4KKyAqIDwvYmxvY2txdW90ZT4KKyAqCisgKiA8cD4KKyAqIEluIGFkZGl0aW9uLCB1bmxpa2Uge0Bjb2RlIHNldCgpfSwge0Bjb2RlIGFkZCgpfSBmb3JjZXMgYW4KKyAqIGltbWVkaWF0ZSByZWNvbXB1dGF0aW9uIG9mIHRoZSBjYWxlbmRhcidzIG1pbGxpc2Vjb25kcyBhbmQgYWxsIGZpZWxkcy4KKyAqCisgKiA8cD4KKyAqIDxlbT5FeGFtcGxlPC9lbT46IENvbnNpZGVyIGEge0Bjb2RlIEdyZWdvcmlhbkNhbGVuZGFyfSBvcmlnaW5hbGx5CisgKiBzZXQgdG8gQXVndXN0IDMxLCAxOTk5LiBDYWxsaW5nIHtAY29kZSBhZGQoQ2FsZW5kYXIuTU9OVEgsIDEzKX0gc2V0cworICogdGhlIGNhbGVuZGFyIHRvIFNlcHRlbWJlciAzMCwgMjAwMC4gPHN0cm9uZz5BZGQgcnVsZSAxPC9zdHJvbmc+IHNldHMgdGhlCisgKiB7QGNvZGUgTU9OVEh9IGZpZWxkIHRvIFNlcHRlbWJlciwgc2luY2UgYWRkaW5nIDEzIG1vbnRocyB0byBBdWd1c3QKKyAqIGdpdmVzIFNlcHRlbWJlciBvZiB0aGUgbmV4dCB5ZWFyLiBTaW5jZSB7QGNvZGUgREFZX09GX01PTlRIfSBjYW5ub3QgYmUKKyAqIDMxIGluIFNlcHRlbWJlciBpbiBhIHtAY29kZSBHcmVnb3JpYW5DYWxlbmRhcn0sIDxzdHJvbmc+YWRkIHJ1bGUgMjwvc3Ryb25nPgorICogc2V0cyB0aGUge0Bjb2RlIERBWV9PRl9NT05USH0gdG8gMzAsIHRoZSBjbG9zZXN0IHBvc3NpYmxlIHZhbHVlLgorICogQWx0aG91Z2ggaXQgaXMgYSBzbWFsbGVyIGZpZWxkLCB7QGNvZGUgREFZX09GX1dFRUt9IGlzIG5vdCBhZGp1c3RlZCBieQorICogcnVsZSAyLCBzaW5jZSBpdCBpcyBleHBlY3RlZCB0byBjaGFuZ2Ugd2hlbiB0aGUgbW9udGggY2hhbmdlcyBpbiBhCisgKiB7QGNvZGUgR3JlZ29yaWFuQ2FsZW5kYXJ9LgorICoKKyAqIDxwPgorICogPHN0cm9uZz57QGNvZGUgcm9sbChmLCBkZWx0YSl9PC9zdHJvbmc+IGFkZHMge0Bjb2RlIGRlbHRhfSB0bworICogZmllbGQge0Bjb2RlIGZ9IHdpdGhvdXQgY2hhbmdpbmcgbGFyZ2VyIGZpZWxkcy4gVGhpcyBpcyBlcXVpdmFsZW50IHRvCisgKiBjYWxsaW5nIHtAY29kZSBhZGQoZiwgZGVsdGEpfSB3aXRoIHRoZSBmb2xsb3dpbmcgYWRqdXN0bWVudDoKKyAqCisgKiA8YmxvY2txdW90ZT4KKyAqIDxwPgorICogPHN0cm9uZz5Sb2xsIHJ1bGU8L3N0cm9uZz4uIExhcmdlciBmaWVsZHMgYXJlIHVuY2hhbmdlZCBhZnRlciB0aGUgY2FsbC4gQQorICogbGFyZ2VyIGZpZWxkIHJlcHJlc2VudHMgYSBsYXJnZXIgdW5pdCBvZiB0aW1lLiB7QGNvZGUgREFZX09GX01PTlRIfSBpcworICogYSBsYXJnZXIgZmllbGQgdGhhbiB7QGNvZGUgSE9VUn0uCisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+CisgKiA8ZW0+RXhhbXBsZTwvZW0+OiBDb25zaWRlciBhIHtAY29kZSBHcmVnb3JpYW5DYWxlbmRhcn0gb3JpZ2luYWxseQorICogc2V0IHRvIEF1Z3VzdCAzMSwgMTk5OS4gQ2FsbGluZyA8Y29kZT5yb2xsKENhbGVuZGFyLk1PTlRILAorICogOCk8L2NvZGU+IHNldHMKKyAqIHRoZSBjYWxlbmRhciB0byBBcHJpbCAzMCwgPHN0cm9uZz4xOTk5PC9zdHJvbmc+LiBBZGQgcnVsZSAxIHNldHMgdGhlCisgKiB7QGNvZGUgTU9OVEh9IGZpZWxkIHRvIEFwcmlsLiBVc2luZyBhIHtAY29kZSBHcmVnb3JpYW5DYWxlbmRhcn0sCisgKiB0aGUge0Bjb2RlIERBWV9PRl9NT05USH0gY2Fubm90IGJlIDMxIGluIHRoZSBtb250aCBBcHJpbC4gQWRkIHJ1bGUgMgorICogc2V0cyBpdCB0byB0aGUgY2xvc2VzdCBwb3NzaWJsZSB2YWx1ZSwgMzAuIEZpbmFsbHksIHRoZSA8c3Ryb25nPnJvbGwgcnVsZTwvc3Ryb25nPgorICogbWFpbnRhaW5zIHRoZSB7QGNvZGUgWUVBUn0gZmllbGQgdmFsdWUgb2YgMTk5OS4KKyAqCisgKiA8cD4KKyAqIDxlbT5FeGFtcGxlPC9lbT46IENvbnNpZGVyIGEge0Bjb2RlIEdyZWdvcmlhbkNhbGVuZGFyfSBvcmlnaW5hbGx5CisgKiBzZXQgdG8gU3VuZGF5IEp1bmUgNiwgMTk5OS4gQ2FsbGluZworICoge0Bjb2RlIHJvbGwoQ2FsZW5kYXIuV0VFS19PRl9NT05USCwgLTEpfSBzZXRzIHRoZSBjYWxlbmRhciB0byBUdWVzZGF5CisgKiBKdW5lIDEsIDE5OTksIHdoZXJlYXMgY2FsbGluZyB7QGNvZGUgYWRkKENhbGVuZGFyLldFRUtfT0ZfTU9OVEgsIC0xKX0KKyAqIHNldHMgdGhlIGNhbGVuZGFyIHRvIFN1bmRheSBNYXkgMzAsIDE5OTkuIFRoaXMgaXMgYmVjYXVzZSB0aGUgcm9sbCBydWxlCisgKiBpbXBvc2VzIGFuIGFkZGl0aW9uYWwgY29uc3RyYWludDogVGhlIHtAY29kZSBNT05USH0gbXVzdCBub3QgY2hhbmdlCisgKiB3aGVuIHRoZSB7QGNvZGUgV0VFS19PRl9NT05USH0gaXMgcm9sbGVkLiBUYWtlbiB0b2dldGhlciB3aXRoIGFkZCBydWxlCisgKiAxLCB0aGUgcmVzdWx0YW50IGRhdGUgbXVzdCBiZSBiZXR3ZWVuIFR1ZXNkYXkgSnVuZSAxIGFuZCBTYXR1cmRheSBKdW5lIDUuCisgKiBBY2NvcmRpbmcgdG8gYWRkIHJ1bGUgMiwgdGhlIHtAY29kZSBEQVlfT0ZfV0VFS30sIGFuIGludmFyaWFudCB3aGVuCisgKiBjaGFuZ2luZyB0aGUge0Bjb2RlIFdFRUtfT0ZfTU9OVEh9LCBpcyBzZXQgdG8gVHVlc2RheSwgdGhlIGNsb3Nlc3QKKyAqIHBvc3NpYmxlIHZhbHVlIHRvIFN1bmRheSAod2hlcmUgU3VuZGF5IGlzIHRoZSBmaXJzdCBkYXkgb2YgdGhlIHdlZWspLgorICoKKyAqIDxwPgorICogPHN0cm9uZz5Vc2FnZSBtb2RlbDwvc3Ryb25nPi4gVG8gbW90aXZhdGUgdGhlIGJlaGF2aW9yIG9mIHtAY29kZSBhZGQoKX0KKyAqIGFuZCB7QGNvZGUgcm9sbCgpfSwgY29uc2lkZXIgYSB1c2VyIGludGVyZmFjZSBjb21wb25lbnQgd2l0aAorICogaW5jcmVtZW50IGFuZCBkZWNyZW1lbnQgYnV0dG9ucyBmb3IgdGhlIG1vbnRoLCBkYXksIGFuZCB5ZWFyLCBhbmQgYW4KKyAqIHVuZGVybHlpbmcge0Bjb2RlIEdyZWdvcmlhbkNhbGVuZGFyfS4gSWYgdGhlIGludGVyZmFjZSByZWFkcyBKYW51YXJ5CisgKiAzMSwgMTk5OSBhbmQgdGhlIHVzZXIgcHJlc3NlcyB0aGUgbW9udGggaW5jcmVtZW50IGJ1dHRvbiwgd2hhdCBzaG91bGQgaXQKKyAqIHJlYWQ/IElmIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uIHVzZXMge0Bjb2RlIHNldCgpfSwgaXQgbWlnaHQKKyAqIHJlYWQgTWFyY2ggMywgMTk5OS4gQSBiZXR0ZXIgcmVzdWx0IHdvdWxkIGJlIEZlYnJ1YXJ5IDI4LCAxOTk5LiBGdXJ0aGVybW9yZSwKKyAqIGlmIHRoZSB1c2VyIHByZXNzZXMgdGhlIG1vbnRoIGluY3JlbWVudCBidXR0b24gYWdhaW4sIGl0IHNob3VsZCByZWFkIE1hcmNoCisgKiAzMSwgMTk5OSwgbm90IE1hcmNoIDI4LCAxOTk5LiBCeSBzYXZpbmcgdGhlIG9yaWdpbmFsIGRhdGUgYW5kIHVzaW5nIGVpdGhlcgorICoge0Bjb2RlIGFkZCgpfSBvciB7QGNvZGUgcm9sbCgpfSwgZGVwZW5kaW5nIG9uIHdoZXRoZXIgbGFyZ2VyCisgKiBmaWVsZHMgc2hvdWxkIGJlIGFmZmVjdGVkLCB0aGUgdXNlciBpbnRlcmZhY2UgY2FuIGJlaGF2ZSBhcyBtb3N0IHVzZXJzIHdpbGwKKyAqIGludHVpdGl2ZWx5IGV4cGVjdC4KKyAqCisgKiA8cD4KKyAqIDxiPk5vdGU6PC9iPiBZb3Ugc2hvdWxkIGFsd2F5cyB1c2Uge0Bjb2RlIHJvbGx9IGFuZCB7QGNvZGUgYWRkfSByYXRoZXIgdGhhbgorICogYXR0ZW1wdGluZyB0byBwZXJmb3JtIGFyaXRobWV0aWMgb3BlcmF0aW9ucyBkaXJlY3RseSBvbiB0aGUgZmllbGRzIG9mIGEKKyAqIDx0dD5DYWxlbmRhcjwvdHQ+LiBJdCBpcyBxdWl0ZSBwb3NzaWJsZSBmb3IgPHR0PkNhbGVuZGFyPC90dD4gc3ViY2xhc3NlcworICogdG8gaGF2ZSBmaWVsZHMgd2l0aCBub24tbGluZWFyIGJlaGF2aW9yLCBmb3IgZXhhbXBsZSBtaXNzaW5nIG1vbnRocyBvciBkYXlzCisgKiBkdXJpbmcgbm9uLWxlYXAgeWVhcnMuIFRoZSBzdWJjbGFzc2VzJyA8dHQ+YWRkPC90dD4gYW5kIDx0dD5yb2xsPC90dD4KKyAqIG1ldGhvZHMgd2lsbCB0YWtlIHRoaXMgaW50byBhY2NvdW50LCB3aGlsZSBzaW1wbGUgYXJpdGhtZXRpYyBtYW5pcHVsYXRpb25zCisgKiBtYXkgZ2l2ZSBpbnZhbGlkIHJlc3VsdHMuCisgKgorICogQHNlZSBEYXRlCisgKiBAc2VlIEdyZWdvcmlhbkNhbGVuZGFyCisgKiBAc2VlIFRpbWVab25lCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBDYWxlbmRhciBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlLCBDb21wYXJhYmxlPENhbGVuZGFyPiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTgwNzU0NzUwNTgyMTU5MDY0Mkw7CisKKyAgICAvKioKKyAgICAgKiBUcnVlIGlmZiB0aGUgdmFsdWVzIGluIHtAY29kZSBmaWVsZHNbXX0gY29ycmVzcG9uZCB0byB7QGNvZGUgdGltZX0uIERlc3BpdGUgdGhlIG5hbWUsIHRoaXMKKyAgICAgKiBpcyBlZmZlY3RpdmVseSAiYXJlIHRoZSB2YWx1ZXMgaW4gZmllbGRzW10gdXAtdG8tZGF0ZT8iIC0tLSB7QGNvZGUgZmllbGRzW119IG1heSBjb250YWluCisgICAgICogbm9uLXplcm8gdmFsdWVzIGFuZCB7QGNvZGUgaXNTZXRbXX0gbWF5IGNvbnRhaW4ge0Bjb2RlIHRydWV9IHZhbHVlcyBldmVuIHdoZW4KKyAgICAgKiB7QGNvZGUgYXJlRmllbGRzU2V0fSBpcyBmYWxzZS4KKyAgICAgKiBBY2Nlc3NpbmcgdGhlIGZpZWxkcyB2aWEge0Bjb2RlIGdldH0gd2lsbCBlbnN1cmUgdGhlIGZpZWxkcyBhcmUgdXAtdG8tZGF0ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBhcmVGaWVsZHNTZXQ7CisKKyAgICAvKioKKyAgICAgKiBDb250YWlucyBicm9rZW4tZG93biBmaWVsZCB2YWx1ZXMgZm9yIHRoZSBjdXJyZW50IHZhbHVlIG9mIHtAY29kZSB0aW1lfSBpZgorICAgICAqIHtAY29kZSBhcmVGaWVsZHNTZXR9IGlzIHRydWUsIG9yIHN0YWxlIGRhdGEgY29ycmVzcG9uZGluZyB0byBzb21lIHByZXZpb3VzIHZhbHVlIG90aGVyd2lzZS4KKyAgICAgKiBBY2Nlc3NpbmcgdGhlIGZpZWxkcyB2aWEge0Bjb2RlIGdldH0gd2lsbCBlbnN1cmUgdGhlIGZpZWxkcyBhcmUgdXAtdG8tZGF0ZS4KKyAgICAgKiBUaGUgYXJyYXkgbGVuZ3RoIGlzIGFsd2F5cyB7QGNvZGUgRklFTERfQ09VTlR9LgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnRbXSBmaWVsZHM7CisKKyAgICAvKioKKyAgICAgKiBXaGV0aGVyIHRoZSBjb3JyZXNwb25kaW5nIGVsZW1lbnQgaW4ge0Bjb2RlIGZpZWxkW119IGhhcyBiZWVuIHNldC4gSW5pdGlhbGx5LCB0aGVzZSBhcmUgYWxsCisgICAgICogZmFsc2UuIFRoZSBmaXJzdCB0aW1lIHRoZSBmaWVsZHMgYXJlIGNvbXB1dGVkLCB0aGVzZSBhcmUgc2V0IHRvIHRydWUgYW5kIHJlbWFpbiBzZXQgZXZlbiBpZgorICAgICAqIHRoZSBkYXRhIGJlY29tZXMgc3RhbGU6IHlvdSA8aT5tdXN0PC9pPiBjaGVjayB7QGNvZGUgYXJlRmllbGRzU2V0fSBpZiB5b3Ugd2FudCB0byBrbm93CisgICAgICogd2hldGhlciB0aGUgdmFsdWUgaXMgdXAtdG8tZGF0ZS4KKyAgICAgKiBOb3RlIHRoYXQge0Bjb2RlIGlzU2V0fSBpcyA8aT5ub3Q8L2k+IGEgc2FmZSBhbHRlcm5hdGl2ZSB0byBhY2Nlc3NpbmcgdGhpcyBhcnJheSBkaXJlY3RseSwKKyAgICAgKiBhbmQgd2lsbCBsaWtld2lzZSByZXR1cm4gc3RhbGUgZGF0YSEKKyAgICAgKiBUaGUgYXJyYXkgbGVuZ3RoIGlzIGFsd2F5cyB7QGNvZGUgRklFTERfQ09VTlR9LgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuW10gaXNTZXQ7CisKKyAgICAvKioKKyAgICAgKiBXaGV0aGVyIHtAY29kZSB0aW1lfSBjb3JyZXNwb25kcyB0byB0aGUgdmFsdWVzIGluIHtAY29kZSBmaWVsZHNbXX0uIElmIGZhbHNlLCB7QGNvZGUgdGltZX0KKyAgICAgKiBpcyBvdXQtb2YtZGF0ZSB3aXRoIHJlc3BlY3QgdG8gY2hhbmdlcyB7QGNvZGUgZmllbGRzW119LgorICAgICAqIEFjY2Vzc2luZyB0aGUgdGltZSB2aWEge0Bjb2RlIGdldFRpbWVJbk1pbGxpc30gd2lsbCBhbHdheXMgcmV0dXJuIHRoZSBjb3JyZWN0IHZhbHVlLgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGlzVGltZVNldDsKKworICAgIC8qKgorICAgICAqIEEgdGltZSBpbiBtaWxsaXNlY29uZHMgc2luY2UgSmFudWFyeSAxLCAxOTcwLiBTZWUge0Bjb2RlIGlzVGltZVNldH0uCisgICAgICogQWNjZXNzaW5nIHRoZSB0aW1lIHZpYSB7QGNvZGUgZ2V0VGltZUluTWlsbGlzfSB3aWxsIGFsd2F5cyByZXR1cm4gdGhlIGNvcnJlY3QgdmFsdWUuCisgICAgICovCisgICAgcHJvdGVjdGVkIGxvbmcgdGltZTsKKworICAgIHRyYW5zaWVudCBpbnQgbGFzdFRpbWVGaWVsZFNldDsKKworICAgIHRyYW5zaWVudCBpbnQgbGFzdERhdGVGaWVsZFNldDsKKworICAgIHByaXZhdGUgYm9vbGVhbiBsZW5pZW50OworCisgICAgcHJpdmF0ZSBpbnQgZmlyc3REYXlPZldlZWs7CisKKyAgICBwcml2YXRlIGludCBtaW5pbWFsRGF5c0luRmlyc3RXZWVrOworCisgICAgcHJpdmF0ZSBUaW1lWm9uZSB6b25lOworCisgICAgLyoqCisgICAgICogVmFsdWUgb2YgdGhlIHtAY29kZSBNT05USH0gZmllbGQgaW5kaWNhdGluZyB0aGUgZmlyc3QgbW9udGggb2YgdGhlCisgICAgICogeWVhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBKQU5VQVJZID0gMDsKKworICAgIC8qKgorICAgICAqIFZhbHVlIG9mIHRoZSB7QGNvZGUgTU9OVEh9IGZpZWxkIGluZGljYXRpbmcgdGhlIHNlY29uZCBtb250aCBvZgorICAgICAqIHRoZSB5ZWFyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZFQlJVQVJZID0gMTsKKworICAgIC8qKgorICAgICAqIFZhbHVlIG9mIHRoZSB7QGNvZGUgTU9OVEh9IGZpZWxkIGluZGljYXRpbmcgdGhlIHRoaXJkIG1vbnRoIG9mIHRoZQorICAgICAqIHllYXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFSQ0ggPSAyOworCisgICAgLyoqCisgICAgICogVmFsdWUgb2YgdGhlIHtAY29kZSBNT05USH0gZmllbGQgaW5kaWNhdGluZyB0aGUgZm91cnRoIG1vbnRoIG9mCisgICAgICogdGhlIHllYXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVBSSUwgPSAzOworCisgICAgLyoqCisgICAgICogVmFsdWUgb2YgdGhlIHtAY29kZSBNT05USH0gZmllbGQgaW5kaWNhdGluZyB0aGUgZmlmdGggbW9udGggb2YgdGhlCisgICAgICogeWVhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVkgPSA0OworCisgICAgLyoqCisgICAgICogVmFsdWUgb2YgdGhlIHtAY29kZSBNT05USH0gZmllbGQgaW5kaWNhdGluZyB0aGUgc2l4dGggbW9udGggb2YgdGhlCisgICAgICogeWVhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBKVU5FID0gNTsKKworICAgIC8qKgorICAgICAqIFZhbHVlIG9mIHRoZSB7QGNvZGUgTU9OVEh9IGZpZWxkIGluZGljYXRpbmcgdGhlIHNldmVudGggbW9udGggb2YKKyAgICAgKiB0aGUgeWVhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBKVUxZID0gNjsKKworICAgIC8qKgorICAgICAqIFZhbHVlIG9mIHRoZSB7QGNvZGUgTU9OVEh9IGZpZWxkIGluZGljYXRpbmcgdGhlIGVpZ2h0aCBtb250aCBvZgorICAgICAqIHRoZSB5ZWFyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFVR1VTVCA9IDc7CisKKyAgICAvKioKKyAgICAgKiBWYWx1ZSBvZiB0aGUge0Bjb2RlIE1PTlRIfSBmaWVsZCBpbmRpY2F0aW5nIHRoZSBuaW50aCBtb250aCBvZiB0aGUKKyAgICAgKiB5ZWFyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUFRFTUJFUiA9IDg7CisKKyAgICAvKioKKyAgICAgKiBWYWx1ZSBvZiB0aGUge0Bjb2RlIE1PTlRIfSBmaWVsZCBpbmRpY2F0aW5nIHRoZSB0ZW50aCBtb250aCBvZiB0aGUKKyAgICAgKiB5ZWFyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9DVE9CRVIgPSA5OworCisgICAgLyoqCisgICAgICogVmFsdWUgb2YgdGhlIHtAY29kZSBNT05USH0gZmllbGQgaW5kaWNhdGluZyB0aGUgZWxldmVudGggbW9udGggb2YKKyAgICAgKiB0aGUgeWVhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT1ZFTUJFUiA9IDEwOworCisgICAgLyoqCisgICAgICogVmFsdWUgb2YgdGhlIHtAY29kZSBNT05USH0gZmllbGQgaW5kaWNhdGluZyB0aGUgdHdlbGZ0aCBtb250aCBvZgorICAgICAqIHRoZSB5ZWFyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFQ0VNQkVSID0gMTE7CisKKyAgICAvKioKKyAgICAgKiBWYWx1ZSBvZiB0aGUge0Bjb2RlIE1PTlRIfSBmaWVsZCBpbmRpY2F0aW5nIHRoZSB0aGlydGVlbnRoIG1vbnRoCisgICAgICogb2YgdGhlIHllYXIuIEFsdGhvdWdoIHtAY29kZSBHcmVnb3JpYW5DYWxlbmRhcn0gZG9lcyBub3QgdXNlIHRoaXMKKyAgICAgKiB2YWx1ZSwgbHVuYXIgY2FsZW5kYXJzIGRvLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOREVDSU1CRVIgPSAxMjsKKworICAgIC8qKgorICAgICAqIFZhbHVlIG9mIHRoZSB7QGNvZGUgREFZX09GX1dFRUt9IGZpZWxkIGluZGljYXRpbmcgU3VuZGF5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNVTkRBWSA9IDE7CisKKyAgICAvKioKKyAgICAgKiBWYWx1ZSBvZiB0aGUge0Bjb2RlIERBWV9PRl9XRUVLfSBmaWVsZCBpbmRpY2F0aW5nIE1vbmRheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNT05EQVkgPSAyOworCisgICAgLyoqCisgICAgICogVmFsdWUgb2YgdGhlIHtAY29kZSBEQVlfT0ZfV0VFS30gZmllbGQgaW5kaWNhdGluZyBUdWVzZGF5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRVRVNEQVkgPSAzOworCisgICAgLyoqCisgICAgICogVmFsdWUgb2YgdGhlIHtAY29kZSBEQVlfT0ZfV0VFS30gZmllbGQgaW5kaWNhdGluZyBXZWRuZXNkYXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0VETkVTREFZID0gNDsKKworICAgIC8qKgorICAgICAqIFZhbHVlIG9mIHRoZSB7QGNvZGUgREFZX09GX1dFRUt9IGZpZWxkIGluZGljYXRpbmcgVGh1cnNkYXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEhVUlNEQVkgPSA1OworCisgICAgLyoqCisgICAgICogVmFsdWUgb2YgdGhlIHtAY29kZSBEQVlfT0ZfV0VFS30gZmllbGQgaW5kaWNhdGluZyBGcmlkYXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlJJREFZID0gNjsKKworICAgIC8qKgorICAgICAqIFZhbHVlIG9mIHRoZSB7QGNvZGUgREFZX09GX1dFRUt9IGZpZWxkIGluZGljYXRpbmcgU2F0dXJkYXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0FUVVJEQVkgPSA3OworCisgICAgLyoqCisgICAgICogRmllbGQgbnVtYmVyIGZvciB7QGNvZGUgZ2V0fSBhbmQge0Bjb2RlIHNldH0gaW5kaWNhdGluZyB0aGUKKyAgICAgKiBlcmEsIGUuZy4sIEFEIG9yIEJDIGluIHRoZSBKdWxpYW4gY2FsZW5kYXIuIFRoaXMgaXMgYSBjYWxlbmRhci1zcGVjaWZpYworICAgICAqIHZhbHVlOyBzZWUgc3ViY2xhc3MgZG9jdW1lbnRhdGlvbi4KKyAgICAgKgorICAgICAqIEBzZWUgR3JlZ29yaWFuQ2FsZW5kYXIjQUQKKyAgICAgKiBAc2VlIEdyZWdvcmlhbkNhbGVuZGFyI0JDCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJBID0gMDsKKworICAgIC8qKgorICAgICAqIEZpZWxkIG51bWJlciBmb3Ige0Bjb2RlIGdldH0gYW5kIHtAY29kZSBzZXR9IGluZGljYXRpbmcgdGhlCisgICAgICogeWVhci4gVGhpcyBpcyBhIGNhbGVuZGFyLXNwZWNpZmljIHZhbHVlOyBzZWUgc3ViY2xhc3MgZG9jdW1lbnRhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBZRUFSID0gMTsKKworICAgIC8qKgorICAgICAqIEZpZWxkIG51bWJlciBmb3Ige0Bjb2RlIGdldH0gYW5kIHtAY29kZSBzZXR9IGluZGljYXRpbmcgdGhlCisgICAgICogbW9udGguIFRoaXMgaXMgYSBjYWxlbmRhci1zcGVjaWZpYyB2YWx1ZS4gVGhlIGZpcnN0IG1vbnRoIG9mIHRoZSB5ZWFyIGlzCisgICAgICoge0Bjb2RlIEpBTlVBUll9OyB0aGUgbGFzdCBkZXBlbmRzIG9uIHRoZSBudW1iZXIgb2YgbW9udGhzIGluIGEKKyAgICAgKiB5ZWFyLgorICAgICAqCisgICAgICogQHNlZSAjSkFOVUFSWQorICAgICAqIEBzZWUgI0ZFQlJVQVJZCisgICAgICogQHNlZSAjTUFSQ0gKKyAgICAgKiBAc2VlICNBUFJJTAorICAgICAqIEBzZWUgI01BWQorICAgICAqIEBzZWUgI0pVTkUKKyAgICAgKiBAc2VlICNKVUxZCisgICAgICogQHNlZSAjQVVHVVNUCisgICAgICogQHNlZSAjU0VQVEVNQkVSCisgICAgICogQHNlZSAjT0NUT0JFUgorICAgICAqIEBzZWUgI05PVkVNQkVSCisgICAgICogQHNlZSAjREVDRU1CRVIKKyAgICAgKiBAc2VlICNVTkRFQ0lNQkVSCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTU9OVEggPSAyOworCisgICAgLyoqCisgICAgICogRmllbGQgbnVtYmVyIGZvciB7QGNvZGUgZ2V0fSBhbmQge0Bjb2RlIHNldH0gaW5kaWNhdGluZyB0aGUKKyAgICAgKiB3ZWVrIG51bWJlciB3aXRoaW4gdGhlIGN1cnJlbnQgeWVhci4gVGhlIGZpcnN0IHdlZWsgb2YgdGhlIHllYXIsIGFzCisgICAgICogZGVmaW5lZCBieSB7QGNvZGUgZ2V0Rmlyc3REYXlPZldlZWsoKX0gYW5kCisgICAgICoge0Bjb2RlIGdldE1pbmltYWxEYXlzSW5GaXJzdFdlZWsoKX0sIGhhcyB2YWx1ZSAxLiBTdWJjbGFzc2VzCisgICAgICogZGVmaW5lIHRoZSB2YWx1ZSBvZiB7QGNvZGUgV0VFS19PRl9ZRUFSfSBmb3IgZGF5cyBiZWZvcmUgdGhlIGZpcnN0CisgICAgICogd2VlayBvZiB0aGUgeWVhci4KKyAgICAgKgorICAgICAqIEBzZWUgI2dldEZpcnN0RGF5T2ZXZWVrCisgICAgICogQHNlZSAjZ2V0TWluaW1hbERheXNJbkZpcnN0V2VlaworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdFRUtfT0ZfWUVBUiA9IDM7CisKKyAgICAvKioKKyAgICAgKiBGaWVsZCBudW1iZXIgZm9yIHtAY29kZSBnZXR9IGFuZCB7QGNvZGUgc2V0fSBpbmRpY2F0aW5nIHRoZQorICAgICAqIHdlZWsgbnVtYmVyIHdpdGhpbiB0aGUgY3VycmVudCBtb250aC4gVGhlIGZpcnN0IHdlZWsgb2YgdGhlIG1vbnRoLCBhcworICAgICAqIGRlZmluZWQgYnkge0Bjb2RlIGdldEZpcnN0RGF5T2ZXZWVrKCl9IGFuZAorICAgICAqIHtAY29kZSBnZXRNaW5pbWFsRGF5c0luRmlyc3RXZWVrKCl9LCBoYXMgdmFsdWUgMS4gU3ViY2xhc3NlcworICAgICAqIGRlZmluZSB0aGUgdmFsdWUgb2Yge0Bjb2RlIFdFRUtfT0ZfTU9OVEh9IGZvciBkYXlzIGJlZm9yZSB0aGUKKyAgICAgKiBmaXJzdCB3ZWVrIG9mIHRoZSBtb250aC4KKyAgICAgKgorICAgICAqIEBzZWUgI2dldEZpcnN0RGF5T2ZXZWVrCisgICAgICogQHNlZSAjZ2V0TWluaW1hbERheXNJbkZpcnN0V2VlaworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdFRUtfT0ZfTU9OVEggPSA0OworCisgICAgLyoqCisgICAgICogRmllbGQgbnVtYmVyIGZvciB7QGNvZGUgZ2V0fSBhbmQge0Bjb2RlIHNldH0gaW5kaWNhdGluZyB0aGUKKyAgICAgKiBkYXkgb2YgdGhlIG1vbnRoLiBUaGlzIGlzIGEgc3lub255bSBmb3Ige0Bjb2RlIERBWV9PRl9NT05USH0uIFRoZQorICAgICAqIGZpcnN0IGRheSBvZiB0aGUgbW9udGggaGFzIHZhbHVlIDEuCisgICAgICoKKyAgICAgKiBAc2VlICNEQVlfT0ZfTU9OVEgKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEQVRFID0gNTsKKworICAgIC8qKgorICAgICAqIEZpZWxkIG51bWJlciBmb3Ige0Bjb2RlIGdldH0gYW5kIHtAY29kZSBzZXR9IGluZGljYXRpbmcgdGhlCisgICAgICogZGF5IG9mIHRoZSBtb250aC4gVGhpcyBpcyBhIHN5bm9ueW0gZm9yIHtAY29kZSBEQVRFfS4gVGhlIGZpcnN0CisgICAgICogZGF5IG9mIHRoZSBtb250aCBoYXMgdmFsdWUgMS4KKyAgICAgKgorICAgICAqIEBzZWUgI0RBVEUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEQVlfT0ZfTU9OVEggPSA1OworCisgICAgLyoqCisgICAgICogRmllbGQgbnVtYmVyIGZvciB7QGNvZGUgZ2V0fSBhbmQge0Bjb2RlIHNldH0gaW5kaWNhdGluZyB0aGUKKyAgICAgKiBkYXkgbnVtYmVyIHdpdGhpbiB0aGUgY3VycmVudCB5ZWFyLiBUaGUgZmlyc3QgZGF5IG9mIHRoZSB5ZWFyIGhhcyB2YWx1ZQorICAgICAqIDEuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREFZX09GX1lFQVIgPSA2OworCisgICAgLyoqCisgICAgICogRmllbGQgbnVtYmVyIGZvciB7QGNvZGUgZ2V0fSBhbmQge0Bjb2RlIHNldH0gaW5kaWNhdGluZyB0aGUKKyAgICAgKiBkYXkgb2YgdGhlIHdlZWsuIFRoaXMgZmllbGQgdGFrZXMgdmFsdWVzIHtAY29kZSBTVU5EQVl9LAorICAgICAqIHtAY29kZSBNT05EQVl9LCB7QGNvZGUgVFVFU0RBWX0sIHtAY29kZSBXRURORVNEQVl9LAorICAgICAqIHtAY29kZSBUSFVSU0RBWX0sIHtAY29kZSBGUklEQVl9LCBhbmQKKyAgICAgKiB7QGNvZGUgU0FUVVJEQVl9LgorICAgICAqCisgICAgICogQHNlZSAjU1VOREFZCisgICAgICogQHNlZSAjTU9OREFZCisgICAgICogQHNlZSAjVFVFU0RBWQorICAgICAqIEBzZWUgI1dFRE5FU0RBWQorICAgICAqIEBzZWUgI1RIVVJTREFZCisgICAgICogQHNlZSAjRlJJREFZCisgICAgICogQHNlZSAjU0FUVVJEQVkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEQVlfT0ZfV0VFSyA9IDc7CisKKyAgICAvKioKKyAgICAgKiBGaWVsZCBudW1iZXIgZm9yIHtAY29kZSBnZXR9IGFuZCB7QGNvZGUgc2V0fSBpbmRpY2F0aW5nIHRoZQorICAgICAqIG9yZGluYWwgbnVtYmVyIG9mIHRoZSBkYXkgb2YgdGhlIHdlZWsgd2l0aGluIHRoZSBjdXJyZW50IG1vbnRoLiBUb2dldGhlcgorICAgICAqIHdpdGggdGhlIHtAY29kZSBEQVlfT0ZfV0VFS30gZmllbGQsIHRoaXMgdW5pcXVlbHkgc3BlY2lmaWVzIGEgZGF5CisgICAgICogd2l0aGluIGEgbW9udGguIFVubGlrZSB7QGNvZGUgV0VFS19PRl9NT05USH0gYW5kCisgICAgICoge0Bjb2RlIFdFRUtfT0ZfWUVBUn0sIHRoaXMgZmllbGQncyB2YWx1ZSBkb2VzIDxlbT5ub3Q8L2VtPgorICAgICAqIGRlcGVuZCBvbiB7QGNvZGUgZ2V0Rmlyc3REYXlPZldlZWsoKX0gb3IKKyAgICAgKiB7QGNvZGUgZ2V0TWluaW1hbERheXNJbkZpcnN0V2VlaygpfS4ge0Bjb2RlIERBWV9PRl9NT05USCAxfQorICAgICAqIHRocm91Z2gge0Bjb2RlIDd9IGFsd2F5cyBjb3JyZXNwb25kIHRvIDxjb2RlPkRBWV9PRl9XRUVLX0lOX01PTlRICisgICAgICogMTwvY29kZT47CisgICAgICoge0Bjb2RlIDh9IHRocm91Z2gge0Bjb2RlIDE1fSBjb3JyZXNwb25kIHRvCisgICAgICoge0Bjb2RlIERBWV9PRl9XRUVLX0lOX01PTlRIIDJ9LCBhbmQgc28gb24uCisgICAgICoge0Bjb2RlIERBWV9PRl9XRUVLX0lOX01PTlRIIDB9IGluZGljYXRlcyB0aGUgd2VlayBiZWZvcmUKKyAgICAgKiB7QGNvZGUgREFZX09GX1dFRUtfSU5fTU9OVEggMX0uIE5lZ2F0aXZlIHZhbHVlcyBjb3VudCBiYWNrIGZyb20KKyAgICAgKiB0aGUgZW5kIG9mIHRoZSBtb250aCwgc28gdGhlIGxhc3QgU3VuZGF5IG9mIGEgbW9udGggaXMgc3BlY2lmaWVkIGFzCisgICAgICoge0Bjb2RlIERBWV9PRl9XRUVLID0gU1VOREFZLCBEQVlfT0ZfV0VFS19JTl9NT05USCA9IC0xfS4gQmVjYXVzZQorICAgICAqIG5lZ2F0aXZlIHZhbHVlcyBjb3VudCBiYWNrd2FyZCB0aGV5IHdpbGwgdXN1YWxseSBiZSBhbGlnbmVkIGRpZmZlcmVudGx5CisgICAgICogd2l0aGluIHRoZSBtb250aCB0aGFuIHBvc2l0aXZlIHZhbHVlcy4gRm9yIGV4YW1wbGUsIGlmIGEgbW9udGggaGFzIDMxCisgICAgICogZGF5cywge0Bjb2RlIERBWV9PRl9XRUVLX0lOX01PTlRIIC0xfSB3aWxsIG92ZXJsYXAKKyAgICAgKiB7QGNvZGUgREFZX09GX1dFRUtfSU5fTU9OVEggNX0gYW5kIHRoZSBlbmQgb2Yge0Bjb2RlIDR9LgorICAgICAqCisgICAgICogQHNlZSAjREFZX09GX1dFRUsKKyAgICAgKiBAc2VlICNXRUVLX09GX01PTlRICisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREFZX09GX1dFRUtfSU5fTU9OVEggPSA4OworCisgICAgLyoqCisgICAgICogRmllbGQgbnVtYmVyIGZvciB7QGNvZGUgZ2V0fSBhbmQge0Bjb2RlIHNldH0gaW5kaWNhdGluZworICAgICAqIHdoZXRoZXIgdGhlIHtAY29kZSBIT1VSfSBpcyBiZWZvcmUgb3IgYWZ0ZXIgbm9vbi4gRS5nLiwgYXQKKyAgICAgKiAxMDowNDoxNS4yNTAgUE0gdGhlIHtAY29kZSBBTV9QTX0gaXMge0Bjb2RlIFBNfS4KKyAgICAgKgorICAgICAqIEBzZWUgI0FNCisgICAgICogQHNlZSAjUE0KKyAgICAgKiBAc2VlICNIT1VSCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQU1fUE0gPSA5OworCisgICAgLyoqCisgICAgICogRmllbGQgbnVtYmVyIGZvciB7QGNvZGUgZ2V0fSBhbmQge0Bjb2RlIHNldH0gaW5kaWNhdGluZyB0aGUKKyAgICAgKiBob3VyIG9mIHRoZSBtb3JuaW5nIG9yIGFmdGVybm9vbi4ge0Bjb2RlIEhPVVJ9IGlzIHVzZWQgZm9yIHRoZQorICAgICAqIDEyLWhvdXIgY2xvY2suIEUuZy4sIGF0IDEwOjA0OjE1LjI1MCBQTSB0aGUge0Bjb2RlIEhPVVJ9IGlzIDEwLgorICAgICAqCisgICAgICogQHNlZSAjQU1fUE0KKyAgICAgKiBAc2VlICNIT1VSX09GX0RBWQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhPVVIgPSAxMDsKKworICAgIC8qKgorICAgICAqIEZpZWxkIG51bWJlciBmb3Ige0Bjb2RlIGdldH0gYW5kIHtAY29kZSBzZXR9IGluZGljYXRpbmcgdGhlCisgICAgICogaG91ciBvZiB0aGUgZGF5LiB7QGNvZGUgSE9VUl9PRl9EQVl9IGlzIHVzZWQgZm9yIHRoZSAyNC1ob3VyCisgICAgICogY2xvY2suIEUuZy4sIGF0IDEwOjA0OjE1LjI1MCBQTSB0aGUge0Bjb2RlIEhPVVJfT0ZfREFZfSBpcyAyMi4KKyAgICAgKgorICAgICAqIEBzZWUgI0hPVVIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIT1VSX09GX0RBWSA9IDExOworCisgICAgLyoqCisgICAgICogRmllbGQgbnVtYmVyIGZvciB7QGNvZGUgZ2V0fSBhbmQge0Bjb2RlIHNldH0gaW5kaWNhdGluZyB0aGUKKyAgICAgKiBtaW51dGUgd2l0aGluIHRoZSBob3VyLiBFLmcuLCBhdCAxMDowNDoxNS4yNTAgUE0gdGhlIHtAY29kZSBNSU5VVEV9CisgICAgICogaXMgNC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNSU5VVEUgPSAxMjsKKworICAgIC8qKgorICAgICAqIEZpZWxkIG51bWJlciBmb3Ige0Bjb2RlIGdldH0gYW5kIHtAY29kZSBzZXR9IGluZGljYXRpbmcgdGhlCisgICAgICogc2Vjb25kIHdpdGhpbiB0aGUgbWludXRlLiBFLmcuLCBhdCAxMDowNDoxNS4yNTAgUE0gdGhlCisgICAgICoge0Bjb2RlIFNFQ09ORH0gaXMgMTUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VDT05EID0gMTM7CisKKyAgICAvKioKKyAgICAgKiBGaWVsZCBudW1iZXIgZm9yIHtAY29kZSBnZXR9IGFuZCB7QGNvZGUgc2V0fSBpbmRpY2F0aW5nIHRoZQorICAgICAqIG1pbGxpc2Vjb25kIHdpdGhpbiB0aGUgc2Vjb25kLiBFLmcuLCBhdCAxMDowNDoxNS4yNTAgUE0gdGhlCisgICAgICoge0Bjb2RlIE1JTExJU0VDT05EfSBpcyAyNTAuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUlMTElTRUNPTkQgPSAxNDsKKworICAgIC8qKgorICAgICAqIEZpZWxkIG51bWJlciBmb3Ige0Bjb2RlIGdldH0gYW5kIHtAY29kZSBzZXR9IGluZGljYXRpbmcgdGhlCisgICAgICogcmF3IG9mZnNldCBmcm9tIEdNVCBpbiBtaWxsaXNlY29uZHMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgWk9ORV9PRkZTRVQgPSAxNTsKKworICAgIC8qKgorICAgICAqIEZpZWxkIG51bWJlciBmb3Ige0Bjb2RlIGdldH0gYW5kIHtAY29kZSBzZXR9IGluZGljYXRpbmcgdGhlCisgICAgICogZGF5bGlnaHQgc2F2aW5ncyBvZmZzZXQgaW4gbWlsbGlzZWNvbmRzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERTVF9PRkZTRVQgPSAxNjsKKworICAgIC8qKgorICAgICAqIFRoaXMgaXMgdGhlIHRvdGFsIG51bWJlciBvZiBmaWVsZHMgaW4gdGhpcyBjYWxlbmRhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9DT1VOVCA9IDE3OworCisgICAgLyoqCisgICAgICogVmFsdWUgb2YgdGhlIHtAY29kZSBBTV9QTX0gZmllbGQgaW5kaWNhdGluZyB0aGUgcGVyaW9kIG9mIHRoZSBkYXkKKyAgICAgKiBmcm9tIG1pZG5pZ2h0IHRvIGp1c3QgYmVmb3JlIG5vb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQU0gPSAwOworCisgICAgLyoqCisgICAgICogVmFsdWUgb2YgdGhlIHtAY29kZSBBTV9QTX0gZmllbGQgaW5kaWNhdGluZyB0aGUgcGVyaW9kIG9mIHRoZSBkYXkKKyAgICAgKiBmcm9tIG5vb24gdG8ganVzdCBiZWZvcmUgbWlkbmlnaHQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUE0gPSAxOworCisgICAgLyoqCisgICAgICogUmVxdWVzdHMgYm90aCB7QGNvZGUgU0hPUlR9IGFuZCB7QGNvZGUgTE9OR30gc3R5bGVzIGluIHRoZSBtYXAgcmV0dXJuZWQgYnkKKyAgICAgKiB7QGxpbmsgI2dldERpc3BsYXlOYW1lc30uCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFMTF9TVFlMRVMgPSAwOworCisgICAgLyoqCisgICAgICogUmVxdWVzdHMgc2hvcnQgbmFtZXMgKHN1Y2ggYXMgIkphbiIpIGZyb20KKyAgICAgKiB7QGxpbmsgI2dldERpc3BsYXlOYW1lfSBvciB7QGxpbmsgI2dldERpc3BsYXlOYW1lc30uCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1JUID0gMTsKKworICAgIC8qKgorICAgICAqIFJlcXVlc3RzIGxvbmcgbmFtZXMgKHN1Y2ggYXMgIkphbnVhcnkiKSBmcm9tCisgICAgICoge0BsaW5rICNnZXREaXNwbGF5TmFtZX0gb3Ige0BsaW5rICNnZXREaXNwbGF5TmFtZXN9LgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HID0gMjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIEZJRUxEX05BTUVTID0geyAiRVJBIiwgIllFQVIiLCAiTU9OVEgiLAorICAgICAgICAgICAgIldFRUtfT0ZfWUVBUiIsICJXRUVLX09GX01PTlRIIiwgIkRBWV9PRl9NT05USCIsICJEQVlfT0ZfWUVBUiIsCisgICAgICAgICAgICAiREFZX09GX1dFRUsiLCAiREFZX09GX1dFRUtfSU5fTU9OVEgiLCAiQU1fUE0iLCAiSE9VUiIsCisgICAgICAgICAgICAiSE9VUl9PRl9EQVkiLCAiTUlOVVRFIiwgIlNFQ09ORCIsICJNSUxMSVNFQ09ORCIsCisgICAgICAgICAgICAiWk9ORV9PRkZTRVQiLCAiRFNUX09GRlNFVCIgfTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgQ2FsZW5kYXJ9IGluc3RhbmNlIHVzaW5nIHRoZSBkZWZhdWx0IHtAY29kZSBUaW1lWm9uZX0gYW5kIHtAY29kZSBMb2NhbGV9LgorICAgICAqLworICAgIHByb3RlY3RlZCBDYWxlbmRhcigpIHsKKyAgICAgICAgdGhpcyhUaW1lWm9uZS5nZXREZWZhdWx0KCksIExvY2FsZS5nZXREZWZhdWx0KCkpOworICAgIH0KKworICAgIENhbGVuZGFyKFRpbWVab25lIHRpbWV6b25lKSB7CisgICAgICAgIGZpZWxkcyA9IG5ldyBpbnRbRklFTERfQ09VTlRdOworICAgICAgICBpc1NldCA9IG5ldyBib29sZWFuW0ZJRUxEX0NPVU5UXTsKKyAgICAgICAgYXJlRmllbGRzU2V0ID0gaXNUaW1lU2V0ID0gZmFsc2U7CisgICAgICAgIHNldExlbmllbnQodHJ1ZSk7CisgICAgICAgIHNldFRpbWVab25lKHRpbWV6b25lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIENhbGVuZGFyfSBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHtAY29kZSBUaW1lWm9uZX0gYW5kIHtAY29kZSBMb2NhbGV9LgorICAgICAqCisgICAgICogQHBhcmFtIHRpbWV6b25lCisgICAgICogICAgICAgICAgICB0aGUgdGltZXpvbmUuCisgICAgICogQHBhcmFtIGxvY2FsZQorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ2FsZW5kYXIoVGltZVpvbmUgdGltZXpvbmUsIExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgdGhpcyh0aW1lem9uZSk7CisgICAgICAgIExvY2FsZURhdGEgbG9jYWxlRGF0YSA9IExvY2FsZURhdGEuZ2V0KGxvY2FsZSk7CisgICAgICAgIHNldEZpcnN0RGF5T2ZXZWVrKGxvY2FsZURhdGEuZmlyc3REYXlPZldlZWsuaW50VmFsdWUoKSk7CisgICAgICAgIHNldE1pbmltYWxEYXlzSW5GaXJzdFdlZWsobG9jYWxlRGF0YS5taW5pbWFsRGF5c0luRmlyc3RXZWVrLmludFZhbHVlKCkpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIGFtb3VudCB0byBhIHtAY29kZSBDYWxlbmRhcn0gZmllbGQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmllbGQKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9IGZpZWxkIHRvIG1vZGlmeS4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbW91bnQgdG8gYWRkIHRvIHRoZSBmaWVsZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBmaWVsZH0gaXMge0Bjb2RlIERTVF9PRkZTRVR9IG9yIHtAY29kZQorICAgICAqICAgICAgICAgICAgICAgIFpPTkVfT0ZGU0VUfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBhZGQoaW50IGZpZWxkLCBpbnQgdmFsdWUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSB7QGNvZGUgRGF0ZX0gc3BlY2lmaWVkIGJ5IHRoaXMge0Bjb2RlIENhbGVuZGFyfSBpbnN0YW5jZSBpcyBhZnRlciB0aGUge0Bjb2RlIERhdGV9CisgICAgICogc3BlY2lmaWVkIGJ5IHRoZSBwYXJhbWV0ZXIuIFRoZSBjb21wYXJpc29uIGlzIG5vdCBkZXBlbmRlbnQgb24gdGhlIHRpbWUKKyAgICAgKiB6b25lcyBvZiB0aGUge0Bjb2RlIENhbGVuZGFyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYWxlbmRhcgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDYWxlbmRhcn0gaW5zdGFuY2UgdG8gY29tcGFyZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSB3aGVuIHRoaXMgQ2FsZW5kYXIgaXMgYWZ0ZXIgY2FsZW5kYXIsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHRpbWUgaXMgbm90IHNldCBhbmQgdGhlIHRpbWUgY2Fubm90IGJlIGNvbXB1dGVkCisgICAgICogICAgICAgICAgICAgICAgZnJvbSB0aGUgY3VycmVudCBmaWVsZCB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYWZ0ZXIoT2JqZWN0IGNhbGVuZGFyKSB7CisgICAgICAgIGlmICghKGNhbGVuZGFyIGluc3RhbmNlb2YgQ2FsZW5kYXIpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldFRpbWVJbk1pbGxpcygpID4gKChDYWxlbmRhcikgY2FsZW5kYXIpLmdldFRpbWVJbk1pbGxpcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGUge0Bjb2RlIERhdGV9IHNwZWNpZmllZCBieSB0aGlzIHtAY29kZSBDYWxlbmRhcn0gaW5zdGFuY2UgaXMgYmVmb3JlIHRoZQorICAgICAqIHtAY29kZSBEYXRlfSBzcGVjaWZpZWQgYnkgdGhlIHBhcmFtZXRlci4gVGhlIGNvbXBhcmlzb24gaXMgbm90IGRlcGVuZGVudCBvbiB0aGUKKyAgICAgKiB0aW1lIHpvbmVzIG9mIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIGNhbGVuZGFyCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIENhbGVuZGFyfSBpbnN0YW5jZSB0byBjb21wYXJlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IHdoZW4gdGhpcyBDYWxlbmRhciBpcyBiZWZvcmUgY2FsZW5kYXIsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHRpbWUgaXMgbm90IHNldCBhbmQgdGhlIHRpbWUgY2Fubm90IGJlIGNvbXB1dGVkCisgICAgICogICAgICAgICAgICAgICAgZnJvbSB0aGUgY3VycmVudCBmaWVsZCB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYmVmb3JlKE9iamVjdCBjYWxlbmRhcikgeworICAgICAgICBpZiAoIShjYWxlbmRhciBpbnN0YW5jZW9mIENhbGVuZGFyKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRUaW1lSW5NaWxsaXMoKSA8ICgoQ2FsZW5kYXIpIGNhbGVuZGFyKS5nZXRUaW1lSW5NaWxsaXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbGVhcnMgYWxsIG9mIHRoZSBmaWVsZHMgb2YgdGhpcyB7QGNvZGUgQ2FsZW5kYXJ9LiBBbGwgZmllbGRzIGFyZSBpbml0aWFsaXplZCB0bworICAgICAqIHplcm8uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgY2xlYXIoKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgRklFTERfQ09VTlQ7IGkrKykgeworICAgICAgICAgICAgZmllbGRzW2ldID0gMDsKKyAgICAgICAgICAgIGlzU2V0W2ldID0gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgYXJlRmllbGRzU2V0ID0gaXNUaW1lU2V0ID0gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xlYXJzIHRoZSBzcGVjaWZpZWQgZmllbGQgdG8gemVybyBhbmQgc2V0cyB0aGUgaXNTZXQgZmxhZyB0byB7QGNvZGUgZmFsc2V9LgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICB0aGUgZmllbGQgdG8gY2xlYXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgY2xlYXIoaW50IGZpZWxkKSB7CisgICAgICAgIGZpZWxkc1tmaWVsZF0gPSAwOworICAgICAgICBpc1NldFtmaWVsZF0gPSBmYWxzZTsKKyAgICAgICAgYXJlRmllbGRzU2V0ID0gaXNUaW1lU2V0ID0gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgQ2FsZW5kYXJ9IHdpdGggdGhlIHNhbWUgcHJvcGVydGllcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzaGFsbG93IGNvcHkgb2YgdGhpcyB7QGNvZGUgQ2FsZW5kYXJ9LgorICAgICAqCisgICAgICogQHNlZSBqYXZhLmxhbmcuQ2xvbmVhYmxlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENhbGVuZGFyIGNsb25lID0gKENhbGVuZGFyKSBzdXBlci5jbG9uZSgpOworICAgICAgICAgICAgY2xvbmUuZmllbGRzID0gZmllbGRzLmNsb25lKCk7CisgICAgICAgICAgICBjbG9uZS5pc1NldCA9IGlzU2V0LmNsb25lKCk7CisgICAgICAgICAgICBjbG9uZS56b25lID0gKFRpbWVab25lKSB6b25lLmNsb25lKCk7CisgICAgICAgICAgICByZXR1cm4gY2xvbmU7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGVzIHRoZSB0aW1lIGZyb20gdGhlIGZpZWxkcyBpZiB0aGUgdGltZSBoYXMgbm90IGFscmVhZHkgYmVlbiBzZXQuCisgICAgICogQ29tcHV0ZXMgdGhlIGZpZWxkcyBmcm9tIHRoZSB0aW1lIGlmIHRoZSBmaWVsZHMgYXJlIG5vdCBhbHJlYWR5IHNldC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHRpbWUgaXMgbm90IHNldCBhbmQgdGhlIHRpbWUgY2Fubm90IGJlIGNvbXB1dGVkCisgICAgICogICAgICAgICAgICAgICAgZnJvbSB0aGUgY3VycmVudCBmaWVsZCB2YWx1ZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgY29tcGxldGUoKSB7CisgICAgICAgIGlmICghaXNUaW1lU2V0KSB7CisgICAgICAgICAgICBjb21wdXRlVGltZSgpOworICAgICAgICAgICAgaXNUaW1lU2V0ID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIWFyZUZpZWxkc1NldCkgeworICAgICAgICAgICAgY29tcHV0ZUZpZWxkcygpOworICAgICAgICAgICAgYXJlRmllbGRzU2V0ID0gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGVzIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9IGZpZWxkcyBmcm9tIHtAY29kZSB0aW1lfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBjb21wdXRlRmllbGRzKCk7CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlcyB7QGNvZGUgdGltZX0gZnJvbSB0aGUgQ2FsZW5kYXIgZmllbGRzLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgdGltZSBjYW5ub3QgYmUgY29tcHV0ZWQgZnJvbSB0aGUgY3VycmVudCBmaWVsZAorICAgICAqICAgICAgICAgICAgICAgIHZhbHVlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBjb21wdXRlVGltZSgpOworCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBvYmplY3QgdG8gdGhpcyB7QGNvZGUgQ2FsZW5kYXJ9IGFuZCByZXR1cm5zIHdoZXRoZXIgdGhleSBhcmUKKyAgICAgKiBlcXVhbC4gVGhlIG9iamVjdCBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIHtAY29kZSBDYWxlbmRhcn0gYW5kIGhhdmUgdGhlIHNhbWUKKyAgICAgKiBwcm9wZXJ0aWVzLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHdpdGggdGhpcyBvYmplY3QuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgZXF1YWwgdG8gdGhpcyB7QGNvZGUgQ2FsZW5kYXJ9LCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgaWYgKHRoaXMgPT0gb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBDYWxlbmRhcikpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBDYWxlbmRhciBjYWwgPSAoQ2FsZW5kYXIpIG9iamVjdDsKKyAgICAgICAgcmV0dXJuIGdldFRpbWVJbk1pbGxpcygpID09IGNhbC5nZXRUaW1lSW5NaWxsaXMoKQorICAgICAgICAgICAgICAgICYmIGlzTGVuaWVudCgpID09IGNhbC5pc0xlbmllbnQoKQorICAgICAgICAgICAgICAgICYmIGdldEZpcnN0RGF5T2ZXZWVrKCkgPT0gY2FsLmdldEZpcnN0RGF5T2ZXZWVrKCkKKyAgICAgICAgICAgICAgICAmJiBnZXRNaW5pbWFsRGF5c0luRmlyc3RXZWVrKCkgPT0gY2FsCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TWluaW1hbERheXNJbkZpcnN0V2VlaygpCisgICAgICAgICAgICAgICAgJiYgZ2V0VGltZVpvbmUoKS5lcXVhbHMoY2FsLmdldFRpbWVab25lKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgZmllbGQgYWZ0ZXIgY29tcHV0aW5nIHRoZSBmaWVsZCB2YWx1ZXMgYnkKKyAgICAgKiBjYWxsaW5nIHtAY29kZSBjb21wbGV0ZSgpfSBmaXJzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgdGhlIGZpZWxkIHRvIGdldC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZpZWxkLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgZmllbGRzIGFyZSBub3Qgc2V0LCB0aGUgdGltZSBpcyBub3Qgc2V0LCBhbmQgdGhlCisgICAgICogICAgICAgICAgICAgICAgdGltZSBjYW5ub3QgYmUgY29tcHV0ZWQgZnJvbSB0aGUgY3VycmVudCBmaWVsZCB2YWx1ZXMuCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgZmllbGQgaXMgbm90IGluc2lkZSB0aGUgcmFuZ2Ugb2YgcG9zc2libGUgZmllbGRzLgorICAgICAqICAgICAgICAgICAgICAgIFRoZSByYW5nZSBpcyBzdGFydGluZyBhdCAwIHVwIHRvIHtAY29kZSBGSUVMRF9DT1VOVH0uCisgICAgICovCisgICAgcHVibGljIGludCBnZXQoaW50IGZpZWxkKSB7CisgICAgICAgIGNvbXBsZXRlKCk7CisgICAgICAgIHJldHVybiBmaWVsZHNbZmllbGRdOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1heGltdW0gdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBmaWVsZCBmb3IgdGhlIGN1cnJlbnQgZGF0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgdGhlIGZpZWxkLgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEFjdHVhbE1heGltdW0oaW50IGZpZWxkKSB7CisgICAgICAgIGludCB2YWx1ZSwgbmV4dDsKKyAgICAgICAgaWYgKGdldE1heGltdW0oZmllbGQpID09IChuZXh0ID0gZ2V0TGVhc3RNYXhpbXVtKGZpZWxkKSkpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXh0OworICAgICAgICB9CisgICAgICAgIGNvbXBsZXRlKCk7CisgICAgICAgIGxvbmcgb3JnVGltZSA9IHRpbWU7CisgICAgICAgIHNldChmaWVsZCwgbmV4dCk7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIHZhbHVlID0gbmV4dDsKKyAgICAgICAgICAgIHJvbGwoZmllbGQsIHRydWUpOworICAgICAgICAgICAgbmV4dCA9IGdldChmaWVsZCk7CisgICAgICAgIH0gd2hpbGUgKG5leHQgPiB2YWx1ZSk7CisgICAgICAgIHRpbWUgPSBvcmdUaW1lOworICAgICAgICBhcmVGaWVsZHNTZXQgPSBmYWxzZTsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1pbmltdW0gdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBmaWVsZCBmb3IgdGhlIGN1cnJlbnQgZGF0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgdGhlIGZpZWxkLgorICAgICAqIEByZXR1cm4gdGhlIG1pbmltdW0gdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEFjdHVhbE1pbmltdW0oaW50IGZpZWxkKSB7CisgICAgICAgIGludCB2YWx1ZSwgbmV4dDsKKyAgICAgICAgaWYgKGdldE1pbmltdW0oZmllbGQpID09IChuZXh0ID0gZ2V0R3JlYXRlc3RNaW5pbXVtKGZpZWxkKSkpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXh0OworICAgICAgICB9CisgICAgICAgIGNvbXBsZXRlKCk7CisgICAgICAgIGxvbmcgb3JnVGltZSA9IHRpbWU7CisgICAgICAgIHNldChmaWVsZCwgbmV4dCk7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIHZhbHVlID0gbmV4dDsKKyAgICAgICAgICAgIHJvbGwoZmllbGQsIGZhbHNlKTsKKyAgICAgICAgICAgIG5leHQgPSBnZXQoZmllbGQpOworICAgICAgICB9IHdoaWxlIChuZXh0IDwgdmFsdWUpOworICAgICAgICB0aW1lID0gb3JnVGltZTsKKyAgICAgICAgYXJlRmllbGRzU2V0ID0gZmFsc2U7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGxvY2FsZXMgZm9yIHdoaWNoIGN1c3RvbSB7QGNvZGUgQ2FsZW5kYXJ9IGluc3RhbmNlcworICAgICAqIGFyZSBhdmFpbGFibGUuCisgICAgICogPHA+Tm90ZSB0aGF0IEFuZHJvaWQgZG9lcyBub3Qgc3VwcG9ydCB1c2VyLXN1cHBsaWVkIGxvY2FsZSBzZXJ2aWNlIHByb3ZpZGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBMb2NhbGVbXSBnZXRBdmFpbGFibGVMb2NhbGVzKCkgeworICAgICAgICByZXR1cm4gSUNVLmdldEF2YWlsYWJsZUNhbGVuZGFyTG9jYWxlcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGZpcnN0IGRheSBvZiB0aGUgd2VlayBmb3IgdGhpcyB7QGNvZGUgQ2FsZW5kYXJ9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZmlyc3QgZGF5IG9mIHRoZSB3ZWVrLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Rmlyc3REYXlPZldlZWsoKSB7CisgICAgICAgIHJldHVybiBmaXJzdERheU9mV2VlazsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBncmVhdGVzdCBtaW5pbXVtIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgZmllbGQuIFRoaXMgaXMgdGhlCisgICAgICogYmlnZ2VzdCB2YWx1ZSB0aGF0IHtAY29kZSBnZXRBY3R1YWxNaW5pbXVtfSBjYW4gcmV0dXJuIGZvciBhbnkgcG9zc2libGUKKyAgICAgKiB0aW1lLgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICB0aGUgZmllbGQuCisgICAgICogQHJldHVybiB0aGUgZ3JlYXRlc3QgbWluaW11bSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0R3JlYXRlc3RNaW5pbXVtKGludCBmaWVsZCk7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9IHN1YmNsYXNzIGFwcHJvcHJpYXRlIGZvciB0aGUKKyAgICAgKiBkZWZhdWx0IHtAY29kZSBMb2NhbGV9LgorICAgICAqCisgICAgICogQHJldHVybiBhIHtAY29kZSBDYWxlbmRhcn0gc3ViY2xhc3MgaW5zdGFuY2Ugc2V0IHRvIHRoZSBjdXJyZW50IGRhdGUgYW5kIHRpbWUgaW4KKyAgICAgKiAgICAgICAgIHRoZSBkZWZhdWx0IHtAY29kZSBUaW1lem9uZX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgQ2FsZW5kYXIgZ2V0SW5zdGFuY2UoKSB7CisgICAgICAgIHJldHVybiBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9IHN1YmNsYXNzIGFwcHJvcHJpYXRlIGZvciB0aGUKKyAgICAgKiBzcGVjaWZpZWQge0Bjb2RlIExvY2FsZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYWxlCisgICAgICogICAgICAgICAgICB0aGUgbG9jYWxlIHRvIHVzZS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIENhbGVuZGFyfSBzdWJjbGFzcyBpbnN0YW5jZSBzZXQgdG8gdGhlIGN1cnJlbnQgZGF0ZSBhbmQgdGltZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBDYWxlbmRhciBnZXRJbnN0YW5jZShMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIHJldHVybiBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIobG9jYWxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9IHN1YmNsYXNzIGFwcHJvcHJpYXRlIGZvciB0aGUKKyAgICAgKiBkZWZhdWx0IHtAY29kZSBMb2NhbGV9LCB1c2luZyB0aGUgc3BlY2lmaWVkIHtAY29kZSBUaW1lWm9uZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGltZXpvbmUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgVGltZVpvbmV9IHRvIHVzZS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIENhbGVuZGFyfSBzdWJjbGFzcyBpbnN0YW5jZSBzZXQgdG8gdGhlIGN1cnJlbnQgZGF0ZSBhbmQgdGltZSBpbgorICAgICAqICAgICAgICAgdGhlIHNwZWNpZmllZCB0aW1lem9uZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBDYWxlbmRhciBnZXRJbnN0YW5jZShUaW1lWm9uZSB0aW1lem9uZSkgeworICAgICAgICByZXR1cm4gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKHRpbWV6b25lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9IHN1YmNsYXNzIGFwcHJvcHJpYXRlIGZvciB0aGUKKyAgICAgKiBzcGVjaWZpZWQge0Bjb2RlIExvY2FsZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGltZXpvbmUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgVGltZVpvbmV9IHRvIHVzZS4KKyAgICAgKiBAcGFyYW0gbG9jYWxlCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIExvY2FsZX0gdG8gdXNlLgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgQ2FsZW5kYXJ9IHN1YmNsYXNzIGluc3RhbmNlIHNldCB0byB0aGUgY3VycmVudCBkYXRlIGFuZCB0aW1lIGluCisgICAgICogICAgICAgICB0aGUgc3BlY2lmaWVkIHRpbWV6b25lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIENhbGVuZGFyIGdldEluc3RhbmNlKFRpbWVab25lIHRpbWV6b25lLCBMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIHJldHVybiBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIodGltZXpvbmUsIGxvY2FsZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc21hbGxlc3QgbWF4aW11bSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZpZWxkLiBUaGlzIGlzIHRoZQorICAgICAqIHNtYWxsZXN0IHZhbHVlIHRoYXQge0Bjb2RlIGdldEFjdHVhbE1heGltdW0oKX0gY2FuIHJldHVybiBmb3IgYW55CisgICAgICogcG9zc2libGUgdGltZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgdGhlIGZpZWxkIG51bWJlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBzbWFsbGVzdCBtYXhpbXVtIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgZmllbGQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRMZWFzdE1heGltdW0oaW50IGZpZWxkKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGdyZWF0ZXN0IG1heGltdW0gdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBmaWVsZC4gVGhpcyByZXR1cm5zIHRoZQorICAgICAqIGJpZ2dlc3QgdmFsdWUgdGhhdCB7QGNvZGUgZ2V0fSBjYW4gcmV0dXJuIGZvciB0aGUgc3BlY2lmaWVkIGZpZWxkLgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICB0aGUgZmllbGQuCisgICAgICogQHJldHVybiB0aGUgZ3JlYXRlc3QgbWF4aW11bSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0TWF4aW11bShpbnQgZmllbGQpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWluaW1hbCBkYXlzIGluIHRoZSBmaXJzdCB3ZWVrIG9mIHRoZSB5ZWFyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbWluaW1hbCBkYXlzIGluIHRoZSBmaXJzdCB3ZWVrIG9mIHRoZSB5ZWFyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWluaW1hbERheXNJbkZpcnN0V2VlaygpIHsKKyAgICAgICAgcmV0dXJuIG1pbmltYWxEYXlzSW5GaXJzdFdlZWs7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc21hbGxlc3QgbWluaW11bSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZpZWxkLiB0aGlzIHJldHVybnMgdGhlCisgICAgICogc21hbGxlc3QgdmFsdWUgdGhldCB7QGNvZGUgZ2V0fSBjYW4gcmV0dXJuIGZvciB0aGUgc3BlY2lmaWVkIGZpZWxkLgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICB0aGUgZmllbGQgbnVtYmVyLgorICAgICAqIEByZXR1cm4gdGhlIHNtYWxsZXN0IG1pbmltdW0gdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldE1pbmltdW0oaW50IGZpZWxkKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHRpbWUgb2YgdGhpcyB7QGNvZGUgQ2FsZW5kYXJ9IGFzIGEge0Bjb2RlIERhdGV9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBuZXcge0Bjb2RlIERhdGV9IGluaXRpYWxpemVkIHRvIHRoZSB0aW1lIG9mIHRoaXMge0Bjb2RlIENhbGVuZGFyfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHRpbWUgaXMgbm90IHNldCBhbmQgdGhlIHRpbWUgY2Fubm90IGJlIGNvbXB1dGVkCisgICAgICogICAgICAgICAgICAgICAgZnJvbSB0aGUgY3VycmVudCBmaWVsZCB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIERhdGUgZ2V0VGltZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBEYXRlKGdldFRpbWVJbk1pbGxpcygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlcyB0aGUgdGltZSBmcm9tIHRoZSBmaWVsZHMgaWYgcmVxdWlyZWQgYW5kIHJldHVybnMgdGhlIHRpbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB0aW1lIG9mIHRoaXMge0Bjb2RlIENhbGVuZGFyfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHRpbWUgaXMgbm90IHNldCBhbmQgdGhlIHRpbWUgY2Fubm90IGJlIGNvbXB1dGVkCisgICAgICogICAgICAgICAgICAgICAgZnJvbSB0aGUgY3VycmVudCBmaWVsZCB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0VGltZUluTWlsbGlzKCkgeworICAgICAgICBpZiAoIWlzVGltZVNldCkgeworICAgICAgICAgICAgY29tcHV0ZVRpbWUoKTsKKyAgICAgICAgICAgIGlzVGltZVNldCA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRpbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdGltZXpvbmUgb2YgdGhpcyB7QGNvZGUgQ2FsZW5kYXJ9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFRpbWVab25lfSB1c2VkIGJ5IHRoaXMge0Bjb2RlIENhbGVuZGFyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGltZVpvbmUgZ2V0VGltZVpvbmUoKSB7CisgICAgICAgIHJldHVybiB6b25lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW50ZWdlciBoYXNoIGNvZGUgZm9yIHRoZSByZWNlaXZlci4gT2JqZWN0cyB3aGljaCBhcmUgZXF1YWwKKyAgICAgKiByZXR1cm4gdGhlIHNhbWUgdmFsdWUgZm9yIHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBoYXNoLgorICAgICAqCisgICAgICogQHNlZSAjZXF1YWxzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIChpc0xlbmllbnQoKSA/IDEyMzcgOiAxMjMxKSArIGdldEZpcnN0RGF5T2ZXZWVrKCkKKyAgICAgICAgICAgICAgICArIGdldE1pbmltYWxEYXlzSW5GaXJzdFdlZWsoKSArIGdldFRpbWVab25lKCkuaGFzaENvZGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZpZWxkIHdpdGhvdXQgcmVjb21wdXRpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmllbGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWVsZC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZpZWxkLgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBpbnQgaW50ZXJuYWxHZXQoaW50IGZpZWxkKSB7CisgICAgICAgIHJldHVybiBmaWVsZHNbZmllbGRdOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgaWYgdGhpcyB7QGNvZGUgQ2FsZW5kYXJ9IGFjY2VwdHMgZmllbGQgdmFsdWVzIHdoaWNoIGFyZSBvdXRzaWRlIHRoZSB2YWxpZAorICAgICAqIHJhbmdlIGZvciB0aGUgZmllbGQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBDYWxlbmRhcn0gaXMgbGVuaWVudCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNMZW5pZW50KCkgeworICAgICAgICByZXR1cm4gbGVuaWVudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBmaWVsZCBpcyBzZXQuIE5vdGUgdGhhdCB0aGUgaW50ZXJwcmV0YXRpb24gb2YgImlzIHNldCIgaXMKKyAgICAgKiBzb21ld2hhdCB0ZWNobmljYWwuIEluIHBhcnRpY3VsYXIsIGl0IGRvZXMgPGk+bm90PC9pPiBtZWFuIHRoYXQgdGhlIGZpZWxkJ3MgdmFsdWUgaXMgdXAKKyAgICAgKiB0byBkYXRlLiBJZiB5b3Ugd2FudCB0byBrbm93IHdoZXRoZXIgYSBmaWVsZCBjb250YWlucyBhbiB1cC10by1kYXRlIHZhbHVlLCB5b3UgbXVzdCBhbHNvCisgICAgICogY2hlY2sge0Bjb2RlIGFyZUZpZWxkc1NldH0sIG1ha2luZyB0aGlzIG1ldGhvZCBzb21ld2hhdCB1c2VsZXNzIHVubGVzcyB5b3UncmUgYSBzdWJjbGFzcywKKyAgICAgKiBpbiB3aGljaCBjYXNlIHlvdSBjYW4gYWNjZXNzIHRoZSB7QGNvZGUgaXNTZXR9IGFycmF5IGRpcmVjdGx5LgorICAgICAqIDxwPgorICAgICAqIEEgZmllbGQgcmVtYWlucyAic2V0IiBmcm9tIHRoZSBmaXJzdCB0aW1lIGl0cyB2YWx1ZSBpcyBjb21wdXRlZCB1bnRpbCBpdCdzIGNsZWFyZWQgYnkgb25lCisgICAgICogb2YgdGhlIHtAY29kZSBjbGVhcn0gbWV0aG9kcy4gVGh1cyAic2V0IiBkb2VzIG5vdCBtZWFuICJ2YWxpZCIuIFlvdSBwcm9iYWJseSB3YW50IHRvIGNhbGwKKyAgICAgKiB7QGNvZGUgZ2V0fSAtLSB3aGljaCB3aWxsIHVwZGF0ZSBmaWVsZHMgYXMgbmVjZXNzYXJ5IC0tIHJhdGhlciB0aGFuIHRyeSB0byBtYWtlIHVzZSBvZgorICAgICAqIHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBDYWxlbmRhcn0gZmllbGQgbnVtYmVyLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgZmllbGQgaXMgc2V0LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc1NldChpbnQgZmllbGQpIHsKKyAgICAgICAgcmV0dXJuIGlzU2V0W2ZpZWxkXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgYW1vdW50IHRvIHRoZSBzcGVjaWZpZWQgZmllbGQgYW5kIHdyYXBzIHRoZSB2YWx1ZSBvZgorICAgICAqIHRoZSBmaWVsZCB3aGVuIGl0IGdvZXMgYmV5b25kIHRoZSBtYXhpbXVtIG9yIG1pbmltdW0gdmFsdWUgZm9yIHRoZQorICAgICAqIGN1cnJlbnQgZGF0ZS4gT3RoZXIgZmllbGRzIHdpbGwgYmUgYWRqdXN0ZWQgYXMgcmVxdWlyZWQgdG8gbWFpbnRhaW4gYQorICAgICAqIGNvbnNpc3RlbnQgZGF0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgdGhlIGZpZWxkIHRvIHJvbGwuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgYW1vdW50IHRvIGFkZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByb2xsKGludCBmaWVsZCwgaW50IHZhbHVlKSB7CisgICAgICAgIGJvb2xlYW4gaW5jcmVtZW50ID0gdmFsdWUgPj0gMDsKKyAgICAgICAgaW50IGNvdW50ID0gaW5jcmVtZW50ID8gdmFsdWUgOiAtdmFsdWU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgeworICAgICAgICAgICAgcm9sbChmaWVsZCwgaW5jcmVtZW50KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluY3JlbWVudCBvciBkZWNyZW1lbnQgdGhlIHNwZWNpZmllZCBmaWVsZCBhbmQgd3JhcCB0aGUgdmFsdWUgb2YgdGhlCisgICAgICogZmllbGQgd2hlbiBpdCBnb2VzIGJleW9uZCB0aGUgbWF4aW11bSBvciBtaW5pbXVtIHZhbHVlIGZvciB0aGUgY3VycmVudAorICAgICAqIGRhdGUuIE90aGVyIGZpZWxkcyB3aWxsIGJlIGFkanVzdGVkIGFzIHJlcXVpcmVkIHRvIG1haW50YWluIGEgY29uc2lzdGVudAorICAgICAqIGRhdGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmllbGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgaW5kaWNhdGluZyB0aGUgZmllbGQgdG8gcm9sbC4KKyAgICAgKiBAcGFyYW0gaW5jcmVtZW50CisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gdG8gaW5jcmVtZW50IHRoZSBmaWVsZCwge0Bjb2RlIGZhbHNlfSB0byBkZWNyZW1lbnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcm9sbChpbnQgZmllbGQsIGJvb2xlYW4gaW5jcmVtZW50KTsKKworICAgIC8qKgorICAgICAqIFNldHMgYSBmaWVsZCB0byB0aGUgc3BlY2lmaWVkIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICB0aGUgY29kZSBpbmRpY2F0aW5nIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9IGZpZWxkIHRvIG1vZGlmeS4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXQoaW50IGZpZWxkLCBpbnQgdmFsdWUpIHsKKyAgICAgICAgZmllbGRzW2ZpZWxkXSA9IHZhbHVlOworICAgICAgICBpc1NldFtmaWVsZF0gPSB0cnVlOworICAgICAgICBhcmVGaWVsZHNTZXQgPSBpc1RpbWVTZXQgPSBmYWxzZTsKKyAgICAgICAgaWYgKGZpZWxkID4gTU9OVEggJiYgZmllbGQgPCBBTV9QTSkgeworICAgICAgICAgICAgbGFzdERhdGVGaWVsZFNldCA9IGZpZWxkOworICAgICAgICB9CisgICAgICAgIGlmIChmaWVsZCA9PSBIT1VSIHx8IGZpZWxkID09IEhPVVJfT0ZfREFZKSB7CisgICAgICAgICAgICBsYXN0VGltZUZpZWxkU2V0ID0gZmllbGQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZpZWxkID09IEFNX1BNKSB7CisgICAgICAgICAgICBsYXN0VGltZUZpZWxkU2V0ID0gSE9VUjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHllYXIsIG1vbnRoIGFuZCBkYXkgb2YgdGhlIG1vbnRoIGZpZWxkcy4gT3RoZXIgZmllbGRzIGFyZSBub3QKKyAgICAgKiBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIHllYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB5ZWFyLgorICAgICAqIEBwYXJhbSBtb250aAorICAgICAqICAgICAgICAgICAgdGhlIG1vbnRoLgorICAgICAqIEBwYXJhbSBkYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXkgb2YgdGhlIG1vbnRoLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldChpbnQgeWVhciwgaW50IG1vbnRoLCBpbnQgZGF5KSB7CisgICAgICAgIHNldChZRUFSLCB5ZWFyKTsKKyAgICAgICAgc2V0KE1PTlRILCBtb250aCk7CisgICAgICAgIHNldChEQVRFLCBkYXkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHllYXIsIG1vbnRoLCBkYXkgb2YgdGhlIG1vbnRoLCBob3VyIG9mIGRheSBhbmQgbWludXRlIGZpZWxkcy4KKyAgICAgKiBPdGhlciBmaWVsZHMgYXJlIG5vdCBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIHllYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB5ZWFyLgorICAgICAqIEBwYXJhbSBtb250aAorICAgICAqICAgICAgICAgICAgdGhlIG1vbnRoLgorICAgICAqIEBwYXJhbSBkYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXkgb2YgdGhlIG1vbnRoLgorICAgICAqIEBwYXJhbSBob3VyT2ZEYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBob3VyIG9mIGRheS4KKyAgICAgKiBAcGFyYW0gbWludXRlCisgICAgICogICAgICAgICAgICB0aGUgbWludXRlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldChpbnQgeWVhciwgaW50IG1vbnRoLCBpbnQgZGF5LCBpbnQgaG91ck9mRGF5LAorICAgICAgICAgICAgaW50IG1pbnV0ZSkgeworICAgICAgICBzZXQoeWVhciwgbW9udGgsIGRheSk7CisgICAgICAgIHNldChIT1VSX09GX0RBWSwgaG91ck9mRGF5KTsKKyAgICAgICAgc2V0KE1JTlVURSwgbWludXRlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB5ZWFyLCBtb250aCwgZGF5IG9mIHRoZSBtb250aCwgaG91ciBvZiBkYXksIG1pbnV0ZSBhbmQgc2Vjb25kCisgICAgICogZmllbGRzLiBPdGhlciBmaWVsZHMgYXJlIG5vdCBjaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIHllYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB5ZWFyLgorICAgICAqIEBwYXJhbSBtb250aAorICAgICAqICAgICAgICAgICAgdGhlIG1vbnRoLgorICAgICAqIEBwYXJhbSBkYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXkgb2YgdGhlIG1vbnRoLgorICAgICAqIEBwYXJhbSBob3VyT2ZEYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBob3VyIG9mIGRheS4KKyAgICAgKiBAcGFyYW0gbWludXRlCisgICAgICogICAgICAgICAgICB0aGUgbWludXRlLgorICAgICAqIEBwYXJhbSBzZWNvbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgc2V0KGludCB5ZWFyLCBpbnQgbW9udGgsIGludCBkYXksIGludCBob3VyT2ZEYXksCisgICAgICAgICAgICBpbnQgbWludXRlLCBpbnQgc2Vjb25kKSB7CisgICAgICAgIHNldCh5ZWFyLCBtb250aCwgZGF5LCBob3VyT2ZEYXksIG1pbnV0ZSk7CisgICAgICAgIHNldChTRUNPTkQsIHNlY29uZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZmlyc3QgZGF5IG9mIHRoZSB3ZWVrIGZvciB0aGlzIHtAY29kZSBDYWxlbmRhcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIGEge0Bjb2RlIENhbGVuZGFyfSBkYXkgb2YgdGhlIHdlZWsuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Rmlyc3REYXlPZldlZWsoaW50IHZhbHVlKSB7CisgICAgICAgIGZpcnN0RGF5T2ZXZWVrID0gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGlzIHtAY29kZSBDYWxlbmRhcn0gdG8gYWNjZXB0IGZpZWxkIHZhbHVlcyB3aGljaCBhcmUgb3V0c2lkZSB0aGUgdmFsaWQKKyAgICAgKiByYW5nZSBmb3IgdGhlIGZpZWxkLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICBhIGJvb2xlYW4gdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TGVuaWVudChib29sZWFuIHZhbHVlKSB7CisgICAgICAgIGxlbmllbnQgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBtaW5pbWFsIGRheXMgaW4gdGhlIGZpcnN0IHdlZWsgb2YgdGhlIHllYXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBtaW5pbWFsIGRheXMgaW4gdGhlIGZpcnN0IHdlZWsgb2YgdGhlIHllYXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TWluaW1hbERheXNJbkZpcnN0V2VlayhpbnQgdmFsdWUpIHsKKyAgICAgICAgbWluaW1hbERheXNJbkZpcnN0V2VlayA9IHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHRpbWUgb2YgdGhpcyB7QGNvZGUgQ2FsZW5kYXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGUKKyAgICAgKiAgICAgICAgICAgIGEge0Bjb2RlIERhdGV9IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRUaW1lKERhdGUgZGF0ZSkgeworICAgICAgICBzZXRUaW1lSW5NaWxsaXMoZGF0ZS5nZXRUaW1lKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHRpbWUgb2YgdGhpcyB7QGNvZGUgQ2FsZW5kYXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIG1pbGxpc2Vjb25kcworICAgICAqICAgICAgICAgICAgdGhlIHRpbWUgYXMgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgc2luY2UgSmFuLiAxLCAxOTcwLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRpbWVJbk1pbGxpcyhsb25nIG1pbGxpc2Vjb25kcykgeworICAgICAgICBpZiAoIWlzVGltZVNldCB8fCAhYXJlRmllbGRzU2V0IHx8IHRpbWUgIT0gbWlsbGlzZWNvbmRzKSB7CisgICAgICAgICAgICB0aW1lID0gbWlsbGlzZWNvbmRzOworICAgICAgICAgICAgaXNUaW1lU2V0ID0gdHJ1ZTsKKyAgICAgICAgICAgIGFyZUZpZWxkc1NldCA9IGZhbHNlOworICAgICAgICAgICAgY29tcGxldGUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHtAY29kZSBUaW1lWm9uZX0gdXNlZCBieSB0aGlzIENhbGVuZGFyLgorICAgICAqCisgICAgICogQHBhcmFtIHRpbWV6b25lCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBUaW1lWm9uZX0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VGltZVpvbmUoVGltZVpvbmUgdGltZXpvbmUpIHsKKyAgICAgICAgem9uZSA9IHRpbWV6b25lOworICAgICAgICBhcmVGaWVsZHNTZXQgPSBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgQ2FsZW5kYXJ9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKworICAgICAgICAgICAgICAgICJbdGltZT0iICsgKGlzVGltZVNldCA/IFN0cmluZy52YWx1ZU9mKHRpbWUpIDogIj8iKSArCisgICAgICAgICAgICAgICAgIixhcmVGaWVsZHNTZXQ9IiArIGFyZUZpZWxkc1NldCArCisgICAgICAgICAgICAgICAgIixsZW5pZW50PSIgKyBsZW5pZW50ICsKKyAgICAgICAgICAgICAgICAiLHpvbmU9IiArIHpvbmUuZ2V0SUQoKSArCisgICAgICAgICAgICAgICAgIixmaXJzdERheU9mV2Vlaz0iICsgZmlyc3REYXlPZldlZWsgKworICAgICAgICAgICAgICAgICIsbWluaW1hbERheXNJbkZpcnN0V2Vlaz0iICsgbWluaW1hbERheXNJbkZpcnN0V2Vlayk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgRklFTERfQ09VTlQ7IGkrKykgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnLCcpOworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChGSUVMRF9OQU1FU1tpXSk7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCc9Jyk7CisgICAgICAgICAgICBpZiAoaXNTZXRbaV0pIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGZpZWxkc1tpXSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJz8nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXN1bHQuYXBwZW5kKCddJyk7CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgdGltZXMgb2YgdGhlIHR3byB7QGNvZGUgQ2FsZW5kYXJ9LCB3aGljaCByZXByZXNlbnQgdGhlIG1pbGxpc2Vjb25kcworICAgICAqIGZyb20gdGhlIEphbnVhcnkgMSwgMTk3MCAwMDowMDowMC4wMDAgR01UIChHcmVnb3JpYW4pLgorICAgICAqCisgICAgICogQHBhcmFtIGFub3RoZXJDYWxlbmRhcgorICAgICAqICAgICAgICAgICAgYW5vdGhlciBjYWxlbmRhciB0aGF0IHRoaXMgb25lIGlzIGNvbXBhcmVkIHdpdGguCisgICAgICogQHJldHVybiAwIGlmIHRoZSB0aW1lcyBvZiB0aGUgdHdvIHtAY29kZSBDYWxlbmRhcn1zIGFyZSBlcXVhbCwgLTEgaWYgdGhlIHRpbWUgb2YKKyAgICAgKiAgICAgICAgIHRoaXMge0Bjb2RlIENhbGVuZGFyfSBpcyBiZWZvcmUgdGhlIG90aGVyIG9uZSwgMSBpZiB0aGUgdGltZSBvZiB0aGlzCisgICAgICogICAgICAgICB7QGNvZGUgQ2FsZW5kYXJ9IGlzIGFmdGVyIHRoZSBvdGhlciBvbmUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhcmd1bWVudCBpcyBudWxsLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGFyZ3VtZW50IGRvZXMgbm90IGluY2x1ZGUgYSB2YWxpZCB0aW1lCisgICAgICogICAgICAgICAgICAgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGludCBjb21wYXJlVG8oQ2FsZW5kYXIgYW5vdGhlckNhbGVuZGFyKSB7CisgICAgICAgIGlmIChhbm90aGVyQ2FsZW5kYXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgbG9uZyB0aW1lSW5NaWxsaXMgPSBnZXRUaW1lSW5NaWxsaXMoKTsKKyAgICAgICAgbG9uZyBhbm90aGVyVGltZUluTWlsbGlzID0gYW5vdGhlckNhbGVuZGFyLmdldFRpbWVJbk1pbGxpcygpOworICAgICAgICBpZiAodGltZUluTWlsbGlzID4gYW5vdGhlclRpbWVJbk1pbGxpcykgeworICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRpbWVJbk1pbGxpcyA9PSBhbm90aGVyVGltZUluTWlsbGlzKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGh1bWFuLXJlYWRhYmxlIHN0cmluZyBmb3IgdGhlIHZhbHVlIG9mIHtAY29kZSBmaWVsZH0KKyAgICAgKiB1c2luZyB0aGUgZ2l2ZW4gc3R5bGUgYW5kIGxvY2FsZS4gSWYgbm8gc3RyaW5nIGlzIGF2YWlsYWJsZSwgcmV0dXJucyBudWxsLgorICAgICAqIFRoZSB2YWx1ZSBpcyByZXRyaWV2ZWQgYnkgaW52b2tpbmcge0Bjb2RlIGdldChmaWVsZCl9LgorICAgICAqCisgICAgICogPHA+Rm9yIGV4YW1wbGUsIHtAY29kZSBnZXREaXNwbGF5TmFtZShNT05USCwgU0hPUlQsIExvY2FsZS5VUyl9IHdpbGwgcmV0dXJuICJKYW4iCisgICAgICogd2hpbGUge0Bjb2RlIGdldERpc3BsYXlOYW1lKE1PTlRILCBMT05HLCBMb2NhbGUuVVMpfSB3aWxsIHJldHVybiAiSmFudWFyeSIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmllbGQgdGhlIGZpZWxkCisgICAgICogQHBhcmFtIHN0eWxlIHtAY29kZSBTSE9SVH0gb3Ige0Bjb2RlIExPTkd9CisgICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlCisgICAgICogQHJldHVybiB0aGUgZGlzcGxheSBuYW1lLCBvciBudWxsCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgbG9jYWxlID09IG51bGx9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGZpZWxkfSBvciB7QGNvZGUgc3R5bGV9IGlzIGludmFsaWQKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXREaXNwbGF5TmFtZShpbnQgZmllbGQsIGludCBzdHlsZSwgTG9jYWxlIGxvY2FsZSkgeworICAgICAgICAvLyBUT0RPOiB0aGUgUkkncyBkb2N1bWVudGF0aW9uIHNheXMgQUxMX1NUWUxFUyBpcyBpbnZhbGlkLCBidXQgYWN0dWFsbHkgdHJlYXRzIGl0IGFzIFNIT1JULgorICAgICAgICBpZiAoc3R5bGUgPT0gQUxMX1NUWUxFUykgeworICAgICAgICAgICAgc3R5bGUgPSBTSE9SVDsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmdbXSBhcnJheSA9IGdldERpc3BsYXlOYW1lQXJyYXkoZmllbGQsIHN0eWxlLCBsb2NhbGUpOworICAgICAgICBpbnQgdmFsdWUgPSBnZXQoZmllbGQpOworICAgICAgICByZXR1cm4gKGFycmF5ICE9IG51bGwpID8gYXJyYXlbdmFsdWVdIDogbnVsbDsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZ1tdIGdldERpc3BsYXlOYW1lQXJyYXkoaW50IGZpZWxkLCBpbnQgc3R5bGUsIExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgaWYgKGZpZWxkIDwgMCB8fCBmaWVsZCA+PSBGSUVMRF9DT1VOVCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiYmFkIGZpZWxkICIgKyBmaWVsZCk7CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tTdHlsZShzdHlsZSk7CisgICAgICAgIERhdGVGb3JtYXRTeW1ib2xzIGRmcyA9IERhdGVGb3JtYXRTeW1ib2xzLmdldEluc3RhbmNlKGxvY2FsZSk7CisgICAgICAgIHN3aXRjaCAoZmllbGQpIHsKKyAgICAgICAgY2FzZSBBTV9QTToKKyAgICAgICAgICAgIHJldHVybiBkZnMuZ2V0QW1QbVN0cmluZ3MoKTsKKyAgICAgICAgY2FzZSBEQVlfT0ZfV0VFSzoKKyAgICAgICAgICAgIHJldHVybiAoc3R5bGUgPT0gTE9ORykgPyBkZnMuZ2V0V2Vla2RheXMoKSA6IGRmcy5nZXRTaG9ydFdlZWtkYXlzKCk7CisgICAgICAgIGNhc2UgRVJBOgorICAgICAgICAgICAgcmV0dXJuIGRmcy5nZXRFcmFzKCk7CisgICAgICAgIGNhc2UgTU9OVEg6CisgICAgICAgICAgICByZXR1cm4gKHN0eWxlID09IExPTkcpID8gZGZzLmdldE1vbnRocygpIDogZGZzLmdldFNob3J0TW9udGhzKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja1N0eWxlKGludCBzdHlsZSkgeworICAgICAgICBpZiAoc3R5bGUgIT0gQUxMX1NUWUxFUyAmJiBzdHlsZSAhPSBTSE9SVCAmJiBzdHlsZSAhPSBMT05HKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJiYWQgc3R5bGUgIiArIHN0eWxlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBtYXAgb2YgaHVtYW4tcmVhZGFibGUgc3RyaW5ncyB0byBjb3JyZXNwb25kaW5nIHZhbHVlcywKKyAgICAgKiBmb3IgdGhlIGdpdmVuIGZpZWxkLCBzdHlsZSwgYW5kIGxvY2FsZS4KKyAgICAgKiBSZXR1cm5zIG51bGwgaWYgbm8gc3RyaW5ncyBhcmUgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogPHA+Rm9yIGV4YW1wbGUsIHtAY29kZSBnZXREaXNwbGF5TmFtZXMoTU9OVEgsIEFMTF9TVFlMRVMsIExvY2FsZS5VUyl9IHdvdWxkCisgICAgICogY29udGFpbiBtYXBwaW5ncyBmcm9tICJKYW4iIGFuZCAiSmFudWFyeSIgdG8ge0BsaW5rICNKQU5VQVJZfSwgYW5kIHNvIG9uLgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkIHRoZSBmaWVsZAorICAgICAqIEBwYXJhbSBzdHlsZSB7QGNvZGUgU0hPUlR9LCB7QGNvZGUgTE9OR30sIG9yIHtAY29kZSBBTExfU1RZTEVTfQorICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZQorICAgICAqIEByZXR1cm4gdGhlIGRpc3BsYXkgbmFtZSwgb3IgbnVsbAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIGxvY2FsZSA9PSBudWxsfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBmaWVsZH0gb3Ige0Bjb2RlIHN0eWxlfSBpcyBpbnZhbGlkCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBnZXREaXNwbGF5TmFtZXMoaW50IGZpZWxkLCBpbnQgc3R5bGUsIExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgY2hlY2tTdHlsZShzdHlsZSk7CisgICAgICAgIGNvbXBsZXRlKCk7CisgICAgICAgIE1hcDxTdHJpbmcsIEludGVnZXI+IHJlc3VsdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgSW50ZWdlcj4oKTsKKyAgICAgICAgaWYgKHN0eWxlID09IFNIT1JUIHx8IHN0eWxlID09IEFMTF9TVFlMRVMpIHsKKyAgICAgICAgICAgIGluc2VydFZhbHVlc0luTWFwKHJlc3VsdCwgZ2V0RGlzcGxheU5hbWVBcnJheShmaWVsZCwgU0hPUlQsIGxvY2FsZSkpOworICAgICAgICB9CisgICAgICAgIGlmIChzdHlsZSA9PSBMT05HIHx8IHN0eWxlID09IEFMTF9TVFlMRVMpIHsKKyAgICAgICAgICAgIGluc2VydFZhbHVlc0luTWFwKHJlc3VsdCwgZ2V0RGlzcGxheU5hbWVBcnJheShmaWVsZCwgTE9ORywgbG9jYWxlKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdC5pc0VtcHR5KCkgPyBudWxsIDogcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgaW5zZXJ0VmFsdWVzSW5NYXAoTWFwPFN0cmluZywgSW50ZWdlcj4gbWFwLCBTdHJpbmdbXSB2YWx1ZXMpIHsKKyAgICAgICAgaWYgKHZhbHVlcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIGlmICh2YWx1ZXNbaV0gIT0gbnVsbCAmJiAhdmFsdWVzW2ldLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIG1hcC5wdXQodmFsdWVzW2ldLCBpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFN0cmVhbUZpZWxkW10gc2VyaWFsUGVyc2lzdGVudEZpZWxkcyA9IHsKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJhcmVGaWVsZHNTZXQiLCBib29sZWFuLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJmaWVsZHMiLCBpbnRbXS5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiZmlyc3REYXlPZldlZWsiLCBpbnQuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImlzU2V0IiwgYm9vbGVhbltdLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJpc1RpbWVTZXQiLCBib29sZWFuLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJsZW5pZW50IiwgYm9vbGVhbi5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgibWluaW1hbERheXNJbkZpcnN0V2VlayIsIGludC5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgibmV4dFN0YW1wIiwgaW50LmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJzZXJpYWxWZXJzaW9uT25TdHJlYW0iLCBpbnQuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInRpbWUiLCBsb25nLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJ6b25lIiwgVGltZVpvbmUuY2xhc3MpLAorICAgIH07CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY29tcGxldGUoKTsKKyAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtLlB1dEZpZWxkIHB1dEZpZWxkcyA9IHN0cmVhbS5wdXRGaWVsZHMoKTsKKyAgICAgICAgcHV0RmllbGRzLnB1dCgiYXJlRmllbGRzU2V0IiwgYXJlRmllbGRzU2V0KTsKKyAgICAgICAgcHV0RmllbGRzLnB1dCgiZmllbGRzIiwgdGhpcy5maWVsZHMpOworICAgICAgICBwdXRGaWVsZHMucHV0KCJmaXJzdERheU9mV2VlayIsIGZpcnN0RGF5T2ZXZWVrKTsKKyAgICAgICAgcHV0RmllbGRzLnB1dCgiaXNTZXQiLCBpc1NldCk7CisgICAgICAgIHB1dEZpZWxkcy5wdXQoImlzVGltZVNldCIsIGlzVGltZVNldCk7CisgICAgICAgIHB1dEZpZWxkcy5wdXQoImxlbmllbnQiLCBsZW5pZW50KTsKKyAgICAgICAgcHV0RmllbGRzLnB1dCgibWluaW1hbERheXNJbkZpcnN0V2VlayIsIG1pbmltYWxEYXlzSW5GaXJzdFdlZWspOworICAgICAgICBwdXRGaWVsZHMucHV0KCJuZXh0U3RhbXAiLCAyIC8qIE1JTklNVU1fVVNFUl9TVEFNUCAqLyk7CisgICAgICAgIHB1dEZpZWxkcy5wdXQoInNlcmlhbFZlcnNpb25PblN0cmVhbSIsIDEpOworICAgICAgICBwdXRGaWVsZHMucHV0KCJ0aW1lIiwgdGltZSk7CisgICAgICAgIHB1dEZpZWxkcy5wdXQoInpvbmUiLCB6b25lKTsKKyAgICAgICAgc3RyZWFtLndyaXRlRmllbGRzKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBPYmplY3RJbnB1dFN0cmVhbS5HZXRGaWVsZCByZWFkRmllbGRzID0gc3RyZWFtLnJlYWRGaWVsZHMoKTsKKyAgICAgICAgYXJlRmllbGRzU2V0ID0gcmVhZEZpZWxkcy5nZXQoImFyZUZpZWxkc1NldCIsIGZhbHNlKTsKKyAgICAgICAgdGhpcy5maWVsZHMgPSAoaW50W10pIHJlYWRGaWVsZHMuZ2V0KCJmaWVsZHMiLCBudWxsKTsKKyAgICAgICAgZmlyc3REYXlPZldlZWsgPSByZWFkRmllbGRzLmdldCgiZmlyc3REYXlPZldlZWsiLCBDYWxlbmRhci5TVU5EQVkpOworICAgICAgICBpc1NldCA9IChib29sZWFuW10pIHJlYWRGaWVsZHMuZ2V0KCJpc1NldCIsIG51bGwpOworICAgICAgICBpc1RpbWVTZXQgPSByZWFkRmllbGRzLmdldCgiaXNUaW1lU2V0IiwgZmFsc2UpOworICAgICAgICBsZW5pZW50ID0gcmVhZEZpZWxkcy5nZXQoImxlbmllbnQiLCB0cnVlKTsKKyAgICAgICAgbWluaW1hbERheXNJbkZpcnN0V2VlayA9IHJlYWRGaWVsZHMuZ2V0KCJtaW5pbWFsRGF5c0luRmlyc3RXZWVrIiwgMSk7CisgICAgICAgIHRpbWUgPSByZWFkRmllbGRzLmdldCgidGltZSIsIDBMKTsKKyAgICAgICAgem9uZSA9IChUaW1lWm9uZSkgcmVhZEZpZWxkcy5nZXQoInpvbmUiLCBudWxsKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0NvbGxlY3Rpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvQ29sbGVjdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFiNWNmZjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0NvbGxlY3Rpb24uamF2YQpAQCAtMCwwICsxLDMxNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKKworLyoqCisgKiB7QGNvZGUgQ29sbGVjdGlvbn0gaXMgdGhlIHJvb3Qgb2YgdGhlIGNvbGxlY3Rpb24gaGllcmFyY2h5LiBJdCBkZWZpbmVzIG9wZXJhdGlvbnMgb24KKyAqIGRhdGEgY29sbGVjdGlvbnMgYW5kIHRoZSBiZWhhdmlvciB0aGF0IHRoZXkgd2lsbCBoYXZlIGluIGFsbCBpbXBsZW1lbnRhdGlvbnMKKyAqIG9mIHtAY29kZSBDb2xsZWN0aW9ufXMuCisgKgorICogQWxsIGRpcmVjdCBvciBpbmRpcmVjdCBpbXBsZW1lbnRhdGlvbnMgb2Yge0Bjb2RlIENvbGxlY3Rpb259IHNob3VsZCBpbXBsZW1lbnQgYXQKKyAqIGxlYXN0IHR3byBjb25zdHJ1Y3RvcnMuIE9uZSB3aXRoIG5vIHBhcmFtZXRlcnMgd2hpY2ggY3JlYXRlcyBhbiBlbXB0eQorICogY29sbGVjdGlvbiBhbmQgb25lIHdpdGggYSBwYXJhbWV0ZXIgb2YgdHlwZSB7QGNvZGUgQ29sbGVjdGlvbn0uIFRoaXMgc2Vjb25kCisgKiBjb25zdHJ1Y3RvciBjYW4gYmUgdXNlZCB0byBjcmVhdGUgYSBjb2xsZWN0aW9uIG9mIGRpZmZlcmVudCB0eXBlIGFzIHRoZQorICogaW5pdGlhbCBjb2xsZWN0aW9uIGJ1dCB3aXRoIHRoZSBzYW1lIGVsZW1lbnRzLiBJbXBsZW1lbnRhdGlvbnMgb2Yge0Bjb2RlIENvbGxlY3Rpb259CisgKiBjYW5ub3QgYmUgZm9yY2VkIHRvIGltcGxlbWVudCB0aGVzZSB0d28gY29uc3RydWN0b3JzIGJ1dCBhdCBsZWFzdCBhbGwKKyAqIGltcGxlbWVudGF0aW9ucyB1bmRlciB7QGNvZGUgamF2YS51dGlsfSBkby4KKyAqCisgKiBNZXRob2RzIHRoYXQgY2hhbmdlIHRoZSBjb250ZW50IG9mIGEgY29sbGVjdGlvbiB0aHJvdyBhbgorICoge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufSBpZiB0aGUgdW5kZXJseWluZyBjb2xsZWN0aW9uIGRvZXMgbm90CisgKiBzdXBwb3J0IHRoYXQgb3BlcmF0aW9uLCB0aG91Z2ggaXQncyBub3QgbWFuZGF0b3J5IHRvIHRocm93IHN1Y2ggYW4ge0Bjb2RlIEV4Y2VwdGlvbn0KKyAqIGluIGNhc2VzIHdoZXJlIHRoZSByZXF1ZXN0ZWQgb3BlcmF0aW9uIHdvdWxkIG5vdCBjaGFuZ2UgdGhlIGNvbGxlY3Rpb24uIEluCisgKiB0aGVzZSBjYXNlcyBpdCdzIHVwIHRvIHRoZSBpbXBsZW1lbnRhdGlvbiB3aGV0aGVyIGl0IHRocm93cyBhbgorICoge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufSBvciBub3QuCisgKgorICogTWV0aG9kcyBtYXJrZWQgd2l0aCAob3B0aW9uYWwpIGNhbiB0aHJvdyBhbgorICoge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufSBpZiB0aGUgdW5kZXJseWluZyBjb2xsZWN0aW9uIGRvZXNuJ3QKKyAqIHN1cHBvcnQgdGhhdCBtZXRob2QuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQ29sbGVjdGlvbjxFPiBleHRlbmRzIEl0ZXJhYmxlPEU+IHsKKworICAgIC8qKgorICAgICAqIEF0dGVtcHRzIHRvIGFkZCB7QGNvZGUgb2JqZWN0fSB0byB0aGUgY29udGVudHMgb2YgdGhpcworICAgICAqIHtAY29kZSBDb2xsZWN0aW9ufSAob3B0aW9uYWwpLgorICAgICAqCisgICAgICogQWZ0ZXIgdGhpcyBtZXRob2QgZmluaXNoZXMgc3VjY2Vzc2Z1bGx5IGl0IGlzIGd1YXJhbnRlZWQgdGhhdCB0aGUgb2JqZWN0CisgICAgICogaXMgY29udGFpbmVkIGluIHRoZSBjb2xsZWN0aW9uLgorICAgICAqCisgICAgICogSWYgdGhlIGNvbGxlY3Rpb24gd2FzIG1vZGlmaWVkIGl0IHJldHVybnMge0Bjb2RlIHRydWV9LCB7QGNvZGUgZmFsc2V9IGlmCisgICAgICogbm8gY2hhbmdlcyB3ZXJlIG1hZGUuCisgICAgICoKKyAgICAgKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiB7QGNvZGUgQ29sbGVjdGlvbn0gbWF5IG5hcnJvdyB0aGUgc2V0IG9mIGFjY2VwdGVkCisgICAgICogb2JqZWN0cywgYnV0IGl0IGhhcyB0byBzcGVjaWZ5IHRoaXMgaW4gdGhlIGRvY3VtZW50YXRpb24uIElmIHRoZSBvYmplY3QKKyAgICAgKiB0byBiZSBhZGRlZCBkb2VzIG5vdCBtZWV0IHRoaXMgcmVzdHJpY3Rpb24sIHRoZW4gYW4KKyAgICAgKiB7QGNvZGUgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufSBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBJZiBhIGNvbGxlY3Rpb24gZG9lcyBub3QgeWV0IGNvbnRhaW4gYW4gb2JqZWN0IHRoYXQgaXMgdG8gYmUgYWRkZWQgYW5kCisgICAgICogYWRkaW5nIHRoZSBvYmplY3QgZmFpbHMsIHRoaXMgbWV0aG9kIDxpPm11c3Q8L2k+IHRocm93IGFuIGFwcHJvcHJpYXRlCisgICAgICogdW5jaGVja2VkIEV4Y2VwdGlvbi4gUmV0dXJuaW5nIGZhbHNlIGlzIG5vdCBwZXJtaXR0ZWQgaW4gdGhpcyBjYXNlCisgICAgICogYmVjYXVzZSBpdCB3b3VsZCB2aW9sYXRlIHRoZSBwb3N0Y29uZGl0aW9uIHRoYXQgdGhlIGVsZW1lbnQgd2lsbCBiZSBwYXJ0CisgICAgICogb2YgdGhlIGNvbGxlY3Rpb24gYWZ0ZXIgdGhpcyBtZXRob2QgZmluaXNoZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFkZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSBpcworICAgICAqICAgICAgICAgbW9kaWZpZWQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGFkZGluZyB0byB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIHRoZSBvYmplY3QgaXMgaW5hcHByb3ByaWF0ZSBmb3IgdGhpcworICAgICAqICAgICAgICAgICAgICAgIGNvbGxlY3Rpb24uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgb2JqZWN0IGNhbm5vdCBiZSBhZGRlZCB0byB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbnVsbCBlbGVtZW50cyBjYW5ub3QgYmUgYWRkZWQgdG8gdGhlIHtAY29kZSBDb2xsZWN0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBhZGQoRSBvYmplY3QpOworCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gYWRkIGFsbCBvZiB0aGUgb2JqZWN0cyBjb250YWluZWQgaW4ge0Bjb2RlIENvbGxlY3Rpb259CisgICAgICogdG8gdGhlIGNvbnRlbnRzIG9mIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IChvcHRpb25hbCkuIElmIHRoZSBwYXNzZWQge0Bjb2RlIENvbGxlY3Rpb259CisgICAgICogaXMgY2hhbmdlZCBkdXJpbmcgdGhlIHByb2Nlc3Mgb2YgYWRkaW5nIGVsZW1lbnRzIHRvIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259LCB0aGUKKyAgICAgKiBiZWhhdmlvciBpcyBub3QgZGVmaW5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2xsZWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIENvbGxlY3Rpb259IG9mIG9iamVjdHMuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gaXMgbW9kaWZpZWQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYWRkaW5nIHRvIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgY2xhc3Mgb2YgYW4gb2JqZWN0IGlzIGluYXBwcm9wcmlhdGUgZm9yIHRoaXMKKyAgICAgKiAgICAgICAgICAgICAgICB7QGNvZGUgQ29sbGVjdGlvbn0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBhbiBvYmplY3QgY2Fubm90IGJlIGFkZGVkIHRvIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgY29sbGVjdGlvbn0gaXMge0Bjb2RlIG51bGx9LCBvciBpZiBpdAorICAgICAqICAgICAgICAgICAgICAgIGNvbnRhaW5zIHtAY29kZSBudWxsfSBlbGVtZW50cyBhbmQgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gZG9lcworICAgICAqICAgICAgICAgICAgICAgIG5vdCBzdXBwb3J0IHN1Y2ggZWxlbWVudHMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYWRkQWxsKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGNvbGxlY3Rpb24pOworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhbGwgZWxlbWVudHMgZnJvbSB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSwgbGVhdmluZyBpdCBlbXB0eSAob3B0aW9uYWwpLgorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHJlbW92aW5nIGZyb20gdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKgorICAgICAqIEBzZWUgI2lzRW1wdHkKKyAgICAgKiBAc2VlICNzaXplCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXIoKTsKKworICAgIC8qKgorICAgICAqIFRlc3RzIHdoZXRoZXIgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gY29udGFpbnMgdGhlIHNwZWNpZmllZCBvYmplY3QuIFJldHVybnMKKyAgICAgKiB7QGNvZGUgdHJ1ZX0gaWYgYW5kIG9ubHkgaWYgYXQgbGVhc3Qgb25lIGVsZW1lbnQge0Bjb2RlIGVsZW19IGluIHRoaXMKKyAgICAgKiB7QGNvZGUgQ29sbGVjdGlvbn0gbWVldHMgZm9sbG93aW5nIHJlcXVpcmVtZW50OgorICAgICAqIHtAY29kZSAob2JqZWN0PT1udWxsID8gZWxlbT09bnVsbCA6IG9iamVjdC5lcXVhbHMoZWxlbSkpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gc2VhcmNoIGZvci4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBvYmplY3QgaXMgYW4gZWxlbWVudCBvZiB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIG9iamVjdCB0byBsb29rIGZvciBpc24ndCBvZiB0aGUgY29ycmVjdAorICAgICAqICAgICAgICAgICAgICAgIHR5cGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSBvYmplY3QgdG8gbG9vayBmb3IgaXMge0Bjb2RlIG51bGx9IGFuZCB0aGlzCisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIENvbGxlY3Rpb259IGRvZXNuJ3Qgc3VwcG9ydCB7QGNvZGUgbnVsbH0gZWxlbWVudHMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG9iamVjdCk7CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB3aGV0aGVyIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IGNvbnRhaW5zIGFsbCBvYmplY3RzIGNvbnRhaW5lZCBpbiB0aGUKKyAgICAgKiBzcGVjaWZpZWQge0Bjb2RlIENvbGxlY3Rpb259LiBJZiBhbiBlbGVtZW50IHtAY29kZSBlbGVtfSBpcyBjb250YWluZWQgc2V2ZXJhbAorICAgICAqIHRpbWVzIGluIHRoZSBzcGVjaWZpZWQge0Bjb2RlIENvbGxlY3Rpb259LCB0aGUgbWV0aG9kIHJldHVybnMge0Bjb2RlIHRydWV9IGV2ZW4KKyAgICAgKiBpZiB7QGNvZGUgZWxlbX0gaXMgY29udGFpbmVkIG9ubHkgb25jZSBpbiB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2xsZWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgY29sbGVjdGlvbiBvZiBvYmplY3RzLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGFsbCBvYmplY3RzIGluIHRoZSBzcGVjaWZpZWQge0Bjb2RlIENvbGxlY3Rpb259IGFyZQorICAgICAqICAgICAgICAgZWxlbWVudHMgb2YgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0sIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgb25lIG9yIG1vcmUgZWxlbWVudHMgb2Yge0Bjb2RlIGNvbGxlY3Rpb259IGlzbid0IG9mIHRoZQorICAgICAqICAgICAgICAgICAgICAgIGNvcnJlY3QgdHlwZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGNvbGxlY3Rpb259IGNvbnRhaW5zIGF0IGxlYXN0IG9uZSB7QGNvZGUgbnVsbH0KKyAgICAgKiAgICAgICAgICAgICAgICBlbGVtZW50IGFuZCB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSBkb2Vzbid0IHN1cHBvcnQge0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICAgICAgICAgZWxlbWVudHMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBjb2xsZWN0aW9ufSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNBbGwoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKTsKKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBhcmd1bWVudCB0byB0aGUgcmVjZWl2ZXIsIGFuZCByZXR1cm5zIHRydWUgaWYgdGhleSByZXByZXNlbnQKKyAgICAgKiB0aGUgPGVtPnNhbWU8L2VtPiBvYmplY3QgdXNpbmcgYSBjbGFzcyBzcGVjaWZpYyBjb21wYXJpc29uLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHdpdGggdGhpcyBvYmplY3QuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIG9iamVjdCBpcyB0aGUgc2FtZSBhcyB0aGlzIG9iamVjdCBhbmQKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gaWYgaXQgaXMgZGlmZmVyZW50IGZyb20gdGhpcyBvYmplY3QuCisgICAgICogQHNlZSAjaGFzaENvZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGludGVnZXIgaGFzaCBjb2RlIGZvciB0aGUgcmVjZWl2ZXIuIE9iamVjdHMgd2hpY2ggYXJlIGVxdWFsCisgICAgICogcmV0dXJuIHRoZSBzYW1lIHZhbHVlIGZvciB0aGlzIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgaGFzaC4KKyAgICAgKgorICAgICAqIEBzZWUgI2VxdWFscworICAgICAqLworICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgaWYgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gY29udGFpbnMgbm8gZWxlbWVudHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSBoYXMgbm8gZWxlbWVudHMsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKgorICAgICAqIEBzZWUgI3NpemUKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIHtAbGluayBJdGVyYXRvcn0gdGhhdCBtYXkgYmUgdXNlZCB0byBhY2Nlc3MgdGhlCisgICAgICogb2JqZWN0cyBjb250YWluZWQgYnkgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0uIFRoZSBvcmRlciBpbiB3aGljaCB0aGUgZWxlbWVudHMgYXJlCisgICAgICogcmV0dXJuZWQgYnkgdGhlIGl0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLiBPbmx5IGlmIHRoZSBpbnN0YW5jZSBvZiB0aGUKKyAgICAgKiB7QGNvZGUgQ29sbGVjdGlvbn0gaGFzIGEgZGVmaW5lZCBvcmRlciB0aGUgZWxlbWVudHMgYXJlIHJldHVybmVkIGluIHRoYXQgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGl0ZXJhdG9yIGZvciBhY2Nlc3NpbmcgdGhlIHtAY29kZSBDb2xsZWN0aW9ufSBjb250ZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3I8RT4gaXRlcmF0b3IoKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgb25lIGluc3RhbmNlIG9mIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGZyb20gdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gaWYgb25lCisgICAgICogaXMgY29udGFpbmVkIChvcHRpb25hbCkuIFRoZSBlbGVtZW50IHtAY29kZSBlbGVtfSB0aGF0IGlzIHJlbW92ZWQKKyAgICAgKiBjb21wbGllcyB3aXRoIHtAY29kZSAob2JqZWN0PT1udWxsID8gZWxlbT09bnVsbCA6IG9iamVjdC5lcXVhbHMoZWxlbSl9LgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byByZW1vdmUuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gaXMgbW9kaWZpZWQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcmVtb3ZpbmcgZnJvbSB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBwYXNzZWQgaXMgbm90IG9mIHRoZSBjb3JyZWN0IHR5cGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBvYmplY3R9IGlzIHtAY29kZSBudWxsfSBhbmQgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0KKyAgICAgKiAgICAgICAgICAgICAgICBkb2Vzbid0IHN1cHBvcnQge0Bjb2RlIG51bGx9IGVsZW1lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3Qgb2JqZWN0KTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIG9jY3VycmVuY2VzIGluIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IG9mIGVhY2ggb2JqZWN0IGluIHRoZQorICAgICAqIHNwZWNpZmllZCB7QGNvZGUgQ29sbGVjdGlvbn0gKG9wdGlvbmFsKS4gQWZ0ZXIgdGhpcyBtZXRob2QgcmV0dXJucyBub25lIG9mIHRoZQorICAgICAqIGVsZW1lbnRzIGluIHRoZSBwYXNzZWQge0Bjb2RlIENvbGxlY3Rpb259IGNhbiBiZSBmb3VuZCBpbiB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufQorICAgICAqIGFueW1vcmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cyB0byByZW1vdmUuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gaXMgbW9kaWZpZWQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiByZW1vdmluZyBmcm9tIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBvbmUgb3IgbW9yZSBlbGVtZW50cyBvZiB7QGNvZGUgY29sbGVjdGlvbn0KKyAgICAgKiAgICAgICAgICAgICAgICBpc24ndCBvZiB0aGUgY29ycmVjdCB0eXBlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgY29sbGVjdGlvbn0gY29udGFpbnMgYXQgbGVhc3Qgb25lCisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIG51bGx9IGVsZW1lbnQgYW5kIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259IGRvZXNuJ3Qgc3VwcG9ydAorICAgICAqICAgICAgICAgICAgICAgIHtAY29kZSBudWxsfSBlbGVtZW50cy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGNvbGxlY3Rpb259IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmVBbGwoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIG9iamVjdHMgZnJvbSB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSB0aGF0IGFyZSBub3QgYWxzbyBmb3VuZCBpbiB0aGUKKyAgICAgKiB7QGNvZGUgQ29sbGVjdGlvbn0gcGFzc2VkIChvcHRpb25hbCkuIEFmdGVyIHRoaXMgbWV0aG9kIHJldHVybnMgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0KKyAgICAgKiB3aWxsIG9ubHkgY29udGFpbiBlbGVtZW50cyB0aGF0IGFsc28gY2FuIGJlIGZvdW5kIGluIHRoZSB7QGNvZGUgQ29sbGVjdGlvbn0KKyAgICAgKiBwYXNzZWQgdG8gdGhpcyBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cyB0byByZXRhaW4uCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0gaXMgbW9kaWZpZWQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcmVtb3ZpbmcgZnJvbSB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgb25lIG9yIG1vcmUgZWxlbWVudHMgb2Yge0Bjb2RlIGNvbGxlY3Rpb259CisgICAgICogICAgICAgICAgICAgICAgaXNuJ3Qgb2YgdGhlIGNvcnJlY3QgdHlwZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGNvbGxlY3Rpb259IGNvbnRhaW5zIGF0IGxlYXN0IG9uZQorICAgICAqICAgICAgICAgICAgICAgIHtAY29kZSBudWxsfSBlbGVtZW50IGFuZCB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSBkb2Vzbid0IHN1cHBvcnQKKyAgICAgKiAgICAgICAgICAgICAgICB7QGNvZGUgbnVsbH0gZWxlbWVudHMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBjb2xsZWN0aW9ufSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmV0YWluQWxsKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY291bnQgb2YgaG93IG1hbnkgb2JqZWN0cyB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSBjb250YWlucy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gaG93IG1hbnkgb2JqZWN0cyB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSBjb250YWlucywgb3IgSW50ZWdlci5NQVhfVkFMVUUKKyAgICAgKiAgICAgICAgIGlmIHRoZXJlIGFyZSBtb3JlIHRoYW4gSW50ZWdlci5NQVhfVkFMVUUgZWxlbWVudHMgaW4gdGhpcworICAgICAqICAgICAgICAge0Bjb2RlIENvbGxlY3Rpb259LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2l6ZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBhcnJheSBjb250YWluaW5nIGFsbCBlbGVtZW50cyBjb250YWluZWQgaW4gdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0uCisgICAgICoKKyAgICAgKiBJZiB0aGUgaW1wbGVtZW50YXRpb24gaGFzIG9yZGVyZWQgZWxlbWVudHMgaXQgd2lsbCByZXR1cm4gdGhlIGVsZW1lbnQKKyAgICAgKiBhcnJheSBpbiB0aGUgc2FtZSBvcmRlciBhcyBhbiBpdGVyYXRvciB3b3VsZCByZXR1cm4gdGhlbS4KKyAgICAgKgorICAgICAqIFRoZSBhcnJheSByZXR1cm5lZCBkb2VzIG5vdCByZWZsZWN0IGFueSBjaGFuZ2VzIG9mIHRoZSB7QGNvZGUgQ29sbGVjdGlvbn0uIEEgbmV3CisgICAgICogYXJyYXkgaXMgY3JlYXRlZCBldmVuIGlmIHRoZSB1bmRlcmx5aW5nIGRhdGEgc3RydWN0dXJlIGlzIGFscmVhZHkgYW4KKyAgICAgKiBhcnJheS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgdGhlIGVsZW1lbnRzIGZyb20gdGhpcyB7QGNvZGUgQ29sbGVjdGlvbn0uCisgICAgICovCisgICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgZWxlbWVudHMgY29udGFpbmVkIGluIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259LiBJZgorICAgICAqIHRoZSBzcGVjaWZpZWQgYXJyYXkgaXMgbGFyZ2UgZW5vdWdoIHRvIGhvbGQgdGhlIGVsZW1lbnRzLCB0aGUgc3BlY2lmaWVkCisgICAgICogYXJyYXkgaXMgdXNlZCwgb3RoZXJ3aXNlIGFuIGFycmF5IG9mIHRoZSBzYW1lIHR5cGUgaXMgY3JlYXRlZC4gSWYgdGhlCisgICAgICogc3BlY2lmaWVkIGFycmF5IGlzIHVzZWQgYW5kIGlzIGxhcmdlciB0aGFuIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259LCB0aGUgYXJyYXkKKyAgICAgKiBlbGVtZW50IGZvbGxvd2luZyB0aGUge0Bjb2RlIENvbGxlY3Rpb259IGVsZW1lbnRzIGlzIHNldCB0byBudWxsLgorICAgICAqCisgICAgICogSWYgdGhlIGltcGxlbWVudGF0aW9uIGhhcyBvcmRlcmVkIGVsZW1lbnRzIGl0IHdpbGwgcmV0dXJuIHRoZSBlbGVtZW50CisgICAgICogYXJyYXkgaW4gdGhlIHNhbWUgb3JkZXIgYXMgYW4gaXRlcmF0b3Igd291bGQgcmV0dXJuIHRoZW0uCisgICAgICoKKyAgICAgKiB7QGNvZGUgdG9BcnJheShuZXcgT2JqZWN0WzBdKX0gYmVoYXZlcyBleGFjdGx5IHRoZSBzYW1lIHdheSBhcworICAgICAqIHtAY29kZSB0b0FycmF5KCl9IGRvZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheS4KKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIHRoZSBlbGVtZW50cyBmcm9tIHRoaXMge0Bjb2RlIENvbGxlY3Rpb259LgorICAgICAqCisgICAgICogQHRocm93cyBBcnJheVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHR5cGUgb2YgYW4gZWxlbWVudCBpbiB0aGlzIHtAY29kZSBDb2xsZWN0aW9ufSBjYW5ub3QgYmUKKyAgICAgKiAgICAgICAgICAgICAgICBzdG9yZWQgaW4gdGhlIHR5cGUgb2YgdGhlIHNwZWNpZmllZCBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgPFQ+IFRbXSB0b0FycmF5KFRbXSBhcnJheSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0NvbGxlY3Rpb25zLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0NvbGxlY3Rpb25zLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjY3MjliNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvQ29sbGVjdGlvbnMuamF2YQpAQCAtMCwwICsxLDMzOTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0U3RyZWFtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkFycmF5OworCisvKioKKyAqIHtAY29kZSBDb2xsZWN0aW9uc30gY29udGFpbnMgc3RhdGljIG1ldGhvZHMgd2hpY2ggb3BlcmF0ZSBvbgorICoge0Bjb2RlIENvbGxlY3Rpb259IGNsYXNzZXMuCisgKgorICogQHNpbmNlIDEuMgorICovCitwdWJsaWMgY2xhc3MgQ29sbGVjdGlvbnMgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSXRlcmF0b3I8Pz4gRU1QVFlfSVRFUkFUT1IgPSBuZXcgSXRlcmF0b3I8T2JqZWN0PigpIHsKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIE9iamVjdCBuZXh0KCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRW51bWVyYXRpb248Pz4gRU1QVFlfRU5VTUVSQVRJT04gPSBuZXcgRW51bWVyYXRpb248T2JqZWN0PigpIHsKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc01vcmVFbGVtZW50cygpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgT2JqZWN0IG5leHRFbGVtZW50KCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBDb3BpZXNMaXN0PEU+IGV4dGVuZHMgQWJzdHJhY3RMaXN0PEU+IGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjczOTA5OTI2ODM5ODcxMTgwMEw7CisgICAgICAgIHByaXZhdGUgZmluYWwgaW50IG47CisgICAgICAgIHByaXZhdGUgZmluYWwgRSBlbGVtZW50OworCisgICAgICAgIENvcGllc0xpc3QoaW50IGxlbmd0aCwgRSBvYmplY3QpIHsKKyAgICAgICAgICAgIGlmIChsZW5ndGggPCAwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbiA9IGxlbmd0aDsKKyAgICAgICAgICAgIGVsZW1lbnQgPSBvYmplY3Q7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQgPT0gbnVsbCA/IG9iamVjdCA9PSBudWxsIDogZWxlbWVudC5lcXVhbHMob2JqZWN0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gbjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgRSBnZXQoaW50IGxvY2F0aW9uKSB7CisgICAgICAgICAgICBpZiAobG9jYXRpb24gPj0gMCAmJiBsb2NhdGlvbiA8IG4pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBFbXB0eUxpc3QgZXh0ZW5kcyBBYnN0cmFjdExpc3QKKyAgICAgICAgICAgIGltcGxlbWVudHMgUmFuZG9tQWNjZXNzLCBTZXJpYWxpemFibGUgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA4ODQyODQzOTMxMjIxMTM5MTY2TDsKKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0KGludCBsb2NhdGlvbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgT2JqZWN0IHJlYWRSZXNvbHZlKCkgeworICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLkVNUFRZX0xJU1Q7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBFbXB0eVNldCBleHRlbmRzIEFic3RyYWN0U2V0IGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTU4MjI5NjMxNTk5MDM2MjkyMEw7CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgSXRlcmF0b3IgaXRlcmF0b3IoKSB7CisgICAgICAgICAgICByZXR1cm4gRU1QVFlfSVRFUkFUT1I7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIE9iamVjdCByZWFkUmVzb2x2ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5FTVBUWV9TRVQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBFbXB0eU1hcCBleHRlbmRzIEFic3RyYWN0TWFwIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjQyODM0ODA4MTEwNTU5NDMyMEw7CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrZXkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ZhbHVlKE9iamVjdCB2YWx1ZSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTZXQgZW50cnlTZXQoKSB7CisgICAgICAgICAgICByZXR1cm4gRU1QVFlfU0VUOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0KE9iamVjdCBrZXkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTZXQga2V5U2V0KCkgeworICAgICAgICAgICAgcmV0dXJuIEVNUFRZX1NFVDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgQ29sbGVjdGlvbiB2YWx1ZXMoKSB7CisgICAgICAgICAgICByZXR1cm4gRU1QVFlfTElTVDsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgT2JqZWN0IHJlYWRSZXNvbHZlKCkgeworICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLkVNUFRZX01BUDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFuIGVtcHR5IGltbXV0YWJsZSBpbnN0YW5jZSBvZiB7QGxpbmsgTGlzdH0uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBMaXN0IEVNUFRZX0xJU1QgPSBuZXcgRW1wdHlMaXN0KCk7CisKKyAgICAvKioKKyAgICAgKiBBbiBlbXB0eSBpbW11dGFibGUgaW5zdGFuY2Ugb2Yge0BsaW5rIFNldH0uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTZXQgRU1QVFlfU0VUID0gbmV3IEVtcHR5U2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBBbiBlbXB0eSBpbW11dGFibGUgaW5zdGFuY2Ugb2Yge0BsaW5rIE1hcH0uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXAgRU1QVFlfTUFQID0gbmV3IEVtcHR5TWFwKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNsYXNzIGlzIGEgc2luZ2xldG9uIHNvIHRoYXQgZXF1YWxzKCkgYW5kIGhhc2hDb2RlKCkgd29yayBwcm9wZXJseS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBSZXZlcnNlQ29tcGFyYXRvcjxUPiBpbXBsZW1lbnRzIENvbXBhcmF0b3I8VD4sIFNlcmlhbGl6YWJsZSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFJldmVyc2VDb21wYXJhdG9yPE9iamVjdD4gSU5TVEFOQ0UgPSBuZXcgUmV2ZXJzZUNvbXBhcmF0b3I8T2JqZWN0PigpOworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDcyMDcwMzgwNjg0OTQwNjAyNDBMOworCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBjb21wYXJlKFQgbzEsIFQgbzIpIHsKKyAgICAgICAgICAgIENvbXBhcmFibGU8VD4gYzIgPSAoQ29tcGFyYWJsZTxUPikgbzI7CisgICAgICAgICAgICByZXR1cm4gYzIuY29tcGFyZVRvKG8xKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgT2JqZWN0IHJlYWRSZXNvbHZlKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gSU5TVEFOQ0U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBSZXZlcnNlQ29tcGFyYXRvcjI8VD4gaW1wbGVtZW50cyBDb21wYXJhdG9yPFQ+LCBTZXJpYWxpemFibGUgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0Mzc0MDkyMTM5ODU3TDsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBDb21wYXJhdG9yPFQ+IGNtcDsKKworICAgICAgICBSZXZlcnNlQ29tcGFyYXRvcjIoQ29tcGFyYXRvcjxUPiBjb21wYXJhdG9yKSB7CisgICAgICAgICAgICB0aGlzLmNtcCA9IGNvbXBhcmF0b3I7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBjb21wYXJlKFQgbzEsIFQgbzIpIHsKKyAgICAgICAgICAgIHJldHVybiBjbXAuY29tcGFyZShvMiwgbzEpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICAgICAgcmV0dXJuIG8gaW5zdGFuY2VvZiBSZXZlcnNlQ29tcGFyYXRvcjIKKyAgICAgICAgICAgICAgICAgICAgJiYgKChSZXZlcnNlQ29tcGFyYXRvcjIpIG8pLmNtcC5lcXVhbHMoY21wKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgcmV0dXJuIH5jbXAuaGFzaENvZGUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFNpbmdsZXRvblNldDxFPiBleHRlbmRzIEFic3RyYWN0U2V0PEU+IGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzE5MzY4NzIwNzU1MDQzMTY3OUw7CisgICAgICAgIGZpbmFsIEUgZWxlbWVudDsKKworICAgICAgICBTaW5nbGV0b25TZXQoRSBvYmplY3QpIHsKKyAgICAgICAgICAgIGVsZW1lbnQgPSBvYmplY3Q7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQgPT0gbnVsbCA/IG9iamVjdCA9PSBudWxsIDogZWxlbWVudC5lcXVhbHMob2JqZWN0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgSXRlcmF0b3I8RT4gaXRlcmF0b3IoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yPEU+KCkgeworICAgICAgICAgICAgICAgIGJvb2xlYW4gaGFzTmV4dCA9IHRydWU7CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhhc05leHQ7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBFIG5leHQoKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChoYXNOZXh0KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBoYXNOZXh0ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTaW5nbGV0b25MaXN0PEU+IGV4dGVuZHMgQWJzdHJhY3RMaXN0PEU+IGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzA5MzczNjYxODc0MDY1Mjk1MUw7CisKKyAgICAgICAgZmluYWwgRSBlbGVtZW50OworCisgICAgICAgIFNpbmdsZXRvbkxpc3QoRSBvYmplY3QpIHsKKyAgICAgICAgICAgIGVsZW1lbnQgPSBvYmplY3Q7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQgPT0gbnVsbCA/IG9iamVjdCA9PSBudWxsIDogZWxlbWVudC5lcXVhbHMob2JqZWN0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgRSBnZXQoaW50IGxvY2F0aW9uKSB7CisgICAgICAgICAgICBpZiAobG9jYXRpb24gPT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50OworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFNpbmdsZXRvbk1hcDxLLCBWPiBleHRlbmRzIEFic3RyYWN0TWFwPEssIFY+CisgICAgICAgICAgICBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC02OTc5NzI0NDc3MjE1MDUyOTExTDsKKworICAgICAgICBmaW5hbCBLIGs7CisgICAgICAgIGZpbmFsIFYgdjsKKworICAgICAgICBTaW5nbGV0b25NYXAoSyBrZXksIFYgdmFsdWUpIHsKKyAgICAgICAgICAgIGsgPSBrZXk7CisgICAgICAgICAgICB2ID0gdmFsdWU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnNLZXkoT2JqZWN0IGtleSkgeworICAgICAgICAgICAgcmV0dXJuIGsgPT0gbnVsbCA/IGtleSA9PSBudWxsIDogay5lcXVhbHMoa2V5KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ZhbHVlKE9iamVjdCB2YWx1ZSkgeworICAgICAgICAgICAgcmV0dXJuIHYgPT0gbnVsbCA/IHZhbHVlID09IG51bGwgOiB2LmVxdWFscyh2YWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFYgZ2V0KE9iamVjdCBrZXkpIHsKKyAgICAgICAgICAgIGlmIChjb250YWluc0tleShrZXkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHY7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU2V0PE1hcC5FbnRyeTxLLCBWPj4gZW50cnlTZXQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEFic3RyYWN0U2V0PE1hcC5FbnRyeTxLLCBWPj4oKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIE1hcC5FbnRyeSkgeworICAgICAgICAgICAgICAgICAgICAgICAgTWFwLkVudHJ5PD8sID8+IGVudHJ5ID0gKE1hcC5FbnRyeTw/LCA/Pikgb2JqZWN0OworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRhaW5zS2V5KGVudHJ5LmdldEtleSgpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBjb250YWluc1ZhbHVlKGVudHJ5LmdldFZhbHVlKCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEl0ZXJhdG9yPE1hcC5FbnRyeTxLLCBWPj4gaXRlcmF0b3IoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSXRlcmF0b3I8TWFwLkVudHJ5PEssIFY+PigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaGFzTmV4dCA9IHRydWU7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBoYXNOZXh0OworICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIE1hcC5FbnRyeTxLLCBWPiBuZXh0KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaGFzTmV4dCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc05leHQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1hcEVudHJ5PEssIFY+KGssIHYpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBWIHNldFZhbHVlKFYgdmFsdWUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9OworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFN5bmNocm9uaXplZENvbGxlY3Rpb248RT4gaW1wbGVtZW50cyBDb2xsZWN0aW9uPEU+LCBTZXJpYWxpemFibGUgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzMDUzOTk1MDMyMDkxMzM1MDkzTDsKKyAgICAgICAgZmluYWwgQ29sbGVjdGlvbjxFPiBjOworICAgICAgICBmaW5hbCBPYmplY3QgbXV0ZXg7CisKKyAgICAgICAgU3luY2hyb25pemVkQ29sbGVjdGlvbihDb2xsZWN0aW9uPEU+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIGMgPSBjb2xsZWN0aW9uOworICAgICAgICAgICAgbXV0ZXggPSB0aGlzOworICAgICAgICB9CisKKyAgICAgICAgU3luY2hyb25pemVkQ29sbGVjdGlvbihDb2xsZWN0aW9uPEU+IGNvbGxlY3Rpb24sIE9iamVjdCBtdXRleCkgeworICAgICAgICAgICAgYyA9IGNvbGxlY3Rpb247CisgICAgICAgICAgICB0aGlzLm11dGV4ID0gbXV0ZXg7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gYWRkKEUgb2JqZWN0KSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGMuYWRkKG9iamVjdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gYWRkQWxsKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYy5hZGRBbGwoY29sbGVjdGlvbik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgYy5jbGVhcigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYy5jb250YWlucyhvYmplY3QpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQWxsKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbikgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjLmNvbnRhaW5zQWxsKGNvbGxlY3Rpb24pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGMuaXNFbXB0eSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBJdGVyYXRvcjxFPiBpdGVyYXRvcigpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYy5pdGVyYXRvcigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGMucmVtb3ZlKG9iamVjdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gcmVtb3ZlQWxsKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbikgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjLnJlbW92ZUFsbChjb2xsZWN0aW9uKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiByZXRhaW5BbGwoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGMucmV0YWluQWxsKGNvbGxlY3Rpb24pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYy5zaXplKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGphdmEubGFuZy5PYmplY3RbXSB0b0FycmF5KCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjLnRvQXJyYXkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjLnRvU3RyaW5nKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIDxUPiBUW10gdG9BcnJheShUW10gYXJyYXkpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYy50b0FycmF5KGFycmF5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHN0cmVhbS5kZWZhdWx0V3JpdGVPYmplY3QoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBTeW5jaHJvbml6ZWRSYW5kb21BY2Nlc3NMaXN0PEU+IGV4dGVuZHMgU3luY2hyb25pemVkTGlzdDxFPgorICAgICAgICAgICAgaW1wbGVtZW50cyBSYW5kb21BY2Nlc3MgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxNTMwNjc0NTgzNjAyMzU4NDgyTDsKKworICAgICAgICBTeW5jaHJvbml6ZWRSYW5kb21BY2Nlc3NMaXN0KExpc3Q8RT4gbCkgeworICAgICAgICAgICAgc3VwZXIobCk7CisgICAgICAgIH0KKworICAgICAgICBTeW5jaHJvbml6ZWRSYW5kb21BY2Nlc3NMaXN0KExpc3Q8RT4gbCwgT2JqZWN0IG11dGV4KSB7CisgICAgICAgICAgICBzdXBlcihsLCBtdXRleCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIExpc3Q8RT4gc3ViTGlzdChpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN5bmNocm9uaXplZFJhbmRvbUFjY2Vzc0xpc3Q8RT4obGlzdC5zdWJMaXN0KHN0YXJ0LCBlbmQpLCBtdXRleCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmVwbGFjZXMgdGhpcyBTeW5jaHJvbml6ZWRSYW5kb21BY2Nlc3NMaXN0IHdpdGggYSBTeW5jaHJvbml6ZWRMaXN0IHNvCisgICAgICAgICAqIHRoYXQgSlJFcyBiZWZvcmUgMS40IGNhbiBkZXNlcmlhbGl6ZSB0aGlzIG9iamVjdCB3aXRob3V0IGFueQorICAgICAgICAgKiBwcm9ibGVtcy4gVGhpcyBpcyBuZWNlc3Nhcnkgc2luY2UgUmFuZG9tQWNjZXNzIEFQSSB3YXMgaW50cm9kdWNlZAorICAgICAgICAgKiBvbmx5IGluIDEuNC4KKyAgICAgICAgICogPHA+CisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gU3luY2hyb25pemVkTGlzdAorICAgICAgICAgKgorICAgICAgICAgKiBAc2VlIFN5bmNocm9uaXplZExpc3QjcmVhZFJlc29sdmUoKQorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBPYmplY3Qgd3JpdGVSZXBsYWNlKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBTeW5jaHJvbml6ZWRMaXN0PEU+KGxpc3QpOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFN5bmNocm9uaXplZExpc3Q8RT4gZXh0ZW5kcyBTeW5jaHJvbml6ZWRDb2xsZWN0aW9uPEU+IGltcGxlbWVudHMgTGlzdDxFPiB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03NzU0MDkwMzcyOTYyOTcxNTI0TDsKKyAgICAgICAgZmluYWwgTGlzdDxFPiBsaXN0OworCisgICAgICAgIFN5bmNocm9uaXplZExpc3QoTGlzdDxFPiBsKSB7CisgICAgICAgICAgICBzdXBlcihsKTsKKyAgICAgICAgICAgIGxpc3QgPSBsOworICAgICAgICB9CisKKyAgICAgICAgU3luY2hyb25pemVkTGlzdChMaXN0PEU+IGwsIE9iamVjdCBtdXRleCkgeworICAgICAgICAgICAgc3VwZXIobCwgbXV0ZXgpOworICAgICAgICAgICAgbGlzdCA9IGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgYWRkKGludCBsb2NhdGlvbiwgRSBvYmplY3QpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICBsaXN0LmFkZChsb2NhdGlvbiwgb2JqZWN0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBhZGRBbGwoaW50IGxvY2F0aW9uLCBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjb2xsZWN0aW9uKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGxpc3QuYWRkQWxsKGxvY2F0aW9uLCBjb2xsZWN0aW9uKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBsaXN0LmVxdWFscyhvYmplY3QpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBFIGdldChpbnQgbG9jYXRpb24pIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbGlzdC5nZXQobG9jYXRpb24pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGxpc3QuaGFzaENvZGUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGluZGV4T2YoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgZmluYWwgaW50IHNpemU7CisgICAgICAgICAgICBmaW5hbCBPYmplY3RbXSBhcnJheTsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICBzaXplID0gbGlzdC5zaXplKCk7CisgICAgICAgICAgICAgICAgYXJyYXkgPSBuZXcgT2JqZWN0W3NpemVdOworICAgICAgICAgICAgICAgIGxpc3QudG9BcnJheShhcnJheSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAob2JqZWN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBpZiAob2JqZWN0LmVxdWFscyhhcnJheVtpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBpZiAoYXJyYXlbaV0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBsYXN0SW5kZXhPZihPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgc2l6ZTsKKyAgICAgICAgICAgIGZpbmFsIE9iamVjdFtdIGFycmF5OworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHNpemUgPSBsaXN0LnNpemUoKTsKKyAgICAgICAgICAgICAgICBhcnJheSA9IG5ldyBPYmplY3Rbc2l6ZV07CisgICAgICAgICAgICAgICAgbGlzdC50b0FycmF5KGFycmF5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChvYmplY3QgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBzaXplIC0gMTsgaSA+PSAwOyBpLS0pIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG9iamVjdC5lcXVhbHMoYXJyYXlbaV0pKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHNpemUgLSAxOyBpID49IDA7IGktLSkgeworICAgICAgICAgICAgICAgICAgICBpZiAoYXJyYXlbaV0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIExpc3RJdGVyYXRvcjxFPiBsaXN0SXRlcmF0b3IoKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGxpc3QubGlzdEl0ZXJhdG9yKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIExpc3RJdGVyYXRvcjxFPiBsaXN0SXRlcmF0b3IoaW50IGxvY2F0aW9uKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGxpc3QubGlzdEl0ZXJhdG9yKGxvY2F0aW9uKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgRSByZW1vdmUoaW50IGxvY2F0aW9uKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGxpc3QucmVtb3ZlKGxvY2F0aW9uKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgRSBzZXQoaW50IGxvY2F0aW9uLCBFIG9iamVjdCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBsaXN0LnNldChsb2NhdGlvbiwgb2JqZWN0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgTGlzdDxFPiBzdWJMaXN0KGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3luY2hyb25pemVkTGlzdDxFPihsaXN0LnN1Ykxpc3Qoc3RhcnQsIGVuZCksIG11dGV4KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHN0cmVhbS5kZWZhdWx0V3JpdGVPYmplY3QoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXNvbHZlcyBTeW5jaHJvbml6ZWRMaXN0IGluc3RhbmNlcyB0byBTeW5jaHJvbml6ZWRSYW5kb21BY2Nlc3NMaXN0CisgICAgICAgICAqIGluc3RhbmNlcyBpZiB0aGUgdW5kZXJseWluZyBsaXN0IGlzIGEgUmFuZG9tIEFjY2VzcyBsaXN0LgorICAgICAgICAgKiA8cD4KKyAgICAgICAgICogVGhpcyBpcyBuZWNlc3Nhcnkgc2luY2UgU3luY2hyb25pemVkUmFuZG9tQWNjZXNzTGlzdCBpbnN0YW5jZXMgYXJlCisgICAgICAgICAqIHJlcGxhY2VkIHdpdGggU3luY2hyb25pemVkTGlzdCBpbnN0YW5jZXMgZHVyaW5nIHNlcmlhbGl6YXRpb24gZm9yCisgICAgICAgICAqIGNvbXBsaWFuY2Ugd2l0aCBKUkVzIGJlZm9yZSAxLjQuCisgICAgICAgICAqIDxwPgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIGEgU3luY2hyb25pemVkTGlzdCBpbnN0YW5jZSBpZiB0aGUgdW5kZXJseWluZyBsaXN0IGltcGxlbWVudHMKKyAgICAgICAgICogICAgICAgICBSYW5kb21BY2Nlc3MgaW50ZXJmYWNlLCBvciB0aGlzIHNhbWUgb2JqZWN0IGlmIG5vdC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNlZSBTeW5jaHJvbml6ZWRSYW5kb21BY2Nlc3NMaXN0I3dyaXRlUmVwbGFjZSgpCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIE9iamVjdCByZWFkUmVzb2x2ZSgpIHsKKyAgICAgICAgICAgIGlmIChsaXN0IGluc3RhbmNlb2YgUmFuZG9tQWNjZXNzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTeW5jaHJvbml6ZWRSYW5kb21BY2Nlc3NMaXN0PEU+KGxpc3QsIG11dGV4KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFN5bmNocm9uaXplZE1hcDxLLCBWPiBpbXBsZW1lbnRzIE1hcDxLLCBWPiwgU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTk3ODE5ODQ3OTY1OTAyMjcxNUw7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBNYXA8SywgVj4gbTsKKworICAgICAgICBmaW5hbCBPYmplY3QgbXV0ZXg7CisKKyAgICAgICAgU3luY2hyb25pemVkTWFwKE1hcDxLLCBWPiBtYXApIHsKKyAgICAgICAgICAgIG0gPSBtYXA7CisgICAgICAgICAgICBtdXRleCA9IHRoaXM7CisgICAgICAgIH0KKworICAgICAgICBTeW5jaHJvbml6ZWRNYXAoTWFwPEssIFY+IG1hcCwgT2JqZWN0IG11dGV4KSB7CisgICAgICAgICAgICBtID0gbWFwOworICAgICAgICAgICAgdGhpcy5tdXRleCA9IG11dGV4OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIG0uY2xlYXIoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBjb250YWluc0tleShPYmplY3Qga2V5KSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG0uY29udGFpbnNLZXkoa2V5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ZhbHVlKE9iamVjdCB2YWx1ZSkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBtLmNvbnRhaW5zVmFsdWUodmFsdWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTZXQ8TWFwLkVudHJ5PEssIFY+PiBlbnRyeVNldCgpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN5bmNocm9uaXplZFNldDxNYXAuRW50cnk8SywgVj4+KG0uZW50cnlTZXQoKSwgbXV0ZXgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG0uZXF1YWxzKG9iamVjdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFYgZ2V0KE9iamVjdCBrZXkpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbS5nZXQoa2V5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBtLmhhc2hDb2RlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbS5pc0VtcHR5KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFNldDxLPiBrZXlTZXQoKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTeW5jaHJvbml6ZWRTZXQ8Sz4obS5rZXlTZXQoKSwgbXV0ZXgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBWIHB1dChLIGtleSwgViB2YWx1ZSkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBtLnB1dChrZXksIHZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBwdXRBbGwoTWFwPD8gZXh0ZW5kcyBLLCA/IGV4dGVuZHMgVj4gbWFwKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgbS5wdXRBbGwobWFwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgViByZW1vdmUoT2JqZWN0IGtleSkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBtLnJlbW92ZShrZXkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbS5zaXplKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIENvbGxlY3Rpb248Vj4gdmFsdWVzKCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3luY2hyb25pemVkQ29sbGVjdGlvbjxWPihtLnZhbHVlcygpLCBtdXRleCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbS50b1N0cmluZygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgc3RyZWFtLmRlZmF1bHRXcml0ZU9iamVjdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFN5bmNocm9uaXplZFNldDxFPiBleHRlbmRzIFN5bmNocm9uaXplZENvbGxlY3Rpb248RT4gaW1wbGVtZW50cyBTZXQ8RT4geworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0ODc0NDcwMDk2ODIxODYwNDRMOworCisgICAgICAgIFN5bmNocm9uaXplZFNldChTZXQ8RT4gc2V0KSB7CisgICAgICAgICAgICBzdXBlcihzZXQpOworICAgICAgICB9CisKKyAgICAgICAgU3luY2hyb25pemVkU2V0KFNldDxFPiBzZXQsIE9iamVjdCBtdXRleCkgeworICAgICAgICAgICAgc3VwZXIoc2V0LCBtdXRleCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYy5lcXVhbHMob2JqZWN0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjLmhhc2hDb2RlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICBzdHJlYW0uZGVmYXVsdFdyaXRlT2JqZWN0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgU3luY2hyb25pemVkU29ydGVkTWFwPEssIFY+IGV4dGVuZHMgU3luY2hyb25pemVkTWFwPEssIFY+CisgICAgICAgICAgICBpbXBsZW1lbnRzIFNvcnRlZE1hcDxLLCBWPiB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04Nzk4MTQ2NzY5NDE2NDgzNzkzTDsKKworICAgICAgICBwcml2YXRlIGZpbmFsIFNvcnRlZE1hcDxLLCBWPiBzbTsKKworICAgICAgICBTeW5jaHJvbml6ZWRTb3J0ZWRNYXAoU29ydGVkTWFwPEssIFY+IG1hcCkgeworICAgICAgICAgICAgc3VwZXIobWFwKTsKKyAgICAgICAgICAgIHNtID0gbWFwOworICAgICAgICB9CisKKyAgICAgICAgU3luY2hyb25pemVkU29ydGVkTWFwKFNvcnRlZE1hcDxLLCBWPiBtYXAsIE9iamVjdCBtdXRleCkgeworICAgICAgICAgICAgc3VwZXIobWFwLCBtdXRleCk7CisgICAgICAgICAgICBzbSA9IG1hcDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgQ29tcGFyYXRvcjw/IHN1cGVyIEs+IGNvbXBhcmF0b3IoKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHNtLmNvbXBhcmF0b3IoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgSyBmaXJzdEtleSgpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc20uZmlyc3RLZXkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU29ydGVkTWFwPEssIFY+IGhlYWRNYXAoSyBlbmRLZXkpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN5bmNocm9uaXplZFNvcnRlZE1hcDxLLCBWPihzbS5oZWFkTWFwKGVuZEtleSksCisgICAgICAgICAgICAgICAgICAgICAgICBtdXRleCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEsgbGFzdEtleSgpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc20ubGFzdEtleSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTb3J0ZWRNYXA8SywgVj4gc3ViTWFwKEsgc3RhcnRLZXksIEsgZW5kS2V5KSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTeW5jaHJvbml6ZWRTb3J0ZWRNYXA8SywgVj4oc20uc3ViTWFwKHN0YXJ0S2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgZW5kS2V5KSwgbXV0ZXgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTb3J0ZWRNYXA8SywgVj4gdGFpbE1hcChLIHN0YXJ0S2V5KSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTeW5jaHJvbml6ZWRTb3J0ZWRNYXA8SywgVj4oc20udGFpbE1hcChzdGFydEtleSksCisgICAgICAgICAgICAgICAgICAgICAgICBtdXRleCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICBzdHJlYW0uZGVmYXVsdFdyaXRlT2JqZWN0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgU3luY2hyb25pemVkU29ydGVkU2V0PEU+IGV4dGVuZHMgU3luY2hyb25pemVkU2V0PEU+IGltcGxlbWVudHMgU29ydGVkU2V0PEU+IHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODY5NTgwMTMxMDg2MjEyNzQwNkw7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTb3J0ZWRTZXQ8RT4gc3M7CisKKyAgICAgICAgU3luY2hyb25pemVkU29ydGVkU2V0KFNvcnRlZFNldDxFPiBzZXQpIHsKKyAgICAgICAgICAgIHN1cGVyKHNldCk7CisgICAgICAgICAgICBzcyA9IHNldDsKKyAgICAgICAgfQorCisgICAgICAgIFN5bmNocm9uaXplZFNvcnRlZFNldChTb3J0ZWRTZXQ8RT4gc2V0LCBPYmplY3QgbXV0ZXgpIHsKKyAgICAgICAgICAgIHN1cGVyKHNldCwgbXV0ZXgpOworICAgICAgICAgICAgc3MgPSBzZXQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIENvbXBhcmF0b3I8PyBzdXBlciBFPiBjb21wYXJhdG9yKCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBzcy5jb21wYXJhdG9yKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEUgZmlyc3QoKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHNzLmZpcnN0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFNvcnRlZFNldDxFPiBoZWFkU2V0KEUgZW5kKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTeW5jaHJvbml6ZWRTb3J0ZWRTZXQ8RT4oc3MuaGVhZFNldChlbmQpLCBtdXRleCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEUgbGFzdCgpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobXV0ZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3MubGFzdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTb3J0ZWRTZXQ8RT4gc3ViU2V0KEUgc3RhcnQsIEUgZW5kKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTeW5jaHJvbml6ZWRTb3J0ZWRTZXQ8RT4oc3Muc3ViU2V0KHN0YXJ0LCBlbmQpLAorICAgICAgICAgICAgICAgICAgICAgICAgbXV0ZXgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTb3J0ZWRTZXQ8RT4gdGFpbFNldChFIHN0YXJ0KSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG11dGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTeW5jaHJvbml6ZWRTb3J0ZWRTZXQ8RT4oc3MudGFpbFNldChzdGFydCksIG11dGV4KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgc3luY2hyb25pemVkIChtdXRleCkgeworICAgICAgICAgICAgICAgIHN0cmVhbS5kZWZhdWx0V3JpdGVPYmplY3QoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFVubW9kaWZpYWJsZUNvbGxlY3Rpb248RT4gaW1wbGVtZW50cyBDb2xsZWN0aW9uPEU+LCBTZXJpYWxpemFibGUgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxODIwMDE3NzUyNTc4OTE0MDc4TDsKKworICAgICAgICBmaW5hbCBDb2xsZWN0aW9uPEU+IGM7CisKKyAgICAgICAgVW5tb2RpZmlhYmxlQ29sbGVjdGlvbihDb2xsZWN0aW9uPEU+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIGMgPSBjb2xsZWN0aW9uOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGFkZChFIG9iamVjdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gYWRkQWxsKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIGMuY29udGFpbnMob2JqZWN0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBjb250YWluc0FsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIHJldHVybiBjLmNvbnRhaW5zQWxsKGNvbGxlY3Rpb24pOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICByZXR1cm4gYy5pc0VtcHR5KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEl0ZXJhdG9yPEU+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcjxFPigpIHsKKyAgICAgICAgICAgICAgICBJdGVyYXRvcjxFPiBpdGVyYXRvciA9IGMuaXRlcmF0b3IoKTsKKworICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3IuaGFzTmV4dCgpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgRSBuZXh0KCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3IubmV4dCgpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIHJlbW92ZUFsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIHJldGFpbkFsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBjLnNpemUoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKKyAgICAgICAgICAgIHJldHVybiBjLnRvQXJyYXkoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgPFQ+IFRbXSB0b0FycmF5KFRbXSBhcnJheSkgeworICAgICAgICAgICAgcmV0dXJuIGMudG9BcnJheShhcnJheSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBjLnRvU3RyaW5nKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBVbm1vZGlmaWFibGVSYW5kb21BY2Nlc3NMaXN0PEU+IGV4dGVuZHMgVW5tb2RpZmlhYmxlTGlzdDxFPgorICAgICAgICAgICAgaW1wbGVtZW50cyBSYW5kb21BY2Nlc3MgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjU0MjMwODgzNjk2NjM4MjAwMUw7CisKKyAgICAgICAgVW5tb2RpZmlhYmxlUmFuZG9tQWNjZXNzTGlzdChMaXN0PEU+IGwpIHsKKyAgICAgICAgICAgIHN1cGVyKGwpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBMaXN0PEU+IHN1Ykxpc3QoaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFVubW9kaWZpYWJsZVJhbmRvbUFjY2Vzc0xpc3Q8RT4obGlzdC5zdWJMaXN0KHN0YXJ0LCBlbmQpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXBsYWNlcyB0aGlzIFVubW9kaWZpYWJsZVJhbmRvbUFjY2Vzc0xpc3Qgd2l0aCBhbiBVbm1vZGlmaWFibGVMaXN0CisgICAgICAgICAqIHNvIHRoYXQgSlJFcyBiZWZvcmUgMS40IGNhbiBkZXNlcmlhbGl6ZSB0aGlzIG9iamVjdCB3aXRob3V0IGFueQorICAgICAgICAgKiBwcm9ibGVtcy4gVGhpcyBpcyBuZWNlc3Nhcnkgc2luY2UgUmFuZG9tQWNjZXNzIEFQSSB3YXMgaW50cm9kdWNlZAorICAgICAgICAgKiBvbmx5IGluIDEuNC4KKyAgICAgICAgICogPHA+CisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gVW5tb2RpZmlhYmxlTGlzdAorICAgICAgICAgKgorICAgICAgICAgKiBAc2VlIFVubW9kaWZpYWJsZUxpc3QjcmVhZFJlc29sdmUoKQorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBPYmplY3Qgd3JpdGVSZXBsYWNlKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBVbm1vZGlmaWFibGVMaXN0PEU+KGxpc3QpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgVW5tb2RpZmlhYmxlTGlzdDxFPiBleHRlbmRzIFVubW9kaWZpYWJsZUNvbGxlY3Rpb248RT4KKyAgICAgICAgICAgIGltcGxlbWVudHMgTGlzdDxFPiB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yODM5NjczNTYwNjUyNDc3MjhMOworCisgICAgICAgIGZpbmFsIExpc3Q8RT4gbGlzdDsKKworICAgICAgICBVbm1vZGlmaWFibGVMaXN0KExpc3Q8RT4gbCkgeworICAgICAgICAgICAgc3VwZXIobCk7CisgICAgICAgICAgICBsaXN0ID0gbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBhZGQoaW50IGxvY2F0aW9uLCBFIG9iamVjdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gYWRkQWxsKGludCBsb2NhdGlvbiwgQ29sbGVjdGlvbjw/IGV4dGVuZHMgRT4gY29sbGVjdGlvbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIHJldHVybiBsaXN0LmVxdWFscyhvYmplY3QpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBFIGdldChpbnQgbG9jYXRpb24pIHsKKyAgICAgICAgICAgIHJldHVybiBsaXN0LmdldChsb2NhdGlvbik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBsaXN0Lmhhc2hDb2RlKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBpbmRleE9mKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIHJldHVybiBsaXN0LmluZGV4T2Yob2JqZWN0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGxhc3RJbmRleE9mKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIHJldHVybiBsaXN0Lmxhc3RJbmRleE9mKG9iamVjdCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIExpc3RJdGVyYXRvcjxFPiBsaXN0SXRlcmF0b3IoKSB7CisgICAgICAgICAgICByZXR1cm4gbGlzdEl0ZXJhdG9yKDApOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBMaXN0SXRlcmF0b3I8RT4gbGlzdEl0ZXJhdG9yKGZpbmFsIGludCBsb2NhdGlvbikgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBMaXN0SXRlcmF0b3I8RT4oKSB7CisgICAgICAgICAgICAgICAgTGlzdEl0ZXJhdG9yPEU+IGl0ZXJhdG9yID0gbGlzdC5saXN0SXRlcmF0b3IobG9jYXRpb24pOworCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGFkZChFIG9iamVjdCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yLmhhc05leHQoKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzUHJldmlvdXMoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVyYXRvci5oYXNQcmV2aW91cygpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgRSBuZXh0KCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3IubmV4dCgpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IG5leHRJbmRleCgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yLm5leHRJbmRleCgpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgRSBwcmV2aW91cygpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yLnByZXZpb3VzKCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgcHJldmlvdXNJbmRleCgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yLnByZXZpb3VzSW5kZXgoKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2V0KEUgb2JqZWN0KSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEUgcmVtb3ZlKGludCBsb2NhdGlvbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEUgc2V0KGludCBsb2NhdGlvbiwgRSBvYmplY3QpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBMaXN0PEU+IHN1Ykxpc3QoaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFVubW9kaWZpYWJsZUxpc3Q8RT4obGlzdC5zdWJMaXN0KHN0YXJ0LCBlbmQpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXNvbHZlcyBVbm1vZGlmaWFibGVMaXN0IGluc3RhbmNlcyB0byBVbm1vZGlmaWFibGVSYW5kb21BY2Nlc3NMaXN0CisgICAgICAgICAqIGluc3RhbmNlcyBpZiB0aGUgdW5kZXJseWluZyBsaXN0IGlzIGEgUmFuZG9tIEFjY2VzcyBsaXN0LgorICAgICAgICAgKiA8cD4KKyAgICAgICAgICogVGhpcyBpcyBuZWNlc3Nhcnkgc2luY2UgVW5tb2RpZmlhYmxlUmFuZG9tQWNjZXNzTGlzdCBpbnN0YW5jZXMgYXJlCisgICAgICAgICAqIHJlcGxhY2VkIHdpdGggVW5tb2RpZmlhYmxlTGlzdCBpbnN0YW5jZXMgZHVyaW5nIHNlcmlhbGl6YXRpb24gZm9yCisgICAgICAgICAqIGNvbXBsaWFuY2Ugd2l0aCBKUkVzIGJlZm9yZSAxLjQuCisgICAgICAgICAqIDxwPgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIGFuIFVubW9kaWZpYWJsZUxpc3QgaW5zdGFuY2UgaWYgdGhlIHVuZGVybHlpbmcgbGlzdAorICAgICAgICAgKiAgICAgICAgIGltcGxlbWVudHMgUmFuZG9tQWNjZXNzIGludGVyZmFjZSwgb3IgdGhpcyBzYW1lIG9iamVjdCBpZgorICAgICAgICAgKiAgICAgICAgIG5vdC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNlZSBVbm1vZGlmaWFibGVSYW5kb21BY2Nlc3NMaXN0I3dyaXRlUmVwbGFjZSgpCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIE9iamVjdCByZWFkUmVzb2x2ZSgpIHsKKyAgICAgICAgICAgIGlmIChsaXN0IGluc3RhbmNlb2YgUmFuZG9tQWNjZXNzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVbm1vZGlmaWFibGVSYW5kb21BY2Nlc3NMaXN0PEU+KGxpc3QpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBVbm1vZGlmaWFibGVNYXA8SywgVj4gaW1wbGVtZW50cyBNYXA8SywgVj4sCisgICAgICAgICAgICBTZXJpYWxpemFibGUgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTAzNDIzNDcyODU3NDI4NjAxNEw7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBNYXA8SywgVj4gbTsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBVbm1vZGlmaWFibGVFbnRyeVNldDxLLCBWPiBleHRlbmRzCisgICAgICAgICAgICAgICAgVW5tb2RpZmlhYmxlU2V0PE1hcC5FbnRyeTxLLCBWPj4geworICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzg1NDM5MDYxMTY1Nzk0MzczM0w7CisKKyAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFVubW9kaWZpYWJsZU1hcEVudHJ5PEssIFY+IGltcGxlbWVudHMKKyAgICAgICAgICAgICAgICAgICAgTWFwLkVudHJ5PEssIFY+IHsKKyAgICAgICAgICAgICAgICBNYXAuRW50cnk8SywgVj4gbWFwRW50cnk7CisKKyAgICAgICAgICAgICAgICBVbm1vZGlmaWFibGVNYXBFbnRyeShNYXAuRW50cnk8SywgVj4gZW50cnkpIHsKKyAgICAgICAgICAgICAgICAgICAgbWFwRW50cnkgPSBlbnRyeTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hcEVudHJ5LmVxdWFscyhvYmplY3QpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgSyBnZXRLZXkoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBtYXBFbnRyeS5nZXRLZXkoKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFYgZ2V0VmFsdWUoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBtYXBFbnRyeS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWFwRW50cnkuaGFzaENvZGUoKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFYgc2V0VmFsdWUoViBvYmplY3QpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBtYXBFbnRyeS50b1N0cmluZygpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgVW5tb2RpZmlhYmxlRW50cnlTZXQoU2V0PE1hcC5FbnRyeTxLLCBWPj4gc2V0KSB7CisgICAgICAgICAgICAgICAgc3VwZXIoc2V0KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBJdGVyYXRvcjxNYXAuRW50cnk8SywgVj4+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSXRlcmF0b3I8TWFwLkVudHJ5PEssIFY+PigpIHsKKyAgICAgICAgICAgICAgICAgICAgSXRlcmF0b3I8TWFwLkVudHJ5PEssIFY+PiBpdGVyYXRvciA9IGMuaXRlcmF0b3IoKTsKKworICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVyYXRvci5oYXNOZXh0KCk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIE1hcC5FbnRyeTxLLCBWPiBuZXh0KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVbm1vZGlmaWFibGVNYXBFbnRyeTxLLCBWPihpdGVyYXRvci5uZXh0KCkpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3RbXSB0b0FycmF5KCkgeworICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBjLnNpemUoKTsKKyAgICAgICAgICAgICAgICBPYmplY3RbXSByZXN1bHQgPSBuZXcgT2JqZWN0W2xlbmd0aF07CisgICAgICAgICAgICAgICAgSXRlcmF0b3I8Pz4gaXQgPSBpdGVyYXRvcigpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBsZW5ndGg7IC0taSA+PSAwOykgeworICAgICAgICAgICAgICAgICAgICByZXN1bHRbaV0gPSBpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyA8VD4gVFtdIHRvQXJyYXkoVFtdIGNvbnRlbnRzKSB7CisgICAgICAgICAgICAgICAgaW50IHNpemUgPSBjLnNpemUoKSwgaW5kZXggPSAwOworICAgICAgICAgICAgICAgIEl0ZXJhdG9yPE1hcC5FbnRyeTxLLCBWPj4gaXQgPSBpdGVyYXRvcigpOworICAgICAgICAgICAgICAgIGlmIChzaXplID4gY29udGVudHMubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIENsYXNzPD8+IGN0ID0gY29udGVudHMuZ2V0Q2xhc3MoKS5nZXRDb21wb25lbnRUeXBlKCk7CisgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gKFRbXSkgQXJyYXkubmV3SW5zdGFuY2UoY3QsIHNpemUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB3aGlsZSAoaW5kZXggPCBzaXplKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRzW2luZGV4KytdID0gKFQpIGl0Lm5leHQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGluZGV4IDwgY29udGVudHMubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRzW2luZGV4XSA9IG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBjb250ZW50czsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFVubW9kaWZpYWJsZU1hcChNYXA8SywgVj4gbWFwKSB7CisgICAgICAgICAgICBtID0gbWFwOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnNLZXkoT2JqZWN0IGtleSkgeworICAgICAgICAgICAgcmV0dXJuIG0uY29udGFpbnNLZXkoa2V5KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ZhbHVlKE9iamVjdCB2YWx1ZSkgeworICAgICAgICAgICAgcmV0dXJuIG0uY29udGFpbnNWYWx1ZSh2YWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFNldDxNYXAuRW50cnk8SywgVj4+IGVudHJ5U2V0KCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBVbm1vZGlmaWFibGVFbnRyeVNldDxLLCBWPihtLmVudHJ5U2V0KCkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gbS5lcXVhbHMob2JqZWN0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgViBnZXQoT2JqZWN0IGtleSkgeworICAgICAgICAgICAgcmV0dXJuIG0uZ2V0KGtleSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBtLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgICAgIHJldHVybiBtLmlzRW1wdHkoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU2V0PEs+IGtleVNldCgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVW5tb2RpZmlhYmxlU2V0PEs+KG0ua2V5U2V0KCkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBWIHB1dChLIGtleSwgViB2YWx1ZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgcHV0QWxsKE1hcDw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+IG1hcCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFYgcmVtb3ZlKE9iamVjdCBrZXkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBtLnNpemUoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgQ29sbGVjdGlvbjxWPiB2YWx1ZXMoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFVubW9kaWZpYWJsZUNvbGxlY3Rpb248Vj4obS52YWx1ZXMoKSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBtLnRvU3RyaW5nKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBVbm1vZGlmaWFibGVTZXQ8RT4gZXh0ZW5kcyBVbm1vZGlmaWFibGVDb2xsZWN0aW9uPEU+CisgICAgICAgICAgICBpbXBsZW1lbnRzIFNldDxFPiB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC05MjE1MDQ3ODMzNzc1MDEzODAzTDsKKworICAgICAgICBVbm1vZGlmaWFibGVTZXQoU2V0PEU+IHNldCkgeworICAgICAgICAgICAgc3VwZXIoc2V0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIGMuZXF1YWxzKG9iamVjdCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBjLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBVbm1vZGlmaWFibGVTb3J0ZWRNYXA8SywgVj4gZXh0ZW5kcworICAgICAgICAgICAgVW5tb2RpZmlhYmxlTWFwPEssIFY+IGltcGxlbWVudHMgU29ydGVkTWFwPEssIFY+IHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTg4MDY3NDM4MTU5OTY3MTMyMDZMOworCisgICAgICAgIHByaXZhdGUgZmluYWwgU29ydGVkTWFwPEssIFY+IHNtOworCisgICAgICAgIFVubW9kaWZpYWJsZVNvcnRlZE1hcChTb3J0ZWRNYXA8SywgVj4gbWFwKSB7CisgICAgICAgICAgICBzdXBlcihtYXApOworICAgICAgICAgICAgc20gPSBtYXA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIENvbXBhcmF0b3I8PyBzdXBlciBLPiBjb21wYXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIHNtLmNvbXBhcmF0b3IoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgSyBmaXJzdEtleSgpIHsKKyAgICAgICAgICAgIHJldHVybiBzbS5maXJzdEtleSgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTb3J0ZWRNYXA8SywgVj4gaGVhZE1hcChLIGJlZm9yZSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBVbm1vZGlmaWFibGVTb3J0ZWRNYXA8SywgVj4oc20uaGVhZE1hcChiZWZvcmUpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgSyBsYXN0S2V5KCkgeworICAgICAgICAgICAgcmV0dXJuIHNtLmxhc3RLZXkoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU29ydGVkTWFwPEssIFY+IHN1Yk1hcChLIHN0YXJ0LCBLIGVuZCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBVbm1vZGlmaWFibGVTb3J0ZWRNYXA8SywgVj4oc20uc3ViTWFwKHN0YXJ0LCBlbmQpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU29ydGVkTWFwPEssIFY+IHRhaWxNYXAoSyBhZnRlcikgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBVbm1vZGlmaWFibGVTb3J0ZWRNYXA8SywgVj4oc20udGFpbE1hcChhZnRlcikpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgVW5tb2RpZmlhYmxlU29ydGVkU2V0PEU+IGV4dGVuZHMgVW5tb2RpZmlhYmxlU2V0PEU+CisgICAgICAgICAgICBpbXBsZW1lbnRzIFNvcnRlZFNldDxFPiB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00OTI5MTQ5NTkxNTk5OTExMTY1TDsKKworICAgICAgICBwcml2YXRlIGZpbmFsIFNvcnRlZFNldDxFPiBzczsKKworICAgICAgICBVbm1vZGlmaWFibGVTb3J0ZWRTZXQoU29ydGVkU2V0PEU+IHNldCkgeworICAgICAgICAgICAgc3VwZXIoc2V0KTsKKyAgICAgICAgICAgIHNzID0gc2V0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBDb21wYXJhdG9yPD8gc3VwZXIgRT4gY29tcGFyYXRvcigpIHsKKyAgICAgICAgICAgIHJldHVybiBzcy5jb21wYXJhdG9yKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEUgZmlyc3QoKSB7CisgICAgICAgICAgICByZXR1cm4gc3MuZmlyc3QoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU29ydGVkU2V0PEU+IGhlYWRTZXQoRSBiZWZvcmUpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVW5tb2RpZmlhYmxlU29ydGVkU2V0PEU+KHNzLmhlYWRTZXQoYmVmb3JlKSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEUgbGFzdCgpIHsKKyAgICAgICAgICAgIHJldHVybiBzcy5sYXN0KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFNvcnRlZFNldDxFPiBzdWJTZXQoRSBzdGFydCwgRSBlbmQpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVW5tb2RpZmlhYmxlU29ydGVkU2V0PEU+KHNzLnN1YlNldChzdGFydCwgZW5kKSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFNvcnRlZFNldDxFPiB0YWlsU2V0KEUgYWZ0ZXIpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVW5tb2RpZmlhYmxlU29ydGVkU2V0PEU+KHNzLnRhaWxTZXQoYWZ0ZXIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgQ29sbGVjdGlvbnMoKSB7fQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBiaW5hcnkgc2VhcmNoIGZvciB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaW4gdGhlIHNwZWNpZmllZAorICAgICAqIHNvcnRlZCBsaXN0LiBUaGUgbGlzdCBuZWVkcyB0byBiZSBhbHJlYWR5IHNvcnRlZCBpbiBuYXR1cmFsIHNvcnRpbmcKKyAgICAgKiBvcmRlci4gU2VhcmNoaW5nIGluIGFuIHVuc29ydGVkIGFycmF5IGhhcyBhbiB1bmRlZmluZWQgcmVzdWx0LiBJdCdzIGFsc28KKyAgICAgKiB1bmRlZmluZWQgd2hpY2ggZWxlbWVudCBpcyBmb3VuZCBpZiB0aGVyZSBhcmUgbXVsdGlwbGUgb2NjdXJyZW5jZXMgb2YgdGhlCisgICAgICogc2FtZSBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGxpc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3J0ZWQgbGlzdCB0byBzZWFyY2guCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIGVsZW1lbnQgdG8gZmluZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBub24tbmVnYXRpdmUgaW5kZXggb2YgdGhlIGVsZW1lbnQsIG9yIGEgbmVnYXRpdmUgaW5kZXggd2hpY2gKKyAgICAgKiAgICAgICAgIGlzIHRoZSB7QGNvZGUgLWluZGV4IC0gMX0gd2hlcmUgdGhlIGVsZW1lbnQgd291bGQgYmUgaW5zZXJ0ZWQKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVsZW1lbnQgaW4gdGhlIExpc3Qgb3IgdGhlIHNlYXJjaCBlbGVtZW50IGRvZXMgbm90CisgICAgICogICAgICAgICAgICAgaW1wbGVtZW50IENvbXBhcmFibGUsIG9yIGNhbm5vdCBiZSBjb21wYXJlZCB0byBlYWNoIG90aGVyLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzdGF0aWMgPFQ+IGludCBiaW5hcnlTZWFyY2goTGlzdDw/IGV4dGVuZHMgQ29tcGFyYWJsZTw/IHN1cGVyIFQ+PiBsaXN0LCBUIG9iamVjdCkgeworICAgICAgICBpZiAobGlzdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobGlzdC5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorCisKKyAgICAgICAgaWYgKCEobGlzdCBpbnN0YW5jZW9mIFJhbmRvbUFjY2VzcykpIHsKKyAgICAgICAgICAgIExpc3RJdGVyYXRvcjw/IGV4dGVuZHMgQ29tcGFyYWJsZTw/IHN1cGVyIFQ+PiBpdCA9IGxpc3QubGlzdEl0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgaW50IHJlc3VsdDsKKyAgICAgICAgICAgICAgICBpZiAoKHJlc3VsdCA9IC1pdC5uZXh0KCkuY29tcGFyZVRvKG9iamVjdCkpIDw9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXQucHJldmlvdXNJbmRleCgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtaXQucHJldmlvdXNJbmRleCgpIC0gMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gLWxpc3Quc2l6ZSgpIC0gMTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBsb3cgPSAwLCBtaWQgPSBsaXN0LnNpemUoKSwgaGlnaCA9IG1pZCAtIDEsIHJlc3VsdCA9IC0xOworICAgICAgICB3aGlsZSAobG93IDw9IGhpZ2gpIHsKKyAgICAgICAgICAgIG1pZCA9IChsb3cgKyBoaWdoKSA+Pj4gMTsKKyAgICAgICAgICAgIGlmICgocmVzdWx0ID0gLWxpc3QuZ2V0KG1pZCkuY29tcGFyZVRvKG9iamVjdCkpID4gMCkgeworICAgICAgICAgICAgICAgIGxvdyA9IG1pZCArIDE7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdCA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG1pZDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaGlnaCA9IG1pZCAtIDE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC1taWQgLSAocmVzdWx0IDwgMCA/IDEgOiAyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggZm9yIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpbiB0aGUgc3BlY2lmaWVkCisgICAgICogc29ydGVkIGxpc3QgdXNpbmcgdGhlIHNwZWNpZmllZCBjb21wYXJhdG9yLiBUaGUgbGlzdCBuZWVkcyB0byBiZSBhbHJlYWR5CisgICAgICogc29ydGVkIGFjY29yZGluZyB0byB0aGUgY29tcGFyYXRvciBwYXNzZWQuIFNlYXJjaGluZyBpbiBhbiB1bnNvcnRlZCBhcnJheQorICAgICAqIGhhcyBhbiB1bmRlZmluZWQgcmVzdWx0LiBJdCdzIGFsc28gdW5kZWZpbmVkIHdoaWNoIGVsZW1lbnQgaXMgZm91bmQgaWYKKyAgICAgKiB0aGVyZSBhcmUgbXVsdGlwbGUgb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgZWxlbWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsaXN0CisgICAgICogICAgICAgICAgICB0aGUgc29ydGVkIExpc3QgdG8gc2VhcmNoLgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IHRvIGZpbmQuCisgICAgICogQHBhcmFtIGNvbXBhcmF0b3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb21wYXJhdG9yLiBJZiB0aGUgY29tcGFyYXRvciBpcyB7QGNvZGUgbnVsbH0gdGhlbiB0aGUKKyAgICAgKiAgICAgICAgICAgIHNlYXJjaCB1c2VzIHRoZSBvYmplY3RzJyBuYXR1cmFsIG9yZGVyaW5nLgorICAgICAqIEByZXR1cm4gdGhlIG5vbi1uZWdhdGl2ZSBpbmRleCBvZiB0aGUgZWxlbWVudCwgb3IgYSBuZWdhdGl2ZSBpbmRleCB3aGljaAorICAgICAqICAgICAgICAgaXMgdGhlIHtAY29kZSAtaW5kZXggLSAxfSB3aGVyZSB0aGUgZWxlbWVudCB3b3VsZCBiZSBpbnNlcnRlZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHdoZW4gYW4gZWxlbWVudCBpbiB0aGUgbGlzdCBhbmQgdGhlIHNlYXJjaGVkIGVsZW1lbnQgY2Fubm90CisgICAgICogICAgICAgICAgICAgYmUgY29tcGFyZWQgdG8gZWFjaCBvdGhlciB1c2luZyB0aGUgY29tcGFyYXRvci4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgc3RhdGljIDxUPiBpbnQgYmluYXJ5U2VhcmNoKExpc3Q8PyBleHRlbmRzIFQ+IGxpc3QsIFQgb2JqZWN0LAorICAgICAgICAgICAgQ29tcGFyYXRvcjw/IHN1cGVyIFQ+IGNvbXBhcmF0b3IpIHsKKyAgICAgICAgaWYgKGNvbXBhcmF0b3IgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmJpbmFyeVNlYXJjaCgKKyAgICAgICAgICAgICAgICAgICAgKExpc3Q8PyBleHRlbmRzIENvbXBhcmFibGU8PyBzdXBlciBUPj4pIGxpc3QsIG9iamVjdCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCEobGlzdCBpbnN0YW5jZW9mIFJhbmRvbUFjY2VzcykpIHsKKyAgICAgICAgICAgIExpc3RJdGVyYXRvcjw/IGV4dGVuZHMgVD4gaXQgPSBsaXN0Lmxpc3RJdGVyYXRvcigpOworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIGludCByZXN1bHQ7CisgICAgICAgICAgICAgICAgaWYgKChyZXN1bHQgPSAtY29tcGFyYXRvci5jb21wYXJlKGl0Lm5leHQoKSwgb2JqZWN0KSkgPD0gMCkgeworICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpdC5wcmV2aW91c0luZGV4KCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC1pdC5wcmV2aW91c0luZGV4KCkgLSAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAtbGlzdC5zaXplKCkgLSAxOworICAgICAgICB9CisKKyAgICAgICAgaW50IGxvdyA9IDAsIG1pZCA9IGxpc3Quc2l6ZSgpLCBoaWdoID0gbWlkIC0gMSwgcmVzdWx0ID0gLTE7CisgICAgICAgIHdoaWxlIChsb3cgPD0gaGlnaCkgeworICAgICAgICAgICAgbWlkID0gKGxvdyArIGhpZ2gpID4+PiAxOworICAgICAgICAgICAgaWYgKChyZXN1bHQgPSAtY29tcGFyYXRvci5jb21wYXJlKGxpc3QuZ2V0KG1pZCksIG9iamVjdCkpID4gMCkgeworICAgICAgICAgICAgICAgIGxvdyA9IG1pZCArIDE7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdCA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG1pZDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaGlnaCA9IG1pZCAtIDE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC1taWQgLSAocmVzdWx0IDwgMCA/IDEgOiAyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgdGhlIGVsZW1lbnRzIGZyb20gdGhlIHNvdXJjZSBsaXN0IHRvIHRoZSBkZXN0aW5hdGlvbiBsaXN0LiBBdCB0aGUKKyAgICAgKiBlbmQgYm90aCBsaXN0cyB3aWxsIGhhdmUgdGhlIHNhbWUgb2JqZWN0cyBhdCB0aGUgc2FtZSBpbmRleC4gSWYgdGhlCisgICAgICogZGVzdGluYXRpb24gYXJyYXkgaXMgbGFyZ2VyIHRoYW4gdGhlIHNvdXJjZSBsaXN0LCB0aGUgZWxlbWVudHMgaW4gdGhlCisgICAgICogZGVzdGluYXRpb24gbGlzdCB3aXRoIHtAY29kZSBpbmRleCA+PSBzb3VyY2Uuc2l6ZSgpfSB3aWxsIGJlIHVuY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgd2hvc2UgZWxlbWVudHMgYXJlIHNldCBmcm9tIHRoZSBzb3VyY2UgbGlzdC4KKyAgICAgKiBAcGFyYW0gc291cmNlCisgICAgICogICAgICAgICAgICB0aGUgbGlzdCB3aXRoIHRoZSBlbGVtZW50cyB0byBiZSBjb3BpZWQgaW50byB0aGUgZGVzdGluYXRpb24uCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiB0aGUgZGVzdGluYXRpb24gbGlzdCBpcyBzbWFsbGVyIHRoYW4gdGhlIHNvdXJjZSBsaXN0LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHJlcGxhY2luZyBhbiBlbGVtZW50IGluIHRoZSBkZXN0aW5hdGlvbiBsaXN0IGlzIG5vdAorICAgICAqICAgICAgICAgICAgIHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUPiB2b2lkIGNvcHkoTGlzdDw/IHN1cGVyIFQ+IGRlc3RpbmF0aW9uLCBMaXN0PD8gZXh0ZW5kcyBUPiBzb3VyY2UpIHsKKyAgICAgICAgaWYgKGRlc3RpbmF0aW9uLnNpemUoKSA8IHNvdXJjZS5zaXplKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJkZXN0aW5hdGlvbi5zaXplKCkgPCBzb3VyY2Uuc2l6ZSgpOiAiICsKKyAgICAgICAgICAgICAgICAgICAgZGVzdGluYXRpb24uc2l6ZSgpICsgIiA8ICIgKyBzb3VyY2Uuc2l6ZSgpKTsKKyAgICAgICAgfQorICAgICAgICBJdGVyYXRvcjw/IGV4dGVuZHMgVD4gc3JjSXQgPSBzb3VyY2UuaXRlcmF0b3IoKTsKKyAgICAgICAgTGlzdEl0ZXJhdG9yPD8gc3VwZXIgVD4gZGVzdEl0ID0gZGVzdGluYXRpb24ubGlzdEl0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChzcmNJdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZGVzdEl0Lm5leHQoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIFRPRE86IEFzc2VydGlvbkVycm9yPworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJTb3VyY2Ugc2l6ZSAiICsgc291cmNlLnNpemUoKSArCisgICAgICAgICAgICAgICAgICAgICAgICAiIGRvZXMgbm90IGZpdCBpbnRvIGRlc3RpbmF0aW9uIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkZXN0SXQuc2V0KHNyY0l0Lm5leHQoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIHtAY29kZSBFbnVtZXJhdGlvbn0gb24gdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIHRvIGVudW1lcmF0ZS4KKyAgICAgKiBAcmV0dXJuIGFuIEVudW1lcmF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFQ+IEVudW1lcmF0aW9uPFQ+IGVudW1lcmF0aW9uKENvbGxlY3Rpb248VD4gY29sbGVjdGlvbikgeworICAgICAgICBmaW5hbCBDb2xsZWN0aW9uPFQ+IGMgPSBjb2xsZWN0aW9uOworICAgICAgICByZXR1cm4gbmV3IEVudW1lcmF0aW9uPFQ+KCkgeworICAgICAgICAgICAgSXRlcmF0b3I8VD4gaXQgPSBjLml0ZXJhdG9yKCk7CisKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNNb3JlRWxlbWVudHMoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGl0Lmhhc05leHQoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBUIG5leHRFbGVtZW50KCkgeworICAgICAgICAgICAgICAgIHJldHVybiBpdC5uZXh0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsbHMgdGhlIHNwZWNpZmllZCBsaXN0IHdpdGggdGhlIHNwZWNpZmllZCBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGxpc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IHRvIGZpbGwuCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIGVsZW1lbnQgdG8gZmlsbCB0aGUgbGlzdCB3aXRoLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHJlcGxhY2luZyBhbiBlbGVtZW50IGluIHRoZSBMaXN0IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8VD4gdm9pZCBmaWxsKExpc3Q8PyBzdXBlciBUPiBsaXN0LCBUIG9iamVjdCkgeworICAgICAgICBMaXN0SXRlcmF0b3I8PyBzdXBlciBUPiBpdCA9IGxpc3QubGlzdEl0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIGl0Lm5leHQoKTsKKyAgICAgICAgICAgIGl0LnNldChvYmplY3QpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VhcmNoZXMgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGZvciB0aGUgbWF4aW11bSBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIHRvIHNlYXJjaC4KKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIGVsZW1lbnQgaW4gdGhlIENvbGxlY3Rpb24uCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIGFuIGVsZW1lbnQgaW4gdGhlIGNvbGxlY3Rpb24gZG9lcyBub3QgaW1wbGVtZW50CisgICAgICogICAgICAgICAgICAge0Bjb2RlIENvbXBhcmFibGV9IG9yIGVsZW1lbnRzIGNhbm5vdCBiZSBjb21wYXJlZCB0byBlYWNoCisgICAgICogICAgICAgICAgICAgb3RoZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8VCBleHRlbmRzIE9iamVjdCAmIENvbXBhcmFibGU8PyBzdXBlciBUPj4gVCBtYXgoCisgICAgICAgICAgICBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBUPiBjb2xsZWN0aW9uKSB7CisgICAgICAgIEl0ZXJhdG9yPD8gZXh0ZW5kcyBUPiBpdCA9IGNvbGxlY3Rpb24uaXRlcmF0b3IoKTsKKyAgICAgICAgVCBtYXggPSBpdC5uZXh0KCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIFQgbmV4dCA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIGlmIChtYXguY29tcGFyZVRvKG5leHQpIDwgMCkgeworICAgICAgICAgICAgICAgIG1heCA9IG5leHQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG1heDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gZm9yIHRoZSBtYXhpbXVtIGVsZW1lbnQgdXNpbmcgdGhlCisgICAgICogc3BlY2lmaWVkIGNvbXBhcmF0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLgorICAgICAqIEBwYXJhbSBjb21wYXJhdG9yCisgICAgICogICAgICAgICAgICB0aGUgY29tcGFyYXRvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIGVsZW1lbnQgaW4gdGhlIENvbGxlY3Rpb24uCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIGVsZW1lbnRzIGluIHRoZSBjb2xsZWN0aW9uIGNhbm5vdCBiZSBjb21wYXJlZCB0byBlYWNoCisgICAgICogICAgICAgICAgICAgb3RoZXIgdXNpbmcgdGhlIHtAY29kZSBDb21wYXJhdG9yfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUPiBUIG1heChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBUPiBjb2xsZWN0aW9uLAorICAgICAgICAgICAgQ29tcGFyYXRvcjw/IHN1cGVyIFQ+IGNvbXBhcmF0b3IpIHsKKyAgICAgICAgaWYgKGNvbXBhcmF0b3IgPT0gbnVsbCkgeworICAgICAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIC8vIG51bGwgY29tcGFyYXRvcj8gVCBpcyBjb21wYXJhYmxlCisgICAgICAgICAgICBUIHJlc3VsdCA9IChUKSBtYXgoKENvbGxlY3Rpb248Q29tcGFyYWJsZT4pIGNvbGxlY3Rpb24pOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIEl0ZXJhdG9yPD8gZXh0ZW5kcyBUPiBpdCA9IGNvbGxlY3Rpb24uaXRlcmF0b3IoKTsKKyAgICAgICAgVCBtYXggPSBpdC5uZXh0KCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIFQgbmV4dCA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIGlmIChjb21wYXJhdG9yLmNvbXBhcmUobWF4LCBuZXh0KSA8IDApIHsKKyAgICAgICAgICAgICAgICBtYXggPSBuZXh0OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBtYXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VhcmNoZXMgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGZvciB0aGUgbWluaW11bSBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIHRvIHNlYXJjaC4KKyAgICAgKiBAcmV0dXJuIHRoZSBtaW5pbXVtIGVsZW1lbnQgaW4gdGhlIGNvbGxlY3Rpb24uCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIGFuIGVsZW1lbnQgaW4gdGhlIGNvbGxlY3Rpb24gZG9lcyBub3QgaW1wbGVtZW50CisgICAgICogICAgICAgICAgICAge0Bjb2RlIENvbXBhcmFibGV9IG9yIGVsZW1lbnRzIGNhbm5vdCBiZSBjb21wYXJlZCB0byBlYWNoCisgICAgICogICAgICAgICAgICAgb3RoZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8VCBleHRlbmRzIE9iamVjdCAmIENvbXBhcmFibGU8PyBzdXBlciBUPj4gVCBtaW4oCisgICAgICAgICAgICBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBUPiBjb2xsZWN0aW9uKSB7CisgICAgICAgIEl0ZXJhdG9yPD8gZXh0ZW5kcyBUPiBpdCA9IGNvbGxlY3Rpb24uaXRlcmF0b3IoKTsKKyAgICAgICAgVCBtaW4gPSBpdC5uZXh0KCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIFQgbmV4dCA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIGlmIChtaW4uY29tcGFyZVRvKG5leHQpID4gMCkgeworICAgICAgICAgICAgICAgIG1pbiA9IG5leHQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG1pbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gZm9yIHRoZSBtaW5pbXVtIGVsZW1lbnQgdXNpbmcgdGhlCisgICAgICogc3BlY2lmaWVkIGNvbXBhcmF0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLgorICAgICAqIEBwYXJhbSBjb21wYXJhdG9yCisgICAgICogICAgICAgICAgICB0aGUgY29tcGFyYXRvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBtaW5pbXVtIGVsZW1lbnQgaW4gdGhlIGNvbGxlY3Rpb24uCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIGVsZW1lbnRzIGluIHRoZSBjb2xsZWN0aW9uIGNhbm5vdCBiZSBjb21wYXJlZCB0byBlYWNoCisgICAgICogICAgICAgICAgICAgb3RoZXIgdXNpbmcgdGhlIHtAY29kZSBDb21wYXJhdG9yfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUPiBUIG1pbihDb2xsZWN0aW9uPD8gZXh0ZW5kcyBUPiBjb2xsZWN0aW9uLAorICAgICAgICAgICAgQ29tcGFyYXRvcjw/IHN1cGVyIFQ+IGNvbXBhcmF0b3IpIHsKKyAgICAgICAgaWYgKGNvbXBhcmF0b3IgPT0gbnVsbCkgeworICAgICAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIC8vIG51bGwgY29tcGFyYXRvcj8gVCBpcyBjb21wYXJhYmxlCisgICAgICAgICAgICBUIHJlc3VsdCA9IChUKSBtaW4oKENvbGxlY3Rpb248Q29tcGFyYWJsZT4pIGNvbGxlY3Rpb24pOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIEl0ZXJhdG9yPD8gZXh0ZW5kcyBUPiBpdCA9IGNvbGxlY3Rpb24uaXRlcmF0b3IoKTsKKyAgICAgICAgVCBtaW4gPSBpdC5uZXh0KCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIFQgbmV4dCA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIGlmIChjb21wYXJhdG9yLmNvbXBhcmUobWluLCBuZXh0KSA+IDApIHsKKyAgICAgICAgICAgICAgICBtaW4gPSBuZXh0OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBtaW47CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGxpc3QgY29udGFpbmluZyB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuCisgICAgICogVGhlIGxpc3QgY2Fubm90IGJlIG1vZGlmaWVkLiBUaGUgbGlzdCBpcyBzZXJpYWxpemFibGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgc2l6ZSBvZiB0aGUgcmV0dXJuZWQgbGlzdC4KKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCB0byBiZSBhZGRlZCB7QGNvZGUgbGVuZ3RofSB0aW1lcyB0byBhIGxpc3QuCisgICAgICogQHJldHVybiBhIGxpc3QgY29udGFpbmluZyB7QGNvZGUgbGVuZ3RofSBjb3BpZXMgb2YgdGhlIGVsZW1lbnQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHtAY29kZSBsZW5ndGggPCAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUPiBMaXN0PFQ+IG5Db3BpZXMoZmluYWwgaW50IGxlbmd0aCwgVCBvYmplY3QpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBDb3BpZXNMaXN0PFQ+KGxlbmd0aCwgb2JqZWN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNb2RpZmllcyB0aGUgc3BlY2lmaWVkIHtAY29kZSBMaXN0fSBieSByZXZlcnNpbmcgdGhlIG9yZGVyIG9mIHRoZQorICAgICAqIGVsZW1lbnRzLgorICAgICAqCisgICAgICogQHBhcmFtIGxpc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IHRvIHJldmVyc2UuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHdoZW4gcmVwbGFjaW5nIGFuIGVsZW1lbnQgaW4gdGhlIExpc3QgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcmV2ZXJzZShMaXN0PD8+IGxpc3QpIHsKKyAgICAgICAgaW50IHNpemUgPSBsaXN0LnNpemUoKTsKKyAgICAgICAgTGlzdEl0ZXJhdG9yPE9iamVjdD4gZnJvbnQgPSAoTGlzdEl0ZXJhdG9yPE9iamVjdD4pIGxpc3QubGlzdEl0ZXJhdG9yKCk7CisgICAgICAgIExpc3RJdGVyYXRvcjxPYmplY3Q+IGJhY2sgPSAoTGlzdEl0ZXJhdG9yPE9iamVjdD4pIGxpc3QKKyAgICAgICAgICAgICAgICAubGlzdEl0ZXJhdG9yKHNpemUpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemUgLyAyOyBpKyspIHsKKyAgICAgICAgICAgIE9iamVjdCBmcm9udE5leHQgPSBmcm9udC5uZXh0KCk7CisgICAgICAgICAgICBPYmplY3QgYmFja1ByZXYgPSBiYWNrLnByZXZpb3VzKCk7CisgICAgICAgICAgICBmcm9udC5zZXQoYmFja1ByZXYpOworICAgICAgICAgICAgYmFjay5zZXQoZnJvbnROZXh0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEEgY29tcGFyYXRvciB3aGljaCByZXZlcnNlcyB0aGUgbmF0dXJhbCBvcmRlciBvZiB0aGUgZWxlbWVudHMuIFRoZQorICAgICAqIHtAY29kZSBDb21wYXJhdG9yfSB0aGF0J3MgcmV0dXJuZWQgaXMge0BsaW5rIFNlcmlhbGl6YWJsZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIENvbXBhcmF0b3J9IGluc3RhbmNlLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzdGF0aWMgPFQ+IENvbXBhcmF0b3I8VD4gcmV2ZXJzZU9yZGVyKCkgeworICAgICAgICByZXR1cm4gKENvbXBhcmF0b3IpIFJldmVyc2VDb21wYXJhdG9yLklOU1RBTkNFOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGxpbmsgQ29tcGFyYXRvcn0gdGhhdCByZXZlcnNlcyB0aGUgb3JkZXIgb2YgdGhlCisgICAgICoge0Bjb2RlIENvbXBhcmF0b3J9IHBhc3NlZC4gSWYgdGhlIHtAY29kZSBDb21wYXJhdG9yfSBwYXNzZWQgaXMKKyAgICAgKiB7QGNvZGUgbnVsbH0sIHRoZW4gdGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byB7QGxpbmsgI3JldmVyc2VPcmRlcigpfS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUge0Bjb2RlIENvbXBhcmF0b3J9IHRoYXQncyByZXR1cm5lZCBpcyB7QGxpbmsgU2VyaWFsaXphYmxlfSBpZiB0aGUKKyAgICAgKiB7QGNvZGUgQ29tcGFyYXRvcn0gcGFzc2VkIGlzIHNlcmlhbGl6YWJsZSBvciB7QGNvZGUgbnVsbH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDb21wYXJhdG9yfSB0byByZXZlcnNlIG9yIHtAY29kZSBudWxsfS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIENvbXBhcmF0b3J9IGluc3RhbmNlLgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUPiBDb21wYXJhdG9yPFQ+IHJldmVyc2VPcmRlcihDb21wYXJhdG9yPFQ+IGMpIHsKKyAgICAgICAgaWYgKGMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHJldmVyc2VPcmRlcigpOworICAgICAgICB9CisgICAgICAgIGlmIChjIGluc3RhbmNlb2YgUmV2ZXJzZUNvbXBhcmF0b3IyKSB7CisgICAgICAgICAgICByZXR1cm4gKChSZXZlcnNlQ29tcGFyYXRvcjI8VD4pIGMpLmNtcDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFJldmVyc2VDb21wYXJhdG9yMjxUPihjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNb3ZlcyBldmVyeSBlbGVtZW50IG9mIHRoZSBsaXN0IHRvIGEgcmFuZG9tIG5ldyBwb3NpdGlvbiBpbiB0aGUgbGlzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsaXN0CisgICAgICogICAgICAgICAgICB0aGUgTGlzdCB0byBzaHVmZmxlLgorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHdoZW4gcmVwbGFjaW5nIGFuIGVsZW1lbnQgaW4gdGhlIExpc3QgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2h1ZmZsZShMaXN0PD8+IGxpc3QpIHsKKyAgICAgICAgc2h1ZmZsZShsaXN0LCBuZXcgUmFuZG9tKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1vdmVzIGV2ZXJ5IGVsZW1lbnQgb2YgdGhlIGxpc3QgdG8gYSByYW5kb20gbmV3IHBvc2l0aW9uIGluIHRoZSBsaXN0CisgICAgICogdXNpbmcgdGhlIHNwZWNpZmllZCByYW5kb20gbnVtYmVyIGdlbmVyYXRvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsaXN0CisgICAgICogICAgICAgICAgICB0aGUgbGlzdCB0byBzaHVmZmxlLgorICAgICAqIEBwYXJhbSByYW5kb20KKyAgICAgKiAgICAgICAgICAgIHRoZSByYW5kb20gbnVtYmVyIGdlbmVyYXRvci4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiByZXBsYWNpbmcgYW4gZWxlbWVudCBpbiB0aGUgbGlzdCBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzaHVmZmxlKExpc3Q8Pz4gbGlzdCwgUmFuZG9tIHJhbmRvbSkgeworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikgLy8gd2Ugd29uJ3QgcHV0IGZvcmVpZ24gb2JqZWN0cyBpbgorICAgICAgICBmaW5hbCBMaXN0PE9iamVjdD4gb2JqZWN0TGlzdCA9IChMaXN0PE9iamVjdD4pIGxpc3Q7CisKKyAgICAgICAgaWYgKGxpc3QgaW5zdGFuY2VvZiBSYW5kb21BY2Nlc3MpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBvYmplY3RMaXN0LnNpemUoKSAtIDE7IGkgPiAwOyBpLS0pIHsKKyAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSByYW5kb20ubmV4dEludChpICsgMSk7CisgICAgICAgICAgICAgICAgb2JqZWN0TGlzdC5zZXQoaW5kZXgsIG9iamVjdExpc3Quc2V0KGksIG9iamVjdExpc3QuZ2V0KGluZGV4KSkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgT2JqZWN0W10gYXJyYXkgPSBvYmplY3RMaXN0LnRvQXJyYXkoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBhcnJheS5sZW5ndGggLSAxOyBpID4gMDsgaS0tKSB7CisgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gcmFuZG9tLm5leHRJbnQoaSArIDEpOworICAgICAgICAgICAgICAgIE9iamVjdCB0ZW1wID0gYXJyYXlbaV07CisgICAgICAgICAgICAgICAgYXJyYXlbaV0gPSBhcnJheVtpbmRleF07CisgICAgICAgICAgICAgICAgYXJyYXlbaW5kZXhdID0gdGVtcDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IGkgPSAwOworICAgICAgICAgICAgTGlzdEl0ZXJhdG9yPE9iamVjdD4gaXQgPSBvYmplY3RMaXN0Lmxpc3RJdGVyYXRvcigpOworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIGl0Lm5leHQoKTsKKyAgICAgICAgICAgICAgICBpdC5zZXQoYXJyYXlbaSsrXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc2V0IGNvbnRhaW5pbmcgdGhlIHNwZWNpZmllZCBlbGVtZW50LiBUaGUgc2V0IGNhbm5vdCBiZQorICAgICAqIG1vZGlmaWVkLiBUaGUgc2V0IGlzIHNlcmlhbGl6YWJsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50LgorICAgICAqIEByZXR1cm4gYSBzZXQgY29udGFpbmluZyB0aGUgZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxFPiBTZXQ8RT4gc2luZ2xldG9uKEUgb2JqZWN0KSB7CisgICAgICAgIHJldHVybiBuZXcgU2luZ2xldG9uU2V0PEU+KG9iamVjdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGxpc3QgY29udGFpbmluZyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuIFRoZSBsaXN0IGNhbm5vdCBiZQorICAgICAqIG1vZGlmaWVkLiBUaGUgbGlzdCBpcyBzZXJpYWxpemFibGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudC4KKyAgICAgKiBAcmV0dXJuIGEgbGlzdCBjb250YWluaW5nIHRoZSBlbGVtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPEU+IExpc3Q8RT4gc2luZ2xldG9uTGlzdChFIG9iamVjdCkgeworICAgICAgICByZXR1cm4gbmV3IFNpbmdsZXRvbkxpc3Q8RT4ob2JqZWN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgTWFwIGNvbnRhaW5pbmcgdGhlIHNwZWNpZmllZCBrZXkgYW5kIHZhbHVlLiBUaGUgbWFwIGNhbm5vdCBiZQorICAgICAqIG1vZGlmaWVkLiBUaGUgbWFwIGlzIHNlcmlhbGl6YWJsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUuCisgICAgICogQHJldHVybiBhIE1hcCBjb250YWluaW5nIHRoZSBrZXkgYW5kIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPEssIFY+IE1hcDxLLCBWPiBzaW5nbGV0b25NYXAoSyBrZXksIFYgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTaW5nbGV0b25NYXA8SywgVj4oa2V5LCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCBsaXN0IGluIGFzY2VuZGluZyBuYXR1cmFsIG9yZGVyLiBUaGUgYWxnb3JpdGhtIGlzCisgICAgICogc3RhYmxlIHdoaWNoIG1lYW5zIGVxdWFsIGVsZW1lbnRzIGRvbid0IGdldCByZW9yZGVyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGlzdAorICAgICAqICAgICAgICAgICAgdGhlIGxpc3QgdG8gYmUgc29ydGVkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiBhbiBlbGVtZW50IGluIHRoZSBMaXN0IGRvZXMgbm90IGltcGxlbWVudCBDb21wYXJhYmxlIG9yCisgICAgICogICAgICAgICAgICAgZWxlbWVudHMgY2Fubm90IGJlIGNvbXBhcmVkIHRvIGVhY2ggb3RoZXIuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN0YXRpYyA8VCBleHRlbmRzIENvbXBhcmFibGU8PyBzdXBlciBUPj4gdm9pZCBzb3J0KExpc3Q8VD4gbGlzdCkgeworICAgICAgICBPYmplY3RbXSBhcnJheSA9IGxpc3QudG9BcnJheSgpOworICAgICAgICBBcnJheXMuc29ydChhcnJheSk7CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgTGlzdEl0ZXJhdG9yPFQ+IGl0ID0gbGlzdC5saXN0SXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgaXQubmV4dCgpOworICAgICAgICAgICAgaXQuc2V0KChUKSBhcnJheVtpKytdKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgbGlzdCB1c2luZyB0aGUgc3BlY2lmaWVkIGNvbXBhcmF0b3IuIFRoZSBhbGdvcml0aG0gaXMKKyAgICAgKiBzdGFibGUgd2hpY2ggbWVhbnMgZXF1YWwgZWxlbWVudHMgZG9uJ3QgZ2V0IHJlb3JkZXJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsaXN0CisgICAgICogICAgICAgICAgICB0aGUgbGlzdCB0byBiZSBzb3J0ZWQuCisgICAgICogQHBhcmFtIGNvbXBhcmF0b3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb21wYXJhdG9yLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiBlbGVtZW50cyBpbiB0aGUgbGlzdCBjYW5ub3QgYmUgY29tcGFyZWQgdG8gZWFjaCBvdGhlcgorICAgICAqICAgICAgICAgICAgIHVzaW5nIHRoZSBjb21wYXJhdG9yLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzdGF0aWMgPFQ+IHZvaWQgc29ydChMaXN0PFQ+IGxpc3QsIENvbXBhcmF0b3I8PyBzdXBlciBUPiBjb21wYXJhdG9yKSB7CisgICAgICAgIFRbXSBhcnJheSA9IGxpc3QudG9BcnJheSgoVFtdKSBuZXcgT2JqZWN0W2xpc3Quc2l6ZSgpXSk7CisgICAgICAgIEFycmF5cy5zb3J0KGFycmF5LCBjb21wYXJhdG9yKTsKKyAgICAgICAgaW50IGkgPSAwOworICAgICAgICBMaXN0SXRlcmF0b3I8VD4gaXQgPSBsaXN0Lmxpc3RJdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBpdC5uZXh0KCk7CisgICAgICAgICAgICBpdC5zZXQoYXJyYXlbaSsrXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTd2FwcyB0aGUgZWxlbWVudHMgb2YgbGlzdCB7QGNvZGUgbGlzdH0gYXQgaW5kaWNlcyB7QGNvZGUgaW5kZXgxfSBhbmQKKyAgICAgKiB7QGNvZGUgaW5kZXgyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsaXN0CisgICAgICogICAgICAgICAgICB0aGUgbGlzdCB0byBtYW5pcHVsYXRlLgorICAgICAqIEBwYXJhbSBpbmRleDEKKyAgICAgKiAgICAgICAgICAgIHBvc2l0aW9uIG9mIHRoZSBmaXJzdCBlbGVtZW50IHRvIHN3YXAgd2l0aCB0aGUgZWxlbWVudCBpbgorICAgICAqICAgICAgICAgICAgaW5kZXgyLgorICAgICAqIEBwYXJhbSBpbmRleDIKKyAgICAgKiAgICAgICAgICAgIHBvc2l0aW9uIG9mIHRoZSBvdGhlciBlbGVtZW50LgorICAgICAqCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgaW5kZXgxIG9yIGluZGV4MiBpcyBvdXQgb2YgcmFuZ2Ugb2YgdGhpcyBsaXN0LgorICAgICAqIEBzaW5jZSAxLjQKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc3dhcChMaXN0PD8+IGxpc3QsIGludCBpbmRleDEsIGludCBpbmRleDIpIHsKKyAgICAgICAgaWYgKGxpc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgaW50IHNpemUgPSBsaXN0LnNpemUoKTsKKyAgICAgICAgaWYgKGluZGV4MSA8IDAgfHwgaW5kZXgxID49IHNpemUgfHwgaW5kZXgyIDwgMCB8fCBpbmRleDIgPj0gc2l6ZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5kZXgxID09IGluZGV4MikgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIExpc3Q8T2JqZWN0PiByYXdMaXN0ID0gKExpc3Q8T2JqZWN0PikgbGlzdDsKKyAgICAgICAgcmF3TGlzdC5zZXQoaW5kZXgyLCByYXdMaXN0LnNldChpbmRleDEsIHJhd0xpc3QuZ2V0KGluZGV4MikpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyBhbGwgb2NjdXJyZW5jZXMgb2YgT2JqZWN0IHtAY29kZSBvYmp9IGluIHtAY29kZSBsaXN0fSB3aXRoCisgICAgICoge0Bjb2RlIG5ld09ian0uIElmIHRoZSB7QGNvZGUgb2JqfSBpcyB7QGNvZGUgbnVsbH0sIHRoZW4gYWxsCisgICAgICogb2NjdXJyZW5jZXMgb2Yge0Bjb2RlIG51bGx9IGFyZSByZXBsYWNlZCB3aXRoIHtAY29kZSBuZXdPYmp9LgorICAgICAqCisgICAgICogQHBhcmFtIGxpc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IHRvIG1vZGlmeS4KKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGZpbmQgYW5kIHJlcGxhY2Ugb2NjdXJyZW5jZXMgb2YuCisgICAgICogQHBhcmFtIG9iajIKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gcmVwbGFjZSBhbGwgb2NjdXJyZW5jZXMgb2Yge0Bjb2RlIG9ian0gaW4KKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBsaXN0fS4KKyAgICAgKiBAcmV0dXJuIHRydWUsIGlmIGF0IGxlYXN0IG9uZSBvY2N1cnJlbmNlIG9mIHtAY29kZSBvYmp9IGhhcyBiZWVuIGZvdW5kIGluCisgICAgICogICAgICAgICB7QGNvZGUgbGlzdH0uCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBsaXN0IGRvZXMgbm90IHN1cHBvcnQgc2V0dGluZyBlbGVtZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUPiBib29sZWFuIHJlcGxhY2VBbGwoTGlzdDxUPiBsaXN0LCBUIG9iaiwgVCBvYmoyKSB7CisgICAgICAgIGludCBpbmRleDsKKyAgICAgICAgYm9vbGVhbiBmb3VuZCA9IGZhbHNlOworCisgICAgICAgIHdoaWxlICgoaW5kZXggPSBsaXN0LmluZGV4T2Yob2JqKSkgPiAtMSkgeworICAgICAgICAgICAgZm91bmQgPSB0cnVlOworICAgICAgICAgICAgbGlzdC5zZXQoaW5kZXgsIG9iajIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmb3VuZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSb3RhdGVzIHRoZSBlbGVtZW50cyBpbiB7QGNvZGUgbGlzdH0gYnkgdGhlIGRpc3RhbmNlIHtAY29kZSBkaXN0fQorICAgICAqIDxwPgorICAgICAqIGUuZy4gZm9yIGEgZ2l2ZW4gbGlzdCB3aXRoIGVsZW1lbnRzIFsxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAwXSwKKyAgICAgKiBjYWxsaW5nIHJvdGF0ZShsaXN0LCAzKSBvciByb3RhdGUobGlzdCwgLTcpIHdvdWxkIG1vZGlmeSB0aGUgbGlzdCB0byBsb29rCisgICAgICogbGlrZSB0aGlzOiBbOCwgOSwgMCwgMSwgMiwgMywgNCwgNSwgNiwgN10KKyAgICAgKgorICAgICAqIEBwYXJhbSBsc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IHdob3NlIGVsZW1lbnRzIGFyZSB0byBiZSByb3RhdGVkLgorICAgICAqIEBwYXJhbSBkaXN0CisgICAgICogICAgICAgICAgICBpcyB0aGUgZGlzdGFuY2UgdGhlIGxpc3QgaXMgcm90YXRlZC4gVGhpcyBjYW4gYmUgYW55IHZhbGlkCisgICAgICogICAgICAgICAgICBpbnRlZ2VyLiBOZWdhdGl2ZSB2YWx1ZXMgcm90YXRlIHRoZSBsaXN0IGJhY2t3YXJkcy4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcm90YXRlKExpc3Q8Pz4gbHN0LCBpbnQgZGlzdCkgeworICAgICAgICBMaXN0PE9iamVjdD4gbGlzdCA9IChMaXN0PE9iamVjdD4pIGxzdDsKKyAgICAgICAgaW50IHNpemUgPSBsaXN0LnNpemUoKTsKKworICAgICAgICAvLyBDYW4ndCBzZW5zaWJseSByb3RhdGUgYW4gZW1wdHkgY29sbGVjdGlvbgorICAgICAgICBpZiAoc2l6ZSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICAvLyBub3JtYWxpemUgdGhlIGRpc3RhbmNlCisgICAgICAgIGludCBub3JtZGlzdDsKKyAgICAgICAgaWYgKGRpc3QgPiAwKSB7CisgICAgICAgICAgICBub3JtZGlzdCA9IGRpc3QgJSBzaXplOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbm9ybWRpc3QgPSBzaXplIC0gKChkaXN0ICUgc2l6ZSkgKiAoLTEpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChub3JtZGlzdCA9PSAwIHx8IG5vcm1kaXN0ID09IHNpemUpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChsaXN0IGluc3RhbmNlb2YgUmFuZG9tQWNjZXNzKSB7CisgICAgICAgICAgICAvLyBtYWtlIHN1cmUgZWFjaCBlbGVtZW50IGdldHMganVnZ2xlZAorICAgICAgICAgICAgLy8gd2l0aCB0aGUgZWxlbWVudCBpbiB0aGUgcG9zaXRpb24gaXQgaXMgc3VwcG9zZWQgdG8gZ28gdG8KKyAgICAgICAgICAgIE9iamVjdCB0ZW1wID0gbGlzdC5nZXQoMCk7CisgICAgICAgICAgICBpbnQgaW5kZXggPSAwLCBiZWdpbkluZGV4ID0gMDsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICAgICAgaW5kZXggPSAoaW5kZXggKyBub3JtZGlzdCkgJSBzaXplOworICAgICAgICAgICAgICAgIHRlbXAgPSBsaXN0LnNldChpbmRleCwgdGVtcCk7CisgICAgICAgICAgICAgICAgaWYgKGluZGV4ID09IGJlZ2luSW5kZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgaW5kZXggPSArK2JlZ2luSW5kZXg7CisgICAgICAgICAgICAgICAgICAgIHRlbXAgPSBsaXN0LmdldChiZWdpbkluZGV4KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpbnQgZGl2aWRlSW5kZXggPSAoc2l6ZSAtIG5vcm1kaXN0KSAlIHNpemU7CisgICAgICAgICAgICBMaXN0PE9iamVjdD4gc3VibGlzdDEgPSBsaXN0LnN1Ykxpc3QoMCwgZGl2aWRlSW5kZXgpOworICAgICAgICAgICAgTGlzdDxPYmplY3Q+IHN1Ymxpc3QyID0gbGlzdC5zdWJMaXN0KGRpdmlkZUluZGV4LCBzaXplKTsKKyAgICAgICAgICAgIHJldmVyc2Uoc3VibGlzdDEpOworICAgICAgICAgICAgcmV2ZXJzZShzdWJsaXN0Mik7CisgICAgICAgICAgICByZXZlcnNlKGxpc3QpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VhcmNoZXMgdGhlIHtAY29kZSBsaXN0fSBmb3Ige0Bjb2RlIHN1Ymxpc3R9IGFuZCByZXR1cm5zIHRoZSBiZWdpbm5pbmcKKyAgICAgKiBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZS4KKyAgICAgKiA8cD4KKyAgICAgKiAtMSBpcyByZXR1cm5lZCBpZiB0aGUge0Bjb2RlIHN1Ymxpc3R9IGRvZXMgbm90IGV4aXN0IGluIHtAY29kZSBsaXN0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsaXN0CisgICAgICogICAgICAgICAgICB0aGUgTGlzdCB0byBzZWFyY2gge0Bjb2RlIHN1Ymxpc3R9IGluLgorICAgICAqIEBwYXJhbSBzdWJsaXN0CisgICAgICogICAgICAgICAgICB0aGUgTGlzdCB0byBzZWFyY2ggaW4ge0Bjb2RlIGxpc3R9LgorICAgICAqIEByZXR1cm4gdGhlIGJlZ2lubmluZyBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB7QGNvZGUgc3VibGlzdH0gaW4KKyAgICAgKiAgICAgICAgIHtAY29kZSBsaXN0fSwgb3IgLTEuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgaW5kZXhPZlN1Ykxpc3QoTGlzdDw/PiBsaXN0LCBMaXN0PD8+IHN1Ymxpc3QpIHsKKyAgICAgICAgaW50IHNpemUgPSBsaXN0LnNpemUoKTsKKyAgICAgICAgaW50IHN1Ymxpc3RTaXplID0gc3VibGlzdC5zaXplKCk7CisKKyAgICAgICAgaWYgKHN1Ymxpc3RTaXplID4gc2l6ZSkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHN1Ymxpc3RTaXplID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgLy8gZmluZCB0aGUgZmlyc3QgZWxlbWVudCBvZiBzdWJsaXN0IGluIHRoZSBsaXN0IHRvIGdldCBhIGhlYWQgc3RhcnQKKyAgICAgICAgT2JqZWN0IGZpcnN0T2JqID0gc3VibGlzdC5nZXQoMCk7CisgICAgICAgIGludCBpbmRleCA9IGxpc3QuaW5kZXhPZihmaXJzdE9iaik7CisgICAgICAgIGlmIChpbmRleCA9PSAtMSkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisKKyAgICAgICAgd2hpbGUgKGluZGV4IDwgc2l6ZSAmJiAoc2l6ZSAtIGluZGV4ID49IHN1Ymxpc3RTaXplKSkgeworICAgICAgICAgICAgTGlzdEl0ZXJhdG9yPD8+IGxpc3RJdCA9IGxpc3QubGlzdEl0ZXJhdG9yKGluZGV4KTsKKworICAgICAgICAgICAgaWYgKChmaXJzdE9iaiA9PSBudWxsKSA/IGxpc3RJdC5uZXh0KCkgPT0gbnVsbCA6IGZpcnN0T2JqCisgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMobGlzdEl0Lm5leHQoKSkpIHsKKworICAgICAgICAgICAgICAgIC8vIGl0ZXJhdGUgdGhyb3VnaCB0aGUgZWxlbWVudHMgaW4gc3VibGlzdCB0byBzZWUKKyAgICAgICAgICAgICAgICAvLyBpZiB0aGV5IGFyZSBpbmNsdWRlZCBpbiB0aGUgc2FtZSBvcmRlciBpbiB0aGUgbGlzdAorICAgICAgICAgICAgICAgIExpc3RJdGVyYXRvcjw/PiBzdWJsaXN0SXQgPSBzdWJsaXN0Lmxpc3RJdGVyYXRvcigxKTsKKyAgICAgICAgICAgICAgICBib29sZWFuIGRpZkZvdW5kID0gZmFsc2U7CisgICAgICAgICAgICAgICAgd2hpbGUgKHN1Ymxpc3RJdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgT2JqZWN0IGVsZW1lbnQgPSBzdWJsaXN0SXQubmV4dCgpOworICAgICAgICAgICAgICAgICAgICBpZiAoIWxpc3RJdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoKGVsZW1lbnQgPT0gbnVsbCkgPyBsaXN0SXQubmV4dCgpICE9IG51bGwgOiAhZWxlbWVudAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMobGlzdEl0Lm5leHQoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRpZkZvdW5kID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIEFsbCBlbGVtZW50cyBvZiBzdWJsaXN0IGFyZSBmb3VuZCBpbiBtYWluIGxpc3QKKyAgICAgICAgICAgICAgICAvLyBzdGFydGluZyBmcm9tIGluZGV4LgorICAgICAgICAgICAgICAgIGlmICghZGlmRm91bmQpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIFRoaXMgd2FzIG5vdCB0aGUgc2VxdWVuY2Ugd2Ugd2VyZSBsb29raW5nIGZvciwKKyAgICAgICAgICAgIC8vIGNvbnRpbnVlIHNlYXJjaCBmb3IgdGhlIGZpcnN0T2JqIGluIG1haW4gbGlzdAorICAgICAgICAgICAgLy8gYXQgdGhlIHBvc2l0aW9uIGFmdGVyIGluZGV4LgorICAgICAgICAgICAgaW5kZXgrKzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VhcmNoZXMgdGhlIHtAY29kZSBsaXN0fSBmb3Ige0Bjb2RlIHN1Ymxpc3R9IGFuZCByZXR1cm5zIHRoZSBiZWdpbm5pbmcKKyAgICAgKiBpbmRleCBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlLgorICAgICAqIDxwPgorICAgICAqIC0xIGlzIHJldHVybmVkIGlmIHRoZSB7QGNvZGUgc3VibGlzdH0gZG9lcyBub3QgZXhpc3QgaW4ge0Bjb2RlIGxpc3R9LgorICAgICAqCisgICAgICogQHBhcmFtIGxpc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IHRvIHNlYXJjaCB7QGNvZGUgc3VibGlzdH0gaW4uCisgICAgICogQHBhcmFtIHN1Ymxpc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IHRvIHNlYXJjaCBpbiB7QGNvZGUgbGlzdH0uCisgICAgICogQHJldHVybiB0aGUgYmVnaW5uaW5nIGluZGV4IG9mIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2Yge0Bjb2RlIHN1Ymxpc3R9IGluCisgICAgICogICAgICAgICB7QGNvZGUgbGlzdH0sIG9yIC0xLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGxhc3RJbmRleE9mU3ViTGlzdChMaXN0PD8+IGxpc3QsIExpc3Q8Pz4gc3VibGlzdCkgeworICAgICAgICBpbnQgc3VibGlzdFNpemUgPSBzdWJsaXN0LnNpemUoKTsKKyAgICAgICAgaW50IHNpemUgPSBsaXN0LnNpemUoKTsKKworICAgICAgICBpZiAoc3VibGlzdFNpemUgPiBzaXplKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc3VibGlzdFNpemUgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHNpemU7CisgICAgICAgIH0KKworICAgICAgICAvLyBmaW5kIHRoZSBsYXN0IGVsZW1lbnQgb2Ygc3VibGlzdCBpbiB0aGUgbGlzdCB0byBnZXQgYSBoZWFkIHN0YXJ0CisgICAgICAgIE9iamVjdCBsYXN0T2JqID0gc3VibGlzdC5nZXQoc3VibGlzdFNpemUgLSAxKTsKKyAgICAgICAgaW50IGluZGV4ID0gbGlzdC5sYXN0SW5kZXhPZihsYXN0T2JqKTsKKworICAgICAgICB3aGlsZSAoKGluZGV4ID4gLTEpICYmIChpbmRleCArIDEgPj0gc3VibGlzdFNpemUpKSB7CisgICAgICAgICAgICBMaXN0SXRlcmF0b3I8Pz4gbGlzdEl0ID0gbGlzdC5saXN0SXRlcmF0b3IoaW5kZXggKyAxKTsKKworICAgICAgICAgICAgaWYgKChsYXN0T2JqID09IG51bGwpID8gbGlzdEl0LnByZXZpb3VzKCkgPT0gbnVsbCA6IGxhc3RPYmoKKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhsaXN0SXQucHJldmlvdXMoKSkpIHsKKyAgICAgICAgICAgICAgICAvLyBpdGVyYXRlIHRocm91Z2ggdGhlIGVsZW1lbnRzIGluIHN1Ymxpc3QgdG8gc2VlCisgICAgICAgICAgICAgICAgLy8gaWYgdGhleSBhcmUgaW5jbHVkZWQgaW4gdGhlIHNhbWUgb3JkZXIgaW4gdGhlIGxpc3QKKyAgICAgICAgICAgICAgICBMaXN0SXRlcmF0b3I8Pz4gc3VibGlzdEl0ID0gc3VibGlzdAorICAgICAgICAgICAgICAgICAgICAgICAgLmxpc3RJdGVyYXRvcihzdWJsaXN0U2l6ZSAtIDEpOworICAgICAgICAgICAgICAgIGJvb2xlYW4gZGlmRm91bmQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB3aGlsZSAoc3VibGlzdEl0Lmhhc1ByZXZpb3VzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgT2JqZWN0IGVsZW1lbnQgPSBzdWJsaXN0SXQucHJldmlvdXMoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFsaXN0SXQuaGFzUHJldmlvdXMoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmICgoZWxlbWVudCA9PSBudWxsKSA/IGxpc3RJdC5wcmV2aW91cygpICE9IG51bGwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICFlbGVtZW50LmVxdWFscyhsaXN0SXQucHJldmlvdXMoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRpZkZvdW5kID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIEFsbCBlbGVtZW50cyBvZiBzdWJsaXN0IGFyZSBmb3VuZCBpbiBtYWluIGxpc3QKKyAgICAgICAgICAgICAgICAvLyBzdGFydGluZyBmcm9tIGxpc3RJdC5uZXh0SW5kZXgoKS4KKyAgICAgICAgICAgICAgICBpZiAoIWRpZkZvdW5kKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBsaXN0SXQubmV4dEluZGV4KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gVGhpcyB3YXMgbm90IHRoZSBzZXF1ZW5jZSB3ZSB3ZXJlIGxvb2tpbmcgZm9yLAorICAgICAgICAgICAgLy8gY29udGludWUgc2VhcmNoIGZvciB0aGUgbGFzdE9iaiBpbiBtYWluIGxpc3QKKyAgICAgICAgICAgIC8vIGF0IHRoZSBwb3NpdGlvbiBiZWZvcmUgaW5kZXguCisgICAgICAgICAgICBpbmRleC0tOworICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIHtAY29kZSBBcnJheUxpc3R9IHdpdGggYWxsIHRoZSBlbGVtZW50cyBpbiB0aGUge0Bjb2RlCisgICAgICogZW51bWVyYXRpb259LiBUaGUgZWxlbWVudHMgaW4gdGhlIHJldHVybmVkIHtAY29kZSBBcnJheUxpc3R9IGFyZSBpbiB0aGUKKyAgICAgKiBzYW1lIG9yZGVyIGFzIGluIHRoZSB7QGNvZGUgZW51bWVyYXRpb259LgorICAgICAqCisgICAgICogQHBhcmFtIGVudW1lcmF0aW9uCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIHtAbGluayBFbnVtZXJhdGlvbn0uCisgICAgICogQHJldHVybiBhbiB7QGNvZGUgQXJyYXlMaXN0fSBmcm9tIHtAY29kZSBlbnVtZXJhdGlvbn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8VD4gQXJyYXlMaXN0PFQ+IGxpc3QoRW51bWVyYXRpb248VD4gZW51bWVyYXRpb24pIHsKKyAgICAgICAgQXJyYXlMaXN0PFQ+IGxpc3QgPSBuZXcgQXJyYXlMaXN0PFQ+KCk7CisgICAgICAgIHdoaWxlIChlbnVtZXJhdGlvbi5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgbGlzdC5hZGQoZW51bWVyYXRpb24ubmV4dEVsZW1lbnQoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGxpc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHdyYXBwZXIgb24gdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIHdoaWNoIHN5bmNocm9uaXplcyBhbGwKKyAgICAgKiBhY2Nlc3MgdG8gdGhlIGNvbGxlY3Rpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIENvbGxlY3Rpb24gdG8gd3JhcCBpbiBhIHN5bmNocm9uaXplZCBjb2xsZWN0aW9uLgorICAgICAqIEByZXR1cm4gYSBzeW5jaHJvbml6ZWQgQ29sbGVjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUPiBDb2xsZWN0aW9uPFQ+IHN5bmNocm9uaXplZENvbGxlY3Rpb24oCisgICAgICAgICAgICBDb2xsZWN0aW9uPFQ+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgaWYgKGNvbGxlY3Rpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBTeW5jaHJvbml6ZWRDb2xsZWN0aW9uPFQ+KGNvbGxlY3Rpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB3cmFwcGVyIG9uIHRoZSBzcGVjaWZpZWQgTGlzdCB3aGljaCBzeW5jaHJvbml6ZXMgYWxsIGFjY2VzcyB0bworICAgICAqIHRoZSBMaXN0LgorICAgICAqCisgICAgICogQHBhcmFtIGxpc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBMaXN0IHRvIHdyYXAgaW4gYSBzeW5jaHJvbml6ZWQgbGlzdC4KKyAgICAgKiBAcmV0dXJuIGEgc3luY2hyb25pemVkIExpc3QuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8VD4gTGlzdDxUPiBzeW5jaHJvbml6ZWRMaXN0KExpc3Q8VD4gbGlzdCkgeworICAgICAgICBpZiAobGlzdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobGlzdCBpbnN0YW5jZW9mIFJhbmRvbUFjY2VzcykgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBTeW5jaHJvbml6ZWRSYW5kb21BY2Nlc3NMaXN0PFQ+KGxpc3QpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU3luY2hyb25pemVkTGlzdDxUPihsaXN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgd3JhcHBlciBvbiB0aGUgc3BlY2lmaWVkIG1hcCB3aGljaCBzeW5jaHJvbml6ZXMgYWxsIGFjY2VzcyB0bworICAgICAqIHRoZSBtYXAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWFwCisgICAgICogICAgICAgICAgICB0aGUgbWFwIHRvIHdyYXAgaW4gYSBzeW5jaHJvbml6ZWQgbWFwLgorICAgICAqIEByZXR1cm4gYSBzeW5jaHJvbml6ZWQgTWFwLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPEssIFY+IE1hcDxLLCBWPiBzeW5jaHJvbml6ZWRNYXAoTWFwPEssIFY+IG1hcCkgeworICAgICAgICBpZiAobWFwID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU3luY2hyb25pemVkTWFwPEssIFY+KG1hcCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHdyYXBwZXIgb24gdGhlIHNwZWNpZmllZCBzZXQgd2hpY2ggc3luY2hyb25pemVzIGFsbCBhY2Nlc3MgdG8KKyAgICAgKiB0aGUgc2V0LgorICAgICAqCisgICAgICogQHBhcmFtIHNldAorICAgICAqICAgICAgICAgICAgdGhlIHNldCB0byB3cmFwIGluIGEgc3luY2hyb25pemVkIHNldC4KKyAgICAgKiBAcmV0dXJuIGEgc3luY2hyb25pemVkIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxFPiBTZXQ8RT4gc3luY2hyb25pemVkU2V0KFNldDxFPiBzZXQpIHsKKyAgICAgICAgaWYgKHNldCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFN5bmNocm9uaXplZFNldDxFPihzZXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB3cmFwcGVyIG9uIHRoZSBzcGVjaWZpZWQgc29ydGVkIG1hcCB3aGljaCBzeW5jaHJvbml6ZXMgYWxsCisgICAgICogYWNjZXNzIHRvIHRoZSBzb3J0ZWQgbWFwLgorICAgICAqCisgICAgICogQHBhcmFtIG1hcAorICAgICAqICAgICAgICAgICAgdGhlIHNvcnRlZCBtYXAgdG8gd3JhcCBpbiBhIHN5bmNocm9uaXplZCBzb3J0ZWQgbWFwLgorICAgICAqIEByZXR1cm4gYSBzeW5jaHJvbml6ZWQgc29ydGVkIG1hcC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxLLCBWPiBTb3J0ZWRNYXA8SywgVj4gc3luY2hyb25pemVkU29ydGVkTWFwKAorICAgICAgICAgICAgU29ydGVkTWFwPEssIFY+IG1hcCkgeworICAgICAgICBpZiAobWFwID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU3luY2hyb25pemVkU29ydGVkTWFwPEssIFY+KG1hcCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHdyYXBwZXIgb24gdGhlIHNwZWNpZmllZCBzb3J0ZWQgc2V0IHdoaWNoIHN5bmNocm9uaXplcyBhbGwKKyAgICAgKiBhY2Nlc3MgdG8gdGhlIHNvcnRlZCBzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2V0CisgICAgICogICAgICAgICAgICB0aGUgc29ydGVkIHNldCB0byB3cmFwIGluIGEgc3luY2hyb25pemVkIHNvcnRlZCBzZXQuCisgICAgICogQHJldHVybiBhIHN5bmNocm9uaXplZCBzb3J0ZWQgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPEU+IFNvcnRlZFNldDxFPiBzeW5jaHJvbml6ZWRTb3J0ZWRTZXQoU29ydGVkU2V0PEU+IHNldCkgeworICAgICAgICBpZiAoc2V0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU3luY2hyb25pemVkU29ydGVkU2V0PEU+KHNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHdyYXBwZXIgb24gdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIHdoaWNoIHRocm93cyBhbgorICAgICAqIHtAY29kZSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gd2hlbmV2ZXIgYW4gYXR0ZW1wdCBpcyBtYWRlIHRvCisgICAgICogbW9kaWZ5IHRoZSBjb2xsZWN0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIHRvIHdyYXAgaW4gYW4gdW5tb2RpZmlhYmxlIGNvbGxlY3Rpb24uCisgICAgICogQHJldHVybiBhbiB1bm1vZGlmaWFibGUgY29sbGVjdGlvbi4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgc3RhdGljIDxFPiBDb2xsZWN0aW9uPEU+IHVubW9kaWZpYWJsZUNvbGxlY3Rpb24oCisgICAgICAgICAgICBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjb2xsZWN0aW9uKSB7CisgICAgICAgIGlmIChjb2xsZWN0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgVW5tb2RpZmlhYmxlQ29sbGVjdGlvbjxFPigoQ29sbGVjdGlvbjxFPikgY29sbGVjdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHdyYXBwZXIgb24gdGhlIHNwZWNpZmllZCBsaXN0IHdoaWNoIHRocm93cyBhbgorICAgICAqIHtAY29kZSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gd2hlbmV2ZXIgYW4gYXR0ZW1wdCBpcyBtYWRlIHRvCisgICAgICogbW9kaWZ5IHRoZSBsaXN0LgorICAgICAqCisgICAgICogQHBhcmFtIGxpc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0IHRvIHdyYXAgaW4gYW4gdW5tb2RpZmlhYmxlIGxpc3QuCisgICAgICogQHJldHVybiBhbiB1bm1vZGlmaWFibGUgTGlzdC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgc3RhdGljIDxFPiBMaXN0PEU+IHVubW9kaWZpYWJsZUxpc3QoTGlzdDw/IGV4dGVuZHMgRT4gbGlzdCkgeworICAgICAgICBpZiAobGlzdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobGlzdCBpbnN0YW5jZW9mIFJhbmRvbUFjY2VzcykgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBVbm1vZGlmaWFibGVSYW5kb21BY2Nlc3NMaXN0PEU+KChMaXN0PEU+KSBsaXN0KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFVubW9kaWZpYWJsZUxpc3Q8RT4oKExpc3Q8RT4pIGxpc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB3cmFwcGVyIG9uIHRoZSBzcGVjaWZpZWQgbWFwIHdoaWNoIHRocm93cyBhbgorICAgICAqIHtAY29kZSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gd2hlbmV2ZXIgYW4gYXR0ZW1wdCBpcyBtYWRlIHRvCisgICAgICogbW9kaWZ5IHRoZSBtYXAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWFwCisgICAgICogICAgICAgICAgICB0aGUgbWFwIHRvIHdyYXAgaW4gYW4gdW5tb2RpZmlhYmxlIG1hcC4KKyAgICAgKiBAcmV0dXJuIGEgdW5tb2RpZmlhYmxlIG1hcC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgc3RhdGljIDxLLCBWPiBNYXA8SywgVj4gdW5tb2RpZmlhYmxlTWFwKAorICAgICAgICAgICAgTWFwPD8gZXh0ZW5kcyBLLCA/IGV4dGVuZHMgVj4gbWFwKSB7CisgICAgICAgIGlmIChtYXAgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBVbm1vZGlmaWFibGVNYXA8SywgVj4oKE1hcDxLLCBWPikgbWFwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgd3JhcHBlciBvbiB0aGUgc3BlY2lmaWVkIHNldCB3aGljaCB0aHJvd3MgYW4KKyAgICAgKiB7QGNvZGUgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259IHdoZW5ldmVyIGFuIGF0dGVtcHQgaXMgbWFkZSB0bworICAgICAqIG1vZGlmeSB0aGUgc2V0LgorICAgICAqCisgICAgICogQHBhcmFtIHNldAorICAgICAqICAgICAgICAgICAgdGhlIHNldCB0byB3cmFwIGluIGFuIHVubW9kaWZpYWJsZSBzZXQuCisgICAgICogQHJldHVybiBhIHVubW9kaWZpYWJsZSBzZXQKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgc3RhdGljIDxFPiBTZXQ8RT4gdW5tb2RpZmlhYmxlU2V0KFNldDw/IGV4dGVuZHMgRT4gc2V0KSB7CisgICAgICAgIGlmIChzZXQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBVbm1vZGlmaWFibGVTZXQ8RT4oKFNldDxFPikgc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgd3JhcHBlciBvbiB0aGUgc3BlY2lmaWVkIHNvcnRlZCBtYXAgd2hpY2ggdGhyb3dzIGFuCisgICAgICoge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufSB3aGVuZXZlciBhbiBhdHRlbXB0IGlzIG1hZGUgdG8KKyAgICAgKiBtb2RpZnkgdGhlIHNvcnRlZCBtYXAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWFwCisgICAgICogICAgICAgICAgICB0aGUgc29ydGVkIG1hcCB0byB3cmFwIGluIGFuIHVubW9kaWZpYWJsZSBzb3J0ZWQgbWFwLgorICAgICAqIEByZXR1cm4gYSB1bm1vZGlmaWFibGUgc29ydGVkIG1hcAorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzdGF0aWMgPEssIFY+IFNvcnRlZE1hcDxLLCBWPiB1bm1vZGlmaWFibGVTb3J0ZWRNYXAoCisgICAgICAgICAgICBTb3J0ZWRNYXA8SywgPyBleHRlbmRzIFY+IG1hcCkgeworICAgICAgICBpZiAobWFwID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgVW5tb2RpZmlhYmxlU29ydGVkTWFwPEssIFY+KChTb3J0ZWRNYXA8SywgVj4pIG1hcCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHdyYXBwZXIgb24gdGhlIHNwZWNpZmllZCBzb3J0ZWQgc2V0IHdoaWNoIHRocm93cyBhbgorICAgICAqIHtAY29kZSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gd2hlbmV2ZXIgYW4gYXR0ZW1wdCBpcyBtYWRlIHRvCisgICAgICogbW9kaWZ5IHRoZSBzb3J0ZWQgc2V0LgorICAgICAqCisgICAgICogQHBhcmFtIHNldAorICAgICAqICAgICAgICAgICAgdGhlIHNvcnRlZCBzZXQgdG8gd3JhcCBpbiBhbiB1bm1vZGlmaWFibGUgc29ydGVkIHNldC4KKyAgICAgKiBAcmV0dXJuIGEgdW5tb2RpZmlhYmxlIHNvcnRlZCBzZXQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8RT4gU29ydGVkU2V0PEU+IHVubW9kaWZpYWJsZVNvcnRlZFNldChTb3J0ZWRTZXQ8RT4gc2V0KSB7CisgICAgICAgIGlmIChzZXQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBVbm1vZGlmaWFibGVTb3J0ZWRTZXQ8RT4oc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIHtAY29kZSBDb2xsZWN0aW9ufSB0aGF0IG1hdGNoIHRoZQorICAgICAqIHtAY29kZSBPYmplY3R9IHBhc3NlZC4gSWYgdGhlIHtAY29kZSBPYmplY3R9IGlzIHtAY29kZSBudWxsfSwgdGhlbiB0aGUKKyAgICAgKiBudW1iZXIgb2Yge0Bjb2RlIG51bGx9IGVsZW1lbnRzIGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ29sbGVjdGlvbn0gdG8gc2VhcmNoLgorICAgICAqIEBwYXJhbSBvCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIE9iamVjdH0gdG8gc2VhcmNoIGZvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgbWF0Y2hpbmcgZWxlbWVudHMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgQ29sbGVjdGlvbn0gcGFyYW1ldGVyIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZnJlcXVlbmN5KENvbGxlY3Rpb248Pz4gYywgT2JqZWN0IG8pIHsKKyAgICAgICAgaWYgKGMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICBpbnQgcmVzdWx0ID0gMDsKKyAgICAgICAgSXRlcmF0b3I8Pz4gaXRyID0gYy5pdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoaXRyLmhhc05leHQoKSkgeworICAgICAgICAgICAgT2JqZWN0IGUgPSBpdHIubmV4dCgpOworICAgICAgICAgICAgaWYgKG8gPT0gbnVsbCA/IGUgPT0gbnVsbCA6IG8uZXF1YWxzKGUpKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0Kys7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgdHlwZS1zYWZlIGVtcHR5LCBpbW11dGFibGUge0BsaW5rIExpc3R9LgorICAgICAqCisgICAgICogQHJldHVybiBhbiBlbXB0eSB7QGxpbmsgTGlzdH0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqIEBzZWUgI0VNUFRZX0xJU1QKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIDxUPiBMaXN0PFQ+IGVtcHR5TGlzdCgpIHsKKyAgICAgICAgcmV0dXJuIEVNUFRZX0xJU1Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHR5cGUtc2FmZSBlbXB0eSwgaW1tdXRhYmxlIHtAbGluayBTZXR9LgorICAgICAqCisgICAgICogQHJldHVybiBhbiBlbXB0eSB7QGxpbmsgU2V0fS4KKyAgICAgKiBAc2luY2UgMS41CisgICAgICogQHNlZSAjRU1QVFlfU0VUCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCA8VD4gU2V0PFQ+IGVtcHR5U2V0KCkgeworICAgICAgICByZXR1cm4gRU1QVFlfU0VUOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB0eXBlLXNhZmUgZW1wdHksIGltbXV0YWJsZSB7QGxpbmsgTWFwfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gZW1wdHkge0BsaW5rIE1hcH0uCisgICAgICogQHNpbmNlIDEuNQorICAgICAqIEBzZWUgI0VNUFRZX01BUAorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgPEssIFY+IE1hcDxLLCBWPiBlbXB0eU1hcCgpIHsKKyAgICAgICAgcmV0dXJuIEVNUFRZX01BUDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGVudW1lcmF0aW9uIGNvbnRhaW5pbmcgbm8gZWxlbWVudHMuCisgICAgICogQGhpZGUgMS43CisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN0YXRpYyA8VD4gRW51bWVyYXRpb248VD4gZW1wdHlFbnVtZXJhdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIChFbnVtZXJhdGlvbjxUPikgRU1QVFlfRU5VTUVSQVRJT047CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpdGVyYXRvciBjb250YWluaW5nIG5vIGVsZW1lbnRzLgorICAgICAqIEBoaWRlIDEuNworICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzdGF0aWMgPFQ+IEl0ZXJhdG9yPFQ+IGVtcHR5SXRlcmF0b3IoKSB7CisgICAgICAgIHJldHVybiAoSXRlcmF0b3I8VD4pIEVNUFRZX0lURVJBVE9SOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBsaXN0IGl0ZXJhdG9yIGNvbnRhaW5pbmcgbm8gZWxlbWVudHMuCisgICAgICogQGhpZGUgMS43CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8VD4gTGlzdEl0ZXJhdG9yPFQ+IGVtcHR5TGlzdEl0ZXJhdG9yKCkgeworICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuPFQ+ZW1wdHlMaXN0KCkubGlzdEl0ZXJhdG9yKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGR5bmFtaWNhbGx5IHR5cGVzYWZlIHZpZXcgb2YgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uLiBUcnlpbmcKKyAgICAgKiB0byBpbnNlcnQgYW4gZWxlbWVudCBvZiB0aGUgd3JvbmcgdHlwZSBpbnRvIHRoaXMgY29sbGVjdGlvbiB0aHJvd3MgYQorICAgICAqIHtAY29kZSBDbGFzc0Nhc3RFeGNlcHRpb259LiBBdCBjcmVhdGlvbiB0aW1lIHRoZSB0eXBlcyBpbiB7QGNvZGUgY30gYXJlCisgICAgICogbm90IGNoZWNrZWQgZm9yIGNvcnJlY3QgdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY29sbGVjdGlvbiB0byBiZSB3cmFwcGVkIGluIGEgdHlwZXNhZmUgY29sbGVjdGlvbi4KKyAgICAgKiBAcGFyYW0gdHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHR5cGUgb2YgdGhlIGVsZW1lbnRzIHBlcm1pdHRlZCB0byBpbnNlcnQuCisgICAgICogQHJldHVybiBhIHR5cGVzYWZlIGNvbGxlY3Rpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8RT4gQ29sbGVjdGlvbjxFPiBjaGVja2VkQ29sbGVjdGlvbihDb2xsZWN0aW9uPEU+IGMsCisgICAgICAgICAgICBDbGFzczxFPiB0eXBlKSB7CisgICAgICAgIHJldHVybiBuZXcgQ2hlY2tlZENvbGxlY3Rpb248RT4oYywgdHlwZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGR5bmFtaWNhbGx5IHR5cGVzYWZlIHZpZXcgb2YgdGhlIHNwZWNpZmllZCBtYXAuIFRyeWluZyB0bworICAgICAqIGluc2VydCBhbiBlbGVtZW50IG9mIHRoZSB3cm9uZyB0eXBlIGludG8gdGhpcyBtYXAgdGhyb3dzIGEKKyAgICAgKiB7QGNvZGUgQ2xhc3NDYXN0RXhjZXB0aW9ufS4gQXQgY3JlYXRpb24gdGltZSB0aGUgdHlwZXMgaW4ge0Bjb2RlIG19IGFyZQorICAgICAqIG5vdCBjaGVja2VkIGZvciBjb3JyZWN0IHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbQorICAgICAqICAgICAgICAgICAgdGhlIG1hcCB0byBiZSB3cmFwcGVkIGluIGEgdHlwZXNhZmUgbWFwLgorICAgICAqIEBwYXJhbSBrZXlUeXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUga2V5cyBwZXJtaXR0ZWQgdG8gaW5zZXJ0LgorICAgICAqIEBwYXJhbSB2YWx1ZVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSB2YWx1ZXMgcGVybWl0dGVkIHRvIGluc2VydC4KKyAgICAgKiBAcmV0dXJuIGEgdHlwZXNhZmUgbWFwLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPEssIFY+IE1hcDxLLCBWPiBjaGVja2VkTWFwKE1hcDxLLCBWPiBtLCBDbGFzczxLPiBrZXlUeXBlLAorICAgICAgICAgICAgQ2xhc3M8Vj4gdmFsdWVUeXBlKSB7CisgICAgICAgIHJldHVybiBuZXcgQ2hlY2tlZE1hcDxLLCBWPihtLCBrZXlUeXBlLCB2YWx1ZVR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBkeW5hbWljYWxseSB0eXBlc2FmZSB2aWV3IG9mIHRoZSBzcGVjaWZpZWQgbGlzdC4gVHJ5aW5nIHRvCisgICAgICogaW5zZXJ0IGFuIGVsZW1lbnQgb2YgdGhlIHdyb25nIHR5cGUgaW50byB0aGlzIGxpc3QgdGhyb3dzIGEKKyAgICAgKiB7QGNvZGUgQ2xhc3NDYXN0RXhjZXB0aW9ufS4gQXQgY3JlYXRpb24gdGltZSB0aGUgdHlwZXMgaW4ge0Bjb2RlIGxpc3R9CisgICAgICogYXJlIG5vdCBjaGVja2VkIGZvciBjb3JyZWN0IHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGlzdAorICAgICAqICAgICAgICAgICAgdGhlIGxpc3QgdG8gYmUgd3JhcHBlZCBpbiBhIHR5cGVzYWZlIGxpc3QuCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSBlbGVtZW50cyBwZXJtaXR0ZWQgdG8gaW5zZXJ0LgorICAgICAqIEByZXR1cm4gYSB0eXBlc2FmZSBsaXN0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPEU+IExpc3Q8RT4gY2hlY2tlZExpc3QoTGlzdDxFPiBsaXN0LCBDbGFzczxFPiB0eXBlKSB7CisgICAgICAgIGlmIChsaXN0IGluc3RhbmNlb2YgUmFuZG9tQWNjZXNzKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IENoZWNrZWRSYW5kb21BY2Nlc3NMaXN0PEU+KGxpc3QsIHR5cGUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgQ2hlY2tlZExpc3Q8RT4obGlzdCwgdHlwZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGR5bmFtaWNhbGx5IHR5cGVzYWZlIHZpZXcgb2YgdGhlIHNwZWNpZmllZCBzZXQuIFRyeWluZyB0bworICAgICAqIGluc2VydCBhbiBlbGVtZW50IG9mIHRoZSB3cm9uZyB0eXBlIGludG8gdGhpcyBzZXQgdGhyb3dzIGEKKyAgICAgKiB7QGNvZGUgQ2xhc3NDYXN0RXhjZXB0aW9ufS4gQXQgY3JlYXRpb24gdGltZSB0aGUgdHlwZXMgaW4ge0Bjb2RlIHN9IGFyZQorICAgICAqIG5vdCBjaGVja2VkIGZvciBjb3JyZWN0IHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIHNldCB0byBiZSB3cmFwcGVkIGluIGEgdHlwZXNhZmUgc2V0LgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgZWxlbWVudHMgcGVybWl0dGVkIHRvIGluc2VydC4KKyAgICAgKiBAcmV0dXJuIGEgdHlwZXNhZmUgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPEU+IFNldDxFPiBjaGVja2VkU2V0KFNldDxFPiBzLCBDbGFzczxFPiB0eXBlKSB7CisgICAgICAgIHJldHVybiBuZXcgQ2hlY2tlZFNldDxFPihzLCB0eXBlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgZHluYW1pY2FsbHkgdHlwZXNhZmUgdmlldyBvZiB0aGUgc3BlY2lmaWVkIHNvcnRlZCBtYXAuIFRyeWluZworICAgICAqIHRvIGluc2VydCBhbiBlbGVtZW50IG9mIHRoZSB3cm9uZyB0eXBlIGludG8gdGhpcyBzb3J0ZWQgbWFwIHRocm93cyBhCisgICAgICoge0Bjb2RlIENsYXNzQ2FzdEV4Y2VwdGlvbn0uIEF0IGNyZWF0aW9uIHRpbWUgdGhlIHR5cGVzIGluIHtAY29kZSBtfSBhcmUKKyAgICAgKiBub3QgY2hlY2tlZCBmb3IgY29ycmVjdCB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3J0ZWQgbWFwIHRvIGJlIHdyYXBwZWQgaW4gYSB0eXBlc2FmZSBzb3J0ZWQgbWFwLgorICAgICAqIEBwYXJhbSBrZXlUeXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUga2V5cyBwZXJtaXR0ZWQgdG8gaW5zZXJ0LgorICAgICAqIEBwYXJhbSB2YWx1ZVR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSB2YWx1ZXMgcGVybWl0dGVkIHRvIGluc2VydC4KKyAgICAgKiBAcmV0dXJuIGEgdHlwZXNhZmUgc29ydGVkIG1hcC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxLLCBWPiBTb3J0ZWRNYXA8SywgVj4gY2hlY2tlZFNvcnRlZE1hcChTb3J0ZWRNYXA8SywgVj4gbSwKKyAgICAgICAgICAgIENsYXNzPEs+IGtleVR5cGUsIENsYXNzPFY+IHZhbHVlVHlwZSkgeworICAgICAgICByZXR1cm4gbmV3IENoZWNrZWRTb3J0ZWRNYXA8SywgVj4obSwga2V5VHlwZSwgdmFsdWVUeXBlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgZHluYW1pY2FsbHkgdHlwZXNhZmUgdmlldyBvZiB0aGUgc3BlY2lmaWVkIHNvcnRlZCBzZXQuIFRyeWluZworICAgICAqIHRvIGluc2VydCBhbiBlbGVtZW50IG9mIHRoZSB3cm9uZyB0eXBlIGludG8gdGhpcyBzb3J0ZWQgc2V0IHRocm93cyBhCisgICAgICoge0Bjb2RlIENsYXNzQ2FzdEV4Y2VwdGlvbn0uIEF0IGNyZWF0aW9uIHRpbWUgdGhlIHR5cGVzIGluIHtAY29kZSBzfSBhcmUKKyAgICAgKiBub3QgY2hlY2tlZCBmb3IgY29ycmVjdCB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3J0ZWQgc2V0IHRvIGJlIHdyYXBwZWQgaW4gYSB0eXBlc2FmZSBzb3J0ZWQgc2V0LgorICAgICAqIEBwYXJhbSB0eXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgZWxlbWVudHMgcGVybWl0dGVkIHRvIGluc2VydC4KKyAgICAgKiBAcmV0dXJuIGEgdHlwZXNhZmUgc29ydGVkIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxFPiBTb3J0ZWRTZXQ8RT4gY2hlY2tlZFNvcnRlZFNldChTb3J0ZWRTZXQ8RT4gcywKKyAgICAgICAgICAgIENsYXNzPEU+IHR5cGUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBDaGVja2VkU29ydGVkU2V0PEU+KHMsIHR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYWxsIHRoZSBzcGVjaWZpZWQgZWxlbWVudHMgdG8gdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIHRoZSBlbGVtZW50cyBhcmUgdG8gYmUgaW5zZXJ0ZWQgaW50by4KKyAgICAgKiBAcGFyYW0gYQorICAgICAqICAgICAgICAgICAgdGhlIGVsZW1lbnRzIHRvIGluc2VydC4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNvbGxlY3Rpb24gY2hhbmdlZCBkdXJpbmcgaW5zZXJ0aW9uLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHRoZSBtZXRob2QgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiB7QGNvZGUgY30gb3Ige0Bjb2RlIGF9IGlzIHtAY29kZSBudWxsfSwgb3Ige0Bjb2RlIGF9CisgICAgICogICAgICAgICAgICAgY29udGFpbnMgb25lIG9yIG1vcmUge0Bjb2RlIG51bGx9IGVsZW1lbnRzIGFuZCB7QGNvZGUgY30KKyAgICAgKiAgICAgICAgICAgICBkb2Vzbid0IHN1cHBvcnQge0Bjb2RlIG51bGx9IGVsZW1lbnRzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYXQgbGVhc3Qgb25lIG9mIHRoZSBlbGVtZW50cyBjYW4ndCBiZSBpbnNlcnRlZCBpbnRvIHRoZQorICAgICAqICAgICAgICAgICAgIGNvbGxlY3Rpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8VD4gYm9vbGVhbiBhZGRBbGwoQ29sbGVjdGlvbjw/IHN1cGVyIFQ+IGMsIFQuLi4gYSkgeworICAgICAgICBib29sZWFuIG1vZGlmaWVkID0gZmFsc2U7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbW9kaWZpZWQgfD0gYy5hZGQoYVtpXSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG1vZGlmaWVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb25zIGhhdmUgbm8gZWxlbWVudHMgaW4gY29tbW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGMxCisgICAgICogICAgICAgICAgICB0aGUgZmlyc3QgY29sbGVjdGlvbi4KKyAgICAgKiBAcGFyYW0gYzIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgY29sbGVjdGlvbi4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgY29sbGVjdGlvbnMgaGF2ZSBubyBlbGVtZW50cyBpbiBjb21tb24sCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgb25lIG9mIHRoZSBjb2xsZWN0aW9ucyBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGRpc2pvaW50KENvbGxlY3Rpb248Pz4gYzEsIENvbGxlY3Rpb248Pz4gYzIpIHsKKyAgICAgICAgaWYgKChjMSBpbnN0YW5jZW9mIFNldCkgJiYgIShjMiBpbnN0YW5jZW9mIFNldCkKKyAgICAgICAgICAgICAgICB8fCAoYzIuc2l6ZSgpKSA+IGMxLnNpemUoKSkgeworICAgICAgICAgICAgQ29sbGVjdGlvbjw/PiB0bXAgPSBjMTsKKyAgICAgICAgICAgIGMxID0gYzI7CisgICAgICAgICAgICBjMiA9IHRtcDsKKyAgICAgICAgfQorICAgICAgICBJdGVyYXRvcjw/PiBpdCA9IGMxLml0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIGlmIChjMi5jb250YWlucyhpdC5uZXh0KCkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiBzcGVjaWZpZWQgb2JqZWN0IGlzIGluc3RhbmNlIG9mIHNwZWNpZmllZCBjbGFzcy4gVXNlZCBmb3IgYQorICAgICAqIGR5bmFtaWNhbGx5IHR5cGVzYWZlIHZpZXcgb2YgdGhlIGNvbGxlY3Rpb25zLgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiAtCisgICAgICogICAgICAgICAgICBvYmplY3QgaXMgdG8gYmUgY2hlY2tlZAorICAgICAqIEBwYXJhbSB0eXBlIC0KKyAgICAgKiAgICAgICAgICAgIGNsYXNzIG9mIG9iamVjdCB0aGF0IHNob3VsZCBiZQorICAgICAqIEByZXR1cm4gc3BlY2lmaWVkIG9iamVjdAorICAgICAqLworICAgIHN0YXRpYyA8RT4gRSBjaGVja1R5cGUoRSBvYmosIENsYXNzPD8gZXh0ZW5kcyBFPiB0eXBlKSB7CisgICAgICAgIGlmIChvYmogIT0gbnVsbCAmJiAhdHlwZS5pc0luc3RhbmNlKG9iaikpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc0Nhc3RFeGNlcHRpb24oIkF0dGVtcHQgdG8gaW5zZXJ0IGVsZW1lbnQgb2YgdHlwZSAiICsgb2JqLmdldENsYXNzKCkgKworICAgICAgICAgICAgICAgICAgICAiIGludG8gY29sbGVjdGlvbiBvZiB0eXBlICIgKyB0eXBlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gb2JqOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzZXQgYmFja2VkIGJ5IHtAY29kZSBtYXB9LgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIG1hcCBpcyBub3QgZW1wdHkKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8RT4gU2V0PEU+IG5ld1NldEZyb21NYXAoTWFwPEUsIEJvb2xlYW4+IG1hcCkgeworICAgICAgICBpZiAobWFwLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBTZXRGcm9tTWFwPEU+KG1hcCk7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBsYXN0LWluLCBmaXJzdC1vdXQgcXVldWUgYXMgYSB2aWV3IG9mIHtAY29kZSBkZXF1ZX0uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8VD4gUXVldWU8VD4gYXNMaWZvUXVldWUoRGVxdWU8VD4gZGVxdWUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBBc0xJRk9RdWV1ZTxUPihkZXF1ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgU2V0RnJvbU1hcDxFPiBleHRlbmRzIEFic3RyYWN0U2V0PEU+IGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjQ1NDY1Nzg1NDc1NzU0Mzg3Nkw7CisKKyAgICAgICAgLy8gbXVzdCBuYW1lZCBhcyBpdCwgdG8gcGFzcyBzZXJpYWxpemF0aW9uIGNvbXBhdGliaWxpdHkgdGVzdC4KKyAgICAgICAgcHJpdmF0ZSBNYXA8RSwgQm9vbGVhbj4gbTsKKworICAgICAgICBwcml2YXRlIHRyYW5zaWVudCBTZXQ8RT4gYmFja2luZ1NldDsKKworICAgICAgICBTZXRGcm9tTWFwKGZpbmFsIE1hcDxFLCBCb29sZWFuPiBtYXApIHsKKyAgICAgICAgICAgIG0gPSBtYXA7CisgICAgICAgICAgICBiYWNraW5nU2V0ID0gbWFwLmtleVNldCgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gYmFja2luZ1NldC5lcXVhbHMob2JqZWN0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgcmV0dXJuIGJhY2tpbmdTZXQuaGFzaENvZGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBhZGQoRSBvYmplY3QpIHsKKyAgICAgICAgICAgIHJldHVybiBtLnB1dChvYmplY3QsIEJvb2xlYW4uVFJVRSkgPT0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgICAgIG0uY2xlYXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuIGJhY2tpbmdTZXQudG9TdHJpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gYmFja2luZ1NldC5jb250YWlucyhvYmplY3QpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQWxsKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbikgeworICAgICAgICAgICAgcmV0dXJuIGJhY2tpbmdTZXQuY29udGFpbnNBbGwoY29sbGVjdGlvbik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgICAgIHJldHVybiBtLmlzRW1wdHkoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIG0ucmVtb3ZlKG9iamVjdCkgIT0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiByZXRhaW5BbGwoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKSB7CisgICAgICAgICAgICByZXR1cm4gYmFja2luZ1NldC5yZXRhaW5BbGwoY29sbGVjdGlvbik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSB7CisgICAgICAgICAgICByZXR1cm4gYmFja2luZ1NldC50b0FycmF5KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIDxUPiBUW10gdG9BcnJheShUW10gY29udGVudHMpIHsKKyAgICAgICAgICAgIHJldHVybiBiYWNraW5nU2V0LnRvQXJyYXkoY29udGVudHMpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBJdGVyYXRvcjxFPiBpdGVyYXRvcigpIHsKKyAgICAgICAgICAgIHJldHVybiBiYWNraW5nU2V0Lml0ZXJhdG9yKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgcmV0dXJuIG0uc2l6ZSgpOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIHN0cmVhbSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICAgICAgc3RyZWFtLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisgICAgICAgICAgICBiYWNraW5nU2V0ID0gbS5rZXlTZXQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEFzTElGT1F1ZXVlPEU+IGV4dGVuZHMgQWJzdHJhY3RRdWV1ZTxFPiBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDE4MDIwMTc3MjU1ODc5NDE3MDhMOworCisgICAgICAgIC8vIG11c3QgbmFtZWQgYXMgaXQsIHRvIHBhc3Mgc2VyaWFsaXphdGlvbiBjb21wYXRpYmlsaXR5IHRlc3QuCisgICAgICAgIHByaXZhdGUgZmluYWwgRGVxdWU8RT4gcTsKKworICAgICAgICBBc0xJRk9RdWV1ZShmaW5hbCBEZXF1ZTxFPiBkZXF1ZSkgeworICAgICAgICAgICAgdGhpcy5xID0gZGVxdWU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEl0ZXJhdG9yPEU+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIHEuaXRlcmF0b3IoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gcS5zaXplKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gb2ZmZXIoRSBvKSB7CisgICAgICAgICAgICByZXR1cm4gcS5vZmZlckZpcnN0KG8pOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBFIHBlZWsoKSB7CisgICAgICAgICAgICByZXR1cm4gcS5wZWVrRmlyc3QoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgRSBwb2xsKCkgeworICAgICAgICAgICAgcmV0dXJuIHEucG9sbEZpcnN0KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gYWRkKEUgbykgeworICAgICAgICAgICAgcS5wdXNoKG8pOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICBxLmNsZWFyKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEUgZWxlbWVudCgpIHsKKyAgICAgICAgICAgIHJldHVybiBxLmdldEZpcnN0KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEUgcmVtb3ZlKCkgeworICAgICAgICAgICAgcmV0dXJuIHEucG9wKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIHEuY29udGFpbnMob2JqZWN0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBjb250YWluc0FsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIHJldHVybiBxLmNvbnRhaW5zQWxsKGNvbGxlY3Rpb24pOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICByZXR1cm4gcS5pc0VtcHR5KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIHJldHVybiBxLnJlbW92ZShvYmplY3QpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIHJlbW92ZUFsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIHJldHVybiBxLnJlbW92ZUFsbChjb2xsZWN0aW9uKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiByZXRhaW5BbGwoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKSB7CisgICAgICAgICAgICByZXR1cm4gcS5yZXRhaW5BbGwoY29sbGVjdGlvbik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSB7CisgICAgICAgICAgICByZXR1cm4gcS50b0FycmF5KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIDxUPiBUW10gdG9BcnJheShUW10gY29udGVudHMpIHsKKyAgICAgICAgICAgIHJldHVybiBxLnRvQXJyYXkoY29udGVudHMpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICByZXR1cm4gcS50b1N0cmluZygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBkeW5hbWljYWxseSB0eXBlc2FmZSB2aWV3IG9mIGEgQ29sbGVjdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBDaGVja2VkQ29sbGVjdGlvbjxFPiBpbXBsZW1lbnRzIENvbGxlY3Rpb248RT4sIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTU3ODkxNDA3ODE4MjAwMTc3NUw7CisKKyAgICAgICAgQ29sbGVjdGlvbjxFPiBjOworCisgICAgICAgIENsYXNzPEU+IHR5cGU7CisKKyAgICAgICAgcHVibGljIENoZWNrZWRDb2xsZWN0aW9uKENvbGxlY3Rpb248RT4gYywgQ2xhc3M8RT4gdHlwZSkgeworICAgICAgICAgICAgaWYgKGMgPT0gbnVsbCB8fCB0eXBlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMuYyA9IGM7CisgICAgICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBjLnNpemUoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICAgICAgcmV0dXJuIGMuaXNFbXB0eSgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvYmopIHsKKyAgICAgICAgICAgIHJldHVybiBjLmNvbnRhaW5zKG9iaik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEl0ZXJhdG9yPEU+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgSXRlcmF0b3I8RT4gaSA9IGMuaXRlcmF0b3IoKTsKKyAgICAgICAgICAgIGlmIChpIGluc3RhbmNlb2YgTGlzdEl0ZXJhdG9yKSB7CisgICAgICAgICAgICAgICAgaSA9IG5ldyBDaGVja2VkTGlzdEl0ZXJhdG9yPEU+KChMaXN0SXRlcmF0b3I8RT4pIGksIHR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSB7CisgICAgICAgICAgICByZXR1cm4gYy50b0FycmF5KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIDxUPiBUW10gdG9BcnJheShUW10gYXJyKSB7CisgICAgICAgICAgICByZXR1cm4gYy50b0FycmF5KGFycik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gYWRkKEUgb2JqKSB7CisgICAgICAgICAgICByZXR1cm4gYy5hZGQoY2hlY2tUeXBlKG9iaiwgdHlwZSkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3Qgb2JqKSB7CisgICAgICAgICAgICByZXR1cm4gYy5yZW1vdmUob2JqKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBjb250YWluc0FsbChDb2xsZWN0aW9uPD8+IGMxKSB7CisgICAgICAgICAgICByZXR1cm4gYy5jb250YWluc0FsbChjMSk7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGFkZEFsbChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjMSkgeworICAgICAgICAgICAgT2JqZWN0W10gYXJyYXkgPSBjMS50b0FycmF5KCk7CisgICAgICAgICAgICBmb3IgKE9iamVjdCBvIDogYXJyYXkpIHsKKyAgICAgICAgICAgICAgICBjaGVja1R5cGUobywgdHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gYy5hZGRBbGwoKExpc3Q8RT4pIEFycmF5cy5hc0xpc3QoYXJyYXkpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiByZW1vdmVBbGwoQ29sbGVjdGlvbjw/PiBjMSkgeworICAgICAgICAgICAgcmV0dXJuIGMucmVtb3ZlQWxsKGMxKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiByZXRhaW5BbGwoQ29sbGVjdGlvbjw/PiBjMSkgeworICAgICAgICAgICAgcmV0dXJuIGMucmV0YWluQWxsKGMxKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgICAgIGMuY2xlYXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuIGMudG9TdHJpbmcoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENsYXNzIHJlcHJlc2VudHMgYSBkeW5hbWljYWxseSB0eXBlc2FmZSB2aWV3IG9mIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBMaXN0SXRlcmF0b3IuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQ2hlY2tlZExpc3RJdGVyYXRvcjxFPiBpbXBsZW1lbnRzIExpc3RJdGVyYXRvcjxFPiB7CisKKyAgICAgICAgcHJpdmF0ZSBMaXN0SXRlcmF0b3I8RT4gaTsKKworICAgICAgICBwcml2YXRlIENsYXNzPEU+IHR5cGU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbnN0cnVjdHMgYSBkeW5hbWljYWxseSB0eXBlc2FmZSB2aWV3IG9mIHRoZSBzcGVjaWZpZWQgTGlzdEl0ZXJhdG9yLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gaSAtCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGxpc3RJdGVyYXRvciBmb3Igd2hpY2ggYSBkeW5hbWljYWxseSB0eXBlc2FmZSB2aWV3IHRvCisgICAgICAgICAqICAgICAgICAgICAgYmUgY29uc3RydWN0ZWQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQ2hlY2tlZExpc3RJdGVyYXRvcihMaXN0SXRlcmF0b3I8RT4gaSwgQ2xhc3M8RT4gdHlwZSkgeworICAgICAgICAgICAgdGhpcy5pID0gaTsKKyAgICAgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiBpLmhhc05leHQoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgRSBuZXh0KCkgeworICAgICAgICAgICAgcmV0dXJuIGkubmV4dCgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgIGkucmVtb3ZlKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzUHJldmlvdXMoKSB7CisgICAgICAgICAgICByZXR1cm4gaS5oYXNQcmV2aW91cygpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBFIHByZXZpb3VzKCkgeworICAgICAgICAgICAgcmV0dXJuIGkucHJldmlvdXMoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IG5leHRJbmRleCgpIHsKKyAgICAgICAgICAgIHJldHVybiBpLm5leHRJbmRleCgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgcHJldmlvdXNJbmRleCgpIHsKKyAgICAgICAgICAgIHJldHVybiBpLnByZXZpb3VzSW5kZXgoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBzZXQoRSBvYmopIHsKKyAgICAgICAgICAgIGkuc2V0KGNoZWNrVHlwZShvYmosIHR5cGUpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBhZGQoRSBvYmopIHsKKyAgICAgICAgICAgIGkuYWRkKGNoZWNrVHlwZShvYmosIHR5cGUpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENsYXNzIHJlcHJlc2VudHMgYSBkeW5hbWljYWxseSB0eXBlc2FmZSB2aWV3IG9mIGEgTGlzdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBDaGVja2VkTGlzdDxFPiBleHRlbmRzIENoZWNrZWRDb2xsZWN0aW9uPEU+IGltcGxlbWVudHMgTGlzdDxFPiB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjUyNDc3MjgyODM5NjczNTZMOworCisgICAgICAgIExpc3Q8RT4gbDsKKworICAgICAgICBwdWJsaWMgQ2hlY2tlZExpc3QoTGlzdDxFPiBsLCBDbGFzczxFPiB0eXBlKSB7CisgICAgICAgICAgICBzdXBlcihsLCB0eXBlKTsKKyAgICAgICAgICAgIHRoaXMubCA9IGw7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGFkZEFsbChpbnQgaW5kZXgsIENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGMxKSB7CisgICAgICAgICAgICBPYmplY3RbXSBhcnJheSA9IGMxLnRvQXJyYXkoKTsKKyAgICAgICAgICAgIGZvciAoT2JqZWN0IG8gOiBhcnJheSkgeworICAgICAgICAgICAgICAgIGNoZWNrVHlwZShvLCB0eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBsLmFkZEFsbChpbmRleCwgKExpc3Q8RT4pIEFycmF5cy5hc0xpc3QoYXJyYXkpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgRSBnZXQoaW50IGluZGV4KSB7CisgICAgICAgICAgICByZXR1cm4gbC5nZXQoaW5kZXgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBFIHNldChpbnQgaW5kZXgsIEUgb2JqKSB7CisgICAgICAgICAgICByZXR1cm4gbC5zZXQoaW5kZXgsIGNoZWNrVHlwZShvYmosIHR5cGUpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBhZGQoaW50IGluZGV4LCBFIG9iaikgeworICAgICAgICAgICAgbC5hZGQoaW5kZXgsIGNoZWNrVHlwZShvYmosIHR5cGUpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgRSByZW1vdmUoaW50IGluZGV4KSB7CisgICAgICAgICAgICByZXR1cm4gbC5yZW1vdmUoaW5kZXgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaW5kZXhPZihPYmplY3Qgb2JqKSB7CisgICAgICAgICAgICByZXR1cm4gbC5pbmRleE9mKG9iaik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBsYXN0SW5kZXhPZihPYmplY3Qgb2JqKSB7CisgICAgICAgICAgICByZXR1cm4gbC5sYXN0SW5kZXhPZihvYmopOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBMaXN0SXRlcmF0b3I8RT4gbGlzdEl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBDaGVja2VkTGlzdEl0ZXJhdG9yPEU+KGwubGlzdEl0ZXJhdG9yKCksIHR5cGUpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBMaXN0SXRlcmF0b3I8RT4gbGlzdEl0ZXJhdG9yKGludCBpbmRleCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBDaGVja2VkTGlzdEl0ZXJhdG9yPEU+KGwubGlzdEl0ZXJhdG9yKGluZGV4KSwgdHlwZSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIExpc3Q8RT4gc3ViTGlzdChpbnQgZnJvbUluZGV4LCBpbnQgdG9JbmRleCkgeworICAgICAgICAgICAgcmV0dXJuIGNoZWNrZWRMaXN0KGwuc3ViTGlzdChmcm9tSW5kZXgsIHRvSW5kZXgpLCB0eXBlKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICAgICAgcmV0dXJuIGwuZXF1YWxzKG9iaik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBsLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBIGR5bmFtaWNhbGx5IHR5cGVzYWZlIHZpZXcgb2YgYSBSYW5kb21BY2Nlc3NMaXN0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIENoZWNrZWRSYW5kb21BY2Nlc3NMaXN0PEU+IGV4dGVuZHMgQ2hlY2tlZExpc3Q8RT4gaW1wbGVtZW50cyBSYW5kb21BY2Nlc3MgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDE2MzgyMDAxMjU0MjMwODgzNjlMOworCisgICAgICAgIHB1YmxpYyBDaGVja2VkUmFuZG9tQWNjZXNzTGlzdChMaXN0PEU+IGwsIENsYXNzPEU+IHR5cGUpIHsKKyAgICAgICAgICAgIHN1cGVyKGwsIHR5cGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBkeW5hbWljYWxseSB0eXBlc2FmZSB2aWV3IG9mIGEgU2V0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIENoZWNrZWRTZXQ8RT4gZXh0ZW5kcyBDaGVja2VkQ29sbGVjdGlvbjxFPiBpbXBsZW1lbnRzIFNldDxFPiB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNDY5NDA0NzgzMzc3NTAxMzgwM0w7CisKKyAgICAgICAgcHVibGljIENoZWNrZWRTZXQoU2V0PEU+IHMsIENsYXNzPEU+IHR5cGUpIHsKKyAgICAgICAgICAgIHN1cGVyKHMsIHR5cGUpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgICAgICByZXR1cm4gYy5lcXVhbHMob2JqKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgcmV0dXJuIGMuaGFzaENvZGUoKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogQSBkeW5hbWljYWxseSB0eXBlc2FmZSB2aWV3IG9mIGEgTWFwLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIENoZWNrZWRNYXA8SywgVj4gaW1wbGVtZW50cyBNYXA8SywgVj4sIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTc0Mjg2MDE0MTAzNDIzNDcyOEw7CisKKyAgICAgICAgTWFwPEssIFY+IG07CisgICAgICAgIENsYXNzPEs+IGtleVR5cGU7CisgICAgICAgIENsYXNzPFY+IHZhbHVlVHlwZTsKKworICAgICAgICBwcml2YXRlIENoZWNrZWRNYXAoTWFwPEssIFY+IG0sIENsYXNzPEs+IGtleVR5cGUsIENsYXNzPFY+IHZhbHVlVHlwZSkgeworICAgICAgICAgICAgaWYgKG0gPT0gbnVsbCB8fCBrZXlUeXBlID09IG51bGwgfHwgdmFsdWVUeXBlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMubSA9IG07CisgICAgICAgICAgICB0aGlzLmtleVR5cGUgPSBrZXlUeXBlOworICAgICAgICAgICAgdGhpcy52YWx1ZVR5cGUgPSB2YWx1ZVR5cGU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgcmV0dXJuIG0uc2l6ZSgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICByZXR1cm4gbS5pc0VtcHR5KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnNLZXkoT2JqZWN0IGtleSkgeworICAgICAgICAgICAgcmV0dXJuIG0uY29udGFpbnNLZXkoa2V5KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ZhbHVlKE9iamVjdCB2YWx1ZSkgeworICAgICAgICAgICAgcmV0dXJuIG0uY29udGFpbnNWYWx1ZSh2YWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFYgZ2V0KE9iamVjdCBrZXkpIHsKKyAgICAgICAgICAgIHJldHVybiBtLmdldChrZXkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBWIHB1dChLIGtleSwgViB2YWx1ZSkgeworICAgICAgICAgICAgcmV0dXJuIG0ucHV0KGNoZWNrVHlwZShrZXksIGtleVR5cGUpLCBjaGVja1R5cGUodmFsdWUsIHZhbHVlVHlwZSkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBWIHJlbW92ZShPYmplY3Qga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gbS5yZW1vdmUoa2V5KTsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgcHV0QWxsKE1hcDw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+IG1hcCkgeworICAgICAgICAgICAgaW50IHNpemUgPSBtYXAuc2l6ZSgpOworICAgICAgICAgICAgaWYgKHNpemUgPT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIE1hcC5FbnRyeTw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+W10gZW50cmllcyA9IG5ldyBNYXAuRW50cnlbc2l6ZV07CisgICAgICAgICAgICBJdGVyYXRvcjw/IGV4dGVuZHMgTWFwLkVudHJ5PD8gZXh0ZW5kcyBLLCA/IGV4dGVuZHMgVj4+IGl0ID0gbWFwCisgICAgICAgICAgICAgICAgICAgIC5lbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICAgICAgICAgIE1hcC5FbnRyeTw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+IGUgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgY2hlY2tUeXBlKGUuZ2V0S2V5KCksIGtleVR5cGUpOworICAgICAgICAgICAgICAgIGNoZWNrVHlwZShlLmdldFZhbHVlKCksIHZhbHVlVHlwZSk7CisgICAgICAgICAgICAgICAgZW50cmllc1tpXSA9IGU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICAgICAgICAgIG0ucHV0KGVudHJpZXNbaV0uZ2V0S2V5KCksIGVudHJpZXNbaV0uZ2V0VmFsdWUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICBtLmNsZWFyKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFNldDxLPiBrZXlTZXQoKSB7CisgICAgICAgICAgICByZXR1cm4gbS5rZXlTZXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgQ29sbGVjdGlvbjxWPiB2YWx1ZXMoKSB7CisgICAgICAgICAgICByZXR1cm4gbS52YWx1ZXMoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU2V0PE1hcC5FbnRyeTxLLCBWPj4gZW50cnlTZXQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IENoZWNrZWRFbnRyeVNldDxLLCBWPihtLmVudHJ5U2V0KCksIHZhbHVlVHlwZSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgICAgIHJldHVybiBtLmVxdWFscyhvYmopOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICByZXR1cm4gbS5oYXNoQ29kZSgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICByZXR1cm4gbS50b1N0cmluZygpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEEgZHluYW1pY2FsbHkgdHlwZXNhZmUgdmlldyBvZiBhIE1hcC5FbnRyeS4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIENoZWNrZWRFbnRyeTxLLCBWPiBpbXBsZW1lbnRzIE1hcC5FbnRyeTxLLCBWPiB7CisgICAgICAgICAgICBNYXAuRW50cnk8SywgVj4gZTsKKyAgICAgICAgICAgIENsYXNzPFY+IHZhbHVlVHlwZTsKKworICAgICAgICAgICAgcHVibGljIENoZWNrZWRFbnRyeShNYXAuRW50cnk8SywgVj4gZSwgQ2xhc3M8Vj4gdmFsdWVUeXBlKSB7CisgICAgICAgICAgICAgICAgaWYgKGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGhpcy5lID0gZTsKKyAgICAgICAgICAgICAgICB0aGlzLnZhbHVlVHlwZSA9IHZhbHVlVHlwZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBLIGdldEtleSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZS5nZXRLZXkoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBWIGdldFZhbHVlKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBlLmdldFZhbHVlKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgViBzZXRWYWx1ZShWIG9iaikgeworICAgICAgICAgICAgICAgIHJldHVybiBlLnNldFZhbHVlKGNoZWNrVHlwZShvYmosIHZhbHVlVHlwZSkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZS5lcXVhbHMob2JqKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGUuaGFzaENvZGUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBBIGR5bmFtaWNhbGx5IHR5cGVzYWZlIHZpZXcgb2YgYW4gZW50cnkgc2V0LgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQ2hlY2tlZEVudHJ5U2V0PEssIFY+IGltcGxlbWVudHMgU2V0PE1hcC5FbnRyeTxLLCBWPj4geworICAgICAgICAgICAgU2V0PE1hcC5FbnRyeTxLLCBWPj4gczsKKyAgICAgICAgICAgIENsYXNzPFY+IHZhbHVlVHlwZTsKKworICAgICAgICAgICAgcHVibGljIENoZWNrZWRFbnRyeVNldChTZXQ8TWFwLkVudHJ5PEssIFY+PiBzLCBDbGFzczxWPiB2YWx1ZVR5cGUpIHsKKyAgICAgICAgICAgICAgICB0aGlzLnMgPSBzOworICAgICAgICAgICAgICAgIHRoaXMudmFsdWVUeXBlID0gdmFsdWVUeXBlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEl0ZXJhdG9yPE1hcC5FbnRyeTxLLCBWPj4gaXRlcmF0b3IoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDaGVja2VkRW50cnlJdGVyYXRvcjxLLCBWPihzLml0ZXJhdG9yKCksIHZhbHVlVHlwZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKKyAgICAgICAgICAgICAgICBpbnQgdGhpc1NpemUgPSBzaXplKCk7CisgICAgICAgICAgICAgICAgT2JqZWN0W10gYXJyYXkgPSBuZXcgT2JqZWN0W3RoaXNTaXplXTsKKyAgICAgICAgICAgICAgICBJdGVyYXRvcjw/PiBpdCA9IGl0ZXJhdG9yKCk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzU2l6ZTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGFycmF5W2ldID0gaXQubmV4dCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyA8VD4gVFtdIHRvQXJyYXkoVFtdIGFycmF5KSB7CisgICAgICAgICAgICAgICAgaW50IHRoaXNTaXplID0gc2l6ZSgpOworICAgICAgICAgICAgICAgIGlmIChhcnJheS5sZW5ndGggPCB0aGlzU2l6ZSkgeworICAgICAgICAgICAgICAgICAgICBDbGFzczw/PiBjdCA9IGFycmF5LmdldENsYXNzKCkuZ2V0Q29tcG9uZW50VHlwZSgpOworICAgICAgICAgICAgICAgICAgICBhcnJheSA9IChUW10pIEFycmF5Lm5ld0luc3RhbmNlKGN0LCB0aGlzU2l6ZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIEl0ZXJhdG9yPD8+IGl0ID0gaXRlcmF0b3IoKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXNTaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgYXJyYXlbaV0gPSAoVCkgaXQubmV4dCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAodGhpc1NpemUgPCBhcnJheS5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgYXJyYXlbdGhpc1NpemVdID0gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gcmV0YWluQWxsKENvbGxlY3Rpb248Pz4gYykgeworICAgICAgICAgICAgICAgIHJldHVybiBzLnJldGFpbkFsbChjKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIHJlbW92ZUFsbChDb2xsZWN0aW9uPD8+IGMpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcy5yZW1vdmVBbGwoYyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBjb250YWluc0FsbChDb2xsZWN0aW9uPD8+IGMpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcy5jb250YWluc0FsbChjKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGFkZEFsbChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBNYXAuRW50cnk8SywgVj4+IGMpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3QgbykgeworICAgICAgICAgICAgICAgIHJldHVybiBzLnJlbW92ZShvKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHMuY29udGFpbnMobyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBhZGQoTWFwLkVudHJ5PEssIFY+IG8pIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHMuaXNFbXB0eSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICAgICAgcy5jbGVhcigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBzLnNpemUoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHMuaGFzaENvZGUoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHMuZXF1YWxzKG9iamVjdCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qKgorICAgICAgICAgICAgICogQSBkeW5hbWljYWxseSB0eXBlc2FmZSB2aWV3IG9mIGFuIGVudHJ5IGl0ZXJhdG9yLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBDaGVja2VkRW50cnlJdGVyYXRvcjxLLCBWPiBpbXBsZW1lbnRzIEl0ZXJhdG9yPE1hcC5FbnRyeTxLLCBWPj4geworICAgICAgICAgICAgICAgIEl0ZXJhdG9yPE1hcC5FbnRyeTxLLCBWPj4gaTsKKyAgICAgICAgICAgICAgICBDbGFzczxWPiB2YWx1ZVR5cGU7CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgQ2hlY2tlZEVudHJ5SXRlcmF0b3IoSXRlcmF0b3I8TWFwLkVudHJ5PEssIFY+PiBpLAorICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3M8Vj4gdmFsdWVUeXBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMuaSA9IGk7CisgICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWVUeXBlID0gdmFsdWVUeXBlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gaS5oYXNOZXh0KCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgaS5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIE1hcC5FbnRyeTxLLCBWPiBuZXh0KCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENoZWNrZWRFbnRyeTxLLCBWPihpLm5leHQoKSwgdmFsdWVUeXBlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBIGR5bmFtaWNhbGx5IHR5cGVzYWZlIHZpZXcgb2YgYSBTb3J0ZWRTZXQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQ2hlY2tlZFNvcnRlZFNldDxFPiBleHRlbmRzIENoZWNrZWRTZXQ8RT4gaW1wbGVtZW50cyBTb3J0ZWRTZXQ8RT4geworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxNTk5OTExMTY1NDkyOTE0OTU5TDsKKyAgICAgICAgcHJpdmF0ZSBTb3J0ZWRTZXQ8RT4gc3M7CisKKyAgICAgICAgcHVibGljIENoZWNrZWRTb3J0ZWRTZXQoU29ydGVkU2V0PEU+IHMsIENsYXNzPEU+IHR5cGUpIHsKKyAgICAgICAgICAgIHN1cGVyKHMsIHR5cGUpOworICAgICAgICAgICAgdGhpcy5zcyA9IHM7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIENvbXBhcmF0b3I8PyBzdXBlciBFPiBjb21wYXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIHNzLmNvbXBhcmF0b3IoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU29ydGVkU2V0PEU+IHN1YlNldChFIGZyb21FbGVtZW50LCBFIHRvRWxlbWVudCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBDaGVja2VkU29ydGVkU2V0PEU+KHNzLnN1YlNldChmcm9tRWxlbWVudCwgdG9FbGVtZW50KSwKKyAgICAgICAgICAgICAgICAgICAgdHlwZSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFNvcnRlZFNldDxFPiBoZWFkU2V0KEUgdG9FbGVtZW50KSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IENoZWNrZWRTb3J0ZWRTZXQ8RT4oc3MuaGVhZFNldCh0b0VsZW1lbnQpLCB0eXBlKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU29ydGVkU2V0PEU+IHRhaWxTZXQoRSBmcm9tRWxlbWVudCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBDaGVja2VkU29ydGVkU2V0PEU+KHNzLnRhaWxTZXQoZnJvbUVsZW1lbnQpLCB0eXBlKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgRSBmaXJzdCgpIHsKKyAgICAgICAgICAgIHJldHVybiBzcy5maXJzdCgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBFIGxhc3QoKSB7CisgICAgICAgICAgICByZXR1cm4gc3MubGFzdCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBkeW5hbWljYWxseSB0eXBlc2FmZSB2aWV3IG9mIGEgU29ydGVkTWFwLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIENoZWNrZWRTb3J0ZWRNYXA8SywgVj4gZXh0ZW5kcyBDaGVja2VkTWFwPEssIFY+CisgICAgICAgICAgICBpbXBsZW1lbnRzIFNvcnRlZE1hcDxLLCBWPiB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDE1OTk2NzEzMjA2ODgwNjc0MzhMOworICAgICAgICBTb3J0ZWRNYXA8SywgVj4gc207CisKKyAgICAgICAgQ2hlY2tlZFNvcnRlZE1hcChTb3J0ZWRNYXA8SywgVj4gbSwgQ2xhc3M8Sz4ga2V5VHlwZSwgQ2xhc3M8Vj4gdmFsdWVUeXBlKSB7CisgICAgICAgICAgICBzdXBlcihtLCBrZXlUeXBlLCB2YWx1ZVR5cGUpOworICAgICAgICAgICAgdGhpcy5zbSA9IG07CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIENvbXBhcmF0b3I8PyBzdXBlciBLPiBjb21wYXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIHNtLmNvbXBhcmF0b3IoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU29ydGVkTWFwPEssIFY+IHN1Yk1hcChLIGZyb21LZXksIEsgdG9LZXkpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQ2hlY2tlZFNvcnRlZE1hcDxLLCBWPihzbS5zdWJNYXAoZnJvbUtleSwgdG9LZXkpLCBrZXlUeXBlLCB2YWx1ZVR5cGUpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTb3J0ZWRNYXA8SywgVj4gaGVhZE1hcChLIHRvS2V5KSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IENoZWNrZWRTb3J0ZWRNYXA8SywgVj4oc20uaGVhZE1hcCh0b0tleSksIGtleVR5cGUsIHZhbHVlVHlwZSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFNvcnRlZE1hcDxLLCBWPiB0YWlsTWFwKEsgZnJvbUtleSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBDaGVja2VkU29ydGVkTWFwPEssIFY+KHNtLnRhaWxNYXAoZnJvbUtleSksIGtleVR5cGUsIHZhbHVlVHlwZSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEsgZmlyc3RLZXkoKSB7CisgICAgICAgICAgICByZXR1cm4gc20uZmlyc3RLZXkoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgSyBsYXN0S2V5KCkgeworICAgICAgICAgICAgcmV0dXJuIHNtLmxhc3RLZXkoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvQ29tcGFyYWJsZVRpbVNvcnQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvQ29tcGFyYWJsZVRpbVNvcnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYmE3NTczCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9Db21wYXJhYmxlVGltU29ydC5qYXZhCkBAIC0wLDAgKzEsODcwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKKy8qKgorICogVGhpcyBpcyBhIG5lYXIgZHVwbGljYXRlIG9mIHtAbGluayBUaW1Tb3J0fSwgbW9kaWZpZWQgZm9yIHVzZSB3aXRoCisgKiBhcnJheXMgb2Ygb2JqZWN0cyB0aGF0IGltcGxlbWVudCB7QGxpbmsgQ29tcGFyYWJsZX0sIGluc3RlYWQgb2YgdXNpbmcKKyAqIGV4cGxpY2l0IGNvbXBhcmF0b3JzLgorICoKKyAqIDxwPklmIHlvdSBhcmUgdXNpbmcgYW4gb3B0aW1pemluZyBWTSwgeW91IG1heSBmaW5kIHRoYXQgQ29tcGFyYWJsZVRpbVNvcnQKKyAqIG9mZmVycyBubyBwZXJmb3JtYW5jZSBiZW5lZml0IG92ZXIgVGltU29ydCBpbiBjb25qdW5jdGlvbiB3aXRoIGEKKyAqIGNvbXBhcmF0b3IgdGhhdCBzaW1wbHkgcmV0dXJucyB7QGNvZGUgKChDb21wYXJhYmxlKWZpcnN0KS5jb21wYXJlVG8oU2Vjb25kKX0uCisgKiBJZiB0aGlzIGlzIHRoZSBjYXNlLCB5b3UgYXJlIGJldHRlciBvZmYgZGVsZXRpbmcgQ29tcGFyYWJsZVRpbVNvcnQgdG8KKyAqIGVsaW1pbmF0ZSB0aGUgY29kZSBkdXBsaWNhdGlvbi4gIChTZWUgQXJyYXlzLmphdmEgZm9yIGRldGFpbHMuKQorICovCitjbGFzcyBDb21wYXJhYmxlVGltU29ydCB7CisgICAgLyoqCisgICAgICogVGhpcyBpcyB0aGUgbWluaW11bSBzaXplZCBzZXF1ZW5jZSB0aGF0IHdpbGwgYmUgbWVyZ2VkLiAgU2hvcnRlcgorICAgICAqIHNlcXVlbmNlcyB3aWxsIGJlIGxlbmd0aGVuZWQgYnkgY2FsbGluZyBiaW5hcnlTb3J0LiAgSWYgdGhlIGVudGlyZQorICAgICAqIGFycmF5IGlzIGxlc3MgdGhhbiB0aGlzIGxlbmd0aCwgbm8gbWVyZ2VzIHdpbGwgYmUgcGVyZm9ybWVkLgorICAgICAqCisgICAgICogVGhpcyBjb25zdGFudCBzaG91bGQgYmUgYSBwb3dlciBvZiB0d28uICBJdCB3YXMgNjQgaW4gVGltIFBldGVyJ3MgQworICAgICAqIGltcGxlbWVudGF0aW9uLCBidXQgMzIgd2FzIGVtcGlyaWNhbGx5IGRldGVybWluZWQgdG8gd29yayBiZXR0ZXIgaW4KKyAgICAgKiB0aGlzIGltcGxlbWVudGF0aW9uLiAgSW4gdGhlIHVubGlrZWx5IGV2ZW50IHRoYXQgeW91IHNldCB0aGlzIGNvbnN0YW50CisgICAgICogdG8gYmUgYSBudW1iZXIgdGhhdCdzIG5vdCBhIHBvd2VyIG9mIHR3bywgeW91J2xsIG5lZWQgdG8gY2hhbmdlIHRoZQorICAgICAqIHtAbGluayAjbWluUnVuTGVuZ3RofSBjb21wdXRhdGlvbi4KKyAgICAgKgorICAgICAqIElmIHlvdSBkZWNyZWFzZSB0aGlzIGNvbnN0YW50LCB5b3UgbXVzdCBjaGFuZ2UgdGhlIHN0YWNrTGVuCisgICAgICogY29tcHV0YXRpb24gaW4gdGhlIFRpbVNvcnQgY29uc3RydWN0b3IsIG9yIHlvdSByaXNrIGFuCisgICAgICogQXJyYXlPdXRPZkJvdW5kcyBleGNlcHRpb24uICBTZWUgbGlzdHNvcnQudHh0IGZvciBhIGRpc2N1c3Npb24KKyAgICAgKiBvZiB0aGUgbWluaW11bSBzdGFjayBsZW5ndGggcmVxdWlyZWQgYXMgYSBmdW5jdGlvbiBvZiB0aGUgbGVuZ3RoCisgICAgICogb2YgdGhlIGFycmF5IGJlaW5nIHNvcnRlZCBhbmQgdGhlIG1pbmltdW0gbWVyZ2Ugc2VxdWVuY2UgbGVuZ3RoLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNSU5fTUVSR0UgPSAzMjsKKworICAgIC8qKgorICAgICAqIFRoZSBhcnJheSBiZWluZyBzb3J0ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3RbXSBhOworCisgICAgLyoqCisgICAgICogV2hlbiB3ZSBnZXQgaW50byBnYWxsb3BpbmcgbW9kZSwgd2Ugc3RheSB0aGVyZSB1bnRpbCBib3RoIHJ1bnMgd2luIGxlc3MKKyAgICAgKiBvZnRlbiB0aGFuIE1JTl9HQUxMT1AgY29uc2VjdXRpdmUgdGltZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50ICBNSU5fR0FMTE9QID0gNzsKKworICAgIC8qKgorICAgICAqIFRoaXMgY29udHJvbHMgd2hlbiB3ZSBnZXQgKmludG8qIGdhbGxvcGluZyBtb2RlLiAgSXQgaXMgaW5pdGlhbGl6ZWQKKyAgICAgKiB0byBNSU5fR0FMTE9QLiAgVGhlIG1lcmdlTG8gYW5kIG1lcmdlSGkgbWV0aG9kcyBudWRnZSBpdCBoaWdoZXIgZm9yCisgICAgICogcmFuZG9tIGRhdGEsIGFuZCBsb3dlciBmb3IgaGlnaGx5IHN0cnVjdHVyZWQgZGF0YS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBtaW5HYWxsb3AgPSBNSU5fR0FMTE9QOworCisgICAgLyoqCisgICAgICogTWF4aW11bSBpbml0aWFsIHNpemUgb2YgdG1wIGFycmF5LCB3aGljaCBpcyB1c2VkIGZvciBtZXJnaW5nLiAgVGhlIGFycmF5CisgICAgICogY2FuIGdyb3cgdG8gYWNjb21tb2RhdGUgZGVtYW5kLgorICAgICAqCisgICAgICogVW5saWtlIFRpbSdzIG9yaWdpbmFsIEMgdmVyc2lvbiwgd2UgZG8gbm90IGFsbG9jYXRlIHRoaXMgbXVjaCBzdG9yYWdlCisgICAgICogd2hlbiBzb3J0aW5nIHNtYWxsZXIgYXJyYXlzLiAgVGhpcyBjaGFuZ2Ugd2FzIHJlcXVpcmVkIGZvciBwZXJmb3JtYW5jZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5JVElBTF9UTVBfU1RPUkFHRV9MRU5HVEggPSAyNTY7CisKKyAgICAvKioKKyAgICAgKiBUZW1wIHN0b3JhZ2UgZm9yIG1lcmdlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIE9iamVjdFtdIHRtcDsKKworICAgIC8qKgorICAgICAqIEEgc3RhY2sgb2YgcGVuZGluZyBydW5zIHlldCB0byBiZSBtZXJnZWQuICBSdW4gaSBzdGFydHMgYXQKKyAgICAgKiBhZGRyZXNzIGJhc2VbaV0gYW5kIGV4dGVuZHMgZm9yIGxlbltpXSBlbGVtZW50cy4gIEl0J3MgYWx3YXlzCisgICAgICogdHJ1ZSAoc28gbG9uZyBhcyB0aGUgaW5kaWNlcyBhcmUgaW4gYm91bmRzKSB0aGF0OgorICAgICAqCisgICAgICogICAgIHJ1bkJhc2VbaV0gKyBydW5MZW5baV0gPT0gcnVuQmFzZVtpICsgMV0KKyAgICAgKgorICAgICAqIHNvIHdlIGNvdWxkIGN1dCB0aGUgc3RvcmFnZSBmb3IgdGhpcywgYnV0IGl0J3MgYSBtaW5vciBhbW91bnQsCisgICAgICogYW5kIGtlZXBpbmcgYWxsIHRoZSBpbmZvIGV4cGxpY2l0IHNpbXBsaWZpZXMgdGhlIGNvZGUuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgc3RhY2tTaXplID0gMDsgIC8vIE51bWJlciBvZiBwZW5kaW5nIHJ1bnMgb24gc3RhY2sKKyAgICBwcml2YXRlIGZpbmFsIGludFtdIHJ1bkJhc2U7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnRbXSBydW5MZW47CisKKyAgICAvKioKKyAgICAgKiBBc3NlcnRzIGhhdmUgYmVlbiBwbGFjZWQgaW4gaWYtc3RhdGVtZW50cyBmb3IgcGVyZm9ybWFjZS4gVG8gZW5hYmxlIHRoZW0sCisgICAgICogc2V0IHRoaXMgZmllbGQgdG8gdHJ1ZSBhbmQgZW5hYmxlIHRoZW0gaW4gVk0gd2l0aCBhIGNvbW1hbmQgbGluZSBmbGFnLgorICAgICAqIElmIHlvdSBtb2RpZnkgdGhpcyBjbGFzcywgcGxlYXNlIGRvIHRlc3QgdGhlIGFzc2VydHMhCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVRyA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIFRpbVNvcnQgaW5zdGFuY2UgdG8gbWFpbnRhaW4gdGhlIHN0YXRlIG9mIGFuIG9uZ29pbmcgc29ydC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSB0byBiZSBzb3J0ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIENvbXBhcmFibGVUaW1Tb3J0KE9iamVjdFtdIGEpIHsKKyAgICAgICAgdGhpcy5hID0gYTsKKworICAgICAgICAvLyBBbGxvY2F0ZSB0ZW1wIHN0b3JhZ2UgKHdoaWNoIG1heSBiZSBpbmNyZWFzZWQgbGF0ZXIgaWYgbmVjZXNzYXJ5KQorICAgICAgICBpbnQgbGVuID0gYS5sZW5ndGg7CisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW5jaGVja2VkIiwgIlVubmVjZXNzYXJ5TG9jYWxWYXJpYWJsZSJ9KQorICAgICAgICBPYmplY3RbXSBuZXdBcnJheSA9IG5ldyBPYmplY3RbbGVuIDwgMiAqIElOSVRJQUxfVE1QX1NUT1JBR0VfTEVOR1RIID8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbiA+Pj4gMSA6IElOSVRJQUxfVE1QX1NUT1JBR0VfTEVOR1RIXTsKKyAgICAgICAgdG1wID0gbmV3QXJyYXk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogQWxsb2NhdGUgcnVucy10by1iZS1tZXJnZWQgc3RhY2sgKHdoaWNoIGNhbm5vdCBiZSBleHBhbmRlZCkuICBUaGUKKyAgICAgICAgICogc3RhY2sgbGVuZ3RoIHJlcXVpcmVtZW50cyBhcmUgZGVzY3JpYmVkIGluIGxpc3Rzb3J0LnR4dC4gIFRoZSBDCisgICAgICAgICAqIHZlcnNpb24gYWx3YXlzIHVzZXMgdGhlIHNhbWUgc3RhY2sgbGVuZ3RoICg4NSksIGJ1dCB0aGlzIHdhcworICAgICAgICAgKiBtZWFzdXJlZCB0byBiZSB0b28gZXhwZW5zaXZlIHdoZW4gc29ydGluZyAibWlkLXNpemVkIiBhcnJheXMgKGUuZy4sCisgICAgICAgICAqIDEwMCBlbGVtZW50cykgaW4gSmF2YS4gIFRoZXJlZm9yZSwgd2UgdXNlIHNtYWxsZXIgKGJ1dCBzdWZmaWNpZW50bHkKKyAgICAgICAgICogbGFyZ2UpIHN0YWNrIGxlbmd0aHMgZm9yIHNtYWxsZXIgYXJyYXlzLiAgVGhlICJtYWdpYyBudW1iZXJzIiBpbiB0aGUKKyAgICAgICAgICogY29tcHV0YXRpb24gYmVsb3cgbXVzdCBiZSBjaGFuZ2VkIGlmIE1JTl9NRVJHRSBpcyBkZWNyZWFzZWQuICBTZWUKKyAgICAgICAgICogdGhlIE1JTl9NRVJHRSBkZWNsYXJhdGlvbiBhYm92ZSBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KKyAgICAgICAgICovCisgICAgICAgIGludCBzdGFja0xlbiA9IChsZW4gPCAgICAxMjAgID8gIDUgOgorICAgICAgICAgICAgICAgICAgICAgICAgbGVuIDwgICAxNTQyICA/IDEwIDoKKyAgICAgICAgICAgICAgICAgICAgICAgIGxlbiA8IDExOTE1MSAgPyAxOSA6IDQwKTsKKyAgICAgICAgcnVuQmFzZSA9IG5ldyBpbnRbc3RhY2tMZW5dOworICAgICAgICBydW5MZW4gPSBuZXcgaW50W3N0YWNrTGVuXTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFRoZSBuZXh0IHR3byBtZXRob2RzICh3aGljaCBhcmUgcGFja2FnZSBwcml2YXRlIGFuZCBzdGF0aWMpIGNvbnN0aXR1dGUKKyAgICAgKiB0aGUgZW50aXJlIEFQSSBvZiB0aGlzIGNsYXNzLiAgRWFjaCBvZiB0aGVzZSBtZXRob2RzIG9iZXlzIHRoZSBjb250cmFjdAorICAgICAqIG9mIHRoZSBwdWJsaWMgbWV0aG9kIHdpdGggdGhlIHNhbWUgc2lnbmF0dXJlIGluIGphdmEudXRpbC5BcnJheXMuCisgICAgICovCisKKyAgICBzdGF0aWMgdm9pZCBzb3J0KE9iamVjdFtdIGEpIHsKKyAgICAgICAgICBzb3J0KGEsIDAsIGEubGVuZ3RoKTsKKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBzb3J0KE9iamVjdFtdIGEsIGludCBsbywgaW50IGhpKSB7CisgICAgICAgIEFycmF5cy5jaGVja1N0YXJ0QW5kRW5kKGEubGVuZ3RoLCBsbywgaGkpOworICAgICAgICBpbnQgblJlbWFpbmluZyAgPSBoaSAtIGxvOworICAgICAgICBpZiAoblJlbWFpbmluZyA8IDIpCisgICAgICAgICAgICByZXR1cm47ICAvLyBBcnJheXMgb2Ygc2l6ZSAwIGFuZCAxIGFyZSBhbHdheXMgc29ydGVkCisKKyAgICAgICAgLy8gSWYgYXJyYXkgaXMgc21hbGwsIGRvIGEgIm1pbmktVGltU29ydCIgd2l0aCBubyBtZXJnZXMKKyAgICAgICAgaWYgKG5SZW1haW5pbmcgPCBNSU5fTUVSR0UpIHsKKyAgICAgICAgICAgIGludCBpbml0UnVuTGVuID0gY291bnRSdW5BbmRNYWtlQXNjZW5kaW5nKGEsIGxvLCBoaSk7CisgICAgICAgICAgICBiaW5hcnlTb3J0KGEsIGxvLCBoaSwgbG8gKyBpbml0UnVuTGVuKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBNYXJjaCBvdmVyIHRoZSBhcnJheSBvbmNlLCBsZWZ0IHRvIHJpZ2h0LCBmaW5kaW5nIG5hdHVyYWwgcnVucywKKyAgICAgICAgICogZXh0ZW5kaW5nIHNob3J0IG5hdHVyYWwgcnVucyB0byBtaW5SdW4gZWxlbWVudHMsIGFuZCBtZXJnaW5nIHJ1bnMKKyAgICAgICAgICogdG8gbWFpbnRhaW4gc3RhY2sgaW52YXJpYW50LgorICAgICAgICAgKi8KKyAgICAgICAgQ29tcGFyYWJsZVRpbVNvcnQgdHMgPSBuZXcgQ29tcGFyYWJsZVRpbVNvcnQoYSk7CisgICAgICAgIGludCBtaW5SdW4gPSBtaW5SdW5MZW5ndGgoblJlbWFpbmluZyk7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIC8vIElkZW50aWZ5IG5leHQgcnVuCisgICAgICAgICAgICBpbnQgcnVuTGVuID0gY291bnRSdW5BbmRNYWtlQXNjZW5kaW5nKGEsIGxvLCBoaSk7CisKKyAgICAgICAgICAgIC8vIElmIHJ1biBpcyBzaG9ydCwgZXh0ZW5kIHRvIG1pbihtaW5SdW4sIG5SZW1haW5pbmcpCisgICAgICAgICAgICBpZiAocnVuTGVuIDwgbWluUnVuKSB7CisgICAgICAgICAgICAgICAgaW50IGZvcmNlID0gblJlbWFpbmluZyA8PSBtaW5SdW4gPyBuUmVtYWluaW5nIDogbWluUnVuOworICAgICAgICAgICAgICAgIGJpbmFyeVNvcnQoYSwgbG8sIGxvICsgZm9yY2UsIGxvICsgcnVuTGVuKTsKKyAgICAgICAgICAgICAgICBydW5MZW4gPSBmb3JjZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gUHVzaCBydW4gb250byBwZW5kaW5nLXJ1biBzdGFjaywgYW5kIG1heWJlIG1lcmdlCisgICAgICAgICAgICB0cy5wdXNoUnVuKGxvLCBydW5MZW4pOworICAgICAgICAgICAgdHMubWVyZ2VDb2xsYXBzZSgpOworCisgICAgICAgICAgICAvLyBBZHZhbmNlIHRvIGZpbmQgbmV4dCBydW4KKyAgICAgICAgICAgIGxvICs9IHJ1bkxlbjsKKyAgICAgICAgICAgIG5SZW1haW5pbmcgLT0gcnVuTGVuOworICAgICAgICB9IHdoaWxlIChuUmVtYWluaW5nICE9IDApOworCisgICAgICAgIC8vIE1lcmdlIGFsbCByZW1haW5pbmcgcnVucyB0byBjb21wbGV0ZSBzb3J0CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxvID09IGhpOworICAgICAgICB0cy5tZXJnZUZvcmNlQ29sbGFwc2UoKTsKKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgdHMuc3RhY2tTaXplID09IDE7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCBwb3J0aW9uIG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkgdXNpbmcgYSBiaW5hcnkKKyAgICAgKiBpbnNlcnRpb24gc29ydC4gIFRoaXMgaXMgdGhlIGJlc3QgbWV0aG9kIGZvciBzb3J0aW5nIHNtYWxsIG51bWJlcnMKKyAgICAgKiBvZiBlbGVtZW50cy4gIEl0IHJlcXVpcmVzIE8obiBsb2cgbikgY29tcGFyZXMsIGJ1dCBPKG5eMikgZGF0YQorICAgICAqIG1vdmVtZW50ICh3b3JzdCBjYXNlKS4KKyAgICAgKgorICAgICAqIElmIHRoZSBpbml0aWFsIHBhcnQgb2YgdGhlIHNwZWNpZmllZCByYW5nZSBpcyBhbHJlYWR5IHNvcnRlZCwKKyAgICAgKiB0aGlzIG1ldGhvZCBjYW4gdGFrZSBhZHZhbnRhZ2Ugb2YgaXQ6IHRoZSBtZXRob2QgYXNzdW1lcyB0aGF0IHRoZQorICAgICAqIGVsZW1lbnRzIGZyb20gaW5kZXgge0Bjb2RlIGxvfSwgaW5jbHVzaXZlLCB0byB7QGNvZGUgc3RhcnR9LAorICAgICAqIGV4Y2x1c2l2ZSBhcmUgYWxyZWFkeSBzb3J0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgaW4gd2hpY2ggYSByYW5nZSBpcyB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gbG8gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50IGluIHRoZSByYW5nZSB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gaGkgdGhlIGluZGV4IGFmdGVyIHRoZSBsYXN0IGVsZW1lbnQgaW4gdGhlIHJhbmdlIHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSBzdGFydCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIHJhbmdlIHRoYXQgaXMKKyAgICAgKiAgICAgICAgbm90IGFscmVhZHkga25vd24gdG8gYmUgc29ydGVkIChAY29kZSBsbyA8PSBzdGFydCA8PSBoaX0KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZmFsbHRocm91Z2giKQorICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYmluYXJ5U29ydChPYmplY3RbXSBhLCBpbnQgbG8sIGludCBoaSwgaW50IHN0YXJ0KSB7CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxvIDw9IHN0YXJ0ICYmIHN0YXJ0IDw9IGhpOworICAgICAgICBpZiAoc3RhcnQgPT0gbG8pCisgICAgICAgICAgICBzdGFydCsrOworICAgICAgICBmb3IgKCA7IHN0YXJ0IDwgaGk7IHN0YXJ0KyspIHsKKyAgICAgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICAgICAgQ29tcGFyYWJsZTxPYmplY3Q+IHBpdm90ID0gKENvbXBhcmFibGUpIGFbc3RhcnRdOworCisgICAgICAgICAgICAvLyBTZXQgbGVmdCAoYW5kIHJpZ2h0KSB0byB0aGUgaW5kZXggd2hlcmUgYVtzdGFydF0gKHBpdm90KSBiZWxvbmdzCisgICAgICAgICAgICBpbnQgbGVmdCA9IGxvOworICAgICAgICAgICAgaW50IHJpZ2h0ID0gc3RhcnQ7CisgICAgICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBsZWZ0IDw9IHJpZ2h0OworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIEludmFyaWFudHM6CisgICAgICAgICAgICAgKiAgIHBpdm90ID49IGFsbCBpbiBbbG8sIGxlZnQpLgorICAgICAgICAgICAgICogICBwaXZvdCA8ICBhbGwgaW4gW3JpZ2h0LCBzdGFydCkuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHdoaWxlIChsZWZ0IDwgcmlnaHQpIHsKKyAgICAgICAgICAgICAgICBpbnQgbWlkID0gKGxlZnQgKyByaWdodCkgPj4+IDE7CisgICAgICAgICAgICAgICAgaWYgKHBpdm90LmNvbXBhcmVUbyhhW21pZF0pIDwgMCkKKyAgICAgICAgICAgICAgICAgICAgcmlnaHQgPSBtaWQ7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBsZWZ0ID0gbWlkICsgMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxlZnQgPT0gcmlnaHQ7CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBUaGUgaW52YXJpYW50cyBzdGlsbCBob2xkOiBwaXZvdCA+PSBhbGwgaW4gW2xvLCBsZWZ0KSBhbmQKKyAgICAgICAgICAgICAqIHBpdm90IDwgYWxsIGluIFtsZWZ0LCBzdGFydCksIHNvIHBpdm90IGJlbG9uZ3MgYXQgbGVmdC4gIE5vdGUKKyAgICAgICAgICAgICAqIHRoYXQgaWYgdGhlcmUgYXJlIGVsZW1lbnRzIGVxdWFsIHRvIHBpdm90LCBsZWZ0IHBvaW50cyB0byB0aGUKKyAgICAgICAgICAgICAqIGZpcnN0IHNsb3QgYWZ0ZXIgdGhlbSAtLSB0aGF0J3Mgd2h5IHRoaXMgc29ydCBpcyBzdGFibGUuCisgICAgICAgICAgICAgKiBTbGlkZSBlbGVtZW50cyBvdmVyIHRvIG1ha2Ugcm9vbSB0byBtYWtlIHJvb20gZm9yIHBpdm90LgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpbnQgbiA9IHN0YXJ0IC0gbGVmdDsgIC8vIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gbW92ZQorICAgICAgICAgICAgLy8gU3dpdGNoIGlzIGp1c3QgYW4gb3B0aW1pemF0aW9uIGZvciBhcnJheWNvcHkgaW4gZGVmYXVsdCBjYXNlCisgICAgICAgICAgICBzd2l0Y2gobikgeworICAgICAgICAgICAgICAgIGNhc2UgMjogIGFbbGVmdCArIDJdID0gYVtsZWZ0ICsgMV07CisgICAgICAgICAgICAgICAgY2FzZSAxOiAgYVtsZWZ0ICsgMV0gPSBhW2xlZnRdOworICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGRlZmF1bHQ6IFN5c3RlbS5hcnJheWNvcHkoYSwgbGVmdCwgYSwgbGVmdCArIDEsIG4pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYVtsZWZ0XSA9IHBpdm90OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBydW4gYmVnaW5uaW5nIGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gaW4KKyAgICAgKiB0aGUgc3BlY2lmaWVkIGFycmF5IGFuZCByZXZlcnNlcyB0aGUgcnVuIGlmIGl0IGlzIGRlc2NlbmRpbmcgKGVuc3VyaW5nCisgICAgICogdGhhdCB0aGUgcnVuIHdpbGwgYWx3YXlzIGJlIGFzY2VuZGluZyB3aGVuIHRoZSBtZXRob2QgcmV0dXJucykuCisgICAgICoKKyAgICAgKiBBIHJ1biBpcyB0aGUgbG9uZ2VzdCBhc2NlbmRpbmcgc2VxdWVuY2Ugd2l0aDoKKyAgICAgKgorICAgICAqICAgIGFbbG9dIDw9IGFbbG8gKyAxXSA8PSBhW2xvICsgMl0gPD0gLi4uCisgICAgICoKKyAgICAgKiBvciB0aGUgbG9uZ2VzdCBkZXNjZW5kaW5nIHNlcXVlbmNlIHdpdGg6CisgICAgICoKKyAgICAgKiAgICBhW2xvXSA+ICBhW2xvICsgMV0gPiAgYVtsbyArIDJdID4gIC4uLgorICAgICAqCisgICAgICogRm9yIGl0cyBpbnRlbmRlZCB1c2UgaW4gYSBzdGFibGUgbWVyZ2Vzb3J0LCB0aGUgc3RyaWN0bmVzcyBvZiB0aGUKKyAgICAgKiBkZWZpbml0aW9uIG9mICJkZXNjZW5kaW5nIiBpcyBuZWVkZWQgc28gdGhhdCB0aGUgY2FsbCBjYW4gc2FmZWx5CisgICAgICogcmV2ZXJzZSBhIGRlc2NlbmRpbmcgc2VxdWVuY2Ugd2l0aG91dCB2aW9sYXRpbmcgc3RhYmlsaXR5LgorICAgICAqCisgICAgICogQHBhcmFtIGEgdGhlIGFycmF5IGluIHdoaWNoIGEgcnVuIGlzIHRvIGJlIGNvdW50ZWQgYW5kIHBvc3NpYmx5IHJldmVyc2VkCisgICAgICogQHBhcmFtIGxvIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50IGluIHRoZSBydW4KKyAgICAgKiBAcGFyYW0gaGkgaW5kZXggYWZ0ZXIgdGhlIGxhc3QgZWxlbWVudCB0aGF0IG1heSBiZSBjb250YWluZWQgaW4gdGhlIHJ1bi4KKyAgICAgICAgICAgICAgSXQgaXMgcmVxdWlyZWQgdGhhdCBAY29kZXtsbyA8IGhpfS4KKyAgICAgKiBAcmV0dXJuICB0aGUgbGVuZ3RoIG9mIHRoZSBydW4gYmVnaW5uaW5nIGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gaW4KKyAgICAgKiAgICAgICAgICB0aGUgc3BlY2lmaWVkIGFycmF5CisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGNvdW50UnVuQW5kTWFrZUFzY2VuZGluZyhPYmplY3RbXSBhLCBpbnQgbG8sIGludCBoaSkgeworICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBsbyA8IGhpOworICAgICAgICBpbnQgcnVuSGkgPSBsbyArIDE7CisgICAgICAgIGlmIChydW5IaSA9PSBoaSkKKyAgICAgICAgICAgIHJldHVybiAxOworCisgICAgICAgIC8vIEZpbmQgZW5kIG9mIHJ1biwgYW5kIHJldmVyc2UgcmFuZ2UgaWYgZGVzY2VuZGluZworICAgICAgICBpZiAoKChDb21wYXJhYmxlKSBhW3J1bkhpKytdKS5jb21wYXJlVG8oYVtsb10pIDwgMCkgeyAvLyBEZXNjZW5kaW5nCisgICAgICAgICAgICB3aGlsZShydW5IaSA8IGhpICYmICgoQ29tcGFyYWJsZSkgYVtydW5IaV0pLmNvbXBhcmVUbyhhW3J1bkhpIC0gMV0pIDwgMCkKKyAgICAgICAgICAgICAgICBydW5IaSsrOworICAgICAgICAgICAgcmV2ZXJzZVJhbmdlKGEsIGxvLCBydW5IaSk7CisgICAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXNjZW5kaW5nCisgICAgICAgICAgICB3aGlsZSAocnVuSGkgPCBoaSAmJiAoKENvbXBhcmFibGUpIGFbcnVuSGldKS5jb21wYXJlVG8oYVtydW5IaSAtIDFdKSA+PSAwKQorICAgICAgICAgICAgICAgIHJ1bkhpKys7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcnVuSGkgLSBsbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXZlcnNlIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhlIHNwZWNpZmllZCBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSBpbiB3aGljaCBhIHJhbmdlIGlzIHRvIGJlIHJldmVyc2VkCisgICAgICogQHBhcmFtIGxvIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgZWxlbWVudCBpbiB0aGUgcmFuZ2UgdG8gYmUgcmV2ZXJzZWQKKyAgICAgKiBAcGFyYW0gaGkgdGhlIGluZGV4IGFmdGVyIHRoZSBsYXN0IGVsZW1lbnQgaW4gdGhlIHJhbmdlIHRvIGJlIHJldmVyc2VkCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCByZXZlcnNlUmFuZ2UoT2JqZWN0W10gYSwgaW50IGxvLCBpbnQgaGkpIHsKKyAgICAgICAgaGktLTsKKyAgICAgICAgd2hpbGUgKGxvIDwgaGkpIHsKKyAgICAgICAgICAgIE9iamVjdCB0ID0gYVtsb107CisgICAgICAgICAgICBhW2xvKytdID0gYVtoaV07CisgICAgICAgICAgICBhW2hpLS1dID0gdDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1pbmltdW0gYWNjZXB0YWJsZSBydW4gbGVuZ3RoIGZvciBhbiBhcnJheSBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogbGVuZ3RoLiBOYXR1cmFsIHJ1bnMgc2hvcnRlciB0aGFuIHRoaXMgd2lsbCBiZSBleHRlbmRlZCB3aXRoCisgICAgICoge0BsaW5rICNiaW5hcnlTb3J0fS4KKyAgICAgKgorICAgICAqIFJvdWdobHkgc3BlYWtpbmcsIHRoZSBjb21wdXRhdGlvbiBpczoKKyAgICAgKgorICAgICAqICBJZiBuIDwgTUlOX01FUkdFLCByZXR1cm4gbiAoaXQncyB0b28gc21hbGwgdG8gYm90aGVyIHdpdGggZmFuY3kgc3R1ZmYpLgorICAgICAqICBFbHNlIGlmIG4gaXMgYW4gZXhhY3QgcG93ZXIgb2YgMiwgcmV0dXJuIE1JTl9NRVJHRS8yLgorICAgICAqICBFbHNlIHJldHVybiBhbiBpbnQgaywgTUlOX01FUkdFLzIgPD0gayA8PSBNSU5fTUVSR0UsIHN1Y2ggdGhhdCBuL2sKKyAgICAgKiAgIGlzIGNsb3NlIHRvLCBidXQgc3RyaWN0bHkgbGVzcyB0aGFuLCBhbiBleGFjdCBwb3dlciBvZiAyLgorICAgICAqCisgICAgICogRm9yIHRoZSByYXRpb25hbGUsIHNlZSBsaXN0c29ydC50eHQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbiB0aGUgbGVuZ3RoIG9mIHRoZSBhcnJheSB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIG1pbmltdW0gcnVuIHRvIGJlIG1lcmdlZAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCBtaW5SdW5MZW5ndGgoaW50IG4pIHsKKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbiA+PSAwOworICAgICAgICBpbnQgciA9IDA7ICAgICAgLy8gQmVjb21lcyAxIGlmIGFueSAxIGJpdHMgYXJlIHNoaWZ0ZWQgb2ZmCisgICAgICAgIHdoaWxlIChuID49IE1JTl9NRVJHRSkgeworICAgICAgICAgICAgciB8PSAobiAmIDEpOworICAgICAgICAgICAgbiA+Pj0gMTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbiArIHI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHVzaGVzIHRoZSBzcGVjaWZpZWQgcnVuIG9udG8gdGhlIHBlbmRpbmctcnVuIHN0YWNrLgorICAgICAqCisgICAgICogQHBhcmFtIHJ1bkJhc2UgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIHJ1bgorICAgICAqIEBwYXJhbSBydW5MZW4gIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIHJ1bgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwdXNoUnVuKGludCBydW5CYXNlLCBpbnQgcnVuTGVuKSB7CisgICAgICAgIHRoaXMucnVuQmFzZVtzdGFja1NpemVdID0gcnVuQmFzZTsKKyAgICAgICAgdGhpcy5ydW5MZW5bc3RhY2tTaXplXSA9IHJ1bkxlbjsKKyAgICAgICAgc3RhY2tTaXplKys7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXhhbWluZXMgdGhlIHN0YWNrIG9mIHJ1bnMgd2FpdGluZyB0byBiZSBtZXJnZWQgYW5kIG1lcmdlcyBhZGphY2VudCBydW5zCisgICAgICogdW50aWwgdGhlIHN0YWNrIGludmFyaWFudHMgYXJlIHJlZXN0YWJsaXNoZWQ6CisgICAgICoKKyAgICAgKiAgICAgMS4gcnVuTGVuW2kgLSAzXSA+IHJ1bkxlbltpIC0gMl0gKyBydW5MZW5baSAtIDFdCisgICAgICogICAgIDIuIHJ1bkxlbltpIC0gMl0gPiBydW5MZW5baSAtIDFdCisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgZWFjaCB0aW1lIGEgbmV3IHJ1biBpcyBwdXNoZWQgb250byB0aGUgc3RhY2ssCisgICAgICogc28gdGhlIGludmFyaWFudHMgYXJlIGd1YXJhbnRlZWQgdG8gaG9sZCBmb3IgaSA8IHN0YWNrU2l6ZSB1cG9uCisgICAgICogZW50cnkgdG8gdGhlIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgbWVyZ2VDb2xsYXBzZSgpIHsKKyAgICAgICAgd2hpbGUgKHN0YWNrU2l6ZSA+IDEpIHsKKyAgICAgICAgICAgIGludCBuID0gc3RhY2tTaXplIC0gMjsKKyAgICAgICAgICAgIGlmIChuID4gMCAmJiBydW5MZW5bbi0xXSA8PSBydW5MZW5bbl0gKyBydW5MZW5bbisxXSkgeworICAgICAgICAgICAgICAgIGlmIChydW5MZW5bbiAtIDFdIDwgcnVuTGVuW24gKyAxXSkKKyAgICAgICAgICAgICAgICAgICAgbi0tOworICAgICAgICAgICAgICAgIG1lcmdlQXQobik7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHJ1bkxlbltuXSA8PSBydW5MZW5bbiArIDFdKSB7CisgICAgICAgICAgICAgICAgbWVyZ2VBdChuKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYnJlYWs7IC8vIEludmFyaWFudCBpcyBlc3RhYmxpc2hlZAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTWVyZ2VzIGFsbCBydW5zIG9uIHRoZSBzdGFjayB1bnRpbCBvbmx5IG9uZSByZW1haW5zLiAgVGhpcyBtZXRob2QgaXMKKyAgICAgKiBjYWxsZWQgb25jZSwgdG8gY29tcGxldGUgdGhlIHNvcnQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIG1lcmdlRm9yY2VDb2xsYXBzZSgpIHsKKyAgICAgICAgd2hpbGUgKHN0YWNrU2l6ZSA+IDEpIHsKKyAgICAgICAgICAgIGludCBuID0gc3RhY2tTaXplIC0gMjsKKyAgICAgICAgICAgIGlmIChuID4gMCAmJiBydW5MZW5bbiAtIDFdIDwgcnVuTGVuW24gKyAxXSkKKyAgICAgICAgICAgICAgICBuLS07CisgICAgICAgICAgICBtZXJnZUF0KG4pOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTWVyZ2VzIHRoZSB0d28gcnVucyBhdCBzdGFjayBpbmRpY2VzIGkgYW5kIGkrMS4gIFJ1biBpIG11c3QgYmUKKyAgICAgKiB0aGUgcGVudWx0aW1hdGUgb3IgYW50ZXBlbnVsdGltYXRlIHJ1biBvbiB0aGUgc3RhY2suICBJbiBvdGhlciB3b3JkcywKKyAgICAgKiBpIG11c3QgYmUgZXF1YWwgdG8gc3RhY2tTaXplLTIgb3Igc3RhY2tTaXplLTMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaSBzdGFjayBpbmRleCBvZiB0aGUgZmlyc3Qgb2YgdGhlIHR3byBydW5zIHRvIG1lcmdlCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHJpdmF0ZSB2b2lkIG1lcmdlQXQoaW50IGkpIHsKKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgc3RhY2tTaXplID49IDI7CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGkgPj0gMDsKKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgaSA9PSBzdGFja1NpemUgLSAyIHx8IGkgPT0gc3RhY2tTaXplIC0gMzsKKworICAgICAgICBpbnQgYmFzZTEgPSBydW5CYXNlW2ldOworICAgICAgICBpbnQgbGVuMSA9IHJ1bkxlbltpXTsKKyAgICAgICAgaW50IGJhc2UyID0gcnVuQmFzZVtpICsgMV07CisgICAgICAgIGludCBsZW4yID0gcnVuTGVuW2kgKyAxXTsKKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbGVuMSA+IDAgJiYgbGVuMiA+IDA7CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGJhc2UxICsgbGVuMSA9PSBiYXNlMjsKKworICAgICAgICAvKgorICAgICAgICAgKiBSZWNvcmQgdGhlIGxlbmd0aCBvZiB0aGUgY29tYmluZWQgcnVuczsgaWYgaSBpcyB0aGUgM3JkLWxhc3QKKyAgICAgICAgICogcnVuIG5vdywgYWxzbyBzbGlkZSBvdmVyIHRoZSBsYXN0IHJ1biAod2hpY2ggaXNuJ3QgaW52b2x2ZWQKKyAgICAgICAgICogaW4gdGhpcyBtZXJnZSkuICBUaGUgY3VycmVudCBydW4gKGkrMSkgZ29lcyBhd2F5IGluIGFueSBjYXNlLgorICAgICAgICAgKi8KKyAgICAgICAgcnVuTGVuW2ldID0gbGVuMSArIGxlbjI7CisgICAgICAgIGlmIChpID09IHN0YWNrU2l6ZSAtIDMpIHsKKyAgICAgICAgICAgIHJ1bkJhc2VbaSArIDFdID0gcnVuQmFzZVtpICsgMl07CisgICAgICAgICAgICBydW5MZW5baSArIDFdID0gcnVuTGVuW2kgKyAyXTsKKyAgICAgICAgfQorICAgICAgICBzdGFja1NpemUtLTsKKworICAgICAgICAvKgorICAgICAgICAgKiBGaW5kIHdoZXJlIHRoZSBmaXJzdCBlbGVtZW50IG9mIHJ1bjIgZ29lcyBpbiBydW4xLiBQcmlvciBlbGVtZW50cworICAgICAgICAgKiBpbiBydW4xIGNhbiBiZSBpZ25vcmVkIChiZWNhdXNlIHRoZXkncmUgYWxyZWFkeSBpbiBwbGFjZSkuCisgICAgICAgICAqLworICAgICAgICBpbnQgayA9IGdhbGxvcFJpZ2h0KChDb21wYXJhYmxlPE9iamVjdD4pIGFbYmFzZTJdLCBhLCBiYXNlMSwgbGVuMSwgMCk7CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGsgPj0gMDsKKyAgICAgICAgYmFzZTEgKz0gazsKKyAgICAgICAgbGVuMSAtPSBrOworICAgICAgICBpZiAobGVuMSA9PSAwKQorICAgICAgICAgICAgcmV0dXJuOworCisgICAgICAgIC8qCisgICAgICAgICAqIEZpbmQgd2hlcmUgdGhlIGxhc3QgZWxlbWVudCBvZiBydW4xIGdvZXMgaW4gcnVuMi4gU3Vic2VxdWVudCBlbGVtZW50cworICAgICAgICAgKiBpbiBydW4yIGNhbiBiZSBpZ25vcmVkIChiZWNhdXNlIHRoZXkncmUgYWxyZWFkeSBpbiBwbGFjZSkuCisgICAgICAgICAqLworICAgICAgICBsZW4yID0gZ2FsbG9wTGVmdCgoQ29tcGFyYWJsZTxPYmplY3Q+KSBhW2Jhc2UxICsgbGVuMSAtIDFdLCBhLAorICAgICAgICAgICAgICAgIGJhc2UyLCBsZW4yLCBsZW4yIC0gMSk7CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxlbjIgPj0gMDsKKyAgICAgICAgaWYgKGxlbjIgPT0gMCkKKyAgICAgICAgICAgIHJldHVybjsKKworICAgICAgICAvLyBNZXJnZSByZW1haW5pbmcgcnVucywgdXNpbmcgdG1wIGFycmF5IHdpdGggbWluKGxlbjEsIGxlbjIpIGVsZW1lbnRzCisgICAgICAgIGlmIChsZW4xIDw9IGxlbjIpCisgICAgICAgICAgICBtZXJnZUxvKGJhc2UxLCBsZW4xLCBiYXNlMiwgbGVuMik7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIG1lcmdlSGkoYmFzZTEsIGxlbjEsIGJhc2UyLCBsZW4yKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2NhdGVzIHRoZSBwb3NpdGlvbiBhdCB3aGljaCB0byBpbnNlcnQgdGhlIHNwZWNpZmllZCBrZXkgaW50byB0aGUKKyAgICAgKiBzcGVjaWZpZWQgc29ydGVkIHJhbmdlOyBpZiB0aGUgcmFuZ2UgY29udGFpbnMgYW4gZWxlbWVudCBlcXVhbCB0byBrZXksCisgICAgICogcmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGxlZnRtb3N0IGVxdWFsIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkgd2hvc2UgaW5zZXJ0aW9uIHBvaW50IHRvIHNlYXJjaCBmb3IKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgaW4gd2hpY2ggdG8gc2VhcmNoCisgICAgICogQHBhcmFtIGJhc2UgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50IGluIHRoZSByYW5nZQorICAgICAqIEBwYXJhbSBsZW4gdGhlIGxlbmd0aCBvZiB0aGUgcmFuZ2U7IG11c3QgYmUgPiAwCisgICAgICogQHBhcmFtIGhpbnQgdGhlIGluZGV4IGF0IHdoaWNoIHRvIGJlZ2luIHRoZSBzZWFyY2gsIDAgPD0gaGludCA8IG4uCisgICAgICogICAgIFRoZSBjbG9zZXIgaGludCBpcyB0byB0aGUgcmVzdWx0LCB0aGUgZmFzdGVyIHRoaXMgbWV0aG9kIHdpbGwgcnVuLgorICAgICAqIEByZXR1cm4gdGhlIGludCBrLCAgMCA8PSBrIDw9IG4gc3VjaCB0aGF0IGFbYiArIGsgLSAxXSA8IGtleSA8PSBhW2IgKyBrXSwKKyAgICAgKiAgICBwcmV0ZW5kaW5nIHRoYXQgYVtiIC0gMV0gaXMgbWludXMgaW5maW5pdHkgYW5kIGFbYiArIG5dIGlzIGluZmluaXR5LgorICAgICAqICAgIEluIG90aGVyIHdvcmRzLCBrZXkgYmVsb25ncyBhdCBpbmRleCBiICsgazsgb3IgaW4gb3RoZXIgd29yZHMsCisgICAgICogICAgdGhlIGZpcnN0IGsgZWxlbWVudHMgb2YgYSBzaG91bGQgcHJlY2VkZSBrZXksIGFuZCB0aGUgbGFzdCBuIC0gaworICAgICAqICAgIHNob3VsZCBmb2xsb3cgaXQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGdhbGxvcExlZnQoQ29tcGFyYWJsZTxPYmplY3Q+IGtleSwgT2JqZWN0W10gYSwKKyAgICAgICAgICAgIGludCBiYXNlLCBpbnQgbGVuLCBpbnQgaGludCkgeworICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBsZW4gPiAwICYmIGhpbnQgPj0gMCAmJiBoaW50IDwgbGVuOworCisgICAgICAgIGludCBsYXN0T2ZzID0gMDsKKyAgICAgICAgaW50IG9mcyA9IDE7CisgICAgICAgIGlmIChrZXkuY29tcGFyZVRvKGFbYmFzZSArIGhpbnRdKSA+IDApIHsKKyAgICAgICAgICAgIC8vIEdhbGxvcCByaWdodCB1bnRpbCBhW2Jhc2UraGludCtsYXN0T2ZzXSA8IGtleSA8PSBhW2Jhc2UraGludCtvZnNdCisgICAgICAgICAgICBpbnQgbWF4T2ZzID0gbGVuIC0gaGludDsKKyAgICAgICAgICAgIHdoaWxlIChvZnMgPCBtYXhPZnMgJiYga2V5LmNvbXBhcmVUbyhhW2Jhc2UgKyBoaW50ICsgb2ZzXSkgPiAwKSB7CisgICAgICAgICAgICAgICAgbGFzdE9mcyA9IG9mczsKKyAgICAgICAgICAgICAgICBvZnMgPSAob2ZzIDw8IDEpICsgMTsKKyAgICAgICAgICAgICAgICBpZiAob2ZzIDw9IDApICAgLy8gaW50IG92ZXJmbG93CisgICAgICAgICAgICAgICAgICAgIG9mcyA9IG1heE9mczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChvZnMgPiBtYXhPZnMpCisgICAgICAgICAgICAgICAgb2ZzID0gbWF4T2ZzOworCisgICAgICAgICAgICAvLyBNYWtlIG9mZnNldHMgcmVsYXRpdmUgdG8gYmFzZQorICAgICAgICAgICAgbGFzdE9mcyArPSBoaW50OworICAgICAgICAgICAgb2ZzICs9IGhpbnQ7CisgICAgICAgIH0gZWxzZSB7IC8vIGtleSA8PSBhW2Jhc2UgKyBoaW50XQorICAgICAgICAgICAgLy8gR2FsbG9wIGxlZnQgdW50aWwgYVtiYXNlK2hpbnQtb2ZzXSA8IGtleSA8PSBhW2Jhc2UraGludC1sYXN0T2ZzXQorICAgICAgICAgICAgZmluYWwgaW50IG1heE9mcyA9IGhpbnQgKyAxOworICAgICAgICAgICAgd2hpbGUgKG9mcyA8IG1heE9mcyAmJiBrZXkuY29tcGFyZVRvKGFbYmFzZSArIGhpbnQgLSBvZnNdKSA8PSAwKSB7CisgICAgICAgICAgICAgICAgbGFzdE9mcyA9IG9mczsKKyAgICAgICAgICAgICAgICBvZnMgPSAob2ZzIDw8IDEpICsgMTsKKyAgICAgICAgICAgICAgICBpZiAob2ZzIDw9IDApICAgLy8gaW50IG92ZXJmbG93CisgICAgICAgICAgICAgICAgICAgIG9mcyA9IG1heE9mczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChvZnMgPiBtYXhPZnMpCisgICAgICAgICAgICAgICAgb2ZzID0gbWF4T2ZzOworCisgICAgICAgICAgICAvLyBNYWtlIG9mZnNldHMgcmVsYXRpdmUgdG8gYmFzZQorICAgICAgICAgICAgaW50IHRtcCA9IGxhc3RPZnM7CisgICAgICAgICAgICBsYXN0T2ZzID0gaGludCAtIG9mczsKKyAgICAgICAgICAgIG9mcyA9IGhpbnQgLSB0bXA7CisgICAgICAgIH0KKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgLTEgPD0gbGFzdE9mcyAmJiBsYXN0T2ZzIDwgb2ZzICYmIG9mcyA8PSBsZW47CisKKyAgICAgICAgLyoKKyAgICAgICAgICogTm93IGFbYmFzZStsYXN0T2ZzXSA8IGtleSA8PSBhW2Jhc2Urb2ZzXSwgc28ga2V5IGJlbG9uZ3Mgc29tZXdoZXJlCisgICAgICAgICAqIHRvIHRoZSByaWdodCBvZiBsYXN0T2ZzIGJ1dCBubyBmYXJ0aGVyIHJpZ2h0IHRoYW4gb2ZzLiAgRG8gYSBiaW5hcnkKKyAgICAgICAgICogc2VhcmNoLCB3aXRoIGludmFyaWFudCBhW2Jhc2UgKyBsYXN0T2ZzIC0gMV0gPCBrZXkgPD0gYVtiYXNlICsgb2ZzXS4KKyAgICAgICAgICovCisgICAgICAgIGxhc3RPZnMrKzsKKyAgICAgICAgd2hpbGUgKGxhc3RPZnMgPCBvZnMpIHsKKyAgICAgICAgICAgIGludCBtID0gbGFzdE9mcyArICgob2ZzIC0gbGFzdE9mcykgPj4+IDEpOworCisgICAgICAgICAgICBpZiAoa2V5LmNvbXBhcmVUbyhhW2Jhc2UgKyBtXSkgPiAwKQorICAgICAgICAgICAgICAgIGxhc3RPZnMgPSBtICsgMTsgIC8vIGFbYmFzZSArIG1dIDwga2V5CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgb2ZzID0gbTsgICAgICAgICAgLy8ga2V5IDw9IGFbYmFzZSArIG1dCisgICAgICAgIH0KKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbGFzdE9mcyA9PSBvZnM7ICAgIC8vIHNvIGFbYmFzZSArIG9mcyAtIDFdIDwga2V5IDw9IGFbYmFzZSArIG9mc10KKyAgICAgICAgcmV0dXJuIG9mczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMaWtlIGdhbGxvcExlZnQsIGV4Y2VwdCB0aGF0IGlmIHRoZSByYW5nZSBjb250YWlucyBhbiBlbGVtZW50IGVxdWFsIHRvCisgICAgICoga2V5LCBnYWxsb3BSaWdodCByZXR1cm5zIHRoZSBpbmRleCBhZnRlciB0aGUgcmlnaHRtb3N0IGVxdWFsIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkgd2hvc2UgaW5zZXJ0aW9uIHBvaW50IHRvIHNlYXJjaCBmb3IKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgaW4gd2hpY2ggdG8gc2VhcmNoCisgICAgICogQHBhcmFtIGJhc2UgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50IGluIHRoZSByYW5nZQorICAgICAqIEBwYXJhbSBsZW4gdGhlIGxlbmd0aCBvZiB0aGUgcmFuZ2U7IG11c3QgYmUgPiAwCisgICAgICogQHBhcmFtIGhpbnQgdGhlIGluZGV4IGF0IHdoaWNoIHRvIGJlZ2luIHRoZSBzZWFyY2gsIDAgPD0gaGludCA8IG4uCisgICAgICogICAgIFRoZSBjbG9zZXIgaGludCBpcyB0byB0aGUgcmVzdWx0LCB0aGUgZmFzdGVyIHRoaXMgbWV0aG9kIHdpbGwgcnVuLgorICAgICAqIEByZXR1cm4gdGhlIGludCBrLCAgMCA8PSBrIDw9IG4gc3VjaCB0aGF0IGFbYiArIGsgLSAxXSA8PSBrZXkgPCBhW2IgKyBrXQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCBnYWxsb3BSaWdodChDb21wYXJhYmxlPE9iamVjdD4ga2V5LCBPYmplY3RbXSBhLAorICAgICAgICAgICAgaW50IGJhc2UsIGludCBsZW4sIGludCBoaW50KSB7CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxlbiA+IDAgJiYgaGludCA+PSAwICYmIGhpbnQgPCBsZW47CisKKyAgICAgICAgaW50IG9mcyA9IDE7CisgICAgICAgIGludCBsYXN0T2ZzID0gMDsKKyAgICAgICAgaWYgKGtleS5jb21wYXJlVG8oYVtiYXNlICsgaGludF0pIDwgMCkgeworICAgICAgICAgICAgLy8gR2FsbG9wIGxlZnQgdW50aWwgYVtiK2hpbnQgLSBvZnNdIDw9IGtleSA8IGFbYitoaW50IC0gbGFzdE9mc10KKyAgICAgICAgICAgIGludCBtYXhPZnMgPSBoaW50ICsgMTsKKyAgICAgICAgICAgIHdoaWxlIChvZnMgPCBtYXhPZnMgJiYga2V5LmNvbXBhcmVUbyhhW2Jhc2UgKyBoaW50IC0gb2ZzXSkgPCAwKSB7CisgICAgICAgICAgICAgICAgbGFzdE9mcyA9IG9mczsKKyAgICAgICAgICAgICAgICBvZnMgPSAob2ZzIDw8IDEpICsgMTsKKyAgICAgICAgICAgICAgICBpZiAob2ZzIDw9IDApICAgLy8gaW50IG92ZXJmbG93CisgICAgICAgICAgICAgICAgICAgIG9mcyA9IG1heE9mczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChvZnMgPiBtYXhPZnMpCisgICAgICAgICAgICAgICAgb2ZzID0gbWF4T2ZzOworCisgICAgICAgICAgICAvLyBNYWtlIG9mZnNldHMgcmVsYXRpdmUgdG8gYgorICAgICAgICAgICAgaW50IHRtcCA9IGxhc3RPZnM7CisgICAgICAgICAgICBsYXN0T2ZzID0gaGludCAtIG9mczsKKyAgICAgICAgICAgIG9mcyA9IGhpbnQgLSB0bXA7CisgICAgICAgIH0gZWxzZSB7IC8vIGFbYiArIGhpbnRdIDw9IGtleQorICAgICAgICAgICAgLy8gR2FsbG9wIHJpZ2h0IHVudGlsIGFbYitoaW50ICsgbGFzdE9mc10gPD0ga2V5IDwgYVtiK2hpbnQgKyBvZnNdCisgICAgICAgICAgICBpbnQgbWF4T2ZzID0gbGVuIC0gaGludDsKKyAgICAgICAgICAgIHdoaWxlIChvZnMgPCBtYXhPZnMgJiYga2V5LmNvbXBhcmVUbyhhW2Jhc2UgKyBoaW50ICsgb2ZzXSkgPj0gMCkgeworICAgICAgICAgICAgICAgIGxhc3RPZnMgPSBvZnM7CisgICAgICAgICAgICAgICAgb2ZzID0gKG9mcyA8PCAxKSArIDE7CisgICAgICAgICAgICAgICAgaWYgKG9mcyA8PSAwKSAgIC8vIGludCBvdmVyZmxvdworICAgICAgICAgICAgICAgICAgICBvZnMgPSBtYXhPZnM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAob2ZzID4gbWF4T2ZzKQorICAgICAgICAgICAgICAgIG9mcyA9IG1heE9mczsKKworICAgICAgICAgICAgLy8gTWFrZSBvZmZzZXRzIHJlbGF0aXZlIHRvIGIKKyAgICAgICAgICAgIGxhc3RPZnMgKz0gaGludDsKKyAgICAgICAgICAgIG9mcyArPSBoaW50OworICAgICAgICB9CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IC0xIDw9IGxhc3RPZnMgJiYgbGFzdE9mcyA8IG9mcyAmJiBvZnMgPD0gbGVuOworCisgICAgICAgIC8qCisgICAgICAgICAqIE5vdyBhW2IgKyBsYXN0T2ZzXSA8PSBrZXkgPCBhW2IgKyBvZnNdLCBzbyBrZXkgYmVsb25ncyBzb21ld2hlcmUgdG8KKyAgICAgICAgICogdGhlIHJpZ2h0IG9mIGxhc3RPZnMgYnV0IG5vIGZhcnRoZXIgcmlnaHQgdGhhbiBvZnMuICBEbyBhIGJpbmFyeQorICAgICAgICAgKiBzZWFyY2gsIHdpdGggaW52YXJpYW50IGFbYiArIGxhc3RPZnMgLSAxXSA8PSBrZXkgPCBhW2IgKyBvZnNdLgorICAgICAgICAgKi8KKyAgICAgICAgbGFzdE9mcysrOworICAgICAgICB3aGlsZSAobGFzdE9mcyA8IG9mcykgeworICAgICAgICAgICAgaW50IG0gPSBsYXN0T2ZzICsgKChvZnMgLSBsYXN0T2ZzKSA+Pj4gMSk7CisKKyAgICAgICAgICAgIGlmIChrZXkuY29tcGFyZVRvKGFbYmFzZSArIG1dKSA8IDApCisgICAgICAgICAgICAgICAgb2ZzID0gbTsgICAgICAgICAgLy8ga2V5IDwgYVtiICsgbV0KKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBsYXN0T2ZzID0gbSArIDE7ICAvLyBhW2IgKyBtXSA8PSBrZXkKKyAgICAgICAgfQorICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBsYXN0T2ZzID09IG9mczsgICAgLy8gc28gYVtiICsgb2ZzIC0gMV0gPD0ga2V5IDwgYVtiICsgb2ZzXQorICAgICAgICByZXR1cm4gb2ZzOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1lcmdlcyB0d28gYWRqYWNlbnQgcnVucyBpbiBwbGFjZSwgaW4gYSBzdGFibGUgZmFzaGlvbi4gIFRoZSBmaXJzdAorICAgICAqIGVsZW1lbnQgb2YgdGhlIGZpcnN0IHJ1biBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGUKKyAgICAgKiBzZWNvbmQgcnVuIChhW2Jhc2UxXSA+IGFbYmFzZTJdKSwgYW5kIHRoZSBsYXN0IGVsZW1lbnQgb2YgdGhlIGZpcnN0IHJ1bgorICAgICAqIChhW2Jhc2UxICsgbGVuMS0xXSkgbXVzdCBiZSBncmVhdGVyIHRoYW4gYWxsIGVsZW1lbnRzIG9mIHRoZSBzZWNvbmQgcnVuLgorICAgICAqCisgICAgICogRm9yIHBlcmZvcm1hbmNlLCB0aGlzIG1ldGhvZCBzaG91bGQgYmUgY2FsbGVkIG9ubHkgd2hlbiBsZW4xIDw9IGxlbjI7CisgICAgICogaXRzIHR3aW4sIG1lcmdlSGkgc2hvdWxkIGJlIGNhbGxlZCBpZiBsZW4xID49IGxlbjIuICAoRWl0aGVyIG1ldGhvZAorICAgICAqIG1heSBiZSBjYWxsZWQgaWYgbGVuMSA9PSBsZW4yLikKKyAgICAgKgorICAgICAqIEBwYXJhbSBiYXNlMSBpbmRleCBvZiBmaXJzdCBlbGVtZW50IGluIGZpcnN0IHJ1biB0byBiZSBtZXJnZWQKKyAgICAgKiBAcGFyYW0gbGVuMSAgbGVuZ3RoIG9mIGZpcnN0IHJ1biB0byBiZSBtZXJnZWQgKG11c3QgYmUgPiAwKQorICAgICAqIEBwYXJhbSBiYXNlMiBpbmRleCBvZiBmaXJzdCBlbGVtZW50IGluIHNlY29uZCBydW4gdG8gYmUgbWVyZ2VkCisgICAgICogICAgICAgIChtdXN0IGJlIGFCYXNlICsgYUxlbikKKyAgICAgKiBAcGFyYW0gbGVuMiAgbGVuZ3RoIG9mIHNlY29uZCBydW4gdG8gYmUgbWVyZ2VkIChtdXN0IGJlID4gMCkKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIHZvaWQgbWVyZ2VMbyhpbnQgYmFzZTEsIGludCBsZW4xLCBpbnQgYmFzZTIsIGludCBsZW4yKSB7CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxlbjEgPiAwICYmIGxlbjIgPiAwICYmIGJhc2UxICsgbGVuMSA9PSBiYXNlMjsKKworICAgICAgICAvLyBDb3B5IGZpcnN0IHJ1biBpbnRvIHRlbXAgYXJyYXkKKyAgICAgICAgT2JqZWN0W10gYSA9IHRoaXMuYTsgLy8gRm9yIHBlcmZvcm1hbmNlCisgICAgICAgIE9iamVjdFtdIHRtcCA9IGVuc3VyZUNhcGFjaXR5KGxlbjEpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIGJhc2UxLCB0bXAsIDAsIGxlbjEpOworCisgICAgICAgIGludCBjdXJzb3IxID0gMDsgICAgICAgLy8gSW5kZXhlcyBpbnRvIHRtcCBhcnJheQorICAgICAgICBpbnQgY3Vyc29yMiA9IGJhc2UyOyAgIC8vIEluZGV4ZXMgaW50IGEKKyAgICAgICAgaW50IGRlc3QgPSBiYXNlMTsgICAgICAvLyBJbmRleGVzIGludCBhCisKKyAgICAgICAgLy8gTW92ZSBmaXJzdCBlbGVtZW50IG9mIHNlY29uZCBydW4gYW5kIGRlYWwgd2l0aCBkZWdlbmVyYXRlIGNhc2VzCisgICAgICAgIGFbZGVzdCsrXSA9IGFbY3Vyc29yMisrXTsKKyAgICAgICAgaWYgKC0tbGVuMiA9PSAwKSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRtcCwgY3Vyc29yMSwgYSwgZGVzdCwgbGVuMSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxlbjEgPT0gMSkgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhLCBjdXJzb3IyLCBhLCBkZXN0LCBsZW4yKTsKKyAgICAgICAgICAgIGFbZGVzdCArIGxlbjJdID0gdG1wW2N1cnNvcjFdOyAvLyBMYXN0IGVsdCBvZiBydW4gMSB0byBlbmQgb2YgbWVyZ2UKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGludCBtaW5HYWxsb3AgPSB0aGlzLm1pbkdhbGxvcDsgIC8vIFVzZSBsb2NhbCB2YXJpYWJsZSBmb3IgcGVyZm9ybWFuY2UKKyAgICBvdXRlcjoKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIGludCBjb3VudDEgPSAwOyAvLyBOdW1iZXIgb2YgdGltZXMgaW4gYSByb3cgdGhhdCBmaXJzdCBydW4gd29uCisgICAgICAgICAgICBpbnQgY291bnQyID0gMDsgLy8gTnVtYmVyIG9mIHRpbWVzIGluIGEgcm93IHRoYXQgc2Vjb25kIHJ1biB3b24KKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIERvIHRoZSBzdHJhaWdodGZvcndhcmQgdGhpbmcgdW50aWwgKGlmIGV2ZXIpIG9uZSBydW4gc3RhcnRzCisgICAgICAgICAgICAgKiB3aW5uaW5nIGNvbnNpc3RlbnRseS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxlbjEgPiAxICYmIGxlbjIgPiAwOworICAgICAgICAgICAgICAgIGlmICgoKENvbXBhcmFibGUpIGFbY3Vyc29yMl0pLmNvbXBhcmVUbyh0bXBbY3Vyc29yMV0pIDwgMCkgeworICAgICAgICAgICAgICAgICAgICBhW2Rlc3QrK10gPSBhW2N1cnNvcjIrK107CisgICAgICAgICAgICAgICAgICAgIGNvdW50MisrOworICAgICAgICAgICAgICAgICAgICBjb3VudDEgPSAwOworICAgICAgICAgICAgICAgICAgICBpZiAoLS1sZW4yID09IDApCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBhW2Rlc3QrK10gPSB0bXBbY3Vyc29yMSsrXTsKKyAgICAgICAgICAgICAgICAgICAgY291bnQxKys7CisgICAgICAgICAgICAgICAgICAgIGNvdW50MiA9IDA7CisgICAgICAgICAgICAgICAgICAgIGlmICgtLWxlbjEgPT0gMSkKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gd2hpbGUgKChjb3VudDEgfCBjb3VudDIpIDwgbWluR2FsbG9wKTsKKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIE9uZSBydW4gaXMgd2lubmluZyBzbyBjb25zaXN0ZW50bHkgdGhhdCBnYWxsb3BpbmcgbWF5IGJlIGEKKyAgICAgICAgICAgICAqIGh1Z2Ugd2luLiBTbyB0cnkgdGhhdCwgYW5kIGNvbnRpbnVlIGdhbGxvcGluZyB1bnRpbCAoaWYgZXZlcikKKyAgICAgICAgICAgICAqIG5laXRoZXIgcnVuIGFwcGVhcnMgdG8gYmUgd2lubmluZyBjb25zaXN0ZW50bHkgYW55bW9yZS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxlbjEgPiAxICYmIGxlbjIgPiAwOworICAgICAgICAgICAgICAgIGNvdW50MSA9IGdhbGxvcFJpZ2h0KChDb21wYXJhYmxlKSBhW2N1cnNvcjJdLCB0bXAsIGN1cnNvcjEsIGxlbjEsIDApOworICAgICAgICAgICAgICAgIGlmIChjb3VudDEgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRtcCwgY3Vyc29yMSwgYSwgZGVzdCwgY291bnQxKTsKKyAgICAgICAgICAgICAgICAgICAgZGVzdCArPSBjb3VudDE7CisgICAgICAgICAgICAgICAgICAgIGN1cnNvcjEgKz0gY291bnQxOworICAgICAgICAgICAgICAgICAgICBsZW4xIC09IGNvdW50MTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGxlbjEgPD0gMSkgIC8vIGxlbjEgPT0gMSB8fCBsZW4xID09IDAKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhW2Rlc3QrK10gPSBhW2N1cnNvcjIrK107CisgICAgICAgICAgICAgICAgaWYgKC0tbGVuMiA9PSAwKQorICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjsKKworICAgICAgICAgICAgICAgIGNvdW50MiA9IGdhbGxvcExlZnQoKENvbXBhcmFibGUpIHRtcFtjdXJzb3IxXSwgYSwgY3Vyc29yMiwgbGVuMiwgMCk7CisgICAgICAgICAgICAgICAgaWYgKGNvdW50MiAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYSwgY3Vyc29yMiwgYSwgZGVzdCwgY291bnQyKTsKKyAgICAgICAgICAgICAgICAgICAgZGVzdCArPSBjb3VudDI7CisgICAgICAgICAgICAgICAgICAgIGN1cnNvcjIgKz0gY291bnQyOworICAgICAgICAgICAgICAgICAgICBsZW4yIC09IGNvdW50MjsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGxlbjIgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhW2Rlc3QrK10gPSB0bXBbY3Vyc29yMSsrXTsKKyAgICAgICAgICAgICAgICBpZiAoLS1sZW4xID09IDEpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworICAgICAgICAgICAgICAgIG1pbkdhbGxvcC0tOworICAgICAgICAgICAgfSB3aGlsZSAoY291bnQxID49IE1JTl9HQUxMT1AgfCBjb3VudDIgPj0gTUlOX0dBTExPUCk7CisgICAgICAgICAgICBpZiAobWluR2FsbG9wIDwgMCkKKyAgICAgICAgICAgICAgICBtaW5HYWxsb3AgPSAwOworICAgICAgICAgICAgbWluR2FsbG9wICs9IDI7ICAvLyBQZW5hbGl6ZSBmb3IgbGVhdmluZyBnYWxsb3AgbW9kZQorICAgICAgICB9ICAvLyBFbmQgb2YgIm91dGVyIiBsb29wCisgICAgICAgIHRoaXMubWluR2FsbG9wID0gbWluR2FsbG9wIDwgMSA/IDEgOiBtaW5HYWxsb3A7ICAvLyBXcml0ZSBiYWNrIHRvIGZpZWxkCisKKyAgICAgICAgaWYgKGxlbjEgPT0gMSkgeworICAgICAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbGVuMiA+IDA7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIGN1cnNvcjIsIGEsIGRlc3QsIGxlbjIpOworICAgICAgICAgICAgYVtkZXN0ICsgbGVuMl0gPSB0bXBbY3Vyc29yMV07IC8vICBMYXN0IGVsdCBvZiBydW4gMSB0byBlbmQgb2YgbWVyZ2UKKyAgICAgICAgfSBlbHNlIGlmIChsZW4xID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgIkNvbXBhcmlzb24gbWV0aG9kIHZpb2xhdGVzIGl0cyBnZW5lcmFsIGNvbnRyYWN0ISIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbGVuMiA9PSAwOworICAgICAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbGVuMSA+IDE7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRtcCwgY3Vyc29yMSwgYSwgZGVzdCwgbGVuMSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMaWtlIG1lcmdlTG8sIGV4Y2VwdCB0aGF0IHRoaXMgbWV0aG9kIHNob3VsZCBiZSBjYWxsZWQgb25seSBpZgorICAgICAqIGxlbjEgPj0gbGVuMjsgbWVyZ2VMbyBzaG91bGQgYmUgY2FsbGVkIGlmIGxlbjEgPD0gbGVuMi4gIChFaXRoZXIgbWV0aG9kCisgICAgICogbWF5IGJlIGNhbGxlZCBpZiBsZW4xID09IGxlbjIuKQorICAgICAqCisgICAgICogQHBhcmFtIGJhc2UxIGluZGV4IG9mIGZpcnN0IGVsZW1lbnQgaW4gZmlyc3QgcnVuIHRvIGJlIG1lcmdlZAorICAgICAqIEBwYXJhbSBsZW4xICBsZW5ndGggb2YgZmlyc3QgcnVuIHRvIGJlIG1lcmdlZCAobXVzdCBiZSA+IDApCisgICAgICogQHBhcmFtIGJhc2UyIGluZGV4IG9mIGZpcnN0IGVsZW1lbnQgaW4gc2Vjb25kIHJ1biB0byBiZSBtZXJnZWQKKyAgICAgKiAgICAgICAgKG11c3QgYmUgYUJhc2UgKyBhTGVuKQorICAgICAqIEBwYXJhbSBsZW4yICBsZW5ndGggb2Ygc2Vjb25kIHJ1biB0byBiZSBtZXJnZWQgKG11c3QgYmUgPiAwKQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHByaXZhdGUgdm9pZCBtZXJnZUhpKGludCBiYXNlMSwgaW50IGxlbjEsIGludCBiYXNlMiwgaW50IGxlbjIpIHsKKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbGVuMSA+IDAgJiYgbGVuMiA+IDAgJiYgYmFzZTEgKyBsZW4xID09IGJhc2UyOworCisgICAgICAgIC8vIENvcHkgc2Vjb25kIHJ1biBpbnRvIHRlbXAgYXJyYXkKKyAgICAgICAgT2JqZWN0W10gYSA9IHRoaXMuYTsgLy8gRm9yIHBlcmZvcm1hbmNlCisgICAgICAgIE9iamVjdFtdIHRtcCA9IGVuc3VyZUNhcGFjaXR5KGxlbjIpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIGJhc2UyLCB0bXAsIDAsIGxlbjIpOworCisgICAgICAgIGludCBjdXJzb3IxID0gYmFzZTEgKyBsZW4xIC0gMTsgIC8vIEluZGV4ZXMgaW50byBhCisgICAgICAgIGludCBjdXJzb3IyID0gbGVuMiAtIDE7ICAgICAgICAgIC8vIEluZGV4ZXMgaW50byB0bXAgYXJyYXkKKyAgICAgICAgaW50IGRlc3QgPSBiYXNlMiArIGxlbjIgLSAxOyAgICAgLy8gSW5kZXhlcyBpbnRvIGEKKworICAgICAgICAvLyBNb3ZlIGxhc3QgZWxlbWVudCBvZiBmaXJzdCBydW4gYW5kIGRlYWwgd2l0aCBkZWdlbmVyYXRlIGNhc2VzCisgICAgICAgIGFbZGVzdC0tXSA9IGFbY3Vyc29yMS0tXTsKKyAgICAgICAgaWYgKC0tbGVuMSA9PSAwKSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRtcCwgMCwgYSwgZGVzdCAtIChsZW4yIC0gMSksIGxlbjIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGlmIChsZW4yID09IDEpIHsKKyAgICAgICAgICAgIGRlc3QgLT0gbGVuMTsKKyAgICAgICAgICAgIGN1cnNvcjEgLT0gbGVuMTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYSwgY3Vyc29yMSArIDEsIGEsIGRlc3QgKyAxLCBsZW4xKTsKKyAgICAgICAgICAgIGFbZGVzdF0gPSB0bXBbY3Vyc29yMl07CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpbnQgbWluR2FsbG9wID0gdGhpcy5taW5HYWxsb3A7ICAvLyBVc2UgbG9jYWwgdmFyaWFibGUgZm9yIHBlcmZvcm1hbmNlCisgICAgb3V0ZXI6CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBpbnQgY291bnQxID0gMDsgLy8gTnVtYmVyIG9mIHRpbWVzIGluIGEgcm93IHRoYXQgZmlyc3QgcnVuIHdvbgorICAgICAgICAgICAgaW50IGNvdW50MiA9IDA7IC8vIE51bWJlciBvZiB0aW1lcyBpbiBhIHJvdyB0aGF0IHNlY29uZCBydW4gd29uCisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBEbyB0aGUgc3RyYWlnaHRmb3J3YXJkIHRoaW5nIHVudGlsIChpZiBldmVyKSBvbmUgcnVuCisgICAgICAgICAgICAgKiBhcHBlYXJzIHRvIHdpbiBjb25zaXN0ZW50bHkuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBsZW4xID4gMCAmJiBsZW4yID4gMTsKKyAgICAgICAgICAgICAgICBpZiAoKChDb21wYXJhYmxlKSB0bXBbY3Vyc29yMl0pLmNvbXBhcmVUbyhhW2N1cnNvcjFdKSA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgYVtkZXN0LS1dID0gYVtjdXJzb3IxLS1dOworICAgICAgICAgICAgICAgICAgICBjb3VudDErKzsKKyAgICAgICAgICAgICAgICAgICAgY291bnQyID0gMDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKC0tbGVuMSA9PSAwKQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYVtkZXN0LS1dID0gdG1wW2N1cnNvcjItLV07CisgICAgICAgICAgICAgICAgICAgIGNvdW50MisrOworICAgICAgICAgICAgICAgICAgICBjb3VudDEgPSAwOworICAgICAgICAgICAgICAgICAgICBpZiAoLS1sZW4yID09IDEpCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IHdoaWxlICgoY291bnQxIHwgY291bnQyKSA8IG1pbkdhbGxvcCk7CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBPbmUgcnVuIGlzIHdpbm5pbmcgc28gY29uc2lzdGVudGx5IHRoYXQgZ2FsbG9waW5nIG1heSBiZSBhCisgICAgICAgICAgICAgKiBodWdlIHdpbi4gU28gdHJ5IHRoYXQsIGFuZCBjb250aW51ZSBnYWxsb3BpbmcgdW50aWwgKGlmIGV2ZXIpCisgICAgICAgICAgICAgKiBuZWl0aGVyIHJ1biBhcHBlYXJzIHRvIGJlIHdpbm5pbmcgY29uc2lzdGVudGx5IGFueW1vcmUuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBsZW4xID4gMCAmJiBsZW4yID4gMTsKKyAgICAgICAgICAgICAgICBjb3VudDEgPSBsZW4xIC0gZ2FsbG9wUmlnaHQoKENvbXBhcmFibGUpIHRtcFtjdXJzb3IyXSwgYSwgYmFzZTEsIGxlbjEsIGxlbjEgLSAxKTsKKyAgICAgICAgICAgICAgICBpZiAoY291bnQxICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgZGVzdCAtPSBjb3VudDE7CisgICAgICAgICAgICAgICAgICAgIGN1cnNvcjEgLT0gY291bnQxOworICAgICAgICAgICAgICAgICAgICBsZW4xIC09IGNvdW50MTsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhLCBjdXJzb3IxICsgMSwgYSwgZGVzdCArIDEsIGNvdW50MSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChsZW4xID09IDApCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYVtkZXN0LS1dID0gdG1wW2N1cnNvcjItLV07CisgICAgICAgICAgICAgICAgaWYgKC0tbGVuMiA9PSAxKQorICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjsKKworICAgICAgICAgICAgICAgIGNvdW50MiA9IGxlbjIgLSBnYWxsb3BMZWZ0KChDb21wYXJhYmxlKSBhW2N1cnNvcjFdLCB0bXAsIDAsIGxlbjIsIGxlbjIgLSAxKTsKKyAgICAgICAgICAgICAgICBpZiAoY291bnQyICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgZGVzdCAtPSBjb3VudDI7CisgICAgICAgICAgICAgICAgICAgIGN1cnNvcjIgLT0gY291bnQyOworICAgICAgICAgICAgICAgICAgICBsZW4yIC09IGNvdW50MjsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0bXAsIGN1cnNvcjIgKyAxLCBhLCBkZXN0ICsgMSwgY291bnQyKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGxlbjIgPD0gMSkKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOyAvLyBsZW4yID09IDEgfHwgbGVuMiA9PSAwCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFbZGVzdC0tXSA9IGFbY3Vyc29yMS0tXTsKKyAgICAgICAgICAgICAgICBpZiAoLS1sZW4xID09IDApCisgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworICAgICAgICAgICAgICAgIG1pbkdhbGxvcC0tOworICAgICAgICAgICAgfSB3aGlsZSAoY291bnQxID49IE1JTl9HQUxMT1AgfCBjb3VudDIgPj0gTUlOX0dBTExPUCk7CisgICAgICAgICAgICBpZiAobWluR2FsbG9wIDwgMCkKKyAgICAgICAgICAgICAgICBtaW5HYWxsb3AgPSAwOworICAgICAgICAgICAgbWluR2FsbG9wICs9IDI7ICAvLyBQZW5hbGl6ZSBmb3IgbGVhdmluZyBnYWxsb3AgbW9kZQorICAgICAgICB9ICAvLyBFbmQgb2YgIm91dGVyIiBsb29wCisgICAgICAgIHRoaXMubWluR2FsbG9wID0gbWluR2FsbG9wIDwgMSA/IDEgOiBtaW5HYWxsb3A7ICAvLyBXcml0ZSBiYWNrIHRvIGZpZWxkCisKKyAgICAgICAgaWYgKGxlbjIgPT0gMSkgeworICAgICAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbGVuMSA+IDA7CisgICAgICAgICAgICBkZXN0IC09IGxlbjE7CisgICAgICAgICAgICBjdXJzb3IxIC09IGxlbjE7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIGN1cnNvcjEgKyAxLCBhLCBkZXN0ICsgMSwgbGVuMSk7CisgICAgICAgICAgICBhW2Rlc3RdID0gdG1wW2N1cnNvcjJdOyAgLy8gTW92ZSBmaXJzdCBlbHQgb2YgcnVuMiB0byBmcm9udCBvZiBtZXJnZQorICAgICAgICB9IGVsc2UgaWYgKGxlbjIgPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiQ29tcGFyaXNvbiBtZXRob2QgdmlvbGF0ZXMgaXRzIGdlbmVyYWwgY29udHJhY3QhIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBsZW4xID09IDA7CisgICAgICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBsZW4yID4gMDsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodG1wLCAwLCBhLCBkZXN0IC0gKGxlbjIgLSAxKSwgbGVuMik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbnN1cmVzIHRoYXQgdGhlIGV4dGVybmFsIGFycmF5IHRtcCBoYXMgYXQgbGVhc3QgdGhlIHNwZWNpZmllZAorICAgICAqIG51bWJlciBvZiBlbGVtZW50cywgaW5jcmVhc2luZyBpdHMgc2l6ZSBpZiBuZWNlc3NhcnkuICBUaGUgc2l6ZQorICAgICAqIGluY3JlYXNlcyBleHBvbmVudGlhbGx5IHRvIGVuc3VyZSBhbW9ydGl6ZWQgbGluZWFyIHRpbWUgY29tcGxleGl0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtaW5DYXBhY2l0eSB0aGUgbWluaW11bSByZXF1aXJlZCBjYXBhY2l0eSBvZiB0aGUgdG1wIGFycmF5CisgICAgICogQHJldHVybiB0bXAsIHdoZXRoZXIgb3Igbm90IGl0IGdyZXcKKyAgICAgKi8KKyAgICBwcml2YXRlIE9iamVjdFtdICBlbnN1cmVDYXBhY2l0eShpbnQgbWluQ2FwYWNpdHkpIHsKKyAgICAgICAgaWYgKHRtcC5sZW5ndGggPCBtaW5DYXBhY2l0eSkgeworICAgICAgICAgICAgLy8gQ29tcHV0ZSBzbWFsbGVzdCBwb3dlciBvZiAyID4gbWluQ2FwYWNpdHkKKyAgICAgICAgICAgIGludCBuZXdTaXplID0gbWluQ2FwYWNpdHk7CisgICAgICAgICAgICBuZXdTaXplIHw9IG5ld1NpemUgPj4gMTsKKyAgICAgICAgICAgIG5ld1NpemUgfD0gbmV3U2l6ZSA+PiAyOworICAgICAgICAgICAgbmV3U2l6ZSB8PSBuZXdTaXplID4+IDQ7CisgICAgICAgICAgICBuZXdTaXplIHw9IG5ld1NpemUgPj4gODsKKyAgICAgICAgICAgIG5ld1NpemUgfD0gbmV3U2l6ZSA+PiAxNjsKKyAgICAgICAgICAgIG5ld1NpemUrKzsKKworICAgICAgICAgICAgaWYgKG5ld1NpemUgPCAwKSAvLyBOb3QgYmxvb2R5IGxpa2VseSEKKyAgICAgICAgICAgICAgICBuZXdTaXplID0gbWluQ2FwYWNpdHk7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgbmV3U2l6ZSA9IE1hdGgubWluKG5ld1NpemUsIGEubGVuZ3RoID4+PiAxKTsKKworICAgICAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bmNoZWNrZWQiLCAiVW5uZWNlc3NhcnlMb2NhbFZhcmlhYmxlIn0pCisgICAgICAgICAgICBPYmplY3RbXSBuZXdBcnJheSA9IG5ldyBPYmplY3RbbmV3U2l6ZV07CisgICAgICAgICAgICB0bXAgPSBuZXdBcnJheTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdG1wOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvQ29tcGFyYXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9Db21wYXJhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDc1ODJkNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvQ29tcGFyYXRvci5qYXZhCkBAIC0wLDAgKzEsNzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisvKioKKyAqIEEge0Bjb2RlIENvbXBhcmF0b3J9IGlzIHVzZWQgdG8gY29tcGFyZSB0d28gb2JqZWN0cyB0byBkZXRlcm1pbmUgdGhlaXIgb3JkZXJpbmcgd2l0aAorICogcmVzcGVjdCB0byBlYWNoIG90aGVyLiBPbiBhIGdpdmVuIHtAY29kZSBDb2xsZWN0aW9ufSwgYSB7QGNvZGUgQ29tcGFyYXRvcn0gY2FuIGJlIHVzZWQgdG8KKyAqIG9idGFpbiBhIHNvcnRlZCB7QGNvZGUgQ29sbGVjdGlvbn0gd2hpY2ggaXMgPGk+dG90YWxseSBvcmRlcmVkPC9pPi4gRm9yIGEge0Bjb2RlIENvbXBhcmF0b3J9CisgKiB0byBiZSA8aT5jb25zaXN0ZW50IHdpdGggZXF1YWxzPC9pPiwgaXRzIHtjb2RlICNjb21wYXJlKE9iamVjdCwgT2JqZWN0KX0KKyAqIG1ldGhvZCBoYXMgdG8gcmV0dXJuIHplcm8gZm9yIGVhY2ggcGFpciBvZiBlbGVtZW50cyAoYSxiKSB3aGVyZSBhLmVxdWFscyhiKQorICogaG9sZHMgdHJ1ZS4gSXQgaXMgcmVjb21tZW5kZWQgdGhhdCBhIHtAY29kZSBDb21wYXJhdG9yfSBpbXBsZW1lbnRzCisgKiB7QGxpbmsgamF2YS5pby5TZXJpYWxpemFibGV9LgorICoKKyAqIEBzaW5jZSAxLjIKKyAqLworcHVibGljIGludGVyZmFjZSBDb21wYXJhdG9yPFQ+IHsKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgdHdvIHNwZWNpZmllZCBvYmplY3RzIHRvIGRldGVybWluZSB0aGVpciByZWxhdGl2ZSBvcmRlcmluZy4gVGhlIG9yZGVyaW5nCisgICAgICogaW1wbGllZCBieSB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoaXMgbWV0aG9kIGZvciBhbGwgcG9zc2libGUgcGFpcnMgb2YKKyAgICAgKiB7QGNvZGUgKGxocywgcmhzKX0gc2hvdWxkIGZvcm0gYW4gPGk+ZXF1aXZhbGVuY2UgcmVsYXRpb248L2k+LgorICAgICAqIFRoaXMgbWVhbnMgdGhhdAorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+e0Bjb2RlIGNvbXBhcmUoYSxhKX0gcmV0dXJucyB6ZXJvIGZvciBhbGwge0Bjb2RlIGF9PC9saT4KKyAgICAgKiA8bGk+dGhlIHNpZ24gb2Yge0Bjb2RlIGNvbXBhcmUoYSxiKX0gbXVzdCBiZSB0aGUgb3Bwb3NpdGUgb2YgdGhlIHNpZ24gb2Yge0Bjb2RlCisgICAgICogY29tcGFyZShiLGEpfSBmb3IgYWxsIHBhaXJzIG9mIChhLGIpPC9saT4KKyAgICAgKiA8bGk+RnJvbSB7QGNvZGUgY29tcGFyZShhLGIpID4gMH0gYW5kIHtAY29kZSBjb21wYXJlKGIsYykgPiAwfSBpdCBtdXN0CisgICAgICogZm9sbG93IHtAY29kZSBjb21wYXJlKGEsYykgPiAwfSBmb3IgYWxsIHBvc3NpYmxlIGNvbWJpbmF0aW9ucyBvZiB7QGNvZGUKKyAgICAgKiAoYSxiLGMpfTwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsaHMKKyAgICAgKiAgICAgICAgICAgIGFuIHtAY29kZSBPYmplY3R9LgorICAgICAqIEBwYXJhbSByaHMKKyAgICAgKiAgICAgICAgICAgIGEgc2Vjb25kIHtAY29kZSBPYmplY3R9IHRvIGNvbXBhcmUgd2l0aCB7QGNvZGUgbGhzfS4KKyAgICAgKiBAcmV0dXJuIGFuIGludGVnZXIgPCAwIGlmIHtAY29kZSBsaHN9IGlzIGxlc3MgdGhhbiB7QGNvZGUgcmhzfSwgMCBpZiB0aGV5IGFyZQorICAgICAqICAgICAgICAgZXF1YWwsIGFuZCA+IDAgaWYge0Bjb2RlIGxoc30gaXMgZ3JlYXRlciB0aGFuIHtAY29kZSByaHN9LgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgb2JqZWN0cyBhcmUgbm90IG9mIHRoZSBjb3JyZWN0IHR5cGUuCisgICAgICovCisgICAgcHVibGljIGludCBjb21wYXJlKFQgbGhzLCBUIHJocyk7CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIHtAY29kZSBDb21wYXJhdG9yfSB3aXRoIHRoZSBzcGVjaWZpZWQge0Bjb2RlIE9iamVjdH0gYW5kIGluZGljYXRlcyB3aGV0aGVyIHRoZXkKKyAgICAgKiBhcmUgZXF1YWwuIEluIG9yZGVyIHRvIGJlIGVxdWFsLCB7QGNvZGUgb2JqZWN0fSBtdXN0IHJlcHJlc2VudCB0aGUgc2FtZSBvYmplY3QKKyAgICAgKiBhcyB0aGlzIGluc3RhbmNlIHVzaW5nIGEgY2xhc3Mtc3BlY2lmaWMgY29tcGFyaXNvbi4KKyAgICAgKiA8cD4KKyAgICAgKiBBIHtAY29kZSBDb21wYXJhdG9yfSBuZXZlciBuZWVkcyB0byBvdmVycmlkZSB0aGlzIG1ldGhvZCwgYnV0IG1heSBjaG9vc2Ugc28gZm9yCisgICAgICogcGVyZm9ybWFuY2UgcmVhc29ucy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT2JqZWN0fSB0byBjb21wYXJlIHdpdGggdGhpcyBjb21wYXJhdG9yLgorICAgICAqIEByZXR1cm4gYm9vbGVhbiB7QGNvZGUgdHJ1ZX0gaWYgc3BlY2lmaWVkIHtAY29kZSBPYmplY3R9IGlzIHRoZSBzYW1lIGFzIHRoaXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBPYmplY3R9LCBhbmQge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNlZSBPYmplY3QjaGFzaENvZGUKKyAgICAgKiBAc2VlIE9iamVjdCNlcXVhbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0NvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVlNTEyNmEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0NvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDY4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworLyoqCisgKiBBbiB7QGNvZGUgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0gaXMgdGhyb3duIHdoZW4gYSBDb2xsZWN0aW9uIGlzCisgKiBtb2RpZmllZCBhbmQgYW4gZXhpc3RpbmcgaXRlcmF0b3Igb24gdGhlIENvbGxlY3Rpb24gaXMgdXNlZCB0byBtb2RpZnkgdGhlCisgKiBDb2xsZWN0aW9uIGFzIHdlbGwuCisgKgorICogQHNlZSBqYXZhLmxhbmcuUnVudGltZUV4Y2VwdGlvbgorICovCitwdWJsaWMgY2xhc3MgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTM2NjY3NTEwMDg5NjU5NTM2MDNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudAorICAgICAqIHN0YWNrIHRyYWNlIGZpbGxlZCBpbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbigpIHsKKyAgICAgICAgLyplbXB0eSovCisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudAorICAgICAqIHN0YWNrIHRyYWNlIGFuZCBtZXNzYWdlIGZpbGxlZCBpbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9ufSB3aXRoIHRoZSBnaXZlbiBkZXRhaWwKKyAgICAgKiBtZXNzYWdlIGFuZCBjYXVzZS4KKyAgICAgKiBAc2luY2UgMS43CisgICAgICogQGhpZGUgMS43CisgICAgICovCisgICAgcHVibGljIENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0gd2l0aCB0aGUgZ2l2ZW4gY2F1c2UuCisgICAgICogQHNpbmNlIDEuNworICAgICAqIEBoaWRlIDEuNworICAgICAqLworICAgIHB1YmxpYyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9DdXJyZW5jeS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9DdXJyZW5jeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNiODBlOTkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0N1cnJlbmN5LmphdmEKQEAgLTAsMCArMSwxOTQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgbGliY29yZS5pY3UuSUNVOworaW1wb3J0IGxpYmNvcmUuaWN1LkxvY2FsZURhdGE7CisKKy8qKgorICogQSBjdXJyZW5jeSBjb3JyZXNwb25kaW5nIHRvIGFuIDxhIGhyZWY9Imh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPXzQyMTciPklTTyA0MjE3PC9hPgorICogY3VycmVuY3kgY29kZSBzdWNoIGFzICJFVVIiIG9yICJVU0QiLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQ3VycmVuY3kgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xNTgzMDg0NjQzNTY5MDY3MjFMOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSGFzaE1hcDxTdHJpbmcsIEN1cnJlbmN5PiBjb2Rlc1RvQ3VycmVuY2llcyA9IG5ldyBIYXNoTWFwPFN0cmluZywgQ3VycmVuY3k+KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSGFzaE1hcDxMb2NhbGUsIEN1cnJlbmN5PiBsb2NhbGVzVG9DdXJyZW5jaWVzID0gbmV3IEhhc2hNYXA8TG9jYWxlLCBDdXJyZW5jeT4oKTsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGN1cnJlbmN5Q29kZTsKKworICAgIHByaXZhdGUgQ3VycmVuY3koU3RyaW5nIGN1cnJlbmN5Q29kZSkgeworICAgICAgICB0aGlzLmN1cnJlbmN5Q29kZSA9IGN1cnJlbmN5Q29kZTsKKyAgICAgICAgU3RyaW5nIHN5bWJvbCA9IElDVS5nZXRDdXJyZW5jeVN5bWJvbChMb2NhbGUuVVMudG9TdHJpbmcoKSwgY3VycmVuY3lDb2RlKTsKKyAgICAgICAgaWYgKHN5bWJvbCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbnN1cHBvcnRlZCBJU08gNDIxNyBjdXJyZW5jeSBjb2RlOiAiICsKKyAgICAgICAgICAgICAgICAgICAgY3VycmVuY3lDb2RlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBDdXJyZW5jeX0gaW5zdGFuY2UgZm9yIHRoZSBnaXZlbiBJU08gNDIxNyBjdXJyZW5jeSBjb2RlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGN1cnJlbmN5IGNvZGUgaXMgbm90IGEgc3VwcG9ydGVkIElTTyA0MjE3IGN1cnJlbmN5IGNvZGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDdXJyZW5jeSBnZXRJbnN0YW5jZShTdHJpbmcgY3VycmVuY3lDb2RlKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoY29kZXNUb0N1cnJlbmNpZXMpIHsKKyAgICAgICAgICAgIEN1cnJlbmN5IGN1cnJlbmN5ID0gY29kZXNUb0N1cnJlbmNpZXMuZ2V0KGN1cnJlbmN5Q29kZSk7CisgICAgICAgICAgICBpZiAoY3VycmVuY3kgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGN1cnJlbmN5ID0gbmV3IEN1cnJlbmN5KGN1cnJlbmN5Q29kZSk7CisgICAgICAgICAgICAgICAgY29kZXNUb0N1cnJlbmNpZXMucHV0KGN1cnJlbmN5Q29kZSwgY3VycmVuY3kpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGN1cnJlbmN5OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIEN1cnJlbmN5fSBpbnN0YW5jZSBmb3IgdGhpcyB7QGNvZGUgTG9jYWxlfSdzIGNvdW50cnkuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbG9jYWxlJ3MgY291bnRyeSBpcyBub3QgYSBzdXBwb3J0ZWQgSVNPIDMxNjYgY291bnRyeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEN1cnJlbmN5IGdldEluc3RhbmNlKExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NhbGVzVG9DdXJyZW5jaWVzKSB7CisgICAgICAgICAgICBDdXJyZW5jeSBjdXJyZW5jeSA9IGxvY2FsZXNUb0N1cnJlbmNpZXMuZ2V0KGxvY2FsZSk7CisgICAgICAgICAgICBpZiAoY3VycmVuY3kgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW5jeTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN0cmluZyBjb3VudHJ5ID0gbG9jYWxlLmdldENvdW50cnkoKTsKKyAgICAgICAgICAgIFN0cmluZyB2YXJpYW50ID0gbG9jYWxlLmdldFZhcmlhbnQoKTsKKyAgICAgICAgICAgIGlmICghdmFyaWFudC5pc0VtcHR5KCkgJiYgKHZhcmlhbnQuZXF1YWxzKCJFVVJPIikgfHwgdmFyaWFudC5lcXVhbHMoIkhLIikgfHwKKyAgICAgICAgICAgICAgICAgICAgdmFyaWFudC5lcXVhbHMoIlBSRUVVUk8iKSkpIHsKKyAgICAgICAgICAgICAgICBjb3VudHJ5ID0gY291bnRyeSArICJfIiArIHZhcmlhbnQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFN0cmluZyBjdXJyZW5jeUNvZGUgPSBJQ1UuZ2V0Q3VycmVuY3lDb2RlKGNvdW50cnkpOworICAgICAgICAgICAgaWYgKGN1cnJlbmN5Q29kZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVW5zdXBwb3J0ZWQgSVNPIDMxNjYgY291bnRyeTogIiArIGxvY2FsZSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbmN5Q29kZS5lcXVhbHMoIk5vbmUiKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQ3VycmVuY3kgcmVzdWx0ID0gZ2V0SW5zdGFuY2UoY3VycmVuY3lDb2RlKTsKKyAgICAgICAgICAgIGxvY2FsZXNUb0N1cnJlbmNpZXMucHV0KGxvY2FsZSwgcmVzdWx0KTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc2V0IG9mIGFsbCBrbm93biBjdXJyZW5jaWVzLgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNldDxDdXJyZW5jeT4gZ2V0QXZhaWxhYmxlQ3VycmVuY2llcygpIHsKKyAgICAgICAgU2V0PEN1cnJlbmN5PiByZXN1bHQgPSBuZXcgTGlua2VkSGFzaFNldDxDdXJyZW5jeT4oKTsKKyAgICAgICAgU3RyaW5nW10gY3VycmVuY3lDb2RlcyA9IElDVS5nZXRBdmFpbGFibGVDdXJyZW5jeUNvZGVzKCk7CisgICAgICAgIGZvciAoU3RyaW5nIGN1cnJlbmN5Q29kZSA6IGN1cnJlbmN5Q29kZXMpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hZGQoQ3VycmVuY3kuZ2V0SW5zdGFuY2UoY3VycmVuY3lDb2RlKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgY3VycmVuY3kncyBJU08gNDIxNyBjdXJyZW5jeSBjb2RlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q3VycmVuY3lDb2RlKCkgeworICAgICAgICByZXR1cm4gY3VycmVuY3lDb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8ge0Bjb2RlIGdldERpc3BsYXlOYW1lKExvY2FsZS5nZXREZWZhdWx0KCkpfS4KKyAgICAgKiBTZWUgIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuCisgICAgICogQHNpbmNlIDEuNworICAgICAqIEBoaWRlIDEuNworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGlzcGxheU5hbWUoKSB7CisgICAgICAgIHJldHVybiBnZXREaXNwbGF5TmFtZShMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbGl6ZWQgbmFtZSBvZiB0aGlzIGN1cnJlbmN5IGluIHRoZSBnaXZlbiB7QGNvZGUgbG9jYWxlfS4KKyAgICAgKiBSZXR1cm5zIHRoZSBJU08gNDIxNyBjdXJyZW5jeSBjb2RlIGlmIG5vIGxvY2FsaXplZCBuYW1lIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBAc2luY2UgMS43CisgICAgICogQGhpZGUgMS43CisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXREaXNwbGF5TmFtZShMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIHJldHVybiBJQ1UuZ2V0Q3VycmVuY3lEaXNwbGF5TmFtZShsb2NhbGUudG9TdHJpbmcoKSwgY3VycmVuY3lDb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVpdmFsZW50IHRvIHtAY29kZSBnZXRTeW1ib2woTG9jYWxlLmdldERlZmF1bHQoKSl9LgorICAgICAqIFNlZSAiPGEgaHJlZj0iLi4vdXRpbC9Mb2NhbGUuaHRtbCNkZWZhdWx0X2xvY2FsZSI+QmUgd2FyeSBvZiB0aGUgZGVmYXVsdCBsb2NhbGU8L2E+Ii4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFN5bWJvbCgpIHsKKyAgICAgICAgcmV0dXJuIGdldFN5bWJvbChMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbGl6ZWQgY3VycmVuY3kgc3ltYm9sIGZvciB0aGlzIGN1cnJlbmN5IGluIHtAY29kZSBsb2NhbGV9LgorICAgICAqIFRoYXQgaXMsIGdpdmVuICJVU0QiIGFuZCBMb2NhbGUuVVMsIHlvdSdkIGdldCAiJCIsIGJ1dCBnaXZlbiAiVVNEIiBhbmQgYSBub24tVVMgbG9jYWxlLAorICAgICAqIHlvdSdkIGdldCAiVVMkIi4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBsb2NhbGUgb25seSBzcGVjaWZpZXMgYSBsYW5ndWFnZSByYXRoZXIgdGhhbiBhIGxhbmd1YWdlIGFuZCBhIGNvdW50cnkgKHN1Y2ggYXMKKyAgICAgKiB7QGNvZGUgTG9jYWxlLkpBUEFORVNFfSBvciB7bmV3IExvY2FsZSgiZW4iLCAiIil9IHJhdGhlciB0aGFuIHtAY29kZSBMb2NhbGUuSkFQQU59IG9yCisgICAgICoge25ldyBMb2NhbGUoImVuIiwgIlVTIil9KSwgdGhlIElTTyA0MjE3IGN1cnJlbmN5IGNvZGUgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGVyZSBpcyBubyBsb2NhbGUtc3BlY2lmaWMgY3VycmVuY3kgc3ltYm9sLCB0aGUgSVNPIDQyMTcgY3VycmVuY3kgY29kZSBpcyByZXR1cm5lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFN5bWJvbChMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIGlmIChsb2NhbGUuZ2V0Q291bnRyeSgpLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBjdXJyZW5jeUNvZGU7CisgICAgICAgIH0KKworICAgICAgICAvLyBDaGVjayB0aGUgbG9jYWxlIGZpcnN0LCBpbiBjYXNlIHRoZSBsb2NhbGUgaGFzIHRoZSBzYW1lIGN1cnJlbmN5LgorICAgICAgICBMb2NhbGVEYXRhIGxvY2FsZURhdGEgPSBMb2NhbGVEYXRhLmdldChsb2NhbGUpOworICAgICAgICBpZiAobG9jYWxlRGF0YS5pbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2wuZXF1YWxzKGN1cnJlbmN5Q29kZSkpIHsKKyAgICAgICAgICAgIHJldHVybiBsb2NhbGVEYXRhLmN1cnJlbmN5U3ltYm9sOworICAgICAgICB9CisKKyAgICAgICAgLy8gVHJ5IElDVSwgYW5kIGZhbGwgYmFjayB0byB0aGUgY3VycmVuY3kgY29kZSBpZiBJQ1UgaGFzIG5vdGhpbmcuCisgICAgICAgIFN0cmluZyBzeW1ib2wgPSBJQ1UuZ2V0Q3VycmVuY3lTeW1ib2wobG9jYWxlLnRvU3RyaW5nKCksIGN1cnJlbmN5Q29kZSk7CisgICAgICAgIHJldHVybiBzeW1ib2wgIT0gbnVsbCA/IHN5bWJvbCA6IGN1cnJlbmN5Q29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IG51bWJlciBvZiBmcmFjdGlvbiBkaWdpdHMgZm9yIHRoaXMgY3VycmVuY3kuCisgICAgICogRm9yIGluc3RhbmNlLCB0aGUgZGVmYXVsdCBudW1iZXIgb2YgZnJhY3Rpb24gZGlnaXRzIGZvciB0aGUgVVMgZG9sbGFyIGlzIDIgYmVjYXVzZSB0aGVyZSBhcmUKKyAgICAgKiAxMDAgVVMgY2VudHMgaW4gYSBVUyBkb2xsYXIuIEZvciB0aGUgSmFwYW5lc2UgWWVuLCB0aGUgbnVtYmVyIGlzIDAgYmVjYXVzZSBjb2lucyBzbWFsbGVyCisgICAgICogdGhhbiAxIFllbiBiZWNhbWUgaW52YWxpZCBpbiAxOTUzLiBJbiB0aGUgY2FzZSBvZiBwc2V1ZG8tY3VycmVuY2llcywgc3VjaCBhcworICAgICAqIElNRiBTcGVjaWFsIERyYXdpbmcgUmlnaHRzLCAtMSBpcyByZXR1cm5lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldERlZmF1bHRGcmFjdGlvbkRpZ2l0cygpIHsKKyAgICAgICAgLy8gSW4gc29tZSBwbGFjZXMgdGhlIGNvZGUgWFhYIGlzIHVzZWQgYXMgdGhlIGZhbGwgYmFjayBjdXJyZW5jeS4KKyAgICAgICAgLy8gVGhlIFJJIHJldHVybnMgLTEsIGJ1dCBJQ1UgZGVmYXVsdHMgdG8gMiBmb3IgdW5rbm93biBjdXJyZW5jaWVzLgorICAgICAgICBpZiAoY3VycmVuY3lDb2RlLmVxdWFscygiWFhYIikpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gSUNVLmdldEN1cnJlbmN5RnJhY3Rpb25EaWdpdHMoY3VycmVuY3lDb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgY3VycmVuY3kncyBJU08gNDIxNyBjdXJyZW5jeSBjb2RlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBjdXJyZW5jeUNvZGU7CisgICAgfQorCisgICAgcHJpdmF0ZSBPYmplY3QgcmVhZFJlc29sdmUoKSB7CisgICAgICAgIHJldHVybiBnZXRJbnN0YW5jZShjdXJyZW5jeUNvZGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRGF0ZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9EYXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGVhYjhkYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRGF0ZS5qYXZhCkBAIC0wLDAgKzEsNzkzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnRleHQuRGF0ZUZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuRGF0ZUZvcm1hdFN5bWJvbHM7CitpbXBvcnQgamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQ7CitpbXBvcnQgbGliY29yZS5pY3UuTG9jYWxlRGF0YTsKKworLyoqCisgKiB7QGNvZGUgRGF0ZX0gcmVwcmVzZW50cyBhIHNwZWNpZmljIG1vbWVudCBpbiB0aW1lLCB0byB0aGUgbWlsbGlzZWNvbmQuCisgKgorICogQHNlZSBTeXN0ZW0jY3VycmVudFRpbWVNaWxsaXMKKyAqIEBzZWUgQ2FsZW5kYXIKKyAqIEBzZWUgR3JlZ29yaWFuQ2FsZW5kYXIKKyAqIEBzZWUgU2ltcGxlVGltZVpvbmUKKyAqIEBzZWUgVGltZVpvbmUKKyAqLworcHVibGljIGNsYXNzIERhdGUgaW1wbGVtZW50cyBTZXJpYWxpemFibGUsIENsb25lYWJsZSwgQ29tcGFyYWJsZTxEYXRlPiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3NTIzOTY3OTcwMDM0OTM4OTA1TDsKKworICAgIC8vIFVzZWQgYnkgcGFyc2UoKQorICAgIHByaXZhdGUgc3RhdGljIGludCBjcmVhdGlvblllYXIgPSBuZXcgRGF0ZSgpLmdldFllYXIoKTsKKworICAgIHByaXZhdGUgdHJhbnNpZW50IGxvbmcgbWlsbGlzZWNvbmRzOworCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyB7QGNvZGUgRGF0ZX0gaW5zdGFuY2UgdG8gdGhlIGN1cnJlbnQgdGltZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0ZSgpIHsKKyAgICAgICAgdGhpcyhTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRGF0ZX0gaW5pdGlhbGl6ZWQgdG8gbWlkbmlnaHQgaW4gdGhlIGRlZmF1bHQge0Bjb2RlIFRpbWVab25lfSBvbgorICAgICAqIHRoZSBzcGVjaWZpZWQgZGF0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB5ZWFyCisgICAgICogICAgICAgICAgICB0aGUgeWVhciwgMCBpcyAxOTAwLgorICAgICAqIEBwYXJhbSBtb250aAorICAgICAqICAgICAgICAgICAgdGhlIG1vbnRoLCAwIC0gMTEuCisgICAgICogQHBhcmFtIGRheQorICAgICAqICAgICAgICAgICAgdGhlIGRheSBvZiB0aGUgbW9udGgsIDEgLSAzMS4KKyAgICAgKgorICAgICAqIEBkZXByZWNhdGVkIHVzZQorICAgICAqICAgICAgICAgICAgIHtAbGluayBHcmVnb3JpYW5DYWxlbmRhciNHcmVnb3JpYW5DYWxlbmRhcihpbnQsIGludCwgaW50KX0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBEYXRlKGludCB5ZWFyLCBpbnQgbW9udGgsIGludCBkYXkpIHsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKGZhbHNlKTsKKyAgICAgICAgY2FsLnNldCgxOTAwICsgeWVhciwgbW9udGgsIGRheSk7CisgICAgICAgIG1pbGxpc2Vjb25kcyA9IGNhbC5nZXRUaW1lSW5NaWxsaXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBEYXRlfSBpbml0aWFsaXplZCB0byB0aGUgc3BlY2lmaWVkIGRhdGUgYW5kIHRpbWUgaW4gdGhlCisgICAgICogZGVmYXVsdCB7QGNvZGUgVGltZVpvbmV9LgorICAgICAqCisgICAgICogQHBhcmFtIHllYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB5ZWFyLCAwIGlzIDE5MDAuCisgICAgICogQHBhcmFtIG1vbnRoCisgICAgICogICAgICAgICAgICB0aGUgbW9udGgsIDAgLSAxMS4KKyAgICAgKiBAcGFyYW0gZGF5CisgICAgICogICAgICAgICAgICB0aGUgZGF5IG9mIHRoZSBtb250aCwgMSAtIDMxLgorICAgICAqIEBwYXJhbSBob3VyCisgICAgICogICAgICAgICAgICB0aGUgaG91ciBvZiBkYXksIDAgLSAyMy4KKyAgICAgKiBAcGFyYW0gbWludXRlCisgICAgICogICAgICAgICAgICB0aGUgbWludXRlIG9mIHRoZSBob3VyLCAwIC0gNTkuCisgICAgICoKKyAgICAgKiBAZGVwcmVjYXRlZCB1c2UKKyAgICAgKiAgICAgICAgICAgICB7QGxpbmsgR3JlZ29yaWFuQ2FsZW5kYXIjR3JlZ29yaWFuQ2FsZW5kYXIoaW50LCBpbnQsIGludCwgaW50LCBpbnQpfQorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIERhdGUoaW50IHllYXIsIGludCBtb250aCwgaW50IGRheSwgaW50IGhvdXIsIGludCBtaW51dGUpIHsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKGZhbHNlKTsKKyAgICAgICAgY2FsLnNldCgxOTAwICsgeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlKTsKKyAgICAgICAgbWlsbGlzZWNvbmRzID0gY2FsLmdldFRpbWVJbk1pbGxpcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIERhdGV9IGluaXRpYWxpemVkIHRvIHRoZSBzcGVjaWZpZWQgZGF0ZSBhbmQgdGltZSBpbiB0aGUKKyAgICAgKiBkZWZhdWx0IHtAY29kZSBUaW1lWm9uZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0geWVhcgorICAgICAqICAgICAgICAgICAgdGhlIHllYXIsIDAgaXMgMTkwMC4KKyAgICAgKiBAcGFyYW0gbW9udGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtb250aCwgMCAtIDExLgorICAgICAqIEBwYXJhbSBkYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXkgb2YgdGhlIG1vbnRoLCAxIC0gMzEuCisgICAgICogQHBhcmFtIGhvdXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBob3VyIG9mIGRheSwgMCAtIDIzLgorICAgICAqIEBwYXJhbSBtaW51dGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBtaW51dGUgb2YgdGhlIGhvdXIsIDAgLSA1OS4KKyAgICAgKiBAcGFyYW0gc2Vjb25kCisgICAgICogICAgICAgICAgICB0aGUgc2Vjb25kIG9mIHRoZSBtaW51dGUsIDAgLSA1OS4KKyAgICAgKgorICAgICAqIEBkZXByZWNhdGVkIHVzZQorICAgICAqICAgICAgICAgICAgIHtAbGluayBHcmVnb3JpYW5DYWxlbmRhciNHcmVnb3JpYW5DYWxlbmRhcihpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50KX0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBEYXRlKGludCB5ZWFyLCBpbnQgbW9udGgsIGludCBkYXksIGludCBob3VyLCBpbnQgbWludXRlLCBpbnQgc2Vjb25kKSB7CisgICAgICAgIEdyZWdvcmlhbkNhbGVuZGFyIGNhbCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcihmYWxzZSk7CisgICAgICAgIGNhbC5zZXQoMTkwMCArIHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgc2Vjb25kKTsKKyAgICAgICAgbWlsbGlzZWNvbmRzID0gY2FsLmdldFRpbWVJbk1pbGxpcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIERhdGV9IGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgbWlsbGlzZWNvbmQgdmFsdWUuIFRoZQorICAgICAqIHZhbHVlIGlzIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHNpbmNlIEphbi4gMSwgMTk3MCBHTVQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWlsbGlzZWNvbmRzCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBzaW5jZSBKYW4uIDEsIDE5NzAgR01ULgorICAgICAqLworICAgIHB1YmxpYyBEYXRlKGxvbmcgbWlsbGlzZWNvbmRzKSB7CisgICAgICAgIHRoaXMubWlsbGlzZWNvbmRzID0gbWlsbGlzZWNvbmRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIERhdGV9IGluaXRpYWxpemVkIHRvIHRoZSBkYXRlIGFuZCB0aW1lIHBhcnNlZCBmcm9tIHRoZQorICAgICAqIHNwZWNpZmllZCBTdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgU3RyaW5nIHRvIHBhcnNlLgorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIHtAbGluayBEYXRlRm9ybWF0fQorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIERhdGUoU3RyaW5nIHN0cmluZykgeworICAgICAgICBtaWxsaXNlY29uZHMgPSBwYXJzZShzdHJpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgaWYgdGhpcyB7QGNvZGUgRGF0ZX0gaXMgYWZ0ZXIgdGhlIHNwZWNpZmllZCBEYXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGUKKyAgICAgKiAgICAgICAgICAgIGEgRGF0ZSBpbnN0YW5jZSB0byBjb21wYXJlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMge0Bjb2RlIERhdGV9IGlzIGFmdGVyIHRoZSBzcGVjaWZpZWQge0Bjb2RlIERhdGV9LAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYWZ0ZXIoRGF0ZSBkYXRlKSB7CisgICAgICAgIHJldHVybiBtaWxsaXNlY29uZHMgPiBkYXRlLm1pbGxpc2Vjb25kczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGlmIHRoaXMge0Bjb2RlIERhdGV9IGlzIGJlZm9yZSB0aGUgc3BlY2lmaWVkIERhdGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0ZQorICAgICAqICAgICAgICAgICAgYSB7QGNvZGUgRGF0ZX0gaW5zdGFuY2UgdG8gY29tcGFyZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBEYXRlfSBpcyBiZWZvcmUgdGhlIHNwZWNpZmllZCB7QGNvZGUgRGF0ZX0sCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBiZWZvcmUoRGF0ZSBkYXRlKSB7CisgICAgICAgIHJldHVybiBtaWxsaXNlY29uZHMgPCBkYXRlLm1pbGxpc2Vjb25kczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBEYXRlfSB3aXRoIHRoZSBzYW1lIG1pbGxpc2Vjb25kIHZhbHVlIGFzIHRoaXMge0Bjb2RlIERhdGV9LgorICAgICAqCisgICAgICogQHJldHVybiBhIHNoYWxsb3cgY29weSBvZiB0aGlzIHtAY29kZSBEYXRlfS4KKyAgICAgKgorICAgICAqIEBzZWUgamF2YS5sYW5nLkNsb25lYWJsZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZSB0aGUgcmVjZWl2ZXIgdG8gdGhlIHNwZWNpZmllZCB7QGNvZGUgRGF0ZX0gdG8gZGV0ZXJtaW5lIHRoZSByZWxhdGl2ZQorICAgICAqIG9yZGVyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGUKKyAgICAgKiAgICAgICAgICAgIGEge0Bjb2RlIERhdGV9IHRvIGNvbXBhcmUgYWdhaW5zdC4KKyAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBpbnQgPCAwfSBpZiB0aGlzIHtAY29kZSBEYXRlfSBpcyBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCB7QGNvZGUgRGF0ZX0sIHtAY29kZSAwfSBpZgorICAgICAqICAgICAgICAgdGhleSBhcmUgZXF1YWwsIGFuZCBhbiB7QGNvZGUgaW50ID4gMH0gaWYgdGhpcyB7QGNvZGUgRGF0ZX0gaXMgZ3JlYXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhEYXRlIGRhdGUpIHsKKyAgICAgICAgaWYgKG1pbGxpc2Vjb25kcyA8IGRhdGUubWlsbGlzZWNvbmRzKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG1pbGxpc2Vjb25kcyA9PSBkYXRlLm1pbGxpc2Vjb25kcykgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBvYmplY3QgdG8gdGhpcyB7QGNvZGUgRGF0ZX0gYW5kIHJldHVybnMgaWYgdGhleSBhcmUgZXF1YWwuCisgICAgICogVG8gYmUgZXF1YWwsIHRoZSBvYmplY3QgbXVzdCBiZSBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgRGF0ZX0gYW5kIGhhdmUgdGhlIHNhbWUgbWlsbGlzZWNvbmQKKyAgICAgKiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB3aXRoIHRoaXMgb2JqZWN0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMge0Bjb2RlIERhdGV9LCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICoKKyAgICAgKiBAc2VlICNoYXNoQ29kZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIHJldHVybiAob2JqZWN0ID09IHRoaXMpIHx8IChvYmplY3QgaW5zdGFuY2VvZiBEYXRlKQorICAgICAgICAgICAgICAgICYmIChtaWxsaXNlY29uZHMgPT0gKChEYXRlKSBvYmplY3QpLm1pbGxpc2Vjb25kcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZ3JlZ29yaWFuIGNhbGVuZGFyIGRheSBvZiB0aGUgbW9udGggZm9yIHRoaXMge0Bjb2RlIERhdGV9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGRheSBvZiB0aGUgbW9udGguCisgICAgICoKKyAgICAgKiBAZGVwcmVjYXRlZCB1c2Uge0Bjb2RlIENhbGVuZGFyLmdldChDYWxlbmRhci5EQVRFKX0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBpbnQgZ2V0RGF0ZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBHcmVnb3JpYW5DYWxlbmRhcihtaWxsaXNlY29uZHMpLmdldChDYWxlbmRhci5EQVRFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBncmVnb3JpYW4gY2FsZW5kYXIgZGF5IG9mIHRoZSB3ZWVrIGZvciB0aGlzIHtAY29kZSBEYXRlfSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkYXkgb2YgdGhlIHdlZWsuCisgICAgICoKKyAgICAgKiBAZGVwcmVjYXRlZCB1c2Uge0Bjb2RlIENhbGVuZGFyLmdldChDYWxlbmRhci5EQVlfT0ZfV0VFSyl9CisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgaW50IGdldERheSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBHcmVnb3JpYW5DYWxlbmRhcihtaWxsaXNlY29uZHMpLmdldChDYWxlbmRhci5EQVlfT0ZfV0VFSykgLSAxOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGdyZWdvcmlhbiBjYWxlbmRhciBob3VyIG9mIHRoZSBkYXkgZm9yIHRoaXMge0Bjb2RlIERhdGV9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhvdXIgb2YgdGhlIGRheS4KKyAgICAgKgorICAgICAqIEBkZXByZWNhdGVkIHVzZSB7QGNvZGUgQ2FsZW5kYXIuZ2V0KENhbGVuZGFyLkhPVVJfT0ZfREFZKX0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBpbnQgZ2V0SG91cnMoKSB7CisgICAgICAgIHJldHVybiBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIobWlsbGlzZWNvbmRzKS5nZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGdyZWdvcmlhbiBjYWxlbmRhciBtaW51dGUgb2YgdGhlIGhvdXIgZm9yIHRoaXMge0Bjb2RlIERhdGV9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1pbnV0ZXMuCisgICAgICoKKyAgICAgKiBAZGVwcmVjYXRlZCB1c2Uge0Bjb2RlIENhbGVuZGFyLmdldChDYWxlbmRhci5NSU5VVEUpfQorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGludCBnZXRNaW51dGVzKCkgeworICAgICAgICByZXR1cm4gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKG1pbGxpc2Vjb25kcykuZ2V0KENhbGVuZGFyLk1JTlVURSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZ3JlZ29yaWFuIGNhbGVuZGFyIG1vbnRoIGZvciB0aGlzIHtAY29kZSBEYXRlfSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtb250aC4KKyAgICAgKgorICAgICAqIEBkZXByZWNhdGVkIHVzZSB7QGNvZGUgQ2FsZW5kYXIuZ2V0KENhbGVuZGFyLk1PTlRIKX0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBpbnQgZ2V0TW9udGgoKSB7CisgICAgICAgIHJldHVybiBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIobWlsbGlzZWNvbmRzKS5nZXQoQ2FsZW5kYXIuTU9OVEgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGdyZWdvcmlhbiBjYWxlbmRhciBzZWNvbmQgb2YgdGhlIG1pbnV0ZSBmb3IgdGhpcyB7QGNvZGUgRGF0ZX0gb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc2Vjb25kcy4KKyAgICAgKgorICAgICAqIEBkZXByZWNhdGVkIHVzZSB7QGNvZGUgQ2FsZW5kYXIuZ2V0KENhbGVuZGFyLlNFQ09ORCl9CisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgaW50IGdldFNlY29uZHMoKSB7CisgICAgICAgIHJldHVybiBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIobWlsbGlzZWNvbmRzKS5nZXQoQ2FsZW5kYXIuU0VDT05EKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMge0Bjb2RlIERhdGV9IGFzIGEgbWlsbGlzZWNvbmQgdmFsdWUuIFRoZSB2YWx1ZSBpcyB0aGUgbnVtYmVyIG9mCisgICAgICogbWlsbGlzZWNvbmRzIHNpbmNlIEphbi4gMSwgMTk3MCwgbWlkbmlnaHQgR01ULgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBzaW5jZSBKYW4uIDEsIDE5NzAsIG1pZG5pZ2h0IEdNVC4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRUaW1lKCkgeworICAgICAgICByZXR1cm4gbWlsbGlzZWNvbmRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRpbWV6b25lIG9mZnNldCBpbiBtaW51dGVzIG9mIHRoZSBkZWZhdWx0IHtAY29kZSBUaW1lWm9uZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB0aW1lem9uZSBvZmZzZXQgaW4gbWludXRlcyBvZiB0aGUgZGVmYXVsdCB7QGNvZGUgVGltZVpvbmV9LgorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgdXNlCisgICAgICogICAgICAgICAgICAge0Bjb2RlIChDYWxlbmRhci5nZXQoQ2FsZW5kYXIuWk9ORV9PRkZTRVQpICsgQ2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRTVF9PRkZTRVQpKSAvIDYwMDAwfQorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIGludCBnZXRUaW1lem9uZU9mZnNldCgpIHsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKG1pbGxpc2Vjb25kcyk7CisgICAgICAgIHJldHVybiAtKGNhbC5nZXQoQ2FsZW5kYXIuWk9ORV9PRkZTRVQpICsgY2FsLmdldChDYWxlbmRhci5EU1RfT0ZGU0VUKSkgLyA2MDAwMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBncmVnb3JpYW4gY2FsZW5kYXIgeWVhciBzaW5jZSAxOTAwIGZvciB0aGlzIHtAY29kZSBEYXRlfSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB5ZWFyIC0gMTkwMC4KKyAgICAgKgorICAgICAqIEBkZXByZWNhdGVkIHVzZSB7QGNvZGUgQ2FsZW5kYXIuZ2V0KENhbGVuZGFyLllFQVIpIC0gMTkwMH0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBpbnQgZ2V0WWVhcigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBHcmVnb3JpYW5DYWxlbmRhcihtaWxsaXNlY29uZHMpLmdldChDYWxlbmRhci5ZRUFSKSAtIDE5MDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnRlZ2VyIGhhc2ggY29kZSBmb3IgdGhlIHJlY2VpdmVyLiBPYmplY3RzIHdoaWNoIGFyZSBlcXVhbAorICAgICAqIHJldHVybiB0aGUgc2FtZSB2YWx1ZSBmb3IgdGhpcyBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMge0Bjb2RlIERhdGV9J3MgaGFzaC4KKyAgICAgKgorICAgICAqIEBzZWUgI2VxdWFscworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiAoaW50KSAobWlsbGlzZWNvbmRzID4+PiAzMikgXiAoaW50KSBtaWxsaXNlY29uZHM7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHBhcnNlKFN0cmluZyBzdHJpbmcsIFN0cmluZ1tdIGFycmF5KSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwLCBhbGVuZ3RoID0gYXJyYXkubGVuZ3RoLCBzbGVuZ3RoID0gc3RyaW5nLmxlbmd0aCgpOyBpIDwgYWxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoc3RyaW5nLnJlZ2lvbk1hdGNoZXModHJ1ZSwgMCwgYXJyYXlbaV0sIDAsIHNsZW5ndGgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1pbGxpc2Vjb25kIHZhbHVlIG9mIHRoZSBkYXRlIGFuZCB0aW1lIHBhcnNlZCBmcm9tIHRoZQorICAgICAqIHNwZWNpZmllZCB7QGNvZGUgU3RyaW5nfS4gTWFueSBkYXRlL3RpbWUgZm9ybWF0cyBhcmUgcmVjb2duaXplZCwgaW5jbHVkaW5nIElFVEYKKyAgICAgKiBzdGFuZGFyZCBzeW50YXgsIGkuZS4gVHVlLCAyMiBKdW4gMTk5OSAxMjoxNjowMCBHTVQtMDUwMAorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIFN0cmluZyB0byBwYXJzZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBtaWxsaXNlY29uZCB2YWx1ZSBwYXJzZWQgZnJvbSB0aGUgU3RyaW5nLgorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIHtAbGluayBEYXRlRm9ybWF0fQorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHN0YXRpYyBsb25nIHBhcnNlKFN0cmluZyBzdHJpbmcpIHsKKyAgICAgICAgaWYgKHN0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJUaGUgc3RyaW5nIGFyZ3VtZW50IGlzIG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIGNoYXIgc2lnbiA9IDA7CisgICAgICAgIGludCBjb21tZW50TGV2ZWwgPSAwOworICAgICAgICBpbnQgb2Zmc2V0ID0gMCwgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aCgpLCBzdGF0ZSA9IDA7CisgICAgICAgIGludCB5ZWFyID0gLTEsIG1vbnRoID0gLTEsIGRhdGUgPSAtMTsKKyAgICAgICAgaW50IGhvdXIgPSAtMSwgbWludXRlID0gLTEsIHNlY29uZCA9IC0xLCB6b25lT2Zmc2V0ID0gMCwgbWludXRlc09mZnNldCA9IDA7CisgICAgICAgIGJvb2xlYW4gem9uZSA9IGZhbHNlOworICAgICAgICBmaW5hbCBpbnQgUEFEID0gMCwgTEVUVEVSUyA9IDEsIE5VTUJFUlMgPSAyOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisKKyAgICAgICAgd2hpbGUgKG9mZnNldCA8PSBsZW5ndGgpIHsKKyAgICAgICAgICAgIGNoYXIgbmV4dCA9IG9mZnNldCA8IGxlbmd0aCA/IHN0cmluZy5jaGFyQXQob2Zmc2V0KSA6ICdccic7CisgICAgICAgICAgICBvZmZzZXQrKzsKKworICAgICAgICAgICAgaWYgKG5leHQgPT0gJygnKSB7CisgICAgICAgICAgICAgICAgY29tbWVudExldmVsKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY29tbWVudExldmVsID4gMCkgeworICAgICAgICAgICAgICAgIGlmIChuZXh0ID09ICcpJykgeworICAgICAgICAgICAgICAgICAgICBjb21tZW50TGV2ZWwtLTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGNvbW1lbnRMZXZlbCA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIG5leHQgPSAnICc7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgbmV4dFN0YXRlID0gUEFEOworICAgICAgICAgICAgaWYgKCdhJyA8PSBuZXh0ICYmIG5leHQgPD0gJ3onIHx8ICdBJyA8PSBuZXh0ICYmIG5leHQgPD0gJ1onKSB7CisgICAgICAgICAgICAgICAgbmV4dFN0YXRlID0gTEVUVEVSUzsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoJzAnIDw9IG5leHQgJiYgbmV4dCA8PSAnOScpIHsKKyAgICAgICAgICAgICAgICBuZXh0U3RhdGUgPSBOVU1CRVJTOworICAgICAgICAgICAgfSBlbHNlIGlmICghQ2hhcmFjdGVyLmlzU3BhY2UobmV4dCkgJiYgIiwrLTovIi5pbmRleE9mKG5leHQpID09IC0xKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoc3RhdGUgPT0gTlVNQkVSUyAmJiBuZXh0U3RhdGUgIT0gTlVNQkVSUykgeworICAgICAgICAgICAgICAgIGludCBkaWdpdCA9IEludGVnZXIucGFyc2VJbnQoYnVmZmVyLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIGJ1ZmZlci5zZXRMZW5ndGgoMCk7CisgICAgICAgICAgICAgICAgaWYgKHNpZ24gPT0gJysnIHx8IHNpZ24gPT0gJy0nKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICh6b25lT2Zmc2V0ID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHpvbmUgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQgPT0gJzonKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlc09mZnNldCA9IHNpZ24gPT0gJy0nID8gLUludGVnZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wYXJzZUludChzdHJpbmcuc3Vic3RyaW5nKG9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICsgMikpIDogSW50ZWdlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnBhcnNlSW50KHN0cmluZy5zdWJzdHJpbmcob2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKyAyKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDI7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB6b25lT2Zmc2V0ID0gc2lnbiA9PSAnLScgPyAtZGlnaXQgOiBkaWdpdDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNpZ24gPSAwOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkaWdpdCA+PSA3MCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoeWVhciA9PSAtMQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIChDaGFyYWN0ZXIuaXNTcGFjZShuZXh0KSB8fCBuZXh0ID09ICcsJworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgbmV4dCA9PSAnLycgfHwgbmV4dCA9PSAnXHInKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgeWVhciA9IGRpZ2l0OworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuZXh0ID09ICc6JykgeworICAgICAgICAgICAgICAgICAgICBpZiAoaG91ciA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaG91ciA9IGRpZ2l0OworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG1pbnV0ZSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlID0gZGlnaXQ7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5leHQgPT0gJy8nKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChtb250aCA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgbW9udGggPSBkaWdpdCAtIDE7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGF0ZSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZGF0ZSA9IGRpZ2l0OworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChDaGFyYWN0ZXIuaXNTcGFjZShuZXh0KSB8fCBuZXh0ID09ICcsJworICAgICAgICAgICAgICAgICAgICAgICAgfHwgbmV4dCA9PSAnLScgfHwgbmV4dCA9PSAnXHInKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChob3VyICE9IC0xICYmIG1pbnV0ZSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlID0gZGlnaXQ7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobWludXRlICE9IC0xICYmIHNlY29uZCA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgc2Vjb25kID0gZGlnaXQ7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGF0ZSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZGF0ZSA9IGRpZ2l0OworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHllYXIgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHllYXIgPSBkaWdpdDsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoeWVhciA9PSAtMSAmJiBtb250aCAhPSAtMSAmJiBkYXRlICE9IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIHllYXIgPSBkaWdpdDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PSBMRVRURVJTICYmIG5leHRTdGF0ZSAhPSBMRVRURVJTKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBidWZmZXIudG9TdHJpbmcoKS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpOworICAgICAgICAgICAgICAgIGJ1ZmZlci5zZXRMZW5ndGgoMCk7CisgICAgICAgICAgICAgICAgaWYgKHRleHQubGVuZ3RoKCkgPT0gMSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICh0ZXh0LmVxdWFscygiQU0iKSkgeworICAgICAgICAgICAgICAgICAgICBpZiAoaG91ciA9PSAxMikgeworICAgICAgICAgICAgICAgICAgICAgICAgaG91ciA9IDA7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaG91ciA8IDEgfHwgaG91ciA+IDEyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRleHQuZXF1YWxzKCJQTSIpKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChob3VyID09IDEyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBob3VyID0gMDsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChob3VyIDwgMSB8fCBob3VyID4gMTIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBob3VyICs9IDEyOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIERhdGVGb3JtYXRTeW1ib2xzIHN5bWJvbHMgPSBuZXcgRGF0ZUZvcm1hdFN5bWJvbHMoTG9jYWxlLlVTKTsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nW10gd2Vla2RheXMgPSBzeW1ib2xzLmdldFdlZWtkYXlzKCksIG1vbnRocyA9IHN5bWJvbHMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TW9udGhzKCk7CisgICAgICAgICAgICAgICAgICAgIGludCB2YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlKHRleHQsIHdlZWtkYXlzKSAhPSAtMSkgey8qIGVtcHR5ICovCisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobW9udGggPT0gLTEgJiYgKG1vbnRoID0gcGFyc2UodGV4dCwgbW9udGhzKSkgIT0gLTEpIHsvKiBlbXB0eSAqLworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRleHQuZXF1YWxzKCJHTVQiKSB8fCB0ZXh0LmVxdWFscygiVVQiKSB8fCB0ZXh0LmVxdWFscygiVVRDIikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHpvbmUgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgem9uZU9mZnNldCA9IDA7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHZhbHVlID0gem9uZSh0ZXh0KSkgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgem9uZSA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICB6b25lT2Zmc2V0ID0gdmFsdWU7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChuZXh0ID09ICcrJyB8fCAoeWVhciAhPSAtMSAmJiBuZXh0ID09ICctJykpIHsKKyAgICAgICAgICAgICAgICBzaWduID0gbmV4dDsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIUNoYXJhY3Rlci5pc1NwYWNlKG5leHQpICYmIG5leHQgIT0gJywnCisgICAgICAgICAgICAgICAgICAgICYmIG5leHRTdGF0ZSAhPSBOVU1CRVJTKSB7CisgICAgICAgICAgICAgICAgc2lnbiA9IDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChuZXh0U3RhdGUgPT0gTEVUVEVSUyB8fCBuZXh0U3RhdGUgPT0gTlVNQkVSUykgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQobmV4dCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzdGF0ZSA9IG5leHRTdGF0ZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh5ZWFyICE9IC0xICYmIG1vbnRoICE9IC0xICYmIGRhdGUgIT0gLTEpIHsKKyAgICAgICAgICAgIGlmIChob3VyID09IC0xKSB7CisgICAgICAgICAgICAgICAgaG91ciA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobWludXRlID09IC0xKSB7CisgICAgICAgICAgICAgICAgbWludXRlID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzZWNvbmQgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICBzZWNvbmQgPSAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHllYXIgPCAoY3JlYXRpb25ZZWFyIC0gODApKSB7CisgICAgICAgICAgICAgICAgeWVhciArPSAyMDAwOworICAgICAgICAgICAgfSBlbHNlIGlmICh5ZWFyIDwgMTAwKSB7CisgICAgICAgICAgICAgICAgeWVhciArPSAxOTAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbWludXRlIC09IG1pbnV0ZXNPZmZzZXQ7CisgICAgICAgICAgICBpZiAoem9uZSkgeworICAgICAgICAgICAgICAgIGlmICh6b25lT2Zmc2V0ID49IDI0IHx8IHpvbmVPZmZzZXQgPD0gLTI0KSB7CisgICAgICAgICAgICAgICAgICAgIGhvdXIgLT0gem9uZU9mZnNldCAvIDEwMDsKKyAgICAgICAgICAgICAgICAgICAgbWludXRlIC09IHpvbmVPZmZzZXQgJSAxMDA7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaG91ciAtPSB6b25lT2Zmc2V0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gVVRDKHllYXIgLSAxOTAwLCBtb250aCwgZGF0ZSwgaG91ciwgbWludXRlLCBzZWNvbmQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKHllYXIgLSAxOTAwLCBtb250aCwgZGF0ZSwgaG91ciwgbWludXRlLCBzZWNvbmQpCisgICAgICAgICAgICAgICAgICAgIC5nZXRUaW1lKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGdyZWdvcmlhbiBjYWxlbmRhciBkYXkgb2YgdGhlIG1vbnRoIGZvciB0aGlzIHtAY29kZSBEYXRlfSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF5CisgICAgICogICAgICAgICAgICB0aGUgZGF5IG9mIHRoZSBtb250aC4KKyAgICAgKgorICAgICAqIEBkZXByZWNhdGVkIHVzZSB7QGNvZGUgQ2FsZW5kYXIuc2V0KENhbGVuZGFyLkRBVEUsIGRheSl9CisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgdm9pZCBzZXREYXRlKGludCBkYXkpIHsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKG1pbGxpc2Vjb25kcyk7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuREFURSwgZGF5KTsKKyAgICAgICAgbWlsbGlzZWNvbmRzID0gY2FsLmdldFRpbWVJbk1pbGxpcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGdyZWdvcmlhbiBjYWxlbmRhciBob3VyIG9mIHRoZSBkYXkgZm9yIHRoaXMge0Bjb2RlIERhdGV9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3VyCisgICAgICogICAgICAgICAgICB0aGUgaG91ciBvZiB0aGUgZGF5LgorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIHtAY29kZSBDYWxlbmRhci5zZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVksIGhvdXIpfQorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHZvaWQgc2V0SG91cnMoaW50IGhvdXIpIHsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKG1pbGxpc2Vjb25kcyk7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVksIGhvdXIpOworICAgICAgICBtaWxsaXNlY29uZHMgPSBjYWwuZ2V0VGltZUluTWlsbGlzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZ3JlZ29yaWFuIGNhbGVuZGFyIG1pbnV0ZSBvZiB0aGUgaG91ciBmb3IgdGhpcyB7QGNvZGUgRGF0ZX0gb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIG1pbnV0ZQorICAgICAqICAgICAgICAgICAgdGhlIG1pbnV0ZXMuCisgICAgICoKKyAgICAgKiBAZGVwcmVjYXRlZCB1c2Uge0Bjb2RlIENhbGVuZGFyLnNldChDYWxlbmRhci5NSU5VVEUsIG1pbnV0ZSl9CisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgdm9pZCBzZXRNaW51dGVzKGludCBtaW51dGUpIHsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKG1pbGxpc2Vjb25kcyk7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuTUlOVVRFLCBtaW51dGUpOworICAgICAgICBtaWxsaXNlY29uZHMgPSBjYWwuZ2V0VGltZUluTWlsbGlzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZ3JlZ29yaWFuIGNhbGVuZGFyIG1vbnRoIGZvciB0aGlzIHtAY29kZSBEYXRlfSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbW9udGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtb250aC4KKyAgICAgKgorICAgICAqIEBkZXByZWNhdGVkIHVzZSB7QGNvZGUgQ2FsZW5kYXIuc2V0KENhbGVuZGFyLk1PTlRILCBtb250aCl9CisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgdm9pZCBzZXRNb250aChpbnQgbW9udGgpIHsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKG1pbGxpc2Vjb25kcyk7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuTU9OVEgsIG1vbnRoKTsKKyAgICAgICAgbWlsbGlzZWNvbmRzID0gY2FsLmdldFRpbWVJbk1pbGxpcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGdyZWdvcmlhbiBjYWxlbmRhciBzZWNvbmQgb2YgdGhlIG1pbnV0ZSBmb3IgdGhpcyB7QGNvZGUgRGF0ZX0gb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHNlY29uZAorICAgICAqICAgICAgICAgICAgdGhlIHNlY29uZHMuCisgICAgICoKKyAgICAgKiBAZGVwcmVjYXRlZCB1c2Uge0Bjb2RlIENhbGVuZGFyLnNldChDYWxlbmRhci5TRUNPTkQsIHNlY29uZCl9CisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgdm9pZCBzZXRTZWNvbmRzKGludCBzZWNvbmQpIHsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKG1pbGxpc2Vjb25kcyk7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuU0VDT05ELCBzZWNvbmQpOworICAgICAgICBtaWxsaXNlY29uZHMgPSBjYWwuZ2V0VGltZUluTWlsbGlzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGlzIHtAY29kZSBEYXRlfSB0byB0aGUgc3BlY2lmaWVkIG1pbGxpc2Vjb25kIHZhbHVlLiBUaGUgdmFsdWUgaXMgdGhlCisgICAgICogbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBzaW5jZSBKYW4uIDEsIDE5NzAgR01ULgorICAgICAqCisgICAgICogQHBhcmFtIG1pbGxpc2Vjb25kcworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgc2luY2UgSmFuLiAxLCAxOTcwIEdNVC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lKGxvbmcgbWlsbGlzZWNvbmRzKSB7CisgICAgICAgIHRoaXMubWlsbGlzZWNvbmRzID0gbWlsbGlzZWNvbmRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGdyZWdvcmlhbiBjYWxlbmRhciB5ZWFyIHNpbmNlIDE5MDAgZm9yIHRoaXMge0Bjb2RlIERhdGV9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB5ZWFyCisgICAgICogICAgICAgICAgICB0aGUgeWVhciBzaW5jZSAxOTAwLgorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIHtAY29kZSBDYWxlbmRhci5zZXQoQ2FsZW5kYXIuWUVBUiwgeWVhciArIDE5MDApfQorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHZvaWQgc2V0WWVhcihpbnQgeWVhcikgeworICAgICAgICBHcmVnb3JpYW5DYWxlbmRhciBjYWwgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIobWlsbGlzZWNvbmRzKTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5ZRUFSLCB5ZWFyICsgMTkwMCk7CisgICAgICAgIG1pbGxpc2Vjb25kcyA9IGNhbC5nZXRUaW1lSW5NaWxsaXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgRGF0ZX0gaW4gR01UIGluIHRoZSBmb3JtYXQKKyAgICAgKiB7QGNvZGUgIjIyIEp1biAxOTk5IDEzOjAyOjAwIEdNVCJ9LgorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIHtAbGluayBEYXRlRm9ybWF0fQorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIFN0cmluZyB0b0dNVFN0cmluZygpIHsKKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBzZGYgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgiZCBNTU0geSBISDptbTpzcyAnR01UJyIsIExvY2FsZS5VUyk7CisgICAgICAgIFRpbWVab25lIGdtdFpvbmUgPSBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiR01UIik7CisgICAgICAgIHNkZi5zZXRUaW1lWm9uZShnbXRab25lKTsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgZ2MgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoZ210Wm9uZSk7CisgICAgICAgIGdjLnNldFRpbWVJbk1pbGxpcyhtaWxsaXNlY29uZHMpOworICAgICAgICByZXR1cm4gc2RmLmZvcm1hdCh0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgRGF0ZX0gZm9yIHRoZSBkZWZhdWx0IHtAY29kZSBMb2NhbGV9LgorICAgICAqCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIHtAbGluayBEYXRlRm9ybWF0fQorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIFN0cmluZyB0b0xvY2FsZVN0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIERhdGVGb3JtYXQuZ2V0RGF0ZVRpbWVJbnN0YW5jZSgpLmZvcm1hdCh0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMge0Bjb2RlIERhdGV9LgorICAgICAqIFRoZSBmb3JtYXR0aW5nIGlzIGVxdWl2YWxlbnQgdG8gdXNpbmcgYSB7QGNvZGUgU2ltcGxlRGF0ZUZvcm1hdH0gd2l0aAorICAgICAqIHRoZSBmb3JtYXQgc3RyaW5nICJFRUUgTU1NIGRkIEhIOm1tOnNzIHp6eiB5eXl5Iiwgd2hpY2ggbG9va3Mgc29tZXRoaW5nCisgICAgICogbGlrZSAiVHVlIEp1biAyMiAxMzowNzowMCBQRFQgMTk5OSIuIFRoZSBjdXJyZW50IGRlZmF1bHQgdGltZSB6b25lIGFuZAorICAgICAqIGxvY2FsZSBhcmUgdXNlZC4gSWYgeW91IG5lZWQgY29udHJvbCBvdmVyIHRoZSB0aW1lIHpvbmUgb3IgbG9jYWxlLAorICAgICAqIHVzZSB7QGNvZGUgU2ltcGxlRGF0ZUZvcm1hdH0gaW5zdGVhZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAvLyBUT0RPOiBlcXVpdmFsZW50IHRvIHRoZSBmb2xsb3dpbmcgb25lLWxpbmVyLCB0aG91Z2ggdGhhdCdzIHNsb3dlciBvbiBzdGluZ3JheQorICAgICAgICAvLyBhdCA0NzZ1cyB2ZXJzdXMgNjl1cy4uLgorICAgICAgICAvLyAgIHJldHVybiBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgiRUVFIE1NTSBkZCBISDptbTpzcyB6enogeXl5eSIpLmZvcm1hdChkKTsKKyAgICAgICAgTG9jYWxlRGF0YSBsb2NhbGVEYXRhID0gTG9jYWxlRGF0YS5nZXQoTG9jYWxlLlVTKTsKKyAgICAgICAgQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKG1pbGxpc2Vjb25kcyk7CisgICAgICAgIFRpbWVab25lIHR6ID0gY2FsLmdldFRpbWVab25lKCk7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZChsb2NhbGVEYXRhLnNob3J0V2Vla2RheU5hbWVzW2NhbC5nZXQoQ2FsZW5kYXIuREFZX09GX1dFRUspXSk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQoJyAnKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZChsb2NhbGVEYXRhLnNob3J0TW9udGhOYW1lc1tjYWwuZ2V0KENhbGVuZGFyLk1PTlRIKV0pOworICAgICAgICByZXN1bHQuYXBwZW5kKCcgJyk7CisgICAgICAgIGFwcGVuZFR3b0RpZ2l0cyhyZXN1bHQsIGNhbC5nZXQoQ2FsZW5kYXIuREFZX09GX01PTlRIKSk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQoJyAnKTsKKyAgICAgICAgYXBwZW5kVHdvRGlnaXRzKHJlc3VsdCwgY2FsLmdldChDYWxlbmRhci5IT1VSX09GX0RBWSkpOworICAgICAgICByZXN1bHQuYXBwZW5kKCc6Jyk7CisgICAgICAgIGFwcGVuZFR3b0RpZ2l0cyhyZXN1bHQsIGNhbC5nZXQoQ2FsZW5kYXIuTUlOVVRFKSk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQoJzonKTsKKyAgICAgICAgYXBwZW5kVHdvRGlnaXRzKHJlc3VsdCwgY2FsLmdldChDYWxlbmRhci5TRUNPTkQpKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZCgnICcpOworICAgICAgICByZXN1bHQuYXBwZW5kKHR6LmdldERpc3BsYXlOYW1lKHR6LmluRGF5bGlnaHRUaW1lKHRoaXMpLCBUaW1lWm9uZS5TSE9SVCkpOworICAgICAgICByZXN1bHQuYXBwZW5kKCcgJyk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQoY2FsLmdldChDYWxlbmRhci5ZRUFSKSk7CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGFwcGVuZFR3b0RpZ2l0cyhTdHJpbmdCdWlsZGVyIHNiLCBpbnQgbikgeworICAgICAgICBpZiAobiA8IDEwKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoJzAnKTsKKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQobik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbWlsbGlzZWNvbmQgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBkYXRlIGFuZCB0aW1lIGluIEdNVC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB5ZWFyCisgICAgICogICAgICAgICAgICB0aGUgeWVhciwgMCBpcyAxOTAwLgorICAgICAqIEBwYXJhbSBtb250aAorICAgICAqICAgICAgICAgICAgdGhlIG1vbnRoLCAwIC0gMTEuCisgICAgICogQHBhcmFtIGRheQorICAgICAqICAgICAgICAgICAgdGhlIGRheSBvZiB0aGUgbW9udGgsIDEgLSAzMS4KKyAgICAgKiBAcGFyYW0gaG91cgorICAgICAqICAgICAgICAgICAgdGhlIGhvdXIgb2YgZGF5LCAwIC0gMjMuCisgICAgICogQHBhcmFtIG1pbnV0ZQorICAgICAqICAgICAgICAgICAgdGhlIG1pbnV0ZSBvZiB0aGUgaG91ciwgMCAtIDU5LgorICAgICAqIEBwYXJhbSBzZWNvbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNvbmQgb2YgdGhlIG1pbnV0ZSwgMCAtIDU5LgorICAgICAqIEByZXR1cm4gdGhlIGRhdGUgYW5kIHRpbWUgaW4gR01UIGluIG1pbGxpc2Vjb25kcy4KKyAgICAgKgorICAgICAqIEBkZXByZWNhdGVkIHVzZTogPGNvZGU+CisgICAgICogIENhbGVuZGFyIGNhbCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcihUaW1lWm9uZS5nZXRUaW1lWm9uZSgiR01UIikpOworICAgICAqICBjYWwuc2V0KHllYXIgKyAxOTAwLCBtb250aCwgZGF5LCBob3VyLCBtaW51dGUsIHNlY29uZCk7CisgICAgICogIGNhbC5nZXRUaW1lKCkuZ2V0VGltZSgpOzwvY29kZT4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBVVEMoaW50IHllYXIsIGludCBtb250aCwgaW50IGRheSwgaW50IGhvdXIsIGludCBtaW51dGUsCisgICAgICAgICAgICBpbnQgc2Vjb25kKSB7CisgICAgICAgIEdyZWdvcmlhbkNhbGVuZGFyIGNhbCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcihmYWxzZSk7CisgICAgICAgIGNhbC5zZXRUaW1lWm9uZShUaW1lWm9uZS5nZXRUaW1lWm9uZSgiR01UIikpOworICAgICAgICBjYWwuc2V0KDE5MDAgKyB5ZWFyLCBtb250aCwgZGF5LCBob3VyLCBtaW51dGUsIHNlY29uZCk7CisgICAgICAgIHJldHVybiBjYWwuZ2V0VGltZUluTWlsbGlzKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHpvbmUoU3RyaW5nIHRleHQpIHsKKyAgICAgICAgaWYgKHRleHQuZXF1YWxzKCJFU1QiKSkgeworICAgICAgICAgICAgcmV0dXJuIC01OworICAgICAgICB9CisgICAgICAgIGlmICh0ZXh0LmVxdWFscygiRURUIikpIHsKKyAgICAgICAgICAgIHJldHVybiAtNDsKKyAgICAgICAgfQorICAgICAgICBpZiAodGV4dC5lcXVhbHMoIkNTVCIpKSB7CisgICAgICAgICAgICByZXR1cm4gLTY7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRleHQuZXF1YWxzKCJDRFQiKSkgeworICAgICAgICAgICAgcmV0dXJuIC01OworICAgICAgICB9CisgICAgICAgIGlmICh0ZXh0LmVxdWFscygiTVNUIikpIHsKKyAgICAgICAgICAgIHJldHVybiAtNzsKKyAgICAgICAgfQorICAgICAgICBpZiAodGV4dC5lcXVhbHMoIk1EVCIpKSB7CisgICAgICAgICAgICByZXR1cm4gLTY7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRleHQuZXF1YWxzKCJQU1QiKSkgeworICAgICAgICAgICAgcmV0dXJuIC04OworICAgICAgICB9CisgICAgICAgIGlmICh0ZXh0LmVxdWFscygiUERUIikpIHsKKyAgICAgICAgICAgIHJldHVybiAtNzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3RyZWFtLmRlZmF1bHRXcml0ZU9iamVjdCgpOworICAgICAgICBzdHJlYW0ud3JpdGVMb25nKGdldFRpbWUoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgICAgICBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgc3RyZWFtLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisgICAgICAgIHNldFRpbWUoc3RyZWFtLnJlYWRMb25nKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRGVxdWUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRGVxdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYjZiZDkwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9EZXF1ZS5qYXZhCkBAIC0wLDAgKzEsNTQ4IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSBhbmQgSm9zaCBCbG9jaCB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mCisgKiBKQ1AgSlNSLTE2NiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQKKyAqIGF0IGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisvLyBCRUdJTiBhbmRyb2lkLW5vdGUKKy8vIHJlbW92ZWQgbGluayB0byBjb2xsZWN0aW9ucyBmcmFtZXdvcmsgZG9jcworLy8gY2hhbmdlZCB7QGxpbmsgI29mZmVyKE9iamVjdCl9IHRvIHtAbGluayAjb2ZmZXJ9IHRvIHNhdGlzZnkgRHJvaWREb2MKKy8vIEVORCBhbmRyb2lkLW5vdGUKKworLyoqCisgKiBBIGxpbmVhciBjb2xsZWN0aW9uIHRoYXQgc3VwcG9ydHMgZWxlbWVudCBpbnNlcnRpb24gYW5kIHJlbW92YWwgYXQKKyAqIGJvdGggZW5kcy4gIFRoZSBuYW1lIDxpPmRlcXVlPC9pPiBpcyBzaG9ydCBmb3IgImRvdWJsZSBlbmRlZCBxdWV1ZSIKKyAqIGFuZCBpcyB1c3VhbGx5IHByb25vdW5jZWQgImRlY2siLiAgTW9zdCA8dHQ+RGVxdWU8L3R0PgorICogaW1wbGVtZW50YXRpb25zIHBsYWNlIG5vIGZpeGVkIGxpbWl0cyBvbiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzCisgKiB0aGV5IG1heSBjb250YWluLCBidXQgdGhpcyBpbnRlcmZhY2Ugc3VwcG9ydHMgY2FwYWNpdHktcmVzdHJpY3RlZAorICogZGVxdWVzIGFzIHdlbGwgYXMgdGhvc2Ugd2l0aCBubyBmaXhlZCBzaXplIGxpbWl0LgorICoKKyAqIDxwPlRoaXMgaW50ZXJmYWNlIGRlZmluZXMgbWV0aG9kcyB0byBhY2Nlc3MgdGhlIGVsZW1lbnRzIGF0IGJvdGgKKyAqIGVuZHMgb2YgdGhlIGRlcXVlLiAgTWV0aG9kcyBhcmUgcHJvdmlkZWQgdG8gaW5zZXJ0LCByZW1vdmUsIGFuZAorICogZXhhbWluZSB0aGUgZWxlbWVudC4gIEVhY2ggb2YgdGhlc2UgbWV0aG9kcyBleGlzdHMgaW4gdHdvIGZvcm1zOgorICogb25lIHRocm93cyBhbiBleGNlcHRpb24gaWYgdGhlIG9wZXJhdGlvbiBmYWlscywgdGhlIG90aGVyIHJldHVybnMgYQorICogc3BlY2lhbCB2YWx1ZSAoZWl0aGVyIDx0dD5udWxsPC90dD4gb3IgPHR0PmZhbHNlPC90dD4sIGRlcGVuZGluZyBvbgorICogdGhlIG9wZXJhdGlvbikuICBUaGUgbGF0dGVyIGZvcm0gb2YgdGhlIGluc2VydCBvcGVyYXRpb24gaXMKKyAqIGRlc2lnbmVkIHNwZWNpZmljYWxseSBmb3IgdXNlIHdpdGggY2FwYWNpdHktcmVzdHJpY3RlZAorICogPHR0PkRlcXVlPC90dD4gaW1wbGVtZW50YXRpb25zOyBpbiBtb3N0IGltcGxlbWVudGF0aW9ucywgaW5zZXJ0CisgKiBvcGVyYXRpb25zIGNhbm5vdCBmYWlsLgorICoKKyAqIDxwPlRoZSB0d2VsdmUgbWV0aG9kcyBkZXNjcmliZWQgYWJvdmUgYXJlIHN1bW1hcml6ZWQgaW4gdGhlCisgKiBmb2xsb3dpbmcgdGFibGU6CisgKgorICogPHA+CisgKiA8dGFibGUgQk9SREVSIENFTExQQURESU5HPTMgQ0VMTFNQQUNJTkc9MT4KKyAqICA8dHI+CisgKiAgICA8dGQ+PC90ZD4KKyAqICAgIDx0ZCBBTElHTj1DRU5URVIgQ09MU1BBTiA9IDI+IDxiPkZpcnN0IEVsZW1lbnQgKEhlYWQpPC9iPjwvdGQ+CisgKiAgICA8dGQgQUxJR049Q0VOVEVSIENPTFNQQU4gPSAyPiA8Yj5MYXN0IEVsZW1lbnQgKFRhaWwpPC9iPjwvdGQ+CisgKiAgPC90cj4KKyAqICA8dHI+CisgKiAgICA8dGQ+PC90ZD4KKyAqICAgIDx0ZCBBTElHTj1DRU5URVI+PGVtPlRocm93cyBleGNlcHRpb248L2VtPjwvdGQ+CisgKiAgICA8dGQgQUxJR049Q0VOVEVSPjxlbT5TcGVjaWFsIHZhbHVlPC9lbT48L3RkPgorICogICAgPHRkIEFMSUdOPUNFTlRFUj48ZW0+VGhyb3dzIGV4Y2VwdGlvbjwvZW0+PC90ZD4KKyAqICAgIDx0ZCBBTElHTj1DRU5URVI+PGVtPlNwZWNpYWwgdmFsdWU8L2VtPjwvdGQ+CisgKiAgPC90cj4KKyAqICA8dHI+CisgKiAgICA8dGQ+PGI+SW5zZXJ0PC9iPjwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNhZGRGaXJzdCBhZGRGaXJzdChlKX08L3RkPgorICogICAgPHRkPntAbGluayAjb2ZmZXJGaXJzdCBvZmZlckZpcnN0KGUpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNhZGRMYXN0IGFkZExhc3QoZSl9PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI29mZmVyTGFzdCBvZmZlckxhc3QoZSl9PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZD48Yj5SZW1vdmU8L2I+PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI3JlbW92ZUZpcnN0IHJlbW92ZUZpcnN0KCl9PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI3BvbGxGaXJzdCBwb2xsRmlyc3QoKX08L3RkPgorICogICAgPHRkPntAbGluayAjcmVtb3ZlTGFzdCByZW1vdmVMYXN0KCl9PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI3BvbGxMYXN0IHBvbGxMYXN0KCl9PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZD48Yj5FeGFtaW5lPC9iPjwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNnZXRGaXJzdCBnZXRGaXJzdCgpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNwZWVrRmlyc3QgcGVla0ZpcnN0KCl9PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI2dldExhc3QgZ2V0TGFzdCgpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNwZWVrTGFzdCBwZWVrTGFzdCgpfTwvdGQ+CisgKiAgPC90cj4KKyAqIDwvdGFibGU+CisgKgorICogPHA+VGhpcyBpbnRlcmZhY2UgZXh0ZW5kcyB0aGUge0BsaW5rIFF1ZXVlfSBpbnRlcmZhY2UuICBXaGVuIGEgZGVxdWUgaXMKKyAqIHVzZWQgYXMgYSBxdWV1ZSwgRklGTyAoRmlyc3QtSW4tRmlyc3QtT3V0KSBiZWhhdmlvciByZXN1bHRzLiAgRWxlbWVudHMgYXJlCisgKiBhZGRlZCBhdCB0aGUgZW5kIG9mIHRoZSBkZXF1ZSBhbmQgcmVtb3ZlZCBmcm9tIHRoZSBiZWdpbm5pbmcuICBUaGUgbWV0aG9kcworICogaW5oZXJpdGVkIGZyb20gdGhlIDx0dD5RdWV1ZTwvdHQ+IGludGVyZmFjZSBhcmUgcHJlY2lzZWx5IGVxdWl2YWxlbnQgdG8KKyAqIDx0dD5EZXF1ZTwvdHQ+IG1ldGhvZHMgYXMgaW5kaWNhdGVkIGluIHRoZSBmb2xsb3dpbmcgdGFibGU6CisgKgorICogPHA+CisgKiA8dGFibGUgQk9SREVSIENFTExQQURESU5HPTMgQ0VMTFNQQUNJTkc9MT4KKyAqICA8dHI+CisgKiAgICA8dGQgQUxJR049Q0VOVEVSPiA8Yj48dHQ+UXVldWU8L3R0PiBNZXRob2Q8L2I+PC90ZD4KKyAqICAgIDx0ZCBBTElHTj1DRU5URVI+IDxiPkVxdWl2YWxlbnQgPHR0PkRlcXVlPC90dD4gTWV0aG9kPC9iPjwvdGQ+CisgKiAgPC90cj4KKyAqICA8dHI+CisgKiAgICA8dGQ+e0BsaW5rIGphdmEudXRpbC5RdWV1ZSNhZGQgYWRkKGUpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNhZGRMYXN0IGFkZExhc3QoZSl9PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZD57QGxpbmsgamF2YS51dGlsLlF1ZXVlI29mZmVyIG9mZmVyKGUpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNvZmZlckxhc3Qgb2ZmZXJMYXN0KGUpfTwvdGQ+CisgKiAgPC90cj4KKyAqICA8dHI+CisgKiAgICA8dGQ+e0BsaW5rIGphdmEudXRpbC5RdWV1ZSNyZW1vdmUgcmVtb3ZlKCl9PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI3JlbW92ZUZpcnN0IHJlbW92ZUZpcnN0KCl9PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZD57QGxpbmsgamF2YS51dGlsLlF1ZXVlI3BvbGwgcG9sbCgpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNwb2xsRmlyc3QgcG9sbEZpcnN0KCl9PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZD57QGxpbmsgamF2YS51dGlsLlF1ZXVlI2VsZW1lbnQgZWxlbWVudCgpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNnZXRGaXJzdCBnZXRGaXJzdCgpfTwvdGQ+CisgKiAgPC90cj4KKyAqICA8dHI+CisgKiAgICA8dGQ+e0BsaW5rIGphdmEudXRpbC5RdWV1ZSNwZWVrIHBlZWsoKX08L3RkPgorICogICAgPHRkPntAbGluayAjcGVlayBwZWVrRmlyc3QoKX08L3RkPgorICogIDwvdHI+CisgKiA8L3RhYmxlPgorICoKKyAqIDxwPkRlcXVlcyBjYW4gYWxzbyBiZSB1c2VkIGFzIExJRk8gKExhc3QtSW4tRmlyc3QtT3V0KSBzdGFja3MuICBUaGlzCisgKiBpbnRlcmZhY2Ugc2hvdWxkIGJlIHVzZWQgaW4gcHJlZmVyZW5jZSB0byB0aGUgbGVnYWN5IHtAbGluayBTdGFja30gY2xhc3MuCisgKiBXaGVuIGEgZGVxdWUgaXMgdXNlZCBhcyBhIHN0YWNrLCBlbGVtZW50cyBhcmUgcHVzaGVkIGFuZCBwb3BwZWQgZnJvbSB0aGUKKyAqIGJlZ2lubmluZyBvZiB0aGUgZGVxdWUuICBTdGFjayBtZXRob2RzIGFyZSBwcmVjaXNlbHkgZXF1aXZhbGVudCB0bworICogPHR0PkRlcXVlPC90dD4gbWV0aG9kcyBhcyBpbmRpY2F0ZWQgaW4gdGhlIHRhYmxlIGJlbG93OgorICoKKyAqIDxwPgorICogPHRhYmxlIEJPUkRFUiBDRUxMUEFERElORz0zIENFTExTUEFDSU5HPTE+CisgKiAgPHRyPgorICogICAgPHRkIEFMSUdOPUNFTlRFUj4gPGI+U3RhY2sgTWV0aG9kPC9iPjwvdGQ+CisgKiAgICA8dGQgQUxJR049Q0VOVEVSPiA8Yj5FcXVpdmFsZW50IDx0dD5EZXF1ZTwvdHQ+IE1ldGhvZDwvYj48L3RkPgorICogIDwvdHI+CisgKiAgPHRyPgorICogICAgPHRkPntAbGluayAjcHVzaCBwdXNoKGUpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNhZGRGaXJzdCBhZGRGaXJzdChlKX08L3RkPgorICogIDwvdHI+CisgKiAgPHRyPgorICogICAgPHRkPntAbGluayAjcG9wIHBvcCgpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNyZW1vdmVGaXJzdCByZW1vdmVGaXJzdCgpfTwvdGQ+CisgKiAgPC90cj4KKyAqICA8dHI+CisgKiAgICA8dGQ+e0BsaW5rICNwZWVrIHBlZWsoKX08L3RkPgorICogICAgPHRkPntAbGluayAjcGVla0ZpcnN0IHBlZWtGaXJzdCgpfTwvdGQ+CisgKiAgPC90cj4KKyAqIDwvdGFibGU+CisgKgorICogPHA+Tm90ZSB0aGF0IHRoZSB7QGxpbmsgI3BlZWsgcGVla30gbWV0aG9kIHdvcmtzIGVxdWFsbHkgd2VsbCB3aGVuCisgKiBhIGRlcXVlIGlzIHVzZWQgYXMgYSBxdWV1ZSBvciBhIHN0YWNrOyBpbiBlaXRoZXIgY2FzZSwgZWxlbWVudHMgYXJlCisgKiBkcmF3biBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGRlcXVlLgorICoKKyAqIDxwPlRoaXMgaW50ZXJmYWNlIHByb3ZpZGVzIHR3byBtZXRob2RzIHRvIHJlbW92ZSBpbnRlcmlvcgorICogZWxlbWVudHMsIHtAbGluayAjcmVtb3ZlRmlyc3RPY2N1cnJlbmNlIHJlbW92ZUZpcnN0T2NjdXJyZW5jZX0gYW5kCisgKiB7QGxpbmsgI3JlbW92ZUxhc3RPY2N1cnJlbmNlIHJlbW92ZUxhc3RPY2N1cnJlbmNlfS4KKyAqCisgKiA8cD5Vbmxpa2UgdGhlIHtAbGluayBMaXN0fSBpbnRlcmZhY2UsIHRoaXMgaW50ZXJmYWNlIGRvZXMgbm90CisgKiBwcm92aWRlIHN1cHBvcnQgZm9yIGluZGV4ZWQgYWNjZXNzIHRvIGVsZW1lbnRzLgorICoKKyAqIDxwPldoaWxlIDx0dD5EZXF1ZTwvdHQ+IGltcGxlbWVudGF0aW9ucyBhcmUgbm90IHN0cmljdGx5IHJlcXVpcmVkCisgKiB0byBwcm9oaWJpdCB0aGUgaW5zZXJ0aW9uIG9mIG51bGwgZWxlbWVudHMsIHRoZXkgYXJlIHN0cm9uZ2x5CisgKiBlbmNvdXJhZ2VkIHRvIGRvIHNvLiAgVXNlcnMgb2YgYW55IDx0dD5EZXF1ZTwvdHQ+IGltcGxlbWVudGF0aW9ucworICogdGhhdCBkbyBhbGxvdyBudWxsIGVsZW1lbnRzIGFyZSBzdHJvbmdseSBlbmNvdXJhZ2VkIDxpPm5vdDwvaT4gdG8KKyAqIHRha2UgYWR2YW50YWdlIG9mIHRoZSBhYmlsaXR5IHRvIGluc2VydCBudWxscy4gIFRoaXMgaXMgc28gYmVjYXVzZQorICogPHR0Pm51bGw8L3R0PiBpcyB1c2VkIGFzIGEgc3BlY2lhbCByZXR1cm4gdmFsdWUgYnkgdmFyaW91cyBtZXRob2RzCisgKiB0byBpbmRpY2F0ZWQgdGhhdCB0aGUgZGVxdWUgaXMgZW1wdHkuCisgKgorICogPHA+PHR0PkRlcXVlPC90dD4gaW1wbGVtZW50YXRpb25zIGdlbmVyYWxseSBkbyBub3QgZGVmaW5lCisgKiBlbGVtZW50LWJhc2VkIHZlcnNpb25zIG9mIHRoZSA8dHQ+ZXF1YWxzPC90dD4gYW5kIDx0dD5oYXNoQ29kZTwvdHQ+CisgKiBtZXRob2RzLCBidXQgaW5zdGVhZCBpbmhlcml0IHRoZSBpZGVudGl0eS1iYXNlZCB2ZXJzaW9ucyBmcm9tIGNsYXNzCisgKiA8dHQ+T2JqZWN0PC90dD4uCisgKgorICogQGF1dGhvciBEb3VnIExlYQorICogQGF1dGhvciBKb3NoIEJsb2NoCisgKiBAc2luY2UgIDEuNgorICogQHBhcmFtIDxFPiB0aGUgdHlwZSBvZiBlbGVtZW50cyBoZWxkIGluIHRoaXMgY29sbGVjdGlvbgorICovCisKK3B1YmxpYyBpbnRlcmZhY2UgRGVxdWU8RT4gZXh0ZW5kcyBRdWV1ZTxFPiB7CisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgYXQgdGhlIGZyb250IG9mIHRoaXMgZGVxdWUgaWYgaXQgaXMKKyAgICAgKiBwb3NzaWJsZSB0byBkbyBzbyBpbW1lZGlhdGVseSB3aXRob3V0IHZpb2xhdGluZyBjYXBhY2l0eSByZXN0cmljdGlvbnMuCisgICAgICogV2hlbiB1c2luZyBhIGNhcGFjaXR5LXJlc3RyaWN0ZWQgZGVxdWUsIGl0IGlzIGdlbmVyYWxseSBwcmVmZXJhYmxlIHRvCisgICAgICogdXNlIG1ldGhvZCB7QGxpbmsgI29mZmVyRmlyc3R9LgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlIGVsZW1lbnQgY2Fubm90IGJlIGFkZGVkIGF0IHRoaXMKKyAgICAgKiAgICAgICAgIHRpbWUgZHVlIHRvIGNhcGFjaXR5IHJlc3RyaWN0aW9ucworICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKiAgICAgICAgIHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBkZXF1ZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwgYW5kIHRoaXMKKyAgICAgKiAgICAgICAgIGRlcXVlIGRvZXMgbm90IHBlcm1pdCBudWxsIGVsZW1lbnRzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc29tZSBwcm9wZXJ0eSBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBlbGVtZW50IHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBkZXF1ZQorICAgICAqLworICAgIHZvaWQgYWRkRmlyc3QoRSBlKTsKKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGF0IHRoZSBlbmQgb2YgdGhpcyBkZXF1ZSBpZiBpdCBpcworICAgICAqIHBvc3NpYmxlIHRvIGRvIHNvIGltbWVkaWF0ZWx5IHdpdGhvdXQgdmlvbGF0aW5nIGNhcGFjaXR5IHJlc3RyaWN0aW9ucy4KKyAgICAgKiBXaGVuIHVzaW5nIGEgY2FwYWNpdHktcmVzdHJpY3RlZCBkZXF1ZSwgaXQgaXMgZ2VuZXJhbGx5IHByZWZlcmFibGUgdG8KKyAgICAgKiB1c2UgbWV0aG9kIHtAbGluayAjb2ZmZXJMYXN0fS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8ge0BsaW5rICNhZGR9LgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlIGVsZW1lbnQgY2Fubm90IGJlIGFkZGVkIGF0IHRoaXMKKyAgICAgKiAgICAgICAgIHRpbWUgZHVlIHRvIGNhcGFjaXR5IHJlc3RyaWN0aW9ucworICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKiAgICAgICAgIHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBkZXF1ZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwgYW5kIHRoaXMKKyAgICAgKiAgICAgICAgIGRlcXVlIGRvZXMgbm90IHBlcm1pdCBudWxsIGVsZW1lbnRzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc29tZSBwcm9wZXJ0eSBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBlbGVtZW50IHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBkZXF1ZQorICAgICAqLworICAgIHZvaWQgYWRkTGFzdChFIGUpOworCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgYXQgdGhlIGZyb250IG9mIHRoaXMgZGVxdWUgdW5sZXNzIGl0IHdvdWxkCisgICAgICogdmlvbGF0ZSBjYXBhY2l0eSByZXN0cmljdGlvbnMuICBXaGVuIHVzaW5nIGEgY2FwYWNpdHktcmVzdHJpY3RlZCBkZXF1ZSwKKyAgICAgKiB0aGlzIG1ldGhvZCBpcyBnZW5lcmFsbHkgcHJlZmVyYWJsZSB0byB0aGUge0BsaW5rICNhZGRGaXJzdH0gbWV0aG9kLAorICAgICAqIHdoaWNoIGNhbiBmYWlsIHRvIGluc2VydCBhbiBlbGVtZW50IG9ubHkgYnkgdGhyb3dpbmcgYW4gZXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoZSBlbGVtZW50IHdhcyBhZGRlZCB0byB0aGlzIGRlcXVlLCBlbHNlCisgICAgICogICAgICAgICA8dHQ+ZmFsc2U8L3R0PgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKiAgICAgICAgIHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBkZXF1ZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwgYW5kIHRoaXMKKyAgICAgKiAgICAgICAgIGRlcXVlIGRvZXMgbm90IHBlcm1pdCBudWxsIGVsZW1lbnRzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc29tZSBwcm9wZXJ0eSBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBlbGVtZW50IHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBkZXF1ZQorICAgICAqLworICAgIGJvb2xlYW4gb2ZmZXJGaXJzdChFIGUpOworCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgYXQgdGhlIGVuZCBvZiB0aGlzIGRlcXVlIHVubGVzcyBpdCB3b3VsZAorICAgICAqIHZpb2xhdGUgY2FwYWNpdHkgcmVzdHJpY3Rpb25zLiAgV2hlbiB1c2luZyBhIGNhcGFjaXR5LXJlc3RyaWN0ZWQgZGVxdWUsCisgICAgICogdGhpcyBtZXRob2QgaXMgZ2VuZXJhbGx5IHByZWZlcmFibGUgdG8gdGhlIHtAbGluayAjYWRkTGFzdH0gbWV0aG9kLAorICAgICAqIHdoaWNoIGNhbiBmYWlsIHRvIGluc2VydCBhbiBlbGVtZW50IG9ubHkgYnkgdGhyb3dpbmcgYW4gZXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoZSBlbGVtZW50IHdhcyBhZGRlZCB0byB0aGlzIGRlcXVlLCBlbHNlCisgICAgICogICAgICAgICA8dHQ+ZmFsc2U8L3R0PgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKiAgICAgICAgIHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBkZXF1ZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwgYW5kIHRoaXMKKyAgICAgKiAgICAgICAgIGRlcXVlIGRvZXMgbm90IHBlcm1pdCBudWxsIGVsZW1lbnRzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc29tZSBwcm9wZXJ0eSBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBlbGVtZW50IHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBkZXF1ZQorICAgICAqLworICAgIGJvb2xlYW4gb2ZmZXJMYXN0KEUgZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYW5kIHJlbW92ZXMgdGhlIGZpcnN0IGVsZW1lbnQgb2YgdGhpcyBkZXF1ZS4gIFRoaXMgbWV0aG9kCisgICAgICogZGlmZmVycyBmcm9tIHtAbGluayAjcG9sbEZpcnN0IHBvbGxGaXJzdH0gb25seSBpbiB0aGF0IGl0IHRocm93cyBhbgorICAgICAqIGV4Y2VwdGlvbiBpZiB0aGlzIGRlcXVlIGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGlzIGRlcXVlCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBFIHJlbW92ZUZpcnN0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYW5kIHJlbW92ZXMgdGhlIGxhc3QgZWxlbWVudCBvZiB0aGlzIGRlcXVlLiAgVGhpcyBtZXRob2QKKyAgICAgKiBkaWZmZXJzIGZyb20ge0BsaW5rICNwb2xsTGFzdCBwb2xsTGFzdH0gb25seSBpbiB0aGF0IGl0IHRocm93cyBhbgorICAgICAqIGV4Y2VwdGlvbiBpZiB0aGlzIGRlcXVlIGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdGFpbCBvZiB0aGlzIGRlcXVlCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBFIHJlbW92ZUxhc3QoKTsKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhbmQgcmVtb3ZlcyB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGlzIGRlcXVlLAorICAgICAqIG9yIHJldHVybnMgPHR0Pm51bGw8L3R0PiBpZiB0aGlzIGRlcXVlIGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGlzIGRlcXVlLCBvciA8dHQ+bnVsbDwvdHQ+IGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBFIHBvbGxGaXJzdCgpOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGFuZCByZW1vdmVzIHRoZSBsYXN0IGVsZW1lbnQgb2YgdGhpcyBkZXF1ZSwKKyAgICAgKiBvciByZXR1cm5zIDx0dD5udWxsPC90dD4gaWYgdGhpcyBkZXF1ZSBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHRhaWwgb2YgdGhpcyBkZXF1ZSwgb3IgPHR0Pm51bGw8L3R0PiBpZiB0aGlzIGRlcXVlIGlzIGVtcHR5CisgICAgICovCisgICAgRSBwb2xsTGFzdCgpOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzLCBidXQgZG9lcyBub3QgcmVtb3ZlLCB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGlzIGRlcXVlLgorICAgICAqCisgICAgICogVGhpcyBtZXRob2QgZGlmZmVycyBmcm9tIHtAbGluayAjcGVla0ZpcnN0IHBlZWtGaXJzdH0gb25seSBpbiB0aGF0IGl0CisgICAgICogdGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0aGlzIGRlcXVlIGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGlzIGRlcXVlCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBFIGdldEZpcnN0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMsIGJ1dCBkb2VzIG5vdCByZW1vdmUsIHRoZSBsYXN0IGVsZW1lbnQgb2YgdGhpcyBkZXF1ZS4KKyAgICAgKiBUaGlzIG1ldGhvZCBkaWZmZXJzIGZyb20ge0BsaW5rICNwZWVrTGFzdCBwZWVrTGFzdH0gb25seSBpbiB0aGF0IGl0CisgICAgICogdGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0aGlzIGRlcXVlIGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdGFpbCBvZiB0aGlzIGRlcXVlCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBFIGdldExhc3QoKTsKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcywgYnV0IGRvZXMgbm90IHJlbW92ZSwgdGhlIGZpcnN0IGVsZW1lbnQgb2YgdGhpcyBkZXF1ZSwKKyAgICAgKiBvciByZXR1cm5zIDx0dD5udWxsPC90dD4gaWYgdGhpcyBkZXF1ZSBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhlYWQgb2YgdGhpcyBkZXF1ZSwgb3IgPHR0Pm51bGw8L3R0PiBpZiB0aGlzIGRlcXVlIGlzIGVtcHR5CisgICAgICovCisgICAgRSBwZWVrRmlyc3QoKTsKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcywgYnV0IGRvZXMgbm90IHJlbW92ZSwgdGhlIGxhc3QgZWxlbWVudCBvZiB0aGlzIGRlcXVlLAorICAgICAqIG9yIHJldHVybnMgPHR0Pm51bGw8L3R0PiBpZiB0aGlzIGRlcXVlIGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdGFpbCBvZiB0aGlzIGRlcXVlLCBvciA8dHQ+bnVsbDwvdHQ+IGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBFIHBlZWtMYXN0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBmcm9tIHRoaXMgZGVxdWUuCisgICAgICogSWYgdGhlIGRlcXVlIGRvZXMgbm90IGNvbnRhaW4gdGhlIGVsZW1lbnQsIGl0IGlzIHVuY2hhbmdlZC4KKyAgICAgKiBNb3JlIGZvcm1hbGx5LCByZW1vdmVzIHRoZSBmaXJzdCBlbGVtZW50IDx0dD5lPC90dD4gc3VjaCB0aGF0CisgICAgICogPHR0PihvPT1udWxsJm5ic3A7PyZuYnNwO2U9PW51bGwmbmJzcDs6Jm5ic3A7by5lcXVhbHMoZSkpPC90dD4KKyAgICAgKiAoaWYgc3VjaCBhbiBlbGVtZW50IGV4aXN0cykuCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgZGVxdWUgY29udGFpbmVkIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqIChvciBlcXVpdmFsZW50bHksIGlmIHRoaXMgZGVxdWUgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBlbGVtZW50IHRvIGJlIHJlbW92ZWQgZnJvbSB0aGlzIGRlcXVlLCBpZiBwcmVzZW50CisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIGFuIGVsZW1lbnQgd2FzIHJlbW92ZWQgYXMgYSByZXN1bHQgb2YgdGhpcyBjYWxsCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqICAgICAgICAgaXMgaW5jb21wYXRpYmxlIHdpdGggdGhpcyBkZXF1ZSAob3B0aW9uYWwpCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbCBhbmQgdGhpcworICAgICAqICAgICAgICAgZGVxdWUgZG9lcyBub3QgcGVybWl0IG51bGwgZWxlbWVudHMgKG9wdGlvbmFsKQorICAgICAqLworICAgIGJvb2xlYW4gcmVtb3ZlRmlyc3RPY2N1cnJlbmNlKE9iamVjdCBvKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgZnJvbSB0aGlzIGRlcXVlLgorICAgICAqIElmIHRoZSBkZXF1ZSBkb2VzIG5vdCBjb250YWluIHRoZSBlbGVtZW50LCBpdCBpcyB1bmNoYW5nZWQuCisgICAgICogTW9yZSBmb3JtYWxseSwgcmVtb3ZlcyB0aGUgbGFzdCBlbGVtZW50IDx0dD5lPC90dD4gc3VjaCB0aGF0CisgICAgICogPHR0PihvPT1udWxsJm5ic3A7PyZuYnNwO2U9PW51bGwmbmJzcDs6Jm5ic3A7by5lcXVhbHMoZSkpPC90dD4KKyAgICAgKiAoaWYgc3VjaCBhbiBlbGVtZW50IGV4aXN0cykuCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgZGVxdWUgY29udGFpbmVkIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqIChvciBlcXVpdmFsZW50bHksIGlmIHRoaXMgZGVxdWUgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBlbGVtZW50IHRvIGJlIHJlbW92ZWQgZnJvbSB0aGlzIGRlcXVlLCBpZiBwcmVzZW50CisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIGFuIGVsZW1lbnQgd2FzIHJlbW92ZWQgYXMgYSByZXN1bHQgb2YgdGhpcyBjYWxsCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqICAgICAgICAgaXMgaW5jb21wYXRpYmxlIHdpdGggdGhpcyBkZXF1ZSAob3B0aW9uYWwpCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbCBhbmQgdGhpcworICAgICAqICAgICAgICAgZGVxdWUgZG9lcyBub3QgcGVybWl0IG51bGwgZWxlbWVudHMgKG9wdGlvbmFsKQorICAgICAqLworICAgIGJvb2xlYW4gcmVtb3ZlTGFzdE9jY3VycmVuY2UoT2JqZWN0IG8pOworCisgICAgLy8gKioqIFF1ZXVlIG1ldGhvZHMgKioqCisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpbnRvIHRoZSBxdWV1ZSByZXByZXNlbnRlZCBieSB0aGlzIGRlcXVlCisgICAgICogKGluIG90aGVyIHdvcmRzLCBhdCB0aGUgdGFpbCBvZiB0aGlzIGRlcXVlKSBpZiBpdCBpcyBwb3NzaWJsZSB0byBkbyBzbworICAgICAqIGltbWVkaWF0ZWx5IHdpdGhvdXQgdmlvbGF0aW5nIGNhcGFjaXR5IHJlc3RyaWN0aW9ucywgcmV0dXJuaW5nCisgICAgICogPHR0PnRydWU8L3R0PiB1cG9uIHN1Y2Nlc3MgYW5kIHRocm93aW5nIGFuCisgICAgICogPHR0PklsbGVnYWxTdGF0ZUV4Y2VwdGlvbjwvdHQ+IGlmIG5vIHNwYWNlIGlzIGN1cnJlbnRseSBhdmFpbGFibGUuCisgICAgICogV2hlbiB1c2luZyBhIGNhcGFjaXR5LXJlc3RyaWN0ZWQgZGVxdWUsIGl0IGlzIGdlbmVyYWxseSBwcmVmZXJhYmxlIHRvCisgICAgICogdXNlIHtAbGluayAjb2ZmZXIgb2ZmZXJ9LgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byB7QGxpbmsgI2FkZExhc3R9LgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IChhcyBzcGVjaWZpZWQgYnkge0BsaW5rIENvbGxlY3Rpb24jYWRkfSkKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgZWxlbWVudCBjYW5ub3QgYmUgYWRkZWQgYXQgdGhpcworICAgICAqICAgICAgICAgdGltZSBkdWUgdG8gY2FwYWNpdHkgcmVzdHJpY3Rpb25zCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqICAgICAgICAgcHJldmVudHMgaXQgZnJvbSBiZWluZyBhZGRlZCB0byB0aGlzIGRlcXVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbCBhbmQgdGhpcworICAgICAqICAgICAgICAgZGVxdWUgZG9lcyBub3QgcGVybWl0IG51bGwgZWxlbWVudHMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBzb21lIHByb3BlcnR5IG9mIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIGVsZW1lbnQgcHJldmVudHMgaXQgZnJvbSBiZWluZyBhZGRlZCB0byB0aGlzIGRlcXVlCisgICAgICovCisgICAgYm9vbGVhbiBhZGQoRSBlKTsKKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGludG8gdGhlIHF1ZXVlIHJlcHJlc2VudGVkIGJ5IHRoaXMgZGVxdWUKKyAgICAgKiAoaW4gb3RoZXIgd29yZHMsIGF0IHRoZSB0YWlsIG9mIHRoaXMgZGVxdWUpIGlmIGl0IGlzIHBvc3NpYmxlIHRvIGRvIHNvCisgICAgICogaW1tZWRpYXRlbHkgd2l0aG91dCB2aW9sYXRpbmcgY2FwYWNpdHkgcmVzdHJpY3Rpb25zLCByZXR1cm5pbmcKKyAgICAgKiA8dHQ+dHJ1ZTwvdHQ+IHVwb24gc3VjY2VzcyBhbmQgPHR0PmZhbHNlPC90dD4gaWYgbm8gc3BhY2UgaXMgY3VycmVudGx5CisgICAgICogYXZhaWxhYmxlLiAgV2hlbiB1c2luZyBhIGNhcGFjaXR5LXJlc3RyaWN0ZWQgZGVxdWUsIHRoaXMgbWV0aG9kIGlzCisgICAgICogZ2VuZXJhbGx5IHByZWZlcmFibGUgdG8gdGhlIHtAbGluayAjYWRkfSBtZXRob2QsIHdoaWNoIGNhbiBmYWlsIHRvCisgICAgICogaW5zZXJ0IGFuIGVsZW1lbnQgb25seSBieSB0aHJvd2luZyBhbiBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAbGluayAjb2ZmZXJMYXN0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIHRoZSBlbGVtZW50IHRvIGFkZAorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGUgZWxlbWVudCB3YXMgYWRkZWQgdG8gdGhpcyBkZXF1ZSwgZWxzZQorICAgICAqICAgICAgICAgPHR0PmZhbHNlPC90dD4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3Mgb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICogICAgICAgICBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgZGVxdWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsIGFuZCB0aGlzCisgICAgICogICAgICAgICBkZXF1ZSBkb2VzIG5vdCBwZXJtaXQgbnVsbCBlbGVtZW50cworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNvbWUgcHJvcGVydHkgb2YgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgZWxlbWVudCBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgZGVxdWUKKyAgICAgKi8KKyAgICBib29sZWFuIG9mZmVyKEUgZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYW5kIHJlbW92ZXMgdGhlIGhlYWQgb2YgdGhlIHF1ZXVlIHJlcHJlc2VudGVkIGJ5IHRoaXMgZGVxdWUKKyAgICAgKiAoaW4gb3RoZXIgd29yZHMsIHRoZSBmaXJzdCBlbGVtZW50IG9mIHRoaXMgZGVxdWUpLgorICAgICAqIFRoaXMgbWV0aG9kIGRpZmZlcnMgZnJvbSB7QGxpbmsgI3BvbGwgcG9sbH0gb25seSBpbiB0aGF0IGl0IHRocm93cyBhbgorICAgICAqIGV4Y2VwdGlvbiBpZiB0aGlzIGRlcXVlIGlzIGVtcHR5LgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byB7QGxpbmsgI3JlbW92ZUZpcnN0KCl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGUgcXVldWUgcmVwcmVzZW50ZWQgYnkgdGhpcyBkZXF1ZQorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBpZiB0aGlzIGRlcXVlIGlzIGVtcHR5CisgICAgICovCisgICAgRSByZW1vdmUoKTsKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhbmQgcmVtb3ZlcyB0aGUgaGVhZCBvZiB0aGUgcXVldWUgcmVwcmVzZW50ZWQgYnkgdGhpcyBkZXF1ZQorICAgICAqIChpbiBvdGhlciB3b3JkcywgdGhlIGZpcnN0IGVsZW1lbnQgb2YgdGhpcyBkZXF1ZSksIG9yIHJldHVybnMKKyAgICAgKiA8dHQ+bnVsbDwvdHQ+IGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAbGluayAjcG9sbEZpcnN0KCl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGlzIGRlcXVlLCBvciA8dHQ+bnVsbDwvdHQ+IGlmCisgICAgICogICAgICAgICB0aGlzIGRlcXVlIGlzIGVtcHR5CisgICAgICovCisgICAgRSBwb2xsKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMsIGJ1dCBkb2VzIG5vdCByZW1vdmUsIHRoZSBoZWFkIG9mIHRoZSBxdWV1ZSByZXByZXNlbnRlZCBieQorICAgICAqIHRoaXMgZGVxdWUgKGluIG90aGVyIHdvcmRzLCB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGlzIGRlcXVlKS4KKyAgICAgKiBUaGlzIG1ldGhvZCBkaWZmZXJzIGZyb20ge0BsaW5rICNwZWVrIHBlZWt9IG9ubHkgaW4gdGhhdCBpdCB0aHJvd3MgYW4KKyAgICAgKiBleGNlcHRpb24gaWYgdGhpcyBkZXF1ZSBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8ge0BsaW5rICNnZXRGaXJzdCgpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhlYWQgb2YgdGhlIHF1ZXVlIHJlcHJlc2VudGVkIGJ5IHRoaXMgZGVxdWUKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gaWYgdGhpcyBkZXF1ZSBpcyBlbXB0eQorICAgICAqLworICAgIEUgZWxlbWVudCgpOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzLCBidXQgZG9lcyBub3QgcmVtb3ZlLCB0aGUgaGVhZCBvZiB0aGUgcXVldWUgcmVwcmVzZW50ZWQgYnkKKyAgICAgKiB0aGlzIGRlcXVlIChpbiBvdGhlciB3b3JkcywgdGhlIGZpcnN0IGVsZW1lbnQgb2YgdGhpcyBkZXF1ZSksIG9yCisgICAgICogcmV0dXJucyA8dHQ+bnVsbDwvdHQ+IGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAbGluayAjcGVla0ZpcnN0KCl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGUgcXVldWUgcmVwcmVzZW50ZWQgYnkgdGhpcyBkZXF1ZSwgb3IKKyAgICAgKiAgICAgICAgIDx0dD5udWxsPC90dD4gaWYgdGhpcyBkZXF1ZSBpcyBlbXB0eQorICAgICAqLworICAgIEUgcGVlaygpOworCisKKyAgICAvLyAqKiogU3RhY2sgbWV0aG9kcyAqKioKKworICAgIC8qKgorICAgICAqIFB1c2hlcyBhbiBlbGVtZW50IG9udG8gdGhlIHN0YWNrIHJlcHJlc2VudGVkIGJ5IHRoaXMgZGVxdWUgKGluIG90aGVyCisgICAgICogd29yZHMsIGF0IHRoZSBoZWFkIG9mIHRoaXMgZGVxdWUpIGlmIGl0IGlzIHBvc3NpYmxlIHRvIGRvIHNvCisgICAgICogaW1tZWRpYXRlbHkgd2l0aG91dCB2aW9sYXRpbmcgY2FwYWNpdHkgcmVzdHJpY3Rpb25zLCByZXR1cm5pbmcKKyAgICAgKiA8dHQ+dHJ1ZTwvdHQ+IHVwb24gc3VjY2VzcyBhbmQgdGhyb3dpbmcgYW4KKyAgICAgKiA8dHQ+SWxsZWdhbFN0YXRlRXhjZXB0aW9uPC90dD4gaWYgbm8gc3BhY2UgaXMgY3VycmVudGx5IGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8ge0BsaW5rICNhZGRGaXJzdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byBwdXNoCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlIGVsZW1lbnQgY2Fubm90IGJlIGFkZGVkIGF0IHRoaXMKKyAgICAgKiAgICAgICAgIHRpbWUgZHVlIHRvIGNhcGFjaXR5IHJlc3RyaWN0aW9ucworICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKiAgICAgICAgIHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBkZXF1ZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwgYW5kIHRoaXMKKyAgICAgKiAgICAgICAgIGRlcXVlIGRvZXMgbm90IHBlcm1pdCBudWxsIGVsZW1lbnRzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc29tZSBwcm9wZXJ0eSBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBlbGVtZW50IHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBkZXF1ZQorICAgICAqLworICAgIHZvaWQgcHVzaChFIGUpOworCisgICAgLyoqCisgICAgICogUG9wcyBhbiBlbGVtZW50IGZyb20gdGhlIHN0YWNrIHJlcHJlc2VudGVkIGJ5IHRoaXMgZGVxdWUuICBJbiBvdGhlcgorICAgICAqIHdvcmRzLCByZW1vdmVzIGFuZCByZXR1cm5zIHRoZSBmaXJzdCBlbGVtZW50IG9mIHRoaXMgZGVxdWUuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAbGluayAjcmVtb3ZlRmlyc3QoKX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBlbGVtZW50IGF0IHRoZSBmcm9udCBvZiB0aGlzIGRlcXVlICh3aGljaCBpcyB0aGUgdG9wCisgICAgICogICAgICAgICBvZiB0aGUgc3RhY2sgcmVwcmVzZW50ZWQgYnkgdGhpcyBkZXF1ZSkKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gaWYgdGhpcyBkZXF1ZSBpcyBlbXB0eQorICAgICAqLworICAgIEUgcG9wKCk7CisKKworICAgIC8vICoqKiBDb2xsZWN0aW9uIG1ldGhvZHMgKioqCisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBmcm9tIHRoaXMgZGVxdWUuCisgICAgICogSWYgdGhlIGRlcXVlIGRvZXMgbm90IGNvbnRhaW4gdGhlIGVsZW1lbnQsIGl0IGlzIHVuY2hhbmdlZC4KKyAgICAgKiBNb3JlIGZvcm1hbGx5LCByZW1vdmVzIHRoZSBmaXJzdCBlbGVtZW50IDx0dD5lPC90dD4gc3VjaCB0aGF0CisgICAgICogPHR0PihvPT1udWxsJm5ic3A7PyZuYnNwO2U9PW51bGwmbmJzcDs6Jm5ic3A7by5lcXVhbHMoZSkpPC90dD4KKyAgICAgKiAoaWYgc3VjaCBhbiBlbGVtZW50IGV4aXN0cykuCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgZGVxdWUgY29udGFpbmVkIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqIChvciBlcXVpdmFsZW50bHksIGlmIHRoaXMgZGVxdWUgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbCkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAbGluayAjcmVtb3ZlRmlyc3RPY2N1cnJlbmNlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvIGVsZW1lbnQgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoaXMgZGVxdWUsIGlmIHByZXNlbnQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgYW4gZWxlbWVudCB3YXMgcmVtb3ZlZCBhcyBhIHJlc3VsdCBvZiB0aGlzIGNhbGwKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3Mgb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICogICAgICAgICBpcyBpbmNvbXBhdGlibGUgd2l0aCB0aGlzIGRlcXVlIChvcHRpb25hbCkKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsIGFuZCB0aGlzCisgICAgICogICAgICAgICBkZXF1ZSBkb2VzIG5vdCBwZXJtaXQgbnVsbCBlbGVtZW50cyAob3B0aW9uYWwpCisgICAgICovCisgICAgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG8pOworCisgICAgLyoqCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgZGVxdWUgY29udGFpbnMgdGhlIHNwZWNpZmllZCBlbGVtZW50LgorICAgICAqIE1vcmUgZm9ybWFsbHksIHJldHVybnMgPHR0PnRydWU8L3R0PiBpZiBhbmQgb25seSBpZiB0aGlzIGRlcXVlIGNvbnRhaW5zCisgICAgICogYXQgbGVhc3Qgb25lIGVsZW1lbnQgPHR0PmU8L3R0PiBzdWNoIHRoYXQKKyAgICAgKiA8dHQ+KG89PW51bGwmbmJzcDs/Jm5ic3A7ZT09bnVsbCZuYnNwOzombmJzcDtvLmVxdWFscyhlKSk8L3R0Pi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvIGVsZW1lbnQgd2hvc2UgcHJlc2VuY2UgaW4gdGhpcyBkZXF1ZSBpcyB0byBiZSB0ZXN0ZWQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBkZXF1ZSBjb250YWlucyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgdHlwZSBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKiAgICAgICAgIGlzIGluY29tcGF0aWJsZSB3aXRoIHRoaXMgZGVxdWUgKG9wdGlvbmFsKQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwgYW5kIHRoaXMKKyAgICAgKiAgICAgICAgIGRlcXVlIGRvZXMgbm90IHBlcm1pdCBudWxsIGVsZW1lbnRzIChvcHRpb25hbCkKKyAgICAgKi8KKyAgICBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIGRlcXVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgZGVxdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNpemUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMgaW4gdGhpcyBkZXF1ZSBpbiBwcm9wZXIgc2VxdWVuY2UuCisgICAgICogVGhlIGVsZW1lbnRzIHdpbGwgYmUgcmV0dXJuZWQgaW4gb3JkZXIgZnJvbSBmaXJzdCAoaGVhZCkgdG8gbGFzdCAodGFpbCkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzIGluIHRoaXMgZGVxdWUgaW4gcHJvcGVyIHNlcXVlbmNlCisgICAgICovCisgICAgSXRlcmF0b3I8RT4gaXRlcmF0b3IoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMgaW4gdGhpcyBkZXF1ZSBpbiByZXZlcnNlCisgICAgICogc2VxdWVudGlhbCBvcmRlci4gIFRoZSBlbGVtZW50cyB3aWxsIGJlIHJldHVybmVkIGluIG9yZGVyIGZyb20KKyAgICAgKiBsYXN0ICh0YWlsKSB0byBmaXJzdCAoaGVhZCkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzIGluIHRoaXMgZGVxdWUgaW4gcmV2ZXJzZQorICAgICAqIHNlcXVlbmNlCisgICAgICovCisgICAgSXRlcmF0b3I8RT4gZGVzY2VuZGluZ0l0ZXJhdG9yKCk7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRGljdGlvbmFyeS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9EaWN0aW9uYXJ5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODE4MmIyYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRGljdGlvbmFyeS5qYXZhCkBAIC0wLDAgKzEsMTE1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworLyoqCisgKiA8c3Ryb25nPk5vdGU6IERvIG5vdCB1c2UgdGhpcyBjbGFzcyBzaW5jZSBpdCBpcyBvYnNvbGV0ZS4gUGxlYXNlIHVzZSB0aGUKKyAqIHtAbGluayBNYXB9IGludGVyZmFjZSBmb3IgbmV3IGltcGxlbWVudGF0aW9ucy48L3N0cm9uZz4KKyAqIDxwPgorICogRGljdGlvbmFyeSBpcyBhbiBhYnN0cmFjdCBjbGFzcyB3aGljaCBpcyB0aGUgc3VwZXJjbGFzcyBvZiBhbGwgY2xhc3NlcyB0aGF0CisgKiBhc3NvY2lhdGUga2V5cyB3aXRoIHZhbHVlcywgc3VjaCBhcyB7QGNvZGUgSGFzaHRhYmxlfS4KKyAqCisgKiBAc2VlIEhhc2h0YWJsZQorICogQHNpbmNlIDEuMAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRGljdGlvbmFyeTxLLCBWPiB7CisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBEaWN0aW9uYXJ5KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gZW51bWVyYXRpb24gb24gdGhlIGVsZW1lbnRzIG9mIHRoaXMgZGljdGlvbmFyeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gZW51bWVyYXRpb24gb2YgdGhlIHZhbHVlcyBvZiB0aGlzIGRpY3Rpb25hcnkuCisgICAgICogQHNlZSAja2V5cworICAgICAqIEBzZWUgI3NpemUKKyAgICAgKiBAc2VlIEVudW1lcmF0aW9uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEVudW1lcmF0aW9uPFY+IGVsZW1lbnRzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSB3aGljaCBpcyBhc3NvY2lhdGVkIHdpdGgge0Bjb2RlIGtleX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IG9mIHRoZSB2YWx1ZSByZXR1cm5lZC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGgge0Bjb2RlIGtleX0sIG9yIHtAY29kZSBudWxsfSBpZiB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBrZXkgZG9lcyBub3QgZXhpc3QuCisgICAgICogQHNlZSAjcHV0CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFYgZ2V0KE9iamVjdCBrZXkpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgZGljdGlvbmFyeSBoYXMgbm8ga2V5L3ZhbHVlIHBhaXJzLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBkaWN0aW9uYXJ5IGhhcyBubyBrZXkvdmFsdWUgcGFpcnMsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNzaXplCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNFbXB0eSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBlbnVtZXJhdGlvbiBvbiB0aGUga2V5cyBvZiB0aGlzIGRpY3Rpb25hcnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGVudW1lcmF0aW9uIG9mIHRoZSBrZXlzIG9mIHRoaXMgZGljdGlvbmFyeS4KKyAgICAgKiBAc2VlICNlbGVtZW50cworICAgICAqIEBzZWUgI3NpemUKKyAgICAgKiBAc2VlIEVudW1lcmF0aW9uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEVudW1lcmF0aW9uPEs+IGtleXMoKTsKKworICAgIC8qKgorICAgICAqIEFzc29jaWF0ZSB7QGNvZGUga2V5fSB3aXRoIHtAY29kZSB2YWx1ZX0gaW4gdGhpcyBkaWN0aW9uYXJ5LiBJZiB7QGNvZGUKKyAgICAgKiBrZXl9IGV4aXN0cyBpbiB0aGUgZGljdGlvbmFyeSBiZWZvcmUgdGhpcyBjYWxsLCB0aGUgb2xkIHZhbHVlIGluIHRoZQorICAgICAqIGRpY3Rpb25hcnkgaXMgcmVwbGFjZWQgYnkge0Bjb2RlIHZhbHVlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgdG8gYWRkLgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIGFkZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBvbGQgdmFsdWUgcHJldmlvdXNseSBhc3NvY2lhdGVkIHdpdGgge0Bjb2RlIGtleX0gb3Ige0Bjb2RlCisgICAgICogICAgICAgICBudWxsfSBpZiB7QGNvZGUga2V5fSBpcyBuZXcgdG8gdGhlIGRpY3Rpb25hcnkuCisgICAgICogQHNlZSAjZWxlbWVudHMKKyAgICAgKiBAc2VlICNnZXQKKyAgICAgKiBAc2VlICNrZXlzCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFYgcHV0KEsga2V5LCBWIHZhbHVlKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGtleS92YWx1ZSBwYWlyIHdpdGggdGhlIHNwZWNpZmllZCB7QGNvZGUga2V5fSBmcm9tIHRoaXMKKyAgICAgKiBkaWN0aW9uYXJ5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byByZW1vdmUuCisgICAgICogQHJldHVybiB0aGUgYXNzb2NpYXRlZCB2YWx1ZSBiZWZvcmUgdGhlIGRlbGV0aW9uIG9yIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAge0Bjb2RlIGtleX0gd2FzIG5vdCBrbm93biB0byB0aGlzIGRpY3Rpb25hcnkuCisgICAgICogQHNlZSAjZ2V0CisgICAgICogQHNlZSAjcHV0CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFYgcmVtb3ZlKE9iamVjdCBrZXkpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGtleS92YWx1ZSBwYWlycyBpbiB0aGlzIGRpY3Rpb25hcnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2Yga2V5L3ZhbHVlIHBhaXJzIGluIHRoaXMgZGljdGlvbmFyeS4KKyAgICAgKiBAc2VlICNlbGVtZW50cworICAgICAqIEBzZWUgI2tleXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IHNpemUoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRHVhbFBpdm90UXVpY2tzb3J0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0R1YWxQaXZvdFF1aWNrc29ydC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk3Nzk3ZDEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0R1YWxQaXZvdFF1aWNrc29ydC5qYXZhCkBAIC0wLDAgKzEsMjI1MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgRHVhbC1QaXZvdCBRdWlja3NvcnQgYWxnb3JpdGhtIGJ5CisgKiBWbGFkaW1pciBZYXJvc2xhdnNraXksIEpvbiBCZW50bGV5LCBhbmQgSm9zaHVhIEJsb2NoLiBUaGUgYWxnb3JpdGhtCisgKiBvZmZlcnMgTyhuIGxvZyhuKSkgcGVyZm9ybWFuY2Ugb24gbWFueSBkYXRhIHNldHMgdGhhdCBjYXVzZSBvdGhlcgorICogcXVpY2tzb3J0cyB0byBkZWdyYWRlIHRvIHF1YWRyYXRpYyBwZXJmb3JtYW5jZSwgYW5kIGlzIHR5cGljYWxseQorICogZmFzdGVyIHRoYW4gdHJhZGl0aW9uYWwgKG9uZS1waXZvdCkgUXVpY2tzb3J0IGltcGxlbWVudGF0aW9ucy4KKyAqCisgKiBAYXV0aG9yIFZsYWRpbWlyIFlhcm9zbGF2c2tpeQorICogQGF1dGhvciBKb24gQmVudGxleQorICogQGF1dGhvciBKb3NoIEJsb2NoCisgKgorICogQHZlcnNpb24gMjAwOS4xMS4yOSBtNzY1LjgyNy4xMmkKKyAqLworZmluYWwgY2xhc3MgRHVhbFBpdm90UXVpY2tzb3J0IHsKKworICAgIC8qKgorICAgICAqIFByZXZlbnRzIGluc3RhbnRpYXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBEdWFsUGl2b3RRdWlja3NvcnQoKSB7fQorCisgICAgLyoKKyAgICAgKiBUdW5pbmcgcGFyYW1ldGVycy4KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIElmIHRoZSBsZW5ndGggb2YgYW4gYXJyYXkgdG8gYmUgc29ydGVkIGlzIGxlc3MgdGhhbiB0aGlzCisgICAgICogY29uc3RhbnQsIGluc2VydGlvbiBzb3J0IGlzIHVzZWQgaW4gcHJlZmVyZW5jZSB0byBRdWlja3NvcnQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOU0VSVElPTl9TT1JUX1RIUkVTSE9MRCA9IDMyOworCisgICAgLyoqCisgICAgICogSWYgdGhlIGxlbmd0aCBvZiBhIGJ5dGUgYXJyYXkgdG8gYmUgc29ydGVkIGlzIGdyZWF0ZXIgdGhhbgorICAgICAqIHRoaXMgY29uc3RhbnQsIGNvdW50aW5nIHNvcnQgaXMgdXNlZCBpbiBwcmVmZXJlbmNlIHRvIFF1aWNrc29ydC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09VTlRJTkdfU09SVF9USFJFU0hPTERfRk9SX0JZVEUgPSAxMjg7CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgbGVuZ3RoIG9mIGEgc2hvcnQgb3IgY2hhciBhcnJheSB0byBiZSBzb3J0ZWQgaXMgZ3JlYXRlcgorICAgICAqIHRoYW4gdGhpcyBjb25zdGFudCwgY291bnRpbmcgc29ydCBpcyB1c2VkIGluIHByZWZlcmVuY2UgdG8gUXVpY2tzb3J0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDT1VOVElOR19TT1JUX1RIUkVTSE9MRF9GT1JfU0hPUlRfT1JfQ0hBUiA9IDMyNzY4OworCisgICAgLyoKKyAgICAgKiBTb3J0aW5nIG1ldGhvZHMgZm9yIDcgcHJpbWl0aXZlIHR5cGVzLgorICAgICAqLworCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCBhcnJheSBpbnRvIGFzY2VuZGluZyBudW1lcmljYWwgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc29ydGVkCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNvcnQoaW50W10gYSkgeworICAgICAgICBkb1NvcnQoYSwgMCwgYS5sZW5ndGggLSAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIHRoZSBhcnJheSBpbnRvIGFzY2VuZGluZyBvcmRlci4gVGhlIHJhbmdlCisgICAgICogdG8gYmUgc29ydGVkIGV4dGVuZHMgZnJvbSB0aGUgaW5kZXgge0Bjb2RlIGZyb21JbmRleH0sIGluY2x1c2l2ZSwgdG8KKyAgICAgKiB0aGUgaW5kZXgge0Bjb2RlIHRvSW5kZXh9LCBleGNsdXNpdmUuIElmIHtAY29kZSBmcm9tSW5kZXggPT0gdG9JbmRleH0sCisgICAgICogdGhlIHJhbmdlIHRvIGJlIHNvcnRlZCBpcyBlbXB0eSAoYW5kIHRoZSBjYWxsIGlzIGEgbm8tb3ApLgorICAgICAqCisgICAgICogQHBhcmFtIGEgdGhlIGFycmF5IHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSBmcm9tSW5kZXggdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSB0b0luZGV4IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBlbGVtZW50LCBleGNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBmcm9tSW5kZXggPiB0b0luZGV4fQorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgIGlmIHtAY29kZSBmcm9tSW5kZXggPCAwfSBvciB7QGNvZGUgdG9JbmRleCA+IGEubGVuZ3RofQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzb3J0KGludFtdIGEsIGludCBmcm9tSW5kZXgsIGludCB0b0luZGV4KSB7CisgICAgICAgIEFycmF5cy5jaGVja1N0YXJ0QW5kRW5kKGEubGVuZ3RoLCBmcm9tSW5kZXgsIHRvSW5kZXgpOworICAgICAgICBkb1NvcnQoYSwgZnJvbUluZGV4LCB0b0luZGV4IC0gMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCByYW5nZSBvZiB0aGUgYXJyYXkgaW50byBhc2NlbmRpbmcgb3JkZXIuIFRoaXMKKyAgICAgKiBtZXRob2QgZGlmZmVycyBmcm9tIHRoZSBwdWJsaWMge0Bjb2RlIHNvcnR9IG1ldGhvZCBpbiB0aGF0IHRoZQorICAgICAqIHtAY29kZSByaWdodH0gaW5kZXggaXMgaW5jbHVzaXZlLCBhbmQgaXQgZG9lcyBubyByYW5nZSBjaGVja2luZworICAgICAqIG9uIHtAY29kZSBsZWZ0fSBvciB7QGNvZGUgcmlnaHR9LgorICAgICAqCisgICAgICogQHBhcmFtIGEgdGhlIGFycmF5IHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSBsZWZ0IHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgZWxlbWVudCwgaW5jbHVzaXZlLCB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gcmlnaHQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IGVsZW1lbnQsIGluY2x1c2l2ZSwgdG8gYmUgc29ydGVkCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBkb1NvcnQoaW50W10gYSwgaW50IGxlZnQsIGludCByaWdodCkgeworICAgICAgICAvLyBVc2UgaW5zZXJ0aW9uIHNvcnQgb24gdGlueSBhcnJheXMKKyAgICAgICAgaWYgKHJpZ2h0IC0gbGVmdCArIDEgPCBJTlNFUlRJT05fU09SVF9USFJFU0hPTEQpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBsZWZ0ICsgMTsgaSA8PSByaWdodDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaW50IGFpID0gYVtpXTsKKyAgICAgICAgICAgICAgICBpbnQgajsKKyAgICAgICAgICAgICAgICBmb3IgKGogPSBpIC0gMTsgaiA+PSBsZWZ0ICYmIGFpIDwgYVtqXTsgai0tKSB7CisgICAgICAgICAgICAgICAgICAgIGFbaiArIDFdID0gYVtqXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYVtqICsgMV0gPSBhaTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsgLy8gVXNlIER1YWwtUGl2b3QgUXVpY2tzb3J0IG9uIGxhcmdlIGFycmF5cworICAgICAgICAgICAgZHVhbFBpdm90UXVpY2tzb3J0KGEsIGxlZnQsIHJpZ2h0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhlIGFycmF5IGludG8gYXNjZW5kaW5nIG9yZGVyIGJ5IHRoZQorICAgICAqIER1YWwtUGl2b3QgUXVpY2tzb3J0IGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gbGVmdCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQsIGluY2x1c2l2ZSwgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIHJpZ2h0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZHVhbFBpdm90UXVpY2tzb3J0KGludFtdIGEsIGludCBsZWZ0LCBpbnQgcmlnaHQpIHsKKyAgICAgICAgLy8gQ29tcHV0ZSBpbmRpY2VzIG9mIGZpdmUgZXZlbmx5IHNwYWNlZCBlbGVtZW50cworICAgICAgICBpbnQgc2l4dGggPSAocmlnaHQgLSBsZWZ0ICsgMSkgLyA2OworICAgICAgICBpbnQgZTEgPSBsZWZ0ICArIHNpeHRoOworICAgICAgICBpbnQgZTUgPSByaWdodCAtIHNpeHRoOworICAgICAgICBpbnQgZTMgPSAobGVmdCArIHJpZ2h0KSA+Pj4gMTsgLy8gVGhlIG1pZHBvaW50CisgICAgICAgIGludCBlNCA9IGUzICsgc2l4dGg7CisgICAgICAgIGludCBlMiA9IGUzIC0gc2l4dGg7CisKKyAgICAgICAgLy8gU29ydCB0aGVzZSBlbGVtZW50cyB1c2luZyBhIDUtZWxlbWVudCBzb3J0aW5nIG5ldHdvcmsKKyAgICAgICAgaW50IGFlMSA9IGFbZTFdLCBhZTIgPSBhW2UyXSwgYWUzID0gYVtlM10sIGFlNCA9IGFbZTRdLCBhZTUgPSBhW2U1XTsKKworICAgICAgICBpZiAoYWUxID4gYWUyKSB7IGludCB0ID0gYWUxOyBhZTEgPSBhZTI7IGFlMiA9IHQ7IH0KKyAgICAgICAgaWYgKGFlNCA+IGFlNSkgeyBpbnQgdCA9IGFlNDsgYWU0ID0gYWU1OyBhZTUgPSB0OyB9CisgICAgICAgIGlmIChhZTEgPiBhZTMpIHsgaW50IHQgPSBhZTE7IGFlMSA9IGFlMzsgYWUzID0gdDsgfQorICAgICAgICBpZiAoYWUyID4gYWUzKSB7IGludCB0ID0gYWUyOyBhZTIgPSBhZTM7IGFlMyA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMSA+IGFlNCkgeyBpbnQgdCA9IGFlMTsgYWUxID0gYWU0OyBhZTQgPSB0OyB9CisgICAgICAgIGlmIChhZTMgPiBhZTQpIHsgaW50IHQgPSBhZTM7IGFlMyA9IGFlNDsgYWU0ID0gdDsgfQorICAgICAgICBpZiAoYWUyID4gYWU1KSB7IGludCB0ID0gYWUyOyBhZTIgPSBhZTU7IGFlNSA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMiA+IGFlMykgeyBpbnQgdCA9IGFlMjsgYWUyID0gYWUzOyBhZTMgPSB0OyB9CisgICAgICAgIGlmIChhZTQgPiBhZTUpIHsgaW50IHQgPSBhZTQ7IGFlNCA9IGFlNTsgYWU1ID0gdDsgfQorCisgICAgICAgIGFbZTFdID0gYWUxOyBhW2UzXSA9IGFlMzsgYVtlNV0gPSBhZTU7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVXNlIHRoZSBzZWNvbmQgYW5kIGZvdXJ0aCBvZiB0aGUgZml2ZSBzb3J0ZWQgZWxlbWVudHMgYXMgcGl2b3RzLgorICAgICAgICAgKiBUaGVzZSB2YWx1ZXMgYXJlIGluZXhwZW5zaXZlIGFwcHJveGltYXRpb25zIG9mIHRoZSBmaXJzdCBhbmQKKyAgICAgICAgICogc2Vjb25kIHRlcmNpbGVzIG9mIHRoZSBhcnJheS4gTm90ZSB0aGF0IHBpdm90MSA8PSBwaXZvdDIuCisgICAgICAgICAqCisgICAgICAgICAqIFRoZSBwaXZvdHMgYXJlIHN0b3JlZCBpbiBsb2NhbCB2YXJpYWJsZXMsIGFuZCB0aGUgZmlyc3QgYW5kCisgICAgICAgICAqIHRoZSBsYXN0IG9mIHRoZSBlbGVtZW50cyB0byBiZSBzb3J0ZWQgYXJlIG1vdmVkIHRvIHRoZSBsb2NhdGlvbnMKKyAgICAgICAgICogZm9ybWVybHkgb2NjdXBpZWQgYnkgdGhlIHBpdm90cy4gV2hlbiBwYXJ0aXRpb25pbmcgaXMgY29tcGxldGUsCisgICAgICAgICAqIHRoZSBwaXZvdHMgYXJlIHN3YXBwZWQgYmFjayBpbnRvIHRoZWlyIGZpbmFsIHBvc2l0aW9ucywgYW5kCisgICAgICAgICAqIGV4Y2x1ZGVkIGZyb20gc3Vic2VxdWVudCBzb3J0aW5nLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IHBpdm90MSA9IGFlMjsgYVtlMl0gPSBhW2xlZnRdOworICAgICAgICBpbnQgcGl2b3QyID0gYWU0OyBhW2U0XSA9IGFbcmlnaHRdOworCisgICAgICAgIC8vIFBvaW50ZXJzCisgICAgICAgIGludCBsZXNzICA9IGxlZnQgICsgMTsgLy8gVGhlIGluZGV4IG9mIGZpcnN0IGVsZW1lbnQgb2YgY2VudGVyIHBhcnQKKyAgICAgICAgaW50IGdyZWF0ID0gcmlnaHQgLSAxOyAvLyBUaGUgaW5kZXggYmVmb3JlIGZpcnN0IGVsZW1lbnQgb2YgcmlnaHQgcGFydAorCisgICAgICAgIGJvb2xlYW4gcGl2b3RzRGlmZmVyID0gKHBpdm90MSAhPSBwaXZvdDIpOworCisgICAgICAgIGlmIChwaXZvdHNEaWZmZXIpIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBQYXJ0aXRpb25pbmc6CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogICBsZWZ0IHBhcnQgICAgICAgICBjZW50ZXIgcGFydCAgICAgICAgICAgICAgICAgICAgcmlnaHQgcGFydAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqIHwgPCBwaXZvdDEgIHwgIHBpdm90MSA8PSAmJiA8PSBwaXZvdDIgIHwgICAgPyAgICB8ICA+IHBpdm90MiB8CisgICAgICAgICAgICAgKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKworICAgICAgICAgICAgICogICAgICAgICAgICAgIF4gICAgICAgICAgICAgICAgICAgICAgICAgIF4gICAgICAgXgorICAgICAgICAgICAgICogICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgfAorICAgICAgICAgICAgICogICAgICAgICAgICAgbGVzcyAgICAgICAgICAgICAgICAgICAgICAgIGsgICAgIGdyZWF0CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogSW52YXJpYW50czoKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgYWxsIGluIChsZWZ0LCBsZXNzKSAgIDwgcGl2b3QxCisgICAgICAgICAgICAgKiAgICBwaXZvdDEgPD0gYWxsIGluIFtsZXNzLCBrKSAgICAgPD0gcGl2b3QyCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgYWxsIGluIChncmVhdCwgcmlnaHQpID4gcGl2b3QyCisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogUG9pbnRlciBrIGlzIHRoZSBmaXJzdCBpbmRleCBvZiA/LXBhcnQKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgb3V0ZXI6CisgICAgICAgICAgICBmb3IgKGludCBrID0gbGVzczsgayA8PSBncmVhdDsgaysrKSB7CisgICAgICAgICAgICAgICAgaW50IGFrID0gYVtrXTsKKyAgICAgICAgICAgICAgICBpZiAoYWsgPCBwaXZvdDEpIHsgLy8gTW92ZSBhW2tdIHRvIGxlZnQgcGFydAorICAgICAgICAgICAgICAgICAgICBpZiAoayAhPSBsZXNzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtsZXNzXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbbGVzc10gPSBhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBsZXNzKys7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhayA+IHBpdm90MikgeyAvLyBNb3ZlIGFba10gdG8gcmlnaHQgcGFydAorICAgICAgICAgICAgICAgICAgICB3aGlsZSAoYVtncmVhdF0gPiBwaXZvdDIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChncmVhdC0tID09IGspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoYVtncmVhdF0gPCBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2xlc3NdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtsZXNzKytdID0gYVtncmVhdF07CisgICAgICAgICAgICAgICAgICAgICAgICBhW2dyZWF0LS1dID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIHBpdm90MSA8PSBhW2dyZWF0XSA8PSBwaXZvdDIKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2dyZWF0XTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbZ3JlYXQtLV0gPSBhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsgLy8gUGl2b3RzIGFyZSBlcXVhbAorICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFBhcnRpdGlvbiBkZWdlbmVyYXRlcyB0byB0aGUgdHJhZGl0aW9uYWwgMy13YXksCisgICAgICAgICAgICAgKiBvciAiRHV0Y2ggTmF0aW9uYWwgRmxhZyIsIHBhcnRpdGlvbjoKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiAgIGxlZnQgcGFydCAgIGNlbnRlciBwYXJ0ICAgICAgICAgICAgcmlnaHQgcGFydAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCisgICAgICAgICAgICAgKiB8ICA8IHBpdm90ICB8ICA9PSBwaXZvdCAgfCAgICA/ICAgIHwgID4gcGl2b3QgIHwKKyAgICAgICAgICAgICAqICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKworICAgICAgICAgICAgICogICAgICAgICAgICAgIF4gICAgICAgICAgICBeICAgICAgIF4KKyAgICAgICAgICAgICAqICAgICAgICAgICAgICB8ICAgICAgICAgICAgfCAgICAgICB8CisgICAgICAgICAgICAgKiAgICAgICAgICAgICBsZXNzICAgICAgICAgIGsgICAgIGdyZWF0CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogSW52YXJpYW50czoKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiAgIGFsbCBpbiAobGVmdCwgbGVzcykgICA8IHBpdm90CisgICAgICAgICAgICAgKiAgIGFsbCBpbiBbbGVzcywgaykgICAgID09IHBpdm90CisgICAgICAgICAgICAgKiAgIGFsbCBpbiAoZ3JlYXQsIHJpZ2h0KSA+IHBpdm90CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogUG9pbnRlciBrIGlzIHRoZSBmaXJzdCBpbmRleCBvZiA/LXBhcnQKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgZm9yIChpbnQgayA9IGxlc3M7IGsgPD0gZ3JlYXQ7IGsrKykgeworICAgICAgICAgICAgICAgIGludCBhayA9IGFba107CisgICAgICAgICAgICAgICAgaWYgKGFrID09IHBpdm90MSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGFrIDwgcGl2b3QxKSB7IC8vIE1vdmUgYVtrXSB0byBsZWZ0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgaWYgKGsgIT0gbGVzcykgeworICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbbGVzc107CisgICAgICAgICAgICAgICAgICAgICAgICBhW2xlc3NdID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgbGVzcysrOworICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIChhW2tdID4gcGl2b3QxKSAtICBNb3ZlIGFba10gdG8gcmlnaHQgcGFydAorICAgICAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAgICAgKiBXZSBrbm93IHRoYXQgcGl2b3QxID09IGFbZTNdID09IHBpdm90Mi4gVGh1cywgd2Uga25vdworICAgICAgICAgICAgICAgICAgICAgKiB0aGF0IGdyZWF0IHdpbGwgc3RpbGwgYmUgPj0gayB3aGVuIHRoZSBmb2xsb3dpbmcgbG9vcAorICAgICAgICAgICAgICAgICAgICAgKiB0ZXJtaW5hdGVzLCBldmVuIHRob3VnaCB3ZSBkb24ndCB0ZXN0IGZvciBpdCBleHBsaWNpdGx5LgorICAgICAgICAgICAgICAgICAgICAgKiBJbiBvdGhlciB3b3JkcywgYVtlM10gYWN0cyBhcyBhIHNlbnRpbmVsIGZvciBncmVhdC4KKyAgICAgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChhW2dyZWF0XSA+IHBpdm90MSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZ3JlYXQtLTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoYVtncmVhdF0gPCBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2xlc3NdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtsZXNzKytdID0gYVtncmVhdF07CisgICAgICAgICAgICAgICAgICAgICAgICBhW2dyZWF0LS1dID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIGFbZ3JlYXRdID09IHBpdm90MQorICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IHBpdm90MTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbZ3JlYXQtLV0gPSBhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFN3YXAgcGl2b3RzIGludG8gdGhlaXIgZmluYWwgcG9zaXRpb25zCisgICAgICAgIGFbbGVmdF0gID0gYVtsZXNzICAtIDFdOyBhW2xlc3MgIC0gMV0gPSBwaXZvdDE7CisgICAgICAgIGFbcmlnaHRdID0gYVtncmVhdCArIDFdOyBhW2dyZWF0ICsgMV0gPSBwaXZvdDI7CisKKyAgICAgICAgLy8gU29ydCBsZWZ0IGFuZCByaWdodCBwYXJ0cyByZWN1cnNpdmVseSwgZXhjbHVkaW5nIGtub3duIHBpdm90IHZhbHVlcworICAgICAgICBkb1NvcnQoYSwgbGVmdCwgICBsZXNzIC0gMik7CisgICAgICAgIGRvU29ydChhLCBncmVhdCArIDIsIHJpZ2h0KTsKKworICAgICAgICAvKgorICAgICAgICAgKiBJZiBwaXZvdDEgPT0gcGl2b3QyLCBhbGwgZWxlbWVudHMgZnJvbSBjZW50ZXIKKyAgICAgICAgICogcGFydCBhcmUgZXF1YWwgYW5kLCB0aGVyZWZvcmUsIGFscmVhZHkgc29ydGVkCisgICAgICAgICAqLworICAgICAgICBpZiAoIXBpdm90c0RpZmZlcikgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogSWYgY2VudGVyIHBhcnQgaXMgdG9vIGxhcmdlIChjb21wcmlzZXMgPiAyLzMgb2YgdGhlIGFycmF5KSwKKyAgICAgICAgICogc3dhcCBpbnRlcm5hbCBwaXZvdCB2YWx1ZXMgdG8gZW5kcworICAgICAgICAgKi8KKyAgICAgICAgaWYgKGxlc3MgPCBlMSAmJiBncmVhdCA+IGU1KSB7CisgICAgICAgICAgICB3aGlsZSAoYVtsZXNzXSA9PSBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICBsZXNzKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB3aGlsZSAoYVtncmVhdF0gPT0gcGl2b3QyKSB7CisgICAgICAgICAgICAgICAgZ3JlYXQtLTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFBhcnRpdGlvbmluZzoKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiAgIGxlZnQgcGFydCAgICAgICBjZW50ZXIgcGFydCAgICAgICAgICAgICAgICAgICByaWdodCBwYXJ0CisgICAgICAgICAgICAgKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqIHwgPT0gcGl2b3QxIHwgIHBpdm90MSA8ICYmIDwgcGl2b3QyICB8ICAgID8gICAgfCA9PSBwaXZvdDIgfAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgXiAgICAgICAgICAgICAgICAgICAgICAgIF4gICAgICAgXgorICAgICAgICAgICAgICogICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgIHwKKyAgICAgICAgICAgICAqICAgICAgICAgICAgIGxlc3MgICAgICAgICAgICAgICAgICAgICAgayAgICAgZ3JlYXQKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBJbnZhcmlhbnRzOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBhbGwgaW4gKCosIGxlc3MpICA9PSBwaXZvdDEKKyAgICAgICAgICAgICAqICAgICBwaXZvdDEgPCBhbGwgaW4gW2xlc3MsIGspICAgPCBwaXZvdDIKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBhbGwgaW4gKGdyZWF0LCAqKSA9PSBwaXZvdDIKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBQb2ludGVyIGsgaXMgdGhlIGZpcnN0IGluZGV4IG9mID8tcGFydAorICAgICAgICAgICAgICovCisgICAgICAgICAgICBvdXRlcjoKKyAgICAgICAgICAgIGZvciAoaW50IGsgPSBsZXNzOyBrIDw9IGdyZWF0OyBrKyspIHsKKyAgICAgICAgICAgICAgICBpbnQgYWsgPSBhW2tdOworICAgICAgICAgICAgICAgIGlmIChhayA9PSBwaXZvdDIpIHsgLy8gTW92ZSBhW2tdIHRvIHJpZ2h0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGFbZ3JlYXRdID09IHBpdm90MikgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdyZWF0LS0gPT0gaykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChhW2dyZWF0XSA9PSBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2xlc3NdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtsZXNzKytdID0gcGl2b3QxOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBwaXZvdDEgPCBhW2dyZWF0XSA8IHBpdm90MgorICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbZ3JlYXRdOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGFbZ3JlYXQtLV0gPSBwaXZvdDI7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhayA9PSBwaXZvdDEpIHsgLy8gTW92ZSBhW2tdIHRvIGxlZnQgcGFydAorICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtsZXNzXTsKKyAgICAgICAgICAgICAgICAgICAgYVtsZXNzKytdID0gcGl2b3QxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFNvcnQgY2VudGVyIHBhcnQgcmVjdXJzaXZlbHksIGV4Y2x1ZGluZyBrbm93biBwaXZvdCB2YWx1ZXMKKyAgICAgICAgZG9Tb3J0KGEsIGxlc3MsIGdyZWF0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIGFycmF5IGludG8gYXNjZW5kaW5nIG51bWVyaWNhbCBvcmRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSB0byBiZSBzb3J0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc29ydChsb25nW10gYSkgeworICAgICAgICBkb1NvcnQoYSwgMCwgYS5sZW5ndGggLSAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIHRoZSBhcnJheSBpbnRvIGFzY2VuZGluZyBvcmRlci4gVGhlIHJhbmdlCisgICAgICogdG8gYmUgc29ydGVkIGV4dGVuZHMgZnJvbSB0aGUgaW5kZXgge0Bjb2RlIGZyb21JbmRleH0sIGluY2x1c2l2ZSwgdG8KKyAgICAgKiB0aGUgaW5kZXgge0Bjb2RlIHRvSW5kZXh9LCBleGNsdXNpdmUuIElmIHtAY29kZSBmcm9tSW5kZXggPT0gdG9JbmRleH0sCisgICAgICogdGhlIHJhbmdlIHRvIGJlIHNvcnRlZCBpcyBlbXB0eSAoYW5kIHRoZSBjYWxsIGlzIGEgbm8tb3ApLgorICAgICAqCisgICAgICogQHBhcmFtIGEgdGhlIGFycmF5IHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSBmcm9tSW5kZXggdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSB0b0luZGV4IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBlbGVtZW50LCBleGNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBmcm9tSW5kZXggPiB0b0luZGV4fQorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgIGlmIHtAY29kZSBmcm9tSW5kZXggPCAwfSBvciB7QGNvZGUgdG9JbmRleCA+IGEubGVuZ3RofQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzb3J0KGxvbmdbXSBhLCBpbnQgZnJvbUluZGV4LCBpbnQgdG9JbmRleCkgeworICAgICAgICBBcnJheXMuY2hlY2tTdGFydEFuZEVuZChhLmxlbmd0aCwgZnJvbUluZGV4LCB0b0luZGV4KTsKKyAgICAgICAgZG9Tb3J0KGEsIGZyb21JbmRleCwgdG9JbmRleCAtIDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhlIGFycmF5IGludG8gYXNjZW5kaW5nIG9yZGVyLiBUaGlzCisgICAgICogbWV0aG9kIGRpZmZlcnMgZnJvbSB0aGUgcHVibGljIHtAY29kZSBzb3J0fSBtZXRob2QgaW4gdGhhdCB0aGUKKyAgICAgKiB7QGNvZGUgcmlnaHR9IGluZGV4IGlzIGluY2x1c2l2ZSwgYW5kIGl0IGRvZXMgbm8gcmFuZ2UgY2hlY2tpbmcgb24KKyAgICAgKiB7QGNvZGUgbGVmdH0gb3Ige0Bjb2RlIHJpZ2h0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gbGVmdCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQsIGluY2x1c2l2ZSwgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIHJpZ2h0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZG9Tb3J0KGxvbmdbXSBhLCBpbnQgbGVmdCwgaW50IHJpZ2h0KSB7CisgICAgICAgIC8vIFVzZSBpbnNlcnRpb24gc29ydCBvbiB0aW55IGFycmF5cworICAgICAgICBpZiAocmlnaHQgLSBsZWZ0ICsgMSA8IElOU0VSVElPTl9TT1JUX1RIUkVTSE9MRCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IGxlZnQgKyAxOyBpIDw9IHJpZ2h0OyBpKyspIHsKKyAgICAgICAgICAgICAgICBsb25nIGFpID0gYVtpXTsKKyAgICAgICAgICAgICAgICBpbnQgajsKKyAgICAgICAgICAgICAgICBmb3IgKGogPSBpIC0gMTsgaiA+PSBsZWZ0ICYmIGFpIDwgYVtqXTsgai0tKSB7CisgICAgICAgICAgICAgICAgICAgIGFbaiArIDFdID0gYVtqXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYVtqICsgMV0gPSBhaTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsgLy8gVXNlIER1YWwtUGl2b3QgUXVpY2tzb3J0IG9uIGxhcmdlIGFycmF5cworICAgICAgICAgICAgZHVhbFBpdm90UXVpY2tzb3J0KGEsIGxlZnQsIHJpZ2h0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhlIGFycmF5IGludG8gYXNjZW5kaW5nIG9yZGVyIGJ5IHRoZQorICAgICAqIER1YWwtUGl2b3QgUXVpY2tzb3J0IGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gbGVmdCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQsIGluY2x1c2l2ZSwgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIHJpZ2h0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZHVhbFBpdm90UXVpY2tzb3J0KGxvbmdbXSBhLCBpbnQgbGVmdCwgaW50IHJpZ2h0KSB7CisgICAgICAgIC8vIENvbXB1dGUgaW5kaWNlcyBvZiBmaXZlIGV2ZW5seSBzcGFjZWQgZWxlbWVudHMKKyAgICAgICAgaW50IHNpeHRoID0gKHJpZ2h0IC0gbGVmdCArIDEpIC8gNjsKKyAgICAgICAgaW50IGUxID0gbGVmdCAgKyBzaXh0aDsKKyAgICAgICAgaW50IGU1ID0gcmlnaHQgLSBzaXh0aDsKKyAgICAgICAgaW50IGUzID0gKGxlZnQgKyByaWdodCkgPj4+IDE7IC8vIFRoZSBtaWRwb2ludAorICAgICAgICBpbnQgZTQgPSBlMyArIHNpeHRoOworICAgICAgICBpbnQgZTIgPSBlMyAtIHNpeHRoOworCisgICAgICAgIC8vIFNvcnQgdGhlc2UgZWxlbWVudHMgdXNpbmcgYSA1LWVsZW1lbnQgc29ydGluZyBuZXR3b3JrCisgICAgICAgIGxvbmcgYWUxID0gYVtlMV0sIGFlMiA9IGFbZTJdLCBhZTMgPSBhW2UzXSwgYWU0ID0gYVtlNF0sIGFlNSA9IGFbZTVdOworCisgICAgICAgIGlmIChhZTEgPiBhZTIpIHsgbG9uZyB0ID0gYWUxOyBhZTEgPSBhZTI7IGFlMiA9IHQ7IH0KKyAgICAgICAgaWYgKGFlNCA+IGFlNSkgeyBsb25nIHQgPSBhZTQ7IGFlNCA9IGFlNTsgYWU1ID0gdDsgfQorICAgICAgICBpZiAoYWUxID4gYWUzKSB7IGxvbmcgdCA9IGFlMTsgYWUxID0gYWUzOyBhZTMgPSB0OyB9CisgICAgICAgIGlmIChhZTIgPiBhZTMpIHsgbG9uZyB0ID0gYWUyOyBhZTIgPSBhZTM7IGFlMyA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMSA+IGFlNCkgeyBsb25nIHQgPSBhZTE7IGFlMSA9IGFlNDsgYWU0ID0gdDsgfQorICAgICAgICBpZiAoYWUzID4gYWU0KSB7IGxvbmcgdCA9IGFlMzsgYWUzID0gYWU0OyBhZTQgPSB0OyB9CisgICAgICAgIGlmIChhZTIgPiBhZTUpIHsgbG9uZyB0ID0gYWUyOyBhZTIgPSBhZTU7IGFlNSA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMiA+IGFlMykgeyBsb25nIHQgPSBhZTI7IGFlMiA9IGFlMzsgYWUzID0gdDsgfQorICAgICAgICBpZiAoYWU0ID4gYWU1KSB7IGxvbmcgdCA9IGFlNDsgYWU0ID0gYWU1OyBhZTUgPSB0OyB9CisKKyAgICAgICAgYVtlMV0gPSBhZTE7IGFbZTNdID0gYWUzOyBhW2U1XSA9IGFlNTsKKworICAgICAgICAvKgorICAgICAgICAgKiBVc2UgdGhlIHNlY29uZCBhbmQgZm91cnRoIG9mIHRoZSBmaXZlIHNvcnRlZCBlbGVtZW50cyBhcyBwaXZvdHMuCisgICAgICAgICAqIFRoZXNlIHZhbHVlcyBhcmUgaW5leHBlbnNpdmUgYXBwcm94aW1hdGlvbnMgb2YgdGhlIGZpcnN0IGFuZAorICAgICAgICAgKiBzZWNvbmQgdGVyY2lsZXMgb2YgdGhlIGFycmF5LiBOb3RlIHRoYXQgcGl2b3QxIDw9IHBpdm90Mi4KKyAgICAgICAgICoKKyAgICAgICAgICogVGhlIHBpdm90cyBhcmUgc3RvcmVkIGluIGxvY2FsIHZhcmlhYmxlcywgYW5kIHRoZSBmaXJzdCBhbmQKKyAgICAgICAgICogdGhlIGxhc3Qgb2YgdGhlIGVsZW1lbnRzIHRvIGJlIHNvcnRlZCBhcmUgbW92ZWQgdG8gdGhlIGxvY2F0aW9ucworICAgICAgICAgKiBmb3JtZXJseSBvY2N1cGllZCBieSB0aGUgcGl2b3RzLiBXaGVuIHBhcnRpdGlvbmluZyBpcyBjb21wbGV0ZSwKKyAgICAgICAgICogdGhlIHBpdm90cyBhcmUgc3dhcHBlZCBiYWNrIGludG8gdGhlaXIgZmluYWwgcG9zaXRpb25zLCBhbmQKKyAgICAgICAgICogZXhjbHVkZWQgZnJvbSBzdWJzZXF1ZW50IHNvcnRpbmcuCisgICAgICAgICAqLworICAgICAgICBsb25nIHBpdm90MSA9IGFlMjsgYVtlMl0gPSBhW2xlZnRdOworICAgICAgICBsb25nIHBpdm90MiA9IGFlNDsgYVtlNF0gPSBhW3JpZ2h0XTsKKworICAgICAgICAvLyBQb2ludGVycworICAgICAgICBpbnQgbGVzcyAgPSBsZWZ0ICArIDE7IC8vIFRoZSBpbmRleCBvZiBmaXJzdCBlbGVtZW50IG9mIGNlbnRlciBwYXJ0CisgICAgICAgIGludCBncmVhdCA9IHJpZ2h0IC0gMTsgLy8gVGhlIGluZGV4IGJlZm9yZSBmaXJzdCBlbGVtZW50IG9mIHJpZ2h0IHBhcnQKKworICAgICAgICBib29sZWFuIHBpdm90c0RpZmZlciA9IChwaXZvdDEgIT0gcGl2b3QyKTsKKworICAgICAgICBpZiAocGl2b3RzRGlmZmVyKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogUGFydGl0aW9uaW5nOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqICAgbGVmdCBwYXJ0ICAgICAgICAgY2VudGVyIHBhcnQgICAgICAgICAgICAgICAgICAgIHJpZ2h0IHBhcnQKKyAgICAgICAgICAgICAqICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCisgICAgICAgICAgICAgKiB8IDwgcGl2b3QxICB8ICBwaXZvdDEgPD0gJiYgPD0gcGl2b3QyICB8ICAgID8gICAgfCAgPiBwaXZvdDIgfAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBeICAgICAgICAgICAgICAgICAgICAgICAgICBeICAgICAgIF4KKyAgICAgICAgICAgICAqICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgIHwKKyAgICAgICAgICAgICAqICAgICAgICAgICAgIGxlc3MgICAgICAgICAgICAgICAgICAgICAgICBrICAgICBncmVhdAorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIEludmFyaWFudHM6CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogICAgICAgICAgICAgIGFsbCBpbiAobGVmdCwgbGVzcykgICA8IHBpdm90MQorICAgICAgICAgICAgICogICAgcGl2b3QxIDw9IGFsbCBpbiBbbGVzcywgaykgICAgIDw9IHBpdm90MgorICAgICAgICAgICAgICogICAgICAgICAgICAgIGFsbCBpbiAoZ3JlYXQsIHJpZ2h0KSA+IHBpdm90MgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIFBvaW50ZXIgayBpcyB0aGUgZmlyc3QgaW5kZXggb2YgPy1wYXJ0CisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIG91dGVyOgorICAgICAgICAgICAgZm9yIChpbnQgayA9IGxlc3M7IGsgPD0gZ3JlYXQ7IGsrKykgeworICAgICAgICAgICAgICAgIGxvbmcgYWsgPSBhW2tdOworICAgICAgICAgICAgICAgIGlmIChhayA8IHBpdm90MSkgeyAvLyBNb3ZlIGFba10gdG8gbGVmdCBwYXJ0CisgICAgICAgICAgICAgICAgICAgIGlmIChrICE9IGxlc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2xlc3NdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtsZXNzXSA9IGFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGxlc3MrKzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFrID4gcGl2b3QyKSB7IC8vIE1vdmUgYVtrXSB0byByaWdodCBwYXJ0CisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChhW2dyZWF0XSA+IHBpdm90MikgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdyZWF0LS0gPT0gaykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChhW2dyZWF0XSA8IHBpdm90MSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbbGVzc107CisgICAgICAgICAgICAgICAgICAgICAgICBhW2xlc3MrK10gPSBhW2dyZWF0XTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbZ3JlYXQtLV0gPSBhazsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gcGl2b3QxIDw9IGFbZ3JlYXRdIDw9IHBpdm90MgorICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbZ3JlYXRdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtncmVhdC0tXSA9IGFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeyAvLyBQaXZvdHMgYXJlIGVxdWFsCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogUGFydGl0aW9uIGRlZ2VuZXJhdGVzIHRvIHRoZSB0cmFkaXRpb25hbCAzLXdheSwKKyAgICAgICAgICAgICAqIG9yICJEdXRjaCBOYXRpb25hbCBGbGFnIiwgcGFydGl0aW9uOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqICAgbGVmdCBwYXJ0ICAgY2VudGVyIHBhcnQgICAgICAgICAgICByaWdodCBwYXJ0CisgICAgICAgICAgICAgKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqIHwgIDwgcGl2b3QgIHwgID09IHBpdm90ICB8ICAgID8gICAgfCAgPiBwaXZvdCAgfAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgXiAgICAgICAgICAgIF4gICAgICAgXgorICAgICAgICAgICAgICogICAgICAgICAgICAgIHwgICAgICAgICAgICB8ICAgICAgIHwKKyAgICAgICAgICAgICAqICAgICAgICAgICAgIGxlc3MgICAgICAgICAgayAgICAgZ3JlYXQKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBJbnZhcmlhbnRzOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqICAgYWxsIGluIChsZWZ0LCBsZXNzKSAgIDwgcGl2b3QKKyAgICAgICAgICAgICAqICAgYWxsIGluIFtsZXNzLCBrKSAgICAgPT0gcGl2b3QKKyAgICAgICAgICAgICAqICAgYWxsIGluIChncmVhdCwgcmlnaHQpID4gcGl2b3QKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBQb2ludGVyIGsgaXMgdGhlIGZpcnN0IGluZGV4IG9mID8tcGFydAorICAgICAgICAgICAgICovCisgICAgICAgICAgICBmb3IgKGludCBrID0gbGVzczsgayA8PSBncmVhdDsgaysrKSB7CisgICAgICAgICAgICAgICAgbG9uZyBhayA9IGFba107CisgICAgICAgICAgICAgICAgaWYgKGFrID09IHBpdm90MSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGFrIDwgcGl2b3QxKSB7IC8vIE1vdmUgYVtrXSB0byBsZWZ0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgaWYgKGsgIT0gbGVzcykgeworICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbbGVzc107CisgICAgICAgICAgICAgICAgICAgICAgICBhW2xlc3NdID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgbGVzcysrOworICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIChhW2tdID4gcGl2b3QxKSAtICBNb3ZlIGFba10gdG8gcmlnaHQgcGFydAorICAgICAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAgICAgKiBXZSBrbm93IHRoYXQgcGl2b3QxID09IGFbZTNdID09IHBpdm90Mi4gVGh1cywgd2Uga25vdworICAgICAgICAgICAgICAgICAgICAgKiB0aGF0IGdyZWF0IHdpbGwgc3RpbGwgYmUgPj0gayB3aGVuIHRoZSBmb2xsb3dpbmcgbG9vcAorICAgICAgICAgICAgICAgICAgICAgKiB0ZXJtaW5hdGVzLCBldmVuIHRob3VnaCB3ZSBkb24ndCB0ZXN0IGZvciBpdCBleHBsaWNpdGx5LgorICAgICAgICAgICAgICAgICAgICAgKiBJbiBvdGhlciB3b3JkcywgYVtlM10gYWN0cyBhcyBhIHNlbnRpbmVsIGZvciBncmVhdC4KKyAgICAgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChhW2dyZWF0XSA+IHBpdm90MSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZ3JlYXQtLTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoYVtncmVhdF0gPCBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2xlc3NdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtsZXNzKytdID0gYVtncmVhdF07CisgICAgICAgICAgICAgICAgICAgICAgICBhW2dyZWF0LS1dID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIGFbZ3JlYXRdID09IHBpdm90MQorICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IHBpdm90MTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbZ3JlYXQtLV0gPSBhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFN3YXAgcGl2b3RzIGludG8gdGhlaXIgZmluYWwgcG9zaXRpb25zCisgICAgICAgIGFbbGVmdF0gID0gYVtsZXNzICAtIDFdOyBhW2xlc3MgIC0gMV0gPSBwaXZvdDE7CisgICAgICAgIGFbcmlnaHRdID0gYVtncmVhdCArIDFdOyBhW2dyZWF0ICsgMV0gPSBwaXZvdDI7CisKKyAgICAgICAgLy8gU29ydCBsZWZ0IGFuZCByaWdodCBwYXJ0cyByZWN1cnNpdmVseSwgZXhjbHVkaW5nIGtub3duIHBpdm90IHZhbHVlcworICAgICAgICBkb1NvcnQoYSwgbGVmdCwgICBsZXNzIC0gMik7CisgICAgICAgIGRvU29ydChhLCBncmVhdCArIDIsIHJpZ2h0KTsKKworICAgICAgICAvKgorICAgICAgICAgKiBJZiBwaXZvdDEgPT0gcGl2b3QyLCBhbGwgZWxlbWVudHMgZnJvbSBjZW50ZXIKKyAgICAgICAgICogcGFydCBhcmUgZXF1YWwgYW5kLCB0aGVyZWZvcmUsIGFscmVhZHkgc29ydGVkCisgICAgICAgICAqLworICAgICAgICBpZiAoIXBpdm90c0RpZmZlcikgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogSWYgY2VudGVyIHBhcnQgaXMgdG9vIGxhcmdlIChjb21wcmlzZXMgPiAyLzMgb2YgdGhlIGFycmF5KSwKKyAgICAgICAgICogc3dhcCBpbnRlcm5hbCBwaXZvdCB2YWx1ZXMgdG8gZW5kcworICAgICAgICAgKi8KKyAgICAgICAgaWYgKGxlc3MgPCBlMSAmJiBncmVhdCA+IGU1KSB7CisgICAgICAgICAgICB3aGlsZSAoYVtsZXNzXSA9PSBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICBsZXNzKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB3aGlsZSAoYVtncmVhdF0gPT0gcGl2b3QyKSB7CisgICAgICAgICAgICAgICAgZ3JlYXQtLTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFBhcnRpdGlvbmluZzoKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiAgIGxlZnQgcGFydCAgICAgICBjZW50ZXIgcGFydCAgICAgICAgICAgICAgICAgICByaWdodCBwYXJ0CisgICAgICAgICAgICAgKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqIHwgPT0gcGl2b3QxIHwgIHBpdm90MSA8ICYmIDwgcGl2b3QyICB8ICAgID8gICAgfCA9PSBwaXZvdDIgfAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgXiAgICAgICAgICAgICAgICAgICAgICAgIF4gICAgICAgXgorICAgICAgICAgICAgICogICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgIHwKKyAgICAgICAgICAgICAqICAgICAgICAgICAgIGxlc3MgICAgICAgICAgICAgICAgICAgICAgayAgICAgZ3JlYXQKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBJbnZhcmlhbnRzOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBhbGwgaW4gKCosIGxlc3MpICA9PSBwaXZvdDEKKyAgICAgICAgICAgICAqICAgICBwaXZvdDEgPCBhbGwgaW4gW2xlc3MsIGspICAgPCBwaXZvdDIKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBhbGwgaW4gKGdyZWF0LCAqKSA9PSBwaXZvdDIKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBQb2ludGVyIGsgaXMgdGhlIGZpcnN0IGluZGV4IG9mID8tcGFydAorICAgICAgICAgICAgICovCisgICAgICAgICAgICBvdXRlcjoKKyAgICAgICAgICAgIGZvciAoaW50IGsgPSBsZXNzOyBrIDw9IGdyZWF0OyBrKyspIHsKKyAgICAgICAgICAgICAgICBsb25nIGFrID0gYVtrXTsKKyAgICAgICAgICAgICAgICBpZiAoYWsgPT0gcGl2b3QyKSB7IC8vIE1vdmUgYVtrXSB0byByaWdodCBwYXJ0CisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChhW2dyZWF0XSA9PSBwaXZvdDIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChncmVhdC0tID09IGspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoYVtncmVhdF0gPT0gcGl2b3QxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtsZXNzXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbbGVzcysrXSA9IHBpdm90MTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gcGl2b3QxIDwgYVtncmVhdF0gPCBwaXZvdDIKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2dyZWF0XTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBhW2dyZWF0LS1dID0gcGl2b3QyOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYWsgPT0gcGl2b3QxKSB7IC8vIE1vdmUgYVtrXSB0byBsZWZ0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbbGVzc107CisgICAgICAgICAgICAgICAgICAgIGFbbGVzcysrXSA9IHBpdm90MTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBTb3J0IGNlbnRlciBwYXJ0IHJlY3Vyc2l2ZWx5LCBleGNsdWRpbmcga25vd24gcGl2b3QgdmFsdWVzCisgICAgICAgIGRvU29ydChhLCBsZXNzLCBncmVhdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCBhcnJheSBpbnRvIGFzY2VuZGluZyBudW1lcmljYWwgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc29ydGVkCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNvcnQoc2hvcnRbXSBhKSB7CisgICAgICAgIGRvU29ydChhLCAwLCBhLmxlbmd0aCAtIDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhlIGFycmF5IGludG8gYXNjZW5kaW5nIG9yZGVyLiBUaGUgcmFuZ2UKKyAgICAgKiB0byBiZSBzb3J0ZWQgZXh0ZW5kcyBmcm9tIHRoZSBpbmRleCB7QGNvZGUgZnJvbUluZGV4fSwgaW5jbHVzaXZlLCB0bworICAgICAqIHRoZSBpbmRleCB7QGNvZGUgdG9JbmRleH0sIGV4Y2x1c2l2ZS4gSWYge0Bjb2RlIGZyb21JbmRleCA9PSB0b0luZGV4fSwKKyAgICAgKiB0aGUgcmFuZ2UgdG8gYmUgc29ydGVkIGlzIGVtcHR5IChhbmQgdGhlIGNhbGwgaXMgYSBuby1vcCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIGZyb21JbmRleCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQsIGluY2x1c2l2ZSwgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIHRvSW5kZXggdGhlIGluZGV4IG9mIHRoZSBsYXN0IGVsZW1lbnQsIGV4Y2x1c2l2ZSwgdG8gYmUgc29ydGVkCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGZyb21JbmRleCA+IHRvSW5kZXh9CisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgaWYge0Bjb2RlIGZyb21JbmRleCA8IDB9IG9yIHtAY29kZSB0b0luZGV4ID4gYS5sZW5ndGh9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNvcnQoc2hvcnRbXSBhLCBpbnQgZnJvbUluZGV4LCBpbnQgdG9JbmRleCkgeworICAgICAgICBBcnJheXMuY2hlY2tTdGFydEFuZEVuZChhLmxlbmd0aCwgZnJvbUluZGV4LCB0b0luZGV4KTsKKyAgICAgICAgZG9Tb3J0KGEsIGZyb21JbmRleCwgdG9JbmRleCAtIDEpOworICAgIH0KKworICAgIC8qKiBUaGUgbnVtYmVyIG9mIGRpc3RpbmN0IHNob3J0IHZhbHVlcy4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTlVNX1NIT1JUX1ZBTFVFUyA9IDEgPDwgMTY7CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIHRoZSBhcnJheSBpbnRvIGFzY2VuZGluZyBvcmRlci4gVGhpcworICAgICAqIG1ldGhvZCBkaWZmZXJzIGZyb20gdGhlIHB1YmxpYyB7QGNvZGUgc29ydH0gbWV0aG9kIGluIHRoYXQgdGhlCisgICAgICoge0Bjb2RlIHJpZ2h0fSBpbmRleCBpcyBpbmNsdXNpdmUsIGFuZCBpdCBkb2VzIG5vIHJhbmdlIGNoZWNraW5nIG9uCisgICAgICoge0Bjb2RlIGxlZnR9IG9yIHtAY29kZSByaWdodH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIGxlZnQgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSByaWdodCB0aGUgaW5kZXggb2YgdGhlIGxhc3QgZWxlbWVudCwgaW5jbHVzaXZlLCB0byBiZSBzb3J0ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGRvU29ydChzaG9ydFtdIGEsIGludCBsZWZ0LCBpbnQgcmlnaHQpIHsKKyAgICAgICAgLy8gVXNlIGluc2VydGlvbiBzb3J0IG9uIHRpbnkgYXJyYXlzCisgICAgICAgIGlmIChyaWdodCAtIGxlZnQgKyAxIDwgSU5TRVJUSU9OX1NPUlRfVEhSRVNIT0xEKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gbGVmdCArIDE7IGkgPD0gcmlnaHQ7IGkrKykgeworICAgICAgICAgICAgICAgIHNob3J0IGFpID0gYVtpXTsKKyAgICAgICAgICAgICAgICBpbnQgajsKKyAgICAgICAgICAgICAgICBmb3IgKGogPSBpIC0gMTsgaiA+PSBsZWZ0ICYmIGFpIDwgYVtqXTsgai0tKSB7CisgICAgICAgICAgICAgICAgICAgIGFbaiArIDFdID0gYVtqXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYVtqICsgMV0gPSBhaTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChyaWdodC1sZWZ0KzEgPiBDT1VOVElOR19TT1JUX1RIUkVTSE9MRF9GT1JfU0hPUlRfT1JfQ0hBUikgeworICAgICAgICAgICAgLy8gVXNlIGNvdW50aW5nIHNvcnQgb24gaHVnZSBhcnJheXMKKyAgICAgICAgICAgIGludFtdIGNvdW50ID0gbmV3IGludFtOVU1fU0hPUlRfVkFMVUVTXTsKKworICAgICAgICAgICAgZm9yIChpbnQgaSA9IGxlZnQ7IGkgPD0gcmlnaHQ7IGkrKykgeworICAgICAgICAgICAgICAgIGNvdW50W2FbaV0gLSBTaG9ydC5NSU5fVkFMVUVdKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgayA9IGxlZnQ7IGkgPCBjb3VudC5sZW5ndGggJiYgayA8PSByaWdodDsgaSsrKSB7CisgICAgICAgICAgICAgICAgc2hvcnQgdmFsdWUgPSAoc2hvcnQpIChpICsgU2hvcnQuTUlOX1ZBTFVFKTsKKworICAgICAgICAgICAgICAgIGZvciAoaW50IHMgPSBjb3VudFtpXTsgcyA+IDA7IHMtLSkgeworICAgICAgICAgICAgICAgICAgICBhW2srK10gPSB2YWx1ZTsKKyAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsgLy8gVXNlIER1YWwtUGl2b3QgUXVpY2tzb3J0IG9uIGxhcmdlIGFycmF5cworICAgICAgICAgICAgZHVhbFBpdm90UXVpY2tzb3J0KGEsIGxlZnQsIHJpZ2h0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhlIGFycmF5IGludG8gYXNjZW5kaW5nIG9yZGVyIGJ5IHRoZQorICAgICAqIER1YWwtUGl2b3QgUXVpY2tzb3J0IGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gbGVmdCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQsIGluY2x1c2l2ZSwgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIHJpZ2h0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZHVhbFBpdm90UXVpY2tzb3J0KHNob3J0W10gYSwgaW50IGxlZnQsIGludCByaWdodCkgeworICAgICAgICAvLyBDb21wdXRlIGluZGljZXMgb2YgZml2ZSBldmVubHkgc3BhY2VkIGVsZW1lbnRzCisgICAgICAgIGludCBzaXh0aCA9IChyaWdodCAtIGxlZnQgKyAxKSAvIDY7CisgICAgICAgIGludCBlMSA9IGxlZnQgICsgc2l4dGg7CisgICAgICAgIGludCBlNSA9IHJpZ2h0IC0gc2l4dGg7CisgICAgICAgIGludCBlMyA9IChsZWZ0ICsgcmlnaHQpID4+PiAxOyAvLyBUaGUgbWlkcG9pbnQKKyAgICAgICAgaW50IGU0ID0gZTMgKyBzaXh0aDsKKyAgICAgICAgaW50IGUyID0gZTMgLSBzaXh0aDsKKworICAgICAgICAvLyBTb3J0IHRoZXNlIGVsZW1lbnRzIHVzaW5nIGEgNS1lbGVtZW50IHNvcnRpbmcgbmV0d29yaworICAgICAgICBzaG9ydCBhZTEgPSBhW2UxXSwgYWUyID0gYVtlMl0sIGFlMyA9IGFbZTNdLCBhZTQgPSBhW2U0XSwgYWU1ID0gYVtlNV07CisKKyAgICAgICAgaWYgKGFlMSA+IGFlMikgeyBzaG9ydCB0ID0gYWUxOyBhZTEgPSBhZTI7IGFlMiA9IHQ7IH0KKyAgICAgICAgaWYgKGFlNCA+IGFlNSkgeyBzaG9ydCB0ID0gYWU0OyBhZTQgPSBhZTU7IGFlNSA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMSA+IGFlMykgeyBzaG9ydCB0ID0gYWUxOyBhZTEgPSBhZTM7IGFlMyA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMiA+IGFlMykgeyBzaG9ydCB0ID0gYWUyOyBhZTIgPSBhZTM7IGFlMyA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMSA+IGFlNCkgeyBzaG9ydCB0ID0gYWUxOyBhZTEgPSBhZTQ7IGFlNCA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMyA+IGFlNCkgeyBzaG9ydCB0ID0gYWUzOyBhZTMgPSBhZTQ7IGFlNCA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMiA+IGFlNSkgeyBzaG9ydCB0ID0gYWUyOyBhZTIgPSBhZTU7IGFlNSA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMiA+IGFlMykgeyBzaG9ydCB0ID0gYWUyOyBhZTIgPSBhZTM7IGFlMyA9IHQ7IH0KKyAgICAgICAgaWYgKGFlNCA+IGFlNSkgeyBzaG9ydCB0ID0gYWU0OyBhZTQgPSBhZTU7IGFlNSA9IHQ7IH0KKworICAgICAgICBhW2UxXSA9IGFlMTsgYVtlM10gPSBhZTM7IGFbZTVdID0gYWU1OworCisgICAgICAgIC8qCisgICAgICAgICAqIFVzZSB0aGUgc2Vjb25kIGFuZCBmb3VydGggb2YgdGhlIGZpdmUgc29ydGVkIGVsZW1lbnRzIGFzIHBpdm90cy4KKyAgICAgICAgICogVGhlc2UgdmFsdWVzIGFyZSBpbmV4cGVuc2l2ZSBhcHByb3hpbWF0aW9ucyBvZiB0aGUgZmlyc3QgYW5kCisgICAgICAgICAqIHNlY29uZCB0ZXJjaWxlcyBvZiB0aGUgYXJyYXkuIE5vdGUgdGhhdCBwaXZvdDEgPD0gcGl2b3QyLgorICAgICAgICAgKgorICAgICAgICAgKiBUaGUgcGl2b3RzIGFyZSBzdG9yZWQgaW4gbG9jYWwgdmFyaWFibGVzLCBhbmQgdGhlIGZpcnN0IGFuZAorICAgICAgICAgKiB0aGUgbGFzdCBvZiB0aGUgZWxlbWVudHMgdG8gYmUgc29ydGVkIGFyZSBtb3ZlZCB0byB0aGUgbG9jYXRpb25zCisgICAgICAgICAqIGZvcm1lcmx5IG9jY3VwaWVkIGJ5IHRoZSBwaXZvdHMuIFdoZW4gcGFydGl0aW9uaW5nIGlzIGNvbXBsZXRlLAorICAgICAgICAgKiB0aGUgcGl2b3RzIGFyZSBzd2FwcGVkIGJhY2sgaW50byB0aGVpciBmaW5hbCBwb3NpdGlvbnMsIGFuZAorICAgICAgICAgKiBleGNsdWRlZCBmcm9tIHN1YnNlcXVlbnQgc29ydGluZy4KKyAgICAgICAgICovCisgICAgICAgIHNob3J0IHBpdm90MSA9IGFlMjsgYVtlMl0gPSBhW2xlZnRdOworICAgICAgICBzaG9ydCBwaXZvdDIgPSBhZTQ7IGFbZTRdID0gYVtyaWdodF07CisKKyAgICAgICAgLy8gUG9pbnRlcnMKKyAgICAgICAgaW50IGxlc3MgID0gbGVmdCAgKyAxOyAvLyBUaGUgaW5kZXggb2YgZmlyc3QgZWxlbWVudCBvZiBjZW50ZXIgcGFydAorICAgICAgICBpbnQgZ3JlYXQgPSByaWdodCAtIDE7IC8vIFRoZSBpbmRleCBiZWZvcmUgZmlyc3QgZWxlbWVudCBvZiByaWdodCBwYXJ0CisKKyAgICAgICAgYm9vbGVhbiBwaXZvdHNEaWZmZXIgPSAocGl2b3QxICE9IHBpdm90Mik7CisKKyAgICAgICAgaWYgKHBpdm90c0RpZmZlcikgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFBhcnRpdGlvbmluZzoKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiAgIGxlZnQgcGFydCAgICAgICAgIGNlbnRlciBwYXJ0ICAgICAgICAgICAgICAgICAgICByaWdodCBwYXJ0CisgICAgICAgICAgICAgKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKworICAgICAgICAgICAgICogfCA8IHBpdm90MSAgfCAgcGl2b3QxIDw9ICYmIDw9IHBpdm90MiAgfCAgICA/ICAgIHwgID4gcGl2b3QyIHwKKyAgICAgICAgICAgICAqICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgXiAgICAgICAgICAgICAgICAgICAgICAgICAgXiAgICAgICBeCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICB8CisgICAgICAgICAgICAgKiAgICAgICAgICAgICBsZXNzICAgICAgICAgICAgICAgICAgICAgICAgayAgICAgZ3JlYXQKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBJbnZhcmlhbnRzOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBhbGwgaW4gKGxlZnQsIGxlc3MpICAgPCBwaXZvdDEKKyAgICAgICAgICAgICAqICAgIHBpdm90MSA8PSBhbGwgaW4gW2xlc3MsIGspICAgICA8PSBwaXZvdDIKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBhbGwgaW4gKGdyZWF0LCByaWdodCkgPiBwaXZvdDIKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBQb2ludGVyIGsgaXMgdGhlIGZpcnN0IGluZGV4IG9mID8tcGFydAorICAgICAgICAgICAgICovCisgICAgICAgICAgICBvdXRlcjoKKyAgICAgICAgICAgIGZvciAoaW50IGsgPSBsZXNzOyBrIDw9IGdyZWF0OyBrKyspIHsKKyAgICAgICAgICAgICAgICBzaG9ydCBhayA9IGFba107CisgICAgICAgICAgICAgICAgaWYgKGFrIDwgcGl2b3QxKSB7IC8vIE1vdmUgYVtrXSB0byBsZWZ0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgaWYgKGsgIT0gbGVzcykgeworICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbbGVzc107CisgICAgICAgICAgICAgICAgICAgICAgICBhW2xlc3NdID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgbGVzcysrOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYWsgPiBwaXZvdDIpIHsgLy8gTW92ZSBhW2tdIHRvIHJpZ2h0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGFbZ3JlYXRdID4gcGl2b3QyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ3JlYXQtLSA9PSBrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKGFbZ3JlYXRdIDwgcGl2b3QxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtsZXNzXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbbGVzcysrXSA9IGFbZ3JlYXRdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtncmVhdC0tXSA9IGFrOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBwaXZvdDEgPD0gYVtncmVhdF0gPD0gcGl2b3QyCisgICAgICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtncmVhdF07CisgICAgICAgICAgICAgICAgICAgICAgICBhW2dyZWF0LS1dID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7IC8vIFBpdm90cyBhcmUgZXF1YWwKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBQYXJ0aXRpb24gZGVnZW5lcmF0ZXMgdG8gdGhlIHRyYWRpdGlvbmFsIDMtd2F5LAorICAgICAgICAgICAgICogb3IgIkR1dGNoIE5hdGlvbmFsIEZsYWciLCBwYXJ0aXRpb246CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogICBsZWZ0IHBhcnQgICBjZW50ZXIgcGFydCAgICAgICAgICAgIHJpZ2h0IHBhcnQKKyAgICAgICAgICAgICAqICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKworICAgICAgICAgICAgICogfCAgPCBwaXZvdCAgfCAgPT0gcGl2b3QgIHwgICAgPyAgICB8ICA+IHBpdm90ICB8CisgICAgICAgICAgICAgKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBeICAgICAgICAgICAgXiAgICAgICBeCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgfCAgICAgICAgICAgIHwgICAgICAgfAorICAgICAgICAgICAgICogICAgICAgICAgICAgbGVzcyAgICAgICAgICBrICAgICBncmVhdAorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIEludmFyaWFudHM6CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogICBhbGwgaW4gKGxlZnQsIGxlc3MpICAgPCBwaXZvdAorICAgICAgICAgICAgICogICBhbGwgaW4gW2xlc3MsIGspICAgICA9PSBwaXZvdAorICAgICAgICAgICAgICogICBhbGwgaW4gKGdyZWF0LCByaWdodCkgPiBwaXZvdAorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIFBvaW50ZXIgayBpcyB0aGUgZmlyc3QgaW5kZXggb2YgPy1wYXJ0CisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGZvciAoaW50IGsgPSBsZXNzOyBrIDw9IGdyZWF0OyBrKyspIHsKKyAgICAgICAgICAgICAgICBzaG9ydCBhayA9IGFba107CisgICAgICAgICAgICAgICAgaWYgKGFrID09IHBpdm90MSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGFrIDwgcGl2b3QxKSB7IC8vIE1vdmUgYVtrXSB0byBsZWZ0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgaWYgKGsgIT0gbGVzcykgeworICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbbGVzc107CisgICAgICAgICAgICAgICAgICAgICAgICBhW2xlc3NdID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgbGVzcysrOworICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIChhW2tdID4gcGl2b3QxKSAtICBNb3ZlIGFba10gdG8gcmlnaHQgcGFydAorICAgICAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAgICAgKiBXZSBrbm93IHRoYXQgcGl2b3QxID09IGFbZTNdID09IHBpdm90Mi4gVGh1cywgd2Uga25vdworICAgICAgICAgICAgICAgICAgICAgKiB0aGF0IGdyZWF0IHdpbGwgc3RpbGwgYmUgPj0gayB3aGVuIHRoZSBmb2xsb3dpbmcgbG9vcAorICAgICAgICAgICAgICAgICAgICAgKiB0ZXJtaW5hdGVzLCBldmVuIHRob3VnaCB3ZSBkb24ndCB0ZXN0IGZvciBpdCBleHBsaWNpdGx5LgorICAgICAgICAgICAgICAgICAgICAgKiBJbiBvdGhlciB3b3JkcywgYVtlM10gYWN0cyBhcyBhIHNlbnRpbmVsIGZvciBncmVhdC4KKyAgICAgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChhW2dyZWF0XSA+IHBpdm90MSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZ3JlYXQtLTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoYVtncmVhdF0gPCBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2xlc3NdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtsZXNzKytdID0gYVtncmVhdF07CisgICAgICAgICAgICAgICAgICAgICAgICBhW2dyZWF0LS1dID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIGFbZ3JlYXRdID09IHBpdm90MQorICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IHBpdm90MTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbZ3JlYXQtLV0gPSBhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFN3YXAgcGl2b3RzIGludG8gdGhlaXIgZmluYWwgcG9zaXRpb25zCisgICAgICAgIGFbbGVmdF0gID0gYVtsZXNzICAtIDFdOyBhW2xlc3MgIC0gMV0gPSBwaXZvdDE7CisgICAgICAgIGFbcmlnaHRdID0gYVtncmVhdCArIDFdOyBhW2dyZWF0ICsgMV0gPSBwaXZvdDI7CisKKyAgICAgICAgLy8gU29ydCBsZWZ0IGFuZCByaWdodCBwYXJ0cyByZWN1cnNpdmVseSwgZXhjbHVkaW5nIGtub3duIHBpdm90IHZhbHVlcworICAgICAgICBkb1NvcnQoYSwgbGVmdCwgICBsZXNzIC0gMik7CisgICAgICAgIGRvU29ydChhLCBncmVhdCArIDIsIHJpZ2h0KTsKKworICAgICAgICAvKgorICAgICAgICAgKiBJZiBwaXZvdDEgPT0gcGl2b3QyLCBhbGwgZWxlbWVudHMgZnJvbSBjZW50ZXIKKyAgICAgICAgICogcGFydCBhcmUgZXF1YWwgYW5kLCB0aGVyZWZvcmUsIGFscmVhZHkgc29ydGVkCisgICAgICAgICAqLworICAgICAgICBpZiAoIXBpdm90c0RpZmZlcikgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogSWYgY2VudGVyIHBhcnQgaXMgdG9vIGxhcmdlIChjb21wcmlzZXMgPiAyLzMgb2YgdGhlIGFycmF5KSwKKyAgICAgICAgICogc3dhcCBpbnRlcm5hbCBwaXZvdCB2YWx1ZXMgdG8gZW5kcworICAgICAgICAgKi8KKyAgICAgICAgaWYgKGxlc3MgPCBlMSAmJiBncmVhdCA+IGU1KSB7CisgICAgICAgICAgICB3aGlsZSAoYVtsZXNzXSA9PSBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICBsZXNzKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB3aGlsZSAoYVtncmVhdF0gPT0gcGl2b3QyKSB7CisgICAgICAgICAgICAgICAgZ3JlYXQtLTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFBhcnRpdGlvbmluZzoKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiAgIGxlZnQgcGFydCAgICAgICBjZW50ZXIgcGFydCAgICAgICAgICAgICAgICAgICByaWdodCBwYXJ0CisgICAgICAgICAgICAgKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqIHwgPT0gcGl2b3QxIHwgIHBpdm90MSA8ICYmIDwgcGl2b3QyICB8ICAgID8gICAgfCA9PSBwaXZvdDIgfAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgXiAgICAgICAgICAgICAgICAgICAgICAgIF4gICAgICAgXgorICAgICAgICAgICAgICogICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgIHwKKyAgICAgICAgICAgICAqICAgICAgICAgICAgIGxlc3MgICAgICAgICAgICAgICAgICAgICAgayAgICAgZ3JlYXQKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBJbnZhcmlhbnRzOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBhbGwgaW4gKCosIGxlc3MpICA9PSBwaXZvdDEKKyAgICAgICAgICAgICAqICAgICBwaXZvdDEgPCBhbGwgaW4gW2xlc3MsIGspICAgPCBwaXZvdDIKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBhbGwgaW4gKGdyZWF0LCAqKSA9PSBwaXZvdDIKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBQb2ludGVyIGsgaXMgdGhlIGZpcnN0IGluZGV4IG9mID8tcGFydAorICAgICAgICAgICAgICovCisgICAgICAgICAgICBvdXRlcjoKKyAgICAgICAgICAgIGZvciAoaW50IGsgPSBsZXNzOyBrIDw9IGdyZWF0OyBrKyspIHsKKyAgICAgICAgICAgICAgICBzaG9ydCBhayA9IGFba107CisgICAgICAgICAgICAgICAgaWYgKGFrID09IHBpdm90MikgeyAvLyBNb3ZlIGFba10gdG8gcmlnaHQgcGFydAorICAgICAgICAgICAgICAgICAgICB3aGlsZSAoYVtncmVhdF0gPT0gcGl2b3QyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ3JlYXQtLSA9PSBrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKGFbZ3JlYXRdID09IHBpdm90MSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbbGVzc107CisgICAgICAgICAgICAgICAgICAgICAgICBhW2xlc3MrK10gPSBwaXZvdDE7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIHBpdm90MSA8IGFbZ3JlYXRdIDwgcGl2b3QyCisgICAgICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtncmVhdF07CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYVtncmVhdC0tXSA9IHBpdm90MjsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFrID09IHBpdm90MSkgeyAvLyBNb3ZlIGFba10gdG8gbGVmdCBwYXJ0CisgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2xlc3NdOworICAgICAgICAgICAgICAgICAgICBhW2xlc3MrK10gPSBwaXZvdDE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gU29ydCBjZW50ZXIgcGFydCByZWN1cnNpdmVseSwgZXhjbHVkaW5nIGtub3duIHBpdm90IHZhbHVlcworICAgICAgICBkb1NvcnQoYSwgbGVzcywgZ3JlYXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgYXJyYXkgaW50byBhc2NlbmRpbmcgbnVtZXJpY2FsIG9yZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGEgdGhlIGFycmF5IHRvIGJlIHNvcnRlZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzb3J0KGNoYXJbXSBhKSB7CisgICAgICAgIGRvU29ydChhLCAwLCBhLmxlbmd0aCAtIDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhlIGFycmF5IGludG8gYXNjZW5kaW5nIG9yZGVyLiBUaGUgcmFuZ2UKKyAgICAgKiB0byBiZSBzb3J0ZWQgZXh0ZW5kcyBmcm9tIHRoZSBpbmRleCB7QGNvZGUgZnJvbUluZGV4fSwgaW5jbHVzaXZlLCB0bworICAgICAqIHRoZSBpbmRleCB7QGNvZGUgdG9JbmRleH0sIGV4Y2x1c2l2ZS4gSWYge0Bjb2RlIGZyb21JbmRleCA9PSB0b0luZGV4fSwKKyAgICAgKiB0aGUgcmFuZ2UgdG8gYmUgc29ydGVkIGlzIGVtcHR5IChhbmQgdGhlIGNhbGwgaXMgYSBuby1vcCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIGZyb21JbmRleCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQsIGluY2x1c2l2ZSwgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIHRvSW5kZXggdGhlIGluZGV4IG9mIHRoZSBsYXN0IGVsZW1lbnQsIGV4Y2x1c2l2ZSwgdG8gYmUgc29ydGVkCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGZyb21JbmRleCA+IHRvSW5kZXh9CisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgaWYge0Bjb2RlIGZyb21JbmRleCA8IDB9IG9yIHtAY29kZSB0b0luZGV4ID4gYS5sZW5ndGh9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNvcnQoY2hhcltdIGEsIGludCBmcm9tSW5kZXgsIGludCB0b0luZGV4KSB7CisgICAgICAgIEFycmF5cy5jaGVja1N0YXJ0QW5kRW5kKGEubGVuZ3RoLCBmcm9tSW5kZXgsIHRvSW5kZXgpOworICAgICAgICBkb1NvcnQoYSwgZnJvbUluZGV4LCB0b0luZGV4IC0gMSk7CisgICAgfQorCisgICAgLyoqIFRoZSBudW1iZXIgb2YgZGlzdGluY3QgY2hhciB2YWx1ZXMuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5VTV9DSEFSX1ZBTFVFUyA9IDEgPDwgMTY7CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIHRoZSBhcnJheSBpbnRvIGFzY2VuZGluZyBvcmRlci4gVGhpcworICAgICAqIG1ldGhvZCBkaWZmZXJzIGZyb20gdGhlIHB1YmxpYyB7QGNvZGUgc29ydH0gbWV0aG9kIGluIHRoYXQgdGhlCisgICAgICoge0Bjb2RlIHJpZ2h0fSBpbmRleCBpcyBpbmNsdXNpdmUsIGFuZCBpdCBkb2VzIG5vIHJhbmdlIGNoZWNraW5nIG9uCisgICAgICoge0Bjb2RlIGxlZnR9IG9yIHtAY29kZSByaWdodH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIGxlZnQgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSByaWdodCB0aGUgaW5kZXggb2YgdGhlIGxhc3QgZWxlbWVudCwgaW5jbHVzaXZlLCB0byBiZSBzb3J0ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGRvU29ydChjaGFyW10gYSwgaW50IGxlZnQsIGludCByaWdodCkgeworICAgICAgICAvLyBVc2UgaW5zZXJ0aW9uIHNvcnQgb24gdGlueSBhcnJheXMKKyAgICAgICAgaWYgKHJpZ2h0IC0gbGVmdCArIDEgPCBJTlNFUlRJT05fU09SVF9USFJFU0hPTEQpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBsZWZ0ICsgMTsgaSA8PSByaWdodDsgaSsrKSB7CisgICAgICAgICAgICAgICAgY2hhciBhaSA9IGFbaV07CisgICAgICAgICAgICAgICAgaW50IGo7CisgICAgICAgICAgICAgICAgZm9yIChqID0gaSAtIDE7IGogPj0gbGVmdCAmJiBhaSA8IGFbal07IGotLSkgeworICAgICAgICAgICAgICAgICAgICBhW2ogKyAxXSA9IGFbal07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFbaiArIDFdID0gYWk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAocmlnaHQtbGVmdCsxID4gQ09VTlRJTkdfU09SVF9USFJFU0hPTERfRk9SX1NIT1JUX09SX0NIQVIpIHsKKyAgICAgICAgICAgIC8vIFVzZSBjb3VudGluZyBzb3J0IG9uIGh1Z2UgYXJyYXlzCisgICAgICAgICAgICBpbnRbXSBjb3VudCA9IG5ldyBpbnRbTlVNX0NIQVJfVkFMVUVTXTsKKworICAgICAgICAgICAgZm9yIChpbnQgaSA9IGxlZnQ7IGkgPD0gcmlnaHQ7IGkrKykgeworICAgICAgICAgICAgICAgIGNvdW50W2FbaV1dKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgayA9IGxlZnQ7IGkgPCBjb3VudC5sZW5ndGggJiYgayA8PSByaWdodDsgaSsrKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgcyA9IGNvdW50W2ldOyBzID4gMDsgcy0tKSB7CisgICAgICAgICAgICAgICAgICAgIGFbaysrXSA9IChjaGFyKSBpOworICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeyAvLyBVc2UgRHVhbC1QaXZvdCBRdWlja3NvcnQgb24gbGFyZ2UgYXJyYXlzCisgICAgICAgICAgICBkdWFsUGl2b3RRdWlja3NvcnQoYSwgbGVmdCwgcmlnaHQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCByYW5nZSBvZiB0aGUgYXJyYXkgaW50byBhc2NlbmRpbmcgb3JkZXIgYnkgdGhlCisgICAgICogRHVhbC1QaXZvdCBRdWlja3NvcnQgYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHBhcmFtIGEgdGhlIGFycmF5IHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSBsZWZ0IHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgZWxlbWVudCwgaW5jbHVzaXZlLCB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gcmlnaHQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IGVsZW1lbnQsIGluY2x1c2l2ZSwgdG8gYmUgc29ydGVkCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBkdWFsUGl2b3RRdWlja3NvcnQoY2hhcltdIGEsIGludCBsZWZ0LCBpbnQgcmlnaHQpIHsKKyAgICAgICAgLy8gQ29tcHV0ZSBpbmRpY2VzIG9mIGZpdmUgZXZlbmx5IHNwYWNlZCBlbGVtZW50cworICAgICAgICBpbnQgc2l4dGggPSAocmlnaHQgLSBsZWZ0ICsgMSkgLyA2OworICAgICAgICBpbnQgZTEgPSBsZWZ0ICArIHNpeHRoOworICAgICAgICBpbnQgZTUgPSByaWdodCAtIHNpeHRoOworICAgICAgICBpbnQgZTMgPSAobGVmdCArIHJpZ2h0KSA+Pj4gMTsgLy8gVGhlIG1pZHBvaW50CisgICAgICAgIGludCBlNCA9IGUzICsgc2l4dGg7CisgICAgICAgIGludCBlMiA9IGUzIC0gc2l4dGg7CisKKyAgICAgICAgLy8gU29ydCB0aGVzZSBlbGVtZW50cyB1c2luZyBhIDUtZWxlbWVudCBzb3J0aW5nIG5ldHdvcmsKKyAgICAgICAgY2hhciBhZTEgPSBhW2UxXSwgYWUyID0gYVtlMl0sIGFlMyA9IGFbZTNdLCBhZTQgPSBhW2U0XSwgYWU1ID0gYVtlNV07CisKKyAgICAgICAgaWYgKGFlMSA+IGFlMikgeyBjaGFyIHQgPSBhZTE7IGFlMSA9IGFlMjsgYWUyID0gdDsgfQorICAgICAgICBpZiAoYWU0ID4gYWU1KSB7IGNoYXIgdCA9IGFlNDsgYWU0ID0gYWU1OyBhZTUgPSB0OyB9CisgICAgICAgIGlmIChhZTEgPiBhZTMpIHsgY2hhciB0ID0gYWUxOyBhZTEgPSBhZTM7IGFlMyA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMiA+IGFlMykgeyBjaGFyIHQgPSBhZTI7IGFlMiA9IGFlMzsgYWUzID0gdDsgfQorICAgICAgICBpZiAoYWUxID4gYWU0KSB7IGNoYXIgdCA9IGFlMTsgYWUxID0gYWU0OyBhZTQgPSB0OyB9CisgICAgICAgIGlmIChhZTMgPiBhZTQpIHsgY2hhciB0ID0gYWUzOyBhZTMgPSBhZTQ7IGFlNCA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMiA+IGFlNSkgeyBjaGFyIHQgPSBhZTI7IGFlMiA9IGFlNTsgYWU1ID0gdDsgfQorICAgICAgICBpZiAoYWUyID4gYWUzKSB7IGNoYXIgdCA9IGFlMjsgYWUyID0gYWUzOyBhZTMgPSB0OyB9CisgICAgICAgIGlmIChhZTQgPiBhZTUpIHsgY2hhciB0ID0gYWU0OyBhZTQgPSBhZTU7IGFlNSA9IHQ7IH0KKworICAgICAgICBhW2UxXSA9IGFlMTsgYVtlM10gPSBhZTM7IGFbZTVdID0gYWU1OworCisgICAgICAgIC8qCisgICAgICAgICAqIFVzZSB0aGUgc2Vjb25kIGFuZCBmb3VydGggb2YgdGhlIGZpdmUgc29ydGVkIGVsZW1lbnRzIGFzIHBpdm90cy4KKyAgICAgICAgICogVGhlc2UgdmFsdWVzIGFyZSBpbmV4cGVuc2l2ZSBhcHByb3hpbWF0aW9ucyBvZiB0aGUgZmlyc3QgYW5kCisgICAgICAgICAqIHNlY29uZCB0ZXJjaWxlcyBvZiB0aGUgYXJyYXkuIE5vdGUgdGhhdCBwaXZvdDEgPD0gcGl2b3QyLgorICAgICAgICAgKgorICAgICAgICAgKiBUaGUgcGl2b3RzIGFyZSBzdG9yZWQgaW4gbG9jYWwgdmFyaWFibGVzLCBhbmQgdGhlIGZpcnN0IGFuZAorICAgICAgICAgKiB0aGUgbGFzdCBvZiB0aGUgZWxlbWVudHMgdG8gYmUgc29ydGVkIGFyZSBtb3ZlZCB0byB0aGUgbG9jYXRpb25zCisgICAgICAgICAqIGZvcm1lcmx5IG9jY3VwaWVkIGJ5IHRoZSBwaXZvdHMuIFdoZW4gcGFydGl0aW9uaW5nIGlzIGNvbXBsZXRlLAorICAgICAgICAgKiB0aGUgcGl2b3RzIGFyZSBzd2FwcGVkIGJhY2sgaW50byB0aGVpciBmaW5hbCBwb3NpdGlvbnMsIGFuZAorICAgICAgICAgKiBleGNsdWRlZCBmcm9tIHN1YnNlcXVlbnQgc29ydGluZy4KKyAgICAgICAgICovCisgICAgICAgIGNoYXIgcGl2b3QxID0gYWUyOyBhW2UyXSA9IGFbbGVmdF07CisgICAgICAgIGNoYXIgcGl2b3QyID0gYWU0OyBhW2U0XSA9IGFbcmlnaHRdOworCisgICAgICAgIC8vIFBvaW50ZXJzCisgICAgICAgIGludCBsZXNzICA9IGxlZnQgICsgMTsgLy8gVGhlIGluZGV4IG9mIGZpcnN0IGVsZW1lbnQgb2YgY2VudGVyIHBhcnQKKyAgICAgICAgaW50IGdyZWF0ID0gcmlnaHQgLSAxOyAvLyBUaGUgaW5kZXggYmVmb3JlIGZpcnN0IGVsZW1lbnQgb2YgcmlnaHQgcGFydAorCisgICAgICAgIGJvb2xlYW4gcGl2b3RzRGlmZmVyID0gKHBpdm90MSAhPSBwaXZvdDIpOworCisgICAgICAgIGlmIChwaXZvdHNEaWZmZXIpIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBQYXJ0aXRpb25pbmc6CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogICBsZWZ0IHBhcnQgICAgICAgICBjZW50ZXIgcGFydCAgICAgICAgICAgICAgICAgICAgcmlnaHQgcGFydAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqIHwgPCBwaXZvdDEgIHwgIHBpdm90MSA8PSAmJiA8PSBwaXZvdDIgIHwgICAgPyAgICB8ICA+IHBpdm90MiB8CisgICAgICAgICAgICAgKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKworICAgICAgICAgICAgICogICAgICAgICAgICAgIF4gICAgICAgICAgICAgICAgICAgICAgICAgIF4gICAgICAgXgorICAgICAgICAgICAgICogICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgfAorICAgICAgICAgICAgICogICAgICAgICAgICAgbGVzcyAgICAgICAgICAgICAgICAgICAgICAgIGsgICAgIGdyZWF0CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogSW52YXJpYW50czoKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgYWxsIGluIChsZWZ0LCBsZXNzKSAgIDwgcGl2b3QxCisgICAgICAgICAgICAgKiAgICBwaXZvdDEgPD0gYWxsIGluIFtsZXNzLCBrKSAgICAgPD0gcGl2b3QyCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgYWxsIGluIChncmVhdCwgcmlnaHQpID4gcGl2b3QyCisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogUG9pbnRlciBrIGlzIHRoZSBmaXJzdCBpbmRleCBvZiA/LXBhcnQKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgb3V0ZXI6CisgICAgICAgICAgICBmb3IgKGludCBrID0gbGVzczsgayA8PSBncmVhdDsgaysrKSB7CisgICAgICAgICAgICAgICAgY2hhciBhayA9IGFba107CisgICAgICAgICAgICAgICAgaWYgKGFrIDwgcGl2b3QxKSB7IC8vIE1vdmUgYVtrXSB0byBsZWZ0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgaWYgKGsgIT0gbGVzcykgeworICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbbGVzc107CisgICAgICAgICAgICAgICAgICAgICAgICBhW2xlc3NdID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgbGVzcysrOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYWsgPiBwaXZvdDIpIHsgLy8gTW92ZSBhW2tdIHRvIHJpZ2h0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGFbZ3JlYXRdID4gcGl2b3QyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ3JlYXQtLSA9PSBrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKGFbZ3JlYXRdIDwgcGl2b3QxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtsZXNzXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbbGVzcysrXSA9IGFbZ3JlYXRdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtncmVhdC0tXSA9IGFrOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBwaXZvdDEgPD0gYVtncmVhdF0gPD0gcGl2b3QyCisgICAgICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtncmVhdF07CisgICAgICAgICAgICAgICAgICAgICAgICBhW2dyZWF0LS1dID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7IC8vIFBpdm90cyBhcmUgZXF1YWwKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBQYXJ0aXRpb24gZGVnZW5lcmF0ZXMgdG8gdGhlIHRyYWRpdGlvbmFsIDMtd2F5LAorICAgICAgICAgICAgICogb3IgIkR1dGNoIE5hdGlvbmFsIEZsYWciLCBwYXJ0aXRpb246CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogICBsZWZ0IHBhcnQgICBjZW50ZXIgcGFydCAgICAgICAgICAgIHJpZ2h0IHBhcnQKKyAgICAgICAgICAgICAqICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKworICAgICAgICAgICAgICogfCAgPCBwaXZvdCAgfCAgPT0gcGl2b3QgIHwgICAgPyAgICB8ICA+IHBpdm90ICB8CisgICAgICAgICAgICAgKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBeICAgICAgICAgICAgXiAgICAgICBeCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgfCAgICAgICAgICAgIHwgICAgICAgfAorICAgICAgICAgICAgICogICAgICAgICAgICAgbGVzcyAgICAgICAgICBrICAgICBncmVhdAorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIEludmFyaWFudHM6CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogICBhbGwgaW4gKGxlZnQsIGxlc3MpICAgPCBwaXZvdAorICAgICAgICAgICAgICogICBhbGwgaW4gW2xlc3MsIGspICAgICA9PSBwaXZvdAorICAgICAgICAgICAgICogICBhbGwgaW4gKGdyZWF0LCByaWdodCkgPiBwaXZvdAorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIFBvaW50ZXIgayBpcyB0aGUgZmlyc3QgaW5kZXggb2YgPy1wYXJ0CisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGZvciAoaW50IGsgPSBsZXNzOyBrIDw9IGdyZWF0OyBrKyspIHsKKyAgICAgICAgICAgICAgICBjaGFyIGFrID0gYVtrXTsKKyAgICAgICAgICAgICAgICBpZiAoYWsgPT0gcGl2b3QxKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoYWsgPCBwaXZvdDEpIHsgLy8gTW92ZSBhW2tdIHRvIGxlZnQgcGFydAorICAgICAgICAgICAgICAgICAgICBpZiAoayAhPSBsZXNzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtsZXNzXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbbGVzc10gPSBhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBsZXNzKys7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gKGFba10gPiBwaXZvdDEpIC0gIE1vdmUgYVtrXSB0byByaWdodCBwYXJ0CisgICAgICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICAgICAqIFdlIGtub3cgdGhhdCBwaXZvdDEgPT0gYVtlM10gPT0gcGl2b3QyLiBUaHVzLCB3ZSBrbm93CisgICAgICAgICAgICAgICAgICAgICAqIHRoYXQgZ3JlYXQgd2lsbCBzdGlsbCBiZSA+PSBrIHdoZW4gdGhlIGZvbGxvd2luZyBsb29wCisgICAgICAgICAgICAgICAgICAgICAqIHRlcm1pbmF0ZXMsIGV2ZW4gdGhvdWdoIHdlIGRvbid0IHRlc3QgZm9yIGl0IGV4cGxpY2l0bHkuCisgICAgICAgICAgICAgICAgICAgICAqIEluIG90aGVyIHdvcmRzLCBhW2UzXSBhY3RzIGFzIGEgc2VudGluZWwgZm9yIGdyZWF0LgorICAgICAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGFbZ3JlYXRdID4gcGl2b3QxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBncmVhdC0tOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChhW2dyZWF0XSA8IHBpdm90MSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbbGVzc107CisgICAgICAgICAgICAgICAgICAgICAgICBhW2xlc3MrK10gPSBhW2dyZWF0XTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbZ3JlYXQtLV0gPSBhazsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gYVtncmVhdF0gPT0gcGl2b3QxCisgICAgICAgICAgICAgICAgICAgICAgICBhW2tdID0gcGl2b3QxOworICAgICAgICAgICAgICAgICAgICAgICAgYVtncmVhdC0tXSA9IGFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gU3dhcCBwaXZvdHMgaW50byB0aGVpciBmaW5hbCBwb3NpdGlvbnMKKyAgICAgICAgYVtsZWZ0XSAgPSBhW2xlc3MgIC0gMV07IGFbbGVzcyAgLSAxXSA9IHBpdm90MTsKKyAgICAgICAgYVtyaWdodF0gPSBhW2dyZWF0ICsgMV07IGFbZ3JlYXQgKyAxXSA9IHBpdm90MjsKKworICAgICAgICAvLyBTb3J0IGxlZnQgYW5kIHJpZ2h0IHBhcnRzIHJlY3Vyc2l2ZWx5LCBleGNsdWRpbmcga25vd24gcGl2b3QgdmFsdWVzCisgICAgICAgIGRvU29ydChhLCBsZWZ0LCAgIGxlc3MgLSAyKTsKKyAgICAgICAgZG9Tb3J0KGEsIGdyZWF0ICsgMiwgcmlnaHQpOworCisgICAgICAgIC8qCisgICAgICAgICAqIElmIHBpdm90MSA9PSBwaXZvdDIsIGFsbCBlbGVtZW50cyBmcm9tIGNlbnRlcgorICAgICAgICAgKiBwYXJ0IGFyZSBlcXVhbCBhbmQsIHRoZXJlZm9yZSwgYWxyZWFkeSBzb3J0ZWQKKyAgICAgICAgICovCisgICAgICAgIGlmICghcGl2b3RzRGlmZmVyKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBJZiBjZW50ZXIgcGFydCBpcyB0b28gbGFyZ2UgKGNvbXByaXNlcyA+IDIvMyBvZiB0aGUgYXJyYXkpLAorICAgICAgICAgKiBzd2FwIGludGVybmFsIHBpdm90IHZhbHVlcyB0byBlbmRzCisgICAgICAgICAqLworICAgICAgICBpZiAobGVzcyA8IGUxICYmIGdyZWF0ID4gZTUpIHsKKyAgICAgICAgICAgIHdoaWxlIChhW2xlc3NdID09IHBpdm90MSkgeworICAgICAgICAgICAgICAgIGxlc3MrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHdoaWxlIChhW2dyZWF0XSA9PSBwaXZvdDIpIHsKKyAgICAgICAgICAgICAgICBncmVhdC0tOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogUGFydGl0aW9uaW5nOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqICAgbGVmdCBwYXJ0ICAgICAgIGNlbnRlciBwYXJ0ICAgICAgICAgICAgICAgICAgIHJpZ2h0IHBhcnQKKyAgICAgICAgICAgICAqICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKworICAgICAgICAgICAgICogfCA9PSBwaXZvdDEgfCAgcGl2b3QxIDwgJiYgPCBwaXZvdDIgIHwgICAgPyAgICB8ID09IHBpdm90MiB8CisgICAgICAgICAgICAgKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBeICAgICAgICAgICAgICAgICAgICAgICAgXiAgICAgICBeCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgfAorICAgICAgICAgICAgICogICAgICAgICAgICAgbGVzcyAgICAgICAgICAgICAgICAgICAgICBrICAgICBncmVhdAorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIEludmFyaWFudHM6CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogICAgICAgICAgICAgIGFsbCBpbiAoKiwgbGVzcykgID09IHBpdm90MQorICAgICAgICAgICAgICogICAgIHBpdm90MSA8IGFsbCBpbiBbbGVzcywgaykgICA8IHBpdm90MgorICAgICAgICAgICAgICogICAgICAgICAgICAgIGFsbCBpbiAoZ3JlYXQsICopID09IHBpdm90MgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIFBvaW50ZXIgayBpcyB0aGUgZmlyc3QgaW5kZXggb2YgPy1wYXJ0CisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIG91dGVyOgorICAgICAgICAgICAgZm9yIChpbnQgayA9IGxlc3M7IGsgPD0gZ3JlYXQ7IGsrKykgeworICAgICAgICAgICAgICAgIGNoYXIgYWsgPSBhW2tdOworICAgICAgICAgICAgICAgIGlmIChhayA9PSBwaXZvdDIpIHsgLy8gTW92ZSBhW2tdIHRvIHJpZ2h0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGFbZ3JlYXRdID09IHBpdm90MikgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdyZWF0LS0gPT0gaykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChhW2dyZWF0XSA9PSBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2xlc3NdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtsZXNzKytdID0gcGl2b3QxOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBwaXZvdDEgPCBhW2dyZWF0XSA8IHBpdm90MgorICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbZ3JlYXRdOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGFbZ3JlYXQtLV0gPSBwaXZvdDI7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhayA9PSBwaXZvdDEpIHsgLy8gTW92ZSBhW2tdIHRvIGxlZnQgcGFydAorICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtsZXNzXTsKKyAgICAgICAgICAgICAgICAgICAgYVtsZXNzKytdID0gcGl2b3QxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFNvcnQgY2VudGVyIHBhcnQgcmVjdXJzaXZlbHksIGV4Y2x1ZGluZyBrbm93biBwaXZvdCB2YWx1ZXMKKyAgICAgICAgZG9Tb3J0KGEsIGxlc3MsIGdyZWF0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIGFycmF5IGludG8gYXNjZW5kaW5nIG51bWVyaWNhbCBvcmRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSB0byBiZSBzb3J0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc29ydChieXRlW10gYSkgeworICAgICAgICBkb1NvcnQoYSwgMCwgYS5sZW5ndGggLSAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIHRoZSBhcnJheSBpbnRvIGFzY2VuZGluZyBvcmRlci4gVGhlIHJhbmdlCisgICAgICogdG8gYmUgc29ydGVkIGV4dGVuZHMgZnJvbSB0aGUgaW5kZXgge0Bjb2RlIGZyb21JbmRleH0sIGluY2x1c2l2ZSwgdG8KKyAgICAgKiB0aGUgaW5kZXgge0Bjb2RlIHRvSW5kZXh9LCBleGNsdXNpdmUuIElmIHtAY29kZSBmcm9tSW5kZXggPT0gdG9JbmRleH0sCisgICAgICogdGhlIHJhbmdlIHRvIGJlIHNvcnRlZCBpcyBlbXB0eSAoYW5kIHRoZSBjYWxsIGlzIGEgbm8tb3ApLgorICAgICAqCisgICAgICogQHBhcmFtIGEgdGhlIGFycmF5IHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSBmcm9tSW5kZXggdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSB0b0luZGV4IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBlbGVtZW50LCBleGNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBmcm9tSW5kZXggPiB0b0luZGV4fQorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgIGlmIHtAY29kZSBmcm9tSW5kZXggPCAwfSBvciB7QGNvZGUgdG9JbmRleCA+IGEubGVuZ3RofQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzb3J0KGJ5dGVbXSBhLCBpbnQgZnJvbUluZGV4LCBpbnQgdG9JbmRleCkgeworICAgICAgICBBcnJheXMuY2hlY2tTdGFydEFuZEVuZChhLmxlbmd0aCwgZnJvbUluZGV4LCB0b0luZGV4KTsKKyAgICAgICAgZG9Tb3J0KGEsIGZyb21JbmRleCwgdG9JbmRleCAtIDEpOworICAgIH0KKworICAgIC8qKiBUaGUgbnVtYmVyIG9mIGRpc3RpbmN0IGJ5dGUgdmFsdWVzLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOVU1fQllURV9WQUxVRVMgPSAxIDw8IDg7CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIHRoZSBhcnJheSBpbnRvIGFzY2VuZGluZyBvcmRlci4gVGhpcworICAgICAqIG1ldGhvZCBkaWZmZXJzIGZyb20gdGhlIHB1YmxpYyB7QGNvZGUgc29ydH0gbWV0aG9kIGluIHRoYXQgdGhlCisgICAgICoge0Bjb2RlIHJpZ2h0fSBpbmRleCBpcyBpbmNsdXNpdmUsIGFuZCBpdCBkb2VzIG5vIHJhbmdlIGNoZWNraW5nIG9uCisgICAgICoge0Bjb2RlIGxlZnR9IG9yIHtAY29kZSByaWdodH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIGxlZnQgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSByaWdodCB0aGUgaW5kZXggb2YgdGhlIGxhc3QgZWxlbWVudCwgaW5jbHVzaXZlLCB0byBiZSBzb3J0ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGRvU29ydChieXRlW10gYSwgaW50IGxlZnQsIGludCByaWdodCkgeworICAgICAgICAvLyBVc2UgaW5zZXJ0aW9uIHNvcnQgb24gdGlueSBhcnJheXMKKyAgICAgICAgaWYgKHJpZ2h0IC0gbGVmdCArIDEgPCBJTlNFUlRJT05fU09SVF9USFJFU0hPTEQpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBsZWZ0ICsgMTsgaSA8PSByaWdodDsgaSsrKSB7CisgICAgICAgICAgICAgICAgYnl0ZSBhaSA9IGFbaV07CisgICAgICAgICAgICAgICAgaW50IGo7CisgICAgICAgICAgICAgICAgZm9yIChqID0gaSAtIDE7IGogPj0gbGVmdCAmJiBhaSA8IGFbal07IGotLSkgeworICAgICAgICAgICAgICAgICAgICBhW2ogKyAxXSA9IGFbal07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFbaiArIDFdID0gYWk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAocmlnaHQgLSBsZWZ0ICsgMSA+IENPVU5USU5HX1NPUlRfVEhSRVNIT0xEX0ZPUl9CWVRFKSB7CisgICAgICAgICAgICAvLyBVc2UgY291bnRpbmcgc29ydCBvbiBodWdlIGFycmF5cworICAgICAgICAgICAgaW50W10gY291bnQgPSBuZXcgaW50W05VTV9CWVRFX1ZBTFVFU107CisKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBsZWZ0OyBpIDw9IHJpZ2h0OyBpKyspIHsKKyAgICAgICAgICAgICAgICBjb3VudFthW2ldIC0gQnl0ZS5NSU5fVkFMVUVdKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgayA9IGxlZnQ7IGkgPCBjb3VudC5sZW5ndGggJiYgayA8PSByaWdodDsgaSsrKSB7CisgICAgICAgICAgICAgICAgYnl0ZSB2YWx1ZSA9IChieXRlKSAoaSArIEJ5dGUuTUlOX1ZBTFVFKTsKKworICAgICAgICAgICAgICAgIGZvciAoaW50IHMgPSBjb3VudFtpXTsgcyA+IDA7IHMtLSkgeworICAgICAgICAgICAgICAgICAgICBhW2srK10gPSB2YWx1ZTsKKyAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsgLy8gVXNlIER1YWwtUGl2b3QgUXVpY2tzb3J0IG9uIGxhcmdlIGFycmF5cworICAgICAgICAgICAgZHVhbFBpdm90UXVpY2tzb3J0KGEsIGxlZnQsIHJpZ2h0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhlIGFycmF5IGludG8gYXNjZW5kaW5nIG9yZGVyIGJ5IHRoZQorICAgICAqIER1YWwtUGl2b3QgUXVpY2tzb3J0IGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gbGVmdCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQsIGluY2x1c2l2ZSwgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIHJpZ2h0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZHVhbFBpdm90UXVpY2tzb3J0KGJ5dGVbXSBhLCBpbnQgbGVmdCwgaW50IHJpZ2h0KSB7CisgICAgICAgIC8vIENvbXB1dGUgaW5kaWNlcyBvZiBmaXZlIGV2ZW5seSBzcGFjZWQgZWxlbWVudHMKKyAgICAgICAgaW50IHNpeHRoID0gKHJpZ2h0IC0gbGVmdCArIDEpIC8gNjsKKyAgICAgICAgaW50IGUxID0gbGVmdCAgKyBzaXh0aDsKKyAgICAgICAgaW50IGU1ID0gcmlnaHQgLSBzaXh0aDsKKyAgICAgICAgaW50IGUzID0gKGxlZnQgKyByaWdodCkgPj4+IDE7IC8vIFRoZSBtaWRwb2ludAorICAgICAgICBpbnQgZTQgPSBlMyArIHNpeHRoOworICAgICAgICBpbnQgZTIgPSBlMyAtIHNpeHRoOworCisgICAgICAgIC8vIFNvcnQgdGhlc2UgZWxlbWVudHMgdXNpbmcgYSA1LWVsZW1lbnQgc29ydGluZyBuZXR3b3JrCisgICAgICAgIGJ5dGUgYWUxID0gYVtlMV0sIGFlMiA9IGFbZTJdLCBhZTMgPSBhW2UzXSwgYWU0ID0gYVtlNF0sIGFlNSA9IGFbZTVdOworCisgICAgICAgIGlmIChhZTEgPiBhZTIpIHsgYnl0ZSB0ID0gYWUxOyBhZTEgPSBhZTI7IGFlMiA9IHQ7IH0KKyAgICAgICAgaWYgKGFlNCA+IGFlNSkgeyBieXRlIHQgPSBhZTQ7IGFlNCA9IGFlNTsgYWU1ID0gdDsgfQorICAgICAgICBpZiAoYWUxID4gYWUzKSB7IGJ5dGUgdCA9IGFlMTsgYWUxID0gYWUzOyBhZTMgPSB0OyB9CisgICAgICAgIGlmIChhZTIgPiBhZTMpIHsgYnl0ZSB0ID0gYWUyOyBhZTIgPSBhZTM7IGFlMyA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMSA+IGFlNCkgeyBieXRlIHQgPSBhZTE7IGFlMSA9IGFlNDsgYWU0ID0gdDsgfQorICAgICAgICBpZiAoYWUzID4gYWU0KSB7IGJ5dGUgdCA9IGFlMzsgYWUzID0gYWU0OyBhZTQgPSB0OyB9CisgICAgICAgIGlmIChhZTIgPiBhZTUpIHsgYnl0ZSB0ID0gYWUyOyBhZTIgPSBhZTU7IGFlNSA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMiA+IGFlMykgeyBieXRlIHQgPSBhZTI7IGFlMiA9IGFlMzsgYWUzID0gdDsgfQorICAgICAgICBpZiAoYWU0ID4gYWU1KSB7IGJ5dGUgdCA9IGFlNDsgYWU0ID0gYWU1OyBhZTUgPSB0OyB9CisKKyAgICAgICAgYVtlMV0gPSBhZTE7IGFbZTNdID0gYWUzOyBhW2U1XSA9IGFlNTsKKworICAgICAgICAvKgorICAgICAgICAgKiBVc2UgdGhlIHNlY29uZCBhbmQgZm91cnRoIG9mIHRoZSBmaXZlIHNvcnRlZCBlbGVtZW50cyBhcyBwaXZvdHMuCisgICAgICAgICAqIFRoZXNlIHZhbHVlcyBhcmUgaW5leHBlbnNpdmUgYXBwcm94aW1hdGlvbnMgb2YgdGhlIGZpcnN0IGFuZAorICAgICAgICAgKiBzZWNvbmQgdGVyY2lsZXMgb2YgdGhlIGFycmF5LiBOb3RlIHRoYXQgcGl2b3QxIDw9IHBpdm90Mi4KKyAgICAgICAgICoKKyAgICAgICAgICogVGhlIHBpdm90cyBhcmUgc3RvcmVkIGluIGxvY2FsIHZhcmlhYmxlcywgYW5kIHRoZSBmaXJzdCBhbmQKKyAgICAgICAgICogdGhlIGxhc3Qgb2YgdGhlIGVsZW1lbnRzIHRvIGJlIHNvcnRlZCBhcmUgbW92ZWQgdG8gdGhlIGxvY2F0aW9ucworICAgICAgICAgKiBmb3JtZXJseSBvY2N1cGllZCBieSB0aGUgcGl2b3RzLiBXaGVuIHBhcnRpdGlvbmluZyBpcyBjb21wbGV0ZSwKKyAgICAgICAgICogdGhlIHBpdm90cyBhcmUgc3dhcHBlZCBiYWNrIGludG8gdGhlaXIgZmluYWwgcG9zaXRpb25zLCBhbmQKKyAgICAgICAgICogZXhjbHVkZWQgZnJvbSBzdWJzZXF1ZW50IHNvcnRpbmcuCisgICAgICAgICAqLworICAgICAgICBieXRlIHBpdm90MSA9IGFlMjsgYVtlMl0gPSBhW2xlZnRdOworICAgICAgICBieXRlIHBpdm90MiA9IGFlNDsgYVtlNF0gPSBhW3JpZ2h0XTsKKworICAgICAgICAvLyBQb2ludGVycworICAgICAgICBpbnQgbGVzcyAgPSBsZWZ0ICArIDE7IC8vIFRoZSBpbmRleCBvZiBmaXJzdCBlbGVtZW50IG9mIGNlbnRlciBwYXJ0CisgICAgICAgIGludCBncmVhdCA9IHJpZ2h0IC0gMTsgLy8gVGhlIGluZGV4IGJlZm9yZSBmaXJzdCBlbGVtZW50IG9mIHJpZ2h0IHBhcnQKKworICAgICAgICBib29sZWFuIHBpdm90c0RpZmZlciA9IChwaXZvdDEgIT0gcGl2b3QyKTsKKworICAgICAgICBpZiAocGl2b3RzRGlmZmVyKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogUGFydGl0aW9uaW5nOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqICAgbGVmdCBwYXJ0ICAgICAgICAgY2VudGVyIHBhcnQgICAgICAgICAgICAgICAgICAgIHJpZ2h0IHBhcnQKKyAgICAgICAgICAgICAqICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCisgICAgICAgICAgICAgKiB8IDwgcGl2b3QxICB8ICBwaXZvdDEgPD0gJiYgPD0gcGl2b3QyICB8ICAgID8gICAgfCAgPiBwaXZvdDIgfAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBeICAgICAgICAgICAgICAgICAgICAgICAgICBeICAgICAgIF4KKyAgICAgICAgICAgICAqICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgIHwKKyAgICAgICAgICAgICAqICAgICAgICAgICAgIGxlc3MgICAgICAgICAgICAgICAgICAgICAgICBrICAgICBncmVhdAorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIEludmFyaWFudHM6CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogICAgICAgICAgICAgIGFsbCBpbiAobGVmdCwgbGVzcykgICA8IHBpdm90MQorICAgICAgICAgICAgICogICAgcGl2b3QxIDw9IGFsbCBpbiBbbGVzcywgaykgICAgIDw9IHBpdm90MgorICAgICAgICAgICAgICogICAgICAgICAgICAgIGFsbCBpbiAoZ3JlYXQsIHJpZ2h0KSA+IHBpdm90MgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIFBvaW50ZXIgayBpcyB0aGUgZmlyc3QgaW5kZXggb2YgPy1wYXJ0CisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIG91dGVyOgorICAgICAgICAgICAgZm9yIChpbnQgayA9IGxlc3M7IGsgPD0gZ3JlYXQ7IGsrKykgeworICAgICAgICAgICAgICAgIGJ5dGUgYWsgPSBhW2tdOworICAgICAgICAgICAgICAgIGlmIChhayA8IHBpdm90MSkgeyAvLyBNb3ZlIGFba10gdG8gbGVmdCBwYXJ0CisgICAgICAgICAgICAgICAgICAgIGlmIChrICE9IGxlc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2xlc3NdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtsZXNzXSA9IGFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGxlc3MrKzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFrID4gcGl2b3QyKSB7IC8vIE1vdmUgYVtrXSB0byByaWdodCBwYXJ0CisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChhW2dyZWF0XSA+IHBpdm90MikgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdyZWF0LS0gPT0gaykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChhW2dyZWF0XSA8IHBpdm90MSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbbGVzc107CisgICAgICAgICAgICAgICAgICAgICAgICBhW2xlc3MrK10gPSBhW2dyZWF0XTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbZ3JlYXQtLV0gPSBhazsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gcGl2b3QxIDw9IGFbZ3JlYXRdIDw9IHBpdm90MgorICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbZ3JlYXRdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtncmVhdC0tXSA9IGFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeyAvLyBQaXZvdHMgYXJlIGVxdWFsCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogUGFydGl0aW9uIGRlZ2VuZXJhdGVzIHRvIHRoZSB0cmFkaXRpb25hbCAzLXdheSwKKyAgICAgICAgICAgICAqIG9yICJEdXRjaCBOYXRpb25hbCBGbGFnIiwgcGFydGl0aW9uOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqICAgbGVmdCBwYXJ0ICAgY2VudGVyIHBhcnQgICAgICAgICAgICByaWdodCBwYXJ0CisgICAgICAgICAgICAgKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqIHwgIDwgcGl2b3QgIHwgID09IHBpdm90ICB8ICAgID8gICAgfCAgPiBwaXZvdCAgfAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgXiAgICAgICAgICAgIF4gICAgICAgXgorICAgICAgICAgICAgICogICAgICAgICAgICAgIHwgICAgICAgICAgICB8ICAgICAgIHwKKyAgICAgICAgICAgICAqICAgICAgICAgICAgIGxlc3MgICAgICAgICAgayAgICAgZ3JlYXQKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBJbnZhcmlhbnRzOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqICAgYWxsIGluIChsZWZ0LCBsZXNzKSAgIDwgcGl2b3QKKyAgICAgICAgICAgICAqICAgYWxsIGluIFtsZXNzLCBrKSAgICAgPT0gcGl2b3QKKyAgICAgICAgICAgICAqICAgYWxsIGluIChncmVhdCwgcmlnaHQpID4gcGl2b3QKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBQb2ludGVyIGsgaXMgdGhlIGZpcnN0IGluZGV4IG9mID8tcGFydAorICAgICAgICAgICAgICovCisgICAgICAgICAgICBmb3IgKGludCBrID0gbGVzczsgayA8PSBncmVhdDsgaysrKSB7CisgICAgICAgICAgICAgICAgYnl0ZSBhayA9IGFba107CisgICAgICAgICAgICAgICAgaWYgKGFrID09IHBpdm90MSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGFrIDwgcGl2b3QxKSB7IC8vIE1vdmUgYVtrXSB0byBsZWZ0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgaWYgKGsgIT0gbGVzcykgeworICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbbGVzc107CisgICAgICAgICAgICAgICAgICAgICAgICBhW2xlc3NdID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgbGVzcysrOworICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIChhW2tdID4gcGl2b3QxKSAtICBNb3ZlIGFba10gdG8gcmlnaHQgcGFydAorICAgICAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAgICAgKiBXZSBrbm93IHRoYXQgcGl2b3QxID09IGFbZTNdID09IHBpdm90Mi4gVGh1cywgd2Uga25vdworICAgICAgICAgICAgICAgICAgICAgKiB0aGF0IGdyZWF0IHdpbGwgc3RpbGwgYmUgPj0gayB3aGVuIHRoZSBmb2xsb3dpbmcgbG9vcAorICAgICAgICAgICAgICAgICAgICAgKiB0ZXJtaW5hdGVzLCBldmVuIHRob3VnaCB3ZSBkb24ndCB0ZXN0IGZvciBpdCBleHBsaWNpdGx5LgorICAgICAgICAgICAgICAgICAgICAgKiBJbiBvdGhlciB3b3JkcywgYVtlM10gYWN0cyBhcyBhIHNlbnRpbmVsIGZvciBncmVhdC4KKyAgICAgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChhW2dyZWF0XSA+IHBpdm90MSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZ3JlYXQtLTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoYVtncmVhdF0gPCBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2xlc3NdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtsZXNzKytdID0gYVtncmVhdF07CisgICAgICAgICAgICAgICAgICAgICAgICBhW2dyZWF0LS1dID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIGFbZ3JlYXRdID09IHBpdm90MQorICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IHBpdm90MTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbZ3JlYXQtLV0gPSBhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFN3YXAgcGl2b3RzIGludG8gdGhlaXIgZmluYWwgcG9zaXRpb25zCisgICAgICAgIGFbbGVmdF0gID0gYVtsZXNzICAtIDFdOyBhW2xlc3MgIC0gMV0gPSBwaXZvdDE7CisgICAgICAgIGFbcmlnaHRdID0gYVtncmVhdCArIDFdOyBhW2dyZWF0ICsgMV0gPSBwaXZvdDI7CisKKyAgICAgICAgLy8gU29ydCBsZWZ0IGFuZCByaWdodCBwYXJ0cyByZWN1cnNpdmVseSwgZXhjbHVkaW5nIGtub3duIHBpdm90IHZhbHVlcworICAgICAgICBkb1NvcnQoYSwgbGVmdCwgICBsZXNzIC0gMik7CisgICAgICAgIGRvU29ydChhLCBncmVhdCArIDIsIHJpZ2h0KTsKKworICAgICAgICAvKgorICAgICAgICAgKiBJZiBwaXZvdDEgPT0gcGl2b3QyLCBhbGwgZWxlbWVudHMgZnJvbSBjZW50ZXIKKyAgICAgICAgICogcGFydCBhcmUgZXF1YWwgYW5kLCB0aGVyZWZvcmUsIGFscmVhZHkgc29ydGVkCisgICAgICAgICAqLworICAgICAgICBpZiAoIXBpdm90c0RpZmZlcikgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogSWYgY2VudGVyIHBhcnQgaXMgdG9vIGxhcmdlIChjb21wcmlzZXMgPiAyLzMgb2YgdGhlIGFycmF5KSwKKyAgICAgICAgICogc3dhcCBpbnRlcm5hbCBwaXZvdCB2YWx1ZXMgdG8gZW5kcworICAgICAgICAgKi8KKyAgICAgICAgaWYgKGxlc3MgPCBlMSAmJiBncmVhdCA+IGU1KSB7CisgICAgICAgICAgICB3aGlsZSAoYVtsZXNzXSA9PSBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICBsZXNzKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB3aGlsZSAoYVtncmVhdF0gPT0gcGl2b3QyKSB7CisgICAgICAgICAgICAgICAgZ3JlYXQtLTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFBhcnRpdGlvbmluZzoKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiAgIGxlZnQgcGFydCAgICAgICBjZW50ZXIgcGFydCAgICAgICAgICAgICAgICAgICByaWdodCBwYXJ0CisgICAgICAgICAgICAgKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqIHwgPT0gcGl2b3QxIHwgIHBpdm90MSA8ICYmIDwgcGl2b3QyICB8ICAgID8gICAgfCA9PSBwaXZvdDIgfAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgXiAgICAgICAgICAgICAgICAgICAgICAgIF4gICAgICAgXgorICAgICAgICAgICAgICogICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgIHwKKyAgICAgICAgICAgICAqICAgICAgICAgICAgIGxlc3MgICAgICAgICAgICAgICAgICAgICAgayAgICAgZ3JlYXQKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBJbnZhcmlhbnRzOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBhbGwgaW4gKCosIGxlc3MpICA9PSBwaXZvdDEKKyAgICAgICAgICAgICAqICAgICBwaXZvdDEgPCBhbGwgaW4gW2xlc3MsIGspICAgPCBwaXZvdDIKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBhbGwgaW4gKGdyZWF0LCAqKSA9PSBwaXZvdDIKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBQb2ludGVyIGsgaXMgdGhlIGZpcnN0IGluZGV4IG9mID8tcGFydAorICAgICAgICAgICAgICovCisgICAgICAgICAgICBvdXRlcjoKKyAgICAgICAgICAgIGZvciAoaW50IGsgPSBsZXNzOyBrIDw9IGdyZWF0OyBrKyspIHsKKyAgICAgICAgICAgICAgICBieXRlIGFrID0gYVtrXTsKKyAgICAgICAgICAgICAgICBpZiAoYWsgPT0gcGl2b3QyKSB7IC8vIE1vdmUgYVtrXSB0byByaWdodCBwYXJ0CisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChhW2dyZWF0XSA9PSBwaXZvdDIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChncmVhdC0tID09IGspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoYVtncmVhdF0gPT0gcGl2b3QxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtsZXNzXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbbGVzcysrXSA9IHBpdm90MTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gcGl2b3QxIDwgYVtncmVhdF0gPCBwaXZvdDIKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2dyZWF0XTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBhW2dyZWF0LS1dID0gcGl2b3QyOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYWsgPT0gcGl2b3QxKSB7IC8vIE1vdmUgYVtrXSB0byBsZWZ0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbbGVzc107CisgICAgICAgICAgICAgICAgICAgIGFbbGVzcysrXSA9IHBpdm90MTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBTb3J0IGNlbnRlciBwYXJ0IHJlY3Vyc2l2ZWx5LCBleGNsdWRpbmcga25vd24gcGl2b3QgdmFsdWVzCisgICAgICAgIGRvU29ydChhLCBsZXNzLCBncmVhdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCBhcnJheSBpbnRvIGFzY2VuZGluZyBudW1lcmljYWwgb3JkZXIuCisgICAgICoKKyAgICAgKiA8cD5UaGUge0Bjb2RlIDx9IHJlbGF0aW9uIGRvZXMgbm90IHByb3ZpZGUgYSB0b3RhbCBvcmRlciBvbiBhbGwgZmxvYXQKKyAgICAgKiB2YWx1ZXM6IHtAY29kZSAtMC4wZiA9PSAwLjBmfSBpcyB7QGNvZGUgdHJ1ZX0gYW5kIGEge0Bjb2RlIEZsb2F0Lk5hTn0KKyAgICAgKiB2YWx1ZSBjb21wYXJlcyBuZWl0aGVyIGxlc3MgdGhhbiwgZ3JlYXRlciB0aGFuLCBub3IgZXF1YWwgdG8gYW55IHZhbHVlLAorICAgICAqIGV2ZW4gaXRzZWxmLiBUaGlzIG1ldGhvZCB1c2VzIHRoZSB0b3RhbCBvcmRlciBpbXBvc2VkIGJ5IHRoZSBtZXRob2QKKyAgICAgKiB7QGxpbmsgRmxvYXQjY29tcGFyZVRvfToge0Bjb2RlIC0wLjBmfSBpcyB0cmVhdGVkIGFzIGxlc3MgdGhhbiB2YWx1ZQorICAgICAqIHtAY29kZSAwLjBmfSBhbmQge0Bjb2RlIEZsb2F0Lk5hTn0gaXMgY29uc2lkZXJlZCBncmVhdGVyIHRoYW4gYW55CisgICAgICogb3RoZXIgdmFsdWUgYW5kIGFsbCB7QGNvZGUgRmxvYXQuTmFOfSB2YWx1ZXMgYXJlIGNvbnNpZGVyZWQgZXF1YWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc29ydGVkCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNvcnQoZmxvYXRbXSBhKSB7CisgICAgICAgIHNvcnROZWdaZXJvQW5kTmFOKGEsIDAsIGEubGVuZ3RoIC0gMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCByYW5nZSBvZiB0aGUgYXJyYXkgaW50byBhc2NlbmRpbmcgb3JkZXIuIFRoZSByYW5nZQorICAgICAqIHRvIGJlIHNvcnRlZCBleHRlbmRzIGZyb20gdGhlIGluZGV4IHtAY29kZSBmcm9tSW5kZXh9LCBpbmNsdXNpdmUsIHRvCisgICAgICogdGhlIGluZGV4IHtAY29kZSB0b0luZGV4fSwgZXhjbHVzaXZlLiBJZiB7QGNvZGUgZnJvbUluZGV4ID09IHRvSW5kZXh9LAorICAgICAqIHRoZSByYW5nZSB0byBiZSBzb3J0ZWQgaXMgZW1wdHkgIGFuZCB0aGUgY2FsbCBpcyBhIG5vLW9wKS4KKyAgICAgKgorICAgICAqIDxwPlRoZSB7QGNvZGUgPH0gcmVsYXRpb24gZG9lcyBub3QgcHJvdmlkZSBhIHRvdGFsIG9yZGVyIG9uIGFsbCBmbG9hdAorICAgICAqIHZhbHVlczoge0Bjb2RlIC0wLjBmID09IDAuMGZ9IGlzIHtAY29kZSB0cnVlfSBhbmQgYSB7QGNvZGUgRmxvYXQuTmFOfQorICAgICAqIHZhbHVlIGNvbXBhcmVzIG5laXRoZXIgbGVzcyB0aGFuLCBncmVhdGVyIHRoYW4sIG5vciBlcXVhbCB0byBhbnkgdmFsdWUsCisgICAgICogZXZlbiBpdHNlbGYuIFRoaXMgbWV0aG9kIHVzZXMgdGhlIHRvdGFsIG9yZGVyIGltcG9zZWQgYnkgdGhlIG1ldGhvZAorICAgICAqIHtAbGluayBGbG9hdCNjb21wYXJlVG99OiB7QGNvZGUgLTAuMGZ9IGlzIHRyZWF0ZWQgYXMgbGVzcyB0aGFuIHZhbHVlCisgICAgICoge0Bjb2RlIDAuMGZ9IGFuZCB7QGNvZGUgRmxvYXQuTmFOfSBpcyBjb25zaWRlcmVkIGdyZWF0ZXIgdGhhbiBhbnkKKyAgICAgKiBvdGhlciB2YWx1ZSBhbmQgYWxsIHtAY29kZSBGbG9hdC5OYU59IHZhbHVlcyBhcmUgY29uc2lkZXJlZCBlcXVhbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gZnJvbUluZGV4IHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgZWxlbWVudCwgaW5jbHVzaXZlLCB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gdG9JbmRleCB0aGUgaW5kZXggb2YgdGhlIGxhc3QgZWxlbWVudCwgZXhjbHVzaXZlLCB0byBiZSBzb3J0ZWQKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgZnJvbUluZGV4ID4gdG9JbmRleH0KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICBpZiB7QGNvZGUgZnJvbUluZGV4IDwgMH0gb3Ige0Bjb2RlIHRvSW5kZXggPiBhLmxlbmd0aH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc29ydChmbG9hdFtdIGEsIGludCBmcm9tSW5kZXgsIGludCB0b0luZGV4KSB7CisgICAgICAgIEFycmF5cy5jaGVja1N0YXJ0QW5kRW5kKGEubGVuZ3RoLCBmcm9tSW5kZXgsIHRvSW5kZXgpOworICAgICAgICBzb3J0TmVnWmVyb0FuZE5hTihhLCBmcm9tSW5kZXgsIHRvSW5kZXggLSAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIHRoZSBhcnJheSBpbnRvIGFzY2VuZGluZyBvcmRlci4gVGhlCisgICAgICogc29ydCBpcyBkb25lIGluIHRocmVlIHBoYXNlcyB0byBhdm9pZCBleHBlbnNpdmUgY29tcGFyaXNvbnMgaW4gdGhlCisgICAgICogaW5uZXIgbG9vcC4gVGhlIGNvbXBhcmlzb25zIHdvdWxkIGJlIGV4cGVuc2l2ZSBkdWUgdG8gYW5vbWFsaWVzCisgICAgICogYXNzb2NpYXRlZCB3aXRoIG5lZ2F0aXZlIHplcm8ge0Bjb2RlIC0wLjBmfSBhbmQge0Bjb2RlIEZsb2F0Lk5hTn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIGxlZnQgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSByaWdodCB0aGUgaW5kZXggb2YgdGhlIGxhc3QgZWxlbWVudCwgaW5jbHVzaXZlLCB0byBiZSBzb3J0ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHNvcnROZWdaZXJvQW5kTmFOKGZsb2F0W10gYSwgaW50IGxlZnQsIGludCByaWdodCkgeworICAgICAgICAvKgorICAgICAgICAgKiBQaGFzZSAxOiBDb3VudCBuZWdhdGl2ZSB6ZXJvcyBhbmQgbW92ZSBOYU5zIHRvIGVuZCBvZiBhcnJheQorICAgICAgICAgKi8KKyAgICAgICAgZmluYWwgaW50IE5FR0FUSVZFX1pFUk8gPSBGbG9hdC5mbG9hdFRvSW50Qml0cygtMC4wZik7CisgICAgICAgIGludCBudW1OZWdhdGl2ZVplcm9zID0gMDsKKyAgICAgICAgaW50IG4gPSByaWdodDsKKworICAgICAgICBmb3IgKGludCBrID0gbGVmdDsgayA8PSBuOyBrKyspIHsKKyAgICAgICAgICAgIGZsb2F0IGFrID0gYVtrXTsKKyAgICAgICAgICAgIGlmIChhayA9PSAwLjBmICYmIE5FR0FUSVZFX1pFUk8gPT0gRmxvYXQuZmxvYXRUb0ludEJpdHMoYWspKSB7CisgICAgICAgICAgICAgICAgYVtrXSA9IDAuMGY7CisgICAgICAgICAgICAgICAgbnVtTmVnYXRpdmVaZXJvcysrOworICAgICAgICAgICAgfSBlbHNlIGlmIChhayAhPSBhaykgeyAvLyBpLmUuLCBhayBpcyBOYU4KKyAgICAgICAgICAgICAgICBhW2stLV0gPSBhW25dOworICAgICAgICAgICAgICAgIGFbbi0tXSA9IEZsb2F0Lk5hTjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIFBoYXNlIDI6IFNvcnQgZXZlcnl0aGluZyBleGNlcHQgTmFOcyAod2hpY2ggYXJlIGFscmVhZHkgaW4gcGxhY2UpCisgICAgICAgICAqLworICAgICAgICBkb1NvcnQoYSwgbGVmdCwgbik7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogUGhhc2UgMzogVHVybiBwb3NpdGl2ZSB6ZXJvcyBiYWNrIGludG8gbmVnYXRpdmUgemVyb3MgYXMgYXBwcm9wcmlhdGUKKyAgICAgICAgICovCisgICAgICAgIGlmIChudW1OZWdhdGl2ZVplcm9zID09IDApIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEZpbmQgZmlyc3QgemVybyBlbGVtZW50CisgICAgICAgIGludCB6ZXJvSW5kZXggPSBmaW5kQW55WmVybyhhLCBsZWZ0LCBuKTsKKworICAgICAgICBmb3IgKGludCBpID0gemVyb0luZGV4IC0gMTsgaSA+PSBsZWZ0ICYmIGFbaV0gPT0gMC4wZjsgaS0tKSB7CisgICAgICAgICAgICB6ZXJvSW5kZXggPSBpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVHVybiB0aGUgcmlnaHQgbnVtYmVyIG9mIHBvc2l0aXZlIHplcm9zIGJhY2sgaW50byBuZWdhdGl2ZSB6ZXJvcworICAgICAgICBmb3IgKGludCBpID0gemVyb0luZGV4LCBtID0gemVyb0luZGV4ICsgbnVtTmVnYXRpdmVaZXJvczsgaSA8IG07IGkrKykgeworICAgICAgICAgICAgYVtpXSA9IC0wLjBmOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXggb2Ygc29tZSB6ZXJvIGVsZW1lbnQgaW4gdGhlIHNwZWNpZmllZCByYW5nZSB2aWEKKyAgICAgKiBiaW5hcnkgc2VhcmNoLiBUaGUgcmFuZ2UgaXMgYXNzdW1lZCB0byBiZSBzb3J0ZWQsIGFuZCBtdXN0IGNvbnRhaW4KKyAgICAgKiBhdCBsZWFzdCBvbmUgemVyby4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSB0byBiZSBzZWFyY2hlZAorICAgICAqIEBwYXJhbSBsb3cgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNlYXJjaGVkCisgICAgICogQHBhcmFtIGhpZ2ggdGhlIGluZGV4IG9mIHRoZSBsYXN0IGVsZW1lbnQsIGluY2x1c2l2ZSwgdG8gYmUgc2VhcmNoZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgZmluZEFueVplcm8oZmxvYXRbXSBhLCBpbnQgbG93LCBpbnQgaGlnaCkgeworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgaW50IG1pZGRsZSA9IChsb3cgKyBoaWdoKSA+Pj4gMTsKKyAgICAgICAgICAgIGZsb2F0IG1pZGRsZVZhbHVlID0gYVttaWRkbGVdOworCisgICAgICAgICAgICBpZiAobWlkZGxlVmFsdWUgPCAwLjBmKSB7CisgICAgICAgICAgICAgICAgbG93ID0gbWlkZGxlICsgMTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAobWlkZGxlVmFsdWUgPiAwLjBmKSB7CisgICAgICAgICAgICAgICAgaGlnaCA9IG1pZGRsZSAtIDE7CisgICAgICAgICAgICB9IGVsc2UgeyAvLyBtaWRkbGVWYWx1ZSA9PSAwLjBmCisgICAgICAgICAgICAgICAgcmV0dXJuIG1pZGRsZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhlIGFycmF5IGludG8gYXNjZW5kaW5nIG9yZGVyLiBUaGlzCisgICAgICogbWV0aG9kIGRpZmZlcnMgZnJvbSB0aGUgcHVibGljIHtAY29kZSBzb3J0fSBtZXRob2QgaW4gdGhyZWUgd2F5czoKKyAgICAgKiB7QGNvZGUgcmlnaHR9IGluZGV4IGlzIGluY2x1c2l2ZSwgaXQgZG9lcyBubyByYW5nZSBjaGVja2luZyBvbgorICAgICAqIHtAY29kZSBsZWZ0fSBvciB7QGNvZGUgcmlnaHR9LCBhbmQgaXQgZG9lcyBub3QgaGFuZGxlIG5lZ2F0aXZlCisgICAgICogemVyb3Mgb3IgTmFOcyBpbiB0aGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc29ydGVkLCB3aGljaCBtdXN0IG5vdCBjb250YWluIC0wLjBmIG9yIE5hTgorICAgICAqIEBwYXJhbSBsZWZ0IHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgZWxlbWVudCwgaW5jbHVzaXZlLCB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gcmlnaHQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IGVsZW1lbnQsIGluY2x1c2l2ZSwgdG8gYmUgc29ydGVkCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBkb1NvcnQoZmxvYXRbXSBhLCBpbnQgbGVmdCwgaW50IHJpZ2h0KSB7CisgICAgICAgIC8vIFVzZSBpbnNlcnRpb24gc29ydCBvbiB0aW55IGFycmF5cworICAgICAgICBpZiAocmlnaHQgLSBsZWZ0ICsgMSA8IElOU0VSVElPTl9TT1JUX1RIUkVTSE9MRCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IGxlZnQgKyAxOyBpIDw9IHJpZ2h0OyBpKyspIHsKKyAgICAgICAgICAgICAgICBmbG9hdCBhaSA9IGFbaV07CisgICAgICAgICAgICAgICAgaW50IGo7CisgICAgICAgICAgICAgICAgZm9yIChqID0gaSAtIDE7IGogPj0gbGVmdCAmJiBhaSA8IGFbal07IGotLSkgeworICAgICAgICAgICAgICAgICAgICBhW2ogKyAxXSA9IGFbal07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFbaiArIDFdID0gYWk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7IC8vIFVzZSBEdWFsLVBpdm90IFF1aWNrc29ydCBvbiBsYXJnZSBhcnJheXMKKyAgICAgICAgICAgIGR1YWxQaXZvdFF1aWNrc29ydChhLCBsZWZ0LCByaWdodCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIHRoZSBhcnJheSBpbnRvIGFzY2VuZGluZyBvcmRlciBieSB0aGUKKyAgICAgKiBEdWFsLVBpdm90IFF1aWNrc29ydCBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIGxlZnQgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSByaWdodCB0aGUgaW5kZXggb2YgdGhlIGxhc3QgZWxlbWVudCwgaW5jbHVzaXZlLCB0byBiZSBzb3J0ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGR1YWxQaXZvdFF1aWNrc29ydChmbG9hdFtdIGEsIGludCBsZWZ0LCBpbnQgcmlnaHQpIHsKKyAgICAgICAgLy8gQ29tcHV0ZSBpbmRpY2VzIG9mIGZpdmUgZXZlbmx5IHNwYWNlZCBlbGVtZW50cworICAgICAgICBpbnQgc2l4dGggPSAocmlnaHQgLSBsZWZ0ICsgMSkgLyA2OworICAgICAgICBpbnQgZTEgPSBsZWZ0ICArIHNpeHRoOworICAgICAgICBpbnQgZTUgPSByaWdodCAtIHNpeHRoOworICAgICAgICBpbnQgZTMgPSAobGVmdCArIHJpZ2h0KSA+Pj4gMTsgLy8gVGhlIG1pZHBvaW50CisgICAgICAgIGludCBlNCA9IGUzICsgc2l4dGg7CisgICAgICAgIGludCBlMiA9IGUzIC0gc2l4dGg7CisKKyAgICAgICAgLy8gU29ydCB0aGVzZSBlbGVtZW50cyB1c2luZyBhIDUtZWxlbWVudCBzb3J0aW5nIG5ldHdvcmsKKyAgICAgICAgZmxvYXQgYWUxID0gYVtlMV0sIGFlMiA9IGFbZTJdLCBhZTMgPSBhW2UzXSwgYWU0ID0gYVtlNF0sIGFlNSA9IGFbZTVdOworCisgICAgICAgIGlmIChhZTEgPiBhZTIpIHsgZmxvYXQgdCA9IGFlMTsgYWUxID0gYWUyOyBhZTIgPSB0OyB9CisgICAgICAgIGlmIChhZTQgPiBhZTUpIHsgZmxvYXQgdCA9IGFlNDsgYWU0ID0gYWU1OyBhZTUgPSB0OyB9CisgICAgICAgIGlmIChhZTEgPiBhZTMpIHsgZmxvYXQgdCA9IGFlMTsgYWUxID0gYWUzOyBhZTMgPSB0OyB9CisgICAgICAgIGlmIChhZTIgPiBhZTMpIHsgZmxvYXQgdCA9IGFlMjsgYWUyID0gYWUzOyBhZTMgPSB0OyB9CisgICAgICAgIGlmIChhZTEgPiBhZTQpIHsgZmxvYXQgdCA9IGFlMTsgYWUxID0gYWU0OyBhZTQgPSB0OyB9CisgICAgICAgIGlmIChhZTMgPiBhZTQpIHsgZmxvYXQgdCA9IGFlMzsgYWUzID0gYWU0OyBhZTQgPSB0OyB9CisgICAgICAgIGlmIChhZTIgPiBhZTUpIHsgZmxvYXQgdCA9IGFlMjsgYWUyID0gYWU1OyBhZTUgPSB0OyB9CisgICAgICAgIGlmIChhZTIgPiBhZTMpIHsgZmxvYXQgdCA9IGFlMjsgYWUyID0gYWUzOyBhZTMgPSB0OyB9CisgICAgICAgIGlmIChhZTQgPiBhZTUpIHsgZmxvYXQgdCA9IGFlNDsgYWU0ID0gYWU1OyBhZTUgPSB0OyB9CisKKyAgICAgICAgYVtlMV0gPSBhZTE7IGFbZTNdID0gYWUzOyBhW2U1XSA9IGFlNTsKKworICAgICAgICAvKgorICAgICAgICAgKiBVc2UgdGhlIHNlY29uZCBhbmQgZm91cnRoIG9mIHRoZSBmaXZlIHNvcnRlZCBlbGVtZW50cyBhcyBwaXZvdHMuCisgICAgICAgICAqIFRoZXNlIHZhbHVlcyBhcmUgaW5leHBlbnNpdmUgYXBwcm94aW1hdGlvbnMgb2YgdGhlIGZpcnN0IGFuZAorICAgICAgICAgKiBzZWNvbmQgdGVyY2lsZXMgb2YgdGhlIGFycmF5LiBOb3RlIHRoYXQgcGl2b3QxIDw9IHBpdm90Mi4KKyAgICAgICAgICoKKyAgICAgICAgICogVGhlIHBpdm90cyBhcmUgc3RvcmVkIGluIGxvY2FsIHZhcmlhYmxlcywgYW5kIHRoZSBmaXJzdCBhbmQKKyAgICAgICAgICogdGhlIGxhc3Qgb2YgdGhlIGVsZW1lbnRzIHRvIGJlIHNvcnRlZCBhcmUgbW92ZWQgdG8gdGhlIGxvY2F0aW9ucworICAgICAgICAgKiBmb3JtZXJseSBvY2N1cGllZCBieSB0aGUgcGl2b3RzLiBXaGVuIHBhcnRpdGlvbmluZyBpcyBjb21wbGV0ZSwKKyAgICAgICAgICogdGhlIHBpdm90cyBhcmUgc3dhcHBlZCBiYWNrIGludG8gdGhlaXIgZmluYWwgcG9zaXRpb25zLCBhbmQKKyAgICAgICAgICogZXhjbHVkZWQgZnJvbSBzdWJzZXF1ZW50IHNvcnRpbmcuCisgICAgICAgICAqLworICAgICAgICBmbG9hdCBwaXZvdDEgPSBhZTI7IGFbZTJdID0gYVtsZWZ0XTsKKyAgICAgICAgZmxvYXQgcGl2b3QyID0gYWU0OyBhW2U0XSA9IGFbcmlnaHRdOworCisgICAgICAgIC8vIFBvaW50ZXJzCisgICAgICAgIGludCBsZXNzICA9IGxlZnQgICsgMTsgLy8gVGhlIGluZGV4IG9mIGZpcnN0IGVsZW1lbnQgb2YgY2VudGVyIHBhcnQKKyAgICAgICAgaW50IGdyZWF0ID0gcmlnaHQgLSAxOyAvLyBUaGUgaW5kZXggYmVmb3JlIGZpcnN0IGVsZW1lbnQgb2YgcmlnaHQgcGFydAorCisgICAgICAgIGJvb2xlYW4gcGl2b3RzRGlmZmVyID0gKHBpdm90MSAhPSBwaXZvdDIpOworCisgICAgICAgIGlmIChwaXZvdHNEaWZmZXIpIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBQYXJ0aXRpb25pbmc6CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogICBsZWZ0IHBhcnQgICAgICAgICBjZW50ZXIgcGFydCAgICAgICAgICAgICAgICAgICAgcmlnaHQgcGFydAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqIHwgPCBwaXZvdDEgIHwgIHBpdm90MSA8PSAmJiA8PSBwaXZvdDIgIHwgICAgPyAgICB8ICA+IHBpdm90MiB8CisgICAgICAgICAgICAgKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKworICAgICAgICAgICAgICogICAgICAgICAgICAgIF4gICAgICAgICAgICAgICAgICAgICAgICAgIF4gICAgICAgXgorICAgICAgICAgICAgICogICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgfAorICAgICAgICAgICAgICogICAgICAgICAgICAgbGVzcyAgICAgICAgICAgICAgICAgICAgICAgIGsgICAgIGdyZWF0CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogSW52YXJpYW50czoKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgYWxsIGluIChsZWZ0LCBsZXNzKSAgIDwgcGl2b3QxCisgICAgICAgICAgICAgKiAgICBwaXZvdDEgPD0gYWxsIGluIFtsZXNzLCBrKSAgICAgPD0gcGl2b3QyCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgYWxsIGluIChncmVhdCwgcmlnaHQpID4gcGl2b3QyCisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogUG9pbnRlciBrIGlzIHRoZSBmaXJzdCBpbmRleCBvZiA/LXBhcnQKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgb3V0ZXI6CisgICAgICAgICAgICBmb3IgKGludCBrID0gbGVzczsgayA8PSBncmVhdDsgaysrKSB7CisgICAgICAgICAgICAgICAgZmxvYXQgYWsgPSBhW2tdOworICAgICAgICAgICAgICAgIGlmIChhayA8IHBpdm90MSkgeyAvLyBNb3ZlIGFba10gdG8gbGVmdCBwYXJ0CisgICAgICAgICAgICAgICAgICAgIGlmIChrICE9IGxlc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2xlc3NdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtsZXNzXSA9IGFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGxlc3MrKzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFrID4gcGl2b3QyKSB7IC8vIE1vdmUgYVtrXSB0byByaWdodCBwYXJ0CisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChhW2dyZWF0XSA+IHBpdm90MikgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdyZWF0LS0gPT0gaykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChhW2dyZWF0XSA8IHBpdm90MSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbbGVzc107CisgICAgICAgICAgICAgICAgICAgICAgICBhW2xlc3MrK10gPSBhW2dyZWF0XTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbZ3JlYXQtLV0gPSBhazsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gcGl2b3QxIDw9IGFbZ3JlYXRdIDw9IHBpdm90MgorICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbZ3JlYXRdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtncmVhdC0tXSA9IGFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeyAvLyBQaXZvdHMgYXJlIGVxdWFsCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogUGFydGl0aW9uIGRlZ2VuZXJhdGVzIHRvIHRoZSB0cmFkaXRpb25hbCAzLXdheSwKKyAgICAgICAgICAgICAqIG9yICJEdXRjaCBOYXRpb25hbCBGbGFnIiwgcGFydGl0aW9uOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqICAgbGVmdCBwYXJ0ICAgY2VudGVyIHBhcnQgICAgICAgICAgICByaWdodCBwYXJ0CisgICAgICAgICAgICAgKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqIHwgIDwgcGl2b3QgIHwgID09IHBpdm90ICB8ICAgID8gICAgfCAgPiBwaXZvdCAgfAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgXiAgICAgICAgICAgIF4gICAgICAgXgorICAgICAgICAgICAgICogICAgICAgICAgICAgIHwgICAgICAgICAgICB8ICAgICAgIHwKKyAgICAgICAgICAgICAqICAgICAgICAgICAgIGxlc3MgICAgICAgICAgayAgICAgZ3JlYXQKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBJbnZhcmlhbnRzOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqICAgYWxsIGluIChsZWZ0LCBsZXNzKSAgIDwgcGl2b3QKKyAgICAgICAgICAgICAqICAgYWxsIGluIFtsZXNzLCBrKSAgICAgPT0gcGl2b3QKKyAgICAgICAgICAgICAqICAgYWxsIGluIChncmVhdCwgcmlnaHQpID4gcGl2b3QKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBQb2ludGVyIGsgaXMgdGhlIGZpcnN0IGluZGV4IG9mID8tcGFydAorICAgICAgICAgICAgICovCisgICAgICAgICAgICBmb3IgKGludCBrID0gbGVzczsgayA8PSBncmVhdDsgaysrKSB7CisgICAgICAgICAgICAgICAgZmxvYXQgYWsgPSBhW2tdOworICAgICAgICAgICAgICAgIGlmIChhayA9PSBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChhayA8IHBpdm90MSkgeyAvLyBNb3ZlIGFba10gdG8gbGVmdCBwYXJ0CisgICAgICAgICAgICAgICAgICAgIGlmIChrICE9IGxlc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2xlc3NdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtsZXNzXSA9IGFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGxlc3MrKzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyAoYVtrXSA+IHBpdm90MSkgLSAgTW92ZSBhW2tdIHRvIHJpZ2h0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgICAgICogV2Uga25vdyB0aGF0IHBpdm90MSA9PSBhW2UzXSA9PSBwaXZvdDIuIFRodXMsIHdlIGtub3cKKyAgICAgICAgICAgICAgICAgICAgICogdGhhdCBncmVhdCB3aWxsIHN0aWxsIGJlID49IGsgd2hlbiB0aGUgZm9sbG93aW5nIGxvb3AKKyAgICAgICAgICAgICAgICAgICAgICogdGVybWluYXRlcywgZXZlbiB0aG91Z2ggd2UgZG9uJ3QgdGVzdCBmb3IgaXQgZXhwbGljaXRseS4KKyAgICAgICAgICAgICAgICAgICAgICogSW4gb3RoZXIgd29yZHMsIGFbZTNdIGFjdHMgYXMgYSBzZW50aW5lbCBmb3IgZ3JlYXQuCisgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICB3aGlsZSAoYVtncmVhdF0gPiBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGdyZWF0LS07CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKGFbZ3JlYXRdIDwgcGl2b3QxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtsZXNzXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbbGVzcysrXSA9IGFbZ3JlYXRdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtncmVhdC0tXSA9IGFrOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBhW2dyZWF0XSA9PSBwaXZvdDEKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBwaXZvdDE7CisgICAgICAgICAgICAgICAgICAgICAgICBhW2dyZWF0LS1dID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBTd2FwIHBpdm90cyBpbnRvIHRoZWlyIGZpbmFsIHBvc2l0aW9ucworICAgICAgICBhW2xlZnRdICA9IGFbbGVzcyAgLSAxXTsgYVtsZXNzICAtIDFdID0gcGl2b3QxOworICAgICAgICBhW3JpZ2h0XSA9IGFbZ3JlYXQgKyAxXTsgYVtncmVhdCArIDFdID0gcGl2b3QyOworCisgICAgICAgIC8vIFNvcnQgbGVmdCBhbmQgcmlnaHQgcGFydHMgcmVjdXJzaXZlbHksIGV4Y2x1ZGluZyBrbm93biBwaXZvdCB2YWx1ZXMKKyAgICAgICAgZG9Tb3J0KGEsIGxlZnQsICAgbGVzcyAtIDIpOworICAgICAgICBkb1NvcnQoYSwgZ3JlYXQgKyAyLCByaWdodCk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogSWYgcGl2b3QxID09IHBpdm90MiwgYWxsIGVsZW1lbnRzIGZyb20gY2VudGVyCisgICAgICAgICAqIHBhcnQgYXJlIGVxdWFsIGFuZCwgdGhlcmVmb3JlLCBhbHJlYWR5IHNvcnRlZAorICAgICAgICAgKi8KKyAgICAgICAgaWYgKCFwaXZvdHNEaWZmZXIpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIElmIGNlbnRlciBwYXJ0IGlzIHRvbyBsYXJnZSAoY29tcHJpc2VzID4gMi8zIG9mIHRoZSBhcnJheSksCisgICAgICAgICAqIHN3YXAgaW50ZXJuYWwgcGl2b3QgdmFsdWVzIHRvIGVuZHMKKyAgICAgICAgICovCisgICAgICAgIGlmIChsZXNzIDwgZTEgJiYgZ3JlYXQgPiBlNSkgeworICAgICAgICAgICAgd2hpbGUgKGFbbGVzc10gPT0gcGl2b3QxKSB7CisgICAgICAgICAgICAgICAgbGVzcysrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgd2hpbGUgKGFbZ3JlYXRdID09IHBpdm90MikgeworICAgICAgICAgICAgICAgIGdyZWF0LS07CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBQYXJ0aXRpb25pbmc6CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogICBsZWZ0IHBhcnQgICAgICAgY2VudGVyIHBhcnQgICAgICAgICAgICAgICAgICAgcmlnaHQgcGFydAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCisgICAgICAgICAgICAgKiB8ID09IHBpdm90MSB8ICBwaXZvdDEgPCAmJiA8IHBpdm90MiAgfCAgICA/ICAgIHwgPT0gcGl2b3QyIHwKKyAgICAgICAgICAgICAqICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKworICAgICAgICAgICAgICogICAgICAgICAgICAgIF4gICAgICAgICAgICAgICAgICAgICAgICBeICAgICAgIF4KKyAgICAgICAgICAgICAqICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICB8CisgICAgICAgICAgICAgKiAgICAgICAgICAgICBsZXNzICAgICAgICAgICAgICAgICAgICAgIGsgICAgIGdyZWF0CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogSW52YXJpYW50czoKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgYWxsIGluICgqLCBsZXNzKSAgPT0gcGl2b3QxCisgICAgICAgICAgICAgKiAgICAgcGl2b3QxIDwgYWxsIGluIFtsZXNzLCBrKSAgIDwgcGl2b3QyCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgYWxsIGluIChncmVhdCwgKikgPT0gcGl2b3QyCisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogUG9pbnRlciBrIGlzIHRoZSBmaXJzdCBpbmRleCBvZiA/LXBhcnQKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgb3V0ZXI6CisgICAgICAgICAgICBmb3IgKGludCBrID0gbGVzczsgayA8PSBncmVhdDsgaysrKSB7CisgICAgICAgICAgICAgICAgZmxvYXQgYWsgPSBhW2tdOworICAgICAgICAgICAgICAgIGlmIChhayA9PSBwaXZvdDIpIHsgLy8gTW92ZSBhW2tdIHRvIHJpZ2h0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGFbZ3JlYXRdID09IHBpdm90MikgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdyZWF0LS0gPT0gaykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChhW2dyZWF0XSA9PSBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2xlc3NdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtsZXNzKytdID0gcGl2b3QxOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBwaXZvdDEgPCBhW2dyZWF0XSA8IHBpdm90MgorICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbZ3JlYXRdOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGFbZ3JlYXQtLV0gPSBwaXZvdDI7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhayA9PSBwaXZvdDEpIHsgLy8gTW92ZSBhW2tdIHRvIGxlZnQgcGFydAorICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtsZXNzXTsKKyAgICAgICAgICAgICAgICAgICAgYVtsZXNzKytdID0gcGl2b3QxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFNvcnQgY2VudGVyIHBhcnQgcmVjdXJzaXZlbHksIGV4Y2x1ZGluZyBrbm93biBwaXZvdCB2YWx1ZXMKKyAgICAgICAgZG9Tb3J0KGEsIGxlc3MsIGdyZWF0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIGFycmF5IGludG8gYXNjZW5kaW5nIG51bWVyaWNhbCBvcmRlci4KKyAgICAgKgorICAgICAqIDxwPlRoZSB7QGNvZGUgPH0gcmVsYXRpb24gZG9lcyBub3QgcHJvdmlkZSBhIHRvdGFsIG9yZGVyIG9uIGFsbCBkb3VibGUKKyAgICAgKiB2YWx1ZXM6IHtAY29kZSAtMC4wZCA9PSAwLjBkfSBpcyB7QGNvZGUgdHJ1ZX0gYW5kIGEge0Bjb2RlIERvdWJsZS5OYU59CisgICAgICogdmFsdWUgY29tcGFyZXMgbmVpdGhlciBsZXNzIHRoYW4sIGdyZWF0ZXIgdGhhbiwgbm9yIGVxdWFsIHRvIGFueSB2YWx1ZSwKKyAgICAgKiBldmVuIGl0c2VsZi4gVGhpcyBtZXRob2QgdXNlcyB0aGUgdG90YWwgb3JkZXIgaW1wb3NlZCBieSB0aGUgbWV0aG9kCisgICAgICoge0BsaW5rIERvdWJsZSNjb21wYXJlVG99OiB7QGNvZGUgLTAuMGR9IGlzIHRyZWF0ZWQgYXMgbGVzcyB0aGFuIHZhbHVlCisgICAgICoge0Bjb2RlIDAuMGR9IGFuZCB7QGNvZGUgRG91YmxlLk5hTn0gaXMgY29uc2lkZXJlZCBncmVhdGVyIHRoYW4gYW55CisgICAgICogb3RoZXIgdmFsdWUgYW5kIGFsbCB7QGNvZGUgRG91YmxlLk5hTn0gdmFsdWVzIGFyZSBjb25zaWRlcmVkIGVxdWFsLgorICAgICAqCisgICAgICogQHBhcmFtIGEgdGhlIGFycmF5IHRvIGJlIHNvcnRlZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzb3J0KGRvdWJsZVtdIGEpIHsKKyAgICAgICAgc29ydE5lZ1plcm9BbmROYU4oYSwgMCwgYS5sZW5ndGggLSAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIHRoZSBhcnJheSBpbnRvIGFzY2VuZGluZyBvcmRlci4gVGhlIHJhbmdlCisgICAgICogdG8gYmUgc29ydGVkIGV4dGVuZHMgZnJvbSB0aGUgaW5kZXgge0Bjb2RlIGZyb21JbmRleH0sIGluY2x1c2l2ZSwgdG8KKyAgICAgKiB0aGUgaW5kZXgge0Bjb2RlIHRvSW5kZXh9LCBleGNsdXNpdmUuIElmIHtAY29kZSBmcm9tSW5kZXggPT0gdG9JbmRleH0sCisgICAgICogdGhlIHJhbmdlIHRvIGJlIHNvcnRlZCBpcyBlbXB0eSAoYW5kIHRoZSBjYWxsIGlzIGEgbm8tb3ApLgorICAgICAqCisgICAgICogPHA+VGhlIHtAY29kZSA8fSByZWxhdGlvbiBkb2VzIG5vdCBwcm92aWRlIGEgdG90YWwgb3JkZXIgb24gYWxsIGRvdWJsZQorICAgICAqIHZhbHVlczoge0Bjb2RlIC0wLjBkID09IDAuMGR9IGlzIHtAY29kZSB0cnVlfSBhbmQgYSB7QGNvZGUgRG91YmxlLk5hTn0KKyAgICAgKiB2YWx1ZSBjb21wYXJlcyBuZWl0aGVyIGxlc3MgdGhhbiwgZ3JlYXRlciB0aGFuLCBub3IgZXF1YWwgdG8gYW55IHZhbHVlLAorICAgICAqIGV2ZW4gaXRzZWxmLiBUaGlzIG1ldGhvZCB1c2VzIHRoZSB0b3RhbCBvcmRlciBpbXBvc2VkIGJ5IHRoZSBtZXRob2QKKyAgICAgKiB7QGxpbmsgRG91YmxlI2NvbXBhcmVUb306IHtAY29kZSAtMC4wZH0gaXMgdHJlYXRlZCBhcyBsZXNzIHRoYW4gdmFsdWUKKyAgICAgKiB7QGNvZGUgMC4wZH0gYW5kIHtAY29kZSBEb3VibGUuTmFOfSBpcyBjb25zaWRlcmVkIGdyZWF0ZXIgdGhhbiBhbnkKKyAgICAgKiBvdGhlciB2YWx1ZSBhbmQgYWxsIHtAY29kZSBEb3VibGUuTmFOfSB2YWx1ZXMgYXJlIGNvbnNpZGVyZWQgZXF1YWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIGZyb21JbmRleCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQsIGluY2x1c2l2ZSwgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIHRvSW5kZXggdGhlIGluZGV4IG9mIHRoZSBsYXN0IGVsZW1lbnQsIGV4Y2x1c2l2ZSwgdG8gYmUgc29ydGVkCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGZyb21JbmRleCA+IHRvSW5kZXh9CisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgaWYge0Bjb2RlIGZyb21JbmRleCA8IDB9IG9yIHtAY29kZSB0b0luZGV4ID4gYS5sZW5ndGh9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNvcnQoZG91YmxlW10gYSwgaW50IGZyb21JbmRleCwgaW50IHRvSW5kZXgpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrU3RhcnRBbmRFbmQoYS5sZW5ndGgsIGZyb21JbmRleCwgdG9JbmRleCk7CisgICAgICAgIHNvcnROZWdaZXJvQW5kTmFOKGEsIGZyb21JbmRleCwgdG9JbmRleCAtIDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhlIGFycmF5IGludG8gYXNjZW5kaW5nIG9yZGVyLiBUaGUKKyAgICAgKiBzb3J0IGlzIGRvbmUgaW4gdGhyZWUgcGhhc2VzIHRvIGF2b2lkIGV4cGVuc2l2ZSBjb21wYXJpc29ucyBpbiB0aGUKKyAgICAgKiBpbm5lciBsb29wLiBUaGUgY29tcGFyaXNvbnMgd291bGQgYmUgZXhwZW5zaXZlIGR1ZSB0byBhbm9tYWxpZXMKKyAgICAgKiBhc3NvY2lhdGVkIHdpdGggbmVnYXRpdmUgemVybyB7QGNvZGUgLTAuMGR9IGFuZCB7QGNvZGUgRG91YmxlLk5hTn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIGxlZnQgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSByaWdodCB0aGUgaW5kZXggb2YgdGhlIGxhc3QgZWxlbWVudCwgaW5jbHVzaXZlLCB0byBiZSBzb3J0ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHNvcnROZWdaZXJvQW5kTmFOKGRvdWJsZVtdIGEsIGludCBsZWZ0LCBpbnQgcmlnaHQpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogUGhhc2UgMTogQ291bnQgbmVnYXRpdmUgemVyb3MgYW5kIG1vdmUgTmFOcyB0byBlbmQgb2YgYXJyYXkKKyAgICAgICAgICovCisgICAgICAgIGZpbmFsIGxvbmcgTkVHQVRJVkVfWkVSTyA9IERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKC0wLjBkKTsKKyAgICAgICAgaW50IG51bU5lZ2F0aXZlWmVyb3MgPSAwOworICAgICAgICBpbnQgbiA9IHJpZ2h0OworCisgICAgICAgIGZvciAoaW50IGsgPSBsZWZ0OyBrIDw9IG47IGsrKykgeworICAgICAgICAgICAgZG91YmxlIGFrID0gYVtrXTsKKyAgICAgICAgICAgIGlmIChhayA9PSAwLjBkICYmIE5FR0FUSVZFX1pFUk8gPT0gRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoYWspKSB7CisgICAgICAgICAgICAgICAgYVtrXSA9IDAuMGQ7CisgICAgICAgICAgICAgICAgbnVtTmVnYXRpdmVaZXJvcysrOworICAgICAgICAgICAgfSBlbHNlIGlmIChhayAhPSBhaykgeyAvLyBpLmUuLCBhayBpcyBOYU4KKyAgICAgICAgICAgICAgICBhW2stLV0gPSBhW25dOworICAgICAgICAgICAgICAgIGFbbi0tXSA9IERvdWJsZS5OYU47CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBQaGFzZSAyOiBTb3J0IGV2ZXJ5dGhpbmcgZXhjZXB0IE5hTnMgKHdoaWNoIGFyZSBhbHJlYWR5IGluIHBsYWNlKQorICAgICAgICAgKi8KKyAgICAgICAgZG9Tb3J0KGEsIGxlZnQsIG4pOworCisgICAgICAgIC8qCisgICAgICAgICAqIFBoYXNlIDM6IFR1cm4gcG9zaXRpdmUgemVyb3MgYmFjayBpbnRvIG5lZ2F0aXZlIHplcm9zIGFzIGFwcHJvcHJpYXRlCisgICAgICAgICAqLworICAgICAgICBpZiAobnVtTmVnYXRpdmVaZXJvcyA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICAvLyBGaW5kIGZpcnN0IHplcm8gZWxlbWVudAorICAgICAgICBpbnQgemVyb0luZGV4ID0gZmluZEFueVplcm8oYSwgbGVmdCwgbik7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IHplcm9JbmRleCAtIDE7IGkgPj0gbGVmdCAmJiBhW2ldID09IDAuMGQ7IGktLSkgeworICAgICAgICAgICAgemVyb0luZGV4ID0gaTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFR1cm4gdGhlIHJpZ2h0IG51bWJlciBvZiBwb3NpdGl2ZSB6ZXJvcyBiYWNrIGludG8gbmVnYXRpdmUgemVyb3MKKyAgICAgICAgZm9yIChpbnQgaSA9IHplcm9JbmRleCwgbSA9IHplcm9JbmRleCArIG51bU5lZ2F0aXZlWmVyb3M7IGkgPCBtOyBpKyspIHsKKyAgICAgICAgICAgIGFbaV0gPSAtMC4wZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGluZGV4IG9mIHNvbWUgemVybyBlbGVtZW50IGluIHRoZSBzcGVjaWZpZWQgcmFuZ2UgdmlhCisgICAgICogYmluYXJ5IHNlYXJjaC4gVGhlIHJhbmdlIGlzIGFzc3VtZWQgdG8gYmUgc29ydGVkLCBhbmQgbXVzdCBjb250YWluCisgICAgICogYXQgbGVhc3Qgb25lIHplcm8uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc2VhcmNoZWQKKyAgICAgKiBAcGFyYW0gbG93IHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgZWxlbWVudCwgaW5jbHVzaXZlLCB0byBiZSBzZWFyY2hlZAorICAgICAqIEBwYXJhbSBoaWdoIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNlYXJjaGVkCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGZpbmRBbnlaZXJvKGRvdWJsZVtdIGEsIGludCBsb3csIGludCBoaWdoKSB7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBpbnQgbWlkZGxlID0gKGxvdyArIGhpZ2gpID4+PiAxOworICAgICAgICAgICAgZG91YmxlIG1pZGRsZVZhbHVlID0gYVttaWRkbGVdOworCisgICAgICAgICAgICBpZiAobWlkZGxlVmFsdWUgPCAwLjBkKSB7CisgICAgICAgICAgICAgICAgbG93ID0gbWlkZGxlICsgMTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAobWlkZGxlVmFsdWUgPiAwLjBkKSB7CisgICAgICAgICAgICAgICAgaGlnaCA9IG1pZGRsZSAtIDE7CisgICAgICAgICAgICB9IGVsc2UgeyAvLyBtaWRkbGVWYWx1ZSA9PSAwLjBkCisgICAgICAgICAgICAgICAgcmV0dXJuIG1pZGRsZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnRzIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhlIGFycmF5IGludG8gYXNjZW5kaW5nIG9yZGVyLiBUaGlzCisgICAgICogbWV0aG9kIGRpZmZlcnMgZnJvbSB0aGUgcHVibGljIHtAY29kZSBzb3J0fSBtZXRob2QgaW4gdGhyZWUgd2F5czoKKyAgICAgKiB7QGNvZGUgcmlnaHR9IGluZGV4IGlzIGluY2x1c2l2ZSwgaXQgZG9lcyBubyByYW5nZSBjaGVja2luZyBvbgorICAgICAqIHtAY29kZSBsZWZ0fSBvciB7QGNvZGUgcmlnaHR9LCBhbmQgaXQgZG9lcyBub3QgaGFuZGxlIG5lZ2F0aXZlCisgICAgICogemVyb3Mgb3IgTmFOcyBpbiB0aGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc29ydGVkLCB3aGljaCBtdXN0IG5vdCBjb250YWluIC0wLjBkIGFuZCBOYU4KKyAgICAgKiBAcGFyYW0gbGVmdCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQsIGluY2x1c2l2ZSwgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIHJpZ2h0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZG9Tb3J0KGRvdWJsZVtdIGEsIGludCBsZWZ0LCBpbnQgcmlnaHQpIHsKKyAgICAgICAgLy8gVXNlIGluc2VydGlvbiBzb3J0IG9uIHRpbnkgYXJyYXlzCisgICAgICAgIGlmIChyaWdodCAtIGxlZnQgKyAxIDwgSU5TRVJUSU9OX1NPUlRfVEhSRVNIT0xEKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gbGVmdCArIDE7IGkgPD0gcmlnaHQ7IGkrKykgeworICAgICAgICAgICAgICAgIGRvdWJsZSBhaSA9IGFbaV07CisgICAgICAgICAgICAgICAgaW50IGo7CisgICAgICAgICAgICAgICAgZm9yIChqID0gaSAtIDE7IGogPj0gbGVmdCAmJiBhaSA8IGFbal07IGotLSkgeworICAgICAgICAgICAgICAgICAgICBhW2ogKyAxXSA9IGFbal07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFbaiArIDFdID0gYWk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7IC8vIFVzZSBEdWFsLVBpdm90IFF1aWNrc29ydCBvbiBsYXJnZSBhcnJheXMKKyAgICAgICAgICAgIGR1YWxQaXZvdFF1aWNrc29ydChhLCBsZWZ0LCByaWdodCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIHRoZSBhcnJheSBpbnRvIGFzY2VuZGluZyBvcmRlciBieSB0aGUKKyAgICAgKiBEdWFsLVBpdm90IFF1aWNrc29ydCBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIGxlZnQgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50LCBpbmNsdXNpdmUsIHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSByaWdodCB0aGUgaW5kZXggb2YgdGhlIGxhc3QgZWxlbWVudCwgaW5jbHVzaXZlLCB0byBiZSBzb3J0ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGR1YWxQaXZvdFF1aWNrc29ydChkb3VibGVbXSBhLCBpbnQgbGVmdCwgaW50IHJpZ2h0KSB7CisgICAgICAgIC8vIENvbXB1dGUgaW5kaWNlcyBvZiBmaXZlIGV2ZW5seSBzcGFjZWQgZWxlbWVudHMKKyAgICAgICAgaW50IHNpeHRoID0gKHJpZ2h0IC0gbGVmdCArIDEpIC8gNjsKKyAgICAgICAgaW50IGUxID0gbGVmdCAgKyBzaXh0aDsKKyAgICAgICAgaW50IGU1ID0gcmlnaHQgLSBzaXh0aDsKKyAgICAgICAgaW50IGUzID0gKGxlZnQgKyByaWdodCkgPj4+IDE7IC8vIFRoZSBtaWRwb2ludAorICAgICAgICBpbnQgZTQgPSBlMyArIHNpeHRoOworICAgICAgICBpbnQgZTIgPSBlMyAtIHNpeHRoOworCisgICAgICAgIC8vIFNvcnQgdGhlc2UgZWxlbWVudHMgdXNpbmcgYSA1LWVsZW1lbnQgc29ydGluZyBuZXR3b3JrCisgICAgICAgIGRvdWJsZSBhZTEgPSBhW2UxXSwgYWUyID0gYVtlMl0sIGFlMyA9IGFbZTNdLCBhZTQgPSBhW2U0XSwgYWU1ID0gYVtlNV07CisKKyAgICAgICAgaWYgKGFlMSA+IGFlMikgeyBkb3VibGUgdCA9IGFlMTsgYWUxID0gYWUyOyBhZTIgPSB0OyB9CisgICAgICAgIGlmIChhZTQgPiBhZTUpIHsgZG91YmxlIHQgPSBhZTQ7IGFlNCA9IGFlNTsgYWU1ID0gdDsgfQorICAgICAgICBpZiAoYWUxID4gYWUzKSB7IGRvdWJsZSB0ID0gYWUxOyBhZTEgPSBhZTM7IGFlMyA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMiA+IGFlMykgeyBkb3VibGUgdCA9IGFlMjsgYWUyID0gYWUzOyBhZTMgPSB0OyB9CisgICAgICAgIGlmIChhZTEgPiBhZTQpIHsgZG91YmxlIHQgPSBhZTE7IGFlMSA9IGFlNDsgYWU0ID0gdDsgfQorICAgICAgICBpZiAoYWUzID4gYWU0KSB7IGRvdWJsZSB0ID0gYWUzOyBhZTMgPSBhZTQ7IGFlNCA9IHQ7IH0KKyAgICAgICAgaWYgKGFlMiA+IGFlNSkgeyBkb3VibGUgdCA9IGFlMjsgYWUyID0gYWU1OyBhZTUgPSB0OyB9CisgICAgICAgIGlmIChhZTIgPiBhZTMpIHsgZG91YmxlIHQgPSBhZTI7IGFlMiA9IGFlMzsgYWUzID0gdDsgfQorICAgICAgICBpZiAoYWU0ID4gYWU1KSB7IGRvdWJsZSB0ID0gYWU0OyBhZTQgPSBhZTU7IGFlNSA9IHQ7IH0KKworICAgICAgICBhW2UxXSA9IGFlMTsgYVtlM10gPSBhZTM7IGFbZTVdID0gYWU1OworCisgICAgICAgIC8qCisgICAgICAgICAqIFVzZSB0aGUgc2Vjb25kIGFuZCBmb3VydGggb2YgdGhlIGZpdmUgc29ydGVkIGVsZW1lbnRzIGFzIHBpdm90cy4KKyAgICAgICAgICogVGhlc2UgdmFsdWVzIGFyZSBpbmV4cGVuc2l2ZSBhcHByb3hpbWF0aW9ucyBvZiB0aGUgZmlyc3QgYW5kCisgICAgICAgICAqIHNlY29uZCB0ZXJjaWxlcyBvZiB0aGUgYXJyYXkuIE5vdGUgdGhhdCBwaXZvdDEgPD0gcGl2b3QyLgorICAgICAgICAgKgorICAgICAgICAgKiBUaGUgcGl2b3RzIGFyZSBzdG9yZWQgaW4gbG9jYWwgdmFyaWFibGVzLCBhbmQgdGhlIGZpcnN0IGFuZAorICAgICAgICAgKiB0aGUgbGFzdCBvZiB0aGUgZWxlbWVudHMgdG8gYmUgc29ydGVkIGFyZSBtb3ZlZCB0byB0aGUgbG9jYXRpb25zCisgICAgICAgICAqIGZvcm1lcmx5IG9jY3VwaWVkIGJ5IHRoZSBwaXZvdHMuIFdoZW4gcGFydGl0aW9uaW5nIGlzIGNvbXBsZXRlLAorICAgICAgICAgKiB0aGUgcGl2b3RzIGFyZSBzd2FwcGVkIGJhY2sgaW50byB0aGVpciBmaW5hbCBwb3NpdGlvbnMsIGFuZAorICAgICAgICAgKiBleGNsdWRlZCBmcm9tIHN1YnNlcXVlbnQgc29ydGluZy4KKyAgICAgICAgICovCisgICAgICAgIGRvdWJsZSBwaXZvdDEgPSBhZTI7IGFbZTJdID0gYVtsZWZ0XTsKKyAgICAgICAgZG91YmxlIHBpdm90MiA9IGFlNDsgYVtlNF0gPSBhW3JpZ2h0XTsKKworICAgICAgICAvLyBQb2ludGVycworICAgICAgICBpbnQgbGVzcyAgPSBsZWZ0ICArIDE7IC8vIFRoZSBpbmRleCBvZiBmaXJzdCBlbGVtZW50IG9mIGNlbnRlciBwYXJ0CisgICAgICAgIGludCBncmVhdCA9IHJpZ2h0IC0gMTsgLy8gVGhlIGluZGV4IGJlZm9yZSBmaXJzdCBlbGVtZW50IG9mIHJpZ2h0IHBhcnQKKworICAgICAgICBib29sZWFuIHBpdm90c0RpZmZlciA9IChwaXZvdDEgIT0gcGl2b3QyKTsKKworICAgICAgICBpZiAocGl2b3RzRGlmZmVyKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogUGFydGl0aW9uaW5nOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqICAgbGVmdCBwYXJ0ICAgICAgICAgY2VudGVyIHBhcnQgICAgICAgICAgICAgICAgICAgIHJpZ2h0IHBhcnQKKyAgICAgICAgICAgICAqICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCisgICAgICAgICAgICAgKiB8IDwgcGl2b3QxICB8ICBwaXZvdDEgPD0gJiYgPD0gcGl2b3QyICB8ICAgID8gICAgfCAgPiBwaXZvdDIgfAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBeICAgICAgICAgICAgICAgICAgICAgICAgICBeICAgICAgIF4KKyAgICAgICAgICAgICAqICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgIHwKKyAgICAgICAgICAgICAqICAgICAgICAgICAgIGxlc3MgICAgICAgICAgICAgICAgICAgICAgICBrICAgICBncmVhdAorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIEludmFyaWFudHM6CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogICAgICAgICAgICAgIGFsbCBpbiAobGVmdCwgbGVzcykgICA8IHBpdm90MQorICAgICAgICAgICAgICogICAgcGl2b3QxIDw9IGFsbCBpbiBbbGVzcywgaykgICAgIDw9IHBpdm90MgorICAgICAgICAgICAgICogICAgICAgICAgICAgIGFsbCBpbiAoZ3JlYXQsIHJpZ2h0KSA+IHBpdm90MgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIFBvaW50ZXIgayBpcyB0aGUgZmlyc3QgaW5kZXggb2YgPy1wYXJ0CisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIG91dGVyOgorICAgICAgICAgICAgZm9yIChpbnQgayA9IGxlc3M7IGsgPD0gZ3JlYXQ7IGsrKykgeworICAgICAgICAgICAgICAgIGRvdWJsZSBhayA9IGFba107CisgICAgICAgICAgICAgICAgaWYgKGFrIDwgcGl2b3QxKSB7IC8vIE1vdmUgYVtrXSB0byBsZWZ0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgaWYgKGsgIT0gbGVzcykgeworICAgICAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbbGVzc107CisgICAgICAgICAgICAgICAgICAgICAgICBhW2xlc3NdID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgbGVzcysrOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYWsgPiBwaXZvdDIpIHsgLy8gTW92ZSBhW2tdIHRvIHJpZ2h0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGFbZ3JlYXRdID4gcGl2b3QyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ3JlYXQtLSA9PSBrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKGFbZ3JlYXRdIDwgcGl2b3QxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtsZXNzXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbbGVzcysrXSA9IGFbZ3JlYXRdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtncmVhdC0tXSA9IGFrOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBwaXZvdDEgPD0gYVtncmVhdF0gPD0gcGl2b3QyCisgICAgICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtncmVhdF07CisgICAgICAgICAgICAgICAgICAgICAgICBhW2dyZWF0LS1dID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7IC8vIFBpdm90cyBhcmUgZXF1YWwKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBQYXJ0aXRpb24gZGVnZW5lcmF0ZXMgdG8gdGhlIHRyYWRpdGlvbmFsIDMtd2F5LAorICAgICAgICAgICAgICogb3IgIkR1dGNoIE5hdGlvbmFsIEZsYWciLCBwYXJ0aXRpb246CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogICBsZWZ0IHBhcnQgICBjZW50ZXIgcGFydCAgICAgICAgICAgIHJpZ2h0IHBhcnQKKyAgICAgICAgICAgICAqICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKworICAgICAgICAgICAgICogfCAgPCBwaXZvdCAgfCAgPT0gcGl2b3QgIHwgICAgPyAgICB8ICA+IHBpdm90ICB8CisgICAgICAgICAgICAgKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKyAgICAgICAgICAgICAqICAgICAgICAgICAgICBeICAgICAgICAgICAgXiAgICAgICBeCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgfCAgICAgICAgICAgIHwgICAgICAgfAorICAgICAgICAgICAgICogICAgICAgICAgICAgbGVzcyAgICAgICAgICBrICAgICBncmVhdAorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIEludmFyaWFudHM6CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogICBhbGwgaW4gKGxlZnQsIGxlc3MpICAgPCBwaXZvdAorICAgICAgICAgICAgICogICBhbGwgaW4gW2xlc3MsIGspICAgICA9PSBwaXZvdAorICAgICAgICAgICAgICogICBhbGwgaW4gKGdyZWF0LCByaWdodCkgPiBwaXZvdAorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIFBvaW50ZXIgayBpcyB0aGUgZmlyc3QgaW5kZXggb2YgPy1wYXJ0CisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGZvciAoaW50IGsgPSBsZXNzOyBrIDw9IGdyZWF0OyBrKyspIHsKKyAgICAgICAgICAgICAgICBkb3VibGUgYWsgPSBhW2tdOworICAgICAgICAgICAgICAgIGlmIChhayA9PSBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChhayA8IHBpdm90MSkgeyAvLyBNb3ZlIGFba10gdG8gbGVmdCBwYXJ0CisgICAgICAgICAgICAgICAgICAgIGlmIChrICE9IGxlc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2xlc3NdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtsZXNzXSA9IGFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGxlc3MrKzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyAoYVtrXSA+IHBpdm90MSkgLSAgTW92ZSBhW2tdIHRvIHJpZ2h0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgICAgICogV2Uga25vdyB0aGF0IHBpdm90MSA9PSBhW2UzXSA9PSBwaXZvdDIuIFRodXMsIHdlIGtub3cKKyAgICAgICAgICAgICAgICAgICAgICogdGhhdCBncmVhdCB3aWxsIHN0aWxsIGJlID49IGsgd2hlbiB0aGUgZm9sbG93aW5nIGxvb3AKKyAgICAgICAgICAgICAgICAgICAgICogdGVybWluYXRlcywgZXZlbiB0aG91Z2ggd2UgZG9uJ3QgdGVzdCBmb3IgaXQgZXhwbGljaXRseS4KKyAgICAgICAgICAgICAgICAgICAgICogSW4gb3RoZXIgd29yZHMsIGFbZTNdIGFjdHMgYXMgYSBzZW50aW5lbCBmb3IgZ3JlYXQuCisgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICB3aGlsZSAoYVtncmVhdF0gPiBwaXZvdDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGdyZWF0LS07CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKGFbZ3JlYXRdIDwgcGl2b3QxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtsZXNzXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbbGVzcysrXSA9IGFbZ3JlYXRdOworICAgICAgICAgICAgICAgICAgICAgICAgYVtncmVhdC0tXSA9IGFrOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBhW2dyZWF0XSA9PSBwaXZvdDEKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBwaXZvdDE7CisgICAgICAgICAgICAgICAgICAgICAgICBhW2dyZWF0LS1dID0gYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBTd2FwIHBpdm90cyBpbnRvIHRoZWlyIGZpbmFsIHBvc2l0aW9ucworICAgICAgICBhW2xlZnRdICA9IGFbbGVzcyAgLSAxXTsgYVtsZXNzICAtIDFdID0gcGl2b3QxOworICAgICAgICBhW3JpZ2h0XSA9IGFbZ3JlYXQgKyAxXTsgYVtncmVhdCArIDFdID0gcGl2b3QyOworCisgICAgICAgIC8vIFNvcnQgbGVmdCBhbmQgcmlnaHQgcGFydHMgcmVjdXJzaXZlbHksIGV4Y2x1ZGluZyBrbm93biBwaXZvdCB2YWx1ZXMKKyAgICAgICAgZG9Tb3J0KGEsIGxlZnQsICAgbGVzcyAtIDIpOworICAgICAgICBkb1NvcnQoYSwgZ3JlYXQgKyAyLCByaWdodCk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogSWYgcGl2b3QxID09IHBpdm90MiwgYWxsIGVsZW1lbnRzIGZyb20gY2VudGVyCisgICAgICAgICAqIHBhcnQgYXJlIGVxdWFsIGFuZCwgdGhlcmVmb3JlLCBhbHJlYWR5IHNvcnRlZAorICAgICAgICAgKi8KKyAgICAgICAgaWYgKCFwaXZvdHNEaWZmZXIpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIElmIGNlbnRlciBwYXJ0IGlzIHRvbyBsYXJnZSAoY29tcHJpc2VzID4gMi8zIG9mIHRoZSBhcnJheSksCisgICAgICAgICAqIHN3YXAgaW50ZXJuYWwgcGl2b3QgdmFsdWVzIHRvIGVuZHMKKyAgICAgICAgICovCisgICAgICAgIGlmIChsZXNzIDwgZTEgJiYgZ3JlYXQgPiBlNSkgeworICAgICAgICAgICAgd2hpbGUgKGFbbGVzc10gPT0gcGl2b3QxKSB7CisgICAgICAgICAgICAgICAgbGVzcysrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgd2hpbGUgKGFbZ3JlYXRdID09IHBpdm90MikgeworICAgICAgICAgICAgICAgIGdyZWF0LS07CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBQYXJ0aXRpb25pbmc6CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogICBsZWZ0IHBhcnQgICAgICAgY2VudGVyIHBhcnQgICAgICAgICAgICAgICAgICAgcmlnaHQgcGFydAorICAgICAgICAgICAgICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCisgICAgICAgICAgICAgKiB8ID09IHBpdm90MSB8ICBwaXZvdDEgPCAmJiA8IHBpdm90MiAgfCAgICA/ICAgIHwgPT0gcGl2b3QyIHwKKyAgICAgICAgICAgICAqICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKworICAgICAgICAgICAgICogICAgICAgICAgICAgIF4gICAgICAgICAgICAgICAgICAgICAgICBeICAgICAgIF4KKyAgICAgICAgICAgICAqICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICB8CisgICAgICAgICAgICAgKiAgICAgICAgICAgICBsZXNzICAgICAgICAgICAgICAgICAgICAgIGsgICAgIGdyZWF0CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogSW52YXJpYW50czoKKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgYWxsIGluICgqLCBsZXNzKSAgPT0gcGl2b3QxCisgICAgICAgICAgICAgKiAgICAgcGl2b3QxIDwgYWxsIGluIFtsZXNzLCBrKSAgIDwgcGl2b3QyCisgICAgICAgICAgICAgKiAgICAgICAgICAgICAgYWxsIGluIChncmVhdCwgKikgPT0gcGl2b3QyCisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogUG9pbnRlciBrIGlzIHRoZSBmaXJzdCBpbmRleCBvZiA/LXBhcnQKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgb3V0ZXI6CisgICAgICAgICAgICBmb3IgKGludCBrID0gbGVzczsgayA8PSBncmVhdDsgaysrKSB7CisgICAgICAgICAgICAgICAgZG91YmxlIGFrID0gYVtrXTsKKyAgICAgICAgICAgICAgICBpZiAoYWsgPT0gcGl2b3QyKSB7IC8vIE1vdmUgYVtrXSB0byByaWdodCBwYXJ0CisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChhW2dyZWF0XSA9PSBwaXZvdDIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChncmVhdC0tID09IGspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoYVtncmVhdF0gPT0gcGl2b3QxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhW2tdID0gYVtsZXNzXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbbGVzcysrXSA9IHBpdm90MTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gcGl2b3QxIDwgYVtncmVhdF0gPCBwaXZvdDIKKyAgICAgICAgICAgICAgICAgICAgICAgIGFba10gPSBhW2dyZWF0XTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBhW2dyZWF0LS1dID0gcGl2b3QyOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYWsgPT0gcGl2b3QxKSB7IC8vIE1vdmUgYVtrXSB0byBsZWZ0IHBhcnQKKyAgICAgICAgICAgICAgICAgICAgYVtrXSA9IGFbbGVzc107CisgICAgICAgICAgICAgICAgICAgIGFbbGVzcysrXSA9IHBpdm90MTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBTb3J0IGNlbnRlciBwYXJ0IHJlY3Vyc2l2ZWx5LCBleGNsdWRpbmcga25vd24gcGl2b3QgdmFsdWVzCisgICAgICAgIGRvU29ydChhLCBsZXNzLCBncmVhdCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9EdXBsaWNhdGVGb3JtYXRGbGFnc0V4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9EdXBsaWNhdGVGb3JtYXRGbGFnc0V4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQwNGRiOGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0R1cGxpY2F0ZUZvcm1hdEZsYWdzRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1OCBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKKy8qKgorICogVGhlIHVuY2hlY2tlZCBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24gb3V0IGlmIHRoZXJlIGFyZSBkdXBsaWNhdGUgZmxhZ3MgZ2l2ZW4KKyAqIG91dCBpbiB0aGUgZm9ybWF0IHNwZWNpZmllci4KKyAqCisgKiBAc2VlIGphdmEubGFuZy5SdW50aW1lRXhjZXB0aW9uCisgKi8KK3B1YmxpYyBjbGFzcyBEdXBsaWNhdGVGb3JtYXRGbGFnc0V4Y2VwdGlvbiBleHRlbmRzIElsbGVnYWxGb3JtYXRFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTg4OTA1MzFMOworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZmxhZ3M7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBEdXBsaWNhdGVGb3JtYXRGbGFnc0V4Y2VwdGlvbn0gd2l0aCB0aGUgZmxhZ3MKKyAgICAgKiBjb250YWluaW5nIGR1cGxpY2F0ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZgorICAgICAqICAgICAgICAgICB0aGUgZm9ybWF0IGZsYWdzIHRoYXQgY29udGFpbiBhIGR1cGxpY2F0ZSBmbGFnLgorICAgICAqLworICAgIHB1YmxpYyBEdXBsaWNhdGVGb3JtYXRGbGFnc0V4Y2VwdGlvbihTdHJpbmcgZikgeworICAgICAgICBpZiAoZiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBmbGFncyA9IGY7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZm9ybWF0IGZsYWdzIHRoYXQgY29udGFpbiBhIGR1cGxpY2F0ZSBmbGFnLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZm9ybWF0IGZsYWdzIHRoYXQgY29udGFpbiBhIGR1cGxpY2F0ZSBmbGFnLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RmxhZ3MoKSB7CisgICAgICAgIHJldHVybiBmbGFnczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2UoKSB7CisgICAgICAgIHJldHVybiBmbGFnczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0VtcHR5U3RhY2tFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRW1wdHlTdGFja0V4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQxZTFlZWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0VtcHR5U3RhY2tFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDM3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworCisvKioKKyAqIEFuIHtAY29kZSBFbXB0eVN0YWNrRXhjZXB0aW9ufSBpcyB0aHJvd24gaWYgdGhlIHBvcC9wZWVrIG1ldGhvZCBvZiBhIHN0YWNrIGlzCisgKiBleGVjdXRlZCBvbiBhbiBlbXB0eSBzdGFjay4KKyAqCisgKiBAc2VlIGphdmEubGFuZy5SdW50aW1lRXhjZXB0aW9uCisgKi8KK3B1YmxpYyBjbGFzcyBFbXB0eVN0YWNrRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1MDg0Njg2Mzc4NDkzMzAyMDk1TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEVtcHR5U3RhY2tFeGNlcHRpb259IHdpdGggdGhlIHN0YWNrIHRyYWNlIGZpbGxlZAorICAgICAqIGluLgorICAgICAqLworICAgIHB1YmxpYyBFbXB0eVN0YWNrRXhjZXB0aW9uKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRW51bU1hcC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9FbnVtTWFwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDNkNDJiNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRW51bU1hcC5qYXZhCkBAIC0wLDAgKzEsNzg5IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5BcnJheTsKKworLyoqCisgKiBBbiB7QGNvZGUgTWFwfSBzcGVjaWFsaXplZCBmb3IgdXNlIHdpdGgge0Bjb2RlIEVudW19IHR5cGVzIGFzIGtleXMuCisgKi8KK3B1YmxpYyBjbGFzcyBFbnVtTWFwPEsgZXh0ZW5kcyBFbnVtPEs+LCBWPiBleHRlbmRzIEFic3RyYWN0TWFwPEssIFY+IGltcGxlbWVudHMKKyAgICAgICAgU2VyaWFsaXphYmxlLCBDbG9uZWFibGUsIE1hcDxLLCBWPiB7CisKKyAgICAvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQKKyAgICAvLyBhZGRlZCBpbXBsZW1lbnRzIE1hcDxLLCBWPiBmb3IgYXBpY2hlY2sKKyAgICAvLyBFTkQgYW5kcm9pZC1jaGFuZ2VkCisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0NTg2NjEyNDAwNjkxOTI4NjVMOworCisgICAgcHJpdmF0ZSBDbGFzczxLPiBrZXlUeXBlOworCisgICAgdHJhbnNpZW50IEVudW1bXSBrZXlzOworCisgICAgdHJhbnNpZW50IE9iamVjdFtdIHZhbHVlczsKKworICAgIHRyYW5zaWVudCBib29sZWFuW10gaGFzTWFwcGluZzsKKworICAgIHByaXZhdGUgdHJhbnNpZW50IGludCBtYXBwaW5nc0NvdW50OworCisgICAgdHJhbnNpZW50IGludCBlbnVtU2l6ZTsKKworICAgIHByaXZhdGUgdHJhbnNpZW50IEVudW1NYXBFbnRyeVNldDxLLCBWPiBlbnRyeVNldCA9IG51bGw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBFbnRyeTxLVCBleHRlbmRzIEVudW08S1Q+LCBWVD4gZXh0ZW5kcworICAgICAgICAgICAgTWFwRW50cnk8S1QsIFZUPiB7CisgICAgICAgIHByaXZhdGUgZmluYWwgRW51bU1hcDxLVCwgVlQ+IGVudW1NYXA7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgb3JkaW5hbDsKKworICAgICAgICBFbnRyeShLVCB0aGVLZXksIFZUIHRoZVZhbHVlLCBFbnVtTWFwPEtULCBWVD4gZW0pIHsKKyAgICAgICAgICAgIHN1cGVyKHRoZUtleSwgdGhlVmFsdWUpOworICAgICAgICAgICAgZW51bU1hcCA9IGVtOworICAgICAgICAgICAgb3JkaW5hbCA9ICgoRW51bSkgdGhlS2V5KS5vcmRpbmFsKCk7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICBpZiAoIWVudW1NYXAuaGFzTWFwcGluZ1tvcmRpbmFsXSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJvb2xlYW4gaXNFcXVhbCA9IGZhbHNlOworICAgICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIE1hcC5FbnRyeSkgeworICAgICAgICAgICAgICAgIE1hcC5FbnRyeTxLVCwgVlQ+IGVudHJ5ID0gKE1hcC5FbnRyeTxLVCwgVlQ+KSBvYmplY3Q7CisgICAgICAgICAgICAgICAgT2JqZWN0IGVudW1LZXkgPSBlbnRyeS5nZXRLZXkoKTsKKyAgICAgICAgICAgICAgICBpZiAoa2V5LmVxdWFscyhlbnVtS2V5KSkgeworICAgICAgICAgICAgICAgICAgICBPYmplY3QgdGhlVmFsdWUgPSBlbnRyeS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgICAgICAgICBpZiAoZW51bU1hcC52YWx1ZXNbb3JkaW5hbF0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgaXNFcXVhbCA9ICh0aGVWYWx1ZSA9PSBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlzRXF1YWwgPSBlbnVtTWFwLnZhbHVlc1tvcmRpbmFsXS5lcXVhbHModGhlVmFsdWUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGlzRXF1YWw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiAoZW51bU1hcC5rZXlzW29yZGluYWxdID09IG51bGwgPyAwIDogZW51bU1hcC5rZXlzW29yZGluYWxdCisgICAgICAgICAgICAgICAgICAgIC5oYXNoQ29kZSgpKQorICAgICAgICAgICAgICAgICAgICBeIChlbnVtTWFwLnZhbHVlc1tvcmRpbmFsXSA9PSBudWxsID8gMAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZW51bU1hcC52YWx1ZXNbb3JkaW5hbF0uaGFzaENvZGUoKSk7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBLVCBnZXRLZXkoKSB7CisgICAgICAgICAgICBjaGVja0VudHJ5U3RhdHVzKCk7CisgICAgICAgICAgICByZXR1cm4gKEtUKSBlbnVtTWFwLmtleXNbb3JkaW5hbF07CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBWVCBnZXRWYWx1ZSgpIHsKKyAgICAgICAgICAgIGNoZWNrRW50cnlTdGF0dXMoKTsKKyAgICAgICAgICAgIHJldHVybiAoVlQpIGVudW1NYXAudmFsdWVzW29yZGluYWxdOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgVlQgc2V0VmFsdWUoVlQgdmFsdWUpIHsKKyAgICAgICAgICAgIGNoZWNrRW50cnlTdGF0dXMoKTsKKyAgICAgICAgICAgIHJldHVybiBlbnVtTWFwLnB1dCgoS1QpIGVudW1NYXAua2V5c1tvcmRpbmFsXSwgdmFsdWUpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKGVudW1NYXAua2V5c1tvcmRpbmFsXQorICAgICAgICAgICAgICAgICAgICAudG9TdHJpbmcoKSk7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCI9Iik7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGVudW1NYXAudmFsdWVzW29yZGluYWxdID09IG51bGwKKyAgICAgICAgICAgICAgICAgICAgPyAibnVsbCIgOiBlbnVtTWFwLnZhbHVlc1tvcmRpbmFsXS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCBjaGVja0VudHJ5U3RhdHVzKCkgeworICAgICAgICAgICAgaWYgKCFlbnVtTWFwLmhhc01hcHBpbmdbb3JkaW5hbF0pIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBFbnVtTWFwSXRlcmF0b3I8RSwgS1QgZXh0ZW5kcyBFbnVtPEtUPiwgVlQ+IGltcGxlbWVudHMKKyAgICAgICAgICAgIEl0ZXJhdG9yPEU+IHsKKyAgICAgICAgaW50IHBvc2l0aW9uID0gMDsKKworICAgICAgICBpbnQgcHJlUG9zaXRpb24gPSAtMTsKKworICAgICAgICBmaW5hbCBFbnVtTWFwPEtULCBWVD4gZW51bU1hcDsKKworICAgICAgICBmaW5hbCBNYXBFbnRyeS5UeXBlPEUsIEtULCBWVD4gdHlwZTsKKworICAgICAgICBFbnVtTWFwSXRlcmF0b3IoTWFwRW50cnkuVHlwZTxFLCBLVCwgVlQ+IHZhbHVlLCBFbnVtTWFwPEtULCBWVD4gZW0pIHsKKyAgICAgICAgICAgIGVudW1NYXAgPSBlbTsKKyAgICAgICAgICAgIHR5cGUgPSB2YWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICBpbnQgbGVuZ3RoID0gZW51bU1hcC5lbnVtU2l6ZTsKKyAgICAgICAgICAgIGZvciAoOyBwb3NpdGlvbiA8IGxlbmd0aDsgcG9zaXRpb24rKykgeworICAgICAgICAgICAgICAgIGlmIChlbnVtTWFwLmhhc01hcHBpbmdbcG9zaXRpb25dKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBwb3NpdGlvbiAhPSBsZW5ndGg7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgcHVibGljIEUgbmV4dCgpIHsKKyAgICAgICAgICAgIGlmICghaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHByZVBvc2l0aW9uID0gcG9zaXRpb24rKzsKKyAgICAgICAgICAgIHJldHVybiB0eXBlLmdldChuZXcgTWFwRW50cnkoZW51bU1hcC5rZXlzW3ByZVBvc2l0aW9uXSwKKyAgICAgICAgICAgICAgICAgICAgZW51bU1hcC52YWx1ZXNbcHJlUG9zaXRpb25dKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICBjaGVja1N0YXR1cygpOworICAgICAgICAgICAgaWYgKGVudW1NYXAuaGFzTWFwcGluZ1twcmVQb3NpdGlvbl0pIHsKKyAgICAgICAgICAgICAgICBlbnVtTWFwLnJlbW92ZShlbnVtTWFwLmtleXNbcHJlUG9zaXRpb25dKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHByZVBvc2l0aW9uID0gLTE7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICBpZiAoLTEgPT0gcHJlUG9zaXRpb24pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0eXBlLmdldCgKKyAgICAgICAgICAgICAgICAgICAgbmV3IE1hcEVudHJ5KGVudW1NYXAua2V5c1twcmVQb3NpdGlvbl0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW51bU1hcC52YWx1ZXNbcHJlUG9zaXRpb25dKSkudG9TdHJpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCBjaGVja1N0YXR1cygpIHsKKyAgICAgICAgICAgIGlmICgtMSA9PSBwcmVQb3NpdGlvbikgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEVudW1NYXBLZXlTZXQ8S1QgZXh0ZW5kcyBFbnVtPEtUPiwgVlQ+IGV4dGVuZHMKKyAgICAgICAgICAgIEFic3RyYWN0U2V0PEtUPiB7CisgICAgICAgIHByaXZhdGUgZmluYWwgRW51bU1hcDxLVCwgVlQ+IGVudW1NYXA7CisKKyAgICAgICAgRW51bU1hcEtleVNldChFbnVtTWFwPEtULCBWVD4gZW0pIHsKKyAgICAgICAgICAgIGVudW1NYXAgPSBlbTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgICAgIGVudW1NYXAuY2xlYXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gZW51bU1hcC5jb250YWluc0tleShvYmplY3QpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICBwdWJsaWMgSXRlcmF0b3IgaXRlcmF0b3IoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEVudW1NYXBJdGVyYXRvcjxLVCwgS1QsIFZUPigKKyAgICAgICAgICAgICAgICAgICAgbmV3IE1hcEVudHJ5LlR5cGU8S1QsIEtULCBWVD4oKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgS1QgZ2V0KE1hcEVudHJ5PEtULCBWVD4gZW50cnkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW50cnkua2V5OworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9LCBlbnVtTWFwKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIGlmIChjb250YWlucyhvYmplY3QpKSB7CisgICAgICAgICAgICAgICAgZW51bU1hcC5yZW1vdmUob2JqZWN0KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gZW51bU1hcC5zaXplKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBFbnVtTWFwVmFsdWVDb2xsZWN0aW9uPEtUIGV4dGVuZHMgRW51bTxLVD4sIFZUPgorICAgICAgICAgICAgZXh0ZW5kcyBBYnN0cmFjdENvbGxlY3Rpb248VlQ+IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBFbnVtTWFwPEtULCBWVD4gZW51bU1hcDsKKworICAgICAgICBFbnVtTWFwVmFsdWVDb2xsZWN0aW9uKEVudW1NYXA8S1QsIFZUPiBlbSkgeworICAgICAgICAgICAgZW51bU1hcCA9IGVtOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICAgICAgZW51bU1hcC5jbGVhcigpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIHJldHVybiBlbnVtTWFwLmNvbnRhaW5zVmFsdWUob2JqZWN0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIEl0ZXJhdG9yIGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBFbnVtTWFwSXRlcmF0b3I8VlQsIEtULCBWVD4oCisgICAgICAgICAgICAgICAgICAgIG5ldyBNYXBFbnRyeS5UeXBlPFZULCBLVCwgVlQ+KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIFZUIGdldChNYXBFbnRyeTxLVCwgVlQ+IGVudHJ5KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVudHJ5LnZhbHVlOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9LCBlbnVtTWFwKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbnVtTWFwLmVudW1TaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGVudW1NYXAuaGFzTWFwcGluZ1tpXSAmJiBlbnVtTWFwLnZhbHVlc1tpXSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBlbnVtTWFwLnJlbW92ZShlbnVtTWFwLmtleXNbaV0pOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZW51bU1hcC5lbnVtU2l6ZTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChlbnVtTWFwLmhhc01hcHBpbmdbaV0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBvYmplY3QuZXF1YWxzKGVudW1NYXAudmFsdWVzW2ldKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZW51bU1hcC5yZW1vdmUoZW51bU1hcC5rZXlzW2ldKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBlbnVtTWFwLnNpemUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEVudW1NYXBFbnRyeUl0ZXJhdG9yPEUsIEtUIGV4dGVuZHMgRW51bTxLVD4sIFZUPgorICAgICAgICAgICAgZXh0ZW5kcyBFbnVtTWFwSXRlcmF0b3I8RSwgS1QsIFZUPiB7CisgICAgICAgIEVudW1NYXBFbnRyeUl0ZXJhdG9yKE1hcEVudHJ5LlR5cGU8RSwgS1QsIFZUPiB2YWx1ZSwgRW51bU1hcDxLVCwgVlQ+IGVtKSB7CisgICAgICAgICAgICBzdXBlcih2YWx1ZSwgZW0pOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgRSBuZXh0KCkgeworICAgICAgICAgICAgaWYgKCFoYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHJlUG9zaXRpb24gPSBwb3NpdGlvbisrOworICAgICAgICAgICAgcmV0dXJuIHR5cGUuZ2V0KG5ldyBFbnRyeTxLVCwgVlQ+KChLVCkgZW51bU1hcC5rZXlzW3ByZVBvc2l0aW9uXSwKKyAgICAgICAgICAgICAgICAgICAgKFZUKSBlbnVtTWFwLnZhbHVlc1twcmVQb3NpdGlvbl0sIGVudW1NYXApKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEVudW1NYXBFbnRyeVNldDxLVCBleHRlbmRzIEVudW08S1Q+LCBWVD4gZXh0ZW5kcworICAgICAgICAgICAgQWJzdHJhY3RTZXQ8TWFwLkVudHJ5PEtULCBWVD4+IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBFbnVtTWFwPEtULCBWVD4gZW51bU1hcDsKKworICAgICAgICBFbnVtTWFwRW50cnlTZXQoRW51bU1hcDxLVCwgVlQ+IGVtKSB7CisgICAgICAgICAgICBlbnVtTWFwID0gZW07CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICBlbnVtTWFwLmNsZWFyKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgYm9vbGVhbiBpc0VxdWFsID0gZmFsc2U7CisgICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgTWFwLkVudHJ5KSB7CisgICAgICAgICAgICAgICAgT2JqZWN0IGVudW1LZXkgPSAoKE1hcC5FbnRyeSkgb2JqZWN0KS5nZXRLZXkoKTsKKyAgICAgICAgICAgICAgICBPYmplY3QgZW51bVZhbHVlID0gKChNYXAuRW50cnkpIG9iamVjdCkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgICAgICBpZiAoZW51bU1hcC5jb250YWluc0tleShlbnVtS2V5KSkgeworICAgICAgICAgICAgICAgICAgICBWVCB2YWx1ZSA9IGVudW1NYXAuZ2V0KGVudW1LZXkpOworICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgaXNFcXVhbCA9IGVudW1WYWx1ZSA9PSBudWxsOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgaXNFcXVhbCA9IHZhbHVlLmVxdWFscyhlbnVtVmFsdWUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGlzRXF1YWw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIEl0ZXJhdG9yPE1hcC5FbnRyeTxLVCwgVlQ+PiBpdGVyYXRvcigpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgRW51bU1hcEVudHJ5SXRlcmF0b3I8TWFwLkVudHJ5PEtULCBWVD4sIEtULCBWVD4oCisgICAgICAgICAgICAgICAgICAgIG5ldyBNYXBFbnRyeS5UeXBlPE1hcC5FbnRyeTxLVCwgVlQ+LCBLVCwgVlQ+KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIE1hcC5FbnRyeTxLVCwgVlQ+IGdldChNYXBFbnRyeTxLVCwgVlQ+IGVudHJ5KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVudHJ5OworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9LCBlbnVtTWFwKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgaWYgKGNvbnRhaW5zKG9iamVjdCkpIHsKKyAgICAgICAgICAgICAgICBlbnVtTWFwLnJlbW92ZSgoKE1hcC5FbnRyeSkgb2JqZWN0KS5nZXRLZXkoKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgcmV0dXJuIGVudW1NYXAuc2l6ZSgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBPYmplY3RbXSB0b0FycmF5KCkgeworICAgICAgICAgICAgT2JqZWN0W10gZW50cnlBcnJheSA9IG5ldyBPYmplY3RbZW51bU1hcC5zaXplKCldOworICAgICAgICAgICAgcmV0dXJuIHRvQXJyYXkoZW50cnlBcnJheSk7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBPYmplY3RbXSB0b0FycmF5KE9iamVjdFtdIGFycmF5KSB7CisgICAgICAgICAgICBpbnQgc2l6ZSA9IGVudW1NYXAuc2l6ZSgpOworICAgICAgICAgICAgaW50IGluZGV4ID0gMDsKKyAgICAgICAgICAgIE9iamVjdFtdIGVudHJ5QXJyYXkgPSBhcnJheTsKKyAgICAgICAgICAgIGlmIChzaXplID4gYXJyYXkubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgQ2xhc3M8Pz4gY2xhenogPSBhcnJheS5nZXRDbGFzcygpLmdldENvbXBvbmVudFR5cGUoKTsKKyAgICAgICAgICAgICAgICBlbnRyeUFycmF5ID0gKE9iamVjdFtdKSBBcnJheS5uZXdJbnN0YW5jZShjbGF6eiwgc2l6ZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBJdGVyYXRvcjxNYXAuRW50cnk8S1QsIFZUPj4gaXRlciA9IGl0ZXJhdG9yKCk7CisgICAgICAgICAgICBmb3IgKDsgaW5kZXggPCBzaXplOyBpbmRleCsrKSB7CisgICAgICAgICAgICAgICAgTWFwLkVudHJ5PEtULCBWVD4gZW50cnkgPSBpdGVyLm5leHQoKTsKKyAgICAgICAgICAgICAgICBlbnRyeUFycmF5W2luZGV4XSA9IG5ldyBNYXBFbnRyeTxLVCwgVlQ+KGVudHJ5LmdldEtleSgpLCBlbnRyeQorICAgICAgICAgICAgICAgICAgICAgICAgLmdldFZhbHVlKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGluZGV4IDwgYXJyYXkubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgZW50cnlBcnJheVtpbmRleF0gPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGVudHJ5QXJyYXk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIGVtcHR5IHtAY29kZSBFbnVtTWFwfSB1c2luZyB0aGUgZ2l2ZW4ga2V5IHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5VHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGNsYXNzIG9iamVjdCBnaXZpbmcgdGhlIHR5cGUgb2YgdGhlIGtleXMgdXNlZCBieSB0aGlzIHtAY29kZSBFbnVtTWFwfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGtleVR5cGV9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bU1hcChDbGFzczxLPiBrZXlUeXBlKSB7CisgICAgICAgIGluaXRpYWxpemF0aW9uKGtleVR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4ge0Bjb2RlIEVudW1NYXB9IHVzaW5nIHRoZSBzYW1lIGtleSB0eXBlIGFzIHRoZSBnaXZlbiB7QGNvZGUgRW51bU1hcH0gYW5kCisgICAgICogaW5pdGlhbGx5IGNvbnRhaW5pbmcgdGhlIHNhbWUgbWFwcGluZ3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWFwCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIEVudW1NYXB9IGZyb20gd2hpY2ggdGhpcyB7QGNvZGUgRW51bU1hcH0gaXMgaW5pdGlhbGl6ZWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBtYXB9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bU1hcChFbnVtTWFwPEssID8gZXh0ZW5kcyBWPiBtYXApIHsKKyAgICAgICAgaW5pdGlhbGl6YXRpb24obWFwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIHtAY29kZSBFbnVtTWFwfSBpbml0aWFsaXplZCBmcm9tIHRoZSBnaXZlbiBtYXAuIElmIHRoZSBnaXZlbiBtYXAKKyAgICAgKiBpcyBhbiB7QGNvZGUgRW51bU1hcH0gaW5zdGFuY2UsIHRoaXMgY29uc3RydWN0b3IgYmVoYXZlcyBpbiB0aGUgZXhhY3RseSB0aGUgc2FtZQorICAgICAqIHdheSBhcyB7QGxpbmsgRW51bU1hcCNFbnVtTWFwKEVudW1NYXApfX0uIE90aGVyd2lzZSwgdGhlIGdpdmVuIG1hcAorICAgICAqIHNob3VsZCBjb250YWluIGF0IGxlYXN0IG9uZSBtYXBwaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIG1hcAorICAgICAqICAgICAgICAgICAgdGhlIG1hcCBmcm9tIHdoaWNoIHRoaXMge0Bjb2RlIEVudW1NYXB9IGlzIGluaXRpYWxpemVkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG1hcH0gaXMgbm90IGFuIHtAY29kZSBFbnVtTWFwfSBpbnN0YW5jZSBhbmQgZG9lcyBub3QgY29udGFpbgorICAgICAqICAgICAgICAgICAgIGFueSBtYXBwaW5ncy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG1hcH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBFbnVtTWFwKE1hcDxLLCA/IGV4dGVuZHMgVj4gbWFwKSB7CisgICAgICAgIGlmIChtYXAgaW5zdGFuY2VvZiBFbnVtTWFwKSB7CisgICAgICAgICAgICBpbml0aWFsaXphdGlvbigoRW51bU1hcDxLLCBWPikgbWFwKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChtYXAuc2l6ZSgpID09IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBJdGVyYXRvcjxLPiBpdGVyID0gbWFwLmtleVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgICAgICBLIGVudW1LZXkgPSBpdGVyLm5leHQoKTsKKyAgICAgICAgICAgIENsYXNzIGNsYXp6ID0gZW51bUtleS5nZXRDbGFzcygpOworICAgICAgICAgICAgaWYgKGNsYXp6LmlzRW51bSgpKSB7CisgICAgICAgICAgICAgICAgaW5pdGlhbGl6YXRpb24oY2xhenopOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpbml0aWFsaXphdGlvbihjbGF6ei5nZXRTdXBlcmNsYXNzKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHV0QWxsSW1wbChtYXApOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhbGwgZWxlbWVudHMgZnJvbSB0aGlzIHtAY29kZSBFbnVtTWFwfSwgbGVhdmluZyBpdCBlbXB0eS4KKyAgICAgKgorICAgICAqIEBzZWUgI2lzRW1wdHkoKQorICAgICAqIEBzZWUgI3NpemUoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBBcnJheXMuZmlsbCh2YWx1ZXMsIG51bGwpOworICAgICAgICBBcnJheXMuZmlsbChoYXNNYXBwaW5nLCBmYWxzZSk7CisgICAgICAgIG1hcHBpbmdzQ291bnQgPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzaGFsbG93IGNvcHkgb2YgdGhpcyB7QGNvZGUgRW51bU1hcH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc2hhbGxvdyBjb3B5IG9mIHRoaXMge0Bjb2RlIEVudW1NYXB9LgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBFbnVtTWFwPEssIFY+IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgRW51bU1hcDxLLCBWPiBlbnVtTWFwID0gKEVudW1NYXA8SywgVj4pIHN1cGVyLmNsb25lKCk7CisgICAgICAgICAgICBlbnVtTWFwLmluaXRpYWxpemF0aW9uKHRoaXMpOworICAgICAgICAgICAgcmV0dXJuIGVudW1NYXA7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIHtAY29kZSBFbnVtTWFwfSBjb250YWlucyB0aGUgc3BlY2lmaWVkIGtleS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgdG8gc2VhcmNoIGZvci4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBFbnVtTWFwfSBjb250YWlucyB0aGUgc3BlY2lmaWVkIGtleSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrZXkpIHsKKyAgICAgICAgaWYgKGlzVmFsaWRLZXlUeXBlKGtleSkpIHsKKyAgICAgICAgICAgIGludCBrZXlPcmRpbmFsID0gKChFbnVtKSBrZXkpLm9yZGluYWwoKTsKKyAgICAgICAgICAgIHJldHVybiBoYXNNYXBwaW5nW2tleU9yZGluYWxdOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyB7QGNvZGUgRW51bU1hcH0gY29udGFpbnMgdGhlIHNwZWNpZmllZCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgRW51bU1hcH0gY29udGFpbnMgdGhlIHNwZWNpZmllZCB2YWx1ZSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVmFsdWUoT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVudW1TaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoaGFzTWFwcGluZ1tpXSAmJiB2YWx1ZXNbaV0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVudW1TaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoaGFzTWFwcGluZ1tpXSAmJiB2YWx1ZS5lcXVhbHModmFsdWVzW2ldKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgU2V0fSBjb250YWluaW5nIGFsbCBvZiB0aGUgbWFwcGluZ3MgaW4gdGhpcyB7QGNvZGUgRW51bU1hcH0uIEVhY2ggbWFwcGluZyBpcworICAgICAqIGFuIGluc3RhbmNlIG9mIHtAbGluayBNYXAuRW50cnl9LiBBcyB0aGUge0Bjb2RlIFNldH0gaXMgYmFja2VkIGJ5IHRoaXMge0Bjb2RlIEVudW1NYXB9LAorICAgICAqIGNoYW5nZXMgaW4gb25lIHdpbGwgYmUgcmVmbGVjdGVkIGluIHRoZSBvdGhlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgb3JkZXIgb2YgdGhlIGVudHJpZXMgaW4gdGhlIHNldCB3aWxsIGJlIHRoZSBvcmRlciB0aGF0IHRoZSBlbnVtIGtleXMKKyAgICAgKiB3ZXJlIGRlY2xhcmVkIGluLgorICAgICAqCisgICAgICogQHJldHVybiBhIHtAY29kZSBTZXR9IG9mIHRoZSBtYXBwaW5ncy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2V0PE1hcC5FbnRyeTxLLCBWPj4gZW50cnlTZXQoKSB7CisgICAgICAgIGlmIChlbnRyeVNldCA9PSBudWxsKSB7CisgICAgICAgICAgICBlbnRyeVNldCA9IG5ldyBFbnVtTWFwRW50cnlTZXQ8SywgVj4odGhpcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVudHJ5U2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBhcmd1bWVudCB0byB0aGUgcmVjZWl2ZXIsIGFuZCByZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGUKKyAgICAgKiBzcGVjaWZpZWQge0Bjb2RlIE9iamVjdH0gaXMgYW4ge0Bjb2RlIEVudW1NYXB9IGFuZCBib3RoIHtAY29kZSBFbnVtTWFwfXMgY29udGFpbiB0aGUgc2FtZSBtYXBwaW5ncy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT2JqZWN0fSB0byBjb21wYXJlIHdpdGggdGhpcyB7QGNvZGUgRW51bU1hcH0uCisgICAgICogQHJldHVybiBib29sZWFuIHtAY29kZSB0cnVlfSBpZiB7QGNvZGUgb2JqZWN0fSBpcyB0aGUgc2FtZSBhcyB0aGlzIHtAY29kZSBFbnVtTWFwfSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgI2hhc2hDb2RlKCkKKyAgICAgKiBAc2VlICNlbnRyeVNldCgpCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgaWYgKHRoaXMgPT0gb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBFbnVtTWFwKSkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmplY3QpOworICAgICAgICB9CisgICAgICAgIEVudW1NYXA8SywgVj4gZW51bU1hcCA9IChFbnVtTWFwPEssIFY+KSBvYmplY3Q7CisgICAgICAgIGlmIChrZXlUeXBlICE9IGVudW1NYXAua2V5VHlwZSB8fCBzaXplKCkgIT0gZW51bU1hcC5zaXplKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscyhoYXNNYXBwaW5nLCBlbnVtTWFwLmhhc01hcHBpbmcpCisgICAgICAgICAgICAgICAgJiYgQXJyYXlzLmVxdWFscyh2YWx1ZXMsIGVudW1NYXAudmFsdWVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgbWFwcGluZyB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleS4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgbWFwcGluZyB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LCBvciB7QGNvZGUgbnVsbH0KKyAgICAgKiAgICAgICAgIGlmIG5vIG1hcHBpbmcgZm9yIHRoZSBzcGVjaWZpZWQga2V5IGlzIGZvdW5kLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBWIGdldChPYmplY3Qga2V5KSB7CisgICAgICAgIGlmICghaXNWYWxpZEtleVR5cGUoa2V5KSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgaW50IGtleU9yZGluYWwgPSAoKEVudW0pIGtleSkub3JkaW5hbCgpOworICAgICAgICByZXR1cm4gKFYpIHZhbHVlc1trZXlPcmRpbmFsXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc2V0IG9mIHRoZSBrZXlzIGNvbnRhaW5lZCBpbiB0aGlzIHtAY29kZSBFbnVtTWFwfS4gVGhlIHtAY29kZSBTZXR9IGlzIGJhY2tlZCBieQorICAgICAqIHRoaXMge0Bjb2RlIEVudW1NYXB9IHNvIGNoYW5nZXMgdG8gb25lIGFyZSByZWZsZWN0ZWQgaW4gdGhlIG90aGVyLiBUaGUge0Bjb2RlIFNldH0gZG9lcyBub3QKKyAgICAgKiBzdXBwb3J0IGFkZGluZy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgb3JkZXIgb2YgdGhlIHNldCB3aWxsIGJlIHRoZSBvcmRlciB0aGF0IHRoZSBlbnVtIGtleXMgd2VyZSBkZWNsYXJlZAorICAgICAqIGluLgorICAgICAqCisgICAgICogQHJldHVybiBhIHtAY29kZSBTZXR9IG9mIHRoZSBrZXlzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTZXQ8Sz4ga2V5U2V0KCkgeworICAgICAgICBpZiAoa2V5U2V0ID09IG51bGwpIHsKKyAgICAgICAgICAgIGtleVNldCA9IG5ldyBFbnVtTWFwS2V5U2V0PEssIFY+KHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBrZXlTZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFwcyB0aGUgc3BlY2lmaWVkIGtleSB0byB0aGUgc3BlY2lmaWVkIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleS4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiBhbnkgcHJldmlvdXMgbWFwcGluZyB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IG9yCisgICAgICogICAgICAgICB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgd2FzIG5vIG1hcHBpbmcuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGFkZGluZyB0byB0aGlzIG1hcCBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIHRoZSBrZXkgb3IgdmFsdWUgaXMgaW5hcHByb3ByaWF0ZSBmb3IgdGhpcworICAgICAqICAgICAgICAgICAgICAgIG1hcC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSBrZXkgb3IgdmFsdWUgY2Fubm90IGJlIGFkZGVkIHRvIHRoaXMgbWFwLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUga2V5IG9yIHZhbHVlIGlzIHtAY29kZSBudWxsfSBhbmQgdGhpcyB7QGNvZGUgRW51bU1hcH0gZG9lcyBub3QKKyAgICAgKiAgICAgICAgICAgICAgICBzdXBwb3J0IHtAY29kZSBudWxsfSBrZXlzIG9yIHZhbHVlcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgViBwdXQoSyBrZXksIFYgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIHB1dEltcGwoa2V5LCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29waWVzIGV2ZXJ5IG1hcHBpbmcgaW4gdGhlIHNwZWNpZmllZCB7QGNvZGUgTWFwfSB0byB0aGlzIHtAY29kZSBFbnVtTWFwfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtYXAKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgTWFwfSB0byBjb3B5IG1hcHBpbmdzIGZyb20uCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGFkZGluZyB0byB0aGlzIHtAY29kZSBFbnVtTWFwfSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIGEga2V5IG9yIHZhbHVlIGlzIGluYXBwcm9wcmlhdGUgZm9yIHRoaXMKKyAgICAgKiAgICAgICAgICAgICAgICB7QGNvZGUgRW51bU1hcH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBhIGtleSBvciB2YWx1ZSBjYW5ub3QgYmUgYWRkZWQgdG8gdGhpcyBtYXAuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGEga2V5IG9yIHZhbHVlIGlzIHtAY29kZSBudWxsfSBhbmQgdGhpcyB7QGNvZGUgRW51bU1hcH0gZG9lcyBub3QKKyAgICAgKiAgICAgICAgICAgICAgICBzdXBwb3J0IHtAY29kZSBudWxsfSBrZXlzIG9yIHZhbHVlcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgdm9pZCBwdXRBbGwoTWFwPD8gZXh0ZW5kcyBLLCA/IGV4dGVuZHMgVj4gbWFwKSB7CisgICAgICAgIHB1dEFsbEltcGwobWFwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGEgbWFwcGluZyB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IGZyb20gdGhpcyB7QGNvZGUgRW51bU1hcH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IG9mIHRoZSBtYXBwaW5nIHRvIHJlbW92ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgcmVtb3ZlZCBtYXBwaW5nIG9yIHtAY29kZSBudWxsfSBpZiBubyBtYXBwaW5nCisgICAgICogICAgICAgICBmb3IgdGhlIHNwZWNpZmllZCBrZXkgd2FzIGZvdW5kLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiByZW1vdmluZyBmcm9tIHRoaXMge0Bjb2RlIEVudW1NYXB9IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIFYgcmVtb3ZlKE9iamVjdCBrZXkpIHsKKyAgICAgICAgaWYgKCFpc1ZhbGlkS2V5VHlwZShrZXkpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpbnQga2V5T3JkaW5hbCA9ICgoRW51bSkga2V5KS5vcmRpbmFsKCk7CisgICAgICAgIGlmIChoYXNNYXBwaW5nW2tleU9yZGluYWxdKSB7CisgICAgICAgICAgICBoYXNNYXBwaW5nW2tleU9yZGluYWxdID0gZmFsc2U7CisgICAgICAgICAgICBtYXBwaW5nc0NvdW50LS07CisgICAgICAgIH0KKyAgICAgICAgViBvbGRWYWx1ZSA9IChWKSB2YWx1ZXNba2V5T3JkaW5hbF07CisgICAgICAgIHZhbHVlc1trZXlPcmRpbmFsXSA9IG51bGw7CisgICAgICAgIHJldHVybiBvbGRWYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyB7QGNvZGUgRW51bU1hcH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyB7QGNvZGUgRW51bU1hcH0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICByZXR1cm4gbWFwcGluZ3NDb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIENvbGxlY3Rpb259IG9mIHRoZSB2YWx1ZXMgY29udGFpbmVkIGluIHRoaXMge0Bjb2RlIEVudW1NYXB9LiBUaGUgcmV0dXJuZWQKKyAgICAgKiB7QGNvZGUgQ29sbGVjdGlvbn0gY29tcGxpZXMgd2l0aCB0aGUgZ2VuZXJhbCBydWxlIHNwZWNpZmllZCBpbgorICAgICAqIHtAbGluayBNYXAjdmFsdWVzKCl9LiBUaGUge0Bjb2RlIENvbGxlY3Rpb259J3Mge0Bjb2RlIEl0ZXJhdG9yfSB3aWxsIHJldHVybiB0aGUgdmFsdWVzCisgICAgICogaW4gdGhlIHRoZWlyIGNvcnJlc3BvbmRpbmcga2V5cycgbmF0dXJhbCBvcmRlciAodGhlIHtAY29kZSBFbnVtfSBjb25zdGFudHMgYXJlCisgICAgICogZGVjbGFyZWQgaW4gdGhpcyBvcmRlcikuCisgICAgICogPHA+CisgICAgICogVGhlIG9yZGVyIG9mIHRoZSB2YWx1ZXMgaW4gdGhlIGNvbGxlY3Rpb24gd2lsbCBiZSB0aGUgb3JkZXIgdGhhdCB0aGVpcgorICAgICAqIGNvcnJlc3BvbmRpbmcgZW51bSBrZXlzIHdlcmUgZGVjbGFyZWQgaW4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29sbGVjdGlvbiBvZiB0aGUgdmFsdWVzIGNvbnRhaW5lZCBpbiB0aGlzIHtAY29kZSBFbnVtTWFwfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ29sbGVjdGlvbjxWPiB2YWx1ZXMoKSB7CisgICAgICAgIGlmICh2YWx1ZXNDb2xsZWN0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIHZhbHVlc0NvbGxlY3Rpb24gPSBuZXcgRW51bU1hcFZhbHVlQ29sbGVjdGlvbjxLLCBWPih0aGlzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdmFsdWVzQ29sbGVjdGlvbjsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBzdHJlYW0uZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgaW5pdGlhbGl6YXRpb24oa2V5VHlwZSk7CisgICAgICAgIGludCBlbGVtZW50Q291bnQgPSBzdHJlYW0ucmVhZEludCgpOworICAgICAgICBFbnVtPEs+IGVudW1LZXk7CisgICAgICAgIE9iamVjdCB2YWx1ZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IGVsZW1lbnRDb3VudDsgaSA+IDA7IGktLSkgeworICAgICAgICAgICAgZW51bUtleSA9IChFbnVtPEs+KSBzdHJlYW0ucmVhZE9iamVjdCgpOworICAgICAgICAgICAgdmFsdWUgPSBzdHJlYW0ucmVhZE9iamVjdCgpOworICAgICAgICAgICAgcHV0SW1wbCgoSykgZW51bUtleSwgKFYpIHZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdHJlYW0uZGVmYXVsdFdyaXRlT2JqZWN0KCk7CisgICAgICAgIHN0cmVhbS53cml0ZUludChtYXBwaW5nc0NvdW50KTsKKyAgICAgICAgSXRlcmF0b3I8TWFwLkVudHJ5PEssIFY+PiBpdGVyYXRvciA9IGVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgeworICAgICAgICAgICAgTWFwLkVudHJ5PEssIFY+IGVudHJ5ID0gaXRlcmF0b3IubmV4dCgpOworICAgICAgICAgICAgc3RyZWFtLndyaXRlT2JqZWN0KGVudHJ5LmdldEtleSgpKTsKKyAgICAgICAgICAgIHN0cmVhbS53cml0ZU9iamVjdChlbnRyeS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBpc1ZhbGlkS2V5VHlwZShPYmplY3Qga2V5KSB7CisgICAgICAgIGlmIChrZXkgIT0gbnVsbCAmJiBrZXlUeXBlLmlzSW5zdGFuY2Uoa2V5KSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHByaXZhdGUgdm9pZCBpbml0aWFsaXphdGlvbihFbnVtTWFwIGVudW1NYXApIHsKKyAgICAgICAga2V5VHlwZSA9IGVudW1NYXAua2V5VHlwZTsKKyAgICAgICAga2V5cyA9IGVudW1NYXAua2V5czsKKyAgICAgICAgZW51bVNpemUgPSBlbnVtTWFwLmVudW1TaXplOworICAgICAgICB2YWx1ZXMgPSBlbnVtTWFwLnZhbHVlcy5jbG9uZSgpOworICAgICAgICBoYXNNYXBwaW5nID0gZW51bU1hcC5oYXNNYXBwaW5nLmNsb25lKCk7CisgICAgICAgIG1hcHBpbmdzQ291bnQgPSBlbnVtTWFwLm1hcHBpbmdzQ291bnQ7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGluaXRpYWxpemF0aW9uKENsYXNzPEs+IHR5cGUpIHsKKyAgICAgICAga2V5VHlwZSA9IHR5cGU7CisgICAgICAgIGtleXMgPSBFbnVtLmdldFNoYXJlZENvbnN0YW50cyhrZXlUeXBlKTsKKyAgICAgICAgZW51bVNpemUgPSBrZXlzLmxlbmd0aDsKKyAgICAgICAgdmFsdWVzID0gbmV3IE9iamVjdFtlbnVtU2l6ZV07CisgICAgICAgIGhhc01hcHBpbmcgPSBuZXcgYm9vbGVhbltlbnVtU2l6ZV07CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHJpdmF0ZSB2b2lkIHB1dEFsbEltcGwoTWFwIG1hcCkgeworICAgICAgICBJdGVyYXRvciBpdGVyID0gbWFwLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0ZXIuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBNYXAuRW50cnkgZW50cnkgPSAoTWFwLkVudHJ5KSBpdGVyLm5leHQoKTsKKyAgICAgICAgICAgIHB1dEltcGwoKEspIGVudHJ5LmdldEtleSgpLCAoVikgZW50cnkuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIFYgcHV0SW1wbChLIGtleSwgViB2YWx1ZSkgeworICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGtleVR5cGUuY2FzdChrZXkpOyAvLyBDYWxsZWQgdG8gdGhyb3cgQ2xhc3NDYXN0RXhjZXB0aW9uLgorICAgICAgICBpbnQga2V5T3JkaW5hbCA9IGtleS5vcmRpbmFsKCk7CisgICAgICAgIGlmICghaGFzTWFwcGluZ1trZXlPcmRpbmFsXSkgeworICAgICAgICAgICAgaGFzTWFwcGluZ1trZXlPcmRpbmFsXSA9IHRydWU7CisgICAgICAgICAgICBtYXBwaW5nc0NvdW50Kys7CisgICAgICAgIH0KKyAgICAgICAgViBvbGRWYWx1ZSA9IChWKSB2YWx1ZXNba2V5T3JkaW5hbF07CisgICAgICAgIHZhbHVlc1trZXlPcmRpbmFsXSA9IHZhbHVlOworICAgICAgICByZXR1cm4gb2xkVmFsdWU7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0VudW1TZXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRW51bVNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjODk2OWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0VudW1TZXQuamF2YQpAQCAtMCwwICsxLDM0MiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKKy8qKgorICogQW4gRW51bVNldCBpcyBhIHNwZWNpYWxpemVkIFNldCB0byBiZSB1c2VkIHdpdGggZW51bXMgYXMga2V5cy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEVudW1TZXQ8RSBleHRlbmRzIEVudW08RT4+IGV4dGVuZHMgQWJzdHJhY3RTZXQ8RT4KKyAgICAgICAgaW1wbGVtZW50cyBDbG9uZWFibGUsIFNlcmlhbGl6YWJsZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTAwOTY4NzQ4NDA1OTg4ODA5M0w7CisKKyAgICBmaW5hbCBDbGFzczxFPiBlbGVtZW50Q2xhc3M7CisKKyAgICBFbnVtU2V0KENsYXNzPEU+IGNscykgeworICAgICAgICBlbGVtZW50Q2xhc3MgPSBjbHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBlbXB0eSBlbnVtIHNldC4gVGhlIHBlcm1pdHRlZCBlbGVtZW50cyBhcmUgb2YgdHlwZQorICAgICAqIENsYXNzJmx0O0UmZ3Q7LgorICAgICAqCisgICAgICogQHBhcmFtIGVsZW1lbnRUeXBlCisgICAgICogICAgICAgICAgICB0aGUgY2xhc3Mgb2JqZWN0IGZvciB0aGUgZWxlbWVudHMgY29udGFpbmVkLgorICAgICAqIEByZXR1cm4gYW4gZW1wdHkgZW51bSBzZXQsIHdpdGggcGVybWl0dGVkIGVsZW1lbnRzIG9mIHR5cGUge0Bjb2RlCisgICAgICogICAgICAgICBlbGVtZW50VHlwZX0uCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgdHlwZSBpcyBub3QgYW5kIGVudW0gdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxFIGV4dGVuZHMgRW51bTxFPj4gRW51bVNldDxFPiBub25lT2YoQ2xhc3M8RT4gZWxlbWVudFR5cGUpIHsKKyAgICAgICAgaWYgKCFlbGVtZW50VHlwZS5pc0VudW0oKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzQ2FzdEV4Y2VwdGlvbihlbGVtZW50VHlwZS5nZXRDbGFzcygpLmdldE5hbWUoKSArICIgaXMgbm90IGFuIEVudW0iKTsKKyAgICAgICAgfQorICAgICAgICBFW10gZW51bXMgPSBFbnVtLmdldFNoYXJlZENvbnN0YW50cyhlbGVtZW50VHlwZSk7CisgICAgICAgIGlmIChlbnVtcy5sZW5ndGggPD0gNjQpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgTWluaUVudW1TZXQ8RT4oZWxlbWVudFR5cGUsIGVudW1zKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEh1Z2VFbnVtU2V0PEU+KGVsZW1lbnRUeXBlLCBlbnVtcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBlbnVtIHNldCBmaWxsZWQgd2l0aCBhbGwgdGhlIGVudW0gZWxlbWVudHMgb2YgdGhlIHNwZWNpZmllZAorICAgICAqIHtAY29kZSBlbGVtZW50VHlwZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZWxlbWVudFR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjbGFzcyBvYmplY3QgZm9yIHRoZSBlbGVtZW50cyBjb250YWluZWQuCisgICAgICogQHJldHVybiBhbiBlbnVtIHNldCB3aXRoIGVsZW1lbnRzIHNvbGVseSBmcm9tIHRoZSBzcGVjaWZpZWQgZWxlbWVudCB0eXBlLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IHR5cGUgaXMgbm90IGFuZCBlbnVtIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8RSBleHRlbmRzIEVudW08RT4+IEVudW1TZXQ8RT4gYWxsT2YoQ2xhc3M8RT4gZWxlbWVudFR5cGUpIHsKKyAgICAgICAgRW51bVNldDxFPiBzZXQgPSBub25lT2YoZWxlbWVudFR5cGUpOworICAgICAgICBzZXQuY29tcGxlbWVudCgpOworICAgICAgICByZXR1cm4gc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gZW51bSBzZXQuIEFsbCB0aGUgY29udGFpbmVkIGVsZW1lbnRzIGFyZSBvZiB0eXBlCisgICAgICogQ2xhc3MmbHQ7RSZndDssIGFuZCB0aGUgY29udGFpbmVkIGVsZW1lbnRzIGFyZSB0aGUgc2FtZSBhcyB0aG9zZQorICAgICAqIGNvbnRhaW5lZCBpbiB7QGNvZGUgc30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIGVudW0gc2V0IGZyb20gd2hpY2ggdG8gY29weS4KKyAgICAgKiBAcmV0dXJuIGFuIGVudW0gc2V0IHdpdGggYWxsIHRoZSBlbGVtZW50cyBmcm9tIHRoZSBzcGVjaWZpZWQgZW51bSBzZXQuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgdHlwZSBpcyBub3QgYW5kIGVudW0gdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxFIGV4dGVuZHMgRW51bTxFPj4gRW51bVNldDxFPiBjb3B5T2YoRW51bVNldDxFPiBzKSB7CisgICAgICAgIEVudW1TZXQ8RT4gc2V0ID0gRW51bVNldC5ub25lT2Yocy5lbGVtZW50Q2xhc3MpOworICAgICAgICBzZXQuYWRkQWxsKHMpOworICAgICAgICByZXR1cm4gc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gZW51bSBzZXQuIFRoZSBjb250YWluZWQgZWxlbWVudHMgYXJlIHRoZSBzYW1lIGFzIHRob3NlCisgICAgICogY29udGFpbmVkIGluIGNvbGxlY3Rpb24ge0Bjb2RlIGN9LiBJZiBjIGlzIGFuIGVudW0gc2V0LCBpbnZva2luZyB0aGlzCisgICAgICogbWV0aG9kIGlzIHRoZSBzYW1lIGFzIGludm9raW5nIHtAbGluayAjY29weU9mKEVudW1TZXQpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY29sbGVjdGlvbiBmcm9tIHdoaWNoIHRvIGNvcHkuIGlmIGl0IGlzIG5vdCBhbiBlbnVtIHNldCwKKyAgICAgKiAgICAgICAgICAgIGl0IG11c3Qgbm90IGJlIGVtcHR5LgorICAgICAqIEByZXR1cm4gYW4gZW51bSBzZXQgd2l0aCBhbGwgdGhlIGVsZW1lbnRzIGZyb20gdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYyBpcyBub3QgYW4gZW51bSBzZXQgYW5kIGNvbnRhaW5zIG5vIGVsZW1lbnRzIGF0IGFsbC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGN9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxFIGV4dGVuZHMgRW51bTxFPj4gRW51bVNldDxFPiBjb3B5T2YoQ29sbGVjdGlvbjxFPiBjKSB7CisgICAgICAgIGlmIChjIGluc3RhbmNlb2YgRW51bVNldCkgeworICAgICAgICAgICAgcmV0dXJuIGNvcHlPZigoRW51bVNldDxFPikgYyk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgSXRlcmF0b3I8RT4gaXRlcmF0b3IgPSBjLml0ZXJhdG9yKCk7CisgICAgICAgIEUgZWxlbWVudCA9IGl0ZXJhdG9yLm5leHQoKTsKKyAgICAgICAgRW51bVNldDxFPiBzZXQgPSBFbnVtU2V0Lm5vbmVPZihlbGVtZW50LmdldERlY2xhcmluZ0NsYXNzKCkpOworICAgICAgICBzZXQuYWRkKGVsZW1lbnQpOworICAgICAgICB3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBzZXQuYWRkKGl0ZXJhdG9yLm5leHQoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGVudW0gc2V0LiBBbGwgdGhlIGNvbnRhaW5lZCBlbGVtZW50cyBjb21wbGVtZW50IHRob3NlIGZyb20gdGhlCisgICAgICogc3BlY2lmaWVkIGVudW0gc2V0LgorICAgICAqCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgZW51bSBzZXQuCisgICAgICogQHJldHVybiBhbiBlbnVtIHNldCB3aXRoIGFsbCB0aGUgZWxlbWVudHMgY29tcGxlbWVudGFyeSB0byB0aG9zZSBmcm9tIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIGVudW0gc2V0LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPEUgZXh0ZW5kcyBFbnVtPEU+PiBFbnVtU2V0PEU+IGNvbXBsZW1lbnRPZihFbnVtU2V0PEU+IHMpIHsKKyAgICAgICAgRW51bVNldDxFPiBzZXQgPSBFbnVtU2V0Lm5vbmVPZihzLmVsZW1lbnRDbGFzcyk7CisgICAgICAgIHNldC5hZGRBbGwocyk7CisgICAgICAgIHNldC5jb21wbGVtZW50KCk7CisgICAgICAgIHJldHVybiBzZXQ7CisgICAgfQorCisgICAgYWJzdHJhY3Qgdm9pZCBjb21wbGVtZW50KCk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGVudW0gc2V0LCBjb250YWluaW5nIG9ubHkgdGhlIHNwZWNpZmllZCBlbGVtZW50LiBUaGVyZSBhcmUKKyAgICAgKiBzaXggb3ZlcmxvYWRpbmdzIG9mIHRoZSBtZXRob2QuIFRoZXkgYWNjZXB0IGZyb20gb25lIHRvIGZpdmUgZWxlbWVudHMKKyAgICAgKiByZXNwZWN0aXZlbHkuIFRoZSBzaXh0aCBvbmUgcmVjZWl2ZXMgYW4gYXJiaXRyYXJ5IG51bWJlciBvZiBlbGVtZW50cywgYW5kCisgICAgICogcnVucyBzbG93ZXIgdGhhbiB0aG9zZSB0aGF0IG9ubHkgcmVjZWl2ZSBhIGZpeGVkIG51bWJlciBvZiBlbGVtZW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCB0byBiZSBpbml0aWFsbHkgY29udGFpbmVkLgorICAgICAqIEByZXR1cm4gYW4gZW51bSBzZXQgY29udGFpbmluZyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBlfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8RSBleHRlbmRzIEVudW08RT4+IEVudW1TZXQ8RT4gb2YoRSBlKSB7CisgICAgICAgIEVudW1TZXQ8RT4gc2V0ID0gRW51bVNldC5ub25lT2YoZS5nZXREZWNsYXJpbmdDbGFzcygpKTsKKyAgICAgICAgc2V0LmFkZChlKTsKKyAgICAgICAgcmV0dXJuIHNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGVudW0gc2V0LCBjb250YWluaW5nIG9ubHkgdGhlIHNwZWNpZmllZCBlbGVtZW50cy4gVGhlcmUgYXJlCisgICAgICogc2l4IG92ZXJsb2FkaW5ncyBvZiB0aGUgbWV0aG9kLiBUaGV5IGFjY2VwdCBmcm9tIG9uZSB0byBmaXZlIGVsZW1lbnRzCisgICAgICogcmVzcGVjdGl2ZWx5LiBUaGUgc2l4dGggb25lIHJlY2VpdmVzIGFuIGFyYml0cmFyeSBudW1iZXIgb2YgZWxlbWVudHMsIGFuZAorICAgICAqIHJ1bnMgc2xvd2VyIHRoYW4gdGhvc2UgdGhhdCBvbmx5IHJlY2VpdmUgYSBmaXhlZCBudW1iZXIgb2YgZWxlbWVudHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZTEKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsbHkgY29udGFpbmVkIGVsZW1lbnQuCisgICAgICogQHBhcmFtIGUyCisgICAgICogICAgICAgICAgICBhbm90aGVyIGluaXRpYWxseSBjb250YWluZWQgZWxlbWVudC4KKyAgICAgKiBAcmV0dXJuIGFuIGVudW0gc2V0IGNvbnRhaW5pbmcgdGhlIHNwZWNpZmllZCBlbGVtZW50cy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudHMgaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPEUgZXh0ZW5kcyBFbnVtPEU+PiBFbnVtU2V0PEU+IG9mKEUgZTEsIEUgZTIpIHsKKyAgICAgICAgRW51bVNldDxFPiBzZXQgPSBvZihlMSk7CisgICAgICAgIHNldC5hZGQoZTIpOworICAgICAgICByZXR1cm4gc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgZW51bSBzZXQsIGNvbnRhaW5pbmcgb25seSB0aGUgc3BlY2lmaWVkIGVsZW1lbnRzLiBUaGVyZSBhcmUKKyAgICAgKiBzaXggb3ZlcmxvYWRpbmdzIG9mIHRoZSBtZXRob2QuIFRoZXkgYWNjZXB0IGZyb20gb25lIHRvIGZpdmUgZWxlbWVudHMKKyAgICAgKiByZXNwZWN0aXZlbHkuIFRoZSBzaXh0aCBvbmUgcmVjZWl2ZXMgYW4gYXJiaXRyYXJ5IG51bWJlciBvZiBlbGVtZW50cywgYW5kCisgICAgICogcnVucyBzbG93ZXIgdGhhbiB0aG9zZSB0aGF0IG9ubHkgcmVjZWl2ZSBhIGZpeGVkIG51bWJlciBvZiBlbGVtZW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlMQorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWxseSBjb250YWluZWQgZWxlbWVudC4KKyAgICAgKiBAcGFyYW0gZTIKKyAgICAgKiAgICAgICAgICAgIGFub3RoZXIgaW5pdGlhbGx5IGNvbnRhaW5lZCBlbGVtZW50LgorICAgICAqIEBwYXJhbSBlMworICAgICAqICAgICAgICAgICAgYW5vdGhlciBpbml0aWFsbHkgY29udGFpbmVkIGVsZW1lbnQuCisgICAgICogQHJldHVybiBhbiBlbnVtIHNldCBjb250YWluaW5nIHRoZSBzcGVjaWZpZWQgZWxlbWVudHMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnRzIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxFIGV4dGVuZHMgRW51bTxFPj4gRW51bVNldDxFPiBvZihFIGUxLCBFIGUyLCBFIGUzKSB7CisgICAgICAgIEVudW1TZXQ8RT4gc2V0ID0gb2YoZTEsIGUyKTsKKyAgICAgICAgc2V0LmFkZChlMyk7CisgICAgICAgIHJldHVybiBzZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBlbnVtIHNldCwgY29udGFpbmluZyBvbmx5IHRoZSBzcGVjaWZpZWQgZWxlbWVudHMuIFRoZXJlIGFyZQorICAgICAqIHNpeCBvdmVybG9hZGluZ3Mgb2YgdGhlIG1ldGhvZC4gVGhleSBhY2NlcHQgZnJvbSBvbmUgdG8gZml2ZSBlbGVtZW50cworICAgICAqIHJlc3BlY3RpdmVseS4gVGhlIHNpeHRoIG9uZSByZWNlaXZlcyBhbiBhcmJpdHJhcnkgbnVtYmVyIG9mIGVsZW1lbnRzLCBhbmQKKyAgICAgKiBydW5zIHNsb3dlciB0aGFuIHRob3NlIHRoYXQgb25seSByZWNlaXZlIGEgZml4ZWQgbnVtYmVyIG9mIGVsZW1lbnRzLgorICAgICAqCisgICAgICogQHBhcmFtIGUxCisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbGx5IGNvbnRhaW5lZCBlbGVtZW50LgorICAgICAqIEBwYXJhbSBlMgorICAgICAqICAgICAgICAgICAgYW5vdGhlciBpbml0aWFsbHkgY29udGFpbmVkIGVsZW1lbnQuCisgICAgICogQHBhcmFtIGUzCisgICAgICogICAgICAgICAgICBhbm90aGVyIGluaXRpYWxseSBjb250YWluZWQgZWxlbWVudC4KKyAgICAgKiBAcGFyYW0gZTQKKyAgICAgKiAgICAgICAgICAgIGFub3RoZXIgaW5pdGlhbGx5IGNvbnRhaW5lZCBlbGVtZW50LgorICAgICAqIEByZXR1cm4gYW4gZW51bSBzZXQgY29udGFpbmluZyB0aGUgc3BlY2lmaWVkIGVsZW1lbnRzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50cyBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8RSBleHRlbmRzIEVudW08RT4+IEVudW1TZXQ8RT4gb2YoRSBlMSwgRSBlMiwgRSBlMywgRSBlNCkgeworICAgICAgICBFbnVtU2V0PEU+IHNldCA9IG9mKGUxLCBlMiwgZTMpOworICAgICAgICBzZXQuYWRkKGU0KTsKKyAgICAgICAgcmV0dXJuIHNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGVudW0gc2V0LCBjb250YWluaW5nIG9ubHkgdGhlIHNwZWNpZmllZCBlbGVtZW50cy4gVGhlcmUgYXJlCisgICAgICogc2l4IG92ZXJsb2FkaW5ncyBvZiB0aGUgbWV0aG9kLiBUaGV5IGFjY2VwdCBmcm9tIG9uZSB0byBmaXZlIGVsZW1lbnRzCisgICAgICogcmVzcGVjdGl2ZWx5LiBUaGUgc2l4dGggb25lIHJlY2VpdmVzIGFuIGFyYml0cmFyeSBudW1iZXIgb2YgZWxlbWVudHMsIGFuZAorICAgICAqIHJ1bnMgc2xvd2VyIHRoYW4gdGhvc2UgdGhhdCBvbmx5IHJlY2VpdmUgYSBmaXhlZCBudW1iZXIgb2YgZWxlbWVudHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZTEKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsbHkgY29udGFpbmVkIGVsZW1lbnQuCisgICAgICogQHBhcmFtIGUyCisgICAgICogICAgICAgICAgICBhbm90aGVyIGluaXRpYWxseSBjb250YWluZWQgZWxlbWVudC4KKyAgICAgKiBAcGFyYW0gZTMKKyAgICAgKiAgICAgICAgICAgIGFub3RoZXIgaW5pdGlhbGx5IGNvbnRhaW5lZCBlbGVtZW50LgorICAgICAqIEBwYXJhbSBlNAorICAgICAqICAgICAgICAgICAgYW5vdGhlciBpbml0aWFsbHkgY29udGFpbmVkIGVsZW1lbnQuCisgICAgICogQHBhcmFtIGU1CisgICAgICogICAgICAgICAgICBhbm90aGVyIGluaXRpYWxseSBjb250YWluZWQgZWxlbWVudC4KKyAgICAgKiBAcmV0dXJuIGFuIGVudW0gc2V0IGNvbnRhaW5pbmcgdGhlIHNwZWNpZmllZCBlbGVtZW50cy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudHMgaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPEUgZXh0ZW5kcyBFbnVtPEU+PiBFbnVtU2V0PEU+IG9mKEUgZTEsIEUgZTIsIEUgZTMsIEUgZTQsIEUgZTUpIHsKKyAgICAgICAgRW51bVNldDxFPiBzZXQgPSBvZihlMSwgZTIsIGUzLCBlNCk7CisgICAgICAgIHNldC5hZGQoZTUpOworICAgICAgICByZXR1cm4gc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgZW51bSBzZXQsIGNvbnRhaW5pbmcgb25seSB0aGUgc3BlY2lmaWVkIGVsZW1lbnRzLiBJdCBjYW4KKyAgICAgKiByZWNlaXZlIGFuIGFyYml0cmFyeSBudW1iZXIgb2YgZWxlbWVudHMsIGFuZCBydW5zIHNsb3dlciB0aGFuIHRob3NlIG9ubHkKKyAgICAgKiByZWNlaXZpbmcgYSBmaXhlZCBudW1iZXIgb2YgZWxlbWVudHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBpbml0aWFsbHkgY29udGFpbmVkIGVsZW1lbnQuCisgICAgICogQHBhcmFtIG90aGVycworICAgICAqICAgICAgICAgICAgdGhlIG90aGVyIGluaXRpYWxseSBjb250YWluZWQgZWxlbWVudHMuCisgICAgICogQHJldHVybiBhbiBlbnVtIHNldCBjb250YWluaW5nIHRoZSBzcGVjaWZpZWQgZWxlbWVudHMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnRzIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxFIGV4dGVuZHMgRW51bTxFPj4gRW51bVNldDxFPiBvZihFIHN0YXJ0LCBFLi4uIG90aGVycykgeworICAgICAgICBFbnVtU2V0PEU+IHNldCA9IG9mKHN0YXJ0KTsKKyAgICAgICAgZm9yIChFIGUgOiBvdGhlcnMpIHsKKyAgICAgICAgICAgIHNldC5hZGQoZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGVudW0gc2V0IGNvbnRhaW5pbmcgYWxsIHRoZSBlbGVtZW50cyB3aXRoaW4gdGhlIHJhbmdlIGRlZmluZWQKKyAgICAgKiBieSB7QGNvZGUgc3RhcnR9IGFuZCB7QGNvZGUgZW5kfSAoaW5jbHVzaXZlKS4gQWxsIHRoZSBlbGVtZW50cyBtdXN0IGJlIGluCisgICAgICogb3JkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IHVzZWQgdG8gZGVmaW5lIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHJhbmdlLgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbGVtZW50IHVzZWQgdG8gZGVmaW5lIHRoZSBlbmQgb2YgdGhlIHJhbmdlLgorICAgICAqIEByZXR1cm4gYW4gZW51bSBzZXQgd2l0aCBlbGVtZW50cyBpbiB0aGUgcmFuZ2UgZnJvbSBzdGFydCB0byBlbmQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBvbmUgb2Yge0Bjb2RlIHN0YXJ0fSBvciB7QGNvZGUgZW5kfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhcnR9IGlzIGJlaGluZCB7QGNvZGUgZW5kfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxFIGV4dGVuZHMgRW51bTxFPj4gRW51bVNldDxFPiByYW5nZShFIHN0YXJ0LCBFIGVuZCkgeworICAgICAgICBpZiAoc3RhcnQuY29tcGFyZVRvKGVuZCkgPiAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgRW51bVNldDxFPiBzZXQgPSBFbnVtU2V0Lm5vbmVPZihzdGFydC5nZXREZWNsYXJpbmdDbGFzcygpKTsKKyAgICAgICAgc2V0LnNldFJhbmdlKHN0YXJ0LCBlbmQpOworICAgICAgICByZXR1cm4gc2V0OworICAgIH0KKworICAgIGFic3RyYWN0IHZvaWQgc2V0UmFuZ2UoRSBzdGFydCwgRSBlbmQpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBlbnVtIHNldCB3aXRoIHRoZSBzYW1lIGVsZW1lbnRzIGFzIHRob3NlIGNvbnRhaW5lZCBpbiB0aGlzCisgICAgICogZW51bSBzZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgbmV3IGVudW0gc2V0IHdpdGggdGhlIHNhbWUgZWxlbWVudHMgYXMgdGhvc2UgY29udGFpbmVkIGluIHRoaXMKKyAgICAgKiAgICAgICAgIGVudW0gc2V0LgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBFbnVtU2V0PEU+IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIChFbnVtU2V0PEU+KSBzdXBlci5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBib29sZWFuIGlzVmFsaWRUeXBlKENsYXNzPD8+IGNscykgeworICAgICAgICByZXR1cm4gY2xzID09IGVsZW1lbnRDbGFzcyB8fCBjbHMuZ2V0U3VwZXJjbGFzcygpID09IGVsZW1lbnRDbGFzczsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTZXJpYWxpemF0aW9uUHJveHk8RSBleHRlbmRzIEVudW08RT4+IGltcGxlbWVudHMKKyAgICAgICAgICAgIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzYyNDkxMjM0NTYzMTgxMjY1TDsKKworICAgICAgICBwcml2YXRlIENsYXNzPEU+IGVsZW1lbnRUeXBlOworCisgICAgICAgIHByaXZhdGUgRVtdIGVsZW1lbnRzOworCisgICAgICAgIHByaXZhdGUgT2JqZWN0IHJlYWRSZXNvbHZlKCkgeworICAgICAgICAgICAgRW51bVNldDxFPiBzZXQgPSBFbnVtU2V0Lm5vbmVPZihlbGVtZW50VHlwZSk7CisgICAgICAgICAgICBmb3IgKEUgZSA6IGVsZW1lbnRzKSB7CisgICAgICAgICAgICAgICAgc2V0LmFkZChlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBzZXQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBPYmplY3Qgd3JpdGVSZXBsYWNlKCkgeworICAgICAgICBTZXJpYWxpemF0aW9uUHJveHkgcHJveHkgPSBuZXcgU2VyaWFsaXphdGlvblByb3h5KCk7CisgICAgICAgIHByb3h5LmVsZW1lbnRzID0gdG9BcnJheShuZXcgRW51bVswXSk7CisgICAgICAgIHByb3h5LmVsZW1lbnRUeXBlID0gZWxlbWVudENsYXNzOworICAgICAgICByZXR1cm4gcHJveHk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9FbnVtZXJhdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9FbnVtZXJhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiZGNiN2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0VudW1lcmF0aW9uLmphdmEKQEAgLTAsMCArMSw1NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKKy8qKgorICogQSBsZWdhY3kgaXRlcmF0aW9uIGludGVyZmFjZS4KKyAqCisgKiA8cD5OZXcgY29kZSBzaG91bGQgdXNlIHtAbGluayBJdGVyYXRvcn0gaW5zdGVhZC4ge0Bjb2RlIEl0ZXJhdG9yfSByZXBsYWNlcyB0aGUKKyAqIGVudW1lcmF0aW9uIGludGVyZmFjZSBhbmQgYWRkcyBhIHdheSB0byByZW1vdmUgZWxlbWVudHMgZnJvbSBhIGNvbGxlY3Rpb24uCisgKgorICogPHA+SWYgeW91IDxpPmhhdmU8L2k+IGFuIHtAY29kZSBFbnVtZXJhdGlvbn0gYW5kIHdhbnQgYSB7QGNvZGUgQ29sbGVjdGlvbn0sIHlvdQorICogY2FuIHVzZSB7QGxpbmsgQ29sbGVjdGlvbnMjbGlzdH0gdG8gZ2V0IGEge0Bjb2RlIExpc3R9LgorICoKKyAqIDxwPklmIHlvdSA8aT5uZWVkPC9pPiBhbiB7QGNvZGUgRW51bWVyYXRpb259IGZvciBhIGxlZ2FjeSBBUEkgYW5kIGhhdmUgYQorICoge0Bjb2RlIENvbGxlY3Rpb259LCB5b3UgY2FuIHVzZSB7QGxpbmsgQ29sbGVjdGlvbnMjZW51bWVyYXRpb259LgorICoKKyAqIEB2ZXJzaW9uIDEuMAorICogQHNlZSBJdGVyYXRvcgorICovCitwdWJsaWMgaW50ZXJmYWNlIEVudW1lcmF0aW9uPEU+IHsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIHtAY29kZSBFbnVtZXJhdGlvbn0gaGFzIG1vcmUgZWxlbWVudHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGVyZSBhcmUgbW9yZSBlbGVtZW50cywge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNlZSAjbmV4dEVsZW1lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNNb3JlRWxlbWVudHMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgZWxlbWVudCBpbiB0aGlzIHtAY29kZSBFbnVtZXJhdGlvbn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGVsZW1lbnQuLgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGFyZSBubyBtb3JlIGVsZW1lbnRzLgorICAgICAqIEBzZWUgI2hhc01vcmVFbGVtZW50cworICAgICAqLworICAgIHB1YmxpYyBFIG5leHRFbGVtZW50KCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0V2ZW50TGlzdGVuZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRXZlbnRMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5NGUwNjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0V2ZW50TGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDI3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworLyoqCisgKiBFdmVudExpc3RlbmVyIGlzIHRoZSBzdXBlcmNsYXNzIG9mIGFsbCBldmVudCBsaXN0ZW5lciBpbnRlcmZhY2VzLgorICoKKyAqIEBzZWUgRXZlbnRPYmplY3QKKyAqLworcHVibGljIGludGVyZmFjZSBFdmVudExpc3RlbmVyIHsKKyAgICAvKiBlbXB0eSAqLworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9FdmVudExpc3RlbmVyUHJveHkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRXZlbnRMaXN0ZW5lclByb3h5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzRiNTBiYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRXZlbnRMaXN0ZW5lclByb3h5LmphdmEKQEAgLTAsMCArMSw0NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKKworLyoqCisgKiBUaGlzIGFic3RyYWN0IGNsYXNzIHByb3ZpZGVzIGEgc2ltcGxlIHdyYXBwZXIgZm9yIG9iamVjdHMgb2YgdHlwZSB7QGNvZGUgRXZlbnRMaXN0ZW5lcn0uCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBFdmVudExpc3RlbmVyUHJveHkgaW1wbGVtZW50cyBFdmVudExpc3RlbmVyIHsKKworICAgIHByaXZhdGUgZmluYWwgRXZlbnRMaXN0ZW5lciBsaXN0ZW5lcjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEV2ZW50TGlzdGVuZXJ9IHByb3h5IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIGxpc3RlbmVyCisgICAgICogICAgICAgICAgICB0aGUgbGlzdGVuZXIgd3JhcHBlZCBieSB0aGlzIHByb3h5LgorICAgICAqLworICAgIHB1YmxpYyBFdmVudExpc3RlbmVyUHJveHkoRXZlbnRMaXN0ZW5lciBsaXN0ZW5lcikgeworICAgICAgICB0aGlzLmxpc3RlbmVyID0gbGlzdGVuZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgd3JhcHBlZCB7QGNvZGUgRXZlbnRMaXN0ZW5lcn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB3cmFwcGVkIHtAY29kZSBFdmVudExpc3RlbmVyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRXZlbnRMaXN0ZW5lciBnZXRMaXN0ZW5lcigpIHsKKyAgICAgICAgcmV0dXJuIGxpc3RlbmVyOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRXZlbnRPYmplY3QuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRXZlbnRPYmplY3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNThlN2U4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9FdmVudE9iamVjdC5qYXZhCkBAIC0wLDAgKzEsNjIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworLyoqCisgKiB7QGNvZGUgRXZlbnRPYmplY3R9cyByZXByZXNlbnQgZXZlbnRzLiBUeXBpY2FsbHkgYXBwbGljYXRpb25zIHN1YmNsYXNzIHRoaXMgY2xhc3MgdG8KKyAqIGFkZCBldmVudCBzcGVjaWZpYyBpbmZvcm1hdGlvbi4KKyAqCisgKiBAc2VlIEV2ZW50TGlzdGVuZXIKKyAqLworcHVibGljIGNsYXNzIEV2ZW50T2JqZWN0IGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDU1MTYwNzUzNDk2MjA2NTM0ODBMOworCisgICAgQEZpbmRCdWdzU3VwcHJlc3NXYXJuaW5ncygiU0VfVFJBTlNJRU5UX0ZJRUxEX05PVF9SRVNUT1JFRCIpCisgICAgcHJvdGVjdGVkIHRyYW5zaWVudCBPYmplY3Qgc291cmNlOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB3aGljaCBmaXJlZCB0aGUgZXZlbnQuCisgICAgICovCisgICAgcHVibGljIEV2ZW50T2JqZWN0KE9iamVjdCBzb3VyY2UpIHsKKyAgICAgICAgaWYgKHNvdXJjZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zb3VyY2UgPSBzb3VyY2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgb2JqZWN0IHdoaWNoIGZpcmVkIHRoZSBldmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldFNvdXJjZSgpIHsKKyAgICAgICAgcmV0dXJuIHNvdXJjZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgRXZlbnRPYmplY3R9LgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiW3NvdXJjZT0iICsgc291cmNlICsgJ10nOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRm9ybWF0RmxhZ3NDb252ZXJzaW9uTWlzbWF0Y2hFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRm9ybWF0RmxhZ3NDb252ZXJzaW9uTWlzbWF0Y2hFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NzkyODc3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9Gb3JtYXRGbGFnc0NvbnZlcnNpb25NaXNtYXRjaEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNzUgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKKy8qKgorICogQSB7QGNvZGUgRm9ybWF0RmxhZ3NDb252ZXJzaW9uTWlzbWF0Y2hFeGNlcHRpb259IHdpbGwgYmUgdGhyb3duIGlmIGEKKyAqIGNvbnZlcnNpb24gYW5kIHRoZSBmbGFncyBhcmUgaW5jb21wYXRpYmxlLgorICoKKyAqIEBzZWUgamF2YS5sYW5nLlJ1bnRpbWVFeGNlcHRpb24KKyAqLworcHVibGljIGNsYXNzIEZvcm1hdEZsYWdzQ29udmVyc2lvbk1pc21hdGNoRXhjZXB0aW9uIGV4dGVuZHMKKyAgICAgICAgSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbiBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxOTEyMDQxNEw7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBmOworCisgICAgcHJpdmF0ZSBmaW5hbCBjaGFyIGM7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBGb3JtYXRGbGFnc0NvbnZlcnNpb25NaXNtYXRjaEV4Y2VwdGlvbn0gd2l0aCB0aGUKKyAgICAgKiBmbGFncyBhbmQgY29udmVyc2lvbiBzcGVjaWZpZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZgorICAgICAqICAgICAgICAgICB0aGUgZmxhZ3MuCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgdGhlIGNvbnZlcnNpb24uCisgICAgICovCisgICAgcHVibGljIEZvcm1hdEZsYWdzQ29udmVyc2lvbk1pc21hdGNoRXhjZXB0aW9uKFN0cmluZyBmLCBjaGFyIGMpIHsKKyAgICAgICAgaWYgKGYgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5mID0gZjsKKyAgICAgICAgdGhpcy5jID0gYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmNvbXBhdGlibGUgZm9ybWF0IGZsYWcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbmNvbXBhdGlibGUgZm9ybWF0IGZsYWcuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRGbGFncygpIHsKKyAgICAgICAgcmV0dXJuIGY7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5jb21wYXRpYmxlIGNvbnZlcnNpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbmNvbXBhdGlibGUgY29udmVyc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgY2hhciBnZXRDb252ZXJzaW9uKCkgeworICAgICAgICByZXR1cm4gYzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2UoKSB7CisgICAgICAgIHJldHVybiAiJSIgKyBjICsgIiBkb2VzIG5vdCBzdXBwb3J0ICciICsgZiArICInIjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0Zvcm1hdHRhYmxlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0Zvcm1hdHRhYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjRlYzExZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRm9ybWF0dGFibGUuamF2YQpAQCAtMCwwICsxLDU5IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworLyoqCisgKiBDbGFzc2VzIHRoYXQgaGFuZGxlIGN1c3RvbSBmb3JtYXR0aW5nIGZvciB0aGUgJ3MnIHNwZWNpZmllciBvZiB7QGNvZGUgRm9ybWF0dGVyfQorICogc2hvdWxkIGltcGxlbWVudCB0aGUge0Bjb2RlIEZvcm1hdHRhYmxlfSBpbnRlcmZhY2UuIEl0IGdpdmVzIGJhc2ljIGNvbnRyb2wgb3ZlcgorICogZm9ybWF0dGluZyBvYmplY3RzLgorICoKKyAqIEBzZWUgRm9ybWF0dGVyCisgKi8KKworcHVibGljIGludGVyZmFjZSBGb3JtYXR0YWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBGb3JtYXRzIHRoZSBvYmplY3QgdXNpbmcgdGhlIHNwZWNpZmllZCB7QGNvZGUgRm9ybWF0dGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmb3JtYXR0ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgRm9ybWF0dGVyfSB0byB1c2UuCisgICAgICogQHBhcmFtIGZsYWdzCisgICAgICogICAgICAgICAgICB0aGUgZmxhZ3MgYXBwbGllZCB0byB0aGUgb3V0cHV0IGZvcm1hdCwgd2hpY2ggaXMgYSBiaXRtYXNrCisgICAgICogICAgICAgICAgICB0aGF0IGlzIGFueSBjb21iaW5hdGlvbiBvZiB7QGNvZGUgRm9ybWF0dGFibGVGbGFncy5MRUZUX0pVU1RJRll9LAorICAgICAqICAgICAgICAgICAge0Bjb2RlIEZvcm1hdHRhYmxlRmxhZ3MuVVBQRVJDQVNFfSwgYW5kIHtAY29kZSBGb3JtYXR0YWJsZUZsYWdzLkFMVEVSTkFURX0uIElmCisgICAgICogICAgICAgICAgICBubyBzdWNoIGZsYWcgaXMgc2V0LCB0aGUgb3V0cHV0IGlzIGZvcm1hdHRlZCBieSB0aGUgZGVmYXVsdAorICAgICAqICAgICAgICAgICAgZm9ybWF0dGluZyBvZiB0aGUgaW1wbGVtZW50YXRpb24uCisgICAgICogQHBhcmFtIHdpZHRoCisgICAgICogICAgICAgICAgICB0aGUgbWluaW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyB0aGF0IHNob3VsZCBiZSB3cml0dGVuIHRvIHRoZQorICAgICAqICAgICAgICAgICAgb3V0cHV0LiBJZiB0aGUgbGVuZ3RoIG9mIHRoZSBjb252ZXJ0ZWQgdmFsdWUgaXMgbGVzcyB0aGFuIHtAY29kZSB3aWR0aH0KKyAgICAgKiAgICAgICAgICAgIEFkZGl0aW9uYWwgc3BhY2UgY2hhcmFjdGVycyAoJyAnKSBhcmUgYWRkZWQgdG8gdGhlIG91dHB1dCBpZiB0aGUKKyAgICAgKiAgICAgICAgICAgIGFzIG5lZWRlZCB0byBtYWtlIHVwIHRoZSBkaWZmZXJlbmNlLiBUaGVzZSBzcGFjZXMgYXJlIGFkZGVkIGF0IHRoZQorICAgICAqICAgICAgICAgICAgYmVnaW5uaW5nIGJ5IGRlZmF1bHQgdW5sZXNzIHRoZSBmbGFnCisgICAgICogICAgICAgICAgICBGb3JtYXR0YWJsZUZsYWdzLkxFRlRfSlVTVElGWSBpcyBzZXQsIHdoaWNoIGRlbm90ZXMgdGhhdAorICAgICAqICAgICAgICAgICAgcGFkZGluZyBzaG91bGQgYmUgYWRkZWQgYXQgdGhlIGVuZC4gSWYgd2lkdGggaXMgLTEsIHRoZW4KKyAgICAgKiAgICAgICAgICAgIG1pbmltdW0gbGVuZ3RoIGlzIG5vdCBlbmZvcmNlZC4KKyAgICAgKiBAcGFyYW0gcHJlY2lzaW9uCisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyB0aGF0IGNhbiBiZSB3cml0dGVuIHRvIHRoZQorICAgICAqICAgICAgICAgICAgb3V0cHV0LiBUaGUgbGVuZ3RoIG9mIHRoZSBvdXRwdXQgaXMgdHJpbW1lZCBkb3duIHRvIHRoaXMgc2l6ZQorICAgICAqICAgICAgICAgICAgYmVmb3JlIHRoZSB3aWR0aCBwYWRkaW5nIGlzIGFwcGxpZWQuIElmIHRoZSBwcmVjaXNpb24KKyAgICAgKiAgICAgICAgICAgIGlzIC0xLCB0aGVuIG1heGltdW0gbGVuZ3RoIGlzIG5vdCBlbmZvcmNlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgb2YgdGhlIHBhcmFtZXRlcnMgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICB2b2lkIGZvcm1hdFRvKEZvcm1hdHRlciBmb3JtYXR0ZXIsIGludCBmbGFncywgaW50IHdpZHRoLCBpbnQgcHJlY2lzaW9uKQorICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxGb3JtYXRFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0Zvcm1hdHRhYmxlRmxhZ3MuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRm9ybWF0dGFibGVGbGFncy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ5NmYxM2IKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0Zvcm1hdHRhYmxlRmxhZ3MuamF2YQpAQCAtMCwwICsxLDU4IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBqYXZhLnV0aWw7CisKKy8qKgorICogRm9ybWF0dGFibGVGbGFncyBhcmUgdXNlZCBhcyBhIHBhcmFtZXRlciB0bworICoge0BsaW5rIEZvcm1hdHRhYmxlI2Zvcm1hdFRvKEZvcm1hdHRlciwgaW50LCBpbnQsIGludCl9IGFuZCBjaGFuZ2UgdGhlIG91dHB1dAorICogZm9ybWF0IGluIHtAY29kZSBGb3JtYXR0YWJsZX1zLiBUaGUgdmFsaWRhdGlvbiBhbmQgaW50ZXJwcmV0YXRpb24gb2YgdGhlCisgKiBmbGFncyBtdXN0IGJlIGRvbmUgYnkgdGhlIGltcGxlbWVudGF0aW9ucy4KKyAqCisgKiBAc2VlIEZvcm1hdHRhYmxlCisgKi8KK3B1YmxpYyBjbGFzcyBGb3JtYXR0YWJsZUZsYWdzIHsKKworICAgIHByaXZhdGUgRm9ybWF0dGFibGVGbGFncygpeworICAgICAgICAvL3ByZXZlbnQgdGhpcyBjbGFzcyBmcm9tIGJlaW5nIGluc3RhbnRpYXRlZAorICAgIH0KKworICAgIC8qKgorICAgICAqIERlbm90ZXMgdGhlIG91dHB1dCBpcyB0byBiZSBsZWZ0LWp1c3RpZmllZC4gSW4gb3JkZXIgdG8gZmlsbCB0aGUgbWluaW11bQorICAgICAqIHdpZHRoIHJlcXVpcmVtZW50LCBzcGFjZXMoJ1x1MDAyMCcpIHdpbGwgYmUgYXBwZW5kZWQgYXQgdGhlIGVuZCBvZiB0aGUKKyAgICAgKiBzcGVjaWZpZWQgb3V0cHV0IGVsZW1lbnQuIElmIG5vIHN1Y2ggZmxhZyBpcyBzZXQsIHRoZSBvdXRwdXQgaXMKKyAgICAgKiByaWdodC1qdXN0aWZpZWQuCisgICAgICoKKyAgICAgKiBUaGUgZmxhZyBjb3JyZXNwb25kcyB0byAnLScgKCdcdTAwMmQnKSBpbiB0aGUgZm9ybWF0IHNwZWNpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMRUZUX0pVU1RJRlkgPSAxOworCisgICAgLyoqCisgICAgICogRGVub3RlcyB0aGUgb3V0cHV0IGlzIHRvIGJlIGNvbnZlcnRlZCB0byB1cHBlciBjYXNlIGluIHRoZSB3YXkgdGhlIGxvY2FsZQorICAgICAqIHBhcmFtZXRlciBvZiBGb3JtYXR0ZXIuZm9ybWF0VG8oKSByZXF1aXJlcy4gVGhlIG91dHB1dCBoYXMgdGhlIHNhbWUKKyAgICAgKiBlZmZlY3QgYXMge0Bjb2RlIFN0cmluZy50b1VwcGVyQ2FzZShqYXZhLnV0aWwuTG9jYWxlKX0uCisgICAgICoKKyAgICAgKiBUaGlzIGZsYWcgY29ycmVzcG9uZHMgdG8ge0Bjb2RlICdeJyAoJ1x1MDA1ZScpfSBpbiB0aGUgZm9ybWF0IHNwZWNpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVUFBFUkNBU0UgPSAyOworCisgICAgLyoqCisgICAgICogRGVub3RlcyB0aGUgb3V0cHV0IGlzIHRvIGJlIGZvcm1hdHRlZCBpbiBhbiBhbHRlcm5hdGUgZm9ybS4gVGhlIGRlZmluaXRpb24KKyAgICAgKiBvZiB0aGUgYWx0ZXJuYXRlIGZvcm0gaXMgZGV0ZXJtaW5lZCBieSB0aGUge0Bjb2RlIEZvcm1hdHRhYmxlfS4KKyAgICAgKgorICAgICAqIFRoaXMgZmxhZyBjb3JyZXNwb25kcyB0byB7QGNvZGUgJyMnICgnXHUwMDIzJyl9IGluIHRoZSBmb3JtYXQgc3BlY2lmaWVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFMVEVSTkFURSA9IDQ7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0Zvcm1hdHRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9Gb3JtYXR0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOWEyZjRhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9Gb3JtYXR0ZXIuamF2YQpAQCAtMCwwICsxLDI0MDYgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRXcml0ZXI7CitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZsdXNoYWJsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtV3JpdGVyOworaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CitpbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEubWF0aC5NYXRoQ29udGV4dDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CitpbXBvcnQgbGliY29yZS5pY3UuTG9jYWxlRGF0YTsKK2ltcG9ydCBsaWJjb3JlLmljdS5OYXRpdmVEZWNpbWFsRm9ybWF0OworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKKworLyoqCisgKiBGb3JtYXRzIGFyZ3VtZW50cyBhY2NvcmRpbmcgdG8gYSBmb3JtYXQgc3RyaW5nIChsaWtlIHtAY29kZSBwcmludGZ9IGluIEMpLgorICogPHA+CisgKiBJdCdzIHJlbGF0aXZlbHkgcmFyZSB0byB1c2UgYSB7QGNvZGUgRm9ybWF0dGVyfSBkaXJlY3RseS4gQSB2YXJpZXR5IG9mIGNsYXNzZXMgb2ZmZXIgY29udmVuaWVuY2UKKyAqIG1ldGhvZHMgZm9yIGFjY2Vzc2luZyBmb3JtYXR0ZXIgZnVuY3Rpb25hbGl0eS4KKyAqIE9mIHRoZXNlLCB7QGxpbmsgU3RyaW5nI2Zvcm1hdH0gaXMgZ2VuZXJhbGx5IHRoZSBtb3N0IHVzZWZ1bC4KKyAqIHtAbGluayBqYXZhLmlvLlByaW50U3RyZWFtfSBhbmQge0BsaW5rIGphdmEuaW8uUHJpbnRXcml0ZXJ9IGJvdGggb2ZmZXIKKyAqIHtAY29kZSBmb3JtYXR9IGFuZCB7QGNvZGUgcHJpbnRmfSBtZXRob2RzLgorICogPHA+CisgKiA8aT5Gb3JtYXQgc3RyaW5nczwvaT4gY29uc2lzdCBvZiBwbGFpbiB0ZXh0IGludGVyc3BlcnNlZCB3aXRoIGZvcm1hdCBzcGVjaWZpZXJzLCBzdWNoCisgKiBhcyB7QGNvZGUgIm5hbWU6ICVzIHdlaWdodDogJTAzZGtnXG4ifS4gQmVpbmcgYSBKYXZhIHN0cmluZywgdGhlIHVzdWFsIEphdmEgc3RyaW5nIGxpdGVyYWwKKyAqIGJhY2tzbGFzaCBlc2NhcGVzIGFyZSBvZiBjb3Vyc2UgYXZhaWxhYmxlLgorICogPHA+CisgKiA8aT5Gb3JtYXQgc3BlY2lmaWVyczwvaT4gKHN1Y2ggYXMge0Bjb2RlICIlcyJ9IG9yIHtAY29kZSAiJTAzZCJ9IGluIHRoZSBleGFtcGxlKSBzdGFydCB3aXRoIGEKKyAqIHtAY29kZSAlfSBhbmQgZGVzY3JpYmUgaG93IHRvIGZvcm1hdCB0aGVpciBjb3JyZXNwb25kaW5nIGFyZ3VtZW50LiBJdCBpbmNsdWRlcyBhbiBvcHRpb25hbAorICogYXJndW1lbnQgaW5kZXgsIG9wdGlvbmFsIGZsYWdzLCBhbiBvcHRpb25hbCB3aWR0aCwgYW4gb3B0aW9uYWwgcHJlY2lzaW9uLCBhbmQgYSBtYW5kYXRvcnkKKyAqIGNvbnZlcnNpb24gdHlwZS4KKyAqIEluIHRoZSBleGFtcGxlLCB7QGNvZGUgIiVzIn0gaGFzIG5vIGZsYWdzLCBubyB3aWR0aCwgYW5kIG5vIHByZWNpc2lvbiwgd2hpbGUKKyAqIHtAY29kZSAiJTAzZCJ9IGhhcyB0aGUgZmxhZyB7QGNvZGUgMH0sIHRoZSB3aWR0aCAzLCBhbmQgbm8gcHJlY2lzaW9uLgorICogPHA+CisgKiBOb3QgYWxsIGNvbWJpbmF0aW9ucyBvZiBhcmd1bWVudCBpbmRleCwgZmxhZ3MsIHdpZHRoLCBwcmVjaXNpb24sIGFuZCBjb252ZXJzaW9uIHR5cGUKKyAqIGFyZSB2YWxpZC4KKyAqIDxwPgorICogPGk+QXJndW1lbnQgaW5kZXg8L2k+LiBOb3JtYWxseSwgZWFjaCBmb3JtYXQgc3BlY2lmaWVyIGNvbnN1bWVzIHRoZSBuZXh0IGFyZ3VtZW50IHRvCisgKiB7QGNvZGUgZm9ybWF0fS4KKyAqIEZvciBjb252ZW5pZW50IGxvY2FsaXphdGlvbiwgaXQncyBwb3NzaWJsZSB0byByZW9yZGVyIGFyZ3VtZW50cyBzbyB0aGF0IHRoZXkgYXBwZWFyIGluIGEKKyAqIGRpZmZlcmVudCBvcmRlciBpbiB0aGUgb3V0cHV0IHRoYW4gdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgd2VyZSBzdXBwbGllZC4KKyAqIEZvciBleGFtcGxlLCB7QGNvZGUgIiU0JHMifSBmb3JtYXRzIHRoZSBmb3VydGggYXJndW1lbnQgKHtAY29kZSA0JH0pIGFzIGEgc3RyaW5nICh7QGNvZGUgc30pLgorICogSXQncyBhbHNvIHBvc3NpYmxlIHRvIHJldXNlIGFuIGFyZ3VtZW50IHdpdGgge0Bjb2RlIDx9LiBGb3IgZXhhbXBsZSwKKyAqIHtAY29kZSBmb3JtYXQoIiVvICUmbHQ7ZCAlJmx0O3giLCA2NCl9IHJlc3VsdHMgaW4ge0Bjb2RlICIxMDAgNjQgNDAifS4KKyAqIDxwPgorICogPGk+RmxhZ3M8L2k+LiBUaGUgYXZhaWxhYmxlIGZsYWdzIGFyZToKKyAqIDxwPgorICogPHRhYmxlIEJPUkRFUj0iMSIgV0lEVEg9IjEwMCUiIENFTExQQURESU5HPSIzIiBDRUxMU1BBQ0lORz0iMCIgU1VNTUFSWT0iIj4KKyAqIDx0ciBCR0NPTE9SPSIjQ0NDQ0ZGIiBDTEFTUz0iVGFibGVIZWFkaW5nQ29sb3IiPiA8VEQgQ09MU1BBTj00PiA8Qj5GbGFnczwvQj4gPC9URD4gPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB3aWR0aD0iNSUiPntAY29kZSAsfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+VXNlIGdyb3VwaW5nIHNlcGFyYXRvcnMgZm9yIGxhcmdlIG51bWJlcnMuIChEZWNpbWFsIG9ubHkuKTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIGZvcm1hdCgiJSxkIiwgMTAyNCk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIDEsMjM0fTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlICt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5BbHdheXMgc2hvdyBzaWduLiAoRGVjaW1hbCBvbmx5Lik8L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiUrZCwgJSs0ZCIsIDUsIDUpO308L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPjxwcmU+KzUsICAgKzU8L3ByZT48L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB3aWR0aD0iNSUiPntAY29kZSAgfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+QSBzcGFjZSBpbmRpY2F0ZXMgdGhhdCBub24tbmVnYXRpdmUgbnVtYmVycworICogc2hvdWxkIGhhdmUgYSBsZWFkaW5nIHNwYWNlLiAoRGVjaW1hbCBvbmx5Lik8L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoInglIGQlIDVkIiwgNCwgNCk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+PHByZT54IDQgICAgNDwvcHJlPjwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlICh9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5QdXQgcGFyZW50aGVzZXMgYXJvdW5kIG5lZ2F0aXZlIG51bWJlcnMuIChEZWNpbWFsIG9ubHkuKTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIGZvcm1hdCgiJShkLCAlKGQsICUoNmQiLCAxMiwgLTEyLCAtMTIpO308L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPjxwcmU+MTIsICgxMiksICAgKDEyKTwvcHJlPjwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIC19PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5MZWZ0LWp1c3RpZnkuIChSZXF1aXJlcyB3aWR0aC4pPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIlLTZkeCIsIDUpO308YnIvPntAY29kZSBmb3JtYXQoIiUtM0MsICUzQyIsICdkJywgMHg2NSk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+PHByZT41ICAgICAgeDwvcHJlPjxici8+PHByZT5EICAsICAgRTwvcHJlPjwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIDB9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5QYWQgdGhlIG51bWJlciB3aXRoIGxlYWRpbmcgemVyb3MuIChSZXF1aXJlcyB3aWR0aC4pPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIlMDdkLCAlMDNkIiwgNCwgNTU1NSk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIDAwMDAwMDQsIDU1NTV9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgI308L3RkPgorICogPHRkIHdpZHRoPSIyNSUiPkFsdGVybmF0ZSBmb3JtLiAoT2N0YWwgYW5kIGhleCBvbmx5LikgPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIlbyAlI28iLCAwMTAsIDAxMCk7fTxici8+e0Bjb2RlIGZvcm1hdCgiJXggJSN4IiwgMHgxMiwgMHgxMik7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIDEwIDAxMH08YnIvPntAY29kZSAxMiAweDEyfTwvdGQ+CisgKiA8L3RyPgorICogPC90YWJsZT4KKyAqIDxwPgorICogPGk+V2lkdGg8L2k+LiBUaGUgd2lkdGggaXMgYSBkZWNpbWFsIGludGVnZXIgc3BlY2lmeWluZyB0aGUgbWluaW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBiZQorICogdXNlZCB0byByZXByZXNlbnQgdGhlIGFyZ3VtZW50LiBJZiB0aGUgcmVzdWx0IHdvdWxkIG90aGVyd2lzZSBiZSBzaG9ydGVyIHRoYW4gdGhlIHdpZHRoLCBwYWRkaW5nCisgKiB3aWxsIGJlIGFkZGVkICh0aGUgZXhhY3QgZGV0YWlscyBvZiB3aGljaCBkZXBlbmQgb24gdGhlIGZsYWdzKS4gTm90ZSB0aGF0IHlvdSBjYW4ndCB1c2Ugd2lkdGggdG8KKyAqIHRydW5jYXRlIGEgZmllbGQsIG9ubHkgdG8gbWFrZSBpdCB3aWRlcjogc2VlIHByZWNpc2lvbiBmb3IgY29udHJvbCBvdmVyIHRoZSBtYXhpbXVtIHdpZHRoLgorICogPHA+CisgKiA8aT5QcmVjaXNpb248L2k+LiBUaGUgcHJlY2lzaW9uIGlzIGEge0Bjb2RlIC59IGZvbGxvd2VkIGJ5IGEgZGVjaW1hbCBpbnRlZ2VyLCBnaXZpbmcgdGhlIG1pbmltdW0KKyAqIG51bWJlciBvZiBkaWdpdHMgZm9yIHtAY29kZSBkfSwge0Bjb2RlIG99LCB7QGNvZGUgeH0sIG9yIHtAY29kZSBYfTsgdGhlIG1pbmltdW0gbnVtYmVyIG9mIGRpZ2l0cworICogYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQgZm9yIHtAY29kZSBhfSwge0Bjb2RlIEF9LCB7QGNvZGUgZX0sIHtAY29kZSBFfSwge0Bjb2RlIGZ9LCBvciB7QGNvZGUgRn07CisgKiB0aGUgbWF4aW11bSBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgZGlnaXRzIGZvciB7QGNvZGUgZ30gb3Ige0Bjb2RlIEd9OyBvciB0aGUgbWF4aW11bSBudW1iZXIgb2YKKyAqIGNoYXJhY3RlcnMgZm9yIHtAY29kZSBzfSBvciB7QGNvZGUgU30uCisgKiA8cD4KKyAqIDxpPkNvbnZlcnNpb24gdHlwZTwvaT4uIE9uZSBvciB0d28gY2hhcmFjdGVycyBkZXNjcmliaW5nIGhvdyB0byBpbnRlcnByZXQgdGhlIGFyZ3VtZW50LiBNb3N0CisgKiBjb252ZXJzaW9ucyBhcmUgYSBzaW5nbGUgY2hhcmFjdGVyLCBidXQgZGF0ZS90aW1lIGNvbnZlcnNpb25zIGFsbCBzdGFydCB3aXRoIHtAY29kZSB0fSBhbmQKKyAqIGhhdmUgYSBzaW5nbGUgZXh0cmEgY2hhcmFjdGVyIGRlc2NyaWJpbmcgdGhlIGRlc2lyZWQgb3V0cHV0LgorICogPHA+CisgKiBNYW55IGNvbnZlcnNpb24gdHlwZXMgaGF2ZSBhIGNvcnJlc3BvbmRpbmcgdXBwZXJjYXNlIHZhcmlhbnQgdGhhdCBjb252ZXJ0cyBpdHMgcmVzdWx0IHRvCisgKiB1cHBlcmNhc2UgdXNpbmcgdGhlIHJ1bGVzIG9mIHRoZSByZWxldmFudCBsb2NhbGUgKGVpdGhlciB0aGUgZGVmYXVsdCBvciB0aGUgbG9jYWxlIHNldCBmb3IKKyAqIHRoaXMgZm9ybWF0dGVyKS4KKyAqIDxwPgorICogVGhpcyB0YWJsZSBzaG93cyB0aGUgYXZhaWxhYmxlIHNpbmdsZS1jaGFyYWN0ZXIgKG5vbi1kYXRlL3RpbWUpIGNvbnZlcnNpb24gdHlwZXM6CisgKiA8dGFibGUgQk9SREVSPSIxIiBXSURUSD0iMTAwJSIgQ0VMTFBBRERJTkc9IjMiIENFTExTUEFDSU5HPSIwIiBTVU1NQVJZPSIiPgorICogPHRyIEJHQ09MT1I9IiNDQ0NDRkYiIENMQVNTPSJUYWJsZUhlYWRpbmdDb2xvciI+CisgKiA8VEQgQ09MU1BBTj00PgorICogPEI+U3RyaW5nIGNvbnZlcnNpb25zPC9CPgorICogPGJyPgorICogQWxsIHR5cGVzIGFyZSBhY2NlcHRhYmxlIGFyZ3VtZW50cy4gVmFsdWVzIG9mIHR5cGUge0BsaW5rIEZvcm1hdHRhYmxlfSBoYXZlIHRoZWlyCisgKiB7QGNvZGUgZm9ybWF0VG99IG1ldGhvZCBpbnZva2VkOyBhbGwgb3RoZXIgdHlwZXMgdXNlIHtAY29kZSB0b1N0cmluZ30uCisgKiA8L1REPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB3aWR0aD0iNSUiPntAY29kZSBzfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+U3RyaW5nLjwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIGZvcm1hdCgiJXMgJXMiLCAiaGVsbG8iLCAiSGVsbG8iKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgaGVsbG8gSGVsbG99PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgU308L3RkPgorICogPHRkIHdpZHRoPSIyNSUiPlVwcGVyY2FzZSBzdHJpbmcuPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIlUyAlUyIsICJoZWxsbyIsICJIZWxsbyIpO308L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBIRUxMTyBIRUxMT308L3RkPgorICogPC90cj4KKyAqIDx0ciBCR0NPTE9SPSIjQ0NDQ0ZGIiBDTEFTUz0iVGFibGVIZWFkaW5nQ29sb3IiPgorICogPFREIENPTFNQQU49ND4KKyAqIDxCPkNoYXJhY3RlciBjb252ZXJzaW9uczwvQj4KKyAqIDxicj4KKyAqIEJ5dGUsIENoYXJhY3RlciwgU2hvcnQsIGFuZCBJbnRlZ2VyIChhbmQgcHJpbWl0aXZlcyB0aGF0IGJveCB0byB0aG9zZSB0eXBlcykgYXJlIGFsbCBhY2NlcHRhYmxlCisgKiBhcyBjaGFyYWN0ZXIgYXJndW1lbnRzLiBBbnkgb3RoZXIgdHlwZSBpcyBhbiBlcnJvci4KKyAqIDwvVEQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIGN9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5DaGFyYWN0ZXIuPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIlYyAlYyIsICdkJywgJ0UnKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZCBFfTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIEN9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5VcHBlcmNhc2UgY2hhcmFjdGVyLjwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIGZvcm1hdCgiJUMgJUMiLCAnZCcsICdFJyk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIEQgRX08L3RkPgorICogPC90cj4KKyAqIDx0ciBCR0NPTE9SPSIjQ0NDQ0ZGIiBDTEFTUz0iVGFibGVIZWFkaW5nQ29sb3IiPgorICogPFREIENPTFNQQU49ND4KKyAqIDxCPkludGVnZXIgY29udmVyc2lvbnM8L0I+CisgKiA8YnI+CisgKiBCeXRlLCBTaG9ydCwgSW50ZWdlciwgTG9uZywgYW5kIEJpZ0ludGVnZXIgKGFuZCBwcmltaXRpdmVzIHRoYXQgYm94IHRvIHRob3NlIHR5cGVzKSBhcmUgYWxsCisgKiBhY2NlcHRhYmxlIGFzIGludGVnZXIgYXJndW1lbnRzLiBBbnkgb3RoZXIgdHlwZSBpcyBhbiBlcnJvci4KKyAqIDwvVEQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIGR9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5EZWNpbWFsLjwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIGZvcm1hdCgiJWQiLCAyNik7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIDI2fTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIG99PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5PY3RhbC48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiVvIiwgMDMyKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgMzJ9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgeH0sIHtAY29kZSBYfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+SGV4YWRlY2ltYWwuPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIleCAlWCIsIDB4MWEsIDB4MWEpO308L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSAxYSAxQX08L3RkPgorICogPC90cj4KKyAqIDx0ciBCR0NPTE9SPSIjQ0NDQ0ZGIiBDTEFTUz0iVGFibGVIZWFkaW5nQ29sb3IiPgorICogPFREIENPTFNQQU49ND48Qj5GbG9hdGluZy1wb2ludCBjb252ZXJzaW9uczwvQj4KKyAqIDxicj4KKyAqIEZsb2F0LCBEb3VibGUsIGFuZCBCaWdEZWNpbWFsIChhbmQgcHJpbWl0aXZlcyB0aGF0IGJveCB0byB0aG9zZSB0eXBlcykgYXJlIGFsbCBhY2NlcHRhYmxlIGFzCisgKiBmbG9hdGluZy1wb2ludCBhcmd1bWVudHMuIEFueSBvdGhlciB0eXBlIGlzIGFuIGVycm9yLgorICogPC9URD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgZn08L3RkPgorICogPHRkIHdpZHRoPSIyNSUiPkRlY2ltYWwgZmxvYXRpbmcgcG9pbnQuPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj48cHJlPgorZm9ybWF0KCIlZiIsIDEyMy40NTZmKTsKK2Zvcm1hdCgiJS4xZiIsIDEyMy40NTZmKTsKK2Zvcm1hdCgiJTEuNWYiLCAxMjMuNDU2Zik7Citmb3JtYXQoIiUxMGYiLCAxMjMuNDU2Zik7Citmb3JtYXQoIiU2LjBmIiwgMTIzLjQ1NmYpOzwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSIgdmFsaWduPSJ0b3AiPjxwcmU+CisxMjMuNDU2MDAxCisxMjMuNQorMTIzLjQ1NjAwCisxMjMuNDU2MDAxCismbmJzcDsmbmJzcDsmbmJzcDsxMjM8L3ByZT48L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB3aWR0aD0iNSUiPntAY29kZSBlfSwge0Bjb2RlIEV9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5FbmdpbmVlcmluZy9leHBvbmVudGlhbCBmbG9hdGluZyBwb2ludC48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPjxwcmU+Citmb3JtYXQoIiVlIiwgMTIzLjQ1NmYpOworZm9ybWF0KCIlLjFlIiwgMTIzLjQ1NmYpOworZm9ybWF0KCIlMS41RSIsIDEyMy40NTZmKTsKK2Zvcm1hdCgiJTEwRSIsIDEyMy40NTZmKTsKK2Zvcm1hdCgiJTYuMEUiLCAxMjMuNDU2Zik7PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIiB2YWxpZ249InRvcCI+PHByZT4KKzEuMjM0NTYwZSswMgorMS4yZSswMgorMS4yMzQ1NkUrMDIKKzEuMjM0NTYwRSswMgorJm5ic3A7MUUrMDI8L3ByZT48L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB3aWR0aD0iNSUiIHZhbGlnbj0idG9wIj57QGNvZGUgZ30sIHtAY29kZSBHfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSIgdmFsaWduPSJ0b3AiPkRlY2ltYWwgb3IgZW5naW5lZXJpbmcsIGRlcGVuZGluZyBvbiB0aGUgbWFnbml0dWRlIG9mIHRoZSB2YWx1ZS48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiIHZhbGlnbj0idG9wIj57QGNvZGUgZm9ybWF0KCIlZyAlZyIsIDAuMTIzLCAwLjAwMDAxMjMpO308L3RkPgorICogPHRkIHdpZHRoPSIzMCUiIHZhbGlnbj0idG9wIj57QGNvZGUgMC4xMjMwMDAgMS4yMzAwMGUtMDV9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgYX0sIHtAY29kZSBBfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+SGV4YWRlY2ltYWwgZmxvYXRpbmcgcG9pbnQuPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIlYSIsIDEyMy40NTZmKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgMHgxLmVkZDJmMnA2fTwvdGQ+CisgKiA8L3RyPgorICogPHRyIEJHQ09MT1I9IiNDQ0NDRkYiIENMQVNTPSJUYWJsZUhlYWRpbmdDb2xvciI+CisgKiA8VEQgQ09MU1BBTj00PgorICogPEI+Qm9vbGVhbiBjb252ZXJzaW9uPC9CPgorICogPGJyPgorICogQWNjZXB0cyBCb29sZWFuIHZhbHVlcy4ge0Bjb2RlIG51bGx9IGlzIGNvbnNpZGVyZWQgZmFsc2UsIGFuZCBpbnN0YW5jZXMgb2YgYWxsIG90aGVyCisgKiB0eXBlcyBhcmUgY29uc2lkZXJlZCB0cnVlLgorICogPC9URD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgYn0sIHtAY29kZSBCfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+Qm9vbGVhbi48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiViICViIiwgdHJ1ZSwgZmFsc2UpO308YnI+e0Bjb2RlIGZvcm1hdCgiJUIgJUIiLCB0cnVlLCBmYWxzZSk7fTxicj57QGNvZGUgZm9ybWF0KCIlYiIsIG51bGwpO308YnI+e0Bjb2RlIGZvcm1hdCgiJWIiLCAiaGVsbG8iKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgdHJ1ZSBmYWxzZX08YnI+e0Bjb2RlIFRSVUUgRkFMU0V9PGJyPntAY29kZSBmYWxzZX08YnI+e0Bjb2RlIHRydWV9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHIgQkdDT0xPUj0iI0NDQ0NGRiIgQ0xBU1M9IlRhYmxlSGVhZGluZ0NvbG9yIj4KKyAqIDxURCBDT0xTUEFOPTQ+CisgKiA8Qj5IYXNoIGNvZGUgY29udmVyc2lvbjwvQj4KKyAqIDxicj4KKyAqIEludm9rZXMge0Bjb2RlIGhhc2hDb2RlfSBvbiBpdHMgYXJndW1lbnQsIHdoaWNoIG1heSBiZSBvZiBhbnkgdHlwZS4KKyAqIDwvVEQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIGh9LCB7QGNvZGUgSH08L3RkPgorICogPHRkIHdpZHRoPSIyNSUiPkhleGFkZWNpbWFsIGhhc2ggY29kZS48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiVoIiwgdGhpcyk7fTxicj57QGNvZGUgZm9ybWF0KCIlSCIsIHRoaXMpO308YnI+e0Bjb2RlIGZvcm1hdCgiJWgiLCBudWxsKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgMTkwZDExfTxicj57QGNvZGUgMTkwRDExfTxicj57QGNvZGUgbnVsbH08L3RkPgorICogPC90cj4KKyAqIDx0ciBCR0NPTE9SPSIjQ0NDQ0ZGIiBDTEFTUz0iVGFibGVIZWFkaW5nQ29sb3IiPgorICogPFREIENPTFNQQU49ND4KKyAqIDxCPlplcm8tYXJndW1lbnQgY29udmVyc2lvbnM8L0I+PC9URD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgJX08L3RkPgorICogPHRkIHdpZHRoPSIyNSUiPkEgbGl0ZXJhbCAlIGNoYXJhY3Rlci48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiVkJSUiLCA1MCk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIDUwJX08L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB3aWR0aD0iNSUiPntAY29kZSBufTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+TmV3bGluZS4gKFRoZSB2YWx1ZSBvZiB0aGUgImxpbmUuc2VwYXJhdG9yIiBzeXN0ZW0gcHJvcGVydHl9Lik8L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoImZpcnN0JW5zZWNvbmQiKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZmlyc3RcbnNlY29uZH08L3RkPgorICogPC90cj4KKyAqIDwvdGFibGU+CisgKiA8cD4KKyAqIEl0J3MgYWxzbyBwb3NzaWJsZSB0byBmb3JtYXQgZGF0ZXMgYW5kIHRpbWVzIHdpdGgge0Bjb2RlIEZvcm1hdHRlcn0sIHRob3VnaCB5b3Ugc2hvdWxkIHNlcmlvdXNseQorICogY29uc2lkZXIgdXNpbmcge0BsaW5rIGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0fSB2aWEgdGhlIGZhY3RvcnkgbWV0aG9kcyBpbgorICoge0BsaW5rIGphdmEudGV4dC5EYXRlRm9ybWF0fSBpbnN0ZWFkLgorICogVGhlIGZhY2lsaXRpZXMgb2ZmZXJlZCBieSB7QGNvZGUgRm9ybWF0dGVyfSBhcmUgbG93LWxldmVsIGFuZCBwbGFjZSB0aGUgYnVyZGVuIG9mIGxvY2FsaXphdGlvbgorICogb24gdGhlIGRldmVsb3Blci4gVXNpbmcge0BsaW5rIGphdmEudGV4dC5EYXRlRm9ybWF0I2dldERhdGVJbnN0YW5jZX0sCisgKiB7QGxpbmsgamF2YS50ZXh0LkRhdGVGb3JtYXQjZ2V0VGltZUluc3RhbmNlfSwgYW5kCisgKiB7QGxpbmsgamF2YS50ZXh0LkRhdGVGb3JtYXQjZ2V0RGF0ZVRpbWVJbnN0YW5jZX0gaXMgcHJlZmVyYWJsZSBmb3IgZGF0ZXMgYW5kIHRpbWVzIHRoYXQgd2lsbCBiZQorICogcHJlc2VudGVkIHRvIGEgaHVtYW4uIFRob3NlIG1ldGhvZHMgd2lsbCBzZWxlY3QgdGhlIGJlc3QgZm9ybWF0IHN0cmluZ3MgZm9yIHRoZSB1c2VyJ3MgbG9jYWxlLgorICogPHA+CisgKiBUaGUgYmVzdCBub24tbG9jYWxpemVkIGZvcm0gaXMgPGEgaHJlZj0iaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fODYwMSI+SVNPIDg2MDE8L2E+LAorICogd2hpY2ggeW91IGNhbiBnZXQgd2l0aCB7QGNvZGUgIiV0RiJ9ICgyMDEwLTAxLTIyKSwge0Bjb2RlICIldEYgJXRSIn0gKDIwMTAtMDEtMjIgMTM6MzkpLAorICoge0Bjb2RlICIldEYgJXRUIn0gKDIwMTAtMDEtMjIgMTM6Mzk6MTUpLCBvciB7QGNvZGUgIiV0RiAldFQleiJ9ICgyMDEwLTAxLTIyIDEzOjM5OjE1LTA4MDApLgorICogPHA+CisgKiBBcyB3aXRoIHRoZSBvdGhlciBjb252ZXJzaW9ucywgZGF0ZS90aW1lIGNvbnZlcnNpb24gaGFzIGFuIHVwcGVyY2FzZSBmb3JtYXQuIFJlcGxhY2luZworICoge0Bjb2RlICV0fSB3aXRoIHtAY29kZSAlVH0gd2lsbCB1cHBlcmNhc2UgdGhlIGZpZWxkIGFjY29yZGluZyB0byB0aGUgcnVsZXMgb2YgdGhlIGZvcm1hdHRlcidzCisgKiBsb2NhbGUuCisgKiA8cD4KKyAqIFRoaXMgdGFibGUgc2hvd3MgdGhlIGRhdGUvdGltZSBjb252ZXJzaW9uczoKKyAqIDx0YWJsZSBCT1JERVI9IjEiIFdJRFRIPSIxMDAlIiBDRUxMUEFERElORz0iMyIgQ0VMTFNQQUNJTkc9IjAiIFNVTU1BUlk9IiI+CisgKiA8dHIgQkdDT0xPUj0iI0NDQ0NGRiIgQ0xBU1M9IlRhYmxlSGVhZGluZ0NvbG9yIj4KKyAqIDxURCBDT0xTUEFOPTQ+PEI+RGF0ZS90aW1lIGNvbnZlcnNpb25zPC9CPgorICogPGJyPgorICogQ2FsZW5kYXIsIERhdGUsIGFuZCBMb25nIChyZXByZXNlbnRpbmcgbWlsbGlzZWNvbmRzIHBhc3QgdGhlIGVwb2NoKSBhcmUgYWxsIGFjY2VwdGFibGUKKyAqIGFzIGRhdGUvdGltZSBhcmd1bWVudHMuIEFueSBvdGhlciB0eXBlIGlzIGFuIGVycm9yLiBUaGUgZXBvY2ggaXMgMTk3MC0wMS0wMSAwMDowMDowMCBVVEMuCisgKiA8L1REPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB3aWR0aD0iNSUiPntAY29kZSB0YX08L3RkPgorICogPHRkIHdpZHRoPSIyNSUiPkxvY2FsaXplZCB3ZWVrZGF5IG5hbWUgKGFiYnJldmlhdGVkKS48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiV0YSIsIGNhbCwgY2FsKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgVHVlfTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIHRBfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+TG9jYWxpemVkIHdlZWtkYXkgbmFtZSAoZnVsbCkuPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIldEEiLCBjYWwsIGNhbCk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIFR1ZXNkYXl9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgdGJ9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5Mb2NhbGl6ZWQgbW9udGggbmFtZSAoYWJicmV2aWF0ZWQpLjwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIGZvcm1hdCgiJXRiIiwgY2FsKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgQXByfTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIHRCfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+TG9jYWxpemVkIG1vbnRoIG5hbWUgKGZ1bGwpLjwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIGZvcm1hdCgiJXRCIiwgY2FsKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgQXByaWx9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgdGN9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5Mb2NhbGUtcHJlZmVycmVkIGRhdGUgYW5kIHRpbWUgcmVwcmVzZW50YXRpb24uIChTZWUge0BsaW5rIGphdmEudGV4dC5EYXRlRm9ybWF0fSBmb3IgbW9yZSB2YXJpYXRpb25zLik8L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiV0YyIsIGNhbCk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIFR1ZSBBcHIgMDEgMTY6MTk6MTcgQ0VTVCAyMDA4fTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIHRDfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+Mi1kaWdpdCBjZW50dXJ5LjwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIGZvcm1hdCgiJXRDIiwgY2FsKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgMjB9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgdGR9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj4yLWRpZ2l0IGRheSBvZiBtb250aCAoMDEtMzEpLjwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIGZvcm1hdCgiJXRkIiwgY2FsKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgMDF9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgdER9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5BbWJpZ3VvdXMgVVMgZGF0ZSBmb3JtYXQgKE1NL0REL1lZKS4gRG8gbm90IHVzZS48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiV0RCIsIGNhbCk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIDA0LzAxLzA4fTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIHRlfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+RGF5IG9mIG1vbnRoICgxLTMxKS48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiV0ZSIsIGNhbCk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIDF9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgdEZ9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5GdWxsIGRhdGUgaW4gSVNPIDg2MDEgZm9ybWF0IChZWVlZLU1NLUREKS48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiV0RiIsIGNhbCk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIDIwMDgtMDQtMDF9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgdGh9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5TeW5vbnltIGZvciB7QGNvZGUgJXRifS48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPjwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgdEh9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj4yNC1ob3VyIGhvdXIgb2YgZGF5ICgwMC0yMykuPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIldEgiLCBjYWwpO308L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSAxNn08L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB3aWR0aD0iNSUiPntAY29kZSB0SX08L3RkPgorICogPHRkIHdpZHRoPSIyNSUiPjEyLWhvdXIgaG91ciBvZiBkYXkgKDAxLTEyKS48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiV0SCIsIGNhbCk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIDA0fTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIHRqfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+My1kaWdpdCBkYXkgb2YgeWVhciAoMDAxLTM2NikuPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIldGoiLCBjYWwpO308L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSAwOTJ9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgdGt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj4yNC1ob3VyIGhvdXIgb2YgZGF5ICgwLTIzKS48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiV0SCIsIGNhbCk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIDE2fTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIHRsfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+MTItaG91ciBob3VyIG9mIGRheSAoMS0xMikuPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIldEgiLCBjYWwpO308L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSA0fTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIHRMfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+TWlsbGlzZWNvbmRzLjwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIGZvcm1hdCgiJXRMIiwgY2FsKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgMzU5fTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIHRtfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+Mi1kaWdpdCBtb250aCBvZiB5ZWFyICgwMS0xMikuPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIldG0iLCBjYWwpO308L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSAwNH08L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB3aWR0aD0iNSUiPntAY29kZSB0TX08L3RkPgorICogPHRkIHdpZHRoPSIyNSUiPjItZGlnaXQgbWludXRlLjwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIGZvcm1hdCgiJXRNIiwgY2FsKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgMDh9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgdE59PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5OYW5vc2Vjb25kcy48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiV0TiIsIGNhbCk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIDM1OTAwMDAwMH08L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB3aWR0aD0iNSUiPntAY29kZSB0cH08L3RkPgorICogPHRkIHdpZHRoPSIyNSUiPmEubS4gb3IgcC5tLjwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIGZvcm1hdCgiJXRwICVUcCIsIGNhbCwgY2FsKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgcG0gUE19PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgdFF9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5NaWxsaXNlY29uZHMgc2luY2UgdGhlIGVwb2NoLjwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIGZvcm1hdCgiJXRRIiwgY2FsKTt9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgMTIwNzA1OTQxMjY1Nn08L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB3aWR0aD0iNSUiPntAY29kZSB0cn08L3RkPgorICogPHRkIHdpZHRoPSIyNSUiPkZ1bGwgMTItaG91ciB0aW1lICh7QGNvZGUgJXRJOiV0TToldFMgJVRwfSkuPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIldHIiLCBjYWwpO308L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSAwNDoxNTozMiBQTX08L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB3aWR0aD0iNSUiPntAY29kZSB0Un08L3RkPgorICogPHRkIHdpZHRoPSIyNSUiPlNob3J0IDI0LWhvdXIgdGltZSAoe0Bjb2RlICV0SDoldE19KS48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiV0UiIsIGNhbCk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIDE2OjE1fTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIHRzfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+U2Vjb25kcyBzaW5jZSB0aGUgZXBvY2guPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIldHMiLCBjYWwpO308L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSAxMjA3MDU5NDEyfTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIHRTfTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+Mi1kaWdpdCBzZWNvbmRzICgwMC02MCkuPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIldFMiLCBjYWwpO308L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSAxN308L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB3aWR0aD0iNSUiPntAY29kZSB0VH08L3RkPgorICogPHRkIHdpZHRoPSIyNSUiPkZ1bGwgMjQtaG91ciB0aW1lICh7QGNvZGUgJXRIOiV0TToldFN9KS48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiV0VCIsIGNhbCk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIDE2OjE1OjMyfTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIHR5fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+Mi1kaWdpdCB5ZWFyICgwMC05OSkuPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIldHkiLCBjYWwpO308L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSAwOH08L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB3aWR0aD0iNSUiPntAY29kZSB0WX08L3RkPgorICogPHRkIHdpZHRoPSIyNSUiPjQtZGlnaXQgeWVhci48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiV0WSIsIGNhbCk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlIDIwMDh9PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgd2lkdGg9IjUlIj57QGNvZGUgdHp9PC90ZD4KKyAqIDx0ZCB3aWR0aD0iMjUlIj5UaW1lIHpvbmUgR01UIG9mZnNldC48L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBmb3JtYXQoIiV0eiIsIGNhbCk7fTwvdGQ+CisgKiA8dGQgd2lkdGg9IjMwJSI+e0Bjb2RlICswMTAwfTwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHdpZHRoPSI1JSI+e0Bjb2RlIHRafTwvdGQ+CisgKiA8dGQgd2lkdGg9IjI1JSI+TG9jYWxpemVkIHRpbWUgem9uZSBhYmJyZXZpYXRpb24uPC90ZD4KKyAqIDx0ZCB3aWR0aD0iMzAlIj57QGNvZGUgZm9ybWF0KCIldFoiLCBjYWwpO308L3RkPgorICogPHRkIHdpZHRoPSIzMCUiPntAY29kZSBDRVNUfTwvdGQ+CisgKiA8L3RyPgorICogPC90YWJsZT4KKyAqIDxwPjxpPk51bWJlciBsb2NhbGl6YXRpb248L2k+LiBTb21lIGNvbnZlcnNpb25zIHVzZSBsb2NhbGl6ZWQgZGVjaW1hbCBkaWdpdHMgcmF0aGVyIHRoYW4gdGhlCisgKiB1c3VhbCBBU0NJSSBkaWdpdHMuIFNvIGZvcm1hdHRpbmcge0Bjb2RlIDEyM30gd2l0aCB7QGNvZGUgJWR9IHdpbGwgZ2l2ZSAxMjMgaW4gRW5nbGlzaCBsb2NhbGVzCisgKiBidXQgJiN4MDY2MTsmI3gwNjYyOyYjeDA2NjM7IGluIGFwcHJvcHJpYXRlIEFyYWJpYyBsb2NhbGVzLCBmb3IgZXhhbXBsZS4gVGhpcyBudW1iZXIgbG9jYWxpemF0aW9uCisgKiBvY2N1cnMgZm9yIHRoZSBkZWNpbWFsIGludGVnZXIgY29udmVyc2lvbiB7QGNvZGUgJWR9LCB0aGUgZmxvYXRpbmcgcG9pbnQgY29udmVyc2lvbnMge0Bjb2RlICVlfSwKKyAqIHtAY29kZSAlZn0sIGFuZCB7QGNvZGUgJWd9LCBhbmQgYWxsIGRhdGUvdGltZSB7QGNvZGUgJXR9IG9yIHtAY29kZSAlVH0gY29udmVyc2lvbnMsIGJ1dCBubyBvdGhlcgorICogY29udmVyc2lvbnMuCisgKiA8cD48aT5UaHJlYWQgc2FmZXR5PC9pPi4gRm9ybWF0dGVyIGlzIG5vdCB0aHJlYWQtc2FmZS4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAc2VlIGphdmEudGV4dC5EYXRlRm9ybWF0CisgKiBAc2VlIEZvcm1hdHRhYmxlCisgKiBAc2VlIGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBGb3JtYXR0ZXIgaW1wbGVtZW50cyBDbG9zZWFibGUsIEZsdXNoYWJsZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIFpFUk9TID0gbmV3IGNoYXJbXSB7ICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcgfTsKKworICAgIC8qKgorICAgICAqIFRoZSBlbnVtZXJhdGlvbiBnaXZpbmcgdGhlIGF2YWlsYWJsZSBzdHlsZXMgZm9yIGZvcm1hdHRpbmcgdmVyeSBsYXJnZQorICAgICAqIGRlY2ltYWwgbnVtYmVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZW51bSBCaWdEZWNpbWFsTGF5b3V0Rm9ybSB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBVc2Ugc2NpZW50aWZpYyBzdHlsZSBmb3IgQmlnRGVjaW1hbHMuCisgICAgICAgICAqLworICAgICAgICBTQ0lFTlRJRklDLAorICAgICAgICAvKioKKyAgICAgICAgICogVXNlIG5vcm1hbCBkZWNpbWFsL2Zsb2F0IHN0eWxlIGZvciBCaWdEZWNpbWFscy4KKyAgICAgICAgICovCisgICAgICAgIERFQ0lNQUxfRkxPQVQKKyAgICB9CisKKyAgICAvLyBVc2VyLXNldHRhYmxlIHBhcmFtZXRlcnMuCisgICAgcHJpdmF0ZSBBcHBlbmRhYmxlIG91dDsKKyAgICBwcml2YXRlIExvY2FsZSBsb2NhbGU7CisKKyAgICAvLyBJbXBsZW1lbnRhdGlvbiBkZXRhaWxzLgorICAgIHByaXZhdGUgT2JqZWN0IGFyZzsKKyAgICBwcml2YXRlIGJvb2xlYW4gY2xvc2VkID0gZmFsc2U7CisgICAgcHJpdmF0ZSBGb3JtYXRUb2tlbiBmb3JtYXRUb2tlbjsKKyAgICBwcml2YXRlIElPRXhjZXB0aW9uIGxhc3RJT0V4Y2VwdGlvbjsKKyAgICBwcml2YXRlIExvY2FsZURhdGEgbG9jYWxlRGF0YTsKKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIENhY2hlZERlY2ltYWxGb3JtYXQgeworICAgICAgICBwdWJsaWMgTmF0aXZlRGVjaW1hbEZvcm1hdCBkZWNpbWFsRm9ybWF0OworICAgICAgICBwdWJsaWMgTG9jYWxlRGF0YSBjdXJyZW50TG9jYWxlRGF0YTsKKyAgICAgICAgcHVibGljIFN0cmluZyBjdXJyZW50UGF0dGVybjsKKworICAgICAgICBwdWJsaWMgQ2FjaGVkRGVjaW1hbEZvcm1hdCgpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBOYXRpdmVEZWNpbWFsRm9ybWF0IHVwZGF0ZShMb2NhbGVEYXRhIGxvY2FsZURhdGEsIFN0cmluZyBwYXR0ZXJuKSB7CisgICAgICAgICAgICBpZiAoZGVjaW1hbEZvcm1hdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY3VycmVudFBhdHRlcm4gPSBwYXR0ZXJuOworICAgICAgICAgICAgICAgIGN1cnJlbnRMb2NhbGVEYXRhID0gbG9jYWxlRGF0YTsKKyAgICAgICAgICAgICAgICBkZWNpbWFsRm9ybWF0ID0gbmV3IE5hdGl2ZURlY2ltYWxGb3JtYXQoY3VycmVudFBhdHRlcm4sIGN1cnJlbnRMb2NhbGVEYXRhKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghcGF0dGVybi5lcXVhbHMoY3VycmVudFBhdHRlcm4pKSB7CisgICAgICAgICAgICAgICAgZGVjaW1hbEZvcm1hdC5hcHBseVBhdHRlcm4ocGF0dGVybik7CisgICAgICAgICAgICAgICAgY3VycmVudFBhdHRlcm4gPSBwYXR0ZXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGxvY2FsZURhdGEgIT0gY3VycmVudExvY2FsZURhdGEpIHsKKyAgICAgICAgICAgICAgICBkZWNpbWFsRm9ybWF0LnNldERlY2ltYWxGb3JtYXRTeW1ib2xzKGxvY2FsZURhdGEpOworICAgICAgICAgICAgICAgIGN1cnJlbnRMb2NhbGVEYXRhID0gbG9jYWxlRGF0YTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBkZWNpbWFsRm9ybWF0OworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVGhyZWFkTG9jYWw8Q2FjaGVkRGVjaW1hbEZvcm1hdD4gY2FjaGVkRGVjaW1hbEZvcm1hdCA9IG5ldyBUaHJlYWRMb2NhbDxDYWNoZWREZWNpbWFsRm9ybWF0PigpIHsKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBDYWNoZWREZWNpbWFsRm9ybWF0IGluaXRpYWxWYWx1ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQ2FjaGVkRGVjaW1hbEZvcm1hdCgpOworICAgICAgICB9CisgICAgfTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuYXRpdmUgcGVlciBpZiB3ZSBkb24ndCBhbHJlYWR5IGhhdmUgb25lLCBvciByZWNvbmZpZ3VyZXMgYW4gZXhpc3Rpbmcgb25lLgorICAgICAqIFRoaXMgbWVhbnMgd2UgZ2V0IHRvIHJldXNlIHRoZSBwZWVyIGluIGNhc2VzIGxpa2UgIng9JS4yZiB5PSUuMmYiLgorICAgICAqLworICAgIHByaXZhdGUgTmF0aXZlRGVjaW1hbEZvcm1hdCBnZXREZWNpbWFsRm9ybWF0KFN0cmluZyBwYXR0ZXJuKSB7CisgICAgICAgIHJldHVybiBjYWNoZWREZWNpbWFsRm9ybWF0LmdldCgpLnVwZGF0ZShsb2NhbGVEYXRhLCBwYXR0ZXJuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIEZvcm1hdHRlcn0uCisgICAgICoKKyAgICAgKiA8cD5UaGUgb3V0cHV0IGlzIHdyaXR0ZW4gdG8gYSB7QGNvZGUgU3RyaW5nQnVpbGRlcn0gd2hpY2ggY2FuIGJlIGFjcXVpcmVkIGJ5IGludm9raW5nCisgICAgICoge0BsaW5rICNvdXQoKX0gYW5kIHdob3NlIGNvbnRlbnQgY2FuIGJlIG9idGFpbmVkIGJ5IGNhbGxpbmcge0Bjb2RlIHRvU3RyaW5nfS4KKyAgICAgKgorICAgICAqIDxwPlRoZSB7QGNvZGUgTG9jYWxlfSB1c2VkIGlzIHRoZSB1c2VyJ3MgZGVmYXVsdCBsb2NhbGUuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqLworICAgIHB1YmxpYyBGb3JtYXR0ZXIoKSB7CisgICAgICAgIHRoaXMobmV3IFN0cmluZ0J1aWxkZXIoKSwgTG9jYWxlLmdldERlZmF1bHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBGb3JtYXR0ZXJ9IHdob3NlIG91dHB1dCB3aWxsIGJlIHdyaXR0ZW4gdG8gdGhlCisgICAgICogc3BlY2lmaWVkIHtAY29kZSBBcHBlbmRhYmxlfS4KKyAgICAgKgorICAgICAqIDxwPlRoZSB7QGNvZGUgTG9jYWxlfSB1c2VkIGlzIHRoZSB1c2VyJ3MgZGVmYXVsdCBsb2NhbGUuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqCisgICAgICogQHBhcmFtIGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdXRwdXQgZGVzdGluYXRpb24gb2YgdGhlIHtAY29kZSBGb3JtYXR0ZXJ9LiBJZiB7QGNvZGUgYX0gaXMge0Bjb2RlIG51bGx9LAorICAgICAqICAgICAgICAgICAgdGhlbiBhIHtAY29kZSBTdHJpbmdCdWlsZGVyfSB3aWxsIGJlIHVzZWQuCisgICAgICovCisgICAgcHVibGljIEZvcm1hdHRlcihBcHBlbmRhYmxlIGEpIHsKKyAgICAgICAgdGhpcyhhLCBMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIEZvcm1hdHRlcn0gd2l0aCB0aGUgc3BlY2lmaWVkIHtAY29kZSBMb2NhbGV9LgorICAgICAqCisgICAgICogPHA+VGhlIG91dHB1dCBpcyB3cml0dGVuIHRvIGEge0Bjb2RlIFN0cmluZ0J1aWxkZXJ9IHdoaWNoIGNhbiBiZSBhY3F1aXJlZCBieSBpbnZva2luZworICAgICAqIHtAbGluayAjb3V0KCl9IGFuZCB3aG9zZSBjb250ZW50IGNhbiBiZSBvYnRhaW5lZCBieSBjYWxsaW5nIHtAY29kZSB0b1N0cmluZ30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBMb2NhbGV9IG9mIHRoZSB7QGNvZGUgRm9ybWF0dGVyfS4gSWYge0Bjb2RlIGx9IGlzIHtAY29kZSBudWxsfSwKKyAgICAgKiAgICAgICAgICAgIHRoZW4gbm8gbG9jYWxpemF0aW9uIHdpbGwgYmUgdXNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRm9ybWF0dGVyKExvY2FsZSBsKSB7CisgICAgICAgIHRoaXMobmV3IFN0cmluZ0J1aWxkZXIoKSwgbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBGb3JtYXR0ZXJ9IHdpdGggdGhlIHNwZWNpZmllZCB7QGNvZGUgTG9jYWxlfQorICAgICAqIGFuZCB3aG9zZSBvdXRwdXQgd2lsbCBiZSB3cml0dGVuIHRvIHRoZQorICAgICAqIHNwZWNpZmllZCB7QGNvZGUgQXBwZW5kYWJsZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYQorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBkZXN0aW5hdGlvbiBvZiB0aGUge0Bjb2RlIEZvcm1hdHRlcn0uIElmIHtAY29kZSBhfSBpcyB7QGNvZGUgbnVsbH0sCisgICAgICogICAgICAgICAgICB0aGVuIGEge0Bjb2RlIFN0cmluZ0J1aWxkZXJ9IHdpbGwgYmUgdXNlZC4KKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBMb2NhbGV9IG9mIHRoZSB7QGNvZGUgRm9ybWF0dGVyfS4gSWYge0Bjb2RlIGx9IGlzIHtAY29kZSBudWxsfSwKKyAgICAgKiAgICAgICAgICAgIHRoZW4gbm8gbG9jYWxpemF0aW9uIHdpbGwgYmUgdXNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRm9ybWF0dGVyKEFwcGVuZGFibGUgYSwgTG9jYWxlIGwpIHsKKyAgICAgICAgaWYgKGEgPT0gbnVsbCkgeworICAgICAgICAgICAgb3V0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG91dCA9IGE7CisgICAgICAgIH0KKyAgICAgICAgbG9jYWxlID0gbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIEZvcm1hdHRlcn0gd2hvc2Ugb3V0cHV0IGlzIHdyaXR0ZW4gdG8gdGhlIHNwZWNpZmllZCBmaWxlLgorICAgICAqCisgICAgICogPHA+VGhlIGNoYXJzZXQgb2YgdGhlIHtAY29kZSBGb3JtYXR0ZXJ9IGlzIHRoZSBkZWZhdWx0IGNoYXJzZXQuCisgICAgICoKKyAgICAgKiA8cD5UaGUge0Bjb2RlIExvY2FsZX0gdXNlZCBpcyB0aGUgdXNlcidzIGRlZmF1bHQgbG9jYWxlLgorICAgICAqIFNlZSAiPGEgaHJlZj0iLi4vdXRpbC9Mb2NhbGUuaHRtbCNkZWZhdWx0X2xvY2FsZSI+QmUgd2FyeSBvZiB0aGUgZGVmYXVsdCBsb2NhbGU8L2E+Ii4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGZpbGVuYW1lIG9mIHRoZSBmaWxlIHRoYXQgaXMgdXNlZCBhcyB0aGUgb3V0cHV0CisgICAgICogICAgICAgICAgICBkZXN0aW5hdGlvbiBmb3IgdGhlIHtAY29kZSBGb3JtYXR0ZXJ9LiBUaGUgZmlsZSB3aWxsIGJlIHRydW5jYXRlZCB0bworICAgICAqICAgICAgICAgICAgemVybyBzaXplIGlmIHRoZSBmaWxlIGV4aXN0cywgb3IgZWxzZSBhIG5ldyBmaWxlIHdpbGwgYmUKKyAgICAgKiAgICAgICAgICAgIGNyZWF0ZWQuIFRoZSBvdXRwdXQgb2YgdGhlIHtAY29kZSBGb3JtYXR0ZXJ9IGlzIGJ1ZmZlcmVkLgorICAgICAqIEB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGZpbGVuYW1lIGRvZXMgbm90IGRlbm90ZSBhIG5vcm1hbCBhbmQgd3JpdGFibGUgZmlsZSwKKyAgICAgKiAgICAgICAgICAgICBvciBpZiBhIG5ldyBmaWxlIGNhbm5vdCBiZSBjcmVhdGVkLCBvciBpZiBhbnkgZXJyb3IgYXJpc2VzIHdoZW4KKyAgICAgKiAgICAgICAgICAgICBvcGVuaW5nIG9yIGNyZWF0aW5nIHRoZSBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBGb3JtYXR0ZXIoU3RyaW5nIGZpbGVOYW1lKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhuZXcgRmlsZShmaWxlTmFtZSkpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBGb3JtYXR0ZXJ9IHdob3NlIG91dHB1dCBpcyB3cml0dGVuIHRvIHRoZSBzcGVjaWZpZWQgZmlsZS4KKyAgICAgKgorICAgICAqIDxwPlRoZSB7QGNvZGUgTG9jYWxlfSB1c2VkIGlzIHRoZSB1c2VyJ3MgZGVmYXVsdCBsb2NhbGUuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGVOYW1lCisgICAgICogICAgICAgICAgICB0aGUgZmlsZW5hbWUgb2YgdGhlIGZpbGUgdGhhdCBpcyB1c2VkIGFzIHRoZSBvdXRwdXQKKyAgICAgKiAgICAgICAgICAgIGRlc3RpbmF0aW9uIGZvciB0aGUge0Bjb2RlIEZvcm1hdHRlcn0uIFRoZSBmaWxlIHdpbGwgYmUgdHJ1bmNhdGVkIHRvCisgICAgICogICAgICAgICAgICB6ZXJvIHNpemUgaWYgdGhlIGZpbGUgZXhpc3RzLCBvciBlbHNlIGEgbmV3IGZpbGUgd2lsbCBiZQorICAgICAqICAgICAgICAgICAgY3JlYXRlZC4gVGhlIG91dHB1dCBvZiB0aGUge0Bjb2RlIEZvcm1hdHRlcn0gaXMgYnVmZmVyZWQuCisgICAgICogQHBhcmFtIGNzbgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNoYXJzZXQgZm9yIHRoZSB7QGNvZGUgRm9ybWF0dGVyfS4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBmaWxlbmFtZSBkb2VzIG5vdCBkZW5vdGUgYSBub3JtYWwgYW5kIHdyaXRhYmxlIGZpbGUsCisgICAgICogICAgICAgICAgICAgb3IgaWYgYSBuZXcgZmlsZSBjYW5ub3QgYmUgY3JlYXRlZCwgb3IgaWYgYW55IGVycm9yIGFyaXNlcyB3aGVuCisgICAgICogICAgICAgICAgICAgb3BlbmluZyBvciBjcmVhdGluZyB0aGUgZmlsZS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhcnNldCB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBGb3JtYXR0ZXIoU3RyaW5nIGZpbGVOYW1lLCBTdHJpbmcgY3NuKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uLAorICAgICAgICAgICAgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMobmV3IEZpbGUoZmlsZU5hbWUpLCBjc24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgRm9ybWF0dGVyfSB3aXRoIHRoZSBnaXZlbiB7QGNvZGUgTG9jYWxlfSBhbmQgY2hhcnNldCwKKyAgICAgKiBhbmQgd2hvc2Ugb3V0cHV0IGlzIHdyaXR0ZW4gdG8gdGhlIHNwZWNpZmllZCBmaWxlLgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGVOYW1lCisgICAgICogICAgICAgICAgICB0aGUgZmlsZW5hbWUgb2YgdGhlIGZpbGUgdGhhdCBpcyB1c2VkIGFzIHRoZSBvdXRwdXQKKyAgICAgKiAgICAgICAgICAgIGRlc3RpbmF0aW9uIGZvciB0aGUge0Bjb2RlIEZvcm1hdHRlcn0uIFRoZSBmaWxlIHdpbGwgYmUgdHJ1bmNhdGVkIHRvCisgICAgICogICAgICAgICAgICB6ZXJvIHNpemUgaWYgdGhlIGZpbGUgZXhpc3RzLCBvciBlbHNlIGEgbmV3IGZpbGUgd2lsbCBiZQorICAgICAqICAgICAgICAgICAgY3JlYXRlZC4gVGhlIG91dHB1dCBvZiB0aGUge0Bjb2RlIEZvcm1hdHRlcn0gaXMgYnVmZmVyZWQuCisgICAgICogQHBhcmFtIGNzbgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNoYXJzZXQgZm9yIHRoZSB7QGNvZGUgRm9ybWF0dGVyfS4KKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBMb2NhbGV9IG9mIHRoZSB7QGNvZGUgRm9ybWF0dGVyfS4gSWYge0Bjb2RlIGx9IGlzIHtAY29kZSBudWxsfSwKKyAgICAgKiAgICAgICAgICAgIHRoZW4gbm8gbG9jYWxpemF0aW9uIHdpbGwgYmUgdXNlZC4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBmaWxlbmFtZSBkb2VzIG5vdCBkZW5vdGUgYSBub3JtYWwgYW5kIHdyaXRhYmxlIGZpbGUsCisgICAgICogICAgICAgICAgICAgb3IgaWYgYSBuZXcgZmlsZSBjYW5ub3QgYmUgY3JlYXRlZCwgb3IgaWYgYW55IGVycm9yIGFyaXNlcyB3aGVuCisgICAgICogICAgICAgICAgICAgb3BlbmluZyBvciBjcmVhdGluZyB0aGUgZmlsZS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhcnNldCB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBGb3JtYXR0ZXIoU3RyaW5nIGZpbGVOYW1lLCBTdHJpbmcgY3NuLCBMb2NhbGUgbCkKKyAgICAgICAgICAgIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24sIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworCisgICAgICAgIHRoaXMobmV3IEZpbGUoZmlsZU5hbWUpLCBjc24sIGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgRm9ybWF0dGVyfSB3aG9zZSBvdXRwdXQgaXMgd3JpdHRlbiB0byB0aGUgc3BlY2lmaWVkIHtAY29kZSBGaWxlfS4KKyAgICAgKgorICAgICAqIFRoZSBjaGFyc2V0IG9mIHRoZSB7QGNvZGUgRm9ybWF0dGVyfSBpcyB0aGUgZGVmYXVsdCBjaGFyc2V0LgorICAgICAqCisgICAgICogPHA+VGhlIHtAY29kZSBMb2NhbGV9IHVzZWQgaXMgdGhlIHVzZXIncyBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKiBTZWUgIjxhIGhyZWY9Ii4uL3V0aWwvTG9jYWxlLmh0bWwjZGVmYXVsdF9sb2NhbGUiPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9hPiIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBGaWxlfSB0aGF0IGlzIHVzZWQgYXMgdGhlIG91dHB1dCBkZXN0aW5hdGlvbiBmb3IgdGhlCisgICAgICogICAgICAgICAgICB7QGNvZGUgRm9ybWF0dGVyfS4gVGhlIHtAY29kZSBGaWxlfSB3aWxsIGJlIHRydW5jYXRlZCB0byB6ZXJvIHNpemUgaWYgdGhlIHtAY29kZSBGaWxlfQorICAgICAqICAgICAgICAgICAgZXhpc3RzLCBvciBlbHNlIGEgbmV3IHtAY29kZSBGaWxlfSB3aWxsIGJlIGNyZWF0ZWQuIFRoZSBvdXRwdXQgb2YgdGhlCisgICAgICogICAgICAgICAgICB7QGNvZGUgRm9ybWF0dGVyfSBpcyBidWZmZXJlZC4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgRmlsZX0gaXMgbm90IGEgbm9ybWFsIGFuZCB3cml0YWJsZSB7QGNvZGUgRmlsZX0sIG9yIGlmIGEKKyAgICAgKiAgICAgICAgICAgICBuZXcge0Bjb2RlIEZpbGV9IGNhbm5vdCBiZSBjcmVhdGVkLCBvciBpZiBhbnkgZXJyb3IgcmlzZXMgd2hlbiBvcGVuaW5nIG9yCisgICAgICogICAgICAgICAgICAgY3JlYXRpbmcgdGhlIHtAY29kZSBGaWxlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRm9ybWF0dGVyKEZpbGUgZmlsZSkgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMobmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgRm9ybWF0dGVyfSB3aXRoIHRoZSBnaXZlbiBjaGFyc2V0LAorICAgICAqIGFuZCB3aG9zZSBvdXRwdXQgaXMgd3JpdHRlbiB0byB0aGUgc3BlY2lmaWVkIHtAY29kZSBGaWxlfS4KKyAgICAgKgorICAgICAqIDxwPlRoZSB7QGNvZGUgTG9jYWxlfSB1c2VkIGlzIHRoZSB1c2VyJ3MgZGVmYXVsdCBsb2NhbGUuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgRmlsZX0gdGhhdCBpcyB1c2VkIGFzIHRoZSBvdXRwdXQgZGVzdGluYXRpb24gZm9yIHRoZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIEZvcm1hdHRlcn0uIFRoZSB7QGNvZGUgRmlsZX0gd2lsbCBiZSB0cnVuY2F0ZWQgdG8gemVybyBzaXplIGlmIHRoZSB7QGNvZGUgRmlsZX0KKyAgICAgKiAgICAgICAgICAgIGV4aXN0cywgb3IgZWxzZSBhIG5ldyB7QGNvZGUgRmlsZX0gd2lsbCBiZSBjcmVhdGVkLiBUaGUgb3V0cHV0IG9mIHRoZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIEZvcm1hdHRlcn0gaXMgYnVmZmVyZWQuCisgICAgICogQHBhcmFtIGNzbgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNoYXJzZXQgZm9yIHRoZSB7QGNvZGUgRm9ybWF0dGVyfS4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgRmlsZX0gaXMgbm90IGEgbm9ybWFsIGFuZCB3cml0YWJsZSB7QGNvZGUgRmlsZX0sIG9yIGlmIGEKKyAgICAgKiAgICAgICAgICAgICBuZXcge0Bjb2RlIEZpbGV9IGNhbm5vdCBiZSBjcmVhdGVkLCBvciBpZiBhbnkgZXJyb3IgcmlzZXMgd2hlbiBvcGVuaW5nIG9yCisgICAgICogICAgICAgICAgICAgY3JlYXRpbmcgdGhlIHtAY29kZSBGaWxlfS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhcnNldCB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBGb3JtYXR0ZXIoRmlsZSBmaWxlLCBTdHJpbmcgY3NuKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uLAorICAgICAgICAgICAgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoZmlsZSwgY3NuLCBMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIEZvcm1hdHRlcn0gd2l0aCB0aGUgZ2l2ZW4ge0Bjb2RlIExvY2FsZX0gYW5kIGNoYXJzZXQsCisgICAgICogYW5kIHdob3NlIG91dHB1dCBpcyB3cml0dGVuIHRvIHRoZSBzcGVjaWZpZWQge0Bjb2RlIEZpbGV9LgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgRmlsZX0gdGhhdCBpcyB1c2VkIGFzIHRoZSBvdXRwdXQgZGVzdGluYXRpb24gZm9yIHRoZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIEZvcm1hdHRlcn0uIFRoZSB7QGNvZGUgRmlsZX0gd2lsbCBiZSB0cnVuY2F0ZWQgdG8gemVybyBzaXplIGlmIHRoZSB7QGNvZGUgRmlsZX0KKyAgICAgKiAgICAgICAgICAgIGV4aXN0cywgb3IgZWxzZSBhIG5ldyB7QGNvZGUgRmlsZX0gd2lsbCBiZSBjcmVhdGVkLiBUaGUgb3V0cHV0IG9mIHRoZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIEZvcm1hdHRlcn0gaXMgYnVmZmVyZWQuCisgICAgICogQHBhcmFtIGNzbgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNoYXJzZXQgZm9yIHRoZSB7QGNvZGUgRm9ybWF0dGVyfS4KKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBMb2NhbGV9IG9mIHRoZSB7QGNvZGUgRm9ybWF0dGVyfS4gSWYge0Bjb2RlIGx9IGlzIHtAY29kZSBudWxsfSwKKyAgICAgKiAgICAgICAgICAgIHRoZW4gbm8gbG9jYWxpemF0aW9uIHdpbGwgYmUgdXNlZC4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgRmlsZX0gaXMgbm90IGEgbm9ybWFsIGFuZCB3cml0YWJsZSB7QGNvZGUgRmlsZX0sIG9yIGlmIGEKKyAgICAgKiAgICAgICAgICAgICBuZXcge0Bjb2RlIEZpbGV9IGNhbm5vdCBiZSBjcmVhdGVkLCBvciBpZiBhbnkgZXJyb3IgcmlzZXMgd2hlbiBvcGVuaW5nIG9yCisgICAgICogICAgICAgICAgICAgY3JlYXRpbmcgdGhlIHtAY29kZSBGaWxlfS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhcnNldCB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBGb3JtYXR0ZXIoRmlsZSBmaWxlLCBTdHJpbmcgY3NuLCBMb2NhbGUgbCkKKyAgICAgICAgICAgIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24sIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIGZvdXQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZpbGUpOworICAgICAgICAgICAgb3V0ID0gbmV3IEJ1ZmZlcmVkV3JpdGVyKG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoZm91dCwgY3NuKSk7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkoZm91dCk7CisgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIElvVXRpbHMuY2xvc2VRdWlldGx5KGZvdXQpOworICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgfQorCisgICAgICAgIGxvY2FsZSA9IGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBGb3JtYXR0ZXJ9IHdob3NlIG91dHB1dCBpcyB3cml0dGVuIHRvIHRoZSBzcGVjaWZpZWQge0Bjb2RlIE91dHB1dFN0cmVhbX0uCisgICAgICoKKyAgICAgKiA8cD5UaGUgY2hhcnNldCBvZiB0aGUge0Bjb2RlIEZvcm1hdHRlcn0gaXMgdGhlIGRlZmF1bHQgY2hhcnNldC4KKyAgICAgKgorICAgICAqIDxwPlRoZSB7QGNvZGUgTG9jYWxlfSB1c2VkIGlzIHRoZSB1c2VyJ3MgZGVmYXVsdCBsb2NhbGUuCisgICAgICogU2VlICI8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4iLgorICAgICAqCisgICAgICogQHBhcmFtIG9zCisgICAgICogICAgICAgICAgICB0aGUgc3RyZWFtIHRvIGJlIHVzZWQgYXMgdGhlIGRlc3RpbmF0aW9uIG9mIHRoZSB7QGNvZGUgRm9ybWF0dGVyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRm9ybWF0dGVyKE91dHB1dFN0cmVhbSBvcykgeworICAgICAgICBvdXQgPSBuZXcgQnVmZmVyZWRXcml0ZXIobmV3IE91dHB1dFN0cmVhbVdyaXRlcihvcywgQ2hhcnNldC5kZWZhdWx0Q2hhcnNldCgpKSk7CisgICAgICAgIGxvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBGb3JtYXR0ZXJ9IHdpdGggdGhlIGdpdmVuIGNoYXJzZXQsCisgICAgICogYW5kIHdob3NlIG91dHB1dCBpcyB3cml0dGVuIHRvIHRoZSBzcGVjaWZpZWQge0Bjb2RlIE91dHB1dFN0cmVhbX0uCisgICAgICoKKyAgICAgKiA8cD5UaGUge0Bjb2RlIExvY2FsZX0gdXNlZCBpcyB0aGUgdXNlcidzIGRlZmF1bHQgbG9jYWxlLgorICAgICAqIFNlZSAiPGEgaHJlZj0iLi4vdXRpbC9Mb2NhbGUuaHRtbCNkZWZhdWx0X2xvY2FsZSI+QmUgd2FyeSBvZiB0aGUgZGVmYXVsdCBsb2NhbGU8L2E+Ii4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcworICAgICAqICAgICAgICAgICAgdGhlIHN0cmVhbSB0byBiZSB1c2VkIGFzIHRoZSBkZXN0aW5hdGlvbiBvZiB0aGUge0Bjb2RlIEZvcm1hdHRlcn0uCisgICAgICogQHBhcmFtIGNzbgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNoYXJzZXQgZm9yIHRoZSB7QGNvZGUgRm9ybWF0dGVyfS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2hhcnNldCB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBGb3JtYXR0ZXIoT3V0cHV0U3RyZWFtIG9zLCBTdHJpbmcgY3NuKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMob3MsIGNzbiwgTG9jYWxlLmdldERlZmF1bHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBGb3JtYXR0ZXJ9IHdpdGggdGhlIGdpdmVuIHtAY29kZSBMb2NhbGV9IGFuZCBjaGFyc2V0LAorICAgICAqIGFuZCB3aG9zZSBvdXRwdXQgaXMgd3JpdHRlbiB0byB0aGUgc3BlY2lmaWVkIHtAY29kZSBPdXRwdXRTdHJlYW19LgorICAgICAqCisgICAgICogQHBhcmFtIG9zCisgICAgICogICAgICAgICAgICB0aGUgc3RyZWFtIHRvIGJlIHVzZWQgYXMgdGhlIGRlc3RpbmF0aW9uIG9mIHRoZSB7QGNvZGUgRm9ybWF0dGVyfS4KKyAgICAgKiBAcGFyYW0gY3NuCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY2hhcnNldCBmb3IgdGhlIHtAY29kZSBGb3JtYXR0ZXJ9LgorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIExvY2FsZX0gb2YgdGhlIHtAY29kZSBGb3JtYXR0ZXJ9LiBJZiB7QGNvZGUgbH0gaXMge0Bjb2RlIG51bGx9LAorICAgICAqICAgICAgICAgICAgdGhlbiBubyBsb2NhbGl6YXRpb24gd2lsbCBiZSB1c2VkLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjaGFyc2V0IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIEZvcm1hdHRlcihPdXRwdXRTdHJlYW0gb3MsIFN0cmluZyBjc24sIExvY2FsZSBsKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIG91dCA9IG5ldyBCdWZmZXJlZFdyaXRlcihuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG9zLCBjc24pKTsKKyAgICAgICAgbG9jYWxlID0gbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIEZvcm1hdHRlcn0gd2hvc2Ugb3V0cHV0IGlzIHdyaXR0ZW4gdG8gdGhlIHNwZWNpZmllZCB7QGNvZGUgUHJpbnRTdHJlYW19LgorICAgICAqCisgICAgICogPHA+VGhlIGNoYXJzZXQgb2YgdGhlIHtAY29kZSBGb3JtYXR0ZXJ9IGlzIHRoZSBkZWZhdWx0IGNoYXJzZXQuCisgICAgICoKKyAgICAgKiA8cD5UaGUge0Bjb2RlIExvY2FsZX0gdXNlZCBpcyB0aGUgdXNlcidzIGRlZmF1bHQgbG9jYWxlLgorICAgICAqIFNlZSAiPGEgaHJlZj0iLi4vdXRpbC9Mb2NhbGUuaHRtbCNkZWZhdWx0X2xvY2FsZSI+QmUgd2FyeSBvZiB0aGUgZGVmYXVsdCBsb2NhbGU8L2E+Ii4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBQcmludFN0cmVhbX0gdXNlZCBhcyBkZXN0aW5hdGlvbiBvZiB0aGUge0Bjb2RlIEZvcm1hdHRlcn0uIElmCisgICAgICogICAgICAgICAgICB7QGNvZGUgcHN9IGlzIHtAY29kZSBudWxsfSwgdGhlbiBhIHtAY29kZSBOdWxsUG9pbnRlckV4Y2VwdGlvbn0gd2lsbAorICAgICAqICAgICAgICAgICAgYmUgcmFpc2VkLgorICAgICAqLworICAgIHB1YmxpYyBGb3JtYXR0ZXIoUHJpbnRTdHJlYW0gcHMpIHsKKyAgICAgICAgaWYgKHBzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIG91dCA9IHBzOworICAgICAgICBsb2NhbGUgPSBMb2NhbGUuZ2V0RGVmYXVsdCgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja05vdENsb3NlZCgpIHsKKyAgICAgICAgaWYgKGNsb3NlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEZvcm1hdHRlckNsb3NlZEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIExvY2FsZX0gb2YgdGhlIHtAY29kZSBGb3JtYXR0ZXJ9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIExvY2FsZX0gZm9yIHRoZSB7QGNvZGUgRm9ybWF0dGVyfSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vIHtAY29kZSBMb2NhbGV9LgorICAgICAqIEB0aHJvd3MgRm9ybWF0dGVyQ2xvc2VkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBGb3JtYXR0ZXJ9IGhhcyBiZWVuIGNsb3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTG9jYWxlIGxvY2FsZSgpIHsKKyAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgcmV0dXJuIGxvY2FsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBvdXRwdXQgZGVzdGluYXRpb24gb2YgdGhlIHtAY29kZSBGb3JtYXR0ZXJ9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgb3V0cHV0IGRlc3RpbmF0aW9uIG9mIHRoZSB7QGNvZGUgRm9ybWF0dGVyfS4KKyAgICAgKiBAdGhyb3dzIEZvcm1hdHRlckNsb3NlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgRm9ybWF0dGVyfSBoYXMgYmVlbiBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIEFwcGVuZGFibGUgb3V0KCkgeworICAgICAgICBjaGVja05vdENsb3NlZCgpOworICAgICAgICByZXR1cm4gb3V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNvbnRlbnQgYnkgY2FsbGluZyB0aGUge0Bjb2RlIHRvU3RyaW5nKCl9IG1ldGhvZCBvZiB0aGUgb3V0cHV0CisgICAgICogZGVzdGluYXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb250ZW50IGJ5IGNhbGxpbmcgdGhlIHtAY29kZSB0b1N0cmluZygpfSBtZXRob2Qgb2YgdGhlIG91dHB1dAorICAgICAqICAgICAgICAgZGVzdGluYXRpb24uCisgICAgICogQHRocm93cyBGb3JtYXR0ZXJDbG9zZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIEZvcm1hdHRlcn0gaGFzIGJlZW4gY2xvc2VkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgIHJldHVybiBvdXQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIHRoZSB7QGNvZGUgRm9ybWF0dGVyfS4gSWYgdGhlIG91dHB1dCBkZXN0aW5hdGlvbiBpcyB7QGxpbmsgRmx1c2hhYmxlfSwKKyAgICAgKiB0aGVuIHRoZSBtZXRob2Qge0Bjb2RlIGZsdXNoKCl9IHdpbGwgYmUgY2FsbGVkIG9uIHRoYXQgZGVzdGluYXRpb24uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEZvcm1hdHRlckNsb3NlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgRm9ybWF0dGVyfSBoYXMgYmVlbiBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB7CisgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgIGlmIChvdXQgaW5zdGFuY2VvZiBGbHVzaGFibGUpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgKChGbHVzaGFibGUpIG91dCkuZmx1c2goKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBsYXN0SU9FeGNlcHRpb24gPSBlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoZSB7QGNvZGUgRm9ybWF0dGVyfS4gSWYgdGhlIG91dHB1dCBkZXN0aW5hdGlvbiBpcyB7QGxpbmsgQ2xvc2VhYmxlfSwKKyAgICAgKiB0aGVuIHRoZSBtZXRob2Qge0Bjb2RlIGNsb3NlKCl9IHdpbGwgYmUgY2FsbGVkIG9uIHRoYXQgZGVzdGluYXRpb24uCisgICAgICoKKyAgICAgKiBJZiB0aGUge0Bjb2RlIEZvcm1hdHRlcn0gaGFzIGJlZW4gY2xvc2VkLCB0aGVuIGNhbGxpbmcgdGhlIHRoaXMgbWV0aG9kIHdpbGwgaGF2ZSBubworICAgICAqIGVmZmVjdC4KKyAgICAgKgorICAgICAqIEFueSBtZXRob2QgYnV0IHRoZSB7QGxpbmsgI2lvRXhjZXB0aW9uKCl9IHRoYXQgaXMgY2FsbGVkIGFmdGVyIHRoZQorICAgICAqIHtAY29kZSBGb3JtYXR0ZXJ9IGhhcyBiZWVuIGNsb3NlZCB3aWxsIHJhaXNlIGEge0Bjb2RlIEZvcm1hdHRlckNsb3NlZEV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgIGlmICghY2xvc2VkKSB7CisgICAgICAgICAgICBjbG9zZWQgPSB0cnVlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAob3V0IGluc3RhbmNlb2YgQ2xvc2VhYmxlKSB7CisgICAgICAgICAgICAgICAgICAgICgoQ2xvc2VhYmxlKSBvdXQpLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGxhc3RJT0V4Y2VwdGlvbiA9IGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsYXN0IHtAY29kZSBJT0V4Y2VwdGlvbn0gdGhyb3duIGJ5IHRoZSB7QGNvZGUgRm9ybWF0dGVyfSdzIG91dHB1dAorICAgICAqIGRlc3RpbmF0aW9uLiBJZiB0aGUge0Bjb2RlIGFwcGVuZCgpfSBtZXRob2Qgb2YgdGhlIGRlc3RpbmF0aW9uIGRvZXMgbm90IHRocm93CisgICAgICoge0Bjb2RlIElPRXhjZXB0aW9ufXMsIHRoZSB7QGNvZGUgaW9FeGNlcHRpb24oKX0gbWV0aG9kIHdpbGwgYWx3YXlzIHJldHVybiB7QGNvZGUgbnVsbH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsYXN0IHtAY29kZSBJT0V4Y2VwdGlvbn0gdGhyb3duIGJ5IHRoZSB7QGNvZGUgRm9ybWF0dGVyfSdzIG91dHB1dAorICAgICAqICAgICAgICAgZGVzdGluYXRpb24uCisgICAgICovCisgICAgcHVibGljIElPRXhjZXB0aW9uIGlvRXhjZXB0aW9uKCkgeworICAgICAgICByZXR1cm4gbGFzdElPRXhjZXB0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGZvcm1hdHRlZCBzdHJpbmcgdG8gdGhlIG91dHB1dCBkZXN0aW5hdGlvbiBvZiB0aGUge0Bjb2RlIEZvcm1hdHRlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9ybWF0CisgICAgICogICAgICAgICAgICBhIGZvcm1hdCBzdHJpbmcuCisgICAgICogQHBhcmFtIGFyZ3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcmd1bWVudHMgbGlzdCB1c2VkIGluIHRoZSB7QGNvZGUgZm9ybWF0KCl9IG1ldGhvZC4gSWYgdGhlcmUgYXJlCisgICAgICogICAgICAgICAgICBtb3JlIGFyZ3VtZW50cyB0aGFuIHRob3NlIHNwZWNpZmllZCBieSB0aGUgZm9ybWF0IHN0cmluZywgdGhlbgorICAgICAqICAgICAgICAgICAgdGhlIGFkZGl0aW9uYWwgYXJndW1lbnRzIGFyZSBpZ25vcmVkLgorICAgICAqIEByZXR1cm4gdGhpcyB7QGNvZGUgRm9ybWF0dGVyfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZm9ybWF0IHN0cmluZyBpcyBpbGxlZ2FsIG9yIGluY29tcGF0aWJsZSB3aXRoIHRoZQorICAgICAqICAgICAgICAgICAgIGFyZ3VtZW50cywgb3IgaWYgZmV3ZXIgYXJndW1lbnRzIGFyZSBzZW50IHRoYW4gdGhvc2UgcmVxdWlyZWQgYnkKKyAgICAgKiAgICAgICAgICAgICB0aGUgZm9ybWF0IHN0cmluZywgb3IgYW55IG90aGVyIGlsbGVnYWwgc2l0dWF0aW9uLgorICAgICAqIEB0aHJvd3MgRm9ybWF0dGVyQ2xvc2VkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBGb3JtYXR0ZXJ9IGhhcyBiZWVuIGNsb3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRm9ybWF0dGVyIGZvcm1hdChTdHJpbmcgZm9ybWF0LCBPYmplY3QuLi4gYXJncykgeworICAgICAgICByZXR1cm4gZm9ybWF0KHRoaXMubG9jYWxlLCBmb3JtYXQsIGFyZ3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGZvcm1hdHRlZCBzdHJpbmcgdG8gdGhlIG91dHB1dCBkZXN0aW5hdGlvbiBvZiB0aGUge0Bjb2RlIEZvcm1hdHRlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBMb2NhbGV9IHVzZWQgaW4gdGhlIG1ldGhvZC4gSWYge0Bjb2RlIGxvY2FsZX0gaXMKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBudWxsfSwgdGhlbiBubyBsb2NhbGl6YXRpb24gd2lsbCBiZSBhcHBsaWVkLiBUaGlzCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIgZG9lcyBub3QgY2hhbmdlIHRoaXMgRm9ybWF0dGVyJ3MgZGVmYXVsdCB7QGNvZGUgTG9jYWxlfQorICAgICAqICAgICAgICAgICAgYXMgc3BlY2lmaWVkIGR1cmluZyBjb25zdHJ1Y3Rpb24sIGFuZCBvbmx5IGFwcGxpZXMgZm9yIHRoZQorICAgICAqICAgICAgICAgICAgZHVyYXRpb24gb2YgdGhpcyBjYWxsLgorICAgICAqIEBwYXJhbSBmb3JtYXQKKyAgICAgKiAgICAgICAgICAgIGEgZm9ybWF0IHN0cmluZy4KKyAgICAgKiBAcGFyYW0gYXJncworICAgICAqICAgICAgICAgICAgdGhlIGFyZ3VtZW50cyBsaXN0IHVzZWQgaW4gdGhlIHtAY29kZSBmb3JtYXQoKX0gbWV0aG9kLiBJZiB0aGVyZSBhcmUKKyAgICAgKiAgICAgICAgICAgIG1vcmUgYXJndW1lbnRzIHRoYW4gdGhvc2Ugc3BlY2lmaWVkIGJ5IHRoZSBmb3JtYXQgc3RyaW5nLCB0aGVuCisgICAgICogICAgICAgICAgICB0aGUgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIGlnbm9yZWQuCisgICAgICogQHJldHVybiB0aGlzIHtAY29kZSBGb3JtYXR0ZXJ9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBmb3JtYXQgc3RyaW5nIGlzIGlsbGVnYWwgb3IgaW5jb21wYXRpYmxlIHdpdGggdGhlCisgICAgICogICAgICAgICAgICAgYXJndW1lbnRzLCBvciBpZiBmZXdlciBhcmd1bWVudHMgYXJlIHNlbnQgdGhhbiB0aG9zZSByZXF1aXJlZCBieQorICAgICAqICAgICAgICAgICAgIHRoZSBmb3JtYXQgc3RyaW5nLCBvciBhbnkgb3RoZXIgaWxsZWdhbCBzaXR1YXRpb24uCisgICAgICogQHRocm93cyBGb3JtYXR0ZXJDbG9zZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIEZvcm1hdHRlcn0gaGFzIGJlZW4gY2xvc2VkLgorICAgICAqLworICAgIHB1YmxpYyBGb3JtYXR0ZXIgZm9ybWF0KExvY2FsZSBsLCBTdHJpbmcgZm9ybWF0LCBPYmplY3QuLi4gYXJncykgeworICAgICAgICBMb2NhbGUgb3JpZ2luYWxMb2NhbGUgPSBsb2NhbGU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGlzLmxvY2FsZSA9IChsID09IG51bGwgPyBMb2NhbGUuVVMgOiBsKTsKKyAgICAgICAgICAgIHRoaXMubG9jYWxlRGF0YSA9IExvY2FsZURhdGEuZ2V0KGxvY2FsZSk7CisgICAgICAgICAgICBkb0Zvcm1hdChmb3JtYXQsIGFyZ3MpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdGhpcy5sb2NhbGUgPSBvcmlnaW5hbExvY2FsZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZG9Gb3JtYXQoU3RyaW5nIGZvcm1hdCwgT2JqZWN0Li4uIGFyZ3MpIHsKKyAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKworICAgICAgICBGb3JtYXRTcGVjaWZpZXJQYXJzZXIgZnNwID0gbmV3IEZvcm1hdFNwZWNpZmllclBhcnNlcihmb3JtYXQpOworICAgICAgICBpbnQgY3VycmVudE9iamVjdEluZGV4ID0gMDsKKyAgICAgICAgT2JqZWN0IGxhc3RBcmd1bWVudCA9IG51bGw7CisgICAgICAgIGJvb2xlYW4gaGFzTGFzdEFyZ3VtZW50U2V0ID0gZmFsc2U7CisKKyAgICAgICAgaW50IGxlbmd0aCA9IGZvcm1hdC5sZW5ndGgoKTsKKyAgICAgICAgaW50IGkgPSAwOworICAgICAgICB3aGlsZSAoaSA8IGxlbmd0aCkgeworICAgICAgICAgICAgLy8gRmluZCB0aGUgbWF4aW1hbCBwbGFpbi10ZXh0IHNlcXVlbmNlLi4uCisgICAgICAgICAgICBpbnQgcGxhaW5UZXh0U3RhcnQgPSBpOworICAgICAgICAgICAgaW50IG5leHRQZXJjZW50ID0gZm9ybWF0LmluZGV4T2YoJyUnLCBpKTsKKyAgICAgICAgICAgIGludCBwbGFpblRleHRFbmQgPSAobmV4dFBlcmNlbnQgPT0gLTEpID8gbGVuZ3RoIDogbmV4dFBlcmNlbnQ7CisgICAgICAgICAgICAvLyAuLi5hbmQgb3V0cHV0IGl0LgorICAgICAgICAgICAgaWYgKHBsYWluVGV4dEVuZCA+IHBsYWluVGV4dFN0YXJ0KSB7CisgICAgICAgICAgICAgICAgb3V0cHV0Q2hhclNlcXVlbmNlKGZvcm1hdCwgcGxhaW5UZXh0U3RhcnQsIHBsYWluVGV4dEVuZCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpID0gcGxhaW5UZXh0RW5kOworICAgICAgICAgICAgLy8gRG8gd2UgaGF2ZSBhIGZvcm1hdCBzcGVjaWZpZXI/CisgICAgICAgICAgICBpZiAoaSA8IGxlbmd0aCkgeworICAgICAgICAgICAgICAgIEZvcm1hdFRva2VuIHRva2VuID0gZnNwLnBhcnNlRm9ybWF0VG9rZW4oaSArIDEpOworCisgICAgICAgICAgICAgICAgT2JqZWN0IGFyZ3VtZW50ID0gbnVsbDsKKyAgICAgICAgICAgICAgICBpZiAodG9rZW4ucmVxdWlyZUFyZ3VtZW50KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gdG9rZW4uZ2V0QXJnSW5kZXgoKSA9PSBGb3JtYXRUb2tlbi5VTlNFVCA/IGN1cnJlbnRPYmplY3RJbmRleCsrIDogdG9rZW4uZ2V0QXJnSW5kZXgoKTsKKyAgICAgICAgICAgICAgICAgICAgYXJndW1lbnQgPSBnZXRBcmd1bWVudChhcmdzLCBpbmRleCwgZnNwLCBsYXN0QXJndW1lbnQsIGhhc0xhc3RBcmd1bWVudFNldCk7CisgICAgICAgICAgICAgICAgICAgIGxhc3RBcmd1bWVudCA9IGFyZ3VtZW50OworICAgICAgICAgICAgICAgICAgICBoYXNMYXN0QXJndW1lbnRTZXQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIENoYXJTZXF1ZW5jZSBzdWJzdGl0dXRpb24gPSB0cmFuc2Zvcm0odG9rZW4sIGFyZ3VtZW50KTsKKyAgICAgICAgICAgICAgICAvLyBUaGUgc3Vic3RpdHV0aW9uIGlzIG51bGwgaWYgd2UgY2FsbGVkIEZvcm1hdHRhYmxlLmZvcm1hdFRvLgorICAgICAgICAgICAgICAgIGlmIChzdWJzdGl0dXRpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFyU2VxdWVuY2Uoc3Vic3RpdHV0aW9uLCAwLCBzdWJzdGl0dXRpb24ubGVuZ3RoKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpID0gZnNwLmk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBGaXhlcyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTE3NjcuCisgICAgcHJpdmF0ZSB2b2lkIG91dHB1dENoYXJTZXF1ZW5jZShDaGFyU2VxdWVuY2UgY3MsIGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3V0LmFwcGVuZChjcywgc3RhcnQsIGVuZCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGxhc3RJT0V4Y2VwdGlvbiA9IGU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIE9iamVjdCBnZXRBcmd1bWVudChPYmplY3RbXSBhcmdzLCBpbnQgaW5kZXgsIEZvcm1hdFNwZWNpZmllclBhcnNlciBmc3AsCisgICAgICAgICAgICBPYmplY3QgbGFzdEFyZ3VtZW50LCBib29sZWFuIGhhc0xhc3RBcmd1bWVudFNldCkgeworICAgICAgICBpZiAoaW5kZXggPT0gRm9ybWF0VG9rZW4uTEFTVF9BUkdVTUVOVF9JTkRFWCAmJiAhaGFzTGFzdEFyZ3VtZW50U2V0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTWlzc2luZ0Zvcm1hdEFyZ3VtZW50RXhjZXB0aW9uKCI8Iik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoYXJncyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChpbmRleCA+PSBhcmdzLmxlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE1pc3NpbmdGb3JtYXRBcmd1bWVudEV4Y2VwdGlvbihmc3AuZ2V0Rm9ybWF0U3BlY2lmaWVyVGV4dCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChpbmRleCA9PSBGb3JtYXRUb2tlbi5MQVNUX0FSR1VNRU5UX0lOREVYKSB7CisgICAgICAgICAgICByZXR1cm4gbGFzdEFyZ3VtZW50OworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGFyZ3NbaW5kZXhdOworICAgIH0KKworICAgIC8qCisgICAgICogQ29tcGxldGUgZGV0YWlscyBvZiBhIHNpbmdsZSBmb3JtYXQgc3BlY2lmaWVyIHBhcnNlZCBmcm9tIGEgZm9ybWF0IHN0cmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBGb3JtYXRUb2tlbiB7CisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgTEFTVF9BUkdVTUVOVF9JTkRFWCA9IC0yOworCisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgVU5TRVQgPSAtMTsKKworICAgICAgICBzdGF0aWMgZmluYWwgaW50IEZMQUdTX1VOU0VUID0gMDsKKworICAgICAgICBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfUFJFQ0lTSU9OID0gNjsKKworICAgICAgICBzdGF0aWMgZmluYWwgaW50IEZMQUdfWkVSTyA9IDEgPDwgNDsKKworICAgICAgICBwcml2YXRlIGludCBhcmdJbmRleCA9IFVOU0VUOworCisgICAgICAgIC8vIFRoZXNlIGhhdmUgcGFja2FnZSBhY2Nlc3MgZm9yIHBlcmZvcm1hbmNlLiBUaGV5IHVzZWQgdG8gYmUgcmVwcmVzZW50ZWQgYnkgYW4gaW50IGJpdG1hc2sKKyAgICAgICAgLy8gYW5kIGFjY2Vzc2VkIHZpYSBtZXRob2RzLCBidXQgQW5kcm9pZCdzIEpJVCBkb2Vzbid0IHlldCBkbyBhIGdvb2Qgam9iIG9mIHN1Y2ggY29kZS4KKyAgICAgICAgLy8gRGlyZWN0IGZpZWxkIGFjY2Vzcywgb24gdGhlIG90aGVyIGhhbmQsIGlzIGZhc3QuCisgICAgICAgIGJvb2xlYW4gZmxhZ0NvbW1hOworICAgICAgICBib29sZWFuIGZsYWdNaW51czsKKyAgICAgICAgYm9vbGVhbiBmbGFnUGFyZW50aGVzaXM7CisgICAgICAgIGJvb2xlYW4gZmxhZ1BsdXM7CisgICAgICAgIGJvb2xlYW4gZmxhZ1NoYXJwOworICAgICAgICBib29sZWFuIGZsYWdTcGFjZTsKKyAgICAgICAgYm9vbGVhbiBmbGFnWmVybzsKKworICAgICAgICBwcml2YXRlIGNoYXIgY29udmVyc2lvblR5cGUgPSAoY2hhcikgVU5TRVQ7CisgICAgICAgIHByaXZhdGUgY2hhciBkYXRlU3VmZml4OworCisgICAgICAgIHByaXZhdGUgaW50IHByZWNpc2lvbiA9IFVOU0VUOworICAgICAgICBwcml2YXRlIGludCB3aWR0aCA9IFVOU0VUOworCisgICAgICAgIHByaXZhdGUgU3RyaW5nQnVpbGRlciBzdHJGbGFnczsKKworICAgICAgICAvLyBUZXN0cyB3aGV0aGVyIHRoZXJlIHdlcmUgbm8gZmxhZ3MsIG5vIHdpZHRoLCBhbmQgbm8gcHJlY2lzaW9uIHNwZWNpZmllZC4KKyAgICAgICAgYm9vbGVhbiBpc0RlZmF1bHQoKSB7CisgICAgICAgICAgICByZXR1cm4gIWZsYWdDb21tYSAmJiAhZmxhZ01pbnVzICYmICFmbGFnUGFyZW50aGVzaXMgJiYgIWZsYWdQbHVzICYmICFmbGFnU2hhcnAgJiYKKyAgICAgICAgICAgICAgICAgICAgIWZsYWdTcGFjZSAmJiAhZmxhZ1plcm8gJiYgd2lkdGggPT0gVU5TRVQgJiYgcHJlY2lzaW9uID09IFVOU0VUOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBpc1ByZWNpc2lvblNldCgpIHsKKyAgICAgICAgICAgIHJldHVybiBwcmVjaXNpb24gIT0gVU5TRVQ7CisgICAgICAgIH0KKworICAgICAgICBpbnQgZ2V0QXJnSW5kZXgoKSB7CisgICAgICAgICAgICByZXR1cm4gYXJnSW5kZXg7CisgICAgICAgIH0KKworICAgICAgICB2b2lkIHNldEFyZ0luZGV4KGludCBpbmRleCkgeworICAgICAgICAgICAgYXJnSW5kZXggPSBpbmRleDsKKyAgICAgICAgfQorCisgICAgICAgIGludCBnZXRXaWR0aCgpIHsKKyAgICAgICAgICAgIHJldHVybiB3aWR0aDsKKyAgICAgICAgfQorCisgICAgICAgIHZvaWQgc2V0V2lkdGgoaW50IHdpZHRoKSB7CisgICAgICAgICAgICB0aGlzLndpZHRoID0gd2lkdGg7CisgICAgICAgIH0KKworICAgICAgICBpbnQgZ2V0UHJlY2lzaW9uKCkgeworICAgICAgICAgICAgcmV0dXJuIHByZWNpc2lvbjsKKyAgICAgICAgfQorCisgICAgICAgIHZvaWQgc2V0UHJlY2lzaW9uKGludCBwcmVjaXNlKSB7CisgICAgICAgICAgICB0aGlzLnByZWNpc2lvbiA9IHByZWNpc2U7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgZ2V0U3RyRmxhZ3MoKSB7CisgICAgICAgICAgICByZXR1cm4gKHN0ckZsYWdzICE9IG51bGwpID8gc3RyRmxhZ3MudG9TdHJpbmcoKSA6ICIiOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogU2V0cyBxdWFsaWZpZWQgY2hhciBhcyBvbmUgb2YgdGhlIGZsYWdzLiBJZiB0aGUgY2hhciBpcyBxdWFsaWZpZWQsCisgICAgICAgICAqIHNldHMgaXQgYXMgYSBmbGFnIGFuZCByZXR1cm5zIHRydWUuIE9yIGVsc2UgcmV0dXJucyBmYWxzZS4KKyAgICAgICAgICovCisgICAgICAgIGJvb2xlYW4gc2V0RmxhZyhpbnQgY2gpIHsKKyAgICAgICAgICAgIGJvb2xlYW4gZHVwZSA9IGZhbHNlOworICAgICAgICAgICAgc3dpdGNoIChjaCkgeworICAgICAgICAgICAgY2FzZSAnLCc6CisgICAgICAgICAgICAgICAgZHVwZSA9IGZsYWdDb21tYTsKKyAgICAgICAgICAgICAgICBmbGFnQ29tbWEgPSB0cnVlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAnLSc6CisgICAgICAgICAgICAgICAgZHVwZSA9IGZsYWdNaW51czsKKyAgICAgICAgICAgICAgICBmbGFnTWludXMgPSB0cnVlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAnKCc6CisgICAgICAgICAgICAgICAgZHVwZSA9IGZsYWdQYXJlbnRoZXNpczsKKyAgICAgICAgICAgICAgICBmbGFnUGFyZW50aGVzaXMgPSB0cnVlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAnKyc6CisgICAgICAgICAgICAgICAgZHVwZSA9IGZsYWdQbHVzOworICAgICAgICAgICAgICAgIGZsYWdQbHVzID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJyMnOgorICAgICAgICAgICAgICAgIGR1cGUgPSBmbGFnU2hhcnA7CisgICAgICAgICAgICAgICAgZmxhZ1NoYXJwID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJyAnOgorICAgICAgICAgICAgICAgIGR1cGUgPSBmbGFnU3BhY2U7CisgICAgICAgICAgICAgICAgZmxhZ1NwYWNlID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJzAnOgorICAgICAgICAgICAgICAgIGR1cGUgPSBmbGFnWmVybzsKKyAgICAgICAgICAgICAgICBmbGFnWmVybyA9IHRydWU7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChkdXBlKSB7CisgICAgICAgICAgICAgICAgLy8gVGhlIFJJIGRvY3VtZW50YXRpb24gaW1wbGllcyB3ZSdyZSBzdXBwb3NlZCB0byByZXBvcnQgYWxsIHRoZSBmbGFncywgbm90IGp1c3QKKyAgICAgICAgICAgICAgICAvLyB0aGUgZmlyc3QgZHVwbGljYXRlLCBidXQgdGhlIFJJIGJlaGF2ZXMgdGhlIHNhbWUgYXMgd2UgZG8uCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IER1cGxpY2F0ZUZvcm1hdEZsYWdzRXhjZXB0aW9uKFN0cmluZy52YWx1ZU9mKGNoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc3RyRmxhZ3MgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHN0ckZsYWdzID0gbmV3IFN0cmluZ0J1aWxkZXIoNyk7IC8vIFRoZXJlIGFyZSBzZXZlbiBwb3NzaWJsZSBmbGFncy4KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHN0ckZsYWdzLmFwcGVuZCgoY2hhcikgY2gpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBjaGFyIGdldENvbnZlcnNpb25UeXBlKCkgeworICAgICAgICAgICAgcmV0dXJuIGNvbnZlcnNpb25UeXBlOworICAgICAgICB9CisKKyAgICAgICAgdm9pZCBzZXRDb252ZXJzaW9uVHlwZShjaGFyIGMpIHsKKyAgICAgICAgICAgIGNvbnZlcnNpb25UeXBlID0gYzsKKyAgICAgICAgfQorCisgICAgICAgIGNoYXIgZ2V0RGF0ZVN1ZmZpeCgpIHsKKyAgICAgICAgICAgIHJldHVybiBkYXRlU3VmZml4OworICAgICAgICB9CisKKyAgICAgICAgdm9pZCBzZXREYXRlU3VmZml4KGNoYXIgYykgeworICAgICAgICAgICAgZGF0ZVN1ZmZpeCA9IGM7CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIHJlcXVpcmVBcmd1bWVudCgpIHsKKyAgICAgICAgICAgIHJldHVybiBjb252ZXJzaW9uVHlwZSAhPSAnJScgJiYgY29udmVyc2lvblR5cGUgIT0gJ24nOworICAgICAgICB9CisKKyAgICAgICAgdm9pZCBjaGVja0ZsYWdzKE9iamVjdCBhcmcpIHsKKyAgICAgICAgICAgIC8vIFdvcmsgb3V0IHdoaWNoIGZsYWdzIGFyZSBhbGxvd2VkLgorICAgICAgICAgICAgYm9vbGVhbiBhbGxvd0NvbW1hID0gZmFsc2U7CisgICAgICAgICAgICBib29sZWFuIGFsbG93TWludXMgPSB0cnVlOworICAgICAgICAgICAgYm9vbGVhbiBhbGxvd1BhcmVudGhlc2lzID0gZmFsc2U7CisgICAgICAgICAgICBib29sZWFuIGFsbG93UGx1cyA9IGZhbHNlOworICAgICAgICAgICAgYm9vbGVhbiBhbGxvd1NoYXJwID0gZmFsc2U7CisgICAgICAgICAgICBib29sZWFuIGFsbG93U3BhY2UgPSBmYWxzZTsKKyAgICAgICAgICAgIGJvb2xlYW4gYWxsb3daZXJvID0gZmFsc2U7CisgICAgICAgICAgICAvLyBQcmVjaXNpb24gYW5kIHdpZHRoPworICAgICAgICAgICAgYm9vbGVhbiBhbGxvd1ByZWNpc2lvbiA9IHRydWU7CisgICAgICAgICAgICBib29sZWFuIGFsbG93V2lkdGggPSB0cnVlOworICAgICAgICAgICAgLy8gQXJndW1lbnQ/CisgICAgICAgICAgICBib29sZWFuIGFsbG93QXJndW1lbnQgPSB0cnVlOworICAgICAgICAgICAgc3dpdGNoIChjb252ZXJzaW9uVHlwZSkgeworICAgICAgICAgICAgLy8gQ2hhcmFjdGVyIGFuZCBkYXRlL3RpbWUuCisgICAgICAgICAgICBjYXNlICdjJzogY2FzZSAnQyc6IGNhc2UgJ3QnOiBjYXNlICdUJzoKKyAgICAgICAgICAgICAgICAvLyBPbmx5ICctJyBpcyBhbGxvd2VkLgorICAgICAgICAgICAgICAgIGFsbG93UHJlY2lzaW9uID0gZmFsc2U7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIC8vIFN0cmluZy4KKyAgICAgICAgICAgIGNhc2UgJ3MnOiBjYXNlICdTJzoKKyAgICAgICAgICAgICAgICBpZiAoYXJnIGluc3RhbmNlb2YgRm9ybWF0dGFibGUpIHsKKyAgICAgICAgICAgICAgICAgICAgYWxsb3dTaGFycCA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICAvLyBGbG9hdGluZyBwb2ludC4KKyAgICAgICAgICAgIGNhc2UgJ2cnOiBjYXNlICdHJzoKKyAgICAgICAgICAgICAgICBhbGxvd0NvbW1hID0gYWxsb3dQYXJlbnRoZXNpcyA9IGFsbG93UGx1cyA9IGFsbG93U3BhY2UgPSBhbGxvd1plcm8gPSB0cnVlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAnZic6CisgICAgICAgICAgICAgICAgYWxsb3dDb21tYSA9IGFsbG93UGFyZW50aGVzaXMgPSBhbGxvd1BsdXMgPSBhbGxvd1NoYXJwID0gYWxsb3dTcGFjZSA9IGFsbG93WmVybyA9IHRydWU7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICdlJzogY2FzZSAnRSc6CisgICAgICAgICAgICAgICAgYWxsb3dQYXJlbnRoZXNpcyA9IGFsbG93UGx1cyA9IGFsbG93U2hhcnAgPSBhbGxvd1NwYWNlID0gYWxsb3daZXJvID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJ2EnOiBjYXNlICdBJzoKKyAgICAgICAgICAgICAgICBhbGxvd1BsdXMgPSBhbGxvd1NoYXJwID0gYWxsb3dTcGFjZSA9IGFsbG93WmVybyA9IHRydWU7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIC8vIEludGVncmFsLgorICAgICAgICAgICAgY2FzZSAnZCc6CisgICAgICAgICAgICAgICAgYWxsb3dDb21tYSA9IGFsbG93UGFyZW50aGVzaXMgPSBhbGxvd1BsdXMgPSBhbGxvd1NwYWNlID0gYWxsb3daZXJvID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBhbGxvd1ByZWNpc2lvbiA9IGZhbHNlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAnbyc6IGNhc2UgJ3gnOiBjYXNlICdYJzoKKyAgICAgICAgICAgICAgICBhbGxvd1NoYXJwID0gYWxsb3daZXJvID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBpZiAoYXJnID09IG51bGwgfHwgYXJnIGluc3RhbmNlb2YgQmlnSW50ZWdlcikgeworICAgICAgICAgICAgICAgICAgICBhbGxvd1BhcmVudGhlc2lzID0gYWxsb3dQbHVzID0gYWxsb3dTcGFjZSA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFsbG93UHJlY2lzaW9uID0gZmFsc2U7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIC8vIFNwZWNpYWwuCisgICAgICAgICAgICBjYXNlICduJzoKKyAgICAgICAgICAgICAgICAvLyBOb3RoaW5nIGlzIGFsbG93ZWQuCisgICAgICAgICAgICAgICAgYWxsb3dNaW51cyA9IGZhbHNlOworICAgICAgICAgICAgICAgIGFsbG93QXJndW1lbnQgPSBhbGxvd1ByZWNpc2lvbiA9IGFsbG93V2lkdGggPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJyUnOgorICAgICAgICAgICAgICAgIC8vIFRoZSBvbmx5IGZsYWcgYWxsb3dlZCBpcyAnLScsIGFuZCBubyBhcmd1bWVudCBvciBwcmVjaXNpb24gaXMgYWxsb3dlZC4KKyAgICAgICAgICAgICAgICBhbGxvd0FyZ3VtZW50ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgYWxsb3dQcmVjaXNpb24gPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgLy8gQm9vbGVhbnMgYW5kIGhhc2ggY29kZXMuCisgICAgICAgICAgICBjYXNlICdiJzogY2FzZSAnQic6IGNhc2UgJ2gnOiBjYXNlICdIJzoKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICB0aHJvdyB1bmtub3duRm9ybWF0Q29udmVyc2lvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBDaGVjayBmb3IgZGlzYWxsb3dlZCBmbGFncy4KKyAgICAgICAgICAgIFN0cmluZyBtaXNtYXRjaCA9IG51bGw7CisgICAgICAgICAgICBpZiAoIWFsbG93Q29tbWEgJiYgZmxhZ0NvbW1hKSB7CisgICAgICAgICAgICAgICAgbWlzbWF0Y2ggPSAiLCI7CisgICAgICAgICAgICB9IGVsc2UgaWYgKCFhbGxvd01pbnVzICYmIGZsYWdNaW51cykgeworICAgICAgICAgICAgICAgIG1pc21hdGNoID0gIi0iOworICAgICAgICAgICAgfSBlbHNlIGlmICghYWxsb3dQYXJlbnRoZXNpcyAmJiBmbGFnUGFyZW50aGVzaXMpIHsKKyAgICAgICAgICAgICAgICBtaXNtYXRjaCA9ICIoIjsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIWFsbG93UGx1cyAmJiBmbGFnUGx1cykgeworICAgICAgICAgICAgICAgIG1pc21hdGNoID0gIisiOworICAgICAgICAgICAgfSBlbHNlIGlmICghYWxsb3dTaGFycCAmJiBmbGFnU2hhcnApIHsKKyAgICAgICAgICAgICAgICBtaXNtYXRjaCA9ICIjIjsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIWFsbG93U3BhY2UgJiYgZmxhZ1NwYWNlKSB7CisgICAgICAgICAgICAgICAgbWlzbWF0Y2ggPSAiICI7CisgICAgICAgICAgICB9IGVsc2UgaWYgKCFhbGxvd1plcm8gJiYgZmxhZ1plcm8pIHsKKyAgICAgICAgICAgICAgICBtaXNtYXRjaCA9ICIwIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChtaXNtYXRjaCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWYgKGNvbnZlcnNpb25UeXBlID09ICduJykgeworICAgICAgICAgICAgICAgICAgICAvLyBGb3Igbm8gZ29vZCByZWFzb24sICVuIGlzIGEgc3BlY2lhbCBjYXNlLi4uCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsRm9ybWF0RmxhZ3NFeGNlcHRpb24obWlzbWF0Y2gpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBGb3JtYXRGbGFnc0NvbnZlcnNpb25NaXNtYXRjaEV4Y2VwdGlvbihtaXNtYXRjaCwgY29udmVyc2lvblR5cGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGEgbWlzc2luZyB3aWR0aCB3aXRoIGZsYWdzIHRoYXQgcmVxdWlyZSBhIHdpZHRoLgorICAgICAgICAgICAgaWYgKChmbGFnTWludXMgfHwgZmxhZ1plcm8pICYmIHdpZHRoID09IFVOU0VUKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1pc3NpbmdGb3JtYXRXaWR0aEV4Y2VwdGlvbigiLSIgKyBjb252ZXJzaW9uVHlwZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgbm8tYXJndW1lbnQgY29udmVyc2lvbiB0eXBlcyBkb24ndCBoYXZlIGFuIGFyZ3VtZW50LgorICAgICAgICAgICAgLy8gTm90ZTogdGhlIFJJIGRvZXNuJ3QgZW5mb3JjZSB0aGlzLgorICAgICAgICAgICAgaWYgKCFhbGxvd0FyZ3VtZW50ICYmIGFyZ0luZGV4ICE9IFVOU0VUKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxGb3JtYXRGbGFnc0V4Y2VwdGlvbigiJSIgKyBjb252ZXJzaW9uVHlwZSArCisgICAgICAgICAgICAgICAgICAgICAgICAiIGRvZXNuJ3QgdGFrZSBhbiBhcmd1bWVudCIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBDaGVjayB0aGF0IHdlIGRvbid0IGhhdmUgYSBwcmVjaXNpb24gb3Igd2lkdGggd2hlcmUgdGhleSdyZSBub3QgYWxsb3dlZC4KKyAgICAgICAgICAgIGlmICghYWxsb3dQcmVjaXNpb24gJiYgcHJlY2lzaW9uICE9IFVOU0VUKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxGb3JtYXRQcmVjaXNpb25FeGNlcHRpb24ocHJlY2lzaW9uKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghYWxsb3dXaWR0aCAmJiB3aWR0aCAhPSBVTlNFVCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsRm9ybWF0V2lkdGhFeGNlcHRpb24od2lkdGgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBTb21lIGNvbWJpbmF0aW9ucyBtYWtlIG5vIHNlbnNlLi4uCisgICAgICAgICAgICBpZiAoZmxhZ1BsdXMgJiYgZmxhZ1NwYWNlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxGb3JtYXRGbGFnc0V4Y2VwdGlvbigidGhlICcrJyBhbmQgJyAnIGZsYWdzIGFyZSBpbmNvbXBhdGlibGUiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChmbGFnTWludXMgJiYgZmxhZ1plcm8pIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEZvcm1hdEZsYWdzRXhjZXB0aW9uKCJ0aGUgJy0nIGFuZCAnMCcgZmxhZ3MgYXJlIGluY29tcGF0aWJsZSIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFVua25vd25Gb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9uIHVua25vd25Gb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9uKCkgeworICAgICAgICAgICAgaWYgKGNvbnZlcnNpb25UeXBlID09ICd0JyB8fCBjb252ZXJzaW9uVHlwZSA9PSAnVCcpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5rbm93bkZvcm1hdENvbnZlcnNpb25FeGNlcHRpb24oU3RyaW5nLmZvcm1hdCgiJWMlYyIsCisgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJzaW9uVHlwZSwgZGF0ZVN1ZmZpeCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IFVua25vd25Gb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9uKFN0cmluZy52YWx1ZU9mKGNvbnZlcnNpb25UeXBlKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIEdldHMgdGhlIGZvcm1hdHRlZCBzdHJpbmcgYWNjb3JkaW5nIHRvIHRoZSBmb3JtYXQgdG9rZW4gYW5kIHRoZQorICAgICAqIGFyZ3VtZW50LgorICAgICAqLworICAgIHByaXZhdGUgQ2hhclNlcXVlbmNlIHRyYW5zZm9ybShGb3JtYXRUb2tlbiB0b2tlbiwgT2JqZWN0IGFyZ3VtZW50KSB7CisgICAgICAgIHRoaXMuZm9ybWF0VG9rZW4gPSB0b2tlbjsKKyAgICAgICAgdGhpcy5hcmcgPSBhcmd1bWVudDsKKworICAgICAgICAvLyBUaGVyZSBhcmUgb25seSB0d28gZm9ybWF0IHNwZWNpZmllcnMgdGhhdCBtYXR0ZXI6ICIlZCIgYW5kICIlcyIuCisgICAgICAgIC8vIE5vdGhpbmcgZWxzZSBpcyBjb21tb24gaW4gdGhlIHdpbGQuIFdlIGZhc3QtcGF0aCB0aGVzZSB0d28gdG8KKyAgICAgICAgLy8gYXZvaWQgdGhlIGhlYXZ5d2VpZ2h0IG1hY2hpbmVyeSBuZWVkZWQgdG8gY29wZSB3aXRoIGZsYWdzLCB3aWR0aCwKKyAgICAgICAgLy8gYW5kIHByZWNpc2lvbi4KKyAgICAgICAgaWYgKHRva2VuLmlzRGVmYXVsdCgpKSB7CisgICAgICAgICAgICBzd2l0Y2ggKHRva2VuLmdldENvbnZlcnNpb25UeXBlKCkpIHsKKyAgICAgICAgICAgIGNhc2UgJ3MnOgorICAgICAgICAgICAgICAgIGlmIChhcmcgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gIm51bGwiOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIShhcmcgaW5zdGFuY2VvZiBGb3JtYXR0YWJsZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFyZy50b1N0cmluZygpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJ2QnOgorICAgICAgICAgICAgICAgIGJvb2xlYW4gbmVlZExvY2FsaXplZERpZ2l0cyA9IChsb2NhbGVEYXRhLnplcm9EaWdpdCAhPSAnMCcpOworICAgICAgICAgICAgICAgIGlmIChvdXQgaW5zdGFuY2VvZiBTdHJpbmdCdWlsZGVyICYmICFuZWVkTG9jYWxpemVkRGlnaXRzKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChhcmcgaW5zdGFuY2VvZiBJbnRlZ2VyIHx8IGFyZyBpbnN0YW5jZW9mIFNob3J0IHx8IGFyZyBpbnN0YW5jZW9mIEJ5dGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIEludGVncmFsVG9TdHJpbmcuYXBwZW5kSW50KChTdHJpbmdCdWlsZGVyKSBvdXQsICgoTnVtYmVyKSBhcmcpLmludFZhbHVlKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJnIGluc3RhbmNlb2YgTG9uZykgeworICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdyYWxUb1N0cmluZy5hcHBlbmRMb25nKChTdHJpbmdCdWlsZGVyKSBvdXQsICgoTG9uZykgYXJnKS5sb25nVmFsdWUoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoYXJnIGluc3RhbmNlb2YgSW50ZWdlciB8fCBhcmcgaW5zdGFuY2VvZiBMb25nIHx8IGFyZyBpbnN0YW5jZW9mIFNob3J0IHx8IGFyZyBpbnN0YW5jZW9mIEJ5dGUpIHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGFyZy50b1N0cmluZygpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmVlZExvY2FsaXplZERpZ2l0cyA/IGxvY2FsaXplRGlnaXRzKHJlc3VsdCkgOiByZXN1bHQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9ybWF0VG9rZW4uY2hlY2tGbGFncyhhcmcpOworICAgICAgICBDaGFyU2VxdWVuY2UgcmVzdWx0OworICAgICAgICBzd2l0Y2ggKHRva2VuLmdldENvbnZlcnNpb25UeXBlKCkpIHsKKyAgICAgICAgY2FzZSAnQic6IGNhc2UgJ2InOgorICAgICAgICAgICAgcmVzdWx0ID0gdHJhbnNmb3JtRnJvbUJvb2xlYW4oKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlICdIJzogY2FzZSAnaCc6CisgICAgICAgICAgICByZXN1bHQgPSB0cmFuc2Zvcm1Gcm9tSGFzaENvZGUoKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlICdTJzogY2FzZSAncyc6CisgICAgICAgICAgICByZXN1bHQgPSB0cmFuc2Zvcm1Gcm9tU3RyaW5nKCk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAnQyc6IGNhc2UgJ2MnOgorICAgICAgICAgICAgcmVzdWx0ID0gdHJhbnNmb3JtRnJvbUNoYXJhY3RlcigpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ2QnOiBjYXNlICdvJzogY2FzZSAneCc6IGNhc2UgJ1gnOgorICAgICAgICAgICAgaWYgKGFyZyA9PSBudWxsIHx8IGFyZyBpbnN0YW5jZW9mIEJpZ0ludGVnZXIpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSB0cmFuc2Zvcm1Gcm9tQmlnSW50ZWdlcigpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSB0cmFuc2Zvcm1Gcm9tSW50ZWdlcigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ0EnOiBjYXNlICdhJzogY2FzZSAnRSc6IGNhc2UgJ2UnOiBjYXNlICdmJzogY2FzZSAnRyc6IGNhc2UgJ2cnOgorICAgICAgICAgICAgcmVzdWx0ID0gdHJhbnNmb3JtRnJvbUZsb2F0KCk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAnJSc6CisgICAgICAgICAgICByZXN1bHQgPSB0cmFuc2Zvcm1Gcm9tUGVyY2VudCgpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ24nOgorICAgICAgICAgICAgcmVzdWx0ID0gU3lzdGVtLmxpbmVTZXBhcmF0b3IoKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlICd0JzogY2FzZSAnVCc6CisgICAgICAgICAgICByZXN1bHQgPSB0cmFuc2Zvcm1Gcm9tRGF0ZVRpbWUoKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgdGhyb3cgdG9rZW4udW5rbm93bkZvcm1hdENvbnZlcnNpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChDaGFyYWN0ZXIuaXNVcHBlckNhc2UodG9rZW4uZ2V0Q29udmVyc2lvblR5cGUoKSkpIHsKKyAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC50b1N0cmluZygpLnRvVXBwZXJDYXNlKGxvY2FsZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIElsbGVnYWxGb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9uIGJhZEFyZ3VtZW50VHlwZSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxGb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9uKGZvcm1hdFRva2VuLmdldENvbnZlcnNpb25UeXBlKCksIGFyZy5nZXRDbGFzcygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgQ2hhclNlcXVlbmNlIGNvcnJlc3BvbmRpbmcgdG8ge0Bjb2RlIHN9IHdpdGggYWxsIHRoZSBBU0NJSSBkaWdpdHMgcmVwbGFjZWQKKyAgICAgKiBieSBkaWdpdHMgYXBwcm9wcmlhdGUgdG8gdGhpcyBmb3JtYXR0ZXIncyBsb2NhbGUuIE90aGVyIGNoYXJhY3RlcnMgcmVtYWluIHVuY2hhbmdlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIENoYXJTZXF1ZW5jZSBsb2NhbGl6ZURpZ2l0cyhDaGFyU2VxdWVuY2UgcykgeworICAgICAgICBpbnQgbGVuZ3RoID0gcy5sZW5ndGgoKTsKKyAgICAgICAgaW50IG9mZnNldFRvTG9jYWxpemVkRGlnaXRzID0gbG9jYWxlRGF0YS56ZXJvRGlnaXQgLSAnMCc7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIobGVuZ3RoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgeworICAgICAgICAgICAgY2hhciBjaCA9IHMuY2hhckF0KGkpOworICAgICAgICAgICAgaWYgKGNoID49ICcwJyAmJiBjaCA8PSAnOScpIHsKKyAgICAgICAgICAgICAgICBjaCArPSBvZmZzZXRUb0xvY2FsaXplZERpZ2l0czsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoY2gpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgZ3JvdXBpbmcgc2VwYXJhdG9yIGV2ZXJ5IDMgZGlnaXRzLiBEZWNpbWFsRm9ybWF0IGxldHMgeW91IGNvbmZpZ3VyZSBncm91cGluZworICAgICAqIHNpemUsIGJ1dCB5b3UgY2FuJ3QgYWNjZXNzIHRoYXQgZnJvbSBGb3JtYXR0ZXIsIGFuZCB0aGUgZGVmYXVsdCBpcyBldmVyeSAzIGRpZ2l0cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIENoYXJTZXF1ZW5jZSBpbnNlcnRHcm91cGluZyhDaGFyU2VxdWVuY2UgcykgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKHMubGVuZ3RoKCkgKyBzLmxlbmd0aCgpLzMpOworCisgICAgICAgIC8vIEEgbGVhZGluZyAnLScgZG9lc24ndCB3YW50IHRvIGJlIGluY2x1ZGVkIGluIHRoZSBncm91cGluZy4KKyAgICAgICAgaW50IGRpZ2l0c0xlbmd0aCA9IHMubGVuZ3RoKCk7CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgaWYgKHMuY2hhckF0KDApID09ICctJykgeworICAgICAgICAgICAgLS1kaWdpdHNMZW5ndGg7CisgICAgICAgICAgICArK2k7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCctJyk7CisgICAgICAgIH0KKworICAgICAgICAvLyBBcHBlbmQgdGhlIGRpZ2l0cyB0aGF0IGNvbWUgYmVmb3JlIHRoZSBmaXJzdCBzZXBhcmF0b3IuCisgICAgICAgIGludCBoZWFkTGVuZ3RoID0gZGlnaXRzTGVuZ3RoICUgMzsKKyAgICAgICAgaWYgKGhlYWRMZW5ndGggPT0gMCkgeworICAgICAgICAgICAgaGVhZExlbmd0aCA9IDM7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0LmFwcGVuZChzLCBpLCBpICsgaGVhZExlbmd0aCk7CisgICAgICAgIGkgKz0gaGVhZExlbmd0aDsKKworICAgICAgICAvLyBBcHBlbmQgdGhlIHJlbWFpbmluZyBncm91cHMuCisgICAgICAgIGZvciAoOyBpIDwgcy5sZW5ndGgoKTsgaSArPSAzKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGxvY2FsZURhdGEuZ3JvdXBpbmdTZXBhcmF0b3IpOworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChzLCBpLCBpICsgMyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIENoYXJTZXF1ZW5jZSB0cmFuc2Zvcm1Gcm9tQm9vbGVhbigpIHsKKyAgICAgICAgQ2hhclNlcXVlbmNlIHJlc3VsdDsKKyAgICAgICAgaWYgKGFyZyBpbnN0YW5jZW9mIEJvb2xlYW4pIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IGFyZy50b1N0cmluZygpOworICAgICAgICB9IGVsc2UgaWYgKGFyZyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXN1bHQgPSAiZmFsc2UiOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmVzdWx0ID0gInRydWUiOworICAgICAgICB9CisgICAgICAgIHJldHVybiBwYWRkaW5nKHJlc3VsdCwgMCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBDaGFyU2VxdWVuY2UgdHJhbnNmb3JtRnJvbUhhc2hDb2RlKCkgeworICAgICAgICBDaGFyU2VxdWVuY2UgcmVzdWx0OworICAgICAgICBpZiAoYXJnID09IG51bGwpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9ICJudWxsIjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IEludGVnZXIudG9IZXhTdHJpbmcoYXJnLmhhc2hDb2RlKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBwYWRkaW5nKHJlc3VsdCwgMCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBDaGFyU2VxdWVuY2UgdHJhbnNmb3JtRnJvbVN0cmluZygpIHsKKyAgICAgICAgaWYgKGFyZyBpbnN0YW5jZW9mIEZvcm1hdHRhYmxlKSB7CisgICAgICAgICAgICBpbnQgZmxhZ3MgPSAwOworICAgICAgICAgICAgaWYgKGZvcm1hdFRva2VuLmZsYWdNaW51cykgeworICAgICAgICAgICAgICAgIGZsYWdzIHw9IEZvcm1hdHRhYmxlRmxhZ3MuTEVGVF9KVVNUSUZZOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGZvcm1hdFRva2VuLmZsYWdTaGFycCkgeworICAgICAgICAgICAgICAgIGZsYWdzIHw9IEZvcm1hdHRhYmxlRmxhZ3MuQUxURVJOQVRFOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKENoYXJhY3Rlci5pc1VwcGVyQ2FzZShmb3JtYXRUb2tlbi5nZXRDb252ZXJzaW9uVHlwZSgpKSkgeworICAgICAgICAgICAgICAgIGZsYWdzIHw9IEZvcm1hdHRhYmxlRmxhZ3MuVVBQRVJDQVNFOworICAgICAgICAgICAgfQorICAgICAgICAgICAgKChGb3JtYXR0YWJsZSkgYXJnKS5mb3JtYXRUbyh0aGlzLCBmbGFncywgZm9ybWF0VG9rZW4uZ2V0V2lkdGgoKSwKKyAgICAgICAgICAgICAgICAgICAgZm9ybWF0VG9rZW4uZ2V0UHJlY2lzaW9uKCkpOworICAgICAgICAgICAgLy8gYWxsIGFjdGlvbnMgaGF2ZSBiZWVuIHRha2VuIG91dCBpbiB0aGUKKyAgICAgICAgICAgIC8vIEZvcm1hdHRhYmxlLmZvcm1hdFRvLCB0aHVzIHRoZXJlIGlzIG5vdGhpbmcgdG8gZG8sIGp1c3QKKyAgICAgICAgICAgIC8vIHJldHVybnMgbnVsbCwgd2hpY2ggdGVsbHMgdGhlIFBhcnNlciB0byBhZGQgbm90aGluZyB0byB0aGUKKyAgICAgICAgICAgIC8vIG91dHB1dC4KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIENoYXJTZXF1ZW5jZSByZXN1bHQgPSBhcmcgIT0gbnVsbCA/IGFyZy50b1N0cmluZygpIDogIm51bGwiOworICAgICAgICByZXR1cm4gcGFkZGluZyhyZXN1bHQsIDApOworICAgIH0KKworICAgIHByaXZhdGUgQ2hhclNlcXVlbmNlIHRyYW5zZm9ybUZyb21DaGFyYWN0ZXIoKSB7CisgICAgICAgIGlmIChhcmcgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHBhZGRpbmcoIm51bGwiLCAwKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYXJnIGluc3RhbmNlb2YgQ2hhcmFjdGVyKSB7CisgICAgICAgICAgICByZXR1cm4gcGFkZGluZyhTdHJpbmcudmFsdWVPZihhcmcpLCAwKTsKKyAgICAgICAgfSBlbHNlIGlmIChhcmcgaW5zdGFuY2VvZiBCeXRlIHx8IGFyZyBpbnN0YW5jZW9mIFNob3J0IHx8IGFyZyBpbnN0YW5jZW9mIEludGVnZXIpIHsKKyAgICAgICAgICAgIGludCBjb2RlUG9pbnQgPSAoKE51bWJlcikgYXJnKS5pbnRWYWx1ZSgpOworICAgICAgICAgICAgaWYgKCFDaGFyYWN0ZXIuaXNWYWxpZENvZGVQb2ludChjb2RlUG9pbnQpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxGb3JtYXRDb2RlUG9pbnRFeGNlcHRpb24oY29kZVBvaW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIENoYXJTZXF1ZW5jZSByZXN1bHQgPSAoY29kZVBvaW50IDwgQ2hhcmFjdGVyLk1JTl9TVVBQTEVNRU5UQVJZX0NPREVfUE9JTlQpCisgICAgICAgICAgICAgICAgICAgID8gU3RyaW5nLnZhbHVlT2YoKGNoYXIpIGNvZGVQb2ludCkKKyAgICAgICAgICAgICAgICAgICAgOiBTdHJpbmcudmFsdWVPZihDaGFyYWN0ZXIudG9DaGFycyhjb2RlUG9pbnQpKTsKKyAgICAgICAgICAgIHJldHVybiBwYWRkaW5nKHJlc3VsdCwgMCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBiYWRBcmd1bWVudFR5cGUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgQ2hhclNlcXVlbmNlIHRyYW5zZm9ybUZyb21QZXJjZW50KCkgeworICAgICAgICByZXR1cm4gcGFkZGluZygiJSIsIDApOworICAgIH0KKworICAgIHByaXZhdGUgQ2hhclNlcXVlbmNlIHBhZGRpbmcoQ2hhclNlcXVlbmNlIHNvdXJjZSwgaW50IHN0YXJ0SW5kZXgpIHsKKyAgICAgICAgaW50IHN0YXJ0ID0gc3RhcnRJbmRleDsKKyAgICAgICAgaW50IHdpZHRoID0gZm9ybWF0VG9rZW4uZ2V0V2lkdGgoKTsKKyAgICAgICAgaW50IHByZWNpc2lvbiA9IGZvcm1hdFRva2VuLmdldFByZWNpc2lvbigpOworCisgICAgICAgIGludCBsZW5ndGggPSBzb3VyY2UubGVuZ3RoKCk7CisgICAgICAgIGlmIChwcmVjaXNpb24gPj0gMCkgeworICAgICAgICAgICAgbGVuZ3RoID0gTWF0aC5taW4obGVuZ3RoLCBwcmVjaXNpb24pOworICAgICAgICAgICAgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIFN0cmluZ0J1aWxkZXIpIHsKKyAgICAgICAgICAgICAgICAoKFN0cmluZ0J1aWxkZXIpIHNvdXJjZSkuc2V0TGVuZ3RoKGxlbmd0aCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHNvdXJjZSA9IHNvdXJjZS5zdWJTZXF1ZW5jZSgwLCBsZW5ndGgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmICh3aWR0aCA+IDApIHsKKyAgICAgICAgICAgIHdpZHRoID0gTWF0aC5tYXgoc291cmNlLmxlbmd0aCgpLCB3aWR0aCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxlbmd0aCA+PSB3aWR0aCkgeworICAgICAgICAgICAgcmV0dXJuIHNvdXJjZTsKKyAgICAgICAgfQorCisgICAgICAgIGNoYXIgcGFkZGluZ0NoYXIgPSAnXHUwMDIwJzsgLy8gc3BhY2UgYXMgcGFkZGluZyBjaGFyLgorICAgICAgICBpZiAoZm9ybWF0VG9rZW4uZmxhZ1plcm8pIHsKKyAgICAgICAgICAgIGlmIChmb3JtYXRUb2tlbi5nZXRDb252ZXJzaW9uVHlwZSgpID09ICdkJykgeworICAgICAgICAgICAgICAgIHBhZGRpbmdDaGFyID0gbG9jYWxlRGF0YS56ZXJvRGlnaXQ7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHBhZGRpbmdDaGFyID0gJzAnOyAvLyBObyBsb2NhbGl6ZWQgZGlnaXRzIGZvciBiYXNlcyBvdGhlciB0aGFuIGRlY2ltYWwuCisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBpZiBwYWRkaW5nIGNoYXIgaXMgc3BhY2UsIGFsd2F5cyBwYWQgZnJvbSB0aGUgc3RhcnQuCisgICAgICAgICAgICBzdGFydCA9IDA7CisgICAgICAgIH0KKyAgICAgICAgY2hhcltdIHBhZGRpbmdDaGFycyA9IG5ldyBjaGFyW3dpZHRoIC0gbGVuZ3RoXTsKKyAgICAgICAgQXJyYXlzLmZpbGwocGFkZGluZ0NoYXJzLCBwYWRkaW5nQ2hhcik7CisKKyAgICAgICAgYm9vbGVhbiBwYWRkaW5nUmlnaHQgPSBmb3JtYXRUb2tlbi5mbGFnTWludXM7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gdG9TdHJpbmdCdWlsZGVyKHNvdXJjZSk7CisgICAgICAgIGlmIChwYWRkaW5nUmlnaHQpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQocGFkZGluZ0NoYXJzKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlc3VsdC5pbnNlcnQoc3RhcnQsIHBhZGRpbmdDaGFycyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZ0J1aWxkZXIgdG9TdHJpbmdCdWlsZGVyKENoYXJTZXF1ZW5jZSBjcykgeworICAgICAgICByZXR1cm4gY3MgaW5zdGFuY2VvZiBTdHJpbmdCdWlsZGVyID8gKFN0cmluZ0J1aWxkZXIpIGNzIDogbmV3IFN0cmluZ0J1aWxkZXIoY3MpOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nQnVpbGRlciB3cmFwUGFyZW50aGVzZXMoU3RyaW5nQnVpbGRlciByZXN1bHQpIHsKKyAgICAgICAgcmVzdWx0LnNldENoYXJBdCgwLCAnKCcpOyAvLyBSZXBsYWNlIHRoZSAnLScuCisgICAgICAgIGlmIChmb3JtYXRUb2tlbi5mbGFnWmVybykgeworICAgICAgICAgICAgZm9ybWF0VG9rZW4uc2V0V2lkdGgoZm9ybWF0VG9rZW4uZ2V0V2lkdGgoKSAtIDEpOworICAgICAgICAgICAgcmVzdWx0ID0gKFN0cmluZ0J1aWxkZXIpIHBhZGRpbmcocmVzdWx0LCAxKTsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJyknKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJyknKTsKKyAgICAgICAgICAgIHJlc3VsdCA9IChTdHJpbmdCdWlsZGVyKSBwYWRkaW5nKHJlc3VsdCwgMCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIENoYXJTZXF1ZW5jZSB0cmFuc2Zvcm1Gcm9tSW50ZWdlcigpIHsKKyAgICAgICAgaW50IHN0YXJ0SW5kZXggPSAwOworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGNoYXIgY3VycmVudENvbnZlcnNpb25UeXBlID0gZm9ybWF0VG9rZW4uZ2V0Q29udmVyc2lvblR5cGUoKTsKKworICAgICAgICBsb25nIHZhbHVlOworICAgICAgICBpZiAoYXJnIGluc3RhbmNlb2YgTG9uZykgeworICAgICAgICAgICAgdmFsdWUgPSAoKExvbmcpIGFyZykubG9uZ1ZhbHVlKCk7CisgICAgICAgIH0gZWxzZSBpZiAoYXJnIGluc3RhbmNlb2YgSW50ZWdlcikgeworICAgICAgICAgICAgdmFsdWUgPSAoKEludGVnZXIpIGFyZykubG9uZ1ZhbHVlKCk7CisgICAgICAgIH0gZWxzZSBpZiAoYXJnIGluc3RhbmNlb2YgU2hvcnQpIHsKKyAgICAgICAgICAgIHZhbHVlID0gKChTaG9ydCkgYXJnKS5sb25nVmFsdWUoKTsKKyAgICAgICAgfSBlbHNlIGlmIChhcmcgaW5zdGFuY2VvZiBCeXRlKSB7CisgICAgICAgICAgICB2YWx1ZSA9ICgoQnl0ZSkgYXJnKS5sb25nVmFsdWUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IGJhZEFyZ3VtZW50VHlwZSgpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGZvcm1hdFRva2VuLmZsYWdTaGFycCkgeworICAgICAgICAgICAgaWYgKGN1cnJlbnRDb252ZXJzaW9uVHlwZSA9PSAnbycpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCIwIik7CisgICAgICAgICAgICAgICAgc3RhcnRJbmRleCArPSAxOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCIweCIpOworICAgICAgICAgICAgICAgIHN0YXJ0SW5kZXggKz0gMjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChjdXJyZW50Q29udmVyc2lvblR5cGUgPT0gJ2QnKSB7CisgICAgICAgICAgICBDaGFyU2VxdWVuY2UgZGlnaXRzID0gTG9uZy50b1N0cmluZyh2YWx1ZSk7CisgICAgICAgICAgICBpZiAoZm9ybWF0VG9rZW4uZmxhZ0NvbW1hKSB7CisgICAgICAgICAgICAgICAgZGlnaXRzID0gaW5zZXJ0R3JvdXBpbmcoZGlnaXRzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChsb2NhbGVEYXRhLnplcm9EaWdpdCAhPSAnMCcpIHsKKyAgICAgICAgICAgICAgICBkaWdpdHMgPSBsb2NhbGl6ZURpZ2l0cyhkaWdpdHMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChkaWdpdHMpOworCisgICAgICAgICAgICBpZiAodmFsdWUgPCAwKSB7CisgICAgICAgICAgICAgICAgaWYgKGZvcm1hdFRva2VuLmZsYWdQYXJlbnRoZXNpcykgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gd3JhcFBhcmVudGhlc2VzKHJlc3VsdCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChmb3JtYXRUb2tlbi5mbGFnWmVybykgeworICAgICAgICAgICAgICAgICAgICBzdGFydEluZGV4Kys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAoZm9ybWF0VG9rZW4uZmxhZ1BsdXMpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0Lmluc2VydCgwLCAnKycpOworICAgICAgICAgICAgICAgICAgICBzdGFydEluZGV4ICs9IDE7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChmb3JtYXRUb2tlbi5mbGFnU3BhY2UpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0Lmluc2VydCgwLCAnICcpOworICAgICAgICAgICAgICAgICAgICBzdGFydEluZGV4ICs9IDE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gVW5kbyBzaWduLWV4dGVuc2lvbiwgc2luY2Ugd2UnbGwgYmUgdXNpbmcgTG9uZy50byhPY3RhbHxIZXgpU3RyaW5nLgorICAgICAgICAgICAgaWYgKGFyZyBpbnN0YW5jZW9mIEJ5dGUpIHsKKyAgICAgICAgICAgICAgICB2YWx1ZSAmPSAweGZmTDsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJnIGluc3RhbmNlb2YgU2hvcnQpIHsKKyAgICAgICAgICAgICAgICB2YWx1ZSAmPSAweGZmZmZMOworICAgICAgICAgICAgfSBlbHNlIGlmIChhcmcgaW5zdGFuY2VvZiBJbnRlZ2VyKSB7CisgICAgICAgICAgICAgICAgdmFsdWUgJj0gMHhmZmZmZmZmZkw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY3VycmVudENvbnZlcnNpb25UeXBlID09ICdvJykgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoTG9uZy50b09jdGFsU3RyaW5nKHZhbHVlKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoTG9uZy50b0hleFN0cmluZyh2YWx1ZSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHBhZGRpbmcocmVzdWx0LCBzdGFydEluZGV4KTsKKyAgICB9CisKKyAgICBwcml2YXRlIENoYXJTZXF1ZW5jZSB0cmFuc2Zvcm1Gcm9tTnVsbCgpIHsKKyAgICAgICAgZm9ybWF0VG9rZW4uZmxhZ1plcm8gPSBmYWxzZTsKKyAgICAgICAgcmV0dXJuIHBhZGRpbmcoIm51bGwiLCAwKTsKKyAgICB9CisKKyAgICBwcml2YXRlIENoYXJTZXF1ZW5jZSB0cmFuc2Zvcm1Gcm9tQmlnSW50ZWdlcigpIHsKKyAgICAgICAgaW50IHN0YXJ0SW5kZXggPSAwOworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIEJpZ0ludGVnZXIgYmlnSW50ID0gKEJpZ0ludGVnZXIpIGFyZzsKKyAgICAgICAgY2hhciBjdXJyZW50Q29udmVyc2lvblR5cGUgPSBmb3JtYXRUb2tlbi5nZXRDb252ZXJzaW9uVHlwZSgpOworCisgICAgICAgIGlmIChiaWdJbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybUZyb21OdWxsKCk7CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIGlzTmVnYXRpdmUgPSAoYmlnSW50LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pIDwgMCk7CisKKyAgICAgICAgaWYgKGN1cnJlbnRDb252ZXJzaW9uVHlwZSA9PSAnZCcpIHsKKyAgICAgICAgICAgIENoYXJTZXF1ZW5jZSBkaWdpdHMgPSBiaWdJbnQudG9TdHJpbmcoMTApOworICAgICAgICAgICAgaWYgKGZvcm1hdFRva2VuLmZsYWdDb21tYSkgeworICAgICAgICAgICAgICAgIGRpZ2l0cyA9IGluc2VydEdyb3VwaW5nKGRpZ2l0cyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGRpZ2l0cyk7CisgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudENvbnZlcnNpb25UeXBlID09ICdvJykgeworICAgICAgICAgICAgLy8gY29udmVydCBCaWdJbnRlZ2VyIHRvIGEgc3RyaW5nIHByZXNlbnRhdGlvbiB1c2luZyByYWRpeCA4CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGJpZ0ludC50b1N0cmluZyg4KSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBjb252ZXJ0IEJpZ0ludGVnZXIgdG8gYSBzdHJpbmcgcHJlc2VudGF0aW9uIHVzaW5nIHJhZGl4IDE2CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGJpZ0ludC50b1N0cmluZygxNikpOworICAgICAgICB9CisgICAgICAgIGlmIChmb3JtYXRUb2tlbi5mbGFnU2hhcnApIHsKKyAgICAgICAgICAgIHN0YXJ0SW5kZXggPSBpc05lZ2F0aXZlID8gMSA6IDA7CisgICAgICAgICAgICBpZiAoY3VycmVudENvbnZlcnNpb25UeXBlID09ICdvJykgeworICAgICAgICAgICAgICAgIHJlc3VsdC5pbnNlcnQoc3RhcnRJbmRleCwgIjAiKTsKKyAgICAgICAgICAgICAgICBzdGFydEluZGV4ICs9IDE7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnRDb252ZXJzaW9uVHlwZSA9PSAneCcgfHwgY3VycmVudENvbnZlcnNpb25UeXBlID09ICdYJykgeworICAgICAgICAgICAgICAgIHJlc3VsdC5pbnNlcnQoc3RhcnRJbmRleCwgIjB4Iik7CisgICAgICAgICAgICAgICAgc3RhcnRJbmRleCArPSAyOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKCFpc05lZ2F0aXZlKSB7CisgICAgICAgICAgICBpZiAoZm9ybWF0VG9rZW4uZmxhZ1BsdXMpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuaW5zZXJ0KDAsICcrJyk7CisgICAgICAgICAgICAgICAgc3RhcnRJbmRleCArPSAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGZvcm1hdFRva2VuLmZsYWdTcGFjZSkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5pbnNlcnQoMCwgJyAnKTsKKyAgICAgICAgICAgICAgICBzdGFydEluZGV4ICs9IDE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKiBwYWQgcGFkZGluZ0NoYXIgdG8gdGhlIG91dHB1dCAqLworICAgICAgICBpZiAoaXNOZWdhdGl2ZSAmJiBmb3JtYXRUb2tlbi5mbGFnUGFyZW50aGVzaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB3cmFwUGFyZW50aGVzZXMocmVzdWx0KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaXNOZWdhdGl2ZSAmJiBmb3JtYXRUb2tlbi5mbGFnWmVybykgeworICAgICAgICAgICAgc3RhcnRJbmRleCsrOworICAgICAgICB9CisgICAgICAgIHJldHVybiBwYWRkaW5nKHJlc3VsdCwgc3RhcnRJbmRleCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBDaGFyU2VxdWVuY2UgdHJhbnNmb3JtRnJvbURhdGVUaW1lKCkgeworICAgICAgICBpZiAoYXJnID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1Gcm9tTnVsbCgpOworICAgICAgICB9CisKKyAgICAgICAgQ2FsZW5kYXIgY2FsZW5kYXI7CisgICAgICAgIGlmIChhcmcgaW5zdGFuY2VvZiBDYWxlbmRhcikgeworICAgICAgICAgICAgY2FsZW5kYXIgPSAoQ2FsZW5kYXIpIGFyZzsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIERhdGUgZGF0ZSA9IG51bGw7CisgICAgICAgICAgICBpZiAoYXJnIGluc3RhbmNlb2YgTG9uZykgeworICAgICAgICAgICAgICAgIGRhdGUgPSBuZXcgRGF0ZSgoKExvbmcpIGFyZykubG9uZ1ZhbHVlKCkpOworICAgICAgICAgICAgfSBlbHNlIGlmIChhcmcgaW5zdGFuY2VvZiBEYXRlKSB7CisgICAgICAgICAgICAgICAgZGF0ZSA9IChEYXRlKSBhcmc7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRocm93IGJhZEFyZ3VtZW50VHlwZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2FsZW5kYXIgPSBDYWxlbmRhci5nZXRJbnN0YW5jZShsb2NhbGUpOworICAgICAgICAgICAgY2FsZW5kYXIuc2V0VGltZShkYXRlKTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgaWYgKCFhcHBlbmRUKHJlc3VsdCwgZm9ybWF0VG9rZW4uZ2V0RGF0ZVN1ZmZpeCgpLCBjYWxlbmRhcikpIHsKKyAgICAgICAgICAgIHRocm93IGZvcm1hdFRva2VuLnVua25vd25Gb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHBhZGRpbmcocmVzdWx0LCAwKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gYXBwZW5kVChTdHJpbmdCdWlsZGVyIHJlc3VsdCwgY2hhciBjb252ZXJzaW9uLCBDYWxlbmRhciBjYWxlbmRhcikgeworICAgICAgICBzd2l0Y2ggKGNvbnZlcnNpb24pIHsKKyAgICAgICAgY2FzZSAnQSc6CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGxvY2FsZURhdGEubG9uZ1dlZWtkYXlOYW1lc1tjYWxlbmRhci5nZXQoQ2FsZW5kYXIuREFZX09GX1dFRUspXSk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSAnYSc6CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGxvY2FsZURhdGEuc2hvcnRXZWVrZGF5TmFtZXNbY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRBWV9PRl9XRUVLKV0pOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ0InOgorICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChsb2NhbGVEYXRhLmxvbmdNb250aE5hbWVzW2NhbGVuZGFyLmdldChDYWxlbmRhci5NT05USCldKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlICdiJzogY2FzZSAnaCc6CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGxvY2FsZURhdGEuc2hvcnRNb250aE5hbWVzW2NhbGVuZGFyLmdldChDYWxlbmRhci5NT05USCldKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlICdDJzoKKyAgICAgICAgICAgIGFwcGVuZExvY2FsaXplZChyZXN1bHQsIGNhbGVuZGFyLmdldChDYWxlbmRhci5ZRUFSKSAvIDEwMCwgMik7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSAnRCc6CisgICAgICAgICAgICBhcHBlbmRUKHJlc3VsdCwgJ20nLCBjYWxlbmRhcik7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCcvJyk7CisgICAgICAgICAgICBhcHBlbmRUKHJlc3VsdCwgJ2QnLCBjYWxlbmRhcik7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCcvJyk7CisgICAgICAgICAgICBhcHBlbmRUKHJlc3VsdCwgJ3knLCBjYWxlbmRhcik7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSAnRic6CisgICAgICAgICAgICBhcHBlbmRUKHJlc3VsdCwgJ1knLCBjYWxlbmRhcik7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCctJyk7CisgICAgICAgICAgICBhcHBlbmRUKHJlc3VsdCwgJ20nLCBjYWxlbmRhcik7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCctJyk7CisgICAgICAgICAgICBhcHBlbmRUKHJlc3VsdCwgJ2QnLCBjYWxlbmRhcik7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSAnSCc6CisgICAgICAgICAgICBhcHBlbmRMb2NhbGl6ZWQocmVzdWx0LCBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVkpLCAyKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlICdJJzoKKyAgICAgICAgICAgIGFwcGVuZExvY2FsaXplZChyZXN1bHQsIHRvMTJIb3VyKGNhbGVuZGFyLmdldChDYWxlbmRhci5IT1VSKSksIDIpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ0wnOgorICAgICAgICAgICAgYXBwZW5kTG9jYWxpemVkKHJlc3VsdCwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLk1JTExJU0VDT05EKSwgMyk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSAnTSc6CisgICAgICAgICAgICBhcHBlbmRMb2NhbGl6ZWQocmVzdWx0LCBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuTUlOVVRFKSwgMik7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSAnTic6CisgICAgICAgICAgICBhcHBlbmRMb2NhbGl6ZWQocmVzdWx0LCBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuTUlMTElTRUNPTkQpICogMTAwMDAwMEwsIDkpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ1EnOgorICAgICAgICAgICAgYXBwZW5kTG9jYWxpemVkKHJlc3VsdCwgY2FsZW5kYXIuZ2V0VGltZUluTWlsbGlzKCksIDApOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ1InOgorICAgICAgICAgICAgYXBwZW5kVChyZXN1bHQsICdIJywgY2FsZW5kYXIpOworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnOicpOworICAgICAgICAgICAgYXBwZW5kVChyZXN1bHQsICdNJywgY2FsZW5kYXIpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ1MnOgorICAgICAgICAgICAgYXBwZW5kTG9jYWxpemVkKHJlc3VsdCwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLlNFQ09ORCksIDIpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ1QnOgorICAgICAgICAgICAgYXBwZW5kVChyZXN1bHQsICdIJywgY2FsZW5kYXIpOworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnOicpOworICAgICAgICAgICAgYXBwZW5kVChyZXN1bHQsICdNJywgY2FsZW5kYXIpOworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnOicpOworICAgICAgICAgICAgYXBwZW5kVChyZXN1bHQsICdTJywgY2FsZW5kYXIpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ1knOgorICAgICAgICAgICAgYXBwZW5kTG9jYWxpemVkKHJlc3VsdCwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLllFQVIpLCA0KTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlICdaJzoKKyAgICAgICAgICAgIFRpbWVab25lIHRpbWVab25lID0gY2FsZW5kYXIuZ2V0VGltZVpvbmUoKTsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQodGltZVpvbmUuZ2V0RGlzcGxheU5hbWUodGltZVpvbmUuaW5EYXlsaWdodFRpbWUoY2FsZW5kYXIuZ2V0VGltZSgpKSwKKyAgICAgICAgICAgICAgICAgICAgVGltZVpvbmUuU0hPUlQsIGxvY2FsZSkpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ2MnOgorICAgICAgICAgICAgYXBwZW5kVChyZXN1bHQsICdhJywgY2FsZW5kYXIpOworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnICcpOworICAgICAgICAgICAgYXBwZW5kVChyZXN1bHQsICdiJywgY2FsZW5kYXIpOworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnICcpOworICAgICAgICAgICAgYXBwZW5kVChyZXN1bHQsICdkJywgY2FsZW5kYXIpOworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnICcpOworICAgICAgICAgICAgYXBwZW5kVChyZXN1bHQsICdUJywgY2FsZW5kYXIpOworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnICcpOworICAgICAgICAgICAgYXBwZW5kVChyZXN1bHQsICdaJywgY2FsZW5kYXIpOworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnICcpOworICAgICAgICAgICAgYXBwZW5kVChyZXN1bHQsICdZJywgY2FsZW5kYXIpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ2QnOgorICAgICAgICAgICAgYXBwZW5kTG9jYWxpemVkKHJlc3VsdCwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCksIDIpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ2UnOgorICAgICAgICAgICAgYXBwZW5kTG9jYWxpemVkKHJlc3VsdCwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCksIDApOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ2onOgorICAgICAgICAgICAgYXBwZW5kTG9jYWxpemVkKHJlc3VsdCwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRBWV9PRl9ZRUFSKSwgMyk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSAnayc6CisgICAgICAgICAgICBhcHBlbmRMb2NhbGl6ZWQocmVzdWx0LCBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVkpLCAwKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlICdsJzoKKyAgICAgICAgICAgIGFwcGVuZExvY2FsaXplZChyZXN1bHQsIHRvMTJIb3VyKGNhbGVuZGFyLmdldChDYWxlbmRhci5IT1VSKSksIDApOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ20nOgorICAgICAgICAgICAgLy8gQ2FsZW5kYXIuSkFOVUFSWSBpcyAwOyBodW1hbnMgd2FudCBKYW51YXJ5IHJlcHJlc2VudGVkIGFzIDEuCisgICAgICAgICAgICBhcHBlbmRMb2NhbGl6ZWQocmVzdWx0LCBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuTU9OVEgpICsgMSwgMik7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSAncCc6CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGxvY2FsZURhdGEuYW1QbVtjYWxlbmRhci5nZXQoQ2FsZW5kYXIuQU1fUE0pXS50b0xvd2VyQ2FzZShsb2NhbGUpKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlICdyJzoKKyAgICAgICAgICAgIGFwcGVuZFQocmVzdWx0LCAnSScsIGNhbGVuZGFyKTsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJzonKTsKKyAgICAgICAgICAgIGFwcGVuZFQocmVzdWx0LCAnTScsIGNhbGVuZGFyKTsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJzonKTsKKyAgICAgICAgICAgIGFwcGVuZFQocmVzdWx0LCAnUycsIGNhbGVuZGFyKTsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJyAnKTsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQobG9jYWxlRGF0YS5hbVBtW2NhbGVuZGFyLmdldChDYWxlbmRhci5BTV9QTSldKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlICdzJzoKKyAgICAgICAgICAgIGFwcGVuZExvY2FsaXplZChyZXN1bHQsIGNhbGVuZGFyLmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMCwgMCk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSAneSc6CisgICAgICAgICAgICBhcHBlbmRMb2NhbGl6ZWQocmVzdWx0LCBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuWUVBUikgJSAxMDAsIDIpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgJ3onOgorICAgICAgICAgICAgbG9uZyBvZmZzZXQgPSBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuWk9ORV9PRkZTRVQpICsgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRTVF9PRkZTRVQpOworICAgICAgICAgICAgY2hhciBzaWduID0gJysnOworICAgICAgICAgICAgaWYgKG9mZnNldCA8IDApIHsKKyAgICAgICAgICAgICAgICBzaWduID0gJy0nOworICAgICAgICAgICAgICAgIG9mZnNldCA9IC1vZmZzZXQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHNpZ24pOworICAgICAgICAgICAgYXBwZW5kTG9jYWxpemVkKHJlc3VsdCwgb2Zmc2V0IC8gMzYwMDAwMCwgMik7CisgICAgICAgICAgICBhcHBlbmRMb2NhbGl6ZWQocmVzdWx0LCAob2Zmc2V0ICUgMzYwMDAwMCkgLyA2MDAwMCwgMik7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgdG8xMkhvdXIoaW50IGhvdXIpIHsKKyAgICAgICAgcmV0dXJuIGhvdXIgPT0gMCA/IDEyIDogaG91cjsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXBwZW5kTG9jYWxpemVkKFN0cmluZ0J1aWxkZXIgcmVzdWx0LCBsb25nIHZhbHVlLCBpbnQgd2lkdGgpIHsKKyAgICAgICAgaW50IHBhZGRpbmdJbmRleCA9IHJlc3VsdC5sZW5ndGgoKTsKKyAgICAgICAgY2hhciB6ZXJvRGlnaXQgPSBsb2NhbGVEYXRhLnplcm9EaWdpdDsKKyAgICAgICAgaWYgKHplcm9EaWdpdCA9PSAnMCcpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQodmFsdWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChsb2NhbGl6ZURpZ2l0cyhMb25nLnRvU3RyaW5nKHZhbHVlKSkpOworICAgICAgICB9CisgICAgICAgIGludCB6ZXJvQ291bnQgPSB3aWR0aCAtIChyZXN1bHQubGVuZ3RoKCkgLSBwYWRkaW5nSW5kZXgpOworICAgICAgICBpZiAoemVyb0NvdW50IDw9IDApIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAoemVyb0RpZ2l0ID09ICcwJykgeworICAgICAgICAgICAgcmVzdWx0Lmluc2VydChwYWRkaW5nSW5kZXgsIFpFUk9TLCAwLCB6ZXJvQ291bnQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB6ZXJvQ291bnQ7ICsraSkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5pbnNlcnQocGFkZGluZ0luZGV4LCB6ZXJvRGlnaXQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBDaGFyU2VxdWVuY2UgdHJhbnNmb3JtRnJvbVNwZWNpYWxOdW1iZXIoZG91YmxlIGQpIHsKKyAgICAgICAgU3RyaW5nIHNvdXJjZSA9IG51bGw7CisgICAgICAgIGlmIChEb3VibGUuaXNOYU4oZCkpIHsKKyAgICAgICAgICAgIHNvdXJjZSA9ICJOYU4iOworICAgICAgICB9IGVsc2UgaWYgKGQgPT0gRG91YmxlLlBPU0lUSVZFX0lORklOSVRZKSB7CisgICAgICAgICAgICBpZiAoZm9ybWF0VG9rZW4uZmxhZ1BsdXMpIHsKKyAgICAgICAgICAgICAgICBzb3VyY2UgPSAiK0luZmluaXR5IjsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0VG9rZW4uZmxhZ1NwYWNlKSB7CisgICAgICAgICAgICAgICAgc291cmNlID0gIiBJbmZpbml0eSI7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHNvdXJjZSA9ICJJbmZpbml0eSI7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAoZCA9PSBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpIHsKKyAgICAgICAgICAgIGlmIChmb3JtYXRUb2tlbi5mbGFnUGFyZW50aGVzaXMpIHsKKyAgICAgICAgICAgICAgICBzb3VyY2UgPSAiKEluZmluaXR5KSI7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHNvdXJjZSA9ICItSW5maW5pdHkiOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBmb3JtYXRUb2tlbi5zZXRQcmVjaXNpb24oRm9ybWF0VG9rZW4uVU5TRVQpOworICAgICAgICBmb3JtYXRUb2tlbi5mbGFnWmVybyA9IGZhbHNlOworICAgICAgICByZXR1cm4gcGFkZGluZyhzb3VyY2UsIDApOworICAgIH0KKworICAgIHByaXZhdGUgQ2hhclNlcXVlbmNlIHRyYW5zZm9ybUZyb21GbG9hdCgpIHsKKyAgICAgICAgaWYgKGFyZyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtRnJvbU51bGwoKTsKKyAgICAgICAgfSBlbHNlIGlmIChhcmcgaW5zdGFuY2VvZiBGbG9hdCB8fCBhcmcgaW5zdGFuY2VvZiBEb3VibGUpIHsKKyAgICAgICAgICAgIE51bWJlciBudW1iZXIgPSAoTnVtYmVyKSBhcmc7CisgICAgICAgICAgICBkb3VibGUgZCA9IG51bWJlci5kb3VibGVWYWx1ZSgpOworICAgICAgICAgICAgaWYgKGQgIT0gZCB8fCBkID09IERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSB8fCBkID09IERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1Gcm9tU3BlY2lhbE51bWJlcihkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChhcmcgaW5zdGFuY2VvZiBCaWdEZWNpbWFsKSB7CisgICAgICAgICAgICAvLyBCaWdEZWNpbWFsIGNhbid0IHJlcHJlc2VudCBOYU4gb3IgaW5maW5pdGllcywgYnV0IGl0cyBkb3VibGVWYWx1ZSBtZXRob2Qgd2lsbCByZXR1cm4KKyAgICAgICAgICAgIC8vIGluZmluaXRpZXMgaWYgdGhlIEJpZ0RlY2ltYWwgaXMgdG9vIGJpZyBmb3IgYSBkb3VibGUuCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBiYWRBcmd1bWVudFR5cGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIGNoYXIgY29udmVyc2lvblR5cGUgPSBmb3JtYXRUb2tlbi5nZXRDb252ZXJzaW9uVHlwZSgpOworICAgICAgICBpZiAoY29udmVyc2lvblR5cGUgIT0gJ2EnICYmIGNvbnZlcnNpb25UeXBlICE9ICdBJyAmJiAhZm9ybWF0VG9rZW4uaXNQcmVjaXNpb25TZXQoKSkgeworICAgICAgICAgICAgZm9ybWF0VG9rZW4uc2V0UHJlY2lzaW9uKEZvcm1hdFRva2VuLkRFRkFVTFRfUFJFQ0lTSU9OKTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgc3dpdGNoIChjb252ZXJzaW9uVHlwZSkgeworICAgICAgICBjYXNlICdhJzogY2FzZSAnQSc6CisgICAgICAgICAgICB0cmFuc2Zvcm1BKHJlc3VsdCk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAnZSc6IGNhc2UgJ0UnOgorICAgICAgICAgICAgdHJhbnNmb3JtRShyZXN1bHQpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ2YnOgorICAgICAgICAgICAgdHJhbnNmb3JtRihyZXN1bHQpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ2cnOgorICAgICAgICBjYXNlICdHJzoKKyAgICAgICAgICAgIHRyYW5zZm9ybUcocmVzdWx0KTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgdGhyb3cgZm9ybWF0VG9rZW4udW5rbm93bkZvcm1hdENvbnZlcnNpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvcm1hdFRva2VuLnNldFByZWNpc2lvbihGb3JtYXRUb2tlbi5VTlNFVCk7CisKKyAgICAgICAgaW50IHN0YXJ0SW5kZXggPSAwOworICAgICAgICBpZiAocmVzdWx0LmNoYXJBdCgwKSA9PSBsb2NhbGVEYXRhLm1pbnVzU2lnbikgeworICAgICAgICAgICAgaWYgKGZvcm1hdFRva2VuLmZsYWdQYXJlbnRoZXNpcykgeworICAgICAgICAgICAgICAgIHJldHVybiB3cmFwUGFyZW50aGVzZXMocmVzdWx0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChmb3JtYXRUb2tlbi5mbGFnU3BhY2UpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuaW5zZXJ0KDAsICcgJyk7CisgICAgICAgICAgICAgICAgc3RhcnRJbmRleCsrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGZvcm1hdFRva2VuLmZsYWdQbHVzKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0Lmluc2VydCgwLCAnKycpOworICAgICAgICAgICAgICAgIHN0YXJ0SW5kZXgrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGNoYXIgZmlyc3RDaGFyID0gcmVzdWx0LmNoYXJBdCgwKTsKKyAgICAgICAgaWYgKGZvcm1hdFRva2VuLmZsYWdaZXJvICYmIChmaXJzdENoYXIgPT0gJysnIHx8IGZpcnN0Q2hhciA9PSBsb2NhbGVEYXRhLm1pbnVzU2lnbikpIHsKKyAgICAgICAgICAgIHN0YXJ0SW5kZXggPSAxOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGNvbnZlcnNpb25UeXBlID09ICdhJyB8fCBjb252ZXJzaW9uVHlwZSA9PSAnQScpIHsKKyAgICAgICAgICAgIHN0YXJ0SW5kZXggKz0gMjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcGFkZGluZyhyZXN1bHQsIHN0YXJ0SW5kZXgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0cmFuc2Zvcm1FKFN0cmluZ0J1aWxkZXIgcmVzdWx0KSB7CisgICAgICAgIC8vIEFsbCB6ZXJvcyBpbiB0aGlzIG1ldGhvZCBhcmUgKnBhdHRlcm4qIGNoYXJhY3RlcnMsIHNvIG5vIGxvY2FsaXphdGlvbi4KKyAgICAgICAgZmluYWwgaW50IHByZWNpc2lvbiA9IGZvcm1hdFRva2VuLmdldFByZWNpc2lvbigpOworICAgICAgICBTdHJpbmcgcGF0dGVybiA9ICIwRSswMCI7CisgICAgICAgIGlmIChwcmVjaXNpb24gPiAwKSB7CisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoIjAuIik7CisgICAgICAgICAgICBjaGFyW10gemVyb3MgPSBuZXcgY2hhcltwcmVjaXNpb25dOworICAgICAgICAgICAgQXJyYXlzLmZpbGwoemVyb3MsICcwJyk7CisgICAgICAgICAgICBzYi5hcHBlbmQoemVyb3MpOworICAgICAgICAgICAgc2IuYXBwZW5kKCJFKzAwIik7CisgICAgICAgICAgICBwYXR0ZXJuID0gc2IudG9TdHJpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIE5hdGl2ZURlY2ltYWxGb3JtYXQgbmYgPSBnZXREZWNpbWFsRm9ybWF0KHBhdHRlcm4pOworICAgICAgICBjaGFyW10gY2hhcnM7CisgICAgICAgIGlmIChhcmcgaW5zdGFuY2VvZiBCaWdEZWNpbWFsKSB7CisgICAgICAgICAgICBjaGFycyA9IG5mLmZvcm1hdEJpZ0RlY2ltYWwoKEJpZ0RlY2ltYWwpIGFyZywgbnVsbCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjaGFycyA9IG5mLmZvcm1hdERvdWJsZSgoKE51bWJlcikgYXJnKS5kb3VibGVWYWx1ZSgpLCBudWxsKTsKKyAgICAgICAgfQorICAgICAgICAvLyBVbmxpa2UgJWYsICVlIHVzZXMgJ2UnIChyZWdhcmRsZXNzIG9mIHdoYXQgdGhlIERlY2ltYWxGb3JtYXRTeW1ib2xzIHdvdWxkIGhhdmUgdXMgdXNlKS4KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaGFycy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgaWYgKGNoYXJzW2ldID09ICdFJykgeworICAgICAgICAgICAgICAgIGNoYXJzW2ldID0gJ2UnOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJlc3VsdC5hcHBlbmQoY2hhcnMpOworICAgICAgICAvLyBUaGUgIyBmbGFnIHJlcXVpcmVzIHRoYXQgd2UgYWx3YXlzIG91dHB1dCBhIGRlY2ltYWwgc2VwYXJhdG9yLgorICAgICAgICBpZiAoZm9ybWF0VG9rZW4uZmxhZ1NoYXJwICYmIHByZWNpc2lvbiA9PSAwKSB7CisgICAgICAgICAgICBpbnQgaW5kZXhPZkUgPSByZXN1bHQuaW5kZXhPZigiZSIpOworICAgICAgICAgICAgcmVzdWx0Lmluc2VydChpbmRleE9mRSwgbG9jYWxlRGF0YS5kZWNpbWFsU2VwYXJhdG9yKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0cmFuc2Zvcm1HKFN0cmluZ0J1aWxkZXIgcmVzdWx0KSB7CisgICAgICAgIGludCBwcmVjaXNpb24gPSBmb3JtYXRUb2tlbi5nZXRQcmVjaXNpb24oKTsKKyAgICAgICAgaWYgKHByZWNpc2lvbiA9PSAwKSB7CisgICAgICAgICAgICBwcmVjaXNpb24gPSAxOworICAgICAgICB9CisgICAgICAgIGZvcm1hdFRva2VuLnNldFByZWNpc2lvbihwcmVjaXNpb24pOworCisgICAgICAgIGRvdWJsZSBkID0gKChOdW1iZXIpIGFyZykuZG91YmxlVmFsdWUoKTsKKyAgICAgICAgaWYgKGQgPT0gMC4wKSB7CisgICAgICAgICAgICBwcmVjaXNpb24tLTsKKyAgICAgICAgICAgIGZvcm1hdFRva2VuLnNldFByZWNpc2lvbihwcmVjaXNpb24pOworICAgICAgICAgICAgdHJhbnNmb3JtRihyZXN1bHQpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiByZXF1aXJlU2NpZW50aWZpY1JlcHJlc2VudGF0aW9uID0gdHJ1ZTsKKyAgICAgICAgZCA9IE1hdGguYWJzKGQpOworICAgICAgICBpZiAoRG91YmxlLmlzSW5maW5pdGUoZCkpIHsKKyAgICAgICAgICAgIHByZWNpc2lvbiA9IGZvcm1hdFRva2VuLmdldFByZWNpc2lvbigpOworICAgICAgICAgICAgcHJlY2lzaW9uLS07CisgICAgICAgICAgICBmb3JtYXRUb2tlbi5zZXRQcmVjaXNpb24ocHJlY2lzaW9uKTsKKyAgICAgICAgICAgIHRyYW5zZm9ybUUocmVzdWx0KTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBCaWdEZWNpbWFsIGIgPSBuZXcgQmlnRGVjaW1hbChkLCBuZXcgTWF0aENvbnRleHQocHJlY2lzaW9uKSk7CisgICAgICAgIGQgPSBiLmRvdWJsZVZhbHVlKCk7CisgICAgICAgIGxvbmcgbCA9IGIubG9uZ1ZhbHVlKCk7CisKKyAgICAgICAgaWYgKGQgPj0gMSAmJiBkIDwgTWF0aC5wb3coMTAsIHByZWNpc2lvbikpIHsKKyAgICAgICAgICAgIGlmIChsIDwgTWF0aC5wb3coMTAsIHByZWNpc2lvbikpIHsKKyAgICAgICAgICAgICAgICByZXF1aXJlU2NpZW50aWZpY1JlcHJlc2VudGF0aW9uID0gZmFsc2U7CisgICAgICAgICAgICAgICAgcHJlY2lzaW9uIC09IFN0cmluZy52YWx1ZU9mKGwpLmxlbmd0aCgpOworICAgICAgICAgICAgICAgIHByZWNpc2lvbiA9IHByZWNpc2lvbiA8IDAgPyAwIDogcHJlY2lzaW9uOworICAgICAgICAgICAgICAgIGwgPSBNYXRoLnJvdW5kKGQgKiBNYXRoLnBvdygxMCwgcHJlY2lzaW9uICsgMSkpOworICAgICAgICAgICAgICAgIGlmIChTdHJpbmcudmFsdWVPZihsKS5sZW5ndGgoKSA8PSBmb3JtYXRUb2tlbi5nZXRQcmVjaXNpb24oKSkgeworICAgICAgICAgICAgICAgICAgICBwcmVjaXNpb24rKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZm9ybWF0VG9rZW4uc2V0UHJlY2lzaW9uKHByZWNpc2lvbik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBsID0gYi5tb3ZlUG9pbnRSaWdodCg0KS5sb25nVmFsdWUoKTsKKyAgICAgICAgICAgIGlmIChkID49IE1hdGgucG93KDEwLCAtNCkgJiYgZCA8IDEpIHsKKyAgICAgICAgICAgICAgICByZXF1aXJlU2NpZW50aWZpY1JlcHJlc2VudGF0aW9uID0gZmFsc2U7CisgICAgICAgICAgICAgICAgcHJlY2lzaW9uICs9IDQgLSBTdHJpbmcudmFsdWVPZihsKS5sZW5ndGgoKTsKKyAgICAgICAgICAgICAgICBsID0gYi5tb3ZlUG9pbnRSaWdodChwcmVjaXNpb24gKyAxKS5sb25nVmFsdWUoKTsKKyAgICAgICAgICAgICAgICBpZiAoU3RyaW5nLnZhbHVlT2YobCkubGVuZ3RoKCkgPD0gZm9ybWF0VG9rZW4uZ2V0UHJlY2lzaW9uKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgcHJlY2lzaW9uKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGwgPSBiLm1vdmVQb2ludFJpZ2h0KHByZWNpc2lvbikubG9uZ1ZhbHVlKCk7CisgICAgICAgICAgICAgICAgaWYgKGwgPj0gTWF0aC5wb3coMTAsIHByZWNpc2lvbiAtIDQpKSB7CisgICAgICAgICAgICAgICAgICAgIGZvcm1hdFRva2VuLnNldFByZWNpc2lvbihwcmVjaXNpb24pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAocmVxdWlyZVNjaWVudGlmaWNSZXByZXNlbnRhdGlvbikgeworICAgICAgICAgICAgcHJlY2lzaW9uID0gZm9ybWF0VG9rZW4uZ2V0UHJlY2lzaW9uKCk7CisgICAgICAgICAgICBwcmVjaXNpb24tLTsKKyAgICAgICAgICAgIGZvcm1hdFRva2VuLnNldFByZWNpc2lvbihwcmVjaXNpb24pOworICAgICAgICAgICAgdHJhbnNmb3JtRShyZXN1bHQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdHJhbnNmb3JtRihyZXN1bHQpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRyYW5zZm9ybUYoU3RyaW5nQnVpbGRlciByZXN1bHQpIHsKKyAgICAgICAgLy8gQWxsIHplcm9zIGluIHRoaXMgbWV0aG9kIGFyZSAqcGF0dGVybiogY2hhcmFjdGVycywgc28gbm8gbG9jYWxpemF0aW9uLgorICAgICAgICBTdHJpbmcgcGF0dGVybiA9ICIwLjAwMDAwMCI7CisgICAgICAgIGZpbmFsIGludCBwcmVjaXNpb24gPSBmb3JtYXRUb2tlbi5nZXRQcmVjaXNpb24oKTsKKyAgICAgICAgaWYgKGZvcm1hdFRva2VuLmZsYWdDb21tYSB8fCBwcmVjaXNpb24gIT0gRm9ybWF0VG9rZW4uREVGQVVMVF9QUkVDSVNJT04pIHsKKyAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgcGF0dGVybkJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICAgICAgaWYgKGZvcm1hdFRva2VuLmZsYWdDb21tYSkgeworICAgICAgICAgICAgICAgIHBhdHRlcm5CdWlsZGVyLmFwcGVuZCgnLCcpOworICAgICAgICAgICAgICAgIGludCBncm91cGluZ1NpemUgPSAzOworICAgICAgICAgICAgICAgIGNoYXJbXSBzaGFycHMgPSBuZXcgY2hhcltncm91cGluZ1NpemUgLSAxXTsKKyAgICAgICAgICAgICAgICBBcnJheXMuZmlsbChzaGFycHMsICcjJyk7CisgICAgICAgICAgICAgICAgcGF0dGVybkJ1aWxkZXIuYXBwZW5kKHNoYXJwcyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwYXR0ZXJuQnVpbGRlci5hcHBlbmQoJzAnKTsKKyAgICAgICAgICAgIGlmIChwcmVjaXNpb24gPiAwKSB7CisgICAgICAgICAgICAgICAgcGF0dGVybkJ1aWxkZXIuYXBwZW5kKCcuJyk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcmVjaXNpb247ICsraSkgeworICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuQnVpbGRlci5hcHBlbmQoJzAnKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwYXR0ZXJuID0gcGF0dGVybkJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIE5hdGl2ZURlY2ltYWxGb3JtYXQgbmYgPSBnZXREZWNpbWFsRm9ybWF0KHBhdHRlcm4pOworICAgICAgICBpZiAoYXJnIGluc3RhbmNlb2YgQmlnRGVjaW1hbCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChuZi5mb3JtYXRCaWdEZWNpbWFsKChCaWdEZWNpbWFsKSBhcmcsIG51bGwpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQobmYuZm9ybWF0RG91YmxlKCgoTnVtYmVyKSBhcmcpLmRvdWJsZVZhbHVlKCksIG51bGwpKTsKKyAgICAgICAgfQorICAgICAgICAvLyBUaGUgIyBmbGFnIHJlcXVpcmVzIHRoYXQgd2UgYWx3YXlzIG91dHB1dCBhIGRlY2ltYWwgc2VwYXJhdG9yLgorICAgICAgICBpZiAoZm9ybWF0VG9rZW4uZmxhZ1NoYXJwICYmIHByZWNpc2lvbiA9PSAwKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGxvY2FsZURhdGEuZGVjaW1hbFNlcGFyYXRvcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdHJhbnNmb3JtQShTdHJpbmdCdWlsZGVyIHJlc3VsdCkgeworICAgICAgICBpZiAoYXJnIGluc3RhbmNlb2YgRmxvYXQpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoRmxvYXQudG9IZXhTdHJpbmcoKChGbG9hdCkgYXJnKS5mbG9hdFZhbHVlKCkpKTsKKyAgICAgICAgfSBlbHNlIGlmIChhcmcgaW5zdGFuY2VvZiBEb3VibGUpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoRG91YmxlLnRvSGV4U3RyaW5nKCgoRG91YmxlKSBhcmcpLmRvdWJsZVZhbHVlKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IGJhZEFyZ3VtZW50VHlwZSgpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFmb3JtYXRUb2tlbi5pc1ByZWNpc2lvblNldCgpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpbnQgcHJlY2lzaW9uID0gZm9ybWF0VG9rZW4uZ2V0UHJlY2lzaW9uKCk7CisgICAgICAgIGlmIChwcmVjaXNpb24gPT0gMCkgeworICAgICAgICAgICAgcHJlY2lzaW9uID0gMTsKKyAgICAgICAgfQorICAgICAgICBpbnQgaW5kZXhPZkZpcnN0RnJhY3Rpb25hbERpZ2l0ID0gcmVzdWx0LmluZGV4T2YoIi4iKSArIDE7CisgICAgICAgIGludCBpbmRleE9mUCA9IHJlc3VsdC5pbmRleE9mKCJwIik7CisgICAgICAgIGludCBmcmFjdGlvbmFsTGVuZ3RoID0gaW5kZXhPZlAgLSBpbmRleE9mRmlyc3RGcmFjdGlvbmFsRGlnaXQ7CisKKyAgICAgICAgaWYgKGZyYWN0aW9uYWxMZW5ndGggPT0gcHJlY2lzaW9uKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAoZnJhY3Rpb25hbExlbmd0aCA8IHByZWNpc2lvbikgeworICAgICAgICAgICAgY2hhcltdIHplcm9zID0gbmV3IGNoYXJbcHJlY2lzaW9uIC0gZnJhY3Rpb25hbExlbmd0aF07CisgICAgICAgICAgICBBcnJheXMuZmlsbCh6ZXJvcywgJzAnKTsgLy8gJWEgc2hvdWxkbid0IGJlIGxvY2FsaXplZC4KKyAgICAgICAgICAgIHJlc3VsdC5pbnNlcnQoaW5kZXhPZlAsIHplcm9zKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICByZXN1bHQuZGVsZXRlKGluZGV4T2ZGaXJzdEZyYWN0aW9uYWxEaWdpdCArIHByZWNpc2lvbiwgaW5kZXhPZlApOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEZvcm1hdFNwZWNpZmllclBhcnNlciB7CisgICAgICAgIHByaXZhdGUgU3RyaW5nIGZvcm1hdDsKKyAgICAgICAgcHJpdmF0ZSBpbnQgbGVuZ3RoOworCisgICAgICAgIHByaXZhdGUgaW50IHN0YXJ0SW5kZXg7CisgICAgICAgIHByaXZhdGUgaW50IGk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgcGFyc2VyIGZvciB0aGUgZ2l2ZW4gZm9ybWF0IHN0cmluZy4KKyAgICAgICAgICovCisgICAgICAgIEZvcm1hdFNwZWNpZmllclBhcnNlcihTdHJpbmcgZm9ybWF0KSB7CisgICAgICAgICAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDsKKyAgICAgICAgICAgIHRoaXMubGVuZ3RoID0gZm9ybWF0Lmxlbmd0aCgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgYSBGb3JtYXRUb2tlbiByZXByZXNlbnRpbmcgdGhlIGZvcm1hdCBzcGVjaWZpZXIgc3RhcnRpbmcgYXQgJ29mZnNldCcuCisgICAgICAgICAqIEBwYXJhbSBvZmZzZXQgdGhlIGZpcnN0IGNoYXJhY3RlciBhZnRlciB0aGUgJyUnCisgICAgICAgICAqLworICAgICAgICBGb3JtYXRUb2tlbiBwYXJzZUZvcm1hdFRva2VuKGludCBvZmZzZXQpIHsKKyAgICAgICAgICAgIHRoaXMuc3RhcnRJbmRleCA9IG9mZnNldDsKKyAgICAgICAgICAgIHRoaXMuaSA9IG9mZnNldDsKKyAgICAgICAgICAgIHJldHVybiBwYXJzZUFyZ3VtZW50SW5kZXhBbmRGbGFncyhuZXcgRm9ybWF0VG9rZW4oKSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyBhIHN0cmluZyBjb3JyZXNwb25kaW5nIHRvIHRoZSBsYXN0IGZvcm1hdCBzcGVjaWZpZXIgdGhhdCB3YXMgcGFyc2VkLgorICAgICAgICAgKiBVc2VkIHRvIGNvbnN0cnVjdCBlcnJvciBtZXNzYWdlcy4KKyAgICAgICAgICovCisgICAgICAgIFN0cmluZyBnZXRGb3JtYXRTcGVjaWZpZXJUZXh0KCkgeworICAgICAgICAgICAgcmV0dXJuIGZvcm1hdC5zdWJzdHJpbmcoc3RhcnRJbmRleCwgaSk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIGludCBwZWVrKCkgeworICAgICAgICAgICAgcmV0dXJuIChpIDwgbGVuZ3RoKSA/IGZvcm1hdC5jaGFyQXQoaSkgOiAtMTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgY2hhciBhZHZhbmNlKCkgeworICAgICAgICAgICAgaWYgKGkgPj0gbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgdW5rbm93bkZvcm1hdENvbnZlcnNpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmb3JtYXQuY2hhckF0KGkrKyk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIFVua25vd25Gb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9uIHVua25vd25Gb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9uKCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVua25vd25Gb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9uKGdldEZvcm1hdFNwZWNpZmllclRleHQoKSk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIEZvcm1hdFRva2VuIHBhcnNlQXJndW1lbnRJbmRleEFuZEZsYWdzKEZvcm1hdFRva2VuIHRva2VuKSB7CisgICAgICAgICAgICAvLyBQYXJzZSB0aGUgYXJndW1lbnQgaW5kZXgsIGlmIHRoZXJlIGlzIG9uZS4KKyAgICAgICAgICAgIGludCBwb3NpdGlvbiA9IGk7CisgICAgICAgICAgICBpbnQgY2ggPSBwZWVrKCk7CisgICAgICAgICAgICBpZiAoQ2hhcmFjdGVyLmlzRGlnaXQoY2gpKSB7CisgICAgICAgICAgICAgICAgaW50IG51bWJlciA9IG5leHRJbnQoKTsKKyAgICAgICAgICAgICAgICBpZiAocGVlaygpID09ICckJykgeworICAgICAgICAgICAgICAgICAgICAvLyBUaGUgbnVtYmVyIHdhcyBhbiBhcmd1bWVudCBpbmRleC4KKyAgICAgICAgICAgICAgICAgICAgYWR2YW5jZSgpOyAvLyBTd2FsbG93IHRoZSAnJCcuCisgICAgICAgICAgICAgICAgICAgIGlmIChudW1iZXIgPT0gRm9ybWF0VG9rZW4uVU5TRVQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nRm9ybWF0QXJndW1lbnRFeGNlcHRpb24oZ2V0Rm9ybWF0U3BlY2lmaWVyVGV4dCgpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAvLyBrJCBzdGFuZHMgZm9yIHRoZSBhcmd1bWVudCB3aG9zZSBpbmRleCBpcyBrLTEgZXhjZXB0IHRoYXQKKyAgICAgICAgICAgICAgICAgICAgLy8gMCQgYW5kIDEkIGJvdGggc3RhbmQgZm9yIHRoZSBmaXJzdCBlbGVtZW50LgorICAgICAgICAgICAgICAgICAgICB0b2tlbi5zZXRBcmdJbmRleChNYXRoLm1heCgwLCBudW1iZXIgLSAxKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNoID09ICcwJykgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGRpZ2l0IHplcm8gaXMgYSBmb3JtYXQgZmxhZywgc28gcmVwYXJzZSBpdCBhcyBzdWNoLgorICAgICAgICAgICAgICAgICAgICAgICAgaSA9IHBvc2l0aW9uOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIG51bWJlciB3YXMgYSB3aWR0aC4gVGhpcyBtZWFucyB0aGVyZSBhcmUgbm8gZmxhZ3MgdG8gcGFyc2UuCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VXaWR0aCh0b2tlbiwgbnVtYmVyKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gJzwnKSB7CisgICAgICAgICAgICAgICAgdG9rZW4uc2V0QXJnSW5kZXgoRm9ybWF0VG9rZW4uTEFTVF9BUkdVTUVOVF9JTkRFWCk7CisgICAgICAgICAgICAgICAgYWR2YW5jZSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBQYXJzZSB0aGUgZmxhZ3MuCisgICAgICAgICAgICB3aGlsZSAodG9rZW4uc2V0RmxhZyhwZWVrKCkpKSB7CisgICAgICAgICAgICAgICAgYWR2YW5jZSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBXaGF0IGNvbWVzIG5leHQ/CisgICAgICAgICAgICBjaCA9IHBlZWsoKTsKKyAgICAgICAgICAgIGlmIChDaGFyYWN0ZXIuaXNEaWdpdChjaCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VXaWR0aCh0b2tlbiwgbmV4dEludCgpKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gJy4nKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlUHJlY2lzaW9uKHRva2VuKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlQ29udmVyc2lvblR5cGUodG9rZW4pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gV2UgcGFzcyB0aGUgd2lkdGggaW4gYmVjYXVzZSBpbiBzb21lIGNhc2VzIHdlJ3ZlIGFscmVhZHkgcGFyc2VkIGl0LgorICAgICAgICAvLyAoQmVjYXVzZSBvZiB0aGUgYW1iaWd1aXR5IGJldHdlZW4gYXJndW1lbnQgaW5kZXhlcyBhbmQgd2lkdGhzLikKKyAgICAgICAgcHJpdmF0ZSBGb3JtYXRUb2tlbiBwYXJzZVdpZHRoKEZvcm1hdFRva2VuIHRva2VuLCBpbnQgd2lkdGgpIHsKKyAgICAgICAgICAgIHRva2VuLnNldFdpZHRoKHdpZHRoKTsKKyAgICAgICAgICAgIGludCBjaCA9IHBlZWsoKTsKKyAgICAgICAgICAgIGlmIChjaCA9PSAnLicpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VQcmVjaXNpb24odG9rZW4pOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VDb252ZXJzaW9uVHlwZSh0b2tlbik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIEZvcm1hdFRva2VuIHBhcnNlUHJlY2lzaW9uKEZvcm1hdFRva2VuIHRva2VuKSB7CisgICAgICAgICAgICBhZHZhbmNlKCk7IC8vIFN3YWxsb3cgdGhlICcuJy4KKyAgICAgICAgICAgIGludCBjaCA9IHBlZWsoKTsKKyAgICAgICAgICAgIGlmIChDaGFyYWN0ZXIuaXNEaWdpdChjaCkpIHsKKyAgICAgICAgICAgICAgICB0b2tlbi5zZXRQcmVjaXNpb24obmV4dEludCgpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VDb252ZXJzaW9uVHlwZSh0b2tlbik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIFRoZSBwcmVjaXNpb24gaXMgcmVxdWlyZWQgYnV0IG5vdCBnaXZlbiBieSB0aGUgZm9ybWF0IHN0cmluZy4KKyAgICAgICAgICAgICAgICB0aHJvdyB1bmtub3duRm9ybWF0Q29udmVyc2lvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBGb3JtYXRUb2tlbiBwYXJzZUNvbnZlcnNpb25UeXBlKEZvcm1hdFRva2VuIHRva2VuKSB7CisgICAgICAgICAgICBjaGFyIGNvbnZlcnNpb25UeXBlID0gYWR2YW5jZSgpOyAvLyBBIGNvbnZlcnNpb24gdHlwZSBpcyBtYW5kYXRvcnkuCisgICAgICAgICAgICB0b2tlbi5zZXRDb252ZXJzaW9uVHlwZShjb252ZXJzaW9uVHlwZSk7CisgICAgICAgICAgICBpZiAoY29udmVyc2lvblR5cGUgPT0gJ3QnIHx8IGNvbnZlcnNpb25UeXBlID09ICdUJykgeworICAgICAgICAgICAgICAgIGNoYXIgZGF0ZVN1ZmZpeCA9IGFkdmFuY2UoKTsgLy8gQSBkYXRlIHN1ZmZpeCBpcyBtYW5kYXRvcnkgZm9yICd0JyBvciAnVCcuCisgICAgICAgICAgICAgICAgdG9rZW4uc2V0RGF0ZVN1ZmZpeChkYXRlU3VmZml4KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0b2tlbjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFBhcnNlcyBhbiBpbnRlZ2VyIChvZiBhcmJpdHJhcnkgbGVuZ3RoLCBidXQgdHlwaWNhbGx5IGp1c3Qgb25lIGRpZ2l0KS4KKyAgICAgICAgcHJpdmF0ZSBpbnQgbmV4dEludCgpIHsKKyAgICAgICAgICAgIGxvbmcgdmFsdWUgPSAwOworICAgICAgICAgICAgd2hpbGUgKGkgPCBsZW5ndGggJiYgQ2hhcmFjdGVyLmlzRGlnaXQoZm9ybWF0LmNoYXJBdChpKSkpIHsKKyAgICAgICAgICAgICAgICB2YWx1ZSA9IDEwICogdmFsdWUgKyAoZm9ybWF0LmNoYXJBdChpKyspIC0gJzAnKTsKKyAgICAgICAgICAgICAgICBpZiAodmFsdWUgPiBJbnRlZ2VyLk1BWF9WQUxVRSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFpbE5leHRJbnQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gKGludCkgdmFsdWU7CisgICAgICAgIH0KKworICAgICAgICAvLyBTd2FsbG93IHJlbWFpbmluZyBkaWdpdHMgdG8gcmVzeW5jIG91ciBhdHRlbXB0ZWQgcGFyc2UsIGJ1dCByZXR1cm4gZmFpbHVyZS4KKyAgICAgICAgcHJpdmF0ZSBpbnQgZmFpbE5leHRJbnQoKSB7CisgICAgICAgICAgICB3aGlsZSAoQ2hhcmFjdGVyLmlzRGlnaXQocGVlaygpKSkgeworICAgICAgICAgICAgICAgIGFkdmFuY2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBGb3JtYXRUb2tlbi5VTlNFVDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvRm9ybWF0dGVyQ2xvc2VkRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0Zvcm1hdHRlckNsb3NlZEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZiOWFiMTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0Zvcm1hdHRlckNsb3NlZEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzcgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKKy8qKgorICogQSB7QGNvZGUgRm9ybWF0dGVyQ2xvc2VkRXhjZXB0aW9ufSB3aWxsIGJlIHRocm93biBpZiB0aGUgZm9ybWF0dGVyIGhhcyBiZWVuCisgKiBjbG9zZWQuCisgKgorICogQHNlZSBqYXZhLmxhbmcuUnVudGltZUV4Y2VwdGlvbgorICovCitwdWJsaWMgY2xhc3MgRm9ybWF0dGVyQ2xvc2VkRXhjZXB0aW9uIGV4dGVuZHMgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGltcGxlbWVudHMKKyAgICAgICAgU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxODExMTIxNkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBGb3JtYXR0ZXJDbG9zZWRFeGNlcHRpb259IHdpdGggdGhlIHN0YWNrIHRyYWNlCisgICAgICogZmlsbGVkIGluLgorICAgICAqLworICAgIHB1YmxpYyBGb3JtYXR0ZXJDbG9zZWRFeGNlcHRpb24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9HcmVnby5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9HcmVnby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmN2E3ZmEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0dyZWdvLmphdmEKQEAgLTAsMCArMSwyMTQgQEAKKy8qKg0KKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQorICogQ29weXJpZ2h0IChDKSAyMDAzLTIwMDgsIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kDQorICogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLg0KKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQorICogUGFydGlhbCBwb3J0IGZyb20gSUNVNEMncyBHcmVnbyBjbGFzcyBpbiBpMThuL2dyZWdvaW1wLmguDQorICoNCisgKiBNZXRob2RzIHBvcnRlZCwgb3IgbW92ZWQgaGVyZSBmcm9tIE9sc29uVGltZVpvbmUsIGluaXRpYWxseQ0KKyAqIGZvciB3b3JrIG9uIEppdHRlcmJ1ZyA1NDcwOg0KKyAqICAgdHpkYXRhMjAwNm4gQnJhemlsIGluY29ycmVjdCBmYWxsLWJhY2sgZGF0ZSAyMDA5LW1hci0wMQ0KKyAqIE9ubHkgdGhlIG1ldGhvZHMgbmVjZXNzYXJ5IGZvciB0aGF0IHdvcmsgYXJlIHByb3ZpZGVkIC0gdGhpcyBpcyBub3QgYSBmdWxsDQorICogcG9ydCBvZiBJQ1U0QydzIEdyZWdvIGNsYXNzICh5ZXQpLg0KKyAqDQorICogVGhlc2UgdXRpbGl0aWVzIGFyZSB1c2VkIGJ5IGJvdGggT2xzb25UaW1lWm9uZSBhbmQgU2ltcGxlVGltZVpvbmUuDQorICovDQorDQorcGFja2FnZSBqYXZhLnV0aWw7IC8vIGFuZHJvaWQtY2hhbmdlZDogY29tLmlibS5pY3UuaW1wbCAoSUNVNEogNC4yKQ0KKw0KKy8vIGFuZHJvaWQtY2hhbmdlZDogaW1wb3J0IGNvbS5pYm0uaWN1LnV0aWwuQ2FsZW5kYXI7DQorDQorLyoqDQorICogQSB1dGlsaXR5IGNsYXNzIHByb3ZpZGluZyBwcm9sZXB0aWMgR3JlZ29yaWFuIGNhbGVuZGFyIGZ1bmN0aW9ucw0KKyAqIHVzZWQgYnkgdGltZSB6b25lIGFuZCBjYWxlbmRhciBjb2RlLiAgRG8gbm90IGluc3RhbnRpYXRlLg0KKyAqDQorICogTm90ZTogIFVubGlrZSBHcmVnb3JpYW5DYWxlbmRhciwgYWxsIGNvbXB1dGF0aW9ucyBwZXJmb3JtZWQgYnkgdGhpcw0KKyAqIGNsYXNzIG9jY3VyIGluIHRoZSBwdXJlIHByb2xlcHRpYyBHcmVnb3JpYW5DYWxlbmRhci4NCisgKi8NCisvLyBhbmRyb2lkLWNoYW5nZWQ6IHB1YmxpYw0KK2NsYXNzIEdyZWdvIHsNCisNCisgICAgLy8gTWF4L21pbiBtaWxsaXNlY29uZHMgDQorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBNSU5fTUlMTElTID0gLTE4NDMwMzkwMjUyODAwMDAwMEw7DQorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBNQVhfTUlMTElTID0gMTgzODgyMTY4OTIxNjAwMDAwTDsNCisNCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUlMTElTX1BFUl9TRUNPTkQgPSAxMDAwOw0KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNSUxMSVNfUEVSX01JTlVURSA9IDYwKk1JTExJU19QRVJfU0VDT05EOw0KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNSUxMSVNfUEVSX0hPVVIgPSA2MCpNSUxMSVNfUEVSX01JTlVURTsNCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUlMTElTX1BFUl9EQVkgPSAyNCpNSUxMSVNfUEVSX0hPVVI7DQorICAgIA0KKyAgICAvLyAgSmFudWFyeSAxLCAxIENFIEdyZWdvcmlhbg0KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSlVMSUFOXzFfQ0UgPSAxNzIxNDI2Ow0KKw0KKyAgICAvLyAgSmFudWFyeSAxLCAxOTcwIENFIEdyZWdvcmlhbg0KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSlVMSUFOXzE5NzBfQ0UgPSAyNDQwNTg4Ow0KKw0KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnRbXSBNT05USF9MRU5HVEggPSBuZXcgaW50W10gew0KKyAgICAgICAgMzEsMjgsMzEsMzAsMzEsMzAsMzEsMzEsMzAsMzEsMzAsMzEsDQorICAgICAgICAzMSwyOSwzMSwzMCwzMSwzMCwzMSwzMSwzMCwzMSwzMCwzMQ0KKyAgICB9Ow0KKw0KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnRbXSBEQVlTX0JFRk9SRSA9IG5ldyBpbnRbXSB7DQorICAgICAgICAwLDMxLDU5LDkwLDEyMCwxNTEsMTgxLDIxMiwyNDMsMjczLDMwNCwzMzQsDQorICAgICAgICAwLDMxLDYwLDkxLDEyMSwxNTIsMTgyLDIxMywyNDQsMjc0LDMwNSwzMzUgfTsNCisNCisgICAgLyoqDQorICAgICAqIFJldHVybiB0cnVlIGlmIHRoZSBnaXZlbiB5ZWFyIGlzIGEgbGVhcCB5ZWFyLg0KKyAgICAgKiBAcGFyYW0geWVhciBHcmVnb3JpYW4geWVhciwgd2l0aCAwID09IDEgQkNFLCAtMSA9PSAyIEJDRSwgZXRjLg0KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHllYXIgaXMgYSBsZWFwIHllYXINCisgICAgICovDQorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYm9vbGVhbiBpc0xlYXBZZWFyKGludCB5ZWFyKSB7DQorICAgICAgICAvLyB5ZWFyJjB4MyA9PSB5ZWFyJTQNCisgICAgICAgIHJldHVybiAoKHllYXImMHgzKSA9PSAwKSAmJiAoKHllYXIlMTAwICE9IDApIHx8ICh5ZWFyJTQwMCA9PSAwKSk7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIFJldHVybiB0aGUgbnVtYmVyIG9mIGRheXMgaW4gdGhlIGdpdmVuIG1vbnRoLg0KKyAgICAgKiBAcGFyYW0geWVhciBHcmVnb3JpYW4geWVhciwgd2l0aCAwID09IDEgQkNFLCAtMSA9PSAyIEJDRSwgZXRjLg0KKyAgICAgKiBAcGFyYW0gbW9udGggMC1iYXNlZCBtb250aCwgd2l0aCAwPT1KYW4NCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGRheXMgaW4gdGhlIGdpdmVuIG1vbnRoDQorICAgICAqLw0KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBtb250aExlbmd0aChpbnQgeWVhciwgaW50IG1vbnRoKSB7DQorICAgICAgICByZXR1cm4gTU9OVEhfTEVOR1RIW21vbnRoICsgKGlzTGVhcFllYXIoeWVhcikgPyAxMiA6IDApXTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogUmV0dXJuIHRoZSBsZW5ndGggb2YgYSBwcmV2aW91cyBtb250aCBvZiB0aGUgR3JlZ29yaWFuIGNhbGVuZGFyLg0KKyAgICAgKiBAcGFyYW0geWVhciBHcmVnb3JpYW4geWVhciwgd2l0aCAwID09IDEgQkNFLCAtMSA9PSAyIEJDRSwgZXRjLg0KKyAgICAgKiBAcGFyYW0gbW9udGggMC1iYXNlZCBtb250aCwgd2l0aCAwPT1KYW4NCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGRheXMgaW4gdGhlIG1vbnRoIHByZXZpb3VzIHRvIHRoZSBnaXZlbiBtb250aA0KKyAgICAgKi8NCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgcHJldmlvdXNNb250aExlbmd0aChpbnQgeWVhciwgaW50IG1vbnRoKSB7DQorICAgICAgICByZXR1cm4gKG1vbnRoID4gMCkgPyBtb250aExlbmd0aCh5ZWFyLCBtb250aC0xKSA6IDMxOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBDb252ZXJ0IGEgeWVhciwgbW9udGgsIGFuZCBkYXktb2YtbW9udGgsIGdpdmVuIGluIHRoZSBwcm9sZXB0aWMNCisgICAgICogR3JlZ29yaWFuIGNhbGVuZGFyLCB0byAxOTcwIGVwb2NoIGRheXMuDQorICAgICAqIEBwYXJhbSB5ZWFyIEdyZWdvcmlhbiB5ZWFyLCB3aXRoIDAgPT0gMSBCQ0UsIC0xID09IDIgQkNFLCBldGMuDQorICAgICAqIEBwYXJhbSBtb250aCAwLWJhc2VkIG1vbnRoLCB3aXRoIDA9PUphbg0KKyAgICAgKiBAcGFyYW0gZG9tIDEtYmFzZWQgZGF5IG9mIG1vbnRoDQorICAgICAqIEByZXR1cm4gdGhlIGRheSBudW1iZXIsIHdpdGggZGF5IDAgPT0gSmFuIDEgMTk3MA0KKyAgICAgKi8NCisgICAgcHVibGljIHN0YXRpYyBsb25nIGZpZWxkc1RvRGF5KGludCB5ZWFyLCBpbnQgbW9udGgsIGludCBkb20pIHsNCisgICAgICAgIGludCB5ID0geWVhciAtIDE7DQorICAgICAgICBsb25nIGp1bGlhbiA9DQorICAgICAgICAgICAgMzY1ICogeSArIGZsb29yRGl2aWRlKHksIDQpICsgKEpVTElBTl8xX0NFIC0gMykgKyAgICAvLyBKdWxpYW4gY2FsDQorICAgICAgICAgICAgZmxvb3JEaXZpZGUoeSwgNDAwKSAtIGZsb29yRGl2aWRlKHksIDEwMCkgKyAyICsgICAvLyA9PiBHcmVnb3JpYW4gY2FsDQorICAgICAgICAgICAgREFZU19CRUZPUkVbbW9udGggKyAoaXNMZWFwWWVhcih5ZWFyKSA/IDEyIDogMCldICsgZG9tOyAvLyA9PiBtb250aC9kb20NCisgICAgICAgIHJldHVybiBqdWxpYW4gLSBKVUxJQU5fMTk3MF9DRTsgLy8gSkQgPT4gZXBvY2ggZGF5DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIFJldHVybiB0aGUgZGF5IG9mIHdlZWsgb24gdGhlIDE5NzAtZXBvY2ggZGF5DQorICAgICAqIEBwYXJhbSBkYXkgdGhlIDE5NzAtZXBvY2ggZGF5IChpbnRlZ3JhbCB2YWx1ZSkNCisgICAgICogQHJldHVybiB0aGUgZGF5IG9mIHdlZWsNCisgICAgICovDQorICAgIHB1YmxpYyBzdGF0aWMgaW50IGRheU9mV2Vlayhsb25nIGRheSkgew0KKyAgICAgICAgbG9uZ1tdIHJlbWFpbmRlciA9IG5ldyBsb25nWzFdOw0KKyAgICAgICAgZmxvb3JEaXZpZGUoZGF5ICsgQ2FsZW5kYXIuVEhVUlNEQVksIDcsIHJlbWFpbmRlcik7DQorICAgICAgICBpbnQgZGF5T2ZXZWVrID0gKGludClyZW1haW5kZXJbMF07DQorICAgICAgICBkYXlPZldlZWsgPSAoZGF5T2ZXZWVrID09IDApID8gNyA6IGRheU9mV2VlazsNCisgICAgICAgIHJldHVybiBkYXlPZldlZWs7DQorICAgIH0NCisNCisgICAgcHVibGljIHN0YXRpYyBpbnRbXSBkYXlUb0ZpZWxkcyhsb25nIGRheSwgaW50W10gZmllbGRzKSB7DQorICAgICAgICBpZiAoZmllbGRzID09IG51bGwgfHwgZmllbGRzLmxlbmd0aCA8IDUpIHsNCisgICAgICAgICAgICBmaWVsZHMgPSBuZXcgaW50WzVdOw0KKyAgICAgICAgfQ0KKyAgICAgICAgLy8gQ29udmVydCBmcm9tIDE5NzAgQ0UgZXBvY2ggdG8gMSBDRSBlcG9jaCAoR3JlZ29yaWFuIGNhbGVuZGFyKQ0KKyAgICAgICAgZGF5ICs9IEpVTElBTl8xOTcwX0NFIC0gSlVMSUFOXzFfQ0U7DQorDQorICAgICAgICBsb25nW10gcmVtID0gbmV3IGxvbmdbMV07DQorICAgICAgICBsb25nIG40MDAgPSBmbG9vckRpdmlkZShkYXksIDE0NjA5NywgcmVtKTsNCisgICAgICAgIGxvbmcgbjEwMCA9IGZsb29yRGl2aWRlKHJlbVswXSwgMzY1MjQsIHJlbSk7DQorICAgICAgICBsb25nIG40ID0gZmxvb3JEaXZpZGUocmVtWzBdLCAxNDYxLCByZW0pOw0KKyAgICAgICAgbG9uZyBuMSA9IGZsb29yRGl2aWRlKHJlbVswXSwgMzY1LCByZW0pOw0KKw0KKyAgICAgICAgaW50IHllYXIgPSAoaW50KSg0MDAgKiBuNDAwICsgMTAwICogbjEwMCArIDQgKiBuNCArIG4xKTsNCisgICAgICAgIGludCBkYXlPZlllYXIgPSAoaW50KXJlbVswXTsNCisgICAgICAgIGlmIChuMTAwID09IDQgfHwgbjEgPT0gNCkgew0KKyAgICAgICAgICAgIGRheU9mWWVhciA9IDM2NTsgICAgLy8gRGVjIDMxIGF0IGVuZCBvZiA0LSBvciA0MDAteXIgY3ljbGUNCisgICAgICAgIH0NCisgICAgICAgIGVsc2Ugew0KKyAgICAgICAgICAgICsreWVhcjsNCisgICAgICAgIH0NCisNCisgICAgICAgIGJvb2xlYW4gaXNMZWFwID0gaXNMZWFwWWVhcih5ZWFyKTsNCisgICAgICAgIGludCBjb3JyZWN0aW9uID0gMDsNCisgICAgICAgIGludCBtYXJjaDEgPSBpc0xlYXAgPyA2MCA6IDU5OyAgLy8gemVyby1iYXNlZCBET1kgZm9yIE1hcmNoIDENCisgICAgICAgIGlmIChkYXlPZlllYXIgPj0gbWFyY2gxKSB7DQorICAgICAgICAgICAgY29ycmVjdGlvbiA9IGlzTGVhcCA/IDEgOiAyOw0KKyAgICAgICAgfQ0KKyAgICAgICAgaW50IG1vbnRoID0gKDEyICogKGRheU9mWWVhciArIGNvcnJlY3Rpb24pICsgNikgLyAzNjc7ICAvLyB6ZXJvLWJhc2VkIG1vbnRoDQorICAgICAgICBpbnQgZGF5T2ZNb250aCA9IGRheU9mWWVhciAtIERBWVNfQkVGT1JFW2lzTGVhcCA/IG1vbnRoICsgMTIgOiBtb250aF0gKyAxOyAvLyBvbmUtYmFzZWQgRE9NDQorICAgICAgICBpbnQgZGF5T2ZXZWVrID0gKGludCkoKGRheSArIDIpICUgNyk7ICAvLyBkYXkgMCBpcyBNb25kYXkoMikNCisgICAgICAgIGlmIChkYXlPZldlZWsgPCAxIC8qIFN1bmRheSAqLykgew0KKyAgICAgICAgICAgIGRheU9mV2VlayArPSA3Ow0KKyAgICAgICAgfQ0KKyAgICAgICAgZGF5T2ZZZWFyKys7IC8vIDEtYmFzZWQgZGF5IG9mIHllYXINCisNCisgICAgICAgIGZpZWxkc1swXSA9IHllYXI7DQorICAgICAgICBmaWVsZHNbMV0gPSBtb250aDsNCisgICAgICAgIGZpZWxkc1syXSA9IGRheU9mTW9udGg7DQorICAgICAgICBmaWVsZHNbM10gPSBkYXlPZldlZWs7DQorICAgICAgICBmaWVsZHNbNF0gPSBkYXlPZlllYXI7DQorDQorICAgICAgICByZXR1cm4gZmllbGRzOw0KKyAgICB9DQorDQorICAgIC8qDQorICAgICAqIENvbnZlcnQgbG9uZyB0aW1lIHRvIGRhdGUvdGltZSBmaWVsZHMNCisgICAgICogDQorICAgICAqIHJlc3VsdFswXSA6IHllYXINCisgICAgICogcmVzdWx0WzFdIDogbW9udGgNCisgICAgICogcmVzdWx0WzJdIDogZGF5T2ZNb250aA0KKyAgICAgKiByZXN1bHRbM10gOiBkYXlPZldlZWsNCisgICAgICogcmVzdWx0WzRdIDogZGF5T2ZZZWFyDQorICAgICAqIHJlc3VsdFs1XSA6IG1pbGxpc2Vjb25kIGluIGRheQ0KKyAgICAgKi8NCisgICAgcHVibGljIHN0YXRpYyBpbnRbXSB0aW1lVG9GaWVsZHMobG9uZyB0aW1lLCBpbnRbXSBmaWVsZHMpIHsNCisgICAgICAgIGlmIChmaWVsZHMgPT0gbnVsbCB8fCBmaWVsZHMubGVuZ3RoIDwgNikgew0KKyAgICAgICAgICAgIGZpZWxkcyA9IG5ldyBpbnRbNl07DQorICAgICAgICB9DQorICAgICAgICBsb25nW10gcmVtYWluZGVyID0gbmV3IGxvbmdbMV07DQorICAgICAgICBsb25nIGRheSA9IGZsb29yRGl2aWRlKHRpbWUsIDI0KjYwKjYwKjEwMDAgLyogbWlsbGlzZWNvbmRzIHBlciBkYXkgKi8sIHJlbWFpbmRlcik7DQorICAgICAgICBkYXlUb0ZpZWxkcyhkYXksIGZpZWxkcyk7DQorICAgICAgICBmaWVsZHNbNV0gPSAoaW50KXJlbWFpbmRlclswXTsNCisgICAgICAgIHJldHVybiBmaWVsZHM7DQorICAgIH0NCisNCisgICAgcHVibGljIHN0YXRpYyBsb25nIGZsb29yRGl2aWRlKGxvbmcgbnVtZXJhdG9yLCBsb25nIGRlbm9taW5hdG9yKSB7DQorICAgICAgICAvLyBXZSBkbyB0aGlzIGNvbXB1dGF0aW9uIGluIG9yZGVyIHRvIGhhbmRsZQ0KKyAgICAgICAgLy8gYSBudW1lcmF0b3Igb2YgTG9uZy5NSU5fVkFMVUUgY29ycmVjdGx5DQorICAgICAgICByZXR1cm4gKG51bWVyYXRvciA+PSAwKSA/DQorICAgICAgICAgICAgbnVtZXJhdG9yIC8gZGVub21pbmF0b3IgOg0KKyAgICAgICAgICAgICgobnVtZXJhdG9yICsgMSkgLyBkZW5vbWluYXRvcikgLSAxOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgc3RhdGljIGxvbmcgZmxvb3JEaXZpZGUobG9uZyBudW1lcmF0b3IsIGxvbmcgZGVub21pbmF0b3IsIGxvbmdbXSByZW1haW5kZXIpIHsNCisgICAgICAgIGlmIChudW1lcmF0b3IgPj0gMCkgew0KKyAgICAgICAgICAgIHJlbWFpbmRlclswXSA9IG51bWVyYXRvciAlIGRlbm9taW5hdG9yOw0KKyAgICAgICAgICAgIHJldHVybiBudW1lcmF0b3IgLyBkZW5vbWluYXRvcjsNCisgICAgICAgIH0NCisgICAgICAgIGxvbmcgcXVvdGllbnQgPSAoKG51bWVyYXRvciArIDEpIC8gZGVub21pbmF0b3IpIC0gMTsNCisgICAgICAgIHJlbWFpbmRlclswXSA9IG51bWVyYXRvciAtIChxdW90aWVudCAqIGRlbm9taW5hdG9yKTsNCisgICAgICAgIHJldHVybiBxdW90aWVudDsNCisgICAgfQ0KKw0KKyAgICAvKg0KKyAgICAgKiBSZXR1cm5zIHRoZSBvcmRpbmFsIG51bWJlciBmb3IgdGhlIHNwZWNpZmllZCBkYXkgb2Ygd2VlayBpbiB0aGUgbW9udGguDQorICAgICAqIFRoZSB2YWxpZCByZXR1cm4gdmFsdWUgaXMgMSwgMiwgMywgNCBvciAtMS4NCisgICAgICovDQorICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldERheU9mV2Vla0luTW9udGgoaW50IHllYXIsIGludCBtb250aCwgaW50IGRheU9mTW9udGgpIHsNCisgICAgICAgIGludCB3ZWVrSW5Nb250aCA9IChkYXlPZk1vbnRoICsgNikvNzsNCisgICAgICAgIGlmICh3ZWVrSW5Nb250aCA9PSA0KSB7DQorICAgICAgICAgICAgaWYgKGRheU9mTW9udGggKyA3ID4gbW9udGhMZW5ndGgoeWVhciwgbW9udGgpKSB7DQorICAgICAgICAgICAgICAgIHdlZWtJbk1vbnRoID0gLTE7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgfSBlbHNlIGlmICh3ZWVrSW5Nb250aCA9PSA1KSB7DQorICAgICAgICAgICAgd2Vla0luTW9udGggPSAtMTsNCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiB3ZWVrSW5Nb250aDsNCisgICAgfQ0KK30NCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0dyZWdvcmlhbkNhbGVuZGFyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0dyZWdvcmlhbkNhbGVuZGFyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzBmZDUyMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvR3JlZ29yaWFuQ2FsZW5kYXIuamF2YQpAQCAtMCwwICsxLDE0NjIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworCisvKioKKyAqIHtAY29kZSBHcmVnb3JpYW5DYWxlbmRhcn0gaXMgYSBjb25jcmV0ZSBzdWJjbGFzcyBvZiB7QGxpbmsgQ2FsZW5kYXJ9CisgKiBhbmQgcHJvdmlkZXMgdGhlIHN0YW5kYXJkIGNhbGVuZGFyIHVzZWQgYnkgbW9zdCBvZiB0aGUgd29ybGQuCisgKgorICogPHA+CisgKiBUaGUgc3RhbmRhcmQgKEdyZWdvcmlhbikgY2FsZW5kYXIgaGFzIDIgZXJhcywgQkMgYW5kIEFELgorICoKKyAqIDxwPgorICogVGhpcyBpbXBsZW1lbnRhdGlvbiBoYW5kbGVzIGEgc2luZ2xlIGRpc2NvbnRpbnVpdHksIHdoaWNoIGNvcnJlc3BvbmRzIGJ5CisgKiBkZWZhdWx0IHRvIHRoZSBkYXRlIHRoZSBHcmVnb3JpYW4gY2FsZW5kYXIgd2FzIGluc3RpdHV0ZWQgKE9jdG9iZXIgMTUsIDE1ODIKKyAqIGluIHNvbWUgY291bnRyaWVzLCBsYXRlciBpbiBvdGhlcnMpLiBUaGUgY3V0b3ZlciBkYXRlIG1heSBiZSBjaGFuZ2VkIGJ5IHRoZQorICogY2FsbGVyIGJ5IGNhbGxpbmcge0Bjb2RlIHNldEdyZWdvcmlhbkNoYW5nZSgpfS4KKyAqCisgKiA8cD4KKyAqIEhpc3RvcmljYWxseSwgaW4gdGhvc2UgY291bnRyaWVzIHdoaWNoIGFkb3B0ZWQgdGhlIEdyZWdvcmlhbiBjYWxlbmRhciBmaXJzdCwKKyAqIE9jdG9iZXIgNCwgMTU4MiB3YXMgdGh1cyBmb2xsb3dlZCBieSBPY3RvYmVyIDE1LCAxNTgyLiBUaGlzIGNhbGVuZGFyIG1vZGVscworICogdGhpcyBjb3JyZWN0bHkuIEJlZm9yZSB0aGUgR3JlZ29yaWFuIGN1dG92ZXIsIHtAY29kZSBHcmVnb3JpYW5DYWxlbmRhcn0KKyAqIGltcGxlbWVudHMgdGhlIEp1bGlhbiBjYWxlbmRhci4gVGhlIG9ubHkgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBHcmVnb3JpYW4gYW5kCisgKiB0aGUgSnVsaWFuIGNhbGVuZGFyIGlzIHRoZSBsZWFwIHllYXIgcnVsZS4gVGhlIEp1bGlhbiBjYWxlbmRhciBzcGVjaWZpZXMgbGVhcAorICogeWVhcnMgZXZlcnkgZm91ciB5ZWFycywgd2hlcmVhcyB0aGUgR3JlZ29yaWFuIGNhbGVuZGFyIG9taXRzIGNlbnR1cnkgeWVhcnMKKyAqIHdoaWNoIGFyZSBub3QgZGl2aXNpYmxlIGJ5IDQwMC4KKyAqCisgKiA8cD4KKyAqIHtAY29kZSBHcmVnb3JpYW5DYWxlbmRhcn0gaW1wbGVtZW50cyA8ZW0+cHJvbGVwdGljPC9lbT4gR3JlZ29yaWFuCisgKiBhbmQgSnVsaWFuIGNhbGVuZGFycy4gVGhhdCBpcywgZGF0ZXMgYXJlIGNvbXB1dGVkIGJ5IGV4dHJhcG9sYXRpbmcgdGhlCisgKiBjdXJyZW50IHJ1bGVzIGluZGVmaW5pdGVseSBmYXIgYmFja3dhcmQgYW5kIGZvcndhcmQgaW4gdGltZS4gQXMgYSByZXN1bHQsCisgKiB7QGNvZGUgR3JlZ29yaWFuQ2FsZW5kYXJ9IG1heSBiZSB1c2VkIGZvciBhbGwgeWVhcnMgdG8gZ2VuZXJhdGUKKyAqIG1lYW5pbmdmdWwgYW5kIGNvbnNpc3RlbnQgcmVzdWx0cy4gSG93ZXZlciwgZGF0ZXMgb2J0YWluZWQgdXNpbmcKKyAqIHtAY29kZSBHcmVnb3JpYW5DYWxlbmRhcn0gYXJlIGhpc3RvcmljYWxseSBhY2N1cmF0ZSBvbmx5IGZyb20gTWFyY2ggMSwKKyAqIDQgQUQgb253YXJkLCB3aGVuIG1vZGVybiBKdWxpYW4gY2FsZW5kYXIgcnVsZXMgd2VyZSBhZG9wdGVkLiBCZWZvcmUgdGhpcworICogZGF0ZSwgbGVhcCB5ZWFyIHJ1bGVzIHdlcmUgYXBwbGllZCBpcnJlZ3VsYXJseSwgYW5kIGJlZm9yZSA0NSBCQyB0aGUgSnVsaWFuCisgKiBjYWxlbmRhciBkaWQgbm90IGV2ZW4gZXhpc3QuCisgKgorICogPHA+CisgKiBQcmlvciB0byB0aGUgaW5zdGl0dXRpb24gb2YgdGhlIEdyZWdvcmlhbiBjYWxlbmRhciwgTmV3IFllYXIncyBEYXkgd2FzIE1hcmNoCisgKiAyNS4gVG8gYXZvaWQgY29uZnVzaW9uLCB0aGlzIGNhbGVuZGFyIGFsd2F5cyB1c2VzIEphbnVhcnkgMS4gQSBtYW51YWwKKyAqIGFkanVzdG1lbnQgbWF5IGJlIG1hZGUgaWYgZGVzaXJlZCBmb3IgZGF0ZXMgdGhhdCBhcmUgcHJpb3IgdG8gdGhlIEdyZWdvcmlhbgorICogY2hhbmdlb3ZlciBhbmQgd2hpY2ggZmFsbCBiZXR3ZWVuIEphbnVhcnkgMSBhbmQgTWFyY2ggMjQuCisgKgorICogPHA+CisgKiBWYWx1ZXMgY2FsY3VsYXRlZCBmb3IgdGhlIHtAY29kZSBXRUVLX09GX1lFQVJ9IGZpZWxkIHJhbmdlIGZyb20gMSB0bworICogNTMuIFdlZWsgMSBmb3IgYSB5ZWFyIGlzIHRoZSBlYXJsaWVzdCBzZXZlbiBkYXkgcGVyaW9kIHN0YXJ0aW5nIG9uCisgKiB7QGNvZGUgZ2V0Rmlyc3REYXlPZldlZWsoKX0gdGhhdCBjb250YWlucyBhdCBsZWFzdAorICoge0Bjb2RlIGdldE1pbmltYWxEYXlzSW5GaXJzdFdlZWsoKX0gZGF5cyBmcm9tIHRoYXQgeWVhci4gSXQgdGh1cworICogZGVwZW5kcyBvbiB0aGUgdmFsdWVzIG9mIHtAY29kZSBnZXRNaW5pbWFsRGF5c0luRmlyc3RXZWVrKCl9LAorICoge0Bjb2RlIGdldEZpcnN0RGF5T2ZXZWVrKCl9LCBhbmQgdGhlIGRheSBvZiB0aGUgd2VlayBvZiBKYW51YXJ5IDEuCisgKiBXZWVrcyBiZXR3ZWVuIHdlZWsgMSBvZiBvbmUgeWVhciBhbmQgd2VlayAxIG9mIHRoZSBmb2xsb3dpbmcgeWVhciBhcmUKKyAqIG51bWJlcmVkIHNlcXVlbnRpYWxseSBmcm9tIDIgdG8gNTIgb3IgNTMgKGFzIG5lZWRlZCkuCisgKgorICogPHA+CisgKiBGb3IgZXhhbXBsZSwgSmFudWFyeSAxLCAxOTk4IHdhcyBhIFRodXJzZGF5LiBJZgorICoge0Bjb2RlIGdldEZpcnN0RGF5T2ZXZWVrKCl9IGlzIHtAY29kZSBNT05EQVl9IGFuZAorICoge0Bjb2RlIGdldE1pbmltYWxEYXlzSW5GaXJzdFdlZWsoKX0gaXMgNCAodGhlc2UgYXJlIHRoZSB2YWx1ZXMKKyAqIHJlZmxlY3RpbmcgSVNPIDg2MDEgYW5kIG1hbnkgbmF0aW9uYWwgc3RhbmRhcmRzKSwgdGhlbiB3ZWVrIDEgb2YgMTk5OCBzdGFydHMKKyAqIG9uIERlY2VtYmVyIDI5LCAxOTk3LCBhbmQgZW5kcyBvbiBKYW51YXJ5IDQsIDE5OTguIElmLCBob3dldmVyLAorICoge0Bjb2RlIGdldEZpcnN0RGF5T2ZXZWVrKCl9IGlzIHtAY29kZSBTVU5EQVl9LCB0aGVuIHdlZWsgMSBvZgorICogMTk5OCBzdGFydHMgb24gSmFudWFyeSA0LCAxOTk4LCBhbmQgZW5kcyBvbiBKYW51YXJ5IDEwLCAxOTk4OyB0aGUgZmlyc3QgdGhyZWUKKyAqIGRheXMgb2YgMTk5OCB0aGVuIGFyZSBwYXJ0IG9mIHdlZWsgNTMgb2YgMTk5Ny4KKyAqCisgKiA8cD4KKyAqIFZhbHVlcyBjYWxjdWxhdGVkIGZvciB0aGUge0Bjb2RlIFdFRUtfT0ZfTU9OVEh9IGZpZWxkIHJhbmdlIGZyb20gMCBvcgorICogMSB0byA0IG9yIDUuIFdlZWsgMSBvZiBhIG1vbnRoICh0aGUgZGF5cyB3aXRoIDxjb2RlPldFRUtfT0ZfTU9OVEggPQorICogMTwvY29kZT4pCisgKiBpcyB0aGUgZWFybGllc3Qgc2V0IG9mIGF0IGxlYXN0IHtAY29kZSBnZXRNaW5pbWFsRGF5c0luRmlyc3RXZWVrKCl9CisgKiBjb250aWd1b3VzIGRheXMgaW4gdGhhdCBtb250aCwgZW5kaW5nIG9uIHRoZSBkYXkgYmVmb3JlCisgKiB7QGNvZGUgZ2V0Rmlyc3REYXlPZldlZWsoKX0uIFVubGlrZSB3ZWVrIDEgb2YgYSB5ZWFyLCB3ZWVrIDEgb2YgYQorICogbW9udGggbWF5IGJlIHNob3J0ZXIgdGhhbiA3IGRheXMsIG5lZWQgbm90IHN0YXJ0IG9uCisgKiB7QGNvZGUgZ2V0Rmlyc3REYXlPZldlZWsoKX0sIGFuZCB3aWxsIG5vdCBpbmNsdWRlIGRheXMgb2YgdGhlCisgKiBwcmV2aW91cyBtb250aC4gRGF5cyBvZiBhIG1vbnRoIGJlZm9yZSB3ZWVrIDEgaGF2ZSBhCisgKiB7QGNvZGUgV0VFS19PRl9NT05USH0gb2YgMC4KKyAqCisgKiA8cD4KKyAqIEZvciBleGFtcGxlLCBpZiB7QGNvZGUgZ2V0Rmlyc3REYXlPZldlZWsoKX0gaXMge0Bjb2RlIFNVTkRBWX0KKyAqIGFuZCB7QGNvZGUgZ2V0TWluaW1hbERheXNJbkZpcnN0V2VlaygpfSBpcyA0LCB0aGVuIHRoZSBmaXJzdCB3ZWVrIG9mCisgKiBKYW51YXJ5IDE5OTggaXMgU3VuZGF5LCBKYW51YXJ5IDQgdGhyb3VnaCBTYXR1cmRheSwgSmFudWFyeSAxMC4gVGhlc2UgZGF5cworICogaGF2ZSBhIHtAY29kZSBXRUVLX09GX01PTlRIfSBvZiAxLiBUaHVyc2RheSwgSmFudWFyeSAxIHRocm91Z2gKKyAqIFNhdHVyZGF5LCBKYW51YXJ5IDMgaGF2ZSBhIHtAY29kZSBXRUVLX09GX01PTlRIfSBvZiAwLiBJZgorICoge0Bjb2RlIGdldE1pbmltYWxEYXlzSW5GaXJzdFdlZWsoKX0gaXMgY2hhbmdlZCB0byAzLCB0aGVuIEphbnVhcnkgMQorICogdGhyb3VnaCBKYW51YXJ5IDMgaGF2ZSBhIHtAY29kZSBXRUVLX09GX01PTlRIfSBvZiAxLgorICoKKyAqIDxwPgorICogPHN0cm9uZz5FeGFtcGxlOjwvc3Ryb25nPiA8YmxvY2txdW90ZT4KKyAqCisgKiA8cHJlPgorICogLy8gZ2V0IHRoZSBzdXBwb3J0ZWQgaWRzIGZvciBHTVQtMDg6MDAgKFBhY2lmaWMgU3RhbmRhcmQgVGltZSkKKyAqIFN0cmluZ1tdIGlkcyA9IFRpbWVab25lLmdldEF2YWlsYWJsZUlEcygtOCAqIDYwICogNjAgKiAxMDAwKTsKKyAqIC8vIGlmIG5vIGlkcyB3ZXJlIHJldHVybmVkLCBzb21ldGhpbmcgaXMgd3JvbmcuIGdldCBvdXQuCisgKiBpZiAoaWRzLmxlbmd0aCA9PSAwKQorICogICAgIFN5c3RlbS5leGl0KDApOworICoKKyAqICAvLyBiZWdpbiBvdXRwdXQKKyAqIFN5c3RlbS5vdXQucHJpbnRsbigiQ3VycmVudCBUaW1lIik7CisgKgorICogLy8gY3JlYXRlIGEgUGFjaWZpYyBTdGFuZGFyZCBUaW1lIHRpbWUgem9uZQorICogU2ltcGxlVGltZVpvbmUgcGR0ID0gbmV3IFNpbXBsZVRpbWVab25lKC04ICogNjAgKiA2MCAqIDEwMDAsIGlkc1swXSk7CisgKgorICogLy8gc2V0IHVwIHJ1bGVzIGZvciBkYXlsaWdodCBzYXZpbmdzIHRpbWUKKyAqIHBkdC5zZXRTdGFydFJ1bGUoQ2FsZW5kYXIuQVBSSUwsIDEsIENhbGVuZGFyLlNVTkRBWSwgMiAqIDYwICogNjAgKiAxMDAwKTsKKyAqIHBkdC5zZXRFbmRSdWxlKENhbGVuZGFyLk9DVE9CRVIsIC0xLCBDYWxlbmRhci5TVU5EQVksIDIgKiA2MCAqIDYwICogMTAwMCk7CisgKgorICogLy8gY3JlYXRlIGEgR3JlZ29yaWFuQ2FsZW5kYXIgd2l0aCB0aGUgUGFjaWZpYyBEYXlsaWdodCB0aW1lIHpvbmUKKyAqIC8vIGFuZCB0aGUgY3VycmVudCBkYXRlIGFuZCB0aW1lCisgKiBDYWxlbmRhciBjYWxlbmRhciA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcihwZHQpOworICogRGF0ZSB0cmlhbFRpbWUgPSBuZXcgRGF0ZSgpOworICogY2FsZW5kYXIuc2V0VGltZSh0cmlhbFRpbWUpOworICoKKyAqIC8vIHByaW50IG91dCBhIGJ1bmNoIG9mIGludGVyZXN0aW5nIHRoaW5ncworICogU3lzdGVtLm91dC5wcmludGxuKCJFUkE6ICIgKyBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuRVJBKSk7CisgKiBTeXN0ZW0ub3V0LnByaW50bG4oIllFQVI6ICIgKyBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuWUVBUikpOworICogU3lzdGVtLm91dC5wcmludGxuKCJNT05USDogIiArIGNhbGVuZGFyLmdldChDYWxlbmRhci5NT05USCkpOworICogU3lzdGVtLm91dC5wcmludGxuKCJXRUVLX09GX1lFQVI6ICIgKyBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuV0VFS19PRl9ZRUFSKSk7CisgKiBTeXN0ZW0ub3V0LnByaW50bG4oIldFRUtfT0ZfTU9OVEg6ICIgKyBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuV0VFS19PRl9NT05USCkpOworICogU3lzdGVtLm91dC5wcmludGxuKCJEQVRFOiAiICsgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRBVEUpKTsKKyAqIFN5c3RlbS5vdXQucHJpbnRsbigiREFZX09GX01PTlRIOiAiICsgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCkpOworICogU3lzdGVtLm91dC5wcmludGxuKCJEQVlfT0ZfWUVBUjogIiArIGNhbGVuZGFyLmdldChDYWxlbmRhci5EQVlfT0ZfWUVBUikpOworICogU3lzdGVtLm91dC5wcmludGxuKCJEQVlfT0ZfV0VFSzogIiArIGNhbGVuZGFyLmdldChDYWxlbmRhci5EQVlfT0ZfV0VFSykpOworICogU3lzdGVtLm91dC5wcmludGxuKCJEQVlfT0ZfV0VFS19JTl9NT05USDogIgorICogICAgICAgICAgICAgICAgICAgICsgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRBWV9PRl9XRUVLX0lOX01PTlRIKSk7CisgKiBTeXN0ZW0ub3V0LnByaW50bG4oIkFNX1BNOiAiICsgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkFNX1BNKSk7CisgKiBTeXN0ZW0ub3V0LnByaW50bG4oIkhPVVI6ICIgKyBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuSE9VUikpOworICogU3lzdGVtLm91dC5wcmludGxuKCJIT1VSX09GX0RBWTogIiArIGNhbGVuZGFyLmdldChDYWxlbmRhci5IT1VSX09GX0RBWSkpOworICogU3lzdGVtLm91dC5wcmludGxuKCJNSU5VVEU6ICIgKyBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuTUlOVVRFKSk7CisgKiBTeXN0ZW0ub3V0LnByaW50bG4oIlNFQ09ORDogIiArIGNhbGVuZGFyLmdldChDYWxlbmRhci5TRUNPTkQpKTsKKyAqIFN5c3RlbS5vdXQucHJpbnRsbigiTUlMTElTRUNPTkQ6ICIgKyBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuTUlMTElTRUNPTkQpKTsKKyAqIFN5c3RlbS5vdXQucHJpbnRsbigiWk9ORV9PRkZTRVQ6ICIKKyAqICAgICAgICAgICAgICAgICAgICArIChjYWxlbmRhci5nZXQoQ2FsZW5kYXIuWk9ORV9PRkZTRVQpLyg2MCo2MCoxMDAwKSkpOworICogU3lzdGVtLm91dC5wcmludGxuKCJEU1RfT0ZGU0VUOiAiCisgKiAgICAgICAgICAgICAgICAgICAgKyAoY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRTVF9PRkZTRVQpLyg2MCo2MCoxMDAwKSkpOworCisgKiBTeXN0ZW0ub3V0LnByaW50bG4oIkN1cnJlbnQgVGltZSwgd2l0aCBob3VyIHJlc2V0IHRvIDMiKTsKKyAqIGNhbGVuZGFyLmNsZWFyKENhbGVuZGFyLkhPVVJfT0ZfREFZKTsgLy8gc28gZG9lc24ndCBvdmVycmlkZQorICogY2FsZW5kYXIuc2V0KENhbGVuZGFyLkhPVVIsIDMpOworICogU3lzdGVtLm91dC5wcmludGxuKCJFUkE6ICIgKyBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuRVJBKSk7CisgKiBTeXN0ZW0ub3V0LnByaW50bG4oIllFQVI6ICIgKyBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuWUVBUikpOworICogU3lzdGVtLm91dC5wcmludGxuKCJNT05USDogIiArIGNhbGVuZGFyLmdldChDYWxlbmRhci5NT05USCkpOworICogU3lzdGVtLm91dC5wcmludGxuKCJXRUVLX09GX1lFQVI6ICIgKyBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuV0VFS19PRl9ZRUFSKSk7CisgKiBTeXN0ZW0ub3V0LnByaW50bG4oIldFRUtfT0ZfTU9OVEg6ICIgKyBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuV0VFS19PRl9NT05USCkpOworICogU3lzdGVtLm91dC5wcmludGxuKCJEQVRFOiAiICsgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRBVEUpKTsKKyAqIFN5c3RlbS5vdXQucHJpbnRsbigiREFZX09GX01PTlRIOiAiICsgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCkpOworICogU3lzdGVtLm91dC5wcmludGxuKCJEQVlfT0ZfWUVBUjogIiArIGNhbGVuZGFyLmdldChDYWxlbmRhci5EQVlfT0ZfWUVBUikpOworICogU3lzdGVtLm91dC5wcmludGxuKCJEQVlfT0ZfV0VFSzogIiArIGNhbGVuZGFyLmdldChDYWxlbmRhci5EQVlfT0ZfV0VFSykpOworICogU3lzdGVtLm91dC5wcmludGxuKCJEQVlfT0ZfV0VFS19JTl9NT05USDogIgorICogICAgICAgICAgICAgICAgICAgICsgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRBWV9PRl9XRUVLX0lOX01PTlRIKSk7CisgKiBTeXN0ZW0ub3V0LnByaW50bG4oIkFNX1BNOiAiICsgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkFNX1BNKSk7CisgKiBTeXN0ZW0ub3V0LnByaW50bG4oIkhPVVI6ICIgKyBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuSE9VUikpOworICogU3lzdGVtLm91dC5wcmludGxuKCJIT1VSX09GX0RBWTogIiArIGNhbGVuZGFyLmdldChDYWxlbmRhci5IT1VSX09GX0RBWSkpOworICogU3lzdGVtLm91dC5wcmludGxuKCJNSU5VVEU6ICIgKyBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuTUlOVVRFKSk7CisgKiBTeXN0ZW0ub3V0LnByaW50bG4oIlNFQ09ORDogIiArIGNhbGVuZGFyLmdldChDYWxlbmRhci5TRUNPTkQpKTsKKyAqIFN5c3RlbS5vdXQucHJpbnRsbigiTUlMTElTRUNPTkQ6ICIgKyBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuTUlMTElTRUNPTkQpKTsKKyAqIFN5c3RlbS5vdXQucHJpbnRsbigiWk9ORV9PRkZTRVQ6ICIKKyAqICAgICAgICArIChjYWxlbmRhci5nZXQoQ2FsZW5kYXIuWk9ORV9PRkZTRVQpLyg2MCo2MCoxMDAwKSkpOyAvLyBpbiBob3VycworICogU3lzdGVtLm91dC5wcmludGxuKCJEU1RfT0ZGU0VUOiAiCisgKiAgICAgICAgKyAoY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRTVF9PRkZTRVQpLyg2MCo2MCoxMDAwKSkpOyAvLyBpbiBob3VycworICogPC9wcmU+CisgKgorICogPC9ibG9ja3F1b3RlPgorICoKKyAqIEBzZWUgQ2FsZW5kYXIKKyAqIEBzZWUgVGltZVpvbmUKKyAqLworcHVibGljIGNsYXNzIEdyZWdvcmlhbkNhbGVuZGFyIGV4dGVuZHMgQ2FsZW5kYXIgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTgxMjUxMDA4MzQ3Mjk5NjMzMjdMOworCisgICAgLyoqCisgICAgICogVmFsdWUgZm9yIHRoZSBCQyBlcmEuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkMgPSAwOworCisgICAgLyoqCisgICAgICogVmFsdWUgZm9yIHRoZSBBRCBlcmEuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUQgPSAxOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBkZWZhdWx0R3JlZ29yaWFuQ3V0b3ZlciA9IC0xMjIxOTI5MjgwMDAwMGw7CisKKyAgICBwcml2YXRlIGxvbmcgZ3JlZ29yaWFuQ3V0b3ZlciA9IGRlZmF1bHRHcmVnb3JpYW5DdXRvdmVyOworCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IGNoYW5nZVllYXIgPSAxNTgyOworCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IGp1bGlhblNrZXcgPSAoKGNoYW5nZVllYXIgLSAyMDAwKSAvIDQwMCkKKyAgICAgICAgICAgICsganVsaWFuRXJyb3IoKSAtICgoY2hhbmdlWWVhciAtIDIwMDApIC8gMTAwKTsKKworICAgIHN0YXRpYyBieXRlW10gRGF5c0luTW9udGggPSBuZXcgYnl0ZVtdIHsgMzEsIDI4LCAzMSwgMzAsIDMxLCAzMCwgMzEsIDMxLAorICAgICAgICAgICAgMzAsIDMxLCAzMCwgMzEgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGludFtdIERheXNJblllYXIgPSBuZXcgaW50W10geyAwLCAzMSwgNTksIDkwLCAxMjAsIDE1MSwgMTgxLAorICAgICAgICAgICAgMjEyLCAyNDMsIDI3MywgMzA0LCAzMzQgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGludFtdIG1heGltdW1zID0gbmV3IGludFtdIHsgMSwgMjkyMjc4OTk0LCAxMSwgNTMsIDYsIDMxLAorICAgICAgICAgICAgMzY2LCA3LCA2LCAxLCAxMSwgMjMsIDU5LCA1OSwgOTk5LCAxNCAqIDM2MDAgKiAxMDAwLCA3MjAwMDAwIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBpbnRbXSBtaW5pbXVtcyA9IG5ldyBpbnRbXSB7IDAsIDEsIDAsIDEsIDAsIDEsIDEsIDEsIDEsIDAsCisgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAtMTMgKiAzNjAwICogMTAwMCwgMCB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50W10gbGVhc3RNYXhpbXVtcyA9IG5ldyBpbnRbXSB7IDEsIDI5MjI2OTA1NCwgMTEsIDUwLCAzLAorICAgICAgICAgICAgMjgsIDM1NSwgNywgMywgMSwgMTEsIDIzLCA1OSwgNTksIDk5OSwgNTA0MDAwMDAsIDEyMDAwMDAgfTsKKworICAgIHByaXZhdGUgYm9vbGVhbiBpc0NhY2hlZDsKKworICAgIHByaXZhdGUgaW50W10gY2FjaGVkRmllbGRzID0geyAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwIH07CisKKyAgICBwcml2YXRlIGxvbmcgbmV4dE1pZG5pZ2h0TWlsbGlzID0gMEw7CisKKyAgICBwcml2YXRlIGxvbmcgbGFzdE1pZG5pZ2h0TWlsbGlzID0gMEw7CisKKyAgICBwcml2YXRlIGludCBjdXJyZW50WWVhclNrZXcgPSAxMDsKKworICAgIHByaXZhdGUgaW50IGxhc3RZZWFyU2tldyA9IDA7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBHcmVnb3JpYW5DYWxlbmRhcn0gaW5pdGlhbGl6ZWQgdG8gdGhlIGN1cnJlbnQgZGF0ZSBhbmQKKyAgICAgKiB0aW1lIHdpdGggdGhlIGRlZmF1bHQge0Bjb2RlIExvY2FsZX0gYW5kIHtAY29kZSBUaW1lWm9uZX0uCisgICAgICovCisgICAgcHVibGljIEdyZWdvcmlhbkNhbGVuZGFyKCkgeworICAgICAgICB0aGlzKFRpbWVab25lLmdldERlZmF1bHQoKSwgTG9jYWxlLmdldERlZmF1bHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgR3JlZ29yaWFuQ2FsZW5kYXJ9IGluaXRpYWxpemVkIHRvIG1pZG5pZ2h0IGluIHRoZSBkZWZhdWx0CisgICAgICoge0Bjb2RlIFRpbWVab25lfSBhbmQge0Bjb2RlIExvY2FsZX0gb24gdGhlIHNwZWNpZmllZCBkYXRlLgorICAgICAqCisgICAgICogQHBhcmFtIHllYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB5ZWFyLgorICAgICAqIEBwYXJhbSBtb250aAorICAgICAqICAgICAgICAgICAgdGhlIG1vbnRoLgorICAgICAqIEBwYXJhbSBkYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXkgb2YgdGhlIG1vbnRoLgorICAgICAqLworICAgIHB1YmxpYyBHcmVnb3JpYW5DYWxlbmRhcihpbnQgeWVhciwgaW50IG1vbnRoLCBpbnQgZGF5KSB7CisgICAgICAgIHN1cGVyKFRpbWVab25lLmdldERlZmF1bHQoKSwgTG9jYWxlLmdldERlZmF1bHQoKSk7CisgICAgICAgIHNldCh5ZWFyLCBtb250aCwgZGF5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBHcmVnb3JpYW5DYWxlbmRhcn0gaW5pdGlhbGl6ZWQgdG8gdGhlIHNwZWNpZmllZCBkYXRlIGFuZAorICAgICAqIHRpbWUgaW4gdGhlIGRlZmF1bHQge0Bjb2RlIFRpbWVab25lfSBhbmQge0Bjb2RlIExvY2FsZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0geWVhcgorICAgICAqICAgICAgICAgICAgdGhlIHllYXIuCisgICAgICogQHBhcmFtIG1vbnRoCisgICAgICogICAgICAgICAgICB0aGUgbW9udGguCisgICAgICogQHBhcmFtIGRheQorICAgICAqICAgICAgICAgICAgdGhlIGRheSBvZiB0aGUgbW9udGguCisgICAgICogQHBhcmFtIGhvdXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBob3VyLgorICAgICAqIEBwYXJhbSBtaW51dGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBtaW51dGUuCisgICAgICovCisgICAgcHVibGljIEdyZWdvcmlhbkNhbGVuZGFyKGludCB5ZWFyLCBpbnQgbW9udGgsIGludCBkYXksIGludCBob3VyLCBpbnQgbWludXRlKSB7CisgICAgICAgIHN1cGVyKFRpbWVab25lLmdldERlZmF1bHQoKSwgTG9jYWxlLmdldERlZmF1bHQoKSk7CisgICAgICAgIHNldCh5ZWFyLCBtb250aCwgZGF5LCBob3VyLCBtaW51dGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEdyZWdvcmlhbkNhbGVuZGFyfSBpbml0aWFsaXplZCB0byB0aGUgc3BlY2lmaWVkIGRhdGUgYW5kCisgICAgICogdGltZSBpbiB0aGUgZGVmYXVsdCB7QGNvZGUgVGltZVpvbmV9IGFuZCB7QGNvZGUgTG9jYWxlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB5ZWFyCisgICAgICogICAgICAgICAgICB0aGUgeWVhci4KKyAgICAgKiBAcGFyYW0gbW9udGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtb250aC4KKyAgICAgKiBAcGFyYW0gZGF5CisgICAgICogICAgICAgICAgICB0aGUgZGF5IG9mIHRoZSBtb250aC4KKyAgICAgKiBAcGFyYW0gaG91cgorICAgICAqICAgICAgICAgICAgdGhlIGhvdXIuCisgICAgICogQHBhcmFtIG1pbnV0ZQorICAgICAqICAgICAgICAgICAgdGhlIG1pbnV0ZS4KKyAgICAgKiBAcGFyYW0gc2Vjb25kCisgICAgICogICAgICAgICAgICB0aGUgc2Vjb25kLgorICAgICAqLworICAgIHB1YmxpYyBHcmVnb3JpYW5DYWxlbmRhcihpbnQgeWVhciwgaW50IG1vbnRoLCBpbnQgZGF5LCBpbnQgaG91ciwKKyAgICAgICAgICAgIGludCBtaW51dGUsIGludCBzZWNvbmQpIHsKKyAgICAgICAgc3VwZXIoVGltZVpvbmUuZ2V0RGVmYXVsdCgpLCBMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICAgICAgc2V0KHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgc2Vjb25kKTsKKyAgICB9CisKKyAgICBHcmVnb3JpYW5DYWxlbmRhcihsb25nIG1pbGxpc2Vjb25kcykgeworICAgICAgICB0aGlzKGZhbHNlKTsKKyAgICAgICAgc2V0VGltZUluTWlsbGlzKG1pbGxpc2Vjb25kcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgR3JlZ29yaWFuQ2FsZW5kYXJ9IGluaXRpYWxpemVkIHRvIHRoZSBjdXJyZW50IGRhdGUgYW5kCisgICAgICogdGltZSBhbmQgdXNpbmcgdGhlIHNwZWNpZmllZCB7QGNvZGUgTG9jYWxlfSBhbmQgdGhlIGRlZmF1bHQge0Bjb2RlIFRpbWVab25lfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgTG9jYWxlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgR3JlZ29yaWFuQ2FsZW5kYXIoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICB0aGlzKFRpbWVab25lLmdldERlZmF1bHQoKSwgbG9jYWxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBHcmVnb3JpYW5DYWxlbmRhcn0gaW5pdGlhbGl6ZWQgdG8gdGhlIGN1cnJlbnQgZGF0ZSBhbmQKKyAgICAgKiB0aW1lIGFuZCB1c2luZyB0aGUgc3BlY2lmaWVkIHtAY29kZSBUaW1lWm9uZX0gYW5kIHRoZSBkZWZhdWx0IHtAY29kZSBMb2NhbGV9LgorICAgICAqCisgICAgICogQHBhcmFtIHRpbWV6b25lCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIFRpbWVab25lfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgR3JlZ29yaWFuQ2FsZW5kYXIoVGltZVpvbmUgdGltZXpvbmUpIHsKKyAgICAgICAgdGhpcyh0aW1lem9uZSwgTG9jYWxlLmdldERlZmF1bHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgR3JlZ29yaWFuQ2FsZW5kYXJ9IGluaXRpYWxpemVkIHRvIHRoZSBjdXJyZW50IGRhdGUgYW5kCisgICAgICogdGltZSBhbmQgdXNpbmcgdGhlIHNwZWNpZmllZCB7QGNvZGUgVGltZVpvbmV9IGFuZCB7QGNvZGUgTG9jYWxlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aW1lem9uZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBUaW1lWm9uZX0uCisgICAgICogQHBhcmFtIGxvY2FsZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBMb2NhbGV9LgorICAgICAqLworICAgIHB1YmxpYyBHcmVnb3JpYW5DYWxlbmRhcihUaW1lWm9uZSB0aW1lem9uZSwgTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBzdXBlcih0aW1lem9uZSwgbG9jYWxlKTsKKyAgICAgICAgc2V0VGltZUluTWlsbGlzKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgICB9CisKKyAgICBHcmVnb3JpYW5DYWxlbmRhcihib29sZWFuIGlnbm9yZWQpIHsKKyAgICAgICAgc3VwZXIoVGltZVpvbmUuZ2V0RGVmYXVsdCgpKTsKKyAgICAgICAgc2V0Rmlyc3REYXlPZldlZWsoU1VOREFZKTsKKyAgICAgICAgc2V0TWluaW1hbERheXNJbkZpcnN0V2VlaygxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgYW1vdW50IHRvIGEge0Bjb2RlIENhbGVuZGFyfSBmaWVsZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDYWxlbmRhcn0gZmllbGQgdG8gbW9kaWZ5LgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGFtb3VudCB0byBhZGQgdG8gdGhlIGZpZWxkLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGZpZWxkIGlzIERTVF9PRkZTRVQgb3IgWk9ORV9PRkZTRVQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYWRkKGludCBmaWVsZCwgaW50IHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZpZWxkIDwgMCB8fCBmaWVsZCA+PSBaT05FX09GRlNFVCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaXNDYWNoZWQgPSBmYWxzZTsKKworICAgICAgICBpZiAoZmllbGQgPT0gRVJBKSB7CisgICAgICAgICAgICBjb21wbGV0ZSgpOworICAgICAgICAgICAgaWYgKGZpZWxkc1tFUkFdID09IEFEKSB7CisgICAgICAgICAgICAgICAgaWYgKHZhbHVlID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzZXQoRVJBLCBCQyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA8PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc2V0KEVSQSwgQUQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY29tcGxldGUoKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChmaWVsZCA9PSBZRUFSIHx8IGZpZWxkID09IE1PTlRIKSB7CisgICAgICAgICAgICBjb21wbGV0ZSgpOworICAgICAgICAgICAgaWYgKGZpZWxkID09IE1PTlRIKSB7CisgICAgICAgICAgICAgICAgaW50IG1vbnRoID0gZmllbGRzW01PTlRIXSArIHZhbHVlOworICAgICAgICAgICAgICAgIGlmIChtb250aCA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAobW9udGggLSAxMSkgLyAxMjsKKyAgICAgICAgICAgICAgICAgICAgbW9udGggPSAxMiArIChtb250aCAlIDEyKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IG1vbnRoIC8gMTI7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHNldChNT05USCwgbW9udGggJSAxMik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzZXQoWUVBUiwgZmllbGRzW1lFQVJdICsgdmFsdWUpOworICAgICAgICAgICAgaW50IGRheXMgPSBkYXlzSW5Nb250aChpc0xlYXBZZWFyKGZpZWxkc1tZRUFSXSksIGZpZWxkc1tNT05USF0pOworICAgICAgICAgICAgaWYgKGZpZWxkc1tEQVRFXSA+IGRheXMpIHsKKyAgICAgICAgICAgICAgICBzZXQoREFURSwgZGF5cyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb21wbGV0ZSgpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgbG9uZyBtdWx0aXBsaWVyID0gMDsKKyAgICAgICAgZ2V0VGltZUluTWlsbGlzKCk7IC8vIFVwZGF0ZSB0aGUgdGltZQorICAgICAgICBzd2l0Y2ggKGZpZWxkKSB7CisgICAgICAgICAgICBjYXNlIE1JTExJU0VDT05EOgorICAgICAgICAgICAgICAgIHRpbWUgKz0gdmFsdWU7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFNFQ09ORDoKKyAgICAgICAgICAgICAgICB0aW1lICs9IHZhbHVlICogMTAwMEw7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIE1JTlVURToKKyAgICAgICAgICAgICAgICB0aW1lICs9IHZhbHVlICogNjAwMDBMOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBIT1VSOgorICAgICAgICAgICAgY2FzZSBIT1VSX09GX0RBWToKKyAgICAgICAgICAgICAgICB0aW1lICs9IHZhbHVlICogMzYwMDAwMEw7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIEFNX1BNOgorICAgICAgICAgICAgICAgIG11bHRpcGxpZXIgPSA0MzIwMDAwMEw7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERBVEU6CisgICAgICAgICAgICBjYXNlIERBWV9PRl9ZRUFSOgorICAgICAgICAgICAgY2FzZSBEQVlfT0ZfV0VFSzoKKyAgICAgICAgICAgICAgICBtdWx0aXBsaWVyID0gODY0MDAwMDBMOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBXRUVLX09GX1lFQVI6CisgICAgICAgICAgICBjYXNlIFdFRUtfT0ZfTU9OVEg6CisgICAgICAgICAgICBjYXNlIERBWV9PRl9XRUVLX0lOX01PTlRIOgorICAgICAgICAgICAgICAgIG11bHRpcGxpZXIgPSA2MDQ4MDAwMDBMOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG11bHRpcGxpZXIgPT0gMCkgeworICAgICAgICAgICAgYXJlRmllbGRzU2V0ID0gZmFsc2U7CisgICAgICAgICAgICBjb21wbGV0ZSgpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgbG9uZyBkZWx0YSA9IHZhbHVlICogbXVsdGlwbGllcjsKKworICAgICAgICAvKgorICAgICAgICAgKiBBdHRlbXB0IHRvIGtlZXAgdGhlIGhvdXIgYW5kIG1pbnV0ZSBjb25zdGFudCB3aGVuIHdlJ3ZlIGNyb3NzZWQgYSBEU1QKKyAgICAgICAgICogYm91bmRhcnkgYW5kIHRoZSB1c2VyJ3MgdW5pdHMgYXJlIEFNX1BNIG9yIGxhcmdlci4gVGhlIHR5cGljYWwKKyAgICAgICAgICogY29uc2VxdWVuY2UgaXMgdGhhdCBjYWxscyB0byBhZGQoREFURSwgMSkgd2lsbCBhZGQgMjMsIDI0IG9yIDI1IGhvdXJzCisgICAgICAgICAqIGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZSBEU1QgZ29lcyBmb3J3YXJkLCBjb25zdGFudCwgb3IgYmFja3dhcmQuCisgICAgICAgICAqCisgICAgICAgICAqIFdlIGtub3cgd2UndmUgY3Jvc3NlZCBhIERTVCBib3VuZGFyeSBpZiB0aGUgbmV3IHRpbWUgd2lsbCBoYXZlIGEKKyAgICAgICAgICogZGlmZmVyZW50IHRpbWV6b25lIG9mZnNldC4gQWRqdXN0IGJ5IGFkZGluZyB0aGUgZGlmZmVyZW5jZSBvZiB0aGUgdHdvCisgICAgICAgICAqIG9mZnNldHMuIFdlIGRvbid0IGFkanVzdCB3aGVuIGRvaW5nIHNvIHByZXZlbnRzIHRoZSBjaGFuZ2UgZnJvbQorICAgICAgICAgKiBjcm9zc2luZyB0aGUgYm91bmRhcnkuCisgICAgICAgICAqLworICAgICAgICBpbnQgem9uZU9mZnNldCA9IGdldFRpbWVab25lKCkuZ2V0UmF3T2Zmc2V0KCk7CisgICAgICAgIGludCBvZmZzZXRCZWZvcmUgPSBnZXRPZmZzZXQodGltZSArIHpvbmVPZmZzZXQpOworICAgICAgICBpbnQgb2Zmc2V0QWZ0ZXIgPSBnZXRPZmZzZXQodGltZSArIHpvbmVPZmZzZXQgKyBkZWx0YSk7CisgICAgICAgIGludCBkc3REZWx0YSA9IG9mZnNldEJlZm9yZSAtIG9mZnNldEFmdGVyOworICAgICAgICBpZiAoZ2V0T2Zmc2V0KHRpbWUgKyB6b25lT2Zmc2V0ICsgZGVsdGEgKyBkc3REZWx0YSkgPT0gb2Zmc2V0QWZ0ZXIpIHsKKyAgICAgICAgICAgIGRlbHRhICs9IGRzdERlbHRhOworICAgICAgICB9CisKKyAgICAgICAgdGltZSArPSBkZWx0YTsKKyAgICAgICAgYXJlRmllbGRzU2V0ID0gZmFsc2U7CisgICAgICAgIGNvbXBsZXRlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEdyZWdvcmlhbkNhbGVuZGFyfSB3aXRoIHRoZSBzYW1lIHByb3BlcnRpZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc2hhbGxvdyBjb3B5IG9mIHRoaXMge0Bjb2RlIEdyZWdvcmlhbkNhbGVuZGFyfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICBHcmVnb3JpYW5DYWxlbmRhciB0aGlzQ2xvbmUgPSAoR3JlZ29yaWFuQ2FsZW5kYXIpIHN1cGVyLmNsb25lKCk7CisgICAgICAgIHRoaXNDbG9uZS5jYWNoZWRGaWVsZHMgPSBjYWNoZWRGaWVsZHMuY2xvbmUoKTsKKyAgICAgICAgcmV0dXJuIHRoaXNDbG9uZTsKKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIHZvaWQgZnVsbEZpZWxkc0NhbGMobG9uZyB0aW1lVmFsLCBpbnQgbWlsbGlzLCBpbnQgem9uZU9mZnNldCkgeworICAgICAgICBsb25nIGRheXMgPSB0aW1lVmFsIC8gODY0MDAwMDA7CisKKyAgICAgICAgaWYgKG1pbGxpcyA8IDApIHsKKyAgICAgICAgICAgIG1pbGxpcyArPSA4NjQwMDAwMDsKKyAgICAgICAgICAgIGRheXMtLTsKKyAgICAgICAgfQorICAgICAgICAvLyBDYW5ub3QgYWRkIFpPTkVfT0ZGU0VUIHRvIHRpbWUgYXMgaXQgbWlnaHQgb3ZlcmZsb3cKKyAgICAgICAgbWlsbGlzICs9IHpvbmVPZmZzZXQ7CisgICAgICAgIHdoaWxlIChtaWxsaXMgPCAwKSB7CisgICAgICAgICAgICBtaWxsaXMgKz0gODY0MDAwMDA7CisgICAgICAgICAgICBkYXlzLS07CisgICAgICAgIH0KKyAgICAgICAgd2hpbGUgKG1pbGxpcyA+PSA4NjQwMDAwMCkgeworICAgICAgICAgICAgbWlsbGlzIC09IDg2NDAwMDAwOworICAgICAgICAgICAgZGF5cysrOworICAgICAgICB9CisKKyAgICAgICAgaW50IGRheU9mWWVhciA9IGNvbXB1dGVZZWFyQW5kRGF5KGRheXMsIHRpbWVWYWwgKyB6b25lT2Zmc2V0KTsKKyAgICAgICAgZmllbGRzW0RBWV9PRl9ZRUFSXSA9IGRheU9mWWVhcjsKKyAgICAgICAgaWYoZmllbGRzW1lFQVJdID09IGNoYW5nZVllYXIgJiYgZ3JlZ29yaWFuQ3V0b3ZlciA8PSB0aW1lVmFsICsgem9uZU9mZnNldCl7CisgICAgICAgICAgICBkYXlPZlllYXIgKz0gY3VycmVudFllYXJTa2V3OworICAgICAgICB9CisgICAgICAgIGludCBtb250aCA9IGRheU9mWWVhciAvIDMyOworICAgICAgICBib29sZWFuIGxlYXBZZWFyID0gaXNMZWFwWWVhcihmaWVsZHNbWUVBUl0pOworICAgICAgICBpbnQgZGF0ZSA9IGRheU9mWWVhciAtIGRheXNJblllYXIobGVhcFllYXIsIG1vbnRoKTsKKyAgICAgICAgaWYgKGRhdGUgPiBkYXlzSW5Nb250aChsZWFwWWVhciwgbW9udGgpKSB7CisgICAgICAgICAgICBkYXRlIC09IGRheXNJbk1vbnRoKGxlYXBZZWFyLCBtb250aCk7CisgICAgICAgICAgICBtb250aCsrOworICAgICAgICB9CisgICAgICAgIGZpZWxkc1tEQVlfT0ZfV0VFS10gPSBtb2Q3KGRheXMgLSAzKSArIDE7CisgICAgICAgIGludCBkc3RPZmZzZXQgPSBmaWVsZHNbWUVBUl0gPD0gMCA/IDAgOiBnZXRUaW1lWm9uZSgpLmdldE9mZnNldChBRCwKKyAgICAgICAgICAgICAgICBmaWVsZHNbWUVBUl0sIG1vbnRoLCBkYXRlLCBmaWVsZHNbREFZX09GX1dFRUtdLCBtaWxsaXMpOworICAgICAgICBpZiAoZmllbGRzW1lFQVJdID4gMCkgeworICAgICAgICAgICAgZHN0T2Zmc2V0IC09IHpvbmVPZmZzZXQ7CisgICAgICAgIH0KKyAgICAgICAgZmllbGRzW0RTVF9PRkZTRVRdID0gZHN0T2Zmc2V0OworICAgICAgICBpZiAoZHN0T2Zmc2V0ICE9IDApIHsKKyAgICAgICAgICAgIGxvbmcgb2xkRGF5cyA9IGRheXM7CisgICAgICAgICAgICBtaWxsaXMgKz0gZHN0T2Zmc2V0OworICAgICAgICAgICAgaWYgKG1pbGxpcyA8IDApIHsKKyAgICAgICAgICAgICAgICBtaWxsaXMgKz0gODY0MDAwMDA7CisgICAgICAgICAgICAgICAgZGF5cy0tOworICAgICAgICAgICAgfSBlbHNlIGlmIChtaWxsaXMgPj0gODY0MDAwMDApIHsKKyAgICAgICAgICAgICAgICBtaWxsaXMgLT0gODY0MDAwMDA7CisgICAgICAgICAgICAgICAgZGF5cysrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG9sZERheXMgIT0gZGF5cykgeworICAgICAgICAgICAgICAgIGRheU9mWWVhciA9IGNvbXB1dGVZZWFyQW5kRGF5KGRheXMsIHRpbWVWYWwgLSB6b25lT2Zmc2V0CisgICAgICAgICAgICAgICAgICAgICAgICArIGRzdE9mZnNldCk7CisgICAgICAgICAgICAgICAgZmllbGRzW0RBWV9PRl9ZRUFSXSA9IGRheU9mWWVhcjsKKyAgICAgICAgICAgICAgICBpZihmaWVsZHNbWUVBUl0gPT0gY2hhbmdlWWVhciAmJiBncmVnb3JpYW5DdXRvdmVyIDw9IHRpbWVWYWwgLSB6b25lT2Zmc2V0ICsgZHN0T2Zmc2V0KXsKKyAgICAgICAgICAgICAgICAgICAgZGF5T2ZZZWFyICs9IGN1cnJlbnRZZWFyU2tldzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbW9udGggPSBkYXlPZlllYXIgLyAzMjsKKyAgICAgICAgICAgICAgICBsZWFwWWVhciA9IGlzTGVhcFllYXIoZmllbGRzW1lFQVJdKTsKKyAgICAgICAgICAgICAgICBkYXRlID0gZGF5T2ZZZWFyIC0gZGF5c0luWWVhcihsZWFwWWVhciwgbW9udGgpOworICAgICAgICAgICAgICAgIGlmIChkYXRlID4gZGF5c0luTW9udGgobGVhcFllYXIsIG1vbnRoKSkgeworICAgICAgICAgICAgICAgICAgICBkYXRlIC09IGRheXNJbk1vbnRoKGxlYXBZZWFyLCBtb250aCk7CisgICAgICAgICAgICAgICAgICAgIG1vbnRoKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZpZWxkc1tEQVlfT0ZfV0VFS10gPSBtb2Q3KGRheXMgLSAzKSArIDE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmaWVsZHNbTUlMTElTRUNPTkRdID0gKG1pbGxpcyAlIDEwMDApOworICAgICAgICBtaWxsaXMgLz0gMTAwMDsKKyAgICAgICAgZmllbGRzW1NFQ09ORF0gPSAobWlsbGlzICUgNjApOworICAgICAgICBtaWxsaXMgLz0gNjA7CisgICAgICAgIGZpZWxkc1tNSU5VVEVdID0gKG1pbGxpcyAlIDYwKTsKKyAgICAgICAgbWlsbGlzIC89IDYwOworICAgICAgICBmaWVsZHNbSE9VUl9PRl9EQVldID0gKG1pbGxpcyAlIDI0KTsKKyAgICAgICAgZmllbGRzW0FNX1BNXSA9IGZpZWxkc1tIT1VSX09GX0RBWV0gPiAxMSA/IDEgOiAwOworICAgICAgICBmaWVsZHNbSE9VUl0gPSBmaWVsZHNbSE9VUl9PRl9EQVldICUgMTI7CisKKyAgICAgICAgaWYgKGZpZWxkc1tZRUFSXSA8PSAwKSB7CisgICAgICAgICAgICBmaWVsZHNbRVJBXSA9IEJDOworICAgICAgICAgICAgZmllbGRzW1lFQVJdID0gLWZpZWxkc1tZRUFSXSArIDE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmaWVsZHNbRVJBXSA9IEFEOworICAgICAgICB9CisgICAgICAgIGZpZWxkc1tNT05USF0gPSBtb250aDsKKyAgICAgICAgZmllbGRzW0RBVEVdID0gZGF0ZTsKKyAgICAgICAgZmllbGRzW0RBWV9PRl9XRUVLX0lOX01PTlRIXSA9IChkYXRlIC0gMSkgLyA3ICsgMTsKKyAgICAgICAgZmllbGRzW1dFRUtfT0ZfTU9OVEhdID0gKGRhdGUgLSAxICsgbW9kNyhkYXlzIC0gZGF0ZSAtIDIKKyAgICAgICAgICAgICAgICAtIChnZXRGaXJzdERheU9mV2VlaygpIC0gMSkpKSAvIDcgKyAxOworICAgICAgICBpbnQgZGF5c0Zyb21TdGFydCA9IG1vZDcoZGF5cyAtIDMgLSAoZmllbGRzW0RBWV9PRl9ZRUFSXSAtIDEpCisgICAgICAgICAgICAgICAgLSAoZ2V0Rmlyc3REYXlPZldlZWsoKSAtIDEpKTsKKyAgICAgICAgaW50IHdlZWsgPSAoZmllbGRzW0RBWV9PRl9ZRUFSXSAtIDEgKyBkYXlzRnJvbVN0YXJ0KSAvIDcKKyAgICAgICAgICAgICAgICArICg3IC0gZGF5c0Zyb21TdGFydCA+PSBnZXRNaW5pbWFsRGF5c0luRmlyc3RXZWVrKCkgPyAxIDogMCk7CisgICAgICAgIGlmICh3ZWVrID09IDApIHsKKyAgICAgICAgICAgIGZpZWxkc1tXRUVLX09GX1lFQVJdID0gNyAtIG1vZDcoZGF5c0Zyb21TdGFydAorICAgICAgICAgICAgICAgICAgICAtIChpc0xlYXBZZWFyKGZpZWxkc1tZRUFSXSAtIDEpID8gMiA6IDEpKSA+PSBnZXRNaW5pbWFsRGF5c0luRmlyc3RXZWVrKCkgPyA1MworICAgICAgICAgICAgICAgICAgICA6IDUyOworICAgICAgICB9IGVsc2UgaWYgKGZpZWxkc1tEQVlfT0ZfWUVBUl0gPj0gKGxlYXBZZWFyID8gMzY3IDogMzY2KQorICAgICAgICAgICAgICAgIC0gbW9kNyhkYXlzRnJvbVN0YXJ0ICsgKGxlYXBZZWFyID8gMiA6IDEpKSkgeworICAgICAgICAgICAgZmllbGRzW1dFRUtfT0ZfWUVBUl0gPSA3IC0gbW9kNyhkYXlzRnJvbVN0YXJ0ICsgKGxlYXBZZWFyID8gMiA6IDEpKSA+PSBnZXRNaW5pbWFsRGF5c0luRmlyc3RXZWVrKCkgPyAxCisgICAgICAgICAgICAgICAgICAgIDogd2VlazsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZpZWxkc1tXRUVLX09GX1lFQVJdID0gd2VlazsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgdm9pZCBjYWNoZWRGaWVsZHNDaGVja0FuZEdldChsb25nIHRpbWVWYWwsCisgICAgICAgICAgICBsb25nIG5ld1RpbWVNaWxsaXMsIGxvbmcgbmV3VGltZU1pbGxpc0FkanVzdGVkLCBpbnQgbWlsbGlzLAorICAgICAgICAgICAgaW50IHpvbmVPZmZzZXQpIHsKKyAgICAgICAgaW50IGRzdE9mZnNldCA9IGZpZWxkc1tEU1RfT0ZGU0VUXTsKKyAgICAgICAgaWYgKCFpc0NhY2hlZAorICAgICAgICAgICAgICAgIHx8IG5ld1RpbWVNaWxsaXMgPj0gbmV4dE1pZG5pZ2h0TWlsbGlzCisgICAgICAgICAgICAgICAgfHwgbmV3VGltZU1pbGxpcyA8PSBsYXN0TWlkbmlnaHRNaWxsaXMKKyAgICAgICAgICAgICAgICB8fCBjYWNoZWRGaWVsZHNbNF0gIT0gem9uZU9mZnNldAorICAgICAgICAgICAgICAgIHx8IChkc3RPZmZzZXQgPT0gMCAmJiAobmV3VGltZU1pbGxpc0FkanVzdGVkID49IG5leHRNaWRuaWdodE1pbGxpcykpCisgICAgICAgICAgICAgICAgfHwgKGRzdE9mZnNldCAhPSAwICYmIChuZXdUaW1lTWlsbGlzQWRqdXN0ZWQgPD0gbGFzdE1pZG5pZ2h0TWlsbGlzKSkpIHsKKyAgICAgICAgICAgIGZ1bGxGaWVsZHNDYWxjKHRpbWVWYWwsIG1pbGxpcywgem9uZU9mZnNldCk7CisgICAgICAgICAgICBpc0NhY2hlZCA9IGZhbHNlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmllbGRzW1lFQVJdID0gY2FjaGVkRmllbGRzWzBdOworICAgICAgICAgICAgZmllbGRzW01PTlRIXSA9IGNhY2hlZEZpZWxkc1sxXTsKKyAgICAgICAgICAgIGZpZWxkc1tEQVRFXSA9IGNhY2hlZEZpZWxkc1syXTsKKyAgICAgICAgICAgIGZpZWxkc1tEQVlfT0ZfV0VFS10gPSBjYWNoZWRGaWVsZHNbM107CisgICAgICAgICAgICBmaWVsZHNbRVJBXSA9IGNhY2hlZEZpZWxkc1s1XTsKKyAgICAgICAgICAgIGZpZWxkc1tXRUVLX09GX1lFQVJdID0gY2FjaGVkRmllbGRzWzZdOworICAgICAgICAgICAgZmllbGRzW1dFRUtfT0ZfTU9OVEhdID0gY2FjaGVkRmllbGRzWzddOworICAgICAgICAgICAgZmllbGRzW0RBWV9PRl9ZRUFSXSA9IGNhY2hlZEZpZWxkc1s4XTsKKyAgICAgICAgICAgIGZpZWxkc1tEQVlfT0ZfV0VFS19JTl9NT05USF0gPSBjYWNoZWRGaWVsZHNbOV07CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBjb21wdXRlRmllbGRzKCkgeworICAgICAgICBUaW1lWm9uZSB0aW1lWm9uZSA9IGdldFRpbWVab25lKCk7CisgICAgICAgIGludCBkc3RPZmZzZXQgPSB0aW1lWm9uZS5pbkRheWxpZ2h0VGltZShuZXcgRGF0ZSh0aW1lKSkgPyB0aW1lWm9uZS5nZXREU1RTYXZpbmdzKCkgOiAwOworICAgICAgICBpbnQgem9uZU9mZnNldCA9IHRpbWVab25lLmdldFJhd09mZnNldCgpOworICAgICAgICBmaWVsZHNbRFNUX09GRlNFVF0gPSBkc3RPZmZzZXQ7CisgICAgICAgIGZpZWxkc1taT05FX09GRlNFVF0gPSB6b25lT2Zmc2V0OworCisgICAgICAgIGludCBtaWxsaXMgPSAoaW50KSAodGltZSAlIDg2NDAwMDAwKTsKKyAgICAgICAgaW50IHNhdmVkTWlsbGlzID0gbWlsbGlzOworICAgICAgICAvLyBjb21wdXRlIHdpdGhvdXQgYSBjaGFuZ2UgaW4gZGF5bGlnaHQgc2F2aW5nIHRpbWUKKyAgICAgICAgaW50IG9mZnNldCA9IHpvbmVPZmZzZXQgKyBkc3RPZmZzZXQ7CisgICAgICAgIGxvbmcgbmV3VGltZSA9IHRpbWUgKyBvZmZzZXQ7CisKKyAgICAgICAgaWYgKHRpbWUgPiAwTCAmJiBuZXdUaW1lIDwgMEwgJiYgb2Zmc2V0ID4gMCkgeworICAgICAgICAgICAgbmV3VGltZSA9IDB4N2ZmZmZmZmZmZmZmZmZmZkw7CisgICAgICAgIH0gZWxzZSBpZiAodGltZSA8IDBMICYmIG5ld1RpbWUgPiAwTCAmJiBvZmZzZXQgPCAwKSB7CisgICAgICAgICAgICBuZXdUaW1lID0gMHg4MDAwMDAwMDAwMDAwMDAwTDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEZJWE1FOiBJIGRvbid0IHRoaW5rIHRoaXMgY2FjaGluZyBldmVyIHJlYWxseSBnZXRzIHVzZWQsIGJlY2F1c2UgaXQgcmVxdWlyZXMgdGhhdCB0aGUKKyAgICAgICAgLy8gdGltZSB6b25lIGRvZXNuJ3QgdXNlIGRheWxpZ2h0IHNhdmluZ3MgKGV2ZXIpLiBTbyB1bmxlc3MgeW91J3JlIHNvbWV3aGVyZSBsaWtlIFRhaXdhbi4uLgorICAgICAgICBpZiAoaXNDYWNoZWQpIHsKKyAgICAgICAgICAgIGlmIChtaWxsaXMgPCAwKSB7CisgICAgICAgICAgICAgICAgbWlsbGlzICs9IDg2NDAwMDAwOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBDYW5ub3QgYWRkIFpPTkVfT0ZGU0VUIHRvIHRpbWUgYXMgaXQgbWlnaHQgb3ZlcmZsb3cKKyAgICAgICAgICAgIG1pbGxpcyArPSB6b25lT2Zmc2V0OworICAgICAgICAgICAgbWlsbGlzICs9IGRzdE9mZnNldDsKKworICAgICAgICAgICAgaWYgKG1pbGxpcyA8IDApIHsKKyAgICAgICAgICAgICAgICBtaWxsaXMgKz0gODY0MDAwMDA7CisgICAgICAgICAgICB9IGVsc2UgaWYgKG1pbGxpcyA+PSA4NjQwMDAwMCkgeworICAgICAgICAgICAgICAgIG1pbGxpcyAtPSA4NjQwMDAwMDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZmllbGRzW01JTExJU0VDT05EXSA9IChtaWxsaXMgJSAxMDAwKTsKKyAgICAgICAgICAgIG1pbGxpcyAvPSAxMDAwOworICAgICAgICAgICAgZmllbGRzW1NFQ09ORF0gPSAobWlsbGlzICUgNjApOworICAgICAgICAgICAgbWlsbGlzIC89IDYwOworICAgICAgICAgICAgZmllbGRzW01JTlVURV0gPSAobWlsbGlzICUgNjApOworICAgICAgICAgICAgbWlsbGlzIC89IDYwOworICAgICAgICAgICAgZmllbGRzW0hPVVJfT0ZfREFZXSA9IChtaWxsaXMgJSAyNCk7CisgICAgICAgICAgICBtaWxsaXMgLz0gMjQ7CisgICAgICAgICAgICBmaWVsZHNbQU1fUE1dID0gZmllbGRzW0hPVVJfT0ZfREFZXSA+IDExID8gMSA6IDA7CisgICAgICAgICAgICBmaWVsZHNbSE9VUl0gPSBmaWVsZHNbSE9VUl9PRl9EQVldICUgMTI7CisKKyAgICAgICAgICAgIC8vIEZJWE1FOiB0aGlzIGhhcyB0byBiZSB3cm9uZzsgdXNlRGF5bGlnaHRUaW1lIGRvZXNuJ3QgbWVhbiB3aGF0IHRoZXkgdGhpbmsgaXQgbWVhbnMhCisgICAgICAgICAgICBsb25nIG5ld1RpbWVBZGp1c3RlZCA9IG5ld1RpbWU7CisgICAgICAgICAgICBpZiAodGltZVpvbmUudXNlRGF5bGlnaHRUaW1lKCkpIHsKKyAgICAgICAgICAgICAgICBpbnQgZHN0U2F2aW5ncyA9IHRpbWVab25lLmdldERTVFNhdmluZ3MoKTsKKyAgICAgICAgICAgICAgICBuZXdUaW1lQWRqdXN0ZWQgKz0gKGRzdE9mZnNldCA9PSAwKSA/IGRzdFNhdmluZ3MgOiAtZHN0U2F2aW5nczsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKG5ld1RpbWUgPiAwTCAmJiBuZXdUaW1lQWRqdXN0ZWQgPCAwTCAmJiBkc3RPZmZzZXQgPT0gMCkgeworICAgICAgICAgICAgICAgIG5ld1RpbWVBZGp1c3RlZCA9IDB4N2ZmZmZmZmZmZmZmZmZmZkw7CisgICAgICAgICAgICB9IGVsc2UgaWYgKG5ld1RpbWUgPCAwTCAmJiBuZXdUaW1lQWRqdXN0ZWQgPiAwTCAmJiBkc3RPZmZzZXQgIT0gMCkgeworICAgICAgICAgICAgICAgIG5ld1RpbWVBZGp1c3RlZCA9IDB4ODAwMDAwMDAwMDAwMDAwMEw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNhY2hlZEZpZWxkc0NoZWNrQW5kR2V0KHRpbWUsIG5ld1RpbWUsIG5ld1RpbWVBZGp1c3RlZCwKKyAgICAgICAgICAgICAgICAgICAgc2F2ZWRNaWxsaXMsIHpvbmVPZmZzZXQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZnVsbEZpZWxkc0NhbGModGltZSwgc2F2ZWRNaWxsaXMsIHpvbmVPZmZzZXQpOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBGSUVMRF9DT1VOVDsgaSsrKSB7CisgICAgICAgICAgICBpc1NldFtpXSA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICAvLyBDYWNoaW5nCisgICAgICAgIGlmICghaXNDYWNoZWQKKyAgICAgICAgICAgICAgICAmJiBuZXdUaW1lICE9IDB4N2ZmZmZmZmZmZmZmZmZmZkwKKyAgICAgICAgICAgICAgICAmJiBuZXdUaW1lICE9IDB4ODAwMDAwMDAwMDAwMDAwMEwKKyAgICAgICAgICAgICAgICAmJiAoIXRpbWVab25lLnVzZURheWxpZ2h0VGltZSgpIHx8IHRpbWVab25lIGluc3RhbmNlb2YgU2ltcGxlVGltZVpvbmUpKSB7CisgICAgICAgICAgICBpbnQgY2FjaGVNaWxsaXMgPSAwOworCisgICAgICAgICAgICBjYWNoZWRGaWVsZHNbMF0gPSBmaWVsZHNbWUVBUl07CisgICAgICAgICAgICBjYWNoZWRGaWVsZHNbMV0gPSBmaWVsZHNbTU9OVEhdOworICAgICAgICAgICAgY2FjaGVkRmllbGRzWzJdID0gZmllbGRzW0RBVEVdOworICAgICAgICAgICAgY2FjaGVkRmllbGRzWzNdID0gZmllbGRzW0RBWV9PRl9XRUVLXTsKKyAgICAgICAgICAgIGNhY2hlZEZpZWxkc1s0XSA9IHpvbmVPZmZzZXQ7CisgICAgICAgICAgICBjYWNoZWRGaWVsZHNbNV0gPSBmaWVsZHNbRVJBXTsKKyAgICAgICAgICAgIGNhY2hlZEZpZWxkc1s2XSA9IGZpZWxkc1tXRUVLX09GX1lFQVJdOworICAgICAgICAgICAgY2FjaGVkRmllbGRzWzddID0gZmllbGRzW1dFRUtfT0ZfTU9OVEhdOworICAgICAgICAgICAgY2FjaGVkRmllbGRzWzhdID0gZmllbGRzW0RBWV9PRl9ZRUFSXTsKKyAgICAgICAgICAgIGNhY2hlZEZpZWxkc1s5XSA9IGZpZWxkc1tEQVlfT0ZfV0VFS19JTl9NT05USF07CisKKyAgICAgICAgICAgIGNhY2hlTWlsbGlzICs9ICgyMyAtIGZpZWxkc1tIT1VSX09GX0RBWV0pICogNjAgKiA2MCAqIDEwMDA7CisgICAgICAgICAgICBjYWNoZU1pbGxpcyArPSAoNTkgLSBmaWVsZHNbTUlOVVRFXSkgKiA2MCAqIDEwMDA7CisgICAgICAgICAgICBjYWNoZU1pbGxpcyArPSAoNTkgLSBmaWVsZHNbU0VDT05EXSkgKiAxMDAwOworICAgICAgICAgICAgbmV4dE1pZG5pZ2h0TWlsbGlzID0gbmV3VGltZSArIGNhY2hlTWlsbGlzOworCisgICAgICAgICAgICBjYWNoZU1pbGxpcyA9IGZpZWxkc1tIT1VSX09GX0RBWV0gKiA2MCAqIDYwICogMTAwMDsKKyAgICAgICAgICAgIGNhY2hlTWlsbGlzICs9IGZpZWxkc1tNSU5VVEVdICogNjAgKiAxMDAwOworICAgICAgICAgICAgY2FjaGVNaWxsaXMgKz0gZmllbGRzW1NFQ09ORF0gKiAxMDAwOworICAgICAgICAgICAgbGFzdE1pZG5pZ2h0TWlsbGlzID0gbmV3VGltZSAtIGNhY2hlTWlsbGlzOworCisgICAgICAgICAgICBpc0NhY2hlZCA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBjb21wdXRlVGltZSgpIHsKKyAgICAgICAgaWYgKCFpc0xlbmllbnQoKSkgeworICAgICAgICAgICAgaWYgKGlzU2V0W0hPVVJfT0ZfREFZXSkgeworICAgICAgICAgICAgICAgIGlmIChmaWVsZHNbSE9VUl9PRl9EQVldIDwgMCB8fCBmaWVsZHNbSE9VUl9PRl9EQVldID4gMjMpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNTZXRbSE9VUl0gJiYgKGZpZWxkc1tIT1VSXSA8IDAgfHwgZmllbGRzW0hPVVJdID4gMTEpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGlzU2V0W01JTlVURV0gJiYgKGZpZWxkc1tNSU5VVEVdIDwgMCB8fCBmaWVsZHNbTUlOVVRFXSA+IDU5KSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpc1NldFtTRUNPTkRdICYmIChmaWVsZHNbU0VDT05EXSA8IDAgfHwgZmllbGRzW1NFQ09ORF0gPiA1OSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaXNTZXRbTUlMTElTRUNPTkRdCisgICAgICAgICAgICAgICAgICAgICYmIChmaWVsZHNbTUlMTElTRUNPTkRdIDwgMCB8fCBmaWVsZHNbTUlMTElTRUNPTkRdID4gOTk5KSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpc1NldFtXRUVLX09GX1lFQVJdCisgICAgICAgICAgICAgICAgICAgICYmIChmaWVsZHNbV0VFS19PRl9ZRUFSXSA8IDEgfHwgZmllbGRzW1dFRUtfT0ZfWUVBUl0gPiA1MykpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaXNTZXRbREFZX09GX1dFRUtdCisgICAgICAgICAgICAgICAgICAgICYmIChmaWVsZHNbREFZX09GX1dFRUtdIDwgMSB8fCBmaWVsZHNbREFZX09GX1dFRUtdID4gNykpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaXNTZXRbREFZX09GX1dFRUtfSU5fTU9OVEhdCisgICAgICAgICAgICAgICAgICAgICYmIChmaWVsZHNbREFZX09GX1dFRUtfSU5fTU9OVEhdIDwgMSB8fCBmaWVsZHNbREFZX09GX1dFRUtfSU5fTU9OVEhdID4gNikpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaXNTZXRbV0VFS19PRl9NT05USF0KKyAgICAgICAgICAgICAgICAgICAgJiYgKGZpZWxkc1tXRUVLX09GX01PTlRIXSA8IDEgfHwgZmllbGRzW1dFRUtfT0ZfTU9OVEhdID4gNikpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaXNTZXRbQU1fUE1dICYmIGZpZWxkc1tBTV9QTV0gIT0gQU0gJiYgZmllbGRzW0FNX1BNXSAhPSBQTSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpc1NldFtIT1VSXSAmJiAoZmllbGRzW0hPVVJdIDwgMCB8fCBmaWVsZHNbSE9VUl0gPiAxMSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaXNTZXRbWUVBUl0pIHsKKyAgICAgICAgICAgICAgICBpZiAoaXNTZXRbRVJBXSAmJiBmaWVsZHNbRVJBXSA9PSBCQworICAgICAgICAgICAgICAgICAgICAgICAgJiYgKGZpZWxkc1tZRUFSXSA8IDEgfHwgZmllbGRzW1lFQVJdID4gMjkyMjY5MDU0KSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChmaWVsZHNbWUVBUl0gPCAxIHx8IGZpZWxkc1tZRUFSXSA+IDI5MjI3ODk5NCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGlzU2V0W01PTlRIXSAmJiAoZmllbGRzW01PTlRIXSA8IDAgfHwgZmllbGRzW01PTlRIXSA+IDExKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGxvbmcgdGltZVZhbDsKKyAgICAgICAgbG9uZyBob3VyID0gMDsKKyAgICAgICAgaWYgKGlzU2V0W0hPVVJfT0ZfREFZXSAmJiBsYXN0VGltZUZpZWxkU2V0ICE9IEhPVVIpIHsKKyAgICAgICAgICAgIGhvdXIgPSBmaWVsZHNbSE9VUl9PRl9EQVldOworICAgICAgICB9IGVsc2UgaWYgKGlzU2V0W0hPVVJdKSB7CisgICAgICAgICAgICBob3VyID0gKGZpZWxkc1tBTV9QTV0gKiAxMikgKyBmaWVsZHNbSE9VUl07CisgICAgICAgIH0KKyAgICAgICAgdGltZVZhbCA9IGhvdXIgKiAzNjAwMDAwOworCisgICAgICAgIGlmIChpc1NldFtNSU5VVEVdKSB7CisgICAgICAgICAgICB0aW1lVmFsICs9ICgobG9uZykgZmllbGRzW01JTlVURV0pICogNjAwMDA7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlzU2V0W1NFQ09ORF0pIHsKKyAgICAgICAgICAgIHRpbWVWYWwgKz0gKChsb25nKSBmaWVsZHNbU0VDT05EXSkgKiAxMDAwOworICAgICAgICB9CisgICAgICAgIGlmIChpc1NldFtNSUxMSVNFQ09ORF0pIHsKKyAgICAgICAgICAgIHRpbWVWYWwgKz0gZmllbGRzW01JTExJU0VDT05EXTsKKyAgICAgICAgfQorCisgICAgICAgIGxvbmcgZGF5czsKKyAgICAgICAgaW50IHllYXIgPSBpc1NldFtZRUFSXSA/IGZpZWxkc1tZRUFSXSA6IDE5NzA7CisgICAgICAgIGlmIChpc1NldFtFUkFdKSB7CisgICAgICAgICAgICAvLyBBbHdheXMgdGVzdCBmb3IgdmFsaWQgRVJBLCBldmVuIGlmIHRoZSBDYWxlbmRhciBpcyBsZW5pZW50CisgICAgICAgICAgICBpZiAoZmllbGRzW0VSQV0gIT0gQkMgJiYgZmllbGRzW0VSQV0gIT0gQUQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZmllbGRzW0VSQV0gPT0gQkMpIHsKKyAgICAgICAgICAgICAgICB5ZWFyID0gMSAtIHllYXI7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIHdlZWtNb250aFNldCA9IGlzU2V0W1dFRUtfT0ZfTU9OVEhdCisgICAgICAgICAgICAgICAgfHwgaXNTZXRbREFZX09GX1dFRUtfSU5fTU9OVEhdOworICAgICAgICBib29sZWFuIHVzZU1vbnRoID0gKGlzU2V0W0RBVEVdIHx8IGlzU2V0W01PTlRIXSB8fCB3ZWVrTW9udGhTZXQpCisgICAgICAgICAgICAgICAgJiYgbGFzdERhdGVGaWVsZFNldCAhPSBEQVlfT0ZfWUVBUjsKKyAgICAgICAgaWYgKHVzZU1vbnRoCisgICAgICAgICAgICAgICAgJiYgKGxhc3REYXRlRmllbGRTZXQgPT0gREFZX09GX1dFRUsgfHwgbGFzdERhdGVGaWVsZFNldCA9PSBXRUVLX09GX1lFQVIpKSB7CisgICAgICAgICAgICBpZiAoaXNTZXRbV0VFS19PRl9ZRUFSXSAmJiBpc1NldFtEQVlfT0ZfV0VFS10pIHsKKyAgICAgICAgICAgICAgICB1c2VNb250aCA9IGxhc3REYXRlRmllbGRTZXQgIT0gV0VFS19PRl9ZRUFSICYmIHdlZWtNb250aFNldAorICAgICAgICAgICAgICAgICAgICAgICAgJiYgaXNTZXRbREFZX09GX1dFRUtdOworICAgICAgICAgICAgfSBlbHNlIGlmIChpc1NldFtEQVlfT0ZfWUVBUl0pIHsKKyAgICAgICAgICAgICAgICB1c2VNb250aCA9IGlzU2V0W0RBVEVdICYmIGlzU2V0W01PTlRIXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmICh1c2VNb250aCkgeworICAgICAgICAgICAgaW50IG1vbnRoID0gZmllbGRzW01PTlRIXTsKKyAgICAgICAgICAgIHllYXIgKz0gbW9udGggLyAxMjsKKyAgICAgICAgICAgIG1vbnRoICU9IDEyOworICAgICAgICAgICAgaWYgKG1vbnRoIDwgMCkgeworICAgICAgICAgICAgICAgIHllYXItLTsKKyAgICAgICAgICAgICAgICBtb250aCArPSAxMjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJvb2xlYW4gbGVhcFllYXIgPSBpc0xlYXBZZWFyKHllYXIpOworICAgICAgICAgICAgZGF5cyA9IGRheXNGcm9tQmFzZVllYXIoeWVhcikgKyBkYXlzSW5ZZWFyKGxlYXBZZWFyLCBtb250aCk7CisgICAgICAgICAgICBib29sZWFuIHVzZURhdGUgPSBpc1NldFtEQVRFXTsKKyAgICAgICAgICAgIGlmICh1c2VEYXRlCisgICAgICAgICAgICAgICAgICAgICYmIChsYXN0RGF0ZUZpZWxkU2V0ID09IERBWV9PRl9XRUVLCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgbGFzdERhdGVGaWVsZFNldCA9PSBXRUVLX09GX01PTlRIIHx8IGxhc3REYXRlRmllbGRTZXQgPT0gREFZX09GX1dFRUtfSU5fTU9OVEgpKSB7CisgICAgICAgICAgICAgICAgdXNlRGF0ZSA9ICEoaXNTZXRbREFZX09GX1dFRUtdICYmIHdlZWtNb250aFNldCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodXNlRGF0ZSkgeworICAgICAgICAgICAgICAgIGlmICghaXNMZW5pZW50KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIChmaWVsZHNbREFURV0gPCAxIHx8IGZpZWxkc1tEQVRFXSA+IGRheXNJbk1vbnRoKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWFwWWVhciwgbW9udGgpKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGRheXMgKz0gZmllbGRzW0RBVEVdIC0gMTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaW50IGRheU9mV2VlazsKKyAgICAgICAgICAgICAgICBpZiAoaXNTZXRbREFZX09GX1dFRUtdKSB7CisgICAgICAgICAgICAgICAgICAgIGRheU9mV2VlayA9IGZpZWxkc1tEQVlfT0ZfV0VFS10gLSAxOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGRheU9mV2VlayA9IGdldEZpcnN0RGF5T2ZXZWVrKCkgLSAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoaXNTZXRbV0VFS19PRl9NT05USF0KKyAgICAgICAgICAgICAgICAgICAgICAgICYmIGxhc3REYXRlRmllbGRTZXQgIT0gREFZX09GX1dFRUtfSU5fTU9OVEgpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHNrZXcgPSBtb2Q3KGRheXMgLSAzIC0gKGdldEZpcnN0RGF5T2ZXZWVrKCkgLSAxKSk7CisgICAgICAgICAgICAgICAgICAgIGRheXMgKz0gKGZpZWxkc1tXRUVLX09GX01PTlRIXSAtIDEpICogNworICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgbW9kNyhza2V3ICsgZGF5T2ZXZWVrIC0gKGRheXMgLSAzKSkgLSBza2V3OworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNTZXRbREFZX09GX1dFRUtfSU5fTU9OVEhdKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZHNbREFZX09GX1dFRUtfSU5fTU9OVEhdID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRheXMgKz0gbW9kNyhkYXlPZldlZWsgLSAoZGF5cyAtIDMpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIChmaWVsZHNbREFZX09GX1dFRUtfSU5fTU9OVEhdIC0gMSkgKiA3OworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgZGF5cyArPSBkYXlzSW5Nb250aChsZWFwWWVhciwgbW9udGgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgbW9kNyhkYXlPZldlZWsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIChkYXlzICsgZGF5c0luTW9udGgobGVhcFllYXIsIG1vbnRoKSAtIDMpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGZpZWxkc1tEQVlfT0ZfV0VFS19JTl9NT05USF0gKiA3OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc1NldFtEQVlfT0ZfV0VFS10pIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHNrZXcgPSBtb2Q3KGRheXMgLSAzIC0gKGdldEZpcnN0RGF5T2ZXZWVrKCkgLSAxKSk7CisgICAgICAgICAgICAgICAgICAgIGRheXMgKz0gbW9kNyhtb2Q3KHNrZXcgKyBkYXlPZldlZWsgLSAoZGF5cyAtIDMpKSAtIHNrZXcpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJvb2xlYW4gdXNlV2Vla1llYXIgPSBpc1NldFtXRUVLX09GX1lFQVJdCisgICAgICAgICAgICAgICAgICAgICYmIGxhc3REYXRlRmllbGRTZXQgIT0gREFZX09GX1lFQVI7CisgICAgICAgICAgICBpZiAodXNlV2Vla1llYXIgJiYgaXNTZXRbREFZX09GX1lFQVJdKSB7CisgICAgICAgICAgICAgICAgdXNlV2Vla1llYXIgPSBpc1NldFtEQVlfT0ZfV0VFS107CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkYXlzID0gZGF5c0Zyb21CYXNlWWVhcih5ZWFyKTsKKyAgICAgICAgICAgIGlmICh1c2VXZWVrWWVhcikgeworICAgICAgICAgICAgICAgIGludCBkYXlPZldlZWs7CisgICAgICAgICAgICAgICAgaWYgKGlzU2V0W0RBWV9PRl9XRUVLXSkgeworICAgICAgICAgICAgICAgICAgICBkYXlPZldlZWsgPSBmaWVsZHNbREFZX09GX1dFRUtdIC0gMTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBkYXlPZldlZWsgPSBnZXRGaXJzdERheU9mV2VlaygpIC0gMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaW50IHNrZXcgPSBtb2Q3KGRheXMgLSAzIC0gKGdldEZpcnN0RGF5T2ZXZWVrKCkgLSAxKSk7CisgICAgICAgICAgICAgICAgZGF5cyArPSAoZmllbGRzW1dFRUtfT0ZfWUVBUl0gLSAxKSAqIDcKKyAgICAgICAgICAgICAgICAgICAgICAgICsgbW9kNyhza2V3ICsgZGF5T2ZXZWVrIC0gKGRheXMgLSAzKSkgLSBza2V3OworICAgICAgICAgICAgICAgIGlmICg3IC0gc2tldyA8IGdldE1pbmltYWxEYXlzSW5GaXJzdFdlZWsoKSkgeworICAgICAgICAgICAgICAgICAgICBkYXlzICs9IDc7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmIChpc1NldFtEQVlfT0ZfWUVBUl0pIHsKKyAgICAgICAgICAgICAgICBpZiAoIWlzTGVuaWVudCgpCisgICAgICAgICAgICAgICAgICAgICAgICAmJiAoZmllbGRzW0RBWV9PRl9ZRUFSXSA8IDEgfHwgZmllbGRzW0RBWV9PRl9ZRUFSXSA+ICgzNjUgKyAoaXNMZWFwWWVhcih5ZWFyKSA/IDEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAwKSkpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZGF5cyArPSBmaWVsZHNbREFZX09GX1lFQVJdIC0gMTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNTZXRbREFZX09GX1dFRUtdKSB7CisgICAgICAgICAgICAgICAgZGF5cyArPSBtb2Q3KGZpZWxkc1tEQVlfT0ZfV0VFS10gLSAxIC0gKGRheXMgLSAzKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgbGFzdERhdGVGaWVsZFNldCA9IDA7CisKKyAgICAgICAgdGltZVZhbCArPSBkYXlzICogODY0MDAwMDA7CisgICAgICAgIC8vIFVzZSBsb2NhbCB0aW1lIHRvIGNvbXBhcmUgd2l0aCB0aGUgZ3JlZ29yaWFuIGNoYW5nZQorICAgICAgICBpZiAoeWVhciA9PSBjaGFuZ2VZZWFyCisgICAgICAgICAgICAgICAgJiYgdGltZVZhbCA+PSBncmVnb3JpYW5DdXRvdmVyICsganVsaWFuRXJyb3IoKSAqIDg2NDAwMDAwTCkgeworICAgICAgICAgICAgdGltZVZhbCAtPSBqdWxpYW5FcnJvcigpICogODY0MDAwMDBMOworICAgICAgICB9CisKKyAgICAgICAgLy8gSXQgaXMgbm90IHBvc3NpYmxlIHRvIHNpbXBseSBzdWJ0cmFjdCBnZXRPZmZzZXQodGltZVZhbCkgZnJvbSB0aW1lVmFsCisgICAgICAgIC8vIHRvIGdldCBVVEMuCisgICAgICAgIC8vIFRoZSB0cmljayBpcyBuZWVkZWQgZm9yIHRoZSBtb21lbnQgd2hlbiBEU1QgdHJhbnNpdGlvbiBvY2N1cnMsCisgICAgICAgIC8vIHNheSAxOjAwIGlzIGEgdHJhbnNpdGlvbiB0aW1lIHdoZW4gRFNUIG9mZnNldCBiZWNvbWVzICsxIGhvdXIsCisgICAgICAgIC8vIHRoZW4gd2FsbCB0aW1lIGluIHRoZSBpbnRlcnZhbCAxOjAwIC0gMjowMCBpcyBpbnZhbGlkIGFuZCBpcworICAgICAgICAvLyB0cmVhdGVkIGFzIFVUQyB0aW1lLgorICAgICAgICBsb25nIHRpbWVWYWxXaXRob3V0RFNUID0gdGltZVZhbCAtIGdldE9mZnNldCh0aW1lVmFsKQorICAgICAgICAgICAgICAgICsgZ2V0VGltZVpvbmUoKS5nZXRSYXdPZmZzZXQoKTsKKyAgICAgICAgdGltZVZhbCAtPSBnZXRPZmZzZXQodGltZVZhbFdpdGhvdXREU1QpOworICAgICAgICAvLyBOZWVkIHRvIHVwZGF0ZSB3YWxsIHRpbWUgaW4gZmllbGRzLCBzaW5jZSBpdCB3YXMgaW52YWxpZCBkdWUgdG8gRFNUCisgICAgICAgIC8vIHRyYW5zaXRpb24KKyAgICAgICAgdGhpcy50aW1lID0gdGltZVZhbDsKKyAgICAgICAgaWYgKHRpbWVWYWxXaXRob3V0RFNUICE9IHRpbWVWYWwpIHsKKyAgICAgICAgICAgIGNvbXB1dGVGaWVsZHMoKTsKKyAgICAgICAgICAgIGFyZUZpZWxkc1NldCA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGludCBjb21wdXRlWWVhckFuZERheShsb25nIGRheUNvdW50LCBsb25nIGxvY2FsVGltZSkgeworICAgICAgICBpbnQgeWVhciA9IDE5NzA7CisgICAgICAgIGxvbmcgZGF5cyA9IGRheUNvdW50OworICAgICAgICBpZiAobG9jYWxUaW1lIDwgZ3JlZ29yaWFuQ3V0b3ZlcikgeworICAgICAgICAgICAgZGF5cyAtPSBqdWxpYW5Ta2V3OworICAgICAgICB9CisgICAgICAgIGludCBhcHByb3hZZWFyczsKKworICAgICAgICB3aGlsZSAoKGFwcHJveFllYXJzID0gKGludCkgKGRheXMgLyAzNjUpKSAhPSAwKSB7CisgICAgICAgICAgICB5ZWFyID0geWVhciArIGFwcHJveFllYXJzOworICAgICAgICAgICAgZGF5cyA9IGRheUNvdW50IC0gZGF5c0Zyb21CYXNlWWVhcih5ZWFyKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZGF5cyA8IDApIHsKKyAgICAgICAgICAgIHllYXIgPSB5ZWFyIC0gMTsKKyAgICAgICAgICAgIGRheXMgPSBkYXlzICsgZGF5c0luWWVhcih5ZWFyKTsKKyAgICAgICAgfQorICAgICAgICBmaWVsZHNbWUVBUl0gPSB5ZWFyOworICAgICAgICByZXR1cm4gKGludCkgZGF5cyArIDE7CisgICAgfQorCisgICAgcHJpdmF0ZSBsb25nIGRheXNGcm9tQmFzZVllYXIoaW50IGl5ZWFyKSB7CisgICAgICAgIGxvbmcgeWVhciA9IGl5ZWFyOworCisgICAgICAgIGlmICh5ZWFyID49IDE5NzApIHsKKyAgICAgICAgICAgIGxvbmcgZGF5cyA9ICh5ZWFyIC0gMTk3MCkgKiAzNjUgKyAoKHllYXIgLSAxOTY5KSAvIDQpOworICAgICAgICAgICAgaWYgKHllYXIgPiBjaGFuZ2VZZWFyKSB7CisgICAgICAgICAgICAgICAgZGF5cyAtPSAoKHllYXIgLSAxOTAxKSAvIDEwMCkgLSAoKHllYXIgLSAxNjAxKSAvIDQwMCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmKHllYXIgPT0gY2hhbmdlWWVhcil7CisgICAgICAgICAgICAgICAgICAgIGRheXMgKz0gY3VycmVudFllYXJTa2V3OworICAgICAgICAgICAgICAgIH1lbHNlIGlmKHllYXIgPT0gY2hhbmdlWWVhciAtMSl7CisgICAgICAgICAgICAgICAgICAgIGRheXMgKz0gbGFzdFllYXJTa2V3OworICAgICAgICAgICAgICAgIH1lbHNleworICAgICAgICAgICAgICAgICAgICBkYXlzICs9IGp1bGlhblNrZXc7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGRheXM7CisgICAgICAgIH0gZWxzZSBpZiAoeWVhciA8PSBjaGFuZ2VZZWFyKSB7CisgICAgICAgICAgICByZXR1cm4gKHllYXIgLSAxOTcwKSAqIDM2NSArICgoeWVhciAtIDE5NzIpIC8gNCkgKyBqdWxpYW5Ta2V3OworICAgICAgICB9CisgICAgICAgIHJldHVybiAoeWVhciAtIDE5NzApICogMzY1ICsgKCh5ZWFyIC0gMTk3MikgLyA0KQorICAgICAgICAgICAgICAgIC0gKCh5ZWFyIC0gMjAwMCkgLyAxMDApICsgKCh5ZWFyIC0gMjAwMCkgLyA0MDApOworICAgIH0KKworICAgIHByaXZhdGUgaW50IGRheXNJbk1vbnRoKCkgeworICAgICAgICByZXR1cm4gZGF5c0luTW9udGgoaXNMZWFwWWVhcihmaWVsZHNbWUVBUl0pLCBmaWVsZHNbTU9OVEhdKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBkYXlzSW5Nb250aChib29sZWFuIGxlYXBZZWFyLCBpbnQgbW9udGgpIHsKKyAgICAgICAgaWYgKGxlYXBZZWFyICYmIG1vbnRoID09IEZFQlJVQVJZKSB7CisgICAgICAgICAgICByZXR1cm4gRGF5c0luTW9udGhbbW9udGhdICsgMTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBEYXlzSW5Nb250aFttb250aF07CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgZGF5c0luWWVhcihpbnQgeWVhcikgeworICAgICAgICBpbnQgZGF5c0luWWVhciA9IGlzTGVhcFllYXIoeWVhcikgPyAzNjYgOiAzNjU7CisgICAgICAgIGlmICh5ZWFyID09IGNoYW5nZVllYXIpIHsKKyAgICAgICAgICAgIGRheXNJblllYXIgLT0gY3VycmVudFllYXJTa2V3OworICAgICAgICB9CisgICAgICAgIGlmICh5ZWFyID09IGNoYW5nZVllYXIgLSAxKSB7CisgICAgICAgICAgICBkYXlzSW5ZZWFyIC09IGxhc3RZZWFyU2tldzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZGF5c0luWWVhcjsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBkYXlzSW5ZZWFyKGJvb2xlYW4gbGVhcFllYXIsIGludCBtb250aCkgeworICAgICAgICBpZiAobGVhcFllYXIgJiYgbW9udGggPiBGRUJSVUFSWSkgeworICAgICAgICAgICAgcmV0dXJuIERheXNJblllYXJbbW9udGhdICsgMTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBEYXlzSW5ZZWFyW21vbnRoXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIHtAY29kZSBPYmplY3R9IHRvIHRoaXMge0Bjb2RlIEdyZWdvcmlhbkNhbGVuZGFyfSBhbmQgcmV0dXJucyB3aGV0aGVyCisgICAgICogdGhleSBhcmUgZXF1YWwuIFRvIGJlIGVxdWFsLCB0aGUge0Bjb2RlIE9iamVjdH0gbXVzdCBiZSBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgR3JlZ29yaWFuQ2FsZW5kYXJ9IGFuZAorICAgICAqIGhhdmUgdGhlIHNhbWUgcHJvcGVydGllcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT2JqZWN0fSB0byBjb21wYXJlIHdpdGggdGhpcyB7QGNvZGUgR3JlZ29yaWFuQ2FsZW5kYXJ9LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBvYmplY3R9IGlzIGVxdWFsIHRvIHRoaXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBHcmVnb3JpYW5DYWxlbmRhcn0sIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHRpbWUgaXMgbm90IHNldCBhbmQgdGhlIHRpbWUgY2Fubm90IGJlIGNvbXB1dGVkCisgICAgICogICAgICAgICAgICAgICAgZnJvbSB0aGUgY3VycmVudCBmaWVsZCB2YWx1ZXMuCisgICAgICogQHNlZSAjaGFzaENvZGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBHcmVnb3JpYW5DYWxlbmRhcikpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2JqZWN0ID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqZWN0KQorICAgICAgICAgICAgICAgICYmIGdyZWdvcmlhbkN1dG92ZXIgPT0gKChHcmVnb3JpYW5DYWxlbmRhcikgb2JqZWN0KS5ncmVnb3JpYW5DdXRvdmVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1heGltdW0gdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBmaWVsZCBmb3IgdGhlIGN1cnJlbnQgZGF0ZS4gRm9yCisgICAgICogZXhhbXBsZSwgdGhlIG1heGltdW0gbnVtYmVyIG9mIGRheXMgaW4gdGhlIGN1cnJlbnQgbW9udGguCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmllbGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWVsZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgZmllbGQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRBY3R1YWxNYXhpbXVtKGludCBmaWVsZCkgeworICAgICAgICBpbnQgdmFsdWU7CisgICAgICAgIGlmICgodmFsdWUgPSBtYXhpbXVtc1tmaWVsZF0pID09IGxlYXN0TWF4aW11bXNbZmllbGRdKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICAgIH0KKworICAgICAgICBzd2l0Y2ggKGZpZWxkKSB7CisgICAgICAgICAgICBjYXNlIFdFRUtfT0ZfWUVBUjoKKyAgICAgICAgICAgIGNhc2UgV0VFS19PRl9NT05USDoKKyAgICAgICAgICAgICAgICBpc0NhY2hlZCA9IGZhbHNlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisKKyAgICAgICAgY29tcGxldGUoKTsKKyAgICAgICAgbG9uZyBvcmdUaW1lID0gdGltZTsKKyAgICAgICAgaW50IHJlc3VsdCA9IDA7CisgICAgICAgIHN3aXRjaCAoZmllbGQpIHsKKyAgICAgICAgICAgIGNhc2UgV0VFS19PRl9ZRUFSOgorICAgICAgICAgICAgICAgIHNldChEQVRFLCAzMSk7CisgICAgICAgICAgICAgICAgc2V0KE1PTlRILCBERUNFTUJFUik7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gZ2V0KFdFRUtfT0ZfWUVBUik7CisgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSAxKSB7CisgICAgICAgICAgICAgICAgICAgIHNldChEQVRFLCAzMSAtIDcpOworICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBnZXQoV0VFS19PRl9ZRUFSKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXJlRmllbGRzU2V0ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFdFRUtfT0ZfTU9OVEg6CisgICAgICAgICAgICAgICAgc2V0KERBVEUsIGRheXNJbk1vbnRoKCkpOworICAgICAgICAgICAgICAgIHJlc3VsdCA9IGdldChXRUVLX09GX01PTlRIKTsKKyAgICAgICAgICAgICAgICBhcmVGaWVsZHNTZXQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgREFURToKKyAgICAgICAgICAgICAgICByZXR1cm4gZGF5c0luTW9udGgoKTsKKyAgICAgICAgICAgIGNhc2UgREFZX09GX1lFQVI6CisgICAgICAgICAgICAgICAgcmV0dXJuIGRheXNJblllYXIoZmllbGRzW1lFQVJdKTsKKyAgICAgICAgICAgIGNhc2UgREFZX09GX1dFRUtfSU5fTU9OVEg6CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gZ2V0KERBWV9PRl9XRUVLX0lOX01PTlRIKQorICAgICAgICAgICAgICAgICAgICAgICAgKyAoKGRheXNJbk1vbnRoKCkgLSBnZXQoREFURSkpIC8gNyk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFlFQVI6CisgICAgICAgICAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgY2xvbmUgPSAoR3JlZ29yaWFuQ2FsZW5kYXIpIGNsb25lKCk7CisgICAgICAgICAgICAgICAgaWYgKGdldChFUkEpID09IEFEKSB7CisgICAgICAgICAgICAgICAgICAgIGNsb25lLnNldFRpbWVJbk1pbGxpcyhMb25nLk1BWF9WQUxVRSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgY2xvbmUuc2V0VGltZUluTWlsbGlzKExvbmcuTUlOX1ZBTFVFKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gY2xvbmUuZ2V0KFlFQVIpOworICAgICAgICAgICAgICAgIGNsb25lLnNldChZRUFSLCBnZXQoWUVBUikpOworICAgICAgICAgICAgICAgIGlmIChjbG9uZS5iZWZvcmUodGhpcykpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0LS07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBEU1RfT0ZGU0VUOgorICAgICAgICAgICAgICAgIHJlc3VsdCA9IGdldE1heGltdW0oRFNUX09GRlNFVCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgdGltZSA9IG9yZ1RpbWU7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbWluaW11bSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZpZWxkIGZvciB0aGUgY3VycmVudCBkYXRlLiBGb3IKKyAgICAgKiB0aGUgZ3JlZ29yaWFuIGNhbGVuZGFyLCB0aGlzIHZhbHVlIGlzIHRoZSBzYW1lIGFzCisgICAgICoge0Bjb2RlIGdldE1pbmltdW0oKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmllbGQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWVsZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBtaW5pbXVtIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgZmllbGQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRBY3R1YWxNaW5pbXVtKGludCBmaWVsZCkgeworICAgICAgICByZXR1cm4gZ2V0TWluaW11bShmaWVsZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZ3JlYXRlc3QgbWluaW11bSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZpZWxkLiBGb3IgdGhlIGdyZWdvcmlhbgorICAgICAqIGNhbGVuZGFyLCB0aGlzIHZhbHVlIGlzIHRoZSBzYW1lIGFzIHtAY29kZSBnZXRNaW5pbXVtKCl9LgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICB0aGUgZmllbGQuCisgICAgICogQHJldHVybiB0aGUgZ3JlYXRlc3QgbWluaW11bSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZpZWxkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0R3JlYXRlc3RNaW5pbXVtKGludCBmaWVsZCkgeworICAgICAgICByZXR1cm4gbWluaW11bXNbZmllbGRdOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGdyZWdvcmlhbiBjaGFuZ2UgZGF0ZSBvZiB0aGlzIGNhbGVuZGFyLiBUaGlzIGlzIHRoZSBkYXRlIG9uCisgICAgICogd2hpY2ggdGhlIGdyZWdvcmlhbiBjYWxlbmRhciBjYW1lIGludG8gZWZmZWN0LgorICAgICAqCisgICAgICogQHJldHVybiBhIHtAY29kZSBEYXRlfSB3aGljaCByZXByZXNlbnRzIHRoZSBncmVnb3JpYW4gY2hhbmdlIGRhdGUuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIERhdGUgZ2V0R3JlZ29yaWFuQ2hhbmdlKCkgeworICAgICAgICByZXR1cm4gbmV3IERhdGUoZ3JlZ29yaWFuQ3V0b3Zlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc21hbGxlc3QgbWF4aW11bSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZpZWxkLiBGb3IgZXhhbXBsZSwgMjgKKyAgICAgKiBmb3IgdGhlIGRheSBvZiBtb250aCBmaWVsZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgdGhlIGZpZWxkLgorICAgICAqIEByZXR1cm4gdGhlIHNtYWxsZXN0IG1heGltdW0gdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBmaWVsZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldExlYXN0TWF4aW11bShpbnQgZmllbGQpIHsKKyAgICAgICAgLy8gcmV0dXJuIHZhbHVlIGZvciBXRUVLX09GX1lFQVIgc2hvdWxkIG1ha2UgY29ycmVzcG9uZGluZyBjaGFuZ2VzIHdoZW4KKyAgICAgICAgLy8gdGhlIGdyZWdvcmlhbiBjaGFuZ2UgZGF0ZSBoYXZlIGJlZW4gcmVzZXQuCisgICAgICAgIGlmIChncmVnb3JpYW5DdXRvdmVyICE9IGRlZmF1bHRHcmVnb3JpYW5DdXRvdmVyCisgICAgICAgICAgICAgICAgJiYgZmllbGQgPT0gV0VFS19PRl9ZRUFSKSB7CisgICAgICAgICAgICBsb25nIGN1cnJlbnRUaW1lSW5NaWxsaXMgPSB0aW1lOworICAgICAgICAgICAgc2V0VGltZUluTWlsbGlzKGdyZWdvcmlhbkN1dG92ZXIpOworICAgICAgICAgICAgaW50IGFjdHVhbCA9IGdldEFjdHVhbE1heGltdW0oZmllbGQpOworICAgICAgICAgICAgc2V0VGltZUluTWlsbGlzKGN1cnJlbnRUaW1lSW5NaWxsaXMpOworICAgICAgICAgICAgcmV0dXJuIGFjdHVhbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbGVhc3RNYXhpbXVtc1tmaWVsZF07CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZ3JlYXRlc3QgbWF4aW11bSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZpZWxkLiBGb3IgZXhhbXBsZSwgMzEKKyAgICAgKiBmb3IgdGhlIGRheSBvZiBtb250aCBmaWVsZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgdGhlIGZpZWxkLgorICAgICAqIEByZXR1cm4gdGhlIGdyZWF0ZXN0IG1heGltdW0gdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBmaWVsZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldE1heGltdW0oaW50IGZpZWxkKSB7CisgICAgICAgIHJldHVybiBtYXhpbXVtc1tmaWVsZF07CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc21hbGxlc3QgbWluaW11bSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZpZWxkLgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICB0aGUgZmllbGQuCisgICAgICogQHJldHVybiB0aGUgc21hbGxlc3QgbWluaW11bSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZpZWxkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0TWluaW11bShpbnQgZmllbGQpIHsKKyAgICAgICAgcmV0dXJuIG1pbmltdW1zW2ZpZWxkXTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBnZXRPZmZzZXQobG9uZyBsb2NhbFRpbWUpIHsKKyAgICAgICAgVGltZVpvbmUgdGltZVpvbmUgPSBnZXRUaW1lWm9uZSgpOworCisgICAgICAgIGxvbmcgZGF5Q291bnQgPSBsb2NhbFRpbWUgLyA4NjQwMDAwMDsKKyAgICAgICAgaW50IG1pbGxpcyA9IChpbnQpIChsb2NhbFRpbWUgJSA4NjQwMDAwMCk7CisgICAgICAgIGlmIChtaWxsaXMgPCAwKSB7CisgICAgICAgICAgICBtaWxsaXMgKz0gODY0MDAwMDA7CisgICAgICAgICAgICBkYXlDb3VudC0tOworICAgICAgICB9CisKKyAgICAgICAgaW50IHllYXIgPSAxOTcwOworICAgICAgICBsb25nIGRheXMgPSBkYXlDb3VudDsKKyAgICAgICAgaWYgKGxvY2FsVGltZSA8IGdyZWdvcmlhbkN1dG92ZXIpIHsKKyAgICAgICAgICAgIGRheXMgLT0ganVsaWFuU2tldzsKKyAgICAgICAgfQorICAgICAgICBpbnQgYXBwcm94WWVhcnM7CisKKyAgICAgICAgd2hpbGUgKChhcHByb3hZZWFycyA9IChpbnQpIChkYXlzIC8gMzY1KSkgIT0gMCkgeworICAgICAgICAgICAgeWVhciA9IHllYXIgKyBhcHByb3hZZWFyczsKKyAgICAgICAgICAgIGRheXMgPSBkYXlDb3VudCAtIGRheXNGcm9tQmFzZVllYXIoeWVhcik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRheXMgPCAwKSB7CisgICAgICAgICAgICB5ZWFyID0geWVhciAtIDE7CisgICAgICAgICAgICBkYXlzID0gZGF5cyArIDM2NSArIChpc0xlYXBZZWFyKHllYXIpID8gMSA6IDApOworICAgICAgICAgICAgaWYgKHllYXIgPT0gY2hhbmdlWWVhciAmJiBsb2NhbFRpbWUgPCBncmVnb3JpYW5DdXRvdmVyKSB7CisgICAgICAgICAgICAgICAgZGF5cyAtPSBqdWxpYW5FcnJvcigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmICh5ZWFyIDw9IDApIHsKKyAgICAgICAgICAgIHJldHVybiB0aW1lWm9uZS5nZXRSYXdPZmZzZXQoKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgZGF5T2ZZZWFyID0gKGludCkgZGF5cyArIDE7CisKKyAgICAgICAgaW50IG1vbnRoID0gZGF5T2ZZZWFyIC8gMzI7CisgICAgICAgIGJvb2xlYW4gbGVhcFllYXIgPSBpc0xlYXBZZWFyKHllYXIpOworICAgICAgICBpbnQgZGF0ZSA9IGRheU9mWWVhciAtIGRheXNJblllYXIobGVhcFllYXIsIG1vbnRoKTsKKyAgICAgICAgaWYgKGRhdGUgPiBkYXlzSW5Nb250aChsZWFwWWVhciwgbW9udGgpKSB7CisgICAgICAgICAgICBkYXRlIC09IGRheXNJbk1vbnRoKGxlYXBZZWFyLCBtb250aCk7CisgICAgICAgICAgICBtb250aCsrOworICAgICAgICB9CisgICAgICAgIGludCBkYXlPZldlZWsgPSBtb2Q3KGRheUNvdW50IC0gMykgKyAxOworICAgICAgICBpbnQgb2Zmc2V0ID0gdGltZVpvbmUuZ2V0T2Zmc2V0KEFELCB5ZWFyLCBtb250aCwgZGF0ZSwgZGF5T2ZXZWVrLAorICAgICAgICAgICAgICAgIG1pbGxpcyk7CisgICAgICAgIHJldHVybiBvZmZzZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnRlZ2VyIGhhc2ggY29kZSBmb3IgdGhlIHJlY2VpdmVyLiBPYmplY3RzIHdoaWNoIGFyZSBlcXVhbAorICAgICAqIHJldHVybiB0aGUgc2FtZSB2YWx1ZSBmb3IgdGhpcyBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIGhhc2guCisgICAgICoKKyAgICAgKiBAc2VlICNlcXVhbHMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gc3VwZXIuaGFzaENvZGUoKQorICAgICAgICAgICAgICAgICsgKChpbnQpIChncmVnb3JpYW5DdXRvdmVyID4+PiAzMikgXiAoaW50KSBncmVnb3JpYW5DdXRvdmVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHNwZWNpZmllZCB5ZWFyIGlzIGEgbGVhcCB5ZWFyLgorICAgICAqCisgICAgICogQHBhcmFtIHllYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB5ZWFyLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgeWVhciBpcyBhIGxlYXAgeWVhciwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzTGVhcFllYXIoaW50IHllYXIpIHsKKyAgICAgICAgaWYgKHllYXIgPiBjaGFuZ2VZZWFyKSB7CisgICAgICAgICAgICByZXR1cm4geWVhciAlIDQgPT0gMCAmJiAoeWVhciAlIDEwMCAhPSAwIHx8IHllYXIgJSA0MDAgPT0gMCk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4geWVhciAlIDQgPT0gMDsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBqdWxpYW5FcnJvcigpIHsKKyAgICAgICAgcmV0dXJuIGNoYW5nZVllYXIgLyAxMDAgLSBjaGFuZ2VZZWFyIC8gNDAwIC0gMjsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBtb2QoaW50IHZhbHVlLCBpbnQgbW9kKSB7CisgICAgICAgIGludCByZW0gPSB2YWx1ZSAlIG1vZDsKKyAgICAgICAgaWYgKHZhbHVlIDwgMCAmJiByZW0gPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gcmVtICsgbW9kOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZW07CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgbW9kNyhsb25nIG51bTEpIHsKKyAgICAgICAgaW50IHJlbSA9IChpbnQpIChudW0xICUgNyk7CisgICAgICAgIGlmIChudW0xIDwgMCAmJiByZW0gPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gcmVtICsgNzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVtOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIHNwZWNpZmllZCBhbW91bnQgdGhlIHNwZWNpZmllZCBmaWVsZCBhbmQgd3JhcHMgdGhlIHZhbHVlIG9mIHRoZQorICAgICAqIGZpZWxkIHdoZW4gaXQgZ29lcyBiZXlvbmQgdGhlIG1heGltdW0gb3IgbWluaW11bSB2YWx1ZSBmb3IgdGhlIGN1cnJlbnQKKyAgICAgKiBkYXRlLiBPdGhlciBmaWVsZHMgd2lsbCBiZSBhZGp1c3RlZCBhcyByZXF1aXJlZCB0byBtYWludGFpbiBhIGNvbnNpc3RlbnQKKyAgICAgKiBkYXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICAgICAgICB0aGUgZmllbGQgdG8gcm9sbC4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbW91bnQgdG8gYWRkLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBhbiBpbnZhbGlkIGZpZWxkIGlzIHNwZWNpZmllZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCByb2xsKGludCBmaWVsZCwgaW50IHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZpZWxkIDwgMCB8fCBmaWVsZCA+PSBaT05FX09GRlNFVCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaXNDYWNoZWQgPSBmYWxzZTsKKworICAgICAgICBjb21wbGV0ZSgpOworICAgICAgICBpbnQgZGF5cywgZGF5LCBtb2QsIG1heFdlZWtzLCBuZXdXZWVrOworICAgICAgICBpbnQgbWF4ID0gLTE7CisgICAgICAgIHN3aXRjaCAoZmllbGQpIHsKKyAgICAgICAgY2FzZSBZRUFSOgorICAgICAgICAgICAgbWF4ID0gbWF4aW11bXNbZmllbGRdOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgV0VFS19PRl9ZRUFSOgorICAgICAgICAgICAgZGF5cyA9IGRheXNJblllYXIoZmllbGRzW1lFQVJdKTsKKyAgICAgICAgICAgIGRheSA9IERBWV9PRl9ZRUFSOworICAgICAgICAgICAgbW9kID0gbW9kNyhmaWVsZHNbREFZX09GX1dFRUtdIC0gZmllbGRzW2RheV0KKyAgICAgICAgICAgICAgICAgICAgLSAoZ2V0Rmlyc3REYXlPZldlZWsoKSAtIDEpKTsKKyAgICAgICAgICAgIG1heFdlZWtzID0gKGRheXMgLSAxICsgbW9kKSAvIDcgKyAxOworICAgICAgICAgICAgbmV3V2VlayA9IG1vZChmaWVsZHNbZmllbGRdIC0gMSArIHZhbHVlLCBtYXhXZWVrcykgKyAxOworICAgICAgICAgICAgaWYgKG5ld1dlZWsgPT0gbWF4V2Vla3MpIHsKKyAgICAgICAgICAgICAgICBpbnQgYWRkRGF5cyA9IChuZXdXZWVrIC0gZmllbGRzW2ZpZWxkXSkgKiA3OworICAgICAgICAgICAgICAgIGlmIChmaWVsZHNbZGF5XSA+IGFkZERheXMgJiYgZmllbGRzW2RheV0gKyBhZGREYXlzID4gZGF5cykgeworICAgICAgICAgICAgICAgICAgICBzZXQoZmllbGQsIDEpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHNldChmaWVsZCwgbmV3V2VlayAtIDEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAobmV3V2VlayA9PSAxKSB7CisgICAgICAgICAgICAgICAgaW50IHdlZWsgPSAoZmllbGRzW2RheV0gLSAoKGZpZWxkc1tkYXldIC0gMSkgLyA3ICogNykgLSAxICsgbW9kKSAvIDcgKyAxOworICAgICAgICAgICAgICAgIGlmICh3ZWVrID4gMSkgeworICAgICAgICAgICAgICAgICAgICBzZXQoZmllbGQsIDEpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHNldChmaWVsZCwgbmV3V2Vlayk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzZXQoZmllbGQsIG5ld1dlZWspOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgV0VFS19PRl9NT05USDoKKyAgICAgICAgICAgIGRheXMgPSBkYXlzSW5Nb250aCgpOworICAgICAgICAgICAgZGF5ID0gREFURTsKKyAgICAgICAgICAgIG1vZCA9IG1vZDcoZmllbGRzW0RBWV9PRl9XRUVLXSAtIGZpZWxkc1tkYXldCisgICAgICAgICAgICAgICAgICAgIC0gKGdldEZpcnN0RGF5T2ZXZWVrKCkgLSAxKSk7CisgICAgICAgICAgICBtYXhXZWVrcyA9IChkYXlzIC0gMSArIG1vZCkgLyA3ICsgMTsKKyAgICAgICAgICAgIG5ld1dlZWsgPSBtb2QoZmllbGRzW2ZpZWxkXSAtIDEgKyB2YWx1ZSwgbWF4V2Vla3MpICsgMTsKKyAgICAgICAgICAgIGlmIChuZXdXZWVrID09IG1heFdlZWtzKSB7CisgICAgICAgICAgICAgICAgaWYgKGZpZWxkc1tkYXldICsgKG5ld1dlZWsgLSBmaWVsZHNbZmllbGRdKSAqIDcgPiBkYXlzKSB7CisgICAgICAgICAgICAgICAgICAgIHNldChkYXksIGRheXMpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHNldChmaWVsZCwgbmV3V2Vlayk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmIChuZXdXZWVrID09IDEpIHsKKyAgICAgICAgICAgICAgICBpbnQgd2VlayA9IChmaWVsZHNbZGF5XSAtICgoZmllbGRzW2RheV0gLSAxKSAvIDcgKiA3KSAtIDEgKyBtb2QpIC8gNyArIDE7CisgICAgICAgICAgICAgICAgaWYgKHdlZWsgPiAxKSB7CisgICAgICAgICAgICAgICAgICAgIHNldChkYXksIDEpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHNldChmaWVsZCwgbmV3V2Vlayk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzZXQoZmllbGQsIG5ld1dlZWspOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgREFURToKKyAgICAgICAgICAgIG1heCA9IGRheXNJbk1vbnRoKCk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBEQVlfT0ZfWUVBUjoKKyAgICAgICAgICAgIG1heCA9IGRheXNJblllYXIoZmllbGRzW1lFQVJdKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIERBWV9PRl9XRUVLOgorICAgICAgICAgICAgbWF4ID0gbWF4aW11bXNbZmllbGRdOworICAgICAgICAgICAgbGFzdERhdGVGaWVsZFNldCA9IFdFRUtfT0ZfTU9OVEg7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBEQVlfT0ZfV0VFS19JTl9NT05USDoKKyAgICAgICAgICAgIG1heCA9IChmaWVsZHNbREFURV0gKyAoKGRheXNJbk1vbnRoKCkgLSBmaWVsZHNbREFURV0pIC8gNyAqIDcpIC0gMSkgLyA3ICsgMTsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgRVJBOgorICAgICAgICBjYXNlIE1PTlRIOgorICAgICAgICBjYXNlIEFNX1BNOgorICAgICAgICBjYXNlIEhPVVI6CisgICAgICAgIGNhc2UgSE9VUl9PRl9EQVk6CisgICAgICAgIGNhc2UgTUlOVVRFOgorICAgICAgICBjYXNlIFNFQ09ORDoKKyAgICAgICAgY2FzZSBNSUxMSVNFQ09ORDoKKyAgICAgICAgICAgIHNldChmaWVsZCwgbW9kKGZpZWxkc1tmaWVsZF0gKyB2YWx1ZSwgbWF4aW11bXNbZmllbGRdICsgMSkpOworICAgICAgICAgICAgaWYgKGZpZWxkID09IE1PTlRIICYmIGZpZWxkc1tEQVRFXSA+IGRheXNJbk1vbnRoKCkpIHsKKyAgICAgICAgICAgICAgICBzZXQoREFURSwgZGF5c0luTW9udGgoKSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGZpZWxkID09IEFNX1BNKSB7CisgICAgICAgICAgICAgICAgbGFzdFRpbWVGaWVsZFNldCA9IEhPVVI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpZiAobWF4ICE9IC0xKSB7CisgICAgICAgICAgICBzZXQoZmllbGQsIG1vZChmaWVsZHNbZmllbGRdIC0gMSArIHZhbHVlLCBtYXgpICsgMSk7CisgICAgICAgIH0KKyAgICAgICAgY29tcGxldGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmNyZW1lbnRzIG9yIGRlY3JlbWVudHMgdGhlIHNwZWNpZmllZCBmaWVsZCBhbmQgd3JhcHMgdGhlIHZhbHVlIG9mIHRoZQorICAgICAqIGZpZWxkIHdoZW4gaXQgZ29lcyBiZXlvbmQgdGhlIG1heGltdW0gb3IgbWluaW11bSB2YWx1ZSBmb3IgdGhlIGN1cnJlbnQKKyAgICAgKiBkYXRlLiBPdGhlciBmaWVsZHMgd2lsbCBiZSBhZGp1c3RlZCBhcyByZXF1aXJlZCB0byBtYWludGFpbiBhIGNvbnNpc3RlbnQKKyAgICAgKiBkYXRlLiBGb3IgZXhhbXBsZSwgTWFyY2ggMzEgd2lsbCByb2xsIHRvIEFwcmlsIDMwIHdoZW4gcm9sbGluZyB0aGUgbW9udGgKKyAgICAgKiBmaWVsZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgICAgICAgdGhlIGZpZWxkIHRvIHJvbGwuCisgICAgICogQHBhcmFtIGluY3JlbWVudAorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IHRvIGluY3JlbWVudCB0aGUgZmllbGQsIHtAY29kZSBmYWxzZX0gdG8KKyAgICAgKiAgICAgICAgICAgIGRlY3JlbWVudC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGFuIGludmFsaWQgZmllbGQgaXMgc3BlY2lmaWVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJvbGwoaW50IGZpZWxkLCBib29sZWFuIGluY3JlbWVudCkgeworICAgICAgICByb2xsKGZpZWxkLCBpbmNyZW1lbnQgPyAxIDogLTEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGdyZWdvcmlhbiBjaGFuZ2UgZGF0ZSBvZiB0aGlzIGNhbGVuZGFyLgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGUKKyAgICAgKiAgICAgICAgICAgIGEge0Bjb2RlIERhdGV9IHdoaWNoIHJlcHJlc2VudHMgdGhlIGdyZWdvcmlhbiBjaGFuZ2UgZGF0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRHcmVnb3JpYW5DaGFuZ2UoRGF0ZSBkYXRlKSB7CisgICAgICAgIGdyZWdvcmlhbkN1dG92ZXIgPSBkYXRlLmdldFRpbWUoKTsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKFRpbWVab25lLkdNVCk7CisgICAgICAgIGNhbC5zZXRUaW1lKGRhdGUpOworICAgICAgICBjaGFuZ2VZZWFyID0gY2FsLmdldChZRUFSKTsKKyAgICAgICAgaWYgKGNhbC5nZXQoRVJBKSA9PSBCQykgeworICAgICAgICAgICAgY2hhbmdlWWVhciA9IDEgLSBjaGFuZ2VZZWFyOworICAgICAgICB9CisgICAgICAgIGp1bGlhblNrZXcgPSAoKGNoYW5nZVllYXIgLSAyMDAwKSAvIDQwMCkgKyBqdWxpYW5FcnJvcigpCisgICAgICAgICAgICAgICAgLSAoKGNoYW5nZVllYXIgLSAyMDAwKSAvIDEwMCk7CisgICAgICAgIGlzQ2FjaGVkID0gZmFsc2U7CisgICAgICAgIGludCBkYXlPZlllYXIgPSBjYWwuZ2V0KERBWV9PRl9ZRUFSKTsKKyAgICAgICAgaWYgKGRheU9mWWVhciA8IGp1bGlhblNrZXcpIHsKKyAgICAgICAgICAgIGN1cnJlbnRZZWFyU2tldyA9IGRheU9mWWVhci0xOworICAgICAgICAgICAgbGFzdFllYXJTa2V3ID0ganVsaWFuU2tldyAtIGRheU9mWWVhciArIDE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBsYXN0WWVhclNrZXcgPSAwOworICAgICAgICAgICAgY3VycmVudFllYXJTa2V3ID0ganVsaWFuU2tldzsKKyAgICAgICAgfQorICAgICAgICBpc0NhY2hlZCA9IGZhbHNlOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdHJlYW0uZGVmYXVsdFdyaXRlT2JqZWN0KCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgICAgICBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKworICAgICAgICBzdHJlYW0uZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgc2V0R3JlZ29yaWFuQ2hhbmdlKG5ldyBEYXRlKGdyZWdvcmlhbkN1dG92ZXIpKTsKKyAgICAgICAgaXNDYWNoZWQgPSBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRGaXJzdERheU9mV2VlayhpbnQgdmFsdWUpIHsKKyAgICAgICAgc3VwZXIuc2V0Rmlyc3REYXlPZldlZWsodmFsdWUpOworICAgICAgICBpc0NhY2hlZCA9IGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldE1pbmltYWxEYXlzSW5GaXJzdFdlZWsoaW50IHZhbHVlKSB7CisgICAgICAgIHN1cGVyLnNldE1pbmltYWxEYXlzSW5GaXJzdFdlZWsodmFsdWUpOworICAgICAgICBpc0NhY2hlZCA9IGZhbHNlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvSGFzaE1hcC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9IYXNoTWFwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWIyNDM4YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvSGFzaE1hcC5qYXZhCkBAIC0wLDAgKzEsMTA0NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkludmFsaWRPYmplY3RFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUZpZWxkOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGxpYmNvcmUudXRpbC5PYmplY3RzOworCisvKioKKyAqIEhhc2hNYXAgaXMgYW4gaW1wbGVtZW50YXRpb24gb2Yge0BsaW5rIE1hcH0uIEFsbCBvcHRpb25hbCBvcGVyYXRpb25zIGFyZSBzdXBwb3J0ZWQuCisgKgorICogPHA+QWxsIGVsZW1lbnRzIGFyZSBwZXJtaXR0ZWQgYXMga2V5cyBvciB2YWx1ZXMsIGluY2x1ZGluZyBudWxsLgorICoKKyAqIDxwPk5vdGUgdGhhdCB0aGUgaXRlcmF0aW9uIG9yZGVyIGZvciBIYXNoTWFwIGlzIG5vbi1kZXRlcm1pbmlzdGljLiBJZiB5b3Ugd2FudAorICogZGV0ZXJtaW5pc3RpYyBpdGVyYXRpb24sIHVzZSB7QGxpbmsgTGlua2VkSGFzaE1hcH0uCisgKgorICogPHA+Tm90ZTogdGhlIGltcGxlbWVudGF0aW9uIG9mIHtAY29kZSBIYXNoTWFwfSBpcyBub3Qgc3luY2hyb25pemVkLgorICogSWYgb25lIHRocmVhZCBvZiBzZXZlcmFsIHRocmVhZHMgYWNjZXNzaW5nIGFuIGluc3RhbmNlIG1vZGlmaWVzIHRoZSBtYXAKKyAqIHN0cnVjdHVyYWxseSwgYWNjZXNzIHRvIHRoZSBtYXAgbmVlZHMgdG8gYmUgc3luY2hyb25pemVkLiBBIHN0cnVjdHVyYWwKKyAqIG1vZGlmaWNhdGlvbiBpcyBhbiBvcGVyYXRpb24gdGhhdCBhZGRzIG9yIHJlbW92ZXMgYW4gZW50cnkuIENoYW5nZXMgaW4KKyAqIHRoZSB2YWx1ZSBvZiBhbiBlbnRyeSBhcmUgbm90IHN0cnVjdHVyYWwgY2hhbmdlcy4KKyAqCisgKiA8cD5UaGUge0Bjb2RlIEl0ZXJhdG9yfSBjcmVhdGVkIGJ5IGNhbGxpbmcgdGhlIHtAY29kZSBpdGVyYXRvcn0gbWV0aG9kCisgKiBtYXkgdGhyb3cgYSB7QGNvZGUgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0gaWYgdGhlIG1hcCBpcyBzdHJ1Y3R1cmFsbHkKKyAqIGNoYW5nZWQgd2hpbGUgYW4gaXRlcmF0b3IgaXMgdXNlZCB0byBpdGVyYXRlIG92ZXIgdGhlIGVsZW1lbnRzLiBPbmx5IHRoZQorICoge0Bjb2RlIHJlbW92ZX0gbWV0aG9kIHRoYXQgaXMgcHJvdmlkZWQgYnkgdGhlIGl0ZXJhdG9yIGFsbG93cyBmb3IgcmVtb3ZhbCBvZgorICogZWxlbWVudHMgZHVyaW5nIGl0ZXJhdGlvbi4gSXQgaXMgbm90IHBvc3NpYmxlIHRvIGd1YXJhbnRlZSB0aGF0IHRoaXMKKyAqIG1lY2hhbmlzbSB3b3JrcyBpbiBhbGwgY2FzZXMgb2YgdW5zeW5jaHJvbml6ZWQgY29uY3VycmVudCBtb2RpZmljYXRpb24uIEl0CisgKiBzaG91bGQgb25seSBiZSB1c2VkIGZvciBkZWJ1Z2dpbmcgcHVycG9zZXMuCisgKgorICogQHBhcmFtIDxLPiB0aGUgdHlwZSBvZiBrZXlzIG1haW50YWluZWQgYnkgdGhpcyBtYXAKKyAqIEBwYXJhbSA8Vj4gdGhlIHR5cGUgb2YgbWFwcGVkIHZhbHVlcworICovCitwdWJsaWMgY2xhc3MgSGFzaE1hcDxLLCBWPiBleHRlbmRzIEFic3RyYWN0TWFwPEssIFY+IGltcGxlbWVudHMgQ2xvbmVhYmxlLCBTZXJpYWxpemFibGUgeworICAgIC8qKgorICAgICAqIE1pbiBjYXBhY2l0eSAob3RoZXIgdGhhbiB6ZXJvKSBmb3IgYSBIYXNoTWFwLiBNdXN0IGJlIGEgcG93ZXIgb2YgdHdvCisgICAgICogZ3JlYXRlciB0aGFuIDEgKGFuZCBsZXNzIHRoYW4gMSA8PCAzMCkuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1JTklNVU1fQ0FQQUNJVFkgPSA0OworCisgICAgLyoqCisgICAgICogTWF4IGNhcGFjaXR5IGZvciBhIEhhc2hNYXAuIE11c3QgYmUgYSBwb3dlciBvZiB0d28gPj0gTUlOSU1VTV9DQVBBQ0lUWS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYSU1VTV9DQVBBQ0lUWSA9IDEgPDwgMzA7CisKKyAgICAvKioKKyAgICAgKiBBbiBlbXB0eSB0YWJsZSBzaGFyZWQgYnkgYWxsIHplcm8tY2FwYWNpdHkgbWFwcyAodHlwaWNhbGx5IGZyb20gZGVmYXVsdAorICAgICAqIGNvbnN0cnVjdG9yKS4gSXQgaXMgbmV2ZXIgd3JpdHRlbiB0bywgYW5kIHJlcGxhY2VkIG9uIGZpcnN0IHB1dC4gSXRzIHNpemUKKyAgICAgKiBpcyBzZXQgdG8gaGFsZiB0aGUgbWluaW11bSwgc28gdGhhdCB0aGUgZmlyc3QgcmVzaXplIHdpbGwgY3JlYXRlIGEKKyAgICAgKiBtaW5pbXVtLXNpemVkIHRhYmxlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEVudHJ5W10gRU1QVFlfVEFCTEUKKyAgICAgICAgICAgID0gbmV3IEhhc2hNYXBFbnRyeVtNSU5JTVVNX0NBUEFDSVRZID4+PiAxXTsKKworICAgIC8qKgorICAgICAqIFRoZSBkZWZhdWx0IGxvYWQgZmFjdG9yLiBOb3RlIHRoYXQgdGhpcyBpbXBsZW1lbnRhdGlvbiBpZ25vcmVzIHRoZQorICAgICAqIGxvYWQgZmFjdG9yLCBidXQgY2Fubm90IGRvIGF3YXkgd2l0aCBpdCBlbnRpcmVseSBiZWNhdXNlIGl0J3MKKyAgICAgKiBtZW50aW9uZWQgaW4gdGhlIEFQSS4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB0aGlzIGNvbnN0YW50IGhhcyBubyBpbXBhY3Qgb24gdGhlIGJlaGF2aW9yIG9mIHRoZSBwcm9ncmFtLAorICAgICAqIGJ1dCBpdCBpcyBlbWl0dGVkIGFzIHBhcnQgb2YgdGhlIHNlcmlhbGl6ZWQgZm9ybS4gVGhlIGxvYWQgZmFjdG9yIG9mCisgICAgICogLjc1IGlzIGhhcmR3aXJlZCBpbnRvIHRoZSBwcm9ncmFtLCB3aGljaCB1c2VzIGNoZWFwIHNoaWZ0cyBpbiBwbGFjZSBvZgorICAgICAqIGV4cGVuc2l2ZSBkaXZpc2lvbi4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgZmxvYXQgREVGQVVMVF9MT0FEX0ZBQ1RPUiA9IC43NUY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaGFzaCB0YWJsZS4gSWYgdGhpcyBoYXNoIG1hcCBjb250YWlucyBhIG1hcHBpbmcgZm9yIG51bGwsIGl0IGlzCisgICAgICogbm90IHJlcHJlc2VudGVkIHRoaXMgaGFzaCB0YWJsZS4KKyAgICAgKi8KKyAgICB0cmFuc2llbnQgSGFzaE1hcEVudHJ5PEssIFY+W10gdGFibGU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZW50cnkgcmVwcmVzZW50aW5nIHRoZSBudWxsIGtleSwgb3IgbnVsbCBpZiB0aGVyZSdzIG5vIHN1Y2ggbWFwcGluZy4KKyAgICAgKi8KKyAgICB0cmFuc2llbnQgSGFzaE1hcEVudHJ5PEssIFY+IGVudHJ5Rm9yTnVsbEtleTsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgbWFwcGluZ3MgaW4gdGhpcyBoYXNoIG1hcC4KKyAgICAgKi8KKyAgICB0cmFuc2llbnQgaW50IHNpemU7CisKKyAgICAvKioKKyAgICAgKiBJbmNyZW1lbnRlZCBieSAic3RydWN0dXJhbCBtb2RpZmljYXRpb25zIiB0byBhbGxvdyAoYmVzdCBlZmZvcnQpCisgICAgICogZGV0ZWN0aW9uIG9mIGNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uLgorICAgICAqLworICAgIHRyYW5zaWVudCBpbnQgbW9kQ291bnQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdGFibGUgaXMgcmVoYXNoZWQgd2hlbiBpdHMgc2l6ZSBleGNlZWRzIHRoaXMgdGhyZXNob2xkLgorICAgICAqIFRoZSB2YWx1ZSBvZiB0aGlzIGZpZWxkIGlzIGdlbmVyYWxseSAuNzUgKiBjYXBhY2l0eSwgZXhjZXB0IHdoZW4KKyAgICAgKiB0aGUgY2FwYWNpdHkgaXMgemVybywgYXMgZGVzY3JpYmVkIGluIHRoZSBFTVBUWV9UQUJMRSBkZWNsYXJhdGlvbgorICAgICAqIGFib3ZlLgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IGludCB0aHJlc2hvbGQ7CisKKyAgICAvLyBWaWV3cyAtIGxhemlseSBpbml0aWFsaXplZAorICAgIHByaXZhdGUgdHJhbnNpZW50IFNldDxLPiBrZXlTZXQ7CisgICAgcHJpdmF0ZSB0cmFuc2llbnQgU2V0PEVudHJ5PEssIFY+PiBlbnRyeVNldDsKKyAgICBwcml2YXRlIHRyYW5zaWVudCBDb2xsZWN0aW9uPFY+IHZhbHVlczsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgZW1wdHkge0Bjb2RlIEhhc2hNYXB9IGluc3RhbmNlLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBIYXNoTWFwKCkgeworICAgICAgICB0YWJsZSA9IChIYXNoTWFwRW50cnk8SywgVj5bXSkgRU1QVFlfVEFCTEU7CisgICAgICAgIHRocmVzaG9sZCA9IC0xOyAvLyBGb3JjZXMgZmlyc3QgcHV0IGludm9jYXRpb24gdG8gcmVwbGFjZSBFTVBUWV9UQUJMRQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEhhc2hNYXB9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBjYXBhY2l0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXBhY2l0eQorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgY2FwYWNpdHkgb2YgdGhpcyBoYXNoIG1hcC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIHdoZW4gdGhlIGNhcGFjaXR5IGlzIGxlc3MgdGhhbiB6ZXJvLgorICAgICAqLworICAgIHB1YmxpYyBIYXNoTWFwKGludCBjYXBhY2l0eSkgeworICAgICAgICBpZiAoY2FwYWNpdHkgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJDYXBhY2l0eTogIiArIGNhcGFjaXR5KTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjYXBhY2l0eSA9PSAwKSB7CisgICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPltdIHRhYiA9IChIYXNoTWFwRW50cnk8SywgVj5bXSkgRU1QVFlfVEFCTEU7CisgICAgICAgICAgICB0YWJsZSA9IHRhYjsKKyAgICAgICAgICAgIHRocmVzaG9sZCA9IC0xOyAvLyBGb3JjZXMgZmlyc3QgcHV0KCkgdG8gcmVwbGFjZSBFTVBUWV9UQUJMRQorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGNhcGFjaXR5IDwgTUlOSU1VTV9DQVBBQ0lUWSkgeworICAgICAgICAgICAgY2FwYWNpdHkgPSBNSU5JTVVNX0NBUEFDSVRZOworICAgICAgICB9IGVsc2UgaWYgKGNhcGFjaXR5ID4gTUFYSU1VTV9DQVBBQ0lUWSkgeworICAgICAgICAgICAgY2FwYWNpdHkgPSBNQVhJTVVNX0NBUEFDSVRZOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY2FwYWNpdHkgPSByb3VuZFVwVG9Qb3dlck9mVHdvKGNhcGFjaXR5KTsKKyAgICAgICAgfQorICAgICAgICBtYWtlVGFibGUoY2FwYWNpdHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEhhc2hNYXB9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBjYXBhY2l0eSBhbmQKKyAgICAgKiBsb2FkIGZhY3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXBhY2l0eQorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgY2FwYWNpdHkgb2YgdGhpcyBoYXNoIG1hcC4KKyAgICAgKiBAcGFyYW0gbG9hZEZhY3RvcgorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgbG9hZCBmYWN0b3IuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICB3aGVuIHRoZSBjYXBhY2l0eSBpcyBsZXNzIHRoYW4gemVybyBvciB0aGUgbG9hZCBmYWN0b3IgaXMKKyAgICAgKiAgICAgICAgICAgICAgICBsZXNzIG9yIGVxdWFsIHRvIHplcm8gb3IgTmFOLgorICAgICAqLworICAgIHB1YmxpYyBIYXNoTWFwKGludCBjYXBhY2l0eSwgZmxvYXQgbG9hZEZhY3RvcikgeworICAgICAgICB0aGlzKGNhcGFjaXR5KTsKKworICAgICAgICBpZiAobG9hZEZhY3RvciA8PSAwIHx8IEZsb2F0LmlzTmFOKGxvYWRGYWN0b3IpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJMb2FkIGZhY3RvcjogIiArIGxvYWRGYWN0b3IpOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogTm90ZSB0aGF0IHRoaXMgaW1wbGVtZW50YXRpb24gaWdub3JlcyBsb2FkRmFjdG9yOyBpdCBhbHdheXMgdXNlcworICAgICAgICAgKiBhIGxvYWQgZmFjdG9yIG9mIDMvNC4gVGhpcyBzaW1wbGlmaWVzIHRoZSBjb2RlIGFuZCBnZW5lcmFsbHkKKyAgICAgICAgICogaW1wcm92ZXMgcGVyZm9ybWFuY2UuCisgICAgICAgICAqLworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEhhc2hNYXB9IGluc3RhbmNlIGNvbnRhaW5pbmcgdGhlIG1hcHBpbmdzIGZyb20KKyAgICAgKiB0aGUgc3BlY2lmaWVkIG1hcC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtYXAKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXBwaW5ncyB0byBhZGQuCisgICAgICovCisgICAgcHVibGljIEhhc2hNYXAoTWFwPD8gZXh0ZW5kcyBLLCA/IGV4dGVuZHMgVj4gbWFwKSB7CisgICAgICAgIHRoaXMoY2FwYWNpdHlGb3JJbml0U2l6ZShtYXAuc2l6ZSgpKSk7CisgICAgICAgIGNvbnN0cnVjdG9yUHV0QWxsKG1hcCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyBhbGwgb2YgdGhlIGVsZW1lbnRzIG9mIG1hcCBpbnRvIHRoaXMgSGFzaE1hcCBpbiBhIG1hbm5lcgorICAgICAqIHN1aXRhYmxlIGZvciB1c2UgYnkgY29uc3RydWN0b3JzIGFuZCBwc2V1ZG8tY29uc3RydWN0b3JzIChpLmUuLCBjbG9uZSwKKyAgICAgKiByZWFkT2JqZWN0KS4gQWxzbyB1c2VkIGJ5IExpbmtlZEhhc2hNYXAuCisgICAgICovCisgICAgZmluYWwgdm9pZCBjb25zdHJ1Y3RvclB1dEFsbChNYXA8PyBleHRlbmRzIEssID8gZXh0ZW5kcyBWPiBtYXApIHsKKyAgICAgICAgZm9yIChFbnRyeTw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+IGUgOiBtYXAuZW50cnlTZXQoKSkgeworICAgICAgICAgICAgY29uc3RydWN0b3JQdXQoZS5nZXRLZXkoKSwgZS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXBwcm9wcmlhdGUgY2FwYWNpdHkgZm9yIHRoZSBzcGVjaWZpZWQgaW5pdGlhbCBzaXplLiBEb2VzCisgICAgICogbm90IHJvdW5kIHRoZSByZXN1bHQgdXAgdG8gYSBwb3dlciBvZiB0d287IHRoZSBjYWxsZXIgbXVzdCBkbyB0aGlzIQorICAgICAqIFRoZSByZXR1cm5lZCB2YWx1ZSB3aWxsIGJlIGJldHdlZW4gMCBhbmQgTUFYSU1VTV9DQVBBQ0lUWSAoaW5jbHVzaXZlKS4KKyAgICAgKi8KKyAgICBzdGF0aWMgaW50IGNhcGFjaXR5Rm9ySW5pdFNpemUoaW50IHNpemUpIHsKKyAgICAgICAgaW50IHJlc3VsdCA9IChzaXplID4+IDEpICsgc2l6ZTsgLy8gTXVsdGlwbHkgYnkgMy8yIHRvIGFsbG93IGZvciBncm93dGgKKworICAgICAgICAvLyBib29sZWFuIGV4cHIgaXMgZXF1aXZhbGVudCB0byByZXN1bHQgPj0gMCAmJiByZXN1bHQ8TUFYSU1VTV9DQVBBQ0lUWQorICAgICAgICByZXR1cm4gKHJlc3VsdCAmIH4oTUFYSU1VTV9DQVBBQ0lUWS0xKSk9PTAgPyByZXN1bHQgOiBNQVhJTVVNX0NBUEFDSVRZOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzaGFsbG93IGNvcHkgb2YgdGhpcyBtYXAuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc2hhbGxvdyBjb3B5IG9mIHRoaXMgbWFwLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIEBPdmVycmlkZSBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICAvKgorICAgICAgICAgKiBUaGlzIGNvdWxkIGJlIG1hZGUgbW9yZSBlZmZpY2llbnQuIEl0IHVubmVjZXNzYXJpbHkgaGFzaGVzIGFsbCBvZgorICAgICAgICAgKiB0aGUgZWxlbWVudHMgaW4gdGhlIG1hcC4KKyAgICAgICAgICovCisgICAgICAgIEhhc2hNYXA8SywgVj4gcmVzdWx0OworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzdWx0ID0gKEhhc2hNYXA8SywgVj4pIHN1cGVyLmNsb25lKCk7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFJlc3RvcmUgY2xvbmUgdG8gZW1wdHkgc3RhdGUsIHJldGFpbmluZyBvdXIgY2FwYWNpdHkgYW5kIHRocmVzaG9sZAorICAgICAgICByZXN1bHQubWFrZVRhYmxlKHRhYmxlLmxlbmd0aCk7CisgICAgICAgIHJlc3VsdC5lbnRyeUZvck51bGxLZXkgPSBudWxsOworICAgICAgICByZXN1bHQuc2l6ZSA9IDA7CisgICAgICAgIHJlc3VsdC5rZXlTZXQgPSBudWxsOworICAgICAgICByZXN1bHQuZW50cnlTZXQgPSBudWxsOworICAgICAgICByZXN1bHQudmFsdWVzID0gbnVsbDsKKworICAgICAgICByZXN1bHQuaW5pdCgpOyAvLyBHaXZlIHN1YmNsYXNzIGEgY2hhbmNlIHRvIGluaXRpYWxpemUgaXRzZWxmCisgICAgICAgIHJlc3VsdC5jb25zdHJ1Y3RvclB1dEFsbCh0aGlzKTsgLy8gQ2FsbHMgbWV0aG9kIG92ZXJyaWRkZW4gaW4gc3ViY2xhc3MhIQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBmcm9tIHRoZSBwc2V1ZG8tY29uc3RydWN0b3JzIChjbG9uZSBhbmQgcmVhZE9iamVjdCkKKyAgICAgKiBwcmlvciB0byBpbnZva2luZyBjb25zdHJ1Y3RvclB1dC9jb25zdHJ1Y3RvclB1dEFsbCwgd2hpY2ggaW52b2tlIHRoZQorICAgICAqIG92ZXJyaWRkZW4gY29uc3RydWN0b3JOZXdFbnRyeSBtZXRob2QuIE5vcm1hbGx5IGl0IGlzIGEgVkVSWSBiYWQgaWRlYSB0bworICAgICAqIGludm9rZSBhbiBvdmVycmlkZGVuIG1ldGhvZCBmcm9tIGEgcHNldWRvLWNvbnN0cnVjdG9yIChFZmZlY3RpdmUgSmF2YQorICAgICAqIEl0ZW0gMTcpLiBJbiB0aGlzIGNhc2UgaXQgaXMgdW5hdm9pZGFibGUsIGFuZCB0aGUgaW5pdCBtZXRob2QgcHJvdmlkZXMgYQorICAgICAqIHdvcmthcm91bmQuCisgICAgICovCisgICAgdm9pZCBpbml0KCkgeyB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBtYXAgaXMgZW1wdHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIG1hcCBoYXMgbm8gZWxlbWVudHMsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNzaXplKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgcmV0dXJuIHNpemUgPT0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBtYXAuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBtYXAuCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIHNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIG1hcHBpbmcgd2l0aCB0aGUgc3BlY2lmaWVkIGtleS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIG1hcHBpbmcgd2l0aCB0aGUgc3BlY2lmaWVkIGtleSwgb3Ige0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpZiBubyBtYXBwaW5nIGZvciB0aGUgc3BlY2lmaWVkIGtleSBpcyBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgViBnZXQoT2JqZWN0IGtleSkgeworICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPiBlID0gZW50cnlGb3JOdWxsS2V5OworICAgICAgICAgICAgcmV0dXJuIGUgPT0gbnVsbCA/IG51bGwgOiBlLnZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgLy8gRG91ZyBMZWEncyBzdXBwbGVtZW50YWwgc2Vjb25kYXJ5SGFzaCBmdW5jdGlvbiAoaW5saW5lZCkKKyAgICAgICAgaW50IGhhc2ggPSBrZXkuaGFzaENvZGUoKTsKKyAgICAgICAgaGFzaCBePSAoaGFzaCA+Pj4gMjApIF4gKGhhc2ggPj4+IDEyKTsKKyAgICAgICAgaGFzaCBePSAoaGFzaCA+Pj4gNykgXiAoaGFzaCA+Pj4gNCk7CisKKyAgICAgICAgSGFzaE1hcEVudHJ5PEssIFY+W10gdGFiID0gdGFibGU7CisgICAgICAgIGZvciAoSGFzaE1hcEVudHJ5PEssIFY+IGUgPSB0YWJbaGFzaCAmICh0YWIubGVuZ3RoIC0gMSldOworICAgICAgICAgICAgICAgIGUgIT0gbnVsbDsgZSA9IGUubmV4dCkgeworICAgICAgICAgICAgSyBlS2V5ID0gZS5rZXk7CisgICAgICAgICAgICBpZiAoZUtleSA9PSBrZXkgfHwgKGUuaGFzaCA9PSBoYXNoICYmIGtleS5lcXVhbHMoZUtleSkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGUudmFsdWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgbWFwIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byBzZWFyY2ggZm9yLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgbWFwIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQga2V5LAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrZXkpIHsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZW50cnlGb3JOdWxsS2V5ICE9IG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvLyBEb3VnIExlYSdzIHN1cHBsZW1lbnRhbCBzZWNvbmRhcnlIYXNoIGZ1bmN0aW9uIChpbmxpbmVkKQorICAgICAgICBpbnQgaGFzaCA9IGtleS5oYXNoQ29kZSgpOworICAgICAgICBoYXNoIF49IChoYXNoID4+PiAyMCkgXiAoaGFzaCA+Pj4gMTIpOworICAgICAgICBoYXNoIF49IChoYXNoID4+PiA3KSBeIChoYXNoID4+PiA0KTsKKworICAgICAgICBIYXNoTWFwRW50cnk8SywgVj5bXSB0YWIgPSB0YWJsZTsKKyAgICAgICAgZm9yIChIYXNoTWFwRW50cnk8SywgVj4gZSA9IHRhYltoYXNoICYgKHRhYi5sZW5ndGggLSAxKV07CisgICAgICAgICAgICAgICAgZSAhPSBudWxsOyBlID0gZS5uZXh0KSB7CisgICAgICAgICAgICBLIGVLZXkgPSBlLmtleTsKKyAgICAgICAgICAgIGlmIChlS2V5ID09IGtleSB8fCAoZS5oYXNoID09IGhhc2ggJiYga2V5LmVxdWFscyhlS2V5KSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgbWFwIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgbWFwIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgdmFsdWUsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnNWYWx1ZShPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgSGFzaE1hcEVudHJ5W10gdGFiID0gdGFibGU7CisgICAgICAgIGludCBsZW4gPSB0YWIubGVuZ3RoOworICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgICAgICAgICAgIGZvciAoSGFzaE1hcEVudHJ5IGUgPSB0YWJbaV07IGUgIT0gbnVsbDsgZSA9IGUubmV4dCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoZS52YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBlbnRyeUZvck51bGxLZXkgIT0gbnVsbCAmJiBlbnRyeUZvck51bGxLZXkudmFsdWUgPT0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHZhbHVlIGlzIG5vbi1udWxsCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoSGFzaE1hcEVudHJ5IGUgPSB0YWJbaV07IGUgIT0gbnVsbDsgZSA9IGUubmV4dCkgeworICAgICAgICAgICAgICAgIGlmICh2YWx1ZS5lcXVhbHMoZS52YWx1ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBlbnRyeUZvck51bGxLZXkgIT0gbnVsbCAmJiB2YWx1ZS5lcXVhbHMoZW50cnlGb3JOdWxsS2V5LnZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXBzIHRoZSBzcGVjaWZpZWQga2V5IHRvIHRoZSBzcGVjaWZpZWQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5LgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlLgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIGFueSBwcmV2aW91cyBtYXBwaW5nIHdpdGggdGhlIHNwZWNpZmllZCBrZXkgb3IKKyAgICAgKiAgICAgICAgIHtAY29kZSBudWxsfSBpZiB0aGVyZSB3YXMgbm8gc3VjaCBtYXBwaW5nLgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgViBwdXQoSyBrZXksIFYgdmFsdWUpIHsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gcHV0VmFsdWVGb3JOdWxsS2V5KHZhbHVlKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBoYXNoID0gc2Vjb25kYXJ5SGFzaChrZXkuaGFzaENvZGUoKSk7CisgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPltdIHRhYiA9IHRhYmxlOworICAgICAgICBpbnQgaW5kZXggPSBoYXNoICYgKHRhYi5sZW5ndGggLSAxKTsKKyAgICAgICAgZm9yIChIYXNoTWFwRW50cnk8SywgVj4gZSA9IHRhYltpbmRleF07IGUgIT0gbnVsbDsgZSA9IGUubmV4dCkgeworICAgICAgICAgICAgaWYgKGUuaGFzaCA9PSBoYXNoICYmIGtleS5lcXVhbHMoZS5rZXkpKSB7CisgICAgICAgICAgICAgICAgcHJlTW9kaWZ5KGUpOworICAgICAgICAgICAgICAgIFYgb2xkVmFsdWUgPSBlLnZhbHVlOworICAgICAgICAgICAgICAgIGUudmFsdWUgPSB2YWx1ZTsKKyAgICAgICAgICAgICAgICByZXR1cm4gb2xkVmFsdWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBObyBlbnRyeSBmb3IgKG5vbi1udWxsKSBrZXkgaXMgcHJlc2VudDsgY3JlYXRlIG9uZQorICAgICAgICBtb2RDb3VudCsrOworICAgICAgICBpZiAoc2l6ZSsrID4gdGhyZXNob2xkKSB7CisgICAgICAgICAgICB0YWIgPSBkb3VibGVDYXBhY2l0eSgpOworICAgICAgICAgICAgaW5kZXggPSBoYXNoICYgKHRhYi5sZW5ndGggLSAxKTsKKyAgICAgICAgfQorICAgICAgICBhZGROZXdFbnRyeShrZXksIHZhbHVlLCBoYXNoLCBpbmRleCk7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHByaXZhdGUgViBwdXRWYWx1ZUZvck51bGxLZXkoViB2YWx1ZSkgeworICAgICAgICBIYXNoTWFwRW50cnk8SywgVj4gZW50cnkgPSBlbnRyeUZvck51bGxLZXk7CisgICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CisgICAgICAgICAgICBhZGROZXdFbnRyeUZvck51bGxLZXkodmFsdWUpOworICAgICAgICAgICAgc2l6ZSsrOworICAgICAgICAgICAgbW9kQ291bnQrKzsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcHJlTW9kaWZ5KGVudHJ5KTsKKyAgICAgICAgICAgIFYgb2xkVmFsdWUgPSBlbnRyeS52YWx1ZTsKKyAgICAgICAgICAgIGVudHJ5LnZhbHVlID0gdmFsdWU7CisgICAgICAgICAgICByZXR1cm4gb2xkVmFsdWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHaXZlIExpbmtlZEhhc2hNYXAgYSBjaGFuY2UgdG8gdGFrZSBhY3Rpb24gd2hlbiB3ZSBtb2RpZnkgYW4gZXhpc3RpbmcKKyAgICAgKiBlbnRyeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIHRoZSBlbnRyeSB3ZSdyZSBhYm91dCB0byBtb2RpZnkuCisgICAgICovCisgICAgdm9pZCBwcmVNb2RpZnkoSGFzaE1hcEVudHJ5PEssIFY+IGUpIHsgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgaXMganVzdCBsaWtlIHB1dCwgZXhjZXB0IHRoYXQgaXQgZG9lc24ndCBkbyB0aGluZ3MgdGhhdAorICAgICAqIGFyZSBpbmFwcHJvcHJpYXRlIG9yIHVubmVjZXNzYXJ5IGZvciBjb25zdHJ1Y3RvcnMgYW5kIHBzZXVkby1jb25zdHJ1Y3RvcnMKKyAgICAgKiAoaS5lLiwgY2xvbmUsIHJlYWRPYmplY3QpLiBJbiBwYXJ0aWN1bGFyLCB0aGlzIG1ldGhvZCBkb2VzIG5vdCBjaGVjayB0bworICAgICAqIGVuc3VyZSB0aGF0IGNhcGFjaXR5IGlzIHN1ZmZpY2llbnQsIGFuZCBkb2VzIG5vdCBpbmNyZW1lbnQgbW9kQ291bnQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNvbnN0cnVjdG9yUHV0KEsga2V5LCBWIHZhbHVlKSB7CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeworICAgICAgICAgICAgSGFzaE1hcEVudHJ5PEssIFY+IGVudHJ5ID0gZW50cnlGb3JOdWxsS2V5OworICAgICAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBlbnRyeUZvck51bGxLZXkgPSBjb25zdHJ1Y3Rvck5ld0VudHJ5KG51bGwsIHZhbHVlLCAwLCBudWxsKTsKKyAgICAgICAgICAgICAgICBzaXplKys7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGVudHJ5LnZhbHVlID0gdmFsdWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpbnQgaGFzaCA9IHNlY29uZGFyeUhhc2goa2V5Lmhhc2hDb2RlKCkpOworICAgICAgICBIYXNoTWFwRW50cnk8SywgVj5bXSB0YWIgPSB0YWJsZTsKKyAgICAgICAgaW50IGluZGV4ID0gaGFzaCAmICh0YWIubGVuZ3RoIC0gMSk7CisgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPiBmaXJzdCA9IHRhYltpbmRleF07CisgICAgICAgIGZvciAoSGFzaE1hcEVudHJ5PEssIFY+IGUgPSBmaXJzdDsgZSAhPSBudWxsOyBlID0gZS5uZXh0KSB7CisgICAgICAgICAgICBpZiAoZS5oYXNoID09IGhhc2ggJiYga2V5LmVxdWFscyhlLmtleSkpIHsKKyAgICAgICAgICAgICAgICBlLnZhbHVlID0gdmFsdWU7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gTm8gZW50cnkgZm9yIChub24tbnVsbCkga2V5IGlzIHByZXNlbnQ7IGNyZWF0ZSBvbmUKKyAgICAgICAgdGFiW2luZGV4XSA9IGNvbnN0cnVjdG9yTmV3RW50cnkoa2V5LCB2YWx1ZSwgaGFzaCwgZmlyc3QpOworICAgICAgICBzaXplKys7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBlbnRyeSBmb3IgdGhlIGdpdmVuIGtleSwgdmFsdWUsIGhhc2gsIGFuZCBpbmRleCBhbmQKKyAgICAgKiBpbnNlcnRzIGl0IGludG8gdGhlIGhhc2ggdGFibGUuIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSBwdXQKKyAgICAgKiAoYW5kIGluZGlyZWN0bHksIHB1dEFsbCksIGFuZCBvdmVycmlkZGVuIGJ5IExpbmtlZEhhc2hNYXAuIFRoZSBoYXNoCisgICAgICogbXVzdCBpbmNvcnBvcmF0ZSB0aGUgc2Vjb25kYXJ5IGhhc2ggZnVuY3Rpb24uCisgICAgICovCisgICAgdm9pZCBhZGROZXdFbnRyeShLIGtleSwgViB2YWx1ZSwgaW50IGhhc2gsIGludCBpbmRleCkgeworICAgICAgICB0YWJsZVtpbmRleF0gPSBuZXcgSGFzaE1hcEVudHJ5PEssIFY+KGtleSwgdmFsdWUsIGhhc2gsIHRhYmxlW2luZGV4XSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBlbnRyeSBmb3IgdGhlIG51bGwga2V5LCBhbmQgdGhlIGdpdmVuIHZhbHVlIGFuZAorICAgICAqIGluc2VydHMgaXQgaW50byB0aGUgaGFzaCB0YWJsZS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHB1dAorICAgICAqIChhbmQgaW5kaXJlY3RseSwgcHV0QWxsKSwgYW5kIG92ZXJyaWRkZW4gYnkgTGlua2VkSGFzaE1hcC4KKyAgICAgKi8KKyAgICB2b2lkIGFkZE5ld0VudHJ5Rm9yTnVsbEtleShWIHZhbHVlKSB7CisgICAgICAgIGVudHJ5Rm9yTnVsbEtleSA9IG5ldyBIYXNoTWFwRW50cnk8SywgVj4obnVsbCwgdmFsdWUsIDAsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExpa2UgbmV3RW50cnksIGJ1dCBkb2VzIG5vdCBwZXJmb3JtIGFueSBhY3Rpdml0eSB0aGF0IHdvdWxkIGJlCisgICAgICogdW5uZWNlc3Nhcnkgb3IgaW5hcHByb3ByaWF0ZSBmb3IgY29uc3RydWN0b3JzLiBJbiB0aGlzIGNsYXNzLCB0aGUKKyAgICAgKiB0d28gbWV0aG9kcyBiZWhhdmUgaWRlbnRpY2FsbHk7IGluIExpbmtlZEhhc2hNYXAsIHRoZXkgZGlmZmVyLgorICAgICAqLworICAgIEhhc2hNYXBFbnRyeTxLLCBWPiBjb25zdHJ1Y3Rvck5ld0VudHJ5KAorICAgICAgICAgICAgSyBrZXksIFYgdmFsdWUsIGludCBoYXNoLCBIYXNoTWFwRW50cnk8SywgVj4gZmlyc3QpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBIYXNoTWFwRW50cnk8SywgVj4oa2V5LCB2YWx1ZSwgaGFzaCwgZmlyc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyBhbGwgdGhlIG1hcHBpbmdzIGluIHRoZSBzcGVjaWZpZWQgbWFwIHRvIHRoaXMgbWFwLiBUaGVzZSBtYXBwaW5ncworICAgICAqIHdpbGwgcmVwbGFjZSBhbGwgbWFwcGluZ3MgdGhhdCB0aGlzIG1hcCBoYWQgZm9yIGFueSBvZiB0aGUga2V5cyBjdXJyZW50bHkKKyAgICAgKiBpbiB0aGUgZ2l2ZW4gbWFwLgorICAgICAqCisgICAgICogQHBhcmFtIG1hcAorICAgICAqICAgICAgICAgICAgdGhlIG1hcCB0byBjb3B5IG1hcHBpbmdzIGZyb20uCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHB1dEFsbChNYXA8PyBleHRlbmRzIEssID8gZXh0ZW5kcyBWPiBtYXApIHsKKyAgICAgICAgZW5zdXJlQ2FwYWNpdHkobWFwLnNpemUoKSk7CisgICAgICAgIHN1cGVyLnB1dEFsbChtYXApOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuc3VyZXMgdGhhdCB0aGUgaGFzaCB0YWJsZSBoYXMgc3VmZmljaWVudCBjYXBhY2l0eSB0byBzdG9yZSB0aGUKKyAgICAgKiBzcGVjaWZpZWQgbnVtYmVyIG9mIG1hcHBpbmdzLCB3aXRoIHJvb20gdG8gZ3Jvdy4gSWYgbm90LCBpdCBpbmNyZWFzZXMgdGhlCisgICAgICogY2FwYWNpdHkgYXMgYXBwcm9wcmlhdGUuIExpa2UgZG91YmxlQ2FwYWNpdHksIHRoaXMgbWV0aG9kIG1vdmVzIGV4aXN0aW5nCisgICAgICogZW50cmllcyB0byBuZXcgYnVja2V0cyBhcyBhcHByb3ByaWF0ZS4gVW5saWtlIGRvdWJsZUNhcGFjaXR5LCB0aGlzIG1ldGhvZAorICAgICAqIGNhbiBncm93IHRoZSB0YWJsZSBieSBmYWN0b3JzIG9mIDJebiBmb3IgbiA+IDEuIEhvcGVmdWxseSwgYSBzaW5nbGUgY2FsbAorICAgICAqIHRvIHRoaXMgbWV0aG9kIHdpbGwgYmUgZmFzdGVyIHRoYW4gbXVsdGlwbGUgY2FsbHMgdG8gZG91YmxlQ2FwYWNpdHkuCisgICAgICoKKyAgICAgKiAgPHA+VGhpcyBtZXRob2QgaXMgY2FsbGVkIG9ubHkgYnkgcHV0QWxsLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBlbnN1cmVDYXBhY2l0eShpbnQgbnVtTWFwcGluZ3MpIHsKKyAgICAgICAgaW50IG5ld0NhcGFjaXR5ID0gcm91bmRVcFRvUG93ZXJPZlR3byhjYXBhY2l0eUZvckluaXRTaXplKG51bU1hcHBpbmdzKSk7CisgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPltdIG9sZFRhYmxlID0gdGFibGU7CisgICAgICAgIGludCBvbGRDYXBhY2l0eSA9IG9sZFRhYmxlLmxlbmd0aDsKKyAgICAgICAgaWYgKG5ld0NhcGFjaXR5IDw9IG9sZENhcGFjaXR5KSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKG5ld0NhcGFjaXR5ID09IG9sZENhcGFjaXR5ICogMikgeworICAgICAgICAgICAgZG91YmxlQ2FwYWNpdHkoKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFdlJ3JlIGdyb3dpbmcgYnkgYXQgbGVhc3QgNHgsIHJlaGFzaCBpbiB0aGUgb2J2aW91cyB3YXkKKyAgICAgICAgSGFzaE1hcEVudHJ5PEssIFY+W10gbmV3VGFibGUgPSBtYWtlVGFibGUobmV3Q2FwYWNpdHkpOworICAgICAgICBpZiAoc2l6ZSAhPSAwKSB7CisgICAgICAgICAgICBpbnQgbmV3TWFzayA9IG5ld0NhcGFjaXR5IC0gMTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2xkQ2FwYWNpdHk7IGkrKykgeworICAgICAgICAgICAgICAgIGZvciAoSGFzaE1hcEVudHJ5PEssIFY+IGUgPSBvbGRUYWJsZVtpXTsgZSAhPSBudWxsOykgeworICAgICAgICAgICAgICAgICAgICBIYXNoTWFwRW50cnk8SywgVj4gb2xkTmV4dCA9IGUubmV4dDsKKyAgICAgICAgICAgICAgICAgICAgaW50IG5ld0luZGV4ID0gZS5oYXNoICYgbmV3TWFzazsKKyAgICAgICAgICAgICAgICAgICAgSGFzaE1hcEVudHJ5PEssIFY+IG5ld05leHQgPSBuZXdUYWJsZVtuZXdJbmRleF07CisgICAgICAgICAgICAgICAgICAgIG5ld1RhYmxlW25ld0luZGV4XSA9IGU7CisgICAgICAgICAgICAgICAgICAgIGUubmV4dCA9IG5ld05leHQ7CisgICAgICAgICAgICAgICAgICAgIGUgPSBvbGROZXh0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFsbG9jYXRlIGEgdGFibGUgb2YgdGhlIGdpdmVuIGNhcGFjaXR5IGFuZCBzZXQgdGhlIHRocmVzaG9sZCBhY2NvcmRpbmdseS4KKyAgICAgKiBAcGFyYW0gbmV3Q2FwYWNpdHkgbXVzdCBiZSBhIHBvd2VyIG9mIHR3bworICAgICAqLworICAgIHByaXZhdGUgSGFzaE1hcEVudHJ5PEssIFY+W10gbWFrZVRhYmxlKGludCBuZXdDYXBhY2l0eSkgeworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikgSGFzaE1hcEVudHJ5PEssIFY+W10gbmV3VGFibGUKKyAgICAgICAgICAgICAgICA9IChIYXNoTWFwRW50cnk8SywgVj5bXSkgbmV3IEhhc2hNYXBFbnRyeVtuZXdDYXBhY2l0eV07CisgICAgICAgIHRhYmxlID0gbmV3VGFibGU7CisgICAgICAgIHRocmVzaG9sZCA9IChuZXdDYXBhY2l0eSA+PiAxKSArIChuZXdDYXBhY2l0eSA+PiAyKTsgLy8gMy80IGNhcGFjaXR5CisgICAgICAgIHJldHVybiBuZXdUYWJsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb3VibGVzIHRoZSBjYXBhY2l0eSBvZiB0aGUgaGFzaCB0YWJsZS4gRXhpc3RpbmcgZW50cmllcyBhcmUgcGxhY2VkIGluCisgICAgICogdGhlIGNvcnJlY3QgYnVja2V0IG9uIHRoZSBlbmxhcmdlZCB0YWJsZS4gSWYgdGhlIGN1cnJlbnQgY2FwYWNpdHkgaXMsCisgICAgICogTUFYSU1VTV9DQVBBQ0lUWSwgdGhpcyBtZXRob2QgaXMgYSBuby1vcC4gUmV0dXJucyB0aGUgdGFibGUsIHdoaWNoCisgICAgICogd2lsbCBiZSBuZXcgdW5sZXNzIHdlIHdlcmUgYWxyZWFkeSBhdCBNQVhJTVVNX0NBUEFDSVRZLgorICAgICAqLworICAgIHByaXZhdGUgSGFzaE1hcEVudHJ5PEssIFY+W10gZG91YmxlQ2FwYWNpdHkoKSB7CisgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPltdIG9sZFRhYmxlID0gdGFibGU7CisgICAgICAgIGludCBvbGRDYXBhY2l0eSA9IG9sZFRhYmxlLmxlbmd0aDsKKyAgICAgICAgaWYgKG9sZENhcGFjaXR5ID09IE1BWElNVU1fQ0FQQUNJVFkpIHsKKyAgICAgICAgICAgIHJldHVybiBvbGRUYWJsZTsKKyAgICAgICAgfQorICAgICAgICBpbnQgbmV3Q2FwYWNpdHkgPSBvbGRDYXBhY2l0eSAqIDI7CisgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPltdIG5ld1RhYmxlID0gbWFrZVRhYmxlKG5ld0NhcGFjaXR5KTsKKyAgICAgICAgaWYgKHNpemUgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIG5ld1RhYmxlOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBvbGRDYXBhY2l0eTsgaisrKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogUmVoYXNoIHRoZSBidWNrZXQgdXNpbmcgdGhlIG1pbmltdW0gbnVtYmVyIG9mIGZpZWxkIHdyaXRlcy4KKyAgICAgICAgICAgICAqIFRoaXMgaXMgdGhlIG1vc3Qgc3VidGxlIGFuZCBkZWxpY2F0ZSBjb2RlIGluIHRoZSBjbGFzcy4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgSGFzaE1hcEVudHJ5PEssIFY+IGUgPSBvbGRUYWJsZVtqXTsKKyAgICAgICAgICAgIGlmIChlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBoaWdoQml0ID0gZS5oYXNoICYgb2xkQ2FwYWNpdHk7CisgICAgICAgICAgICBIYXNoTWFwRW50cnk8SywgVj4gYnJva2VuID0gbnVsbDsKKyAgICAgICAgICAgIG5ld1RhYmxlW2ogfCBoaWdoQml0XSA9IGU7CisgICAgICAgICAgICBmb3IgKEhhc2hNYXBFbnRyeTxLLCBWPiBuID0gZS5uZXh0OyBuICE9IG51bGw7IGUgPSBuLCBuID0gbi5uZXh0KSB7CisgICAgICAgICAgICAgICAgaW50IG5leHRIaWdoQml0ID0gbi5oYXNoICYgb2xkQ2FwYWNpdHk7CisgICAgICAgICAgICAgICAgaWYgKG5leHRIaWdoQml0ICE9IGhpZ2hCaXQpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGJyb2tlbiA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgbmV3VGFibGVbaiB8IG5leHRIaWdoQml0XSA9IG47CisgICAgICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyb2tlbi5uZXh0ID0gbjsKKyAgICAgICAgICAgICAgICAgICAgYnJva2VuID0gZTsKKyAgICAgICAgICAgICAgICAgICAgaGlnaEJpdCA9IG5leHRIaWdoQml0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChicm9rZW4gIT0gbnVsbCkKKyAgICAgICAgICAgICAgICBicm9rZW4ubmV4dCA9IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ld1RhYmxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIG1hcHBpbmcgd2l0aCB0aGUgc3BlY2lmaWVkIGtleSBmcm9tIHRoaXMgbWFwLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBvZiB0aGUgbWFwcGluZyB0byByZW1vdmUuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHJlbW92ZWQgbWFwcGluZyBvciB7QGNvZGUgbnVsbH0gaWYgbm8gbWFwcGluZworICAgICAqICAgICAgICAgZm9yIHRoZSBzcGVjaWZpZWQga2V5IHdhcyBmb3VuZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIFYgcmVtb3ZlKE9iamVjdCBrZXkpIHsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gcmVtb3ZlTnVsbEtleSgpOworICAgICAgICB9CisgICAgICAgIGludCBoYXNoID0gc2Vjb25kYXJ5SGFzaChrZXkuaGFzaENvZGUoKSk7CisgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPltdIHRhYiA9IHRhYmxlOworICAgICAgICBpbnQgaW5kZXggPSBoYXNoICYgKHRhYi5sZW5ndGggLSAxKTsKKyAgICAgICAgZm9yIChIYXNoTWFwRW50cnk8SywgVj4gZSA9IHRhYltpbmRleF0sIHByZXYgPSBudWxsOworICAgICAgICAgICAgICAgIGUgIT0gbnVsbDsgcHJldiA9IGUsIGUgPSBlLm5leHQpIHsKKyAgICAgICAgICAgIGlmIChlLmhhc2ggPT0gaGFzaCAmJiBrZXkuZXF1YWxzKGUua2V5KSkgeworICAgICAgICAgICAgICAgIGlmIChwcmV2ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGFiW2luZGV4XSA9IGUubmV4dDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBwcmV2Lm5leHQgPSBlLm5leHQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG1vZENvdW50Kys7CisgICAgICAgICAgICAgICAgc2l6ZS0tOworICAgICAgICAgICAgICAgIHBvc3RSZW1vdmUoZSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGUudmFsdWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBWIHJlbW92ZU51bGxLZXkoKSB7CisgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPiBlID0gZW50cnlGb3JOdWxsS2V5OworICAgICAgICBpZiAoZSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBlbnRyeUZvck51bGxLZXkgPSBudWxsOworICAgICAgICBtb2RDb3VudCsrOworICAgICAgICBzaXplLS07CisgICAgICAgIHBvc3RSZW1vdmUoZSk7CisgICAgICAgIHJldHVybiBlLnZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN1YmNsYXNzIG92ZXJyaWRlcyB0aGlzIG1ldGhvZCB0byB1bmxpbmsgZW50cnkuCisgICAgICovCisgICAgdm9pZCBwb3N0UmVtb3ZlKEhhc2hNYXBFbnRyeTxLLCBWPiBlKSB7IH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIG1hcHBpbmdzIGZyb20gdGhpcyBoYXNoIG1hcCwgbGVhdmluZyBpdCBlbXB0eS4KKyAgICAgKgorICAgICAqIEBzZWUgI2lzRW1wdHkKKyAgICAgKiBAc2VlICNzaXplCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBpZiAoc2l6ZSAhPSAwKSB7CisgICAgICAgICAgICBBcnJheXMuZmlsbCh0YWJsZSwgbnVsbCk7CisgICAgICAgICAgICBlbnRyeUZvck51bGxLZXkgPSBudWxsOworICAgICAgICAgICAgbW9kQ291bnQrKzsKKyAgICAgICAgICAgIHNpemUgPSAwOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNldCBvZiB0aGUga2V5cyBjb250YWluZWQgaW4gdGhpcyBtYXAuIFRoZSBzZXQgaXMgYmFja2VkIGJ5CisgICAgICogdGhpcyBtYXAgc28gY2hhbmdlcyB0byBvbmUgYXJlIHJlZmxlY3RlZCBieSB0aGUgb3RoZXIuIFRoZSBzZXQgZG9lcyBub3QKKyAgICAgKiBzdXBwb3J0IGFkZGluZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzZXQgb2YgdGhlIGtleXMuCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTZXQ8Sz4ga2V5U2V0KCkgeworICAgICAgICBTZXQ8Sz4ga3MgPSBrZXlTZXQ7CisgICAgICAgIHJldHVybiAoa3MgIT0gbnVsbCkgPyBrcyA6IChrZXlTZXQgPSBuZXcgS2V5U2V0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb2xsZWN0aW9uIG9mIHRoZSB2YWx1ZXMgY29udGFpbmVkIGluIHRoaXMgbWFwLiBUaGUgY29sbGVjdGlvbgorICAgICAqIGlzIGJhY2tlZCBieSB0aGlzIG1hcCBzbyBjaGFuZ2VzIHRvIG9uZSBhcmUgcmVmbGVjdGVkIGJ5IHRoZSBvdGhlci4gVGhlCisgICAgICogY29sbGVjdGlvbiBzdXBwb3J0cyByZW1vdmUsIHJlbW92ZUFsbCwgcmV0YWluQWxsIGFuZCBjbGVhciBvcGVyYXRpb25zLAorICAgICAqIGFuZCBpdCBkb2VzIG5vdCBzdXBwb3J0IGFkZCBvciBhZGRBbGwgb3BlcmF0aW9ucy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIGEgY29sbGVjdGlvbiB3aGljaCBpcyB0aGUgc3ViY2xhc3Mgb2YKKyAgICAgKiBBYnN0cmFjdENvbGxlY3Rpb24uIFRoZSBpdGVyYXRvciBtZXRob2Qgb2YgdGhpcyBzdWJjbGFzcyByZXR1cm5zIGEKKyAgICAgKiAid3JhcHBlciBvYmplY3QiIG92ZXIgdGhlIGl0ZXJhdG9yIG9mIG1hcCdzIGVudHJ5U2V0KCkuIFRoZSB7QGNvZGUgc2l6ZX0KKyAgICAgKiBtZXRob2Qgd3JhcHMgdGhlIG1hcCdzIHNpemUgbWV0aG9kIGFuZCB0aGUge0Bjb2RlIGNvbnRhaW5zfSBtZXRob2Qgd3JhcHMKKyAgICAgKiB0aGUgbWFwJ3MgY29udGFpbnNWYWx1ZSBtZXRob2QuCisgICAgICogPC9wPgorICAgICAqIDxwPgorICAgICAqIFRoZSBjb2xsZWN0aW9uIGlzIGNyZWF0ZWQgd2hlbiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgZm9yIHRoZSBmaXJzdCB0aW1lCisgICAgICogYW5kIHJldHVybmVkIGluIHJlc3BvbnNlIHRvIGFsbCBzdWJzZXF1ZW50IGNhbGxzLiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuCisgICAgICogZGlmZmVyZW50IGNvbGxlY3Rpb25zIHdoZW4gbXVsdGlwbGUgY29uY3VycmVudCBjYWxscyBvY2N1ciwgc2luY2Ugbm8KKyAgICAgKiBzeW5jaHJvbml6YXRpb24gaXMgcGVyZm9ybWVkLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBjb2xsZWN0aW9uIG9mIHRoZSB2YWx1ZXMgY29udGFpbmVkIGluIHRoaXMgbWFwLgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgQ29sbGVjdGlvbjxWPiB2YWx1ZXMoKSB7CisgICAgICAgIENvbGxlY3Rpb248Vj4gdnMgPSB2YWx1ZXM7CisgICAgICAgIHJldHVybiAodnMgIT0gbnVsbCkgPyB2cyA6ICh2YWx1ZXMgPSBuZXcgVmFsdWVzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzZXQgY29udGFpbmluZyBhbGwgb2YgdGhlIG1hcHBpbmdzIGluIHRoaXMgbWFwLiBFYWNoIG1hcHBpbmcgaXMKKyAgICAgKiBhbiBpbnN0YW5jZSBvZiB7QGxpbmsgTWFwLkVudHJ5fS4gQXMgdGhlIHNldCBpcyBiYWNrZWQgYnkgdGhpcyBtYXAsCisgICAgICogY2hhbmdlcyBpbiBvbmUgd2lsbCBiZSByZWZsZWN0ZWQgaW4gdGhlIG90aGVyLgorICAgICAqCisgICAgICogQHJldHVybiBhIHNldCBvZiB0aGUgbWFwcGluZ3MuCisgICAgICovCisgICAgcHVibGljIFNldDxFbnRyeTxLLCBWPj4gZW50cnlTZXQoKSB7CisgICAgICAgIFNldDxFbnRyeTxLLCBWPj4gZXMgPSBlbnRyeVNldDsKKyAgICAgICAgcmV0dXJuIChlcyAhPSBudWxsKSA/IGVzIDogKGVudHJ5U2V0ID0gbmV3IEVudHJ5U2V0KCkpOworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBIYXNoTWFwRW50cnk8SywgVj4gaW1wbGVtZW50cyBFbnRyeTxLLCBWPiB7CisgICAgICAgIGZpbmFsIEsga2V5OworICAgICAgICBWIHZhbHVlOworICAgICAgICBmaW5hbCBpbnQgaGFzaDsKKyAgICAgICAgSGFzaE1hcEVudHJ5PEssIFY+IG5leHQ7CisKKyAgICAgICAgSGFzaE1hcEVudHJ5KEsga2V5LCBWIHZhbHVlLCBpbnQgaGFzaCwgSGFzaE1hcEVudHJ5PEssIFY+IG5leHQpIHsKKyAgICAgICAgICAgIHRoaXMua2V5ID0ga2V5OworICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgICAgICAgICAgdGhpcy5oYXNoID0gaGFzaDsKKyAgICAgICAgICAgIHRoaXMubmV4dCA9IG5leHQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgZmluYWwgSyBnZXRLZXkoKSB7CisgICAgICAgICAgICByZXR1cm4ga2V5OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGZpbmFsIFYgZ2V0VmFsdWUoKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgZmluYWwgViBzZXRWYWx1ZShWIHZhbHVlKSB7CisgICAgICAgICAgICBWIG9sZFZhbHVlID0gdGhpcy52YWx1ZTsKKyAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICAgICAgICAgIHJldHVybiBvbGRWYWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgZmluYWwgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBFbnRyeSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBFbnRyeTw/LCA/PiBlID0gKEVudHJ5PD8sID8+KSBvOworICAgICAgICAgICAgcmV0dXJuIE9iamVjdHMuZXF1YWwoZS5nZXRLZXkoKSwga2V5KQorICAgICAgICAgICAgICAgICAgICAmJiBPYmplY3RzLmVxdWFsKGUuZ2V0VmFsdWUoKSwgdmFsdWUpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBmaW5hbCBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICByZXR1cm4gKGtleSA9PSBudWxsID8gMCA6IGtleS5oYXNoQ29kZSgpKSBeCisgICAgICAgICAgICAgICAgICAgICh2YWx1ZSA9PSBudWxsID8gMCA6IHZhbHVlLmhhc2hDb2RlKCkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICByZXR1cm4ga2V5ICsgIj0iICsgdmFsdWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGFic3RyYWN0IGNsYXNzIEhhc2hJdGVyYXRvciB7CisgICAgICAgIGludCBuZXh0SW5kZXg7CisgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPiBuZXh0RW50cnkgPSBlbnRyeUZvck51bGxLZXk7CisgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPiBsYXN0RW50cnlSZXR1cm5lZDsKKyAgICAgICAgaW50IGV4cGVjdGVkTW9kQ291bnQgPSBtb2RDb3VudDsKKworICAgICAgICBIYXNoSXRlcmF0b3IoKSB7CisgICAgICAgICAgICBpZiAobmV4dEVudHJ5ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBIYXNoTWFwRW50cnk8SywgVj5bXSB0YWIgPSB0YWJsZTsKKyAgICAgICAgICAgICAgICBIYXNoTWFwRW50cnk8SywgVj4gbmV4dCA9IG51bGw7CisgICAgICAgICAgICAgICAgd2hpbGUgKG5leHQgPT0gbnVsbCAmJiBuZXh0SW5kZXggPCB0YWIubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIG5leHQgPSB0YWJbbmV4dEluZGV4KytdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBuZXh0RW50cnkgPSBuZXh0OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXh0RW50cnkgIT0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPiBuZXh0RW50cnkoKSB7CisgICAgICAgICAgICBpZiAobW9kQ291bnQgIT0gZXhwZWN0ZWRNb2RDb3VudCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgaWYgKG5leHRFbnRyeSA9PSBudWxsKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisKKyAgICAgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPiBlbnRyeVRvUmV0dXJuID0gbmV4dEVudHJ5OworICAgICAgICAgICAgSGFzaE1hcEVudHJ5PEssIFY+W10gdGFiID0gdGFibGU7CisgICAgICAgICAgICBIYXNoTWFwRW50cnk8SywgVj4gbmV4dCA9IGVudHJ5VG9SZXR1cm4ubmV4dDsKKyAgICAgICAgICAgIHdoaWxlIChuZXh0ID09IG51bGwgJiYgbmV4dEluZGV4IDwgdGFiLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIG5leHQgPSB0YWJbbmV4dEluZGV4KytdOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbmV4dEVudHJ5ID0gbmV4dDsKKyAgICAgICAgICAgIHJldHVybiBsYXN0RW50cnlSZXR1cm5lZCA9IGVudHJ5VG9SZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICBpZiAobGFzdEVudHJ5UmV0dXJuZWQgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBpZiAobW9kQ291bnQgIT0gZXhwZWN0ZWRNb2RDb3VudCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgSGFzaE1hcC50aGlzLnJlbW92ZShsYXN0RW50cnlSZXR1cm5lZC5rZXkpOworICAgICAgICAgICAgbGFzdEVudHJ5UmV0dXJuZWQgPSBudWxsOworICAgICAgICAgICAgZXhwZWN0ZWRNb2RDb3VudCA9IG1vZENvdW50OworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBLZXlJdGVyYXRvciBleHRlbmRzIEhhc2hJdGVyYXRvcgorICAgICAgICAgICAgaW1wbGVtZW50cyBJdGVyYXRvcjxLPiB7CisgICAgICAgIHB1YmxpYyBLIG5leHQoKSB7IHJldHVybiBuZXh0RW50cnkoKS5rZXk7IH0KKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIGNsYXNzIFZhbHVlSXRlcmF0b3IgZXh0ZW5kcyBIYXNoSXRlcmF0b3IKKyAgICAgICAgICAgIGltcGxlbWVudHMgSXRlcmF0b3I8Vj4geworICAgICAgICBwdWJsaWMgViBuZXh0KCkgeyByZXR1cm4gbmV4dEVudHJ5KCkudmFsdWU7IH0KKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIGNsYXNzIEVudHJ5SXRlcmF0b3IgZXh0ZW5kcyBIYXNoSXRlcmF0b3IKKyAgICAgICAgICAgIGltcGxlbWVudHMgSXRlcmF0b3I8RW50cnk8SywgVj4+IHsKKyAgICAgICAgcHVibGljIEVudHJ5PEssIFY+IG5leHQoKSB7IHJldHVybiBuZXh0RW50cnkoKTsgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIG1hcCBjb250YWlucyB0aGUgc3BlY2lmaWVkIG1hcHBpbmcuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGNvbnRhaW5zTWFwcGluZyhPYmplY3Qga2V5LCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICBIYXNoTWFwRW50cnk8SywgVj4gZSA9IGVudHJ5Rm9yTnVsbEtleTsKKyAgICAgICAgICAgIHJldHVybiBlICE9IG51bGwgJiYgT2JqZWN0cy5lcXVhbCh2YWx1ZSwgZS52YWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgaGFzaCA9IHNlY29uZGFyeUhhc2goa2V5Lmhhc2hDb2RlKCkpOworICAgICAgICBIYXNoTWFwRW50cnk8SywgVj5bXSB0YWIgPSB0YWJsZTsKKyAgICAgICAgaW50IGluZGV4ID0gaGFzaCAmICh0YWIubGVuZ3RoIC0gMSk7CisgICAgICAgIGZvciAoSGFzaE1hcEVudHJ5PEssIFY+IGUgPSB0YWJbaW5kZXhdOyBlICE9IG51bGw7IGUgPSBlLm5leHQpIHsKKyAgICAgICAgICAgIGlmIChlLmhhc2ggPT0gaGFzaCAmJiBrZXkuZXF1YWxzKGUua2V5KSkgeworICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3RzLmVxdWFsKHZhbHVlLCBlLnZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7IC8vIE5vIGVudHJ5IGZvciBrZXkKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBtYXBwaW5nIGZyb20ga2V5IHRvIHZhbHVlIGFuZCByZXR1cm5zIHRydWUgaWYgdGhpcyBtYXBwaW5nCisgICAgICogZXhpc3RzOyBvdGhlcndpc2UsIHJldHVybnMgZG9lcyBub3RoaW5nIGFuZCByZXR1cm5zIGZhbHNlLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiByZW1vdmVNYXBwaW5nKE9iamVjdCBrZXksIE9iamVjdCB2YWx1ZSkgeworICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPiBlID0gZW50cnlGb3JOdWxsS2V5OworICAgICAgICAgICAgaWYgKGUgPT0gbnVsbCB8fCAhT2JqZWN0cy5lcXVhbCh2YWx1ZSwgZS52YWx1ZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbnRyeUZvck51bGxLZXkgPSBudWxsOworICAgICAgICAgICAgbW9kQ291bnQrKzsKKyAgICAgICAgICAgIHNpemUtLTsKKyAgICAgICAgICAgIHBvc3RSZW1vdmUoZSk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBoYXNoID0gc2Vjb25kYXJ5SGFzaChrZXkuaGFzaENvZGUoKSk7CisgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPltdIHRhYiA9IHRhYmxlOworICAgICAgICBpbnQgaW5kZXggPSBoYXNoICYgKHRhYi5sZW5ndGggLSAxKTsKKyAgICAgICAgZm9yIChIYXNoTWFwRW50cnk8SywgVj4gZSA9IHRhYltpbmRleF0sIHByZXYgPSBudWxsOworICAgICAgICAgICAgICAgIGUgIT0gbnVsbDsgcHJldiA9IGUsIGUgPSBlLm5leHQpIHsKKyAgICAgICAgICAgIGlmIChlLmhhc2ggPT0gaGFzaCAmJiBrZXkuZXF1YWxzKGUua2V5KSkgeworICAgICAgICAgICAgICAgIGlmICghT2JqZWN0cy5lcXVhbCh2YWx1ZSwgZS52YWx1ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAgLy8gTWFwIGhhcyB3cm9uZyB2YWx1ZSBmb3Iga2V5CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChwcmV2ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGFiW2luZGV4XSA9IGUubmV4dDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBwcmV2Lm5leHQgPSBlLm5leHQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG1vZENvdW50Kys7CisgICAgICAgICAgICAgICAgc2l6ZS0tOworICAgICAgICAgICAgICAgIHBvc3RSZW1vdmUoZSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBObyBlbnRyeSBmb3Iga2V5CisgICAgfQorCisgICAgLy8gU3ViY2xhc3MgKExpbmtlZEhhc2hNYXApIG92ZXJyaWRlcyB0aGVzZSBmb3IgY29ycmVjdCBpdGVyYXRpb24gb3JkZXIKKyAgICBJdGVyYXRvcjxLPiBuZXdLZXlJdGVyYXRvcigpIHsgcmV0dXJuIG5ldyBLZXlJdGVyYXRvcigpOyAgIH0KKyAgICBJdGVyYXRvcjxWPiBuZXdWYWx1ZUl0ZXJhdG9yKCkgeyByZXR1cm4gbmV3IFZhbHVlSXRlcmF0b3IoKTsgfQorICAgIEl0ZXJhdG9yPEVudHJ5PEssIFY+PiBuZXdFbnRyeUl0ZXJhdG9yKCkgeyByZXR1cm4gbmV3IEVudHJ5SXRlcmF0b3IoKTsgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBLZXlTZXQgZXh0ZW5kcyBBYnN0cmFjdFNldDxLPiB7CisgICAgICAgIHB1YmxpYyBJdGVyYXRvcjxLPiBpdGVyYXRvcigpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXdLZXlJdGVyYXRvcigpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBzaXplOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICByZXR1cm4gc2l6ZSA9PSAwOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKSB7CisgICAgICAgICAgICByZXR1cm4gY29udGFpbnNLZXkobyk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvKSB7CisgICAgICAgICAgICBpbnQgb2xkU2l6ZSA9IHNpemU7CisgICAgICAgICAgICBIYXNoTWFwLnRoaXMucmVtb3ZlKG8pOworICAgICAgICAgICAgcmV0dXJuIHNpemUgIT0gb2xkU2l6ZTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgICAgIEhhc2hNYXAudGhpcy5jbGVhcigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBWYWx1ZXMgZXh0ZW5kcyBBYnN0cmFjdENvbGxlY3Rpb248Vj4geworICAgICAgICBwdWJsaWMgSXRlcmF0b3I8Vj4gaXRlcmF0b3IoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3VmFsdWVJdGVyYXRvcigpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBzaXplOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICByZXR1cm4gc2l6ZSA9PSAwOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKSB7CisgICAgICAgICAgICByZXR1cm4gY29udGFpbnNWYWx1ZShvKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgICAgIEhhc2hNYXAudGhpcy5jbGVhcigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBFbnRyeVNldCBleHRlbmRzIEFic3RyYWN0U2V0PEVudHJ5PEssIFY+PiB7CisgICAgICAgIHB1YmxpYyBJdGVyYXRvcjxFbnRyeTxLLCBWPj4gaXRlcmF0b3IoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3RW50cnlJdGVyYXRvcigpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKSB7CisgICAgICAgICAgICBpZiAoIShvIGluc3RhbmNlb2YgRW50cnkpKQorICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIEVudHJ5PD8sID8+IGUgPSAoRW50cnk8PywgPz4pIG87CisgICAgICAgICAgICByZXR1cm4gY29udGFpbnNNYXBwaW5nKGUuZ2V0S2V5KCksIGUuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvKSB7CisgICAgICAgICAgICBpZiAoIShvIGluc3RhbmNlb2YgRW50cnkpKQorICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIEVudHJ5PD8sID8+IGUgPSAoRW50cnk8PywgPz4pbzsKKyAgICAgICAgICAgIHJldHVybiByZW1vdmVNYXBwaW5nKGUuZ2V0S2V5KCksIGUuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgcmV0dXJuIHNpemU7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgICAgIHJldHVybiBzaXplID09IDA7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICBIYXNoTWFwLnRoaXMuY2xlYXIoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGxpZXMgYSBzdXBwbGVtZW50YWwgaGFzaCBmdW5jdGlvbiB0byBhIGdpdmVuIGhhc2hDb2RlLCB3aGljaCBkZWZlbmRzCisgICAgICogYWdhaW5zdCBwb29yIHF1YWxpdHkgaGFzaCBmdW5jdGlvbnMuIFRoaXMgaXMgY3JpdGljYWwgYmVjYXVzZSBIYXNoTWFwCisgICAgICogdXNlcyBwb3dlci1vZi10d28gbGVuZ3RoIGhhc2ggdGFibGVzLCB0aGF0IG90aGVyd2lzZSBlbmNvdW50ZXIgY29sbGlzaW9ucworICAgICAqIGZvciBoYXNoQ29kZXMgdGhhdCBkbyBub3QgZGlmZmVyIGluIGxvd2VyIG9yIHVwcGVyIGJpdHMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHNlY29uZGFyeUhhc2goaW50IGgpIHsKKyAgICAgICAgLy8gRG91ZyBMZWEncyBzdXBwbGVtZW50YWwgaGFzaCBmdW5jdGlvbgorICAgICAgICBoIF49IChoID4+PiAyMCkgXiAoaCA+Pj4gMTIpOworICAgICAgICByZXR1cm4gaCBeIChoID4+PiA3KSBeIChoID4+PiA0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzbWFsbGVzdCBwb3dlciBvZiB0d28gPj0gaXRzIGFyZ3VtZW50LCB3aXRoIHNldmVyYWwgY2F2ZWF0czoKKyAgICAgKiBJZiB0aGUgYXJndW1lbnQgaXMgbmVnYXRpdmUgYnV0IG5vdCBJbnRlZ2VyLk1JTl9WQUxVRSwgdGhlIG1ldGhvZCByZXR1cm5zCisgICAgICogemVyby4gSWYgdGhlIGFyZ3VtZW50IGlzID4gMl4zMCBvciBlcXVhbCB0byBJbnRlZ2VyLk1JTl9WQUxVRSwgdGhlIG1ldGhvZAorICAgICAqIHJldHVybnMgSW50ZWdlci5NSU5fVkFMVUUuIElmIHRoZSBhcmd1bWVudCBpcyB6ZXJvLCB0aGUgbWV0aG9kIHJldHVybnMKKyAgICAgKiB6ZXJvLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCByb3VuZFVwVG9Qb3dlck9mVHdvKGludCBpKSB7CisgICAgICAgIGktLTsgLy8gSWYgaW5wdXQgaXMgYSBwb3dlciBvZiB0d28sIHNoaWZ0IGl0cyBoaWdoLW9yZGVyIGJpdCByaWdodAorCisgICAgICAgIC8vICJTbWVhciIgdGhlIGhpZ2gtb3JkZXIgYml0IGFsbCB0aGUgd2F5IHRvIHRoZSByaWdodAorICAgICAgICBpIHw9IGkgPj4+ICAxOworICAgICAgICBpIHw9IGkgPj4+ICAyOworICAgICAgICBpIHw9IGkgPj4+ICA0OworICAgICAgICBpIHw9IGkgPj4+ICA4OworICAgICAgICBpIHw9IGkgPj4+IDE2OworCisgICAgICAgIHJldHVybiBpICsgMTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzNjI0OTg4MjA3NjMxODEyNjVMOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0U3RyZWFtRmllbGRbXSBzZXJpYWxQZXJzaXN0ZW50RmllbGRzID0geworICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImxvYWRGYWN0b3IiLCBmbG9hdC5jbGFzcykKKyAgICB9OworCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIEVtdWxhdGUgbG9hZEZhY3RvciBmaWVsZCBmb3Igb3RoZXIgaW1wbGVtZW50YXRpb25zIHRvIHJlYWQKKyAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtLlB1dEZpZWxkIGZpZWxkcyA9IHN0cmVhbS5wdXRGaWVsZHMoKTsKKyAgICAgICAgZmllbGRzLnB1dCgibG9hZEZhY3RvciIsIERFRkFVTFRfTE9BRF9GQUNUT1IpOworICAgICAgICBzdHJlYW0ud3JpdGVGaWVsZHMoKTsKKworICAgICAgICBzdHJlYW0ud3JpdGVJbnQodGFibGUubGVuZ3RoKTsgLy8gQ2FwYWNpdHkKKyAgICAgICAgc3RyZWFtLndyaXRlSW50KHNpemUpOworICAgICAgICBmb3IgKEVudHJ5PEssIFY+IGUgOiBlbnRyeVNldCgpKSB7CisgICAgICAgICAgICBzdHJlYW0ud3JpdGVPYmplY3QoZS5nZXRLZXkoKSk7CisgICAgICAgICAgICBzdHJlYW0ud3JpdGVPYmplY3QoZS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIHN0cmVhbS5kZWZhdWx0UmVhZE9iamVjdCgpOworICAgICAgICBpbnQgY2FwYWNpdHkgPSBzdHJlYW0ucmVhZEludCgpOworICAgICAgICBpZiAoY2FwYWNpdHkgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9iamVjdEV4Y2VwdGlvbigiQ2FwYWNpdHk6ICIgKyBjYXBhY2l0eSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNhcGFjaXR5IDwgTUlOSU1VTV9DQVBBQ0lUWSkgeworICAgICAgICAgICAgY2FwYWNpdHkgPSBNSU5JTVVNX0NBUEFDSVRZOworICAgICAgICB9IGVsc2UgaWYgKGNhcGFjaXR5ID4gTUFYSU1VTV9DQVBBQ0lUWSkgeworICAgICAgICAgICAgY2FwYWNpdHkgPSBNQVhJTVVNX0NBUEFDSVRZOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY2FwYWNpdHkgPSByb3VuZFVwVG9Qb3dlck9mVHdvKGNhcGFjaXR5KTsKKyAgICAgICAgfQorICAgICAgICBtYWtlVGFibGUoY2FwYWNpdHkpOworCisgICAgICAgIGludCBzaXplID0gc3RyZWFtLnJlYWRJbnQoKTsKKyAgICAgICAgaWYgKHNpemUgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9iamVjdEV4Y2VwdGlvbigiU2l6ZTogIiArIHNpemUpOworICAgICAgICB9CisKKyAgICAgICAgaW5pdCgpOyAvLyBHaXZlIHN1YmNsYXNzIChMaW5rZWRIYXNoTWFwKSBhIGNoYW5jZSB0byBpbml0aWFsaXplIGl0c2VsZgorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIEsga2V5ID0gKEspIHN0cmVhbS5yZWFkT2JqZWN0KCk7CisgICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikgViB2YWwgPSAoVikgc3RyZWFtLnJlYWRPYmplY3QoKTsKKyAgICAgICAgICAgIGNvbnN0cnVjdG9yUHV0KGtleSwgdmFsKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvSGFzaFNldC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9IYXNoU2V0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTM1ZmQ1NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvSGFzaFNldC5qYXZhCkBAIC0wLDAgKzEsMjEzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworLyoqCisgKiBIYXNoU2V0IGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIGEgU2V0LiBBbGwgb3B0aW9uYWwgb3BlcmF0aW9ucyAoYWRkaW5nIGFuZAorICogcmVtb3ZpbmcpIGFyZSBzdXBwb3J0ZWQuIFRoZSBlbGVtZW50cyBjYW4gYmUgYW55IG9iamVjdHMuCisgKi8KK3B1YmxpYyBjbGFzcyBIYXNoU2V0PEU+IGV4dGVuZHMgQWJzdHJhY3RTZXQ8RT4gaW1wbGVtZW50cyBTZXQ8RT4sIENsb25lYWJsZSwKKyAgICAgICAgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC01MDI0NzQ0NDA2NzEzMzIxNjc2TDsKKworICAgIHRyYW5zaWVudCBIYXNoTWFwPEUsIEhhc2hTZXQ8RT4+IGJhY2tpbmdNYXA7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGVtcHR5IGluc3RhbmNlIG9mIHtAY29kZSBIYXNoU2V0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSGFzaFNldCgpIHsKKyAgICAgICAgdGhpcyhuZXcgSGFzaE1hcDxFLCBIYXNoU2V0PEU+PigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBIYXNoU2V0fSB3aXRoIHRoZSBzcGVjaWZpZWQgY2FwYWNpdHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2FwYWNpdHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIGNhcGFjaXR5IG9mIHRoaXMge0Bjb2RlIEhhc2hTZXR9LgorICAgICAqLworICAgIHB1YmxpYyBIYXNoU2V0KGludCBjYXBhY2l0eSkgeworICAgICAgICB0aGlzKG5ldyBIYXNoTWFwPEUsIEhhc2hTZXQ8RT4+KGNhcGFjaXR5KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgSGFzaFNldH0gd2l0aCB0aGUgc3BlY2lmaWVkIGNhcGFjaXR5CisgICAgICogYW5kIGxvYWQgZmFjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGNhcGFjaXR5CisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBjYXBhY2l0eS4KKyAgICAgKiBAcGFyYW0gbG9hZEZhY3RvcgorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgbG9hZCBmYWN0b3IuCisgICAgICovCisgICAgcHVibGljIEhhc2hTZXQoaW50IGNhcGFjaXR5LCBmbG9hdCBsb2FkRmFjdG9yKSB7CisgICAgICAgIHRoaXMobmV3IEhhc2hNYXA8RSwgSGFzaFNldDxFPj4oY2FwYWNpdHksIGxvYWRGYWN0b3IpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBIYXNoU2V0fSBjb250YWluaW5nIHRoZSB1bmlxdWUKKyAgICAgKiBlbGVtZW50cyBpbiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbGxlY3Rpb24gb2YgZWxlbWVudHMgdG8gYWRkLgorICAgICAqLworICAgIHB1YmxpYyBIYXNoU2V0KENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgdGhpcyhuZXcgSGFzaE1hcDxFLCBIYXNoU2V0PEU+Pihjb2xsZWN0aW9uLnNpemUoKSA8IDYgPyAxMSA6IGNvbGxlY3Rpb24KKyAgICAgICAgICAgICAgICAuc2l6ZSgpICogMikpOworICAgICAgICBmb3IgKEUgZSA6IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIGFkZChlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEhhc2hTZXQoSGFzaE1hcDxFLCBIYXNoU2V0PEU+PiBiYWNraW5nTWFwKSB7CisgICAgICAgIHRoaXMuYmFja2luZ01hcCA9IGJhY2tpbmdNYXA7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIG9iamVjdCB0byB0aGlzIHtAY29kZSBIYXNoU2V0fSBpZiBub3QgYWxyZWFkeSBwcmVzZW50LgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBhZGQuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gd2hlbiB0aGlzIHtAY29kZSBIYXNoU2V0fSBkaWQgbm90IGFscmVhZHkgY29udGFpbgorICAgICAqICAgICAgICAgdGhlIG9iamVjdCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBhZGQoRSBvYmplY3QpIHsKKyAgICAgICAgcmV0dXJuIGJhY2tpbmdNYXAucHV0KG9iamVjdCwgdGhpcykgPT0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGFsbCBlbGVtZW50cyBmcm9tIHRoaXMge0Bjb2RlIEhhc2hTZXR9LCBsZWF2aW5nIGl0IGVtcHR5LgorICAgICAqCisgICAgICogQHNlZSAjaXNFbXB0eQorICAgICAqIEBzZWUgI3NpemUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgYmFja2luZ01hcC5jbGVhcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEhhc2hTZXR9IHdpdGggdGhlIHNhbWUgZWxlbWVudHMgYW5kIHNpemUgYXMgdGhpcworICAgICAqIHtAY29kZSBIYXNoU2V0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzaGFsbG93IGNvcHkgb2YgdGhpcyB7QGNvZGUgSGFzaFNldH0uCisgICAgICogQHNlZSBqYXZhLmxhbmcuQ2xvbmVhYmxlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEhhc2hTZXQ8RT4gY2xvbmUgPSAoSGFzaFNldDxFPikgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgICAgIGNsb25lLmJhY2tpbmdNYXAgPSAoSGFzaE1hcDxFLCBIYXNoU2V0PEU+PikgYmFja2luZ01hcC5jbG9uZSgpOworICAgICAgICAgICAgcmV0dXJuIGNsb25lOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyB0aGlzIHtAY29kZSBIYXNoU2V0fSBmb3IgdGhlIHNwZWNpZmllZCBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIHNlYXJjaCBmb3IuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIG9iamVjdH0gaXMgYW4gZWxlbWVudCBvZiB0aGlzCisgICAgICogICAgICAgICB7QGNvZGUgSGFzaFNldH0sIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgcmV0dXJuIGJhY2tpbmdNYXAuY29udGFpbnNLZXkob2JqZWN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyB7QGNvZGUgSGFzaFNldH0gaGFzIG5vIGVsZW1lbnRzLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBIYXNoU2V0fSBoYXMgbm8gZWxlbWVudHMsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNzaXplCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgcmV0dXJuIGJhY2tpbmdNYXAuaXNFbXB0eSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gSXRlcmF0b3Igb24gdGhlIGVsZW1lbnRzIG9mIHRoaXMge0Bjb2RlIEhhc2hTZXR9LgorICAgICAqCisgICAgICogQHJldHVybiBhbiBJdGVyYXRvciBvbiB0aGUgZWxlbWVudHMgb2YgdGhpcyB7QGNvZGUgSGFzaFNldH0uCisgICAgICogQHNlZSBJdGVyYXRvcgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJdGVyYXRvcjxFPiBpdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIGJhY2tpbmdNYXAua2V5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGZyb20gdGhpcyB7QGNvZGUgSGFzaFNldH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIHJlbW92ZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgb2JqZWN0IHdhcyByZW1vdmVkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG9iamVjdCkgeworICAgICAgICByZXR1cm4gYmFja2luZ01hcC5yZW1vdmUob2JqZWN0KSAhPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIHtAY29kZSBIYXNoU2V0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIHtAY29kZSBIYXNoU2V0fS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgIHJldHVybiBiYWNraW5nTWFwLnNpemUoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3RyZWFtLmRlZmF1bHRXcml0ZU9iamVjdCgpOworICAgICAgICBzdHJlYW0ud3JpdGVJbnQoYmFja2luZ01hcC50YWJsZS5sZW5ndGgpOworICAgICAgICBzdHJlYW0ud3JpdGVGbG9hdChIYXNoTWFwLkRFRkFVTFRfTE9BRF9GQUNUT1IpOworICAgICAgICBzdHJlYW0ud3JpdGVJbnQoc2l6ZSgpKTsKKyAgICAgICAgZm9yIChFIGUgOiB0aGlzKSB7CisgICAgICAgICAgICBzdHJlYW0ud3JpdGVPYmplY3QoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBzdHJlYW0uZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgaW50IGxlbmd0aCA9IHN0cmVhbS5yZWFkSW50KCk7CisgICAgICAgIGZsb2F0IGxvYWRGYWN0b3IgPSBzdHJlYW0ucmVhZEZsb2F0KCk7CisgICAgICAgIGJhY2tpbmdNYXAgPSBjcmVhdGVCYWNraW5nTWFwKGxlbmd0aCwgbG9hZEZhY3Rvcik7CisgICAgICAgIGludCBlbGVtZW50Q291bnQgPSBzdHJlYW0ucmVhZEludCgpOworICAgICAgICBmb3IgKGludCBpID0gZWxlbWVudENvdW50OyAtLWkgPj0gMDspIHsKKyAgICAgICAgICAgIEUga2V5ID0gKEUpIHN0cmVhbS5yZWFkT2JqZWN0KCk7CisgICAgICAgICAgICBiYWNraW5nTWFwLnB1dChrZXksIHRoaXMpOworICAgICAgICB9CisgICAgfQorCisgICAgSGFzaE1hcDxFLCBIYXNoU2V0PEU+PiBjcmVhdGVCYWNraW5nTWFwKGludCBjYXBhY2l0eSwgZmxvYXQgbG9hZEZhY3RvcikgeworICAgICAgICByZXR1cm4gbmV3IEhhc2hNYXA8RSwgSGFzaFNldDxFPj4oY2FwYWNpdHksIGxvYWRGYWN0b3IpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvSGFzaHRhYmxlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0hhc2h0YWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNlYTI5ZGEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0hhc2h0YWJsZS5qYXZhCkBAIC0wLDAgKzEsMTE0MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW52YWxpZE9iamVjdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0U3RyZWFtRmllbGQ7CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKKy8qKgorICogSGFzaHRhYmxlIGlzIGEgc3luY2hyb25pemVkIGltcGxlbWVudGF0aW9uIG9mIHtAbGluayBNYXB9LiBBbGwgb3B0aW9uYWwgb3BlcmF0aW9ucyBhcmUgc3VwcG9ydGVkLgorICoKKyAqIDxwPk5laXRoZXIga2V5cyBub3IgdmFsdWVzIGNhbiBiZSBudWxsLiAoVXNlIHtAY29kZSBIYXNoTWFwfSBvciB7QGNvZGUgTGlua2VkSGFzaE1hcH0gaWYgeW91CisgKiBuZWVkIG51bGwga2V5cyBvciB2YWx1ZXMuKQorICoKKyAqIEBwYXJhbSA8Sz4gdGhlIHR5cGUgb2Yga2V5cyBtYWludGFpbmVkIGJ5IHRoaXMgbWFwCisgKiBAcGFyYW0gPFY+IHRoZSB0eXBlIG9mIG1hcHBlZCB2YWx1ZXMKKyAqIEBzZWUgSGFzaE1hcAorICovCitwdWJsaWMgY2xhc3MgSGFzaHRhYmxlPEssIFY+IGV4dGVuZHMgRGljdGlvbmFyeTxLLCBWPgorICAgICAgICBpbXBsZW1lbnRzIE1hcDxLLCBWPiwgQ2xvbmVhYmxlLCBTZXJpYWxpemFibGUgeworICAgIC8qKgorICAgICAqIE1pbiBjYXBhY2l0eSAob3RoZXIgdGhhbiB6ZXJvKSBmb3IgYSBIYXNodGFibGUuIE11c3QgYmUgYSBwb3dlciBvZiB0d28KKyAgICAgKiBncmVhdGVyIHRoYW4gMSAoYW5kIGxlc3MgdGhhbiAxIDw8IDMwKS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUlOSU1VTV9DQVBBQ0lUWSA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBNYXggY2FwYWNpdHkgZm9yIGEgSGFzaHRhYmxlLiBNdXN0IGJlIGEgcG93ZXIgb2YgdHdvID49IE1JTklNVU1fQ0FQQUNJVFkuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWElNVU1fQ0FQQUNJVFkgPSAxIDw8IDMwOworCisgICAgLyoqCisgICAgICogQW4gZW1wdHkgdGFibGUgc2hhcmVkIGJ5IGFsbCB6ZXJvLWNhcGFjaXR5IG1hcHMgKHR5cGljYWxseSBmcm9tIGRlZmF1bHQKKyAgICAgKiBjb25zdHJ1Y3RvcikuIEl0IGlzIG5ldmVyIHdyaXR0ZW4gdG8sIGFuZCByZXBsYWNlZCBvbiBmaXJzdCBwdXQuIEl0cyBzaXplCisgICAgICogaXMgc2V0IHRvIGhhbGYgdGhlIG1pbmltdW0sIHNvIHRoYXQgdGhlIGZpcnN0IHJlc2l6ZSB3aWxsIGNyZWF0ZSBhCisgICAgICogbWluaW11bS1zaXplZCB0YWJsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFbnRyeVtdIEVNUFRZX1RBQkxFCisgICAgICAgICAgICA9IG5ldyBIYXNodGFibGVFbnRyeVtNSU5JTVVNX0NBUEFDSVRZID4+PiAxXTsKKworICAgIC8qKgorICAgICAqIFRoZSBkZWZhdWx0IGxvYWQgZmFjdG9yLiBOb3RlIHRoYXQgdGhpcyBpbXBsZW1lbnRhdGlvbiBpZ25vcmVzIHRoZQorICAgICAqIGxvYWQgZmFjdG9yLCBidXQgY2Fubm90IGRvIGF3YXkgd2l0aCBpdCBlbnRpcmVseSBiZWNhdXNlIGl0J3MKKyAgICAgKiBtZW50aW9uZWQgaW4gdGhlIEFQSS4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB0aGlzIGNvbnN0YW50IGhhcyBubyBpbXBhY3Qgb24gdGhlIGJlaGF2aW9yIG9mIHRoZSBwcm9ncmFtLAorICAgICAqIGJ1dCBpdCBpcyBlbWl0dGVkIGFzIHBhcnQgb2YgdGhlIHNlcmlhbGl6ZWQgZm9ybS4gVGhlIGxvYWQgZmFjdG9yIG9mCisgICAgICogLjc1IGlzIGhhcmR3aXJlZCBpbnRvIHRoZSBwcm9ncmFtLCB3aGljaCB1c2VzIGNoZWFwIHNoaWZ0cyBpbiBwbGFjZSBvZgorICAgICAqIGV4cGVuc2l2ZSBkaXZpc2lvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBmbG9hdCBERUZBVUxUX0xPQURfRkFDVE9SID0gLjc1RjsKKworICAgIC8qKgorICAgICAqIFRoZSBoYXNoIHRhYmxlLgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IEhhc2h0YWJsZUVudHJ5PEssIFY+W10gdGFibGU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtYmVyIG9mIG1hcHBpbmdzIGluIHRoaXMgaGFzaCBtYXAuCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IHNpemU7CisKKyAgICAvKioKKyAgICAgKiBJbmNyZW1lbnRlZCBieSAic3RydWN0dXJhbCBtb2RpZmljYXRpb25zIiB0byBhbGxvdyAoYmVzdCBlZmZvcnQpCisgICAgICogZGV0ZWN0aW9uIG9mIGNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IGludCBtb2RDb3VudDsKKworICAgIC8qKgorICAgICAqIFRoZSB0YWJsZSBpcyByZWhhc2hlZCB3aGVuIGl0cyBzaXplIGV4Y2VlZHMgdGhpcyB0aHJlc2hvbGQuCisgICAgICogVGhlIHZhbHVlIG9mIHRoaXMgZmllbGQgaXMgZ2VuZXJhbGx5IC43NSAqIGNhcGFjaXR5LCBleGNlcHQgd2hlbgorICAgICAqIHRoZSBjYXBhY2l0eSBpcyB6ZXJvLCBhcyBkZXNjcmliZWQgaW4gdGhlIEVNUFRZX1RBQkxFIGRlY2xhcmF0aW9uCisgICAgICogYWJvdmUuCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IHRocmVzaG9sZDsKKworICAgIC8vIFZpZXdzIC0gbGF6aWx5IGluaXRpYWxpemVkCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgU2V0PEs+IGtleVNldDsKKyAgICBwcml2YXRlIHRyYW5zaWVudCBTZXQ8RW50cnk8SywgVj4+IGVudHJ5U2V0OworICAgIHByaXZhdGUgdHJhbnNpZW50IENvbGxlY3Rpb248Vj4gdmFsdWVzOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSGFzaHRhYmxlfSB1c2luZyB0aGUgZGVmYXVsdCBjYXBhY2l0eSBhbmQgbG9hZAorICAgICAqIGZhY3Rvci4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgSGFzaHRhYmxlKCkgeworICAgICAgICB0YWJsZSA9IChIYXNodGFibGVFbnRyeTxLLCBWPltdKSBFTVBUWV9UQUJMRTsKKyAgICAgICAgdGhyZXNob2xkID0gLTE7IC8vIEZvcmNlcyBmaXJzdCBwdXQgaW52b2NhdGlvbiB0byByZXBsYWNlIEVNUFRZX1RBQkxFCisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSGFzaHRhYmxlfSB1c2luZyB0aGUgc3BlY2lmaWVkIGNhcGFjaXR5IGFuZCB0aGUKKyAgICAgKiBkZWZhdWx0IGxvYWQgZmFjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGNhcGFjaXR5CisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBjYXBhY2l0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSGFzaHRhYmxlKGludCBjYXBhY2l0eSkgeworICAgICAgICBpZiAoY2FwYWNpdHkgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJDYXBhY2l0eTogIiArIGNhcGFjaXR5KTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjYXBhY2l0eSA9PSAwKSB7CisgICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgICAgIEhhc2h0YWJsZUVudHJ5PEssIFY+W10gdGFiID0gKEhhc2h0YWJsZUVudHJ5PEssIFY+W10pIEVNUFRZX1RBQkxFOworICAgICAgICAgICAgdGFibGUgPSB0YWI7CisgICAgICAgICAgICB0aHJlc2hvbGQgPSAtMTsgLy8gRm9yY2VzIGZpcnN0IHB1dCgpIHRvIHJlcGxhY2UgRU1QVFlfVEFCTEUKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjYXBhY2l0eSA8IE1JTklNVU1fQ0FQQUNJVFkpIHsKKyAgICAgICAgICAgIGNhcGFjaXR5ID0gTUlOSU1VTV9DQVBBQ0lUWTsKKyAgICAgICAgfSBlbHNlIGlmIChjYXBhY2l0eSA+IE1BWElNVU1fQ0FQQUNJVFkpIHsKKyAgICAgICAgICAgIGNhcGFjaXR5ID0gTUFYSU1VTV9DQVBBQ0lUWTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNhcGFjaXR5ID0gcm91bmRVcFRvUG93ZXJPZlR3byhjYXBhY2l0eSk7CisgICAgICAgIH0KKyAgICAgICAgbWFrZVRhYmxlKGNhcGFjaXR5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBIYXNodGFibGV9IHVzaW5nIHRoZSBzcGVjaWZpZWQgY2FwYWNpdHkgYW5kIGxvYWQKKyAgICAgKiBmYWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2FwYWNpdHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIGNhcGFjaXR5LgorICAgICAqIEBwYXJhbSBsb2FkRmFjdG9yCisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBsb2FkIGZhY3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgSGFzaHRhYmxlKGludCBjYXBhY2l0eSwgZmxvYXQgbG9hZEZhY3RvcikgeworICAgICAgICB0aGlzKGNhcGFjaXR5KTsKKworICAgICAgICBpZiAobG9hZEZhY3RvciA8PSAwIHx8IEZsb2F0LmlzTmFOKGxvYWRGYWN0b3IpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJMb2FkIGZhY3RvcjogIiArIGxvYWRGYWN0b3IpOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogTm90ZSB0aGF0IHRoaXMgaW1wbGVtZW50YXRpb24gaWdub3JlcyBsb2FkRmFjdG9yOyBpdCBhbHdheXMgdXNlcworICAgICAgICAgKiBhIGxvYWQgZmFjdG9yIG9mIDMvNC4gVGhpcyBzaW1wbGlmaWVzIHRoZSBjb2RlIGFuZCBnZW5lcmFsbHkKKyAgICAgICAgICogaW1wcm92ZXMgcGVyZm9ybWFuY2UuCisgICAgICAgICAqLworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEhhc2h0YWJsZX0gY29udGFpbmluZyB0aGUgbWFwcGluZ3MKKyAgICAgKiBmcm9tIHRoZSBzcGVjaWZpZWQgbWFwLgorICAgICAqCisgICAgICogQHBhcmFtIG1hcAorICAgICAqICAgICAgICAgICAgdGhlIG1hcHBpbmdzIHRvIGFkZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSGFzaHRhYmxlKE1hcDw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+IG1hcCkgeworICAgICAgICB0aGlzKGNhcGFjaXR5Rm9ySW5pdFNpemUobWFwLnNpemUoKSkpOworICAgICAgICBjb25zdHJ1Y3RvclB1dEFsbChtYXApOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgYWxsIG9mIHRoZSBlbGVtZW50cyBvZiBtYXAgaW50byB0aGlzIEhhc2h0YWJsZSBpbiBhIG1hbm5lcgorICAgICAqIHN1aXRhYmxlIGZvciB1c2UgYnkgY29uc3RydWN0b3JzIGFuZCBwc2V1ZG8tY29uc3RydWN0b3JzIChpLmUuLCBjbG9uZSwKKyAgICAgKiByZWFkT2JqZWN0KS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY29uc3RydWN0b3JQdXRBbGwoTWFwPD8gZXh0ZW5kcyBLLCA/IGV4dGVuZHMgVj4gbWFwKSB7CisgICAgICAgIGZvciAoRW50cnk8PyBleHRlbmRzIEssID8gZXh0ZW5kcyBWPiBlIDogbWFwLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIGNvbnN0cnVjdG9yUHV0KGUuZ2V0S2V5KCksIGUuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFwcHJvcHJpYXRlIGNhcGFjaXR5IGZvciB0aGUgc3BlY2lmaWVkIGluaXRpYWwgc2l6ZS4gRG9lcworICAgICAqIG5vdCByb3VuZCB0aGUgcmVzdWx0IHVwIHRvIGEgcG93ZXIgb2YgdHdvOyB0aGUgY2FsbGVyIG11c3QgZG8gdGhpcyEKKyAgICAgKiBUaGUgcmV0dXJuZWQgdmFsdWUgd2lsbCBiZSBiZXR3ZWVuIDAgYW5kIE1BWElNVU1fQ0FQQUNJVFkgKGluY2x1c2l2ZSkuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGNhcGFjaXR5Rm9ySW5pdFNpemUoaW50IHNpemUpIHsKKyAgICAgICAgaW50IHJlc3VsdCA9IChzaXplID4+IDEpICsgc2l6ZTsgLy8gTXVsdGlwbHkgYnkgMy8yIHRvIGFsbG93IGZvciBncm93dGgKKworICAgICAgICAvLyBib29sZWFuIGV4cHIgaXMgZXF1aXZhbGVudCB0byByZXN1bHQgPj0gMCAmJiByZXN1bHQ8TUFYSU1VTV9DQVBBQ0lUWQorICAgICAgICByZXR1cm4gKHJlc3VsdCAmIH4oTUFYSU1VTV9DQVBBQ0lUWS0xKSk9PTAgPyByZXN1bHQgOiBNQVhJTVVNX0NBUEFDSVRZOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0Bjb2RlIEhhc2h0YWJsZX0gd2l0aCB0aGUgc2FtZSBrZXkvdmFsdWUgcGFpcnMsIGNhcGFjaXR5CisgICAgICogYW5kIGxvYWQgZmFjdG9yLgorICAgICAqCisgICAgICogQHJldHVybiBhIHNoYWxsb3cgY29weSBvZiB0aGlzIHtAY29kZSBIYXNodGFibGV9LgorICAgICAqIEBzZWUgamF2YS5sYW5nLkNsb25lYWJsZQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIEBPdmVycmlkZSBwdWJsaWMgc3luY2hyb25pemVkIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogVGhpcyBjb3VsZCBiZSBtYWRlIG1vcmUgZWZmaWNpZW50LiBJdCB1bm5lY2Vzc2FyaWx5IGhhc2hlcyBhbGwgb2YKKyAgICAgICAgICogdGhlIGVsZW1lbnRzIGluIHRoZSBtYXAuCisgICAgICAgICAqLworICAgICAgICBIYXNodGFibGU8SywgVj4gcmVzdWx0OworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzdWx0ID0gKEhhc2h0YWJsZTxLLCBWPikgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGUpOworICAgICAgICB9CisKKyAgICAgICAgLy8gUmVzdG9yZSBjbG9uZSB0byBlbXB0eSBzdGF0ZSwgcmV0YWluaW5nIG91ciBjYXBhY2l0eSBhbmQgdGhyZXNob2xkCisgICAgICAgIHJlc3VsdC5tYWtlVGFibGUodGFibGUubGVuZ3RoKTsKKyAgICAgICAgcmVzdWx0LnNpemUgPSAwOworICAgICAgICByZXN1bHQua2V5U2V0ID0gbnVsbDsKKyAgICAgICAgcmVzdWx0LmVudHJ5U2V0ID0gbnVsbDsKKyAgICAgICAgcmVzdWx0LnZhbHVlcyA9IG51bGw7CisKKyAgICAgICAgcmVzdWx0LmNvbnN0cnVjdG9yUHV0QWxsKHRoaXMpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHtAY29kZSBIYXNodGFibGV9IGhhcyBubyBrZXkvdmFsdWUgcGFpcnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBIYXNodGFibGV9IGhhcyBubyBrZXkvdmFsdWUgcGFpcnMsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNzaXplCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgIHJldHVybiBzaXplID09IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGtleS92YWx1ZSBwYWlycyBpbiB0aGlzIHtAY29kZSBIYXNodGFibGV9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGtleS92YWx1ZSBwYWlycyBpbiB0aGlzIHtAY29kZSBIYXNodGFibGV9LgorICAgICAqIEBzZWUgI2VsZW1lbnRzCisgICAgICogQHNlZSAja2V5cworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IHNpemUoKSB7CisgICAgICAgIHJldHVybiBzaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGtleSBpbiB0aGlzCisgICAgICoge0Bjb2RlIEhhc2h0YWJsZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IG9mIHRoZSB2YWx1ZSByZXR1cm5lZC4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBrZXksIG9yIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAgdGhlIHNwZWNpZmllZCBrZXkgZG9lcyBub3QgZXhpc3QuCisgICAgICogQHNlZSAjcHV0CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBWIGdldChPYmplY3Qga2V5KSB7CisgICAgICAgIC8vIERvdWcgTGVhJ3Mgc3VwcGxlbWVudGFsIHNlY29uZGFyeUhhc2ggZnVuY3Rpb24gKGlubGluZWQpCisgICAgICAgIGludCBoYXNoID0ga2V5Lmhhc2hDb2RlKCk7CisgICAgICAgIGhhc2ggXj0gKGhhc2ggPj4+IDIwKSBeIChoYXNoID4+PiAxMik7CisgICAgICAgIGhhc2ggXj0gKGhhc2ggPj4+IDcpIF4gKGhhc2ggPj4+IDQpOworCisgICAgICAgIEhhc2h0YWJsZUVudHJ5PEssIFY+W10gdGFiID0gdGFibGU7CisgICAgICAgIGZvciAoSGFzaHRhYmxlRW50cnk8SywgVj4gZSA9IHRhYltoYXNoICYgKHRhYi5sZW5ndGggLSAxKV07CisgICAgICAgICAgICAgICAgZSAhPSBudWxsOyBlID0gZS5uZXh0KSB7CisgICAgICAgICAgICBLIGVLZXkgPSBlLmtleTsKKyAgICAgICAgICAgIGlmIChlS2V5ID09IGtleSB8fCAoZS5oYXNoID09IGhhc2ggJiYga2V5LmVxdWFscyhlS2V5KSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZS52YWx1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyB7QGNvZGUgSGFzaHRhYmxlfSBjb250YWlucyB0aGUgc3BlY2lmaWVkIG9iamVjdCBhcyBhCisgICAgICoga2V5IG9mIG9uZSBvZiB0aGUga2V5L3ZhbHVlIHBhaXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBsb29rIGZvciBhcyBhIGtleSBpbiB0aGlzIHtAY29kZSBIYXNodGFibGV9LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIG9iamVjdCBpcyBhIGtleSBpbiB0aGlzIHtAY29kZSBIYXNodGFibGV9LAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNlZSAjY29udGFpbnMKKyAgICAgKiBAc2VlIGphdmEubGFuZy5PYmplY3QjZXF1YWxzCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrZXkpIHsKKyAgICAgICAgLy8gRG91ZyBMZWEncyBzdXBwbGVtZW50YWwgc2Vjb25kYXJ5SGFzaCBmdW5jdGlvbiAoaW5saW5lZCkKKyAgICAgICAgaW50IGhhc2ggPSBrZXkuaGFzaENvZGUoKTsKKyAgICAgICAgaGFzaCBePSAoaGFzaCA+Pj4gMjApIF4gKGhhc2ggPj4+IDEyKTsKKyAgICAgICAgaGFzaCBePSAoaGFzaCA+Pj4gNykgXiAoaGFzaCA+Pj4gNCk7CisKKyAgICAgICAgSGFzaHRhYmxlRW50cnk8SywgVj5bXSB0YWIgPSB0YWJsZTsKKyAgICAgICAgZm9yIChIYXNodGFibGVFbnRyeTxLLCBWPiBlID0gdGFiW2hhc2ggJiAodGFiLmxlbmd0aCAtIDEpXTsKKyAgICAgICAgICAgICAgICBlICE9IG51bGw7IGUgPSBlLm5leHQpIHsKKyAgICAgICAgICAgIEsgZUtleSA9IGUua2V5OworICAgICAgICAgICAgaWYgKGVLZXkgPT0ga2V5IHx8IChlLmhhc2ggPT0gaGFzaCAmJiBrZXkuZXF1YWxzKGVLZXkpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyB0aGlzIHtAY29kZSBIYXNodGFibGV9IGZvciB0aGUgc3BlY2lmaWVkIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIHNlYXJjaCBmb3IuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIHZhbHVlfSBpcyBhIHZhbHVlIG9mIHRoaXMKKyAgICAgKiAgICAgICAgIHtAY29kZSBIYXNodGFibGV9LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gY29udGFpbnNWYWx1ZShPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgSGFzaHRhYmxlRW50cnlbXSB0YWIgPSB0YWJsZTsKKyAgICAgICAgaW50IGxlbiA9IHRhYi5sZW5ndGg7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgICAgICAgZm9yIChIYXNodGFibGVFbnRyeSBlID0gdGFiW2ldOyBlICE9IG51bGw7IGUgPSBlLm5leHQpIHsKKyAgICAgICAgICAgICAgICBpZiAodmFsdWUuZXF1YWxzKGUudmFsdWUpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMge0Bjb2RlIEhhc2h0YWJsZX0gY29udGFpbnMgdGhlIHNwZWNpZmllZCBvYmplY3QgYXMKKyAgICAgKiB0aGUgdmFsdWUgb2YgYXQgbGVhc3Qgb25lIG9mIHRoZSBrZXkvdmFsdWUgcGFpcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gbG9vayBmb3IgYXMgYSB2YWx1ZSBpbiB0aGlzIHtAY29kZSBIYXNodGFibGV9LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIG9iamVjdCBpcyBhIHZhbHVlIGluIHRoaXMge0Bjb2RlIEhhc2h0YWJsZX0sCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNjb250YWluc0tleQorICAgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCNlcXVhbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIGNvbnRhaW5zVmFsdWUodmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFzc29jaWF0ZSB0aGUgc3BlY2lmaWVkIHZhbHVlIHdpdGggdGhlIHNwZWNpZmllZCBrZXkgaW4gdGhpcworICAgICAqIHtAY29kZSBIYXNodGFibGV9LiBJZiB0aGUga2V5IGFscmVhZHkgZXhpc3RzLCB0aGUgb2xkIHZhbHVlIGlzIHJlcGxhY2VkLgorICAgICAqIFRoZSBrZXkgYW5kIHZhbHVlIGNhbm5vdCBiZSBudWxsLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byBhZGQuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gYWRkLgorICAgICAqIEByZXR1cm4gdGhlIG9sZCB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBrZXksIG9yIHtAY29kZSBudWxsfQorICAgICAqICAgICAgICAgaWYgdGhlIGtleSBkaWQgbm90IGV4aXN0LgorICAgICAqIEBzZWUgI2VsZW1lbnRzCisgICAgICogQHNlZSAjZ2V0CisgICAgICogQHNlZSAja2V5cworICAgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCNlcXVhbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFYgcHV0KEsga2V5LCBWIHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgaGFzaCA9IHNlY29uZGFyeUhhc2goa2V5Lmhhc2hDb2RlKCkpOworICAgICAgICBIYXNodGFibGVFbnRyeTxLLCBWPltdIHRhYiA9IHRhYmxlOworICAgICAgICBpbnQgaW5kZXggPSBoYXNoICYgKHRhYi5sZW5ndGggLSAxKTsKKyAgICAgICAgSGFzaHRhYmxlRW50cnk8SywgVj4gZmlyc3QgPSB0YWJbaW5kZXhdOworICAgICAgICBmb3IgKEhhc2h0YWJsZUVudHJ5PEssIFY+IGUgPSBmaXJzdDsgZSAhPSBudWxsOyBlID0gZS5uZXh0KSB7CisgICAgICAgICAgICBpZiAoZS5oYXNoID09IGhhc2ggJiYga2V5LmVxdWFscyhlLmtleSkpIHsKKyAgICAgICAgICAgICAgICBWIG9sZFZhbHVlID0gZS52YWx1ZTsKKyAgICAgICAgICAgICAgICBlLnZhbHVlID0gdmFsdWU7CisgICAgICAgICAgICAgICAgcmV0dXJuIG9sZFZhbHVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gTm8gZW50cnkgZm9yIGtleSBpcyBwcmVzZW50OyBjcmVhdGUgb25lCisgICAgICAgIG1vZENvdW50Kys7CisgICAgICAgIGlmIChzaXplKysgPiB0aHJlc2hvbGQpIHsKKyAgICAgICAgICAgIHJlaGFzaCgpOyAgLy8gRG9lcyBub3RoaW5nISEKKyAgICAgICAgICAgIHRhYiA9IGRvdWJsZUNhcGFjaXR5KCk7CisgICAgICAgICAgICBpbmRleCA9IGhhc2ggJiAodGFiLmxlbmd0aCAtIDEpOworICAgICAgICAgICAgZmlyc3QgPSB0YWJbaW5kZXhdOworICAgICAgICB9CisgICAgICAgIHRhYltpbmRleF0gPSBuZXcgSGFzaHRhYmxlRW50cnk8SywgVj4oa2V5LCB2YWx1ZSwgaGFzaCwgZmlyc3QpOworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBqdXN0IGxpa2UgcHV0LCBleGNlcHQgdGhhdCBpdCBkb2Vzbid0IGRvIHRoaW5ncyB0aGF0CisgICAgICogYXJlIGluYXBwcm9wcmlhdGUgb3IgdW5uZWNlc3NhcnkgZm9yIGNvbnN0cnVjdG9ycyBhbmQgcHNldWRvLWNvbnN0cnVjdG9ycworICAgICAqIChpLmUuLCBjbG9uZSwgcmVhZE9iamVjdCkuIEluIHBhcnRpY3VsYXIsIHRoaXMgbWV0aG9kIGRvZXMgbm90IGNoZWNrIHRvCisgICAgICogZW5zdXJlIHRoYXQgY2FwYWNpdHkgaXMgc3VmZmljaWVudCwgYW5kIGRvZXMgbm90IGluY3JlbWVudCBtb2RDb3VudC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY29uc3RydWN0b3JQdXQoSyBrZXksIFYgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGludCBoYXNoID0gc2Vjb25kYXJ5SGFzaChrZXkuaGFzaENvZGUoKSk7CisgICAgICAgIEhhc2h0YWJsZUVudHJ5PEssIFY+W10gdGFiID0gdGFibGU7CisgICAgICAgIGludCBpbmRleCA9IGhhc2ggJiAodGFiLmxlbmd0aCAtIDEpOworICAgICAgICBIYXNodGFibGVFbnRyeTxLLCBWPiBmaXJzdCA9IHRhYltpbmRleF07CisgICAgICAgIGZvciAoSGFzaHRhYmxlRW50cnk8SywgVj4gZSA9IGZpcnN0OyBlICE9IG51bGw7IGUgPSBlLm5leHQpIHsKKyAgICAgICAgICAgIGlmIChlLmhhc2ggPT0gaGFzaCAmJiBrZXkuZXF1YWxzKGUua2V5KSkgeworICAgICAgICAgICAgICAgIGUudmFsdWUgPSB2YWx1ZTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBObyBlbnRyeSBmb3Iga2V5IGlzIHByZXNlbnQ7IGNyZWF0ZSBvbmUKKyAgICAgICAgdGFiW2luZGV4XSA9IG5ldyBIYXNodGFibGVFbnRyeTxLLCBWPihrZXksIHZhbHVlLCBoYXNoLCBmaXJzdCk7CisgICAgICAgIHNpemUrKzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgZXZlcnkgbWFwcGluZyB0byB0aGlzIHtAY29kZSBIYXNodGFibGV9IGZyb20gdGhlIHNwZWNpZmllZCBtYXAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWFwCisgICAgICogICAgICAgICAgICB0aGUgbWFwIHRvIGNvcHkgbWFwcGluZ3MgZnJvbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcHV0QWxsKE1hcDw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+IG1hcCkgeworICAgICAgICBlbnN1cmVDYXBhY2l0eShtYXAuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChFbnRyeTw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+IGUgOiBtYXAuZW50cnlTZXQoKSkgeworICAgICAgICAgICAgcHV0KGUuZ2V0S2V5KCksIGUuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbnN1cmVzIHRoYXQgdGhlIGhhc2ggdGFibGUgaGFzIHN1ZmZpY2llbnQgY2FwYWNpdHkgdG8gc3RvcmUgdGhlCisgICAgICogc3BlY2lmaWVkIG51bWJlciBvZiBtYXBwaW5ncywgd2l0aCByb29tIHRvIGdyb3cuIElmIG5vdCwgaXQgaW5jcmVhc2VzIHRoZQorICAgICAqIGNhcGFjaXR5IGFzIGFwcHJvcHJpYXRlLiBMaWtlIGRvdWJsZUNhcGFjaXR5LCB0aGlzIG1ldGhvZCBtb3ZlcyBleGlzdGluZworICAgICAqIGVudHJpZXMgdG8gbmV3IGJ1Y2tldHMgYXMgYXBwcm9wcmlhdGUuIFVubGlrZSBkb3VibGVDYXBhY2l0eSwgdGhpcyBtZXRob2QKKyAgICAgKiBjYW4gZ3JvdyB0aGUgdGFibGUgYnkgZmFjdG9ycyBvZiAyXm4gZm9yIG4gPiAxLiBIb3BlZnVsbHksIGEgc2luZ2xlIGNhbGwKKyAgICAgKiB0byB0aGlzIG1ldGhvZCB3aWxsIGJlIGZhc3RlciB0aGFuIG11bHRpcGxlIGNhbGxzIHRvIGRvdWJsZUNhcGFjaXR5LgorICAgICAqCisgICAgICogIDxwPlRoaXMgbWV0aG9kIGlzIGNhbGxlZCBvbmx5IGJ5IHB1dEFsbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZW5zdXJlQ2FwYWNpdHkoaW50IG51bU1hcHBpbmdzKSB7CisgICAgICAgIGludCBuZXdDYXBhY2l0eSA9IHJvdW5kVXBUb1Bvd2VyT2ZUd28oY2FwYWNpdHlGb3JJbml0U2l6ZShudW1NYXBwaW5ncykpOworICAgICAgICBIYXNodGFibGVFbnRyeTxLLCBWPltdIG9sZFRhYmxlID0gdGFibGU7CisgICAgICAgIGludCBvbGRDYXBhY2l0eSA9IG9sZFRhYmxlLmxlbmd0aDsKKyAgICAgICAgaWYgKG5ld0NhcGFjaXR5IDw9IG9sZENhcGFjaXR5KSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICByZWhhc2goKTsgIC8vIERvZXMgbm90aGluZyEhCisKKyAgICAgICAgaWYgKG5ld0NhcGFjaXR5ID09IG9sZENhcGFjaXR5ICogMikgeworICAgICAgICAgICAgZG91YmxlQ2FwYWNpdHkoKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFdlJ3JlIGdyb3dpbmcgYnkgYXQgbGVhc3QgNHgsIHJlaGFzaCBpbiB0aGUgb2J2aW91cyB3YXkKKyAgICAgICAgSGFzaHRhYmxlRW50cnk8SywgVj5bXSBuZXdUYWJsZSA9IG1ha2VUYWJsZShuZXdDYXBhY2l0eSk7CisgICAgICAgIGlmIChzaXplICE9IDApIHsKKyAgICAgICAgICAgIGludCBuZXdNYXNrID0gbmV3Q2FwYWNpdHkgLSAxOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvbGRDYXBhY2l0eTsgaSsrKSB7CisgICAgICAgICAgICAgICAgZm9yIChIYXNodGFibGVFbnRyeTxLLCBWPiBlID0gb2xkVGFibGVbaV07IGUgIT0gbnVsbDspIHsKKyAgICAgICAgICAgICAgICAgICAgSGFzaHRhYmxlRW50cnk8SywgVj4gb2xkTmV4dCA9IGUubmV4dDsKKyAgICAgICAgICAgICAgICAgICAgaW50IG5ld0luZGV4ID0gZS5oYXNoICYgbmV3TWFzazsKKyAgICAgICAgICAgICAgICAgICAgSGFzaHRhYmxlRW50cnk8SywgVj4gbmV3TmV4dCA9IG5ld1RhYmxlW25ld0luZGV4XTsKKyAgICAgICAgICAgICAgICAgICAgbmV3VGFibGVbbmV3SW5kZXhdID0gZTsKKyAgICAgICAgICAgICAgICAgICAgZS5uZXh0ID0gbmV3TmV4dDsKKyAgICAgICAgICAgICAgICAgICAgZSA9IG9sZE5leHQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5jcmVhc2VzIHRoZSBjYXBhY2l0eSBvZiB0aGlzIHtAY29kZSBIYXNodGFibGV9LiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQKKyAgICAgKiB3aGVuIHRoZSBzaXplIG9mIHRoaXMge0Bjb2RlIEhhc2h0YWJsZX0gZXhjZWVkcyB0aGUgbG9hZCBmYWN0b3IuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcmVoYXNoKCkgeworICAgICAgICAvKgorICAgICAgICAgKiBUaGlzIG1ldGhvZCBoYXMgbm8gdGVzdGFibGUgc2VtYW50aWNzLCBvdGhlciB0aGFuIHRoYXQgaXQgZ2V0cworICAgICAgICAgKiBjYWxsZWQgZnJvbSB0aW1lIHRvIHRpbWUuCisgICAgICAgICAqLworICAgIH0KKworICAgIC8qKgorICAgICAqIEFsbG9jYXRlIGEgdGFibGUgb2YgdGhlIGdpdmVuIGNhcGFjaXR5IGFuZCBzZXQgdGhlIHRocmVzaG9sZCBhY2NvcmRpbmdseS4KKyAgICAgKiBAcGFyYW0gbmV3Q2FwYWNpdHkgbXVzdCBiZSBhIHBvd2VyIG9mIHR3bworICAgICAqLworICAgIHByaXZhdGUgSGFzaHRhYmxlRW50cnk8SywgVj5bXSBtYWtlVGFibGUoaW50IG5ld0NhcGFjaXR5KSB7CisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSBIYXNodGFibGVFbnRyeTxLLCBWPltdIG5ld1RhYmxlCisgICAgICAgICAgICAgICAgPSAoSGFzaHRhYmxlRW50cnk8SywgVj5bXSkgbmV3IEhhc2h0YWJsZUVudHJ5W25ld0NhcGFjaXR5XTsKKyAgICAgICAgdGFibGUgPSBuZXdUYWJsZTsKKyAgICAgICAgdGhyZXNob2xkID0gKG5ld0NhcGFjaXR5ID4+IDEpICsgKG5ld0NhcGFjaXR5ID4+IDIpOyAvLyAzLzQgY2FwYWNpdHkKKyAgICAgICAgcmV0dXJuIG5ld1RhYmxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIERvdWJsZXMgdGhlIGNhcGFjaXR5IG9mIHRoZSBoYXNoIHRhYmxlLiBFeGlzdGluZyBlbnRyaWVzIGFyZSBwbGFjZWQgaW4KKyAgICAgKiB0aGUgY29ycmVjdCBidWNrZXQgb24gdGhlIGVubGFyZ2VkIHRhYmxlLiBJZiB0aGUgY3VycmVudCBjYXBhY2l0eSBpcywKKyAgICAgKiBNQVhJTVVNX0NBUEFDSVRZLCB0aGlzIG1ldGhvZCBpcyBhIG5vLW9wLiBSZXR1cm5zIHRoZSB0YWJsZSwgd2hpY2gKKyAgICAgKiB3aWxsIGJlIG5ldyB1bmxlc3Mgd2Ugd2VyZSBhbHJlYWR5IGF0IE1BWElNVU1fQ0FQQUNJVFkuCisgICAgICovCisgICAgcHJpdmF0ZSBIYXNodGFibGVFbnRyeTxLLCBWPltdIGRvdWJsZUNhcGFjaXR5KCkgeworICAgICAgICBIYXNodGFibGVFbnRyeTxLLCBWPltdIG9sZFRhYmxlID0gdGFibGU7CisgICAgICAgIGludCBvbGRDYXBhY2l0eSA9IG9sZFRhYmxlLmxlbmd0aDsKKyAgICAgICAgaWYgKG9sZENhcGFjaXR5ID09IE1BWElNVU1fQ0FQQUNJVFkpIHsKKyAgICAgICAgICAgIHJldHVybiBvbGRUYWJsZTsKKyAgICAgICAgfQorICAgICAgICBpbnQgbmV3Q2FwYWNpdHkgPSBvbGRDYXBhY2l0eSAqIDI7CisgICAgICAgIEhhc2h0YWJsZUVudHJ5PEssIFY+W10gbmV3VGFibGUgPSBtYWtlVGFibGUobmV3Q2FwYWNpdHkpOworICAgICAgICBpZiAoc2l6ZSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3VGFibGU7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IG9sZENhcGFjaXR5OyBqKyspIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBSZWhhc2ggdGhlIGJ1Y2tldCB1c2luZyB0aGUgbWluaW11bSBudW1iZXIgb2YgZmllbGQgd3JpdGVzLgorICAgICAgICAgICAgICogVGhpcyBpcyB0aGUgbW9zdCBzdWJ0bGUgYW5kIGRlbGljYXRlIGNvZGUgaW4gdGhlIGNsYXNzLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBIYXNodGFibGVFbnRyeTxLLCBWPiBlID0gb2xkVGFibGVbal07CisgICAgICAgICAgICBpZiAoZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgaGlnaEJpdCA9IGUuaGFzaCAmIG9sZENhcGFjaXR5OworICAgICAgICAgICAgSGFzaHRhYmxlRW50cnk8SywgVj4gYnJva2VuID0gbnVsbDsKKyAgICAgICAgICAgIG5ld1RhYmxlW2ogfCBoaWdoQml0XSA9IGU7CisgICAgICAgICAgICBmb3IgKEhhc2h0YWJsZUVudHJ5PEssVj4gbiA9IGUubmV4dDsgbiAhPSBudWxsOyBlID0gbiwgbiA9IG4ubmV4dCkgeworICAgICAgICAgICAgICAgIGludCBuZXh0SGlnaEJpdCA9IG4uaGFzaCAmIG9sZENhcGFjaXR5OworICAgICAgICAgICAgICAgIGlmIChuZXh0SGlnaEJpdCAhPSBoaWdoQml0KSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChicm9rZW4gPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ld1RhYmxlW2ogfCBuZXh0SGlnaEJpdF0gPSBuOworICAgICAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgICAgICBicm9rZW4ubmV4dCA9IG47CisgICAgICAgICAgICAgICAgICAgIGJyb2tlbiA9IGU7CisgICAgICAgICAgICAgICAgICAgIGhpZ2hCaXQgPSBuZXh0SGlnaEJpdDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYnJva2VuICE9IG51bGwpCisgICAgICAgICAgICAgICAgYnJva2VuLm5leHQgPSBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXdUYWJsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBrZXkvdmFsdWUgcGFpciB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IGZyb20gdGhpcworICAgICAqIHtAY29kZSBIYXNodGFibGV9LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byByZW1vdmUuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LCBvciB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiAgICAgICAgIHRoZSBzcGVjaWZpZWQga2V5IGRpZCBub3QgZXhpc3QuCisgICAgICogQHNlZSAjZ2V0CisgICAgICogQHNlZSAjcHV0CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBWIHJlbW92ZShPYmplY3Qga2V5KSB7CisgICAgICAgIGludCBoYXNoID0gc2Vjb25kYXJ5SGFzaChrZXkuaGFzaENvZGUoKSk7CisgICAgICAgIEhhc2h0YWJsZUVudHJ5PEssIFY+W10gdGFiID0gdGFibGU7CisgICAgICAgIGludCBpbmRleCA9IGhhc2ggJiAodGFiLmxlbmd0aCAtIDEpOworICAgICAgICBmb3IgKEhhc2h0YWJsZUVudHJ5PEssIFY+IGUgPSB0YWJbaW5kZXhdLCBwcmV2ID0gbnVsbDsKKyAgICAgICAgICAgICAgICBlICE9IG51bGw7IHByZXYgPSBlLCBlID0gZS5uZXh0KSB7CisgICAgICAgICAgICBpZiAoZS5oYXNoID09IGhhc2ggJiYga2V5LmVxdWFscyhlLmtleSkpIHsKKyAgICAgICAgICAgICAgICBpZiAocHJldiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRhYltpbmRleF0gPSBlLm5leHQ7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcHJldi5uZXh0ID0gZS5uZXh0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBtb2RDb3VudCsrOworICAgICAgICAgICAgICAgIHNpemUtLTsKKyAgICAgICAgICAgICAgICByZXR1cm4gZS52YWx1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGFsbCBrZXkvdmFsdWUgcGFpcnMgZnJvbSB0aGlzIHtAY29kZSBIYXNodGFibGV9LCBsZWF2aW5nIHRoZQorICAgICAqIHNpemUgemVybyBhbmQgdGhlIGNhcGFjaXR5IHVuY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEBzZWUgI2lzRW1wdHkKKyAgICAgKiBAc2VlICNzaXplCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNsZWFyKCkgeworICAgICAgICBpZiAoc2l6ZSAhPSAwKSB7CisgICAgICAgICAgICBBcnJheXMuZmlsbCh0YWJsZSwgbnVsbCk7CisgICAgICAgICAgICBtb2RDb3VudCsrOworICAgICAgICAgICAgc2l6ZSA9IDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc2V0IG9mIHRoZSBrZXlzIGNvbnRhaW5lZCBpbiB0aGlzIHtAY29kZSBIYXNodGFibGV9LiBUaGUgc2V0CisgICAgICogaXMgYmFja2VkIGJ5IHRoaXMge0Bjb2RlIEhhc2h0YWJsZX0gc28gY2hhbmdlcyB0byBvbmUgYXJlIHJlZmxlY3RlZCBieQorICAgICAqIHRoZSBvdGhlci4gVGhlIHNldCBkb2VzIG5vdCBzdXBwb3J0IGFkZGluZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzZXQgb2YgdGhlIGtleXMuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTZXQ8Sz4ga2V5U2V0KCkgeworICAgICAgICBTZXQ8Sz4ga3MgPSBrZXlTZXQ7CisgICAgICAgIHJldHVybiAoa3MgIT0gbnVsbCkgPyBrcyA6IChrZXlTZXQgPSBuZXcgS2V5U2V0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb2xsZWN0aW9uIG9mIHRoZSB2YWx1ZXMgY29udGFpbmVkIGluIHRoaXMge0Bjb2RlIEhhc2h0YWJsZX0uCisgICAgICogVGhlIGNvbGxlY3Rpb24gaXMgYmFja2VkIGJ5IHRoaXMge0Bjb2RlIEhhc2h0YWJsZX0gc28gY2hhbmdlcyB0byBvbmUgYXJlCisgICAgICogcmVmbGVjdGVkIGJ5IHRoZSBvdGhlci4gVGhlIGNvbGxlY3Rpb24gZG9lcyBub3Qgc3VwcG9ydCBhZGRpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29sbGVjdGlvbiBvZiB0aGUgdmFsdWVzLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgQ29sbGVjdGlvbjxWPiB2YWx1ZXMoKSB7CisgICAgICAgIENvbGxlY3Rpb248Vj4gdnMgPSB2YWx1ZXM7CisgICAgICAgIHJldHVybiAodnMgIT0gbnVsbCkgPyB2cyA6ICh2YWx1ZXMgPSBuZXcgVmFsdWVzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzZXQgb2YgdGhlIG1hcHBpbmdzIGNvbnRhaW5lZCBpbiB0aGlzIHtAY29kZSBIYXNodGFibGV9LiBFYWNoCisgICAgICogZWxlbWVudCBpbiB0aGUgc2V0IGlzIGEge0BsaW5rIE1hcC5FbnRyeX0uIFRoZSBzZXQgaXMgYmFja2VkIGJ5IHRoaXMKKyAgICAgKiB7QGNvZGUgSGFzaHRhYmxlfSBzbyBjaGFuZ2VzIHRvIG9uZSBhcmUgcmVmbGVjdGVkIGJ5IHRoZSBvdGhlci4gVGhlIHNldAorICAgICAqIGRvZXMgbm90IHN1cHBvcnQgYWRkaW5nLgorICAgICAqCisgICAgICogQHJldHVybiBhIHNldCBvZiB0aGUgbWFwcGluZ3MuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTZXQ8RW50cnk8SywgVj4+IGVudHJ5U2V0KCkgeworICAgICAgICBTZXQ8RW50cnk8SywgVj4+IGVzID0gZW50cnlTZXQ7CisgICAgICAgIHJldHVybiAoZXMgIT0gbnVsbCkgPyBlcyA6IChlbnRyeVNldCA9IG5ldyBFbnRyeVNldCgpKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gZW51bWVyYXRpb24gb24gdGhlIGtleXMgb2YgdGhpcyB7QGNvZGUgSGFzaHRhYmxlfSBpbnN0YW5jZS4KKyAgICAgKiBUaGUgcmVzdWx0cyBvZiB0aGUgZW51bWVyYXRpb24gbWF5IGJlIGFmZmVjdGVkIGlmIHRoZSBjb250ZW50cyBvZiB0aGlzCisgICAgICoge0Bjb2RlIEhhc2h0YWJsZX0gYXJlIG1vZGlmaWVkLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBlbnVtZXJhdGlvbiBvZiB0aGUga2V5cyBvZiB0aGlzIHtAY29kZSBIYXNodGFibGV9LgorICAgICAqIEBzZWUgI2VsZW1lbnRzCisgICAgICogQHNlZSAjc2l6ZQorICAgICAqIEBzZWUgRW51bWVyYXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEVudW1lcmF0aW9uPEs+IGtleXMoKSB7CisgICAgICAgIHJldHVybiBuZXcgS2V5RW51bWVyYXRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGVudW1lcmF0aW9uIG9uIHRoZSB2YWx1ZXMgb2YgdGhpcyB7QGNvZGUgSGFzaHRhYmxlfS4gVGhlCisgICAgICogcmVzdWx0cyBvZiB0aGUgRW51bWVyYXRpb24gbWF5IGJlIGFmZmVjdGVkIGlmIHRoZSBjb250ZW50cyBvZiB0aGlzCisgICAgICoge0Bjb2RlIEhhc2h0YWJsZX0gYXJlIG1vZGlmaWVkLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBlbnVtZXJhdGlvbiBvZiB0aGUgdmFsdWVzIG9mIHRoaXMge0Bjb2RlIEhhc2h0YWJsZX0uCisgICAgICogQHNlZSAja2V5cworICAgICAqIEBzZWUgI3NpemUKKyAgICAgKiBAc2VlIEVudW1lcmF0aW9uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBFbnVtZXJhdGlvbjxWPiBlbGVtZW50cygpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBWYWx1ZUVudW1lcmF0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTm90ZTogdGVjaG5pY2FsbHkgdGhlIG1ldGhvZHMgb2YgdGhpcyBjbGFzcyBzaG91bGQgc3luY2hyb25pemUgdGhlCisgICAgICogYmFja2luZyBtYXAuICBIb3dldmVyLCB0aGlzIHdvdWxkIHJlcXVpcmUgdGhlbSB0byBoYXZlIGEgcmVmZXJlbmNlCisgICAgICogdG8gaXQsIHdoaWNoIHdvdWxkIGNhdXNlIGNvbnNpZGVyYWJsZSBibG9hdC4gIE1vcmVvdmVyLCB0aGUgUkkKKyAgICAgKiBiZWhhdmVzIHRoZSBzYW1lIHdheS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBIYXNodGFibGVFbnRyeTxLLCBWPiBpbXBsZW1lbnRzIEVudHJ5PEssIFY+IHsKKyAgICAgICAgZmluYWwgSyBrZXk7CisgICAgICAgIFYgdmFsdWU7CisgICAgICAgIGZpbmFsIGludCBoYXNoOworICAgICAgICBIYXNodGFibGVFbnRyeTxLLCBWPiBuZXh0OworCisgICAgICAgIEhhc2h0YWJsZUVudHJ5KEsga2V5LCBWIHZhbHVlLCBpbnQgaGFzaCwgSGFzaHRhYmxlRW50cnk8SywgVj4gbmV4dCkgeworICAgICAgICAgICAgdGhpcy5rZXkgPSBrZXk7CisgICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgICAgICAgICB0aGlzLmhhc2ggPSBoYXNoOworICAgICAgICAgICAgdGhpcy5uZXh0ID0gbmV4dDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBmaW5hbCBLIGdldEtleSgpIHsKKyAgICAgICAgICAgIHJldHVybiBrZXk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgZmluYWwgViBnZXRWYWx1ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBmaW5hbCBWIHNldFZhbHVlKFYgdmFsdWUpIHsKKyAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBWIG9sZFZhbHVlID0gdGhpcy52YWx1ZTsKKyAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICAgICAgICAgIHJldHVybiBvbGRWYWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgZmluYWwgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBFbnRyeSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBFbnRyeTw/LCA/PiBlID0gKEVudHJ5PD8sID8+KSBvOworICAgICAgICAgICAgcmV0dXJuIGtleS5lcXVhbHMoZS5nZXRLZXkoKSkgJiYgdmFsdWUuZXF1YWxzKGUuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGZpbmFsIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBrZXkuaGFzaENvZGUoKSBeIHZhbHVlLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBrZXkgKyAiPSIgKyB2YWx1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgYWJzdHJhY3QgY2xhc3MgSGFzaEl0ZXJhdG9yIHsKKyAgICAgICAgaW50IG5leHRJbmRleDsKKyAgICAgICAgSGFzaHRhYmxlRW50cnk8SywgVj4gbmV4dEVudHJ5OworICAgICAgICBIYXNodGFibGVFbnRyeTxLLCBWPiBsYXN0RW50cnlSZXR1cm5lZDsKKyAgICAgICAgaW50IGV4cGVjdGVkTW9kQ291bnQgPSBtb2RDb3VudDsKKworICAgICAgICBIYXNoSXRlcmF0b3IoKSB7CisgICAgICAgICAgICBIYXNodGFibGVFbnRyeTxLLCBWPltdIHRhYiA9IHRhYmxlOworICAgICAgICAgICAgSGFzaHRhYmxlRW50cnk8SywgVj4gbmV4dCA9IG51bGw7CisgICAgICAgICAgICB3aGlsZSAobmV4dCA9PSBudWxsICYmIG5leHRJbmRleCA8IHRhYi5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBuZXh0ID0gdGFiW25leHRJbmRleCsrXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG5leHRFbnRyeSA9IG5leHQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgcmV0dXJuIG5leHRFbnRyeSAhPSBudWxsOworICAgICAgICB9CisKKyAgICAgICAgSGFzaHRhYmxlRW50cnk8SywgVj4gbmV4dEVudHJ5KCkgeworICAgICAgICAgICAgaWYgKG1vZENvdW50ICE9IGV4cGVjdGVkTW9kQ291bnQpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGlmIChuZXh0RW50cnkgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworCisgICAgICAgICAgICBIYXNodGFibGVFbnRyeTxLLCBWPiBlbnRyeVRvUmV0dXJuID0gbmV4dEVudHJ5OworICAgICAgICAgICAgSGFzaHRhYmxlRW50cnk8SywgVj5bXSB0YWIgPSB0YWJsZTsKKyAgICAgICAgICAgIEhhc2h0YWJsZUVudHJ5PEssIFY+IG5leHQgPSBlbnRyeVRvUmV0dXJuLm5leHQ7CisgICAgICAgICAgICB3aGlsZSAobmV4dCA9PSBudWxsICYmIG5leHRJbmRleCA8IHRhYi5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBuZXh0ID0gdGFiW25leHRJbmRleCsrXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG5leHRFbnRyeSA9IG5leHQ7CisgICAgICAgICAgICByZXR1cm4gbGFzdEVudHJ5UmV0dXJuZWQgPSBlbnRyeVRvUmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgSGFzaHRhYmxlRW50cnk8SywgVj4gbmV4dEVudHJ5Tm90RmFpbEZhc3QoKSB7CisgICAgICAgICAgICBpZiAobmV4dEVudHJ5ID09IG51bGwpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKworICAgICAgICAgICAgSGFzaHRhYmxlRW50cnk8SywgVj4gZW50cnlUb1JldHVybiA9IG5leHRFbnRyeTsKKyAgICAgICAgICAgIEhhc2h0YWJsZUVudHJ5PEssIFY+W10gdGFiID0gdGFibGU7CisgICAgICAgICAgICBIYXNodGFibGVFbnRyeTxLLCBWPiBuZXh0ID0gZW50cnlUb1JldHVybi5uZXh0OworICAgICAgICAgICAgd2hpbGUgKG5leHQgPT0gbnVsbCAmJiBuZXh0SW5kZXggPCB0YWIubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgbmV4dCA9IHRhYltuZXh0SW5kZXgrK107CisgICAgICAgICAgICB9CisgICAgICAgICAgICBuZXh0RW50cnkgPSBuZXh0OworICAgICAgICAgICAgcmV0dXJuIGxhc3RFbnRyeVJldHVybmVkID0gZW50cnlUb1JldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgIGlmIChsYXN0RW50cnlSZXR1cm5lZCA9PSBudWxsKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGlmIChtb2RDb3VudCAhPSBleHBlY3RlZE1vZENvdW50KQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBIYXNodGFibGUudGhpcy5yZW1vdmUobGFzdEVudHJ5UmV0dXJuZWQua2V5KTsKKyAgICAgICAgICAgIGxhc3RFbnRyeVJldHVybmVkID0gbnVsbDsKKyAgICAgICAgICAgIGV4cGVjdGVkTW9kQ291bnQgPSBtb2RDb3VudDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgY2xhc3MgS2V5SXRlcmF0b3IgZXh0ZW5kcyBIYXNoSXRlcmF0b3IKKyAgICAgICAgICAgIGltcGxlbWVudHMgSXRlcmF0b3I8Sz4geworICAgICAgICBwdWJsaWMgSyBuZXh0KCkgeyByZXR1cm4gbmV4dEVudHJ5KCkua2V5OyB9CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBWYWx1ZUl0ZXJhdG9yIGV4dGVuZHMgSGFzaEl0ZXJhdG9yCisgICAgICAgICAgICBpbXBsZW1lbnRzIEl0ZXJhdG9yPFY+IHsKKyAgICAgICAgcHVibGljIFYgbmV4dCgpIHsgcmV0dXJuIG5leHRFbnRyeSgpLnZhbHVlOyB9CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBFbnRyeUl0ZXJhdG9yIGV4dGVuZHMgSGFzaEl0ZXJhdG9yCisgICAgICAgICAgICBpbXBsZW1lbnRzIEl0ZXJhdG9yPEVudHJ5PEssIFY+PiB7CisgICAgICAgIHB1YmxpYyBFbnRyeTxLLCBWPiBuZXh0KCkgeyByZXR1cm4gbmV4dEVudHJ5KCk7IH0KKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIGNsYXNzIEtleUVudW1lcmF0aW9uIGV4dGVuZHMgSGFzaEl0ZXJhdG9yCisgICAgICAgICAgICBpbXBsZW1lbnRzIEVudW1lcmF0aW9uPEs+IHsKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTW9yZUVsZW1lbnRzKCkgeyByZXR1cm4gaGFzTmV4dCgpOyB9CisgICAgICAgIHB1YmxpYyBLIG5leHRFbGVtZW50KCkgeyByZXR1cm4gbmV4dEVudHJ5Tm90RmFpbEZhc3QoKS5rZXk7IH0KKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIGNsYXNzIFZhbHVlRW51bWVyYXRpb24gZXh0ZW5kcyBIYXNoSXRlcmF0b3IKKyAgICAgICAgICAgIGltcGxlbWVudHMgRW51bWVyYXRpb248Vj4geworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNNb3JlRWxlbWVudHMoKSB7IHJldHVybiBoYXNOZXh0KCk7IH0KKyAgICAgICAgcHVibGljIFYgbmV4dEVsZW1lbnQoKSB7IHJldHVybiBuZXh0RW50cnlOb3RGYWlsRmFzdCgpLnZhbHVlOyB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgbWFwIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgbWFwcGluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCBib29sZWFuIGNvbnRhaW5zTWFwcGluZyhPYmplY3Qga2V5LCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaW50IGhhc2ggPSBzZWNvbmRhcnlIYXNoKGtleS5oYXNoQ29kZSgpKTsKKyAgICAgICAgSGFzaHRhYmxlRW50cnk8SywgVj5bXSB0YWIgPSB0YWJsZTsKKyAgICAgICAgaW50IGluZGV4ID0gaGFzaCAmICh0YWIubGVuZ3RoIC0gMSk7CisgICAgICAgIGZvciAoSGFzaHRhYmxlRW50cnk8SywgVj4gZSA9IHRhYltpbmRleF07IGUgIT0gbnVsbDsgZSA9IGUubmV4dCkgeworICAgICAgICAgICAgaWYgKGUuaGFzaCA9PSBoYXNoICYmIGUua2V5LmVxdWFscyhrZXkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGUudmFsdWUuZXF1YWxzKHZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7IC8vIE5vIGVudHJ5IGZvciBrZXkKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBtYXBwaW5nIGZyb20ga2V5IHRvIHZhbHVlIGFuZCByZXR1cm5zIHRydWUgaWYgdGhpcyBtYXBwaW5nCisgICAgICogZXhpc3RzOyBvdGhlcndpc2UsIHJldHVybnMgZG9lcyBub3RoaW5nIGFuZCByZXR1cm5zIGZhbHNlLgorICAgICAqLworICAgIHByaXZhdGUgc3luY2hyb25pemVkIGJvb2xlYW4gcmVtb3ZlTWFwcGluZyhPYmplY3Qga2V5LCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaW50IGhhc2ggPSBzZWNvbmRhcnlIYXNoKGtleS5oYXNoQ29kZSgpKTsKKyAgICAgICAgSGFzaHRhYmxlRW50cnk8SywgVj5bXSB0YWIgPSB0YWJsZTsKKyAgICAgICAgaW50IGluZGV4ID0gaGFzaCAmICh0YWIubGVuZ3RoIC0gMSk7CisgICAgICAgIGZvciAoSGFzaHRhYmxlRW50cnk8SywgVj4gZSA9IHRhYltpbmRleF0sIHByZXYgPSBudWxsOworICAgICAgICAgICAgICAgIGUgIT0gbnVsbDsgcHJldiA9IGUsIGUgPSBlLm5leHQpIHsKKyAgICAgICAgICAgIGlmIChlLmhhc2ggPT0gaGFzaCAmJiBlLmtleS5lcXVhbHMoa2V5KSkgeworICAgICAgICAgICAgICAgIGlmICghZS52YWx1ZS5lcXVhbHModmFsdWUpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgIC8vIE1hcCBoYXMgd3JvbmcgdmFsdWUgZm9yIGtleQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAocHJldiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRhYltpbmRleF0gPSBlLm5leHQ7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcHJldi5uZXh0ID0gZS5uZXh0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBtb2RDb3VudCsrOworICAgICAgICAgICAgICAgIHNpemUtLTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7IC8vIE5vIGVudHJ5IGZvciBrZXkKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGlzIHtAY29kZSBIYXNodGFibGV9IHdpdGggdGhlIHNwZWNpZmllZCBvYmplY3QgYW5kIGluZGljYXRlcworICAgICAqIGlmIHRoZXkgYXJlIGVxdWFsLiBJbiBvcmRlciB0byBiZSBlcXVhbCwge0Bjb2RlIG9iamVjdH0gbXVzdCBiZSBhbgorICAgICAqIGluc3RhbmNlIG9mIE1hcCBhbmQgY29udGFpbiB0aGUgc2FtZSBrZXkvdmFsdWUgcGFpcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUgd2l0aCB0aGlzIG9iamVjdC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBlcXVhbCB0byB0aGlzIE1hcCwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgI2hhc2hDb2RlCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICByZXR1cm4gKG9iamVjdCBpbnN0YW5jZW9mIE1hcCkgJiYKKyAgICAgICAgICAgICAgICBlbnRyeVNldCgpLmVxdWFscygoKE1hcDw/LCA/PilvYmplY3QpLmVudHJ5U2V0KCkpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgc3luY2hyb25pemVkIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IHJlc3VsdCA9IDA7CisgICAgICAgIGZvciAoRW50cnk8SywgVj4gZSA6IGVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIEsga2V5ID0gZS5nZXRLZXkoKTsKKyAgICAgICAgICAgIFYgdmFsdWUgPSBlLmdldFZhbHVlKCk7CisgICAgICAgICAgICBpZiAoa2V5ID09IHRoaXMgfHwgdmFsdWUgPT0gdGhpcykgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0ICs9IChrZXkgIT0gbnVsbCA/IGtleS5oYXNoQ29kZSgpIDogMCkKKyAgICAgICAgICAgICAgICAgICAgXiAodmFsdWUgIT0gbnVsbCA/IHZhbHVlLmhhc2hDb2RlKCkgOiAwKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgcm91Z2ggZXN0aW1hdGUgb2YgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHBlciBlbnRyeSwgZm9yIHVzZQorICAgICAqIHdoZW4gY3JlYXRpbmcgYSBzdHJpbmcgYnVmZmVyIGluIHRoZSB0b1N0cmluZyBtZXRob2QuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENIQVJTX1BFUl9FTlRSWSA9IDE1OworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMge0Bjb2RlIEhhc2h0YWJsZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB7QGNvZGUgSGFzaHRhYmxlfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoQ0hBUlNfUEVSX0VOVFJZICogc2l6ZSk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQoJ3snKTsKKyAgICAgICAgSXRlcmF0b3I8RW50cnk8SywgVj4+IGkgPSBlbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgIGJvb2xlYW4gaGFzTW9yZSA9IGkuaGFzTmV4dCgpOworICAgICAgICB3aGlsZSAoaGFzTW9yZSkgeworICAgICAgICAgICAgRW50cnk8SywgVj4gZW50cnkgPSBpLm5leHQoKTsKKworICAgICAgICAgICAgSyBrZXkgPSBlbnRyeS5nZXRLZXkoKTsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoa2V5ID09IHRoaXMgPyAiKHRoaXMgTWFwKSIgOiBrZXkudG9TdHJpbmcoKSk7CisKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJz0nKTsKKworICAgICAgICAgICAgViB2YWx1ZSA9IGVudHJ5LmdldFZhbHVlKCk7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHZhbHVlID09IHRoaXMgPyAiKHRoaXMgTWFwKSIgOiB2YWx1ZS50b1N0cmluZygpKTsKKworICAgICAgICAgICAgaWYgKGhhc01vcmUgPSBpLmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIiwgIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXN1bHQuYXBwZW5kKCd9Jyk7CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIGNsYXNzIEtleVNldCBleHRlbmRzIEFic3RyYWN0U2V0PEs+IHsKKyAgICAgICAgcHVibGljIEl0ZXJhdG9yPEs+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBLZXlJdGVyYXRvcigpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBIYXNodGFibGUudGhpcy5zaXplKCk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIHJldHVybiBjb250YWluc0tleShvKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoSGFzaHRhYmxlLnRoaXMpIHsKKyAgICAgICAgICAgICAgICBpbnQgb2xkU2l6ZSA9IHNpemU7CisgICAgICAgICAgICAgICAgSGFzaHRhYmxlLnRoaXMucmVtb3ZlKG8pOworICAgICAgICAgICAgICAgIHJldHVybiBzaXplICE9IG9sZFNpemU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICBIYXNodGFibGUudGhpcy5jbGVhcigpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZUFsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoSGFzaHRhYmxlLnRoaXMpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIucmVtb3ZlQWxsKGNvbGxlY3Rpb24pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIHJldGFpbkFsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoSGFzaHRhYmxlLnRoaXMpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIucmV0YWluQWxsKGNvbGxlY3Rpb24pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQWxsKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbikgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChIYXNodGFibGUudGhpcykgeworICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5jb250YWluc0FsbChjb2xsZWN0aW9uKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChIYXNodGFibGUudGhpcykgeworICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqZWN0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChIYXNodGFibGUudGhpcykgeworICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5oYXNoQ29kZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKEhhc2h0YWJsZS50aGlzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKEhhc2h0YWJsZS50aGlzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnRvQXJyYXkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgPFQ+IFRbXSB0b0FycmF5KFRbXSBhKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKEhhc2h0YWJsZS50aGlzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnRvQXJyYXkoYSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIGNsYXNzIFZhbHVlcyBleHRlbmRzIEFic3RyYWN0Q29sbGVjdGlvbjxWPiB7CisgICAgICAgIHB1YmxpYyBJdGVyYXRvcjxWPiBpdGVyYXRvcigpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVmFsdWVJdGVyYXRvcigpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBIYXNodGFibGUudGhpcy5zaXplKCk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIHJldHVybiBjb250YWluc1ZhbHVlKG8pOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICAgICAgSGFzaHRhYmxlLnRoaXMuY2xlYXIoKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0FsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoSGFzaHRhYmxlLnRoaXMpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuY29udGFpbnNBbGwoY29sbGVjdGlvbik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoSGFzaHRhYmxlLnRoaXMpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoSGFzaHRhYmxlLnRoaXMpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIudG9BcnJheSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHB1YmxpYyA8VD4gVFtdIHRvQXJyYXkoVFtdIGEpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoSGFzaHRhYmxlLnRoaXMpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIudG9BcnJheShhKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgY2xhc3MgRW50cnlTZXQgZXh0ZW5kcyBBYnN0cmFjdFNldDxFbnRyeTxLLCBWPj4geworICAgICAgICBwdWJsaWMgSXRlcmF0b3I8RW50cnk8SywgVj4+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBFbnRyeUl0ZXJhdG9yKCk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBFbnRyeSkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgRW50cnk8PywgPz4gZSA9IChFbnRyeTw/LCA/PikgbzsKKyAgICAgICAgICAgIHJldHVybiBjb250YWluc01hcHBpbmcoZS5nZXRLZXkoKSwgZS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBFbnRyeSkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgRW50cnk8PywgPz4gZSA9IChFbnRyeTw/LCA/PilvOworICAgICAgICAgICAgcmV0dXJuIHJlbW92ZU1hcHBpbmcoZS5nZXRLZXkoKSwgZS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gSGFzaHRhYmxlLnRoaXMuc2l6ZSgpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICAgICAgSGFzaHRhYmxlLnRoaXMuY2xlYXIoKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmVBbGwoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKEhhc2h0YWJsZS50aGlzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnJlbW92ZUFsbChjb2xsZWN0aW9uKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiByZXRhaW5BbGwoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKEhhc2h0YWJsZS50aGlzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnJldGFpbkFsbChjb2xsZWN0aW9uKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0FsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoSGFzaHRhYmxlLnRoaXMpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuY29udGFpbnNBbGwoY29sbGVjdGlvbik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoSGFzaHRhYmxlLnRoaXMpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iamVjdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBIYXNodGFibGUudGhpcy5oYXNoQ29kZSgpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKEhhc2h0YWJsZS50aGlzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKEhhc2h0YWJsZS50aGlzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnRvQXJyYXkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgPFQ+IFRbXSB0b0FycmF5KFRbXSBhKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKEhhc2h0YWJsZS50aGlzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnRvQXJyYXkoYSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBsaWVzIGEgc3VwcGxlbWVudGFsIGhhc2ggZnVuY3Rpb24gdG8gYSBnaXZlbiBoYXNoQ29kZSwgd2hpY2ggZGVmZW5kcworICAgICAqIGFnYWluc3QgcG9vciBxdWFsaXR5IGhhc2ggZnVuY3Rpb25zLiBUaGlzIGlzIGNyaXRpY2FsIGJlY2F1c2UgSGFzaHRhYmxlCisgICAgICogdXNlcyBwb3dlci1vZi10d28gbGVuZ3RoIGhhc2ggdGFibGVzLCB0aGF0IG90aGVyd2lzZSBlbmNvdW50ZXIgY29sbGlzaW9ucworICAgICAqIGZvciBoYXNoQ29kZXMgdGhhdCBkbyBub3QgZGlmZmVyIGluIGxvd2VyIG9yIHVwcGVyIGJpdHMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHNlY29uZGFyeUhhc2goaW50IGgpIHsKKyAgICAgICAgLy8gRG91ZyBMZWEncyBzdXBwbGVtZW50YWwgaGFzaCBmdW5jdGlvbgorICAgICAgICBoIF49IChoID4+PiAyMCkgXiAoaCA+Pj4gMTIpOworICAgICAgICByZXR1cm4gaCBeIChoID4+PiA3KSBeIChoID4+PiA0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzbWFsbGVzdCBwb3dlciBvZiB0d28gPj0gaXRzIGFyZ3VtZW50LCB3aXRoIHNldmVyYWwgY2F2ZWF0czoKKyAgICAgKiBJZiB0aGUgYXJndW1lbnQgaXMgbmVnYXRpdmUgYnV0IG5vdCBJbnRlZ2VyLk1JTl9WQUxVRSwgdGhlIG1ldGhvZCByZXR1cm5zCisgICAgICogemVyby4gSWYgdGhlIGFyZ3VtZW50IGlzID4gMl4zMCBvciBlcXVhbCB0byBJbnRlZ2VyLk1JTl9WQUxVRSwgdGhlIG1ldGhvZAorICAgICAqIHJldHVybnMgSW50ZWdlci5NSU5fVkFMVUUuIElmIHRoZSBhcmd1bWVudCBpcyB6ZXJvLCB0aGUgbWV0aG9kIHJldHVybnMKKyAgICAgKiB6ZXJvLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCByb3VuZFVwVG9Qb3dlck9mVHdvKGludCBpKSB7CisgICAgICAgIGktLTsgLy8gSWYgaW5wdXQgaXMgYSBwb3dlciBvZiB0d28sIHNoaWZ0IGl0cyBoaWdoLW9yZGVyIGJpdCByaWdodAorCisgICAgICAgIC8vICJTbWVhciIgdGhlIGhpZ2gtb3JkZXIgYml0IGFsbCB0aGUgd2F5IHRvIHRoZSByaWdodAorICAgICAgICBpIHw9IGkgPj4+ICAxOworICAgICAgICBpIHw9IGkgPj4+ICAyOworICAgICAgICBpIHw9IGkgPj4+ICA0OworICAgICAgICBpIHw9IGkgPj4+ICA4OworICAgICAgICBpIHw9IGkgPj4+IDE2OworCisgICAgICAgIHJldHVybiBpICsgMTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxNDIxNzQ2NzU5NTEyMjg2MzkyTDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFN0cmVhbUZpZWxkW10gc2VyaWFsUGVyc2lzdGVudEZpZWxkcyA9IHsKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJ0aHJlc2hvbGQiLCBpbnQuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImxvYWRGYWN0b3IiLCBmbG9hdC5jbGFzcyksCisgICAgfTsKKworICAgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIHN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIEVtdWxhdGUgbG9hZEZhY3RvciBmaWVsZCBmb3Igb3RoZXIgaW1wbGVtZW50YXRpb25zIHRvIHJlYWQKKyAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtLlB1dEZpZWxkIGZpZWxkcyA9IHN0cmVhbS5wdXRGaWVsZHMoKTsKKyAgICAgICAgZmllbGRzLnB1dCgidGhyZXNob2xkIiwgIChpbnQpIChERUZBVUxUX0xPQURfRkFDVE9SICogdGFibGUubGVuZ3RoKSk7CisgICAgICAgIGZpZWxkcy5wdXQoImxvYWRGYWN0b3IiLCBERUZBVUxUX0xPQURfRkFDVE9SKTsKKyAgICAgICAgc3RyZWFtLndyaXRlRmllbGRzKCk7CisKKyAgICAgICAgc3RyZWFtLndyaXRlSW50KHRhYmxlLmxlbmd0aCk7IC8vIENhcGFjaXR5CisgICAgICAgIHN0cmVhbS53cml0ZUludChzaXplKTsKKyAgICAgICAgZm9yIChFbnRyeTxLLCBWPiBlIDogZW50cnlTZXQoKSkgeworICAgICAgICAgICAgc3RyZWFtLndyaXRlT2JqZWN0KGUuZ2V0S2V5KCkpOworICAgICAgICAgICAgc3RyZWFtLndyaXRlT2JqZWN0KGUuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBzdHJlYW0uZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgaW50IGNhcGFjaXR5ID0gc3RyZWFtLnJlYWRJbnQoKTsKKyAgICAgICAgaWYgKGNhcGFjaXR5IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPYmplY3RFeGNlcHRpb24oIkNhcGFjaXR5OiAiICsgY2FwYWNpdHkpOworICAgICAgICB9CisgICAgICAgIGlmIChjYXBhY2l0eSA8IE1JTklNVU1fQ0FQQUNJVFkpIHsKKyAgICAgICAgICAgIGNhcGFjaXR5ID0gTUlOSU1VTV9DQVBBQ0lUWTsKKyAgICAgICAgfSBlbHNlIGlmIChjYXBhY2l0eSA+IE1BWElNVU1fQ0FQQUNJVFkpIHsKKyAgICAgICAgICAgIGNhcGFjaXR5ID0gTUFYSU1VTV9DQVBBQ0lUWTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNhcGFjaXR5ID0gcm91bmRVcFRvUG93ZXJPZlR3byhjYXBhY2l0eSk7CisgICAgICAgIH0KKyAgICAgICAgbWFrZVRhYmxlKGNhcGFjaXR5KTsKKworICAgICAgICBpbnQgc2l6ZSA9IHN0cmVhbS5yZWFkSW50KCk7CisgICAgICAgIGlmIChzaXplIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPYmplY3RFeGNlcHRpb24oIlNpemU6ICIgKyBzaXplKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikgSyBrZXkgPSAoSykgc3RyZWFtLnJlYWRPYmplY3QoKTsKKyAgICAgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSBWIHZhbCA9IChWKSBzdHJlYW0ucmVhZE9iamVjdCgpOworICAgICAgICAgICAgY29uc3RydWN0b3JQdXQoa2V5LCB2YWwpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9IdWdlRW51bVNldC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9IdWdlRW51bVNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI4NTQzNzIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0h1Z2VFbnVtU2V0LmphdmEKQEAgLTAsMCArMSwzNTcgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisKKy8qKgorICogQSBjb25jcmV0ZSBFbnVtU2V0IGZvciBlbnVtcyB3aXRoIG1vcmUgdGhhbiA2NCBlbGVtZW50cy4KKyAqLworQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCitmaW5hbCBjbGFzcyBIdWdlRW51bVNldDxFIGV4dGVuZHMgRW51bTxFPj4gZXh0ZW5kcyBFbnVtU2V0PEU+IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCSVRfSU5fTE9ORyA9IDY0OworCisgICAgZmluYWwgcHJpdmF0ZSBFW10gZW51bXM7CisKKyAgICBwcml2YXRlIGxvbmdbXSBiaXRzOworCisgICAgcHJpdmF0ZSBpbnQgc2l6ZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZWxlbWVudFR5cGUgbm9uLW51bGw7IHR5cGUgb2YgdGhlIGVsZW1lbnRzCisgICAgICogQHBhcmFtIGVudW1zIG5vbi1udWxsOyBwcmUtcG9wdWxhdGVkIGFycmF5IG9mIGNvbnN0YW50cyBpbiBvcmRpbmFsCisgICAgICogb3JkZXIKKyAgICAgKi8KKyAgICBIdWdlRW51bVNldChDbGFzczxFPiBlbGVtZW50VHlwZSwgRVtdIGVudW1zKSB7CisgICAgICAgIHN1cGVyKGVsZW1lbnRUeXBlKTsKKyAgICAgICAgdGhpcy5lbnVtcyA9IGVudW1zOworICAgICAgICBiaXRzID0gbmV3IGxvbmdbKGVudW1zLmxlbmd0aCArIEJJVF9JTl9MT05HIC0gMSkgLyBCSVRfSU5fTE9OR107CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBIdWdlRW51bVNldEl0ZXJhdG9yIGltcGxlbWVudHMgSXRlcmF0b3I8RT4geworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgYml0cyB5ZXQgdG8gYmUgcmV0dXJuZWQgZm9yIHRoZSBsb25nIGluIGJpdHNbaW5kZXhdLiBBcyB2YWx1ZXMgZnJvbSB0aGUgY3VycmVudCBpbmRleAorICAgICAgICAgKiBhcmUgcmV0dXJuZWQsIHRoZWlyIGJpdHMgYXJlIHplcm9lZCBvdXQuIFdoZW4gdGhpcyByZWFjaGVzIHplcm8sIHRoZSBpbmRleCBtdXN0IGJlCisgICAgICAgICAqIGluY3JlbWVudGVkLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBsb25nIGN1cnJlbnRCaXRzID0gYml0c1swXTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGluZGV4IGludG8gSHVnZUVudW1TZXQuYml0cyBvZiB0aGUgbmV4dCB2YWx1ZSB0byByZXR1cm4uCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGludCBpbmRleDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHNpbmdsZSBiaXQgb2YgdGhlIG5leHQgdmFsdWUgdG8gcmV0dXJuLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBsb25nIG1hc2s7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBjYW5kaWRhdGUgZm9yIHJlbW92YWwuIElmIG51bGwsIG5vIHZhbHVlIG1heSBiZSByZW1vdmVkLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBFIGxhc3Q7CisKKyAgICAgICAgcHJpdmF0ZSBIdWdlRW51bVNldEl0ZXJhdG9yKCkgeworICAgICAgICAgICAgY29tcHV0ZU5leHRFbGVtZW50KCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQXNzaWducyBtYXNrIGFuZCBpbmRleCB0byB0aGUgbmV4dCBhdmFpbGFibGUgdmFsdWUsIGN5Y2xpbmcgY3VycmVudEJpdHMgYXMgbmVjZXNzYXJ5LgorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBjb21wdXRlTmV4dEVsZW1lbnQoKSB7CisgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgIGlmIChjdXJyZW50Qml0cyAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIG1hc2sgPSBjdXJyZW50Qml0cyAmIC1jdXJyZW50Qml0czsgLy8gdGhlIGxvd2VzdCAxIGJpdCBpbiBjdXJyZW50Qml0cworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgrK2luZGV4IDwgYml0cy5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgY3VycmVudEJpdHMgPSBiaXRzW2luZGV4XTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBtYXNrID0gMDsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICByZXR1cm4gbWFzayAhPSAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEUgbmV4dCgpIHsKKyAgICAgICAgICAgIGlmIChtYXNrID09IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgb3JkaW5hbCA9IExvbmcubnVtYmVyT2ZUcmFpbGluZ1plcm9zKG1hc2spICsgaW5kZXggKiBCSVRfSU5fTE9ORzsKKyAgICAgICAgICAgIGxhc3QgPSBlbnVtc1tvcmRpbmFsXTsKKworICAgICAgICAgICAgY3VycmVudEJpdHMgJj0gfm1hc2s7CisgICAgICAgICAgICBjb21wdXRlTmV4dEVsZW1lbnQoKTsKKworICAgICAgICAgICAgcmV0dXJuIGxhc3Q7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICBpZiAobGFzdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBIdWdlRW51bVNldC50aGlzLnJlbW92ZShsYXN0KTsKKyAgICAgICAgICAgIGxhc3QgPSBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gYWRkKEUgZWxlbWVudCkgeworICAgICAgICBlbGVtZW50Q2xhc3MuY2FzdChlbGVtZW50KTsgLy8gQ2FsbGVkIHRvIHRocm93IENsYXNzQ2FzdEV4Y2VwdGlvbi4KKyAgICAgICAgaW50IG9yZGluYWwgPSBlbGVtZW50Lm9yZGluYWwoKTsKKyAgICAgICAgaW50IGluZGV4ID0gb3JkaW5hbCAvIEJJVF9JTl9MT05HOworICAgICAgICBpbnQgaW5CaXRzID0gb3JkaW5hbCAlIEJJVF9JTl9MT05HOworICAgICAgICBsb25nIG9sZEJpdHMgPSBiaXRzW2luZGV4XTsKKyAgICAgICAgbG9uZyBuZXdCaXRzID0gb2xkQml0cyB8ICgxTCA8PCBpbkJpdHMpOworICAgICAgICBpZiAob2xkQml0cyAhPSBuZXdCaXRzKSB7CisgICAgICAgICAgICBiaXRzW2luZGV4XSA9IG5ld0JpdHM7CisgICAgICAgICAgICBzaXplKys7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gYWRkQWxsKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgaWYgKGNvbGxlY3Rpb24uaXNFbXB0eSgpIHx8IGNvbGxlY3Rpb24gPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGNvbGxlY3Rpb24gaW5zdGFuY2VvZiBFbnVtU2V0KSB7CisgICAgICAgICAgICBFbnVtU2V0PD8+IHNldCA9IChFbnVtU2V0KSBjb2xsZWN0aW9uOyAvLyByYXcgdHlwZSBkdWUgdG8gamF2YWMgYnVnIDY1NDg0MzYKKyAgICAgICAgICAgIHNldC5lbGVtZW50Q2xhc3MuYXNTdWJjbGFzcyhlbGVtZW50Q2xhc3MpOyAvLyBDYWxsZWQgdG8gdGhyb3cgQ2xhc3NDYXN0RXhjZXB0aW9uLgorCisgICAgICAgICAgICBIdWdlRW51bVNldDxFPiBodWdlU2V0ID0gKEh1Z2VFbnVtU2V0PEU+KSBzZXQ7CisgICAgICAgICAgICBib29sZWFuIGNoYW5nZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYml0cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGxvbmcgb2xkQml0cyA9IGJpdHNbaV07CisgICAgICAgICAgICAgICAgbG9uZyBuZXdCaXRzID0gb2xkQml0cyB8IGh1Z2VTZXQuYml0c1tpXTsKKyAgICAgICAgICAgICAgICBpZiAob2xkQml0cyAhPSBuZXdCaXRzKSB7CisgICAgICAgICAgICAgICAgICAgIGJpdHNbaV0gPSBuZXdCaXRzOworICAgICAgICAgICAgICAgICAgICBzaXplICs9IExvbmcuYml0Q291bnQobmV3Qml0cykgLSBMb25nLmJpdENvdW50KG9sZEJpdHMpOworICAgICAgICAgICAgICAgICAgICBjaGFuZ2VkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gY2hhbmdlZDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3VwZXIuYWRkQWxsKGNvbGxlY3Rpb24pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIHNpemU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgIEFycmF5cy5maWxsKGJpdHMsIDApOworICAgICAgICBzaXplID0gMDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBjb21wbGVtZW50KCkgeworICAgICAgICBzaXplID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDAsIGxlbmd0aCA9IGJpdHMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGxvbmcgYiA9IH5iaXRzW2ldOworCisgICAgICAgICAgICAvLyB6ZXJvIG91dCB1bnVzZWQgYml0cyBvbiB0aGUgbGFzdCBlbGVtZW50CisgICAgICAgICAgICBpZiAoaSA9PSBsZW5ndGggLSAxKSB7CisgICAgICAgICAgICAgICAgYiAmPSAtMUwgPj4+IChCSVRfSU5fTE9ORyAtIChlbnVtcy5sZW5ndGggJSBCSVRfSU5fTE9ORykpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzaXplICs9IExvbmcuYml0Q291bnQoYik7CisgICAgICAgICAgICBiaXRzW2ldID0gYjsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgaWYgKG9iamVjdCA9PSBudWxsIHx8ICFpc1ZhbGlkVHlwZShvYmplY3QuZ2V0Q2xhc3MoKSkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSAvLyBndWFyZGVkIGJ5IGlzVmFsaWRUeXBlKCkKKyAgICAgICAgaW50IG9yZGluYWwgPSAoKEUpIG9iamVjdCkub3JkaW5hbCgpOworICAgICAgICBpbnQgaW5kZXggPSBvcmRpbmFsIC8gQklUX0lOX0xPTkc7CisgICAgICAgIGludCBpbkJpdHMgPSBvcmRpbmFsICUgQklUX0lOX0xPTkc7CisgICAgICAgIHJldHVybiAoYml0c1tpbmRleF0gJiAoMUwgPDwgaW5CaXRzKSkgIT0gMDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSHVnZUVudW1TZXQ8RT4gY2xvbmUoKSB7CisgICAgICAgIEh1Z2VFbnVtU2V0PEU+IHNldCA9IChIdWdlRW51bVNldDxFPikgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgc2V0LmJpdHMgPSBiaXRzLmNsb25lKCk7CisgICAgICAgIHJldHVybiBzZXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNBbGwoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKSB7CisgICAgICAgIGlmIChjb2xsZWN0aW9uLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvbGxlY3Rpb24gaW5zdGFuY2VvZiBIdWdlRW51bVNldCkgeworICAgICAgICAgICAgSHVnZUVudW1TZXQ8Pz4gc2V0ID0gKEh1Z2VFbnVtU2V0PD8+KSBjb2xsZWN0aW9uOworICAgICAgICAgICAgaWYgKGlzVmFsaWRUeXBlKHNldC5lbGVtZW50Q2xhc3MpKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBiaXRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGxvbmcgc2V0Qml0cyA9IHNldC5iaXRzW2ldOworICAgICAgICAgICAgICAgICAgICBpZiAoKGJpdHNbaV0gJiBzZXRCaXRzKSAhPSBzZXRCaXRzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuICEoY29sbGVjdGlvbiBpbnN0YW5jZW9mIEVudW1TZXQpICYmIHN1cGVyLmNvbnRhaW5zQWxsKGNvbGxlY3Rpb24pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmICghaXNWYWxpZFR5cGUob2JqZWN0LmdldENsYXNzKCkpKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iamVjdCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMoYml0cywgKChIdWdlRW51bVNldDw/Pikgb2JqZWN0KS5iaXRzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSXRlcmF0b3I8RT4gaXRlcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBuZXcgSHVnZUVudW1TZXRJdGVyYXRvcigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmIChvYmplY3QgPT0gbnVsbCB8fCAhaXNWYWxpZFR5cGUob2JqZWN0LmdldENsYXNzKCkpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikgLy8gZ3VhcmRlZCBieSBpc1ZhbGlkVHlwZSgpCisgICAgICAgIGludCBvcmRpbmFsID0gKChFKSBvYmplY3QpLm9yZGluYWwoKTsKKyAgICAgICAgaW50IGluZGV4ID0gb3JkaW5hbCAvIEJJVF9JTl9MT05HOworICAgICAgICBpbnQgaW5CaXRzID0gb3JkaW5hbCAlIEJJVF9JTl9MT05HOworICAgICAgICBsb25nIG9sZEJpdHMgPSBiaXRzW2luZGV4XTsKKyAgICAgICAgbG9uZyBuZXdCaXRzID0gb2xkQml0cyAmIH4oMUwgPDwgaW5CaXRzKTsKKyAgICAgICAgaWYgKG9sZEJpdHMgIT0gbmV3Qml0cykgeworICAgICAgICAgICAgYml0c1tpbmRleF0gPSBuZXdCaXRzOworICAgICAgICAgICAgc2l6ZS0tOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZUFsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgaWYgKGNvbGxlY3Rpb24uaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBpZiAoY29sbGVjdGlvbiBpbnN0YW5jZW9mIEVudW1TZXQpIHsKKyAgICAgICAgICAgIEVudW1TZXQ8Pz4gc2V0ID0gKEVudW1TZXQ8Pz4pIGNvbGxlY3Rpb247CisgICAgICAgICAgICBpZiAoIWlzVmFsaWRUeXBlKHNldC5lbGVtZW50Q2xhc3MpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBIdWdlRW51bVNldDxFPiBodWdlU2V0ID0gKEh1Z2VFbnVtU2V0PEU+KSBzZXQ7CisgICAgICAgICAgICBib29sZWFuIGNoYW5nZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYml0cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGxvbmcgb2xkQml0cyA9IGJpdHNbaV07CisgICAgICAgICAgICAgICAgbG9uZyBuZXdCaXRzID0gb2xkQml0cyAmIH5odWdlU2V0LmJpdHNbaV07CisgICAgICAgICAgICAgICAgaWYgKG9sZEJpdHMgIT0gbmV3Qml0cykgeworICAgICAgICAgICAgICAgICAgICBiaXRzW2ldID0gbmV3Qml0czsKKyAgICAgICAgICAgICAgICAgICAgc2l6ZSArPSBMb25nLmJpdENvdW50KG5ld0JpdHMpIC0gTG9uZy5iaXRDb3VudChvbGRCaXRzKTsKKyAgICAgICAgICAgICAgICAgICAgY2hhbmdlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGNoYW5nZWQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN1cGVyLnJlbW92ZUFsbChjb2xsZWN0aW9uKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiByZXRhaW5BbGwoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKSB7CisgICAgICAgIGlmIChjb2xsZWN0aW9uIGluc3RhbmNlb2YgRW51bVNldCkgeworICAgICAgICAgICAgRW51bVNldDw/PiBzZXQgPSAoRW51bVNldDw/PikgY29sbGVjdGlvbjsKKyAgICAgICAgICAgIGlmICghaXNWYWxpZFR5cGUoc2V0LmVsZW1lbnRDbGFzcykpIHsKKyAgICAgICAgICAgICAgICBpZiAoc2l6ZSA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgY2xlYXIoKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgSHVnZUVudW1TZXQ8RT4gaHVnZVNldCA9IChIdWdlRW51bVNldDxFPikgc2V0OworICAgICAgICAgICAgYm9vbGVhbiBjaGFuZ2VkID0gZmFsc2U7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJpdHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBsb25nIG9sZEJpdHMgPSBiaXRzW2ldOworICAgICAgICAgICAgICAgIGxvbmcgbmV3Qml0cyA9IG9sZEJpdHMgJiBodWdlU2V0LmJpdHNbaV07CisgICAgICAgICAgICAgICAgaWYgKG9sZEJpdHMgIT0gbmV3Qml0cykgeworICAgICAgICAgICAgICAgICAgICBiaXRzW2ldID0gbmV3Qml0czsKKyAgICAgICAgICAgICAgICAgICAgc2l6ZSArPSBMb25nLmJpdENvdW50KG5ld0JpdHMpIC0gTG9uZy5iaXRDb3VudChvbGRCaXRzKTsKKyAgICAgICAgICAgICAgICAgICAgY2hhbmdlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGNoYW5nZWQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN1cGVyLnJldGFpbkFsbChjb2xsZWN0aW9uKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICB2b2lkIHNldFJhbmdlKEUgc3RhcnQsIEUgZW5kKSB7CisgICAgICAgIGludCBzdGFydE9yZGluYWwgPSBzdGFydC5vcmRpbmFsKCk7CisgICAgICAgIGludCBzdGFydEluZGV4ID0gc3RhcnRPcmRpbmFsIC8gQklUX0lOX0xPTkc7CisgICAgICAgIGludCBzdGFydEluQml0cyA9IHN0YXJ0T3JkaW5hbCAlIEJJVF9JTl9MT05HOworCisgICAgICAgIGludCBlbmRPcmRpbmFsID0gZW5kLm9yZGluYWwoKTsKKyAgICAgICAgaW50IGVuZEluZGV4ID0gZW5kT3JkaW5hbCAvIEJJVF9JTl9MT05HOworICAgICAgICBpbnQgZW5kSW5CaXRzID0gZW5kT3JkaW5hbCAlIEJJVF9JTl9MT05HOworCisgICAgICAgIGlmIChzdGFydEluZGV4ID09IGVuZEluZGV4KSB7CisgICAgICAgICAgICBsb25nIHJhbmdlID0gKC0xTCA+Pj4gKEJJVF9JTl9MT05HIC0oZW5kSW5CaXRzIC0gc3RhcnRJbkJpdHMgKyAxKSkpIDw8IHN0YXJ0SW5CaXRzOworICAgICAgICAgICAgc2l6ZSAtPSBMb25nLmJpdENvdW50KGJpdHNbc3RhcnRJbmRleF0pOworICAgICAgICAgICAgYml0c1tzdGFydEluZGV4XSB8PSByYW5nZTsKKyAgICAgICAgICAgIHNpemUgKz0gTG9uZy5iaXRDb3VudChiaXRzW3N0YXJ0SW5kZXhdKTsKKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbG9uZyByYW5nZSA9ICgtMUwgPj4+IHN0YXJ0SW5CaXRzKSA8PCBzdGFydEluQml0czsKKyAgICAgICAgICAgIHNpemUgLT0gTG9uZy5iaXRDb3VudChiaXRzW3N0YXJ0SW5kZXhdKTsKKyAgICAgICAgICAgIGJpdHNbc3RhcnRJbmRleF0gfD0gcmFuZ2U7CisgICAgICAgICAgICBzaXplICs9IExvbmcuYml0Q291bnQoYml0c1tzdGFydEluZGV4XSk7CisKKyAgICAgICAgICAgIC8vIGVuZEluQml0cyArIDEgaXMgdGhlIG51bWJlciBvZiBjb25zZWN1dGl2ZSBvbmVzLgorICAgICAgICAgICAgLy8gNjMgLSBlbmRJbkJpdHMgaXMgdGhlIGZvbGxvd2luZyB6ZXJvcyBvZiB0aGUgcmlnaHQgbW9zdCBvbmUuCisgICAgICAgICAgICByYW5nZSA9IC0xTCA+Pj4gKEJJVF9JTl9MT05HIC0gKGVuZEluQml0cyArIDEpKTsKKyAgICAgICAgICAgIHNpemUgLT0gTG9uZy5iaXRDb3VudChiaXRzW2VuZEluZGV4XSk7CisgICAgICAgICAgICBiaXRzW2VuZEluZGV4XSB8PSByYW5nZTsKKyAgICAgICAgICAgIHNpemUgKz0gTG9uZy5iaXRDb3VudChiaXRzW2VuZEluZGV4XSk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gKHN0YXJ0SW5kZXggKyAxKTsgaSA8PSAoZW5kSW5kZXggLSAxKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgc2l6ZSAtPSBMb25nLmJpdENvdW50KGJpdHNbaV0pOworICAgICAgICAgICAgICAgIGJpdHNbaV0gPSAtMUw7CisgICAgICAgICAgICAgICAgc2l6ZSArPSBMb25nLmJpdENvdW50KGJpdHNbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9JZGVudGl0eUhhc2hNYXAuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvSWRlbnRpdHlIYXNoTWFwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTY5M2Y3ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvSWRlbnRpdHlIYXNoTWFwLmphdmEKQEAgLTAsMCArMSw4MjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCisvKioKKyAqIElkZW50aXR5SGFzaE1hcCBpcyBhIHZhcmlhbnQgb24gSGFzaE1hcCB3aGljaCB0ZXN0cyBlcXVhbGl0eSBieSByZWZlcmVuY2UKKyAqIGluc3RlYWQgb2YgZXF1YWxpdHkgYnkgdmFsdWUuIEJhc2ljYWxseSwga2V5cyBhbmQgdmFsdWVzIGFyZSBjb21wYXJlZCBmb3IKKyAqIGVxdWFsaXR5IGJ5IGNoZWNraW5nIGlmIHRoZWlyIHJlZmVyZW5jZXMgYXJlIGVxdWFsIHJhdGhlciB0aGFuIGJ5IGNhbGxpbmcgdGhlCisgKiAiZXF1YWxzIiBmdW5jdGlvbi4KKyAqIDxwPgorICogPGI+Tm90ZTogVGhpcyBjbGFzcyBpbnRlbnRpb25hbGx5IHZpb2xhdGVzIHRoZSBnZW5lcmFsIGNvbnRyYWN0IG9mIHtAY29kZQorICogTWFwfSdzIG9uIGNvbXBhcmluZyBvYmplY3RzIGJ5IHRoZWlyIHtAY29kZSBlcXVhbHN9IG1ldGhvZC48L2I+CisgKiA8cD4KKyAqIElkZW50aXR5SGFzaE1hcCB1c2VzIG9wZW4gYWRkcmVzc2luZyAobGluZWFyIHByb2JpbmcgaW4gcGFydGljdWxhcikgZm9yCisgKiBjb2xsaXNpb24gcmVzb2x1dGlvbi4gVGhpcyBpcyBkaWZmZXJlbnQgZnJvbSBIYXNoTWFwIHdoaWNoIHVzZXMgQ2hhaW5pbmcuCisgKiA8cD4KKyAqIExpa2UgSGFzaE1hcCwgSWRlbnRpdHlIYXNoTWFwIGlzIG5vdCB0aHJlYWQgc2FmZSwgc28gYWNjZXNzIGJ5IG11bHRpcGxlCisgKiB0aHJlYWRzIG11c3QgYmUgc3luY2hyb25pemVkIGJ5IGFuIGV4dGVybmFsIG1lY2hhbmlzbSBzdWNoIGFzCisgKiBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRNYXAuCisgKgorICogQHNpbmNlIDEuNAorICovCitwdWJsaWMgY2xhc3MgSWRlbnRpdHlIYXNoTWFwPEssIFY+IGV4dGVuZHMgQWJzdHJhY3RNYXA8SywgVj4gaW1wbGVtZW50cworICAgICAgICBNYXA8SywgVj4sIFNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDgxODgyMTgxMjgzNTM5MTMyMTZMOworCisgICAgLyoKKyAgICAgKiBUaGUgaW50ZXJuYWwgZGF0YSBzdHJ1Y3R1cmUgdG8gaG9sZCBrZXkgdmFsdWUgcGFpcnMgVGhpcyBhcnJheSBob2xkcyBrZXlzCisgICAgICogYW5kIHZhbHVlcyBpbiBhbiBhbHRlcm5hdGluZyBmYXNoaW9uLgorICAgICAqLworICAgIHRyYW5zaWVudCBPYmplY3RbXSBlbGVtZW50RGF0YTsKKworICAgIC8qIEFjdHVhbCBudW1iZXIgb2Yga2V5LXZhbHVlIHBhaXJzLiAqLworICAgIGludCBzaXplOworCisgICAgLyoKKyAgICAgKiBtYXhpbXVtIG51bWJlciBvZiBlbGVtZW50cyB0aGF0IGNhbiBiZSBwdXQgaW4gdGhpcyBtYXAgYmVmb3JlIGhhdmluZyB0bworICAgICAqIHJlaGFzaC4KKyAgICAgKi8KKyAgICB0cmFuc2llbnQgaW50IHRocmVzaG9sZDsKKworICAgIC8qCisgICAgICogZGVmYXVsdCB0aHJlc2hvbGQgdmFsdWUgdGhhdCBhbiBJZGVudGl0eUhhc2hNYXAgY3JlYXRlZCB1c2luZyB0aGUgZGVmYXVsdAorICAgICAqIGNvbnN0cnVjdG9yIHdvdWxkIGhhdmUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfTUFYX1NJWkUgPSAyMTsKKworICAgIC8qIERlZmF1bHQgbG9hZCBmYWN0b3Igb2YgMC43NTsgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgbG9hZEZhY3RvciA9IDc1MDA7CisKKyAgICAvKgorICAgICAqIG1vZGlmaWNhdGlvbiBjb3VudCwgdG8ga2VlcCB0cmFjayBvZiBzdHJ1Y3R1cmFsIG1vZGlmaWNhdGlvbnMgYmV0d2VlbiB0aGUKKyAgICAgKiBJZGVudGl0eUhhc2hNYXAgYW5kIHRoZSBpdGVyYXRvcgorICAgICAqLworICAgIHRyYW5zaWVudCBpbnQgbW9kQ291bnQgPSAwOworCisgICAgLyoKKyAgICAgKiBPYmplY3QgdXNlZCB0byByZXByZXNlbnQgbnVsbCBrZXlzIGFuZCB2YWx1ZXMuIFRoaXMgaXMgdXNlZCB0bworICAgICAqIGRpZmZlcmVudGlhdGUgYSBsaXRlcmFsICdudWxsJyBrZXkgdmFsdWUgcGFpciBmcm9tIGFuIGVtcHR5IHNwb3QgaW4gdGhlCisgICAgICogbWFwLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdCBOVUxMX09CSkVDVCA9IG5ldyBPYmplY3QoKTsgIC8vJE5PTi1MT0NLLTEkCisKKyAgICBzdGF0aWMgY2xhc3MgSWRlbnRpdHlIYXNoTWFwRW50cnk8SywgVj4gZXh0ZW5kcyBNYXBFbnRyeTxLLCBWPiB7CisgICAgICAgIHByaXZhdGUgZmluYWwgSWRlbnRpdHlIYXNoTWFwPEssVj4gbWFwOworCisgICAgICAgIElkZW50aXR5SGFzaE1hcEVudHJ5KElkZW50aXR5SGFzaE1hcDxLLFY+IG1hcCwgSyB0aGVLZXksIFYgdGhlVmFsdWUpIHsKKyAgICAgICAgICAgIHN1cGVyKHRoZUtleSwgdGhlVmFsdWUpOworICAgICAgICAgICAgdGhpcy5tYXAgPSBtYXA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICBpZiAodGhpcyA9PSBvYmplY3QpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBNYXAuRW50cnkpIHsKKyAgICAgICAgICAgICAgICBNYXAuRW50cnk8PywgPz4gZW50cnkgPSAoTWFwLkVudHJ5KSBvYmplY3Q7CisgICAgICAgICAgICAgICAgcmV0dXJuIChrZXkgPT0gZW50cnkuZ2V0S2V5KCkpICYmICh2YWx1ZSA9PSBlbnRyeS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgcmV0dXJuIFN5c3RlbS5pZGVudGl0eUhhc2hDb2RlKGtleSkKKyAgICAgICAgICAgICAgICAgICAgXiBTeXN0ZW0uaWRlbnRpdHlIYXNoQ29kZSh2YWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBrZXkgKyAiPSIgKyB2YWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgViBzZXRWYWx1ZShWIG9iamVjdCkgeworICAgICAgICAgICAgViByZXN1bHQgPSBzdXBlci5zZXRWYWx1ZShvYmplY3QpOworICAgICAgICAgICAgbWFwLnB1dChrZXksIG9iamVjdCk7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIElkZW50aXR5SGFzaE1hcEl0ZXJhdG9yPEUsIEtULCBWVD4gaW1wbGVtZW50cyBJdGVyYXRvcjxFPiB7CisgICAgICAgIHByaXZhdGUgaW50IHBvc2l0aW9uID0gMDsgLy8gdGhlIGN1cnJlbnQgcG9zaXRpb24KKworICAgICAgICAvLyB0aGUgcG9zaXRpb24gb2YgdGhlIGVudHJ5IHRoYXQgd2FzIGxhc3QgcmV0dXJuZWQgZnJvbSBuZXh0KCkKKyAgICAgICAgcHJpdmF0ZSBpbnQgbGFzdFBvc2l0aW9uID0gMDsKKworICAgICAgICBmaW5hbCBJZGVudGl0eUhhc2hNYXA8S1QsIFZUPiBhc3NvY2lhdGVkTWFwOworCisgICAgICAgIGludCBleHBlY3RlZE1vZENvdW50OworCisgICAgICAgIGZpbmFsIE1hcEVudHJ5LlR5cGU8RSwgS1QsIFZUPiB0eXBlOworCisgICAgICAgIGJvb2xlYW4gY2FuUmVtb3ZlID0gZmFsc2U7CisKKyAgICAgICAgSWRlbnRpdHlIYXNoTWFwSXRlcmF0b3IoTWFwRW50cnkuVHlwZTxFLCBLVCwgVlQ+IHZhbHVlLAorICAgICAgICAgICAgICAgIElkZW50aXR5SGFzaE1hcDxLVCwgVlQ+IGhtKSB7CisgICAgICAgICAgICBhc3NvY2lhdGVkTWFwID0gaG07CisgICAgICAgICAgICB0eXBlID0gdmFsdWU7CisgICAgICAgICAgICBleHBlY3RlZE1vZENvdW50ID0gaG0ubW9kQ291bnQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgd2hpbGUgKHBvc2l0aW9uIDwgYXNzb2NpYXRlZE1hcC5lbGVtZW50RGF0YS5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAvLyBpZiB0aGlzIGlzIGFuIGVtcHR5IHNwb3QsIGdvIHRvIHRoZSBuZXh0IG9uZQorICAgICAgICAgICAgICAgIGlmIChhc3NvY2lhdGVkTWFwLmVsZW1lbnREYXRhW3Bvc2l0aW9uXSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uICs9IDI7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgdm9pZCBjaGVja0NvbmN1cnJlbnRNb2QoKSB0aHJvd3MgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoZXhwZWN0ZWRNb2RDb3VudCAhPSBhc3NvY2lhdGVkTWFwLm1vZENvdW50KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFIG5leHQoKSB7CisgICAgICAgICAgICBjaGVja0NvbmN1cnJlbnRNb2QoKTsKKyAgICAgICAgICAgIGlmICghaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgSWRlbnRpdHlIYXNoTWFwRW50cnk8S1QsIFZUPiByZXN1bHQgPSBhc3NvY2lhdGVkTWFwCisgICAgICAgICAgICAgICAgICAgIC5nZXRFbnRyeShwb3NpdGlvbik7CisgICAgICAgICAgICBsYXN0UG9zaXRpb24gPSBwb3NpdGlvbjsKKyAgICAgICAgICAgIHBvc2l0aW9uICs9IDI7CisKKyAgICAgICAgICAgIGNhblJlbW92ZSA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gdHlwZS5nZXQocmVzdWx0KTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgIGNoZWNrQ29uY3VycmVudE1vZCgpOworICAgICAgICAgICAgaWYgKCFjYW5SZW1vdmUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNhblJlbW92ZSA9IGZhbHNlOworICAgICAgICAgICAgYXNzb2NpYXRlZE1hcC5yZW1vdmUoYXNzb2NpYXRlZE1hcC5lbGVtZW50RGF0YVtsYXN0UG9zaXRpb25dKTsKKyAgICAgICAgICAgIHBvc2l0aW9uID0gbGFzdFBvc2l0aW9uOworICAgICAgICAgICAgZXhwZWN0ZWRNb2RDb3VudCsrOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIElkZW50aXR5SGFzaE1hcEVudHJ5U2V0PEtULCBWVD4gZXh0ZW5kcworICAgICAgICAgICAgQWJzdHJhY3RTZXQ8TWFwLkVudHJ5PEtULCBWVD4+IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBJZGVudGl0eUhhc2hNYXA8S1QsIFZUPiBhc3NvY2lhdGVkTWFwOworCisgICAgICAgIHB1YmxpYyBJZGVudGl0eUhhc2hNYXBFbnRyeVNldChJZGVudGl0eUhhc2hNYXA8S1QsIFZUPiBobSkgeworICAgICAgICAgICAgYXNzb2NpYXRlZE1hcCA9IGhtOworICAgICAgICB9CisKKyAgICAgICAgSWRlbnRpdHlIYXNoTWFwPEtULCBWVD4gaGFzaE1hcCgpIHsKKyAgICAgICAgICAgIHJldHVybiBhc3NvY2lhdGVkTWFwOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBhc3NvY2lhdGVkTWFwLnNpemU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICBhc3NvY2lhdGVkTWFwLmNsZWFyKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIGlmIChjb250YWlucyhvYmplY3QpKSB7CisgICAgICAgICAgICAgICAgYXNzb2NpYXRlZE1hcC5yZW1vdmUoKChNYXAuRW50cnkpIG9iamVjdCkuZ2V0S2V5KCkpOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBNYXAuRW50cnkpIHsKKyAgICAgICAgICAgICAgICBJZGVudGl0eUhhc2hNYXBFbnRyeTw/LCA/PiBlbnRyeSA9IGFzc29jaWF0ZWRNYXAKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRFbnRyeSgoKE1hcC5FbnRyeSkgb2JqZWN0KS5nZXRLZXkoKSk7CisgICAgICAgICAgICAgICAgLy8gd2UgbXVzdCBjYWxsIGVxdWFscyBvbiB0aGUgZW50cnkgb2J0YWluZWQgZnJvbSAidGhpcyIKKyAgICAgICAgICAgICAgICByZXR1cm4gZW50cnkgIT0gbnVsbCAmJiBlbnRyeS5lcXVhbHMob2JqZWN0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgSXRlcmF0b3I8TWFwLkVudHJ5PEtULCBWVD4+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBJZGVudGl0eUhhc2hNYXBJdGVyYXRvcjxNYXAuRW50cnk8S1QsIFZUPiwgS1QsIFZUPigKKyAgICAgICAgICAgICAgICAgICAgbmV3IE1hcEVudHJ5LlR5cGU8TWFwLkVudHJ5PEtULCBWVD4sIEtULCBWVD4oKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgTWFwLkVudHJ5PEtULCBWVD4gZ2V0KE1hcEVudHJ5PEtULCBWVD4gZW50cnkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW50cnk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0sIGFzc29jaWF0ZWRNYXApOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBJZGVudGl0eUhhc2hNYXAgd2l0aCBkZWZhdWx0IGV4cGVjdGVkIG1heGltdW0gc2l6ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSWRlbnRpdHlIYXNoTWFwKCkgeworICAgICAgICB0aGlzKERFRkFVTFRfTUFYX1NJWkUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gSWRlbnRpdHlIYXNoTWFwIHdpdGggdGhlIHNwZWNpZmllZCBtYXhpbXVtIHNpemUgcGFyYW1ldGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG1heFNpemUKKyAgICAgKiAgICAgICAgICAgIFRoZSBlc3RpbWF0ZWQgbWF4aW11bSBudW1iZXIgb2YgZW50cmllcyB0aGF0IHdpbGwgYmUgcHV0IGluCisgICAgICogICAgICAgICAgICB0aGlzIG1hcC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSWRlbnRpdHlIYXNoTWFwKGludCBtYXhTaXplKSB7CisgICAgICAgIGlmIChtYXhTaXplID49IDApIHsKKyAgICAgICAgICAgIHRoaXMuc2l6ZSA9IDA7CisgICAgICAgICAgICB0aHJlc2hvbGQgPSBnZXRUaHJlc2hvbGQobWF4U2l6ZSk7CisgICAgICAgICAgICBlbGVtZW50RGF0YSA9IG5ld0VsZW1lbnRBcnJheShjb21wdXRlRWxlbWVudEFycmF5U2l6ZSgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgaW50IGdldFRocmVzaG9sZChpbnQgbWF4U2l6ZSkgeworICAgICAgICAvLyBhc3NpZ24gdGhlIHRocmVzaG9sZCB0byBtYXhTaXplIGluaXRpYWxseSwgdGhpcyB3aWxsIGNoYW5nZSB0byBhCisgICAgICAgIC8vIGhpZ2hlciB2YWx1ZSBpZiByZWhhc2hpbmcgb2NjdXJzLgorICAgICAgICByZXR1cm4gbWF4U2l6ZSA+IDMgPyBtYXhTaXplIDogMzsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBjb21wdXRlRWxlbWVudEFycmF5U2l6ZSgpIHsKKyAgICAgICAgaW50IGFycmF5U2l6ZSA9IChpbnQpICgoKGxvbmcpIHRocmVzaG9sZCAqIDEwMDAwKSAvIGxvYWRGYWN0b3IpICogMjsKKyAgICAgICAgLy8gZW5zdXJlIGFycmF5U2l6ZSBpcyBwb3NpdGl2ZSwgdGhlIGFib3ZlIGNhc3QgZnJvbSBsb25nIHRvIGludCB0eXBlCisgICAgICAgIC8vIGxlYWRzIHRvIG92ZXJmbG93IGFuZCBuZWdhdGl2ZSBhcnJheVNpemUgaWYgdGhyZXNob2xkIGlzIHRvbyBiaWcKKyAgICAgICAgcmV0dXJuIGFycmF5U2l6ZSA8IDAgPyAtYXJyYXlTaXplIDogYXJyYXlTaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBlbGVtZW50IGFycmF5CisgICAgICoKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBlbGVtZW50cworICAgICAqIEByZXR1cm4gUmVmZXJlbmNlIHRvIHRoZSBlbGVtZW50IGFycmF5CisgICAgICovCisgICAgcHJpdmF0ZSBPYmplY3RbXSBuZXdFbGVtZW50QXJyYXkoaW50IHMpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBPYmplY3Rbc107CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBJZGVudGl0eUhhc2hNYXAgdXNpbmcgdGhlIGdpdmVuIG1hcCBhcyBpbml0aWFsIHZhbHVlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtYXAKKyAgICAgKiAgICAgICAgICAgIEEgbWFwIG9mIChrZXksdmFsdWUpIHBhaXJzIHRvIGNvcHkgaW50byB0aGUgSWRlbnRpdHlIYXNoTWFwLgorICAgICAqLworICAgIHB1YmxpYyBJZGVudGl0eUhhc2hNYXAoTWFwPD8gZXh0ZW5kcyBLLCA/IGV4dGVuZHMgVj4gbWFwKSB7CisgICAgICAgIHRoaXMobWFwLnNpemUoKSA8IDYgPyAxMSA6IG1hcC5zaXplKCkgKiAyKTsKKyAgICAgICAgcHV0QWxsSW1wbChtYXApOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHByaXZhdGUgViBtYXNzYWdlVmFsdWUoT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIHJldHVybiAoVikgKCh2YWx1ZSA9PSBOVUxMX09CSkVDVCkgPyBudWxsIDogdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIGVsZW1lbnRzIGZyb20gdGhpcyBtYXAsIGxlYXZpbmcgaXQgZW1wdHkuCisgICAgICoKKyAgICAgKiBAc2VlICNpc0VtcHR5KCkKKyAgICAgKiBAc2VlICNzaXplKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgc2l6ZSA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZWxlbWVudERhdGEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGVsZW1lbnREYXRhW2ldID0gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBtb2RDb3VudCsrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIG1hcCBjb250YWlucyB0aGUgc3BlY2lmaWVkIGtleS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgdG8gc2VhcmNoIGZvci4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIG1hcCBjb250YWlucyB0aGUgc3BlY2lmaWVkIGtleSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrZXkpIHsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICBrZXkgPSBOVUxMX09CSkVDVDsKKyAgICAgICAgfQorCisgICAgICAgIGludCBpbmRleCA9IGZpbmRJbmRleChrZXksIGVsZW1lbnREYXRhKTsKKyAgICAgICAgcmV0dXJuIGVsZW1lbnREYXRhW2luZGV4XSA9PSBrZXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgbWFwIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgbWFwIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgdmFsdWUsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ZhbHVlKE9iamVjdCB2YWx1ZSkgeworICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdmFsdWUgPSBOVUxMX09CSkVDVDsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgZWxlbWVudERhdGEubGVuZ3RoOyBpID0gaSArIDIpIHsKKyAgICAgICAgICAgIGlmIChlbGVtZW50RGF0YVtpXSA9PSB2YWx1ZSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgbWFwcGluZyB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleS4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgbWFwcGluZyB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBWIGdldChPYmplY3Qga2V5KSB7CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeworICAgICAgICAgICAga2V5ID0gTlVMTF9PQkpFQ1Q7CisgICAgICAgIH0KKworICAgICAgICBpbnQgaW5kZXggPSBmaW5kSW5kZXgoa2V5LCBlbGVtZW50RGF0YSk7CisKKyAgICAgICAgaWYgKGVsZW1lbnREYXRhW2luZGV4XSA9PSBrZXkpIHsKKyAgICAgICAgICAgIE9iamVjdCByZXN1bHQgPSBlbGVtZW50RGF0YVtpbmRleCArIDFdOworICAgICAgICAgICAgcmV0dXJuIG1hc3NhZ2VWYWx1ZShyZXN1bHQpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBJZGVudGl0eUhhc2hNYXBFbnRyeTxLLCBWPiBnZXRFbnRyeShPYmplY3Qga2V5KSB7CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeworICAgICAgICAgICAga2V5ID0gTlVMTF9PQkpFQ1Q7CisgICAgICAgIH0KKworICAgICAgICBpbnQgaW5kZXggPSBmaW5kSW5kZXgoa2V5LCBlbGVtZW50RGF0YSk7CisgICAgICAgIGlmIChlbGVtZW50RGF0YVtpbmRleF0gPT0ga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0RW50cnkoaW5kZXgpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVuaWVuY2UgbWV0aG9kIGZvciBnZXR0aW5nIHRoZSBJZGVudGl0eUhhc2hNYXBFbnRyeSB3aXRob3V0IHRoZQorICAgICAqIE5VTExfT0JKRUNUIGVsZW1lbnRzCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHJpdmF0ZSBJZGVudGl0eUhhc2hNYXBFbnRyeTxLLCBWPiBnZXRFbnRyeShpbnQgaW5kZXgpIHsKKyAgICAgICAgT2JqZWN0IGtleSA9IGVsZW1lbnREYXRhW2luZGV4XTsKKyAgICAgICAgT2JqZWN0IHZhbHVlID0gZWxlbWVudERhdGFbaW5kZXggKyAxXTsKKworICAgICAgICBpZiAoa2V5ID09IE5VTExfT0JKRUNUKSB7CisgICAgICAgICAgICBrZXkgPSBudWxsOworICAgICAgICB9CisgICAgICAgIGlmICh2YWx1ZSA9PSBOVUxMX09CSkVDVCkgeworICAgICAgICAgICAgdmFsdWUgPSBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ldyBJZGVudGl0eUhhc2hNYXBFbnRyeTxLLCBWPih0aGlzLCAoSykga2V5LCAoVikgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGluZGV4IHdoZXJlIHRoZSBrZXkgaXMgZm91bmQgYXQsIG9yIHRoZSBpbmRleCBvZiB0aGUgbmV4dAorICAgICAqIGVtcHR5IHNwb3QgaWYgdGhlIGtleSBpcyBub3QgZm91bmQgaW4gdGhpcyB0YWJsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBmaW5kSW5kZXgoT2JqZWN0IGtleSwgT2JqZWN0W10gYXJyYXkpIHsKKyAgICAgICAgaW50IGxlbmd0aCA9IGFycmF5Lmxlbmd0aDsKKyAgICAgICAgaW50IGluZGV4ID0gZ2V0TW9kdWxvSGFzaChrZXksIGxlbmd0aCk7CisgICAgICAgIGludCBsYXN0ID0gKGluZGV4ICsgbGVuZ3RoIC0gMikgJSBsZW5ndGg7CisgICAgICAgIHdoaWxlIChpbmRleCAhPSBsYXN0KSB7CisgICAgICAgICAgICBpZiAoYXJyYXlbaW5kZXhdID09IGtleSB8fCAoYXJyYXlbaW5kZXhdID09IG51bGwpKSB7CisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgKiBGb3VuZCB0aGUga2V5LCBvciB0aGUgbmV4dCBlbXB0eSBzcG90ICh3aGljaCBtZWFucyBrZXkgaXMgbm90CisgICAgICAgICAgICAgICAgICogaW4gdGhlIHRhYmxlKQorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW5kZXggPSAoaW5kZXggKyAyKSAlIGxlbmd0aDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW5kZXg7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgZ2V0TW9kdWxvSGFzaChPYmplY3Qga2V5LCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIHJldHVybiAoKFN5c3RlbS5pZGVudGl0eUhhc2hDb2RlKGtleSkgJiAweDdGRkZGRkZGKSAlIChsZW5ndGggLyAyKSkgKiAyOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1hcHMgdGhlIHNwZWNpZmllZCBrZXkgdG8gdGhlIHNwZWNpZmllZCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgYW55IHByZXZpb3VzIG1hcHBpbmcgd2l0aCB0aGUgc3BlY2lmaWVkIGtleSBvcgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlmIHRoZXJlIHdhcyBubyBzdWNoIG1hcHBpbmcuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFYgcHV0KEsga2V5LCBWIHZhbHVlKSB7CisgICAgICAgIE9iamVjdCBfa2V5ID0ga2V5OworICAgICAgICBPYmplY3QgX3ZhbHVlID0gdmFsdWU7CisgICAgICAgIGlmIChfa2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIF9rZXkgPSBOVUxMX09CSkVDVDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChfdmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgX3ZhbHVlID0gTlVMTF9PQkpFQ1Q7CisgICAgICAgIH0KKworICAgICAgICBpbnQgaW5kZXggPSBmaW5kSW5kZXgoX2tleSwgZWxlbWVudERhdGEpOworCisgICAgICAgIC8vIGlmIHRoZSBrZXkgZG9lc24ndCBleGlzdCBpbiB0aGUgdGFibGUKKyAgICAgICAgaWYgKGVsZW1lbnREYXRhW2luZGV4XSAhPSBfa2V5KSB7CisgICAgICAgICAgICBtb2RDb3VudCsrOworICAgICAgICAgICAgaWYgKCsrc2l6ZSA+IHRocmVzaG9sZCkgeworICAgICAgICAgICAgICAgIHJlaGFzaCgpOworICAgICAgICAgICAgICAgIGluZGV4ID0gZmluZEluZGV4KF9rZXksIGVsZW1lbnREYXRhKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gaW5zZXJ0IHRoZSBrZXkgYW5kIGFzc2lnbiB0aGUgdmFsdWUgdG8gbnVsbCBpbml0aWFsbHkKKyAgICAgICAgICAgIGVsZW1lbnREYXRhW2luZGV4XSA9IF9rZXk7CisgICAgICAgICAgICBlbGVtZW50RGF0YVtpbmRleCArIDFdID0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGluc2VydCB2YWx1ZSB0byB3aGVyZSBpdCBuZWVkcyB0byBnbywgcmV0dXJuIHRoZSBvbGQgdmFsdWUKKyAgICAgICAgT2JqZWN0IHJlc3VsdCA9IGVsZW1lbnREYXRhW2luZGV4ICsgMV07CisgICAgICAgIGVsZW1lbnREYXRhW2luZGV4ICsgMV0gPSBfdmFsdWU7CisKKyAgICAgICAgcmV0dXJuIG1hc3NhZ2VWYWx1ZShyZXN1bHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyBhbGwgdGhlIG1hcHBpbmdzIGluIHRoZSBzcGVjaWZpZWQgbWFwIHRvIHRoaXMgbWFwLiBUaGVzZSBtYXBwaW5ncworICAgICAqIHdpbGwgcmVwbGFjZSBhbGwgbWFwcGluZ3MgdGhhdCB0aGlzIG1hcCBoYWQgZm9yIGFueSBvZiB0aGUga2V5cyBjdXJyZW50bHkKKyAgICAgKiBpbiB0aGUgZ2l2ZW4gbWFwLgorICAgICAqCisgICAgICogQHBhcmFtIG1hcAorICAgICAqICAgICAgICAgICAgdGhlIG1hcCB0byBjb3B5IG1hcHBpbmdzIGZyb20uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBtYXB9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBwdXRBbGwoTWFwPD8gZXh0ZW5kcyBLLCA/IGV4dGVuZHMgVj4gbWFwKSB7CisgICAgICAgIHB1dEFsbEltcGwobWFwKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVoYXNoKCkgeworICAgICAgICBpbnQgbmV3bGVuZ3RoID0gZWxlbWVudERhdGEubGVuZ3RoICogMjsKKyAgICAgICAgaWYgKG5ld2xlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICBuZXdsZW5ndGggPSAxOworICAgICAgICB9CisgICAgICAgIE9iamVjdFtdIG5ld0RhdGEgPSBuZXdFbGVtZW50QXJyYXkobmV3bGVuZ3RoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbGVtZW50RGF0YS5sZW5ndGg7IGkgPSBpICsgMikgeworICAgICAgICAgICAgT2JqZWN0IGtleSA9IGVsZW1lbnREYXRhW2ldOworICAgICAgICAgICAgaWYgKGtleSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgLy8gaWYgbm90IGVtcHR5CisgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gZmluZEluZGV4KGtleSwgbmV3RGF0YSk7CisgICAgICAgICAgICAgICAgbmV3RGF0YVtpbmRleF0gPSBrZXk7CisgICAgICAgICAgICAgICAgbmV3RGF0YVtpbmRleCArIDFdID0gZWxlbWVudERhdGFbaSArIDFdOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsZW1lbnREYXRhID0gbmV3RGF0YTsKKyAgICAgICAgY29tcHV0ZU1heFNpemUoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY29tcHV0ZU1heFNpemUoKSB7CisgICAgICAgIHRocmVzaG9sZCA9IChpbnQpICgobG9uZykgKGVsZW1lbnREYXRhLmxlbmd0aCAvIDIpICogbG9hZEZhY3RvciAvIDEwMDAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBtYXBwaW5nIHdpdGggdGhlIHNwZWNpZmllZCBrZXkgZnJvbSB0aGlzIG1hcC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgb2YgdGhlIG1hcHBpbmcgdG8gcmVtb3ZlLgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSByZW1vdmVkIG1hcHBpbmcsIG9yIHtAY29kZSBudWxsfSBpZiBubyBtYXBwaW5nCisgICAgICogICAgICAgICBmb3IgdGhlIHNwZWNpZmllZCBrZXkgd2FzIGZvdW5kLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBWIHJlbW92ZShPYmplY3Qga2V5KSB7CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeworICAgICAgICAgICAga2V5ID0gTlVMTF9PQkpFQ1Q7CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIGhhc2hlZE9rOworICAgICAgICBpbnQgaW5kZXgsIG5leHQsIGhhc2g7CisgICAgICAgIE9iamVjdCByZXN1bHQsIG9iamVjdDsKKyAgICAgICAgaW5kZXggPSBuZXh0ID0gZmluZEluZGV4KGtleSwgZWxlbWVudERhdGEpOworCisgICAgICAgIGlmIChlbGVtZW50RGF0YVtpbmRleF0gIT0ga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHN0b3JlIHRoZSB2YWx1ZSBmb3IgdGhpcyBrZXkKKyAgICAgICAgcmVzdWx0ID0gZWxlbWVudERhdGFbaW5kZXggKyAxXTsKKworICAgICAgICAvLyBzaGlmdCB0aGUgZm9sbG93aW5nIGVsZW1lbnRzIHVwIGlmIG5lZWRlZAorICAgICAgICAvLyB1bnRpbCB3ZSByZWFjaCBhbiBlbXB0eSBzcG90CisgICAgICAgIGludCBsZW5ndGggPSBlbGVtZW50RGF0YS5sZW5ndGg7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBuZXh0ID0gKG5leHQgKyAyKSAlIGxlbmd0aDsKKyAgICAgICAgICAgIG9iamVjdCA9IGVsZW1lbnREYXRhW25leHRdOworICAgICAgICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGhhc2ggPSBnZXRNb2R1bG9IYXNoKG9iamVjdCwgbGVuZ3RoKTsKKyAgICAgICAgICAgIGhhc2hlZE9rID0gaGFzaCA+IGluZGV4OworICAgICAgICAgICAgaWYgKG5leHQgPCBpbmRleCkgeworICAgICAgICAgICAgICAgIGhhc2hlZE9rID0gaGFzaGVkT2sgfHwgKGhhc2ggPD0gbmV4dCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGhhc2hlZE9rID0gaGFzaGVkT2sgJiYgKGhhc2ggPD0gbmV4dCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIWhhc2hlZE9rKSB7CisgICAgICAgICAgICAgICAgZWxlbWVudERhdGFbaW5kZXhdID0gb2JqZWN0OworICAgICAgICAgICAgICAgIGVsZW1lbnREYXRhW2luZGV4ICsgMV0gPSBlbGVtZW50RGF0YVtuZXh0ICsgMV07CisgICAgICAgICAgICAgICAgaW5kZXggPSBuZXh0OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgc2l6ZS0tOworICAgICAgICBtb2RDb3VudCsrOworCisgICAgICAgIC8vIGNsZWFyIGJvdGggdGhlIGtleSBhbmQgdGhlIHZhbHVlCisgICAgICAgIGVsZW1lbnREYXRhW2luZGV4XSA9IG51bGw7CisgICAgICAgIGVsZW1lbnREYXRhW2luZGV4ICsgMV0gPSBudWxsOworCisgICAgICAgIHJldHVybiBtYXNzYWdlVmFsdWUocmVzdWx0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc2V0IGNvbnRhaW5pbmcgYWxsIG9mIHRoZSBtYXBwaW5ncyBpbiB0aGlzIG1hcC4gRWFjaCBtYXBwaW5nIGlzCisgICAgICogYW4gaW5zdGFuY2Ugb2Yge0BsaW5rIE1hcC5FbnRyeX0uIEFzIHRoZSBzZXQgaXMgYmFja2VkIGJ5IHRoaXMgbWFwLAorICAgICAqIGNoYW5nZXMgaW4gb25lIHdpbGwgYmUgcmVmbGVjdGVkIGluIHRoZSBvdGhlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzZXQgb2YgdGhlIG1hcHBpbmdzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTZXQ8TWFwLkVudHJ5PEssIFY+PiBlbnRyeVNldCgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBJZGVudGl0eUhhc2hNYXBFbnRyeVNldDxLLCBWPih0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc2V0IG9mIHRoZSBrZXlzIGNvbnRhaW5lZCBpbiB0aGlzIG1hcC4gVGhlIHNldCBpcyBiYWNrZWQgYnkKKyAgICAgKiB0aGlzIG1hcCBzbyBjaGFuZ2VzIHRvIG9uZSBhcmUgcmVmbGVjdGVkIGJ5IHRoZSBvdGhlci4gVGhlIHNldCBkb2VzIG5vdAorICAgICAqIHN1cHBvcnQgYWRkaW5nLgorICAgICAqCisgICAgICogQHJldHVybiBhIHNldCBvZiB0aGUga2V5cy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2V0PEs+IGtleVNldCgpIHsKKyAgICAgICAgaWYgKGtleVNldCA9PSBudWxsKSB7CisgICAgICAgICAgICBrZXlTZXQgPSBuZXcgQWJzdHJhY3RTZXQ8Sz4oKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udGFpbnNLZXkob2JqZWN0KTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBJZGVudGl0eUhhc2hNYXAudGhpcy5zaXplKCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICAgICAgICAgIElkZW50aXR5SGFzaE1hcC50aGlzLmNsZWFyKCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBrZXkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRhaW5zS2V5KGtleSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIElkZW50aXR5SGFzaE1hcC50aGlzLnJlbW92ZShrZXkpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyBJdGVyYXRvcjxLPiBpdGVyYXRvcigpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBJZGVudGl0eUhhc2hNYXBJdGVyYXRvcjxLLCBLLCBWPigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTWFwRW50cnkuVHlwZTxLLCBLLCBWPigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIEsgZ2V0KE1hcEVudHJ5PEssIFY+IGVudHJ5KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW50cnkua2V5OworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgSWRlbnRpdHlIYXNoTWFwLnRoaXMpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGtleVNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29sbGVjdGlvbiBvZiB0aGUgdmFsdWVzIGNvbnRhaW5lZCBpbiB0aGlzIG1hcC4gVGhlIGNvbGxlY3Rpb24KKyAgICAgKiBpcyBiYWNrZWQgYnkgdGhpcyBtYXAgc28gY2hhbmdlcyB0byBvbmUgYXJlIHJlZmxlY3RlZCBieSB0aGUgb3RoZXIuIFRoZQorICAgICAqIGNvbGxlY3Rpb24gc3VwcG9ydHMgcmVtb3ZlLCByZW1vdmVBbGwsIHJldGFpbkFsbCBhbmQgY2xlYXIgb3BlcmF0aW9ucywKKyAgICAgKiBhbmQgaXQgZG9lcyBub3Qgc3VwcG9ydCBhZGQgb3IgYWRkQWxsIG9wZXJhdGlvbnMuCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhIGNvbGxlY3Rpb24gd2hpY2ggaXMgdGhlIHN1YmNsYXNzIG9mCisgICAgICogQWJzdHJhY3RDb2xsZWN0aW9uLiBUaGUgaXRlcmF0b3IgbWV0aG9kIG9mIHRoaXMgc3ViY2xhc3MgcmV0dXJucyBhCisgICAgICogIndyYXBwZXIgb2JqZWN0IiBvdmVyIHRoZSBpdGVyYXRvciBvZiBtYXAncyBlbnRyeVNldCgpLiBUaGUge0Bjb2RlIHNpemV9CisgICAgICogbWV0aG9kIHdyYXBzIHRoZSBtYXAncyBzaXplIG1ldGhvZCBhbmQgdGhlIHtAY29kZSBjb250YWluc30gbWV0aG9kIHdyYXBzCisgICAgICogdGhlIG1hcCdzIGNvbnRhaW5zVmFsdWUgbWV0aG9kLgorICAgICAqIDxwPgorICAgICAqIFRoZSBjb2xsZWN0aW9uIGlzIGNyZWF0ZWQgd2hlbiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgZm9yIHRoZSBmaXJzdCB0aW1lCisgICAgICogYW5kIHJldHVybmVkIGluIHJlc3BvbnNlIHRvIGFsbCBzdWJzZXF1ZW50IGNhbGxzLiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuCisgICAgICogZGlmZmVyZW50IGNvbGxlY3Rpb25zIHdoZW4gbXVsdGlwbGUgY29uY3VycmVudCBjYWxscyBvY2N1ciwgc2luY2Ugbm8KKyAgICAgKiBzeW5jaHJvbml6YXRpb24gaXMgcGVyZm9ybWVkLgorICAgICAqCisgICAgICogQHJldHVybiBhIGNvbGxlY3Rpb24gb2YgdGhlIHZhbHVlcyBjb250YWluZWQgaW4gdGhpcyBtYXAuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENvbGxlY3Rpb248Vj4gdmFsdWVzKCkgeworICAgICAgICBpZiAodmFsdWVzQ29sbGVjdGlvbiA9PSBudWxsKSB7CisgICAgICAgICAgICB2YWx1ZXNDb2xsZWN0aW9uID0gbmV3IEFic3RyYWN0Q29sbGVjdGlvbjxWPigpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250YWluc1ZhbHVlKG9iamVjdCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gSWRlbnRpdHlIYXNoTWFwLnRoaXMuc2l6ZSgpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICAgICAgICAgICAgICBJZGVudGl0eUhhc2hNYXAudGhpcy5jbGVhcigpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyBJdGVyYXRvcjxWPiBpdGVyYXRvcigpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBJZGVudGl0eUhhc2hNYXBJdGVyYXRvcjxWLCBLLCBWPigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTWFwRW50cnkuVHlwZTxWLCBLLCBWPigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIFYgZ2V0KE1hcEVudHJ5PEssIFY+IGVudHJ5KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW50cnkudmFsdWU7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCBJZGVudGl0eUhhc2hNYXAudGhpcyk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgICAgICAgICAgSXRlcmF0b3I8Pz4gaXQgPSBpdGVyYXRvcigpOworICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAob2JqZWN0ID09IGl0Lm5leHQoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0LnJlbW92ZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9OworICAgICAgICB9CisgICAgICAgIHJldHVybiB2YWx1ZXNDb2xsZWN0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoaXMgbWFwIHdpdGggb3RoZXIgb2JqZWN0cy4gVGhpcyBtYXAgaXMgZXF1YWwgdG8gYW5vdGhlciBtYXAgaXMKKyAgICAgKiBpdCByZXByZXNlbnRzIHRoZSBzYW1lIHNldCBvZiBtYXBwaW5ncy4gV2l0aCB0aGlzIG1hcCwgdHdvIG1hcHBpbmdzIGFyZQorICAgICAqIHRoZSBzYW1lIGlmIGJvdGggdGhlIGtleSBhbmQgdGhlIHZhbHVlIGFyZSBlcXVhbCBieSByZWZlcmVuY2UuIFdoZW4KKyAgICAgKiBjb21wYXJlZCB3aXRoIGEgbWFwIHRoYXQgaXMgbm90IGFuIElkZW50aXR5SGFzaE1hcCwgdGhlIGVxdWFscyBtZXRob2QgaXMKKyAgICAgKiBuZWl0aGVyIG5lY2Vzc2FyaWx5IHN5bW1ldHJpYyAoYS5lcXVhbHMoYikgaW1wbGllcyBiLmVxdWFscyhhKSkgbm9yCisgICAgICogdHJhbnNpdGl2ZSAoYS5lcXVhbHMoYikgYW5kIGIuZXF1YWxzKGMpIGltcGxpZXMgYS5lcXVhbHMoYykpLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHRvLgorICAgICAqIEByZXR1cm4gd2hldGhlciB0aGUgYXJndW1lbnQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFdlIG5lZWQgdG8gb3ZlcnJpZGUgdGhlIGVxdWFscyBtZXRob2QgaW4gQWJzdHJhY3RNYXAgYmVjYXVzZQorICAgICAgICAgKiBBYnN0cmFjdE1hcC5lcXVhbHMgd2lsbCBjYWxsICgoTWFwKSBvYmplY3QpLmVudHJ5U2V0KCkuY29udGFpbnMoKSB0bworICAgICAgICAgKiBkZXRlcm1pbmUgZXF1YWxpdHkgb2YgdGhlIGVudHJpZXMsIHNvIGl0IHdpbGwgZGVmZXIgdG8gdGhlIGFyZ3VtZW50CisgICAgICAgICAqIGZvciBjb21wYXJpc29uLCBtZWFuaW5nIHRoYXQgcmVmZXJlbmNlLWJhc2VkIGNvbXBhcmlzb24gd2lsbCBub3QgdGFrZQorICAgICAgICAgKiBwbGFjZS4gV2UgbXVzdCBlbnN1cmUgdGhhdCBhbGwgY29tcGFyaXNvbiBpcyBpbXBsZW1lbnRlZCBieSBtZXRob2RzCisgICAgICAgICAqIGluIHRoaXMgY2xhc3MgKG9yIGluIG9uZSBvZiBvdXIgaW5uZXIgY2xhc3NlcykgZm9yIHJlZmVyZW5jZS1iYXNlZAorICAgICAgICAgKiBjb21wYXJpc29uIHRvIHRha2UgcGxhY2UuCisgICAgICAgICAqLworICAgICAgICBpZiAodGhpcyA9PSBvYmplY3QpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBNYXApIHsKKyAgICAgICAgICAgIE1hcDw/LCA/PiBtYXAgPSAoTWFwKSBvYmplY3Q7CisgICAgICAgICAgICBpZiAoc2l6ZSgpICE9IG1hcC5zaXplKCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFNldDxNYXAuRW50cnk8SywgVj4+IHNldCA9IGVudHJ5U2V0KCk7CisgICAgICAgICAgICAvLyBlbnN1cmUgd2UgdXNlIHRoZSBlcXVhbHMgbWV0aG9kIG9mIHRoZSBzZXQgY3JlYXRlZCBieSAidGhpcyIKKyAgICAgICAgICAgIHJldHVybiBzZXQuZXF1YWxzKG1hcC5lbnRyeVNldCgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBJZGVudGl0eUhhc2hNYXAgd2l0aCB0aGUgc2FtZSBtYXBwaW5ncyBhbmQgc2l6ZSBhcyB0aGlzCisgICAgICogb25lLgorICAgICAqCisgICAgICogQHJldHVybiBhIHNoYWxsb3cgY29weSBvZiB0aGlzIElkZW50aXR5SGFzaE1hcC4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5DbG9uZWFibGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgSWRlbnRpdHlIYXNoTWFwPEssIFY+IGNsb25lSGFzaE1hcCA9IChJZGVudGl0eUhhc2hNYXA8SywgVj4pIHN1cGVyLmNsb25lKCk7CisgICAgICAgICAgICBjbG9uZUhhc2hNYXAuZWxlbWVudERhdGEgPSBuZXdFbGVtZW50QXJyYXkoZWxlbWVudERhdGEubGVuZ3RoKTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZWxlbWVudERhdGEsIDAsIGNsb25lSGFzaE1hcC5lbGVtZW50RGF0YSwgMCwgZWxlbWVudERhdGEubGVuZ3RoKTsKKyAgICAgICAgICAgIHJldHVybiBjbG9uZUhhc2hNYXA7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIElkZW50aXR5SGFzaE1hcCBoYXMgbm8gZWxlbWVudHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIElkZW50aXR5SGFzaE1hcCBoYXMgbm8gZWxlbWVudHMsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNzaXplKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICByZXR1cm4gc2l6ZSA9PSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBtYXBwaW5ncyBpbiB0aGlzIElkZW50aXR5SGFzaE1hcC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBtYXBwaW5ncyBpbiB0aGlzIElkZW50aXR5SGFzaE1hcC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgIHJldHVybiBzaXplOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdHJlYW0uZGVmYXVsdFdyaXRlT2JqZWN0KCk7CisgICAgICAgIHN0cmVhbS53cml0ZUludChzaXplKTsKKyAgICAgICAgSXRlcmF0b3I8Pz4gaXRlcmF0b3IgPSBlbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIE1hcEVudHJ5PD8sID8+IGVudHJ5ID0gKE1hcEVudHJ5KSBpdGVyYXRvci5uZXh0KCk7CisgICAgICAgICAgICBzdHJlYW0ud3JpdGVPYmplY3QoZW50cnkua2V5KTsKKyAgICAgICAgICAgIHN0cmVhbS53cml0ZU9iamVjdChlbnRyeS52YWx1ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBzdHJlYW0uZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgaW50IHNhdmVkU2l6ZSA9IHN0cmVhbS5yZWFkSW50KCk7CisgICAgICAgIHRocmVzaG9sZCA9IGdldFRocmVzaG9sZChERUZBVUxUX01BWF9TSVpFKTsKKyAgICAgICAgZWxlbWVudERhdGEgPSBuZXdFbGVtZW50QXJyYXkoY29tcHV0ZUVsZW1lbnRBcnJheVNpemUoKSk7CisgICAgICAgIGZvciAoaW50IGkgPSBzYXZlZFNpemU7IC0taSA+PSAwOykgeworICAgICAgICAgICAgSyBrZXkgPSAoSykgc3RyZWFtLnJlYWRPYmplY3QoKTsKKyAgICAgICAgICAgIHB1dChrZXksIChWKSBzdHJlYW0ucmVhZE9iamVjdCgpKTsKKyAgICAgICAgfQorICAgICAgICBzaXplID0gc2F2ZWRTaXplOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwdXRBbGxJbXBsKE1hcDw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+IG1hcCkgeworICAgICAgICBpZiAobWFwLmVudHJ5U2V0KCkgIT0gbnVsbCkgeworICAgICAgICAgICAgc3VwZXIucHV0QWxsKG1hcCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0lsbGVnYWxGb3JtYXRDb2RlUG9pbnRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvSWxsZWdhbEZvcm1hdENvZGVQb2ludEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRkZGVkODgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0lsbGVnYWxGb3JtYXRDb2RlUG9pbnRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDU4IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCisvKioKKyAqIEFuIHtAY29kZSBJbGxlZ2FsRm9ybWF0Q29kZVBvaW50RXhjZXB0aW9ufSB3aWxsIGJlIHRocm93biBpZiBhbiBpbnZhbGlkCisgKiBVbmljb2RlIGNvZGUgcG9pbnQgKGRlZmluZWQgYnkge0BsaW5rIENoYXJhY3RlciNpc1ZhbGlkQ29kZVBvaW50KGludCl9KSBpcworICogcGFzc2VkIGFzIGEgcGFyYW1ldGVyIHRvIGEgRm9ybWF0dGVyLgorICoKKyAqIEBzZWUgamF2YS5sYW5nLlJ1bnRpbWVFeGNlcHRpb24KKyAqLworcHVibGljIGNsYXNzIElsbGVnYWxGb3JtYXRDb2RlUG9pbnRFeGNlcHRpb24gZXh0ZW5kcyBJbGxlZ2FsRm9ybWF0RXhjZXB0aW9uCisgICAgICAgIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxOTA4MDYzMEw7CisKKyAgICBwcml2YXRlIGZpbmFsIGludCBjOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSWxsZWdhbEZvcm1hdENvZGVQb2ludEV4Y2VwdGlvbn0gd2hpY2ggaXMKKyAgICAgKiBzcGVjaWZpZWQgYnkgdGhlIGludmFsaWQgVW5pY29kZSBjb2RlIHBvaW50LgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgdGhlIGludmFsaWQgVW5pY29kZSBjb2RlIHBvaW50LgorICAgICAqLworICAgIHB1YmxpYyBJbGxlZ2FsRm9ybWF0Q29kZVBvaW50RXhjZXB0aW9uKGludCBjKSB7CisgICAgICAgIHRoaXMuYyA9IGM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW52YWxpZCBVbmljb2RlIGNvZGUgcG9pbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbnZhbGlkIFVuaWNvZGUgY29kZSBwb2ludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldENvZGVQb2ludCgpIHsKKyAgICAgICAgcmV0dXJuIGM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkgeworICAgICAgICByZXR1cm4gSW50ZWdlci50b0hleFN0cmluZyhjKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0lsbGVnYWxGb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0lsbGVnYWxGb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzFjMGVlZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvSWxsZWdhbEZvcm1hdENvbnZlcnNpb25FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDc2IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCisvKioKKyAqIEFuIHtAY29kZSBJbGxlZ2FsRm9ybWF0Q29udmVyc2lvbkV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gd2hlbiB0aGUgcGFyYW1ldGVyCisgKiBpcyBpbmNvbXBhdGlibGUgd2l0aCB0aGUgY29ycmVzcG9uZGluZyBmb3JtYXQgc3BlY2lmaWVyLgorICoKKyAqIEBzZWUgamF2YS5sYW5nLlJ1bnRpbWVFeGNlcHRpb24KKyAqCisgKiBAc2luY2UgMS41CisgKi8KK3B1YmxpYyBjbGFzcyBJbGxlZ2FsRm9ybWF0Q29udmVyc2lvbkV4Y2VwdGlvbiBleHRlbmRzIElsbGVnYWxGb3JtYXRFeGNlcHRpb24KKyAgICAgICAgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDE3MDAwMTI2TDsKKworICAgIHByaXZhdGUgZmluYWwgY2hhciBjOworCisgICAgcHJpdmF0ZSBmaW5hbCBDbGFzczw/PiBhcmc7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJbGxlZ2FsRm9ybWF0Q29udmVyc2lvbkV4Y2VwdGlvbn0gd2l0aCB0aGUgY2xhc3MKKyAgICAgKiBvZiB0aGUgbWlzbWF0Y2hlZCBjb252ZXJzaW9uIGFuZCBjb3JyZXNwb25kaW5nIHBhcmFtZXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgIHRoZSBjbGFzcyBvZiB0aGUgbWlzbWF0Y2hlZCBjb252ZXJzaW9uLgorICAgICAqIEBwYXJhbSBhcmcKKyAgICAgKiAgICAgICAgICAgdGhlIGNvcnJlc3BvbmRpbmcgcGFyYW1ldGVyLgorICAgICAqLworICAgIHB1YmxpYyBJbGxlZ2FsRm9ybWF0Q29udmVyc2lvbkV4Y2VwdGlvbihjaGFyIGMsIENsYXNzPD8+IGFyZykgeworICAgICAgICB0aGlzLmMgPSBjOworICAgICAgICBpZiAoYXJnID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMuYXJnID0gYXJnOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNsYXNzIG9mIHRoZSBtaXNtYXRjaGVkIHBhcmFtZXRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNsYXNzIG9mIHRoZSBtaXNtYXRjaGVkIHBhcmFtZXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xhc3M8Pz4gZ2V0QXJndW1lbnRDbGFzcygpIHsKKyAgICAgICAgcmV0dXJuIGFyZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmNvbXBhdGlibGUgY29udmVyc2lvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGluY29tcGF0aWJsZSBjb252ZXJzaW9uLgorICAgICAqLworICAgIHB1YmxpYyBjaGFyIGdldENvbnZlcnNpb24oKSB7CisgICAgICAgIHJldHVybiBjOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKyAgICAgICAgcmV0dXJuICIlIiArIGMgKyAiIGNhbid0IGZvcm1hdCAiICsgYXJnLmdldE5hbWUoKSArICIgYXJndW1lbnRzIjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0lsbGVnYWxGb3JtYXRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBlMTgwOWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0lsbGVnYWxGb3JtYXRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDM3IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBqYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworLyoqCisgKiBBbiB7QGNvZGUgSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbn0gaXMgdGhyb3duIHdoZW4gYSBmb3JtYXQgc3RyaW5nIHRoYXQKKyAqIGNvbnRhaW5zIGVpdGhlciBhbiBpbGxlZ2FsIHN5bnRheCBvciBmb3JtYXQgc3BlY2lmaWVyIGlzIHRyYW5zZmVycmVkIGFzIGEKKyAqIHBhcmFtZXRlci4gT25seSBzdWJjbGFzc2VzIGluaGVyaXRpbmcgZXhwbGljaXRseSBmcm9tIHRoaXMgZXhjZXB0aW9uIGFyZQorICogYWxsb3dlZCB0byBiZSBpbnN0YW50aWF0ZWQuCisgKgorICogQHNlZSBqYXZhLmxhbmcuUnVudGltZUV4Y2VwdGlvbgorICovCitwdWJsaWMgY2xhc3MgSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbiBleHRlbmRzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpbXBsZW1lbnRzCisgICAgICAgIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxODgzMDgyNkw7CisKKyAgICAvLyB0aGUgY29uc3RydWN0b3IgaXMgbm90IGNhbGxhYmxlIGZyb20gb3V0c2lkZSBmcm9tIHRoZSBwYWNrYWdlCisgICAgSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbigpIHsKKyAgICAgICAgLy8gZG8gbm90aGluZworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvSWxsZWdhbEZvcm1hdEZsYWdzRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0lsbGVnYWxGb3JtYXRGbGFnc0V4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5NDc5MTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0lsbGVnYWxGb3JtYXRGbGFnc0V4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTkgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKKy8qKgorICogQW4ge0Bjb2RlIElsbGVnYWxGb3JtYXRGbGFnc0V4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGNvbWJpbmF0aW9uIG9mCisgKiB0aGUgZm9ybWF0IGZsYWdzIGlzIGlsbGVnYWwuCisgKgorICogQHNlZSBqYXZhLmxhbmcuUnVudGltZUV4Y2VwdGlvbgorICovCitwdWJsaWMgY2xhc3MgSWxsZWdhbEZvcm1hdEZsYWdzRXhjZXB0aW9uIGV4dGVuZHMgSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbiBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzkwODI0TDsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGZsYWdzOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSWxsZWdhbEZvcm1hdEZsYWdzRXhjZXB0aW9ufSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBmbGFncy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmbGFncworICAgICAqICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGZsYWdzLgorICAgICAqLworICAgIHB1YmxpYyBJbGxlZ2FsRm9ybWF0RmxhZ3NFeGNlcHRpb24oU3RyaW5nIGZsYWdzKSB7CisgICAgICAgIGlmIChmbGFncyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmZsYWdzID0gZmxhZ3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZmxhZ3MgdGhhdCBhcmUgaWxsZWdhbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGZsYWdzIHRoYXQgYXJlIGlsbGVnYWwuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRGbGFncygpIHsKKyAgICAgICAgcmV0dXJuIGZsYWdzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKyAgICAgICAgcmV0dXJuIGZsYWdzOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvSWxsZWdhbEZvcm1hdFByZWNpc2lvbkV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9JbGxlZ2FsRm9ybWF0UHJlY2lzaW9uRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDdiZTY1ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvSWxsZWdhbEZvcm1hdFByZWNpc2lvbkV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTUgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisvKioKKyAqIEFuIHtAY29kZSBJbGxlZ2FsRm9ybWF0UHJlY2lzaW9uRXhjZXB0aW9ufSB3aWxsIGJlIHRocm93biBpZiB0aGUgcHJlY2lzaW9uIGlzCisgKiBhIG5lZ2F0aXZlIG90aGVyIHRoYW4gLTEgb3IgaW4gb3RoZXIgY2FzZXMgd2hlcmUgcHJlY2lzaW9uIGlzIG5vdCBzdXBwb3J0ZWQuCisgKgorICogQHNlZSBqYXZhLmxhbmcuUnVudGltZUV4Y2VwdGlvbgorICovCisKK3B1YmxpYyBjbGFzcyBJbGxlZ2FsRm9ybWF0UHJlY2lzaW9uRXhjZXB0aW9uIGV4dGVuZHMgSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbiB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTg3MTEwMDhMOworCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgcDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIElsbGVnYWxGb3JtYXRQcmVjaXNpb25FeGNlcHRpb259IHdpdGggc3BlY2lmaWVkCisgICAgICogcHJlY2lzaW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHAKKyAgICAgKiAgICAgICAgICAgdGhlIHByZWNpc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgSWxsZWdhbEZvcm1hdFByZWNpc2lvbkV4Y2VwdGlvbihpbnQgcCkgeworICAgICAgICB0aGlzLnAgPSBwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByZWNpc2lvbiBhc3NvY2lhdGVkIHdpdGggdGhlIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByZWNpc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFByZWNpc2lvbigpIHsKKyAgICAgICAgcmV0dXJuIHA7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkgeworICAgICAgICByZXR1cm4gSW50ZWdlci50b1N0cmluZyhwKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0lsbGVnYWxGb3JtYXRXaWR0aEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9JbGxlZ2FsRm9ybWF0V2lkdGhFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iODY0MzU4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9JbGxlZ2FsRm9ybWF0V2lkdGhFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDU2IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworLyoqCisgKiBBbiB7QGNvZGUgSWxsZWdhbEZvcm1hdFdpZHRoRXhjZXB0aW9ufSB3aWxsIGJlIHRocm93biBpZiB0aGUgd2lkdGggaXMgYQorICogbmVnYXRpdmUgdmFsdWUgb3RoZXIgdGhhbiAtMSBvciBpbiBvdGhlciBjYXNlcyB3aGVyZSBhIHdpZHRoIGlzIG5vdAorICogc3VwcG9ydGVkLgorICoKKyAqIEBzZWUgamF2YS5sYW5nLlJ1bnRpbWVFeGNlcHRpb24KKyAqLworcHVibGljIGNsYXNzIElsbGVnYWxGb3JtYXRXaWR0aEV4Y2VwdGlvbiBleHRlbmRzIElsbGVnYWxGb3JtYXRFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTY2NjA5MDJMOworCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdzsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIElsbGVnYWxGb3JtYXRXaWR0aEV4Y2VwdGlvbn0gd2l0aCBzcGVjaWZpZWQKKyAgICAgKiB3aWR0aC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB3CisgICAgICogICAgICAgICAgIHRoZSB3aWR0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSWxsZWdhbEZvcm1hdFdpZHRoRXhjZXB0aW9uKGludCB3KSB7CisgICAgICAgIHRoaXMudyA9IHc7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgd2lkdGggYXNzb2NpYXRlZCB3aXRoIHRoZSBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB3aWR0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFdpZHRoKCkgeworICAgICAgICByZXR1cm4gdzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2UoKSB7CisgICAgICAgIHJldHVybiBJbnRlZ2VyLnRvU3RyaW5nKHcpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvSW5wdXRNaXNtYXRjaEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9JbnB1dE1pc21hdGNoRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2FhN2QzMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvSW5wdXRNaXNtYXRjaEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTAgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCisvKioKKyAqIEFuIHtAY29kZSBJbnB1dE1pc21hdGNoRXhjZXB0aW9ufSBpcyB0aHJvd24gYnkgYSBzY2FubmVyIHRvIGluZGljYXRlIHRoYXQgdGhlCisgKiBuZXh0IHRva2VuIGRvZXMgbm90IG1hdGNoIG9yIGlzIG91dCBvZiByYW5nZSBmb3IgdGhlIHR5cGUgc3BlY2lmaWVkIGluIHRoZQorICogcGF0dGVybi4KKyAqCisgKiBAc2VlIFNjYW5uZXIKKyAqIEBzZWUgamF2YS5sYW5nLlJ1bnRpbWVFeGNlcHRpb24KKyAqLworcHVibGljIGNsYXNzIElucHV0TWlzbWF0Y2hFeGNlcHRpb24gZXh0ZW5kcyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGltcGxlbWVudHMKKyAgICAgICAgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDg4MTEyMzA3NjA5OTcwNjY0MjhMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSW5wdXRNaXNtYXRjaEV4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudCBzdGFjaworICAgICAqIHRyYWNlIGZpbGxlZCBpbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRNaXNtYXRjaEV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJbnB1dE1pc21hdGNoRXhjZXB0aW9ufSB3aXRoIHRoZSBzdGFjayB0cmFjZQorICAgICAqIGZpbGxlZCBpbiBhbmQge0Bjb2RlIG1zZ30gYXMgaXRzIGVycm9yIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgIHRoZSBzcGVjaWZpZWQgZXJyb3IgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRNaXNtYXRjaEV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9JbnZhbGlkUHJvcGVydGllc0Zvcm1hdEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9JbnZhbGlkUHJvcGVydGllc0Zvcm1hdEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhMDA0ZDUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0ludmFsaWRQcm9wZXJ0aWVzRm9ybWF0RXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw2OSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworCitwYWNrYWdlIGphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5Ob3RTZXJpYWxpemFibGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKKworLyoqCisgKiBBbiB7QGNvZGUgSW52YWxpZFByb3BlcnRpZXNGb3JtYXRFeGNlcHRpb259IGlzIHRocm93biBpZiBsb2FkaW5nIHRoZSBYTUwKKyAqIGRvY3VtZW50IGRlZmluaW5nIHRoZSBwcm9wZXJ0aWVzIGRvZXMgbm90IGZvbGxvdyB0aGUge0Bjb2RlIFByb3BlcnRpZXN9CisgKiBzcGVjaWZpY2F0aW9uLgorICoKKyAqIEV2ZW4gdGhvdWdoIHRoaXMgRXhjZXB0aW9uIGluaGVyaXRzIHRoZSB7QGNvZGUgU2VyaWFsaXphYmxlfSBpbnRlcmZhY2UsIGl0IGlzIG5vdAorICogc2VyaWFsaXphYmxlLiBUaGUgbWV0aG9kcyB1c2VkIGZvciBzZXJpYWxpemF0aW9uIHRocm93CisgKiB7QGNvZGUgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9ufXMuCisgKi8KK3B1YmxpYyBjbGFzcyBJbnZhbGlkUHJvcGVydGllc0Zvcm1hdEV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDc3NjMwNTYwNzYwMDkzNjAyMTlMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSW52YWxpZFByb3BlcnRpZXNGb3JtYXRFeGNlcHRpb259IHdpdGggdGhlCisgICAgICogY3VycmVudCBzdGFjayB0cmFjZSBhbmQgbWVzc2FnZSBmaWxsZWQgaW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbQorICAgICAqICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIEludmFsaWRQcm9wZXJ0aWVzRm9ybWF0RXhjZXB0aW9uKFN0cmluZyBtKSB7CisgICAgICAgIHN1cGVyKG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEludmFsaWRQcm9wZXJ0aWVzRm9ybWF0RXhjZXB0aW9ufSB3aXRoIHRoZSBjYXVzZQorICAgICAqIGZvciB0aGUgRXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgdGhlIGNhdXNlIGZvciB0aGUgRXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBJbnZhbGlkUHJvcGVydGllc0Zvcm1hdEV4Y2VwdGlvbihUaHJvd2FibGUgYykgeworICAgICAgICBpbml0Q2F1c2UoYyk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBvdXQpCisgICAgICAgICAgICB0aHJvd3MgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9ueworICAgICAgICB0aHJvdyBuZXcgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gaW4pCisgICAgICAgICAgICB0aHJvd3MgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9ueworICAgICAgICB0aHJvdyBuZXcgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9JdGVyYXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9JdGVyYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNiZTYxZDIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0l0ZXJhdG9yLmphdmEKQEAgLTAsMCArMSw2NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKKy8qKgorICogQW4gaXRlcmF0b3Igb3ZlciBhIHNlcXVlbmNlIG9mIG9iamVjdHMsIHN1Y2ggYXMgYSBjb2xsZWN0aW9uLgorICoKKyAqIDxwPklmIGEgY29sbGVjdGlvbiBoYXMgYmVlbiBjaGFuZ2VkIHNpbmNlIHRoZSBpdGVyYXRvciB3YXMgY3JlYXRlZCwKKyAqIG1ldGhvZHMge0Bjb2RlIG5leHR9IGFuZCB7QGNvZGUgaGFzTmV4dCgpfSBtYXkgdGhyb3cgYSB7QGNvZGUgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0uCisgKiBJdCBpcyBub3QgcG9zc2libGUgdG8gZ3VhcmFudGVlIHRoYXQgdGhpcyBtZWNoYW5pc20gd29ya3MgaW4gYWxsIGNhc2VzIG9mIHVuc3luY2hyb25pemVkCisgKiBjb25jdXJyZW50IG1vZGlmaWNhdGlvbi4gSXQgc2hvdWxkIG9ubHkgYmUgdXNlZCBmb3IgZGVidWdnaW5nIHB1cnBvc2VzLiBJdGVyYXRvcnMgd2l0aCB0aGlzCisgKiBiZWhhdmlvciBhcmUgY2FsbGVkIGZhaWwtZmFzdCBpdGVyYXRvcnMuCisgKgorICogPHA+SW1wbGVtZW50aW5nIHtAbGluayBJdGVyYWJsZX0gYW5kIHJldHVybmluZyBhbiB7QGNvZGUgSXRlcmF0b3J9IGFsbG93cyB5b3VyCisgKiBjbGFzcyB0byBiZSB1c2VkIGFzIGEgY29sbGVjdGlvbiB3aXRoIHRoZSBlbmhhbmNlZCBmb3IgbG9vcC4KKyAqCisgKiBAcGFyYW0gPEU+CisgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIG9iamVjdCByZXR1cm5lZCBieSB0aGUgaXRlcmF0b3IuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSXRlcmF0b3I8RT4geworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgbW9yZSBlbGVtZW50LCBmYWxzZSBvdGhlcndpc2UuCisgICAgICogQHNlZSAjbmV4dAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgb2JqZWN0IGFuZCBhZHZhbmNlcyB0aGUgaXRlcmF0b3IuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBhcmUgbm8gbW9yZSBlbGVtZW50cy4KKyAgICAgKiBAc2VlICNoYXNOZXh0CisgICAgICovCisgICAgcHVibGljIEUgbmV4dCgpOworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgbGFzdCBvYmplY3QgcmV0dXJuZWQgYnkge0Bjb2RlIG5leHR9IGZyb20gdGhlIGNvbGxlY3Rpb24uCisgICAgICogVGhpcyBtZXRob2QgY2FuIG9ubHkgYmUgY2FsbGVkIG9uY2UgYmV0d2VlbiBlYWNoIGNhbGwgdG8ge0Bjb2RlIG5leHR9LgorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHJlbW92aW5nIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIGNvbGxlY3Rpb24gYmVpbmcKKyAgICAgKiAgICAgICAgICAgICBpdGVyYXRlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBuZXh0fSBoYXMgbm90IGJlZW4gY2FsbGVkLCBvciB7QGNvZGUgcmVtb3ZlfSBoYXMKKyAgICAgKiAgICAgICAgICAgICBhbHJlYWR5IGJlZW4gY2FsbGVkIGFmdGVyIHRoZSBsYXN0IGNhbGwgdG8ge0Bjb2RlIG5leHR9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9MaW5rZWRIYXNoTWFwLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0xpbmtlZEhhc2hNYXAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOGZjMDJkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9MaW5rZWRIYXNoTWFwLmphdmEKQEAgLTAsMCArMSwzOTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworLyoqCisgKiBMaW5rZWRIYXNoTWFwIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIHtAbGluayBNYXB9IHRoYXQgZ3VhcmFudGVlcyBpdGVyYXRpb24gb3JkZXIuCisgKiBBbGwgb3B0aW9uYWwgb3BlcmF0aW9ucyBhcmUgc3VwcG9ydGVkLgorICoKKyAqIDxwPkFsbCBlbGVtZW50cyBhcmUgcGVybWl0dGVkIGFzIGtleXMgb3IgdmFsdWVzLCBpbmNsdWRpbmcgbnVsbC4KKyAqCisgKiA8cD5FbnRyaWVzIGFyZSBrZXB0IGluIGEgZG91Ymx5LWxpbmtlZCBsaXN0LiBUaGUgaXRlcmF0aW9uIG9yZGVyIGlzLCBieSBkZWZhdWx0LCB0aGUKKyAqIG9yZGVyIGluIHdoaWNoIGtleXMgd2VyZSBpbnNlcnRlZC4gUmVpbnNlcnRpbmcgYW4gYWxyZWFkeS1wcmVzZW50IGtleSBkb2Vzbid0IGNoYW5nZSB0aGUKKyAqIG9yZGVyLiBJZiB0aGUgdGhyZWUgYXJndW1lbnQgY29uc3RydWN0b3IgaXMgdXNlZCwgYW5kIHtAY29kZSBhY2Nlc3NPcmRlcn0gaXMgc3BlY2lmaWVkIGFzCisgKiB7QGNvZGUgdHJ1ZX0sIHRoZSBpdGVyYXRpb24gd2lsbCBiZSBpbiB0aGUgb3JkZXIgdGhhdCBlbnRyaWVzIHdlcmUgYWNjZXNzZWQuCisgKiBUaGUgYWNjZXNzIG9yZGVyIGlzIGFmZmVjdGVkIGJ5IHtAY29kZSBwdXR9LCB7QGNvZGUgZ2V0fSwgYW5kIHtAY29kZSBwdXRBbGx9IG9wZXJhdGlvbnMsCisgKiBidXQgbm90IGJ5IG9wZXJhdGlvbnMgb24gdGhlIGNvbGxlY3Rpb24gdmlld3MuCisgKgorICogPHA+Tm90ZTogdGhlIGltcGxlbWVudGF0aW9uIG9mIHtAY29kZSBMaW5rZWRIYXNoTWFwfSBpcyBub3Qgc3luY2hyb25pemVkLgorICogSWYgb25lIHRocmVhZCBvZiBzZXZlcmFsIHRocmVhZHMgYWNjZXNzaW5nIGFuIGluc3RhbmNlIG1vZGlmaWVzIHRoZSBtYXAKKyAqIHN0cnVjdHVyYWxseSwgYWNjZXNzIHRvIHRoZSBtYXAgbmVlZHMgdG8gYmUgc3luY2hyb25pemVkLiBGb3IKKyAqIGluc2VydGlvbi1vcmRlcmVkIGluc3RhbmNlcyBhIHN0cnVjdHVyYWwgbW9kaWZpY2F0aW9uIGlzIGFuIG9wZXJhdGlvbiB0aGF0CisgKiByZW1vdmVzIG9yIGFkZHMgYW4gZW50cnkuIEFjY2Vzcy1vcmRlcmVkIGluc3RhbmNlcyBhbHNvIGFyZSBzdHJ1Y3R1cmFsbHkKKyAqIG1vZGlmaWVkIGJ5IHtAY29kZSBwdXR9LCB7QGNvZGUgZ2V0fSwgYW5kIHtAY29kZSBwdXRBbGx9IHNpbmNlIHRoZXNlIG1ldGhvZHMKKyAqIGNoYW5nZSB0aGUgb3JkZXIgb2YgdGhlIGVudHJpZXMuIENoYW5nZXMgaW4gdGhlIHZhbHVlIG9mIGFuIGVudHJ5IGFyZSBub3Qgc3RydWN0dXJhbCBjaGFuZ2VzLgorICoKKyAqIDxwPlRoZSB7QGNvZGUgSXRlcmF0b3J9IGNyZWF0ZWQgYnkgY2FsbGluZyB0aGUge0Bjb2RlIGl0ZXJhdG9yfSBtZXRob2QKKyAqIG1heSB0aHJvdyBhIHtAY29kZSBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9ufSBpZiB0aGUgbWFwIGlzIHN0cnVjdHVyYWxseQorICogY2hhbmdlZCB3aGlsZSBhbiBpdGVyYXRvciBpcyB1c2VkIHRvIGl0ZXJhdGUgb3ZlciB0aGUgZWxlbWVudHMuIE9ubHkgdGhlCisgKiB7QGNvZGUgcmVtb3ZlfSBtZXRob2QgdGhhdCBpcyBwcm92aWRlZCBieSB0aGUgaXRlcmF0b3IgYWxsb3dzIGZvciByZW1vdmFsIG9mCisgKiBlbGVtZW50cyBkdXJpbmcgaXRlcmF0aW9uLiBJdCBpcyBub3QgcG9zc2libGUgdG8gZ3VhcmFudGVlIHRoYXQgdGhpcworICogbWVjaGFuaXNtIHdvcmtzIGluIGFsbCBjYXNlcyBvZiB1bnN5bmNocm9uaXplZCBjb25jdXJyZW50IG1vZGlmaWNhdGlvbi4gSXQKKyAqIHNob3VsZCBvbmx5IGJlIHVzZWQgZm9yIGRlYnVnZ2luZyBwdXJwb3Nlcy4KKyAqLworcHVibGljIGNsYXNzIExpbmtlZEhhc2hNYXA8SywgVj4gZXh0ZW5kcyBIYXNoTWFwPEssIFY+IHsKKworICAgIC8qKgorICAgICAqIEEgZHVtbXkgZW50cnkgaW4gdGhlIGNpcmN1bGFyIGxpbmtlZCBsaXN0IG9mIGVudHJpZXMgaW4gdGhlIG1hcC4KKyAgICAgKiBUaGUgZmlyc3QgcmVhbCBlbnRyeSBpcyBoZWFkZXIubnh0LCBhbmQgdGhlIGxhc3QgaXMgaGVhZGVyLnBydi4KKyAgICAgKiBJZiB0aGUgbWFwIGlzIGVtcHR5LCBoZWFkZXIubnh0ID09IGhlYWRlciAmJiBoZWFkZXIucHJ2ID09IGhlYWRlci4KKyAgICAgKi8KKyAgICB0cmFuc2llbnQgTGlua2VkRW50cnk8SywgVj4gaGVhZGVyOworCisgICAgLyoqCisgICAgICogVHJ1ZSBpZiBhY2Nlc3Mgb3JkZXJlZCwgZmFsc2UgaWYgaW5zZXJ0aW9uIG9yZGVyZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGFjY2Vzc09yZGVyOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBlbXB0eSB7QGNvZGUgTGlua2VkSGFzaE1hcH0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIExpbmtlZEhhc2hNYXAoKSB7CisgICAgICAgIGluaXQoKTsKKyAgICAgICAgYWNjZXNzT3JkZXIgPSBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBMaW5rZWRIYXNoTWFwfSBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjYXBhY2l0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbml0aWFsQ2FwYWNpdHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIGNhcGFjaXR5IG9mIHRoaXMgbWFwLgorICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgd2hlbiB0aGUgY2FwYWNpdHkgaXMgbGVzcyB0aGFuIHplcm8uCisgICAgICovCisgICAgcHVibGljIExpbmtlZEhhc2hNYXAoaW50IGluaXRpYWxDYXBhY2l0eSkgeworICAgICAgICB0aGlzKGluaXRpYWxDYXBhY2l0eSwgREVGQVVMVF9MT0FEX0ZBQ1RPUik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTGlua2VkSGFzaE1hcH0gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogY2FwYWNpdHkgYW5kIGxvYWQgZmFjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGluaXRpYWxDYXBhY2l0eQorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgY2FwYWNpdHkgb2YgdGhpcyBtYXAuCisgICAgICogQHBhcmFtIGxvYWRGYWN0b3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIGxvYWQgZmFjdG9yLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiB0aGUgY2FwYWNpdHkgaXMgbGVzcyB0aGFuIHplcm8gb3IgdGhlIGxvYWQgZmFjdG9yIGlzCisgICAgICogICAgICAgICAgICAgbGVzcyBvciBlcXVhbCB0byB6ZXJvLgorICAgICAqLworICAgIHB1YmxpYyBMaW5rZWRIYXNoTWFwKGludCBpbml0aWFsQ2FwYWNpdHksIGZsb2F0IGxvYWRGYWN0b3IpIHsKKyAgICAgICAgdGhpcyhpbml0aWFsQ2FwYWNpdHksIGxvYWRGYWN0b3IsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBMaW5rZWRIYXNoTWFwfSBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjYXBhY2l0eSwgbG9hZCBmYWN0b3IgYW5kIGEgZmxhZyBzcGVjaWZ5aW5nIHRoZSBvcmRlcmluZyBiZWhhdmlvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbml0aWFsQ2FwYWNpdHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIGNhcGFjaXR5IG9mIHRoaXMgaGFzaCBtYXAuCisgICAgICogQHBhcmFtIGxvYWRGYWN0b3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIGxvYWQgZmFjdG9yLgorICAgICAqIEBwYXJhbSBhY2Nlc3NPcmRlcgorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGlmIHRoZSBvcmRlcmluZyBzaG91bGQgYmUgZG9uZSBiYXNlZCBvbiB0aGUgbGFzdAorICAgICAqICAgICAgICAgICAgYWNjZXNzIChmcm9tIGxlYXN0LXJlY2VudGx5IGFjY2Vzc2VkIHRvIG1vc3QtcmVjZW50bHkKKyAgICAgKiAgICAgICAgICAgIGFjY2Vzc2VkKSwgYW5kIHtAY29kZSBmYWxzZX0gaWYgdGhlIG9yZGVyaW5nIHNob3VsZCBiZSB0aGUKKyAgICAgKiAgICAgICAgICAgIG9yZGVyIGluIHdoaWNoIHRoZSBlbnRyaWVzIHdlcmUgaW5zZXJ0ZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHRoZSBjYXBhY2l0eSBpcyBsZXNzIHRoYW4gemVybyBvciB0aGUgbG9hZCBmYWN0b3IgaXMKKyAgICAgKiAgICAgICAgICAgICBsZXNzIG9yIGVxdWFsIHRvIHplcm8uCisgICAgICovCisgICAgcHVibGljIExpbmtlZEhhc2hNYXAoCisgICAgICAgICAgICBpbnQgaW5pdGlhbENhcGFjaXR5LCBmbG9hdCBsb2FkRmFjdG9yLCBib29sZWFuIGFjY2Vzc09yZGVyKSB7CisgICAgICAgIHN1cGVyKGluaXRpYWxDYXBhY2l0eSwgbG9hZEZhY3Rvcik7CisgICAgICAgIGluaXQoKTsKKyAgICAgICAgdGhpcy5hY2Nlc3NPcmRlciA9IGFjY2Vzc09yZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIExpbmtlZEhhc2hNYXB9IGluc3RhbmNlIGNvbnRhaW5pbmcgdGhlIG1hcHBpbmdzCisgICAgICogZnJvbSB0aGUgc3BlY2lmaWVkIG1hcC4gVGhlIG9yZGVyIG9mIHRoZSBlbGVtZW50cyBpcyBwcmVzZXJ2ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWFwCisgICAgICogICAgICAgICAgICB0aGUgbWFwcGluZ3MgdG8gYWRkLgorICAgICAqLworICAgIHB1YmxpYyBMaW5rZWRIYXNoTWFwKE1hcDw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+IG1hcCkgeworICAgICAgICB0aGlzKGNhcGFjaXR5Rm9ySW5pdFNpemUobWFwLnNpemUoKSkpOworICAgICAgICBjb25zdHJ1Y3RvclB1dEFsbChtYXApOworICAgIH0KKworICAgIEBPdmVycmlkZSB2b2lkIGluaXQoKSB7CisgICAgICAgIGhlYWRlciA9IG5ldyBMaW5rZWRFbnRyeTxLLCBWPigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExpbmtlZEVudHJ5IGFkZHMgbnh0L3BydiBkb3VibGUtbGlua3MgdG8gcGxhaW4gSGFzaE1hcEVudHJ5LgorICAgICAqLworICAgIHN0YXRpYyBjbGFzcyBMaW5rZWRFbnRyeTxLLCBWPiBleHRlbmRzIEhhc2hNYXBFbnRyeTxLLCBWPiB7CisgICAgICAgIExpbmtlZEVudHJ5PEssIFY+IG54dDsKKyAgICAgICAgTGlua2VkRW50cnk8SywgVj4gcHJ2OworCisgICAgICAgIC8qKiBDcmVhdGUgdGhlIGhlYWRlciBlbnRyeSAqLworICAgICAgICBMaW5rZWRFbnRyeSgpIHsKKyAgICAgICAgICAgIHN1cGVyKG51bGwsIG51bGwsIDAsIG51bGwpOworICAgICAgICAgICAgbnh0ID0gcHJ2ID0gdGhpczsKKyAgICAgICAgfQorCisgICAgICAgIC8qKiBDcmVhdGUgYSBub3JtYWwgZW50cnkgKi8KKyAgICAgICAgTGlua2VkRW50cnkoSyBrZXksIFYgdmFsdWUsIGludCBoYXNoLCBIYXNoTWFwRW50cnk8SywgVj4gbmV4dCwKKyAgICAgICAgICAgICAgICAgICAgTGlua2VkRW50cnk8SywgVj4gbnh0LCBMaW5rZWRFbnRyeTxLLCBWPiBwcnYpIHsKKyAgICAgICAgICAgIHN1cGVyKGtleSwgdmFsdWUsIGhhc2gsIG5leHQpOworICAgICAgICAgICAgdGhpcy5ueHQgPSBueHQ7CisgICAgICAgICAgICB0aGlzLnBydiA9IHBydjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGVsZGVzdCBlbnRyeSBpbiB0aGUgbWFwLCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIG1hcCBpcyBlbXB0eS4KKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIHB1YmxpYyBFbnRyeTxLLCBWPiBlbGRlc3QoKSB7CisgICAgICAgIExpbmtlZEVudHJ5PEssIFY+IGVsZGVzdCA9IGhlYWRlci5ueHQ7CisgICAgICAgIHJldHVybiBlbGRlc3QgIT0gaGVhZGVyID8gZWxkZXN0IDogbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFdmljdHMgZWxkZXN0IGVudHJ5IGlmIGluc3RydWN0ZWQsIGNyZWF0ZXMgYSBuZXcgZW50cnkgYW5kIGxpbmtzIGl0IGluCisgICAgICogYXMgaGVhZCBvZiBsaW5rZWQgbGlzdC4gVGhpcyBtZXRob2Qgc2hvdWxkIGNhbGwgY29uc3RydWN0b3JOZXdFbnRyeQorICAgICAqIChpbnN0ZWFkIG9mIGR1cGxpY2F0aW5nIGNvZGUpIGlmIHRoZSBwZXJmb3JtYW5jZSBvZiB5b3VyIFZNIHBlcm1pdHMuCisgICAgICoKKyAgICAgKiA8cD5JdCBtYXkgc2VlbSBzdHJhbmdlIHRoYXQgdGhpcyBtZXRob2QgaXMgdGFza2VkIHdpdGggYWRkaW5nIHRoZSBlbnRyeQorICAgICAqIHRvIHRoZSBoYXNoIHRhYmxlICh3aGljaCBpcyBwcm9wZXJseSB0aGUgcHJvdmluY2Ugb2Ygb3VyIHN1cGVyY2xhc3MpLgorICAgICAqIFRoZSBhbHRlcm5hdGl2ZSBvZiBwYXNzaW5nIHRoZSAibmV4dCIgbGluayBpbiB0byB0aGlzIG1ldGhvZCBhbmQKKyAgICAgKiByZXR1cm5pbmcgdGhlIG5ld2x5IGNyZWF0ZWQgZWxlbWVudCBkb2VzIG5vdCB3b3JrISBJZiB3ZSByZW1vdmUgYW4KKyAgICAgKiAoZWxkZXN0KSBlbnRyeSB0aGF0IGhhcHBlbnMgdG8gYmUgdGhlIGZpcnN0IGVudHJ5IGluIHRoZSBzYW1lIGJ1Y2tldAorICAgICAqIGFzIHRoZSBuZXdseSBjcmVhdGVkIGVudHJ5LCB0aGUgIm5leHQiIGxpbmsgd291bGQgYmVjb21lIGludmFsaWQsIGFuZAorICAgICAqIHRoZSByZXN1bHRpbmcgaGFzaCB0YWJsZSBjb3JydXB0LgorICAgICAqLworICAgIEBPdmVycmlkZSB2b2lkIGFkZE5ld0VudHJ5KEsga2V5LCBWIHZhbHVlLCBpbnQgaGFzaCwgaW50IGluZGV4KSB7CisgICAgICAgIExpbmtlZEVudHJ5PEssIFY+IGhlYWRlciA9IHRoaXMuaGVhZGVyOworCisgICAgICAgIC8vIFJlbW92ZSBlbGRlc3QgZW50cnkgaWYgaW5zdHJ1Y3RlZCB0byBkbyBzby4KKyAgICAgICAgTGlua2VkRW50cnk8SywgVj4gZWxkZXN0ID0gaGVhZGVyLm54dDsKKyAgICAgICAgaWYgKGVsZGVzdCAhPSBoZWFkZXIgJiYgcmVtb3ZlRWxkZXN0RW50cnkoZWxkZXN0KSkgeworICAgICAgICAgICAgcmVtb3ZlKGVsZGVzdC5rZXkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ3JlYXRlIG5ldyBlbnRyeSwgbGluayBpdCBvbiB0byBsaXN0LCBhbmQgcHV0IGl0IGludG8gdGFibGUKKyAgICAgICAgTGlua2VkRW50cnk8SywgVj4gb2xkVGFpbCA9IGhlYWRlci5wcnY7CisgICAgICAgIExpbmtlZEVudHJ5PEssIFY+IG5ld1RhaWwgPSBuZXcgTGlua2VkRW50cnk8SyxWPigKKyAgICAgICAgICAgICAgICBrZXksIHZhbHVlLCBoYXNoLCB0YWJsZVtpbmRleF0sIGhlYWRlciwgb2xkVGFpbCk7CisgICAgICAgIHRhYmxlW2luZGV4XSA9IG9sZFRhaWwubnh0ID0gaGVhZGVyLnBydiA9IG5ld1RhaWw7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHZvaWQgYWRkTmV3RW50cnlGb3JOdWxsS2V5KFYgdmFsdWUpIHsKKyAgICAgICAgTGlua2VkRW50cnk8SywgVj4gaGVhZGVyID0gdGhpcy5oZWFkZXI7CisKKyAgICAgICAgLy8gUmVtb3ZlIGVsZGVzdCBlbnRyeSBpZiBpbnN0cnVjdGVkIHRvIGRvIHNvLgorICAgICAgICBMaW5rZWRFbnRyeTxLLCBWPiBlbGRlc3QgPSBoZWFkZXIubnh0OworICAgICAgICBpZiAoZWxkZXN0ICE9IGhlYWRlciAmJiByZW1vdmVFbGRlc3RFbnRyeShlbGRlc3QpKSB7CisgICAgICAgICAgICByZW1vdmUoZWxkZXN0LmtleSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBDcmVhdGUgbmV3IGVudHJ5LCBsaW5rIGl0IG9uIHRvIGxpc3QsIGFuZCBwdXQgaXQgaW50byB0YWJsZQorICAgICAgICBMaW5rZWRFbnRyeTxLLCBWPiBvbGRUYWlsID0gaGVhZGVyLnBydjsKKyAgICAgICAgTGlua2VkRW50cnk8SywgVj4gbmV3VGFpbCA9IG5ldyBMaW5rZWRFbnRyeTxLLFY+KAorICAgICAgICAgICAgICAgIG51bGwsIHZhbHVlLCAwLCBudWxsLCBoZWFkZXIsIG9sZFRhaWwpOworICAgICAgICBlbnRyeUZvck51bGxLZXkgPSBvbGRUYWlsLm54dCA9IGhlYWRlci5wcnYgPSBuZXdUYWlsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFzIGFib3ZlLCBidXQgd2l0aG91dCBldmljdGlvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgSGFzaE1hcEVudHJ5PEssIFY+IGNvbnN0cnVjdG9yTmV3RW50cnkoCisgICAgICAgICAgICBLIGtleSwgViB2YWx1ZSwgaW50IGhhc2gsIEhhc2hNYXBFbnRyeTxLLCBWPiBuZXh0KSB7CisgICAgICAgIExpbmtlZEVudHJ5PEssIFY+IGhlYWRlciA9IHRoaXMuaGVhZGVyOworICAgICAgICBMaW5rZWRFbnRyeTxLLCBWPiBvbGRUYWlsID0gaGVhZGVyLnBydjsKKyAgICAgICAgTGlua2VkRW50cnk8SywgVj4gbmV3VGFpbAorICAgICAgICAgICAgICAgID0gbmV3IExpbmtlZEVudHJ5PEssVj4oa2V5LCB2YWx1ZSwgaGFzaCwgbmV4dCwgaGVhZGVyLCBvbGRUYWlsKTsKKyAgICAgICAgcmV0dXJuIG9sZFRhaWwubnh0ID0gaGVhZGVyLnBydiA9IG5ld1RhaWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIG1hcHBpbmcgd2l0aCB0aGUgc3BlY2lmaWVkIGtleS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIG1hcHBpbmcgd2l0aCB0aGUgc3BlY2lmaWVkIGtleSwgb3Ige0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpZiBubyBtYXBwaW5nIGZvciB0aGUgc3BlY2lmaWVkIGtleSBpcyBmb3VuZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIFYgZ2V0KE9iamVjdCBrZXkpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogVGhpcyBtZXRob2QgaXMgb3ZlcnJpZGRlbiB0byBlbGltaW5hdGUgdGhlIG5lZWQgZm9yIGEgcG9seW1vcnBoaWMKKyAgICAgICAgICogaW52b2NhdGlvbiBpbiBzdXBlcmNsYXNzIGF0IHRoZSBleHBlbnNlIG9mIGNvZGUgZHVwbGljYXRpb24uCisgICAgICAgICAqLworICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIEhhc2hNYXBFbnRyeTxLLCBWPiBlID0gZW50cnlGb3JOdWxsS2V5OworICAgICAgICAgICAgaWYgKGUgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIGlmIChhY2Nlc3NPcmRlcikKKyAgICAgICAgICAgICAgICBtYWtlVGFpbCgoTGlua2VkRW50cnk8SywgVj4pIGUpOworICAgICAgICAgICAgcmV0dXJuIGUudmFsdWU7CisgICAgICAgIH0KKworICAgICAgICAvLyBEb3VnIExlYSdzIHN1cHBsZW1lbnRhbCBzZWNvbmRhcnlIYXNoIGZ1bmN0aW9uIChpbmxpbmVkKQorICAgICAgICBpbnQgaGFzaCA9IGtleS5oYXNoQ29kZSgpOworICAgICAgICBoYXNoIF49IChoYXNoID4+PiAyMCkgXiAoaGFzaCA+Pj4gMTIpOworICAgICAgICBoYXNoIF49IChoYXNoID4+PiA3KSBeIChoYXNoID4+PiA0KTsKKworICAgICAgICBIYXNoTWFwRW50cnk8SywgVj5bXSB0YWIgPSB0YWJsZTsKKyAgICAgICAgZm9yIChIYXNoTWFwRW50cnk8SywgVj4gZSA9IHRhYltoYXNoICYgKHRhYi5sZW5ndGggLSAxKV07CisgICAgICAgICAgICAgICAgZSAhPSBudWxsOyBlID0gZS5uZXh0KSB7CisgICAgICAgICAgICBLIGVLZXkgPSBlLmtleTsKKyAgICAgICAgICAgIGlmIChlS2V5ID09IGtleSB8fCAoZS5oYXNoID09IGhhc2ggJiYga2V5LmVxdWFscyhlS2V5KSkpIHsKKyAgICAgICAgICAgICAgICBpZiAoYWNjZXNzT3JkZXIpCisgICAgICAgICAgICAgICAgICAgIG1ha2VUYWlsKChMaW5rZWRFbnRyeTxLLCBWPikgZSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGUudmFsdWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVsaW5rcyB0aGUgZ2l2ZW4gZW50cnkgdG8gdGhlIHRhaWwgb2YgdGhlIGxpc3QuIFVuZGVyIGFjY2VzcyBvcmRlcmluZywKKyAgICAgKiB0aGlzIG1ldGhvZCBpcyBpbnZva2VkIHdoZW5ldmVyIHRoZSB2YWx1ZSBvZiBhICBwcmUtZXhpc3RpbmcgZW50cnkgaXMKKyAgICAgKiByZWFkIGJ5IE1hcC5nZXQgb3IgbW9kaWZpZWQgYnkgTWFwLnB1dC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgbWFrZVRhaWwoTGlua2VkRW50cnk8SywgVj4gZSkgeworICAgICAgICAvLyBVbmxpbmsgZQorICAgICAgICBlLnBydi5ueHQgPSBlLm54dDsKKyAgICAgICAgZS5ueHQucHJ2ID0gZS5wcnY7CisKKyAgICAgICAgLy8gUmVsaW5rIGUgYXMgdGFpbAorICAgICAgICBMaW5rZWRFbnRyeTxLLCBWPiBoZWFkZXIgPSB0aGlzLmhlYWRlcjsKKyAgICAgICAgTGlua2VkRW50cnk8SywgVj4gb2xkVGFpbCA9IGhlYWRlci5wcnY7CisgICAgICAgIGUubnh0ID0gaGVhZGVyOworICAgICAgICBlLnBydiA9IG9sZFRhaWw7CisgICAgICAgIG9sZFRhaWwubnh0ID0gaGVhZGVyLnBydiA9IGU7CisgICAgICAgIG1vZENvdW50Kys7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHZvaWQgcHJlTW9kaWZ5KEhhc2hNYXBFbnRyeTxLLCBWPiBlKSB7CisgICAgICAgIGlmIChhY2Nlc3NPcmRlcikgeworICAgICAgICAgICAgbWFrZVRhaWwoKExpbmtlZEVudHJ5PEssIFY+KSBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSB2b2lkIHBvc3RSZW1vdmUoSGFzaE1hcEVudHJ5PEssIFY+IGUpIHsKKyAgICAgICAgTGlua2VkRW50cnk8SywgVj4gbGUgPSAoTGlua2VkRW50cnk8SywgVj4pIGU7CisgICAgICAgIGxlLnBydi5ueHQgPSBsZS5ueHQ7CisgICAgICAgIGxlLm54dC5wcnYgPSBsZS5wcnY7CisgICAgICAgIGxlLm54dCA9IGxlLnBydiA9IG51bGw7IC8vIEhlbHAgdGhlIEdDIChmb3IgcGVyZm9ybWFuY2UpCisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBvdmVycmlkZSBpcyBkb25lIGZvciBMaW5rZWRIYXNoTWFwIHBlcmZvcm1hbmNlOiBpdGVyYXRpb24gaXMgY2hlYXBlcgorICAgICAqIHZpYSBMaW5rZWRIYXNoTWFwIG54dCBsaW5rcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnNWYWx1ZShPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoTGlua2VkRW50cnk8SywgVj4gaGVhZGVyID0gdGhpcy5oZWFkZXIsIGUgPSBoZWFkZXIubnh0OworICAgICAgICAgICAgICAgICAgICBlICE9IGhlYWRlcjsgZSA9IGUubnh0KSB7CisgICAgICAgICAgICAgICAgaWYgKGUudmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICAvLyB2YWx1ZSBpcyBub24tbnVsbAorICAgICAgICBmb3IgKExpbmtlZEVudHJ5PEssIFY+IGhlYWRlciA9IHRoaXMuaGVhZGVyLCBlID0gaGVhZGVyLm54dDsKKyAgICAgICAgICAgICAgICBlICE9IGhlYWRlcjsgZSA9IGUubnh0KSB7CisgICAgICAgICAgICBpZiAodmFsdWUuZXF1YWxzKGUudmFsdWUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBzdXBlci5jbGVhcigpOworCisgICAgICAgIC8vIENsZWFyIGFsbCBsaW5rcyB0byBoZWxwIEdDCisgICAgICAgIExpbmtlZEVudHJ5PEssIFY+IGhlYWRlciA9IHRoaXMuaGVhZGVyOworICAgICAgICBmb3IgKExpbmtlZEVudHJ5PEssIFY+IGUgPSBoZWFkZXIubnh0OyBlICE9IGhlYWRlcjsgKSB7CisgICAgICAgICAgICBMaW5rZWRFbnRyeTxLLCBWPiBueHQgPSBlLm54dDsKKyAgICAgICAgICAgIGUubnh0ID0gZS5wcnYgPSBudWxsOworICAgICAgICAgICAgZSA9IG54dDsKKyAgICAgICAgfQorCisgICAgICAgIGhlYWRlci5ueHQgPSBoZWFkZXIucHJ2ID0gaGVhZGVyOworICAgIH0KKworICAgIHByaXZhdGUgYWJzdHJhY3QgY2xhc3MgTGlua2VkSGFzaEl0ZXJhdG9yPFQ+IGltcGxlbWVudHMgSXRlcmF0b3I8VD4geworICAgICAgICBMaW5rZWRFbnRyeTxLLCBWPiBuZXh0ID0gaGVhZGVyLm54dDsKKyAgICAgICAgTGlua2VkRW50cnk8SywgVj4gbGFzdFJldHVybmVkID0gbnVsbDsKKyAgICAgICAgaW50IGV4cGVjdGVkTW9kQ291bnQgPSBtb2RDb3VudDsKKworICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgcmV0dXJuIG5leHQgIT0gaGVhZGVyOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgTGlua2VkRW50cnk8SywgVj4gbmV4dEVudHJ5KCkgeworICAgICAgICAgICAgaWYgKG1vZENvdW50ICE9IGV4cGVjdGVkTW9kQ291bnQpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIExpbmtlZEVudHJ5PEssIFY+IGUgPSBuZXh0OworICAgICAgICAgICAgaWYgKGUgPT0gaGVhZGVyKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICBuZXh0ID0gZS5ueHQ7CisgICAgICAgICAgICByZXR1cm4gbGFzdFJldHVybmVkID0gZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBmaW5hbCB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgIGlmIChtb2RDb3VudCAhPSBleHBlY3RlZE1vZENvdW50KQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBpZiAobGFzdFJldHVybmVkID09IG51bGwpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgTGlua2VkSGFzaE1hcC50aGlzLnJlbW92ZShsYXN0UmV0dXJuZWQua2V5KTsKKyAgICAgICAgICAgIGxhc3RSZXR1cm5lZCA9IG51bGw7CisgICAgICAgICAgICBleHBlY3RlZE1vZENvdW50ID0gbW9kQ291bnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIGNsYXNzIEtleUl0ZXJhdG9yIGV4dGVuZHMgTGlua2VkSGFzaEl0ZXJhdG9yPEs+IHsKKyAgICAgICAgcHVibGljIGZpbmFsIEsgbmV4dCgpIHsgcmV0dXJuIG5leHRFbnRyeSgpLmtleTsgfQorICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgY2xhc3MgVmFsdWVJdGVyYXRvciBleHRlbmRzIExpbmtlZEhhc2hJdGVyYXRvcjxWPiB7CisgICAgICAgIHB1YmxpYyBmaW5hbCBWIG5leHQoKSB7IHJldHVybiBuZXh0RW50cnkoKS52YWx1ZTsgfQorICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgY2xhc3MgRW50cnlJdGVyYXRvcgorICAgICAgICAgICAgZXh0ZW5kcyBMaW5rZWRIYXNoSXRlcmF0b3I8TWFwLkVudHJ5PEssIFY+PiB7CisgICAgICAgIHB1YmxpYyBmaW5hbCBNYXAuRW50cnk8SywgVj4gbmV4dCgpIHsgcmV0dXJuIG5leHRFbnRyeSgpOyB9CisgICAgfQorCisgICAgLy8gT3ZlcnJpZGUgdmlldyBpdGVyYXRvciBtZXRob2RzIHRvIGdlbmVyYXRlIGNvcnJlY3QgaXRlcmF0aW9uIG9yZGVyCisgICAgQE92ZXJyaWRlIEl0ZXJhdG9yPEs+IG5ld0tleUl0ZXJhdG9yKCkgeworICAgICAgICByZXR1cm4gbmV3IEtleUl0ZXJhdG9yKCk7CisgICAgfQorICAgIEBPdmVycmlkZSBJdGVyYXRvcjxWPiBuZXdWYWx1ZUl0ZXJhdG9yKCkgeworICAgICAgICByZXR1cm4gbmV3IFZhbHVlSXRlcmF0b3IoKTsKKyAgICB9CisgICAgQE92ZXJyaWRlIEl0ZXJhdG9yPE1hcC5FbnRyeTxLLCBWPj4gbmV3RW50cnlJdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBFbnRyeUl0ZXJhdG9yKCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcmVtb3ZlRWxkZXN0RW50cnkoTWFwLkVudHJ5PEssIFY+IGVsZGVzdCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzgwMTEyNDI0MjgyMDIxOTEzMUw7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0xpbmtlZEhhc2hTZXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTGlua2VkSGFzaFNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE0ZmI3NWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0xpbmtlZEhhc2hTZXQuamF2YQpAQCAtMCwwICsxLDkxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCisvKioKKyAqIExpbmtlZEhhc2hTZXQgaXMgYSB2YXJpYW50IG9mIEhhc2hTZXQuIEl0cyBlbnRyaWVzIGFyZSBrZXB0IGluIGEKKyAqIGRvdWJseS1saW5rZWQgbGlzdC4gVGhlIGl0ZXJhdGlvbiBvcmRlciBpcyB0aGUgb3JkZXIgaW4gd2hpY2ggZW50cmllcyB3ZXJlCisgKiBpbnNlcnRlZC4KKyAqIDxwPgorICogTnVsbCBlbGVtZW50cyBhcmUgYWxsb3dlZCwgYW5kIGFsbCB0aGUgb3B0aW9uYWwgU2V0IG9wZXJhdGlvbnMgYXJlIHN1cHBvcnRlZC4KKyAqIDxwPgorICogTGlrZSBIYXNoU2V0LCBMaW5rZWRIYXNoU2V0IGlzIG5vdCB0aHJlYWQgc2FmZSwgc28gYWNjZXNzIGJ5IG11bHRpcGxlIHRocmVhZHMKKyAqIG11c3QgYmUgc3luY2hyb25pemVkIGJ5IGFuIGV4dGVybmFsIG1lY2hhbmlzbSBzdWNoIGFzCisgKiB7QGxpbmsgQ29sbGVjdGlvbnMjc3luY2hyb25pemVkU2V0KFNldCl9LgorICoKKyAqIEBzaW5jZSAxLjQKKyAqLworcHVibGljIGNsYXNzIExpbmtlZEhhc2hTZXQ8RT4gZXh0ZW5kcyBIYXNoU2V0PEU+IGltcGxlbWVudHMgU2V0PEU+LCBDbG9uZWFibGUsCisgICAgICAgIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjg1MTY2NzY3OTk3MTAzODY5MEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGVtcHR5IGluc3RhbmNlIG9mIHtAY29kZSBMaW5rZWRIYXNoU2V0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGlua2VkSGFzaFNldCgpIHsKKyAgICAgICAgc3VwZXIobmV3IExpbmtlZEhhc2hNYXA8RSwgSGFzaFNldDxFPj4oKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgTGlua2VkSGFzaFNldH0gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogY2FwYWNpdHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2FwYWNpdHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIGNhcGFjaXR5IG9mIHRoaXMge0Bjb2RlIExpbmtlZEhhc2hTZXR9LgorICAgICAqLworICAgIHB1YmxpYyBMaW5rZWRIYXNoU2V0KGludCBjYXBhY2l0eSkgeworICAgICAgICBzdXBlcihuZXcgTGlua2VkSGFzaE1hcDxFLCBIYXNoU2V0PEU+PihjYXBhY2l0eSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIExpbmtlZEhhc2hTZXR9IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIGNhcGFjaXR5IGFuZCBsb2FkIGZhY3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXBhY2l0eQorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgY2FwYWNpdHkuCisgICAgICogQHBhcmFtIGxvYWRGYWN0b3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIGxvYWQgZmFjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBMaW5rZWRIYXNoU2V0KGludCBjYXBhY2l0eSwgZmxvYXQgbG9hZEZhY3RvcikgeworICAgICAgICBzdXBlcihuZXcgTGlua2VkSGFzaE1hcDxFLCBIYXNoU2V0PEU+PihjYXBhY2l0eSwgbG9hZEZhY3RvcikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIExpbmtlZEhhc2hTZXR9IGNvbnRhaW5pbmcgdGhlIHVuaXF1ZQorICAgICAqIGVsZW1lbnRzIGluIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2xsZWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgY29sbGVjdGlvbiBvZiBlbGVtZW50cyB0byBhZGQuCisgICAgICovCisgICAgcHVibGljIExpbmtlZEhhc2hTZXQoQ29sbGVjdGlvbjw/IGV4dGVuZHMgRT4gY29sbGVjdGlvbikgeworICAgICAgICBzdXBlcihuZXcgTGlua2VkSGFzaE1hcDxFLCBIYXNoU2V0PEU+Pihjb2xsZWN0aW9uLnNpemUoKSA8IDYgPyAxMQorICAgICAgICAgICAgICAgIDogY29sbGVjdGlvbi5zaXplKCkgKiAyKSk7CisgICAgICAgIGZvciAoRSBlIDogY29sbGVjdGlvbikgeworICAgICAgICAgICAgYWRkKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyogb3ZlcnJpZGVzIG1ldGhvZCBpbiBIYXNoTWFwICovCisgICAgQE92ZXJyaWRlCisgICAgSGFzaE1hcDxFLCBIYXNoU2V0PEU+PiBjcmVhdGVCYWNraW5nTWFwKGludCBjYXBhY2l0eSwgZmxvYXQgbG9hZEZhY3RvcikgeworICAgICAgICByZXR1cm4gbmV3IExpbmtlZEhhc2hNYXA8RSwgSGFzaFNldDxFPj4oY2FwYWNpdHksIGxvYWRGYWN0b3IpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTGlua2VkTGlzdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9MaW5rZWRMaXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTFkYzhkOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTGlua2VkTGlzdC5qYXZhCkBAIC0wLDAgKzEsOTkxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5BcnJheTsKKworLyoqCisgKiBMaW5rZWRMaXN0IGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIHtAbGluayBMaXN0fSwgYmFja2VkIGJ5IGEgZG91Ymx5LWxpbmtlZCBsaXN0LgorICogQWxsIG9wdGlvbmFsIG9wZXJhdGlvbnMgaW5jbHVkaW5nIGFkZGluZywgcmVtb3ZpbmcsIGFuZCByZXBsYWNpbmcgZWxlbWVudHMgYXJlIHN1cHBvcnRlZC4KKyAqCisgKiA8cD5BbGwgZWxlbWVudHMgYXJlIHBlcm1pdHRlZCwgaW5jbHVkaW5nIG51bGwuCisgKgorICogPHA+VGhpcyBjbGFzcyBpcyBwcmltYXJpbHkgdXNlZnVsIGlmIHlvdSBuZWVkIHF1ZXVlLWxpa2UgYmVoYXZpb3IuIEl0IG1heSBhbHNvIGJlIHVzZWZ1bAorICogYXMgYSBsaXN0IGlmIHlvdSBleHBlY3QgeW91ciBsaXN0cyB0byBjb250YWluIHplcm8gb3Igb25lIGVsZW1lbnQsIGJ1dCBzdGlsbCByZXF1aXJlIHRoZQorICogYWJpbGl0eSB0byBzY2FsZSB0byBzbGlnaHRseSBsYXJnZXIgbnVtYmVycyBvZiBlbGVtZW50cy4gSW4gZ2VuZXJhbCwgdGhvdWdoLCB5b3Ugc2hvdWxkCisgKiBwcm9iYWJseSB1c2Uge0BsaW5rIEFycmF5TGlzdH0gaWYgeW91IGRvbid0IG5lZWQgdGhlIHF1ZXVlLWxpa2UgYmVoYXZpb3IuCisgKgorICogQHNpbmNlIDEuMgorICovCitwdWJsaWMgY2xhc3MgTGlua2VkTGlzdDxFPiBleHRlbmRzIEFic3RyYWN0U2VxdWVudGlhbExpc3Q8RT4gaW1wbGVtZW50cworICAgICAgICBMaXN0PEU+LCBEZXF1ZTxFPiwgUXVldWU8RT4sIENsb25lYWJsZSwgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDg3NjMyMzI2MjY0NTE3NjM1NEw7CisKKyAgICB0cmFuc2llbnQgaW50IHNpemUgPSAwOworCisgICAgdHJhbnNpZW50IExpbms8RT4gdm9pZExpbms7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBMaW5rPEVUPiB7CisgICAgICAgIEVUIGRhdGE7CisKKyAgICAgICAgTGluazxFVD4gcHJldmlvdXMsIG5leHQ7CisKKyAgICAgICAgTGluayhFVCBvLCBMaW5rPEVUPiBwLCBMaW5rPEVUPiBuKSB7CisgICAgICAgICAgICBkYXRhID0gbzsKKyAgICAgICAgICAgIHByZXZpb3VzID0gcDsKKyAgICAgICAgICAgIG5leHQgPSBuOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTGlua0l0ZXJhdG9yPEVUPiBpbXBsZW1lbnRzIExpc3RJdGVyYXRvcjxFVD4geworICAgICAgICBpbnQgcG9zLCBleHBlY3RlZE1vZENvdW50OworCisgICAgICAgIGZpbmFsIExpbmtlZExpc3Q8RVQ+IGxpc3Q7CisKKyAgICAgICAgTGluazxFVD4gbGluaywgbGFzdExpbms7CisKKyAgICAgICAgTGlua0l0ZXJhdG9yKExpbmtlZExpc3Q8RVQ+IG9iamVjdCwgaW50IGxvY2F0aW9uKSB7CisgICAgICAgICAgICBsaXN0ID0gb2JqZWN0OworICAgICAgICAgICAgZXhwZWN0ZWRNb2RDb3VudCA9IGxpc3QubW9kQ291bnQ7CisgICAgICAgICAgICBpZiAobG9jYXRpb24gPj0gMCAmJiBsb2NhdGlvbiA8PSBsaXN0LnNpemUpIHsKKyAgICAgICAgICAgICAgICAvLyBwb3MgZW5kcyB1cCBhcyAtMSBpZiBsaXN0IGlzIGVtcHR5LCBpdCByYW5nZXMgZnJvbSAtMSB0bworICAgICAgICAgICAgICAgIC8vIGxpc3Quc2l6ZSAtIDEKKyAgICAgICAgICAgICAgICAvLyBpZiBsaW5rID09IHZvaWRMaW5rIHRoZW4gcG9zIG11c3QgPT0gLTEKKyAgICAgICAgICAgICAgICBsaW5rID0gbGlzdC52b2lkTGluazsKKyAgICAgICAgICAgICAgICBpZiAobG9jYXRpb24gPCBsaXN0LnNpemUgLyAyKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAocG9zID0gLTE7IHBvcyArIDEgPCBsb2NhdGlvbjsgcG9zKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxpbmsgPSBsaW5rLm5leHQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBmb3IgKHBvcyA9IGxpc3Quc2l6ZTsgcG9zID49IGxvY2F0aW9uOyBwb3MtLSkgeworICAgICAgICAgICAgICAgICAgICAgICAgbGluayA9IGxpbmsucHJldmlvdXM7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBhZGQoRVQgb2JqZWN0KSB7CisgICAgICAgICAgICBpZiAoZXhwZWN0ZWRNb2RDb3VudCA9PSBsaXN0Lm1vZENvdW50KSB7CisgICAgICAgICAgICAgICAgTGluazxFVD4gbmV4dCA9IGxpbmsubmV4dDsKKyAgICAgICAgICAgICAgICBMaW5rPEVUPiBuZXdMaW5rID0gbmV3IExpbms8RVQ+KG9iamVjdCwgbGluaywgbmV4dCk7CisgICAgICAgICAgICAgICAgbGluay5uZXh0ID0gbmV3TGluazsKKyAgICAgICAgICAgICAgICBuZXh0LnByZXZpb3VzID0gbmV3TGluazsKKyAgICAgICAgICAgICAgICBsaW5rID0gbmV3TGluazsKKyAgICAgICAgICAgICAgICBsYXN0TGluayA9IG51bGw7CisgICAgICAgICAgICAgICAgcG9zKys7CisgICAgICAgICAgICAgICAgZXhwZWN0ZWRNb2RDb3VudCsrOworICAgICAgICAgICAgICAgIGxpc3Quc2l6ZSsrOworICAgICAgICAgICAgICAgIGxpc3QubW9kQ291bnQrKzsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICByZXR1cm4gbGluay5uZXh0ICE9IGxpc3Qudm9pZExpbms7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcmV2aW91cygpIHsKKyAgICAgICAgICAgIHJldHVybiBsaW5rICE9IGxpc3Qudm9pZExpbms7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgRVQgbmV4dCgpIHsKKyAgICAgICAgICAgIGlmIChleHBlY3RlZE1vZENvdW50ID09IGxpc3QubW9kQ291bnQpIHsKKyAgICAgICAgICAgICAgICBMaW5rZWRMaXN0Lkxpbms8RVQ+IG5leHQgPSBsaW5rLm5leHQ7CisgICAgICAgICAgICAgICAgaWYgKG5leHQgIT0gbGlzdC52b2lkTGluaykgeworICAgICAgICAgICAgICAgICAgICBsYXN0TGluayA9IGxpbmsgPSBuZXh0OworICAgICAgICAgICAgICAgICAgICBwb3MrKzsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxpbmsuZGF0YTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IG5leHRJbmRleCgpIHsKKyAgICAgICAgICAgIHJldHVybiBwb3MgKyAxOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEVUIHByZXZpb3VzKCkgeworICAgICAgICAgICAgaWYgKGV4cGVjdGVkTW9kQ291bnQgPT0gbGlzdC5tb2RDb3VudCkgeworICAgICAgICAgICAgICAgIGlmIChsaW5rICE9IGxpc3Qudm9pZExpbmspIHsKKyAgICAgICAgICAgICAgICAgICAgbGFzdExpbmsgPSBsaW5rOworICAgICAgICAgICAgICAgICAgICBsaW5rID0gbGluay5wcmV2aW91czsKKyAgICAgICAgICAgICAgICAgICAgcG9zLS07CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBsYXN0TGluay5kYXRhOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgcHJldmlvdXNJbmRleCgpIHsKKyAgICAgICAgICAgIHJldHVybiBwb3M7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICBpZiAoZXhwZWN0ZWRNb2RDb3VudCA9PSBsaXN0Lm1vZENvdW50KSB7CisgICAgICAgICAgICAgICAgaWYgKGxhc3RMaW5rICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgTGluazxFVD4gbmV4dCA9IGxhc3RMaW5rLm5leHQ7CisgICAgICAgICAgICAgICAgICAgIExpbms8RVQ+IHByZXZpb3VzID0gbGFzdExpbmsucHJldmlvdXM7CisgICAgICAgICAgICAgICAgICAgIG5leHQucHJldmlvdXMgPSBwcmV2aW91czsKKyAgICAgICAgICAgICAgICAgICAgcHJldmlvdXMubmV4dCA9IG5leHQ7CisgICAgICAgICAgICAgICAgICAgIGlmIChsYXN0TGluayA9PSBsaW5rKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwb3MtLTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBsaW5rID0gcHJldmlvdXM7CisgICAgICAgICAgICAgICAgICAgIGxhc3RMaW5rID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWRNb2RDb3VudCsrOworICAgICAgICAgICAgICAgICAgICBsaXN0LnNpemUtLTsKKyAgICAgICAgICAgICAgICAgICAgbGlzdC5tb2RDb3VudCsrOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXQoRVQgb2JqZWN0KSB7CisgICAgICAgICAgICBpZiAoZXhwZWN0ZWRNb2RDb3VudCA9PSBsaXN0Lm1vZENvdW50KSB7CisgICAgICAgICAgICAgICAgaWYgKGxhc3RMaW5rICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgbGFzdExpbmsuZGF0YSA9IG9iamVjdDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBOT1RFUzpkZXNjZW5kaW5nSXRlcmF0b3IgaXMgbm90IGZhaWwtZmFzdCwgYWNjb3JkaW5nIHRvIHRoZSBkb2N1bWVudGF0aW9uCisgICAgICogYW5kIHRlc3QgY2FzZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGNsYXNzIFJldmVyc2VMaW5rSXRlcmF0b3I8RVQ+IGltcGxlbWVudHMgSXRlcmF0b3I8RVQ+IHsKKyAgICAgICAgcHJpdmF0ZSBpbnQgZXhwZWN0ZWRNb2RDb3VudDsKKworICAgICAgICBwcml2YXRlIGZpbmFsIExpbmtlZExpc3Q8RVQ+IGxpc3Q7CisKKyAgICAgICAgcHJpdmF0ZSBMaW5rPEVUPiBsaW5rOworCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBjYW5SZW1vdmU7CisKKyAgICAgICAgUmV2ZXJzZUxpbmtJdGVyYXRvcihMaW5rZWRMaXN0PEVUPiBsaW5rZWRMaXN0KSB7CisgICAgICAgICAgICBsaXN0ID0gbGlua2VkTGlzdDsKKyAgICAgICAgICAgIGV4cGVjdGVkTW9kQ291bnQgPSBsaXN0Lm1vZENvdW50OworICAgICAgICAgICAgbGluayA9IGxpc3Qudm9pZExpbms7CisgICAgICAgICAgICBjYW5SZW1vdmUgPSBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICByZXR1cm4gbGluay5wcmV2aW91cyAhPSBsaXN0LnZvaWRMaW5rOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEVUIG5leHQoKSB7CisgICAgICAgICAgICBpZiAoZXhwZWN0ZWRNb2RDb3VudCA9PSBsaXN0Lm1vZENvdW50KSB7CisgICAgICAgICAgICAgICAgaWYgKGhhc05leHQoKSkgeworICAgICAgICAgICAgICAgICAgICBsaW5rID0gbGluay5wcmV2aW91czsKKyAgICAgICAgICAgICAgICAgICAgY2FuUmVtb3ZlID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxpbmsuZGF0YTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgIGlmIChleHBlY3RlZE1vZENvdW50ID09IGxpc3QubW9kQ291bnQpIHsKKyAgICAgICAgICAgICAgICBpZiAoY2FuUmVtb3ZlKSB7CisgICAgICAgICAgICAgICAgICAgIExpbms8RVQ+IG5leHQgPSBsaW5rLnByZXZpb3VzOworICAgICAgICAgICAgICAgICAgICBMaW5rPEVUPiBwcmV2aW91cyA9IGxpbmsubmV4dDsKKyAgICAgICAgICAgICAgICAgICAgbmV4dC5uZXh0ID0gcHJldmlvdXM7CisgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzLnByZXZpb3VzID0gbmV4dDsKKyAgICAgICAgICAgICAgICAgICAgbGluayA9IHByZXZpb3VzOworICAgICAgICAgICAgICAgICAgICBsaXN0LnNpemUtLTsKKyAgICAgICAgICAgICAgICAgICAgbGlzdC5tb2RDb3VudCsrOworICAgICAgICAgICAgICAgICAgICBleHBlY3RlZE1vZENvdW50Kys7CisgICAgICAgICAgICAgICAgICAgIGNhblJlbW92ZSA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGVtcHR5IGluc3RhbmNlIG9mIHtAY29kZSBMaW5rZWRMaXN0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGlua2VkTGlzdCgpIHsKKyAgICAgICAgdm9pZExpbmsgPSBuZXcgTGluazxFPihudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgdm9pZExpbmsucHJldmlvdXMgPSB2b2lkTGluazsKKyAgICAgICAgdm9pZExpbmsubmV4dCA9IHZvaWRMaW5rOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIExpbmtlZExpc3R9IHRoYXQgaG9sZHMgYWxsIG9mIHRoZQorICAgICAqIGVsZW1lbnRzIGNvbnRhaW5lZCBpbiB0aGUgc3BlY2lmaWVkIHtAY29kZSBjb2xsZWN0aW9ufS4gVGhlIG9yZGVyIG9mIHRoZQorICAgICAqIGVsZW1lbnRzIGluIHRoaXMgbmV3IHtAY29kZSBMaW5rZWRMaXN0fSB3aWxsIGJlIGRldGVybWluZWQgYnkgdGhlCisgICAgICogaXRlcmF0aW9uIG9yZGVyIG9mIHtAY29kZSBjb2xsZWN0aW9ufS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2xsZWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgY29sbGVjdGlvbiBvZiBlbGVtZW50cyB0byBhZGQuCisgICAgICovCisgICAgcHVibGljIExpbmtlZExpc3QoQ29sbGVjdGlvbjw/IGV4dGVuZHMgRT4gY29sbGVjdGlvbikgeworICAgICAgICB0aGlzKCk7CisgICAgICAgIGFkZEFsbChjb2xsZWN0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGludG8gdGhpcyB7QGNvZGUgTGlua2VkTGlzdH0gYXQgdGhlCisgICAgICogc3BlY2lmaWVkIGxvY2F0aW9uLiBUaGUgb2JqZWN0IGlzIGluc2VydGVkIGJlZm9yZSBhbnkgcHJldmlvdXMgZWxlbWVudCBhdAorICAgICAqIHRoZSBzcGVjaWZpZWQgbG9jYXRpb24uIElmIHRoZSBsb2NhdGlvbiBpcyBlcXVhbCB0byB0aGUgc2l6ZSBvZiB0aGlzCisgICAgICoge0Bjb2RlIExpbmtlZExpc3R9LCB0aGUgb2JqZWN0IGlzIGFkZGVkIGF0IHRoZSBlbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhdCB3aGljaCB0byBpbnNlcnQuCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBhZGQuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGxvY2F0aW9uIDwgMCB8fCA+PSBzaXplKCl9CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYWRkKGludCBsb2NhdGlvbiwgRSBvYmplY3QpIHsKKyAgICAgICAgaWYgKGxvY2F0aW9uID49IDAgJiYgbG9jYXRpb24gPD0gc2l6ZSkgeworICAgICAgICAgICAgTGluazxFPiBsaW5rID0gdm9pZExpbms7CisgICAgICAgICAgICBpZiAobG9jYXRpb24gPCAoc2l6ZSAvIDIpKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gbG9jYXRpb247IGkrKykgeworICAgICAgICAgICAgICAgICAgICBsaW5rID0gbGluay5uZXh0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHNpemU7IGkgPiBsb2NhdGlvbjsgaS0tKSB7CisgICAgICAgICAgICAgICAgICAgIGxpbmsgPSBsaW5rLnByZXZpb3VzOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIExpbms8RT4gcHJldmlvdXMgPSBsaW5rLnByZXZpb3VzOworICAgICAgICAgICAgTGluazxFPiBuZXdMaW5rID0gbmV3IExpbms8RT4ob2JqZWN0LCBwcmV2aW91cywgbGluayk7CisgICAgICAgICAgICBwcmV2aW91cy5uZXh0ID0gbmV3TGluazsKKyAgICAgICAgICAgIGxpbmsucHJldmlvdXMgPSBuZXdMaW5rOworICAgICAgICAgICAgc2l6ZSsrOworICAgICAgICAgICAgbW9kQ291bnQrKzsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGF0IHRoZSBlbmQgb2YgdGhpcyB7QGNvZGUgTGlua2VkTGlzdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFkZC4KKyAgICAgKiBAcmV0dXJuIGFsd2F5cyB0cnVlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gYWRkKEUgb2JqZWN0KSB7CisgICAgICAgIHJldHVybiBhZGRMYXN0SW1wbChvYmplY3QpOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBhZGRMYXN0SW1wbChFIG9iamVjdCkgeworICAgICAgICBMaW5rPEU+IG9sZExhc3QgPSB2b2lkTGluay5wcmV2aW91czsKKyAgICAgICAgTGluazxFPiBuZXdMaW5rID0gbmV3IExpbms8RT4ob2JqZWN0LCBvbGRMYXN0LCB2b2lkTGluayk7CisgICAgICAgIHZvaWRMaW5rLnByZXZpb3VzID0gbmV3TGluazsKKyAgICAgICAgb2xkTGFzdC5uZXh0ID0gbmV3TGluazsKKyAgICAgICAgc2l6ZSsrOworICAgICAgICBtb2RDb3VudCsrOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBvYmplY3RzIGluIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uCisgICAgICogaW4gdGhpcyB7QGNvZGUgTGlua2VkTGlzdH0uIFRoZSBvYmplY3RzIGFyZSBhZGRlZCBpbiB0aGUgb3JkZXIgdGhleSBhcmUKKyAgICAgKiByZXR1cm5lZCBmcm9tIHRoZSBjb2xsZWN0aW9uJ3MgaXRlcmF0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhdCB3aGljaCB0byBpbnNlcnQuCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIG9mIG9iamVjdHMKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBMaW5rZWRMaXN0fSBpcyBtb2RpZmllZCwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIGFuIG9iamVjdCBpcyBpbmFwcHJvcHJpYXRlIGZvciB0aGlzIGxpc3QuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBvYmplY3QgY2Fubm90IGJlIGFkZGVkIHRvIHRoaXMgbGlzdC4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbG9jYXRpb24gPCAwIHx8ID4gc2l6ZSgpfQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGFkZEFsbChpbnQgbG9jYXRpb24sIENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgaWYgKGxvY2F0aW9uIDwgMCB8fCBsb2NhdGlvbiA+IHNpemUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGFkZGluZyA9IGNvbGxlY3Rpb24uc2l6ZSgpOworICAgICAgICBpZiAoYWRkaW5nID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBlbGVtZW50cyA9IChjb2xsZWN0aW9uID09IHRoaXMpID8KKyAgICAgICAgICAgICAgICBuZXcgQXJyYXlMaXN0PEU+KGNvbGxlY3Rpb24pIDogY29sbGVjdGlvbjsKKworICAgICAgICBMaW5rPEU+IHByZXZpb3VzID0gdm9pZExpbms7CisgICAgICAgIGlmIChsb2NhdGlvbiA8IChzaXplIC8gMikpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbG9jYXRpb247IGkrKykgeworICAgICAgICAgICAgICAgIHByZXZpb3VzID0gcHJldmlvdXMubmV4dDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBzaXplOyBpID49IGxvY2F0aW9uOyBpLS0pIHsKKyAgICAgICAgICAgICAgICBwcmV2aW91cyA9IHByZXZpb3VzLnByZXZpb3VzOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIExpbms8RT4gbmV4dCA9IHByZXZpb3VzLm5leHQ7CisgICAgICAgIGZvciAoRSBlIDogZWxlbWVudHMpIHsKKyAgICAgICAgICAgIExpbms8RT4gbmV3TGluayA9IG5ldyBMaW5rPEU+KGUsIHByZXZpb3VzLCBudWxsKTsKKyAgICAgICAgICAgIHByZXZpb3VzLm5leHQgPSBuZXdMaW5rOworICAgICAgICAgICAgcHJldmlvdXMgPSBuZXdMaW5rOworICAgICAgICB9CisgICAgICAgIHByZXZpb3VzLm5leHQgPSBuZXh0OworICAgICAgICBuZXh0LnByZXZpb3VzID0gcHJldmlvdXM7CisgICAgICAgIHNpemUgKz0gYWRkaW5nOworICAgICAgICBtb2RDb3VudCsrOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBvYmplY3RzIGluIHRoZSBzcGVjaWZpZWQgQ29sbGVjdGlvbiB0byB0aGlzIHtAY29kZSBMaW5rZWRMaXN0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2xsZWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgY29sbGVjdGlvbiBvZiBvYmplY3RzLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMge0Bjb2RlIExpbmtlZExpc3R9IGlzIG1vZGlmaWVkLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gYWRkQWxsKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgaW50IGFkZGluZyA9IGNvbGxlY3Rpb24uc2l6ZSgpOworICAgICAgICBpZiAoYWRkaW5nID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBlbGVtZW50cyA9IChjb2xsZWN0aW9uID09IHRoaXMpID8KKyAgICAgICAgICAgICAgICBuZXcgQXJyYXlMaXN0PEU+KGNvbGxlY3Rpb24pIDogY29sbGVjdGlvbjsKKworICAgICAgICBMaW5rPEU+IHByZXZpb3VzID0gdm9pZExpbmsucHJldmlvdXM7CisgICAgICAgIGZvciAoRSBlIDogZWxlbWVudHMpIHsKKyAgICAgICAgICAgIExpbms8RT4gbmV3TGluayA9IG5ldyBMaW5rPEU+KGUsIHByZXZpb3VzLCBudWxsKTsKKyAgICAgICAgICAgIHByZXZpb3VzLm5leHQgPSBuZXdMaW5rOworICAgICAgICAgICAgcHJldmlvdXMgPSBuZXdMaW5rOworICAgICAgICB9CisgICAgICAgIHByZXZpb3VzLm5leHQgPSB2b2lkTGluazsKKyAgICAgICAgdm9pZExpbmsucHJldmlvdXMgPSBwcmV2aW91czsKKyAgICAgICAgc2l6ZSArPSBhZGRpbmc7CisgICAgICAgIG1vZENvdW50Kys7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIHNwZWNpZmllZCBvYmplY3QgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGlzIHtAY29kZSBMaW5rZWRMaXN0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYWRkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZEZpcnN0KEUgb2JqZWN0KSB7CisgICAgICAgIGFkZEZpcnN0SW1wbChvYmplY3QpOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBhZGRGaXJzdEltcGwoRSBvYmplY3QpIHsKKyAgICAgICAgTGluazxFPiBvbGRGaXJzdCA9IHZvaWRMaW5rLm5leHQ7CisgICAgICAgIExpbms8RT4gbmV3TGluayA9IG5ldyBMaW5rPEU+KG9iamVjdCwgdm9pZExpbmssIG9sZEZpcnN0KTsKKyAgICAgICAgdm9pZExpbmsubmV4dCA9IG5ld0xpbms7CisgICAgICAgIG9sZEZpcnN0LnByZXZpb3VzID0gbmV3TGluazsKKyAgICAgICAgc2l6ZSsrOworICAgICAgICBtb2RDb3VudCsrOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGF0IHRoZSBlbmQgb2YgdGhpcyB7QGNvZGUgTGlua2VkTGlzdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFkZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRMYXN0KEUgb2JqZWN0KSB7CisgICAgICAgIGFkZExhc3RJbXBsKG9iamVjdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhbGwgZWxlbWVudHMgZnJvbSB0aGlzIHtAY29kZSBMaW5rZWRMaXN0fSwgbGVhdmluZyBpdCBlbXB0eS4KKyAgICAgKgorICAgICAqIEBzZWUgTGlzdCNpc0VtcHR5CisgICAgICogQHNlZSAjc2l6ZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBpZiAoc2l6ZSA+IDApIHsKKyAgICAgICAgICAgIHNpemUgPSAwOworICAgICAgICAgICAgdm9pZExpbmsubmV4dCA9IHZvaWRMaW5rOworICAgICAgICAgICAgdm9pZExpbmsucHJldmlvdXMgPSB2b2lkTGluazsKKyAgICAgICAgICAgIG1vZENvdW50Kys7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBMaW5rZWRMaXN0fSB3aXRoIHRoZSBzYW1lIGVsZW1lbnRzIGFuZCBzaXplIGFzIHRoaXMKKyAgICAgKiB7QGNvZGUgTGlua2VkTGlzdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc2hhbGxvdyBjb3B5IG9mIHRoaXMge0Bjb2RlIExpbmtlZExpc3R9LgorICAgICAqIEBzZWUgamF2YS5sYW5nLkNsb25lYWJsZQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMaW5rZWRMaXN0PEU+IGwgPSAoTGlua2VkTGlzdDxFPikgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgICAgIGwuc2l6ZSA9IDA7CisgICAgICAgICAgICBsLnZvaWRMaW5rID0gbmV3IExpbms8RT4obnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICBsLnZvaWRMaW5rLnByZXZpb3VzID0gbC52b2lkTGluazsKKyAgICAgICAgICAgIGwudm9pZExpbmsubmV4dCA9IGwudm9pZExpbms7CisgICAgICAgICAgICBsLmFkZEFsbCh0aGlzKTsKKyAgICAgICAgICAgIHJldHVybiBsOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyB0aGlzIHtAY29kZSBMaW5rZWRMaXN0fSBmb3IgdGhlIHNwZWNpZmllZCBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIHNlYXJjaCBmb3IuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIG9iamVjdH0gaXMgYW4gZWxlbWVudCBvZiB0aGlzCisgICAgICogICAgICAgICB7QGNvZGUgTGlua2VkTGlzdH0sIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBMaW5rPEU+IGxpbmsgPSB2b2lkTGluay5uZXh0OworICAgICAgICBpZiAob2JqZWN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHdoaWxlIChsaW5rICE9IHZvaWRMaW5rKSB7CisgICAgICAgICAgICAgICAgaWYgKG9iamVjdC5lcXVhbHMobGluay5kYXRhKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbGluayA9IGxpbmsubmV4dDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHdoaWxlIChsaW5rICE9IHZvaWRMaW5rKSB7CisgICAgICAgICAgICAgICAgaWYgKGxpbmsuZGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBsaW5rID0gbGluay5uZXh0OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRSBnZXQoaW50IGxvY2F0aW9uKSB7CisgICAgICAgIGlmIChsb2NhdGlvbiA+PSAwICYmIGxvY2F0aW9uIDwgc2l6ZSkgeworICAgICAgICAgICAgTGluazxFPiBsaW5rID0gdm9pZExpbms7CisgICAgICAgICAgICBpZiAobG9jYXRpb24gPCAoc2l6ZSAvIDIpKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gbG9jYXRpb247IGkrKykgeworICAgICAgICAgICAgICAgICAgICBsaW5rID0gbGluay5uZXh0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHNpemU7IGkgPiBsb2NhdGlvbjsgaS0tKSB7CisgICAgICAgICAgICAgICAgICAgIGxpbmsgPSBsaW5rLnByZXZpb3VzOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBsaW5rLmRhdGE7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBmaXJzdCBlbGVtZW50IGluIHRoaXMge0Bjb2RlIExpbmtlZExpc3R9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZmlyc3QgZWxlbWVudC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBMaW5rZWRMaXN0fSBpcyBlbXB0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRSBnZXRGaXJzdCgpIHsKKyAgICAgICAgcmV0dXJuIGdldEZpcnN0SW1wbCgpOworICAgIH0KKworICAgIHByaXZhdGUgRSBnZXRGaXJzdEltcGwoKSB7CisgICAgICAgIExpbms8RT4gZmlyc3QgPSB2b2lkTGluay5uZXh0OworICAgICAgICBpZiAoZmlyc3QgIT0gdm9pZExpbmspIHsKKyAgICAgICAgICAgIHJldHVybiBmaXJzdC5kYXRhOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGFzdCBlbGVtZW50IGluIHRoaXMge0Bjb2RlIExpbmtlZExpc3R9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGFzdCBlbGVtZW50CisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgTGlua2VkTGlzdH0gaXMgZW1wdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgRSBnZXRMYXN0KCkgeworICAgICAgICBMaW5rPEU+IGxhc3QgPSB2b2lkTGluay5wcmV2aW91czsKKyAgICAgICAgaWYgKGxhc3QgIT0gdm9pZExpbmspIHsKKyAgICAgICAgICAgIHJldHVybiBsYXN0LmRhdGE7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGluZGV4T2YoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBpbnQgcG9zID0gMDsKKyAgICAgICAgTGluazxFPiBsaW5rID0gdm9pZExpbmsubmV4dDsKKyAgICAgICAgaWYgKG9iamVjdCAhPSBudWxsKSB7CisgICAgICAgICAgICB3aGlsZSAobGluayAhPSB2b2lkTGluaykgeworICAgICAgICAgICAgICAgIGlmIChvYmplY3QuZXF1YWxzKGxpbmsuZGF0YSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBvczsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbGluayA9IGxpbmsubmV4dDsKKyAgICAgICAgICAgICAgICBwb3MrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHdoaWxlIChsaW5rICE9IHZvaWRMaW5rKSB7CisgICAgICAgICAgICAgICAgaWYgKGxpbmsuZGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBwb3M7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGxpbmsgPSBsaW5rLm5leHQ7CisgICAgICAgICAgICAgICAgcG9zKys7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlYXJjaGVzIHRoaXMge0Bjb2RlIExpbmtlZExpc3R9IGZvciB0aGUgc3BlY2lmaWVkIG9iamVjdCBhbmQgcmV0dXJucyB0aGUKKyAgICAgKiBpbmRleCBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBzZWFyY2ggZm9yCisgICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUgb2JqZWN0LCBvciAtMSBpZiBpdCB3YXMKKyAgICAgKiAgICAgICAgIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGxhc3RJbmRleE9mKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgaW50IHBvcyA9IHNpemU7CisgICAgICAgIExpbms8RT4gbGluayA9IHZvaWRMaW5rLnByZXZpb3VzOworICAgICAgICBpZiAob2JqZWN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHdoaWxlIChsaW5rICE9IHZvaWRMaW5rKSB7CisgICAgICAgICAgICAgICAgcG9zLS07CisgICAgICAgICAgICAgICAgaWYgKG9iamVjdC5lcXVhbHMobGluay5kYXRhKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcG9zOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBsaW5rID0gbGluay5wcmV2aW91czsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHdoaWxlIChsaW5rICE9IHZvaWRMaW5rKSB7CisgICAgICAgICAgICAgICAgcG9zLS07CisgICAgICAgICAgICAgICAgaWYgKGxpbmsuZGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBwb3M7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGxpbmsgPSBsaW5rLnByZXZpb3VzOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgTGlzdEl0ZXJhdG9yIG9uIHRoZSBlbGVtZW50cyBvZiB0aGlzIHtAY29kZSBMaW5rZWRMaXN0fS4gVGhlCisgICAgICogZWxlbWVudHMgYXJlIGl0ZXJhdGVkIGluIHRoZSBzYW1lIG9yZGVyIHRoYXQgdGhleSBvY2N1ciBpbiB0aGUKKyAgICAgKiB7QGNvZGUgTGlua2VkTGlzdH0uIFRoZSBpdGVyYXRpb24gc3RhcnRzIGF0IHRoZSBzcGVjaWZpZWQgbG9jYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhdCB3aGljaCB0byBzdGFydCB0aGUgaXRlcmF0aW9uCisgICAgICogQHJldHVybiBhIExpc3RJdGVyYXRvciBvbiB0aGUgZWxlbWVudHMgb2YgdGhpcyB7QGNvZGUgTGlua2VkTGlzdH0KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbG9jYXRpb24gPCAwIHx8ID49IHNpemUoKX0KKyAgICAgKiBAc2VlIExpc3RJdGVyYXRvcgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBMaXN0SXRlcmF0b3I8RT4gbGlzdEl0ZXJhdG9yKGludCBsb2NhdGlvbikgeworICAgICAgICByZXR1cm4gbmV3IExpbmtJdGVyYXRvcjxFPih0aGlzLCBsb2NhdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgb2JqZWN0IGF0IHRoZSBzcGVjaWZpZWQgbG9jYXRpb24gZnJvbSB0aGlzIHtAY29kZSBMaW5rZWRMaXN0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBvYmplY3QgdG8gcmVtb3ZlCisgICAgICogQHJldHVybiB0aGUgcmVtb3ZlZCBvYmplY3QKKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbG9jYXRpb24gPCAwIHx8ID49IHNpemUoKX0KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRSByZW1vdmUoaW50IGxvY2F0aW9uKSB7CisgICAgICAgIGlmIChsb2NhdGlvbiA+PSAwICYmIGxvY2F0aW9uIDwgc2l6ZSkgeworICAgICAgICAgICAgTGluazxFPiBsaW5rID0gdm9pZExpbms7CisgICAgICAgICAgICBpZiAobG9jYXRpb24gPCAoc2l6ZSAvIDIpKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gbG9jYXRpb247IGkrKykgeworICAgICAgICAgICAgICAgICAgICBsaW5rID0gbGluay5uZXh0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHNpemU7IGkgPiBsb2NhdGlvbjsgaS0tKSB7CisgICAgICAgICAgICAgICAgICAgIGxpbmsgPSBsaW5rLnByZXZpb3VzOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIExpbms8RT4gcHJldmlvdXMgPSBsaW5rLnByZXZpb3VzOworICAgICAgICAgICAgTGluazxFPiBuZXh0ID0gbGluay5uZXh0OworICAgICAgICAgICAgcHJldmlvdXMubmV4dCA9IG5leHQ7CisgICAgICAgICAgICBuZXh0LnByZXZpb3VzID0gcHJldmlvdXM7CisgICAgICAgICAgICBzaXplLS07CisgICAgICAgICAgICBtb2RDb3VudCsrOworICAgICAgICAgICAgcmV0dXJuIGxpbmsuZGF0YTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIHJldHVybiByZW1vdmVGaXJzdE9jY3VycmVuY2VJbXBsKG9iamVjdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgZmlyc3Qgb2JqZWN0IGZyb20gdGhpcyB7QGNvZGUgTGlua2VkTGlzdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZW1vdmVkIG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBMaW5rZWRMaXN0fSBpcyBlbXB0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRSByZW1vdmVGaXJzdCgpIHsKKyAgICAgICAgcmV0dXJuIHJlbW92ZUZpcnN0SW1wbCgpOworICAgIH0KKworICAgIHByaXZhdGUgRSByZW1vdmVGaXJzdEltcGwoKSB7CisgICAgICAgIExpbms8RT4gZmlyc3QgPSB2b2lkTGluay5uZXh0OworICAgICAgICBpZiAoZmlyc3QgIT0gdm9pZExpbmspIHsKKyAgICAgICAgICAgIExpbms8RT4gbmV4dCA9IGZpcnN0Lm5leHQ7CisgICAgICAgICAgICB2b2lkTGluay5uZXh0ID0gbmV4dDsKKyAgICAgICAgICAgIG5leHQucHJldmlvdXMgPSB2b2lkTGluazsKKyAgICAgICAgICAgIHNpemUtLTsKKyAgICAgICAgICAgIG1vZENvdW50Kys7CisgICAgICAgICAgICByZXR1cm4gZmlyc3QuZGF0YTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGxhc3Qgb2JqZWN0IGZyb20gdGhpcyB7QGNvZGUgTGlua2VkTGlzdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZW1vdmVkIG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBMaW5rZWRMaXN0fSBpcyBlbXB0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRSByZW1vdmVMYXN0KCkgeworICAgICAgICByZXR1cm4gcmVtb3ZlTGFzdEltcGwoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIEUgcmVtb3ZlTGFzdEltcGwoKSB7CisgICAgICAgIExpbms8RT4gbGFzdCA9IHZvaWRMaW5rLnByZXZpb3VzOworICAgICAgICBpZiAobGFzdCAhPSB2b2lkTGluaykgeworICAgICAgICAgICAgTGluazxFPiBwcmV2aW91cyA9IGxhc3QucHJldmlvdXM7CisgICAgICAgICAgICB2b2lkTGluay5wcmV2aW91cyA9IHByZXZpb3VzOworICAgICAgICAgICAgcHJldmlvdXMubmV4dCA9IHZvaWRMaW5rOworICAgICAgICAgICAgc2l6ZS0tOworICAgICAgICAgICAgbW9kQ291bnQrKzsKKyAgICAgICAgICAgIHJldHVybiBsYXN0LmRhdGE7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiBAc2VlIGphdmEudXRpbC5EZXF1ZSNkZXNjZW5kaW5nSXRlcmF0b3IoKQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3I8RT4gZGVzY2VuZGluZ0l0ZXJhdG9yKCkgeworICAgICAgICByZXR1cm4gbmV3IFJldmVyc2VMaW5rSXRlcmF0b3I8RT4odGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogQHNlZSBqYXZhLnV0aWwuRGVxdWUjb2ZmZXJGaXJzdChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBvZmZlckZpcnN0KEUgZSkgeworICAgICAgICByZXR1cm4gYWRkRmlyc3RJbXBsKGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIEBzZWUgamF2YS51dGlsLkRlcXVlI29mZmVyTGFzdChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBvZmZlckxhc3QoRSBlKSB7CisgICAgICAgIHJldHVybiBhZGRMYXN0SW1wbChlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiBAc2VlIGphdmEudXRpbC5EZXF1ZSNwZWVrRmlyc3QoKQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgRSBwZWVrRmlyc3QoKSB7CisgICAgICAgIHJldHVybiBwZWVrRmlyc3RJbXBsKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogQHNlZSBqYXZhLnV0aWwuRGVxdWUjcGVla0xhc3QoKQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgRSBwZWVrTGFzdCgpIHsKKyAgICAgICAgTGluazxFPiBsYXN0ID0gdm9pZExpbmsucHJldmlvdXM7CisgICAgICAgIHJldHVybiAobGFzdCA9PSB2b2lkTGluaykgPyBudWxsIDogbGFzdC5kYXRhOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIEBzZWUgamF2YS51dGlsLkRlcXVlI3BvbGxGaXJzdCgpCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBFIHBvbGxGaXJzdCgpIHsKKyAgICAgICAgcmV0dXJuIChzaXplID09IDApID8gbnVsbCA6IHJlbW92ZUZpcnN0SW1wbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIEBzZWUgamF2YS51dGlsLkRlcXVlI3BvbGxMYXN0KCkKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIEUgcG9sbExhc3QoKSB7CisgICAgICAgIHJldHVybiAoc2l6ZSA9PSAwKSA/IG51bGwgOiByZW1vdmVMYXN0SW1wbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIEBzZWUgamF2YS51dGlsLkRlcXVlI3BvcCgpCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBFIHBvcCgpIHsKKyAgICAgICAgcmV0dXJuIHJlbW92ZUZpcnN0SW1wbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIEBzZWUgamF2YS51dGlsLkRlcXVlI3B1c2goamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHZvaWQgcHVzaChFIGUpIHsKKyAgICAgICAgYWRkRmlyc3RJbXBsKGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIEBzZWUgamF2YS51dGlsLkRlcXVlI3JlbW92ZUZpcnN0T2NjdXJyZW5jZShqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmVGaXJzdE9jY3VycmVuY2UoT2JqZWN0IG8pIHsKKyAgICAgICAgcmV0dXJuIHJlbW92ZUZpcnN0T2NjdXJyZW5jZUltcGwobyk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogQHNlZSBqYXZhLnV0aWwuRGVxdWUjcmVtb3ZlTGFzdE9jY3VycmVuY2UoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlTGFzdE9jY3VycmVuY2UoT2JqZWN0IG8pIHsKKyAgICAgICAgSXRlcmF0b3I8RT4gaXRlciA9IG5ldyBSZXZlcnNlTGlua0l0ZXJhdG9yPEU+KHRoaXMpOworICAgICAgICByZXR1cm4gcmVtb3ZlT25lT2NjdXJyZW5jZShvLCBpdGVyKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gcmVtb3ZlRmlyc3RPY2N1cnJlbmNlSW1wbChPYmplY3QgbykgeworICAgICAgICBJdGVyYXRvcjxFPiBpdGVyID0gbmV3IExpbmtJdGVyYXRvcjxFPih0aGlzLCAwKTsKKyAgICAgICAgcmV0dXJuIHJlbW92ZU9uZU9jY3VycmVuY2UobywgaXRlcik7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIHJlbW92ZU9uZU9jY3VycmVuY2UoT2JqZWN0IG8sIEl0ZXJhdG9yPEU+IGl0ZXIpIHsKKyAgICAgICAgd2hpbGUgKGl0ZXIuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBFIGVsZW1lbnQgPSBpdGVyLm5leHQoKTsKKyAgICAgICAgICAgIGlmIChvID09IG51bGwgPyBlbGVtZW50ID09IG51bGwgOiBvLmVxdWFscyhlbGVtZW50KSkgeworICAgICAgICAgICAgICAgIGl0ZXIucmVtb3ZlKCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2VzIHRoZSBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgbG9jYXRpb24gaW4gdGhpcyB7QGNvZGUgTGlua2VkTGlzdH0KKyAgICAgKiB3aXRoIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2F0aW9uCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggYXQgd2hpY2ggdG8gcHV0IHRoZSBzcGVjaWZpZWQgb2JqZWN0LgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYWRkLgorICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIGVsZW1lbnQgYXQgdGhlIGluZGV4LgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIGFuIG9iamVjdCBpcyBpbmFwcHJvcHJpYXRlIGZvciB0aGlzIGxpc3QuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBvYmplY3QgY2Fubm90IGJlIGFkZGVkIHRvIHRoaXMgbGlzdC4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbG9jYXRpb24gPCAwIHx8ID49IHNpemUoKX0KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRSBzZXQoaW50IGxvY2F0aW9uLCBFIG9iamVjdCkgeworICAgICAgICBpZiAobG9jYXRpb24gPj0gMCAmJiBsb2NhdGlvbiA8IHNpemUpIHsKKyAgICAgICAgICAgIExpbms8RT4gbGluayA9IHZvaWRMaW5rOworICAgICAgICAgICAgaWYgKGxvY2F0aW9uIDwgKHNpemUgLyAyKSkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IGxvY2F0aW9uOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgbGluayA9IGxpbmsubmV4dDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBzaXplOyBpID4gbG9jYXRpb247IGktLSkgeworICAgICAgICAgICAgICAgICAgICBsaW5rID0gbGluay5wcmV2aW91czsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBFIHJlc3VsdCA9IGxpbmsuZGF0YTsKKyAgICAgICAgICAgIGxpbmsuZGF0YSA9IG9iamVjdDsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyB7QGNvZGUgTGlua2VkTGlzdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyB7QGNvZGUgTGlua2VkTGlzdH0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICByZXR1cm4gc2l6ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBvZmZlcihFIG8pIHsKKyAgICAgICAgcmV0dXJuIGFkZExhc3RJbXBsKG8pOworICAgIH0KKworICAgIHB1YmxpYyBFIHBvbGwoKSB7CisgICAgICAgIHJldHVybiBzaXplID09IDAgPyBudWxsIDogcmVtb3ZlRmlyc3QoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRSByZW1vdmUoKSB7CisgICAgICAgIHJldHVybiByZW1vdmVGaXJzdEltcGwoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRSBwZWVrKCkgeworICAgICAgICByZXR1cm4gcGVla0ZpcnN0SW1wbCgpOworICAgIH0KKworICAgIHByaXZhdGUgRSBwZWVrRmlyc3RJbXBsKCkgeworICAgICAgICBMaW5rPEU+IGZpcnN0ID0gdm9pZExpbmsubmV4dDsKKyAgICAgICAgcmV0dXJuIGZpcnN0ID09IHZvaWRMaW5rID8gbnVsbCA6IGZpcnN0LmRhdGE7CisgICAgfQorCisgICAgcHVibGljIEUgZWxlbWVudCgpIHsKKyAgICAgICAgcmV0dXJuIGdldEZpcnN0SW1wbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgYXJyYXkgY29udGFpbmluZyBhbGwgZWxlbWVudHMgY29udGFpbmVkIGluIHRoaXMKKyAgICAgKiB7QGNvZGUgTGlua2VkTGlzdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIHRoZSBlbGVtZW50cyBmcm9tIHRoaXMge0Bjb2RlIExpbmtlZExpc3R9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3RbXSB0b0FycmF5KCkgeworICAgICAgICBpbnQgaW5kZXggPSAwOworICAgICAgICBPYmplY3RbXSBjb250ZW50cyA9IG5ldyBPYmplY3Rbc2l6ZV07CisgICAgICAgIExpbms8RT4gbGluayA9IHZvaWRMaW5rLm5leHQ7CisgICAgICAgIHdoaWxlIChsaW5rICE9IHZvaWRMaW5rKSB7CisgICAgICAgICAgICBjb250ZW50c1tpbmRleCsrXSA9IGxpbmsuZGF0YTsKKyAgICAgICAgICAgIGxpbmsgPSBsaW5rLm5leHQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvbnRlbnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgZWxlbWVudHMgY29udGFpbmVkIGluIHRoaXMKKyAgICAgKiB7QGNvZGUgTGlua2VkTGlzdH0uIElmIHRoZSBzcGVjaWZpZWQgYXJyYXkgaXMgbGFyZ2UgZW5vdWdoIHRvIGhvbGQgdGhlCisgICAgICogZWxlbWVudHMsIHRoZSBzcGVjaWZpZWQgYXJyYXkgaXMgdXNlZCwgb3RoZXJ3aXNlIGFuIGFycmF5IG9mIHRoZSBzYW1lCisgICAgICogdHlwZSBpcyBjcmVhdGVkLiBJZiB0aGUgc3BlY2lmaWVkIGFycmF5IGlzIHVzZWQgYW5kIGlzIGxhcmdlciB0aGFuIHRoaXMKKyAgICAgKiB7QGNvZGUgTGlua2VkTGlzdH0sIHRoZSBhcnJheSBlbGVtZW50IGZvbGxvd2luZyB0aGUgY29sbGVjdGlvbiBlbGVtZW50cworICAgICAqIGlzIHNldCB0byBudWxsLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbnRlbnRzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkuCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiB0aGUgZWxlbWVudHMgZnJvbSB0aGlzIHtAY29kZSBMaW5rZWRMaXN0fS4KKyAgICAgKiBAdGhyb3dzIEFycmF5U3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgdHlwZSBvZiBhbiBlbGVtZW50IGluIHRoaXMge0Bjb2RlIExpbmtlZExpc3R9IGNhbm5vdAorICAgICAqICAgICAgICAgICAgIGJlIHN0b3JlZCBpbiB0aGUgdHlwZSBvZiB0aGUgc3BlY2lmaWVkIGFycmF5LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyA8VD4gVFtdIHRvQXJyYXkoVFtdIGNvbnRlbnRzKSB7CisgICAgICAgIGludCBpbmRleCA9IDA7CisgICAgICAgIGlmIChzaXplID4gY29udGVudHMubGVuZ3RoKSB7CisgICAgICAgICAgICBDbGFzczw/PiBjdCA9IGNvbnRlbnRzLmdldENsYXNzKCkuZ2V0Q29tcG9uZW50VHlwZSgpOworICAgICAgICAgICAgY29udGVudHMgPSAoVFtdKSBBcnJheS5uZXdJbnN0YW5jZShjdCwgc2l6ZSk7CisgICAgICAgIH0KKyAgICAgICAgTGluazxFPiBsaW5rID0gdm9pZExpbmsubmV4dDsKKyAgICAgICAgd2hpbGUgKGxpbmsgIT0gdm9pZExpbmspIHsKKyAgICAgICAgICAgIGNvbnRlbnRzW2luZGV4KytdID0gKFQpIGxpbmsuZGF0YTsKKyAgICAgICAgICAgIGxpbmsgPSBsaW5rLm5leHQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGluZGV4IDwgY29udGVudHMubGVuZ3RoKSB7CisgICAgICAgICAgICBjb250ZW50c1tpbmRleF0gPSBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb250ZW50czsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3RyZWFtLmRlZmF1bHRXcml0ZU9iamVjdCgpOworICAgICAgICBzdHJlYW0ud3JpdGVJbnQoc2l6ZSk7CisgICAgICAgIEl0ZXJhdG9yPEU+IGl0ID0gaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgc3RyZWFtLndyaXRlT2JqZWN0KGl0Lm5leHQoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBzdHJlYW0uZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgc2l6ZSA9IHN0cmVhbS5yZWFkSW50KCk7CisgICAgICAgIHZvaWRMaW5rID0gbmV3IExpbms8RT4obnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgIExpbms8RT4gbGluayA9IHZvaWRMaW5rOworICAgICAgICBmb3IgKGludCBpID0gc2l6ZTsgLS1pID49IDA7KSB7CisgICAgICAgICAgICBMaW5rPEU+IG5leHRMaW5rID0gbmV3IExpbms8RT4oKEUpIHN0cmVhbS5yZWFkT2JqZWN0KCksIGxpbmssIG51bGwpOworICAgICAgICAgICAgbGluay5uZXh0ID0gbmV4dExpbms7CisgICAgICAgICAgICBsaW5rID0gbmV4dExpbms7CisgICAgICAgIH0KKyAgICAgICAgbGluay5uZXh0ID0gdm9pZExpbms7CisgICAgICAgIHZvaWRMaW5rLnByZXZpb3VzID0gbGluazsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0xpc3QuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTGlzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyN2NhM2YKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0xpc3QuamF2YQpAQCAtMCwwICsxLDM1MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKKworLyoqCisgKiBBIHtAY29kZSBMaXN0fSBpcyBhIGNvbGxlY3Rpb24gd2hpY2ggbWFpbnRhaW5zIGFuIG9yZGVyaW5nIGZvciBpdHMgZWxlbWVudHMuIEV2ZXJ5CisgKiBlbGVtZW50IGluIHRoZSB7QGNvZGUgTGlzdH0gaGFzIGFuIGluZGV4LiBFYWNoIGVsZW1lbnQgY2FuIHRodXMgYmUgYWNjZXNzZWQgYnkgaXRzCisgKiBpbmRleCwgd2l0aCB0aGUgZmlyc3QgaW5kZXggYmVpbmcgemVyby4gTm9ybWFsbHksIHtAY29kZSBMaXN0fXMgYWxsb3cgZHVwbGljYXRlCisgKiBlbGVtZW50cywgYXMgY29tcGFyZWQgdG8gU2V0cywgd2hlcmUgZWxlbWVudHMgaGF2ZSB0byBiZSB1bmlxdWUuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgTGlzdDxFPiBleHRlbmRzIENvbGxlY3Rpb248RT4geworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBvYmplY3QgaW50byB0aGlzIHtAY29kZSBMaXN0fSBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uLgorICAgICAqIFRoZSBvYmplY3QgaXMgaW5zZXJ0ZWQgYmVmb3JlIHRoZSBjdXJyZW50IGVsZW1lbnQgYXQgdGhlIHNwZWNpZmllZAorICAgICAqIGxvY2F0aW9uLiBJZiB0aGUgbG9jYXRpb24gaXMgZXF1YWwgdG8gdGhlIHNpemUgb2YgdGhpcyB7QGNvZGUgTGlzdH0sIHRoZSBvYmplY3QKKyAgICAgKiBpcyBhZGRlZCBhdCB0aGUgZW5kLiBJZiB0aGUgbG9jYXRpb24gaXMgc21hbGxlciB0aGFuIHRoZSBzaXplIG9mIHRoaXMKKyAgICAgKiB7QGNvZGUgTGlzdH0sIHRoZW4gYWxsIGVsZW1lbnRzIGJleW9uZCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uIGFyZSBtb3ZlZCBieSBvbmUKKyAgICAgKiBwb3NpdGlvbiB0b3dhcmRzIHRoZSBlbmQgb2YgdGhlIHtAY29kZSBMaXN0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGF0IHdoaWNoIHRvIGluc2VydC4KKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFkZC4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYWRkaW5nIHRvIHRoaXMge0Bjb2RlIExpc3R9IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgY2xhc3Mgb2YgdGhlIG9iamVjdCBpcyBpbmFwcHJvcHJpYXRlIGZvciB0aGlzCisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIExpc3R9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBjYW5ub3QgYmUgYWRkZWQgdG8gdGhpcyB7QGNvZGUgTGlzdH0uCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGxvY2F0aW9uIDwgMCB8fCBsb2NhdGlvbiA+IHNpemUoKX0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGQoaW50IGxvY2F0aW9uLCBFIG9iamVjdCk7CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGF0IHRoZSBlbmQgb2YgdGhpcyB7QGNvZGUgTGlzdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFkZC4KKyAgICAgKiBAcmV0dXJuIGFsd2F5cyB0cnVlLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBhZGRpbmcgdG8gdGhpcyB7QGNvZGUgTGlzdH0gaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSBjbGFzcyBvZiB0aGUgb2JqZWN0IGlzIGluYXBwcm9wcmlhdGUgZm9yIHRoaXMKKyAgICAgKiAgICAgICAgICAgICAgICB7QGNvZGUgTGlzdH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgb2JqZWN0IGNhbm5vdCBiZSBhZGRlZCB0byB0aGlzIHtAY29kZSBMaXN0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBhZGQoRSBvYmplY3QpOworCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgb2JqZWN0cyBpbiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gYXQgdGhlIHNwZWNpZmllZCBsb2NhdGlvbgorICAgICAqIGluIHRoaXMge0Bjb2RlIExpc3R9LiBUaGUgb2JqZWN0cyBhcmUgYWRkZWQgaW4gdGhlIG9yZGVyIHRoZXkgYXJlIHJldHVybmVkIGZyb20KKyAgICAgKiB0aGUgY29sbGVjdGlvbidzIGl0ZXJhdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2F0aW9uCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggYXQgd2hpY2ggdG8gaW5zZXJ0LgorICAgICAqIEBwYXJhbSBjb2xsZWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgY29sbGVjdGlvbiBvZiBvYmplY3RzIHRvIGJlIGluc2VydGVkLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIHtAY29kZSBMaXN0fSBoYXMgYmVlbiBtb2RpZmllZCB0aHJvdWdoIHRoZSBpbnNlcnRpb24sIGZhbHNlCisgICAgICogICAgICAgICBvdGhlcndpc2UgKGkuZS4gaWYgdGhlIHBhc3NlZCBjb2xsZWN0aW9uIHdhcyBlbXB0eSkuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGFkZGluZyB0byB0aGlzIHtAY29kZSBMaXN0fSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIGFuIG9iamVjdCBpcyBpbmFwcHJvcHJpYXRlIGZvciB0aGlzCisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIExpc3R9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW4gb2JqZWN0IGNhbm5vdCBiZSBhZGRlZCB0byB0aGlzIHtAY29kZSBMaXN0fS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgbG9jYXRpb24gPCAwIHx8ID4gc2l6ZSgpfQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGFkZEFsbChpbnQgbG9jYXRpb24sIENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGNvbGxlY3Rpb24pOworCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgb2JqZWN0cyBpbiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gdG8gdGhlIGVuZCBvZiB0aGlzIHtAY29kZSBMaXN0fS4gVGhlCisgICAgICogb2JqZWN0cyBhcmUgYWRkZWQgaW4gdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlIHJldHVybmVkIGZyb20gdGhlCisgICAgICogY29sbGVjdGlvbidzIGl0ZXJhdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIG9mIG9iamVjdHMuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgTGlzdH0gaXMgbW9kaWZpZWQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICogICAgICAgICAoaS5lLiBpZiB0aGUgcGFzc2VkIGNvbGxlY3Rpb24gd2FzIGVtcHR5KS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYWRkaW5nIHRvIHRoaXMge0Bjb2RlIExpc3R9IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgY2xhc3Mgb2YgYW4gb2JqZWN0IGlzIGluYXBwcm9wcmlhdGUgZm9yIHRoaXMKKyAgICAgKiAgICAgICAgICAgICAgICB7QGNvZGUgTGlzdH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBhbiBvYmplY3QgY2Fubm90IGJlIGFkZGVkIHRvIHRoaXMge0Bjb2RlIExpc3R9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGFkZEFsbChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjb2xsZWN0aW9uKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIGVsZW1lbnRzIGZyb20gdGhpcyB7QGNvZGUgTGlzdH0sIGxlYXZpbmcgaXQgZW1wdHkuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcmVtb3ZpbmcgZnJvbSB0aGlzIHtAY29kZSBMaXN0fSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqIEBzZWUgI2lzRW1wdHkKKyAgICAgKiBAc2VlICNzaXplCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXIoKTsKKworICAgIC8qKgorICAgICAqIFRlc3RzIHdoZXRoZXIgdGhpcyB7QGNvZGUgTGlzdH0gY29udGFpbnMgdGhlIHNwZWNpZmllZCBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIHNlYXJjaCBmb3IuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgb2JqZWN0IGlzIGFuIGVsZW1lbnQgb2YgdGhpcyB7QGNvZGUgTGlzdH0sIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvYmplY3QpOworCisgICAgLyoqCisgICAgICogVGVzdHMgd2hldGhlciB0aGlzIHtAY29kZSBMaXN0fSBjb250YWlucyBhbGwgb2JqZWN0cyBjb250YWluZWQgaW4gdGhlCisgICAgICogc3BlY2lmaWVkIGNvbGxlY3Rpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cworICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGFsbCBvYmplY3RzIGluIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiBhcmUKKyAgICAgKiAgICAgICAgIGVsZW1lbnRzIG9mIHRoaXMge0Bjb2RlIExpc3R9LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0FsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pOworCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIGdpdmVuIG9iamVjdCB3aXRoIHRoZSB7QGNvZGUgTGlzdH0sIGFuZCByZXR1cm5zIHRydWUgaWYgdGhleQorICAgICAqIHJlcHJlc2VudCB0aGUgPGVtPnNhbWU8L2VtPiBvYmplY3QgdXNpbmcgYSBjbGFzcyBzcGVjaWZpYyBjb21wYXJpc29uLiBGb3IKKyAgICAgKiB7QGNvZGUgTGlzdH1zLCB0aGlzIG1lYW5zIHRoYXQgdGhleSBjb250YWluIHRoZSBzYW1lIGVsZW1lbnRzIGluIGV4YWN0bHkgdGhlIHNhbWUKKyAgICAgKiBvcmRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB3aXRoIHRoaXMgb2JqZWN0LgorICAgICAqIEByZXR1cm4gYm9vbGVhbiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIG9iamVjdCBpcyB0aGUgc2FtZSBhcyB0aGlzIG9iamVjdCwKKyAgICAgKiAgICAgICAgIGFuZCB7QGNvZGUgZmFsc2V9IGlmIGl0IGlzIGRpZmZlcmVudCBmcm9tIHRoaXMgb2JqZWN0LgorICAgICAqIEBzZWUgI2hhc2hDb2RlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZWxlbWVudCBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uIGluIHRoaXMge0Bjb2RlIExpc3R9LgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2F0aW9uCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgorICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnQgYXQgdGhlIHNwZWNpZmllZCBsb2NhdGlvbi4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgbG9jYXRpb24gPCAwIHx8ID49IHNpemUoKX0KKyAgICAgKi8KKyAgICBwdWJsaWMgRSBnZXQoaW50IGxvY2F0aW9uKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhhc2ggY29kZSBmb3IgdGhpcyB7QGNvZGUgTGlzdH0uIEl0IGlzIGNhbGN1bGF0ZWQgYnkgdGFraW5nIGVhY2gKKyAgICAgKiBlbGVtZW50JyBoYXNoY29kZSBhbmQgaXRzIHBvc2l0aW9uIGluIHRoZSB7QGNvZGUgTGlzdH0gaW50byBhY2NvdW50LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIG9mIHRoZSB7QGNvZGUgTGlzdH0uCisgICAgICovCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpOworCisgICAgLyoqCisgICAgICogU2VhcmNoZXMgdGhpcyB7QGNvZGUgTGlzdH0gZm9yIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFuZCByZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUKKyAgICAgKiBmaXJzdCBvY2N1cnJlbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBzZWFyY2ggZm9yLgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3Qgb3IgLTEgaWYgdGhlCisgICAgICogICAgICAgICBvYmplY3Qgd2FzIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGluZGV4T2YoT2JqZWN0IG9iamVjdCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyB7QGNvZGUgTGlzdH0gY29udGFpbnMgbm8gZWxlbWVudHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBMaXN0fSBoYXMgbm8gZWxlbWVudHMsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNzaXplCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpdGVyYXRvciBvbiB0aGUgZWxlbWVudHMgb2YgdGhpcyB7QGNvZGUgTGlzdH0uIFRoZSBlbGVtZW50cyBhcmUKKyAgICAgKiBpdGVyYXRlZCBpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGV5IG9jY3VyIGluIHRoZSB7QGNvZGUgTGlzdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGl0ZXJhdG9yIG9uIHRoZSBlbGVtZW50cyBvZiB0aGlzIHtAY29kZSBMaXN0fS4KKyAgICAgKiBAc2VlIEl0ZXJhdG9yCisgICAgICovCisgICAgcHVibGljIEl0ZXJhdG9yPEU+IGl0ZXJhdG9yKCk7CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyB0aGlzIHtAY29kZSBMaXN0fSBmb3IgdGhlIHNwZWNpZmllZCBvYmplY3QgYW5kIHJldHVybnMgdGhlIGluZGV4IG9mIHRoZQorICAgICAqIGxhc3Qgb2NjdXJyZW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gc2VhcmNoIGZvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3QsIG9yIC0xIGlmIHRoZQorICAgICAqICAgICAgICAgb2JqZWN0IHdhcyBub3QgZm91bmQuCisgICAgICovCisgICAgcHVibGljIGludCBsYXN0SW5kZXhPZihPYmplY3Qgb2JqZWN0KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgTGlzdH0gaXRlcmF0b3Igb24gdGhlIGVsZW1lbnRzIG9mIHRoaXMge0Bjb2RlIExpc3R9LiBUaGUgZWxlbWVudHMgYXJlCisgICAgICogaXRlcmF0ZWQgaW4gdGhlIHNhbWUgb3JkZXIgdGhhdCB0aGV5IG9jY3VyIGluIHRoZSB7QGNvZGUgTGlzdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIExpc3R9IGl0ZXJhdG9yIG9uIHRoZSBlbGVtZW50cyBvZiB0aGlzIHtAY29kZSBMaXN0fQorICAgICAqCisgICAgICogQHNlZSBMaXN0SXRlcmF0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdEl0ZXJhdG9yPEU+IGxpc3RJdGVyYXRvcigpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGxpc3QgaXRlcmF0b3Igb24gdGhlIGVsZW1lbnRzIG9mIHRoaXMge0Bjb2RlIExpc3R9LiBUaGUgZWxlbWVudHMgYXJlCisgICAgICogaXRlcmF0ZWQgaW4gdGhlIHNhbWUgb3JkZXIgYXMgdGhleSBvY2N1ciBpbiB0aGUge0Bjb2RlIExpc3R9LiBUaGUgaXRlcmF0aW9uCisgICAgICogc3RhcnRzIGF0IHRoZSBzcGVjaWZpZWQgbG9jYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhdCB3aGljaCB0byBzdGFydCB0aGUgaXRlcmF0aW9uLgorICAgICAqIEByZXR1cm4gYSBsaXN0IGl0ZXJhdG9yIG9uIHRoZSBlbGVtZW50cyBvZiB0aGlzIHtAY29kZSBMaXN0fS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgbG9jYXRpb24gPCAwIHx8IGxvY2F0aW9uID4gc2l6ZSgpfQorICAgICAqIEBzZWUgTGlzdEl0ZXJhdG9yCisgICAgICovCisgICAgcHVibGljIExpc3RJdGVyYXRvcjxFPiBsaXN0SXRlcmF0b3IoaW50IGxvY2F0aW9uKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIG9iamVjdCBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uIGZyb20gdGhpcyB7QGNvZGUgTGlzdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgb2JqZWN0IHRvIHJlbW92ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSByZW1vdmVkIG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcmVtb3ZpbmcgZnJvbSB0aGlzIHtAY29kZSBMaXN0fSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBsb2NhdGlvbiA8IDAgfHwgPj0gc2l6ZSgpfQorICAgICAqLworICAgIHB1YmxpYyBFIHJlbW92ZShpbnQgbG9jYXRpb24pOworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBmcm9tIHRoaXMge0Bjb2RlIExpc3R9LgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byByZW1vdmUuCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMge0Bjb2RlIExpc3R9IHdhcyBtb2RpZmllZCBieSB0aGlzIG9wZXJhdGlvbiwgZmFsc2UKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcmVtb3ZpbmcgZnJvbSB0aGlzIHtAY29kZSBMaXN0fSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3Qgb2JqZWN0KTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIG9jY3VycmVuY2VzIGluIHRoaXMge0Bjb2RlIExpc3R9IG9mIGVhY2ggb2JqZWN0IGluIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjb2xsZWN0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIG9mIG9iamVjdHMgdG8gcmVtb3ZlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMge0Bjb2RlIExpc3R9IGlzIG1vZGlmaWVkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcmVtb3ZpbmcgZnJvbSB0aGlzIHtAY29kZSBMaXN0fSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZUFsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pOworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhbGwgb2JqZWN0cyBmcm9tIHRoaXMge0Bjb2RlIExpc3R9IHRoYXQgYXJlIG5vdCBjb250YWluZWQgaW4gdGhlCisgICAgICogc3BlY2lmaWVkIGNvbGxlY3Rpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cyB0byByZXRhaW4uCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgTGlzdH0gaXMgbW9kaWZpZWQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiByZW1vdmluZyBmcm9tIHRoaXMge0Bjb2RlIExpc3R9IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmV0YWluQWxsKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbik7CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyB0aGUgZWxlbWVudCBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uIGluIHRoaXMge0Bjb2RlIExpc3R9IHdpdGggdGhlCisgICAgICogc3BlY2lmaWVkIG9iamVjdC4gVGhpcyBvcGVyYXRpb24gZG9lcyBub3QgY2hhbmdlIHRoZSBzaXplIG9mIHRoZSB7QGNvZGUgTGlzdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhdCB3aGljaCB0byBwdXQgdGhlIHNwZWNpZmllZCBvYmplY3QuCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBpbnNlcnQuCisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgZWxlbWVudCBhdCB0aGUgaW5kZXguCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHJlcGxhY2luZyBlbGVtZW50cyBpbiB0aGlzIHtAY29kZSBMaXN0fSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIGFuIG9iamVjdCBpcyBpbmFwcHJvcHJpYXRlIGZvciB0aGlzCisgICAgICogICAgICAgICAgICAgICAge0Bjb2RlIExpc3R9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW4gb2JqZWN0IGNhbm5vdCBiZSBhZGRlZCB0byB0aGlzIHtAY29kZSBMaXN0fS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgbG9jYXRpb24gPCAwIHx8ID49IHNpemUoKX0KKyAgICAgKi8KKyAgICBwdWJsaWMgRSBzZXQoaW50IGxvY2F0aW9uLCBFIG9iamVjdCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyB7QGNvZGUgTGlzdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyB7QGNvZGUgTGlzdH0uCisgICAgICovCisgICAgcHVibGljIGludCBzaXplKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIExpc3R9IG9mIHRoZSBzcGVjaWZpZWQgcG9ydGlvbiBvZiB0aGlzIHtAY29kZSBMaXN0fSBmcm9tIHRoZSBnaXZlbiBzdGFydAorICAgICAqIGluZGV4IHRvIHRoZSBlbmQgaW5kZXggbWludXMgb25lLiBUaGUgcmV0dXJuZWQge0Bjb2RlIExpc3R9IGlzIGJhY2tlZCBieSB0aGlzCisgICAgICoge0Bjb2RlIExpc3R9IHNvIGNoYW5nZXMgdG8gaXQgYXJlIHJlZmxlY3RlZCBieSB0aGUgb3RoZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhdCB3aGljaCB0byBzdGFydCB0aGUgc3VibGlzdC4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb25lIHBhc3QgdGhlIGVuZCBvZiB0aGUgc3VibGlzdC4KKyAgICAgKiBAcmV0dXJuIGEgbGlzdCBvZiBhIHBvcnRpb24gb2YgdGhpcyB7QGNvZGUgTGlzdH0uCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0IDwgMCwgc3RhcnQgPiBlbmR9IG9yIHtAY29kZSBlbmQgPgorICAgICAqICAgICAgICAgICAgICAgIHNpemUoKX0KKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxFPiBzdWJMaXN0KGludCBzdGFydCwgaW50IGVuZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcgYWxsIGVsZW1lbnRzIGNvbnRhaW5lZCBpbiB0aGlzIHtAY29kZSBMaXN0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgdGhlIGVsZW1lbnRzIGZyb20gdGhpcyB7QGNvZGUgTGlzdH0uCisgICAgICovCisgICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgZWxlbWVudHMgY29udGFpbmVkIGluIHRoaXMge0Bjb2RlIExpc3R9LiBJZiB0aGUKKyAgICAgKiBzcGVjaWZpZWQgYXJyYXkgaXMgbGFyZ2UgZW5vdWdoIHRvIGhvbGQgdGhlIGVsZW1lbnRzLCB0aGUgc3BlY2lmaWVkIGFycmF5CisgICAgICogaXMgdXNlZCwgb3RoZXJ3aXNlIGFuIGFycmF5IG9mIHRoZSBzYW1lIHR5cGUgaXMgY3JlYXRlZC4gSWYgdGhlIHNwZWNpZmllZAorICAgICAqIGFycmF5IGlzIHVzZWQgYW5kIGlzIGxhcmdlciB0aGFuIHRoaXMge0Bjb2RlIExpc3R9LCB0aGUgYXJyYXkgZWxlbWVudCBmb2xsb3dpbmcKKyAgICAgKiB0aGUgY29sbGVjdGlvbiBlbGVtZW50cyBpcyBzZXQgdG8gbnVsbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheQorICAgICAqICAgICAgICAgICAgdGhlIGFycmF5LgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgdGhlIGVsZW1lbnRzIGZyb20gdGhpcyB7QGNvZGUgTGlzdH0uCisgICAgICogQHRocm93cyBBcnJheVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHR5cGUgb2YgYW4gZWxlbWVudCBpbiB0aGlzIHtAY29kZSBMaXN0fSBjYW5ub3QgYmUgc3RvcmVkCisgICAgICogICAgICAgICAgICAgICAgaW4gdGhlIHR5cGUgb2YgdGhlIHNwZWNpZmllZCBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgPFQ+IFRbXSB0b0FycmF5KFRbXSBhcnJheSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0xpc3RJdGVyYXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9MaXN0SXRlcmF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOGRmNGU4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9MaXN0SXRlcmF0b3IuamF2YQpAQCAtMCwwICsxLDEzMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKKworLyoqCisgKiBBbiBMaXN0SXRlcmF0b3IgaXMgdXNlZCB0byBzZXF1ZW5jZSBvdmVyIGEgTGlzdCBvZiBvYmplY3RzLiBMaXN0SXRlcmF0b3IgY2FuCisgKiBtb3ZlIGJhY2t3YXJkcyBvciBmb3J3YXJkcyB0aHJvdWdoIHRoZSBsaXN0LgorICovCitwdWJsaWMgaW50ZXJmYWNlIExpc3RJdGVyYXRvcjxFPiBleHRlbmRzIEl0ZXJhdG9yPEU+IHsKKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBvYmplY3QgaW50byB0aGUgbGlzdCBiZXR3ZWVuIHtAY29kZSBuZXh0fSBhbmQKKyAgICAgKiB7QGNvZGUgcHJldmlvdXN9LiBUaGUgb2JqZWN0IGluc2VydGVkIHdpbGwgYmUgdGhlIHByZXZpb3VzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gaW5zZXJ0LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhZGRpbmcgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgbGlzdCBiZWluZyBpdGVyYXRlZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjbGFzcyBvZiB0aGUgb2JqZWN0IGlzIGluYXBwcm9wcmlhdGUgZm9yIHRoZSBsaXN0LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG9iamVjdCBjYW5ub3QgYmUgYWRkZWQgdG8gdGhlIGxpc3QuCisgICAgICovCisgICAgdm9pZCBhZGQoRSBvYmplY3QpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZXJlIGFyZSBtb3JlIGVsZW1lbnRzIHRvIGl0ZXJhdGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGVyZSBhcmUgbW9yZSBlbGVtZW50cywge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNlZSAjbmV4dAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGVyZSBhcmUgcHJldmlvdXMgZWxlbWVudHMgdG8gaXRlcmF0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZXJlIGFyZSBwcmV2aW91cyBlbGVtZW50cywge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgI3ByZXZpb3VzCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzUHJldmlvdXMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgb2JqZWN0IGluIHRoZSBpdGVyYXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBhcmUgbm8gbW9yZSBlbGVtZW50cy4KKyAgICAgKiBAc2VlICNoYXNOZXh0CisgICAgICovCisgICAgcHVibGljIEUgbmV4dCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG5leHQgb2JqZWN0IGluIHRoZSBpdGVyYXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBvYmplY3QsIG9yIHRoZSBzaXplIG9mIHRoZSBsaXN0IGlmIHRoZQorICAgICAqICAgICAgICAgaXRlcmF0b3IgaXMgYXQgdGhlIGVuZC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBhcmUgbm8gbW9yZSBlbGVtZW50cy4KKyAgICAgKiBAc2VlICNuZXh0CisgICAgICovCisgICAgcHVibGljIGludCBuZXh0SW5kZXgoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByZXZpb3VzIG9iamVjdCBpbiB0aGUgaXRlcmF0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgb2JqZWN0LgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGFyZSBubyBwcmV2aW91cyBlbGVtZW50cy4KKyAgICAgKiBAc2VlICNoYXNQcmV2aW91cworICAgICAqLworICAgIHB1YmxpYyBFIHByZXZpb3VzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgcHJldmlvdXMgb2JqZWN0IGluIHRoZSBpdGVyYXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgcHJldmlvdXMgb2JqZWN0LCBvciAtMSBpZiB0aGUgaXRlcmF0b3IgaXMgYXQgdGhlCisgICAgICogICAgICAgICBiZWdpbm5pbmcuCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgYXJlIG5vIHByZXZpb3VzIGVsZW1lbnRzLgorICAgICAqIEBzZWUgI3ByZXZpb3VzCisgICAgICovCisgICAgcHVibGljIGludCBwcmV2aW91c0luZGV4KCk7CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBsYXN0IG9iamVjdCByZXR1cm5lZCBieSB7QGNvZGUgbmV4dH0gb3Ige0Bjb2RlIHByZXZpb3VzfSBmcm9tCisgICAgICogdGhlIGxpc3QuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgcmVtb3ZpbmcgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgbGlzdCBiZWluZyBpdGVyYXRlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBuZXh0fSBvciB7QGNvZGUgcHJldmlvdXN9IGhhdmUgbm90IGJlZW4gY2FsbGVkLCBvcgorICAgICAqICAgICAgICAgICAgIHtAY29kZSByZW1vdmV9IG9yIHtAY29kZSBhZGR9IGhhdmUgYWxyZWFkeSBiZWVuIGNhbGxlZCBhZnRlcgorICAgICAqICAgICAgICAgICAgIHRoZSBsYXN0IGNhbGwgdG8ge0Bjb2RlIG5leHR9IG9yIHtAY29kZSBwcmV2aW91c30uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyB0aGUgbGFzdCBvYmplY3QgcmV0dXJuZWQgYnkge0Bjb2RlIG5leHR9IG9yIHtAY29kZSBwcmV2aW91c30KKyAgICAgKiB3aXRoIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBzZXQuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHNldHRpbmcgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgbGlzdCBiZWluZyBpdGVyYXRlZAorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIHRoZSBvYmplY3QgaXMgaW5hcHByb3ByaWF0ZSBmb3IgdGhlIGxpc3QuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgb2JqZWN0IGNhbm5vdCBiZSBhZGRlZCB0byB0aGUgbGlzdC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBuZXh0fSBvciB7QGNvZGUgcHJldmlvdXN9IGhhdmUgbm90IGJlZW4gY2FsbGVkLCBvcgorICAgICAqICAgICAgICAgICAgIHtAY29kZSByZW1vdmV9IG9yIHtAY29kZSBhZGR9IGhhdmUgYWxyZWFkeSBiZWVuIGNhbGxlZCBhZnRlcgorICAgICAqICAgICAgICAgICAgIHRoZSBsYXN0IGNhbGwgdG8ge0Bjb2RlIG5leHR9IG9yIHtAY29kZSBwcmV2aW91c30uCisgICAgICovCisgICAgdm9pZCBzZXQoRSBvYmplY3QpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9MaXN0UmVzb3VyY2VCdW5kbGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTGlzdFJlc291cmNlQnVuZGxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTUwOGI5MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTGlzdFJlc291cmNlQnVuZGxlLmphdmEKQEAgLTAsMCArMSwxMzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisvKioKKyAqIHtAY29kZSBMaXN0UmVzb3VyY2VCdW5kbGV9IGlzIHRoZSBhYnN0cmFjdCBzdXBlcmNsYXNzIG9mIGNsYXNzZXMgd2hpY2ggcHJvdmlkZQorICogcmVzb3VyY2VzIGJ5IGltcGxlbWVudGluZyB0aGUge0Bjb2RlIGdldENvbnRlbnRzKCl9IG1ldGhvZCB0byByZXR1cm4KKyAqIHRoZSBsaXN0IG9mIHJlc291cmNlcy4KKyAqCisgKiBAc2VlIFJlc291cmNlQnVuZGxlCisgKiBAc2luY2UgMS4xCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBMaXN0UmVzb3VyY2VCdW5kbGUgZXh0ZW5kcyBSZXNvdXJjZUJ1bmRsZSB7CisgICAgSGFzaE1hcDxTdHJpbmcsIE9iamVjdD4gdGFibGU7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIExpc3RSZXNvdXJjZUJ1bmRsZSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIHtAY29kZSBPYmplY3R9IGFycmF5IGNvbnRhaW5pbmcgdGhlIHJlc291cmNlcyBvZiB0aGlzCisgICAgICoge0Bjb2RlIExpc3RSZXNvdXJjZUJ1bmRsZX0uIEVhY2ggZWxlbWVudCBpbiB0aGUgYXJyYXkgaXMgYW4gYXJyYXkgb2YgdHdvCisgICAgICogZWxlbWVudHMsIHRoZSBmaXJzdCBpcyB0aGUgcmVzb3VyY2Uga2V5IHN0cmluZyBhbmQgdGhlIHNlY29uZCBpcyB0aGUKKyAgICAgKiByZXNvdXJjZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgT2JqZWN0fSBhcnJheSBjb250YWluaW5nIHRoZSByZXNvdXJjZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IE9iamVjdFtdW10gZ2V0Q29udGVudHMoKTsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGdldEtleXMoKSB7CisgICAgICAgIGluaXRpYWxpemVUYWJsZSgpOworICAgICAgICBpZiAocGFyZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgRW51bWVyYXRpb248U3RyaW5nPigpIHsKKyAgICAgICAgICAgICAgICBJdGVyYXRvcjxTdHJpbmc+IGxvY2FsID0gdGFibGUua2V5U2V0KCkuaXRlcmF0b3IoKTsKKworICAgICAgICAgICAgICAgIEVudW1lcmF0aW9uPFN0cmluZz4gcEVudW0gPSBwYXJlbnQuZ2V0S2V5cygpOworCisgICAgICAgICAgICAgICAgU3RyaW5nIG5leHRFbGVtZW50OworCisgICAgICAgICAgICAgICAgcHJpdmF0ZSBib29sZWFuIGZpbmROZXh0KCkgeworICAgICAgICAgICAgICAgICAgICBpZiAobmV4dEVsZW1lbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHBFbnVtLmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmV4dCA9IHBFbnVtLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRhYmxlLmNvbnRhaW5zS2V5KG5leHQpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dEVsZW1lbnQgPSBuZXh0OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNNb3JlRWxlbWVudHMoKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChsb2NhbC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmaW5kTmV4dCgpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgbmV4dEVsZW1lbnQoKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChsb2NhbC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbC5uZXh0KCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmROZXh0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSBuZXh0RWxlbWVudDsKKyAgICAgICAgICAgICAgICAgICAgICAgIG5leHRFbGVtZW50ID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgLy8gQ2F1c2UgYW4gZXhjZXB0aW9uCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBwRW51bS5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEVudW1lcmF0aW9uPFN0cmluZz4oKSB7CisgICAgICAgICAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBpdCA9IHRhYmxlLmtleVNldCgpLml0ZXJhdG9yKCk7CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNNb3JlRWxlbWVudHMoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpdC5oYXNOZXh0KCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcHVibGljIFN0cmluZyBuZXh0RWxlbWVudCgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0Lm5leHQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9OworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIE9iamVjdCBoYW5kbGVHZXRPYmplY3QoU3RyaW5nIGtleSkgeworICAgICAgICBpbml0aWFsaXplVGFibGUoKTsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGFibGUuZ2V0KGtleSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCBpbml0aWFsaXplVGFibGUoKSB7CisgICAgICAgIGlmICh0YWJsZSA9PSBudWxsKSB7CisgICAgICAgICAgICBPYmplY3RbXVtdIGNvbnRlbnRzID0gZ2V0Q29udGVudHMoKTsKKyAgICAgICAgICAgIHRhYmxlID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBPYmplY3Q+KGNvbnRlbnRzLmxlbmd0aCAvIDMgKiA0ICsgMyk7CisgICAgICAgICAgICBmb3IgKE9iamVjdFtdIGNvbnRlbnQgOiBjb250ZW50cykgeworICAgICAgICAgICAgICAgIGlmIChjb250ZW50WzBdID09IG51bGwgfHwgY29udGVudFsxXSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0YWJsZS5wdXQoKFN0cmluZykgY29udGVudFswXSwgY29udGVudFsxXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc2V0IG9mIHRoZSBrZXlzIGluIHRoaXMgUmVzb3VyY2VCdW5kbGUgYnV0IG5vdCBpbiBpdHMgcGFyZW50cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzZXQgb2YgdGhlIGtleXMgaW4gdGhpcyBSZXNvdXJjZUJ1bmRsZSBidXQgbm90IGluIGl0cyBwYXJlbnRzLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU2V0PFN0cmluZz4gaGFuZGxlS2V5U2V0KCkgeworICAgICAgICBpbml0aWFsaXplVGFibGUoKTsKKyAgICAgICAgcmV0dXJuIHRhYmxlLmtleVNldCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTG9jYWxlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0xvY2FsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc0MTI2Y2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL0xvY2FsZS5qYXZhCkBAIC0wLDAgKzEsNjIwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUZpZWxkOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGxpYmNvcmUuaWN1LklDVTsKKworLyoqCisgKiB7QGNvZGUgTG9jYWxlfSByZXByZXNlbnRzIGEgbGFuZ3VhZ2UvY291bnRyeS92YXJpYW50IGNvbWJpbmF0aW9uLiBMb2NhbGVzIGFyZSB1c2VkIHRvCisgKiBhbHRlciB0aGUgcHJlc2VudGF0aW9uIG9mIGluZm9ybWF0aW9uIHN1Y2ggYXMgbnVtYmVycyBvciBkYXRlcyB0byBzdWl0IHRoZSBjb252ZW50aW9ucworICogaW4gdGhlIHJlZ2lvbiB0aGV5IGRlc2NyaWJlLgorICoKKyAqIDxwPlRoZSBsYW5ndWFnZSBjb2RlcyBhcmUgdHdvLWxldHRlciBsb3dlcmNhc2UgSVNPIGxhbmd1YWdlIGNvZGVzIChzdWNoIGFzICJlbiIpIGFzIGRlZmluZWQgYnkKKyAqIDxhIGhyZWY9Imh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPXzYzOS0xIj5JU08gNjM5LTE8L2E+LgorICogVGhlIGNvdW50cnkgY29kZXMgYXJlIHR3by1sZXR0ZXIgdXBwZXJjYXNlIElTTyBjb3VudHJ5IGNvZGVzIChzdWNoIGFzICJVUyIpIGFzIGRlZmluZWQgYnkKKyAqIDxhIGhyZWY9Imh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPXzMxNjYtMV9hbHBoYS0zIj5JU08gMzE2Ni0xPC9hPi4KKyAqIFRoZSB2YXJpYW50IGNvZGVzIGFyZSB1bnNwZWNpZmllZC4KKyAqCisgKiA8cD5Ob3RlIHRoYXQgSmF2YSB1c2VzIHNldmVyYWwgZGVwcmVjYXRlZCB0d28tbGV0dGVyIGNvZGVzLiBUaGUgSGVicmV3ICgiaGUiKSBsYW5ndWFnZQorICogY29kZSBpcyByZXdyaXR0ZW4gYXMgIml3IiwgSW5kb25lc2lhbiAoImlkIikgYXMgImluIiwgYW5kIFlpZGRpc2ggKCJ5aSIpIGFzICJqaSIuIFRoaXMKKyAqIHJld3JpdGluZyBoYXBwZW5zIGV2ZW4gaWYgeW91IGNvbnN0cnVjdCB5b3VyIG93biB7QGNvZGUgTG9jYWxlfSBvYmplY3QsIG5vdCBqdXN0IGZvcgorICogaW5zdGFuY2VzIHJldHVybmVkIGJ5IHRoZSB2YXJpb3VzIGxvb2t1cCBtZXRob2RzLgorICoKKyAqIDxhIG5hbWU9ImF2YWlsYWJsZV9sb2NhbGVzIj48aDM+QXZhaWxhYmxlIGxvY2FsZXM8L2gzPjwvYT4KKyAqIDxwPlRoaXMgY2xhc3MnIGNvbnN0cnVjdG9ycyBkbyBubyBlcnJvciBjaGVja2luZy4gWW91IGNhbiBjcmVhdGUgYSB7QGNvZGUgTG9jYWxlfSBmb3IgbGFuZ3VhZ2VzCisgKiBhbmQgY291bnRyaWVzIHRoYXQgZG9uJ3QgZXhpc3QsIGFuZCB5b3UgY2FuIGNyZWF0ZSBpbnN0YW5jZXMgZm9yIGNvbWJpbmF0aW9ucyB0aGF0IGRvbid0CisgKiBleGlzdCAoc3VjaCBhcyAiZGVfVVMiIGZvciAiR2VybWFuIGFzIHNwb2tlbiBpbiB0aGUgVVMiKS4KKyAqCisgKiA8cD5Ob3RlIHRoYXQgbG9jYWxlIGRhdGEgaXMgbm90IG5lY2Vzc2FyaWx5IGF2YWlsYWJsZSBmb3IgYW55IG9mIHRoZSBsb2NhbGVzIHByZS1kZWZpbmVkIGFzCisgKiBjb25zdGFudHMgaW4gdGhpcyBjbGFzcyBleGNlcHQgZm9yIGVuX1VTLCB3aGljaCBpcyB0aGUgb25seSBsb2NhbGUgSmF2YSBndWFyYW50ZWVzIGlzIGFsd2F5cworICogYXZhaWxhYmxlLgorICoKKyAqIDxwPkl0IGlzIGFsc28gYSBtaXN0YWtlIHRvIGFzc3VtZSB0aGF0IGFsbCBkZXZpY2VzIGhhdmUgdGhlIHNhbWUgbG9jYWxlcyBhdmFpbGFibGUuCisgKiBBIGRldmljZSBzb2xkIGluIHRoZSBVUyB3aWxsIGFsbW9zdCBjZXJ0YWlubHkgc3VwcG9ydCBlbl9VUyBhbmQgZXNfVVMsIGJ1dCBub3QgbmVjZXNzYXJpbHkKKyAqIGFueSBsb2NhbGVzIHdpdGggdGhlIHNhbWUgbGFuZ3VhZ2UgYnV0IGRpZmZlcmVudCBjb3VudHJpZXMgKHN1Y2ggYXMgZW5fR0Igb3IgZXNfRVMpLAorICogbm9yIGFueSBsb2NhbGVzIGZvciBvdGhlciBsYW5ndWFnZXMgKHN1Y2ggYXMgZGVfREUpLiBUaGUgb3Bwb3NpdGUgbWF5IHdlbGwgYmUgdHJ1ZSBmb3IgYSBkZXZpY2UKKyAqIHNvbGQgaW4gRXVyb3BlLgorICoKKyAqIDxwPllvdSBjYW4gdXNlIHtAbGluayBMb2NhbGUjZ2V0RGVmYXVsdH0gdG8gZ2V0IGFuIGFwcHJvcHJpYXRlIGxvY2FsZSBmb3IgdGhlIDxpPnVzZXI8L2k+IG9mIHRoZQorICogZGV2aWNlIHlvdSdyZSBydW5uaW5nIG9uLCBvciB7QGxpbmsgTG9jYWxlI2dldEF2YWlsYWJsZUxvY2FsZXN9IHRvIGdldCBhIGxpc3Qgb2YgYWxsIHRoZSBsb2NhbGVzCisgKiBhdmFpbGFibGUgb24gdGhlIGRldmljZSB5b3UncmUgcnVubmluZyBvbi4KKyAqCisgKiA8YSBuYW1lPSJsb2NhbGVfZGF0YSI+PGgzPkxvY2FsZSBkYXRhPC9oMz48L2E+CisgKiA8cD5Ob3RlIHRoYXQgbG9jYWxlIGRhdGEgY29tZXMgc29sZWx5IGZyb20gSUNVLiBVc2VyLXN1cHBsaWVkIGxvY2FsZSBzZXJ2aWNlIHByb3ZpZGVycyAodXNpbmcKKyAqIHRoZSB7QGNvZGUgamF2YS50ZXh0LnNwaX0gb3Ige0Bjb2RlIGphdmEudXRpbC5zcGl9IG1lY2hhbmlzbXMpIGFyZSBub3Qgc3VwcG9ydGVkLgorICoKKyAqIDxwPkhlcmUgYXJlIHRoZSB2ZXJzaW9ucyBvZiBJQ1UgKGFuZCB0aGUgY29ycmVzcG9uZGluZyBDTERSIGFuZCBVbmljb2RlIHZlcnNpb25zKSB1c2VkIGluCisgKiB2YXJpb3VzIEFuZHJvaWQgcmVsZWFzZXM6CisgKiA8dGFibGUgQk9SREVSPSIxIiBXSURUSD0iMTAwJSIgQ0VMTFBBRERJTkc9IjMiIENFTExTUEFDSU5HPSIwIiBTVU1NQVJZPSIiPgorICogPHRyPjx0ZD5jdXBjYWtlL2RvbnV0L2VjbGFpcjwvdGQ+IDx0ZD5JQ1UgMy44PC90ZD4gPHRkPjxhIGhyZWY9Imh0dHA6Ly9jbGRyLnVuaWNvZGUub3JnL2luZGV4L2Rvd25sb2Fkcy9jbGRyLTEtNSI+Q0xEUiAxLjU8L2E+PC90ZD4gPHRkPjxhIGhyZWY9Imh0dHA6Ly93d3cudW5pY29kZS5vcmcvdmVyc2lvbnMvVW5pY29kZTUuMC4wLyI+VW5pY29kZSA1LjA8L2E+PC90ZD48L3RyPgorICogPHRyPjx0ZD5mcm95bzwvdGQ+ICAgICAgICAgICAgICAgIDx0ZD5JQ1UgNC4yPC90ZD4gPHRkPjxhIGhyZWY9Imh0dHA6Ly9jbGRyLnVuaWNvZGUub3JnL2luZGV4L2Rvd25sb2Fkcy9jbGRyLTEtNyI+Q0xEUiAxLjc8L2E+PC90ZD4gPHRkPjxhIGhyZWY9Imh0dHA6Ly93d3cudW5pY29kZS5vcmcvdmVyc2lvbnMvVW5pY29kZTUuMS4wLyI+VW5pY29kZSA1LjE8L2E+PC90ZD48L3RyPgorICogPHRyPjx0ZD5naW5nZXJicmVhZC9ob25leWNvbWI8L3RkPjx0ZD5JQ1UgNC40PC90ZD4gPHRkPjxhIGhyZWY9Imh0dHA6Ly9jbGRyLnVuaWNvZGUub3JnL2luZGV4L2Rvd25sb2Fkcy9jbGRyLTEtOCI+Q0xEUiAxLjg8L2E+PC90ZD4gPHRkPjxhIGhyZWY9Imh0dHA6Ly93d3cudW5pY29kZS5vcmcvdmVyc2lvbnMvVW5pY29kZTUuMi4wLyI+VW5pY29kZSA1LjI8L2E+PC90ZD48L3RyPgorICogPHRyPjx0ZD5pY2UgY3JlYW0gc2FuZHdpY2g8L3RkPjx0ZD5JQ1UgNC42PC90ZD4gPHRkPjxhIGhyZWY9Imh0dHA6Ly9jbGRyLnVuaWNvZGUub3JnL2luZGV4L2Rvd25sb2Fkcy9jbGRyLTEtOSI+Q0xEUiAxLjk8L2E+PC90ZD4gPHRkPjxhIGhyZWY9Imh0dHA6Ly93d3cudW5pY29kZS5vcmcvdmVyc2lvbnMvVW5pY29kZTYuMC4wLyI+VW5pY29kZSA2LjA8L2E+PC90ZD48L3RyPgorICogPC90YWJsZT4KKyAqCisgKiA8YSBuYW1lPSJkZWZhdWx0X2xvY2FsZSI+PGgzPkJlIHdhcnkgb2YgdGhlIGRlZmF1bHQgbG9jYWxlPC9oMz48L2E+CisgKiA8cD5Ob3RlIHRoYXQgdGhlcmUgYXJlIG1hbnkgY29udmVuaWVuY2UgbWV0aG9kcyB0aGF0IGF1dG9tYXRpY2FsbHkgdXNlIHRoZSBkZWZhdWx0IGxvY2FsZSwgYnV0CisgKiB1c2luZyB0aGVtIG1heSBsZWFkIHRvIHN1YnRsZSBidWdzLgorICoKKyAqIDxwPlRoZSBkZWZhdWx0IGxvY2FsZSBpcyBhcHByb3ByaWF0ZSBmb3IgdGFza3MgdGhhdCBpbnZvbHZlIHByZXNlbnRpbmcgZGF0YSB0byB0aGUgdXNlci4gSW4KKyAqIHRoaXMgY2FzZSwgeW91IHdhbnQgdG8gdXNlIHRoZSB1c2VyJ3MgZGF0ZS90aW1lIGZvcm1hdHMsIG51bWJlcgorICogZm9ybWF0cywgcnVsZXMgZm9yIGNvbnZlcnNpb24gdG8gbG93ZXJjYXNlLCBhbmQgc28gb24uIEluIHRoaXMgY2FzZSwgaXQncyBzYWZlIHRvIHVzZSB0aGUKKyAqIGNvbnZlbmllbmNlIG1ldGhvZHMuCisgKgorICogPHA+VGhlIGRlZmF1bHQgbG9jYWxlIGlzIDxpPm5vdDwvaT4gYXBwcm9wcmlhdGUgZm9yIG1hY2hpbmUtcmVhZGFibGUgb3V0cHV0LiBUaGUgYmVzdCBjaG9pY2UKKyAqIHRoZXJlIGlzIHVzdWFsbHkge0Bjb2RlIExvY2FsZS5VU30mbmJzcDsmbmRhc2g7IHRoaXMgbG9jYWxlIGlzIGd1YXJhbnRlZWQgdG8gYmUgYXZhaWxhYmxlIG9uIGFsbAorICogZGV2aWNlcywgYW5kIHRoZSBmYWN0IHRoYXQgaXQgaGFzIG5vIHN1cnByaXNpbmcgc3BlY2lhbCBjYXNlcyBhbmQgaXMgZnJlcXVlbnRseSB1c2VkIChlc3BlY2lhbGx5CisgKiBmb3IgY29tcHV0ZXItY29tcHV0ZXIgY29tbXVuaWNhdGlvbikgbWVhbnMgdGhhdCBpdCB0ZW5kcyB0byBiZSB0aGUgbW9zdCBlZmZpY2llbnQgY2hvaWNlIHRvby4KKyAqCisgKiA8cD5BIGNvbW1vbiBtaXN0YWtlIGlzIHRvIGltcGxpY2l0bHkgdXNlIHRoZSBkZWZhdWx0IGxvY2FsZSB3aGVuIHByb2R1Y2luZyBvdXRwdXQgbWVhbnQgdG8gYmUKKyAqIG1hY2hpbmUtcmVhZGFibGUuIFRoaXMgdGVuZHMgdG8gd29yayBvbiB0aGUgZGV2ZWxvcGVyJ3MgdGVzdCBkZXZpY2VzIChlc3BlY2lhbGx5IGJlY2F1c2Ugc28gbWFueQorICogZGV2ZWxvcGVycyB1c2UgZW5fVVMpLCBidXQgZmFpbHMgd2hlbiBydW4gb24gYSBkZXZpY2Ugd2hvc2UgdXNlciBpcyBpbiBhIG1vcmUgY29tcGxleCBsb2NhbGUuCisgKgorICogPHA+Rm9yIGV4YW1wbGUsIGlmIHlvdSdyZSBmb3JtYXR0aW5nIGludGVnZXJzIHNvbWUgbG9jYWxlcyB3aWxsIHVzZSBub24tQVNDSUkgZGVjaW1hbAorICogZGlnaXRzLiBBcyBhbm90aGVyIGV4YW1wbGUsIGlmIHlvdSdyZSBmb3JtYXR0aW5nIGZsb2F0aW5nLXBvaW50IG51bWJlcnMgc29tZSBsb2NhbGVzIHdpbGwgdXNlCisgKiB7QGNvZGUgJywnfSBhcyB0aGUgZGVjaW1hbCBwb2ludCBhbmQge0Bjb2RlICcuJ30gZm9yIGRpZ2l0IGdyb3VwaW5nLiBUaGF0J3MgY29ycmVjdCBmb3IKKyAqIGh1bWFuLXJlYWRhYmxlIG91dHB1dCwgYnV0IGxpa2VseSB0byBjYXVzZSBwcm9ibGVtcyBpZiBwcmVzZW50ZWQgdG8gYW5vdGhlcgorICogY29tcHV0ZXIgKHtAbGluayBEb3VibGUjcGFyc2VEb3VibGV9IGNhbid0IHBhcnNlIHN1Y2ggYSBudW1iZXIsIGZvciBleGFtcGxlKS4KKyAqIFlvdSBzaG91bGQgYWxzbyBiZSB3YXJ5IG9mIHRoZSB7QGxpbmsgU3RyaW5nI3RvTG93ZXJDYXNlfSBhbmQKKyAqIHtAbGluayBTdHJpbmcjdG9VcHBlckNhc2V9IG92ZXJsb2FkcyB0aGF0IGRvbid0IHRha2UgYSB7QGNvZGUgTG9jYWxlfTogaW4gVHVya2V5LCBmb3IgZXhhbXBsZSwKKyAqIHRoZSBjaGFyYWN0ZXJzIHtAY29kZSAnaSd9IGFuZCB7QGNvZGUgJ0knfSB3b24ndCBiZSBjb252ZXJ0ZWQgdG8ge0Bjb2RlICdJJ30gYW5kIHtAY29kZSAnaSd9LgorICogVGhpcyBpcyB0aGUgY29ycmVjdCBiZWhhdmlvciBmb3IgVHVya2lzaCB0ZXh0IChzdWNoIGFzIHVzZXIgaW5wdXQpLCBidXQgaW5hcHByb3ByaWF0ZSBmb3IsIHNheSwKKyAqIEhUVFAgaGVhZGVycy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIExvY2FsZSBpbXBsZW1lbnRzIENsb25lYWJsZSwgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDkxNDkwODE3NDk2MzgxNTA2MzZMOworCisgICAgLyoqCisgICAgICogTG9jYWxlIGNvbnN0YW50IGZvciBlbl9DQS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIExvY2FsZSBDQU5BREEgPSBuZXcgTG9jYWxlKHRydWUsICJlbiIsICJDQSIpOworCisgICAgLyoqCisgICAgICogTG9jYWxlIGNvbnN0YW50IGZvciBmcl9DQS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIExvY2FsZSBDQU5BREFfRlJFTkNIID0gbmV3IExvY2FsZSh0cnVlLCAiZnIiLCAiQ0EiKTsKKworICAgIC8qKgorICAgICAqIExvY2FsZSBjb25zdGFudCBmb3IgemhfQ04uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBMb2NhbGUgQ0hJTkEgPSBuZXcgTG9jYWxlKHRydWUsICJ6aCIsICJDTiIpOworCisgICAgLyoqCisgICAgICogTG9jYWxlIGNvbnN0YW50IGZvciB6aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIExvY2FsZSBDSElORVNFID0gbmV3IExvY2FsZSh0cnVlLCAiemgiLCAiIik7CisKKyAgICAvKioKKyAgICAgKiBMb2NhbGUgY29uc3RhbnQgZm9yIGVuLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTG9jYWxlIEVOR0xJU0ggPSBuZXcgTG9jYWxlKHRydWUsICJlbiIsICIiKTsKKworICAgIC8qKgorICAgICAqIExvY2FsZSBjb25zdGFudCBmb3IgZnJfRlIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBMb2NhbGUgRlJBTkNFID0gbmV3IExvY2FsZSh0cnVlLCAiZnIiLCAiRlIiKTsKKworICAgIC8qKgorICAgICAqIExvY2FsZSBjb25zdGFudCBmb3IgZnIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBMb2NhbGUgRlJFTkNIID0gbmV3IExvY2FsZSh0cnVlLCAiZnIiLCAiIik7CisKKyAgICAvKioKKyAgICAgKiBMb2NhbGUgY29uc3RhbnQgZm9yIGRlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTG9jYWxlIEdFUk1BTiA9IG5ldyBMb2NhbGUodHJ1ZSwgImRlIiwgIiIpOworCisgICAgLyoqCisgICAgICogTG9jYWxlIGNvbnN0YW50IGZvciBkZV9ERS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIExvY2FsZSBHRVJNQU5ZID0gbmV3IExvY2FsZSh0cnVlLCAiZGUiLCAiREUiKTsKKworICAgIC8qKgorICAgICAqIExvY2FsZSBjb25zdGFudCBmb3IgaXQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBMb2NhbGUgSVRBTElBTiA9IG5ldyBMb2NhbGUodHJ1ZSwgIml0IiwgIiIpOworCisgICAgLyoqCisgICAgICogTG9jYWxlIGNvbnN0YW50IGZvciBpdF9JVC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIExvY2FsZSBJVEFMWSA9IG5ldyBMb2NhbGUodHJ1ZSwgIml0IiwgIklUIik7CisKKyAgICAvKioKKyAgICAgKiBMb2NhbGUgY29uc3RhbnQgZm9yIGphX0pQLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTG9jYWxlIEpBUEFOID0gbmV3IExvY2FsZSh0cnVlLCAiamEiLCAiSlAiKTsKKworICAgIC8qKgorICAgICAqIExvY2FsZSBjb25zdGFudCBmb3IgamEuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBMb2NhbGUgSkFQQU5FU0UgPSBuZXcgTG9jYWxlKHRydWUsICJqYSIsICIiKTsKKworICAgIC8qKgorICAgICAqIExvY2FsZSBjb25zdGFudCBmb3Iga29fS1IuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBMb2NhbGUgS09SRUEgPSBuZXcgTG9jYWxlKHRydWUsICJrbyIsICJLUiIpOworCisgICAgLyoqCisgICAgICogTG9jYWxlIGNvbnN0YW50IGZvciBrby4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIExvY2FsZSBLT1JFQU4gPSBuZXcgTG9jYWxlKHRydWUsICJrbyIsICIiKTsKKworICAgIC8qKgorICAgICAqIExvY2FsZSBjb25zdGFudCBmb3IgemhfQ04uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBMb2NhbGUgUFJDID0gbmV3IExvY2FsZSh0cnVlLCAiemgiLCAiQ04iKTsKKworICAgIC8qKgorICAgICAqIExvY2FsZSBjb25zdGFudCBmb3IgdGhlIHJvb3QgbG9jYWxlLiBUaGUgcm9vdCBsb2NhbGUgaGFzIGFuIGVtcHR5IGxhbmd1YWdlLAorICAgICAqIGNvdW50cnksIGFuZCB2YXJpYW50LgorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTG9jYWxlIFJPT1QgPSBuZXcgTG9jYWxlKHRydWUsICIiLCAiIik7CisKKyAgICAvKioKKyAgICAgKiBMb2NhbGUgY29uc3RhbnQgZm9yIHpoX0NOLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTG9jYWxlIFNJTVBMSUZJRURfQ0hJTkVTRSA9IG5ldyBMb2NhbGUodHJ1ZSwgInpoIiwgIkNOIik7CisKKyAgICAvKioKKyAgICAgKiBMb2NhbGUgY29uc3RhbnQgZm9yIHpoX1RXLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTG9jYWxlIFRBSVdBTiA9IG5ldyBMb2NhbGUodHJ1ZSwgInpoIiwgIlRXIik7CisKKyAgICAvKioKKyAgICAgKiBMb2NhbGUgY29uc3RhbnQgZm9yIHpoX1RXLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTG9jYWxlIFRSQURJVElPTkFMX0NISU5FU0UgPSBuZXcgTG9jYWxlKHRydWUsICJ6aCIsICJUVyIpOworCisgICAgLyoqCisgICAgICogTG9jYWxlIGNvbnN0YW50IGZvciBlbl9HQi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIExvY2FsZSBVSyA9IG5ldyBMb2NhbGUodHJ1ZSwgImVuIiwgIkdCIik7CisKKyAgICAvKioKKyAgICAgKiBMb2NhbGUgY29uc3RhbnQgZm9yIGVuX1VTLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTG9jYWxlIFVTID0gbmV3IExvY2FsZSh0cnVlLCAiZW4iLCAiVVMiKTsKKworICAgIC8qKgorICAgICAqIFRoZSBjdXJyZW50IGRlZmF1bHQgbG9jYWxlLiBJdCBpcyB0ZW1wb3JhcmlseSBhc3NpZ25lZCB0byBVUyBiZWNhdXNlIHdlCisgICAgICogbmVlZCBhIGRlZmF1bHQgbG9jYWxlIHRvIGxvb2t1cCB0aGUgcmVhbCBkZWZhdWx0IGxvY2FsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBMb2NhbGUgZGVmYXVsdExvY2FsZSA9IFVTOworCisgICAgc3RhdGljIHsKKyAgICAgICAgU3RyaW5nIGxhbmd1YWdlID0gU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLmxhbmd1YWdlIiwgImVuIik7CisgICAgICAgIFN0cmluZyByZWdpb24gPSBTeXN0ZW0uZ2V0UHJvcGVydHkoInVzZXIucmVnaW9uIiwgIlVTIik7CisgICAgICAgIFN0cmluZyB2YXJpYW50ID0gU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLnZhcmlhbnQiLCAiIik7CisgICAgICAgIGRlZmF1bHRMb2NhbGUgPSBuZXcgTG9jYWxlKGxhbmd1YWdlLCByZWdpb24sIHZhcmlhbnQpOworICAgIH0KKworICAgIHByaXZhdGUgdHJhbnNpZW50IFN0cmluZyBjb3VudHJ5Q29kZTsKKyAgICBwcml2YXRlIHRyYW5zaWVudCBTdHJpbmcgbGFuZ3VhZ2VDb2RlOworICAgIHByaXZhdGUgdHJhbnNpZW50IFN0cmluZyB2YXJpYW50Q29kZTsKKyAgICBwcml2YXRlIHRyYW5zaWVudCBTdHJpbmcgY2FjaGVkVG9TdHJpbmdSZXN1bHQ7CisKKyAgICAvKioKKyAgICAgKiBUaGVyZSdzIGEgY2lyY3VsYXIgZGVwZW5kZW5jeSBiZXR3ZWVuIHRvTG93ZXJDYXNlL3RvVXBwZXJDYXNlIGFuZAorICAgICAqIExvY2FsZS5VUy4gV29yayBhcm91bmQgdGhpcyBieSBhdm9pZGluZyB0aGVzZSBtZXRob2RzIHdoZW4gY29uc3RydWN0aW5nCisgICAgICogdGhlIGJ1aWx0LWluIGxvY2FsZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdW51c2VkIHJlcXVpcmVkIGZvciB0aGlzIGNvbnN0cnVjdG9yIHRvIGhhdmUgYSB1bmlxdWUgc2lnbmF0dXJlCisgICAgICovCisgICAgcHJpdmF0ZSBMb2NhbGUoYm9vbGVhbiB1bnVzZWQsIFN0cmluZyBsb3dlckNhc2VMYW5ndWFnZUNvZGUsIFN0cmluZyB1cHBlckNhc2VDb3VudHJ5Q29kZSkgeworICAgICAgICB0aGlzLmxhbmd1YWdlQ29kZSA9IGxvd2VyQ2FzZUxhbmd1YWdlQ29kZTsKKyAgICAgICAgdGhpcy5jb3VudHJ5Q29kZSA9IHVwcGVyQ2FzZUNvdW50cnlDb2RlOworICAgICAgICB0aGlzLnZhcmlhbnRDb2RlID0gIiI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTG9jYWxlfSB1c2luZyB0aGUgc3BlY2lmaWVkIGxhbmd1YWdlLgorICAgICAqLworICAgIHB1YmxpYyBMb2NhbGUoU3RyaW5nIGxhbmd1YWdlKSB7CisgICAgICAgIHRoaXMobGFuZ3VhZ2UsICIiLCAiIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTG9jYWxlfSB1c2luZyB0aGUgc3BlY2lmaWVkIGxhbmd1YWdlIGFuZCBjb3VudHJ5IGNvZGVzLgorICAgICAqLworICAgIHB1YmxpYyBMb2NhbGUoU3RyaW5nIGxhbmd1YWdlLCBTdHJpbmcgY291bnRyeSkgeworICAgICAgICB0aGlzKGxhbmd1YWdlLCBjb3VudHJ5LCAiIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTG9jYWxlfSB1c2luZyB0aGUgc3BlY2lmaWVkIGxhbmd1YWdlLCBjb3VudHJ5LAorICAgICAqIGFuZCB2YXJpYW50IGNvZGVzLgorICAgICAqLworICAgIHB1YmxpYyBMb2NhbGUoU3RyaW5nIGxhbmd1YWdlLCBTdHJpbmcgY291bnRyeSwgU3RyaW5nIHZhcmlhbnQpIHsKKyAgICAgICAgaWYgKGxhbmd1YWdlID09IG51bGwgfHwgY291bnRyeSA9PSBudWxsIHx8IHZhcmlhbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxhbmd1YWdlLmlzRW1wdHkoKSAmJiBjb3VudHJ5LmlzRW1wdHkoKSkgeworICAgICAgICAgICAgbGFuZ3VhZ2VDb2RlID0gIiI7CisgICAgICAgICAgICBjb3VudHJ5Q29kZSA9ICIiOworICAgICAgICAgICAgdmFyaWFudENvZGUgPSB2YXJpYW50OworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgbGFuZ3VhZ2VDb2RlID0gbGFuZ3VhZ2UudG9Mb3dlckNhc2UoTG9jYWxlLlVTKTsKKyAgICAgICAgLy8gTWFwIG5ldyBsYW5ndWFnZSBjb2RlcyB0byB0aGUgb2Jzb2xldGUgbGFuZ3VhZ2UKKyAgICAgICAgLy8gY29kZXMgc28gdGhlIGNvcnJlY3QgcmVzb3VyY2UgYnVuZGxlcyB3aWxsIGJlIHVzZWQuCisgICAgICAgIGlmIChsYW5ndWFnZUNvZGUuZXF1YWxzKCJoZSIpKSB7CisgICAgICAgICAgICBsYW5ndWFnZUNvZGUgPSAiaXciOworICAgICAgICB9IGVsc2UgaWYgKGxhbmd1YWdlQ29kZS5lcXVhbHMoImlkIikpIHsKKyAgICAgICAgICAgIGxhbmd1YWdlQ29kZSA9ICJpbiI7CisgICAgICAgIH0gZWxzZSBpZiAobGFuZ3VhZ2VDb2RlLmVxdWFscygieWkiKSkgeworICAgICAgICAgICAgbGFuZ3VhZ2VDb2RlID0gImppIjsKKyAgICAgICAgfQorCisgICAgICAgIGNvdW50cnlDb2RlID0gY291bnRyeS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpOworCisgICAgICAgIC8vIFdvcmsgYXJvdW5kIGZvciBiZSBjb21wYXRpYmxlIHdpdGggUkkKKyAgICAgICAgdmFyaWFudENvZGUgPSB2YXJpYW50OworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB7QGNvZGUgb2JqZWN0fSBpcyBhIGxvY2FsZSB3aXRoIHRoZSBzYW1lIGxhbmd1YWdlLAorICAgICAqIGNvdW50cnkgYW5kIHZhcmlhbnQuCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmIChvYmplY3QgPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIExvY2FsZSkgeworICAgICAgICAgICAgTG9jYWxlIG8gPSAoTG9jYWxlKSBvYmplY3Q7CisgICAgICAgICAgICByZXR1cm4gbGFuZ3VhZ2VDb2RlLmVxdWFscyhvLmxhbmd1YWdlQ29kZSkKKyAgICAgICAgICAgICAgICAgICAgJiYgY291bnRyeUNvZGUuZXF1YWxzKG8uY291bnRyeUNvZGUpCisgICAgICAgICAgICAgICAgICAgICYmIHZhcmlhbnRDb2RlLmVxdWFscyhvLnZhcmlhbnRDb2RlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3lzdGVtJ3MgaW5zdGFsbGVkIGxvY2FsZXMuIFRoaXMgYXJyYXkgYWx3YXlzIGluY2x1ZGVzIHtAY29kZQorICAgICAqIExvY2FsZS5VU30sIGFuZCB1c3VhbGx5IHNldmVyYWwgb3RoZXJzLiBNb3N0IGxvY2FsZS1zZW5zaXRpdmUgY2xhc3NlcworICAgICAqIG9mZmVyIHRoZWlyIG93biB7QGNvZGUgZ2V0QXZhaWxhYmxlTG9jYWxlc30gbWV0aG9kLCB3aGljaCBzaG91bGQgYmUKKyAgICAgKiBwcmVmZXJyZWQgb3ZlciB0aGlzIGdlbmVyYWwgcHVycG9zZSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAc2VlIGphdmEudGV4dC5CcmVha0l0ZXJhdG9yI2dldEF2YWlsYWJsZUxvY2FsZXMoKQorICAgICAqIEBzZWUgamF2YS50ZXh0LkNvbGxhdG9yI2dldEF2YWlsYWJsZUxvY2FsZXMoKQorICAgICAqIEBzZWUgamF2YS50ZXh0LkRhdGVGb3JtYXQjZ2V0QXZhaWxhYmxlTG9jYWxlcygpCisgICAgICogQHNlZSBqYXZhLnRleHQuRGF0ZUZvcm1hdFN5bWJvbHMjZ2V0QXZhaWxhYmxlTG9jYWxlcygpCisgICAgICogQHNlZSBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdFN5bWJvbHMjZ2V0QXZhaWxhYmxlTG9jYWxlcygpCisgICAgICogQHNlZSBqYXZhLnRleHQuTnVtYmVyRm9ybWF0I2dldEF2YWlsYWJsZUxvY2FsZXMoKQorICAgICAqIEBzZWUgamF2YS51dGlsLkNhbGVuZGFyI2dldEF2YWlsYWJsZUxvY2FsZXMoKQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTG9jYWxlW10gZ2V0QXZhaWxhYmxlTG9jYWxlcygpIHsKKyAgICAgICAgcmV0dXJuIElDVS5nZXRBdmFpbGFibGVMb2NhbGVzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY291bnRyeSBjb2RlIGZvciB0aGlzIGxvY2FsZSwgb3Ige0Bjb2RlICIifSBpZiB0aGlzIGxvY2FsZQorICAgICAqIGRvZXNuJ3QgY29ycmVzcG9uZCB0byBhIHNwZWNpZmljIGNvdW50cnkuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb3VudHJ5KCkgeworICAgICAgICByZXR1cm4gY291bnRyeUNvZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdXNlcidzIHByZWZlcnJlZCBsb2NhbGUuIFRoaXMgbWF5IGhhdmUgYmVlbiBvdmVycmlkZGVuIGZvcgorICAgICAqIHRoaXMgcHJvY2VzcyB3aXRoIHtAbGluayAjc2V0RGVmYXVsdH0uCisgICAgICoKKyAgICAgKiA8cD5TaW5jZSB0aGUgdXNlcidzIGxvY2FsZSBjaGFuZ2VzIGR5bmFtaWNhbGx5LCBhdm9pZCBjYWNoaW5nIHRoaXMgdmFsdWUuCisgICAgICogSW5zdGVhZCwgdXNlIHRoaXMgbWV0aG9kIHRvIGxvb2sgaXQgdXAgZm9yIGVhY2ggdXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTG9jYWxlIGdldERlZmF1bHQoKSB7CisgICAgICAgIHJldHVybiBkZWZhdWx0TG9jYWxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8ge0Bjb2RlIGdldERpc3BsYXlDb3VudHJ5KExvY2FsZS5nZXREZWZhdWx0KCkpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldERpc3BsYXlDb3VudHJ5KCkgeworICAgICAgICByZXR1cm4gZ2V0RGlzcGxheUNvdW50cnkoZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoaXMgbG9jYWxlJ3MgY291bnRyeSwgbG9jYWxpemVkIHRvIHtAY29kZSBsb2NhbGV9LgorICAgICAqIFJldHVybnMgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGlzIGxvY2FsZSBkb2VzIG5vdCBjb3JyZXNwb25kIHRvIGEgc3BlY2lmaWMKKyAgICAgKiBjb3VudHJ5LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGlzcGxheUNvdW50cnkoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBpZiAoY291bnRyeUNvZGUuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gIiI7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IElDVS5nZXREaXNwbGF5Q291bnRyeU5hdGl2ZSh0b1N0cmluZygpLCBsb2NhbGUudG9TdHJpbmcoKSk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeyAvLyBUT0RPOiBkbyB3ZSBuZWVkIHRvIGRvIHRoaXMsIG9yIGRvZXMgSUNVIGRvIGl0IGZvciB1cz8KKyAgICAgICAgICAgIHJlc3VsdCA9IElDVS5nZXREaXNwbGF5Q291bnRyeU5hdGl2ZSh0b1N0cmluZygpLCBMb2NhbGUuZ2V0RGVmYXVsdCgpLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgZ2V0RGlzcGxheUxhbmd1YWdlKExvY2FsZS5nZXREZWZhdWx0KCkpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldERpc3BsYXlMYW5ndWFnZSgpIHsKKyAgICAgICAgcmV0dXJuIGdldERpc3BsYXlMYW5ndWFnZShnZXREZWZhdWx0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhpcyBsb2NhbGUncyBsYW5ndWFnZSwgbG9jYWxpemVkIHRvIHtAY29kZSBsb2NhbGV9LgorICAgICAqIElmIHRoZSBsYW5ndWFnZSBuYW1lIGlzIHVua25vd24sIHRoZSBsYW5ndWFnZSBjb2RlIGlzIHJldHVybmVkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGlzcGxheUxhbmd1YWdlKExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgaWYgKGxhbmd1YWdlQ29kZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gSUNVLmdldERpc3BsYXlMYW5ndWFnZU5hdGl2ZSh0b1N0cmluZygpLCBsb2NhbGUudG9TdHJpbmcoKSk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeyAvLyBUT0RPOiBkbyB3ZSBuZWVkIHRvIGRvIHRoaXMsIG9yIGRvZXMgSUNVIGRvIGl0IGZvciB1cz8KKyAgICAgICAgICAgIHJlc3VsdCA9IElDVS5nZXREaXNwbGF5TGFuZ3VhZ2VOYXRpdmUodG9TdHJpbmcoKSwgTG9jYWxlLmdldERlZmF1bHQoKS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8ge0Bjb2RlIGdldERpc3BsYXlOYW1lKExvY2FsZS5nZXREZWZhdWx0KCkpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldERpc3BsYXlOYW1lKCkgeworICAgICAgICByZXR1cm4gZ2V0RGlzcGxheU5hbWUoZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgbG9jYWxlJ3MgbGFuZ3VhZ2UgbmFtZSwgY291bnRyeSBuYW1lLCBhbmQgdmFyaWFudCwgbG9jYWxpemVkCisgICAgICogdG8ge0Bjb2RlIGxvY2FsZX0uIFRoZSBleGFjdCBvdXRwdXQgZm9ybSBkZXBlbmRzIG9uIHdoZXRoZXIgdGhpcyBsb2NhbGUKKyAgICAgKiBjb3JyZXNwb25kcyB0byBhIHNwZWNpZmljIGxhbmd1YWdlLCBjb3VudHJ5IGFuZCB2YXJpYW50LgorICAgICAqCisgICAgICogPHA+Rm9yIGV4YW1wbGU6CisgICAgICogPHVsPgorICAgICAqIDxsaT57QGNvZGUgbmV3IExvY2FsZSgiZW4iKS5nZXREaXNwbGF5TmFtZShMb2NhbGUuVVMpfSAtPiB7QGNvZGUgRW5nbGlzaH0KKyAgICAgKiA8bGk+e0Bjb2RlIG5ldyBMb2NhbGUoImVuIiwgIlVTIikuZ2V0RGlzcGxheU5hbWUoTG9jYWxlLlVTKX0gLT4ge0Bjb2RlIEVuZ2xpc2ggKFVuaXRlZCBTdGF0ZXMpfQorICAgICAqIDxsaT57QGNvZGUgbmV3IExvY2FsZSgiZW4iLCAiVVMiLCAiUE9TSVgiKS5nZXREaXNwbGF5TmFtZShMb2NhbGUuVVMpfSAtPiB7QGNvZGUgRW5nbGlzaCAoVW5pdGVkIFN0YXRlcyxDb21wdXRlcil9CisgICAgICogPGxpPntAY29kZSBuZXcgTG9jYWxlKCJlbiIpLmdldERpc3BsYXlOYW1lKExvY2FsZS5GUkFOQ0UpfSAtPiB7QGNvZGUgYW5nbGFpc30KKyAgICAgKiA8bGk+e0Bjb2RlIG5ldyBMb2NhbGUoImVuIiwgIlVTIikuZ2V0RGlzcGxheU5hbWUoTG9jYWxlLkZSQU5DRSl9IC0+IHtAY29kZSBhbmdsYWlzICjDiXRhdHMtVW5pcyl9CisgICAgICogPGxpPntAY29kZSBuZXcgTG9jYWxlKCJlbiIsICJVUyIsICJQT1NJWCIpLmdldERpc3BsYXlOYW1lKExvY2FsZS5GUkFOQ0UpfSAtPiB7QGNvZGUgYW5nbGFpcyAow4l0YXRzLVVuaXMsaW5mb3JtYXRpcXVlKX0uCisgICAgICogPC91bD4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldERpc3BsYXlOYW1lKExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBpZiAoIWxhbmd1YWdlQ29kZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIFN0cmluZyBkaXNwbGF5TGFuZ3VhZ2UgPSBnZXREaXNwbGF5TGFuZ3VhZ2UobG9jYWxlKTsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZGlzcGxheUxhbmd1YWdlLmlzRW1wdHkoKSA/IGxhbmd1YWdlQ29kZSA6IGRpc3BsYXlMYW5ndWFnZSk7CisgICAgICAgICAgICArK2NvdW50OworICAgICAgICB9CisgICAgICAgIGlmICghY291bnRyeUNvZGUuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBpZiAoY291bnQgPT0gMSkgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIiAoIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTdHJpbmcgZGlzcGxheUNvdW50cnkgPSBnZXREaXNwbGF5Q291bnRyeShsb2NhbGUpOworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChkaXNwbGF5Q291bnRyeS5pc0VtcHR5KCkgPyBjb3VudHJ5Q29kZSA6IGRpc3BsYXlDb3VudHJ5KTsKKyAgICAgICAgICAgICsrY291bnQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF2YXJpYW50Q29kZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIGlmIChjb3VudCA9PSAxKSB7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiICgiKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY291bnQgPT0gMikgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIiwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN0cmluZyBkaXNwbGF5VmFyaWFudCA9IGdldERpc3BsYXlWYXJpYW50KGxvY2FsZSk7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGRpc3BsYXlWYXJpYW50LmlzRW1wdHkoKSA/IHZhcmlhbnRDb2RlIDogZGlzcGxheVZhcmlhbnQpOworICAgICAgICAgICAgKytjb3VudDsKKyAgICAgICAgfQorICAgICAgICBpZiAoY291bnQgPiAxKSB7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCIpIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZ1bGwgdmFyaWFudCBuYW1lIGluIHRoZSBkZWZhdWx0IHtAY29kZSBMb2NhbGV9IGZvciB0aGUgdmFyaWFudCBjb2RlIG9mCisgICAgICogdGhpcyB7QGNvZGUgTG9jYWxlfS4gSWYgdGhlcmUgaXMgbm8gbWF0Y2hpbmcgdmFyaWFudCBuYW1lLCB0aGUgdmFyaWFudCBjb2RlIGlzCisgICAgICogcmV0dXJuZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXREaXNwbGF5VmFyaWFudCgpIHsKKyAgICAgICAgcmV0dXJuIGdldERpc3BsYXlWYXJpYW50KGdldERlZmF1bHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZnVsbCB2YXJpYW50IG5hbWUgaW4gdGhlIHNwZWNpZmllZCB7QGNvZGUgTG9jYWxlfSBmb3IgdGhlIHZhcmlhbnQgY29kZQorICAgICAqIG9mIHRoaXMge0Bjb2RlIExvY2FsZX0uIElmIHRoZXJlIGlzIG5vIG1hdGNoaW5nIHZhcmlhbnQgbmFtZSwgdGhlIHZhcmlhbnQgY29kZSBpcworICAgICAqIHJldHVybmVkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGlzcGxheVZhcmlhbnQoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBpZiAodmFyaWFudENvZGUubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHZhcmlhbnRDb2RlOworICAgICAgICB9CisgICAgICAgIFN0cmluZyByZXN1bHQgPSBJQ1UuZ2V0RGlzcGxheVZhcmlhbnROYXRpdmUodG9TdHJpbmcoKSwgbG9jYWxlLnRvU3RyaW5nKCkpOworICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsgLy8gVE9ETzogZG8gd2UgbmVlZCB0byBkbyB0aGlzLCBvciBkb2VzIElDVSBkbyBpdCBmb3IgdXM/CisgICAgICAgICAgICByZXN1bHQgPSBJQ1UuZ2V0RGlzcGxheVZhcmlhbnROYXRpdmUodG9TdHJpbmcoKSwgTG9jYWxlLmdldERlZmF1bHQoKS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRocmVlIGxldHRlciBJU08gY291bnRyeSBjb2RlIHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZSBjb3VudHJ5CisgICAgICogY29kZSBmb3IgdGhpcyB7QGNvZGUgTG9jYWxlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldElTTzNDb3VudHJ5KCkgeworICAgICAgICBpZiAoY291bnRyeUNvZGUubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGNvdW50cnlDb2RlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBJQ1UuZ2V0SVNPM0NvdW50cnlOYXRpdmUodG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGhyZWUgbGV0dGVyIElTTyBsYW5ndWFnZSBjb2RlIHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZSBsYW5ndWFnZQorICAgICAqIGNvZGUgZm9yIHRoaXMge0Bjb2RlIExvY2FsZX0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRJU08zTGFuZ3VhZ2UoKSB7CisgICAgICAgIGlmIChsYW5ndWFnZUNvZGUubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGxhbmd1YWdlQ29kZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gSUNVLmdldElTTzNMYW5ndWFnZU5hdGl2ZSh0b1N0cmluZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHN0cmluZ3MgY29udGFpbmluZyBhbGwgdGhlIHR3by1sZXR0ZXIgSVNPIGNvdW50cnkgY29kZXMgdGhhdCBjYW4gYmUKKyAgICAgKiB1c2VkIGFzIHRoZSBjb3VudHJ5IGNvZGUgd2hlbiBjb25zdHJ1Y3RpbmcgYSB7QGNvZGUgTG9jYWxlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZ1tdIGdldElTT0NvdW50cmllcygpIHsKKyAgICAgICAgcmV0dXJuIElDVS5nZXRJU09Db3VudHJpZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHN0cmluZ3MgY29udGFpbmluZyBhbGwgdGhlIHR3by1sZXR0ZXIgSVNPIGxhbmd1YWdlIGNvZGVzIHRoYXQgY2FuIGJlCisgICAgICogdXNlZCBhcyB0aGUgbGFuZ3VhZ2UgY29kZSB3aGVuIGNvbnN0cnVjdGluZyBhIHtAY29kZSBMb2NhbGV9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gZ2V0SVNPTGFuZ3VhZ2VzKCkgeworICAgICAgICByZXR1cm4gSUNVLmdldElTT0xhbmd1YWdlcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxhbmd1YWdlIGNvZGUgZm9yIHRoaXMge0Bjb2RlIExvY2FsZX0gb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBubyBsYW5ndWFnZQorICAgICAqIHdhcyBzZXQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRMYW5ndWFnZSgpIHsKKyAgICAgICAgcmV0dXJuIGxhbmd1YWdlQ29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YXJpYW50IGNvZGUgZm9yIHRoaXMge0Bjb2RlIExvY2FsZX0gb3IgYW4gZW1wdHkge0Bjb2RlIFN0cmluZ30gaWYgbm8gdmFyaWFudAorICAgICAqIHdhcyBzZXQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRWYXJpYW50KCkgeworICAgICAgICByZXR1cm4gdmFyaWFudENvZGU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiBjb3VudHJ5Q29kZS5oYXNoQ29kZSgpICsgbGFuZ3VhZ2VDb2RlLmhhc2hDb2RlKCkKKyAgICAgICAgICAgICAgICArIHZhcmlhbnRDb2RlLmhhc2hDb2RlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3ZlcnJpZGVzIHRoZSBkZWZhdWx0IGxvY2FsZS4gVGhpcyBkb2VzIG5vdCBhZmZlY3Qgc3lzdGVtIGNvbmZpZ3VyYXRpb24sCisgICAgICogYW5kIGF0dGVtcHRzIHRvIG92ZXJyaWRlIHRoZSBzeXN0ZW0tcHJvdmlkZWQgZGVmYXVsdCBsb2NhbGUgbWF5CisgICAgICogdGhlbXNlbHZlcyBiZSBvdmVycmlkZGVuIGJ5IGFjdHVhbCBjaGFuZ2VzIHRvIHRoZSBzeXN0ZW0gY29uZmlndXJhdGlvbi4KKyAgICAgKiBDb2RlIHRoYXQgY2FsbHMgdGhpcyBtZXRob2QgaXMgdXN1YWxseSBpbmNvcnJlY3QsIGFuZCBzaG91bGQgYmUgZml4ZWQgYnkKKyAgICAgKiBwYXNzaW5nIHRoZSBhcHByb3ByaWF0ZSBsb2NhbGUgdG8gZWFjaCBsb2NhbGUtc2Vuc2l0aXZlIG1ldGhvZCB0aGF0J3MKKyAgICAgKiBjYWxsZWQuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBzdGF0aWMgdm9pZCBzZXREZWZhdWx0KExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgaWYgKGxvY2FsZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBkZWZhdWx0TG9jYWxlID0gbG9jYWxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZSBMb2NhbGV9LiBJdCBjb25zaXN0cyBvZiB0aGUKKyAgICAgKiBsYW5ndWFnZSBjb2RlLCBjb3VudHJ5IGNvZGUgYW5kIHZhcmlhbnQgc2VwYXJhdGVkIGJ5IHVuZGVyc2NvcmVzLgorICAgICAqIElmIHRoZSBsYW5ndWFnZSBpcyBtaXNzaW5nIHRoZSBzdHJpbmcgYmVnaW5zCisgICAgICogd2l0aCBhbiB1bmRlcnNjb3JlLiBJZiB0aGUgY291bnRyeSBpcyBtaXNzaW5nIHRoZXJlIGFyZSAyIHVuZGVyc2NvcmVzCisgICAgICogYmV0d2VlbiB0aGUgbGFuZ3VhZ2UgYW5kIHRoZSB2YXJpYW50LiBUaGUgdmFyaWFudCBjYW5ub3Qgc3RhbmQgYWxvbmUKKyAgICAgKiB3aXRob3V0IGEgbGFuZ3VhZ2UgYW5kL29yIGNvdW50cnkgY29kZTogaW4gdGhpcyBjYXNlIHRoaXMgbWV0aG9kIHdvdWxkCisgICAgICogcmV0dXJuIHRoZSBlbXB0eSBzdHJpbmcuCisgICAgICoKKyAgICAgKiA8cD5FeGFtcGxlczogImVuIiwgImVuX1VTIiwgIl9VUyIsICJlbl9fUE9TSVgiLCAiZW5fVVNfUE9TSVgiCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGNhY2hlZFRvU3RyaW5nUmVzdWx0OworICAgICAgICByZXR1cm4gKHJlc3VsdCA9PSBudWxsKSA/IChjYWNoZWRUb1N0cmluZ1Jlc3VsdCA9IHRvTmV3U3RyaW5nKCkpIDogcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIHRvTmV3U3RyaW5nKCkgeworICAgICAgICAvLyBUaGUgc3RyaW5nIGZvcm0gb2YgYSBsb2NhbGUgdGhhdCBvbmx5IGhhcyBhIHZhcmlhbnQgaXMgdGhlIGVtcHR5IHN0cmluZy4KKyAgICAgICAgaWYgKGxhbmd1YWdlQ29kZS5sZW5ndGgoKSA9PSAwICYmIGNvdW50cnlDb2RlLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorICAgICAgICAvLyBPdGhlcndpc2UsIHRoZSBvdXRwdXQgZm9ybWF0IGlzICJsbF9jY192YXJpYW50Iiwgd2hlcmUgbGFuZ3VhZ2UgYW5kIGNvdW50cnkgYXJlIGFsd2F5cworICAgICAgICAvLyB0d28gbGV0dGVycywgYnV0IHRoZSB2YXJpYW50IGlzIGFuIGFyYml0cmFyeSBsZW5ndGguIEEgc2l6ZSBvZiAxMSBjaGFyYWN0ZXJzIGhhcyByb29tCisgICAgICAgIC8vIGZvciAiZW5fVVNfUE9TSVgiLCB0aGUgbGFyZ2VzdCAiY29tbW9uIiB2YWx1ZS4gKEluIHByYWN0aWNlLCB0aGUgc3RyaW5nIGZvcm0gaXMgYWxtb3N0CisgICAgICAgIC8vIGFsd2F5cyA1IGNoYXJhY3RlcnM6ICJsbF9jYyIuKQorICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKDExKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZChsYW5ndWFnZUNvZGUpOworICAgICAgICBpZiAoY291bnRyeUNvZGUubGVuZ3RoKCkgPiAwIHx8IHZhcmlhbnRDb2RlLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnXycpOworICAgICAgICB9CisgICAgICAgIHJlc3VsdC5hcHBlbmQoY291bnRyeUNvZGUpOworICAgICAgICBpZiAodmFyaWFudENvZGUubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCdfJyk7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0LmFwcGVuZCh2YXJpYW50Q29kZSk7CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RTdHJlYW1GaWVsZFtdIHNlcmlhbFBlcnNpc3RlbnRGaWVsZHMgPSB7CisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiY291bnRyeSIsIFN0cmluZy5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiaGFzaGNvZGUiLCBpbnQuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImxhbmd1YWdlIiwgU3RyaW5nLmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJ2YXJpYW50IiwgU3RyaW5nLmNsYXNzKSwKKyAgICB9OworCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdE91dHB1dFN0cmVhbS5QdXRGaWVsZCBmaWVsZHMgPSBzdHJlYW0ucHV0RmllbGRzKCk7CisgICAgICAgIGZpZWxkcy5wdXQoImNvdW50cnkiLCBjb3VudHJ5Q29kZSk7CisgICAgICAgIGZpZWxkcy5wdXQoImhhc2hjb2RlIiwgLTEpOworICAgICAgICBmaWVsZHMucHV0KCJsYW5ndWFnZSIsIGxhbmd1YWdlQ29kZSk7CisgICAgICAgIGZpZWxkcy5wdXQoInZhcmlhbnQiLCB2YXJpYW50Q29kZSk7CisgICAgICAgIHN0cmVhbS53cml0ZUZpZWxkcygpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0uR2V0RmllbGQgZmllbGRzID0gc3RyZWFtLnJlYWRGaWVsZHMoKTsKKyAgICAgICAgY291bnRyeUNvZGUgPSAoU3RyaW5nKSBmaWVsZHMuZ2V0KCJjb3VudHJ5IiwgIiIpOworICAgICAgICBsYW5ndWFnZUNvZGUgPSAoU3RyaW5nKSBmaWVsZHMuZ2V0KCJsYW5ndWFnZSIsICIiKTsKKyAgICAgICAgdmFyaWFudENvZGUgPSAoU3RyaW5nKSBmaWVsZHMuZ2V0KCJ2YXJpYW50IiwgIiIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTWFwLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL01hcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM4ZDJiYjAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL01hcC5qYXZhCkBAIC0wLDAgKzEsMjUzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworCisvKioKKyAqIEEge0Bjb2RlIE1hcH0gaXMgYSBkYXRhIHN0cnVjdHVyZSBjb25zaXN0aW5nIG9mIGEgc2V0IG9mIGtleXMgYW5kIHZhbHVlcworICogaW4gd2hpY2ggZWFjaCBrZXkgaXMgbWFwcGVkIHRvIGEgc2luZ2xlIHZhbHVlLiAgVGhlIGNsYXNzIG9mIHRoZSBvYmplY3RzCisgKiB1c2VkIGFzIGtleXMgaXMgZGVjbGFyZWQgd2hlbiB0aGUge0Bjb2RlIE1hcH0gaXMgZGVjbGFyZWQsIGFzIGlzIHRoZQorICogY2xhc3Mgb2YgdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWVzLgorICogPHA+CisgKiBBIHtAY29kZSBNYXB9IHByb3ZpZGVzIGhlbHBlciBtZXRob2RzIHRvIGl0ZXJhdGUgdGhyb3VnaCBhbGwgb2YgdGhlCisgKiBrZXlzIGNvbnRhaW5lZCBpbiBpdCwgYXMgd2VsbCBhcyB2YXJpb3VzIG1ldGhvZHMgdG8gYWNjZXNzIGFuZCB1cGRhdGUKKyAqIHRoZSBrZXkvdmFsdWUgcGFpcnMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgTWFwPEssVj4geworCisgICAgLyoqCisgICAgICoge0Bjb2RlIE1hcC5FbnRyeX0gaXMgYSBrZXkvdmFsdWUgbWFwcGluZyBjb250YWluZWQgaW4gYSB7QGNvZGUgTWFwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludGVyZmFjZSBFbnRyeTxLLFY+IHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHRvIHRoaXMge0Bjb2RlIE1hcC5FbnRyeX0gYW5kIHJldHVybnMgaWYgdGhleQorICAgICAgICAgKiBhcmUgZXF1YWwuIFRvIGJlIGVxdWFsLCB0aGUgb2JqZWN0IG11c3QgYmUgYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIE1hcC5FbnRyeX0gYW5kIGhhdmUgdGhlCisgICAgICAgICAqIHNhbWUga2V5IGFuZCB2YWx1ZS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG9iamVjdAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT2JqZWN0fSB0byBjb21wYXJlIHdpdGggdGhpcyB7QGNvZGUgT2JqZWN0fS4KKyAgICAgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCB7QGNvZGUgT2JqZWN0fSBpcyBlcXVhbCB0byB0aGlzCisgICAgICAgICAqICAgICAgICAge0Bjb2RlIE1hcC5FbnRyeX0sIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAgICAgKiBAc2VlICNoYXNoQ29kZSgpCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIGtleS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUga2V5CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgSyBnZXRLZXkoKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgdmFsdWUuCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gdGhlIHZhbHVlCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgViBnZXRWYWx1ZSgpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGFuIGludGVnZXIgaGFzaCBjb2RlIGZvciB0aGUgcmVjZWl2ZXIuIHtAY29kZSBPYmplY3R9IHdoaWNoIGFyZQorICAgICAgICAgKiBlcXVhbCByZXR1cm4gdGhlIHNhbWUgdmFsdWUgZm9yIHRoaXMgbWV0aG9kLgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIGhhc2ggY29kZS4KKyAgICAgICAgICogQHNlZSAjZXF1YWxzKE9iamVjdCkKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhpcyBlbnRyeSB0byB0aGUgc3BlY2lmaWVkIHZhbHVlLCByZXBsYWNpbmcgYW55CisgICAgICAgICAqIGV4aXN0aW5nIHZhbHVlLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSB0byBzZXQuCisgICAgICAgICAqIEByZXR1cm4gb2JqZWN0IHRoZSByZXBsYWNlZCB2YWx1ZSBvZiB0aGlzIGVudHJ5LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFYgc2V0VmFsdWUoViBvYmplY3QpOworICAgIH07CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGFsbCBlbGVtZW50cyBmcm9tIHRoaXMge0Bjb2RlIE1hcH0sIGxlYXZpbmcgaXQgZW1wdHkuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcmVtb3ZpbmcgZWxlbWVudHMgZnJvbSB0aGlzIHtAY29kZSBNYXB9IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICogQHNlZSAjaXNFbXB0eSgpCisgICAgICogQHNlZSAjc2l6ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXIoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIHtAY29kZSBNYXB9IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byBzZWFyY2ggZm9yLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgbWFwIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQga2V5LAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNLZXkoT2JqZWN0IGtleSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyB7QGNvZGUgTWFwfSBjb250YWlucyB0aGUgc3BlY2lmaWVkIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gc2VhcmNoIGZvci4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIG1hcCBjb250YWlucyB0aGUgc3BlY2lmaWVkIHZhbHVlLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNWYWx1ZShPYmplY3QgdmFsdWUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBTZXR9IGNvbnRhaW5pbmcgYWxsIG9mIHRoZSBtYXBwaW5ncyBpbiB0aGlzIHtAY29kZSBNYXB9LiBFYWNoIG1hcHBpbmcgaXMKKyAgICAgKiBhbiBpbnN0YW5jZSBvZiB7QGxpbmsgTWFwLkVudHJ5fS4gQXMgdGhlIHtAY29kZSBTZXR9IGlzIGJhY2tlZCBieSB0aGlzIHtAY29kZSBNYXB9LAorICAgICAqIGNoYW5nZXMgaW4gb25lIHdpbGwgYmUgcmVmbGVjdGVkIGluIHRoZSBvdGhlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzZXQgb2YgdGhlIG1hcHBpbmdzCisgICAgICovCisgICAgcHVibGljIFNldDxNYXAuRW50cnk8SyxWPj4gZW50cnlTZXQoKTsKKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBhcmd1bWVudCB0byB0aGUgcmVjZWl2ZXIsIGFuZCByZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGUKKyAgICAgKiBzcGVjaWZpZWQgb2JqZWN0IGlzIGEge0Bjb2RlIE1hcH0gYW5kIGJvdGgge0Bjb2RlIE1hcH1zIGNvbnRhaW4gdGhlIHNhbWUgbWFwcGluZ3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIE9iamVjdH0gdG8gY29tcGFyZSB3aXRoIHRoaXMge0Bjb2RlIE9iamVjdH0uCisgICAgICogQHJldHVybiBib29sZWFuIHtAY29kZSB0cnVlfSBpZiB0aGUge0Bjb2RlIE9iamVjdH0gaXMgdGhlIHNhbWUgYXMgdGhpcyB7QGNvZGUgT2JqZWN0fQorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBpZiBpdCBpcyBkaWZmZXJlbnQgZnJvbSB0aGlzIHtAY29kZSBPYmplY3R9LgorICAgICAqIEBzZWUgI2hhc2hDb2RlKCkKKyAgICAgKiBAc2VlICNlbnRyeVNldCgpCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIG1hcHBpbmcgd2l0aCB0aGUgc3BlY2lmaWVkIGtleS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIG1hcHBpbmcgd2l0aCB0aGUgc3BlY2lmaWVkIGtleSwgb3Ige0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpZiBubyBtYXBwaW5nIGZvciB0aGUgc3BlY2lmaWVkIGtleSBpcyBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgViBnZXQoT2JqZWN0IGtleSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGludGVnZXIgaGFzaCBjb2RlIGZvciB0aGUgcmVjZWl2ZXIuIHtAY29kZSBPYmplY3R9cyB3aGljaCBhcmUgZXF1YWwKKyAgICAgKiByZXR1cm4gdGhlIHNhbWUgdmFsdWUgZm9yIHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBoYXNoLgorICAgICAqIEBzZWUgI2VxdWFscyhPYmplY3QpCisgICAgICovCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgbWFwIGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBtYXAgaGFzIG5vIGVsZW1lbnRzLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHNlZSAjc2l6ZSgpCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNldCBvZiB0aGUga2V5cyBjb250YWluZWQgaW4gdGhpcyB7QGNvZGUgTWFwfS4gVGhlIHtAY29kZSBTZXR9IGlzIGJhY2tlZCBieQorICAgICAqIHRoaXMge0Bjb2RlIE1hcH0gc28gY2hhbmdlcyB0byBvbmUgYXJlIHJlZmxlY3RlZCBieSB0aGUgb3RoZXIuIFRoZSB7QGNvZGUgU2V0fSBkb2VzIG5vdAorICAgICAqIHN1cHBvcnQgYWRkaW5nLgorICAgICAqCisgICAgICogQHJldHVybiBhIHNldCBvZiB0aGUga2V5cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2V0PEs+IGtleVNldCgpOworCisgICAgLyoqCisgICAgICogTWFwcyB0aGUgc3BlY2lmaWVkIGtleSB0byB0aGUgc3BlY2lmaWVkIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleS4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiBhbnkgcHJldmlvdXMgbWFwcGluZyB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IG9yCisgICAgICogICAgICAgICB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgd2FzIG5vIG1hcHBpbmcuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIGFkZGluZyB0byB0aGlzIHtAY29kZSBNYXB9IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgY2xhc3Mgb2YgdGhlIGtleSBvciB2YWx1ZSBpcyBpbmFwcHJvcHJpYXRlIGZvcgorICAgICAqICAgICAgICAgICAgICAgIHRoaXMge0Bjb2RlIE1hcH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUga2V5IG9yIHZhbHVlIGNhbm5vdCBiZSBhZGRlZCB0byB0aGlzIHtAY29kZSBNYXB9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUga2V5IG9yIHZhbHVlIGlzIHtAY29kZSBudWxsfSBhbmQgdGhpcyB7QGNvZGUgTWFwfSBkb2VzCisgICAgICogICAgICAgICAgICAgICAgbm90IHN1cHBvcnQge0Bjb2RlIG51bGx9IGtleXMgb3IgdmFsdWVzLgorICAgICAqLworICAgIHB1YmxpYyBWIHB1dChLIGtleSwgViB2YWx1ZSk7CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgZXZlcnkgbWFwcGluZyBpbiB0aGUgc3BlY2lmaWVkIHtAY29kZSBNYXB9IHRvIHRoaXMge0Bjb2RlIE1hcH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWFwCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIE1hcH0gdG8gY29weSBtYXBwaW5ncyBmcm9tLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBhZGRpbmcgdG8gdGhpcyB7QGNvZGUgTWFwfSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIGEga2V5IG9yIGEgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCB7QGNvZGUgTWFwfSBpcworICAgICAqICAgICAgICAgICAgICAgIGluYXBwcm9wcmlhdGUgZm9yIHRoaXMge0Bjb2RlIE1hcH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBhIGtleSBvciB2YWx1ZSBjYW5ub3QgYmUgYWRkZWQgdG8gdGhpcyB7QGNvZGUgTWFwfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYSBrZXkgb3IgdmFsdWUgaXMge0Bjb2RlIG51bGx9IGFuZCB0aGlzIHtAY29kZSBNYXB9IGRvZXMgbm90CisgICAgICogICAgICAgICAgICAgICAgc3VwcG9ydCB7QGNvZGUgbnVsbH0ga2V5cyBvciB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHV0QWxsKE1hcDw/IGV4dGVuZHMgSyw/IGV4dGVuZHMgVj4gbWFwKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYSBtYXBwaW5nIHdpdGggdGhlIHNwZWNpZmllZCBrZXkgZnJvbSB0aGlzIHtAY29kZSBNYXB9LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBvZiB0aGUgbWFwcGluZyB0byByZW1vdmUuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHJlbW92ZWQgbWFwcGluZyBvciB7QGNvZGUgbnVsbH0gaWYgbm8gbWFwcGluZworICAgICAqICAgICAgICAgZm9yIHRoZSBzcGVjaWZpZWQga2V5IHdhcyBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgcmVtb3ZpbmcgZnJvbSB0aGlzIHtAY29kZSBNYXB9IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIFYgcmVtb3ZlKE9iamVjdCBrZXkpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIG1hcHBpbmdzIGluIHRoaXMge0Bjb2RlIE1hcH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgbWFwcGluZ3MgaW4gdGhpcyB7QGNvZGUgTWFwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNpemUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgQ29sbGVjdGlvbn0gb2YgdGhlIHZhbHVlcyBjb250YWluZWQgaW4gdGhpcyB7QGNvZGUgTWFwfS4gVGhlIHtAY29kZSBDb2xsZWN0aW9ufQorICAgICAqIGlzIGJhY2tlZCBieSB0aGlzIHtAY29kZSBNYXB9IHNvIGNoYW5nZXMgdG8gb25lIGFyZSByZWZsZWN0ZWQgYnkgdGhlIG90aGVyLiBUaGUKKyAgICAgKiB7QGNvZGUgQ29sbGVjdGlvbn0gc3VwcG9ydHMge0BsaW5rIENvbGxlY3Rpb24jcmVtb3ZlfSwge0BsaW5rIENvbGxlY3Rpb24jcmVtb3ZlQWxsfSwKKyAgICAgKiB7QGxpbmsgQ29sbGVjdGlvbiNyZXRhaW5BbGx9LCBhbmQge0BsaW5rIENvbGxlY3Rpb24jY2xlYXJ9IG9wZXJhdGlvbnMsCisgICAgICogYW5kIGl0IGRvZXMgbm90IHN1cHBvcnQge0BsaW5rIENvbGxlY3Rpb24jYWRkfSBvciB7QGxpbmsgQ29sbGVjdGlvbiNhZGRBbGx9IG9wZXJhdGlvbnMuCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhIHtAY29kZSBDb2xsZWN0aW9ufSB3aGljaCBpcyB0aGUgc3ViY2xhc3Mgb2YKKyAgICAgKiB7QGxpbmsgQWJzdHJhY3RDb2xsZWN0aW9ufS4gVGhlIHtAbGluayBBYnN0cmFjdENvbGxlY3Rpb24jaXRlcmF0b3J9IG1ldGhvZCBvZiB0aGlzIHN1YmNsYXNzIHJldHVybnMgYQorICAgICAqICJ3cmFwcGVyIG9iamVjdCIgb3ZlciB0aGUgaXRlcmF0b3Igb2YgdGhpcyB7QGNvZGUgTWFwfSdzIHtAbGluayAjZW50cnlTZXQoKX0uIFRoZSB7QGxpbmsgQWJzdHJhY3RDb2xsZWN0aW9uI3NpemV9IG1ldGhvZAorICAgICAqIHdyYXBzIHRoaXMge0Bjb2RlIE1hcH0ncyB7QGxpbmsgI3NpemV9IG1ldGhvZCBhbmQgdGhlIHtAbGluayBBYnN0cmFjdENvbGxlY3Rpb24jY29udGFpbnN9IG1ldGhvZCB3cmFwcyB0aGlzIHtAY29kZSBNYXB9J3MKKyAgICAgKiB7QGxpbmsgI2NvbnRhaW5zVmFsdWV9IG1ldGhvZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgY29sbGVjdGlvbiBpcyBjcmVhdGVkIHdoZW4gdGhpcyBtZXRob2QgaXMgY2FsbGVkIGF0IGZpcnN0IHRpbWUgYW5kCisgICAgICogcmV0dXJuZWQgaW4gcmVzcG9uc2UgdG8gYWxsIHN1YnNlcXVlbnQgY2FsbHMuIFRoaXMgbWV0aG9kIG1heSByZXR1cm4KKyAgICAgKiBkaWZmZXJlbnQgQ29sbGVjdGlvbiB3aGVuIG11bHRpcGxlIGNhbGxzIHRvIHRoaXMgbWV0aG9kLCBzaW5jZSBpdCBoYXMgbm8KKyAgICAgKiBzeW5jaHJvbml6YXRpb24gcGVyZm9ybWVkLgorICAgICAqCisgICAgICogQHJldHVybiBhIGNvbGxlY3Rpb24gb2YgdGhlIHZhbHVlcyBjb250YWluZWQgaW4gdGhpcyBtYXAuCisgICAgICovCisgICAgcHVibGljIENvbGxlY3Rpb248Vj4gdmFsdWVzKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL01hcEVudHJ5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL01hcEVudHJ5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTE5YjFjZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTWFwRW50cnkuamF2YQpAQCAtMCwwICsxLDg5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworLyoqCisgKiBNYXBFbnRyeSBpcyBhbiBpbnRlcm5hbCBjbGFzcyB3aGljaCBwcm92aWRlcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiBNYXAuRW50cnkuCisgKi8KK2NsYXNzIE1hcEVudHJ5PEssIFY+IGltcGxlbWVudHMgTWFwLkVudHJ5PEssIFY+LCBDbG9uZWFibGUgeworCisgICAgSyBrZXk7CisgICAgViB2YWx1ZTsKKworICAgIGludGVyZmFjZSBUeXBlPFJULCBLVCwgVlQ+IHsKKyAgICAgICAgUlQgZ2V0KE1hcEVudHJ5PEtULCBWVD4gZW50cnkpOworICAgIH0KKworICAgIE1hcEVudHJ5KEsgdGhlS2V5KSB7CisgICAgICAgIGtleSA9IHRoZUtleTsKKyAgICB9CisKKyAgICBNYXBFbnRyeShLIHRoZUtleSwgViB0aGVWYWx1ZSkgeworICAgICAgICBrZXkgPSB0aGVLZXk7CisgICAgICAgIHZhbHVlID0gdGhlVmFsdWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBpZiAodGhpcyA9PSBvYmplY3QpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBNYXAuRW50cnkpIHsKKyAgICAgICAgICAgIE1hcC5FbnRyeTw/LCA/PiBlbnRyeSA9IChNYXAuRW50cnk8PywgPz4pIG9iamVjdDsKKyAgICAgICAgICAgIHJldHVybiAoa2V5ID09IG51bGwgPyBlbnRyeS5nZXRLZXkoKSA9PSBudWxsIDoga2V5LmVxdWFscyhlbnRyeQorICAgICAgICAgICAgICAgICAgICAuZ2V0S2V5KCkpKQorICAgICAgICAgICAgICAgICAgICAmJiAodmFsdWUgPT0gbnVsbCA/IGVudHJ5LmdldFZhbHVlKCkgPT0gbnVsbCA6IHZhbHVlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhlbnRyeS5nZXRWYWx1ZSgpKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBLIGdldEtleSgpIHsKKyAgICAgICAgcmV0dXJuIGtleTsKKyAgICB9CisKKyAgICBwdWJsaWMgViBnZXRWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiAoa2V5ID09IG51bGwgPyAwIDoga2V5Lmhhc2hDb2RlKCkpCisgICAgICAgICAgICAgICAgXiAodmFsdWUgPT0gbnVsbCA/IDAgOiB2YWx1ZS5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgViBzZXRWYWx1ZShWIG9iamVjdCkgeworICAgICAgICBWIHJlc3VsdCA9IHZhbHVlOworICAgICAgICB2YWx1ZSA9IG9iamVjdDsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4ga2V5ICsgIj0iICsgdmFsdWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9NaW5pRW51bVNldC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9NaW5pRW51bVNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM4NzYxNjAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL01pbmlFbnVtU2V0LmphdmEKQEAgLTAsMCArMSwyNjEgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisKKy8qKgorICogQSBjb25jcmV0ZSBFbnVtU2V0IGZvciBlbnVtcyB3aXRoIDY0IG9yIGZld2VyIGVsZW1lbnRzLgorICovCitAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKK2ZpbmFsIGNsYXNzIE1pbmlFbnVtU2V0PEUgZXh0ZW5kcyBFbnVtPEU+PiBleHRlbmRzIEVudW1TZXQ8RT4geworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfRUxFTUVOVFMgPSA2NDsKKworICAgIHByaXZhdGUgaW50IHNpemU7CisKKyAgICBwcml2YXRlIGZpbmFsIEVbXSBlbnVtczsKKworICAgIHByaXZhdGUgbG9uZyBiaXRzOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbGVtZW50VHlwZSBub24tbnVsbDsgdHlwZSBvZiB0aGUgZWxlbWVudHMKKyAgICAgKiBAcGFyYW0gZW51bXMgbm9uLW51bGw7IHByZS1wb3B1bGF0ZWQgYXJyYXkgb2YgY29uc3RhbnRzIGluIG9yZGluYWwKKyAgICAgKiBvcmRlcgorICAgICAqLworICAgIE1pbmlFbnVtU2V0KENsYXNzPEU+IGVsZW1lbnRUeXBlLCBFW10gZW51bXMpIHsKKyAgICAgICAgc3VwZXIoZWxlbWVudFR5cGUpOworICAgICAgICB0aGlzLmVudW1zID0gZW51bXM7CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBNaW5pRW51bVNldEl0ZXJhdG9yIGltcGxlbWVudHMgSXRlcmF0b3I8RT4geworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgYml0cyB5ZXQgdG8gYmUgcmV0dXJuZWQgZm9yIGJpdHMuIEFzIHZhbHVlcyBmcm9tIHRoZSBjdXJyZW50IGluZGV4IGFyZSByZXR1cm5lZCwKKyAgICAgICAgICogdGhlaXIgYml0cyBhcmUgemVyb2VkIG91dC4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgbG9uZyBjdXJyZW50Qml0cyA9IGJpdHM7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBzaW5nbGUgYml0IG9mIHRoZSBuZXh0IHZhbHVlIHRvIHJldHVybi4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgbG9uZyBtYXNrID0gY3VycmVudEJpdHMgJiAtY3VycmVudEJpdHM7IC8vIHRoZSBsb3dlc3QgMSBiaXQgaW4gY3VycmVudEJpdHMKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGNhbmRpZGF0ZSBmb3IgcmVtb3ZhbC4gSWYgbnVsbCwgbm8gdmFsdWUgbWF5IGJlIHJlbW92ZWQuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIEUgbGFzdDsKKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgcmV0dXJuIG1hc2sgIT0gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFIG5leHQoKSB7CisgICAgICAgICAgICBpZiAobWFzayA9PSAwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IG9yZGluYWwgPSBMb25nLm51bWJlck9mVHJhaWxpbmdaZXJvcyhtYXNrKTsKKyAgICAgICAgICAgIGxhc3QgPSBlbnVtc1tvcmRpbmFsXTsKKworICAgICAgICAgICAgY3VycmVudEJpdHMgJj0gfm1hc2s7CisgICAgICAgICAgICBtYXNrID0gY3VycmVudEJpdHMgJiAtY3VycmVudEJpdHM7IC8vIHRoZSBsb3dlc3QgMSBiaXQgaW4gY3VycmVudEJpdHMKKworICAgICAgICAgICAgcmV0dXJuIGxhc3Q7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICBpZiAobGFzdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBNaW5pRW51bVNldC50aGlzLnJlbW92ZShsYXN0KTsKKyAgICAgICAgICAgIGxhc3QgPSBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEl0ZXJhdG9yPEU+IGl0ZXJhdG9yKCkgeworICAgICAgICByZXR1cm4gbmV3IE1pbmlFbnVtU2V0SXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgIHJldHVybiBzaXplOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBiaXRzID0gMDsKKyAgICAgICAgc2l6ZSA9IDA7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gYWRkKEUgZWxlbWVudCkgeworICAgICAgICBlbGVtZW50Q2xhc3MuY2FzdChlbGVtZW50KTsgLy8gQ2FsbGVkIHRvIHRocm93IENsYXNzQ2FzdEV4Y2VwdGlvbi4KKyAgICAgICAgbG9uZyBvbGRCaXRzID0gYml0czsKKyAgICAgICAgbG9uZyBuZXdCaXRzID0gb2xkQml0cyB8ICgxTCA8PCBlbGVtZW50Lm9yZGluYWwoKSk7CisgICAgICAgIGlmIChvbGRCaXRzICE9IG5ld0JpdHMpIHsKKyAgICAgICAgICAgIGJpdHMgPSBuZXdCaXRzOworICAgICAgICAgICAgc2l6ZSsrOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGFkZEFsbChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjb2xsZWN0aW9uKSB7CisgICAgICAgIGlmIChjb2xsZWN0aW9uLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmIChjb2xsZWN0aW9uIGluc3RhbmNlb2YgRW51bVNldCkgeworICAgICAgICAgICAgRW51bVNldDw/PiBzZXQgPSAoRW51bVNldCkgY29sbGVjdGlvbjsgLy8gcmF3IHR5cGUgZHVlIHRvIGphdmFjIGJ1ZyA2NTQ4NDM2CisgICAgICAgICAgICBzZXQuZWxlbWVudENsYXNzLmFzU3ViY2xhc3MoZWxlbWVudENsYXNzKTsgLy8gQ2FsbGVkIHRvIHRocm93IENsYXNzQ2FzdEV4Y2VwdGlvbi4KKworICAgICAgICAgICAgTWluaUVudW1TZXQ8Pz4gbWluaVNldCA9IChNaW5pRW51bVNldDw/Pikgc2V0OworICAgICAgICAgICAgbG9uZyBvbGRCaXRzID0gYml0czsKKyAgICAgICAgICAgIGxvbmcgbmV3Qml0cyA9IG9sZEJpdHMgfCBtaW5pU2V0LmJpdHM7CisgICAgICAgICAgICBiaXRzID0gbmV3Qml0czsKKyAgICAgICAgICAgIHNpemUgPSBMb25nLmJpdENvdW50KG5ld0JpdHMpOworICAgICAgICAgICAgcmV0dXJuIChvbGRCaXRzICE9IG5ld0JpdHMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzdXBlci5hZGRBbGwoY29sbGVjdGlvbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBpZiAob2JqZWN0ID09IG51bGwgfHwgIWlzVmFsaWRUeXBlKG9iamVjdC5nZXRDbGFzcygpKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIC8vIGd1YXJkZWQgYnkgaXNWYWxpZFR5cGUoKQorICAgICAgICBFbnVtPEU+IGVsZW1lbnQgPSAoRW51bTxFPikgb2JqZWN0OworICAgICAgICBpbnQgb3JkaW5hbCA9IGVsZW1lbnQub3JkaW5hbCgpOworICAgICAgICByZXR1cm4gKGJpdHMgJiAoMUwgPDwgb3JkaW5hbCkpICE9IDA7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNBbGwoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKSB7CisgICAgICAgIGlmIChjb2xsZWN0aW9uLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvbGxlY3Rpb24gaW5zdGFuY2VvZiBNaW5pRW51bVNldCkgeworICAgICAgICAgICAgTWluaUVudW1TZXQ8Pz4gc2V0ID0gKE1pbmlFbnVtU2V0PD8+KSBjb2xsZWN0aW9uOworICAgICAgICAgICAgbG9uZyBzZXRCaXRzID0gc2V0LmJpdHM7CisgICAgICAgICAgICByZXR1cm4gaXNWYWxpZFR5cGUoc2V0LmVsZW1lbnRDbGFzcykgJiYgKChiaXRzICYgc2V0Qml0cykgPT0gc2V0Qml0cyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuICEoY29sbGVjdGlvbiBpbnN0YW5jZW9mIEVudW1TZXQpICYmIHN1cGVyLmNvbnRhaW5zQWxsKGNvbGxlY3Rpb24pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZUFsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgaWYgKGNvbGxlY3Rpb24uaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvbGxlY3Rpb24gaW5zdGFuY2VvZiBFbnVtU2V0KSB7CisgICAgICAgICAgICBFbnVtU2V0PD8+IHNldCA9IChFbnVtU2V0PD8+KSBjb2xsZWN0aW9uOworICAgICAgICAgICAgaWYgKCFpc1ZhbGlkVHlwZShzZXQuZWxlbWVudENsYXNzKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgTWluaUVudW1TZXQ8RT4gbWluaVNldCA9IChNaW5pRW51bVNldDxFPikgc2V0OworICAgICAgICAgICAgbG9uZyBvbGRCaXRzID0gYml0czsKKyAgICAgICAgICAgIGxvbmcgbmV3Qml0cyA9IG9sZEJpdHMgJiB+bWluaVNldC5iaXRzOworICAgICAgICAgICAgaWYgKG9sZEJpdHMgIT0gbmV3Qml0cykgeworICAgICAgICAgICAgICAgIGJpdHMgPSBuZXdCaXRzOworICAgICAgICAgICAgICAgIHNpemUgPSBMb25nLmJpdENvdW50KG5ld0JpdHMpOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzdXBlci5yZW1vdmVBbGwoY29sbGVjdGlvbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gcmV0YWluQWxsKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbikgeworICAgICAgICBpZiAoY29sbGVjdGlvbiBpbnN0YW5jZW9mIEVudW1TZXQpIHsKKyAgICAgICAgICAgIEVudW1TZXQ8Pz4gc2V0ID0gKEVudW1TZXQ8Pz4pIGNvbGxlY3Rpb247CisgICAgICAgICAgICBpZiAoIWlzVmFsaWRUeXBlKHNldC5lbGVtZW50Q2xhc3MpKSB7CisgICAgICAgICAgICAgICAgaWYgKHNpemUgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIGNsZWFyKCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIE1pbmlFbnVtU2V0PEU+IG1pbmlTZXQgPSAoTWluaUVudW1TZXQ8RT4pIHNldDsKKyAgICAgICAgICAgIGxvbmcgb2xkQml0cyA9IGJpdHM7CisgICAgICAgICAgICBsb25nIG5ld0JpdHMgPSBvbGRCaXRzICYgbWluaVNldC5iaXRzOworICAgICAgICAgICAgaWYgKG9sZEJpdHMgIT0gbmV3Qml0cykgeworICAgICAgICAgICAgICAgIGJpdHMgPSBuZXdCaXRzOworICAgICAgICAgICAgICAgIHNpemUgPSBMb25nLmJpdENvdW50KG5ld0JpdHMpOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzdXBlci5yZXRhaW5BbGwoY29sbGVjdGlvbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgaWYgKG9iamVjdCA9PSBudWxsIHx8ICFpc1ZhbGlkVHlwZShvYmplY3QuZ2V0Q2xhc3MoKSkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSAvLyBndWFyZGVkIGJ5IGlzVmFsaWRUeXBlKCkKKyAgICAgICAgRW51bTxFPiBlbGVtZW50ID0gKEVudW08RT4pIG9iamVjdDsKKyAgICAgICAgaW50IG9yZGluYWwgPSBlbGVtZW50Lm9yZGluYWwoKTsKKyAgICAgICAgbG9uZyBvbGRCaXRzID0gYml0czsKKyAgICAgICAgbG9uZyBuZXdCaXRzID0gb2xkQml0cyAmIH4oMUwgPDwgb3JkaW5hbCk7CisgICAgICAgIGlmIChvbGRCaXRzICE9IG5ld0JpdHMpIHsKKyAgICAgICAgICAgIGJpdHMgPSBuZXdCaXRzOworICAgICAgICAgICAgc2l6ZS0tOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmICghKG9iamVjdCBpbnN0YW5jZW9mIEVudW1TZXQpKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iamVjdCk7CisgICAgICAgIH0KKyAgICAgICAgRW51bVNldDw/PiBzZXQgPShFbnVtU2V0PD8+KSBvYmplY3Q7CisgICAgICAgIGlmICghaXNWYWxpZFR5cGUoc2V0LmVsZW1lbnRDbGFzcykpIHsKKyAgICAgICAgICAgIHJldHVybiBzaXplID09IDAgJiYgc2V0LmlzRW1wdHkoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYml0cyA9PSAoKE1pbmlFbnVtU2V0PD8+KSBzZXQpLmJpdHM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgdm9pZCBjb21wbGVtZW50KCkgeworICAgICAgICBpZiAoZW51bXMubGVuZ3RoICE9IDApIHsKKyAgICAgICAgICAgIGJpdHMgPSB+Yml0czsKKyAgICAgICAgICAgIGJpdHMgJj0gKC0xTCA+Pj4gKE1BWF9FTEVNRU5UUyAtIGVudW1zLmxlbmd0aCkpOworICAgICAgICAgICAgc2l6ZSA9IGVudW1zLmxlbmd0aCAtIHNpemU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICB2b2lkIHNldFJhbmdlKEUgc3RhcnQsIEUgZW5kKSB7CisgICAgICAgIGludCBsZW5ndGggPSBlbmQub3JkaW5hbCgpIC0gc3RhcnQub3JkaW5hbCgpICsgMTsKKyAgICAgICAgbG9uZyByYW5nZSA9ICgtMUwgPj4+IChNQVhfRUxFTUVOVFMgLSBsZW5ndGgpKSA8PCBzdGFydC5vcmRpbmFsKCk7CisgICAgICAgIGJpdHMgfD0gcmFuZ2U7CisgICAgICAgIHNpemUgPSBMb25nLmJpdENvdW50KGJpdHMpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTWlzc2luZ0Zvcm1hdEFyZ3VtZW50RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL01pc3NpbmdGb3JtYXRBcmd1bWVudEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNlNzJlZmEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL01pc3NpbmdGb3JtYXRBcmd1bWVudEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTggQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisvKioKKyAqIEEge0Bjb2RlIE1pc3NpbmdGb3JtYXRBcmd1bWVudEV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gaWYgdGhlcmUgaXMgbm8KKyAqIGNvcnJlc3BvbmRpbmcgYXJndW1lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIGNvbnZlcnNpb24gb3IgYW4gYXJndW1lbnQgaW5kZXgKKyAqIHRoYXQgcmVmZXJzIHRvIGEgbWlzc2luZyBhcmd1bWVudC4KKyAqCisgKiBAc2VlIGphdmEubGFuZy5SdW50aW1lRXhjZXB0aW9uCisgKi8KK3B1YmxpYyBjbGFzcyBNaXNzaW5nRm9ybWF0QXJndW1lbnRFeGNlcHRpb24gZXh0ZW5kcyBJbGxlZ2FsRm9ybWF0RXhjZXB0aW9uIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxOTE5MDExNUw7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBzOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTWlzc2luZ0Zvcm1hdEFyZ3VtZW50RXhjZXB0aW9ufSB3aXRoIHRoZQorICAgICAqIHNwZWNpZmllZCBjb252ZXJzaW9uIHRoYXQgbGFja3MgdGhlIGFyZ3VtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgdGhlIHNwZWNpZmllZCBjb252ZXJzaW9uIHRoYXQgbGFja3MgdGhlIGFyZ3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBNaXNzaW5nRm9ybWF0QXJndW1lbnRFeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICAgICAgaWYgKHMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zID0gczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb252ZXJzaW9uIGFzc29jaWF0ZWQgd2l0aCB0aGUgZXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29udmVyc2lvbiBhc3NvY2lhdGVkIHdpdGggdGhlIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdFNwZWNpZmllcigpIHsKKyAgICAgICAgcmV0dXJuIHM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkgeworICAgICAgICByZXR1cm4gIkZvcm1hdCBzcGVjaWZpZXI6ICIgKyBzOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTWlzc2luZ0Zvcm1hdFdpZHRoRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL01pc3NpbmdGb3JtYXRXaWR0aEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2ZDBjYTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL01pc3NpbmdGb3JtYXRXaWR0aEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisvKioKKyAqIEEge0Bjb2RlIE1pc3NpbmdGb3JtYXRXaWR0aEV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGZvcm1hdCB3aWR0aCBpcworICogbWlzc2luZyBidXQgaXMgcmVxdWlyZWQuCisgKgorICogQHNlZSBqYXZhLmxhbmcuUnVudGltZUV4Y2VwdGlvbgorICovCitwdWJsaWMgY2xhc3MgTWlzc2luZ0Zvcm1hdFdpZHRoRXhjZXB0aW9uIGV4dGVuZHMgSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbiB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTU1NjAxMjNMOworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgczsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIE1pc3NpbmdGb3JtYXRXaWR0aEV4Y2VwdGlvbn0gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogZm9ybWF0IHNwZWNpZmllci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgIHRoZSBzcGVjaWZpZWQgZm9ybWF0IHNwZWNpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWlzc2luZ0Zvcm1hdFdpZHRoRXhjZXB0aW9uKFN0cmluZyBzKSB7CisgICAgICAgIGlmIChzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMucyA9IHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZm9ybWF0IHNwZWNpZmllciBhc3NvY2lhdGVkIHdpdGggdGhlIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGZvcm1hdCBzcGVjaWZpZXIgYXNzb2NpYXRlZCB3aXRoIHRoZSBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRGb3JtYXRTcGVjaWZpZXIoKSB7CisgICAgICAgIHJldHVybiBzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKyAgICAgICAgcmV0dXJuIHM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWVkY2U5YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw3NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKKworLyoqCisgKiBBIHtAY29kZSBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb259IGlzIHRocm93biBieSBSZXNvdXJjZUJ1bmRsZSB3aGVuIGEKKyAqIHJlc291cmNlIGJ1bmRsZSBjYW5ub3QgYmUgZm91bmQgb3IgYSByZXNvdXJjZSBpcyBtaXNzaW5nIGZyb20gYSByZXNvdXJjZQorICogYnVuZGxlLgorICoKKyAqIEBzZWUgUmVzb3VyY2VCdW5kbGUKKyAqIEBzZWUgamF2YS5sYW5nLlJ1bnRpbWVFeGNlcHRpb24KKyAqLworcHVibGljIGNsYXNzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQ4NzYzNDUxNzYwNjIwMDA0MDFMOworCisgICAgU3RyaW5nIGNsYXNzTmFtZSwga2V5OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9ufSB3aXRoIHRoZSBzdGFjayB0cmFjZSwKKyAgICAgKiBtZXNzYWdlLCB0aGUgY2xhc3MgbmFtZSBvZiB0aGUgcmVzb3VyY2UgYnVuZGxlIGFuZCB0aGUgbmFtZSBvZiB0aGUKKyAgICAgKiBtaXNzaW5nIHJlc291cmNlIGZpbGxlZCBpbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gY2xhc3NOYW1lCisgICAgICogICAgICAgICAgIHRoZSBjbGFzcyBuYW1lIG9mIHRoZSByZXNvdXJjZSBidW5kbGUuCisgICAgICogQHBhcmFtIHJlc291cmNlTmFtZQorICAgICAqICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgbWlzc2luZyByZXNvdXJjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlLCBTdHJpbmcgY2xhc3NOYW1lLAorICAgICAgICAgICAgU3RyaW5nIHJlc291cmNlTmFtZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICAgICAgdGhpcy5jbGFzc05hbWUgPSBjbGFzc05hbWU7CisgICAgICAgIGtleSA9IHJlc291cmNlTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjbGFzcyBuYW1lIG9mIHRoZSByZXNvdXJjZSBidW5kbGUgZnJvbSB3aGljaCBhIHJlc291cmNlIGNvdWxkCisgICAgICogbm90IGJlIGZvdW5kLCBvciBpbiB0aGUgY2FzZSBvZiBhIG1pc3NpbmcgcmVzb3VyY2UsIHRoZSBuYW1lIG9mIHRoZQorICAgICAqIG1pc3NpbmcgcmVzb3VyY2UgYnVuZGxlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2xhc3MgbmFtZSBvZiB0aGUgcmVzb3VyY2UgYnVuZGxlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2xhc3NOYW1lKCkgeworICAgICAgICByZXR1cm4gY2xhc3NOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIG1pc3NpbmcgcmVzb3VyY2UsIG9yIGFuIGVtcHR5IHN0cmluZyBpZiB0aGUKKyAgICAgKiByZXNvdXJjZSBidW5kbGUgaXMgbWlzc2luZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIG1pc3NpbmcgcmVzb3VyY2UuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRLZXkoKSB7CisgICAgICAgIHJldHVybiBrZXk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL05hdmlnYWJsZU1hcC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9OYXZpZ2FibGVNYXAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOTk2MWM4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9OYXZpZ2FibGVNYXAuamF2YQpAQCAtMCwwICsxLDM5NiBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgYW5kIEpvc2ggQmxvY2ggd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AKKyAqIEpTUi0xNjYgRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworLy8gQkVHSU4gYW5kcm9pZC1ub3RlCisvLyByZW1vdmVkIGxpbmsgdG8gY29sbGVjdGlvbnMgZnJhbWV3b3JrIGRvY3MKKy8vIGNoYW5nZWQge0BsaW5rICNzdWJNYXAoT2JqZWN0KX0gdG8ge0BsaW5rICNzdWJNYXB9IHRvIHNhdGlzZnkgRHJvaWREb2MKKy8vIEVORCBhbmRyb2lkLW5vdGUKKworLyoqCisgKiBBIHtAbGluayBTb3J0ZWRNYXB9IGV4dGVuZGVkIHdpdGggbmF2aWdhdGlvbiBtZXRob2RzIHJldHVybmluZyB0aGUKKyAqIGNsb3Nlc3QgbWF0Y2hlcyBmb3IgZ2l2ZW4gc2VhcmNoIHRhcmdldHMuIE1ldGhvZHMKKyAqIHtAY29kZSBsb3dlckVudHJ5fSwge0Bjb2RlIGZsb29yRW50cnl9LCB7QGNvZGUgY2VpbGluZ0VudHJ5fSwKKyAqIGFuZCB7QGNvZGUgaGlnaGVyRW50cnl9IHJldHVybiB7QGNvZGUgTWFwLkVudHJ5fSBvYmplY3RzCisgKiBhc3NvY2lhdGVkIHdpdGgga2V5cyByZXNwZWN0aXZlbHkgbGVzcyB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwsCisgKiBncmVhdGVyIHRoYW4gb3IgZXF1YWwsIGFuZCBncmVhdGVyIHRoYW4gYSBnaXZlbiBrZXksIHJldHVybmluZworICoge0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIG5vIHN1Y2gga2V5LiAgU2ltaWxhcmx5LCBtZXRob2RzCisgKiB7QGNvZGUgbG93ZXJLZXl9LCB7QGNvZGUgZmxvb3JLZXl9LCB7QGNvZGUgY2VpbGluZ0tleX0sIGFuZAorICoge0Bjb2RlIGhpZ2hlcktleX0gcmV0dXJuIG9ubHkgdGhlIGFzc29jaWF0ZWQga2V5cy4gQWxsIG9mIHRoZXNlCisgKiBtZXRob2RzIGFyZSBkZXNpZ25lZCBmb3IgbG9jYXRpbmcsIG5vdCB0cmF2ZXJzaW5nIGVudHJpZXMuCisgKgorICogPHA+QSB7QGNvZGUgTmF2aWdhYmxlTWFwfSBtYXkgYmUgYWNjZXNzZWQgYW5kIHRyYXZlcnNlZCBpbiBlaXRoZXIKKyAqIGFzY2VuZGluZyBvciBkZXNjZW5kaW5nIGtleSBvcmRlci4gIFRoZSB7QGNvZGUgZGVzY2VuZGluZ01hcH0KKyAqIG1ldGhvZCByZXR1cm5zIGEgdmlldyBvZiB0aGUgbWFwIHdpdGggdGhlIHNlbnNlcyBvZiBhbGwgcmVsYXRpb25hbAorICogYW5kIGRpcmVjdGlvbmFsIG1ldGhvZHMgaW52ZXJ0ZWQuIFRoZSBwZXJmb3JtYW5jZSBvZiBhc2NlbmRpbmcKKyAqIG9wZXJhdGlvbnMgYW5kIHZpZXdzIGlzIGxpa2VseSB0byBiZSBmYXN0ZXIgdGhhbiB0aGF0IG9mIGRlc2NlbmRpbmcKKyAqIG9uZXMuICBNZXRob2RzIHtAY29kZSBzdWJNYXB9LCB7QGNvZGUgaGVhZE1hcH0sCisgKiBhbmQge0Bjb2RlIHRhaWxNYXB9IGRpZmZlciBmcm9tIHRoZSBsaWtlLW5hbWVkIHtAY29kZQorICogU29ydGVkTWFwfSBtZXRob2RzIGluIGFjY2VwdGluZyBhZGRpdGlvbmFsIGFyZ3VtZW50cyBkZXNjcmliaW5nCisgKiB3aGV0aGVyIGxvd2VyIGFuZCB1cHBlciBib3VuZHMgYXJlIGluY2x1c2l2ZSB2ZXJzdXMgZXhjbHVzaXZlLgorICogU3VibWFwcyBvZiBhbnkge0Bjb2RlIE5hdmlnYWJsZU1hcH0gbXVzdCBpbXBsZW1lbnQgdGhlIHtAY29kZQorICogTmF2aWdhYmxlTWFwfSBpbnRlcmZhY2UuCisgKgorICogPHA+VGhpcyBpbnRlcmZhY2UgYWRkaXRpb25hbGx5IGRlZmluZXMgbWV0aG9kcyB7QGNvZGUgZmlyc3RFbnRyeX0sCisgKiB7QGNvZGUgcG9sbEZpcnN0RW50cnl9LCB7QGNvZGUgbGFzdEVudHJ5fSwgYW5kCisgKiB7QGNvZGUgcG9sbExhc3RFbnRyeX0gdGhhdCByZXR1cm4gYW5kL29yIHJlbW92ZSB0aGUgbGVhc3QgYW5kCisgKiBncmVhdGVzdCBtYXBwaW5ncywgaWYgYW55IGV4aXN0LCBlbHNlIHJldHVybmluZyB7QGNvZGUgbnVsbH0uCisgKgorICogPHA+SW1wbGVtZW50YXRpb25zIG9mIGVudHJ5LXJldHVybmluZyBtZXRob2RzIGFyZSBleHBlY3RlZCB0bworICogcmV0dXJuIHtAY29kZSBNYXAuRW50cnl9IHBhaXJzIHJlcHJlc2VudGluZyBzbmFwc2hvdHMgb2YgbWFwcGluZ3MKKyAqIGF0IHRoZSB0aW1lIHRoZXkgd2VyZSBwcm9kdWNlZCwgYW5kIHRodXMgZ2VuZXJhbGx5IGRvIDxlbT5ub3Q8L2VtPgorICogc3VwcG9ydCB0aGUgb3B0aW9uYWwge0Bjb2RlIEVudHJ5LnNldFZhbHVlfSBtZXRob2QuIE5vdGUgaG93ZXZlcgorICogdGhhdCBpdCBpcyBwb3NzaWJsZSB0byBjaGFuZ2UgbWFwcGluZ3MgaW4gdGhlIGFzc29jaWF0ZWQgbWFwIHVzaW5nCisgKiBtZXRob2Qge0Bjb2RlIHB1dH0uCisgKgorICogPHA+TWV0aG9kcworICoge0BsaW5rICNzdWJNYXAgc3ViTWFwKEssIEspfSwKKyAqIHtAbGluayAjaGVhZE1hcCBoZWFkTWFwKEspfSwgYW5kCisgKiB7QGxpbmsgI3RhaWxNYXAgdGFpbE1hcChLKX0KKyAqIGFyZSBzcGVjaWZpZWQgdG8gcmV0dXJuIHtAY29kZSBTb3J0ZWRNYXB9IHRvIGFsbG93IGV4aXN0aW5nCisgKiBpbXBsZW1lbnRhdGlvbnMgb2Yge0Bjb2RlIFNvcnRlZE1hcH0gdG8gYmUgY29tcGF0aWJseSByZXRyb2ZpdHRlZCB0bworICogaW1wbGVtZW50IHtAY29kZSBOYXZpZ2FibGVNYXB9LCBidXQgZXh0ZW5zaW9ucyBhbmQgaW1wbGVtZW50YXRpb25zCisgKiBvZiB0aGlzIGludGVyZmFjZSBhcmUgZW5jb3VyYWdlZCB0byBvdmVycmlkZSB0aGVzZSBtZXRob2RzIHRvIHJldHVybgorICoge0Bjb2RlIE5hdmlnYWJsZU1hcH0uICBTaW1pbGFybHksCisgKiB7QGxpbmsgI2tleVNldCgpfSBjYW4gYmUgb3ZlcnJpZGVuIHRvIHJldHVybiB7QGNvZGUgTmF2aWdhYmxlU2V0fS4KKyAqCisgKiBAYXV0aG9yIERvdWcgTGVhCisgKiBAYXV0aG9yIEpvc2ggQmxvY2gKKyAqIEBwYXJhbSA8Sz4gdGhlIHR5cGUgb2Yga2V5cyBtYWludGFpbmVkIGJ5IHRoaXMgbWFwCisgKiBAcGFyYW0gPFY+IHRoZSB0eXBlIG9mIG1hcHBlZCB2YWx1ZXMKKyAqIEBzaW5jZSAxLjYKKyAqLworcHVibGljIGludGVyZmFjZSBOYXZpZ2FibGVNYXA8SyxWPiBleHRlbmRzIFNvcnRlZE1hcDxLLFY+IHsKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEga2V5LXZhbHVlIG1hcHBpbmcgYXNzb2NpYXRlZCB3aXRoIHRoZSBncmVhdGVzdCBrZXkKKyAgICAgKiBzdHJpY3RseSBsZXNzIHRoYW4gdGhlIGdpdmVuIGtleSwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzCisgICAgICogbm8gc3VjaCBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkKKyAgICAgKiBAcmV0dXJuIGFuIGVudHJ5IHdpdGggdGhlIGdyZWF0ZXN0IGtleSBsZXNzIHRoYW4ge0Bjb2RlIGtleX0sCisgICAgICogICAgICAgICBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgaXMgbm8gc3VjaCBrZXkKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgY29tcGFyZWQKKyAgICAgKiAgICAgICAgIHdpdGggdGhlIGtleXMgY3VycmVudGx5IGluIHRoZSBtYXAKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQga2V5IGlzIG51bGwKKyAgICAgKiAgICAgICAgIGFuZCB0aGlzIG1hcCBkb2VzIG5vdCBwZXJtaXQgbnVsbCBrZXlzCisgICAgICovCisgICAgTWFwLkVudHJ5PEssVj4gbG93ZXJFbnRyeShLIGtleSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBncmVhdGVzdCBrZXkgc3RyaWN0bHkgbGVzcyB0aGFuIHRoZSBnaXZlbiBrZXksIG9yCisgICAgICoge0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIG5vIHN1Y2gga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleSB0aGUga2V5CisgICAgICogQHJldHVybiB0aGUgZ3JlYXRlc3Qga2V5IGxlc3MgdGhhbiB7QGNvZGUga2V5fSwKKyAgICAgKiAgICAgICAgIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSBpcyBubyBzdWNoIGtleQorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbm5vdCBiZSBjb21wYXJlZAorICAgICAqICAgICAgICAgd2l0aCB0aGUga2V5cyBjdXJyZW50bHkgaW4gdGhlIG1hcAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgaXMgbnVsbAorICAgICAqICAgICAgICAgYW5kIHRoaXMgbWFwIGRvZXMgbm90IHBlcm1pdCBudWxsIGtleXMKKyAgICAgKi8KKyAgICBLIGxvd2VyS2V5KEsga2V5KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBrZXktdmFsdWUgbWFwcGluZyBhc3NvY2lhdGVkIHdpdGggdGhlIGdyZWF0ZXN0IGtleQorICAgICAqIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgZ2l2ZW4ga2V5LCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUKKyAgICAgKiBpcyBubyBzdWNoIGtleS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkgdGhlIGtleQorICAgICAqIEByZXR1cm4gYW4gZW50cnkgd2l0aCB0aGUgZ3JlYXRlc3Qga2V5IGxlc3MgdGhhbiBvciBlcXVhbCB0bworICAgICAqICAgICAgICAge0Bjb2RlIGtleX0sIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSBpcyBubyBzdWNoIGtleQorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbm5vdCBiZSBjb21wYXJlZAorICAgICAqICAgICAgICAgd2l0aCB0aGUga2V5cyBjdXJyZW50bHkgaW4gdGhlIG1hcAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgaXMgbnVsbAorICAgICAqICAgICAgICAgYW5kIHRoaXMgbWFwIGRvZXMgbm90IHBlcm1pdCBudWxsIGtleXMKKyAgICAgKi8KKyAgICBNYXAuRW50cnk8SyxWPiBmbG9vckVudHJ5KEsga2V5KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGdyZWF0ZXN0IGtleSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuIGtleSwKKyAgICAgKiBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgaXMgbm8gc3VjaCBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkKKyAgICAgKiBAcmV0dXJuIHRoZSBncmVhdGVzdCBrZXkgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHtAY29kZSBrZXl9LAorICAgICAqICAgICAgICAgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIG5vIHN1Y2gga2V5CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIGNvbXBhcmVkCisgICAgICogICAgICAgICB3aXRoIHRoZSBrZXlzIGN1cnJlbnRseSBpbiB0aGUgbWFwCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBpcyBudWxsCisgICAgICogICAgICAgICBhbmQgdGhpcyBtYXAgZG9lcyBub3QgcGVybWl0IG51bGwga2V5cworICAgICAqLworICAgIEsgZmxvb3JLZXkoSyBrZXkpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGtleS12YWx1ZSBtYXBwaW5nIGFzc29jaWF0ZWQgd2l0aCB0aGUgbGVhc3Qga2V5CisgICAgICogZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiBrZXksIG9yIHtAY29kZSBudWxsfSBpZgorICAgICAqIHRoZXJlIGlzIG5vIHN1Y2gga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleSB0aGUga2V5CisgICAgICogQHJldHVybiBhbiBlbnRyeSB3aXRoIHRoZSBsZWFzdCBrZXkgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvCisgICAgICogICAgICAgICB7QGNvZGUga2V5fSwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIG5vIHN1Y2gga2V5CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIGNvbXBhcmVkCisgICAgICogICAgICAgICB3aXRoIHRoZSBrZXlzIGN1cnJlbnRseSBpbiB0aGUgbWFwCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBpcyBudWxsCisgICAgICogICAgICAgICBhbmQgdGhpcyBtYXAgZG9lcyBub3QgcGVybWl0IG51bGwga2V5cworICAgICAqLworICAgIE1hcC5FbnRyeTxLLFY+IGNlaWxpbmdFbnRyeShLIGtleSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsZWFzdCBrZXkgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiBrZXksCisgICAgICogb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIG5vIHN1Y2gga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleSB0aGUga2V5CisgICAgICogQHJldHVybiB0aGUgbGVhc3Qga2V5IGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB7QGNvZGUga2V5fSwKKyAgICAgKiAgICAgICAgIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSBpcyBubyBzdWNoIGtleQorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbm5vdCBiZSBjb21wYXJlZAorICAgICAqICAgICAgICAgd2l0aCB0aGUga2V5cyBjdXJyZW50bHkgaW4gdGhlIG1hcAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgaXMgbnVsbAorICAgICAqICAgICAgICAgYW5kIHRoaXMgbWFwIGRvZXMgbm90IHBlcm1pdCBudWxsIGtleXMKKyAgICAgKi8KKyAgICBLIGNlaWxpbmdLZXkoSyBrZXkpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGtleS12YWx1ZSBtYXBwaW5nIGFzc29jaWF0ZWQgd2l0aCB0aGUgbGVhc3Qga2V5CisgICAgICogc3RyaWN0bHkgZ3JlYXRlciB0aGFuIHRoZSBnaXZlbiBrZXksIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZQorICAgICAqIGlzIG5vIHN1Y2gga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleSB0aGUga2V5CisgICAgICogQHJldHVybiBhbiBlbnRyeSB3aXRoIHRoZSBsZWFzdCBrZXkgZ3JlYXRlciB0aGFuIHtAY29kZSBrZXl9LAorICAgICAqICAgICAgICAgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIG5vIHN1Y2gga2V5CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIGNvbXBhcmVkCisgICAgICogICAgICAgICB3aXRoIHRoZSBrZXlzIGN1cnJlbnRseSBpbiB0aGUgbWFwCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBpcyBudWxsCisgICAgICogICAgICAgICBhbmQgdGhpcyBtYXAgZG9lcyBub3QgcGVybWl0IG51bGwga2V5cworICAgICAqLworICAgIE1hcC5FbnRyeTxLLFY+IGhpZ2hlckVudHJ5KEsga2V5KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxlYXN0IGtleSBzdHJpY3RseSBncmVhdGVyIHRoYW4gdGhlIGdpdmVuIGtleSwgb3IKKyAgICAgKiB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgaXMgbm8gc3VjaCBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkKKyAgICAgKiBAcmV0dXJuIHRoZSBsZWFzdCBrZXkgZ3JlYXRlciB0aGFuIHtAY29kZSBrZXl9LAorICAgICAqICAgICAgICAgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIG5vIHN1Y2gga2V5CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIGNvbXBhcmVkCisgICAgICogICAgICAgICB3aXRoIHRoZSBrZXlzIGN1cnJlbnRseSBpbiB0aGUgbWFwCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBpcyBudWxsCisgICAgICogICAgICAgICBhbmQgdGhpcyBtYXAgZG9lcyBub3QgcGVybWl0IG51bGwga2V5cworICAgICAqLworICAgIEsgaGlnaGVyS2V5KEsga2V5KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBrZXktdmFsdWUgbWFwcGluZyBhc3NvY2lhdGVkIHdpdGggdGhlIGxlYXN0CisgICAgICoga2V5IGluIHRoaXMgbWFwLCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIG1hcCBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gZW50cnkgd2l0aCB0aGUgbGVhc3Qga2V5LAorICAgICAqICAgICAgICAgb3Ige0Bjb2RlIG51bGx9IGlmIHRoaXMgbWFwIGlzIGVtcHR5CisgICAgICovCisgICAgTWFwLkVudHJ5PEssVj4gZmlyc3RFbnRyeSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGtleS12YWx1ZSBtYXBwaW5nIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ3JlYXRlc3QKKyAgICAgKiBrZXkgaW4gdGhpcyBtYXAsIG9yIHtAY29kZSBudWxsfSBpZiB0aGUgbWFwIGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHJldHVybiBhbiBlbnRyeSB3aXRoIHRoZSBncmVhdGVzdCBrZXksCisgICAgICogICAgICAgICBvciB7QGNvZGUgbnVsbH0gaWYgdGhpcyBtYXAgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBNYXAuRW50cnk8SyxWPiBsYXN0RW50cnkoKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYW5kIHJldHVybnMgYSBrZXktdmFsdWUgbWFwcGluZyBhc3NvY2lhdGVkIHdpdGgKKyAgICAgKiB0aGUgbGVhc3Qga2V5IGluIHRoaXMgbWFwLCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIG1hcCBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJlbW92ZWQgZmlyc3QgZW50cnkgb2YgdGhpcyBtYXAsCisgICAgICogICAgICAgICBvciB7QGNvZGUgbnVsbH0gaWYgdGhpcyBtYXAgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBNYXAuRW50cnk8SyxWPiBwb2xsRmlyc3RFbnRyeSgpOworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhbmQgcmV0dXJucyBhIGtleS12YWx1ZSBtYXBwaW5nIGFzc29jaWF0ZWQgd2l0aAorICAgICAqIHRoZSBncmVhdGVzdCBrZXkgaW4gdGhpcyBtYXAsIG9yIHtAY29kZSBudWxsfSBpZiB0aGUgbWFwIGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVtb3ZlZCBsYXN0IGVudHJ5IG9mIHRoaXMgbWFwLAorICAgICAqICAgICAgICAgb3Ige0Bjb2RlIG51bGx9IGlmIHRoaXMgbWFwIGlzIGVtcHR5CisgICAgICovCisgICAgTWFwLkVudHJ5PEssVj4gcG9sbExhc3RFbnRyeSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHJldmVyc2Ugb3JkZXIgdmlldyBvZiB0aGUgbWFwcGluZ3MgY29udGFpbmVkIGluIHRoaXMgbWFwLgorICAgICAqIFRoZSBkZXNjZW5kaW5nIG1hcCBpcyBiYWNrZWQgYnkgdGhpcyBtYXAsIHNvIGNoYW5nZXMgdG8gdGhlIG1hcCBhcmUKKyAgICAgKiByZWZsZWN0ZWQgaW4gdGhlIGRlc2NlbmRpbmcgbWFwLCBhbmQgdmljZS12ZXJzYS4gIElmIGVpdGhlciBtYXAgaXMKKyAgICAgKiBtb2RpZmllZCB3aGlsZSBhbiBpdGVyYXRpb24gb3ZlciBhIGNvbGxlY3Rpb24gdmlldyBvZiBlaXRoZXIgbWFwCisgICAgICogaXMgaW4gcHJvZ3Jlc3MgKGV4Y2VwdCB0aHJvdWdoIHRoZSBpdGVyYXRvcidzIG93biB7QGNvZGUgcmVtb3ZlfQorICAgICAqIG9wZXJhdGlvbiksIHRoZSByZXN1bHRzIG9mIHRoZSBpdGVyYXRpb24gYXJlIHVuZGVmaW5lZC4KKyAgICAgKgorICAgICAqIDxwPlRoZSByZXR1cm5lZCBtYXAgaGFzIGFuIG9yZGVyaW5nIGVxdWl2YWxlbnQgdG8KKyAgICAgKiA8dHQ+e0BsaW5rIENvbGxlY3Rpb25zI3JldmVyc2VPcmRlcihDb21wYXJhdG9yKSBDb2xsZWN0aW9ucy5yZXZlcnNlT3JkZXJ9KGNvbXBhcmF0b3IoKSk8L3R0Pi4KKyAgICAgKiBUaGUgZXhwcmVzc2lvbiB7QGNvZGUgbS5kZXNjZW5kaW5nTWFwKCkuZGVzY2VuZGluZ01hcCgpfSByZXR1cm5zIGEKKyAgICAgKiB2aWV3IG9mIHtAY29kZSBtfSBlc3NlbnRpYWxseSBlcXVpdmFsZW50IHRvIHtAY29kZSBtfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSByZXZlcnNlIG9yZGVyIHZpZXcgb2YgdGhpcyBtYXAKKyAgICAgKi8KKyAgICBOYXZpZ2FibGVNYXA8SyxWPiBkZXNjZW5kaW5nTWFwKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0BsaW5rIE5hdmlnYWJsZVNldH0gdmlldyBvZiB0aGUga2V5cyBjb250YWluZWQgaW4gdGhpcyBtYXAuCisgICAgICogVGhlIHNldCdzIGl0ZXJhdG9yIHJldHVybnMgdGhlIGtleXMgaW4gYXNjZW5kaW5nIG9yZGVyLgorICAgICAqIFRoZSBzZXQgaXMgYmFja2VkIGJ5IHRoZSBtYXAsIHNvIGNoYW5nZXMgdG8gdGhlIG1hcCBhcmUgcmVmbGVjdGVkIGluCisgICAgICogdGhlIHNldCwgYW5kIHZpY2UtdmVyc2EuICBJZiB0aGUgbWFwIGlzIG1vZGlmaWVkIHdoaWxlIGFuIGl0ZXJhdGlvbgorICAgICAqIG92ZXIgdGhlIHNldCBpcyBpbiBwcm9ncmVzcyAoZXhjZXB0IHRocm91Z2ggdGhlIGl0ZXJhdG9yJ3Mgb3duIHtAY29kZQorICAgICAqIHJlbW92ZX0gb3BlcmF0aW9uKSwgdGhlIHJlc3VsdHMgb2YgdGhlIGl0ZXJhdGlvbiBhcmUgdW5kZWZpbmVkLiAgVGhlCisgICAgICogc2V0IHN1cHBvcnRzIGVsZW1lbnQgcmVtb3ZhbCwgd2hpY2ggcmVtb3ZlcyB0aGUgY29ycmVzcG9uZGluZyBtYXBwaW5nCisgICAgICogZnJvbSB0aGUgbWFwLCB2aWEgdGhlIHtAY29kZSBJdGVyYXRvci5yZW1vdmV9LCB7QGNvZGUgU2V0LnJlbW92ZX0sCisgICAgICoge0Bjb2RlIHJlbW92ZUFsbH0sIHtAY29kZSByZXRhaW5BbGx9LCBhbmQge0Bjb2RlIGNsZWFyfSBvcGVyYXRpb25zLgorICAgICAqIEl0IGRvZXMgbm90IHN1cHBvcnQgdGhlIHtAY29kZSBhZGR9IG9yIHtAY29kZSBhZGRBbGx9IG9wZXJhdGlvbnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgbmF2aWdhYmxlIHNldCB2aWV3IG9mIHRoZSBrZXlzIGluIHRoaXMgbWFwCisgICAgICovCisgICAgTmF2aWdhYmxlU2V0PEs+IG5hdmlnYWJsZUtleVNldCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHJldmVyc2Ugb3JkZXIge0BsaW5rIE5hdmlnYWJsZVNldH0gdmlldyBvZiB0aGUga2V5cyBjb250YWluZWQgaW4gdGhpcyBtYXAuCisgICAgICogVGhlIHNldCdzIGl0ZXJhdG9yIHJldHVybnMgdGhlIGtleXMgaW4gZGVzY2VuZGluZyBvcmRlci4KKyAgICAgKiBUaGUgc2V0IGlzIGJhY2tlZCBieSB0aGUgbWFwLCBzbyBjaGFuZ2VzIHRvIHRoZSBtYXAgYXJlIHJlZmxlY3RlZCBpbgorICAgICAqIHRoZSBzZXQsIGFuZCB2aWNlLXZlcnNhLiAgSWYgdGhlIG1hcCBpcyBtb2RpZmllZCB3aGlsZSBhbiBpdGVyYXRpb24KKyAgICAgKiBvdmVyIHRoZSBzZXQgaXMgaW4gcHJvZ3Jlc3MgKGV4Y2VwdCB0aHJvdWdoIHRoZSBpdGVyYXRvcidzIG93biB7QGNvZGUKKyAgICAgKiByZW1vdmV9IG9wZXJhdGlvbiksIHRoZSByZXN1bHRzIG9mIHRoZSBpdGVyYXRpb24gYXJlIHVuZGVmaW5lZC4gIFRoZQorICAgICAqIHNldCBzdXBwb3J0cyBlbGVtZW50IHJlbW92YWwsIHdoaWNoIHJlbW92ZXMgdGhlIGNvcnJlc3BvbmRpbmcgbWFwcGluZworICAgICAqIGZyb20gdGhlIG1hcCwgdmlhIHRoZSB7QGNvZGUgSXRlcmF0b3IucmVtb3ZlfSwge0Bjb2RlIFNldC5yZW1vdmV9LAorICAgICAqIHtAY29kZSByZW1vdmVBbGx9LCB7QGNvZGUgcmV0YWluQWxsfSwgYW5kIHtAY29kZSBjbGVhcn0gb3BlcmF0aW9ucy4KKyAgICAgKiBJdCBkb2VzIG5vdCBzdXBwb3J0IHRoZSB7QGNvZGUgYWRkfSBvciB7QGNvZGUgYWRkQWxsfSBvcGVyYXRpb25zLgorICAgICAqCisgICAgICogQHJldHVybiBhIHJldmVyc2Ugb3JkZXIgbmF2aWdhYmxlIHNldCB2aWV3IG9mIHRoZSBrZXlzIGluIHRoaXMgbWFwCisgICAgICovCisgICAgTmF2aWdhYmxlU2V0PEs+IGRlc2NlbmRpbmdLZXlTZXQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB2aWV3IG9mIHRoZSBwb3J0aW9uIG9mIHRoaXMgbWFwIHdob3NlIGtleXMgcmFuZ2UgZnJvbQorICAgICAqIHtAY29kZSBmcm9tS2V5fSB0byB7QGNvZGUgdG9LZXl9LiAgSWYge0Bjb2RlIGZyb21LZXl9IGFuZAorICAgICAqIHtAY29kZSB0b0tleX0gYXJlIGVxdWFsLCB0aGUgcmV0dXJuZWQgbWFwIGlzIGVtcHR5IHVubGVzcworICAgICAqIHtAY29kZSBmcm9tRXhjbHVzaXZlfSBhbmQge0Bjb2RlIHRvRXhjbHVzaXZlfSBhcmUgYm90aCB0cnVlLiAgVGhlCisgICAgICogcmV0dXJuZWQgbWFwIGlzIGJhY2tlZCBieSB0aGlzIG1hcCwgc28gY2hhbmdlcyBpbiB0aGUgcmV0dXJuZWQgbWFwIGFyZQorICAgICAqIHJlZmxlY3RlZCBpbiB0aGlzIG1hcCwgYW5kIHZpY2UtdmVyc2EuICBUaGUgcmV0dXJuZWQgbWFwIHN1cHBvcnRzIGFsbAorICAgICAqIG9wdGlvbmFsIG1hcCBvcGVyYXRpb25zIHRoYXQgdGhpcyBtYXAgc3VwcG9ydHMuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQgbWFwIHdpbGwgdGhyb3cgYW4ge0Bjb2RlIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbn0KKyAgICAgKiBvbiBhbiBhdHRlbXB0IHRvIGluc2VydCBhIGtleSBvdXRzaWRlIG9mIGl0cyByYW5nZSwgb3IgdG8gY29uc3RydWN0IGEKKyAgICAgKiBzdWJtYXAgZWl0aGVyIG9mIHdob3NlIGVuZHBvaW50cyBsaWUgb3V0c2lkZSBpdHMgcmFuZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZnJvbUtleSBsb3cgZW5kcG9pbnQgb2YgdGhlIGtleXMgaW4gdGhlIHJldHVybmVkIG1hcAorICAgICAqIEBwYXJhbSBmcm9tSW5jbHVzaXZlIHtAY29kZSB0cnVlfSBpZiB0aGUgbG93IGVuZHBvaW50CisgICAgICogICAgICAgIGlzIHRvIGJlIGluY2x1ZGVkIGluIHRoZSByZXR1cm5lZCB2aWV3CisgICAgICogQHBhcmFtIHRvS2V5IGhpZ2ggZW5kcG9pbnQgb2YgdGhlIGtleXMgaW4gdGhlIHJldHVybmVkIG1hcAorICAgICAqIEBwYXJhbSB0b0luY2x1c2l2ZSB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGhpZ2ggZW5kcG9pbnQKKyAgICAgKiAgICAgICAgaXMgdG8gYmUgaW5jbHVkZWQgaW4gdGhlIHJldHVybmVkIHZpZXcKKyAgICAgKiBAcmV0dXJuIGEgdmlldyBvZiB0aGUgcG9ydGlvbiBvZiB0aGlzIG1hcCB3aG9zZSBrZXlzIHJhbmdlIGZyb20KKyAgICAgKiAgICAgICAgIHtAY29kZSBmcm9tS2V5fSB0byB7QGNvZGUgdG9LZXl9CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYge0Bjb2RlIGZyb21LZXl9IGFuZCB7QGNvZGUgdG9LZXl9CisgICAgICogICAgICAgICBjYW5ub3QgYmUgY29tcGFyZWQgdG8gb25lIGFub3RoZXIgdXNpbmcgdGhpcyBtYXAncyBjb21wYXJhdG9yCisgICAgICogICAgICAgICAob3IsIGlmIHRoZSBtYXAgaGFzIG5vIGNvbXBhcmF0b3IsIHVzaW5nIG5hdHVyYWwgb3JkZXJpbmcpLgorICAgICAqICAgICAgICAgSW1wbGVtZW50YXRpb25zIG1heSwgYnV0IGFyZSBub3QgcmVxdWlyZWQgdG8sIHRocm93IHRoaXMKKyAgICAgKiAgICAgICAgIGV4Y2VwdGlvbiBpZiB7QGNvZGUgZnJvbUtleX0gb3Ige0Bjb2RlIHRvS2V5fQorICAgICAqICAgICAgICAgY2Fubm90IGJlIGNvbXBhcmVkIHRvIGtleXMgY3VycmVudGx5IGluIHRoZSBtYXAuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgZnJvbUtleX0gb3Ige0Bjb2RlIHRvS2V5fQorICAgICAqICAgICAgICAgaXMgbnVsbCBhbmQgdGhpcyBtYXAgZG9lcyBub3QgcGVybWl0IG51bGwga2V5cworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBmcm9tS2V5fSBpcyBncmVhdGVyIHRoYW4KKyAgICAgKiAgICAgICAgIHtAY29kZSB0b0tleX07IG9yIGlmIHRoaXMgbWFwIGl0c2VsZiBoYXMgYSByZXN0cmljdGVkCisgICAgICogICAgICAgICByYW5nZSwgYW5kIHtAY29kZSBmcm9tS2V5fSBvciB7QGNvZGUgdG9LZXl9IGxpZXMKKyAgICAgKiAgICAgICAgIG91dHNpZGUgdGhlIGJvdW5kcyBvZiB0aGUgcmFuZ2UKKyAgICAgKi8KKyAgICBOYXZpZ2FibGVNYXA8SyxWPiBzdWJNYXAoSyBmcm9tS2V5LCBib29sZWFuIGZyb21JbmNsdXNpdmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEsgdG9LZXksICAgYm9vbGVhbiB0b0luY2x1c2l2ZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgdmlldyBvZiB0aGUgcG9ydGlvbiBvZiB0aGlzIG1hcCB3aG9zZSBrZXlzIGFyZSBsZXNzIHRoYW4gKG9yCisgICAgICogZXF1YWwgdG8sIGlmIHtAY29kZSBpbmNsdXNpdmV9IGlzIHRydWUpIHtAY29kZSB0b0tleX0uICBUaGUgcmV0dXJuZWQKKyAgICAgKiBtYXAgaXMgYmFja2VkIGJ5IHRoaXMgbWFwLCBzbyBjaGFuZ2VzIGluIHRoZSByZXR1cm5lZCBtYXAgYXJlIHJlZmxlY3RlZAorICAgICAqIGluIHRoaXMgbWFwLCBhbmQgdmljZS12ZXJzYS4gIFRoZSByZXR1cm5lZCBtYXAgc3VwcG9ydHMgYWxsIG9wdGlvbmFsCisgICAgICogbWFwIG9wZXJhdGlvbnMgdGhhdCB0aGlzIG1hcCBzdXBwb3J0cy4KKyAgICAgKgorICAgICAqIDxwPlRoZSByZXR1cm5lZCBtYXAgd2lsbCB0aHJvdyBhbiB7QGNvZGUgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufQorICAgICAqIG9uIGFuIGF0dGVtcHQgdG8gaW5zZXJ0IGEga2V5IG91dHNpZGUgaXRzIHJhbmdlLgorICAgICAqCisgICAgICogQHBhcmFtIHRvS2V5IGhpZ2ggZW5kcG9pbnQgb2YgdGhlIGtleXMgaW4gdGhlIHJldHVybmVkIG1hcAorICAgICAqIEBwYXJhbSBpbmNsdXNpdmUge0Bjb2RlIHRydWV9IGlmIHRoZSBoaWdoIGVuZHBvaW50CisgICAgICogICAgICAgIGlzIHRvIGJlIGluY2x1ZGVkIGluIHRoZSByZXR1cm5lZCB2aWV3CisgICAgICogQHJldHVybiBhIHZpZXcgb2YgdGhlIHBvcnRpb24gb2YgdGhpcyBtYXAgd2hvc2Uga2V5cyBhcmUgbGVzcyB0aGFuCisgICAgICogICAgICAgICAob3IgZXF1YWwgdG8sIGlmIHtAY29kZSBpbmNsdXNpdmV9IGlzIHRydWUpIHtAY29kZSB0b0tleX0KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB7QGNvZGUgdG9LZXl9IGlzIG5vdCBjb21wYXRpYmxlCisgICAgICogICAgICAgICB3aXRoIHRoaXMgbWFwJ3MgY29tcGFyYXRvciAob3IsIGlmIHRoZSBtYXAgaGFzIG5vIGNvbXBhcmF0b3IsCisgICAgICogICAgICAgICBpZiB7QGNvZGUgdG9LZXl9IGRvZXMgbm90IGltcGxlbWVudCB7QGxpbmsgQ29tcGFyYWJsZX0pLgorICAgICAqICAgICAgICAgSW1wbGVtZW50YXRpb25zIG1heSwgYnV0IGFyZSBub3QgcmVxdWlyZWQgdG8sIHRocm93IHRoaXMKKyAgICAgKiAgICAgICAgIGV4Y2VwdGlvbiBpZiB7QGNvZGUgdG9LZXl9IGNhbm5vdCBiZSBjb21wYXJlZCB0byBrZXlzCisgICAgICogICAgICAgICBjdXJyZW50bHkgaW4gdGhlIG1hcC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSB0b0tleX0gaXMgbnVsbAorICAgICAqICAgICAgICAgYW5kIHRoaXMgbWFwIGRvZXMgbm90IHBlcm1pdCBudWxsIGtleXMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGlzIG1hcCBpdHNlbGYgaGFzIGEKKyAgICAgKiAgICAgICAgIHJlc3RyaWN0ZWQgcmFuZ2UsIGFuZCB7QGNvZGUgdG9LZXl9IGxpZXMgb3V0c2lkZSB0aGUKKyAgICAgKiAgICAgICAgIGJvdW5kcyBvZiB0aGUgcmFuZ2UKKyAgICAgKi8KKyAgICBOYXZpZ2FibGVNYXA8SyxWPiBoZWFkTWFwKEsgdG9LZXksIGJvb2xlYW4gaW5jbHVzaXZlKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB2aWV3IG9mIHRoZSBwb3J0aW9uIG9mIHRoaXMgbWFwIHdob3NlIGtleXMgYXJlIGdyZWF0ZXIgdGhhbiAob3IKKyAgICAgKiBlcXVhbCB0bywgaWYge0Bjb2RlIGluY2x1c2l2ZX0gaXMgdHJ1ZSkge0Bjb2RlIGZyb21LZXl9LiAgVGhlIHJldHVybmVkCisgICAgICogbWFwIGlzIGJhY2tlZCBieSB0aGlzIG1hcCwgc28gY2hhbmdlcyBpbiB0aGUgcmV0dXJuZWQgbWFwIGFyZSByZWZsZWN0ZWQKKyAgICAgKiBpbiB0aGlzIG1hcCwgYW5kIHZpY2UtdmVyc2EuICBUaGUgcmV0dXJuZWQgbWFwIHN1cHBvcnRzIGFsbCBvcHRpb25hbAorICAgICAqIG1hcCBvcGVyYXRpb25zIHRoYXQgdGhpcyBtYXAgc3VwcG9ydHMuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQgbWFwIHdpbGwgdGhyb3cgYW4ge0Bjb2RlIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbn0KKyAgICAgKiBvbiBhbiBhdHRlbXB0IHRvIGluc2VydCBhIGtleSBvdXRzaWRlIGl0cyByYW5nZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmcm9tS2V5IGxvdyBlbmRwb2ludCBvZiB0aGUga2V5cyBpbiB0aGUgcmV0dXJuZWQgbWFwCisgICAgICogQHBhcmFtIGluY2x1c2l2ZSB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGxvdyBlbmRwb2ludAorICAgICAqICAgICAgICBpcyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgcmV0dXJuZWQgdmlldworICAgICAqIEByZXR1cm4gYSB2aWV3IG9mIHRoZSBwb3J0aW9uIG9mIHRoaXMgbWFwIHdob3NlIGtleXMgYXJlIGdyZWF0ZXIgdGhhbgorICAgICAqICAgICAgICAgKG9yIGVxdWFsIHRvLCBpZiB7QGNvZGUgaW5jbHVzaXZlfSBpcyB0cnVlKSB7QGNvZGUgZnJvbUtleX0KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB7QGNvZGUgZnJvbUtleX0gaXMgbm90IGNvbXBhdGlibGUKKyAgICAgKiAgICAgICAgIHdpdGggdGhpcyBtYXAncyBjb21wYXJhdG9yIChvciwgaWYgdGhlIG1hcCBoYXMgbm8gY29tcGFyYXRvciwKKyAgICAgKiAgICAgICAgIGlmIHtAY29kZSBmcm9tS2V5fSBkb2VzIG5vdCBpbXBsZW1lbnQge0BsaW5rIENvbXBhcmFibGV9KS4KKyAgICAgKiAgICAgICAgIEltcGxlbWVudGF0aW9ucyBtYXksIGJ1dCBhcmUgbm90IHJlcXVpcmVkIHRvLCB0aHJvdyB0aGlzCisgICAgICogICAgICAgICBleGNlcHRpb24gaWYge0Bjb2RlIGZyb21LZXl9IGNhbm5vdCBiZSBjb21wYXJlZCB0byBrZXlzCisgICAgICogICAgICAgICBjdXJyZW50bHkgaW4gdGhlIG1hcC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBmcm9tS2V5fSBpcyBudWxsCisgICAgICogICAgICAgICBhbmQgdGhpcyBtYXAgZG9lcyBub3QgcGVybWl0IG51bGwga2V5cworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoaXMgbWFwIGl0c2VsZiBoYXMgYQorICAgICAqICAgICAgICAgcmVzdHJpY3RlZCByYW5nZSwgYW5kIHtAY29kZSBmcm9tS2V5fSBsaWVzIG91dHNpZGUgdGhlCisgICAgICogICAgICAgICBib3VuZHMgb2YgdGhlIHJhbmdlCisgICAgICovCisgICAgTmF2aWdhYmxlTWFwPEssVj4gdGFpbE1hcChLIGZyb21LZXksIGJvb2xlYW4gaW5jbHVzaXZlKTsKKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIDxwPkVxdWl2YWxlbnQgdG8ge0Bjb2RlIHN1Yk1hcChmcm9tS2V5LCB0cnVlLCB0b0tleSwgZmFsc2UpfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIFNvcnRlZE1hcDxLLFY+IHN1Yk1hcChLIGZyb21LZXksIEsgdG9LZXkpOworCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogPHA+RXF1aXZhbGVudCB0byB7QGNvZGUgaGVhZE1hcCh0b0tleSwgZmFsc2UpfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIFNvcnRlZE1hcDxLLFY+IGhlYWRNYXAoSyB0b0tleSk7CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiA8cD5FcXVpdmFsZW50IHRvIHtAY29kZSB0YWlsTWFwKGZyb21LZXksIHRydWUpfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIFNvcnRlZE1hcDxLLFY+IHRhaWxNYXAoSyBmcm9tS2V5KTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTmF2aWdhYmxlU2V0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL05hdmlnYWJsZVNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNmZjA4MDAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL05hdmlnYWJsZVNldC5qYXZhCkBAIC0wLDAgKzEsMjkxIEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSBhbmQgSm9zaCBCbG9jaCB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUAorICogSlNSLTE2NiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisvLyBCRUdJTiBhbmRyb2lkLW5vdGUKKy8vIHJlbW92ZWQgbGluayB0byBjb2xsZWN0aW9ucyBmcmFtZXdvcmsgZG9jcworLy8gY2hhbmdlZCB7QGxpbmsgI3N1YlNldChPYmplY3QpfSB0byB7QGxpbmsgI3N1YlNldH0gdG8gc2F0aXNmeSBEcm9pZERvYworLy8gRU5EIGFuZHJvaWQtbm90ZQorCisvKioKKyAqIEEge0BsaW5rIFNvcnRlZFNldH0gZXh0ZW5kZWQgd2l0aCBuYXZpZ2F0aW9uIG1ldGhvZHMgcmVwb3J0aW5nCisgKiBjbG9zZXN0IG1hdGNoZXMgZm9yIGdpdmVuIHNlYXJjaCB0YXJnZXRzLiBNZXRob2RzIHtAY29kZSBsb3dlcn0sCisgKiB7QGNvZGUgZmxvb3J9LCB7QGNvZGUgY2VpbGluZ30sIGFuZCB7QGNvZGUgaGlnaGVyfSByZXR1cm4gZWxlbWVudHMKKyAqIHJlc3BlY3RpdmVseSBsZXNzIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCwgZ3JlYXRlciB0aGFuIG9yIGVxdWFsLAorICogYW5kIGdyZWF0ZXIgdGhhbiBhIGdpdmVuIGVsZW1lbnQsIHJldHVybmluZyB7QGNvZGUgbnVsbH0gaWYgdGhlcmUKKyAqIGlzIG5vIHN1Y2ggZWxlbWVudC4gIEEge0Bjb2RlIE5hdmlnYWJsZVNldH0gbWF5IGJlIGFjY2Vzc2VkIGFuZAorICogdHJhdmVyc2VkIGluIGVpdGhlciBhc2NlbmRpbmcgb3IgZGVzY2VuZGluZyBvcmRlci4gIFRoZSB7QGNvZGUKKyAqIGRlc2NlbmRpbmdTZXR9IG1ldGhvZCByZXR1cm5zIGEgdmlldyBvZiB0aGUgc2V0IHdpdGggdGhlIHNlbnNlcyBvZgorICogYWxsIHJlbGF0aW9uYWwgYW5kIGRpcmVjdGlvbmFsIG1ldGhvZHMgaW52ZXJ0ZWQuIFRoZSBwZXJmb3JtYW5jZSBvZgorICogYXNjZW5kaW5nIG9wZXJhdGlvbnMgYW5kIHZpZXdzIGlzIGxpa2VseSB0byBiZSBmYXN0ZXIgdGhhbiB0aGF0IG9mCisgKiBkZXNjZW5kaW5nIG9uZXMuICBUaGlzIGludGVyZmFjZSBhZGRpdGlvbmFsbHkgZGVmaW5lcyBtZXRob2RzCisgKiB7QGNvZGUgcG9sbEZpcnN0fSBhbmQge0Bjb2RlIHBvbGxMYXN0fSB0aGF0IHJldHVybiBhbmQgcmVtb3ZlIHRoZQorICogbG93ZXN0IGFuZCBoaWdoZXN0IGVsZW1lbnQsIGlmIG9uZSBleGlzdHMsIGVsc2UgcmV0dXJuaW5nIHtAY29kZQorICogbnVsbH0uICBNZXRob2RzIHtAY29kZSBzdWJTZXR9LCB7QGNvZGUgaGVhZFNldH0sCisgKiBhbmQge0Bjb2RlIHRhaWxTZXR9IGRpZmZlciBmcm9tIHRoZSBsaWtlLW5hbWVkIHtAY29kZQorICogU29ydGVkU2V0fSBtZXRob2RzIGluIGFjY2VwdGluZyBhZGRpdGlvbmFsIGFyZ3VtZW50cyBkZXNjcmliaW5nCisgKiB3aGV0aGVyIGxvd2VyIGFuZCB1cHBlciBib3VuZHMgYXJlIGluY2x1c2l2ZSB2ZXJzdXMgZXhjbHVzaXZlLgorICogU3Vic2V0cyBvZiBhbnkge0Bjb2RlIE5hdmlnYWJsZVNldH0gbXVzdCBpbXBsZW1lbnQgdGhlIHtAY29kZQorICogTmF2aWdhYmxlU2V0fSBpbnRlcmZhY2UuCisgKgorICogPHA+IFRoZSByZXR1cm4gdmFsdWVzIG9mIG5hdmlnYXRpb24gbWV0aG9kcyBtYXkgYmUgYW1iaWd1b3VzIGluCisgKiBpbXBsZW1lbnRhdGlvbnMgdGhhdCBwZXJtaXQge0Bjb2RlIG51bGx9IGVsZW1lbnRzLiBIb3dldmVyLCBldmVuCisgKiBpbiB0aGlzIGNhc2UgdGhlIHJlc3VsdCBjYW4gYmUgZGlzYW1iaWd1YXRlZCBieSBjaGVja2luZworICoge0Bjb2RlIGNvbnRhaW5zKG51bGwpfS4gVG8gYXZvaWQgc3VjaCBpc3N1ZXMsIGltcGxlbWVudGF0aW9ucyBvZgorICogdGhpcyBpbnRlcmZhY2UgYXJlIGVuY291cmFnZWQgdG8gPGVtPm5vdDwvZW0+IHBlcm1pdCBpbnNlcnRpb24gb2YKKyAqIHtAY29kZSBudWxsfSBlbGVtZW50cy4gKE5vdGUgdGhhdCBzb3J0ZWQgc2V0cyBvZiB7QGxpbmsKKyAqIENvbXBhcmFibGV9IGVsZW1lbnRzIGludHJpbnNpY2FsbHkgZG8gbm90IHBlcm1pdCB7QGNvZGUgbnVsbH0uKQorICoKKyAqIDxwPk1ldGhvZHMKKyAqIHtAbGluayAjc3ViU2V0IHN1YlNldChFLCBFKX0sCisgKiB7QGxpbmsgI2hlYWRTZXQgaGVhZFNldChFKX0sIGFuZAorICoge0BsaW5rICN0YWlsU2V0IHRhaWxTZXQoRSl9CisgKiBhcmUgc3BlY2lmaWVkIHRvIHJldHVybiB7QGNvZGUgU29ydGVkU2V0fSB0byBhbGxvdyBleGlzdGluZworICogaW1wbGVtZW50YXRpb25zIG9mIHtAY29kZSBTb3J0ZWRTZXR9IHRvIGJlIGNvbXBhdGlibHkgcmV0cm9maXR0ZWQgdG8KKyAqIGltcGxlbWVudCB7QGNvZGUgTmF2aWdhYmxlU2V0fSwgYnV0IGV4dGVuc2lvbnMgYW5kIGltcGxlbWVudGF0aW9ucworICogb2YgdGhpcyBpbnRlcmZhY2UgYXJlIGVuY291cmFnZWQgdG8gb3ZlcnJpZGUgdGhlc2UgbWV0aG9kcyB0byByZXR1cm4KKyAqIHtAY29kZSBOYXZpZ2FibGVTZXR9LgorICoKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqIEBhdXRob3IgSm9zaCBCbG9jaAorICogQHBhcmFtIDxFPiB0aGUgdHlwZSBvZiBlbGVtZW50cyBtYWludGFpbmVkIGJ5IHRoaXMgc2V0CisgKiBAc2luY2UgMS42CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgTmF2aWdhYmxlU2V0PEU+IGV4dGVuZHMgU29ydGVkU2V0PEU+IHsKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBncmVhdGVzdCBlbGVtZW50IGluIHRoaXMgc2V0IHN0cmljdGx5IGxlc3MgdGhhbiB0aGUKKyAgICAgKiBnaXZlbiBlbGVtZW50LCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgaXMgbm8gc3VjaCBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIHZhbHVlIHRvIG1hdGNoCisgICAgICogQHJldHVybiB0aGUgZ3JlYXRlc3QgZWxlbWVudCBsZXNzIHRoYW4ge0Bjb2RlIGV9LAorICAgICAqICAgICAgICAgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIG5vIHN1Y2ggZWxlbWVudAorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBjYW5ub3QgYmUKKyAgICAgKiAgICAgICAgIGNvbXBhcmVkIHdpdGggdGhlIGVsZW1lbnRzIGN1cnJlbnRseSBpbiB0aGUgc2V0CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqICAgICAgICAgYW5kIHRoaXMgc2V0IGRvZXMgbm90IHBlcm1pdCBudWxsIGVsZW1lbnRzCisgICAgICovCisgICAgRSBsb3dlcihFIGUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZ3JlYXRlc3QgZWxlbWVudCBpbiB0aGlzIHNldCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8KKyAgICAgKiB0aGUgZ2l2ZW4gZWxlbWVudCwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIG5vIHN1Y2ggZWxlbWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIHRoZSB2YWx1ZSB0byBtYXRjaAorICAgICAqIEByZXR1cm4gdGhlIGdyZWF0ZXN0IGVsZW1lbnQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHtAY29kZSBlfSwKKyAgICAgKiAgICAgICAgIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSBpcyBubyBzdWNoIGVsZW1lbnQKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgY2Fubm90IGJlCisgICAgICogICAgICAgICBjb21wYXJlZCB3aXRoIHRoZSBlbGVtZW50cyBjdXJyZW50bHkgaW4gdGhlIHNldAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwKKyAgICAgKiAgICAgICAgIGFuZCB0aGlzIHNldCBkb2VzIG5vdCBwZXJtaXQgbnVsbCBlbGVtZW50cworICAgICAqLworICAgIEUgZmxvb3IoRSBlKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxlYXN0IGVsZW1lbnQgaW4gdGhpcyBzZXQgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvCisgICAgICogdGhlIGdpdmVuIGVsZW1lbnQsIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSBpcyBubyBzdWNoIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSB0aGUgdmFsdWUgdG8gbWF0Y2gKKyAgICAgKiBAcmV0dXJuIHRoZSBsZWFzdCBlbGVtZW50IGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB7QGNvZGUgZX0sCisgICAgICogICAgICAgICBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgaXMgbm8gc3VjaCBlbGVtZW50CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGNhbm5vdCBiZQorICAgICAqICAgICAgICAgY29tcGFyZWQgd2l0aCB0aGUgZWxlbWVudHMgY3VycmVudGx5IGluIHRoZSBzZXQKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICogICAgICAgICBhbmQgdGhpcyBzZXQgZG9lcyBub3QgcGVybWl0IG51bGwgZWxlbWVudHMKKyAgICAgKi8KKyAgICBFIGNlaWxpbmcoRSBlKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxlYXN0IGVsZW1lbnQgaW4gdGhpcyBzZXQgc3RyaWN0bHkgZ3JlYXRlciB0aGFuIHRoZQorICAgICAqIGdpdmVuIGVsZW1lbnQsIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSBpcyBubyBzdWNoIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSB0aGUgdmFsdWUgdG8gbWF0Y2gKKyAgICAgKiBAcmV0dXJuIHRoZSBsZWFzdCBlbGVtZW50IGdyZWF0ZXIgdGhhbiB7QGNvZGUgZX0sCisgICAgICogICAgICAgICBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgaXMgbm8gc3VjaCBlbGVtZW50CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGNhbm5vdCBiZQorICAgICAqICAgICAgICAgY29tcGFyZWQgd2l0aCB0aGUgZWxlbWVudHMgY3VycmVudGx5IGluIHRoZSBzZXQKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICogICAgICAgICBhbmQgdGhpcyBzZXQgZG9lcyBub3QgcGVybWl0IG51bGwgZWxlbWVudHMKKyAgICAgKi8KKyAgICBFIGhpZ2hlcihFIGUpOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGFuZCByZW1vdmVzIHRoZSBmaXJzdCAobG93ZXN0KSBlbGVtZW50LAorICAgICAqIG9yIHJldHVybnMge0Bjb2RlIG51bGx9IGlmIHRoaXMgc2V0IGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZmlyc3QgZWxlbWVudCwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoaXMgc2V0IGlzIGVtcHR5CisgICAgICovCisgICAgRSBwb2xsRmlyc3QoKTsKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhbmQgcmVtb3ZlcyB0aGUgbGFzdCAoaGlnaGVzdCkgZWxlbWVudCwKKyAgICAgKiBvciByZXR1cm5zIHtAY29kZSBudWxsfSBpZiB0aGlzIHNldCBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxhc3QgZWxlbWVudCwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoaXMgc2V0IGlzIGVtcHR5CisgICAgICovCisgICAgRSBwb2xsTGFzdCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cyBpbiB0aGlzIHNldCwgaW4gYXNjZW5kaW5nIG9yZGVyLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cyBpbiB0aGlzIHNldCwgaW4gYXNjZW5kaW5nIG9yZGVyCisgICAgICovCisgICAgSXRlcmF0b3I8RT4gaXRlcmF0b3IoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSByZXZlcnNlIG9yZGVyIHZpZXcgb2YgdGhlIGVsZW1lbnRzIGNvbnRhaW5lZCBpbiB0aGlzIHNldC4KKyAgICAgKiBUaGUgZGVzY2VuZGluZyBzZXQgaXMgYmFja2VkIGJ5IHRoaXMgc2V0LCBzbyBjaGFuZ2VzIHRvIHRoZSBzZXQgYXJlCisgICAgICogcmVmbGVjdGVkIGluIHRoZSBkZXNjZW5kaW5nIHNldCwgYW5kIHZpY2UtdmVyc2EuICBJZiBlaXRoZXIgc2V0IGlzCisgICAgICogbW9kaWZpZWQgd2hpbGUgYW4gaXRlcmF0aW9uIG92ZXIgZWl0aGVyIHNldCBpcyBpbiBwcm9ncmVzcyAoZXhjZXB0CisgICAgICogdGhyb3VnaCB0aGUgaXRlcmF0b3IncyBvd24ge0Bjb2RlIHJlbW92ZX0gb3BlcmF0aW9uKSwgdGhlIHJlc3VsdHMgb2YKKyAgICAgKiB0aGUgaXRlcmF0aW9uIGFyZSB1bmRlZmluZWQuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQgc2V0IGhhcyBhbiBvcmRlcmluZyBlcXVpdmFsZW50IHRvCisgICAgICogPHR0PntAbGluayBDb2xsZWN0aW9ucyNyZXZlcnNlT3JkZXIoQ29tcGFyYXRvcikgQ29sbGVjdGlvbnMucmV2ZXJzZU9yZGVyfShjb21wYXJhdG9yKCkpPC90dD4uCisgICAgICogVGhlIGV4cHJlc3Npb24ge0Bjb2RlIHMuZGVzY2VuZGluZ1NldCgpLmRlc2NlbmRpbmdTZXQoKX0gcmV0dXJucyBhCisgICAgICogdmlldyBvZiB7QGNvZGUgc30gZXNzZW50aWFsbHkgZXF1aXZhbGVudCB0byB7QGNvZGUgc30uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcmV2ZXJzZSBvcmRlciB2aWV3IG9mIHRoaXMgc2V0CisgICAgICovCisgICAgTmF2aWdhYmxlU2V0PEU+IGRlc2NlbmRpbmdTZXQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMgaW4gdGhpcyBzZXQsIGluIGRlc2NlbmRpbmcgb3JkZXIuCisgICAgICogRXF1aXZhbGVudCBpbiBlZmZlY3QgdG8ge0Bjb2RlIGRlc2NlbmRpbmdTZXQoKS5pdGVyYXRvcigpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMgaW4gdGhpcyBzZXQsIGluIGRlc2NlbmRpbmcgb3JkZXIKKyAgICAgKi8KKyAgICBJdGVyYXRvcjxFPiBkZXNjZW5kaW5nSXRlcmF0b3IoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB2aWV3IG9mIHRoZSBwb3J0aW9uIG9mIHRoaXMgc2V0IHdob3NlIGVsZW1lbnRzIHJhbmdlIGZyb20KKyAgICAgKiB7QGNvZGUgZnJvbUVsZW1lbnR9IHRvIHtAY29kZSB0b0VsZW1lbnR9LiAgSWYge0Bjb2RlIGZyb21FbGVtZW50fSBhbmQKKyAgICAgKiB7QGNvZGUgdG9FbGVtZW50fSBhcmUgZXF1YWwsIHRoZSByZXR1cm5lZCBzZXQgaXMgZW1wdHkgdW5sZXNzIHtAY29kZQorICAgICAqIGZyb21FeGNsdXNpdmV9IGFuZCB7QGNvZGUgdG9FeGNsdXNpdmV9IGFyZSBib3RoIHRydWUuICBUaGUgcmV0dXJuZWQgc2V0CisgICAgICogaXMgYmFja2VkIGJ5IHRoaXMgc2V0LCBzbyBjaGFuZ2VzIGluIHRoZSByZXR1cm5lZCBzZXQgYXJlIHJlZmxlY3RlZCBpbgorICAgICAqIHRoaXMgc2V0LCBhbmQgdmljZS12ZXJzYS4gIFRoZSByZXR1cm5lZCBzZXQgc3VwcG9ydHMgYWxsIG9wdGlvbmFsIHNldAorICAgICAqIG9wZXJhdGlvbnMgdGhhdCB0aGlzIHNldCBzdXBwb3J0cy4KKyAgICAgKgorICAgICAqIDxwPlRoZSByZXR1cm5lZCBzZXQgd2lsbCB0aHJvdyBhbiB7QGNvZGUgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufQorICAgICAqIG9uIGFuIGF0dGVtcHQgdG8gaW5zZXJ0IGFuIGVsZW1lbnQgb3V0c2lkZSBpdHMgcmFuZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZnJvbUVsZW1lbnQgbG93IGVuZHBvaW50IG9mIHRoZSByZXR1cm5lZCBzZXQKKyAgICAgKiBAcGFyYW0gZnJvbUluY2x1c2l2ZSB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGxvdyBlbmRwb2ludAorICAgICAqICAgICAgICBpcyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgcmV0dXJuZWQgdmlldworICAgICAqIEBwYXJhbSB0b0VsZW1lbnQgaGlnaCBlbmRwb2ludCBvZiB0aGUgcmV0dXJuZWQgc2V0CisgICAgICogQHBhcmFtIHRvSW5jbHVzaXZlIHtAY29kZSB0cnVlfSBpZiB0aGUgaGlnaCBlbmRwb2ludAorICAgICAqICAgICAgICBpcyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgcmV0dXJuZWQgdmlldworICAgICAqIEByZXR1cm4gYSB2aWV3IG9mIHRoZSBwb3J0aW9uIG9mIHRoaXMgc2V0IHdob3NlIGVsZW1lbnRzIHJhbmdlIGZyb20KKyAgICAgKiAgICAgICAgIHtAY29kZSBmcm9tRWxlbWVudH0sIGluY2x1c2l2ZSwgdG8ge0Bjb2RlIHRvRWxlbWVudH0sIGV4Y2x1c2l2ZQorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHtAY29kZSBmcm9tRWxlbWVudH0gYW5kCisgICAgICogICAgICAgICB7QGNvZGUgdG9FbGVtZW50fSBjYW5ub3QgYmUgY29tcGFyZWQgdG8gb25lIGFub3RoZXIgdXNpbmcgdGhpcworICAgICAqICAgICAgICAgc2V0J3MgY29tcGFyYXRvciAob3IsIGlmIHRoZSBzZXQgaGFzIG5vIGNvbXBhcmF0b3IsIHVzaW5nCisgICAgICogICAgICAgICBuYXR1cmFsIG9yZGVyaW5nKS4gIEltcGxlbWVudGF0aW9ucyBtYXksIGJ1dCBhcmUgbm90IHJlcXVpcmVkCisgICAgICogICAgICAgICB0bywgdGhyb3cgdGhpcyBleGNlcHRpb24gaWYge0Bjb2RlIGZyb21FbGVtZW50fSBvcgorICAgICAqICAgICAgICAge0Bjb2RlIHRvRWxlbWVudH0gY2Fubm90IGJlIGNvbXBhcmVkIHRvIGVsZW1lbnRzIGN1cnJlbnRseSBpbgorICAgICAqICAgICAgICAgdGhlIHNldC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBmcm9tRWxlbWVudH0gb3IKKyAgICAgKiAgICAgICAgIHtAY29kZSB0b0VsZW1lbnR9IGlzIG51bGwgYW5kIHRoaXMgc2V0IGRvZXMKKyAgICAgKiAgICAgICAgIG5vdCBwZXJtaXQgbnVsbCBlbGVtZW50cworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBmcm9tRWxlbWVudH0gaXMKKyAgICAgKiAgICAgICAgIGdyZWF0ZXIgdGhhbiB7QGNvZGUgdG9FbGVtZW50fTsgb3IgaWYgdGhpcyBzZXQgaXRzZWxmCisgICAgICogICAgICAgICBoYXMgYSByZXN0cmljdGVkIHJhbmdlLCBhbmQge0Bjb2RlIGZyb21FbGVtZW50fSBvcgorICAgICAqICAgICAgICAge0Bjb2RlIHRvRWxlbWVudH0gbGllcyBvdXRzaWRlIHRoZSBib3VuZHMgb2YgdGhlIHJhbmdlLgorICAgICAqLworICAgIE5hdmlnYWJsZVNldDxFPiBzdWJTZXQoRSBmcm9tRWxlbWVudCwgYm9vbGVhbiBmcm9tSW5jbHVzaXZlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgRSB0b0VsZW1lbnQsICAgYm9vbGVhbiB0b0luY2x1c2l2ZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgdmlldyBvZiB0aGUgcG9ydGlvbiBvZiB0aGlzIHNldCB3aG9zZSBlbGVtZW50cyBhcmUgbGVzcyB0aGFuCisgICAgICogKG9yIGVxdWFsIHRvLCBpZiB7QGNvZGUgaW5jbHVzaXZlfSBpcyB0cnVlKSB7QGNvZGUgdG9FbGVtZW50fS4gIFRoZQorICAgICAqIHJldHVybmVkIHNldCBpcyBiYWNrZWQgYnkgdGhpcyBzZXQsIHNvIGNoYW5nZXMgaW4gdGhlIHJldHVybmVkIHNldCBhcmUKKyAgICAgKiByZWZsZWN0ZWQgaW4gdGhpcyBzZXQsIGFuZCB2aWNlLXZlcnNhLiAgVGhlIHJldHVybmVkIHNldCBzdXBwb3J0cyBhbGwKKyAgICAgKiBvcHRpb25hbCBzZXQgb3BlcmF0aW9ucyB0aGF0IHRoaXMgc2V0IHN1cHBvcnRzLgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybmVkIHNldCB3aWxsIHRocm93IGFuIHtAY29kZSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259CisgICAgICogb24gYW4gYXR0ZW1wdCB0byBpbnNlcnQgYW4gZWxlbWVudCBvdXRzaWRlIGl0cyByYW5nZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0b0VsZW1lbnQgaGlnaCBlbmRwb2ludCBvZiB0aGUgcmV0dXJuZWQgc2V0CisgICAgICogQHBhcmFtIGluY2x1c2l2ZSB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGhpZ2ggZW5kcG9pbnQKKyAgICAgKiAgICAgICAgaXMgdG8gYmUgaW5jbHVkZWQgaW4gdGhlIHJldHVybmVkIHZpZXcKKyAgICAgKiBAcmV0dXJuIGEgdmlldyBvZiB0aGUgcG9ydGlvbiBvZiB0aGlzIHNldCB3aG9zZSBlbGVtZW50cyBhcmUgbGVzcyB0aGFuCisgICAgICogICAgICAgICAob3IgZXF1YWwgdG8sIGlmIHtAY29kZSBpbmNsdXNpdmV9IGlzIHRydWUpIHtAY29kZSB0b0VsZW1lbnR9CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYge0Bjb2RlIHRvRWxlbWVudH0gaXMgbm90IGNvbXBhdGlibGUKKyAgICAgKiAgICAgICAgIHdpdGggdGhpcyBzZXQncyBjb21wYXJhdG9yIChvciwgaWYgdGhlIHNldCBoYXMgbm8gY29tcGFyYXRvciwKKyAgICAgKiAgICAgICAgIGlmIHtAY29kZSB0b0VsZW1lbnR9IGRvZXMgbm90IGltcGxlbWVudCB7QGxpbmsgQ29tcGFyYWJsZX0pLgorICAgICAqICAgICAgICAgSW1wbGVtZW50YXRpb25zIG1heSwgYnV0IGFyZSBub3QgcmVxdWlyZWQgdG8sIHRocm93IHRoaXMKKyAgICAgKiAgICAgICAgIGV4Y2VwdGlvbiBpZiB7QGNvZGUgdG9FbGVtZW50fSBjYW5ub3QgYmUgY29tcGFyZWQgdG8gZWxlbWVudHMKKyAgICAgKiAgICAgICAgIGN1cnJlbnRseSBpbiB0aGUgc2V0LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIHRvRWxlbWVudH0gaXMgbnVsbCBhbmQKKyAgICAgKiAgICAgICAgIHRoaXMgc2V0IGRvZXMgbm90IHBlcm1pdCBudWxsIGVsZW1lbnRzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhpcyBzZXQgaXRzZWxmIGhhcyBhCisgICAgICogICAgICAgICByZXN0cmljdGVkIHJhbmdlLCBhbmQge0Bjb2RlIHRvRWxlbWVudH0gbGllcyBvdXRzaWRlIHRoZQorICAgICAqICAgICAgICAgYm91bmRzIG9mIHRoZSByYW5nZQorICAgICAqLworICAgIE5hdmlnYWJsZVNldDxFPiBoZWFkU2V0KEUgdG9FbGVtZW50LCBib29sZWFuIGluY2x1c2l2ZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgdmlldyBvZiB0aGUgcG9ydGlvbiBvZiB0aGlzIHNldCB3aG9zZSBlbGVtZW50cyBhcmUgZ3JlYXRlcgorICAgICAqIHRoYW4gKG9yIGVxdWFsIHRvLCBpZiB7QGNvZGUgaW5jbHVzaXZlfSBpcyB0cnVlKSB7QGNvZGUgZnJvbUVsZW1lbnR9LgorICAgICAqIFRoZSByZXR1cm5lZCBzZXQgaXMgYmFja2VkIGJ5IHRoaXMgc2V0LCBzbyBjaGFuZ2VzIGluIHRoZSByZXR1cm5lZCBzZXQKKyAgICAgKiBhcmUgcmVmbGVjdGVkIGluIHRoaXMgc2V0LCBhbmQgdmljZS12ZXJzYS4gIFRoZSByZXR1cm5lZCBzZXQgc3VwcG9ydHMKKyAgICAgKiBhbGwgb3B0aW9uYWwgc2V0IG9wZXJhdGlvbnMgdGhhdCB0aGlzIHNldCBzdXBwb3J0cy4KKyAgICAgKgorICAgICAqIDxwPlRoZSByZXR1cm5lZCBzZXQgd2lsbCB0aHJvdyBhbiB7QGNvZGUgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufQorICAgICAqIG9uIGFuIGF0dGVtcHQgdG8gaW5zZXJ0IGFuIGVsZW1lbnQgb3V0c2lkZSBpdHMgcmFuZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZnJvbUVsZW1lbnQgbG93IGVuZHBvaW50IG9mIHRoZSByZXR1cm5lZCBzZXQKKyAgICAgKiBAcGFyYW0gaW5jbHVzaXZlIHtAY29kZSB0cnVlfSBpZiB0aGUgbG93IGVuZHBvaW50CisgICAgICogICAgICAgIGlzIHRvIGJlIGluY2x1ZGVkIGluIHRoZSByZXR1cm5lZCB2aWV3CisgICAgICogQHJldHVybiBhIHZpZXcgb2YgdGhlIHBvcnRpb24gb2YgdGhpcyBzZXQgd2hvc2UgZWxlbWVudHMgYXJlIGdyZWF0ZXIKKyAgICAgKiAgICAgICAgIHRoYW4gb3IgZXF1YWwgdG8ge0Bjb2RlIGZyb21FbGVtZW50fQorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHtAY29kZSBmcm9tRWxlbWVudH0gaXMgbm90IGNvbXBhdGlibGUKKyAgICAgKiAgICAgICAgIHdpdGggdGhpcyBzZXQncyBjb21wYXJhdG9yIChvciwgaWYgdGhlIHNldCBoYXMgbm8gY29tcGFyYXRvciwKKyAgICAgKiAgICAgICAgIGlmIHtAY29kZSBmcm9tRWxlbWVudH0gZG9lcyBub3QgaW1wbGVtZW50IHtAbGluayBDb21wYXJhYmxlfSkuCisgICAgICogICAgICAgICBJbXBsZW1lbnRhdGlvbnMgbWF5LCBidXQgYXJlIG5vdCByZXF1aXJlZCB0bywgdGhyb3cgdGhpcworICAgICAqICAgICAgICAgZXhjZXB0aW9uIGlmIHtAY29kZSBmcm9tRWxlbWVudH0gY2Fubm90IGJlIGNvbXBhcmVkIHRvIGVsZW1lbnRzCisgICAgICogICAgICAgICBjdXJyZW50bHkgaW4gdGhlIHNldC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBmcm9tRWxlbWVudH0gaXMgbnVsbAorICAgICAqICAgICAgICAgYW5kIHRoaXMgc2V0IGRvZXMgbm90IHBlcm1pdCBudWxsIGVsZW1lbnRzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhpcyBzZXQgaXRzZWxmIGhhcyBhCisgICAgICogICAgICAgICByZXN0cmljdGVkIHJhbmdlLCBhbmQge0Bjb2RlIGZyb21FbGVtZW50fSBsaWVzIG91dHNpZGUgdGhlCisgICAgICogICAgICAgICBib3VuZHMgb2YgdGhlIHJhbmdlCisgICAgICovCisgICAgTmF2aWdhYmxlU2V0PEU+IHRhaWxTZXQoRSBmcm9tRWxlbWVudCwgYm9vbGVhbiBpbmNsdXNpdmUpOworCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogPHA+RXF1aXZhbGVudCB0byB7QGNvZGUgc3ViU2V0KGZyb21FbGVtZW50LCB0cnVlLCB0b0VsZW1lbnQsIGZhbHNlKX0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiAgICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBTb3J0ZWRTZXQ8RT4gc3ViU2V0KEUgZnJvbUVsZW1lbnQsIEUgdG9FbGVtZW50KTsKKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIDxwPkVxdWl2YWxlbnQgdG8ge0Bjb2RlIGhlYWRTZXQodG9FbGVtZW50LCBmYWxzZSl9LgorICAgICAqCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CituYSAgICAgKi8KKyAgICBTb3J0ZWRTZXQ8RT4gaGVhZFNldChFIHRvRWxlbWVudCk7CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiA8cD5FcXVpdmFsZW50IHRvIHtAY29kZSB0YWlsU2V0KGZyb21FbGVtZW50LCB0cnVlKX0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiAgICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBTb3J0ZWRTZXQ8RT4gdGFpbFNldChFIGZyb21FbGVtZW50KTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTm9TdWNoRWxlbWVudEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGM3MmVhMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvTm9TdWNoRWxlbWVudEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisKKy8qKgorICogVGhyb3duIHdoZW4gdHJ5aW5nIHRvIHJldHJpZXZlIGFuIGVsZW1lbnQKKyAqIHBhc3QgdGhlIGVuZCBvZiBhbiBFbnVtZXJhdGlvbiBvciBJdGVyYXRvci4KKyAqLworcHVibGljIGNsYXNzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDY3Njk4MjkyNTA2Mzk0MTE4ODBMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbn0gd2l0aCB0aGUgY3VycmVudCBzdGFjaworICAgICAqIHRyYWNlIGZpbGxlZCBpbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBOb1N1Y2hFbGVtZW50RXhjZXB0aW9ufSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrCisgICAgICogdHJhY2UgYW5kIG1lc3NhZ2UgZmlsbGVkIGluLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGUgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKFN0cmluZyBkZXRhaWxNZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKGRldGFpbE1lc3NhZ2UpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9PYnNlcnZhYmxlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL09ic2VydmFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYzI4NzdlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9PYnNlcnZhYmxlLmphdmEKQEAgLTAsMCArMSwxNTAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisvKioKKyAqIE9ic2VydmFibGUgaXMgdXNlZCB0byBub3RpZnkgYSBncm91cCBvZiBPYnNlcnZlciBvYmplY3RzIHdoZW4gYSBjaGFuZ2UKKyAqIG9jY3Vycy4gT24gY3JlYXRpb24sIHRoZSBzZXQgb2Ygb2JzZXJ2ZXJzIGlzIGVtcHR5LiBBZnRlciBhIGNoYW5nZSBvY2N1cnJlZCwKKyAqIHRoZSBhcHBsaWNhdGlvbiBjYW4gY2FsbCB0aGUge0BsaW5rICNub3RpZnlPYnNlcnZlcnMoKX0gbWV0aG9kLiBUaGlzIHdpbGwKKyAqIGNhdXNlIHRoZSBpbnZvY2F0aW9uIG9mIHRoZSB7QGNvZGUgdXBkYXRlKCl9IG1ldGhvZCBvZiBhbGwgcmVnaXN0ZXJlZAorICogT2JzZXJ2ZXJzLiBUaGUgb3JkZXIgb2YgaW52b2NhdGlvbiBpcyBub3Qgc3BlY2lmaWVkLiBUaGlzIGltcGxlbWVudGF0aW9uIHdpbGwKKyAqIGNhbGwgdGhlIE9ic2VydmVycyBpbiB0aGUgb3JkZXIgdGhleSByZWdpc3RlcmVkLiBTdWJjbGFzc2VzIGFyZSBjb21wbGV0ZWx5CisgKiBmcmVlIGluIHdoYXQgb3JkZXIgdGhleSBjYWxsIHRoZSB1cGRhdGUgbWV0aG9kcy4KKyAqCisgKiBAc2VlIE9ic2VydmVyCisgKi8KK3B1YmxpYyBjbGFzcyBPYnNlcnZhYmxlIHsKKworICAgIExpc3Q8T2JzZXJ2ZXI+IG9ic2VydmVycyA9IG5ldyBBcnJheUxpc3Q8T2JzZXJ2ZXI+KCk7CisKKyAgICBib29sZWFuIGNoYW5nZWQgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIE9ic2VydmFibGV9IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JzZXJ2YWJsZSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgb2JzZXJ2ZXIgdG8gdGhlIGxpc3Qgb2Ygb2JzZXJ2ZXJzLiBJZiBpdCBpcyBhbHJlYWR5CisgICAgICogcmVnaXN0ZXJlZCwgaXQgaXMgbm90IGFkZGVkIGEgc2Vjb25kIHRpbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JzZXJ2ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBPYnNlcnZlciB0byBhZGQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkT2JzZXJ2ZXIoT2JzZXJ2ZXIgb2JzZXJ2ZXIpIHsKKyAgICAgICAgaWYgKG9ic2VydmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgaWYgKCFvYnNlcnZlcnMuY29udGFpbnMob2JzZXJ2ZXIpKQorICAgICAgICAgICAgICAgIG9ic2VydmVycy5hZGQob2JzZXJ2ZXIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xlYXJzIHRoZSBjaGFuZ2VkIGZsYWcgZm9yIHRoaXMge0Bjb2RlIE9ic2VydmFibGV9LiBBZnRlciBjYWxsaW5nCisgICAgICoge0Bjb2RlIGNsZWFyQ2hhbmdlZCgpfSwge0Bjb2RlIGhhc0NoYW5nZWQoKX0gd2lsbCByZXR1cm4ge0Bjb2RlIGZhbHNlfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBjbGVhckNoYW5nZWQoKSB7CisgICAgICAgIGNoYW5nZWQgPSBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Ygb2JzZXJ2ZXJzIHJlZ2lzdGVyZWQgdG8gdGhpcyB7QGNvZGUgT2JzZXJ2YWJsZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2Ygb2JzZXJ2ZXJzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY291bnRPYnNlcnZlcnMoKSB7CisgICAgICAgIHJldHVybiBvYnNlcnZlcnMuc2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCBvYnNlcnZlciBmcm9tIHRoZSBsaXN0IG9mIG9ic2VydmVycy4gUGFzc2luZyBudWxsCisgICAgICogd29uJ3QgZG8gYW55dGhpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JzZXJ2ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYnNlcnZlciB0byByZW1vdmUuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGRlbGV0ZU9ic2VydmVyKE9ic2VydmVyIG9ic2VydmVyKSB7CisgICAgICAgIG9ic2VydmVycy5yZW1vdmUob2JzZXJ2ZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIG9ic2VydmVycyBmcm9tIHRoZSBsaXN0IG9mIG9ic2VydmVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgZGVsZXRlT2JzZXJ2ZXJzKCkgeworICAgICAgICBvYnNlcnZlcnMuY2xlYXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjaGFuZ2VkIGZsYWcgZm9yIHRoaXMge0Bjb2RlIE9ic2VydmFibGV9LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gd2hlbiB0aGUgY2hhbmdlZCBmbGFnIGZvciB0aGlzIHtAY29kZSBPYnNlcnZhYmxlfSBpcworICAgICAqICAgICAgICAgc2V0LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGFuZ2VkKCkgeworICAgICAgICByZXR1cm4gY2hhbmdlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB7QGNvZGUgaGFzQ2hhbmdlZCgpfSByZXR1cm5zIHtAY29kZSB0cnVlfSwgY2FsbHMgdGhlIHtAY29kZSB1cGRhdGUoKX0KKyAgICAgKiBtZXRob2QgZm9yIGV2ZXJ5IG9ic2VydmVyIGluIHRoZSBsaXN0IG9mIG9ic2VydmVycyB1c2luZyBudWxsIGFzIHRoZQorICAgICAqIGFyZ3VtZW50LiBBZnRlcndhcmRzLCBjYWxscyB7QGNvZGUgY2xlYXJDaGFuZ2VkKCl9LgorICAgICAqIDxwPgorICAgICAqIEVxdWl2YWxlbnQgdG8gY2FsbGluZyB7QGNvZGUgbm90aWZ5T2JzZXJ2ZXJzKG51bGwpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBub3RpZnlPYnNlcnZlcnMoKSB7CisgICAgICAgIG5vdGlmeU9ic2VydmVycyhudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB7QGNvZGUgaGFzQ2hhbmdlZCgpfSByZXR1cm5zIHtAY29kZSB0cnVlfSwgY2FsbHMgdGhlIHtAY29kZSB1cGRhdGUoKX0KKyAgICAgKiBtZXRob2QgZm9yIGV2ZXJ5IE9ic2VydmVyIGluIHRoZSBsaXN0IG9mIG9ic2VydmVycyB1c2luZyB0aGUgc3BlY2lmaWVkCisgICAgICogYXJndW1lbnQuIEFmdGVyd2FyZHMgY2FsbHMge0Bjb2RlIGNsZWFyQ2hhbmdlZCgpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICB0aGUgYXJndW1lbnQgcGFzc2VkIHRvIHtAY29kZSB1cGRhdGUoKX0uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHZvaWQgbm90aWZ5T2JzZXJ2ZXJzKE9iamVjdCBkYXRhKSB7CisgICAgICAgIGludCBzaXplID0gMDsKKyAgICAgICAgT2JzZXJ2ZXJbXSBhcnJheXMgPSBudWxsOworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGlmIChoYXNDaGFuZ2VkKCkpIHsKKyAgICAgICAgICAgICAgICBjbGVhckNoYW5nZWQoKTsKKyAgICAgICAgICAgICAgICBzaXplID0gb2JzZXJ2ZXJzLnNpemUoKTsKKyAgICAgICAgICAgICAgICBhcnJheXMgPSBuZXcgT2JzZXJ2ZXJbc2l6ZV07CisgICAgICAgICAgICAgICAgb2JzZXJ2ZXJzLnRvQXJyYXkoYXJyYXlzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoYXJyYXlzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoT2JzZXJ2ZXIgb2JzZXJ2ZXIgOiBhcnJheXMpIHsKKyAgICAgICAgICAgICAgICBvYnNlcnZlci51cGRhdGUodGhpcywgZGF0YSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjaGFuZ2VkIGZsYWcgZm9yIHRoaXMge0Bjb2RlIE9ic2VydmFibGV9LiBBZnRlciBjYWxsaW5nCisgICAgICoge0Bjb2RlIHNldENoYW5nZWQoKX0sIHtAY29kZSBoYXNDaGFuZ2VkKCl9IHdpbGwgcmV0dXJuIHtAY29kZSB0cnVlfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRDaGFuZ2VkKCkgeworICAgICAgICBjaGFuZ2VkID0gdHJ1ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL09ic2VydmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL09ic2VydmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTljYzNhNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvT2JzZXJ2ZXIuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworCisvKioKKyAqIHtAY29kZSBPYnNlcnZlcn0gaXMgdGhlIGludGVyZmFjZSB0byBiZSBpbXBsZW1lbnRlZCBieSBvYmplY3RzIHRoYXQKKyAqIHJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHVwZGF0ZXMgb24gYW4ge0Bjb2RlIE9ic2VydmFibGV9IG9iamVjdC4KKyAqCisgKiBAc2VlIE9ic2VydmFibGUKKyAqLworcHVibGljIGludGVyZmFjZSBPYnNlcnZlciB7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgaWYgdGhlIHNwZWNpZmllZCB7QGNvZGUgT2JzZXJ2YWJsZX0gb2JqZWN0J3MKKyAgICAgKiB7QGNvZGUgbm90aWZ5T2JzZXJ2ZXJzfSBtZXRob2QgaXMgY2FsbGVkIChiZWNhdXNlIHRoZSB7QGNvZGUgT2JzZXJ2YWJsZX0KKyAgICAgKiBvYmplY3QgaGFzIGJlZW4gdXBkYXRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYnNlcnZhYmxlCisgICAgICogICAgICAgICAgICB0aGUge0BsaW5rIE9ic2VydmFibGV9IG9iamVjdC4KKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGEgcGFzc2VkIHRvIHtAbGluayBPYnNlcnZhYmxlI25vdGlmeU9ic2VydmVycyhPYmplY3QpfS4KKyAgICAgKi8KKyAgICB2b2lkIHVwZGF0ZShPYnNlcnZhYmxlIG9ic2VydmFibGUsIE9iamVjdCBkYXRhKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvUHJpb3JpdHlRdWV1ZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9Qcmlvcml0eVF1ZXVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTBjNTk2OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvUHJpb3JpdHlRdWV1ZS5qYXZhCkBAIC0wLDAgKzEsNDA4IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBqYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKKy8qKgorICogQSBQcmlvcml0eVF1ZXVlIGhvbGRzIGVsZW1lbnRzIG9uIGEgcHJpb3JpdHkgaGVhcCwgd2hpY2ggb3JkZXJzIHRoZSBlbGVtZW50cworICogYWNjb3JkaW5nIHRvIHRoZWlyIG5hdHVyYWwgb3JkZXIgb3IgYWNjb3JkaW5nIHRvIHRoZSBjb21wYXJhdG9yIHNwZWNpZmllZCBhdAorICogY29uc3RydWN0aW9uIHRpbWUuIElmIHRoZSBxdWV1ZSB1c2VzIG5hdHVyYWwgb3JkZXJpbmcsIG9ubHkgZWxlbWVudHMgdGhhdCBhcmUKKyAqIGNvbXBhcmFibGUgYXJlIHBlcm1pdHRlZCB0byBiZSBpbnNlcnRlZCBpbnRvIHRoZSBxdWV1ZS4KKyAqIDxwPgorICogVGhlIGxlYXN0IGVsZW1lbnQgb2YgdGhlIHNwZWNpZmllZCBvcmRlcmluZyBpcyBzdG9yZWQgYXQgdGhlIGhlYWQgb2YgdGhlCisgKiBxdWV1ZSBhbmQgdGhlIGdyZWF0ZXN0IGVsZW1lbnQgaXMgc3RvcmVkIGF0IHRoZSB0YWlsIG9mIHRoZSBxdWV1ZS4KKyAqIDxwPgorICogQSBQcmlvcml0eVF1ZXVlIGlzIG5vdCBzeW5jaHJvbml6ZWQuIElmIG11bHRpcGxlIHRocmVhZHMgd2lsbCBoYXZlIHRvIGFjY2VzcworICogaXQgY29uY3VycmVudGx5LCB1c2UgdGhlIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5Qcmlvcml0eUJsb2NraW5nUXVldWV9LgorICovCitwdWJsaWMgY2xhc3MgUHJpb3JpdHlRdWV1ZTxFPiBleHRlbmRzIEFic3RyYWN0UXVldWU8RT4gaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTc3MjA4MDUwNTczMDU4MDQxMTFMOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfQ0FQQUNJVFkgPSAxMTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGRvdWJsZSBERUZBVUxUX0lOSVRfQ0FQQUNJVFlfUkFUSU8gPSAxLjE7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9DQVBBQ0lUWV9SQVRJTyA9IDI7CisKKyAgICBwcml2YXRlIGludCBzaXplOworCisgICAgcHJpdmF0ZSBDb21wYXJhdG9yPD8gc3VwZXIgRT4gY29tcGFyYXRvcjsKKworICAgIHByaXZhdGUgdHJhbnNpZW50IEVbXSBlbGVtZW50czsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBwcmlvcml0eSBxdWV1ZSB3aXRoIGFuIGluaXRpYWwgY2FwYWNpdHkgb2YgMTEgYW5kIG5hdHVyYWwKKyAgICAgKiBvcmRlcmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpb3JpdHlRdWV1ZSgpIHsKKyAgICAgICAgdGhpcyhERUZBVUxUX0NBUEFDSVRZKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgcHJpb3JpdHkgcXVldWUgd2l0aCB0aGUgc3BlY2lmaWVkIGNhcGFjaXR5IGFuZCBuYXR1cmFsCisgICAgICogb3JkZXJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5pdGlhbENhcGFjaXR5CisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGNhcGFjaXR5LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGluaXRpYWxDYXBhY2l0eSBpcyBsZXNzIHRoYW4gMS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpb3JpdHlRdWV1ZShpbnQgaW5pdGlhbENhcGFjaXR5KSB7CisgICAgICAgIHRoaXMoaW5pdGlhbENhcGFjaXR5LCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgcHJpb3JpdHkgcXVldWUgd2l0aCB0aGUgc3BlY2lmaWVkIGNhcGFjaXR5IGFuZCBjb21wYXJhdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGluaXRpYWxDYXBhY2l0eQorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBjYXBhY2l0eS4KKyAgICAgKiBAcGFyYW0gY29tcGFyYXRvcgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBjb21wYXJhdG9yLiBJZiBpdCBpcyBudWxsLCB0aGUgbmF0dXJhbCBvcmRlcmluZworICAgICAqICAgICAgICAgICAgd2lsbCBiZSB1c2VkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGluaXRpYWxDYXBhY2l0eSBpcyBsZXNzIHRoYW4gMS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpb3JpdHlRdWV1ZShpbnQgaW5pdGlhbENhcGFjaXR5LCBDb21wYXJhdG9yPD8gc3VwZXIgRT4gY29tcGFyYXRvcikgeworICAgICAgICBpZiAoaW5pdGlhbENhcGFjaXR5IDwgMSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGVsZW1lbnRzID0gbmV3RWxlbWVudEFycmF5KGluaXRpYWxDYXBhY2l0eSk7CisgICAgICAgIHRoaXMuY29tcGFyYXRvciA9IGNvbXBhcmF0b3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHByaW9yaXR5IHF1ZXVlIHRoYXQgY29udGFpbnMgdGhlIGVsZW1lbnRzIG9mIGEgY29sbGVjdGlvbi4KKyAgICAgKiBUaGUgY29uc3RydWN0ZWQgcHJpb3JpdHkgcXVldWUgaGFzIHRoZSBpbml0aWFsIGNhcGFjaXR5IG9mIDExMCUgb2YgdGhlCisgICAgICogc2l6ZSBvZiB0aGUgY29sbGVjdGlvbi4gVGhlIHF1ZXVlIHVzZXMgbmF0dXJhbCBvcmRlcmluZyB0byBvcmRlciBpdHMKKyAgICAgKiBlbGVtZW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgY29sbGVjdGlvbiB3aG9zZSBlbGVtZW50cyB3aWxsIGJlIGFkZGVkIHRvIHRoZSBwcmlvcml0eQorICAgICAqICAgICAgICAgICAgcXVldWUgdG8gYmUgY29uc3RydWN0ZWQuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgb2YgdGhlIGVsZW1lbnRzIGluIHRoZSBjb2xsZWN0aW9uIGFyZSBub3QgY29tcGFyYWJsZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IG9mIHRoZSBlbGVtZW50cyBpbiB0aGUgY29sbGVjdGlvbiBhcmUgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpb3JpdHlRdWV1ZShDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjKSB7CisgICAgICAgIGlmIChjIGluc3RhbmNlb2YgUHJpb3JpdHlRdWV1ZSkgeworICAgICAgICAgICAgZ2V0RnJvbVByaW9yaXR5UXVldWUoKFByaW9yaXR5UXVldWU8PyBleHRlbmRzIEU+KSBjKTsKKyAgICAgICAgfSBlbHNlIGlmIChjIGluc3RhbmNlb2YgU29ydGVkU2V0KSB7CisgICAgICAgICAgICBnZXRGcm9tU29ydGVkU2V0KChTb3J0ZWRTZXQ8PyBleHRlbmRzIEU+KSBjKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGluaXRTaXplKGMpOworICAgICAgICAgICAgYWRkQWxsKGMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHByaW9yaXR5IHF1ZXVlIHRoYXQgY29udGFpbnMgdGhlIGVsZW1lbnRzIG9mIGFub3RoZXIKKyAgICAgKiBwcmlvcml0eSBxdWV1ZS4gVGhlIGNvbnN0cnVjdGVkIHByaW9yaXR5IHF1ZXVlIGhhcyB0aGUgaW5pdGlhbCBjYXBhY2l0eQorICAgICAqIG9mIDExMCUgb2YgdGhlIHNwZWNpZmllZCBvbmUuIEJvdGggcHJpb3JpdHkgcXVldWVzIGhhdmUgdGhlIHNhbWUKKyAgICAgKiBjb21wYXJhdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmlvcml0eSBxdWV1ZSB3aG9zZSBlbGVtZW50cyB3aWxsIGJlIGFkZGVkIHRvIHRoZQorICAgICAqICAgICAgICAgICAgcHJpb3JpdHkgcXVldWUgdG8gYmUgY29uc3RydWN0ZWQuCisgICAgICovCisgICAgcHVibGljIFByaW9yaXR5UXVldWUoUHJpb3JpdHlRdWV1ZTw/IGV4dGVuZHMgRT4gYykgeworICAgICAgICBnZXRGcm9tUHJpb3JpdHlRdWV1ZShjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgcHJpb3JpdHkgcXVldWUgdGhhdCBjb250YWlucyB0aGUgZWxlbWVudHMgb2YgYSBzb3J0ZWQgc2V0LgorICAgICAqIFRoZSBjb25zdHJ1Y3RlZCBwcmlvcml0eSBxdWV1ZSBoYXMgdGhlIGluaXRpYWwgY2FwYWNpdHkgb2YgMTEwJSBvZiB0aGUKKyAgICAgKiBzaXplIG9mIHRoZSBzb3J0ZWQgc2V0LiBUaGUgcHJpb3JpdHkgcXVldWUgd2lsbCBoYXZlIHRoZSBzYW1lIGNvbXBhcmF0b3IKKyAgICAgKiBhcyB0aGUgc29ydGVkIHNldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjCisgICAgICogICAgICAgICAgICB0aGUgc29ydGVkIHNldCB3aG9zZSBlbGVtZW50cyB3aWxsIGJlIGFkZGVkIHRvIHRoZSBwcmlvcml0eQorICAgICAqICAgICAgICAgICAgcXVldWUgdG8gYmUgY29uc3RydWN0ZWQuCisgICAgICovCisgICAgcHVibGljIFByaW9yaXR5UXVldWUoU29ydGVkU2V0PD8gZXh0ZW5kcyBFPiBjKSB7CisgICAgICAgIGdldEZyb21Tb3J0ZWRTZXQoYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgaXRlcmF0b3Igb2YgdGhlIHByaW9yaXR5IHF1ZXVlLCB3aGljaCB3aWxsIG5vdCByZXR1cm4gZWxlbWVudHMKKyAgICAgKiBpbiBhbnkgc3BlY2lmaWVkIG9yZGVyaW5nLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaXRlcmF0b3Igb2YgdGhlIHByaW9yaXR5IHF1ZXVlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJdGVyYXRvcjxFPiBpdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBQcmlvcml0eUl0ZXJhdG9yKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2l6ZSBvZiB0aGUgcHJpb3JpdHkgcXVldWUuIElmIHRoZSBzaXplIG9mIHRoZSBxdWV1ZSBpcyBncmVhdGVyCisgICAgICogdGhhbiB0aGUgSW50ZWdlci5NQVgsIHRoZW4gaXQgcmV0dXJucyBJbnRlZ2VyLk1BWC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNpemUgb2YgdGhlIHByaW9yaXR5IHF1ZXVlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIHNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhbGwgdGhlIGVsZW1lbnRzIG9mIHRoZSBwcmlvcml0eSBxdWV1ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgQXJyYXlzLmZpbGwoZWxlbWVudHMsIG51bGwpOworICAgICAgICBzaXplID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBlbGVtZW50IHRvIHRoZSBwcmlvcml0eSBxdWV1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvCisgICAgICogICAgICAgICAgICB0aGUgZWxlbWVudCB0byBhZGQgdG8gdGhlIHByaW9yaXR5IHF1ZXVlLgorICAgICAqIEByZXR1cm4gYWx3YXlzIHRydWUKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbGVtZW50IGNhbm5vdCBiZSBjb21wYXJlZCB3aXRoIHRoZSBlbGVtZW50cyBpbiB0aGUKKyAgICAgKiAgICAgICAgICAgICBwcmlvcml0eSBxdWV1ZSB1c2luZyB0aGUgb3JkZXJpbmcgb2YgdGhlIHByaW9yaXR5IHF1ZXVlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG9mZmVyKEUgbykgeworICAgICAgICBpZiAobyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBncm93VG9TaXplKHNpemUgKyAxKTsKKyAgICAgICAgZWxlbWVudHNbc2l6ZV0gPSBvOworICAgICAgICBzaWZ0VXAoc2l6ZSsrKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhbmQgcmVtb3ZlcyB0aGUgaGVhZCBvZiB0aGUgcXVldWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWFkIG9mIHRoZSBxdWV1ZSBvciBudWxsIGlmIHRoZSBxdWV1ZSBpcyBlbXB0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRSBwb2xsKCkgeworICAgICAgICBpZiAoaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBFIHJlc3VsdCA9IGVsZW1lbnRzWzBdOworICAgICAgICByZW1vdmVBdCgwKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGJ1dCBkb2VzIG5vdCByZW1vdmUgdGhlIGhlYWQgb2YgdGhlIHF1ZXVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGUgcXVldWUgb3IgbnVsbCBpZiB0aGUgcXVldWUgaXMgZW1wdHkuCisgICAgICovCisgICAgcHVibGljIEUgcGVlaygpIHsKKyAgICAgICAgaWYgKGlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVsZW1lbnRzWzBdOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNvbXBhcmF0b3Igb2YgdGhlIHByaW9yaXR5IHF1ZXVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29tcGFyYXRvciBvZiB0aGUgcHJpb3JpdHkgcXVldWUgb3IgbnVsbCBpZiB0aGUgbmF0dXJhbAorICAgICAqICAgICAgICAgb3JkZXJpbmcgaXMgdXNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29tcGFyYXRvcjw/IHN1cGVyIEU+IGNvbXBhcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBjb21wYXJhdG9yOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCBvYmplY3QgZnJvbSB0aGUgcHJpb3JpdHkgcXVldWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbworICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBiZSByZW1vdmVkLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgb2JqZWN0IHdhcyBpbiB0aGUgcHJpb3JpdHkgcXVldWUsIGZhbHNlIGlmIHRoZSBvYmplY3QKKyAgICAgKiAgICAgICAgIHdhcyBub3QgaW4gdGhlIHByaW9yaXR5IHF1ZXVlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3QgbykgeworICAgICAgICBpZiAobyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgdGFyZ2V0SW5kZXggPSAwOyB0YXJnZXRJbmRleCA8IHNpemU7IHRhcmdldEluZGV4KyspIHsKKyAgICAgICAgICAgIGlmIChvLmVxdWFscyhlbGVtZW50c1t0YXJnZXRJbmRleF0pKSB7CisgICAgICAgICAgICAgICAgcmVtb3ZlQXQodGFyZ2V0SW5kZXgpOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHRvIHRoZSBwcmlvcml0eSBxdWV1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGJlIGFkZGVkLgorICAgICAqIEByZXR1cm4gYWx3YXlzIHRydWUuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZWxlbWVudCBjYW5ub3QgYmUgY29tcGFyZWQgd2l0aCB0aGUgZWxlbWVudHMgaW4gdGhlCisgICAgICogICAgICAgICAgICAgcHJpb3JpdHkgcXVldWUgdXNpbmcgdGhlIG9yZGVyaW5nIG9mIHRoZSBwcmlvcml0eSBxdWV1ZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG99IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBhZGQoRSBvKSB7CisgICAgICAgIHJldHVybiBvZmZlcihvKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIFByaW9yaXR5SXRlcmF0b3IgaW1wbGVtZW50cyBJdGVyYXRvcjxFPiB7CisKKyAgICAgICAgcHJpdmF0ZSBpbnQgY3VycmVudEluZGV4ID0gLTE7CisKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGFsbG93UmVtb3ZlID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiBjdXJyZW50SW5kZXggPCBzaXplIC0gMTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFIG5leHQoKSB7CisgICAgICAgICAgICBpZiAoIWhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhbGxvd1JlbW92ZSA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gZWxlbWVudHNbKytjdXJyZW50SW5kZXhdOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICAgICAgaWYgKCFhbGxvd1JlbW92ZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFsbG93UmVtb3ZlID0gZmFsc2U7CisgICAgICAgICAgICByZW1vdmVBdChjdXJyZW50SW5kZXgtLSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIGluLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisgICAgICAgIGludCBjYXBhY2l0eSA9IGluLnJlYWRJbnQoKTsKKyAgICAgICAgZWxlbWVudHMgPSBuZXdFbGVtZW50QXJyYXkoY2FwYWNpdHkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgICAgICAgZWxlbWVudHNbaV0gPSAoRSkgaW4ucmVhZE9iamVjdCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHJpdmF0ZSBFW10gbmV3RWxlbWVudEFycmF5KGludCBjYXBhY2l0eSkgeworICAgICAgICByZXR1cm4gKEVbXSkgbmV3IE9iamVjdFtjYXBhY2l0eV07CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC5kZWZhdWx0V3JpdGVPYmplY3QoKTsKKyAgICAgICAgb3V0LndyaXRlSW50KGVsZW1lbnRzLmxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBvdXQud3JpdGVPYmplY3QoZWxlbWVudHNbaV0pOworICAgICAgICB9CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHJpdmF0ZSB2b2lkIGdldEZyb21Qcmlvcml0eVF1ZXVlKFByaW9yaXR5UXVldWU8PyBleHRlbmRzIEU+IGMpIHsKKyAgICAgICAgaW5pdFNpemUoYyk7CisgICAgICAgIGNvbXBhcmF0b3IgPSAoQ29tcGFyYXRvcjw/IHN1cGVyIEU+KSBjLmNvbXBhcmF0b3IoKTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShjLmVsZW1lbnRzLCAwLCBlbGVtZW50cywgMCwgYy5zaXplKCkpOworICAgICAgICBzaXplID0gYy5zaXplKCk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHJpdmF0ZSB2b2lkIGdldEZyb21Tb3J0ZWRTZXQoU29ydGVkU2V0PD8gZXh0ZW5kcyBFPiBjKSB7CisgICAgICAgIGluaXRTaXplKGMpOworICAgICAgICBjb21wYXJhdG9yID0gKENvbXBhcmF0b3I8PyBzdXBlciBFPikgYy5jb21wYXJhdG9yKCk7CisgICAgICAgIEl0ZXJhdG9yPD8gZXh0ZW5kcyBFPiBpdGVyID0gYy5pdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoaXRlci5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIGVsZW1lbnRzW3NpemUrK10gPSBpdGVyLm5leHQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZW1vdmVBdChpbnQgaW5kZXgpIHsKKyAgICAgICAgc2l6ZS0tOworICAgICAgICBlbGVtZW50c1tpbmRleF0gPSBlbGVtZW50c1tzaXplXTsKKyAgICAgICAgc2lmdERvd24oaW5kZXgpOworICAgICAgICBlbGVtZW50c1tzaXplXSA9IG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgY29tcGFyZShFIG8xLCBFIG8yKSB7CisgICAgICAgIGlmIChjb21wYXJhdG9yICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBjb21wYXJhdG9yLmNvbXBhcmUobzEsIG8yKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKChDb21wYXJhYmxlPD8gc3VwZXIgRT4pIG8xKS5jb21wYXJlVG8obzIpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzaWZ0VXAoaW50IGNoaWxkSW5kZXgpIHsKKyAgICAgICAgRSB0YXJnZXQgPSBlbGVtZW50c1tjaGlsZEluZGV4XTsKKyAgICAgICAgaW50IHBhcmVudEluZGV4OworICAgICAgICB3aGlsZSAoY2hpbGRJbmRleCA+IDApIHsKKyAgICAgICAgICAgIHBhcmVudEluZGV4ID0gKGNoaWxkSW5kZXggLSAxKSAvIDI7CisgICAgICAgICAgICBFIHBhcmVudCA9IGVsZW1lbnRzW3BhcmVudEluZGV4XTsKKyAgICAgICAgICAgIGlmIChjb21wYXJlKHBhcmVudCwgdGFyZ2V0KSA8PSAwKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbGVtZW50c1tjaGlsZEluZGV4XSA9IHBhcmVudDsKKyAgICAgICAgICAgIGNoaWxkSW5kZXggPSBwYXJlbnRJbmRleDsKKyAgICAgICAgfQorICAgICAgICBlbGVtZW50c1tjaGlsZEluZGV4XSA9IHRhcmdldDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc2lmdERvd24oaW50IHJvb3RJbmRleCkgeworICAgICAgICBFIHRhcmdldCA9IGVsZW1lbnRzW3Jvb3RJbmRleF07CisgICAgICAgIGludCBjaGlsZEluZGV4OworICAgICAgICB3aGlsZSAoKGNoaWxkSW5kZXggPSByb290SW5kZXggKiAyICsgMSkgPCBzaXplKSB7CisgICAgICAgICAgICBpZiAoY2hpbGRJbmRleCArIDEgPCBzaXplCisgICAgICAgICAgICAgICAgICAgICYmIGNvbXBhcmUoZWxlbWVudHNbY2hpbGRJbmRleCArIDFdLCBlbGVtZW50c1tjaGlsZEluZGV4XSkgPCAwKSB7CisgICAgICAgICAgICAgICAgY2hpbGRJbmRleCsrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGNvbXBhcmUodGFyZ2V0LCBlbGVtZW50c1tjaGlsZEluZGV4XSkgPD0gMCkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxlbWVudHNbcm9vdEluZGV4XSA9IGVsZW1lbnRzW2NoaWxkSW5kZXhdOworICAgICAgICAgICAgcm9vdEluZGV4ID0gY2hpbGRJbmRleDsKKyAgICAgICAgfQorICAgICAgICBlbGVtZW50c1tyb290SW5kZXhdID0gdGFyZ2V0OworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBpbml0U2l6ZShDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjKSB7CisgICAgICAgIGlmIChjID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChjLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgZWxlbWVudHMgPSBuZXdFbGVtZW50QXJyYXkoMSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpbnQgY2FwYWNpdHkgPSAoaW50KSBNYXRoLmNlaWwoYy5zaXplKCkKKyAgICAgICAgICAgICAgICAgICAgKiBERUZBVUxUX0lOSVRfQ0FQQUNJVFlfUkFUSU8pOworICAgICAgICAgICAgZWxlbWVudHMgPSBuZXdFbGVtZW50QXJyYXkoY2FwYWNpdHkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGdyb3dUb1NpemUoaW50IHNpemUpIHsKKyAgICAgICAgaWYgKHNpemUgPiBlbGVtZW50cy5sZW5ndGgpIHsKKyAgICAgICAgICAgIEVbXSBuZXdFbGVtZW50cyA9IG5ld0VsZW1lbnRBcnJheShzaXplICogREVGQVVMVF9DQVBBQ0lUWV9SQVRJTyk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVsZW1lbnRzLCAwLCBuZXdFbGVtZW50cywgMCwgZWxlbWVudHMubGVuZ3RoKTsKKyAgICAgICAgICAgIGVsZW1lbnRzID0gbmV3RWxlbWVudHM7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1Byb3BlcnRpZXMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvUHJvcGVydGllcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE3MzFhZDgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1Byb3BlcnRpZXMuamF2YQpAQCAtMCwwICsxLDc1OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtV3JpdGVyOworaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLlJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1JlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLldyaXRlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5JbGxlZ2FsQ2hhcnNldE5hbWVFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5VbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb247CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CitpbXBvcnQgb3JnLnczYy5kb20uVGV4dDsKK2ltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOworCisvKioKKyAqIEEge0Bjb2RlIFByb3BlcnRpZXN9IG9iamVjdCBpcyBhIHtAY29kZSBIYXNodGFibGV9IHdoZXJlIHRoZSBrZXlzIGFuZCB2YWx1ZXMKKyAqIG11c3QgYmUge0Bjb2RlIFN0cmluZ31zLiBFYWNoIHByb3BlcnR5IGNhbiBoYXZlIGEgZGVmYXVsdAorICoge0Bjb2RlIFByb3BlcnRpZXN9IGxpc3Qgd2hpY2ggc3BlY2lmaWVzIHRoZSBkZWZhdWx0CisgKiB2YWx1ZXMgdG8gYmUgdXNlZCB3aGVuIGEgZ2l2ZW4ga2V5IGlzIG5vdCBmb3VuZCBpbiB0aGlzIHtAY29kZSBQcm9wZXJ0aWVzfQorICogaW5zdGFuY2UuCisgKgorICogPGEgbmFtZT0iY2hhcmFjdGVyX2VuY29kaW5nIj48aDM+Q2hhcmFjdGVyIEVuY29kaW5nPC9oMz48L2E+CisgKiA8cD5Ob3RlIHRoYXQgaW4gc29tZSBjYXNlcyB7QGNvZGUgUHJvcGVydGllc30gdXNlcyBJU08tODg1OS0xIGluc3RlYWQgb2YgVVRGLTguCisgKiBJU08tODg1OS0xIGlzIG9ubHkgY2FwYWJsZSBvZiByZXByZXNlbnRpbmcgYSB0aW55IHN1YnNldCBvZiBVbmljb2RlLgorICogVXNlIGVpdGhlciB0aGUge0Bjb2RlIGxvYWRGcm9tWE1MfS97QGNvZGUgc3RvcmVUb1hNTH0gbWV0aG9kcyAod2hpY2ggdXNlIFVURi04IGJ5CisgKiBkZWZhdWx0KSBvciB0aGUge0Bjb2RlIGxvYWR9L3tAY29kZSBzdG9yZX0gb3ZlcmxvYWRzIHRoYXQgdGFrZQorICogYW4ge0Bjb2RlIE91dHB1dFN0cmVhbVdyaXRlcn0gKHNvIHlvdSBjYW4gc3VwcGx5IGEgVVRGLTggaW5zdGFuY2UpIGluc3RlYWQuCisgKgorICogQHNlZSBIYXNodGFibGUKKyAqIEBzZWUgamF2YS5sYW5nLlN5c3RlbSNnZXRQcm9wZXJ0aWVzCisgKi8KK3B1YmxpYyBjbGFzcyBQcm9wZXJ0aWVzIGV4dGVuZHMgSGFzaHRhYmxlPE9iamVjdCwgT2JqZWN0PiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0MTEyNTc4NjM0MDI5ODc0ODQwTDsKKworICAgIHByaXZhdGUgdHJhbnNpZW50IERvY3VtZW50QnVpbGRlciBidWlsZGVyID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QX0RURF9OQU1FID0gImh0dHA6Ly9qYXZhLnN1bi5jb20vZHRkL3Byb3BlcnRpZXMuZHRkIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QX0RURCA9ICI8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJVVEYtOFwiPz4iCisgICAgICAgICAgICArICIgICAgPCFFTEVNRU5UIHByb3BlcnRpZXMgKGNvbW1lbnQ/LCBlbnRyeSopID4iCisgICAgICAgICAgICArICIgICAgPCFBVFRMSVNUIHByb3BlcnRpZXMgdmVyc2lvbiBDREFUQSAjRklYRUQgXCIxLjBcIiA+IgorICAgICAgICAgICAgKyAiICAgIDwhRUxFTUVOVCBjb21tZW50ICgjUENEQVRBKSA+IgorICAgICAgICAgICAgKyAiICAgIDwhRUxFTUVOVCBlbnRyeSAoI1BDREFUQSkgPiIKKyAgICAgICAgICAgICsgIiAgICA8IUFUVExJU1QgZW50cnkga2V5IENEQVRBICNSRVFVSVJFRCA+IjsKKworICAgIC8qKgorICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlcyBmb3Iga2V5cyBub3QgZm91bmQgaW4gdGhpcyB7QGNvZGUgUHJvcGVydGllc30KKyAgICAgKiBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUHJvcGVydGllcyBkZWZhdWx0czsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOT05FID0gMCwgU0xBU0ggPSAxLCBVTklDT0RFID0gMiwgQ09OVElOVUUgPSAzLAorICAgICAgICAgICAgS0VZX0RPTkUgPSA0LCBJR05PUkUgPSA1OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgUHJvcGVydGllc30gb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBQcm9wZXJ0aWVzKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFByb3BlcnRpZXN9IG9iamVjdCB1c2luZyB0aGUgc3BlY2lmaWVkIGRlZmF1bHQKKyAgICAgKiB7QGNvZGUgUHJvcGVydGllc30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJvcGVydGllcworICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQge0Bjb2RlIFByb3BlcnRpZXN9LgorICAgICAqLworICAgIHB1YmxpYyBQcm9wZXJ0aWVzKFByb3BlcnRpZXMgcHJvcGVydGllcykgeworICAgICAgICBkZWZhdWx0cyA9IHByb3BlcnRpZXM7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGR1bXBTdHJpbmcoU3RyaW5nQnVpbGRlciBidWZmZXIsIFN0cmluZyBzdHJpbmcsIGJvb2xlYW4ga2V5KSB7CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgaWYgKCFrZXkgJiYgaSA8IHN0cmluZy5sZW5ndGgoKSAmJiBzdHJpbmcuY2hhckF0KGkpID09ICcgJykgeworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiXFwgIik7CisgICAgICAgICAgICBpKys7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKDsgaSA8IHN0cmluZy5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBjaGFyIGNoID0gc3RyaW5nLmNoYXJBdChpKTsKKyAgICAgICAgICAgIHN3aXRjaCAoY2gpIHsKKyAgICAgICAgICAgIGNhc2UgJ1x0JzoKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCJcXHQiKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJ1xuJzoKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCJcXG4iKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJ1xmJzoKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCJcXGYiKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJ1xyJzoKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCJcXHIiKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgaWYgKCJcXCMhPToiLmluZGV4T2YoY2gpID49IDAgfHwgKGtleSAmJiBjaCA9PSAnICcpKSB7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJ1xcJyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChjaCA+PSAnICcgJiYgY2ggPD0gJ34nKSB7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoY2gpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBoZXggPSBJbnRlZ2VyLnRvSGV4U3RyaW5nKGNoKTsKKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiXFx1Iik7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgNCAtIGhleC5sZW5ndGgoKTsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCIwIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChoZXgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNlYXJjaGVzIGZvciB0aGUgcHJvcGVydHkgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuIElmIHRoZSBwcm9wZXJ0eSBpcyBub3QKKyAgICAgKiBmb3VuZCwgdGhlIGRlZmF1bHQge0Bjb2RlIFByb3BlcnRpZXN9IGFyZSBjaGVja2VkLiBJZiB0aGUgcHJvcGVydHkgaXMgbm90CisgICAgICogZm91bmQgaW4gdGhlIGRlZmF1bHQge0Bjb2RlIFByb3BlcnRpZXN9LCB7QGNvZGUgbnVsbH0gaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIGZpbmQuCisgICAgICogQHJldHVybiB0aGUgbmFtZWQgcHJvcGVydHkgdmFsdWUsIG9yIHtAY29kZSBudWxsfSBpZiBpdCBjYW4ndCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFByb3BlcnR5KFN0cmluZyBuYW1lKSB7CisgICAgICAgIE9iamVjdCByZXN1bHQgPSBzdXBlci5nZXQobmFtZSk7CisgICAgICAgIFN0cmluZyBwcm9wZXJ0eSA9IHJlc3VsdCBpbnN0YW5jZW9mIFN0cmluZyA/IChTdHJpbmcpIHJlc3VsdCA6IG51bGw7CisgICAgICAgIGlmIChwcm9wZXJ0eSA9PSBudWxsICYmIGRlZmF1bHRzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHByb3BlcnR5ID0gZGVmYXVsdHMuZ2V0UHJvcGVydHkobmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHByb3BlcnR5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlYXJjaGVzIGZvciB0aGUgcHJvcGVydHkgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuIElmIHRoZSBwcm9wZXJ0eSBpcyBub3QKKyAgICAgKiBmb3VuZCwgaXQgbG9va3MgaW4gdGhlIGRlZmF1bHQge0Bjb2RlIFByb3BlcnRpZXN9LiBJZiB0aGUgcHJvcGVydHkgaXMgbm90CisgICAgICogZm91bmQgaW4gdGhlIGRlZmF1bHQge0Bjb2RlIFByb3BlcnRpZXN9LCBpdCByZXR1cm5zIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBkZWZhdWx0LgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0byBmaW5kLgorICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZWZhdWx0IHZhbHVlLgorICAgICAqIEByZXR1cm4gdGhlIG5hbWVkIHByb3BlcnR5IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUsIFN0cmluZyBkZWZhdWx0VmFsdWUpIHsKKyAgICAgICAgT2JqZWN0IHJlc3VsdCA9IHN1cGVyLmdldChuYW1lKTsKKyAgICAgICAgU3RyaW5nIHByb3BlcnR5ID0gcmVzdWx0IGluc3RhbmNlb2YgU3RyaW5nID8gKFN0cmluZykgcmVzdWx0IDogbnVsbDsKKyAgICAgICAgaWYgKHByb3BlcnR5ID09IG51bGwgJiYgZGVmYXVsdHMgIT0gbnVsbCkgeworICAgICAgICAgICAgcHJvcGVydHkgPSBkZWZhdWx0cy5nZXRQcm9wZXJ0eShuYW1lKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocHJvcGVydHkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcHJvcGVydHk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTGlzdHMgdGhlIG1hcHBpbmdzIGluIHRoaXMge0Bjb2RlIFByb3BlcnRpZXN9IHRvIHtAY29kZSBvdXR9IGluIGEgaHVtYW4tcmVhZGFibGUgZm9ybS4KKyAgICAgKiBOb3RlIHRoYXQgdmFsdWVzIGFyZSB0cnVuY2F0ZWQgdG8gMzcgY2hhcmFjdGVycywgc28gdGhpcyBtZXRob2QgaXMgcmFyZWx5IHVzZWZ1bC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBsaXN0KFByaW50U3RyZWFtIG91dCkgeworICAgICAgICBsaXN0VG9BcHBlbmRhYmxlKG91dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTGlzdHMgdGhlIG1hcHBpbmdzIGluIHRoaXMge0Bjb2RlIFByb3BlcnRpZXN9IHRvIHtAY29kZSBvdXR9IGluIGEgaHVtYW4tcmVhZGFibGUgZm9ybS4KKyAgICAgKiBOb3RlIHRoYXQgdmFsdWVzIGFyZSB0cnVuY2F0ZWQgdG8gMzcgY2hhcmFjdGVycywgc28gdGhpcyBtZXRob2QgaXMgcmFyZWx5IHVzZWZ1bC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBsaXN0KFByaW50V3JpdGVyIG91dCkgeworICAgICAgICBsaXN0VG9BcHBlbmRhYmxlKG91dCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGxpc3RUb0FwcGVuZGFibGUoQXBwZW5kYWJsZSBvdXQpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChvdXQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigib3V0ID09IG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcig4MCk7CisgICAgICAgICAgICBFbnVtZXJhdGlvbjw/PiBrZXlzID0gcHJvcGVydHlOYW1lcygpOworICAgICAgICAgICAgd2hpbGUgKGtleXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcga2V5ID0gKFN0cmluZykga2V5cy5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgICAgIHNiLmFwcGVuZChrZXkpOworICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgnPScpOworICAgICAgICAgICAgICAgIFN0cmluZyBwcm9wZXJ0eSA9IChTdHJpbmcpIHN1cGVyLmdldChrZXkpOworICAgICAgICAgICAgICAgIFByb3BlcnRpZXMgZGVmID0gZGVmYXVsdHM7CisgICAgICAgICAgICAgICAgd2hpbGUgKHByb3BlcnR5ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcHJvcGVydHkgPSAoU3RyaW5nKSBkZWYuZ2V0KGtleSk7CisgICAgICAgICAgICAgICAgICAgIGRlZiA9IGRlZi5kZWZhdWx0czsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHByb3BlcnR5Lmxlbmd0aCgpID4gNDApIHsKKyAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKHByb3BlcnR5LnN1YnN0cmluZygwLCAzNykpOworICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIi4uLiIpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZChwcm9wZXJ0eSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHNiLmFwcGVuZChTeXN0ZW0ubGluZVNlcGFyYXRvcigpKTsKKyAgICAgICAgICAgICAgICBvdXQuYXBwZW5kKHNiLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIHNiLnNldExlbmd0aCgwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIEFwcGVuZGFibGUuYXBwZW5kIHRocm93cyBJT0V4Y2VwdGlvbiwgYnV0IFByaW50U3RyZWFtIGFuZCBQcmludFdyaXRlciBkb24ndC4KKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2FkcyBwcm9wZXJ0aWVzIGZyb20gdGhlIHNwZWNpZmllZCB7QGNvZGUgSW5wdXRTdHJlYW19LCBhc3N1bWVkIHRvIGJlIElTTy04ODU5LTEuCisgICAgICogU2VlICI8YSBocmVmPSIjY2hhcmFjdGVyX2VuY29kaW5nIj5DaGFyYWN0ZXIgRW5jb2Rpbmc8L2E+Ii4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbiB0aGUge0Bjb2RlIElucHV0U3RyZWFtfQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgbG9hZChJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGxvYWQobmV3IElucHV0U3RyZWFtUmVhZGVyKGluLCAiSVNPLTg4NTktMSIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2FkcyBwcm9wZXJ0aWVzIGZyb20gdGhlIHNwZWNpZmllZCB7QGNvZGUgUmVhZGVyfS4KKyAgICAgKiBUaGUgcHJvcGVydGllcyBmaWxlIGlzIGludGVycHJldGVkIGFjY29yZGluZyB0byB0aGUgZm9sbG93aW5nIHJ1bGVzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+RW1wdHkgbGluZXMgYXJlIGlnbm9yZWQuPC9saT4KKyAgICAgKiA8bGk+TGluZXMgc3RhcnRpbmcgd2l0aCBlaXRoZXIgYSAiIyIgb3IgYSAiISIgYXJlIGNvbW1lbnQgbGluZXMgYW5kIGFyZQorICAgICAqIGlnbm9yZWQuPC9saT4KKyAgICAgKiA8bGk+QSBiYWNrc2xhc2ggYXQgdGhlIGVuZCBvZiB0aGUgbGluZSBlc2NhcGVzIHRoZSBmb2xsb3dpbmcgbmV3bGluZQorICAgICAqIGNoYXJhY3RlciAoIlxyIiwgIlxuIiwgIlxyXG4iKS4gSWYgdGhlcmUncyB3aGl0ZXNwYWNlIGFmdGVyIHRoZQorICAgICAqIGJhY2tzbGFzaCBpdCB3aWxsIGp1c3QgZXNjYXBlIHRoYXQgd2hpdGVzcGFjZSBpbnN0ZWFkIG9mIGNvbmNhdGVuYXRpbmcKKyAgICAgKiB0aGUgbGluZXMuIFRoaXMgZG9lcyBub3QgYXBwbHkgdG8gY29tbWVudCBsaW5lcy48L2xpPgorICAgICAqIDxsaT5BIHByb3BlcnR5IGxpbmUgY29uc2lzdHMgb2YgdGhlIGtleSwgdGhlIHNwYWNlIGJldHdlZW4gdGhlIGtleSBhbmQKKyAgICAgKiB0aGUgdmFsdWUsIGFuZCB0aGUgdmFsdWUuIFRoZSBrZXkgZ29lcyB1cCB0byB0aGUgZmlyc3Qgd2hpdGVzcGFjZSwgIj0iIG9yCisgICAgICogIjoiIHRoYXQgaXMgbm90IGVzY2FwZWQuIFRoZSBzcGFjZSBiZXR3ZWVuIHRoZSBrZXkgYW5kIHRoZSB2YWx1ZSBjb250YWlucworICAgICAqIGVpdGhlciBvbmUgd2hpdGVzcGFjZSwgb25lICI9IiBvciBvbmUgIjoiIGFuZCBhbnkgYW1vdW50IG9mIGFkZGl0aW9uYWwKKyAgICAgKiB3aGl0ZXNwYWNlIGJlZm9yZSBhbmQgYWZ0ZXIgdGhhdCBjaGFyYWN0ZXIuIFRoZSB2YWx1ZSBzdGFydHMgd2l0aCB0aGUKKyAgICAgKiBmaXJzdCBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIHNwYWNlIGJldHdlZW4gdGhlIGtleSBhbmQgdGhlIHZhbHVlLjwvbGk+CisgICAgICogPGxpPkZvbGxvd2luZyBlc2NhcGUgc2VxdWVuY2VzIGFyZSByZWNvZ25pemVkOiAiXCAiLCAiXFwiLCAiXHIiLCAiXG4iLAorICAgICAqICJcISIsICJcIyIsICJcdCIsICJcYiIsICJcZiIsIGFuZCAiJiM5Mjt1WFhYWCIgKHVuaWNvZGUgY2hhcmFjdGVyKS48L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4gdGhlIHtAY29kZSBSZWFkZXJ9CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZmFsbHRocm91Z2giKQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBsb2FkKFJlYWRlciBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGludCBtb2RlID0gTk9ORSwgdW5pY29kZSA9IDAsIGNvdW50ID0gMDsKKyAgICAgICAgY2hhciBuZXh0Q2hhciwgYnVmW10gPSBuZXcgY2hhcls0MF07CisgICAgICAgIGludCBvZmZzZXQgPSAwLCBrZXlMZW5ndGggPSAtMSwgaW50VmFsOworICAgICAgICBib29sZWFuIGZpcnN0Q2hhciA9IHRydWU7CisKKyAgICAgICAgQnVmZmVyZWRSZWFkZXIgYnIgPSBuZXcgQnVmZmVyZWRSZWFkZXIoaW4pOworCisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBpbnRWYWwgPSBici5yZWFkKCk7CisgICAgICAgICAgICBpZiAoaW50VmFsID09IC0xKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBuZXh0Q2hhciA9IChjaGFyKSBpbnRWYWw7CisKKyAgICAgICAgICAgIGlmIChvZmZzZXQgPT0gYnVmLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIGNoYXJbXSBuZXdCdWYgPSBuZXcgY2hhcltidWYubGVuZ3RoICogMl07CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWYsIDAsIG5ld0J1ZiwgMCwgb2Zmc2V0KTsKKyAgICAgICAgICAgICAgICBidWYgPSBuZXdCdWY7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobW9kZSA9PSBVTklDT0RFKSB7CisgICAgICAgICAgICAgICAgaW50IGRpZ2l0ID0gQ2hhcmFjdGVyLmRpZ2l0KG5leHRDaGFyLCAxNik7CisgICAgICAgICAgICAgICAgaWYgKGRpZ2l0ID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgdW5pY29kZSA9ICh1bmljb2RlIDw8IDQpICsgZGlnaXQ7CisgICAgICAgICAgICAgICAgICAgIGlmICgrK2NvdW50IDwgNCkgeworICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvdW50IDw9IDQpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBVbmljb2RlIHNlcXVlbmNlOiBpbGxlZ2FsIGNoYXJhY3RlciIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBtb2RlID0gTk9ORTsKKyAgICAgICAgICAgICAgICBidWZbb2Zmc2V0KytdID0gKGNoYXIpIHVuaWNvZGU7CisgICAgICAgICAgICAgICAgaWYgKG5leHRDaGFyICE9ICdcbicpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG1vZGUgPT0gU0xBU0gpIHsKKyAgICAgICAgICAgICAgICBtb2RlID0gTk9ORTsKKyAgICAgICAgICAgICAgICBzd2l0Y2ggKG5leHRDaGFyKSB7CisgICAgICAgICAgICAgICAgY2FzZSAnXHInOgorICAgICAgICAgICAgICAgICAgICBtb2RlID0gQ09OVElOVUU7IC8vIExvb2sgZm9yIGEgZm9sbG93aW5nIFxuCisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIGNhc2UgJ1xuJzoKKyAgICAgICAgICAgICAgICAgICAgbW9kZSA9IElHTk9SRTsgLy8gSWdub3JlIHdoaXRlc3BhY2Ugb24gdGhlIG5leHQgbGluZQorICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICBjYXNlICdiJzoKKyAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIgPSAnXGInOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdmJzoKKyAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIgPSAnXGYnOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICduJzoKKyAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIgPSAnXG4nOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdyJzoKKyAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIgPSAnXHInOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICd0JzoKKyAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIgPSAnXHQnOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICd1JzoKKyAgICAgICAgICAgICAgICAgICAgbW9kZSA9IFVOSUNPREU7CisgICAgICAgICAgICAgICAgICAgIHVuaWNvZGUgPSBjb3VudCA9IDA7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc3dpdGNoIChuZXh0Q2hhcikgeworICAgICAgICAgICAgICAgIGNhc2UgJyMnOgorICAgICAgICAgICAgICAgIGNhc2UgJyEnOgorICAgICAgICAgICAgICAgICAgICBpZiAoZmlyc3RDaGFyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludFZhbCA9IGJyLnJlYWQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW50VmFsID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0Q2hhciA9IChjaGFyKSBpbnRWYWw7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRDaGFyID09ICdccicgfHwgbmV4dENoYXIgPT0gJ1xuJykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdcbic6CisgICAgICAgICAgICAgICAgICAgIGlmIChtb2RlID09IENPTlRJTlVFKSB7IC8vIFBhcnQgb2YgYSBcclxuIHNlcXVlbmNlCisgICAgICAgICAgICAgICAgICAgICAgICBtb2RlID0gSUdOT1JFOyAvLyBJZ25vcmUgd2hpdGVzcGFjZSBvbiB0aGUgbmV4dCBsaW5lCisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAvLyBmYWxsIGludG8gdGhlIG5leHQgY2FzZQorICAgICAgICAgICAgICAgIGNhc2UgJ1xyJzoKKyAgICAgICAgICAgICAgICAgICAgbW9kZSA9IE5PTkU7CisgICAgICAgICAgICAgICAgICAgIGZpcnN0Q2hhciA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPiAwIHx8IChvZmZzZXQgPT0gMCAmJiBrZXlMZW5ndGggPT0gMCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrZXlMZW5ndGggPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlMZW5ndGggPSBvZmZzZXQ7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdGVtcCA9IG5ldyBTdHJpbmcoYnVmLCAwLCBvZmZzZXQpOworICAgICAgICAgICAgICAgICAgICAgICAgcHV0KHRlbXAuc3Vic3RyaW5nKDAsIGtleUxlbmd0aCksIHRlbXAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN1YnN0cmluZyhrZXlMZW5ndGgpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBrZXlMZW5ndGggPSAtMTsKKyAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgY2FzZSAnXFwnOgorICAgICAgICAgICAgICAgICAgICBpZiAobW9kZSA9PSBLRVlfRE9ORSkgeworICAgICAgICAgICAgICAgICAgICAgICAga2V5TGVuZ3RoID0gb2Zmc2V0OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIG1vZGUgPSBTTEFTSDsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgY2FzZSAnOic6CisgICAgICAgICAgICAgICAgY2FzZSAnPSc6CisgICAgICAgICAgICAgICAgICAgIGlmIChrZXlMZW5ndGggPT0gLTEpIHsgLy8gaWYgcGFyc2luZyB0aGUga2V5CisgICAgICAgICAgICAgICAgICAgICAgICBtb2RlID0gTk9ORTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGtleUxlbmd0aCA9IG9mZnNldDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoQ2hhcmFjdGVyLmlzV2hpdGVzcGFjZShuZXh0Q2hhcikpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG1vZGUgPT0gQ09OVElOVUUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1vZGUgPSBJR05PUkU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgLy8gaWYga2V5IGxlbmd0aCA9PSAwIG9yIHZhbHVlIGxlbmd0aCA9PSAwCisgICAgICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPT0gMCB8fCBvZmZzZXQgPT0ga2V5TGVuZ3RoIHx8IG1vZGUgPT0gSUdOT1JFKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoa2V5TGVuZ3RoID09IC0xKSB7IC8vIGlmIHBhcnNpbmcgdGhlIGtleQorICAgICAgICAgICAgICAgICAgICAgICAgbW9kZSA9IEtFWV9ET05FOworICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKG1vZGUgPT0gSUdOT1JFIHx8IG1vZGUgPT0gQ09OVElOVUUpIHsKKyAgICAgICAgICAgICAgICAgICAgbW9kZSA9IE5PTkU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgZmlyc3RDaGFyID0gZmFsc2U7CisgICAgICAgICAgICBpZiAobW9kZSA9PSBLRVlfRE9ORSkgeworICAgICAgICAgICAgICAgIGtleUxlbmd0aCA9IG9mZnNldDsKKyAgICAgICAgICAgICAgICBtb2RlID0gTk9ORTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ1ZltvZmZzZXQrK10gPSBuZXh0Q2hhcjsKKyAgICAgICAgfQorICAgICAgICBpZiAobW9kZSA9PSBVTklDT0RFICYmIGNvdW50IDw9IDQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgVW5pY29kZSBzZXF1ZW5jZTogZXhwZWN0ZWQgZm9ybWF0IFxcdXh4eHgiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoa2V5TGVuZ3RoID09IC0xICYmIG9mZnNldCA+IDApIHsKKyAgICAgICAgICAgIGtleUxlbmd0aCA9IG9mZnNldDsKKyAgICAgICAgfQorICAgICAgICBpZiAoa2V5TGVuZ3RoID49IDApIHsKKyAgICAgICAgICAgIFN0cmluZyB0ZW1wID0gbmV3IFN0cmluZyhidWYsIDAsIG9mZnNldCk7CisgICAgICAgICAgICBTdHJpbmcga2V5ID0gdGVtcC5zdWJzdHJpbmcoMCwga2V5TGVuZ3RoKTsKKyAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IHRlbXAuc3Vic3RyaW5nKGtleUxlbmd0aCk7CisgICAgICAgICAgICBpZiAobW9kZSA9PSBTTEFTSCkgeworICAgICAgICAgICAgICAgIHZhbHVlICs9ICJcdTAwMDAiOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHV0KGtleSwgdmFsdWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbGwgb2YgdGhlIHByb3BlcnR5IG5hbWVzIChrZXlzKSBpbiB0aGlzIHtAY29kZSBQcm9wZXJ0aWVzfSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIEVudW1lcmF0aW9uPD8+IHByb3BlcnR5TmFtZXMoKSB7CisgICAgICAgIEhhc2h0YWJsZTxPYmplY3QsIE9iamVjdD4gc2VsZWN0ZWQgPSBuZXcgSGFzaHRhYmxlPE9iamVjdCwgT2JqZWN0PigpOworICAgICAgICBzZWxlY3RQcm9wZXJ0aWVzKHNlbGVjdGVkLCBmYWxzZSk7CisgICAgICAgIHJldHVybiBzZWxlY3RlZC5rZXlzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aG9zZSBwcm9wZXJ0eSBuYW1lcyAoa2V5cykgaW4gdGhpcyB7QGNvZGUgUHJvcGVydGllc30gb2JqZWN0IGZvciB3aGljaAorICAgICAqIGJvdGgga2V5IGFuZCB2YWx1ZSBhcmUgc3RyaW5ncy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzZXQgb2Yga2V5cyBpbiB0aGUgcHJvcGVydHkgbGlzdAorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgU2V0PFN0cmluZz4gc3RyaW5nUHJvcGVydHlOYW1lcygpIHsKKyAgICAgICAgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PiBzdHJpbmdQcm9wZXJ0aWVzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKKyAgICAgICAgc2VsZWN0UHJvcGVydGllcyhzdHJpbmdQcm9wZXJ0aWVzLCB0cnVlKTsKKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNldChzdHJpbmdQcm9wZXJ0aWVzLmtleVNldCgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIDxLPiB2b2lkIHNlbGVjdFByb3BlcnRpZXMoSGFzaHRhYmxlPEssIE9iamVjdD4gc2VsZWN0UHJvcGVydGllcywgZmluYWwgYm9vbGVhbiBpc1N0cmluZ09ubHkpIHsKKyAgICAgICAgaWYgKGRlZmF1bHRzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGRlZmF1bHRzLnNlbGVjdFByb3BlcnRpZXMoc2VsZWN0UHJvcGVydGllcywgaXNTdHJpbmdPbmx5KTsKKyAgICAgICAgfQorICAgICAgICBFbnVtZXJhdGlvbjxPYmplY3Q+IGtleXMgPSBrZXlzKCk7CisgICAgICAgIHdoaWxlIChrZXlzLmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgICAgIEsga2V5ID0gKEspIGtleXMubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGlmIChpc1N0cmluZ09ubHkgJiYgIShrZXkgaW5zdGFuY2VvZiBTdHJpbmcpKSB7CisgICAgICAgICAgICAgICAgLy8gT25seSBzZWxlY3QgcHJvcGVydHkgd2l0aCBzdHJpbmcga2V5IGFuZCB2YWx1ZQorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gZ2V0KGtleSk7CisgICAgICAgICAgICBzZWxlY3RQcm9wZXJ0aWVzLnB1dChrZXksIHZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNhdmVzIHRoZSBtYXBwaW5ncyBpbiB0aGlzIHtAY29kZSBQcm9wZXJ0aWVzfSB0byB0aGUgc3BlY2lmaWVkIHtAY29kZQorICAgICAqIE91dHB1dFN0cmVhbX0sIHB1dHRpbmcgdGhlIHNwZWNpZmllZCBjb21tZW50IGF0IHRoZSBiZWdpbm5pbmcuIFRoZSBvdXRwdXQKKyAgICAgKiBmcm9tIHRoaXMgbWV0aG9kIGlzIHN1aXRhYmxlIGZvciBiZWluZyByZWFkIGJ5IHRoZQorICAgICAqIHtAbGluayAjbG9hZChJbnB1dFN0cmVhbSl9IG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQgdGhlIHtAY29kZSBPdXRwdXRTdHJlYW19IHRvIHdyaXRlIHRvLgorICAgICAqIEBwYXJhbSBjb21tZW50IHRoZSBjb21tZW50IHRvIGFkZCBhdCB0aGUgYmVnaW5uaW5nLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBrZXkgb3IgdmFsdWUgb2YgYSBtYXBwaW5nIGlzIG5vdCBhCisgICAgICogICAgICAgICAgICAgICAgU3RyaW5nLgorICAgICAqIEBkZXByZWNhdGVkIFRoaXMgbWV0aG9kIGlnbm9yZXMgYW55IHtAY29kZSBJT0V4Y2VwdGlvbn0gdGhyb3duIHdoaWxlCisgICAgICogICAgICAgICAgICAgd3JpdGluZyAtLSB1c2Uge0BsaW5rICNzdG9yZX0gaW5zdGVhZCBmb3IgYmV0dGVyIGV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGhhbmRsaW5nLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHZvaWQgc2F2ZShPdXRwdXRTdHJlYW0gb3V0LCBTdHJpbmcgY29tbWVudCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RvcmUob3V0LCBjb21tZW50KTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFwcyB0aGUgc3BlY2lmaWVkIGtleSB0byB0aGUgc3BlY2lmaWVkIHZhbHVlLiBJZiB0aGUga2V5IGFscmVhZHkgZXhpc3RzLAorICAgICAqIHRoZSBvbGQgdmFsdWUgaXMgcmVwbGFjZWQuIFRoZSBrZXkgYW5kIHZhbHVlIGNhbm5vdCBiZSB7QGNvZGUgbnVsbH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGtleS4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBvbGQgdmFsdWUgbWFwcGVkIHRvIHRoZSBrZXksIG9yIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IHNldFByb3BlcnR5KFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIHB1dChuYW1lLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3RvcmVzIHByb3BlcnRpZXMgdG8gdGhlIHNwZWNpZmllZCB7QGNvZGUgT3V0cHV0U3RyZWFtfSwgdXNpbmcgSVNPLTg4NTktMS4KKyAgICAgKiBTZWUgIjxhIGhyZWY9IiNjaGFyYWN0ZXJfZW5jb2RpbmciPkNoYXJhY3RlciBFbmNvZGluZzwvYT4iLgorICAgICAqCisgICAgICogQHBhcmFtIG91dCB0aGUge0Bjb2RlIE91dHB1dFN0cmVhbX0KKyAgICAgKiBAcGFyYW0gY29tbWVudCBhbiBvcHRpb25hbCBjb21tZW50IHRvIGJlIHdyaXR0ZW4sIG9yIG51bGwKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgYSBrZXkgb3IgdmFsdWUgaXMgbm90IGEgc3RyaW5nCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHN0b3JlKE91dHB1dFN0cmVhbSBvdXQsIFN0cmluZyBjb21tZW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdG9yZShuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG91dCwgIklTTy04ODU5LTEiKSwgY29tbWVudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3RvcmVzIHRoZSBtYXBwaW5ncyBpbiB0aGlzIHtAY29kZSBQcm9wZXJ0aWVzfSBvYmplY3QgdG8ge0Bjb2RlIG91dH0sCisgICAgICogcHV0dGluZyB0aGUgc3BlY2lmaWVkIGNvbW1lbnQgYXQgdGhlIGJlZ2lubmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB3cml0ZXIgdGhlIHtAY29kZSBXcml0ZXJ9CisgICAgICogQHBhcmFtIGNvbW1lbnQgYW4gb3B0aW9uYWwgY29tbWVudCB0byBiZSB3cml0dGVuLCBvciBudWxsCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIGEga2V5IG9yIHZhbHVlIGlzIG5vdCBhIHN0cmluZworICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc3RvcmUoV3JpdGVyIHdyaXRlciwgU3RyaW5nIGNvbW1lbnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjb21tZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHdyaXRlci53cml0ZSgiIyIpOworICAgICAgICAgICAgd3JpdGVyLndyaXRlKGNvbW1lbnQpOworICAgICAgICAgICAgd3JpdGVyLndyaXRlKFN5c3RlbS5saW5lU2VwYXJhdG9yKCkpOworICAgICAgICB9CisgICAgICAgIHdyaXRlci53cml0ZSgiIyIpOworICAgICAgICB3cml0ZXIud3JpdGUobmV3IERhdGUoKS50b1N0cmluZygpKTsKKyAgICAgICAgd3JpdGVyLndyaXRlKFN5c3RlbS5saW5lU2VwYXJhdG9yKCkpOworCisgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigyMDApOworICAgICAgICBmb3IgKE1hcC5FbnRyeTxPYmplY3QsIE9iamVjdD4gZW50cnkgOiBlbnRyeVNldCgpKSB7CisgICAgICAgICAgICBTdHJpbmcga2V5ID0gKFN0cmluZykgZW50cnkuZ2V0S2V5KCk7CisgICAgICAgICAgICBkdW1wU3RyaW5nKHNiLCBrZXksIHRydWUpOworICAgICAgICAgICAgc2IuYXBwZW5kKCc9Jyk7CisgICAgICAgICAgICBkdW1wU3RyaW5nKHNiLCAoU3RyaW5nKSBlbnRyeS5nZXRWYWx1ZSgpLCBmYWxzZSk7CisgICAgICAgICAgICBzYi5hcHBlbmQoU3lzdGVtLmxpbmVTZXBhcmF0b3IoKSk7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoc2IudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBzYi5zZXRMZW5ndGgoMCk7CisgICAgICAgIH0KKyAgICAgICAgd3JpdGVyLmZsdXNoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9hZHMgdGhlIHByb3BlcnRpZXMgZnJvbSBhbiB7QGNvZGUgSW5wdXRTdHJlYW19IGNvbnRhaW5pbmcgdGhlCisgICAgICogcHJvcGVydGllcyBpbiBYTUwgZm9ybS4gVGhlIFhNTCBkb2N1bWVudCBtdXN0IGJlZ2luIHdpdGggKGFuZCBjb25mb3JtIHRvKQorICAgICAqIGZvbGxvd2luZyBET0NUWVBFOgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiAmbHQ7IURPQ1RZUEUgcHJvcGVydGllcyBTWVNURU0gJnF1b3Q7aHR0cDovL2phdmEuc3VuLmNvbS9kdGQvcHJvcGVydGllcy5kdGQmcXVvdDsmZ3Q7CisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiBBbHNvIHRoZSBjb250ZW50IG9mIHRoZSBYTUwgZGF0YSBtdXN0IHNhdGlzZnkgdGhlIERURCBidXQgdGhlIHhtbCBpcyBub3QKKyAgICAgKiB2YWxpZGF0ZWQgYWdhaW5zdCBpdC4gVGhlIERURCBpcyBub3QgbG9hZGVkIGZyb20gdGhlIFNZU1RFTSBJRC4gQWZ0ZXIKKyAgICAgKiB0aGlzIG1ldGhvZCByZXR1cm5zIHRoZSBJbnB1dFN0cmVhbSBpcyBub3QgY2xvc2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGluIHRoZSBJbnB1dFN0cmVhbSBjb250YWluaW5nIHRoZSBYTUwgZG9jdW1lbnQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpbiBjYXNlIGFuIGVycm9yIG9jY3VycyBkdXJpbmcgYSByZWFkIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRQcm9wZXJ0aWVzRm9ybWF0RXhjZXB0aW9uIGlmIHRoZSBYTUwgZGF0YSBpcyBub3QgYSB2YWxpZAorICAgICAqICAgICAgICAgICAgIHByb3BlcnRpZXMgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgbG9hZEZyb21YTUwoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRQcm9wZXJ0aWVzRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGJ1aWxkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICAgICAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1yZW1vdmVkOiB3ZSBzdGlsbCBkb24ndCBzdXBwb3J0IHZhbGlkYXRpb24uCisgICAgICAgICAgICAvLyBmYWN0b3J5LnNldFZhbGlkYXRpbmcodHJ1ZSk7CisgICAgICAgICAgICAvLyBFTkQgYW5kcm9pZC1yZW1vdmVkCisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkubmV3RG9jdW1lbnRCdWlsZGVyKCk7CisgICAgICAgICAgICB9IGNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGJ1aWxkZXIuc2V0RXJyb3JIYW5kbGVyKG5ldyBFcnJvckhhbmRsZXIoKSB7CisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgd2FybmluZyhTQVhQYXJzZUV4Y2VwdGlvbiBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBlcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBmYXRhbEVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworCisgICAgICAgICAgICBidWlsZGVyLnNldEVudGl0eVJlc29sdmVyKG5ldyBFbnRpdHlSZXNvbHZlcigpIHsKKyAgICAgICAgICAgICAgICBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eShTdHJpbmcgcHVibGljSWQsCisgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc3lzdGVtSWQpIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHN5c3RlbUlkLmVxdWFscyhQUk9QX0RURF9OQU1FKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgSW5wdXRTb3VyY2UgcmVzdWx0ID0gbmV3IElucHV0U291cmNlKG5ldyBTdHJpbmdSZWFkZXIoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBST1BfRFREKSk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuc2V0U3lzdGVtSWQoUFJPUF9EVERfTkFNRSk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oIkludmFsaWQgRE9DVFlQRSBkZWNsYXJhdGlvbjogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgc3lzdGVtSWQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIERvY3VtZW50IGRvYyA9IGJ1aWxkZXIucGFyc2UoaW4pOworICAgICAgICAgICAgTm9kZUxpc3QgZW50cmllcyA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW50cnkiKTsKKyAgICAgICAgICAgIGlmIChlbnRyaWVzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgZW50cmllc0xpc3RMZW5ndGggPSBlbnRyaWVzLmdldExlbmd0aCgpOworCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVudHJpZXNMaXN0TGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBFbGVtZW50IGVudHJ5ID0gKEVsZW1lbnQpIGVudHJpZXMuaXRlbShpKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcga2V5ID0gZW50cnkuZ2V0QXR0cmlidXRlKCJrZXkiKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBlbnRyeS5nZXRUZXh0Q29udGVudCgpOworCisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgKiBrZXkgIT0gbnVsbCAmIHZhbHVlICE9IG51bGwgYnV0IGtleSBvcihhbmQpIHZhbHVlIGNhbiBiZQorICAgICAgICAgICAgICAgICAqIGVtcHR5IFN0cmluZworICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIHB1dChrZXksIHZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUHJvcGVydGllc0Zvcm1hdEV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhbGwgcHJvcGVydGllcyBzdG9yZWQgaW4gdGhpcyBpbnN0YW5jZSBpbnRvIHRoZSB7QGNvZGUKKyAgICAgKiBPdXRwdXRTdHJlYW19IGluIFhNTCByZXByZXNlbnRhdGlvbi4gVGhlIERPQ1RZUEUgaXMKKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogJmx0OyFET0NUWVBFIHByb3BlcnRpZXMgU1lTVEVNICZxdW90O2h0dHA6Ly9qYXZhLnN1bi5jb20vZHRkL3Byb3BlcnRpZXMuZHRkJnF1b3Q7Jmd0OworICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogSWYgdGhlIGNvbW1lbnQgaXMgbnVsbCwgbm8gY29tbWVudCBpcyBhZGRlZCB0byB0aGUgb3V0cHV0LiBVVEYtOCBpcyB1c2VkCisgICAgICogYXMgdGhlIGVuY29kaW5nLiBUaGUge0Bjb2RlIE91dHB1dFN0cmVhbX0gaXMgbm90IGNsb3NlZCBhdCB0aGUgZW5kLiBBCisgICAgICogY2FsbCB0byB0aGlzIG1ldGhvZCBpcyB0aGUgc2FtZSBhcyBhIGNhbGwgdG8ge0Bjb2RlIHN0b3JlVG9YTUwob3MsCisgICAgICogY29tbWVudCwgIlVURi04Iil9LgorICAgICAqCisgICAgICogQHBhcmFtIG9zIHRoZSB7QGNvZGUgT3V0cHV0U3RyZWFtfSB0byB3cml0ZSB0by4KKyAgICAgKiBAcGFyYW0gY29tbWVudCB0aGUgY29tbWVudCB0byBhZGQuIElmIG51bGwsIG5vIGNvbW1lbnQgaXMgYWRkZWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIHdyaXRpbmcgdG8gdGhlIG91dHB1dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdG9yZVRvWE1MKE91dHB1dFN0cmVhbSBvcywgU3RyaW5nIGNvbW1lbnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN0b3JlVG9YTUwob3MsIGNvbW1lbnQsICJVVEYtOCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhbGwgcHJvcGVydGllcyBzdG9yZWQgaW4gdGhpcyBpbnN0YW5jZSBpbnRvIHRoZSB7QGNvZGUKKyAgICAgKiBPdXRwdXRTdHJlYW19IGluIFhNTCByZXByZXNlbnRhdGlvbi4gVGhlIERPQ1RZUEUgaXMKKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogJmx0OyFET0NUWVBFIHByb3BlcnRpZXMgU1lTVEVNICZxdW90O2h0dHA6Ly9qYXZhLnN1bi5jb20vZHRkL3Byb3BlcnRpZXMuZHRkJnF1b3Q7Jmd0OworICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogSWYgdGhlIGNvbW1lbnQgaXMgbnVsbCwgbm8gY29tbWVudCBpcyBhZGRlZCB0byB0aGUgb3V0cHV0LiBUaGUgcGFyYW1ldGVyCisgICAgICoge0Bjb2RlIGVuY29kaW5nfSBkZWZpbmVzIHdoaWNoIGVuY29kaW5nIHNob3VsZCBiZSB1c2VkLiBUaGUge0Bjb2RlCisgICAgICogT3V0cHV0U3RyZWFtfSBpcyBub3QgY2xvc2VkIGF0IHRoZSBlbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3MgdGhlIHtAY29kZSBPdXRwdXRTdHJlYW19IHRvIHdyaXRlIHRvLgorICAgICAqIEBwYXJhbSBjb21tZW50IHRoZSBjb21tZW50IHRvIGFkZC4gSWYgbnVsbCwgbm8gY29tbWVudCBpcyBhZGRlZC4KKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGNvZGUgaWRlbnRpZnlpbmcgdGhlIGVuY29kaW5nIHRoYXQgc2hvdWxkIGJlIHVzZWQgdG8KKyAgICAgKiAgICAgICAgICAgIHdyaXRlIGludG8gdGhlIHtAY29kZSBPdXRwdXRTdHJlYW19LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyB3cml0aW5nIHRvIHRoZSBvdXRwdXQuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHN0b3JlVG9YTUwoT3V0cHV0U3RyZWFtIG9zLCBTdHJpbmcgY29tbWVudCwKKyAgICAgICAgICAgIFN0cmluZyBlbmNvZGluZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBpZiAob3MgPT0gbnVsbCB8fCBlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIFdlIGNhbiB3cml0ZSB0byBYTUwgZmlsZSB1c2luZyBlbmNvZGluZyBwYXJhbWV0ZXIgYnV0IG5vdGUgdGhhdCBzb21lCisgICAgICAgICAqIGFsaWFzZXMgZm9yIGVuY29kaW5ncyBhcmUgbm90IHN1cHBvcnRlZCBieSB0aGUgWE1MIHBhcnNlci4gVGh1cyB3ZQorICAgICAgICAgKiBoYXZlIHRvIGtub3cgY2Fub25pY2FsIG5hbWUgZm9yIGVuY29kaW5nIHVzZWQgdG8gc3RvcmUgZGF0YSBpbiBYTUwKKyAgICAgICAgICogc2luY2UgdGhlIFhNTCBwYXJzZXIgbXVzdCByZWNvZ25pemUgZW5jb2RpbmcgbmFtZSB1c2VkIHRvIHN0b3JlIGRhdGEuCisgICAgICAgICAqLworCisgICAgICAgIFN0cmluZyBlbmNvZGluZ0Nhbm9uaWNhbE5hbWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbmNvZGluZ0Nhbm9uaWNhbE5hbWUgPSBDaGFyc2V0LmZvck5hbWUoZW5jb2RpbmcpLm5hbWUoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbENoYXJzZXROYW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiV2FybmluZzogZW5jb2RpbmcgbmFtZSAiICsgZW5jb2RpbmcKKyAgICAgICAgICAgICAgICAgICAgKyAiIGlzIGlsbGVnYWwsIHVzaW5nIFVURi04IGFzIGRlZmF1bHQgZW5jb2RpbmciKTsKKyAgICAgICAgICAgIGVuY29kaW5nQ2Fub25pY2FsTmFtZSA9ICJVVEYtOCI7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkQ2hhcnNldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIldhcm5pbmc6IGVuY29kaW5nICIgKyBlbmNvZGluZworICAgICAgICAgICAgICAgICAgICArICIgaXMgbm90IHN1cHBvcnRlZCwgdXNpbmcgVVRGLTggYXMgZGVmYXVsdCBlbmNvZGluZyIpOworICAgICAgICAgICAgZW5jb2RpbmdDYW5vbmljYWxOYW1lID0gIlVURi04IjsKKyAgICAgICAgfQorCisgICAgICAgIFByaW50U3RyZWFtIHByaW50U3RyZWFtID0gbmV3IFByaW50U3RyZWFtKG9zLCBmYWxzZSwKKyAgICAgICAgICAgICAgICBlbmNvZGluZ0Nhbm9uaWNhbE5hbWUpOworCisgICAgICAgIHByaW50U3RyZWFtLnByaW50KCI8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCIiKTsKKyAgICAgICAgcHJpbnRTdHJlYW0ucHJpbnQoZW5jb2RpbmdDYW5vbmljYWxOYW1lKTsKKyAgICAgICAgcHJpbnRTdHJlYW0ucHJpbnRsbigiXCI/PiIpOworCisgICAgICAgIHByaW50U3RyZWFtLnByaW50KCI8IURPQ1RZUEUgcHJvcGVydGllcyBTWVNURU0gXCIiKTsKKyAgICAgICAgcHJpbnRTdHJlYW0ucHJpbnQoUFJPUF9EVERfTkFNRSk7CisgICAgICAgIHByaW50U3RyZWFtLnByaW50bG4oIlwiPiIpOworCisgICAgICAgIHByaW50U3RyZWFtLnByaW50bG4oIjxwcm9wZXJ0aWVzPiIpOworCisgICAgICAgIGlmIChjb21tZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHByaW50U3RyZWFtLnByaW50KCI8Y29tbWVudD4iKTsKKyAgICAgICAgICAgIHByaW50U3RyZWFtLnByaW50KHN1YnN0aXR1dGVQcmVkZWZpbmVkRW50cmllcyhjb21tZW50KSk7CisgICAgICAgICAgICBwcmludFN0cmVhbS5wcmludGxuKCI8L2NvbW1lbnQ+Iik7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKE1hcC5FbnRyeTxPYmplY3QsIE9iamVjdD4gZW50cnkgOiBlbnRyeVNldCgpKSB7CisgICAgICAgICAgICBTdHJpbmcga2V5VmFsdWUgPSAoU3RyaW5nKSBlbnRyeS5nZXRLZXkoKTsKKyAgICAgICAgICAgIFN0cmluZyBlbnRyeVZhbHVlID0gKFN0cmluZykgZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgIHByaW50U3RyZWFtLnByaW50KCI8ZW50cnkga2V5PVwiIik7CisgICAgICAgICAgICBwcmludFN0cmVhbS5wcmludChzdWJzdGl0dXRlUHJlZGVmaW5lZEVudHJpZXMoa2V5VmFsdWUpKTsKKyAgICAgICAgICAgIHByaW50U3RyZWFtLnByaW50KCJcIj4iKTsKKyAgICAgICAgICAgIHByaW50U3RyZWFtLnByaW50KHN1YnN0aXR1dGVQcmVkZWZpbmVkRW50cmllcyhlbnRyeVZhbHVlKSk7CisgICAgICAgICAgICBwcmludFN0cmVhbS5wcmludGxuKCI8L2VudHJ5PiIpOworICAgICAgICB9CisgICAgICAgIHByaW50U3RyZWFtLnByaW50bG4oIjwvcHJvcGVydGllcz4iKTsKKyAgICAgICAgcHJpbnRTdHJlYW0uZmx1c2goKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyBzdWJzdGl0dXRlUHJlZGVmaW5lZEVudHJpZXMoU3RyaW5nIHMpIHsKKyAgICAgICAgLy8gc3Vic3RpdHV0aW9uIGZvciBwcmVkZWZpbmVkIGNoYXJhY3RlciBlbnRpdGllcyB0byB1c2UgdGhlbSBzYWZlbHkgaW4gWE1MLgorICAgICAgICBzID0gcy5yZXBsYWNlQWxsKCImIiwgIiZhbXA7Iik7CisgICAgICAgIHMgPSBzLnJlcGxhY2VBbGwoIjwiLCAiJmx0OyIpOworICAgICAgICBzID0gcy5yZXBsYWNlQWxsKCI+IiwgIiZndDsiKTsKKyAgICAgICAgcyA9IHMucmVwbGFjZUFsbCgiJyIsICImYXBvczsiKTsKKyAgICAgICAgcyA9IHMucmVwbGFjZUFsbCgiXCIiLCAiJnF1b3Q7Iik7CisgICAgICAgIHJldHVybiBzOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvUHJvcGVydHlQZXJtaXNzaW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1Byb3BlcnR5UGVybWlzc2lvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYyODdiOTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1Byb3BlcnR5UGVybWlzc2lvbi5qYXZhCkBAIC0wLDAgKzEsMzcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0U3RyZWFtRmllbGQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5CYXNpY1Blcm1pc3Npb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbkNvbGxlY3Rpb247CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBQcm9wZXJ0eVBlcm1pc3Npb24gZXh0ZW5kcyBCYXNpY1Blcm1pc3Npb24geworICAgIHB1YmxpYyBQcm9wZXJ0eVBlcm1pc3Npb24oU3RyaW5nIG5hbWUsIFN0cmluZyBhY3Rpb25zKSB7IHN1cGVyKCIiKTsgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgZ2V0QWN0aW9ucygpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpbXBsaWVzKFBlcm1pc3Npb24gcGVybWlzc2lvbikgeyByZXR1cm4gdHJ1ZTsgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9Qcm9wZXJ0eVJlc291cmNlQnVuZGxlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1Byb3BlcnR5UmVzb3VyY2VCdW5kbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MDI5ZWUxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9Qcm9wZXJ0eVJlc291cmNlQnVuZGxlLmphdmEKQEAgLTAsMCArMSwxMjggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUmVhZGVyOworCisvKioKKyAqIHtAY29kZSBQcm9wZXJ0eVJlc291cmNlQnVuZGxlfSBsb2FkcyByZXNvdXJjZXMgZnJvbSBhbiB7QGNvZGUgSW5wdXRTdHJlYW19LiBBbGwgcmVzb3VyY2VzIGFyZQorICogU3RyaW5ncy4gVGhlIHJlc291cmNlcyBtdXN0IGJlIG9mIHRoZSBmb3JtIHtAY29kZSBrZXk9dmFsdWV9LCBvbmUKKyAqIHJlc291cmNlIHBlciBsaW5lIChzZWUgUHJvcGVydGllcykuCisgKgorICogQHNlZSBSZXNvdXJjZUJ1bmRsZQorICogQHNlZSBQcm9wZXJ0aWVzCisgKiBAc2luY2UgMS4xCisgKi8KK3B1YmxpYyBjbGFzcyBQcm9wZXJ0eVJlc291cmNlQnVuZGxlIGV4dGVuZHMgUmVzb3VyY2VCdW5kbGUgeworCisgICAgUHJvcGVydGllcyByZXNvdXJjZXM7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBQcm9wZXJ0eVJlc291cmNlQnVuZGxlfSBhbmQgbG9hZHMgdGhlCisgICAgICogcHJvcGVydGllcyBmaWxlIGZyb20gdGhlIHNwZWNpZmllZCB7QGNvZGUgSW5wdXRTdHJlYW19LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBJbnB1dFN0cmVhbX0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBkdXJpbmcgYSByZWFkIG9wZXJhdGlvbiBvbiB0aGUKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgSW5wdXRTdHJlYW19LgorICAgICAqLworICAgIHB1YmxpYyBQcm9wZXJ0eVJlc291cmNlQnVuZGxlKElucHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHN0cmVhbSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXNvdXJjZXMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICByZXNvdXJjZXMubG9hZChzdHJlYW0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgcmVzb3VyY2UgYnVuZGxlIHdpdGggcHJvcGVydGllcyByZWFkIGZyb20ge0Bjb2RlIHJlYWRlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhZGVyIHRoZSB7QGNvZGUgUmVhZGVyfQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIFByb3BlcnR5UmVzb3VyY2VCdW5kbGUoUmVhZGVyIHJlYWRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmVzb3VyY2VzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgcmVzb3VyY2VzLmxvYWQocmVhZGVyKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgU2V0PFN0cmluZz4gaGFuZGxlS2V5U2V0KCl7CisgICAgICAgIHJldHVybiByZXNvdXJjZXMuc3RyaW5nUHJvcGVydHlOYW1lcygpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHByaXZhdGUgRW51bWVyYXRpb248U3RyaW5nPiBnZXRMb2NhbEtleXMoKSB7CisgICAgICAgIHJldHVybiAoRW51bWVyYXRpb248U3RyaW5nPikgcmVzb3VyY2VzLnByb3BlcnR5TmFtZXMoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXRLZXlzKCkgeworICAgICAgICBpZiAocGFyZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRMb2NhbEtleXMoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEVudW1lcmF0aW9uPFN0cmluZz4oKSB7CisgICAgICAgICAgICBFbnVtZXJhdGlvbjxTdHJpbmc+IGxvY2FsID0gZ2V0TG9jYWxLZXlzKCk7CisKKyAgICAgICAgICAgIEVudW1lcmF0aW9uPFN0cmluZz4gcEVudW0gPSBwYXJlbnQuZ2V0S2V5cygpOworCisgICAgICAgICAgICBTdHJpbmcgbmV4dEVsZW1lbnQ7CisKKyAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiBmaW5kTmV4dCgpIHsKKyAgICAgICAgICAgICAgICBpZiAobmV4dEVsZW1lbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgd2hpbGUgKHBFbnVtLmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuZXh0ID0gcEVudW0ubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFyZXNvdXJjZXMuY29udGFpbnNLZXkobmV4dCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG5leHRFbGVtZW50ID0gbmV4dDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTW9yZUVsZW1lbnRzKCkgeworICAgICAgICAgICAgICAgIGlmIChsb2NhbC5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGZpbmROZXh0KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgbmV4dEVsZW1lbnQoKSB7CisgICAgICAgICAgICAgICAgaWYgKGxvY2FsLmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbC5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoZmluZE5leHQoKSkgeworICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcmVzdWx0ID0gbmV4dEVsZW1lbnQ7CisgICAgICAgICAgICAgICAgICAgIG5leHRFbGVtZW50ID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gQ2F1c2UgYW4gZXhjZXB0aW9uCisgICAgICAgICAgICAgICAgcmV0dXJuIHBFbnVtLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBoYW5kbGVHZXRPYmplY3QoU3RyaW5nIGtleSkgeworICAgICAgICByZXR1cm4gcmVzb3VyY2VzLmdldChrZXkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvUXVldWUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvUXVldWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YWVmOTQ0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9RdWV1ZS5qYXZhCkBAIC0wLDAgKzEsMTg4IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisvLyBCRUdJTiBhbmRyb2lkLW5vdGUKKy8vIHJlbW92ZWQgbGluayB0byBjb2xsZWN0aW9ucyBmcmFtZXdvcmsgZG9jcworLy8gRU5EIGFuZHJvaWQtbm90ZQorCisvKioKKyAqIEEgY29sbGVjdGlvbiBkZXNpZ25lZCBmb3IgaG9sZGluZyBlbGVtZW50cyBwcmlvciB0byBwcm9jZXNzaW5nLgorICogQmVzaWRlcyBiYXNpYyB7QGxpbmsgamF2YS51dGlsLkNvbGxlY3Rpb24gQ29sbGVjdGlvbn0gb3BlcmF0aW9ucywKKyAqIHF1ZXVlcyBwcm92aWRlIGFkZGl0aW9uYWwgaW5zZXJ0aW9uLCBleHRyYWN0aW9uLCBhbmQgaW5zcGVjdGlvbgorICogb3BlcmF0aW9ucy4gIEVhY2ggb2YgdGhlc2UgbWV0aG9kcyBleGlzdHMgaW4gdHdvIGZvcm1zOiBvbmUgdGhyb3dzCisgKiBhbiBleGNlcHRpb24gaWYgdGhlIG9wZXJhdGlvbiBmYWlscywgdGhlIG90aGVyIHJldHVybnMgYSBzcGVjaWFsCisgKiB2YWx1ZSAoZWl0aGVyIDx0dD5udWxsPC90dD4gb3IgPHR0PmZhbHNlPC90dD4sIGRlcGVuZGluZyBvbiB0aGUKKyAqIG9wZXJhdGlvbikuICBUaGUgbGF0dGVyIGZvcm0gb2YgdGhlIGluc2VydCBvcGVyYXRpb24gaXMgZGVzaWduZWQKKyAqIHNwZWNpZmljYWxseSBmb3IgdXNlIHdpdGggY2FwYWNpdHktcmVzdHJpY3RlZCA8dHQ+UXVldWU8L3R0PgorICogaW1wbGVtZW50YXRpb25zOyBpbiBtb3N0IGltcGxlbWVudGF0aW9ucywgaW5zZXJ0IG9wZXJhdGlvbnMgY2Fubm90CisgKiBmYWlsLgorICoKKyAqIDxwPgorICogPHRhYmxlIEJPUkRFUiBDRUxMUEFERElORz0zIENFTExTUEFDSU5HPTE+CisgKiAgPHRyPgorICogICAgPHRkPjwvdGQ+CisgKiAgICA8dGQgQUxJR049Q0VOVEVSPjxlbT5UaHJvd3MgZXhjZXB0aW9uPC9lbT48L3RkPgorICogICAgPHRkIEFMSUdOPUNFTlRFUj48ZW0+UmV0dXJucyBzcGVjaWFsIHZhbHVlPC9lbT48L3RkPgorICogIDwvdHI+CisgKiAgPHRyPgorICogICAgPHRkPjxiPkluc2VydDwvYj48L3RkPgorICogICAgPHRkPntAbGluayAjYWRkIGFkZChlKX08L3RkPgorICogICAgPHRkPntAbGluayAjb2ZmZXIgb2ZmZXIoZSl9PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZD48Yj5SZW1vdmU8L2I+PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI3JlbW92ZSByZW1vdmUoKX08L3RkPgorICogICAgPHRkPntAbGluayAjcG9sbCBwb2xsKCl9PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZD48Yj5FeGFtaW5lPC9iPjwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNlbGVtZW50IGVsZW1lbnQoKX08L3RkPgorICogICAgPHRkPntAbGluayAjcGVlayBwZWVrKCl9PC90ZD4KKyAqICA8L3RyPgorICogPC90YWJsZT4KKyAqCisgKiA8cD5RdWV1ZXMgdHlwaWNhbGx5LCBidXQgZG8gbm90IG5lY2Vzc2FyaWx5LCBvcmRlciBlbGVtZW50cyBpbiBhCisgKiBGSUZPIChmaXJzdC1pbi1maXJzdC1vdXQpIG1hbm5lci4gIEFtb25nIHRoZSBleGNlcHRpb25zIGFyZQorICogcHJpb3JpdHkgcXVldWVzLCB3aGljaCBvcmRlciBlbGVtZW50cyBhY2NvcmRpbmcgdG8gYSBzdXBwbGllZAorICogY29tcGFyYXRvciwgb3IgdGhlIGVsZW1lbnRzJyBuYXR1cmFsIG9yZGVyaW5nLCBhbmQgTElGTyBxdWV1ZXMgKG9yCisgKiBzdGFja3MpIHdoaWNoIG9yZGVyIHRoZSBlbGVtZW50cyBMSUZPIChsYXN0LWluLWZpcnN0LW91dCkuCisgKiBXaGF0ZXZlciB0aGUgb3JkZXJpbmcgdXNlZCwgdGhlIDxlbT5oZWFkPC9lbT4gb2YgdGhlIHF1ZXVlIGlzIHRoYXQKKyAqIGVsZW1lbnQgd2hpY2ggd291bGQgYmUgcmVtb3ZlZCBieSBhIGNhbGwgdG8ge0BsaW5rICNyZW1vdmUoKSB9IG9yCisgKiB7QGxpbmsgI3BvbGwoKX0uICBJbiBhIEZJRk8gcXVldWUsIGFsbCBuZXcgZWxlbWVudHMgYXJlIGluc2VydGVkIGF0CisgKiB0aGUgPGVtPiB0YWlsPC9lbT4gb2YgdGhlIHF1ZXVlLiBPdGhlciBraW5kcyBvZiBxdWV1ZXMgbWF5IHVzZQorICogZGlmZmVyZW50IHBsYWNlbWVudCBydWxlcy4gIEV2ZXJ5IDx0dD5RdWV1ZTwvdHQ+IGltcGxlbWVudGF0aW9uCisgKiBtdXN0IHNwZWNpZnkgaXRzIG9yZGVyaW5nIHByb3BlcnRpZXMuCisgKgorICogPHA+VGhlIHtAbGluayAjb2ZmZXIgb2ZmZXJ9IG1ldGhvZCBpbnNlcnRzIGFuIGVsZW1lbnQgaWYgcG9zc2libGUsCisgKiBvdGhlcndpc2UgcmV0dXJuaW5nIDx0dD5mYWxzZTwvdHQ+LiAgVGhpcyBkaWZmZXJzIGZyb20gdGhlIHtAbGluaworICogamF2YS51dGlsLkNvbGxlY3Rpb24jYWRkIENvbGxlY3Rpb24uYWRkfSBtZXRob2QsIHdoaWNoIGNhbiBmYWlsIHRvCisgKiBhZGQgYW4gZWxlbWVudCBvbmx5IGJ5IHRocm93aW5nIGFuIHVuY2hlY2tlZCBleGNlcHRpb24uICBUaGUKKyAqIDx0dD5vZmZlcjwvdHQ+IG1ldGhvZCBpcyBkZXNpZ25lZCBmb3IgdXNlIHdoZW4gZmFpbHVyZSBpcyBhIG5vcm1hbCwKKyAqIHJhdGhlciB0aGFuIGV4Y2VwdGlvbmFsIG9jY3VycmVuY2UsIGZvciBleGFtcGxlLCBpbiBmaXhlZC1jYXBhY2l0eQorICogKG9yICZxdW90O2JvdW5kZWQmcXVvdDspIHF1ZXVlcy4KKyAqCisgKiA8cD5UaGUge0BsaW5rICNyZW1vdmUoKX0gYW5kIHtAbGluayAjcG9sbCgpfSBtZXRob2RzIHJlbW92ZSBhbmQKKyAqIHJldHVybiB0aGUgaGVhZCBvZiB0aGUgcXVldWUuCisgKiBFeGFjdGx5IHdoaWNoIGVsZW1lbnQgaXMgcmVtb3ZlZCBmcm9tIHRoZSBxdWV1ZSBpcyBhCisgKiBmdW5jdGlvbiBvZiB0aGUgcXVldWUncyBvcmRlcmluZyBwb2xpY3ksIHdoaWNoIGRpZmZlcnMgZnJvbQorICogaW1wbGVtZW50YXRpb24gdG8gaW1wbGVtZW50YXRpb24uIFRoZSA8dHQ+cmVtb3ZlKCk8L3R0PiBhbmQKKyAqIDx0dD5wb2xsKCk8L3R0PiBtZXRob2RzIGRpZmZlciBvbmx5IGluIHRoZWlyIGJlaGF2aW9yIHdoZW4gdGhlCisgKiBxdWV1ZSBpcyBlbXB0eTogdGhlIDx0dD5yZW1vdmUoKTwvdHQ+IG1ldGhvZCB0aHJvd3MgYW4gZXhjZXB0aW9uLAorICogd2hpbGUgdGhlIDx0dD5wb2xsKCk8L3R0PiBtZXRob2QgcmV0dXJucyA8dHQ+bnVsbDwvdHQ+LgorICoKKyAqIDxwPlRoZSB7QGxpbmsgI2VsZW1lbnQoKX0gYW5kIHtAbGluayAjcGVlaygpfSBtZXRob2RzIHJldHVybiwgYnV0IGRvCisgKiBub3QgcmVtb3ZlLCB0aGUgaGVhZCBvZiB0aGUgcXVldWUuCisgKgorICogPHA+VGhlIDx0dD5RdWV1ZTwvdHQ+IGludGVyZmFjZSBkb2VzIG5vdCBkZWZpbmUgdGhlIDxpPmJsb2NraW5nIHF1ZXVlCisgKiBtZXRob2RzPC9pPiwgd2hpY2ggYXJlIGNvbW1vbiBpbiBjb25jdXJyZW50IHByb2dyYW1taW5nLiAgVGhlc2UgbWV0aG9kcywKKyAqIHdoaWNoIHdhaXQgZm9yIGVsZW1lbnRzIHRvIGFwcGVhciBvciBmb3Igc3BhY2UgdG8gYmVjb21lIGF2YWlsYWJsZSwgYXJlCisgKiBkZWZpbmVkIGluIHRoZSB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuQmxvY2tpbmdRdWV1ZX0gaW50ZXJmYWNlLCB3aGljaAorICogZXh0ZW5kcyB0aGlzIGludGVyZmFjZS4KKyAqCisgKiA8cD48dHQ+UXVldWU8L3R0PiBpbXBsZW1lbnRhdGlvbnMgZ2VuZXJhbGx5IGRvIG5vdCBhbGxvdyBpbnNlcnRpb24KKyAqIG9mIDx0dD5udWxsPC90dD4gZWxlbWVudHMsIGFsdGhvdWdoIHNvbWUgaW1wbGVtZW50YXRpb25zLCBzdWNoIGFzCisgKiB7QGxpbmsgTGlua2VkTGlzdH0sIGRvIG5vdCBwcm9oaWJpdCBpbnNlcnRpb24gb2YgPHR0Pm51bGw8L3R0Pi4KKyAqIEV2ZW4gaW4gdGhlIGltcGxlbWVudGF0aW9ucyB0aGF0IHBlcm1pdCBpdCwgPHR0Pm51bGw8L3R0PiBzaG91bGQKKyAqIG5vdCBiZSBpbnNlcnRlZCBpbnRvIGEgPHR0PlF1ZXVlPC90dD4sIGFzIDx0dD5udWxsPC90dD4gaXMgYWxzbworICogdXNlZCBhcyBhIHNwZWNpYWwgcmV0dXJuIHZhbHVlIGJ5IHRoZSA8dHQ+cG9sbDwvdHQ+IG1ldGhvZCB0bworICogaW5kaWNhdGUgdGhhdCB0aGUgcXVldWUgY29udGFpbnMgbm8gZWxlbWVudHMuCisgKgorICogPHA+PHR0PlF1ZXVlPC90dD4gaW1wbGVtZW50YXRpb25zIGdlbmVyYWxseSBkbyBub3QgZGVmaW5lCisgKiBlbGVtZW50LWJhc2VkIHZlcnNpb25zIG9mIG1ldGhvZHMgPHR0PmVxdWFsczwvdHQ+IGFuZAorICogPHR0Pmhhc2hDb2RlPC90dD4gYnV0IGluc3RlYWQgaW5oZXJpdCB0aGUgaWRlbnRpdHkgYmFzZWQgdmVyc2lvbnMKKyAqIGZyb20gY2xhc3MgPHR0Pk9iamVjdDwvdHQ+LCBiZWNhdXNlIGVsZW1lbnQtYmFzZWQgZXF1YWxpdHkgaXMgbm90CisgKiBhbHdheXMgd2VsbC1kZWZpbmVkIGZvciBxdWV1ZXMgd2l0aCB0aGUgc2FtZSBlbGVtZW50cyBidXQgZGlmZmVyZW50CisgKiBvcmRlcmluZyBwcm9wZXJ0aWVzLgorICoKKyAqIEBzZWUgamF2YS51dGlsLkNvbGxlY3Rpb24KKyAqIEBzZWUgTGlua2VkTGlzdAorICogQHNlZSBQcmlvcml0eVF1ZXVlCisgKiBAc2VlIGphdmEudXRpbC5jb25jdXJyZW50LkxpbmtlZEJsb2NraW5nUXVldWUKKyAqIEBzZWUgamF2YS51dGlsLmNvbmN1cnJlbnQuQmxvY2tpbmdRdWV1ZQorICogQHNlZSBqYXZhLnV0aWwuY29uY3VycmVudC5BcnJheUJsb2NraW5nUXVldWUKKyAqIEBzZWUgamF2YS51dGlsLmNvbmN1cnJlbnQuTGlua2VkQmxvY2tpbmdRdWV1ZQorICogQHNlZSBqYXZhLnV0aWwuY29uY3VycmVudC5Qcmlvcml0eUJsb2NraW5nUXVldWUKKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqIEBwYXJhbSA8RT4gdGhlIHR5cGUgb2YgZWxlbWVudHMgaGVsZCBpbiB0aGlzIGNvbGxlY3Rpb24KKyAqLworcHVibGljIGludGVyZmFjZSBRdWV1ZTxFPiBleHRlbmRzIENvbGxlY3Rpb248RT4geworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGludG8gdGhpcyBxdWV1ZSBpZiBpdCBpcyBwb3NzaWJsZSB0byBkbyBzbworICAgICAqIGltbWVkaWF0ZWx5IHdpdGhvdXQgdmlvbGF0aW5nIGNhcGFjaXR5IHJlc3RyaWN0aW9ucywgcmV0dXJuaW5nCisgICAgICogPHR0PnRydWU8L3R0PiB1cG9uIHN1Y2Nlc3MgYW5kIHRocm93aW5nIGFuIDx0dD5JbGxlZ2FsU3RhdGVFeGNlcHRpb248L3R0PgorICAgICAqIGlmIG5vIHNwYWNlIGlzIGN1cnJlbnRseSBhdmFpbGFibGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byBhZGQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gKGFzIHNwZWNpZmllZCBieSB7QGxpbmsgQ29sbGVjdGlvbiNhZGR9KQorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZSBlbGVtZW50IGNhbm5vdCBiZSBhZGRlZCBhdCB0aGlzCisgICAgICogICAgICAgICB0aW1lIGR1ZSB0byBjYXBhY2l0eSByZXN0cmljdGlvbnMKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3Mgb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICogICAgICAgICBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgcXVldWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsIGFuZAorICAgICAqICAgICAgICAgdGhpcyBxdWV1ZSBkb2VzIG5vdCBwZXJtaXQgbnVsbCBlbGVtZW50cworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNvbWUgcHJvcGVydHkgb2YgdGhpcyBlbGVtZW50CisgICAgICogICAgICAgICBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgcXVldWUKKyAgICAgKi8KKyAgICBib29sZWFuIGFkZChFIGUpOworCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaW50byB0aGlzIHF1ZXVlIGlmIGl0IGlzIHBvc3NpYmxlIHRvIGRvCisgICAgICogc28gaW1tZWRpYXRlbHkgd2l0aG91dCB2aW9sYXRpbmcgY2FwYWNpdHkgcmVzdHJpY3Rpb25zLgorICAgICAqIFdoZW4gdXNpbmcgYSBjYXBhY2l0eS1yZXN0cmljdGVkIHF1ZXVlLCB0aGlzIG1ldGhvZCBpcyBnZW5lcmFsbHkKKyAgICAgKiBwcmVmZXJhYmxlIHRvIHtAbGluayAjYWRkfSwgd2hpY2ggY2FuIGZhaWwgdG8gaW5zZXJ0IGFuIGVsZW1lbnQgb25seQorICAgICAqIGJ5IHRocm93aW5nIGFuIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIHRoZSBlbGVtZW50IHRvIGFkZAorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGUgZWxlbWVudCB3YXMgYWRkZWQgdG8gdGhpcyBxdWV1ZSwgZWxzZQorICAgICAqICAgICAgICAgPHR0PmZhbHNlPC90dD4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3Mgb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICogICAgICAgICBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgcXVldWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsIGFuZAorICAgICAqICAgICAgICAgdGhpcyBxdWV1ZSBkb2VzIG5vdCBwZXJtaXQgbnVsbCBlbGVtZW50cworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNvbWUgcHJvcGVydHkgb2YgdGhpcyBlbGVtZW50CisgICAgICogICAgICAgICBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgcXVldWUKKyAgICAgKi8KKyAgICBib29sZWFuIG9mZmVyKEUgZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYW5kIHJlbW92ZXMgdGhlIGhlYWQgb2YgdGhpcyBxdWV1ZS4gIFRoaXMgbWV0aG9kIGRpZmZlcnMKKyAgICAgKiBmcm9tIHtAbGluayAjcG9sbCBwb2xsfSBvbmx5IGluIHRoYXQgaXQgdGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0aGlzCisgICAgICogcXVldWUgaXMgZW1wdHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWFkIG9mIHRoaXMgcXVldWUKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gaWYgdGhpcyBxdWV1ZSBpcyBlbXB0eQorICAgICAqLworICAgIEUgcmVtb3ZlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYW5kIHJlbW92ZXMgdGhlIGhlYWQgb2YgdGhpcyBxdWV1ZSwKKyAgICAgKiBvciByZXR1cm5zIDx0dD5udWxsPC90dD4gaWYgdGhpcyBxdWV1ZSBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhlYWQgb2YgdGhpcyBxdWV1ZSwgb3IgPHR0Pm51bGw8L3R0PiBpZiB0aGlzIHF1ZXVlIGlzIGVtcHR5CisgICAgICovCisgICAgRSBwb2xsKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMsIGJ1dCBkb2VzIG5vdCByZW1vdmUsIHRoZSBoZWFkIG9mIHRoaXMgcXVldWUuICBUaGlzIG1ldGhvZAorICAgICAqIGRpZmZlcnMgZnJvbSB7QGxpbmsgI3BlZWsgcGVla30gb25seSBpbiB0aGF0IGl0IHRocm93cyBhbiBleGNlcHRpb24KKyAgICAgKiBpZiB0aGlzIHF1ZXVlIGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGlzIHF1ZXVlCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGlmIHRoaXMgcXVldWUgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBFIGVsZW1lbnQoKTsKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcywgYnV0IGRvZXMgbm90IHJlbW92ZSwgdGhlIGhlYWQgb2YgdGhpcyBxdWV1ZSwKKyAgICAgKiBvciByZXR1cm5zIDx0dD5udWxsPC90dD4gaWYgdGhpcyBxdWV1ZSBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhlYWQgb2YgdGhpcyBxdWV1ZSwgb3IgPHR0Pm51bGw8L3R0PiBpZiB0aGlzIHF1ZXVlIGlzIGVtcHR5CisgICAgICovCisgICAgRSBwZWVrKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1JhbmRvbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9SYW5kb20uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43Y2U3NGNjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9SYW5kb20uamF2YQpAQCAtMCwwICsxLDIwNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCisvKioKKyAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgbWV0aG9kcyB0aGF0IHJldHVybiBwc2V1ZG8tcmFuZG9tIHZhbHVlcy4KKyAqCisgKiA8cD5JdCBpcyBkYW5nZXJvdXMgdG8gc2VlZCB7QGNvZGUgUmFuZG9tfSB3aXRoIHRoZSBjdXJyZW50IHRpbWUgYmVjYXVzZQorICogdGhhdCB2YWx1ZSBpcyBtb3JlIHByZWRpY3RhYmxlIHRvIGFuIGF0dGFja2VyIHRoYW4gdGhlIGRlZmF1bHQgc2VlZC4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGlzIHRocmVhZC1zYWZlLgorICoKKyAqIEBzZWUgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb20KKyAqLworcHVibGljIGNsYXNzIFJhbmRvbSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzOTA1MzQ4OTc4MjQwMTI5NjE5TDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgbXVsdGlwbGllciA9IDB4NWRlZWNlNjZkTDsKKworICAgIC8qKgorICAgICAqIFRoZSBib29sZWFuIHZhbHVlIGluZGljYXRpbmcgaWYgdGhlIHNlY29uZCBHYXVzc2lhbiBudW1iZXIgaXMgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBoYXZlTmV4dE5leHRHYXVzc2lhbjsKKworICAgIC8qKgorICAgICAqIEBzZXJpYWwgSXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBpbnRlcm5hbCBzdGF0ZSBvZiB0aGlzIGdlbmVyYXRvci4KKyAgICAgKi8KKyAgICBwcml2YXRlIGxvbmcgc2VlZDsKKworICAgIC8qKgorICAgICAqIFRoZSBzZWNvbmQgR2F1c3NpYW4gZ2VuZXJhdGVkIG51bWJlci4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIGRvdWJsZSBuZXh0TmV4dEdhdXNzaWFuOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHJhbmRvbSBnZW5lcmF0b3Igd2l0aCBhbiBpbml0aWFsIHN0YXRlIHRoYXQgaXMKKyAgICAgKiB1bmxpa2VseSB0byBiZSBkdXBsaWNhdGVkIGJ5IGEgc3Vic2VxdWVudCBpbnN0YW50aWF0aW9uLgorICAgICAqCisgICAgICogPHA+VGhlIGluaXRpYWwgc3RhdGUgKHRoYXQgaXMsIHRoZSBzZWVkKSBpcyA8aT5wYXJ0aWFsbHk8L2k+IGJhc2VkCisgICAgICogb24gdGhlIGN1cnJlbnQgdGltZSBvZiBkYXkgaW4gbWlsbGlzZWNvbmRzLgorICAgICAqLworICAgIHB1YmxpYyBSYW5kb20oKSB7CisgICAgICAgIC8vIE5vdGU6IFVzaW5nIGlkZW50aXR5SGFzaENvZGUoKSB0byBiZSBoZXJtZXRpYyB3cnQgc3ViY2xhc3Nlcy4KKyAgICAgICAgc2V0U2VlZChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIFN5c3RlbS5pZGVudGl0eUhhc2hDb2RlKHRoaXMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSByYW5kb20gZ2VuZXJhdG9yIHdpdGggdGhlIGdpdmVuIHtAY29kZSBzZWVkfSBhcyB0aGUKKyAgICAgKiBpbml0aWFsIHN0YXRlLiBFcXVpdmFsZW50IHRvIHtAY29kZSBSYW5kb20gciA9IG5ldyBSYW5kb20oKTsgci5zZXRTZWVkKHNlZWQpO30uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGNvbnN0cnVjdG9yIGlzIG1haW5seSB1c2VmdWwgZm9yIDxpPnByZWRpY3RhYmlsaXR5PC9pPiBpbiB0ZXN0cy4KKyAgICAgKiBUaGUgZGVmYXVsdCBjb25zdHJ1Y3RvciBpcyBsaWtlbHkgdG8gcHJvdmlkZSBiZXR0ZXIgcmFuZG9tbmVzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmFuZG9tKGxvbmcgc2VlZCkgeworICAgICAgICBzZXRTZWVkKHNlZWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBwc2V1ZG8tcmFuZG9tIHVuaWZvcm1seSBkaXN0cmlidXRlZCB7QGNvZGUgaW50fSB2YWx1ZSBvZgorICAgICAqIHRoZSBudW1iZXIgb2YgYml0cyBzcGVjaWZpZWQgYnkgdGhlIGFyZ3VtZW50IHtAY29kZSBiaXRzfSBhcworICAgICAqIGRlc2NyaWJlZCBieSBEb25hbGQgRS4gS251dGggaW4gPGk+VGhlIEFydCBvZiBDb21wdXRlciBQcm9ncmFtbWluZywKKyAgICAgKiBWb2x1bWUgMjogU2VtaW51bWVyaWNhbCBBbGdvcml0aG1zPC9pPiwgc2VjdGlvbiAzLjIuMS4KKyAgICAgKgorICAgICAqIDxwPk1vc3QgYXBwbGljYXRpb25zIHdpbGwgd2FudCB0byB1c2Ugb25lIG9mIHRoaXMgY2xhc3MnIGNvbnZlbmllbmNlIG1ldGhvZHMgaW5zdGVhZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIGludCBuZXh0KGludCBiaXRzKSB7CisgICAgICAgIHNlZWQgPSAoc2VlZCAqIG11bHRpcGxpZXIgKyAweGJMKSAmICgoMUwgPDwgNDgpIC0gMSk7CisgICAgICAgIHJldHVybiAoaW50KSAoc2VlZCA+Pj4gKDQ4IC0gYml0cykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBwc2V1ZG8tcmFuZG9tIHVuaWZvcm1seSBkaXN0cmlidXRlZCB7QGNvZGUgYm9vbGVhbn0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbmV4dEJvb2xlYW4oKSB7CisgICAgICAgIHJldHVybiBuZXh0KDEpICE9IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsbHMge0Bjb2RlIGJ1Zn0gd2l0aCByYW5kb20gYnl0ZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgbmV4dEJ5dGVzKGJ5dGVbXSBidWYpIHsKKyAgICAgICAgaW50IHJhbmQgPSAwLCBjb3VudCA9IDAsIGxvb3AgPSAwOworICAgICAgICB3aGlsZSAoY291bnQgPCBidWYubGVuZ3RoKSB7CisgICAgICAgICAgICBpZiAobG9vcCA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmFuZCA9IG5leHRJbnQoKTsKKyAgICAgICAgICAgICAgICBsb29wID0gMzsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgbG9vcC0tOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnVmW2NvdW50KytdID0gKGJ5dGUpIHJhbmQ7CisgICAgICAgICAgICByYW5kID4+PSA4OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHBzZXVkby1yYW5kb20gdW5pZm9ybWx5IGRpc3RyaWJ1dGVkIHtAY29kZSBkb3VibGV9CisgICAgICogaW4gdGhlIGhhbGYtb3BlbiByYW5nZSBbMC4wLCAxLjApLgorICAgICAqLworICAgIHB1YmxpYyBkb3VibGUgbmV4dERvdWJsZSgpIHsKKyAgICAgICAgcmV0dXJuICgoKChsb25nKSBuZXh0KDI2KSA8PCAyNykgKyBuZXh0KDI3KSkgLyAoZG91YmxlKSAoMUwgPDwgNTMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcHNldWRvLXJhbmRvbSB1bmlmb3JtbHkgZGlzdHJpYnV0ZWQge0Bjb2RlIGZsb2F0fQorICAgICAqIGluIHRoZSBoYWxmLW9wZW4gcmFuZ2UgWzAuMCwgMS4wKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgbmV4dEZsb2F0KCkgeworICAgICAgICByZXR1cm4gKG5leHQoMjQpIC8gMTY3NzcyMTZmKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcHNldWRvLXJhbmRvbSAoYXBwcm94aW1hdGVseSkgbm9ybWFsbHkgZGlzdHJpYnV0ZWQKKyAgICAgKiB7QGNvZGUgZG91YmxlfSB3aXRoIG1lYW4gMC4wIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gMS4wLgorICAgICAqIFRoaXMgbWV0aG9kIHVzZXMgdGhlIDxpPnBvbGFyIG1ldGhvZDwvaT4gb2YgRy4gRS4gUC4gQm94LCBNLgorICAgICAqIEUuIE11bGxlciwgYW5kIEcuIE1hcnNhZ2xpYSwgYXMgZGVzY3JpYmVkIGJ5IERvbmFsZCBFLiBLbnV0aCBpbiA8aT5UaGUKKyAgICAgKiBBcnQgb2YgQ29tcHV0ZXIgUHJvZ3JhbW1pbmcsIFZvbHVtZSAyOiBTZW1pbnVtZXJpY2FsIEFsZ29yaXRobXM8L2k+LAorICAgICAqIHNlY3Rpb24gMy40LjEsIHN1YnNlY3Rpb24gQywgYWxnb3JpdGhtIFAuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBkb3VibGUgbmV4dEdhdXNzaWFuKCkgeworICAgICAgICBpZiAoaGF2ZU5leHROZXh0R2F1c3NpYW4pIHsgLy8gaWYgWDEgaGFzIGJlZW4gcmV0dXJuZWQsIHJldHVybiB0aGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlY29uZCBHYXVzc2lhbgorICAgICAgICAgICAgaGF2ZU5leHROZXh0R2F1c3NpYW4gPSBmYWxzZTsKKyAgICAgICAgICAgIHJldHVybiBuZXh0TmV4dEdhdXNzaWFuOworICAgICAgICB9CisKKyAgICAgICAgZG91YmxlIHYxLCB2MiwgczsKKyAgICAgICAgZG8geworICAgICAgICAgICAgdjEgPSAyICogbmV4dERvdWJsZSgpIC0gMTsgLy8gR2VuZXJhdGVzIHR3byBpbmRlcGVuZGVudCByYW5kb20KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2YXJpYWJsZXMgVTEsIFUyCisgICAgICAgICAgICB2MiA9IDIgKiBuZXh0RG91YmxlKCkgLSAxOworICAgICAgICAgICAgcyA9IHYxICogdjEgKyB2MiAqIHYyOworICAgICAgICB9IHdoaWxlIChzID49IDEpOworICAgICAgICBkb3VibGUgbm9ybSA9IE1hdGguc3FydCgtMiAqIE1hdGgubG9nKHMpIC8gcyk7CisgICAgICAgIG5leHROZXh0R2F1c3NpYW4gPSB2MiAqIG5vcm07IC8vIHNob3VsZCB0aGF0IG5vdCBiZSBub3JtIGluc3RlYWQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvZiBtdWx0aXBsaWVyID8KKyAgICAgICAgaGF2ZU5leHROZXh0R2F1c3NpYW4gPSB0cnVlOworICAgICAgICByZXR1cm4gdjEgKiBub3JtOyAvLyBzaG91bGQgdGhhdCBub3QgYmUgbm9ybSBpbnN0ZWFkIG9mIG11bHRpcGxpZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA/CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHBzZXVkby1yYW5kb20gdW5pZm9ybWx5IGRpc3RyaWJ1dGVkIHtAY29kZSBpbnR9LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgbmV4dEludCgpIHsKKyAgICAgICAgcmV0dXJuIG5leHQoMzIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBwc2V1ZG8tcmFuZG9tIHVuaWZvcm1seSBkaXN0cmlidXRlZCB7QGNvZGUgaW50fQorICAgICAqIGluIHRoZSBoYWxmLW9wZW4gcmFuZ2UgWzAsIG4pLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgbmV4dEludChpbnQgbikgeworICAgICAgICBpZiAobiA+IDApIHsKKyAgICAgICAgICAgIGlmICgobiAmIC1uKSA9PSBuKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChpbnQpICgobiAqIChsb25nKSBuZXh0KDMxKSkgPj4gMzEpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IGJpdHMsIHZhbDsKKyAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICBiaXRzID0gbmV4dCgzMSk7CisgICAgICAgICAgICAgICAgdmFsID0gYml0cyAlIG47CisgICAgICAgICAgICB9IHdoaWxlIChiaXRzIC0gdmFsICsgKG4gLSAxKSA8IDApOworICAgICAgICAgICAgcmV0dXJuIHZhbDsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHBzZXVkby1yYW5kb20gdW5pZm9ybWx5IGRpc3RyaWJ1dGVkIHtAY29kZSBsb25nfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBuZXh0TG9uZygpIHsKKyAgICAgICAgcmV0dXJuICgobG9uZykgbmV4dCgzMikgPDwgMzIpICsgbmV4dCgzMik7CisgICAgfQorCisgICAgLyoqCisgICAgICogTW9kaWZpZXMgdGhlIHNlZWQgdXNpbmcgYSBsaW5lYXIgY29uZ3J1ZW50aWFsIGZvcm11bGEgcHJlc2VudGVkIGluIDxpPlRoZQorICAgICAqIEFydCBvZiBDb21wdXRlciBQcm9ncmFtbWluZywgVm9sdW1lIDI8L2k+LCBTZWN0aW9uIDMuMi4xLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRTZWVkKGxvbmcgc2VlZCkgeworICAgICAgICB0aGlzLnNlZWQgPSAoc2VlZCBeIG11bHRpcGxpZXIpICYgKCgxTCA8PCA0OCkgLSAxKTsKKyAgICAgICAgaGF2ZU5leHROZXh0R2F1c3NpYW4gPSBmYWxzZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1JhbmRvbUFjY2Vzcy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9SYW5kb21BY2Nlc3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MTIxYmZmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9SYW5kb21BY2Nlc3MuamF2YQpAQCAtMCwwICsxLDI2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworLyoqCisgKiBSYW5kb21BY2Nlc3MgaXMgaW1wbGVtZW50ZWQgYnkge0Bjb2RlIExpc3R9IGltcGxlbWVudGF0aW9ucyB0aGF0IHN1cHBvcnQgZmFzdAorICogKHVzdWFsbHkgY29uc3RhbnQgdGltZSkgcmFuZG9tIGFjY2Vzcy4KKyAqLworcHVibGljIGludGVyZmFjZSBSYW5kb21BY2Nlc3MgeworICAgIC8qIGVtcHR5ICovCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1Jlc291cmNlQnVuZGxlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1Jlc291cmNlQnVuZGxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmYzOGI1YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvUmVzb3VyY2VCdW5kbGUuamF2YQpAQCAtMCwwICsxLDEwNTUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgZGFsdmlrLnN5c3RlbS5WTVN0YWNrOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5uZXQuVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRzOworaW1wb3J0IHN0YXRpYyBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRzLlVURl84OworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKKworLyoqCisgKiB7QGNvZGUgUmVzb3VyY2VCdW5kbGV9IGlzIGFuIGFic3RyYWN0IGNsYXNzIHdoaWNoIGlzIHRoZSBzdXBlcmNsYXNzIG9mIGNsYXNzZXMgd2hpY2gKKyAqIHByb3ZpZGUge0Bjb2RlIExvY2FsZX0tc3BlY2lmaWMgcmVzb3VyY2VzLiBBIGJ1bmRsZSBjb250YWlucyBhIG51bWJlciBvZiBuYW1lZAorICogcmVzb3VyY2VzLCB3aGVyZSB0aGUgbmFtZXMgYXJlIHtAY29kZSBTdHJpbmdzfS4gQSBidW5kbGUgbWF5IGhhdmUgYSBwYXJlbnQgYnVuZGxlLAorICogYW5kIHdoZW4gYSByZXNvdXJjZSBpcyBub3QgZm91bmQgaW4gYSBidW5kbGUsIHRoZSBwYXJlbnQgYnVuZGxlIGlzIHNlYXJjaGVkIGZvcgorICogdGhlIHJlc291cmNlLiBJZiB0aGUgZmFsbGJhY2sgbWVjaGFuaXNtIHJlYWNoZXMgdGhlIGJhc2UgYnVuZGxlIGFuZCBzdGlsbAorICogY2FuJ3QgZmluZCB0aGUgcmVzb3VyY2UgaXQgdGhyb3dzIGEge0Bjb2RlIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbn0uCisgKgorICogPHVsPgorICogPGxpPkFsbCBidW5kbGVzIGZvciB0aGUgc2FtZSBncm91cCBvZiByZXNvdXJjZXMgc2hhcmUgYSBjb21tb24gYmFzZSBidW5kbGUuCisgKiBUaGlzIGJhc2UgYnVuZGxlIGFjdHMgYXMgdGhlIHJvb3QgYW5kIGlzIHRoZSBsYXN0IGZhbGxiYWNrIGluIGNhc2Ugbm9uZSBvZgorICogaXRzIGNoaWxkcmVuIHdhcyBhYmxlIHRvIHJlc3BvbmQgdG8gYSByZXF1ZXN0LjwvbGk+CisgKiA8bGk+VGhlIGZpcnN0IGxldmVsIGNvbnRhaW5zIGNoYW5nZXMgYmV0d2VlbiBkaWZmZXJlbnQgbGFuZ3VhZ2VzLiBPbmx5IHRoZQorICogZGlmZmVyZW5jZXMgYmV0d2VlbiBhIGxhbmd1YWdlIGFuZCB0aGUgbGFuZ3VhZ2Ugb2YgdGhlIGJhc2UgYnVuZGxlIG5lZWQgdG8gYmUKKyAqIGhhbmRsZWQgYnkgYSBsYW5ndWFnZS1zcGVjaWZpYyB7QGNvZGUgUmVzb3VyY2VCdW5kbGV9LjwvbGk+CisgKiA8bGk+VGhlIHNlY29uZCBsZXZlbCBjb250YWlucyBjaGFuZ2VzIGJldHdlZW4gZGlmZmVyZW50IGNvdW50cmllcyB0aGF0IHVzZQorICogdGhlIHNhbWUgbGFuZ3VhZ2UuIE9ubHkgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gYSBjb3VudHJ5IGFuZCB0aGUgY291bnRyeSBvZgorICogdGhlIGxhbmd1YWdlIGJ1bmRsZSBuZWVkIHRvIGJlIGhhbmRsZWQgYnkgYSBjb3VudHJ5LXNwZWNpZmljIHtAY29kZSBSZXNvdXJjZUJ1bmRsZX0uCisgKiA8L2xpPgorICogPGxpPlRoZSB0aGlyZCBsZXZlbCBjb250YWlucyBjaGFuZ2VzIHRoYXQgZG9uJ3QgaGF2ZSBhIGdlb2dyYXBoaWMgcmVhc29uCisgKiAoZS5nLiBjaGFuZ2VzIHRoYXQgd2hlcmUgbWFkZSBhdCBzb21lIHBvaW50IGluIHRpbWUgbGlrZSB7QGNvZGUgUFJFRVVST30gd2hlcmUgdGhlCisgKiBjdXJyZW5jeSBvZiBjb21lIGNvdW50cmllcyBjaGFuZ2VkLiBUaGUgY291bnRyeSBidW5kbGUgd291bGQgcmV0dXJuIHRoZQorICogY3VycmVudCBjdXJyZW5jeSAoRXVybykgYW5kIHRoZSB7QGNvZGUgUFJFRVVST30gdmFyaWFudCBidW5kbGUgd291bGQgcmV0dXJuIHRoZSBvbGQKKyAqIGN1cnJlbmN5IChlLmcuIERNIGZvciBHZXJtYW55KS48L2xpPgorICogPC91bD4KKyAqCisgKiA8c3Ryb25nPkV4YW1wbGVzPC9zdHJvbmc+CisgKiA8dWw+CisgKiA8bGk+QmFzZU5hbWUgKGJhc2UgYnVuZGxlKQorICogPGxpPkJhc2VOYW1lX2RlIChnZXJtYW4gbGFuZ3VhZ2UgYnVuZGxlKQorICogPGxpPkJhc2VOYW1lX2ZyIChmcmVuY2ggbGFuZ3VhZ2UgYnVuZGxlKQorICogPGxpPkJhc2VOYW1lX2RlX0RFIChidW5kbGUgd2l0aCBHZXJtYW55IHNwZWNpZmljIHJlc291cmNlcyBpbiBnZXJtYW4pCisgKiA8bGk+QmFzZU5hbWVfZGVfQ0ggKGJ1bmRsZSB3aXRoIFN3aXR6ZXJsYW5kIHNwZWNpZmljIHJlc291cmNlcyBpbiBnZXJtYW4pCisgKiA8bGk+QmFzZU5hbWVfZnJfQ0ggKGJ1bmRsZSB3aXRoIFN3aXR6ZXJsYW5kIHNwZWNpZmljIHJlc291cmNlcyBpbiBmcmVuY2gpCisgKiA8bGk+QmFzZU5hbWVfZGVfREVfUFJFRVVSTyAoYnVuZGxlIHdpdGggR2VybWFueSBzcGVjaWZpYyByZXNvdXJjZXMgaW4gZ2VybWFuIG9mCisgKiB0aGUgdGltZSBiZWZvcmUgdGhlIEV1cm8pCisgKiA8bGk+QmFzZU5hbWVfZnJfRlJfUFJFRVVSTyAoYnVuZGxlIHdpdGggRnJhbmNlIHNwZWNpZmljIHJlc291cmNlcyBpbiBmcmVuY2ggb2YKKyAqIHRoZSB0aW1lIGJlZm9yZSB0aGUgRXVybykKKyAqIDwvdWw+CisgKgorICogSXQncyBhbHNvIHBvc3NpYmxlIHRvIGNyZWF0ZSB2YXJpYW50cyBmb3IgbGFuZ3VhZ2VzIG9yIGNvdW50cmllcy4gVGhpcyBjYW4gYmUKKyAqIGRvbmUgYnkganVzdCBza2lwcGluZyB0aGUgY291bnRyeSBvciBsYW5ndWFnZSBhYmJyZXZpYXRpb246CisgKiBCYXNlTmFtZV91c19fUE9TSVggb3IgQmFzZU5hbWVfX0RFX1BSRUVVUk8uIEJ1dCBpdCdzIG5vdCBhbGxvd2VkIHRvCisgKiBjaXJjdW12ZW50IGJvdGggbGFuZ3VhZ2UgYW5kIGNvdW50cnk6IEJhc2VOYW1lX19fVkFSSUFOVCBpcyBpbGxlZ2FsLgorICoKKyAqIEBzZWUgUHJvcGVydGllcworICogQHNlZSBQcm9wZXJ0eVJlc291cmNlQnVuZGxlCisgKiBAc2VlIExpc3RSZXNvdXJjZUJ1bmRsZQorICogQHNpbmNlIDEuMQorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgUmVzb3VyY2VCdW5kbGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFVOREVSX1NDT1JFID0gIl8iOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVNUFRZX1NUUklORyA9ICIiOworCisgICAgLyoqCisgICAgICogVGhlIHBhcmVudCBvZiB0aGlzIHtAY29kZSBSZXNvdXJjZUJ1bmRsZX0gdGhhdCBpcyB1c2VkIGlmIHRoaXMgYnVuZGxlIGRvZXNuJ3QKKyAgICAgKiBpbmNsdWRlIHRoZSByZXF1ZXN0ZWQgcmVzb3VyY2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIFJlc291cmNlQnVuZGxlIHBhcmVudDsKKworICAgIHByaXZhdGUgTG9jYWxlIGxvY2FsZTsKKworICAgIHByaXZhdGUgbG9uZyBsYXN0TG9hZFRpbWUgPSAwOworCisgICAgc3RhdGljIGNsYXNzIE1pc3NpbmdCdW5kbGUgZXh0ZW5kcyBSZXNvdXJjZUJ1bmRsZSB7CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXRLZXlzKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIE9iamVjdCBoYW5kbGVHZXRPYmplY3QoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUmVzb3VyY2VCdW5kbGUgTUlTU0lORyA9IG5ldyBNaXNzaW5nQnVuZGxlKCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBSZXNvdXJjZUJ1bmRsZSBNSVNTSU5HQkFTRSA9IG5ldyBNaXNzaW5nQnVuZGxlKCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBXZWFrSGFzaE1hcDxPYmplY3QsIEhhc2h0YWJsZTxTdHJpbmcsIFJlc291cmNlQnVuZGxlPj4gY2FjaGUKKyAgICAgICAgICAgID0gbmV3IFdlYWtIYXNoTWFwPE9iamVjdCwgSGFzaHRhYmxlPFN0cmluZywgUmVzb3VyY2VCdW5kbGU+PigpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgTG9jYWxlIGNhY2hlTG9jYWxlID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzb3VyY2VCdW5kbGUoKSB7CisgICAgICAgIC8qIGVtcHR5ICovCisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgdGhlIG5hbWVkIHJlc291cmNlIGJ1bmRsZSBmb3IgdGhlIGRlZmF1bHQge0Bjb2RlIExvY2FsZX0gYW5kIHRoZSBjYWxsZXIncworICAgICAqIHtAY29kZSBDbGFzc0xvYWRlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVuZGxlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHtAY29kZSBSZXNvdXJjZUJ1bmRsZX0uCisgICAgICogQHJldHVybiB0aGUgcmVxdWVzdGVkIHtAY29kZSBSZXNvdXJjZUJ1bmRsZX0uCisgICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIFJlc291cmNlQnVuZGxlfSBjYW5ub3QgYmUgZm91bmQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBSZXNvdXJjZUJ1bmRsZSBnZXRCdW5kbGUoU3RyaW5nIGJ1bmRsZU5hbWUpIHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24geworICAgICAgICBDbGFzc0xvYWRlciBjbGFzc0xvYWRlciA9IFZNU3RhY2suZ2V0Q2FsbGluZ0NsYXNzTG9hZGVyKCk7CisgICAgICAgIGlmIChjbGFzc0xvYWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICBjbGFzc0xvYWRlciA9IGdldExvYWRlcigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRCdW5kbGUoYnVuZGxlTmFtZSwgTG9jYWxlLmdldERlZmF1bHQoKSwgY2xhc3NMb2FkZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIHRoZSBuYW1lZCB7QGNvZGUgUmVzb3VyY2VCdW5kbGV9IGZvciB0aGUgc3BlY2lmaWVkIHtAY29kZSBMb2NhbGV9IGFuZCB0aGUgY2FsbGVyCisgICAgICoge0Bjb2RlIENsYXNzTG9hZGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidW5kbGVOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUge0Bjb2RlIFJlc291cmNlQnVuZGxlfS4KKyAgICAgKiBAcGFyYW0gbG9jYWxlCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIExvY2FsZX0uCisgICAgICogQHJldHVybiB0aGUgcmVxdWVzdGVkIHJlc291cmNlIGJ1bmRsZS4KKyAgICAgKiBAdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSByZXNvdXJjZSBidW5kbGUgY2Fubm90IGJlIGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUmVzb3VyY2VCdW5kbGUgZ2V0QnVuZGxlKFN0cmluZyBidW5kbGVOYW1lLCBMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyID0gVk1TdGFjay5nZXRDYWxsaW5nQ2xhc3NMb2FkZXIoKTsKKyAgICAgICAgaWYgKGNsYXNzTG9hZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIGNsYXNzTG9hZGVyID0gZ2V0TG9hZGVyKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEJ1bmRsZShidW5kbGVOYW1lLCBsb2NhbGUsIGNsYXNzTG9hZGVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kcyB0aGUgbmFtZWQgcmVzb3VyY2UgYnVuZGxlIGZvciB0aGUgc3BlY2lmaWVkIHtAY29kZSBMb2NhbGV9IGFuZCB7QGNvZGUgQ2xhc3NMb2FkZXJ9LgorICAgICAqCisgICAgICogVGhlIHBhc3NlZCBiYXNlIG5hbWUgYW5kIHtAY29kZSBMb2NhbGV9IGFyZSB1c2VkIHRvIGNyZWF0ZSByZXNvdXJjZSBidW5kbGUgbmFtZXMuCisgICAgICogVGhlIGZpcnN0IG5hbWUgaXMgY3JlYXRlZCBieSBjb25jYXRlbmF0aW5nIHRoZSBiYXNlIG5hbWUgd2l0aCB0aGUgcmVzdWx0CisgICAgICogb2Yge0BsaW5rIExvY2FsZSN0b1N0cmluZygpfS4gRnJvbSB0aGlzIG5hbWUgYWxsIHBhcmVudCBidW5kbGUgbmFtZXMgYXJlCisgICAgICogZGVyaXZlZC4gVGhlbiB0aGUgc2FtZSB0aGluZyBpcyBkb25lIGZvciB0aGUgZGVmYXVsdCB7QGNvZGUgTG9jYWxlfS4gVGhpcyByZXN1bHRzCisgICAgICogaW4gYSBsaXN0IG9mIHBvc3NpYmxlIGJ1bmRsZSBuYW1lcy4KKyAgICAgKgorICAgICAqIDxzdHJvbmc+RXhhbXBsZTwvc3Ryb25nPiBGb3IgdGhlIGJhc2VuYW1lICJCYXNlTmFtZSIsIHRoZSB7QGNvZGUgTG9jYWxlfSBvZiB0aGUKKyAgICAgKiBHZXJtYW4gcGFydCBvZiBTd2l0emVybGFuZCAoZGVfQ0gpIGFuZCB0aGUgZGVmYXVsdCB7QGNvZGUgTG9jYWxlfSBlbl9VUyB0aGUgbGlzdAorICAgICAqIHdvdWxkIGxvb2sgc29tZXRoaW5nIGxpa2UgdGhpczoKKyAgICAgKgorICAgICAqIDxvbD4KKyAgICAgKiA8bGk+QmFzZU5hbWVfZGVfQ0g8L2xpPgorICAgICAqIDxsaT5CYXNlTmFtZV9kZTwvbGk+CisgICAgICogPGxpPkJhc2VuYW1lX2VuX1VTPC9saT4KKyAgICAgKiA8bGk+QmFzZW5hbWVfZW48L2xpPgorICAgICAqIDxsaT5CYXNlTmFtZTwvbGk+CisgICAgICogPC9vbD4KKyAgICAgKgorICAgICAqIFRoaXMgbGlzdCBhbHNvIHNob3dzIHRoZSBvcmRlciBpbiB3aGljaCB0aGUgYnVuZGxlcyB3aWxsIGJlIHNlYXJjaGVkIGZvciBhIHJlcXVlc3RlZAorICAgICAqIHJlc291cmNlIGluIHRoZSBHZXJtYW4gcGFydCBvZiBTd2l0emVybGFuZCAoZGVfQ0gpLgorICAgICAqCisgICAgICogQXMgYSBmaXJzdCBzdGVwLCB0aGlzIG1ldGhvZCB0cmllcyB0byBpbnN0YW50aWF0ZQorICAgICAqIGEge0Bjb2RlIFJlc291cmNlQnVuZGxlfSB3aXRoIHRoZSBuYW1lcyBwcm92aWRlZC4KKyAgICAgKiBJZiBzdWNoIGEgY2xhc3MgY2FuIGJlIGluc3RhbnRpYXRlZCBhbmQgaW5pdGlhbGl6ZWQsIGl0IGlzIHJldHVybmVkIGFuZAorICAgICAqIGFsbCB0aGUgcGFyZW50IGJ1bmRsZXMgYXJlIGluc3RhbnRpYXRlZCB0b28uIElmIG5vIHN1Y2ggY2xhc3MgY2FuIGJlCisgICAgICogZm91bmQgdGhpcyBtZXRob2QgdHJpZXMgdG8gbG9hZCBhIHtAY29kZSAucHJvcGVydGllc30gZmlsZSB3aXRoIHRoZSBuYW1lcyBieQorICAgICAqIHJlcGxhY2luZyBkb3RzIGluIHRoZSBiYXNlIG5hbWUgd2l0aCBhIHNsYXNoIGFuZCBieSBhcHBlbmRpbmcKKyAgICAgKiAie0Bjb2RlIC5wcm9wZXJ0aWVzfSIgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLiBJZiBzdWNoIGEgcmVzb3VyY2UgY2FuIGJlIGZvdW5kCisgICAgICogYnkgY2FsbGluZyB7QGxpbmsgQ2xhc3NMb2FkZXIjZ2V0UmVzb3VyY2UoU3RyaW5nKX0gaXQgaXMgdXNlZCB0bworICAgICAqIGluaXRpYWxpemUgYSB7QGxpbmsgUHJvcGVydHlSZXNvdXJjZUJ1bmRsZX0uIElmIHRoaXMgc3VjY2VlZHMsIGl0IHdpbGwKKyAgICAgKiBhbHNvIGxvYWQgdGhlIHBhcmVudHMgb2YgdGhpcyB7QGNvZGUgUmVzb3VyY2VCdW5kbGV9LgorICAgICAqCisgICAgICogRm9yIGNvbXBhdGliaWxpdHkgd2l0aCBvbGRlciBjb2RlLCB0aGUgYnVuZGxlIG5hbWUgaXNuJ3QgcmVxdWlyZWQgdG8gYmUKKyAgICAgKiBhIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lLiBJdCdzIGFsc28gcG9zc2libGUgdG8gZGlyZWN0bHkgcGFzcworICAgICAqIHRoZSBwYXRoIHRvIGEgcHJvcGVydGllcyBmaWxlICh3aXRob3V0IGEgZmlsZSBleHRlbnNpb24pLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1bmRsZU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSB7QGNvZGUgUmVzb3VyY2VCdW5kbGV9LgorICAgICAqIEBwYXJhbSBsb2NhbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgTG9jYWxlfS4KKyAgICAgKiBAcGFyYW0gbG9hZGVyCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIENsYXNzTG9hZGVyfSB0byB1c2UuCisgICAgICogQHJldHVybiB0aGUgcmVxdWVzdGVkIHtAY29kZSBSZXNvdXJjZUJ1bmRsZX0uCisgICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIFJlc291cmNlQnVuZGxlfSBjYW5ub3QgYmUgZm91bmQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBSZXNvdXJjZUJ1bmRsZSBnZXRCdW5kbGUoU3RyaW5nIGJ1bmRsZU5hbWUsIExvY2FsZSBsb2NhbGUsCisgICAgICAgICAgICBDbGFzc0xvYWRlciBsb2FkZXIpIHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24geworICAgICAgICBpZiAobG9hZGVyID09IG51bGwgfHwgYnVuZGxlTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBMb2NhbGUgZGVmYXVsdExvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgICAgIGlmICghY2FjaGVMb2NhbGUuZXF1YWxzKGRlZmF1bHRMb2NhbGUpKSB7CisgICAgICAgICAgICBjYWNoZS5jbGVhcigpOworICAgICAgICAgICAgY2FjaGVMb2NhbGUgPSBkZWZhdWx0TG9jYWxlOworICAgICAgICB9CisgICAgICAgIFJlc291cmNlQnVuZGxlIGJ1bmRsZSA9IG51bGw7CisgICAgICAgIGlmICghbG9jYWxlLmVxdWFscyhkZWZhdWx0TG9jYWxlKSkgeworICAgICAgICAgICAgYnVuZGxlID0gaGFuZGxlR2V0QnVuZGxlKGZhbHNlLCBidW5kbGVOYW1lLCBsb2NhbGUsIGxvYWRlcik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJ1bmRsZSA9PSBudWxsKSB7CisgICAgICAgICAgICBidW5kbGUgPSBoYW5kbGVHZXRCdW5kbGUodHJ1ZSwgYnVuZGxlTmFtZSwgZGVmYXVsdExvY2FsZSwgbG9hZGVyKTsKKyAgICAgICAgICAgIGlmIChidW5kbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbihidW5kbGVOYW1lICsgJ18nICsgbG9jYWxlLCAiIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ1bmRsZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gbWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uKFN0cmluZyBjbGFzc05hbWUsIFN0cmluZyBrZXkpIHsKKyAgICAgICAgU3RyaW5nIGRldGFpbCA9ICJDYW4ndCBmaW5kIHJlc291cmNlIGZvciBidW5kbGUgJyIgKyBjbGFzc05hbWUgKyAiJywga2V5ICciICsga2V5ICsgIiciOworICAgICAgICB0aHJvdyBuZXcgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uKGRldGFpbCwgY2xhc3NOYW1lLCBrZXkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIHRoZSBuYW1lZCByZXNvdXJjZSBidW5kbGUgZm9yIHRoZSBzcGVjaWZpZWQgYmFzZSBuYW1lIGFuZCBjb250cm9sLgorICAgICAqCisgICAgICogQHBhcmFtIGJhc2VOYW1lCisgICAgICogICAgICAgICAgICB0aGUgYmFzZSBuYW1lIG9mIGEgcmVzb3VyY2UgYnVuZGxlCisgICAgICogQHBhcmFtIGNvbnRyb2wKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb250cm9sIHRoYXQgY29udHJvbCB0aGUgYWNjZXNzIHNlcXVlbmNlCisgICAgICogQHJldHVybiB0aGUgbmFtZWQgcmVzb3VyY2UgYnVuZGxlCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBSZXNvdXJjZUJ1bmRsZSBnZXRCdW5kbGUoU3RyaW5nIGJhc2VOYW1lLCBSZXNvdXJjZUJ1bmRsZS5Db250cm9sIGNvbnRyb2wpIHsKKyAgICAgICAgcmV0dXJuIGdldEJ1bmRsZShiYXNlTmFtZSwgTG9jYWxlLmdldERlZmF1bHQoKSwgZ2V0TG9hZGVyKCksIGNvbnRyb2wpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIHRoZSBuYW1lZCByZXNvdXJjZSBidW5kbGUgZm9yIHRoZSBzcGVjaWZpZWQgYmFzZSBuYW1lIGFuZCBjb250cm9sLgorICAgICAqCisgICAgICogQHBhcmFtIGJhc2VOYW1lCisgICAgICogICAgICAgICAgICB0aGUgYmFzZSBuYW1lIG9mIGEgcmVzb3VyY2UgYnVuZGxlCisgICAgICogQHBhcmFtIHRhcmdldExvY2FsZQorICAgICAqICAgICAgICAgICAgdGhlIHRhcmdldCBsb2NhbGUgb2YgdGhlIHJlc291cmNlIGJ1bmRsZQorICAgICAqIEBwYXJhbSBjb250cm9sCisgICAgICogICAgICAgICAgICB0aGUgY29udHJvbCB0aGF0IGNvbnRyb2wgdGhlIGFjY2VzcyBzZXF1ZW5jZQorICAgICAqIEByZXR1cm4gdGhlIG5hbWVkIHJlc291cmNlIGJ1bmRsZQorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUmVzb3VyY2VCdW5kbGUgZ2V0QnVuZGxlKFN0cmluZyBiYXNlTmFtZSwKKyAgICAgICAgICAgIExvY2FsZSB0YXJnZXRMb2NhbGUsIFJlc291cmNlQnVuZGxlLkNvbnRyb2wgY29udHJvbCkgeworICAgICAgICByZXR1cm4gZ2V0QnVuZGxlKGJhc2VOYW1lLCB0YXJnZXRMb2NhbGUsIGdldExvYWRlcigpLCBjb250cm9sKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBDbGFzc0xvYWRlciBnZXRMb2FkZXIoKSB7CisgICAgICAgIENsYXNzTG9hZGVyIGNsID0gUmVzb3VyY2VCdW5kbGUuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgaWYgKGNsID09IG51bGwpIHsKKyAgICAgICAgICAgIGNsID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2w7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgdGhlIG5hbWVkIHJlc291cmNlIGJ1bmRsZSBmb3IgdGhlIHNwZWNpZmllZCBiYXNlIG5hbWUgYW5kIGNvbnRyb2wuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYmFzZU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBiYXNlIG5hbWUgb2YgYSByZXNvdXJjZSBidW5kbGUKKyAgICAgKiBAcGFyYW0gdGFyZ2V0TG9jYWxlCisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IGxvY2FsZSBvZiB0aGUgcmVzb3VyY2UgYnVuZGxlCisgICAgICogQHBhcmFtIGxvYWRlcgorICAgICAqICAgICAgICAgICAgdGhlIGNsYXNzIGxvYWRlciB0byBsb2FkIHJlc291cmNlCisgICAgICogQHBhcmFtIGNvbnRyb2wKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb250cm9sIHRoYXQgY29udHJvbCB0aGUgYWNjZXNzIHNlcXVlbmNlCisgICAgICogQHJldHVybiB0aGUgbmFtZWQgcmVzb3VyY2UgYnVuZGxlCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBSZXNvdXJjZUJ1bmRsZSBnZXRCdW5kbGUoU3RyaW5nIGJhc2VOYW1lLAorICAgICAgICAgICAgTG9jYWxlIHRhcmdldExvY2FsZSwgQ2xhc3NMb2FkZXIgbG9hZGVyLAorICAgICAgICAgICAgUmVzb3VyY2VCdW5kbGUuQ29udHJvbCBjb250cm9sKSB7CisgICAgICAgIGJvb2xlYW4gZXhwaXJlZCA9IGZhbHNlOworICAgICAgICBTdHJpbmcgYnVuZGxlTmFtZSA9IGNvbnRyb2wudG9CdW5kbGVOYW1lKGJhc2VOYW1lLCB0YXJnZXRMb2NhbGUpOworICAgICAgICBPYmplY3QgY2FjaGVLZXkgPSBsb2FkZXIgIT0gbnVsbCA/IGxvYWRlciA6ICJudWxsIjsKKyAgICAgICAgSGFzaHRhYmxlPFN0cmluZywgUmVzb3VyY2VCdW5kbGU+IGxvYWRlckNhY2hlID0gZ2V0TG9hZGVyQ2FjaGUoY2FjaGVLZXkpOworICAgICAgICBSZXNvdXJjZUJ1bmRsZSByZXN1bHQgPSBsb2FkZXJDYWNoZS5nZXQoYnVuZGxlTmFtZSk7CisgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgeworICAgICAgICAgICAgbG9uZyB0aW1lID0gY29udHJvbC5nZXRUaW1lVG9MaXZlKGJhc2VOYW1lLCB0YXJnZXRMb2NhbGUpOworICAgICAgICAgICAgaWYgKHRpbWUgPT0gMCB8fCB0aW1lID09IENvbnRyb2wuVFRMX05PX0VYUElSQVRJT05fQ09OVFJPTAorICAgICAgICAgICAgICAgICAgICB8fCB0aW1lICsgcmVzdWx0Lmxhc3RMb2FkVGltZSA8IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKSB7CisgICAgICAgICAgICAgICAgaWYgKE1JU1NJTkcgPT0gcmVzdWx0KSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24obnVsbCwgYnVuZGxlTmFtZSArICdfJworICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdGFyZ2V0TG9jYWxlLCBFTVBUWV9TVFJJTkcpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgZXhwaXJlZCA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgLy8gdHJ5IHRvIGxvYWQKKyAgICAgICAgUmVzb3VyY2VCdW5kbGUgcmV0ID0gcHJvY2Vzc0dldEJ1bmRsZShiYXNlTmFtZSwgdGFyZ2V0TG9jYWxlLCBsb2FkZXIsCisgICAgICAgICAgICAgICAgY29udHJvbCwgZXhwaXJlZCwgcmVzdWx0KTsKKworICAgICAgICBpZiAocmV0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxvYWRlckNhY2hlLnB1dChidW5kbGVOYW1lLCByZXQpOworICAgICAgICAgICAgcmV0Lmxhc3RMb2FkVGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICAgICAgcmV0dXJuIHJldDsKKyAgICAgICAgfQorICAgICAgICBsb2FkZXJDYWNoZS5wdXQoYnVuZGxlTmFtZSwgTUlTU0lORyk7CisgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24obnVsbCwgYnVuZGxlTmFtZSArICdfJyArIHRhcmdldExvY2FsZSwgRU1QVFlfU1RSSU5HKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBSZXNvdXJjZUJ1bmRsZSBwcm9jZXNzR2V0QnVuZGxlKFN0cmluZyBiYXNlTmFtZSwKKyAgICAgICAgICAgIExvY2FsZSB0YXJnZXRMb2NhbGUsIENsYXNzTG9hZGVyIGxvYWRlciwKKyAgICAgICAgICAgIFJlc291cmNlQnVuZGxlLkNvbnRyb2wgY29udHJvbCwgYm9vbGVhbiBleHBpcmVkLAorICAgICAgICAgICAgUmVzb3VyY2VCdW5kbGUgcmVzdWx0KSB7CisgICAgICAgIExpc3Q8TG9jYWxlPiBsb2NhbGVzID0gY29udHJvbC5nZXRDYW5kaWRhdGVMb2NhbGVzKGJhc2VOYW1lLCB0YXJnZXRMb2NhbGUpOworICAgICAgICBpZiAobG9jYWxlcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgTGlzdDxTdHJpbmc+IGZvcm1hdHMgPSBjb250cm9sLmdldEZvcm1hdHMoYmFzZU5hbWUpOworICAgICAgICBpZiAoQ29udHJvbC5GT1JNQVRfQ0xBU1MgPT0gZm9ybWF0cworICAgICAgICAgICAgICAgIHx8IENvbnRyb2wuRk9STUFUX1BST1BFUlRJRVMgPT0gZm9ybWF0cworICAgICAgICAgICAgICAgIHx8IENvbnRyb2wuRk9STUFUX0RFRkFVTFQgPT0gZm9ybWF0cykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIFJlc291cmNlQnVuZGxlIHJldCA9IG51bGw7CisgICAgICAgIFJlc291cmNlQnVuZGxlIGN1cnJlbnRCdW5kbGUgPSBudWxsOworICAgICAgICBSZXNvdXJjZUJ1bmRsZSBidW5kbGUgPSBudWxsOworICAgICAgICBmb3IgKExvY2FsZSBsb2NhbGUgOiBsb2NhbGVzKSB7CisgICAgICAgICAgICBmb3IgKFN0cmluZyBmb3JtYXQgOiBmb3JtYXRzKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGV4cGlyZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1bmRsZSA9IGNvbnRyb2wubmV3QnVuZGxlKGJhc2VOYW1lLCBsb2NhbGUsIGZvcm1hdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVyLCBjb250cm9sLm5lZWRzUmVsb2FkKGJhc2VOYW1lLCBsb2NhbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0LCBsb2FkZXIsIHJlc3VsdCwgU3lzdGVtCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY3VycmVudFRpbWVNaWxsaXMoKSkpOworCisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1bmRsZSA9IGNvbnRyb2wubmV3QnVuZGxlKGJhc2VOYW1lLCBsb2NhbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQsIGxvYWRlciwgZmFsc2UpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkbyBub3RoaW5nCisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gZG8gbm90aGluZworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAvLyBkbyBub3RoaW5nCisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAvLyBkbyBub3RoaW5nCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChidW5kbGUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudEJ1bmRsZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50QnVuZGxlLnNldFBhcmVudChidW5kbGUpOworICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudEJ1bmRsZSA9IGJ1bmRsZTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IGJ1bmRsZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50QnVuZGxlID0gcmV0OworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChidW5kbGUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoKHJldCA9PSBudWxsKQorICAgICAgICAgICAgICAgIHx8IChMb2NhbGUuUk9PVC5lcXVhbHMocmV0LmdldExvY2FsZSgpKSAmJiAoIShsb2NhbGVzLnNpemUoKSA9PSAxICYmIGxvY2FsZXMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb250YWlucyhMb2NhbGUuUk9PVCkpKSkpIHsKKyAgICAgICAgICAgIExvY2FsZSBuZXh0TG9jYWxlID0gY29udHJvbC5nZXRGYWxsYmFja0xvY2FsZShiYXNlTmFtZSwgdGFyZ2V0TG9jYWxlKTsKKyAgICAgICAgICAgIGlmIChuZXh0TG9jYWxlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXQgPSBwcm9jZXNzR2V0QnVuZGxlKGJhc2VOYW1lLCBuZXh0TG9jYWxlLCBsb2FkZXIsIGNvbnRyb2wsCisgICAgICAgICAgICAgICAgICAgICAgICBleHBpcmVkLCByZXN1bHQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lcyBvZiB0aGUgcmVzb3VyY2VzIGNvbnRhaW5lZCBpbiB0aGlzIHtAY29kZSBSZXNvdXJjZUJ1bmRsZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBFbnVtZXJhdGlvbn0gb2YgdGhlIHJlc291cmNlIG5hbWVzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBFbnVtZXJhdGlvbjxTdHJpbmc+IGdldEtleXMoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHtAY29kZSBMb2NhbGV9IG9mIHRoaXMge0Bjb2RlIFJlc291cmNlQnVuZGxlfS4gSW4gY2FzZSBhIGJ1bmRsZSB3YXMgbm90CisgICAgICogZm91bmQgZm9yIHRoZSByZXF1ZXN0ZWQge0Bjb2RlIExvY2FsZX0sIHRoaXMgd2lsbCByZXR1cm4gdGhlIGFjdHVhbCB7QGNvZGUgTG9jYWxlfSBvZgorICAgICAqIHRoaXMgcmVzb3VyY2UgYnVuZGxlIHRoYXQgd2FzIGZvdW5kIGFmdGVyIGRvaW5nIGEgZmFsbGJhY2suCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgTG9jYWxlfSBvZiB0aGlzIHtAY29kZSBSZXNvdXJjZUJ1bmRsZX0uCisgICAgICovCisgICAgcHVibGljIExvY2FsZSBnZXRMb2NhbGUoKSB7CisgICAgICAgIHJldHVybiBsb2NhbGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZWQgcmVzb3VyY2UgZnJvbSB0aGlzIHtAY29kZSBSZXNvdXJjZUJ1bmRsZX0uIElmIHRoZSByZXNvdXJjZQorICAgICAqIGNhbm5vdCBiZSBmb3VuZCBpbiB0aGlzIGJ1bmRsZSwgaXQgZmFsbHMgYmFjayB0byB0aGUgcGFyZW50IGJ1bmRsZSAoaWYKKyAgICAgKiBpdCdzIG5vdCBudWxsKSBieSBjYWxsaW5nIHRoZSB7QGxpbmsgI2hhbmRsZUdldE9iamVjdH0gbWV0aG9kLiBJZiB0aGUgcmVzb3VyY2Ugc3RpbGwKKyAgICAgKiBjYW4ndCBiZSBmb3VuZCBpdCB0aHJvd3MgYSB7QGNvZGUgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9ufS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZS4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXNvdXJjZSBvYmplY3QuCisgICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgcmVzb3VyY2UgaXMgbm90IGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBPYmplY3QgZ2V0T2JqZWN0KFN0cmluZyBrZXkpIHsKKyAgICAgICAgUmVzb3VyY2VCdW5kbGUgbGFzdCwgdGhlUGFyZW50ID0gdGhpczsKKyAgICAgICAgZG8geworICAgICAgICAgICAgT2JqZWN0IHJlc3VsdCA9IHRoZVBhcmVudC5oYW5kbGVHZXRPYmplY3Qoa2V5KTsKKyAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsYXN0ID0gdGhlUGFyZW50OworICAgICAgICAgICAgdGhlUGFyZW50ID0gdGhlUGFyZW50LnBhcmVudDsKKyAgICAgICAgfSB3aGlsZSAodGhlUGFyZW50ICE9IG51bGwpOworICAgICAgICB0aHJvdyBtaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24obGFzdC5nZXRDbGFzcygpLmdldE5hbWUoKSwga2V5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lZCBzdHJpbmcgcmVzb3VyY2UgZnJvbSB0aGlzIHtAY29kZSBSZXNvdXJjZUJ1bmRsZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcmVzb3VyY2UuCisgICAgICogQHJldHVybiB0aGUgcmVzb3VyY2Ugc3RyaW5nLgorICAgICAqIEB0aHJvd3MgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHJlc291cmNlIGlzIG5vdCBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSByZXNvdXJjZSBmb3VuZCBpcyBub3QgYSBzdHJpbmcuCisgICAgICogQHNlZSAjZ2V0T2JqZWN0KFN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldFN0cmluZyhTdHJpbmcga2V5KSB7CisgICAgICAgIHJldHVybiAoU3RyaW5nKSBnZXRPYmplY3Qoa2V5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lZCByZXNvdXJjZSBmcm9tIHRoaXMge0Bjb2RlIFJlc291cmNlQnVuZGxlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZS4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXNvdXJjZSBzdHJpbmcgYXJyYXkuCisgICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgcmVzb3VyY2UgaXMgbm90IGZvdW5kLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHJlc291cmNlIGZvdW5kIGlzIG5vdCBhbiBhcnJheSBvZiBzdHJpbmdzLgorICAgICAqIEBzZWUgI2dldE9iamVjdChTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZ1tdIGdldFN0cmluZ0FycmF5KFN0cmluZyBrZXkpIHsKKyAgICAgICAgcmV0dXJuIChTdHJpbmdbXSkgZ2V0T2JqZWN0KGtleSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgUmVzb3VyY2VCdW5kbGUgaGFuZGxlR2V0QnVuZGxlKGJvb2xlYW4gbG9hZEJhc2UsIFN0cmluZyBiYXNlLCBMb2NhbGUgbG9jYWxlLAorICAgICAgICAgICAgQ2xhc3NMb2FkZXIgbG9hZGVyKSB7CisgICAgICAgIFN0cmluZyBsb2NhbGVOYW1lID0gbG9jYWxlLnRvU3RyaW5nKCk7CisgICAgICAgIFN0cmluZyBidW5kbGVOYW1lID0gbG9jYWxlTmFtZS5pc0VtcHR5KCkKKyAgICAgICAgICAgICAgICA/IGJhc2UKKyAgICAgICAgICAgICAgICA6IChiYXNlICsgIl8iICsgbG9jYWxlTmFtZSk7CisgICAgICAgIE9iamVjdCBjYWNoZUtleSA9IGxvYWRlciAhPSBudWxsID8gbG9hZGVyIDogIm51bGwiOworICAgICAgICBIYXNodGFibGU8U3RyaW5nLCBSZXNvdXJjZUJ1bmRsZT4gbG9hZGVyQ2FjaGUgPSBnZXRMb2FkZXJDYWNoZShjYWNoZUtleSk7CisgICAgICAgIFJlc291cmNlQnVuZGxlIGNhY2hlZCA9IGxvYWRlckNhY2hlLmdldChidW5kbGVOYW1lKTsKKyAgICAgICAgaWYgKGNhY2hlZCAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoY2FjaGVkID09IE1JU1NJTkdCQVNFKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGNhY2hlZCA9PSBNSVNTSU5HKSB7CisgICAgICAgICAgICAgICAgaWYgKCFsb2FkQmFzZSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgTG9jYWxlIG5ld0xvY2FsZSA9IHN0cmlwKGxvY2FsZSk7CisgICAgICAgICAgICAgICAgaWYgKG5ld0xvY2FsZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlR2V0QnVuZGxlKGxvYWRCYXNlLCBiYXNlLCBuZXdMb2NhbGUsIGxvYWRlcik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gY2FjaGVkOworICAgICAgICB9CisKKyAgICAgICAgUmVzb3VyY2VCdW5kbGUgYnVuZGxlID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENsYXNzPD8+IGJ1bmRsZUNsYXNzID0gQ2xhc3MuZm9yTmFtZShidW5kbGVOYW1lLCB0cnVlLCBsb2FkZXIpOworICAgICAgICAgICAgaWYgKFJlc291cmNlQnVuZGxlLmNsYXNzLmlzQXNzaWduYWJsZUZyb20oYnVuZGxlQ2xhc3MpKSB7CisgICAgICAgICAgICAgICAgYnVuZGxlID0gKFJlc291cmNlQnVuZGxlKSBidW5kbGVDbGFzcy5uZXdJbnN0YW5jZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChMaW5rYWdlRXJyb3IgaWdub3JlZCkgeworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICB9CisKKyAgICAgICAgaWYgKGJ1bmRsZSAhPSBudWxsKSB7CisgICAgICAgICAgICBidW5kbGUuc2V0TG9jYWxlKGxvY2FsZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBTdHJpbmcgZmlsZU5hbWUgPSBidW5kbGVOYW1lLnJlcGxhY2UoJy4nLCAnLycpICsgIi5wcm9wZXJ0aWVzIjsKKyAgICAgICAgICAgIElucHV0U3RyZWFtIHN0cmVhbSA9IGxvYWRlciAhPSBudWxsCisgICAgICAgICAgICAgICAgICAgID8gbG9hZGVyLmdldFJlc291cmNlQXNTdHJlYW0oZmlsZU5hbWUpCisgICAgICAgICAgICAgICAgICAgIDogQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtUmVzb3VyY2VBc1N0cmVhbShmaWxlTmFtZSk7CisgICAgICAgICAgICBpZiAoc3RyZWFtICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBidW5kbGUgPSBuZXcgUHJvcGVydHlSZXNvdXJjZUJ1bmRsZShuZXcgSW5wdXRTdHJlYW1SZWFkZXIoc3RyZWFtLCBVVEZfOCkpOworICAgICAgICAgICAgICAgICAgICBidW5kbGUuc2V0TG9jYWxlKGxvY2FsZSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIElvVXRpbHMuY2xvc2VRdWlldGx5KHN0cmVhbSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgTG9jYWxlIHN0cmlwcGVkTG9jYWxlID0gc3RyaXAobG9jYWxlKTsKKyAgICAgICAgaWYgKGJ1bmRsZSAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoc3RyaXBwZWRMb2NhbGUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIFJlc291cmNlQnVuZGxlIHBhcmVudCA9IGhhbmRsZUdldEJ1bmRsZShsb2FkQmFzZSwgYmFzZSwgc3RyaXBwZWRMb2NhbGUsIGxvYWRlcik7CisgICAgICAgICAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGJ1bmRsZS5zZXRQYXJlbnQocGFyZW50KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsb2FkZXJDYWNoZS5wdXQoYnVuZGxlTmFtZSwgYnVuZGxlKTsKKyAgICAgICAgICAgIHJldHVybiBidW5kbGU7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc3RyaXBwZWRMb2NhbGUgIT0gbnVsbCAmJiAobG9hZEJhc2UgfHwgIXN0cmlwcGVkTG9jYWxlLnRvU3RyaW5nKCkuaXNFbXB0eSgpKSkgeworICAgICAgICAgICAgYnVuZGxlID0gaGFuZGxlR2V0QnVuZGxlKGxvYWRCYXNlLCBiYXNlLCBzdHJpcHBlZExvY2FsZSwgbG9hZGVyKTsKKyAgICAgICAgICAgIGlmIChidW5kbGUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGxvYWRlckNhY2hlLnB1dChidW5kbGVOYW1lLCBidW5kbGUpOworICAgICAgICAgICAgICAgIHJldHVybiBidW5kbGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgbG9hZGVyQ2FjaGUucHV0KGJ1bmRsZU5hbWUsIGxvYWRCYXNlID8gTUlTU0lOR0JBU0UgOiBNSVNTSU5HKTsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgSGFzaHRhYmxlPFN0cmluZywgUmVzb3VyY2VCdW5kbGU+IGdldExvYWRlckNhY2hlKE9iamVjdCBjYWNoZUtleSkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGNhY2hlKSB7CisgICAgICAgICAgICBIYXNodGFibGU8U3RyaW5nLCBSZXNvdXJjZUJ1bmRsZT4gbG9hZGVyQ2FjaGUgPSBjYWNoZS5nZXQoY2FjaGVLZXkpOworICAgICAgICAgICAgaWYgKGxvYWRlckNhY2hlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBsb2FkZXJDYWNoZSA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBSZXNvdXJjZUJ1bmRsZT4oKTsKKyAgICAgICAgICAgICAgICBjYWNoZS5wdXQoY2FjaGVLZXksIGxvYWRlckNhY2hlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBsb2FkZXJDYWNoZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWVkIHJlc291cmNlIGZyb20gdGhpcyB7QGNvZGUgUmVzb3VyY2VCdW5kbGV9LCBvciBudWxsIGlmIHRoZQorICAgICAqIHJlc291cmNlIGlzIG5vdCBmb3VuZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZS4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXNvdXJjZSBvYmplY3QuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IE9iamVjdCBoYW5kbGVHZXRPYmplY3QoU3RyaW5nIGtleSk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwYXJlbnQgcmVzb3VyY2UgYnVuZGxlIG9mIHRoaXMge0Bjb2RlIFJlc291cmNlQnVuZGxlfS4gVGhlIHBhcmVudCBpcworICAgICAqIHNlYXJjaGVkIGZvciByZXNvdXJjZXMgd2hpY2ggYXJlIG5vdCBmb3VuZCBpbiB0aGlzIHtAY29kZSBSZXNvdXJjZUJ1bmRsZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVuZGxlCisgICAgICogICAgICAgICAgICB0aGUgcGFyZW50IHtAY29kZSBSZXNvdXJjZUJ1bmRsZX0uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0UGFyZW50KFJlc291cmNlQnVuZGxlIGJ1bmRsZSkgeworICAgICAgICBwYXJlbnQgPSBidW5kbGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGxvY2FsZSB3aXRoIHRoZSBtb3N0LXNwZWNpZmljIGZpZWxkIHJlbW92ZWQsIG9yIG51bGwgaWYgdGhpcworICAgICAqIGxvY2FsZSBoYWQgYW4gZW1wdHkgbGFuZ3VhZ2UsIGNvdW50cnkgYW5kIHZhcmlhbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgTG9jYWxlIHN0cmlwKExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgU3RyaW5nIGxhbmd1YWdlID0gbG9jYWxlLmdldExhbmd1YWdlKCk7CisgICAgICAgIFN0cmluZyBjb3VudHJ5ID0gbG9jYWxlLmdldENvdW50cnkoKTsKKyAgICAgICAgU3RyaW5nIHZhcmlhbnQgPSBsb2NhbGUuZ2V0VmFyaWFudCgpOworICAgICAgICBpZiAoIXZhcmlhbnQuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB2YXJpYW50ID0gIiI7CisgICAgICAgIH0gZWxzZSBpZiAoIWNvdW50cnkuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBjb3VudHJ5ID0gIiI7CisgICAgICAgIH0gZWxzZSBpZiAoIWxhbmd1YWdlLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgbGFuZ3VhZ2UgPSAiIjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgTG9jYWxlKGxhbmd1YWdlLCBjb3VudHJ5LCB2YXJpYW50KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgdGhpcy5sb2NhbGUgPSBsb2NhbGU7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGNsZWFyQ2FjaGUoKSB7CisgICAgICAgIGNhY2hlLnJlbW92ZShDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgY2xlYXJDYWNoZShDbGFzc0xvYWRlciBsb2FkZXIpIHsKKyAgICAgICAgaWYgKGxvYWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBjYWNoZS5yZW1vdmUobG9hZGVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0tleShTdHJpbmcga2V5KSB7CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGtleVNldCgpLmNvbnRhaW5zKGtleSk7CisgICAgfQorCisgICAgcHVibGljIFNldDxTdHJpbmc+IGtleVNldCgpIHsKKyAgICAgICAgU2V0PFN0cmluZz4gcmV0ID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgICBFbnVtZXJhdGlvbjxTdHJpbmc+IGtleXMgPSBnZXRLZXlzKCk7CisgICAgICAgIHdoaWxlIChrZXlzLmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICByZXQuYWRkKGtleXMubmV4dEVsZW1lbnQoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgU2V0PFN0cmluZz4gaGFuZGxlS2V5U2V0KCkgeworICAgICAgICBTZXQ8U3RyaW5nPiBzZXQgPSBrZXlTZXQoKTsKKyAgICAgICAgU2V0PFN0cmluZz4gcmV0ID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgICBmb3IgKFN0cmluZyBrZXkgOiBzZXQpIHsKKyAgICAgICAgICAgIGlmIChoYW5kbGVHZXRPYmplY3Qoa2V5KSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0LmFkZChrZXkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTm9GYWxsYmFja0NvbnRyb2wgZXh0ZW5kcyBDb250cm9sIHsKKworICAgICAgICBzdGF0aWMgZmluYWwgQ29udHJvbCBOT0ZBTExCQUNLX0ZPUk1BVF9QUk9QRVJUSUVTX0NPTlRST0wgPSBuZXcgTm9GYWxsYmFja0NvbnRyb2woCisgICAgICAgICAgICAgICAgSkFWQVBST1BFUlRJRVMpOworCisgICAgICAgIHN0YXRpYyBmaW5hbCBDb250cm9sIE5PRkFMTEJBQ0tfRk9STUFUX0NMQVNTX0NPTlRST0wgPSBuZXcgTm9GYWxsYmFja0NvbnRyb2woCisgICAgICAgICAgICAgICAgSkFWQUNMQVNTKTsKKworICAgICAgICBzdGF0aWMgZmluYWwgQ29udHJvbCBOT0ZBTExCQUNLX0ZPUk1BVF9ERUZBVUxUX0NPTlRST0wgPSBuZXcgTm9GYWxsYmFja0NvbnRyb2woCisgICAgICAgICAgICAgICAgbGlzdERlZmF1bHQpOworCisgICAgICAgIHB1YmxpYyBOb0ZhbGxiYWNrQ29udHJvbChTdHJpbmcgZm9ybWF0KSB7CisgICAgICAgICAgICBsaXN0Q2xhc3MgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgICAgIGxpc3RDbGFzcy5hZGQoZm9ybWF0KTsKKyAgICAgICAgICAgIHN1cGVyLmZvcm1hdCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QobGlzdENsYXNzKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBOb0ZhbGxiYWNrQ29udHJvbChMaXN0PFN0cmluZz4gbGlzdCkgeworICAgICAgICAgICAgc3VwZXIuZm9ybWF0ID0gbGlzdDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgTG9jYWxlIGdldEZhbGxiYWNrTG9jYWxlKFN0cmluZyBiYXNlTmFtZSwgTG9jYWxlIGxvY2FsZSkgeworICAgICAgICAgICAgaWYgKGJhc2VOYW1lID09IG51bGwgfHwgbG9jYWxlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgU2ltcGxlQ29udHJvbCBleHRlbmRzIENvbnRyb2wgeworICAgICAgICBwdWJsaWMgU2ltcGxlQ29udHJvbChTdHJpbmcgZm9ybWF0KSB7CisgICAgICAgICAgICBsaXN0Q2xhc3MgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgICAgIGxpc3RDbGFzcy5hZGQoZm9ybWF0KTsKKyAgICAgICAgICAgIHN1cGVyLmZvcm1hdCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QobGlzdENsYXNzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc291cmNlQnVuZGxlLkNvbnRyb2wgaXMgYSBzdGF0aWMgdXRpbGl0eSBjbGFzcyBkZWZpbmVzIFJlc291cmNlQnVuZGxlCisgICAgICogbG9hZCBhY2Nlc3MgbWV0aG9kcywgaXRzIGRlZmF1bHQgYWNjZXNzIG9yZGVyIGlzIGFzIHRoZSBzYW1lIGFzIGJlZm9yZS4KKyAgICAgKiBIb3dldmVyIHVzZXJzIGNhbiBpbXBsZW1lbnQgdGhlaXIgb3duIGNvbnRyb2wuCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBDb250cm9sIHsKKyAgICAgICAgc3RhdGljIExpc3Q8U3RyaW5nPiBsaXN0RGVmYXVsdCA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworCisgICAgICAgIHN0YXRpYyBMaXN0PFN0cmluZz4gbGlzdENsYXNzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisKKyAgICAgICAgc3RhdGljIExpc3Q8U3RyaW5nPiBsaXN0UHJvcGVydGllcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworCisgICAgICAgIHN0YXRpYyBTdHJpbmcgSkFWQUNMQVNTID0gImphdmEuY2xhc3MiOworCisgICAgICAgIHN0YXRpYyBTdHJpbmcgSkFWQVBST1BFUlRJRVMgPSAiamF2YS5wcm9wZXJ0aWVzIjsKKworICAgICAgICBzdGF0aWMgeworICAgICAgICAgICAgbGlzdERlZmF1bHQuYWRkKEpBVkFDTEFTUyk7CisgICAgICAgICAgICBsaXN0RGVmYXVsdC5hZGQoSkFWQVBST1BFUlRJRVMpOworICAgICAgICAgICAgbGlzdENsYXNzLmFkZChKQVZBQ0xBU1MpOworICAgICAgICAgICAgbGlzdFByb3BlcnRpZXMuYWRkKEpBVkFQUk9QRVJUSUVTKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBhIGxpc3QgZGVmaW5lcyBkZWZhdWx0IGZvcm1hdAorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBMaXN0PFN0cmluZz4gRk9STUFUX0RFRkFVTFQgPSBDb2xsZWN0aW9ucworICAgICAgICAgICAgICAgIC51bm1vZGlmaWFibGVMaXN0KGxpc3REZWZhdWx0KTsKKworICAgICAgICAvKioKKyAgICAgICAgICogYSBsaXN0IGRlZmluZXMgamF2YSBjbGFzcyBmb3JtYXQKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTGlzdDxTdHJpbmc+IEZPUk1BVF9DTEFTUyA9IENvbGxlY3Rpb25zCisgICAgICAgICAgICAgICAgLnVubW9kaWZpYWJsZUxpc3QobGlzdENsYXNzKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogYSBsaXN0IGRlZmluZXMgcHJvcGVydHkgZm9ybWF0CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIExpc3Q8U3RyaW5nPiBGT1JNQVRfUFJPUEVSVElFUyA9IENvbGxlY3Rpb25zCisgICAgICAgICAgICAgICAgLnVubW9kaWZpYWJsZUxpc3QobGlzdFByb3BlcnRpZXMpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBhIGNvbnN0YW50IHRoYXQgaW5kaWNhdGVzIGNhY2hlIHdpbGwgbm90IGJlIHVzZWQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgVFRMX0RPTlRfQ0FDSEUgPSAtMUw7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIGEgY29uc3RhbnQgdGhhdCBpbmRpY2F0ZXMgY2FjaGUgd2lsbCBub3QgYmUgZXhwaXJlZC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBUVExfTk9fRVhQSVJBVElPTl9DT05UUk9MID0gLTJMOworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbnRyb2wgRk9STUFUX1BST1BFUlRJRVNfQ09OVFJPTCA9IG5ldyBTaW1wbGVDb250cm9sKAorICAgICAgICAgICAgICAgIEpBVkFQUk9QRVJUSUVTKTsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDb250cm9sIEZPUk1BVF9DTEFTU19DT05UUk9MID0gbmV3IFNpbXBsZUNvbnRyb2woCisgICAgICAgICAgICAgICAgSkFWQUNMQVNTKTsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDb250cm9sIEZPUk1BVF9ERUZBVUxUX0NPTlRST0wgPSBuZXcgQ29udHJvbCgpOworCisgICAgICAgIExpc3Q8U3RyaW5nPiBmb3JtYXQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIGRlZmF1bHQgY29uc3RydWN0b3IKKyAgICAgICAgICoKKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBDb250cm9sKCkgeworICAgICAgICAgICAgbGlzdENsYXNzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgICAgICBsaXN0Q2xhc3MuYWRkKEpBVkFDTEFTUyk7CisgICAgICAgICAgICBsaXN0Q2xhc3MuYWRkKEpBVkFQUk9QRVJUSUVTKTsKKyAgICAgICAgICAgIGZvcm1hdCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QobGlzdENsYXNzKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGEgY29udHJvbCBhY2NvcmRpbmcgdG8ge0Bjb2RlIGZvcm1hdHN9LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBDb250cm9sIGdldENvbnRyb2woTGlzdDxTdHJpbmc+IGZvcm1hdHMpIHsKKyAgICAgICAgICAgIHN3aXRjaCAoZm9ybWF0cy5zaXplKCkpIHsKKyAgICAgICAgICAgIGNhc2UgMToKKyAgICAgICAgICAgICAgICBpZiAoZm9ybWF0cy5jb250YWlucyhKQVZBQ0xBU1MpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBGT1JNQVRfQ0xBU1NfQ09OVFJPTDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGZvcm1hdHMuY29udGFpbnMoSkFWQVBST1BFUlRJRVMpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBGT1JNQVRfUFJPUEVSVElFU19DT05UUk9MOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgMjoKKyAgICAgICAgICAgICAgICBpZiAoZm9ybWF0cy5lcXVhbHMoRk9STUFUX0RFRkFVTFQpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBGT1JNQVRfREVGQVVMVF9DT05UUk9MOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGEgY29udHJvbCBhY2NvcmRpbmcgdG8ge0Bjb2RlIGZvcm1hdHN9IHdob3NlIGZhbGxiYWNrCisgICAgICAgICAqIGxvY2FsZSBpcyBudWxsLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBDb250cm9sIGdldE5vRmFsbGJhY2tDb250cm9sKExpc3Q8U3RyaW5nPiBmb3JtYXRzKSB7CisgICAgICAgICAgICBzd2l0Y2ggKGZvcm1hdHMuc2l6ZSgpKSB7CisgICAgICAgICAgICBjYXNlIDE6CisgICAgICAgICAgICAgICAgaWYgKGZvcm1hdHMuY29udGFpbnMoSkFWQUNMQVNTKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gTm9GYWxsYmFja0NvbnRyb2wuTk9GQUxMQkFDS19GT1JNQVRfQ0xBU1NfQ09OVFJPTDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGZvcm1hdHMuY29udGFpbnMoSkFWQVBST1BFUlRJRVMpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBOb0ZhbGxiYWNrQ29udHJvbC5OT0ZBTExCQUNLX0ZPUk1BVF9QUk9QRVJUSUVTX0NPTlRST0w7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAyOgorICAgICAgICAgICAgICAgIGlmIChmb3JtYXRzLmVxdWFscyhGT1JNQVRfREVGQVVMVCkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5vRmFsbGJhY2tDb250cm9sLk5PRkFMTEJBQ0tfRk9STUFUX0RFRkFVTFRfQ09OVFJPTDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyBhIGxpc3Qgb2YgY2FuZGlkYXRlIGxvY2FsZXMgYWNjb3JkaW5nIHRvIHtAY29kZSBiYXNlTmFtZX0gaW4KKyAgICAgICAgICoge0Bjb2RlIGxvY2FsZX0uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgTGlzdDxMb2NhbGU+IGdldENhbmRpZGF0ZUxvY2FsZXMoU3RyaW5nIGJhc2VOYW1lLCBMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgICAgICBpZiAoYmFzZU5hbWUgPT0gbnVsbCB8fCBsb2NhbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgTGlzdDxMb2NhbGU+IHJldExpc3QgPSBuZXcgQXJyYXlMaXN0PExvY2FsZT4oKTsKKyAgICAgICAgICAgIFN0cmluZyBsYW5ndWFnZSA9IGxvY2FsZS5nZXRMYW5ndWFnZSgpOworICAgICAgICAgICAgU3RyaW5nIGNvdW50cnkgPSBsb2NhbGUuZ2V0Q291bnRyeSgpOworICAgICAgICAgICAgU3RyaW5nIHZhcmlhbnQgPSBsb2NhbGUuZ2V0VmFyaWFudCgpOworICAgICAgICAgICAgaWYgKCFFTVBUWV9TVFJJTkcuZXF1YWxzKHZhcmlhbnQpKSB7CisgICAgICAgICAgICAgICAgcmV0TGlzdC5hZGQobmV3IExvY2FsZShsYW5ndWFnZSwgY291bnRyeSwgdmFyaWFudCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFFTVBUWV9TVFJJTkcuZXF1YWxzKGNvdW50cnkpKSB7CisgICAgICAgICAgICAgICAgcmV0TGlzdC5hZGQobmV3IExvY2FsZShsYW5ndWFnZSwgY291bnRyeSkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFFTVBUWV9TVFJJTkcuZXF1YWxzKGxhbmd1YWdlKSkgeworICAgICAgICAgICAgICAgIHJldExpc3QuYWRkKG5ldyBMb2NhbGUobGFuZ3VhZ2UpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldExpc3QuYWRkKExvY2FsZS5ST09UKTsKKyAgICAgICAgICAgIHJldHVybiByZXRMaXN0OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgYSBsaXN0IG9mIHN0cmluZ3Mgb2YgZm9ybWF0cyBhY2NvcmRpbmcgdG8ge0Bjb2RlIGJhc2VOYW1lfS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBMaXN0PFN0cmluZz4gZ2V0Rm9ybWF0cyhTdHJpbmcgYmFzZU5hbWUpIHsKKyAgICAgICAgICAgIGlmIChiYXNlTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZm9ybWF0OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIGZhbGxiYWNrIGxvY2FsZSBmb3Ige0Bjb2RlIGJhc2VOYW1lfSBpbiB7QGNvZGUgbG9jYWxlfS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBMb2NhbGUgZ2V0RmFsbGJhY2tMb2NhbGUoU3RyaW5nIGJhc2VOYW1lLCBMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgICAgICBpZiAoYmFzZU5hbWUgPT0gbnVsbCB8fCBsb2NhbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKExvY2FsZS5nZXREZWZhdWx0KCkgIT0gbG9jYWxlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGEgbmV3IFJlc291cmNlQnVuZGxlLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gYmFzZU5hbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgYmFzZSBuYW1lIHRvIHVzZQorICAgICAgICAgKiBAcGFyYW0gbG9jYWxlCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGdpdmVuIGxvY2FsZQorICAgICAgICAgKiBAcGFyYW0gZm9ybWF0CisgICAgICAgICAqICAgICAgICAgICAgdGhlIGZvcm1hdCwgZGVmYXVsdCBpcyAiamF2YS5jbGFzcyIgb3IgImphdmEucHJvcGVydGllcyIKKyAgICAgICAgICogQHBhcmFtIGxvYWRlcgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBjbGFzc2xvYWRlciB0byB1c2UKKyAgICAgICAgICogQHBhcmFtIHJlbG9hZAorICAgICAgICAgKiAgICAgICAgICAgIHdoZXRoZXIgdG8gcmVsb2FkIHRoZSByZXNvdXJjZQorICAgICAgICAgKiBAcmV0dXJuIGEgbmV3IFJlc291cmNlQnVuZGxlIGFjY29yZGluZyB0byB0aGUgZ2l2ZSBwYXJhbWV0ZXJzCisgICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgorICAgICAgICAgKiAgICAgICAgICAgICBpZiB3ZSBjYW4gbm90IGFjY2VzcyByZXNvdXJjZXMKKyAgICAgICAgICogQHRocm93cyBJbnN0YW50aWF0aW9uRXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIHdlIGNhbiBub3QgaW5zdGFudGlhdGUgYSByZXNvdXJjZSBjbGFzcworICAgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIG90aGVyIEkvTyBleGNlcHRpb24gaGFwcGVucworICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFJlc291cmNlQnVuZGxlIG5ld0J1bmRsZShTdHJpbmcgYmFzZU5hbWUsIExvY2FsZSBsb2NhbGUsCisgICAgICAgICAgICAgICAgU3RyaW5nIGZvcm1hdCwgQ2xhc3NMb2FkZXIgbG9hZGVyLCBib29sZWFuIHJlbG9hZCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwgSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoZm9ybWF0ID09IG51bGwgfHwgbG9hZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBidW5kbGVOYW1lID0gdG9CdW5kbGVOYW1lKGJhc2VOYW1lLCBsb2NhbGUpOworICAgICAgICAgICAgZmluYWwgQ2xhc3NMb2FkZXIgY2xzbG9hZGVyID0gbG9hZGVyOworICAgICAgICAgICAgUmVzb3VyY2VCdW5kbGUgcmV0OworICAgICAgICAgICAgaWYgKGZvcm1hdC5lcXVhbHMoSkFWQUNMQVNTKSkgeworICAgICAgICAgICAgICAgIENsYXNzPD8+IGNscyA9IG51bGw7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgY2xzID0gY2xzbG9hZGVyLmxvYWRDbGFzcyhidW5kbGVOYW1lKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vQ2xhc3NEZWZGb3VuZEVycm9yIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGNscyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBSZXNvdXJjZUJ1bmRsZSBidW5kbGUgPSAoUmVzb3VyY2VCdW5kbGUpIGNscy5uZXdJbnN0YW5jZSgpOworICAgICAgICAgICAgICAgICAgICBidW5kbGUuc2V0TG9jYWxlKGxvY2FsZSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBidW5kbGU7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZm9ybWF0LmVxdWFscyhKQVZBUFJPUEVSVElFUykpIHsKKyAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBzdHJlYW1zID0gbnVsbDsKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcmVzb3VyY2VOYW1lID0gdG9SZXNvdXJjZU5hbWUoYnVuZGxlTmFtZSwgInByb3BlcnRpZXMiKTsKKyAgICAgICAgICAgICAgICBpZiAocmVsb2FkKSB7CisgICAgICAgICAgICAgICAgICAgIFVSTCB1cmwgPSBudWxsOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgdXJsID0gbG9hZGVyLmdldFJlc291cmNlKHJlc291cmNlTmFtZSk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAodXJsICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFVSTENvbm5lY3Rpb24gY29uID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBjb24uc2V0VXNlQ2FjaGVzKGZhbHNlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbXMgPSBjb24uZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zID0gY2xzbG9hZGVyLmdldFJlc291cmNlQXNTdHJlYW0ocmVzb3VyY2VOYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG8gbm90aGluZworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChzdHJlYW1zICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IG5ldyBQcm9wZXJ0eVJlc291cmNlQnVuZGxlKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihzdHJlYW1zKSk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXQuc2V0TG9jYWxlKGxvY2FsZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIHRpbWUgdG8gbGl2ZSBvZiB0aGUgUmVzb3VyY2VCdW5kbGUge0Bjb2RlIGJhc2VOYW1lfSBpbiB7QGNvZGUgbG9jYWxlfSwKKyAgICAgICAgICogZGVmYXVsdCBpcyBUVExfTk9fRVhQSVJBVElPTl9DT05UUk9MLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGxvbmcgZ2V0VGltZVRvTGl2ZShTdHJpbmcgYmFzZU5hbWUsIExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgICAgIGlmIChiYXNlTmFtZSA9PSBudWxsIHx8IGxvY2FsZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gVFRMX05PX0VYUElSQVRJT05fQ09OVFJPTDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIFJlc291cmNlQnVuZGxlIG5lZWRzIHRvIHJlbG9hZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIGJhc2VOYW1lCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGJhc2UgbmFtZSBvZiB0aGUgUmVzb3VyY2VCdW5kbGUKKyAgICAgICAgICogQHBhcmFtIGxvY2FsZQorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhbGUgb2YgdGhlIFJlc291cmNlQnVuZGxlCisgICAgICAgICAqIEBwYXJhbSBmb3JtYXQKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZm9ybWF0IHRvIGxvYWQKKyAgICAgICAgICogQHBhcmFtIGxvYWRlcgorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBDbGFzc0xvYWRlciB0byBsb2FkIHJlc291cmNlCisgICAgICAgICAqIEBwYXJhbSBidW5kbGUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgUmVzb3VyY2VCdW5kbGUKKyAgICAgICAgICogQHBhcmFtIGxvYWRUaW1lCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGV4cGlyZWQgdGltZQorICAgICAgICAgKiBAcmV0dXJuIGlmIHRoZSBSZXNvdXJjZUJ1bmRsZSBuZWVkcyB0byByZWxvYWQKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBib29sZWFuIG5lZWRzUmVsb2FkKFN0cmluZyBiYXNlTmFtZSwgTG9jYWxlIGxvY2FsZSwKKyAgICAgICAgICAgICAgICBTdHJpbmcgZm9ybWF0LCBDbGFzc0xvYWRlciBsb2FkZXIsIFJlc291cmNlQnVuZGxlIGJ1bmRsZSwKKyAgICAgICAgICAgICAgICBsb25nIGxvYWRUaW1lKSB7CisgICAgICAgICAgICBpZiAoYnVuZGxlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyBGSVhNRSB3aGF0J3MgdGhlIHVzZSBvZiBidW5kbGU/CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTdHJpbmcgYnVuZGxlTmFtZSA9IHRvQnVuZGxlTmFtZShiYXNlTmFtZSwgbG9jYWxlKTsKKyAgICAgICAgICAgIFN0cmluZyBzdWZmaXggPSBmb3JtYXQ7CisgICAgICAgICAgICBpZiAoZm9ybWF0LmVxdWFscyhKQVZBQ0xBU1MpKSB7CisgICAgICAgICAgICAgICAgc3VmZml4ID0gImNsYXNzIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChmb3JtYXQuZXF1YWxzKEpBVkFQUk9QRVJUSUVTKSkgeworICAgICAgICAgICAgICAgIHN1ZmZpeCA9ICJwcm9wZXJ0aWVzIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN0cmluZyB1cmxuYW1lID0gdG9SZXNvdXJjZU5hbWUoYnVuZGxlTmFtZSwgc3VmZml4KTsKKyAgICAgICAgICAgIFVSTCB1cmwgPSBsb2FkZXIuZ2V0UmVzb3VyY2UodXJsbmFtZSk7CisgICAgICAgICAgICBpZiAodXJsICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgZmlsZU5hbWUgPSB1cmwuZ2V0RmlsZSgpOworICAgICAgICAgICAgICAgIGxvbmcgbGFzdE1vZGlmaWVkID0gbmV3IEZpbGUoZmlsZU5hbWUpLmxhc3RNb2RpZmllZCgpOworICAgICAgICAgICAgICAgIGlmIChsYXN0TW9kaWZpZWQgPiBsb2FkVGltZSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogYSB1dGlsaXR5IG1ldGhvZCB0byBhbnN3ZXIgdGhlIG5hbWUgb2YgYSByZXNvdXJjZSBidW5kbGUgYWNjb3JkaW5nIHRvCisgICAgICAgICAqIHRoZSBnaXZlbiBiYXNlIG5hbWUgYW5kIGxvY2FsZQorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gYmFzZU5hbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZ2l2ZW4gYmFzZSBuYW1lCisgICAgICAgICAqIEBwYXJhbSBsb2NhbGUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgbG9jYWxlIHRvIHVzZQorICAgICAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIGEgcmVzb3VyY2UgYnVuZGxlIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gYmFzZQorICAgICAgICAgKiAgICAgICAgIG5hbWUgYW5kIGxvY2FsZQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFN0cmluZyB0b0J1bmRsZU5hbWUoU3RyaW5nIGJhc2VOYW1lLCBMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZW1wdHlTdHJpbmcgPSBFTVBUWV9TVFJJTkc7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcHJlU3RyaW5nID0gVU5ERVJfU0NPUkU7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdW5kZXJsaW5lID0gVU5ERVJfU0NPUkU7CisgICAgICAgICAgICBpZiAoYmFzZU5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3RyaW5nQnVpbGRlciByZXQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBwcmVmaXggPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICAgICAgcmV0LmFwcGVuZChiYXNlTmFtZSk7CisgICAgICAgICAgICBpZiAoIWxvY2FsZS5nZXRMYW5ndWFnZSgpLmVxdWFscyhlbXB0eVN0cmluZykpIHsKKyAgICAgICAgICAgICAgICByZXQuYXBwZW5kKHVuZGVybGluZSk7CisgICAgICAgICAgICAgICAgcmV0LmFwcGVuZChsb2NhbGUuZ2V0TGFuZ3VhZ2UoKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHByZWZpeC5hcHBlbmQocHJlU3RyaW5nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghbG9jYWxlLmdldENvdW50cnkoKS5lcXVhbHMoZW1wdHlTdHJpbmcpKSB7CisgICAgICAgICAgICAgICAgcmV0LmFwcGVuZCgoQ2hhclNlcXVlbmNlKSBwcmVmaXgpOworICAgICAgICAgICAgICAgIHJldC5hcHBlbmQodW5kZXJsaW5lKTsKKyAgICAgICAgICAgICAgICByZXQuYXBwZW5kKGxvY2FsZS5nZXRDb3VudHJ5KCkpOworICAgICAgICAgICAgICAgIHByZWZpeCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHByZWZpeC5hcHBlbmQocHJlU3RyaW5nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghbG9jYWxlLmdldFZhcmlhbnQoKS5lcXVhbHMoZW1wdHlTdHJpbmcpKSB7CisgICAgICAgICAgICAgICAgcmV0LmFwcGVuZCgoQ2hhclNlcXVlbmNlKSBwcmVmaXgpOworICAgICAgICAgICAgICAgIHJldC5hcHBlbmQodW5kZXJsaW5lKTsKKyAgICAgICAgICAgICAgICByZXQuYXBwZW5kKGxvY2FsZS5nZXRWYXJpYW50KCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJldC50b1N0cmluZygpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIGEgdXRpbGl0eSBtZXRob2QgdG8gYW5zd2VyIHRoZSBuYW1lIG9mIGEgcmVzb3VyY2UgYWNjb3JkaW5nIHRvIHRoZQorICAgICAgICAgKiBnaXZlbiBidW5kbGVOYW1lIGFuZCBzdWZmaXgKKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIGJ1bmRsZU5hbWUKKyAgICAgICAgICogICAgICAgICAgICB0aGUgZ2l2ZW4gYnVuZGxlIG5hbWUKKyAgICAgICAgICogQHBhcmFtIHN1ZmZpeAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBzdWZmaXgKKyAgICAgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiBhIHJlc291cmNlIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gYnVuZGxlTmFtZSBhbmQKKyAgICAgICAgICogICAgICAgICBzdWZmaXgKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9SZXNvdXJjZU5hbWUoU3RyaW5nIGJ1bmRsZU5hbWUsIFN0cmluZyBzdWZmaXgpIHsKKyAgICAgICAgICAgIGlmIChzdWZmaXggPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3RyaW5nQnVpbGRlciByZXQgPSBuZXcgU3RyaW5nQnVpbGRlcihidW5kbGVOYW1lLnJlcGxhY2UoJy4nLCAnLycpKTsKKyAgICAgICAgICAgIHJldC5hcHBlbmQoJy4nKTsKKyAgICAgICAgICAgIHJldC5hcHBlbmQoc3VmZml4KTsKKyAgICAgICAgICAgIHJldHVybiByZXQudG9TdHJpbmcoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvU2Nhbm5lci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9TY2FubmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGY4ODliMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvU2Nhbm5lci5qYXZhCkBAIC0wLDAgKzEsMjE4OCBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm1hdGguQmlnRGVjaW1hbDsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLm5pby5DaGFyQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkNoYW5uZWxzOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlJlYWRhYmxlQnl0ZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OworaW1wb3J0IGphdmEudGV4dC5EZWNpbWFsRm9ybWF0OworaW1wb3J0IGphdmEudGV4dC5OdW1iZXJGb3JtYXQ7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4Lk1hdGNoUmVzdWx0OworaW1wb3J0IGphdmEudXRpbC5yZWdleC5NYXRjaGVyOworaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKKworLyoqCisgKiBBIHBhcnNlciB0aGF0IHBhcnNlcyBhIHRleHQgc3RyaW5nIG9mIHByaW1pdGl2ZSB0eXBlcyBhbmQgc3RyaW5ncyB3aXRoIHRoZQorICogaGVscCBvZiByZWd1bGFyIGV4cHJlc3Npb25zLiBJdCBzdXBwb3J0cyBsb2NhbGl6ZWQgbnVtYmVycyBhbmQgdmFyaW91cworICogcmFkaXhlcy4gVGhlIGlucHV0IGlzIGJyb2tlbiBpbnRvIHRva2VucyBieSB0aGUgZGVsaW1pdGVyIHBhdHRlcm4sIHdoaWNoIGlzCisgKiB3aGl0ZXNwYWNlIGJ5IGRlZmF1bHQuIFRoZSBwcmltaXRpdmUgdHlwZXMgY2FuIGJlIG9idGFpbmVkIHZpYSBjb3JyZXNwb25kaW5nCisgKiBuZXh0KiBtZXRob2RzLiBJZiB0aGUgdG9rZW4gaXMgbm90IGluIGEgdmFsaWQgZm9ybWF0LCBhbgorICoge0Bjb2RlIElucHV0TWlzbWF0Y2hFeGNlcHRpb259IGlzIHRocm93bi4KKyAqIDxwPgorICogRm9yIGV4YW1wbGU6CisgKiA8cHJlPgorICogU2Nhbm5lciBzID0gbmV3IFNjYW5uZXIoIjFBIHRydWUiKTsKKyAqIFN5c3RlbS5vdXQucHJpbnRsbihzLm5leHRJbnQoMTYpKTsKKyAqIFN5c3RlbS5vdXQucHJpbnRsbihzLm5leHRCb29sZWFuKCkpOworICogPC9wcmU+CisgKiA8cD4KKyAqIFlpZWxkcyB0aGUgcmVzdWx0OiB7QGNvZGUgMjYgdHJ1ZX0KKyAqIDxwPkEge0Bjb2RlIFNjYW5uZXJ9IGNhbiBhbHNvIGZpbmQgb3Igc2tpcCBzcGVjaWZpYyBwYXR0ZXJucyB3aXRob3V0IHJlZ2FyZCBmb3IgdGhlCisgKiBkZWxpbWl0ZXIuIEFsbCB0aGVzZSBtZXRob2RzIGFuZCB0aGUgdmFyaW91cyBuZXh0KiBhbmQgaGFzTmV4dCogbWV0aG9kcyBtYXkKKyAqIGJsb2NrLgorICogPHA+CisgKiBUaGUge0Bjb2RlIFNjYW5uZXJ9IGNsYXNzIGlzIG5vdCB0aHJlYWQtc2FmZS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFNjYW5uZXIgaW1wbGVtZW50cyBJdGVyYXRvcjxTdHJpbmc+IHsKKworICAgIC8vIERlZmF1bHQgZGVsaW1pdGluZyBwYXR0ZXJuLgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gREVGQVVMVF9ERUxJTUlURVIgPSBQYXR0ZXJuCisgICAgICAgICAgICAuY29tcGlsZSgiXFxwe2phdmFXaGl0ZXNwYWNlfSsiKTsKKworICAgIC8vIFRoZSBib29sZWFuJ3MgcGF0dGVybi4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQYXR0ZXJuIEJPT0xFQU5fUEFUVEVSTiA9IFBhdHRlcm4uY29tcGlsZSgKKyAgICAgICAgICAgICJ0cnVlfGZhbHNlIiwgUGF0dGVybi5DQVNFX0lOU0VOU0lUSVZFKTsKKworICAgIC8vIFBhdHRlcm4gdXNlZCB0byByZWNvZ25pemUgbGluZSB0ZXJtaW5hdG9yLgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gTElORV9URVJNSU5BVE9SOworCisgICAgLy8gUGF0dGVybiB1c2VkIHRvIHJlY29nbml6ZSBtdWx0aXBsZSBsaW5lIHRlcm1pbmF0b3JzLgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gTVVMVElfTElORV9URVJNSU5BVE9SOworCisgICAgLy8gUGF0dGVybiB1c2VkIHRvIHJlY29nbml6ZSBhIGxpbmUgd2l0aCBhIGxpbmUgdGVybWluYXRvci4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQYXR0ZXJuIExJTkVfUEFUVEVSTjsKKworICAgIHN0YXRpYyB7CisgICAgICAgIFN0cmluZyBOTCA9ICJcbnxcclxufFxyfFx1MDA4NXxcdTIwMjh8XHUyMDI5IjsKKyAgICAgICAgTElORV9URVJNSU5BVE9SID0gUGF0dGVybi5jb21waWxlKE5MKTsKKyAgICAgICAgTVVMVElfTElORV9URVJNSU5BVE9SID0gUGF0dGVybi5jb21waWxlKCIoIiArIE5MICsgIikrIik7CisgICAgICAgIExJTkVfUEFUVEVSTiA9IFBhdHRlcm4uY29tcGlsZSgiLiooIiArIE5MICsgIil8LisoIiArIE5MICsgIik/Iik7CisgICAgfQorCisgICAgLy8gVGhlIHBhdHRlcm4gbWF0Y2hlcyBhbnl0aGluZy4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQYXR0ZXJuIEFOWV9QQVRURVJOID0gUGF0dGVybi5jb21waWxlKCIoP3MpLioiKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBESVBMT0lEID0gMjsKKworICAgIC8vIERlZmF1bHQgcmFkaXguCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfUkFESVggPSAxMDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1RSVU5LX1NJWkUgPSAxMDI0OworCisgICAgLy8gVGhlIGlucHV0IHNvdXJjZSBvZiBzY2FubmVyLgorICAgIHByaXZhdGUgUmVhZGFibGUgaW5wdXQ7CisKKyAgICBwcml2YXRlIENoYXJCdWZmZXIgYnVmZmVyOworCisgICAgcHJpdmF0ZSBQYXR0ZXJuIGRlbGltaXRlciA9IERFRkFVTFRfREVMSU1JVEVSOworCisgICAgcHJpdmF0ZSBNYXRjaGVyIG1hdGNoZXI7CisKKyAgICBwcml2YXRlIGludCBpbnRlZ2VyUmFkaXggPSBERUZBVUxUX1JBRElYOworCisgICAgcHJpdmF0ZSBMb2NhbGUgbG9jYWxlID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKworICAgIC8vIFRoZSBwb3NpdGlvbiB3aGVyZSBmaW5kIGJlZ2lucy4KKyAgICBwcml2YXRlIGludCBmaW5kU3RhcnRJbmRleCA9IDA7CisKKyAgICAvLyBUaGUgbGFzdCBmaW5kIHN0YXJ0IHBvc2l0aW9uLgorICAgIHByaXZhdGUgaW50IHByZVN0YXJ0SW5kZXggPSBmaW5kU3RhcnRJbmRleDsKKworICAgIC8vIFRoZSBsZW5ndGggb2YgdGhlIGJ1ZmZlci4KKyAgICBwcml2YXRlIGludCBidWZmZXJMZW5ndGggPSAwOworCisgICAgLy8gUmVjb3JkIHRoZSBzdGF0dXMgb2YgdGhpcyBzY2FubmVyLiBUcnVlIGlmIHRoZSBzY2FubmVyCisgICAgLy8gaXMgY2xvc2VkLgorICAgIHByaXZhdGUgYm9vbGVhbiBjbG9zZWQgPSBmYWxzZTsKKworICAgIHByaXZhdGUgSU9FeGNlcHRpb24gbGFzdElPRXhjZXB0aW9uOworCisgICAgcHJpdmF0ZSBib29sZWFuIG1hdGNoU3VjY2Vzc2Z1bCA9IGZhbHNlOworCisgICAgcHJpdmF0ZSBEZWNpbWFsRm9ybWF0IGRlY2ltYWxGb3JtYXQ7CisKKyAgICAvLyBSZWNvcmRzIHdoZXRoZXIgdGhlIHVuZGVybHlpbmcgcmVhZGFibGUgaGFzIG1vcmUgaW5wdXQuCisgICAgcHJpdmF0ZSBib29sZWFuIGlucHV0RXhoYXVzdGVkID0gZmFsc2U7CisKKyAgICBwcml2YXRlIE9iamVjdCBjYWNoZUhhc05leHRWYWx1ZSA9IG51bGw7CisKKyAgICBwcml2YXRlIGludCBjYWNoZWhhc05leHRJbmRleCA9IC0xOworCisgICAgcHJpdmF0ZSBlbnVtIERhdGFUeXBlIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogU3RhbmRzIGZvciBJbnRlZ2VyCisgICAgICAgICAqLworICAgICAgICBJTlQsCisgICAgICAgIC8qCisgICAgICAgICAqIFN0YW5kcyBmb3IgRmxvYXQKKyAgICAgICAgICovCisgICAgICAgIEZMT0FUOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgU2Nhbm5lcn0gd2l0aCB0aGUgc3BlY2lmaWVkIHtAY29kZSBGaWxlfSBhcyBpbnB1dC4gVGhlIGRlZmF1bHQgY2hhcnNldAorICAgICAqIGlzIGFwcGxpZWQgd2hlbiByZWFkaW5nIHRoZSBmaWxlLgorICAgICAqCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIGZpbGUgdG8gYmUgc2Nhbm5lZC4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgZmlsZSBkb2VzIG5vdCBleGlzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2Nhbm5lcihGaWxlIHNyYykgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoc3JjLCBDaGFyc2V0LmRlZmF1bHRDaGFyc2V0KCkubmFtZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIFNjYW5uZXJ9IHdpdGggdGhlIHNwZWNpZmllZCB7QGNvZGUgRmlsZX0gYXMgaW5wdXQuIFRoZSBzcGVjaWZpZWQgY2hhcnNldAorICAgICAqIGlzIGFwcGxpZWQgd2hlbiByZWFkaW5nIHRoZSBmaWxlLgorICAgICAqCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIGZpbGUgdG8gYmUgc2Nhbm5lZC4KKyAgICAgKiBAcGFyYW0gY2hhcnNldE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBlbmNvZGluZyB0eXBlIG9mIHRoZSBmaWxlLgorICAgICAqIEB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBmaWxlIGRvZXMgbm90IGV4aXN0LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBjb2RpbmcgZG9lcyBub3QgZXhpc3QuCisgICAgICovCisgICAgcHVibGljIFNjYW5uZXIoRmlsZSBzcmMsIFN0cmluZyBjaGFyc2V0TmFtZSkgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzcmMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJzcmMgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBmaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKHNyYyk7CisgICAgICAgIGlmIChjaGFyc2V0TmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJjaGFyc2V0TmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlucHV0ID0gbmV3IElucHV0U3RyZWFtUmVhZGVyKGZpcywgY2hhcnNldE5hbWUpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIElvVXRpbHMuY2xvc2VRdWlldGx5KGZpcyk7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBpbml0aWFsaXphdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgU2Nhbm5lcn0gb24gdGhlIHNwZWNpZmllZCBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHRvIGJlIHNjYW5uZWQuCisgICAgICovCisgICAgcHVibGljIFNjYW5uZXIoU3RyaW5nIHNyYykgeworICAgICAgICBpbnB1dCA9IG5ldyBTdHJpbmdSZWFkZXIoc3JjKTsKKyAgICAgICAgaW5pdGlhbGl6YXRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIFNjYW5uZXJ9IG9uIHRoZSBzcGVjaWZpZWQge0Bjb2RlIElucHV0U3RyZWFtfS4gVGhlIGRlZmF1bHQgY2hhcnNldCBpcworICAgICAqIGFwcGxpZWQgd2hlbiBkZWNvZGluZyB0aGUgaW5wdXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIElucHV0U3RyZWFtfSB0byBiZSBzY2FubmVkLgorICAgICAqLworICAgIHB1YmxpYyBTY2FubmVyKElucHV0U3RyZWFtIHNyYykgeworICAgICAgICB0aGlzKHNyYywgQ2hhcnNldC5kZWZhdWx0Q2hhcnNldCgpLm5hbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHtAY29kZSBTY2FubmVyfSBvbiB0aGUgc3BlY2lmaWVkIHtAY29kZSBJbnB1dFN0cmVhbX0uIFRoZSBzcGVjaWZpZWQgY2hhcnNldCBpcworICAgICAqIGFwcGxpZWQgd2hlbiBkZWNvZGluZyB0aGUgaW5wdXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIElucHV0U3RyZWFtfSB0byBiZSBzY2FubmVkLgorICAgICAqIEBwYXJhbSBjaGFyc2V0TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGVuY29kaW5nIHR5cGUgb2YgdGhlIHtAY29kZSBJbnB1dFN0cmVhbX0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBzZXQgaXMgbm90IGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBTY2FubmVyKElucHV0U3RyZWFtIHNyYywgU3RyaW5nIGNoYXJzZXROYW1lKSB7CisgICAgICAgIGlmIChzcmMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJzcmMgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnB1dCA9IG5ldyBJbnB1dFN0cmVhbVJlYWRlcihzcmMsIGNoYXJzZXROYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBpbml0aWFsaXphdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgU2Nhbm5lcn0gd2l0aCB0aGUgc3BlY2lmaWVkIHtAY29kZSBSZWFkYWJsZX0gYXMgaW5wdXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIFJlYWRhYmxlfSB0byBiZSBzY2FubmVkLgorICAgICAqLworICAgIHB1YmxpYyBTY2FubmVyKFJlYWRhYmxlIHNyYykgeworICAgICAgICBpZiAoc3JjID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlucHV0ID0gc3JjOworICAgICAgICBpbml0aWFsaXphdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgU2Nhbm5lcn0gd2l0aCB0aGUgc3BlY2lmaWVkIHtAY29kZSBSZWFkYWJsZUJ5dGVDaGFubmVsfSBhcworICAgICAqIGlucHV0LiBUaGUgZGVmYXVsdCBjaGFyc2V0IGlzIGFwcGxpZWQgd2hlbiBkZWNvZGluZyB0aGUgaW5wdXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIFJlYWRhYmxlQnl0ZUNoYW5uZWx9IHRvIGJlIHNjYW5uZWQuCisgICAgICovCisgICAgcHVibGljIFNjYW5uZXIoUmVhZGFibGVCeXRlQ2hhbm5lbCBzcmMpIHsKKyAgICAgICAgdGhpcyhzcmMsIENoYXJzZXQuZGVmYXVsdENoYXJzZXQoKS5uYW1lKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgU2Nhbm5lcn0gd2l0aCB0aGUgc3BlY2lmaWVkIHtAY29kZSBSZWFkYWJsZUJ5dGVDaGFubmVsfSBhcworICAgICAqIGlucHV0LiBUaGUgc3BlY2lmaWVkIGNoYXJzZXQgaXMgYXBwbGllZCB3aGVuIGRlY29kaW5nIHRoZSBpbnB1dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcmMKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgUmVhZGFibGVCeXRlQ2hhbm5lbH0gdG8gYmUgc2Nhbm5lZC4KKyAgICAgKiBAcGFyYW0gY2hhcnNldE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmNvZGluZyB0eXBlIG9mIHRoZSBjb250ZW50LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgc2V0IGlzIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2Nhbm5lcihSZWFkYWJsZUJ5dGVDaGFubmVsIHNyYywgU3RyaW5nIGNoYXJzZXROYW1lKSB7CisgICAgICAgIGlmIChzcmMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJzcmMgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChjaGFyc2V0TmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJjaGFyc2V0TmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaW5wdXQgPSBDaGFubmVscy5uZXdSZWFkZXIoc3JjLCBjaGFyc2V0TmFtZSk7CisgICAgICAgIGluaXRpYWxpemF0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMge0Bjb2RlIFNjYW5uZXJ9IGFuZCB0aGUgdW5kZXJseWluZyBpbnB1dCBpZiB0aGUgaW5wdXQgaW1wbGVtZW50cworICAgICAqIHtAY29kZSBDbG9zZWFibGV9LiBJZiB0aGUge0Bjb2RlIFNjYW5uZXJ9IGhhcyBiZWVuIGNsb3NlZCwgdGhpcyBtZXRob2Qgd2lsbCBoYXZlCisgICAgICogbm8gZWZmZWN0LiBBbnkgc2Nhbm5pbmcgb3BlcmF0aW9uIGNhbGxlZCBhZnRlciBjYWxsaW5nIHRoaXMgbWV0aG9kIHdpbGwgdGhyb3cKKyAgICAgKiBhbiB7QGNvZGUgSWxsZWdhbFN0YXRlRXhjZXB0aW9ufS4KKyAgICAgKgorICAgICAqIEBzZWUgQ2xvc2VhYmxlCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgIGlmIChjbG9zZWQpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBDbG9zZWFibGUpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgKChDbG9zZWFibGUpIGlucHV0KS5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGxhc3RJT0V4Y2VwdGlvbiA9IGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY2xvc2VkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWxpbWl0ZXIge0Bjb2RlIFBhdHRlcm59IGluIHVzZSBieSB0aGlzIHtAY29kZSBTY2FubmVyfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGRlbGltaXRlciB7QGNvZGUgUGF0dGVybn0gaW4gdXNlIGJ5IHRoaXMge0Bjb2RlIFNjYW5uZXJ9LgorICAgICAqLworICAgIHB1YmxpYyBQYXR0ZXJuIGRlbGltaXRlcigpIHsKKyAgICAgICAgcmV0dXJuIGRlbGltaXRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmllcyB0byBmaW5kIHRoZSBwYXR0ZXJuIGluIHRoZSBpbnB1dC4gRGVsaW1pdGVycyBhcmUgaWdub3JlZC4gSWYgdGhlCisgICAgICogcGF0dGVybiBpcyBmb3VuZCBiZWZvcmUgbGluZSB0ZXJtaW5hdG9yLCB0aGUgbWF0Y2hlZCBzdHJpbmcgd2lsbCBiZQorICAgICAqIHJldHVybmVkLCBhbmQgdGhlIHtAY29kZSBTY2FubmVyfSB3aWxsIGFkdmFuY2UgdG8gdGhlIGVuZCBvZiB0aGUgbWF0Y2hlZCBzdHJpbmcuCisgICAgICogT3RoZXJ3aXNlLCB7QGNvZGUgbnVsbH0gd2lsbCBiZSByZXR1cm5lZCBhbmQgdGhlIHtAY29kZSBTY2FubmVyfSB3aWxsIG5vdCBhZHZhbmNlLgorICAgICAqIFdoZW4gd2FpdGluZyBmb3IgaW5wdXQsIHRoZSB7QGNvZGUgU2Nhbm5lcn0gbWF5IGJlIGJsb2NrZWQuIEFsbCB0aGUKKyAgICAgKiBpbnB1dCBtYXkgYmUgY2FjaGVkIGlmIG5vIGxpbmUgdGVybWluYXRvciBleGlzdHMgaW4gdGhlIGJ1ZmZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXR0ZXJuCisgICAgICogICAgICAgICAgICB0aGUgcGF0dGVybiB0byBmaW5kIGluIHRoZSBpbnB1dC4KKyAgICAgKiBAcmV0dXJuIHRoZSBtYXRjaGVkIHN0cmluZyBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIHBhdHRlcm4gaXMgbm90IGZvdW5kCisgICAgICogICAgICAgICBiZWZvcmUgdGhlIG5leHQgbGluZSB0ZXJtaW5hdG9yLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBTY2FubmVyfSBpcyBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBmaW5kSW5MaW5lKFBhdHRlcm4gcGF0dGVybikgeworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICBjaGVja051bGwocGF0dGVybik7CisgICAgICAgIGludCBob3Jpem9uTGluZVNlcGFyYXRvciA9IDA7CisKKyAgICAgICAgbWF0Y2hlci51c2VQYXR0ZXJuKE1VTFRJX0xJTkVfVEVSTUlOQVRPUik7CisgICAgICAgIG1hdGNoZXIucmVnaW9uKGZpbmRTdGFydEluZGV4LCBidWZmZXJMZW5ndGgpOworCisgICAgICAgIGJvb2xlYW4gZmluZENvbXBsZXRlID0gZmFsc2U7CisgICAgICAgIGludCB0ZXJtaW5hdG9yTGVuZ3RoID0gMDsKKyAgICAgICAgd2hpbGUgKCFmaW5kQ29tcGxldGUpIHsKKyAgICAgICAgICAgIGlmIChtYXRjaGVyLmZpbmQoKSkgeworICAgICAgICAgICAgICAgIGhvcml6b25MaW5lU2VwYXJhdG9yID0gbWF0Y2hlci5zdGFydCgpOworICAgICAgICAgICAgICAgIHRlcm1pbmF0b3JMZW5ndGggPSBtYXRjaGVyLmVuZCgpIC0gbWF0Y2hlci5zdGFydCgpOworICAgICAgICAgICAgICAgIGZpbmRDb21wbGV0ZSA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmICghaW5wdXRFeGhhdXN0ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVhZE1vcmUoKTsKKyAgICAgICAgICAgICAgICAgICAgcmVzZXRNYXRjaGVyKCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaG9yaXpvbkxpbmVTZXBhcmF0b3IgPSBidWZmZXJMZW5ndGg7CisgICAgICAgICAgICAgICAgICAgIGZpbmRDb21wbGV0ZSA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgbWF0Y2hlci51c2VQYXR0ZXJuKHBhdHRlcm4pOworCisgICAgICAgIC8qCisgICAgICAgICAqIFRPRE8gVGhlIGZvbGxvd2luZyAyIHN0YXRlbWVudHMgYXJlIHVzZWQgdG8gZGVhbCB3aXRoIHJlZ2V4J3MgYnVnLgorICAgICAgICAgKiBqYXZhLnV0aWwucmVnZXguTWF0Y2hlci5yZWdpb24oaW50IHN0YXJ0LCBpbnQgZW5kKSBpbXBsZW1lbnRhdGlvbgorICAgICAgICAgKiBkb2VzIG5vdCBoYXZlIGFueSBlZmZlY3RzIHdoZW4gY2FsbGVkLiBUaGV5IHdpbGwgYmUgcmVtb3ZlZCBvbmNlIHRoZQorICAgICAgICAgKiBidWcgaXMgZml4ZWQuCisgICAgICAgICAqLworICAgICAgICBpbnQgb2xkTGltaXQgPSBidWZmZXIubGltaXQoKTsKKyAgICAgICAgLy8gQ29uc2lkZXJpbmcgdGhlIGxvb2sgYWhlYWQgZmVhdHVyZSwgdGhlIGxpbmUgdGVybWluYXRvciBzaG91bGQgYmUgaW52b2x2ZWQgYXMgUkkKKyAgICAgICAgYnVmZmVyLmxpbWl0KGhvcml6b25MaW5lU2VwYXJhdG9yICsgdGVybWluYXRvckxlbmd0aCk7CisgICAgICAgIC8vID09PT09PT09PT0gVG8gZGVhbCB3aXRoIHJlZ2V4IGJ1ZyA9PT09PT09PT09PT09PT09PT09PQorCisgICAgICAgIC8vIENvbnNpZGVyaW5nIHRoZSBsb29rIGFoZWFkIGZlYXR1cmUsIHRoZSBsaW5lIHRlcm1pbmF0b3Igc2hvdWxkIGJlIGludm9sdmVkIGFzIFJJCisgICAgICAgIG1hdGNoZXIucmVnaW9uKGZpbmRTdGFydEluZGV4LCBob3Jpem9uTGluZVNlcGFyYXRvciArIHRlcm1pbmF0b3JMZW5ndGgpOworICAgICAgICBpZiAobWF0Y2hlci5maW5kKCkpIHsKKyAgICAgICAgICAgIC8vIFRoZSBzY2FubmVyIGFkdmFuY2VzIHBhc3QgdGhlIGlucHV0IHRoYXQgbWF0Y2hlZAorICAgICAgICAgICAgZmluZFN0YXJ0SW5kZXggPSBtYXRjaGVyLmVuZCgpOworICAgICAgICAgICAgLy8gSWYgdGhlIG1hdGNoZWQgcGF0dGVybiBpcyBpbW1lZGlhdGVseSBmb2xsb3dlZCBieSBsaW5lCisgICAgICAgICAgICAvLyB0ZXJtaW5hdG9yLgorICAgICAgICAgICAgaWYgKGhvcml6b25MaW5lU2VwYXJhdG9yID09IG1hdGNoZXIuZW5kKCkpIHsKKyAgICAgICAgICAgICAgICBmaW5kU3RhcnRJbmRleCArPSB0ZXJtaW5hdG9yTGVuZ3RoOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gdGhlIGxpbmUgdGVybWluYXRvciBpdHNlbGYgc2hvdWxkIG5vdCBiZSBhIHBhcnQgb2YKKyAgICAgICAgICAgIC8vIHRoZSBtYXRjaCByZXN1bHQgYWNjb3JkaW5nIHRvIHRoZSBTcGVjCisgICAgICAgICAgICBpZiAoaG9yaXpvbkxpbmVTZXBhcmF0b3IgIT0gYnVmZmVyTGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICYmIChob3Jpem9uTGluZVNlcGFyYXRvciArIHRlcm1pbmF0b3JMZW5ndGggPT0gbWF0Y2hlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5lbmQoKSkpIHsKKyAgICAgICAgICAgICAgICAvLyA9PT09PT09PT09IFRvIGRlYWwgd2l0aCByZWdleCBidWcgPT09PT09PT09PT09PT09PT09PT0KKyAgICAgICAgICAgICAgICBidWZmZXIubGltaXQob2xkTGltaXQpOworICAgICAgICAgICAgICAgIC8vID09PT09PT09PT0gVG8gZGVhbCB3aXRoIHJlZ2V4IGJ1ZyA9PT09PT09PT09PT09PT09PT09PQorCisgICAgICAgICAgICAgICAgbWF0Y2hTdWNjZXNzZnVsID0gZmFsc2U7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtYXRjaFN1Y2Nlc3NmdWwgPSB0cnVlOworCisgICAgICAgICAgICAvLyA9PT09PT09PT09IFRvIGRlYWwgd2l0aCByZWdleCBidWcgPT09PT09PT09PT09PT09PT09PT0KKyAgICAgICAgICAgIGJ1ZmZlci5saW1pdChvbGRMaW1pdCk7CisgICAgICAgICAgICAvLyA9PT09PT09PT09IFRvIGRlYWwgd2l0aCByZWdleCBidWcgPT09PT09PT09PT09PT09PT09PT0KKworICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXIuZ3JvdXAoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vID09PT09PT09PT0gVG8gZGVhbCB3aXRoIHJlZ2V4IGJ1ZyA9PT09PT09PT09PT09PT09PT09PQorICAgICAgICBidWZmZXIubGltaXQob2xkTGltaXQpOworICAgICAgICAvLyA9PT09PT09PT09IFRvIGRlYWwgd2l0aCByZWdleCBidWcgPT09PT09PT09PT09PT09PT09PT0KKworICAgICAgICBtYXRjaFN1Y2Nlc3NmdWwgPSBmYWxzZTsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGlsZXMgdGhlIHBhdHRlcm4gc3RyaW5nIGFuZCB0cmllcyB0byBmaW5kIGEgc3Vic3RpbmcgbWF0Y2hpbmcgaXQgaW4gdGhlIGlucHV0IGRhdGEuIFRoZQorICAgICAqIGRlbGltaXRlciB3aWxsIGJlIGlnbm9yZWQuIFRoaXMgaXMgdGhlIHNhbWUgYXMgaW52b2tpbmcKKyAgICAgKiB7QGNvZGUgZmluZEluTGluZShQYXR0ZXJuLmNvbXBpbGUocGF0dGVybikpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXR0ZXJuCisgICAgICogICAgICAgICAgICBhIHN0cmluZyB1c2VkIHRvIGNvbnN0cnVjdCBhIHBhdHRlcm4gd2hpY2ggaXMgaW4gdHVybiB1c2VkIHRvCisgICAgICogICAgICAgICAgICBtYXRjaCBhIHN1YnN0cmluZyBvZiB0aGUgaW5wdXQgZGF0YS4KKyAgICAgKiBAcmV0dXJuIHRoZSBtYXRjaGVkIHN0cmluZyBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIHBhdHRlcm4gaXMgbm90IGZvdW5kCisgICAgICogICAgICAgICBiZWZvcmUgdGhlIG5leHQgbGluZSB0ZXJtaW5hdG9yLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBTY2FubmVyfSBpcyBjbG9zZWQuCisgICAgICogQHNlZSAjZmluZEluTGluZShQYXR0ZXJuKQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZmluZEluTGluZShTdHJpbmcgcGF0dGVybikgeworICAgICAgICByZXR1cm4gZmluZEluTGluZShQYXR0ZXJuLmNvbXBpbGUocGF0dGVybikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyaWVzIHRvIGZpbmQgdGhlIHBhdHRlcm4gaW4gdGhlIGlucHV0IGJldHdlZW4gdGhlIGN1cnJlbnQgcG9zaXRpb24gYW5kIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBob3Jpem9uLiBEZWxpbWl0ZXJzIGFyZSBpZ25vcmVkLiBJZiB0aGUgcGF0dGVybiBpcyBmb3VuZCwgdGhlIG1hdGNoZWQKKyAgICAgKiBzdHJpbmcgd2lsbCBiZSByZXR1cm5lZCwgYW5kIHRoZSB7QGNvZGUgU2Nhbm5lcn0gd2lsbCBhZHZhbmNlIHRvIHRoZSBlbmQgb2YgdGhlCisgICAgICogbWF0Y2hlZCBzdHJpbmcuIE90aGVyd2lzZSwgbnVsbCB3aWxsIGJlIHJldHVybmVkIGFuZCB7QGNvZGUgU2Nhbm5lcn0gd2lsbCBub3QKKyAgICAgKiBhZHZhbmNlLiBXaGVuIHdhaXRpbmcgZm9yIGlucHV0LCB0aGUge0Bjb2RlIFNjYW5uZXJ9IG1heSBiZSBibG9ja2VkLgorICAgICAqIDxwPgorICAgICAqIFRoZSB7QGNvZGUgU2Nhbm5lcn0ncyBzZWFyY2ggd2lsbCBuZXZlciBnbyBtb3JlIHRoYW4ge0Bjb2RlIGhvcml6b259IGNvZGUgcG9pbnRzIGZyb20gY3VycmVudAorICAgICAqIHBvc2l0aW9uLiBUaGUgcG9zaXRpb24gb2Yge0Bjb2RlIGhvcml6b259IGRvZXMgaGF2ZSBhbiBlZmZlY3Qgb24gdGhlIHJlc3VsdCBvZiB0aGUKKyAgICAgKiBtYXRjaC4gRm9yIGV4YW1wbGUsIHdoZW4gdGhlIGlucHV0IGlzICIxMjMiIGFuZCBjdXJyZW50IHBvc2l0aW9uIGlzIGF0IHplcm8sCisgICAgICogPGNvZGU+ZmluZFdpdGhpbkhvcml6b24oUGF0dGVybi5jb21waWxlKCJcXHB7RGlnaXR9ezN9IiksIDIpPC9jb2RlPgorICAgICAqIHdpbGwgcmV0dXJuIHtAY29kZSBudWxsfSwgd2hpbGUKKyAgICAgKiA8Y29kZT5maW5kV2l0aGluSG9yaXpvbihQYXR0ZXJuLmNvbXBpbGUoIlxccHtEaWdpdH17M30iKSwgMyk8L2NvZGU+CisgICAgICogd2lsbCByZXR1cm4ge0Bjb2RlICIxMjMifS4ge0Bjb2RlIGhvcml6b259IGlzIHRyZWF0ZWQgYXMgYSB0cmFuc3BhcmVudCwKKyAgICAgKiBub24tYW5jaG9yaW5nIGJvdW5kLiAocmVmZXIgdG8KKyAgICAgKiB7QGxpbmsgTWF0Y2hlciN1c2VUcmFuc3BhcmVudEJvdW5kcyhib29sZWFuKX0gYW5kCisgICAgICoge0BsaW5rIE1hdGNoZXIjdXNlQW5jaG9yaW5nQm91bmRzKGJvb2xlYW4pfSkKKyAgICAgKiA8cD4KKyAgICAgKiBBIHtAY29kZSBob3Jpem9ufSB3aG9zZSB2YWx1ZSBpcyB6ZXJvIHdpbGwgYmUgaWdub3JlZCBhbmQgdGhlIHdob2xlIGlucHV0IHdpbGwgYmUKKyAgICAgKiB1c2VkIGZvciBzZWFyY2guIEluIHRoaXMgc2l0dWF0aW9uLCBhbGwgdGhlIGlucHV0IG1heSBiZSBjYWNoZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGF0dGVybgorICAgICAqICAgICAgICAgICAgdGhlIHBhdHRlcm4gdXNlZCB0byBzY2FuLgorICAgICAqIEBwYXJhbSBob3Jpem9uCisgICAgICogICAgICAgICAgICB0aGUgc2VhcmNoIGxpbWl0LgorICAgICAqIEByZXR1cm4gdGhlIG1hdGNoZWQgc3RyaW5nIG9yIHtAY29kZSBudWxsfSBpZiB0aGUgcGF0dGVybiBpcyBub3QgZm91bmQKKyAgICAgKiAgICAgICAgIHdpdGhpbiB0aGUgc3BlY2lmaWVkIHtAY29kZSBob3Jpem9ufS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgU2Nhbm5lcn0gaXMgY2xvc2VkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGhvcml6b259IGlzIGxlc3MgdGhhbiB6ZXJvLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZmluZFdpdGhpbkhvcml6b24oUGF0dGVybiBwYXR0ZXJuLCBpbnQgaG9yaXpvbikgeworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICBjaGVja051bGwocGF0dGVybik7CisgICAgICAgIGlmIChob3Jpem9uIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaG9yaXpvbiA8IDAiKTsKKyAgICAgICAgfQorICAgICAgICBtYXRjaGVyLnVzZVBhdHRlcm4ocGF0dGVybik7CisKKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IG51bGw7CisgICAgICAgIGludCBmaW5kRW5kSW5kZXggPSAwOworICAgICAgICBpbnQgaG9yaXpvbkVuZEluZGV4ID0gMDsKKyAgICAgICAgaWYgKGhvcml6b24gPT0gMCkgeworICAgICAgICAgICAgaG9yaXpvbkVuZEluZGV4ID0gSW50ZWdlci5NQVhfVkFMVUU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBob3Jpem9uRW5kSW5kZXggPSBmaW5kU3RhcnRJbmRleCArIGhvcml6b247CisgICAgICAgIH0KKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIGZpbmRFbmRJbmRleCA9IGJ1ZmZlckxlbmd0aDsKKworICAgICAgICAgICAgLy8gSWYgaG9yaXpvbiA+IDAsIHRoZW4gc2VhcmNoIHVwIHRvCisgICAgICAgICAgICAvLyBtaW4oIGJ1ZmZlckxlbmd0aCwgZmluZFN0YXJ0SW5kZXggKyBob3Jpem9uKS4KKyAgICAgICAgICAgIC8vIE90aGVyd2lzZSBzZWFyY2ggdW50aWwgcmVhZGFibGUgaXMgZXhoYXVzdGVkLgorICAgICAgICAgICAgZmluZEVuZEluZGV4ID0gTWF0aC5taW4oaG9yaXpvbkVuZEluZGV4LCBidWZmZXJMZW5ndGgpOworICAgICAgICAgICAgLy8gSWYgaG9yaXpvbiA9PSAwLCBjb25zaWRlciBob3Jpem9uIGFzIGFsd2F5cyBvdXRzaWRlIGJ1ZmZlci4KKyAgICAgICAgICAgIGJvb2xlYW4gaXNIb3Jpem9uSW5CdWZmZXIgPSAoaG9yaXpvbkVuZEluZGV4IDw9IGJ1ZmZlckxlbmd0aCk7CisgICAgICAgICAgICAvLyBGaXJzdCwgdHJ5IHRvIGZpbmQgcGF0dGVybiB3aXRoaW4gYnVmZmVyLiBJZiBwYXR0ZXJuIGNhbiBub3QgYmUKKyAgICAgICAgICAgIC8vIGZvdW5kIGluIGJ1ZmZlciwgdGhlbiBleHBhbmQgdGhlIGJ1ZmZlciBhbmQgdHJ5IGFnYWluLAorICAgICAgICAgICAgLy8gdXRpbCBob3Jpem9uRW5kSW5kZXggaXMgZXhjZWVkZWQgb3Igbm8gbW9yZSBpbnB1dCBsZWZ0LgorICAgICAgICAgICAgbWF0Y2hlci5yZWdpb24oZmluZFN0YXJ0SW5kZXgsIGZpbmRFbmRJbmRleCk7CisgICAgICAgICAgICBpZiAobWF0Y2hlci5maW5kKCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoaXNIb3Jpem9uSW5CdWZmZXIgfHwgaW5wdXRFeGhhdXN0ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbWF0Y2hlci5ncm91cCgpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIFBhdHRlcm4gaXMgbm90IGZvdW5kIGluIGJ1ZmZlciB3aGlsZSBob3Jpem9uRW5kSW5kZXggaXMKKyAgICAgICAgICAgICAgICAvLyB3aXRoaW4gYnVmZmVyLCBvciBpbnB1dCBpcyBleGhhdXN0ZWQuIFVuZGVyIHRoaXMgc2l0dWF0aW9uLAorICAgICAgICAgICAgICAgIC8vIGl0IGNhbiBiZSBqdWRnZWQgdGhhdCBmaW5kIGZhaWxzLgorICAgICAgICAgICAgICAgIGlmIChpc0hvcml6b25JbkJ1ZmZlciB8fCBpbnB1dEV4aGF1c3RlZCkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIEV4cGFuZCBidWZmZXIgYW5kIHJlc2V0IG1hdGNoZXIgaWYgbmVlZGVkLgorICAgICAgICAgICAgaWYgKCFpbnB1dEV4aGF1c3RlZCkgeworICAgICAgICAgICAgICAgIHJlYWRNb3JlKCk7CisgICAgICAgICAgICAgICAgcmVzZXRNYXRjaGVyKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7CisgICAgICAgICAgICBmaW5kU3RhcnRJbmRleCA9IG1hdGNoZXIuZW5kKCk7CisgICAgICAgICAgICBtYXRjaFN1Y2Nlc3NmdWwgPSB0cnVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbWF0Y2hTdWNjZXNzZnVsID0gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmllcyB0byBmaW5kIHRoZSBwYXR0ZXJuIGluIHRoZSBpbnB1dCBiZXR3ZWVuIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCB0aGUgc3BlY2lmaWVkCisgICAgICoge0Bjb2RlIGhvcml6b259LiBEZWxpbWl0ZXJzIGFyZSBpZ25vcmVkLiBUaGlzIGNhbGwgaXMgdGhlIHNhbWUgYXMgaW52b2tpbmcKKyAgICAgKiB7QGNvZGUgZmluZFdpdGhpbkhvcml6b24oUGF0dGVybi5jb21waWxlKHBhdHRlcm4pKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGF0dGVybgorICAgICAqICAgICAgICAgICAgdGhlIHBhdHRlcm4gdXNlZCB0byBzY2FuLgorICAgICAqIEBwYXJhbSBob3Jpem9uCisgICAgICogICAgICAgICAgICB0aGUgc2VhcmNoIGxpbWl0LgorICAgICAqIEByZXR1cm4gdGhlIG1hdGNoZWQgc3RyaW5nLCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIHBhdHRlcm4gaXMgbm90IGZvdW5kCisgICAgICogICAgICAgICB3aXRoaW4gdGhlIHNwZWNpZmllZCBob3Jpem9uLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBTY2FubmVyfSBpcyBjbG9zZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaG9yaXpvbn0gaXMgbGVzcyB0aGFuIHplcm8uCisgICAgICogQHNlZSAjZmluZFdpdGhpbkhvcml6b24oUGF0dGVybiwgaW50KQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZmluZFdpdGhpbkhvcml6b24oU3RyaW5nIHBhdHRlcm4sIGludCBob3Jpem9uKSB7CisgICAgICAgIHJldHVybiBmaW5kV2l0aGluSG9yaXpvbihQYXR0ZXJuLmNvbXBpbGUocGF0dGVybiksIGhvcml6b24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIHtAY29kZSBTY2FubmVyfSBoYXMgb25lIG9yIG1vcmUgdG9rZW5zIHJlbWFpbmluZyB0byBwYXJzZS4KKyAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGJsb2NrIGlmIHRoZSBkYXRhIGlzIHN0aWxsIGJlaW5nIHJlYWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBTY2FubmVyfSBoYXMgb25lIG9yIG1vcmUgdG9rZW5zIHJlbWFpbmluZywKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBTY2FubmVyfSBoYXMgYmVlbiBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgcmV0dXJuIGhhc05leHQoQU5ZX1BBVFRFUk4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIHtAY29kZSBTY2FubmVyfSBoYXMgb25lIG9yIG1vcmUgdG9rZW5zIHJlbWFpbmluZyB0byBwYXJzZQorICAgICAqIGFuZCB0aGUgbmV4dCB0b2tlbiBtYXRjaGVzIHRoZSBnaXZlbiBwYXR0ZXJuLiBUaGlzIG1ldGhvZCB3aWxsIGJsb2NrIGlmIHRoZSBkYXRhIGlzCisgICAgICogc3RpbGwgYmVpbmcgcmVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXR0ZXJuCisgICAgICogICAgICAgICAgICB0aGUgcGF0dGVybiB0byBjaGVjayBmb3IuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgU2Nhbm5lcn0gaGFzIG1vcmUgdG9rZW5zIGFuZCB0aGUgbmV4dCB0b2tlbgorICAgICAqICAgICAgICAgbWF0Y2hlcyB0aGUgcGF0dGVybiwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIFNjYW5uZXJ9IGhhcyBiZWVuIGNsb3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KFBhdHRlcm4gcGF0dGVybikgeworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICBjaGVja051bGwocGF0dGVybik7CisgICAgICAgIG1hdGNoU3VjY2Vzc2Z1bCA9IGZhbHNlOworICAgICAgICBzYXZlQ3VycmVudFN0YXR1cygpOworICAgICAgICAvLyBpZiB0aGUgbmV4dCB0b2tlbiBleGlzdHMsIHNldCB0aGUgbWF0Y2ggcmVnaW9uLCBvdGhlcndpc2UgcmV0dXJuCisgICAgICAgIC8vIGZhbHNlCisgICAgICAgIGlmICghc2V0VG9rZW5SZWdpb24oKSkgeworICAgICAgICAgICAgcmVjb3ZlclByZXZpb3VzU3RhdHVzKCk7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgbWF0Y2hlci51c2VQYXR0ZXJuKHBhdHRlcm4pOworICAgICAgICBib29sZWFuIGhhc05leHQgPSBmYWxzZTsKKyAgICAgICAgLy8gY2hlY2sgd2hldGhlciBuZXh0IHRva2VuIG1hdGNoZXMgdGhlIHNwZWNpZmllZCBwYXR0ZXJuCisgICAgICAgIGlmIChtYXRjaGVyLm1hdGNoZXMoKSkgeworICAgICAgICAgICAgY2FjaGVoYXNOZXh0SW5kZXggPSBmaW5kU3RhcnRJbmRleDsKKyAgICAgICAgICAgIG1hdGNoU3VjY2Vzc2Z1bCA9IHRydWU7CisgICAgICAgICAgICBoYXNOZXh0ID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZWNvdmVyUHJldmlvdXNTdGF0dXMoKTsKKyAgICAgICAgcmV0dXJuIGhhc05leHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgU2Nhbm5lcn0gaGFzIG9uZSBvciBtb3JlIHRva2VucyByZW1haW5pbmcgdG8gcGFyc2UKKyAgICAgKiBhbmQgdGhlIG5leHQgdG9rZW4gbWF0Y2hlcyBhIHBhdHRlcm4gY29tcGlsZWQgZnJvbSB0aGUgZ2l2ZW4gc3RyaW5nLiBUaGlzIG1ldGhvZCB3aWxsCisgICAgICogYmxvY2sgaWYgdGhlIGRhdGEgaXMgc3RpbGwgYmVpbmcgcmVhZC4gVGhpcyBjYWxsIGlzIGVxdWl2YWxlbnQgdG8KKyAgICAgKiB7QGNvZGUgaGFzTmV4dChQYXR0ZXJuLmNvbXBpbGUocGF0dGVybikpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXR0ZXJuCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHNwZWNpZnlpbmcgdGhlIHBhdHRlcm4gdG8gc2NhbiBmb3IKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIHBhdHRlcm4gbWF0Y2hlcyB0aGlzIHtAY29kZSBTY2FubmVyfSdzCisgICAgICogICAgICAgICBuZXh0IHRva2VuLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgU2Nhbm5lcn0gaGFzIGJlZW4gY2xvc2VkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoU3RyaW5nIHBhdHRlcm4pIHsKKyAgICAgICAgcmV0dXJuIGhhc05leHQoUGF0dGVybi5jb21waWxlKHBhdHRlcm4pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIG5leHQgdG9rZW4gY2FuIGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkCisgICAgICoge0Bjb2RlIEJpZ0RlY2ltYWx9LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIG5leHQgdG9rZW4gY2FuIGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkCisgICAgICogICAgICAgICB7QGNvZGUgQmlnRGVjaW1hbH0sIG90aGVyd2lzZSB7QGNvZGUgZmFsc2UufQorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBTY2FubmVyfSBoYXMgYmVlbiBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dEJpZ0RlY2ltYWwoKSB7CisgICAgICAgIFBhdHRlcm4gZmxvYXRQYXR0ZXJuID0gZ2V0RmxvYXRQYXR0ZXJuKCk7CisgICAgICAgIGJvb2xlYW4gaXNCaWdEZWNpbWFsVmFsdWUgPSBmYWxzZTsKKyAgICAgICAgaWYgKGhhc05leHQoZmxvYXRQYXR0ZXJuKSkgeworICAgICAgICAgICAgU3RyaW5nIGZsb2F0U3RyaW5nID0gbWF0Y2hlci5ncm91cCgpOworICAgICAgICAgICAgZmxvYXRTdHJpbmcgPSByZW1vdmVMb2NhbGVJbmZvRnJvbUZsb2F0KGZsb2F0U3RyaW5nKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2FjaGVIYXNOZXh0VmFsdWUgPSBuZXcgQmlnRGVjaW1hbChmbG9hdFN0cmluZyk7CisgICAgICAgICAgICAgICAgaXNCaWdEZWNpbWFsVmFsdWUgPSB0cnVlOworICAgICAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBtYXRjaFN1Y2Nlc3NmdWwgPSBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaXNCaWdEZWNpbWFsVmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBuZXh0IHRva2VuIGNhbiBiZSB0cmFuc2xhdGVkIGludG8gYSB2YWxpZAorICAgICAqIHtAY29kZSBCaWdJbnRlZ2VyfSBpbiB0aGUgZGVmYXVsdCByYWRpeC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBuZXh0IHRva2VuIGNhbiBiZSB0cmFuc2xhdGVkIGludG8gYSB2YWxpZAorICAgICAqICAgICAgICAge0Bjb2RlIEJpZ0ludGVnZXJ9LCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgU2Nhbm5lcn0gaGFzIGJlZW4gY2xvc2VkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc05leHRCaWdJbnRlZ2VyKCkgeworICAgICAgICByZXR1cm4gaGFzTmV4dEJpZ0ludGVnZXIoaW50ZWdlclJhZGl4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIG5leHQgdG9rZW4gY2FuIGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkCisgICAgICoge0Bjb2RlIEJpZ0ludGVnZXJ9IGluIHRoZSBzcGVjaWZpZWQgcmFkaXguCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmFkaXgKKyAgICAgKiAgICAgICAgICAgIHRoZSByYWRpeCB1c2VkIHRvIHRyYW5zbGF0ZSB0aGUgdG9rZW4gaW50byBhCisgICAgICogICAgICAgICAgICB7QGNvZGUgQmlnSW50ZWdlcn0uCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIG5leHQgdG9rZW4gY2FuIGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkCisgICAgICogICAgICAgICB7QGNvZGUgQmlnSW50ZWdlcn0sIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBTY2FubmVyfSBoYXMgYmVlbiBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dEJpZ0ludGVnZXIoaW50IHJhZGl4KSB7CisgICAgICAgIFBhdHRlcm4gaW50ZWdlclBhdHRlcm4gPSBnZXRJbnRlZ2VyUGF0dGVybihyYWRpeCk7CisgICAgICAgIGJvb2xlYW4gaXNCaWdJbnRlZ2VyVmFsdWUgPSBmYWxzZTsKKyAgICAgICAgaWYgKGhhc05leHQoaW50ZWdlclBhdHRlcm4pKSB7CisgICAgICAgICAgICBTdHJpbmcgaW50U3RyaW5nID0gbWF0Y2hlci5ncm91cCgpOworICAgICAgICAgICAgaW50U3RyaW5nID0gcmVtb3ZlTG9jYWxlSW5mbyhpbnRTdHJpbmcsIERhdGFUeXBlLklOVCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNhY2hlSGFzTmV4dFZhbHVlID0gbmV3IEJpZ0ludGVnZXIoaW50U3RyaW5nLCByYWRpeCk7CisgICAgICAgICAgICAgICAgaXNCaWdJbnRlZ2VyVmFsdWUgPSB0cnVlOworICAgICAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBtYXRjaFN1Y2Nlc3NmdWwgPSBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaXNCaWdJbnRlZ2VyVmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBuZXh0IHRva2VuIGNhbiBiZSB0cmFuc2xhdGVkIGludG8gYSB2YWxpZAorICAgICAqIHtAY29kZSBib29sZWFufSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBuZXh0IHRva2VuIGNhbiBiZSB0cmFuc2xhdGVkIGludG8gYSB2YWxpZAorICAgICAqICAgICAgICAge0Bjb2RlIGJvb2xlYW59IHZhbHVlLCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgU2Nhbm5lcn0gaGFzIGJlZW4gY2xvc2VkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc05leHRCb29sZWFuKCkgeworICAgICAgICByZXR1cm4gaGFzTmV4dChCT09MRUFOX1BBVFRFUk4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgbmV4dCB0b2tlbiBjYW4gYmUgdHJhbnNsYXRlZCBpbnRvIGEgdmFsaWQKKyAgICAgKiB7QGNvZGUgYnl0ZX0gdmFsdWUgaW4gdGhlIGRlZmF1bHQgcmFkaXguCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgbmV4dCB0b2tlbiBjYW4gYmUgdHJhbnNsYXRlZCBpbnRvIGEgdmFsaWQKKyAgICAgKiAgICAgICAgIHtAY29kZSBieXRlfSB2YWx1ZSwgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIFNjYW5uZXJ9IGhhcyBiZWVuIGNsb3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0Qnl0ZSgpIHsKKyAgICAgICAgcmV0dXJuIGhhc05leHRCeXRlKGludGVnZXJSYWRpeCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBuZXh0IHRva2VuIGNhbiBiZSB0cmFuc2xhdGVkIGludG8gYSB2YWxpZAorICAgICAqIHtAY29kZSBieXRlfSB2YWx1ZSBpbiB0aGUgc3BlY2lmaWVkIHJhZGl4LgorICAgICAqCisgICAgICogQHBhcmFtIHJhZGl4CisgICAgICogICAgICAgICAgICB0aGUgcmFkaXggdXNlZCB0byB0cmFuc2xhdGUgdGhlIHRva2VuIGludG8gYSB7QGNvZGUgYnl0ZX0KKyAgICAgKiAgICAgICAgICAgIHZhbHVlCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIG5leHQgdG9rZW4gY2FuIGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkCisgICAgICogICAgICAgICB7QGNvZGUgYnl0ZX0gdmFsdWUsIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBTY2FubmVyfSBoYXMgYmVlbiBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dEJ5dGUoaW50IHJhZGl4KSB7CisgICAgICAgIFBhdHRlcm4gaW50ZWdlclBhdHRlcm4gPSBnZXRJbnRlZ2VyUGF0dGVybihyYWRpeCk7CisgICAgICAgIGJvb2xlYW4gaXNCeXRlVmFsdWUgPSBmYWxzZTsKKyAgICAgICAgaWYgKGhhc05leHQoaW50ZWdlclBhdHRlcm4pKSB7CisgICAgICAgICAgICBTdHJpbmcgaW50U3RyaW5nID0gbWF0Y2hlci5ncm91cCgpOworICAgICAgICAgICAgaW50U3RyaW5nID0gcmVtb3ZlTG9jYWxlSW5mbyhpbnRTdHJpbmcsIERhdGFUeXBlLklOVCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNhY2hlSGFzTmV4dFZhbHVlID0gQnl0ZS52YWx1ZU9mKGludFN0cmluZywgcmFkaXgpOworICAgICAgICAgICAgICAgIGlzQnl0ZVZhbHVlID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgbWF0Y2hTdWNjZXNzZnVsID0gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlzQnl0ZVZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgbmV4dCB0b2tlbiB0cmFuc2xhdGVkIGludG8gYSB2YWxpZCB7QGNvZGUgZG91YmxlfQorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIG5leHQgdG9rZW4gY2FuIGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkCisgICAgICogICAgICAgICB7QGNvZGUgZG91YmxlfSB2YWx1ZSwgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIFNjYW5uZXJ9IGhhcyBiZWVuIGNsb3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0RG91YmxlKCkgeworICAgICAgICBQYXR0ZXJuIGZsb2F0UGF0dGVybiA9IGdldEZsb2F0UGF0dGVybigpOworICAgICAgICBib29sZWFuIGlzRG91YmxlVmFsdWUgPSBmYWxzZTsKKyAgICAgICAgaWYgKGhhc05leHQoZmxvYXRQYXR0ZXJuKSkgeworICAgICAgICAgICAgU3RyaW5nIGZsb2F0U3RyaW5nID0gbWF0Y2hlci5ncm91cCgpOworICAgICAgICAgICAgZmxvYXRTdHJpbmcgPSByZW1vdmVMb2NhbGVJbmZvRnJvbUZsb2F0KGZsb2F0U3RyaW5nKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2FjaGVIYXNOZXh0VmFsdWUgPSBEb3VibGUudmFsdWVPZihmbG9hdFN0cmluZyk7CisgICAgICAgICAgICAgICAgaXNEb3VibGVWYWx1ZSA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIG1hdGNoU3VjY2Vzc2Z1bCA9IGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBpc0RvdWJsZVZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgbmV4dCB0b2tlbiBjYW4gYmUgdHJhbnNsYXRlZCBpbnRvIGEgdmFsaWQKKyAgICAgKiB7QGNvZGUgZmxvYXR9IHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIG5leHQgdG9rZW4gY2FuIGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkCisgICAgICogICAgICAgICB7QGNvZGUgZmxvYXR9IHZhbHVlLCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgU2Nhbm5lcn0gaGFzIGJlZW4gY2xvc2VkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc05leHRGbG9hdCgpIHsKKyAgICAgICAgUGF0dGVybiBmbG9hdFBhdHRlcm4gPSBnZXRGbG9hdFBhdHRlcm4oKTsKKyAgICAgICAgYm9vbGVhbiBpc0Zsb2F0VmFsdWUgPSBmYWxzZTsKKyAgICAgICAgaWYgKGhhc05leHQoZmxvYXRQYXR0ZXJuKSkgeworICAgICAgICAgICAgU3RyaW5nIGZsb2F0U3RyaW5nID0gbWF0Y2hlci5ncm91cCgpOworICAgICAgICAgICAgZmxvYXRTdHJpbmcgPSByZW1vdmVMb2NhbGVJbmZvRnJvbUZsb2F0KGZsb2F0U3RyaW5nKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2FjaGVIYXNOZXh0VmFsdWUgPSBGbG9hdC52YWx1ZU9mKGZsb2F0U3RyaW5nKTsKKyAgICAgICAgICAgICAgICBpc0Zsb2F0VmFsdWUgPSB0cnVlOworICAgICAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBtYXRjaFN1Y2Nlc3NmdWwgPSBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaXNGbG9hdFZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgbmV4dCB0b2tlbiBjYW4gYmUgdHJhbnNsYXRlZCBpbnRvIGEgdmFsaWQge0Bjb2RlIGludH0KKyAgICAgKiB2YWx1ZSBpbiB0aGUgZGVmYXVsdCByYWRpeC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBuZXh0IHRva2VuIGNhbiBiZSB0cmFuc2xhdGVkIGludG8gYSB2YWxpZAorICAgICAqICAgICAgICAge0Bjb2RlIGludH0gdmFsdWUsIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBTY2FubmVyfSBoYXMgYmVlbiBjbG9zZWQsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dEludCgpIHsKKyAgICAgICAgcmV0dXJuIGhhc05leHRJbnQoaW50ZWdlclJhZGl4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIG5leHQgdG9rZW4gY2FuIGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkIHtAY29kZSBpbnR9CisgICAgICogdmFsdWUgaW4gdGhlIHNwZWNpZmllZCByYWRpeC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByYWRpeAorICAgICAqICAgICAgICAgICAgdGhlIHJhZGl4IHVzZWQgdG8gdHJhbnNsYXRlIHRoZSB0b2tlbiBpbnRvIGFuIHtAY29kZSBpbnR9CisgICAgICogICAgICAgICAgICB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgbmV4dCB0b2tlbiBpbiB0aGlzIHtAY29kZSBTY2FubmVyfSdzIGlucHV0IGNhbiBiZQorICAgICAqICAgICAgICAgdHJhbnNsYXRlZCBpbnRvIGEgdmFsaWQge0Bjb2RlIGludH0gdmFsdWUsIG90aGVyd2lzZQorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgU2Nhbm5lcn0gaGFzIGJlZW4gY2xvc2VkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc05leHRJbnQoaW50IHJhZGl4KSB7CisgICAgICAgIFBhdHRlcm4gaW50ZWdlclBhdHRlcm4gPSBnZXRJbnRlZ2VyUGF0dGVybihyYWRpeCk7CisgICAgICAgIGJvb2xlYW4gaXNJbnRWYWx1ZSA9IGZhbHNlOworICAgICAgICBpZiAoaGFzTmV4dChpbnRlZ2VyUGF0dGVybikpIHsKKyAgICAgICAgICAgIFN0cmluZyBpbnRTdHJpbmcgPSBtYXRjaGVyLmdyb3VwKCk7CisgICAgICAgICAgICBpbnRTdHJpbmcgPSByZW1vdmVMb2NhbGVJbmZvKGludFN0cmluZywgRGF0YVR5cGUuSU5UKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2FjaGVIYXNOZXh0VmFsdWUgPSBJbnRlZ2VyLnZhbHVlT2YoaW50U3RyaW5nLCByYWRpeCk7CisgICAgICAgICAgICAgICAgaXNJbnRWYWx1ZSA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIG1hdGNoU3VjY2Vzc2Z1bCA9IGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBpc0ludFZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGVyZSBpcyBhIGxpbmUgdGVybWluYXRvciBpbiB0aGUgaW5wdXQuCisgICAgICogVGhpcyBtZXRob2QgbWF5IGJsb2NrLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlcmUgaXMgYSBsaW5lIHRlcm1pbmF0b3IgaW4gdGhlIGlucHV0LAorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLCB7QGNvZGUgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBTY2FubmVyfSBpcyBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dExpbmUoKSB7CisgICAgICAgIGNoZWNrQ2xvc2VkKCk7CisgICAgICAgIG1hdGNoZXIudXNlUGF0dGVybihMSU5FX1BBVFRFUk4pOworICAgICAgICBtYXRjaGVyLnJlZ2lvbihmaW5kU3RhcnRJbmRleCwgYnVmZmVyTGVuZ3RoKTsKKworICAgICAgICBib29sZWFuIGhhc05leHRMaW5lID0gZmFsc2U7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBpZiAobWF0Y2hlci5maW5kKCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoaW5wdXRFeGhhdXN0ZWQgfHwgbWF0Y2hlci5lbmQoKSAhPSBidWZmZXJMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgbWF0Y2hTdWNjZXNzZnVsID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgaGFzTmV4dExpbmUgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmIChpbnB1dEV4aGF1c3RlZCkgeworICAgICAgICAgICAgICAgICAgICBtYXRjaFN1Y2Nlc3NmdWwgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFpbnB1dEV4aGF1c3RlZCkgeworICAgICAgICAgICAgICAgIHJlYWRNb3JlKCk7CisgICAgICAgICAgICAgICAgcmVzZXRNYXRjaGVyKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGhhc05leHRMaW5lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgbmV4dCB0b2tlbiBjYW4gYmUgdHJhbnNsYXRlZCBpbnRvIGEgdmFsaWQKKyAgICAgKiB7QGNvZGUgbG9uZ30gdmFsdWUgaW4gdGhlIGRlZmF1bHQgcmFkaXguCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgbmV4dCB0b2tlbiBjYW4gYmUgdHJhbnNsYXRlZCBpbnRvIGEgdmFsaWQKKyAgICAgKiAgICAgICAgIHtAY29kZSBsb25nfSB2YWx1ZSwgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIFNjYW5uZXJ9IGhhcyBiZWVuIGNsb3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0TG9uZygpIHsKKyAgICAgICAgcmV0dXJuIGhhc05leHRMb25nKGludGVnZXJSYWRpeCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBuZXh0IHRva2VuIGNhbiBiZSB0cmFuc2xhdGVkIGludG8gYSB2YWxpZAorICAgICAqIHtAY29kZSBsb25nfSB2YWx1ZSBpbiB0aGUgc3BlY2lmaWVkIHJhZGl4LgorICAgICAqCisgICAgICogQHBhcmFtIHJhZGl4CisgICAgICogICAgICAgICAgICB0aGUgcmFkaXggdXNlZCB0byB0cmFuc2xhdGUgdGhlIHRva2VuIGludG8gYSB7QGNvZGUgbG9uZ30KKyAgICAgKiAgICAgICAgICAgIHZhbHVlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBuZXh0IHRva2VuIGNhbiBiZSB0cmFuc2xhdGVkIGludG8gYSB2YWxpZAorICAgICAqICAgICAgICAge0Bjb2RlIGxvbmd9IHZhbHVlLCBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgU2Nhbm5lcn0gaGFzIGJlZW4gY2xvc2VkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc05leHRMb25nKGludCByYWRpeCkgeworICAgICAgICBQYXR0ZXJuIGludGVnZXJQYXR0ZXJuID0gZ2V0SW50ZWdlclBhdHRlcm4ocmFkaXgpOworICAgICAgICBib29sZWFuIGlzTG9uZ1ZhbHVlID0gZmFsc2U7CisgICAgICAgIGlmIChoYXNOZXh0KGludGVnZXJQYXR0ZXJuKSkgeworICAgICAgICAgICAgU3RyaW5nIGludFN0cmluZyA9IG1hdGNoZXIuZ3JvdXAoKTsKKyAgICAgICAgICAgIGludFN0cmluZyA9IHJlbW92ZUxvY2FsZUluZm8oaW50U3RyaW5nLCBEYXRhVHlwZS5JTlQpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjYWNoZUhhc05leHRWYWx1ZSA9IExvbmcudmFsdWVPZihpbnRTdHJpbmcsIHJhZGl4KTsKKyAgICAgICAgICAgICAgICBpc0xvbmdWYWx1ZSA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIG1hdGNoU3VjY2Vzc2Z1bCA9IGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBpc0xvbmdWYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIG5leHQgdG9rZW4gY2FuIGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkCisgICAgICoge0Bjb2RlIHNob3J0fSB2YWx1ZSBpbiB0aGUgZGVmYXVsdCByYWRpeC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBuZXh0IHRva2VuIGNhbiBiZSB0cmFuc2xhdGVkIGludG8gYSB2YWxpZAorICAgICAqICAgICAgICAge0Bjb2RlIHNob3J0fSB2YWx1ZSwgb3RoZXJ3aXNlIHtAY29kZSBmYWxzZX0uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIFNjYW5uZXJ9IGhhcyBiZWVuIGNsb3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0U2hvcnQoKSB7CisgICAgICAgIHJldHVybiBoYXNOZXh0U2hvcnQoaW50ZWdlclJhZGl4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIG5leHQgdG9rZW4gY2FuIGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkCisgICAgICoge0Bjb2RlIHNob3J0fSB2YWx1ZSBpbiB0aGUgc3BlY2lmaWVkIHJhZGl4LgorICAgICAqCisgICAgICogQHBhcmFtIHJhZGl4CisgICAgICogICAgICAgICAgICB0aGUgcmFkaXggdXNlZCB0byB0cmFuc2xhdGUgdGhlIHRva2VuIGludG8gYSB7QGNvZGUgc2hvcnR9CisgICAgICogICAgICAgICAgICB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgbmV4dCB0b2tlbiBjYW4gYmUgdHJhbnNsYXRlZCBpbnRvIGEgdmFsaWQKKyAgICAgKiAgICAgICAgIHtAY29kZSBzaG9ydH0gdmFsdWUsIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBTY2FubmVyfSBoYXMgYmVlbiBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dFNob3J0KGludCByYWRpeCkgeworICAgICAgICBQYXR0ZXJuIGludGVnZXJQYXR0ZXJuID0gZ2V0SW50ZWdlclBhdHRlcm4ocmFkaXgpOworICAgICAgICBib29sZWFuIGlzU2hvcnRWYWx1ZSA9IGZhbHNlOworICAgICAgICBpZiAoaGFzTmV4dChpbnRlZ2VyUGF0dGVybikpIHsKKyAgICAgICAgICAgIFN0cmluZyBpbnRTdHJpbmcgPSBtYXRjaGVyLmdyb3VwKCk7CisgICAgICAgICAgICBpbnRTdHJpbmcgPSByZW1vdmVMb2NhbGVJbmZvKGludFN0cmluZywgRGF0YVR5cGUuSU5UKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2FjaGVIYXNOZXh0VmFsdWUgPSBTaG9ydC52YWx1ZU9mKGludFN0cmluZywgcmFkaXgpOworICAgICAgICAgICAgICAgIGlzU2hvcnRWYWx1ZSA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIG1hdGNoU3VjY2Vzc2Z1bCA9IGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBpc1Nob3J0VmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGFzdCB7QGNvZGUgSU9FeGNlcHRpb259IHRoYXQgd2FzIHJhaXNlZCB3aGlsZSByZWFkaW5nIGZyb20gdGhlIHVuZGVybHlpbmcKKyAgICAgKiBpbnB1dC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxhc3QgdGhyb3duIHtAY29kZSBJT0V4Y2VwdGlvbn0sIG9yIHtAY29kZSBudWxsfSBpZiBub25lIHdhcyB0aHJvd24uCisgICAgICovCisgICAgcHVibGljIElPRXhjZXB0aW9uIGlvRXhjZXB0aW9uKCkgeworICAgICAgICByZXR1cm4gbGFzdElPRXhjZXB0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUge0Bjb2RlIExvY2FsZX0gb2YgdGhpcyB7QGNvZGUgU2Nhbm5lcn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgTG9jYWxlfSBvZiB0aGlzIHtAY29kZSBTY2FubmVyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTG9jYWxlIGxvY2FsZSgpIHsKKyAgICAgICAgcmV0dXJuIGxvY2FsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIGxhc3QgbWF0Y2hpbmcgb3BlcmF0aW9uLgorICAgICAqIDxwPgorICAgICAqIFRoZSBuZXh0KiBhbmQgZmluZCogbWV0aG9kcyByZXR1cm4gdGhlIG1hdGNoIHJlc3VsdCBpbiB0aGUgY2FzZSBvZiBhCisgICAgICogc3VjY2Vzc2Z1bCBtYXRjaC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1hdGNoIHJlc3VsdCBvZiB0aGUgbGFzdCBzdWNjZXNzZnVsIG1hdGNoIG9wZXJhdGlvbgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG1hdGNoIHJlc3VsdCBpcyBub3QgYXZhaWxhYmxlLCBvZiBpZiB0aGUgbGFzdCBtYXRjaAorICAgICAqICAgICAgICAgICAgIHdhcyBub3Qgc3VjY2Vzc2Z1bC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWF0Y2hSZXN1bHQgbWF0Y2goKSB7CisgICAgICAgIGlmICghbWF0Y2hTdWNjZXNzZnVsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG1hdGNoZXIudG9NYXRjaFJlc3VsdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgdG9rZW4uIFRoZSB0b2tlbiB3aWxsIGJlIGJvdGggcHJlZml4ZWQgYW5kIHBvc3RmaXhlZCBieQorICAgICAqIHRoZSBkZWxpbWl0ZXIgdGhhdCBpcyBjdXJyZW50bHkgYmVpbmcgdXNlZCAob3IgYSBzdHJpbmcgdGhhdCBtYXRjaGVzIHRoZQorICAgICAqIGRlbGltaXRlciBwYXR0ZXJuKS4gVGhpcyBtZXRob2Qgd2lsbCBibG9jayBpZiBpbnB1dCBpcyBiZWluZyByZWFkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBjb21wbGV0ZSB0b2tlbi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIFNjYW5uZXJ9IGhhcyBiZWVuIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBpbnB1dCBoYXMgYmVlbiBleGhhdXN0ZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBuZXh0KCkgeworICAgICAgICByZXR1cm4gbmV4dChBTllfUEFUVEVSTik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCB0b2tlbiBpZiBpdCBtYXRjaGVzIHRoZSBzcGVjaWZpZWQgcGF0dGVybi4gVGhlIHRva2VuCisgICAgICogd2lsbCBiZSBib3RoIHByZWZpeGVkIGFuZCBwb3N0Zml4ZWQgYnkgdGhlIGRlbGltaXRlciB0aGF0IGlzIGN1cnJlbnRseQorICAgICAqIGJlaW5nIHVzZWQgKG9yIGEgc3RyaW5nIHRoYXQgbWF0Y2hlcyB0aGUgZGVsaW1pdGVyIHBhdHRlcm4pLiBUaGlzIG1ldGhvZCB3aWxsIGJsb2NrCisgICAgICogaWYgaW5wdXQgaXMgYmVpbmcgcmVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXR0ZXJuCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIHBhdHRlcm4gdG8gc2Nhbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IHRva2VuLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgU2Nhbm5lcn0gaGFzIGJlZW4gY2xvc2VkLgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGlucHV0IGhhcyBiZWVuIGV4aGF1c3RlZC4KKyAgICAgKiBAdGhyb3dzIElucHV0TWlzbWF0Y2hFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbmV4dCB0b2tlbiBkb2VzIG5vdCBtYXRjaCB0aGUgcGF0dGVybiBnaXZlbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIG5leHQoUGF0dGVybiBwYXR0ZXJuKSB7CisgICAgICAgIGNoZWNrQ2xvc2VkKCk7CisgICAgICAgIGNoZWNrTnVsbChwYXR0ZXJuKTsKKyAgICAgICAgbWF0Y2hTdWNjZXNzZnVsID0gZmFsc2U7CisgICAgICAgIHNhdmVDdXJyZW50U3RhdHVzKCk7CisgICAgICAgIGlmICghc2V0VG9rZW5SZWdpb24oKSkgeworICAgICAgICAgICAgcmVjb3ZlclByZXZpb3VzU3RhdHVzKCk7CisgICAgICAgICAgICAvLyBpZiBzZXR0aW5nIG1hdGNoIHJlZ2lvbiBmYWlscworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBtYXRjaGVyLnVzZVBhdHRlcm4ocGF0dGVybik7CisgICAgICAgIGlmICghbWF0Y2hlci5tYXRjaGVzKCkpIHsKKyAgICAgICAgICAgIHJlY292ZXJQcmV2aW91c1N0YXR1cygpOworICAgICAgICAgICAgdGhyb3cgbmV3IElucHV0TWlzbWF0Y2hFeGNlcHRpb24oKTsKKworICAgICAgICB9CisgICAgICAgIG1hdGNoU3VjY2Vzc2Z1bCA9IHRydWU7CisgICAgICAgIHJldHVybiBtYXRjaGVyLmdyb3VwKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCB0b2tlbiBpZiBpdCBtYXRjaGVzIHRoZSBzcGVjaWZpZWQgcGF0dGVybi4gVGhlIHRva2VuCisgICAgICogd2lsbCBiZSBib3RoIHByZWZpeGVkIGFuZCBwb3N0Zml4ZWQgYnkgdGhlIGRlbGltaXRlciB0aGF0IGlzIGN1cnJlbnRseQorICAgICAqIGJlaW5nIHVzZWQgKG9yIGEgc3RyaW5nIHRoYXQgbWF0Y2hlcyB0aGUgZGVsaW1pdGVyIHBhdHRlcm4pLiBUaGlzIG1ldGhvZCB3aWxsIGJsb2NrCisgICAgICogaWYgaW5wdXQgaXMgYmVpbmcgcmVhZC4gQ2FsbGluZyB0aGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvCisgICAgICoge0Bjb2RlIG5leHQoUGF0dGVybi5jb21waWxlKHBhdHRlcm4pKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGF0dGVybgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyBzcGVjaWZ5aW5nIHRoZSBwYXR0ZXJuIHRvIHNjYW4gZm9yLgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgdG9rZW4uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBTY2FubmVyfSBoYXMgYmVlbiBjbG9zZWQuCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgaW5wdXQgaGFzIGJlZW4gZXhoYXVzdGVkLgorICAgICAqIEB0aHJvd3MgSW5wdXRNaXNtYXRjaEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBuZXh0IHRva2VuIGRvZXMgbm90IG1hdGNoIHRoZSBwYXR0ZXJuIGdpdmVuLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgbmV4dChTdHJpbmcgcGF0dGVybikgeworICAgICAgICByZXR1cm4gbmV4dChQYXR0ZXJuLmNvbXBpbGUocGF0dGVybikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgdG9rZW4gYXMgYSB7QGNvZGUgQmlnRGVjaW1hbH0uIFRoaXMgbWV0aG9kIHdpbGwgYmxvY2sgaWYgaW5wdXQgaXMKKyAgICAgKiBiZWluZyByZWFkLiBJZiB0aGUgbmV4dCB0b2tlbiBjYW4gYmUgdHJhbnNsYXRlZCBpbnRvIGEge0Bjb2RlIEJpZ0RlY2ltYWx9CisgICAgICogdGhlIGZvbGxvd2luZyBpcyBkb25lOiBBbGwge0Bjb2RlIExvY2FsZX0tc3BlY2lmaWMgcHJlZml4ZXMsIGdyb3VwIHNlcGFyYXRvcnMsCisgICAgICogYW5kIHtAY29kZSBMb2NhbGV9LXNwZWNpZmljIHN1ZmZpeGVzIGFyZSByZW1vdmVkLiBUaGVuIG5vbi1BU0NJSSBkaWdpdHMgYXJlCisgICAgICogbWFwcGVkIGludG8gQVNDSUkgZGlnaXRzIHZpYSB7QGxpbmsgQ2hhcmFjdGVyI2RpZ2l0KGNoYXIsIGludCl9LCBhbmQgYQorICAgICAqIG5lZ2F0aXZlIHNpZ24gKC0pIGlzIGFkZGVkIGlmIHRoZSB7QGNvZGUgTG9jYWxlfS1zcGVjaWZpYyBuZWdhdGl2ZSBwcmVmaXggb3IKKyAgICAgKiBzdWZmaXggd2FzIHByZXNlbnQuIEZpbmFsbHkgdGhlIHJlc3VsdGluZyBzdHJpbmcgaXMgcGFzc2VkIHRvCisgICAgICoge0Bjb2RlIEJpZ0RlY2ltYWwoU3RyaW5nKSB9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCB0b2tlbiBhcyBhIHtAY29kZSBCaWdEZWNpbWFsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIFNjYW5uZXJ9IGhhcyBiZWVuIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBpbnB1dCBoYXMgYmVlbiBleGhhdXN0ZWQuCisgICAgICogQHRocm93cyBJbnB1dE1pc21hdGNoRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG5leHQgdG9rZW4gY2FuIG5vdCBiZSB0cmFuc2xhdGVkIGludG8gYSB2YWxpZAorICAgICAqICAgICAgICAgICAgIHtAY29kZSBCaWdEZWNpbWFsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnRGVjaW1hbCBuZXh0QmlnRGVjaW1hbCgpIHsKKyAgICAgICAgY2hlY2tDbG9zZWQoKTsKKyAgICAgICAgT2JqZWN0IG9iaiA9IGNhY2hlSGFzTmV4dFZhbHVlOworICAgICAgICBjYWNoZUhhc05leHRWYWx1ZSA9IG51bGw7CisgICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBCaWdEZWNpbWFsKSB7CisgICAgICAgICAgICBmaW5kU3RhcnRJbmRleCA9IGNhY2hlaGFzTmV4dEluZGV4OworICAgICAgICAgICAgcmV0dXJuIChCaWdEZWNpbWFsKSBvYmo7CisgICAgICAgIH0KKyAgICAgICAgUGF0dGVybiBmbG9hdFBhdHRlcm4gPSBnZXRGbG9hdFBhdHRlcm4oKTsKKyAgICAgICAgU3RyaW5nIGZsb2F0U3RyaW5nID0gbmV4dChmbG9hdFBhdHRlcm4pOworICAgICAgICBmbG9hdFN0cmluZyA9IHJlbW92ZUxvY2FsZUluZm9Gcm9tRmxvYXQoZmxvYXRTdHJpbmcpOworICAgICAgICBCaWdEZWNpbWFsIGJpZ0RlY2ltYWxWYWx1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJpZ0RlY2ltYWxWYWx1ZSA9IG5ldyBCaWdEZWNpbWFsKGZsb2F0U3RyaW5nKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIG1hdGNoU3VjY2Vzc2Z1bCA9IGZhbHNlOworICAgICAgICAgICAgcmVjb3ZlclByZXZpb3VzU3RhdHVzKCk7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5wdXRNaXNtYXRjaEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBiaWdEZWNpbWFsVmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCB0b2tlbiBhcyBhIHtAY29kZSBCaWdJbnRlZ2VyfS4gVGhpcyBtZXRob2Qgd2lsbCBibG9jayBpZiBpbnB1dCBpcworICAgICAqIGJlaW5nIHJlYWQuIEVxdWl2YWxlbnQgdG8ge0Bjb2RlIG5leHRCaWdJbnRlZ2VyKERFRkFVTFRfUkFESVgpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgdG9rZW4gYXMge0Bjb2RlIEJpZ0ludGVnZXJ9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgU2Nhbm5lcn0gaGFzIGJlZW4gY2xvc2VkLgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGlucHV0IGhhcyBiZWVuIGV4aGF1c3RlZC4KKyAgICAgKiBAdGhyb3dzIElucHV0TWlzbWF0Y2hFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbmV4dCB0b2tlbiBjYW4gbm90IGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkCisgICAgICogICAgICAgICAgICAge0Bjb2RlIEJpZ0ludGVnZXJ9LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIG5leHRCaWdJbnRlZ2VyKCkgeworICAgICAgICByZXR1cm4gbmV4dEJpZ0ludGVnZXIoaW50ZWdlclJhZGl4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IHRva2VuIGFzIGEge0Bjb2RlIEJpZ0ludGVnZXJ9IHdpdGggdGhlIHNwZWNpZmllZCByYWRpeC4KKyAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGJsb2NrIGlmIGlucHV0IGlzIGJlaW5nIHJlYWQuIElmIHRoZSBuZXh0IHRva2VuIGNhbiBiZSB0cmFuc2xhdGVkCisgICAgICogaW50byBhIHtAY29kZSBCaWdJbnRlZ2VyfSB0aGUgZm9sbG93aW5nIGlzIGRvbmU6IEFsbCB7QGNvZGUgTG9jYWxlfS1zcGVjaWZpYworICAgICAqIHByZWZpeGVzLCBncm91cCBzZXBhcmF0b3JzLCBhbmQge0Bjb2RlIExvY2FsZX0tc3BlY2lmaWMgc3VmZml4ZXMgYXJlIHJlbW92ZWQuCisgICAgICogVGhlbiBub24tQVNDSUkgZGlnaXRzIGFyZSBtYXBwZWQgaW50byBBU0NJSSBkaWdpdHMgdmlhCisgICAgICoge0BsaW5rIENoYXJhY3RlciNkaWdpdChjaGFyLCBpbnQpfSwgYW5kIGEgbmVnYXRpdmUgc2lnbiAoLSkgaXMgYWRkZWQgaWYgdGhlCisgICAgICoge0Bjb2RlIExvY2FsZX0tc3BlY2lmaWMgbmVnYXRpdmUgcHJlZml4IG9yIHN1ZmZpeCB3YXMgcHJlc2VudC4gRmluYWxseSB0aGUKKyAgICAgKiByZXN1bHRpbmcgU3RyaW5nIGlzIHBhc3NlZCB0byB7QGxpbmsgQmlnSW50ZWdlciNCaWdJbnRlZ2VyKFN0cmluZywgaW50KX19CisgICAgICogd2l0aCB0aGUgc3BlY2lmaWVkIHJhZGl4LgorICAgICAqCisgICAgICogQHBhcmFtIHJhZGl4CisgICAgICogICAgICAgICAgICB0aGUgcmFkaXggdXNlZCB0byB0cmFuc2xhdGUgdGhlIHRva2VuIGludG8gYQorICAgICAqICAgICAgICAgICAge0Bjb2RlIEJpZ0ludGVnZXJ9LgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgdG9rZW4gYXMgYSB7QGNvZGUgQmlnSW50ZWdlcn0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIFNjYW5uZXJ9IGhhcyBiZWVuIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBpbnB1dCBoYXMgYmVlbiBleGhhdXN0ZWQuCisgICAgICogQHRocm93cyBJbnB1dE1pc21hdGNoRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG5leHQgdG9rZW4gY2FuIG5vdCBiZSB0cmFuc2xhdGVkIGludG8gYSB2YWxpZAorICAgICAqICAgICAgICAgICAgIHtAY29kZSBCaWdJbnRlZ2VyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBuZXh0QmlnSW50ZWdlcihpbnQgcmFkaXgpIHsKKyAgICAgICAgY2hlY2tDbG9zZWQoKTsKKyAgICAgICAgT2JqZWN0IG9iaiA9IGNhY2hlSGFzTmV4dFZhbHVlOworICAgICAgICBjYWNoZUhhc05leHRWYWx1ZSA9IG51bGw7CisgICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBCaWdJbnRlZ2VyKSB7CisgICAgICAgICAgICBmaW5kU3RhcnRJbmRleCA9IGNhY2hlaGFzTmV4dEluZGV4OworICAgICAgICAgICAgcmV0dXJuIChCaWdJbnRlZ2VyKSBvYmo7CisgICAgICAgIH0KKyAgICAgICAgUGF0dGVybiBpbnRlZ2VyUGF0dGVybiA9IGdldEludGVnZXJQYXR0ZXJuKHJhZGl4KTsKKyAgICAgICAgU3RyaW5nIGludFN0cmluZyA9IG5leHQoaW50ZWdlclBhdHRlcm4pOworICAgICAgICBpbnRTdHJpbmcgPSByZW1vdmVMb2NhbGVJbmZvKGludFN0cmluZywgRGF0YVR5cGUuSU5UKTsKKyAgICAgICAgQmlnSW50ZWdlciBiaWdJbnRlZ2VyVmFsdWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiaWdJbnRlZ2VyVmFsdWUgPSBuZXcgQmlnSW50ZWdlcihpbnRTdHJpbmcsIHJhZGl4KTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIG1hdGNoU3VjY2Vzc2Z1bCA9IGZhbHNlOworICAgICAgICAgICAgcmVjb3ZlclByZXZpb3VzU3RhdHVzKCk7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5wdXRNaXNtYXRjaEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBiaWdJbnRlZ2VyVmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCB0b2tlbiBhcyBhIHtAY29kZSBib29sZWFufS4gVGhpcyBtZXRob2Qgd2lsbCBibG9jayBpZiBpbnB1dCBpcworICAgICAqIGJlaW5nIHJlYWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IHRva2VuIGFzIGEge0Bjb2RlIGJvb2xlYW59LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgU2Nhbm5lcn0gaGFzIGJlZW4gY2xvc2VkLgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGlucHV0IGhhcyBiZWVuIGV4aGF1c3RlZC4KKyAgICAgKiBAdGhyb3dzIElucHV0TWlzbWF0Y2hFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbmV4dCB0b2tlbiBjYW4gbm90IGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGJvb2xlYW59IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG5leHRCb29sZWFuKCkgeworICAgICAgICByZXR1cm4gQm9vbGVhbi5wYXJzZUJvb2xlYW4obmV4dChCT09MRUFOX1BBVFRFUk4pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IHRva2VuIGFzIGEge0Bjb2RlIGJ5dGV9LiBUaGlzIG1ldGhvZCB3aWxsIGJsb2NrIGlmIGlucHV0IGlzIGJlaW5nCisgICAgICogcmVhZC4gRXF1aXZhbGVudCB0byB7QGNvZGUgbmV4dEJ5dGUoREVGQVVMVF9SQURJWCl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCB0b2tlbiBhcyBhIHtAY29kZSBieXRlfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIFNjYW5uZXJ9IGhhcyBiZWVuIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBpbnB1dCBoYXMgYmVlbiBleGhhdXN0ZWQuCisgICAgICogQHRocm93cyBJbnB1dE1pc21hdGNoRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG5leHQgdG9rZW4gY2FuIG5vdCBiZSB0cmFuc2xhdGVkIGludG8gYSB2YWxpZAorICAgICAqICAgICAgICAgICAgIHtAY29kZSBieXRlfSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZSBuZXh0Qnl0ZSgpIHsKKyAgICAgICAgcmV0dXJuIG5leHRCeXRlKGludGVnZXJSYWRpeCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCB0b2tlbiBhcyBhIHtAY29kZSBieXRlfSB3aXRoIHRoZSBzcGVjaWZpZWQgcmFkaXguIFdpbGwKKyAgICAgKiBibG9jayBpZiBpbnB1dCBpcyBiZWluZyByZWFkLiBJZiB0aGUgbmV4dCB0b2tlbiBjYW4gYmUgdHJhbnNsYXRlZCBpbnRvIGEKKyAgICAgKiB7QGNvZGUgYnl0ZX0gdGhlIGZvbGxvd2luZyBpcyBkb25lOiBBbGwge0Bjb2RlIExvY2FsZX0tc3BlY2lmaWMgcHJlZml4ZXMsIGdyb3VwCisgICAgICogc2VwYXJhdG9ycywgYW5kIHtAY29kZSBMb2NhbGV9LXNwZWNpZmljIHN1ZmZpeGVzIGFyZSByZW1vdmVkLiBUaGVuIG5vbi1BU0NJSQorICAgICAqIGRpZ2l0cyBhcmUgbWFwcGVkIGludG8gQVNDSUkgZGlnaXRzIHZpYQorICAgICAqIHtAbGluayBDaGFyYWN0ZXIjZGlnaXQoY2hhciwgaW50KX0sIGFuZCBhIG5lZ2F0aXZlIHNpZ24gKC0pIGlzIGFkZGVkIGlmIHRoZQorICAgICAqIHtAY29kZSBMb2NhbGV9LXNwZWNpZmljIG5lZ2F0aXZlIHByZWZpeCBvciBzdWZmaXggd2FzIHByZXNlbnQuIEZpbmFsbHkgdGhlCisgICAgICogcmVzdWx0aW5nIFN0cmluZyBpcyBwYXNzZWQgdG8ge0BsaW5rIEJ5dGUjcGFyc2VCeXRlKFN0cmluZywgaW50KX19IHdpdGgKKyAgICAgKiB0aGUgc3BlY2lmaWVkIHJhZGl4LgorICAgICAqCisgICAgICogQHBhcmFtIHJhZGl4CisgICAgICogICAgICAgICAgICB0aGUgcmFkaXggdXNlZCB0byB0cmFuc2xhdGUgdGhlIHRva2VuIGludG8ge0Bjb2RlIGJ5dGV9IHZhbHVlLgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgdG9rZW4gYXMgYSB7QGNvZGUgYnl0ZX0uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBTY2FubmVyfSBoYXMgYmVlbiBjbG9zZWQuCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgaW5wdXQgaGFzIGJlZW4gZXhoYXVzdGVkLgorICAgICAqIEB0aHJvd3MgSW5wdXRNaXNtYXRjaEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBuZXh0IHRva2VuIGNhbiBub3QgYmUgdHJhbnNsYXRlZCBpbnRvIGEgdmFsaWQKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgYnl0ZX0gdmFsdWUuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImJveGluZyIpCisgICAgcHVibGljIGJ5dGUgbmV4dEJ5dGUoaW50IHJhZGl4KSB7CisgICAgICAgIGNoZWNrQ2xvc2VkKCk7CisgICAgICAgIE9iamVjdCBvYmogPSBjYWNoZUhhc05leHRWYWx1ZTsKKyAgICAgICAgY2FjaGVIYXNOZXh0VmFsdWUgPSBudWxsOworICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgQnl0ZSkgeworICAgICAgICAgICAgZmluZFN0YXJ0SW5kZXggPSBjYWNoZWhhc05leHRJbmRleDsKKyAgICAgICAgICAgIHJldHVybiAoQnl0ZSkgb2JqOworICAgICAgICB9CisgICAgICAgIFBhdHRlcm4gaW50ZWdlclBhdHRlcm4gPSBnZXRJbnRlZ2VyUGF0dGVybihyYWRpeCk7CisgICAgICAgIFN0cmluZyBpbnRTdHJpbmcgPSBuZXh0KGludGVnZXJQYXR0ZXJuKTsKKyAgICAgICAgaW50U3RyaW5nID0gcmVtb3ZlTG9jYWxlSW5mbyhpbnRTdHJpbmcsIERhdGFUeXBlLklOVCk7CisgICAgICAgIGJ5dGUgYnl0ZVZhbHVlID0gMDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ5dGVWYWx1ZSA9IEJ5dGUucGFyc2VCeXRlKGludFN0cmluZywgcmFkaXgpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgbWF0Y2hTdWNjZXNzZnVsID0gZmFsc2U7CisgICAgICAgICAgICByZWNvdmVyUHJldmlvdXNTdGF0dXMoKTsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnB1dE1pc21hdGNoRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ5dGVWYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IHRva2VuIGFzIGEge0Bjb2RlIGRvdWJsZX0uIFRoaXMgbWV0aG9kIHdpbGwgYmxvY2sgaWYgaW5wdXQgaXMgYmVpbmcKKyAgICAgKiByZWFkLiBJZiB0aGUgbmV4dCB0b2tlbiBjYW4gYmUgdHJhbnNsYXRlZCBpbnRvIGEge0Bjb2RlIGRvdWJsZX0gdGhlCisgICAgICogZm9sbG93aW5nIGlzIGRvbmU6IEFsbCB7QGNvZGUgTG9jYWxlfS1zcGVjaWZpYyBwcmVmaXhlcywgZ3JvdXAgc2VwYXJhdG9ycywgYW5kCisgICAgICoge0Bjb2RlIExvY2FsZX0tc3BlY2lmaWMgc3VmZml4ZXMgYXJlIHJlbW92ZWQuIFRoZW4gbm9uLUFTQ0lJIGRpZ2l0cyBhcmUgbWFwcGVkCisgICAgICogaW50byBBU0NJSSBkaWdpdHMgdmlhIHtAbGluayBDaGFyYWN0ZXIjZGlnaXQoY2hhciwgaW50KX0sIGFuZCBhIG5lZ2F0aXZlCisgICAgICogc2lnbiAoLSkgaXMgYWRkZWQgaWYgdGhlIHtAY29kZSBMb2NhbGV9LXNwZWNpZmljIG5lZ2F0aXZlIHByZWZpeCBvciBzdWZmaXggd2FzCisgICAgICogcHJlc2VudC4gRmluYWxseSB0aGUgcmVzdWx0aW5nIFN0cmluZyBpcyBwYXNzZWQgdG8KKyAgICAgKiB7QGxpbmsgRG91YmxlI3BhcnNlRG91YmxlKFN0cmluZyl9fS4gSWYgdGhlIHRva2VuIG1hdGNoZXMgdGhlIGxvY2FsaXplZAorICAgICAqIE5hTiBvciBpbmZpbml0eSBzdHJpbmdzLCBpdCBpcyBhbHNvIHBhc3NlZCB0bworICAgICAqIHtAbGluayBEb3VibGUjcGFyc2VEb3VibGUoU3RyaW5nKX19LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCB0b2tlbiBhcyBhIHtAY29kZSBkb3VibGV9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgU2Nhbm5lcn0gaGFzIGJlZW4gY2xvc2VkLgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGlucHV0IGhhcyBiZWVuIGV4aGF1c3RlZC4KKyAgICAgKiBAdGhyb3dzIElucHV0TWlzbWF0Y2hFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbmV4dCB0b2tlbiBjYW4gbm90IGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGRvdWJsZX0gdmFsdWUuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImJveGluZyIpCisgICAgcHVibGljIGRvdWJsZSBuZXh0RG91YmxlKCkgeworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICBPYmplY3Qgb2JqID0gY2FjaGVIYXNOZXh0VmFsdWU7CisgICAgICAgIGNhY2hlSGFzTmV4dFZhbHVlID0gbnVsbDsKKyAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIERvdWJsZSkgeworICAgICAgICAgICAgZmluZFN0YXJ0SW5kZXggPSBjYWNoZWhhc05leHRJbmRleDsKKyAgICAgICAgICAgIHJldHVybiAoRG91YmxlKSBvYmo7CisgICAgICAgIH0KKyAgICAgICAgUGF0dGVybiBmbG9hdFBhdHRlcm4gPSBnZXRGbG9hdFBhdHRlcm4oKTsKKyAgICAgICAgU3RyaW5nIGZsb2F0U3RyaW5nID0gbmV4dChmbG9hdFBhdHRlcm4pOworICAgICAgICBmbG9hdFN0cmluZyA9IHJlbW92ZUxvY2FsZUluZm9Gcm9tRmxvYXQoZmxvYXRTdHJpbmcpOworICAgICAgICBkb3VibGUgZG91YmxlVmFsdWUgPSAwOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZG91YmxlVmFsdWUgPSBEb3VibGUucGFyc2VEb3VibGUoZmxvYXRTdHJpbmcpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgbWF0Y2hTdWNjZXNzZnVsID0gZmFsc2U7CisgICAgICAgICAgICByZWNvdmVyUHJldmlvdXNTdGF0dXMoKTsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnB1dE1pc21hdGNoRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRvdWJsZVZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgdG9rZW4gYXMgYSB7QGNvZGUgZmxvYXR9LiBUaGlzIG1ldGhvZCB3aWxsIGJsb2NrIGlmIGlucHV0IGlzIGJlaW5nCisgICAgICogcmVhZC4gSWYgdGhlIG5leHQgdG9rZW4gY2FuIGJlIHRyYW5zbGF0ZWQgaW50byBhIHtAY29kZSBmbG9hdH0gdGhlCisgICAgICogZm9sbG93aW5nIGlzIGRvbmU6IEFsbCB7QGNvZGUgTG9jYWxlfS1zcGVjaWZpYyBwcmVmaXhlcywgZ3JvdXAgc2VwYXJhdG9ycywgYW5kCisgICAgICoge0Bjb2RlIExvY2FsZX0tc3BlY2lmaWMgc3VmZml4ZXMgYXJlIHJlbW92ZWQuIFRoZW4gbm9uLUFTQ0lJIGRpZ2l0cyBhcmUgbWFwcGVkCisgICAgICogaW50byBBU0NJSSBkaWdpdHMgdmlhIHtAbGluayBDaGFyYWN0ZXIjZGlnaXQoY2hhciwgaW50KX0sIGFuZCBhIG5lZ2F0aXZlCisgICAgICogc2lnbiAoLSkgaXMgYWRkZWQgaWYgdGhlIHtAY29kZSBMb2NhbGV9LXNwZWNpZmljIG5lZ2F0aXZlIHByZWZpeCBvciBzdWZmaXggd2FzCisgICAgICogcHJlc2VudC4gRmluYWxseSB0aGUgcmVzdWx0aW5nIFN0cmluZyBpcyBwYXNzZWQgdG8KKyAgICAgKiB7QGxpbmsgRmxvYXQjcGFyc2VGbG9hdChTdHJpbmcpfX0uSWYgdGhlIHRva2VuIG1hdGNoZXMgdGhlIGxvY2FsaXplZCBOYU4KKyAgICAgKiBvciBpbmZpbml0eSBzdHJpbmdzLCBpdCBpcyBhbHNvIHBhc3NlZCB0bworICAgICAqIHtAbGluayBGbG9hdCNwYXJzZUZsb2F0KFN0cmluZyl9fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgdG9rZW4gYXMgYSB7QGNvZGUgZmxvYXR9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgU2Nhbm5lcn0gaGFzIGJlZW4gY2xvc2VkLgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGlucHV0IGhhcyBiZWVuIGV4aGF1c3RlZC4KKyAgICAgKiBAdGhyb3dzIElucHV0TWlzbWF0Y2hFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbmV4dCB0b2tlbiBjYW4gbm90IGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGZsb2F0fSB2YWx1ZS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiYm94aW5nIikKKyAgICBwdWJsaWMgZmxvYXQgbmV4dEZsb2F0KCkgeworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICBPYmplY3Qgb2JqID0gY2FjaGVIYXNOZXh0VmFsdWU7CisgICAgICAgIGNhY2hlSGFzTmV4dFZhbHVlID0gbnVsbDsKKyAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIEZsb2F0KSB7CisgICAgICAgICAgICBmaW5kU3RhcnRJbmRleCA9IGNhY2hlaGFzTmV4dEluZGV4OworICAgICAgICAgICAgcmV0dXJuIChGbG9hdCkgb2JqOworICAgICAgICB9CisgICAgICAgIFBhdHRlcm4gZmxvYXRQYXR0ZXJuID0gZ2V0RmxvYXRQYXR0ZXJuKCk7CisgICAgICAgIFN0cmluZyBmbG9hdFN0cmluZyA9IG5leHQoZmxvYXRQYXR0ZXJuKTsKKyAgICAgICAgZmxvYXRTdHJpbmcgPSByZW1vdmVMb2NhbGVJbmZvRnJvbUZsb2F0KGZsb2F0U3RyaW5nKTsKKyAgICAgICAgZmxvYXQgZmxvYXRWYWx1ZSA9IDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmbG9hdFZhbHVlID0gRmxvYXQucGFyc2VGbG9hdChmbG9hdFN0cmluZyk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBtYXRjaFN1Y2Nlc3NmdWwgPSBmYWxzZTsKKyAgICAgICAgICAgIHJlY292ZXJQcmV2aW91c1N0YXR1cygpOworICAgICAgICAgICAgdGhyb3cgbmV3IElucHV0TWlzbWF0Y2hFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmxvYXRWYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IHRva2VuIGFzIGFuIHtAY29kZSBpbnR9LiBUaGlzIG1ldGhvZCB3aWxsIGJsb2NrIGlmIGlucHV0IGlzIGJlaW5nCisgICAgICogcmVhZC4gRXF1aXZhbGVudCB0byB7QGNvZGUgbmV4dEludChERUZBVUxUX1JBRElYKX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IHRva2VuIGFzIGFuIHtAY29kZSBpbnR9CisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBTY2FubmVyfSBoYXMgYmVlbiBjbG9zZWQuCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgaW5wdXQgaGFzIGJlZW4gZXhoYXVzdGVkLgorICAgICAqIEB0aHJvd3MgSW5wdXRNaXNtYXRjaEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBuZXh0IHRva2VuIGNhbiBub3QgYmUgdHJhbnNsYXRlZCBpbnRvIGEgdmFsaWQKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgaW50fSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IG5leHRJbnQoKSB7CisgICAgICAgIHJldHVybiBuZXh0SW50KGludGVnZXJSYWRpeCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCB0b2tlbiBhcyBhbiB7QGNvZGUgaW50fSB3aXRoIHRoZSBzcGVjaWZpZWQgcmFkaXguIFRoaXMgbWV0aG9kIHdpbGwKKyAgICAgKiBibG9jayBpZiBpbnB1dCBpcyBiZWluZyByZWFkLiBJZiB0aGUgbmV4dCB0b2tlbiBjYW4gYmUgdHJhbnNsYXRlZCBpbnRvIGFuCisgICAgICoge0Bjb2RlIGludH0gdGhlIGZvbGxvd2luZyBpcyBkb25lOiBBbGwge0Bjb2RlIExvY2FsZX0tc3BlY2lmaWMgcHJlZml4ZXMsIGdyb3VwCisgICAgICogc2VwYXJhdG9ycywgYW5kIHtAY29kZSBMb2NhbGV9LXNwZWNpZmljIHN1ZmZpeGVzIGFyZSByZW1vdmVkLiBUaGVuIG5vbi1BU0NJSQorICAgICAqIGRpZ2l0cyBhcmUgbWFwcGVkIGludG8gQVNDSUkgZGlnaXRzIHZpYQorICAgICAqIHtAbGluayBDaGFyYWN0ZXIjZGlnaXQoY2hhciwgaW50KX0sIGFuZCBhIG5lZ2F0aXZlIHNpZ24gKC0pIGlzIGFkZGVkIGlmIHRoZQorICAgICAqIHtAY29kZSBMb2NhbGV9LXNwZWNpZmljIG5lZ2F0aXZlIHByZWZpeCBvciBzdWZmaXggd2FzIHByZXNlbnQuIEZpbmFsbHkgdGhlCisgICAgICogcmVzdWx0aW5nIFN0cmluZyBpcyBwYXNzZWQgdG8ge0BsaW5rIEludGVnZXIjcGFyc2VJbnQoU3RyaW5nLCBpbnQpfSB3aXRoCisgICAgICogdGhlIHNwZWNpZmllZCByYWRpeC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByYWRpeAorICAgICAqICAgICAgICAgICAgdGhlIHJhZGl4IHVzZWQgdG8gdHJhbnNsYXRlIHRoZSB0b2tlbiBpbnRvIGFuIHtAY29kZSBpbnR9CisgICAgICogICAgICAgICAgICB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IHRva2VuIGFzIGFuIHtAY29kZSBpbnR9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgU2Nhbm5lcn0gaGFzIGJlZW4gY2xvc2VkLgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGlucHV0IGhhcyBiZWVuIGV4aGF1c3RlZC4KKyAgICAgKiBAdGhyb3dzIElucHV0TWlzbWF0Y2hFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbmV4dCB0b2tlbiBjYW4gbm90IGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGludH0gdmFsdWUuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImJveGluZyIpCisgICAgcHVibGljIGludCBuZXh0SW50KGludCByYWRpeCkgeworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICBPYmplY3Qgb2JqID0gY2FjaGVIYXNOZXh0VmFsdWU7CisgICAgICAgIGNhY2hlSGFzTmV4dFZhbHVlID0gbnVsbDsKKyAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIEludGVnZXIpIHsKKyAgICAgICAgICAgIGZpbmRTdGFydEluZGV4ID0gY2FjaGVoYXNOZXh0SW5kZXg7CisgICAgICAgICAgICByZXR1cm4gKEludGVnZXIpIG9iajsKKyAgICAgICAgfQorICAgICAgICBQYXR0ZXJuIGludGVnZXJQYXR0ZXJuID0gZ2V0SW50ZWdlclBhdHRlcm4ocmFkaXgpOworICAgICAgICBTdHJpbmcgaW50U3RyaW5nID0gbmV4dChpbnRlZ2VyUGF0dGVybik7CisgICAgICAgIGludFN0cmluZyA9IHJlbW92ZUxvY2FsZUluZm8oaW50U3RyaW5nLCBEYXRhVHlwZS5JTlQpOworICAgICAgICBpbnQgaW50VmFsdWUgPSAwOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50VmFsdWUgPSBJbnRlZ2VyLnBhcnNlSW50KGludFN0cmluZywgcmFkaXgpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgbWF0Y2hTdWNjZXNzZnVsID0gZmFsc2U7CisgICAgICAgICAgICByZWNvdmVyUHJldmlvdXNTdGF0dXMoKTsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnB1dE1pc21hdGNoRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGludFZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNraXBwZWQgaW5wdXQgYW5kIGFkdmFuY2VzIHRoZSB7QGNvZGUgU2Nhbm5lcn0gdG8gdGhlIGJlZ2lubmluZyBvZgorICAgICAqIHRoZSBuZXh0IGxpbmUuIFRoZSByZXR1cm5lZCByZXN1bHQgd2lsbCBleGNsdWRlIGFueSBsaW5lIHRlcm1pbmF0b3IuIFdoZW4KKyAgICAgKiBzZWFyY2hpbmcsIGlmIG5vIGxpbmUgdGVybWluYXRvciBpcyBmb3VuZCwgdGhlbiBhIGxhcmdlIGFtb3VudCBvZiBpbnB1dAorICAgICAqIHdpbGwgYmUgY2FjaGVkLiBJZiBubyBsaW5lIGF0IGFsbCBjYW4gYmUgZm91bmQsIGEge0Bjb2RlIE5vU3VjaEVsZW1lbnRFeGNlcHRpb259CisgICAgICogd2lsbCBiZSB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBza2lwcGVkIGxpbmUuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIFNjYW5uZXJ9IGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBsaW5lIGNhbiBiZSBmb3VuZCwgZS5nLiB3aGVuIGlucHV0IGlzIGFuIGVtcHR5IHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIG5leHRMaW5lKCkgeworICAgICAgICBjaGVja0Nsb3NlZCgpOworCisgICAgICAgIG1hdGNoZXIudXNlUGF0dGVybihMSU5FX1BBVFRFUk4pOworICAgICAgICBtYXRjaGVyLnJlZ2lvbihmaW5kU3RhcnRJbmRleCwgYnVmZmVyTGVuZ3RoKTsKKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IG51bGw7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBpZiAobWF0Y2hlci5maW5kKCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoaW5wdXRFeGhhdXN0ZWQgfHwgbWF0Y2hlci5lbmQoKSAhPSBidWZmZXJMZW5ndGgKKyAgICAgICAgICAgICAgICAgICAgICAgIHx8IGJ1ZmZlckxlbmd0aCA8IGJ1ZmZlci5jYXBhY2l0eSgpKSB7CisgICAgICAgICAgICAgICAgICAgIG1hdGNoU3VjY2Vzc2Z1bCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIGZpbmRTdGFydEluZGV4ID0gbWF0Y2hlci5lbmQoKTsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbWF0Y2hlci5ncm91cCgpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmIChpbnB1dEV4aGF1c3RlZCkgeworICAgICAgICAgICAgICAgICAgICBtYXRjaFN1Y2Nlc3NmdWwgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIWlucHV0RXhoYXVzdGVkKSB7CisgICAgICAgICAgICAgICAgcmVhZE1vcmUoKTsKKyAgICAgICAgICAgICAgICByZXNldE1hdGNoZXIoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBGaW5kIHRleHQgd2l0aG91dCBsaW5lIHRlcm1pbmF0b3IgaGVyZS4KKyAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7CisgICAgICAgICAgICBNYXRjaGVyIHRlcm1pbmF0b3JNYXRjaGVyID0gTElORV9URVJNSU5BVE9SLm1hdGNoZXIocmVzdWx0KTsKKyAgICAgICAgICAgIGlmICh0ZXJtaW5hdG9yTWF0Y2hlci5maW5kKCkpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQuc3Vic3RyaW5nKDAsIHRlcm1pbmF0b3JNYXRjaGVyLnN0YXJ0KCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCB0b2tlbiBhcyBhIHtAY29kZSBsb25nfS4gVGhpcyBtZXRob2Qgd2lsbCBibG9jayBpZiBpbnB1dCBpcyBiZWluZworICAgICAqIHJlYWQuIEVxdWl2YWxlbnQgdG8ge0Bjb2RlIG5leHRMb25nKERFRkFVTFRfUkFESVgpfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgdG9rZW4gYXMgYSB7QGNvZGUgbG9uZ30uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBTY2FubmVyfSBoYXMgYmVlbiBjbG9zZWQuCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgaW5wdXQgaGFzIGJlZW4gZXhoYXVzdGVkLgorICAgICAqIEB0aHJvd3MgSW5wdXRNaXNtYXRjaEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBuZXh0IHRva2VuIGNhbiBub3QgYmUgdHJhbnNsYXRlZCBpbnRvIGEgdmFsaWQKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgbG9uZ30gdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGxvbmcgbmV4dExvbmcoKSB7CisgICAgICAgIHJldHVybiBuZXh0TG9uZyhpbnRlZ2VyUmFkaXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgdG9rZW4gYXMgYSB7QGNvZGUgbG9uZ30gd2l0aCB0aGUgc3BlY2lmaWVkIHJhZGl4LiBUaGlzIG1ldGhvZCB3aWxsCisgICAgICogYmxvY2sgaWYgaW5wdXQgaXMgYmVpbmcgcmVhZC4gSWYgdGhlIG5leHQgdG9rZW4gY2FuIGJlIHRyYW5zbGF0ZWQgaW50byBhCisgICAgICoge0Bjb2RlIGxvbmd9IHRoZSBmb2xsb3dpbmcgaXMgZG9uZTogQWxsIHtAY29kZSBMb2NhbGV9LXNwZWNpZmljIHByZWZpeGVzLCBncm91cAorICAgICAqIHNlcGFyYXRvcnMsIGFuZCB7QGNvZGUgTG9jYWxlfS1zcGVjaWZpYyBzdWZmaXhlcyBhcmUgcmVtb3ZlZC4gVGhlbiBub24tQVNDSUkKKyAgICAgKiBkaWdpdHMgYXJlIG1hcHBlZCBpbnRvIEFTQ0lJIGRpZ2l0cyB2aWEKKyAgICAgKiB7QGxpbmsgQ2hhcmFjdGVyI2RpZ2l0KGNoYXIsIGludCl9LCBhbmQgYSBuZWdhdGl2ZSBzaWduICgtKSBpcyBhZGRlZCBpZiB0aGUKKyAgICAgKiB7QGNvZGUgTG9jYWxlfS1zcGVjaWZpYyBuZWdhdGl2ZSBwcmVmaXggb3Igc3VmZml4IHdhcyBwcmVzZW50LiBGaW5hbGx5IHRoZQorICAgICAqIHJlc3VsdGluZyBTdHJpbmcgaXMgcGFzc2VkIHRvIHtAbGluayBMb25nI3BhcnNlTG9uZyhTdHJpbmcsIGludCl9fSB3aXRoCisgICAgICogdGhlIHNwZWNpZmllZCByYWRpeC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByYWRpeAorICAgICAqICAgICAgICAgICAgdGhlIHJhZGl4IHVzZWQgdG8gdHJhbnNsYXRlIHRoZSB0b2tlbiBpbnRvIGEge0Bjb2RlIGxvbmd9CisgICAgICogICAgICAgICAgICB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IHRva2VuIGFzIGEge0Bjb2RlIGxvbmd9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgU2Nhbm5lcn0gaGFzIGJlZW4gY2xvc2VkLgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGlucHV0IGhhcyBiZWVuIGV4aGF1c3RlZC4KKyAgICAgKiBAdGhyb3dzIElucHV0TWlzbWF0Y2hFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbmV4dCB0b2tlbiBjYW4gbm90IGJlIHRyYW5zbGF0ZWQgaW50byBhIHZhbGlkCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGxvbmd9IHZhbHVlLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJib3hpbmciKQorICAgIHB1YmxpYyBsb25nIG5leHRMb25nKGludCByYWRpeCkgeworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICBPYmplY3Qgb2JqID0gY2FjaGVIYXNOZXh0VmFsdWU7CisgICAgICAgIGNhY2hlSGFzTmV4dFZhbHVlID0gbnVsbDsKKyAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIExvbmcpIHsKKyAgICAgICAgICAgIGZpbmRTdGFydEluZGV4ID0gY2FjaGVoYXNOZXh0SW5kZXg7CisgICAgICAgICAgICByZXR1cm4gKExvbmcpIG9iajsKKyAgICAgICAgfQorICAgICAgICBQYXR0ZXJuIGludGVnZXJQYXR0ZXJuID0gZ2V0SW50ZWdlclBhdHRlcm4ocmFkaXgpOworICAgICAgICBTdHJpbmcgaW50U3RyaW5nID0gbmV4dChpbnRlZ2VyUGF0dGVybik7CisgICAgICAgIGludFN0cmluZyA9IHJlbW92ZUxvY2FsZUluZm8oaW50U3RyaW5nLCBEYXRhVHlwZS5JTlQpOworICAgICAgICBsb25nIGxvbmdWYWx1ZSA9IDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsb25nVmFsdWUgPSBMb25nLnBhcnNlTG9uZyhpbnRTdHJpbmcsIHJhZGl4KTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIG1hdGNoU3VjY2Vzc2Z1bCA9IGZhbHNlOworICAgICAgICAgICAgcmVjb3ZlclByZXZpb3VzU3RhdHVzKCk7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5wdXRNaXNtYXRjaEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBsb25nVmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCB0b2tlbiBhcyBhIHtAY29kZSBzaG9ydH0uIFRoaXMgbWV0aG9kIHdpbGwgYmxvY2sgaWYgaW5wdXQgaXMgYmVpbmcKKyAgICAgKiByZWFkLiBFcXVpdmFsZW50IHRvIHtAY29kZSBuZXh0U2hvcnQoREVGQVVMVF9SQURJWCl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCB0b2tlbiBhcyBhIHtAY29kZSBzaG9ydH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBTY2FubmVyfSBoYXMgYmVlbiBjbG9zZWQuCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgaW5wdXQgaGFzIGJlZW4gZXhoYXVzdGVkLgorICAgICAqIEB0aHJvd3MgSW5wdXRNaXNtYXRjaEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBuZXh0IHRva2VuIGNhbiBub3QgYmUgdHJhbnNsYXRlZCBpbnRvIGEgdmFsaWQKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgc2hvcnR9IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzaG9ydCBuZXh0U2hvcnQoKSB7CisgICAgICAgIHJldHVybiBuZXh0U2hvcnQoaW50ZWdlclJhZGl4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IHRva2VuIGFzIGEge0Bjb2RlIHNob3J0fSB3aXRoIHRoZSBzcGVjaWZpZWQgcmFkaXguIFRoaXMgbWV0aG9kIHdpbGwKKyAgICAgKiBibG9jayBpZiBpbnB1dCBpcyBiZWluZyByZWFkLiBJZiB0aGUgbmV4dCB0b2tlbiBjYW4gYmUgdHJhbnNsYXRlZCBpbnRvIGEKKyAgICAgKiB7QGNvZGUgc2hvcnR9IHRoZSBmb2xsb3dpbmcgaXMgZG9uZTogQWxsIHtAY29kZSBMb2NhbGV9LXNwZWNpZmljIHByZWZpeGVzLCBncm91cAorICAgICAqIHNlcGFyYXRvcnMsIGFuZCB7QGNvZGUgTG9jYWxlfS1zcGVjaWZpYyBzdWZmaXhlcyBhcmUgcmVtb3ZlZC4gVGhlbiBub24tQVNDSUkKKyAgICAgKiBkaWdpdHMgYXJlIG1hcHBlZCBpbnRvIEFTQ0lJIGRpZ2l0cyB2aWEKKyAgICAgKiB7QGxpbmsgQ2hhcmFjdGVyI2RpZ2l0KGNoYXIsIGludCl9LCBhbmQgYSBuZWdhdGl2ZSBzaWduICgtKSBpcyBhZGRlZCBpZiB0aGUKKyAgICAgKiB7QGNvZGUgTG9jYWxlfS1zcGVjaWZpYyBuZWdhdGl2ZSBwcmVmaXggb3Igc3VmZml4IHdhcyBwcmVzZW50LiBGaW5hbGx5IHRoZQorICAgICAqIHJlc3VsdGluZyBTdHJpbmcgaXMgcGFzc2VkIHRvIHtAbGluayBTaG9ydCNwYXJzZVNob3J0KFN0cmluZywgaW50KX19CisgICAgICogd2l0aCB0aGUgc3BlY2lmaWVkIHJhZGl4LgorICAgICAqCisgICAgICogQHBhcmFtIHJhZGl4CisgICAgICogICAgICAgICAgICB0aGUgcmFkaXggdXNlZCB0byB0cmFuc2xhdGUgdGhlIHRva2VuIGludG8ge0Bjb2RlIHNob3J0fQorICAgICAqICAgICAgICAgICAgdmFsdWUuCisgICAgICogQHJldHVybiB0aGUgbmV4dCB0b2tlbiBhcyBhIHtAY29kZSBzaG9ydH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBTY2FubmVyfSBoYXMgYmVlbiBjbG9zZWQuCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgaW5wdXQgaGFzIGJlZW4gZXhoYXVzdGVkLgorICAgICAqIEB0aHJvd3MgSW5wdXRNaXNtYXRjaEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBuZXh0IHRva2VuIGNhbiBub3QgYmUgdHJhbnNsYXRlZCBpbnRvIGEgdmFsaWQKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgc2hvcnR9IHZhbHVlLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJib3hpbmciKQorICAgIHB1YmxpYyBzaG9ydCBuZXh0U2hvcnQoaW50IHJhZGl4KSB7CisgICAgICAgIGNoZWNrQ2xvc2VkKCk7CisgICAgICAgIE9iamVjdCBvYmogPSBjYWNoZUhhc05leHRWYWx1ZTsKKyAgICAgICAgY2FjaGVIYXNOZXh0VmFsdWUgPSBudWxsOworICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgU2hvcnQpIHsKKyAgICAgICAgICAgIGZpbmRTdGFydEluZGV4ID0gY2FjaGVoYXNOZXh0SW5kZXg7CisgICAgICAgICAgICByZXR1cm4gKFNob3J0KSBvYmo7CisgICAgICAgIH0KKyAgICAgICAgUGF0dGVybiBpbnRlZ2VyUGF0dGVybiA9IGdldEludGVnZXJQYXR0ZXJuKHJhZGl4KTsKKyAgICAgICAgU3RyaW5nIGludFN0cmluZyA9IG5leHQoaW50ZWdlclBhdHRlcm4pOworICAgICAgICBpbnRTdHJpbmcgPSByZW1vdmVMb2NhbGVJbmZvKGludFN0cmluZywgRGF0YVR5cGUuSU5UKTsKKyAgICAgICAgc2hvcnQgc2hvcnRWYWx1ZSA9IDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaG9ydFZhbHVlID0gU2hvcnQucGFyc2VTaG9ydChpbnRTdHJpbmcsIHJhZGl4KTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIG1hdGNoU3VjY2Vzc2Z1bCA9IGZhbHNlOworICAgICAgICAgICAgcmVjb3ZlclByZXZpb3VzU3RhdHVzKCk7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5wdXRNaXNtYXRjaEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzaG9ydFZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgcmFkaXggb2YgdGhpcyB7QGNvZGUgU2Nhbm5lcn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByYWRpeCBvZiB0aGlzIHtAY29kZSBTY2FubmVyfQorICAgICAqLworICAgIHB1YmxpYyBpbnQgcmFkaXgoKSB7CisgICAgICAgIHJldHVybiBpbnRlZ2VyUmFkaXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJpZXMgdG8gdXNlIHNwZWNpZmllZCBwYXR0ZXJuIHRvIG1hdGNoIGlucHV0IHN0YXJ0aW5nIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24uCisgICAgICogVGhlIGRlbGltaXRlciB3aWxsIGJlIGlnbm9yZWQuIElmIGEgbWF0Y2ggaXMgZm91bmQsIHRoZSBtYXRjaGVkIGlucHV0IHdpbGwgYmUKKyAgICAgKiBza2lwcGVkLiBJZiBhbiBhbmNob3JlZCBtYXRjaCBvZiB0aGUgc3BlY2lmaWVkIHBhdHRlcm4gc3VjY2VlZHMsIHRoZSBjb3JyZXNwb25kaW5nIGlucHV0CisgICAgICogd2lsbCBhbHNvIGJlIHNraXBwZWQuIE90aGVyd2lzZSwgYSB7QGNvZGUgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24uCisgICAgICogUGF0dGVybnMgdGhhdCBjYW4gbWF0Y2ggYSBsb3Qgb2YgaW5wdXQgbWF5IGNhdXNlIHRoZSB7QGNvZGUgU2Nhbm5lcn0gdG8gcmVhZAorICAgICAqIGluIGEgbGFyZ2UgYW1vdW50IG9mIGlucHV0LgorICAgICAqCisgICAgICogQHBhcmFtIHBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIHVzZWQgdG8gc2tpcCBvdmVyIGlucHV0LgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBTY2FubmVyfSBpdHNlbGYuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIFNjYW5uZXJ9IGlzIGNsb3NlZC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHBhdHRlcm4gbWF0Y2ggZmFpbHMuCisgICAgICovCisgICAgcHVibGljIFNjYW5uZXIgc2tpcChQYXR0ZXJuIHBhdHRlcm4pIHsKKyAgICAgICAgY2hlY2tDbG9zZWQoKTsKKyAgICAgICAgY2hlY2tOdWxsKHBhdHRlcm4pOworICAgICAgICBtYXRjaGVyLnVzZVBhdHRlcm4ocGF0dGVybik7CisgICAgICAgIG1hdGNoZXIucmVnaW9uKGZpbmRTdGFydEluZGV4LCBidWZmZXJMZW5ndGgpOworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgaWYgKG1hdGNoZXIubG9va2luZ0F0KCkpIHsKKyAgICAgICAgICAgICAgICBib29sZWFuIG1hdGNoSW5CdWZmZXIgPSBtYXRjaGVyLmVuZCgpIDwgYnVmZmVyTGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICAgICB8fCAobWF0Y2hlci5lbmQoKSA9PSBidWZmZXJMZW5ndGggJiYgaW5wdXRFeGhhdXN0ZWQpOworICAgICAgICAgICAgICAgIGlmIChtYXRjaEluQnVmZmVyKSB7CisgICAgICAgICAgICAgICAgICAgIG1hdGNoU3VjY2Vzc2Z1bCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIGZpbmRTdGFydEluZGV4ID0gbWF0Y2hlci5lbmQoKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAoaW5wdXRFeGhhdXN0ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgbWF0Y2hTdWNjZXNzZnVsID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFpbnB1dEV4aGF1c3RlZCkgeworICAgICAgICAgICAgICAgIHJlYWRNb3JlKCk7CisgICAgICAgICAgICAgICAgcmVzZXRNYXRjaGVyKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJpZXMgdG8gdXNlIHRoZSBzcGVjaWZpZWQgc3RyaW5nIHRvIGNvbnN0cnVjdCBhIHBhdHRlcm4gYW5kIHRoZW4gdXNlcworICAgICAqIHRoZSBjb25zdHJ1Y3RlZCBwYXR0ZXJuIHRvIG1hdGNoIGlucHV0IHN0YXJ0aW5nIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24uIFRoZQorICAgICAqIGRlbGltaXRlciB3aWxsIGJlIGlnbm9yZWQuIFRoaXMgY2FsbCBpcyB0aGUgc2FtZSBhcyBpbnZva2UKKyAgICAgKiB7QGNvZGUgc2tpcChQYXR0ZXJuLmNvbXBpbGUocGF0dGVybikpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXR0ZXJuCisgICAgICogICAgICAgICAgICB0aGUgc3RyaW5nIHVzZWQgdG8gY29uc3RydWN0IGEgcGF0dGVybiB3aGljaCBpbiB0dXJuIGlzIHVzZWQgdG8KKyAgICAgKiAgICAgICAgICAgIG1hdGNoIGlucHV0LgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBTY2FubmVyfSBpdHNlbGYuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIFNjYW5uZXJ9IGlzIGNsb3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2Nhbm5lciBza2lwKFN0cmluZyBwYXR0ZXJuKSB7CisgICAgICAgIHJldHVybiBza2lwKFBhdHRlcm4uY29tcGlsZShwYXR0ZXJuKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZSBTY2FubmVyfS4gVGhlIGluZm9ybWF0aW9uCisgICAgICogcmV0dXJuZWQgbWF5IGJlIGhlbHBmdWwgZm9yIGRlYnVnZ2luZy4gVGhlIGZvcm1hdCBvZiB0aGUgc3RyaW5nIGlzIHVuc3BlY2lmaWVkLgorICAgICAqCisgICAgICogQHJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZSBTY2FubmVyfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKworICAgICAgICAgICAgICAgICJbZGVsaW1pdGVyPSIgKyBkZWxpbWl0ZXIgKworICAgICAgICAgICAgICAgICIsZmluZFN0YXJ0SW5kZXg9IiArIGZpbmRTdGFydEluZGV4ICsKKyAgICAgICAgICAgICAgICAiLG1hdGNoU3VjY2Vzc2Z1bD0iICsgbWF0Y2hTdWNjZXNzZnVsICsKKyAgICAgICAgICAgICAgICAiLGNsb3NlZD0iICsgY2xvc2VkICsKKyAgICAgICAgICAgICAgICAiXSI7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGVsaW1pdGluZyBwYXR0ZXJuIG9mIHRoaXMge0Bjb2RlIFNjYW5uZXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIHRoZSBkZWxpbWl0aW5nIHBhdHRlcm4gdG8gdXNlLgorICAgICAqIEByZXR1cm4gdGhpcyB7QGNvZGUgU2Nhbm5lcn0uCisgICAgICovCisgICAgcHVibGljIFNjYW5uZXIgdXNlRGVsaW1pdGVyKFBhdHRlcm4gcGF0dGVybikgeworICAgICAgICBkZWxpbWl0ZXIgPSBwYXR0ZXJuOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkZWxpbWl0aW5nIHBhdHRlcm4gb2YgdGhpcyB7QGNvZGUgU2Nhbm5lcn0gd2l0aCBhIHBhdHRlcm4gY29tcGlsZWQgZnJvbQorICAgICAqIHRoZSBzdXBwbGllZCBzdHJpbmcgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGF0dGVybgorICAgICAqICAgICAgICAgICAgYSBzdHJpbmcgZnJvbSB3aGljaCBhIHtAY29kZSBQYXR0ZXJufSBjYW4gYmUgY29tcGlsZWQuCisgICAgICogQHJldHVybiB0aGlzIHtAY29kZSBTY2FubmVyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2Nhbm5lciB1c2VEZWxpbWl0ZXIoU3RyaW5nIHBhdHRlcm4pIHsKKyAgICAgICAgcmV0dXJuIHVzZURlbGltaXRlcihQYXR0ZXJuLmNvbXBpbGUocGF0dGVybikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHtAY29kZSBMb2NhbGV9IG9mIHRoaXMge0Bjb2RlIFNjYW5uZXJ9IHRvIGEgc3BlY2lmaWVkIHtAY29kZSBMb2NhbGV9LgorICAgICAqCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQge0Bjb2RlIExvY2FsZX0gdG8gdXNlLgorICAgICAqIEByZXR1cm4gdGhpcyB7QGNvZGUgU2Nhbm5lcn0uCisgICAgICovCisgICAgcHVibGljIFNjYW5uZXIgdXNlTG9jYWxlKExvY2FsZSBsKSB7CisgICAgICAgIGlmIChsID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMubG9jYWxlID0gbDsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcmFkaXggb2YgdGhpcyB7QGNvZGUgU2Nhbm5lcn0gdG8gdGhlIHNwZWNpZmllZCByYWRpeC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByYWRpeAorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCByYWRpeCB0byB1c2UuCisgICAgICogQHJldHVybiB0aGlzIHtAY29kZSBTY2FubmVyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2Nhbm5lciB1c2VSYWRpeChpbnQgcmFkaXgpIHsKKyAgICAgICAgY2hlY2tSYWRpeChyYWRpeCk7CisgICAgICAgIHRoaXMuaW50ZWdlclJhZGl4ID0gcmFkaXg7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja1JhZGl4KGludCByYWRpeCkgeworICAgICAgICBpZiAocmFkaXggPCBDaGFyYWN0ZXIuTUlOX1JBRElYIHx8IHJhZGl4ID4gQ2hhcmFjdGVyLk1BWF9SQURJWCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCByYWRpeDogIiArIHJhZGl4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSBpcyBub3QgYSBzdXBwb3J0ZWQgb3BlcmF0aW9uIG9uIHtAY29kZSBTY2FubmVyfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1ldGhvZCBpcyBpbnZva2VkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBJbml0aWFsaXplIHNvbWUgY29tcG9uZW50cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdGlhbGl6YXRpb24oKSB7CisgICAgICAgIGJ1ZmZlciA9IENoYXJCdWZmZXIuYWxsb2NhdGUoREVGQVVMVF9UUlVOS19TSVpFKTsKKyAgICAgICAgYnVmZmVyLmxpbWl0KDApOworICAgICAgICBtYXRjaGVyID0gZGVsaW1pdGVyLm1hdGNoZXIoYnVmZmVyKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENoZWNrIHRoZSB7QGNvZGUgU2Nhbm5lcn0ncyBzdGF0ZSwgaWYgaXQgaXMgY2xvc2VkLCBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gd2lsbCBiZQorICAgICAqIHRocm93bi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY2hlY2tDbG9zZWQoKSB7CisgICAgICAgIGlmIChjbG9zZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQ2hlY2sgdGhlIGlucHV0ZWQgcGF0dGVybi4gSWYgaXQgaXMgbnVsbCwgdGhlbiBhIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogd2lsbCBiZSB0aHJvd24gb3V0LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjaGVja051bGwoUGF0dGVybiBwYXR0ZXJuKSB7CisgICAgICAgIGlmIChwYXR0ZXJuID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDaGFuZ2UgdGhlIG1hdGNoZXIncyBzdHJpbmcgYWZ0ZXIgcmVhZGluZyBpbnB1dAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZXNldE1hdGNoZXIoKSB7CisgICAgICAgIGlmIChtYXRjaGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIG1hdGNoZXIgPSBkZWxpbWl0ZXIubWF0Y2hlcihidWZmZXIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbWF0Y2hlci5yZXNldChidWZmZXIpOworICAgICAgICB9CisgICAgICAgIG1hdGNoZXIucmVnaW9uKGZpbmRTdGFydEluZGV4LCBidWZmZXJMZW5ndGgpOworICAgIH0KKworICAgIC8qCisgICAgICogU2F2ZSB0aGUgbWF0Y2hlcidzIGxhc3QgZmluZCBwb3NpdGlvbgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzYXZlQ3VycmVudFN0YXR1cygpIHsKKyAgICAgICAgcHJlU3RhcnRJbmRleCA9IGZpbmRTdGFydEluZGV4OworICAgIH0KKworICAgIC8qCisgICAgICogQ2hhbmdlIHRoZSBtYXRjaGVyJ3Mgc3RhdHVzIHRvIGxhc3QgZmluZCBwb3NpdGlvbgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWNvdmVyUHJldmlvdXNTdGF0dXMoKSB7CisgICAgICAgIGZpbmRTdGFydEluZGV4ID0gcHJlU3RhcnRJbmRleDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEdldCBpbnRlZ2VyJ3MgcGF0dGVybgorICAgICAqLworICAgIHByaXZhdGUgUGF0dGVybiBnZXRJbnRlZ2VyUGF0dGVybihpbnQgcmFkaXgpIHsKKyAgICAgICAgY2hlY2tSYWRpeChyYWRpeCk7CisgICAgICAgIGRlY2ltYWxGb3JtYXQgPSAoRGVjaW1hbEZvcm1hdCkgTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKGxvY2FsZSk7CisKKyAgICAgICAgU3RyaW5nIGFsbEF2YWlsYWJsZURpZ2l0cyA9ICIwMTIzNDU2Nzg5YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoiOworICAgICAgICBTdHJpbmcgQVNDSUlEaWdpdCA9IGFsbEF2YWlsYWJsZURpZ2l0cy5zdWJzdHJpbmcoMCwgcmFkaXgpOworICAgICAgICBTdHJpbmcgbm9uWmVyb0FTQ0lJRGlnaXQgPSBhbGxBdmFpbGFibGVEaWdpdHMuc3Vic3RyaW5nKDEsIHJhZGl4KTsKKworICAgICAgICBTdHJpbmdCdWlsZGVyIGRpZ2l0ID0gbmV3IFN0cmluZ0J1aWxkZXIoIigoP2kpWyIpLmFwcGVuZChBU0NJSURpZ2l0KQorICAgICAgICAgICAgICAgIC5hcHBlbmQoIl18XFxwe2phdmFEaWdpdH0pIik7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgbm9uWmVyb0RpZ2l0ID0gbmV3IFN0cmluZ0J1aWxkZXIoIigoP2kpWyIpLmFwcGVuZCgKKyAgICAgICAgICAgICAgICBub25aZXJvQVNDSUlEaWdpdCkuYXBwZW5kKCJdfChbXFxwe2phdmFEaWdpdH0mJlteMF1dKSkiKTsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBudW1lcmFsID0gZ2V0TnVtZXJhbChkaWdpdCwgbm9uWmVyb0RpZ2l0KTsKKworICAgICAgICBTdHJpbmdCdWlsZGVyIGludGVnZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigiKChbLStdPygiKS5hcHBlbmQobnVtZXJhbCkKKyAgICAgICAgICAgICAgICAuYXBwZW5kKCIpKSl8KCIpLmFwcGVuZChhZGRQb3NpdGl2ZVNpZ24obnVtZXJhbCkpLmFwcGVuZCgiKXwoIikKKyAgICAgICAgICAgICAgICAuYXBwZW5kKGFkZE5lZ2F0aXZlU2lnbihudW1lcmFsKSkuYXBwZW5kKCIpIik7CisKKyAgICAgICAgUGF0dGVybiBpbnRlZ2VyUGF0dGVybiA9IFBhdHRlcm4uY29tcGlsZShpbnRlZ2VyLnRvU3RyaW5nKCkpOworICAgICAgICByZXR1cm4gaW50ZWdlclBhdHRlcm47CisgICAgfQorCisgICAgLyoKKyAgICAgKiBHZXQgcGF0dGVybiBvZiBmbG9hdAorICAgICAqLworICAgIHByaXZhdGUgUGF0dGVybiBnZXRGbG9hdFBhdHRlcm4oKSB7CisgICAgICAgIGRlY2ltYWxGb3JtYXQgPSAoRGVjaW1hbEZvcm1hdCkgTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKGxvY2FsZSk7CisKKyAgICAgICAgU3RyaW5nQnVpbGRlciBkaWdpdCA9IG5ldyBTdHJpbmdCdWlsZGVyKCIoWzAtOV18KFxccHtqYXZhRGlnaXR9KSkiKTsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBub25aZXJvRGlnaXQgPSBuZXcgU3RyaW5nQnVpbGRlcigiW1xccHtqYXZhRGlnaXR9JiZbXjBdXSIpOworICAgICAgICBTdHJpbmdCdWlsZGVyIG51bWVyYWwgPSBnZXROdW1lcmFsKGRpZ2l0LCBub25aZXJvRGlnaXQpOworCisgICAgICAgIFN0cmluZyBkZWNpbWFsU2VwYXJhdG9yID0gIlxcIiArIGRlY2ltYWxGb3JtYXQuZ2V0RGVjaW1hbEZvcm1hdFN5bWJvbHMoKQorICAgICAgICAgICAgICAgICAgICAgICAgLmdldERlY2ltYWxTZXBhcmF0b3IoKTsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBkZWNpbWFsTnVtZXJhbCA9IG5ldyBTdHJpbmdCdWlsZGVyKCIoIikuYXBwZW5kKG51bWVyYWwpCisgICAgICAgICAgICAgICAgLmFwcGVuZCgifCIpLmFwcGVuZChudW1lcmFsKQorICAgICAgICAgICAgICAgIC5hcHBlbmQoZGVjaW1hbFNlcGFyYXRvcikuYXBwZW5kKGRpZ2l0KS5hcHBlbmQoIiorfCIpLmFwcGVuZCgKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlY2ltYWxTZXBhcmF0b3IpLmFwcGVuZChkaWdpdCkuYXBwZW5kKCIrKykiKTsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBleHBvbmVudCA9IG5ldyBTdHJpbmdCdWlsZGVyKCIoW2VFXVsrLV0/IikuYXBwZW5kKGRpZ2l0KQorICAgICAgICAgICAgICAgIC5hcHBlbmQoIispPyIpOworCisgICAgICAgIFN0cmluZ0J1aWxkZXIgZGVjaW1hbCA9IG5ldyBTdHJpbmdCdWlsZGVyKCIoKFstK10/IikuYXBwZW5kKAorICAgICAgICAgICAgICAgIGRlY2ltYWxOdW1lcmFsKS5hcHBlbmQoIigiKS5hcHBlbmQoZXhwb25lbnQpLmFwcGVuZCgiPykiKQorICAgICAgICAgICAgICAgIC5hcHBlbmQoIil8KCIpLmFwcGVuZChhZGRQb3NpdGl2ZVNpZ24oZGVjaW1hbE51bWVyYWwpKS5hcHBlbmQoCisgICAgICAgICAgICAgICAgICAgICAgICAiKCIpLmFwcGVuZChleHBvbmVudCkuYXBwZW5kKCI/KSIpLmFwcGVuZCgiKXwoIikKKyAgICAgICAgICAgICAgICAuYXBwZW5kKGFkZE5lZ2F0aXZlU2lnbihkZWNpbWFsTnVtZXJhbCkpLmFwcGVuZCgiKCIpLmFwcGVuZCgKKyAgICAgICAgICAgICAgICAgICAgICAgIGV4cG9uZW50KS5hcHBlbmQoIj8pIikuYXBwZW5kKCIpKSIpOworCisgICAgICAgIFN0cmluZ0J1aWxkZXIgaGV4RmxvYXQgPSBuZXcgU3RyaW5nQnVpbGRlcigiKFstK10/MFt4WF1bMC05YS1mQS1GXSoiKQorICAgICAgICAgICAgICAgIC5hcHBlbmQoIlxcLiIpLmFwcGVuZCgKKyAgICAgICAgICAgICAgICAgICAgICAgICJbMC05YS1mQS1GXSsoW3BQXVstK10/WzAtOV0rKT8pIik7CisgICAgICAgIFN0cmluZyBsb2NhbE5hTiA9IGRlY2ltYWxGb3JtYXQuZ2V0RGVjaW1hbEZvcm1hdFN5bWJvbHMoKS5nZXROYU4oKTsKKyAgICAgICAgU3RyaW5nIGxvY2FsZUluZmluaXR5ID0gZGVjaW1hbEZvcm1hdC5nZXREZWNpbWFsRm9ybWF0U3ltYm9scygpCisgICAgICAgICAgICAgICAgLmdldEluZmluaXR5KCk7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgbm9uTnVtYmVyID0gbmV3IFN0cmluZ0J1aWxkZXIoIihOYU58XFxRIikuYXBwZW5kKGxvY2FsTmFOKQorICAgICAgICAgICAgICAgIC5hcHBlbmQoIlxcRXxJbmZpbml0eXxcXFEiKS5hcHBlbmQobG9jYWxlSW5maW5pdHkpLmFwcGVuZCgiXFxFKSIpOworICAgICAgICBTdHJpbmdCdWlsZGVyIHNpbmdlZE5vbk51bWJlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCIoKChbLStdPygiKS5hcHBlbmQoCisgICAgICAgICAgICAgICAgbm9uTnVtYmVyKS5hcHBlbmQoIikpKXwoIikuYXBwZW5kKGFkZFBvc2l0aXZlU2lnbihub25OdW1iZXIpKQorICAgICAgICAgICAgICAgIC5hcHBlbmQoIil8KCIpLmFwcGVuZChhZGROZWdhdGl2ZVNpZ24obm9uTnVtYmVyKSkuYXBwZW5kKCIpKSIpOworCisgICAgICAgIFN0cmluZ0J1aWxkZXIgZmxvYXRTdHJpbmcgPSBuZXcgU3RyaW5nQnVpbGRlcigpLmFwcGVuZChkZWNpbWFsKS5hcHBlbmQoCisgICAgICAgICAgICAgICAgInwiKS5hcHBlbmQoaGV4RmxvYXQpLmFwcGVuZCgifCIpLmFwcGVuZChzaW5nZWROb25OdW1iZXIpOworICAgICAgICBQYXR0ZXJuIGZsb2F0UGF0dGVybiA9IFBhdHRlcm4uY29tcGlsZShmbG9hdFN0cmluZy50b1N0cmluZygpKTsKKyAgICAgICAgcmV0dXJuIGZsb2F0UGF0dGVybjsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZ0J1aWxkZXIgZ2V0TnVtZXJhbChTdHJpbmdCdWlsZGVyIGRpZ2l0LAorICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBub25aZXJvRGlnaXQpIHsKKyAgICAgICAgU3RyaW5nIGdyb3VwU2VwYXJhdG9yID0gIlxcIgorICAgICAgICAgICAgICAgICsgZGVjaW1hbEZvcm1hdC5nZXREZWNpbWFsRm9ybWF0U3ltYm9scygpCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0R3JvdXBpbmdTZXBhcmF0b3IoKTsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBncm91cGVkTnVtZXJhbCA9IG5ldyBTdHJpbmdCdWlsZGVyKCIoIikuYXBwZW5kKAorICAgICAgICAgICAgICAgIG5vblplcm9EaWdpdCkuYXBwZW5kKGRpZ2l0KS5hcHBlbmQoIj8iKS5hcHBlbmQoZGlnaXQpLmFwcGVuZCgKKyAgICAgICAgICAgICAgICAiPygiKS5hcHBlbmQoZ3JvdXBTZXBhcmF0b3IpLmFwcGVuZChkaWdpdCkuYXBwZW5kKGRpZ2l0KQorICAgICAgICAgICAgICAgIC5hcHBlbmQoZGlnaXQpLmFwcGVuZCgiKSspIik7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgbnVtZXJhbCA9IG5ldyBTdHJpbmdCdWlsZGVyKCIoKCIpLmFwcGVuZChkaWdpdCkuYXBwZW5kKAorICAgICAgICAgICAgICAgICIrKyl8IikuYXBwZW5kKGdyb3VwZWROdW1lcmFsKS5hcHBlbmQoIikiKTsKKyAgICAgICAgcmV0dXJuIG51bWVyYWw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBBZGQgdGhlIGxvY2FsZSBzcGVjaWZpYyBwb3NpdGl2ZSBwcmVmaXhlcyBhbmQgc3VmZml4ZXMgdG8gdGhlIHBhdHRlcm4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZ0J1aWxkZXIgYWRkUG9zaXRpdmVTaWduKFN0cmluZ0J1aWxkZXIgdW5TaWduTnVtZXJhbCkgeworICAgICAgICBTdHJpbmcgcG9zaXRpdmVQcmVmaXggPSAiIjsKKyAgICAgICAgU3RyaW5nIHBvc2l0aXZlU3VmZml4ID0gIiI7CisgICAgICAgIGlmICghZGVjaW1hbEZvcm1hdC5nZXRQb3NpdGl2ZVByZWZpeCgpLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcG9zaXRpdmVQcmVmaXggPSAiXFxRIiArIGRlY2ltYWxGb3JtYXQuZ2V0UG9zaXRpdmVQcmVmaXgoKSArICJcXEUiOworICAgICAgICB9CisgICAgICAgIGlmICghZGVjaW1hbEZvcm1hdC5nZXRQb3NpdGl2ZVN1ZmZpeCgpLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcG9zaXRpdmVTdWZmaXggPSAiXFxRIiArIGRlY2ltYWxGb3JtYXQuZ2V0UG9zaXRpdmVTdWZmaXgoKSArICJcXEUiOworICAgICAgICB9CisgICAgICAgIFN0cmluZ0J1aWxkZXIgc2lnbmVkTnVtZXJhbCA9IG5ldyBTdHJpbmdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuYXBwZW5kKHBvc2l0aXZlUHJlZml4KS5hcHBlbmQodW5TaWduTnVtZXJhbCkuYXBwZW5kKAorICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVTdWZmaXgpOworICAgICAgICByZXR1cm4gc2lnbmVkTnVtZXJhbDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEFkZCB0aGUgbG9jYWxlIHNwZWNpZmljIG5lZ2F0aXZlIHByZWZpeGVzIGFuZCBzdWZmaXhlcyB0byB0aGUgcGF0dGVybgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nQnVpbGRlciBhZGROZWdhdGl2ZVNpZ24oU3RyaW5nQnVpbGRlciB1blNpZ25OdW1lcmFsKSB7CisgICAgICAgIFN0cmluZyBuZWdhdGl2ZVByZWZpeCA9ICIiOworICAgICAgICBTdHJpbmcgbmVnYXRpdmVTdWZmaXggPSAiIjsKKyAgICAgICAgaWYgKCFkZWNpbWFsRm9ybWF0LmdldE5lZ2F0aXZlUHJlZml4KCkuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBuZWdhdGl2ZVByZWZpeCA9ICJcXFEiICsgZGVjaW1hbEZvcm1hdC5nZXROZWdhdGl2ZVByZWZpeCgpICsgIlxcRSI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFkZWNpbWFsRm9ybWF0LmdldE5lZ2F0aXZlU3VmZml4KCkuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBuZWdhdGl2ZVN1ZmZpeCA9ICJcXFEiICsgZGVjaW1hbEZvcm1hdC5nZXROZWdhdGl2ZVN1ZmZpeCgpICsgIlxcRSI7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nQnVpbGRlciBzaWduZWROdW1lcmFsID0gbmV3IFN0cmluZ0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5hcHBlbmQobmVnYXRpdmVQcmVmaXgpLmFwcGVuZCh1blNpZ25OdW1lcmFsKS5hcHBlbmQoCisgICAgICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZVN1ZmZpeCk7CisgICAgICAgIHJldHVybiBzaWduZWROdW1lcmFsOworICAgIH0KKworICAgIC8qCisgICAgICogUmVtb3ZlIGxvY2FsZSByZWxhdGVkIGluZm9ybWF0aW9uIGZyb20gZmxvYXQgU3RyaW5nCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgcmVtb3ZlTG9jYWxlSW5mb0Zyb21GbG9hdChTdHJpbmcgZmxvYXRTdHJpbmcpIHsKKyAgICAgICAgLy8gSWYgdGhlIHRva2VuIGlzIEhleEZsb2F0CisgICAgICAgIGlmICgtMSAhPSBmbG9hdFN0cmluZy5pbmRleE9mKCd4JykgfHwgLTEgIT0gZmxvYXRTdHJpbmcuaW5kZXhPZignWCcpKSB7CisgICAgICAgICAgICByZXR1cm4gZmxvYXRTdHJpbmc7CisgICAgICAgIH0KKworICAgICAgICBpbnQgZXhwb25lbnRJbmRleDsKKyAgICAgICAgU3RyaW5nIGRlY2ltYWxOdW1lcmFsU3RyaW5nOworICAgICAgICBTdHJpbmcgZXhwb25lbnRTdHJpbmc7CisgICAgICAgIC8vIElmIHRoZSB0b2tlbiBpcyBzY2llbnRpZmljIG5vdGF0aW9uCisgICAgICAgIGlmICgtMSAhPSAoZXhwb25lbnRJbmRleCA9IGZsb2F0U3RyaW5nLmluZGV4T2YoJ2UnKSkKKyAgICAgICAgICAgICAgICB8fCAtMSAhPSAoZXhwb25lbnRJbmRleCA9IGZsb2F0U3RyaW5nLmluZGV4T2YoJ0UnKSkpIHsKKyAgICAgICAgICAgIGRlY2ltYWxOdW1lcmFsU3RyaW5nID0gZmxvYXRTdHJpbmcuc3Vic3RyaW5nKDAsIGV4cG9uZW50SW5kZXgpOworICAgICAgICAgICAgZXhwb25lbnRTdHJpbmcgPSBmbG9hdFN0cmluZy5zdWJzdHJpbmcoZXhwb25lbnRJbmRleCArIDEsCisgICAgICAgICAgICAgICAgICAgIGZsb2F0U3RyaW5nLmxlbmd0aCgpKTsKKyAgICAgICAgICAgIGRlY2ltYWxOdW1lcmFsU3RyaW5nID0gcmVtb3ZlTG9jYWxlSW5mbyhkZWNpbWFsTnVtZXJhbFN0cmluZywKKyAgICAgICAgICAgICAgICAgICAgRGF0YVR5cGUuRkxPQVQpOworICAgICAgICAgICAgcmV0dXJuIGRlY2ltYWxOdW1lcmFsU3RyaW5nICsgImUiICsgZXhwb25lbnRTdHJpbmc7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlbW92ZUxvY2FsZUluZm8oZmxvYXRTdHJpbmcsIERhdGFUeXBlLkZMT0FUKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFJlbW92ZSB0aGUgbG9jYWxlIHNwZWNpZmljIHByZWZpeGVzLCBncm91cCBzZXBhcmF0b3JzLCBhbmQgbG9jYWxlCisgICAgICogc3BlY2lmaWMgc3VmZml4ZXMgZnJvbSBpbnB1dCBzdHJpbmcKKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyByZW1vdmVMb2NhbGVJbmZvKFN0cmluZyB0b2tlbiwgRGF0YVR5cGUgdHlwZSkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHRva2VuQnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKHRva2VuKTsKKyAgICAgICAgYm9vbGVhbiBuZWdhdGl2ZSA9IHJlbW92ZUxvY2FsZVNpZ24odG9rZW5CdWlsZGVyKTsKKyAgICAgICAgLy8gUmVtb3ZlIGdyb3VwIHNlcGFyYXRvcgorICAgICAgICBTdHJpbmcgZ3JvdXBTZXBhcmF0b3IgPSBTdHJpbmcudmFsdWVPZihkZWNpbWFsRm9ybWF0CisgICAgICAgICAgICAgICAgLmdldERlY2ltYWxGb3JtYXRTeW1ib2xzKCkuZ2V0R3JvdXBpbmdTZXBhcmF0b3IoKSk7CisgICAgICAgIGludCBzZXBhcmF0b3JJbmRleCA9IC0xOworICAgICAgICB3aGlsZSAoLTEgIT0gKHNlcGFyYXRvckluZGV4ID0gdG9rZW5CdWlsZGVyLmluZGV4T2YoZ3JvdXBTZXBhcmF0b3IpKSkgeworICAgICAgICAgICAgdG9rZW5CdWlsZGVyLmRlbGV0ZShzZXBhcmF0b3JJbmRleCwgc2VwYXJhdG9ySW5kZXggKyAxKTsKKyAgICAgICAgfQorICAgICAgICAvLyBSZW1vdmUgZGVjaW1hbCBzZXBhcmF0b3IKKyAgICAgICAgU3RyaW5nIGRlY2ltYWxTZXBhcmF0b3IgPSBTdHJpbmcudmFsdWVPZihkZWNpbWFsRm9ybWF0CisgICAgICAgICAgICAgICAgLmdldERlY2ltYWxGb3JtYXRTeW1ib2xzKCkuZ2V0RGVjaW1hbFNlcGFyYXRvcigpKTsKKyAgICAgICAgc2VwYXJhdG9ySW5kZXggPSB0b2tlbkJ1aWxkZXIuaW5kZXhPZihkZWNpbWFsU2VwYXJhdG9yKTsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigiIik7CisgICAgICAgIGlmIChEYXRhVHlwZS5JTlQgPT0gdHlwZSkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0b2tlbkJ1aWxkZXIubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgICAgIGlmICgtMSAhPSBDaGFyYWN0ZXIuZGlnaXQodG9rZW5CdWlsZGVyLmNoYXJBdChpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIENoYXJhY3Rlci5NQVhfUkFESVgpKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQodG9rZW5CdWlsZGVyLmNoYXJBdChpKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChEYXRhVHlwZS5GTE9BVCA9PSB0eXBlKSB7CisgICAgICAgICAgICBpZiAodG9rZW5CdWlsZGVyLnRvU3RyaW5nKCkuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICBkZWNpbWFsRm9ybWF0LmdldERlY2ltYWxGb3JtYXRTeW1ib2xzKCkuZ2V0TmFOKCkpKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiTmFOIik7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHRva2VuQnVpbGRlci50b1N0cmluZygpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgZGVjaW1hbEZvcm1hdC5nZXREZWNpbWFsRm9ybWF0U3ltYm9scygpLmdldEluZmluaXR5KCkpKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiSW5maW5pdHkiKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0b2tlbkJ1aWxkZXIubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBpZiAoLTEgIT0gQ2hhcmFjdGVyLmRpZ2l0KHRva2VuQnVpbGRlci5jaGFyQXQoaSksIDEwKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChDaGFyYWN0ZXIuZGlnaXQodG9rZW5CdWlsZGVyLmNoYXJBdChpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTApKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBUb2tlbiBpcyBOYU4gb3IgSW5maW5pdHkKKyAgICAgICAgaWYgKHJlc3VsdC5sZW5ndGgoKSA9PSAwKSB7CisgICAgICAgICAgICByZXN1bHQgPSB0b2tlbkJ1aWxkZXI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKC0xICE9IHNlcGFyYXRvckluZGV4KSB7CisgICAgICAgICAgICByZXN1bHQuaW5zZXJ0KHNlcGFyYXRvckluZGV4LCAiLiIpOworICAgICAgICB9CisgICAgICAgIC8vIElmIGlucHV0IGlzIG5lZ2F0aXZlCisgICAgICAgIGlmIChuZWdhdGl2ZSkgeworICAgICAgICAgICAgcmVzdWx0Lmluc2VydCgwLCAnLScpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFJlbW92ZSBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgc2lnbiBmcm9tIHRoZSBwYXJhbWV0ZXIgc3RyaW5nQnVpbGRlciwgYW5kCisgICAgICogcmV0dXJuIHdoZXRoZXIgdGhlIGlucHV0IHN0cmluZyBpcyBuZWdhdGl2ZQorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiByZW1vdmVMb2NhbGVTaWduKFN0cmluZ0J1aWxkZXIgdG9rZW5CdWlsZGVyKSB7CisgICAgICAgIFN0cmluZyBwb3NpdGl2ZVByZWZpeCA9IGRlY2ltYWxGb3JtYXQuZ2V0UG9zaXRpdmVQcmVmaXgoKTsKKyAgICAgICAgU3RyaW5nIHBvc2l0aXZlU3VmZml4ID0gZGVjaW1hbEZvcm1hdC5nZXRQb3NpdGl2ZVN1ZmZpeCgpOworICAgICAgICBTdHJpbmcgbmVnYXRpdmVQcmVmaXggPSBkZWNpbWFsRm9ybWF0LmdldE5lZ2F0aXZlUHJlZml4KCk7CisgICAgICAgIFN0cmluZyBuZWdhdGl2ZVN1ZmZpeCA9IGRlY2ltYWxGb3JtYXQuZ2V0TmVnYXRpdmVTdWZmaXgoKTsKKworICAgICAgICBpZiAodG9rZW5CdWlsZGVyLmluZGV4T2YoIisiKSA9PSAwKSB7CisgICAgICAgICAgICB0b2tlbkJ1aWxkZXIuZGVsZXRlKDAsIDEpOworICAgICAgICB9CisgICAgICAgIGlmICghcG9zaXRpdmVQcmVmaXguaXNFbXB0eSgpICYmIHRva2VuQnVpbGRlci5pbmRleE9mKHBvc2l0aXZlUHJlZml4KSA9PSAwKSB7CisgICAgICAgICAgICB0b2tlbkJ1aWxkZXIuZGVsZXRlKDAsIHBvc2l0aXZlUHJlZml4Lmxlbmd0aCgpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXBvc2l0aXZlU3VmZml4LmlzRW1wdHkoKQorICAgICAgICAgICAgICAgICYmIC0xICE9IHRva2VuQnVpbGRlci5pbmRleE9mKHBvc2l0aXZlU3VmZml4KSkgeworICAgICAgICAgICAgdG9rZW5CdWlsZGVyLmRlbGV0ZSgKKyAgICAgICAgICAgICAgICAgICAgdG9rZW5CdWlsZGVyLmxlbmd0aCgpIC0gcG9zaXRpdmVTdWZmaXgubGVuZ3RoKCksCisgICAgICAgICAgICAgICAgICAgIHRva2VuQnVpbGRlci5sZW5ndGgoKSk7CisgICAgICAgIH0KKyAgICAgICAgYm9vbGVhbiBuZWdhdGl2ZSA9IGZhbHNlOworICAgICAgICBpZiAodG9rZW5CdWlsZGVyLmluZGV4T2YoIi0iKSA9PSAwKSB7CisgICAgICAgICAgICB0b2tlbkJ1aWxkZXIuZGVsZXRlKDAsIDEpOworICAgICAgICAgICAgbmVnYXRpdmUgPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghbmVnYXRpdmVQcmVmaXguaXNFbXB0eSgpICYmIHRva2VuQnVpbGRlci5pbmRleE9mKG5lZ2F0aXZlUHJlZml4KSA9PSAwKSB7CisgICAgICAgICAgICB0b2tlbkJ1aWxkZXIuZGVsZXRlKDAsIG5lZ2F0aXZlUHJlZml4Lmxlbmd0aCgpKTsKKyAgICAgICAgICAgIG5lZ2F0aXZlID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIW5lZ2F0aXZlU3VmZml4LmlzRW1wdHkoKQorICAgICAgICAgICAgICAgICYmIC0xICE9IHRva2VuQnVpbGRlci5pbmRleE9mKG5lZ2F0aXZlU3VmZml4KSkgeworICAgICAgICAgICAgdG9rZW5CdWlsZGVyLmRlbGV0ZSgKKyAgICAgICAgICAgICAgICAgICAgdG9rZW5CdWlsZGVyLmxlbmd0aCgpIC0gbmVnYXRpdmVTdWZmaXgubGVuZ3RoKCksCisgICAgICAgICAgICAgICAgICAgIHRva2VuQnVpbGRlci5sZW5ndGgoKSk7CisgICAgICAgICAgICBuZWdhdGl2ZSA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5lZ2F0aXZlOworICAgIH0KKworICAgIC8qCisgICAgICogRmluZCB0aGUgcHJlZml4ZWQgZGVsaW1pdGVyIGFuZCBwb3NlZml4ZWQgZGVsaW1pdGVyIGluIHRoZSBpbnB1dCByZXNvdXJjZQorICAgICAqIGFuZCBzZXQgdGhlIHN0YXJ0IGluZGV4IGFuZCBlbmQgaW5kZXggb2YgTWF0Y2hlciByZWdpb24uIElmIHBvc3RmaXhlZAorICAgICAqIGRlbGltaXRlciBkb2VzIG5vdCBleGlzdCwgdGhlIGVuZCBpbmRleCBpcyBzZXQgdG8gYmUgZW5kIG9mIGlucHV0LgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBzZXRUb2tlblJlZ2lvbigpIHsKKyAgICAgICAgLy8gVGhlIHBvc2l0aW9uIHdoZXJlIHRva2VuIGJlZ2lucworICAgICAgICBpbnQgdG9rZW5TdGFydEluZGV4ID0gMDsKKyAgICAgICAgLy8gVGhlIHBvc2l0aW9uIHdoZXJlIHRva2VuIGVuZHMKKyAgICAgICAgaW50IHRva2VuRW5kSW5kZXggPSAwOworICAgICAgICAvLyBVc2UgZGVsaW1pdGVyIHBhdHRlcm4KKyAgICAgICAgbWF0Y2hlci51c2VQYXR0ZXJuKGRlbGltaXRlcik7CisgICAgICAgIG1hdGNoZXIucmVnaW9uKGZpbmRTdGFydEluZGV4LCBidWZmZXJMZW5ndGgpOworCisgICAgICAgIHRva2VuU3RhcnRJbmRleCA9IGZpbmRQcmVEZWxpbWl0ZXIoKTsKKyAgICAgICAgaWYgKHNldEhlYWRUb2tlblJlZ2lvbih0b2tlblN0YXJ0SW5kZXgpKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICB0b2tlbkVuZEluZGV4ID0gZmluZFBvc3REZWxpbWl0ZXIoKTsKKyAgICAgICAgLy8gSWYgdGhlIHNlY29uZCBkZWxpbWl0ZXIgaXMgbm90IGZvdW5kCisgICAgICAgIGlmICgtMSA9PSB0b2tlbkVuZEluZGV4KSB7CisgICAgICAgICAgICAvLyBKdXN0IGZpcnN0IERlbGltaXRlciBFeGlzdHMKKyAgICAgICAgICAgIGlmIChmaW5kU3RhcnRJbmRleCA9PSBidWZmZXJMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0b2tlbkVuZEluZGV4ID0gYnVmZmVyTGVuZ3RoOworICAgICAgICAgICAgZmluZFN0YXJ0SW5kZXggPSBidWZmZXJMZW5ndGg7CisgICAgICAgIH0KKworICAgICAgICBtYXRjaGVyLnJlZ2lvbih0b2tlblN0YXJ0SW5kZXgsIHRva2VuRW5kSW5kZXgpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEZpbmQgcHJlZml4IGRlbGltaXRlcgorICAgICAqLworICAgIHByaXZhdGUgaW50IGZpbmRQcmVEZWxpbWl0ZXIoKSB7CisgICAgICAgIGludCB0b2tlblN0YXJ0SW5kZXg7CisgICAgICAgIGJvb2xlYW4gZmluZENvbXBsZXRlID0gZmFsc2U7CisgICAgICAgIHdoaWxlICghZmluZENvbXBsZXRlKSB7CisgICAgICAgICAgICBpZiAobWF0Y2hlci5maW5kKCkpIHsKKyAgICAgICAgICAgICAgICBmaW5kQ29tcGxldGUgPSB0cnVlOworICAgICAgICAgICAgICAgIC8vIElmIGp1c3QgZGVsaW1pdGVyIHJlbWFpbnMKKyAgICAgICAgICAgICAgICBpZiAobWF0Y2hlci5zdGFydCgpID09IGZpbmRTdGFydEluZGV4CisgICAgICAgICAgICAgICAgICAgICAgICAmJiBtYXRjaGVyLmVuZCgpID09IGJ1ZmZlckxlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICAvLyBJZiBtb3JlIGlucHV0IHJlc291cmNlIGV4aXN0cworICAgICAgICAgICAgICAgICAgICBpZiAoIWlucHV0RXhoYXVzdGVkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZWFkTW9yZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXRNYXRjaGVyKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBmaW5kQ29tcGxldGUgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKCFpbnB1dEV4aGF1c3RlZCkgeworICAgICAgICAgICAgICAgICAgICByZWFkTW9yZSgpOworICAgICAgICAgICAgICAgICAgICByZXNldE1hdGNoZXIoKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRva2VuU3RhcnRJbmRleCA9IG1hdGNoZXIuZW5kKCk7CisgICAgICAgIGZpbmRTdGFydEluZGV4ID0gbWF0Y2hlci5lbmQoKTsKKyAgICAgICAgcmV0dXJuIHRva2VuU3RhcnRJbmRleDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEhhbmRsZSBzb21lIHNwZWNpYWwgY2FzZXMKKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gc2V0SGVhZFRva2VuUmVnaW9uKGludCBmaW5kSW5kZXgpIHsKKyAgICAgICAgaW50IHRva2VuU3RhcnRJbmRleDsKKyAgICAgICAgaW50IHRva2VuRW5kSW5kZXg7CisgICAgICAgIGJvb2xlYW4gc2V0U3VjY2VzcyA9IGZhbHNlOworICAgICAgICAvLyBJZiBubyBkZWxpbWl0ZXIgZXhpc3RzLCBidXQgc29tZXRoaW5nIGV4aXRlcyBpbiB0aGlzIHNjYW5uZXIKKyAgICAgICAgaWYgKC0xID09IGZpbmRJbmRleCAmJiBwcmVTdGFydEluZGV4ICE9IGJ1ZmZlckxlbmd0aCkgeworICAgICAgICAgICAgdG9rZW5TdGFydEluZGV4ID0gcHJlU3RhcnRJbmRleDsKKyAgICAgICAgICAgIHRva2VuRW5kSW5kZXggPSBidWZmZXJMZW5ndGg7CisgICAgICAgICAgICBmaW5kU3RhcnRJbmRleCA9IGJ1ZmZlckxlbmd0aDsKKyAgICAgICAgICAgIG1hdGNoZXIucmVnaW9uKHRva2VuU3RhcnRJbmRleCwgdG9rZW5FbmRJbmRleCk7CisgICAgICAgICAgICBzZXRTdWNjZXNzID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICAvLyBJZiB0aGUgZmlyc3QgZGVsaW1pdGVyIG9mIHNjYW5uZXIgaXMgbm90IGF0IHRoZSBmaW5kIHN0YXJ0IHBvc2l0aW9uCisgICAgICAgIGlmICgtMSAhPSBmaW5kSW5kZXggJiYgcHJlU3RhcnRJbmRleCAhPSBtYXRjaGVyLnN0YXJ0KCkpIHsKKyAgICAgICAgICAgIHRva2VuU3RhcnRJbmRleCA9IHByZVN0YXJ0SW5kZXg7CisgICAgICAgICAgICB0b2tlbkVuZEluZGV4ID0gbWF0Y2hlci5zdGFydCgpOworICAgICAgICAgICAgZmluZFN0YXJ0SW5kZXggPSBtYXRjaGVyLnN0YXJ0KCk7CisgICAgICAgICAgICAvLyBzZXQgbWF0Y2ggcmVnaW9uIGFuZCByZXR1cm4KKyAgICAgICAgICAgIG1hdGNoZXIucmVnaW9uKHRva2VuU3RhcnRJbmRleCwgdG9rZW5FbmRJbmRleCk7CisgICAgICAgICAgICBzZXRTdWNjZXNzID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2V0U3VjY2VzczsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEZpbmQgcG9zdGZpeCBkZWxpbWl0ZXIKKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBmaW5kUG9zdERlbGltaXRlcigpIHsKKyAgICAgICAgaW50IHRva2VuRW5kSW5kZXggPSAwOworICAgICAgICBib29sZWFuIGZpbmRDb21wbGV0ZSA9IGZhbHNlOworICAgICAgICB3aGlsZSAoIWZpbmRDb21wbGV0ZSkgeworICAgICAgICAgICAgaWYgKG1hdGNoZXIuZmluZCgpKSB7CisgICAgICAgICAgICAgICAgZmluZENvbXBsZXRlID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBpZiAobWF0Y2hlci5zdGFydCgpID09IGZpbmRTdGFydEluZGV4CisgICAgICAgICAgICAgICAgICAgICAgICAmJiBtYXRjaGVyLnN0YXJ0KCkgPT0gbWF0Y2hlci5lbmQoKSkgeworICAgICAgICAgICAgICAgICAgICBmaW5kQ29tcGxldGUgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmICghaW5wdXRFeGhhdXN0ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVhZE1vcmUoKTsKKyAgICAgICAgICAgICAgICAgICAgcmVzZXRNYXRjaGVyKCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0b2tlbkVuZEluZGV4ID0gbWF0Y2hlci5zdGFydCgpOworICAgICAgICBmaW5kU3RhcnRJbmRleCA9IG1hdGNoZXIuc3RhcnQoKTsKKyAgICAgICAgcmV0dXJuIHRva2VuRW5kSW5kZXg7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBSZWFkIG1vcmUgZGF0YSBmcm9tIHVuZGVybHlpbmcgUmVhZGFibGUuIElmIG5vdGhpbmcgaXMgYXZhaWxhYmxlIG9yIEkvTworICAgICAqIG9wZXJhdGlvbiBmYWlscywgZ2xvYmFsIGJvb2xlYW4gdmFyaWFibGUgaW5wdXRFeGhhdXN0ZWQgd2lsbCBiZSBzZXQgdG8KKyAgICAgKiB0cnVlLCBvdGhlcndpc2Ugc2V0IHRvIGZhbHNlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkTW9yZSgpIHsKKyAgICAgICAgaW50IG9sZFBvc2l0aW9uID0gYnVmZmVyLnBvc2l0aW9uKCk7CisgICAgICAgIGludCBvbGRCdWZmZXJMZW5ndGggPSBidWZmZXJMZW5ndGg7CisgICAgICAgIC8vIEluY3JlYXNlIGNhcGFjaXR5IGlmIGVtcHR5IHNwYWNlIGlzIG5vdCBlbm91Z2gKKyAgICAgICAgaWYgKGJ1ZmZlckxlbmd0aCA+PSBidWZmZXIuY2FwYWNpdHkoKSkgeworICAgICAgICAgICAgZXhwYW5kQnVmZmVyKCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBSZWFkIGlucHV0IHJlc291cmNlCisgICAgICAgIGludCByZWFkQ291bnQgPSAwOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnVmZmVyLmxpbWl0KGJ1ZmZlci5jYXBhY2l0eSgpKTsKKyAgICAgICAgICAgIGJ1ZmZlci5wb3NpdGlvbihvbGRCdWZmZXJMZW5ndGgpOworICAgICAgICAgICAgd2hpbGUgKChyZWFkQ291bnQgPSBpbnB1dC5yZWFkKGJ1ZmZlcikpID09IDApIHsKKyAgICAgICAgICAgICAgICAvLyBub3RoaW5nIHRvIGRvIGhlcmUKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29uc2lkZXIgdGhlIHNjZW5hcmlvOiByZWFkYWJsZSBwdXRzIDQgY2hhcnMgaW50bworICAgICAgICAgICAgLy8gYnVmZmVyIGFuZCB0aGVuIGFuIElPRXhjZXB0aW9uIGlzIHRocm93biBvdXQuIEluIHRoaXMgY2FzZSwKKyAgICAgICAgICAgIC8vIGJ1ZmZlciBpcworICAgICAgICAgICAgLy8gYWN0dWFsbHkgZ3Jvd24sIGJ1dCByZWFkYWJsZS5yZWFkKCkgd2lsbCBuZXZlciByZXR1cm4uCisgICAgICAgICAgICBidWZmZXJMZW5ndGggPSBidWZmZXIucG9zaXRpb24oKTsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBVc2VzIC0xIHRvIHJlY29yZCBJT0V4Y2VwdGlvbiBvY2N1cnJpbmcsIGFuZCBubyBtb3JlIGlucHV0IGNhbiBiZQorICAgICAgICAgICAgICogcmVhZC4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgcmVhZENvdW50ID0gLTE7CisgICAgICAgICAgICBsYXN0SU9FeGNlcHRpb24gPSBlOworICAgICAgICB9CisKKyAgICAgICAgYnVmZmVyLmZsaXAoKTsKKyAgICAgICAgYnVmZmVyLnBvc2l0aW9uKG9sZFBvc2l0aW9uKTsKKyAgICAgICAgaWYgKC0xID09IHJlYWRDb3VudCkgeworICAgICAgICAgICAgaW5wdXRFeGhhdXN0ZWQgPSB0cnVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYnVmZmVyTGVuZ3RoID0gcmVhZENvdW50ICsgYnVmZmVyTGVuZ3RoOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gRXhwYW5kIHRoZSBzaXplIG9mIGludGVybmFsIGJ1ZmZlci4KKyAgICBwcml2YXRlIHZvaWQgZXhwYW5kQnVmZmVyKCkgeworICAgICAgICBpbnQgb2xkUG9zaXRpb24gPSBidWZmZXIucG9zaXRpb24oKTsKKyAgICAgICAgaW50IG9sZENhcGFjaXR5ID0gYnVmZmVyLmNhcGFjaXR5KCk7CisgICAgICAgIGludCBvbGRMaW1pdCA9IGJ1ZmZlci5saW1pdCgpOworICAgICAgICBpbnQgbmV3Q2FwYWNpdHkgPSBvbGRDYXBhY2l0eSAqIERJUExPSUQ7CisgICAgICAgIGNoYXJbXSBuZXdCdWZmZXIgPSBuZXcgY2hhcltuZXdDYXBhY2l0eV07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLmFycmF5KCksIDAsIG5ld0J1ZmZlciwgMCwgb2xkTGltaXQpOworICAgICAgICBidWZmZXIgPSBDaGFyQnVmZmVyLndyYXAobmV3QnVmZmVyLCAwLCBuZXdDYXBhY2l0eSk7CisgICAgICAgIGJ1ZmZlci5wb3NpdGlvbihvbGRQb3NpdGlvbik7CisgICAgICAgIGJ1ZmZlci5saW1pdChvbGRMaW1pdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzZXRzIHRoaXMgc2Nhbm5lcidzIGRlbGltaXRlciwgbG9jYWxlLCBhbmQgcmFkaXguCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgc2Nhbm5lcgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgU2Nhbm5lciByZXNldCgpIHsKKyAgICAgICAgZGVsaW1pdGVyID0gREVGQVVMVF9ERUxJTUlURVI7CisgICAgICAgIGxvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgICAgIGludGVnZXJSYWRpeCA9IDEwOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1NlcnZpY2VDb25maWd1cmF0aW9uRXJyb3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcxZmNlNjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1NlcnZpY2VDb25maWd1cmF0aW9uRXJyb3IuamF2YQpAQCAtMCwwICsxLDQzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworLyoqCisgKiBUaHJvd24gd2hlbiBhIHNlcnZpY2UgcHJvdmlkZXIgY2FuJ3QgYmUgbG9hZGVkIGJ5IHtAbGluayBTZXJ2aWNlTG9hZGVyfS4KKyAqIEBzaW5jZSAxLjYKKyAqLworcHVibGljIGNsYXNzIFNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzQxMzI3NzA0MTQ4ODFMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBlcnJvciB3aXRoIHRoZSBnaXZlbiBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKiBAcGFyYW0gbWVzc2FnZSB0aGUgZGV0YWlsIG1lc3NhZ2UsIG9yIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvcihTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGVycm9yIHdpdGggdGhlIGdpdmVuIGRldGFpbCBtZXNzYWdlIGFuZCBjYXVzZS4KKyAgICAgKiBAcGFyYW0gbWVzc2FnZSB0aGUgZGV0YWlsIG1lc3NhZ2UsIG9yIG51bGwKKyAgICAgKiBAcGFyYW0gY2F1c2UgdGhlIGNhdXNlLCBudWxsCisgICAgICovCisgICAgcHVibGljIFNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3IoU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlLCBjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9TZXJ2aWNlTG9hZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1NlcnZpY2VMb2FkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZWFjYWFiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9TZXJ2aWNlTG9hZGVyLmphdmEKQEAgLTAsMCArMSwyNjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBsaWJjb3JlLmlvLklvVXRpbHM7CisKKy8qKgorICogQSBzZXJ2aWNlLXByb3ZpZGVyIGxvYWRlci4KKyAqCisgKiA8cD5BIHNlcnZpY2UgcHJvdmlkZXIgaXMgYSBmYWN0b3J5IGZvciBjcmVhdGluZyBhbGwga25vd24gaW1wbGVtZW50YXRpb25zIG9mIGEgcGFydGljdWxhcgorICogY2xhc3Mgb3IgaW50ZXJmYWNlIHtAY29kZSBTfS4gVGhlIGtub3duIGltcGxlbWVudGF0aW9ucyBhcmUgcmVhZCBmcm9tIGEgY29uZmlndXJhdGlvbiBmaWxlIGluCisgKiB7QGNvZGUgTUVUQS1JTkYvc2VydmljZXMvfS4gVGhlIGZpbGUncyBuYW1lIHNob3VsZCBtYXRjaCB0aGUgY2xhc3MnIGJpbmFyeSBuYW1lIChzdWNoIGFzCisgKiB7QGNvZGUgamF2YS51dGlsLk91dGVyJElubmVyfSkuCisgKgorICogPHA+VGhlIGZpbGUgZm9ybWF0IGlzIGFzIGZvbGxvd3MuCisgKiBUaGUgZmlsZSdzIGNoYXJhY3RlciBlbmNvZGluZyBtdXN0IGJlIFVURi04LgorICogV2hpdGVzcGFjZSBpcyBpZ25vcmVkLCBhbmQge0Bjb2RlICN9IGlzIHVzZWQgdG8gYmVnaW4gYSBjb21tZW50IHRoYXQgY29udGludWVzIHRvIHRoZQorICogbmV4dCBuZXdsaW5lLgorICogTGluZXMgdGhhdCBhcmUgZW1wdHkgYWZ0ZXIgY29tbWVudCByZW1vdmFsIGFuZCB3aGl0ZXNwYWNlIHRyaW1taW5nIGFyZSBpZ25vcmVkLgorICogT3RoZXJ3aXNlLCBlYWNoIGxpbmUgY29udGFpbnMgdGhlIGJpbmFyeSBuYW1lIG9mIG9uZSBpbXBsZW1lbnRhdGlvbiBjbGFzcy4KKyAqIER1cGxpY2F0ZSBlbnRyaWVzIGFyZSBpZ25vcmVkLCBidXQgZW50cmllcyBhcmUgb3RoZXJ3aXNlIHJldHVybmVkIGluIG9yZGVyICh0aGF0IGlzLCB0aGUgZmlsZQorICogaXMgdHJlYXRlZCBhcyBhbiBvcmRlcmVkIHNldCkuCisgKgorICogPHA+R2l2ZW4gdGhlc2UgY2xhc3NlczoKKyAqIDxwcmU+CisgKiBwYWNrYWdlIGEuYi5jOworICogcHVibGljIGludGVyZmFjZSBNeVNlcnZpY2UgeyAuLi4gfQorICogcHVibGljIGNsYXNzIE15SW1wbDEgaW1wbGVtZW50cyBNeVNlcnZpY2UgeyAuLi4gfQorICogcHVibGljIGNsYXNzIE15SW1wbDIgaW1wbGVtZW50cyBNeVNlcnZpY2UgeyAuLi4gfQorICogPC9wcmU+CisgKiBBbmQgdGhpcyBjb25maWd1cmF0aW9uIGZpbGUgKHN0b3JlZCBhcyB7QGNvZGUgTUVUQS1JTkYvc2VydmljZXMvYS5iLmMuTXlTZXJ2aWNlfSk6CisgKiA8cHJlPgorICogIyBLbm93biBNeVNlcnZpY2UgcHJvdmlkZXJzLgorICogYS5iLmMuTXlJbXBsMSAgIyBUaGUgb3JpZ2luYWwgaW1wbGVtZW50YXRpb24gZm9yIGhhbmRsaW5nICJiYXIicy4KKyAqIGEuYi5jLk15SW1wbDIgICMgQSBsYXRlciBpbXBsZW1lbnRhdGlvbiBmb3IgImZvbyJzLgorICogPC9wcmU+CisgKiBZb3UgbWlnaHQgdXNlIHtAY29kZSBTZXJ2aWNlUHJvdmlkZXJ9IHNvbWV0aGluZyBsaWtlIHRoaXM6CisgKiA8cHJlPgorICogICBmb3IgKE15U2VydmljZSBzZXJ2aWNlIDogU2VydmljZUxvYWRlcjxNeVNlcnZpY2U+LmxvYWQoTXlTZXJ2aWNlLmNsYXNzKSkgeworICogICAgIGlmIChzZXJ2aWNlLnN1cHBvcnRzKG8pKSB7CisgKiAgICAgICByZXR1cm4gc2VydmljZS5oYW5kbGUobyk7CisgKiAgICAgfQorICogICB9CisgKiA8L3ByZT4KKyAqCisgKiA8cD5Ob3RlIHRoYXQgZWFjaCBpdGVyYXRpb24gY3JlYXRlcyBuZXcgaW5zdGFuY2VzIG9mIHRoZSB2YXJpb3VzIHNlcnZpY2UgaW1wbGVtZW50YXRpb25zLCBzbworICogYW55IGhlYXZpbHktdXNlZCBjb2RlIHdpbGwgbGlrZWx5IHdhbnQgdG8gY2FjaGUgdGhlIGtub3duIGltcGxlbWVudGF0aW9ucyBpdHNlbGYgYW5kIHJldXNlIHRoZW0uCisgKiBOb3RlIGFsc28gdGhhdCB0aGUgY2FuZGlkYXRlIGNsYXNzZXMgYXJlIGluc3RhbnRpYXRlZCBsYXppbHkgYXMgeW91IGNhbGwge0Bjb2RlIG5leHR9IG9uIHRoZQorICogaXRlcmF0b3I6IGNvbnN0cnVjdGlvbiBvZiB0aGUgaXRlcmF0b3IgaXRzZWxmIGRvZXMgbm90IGluc3RhbnRpYXRlIGFueSBvZiB0aGUgcHJvdmlkZXJzLgorICoKKyAqIEBwYXJhbSA8Uz4gdGhlIHNlcnZpY2UgY2xhc3Mgb3IgaW50ZXJmYWNlCisgKiBAc2luY2UgMS42CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTZXJ2aWNlTG9hZGVyPFM+IGltcGxlbWVudHMgSXRlcmFibGU8Uz4geworICAgIHByaXZhdGUgZmluYWwgQ2xhc3M8Uz4gc2VydmljZTsKKyAgICBwcml2YXRlIGZpbmFsIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyOworICAgIHByaXZhdGUgZmluYWwgU2V0PFVSTD4gc2VydmljZXM7CisKKyAgICBwcml2YXRlIFNlcnZpY2VMb2FkZXIoQ2xhc3M8Uz4gc2VydmljZSwgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIpIHsKKyAgICAgICAgLy8gSXQgbWFrZXMgbm8gc2Vuc2UgZm9yIHNlcnZpY2UgdG8gYmUgbnVsbC4KKyAgICAgICAgLy8gY2xhc3NMb2FkZXIgaXMgbnVsbCBpZiB5b3Ugd2FudCB0aGUgc3lzdGVtIGNsYXNzIGxvYWRlci4KKyAgICAgICAgaWYgKHNlcnZpY2UgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zZXJ2aWNlID0gc2VydmljZTsKKyAgICAgICAgdGhpcy5jbGFzc0xvYWRlciA9IGNsYXNzTG9hZGVyOworICAgICAgICB0aGlzLnNlcnZpY2VzID0gbmV3IEhhc2hTZXQ8VVJMPigpOworICAgICAgICByZWxvYWQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnZhbGlkYXRlcyB0aGUgY2FjaGUgb2Yga25vd24gc2VydmljZSBwcm92aWRlciBjbGFzcyBuYW1lcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZWxvYWQoKSB7CisgICAgICAgIGludGVybmFsTG9hZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igb3ZlciBhbGwgdGhlIHNlcnZpY2UgcHJvdmlkZXJzIG9mZmVyZWQgYnkgdGhpcyBzZXJ2aWNlIGxvYWRlci4KKyAgICAgKiBOb3RlIHRoYXQge0Bjb2RlIGhhc05leHR9IGFuZCB7QGNvZGUgbmV4dH0gbWF5IHRocm93IGlmIHRoZSBjb25maWd1cmF0aW9uIGlzIGludmFsaWQuCisgICAgICoKKyAgICAgKiA8cD5FYWNoIGl0ZXJhdG9yIHdpbGwgcmV0dXJuIG5ldyBpbnN0YW5jZXMgb2YgdGhlIGNsYXNzZXMgaXQgaXRlcmF0ZXMgb3Zlciwgc28gY2FsbGVycworICAgICAqIG1heSB3YW50IHRvIGNhY2hlIHRoZSByZXN1bHRzIG9mIGEgc2luZ2xlIGNhbGwgdG8gdGhpcyBtZXRob2QgcmF0aGVyIHRoYW4gY2FsbCBpdAorICAgICAqIHJlcGVhdGVkbHkuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQgaXRlcmF0b3IgZG9lcyBub3Qgc3VwcG9ydCB7QGNvZGUgcmVtb3ZlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3I8Uz4gaXRlcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBuZXcgU2VydmljZUl0ZXJhdG9yKHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBzZXJ2aWNlIGxvYWRlci4gSWYge0Bjb2RlIGNsYXNzTG9hZGVyfSBpcyBudWxsLCB0aGUgc3lzdGVtIGNsYXNzIGxvYWRlcgorICAgICAqIGlzIHVzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2VydmljZSB0aGUgc2VydmljZSBjbGFzcyBvciBpbnRlcmZhY2UKKyAgICAgKiBAcGFyYW0gY2xhc3NMb2FkZXIgdGhlIGNsYXNzIGxvYWRlcgorICAgICAqIEByZXR1cm4gYSBuZXcgU2VydmljZUxvYWRlcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFM+IFNlcnZpY2VMb2FkZXI8Uz4gbG9hZChDbGFzczxTPiBzZXJ2aWNlLCBDbGFzc0xvYWRlciBjbGFzc0xvYWRlcikgeworICAgICAgICBpZiAoY2xhc3NMb2FkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgY2xhc3NMb2FkZXIgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU2VydmljZUxvYWRlcjxTPihzZXJ2aWNlLCBjbGFzc0xvYWRlcik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGludGVybmFsTG9hZCgpIHsKKyAgICAgICAgc2VydmljZXMuY2xlYXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBuYW1lID0gIk1FVEEtSU5GL3NlcnZpY2VzLyIgKyBzZXJ2aWNlLmdldE5hbWUoKTsKKyAgICAgICAgICAgIHNlcnZpY2VzLmFkZEFsbChDb2xsZWN0aW9ucy5saXN0KGNsYXNzTG9hZGVyLmdldFJlc291cmNlcyhuYW1lKSkpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgc2VydmljZSBsb2FkZXIsIHVzaW5nIHRoZSBjdXJyZW50IHRocmVhZCdzIGNvbnRleHQgY2xhc3MgbG9hZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHNlcnZpY2UgdGhlIHNlcnZpY2UgY2xhc3Mgb3IgaW50ZXJmYWNlCisgICAgICogQHJldHVybiBhIG5ldyBTZXJ2aWNlTG9hZGVyCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8Uz4gU2VydmljZUxvYWRlcjxTPiBsb2FkKENsYXNzPFM+IHNlcnZpY2UpIHsKKyAgICAgICAgcmV0dXJuIFNlcnZpY2VMb2FkZXIubG9hZChzZXJ2aWNlLCBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgc2VydmljZSBsb2FkZXIsIHVzaW5nIHRoZSBleHRlbnNpb24gY2xhc3MgbG9hZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHNlcnZpY2UgdGhlIHNlcnZpY2UgY2xhc3Mgb3IgaW50ZXJmYWNlCisgICAgICogQHJldHVybiBhIG5ldyBTZXJ2aWNlTG9hZGVyCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8Uz4gU2VydmljZUxvYWRlcjxTPiBsb2FkSW5zdGFsbGVkKENsYXNzPFM+IHNlcnZpY2UpIHsKKyAgICAgICAgQ2xhc3NMb2FkZXIgY2wgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpOworICAgICAgICBpZiAoY2wgIT0gbnVsbCkgeworICAgICAgICAgICAgd2hpbGUgKGNsLmdldFBhcmVudCgpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjbCA9IGNsLmdldFBhcmVudCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBTZXJ2aWNlTG9hZGVyLmxvYWQoc2VydmljZSwgY2wpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEludGVybmFsIEFQSSB0byBzdXBwb3J0IGJ1aWx0LWluIFNQSXMgdGhhdCBjaGVjayBhIHN5c3RlbSBwcm9wZXJ0eSBmaXJzdC4KKyAgICAgKiBSZXR1cm5zIGFuIGluc3RhbmNlIHNwZWNpZmllZCBieSBhIHByb3BlcnR5IHdpdGggdGhlIGNsYXNzJyBiaW5hcnkgbmFtZSwgb3IgbnVsbCBpZgorICAgICAqIG5vIHN1Y2ggcHJvcGVydHkgaXMgc2V0LgorICAgICAqIEBoaWRlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8Uz4gUyBsb2FkRnJvbVN5c3RlbVByb3BlcnR5KGZpbmFsIENsYXNzPFM+IHNlcnZpY2UpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBjbGFzc05hbWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoc2VydmljZS5nZXROYW1lKCkpOworICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgQ2xhc3M8Pz4gYyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKGNsYXNzTmFtZSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIChTKSBjLm5ld0luc3RhbmNlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiAiU2VydmljZUxvYWRlciBmb3IgIiArIHNlcnZpY2UuZ2V0TmFtZSgpOworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgU2VydmljZUl0ZXJhdG9yIGltcGxlbWVudHMgSXRlcmF0b3I8Uz4geworICAgICAgICBwcml2YXRlIGZpbmFsIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyOworICAgICAgICBwcml2YXRlIGZpbmFsIENsYXNzPFM+IHNlcnZpY2U7CisgICAgICAgIHByaXZhdGUgZmluYWwgU2V0PFVSTD4gc2VydmljZXM7CisKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzUmVhZCA9IGZhbHNlOworCisgICAgICAgIHByaXZhdGUgTGlua2VkTGlzdDxTdHJpbmc+IHF1ZXVlID0gbmV3IExpbmtlZExpc3Q8U3RyaW5nPigpOworCisgICAgICAgIHB1YmxpYyBTZXJ2aWNlSXRlcmF0b3IoU2VydmljZUxvYWRlcjxTPiBzbCkgeworICAgICAgICAgICAgdGhpcy5jbGFzc0xvYWRlciA9IHNsLmNsYXNzTG9hZGVyOworICAgICAgICAgICAgdGhpcy5zZXJ2aWNlID0gc2wuc2VydmljZTsKKyAgICAgICAgICAgIHRoaXMuc2VydmljZXMgPSBzbC5zZXJ2aWNlczsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICBpZiAoIWlzUmVhZCkgeworICAgICAgICAgICAgICAgIHJlYWRDbGFzcygpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIChxdWV1ZSAhPSBudWxsICYmICFxdWV1ZS5pc0VtcHR5KCkpOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgICAgIHB1YmxpYyBTIG5leHQoKSB7CisgICAgICAgICAgICBpZiAoIWhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lID0gcXVldWUucmVtb3ZlKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiBzZXJ2aWNlLmNhc3QoY2xhc3NMb2FkZXIubG9hZENsYXNzKGNsYXNzTmFtZSkubmV3SW5zdGFuY2UoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZXJ2aWNlQ29uZmlndXJhdGlvbkVycm9yKCJDb3VsZG4ndCBpbnN0YW50aWF0ZSBjbGFzcyAiICsgY2xhc3NOYW1lLCBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCByZWFkQ2xhc3MoKSB7CisgICAgICAgICAgICBmb3IgKFVSTCB1cmwgOiBzZXJ2aWNlcykgeworICAgICAgICAgICAgICAgIEJ1ZmZlcmVkUmVhZGVyIHJlYWRlciA9IG51bGw7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcih1cmwub3BlblN0cmVhbSgpLCAiVVRGLTgiKSk7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsaW5lOworICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGxpbmUgPSByZWFkZXIucmVhZExpbmUoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3RyaXAgY29tbWVudHMgYW5kIHdoaXRlc3BhY2UuLi4KKyAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb21tZW50U3RhcnQgPSBsaW5lLmluZGV4T2YoJyMnKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb21tZW50U3RhcnQgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lID0gbGluZS5zdWJzdHJpbmcoMCwgY29tbWVudFN0YXJ0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUgPSBsaW5lLnRyaW0oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIElnbm9yZSBlbXB0eSBsaW5lcy4KKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsaW5lLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9IGxpbmU7CisgICAgICAgICAgICAgICAgICAgICAgICBjaGVja1ZhbGlkSmF2YUNsYXNzTmFtZShjbGFzc05hbWUpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFxdWV1ZS5jb250YWlucyhjbGFzc05hbWUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVldWUuYWRkKGNsYXNzTmFtZSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaXNSZWFkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvcigiQ291bGRuJ3QgcmVhZCAiICsgdXJsLCBlKTsKKyAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICBJb1V0aWxzLmNsb3NlUXVpZXRseShyZWFkZXIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSB2b2lkIGNoZWNrVmFsaWRKYXZhQ2xhc3NOYW1lKFN0cmluZyBjbGFzc05hbWUpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2xhc3NOYW1lLmxlbmd0aCgpOyArK2kpIHsKKyAgICAgICAgICAgICAgICBjaGFyIGNoID0gY2xhc3NOYW1lLmNoYXJBdChpKTsKKyAgICAgICAgICAgICAgICBpZiAoIUNoYXJhY3Rlci5pc0phdmFJZGVudGlmaWVyUGFydChjaCkgJiYgY2ggIT0gJy4nKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZXJ2aWNlQ29uZmlndXJhdGlvbkVycm9yKCJCYWQgY2hhcmFjdGVyICciICsgY2ggKyAiJyBpbiBjbGFzcyBuYW1lIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9TZXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvU2V0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDBiMDdhOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvU2V0LmphdmEKQEAgLTAsMCArMSwxOTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisKKy8qKgorICogQSB7QGNvZGUgU2V0fSBpcyBhIGRhdGEgc3RydWN0dXJlIHdoaWNoIGRvZXMgbm90IGFsbG93IGR1cGxpY2F0ZSBlbGVtZW50cy4KKyAqCisgKiBAc2luY2UgMS4yCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgU2V0PEU+IGV4dGVuZHMgQ29sbGVjdGlvbjxFPiB7CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHRvIHRoaXMgc2V0LiBUaGUgc2V0IGlzIG5vdCBtb2RpZmllZCBpZiBpdAorICAgICAqIGFscmVhZHkgY29udGFpbnMgdGhlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYWRkLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgc2V0IGlzIG1vZGlmaWVkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiBhZGRpbmcgdG8gdGhpcyBzZXQgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHdoZW4gdGhlIGNsYXNzIG9mIHRoZSBvYmplY3QgaXMgaW5hcHByb3ByaWF0ZSBmb3IgdGhpcyBzZXQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHRoZSBvYmplY3QgY2Fubm90IGJlIGFkZGVkIHRvIHRoaXMgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGFkZChFIG9iamVjdCk7CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBvYmplY3RzIGluIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiB3aGljaCBkbyBub3QgZXhpc3QgeWV0IGluCisgICAgICogdGhpcyBzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cy4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHNldCBpcyBtb2RpZmllZCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHdoZW4gYWRkaW5nIHRvIHRoaXMgc2V0IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHRoZSBjbGFzcyBvZiBhbiBvYmplY3QgaXMgaW5hcHByb3ByaWF0ZSBmb3IgdGhpcyBzZXQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIGFuIG9iamVjdCBjYW5ub3QgYmUgYWRkZWQgdG8gdGhpcyBzZXQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYWRkQWxsKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGNvbGxlY3Rpb24pOworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhbGwgZWxlbWVudHMgZnJvbSB0aGlzIHNldCwgbGVhdmluZyBpdCBlbXB0eS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHJlbW92aW5nIGZyb20gdGhpcyBzZXQgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKiBAc2VlICNpc0VtcHR5CisgICAgICogQHNlZSAjc2l6ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsZWFyKCk7CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyB0aGlzIHNldCBmb3IgdGhlIHNwZWNpZmllZCBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIHNlYXJjaCBmb3IuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgb2JqZWN0IGlzIGFuIGVsZW1lbnQgb2YgdGhpcyBzZXQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3Qgb2JqZWN0KTsKKworICAgIC8qKgorICAgICAqIFNlYXJjaGVzIHRoaXMgc2V0IGZvciBhbGwgb2JqZWN0cyBpbiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cy4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBhbGwgb2JqZWN0cyBpbiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gYXJlCisgICAgICogICAgICAgICBlbGVtZW50cyBvZiB0aGlzIHNldCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNBbGwoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKTsKKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHRvIHRoaXMgc2V0LCBhbmQgcmV0dXJucyB0cnVlIGlmIHRoZXkKKyAgICAgKiByZXByZXNlbnQgdGhlIDxlbT5zYW1lPC9lbT4gb2JqZWN0IHVzaW5nIGEgY2xhc3Mgc3BlY2lmaWMgY29tcGFyaXNvbi4KKyAgICAgKiBFcXVhbGl0eSBmb3IgYSBzZXQgbWVhbnMgdGhhdCBib3RoIHNldHMgaGF2ZSB0aGUgc2FtZSBzaXplIGFuZCB0aGUgc2FtZQorICAgICAqIGVsZW1lbnRzLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHdpdGggdGhpcyBvYmplY3QuCisgICAgICogQHJldHVybiBib29sZWFuIHtAY29kZSB0cnVlfSBpZiB0aGUgb2JqZWN0IGlzIHRoZSBzYW1lIGFzIHRoaXMgb2JqZWN0LAorICAgICAqICAgICAgICAgYW5kIHtAY29kZSBmYWxzZX0gaWYgaXQgaXMgZGlmZmVyZW50IGZyb20gdGhpcyBvYmplY3QuCisgICAgICogQHNlZSAjaGFzaENvZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgZm9yIHRoaXMgc2V0LiBUd28gc2V0IHdoaWNoIGFyZSBlcXVhbCBtdXN0IHJldHVybgorICAgICAqIHRoZSBzYW1lIHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIG9mIHRoaXMgc2V0LgorICAgICAqCisgICAgICogQHNlZSAjZXF1YWxzCisgICAgICovCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgc2V0IGhhcyBubyBlbGVtZW50cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgc2V0IGhhcyBubyBlbGVtZW50cywge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgI3NpemUKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGl0ZXJhdG9yIG9uIHRoZSBlbGVtZW50cyBvZiB0aGlzIHNldC4gVGhlIGVsZW1lbnRzIGFyZQorICAgICAqIHVub3JkZXJlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gaXRlcmF0b3Igb24gdGhlIGVsZW1lbnRzIG9mIHRoaXMgc2V0LgorICAgICAqIEBzZWUgSXRlcmF0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3I8RT4gaXRlcmF0b3IoKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCBvYmplY3QgZnJvbSB0aGlzIHNldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gcmVtb3ZlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgc2V0IHdhcyBtb2RpZmllZCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHdoZW4gcmVtb3ZpbmcgZnJvbSB0aGlzIHNldCBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3Qgb2JqZWN0KTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIG9iamVjdHMgaW4gdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGZyb20gdGhpcyBzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cyB0byByZW1vdmUuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBzZXQgd2FzIG1vZGlmaWVkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiByZW1vdmluZyBmcm9tIHRoaXMgc2V0IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlQWxsKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbik7CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGFsbCBvYmplY3RzIGZyb20gdGhpcyBzZXQgdGhhdCBhcmUgbm90IGNvbnRhaW5lZCBpbiB0aGUgc3BlY2lmaWVkCisgICAgICogY29sbGVjdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2xsZWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgY29sbGVjdGlvbiBvZiBvYmplY3RzIHRvIHJldGFpbi4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHNldCB3YXMgbW9kaWZpZWQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHJlbW92aW5nIGZyb20gdGhpcyBzZXQgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiByZXRhaW5BbGwoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIHNldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNpemUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgZWxlbWVudHMgY29udGFpbmVkIGluIHRoaXMgc2V0LgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiB0aGUgZWxlbWVudHMgZnJvbSB0aGlzIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIGFsbCBlbGVtZW50cyBjb250YWluZWQgaW4gdGhpcyBzZXQuIElmIHRoZQorICAgICAqIHNwZWNpZmllZCBhcnJheSBpcyBsYXJnZSBlbm91Z2ggdG8gaG9sZCB0aGUgZWxlbWVudHMsIHRoZSBzcGVjaWZpZWQgYXJyYXkKKyAgICAgKiBpcyB1c2VkLCBvdGhlcndpc2UgYW4gYXJyYXkgb2YgdGhlIHNhbWUgdHlwZSBpcyBjcmVhdGVkLiBJZiB0aGUgc3BlY2lmaWVkCisgICAgICogYXJyYXkgaXMgdXNlZCBhbmQgaXMgbGFyZ2VyIHRoYW4gdGhpcyBzZXQsIHRoZSBhcnJheSBlbGVtZW50IGZvbGxvd2luZworICAgICAqIHRoZSBjb2xsZWN0aW9uIGVsZW1lbnRzIGlzIHNldCB0byBudWxsLgorICAgICAqCisgICAgICogQHBhcmFtIGFycmF5CisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkuCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiB0aGUgZWxlbWVudHMgZnJvbSB0aGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIEFycmF5U3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHRoZSB0eXBlIG9mIGFuIGVsZW1lbnQgaW4gdGhpcyBzZXQgY2Fubm90IGJlIHN0b3JlZCBpbgorICAgICAqICAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkuCisgICAgICogQHNlZSBDb2xsZWN0aW9uI3RvQXJyYXkoT2JqZWN0W10pCisgICAgICovCisgICAgcHVibGljIDxUPiBUW10gdG9BcnJheShUW10gYXJyYXkpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9TaW1wbGVUaW1lWm9uZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9TaW1wbGVUaW1lWm9uZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZjOWI0NDMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1NpbXBsZVRpbWVab25lLmphdmEKQEAgLTAsMCArMSw5MzYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0U3RyZWFtRmllbGQ7CisKKy8qKgorICoge0Bjb2RlIFNpbXBsZVRpbWVab25lfSBpcyBhIGNvbmNyZXRlIHN1YmNsYXNzIG9mIHtAY29kZSBUaW1lWm9uZX0KKyAqIHRoYXQgcmVwcmVzZW50cyBhIHRpbWUgem9uZSBmb3IgdXNlIHdpdGggYSBHcmVnb3JpYW4gY2FsZW5kYXIuIFRoaXMgY2xhc3MKKyAqIGRvZXMgbm90IGhhbmRsZSBoaXN0b3JpY2FsIGNoYW5nZXMuCisgKiA8cD4KKyAqIFVzZSBhIG5lZ2F0aXZlIHZhbHVlIGZvciB7QGNvZGUgZGF5T2ZXZWVrSW5Nb250aH0gdG8gaW5kaWNhdGUgdGhhdAorICoge0Bjb2RlIFNpbXBsZVRpbWVab25lfSBzaG91bGQgY291bnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBtb250aAorICogYmFja3dhcmRzLiBGb3IgZXhhbXBsZSwgRGF5bGlnaHQgU2F2aW5ncyBUaW1lIGVuZHMgYXQgdGhlIGxhc3QKKyAqIChkYXlPZldlZWtJbk1vbnRoID0gLTEpIFN1bmRheSBpbiBPY3RvYmVyLCBhdCAyIEFNIGluIHN0YW5kYXJkIHRpbWUuCisgKgorICogQHNlZSBDYWxlbmRhcgorICogQHNlZSBHcmVnb3JpYW5DYWxlbmRhcgorICogQHNlZSBUaW1lWm9uZQorICovCitwdWJsaWMgY2xhc3MgU2ltcGxlVGltZVpvbmUgZXh0ZW5kcyBUaW1lWm9uZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDAzMjUwOTcxMjE1NDY1MDUwTDsKKworICAgIHByaXZhdGUgaW50IHJhd09mZnNldDsKKworICAgIHByaXZhdGUgaW50IHN0YXJ0WWVhciwgc3RhcnRNb250aCwgc3RhcnREYXksIHN0YXJ0RGF5T2ZXZWVrLCBzdGFydFRpbWU7CisKKyAgICBwcml2YXRlIGludCBlbmRNb250aCwgZW5kRGF5LCBlbmREYXlPZldlZWssIGVuZFRpbWU7CisKKyAgICBwcml2YXRlIGludCBzdGFydE1vZGUsIGVuZE1vZGU7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRE9NX01PREUgPSAxLCBET1dfSU5fTU9OVEhfTU9ERSA9IDIsCisgICAgICAgICAgICBET1dfR0VfRE9NX01PREUgPSAzLCBET1dfTEVfRE9NX01PREUgPSA0OworCisgICAgLyoqCisgICAgICogVGhlIGNvbnN0YW50IGZvciByZXByZXNlbnRpbmcgYSBzdGFydCBvciBlbmQgdGltZSBpbiBHTVQgdGltZSBtb2RlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVUQ19USU1FID0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSBjb25zdGFudCBmb3IgcmVwcmVzZW50aW5nIGEgc3RhcnQgb3IgZW5kIHRpbWUgaW4gc3RhbmRhcmQgbG9jYWwgdGltZSBtb2RlLAorICAgICAqIGJhc2VkIG9uIHRpbWV6b25lJ3MgcmF3IG9mZnNldCBmcm9tIEdNVDsgZG9lcyBub3QgaW5jbHVkZSBEYXlsaWdodAorICAgICAqIHNhdmluZ3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RBTkRBUkRfVElNRSA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29uc3RhbnQgZm9yIHJlcHJlc2VudGluZyBhIHN0YXJ0IG9yIGVuZCB0aW1lIGluIGxvY2FsIHdhbGwgY2xvY2sgdGltZQorICAgICAqIG1vZGUsIGJhc2VkIG9uIHRpbWV6b25lJ3MgYWRqdXN0ZWQgb2Zmc2V0IGZyb20gR01UOyBpbmNsdWRlcworICAgICAqIERheWxpZ2h0IHNhdmluZ3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0FMTF9USU1FID0gMDsKKworICAgIHByaXZhdGUgYm9vbGVhbiB1c2VEYXlsaWdodDsKKworICAgIHByaXZhdGUgaW50IGRzdFNhdmluZ3MgPSAzNjAwMDAwOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBTaW1wbGVUaW1lWm9uZX0gd2l0aCB0aGUgZ2l2ZW4gYmFzZSB0aW1lIHpvbmUgb2Zmc2V0IGZyb20gR01UCisgICAgICogYW5kIHRpbWUgem9uZSBJRC4gVGltZXpvbmUgSURzIGNhbiBiZSBvYnRhaW5lZCBmcm9tCisgICAgICoge0Bjb2RlIFRpbWVab25lLmdldEF2YWlsYWJsZUlEc30uIE5vcm1hbGx5IHlvdSBzaG91bGQgdXNlIHtAY29kZSBUaW1lWm9uZS5nZXREZWZhdWx0fSB0bworICAgICAqIGNvbnN0cnVjdCBhIHtAY29kZSBUaW1lWm9uZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgZ2l2ZW4gYmFzZSB0aW1lIHpvbmUgb2Zmc2V0IHRvIEdNVC4KKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHRpbWUgem9uZSBJRCB3aGljaCBpcyBvYnRhaW5lZCBmcm9tCisgICAgICogICAgICAgICAgICB7QGNvZGUgVGltZVpvbmUuZ2V0QXZhaWxhYmxlSURzfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2ltcGxlVGltZVpvbmUoaW50IG9mZnNldCwgZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgc2V0SUQobmFtZSk7CisgICAgICAgIHJhd09mZnNldCA9IG9mZnNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIFNpbXBsZVRpbWVab25lfSB3aXRoIHRoZSBnaXZlbiBiYXNlIHRpbWUgem9uZSBvZmZzZXQgZnJvbSBHTVQsCisgICAgICogdGltZSB6b25lIElELCBhbmQgdGltZXMgdG8gc3RhcnQgYW5kIGVuZCB0aGUgZGF5bGlnaHQgc2F2aW5ncyB0aW1lLiBUaW1lem9uZSBJRHMgY2FuCisgICAgICogYmUgb2J0YWluZWQgZnJvbSB7QGNvZGUgVGltZVpvbmUuZ2V0QXZhaWxhYmxlSURzfS4gTm9ybWFsbHkgeW91IHNob3VsZCB1c2UKKyAgICAgKiB7QGNvZGUgVGltZVpvbmUuZ2V0RGVmYXVsdH0gdG8gY3JlYXRlIGEge0Bjb2RlIFRpbWVab25lfS4gRm9yIGEgdGltZSB6b25lIHRoYXQgZG9lcyBub3QKKyAgICAgKiB1c2UgZGF5bGlnaHQgc2F2aW5nIHRpbWUsIGRvIG5vdCB1c2UgdGhpcyBjb25zdHJ1Y3RvcjsgaW5zdGVhZCB5b3Ugc2hvdWxkCisgICAgICogdXNlIHtAY29kZSBTaW1wbGVUaW1lWm9uZShyYXdPZmZzZXQsIElEKX0uCisgICAgICogPHA+CisgICAgICogQnkgZGVmYXVsdCwgdGhpcyBjb25zdHJ1Y3RvciBzcGVjaWZpZXMgZGF5LW9mLXdlZWstaW4tbW9udGggcnVsZXMuIFRoYXQKKyAgICAgKiBpcywgaWYgdGhlIHtAY29kZSBzdGFydERheX0gaXMgMSwgYW5kIHRoZSB7QGNvZGUgc3RhcnREYXlPZldlZWt9IGlzIHtAY29kZSBTVU5EQVl9LCB0aGVuIHRoaXMKKyAgICAgKiBpbmRpY2F0ZXMgdGhlIGZpcnN0IFN1bmRheSBpbiB0aGUge0Bjb2RlIHN0YXJ0TW9udGh9LiBBIHtAY29kZSBzdGFydERheX0gb2YgLTEgbGlrZXdpc2UKKyAgICAgKiBpbmRpY2F0ZXMgdGhlIGxhc3QgU3VuZGF5LiBIb3dldmVyLCBieSB1c2luZyBuZWdhdGl2ZSBvciB6ZXJvIHZhbHVlcyBmb3IKKyAgICAgKiBjZXJ0YWluIHBhcmFtZXRlcnMsIG90aGVyIHR5cGVzIG9mIHJ1bGVzIGNhbiBiZSBzcGVjaWZpZWQuCisgICAgICogPHA+CisgICAgICogRGF5IG9mIG1vbnRoOiBUbyBzcGVjaWZ5IGFuIGV4YWN0IGRheSBvZiB0aGUgbW9udGgsIHN1Y2ggYXMgTWFyY2ggMSwgc2V0CisgICAgICoge0Bjb2RlIHN0YXJ0RGF5T2ZXZWVrfSB0byB6ZXJvLgorICAgICAqIDxwPgorICAgICAqIERheSBvZiB3ZWVrIGFmdGVyIGRheSBvZiBtb250aDogVG8gc3BlY2lmeSB0aGUgZmlyc3QgZGF5IG9mIHRoZSB3ZWVrCisgICAgICogb2NjdXJyaW5nIG9uIG9yIGFmdGVyIGFuIGV4YWN0IGRheSBvZiB0aGUgbW9udGgsIG1ha2UgdGhlIGRheSBvZiB0aGUgd2VlaworICAgICAqIG5lZ2F0aXZlLiBGb3IgZXhhbXBsZSwgaWYge0Bjb2RlIHN0YXJ0RGF5fSBpcyA1IGFuZCB7QGNvZGUgc3RhcnREYXlPZldlZWt9IGlzIHtAY29kZSAtTU9OREFZfSwKKyAgICAgKiB0aGlzIGluZGljYXRlcyB0aGUgZmlyc3QgTW9uZGF5IG9uIG9yIGFmdGVyIHRoZSA1dGggZGF5IG9mIHRoZQorICAgICAqIHtAY29kZSBzdGFydE1vbnRofS4KKyAgICAgKiA8cD4KKyAgICAgKiBEYXkgb2Ygd2VlayBiZWZvcmUgZGF5IG9mIG1vbnRoOiBUbyBzcGVjaWZ5IHRoZSBsYXN0IGRheSBvZiB0aGUgd2VlaworICAgICAqIG9jY3VycmluZyBvbiBvciBiZWZvcmUgYW4gZXhhY3QgZGF5IG9mIHRoZSBtb250aCwgbWFrZSB0aGUgZGF5IG9mIHRoZQorICAgICAqIHdlZWsgYW5kIHRoZSBkYXkgb2YgdGhlIG1vbnRoIG5lZ2F0aXZlLiBGb3IgZXhhbXBsZSwgaWYge0Bjb2RlIHN0YXJ0RGF5fSBpcyB7QGNvZGUgLTIxfQorICAgICAqIGFuZCB7QGNvZGUgc3RhcnREYXlPZldlZWt9IGlzIHtAY29kZSAtV0VETkVTREFZfSwgdGhpcyBpbmRpY2F0ZXMgdGhlIGxhc3QgV2VkbmVzZGF5IG9uIG9yCisgICAgICogYmVmb3JlIHRoZSAyMXN0IG9mIHRoZSB7QGNvZGUgc3RhcnRNb250aH0uCisgICAgICogPHA+CisgICAgICogVGhlIGFib3ZlIGV4YW1wbGVzIHJlZmVyIHRvIHRoZSB7QGNvZGUgc3RhcnRNb250aH0sIHtAY29kZSBzdGFydERheX0sIGFuZCB7QGNvZGUgc3RhcnREYXlPZldlZWt9OworICAgICAqIHRoZSBzYW1lIGFwcGxpZXMgZm9yIHRoZSB7QGNvZGUgZW5kTW9udGh9LCB7QGNvZGUgZW5kRGF5fSwgYW5kIHtAY29kZSBlbmREYXlPZldlZWt9LgorICAgICAqIDxwPgorICAgICAqIFRoZSBkYXlsaWdodCBzYXZpbmdzIHRpbWUgZGlmZmVyZW5jZSBpcyBzZXQgdG8gdGhlIGRlZmF1bHQgdmFsdWU6IG9uZSBob3VyLgorICAgICAqCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGdpdmVuIGJhc2UgdGltZSB6b25lIG9mZnNldCB0byBHTVQuCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0aW1lIHpvbmUgSUQgd2hpY2ggaXMgb2J0YWluZWQgZnJvbQorICAgICAqICAgICAgICAgICAge0Bjb2RlIFRpbWVab25lLmdldEF2YWlsYWJsZUlEc30uCisgICAgICogQHBhcmFtIHN0YXJ0TW9udGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXlsaWdodCBzYXZpbmdzIHN0YXJ0aW5nIG1vbnRoLiBUaGUgbW9udGggaW5kZXhpbmcgaXMgMC1iYXNlZC4gZWcsIDAKKyAgICAgKiAgICAgICAgICAgIGZvciBKYW51YXJ5LgorICAgICAqIEBwYXJhbSBzdGFydERheQorICAgICAqICAgICAgICAgICAgdGhlIGRheWxpZ2h0IHNhdmluZ3Mgc3RhcnRpbmcgZGF5LW9mLXdlZWstaW4tbW9udGguIFBsZWFzZSBzZWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBtZW1iZXIgZGVzY3JpcHRpb24gZm9yIGFuIGV4YW1wbGUuCisgICAgICogQHBhcmFtIHN0YXJ0RGF5T2ZXZWVrCisgICAgICogICAgICAgICAgICB0aGUgZGF5bGlnaHQgc2F2aW5ncyBzdGFydGluZyBkYXktb2Ytd2Vlay4gUGxlYXNlIHNlZSB0aGUKKyAgICAgKiAgICAgICAgICAgIG1lbWJlciBkZXNjcmlwdGlvbiBmb3IgYW4gZXhhbXBsZS4KKyAgICAgKiBAcGFyYW0gc3RhcnRUaW1lCisgICAgICogICAgICAgICAgICB0aGUgZGF5bGlnaHQgc2F2aW5ncyBzdGFydGluZyB0aW1lIGluIGxvY2FsIHdhbGwgdGltZSwgd2hpY2gKKyAgICAgKiAgICAgICAgICAgIGlzIHN0YW5kYXJkIHRpbWUgaW4gdGhpcyBjYXNlLiBQbGVhc2Ugc2VlIHRoZSBtZW1iZXIKKyAgICAgKiAgICAgICAgICAgIGRlc2NyaXB0aW9uIGZvciBhbiBleGFtcGxlLgorICAgICAqIEBwYXJhbSBlbmRNb250aAorICAgICAqICAgICAgICAgICAgdGhlIGRheWxpZ2h0IHNhdmluZ3MgZW5kaW5nIG1vbnRoLiBUaGUgbW9udGggaW5kZXhpbmcgaXMgMC1iYXNlZC4gZWcsIDAgZm9yCisgICAgICogICAgICAgICAgICBKYW51YXJ5LgorICAgICAqIEBwYXJhbSBlbmREYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXlsaWdodCBzYXZpbmdzIGVuZGluZyBkYXktb2Ytd2Vlay1pbi1tb250aC4gUGxlYXNlIHNlZQorICAgICAqICAgICAgICAgICAgdGhlIG1lbWJlciBkZXNjcmlwdGlvbiBmb3IgYW4gZXhhbXBsZS4KKyAgICAgKiBAcGFyYW0gZW5kRGF5T2ZXZWVrCisgICAgICogICAgICAgICAgICB0aGUgZGF5bGlnaHQgc2F2aW5ncyBlbmRpbmcgZGF5LW9mLXdlZWsuIFBsZWFzZSBzZWUgdGhlIG1lbWJlcgorICAgICAqICAgICAgICAgICAgZGVzY3JpcHRpb24gZm9yIGFuIGV4YW1wbGUuCisgICAgICogQHBhcmFtIGVuZFRpbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXlsaWdodCBzYXZpbmdzIGVuZGluZyB0aW1lIGluIGxvY2FsIHdhbGwgdGltZSwgd2hpY2ggaXMKKyAgICAgKiAgICAgICAgICAgIGRheWxpZ2h0IHRpbWUgaW4gdGhpcyBjYXNlLiBQbGVhc2Ugc2VlIHRoZSBtZW1iZXIgZGVzY3JpcHRpb24KKyAgICAgKiAgICAgICAgICAgIGZvciBhbiBleGFtcGxlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG1vbnRoLCBkYXksIGRheU9mV2Vlaywgb3IgdGltZSBwYXJhbWV0ZXJzIGFyZSBvdXQgb2YKKyAgICAgKiAgICAgICAgICAgICByYW5nZSBmb3IgdGhlIHN0YXJ0IG9yIGVuZCBydWxlLgorICAgICAqLworICAgIHB1YmxpYyBTaW1wbGVUaW1lWm9uZShpbnQgb2Zmc2V0LCBTdHJpbmcgbmFtZSwgaW50IHN0YXJ0TW9udGgsCisgICAgICAgICAgICBpbnQgc3RhcnREYXksIGludCBzdGFydERheU9mV2VlaywgaW50IHN0YXJ0VGltZSwgaW50IGVuZE1vbnRoLAorICAgICAgICAgICAgaW50IGVuZERheSwgaW50IGVuZERheU9mV2VlaywgaW50IGVuZFRpbWUpIHsKKyAgICAgICAgdGhpcyhvZmZzZXQsIG5hbWUsIHN0YXJ0TW9udGgsIHN0YXJ0RGF5LCBzdGFydERheU9mV2Vlaywgc3RhcnRUaW1lLAorICAgICAgICAgICAgICAgIGVuZE1vbnRoLCBlbmREYXksIGVuZERheU9mV2VlaywgZW5kVGltZSwgMzYwMDAwMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBTaW1wbGVUaW1lWm9uZX0gd2l0aCB0aGUgZ2l2ZW4gYmFzZSB0aW1lIHpvbmUgb2Zmc2V0IGZyb20gR01ULAorICAgICAqIHRpbWUgem9uZSBJRCwgdGltZXMgdG8gc3RhcnQgYW5kIGVuZCB0aGUgZGF5bGlnaHQgc2F2aW5ncyB0aW1lLCBhbmQKKyAgICAgKiB0aGUgZGF5bGlnaHQgc2F2aW5ncyB0aW1lIGRpZmZlcmVuY2UgaW4gbWlsbGlzZWNvbmRzLgorICAgICAqCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIGdpdmVuIGJhc2UgdGltZSB6b25lIG9mZnNldCB0byBHTVQuCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0aW1lIHpvbmUgSUQgd2hpY2ggaXMgb2J0YWluZWQgZnJvbQorICAgICAqICAgICAgICAgICAge0Bjb2RlIFRpbWVab25lLmdldEF2YWlsYWJsZUlEc30uCisgICAgICogQHBhcmFtIHN0YXJ0TW9udGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXlsaWdodCBzYXZpbmdzIHN0YXJ0aW5nIG1vbnRoLiBNb250aCBpcyAwLWJhc2VkLiBlZywgMAorICAgICAqICAgICAgICAgICAgZm9yIEphbnVhcnkuCisgICAgICogQHBhcmFtIHN0YXJ0RGF5CisgICAgICogICAgICAgICAgICB0aGUgZGF5bGlnaHQgc2F2aW5ncyBzdGFydGluZyBkYXktb2Ytd2Vlay1pbi1tb250aC4gUGxlYXNlIHNlZQorICAgICAqICAgICAgICAgICAgdGhlIGRlc2NyaXB0aW9uIG9mIHtAbGluayAjU2ltcGxlVGltZVpvbmUoaW50LCBTdHJpbmcsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50KX0gZm9yIGFuIGV4YW1wbGUuCisgICAgICogQHBhcmFtIHN0YXJ0RGF5T2ZXZWVrCisgICAgICogICAgICAgICAgICB0aGUgZGF5bGlnaHQgc2F2aW5ncyBzdGFydGluZyBkYXktb2Ytd2Vlay4gUGxlYXNlIHNlZSB0aGUKKyAgICAgKiAgICAgICAgICAgIGRlc2NyaXB0aW9uIG9mIHtAbGluayAjU2ltcGxlVGltZVpvbmUoaW50LCBTdHJpbmcsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50KX0gZm9yIGFuIGV4YW1wbGUuCisgICAgICogQHBhcmFtIHN0YXJ0VGltZQorICAgICAqICAgICAgICAgICAgVGhlIGRheWxpZ2h0IHNhdmluZ3Mgc3RhcnRpbmcgdGltZSBpbiBsb2NhbCB3YWxsIHRpbWUsIHdoaWNoCisgICAgICogICAgICAgICAgICBpcyBzdGFuZGFyZCB0aW1lIGluIHRoaXMgY2FzZS4gUGxlYXNlIHNlZSB0aGUgZGVzY3JpcHRpb24gb2YKKyAgICAgKiAgICAgICAgICAgIHtAbGluayAjU2ltcGxlVGltZVpvbmUoaW50LCBTdHJpbmcsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50KX0gZm9yIGFuIGV4YW1wbGUuCisgICAgICogQHBhcmFtIGVuZE1vbnRoCisgICAgICogICAgICAgICAgICB0aGUgZGF5bGlnaHQgc2F2aW5ncyBlbmRpbmcgbW9udGguIE1vbnRoIGlzIDAtYmFzZWQuIGVnLCAwIGZvcgorICAgICAqICAgICAgICAgICAgSmFudWFyeS4KKyAgICAgKiBAcGFyYW0gZW5kRGF5CisgICAgICogICAgICAgICAgICB0aGUgZGF5bGlnaHQgc2F2aW5ncyBlbmRpbmcgZGF5LW9mLXdlZWstaW4tbW9udGguIFBsZWFzZSBzZWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXNjcmlwdGlvbiBvZiB7QGxpbmsgI1NpbXBsZVRpbWVab25lKGludCwgU3RyaW5nLCBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCl9IGZvciBhbiBleGFtcGxlLgorICAgICAqIEBwYXJhbSBlbmREYXlPZldlZWsKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXlsaWdodCBzYXZpbmdzIGVuZGluZyBkYXktb2Ytd2Vlay4gUGxlYXNlIHNlZSB0aGUgZGVzY3JpcHRpb24gb2YKKyAgICAgKiAgICAgICAgICAgIHtAbGluayAjU2ltcGxlVGltZVpvbmUoaW50LCBTdHJpbmcsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50KX0gZm9yIGFuIGV4YW1wbGUuCisgICAgICogQHBhcmFtIGVuZFRpbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXlsaWdodCBzYXZpbmdzIGVuZGluZyB0aW1lIGluIGxvY2FsIHdhbGwgdGltZSwgd2hpY2ggaXMKKyAgICAgKiAgICAgICAgICAgIGRheWxpZ2h0IHRpbWUgaW4gdGhpcyBjYXNlLiBQbGVhc2Ugc2VlIHRoZSBkZXNjcmlwdGlvbiBvZiB7QGxpbmsgI1NpbXBsZVRpbWVab25lKGludCwgU3RyaW5nLCBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCl9CisgICAgICogICAgICAgICAgICBmb3IgYW4gZXhhbXBsZS4KKyAgICAgKiBAcGFyYW0gZGF5bGlnaHRTYXZpbmdzCisgICAgICogICAgICAgICAgICB0aGUgZGF5bGlnaHQgc2F2aW5ncyB0aW1lIGRpZmZlcmVuY2UgaW4gbWlsbGlzZWNvbmRzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIG1vbnRoLCBkYXksIGRheU9mV2Vlaywgb3IgdGltZSBwYXJhbWV0ZXJzIGFyZSBvdXQgb2YKKyAgICAgKiAgICAgICAgICAgICAgICByYW5nZSBmb3IgdGhlIHN0YXJ0IG9yIGVuZCBydWxlLgorICAgICAqLworICAgIHB1YmxpYyBTaW1wbGVUaW1lWm9uZShpbnQgb2Zmc2V0LCBTdHJpbmcgbmFtZSwgaW50IHN0YXJ0TW9udGgsCisgICAgICAgICAgICBpbnQgc3RhcnREYXksIGludCBzdGFydERheU9mV2VlaywgaW50IHN0YXJ0VGltZSwgaW50IGVuZE1vbnRoLAorICAgICAgICAgICAgaW50IGVuZERheSwgaW50IGVuZERheU9mV2VlaywgaW50IGVuZFRpbWUsIGludCBkYXlsaWdodFNhdmluZ3MpIHsKKyAgICAgICAgdGhpcyhvZmZzZXQsIG5hbWUpOworICAgICAgICBpZiAoZGF5bGlnaHRTYXZpbmdzIDw9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgZGF5bGlnaHRTYXZpbmdzOiAiICsgZGF5bGlnaHRTYXZpbmdzKTsKKyAgICAgICAgfQorICAgICAgICBkc3RTYXZpbmdzID0gZGF5bGlnaHRTYXZpbmdzOworICAgICAgICAvLyBUT0RPOiBkbyB3ZSBuZWVkIHRvIHNldCB1c2VEYXlsaWdodCBpcyBkc3RTYXZpbmdzICE9IDA/CisKKyAgICAgICAgc2V0U3RhcnRSdWxlKHN0YXJ0TW9udGgsIHN0YXJ0RGF5LCBzdGFydERheU9mV2Vlaywgc3RhcnRUaW1lKTsKKyAgICAgICAgc2V0RW5kUnVsZShlbmRNb250aCwgZW5kRGF5LCBlbmREYXlPZldlZWssIGVuZFRpbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIHtAY29kZSBTaW1wbGVUaW1lWm9uZX0gd2l0aCB0aGUgZ2l2ZW4gYmFzZSB0aW1lIHpvbmUgb2Zmc2V0IGZyb20gR01ULAorICAgICAqIHRpbWUgem9uZSBJRCwgdGltZXMgdG8gc3RhcnQgYW5kIGVuZCB0aGUgZGF5bGlnaHQgc2F2aW5ncyB0aW1lIGluY2x1ZGluZyBhCisgICAgICogbW9kZSBzcGVjaWZpZXIsIHRoZSBkYXlsaWdodCBzYXZpbmdzIHRpbWUgZGlmZmVyZW5jZSBpbiBtaWxsaXNlY29uZHMuCisgICAgICogVGhlIG1vZGUgc3BlY2lmaWVzIGVpdGhlciB7QGxpbmsgI1dBTExfVElNRX0sIHtAbGluayAjU1RBTkRBUkRfVElNRX0sIG9yCisgICAgICoge0BsaW5rICNVVENfVElNRX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgZ2l2ZW4gYmFzZSB0aW1lIHpvbmUgb2Zmc2V0IHRvIEdNVC4KKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHRpbWUgem9uZSBJRCB3aGljaCBpcyBvYnRhaW5lZCBmcm9tCisgICAgICogICAgICAgICAgICB7QGNvZGUgVGltZVpvbmUuZ2V0QXZhaWxhYmxlSURzfS4KKyAgICAgKiBAcGFyYW0gc3RhcnRNb250aAorICAgICAqICAgICAgICAgICAgdGhlIGRheWxpZ2h0IHNhdmluZ3Mgc3RhcnRpbmcgbW9udGguIFRoZSBtb250aCBpbmRleGluZyBpcyAwLWJhc2VkLiBlZywgMAorICAgICAqICAgICAgICAgICAgZm9yIEphbnVhcnkuCisgICAgICogQHBhcmFtIHN0YXJ0RGF5CisgICAgICogICAgICAgICAgICB0aGUgZGF5bGlnaHQgc2F2aW5ncyBzdGFydGluZyBkYXktb2Ytd2Vlay1pbi1tb250aC4gUGxlYXNlIHNlZQorICAgICAqICAgICAgICAgICAgdGhlIGRlc2NyaXB0aW9uIG9mIHtAbGluayAjU2ltcGxlVGltZVpvbmUoaW50LCBTdHJpbmcsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50KX0gZm9yIGFuIGV4YW1wbGUuCisgICAgICogQHBhcmFtIHN0YXJ0RGF5T2ZXZWVrCisgICAgICogICAgICAgICAgICB0aGUgZGF5bGlnaHQgc2F2aW5ncyBzdGFydGluZyBkYXktb2Ytd2Vlay4gUGxlYXNlIHNlZSB0aGUKKyAgICAgKiAgICAgICAgICAgIGRlc2NyaXB0aW9uIG9mIHtAbGluayAjU2ltcGxlVGltZVpvbmUoaW50LCBTdHJpbmcsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50KX0gZm9yIGFuIGV4YW1wbGUuCisgICAgICogQHBhcmFtIHN0YXJ0VGltZQorICAgICAqICAgICAgICAgICAgdGhlIHRpbWUgb2YgZGF5IGluIG1pbGxpc2Vjb25kcyBvbiB3aGljaCBkYXlsaWdodCBzYXZpbmdzCisgICAgICogICAgICAgICAgICB0aW1lIHN0YXJ0cywgYmFzZWQgb24gdGhlIHtAY29kZSBzdGFydFRpbWVNb2RlfS4KKyAgICAgKiBAcGFyYW0gc3RhcnRUaW1lTW9kZQorICAgICAqICAgICAgICAgICAgdGhlIG1vZGUgKFVUQywgc3RhbmRhcmQsIG9yIHdhbGwgdGltZSkgb2YgdGhlIHN0YXJ0IHRpbWUKKyAgICAgKiAgICAgICAgICAgIHZhbHVlLgorICAgICAqIEBwYXJhbSBlbmREYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXkgb2YgdGhlIHdlZWsgb24gd2hpY2ggZGF5bGlnaHQgc2F2aW5ncyB0aW1lIGVuZHMuCisgICAgICogQHBhcmFtIGVuZE1vbnRoCisgICAgICogICAgICAgICAgICB0aGUgZGF5bGlnaHQgc2F2aW5ncyBlbmRpbmcgbW9udGguIFRoZSBtb250aCBpbmRleGluZyBpcyAwLWJhc2VkLiBlZywgMCBmb3IKKyAgICAgKiAgICAgICAgICAgIEphbnVhcnkuCisgICAgICogQHBhcmFtIGVuZERheU9mV2VlaworICAgICAqICAgICAgICAgICAgdGhlIGRheWxpZ2h0IHNhdmluZ3MgZW5kaW5nIGRheS1vZi13ZWVrLiBQbGVhc2Ugc2VlIHRoZSBkZXNjcmlwdGlvbiBvZgorICAgICAqICAgICAgICAgICAge0BsaW5rICNTaW1wbGVUaW1lWm9uZShpbnQsIFN0cmluZywgaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQpfSBmb3IgYW4gZXhhbXBsZS4KKyAgICAgKiBAcGFyYW0gZW5kVGltZQorICAgICAqICAgICAgICAgICAgdGhlIHRpbWUgb2YgZGF5IGluIG1pbGxpc2Vjb25kcyBvbiB3aGljaCBkYXlsaWdodCBzYXZpbmdzCisgICAgICogICAgICAgICAgICB0aW1lIGVuZHMsIGJhc2VkIG9uIHRoZSB7QGNvZGUgZW5kVGltZU1vZGV9LgorICAgICAqIEBwYXJhbSBlbmRUaW1lTW9kZQorICAgICAqICAgICAgICAgICAgdGhlIG1vZGUgKFVUQywgc3RhbmRhcmQsIG9yIHdhbGwgdGltZSkgb2YgdGhlIGVuZCB0aW1lIHZhbHVlLgorICAgICAqIEBwYXJhbSBkYXlsaWdodFNhdmluZ3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXlsaWdodCBzYXZpbmdzIHRpbWUgZGlmZmVyZW5jZSBpbiBtaWxsaXNlY29uZHMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbW9udGgsIGRheSwgZGF5T2ZXZWVrLCBvciB0aW1lIHBhcmFtZXRlcnMgYXJlIG91dCBvZgorICAgICAqICAgICAgICAgICAgIHJhbmdlIGZvciB0aGUgc3RhcnQgb3IgZW5kIHJ1bGUuCisgICAgICovCisgICAgcHVibGljIFNpbXBsZVRpbWVab25lKGludCBvZmZzZXQsIFN0cmluZyBuYW1lLCBpbnQgc3RhcnRNb250aCwKKyAgICAgICAgICAgIGludCBzdGFydERheSwgaW50IHN0YXJ0RGF5T2ZXZWVrLCBpbnQgc3RhcnRUaW1lLCBpbnQgc3RhcnRUaW1lTW9kZSwKKyAgICAgICAgICAgIGludCBlbmRNb250aCwgaW50IGVuZERheSwgaW50IGVuZERheU9mV2VlaywgaW50IGVuZFRpbWUsCisgICAgICAgICAgICBpbnQgZW5kVGltZU1vZGUsIGludCBkYXlsaWdodFNhdmluZ3MpIHsKKworICAgICAgICB0aGlzKG9mZnNldCwgbmFtZSwgc3RhcnRNb250aCwgc3RhcnREYXksIHN0YXJ0RGF5T2ZXZWVrLCBzdGFydFRpbWUsCisgICAgICAgICAgICAgICAgZW5kTW9udGgsIGVuZERheSwgZW5kRGF5T2ZXZWVrLCBlbmRUaW1lLCBkYXlsaWdodFNhdmluZ3MpOworICAgICAgICBzdGFydE1vZGUgPSBzdGFydFRpbWVNb2RlOworICAgICAgICBlbmRNb2RlID0gZW5kVGltZU1vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgU2ltcGxlVGltZVpvbmV9IHdpdGggdGhlIHNhbWUgSUQsIHtAY29kZSByYXdPZmZzZXR9IGFuZCBkYXlsaWdodAorICAgICAqIHNhdmluZ3MgdGltZSBydWxlcyBhcyB0aGlzIFNpbXBsZVRpbWVab25lLgorICAgICAqCisgICAgICogQHJldHVybiBhIHNoYWxsb3cgY29weSBvZiB0aGlzIHtAY29kZSBTaW1wbGVUaW1lWm9uZX0uCisgICAgICogQHNlZSBqYXZhLmxhbmcuQ2xvbmVhYmxlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgU2ltcGxlVGltZVpvbmUgem9uZSA9IChTaW1wbGVUaW1lWm9uZSkgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgcmV0dXJuIHpvbmU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBvYmplY3QgdG8gdGhpcyB7QGNvZGUgU2ltcGxlVGltZVpvbmV9IGFuZCByZXR1cm5zIHdoZXRoZXIgdGhleQorICAgICAqIGFyZSBlcXVhbC4gVGhlIG9iamVjdCBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIHtAY29kZSBTaW1wbGVUaW1lWm9uZX0gYW5kIGhhdmUgdGhlCisgICAgICogc2FtZSBpbnRlcm5hbCBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHdpdGggdGhpcyBvYmplY3QuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgZXF1YWwgdG8gdGhpcworICAgICAqICAgICAgICAge0Bjb2RlIFNpbXBsZVRpbWVab25lfSwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNlZSAjaGFzaENvZGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBTaW1wbGVUaW1lWm9uZSkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBTaW1wbGVUaW1lWm9uZSB0eiA9IChTaW1wbGVUaW1lWm9uZSkgb2JqZWN0OworICAgICAgICByZXR1cm4gZ2V0SUQoKS5lcXVhbHModHouZ2V0SUQoKSkKKyAgICAgICAgICAgICAgICAmJiByYXdPZmZzZXQgPT0gdHoucmF3T2Zmc2V0CisgICAgICAgICAgICAgICAgJiYgdXNlRGF5bGlnaHQgPT0gdHoudXNlRGF5bGlnaHQKKyAgICAgICAgICAgICAgICAmJiAoIXVzZURheWxpZ2h0IHx8IChzdGFydFllYXIgPT0gdHouc3RhcnRZZWFyCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBzdGFydE1vbnRoID09IHR6LnN0YXJ0TW9udGgKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIHN0YXJ0RGF5ID09IHR6LnN0YXJ0RGF5ICYmIHN0YXJ0TW9kZSA9PSB0ei5zdGFydE1vZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIHN0YXJ0RGF5T2ZXZWVrID09IHR6LnN0YXJ0RGF5T2ZXZWVrCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBzdGFydFRpbWUgPT0gdHouc3RhcnRUaW1lICYmIGVuZE1vbnRoID09IHR6LmVuZE1vbnRoCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBlbmREYXkgPT0gdHouZW5kRGF5CisgICAgICAgICAgICAgICAgICAgICAgICAmJiBlbmREYXlPZldlZWsgPT0gdHouZW5kRGF5T2ZXZWVrCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBlbmRUaW1lID09IHR6LmVuZFRpbWUgJiYgZW5kTW9kZSA9PSB0ei5lbmRNb2RlICYmIGRzdFNhdmluZ3MgPT0gdHouZHN0U2F2aW5ncykpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0RFNUU2F2aW5ncygpIHsKKyAgICAgICAgaWYgKCF1c2VEYXlsaWdodCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRzdFNhdmluZ3M7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRPZmZzZXQoaW50IGVyYSwgaW50IHllYXIsIGludCBtb250aCwgaW50IGRheSwgaW50IGRheU9mV2VlaywgaW50IHRpbWUpIHsKKyAgICAgICAgaWYgKGVyYSAhPSBHcmVnb3JpYW5DYWxlbmRhci5CQyAmJiBlcmEgIT0gR3JlZ29yaWFuQ2FsZW5kYXIuQUQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgZXJhOiAiICsgZXJhKTsKKyAgICAgICAgfQorICAgICAgICBjaGVja1JhbmdlKG1vbnRoLCBkYXlPZldlZWssIHRpbWUpOworICAgICAgICBpZiAobW9udGggIT0gQ2FsZW5kYXIuRkVCUlVBUlkgfHwgZGF5ICE9IDI5IHx8ICFpc0xlYXBZZWFyKHllYXIpKSB7CisgICAgICAgICAgICBjaGVja0RheShtb250aCwgZGF5KTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghdXNlRGF5bGlnaHRUaW1lKCkgfHwgZXJhICE9IEdyZWdvcmlhbkNhbGVuZGFyLkFEIHx8IHllYXIgPCBzdGFydFllYXIpIHsKKyAgICAgICAgICAgIHJldHVybiByYXdPZmZzZXQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVuZE1vbnRoIDwgc3RhcnRNb250aCkgeworICAgICAgICAgICAgaWYgKG1vbnRoID4gZW5kTW9udGggJiYgbW9udGggPCBzdGFydE1vbnRoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHJhd09mZnNldDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChtb250aCA8IHN0YXJ0TW9udGggfHwgbW9udGggPiBlbmRNb250aCkgeworICAgICAgICAgICAgICAgIHJldHVybiByYXdPZmZzZXQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpbnQgcnVsZURheSA9IDAsIGRheXNJbk1vbnRoLCBmaXJzdERheU9mTW9udGggPSBtb2Q3KGRheU9mV2VlayAtIGRheSk7CisgICAgICAgIGlmIChtb250aCA9PSBzdGFydE1vbnRoKSB7CisgICAgICAgICAgICBzd2l0Y2ggKHN0YXJ0TW9kZSkgeworICAgICAgICAgICAgICAgIGNhc2UgRE9NX01PREU6CisgICAgICAgICAgICAgICAgICAgIHJ1bGVEYXkgPSBzdGFydERheTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBET1dfSU5fTU9OVEhfTU9ERToKKyAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXJ0RGF5ID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGVEYXkgPSBtb2Q3KHN0YXJ0RGF5T2ZXZWVrIC0gZmlyc3REYXlPZk1vbnRoKSArIDEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAoc3RhcnREYXkgLSAxKSAqIDc7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkYXlzSW5Nb250aCA9IEdyZWdvcmlhbkNhbGVuZGFyLkRheXNJbk1vbnRoW3N0YXJ0TW9udGhdOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXJ0TW9udGggPT0gQ2FsZW5kYXIuRkVCUlVBUlkgJiYgaXNMZWFwWWVhcigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhcikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXlzSW5Nb250aCArPSAxOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgcnVsZURheSA9IGRheXNJbk1vbnRoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgMQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIG1vZDcoc3RhcnREYXlPZldlZWsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSAoZmlyc3REYXlPZk1vbnRoICsgZGF5c0luTW9udGgpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHN0YXJ0RGF5ICogNzsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIERPV19HRV9ET01fTU9ERToKKyAgICAgICAgICAgICAgICAgICAgcnVsZURheSA9IHN0YXJ0RGF5CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBtb2Q3KHN0YXJ0RGF5T2ZXZWVrCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSAoZmlyc3REYXlPZk1vbnRoICsgc3RhcnREYXkgLSAxKSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgRE9XX0xFX0RPTV9NT0RFOgorICAgICAgICAgICAgICAgICAgICBydWxlRGF5ID0gc3RhcnREYXkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIG1vZDcoc3RhcnREYXlPZldlZWsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIChmaXJzdERheU9mTW9udGggKyBzdGFydERheSAtIDEpKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHJ1bGVEYXkgIT0gc3RhcnREYXkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGVEYXkgLT0gNzsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChydWxlRGF5ID4gZGF5IHx8IHJ1bGVEYXkgPT0gZGF5ICYmIHRpbWUgPCBzdGFydFRpbWUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmF3T2Zmc2V0OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaW50IHJ1bGVUaW1lID0gZW5kVGltZSAtIGRzdFNhdmluZ3M7CisgICAgICAgIGludCBuZXh0TW9udGggPSAobW9udGggKyAxKSAlIDEyOworICAgICAgICBpZiAobW9udGggPT0gZW5kTW9udGggfHwgKHJ1bGVUaW1lIDwgMCAmJiBuZXh0TW9udGggPT0gZW5kTW9udGgpKSB7CisgICAgICAgICAgICBzd2l0Y2ggKGVuZE1vZGUpIHsKKyAgICAgICAgICAgICAgICBjYXNlIERPTV9NT0RFOgorICAgICAgICAgICAgICAgICAgICBydWxlRGF5ID0gZW5kRGF5OworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIERPV19JTl9NT05USF9NT0RFOgorICAgICAgICAgICAgICAgICAgICBpZiAoZW5kRGF5ID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGVEYXkgPSBtb2Q3KGVuZERheU9mV2VlayAtIGZpcnN0RGF5T2ZNb250aCkgKyAxCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKGVuZERheSAtIDEpICogNzsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRheXNJbk1vbnRoID0gR3JlZ29yaWFuQ2FsZW5kYXIuRGF5c0luTW9udGhbZW5kTW9udGhdOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVuZE1vbnRoID09IENhbGVuZGFyLkZFQlJVQVJZICYmIGlzTGVhcFllYXIoeWVhcikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXlzSW5Nb250aCsrOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgcnVsZURheSA9IGRheXNJbk1vbnRoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgMQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIG1vZDcoZW5kRGF5T2ZXZWVrCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gKGZpcnN0RGF5T2ZNb250aCArIGRheXNJbk1vbnRoKSkgKyBlbmREYXkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiA3OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgRE9XX0dFX0RPTV9NT0RFOgorICAgICAgICAgICAgICAgICAgICBydWxlRGF5ID0gZW5kRGF5CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBtb2Q3KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZERheU9mV2VlayAtIChmaXJzdERheU9mTW9udGggKyBlbmREYXkgLSAxKSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgRE9XX0xFX0RPTV9NT0RFOgorICAgICAgICAgICAgICAgICAgICBydWxlRGF5ID0gZW5kRGF5CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBtb2Q3KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZERheU9mV2VlayAtIChmaXJzdERheU9mTW9udGggKyBlbmREYXkgLSAxKSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChydWxlRGF5ICE9IGVuZERheSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcnVsZURheSAtPSA3OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgcnVsZU1vbnRoID0gZW5kTW9udGg7CisgICAgICAgICAgICBpZiAocnVsZVRpbWUgPCAwKSB7CisgICAgICAgICAgICAgICAgaW50IGNoYW5nZURheXMgPSAxIC0gKHJ1bGVUaW1lIC8gODY0MDAwMDApOworICAgICAgICAgICAgICAgIHJ1bGVUaW1lID0gKHJ1bGVUaW1lICUgODY0MDAwMDApICsgODY0MDAwMDA7CisgICAgICAgICAgICAgICAgcnVsZURheSAtPSBjaGFuZ2VEYXlzOworICAgICAgICAgICAgICAgIGlmIChydWxlRGF5IDw9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKC0tcnVsZU1vbnRoIDwgQ2FsZW5kYXIuSkFOVUFSWSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcnVsZU1vbnRoID0gQ2FsZW5kYXIuREVDRU1CRVI7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcnVsZURheSArPSBHcmVnb3JpYW5DYWxlbmRhci5EYXlzSW5Nb250aFtydWxlTW9udGhdOworICAgICAgICAgICAgICAgICAgICBpZiAocnVsZU1vbnRoID09IENhbGVuZGFyLkZFQlJVQVJZICYmIGlzTGVhcFllYXIoeWVhcikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGVEYXkrKzsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKG1vbnRoID09IHJ1bGVNb250aCkgeworICAgICAgICAgICAgICAgIGlmIChydWxlRGF5IDwgZGF5IHx8IHJ1bGVEYXkgPT0gZGF5ICYmIHRpbWUgPj0gcnVsZVRpbWUpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJhd09mZnNldDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKG5leHRNb250aCAhPSBydWxlTW9udGgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmF3T2Zmc2V0OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByYXdPZmZzZXQgKyBkc3RTYXZpbmdzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0T2Zmc2V0KGxvbmcgdGltZSkgeworICAgICAgICAvLyBTaW1wbGlmaWVkIHZhcmlhbnQgb2YgdGhlIElDVTRKIGNvZGUuCisgICAgICAgIGlmICghdXNlRGF5bGlnaHRUaW1lKCkpIHsKKyAgICAgICAgICAgIHJldHVybiByYXdPZmZzZXQ7CisgICAgICAgIH0KKyAgICAgICAgaW50W10gZmllbGRzID0gR3JlZ28udGltZVRvRmllbGRzKHRpbWUgKyByYXdPZmZzZXQsIG51bGwpOworICAgICAgICByZXR1cm4gZ2V0T2Zmc2V0KEdyZWdvcmlhbkNhbGVuZGFyLkFELCBmaWVsZHNbMF0sIGZpZWxkc1sxXSwgZmllbGRzWzJdLAorICAgICAgICAgICAgICAgIGZpZWxkc1szXSwgZmllbGRzWzVdKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFJhd09mZnNldCgpIHsKKyAgICAgICAgcmV0dXJuIHJhd09mZnNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGludGVnZXIgaGFzaCBjb2RlIGZvciB0aGUgcmVjZWl2ZXIuIE9iamVjdHMgd2hpY2ggYXJlIGVxdWFsCisgICAgICogcmV0dXJuIHRoZSBzYW1lIHZhbHVlIGZvciB0aGlzIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgaGFzaC4KKyAgICAgKiBAc2VlICNlcXVhbHMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IGhhc2hDb2RlID0gZ2V0SUQoKS5oYXNoQ29kZSgpICsgcmF3T2Zmc2V0OworICAgICAgICBpZiAodXNlRGF5bGlnaHQpIHsKKyAgICAgICAgICAgIGhhc2hDb2RlICs9IHN0YXJ0WWVhciArIHN0YXJ0TW9udGggKyBzdGFydERheSArIHN0YXJ0RGF5T2ZXZWVrCisgICAgICAgICAgICAgICAgICAgICsgc3RhcnRUaW1lICsgc3RhcnRNb2RlICsgZW5kTW9udGggKyBlbmREYXkgKyBlbmREYXlPZldlZWsKKyAgICAgICAgICAgICAgICAgICAgKyBlbmRUaW1lICsgZW5kTW9kZSArIGRzdFNhdmluZ3M7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGhhc2hDb2RlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGhhc1NhbWVSdWxlcyhUaW1lWm9uZSB6b25lKSB7CisgICAgICAgIGlmICghKHpvbmUgaW5zdGFuY2VvZiBTaW1wbGVUaW1lWm9uZSkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBTaW1wbGVUaW1lWm9uZSB0eiA9IChTaW1wbGVUaW1lWm9uZSkgem9uZTsKKyAgICAgICAgaWYgKHVzZURheWxpZ2h0ICE9IHR6LnVzZURheWxpZ2h0KSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF1c2VEYXlsaWdodCkgeworICAgICAgICAgICAgcmV0dXJuIHJhd09mZnNldCA9PSB0ei5yYXdPZmZzZXQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJhd09mZnNldCA9PSB0ei5yYXdPZmZzZXQgJiYgZHN0U2F2aW5ncyA9PSB0ei5kc3RTYXZpbmdzCisgICAgICAgICAgICAgICAgJiYgc3RhcnRZZWFyID09IHR6LnN0YXJ0WWVhciAmJiBzdGFydE1vbnRoID09IHR6LnN0YXJ0TW9udGgKKyAgICAgICAgICAgICAgICAmJiBzdGFydERheSA9PSB0ei5zdGFydERheSAmJiBzdGFydE1vZGUgPT0gdHouc3RhcnRNb2RlCisgICAgICAgICAgICAgICAgJiYgc3RhcnREYXlPZldlZWsgPT0gdHouc3RhcnREYXlPZldlZWsKKyAgICAgICAgICAgICAgICAmJiBzdGFydFRpbWUgPT0gdHouc3RhcnRUaW1lICYmIGVuZE1vbnRoID09IHR6LmVuZE1vbnRoCisgICAgICAgICAgICAgICAgJiYgZW5kRGF5ID09IHR6LmVuZERheSAmJiBlbmREYXlPZldlZWsgPT0gdHouZW5kRGF5T2ZXZWVrCisgICAgICAgICAgICAgICAgJiYgZW5kVGltZSA9PSB0ei5lbmRUaW1lICYmIGVuZE1vZGUgPT0gdHouZW5kTW9kZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaW5EYXlsaWdodFRpbWUoRGF0ZSB0aW1lKSB7CisgICAgICAgIHJldHVybiB1c2VEYXlsaWdodFRpbWUoKSAmJiBnZXRPZmZzZXQodGltZS5nZXRUaW1lKCkpICE9IGdldFJhd09mZnNldCgpOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBpc0xlYXBZZWFyKGludCB5ZWFyKSB7CisgICAgICAgIGlmICh5ZWFyID4gMTU4MikgeworICAgICAgICAgICAgcmV0dXJuIHllYXIgJSA0ID09IDAgJiYgKHllYXIgJSAxMDAgIT0gMCB8fCB5ZWFyICUgNDAwID09IDApOworICAgICAgICB9CisgICAgICAgIHJldHVybiB5ZWFyICUgNCA9PSAwOworICAgIH0KKworICAgIHByaXZhdGUgaW50IG1vZDcoaW50IG51bTEpIHsKKyAgICAgICAgaW50IHJlbSA9IG51bTEgJSA3OworICAgICAgICByZXR1cm4gKG51bTEgPCAwICYmIHJlbSA8IDApID8gNyArIHJlbSA6IHJlbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkYXlsaWdodCBzYXZpbmdzIG9mZnNldCBpbiBtaWxsaXNlY29uZHMgZm9yIHRoaXMge0Bjb2RlIFNpbXBsZVRpbWVab25lfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtaWxsaXNlY29uZHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXlsaWdodCBzYXZpbmdzIG9mZnNldCBpbiBtaWxsaXNlY29uZHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RFNUU2F2aW5ncyhpbnQgbWlsbGlzZWNvbmRzKSB7CisgICAgICAgIGlmIChtaWxsaXNlY29uZHMgPiAwKSB7CisgICAgICAgICAgICBkc3RTYXZpbmdzID0gbWlsbGlzZWNvbmRzOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrUmFuZ2UoaW50IG1vbnRoLCBpbnQgZGF5T2ZXZWVrLCBpbnQgdGltZSkgeworICAgICAgICBpZiAobW9udGggPCBDYWxlbmRhci5KQU5VQVJZIHx8IG1vbnRoID4gQ2FsZW5kYXIuREVDRU1CRVIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgbW9udGg6ICIgKyBtb250aCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRheU9mV2VlayA8IENhbGVuZGFyLlNVTkRBWSB8fCBkYXlPZldlZWsgPiBDYWxlbmRhci5TQVRVUkRBWSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBkYXkgb2Ygd2VlazogIiArIGRheU9mV2Vlayk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRpbWUgPCAwIHx8IHRpbWUgPj0gMjQgKiAzNjAwMDAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIHRpbWU6ICIgKyB0aW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja0RheShpbnQgbW9udGgsIGludCBkYXkpIHsKKyAgICAgICAgaWYgKGRheSA8PSAwIHx8IGRheSA+IEdyZWdvcmlhbkNhbGVuZGFyLkRheXNJbk1vbnRoW21vbnRoXSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBkYXkgb2YgbW9udGg6ICIgKyBkYXkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNldEVuZE1vZGUoKSB7CisgICAgICAgIGlmIChlbmREYXlPZldlZWsgPT0gMCkgeworICAgICAgICAgICAgZW5kTW9kZSA9IERPTV9NT0RFOworICAgICAgICB9IGVsc2UgaWYgKGVuZERheU9mV2VlayA8IDApIHsKKyAgICAgICAgICAgIGVuZERheU9mV2VlayA9IC1lbmREYXlPZldlZWs7CisgICAgICAgICAgICBpZiAoZW5kRGF5IDwgMCkgeworICAgICAgICAgICAgICAgIGVuZERheSA9IC1lbmREYXk7CisgICAgICAgICAgICAgICAgZW5kTW9kZSA9IERPV19MRV9ET01fTU9ERTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZW5kTW9kZSA9IERPV19HRV9ET01fTU9ERTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGVuZE1vZGUgPSBET1dfSU5fTU9OVEhfTU9ERTsKKyAgICAgICAgfQorICAgICAgICB1c2VEYXlsaWdodCA9IHN0YXJ0RGF5ICE9IDAgJiYgZW5kRGF5ICE9IDA7CisgICAgICAgIGlmIChlbmREYXkgIT0gMCkgeworICAgICAgICAgICAgY2hlY2tSYW5nZShlbmRNb250aCwgZW5kTW9kZSA9PSBET01fTU9ERSA/IDEgOiBlbmREYXlPZldlZWssCisgICAgICAgICAgICAgICAgICAgIGVuZFRpbWUpOworICAgICAgICAgICAgaWYgKGVuZE1vZGUgIT0gRE9XX0lOX01PTlRIX01PREUpIHsKKyAgICAgICAgICAgICAgICBjaGVja0RheShlbmRNb250aCwgZW5kRGF5KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKGVuZERheSA8IC01IHx8IGVuZERheSA+IDUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRGF5IG9mIHdlZWsgaW4gbW9udGg6ICIgKyBlbmREYXkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoZW5kTW9kZSAhPSBET01fTU9ERSkgeworICAgICAgICAgICAgZW5kRGF5T2ZXZWVrLS07CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBydWxlIHdoaWNoIHNwZWNpZmllcyB0aGUgZW5kIG9mIGRheWxpZ2h0IHNhdmluZ3MgdGltZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb250aAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDYWxlbmRhcn0gbW9udGggaW4gd2hpY2ggZGF5bGlnaHQgc2F2aW5ncyB0aW1lIGVuZHMuCisgICAgICogQHBhcmFtIGRheU9mTW9udGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9IGRheSBvZiB0aGUgbW9udGggb24gd2hpY2ggZGF5bGlnaHQgc2F2aW5ncyB0aW1lCisgICAgICogICAgICAgICAgICBlbmRzLgorICAgICAqIEBwYXJhbSB0aW1lCisgICAgICogICAgICAgICAgICB0aGUgdGltZSBvZiBkYXkgaW4gbWlsbGlzZWNvbmRzIHN0YW5kYXJkIHRpbWUgb24gd2hpY2gKKyAgICAgKiAgICAgICAgICAgIGRheWxpZ2h0IHNhdmluZ3MgdGltZSBlbmRzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEVuZFJ1bGUoaW50IG1vbnRoLCBpbnQgZGF5T2ZNb250aCwgaW50IHRpbWUpIHsKKyAgICAgICAgZW5kTW9udGggPSBtb250aDsKKyAgICAgICAgZW5kRGF5ID0gZGF5T2ZNb250aDsKKyAgICAgICAgZW5kRGF5T2ZXZWVrID0gMDsgLy8gSW5pdGlhbGl6ZSB0aGlzIHZhbHVlIGZvciBoYXNTYW1lUnVsZXMoKQorICAgICAgICBlbmRUaW1lID0gdGltZTsKKyAgICAgICAgc2V0RW5kTW9kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHJ1bGUgd2hpY2ggc3BlY2lmaWVzIHRoZSBlbmQgb2YgZGF5bGlnaHQgc2F2aW5ncyB0aW1lLgorICAgICAqCisgICAgICogQHBhcmFtIG1vbnRoCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIENhbGVuZGFyfSBtb250aCBpbiB3aGljaCBkYXlsaWdodCBzYXZpbmdzIHRpbWUgZW5kcy4KKyAgICAgKiBAcGFyYW0gZGF5CisgICAgICogICAgICAgICAgICB0aGUgb2NjdXJyZW5jZSBvZiB0aGUgZGF5IG9mIHRoZSB3ZWVrIG9uIHdoaWNoIGRheWxpZ2h0CisgICAgICogICAgICAgICAgICBzYXZpbmdzIHRpbWUgZW5kcy4KKyAgICAgKiBAcGFyYW0gZGF5T2ZXZWVrCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIENhbGVuZGFyfSBkYXkgb2YgdGhlIHdlZWsgb24gd2hpY2ggZGF5bGlnaHQgc2F2aW5ncyB0aW1lCisgICAgICogICAgICAgICAgICBlbmRzLgorICAgICAqIEBwYXJhbSB0aW1lCisgICAgICogICAgICAgICAgICB0aGUgdGltZSBvZiBkYXkgaW4gbWlsbGlzZWNvbmRzIHN0YW5kYXJkIHRpbWUgb24gd2hpY2gKKyAgICAgKiAgICAgICAgICAgIGRheWxpZ2h0IHNhdmluZ3MgdGltZSBlbmRzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEVuZFJ1bGUoaW50IG1vbnRoLCBpbnQgZGF5LCBpbnQgZGF5T2ZXZWVrLCBpbnQgdGltZSkgeworICAgICAgICBlbmRNb250aCA9IG1vbnRoOworICAgICAgICBlbmREYXkgPSBkYXk7CisgICAgICAgIGVuZERheU9mV2VlayA9IGRheU9mV2VlazsKKyAgICAgICAgZW5kVGltZSA9IHRpbWU7CisgICAgICAgIHNldEVuZE1vZGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBydWxlIHdoaWNoIHNwZWNpZmllcyB0aGUgZW5kIG9mIGRheWxpZ2h0IHNhdmluZ3MgdGltZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb250aAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDYWxlbmRhcn0gbW9udGggaW4gd2hpY2ggZGF5bGlnaHQgc2F2aW5ncyB0aW1lIGVuZHMuCisgICAgICogQHBhcmFtIGRheQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDYWxlbmRhcn0gZGF5IG9mIHRoZSBtb250aC4KKyAgICAgKiBAcGFyYW0gZGF5T2ZXZWVrCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIENhbGVuZGFyfSBkYXkgb2YgdGhlIHdlZWsgb24gd2hpY2ggZGF5bGlnaHQgc2F2aW5ncyB0aW1lCisgICAgICogICAgICAgICAgICBlbmRzLgorICAgICAqIEBwYXJhbSB0aW1lCisgICAgICogICAgICAgICAgICB0aGUgdGltZSBvZiBkYXkgaW4gbWlsbGlzZWNvbmRzIG9uIHdoaWNoIGRheWxpZ2h0IHNhdmluZ3MgdGltZQorICAgICAqICAgICAgICAgICAgZW5kcy4KKyAgICAgKiBAcGFyYW0gYWZ0ZXIKKyAgICAgKiAgICAgICAgICAgIHNlbGVjdHMgdGhlIGRheSBhZnRlciBvciBiZWZvcmUgdGhlIGRheSBvZiBtb250aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRFbmRSdWxlKGludCBtb250aCwgaW50IGRheSwgaW50IGRheU9mV2VlaywgaW50IHRpbWUsIGJvb2xlYW4gYWZ0ZXIpIHsKKyAgICAgICAgZW5kTW9udGggPSBtb250aDsKKyAgICAgICAgZW5kRGF5ID0gYWZ0ZXIgPyBkYXkgOiAtZGF5OworICAgICAgICBlbmREYXlPZldlZWsgPSAtZGF5T2ZXZWVrOworICAgICAgICBlbmRUaW1lID0gdGltZTsKKyAgICAgICAgc2V0RW5kTW9kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG9mZnNldCBmb3Igc3RhbmRhcmQgdGltZSBmcm9tIEdNVCBmb3IgdGhpcyB7QGNvZGUgU2ltcGxlVGltZVpvbmV9LgorICAgICAqCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBmcm9tIEdNVCBvZiBzdGFuZGFyZCB0aW1lIGluIG1pbGxpc2Vjb25kcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRSYXdPZmZzZXQoaW50IG9mZnNldCkgeworICAgICAgICByYXdPZmZzZXQgPSBvZmZzZXQ7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNldFN0YXJ0TW9kZSgpIHsKKyAgICAgICAgaWYgKHN0YXJ0RGF5T2ZXZWVrID09IDApIHsKKyAgICAgICAgICAgIHN0YXJ0TW9kZSA9IERPTV9NT0RFOworICAgICAgICB9IGVsc2UgaWYgKHN0YXJ0RGF5T2ZXZWVrIDwgMCkgeworICAgICAgICAgICAgc3RhcnREYXlPZldlZWsgPSAtc3RhcnREYXlPZldlZWs7CisgICAgICAgICAgICBpZiAoc3RhcnREYXkgPCAwKSB7CisgICAgICAgICAgICAgICAgc3RhcnREYXkgPSAtc3RhcnREYXk7CisgICAgICAgICAgICAgICAgc3RhcnRNb2RlID0gRE9XX0xFX0RPTV9NT0RFOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzdGFydE1vZGUgPSBET1dfR0VfRE9NX01PREU7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzdGFydE1vZGUgPSBET1dfSU5fTU9OVEhfTU9ERTsKKyAgICAgICAgfQorICAgICAgICB1c2VEYXlsaWdodCA9IHN0YXJ0RGF5ICE9IDAgJiYgZW5kRGF5ICE9IDA7CisgICAgICAgIGlmIChzdGFydERheSAhPSAwKSB7CisgICAgICAgICAgICBjaGVja1JhbmdlKHN0YXJ0TW9udGgsIHN0YXJ0TW9kZSA9PSBET01fTU9ERSA/IDEgOiBzdGFydERheU9mV2VlaywKKyAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lKTsKKyAgICAgICAgICAgIGlmIChzdGFydE1vZGUgIT0gRE9XX0lOX01PTlRIX01PREUpIHsKKyAgICAgICAgICAgICAgICBjaGVja0RheShzdGFydE1vbnRoLCBzdGFydERheSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmIChzdGFydERheSA8IC01IHx8IHN0YXJ0RGF5ID4gNSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJEYXkgb2Ygd2VlayBpbiBtb250aDogIiArIHN0YXJ0RGF5KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHN0YXJ0TW9kZSAhPSBET01fTU9ERSkgeworICAgICAgICAgICAgc3RhcnREYXlPZldlZWstLTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHJ1bGUgd2hpY2ggc3BlY2lmaWVzIHRoZSBzdGFydCBvZiBkYXlsaWdodCBzYXZpbmdzIHRpbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbW9udGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9IG1vbnRoIGluIHdoaWNoIGRheWxpZ2h0IHNhdmluZ3MgdGltZSBzdGFydHMuCisgICAgICogQHBhcmFtIGRheU9mTW9udGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9IGRheSBvZiB0aGUgbW9udGggb24gd2hpY2ggZGF5bGlnaHQgc2F2aW5ncyB0aW1lCisgICAgICogICAgICAgICAgICBzdGFydHMuCisgICAgICogQHBhcmFtIHRpbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0aW1lIG9mIGRheSBpbiBtaWxsaXNlY29uZHMgb24gd2hpY2ggZGF5bGlnaHQgc2F2aW5ncyB0aW1lCisgICAgICogICAgICAgICAgICBzdGFydHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3RhcnRSdWxlKGludCBtb250aCwgaW50IGRheU9mTW9udGgsIGludCB0aW1lKSB7CisgICAgICAgIHN0YXJ0TW9udGggPSBtb250aDsKKyAgICAgICAgc3RhcnREYXkgPSBkYXlPZk1vbnRoOworICAgICAgICBzdGFydERheU9mV2VlayA9IDA7IC8vIEluaXRpYWxpemUgdGhpcyB2YWx1ZSBmb3IgaGFzU2FtZVJ1bGVzKCkKKyAgICAgICAgc3RhcnRUaW1lID0gdGltZTsKKyAgICAgICAgc2V0U3RhcnRNb2RlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcnVsZSB3aGljaCBzcGVjaWZpZXMgdGhlIHN0YXJ0IG9mIGRheWxpZ2h0IHNhdmluZ3MgdGltZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb250aAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDYWxlbmRhcn0gbW9udGggaW4gd2hpY2ggZGF5bGlnaHQgc2F2aW5ncyB0aW1lIHN0YXJ0cy4KKyAgICAgKiBAcGFyYW0gZGF5CisgICAgICogICAgICAgICAgICB0aGUgb2NjdXJyZW5jZSBvZiB0aGUgZGF5IG9mIHRoZSB3ZWVrIG9uIHdoaWNoIGRheWxpZ2h0CisgICAgICogICAgICAgICAgICBzYXZpbmdzIHRpbWUgc3RhcnRzLgorICAgICAqIEBwYXJhbSBkYXlPZldlZWsKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9IGRheSBvZiB0aGUgd2VlayBvbiB3aGljaCBkYXlsaWdodCBzYXZpbmdzIHRpbWUKKyAgICAgKiAgICAgICAgICAgIHN0YXJ0cy4KKyAgICAgKiBAcGFyYW0gdGltZQorICAgICAqICAgICAgICAgICAgdGhlIHRpbWUgb2YgZGF5IGluIG1pbGxpc2Vjb25kcyBvbiB3aGljaCBkYXlsaWdodCBzYXZpbmdzIHRpbWUKKyAgICAgKiAgICAgICAgICAgIHN0YXJ0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTdGFydFJ1bGUoaW50IG1vbnRoLCBpbnQgZGF5LCBpbnQgZGF5T2ZXZWVrLCBpbnQgdGltZSkgeworICAgICAgICBzdGFydE1vbnRoID0gbW9udGg7CisgICAgICAgIHN0YXJ0RGF5ID0gZGF5OworICAgICAgICBzdGFydERheU9mV2VlayA9IGRheU9mV2VlazsKKyAgICAgICAgc3RhcnRUaW1lID0gdGltZTsKKyAgICAgICAgc2V0U3RhcnRNb2RlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcnVsZSB3aGljaCBzcGVjaWZpZXMgdGhlIHN0YXJ0IG9mIGRheWxpZ2h0IHNhdmluZ3MgdGltZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb250aAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDYWxlbmRhcn0gbW9udGggaW4gd2hpY2ggZGF5bGlnaHQgc2F2aW5ncyB0aW1lIHN0YXJ0cy4KKyAgICAgKiBAcGFyYW0gZGF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIENhbGVuZGFyfSBkYXkgb2YgdGhlIG1vbnRoLgorICAgICAqIEBwYXJhbSBkYXlPZldlZWsKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9IGRheSBvZiB0aGUgd2VlayBvbiB3aGljaCBkYXlsaWdodCBzYXZpbmdzIHRpbWUKKyAgICAgKiAgICAgICAgICAgIHN0YXJ0cy4KKyAgICAgKiBAcGFyYW0gdGltZQorICAgICAqICAgICAgICAgICAgdGhlIHRpbWUgb2YgZGF5IGluIG1pbGxpc2Vjb25kcyBvbiB3aGljaCBkYXlsaWdodCBzYXZpbmdzIHRpbWUKKyAgICAgKiAgICAgICAgICAgIHN0YXJ0cy4KKyAgICAgKiBAcGFyYW0gYWZ0ZXIKKyAgICAgKiAgICAgICAgICAgIHNlbGVjdHMgdGhlIGRheSBhZnRlciBvciBiZWZvcmUgdGhlIGRheSBvZiBtb250aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTdGFydFJ1bGUoaW50IG1vbnRoLCBpbnQgZGF5LCBpbnQgZGF5T2ZXZWVrLCBpbnQgdGltZSwgYm9vbGVhbiBhZnRlcikgeworICAgICAgICBzdGFydE1vbnRoID0gbW9udGg7CisgICAgICAgIHN0YXJ0RGF5ID0gYWZ0ZXIgPyBkYXkgOiAtZGF5OworICAgICAgICBzdGFydERheU9mV2VlayA9IC1kYXlPZldlZWs7CisgICAgICAgIHN0YXJ0VGltZSA9IHRpbWU7CisgICAgICAgIHNldFN0YXJ0TW9kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHN0YXJ0aW5nIHllYXIgZm9yIGRheWxpZ2h0IHNhdmluZ3MgdGltZSBpbiB0aGlzIHtAY29kZSBTaW1wbGVUaW1lWm9uZX0uCisgICAgICogWWVhcnMgYmVmb3JlIHRoaXMgc3RhcnQgeWVhciB3aWxsIGFsd2F5cyBiZSBpbiBzdGFuZGFyZCB0aW1lLgorICAgICAqCisgICAgICogQHBhcmFtIHllYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydGluZyB5ZWFyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN0YXJ0WWVhcihpbnQgeWVhcikgeworICAgICAgICBzdGFydFllYXIgPSB5ZWFyOworICAgICAgICB1c2VEYXlsaWdodCA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMge0Bjb2RlIFNpbXBsZVRpbWVab25lfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZSBTaW1wbGVUaW1lWm9uZX0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIGdldENsYXNzKCkuZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgKyAiW2lkPSIKKyAgICAgICAgICAgICAgICArIGdldElEKCkKKyAgICAgICAgICAgICAgICArICIsb2Zmc2V0PSIKKyAgICAgICAgICAgICAgICArIHJhd09mZnNldAorICAgICAgICAgICAgICAgICsgIixkc3RTYXZpbmdzPSIKKyAgICAgICAgICAgICAgICArIGRzdFNhdmluZ3MKKyAgICAgICAgICAgICAgICArICIsdXNlRGF5bGlnaHQ9IgorICAgICAgICAgICAgICAgICsgdXNlRGF5bGlnaHQKKyAgICAgICAgICAgICAgICArICIsc3RhcnRZZWFyPSIKKyAgICAgICAgICAgICAgICArIHN0YXJ0WWVhcgorICAgICAgICAgICAgICAgICsgIixzdGFydE1vZGU9IgorICAgICAgICAgICAgICAgICsgc3RhcnRNb2RlCisgICAgICAgICAgICAgICAgKyAiLHN0YXJ0TW9udGg9IgorICAgICAgICAgICAgICAgICsgc3RhcnRNb250aAorICAgICAgICAgICAgICAgICsgIixzdGFydERheT0iCisgICAgICAgICAgICAgICAgKyBzdGFydERheQorICAgICAgICAgICAgICAgICsgIixzdGFydERheU9mV2Vlaz0iCisgICAgICAgICAgICAgICAgKyAodXNlRGF5bGlnaHQgJiYgKHN0YXJ0TW9kZSAhPSBET01fTU9ERSkgPyBzdGFydERheU9mV2VlayArIDEKKyAgICAgICAgICAgICAgICAgICAgICAgIDogMCkgKyAiLHN0YXJ0VGltZT0iICsgc3RhcnRUaW1lICsgIixlbmRNb2RlPSIKKyAgICAgICAgICAgICAgICArIGVuZE1vZGUgKyAiLGVuZE1vbnRoPSIgKyBlbmRNb250aCArICIsZW5kRGF5PSIgKyBlbmREYXkKKyAgICAgICAgICAgICAgICArICIsZW5kRGF5T2ZXZWVrPSIKKyAgICAgICAgICAgICAgICArICh1c2VEYXlsaWdodCAmJiAoZW5kTW9kZSAhPSBET01fTU9ERSkgPyBlbmREYXlPZldlZWsgKyAxIDogMCkKKyAgICAgICAgICAgICAgICArICIsZW5kVGltZT0iICsgZW5kVGltZSArICJdIjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiB1c2VEYXlsaWdodFRpbWUoKSB7CisgICAgICAgIHJldHVybiB1c2VEYXlsaWdodDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RTdHJlYW1GaWVsZFtdIHNlcmlhbFBlcnNpc3RlbnRGaWVsZHMgPSB7CisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiZHN0U2F2aW5ncyIsIGludC5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiZW5kRGF5IiwgaW50LmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJlbmREYXlPZldlZWsiLCBpbnQuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImVuZE1vZGUiLCBpbnQuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImVuZE1vbnRoIiwgaW50LmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJlbmRUaW1lIiwgaW50LmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJtb250aExlbmd0aCIsIGJ5dGVbXS5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgicmF3T2Zmc2V0IiwgaW50LmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJzZXJpYWxWZXJzaW9uT25TdHJlYW0iLCBpbnQuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInN0YXJ0RGF5IiwgaW50LmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJzdGFydERheU9mV2VlayIsIGludC5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgic3RhcnRNb2RlIiwgaW50LmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJzdGFydE1vbnRoIiwgaW50LmNsYXNzKSwKKyAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJzdGFydFRpbWUiLCBpbnQuY2xhc3MpLAorICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInN0YXJ0WWVhciIsIGludC5jbGFzcyksCisgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgidXNlRGF5bGlnaHQiLCBib29sZWFuLmNsYXNzKSwKKyAgICB9OworCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBzRW5kRGF5ID0gZW5kRGF5LCBzRW5kRGF5T2ZXZWVrID0gZW5kRGF5T2ZXZWVrICsgMSwgc1N0YXJ0RGF5ID0gc3RhcnREYXksIHNTdGFydERheU9mV2VlayA9IHN0YXJ0RGF5T2ZXZWVrICsgMTsKKyAgICAgICAgaWYgKHVzZURheWxpZ2h0CisgICAgICAgICAgICAgICAgJiYgKHN0YXJ0TW9kZSAhPSBET1dfSU5fTU9OVEhfTU9ERSB8fCBlbmRNb2RlICE9IERPV19JTl9NT05USF9NT0RFKSkgeworICAgICAgICAgICAgQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKHRoaXMpOworICAgICAgICAgICAgaWYgKGVuZE1vZGUgIT0gRE9XX0lOX01PTlRIX01PREUpIHsKKyAgICAgICAgICAgICAgICBjYWwuc2V0KENhbGVuZGFyLk1PTlRILCBlbmRNb250aCk7CisgICAgICAgICAgICAgICAgY2FsLnNldChDYWxlbmRhci5EQVRFLCBlbmREYXkpOworICAgICAgICAgICAgICAgIHNFbmREYXkgPSBjYWwuZ2V0KENhbGVuZGFyLkRBWV9PRl9XRUVLX0lOX01PTlRIKTsKKyAgICAgICAgICAgICAgICBpZiAoZW5kTW9kZSA9PSBET01fTU9ERSkgeworICAgICAgICAgICAgICAgICAgICBzRW5kRGF5T2ZXZWVrID0gY2FsLmdldEZpcnN0RGF5T2ZXZWVrKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHN0YXJ0TW9kZSAhPSBET1dfSU5fTU9OVEhfTU9ERSkgeworICAgICAgICAgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuTU9OVEgsIHN0YXJ0TW9udGgpOworICAgICAgICAgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuREFURSwgc3RhcnREYXkpOworICAgICAgICAgICAgICAgIHNTdGFydERheSA9IGNhbC5nZXQoQ2FsZW5kYXIuREFZX09GX1dFRUtfSU5fTU9OVEgpOworICAgICAgICAgICAgICAgIGlmIChzdGFydE1vZGUgPT0gRE9NX01PREUpIHsKKyAgICAgICAgICAgICAgICAgICAgc1N0YXJ0RGF5T2ZXZWVrID0gY2FsLmdldEZpcnN0RGF5T2ZXZWVrKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIE9iamVjdE91dHB1dFN0cmVhbS5QdXRGaWVsZCBmaWVsZHMgPSBzdHJlYW0ucHV0RmllbGRzKCk7CisgICAgICAgIGZpZWxkcy5wdXQoImRzdFNhdmluZ3MiLCBkc3RTYXZpbmdzKTsKKyAgICAgICAgZmllbGRzLnB1dCgiZW5kRGF5Iiwgc0VuZERheSk7CisgICAgICAgIGZpZWxkcy5wdXQoImVuZERheU9mV2VlayIsIHNFbmREYXlPZldlZWspOworICAgICAgICBmaWVsZHMucHV0KCJlbmRNb2RlIiwgZW5kTW9kZSk7CisgICAgICAgIGZpZWxkcy5wdXQoImVuZE1vbnRoIiwgZW5kTW9udGgpOworICAgICAgICBmaWVsZHMucHV0KCJlbmRUaW1lIiwgZW5kVGltZSk7CisgICAgICAgIGZpZWxkcy5wdXQoIm1vbnRoTGVuZ3RoIiwgR3JlZ29yaWFuQ2FsZW5kYXIuRGF5c0luTW9udGgpOworICAgICAgICBmaWVsZHMucHV0KCJyYXdPZmZzZXQiLCByYXdPZmZzZXQpOworICAgICAgICBmaWVsZHMucHV0KCJzZXJpYWxWZXJzaW9uT25TdHJlYW0iLCAxKTsKKyAgICAgICAgZmllbGRzLnB1dCgic3RhcnREYXkiLCBzU3RhcnREYXkpOworICAgICAgICBmaWVsZHMucHV0KCJzdGFydERheU9mV2VlayIsIHNTdGFydERheU9mV2Vlayk7CisgICAgICAgIGZpZWxkcy5wdXQoInN0YXJ0TW9kZSIsIHN0YXJ0TW9kZSk7CisgICAgICAgIGZpZWxkcy5wdXQoInN0YXJ0TW9udGgiLCBzdGFydE1vbnRoKTsKKyAgICAgICAgZmllbGRzLnB1dCgic3RhcnRUaW1lIiwgc3RhcnRUaW1lKTsKKyAgICAgICAgZmllbGRzLnB1dCgic3RhcnRZZWFyIiwgc3RhcnRZZWFyKTsKKyAgICAgICAgZmllbGRzLnB1dCgidXNlRGF5bGlnaHQiLCB1c2VEYXlsaWdodCk7CisgICAgICAgIHN0cmVhbS53cml0ZUZpZWxkcygpOworICAgICAgICBzdHJlYW0ud3JpdGVJbnQoNCk7CisgICAgICAgIGJ5dGVbXSB2YWx1ZXMgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgdmFsdWVzWzBdID0gKGJ5dGUpIHN0YXJ0RGF5OworICAgICAgICB2YWx1ZXNbMV0gPSAoYnl0ZSkgKHN0YXJ0TW9kZSA9PSBET01fTU9ERSA/IDAgOiBzdGFydERheU9mV2VlayArIDEpOworICAgICAgICB2YWx1ZXNbMl0gPSAoYnl0ZSkgZW5kRGF5OworICAgICAgICB2YWx1ZXNbM10gPSAoYnl0ZSkgKGVuZE1vZGUgPT0gRE9NX01PREUgPyAwIDogZW5kRGF5T2ZXZWVrICsgMSk7CisgICAgICAgIHN0cmVhbS53cml0ZSh2YWx1ZXMpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkIGZpZWxkcyA9IHN0cmVhbS5yZWFkRmllbGRzKCk7CisgICAgICAgIHJhd09mZnNldCA9IGZpZWxkcy5nZXQoInJhd09mZnNldCIsIDApOworICAgICAgICB1c2VEYXlsaWdodCA9IGZpZWxkcy5nZXQoInVzZURheWxpZ2h0IiwgZmFsc2UpOworICAgICAgICBpZiAodXNlRGF5bGlnaHQpIHsKKyAgICAgICAgICAgIGVuZE1vbnRoID0gZmllbGRzLmdldCgiZW5kTW9udGgiLCAwKTsKKyAgICAgICAgICAgIGVuZFRpbWUgPSBmaWVsZHMuZ2V0KCJlbmRUaW1lIiwgMCk7CisgICAgICAgICAgICBzdGFydE1vbnRoID0gZmllbGRzLmdldCgic3RhcnRNb250aCIsIDApOworICAgICAgICAgICAgc3RhcnRUaW1lID0gZmllbGRzLmdldCgic3RhcnRUaW1lIiwgMCk7CisgICAgICAgICAgICBzdGFydFllYXIgPSBmaWVsZHMuZ2V0KCJzdGFydFllYXIiLCAwKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZmllbGRzLmdldCgic2VyaWFsVmVyc2lvbk9uU3RyZWFtIiwgMCkgPT0gMCkgeworICAgICAgICAgICAgaWYgKHVzZURheWxpZ2h0KSB7CisgICAgICAgICAgICAgICAgc3RhcnRNb2RlID0gZW5kTW9kZSA9IERPV19JTl9NT05USF9NT0RFOworICAgICAgICAgICAgICAgIGVuZERheSA9IGZpZWxkcy5nZXQoImVuZERheSIsIDApOworICAgICAgICAgICAgICAgIGVuZERheU9mV2VlayA9IGZpZWxkcy5nZXQoImVuZERheU9mV2VlayIsIDApIC0gMTsKKyAgICAgICAgICAgICAgICBzdGFydERheSA9IGZpZWxkcy5nZXQoInN0YXJ0RGF5IiwgMCk7CisgICAgICAgICAgICAgICAgc3RhcnREYXlPZldlZWsgPSBmaWVsZHMuZ2V0KCJzdGFydERheU9mV2VlayIsIDApIC0gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGRzdFNhdmluZ3MgPSBmaWVsZHMuZ2V0KCJkc3RTYXZpbmdzIiwgMCk7CisgICAgICAgICAgICBpZiAodXNlRGF5bGlnaHQpIHsKKyAgICAgICAgICAgICAgICBlbmRNb2RlID0gZmllbGRzLmdldCgiZW5kTW9kZSIsIDApOworICAgICAgICAgICAgICAgIHN0YXJ0TW9kZSA9IGZpZWxkcy5nZXQoInN0YXJ0TW9kZSIsIDApOworICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBzdHJlYW0ucmVhZEludCgpOworICAgICAgICAgICAgICAgIGJ5dGVbXSB2YWx1ZXMgPSBuZXcgYnl0ZVtsZW5ndGhdOworICAgICAgICAgICAgICAgIHN0cmVhbS5yZWFkRnVsbHkodmFsdWVzKTsKKyAgICAgICAgICAgICAgICBpZiAobGVuZ3RoID49IDQpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhcnREYXkgPSB2YWx1ZXNbMF07CisgICAgICAgICAgICAgICAgICAgIHN0YXJ0RGF5T2ZXZWVrID0gdmFsdWVzWzFdOworICAgICAgICAgICAgICAgICAgICBpZiAoc3RhcnRNb2RlICE9IERPTV9NT0RFKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzdGFydERheU9mV2Vlay0tOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGVuZERheSA9IHZhbHVlc1syXTsKKyAgICAgICAgICAgICAgICAgICAgZW5kRGF5T2ZXZWVrID0gdmFsdWVzWzNdOworICAgICAgICAgICAgICAgICAgICBpZiAoZW5kTW9kZSAhPSBET01fTU9ERSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZW5kRGF5T2ZXZWVrLS07CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvU29ydGVkTWFwLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1NvcnRlZE1hcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFlYzdhZGYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1NvcnRlZE1hcC5qYXZhCkBAIC0wLDAgKzEsMTI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworCisvKioKKyAqIEEgbWFwIHRoYXQgaGFzIGl0cyBrZXlzIG9yZGVyZWQuIFRoZSBzb3J0aW5nIGlzIGFjY29yZGluZyB0byBlaXRoZXIgdGhlCisgKiBuYXR1cmFsIG9yZGVyaW5nIG9mIGl0cyBrZXlzIG9yIHRoZSBvcmRlcmluZyBnaXZlbiBieSBhIHNwZWNpZmllZCBjb21wYXJhdG9yLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFNvcnRlZE1hcDxLLFY+IGV4dGVuZHMgTWFwPEssVj4geworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29tcGFyYXRvciB1c2VkIHRvIGNvbXBhcmUga2V5cyBpbiB0aGlzIHNvcnRlZCBtYXAuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb21wYXJhdG9yIG9yIHtAY29kZSBudWxsfSBpZiB0aGUgbmF0dXJhbCBvcmRlciBpcyB1c2VkLgorICAgICAqLworICAgIHB1YmxpYyBDb21wYXJhdG9yPD8gc3VwZXIgSz4gY29tcGFyYXRvcigpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZmlyc3Qga2V5IGluIHRoaXMgc29ydGVkIG1hcC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGZpcnN0IGtleSBpbiB0aGlzIHNvcnRlZCBtYXAuCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhpcyBzb3J0ZWQgbWFwIGlzIGVtcHR5LgorICAgICAqLworICAgIHB1YmxpYyBLIGZpcnN0S2V5KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc29ydGVkIG1hcCBvdmVyIGEgcmFuZ2Ugb2YgdGhpcyBzb3J0ZWQgbWFwIHdpdGggYWxsIGtleXMgdGhhdAorICAgICAqIGFyZSBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCB7QGNvZGUgZW5kS2V5fS4gQ2hhbmdlcyB0byB0aGUgcmV0dXJuZWQKKyAgICAgKiBzb3J0ZWQgbWFwIGFyZSByZWZsZWN0ZWQgaW4gdGhpcyBzb3J0ZWQgbWFwIGFuZCB2aWNlIHZlcnNhLgorICAgICAqIDxwPgorICAgICAqIE5vdGU6IFRoZSByZXR1cm5lZCBtYXAgd2lsbCBub3QgYWxsb3cgYW4gaW5zZXJ0aW9uIG9mIGEga2V5IG91dHNpZGUgdGhlCisgICAgICogc3BlY2lmaWVkIHJhbmdlLgorICAgICAqCisgICAgICogQHBhcmFtIGVuZEtleQorICAgICAqICAgICAgICAgICAgdGhlIGhpZ2ggYm91bmRhcnkgb2YgdGhlIHJhbmdlIHNwZWNpZmllZC4KKyAgICAgKiBAcmV0dXJuIGEgc29ydGVkIG1hcCB3aGVyZSB0aGUga2V5cyBhcmUgbGVzcyB0aGFuIHtAY29kZSBlbmRLZXl9LgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNsYXNzIG9mIHRoZSBlbmQga2V5IGlzIGluYXBwcm9wcmlhdGUgZm9yIHRoaXMgc29ydGVkCisgICAgICogICAgICAgICAgICAgbWFwLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZW5kIGtleSBpcyB7QGNvZGUgbnVsbH0gYW5kIHRoaXMgc29ydGVkIG1hcCBkb2VzIG5vdAorICAgICAqICAgICAgICAgICAgIHN1cHBvcnQge0Bjb2RlIG51bGx9IGtleXMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1hcCBpcyBpdHNlbGYgYSBzb3J0ZWQgbWFwIG92ZXIgYSByYW5nZSBvZiBhbm90aGVyCisgICAgICogICAgICAgICAgICAgbWFwIGFuZCB0aGUgc3BlY2lmaWVkIGtleSBpcyBvdXRzaWRlIG9mIGl0cyByYW5nZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU29ydGVkTWFwPEssVj4gaGVhZE1hcChLIGVuZEtleSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsYXN0IGtleSBpbiB0aGlzIHNvcnRlZCBtYXAuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsYXN0IGtleSBpbiB0aGlzIHNvcnRlZCBtYXAuCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhpcyBzb3J0ZWQgbWFwIGlzIGVtcHR5LgorICAgICAqLworICAgIHB1YmxpYyBLIGxhc3RLZXkoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzb3J0ZWQgbWFwIG92ZXIgYSByYW5nZSBvZiB0aGlzIHNvcnRlZCBtYXAgd2l0aCBhbGwga2V5cworICAgICAqIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgc3BlY2lmaWVkIHtAY29kZSBzdGFydEtleX0gYW5kIGxlc3MgdGhhbiB0aGUKKyAgICAgKiBzcGVjaWZpZWQge0Bjb2RlIGVuZEtleX0uIENoYW5nZXMgdG8gdGhlIHJldHVybmVkIHNvcnRlZCBtYXAgYXJlCisgICAgICogcmVmbGVjdGVkIGluIHRoaXMgc29ydGVkIG1hcCBhbmQgdmljZSB2ZXJzYS4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlOiBUaGUgcmV0dXJuZWQgbWFwIHdpbGwgbm90IGFsbG93IGFuIGluc2VydGlvbiBvZiBhIGtleSBvdXRzaWRlIHRoZQorICAgICAqIHNwZWNpZmllZCByYW5nZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdGFydEtleQorICAgICAqICAgICAgICAgICAgdGhlIGxvdyBib3VuZGFyeSBvZiB0aGUgcmFuZ2UgKGluY2x1c2l2ZSkuCisgICAgICogQHBhcmFtIGVuZEtleQorICAgICAqICAgICAgICAgICAgdGhlIGhpZ2ggYm91bmRhcnkgb2YgdGhlIHJhbmdlIChleGNsdXNpdmUpLAorICAgICAqIEByZXR1cm4gYSBzb3J0ZWQgbWFwIHdpdGggdGhlIGtleSBmcm9tIHRoZSBzcGVjaWZpZWQgcmFuZ2UuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2xhc3Mgb2YgdGhlIHN0YXJ0IG9yIGVuZCBrZXkgaXMgaW5hcHByb3ByaWF0ZSBmb3IKKyAgICAgKiAgICAgICAgICAgICB0aGlzIHNvcnRlZCBtYXAuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzdGFydCBvciBlbmQga2V5IGlzIHtAY29kZSBudWxsfSBhbmQgdGhpcyBzb3J0ZWQgbWFwCisgICAgICogICAgICAgICAgICAgZG9lcyBub3Qgc3VwcG9ydCB7QGNvZGUgbnVsbH0ga2V5cy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzdGFydCBrZXkgaXMgZ3JlYXRlciB0aGFuIHRoZSBlbmQga2V5LCBvciBpZiB0aGlzIG1hcAorICAgICAqICAgICAgICAgICAgIGlzIGl0c2VsZiBhIHNvcnRlZCBtYXAgb3ZlciBhIHJhbmdlIG9mIGFub3RoZXIgc29ydGVkIG1hcCBhbmQKKyAgICAgKiAgICAgICAgICAgICB0aGUgc3BlY2lmaWVkIHJhbmdlIGlzIG91dHNpZGUgb2YgaXRzIHJhbmdlLgorICAgICAqLworICAgIHB1YmxpYyBTb3J0ZWRNYXA8SyxWPiBzdWJNYXAoSyBzdGFydEtleSwgSyBlbmRLZXkpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNvcnRlZCBtYXAgb3ZlciBhIHJhbmdlIG9mIHRoaXMgc29ydGVkIG1hcCB3aXRoIGFsbCBrZXlzIHRoYXQKKyAgICAgKiBhcmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQge0Bjb2RlIHN0YXJ0S2V5fS4gQ2hhbmdlcyB0bworICAgICAqIHRoZSByZXR1cm5lZCBzb3J0ZWQgbWFwIGFyZSByZWZsZWN0ZWQgaW4gdGhpcyBzb3J0ZWQgbWFwIGFuZCB2aWNlIHZlcnNhLgorICAgICAqIDxwPgorICAgICAqIE5vdGU6IFRoZSByZXR1cm5lZCBtYXAgd2lsbCBub3QgYWxsb3cgYW4gaW5zZXJ0aW9uIG9mIGEga2V5IG91dHNpZGUgdGhlCisgICAgICogc3BlY2lmaWVkIHJhbmdlLgorICAgICAqCisgICAgICogQHBhcmFtIHN0YXJ0S2V5CisgICAgICogICAgICAgICAgICB0aGUgbG93IGJvdW5kYXJ5IG9mIHRoZSByYW5nZSBzcGVjaWZpZWQuCisgICAgICogQHJldHVybiBhIHNvcnRlZCBtYXAgd2hlcmUgdGhlIGtleXMgYXJlIGdyZWF0ZXIgb3IgZXF1YWwgdG8KKyAgICAgKiAgICAgICAgIHtAY29kZSBzdGFydEtleX0uCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2xhc3Mgb2YgdGhlIHN0YXJ0IGtleSBpcyBpbmFwcHJvcHJpYXRlIGZvciB0aGlzCisgICAgICogICAgICAgICAgICAgc29ydGVkIG1hcC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHN0YXJ0IGtleSBpcyB7QGNvZGUgbnVsbH0gYW5kIHRoaXMgc29ydGVkIG1hcCBkb2VzIG5vdAorICAgICAqICAgICAgICAgICAgIHN1cHBvcnQge0Bjb2RlIG51bGx9IGtleXMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG1hcCBpdHNlbGYgYSBzb3J0ZWQgbWFwIG92ZXIgYSByYW5nZSBvZiBhbm90aGVyIG1hcAorICAgICAqICAgICAgICAgICAgIGFuZCB0aGUgc3BlY2lmaWVkIGtleSBpcyBvdXRzaWRlIG9mIGl0cyByYW5nZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU29ydGVkTWFwPEssVj4gdGFpbE1hcChLIHN0YXJ0S2V5KTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvU29ydGVkU2V0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1NvcnRlZFNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEzYjhjMmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1NvcnRlZFNldC5qYXZhCkBAIC0wLDAgKzEsMTE5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworCisvKioKKyAqIFNvcnRlZFNldCBpcyBhIFNldCB3aGljaCBpdGVyYXRlcyBvdmVyIGl0cyBlbGVtZW50cyBpbiBhIHNvcnRlZCBvcmRlci4gVGhlCisgKiBvcmRlciBpcyBkZXRlcm1pbmVkIGVpdGhlciBieSB0aGUgZWxlbWVudHMgbmF0dXJhbCBvcmRlcmluZywgb3IgYnkgYQorICoge0BsaW5rIENvbXBhcmF0b3J9IHdoaWNoIGlzIHBhc3NlZCBpbnRvIGEgY29uY3JldGUgaW1wbGVtZW50YXRpb24gYXQKKyAqIGNvbnN0cnVjdGlvbiB0aW1lLiBBbGwgZWxlbWVudHMgaW4gdGhpcyBzZXQgbXVzdCBiZSBtdXR1YWxseSBjb21wYXJhYmxlLiBUaGUKKyAqIG9yZGVyaW5nIGluIHRoaXMgc2V0IG11c3QgYmUgY29uc2lzdGVudCB3aXRoIHtAY29kZSBlcXVhbHN9IG9mIGl0cyBlbGVtZW50cy4KKyAqCisgKiBAc2VlIENvbXBhcmF0b3IKKyAqIEBzZWUgQ29tcGFyYWJsZQorICovCitwdWJsaWMgaW50ZXJmYWNlIFNvcnRlZFNldDxFPiBleHRlbmRzIFNldDxFPiB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb21wYXJhdG9yIHVzZWQgdG8gY29tcGFyZSBlbGVtZW50cyBpbiB0aGlzIHtAY29kZSBTb3J0ZWRTZXR9LgorICAgICAqCisgICAgICogQHJldHVybiBhIGNvbXBhcmF0b3Igb3IgbnVsbCBpZiB0aGUgbmF0dXJhbCBvcmRlcmluZyBpcyB1c2VkLgorICAgICAqLworICAgIHB1YmxpYyBDb21wYXJhdG9yPD8gc3VwZXIgRT4gY29tcGFyYXRvcigpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZmlyc3QgZWxlbWVudCBpbiB0aGlzIHtAY29kZSBTb3J0ZWRTZXR9LiBUaGUgZmlyc3QgZWxlbWVudAorICAgICAqIGlzIHRoZSBsb3dlc3QgZWxlbWVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGZpcnN0IGVsZW1lbnQuCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiB0aGlzIHtAY29kZSBTb3J0ZWRTZXR9IGlzIGVtcHR5LgorICAgICAqLworICAgIHB1YmxpYyBFIGZpcnN0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0Bjb2RlIFNvcnRlZFNldH0gb2YgdGhlIHNwZWNpZmllZCBwb3J0aW9uIG9mIHRoaXMKKyAgICAgKiB7QGNvZGUgU29ydGVkU2V0fSB3aGljaCBjb250YWlucyBlbGVtZW50cyBsZXNzIHRoYW4gdGhlIGVuZCBlbGVtZW50LiBUaGUKKyAgICAgKiByZXR1cm5lZCB7QGNvZGUgU29ydGVkU2V0fSBpcyBiYWNrZWQgYnkgdGhpcyB7QGNvZGUgU29ydGVkU2V0fSBzbyBjaGFuZ2VzCisgICAgICogdG8gb25lIHNldCBhcmUgcmVmbGVjdGVkIGJ5IHRoZSBvdGhlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmQgZWxlbWVudC4KKyAgICAgKiBAcmV0dXJuIGEgc3Vic2V0IHdoZXJlIHRoZSBlbGVtZW50cyBhcmUgbGVzcyB0aGFuIHtAY29kZSBlbmR9LgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiB0aGUgY2xhc3Mgb2YgdGhlIGVuZCBlbGVtZW50IGlzIGluYXBwcm9wcmlhdGUgZm9yIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBTdWJTZXQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHdoZW4gdGhlIGVuZCBlbGVtZW50IGlzIG51bGwgYW5kIHRoaXMge0Bjb2RlIFNvcnRlZFNldH0gZG9lcworICAgICAqICAgICAgICAgICAgIG5vdCBzdXBwb3J0IG51bGwgZWxlbWVudHMuCisgICAgICovCisgICAgcHVibGljIFNvcnRlZFNldDxFPiBoZWFkU2V0KEUgZW5kKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxhc3QgZWxlbWVudCBpbiB0aGlzIHtAY29kZSBTb3J0ZWRTZXR9LiBUaGUgbGFzdCBlbGVtZW50IGlzCisgICAgICogdGhlIGhpZ2hlc3QgZWxlbWVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxhc3QgZWxlbWVudC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHRoaXMge0Bjb2RlIFNvcnRlZFNldH0gaXMgZW1wdHkuCisgICAgICovCisgICAgcHVibGljIEUgbGFzdCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBTb3J0ZWRTZXR9IG9mIHRoZSBzcGVjaWZpZWQgcG9ydGlvbiBvZiB0aGlzCisgICAgICoge0Bjb2RlIFNvcnRlZFNldH0gd2hpY2ggY29udGFpbnMgZWxlbWVudHMgZ3JlYXRlciBvciBlcXVhbCB0byB0aGUgc3RhcnQKKyAgICAgKiBlbGVtZW50IGJ1dCBsZXNzIHRoYW4gdGhlIGVuZCBlbGVtZW50LiBUaGUgcmV0dXJuZWQge0Bjb2RlIFNvcnRlZFNldH0gaXMKKyAgICAgKiBiYWNrZWQgYnkgdGhpcyBTb3J0ZWRNYXAgc28gY2hhbmdlcyB0byBvbmUgc2V0IGFyZSByZWZsZWN0ZWQgYnkgdGhlCisgICAgICogb3RoZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBlbGVtZW50LgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmQgZWxlbWVudC4KKyAgICAgKiBAcmV0dXJuIGEgc3Vic2V0IHdoZXJlIHRoZSBlbGVtZW50cyBhcmUgZ3JlYXRlciBvciBlcXVhbCB0byB7QGNvZGUgc3RhcnR9CisgICAgICogICAgICAgICBhbmQgbGVzcyB0aGFuIHtAY29kZSBlbmR9LgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiB0aGUgY2xhc3Mgb2YgdGhlIHN0YXJ0IG9yIGVuZCBlbGVtZW50IGlzIGluYXBwcm9wcmlhdGUKKyAgICAgKiAgICAgICAgICAgICBmb3IgdGhpcyBTdWJTZXQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHdoZW4gdGhlIHN0YXJ0IG9yIGVuZCBlbGVtZW50IGlzIG51bGwgYW5kIHRoaXMKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgU29ydGVkU2V0fSBkb2VzIG5vdCBzdXBwb3J0IG51bGwgZWxlbWVudHMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHRoZSBzdGFydCBlbGVtZW50IGlzIGdyZWF0ZXIgdGhhbiB0aGUgZW5kIGVsZW1lbnQuCisgICAgICovCisgICAgcHVibGljIFNvcnRlZFNldDxFPiBzdWJTZXQoRSBzdGFydCwgRSBlbmQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBTb3J0ZWRTZXR9IG9mIHRoZSBzcGVjaWZpZWQgcG9ydGlvbiBvZiB0aGlzCisgICAgICoge0Bjb2RlIFNvcnRlZFNldH0gd2hpY2ggY29udGFpbnMgZWxlbWVudHMgZ3JlYXRlciBvciBlcXVhbCB0byB0aGUgc3RhcnQKKyAgICAgKiBlbGVtZW50LiBUaGUgcmV0dXJuZWQge0Bjb2RlIFNvcnRlZFNldH0gaXMgYmFja2VkIGJ5IHRoaXMKKyAgICAgKiB7QGNvZGUgU29ydGVkU2V0fSBzbyBjaGFuZ2VzIHRvIG9uZSBzZXQgYXJlIHJlZmxlY3RlZCBieSB0aGUgb3RoZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBlbGVtZW50LgorICAgICAqIEByZXR1cm4gYSBzdWJzZXQgd2hlcmUgdGhlIGVsZW1lbnRzIGFyZSBncmVhdGVyIG9yIGVxdWFsIHRvIHtAY29kZSBzdGFydH0gLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiB0aGUgY2xhc3Mgb2YgdGhlIHN0YXJ0IGVsZW1lbnQgaXMgaW5hcHByb3ByaWF0ZSBmb3IgdGhpcworICAgICAqICAgICAgICAgICAgIFN1YlNldC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiB0aGUgc3RhcnQgZWxlbWVudCBpcyBudWxsIGFuZCB0aGlzIHtAY29kZSBTb3J0ZWRTZXR9CisgICAgICogICAgICAgICAgICAgZG9lcyBub3Qgc3VwcG9ydCBudWxsIGVsZW1lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBTb3J0ZWRTZXQ8RT4gdGFpbFNldChFIHN0YXJ0KTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvU3RhY2suamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvU3RhY2suamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZTUxYmVlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9TdGFjay5qYXZhCkBAIC0wLDAgKzEsMTIzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworLyoqCisgKiB7QGNvZGUgU3RhY2t9IGlzIGEgTGFzdC1Jbi9GaXJzdC1PdXQoTElGTykgZGF0YSBzdHJ1Y3R1cmUgd2hpY2ggcmVwcmVzZW50cyBhCisgKiBzdGFjayBvZiBvYmplY3RzLiBJdCBlbmFibGVzIHVzZXJzIHRvIHBvcCB0byBhbmQgcHVzaCBmcm9tIHRoZSBzdGFjaywKKyAqIGluY2x1ZGluZyBudWxsIG9iamVjdHMuIFRoZXJlIGlzIG5vIGxpbWl0IHRvIHRoZSBzaXplIG9mIHRoZSBzdGFjay4KKyAqLworcHVibGljIGNsYXNzIFN0YWNrPEU+IGV4dGVuZHMgVmVjdG9yPEU+IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDEyMjQ0NjMxNjQ1NDEzMzkxNjVMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHN0YWNrIHdpdGggdGhlIGRlZmF1bHQgc2l6ZSBvZiB7QGNvZGUgVmVjdG9yfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RhY2soKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBzdGFjayBpcyBlbXB0eSBvciBub3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3RhY2sgaXMgZW1wdHksIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVtcHR5KCkgeworICAgICAgICByZXR1cm4gaXNFbXB0eSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGVsZW1lbnQgYXQgdGhlIHRvcCBvZiB0aGUgc3RhY2sgd2l0aG91dCByZW1vdmluZyBpdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnQgYXQgdGhlIHRvcCBvZiB0aGUgc3RhY2suCisgICAgICogQHRocm93cyBFbXB0eVN0YWNrRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHN0YWNrIGlzIGVtcHR5LgorICAgICAqIEBzZWUgI3BvcAorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgRSBwZWVrKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIChFKSBlbGVtZW50RGF0YVtlbGVtZW50Q291bnQgLSAxXTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRW1wdHlTdGFja0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZWxlbWVudCBhdCB0aGUgdG9wIG9mIHRoZSBzdGFjayBhbmQgcmVtb3ZlcyBpdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnQgYXQgdGhlIHRvcCBvZiB0aGUgc3RhY2suCisgICAgICogQHRocm93cyBFbXB0eVN0YWNrRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHN0YWNrIGlzIGVtcHR5LgorICAgICAqIEBzZWUgI3BlZWsKKyAgICAgKiBAc2VlICNwdXNoCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN5bmNocm9uaXplZCBFIHBvcCgpIHsKKyAgICAgICAgaWYgKGVsZW1lbnRDb3VudCA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRW1wdHlTdGFja0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIGludCBpbmRleCA9IC0tZWxlbWVudENvdW50OworICAgICAgICBmaW5hbCBFIG9iaiA9IChFKSBlbGVtZW50RGF0YVtpbmRleF07CisgICAgICAgIGVsZW1lbnREYXRhW2luZGV4XSA9IG51bGw7CisgICAgICAgIG1vZENvdW50Kys7CisgICAgICAgIHJldHVybiBvYmo7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHVzaGVzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IG9udG8gdGhlIHRvcCBvZiB0aGUgc3RhY2suCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICBUaGUgb2JqZWN0IHRvIGJlIGFkZGVkIG9uIHRvcCBvZiB0aGUgc3RhY2suCisgICAgICogQHJldHVybiB0aGUgb2JqZWN0IGFyZ3VtZW50LgorICAgICAqIEBzZWUgI3BlZWsKKyAgICAgKiBAc2VlICNwb3AKKyAgICAgKi8KKyAgICBwdWJsaWMgRSBwdXNoKEUgb2JqZWN0KSB7CisgICAgICAgIGFkZEVsZW1lbnQob2JqZWN0KTsKKyAgICAgICAgcmV0dXJuIG9iamVjdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgb2JqZWN0LCBzdGFydGluZyBmcm9tCisgICAgICogdGhlIHRvcCBvZiB0aGUgc3RhY2suCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgb2JqZWN0LCBhc3N1bWluZyB0aGF0CisgICAgICogICAgICAgICB0aGUgdG9wbW9zdCBvYmplY3Qgb24gdGhlIHN0YWNrIGhhcyBhIGRpc3RhbmNlIG9mIG9uZS4KKyAgICAgKiBAcGFyYW0gbworICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBiZSBzZWFyY2hlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBzZWFyY2goT2JqZWN0IG8pIHsKKyAgICAgICAgZmluYWwgT2JqZWN0W10gZHVtcEFycmF5ID0gZWxlbWVudERhdGE7CisgICAgICAgIGZpbmFsIGludCBzaXplID0gZWxlbWVudENvdW50OworICAgICAgICBpZiAobyAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gc2l6ZSAtIDE7IGkgPj0gMDsgaS0tKSB7CisgICAgICAgICAgICAgICAgaWYgKG8uZXF1YWxzKGR1bXBBcnJheVtpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNpemUgLSBpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBzaXplIC0gMTsgaSA+PSAwOyBpLS0pIHsKKyAgICAgICAgICAgICAgICBpZiAoZHVtcEFycmF5W2ldID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNpemUgLSBpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9TdHJpbmdUb2tlbml6ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvU3RyaW5nVG9rZW5pemVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWIwNzYwNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvU3RyaW5nVG9rZW5pemVyLmphdmEKQEAgLTAsMCArMSwyMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisvKioKKyAqIEJyZWFrcyBhIHN0cmluZyBpbnRvIHRva2VuczsgbmV3IGNvZGUgc2hvdWxkIHByb2JhYmx5IHVzZSB7QGxpbmsgU3RyaW5nI3NwbGl0fS4KKyAqCisgKiA8YmxvY2txdW90ZT4KKyAqIDxwcmU+CisgKiAvLyBMZWdhY3kgY29kZToKKyAqIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoImE6YjpjIiwgIjoiKTsKKyAqIHdoaWxlIChzdC5oYXNNb3JlVG9rZW5zKCkpIHsKKyAqICAgICBTeXN0ZW0uZXJyLnByaW50bG4oc3QubmV4dFRva2VuKCkpOworICogfQorICoKKyAqIC8vIE5ldyBjb2RlOgorICogZm9yIChTdHJpbmcgdG9rZW4gOiAiYTpiOmMiLnNwbGl0KCI6IikpIHsKKyAqICAgICBTeXN0ZW0uZXJyLnByaW50bG4odG9rZW4pOworICogfQorICogPC9wcmU+CisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogQHNpbmNlIDEuMAorICovCitwdWJsaWMgY2xhc3MgU3RyaW5nVG9rZW5pemVyIGltcGxlbWVudHMgRW51bWVyYXRpb248T2JqZWN0PiB7CisKKyAgICBwcml2YXRlIFN0cmluZyBzdHJpbmc7CisKKyAgICBwcml2YXRlIFN0cmluZyBkZWxpbWl0ZXJzOworCisgICAgcHJpdmF0ZSBib29sZWFuIHJldHVybkRlbGltaXRlcnM7CisKKyAgICBwcml2YXRlIGludCBwb3NpdGlvbjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFN0cmluZ1Rva2VuaXplcn0gZm9yIHRoZSBwYXJhbWV0ZXIgc3RyaW5nIHVzaW5nCisgICAgICogd2hpdGVzcGFjZSBhcyB0aGUgZGVsaW1pdGVyLiBUaGUge0Bjb2RlIHJldHVybkRlbGltaXRlcnN9IGZsYWcgaXMgc2V0IHRvCisgICAgICoge0Bjb2RlIGZhbHNlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gYmUgdG9rZW5pemVkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdUb2tlbml6ZXIoU3RyaW5nIHN0cmluZykgeworICAgICAgICB0aGlzKHN0cmluZywgIiBcdFxuXHJcZiIsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBTdHJpbmdUb2tlbml6ZXJ9IGZvciB0aGUgcGFyYW1ldGVyIHN0cmluZyB1c2luZworICAgICAqIHRoZSBzcGVjaWZpZWQgZGVsaW1pdGVycy4gVGhlIHtAY29kZSByZXR1cm5EZWxpbWl0ZXJzfSBmbGFnIGlzIHNldCB0bworICAgICAqIHtAY29kZSBmYWxzZX0uIElmIHtAY29kZSBkZWxpbWl0ZXJzfSBpcyB7QGNvZGUgbnVsbH0sIHRoaXMgY29uc3RydWN0b3IKKyAgICAgKiBkb2Vzbid0IHRocm93IGFuIHtAY29kZSBFeGNlcHRpb259LCBidXQgbGF0ZXIgY2FsbHMgdG8gc29tZSBtZXRob2RzIG1pZ2h0CisgICAgICogdGhyb3cgYSB7QGNvZGUgTnVsbFBvaW50ZXJFeGNlcHRpb259LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBiZSB0b2tlbml6ZWQuCisgICAgICogQHBhcmFtIGRlbGltaXRlcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZWxpbWl0ZXJzIHRvIHVzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nVG9rZW5pemVyKFN0cmluZyBzdHJpbmcsIFN0cmluZyBkZWxpbWl0ZXJzKSB7CisgICAgICAgIHRoaXMoc3RyaW5nLCBkZWxpbWl0ZXJzLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgU3RyaW5nVG9rZW5pemVyfSBmb3IgdGhlIHBhcmFtZXRlciBzdHJpbmcgdXNpbmcKKyAgICAgKiB0aGUgc3BlY2lmaWVkIGRlbGltaXRlcnMsIHJldHVybmluZyB0aGUgZGVsaW1pdGVycyBhcyB0b2tlbnMgaWYgdGhlCisgICAgICogcGFyYW1ldGVyIHtAY29kZSByZXR1cm5EZWxpbWl0ZXJzfSBpcyB7QGNvZGUgdHJ1ZX0uIElmIHtAY29kZSBkZWxpbWl0ZXJzfQorICAgICAqIGlzIG51bGwgdGhpcyBjb25zdHJ1Y3RvciBkb2Vzbid0IHRocm93IGFuIHtAY29kZSBFeGNlcHRpb259LCBidXQgbGF0ZXIKKyAgICAgKiBjYWxscyB0byBzb21lIG1ldGhvZHMgbWlnaHQgdGhyb3cgYSB7QGNvZGUgTnVsbFBvaW50ZXJFeGNlcHRpb259LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBiZSB0b2tlbml6ZWQuCisgICAgICogQHBhcmFtIGRlbGltaXRlcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZWxpbWl0ZXJzIHRvIHVzZS4KKyAgICAgKiBAcGFyYW0gcmV0dXJuRGVsaW1pdGVycworICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IHRvIHJldHVybiBlYWNoIGRlbGltaXRlciBhcyBhIHRva2VuLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdUb2tlbml6ZXIoU3RyaW5nIHN0cmluZywgU3RyaW5nIGRlbGltaXRlcnMsCisgICAgICAgICAgICBib29sZWFuIHJldHVybkRlbGltaXRlcnMpIHsKKyAgICAgICAgaWYgKHN0cmluZyAhPSBudWxsKSB7CisgICAgICAgICAgICB0aGlzLnN0cmluZyA9IHN0cmluZzsKKyAgICAgICAgICAgIHRoaXMuZGVsaW1pdGVycyA9IGRlbGltaXRlcnM7CisgICAgICAgICAgICB0aGlzLnJldHVybkRlbGltaXRlcnMgPSByZXR1cm5EZWxpbWl0ZXJzOworICAgICAgICAgICAgdGhpcy5wb3NpdGlvbiA9IDA7CisgICAgICAgIH0gZWxzZQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHVucHJvY2Vzc2VkIHRva2VucyByZW1haW5pbmcgaW4gdGhlIHN0cmluZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gbnVtYmVyIG9mIHRva2VucyB0aGF0IGNhbiBiZSByZXRyZWl2ZWQgYmVmb3JlIGFuIHtAY29kZQorICAgICAqICAgICAgICAgRXhjZXB0aW9ufSB3aWxsIHJlc3VsdCBmcm9tIGEgY2FsbCB0byB7QGNvZGUgbmV4dFRva2VuKCl9LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY291bnRUb2tlbnMoKSB7CisgICAgICAgIGludCBjb3VudCA9IDA7CisgICAgICAgIGJvb2xlYW4gaW5Ub2tlbiA9IGZhbHNlOworICAgICAgICBmb3IgKGludCBpID0gcG9zaXRpb24sIGxlbmd0aCA9IHN0cmluZy5sZW5ndGgoKTsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoZGVsaW1pdGVycy5pbmRleE9mKHN0cmluZy5jaGFyQXQoaSksIDApID49IDApIHsKKyAgICAgICAgICAgICAgICBpZiAocmV0dXJuRGVsaW1pdGVycykKKyAgICAgICAgICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgICAgICAgICBpZiAoaW5Ub2tlbikgeworICAgICAgICAgICAgICAgICAgICBjb3VudCsrOworICAgICAgICAgICAgICAgICAgICBpblRva2VuID0gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpblRva2VuID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoaW5Ub2tlbikKKyAgICAgICAgICAgIGNvdW50Kys7CisgICAgICAgIHJldHVybiBjb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB1bnByb2Nlc3NlZCB0b2tlbnMgcmVtYWluLiBUaGlzIG1ldGhvZCBpcworICAgICAqIGltcGxlbWVudGVkIGluIG9yZGVyIHRvIHNhdGlzZnkgdGhlIHtAY29kZSBFbnVtZXJhdGlvbn0gaW50ZXJmYWNlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdW5wcm9jZXNzZWQgdG9rZW5zIHJlbWFpbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNNb3JlRWxlbWVudHMoKSB7CisgICAgICAgIHJldHVybiBoYXNNb3JlVG9rZW5zKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdW5wcm9jZXNzZWQgdG9rZW5zIHJlbWFpbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHVucHJvY2Vzc2VkIHRva2VucyByZW1haW4uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzTW9yZVRva2VucygpIHsKKyAgICAgICAgaWYgKGRlbGltaXRlcnMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGxlbmd0aCA9IHN0cmluZy5sZW5ndGgoKTsKKyAgICAgICAgaWYgKHBvc2l0aW9uIDwgbGVuZ3RoKSB7CisgICAgICAgICAgICBpZiAocmV0dXJuRGVsaW1pdGVycykKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gdGhlcmUgaXMgYXQgbGVhc3Qgb25lIGNoYXJhY3RlciBhbmQgZXZlbiBpZgorICAgICAgICAgICAgLy8gaXQgaXMgYSBkZWxpbWl0ZXIgaXQgaXMgYSB0b2tlbgorCisgICAgICAgICAgICAvLyBvdGhlcndpc2UgZmluZCBhIGNoYXJhY3RlciB3aGljaCBpcyBub3QgYSBkZWxpbWl0ZXIKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBwb3NpdGlvbjsgaSA8IGxlbmd0aDsgaSsrKQorICAgICAgICAgICAgICAgIGlmIChkZWxpbWl0ZXJzLmluZGV4T2Yoc3RyaW5nLmNoYXJBdChpKSwgMCkgPT0gLTEpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IHRva2VuIGluIHRoZSBzdHJpbmcgYXMgYW4ge0Bjb2RlIE9iamVjdH0uIFRoaXMgbWV0aG9kIGlzCisgICAgICogaW1wbGVtZW50ZWQgaW4gb3JkZXIgdG8gc2F0aXNmeSB0aGUge0Bjb2RlIEVudW1lcmF0aW9ufSBpbnRlcmZhY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIG5leHQgdG9rZW4gaW4gdGhlIHN0cmluZyBhcyBhbiB7QGNvZGUgT2JqZWN0fQorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG5vIHRva2VucyByZW1haW4uCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBuZXh0RWxlbWVudCgpIHsKKyAgICAgICAgcmV0dXJuIG5leHRUb2tlbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQgdG9rZW4gaW4gdGhlIHN0cmluZyBhcyBhIHtAY29kZSBTdHJpbmd9LgorICAgICAqCisgICAgICogQHJldHVybiBuZXh0IHRva2VuIGluIHRoZSBzdHJpbmcgYXMgYSB7QGNvZGUgU3RyaW5nfS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyB0b2tlbnMgcmVtYWluLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgbmV4dFRva2VuKCkgeworICAgICAgICBpZiAoZGVsaW1pdGVycyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgaSA9IHBvc2l0aW9uOworICAgICAgICBpbnQgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aCgpOworCisgICAgICAgIGlmIChpIDwgbGVuZ3RoKSB7CisgICAgICAgICAgICBpZiAocmV0dXJuRGVsaW1pdGVycykgeworICAgICAgICAgICAgICAgIGlmIChkZWxpbWl0ZXJzLmluZGV4T2Yoc3RyaW5nLmNoYXJBdChwb3NpdGlvbiksIDApID49IDApCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBTdHJpbmcudmFsdWVPZihzdHJpbmcuY2hhckF0KHBvc2l0aW9uKyspKTsKKyAgICAgICAgICAgICAgICBmb3IgKHBvc2l0aW9uKys7IHBvc2l0aW9uIDwgbGVuZ3RoOyBwb3NpdGlvbisrKQorICAgICAgICAgICAgICAgICAgICBpZiAoZGVsaW1pdGVycy5pbmRleE9mKHN0cmluZy5jaGFyQXQocG9zaXRpb24pLCAwKSA+PSAwKQorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0cmluZy5zdWJzdHJpbmcoaSwgcG9zaXRpb24pOworICAgICAgICAgICAgICAgIHJldHVybiBzdHJpbmcuc3Vic3RyaW5nKGkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB3aGlsZSAoaSA8IGxlbmd0aCAmJiBkZWxpbWl0ZXJzLmluZGV4T2Yoc3RyaW5nLmNoYXJBdChpKSwgMCkgPj0gMCkKKyAgICAgICAgICAgICAgICBpKys7CisgICAgICAgICAgICBwb3NpdGlvbiA9IGk7CisgICAgICAgICAgICBpZiAoaSA8IGxlbmd0aCkgeworICAgICAgICAgICAgICAgIGZvciAocG9zaXRpb24rKzsgcG9zaXRpb24gPCBsZW5ndGg7IHBvc2l0aW9uKyspCisgICAgICAgICAgICAgICAgICAgIGlmIChkZWxpbWl0ZXJzLmluZGV4T2Yoc3RyaW5nLmNoYXJBdChwb3NpdGlvbiksIDApID49IDApCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyaW5nLnN1YnN0cmluZyhpLCBwb3NpdGlvbik7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN0cmluZy5zdWJzdHJpbmcoaSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IHRva2VuIGluIHRoZSBzdHJpbmcgYXMgYSB7QGNvZGUgU3RyaW5nfS4gVGhlIGRlbGltaXRlcnMKKyAgICAgKiB1c2VkIGFyZSBjaGFuZ2VkIHRvIHRoZSBzcGVjaWZpZWQgZGVsaW1pdGVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZWxpbXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgZGVsaW1pdGVycyB0byB1c2UuCisgICAgICogQHJldHVybiBuZXh0IHRva2VuIGluIHRoZSBzdHJpbmcgYXMgYSB7QGNvZGUgU3RyaW5nfS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBubyB0b2tlbnMgcmVtYWluLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgbmV4dFRva2VuKFN0cmluZyBkZWxpbXMpIHsKKyAgICAgICAgdGhpcy5kZWxpbWl0ZXJzID0gZGVsaW1zOworICAgICAgICByZXR1cm4gbmV4dFRva2VuKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9UaW1Tb3J0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1RpbVNvcnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZmU0ZTE3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9UaW1Tb3J0LmphdmEKQEAgLTAsMCArMSw5MDMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworLyoqCisgKiBBIHN0YWJsZSwgYWRhcHRpdmUsIGl0ZXJhdGl2ZSBtZXJnZXNvcnQgdGhhdCByZXF1aXJlcyBmYXIgZmV3ZXIgdGhhbgorICogbiBsZyhuKSBjb21wYXJpc29ucyB3aGVuIHJ1bm5pbmcgb24gcGFydGlhbGx5IHNvcnRlZCBhcnJheXMsIHdoaWxlCisgKiBvZmZlcmluZyBwZXJmb3JtYW5jZSBjb21wYXJhYmxlIHRvIGEgdHJhZGl0aW9uYWwgbWVyZ2Vzb3J0IHdoZW4gcnVuCisgKiBvbiByYW5kb20gYXJyYXlzLiAgTGlrZSBhbGwgcHJvcGVyIG1lcmdlc29ydHMsIHRoaXMgc29ydCBpcyBzdGFibGUgYW5kCisgKiBydW5zIE8obiBsb2cgbikgdGltZSAod29yc3QgY2FzZSkuICBJbiB0aGUgd29yc3QgY2FzZSwgdGhpcyBzb3J0IHJlcXVpcmVzCisgKiB0ZW1wb3Jhcnkgc3RvcmFnZSBzcGFjZSBmb3Igbi8yIG9iamVjdCByZWZlcmVuY2VzOyBpbiB0aGUgYmVzdCBjYXNlLAorICogaXQgcmVxdWlyZXMgb25seSBhIHNtYWxsIGNvbnN0YW50IGFtb3VudCBvZiBzcGFjZS4KKyAqCisgKiBUaGlzIGltcGxlbWVudGF0aW9uIHdhcyBhZGFwdGVkIGZyb20gVGltIFBldGVycydzIGxpc3Qgc29ydCBmb3IKKyAqIFB5dGhvbiwgd2hpY2ggaXMgZGVzY3JpYmVkIGluIGRldGFpbCBoZXJlOgorICoKKyAqICAgaHR0cDovL3N2bi5weXRob24ub3JnL3Byb2plY3RzL3B5dGhvbi90cnVuay9PYmplY3RzL2xpc3Rzb3J0LnR4dAorICoKKyAqIFRpbSdzIEMgY29kZSBtYXkgYmUgZm91bmQgaGVyZToKKyAqCisgKiAgIGh0dHA6Ly9zdm4ucHl0aG9uLm9yZy9wcm9qZWN0cy9weXRob24vdHJ1bmsvT2JqZWN0cy9saXN0b2JqZWN0LmMKKyAqCisgKiBUaGUgdW5kZXJseWluZyB0ZWNobmlxdWVzIGFyZSBkZXNjcmliZWQgaW4gdGhpcyBwYXBlciAoYW5kIG1heSBoYXZlCisgKiBldmVuIGVhcmxpZXIgb3JpZ2lucyk6CisgKgorICogICJPcHRpbWlzdGljIFNvcnRpbmcgYW5kIEluZm9ybWF0aW9uIFRoZW9yZXRpYyBDb21wbGV4aXR5IgorICogIFBldGVyIE1jSWxyb3kKKyAqICBTT0RBIChGb3VydGggQW5udWFsIEFDTS1TSUFNIFN5bXBvc2l1bSBvbiBEaXNjcmV0ZSBBbGdvcml0aG1zKSwKKyAqICBwcCA0NjctNDc0LCBBdXN0aW4sIFRleGFzLCAyNS0yNyBKYW51YXJ5IDE5OTMuCisgKgorICogV2hpbGUgdGhlIEFQSSB0byB0aGlzIGNsYXNzIGNvbnNpc3RzIHNvbGVseSBvZiBzdGF0aWMgbWV0aG9kcywgaXQgaXMKKyAqIChwcml2YXRlbHkpIGluc3RhbnRpYWJsZTsgYSBUaW1Tb3J0IGluc3RhbmNlIGhvbGRzIHRoZSBzdGF0ZSBvZiBhbiBvbmdvaW5nCisgKiBzb3J0LCBhc3N1bWluZyB0aGUgaW5wdXQgYXJyYXkgaXMgbGFyZ2UgZW5vdWdoIHRvIHdhcnJhbnQgdGhlIGZ1bGwtYmxvd24KKyAqIFRpbVNvcnQuIFNtYWxsIGFycmF5cyBhcmUgc29ydGVkIGluIHBsYWNlLCB1c2luZyBhIGJpbmFyeSBpbnNlcnRpb24gc29ydC4KKyAqLworY2xhc3MgVGltU29ydDxUPiB7CisgICAgLyoqCisgICAgICogVGhpcyBpcyB0aGUgbWluaW11bSBzaXplZCBzZXF1ZW5jZSB0aGF0IHdpbGwgYmUgbWVyZ2VkLiAgU2hvcnRlcgorICAgICAqIHNlcXVlbmNlcyB3aWxsIGJlIGxlbmd0aGVuZWQgYnkgY2FsbGluZyBiaW5hcnlTb3J0LiAgSWYgdGhlIGVudGlyZQorICAgICAqIGFycmF5IGlzIGxlc3MgdGhhbiB0aGlzIGxlbmd0aCwgbm8gbWVyZ2VzIHdpbGwgYmUgcGVyZm9ybWVkLgorICAgICAqCisgICAgICogVGhpcyBjb25zdGFudCBzaG91bGQgYmUgYSBwb3dlciBvZiB0d28uICBJdCB3YXMgNjQgaW4gVGltIFBldGVyJ3MgQworICAgICAqIGltcGxlbWVudGF0aW9uLCBidXQgMzIgd2FzIGVtcGlyaWNhbGx5IGRldGVybWluZWQgdG8gd29yayBiZXR0ZXIgaW4KKyAgICAgKiB0aGlzIGltcGxlbWVudGF0aW9uLiAgSW4gdGhlIHVubGlrZWx5IGV2ZW50IHRoYXQgeW91IHNldCB0aGlzIGNvbnN0YW50CisgICAgICogdG8gYmUgYSBudW1iZXIgdGhhdCdzIG5vdCBhIHBvd2VyIG9mIHR3bywgeW91J2xsIG5lZWQgdG8gY2hhbmdlIHRoZQorICAgICAqIHtAbGluayAjbWluUnVuTGVuZ3RofSBjb21wdXRhdGlvbi4KKyAgICAgKgorICAgICAqIElmIHlvdSBkZWNyZWFzZSB0aGlzIGNvbnN0YW50LCB5b3UgbXVzdCBjaGFuZ2UgdGhlIHN0YWNrTGVuCisgICAgICogY29tcHV0YXRpb24gaW4gdGhlIFRpbVNvcnQgY29uc3RydWN0b3IsIG9yIHlvdSByaXNrIGFuCisgICAgICogQXJyYXlPdXRPZkJvdW5kcyBleGNlcHRpb24uICBTZWUgbGlzdHNvcnQudHh0IGZvciBhIGRpc2N1c3Npb24KKyAgICAgKiBvZiB0aGUgbWluaW11bSBzdGFjayBsZW5ndGggcmVxdWlyZWQgYXMgYSBmdW5jdGlvbiBvZiB0aGUgbGVuZ3RoCisgICAgICogb2YgdGhlIGFycmF5IGJlaW5nIHNvcnRlZCBhbmQgdGhlIG1pbmltdW0gbWVyZ2Ugc2VxdWVuY2UgbGVuZ3RoLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNSU5fTUVSR0UgPSAzMjsKKworICAgIC8qKgorICAgICAqIFRoZSBhcnJheSBiZWluZyBzb3J0ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBUW10gYTsKKworICAgIC8qKgorICAgICAqIFRoZSBjb21wYXJhdG9yIGZvciB0aGlzIHNvcnQuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBDb21wYXJhdG9yPD8gc3VwZXIgVD4gYzsKKworICAgIC8qKgorICAgICAqIFdoZW4gd2UgZ2V0IGludG8gZ2FsbG9waW5nIG1vZGUsIHdlIHN0YXkgdGhlcmUgdW50aWwgYm90aCBydW5zIHdpbiBsZXNzCisgICAgICogb2Z0ZW4gdGhhbiBNSU5fR0FMTE9QIGNvbnNlY3V0aXZlIHRpbWVzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCAgTUlOX0dBTExPUCA9IDc7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNvbnRyb2xzIHdoZW4gd2UgZ2V0ICppbnRvKiBnYWxsb3BpbmcgbW9kZS4gIEl0IGlzIGluaXRpYWxpemVkCisgICAgICogdG8gTUlOX0dBTExPUC4gIFRoZSBtZXJnZUxvIGFuZCBtZXJnZUhpIG1ldGhvZHMgbnVkZ2UgaXQgaGlnaGVyIGZvcgorICAgICAqIHJhbmRvbSBkYXRhLCBhbmQgbG93ZXIgZm9yIGhpZ2hseSBzdHJ1Y3R1cmVkIGRhdGEuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbWluR2FsbG9wID0gTUlOX0dBTExPUDsKKworICAgIC8qKgorICAgICAqIE1heGltdW0gaW5pdGlhbCBzaXplIG9mIHRtcCBhcnJheSwgd2hpY2ggaXMgdXNlZCBmb3IgbWVyZ2luZy4gIFRoZSBhcnJheQorICAgICAqIGNhbiBncm93IHRvIGFjY29tbW9kYXRlIGRlbWFuZC4KKyAgICAgKgorICAgICAqIFVubGlrZSBUaW0ncyBvcmlnaW5hbCBDIHZlcnNpb24sIHdlIGRvIG5vdCBhbGxvY2F0ZSB0aGlzIG11Y2ggc3RvcmFnZQorICAgICAqIHdoZW4gc29ydGluZyBzbWFsbGVyIGFycmF5cy4gIFRoaXMgY2hhbmdlIHdhcyByZXF1aXJlZCBmb3IgcGVyZm9ybWFuY2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOSVRJQUxfVE1QX1NUT1JBR0VfTEVOR1RIID0gMjU2OworCisgICAgLyoqCisgICAgICogVGVtcCBzdG9yYWdlIGZvciBtZXJnZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBUW10gdG1wOyAvLyBBY3R1YWwgcnVudGltZSB0eXBlIHdpbGwgYmUgT2JqZWN0W10sIHJlZ2FyZGxlc3Mgb2YgVAorCisgICAgLyoqCisgICAgICogQSBzdGFjayBvZiBwZW5kaW5nIHJ1bnMgeWV0IHRvIGJlIG1lcmdlZC4gIFJ1biBpIHN0YXJ0cyBhdAorICAgICAqIGFkZHJlc3MgYmFzZVtpXSBhbmQgZXh0ZW5kcyBmb3IgbGVuW2ldIGVsZW1lbnRzLiAgSXQncyBhbHdheXMKKyAgICAgKiB0cnVlIChzbyBsb25nIGFzIHRoZSBpbmRpY2VzIGFyZSBpbiBib3VuZHMpIHRoYXQ6CisgICAgICoKKyAgICAgKiAgICAgcnVuQmFzZVtpXSArIHJ1bkxlbltpXSA9PSBydW5CYXNlW2kgKyAxXQorICAgICAqCisgICAgICogc28gd2UgY291bGQgY3V0IHRoZSBzdG9yYWdlIGZvciB0aGlzLCBidXQgaXQncyBhIG1pbm9yIGFtb3VudCwKKyAgICAgKiBhbmQga2VlcGluZyBhbGwgdGhlIGluZm8gZXhwbGljaXQgc2ltcGxpZmllcyB0aGUgY29kZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBzdGFja1NpemUgPSAwOyAgLy8gTnVtYmVyIG9mIHBlbmRpbmcgcnVucyBvbiBzdGFjaworICAgIHByaXZhdGUgZmluYWwgaW50W10gcnVuQmFzZTsKKyAgICBwcml2YXRlIGZpbmFsIGludFtdIHJ1bkxlbjsKKworICAgIC8qKgorICAgICAqIEFzc2VydHMgaGF2ZSBiZWVuIHBsYWNlZCBpbiBpZi1zdGF0ZW1lbnRzIGZvciBwZXJmb3JtYWNlLiBUbyBlbmFibGUgdGhlbSwKKyAgICAgKiBzZXQgdGhpcyBmaWVsZCB0byB0cnVlIGFuZCBlbmFibGUgdGhlbSBpbiBWTSB3aXRoIGEgY29tbWFuZCBsaW5lIGZsYWcuCisgICAgICogSWYgeW91IG1vZGlmeSB0aGlzIGNsYXNzLCBwbGVhc2UgZG8gdGVzdCB0aGUgYXNzZXJ0cyEKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgVGltU29ydCBpbnN0YW5jZSB0byBtYWludGFpbiB0aGUgc3RhdGUgb2YgYW4gb25nb2luZyBzb3J0LgorICAgICAqCisgICAgICogQHBhcmFtIGEgdGhlIGFycmF5IHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSBjIHRoZSBjb21wYXJhdG9yIHRvIGRldGVybWluZSB0aGUgb3JkZXIgb2YgdGhlIHNvcnQKKyAgICAgKi8KKyAgICBwcml2YXRlIFRpbVNvcnQoVFtdIGEsIENvbXBhcmF0b3I8PyBzdXBlciBUPiBjKSB7CisgICAgICAgIHRoaXMuYSA9IGE7CisgICAgICAgIHRoaXMuYyA9IGM7CisKKyAgICAgICAgLy8gQWxsb2NhdGUgdGVtcCBzdG9yYWdlICh3aGljaCBtYXkgYmUgaW5jcmVhc2VkIGxhdGVyIGlmIG5lY2Vzc2FyeSkKKyAgICAgICAgaW50IGxlbiA9IGEubGVuZ3RoOworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVuY2hlY2tlZCIsICJVbm5lY2Vzc2FyeUxvY2FsVmFyaWFibGUifSkKKyAgICAgICAgVFtdIG5ld0FycmF5ID0gKFRbXSkgbmV3IE9iamVjdFtsZW4gPCAyICogSU5JVElBTF9UTVBfU1RPUkFHRV9MRU5HVEggPworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbiA+Pj4gMSA6IElOSVRJQUxfVE1QX1NUT1JBR0VfTEVOR1RIXTsKKyAgICAgICAgdG1wID0gbmV3QXJyYXk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogQWxsb2NhdGUgcnVucy10by1iZS1tZXJnZWQgc3RhY2sgKHdoaWNoIGNhbm5vdCBiZSBleHBhbmRlZCkuICBUaGUKKyAgICAgICAgICogc3RhY2sgbGVuZ3RoIHJlcXVpcmVtZW50cyBhcmUgZGVzY3JpYmVkIGluIGxpc3Rzb3J0LnR4dC4gIFRoZSBDCisgICAgICAgICAqIHZlcnNpb24gYWx3YXlzIHVzZXMgdGhlIHNhbWUgc3RhY2sgbGVuZ3RoICg4NSksIGJ1dCB0aGlzIHdhcworICAgICAgICAgKiBtZWFzdXJlZCB0byBiZSB0b28gZXhwZW5zaXZlIHdoZW4gc29ydGluZyAibWlkLXNpemVkIiBhcnJheXMgKGUuZy4sCisgICAgICAgICAqIDEwMCBlbGVtZW50cykgaW4gSmF2YS4gIFRoZXJlZm9yZSwgd2UgdXNlIHNtYWxsZXIgKGJ1dCBzdWZmaWNpZW50bHkKKyAgICAgICAgICogbGFyZ2UpIHN0YWNrIGxlbmd0aHMgZm9yIHNtYWxsZXIgYXJyYXlzLiAgVGhlICJtYWdpYyBudW1iZXJzIiBpbiB0aGUKKyAgICAgICAgICogY29tcHV0YXRpb24gYmVsb3cgbXVzdCBiZSBjaGFuZ2VkIGlmIE1JTl9NRVJHRSBpcyBkZWNyZWFzZWQuICBTZWUKKyAgICAgICAgICogdGhlIE1JTl9NRVJHRSBkZWNsYXJhdGlvbiBhYm92ZSBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KKyAgICAgICAgICovCisgICAgICAgIGludCBzdGFja0xlbiA9IChsZW4gPCAgICAxMjAgID8gIDUgOgorICAgICAgICAgICAgICAgICAgICAgICAgbGVuIDwgICAxNTQyICA/IDEwIDoKKyAgICAgICAgICAgICAgICAgICAgICAgIGxlbiA8IDExOTE1MSAgPyAxOSA6IDQwKTsKKyAgICAgICAgcnVuQmFzZSA9IG5ldyBpbnRbc3RhY2tMZW5dOworICAgICAgICBydW5MZW4gPSBuZXcgaW50W3N0YWNrTGVuXTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFRoZSBuZXh0IHR3byBtZXRob2RzICh3aGljaCBhcmUgcGFja2FnZSBwcml2YXRlIGFuZCBzdGF0aWMpIGNvbnN0aXR1dGUKKyAgICAgKiB0aGUgZW50aXJlIEFQSSBvZiB0aGlzIGNsYXNzLiAgRWFjaCBvZiB0aGVzZSBtZXRob2RzIG9iZXlzIHRoZSBjb250cmFjdAorICAgICAqIG9mIHRoZSBwdWJsaWMgbWV0aG9kIHdpdGggdGhlIHNhbWUgc2lnbmF0dXJlIGluIGphdmEudXRpbC5BcnJheXMuCisgICAgICovCisKKyAgICBzdGF0aWMgPFQ+IHZvaWQgc29ydChUW10gYSwgQ29tcGFyYXRvcjw/IHN1cGVyIFQ+IGMpIHsKKyAgICAgICAgc29ydChhLCAwLCBhLmxlbmd0aCwgYyk7CisgICAgfQorCisgICAgc3RhdGljIDxUPiB2b2lkIHNvcnQoVFtdIGEsIGludCBsbywgaW50IGhpLCBDb21wYXJhdG9yPD8gc3VwZXIgVD4gYykgeworICAgICAgICBpZiAoYyA9PSBudWxsKSB7CisgICAgICAgICAgICBBcnJheXMuc29ydChhLCBsbywgaGkpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgQXJyYXlzLmNoZWNrU3RhcnRBbmRFbmQoYS5sZW5ndGgsIGxvLCBoaSk7CisgICAgICAgIGludCBuUmVtYWluaW5nICA9IGhpIC0gbG87CisgICAgICAgIGlmIChuUmVtYWluaW5nIDwgMikKKyAgICAgICAgICAgIHJldHVybjsgIC8vIEFycmF5cyBvZiBzaXplIDAgYW5kIDEgYXJlIGFsd2F5cyBzb3J0ZWQKKworICAgICAgICAvLyBJZiBhcnJheSBpcyBzbWFsbCwgZG8gYSAibWluaS1UaW1Tb3J0IiB3aXRoIG5vIG1lcmdlcworICAgICAgICBpZiAoblJlbWFpbmluZyA8IE1JTl9NRVJHRSkgeworICAgICAgICAgICAgaW50IGluaXRSdW5MZW4gPSBjb3VudFJ1bkFuZE1ha2VBc2NlbmRpbmcoYSwgbG8sIGhpLCBjKTsKKyAgICAgICAgICAgIGJpbmFyeVNvcnQoYSwgbG8sIGhpLCBsbyArIGluaXRSdW5MZW4sIGMpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE1hcmNoIG92ZXIgdGhlIGFycmF5IG9uY2UsIGxlZnQgdG8gcmlnaHQsIGZpbmRpbmcgbmF0dXJhbCBydW5zLAorICAgICAgICAgKiBleHRlbmRpbmcgc2hvcnQgbmF0dXJhbCBydW5zIHRvIG1pblJ1biBlbGVtZW50cywgYW5kIG1lcmdpbmcgcnVucworICAgICAgICAgKiB0byBtYWludGFpbiBzdGFjayBpbnZhcmlhbnQuCisgICAgICAgICAqLworICAgICAgICBUaW1Tb3J0PFQ+IHRzID0gbmV3IFRpbVNvcnQ8VD4oYSwgYyk7CisgICAgICAgIGludCBtaW5SdW4gPSBtaW5SdW5MZW5ndGgoblJlbWFpbmluZyk7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIC8vIElkZW50aWZ5IG5leHQgcnVuCisgICAgICAgICAgICBpbnQgcnVuTGVuID0gY291bnRSdW5BbmRNYWtlQXNjZW5kaW5nKGEsIGxvLCBoaSwgYyk7CisKKyAgICAgICAgICAgIC8vIElmIHJ1biBpcyBzaG9ydCwgZXh0ZW5kIHRvIG1pbihtaW5SdW4sIG5SZW1haW5pbmcpCisgICAgICAgICAgICBpZiAocnVuTGVuIDwgbWluUnVuKSB7CisgICAgICAgICAgICAgICAgaW50IGZvcmNlID0gblJlbWFpbmluZyA8PSBtaW5SdW4gPyBuUmVtYWluaW5nIDogbWluUnVuOworICAgICAgICAgICAgICAgIGJpbmFyeVNvcnQoYSwgbG8sIGxvICsgZm9yY2UsIGxvICsgcnVuTGVuLCBjKTsKKyAgICAgICAgICAgICAgICBydW5MZW4gPSBmb3JjZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gUHVzaCBydW4gb250byBwZW5kaW5nLXJ1biBzdGFjaywgYW5kIG1heWJlIG1lcmdlCisgICAgICAgICAgICB0cy5wdXNoUnVuKGxvLCBydW5MZW4pOworICAgICAgICAgICAgdHMubWVyZ2VDb2xsYXBzZSgpOworCisgICAgICAgICAgICAvLyBBZHZhbmNlIHRvIGZpbmQgbmV4dCBydW4KKyAgICAgICAgICAgIGxvICs9IHJ1bkxlbjsKKyAgICAgICAgICAgIG5SZW1haW5pbmcgLT0gcnVuTGVuOworICAgICAgICB9IHdoaWxlIChuUmVtYWluaW5nICE9IDApOworCisgICAgICAgIC8vIE1lcmdlIGFsbCByZW1haW5pbmcgcnVucyB0byBjb21wbGV0ZSBzb3J0CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxvID09IGhpOworICAgICAgICB0cy5tZXJnZUZvcmNlQ29sbGFwc2UoKTsKKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgdHMuc3RhY2tTaXplID09IDE7CisgICAgfQorCisgICAgLyoqCisgICAgICogU29ydHMgdGhlIHNwZWNpZmllZCBwb3J0aW9uIG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkgdXNpbmcgYSBiaW5hcnkKKyAgICAgKiBpbnNlcnRpb24gc29ydC4gIFRoaXMgaXMgdGhlIGJlc3QgbWV0aG9kIGZvciBzb3J0aW5nIHNtYWxsIG51bWJlcnMKKyAgICAgKiBvZiBlbGVtZW50cy4gIEl0IHJlcXVpcmVzIE8obiBsb2cgbikgY29tcGFyZXMsIGJ1dCBPKG5eMikgZGF0YQorICAgICAqIG1vdmVtZW50ICh3b3JzdCBjYXNlKS4KKyAgICAgKgorICAgICAqIElmIHRoZSBpbml0aWFsIHBhcnQgb2YgdGhlIHNwZWNpZmllZCByYW5nZSBpcyBhbHJlYWR5IHNvcnRlZCwKKyAgICAgKiB0aGlzIG1ldGhvZCBjYW4gdGFrZSBhZHZhbnRhZ2Ugb2YgaXQ6IHRoZSBtZXRob2QgYXNzdW1lcyB0aGF0IHRoZQorICAgICAqIGVsZW1lbnRzIGZyb20gaW5kZXgge0Bjb2RlIGxvfSwgaW5jbHVzaXZlLCB0byB7QGNvZGUgc3RhcnR9LAorICAgICAqIGV4Y2x1c2l2ZSBhcmUgYWxyZWFkeSBzb3J0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgaW4gd2hpY2ggYSByYW5nZSBpcyB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gbG8gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50IGluIHRoZSByYW5nZSB0byBiZSBzb3J0ZWQKKyAgICAgKiBAcGFyYW0gaGkgdGhlIGluZGV4IGFmdGVyIHRoZSBsYXN0IGVsZW1lbnQgaW4gdGhlIHJhbmdlIHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSBzdGFydCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIHJhbmdlIHRoYXQgaXMKKyAgICAgKiAgICAgICAgbm90IGFscmVhZHkga25vd24gdG8gYmUgc29ydGVkIChAY29kZSBsbyA8PSBzdGFydCA8PSBoaX0KKyAgICAgKiBAcGFyYW0gYyBjb21wYXJhdG9yIHRvIHVzZWQgZm9yIHRoZSBzb3J0CisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImZhbGx0aHJvdWdoIikKKyAgICBwcml2YXRlIHN0YXRpYyA8VD4gdm9pZCBiaW5hcnlTb3J0KFRbXSBhLCBpbnQgbG8sIGludCBoaSwgaW50IHN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29tcGFyYXRvcjw/IHN1cGVyIFQ+IGMpIHsKKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbG8gPD0gc3RhcnQgJiYgc3RhcnQgPD0gaGk7CisgICAgICAgIGlmIChzdGFydCA9PSBsbykKKyAgICAgICAgICAgIHN0YXJ0Kys7CisgICAgICAgIGZvciAoIDsgc3RhcnQgPCBoaTsgc3RhcnQrKykgeworICAgICAgICAgICAgVCBwaXZvdCA9IGFbc3RhcnRdOworCisgICAgICAgICAgICAvLyBTZXQgbGVmdCAoYW5kIHJpZ2h0KSB0byB0aGUgaW5kZXggd2hlcmUgYVtzdGFydF0gKHBpdm90KSBiZWxvbmdzCisgICAgICAgICAgICBpbnQgbGVmdCA9IGxvOworICAgICAgICAgICAgaW50IHJpZ2h0ID0gc3RhcnQ7CisgICAgICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBsZWZ0IDw9IHJpZ2h0OworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIEludmFyaWFudHM6CisgICAgICAgICAgICAgKiAgIHBpdm90ID49IGFsbCBpbiBbbG8sIGxlZnQpLgorICAgICAgICAgICAgICogICBwaXZvdCA8ICBhbGwgaW4gW3JpZ2h0LCBzdGFydCkuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHdoaWxlIChsZWZ0IDwgcmlnaHQpIHsKKyAgICAgICAgICAgICAgICBpbnQgbWlkID0gKGxlZnQgKyByaWdodCkgPj4+IDE7CisgICAgICAgICAgICAgICAgaWYgKGMuY29tcGFyZShwaXZvdCwgYVttaWRdKSA8IDApCisgICAgICAgICAgICAgICAgICAgIHJpZ2h0ID0gbWlkOworICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgbGVmdCA9IG1pZCArIDE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBsZWZ0ID09IHJpZ2h0OworCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogVGhlIGludmFyaWFudHMgc3RpbGwgaG9sZDogcGl2b3QgPj0gYWxsIGluIFtsbywgbGVmdCkgYW5kCisgICAgICAgICAgICAgKiBwaXZvdCA8IGFsbCBpbiBbbGVmdCwgc3RhcnQpLCBzbyBwaXZvdCBiZWxvbmdzIGF0IGxlZnQuICBOb3RlCisgICAgICAgICAgICAgKiB0aGF0IGlmIHRoZXJlIGFyZSBlbGVtZW50cyBlcXVhbCB0byBwaXZvdCwgbGVmdCBwb2ludHMgdG8gdGhlCisgICAgICAgICAgICAgKiBmaXJzdCBzbG90IGFmdGVyIHRoZW0gLS0gdGhhdCdzIHdoeSB0aGlzIHNvcnQgaXMgc3RhYmxlLgorICAgICAgICAgICAgICogU2xpZGUgZWxlbWVudHMgb3ZlciB0byBtYWtlIHJvb20gZm9yIHBpdm90LgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpbnQgbiA9IHN0YXJ0IC0gbGVmdDsgIC8vIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gbW92ZQorICAgICAgICAgICAgLy8gU3dpdGNoIGlzIGp1c3QgYW4gb3B0aW1pemF0aW9uIGZvciBhcnJheWNvcHkgaW4gZGVmYXVsdCBjYXNlCisgICAgICAgICAgICBzd2l0Y2gobikgeworICAgICAgICAgICAgICAgIGNhc2UgMjogIGFbbGVmdCArIDJdID0gYVtsZWZ0ICsgMV07CisgICAgICAgICAgICAgICAgY2FzZSAxOiAgYVtsZWZ0ICsgMV0gPSBhW2xlZnRdOworICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGRlZmF1bHQ6IFN5c3RlbS5hcnJheWNvcHkoYSwgbGVmdCwgYSwgbGVmdCArIDEsIG4pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYVtsZWZ0XSA9IHBpdm90OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBydW4gYmVnaW5uaW5nIGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gaW4KKyAgICAgKiB0aGUgc3BlY2lmaWVkIGFycmF5IGFuZCByZXZlcnNlcyB0aGUgcnVuIGlmIGl0IGlzIGRlc2NlbmRpbmcgKGVuc3VyaW5nCisgICAgICogdGhhdCB0aGUgcnVuIHdpbGwgYWx3YXlzIGJlIGFzY2VuZGluZyB3aGVuIHRoZSBtZXRob2QgcmV0dXJucykuCisgICAgICoKKyAgICAgKiBBIHJ1biBpcyB0aGUgbG9uZ2VzdCBhc2NlbmRpbmcgc2VxdWVuY2Ugd2l0aDoKKyAgICAgKgorICAgICAqICAgIGFbbG9dIDw9IGFbbG8gKyAxXSA8PSBhW2xvICsgMl0gPD0gLi4uCisgICAgICoKKyAgICAgKiBvciB0aGUgbG9uZ2VzdCBkZXNjZW5kaW5nIHNlcXVlbmNlIHdpdGg6CisgICAgICoKKyAgICAgKiAgICBhW2xvXSA+ICBhW2xvICsgMV0gPiAgYVtsbyArIDJdID4gIC4uLgorICAgICAqCisgICAgICogRm9yIGl0cyBpbnRlbmRlZCB1c2UgaW4gYSBzdGFibGUgbWVyZ2Vzb3J0LCB0aGUgc3RyaWN0bmVzcyBvZiB0aGUKKyAgICAgKiBkZWZpbml0aW9uIG9mICJkZXNjZW5kaW5nIiBpcyBuZWVkZWQgc28gdGhhdCB0aGUgY2FsbCBjYW4gc2FmZWx5CisgICAgICogcmV2ZXJzZSBhIGRlc2NlbmRpbmcgc2VxdWVuY2Ugd2l0aG91dCB2aW9sYXRpbmcgc3RhYmlsaXR5LgorICAgICAqCisgICAgICogQHBhcmFtIGEgdGhlIGFycmF5IGluIHdoaWNoIGEgcnVuIGlzIHRvIGJlIGNvdW50ZWQgYW5kIHBvc3NpYmx5IHJldmVyc2VkCisgICAgICogQHBhcmFtIGxvIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50IGluIHRoZSBydW4KKyAgICAgKiBAcGFyYW0gaGkgaW5kZXggYWZ0ZXIgdGhlIGxhc3QgZWxlbWVudCB0aGF0IG1heSBiZSBjb250YWluZWQgaW4gdGhlIHJ1bi4KKyAgICAgICAgICAgICAgSXQgaXMgcmVxdWlyZWQgdGhhdCBAY29kZXtsbyA8IGhpfS4KKyAgICAgKiBAcGFyYW0gYyB0aGUgY29tcGFyYXRvciB0byB1c2VkIGZvciB0aGUgc29ydAorICAgICAqIEByZXR1cm4gIHRoZSBsZW5ndGggb2YgdGhlIHJ1biBiZWdpbm5pbmcgYXQgdGhlIHNwZWNpZmllZCBwb3NpdGlvbiBpbgorICAgICAqICAgICAgICAgIHRoZSBzcGVjaWZpZWQgYXJyYXkKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyA8VD4gaW50IGNvdW50UnVuQW5kTWFrZUFzY2VuZGluZyhUW10gYSwgaW50IGxvLCBpbnQgaGksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29tcGFyYXRvcjw/IHN1cGVyIFQ+IGMpIHsKKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbG8gPCBoaTsKKyAgICAgICAgaW50IHJ1bkhpID0gbG8gKyAxOworICAgICAgICBpZiAocnVuSGkgPT0gaGkpCisgICAgICAgICAgICByZXR1cm4gMTsKKworICAgICAgICAvLyBGaW5kIGVuZCBvZiBydW4sIGFuZCByZXZlcnNlIHJhbmdlIGlmIGRlc2NlbmRpbmcKKyAgICAgICAgaWYgKGMuY29tcGFyZShhW3J1bkhpKytdLCBhW2xvXSkgPCAwKSB7IC8vIERlc2NlbmRpbmcKKyAgICAgICAgICAgIHdoaWxlKHJ1bkhpIDwgaGkgJiYgYy5jb21wYXJlKGFbcnVuSGldLCBhW3J1bkhpIC0gMV0pIDwgMCkKKyAgICAgICAgICAgICAgICBydW5IaSsrOworICAgICAgICAgICAgcmV2ZXJzZVJhbmdlKGEsIGxvLCBydW5IaSk7CisgICAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXNjZW5kaW5nCisgICAgICAgICAgICB3aGlsZSAocnVuSGkgPCBoaSAmJiBjLmNvbXBhcmUoYVtydW5IaV0sIGFbcnVuSGkgLSAxXSkgPj0gMCkKKyAgICAgICAgICAgICAgICBydW5IaSsrOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHJ1bkhpIC0gbG87CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV2ZXJzZSB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgaW4gd2hpY2ggYSByYW5nZSBpcyB0byBiZSByZXZlcnNlZAorICAgICAqIEBwYXJhbSBsbyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIHJhbmdlIHRvIGJlIHJldmVyc2VkCisgICAgICogQHBhcmFtIGhpIHRoZSBpbmRleCBhZnRlciB0aGUgbGFzdCBlbGVtZW50IGluIHRoZSByYW5nZSB0byBiZSByZXZlcnNlZAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcmV2ZXJzZVJhbmdlKE9iamVjdFtdIGEsIGludCBsbywgaW50IGhpKSB7CisgICAgICAgIGhpLS07CisgICAgICAgIHdoaWxlIChsbyA8IGhpKSB7CisgICAgICAgICAgICBPYmplY3QgdCA9IGFbbG9dOworICAgICAgICAgICAgYVtsbysrXSA9IGFbaGldOworICAgICAgICAgICAgYVtoaS0tXSA9IHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtaW5pbXVtIGFjY2VwdGFibGUgcnVuIGxlbmd0aCBmb3IgYW4gYXJyYXkgb2YgdGhlIHNwZWNpZmllZAorICAgICAqIGxlbmd0aC4gTmF0dXJhbCBydW5zIHNob3J0ZXIgdGhhbiB0aGlzIHdpbGwgYmUgZXh0ZW5kZWQgd2l0aAorICAgICAqIHtAbGluayAjYmluYXJ5U29ydH0uCisgICAgICoKKyAgICAgKiBSb3VnaGx5IHNwZWFraW5nLCB0aGUgY29tcHV0YXRpb24gaXM6CisgICAgICoKKyAgICAgKiAgSWYgbiA8IE1JTl9NRVJHRSwgcmV0dXJuIG4gKGl0J3MgdG9vIHNtYWxsIHRvIGJvdGhlciB3aXRoIGZhbmN5IHN0dWZmKS4KKyAgICAgKiAgRWxzZSBpZiBuIGlzIGFuIGV4YWN0IHBvd2VyIG9mIDIsIHJldHVybiBNSU5fTUVSR0UvMi4KKyAgICAgKiAgRWxzZSByZXR1cm4gYW4gaW50IGssIE1JTl9NRVJHRS8yIDw9IGsgPD0gTUlOX01FUkdFLCBzdWNoIHRoYXQgbi9rCisgICAgICogICBpcyBjbG9zZSB0bywgYnV0IHN0cmljdGx5IGxlc3MgdGhhbiwgYW4gZXhhY3QgcG93ZXIgb2YgMi4KKyAgICAgKgorICAgICAqIEZvciB0aGUgcmF0aW9uYWxlLCBzZWUgbGlzdHNvcnQudHh0LgorICAgICAqCisgICAgICogQHBhcmFtIG4gdGhlIGxlbmd0aCBvZiB0aGUgYXJyYXkgdG8gYmUgc29ydGVkCisgICAgICogQHJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSBtaW5pbXVtIHJ1biB0byBiZSBtZXJnZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgbWluUnVuTGVuZ3RoKGludCBuKSB7CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IG4gPj0gMDsKKyAgICAgICAgaW50IHIgPSAwOyAgICAgIC8vIEJlY29tZXMgMSBpZiBhbnkgMSBiaXRzIGFyZSBzaGlmdGVkIG9mZgorICAgICAgICB3aGlsZSAobiA+PSBNSU5fTUVSR0UpIHsKKyAgICAgICAgICAgIHIgfD0gKG4gJiAxKTsKKyAgICAgICAgICAgIG4gPj49IDE7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG4gKyByOworICAgIH0KKworICAgIC8qKgorICAgICAqIFB1c2hlcyB0aGUgc3BlY2lmaWVkIHJ1biBvbnRvIHRoZSBwZW5kaW5nLXJ1biBzdGFjay4KKyAgICAgKgorICAgICAqIEBwYXJhbSBydW5CYXNlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50IGluIHRoZSBydW4KKyAgICAgKiBAcGFyYW0gcnVuTGVuICB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBydW4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcHVzaFJ1bihpbnQgcnVuQmFzZSwgaW50IHJ1bkxlbikgeworICAgICAgICB0aGlzLnJ1bkJhc2Vbc3RhY2tTaXplXSA9IHJ1bkJhc2U7CisgICAgICAgIHRoaXMucnVuTGVuW3N0YWNrU2l6ZV0gPSBydW5MZW47CisgICAgICAgIHN0YWNrU2l6ZSsrOworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4YW1pbmVzIHRoZSBzdGFjayBvZiBydW5zIHdhaXRpbmcgdG8gYmUgbWVyZ2VkIGFuZCBtZXJnZXMgYWRqYWNlbnQgcnVucworICAgICAqIHVudGlsIHRoZSBzdGFjayBpbnZhcmlhbnRzIGFyZSByZWVzdGFibGlzaGVkOgorICAgICAqCisgICAgICogICAgIDEuIHJ1bkxlbltpIC0gM10gPiBydW5MZW5baSAtIDJdICsgcnVuTGVuW2kgLSAxXQorICAgICAqICAgICAyLiBydW5MZW5baSAtIDJdID4gcnVuTGVuW2kgLSAxXQorICAgICAqCisgICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGVhY2ggdGltZSBhIG5ldyBydW4gaXMgcHVzaGVkIG9udG8gdGhlIHN0YWNrLAorICAgICAqIHNvIHRoZSBpbnZhcmlhbnRzIGFyZSBndWFyYW50ZWVkIHRvIGhvbGQgZm9yIGkgPCBzdGFja1NpemUgdXBvbgorICAgICAqIGVudHJ5IHRvIHRoZSBtZXRob2QuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIG1lcmdlQ29sbGFwc2UoKSB7CisgICAgICAgIHdoaWxlIChzdGFja1NpemUgPiAxKSB7CisgICAgICAgICAgICBpbnQgbiA9IHN0YWNrU2l6ZSAtIDI7CisgICAgICAgICAgICBpZiAobiA+IDAgJiYgcnVuTGVuW24tMV0gPD0gcnVuTGVuW25dICsgcnVuTGVuW24rMV0pIHsKKyAgICAgICAgICAgICAgICBpZiAocnVuTGVuW24gLSAxXSA8IHJ1bkxlbltuICsgMV0pCisgICAgICAgICAgICAgICAgICAgIG4tLTsKKyAgICAgICAgICAgICAgICBtZXJnZUF0KG4pOworICAgICAgICAgICAgfSBlbHNlIGlmIChydW5MZW5bbl0gPD0gcnVuTGVuW24gKyAxXSkgeworICAgICAgICAgICAgICAgIG1lcmdlQXQobik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJyZWFrOyAvLyBJbnZhcmlhbnQgaXMgZXN0YWJsaXNoZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIE1lcmdlcyBhbGwgcnVucyBvbiB0aGUgc3RhY2sgdW50aWwgb25seSBvbmUgcmVtYWlucy4gIFRoaXMgbWV0aG9kIGlzCisgICAgICogY2FsbGVkIG9uY2UsIHRvIGNvbXBsZXRlIHRoZSBzb3J0LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBtZXJnZUZvcmNlQ29sbGFwc2UoKSB7CisgICAgICAgIHdoaWxlIChzdGFja1NpemUgPiAxKSB7CisgICAgICAgICAgICBpbnQgbiA9IHN0YWNrU2l6ZSAtIDI7CisgICAgICAgICAgICBpZiAobiA+IDAgJiYgcnVuTGVuW24gLSAxXSA8IHJ1bkxlbltuICsgMV0pCisgICAgICAgICAgICAgICAgbi0tOworICAgICAgICAgICAgbWVyZ2VBdChuKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIE1lcmdlcyB0aGUgdHdvIHJ1bnMgYXQgc3RhY2sgaW5kaWNlcyBpIGFuZCBpKzEuICBSdW4gaSBtdXN0IGJlCisgICAgICogdGhlIHBlbnVsdGltYXRlIG9yIGFudGVwZW51bHRpbWF0ZSBydW4gb24gdGhlIHN0YWNrLiAgSW4gb3RoZXIgd29yZHMsCisgICAgICogaSBtdXN0IGJlIGVxdWFsIHRvIHN0YWNrU2l6ZS0yIG9yIHN0YWNrU2l6ZS0zLgorICAgICAqCisgICAgICogQHBhcmFtIGkgc3RhY2sgaW5kZXggb2YgdGhlIGZpcnN0IG9mIHRoZSB0d28gcnVucyB0byBtZXJnZQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBtZXJnZUF0KGludCBpKSB7CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IHN0YWNrU2l6ZSA+PSAyOworICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBpID49IDA7CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGkgPT0gc3RhY2tTaXplIC0gMiB8fCBpID09IHN0YWNrU2l6ZSAtIDM7CisKKyAgICAgICAgaW50IGJhc2UxID0gcnVuQmFzZVtpXTsKKyAgICAgICAgaW50IGxlbjEgPSBydW5MZW5baV07CisgICAgICAgIGludCBiYXNlMiA9IHJ1bkJhc2VbaSArIDFdOworICAgICAgICBpbnQgbGVuMiA9IHJ1bkxlbltpICsgMV07CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxlbjEgPiAwICYmIGxlbjIgPiAwOworICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBiYXNlMSArIGxlbjEgPT0gYmFzZTI7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogUmVjb3JkIHRoZSBsZW5ndGggb2YgdGhlIGNvbWJpbmVkIHJ1bnM7IGlmIGkgaXMgdGhlIDNyZC1sYXN0CisgICAgICAgICAqIHJ1biBub3csIGFsc28gc2xpZGUgb3ZlciB0aGUgbGFzdCBydW4gKHdoaWNoIGlzbid0IGludm9sdmVkCisgICAgICAgICAqIGluIHRoaXMgbWVyZ2UpLiAgVGhlIGN1cnJlbnQgcnVuIChpKzEpIGdvZXMgYXdheSBpbiBhbnkgY2FzZS4KKyAgICAgICAgICovCisgICAgICAgIHJ1bkxlbltpXSA9IGxlbjEgKyBsZW4yOworICAgICAgICBpZiAoaSA9PSBzdGFja1NpemUgLSAzKSB7CisgICAgICAgICAgICBydW5CYXNlW2kgKyAxXSA9IHJ1bkJhc2VbaSArIDJdOworICAgICAgICAgICAgcnVuTGVuW2kgKyAxXSA9IHJ1bkxlbltpICsgMl07CisgICAgICAgIH0KKyAgICAgICAgc3RhY2tTaXplLS07CisKKyAgICAgICAgLyoKKyAgICAgICAgICogRmluZCB3aGVyZSB0aGUgZmlyc3QgZWxlbWVudCBvZiBydW4yIGdvZXMgaW4gcnVuMS4gUHJpb3IgZWxlbWVudHMKKyAgICAgICAgICogaW4gcnVuMSBjYW4gYmUgaWdub3JlZCAoYmVjYXVzZSB0aGV5J3JlIGFscmVhZHkgaW4gcGxhY2UpLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IGsgPSBnYWxsb3BSaWdodChhW2Jhc2UyXSwgYSwgYmFzZTEsIGxlbjEsIDAsIGMpOworICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBrID49IDA7CisgICAgICAgIGJhc2UxICs9IGs7CisgICAgICAgIGxlbjEgLT0gazsKKyAgICAgICAgaWYgKGxlbjEgPT0gMCkKKyAgICAgICAgICAgIHJldHVybjsKKworICAgICAgICAvKgorICAgICAgICAgKiBGaW5kIHdoZXJlIHRoZSBsYXN0IGVsZW1lbnQgb2YgcnVuMSBnb2VzIGluIHJ1bjIuIFN1YnNlcXVlbnQgZWxlbWVudHMKKyAgICAgICAgICogaW4gcnVuMiBjYW4gYmUgaWdub3JlZCAoYmVjYXVzZSB0aGV5J3JlIGFscmVhZHkgaW4gcGxhY2UpLgorICAgICAgICAgKi8KKyAgICAgICAgbGVuMiA9IGdhbGxvcExlZnQoYVtiYXNlMSArIGxlbjEgLSAxXSwgYSwgYmFzZTIsIGxlbjIsIGxlbjIgLSAxLCBjKTsKKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbGVuMiA+PSAwOworICAgICAgICBpZiAobGVuMiA9PSAwKQorICAgICAgICAgICAgcmV0dXJuOworCisgICAgICAgIC8vIE1lcmdlIHJlbWFpbmluZyBydW5zLCB1c2luZyB0bXAgYXJyYXkgd2l0aCBtaW4obGVuMSwgbGVuMikgZWxlbWVudHMKKyAgICAgICAgaWYgKGxlbjEgPD0gbGVuMikKKyAgICAgICAgICAgIG1lcmdlTG8oYmFzZTEsIGxlbjEsIGJhc2UyLCBsZW4yKTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgbWVyZ2VIaShiYXNlMSwgbGVuMSwgYmFzZTIsIGxlbjIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvY2F0ZXMgdGhlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIGluc2VydCB0aGUgc3BlY2lmaWVkIGtleSBpbnRvIHRoZQorICAgICAqIHNwZWNpZmllZCBzb3J0ZWQgcmFuZ2U7IGlmIHRoZSByYW5nZSBjb250YWlucyBhbiBlbGVtZW50IGVxdWFsIHRvIGtleSwKKyAgICAgKiByZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbGVmdG1vc3QgZXF1YWwgZWxlbWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkgdGhlIGtleSB3aG9zZSBpbnNlcnRpb24gcG9pbnQgdG8gc2VhcmNoIGZvcgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSBpbiB3aGljaCB0byBzZWFyY2gKKyAgICAgKiBAcGFyYW0gYmFzZSB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIHJhbmdlCisgICAgICogQHBhcmFtIGxlbiB0aGUgbGVuZ3RoIG9mIHRoZSByYW5nZTsgbXVzdCBiZSA+IDAKKyAgICAgKiBAcGFyYW0gaGludCB0aGUgaW5kZXggYXQgd2hpY2ggdG8gYmVnaW4gdGhlIHNlYXJjaCwgMCA8PSBoaW50IDwgbi4KKyAgICAgKiAgICAgVGhlIGNsb3NlciBoaW50IGlzIHRvIHRoZSByZXN1bHQsIHRoZSBmYXN0ZXIgdGhpcyBtZXRob2Qgd2lsbCBydW4uCisgICAgICogQHBhcmFtIGMgdGhlIGNvbXBhcmF0b3IgdXNlZCB0byBvcmRlciB0aGUgcmFuZ2UsIGFuZCB0byBzZWFyY2gKKyAgICAgKiBAcmV0dXJuIHRoZSBpbnQgaywgIDAgPD0gayA8PSBuIHN1Y2ggdGhhdCBhW2IgKyBrIC0gMV0gPCBrZXkgPD0gYVtiICsga10sCisgICAgICogICAgcHJldGVuZGluZyB0aGF0IGFbYiAtIDFdIGlzIG1pbnVzIGluZmluaXR5IGFuZCBhW2IgKyBuXSBpcyBpbmZpbml0eS4KKyAgICAgKiAgICBJbiBvdGhlciB3b3Jkcywga2V5IGJlbG9uZ3MgYXQgaW5kZXggYiArIGs7IG9yIGluIG90aGVyIHdvcmRzLAorICAgICAqICAgIHRoZSBmaXJzdCBrIGVsZW1lbnRzIG9mIGEgc2hvdWxkIHByZWNlZGUga2V5LCBhbmQgdGhlIGxhc3QgbiAtIGsKKyAgICAgKiAgICBzaG91bGQgZm9sbG93IGl0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIDxUPiBpbnQgZ2FsbG9wTGVmdChUIGtleSwgVFtdIGEsIGludCBiYXNlLCBpbnQgbGVuLCBpbnQgaGludCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29tcGFyYXRvcjw/IHN1cGVyIFQ+IGMpIHsKKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbGVuID4gMCAmJiBoaW50ID49IDAgJiYgaGludCA8IGxlbjsKKyAgICAgICAgaW50IGxhc3RPZnMgPSAwOworICAgICAgICBpbnQgb2ZzID0gMTsKKyAgICAgICAgaWYgKGMuY29tcGFyZShrZXksIGFbYmFzZSArIGhpbnRdKSA+IDApIHsKKyAgICAgICAgICAgIC8vIEdhbGxvcCByaWdodCB1bnRpbCBhW2Jhc2UraGludCtsYXN0T2ZzXSA8IGtleSA8PSBhW2Jhc2UraGludCtvZnNdCisgICAgICAgICAgICBpbnQgbWF4T2ZzID0gbGVuIC0gaGludDsKKyAgICAgICAgICAgIHdoaWxlIChvZnMgPCBtYXhPZnMgJiYgYy5jb21wYXJlKGtleSwgYVtiYXNlICsgaGludCArIG9mc10pID4gMCkgeworICAgICAgICAgICAgICAgIGxhc3RPZnMgPSBvZnM7CisgICAgICAgICAgICAgICAgb2ZzID0gKG9mcyAqIDIpICsgMTsKKyAgICAgICAgICAgICAgICBpZiAob2ZzIDw9IDApICAgLy8gaW50IG92ZXJmbG93CisgICAgICAgICAgICAgICAgICAgIG9mcyA9IG1heE9mczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChvZnMgPiBtYXhPZnMpCisgICAgICAgICAgICAgICAgb2ZzID0gbWF4T2ZzOworCisgICAgICAgICAgICAvLyBNYWtlIG9mZnNldHMgcmVsYXRpdmUgdG8gYmFzZQorICAgICAgICAgICAgbGFzdE9mcyArPSBoaW50OworICAgICAgICAgICAgb2ZzICs9IGhpbnQ7CisgICAgICAgIH0gZWxzZSB7IC8vIGtleSA8PSBhW2Jhc2UgKyBoaW50XQorICAgICAgICAgICAgLy8gR2FsbG9wIGxlZnQgdW50aWwgYVtiYXNlK2hpbnQtb2ZzXSA8IGtleSA8PSBhW2Jhc2UraGludC1sYXN0T2ZzXQorICAgICAgICAgICAgZmluYWwgaW50IG1heE9mcyA9IGhpbnQgKyAxOworICAgICAgICAgICAgd2hpbGUgKG9mcyA8IG1heE9mcyAmJiBjLmNvbXBhcmUoa2V5LCBhW2Jhc2UgKyBoaW50IC0gb2ZzXSkgPD0gMCkgeworICAgICAgICAgICAgICAgIGxhc3RPZnMgPSBvZnM7CisgICAgICAgICAgICAgICAgb2ZzID0gKG9mcyAqIDIpICsgMTsKKyAgICAgICAgICAgICAgICBpZiAob2ZzIDw9IDApICAgLy8gaW50IG92ZXJmbG93CisgICAgICAgICAgICAgICAgICAgIG9mcyA9IG1heE9mczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChvZnMgPiBtYXhPZnMpCisgICAgICAgICAgICAgICAgb2ZzID0gbWF4T2ZzOworCisgICAgICAgICAgICAvLyBNYWtlIG9mZnNldHMgcmVsYXRpdmUgdG8gYmFzZQorICAgICAgICAgICAgaW50IHRtcCA9IGxhc3RPZnM7CisgICAgICAgICAgICBsYXN0T2ZzID0gaGludCAtIG9mczsKKyAgICAgICAgICAgIG9mcyA9IGhpbnQgLSB0bXA7CisgICAgICAgIH0KKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgLTEgPD0gbGFzdE9mcyAmJiBsYXN0T2ZzIDwgb2ZzICYmIG9mcyA8PSBsZW47CisKKyAgICAgICAgLyoKKyAgICAgICAgICogTm93IGFbYmFzZStsYXN0T2ZzXSA8IGtleSA8PSBhW2Jhc2Urb2ZzXSwgc28ga2V5IGJlbG9uZ3Mgc29tZXdoZXJlCisgICAgICAgICAqIHRvIHRoZSByaWdodCBvZiBsYXN0T2ZzIGJ1dCBubyBmYXJ0aGVyIHJpZ2h0IHRoYW4gb2ZzLiAgRG8gYSBiaW5hcnkKKyAgICAgICAgICogc2VhcmNoLCB3aXRoIGludmFyaWFudCBhW2Jhc2UgKyBsYXN0T2ZzIC0gMV0gPCBrZXkgPD0gYVtiYXNlICsgb2ZzXS4KKyAgICAgICAgICovCisgICAgICAgIGxhc3RPZnMrKzsKKyAgICAgICAgd2hpbGUgKGxhc3RPZnMgPCBvZnMpIHsKKyAgICAgICAgICAgIGludCBtID0gbGFzdE9mcyArICgob2ZzIC0gbGFzdE9mcykgPj4+IDEpOworCisgICAgICAgICAgICBpZiAoYy5jb21wYXJlKGtleSwgYVtiYXNlICsgbV0pID4gMCkKKyAgICAgICAgICAgICAgICBsYXN0T2ZzID0gbSArIDE7ICAvLyBhW2Jhc2UgKyBtXSA8IGtleQorICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIG9mcyA9IG07ICAgICAgICAgIC8vIGtleSA8PSBhW2Jhc2UgKyBtXQorICAgICAgICB9CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxhc3RPZnMgPT0gb2ZzOyAgICAvLyBzbyBhW2Jhc2UgKyBvZnMgLSAxXSA8IGtleSA8PSBhW2Jhc2UgKyBvZnNdCisgICAgICAgIHJldHVybiBvZnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogTGlrZSBnYWxsb3BMZWZ0LCBleGNlcHQgdGhhdCBpZiB0aGUgcmFuZ2UgY29udGFpbnMgYW4gZWxlbWVudCBlcXVhbCB0bworICAgICAqIGtleSwgZ2FsbG9wUmlnaHQgcmV0dXJucyB0aGUgaW5kZXggYWZ0ZXIgdGhlIHJpZ2h0bW9zdCBlcXVhbCBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGtleSB0aGUga2V5IHdob3NlIGluc2VydGlvbiBwb2ludCB0byBzZWFyY2ggZm9yCisgICAgICogQHBhcmFtIGEgdGhlIGFycmF5IGluIHdoaWNoIHRvIHNlYXJjaAorICAgICAqIEBwYXJhbSBiYXNlIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgZWxlbWVudCBpbiB0aGUgcmFuZ2UKKyAgICAgKiBAcGFyYW0gbGVuIHRoZSBsZW5ndGggb2YgdGhlIHJhbmdlOyBtdXN0IGJlID4gMAorICAgICAqIEBwYXJhbSBoaW50IHRoZSBpbmRleCBhdCB3aGljaCB0byBiZWdpbiB0aGUgc2VhcmNoLCAwIDw9IGhpbnQgPCBuLgorICAgICAqICAgICBUaGUgY2xvc2VyIGhpbnQgaXMgdG8gdGhlIHJlc3VsdCwgdGhlIGZhc3RlciB0aGlzIG1ldGhvZCB3aWxsIHJ1bi4KKyAgICAgKiBAcGFyYW0gYyB0aGUgY29tcGFyYXRvciB1c2VkIHRvIG9yZGVyIHRoZSByYW5nZSwgYW5kIHRvIHNlYXJjaAorICAgICAqIEByZXR1cm4gdGhlIGludCBrLCAgMCA8PSBrIDw9IG4gc3VjaCB0aGF0IGFbYiArIGsgLSAxXSA8PSBrZXkgPCBhW2IgKyBrXQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIDxUPiBpbnQgZ2FsbG9wUmlnaHQoVCBrZXksIFRbXSBhLCBpbnQgYmFzZSwgaW50IGxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBoaW50LCBDb21wYXJhdG9yPD8gc3VwZXIgVD4gYykgeworICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBsZW4gPiAwICYmIGhpbnQgPj0gMCAmJiBoaW50IDwgbGVuOworCisgICAgICAgIGludCBvZnMgPSAxOworICAgICAgICBpbnQgbGFzdE9mcyA9IDA7CisgICAgICAgIGlmIChjLmNvbXBhcmUoa2V5LCBhW2Jhc2UgKyBoaW50XSkgPCAwKSB7CisgICAgICAgICAgICAvLyBHYWxsb3AgbGVmdCB1bnRpbCBhW2IraGludCAtIG9mc10gPD0ga2V5IDwgYVtiK2hpbnQgLSBsYXN0T2ZzXQorICAgICAgICAgICAgaW50IG1heE9mcyA9IGhpbnQgKyAxOworICAgICAgICAgICAgd2hpbGUgKG9mcyA8IG1heE9mcyAmJiBjLmNvbXBhcmUoa2V5LCBhW2Jhc2UgKyBoaW50IC0gb2ZzXSkgPCAwKSB7CisgICAgICAgICAgICAgICAgbGFzdE9mcyA9IG9mczsKKyAgICAgICAgICAgICAgICBvZnMgPSAob2ZzICogMikgKyAxOworICAgICAgICAgICAgICAgIGlmIChvZnMgPD0gMCkgICAvLyBpbnQgb3ZlcmZsb3cKKyAgICAgICAgICAgICAgICAgICAgb2ZzID0gbWF4T2ZzOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG9mcyA+IG1heE9mcykKKyAgICAgICAgICAgICAgICBvZnMgPSBtYXhPZnM7CisKKyAgICAgICAgICAgIC8vIE1ha2Ugb2Zmc2V0cyByZWxhdGl2ZSB0byBiCisgICAgICAgICAgICBpbnQgdG1wID0gbGFzdE9mczsKKyAgICAgICAgICAgIGxhc3RPZnMgPSBoaW50IC0gb2ZzOworICAgICAgICAgICAgb2ZzID0gaGludCAtIHRtcDsKKyAgICAgICAgfSBlbHNlIHsgLy8gYVtiICsgaGludF0gPD0ga2V5CisgICAgICAgICAgICAvLyBHYWxsb3AgcmlnaHQgdW50aWwgYVtiK2hpbnQgKyBsYXN0T2ZzXSA8PSBrZXkgPCBhW2IraGludCArIG9mc10KKyAgICAgICAgICAgIGludCBtYXhPZnMgPSBsZW4gLSBoaW50OworICAgICAgICAgICAgd2hpbGUgKG9mcyA8IG1heE9mcyAmJiBjLmNvbXBhcmUoa2V5LCBhW2Jhc2UgKyBoaW50ICsgb2ZzXSkgPj0gMCkgeworICAgICAgICAgICAgICAgIGxhc3RPZnMgPSBvZnM7CisgICAgICAgICAgICAgICAgb2ZzID0gKG9mcyAqIDIpICsgMTsKKyAgICAgICAgICAgICAgICBpZiAob2ZzIDw9IDApICAgLy8gaW50IG92ZXJmbG93CisgICAgICAgICAgICAgICAgICAgIG9mcyA9IG1heE9mczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChvZnMgPiBtYXhPZnMpCisgICAgICAgICAgICAgICAgb2ZzID0gbWF4T2ZzOworCisgICAgICAgICAgICAvLyBNYWtlIG9mZnNldHMgcmVsYXRpdmUgdG8gYgorICAgICAgICAgICAgbGFzdE9mcyArPSBoaW50OworICAgICAgICAgICAgb2ZzICs9IGhpbnQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgLTEgPD0gbGFzdE9mcyAmJiBsYXN0T2ZzIDwgb2ZzICYmIG9mcyA8PSBsZW47CisKKyAgICAgICAgLyoKKyAgICAgICAgICogTm93IGFbYiArIGxhc3RPZnNdIDw9IGtleSA8IGFbYiArIG9mc10sIHNvIGtleSBiZWxvbmdzIHNvbWV3aGVyZSB0bworICAgICAgICAgKiB0aGUgcmlnaHQgb2YgbGFzdE9mcyBidXQgbm8gZmFydGhlciByaWdodCB0aGFuIG9mcy4gIERvIGEgYmluYXJ5CisgICAgICAgICAqIHNlYXJjaCwgd2l0aCBpbnZhcmlhbnQgYVtiICsgbGFzdE9mcyAtIDFdIDw9IGtleSA8IGFbYiArIG9mc10uCisgICAgICAgICAqLworICAgICAgICBsYXN0T2ZzKys7CisgICAgICAgIHdoaWxlIChsYXN0T2ZzIDwgb2ZzKSB7CisgICAgICAgICAgICBpbnQgbSA9IGxhc3RPZnMgKyAoKG9mcyAtIGxhc3RPZnMpID4+PiAxKTsKKworICAgICAgICAgICAgaWYgKGMuY29tcGFyZShrZXksIGFbYmFzZSArIG1dKSA8IDApCisgICAgICAgICAgICAgICAgb2ZzID0gbTsgICAgICAgICAgLy8ga2V5IDwgYVtiICsgbV0KKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBsYXN0T2ZzID0gbSArIDE7ICAvLyBhW2IgKyBtXSA8PSBrZXkKKyAgICAgICAgfQorICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBsYXN0T2ZzID09IG9mczsgICAgLy8gc28gYVtiICsgb2ZzIC0gMV0gPD0ga2V5IDwgYVtiICsgb2ZzXQorICAgICAgICByZXR1cm4gb2ZzOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1lcmdlcyB0d28gYWRqYWNlbnQgcnVucyBpbiBwbGFjZSwgaW4gYSBzdGFibGUgZmFzaGlvbi4gIFRoZSBmaXJzdAorICAgICAqIGVsZW1lbnQgb2YgdGhlIGZpcnN0IHJ1biBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGUKKyAgICAgKiBzZWNvbmQgcnVuIChhW2Jhc2UxXSA+IGFbYmFzZTJdKSwgYW5kIHRoZSBsYXN0IGVsZW1lbnQgb2YgdGhlIGZpcnN0IHJ1bgorICAgICAqIChhW2Jhc2UxICsgbGVuMS0xXSkgbXVzdCBiZSBncmVhdGVyIHRoYW4gYWxsIGVsZW1lbnRzIG9mIHRoZSBzZWNvbmQgcnVuLgorICAgICAqCisgICAgICogRm9yIHBlcmZvcm1hbmNlLCB0aGlzIG1ldGhvZCBzaG91bGQgYmUgY2FsbGVkIG9ubHkgd2hlbiBsZW4xIDw9IGxlbjI7CisgICAgICogaXRzIHR3aW4sIG1lcmdlSGkgc2hvdWxkIGJlIGNhbGxlZCBpZiBsZW4xID49IGxlbjIuICAoRWl0aGVyIG1ldGhvZAorICAgICAqIG1heSBiZSBjYWxsZWQgaWYgbGVuMSA9PSBsZW4yLikKKyAgICAgKgorICAgICAqIEBwYXJhbSBiYXNlMSBpbmRleCBvZiBmaXJzdCBlbGVtZW50IGluIGZpcnN0IHJ1biB0byBiZSBtZXJnZWQKKyAgICAgKiBAcGFyYW0gbGVuMSAgbGVuZ3RoIG9mIGZpcnN0IHJ1biB0byBiZSBtZXJnZWQgKG11c3QgYmUgPiAwKQorICAgICAqIEBwYXJhbSBiYXNlMiBpbmRleCBvZiBmaXJzdCBlbGVtZW50IGluIHNlY29uZCBydW4gdG8gYmUgbWVyZ2VkCisgICAgICogICAgICAgIChtdXN0IGJlIGFCYXNlICsgYUxlbikKKyAgICAgKiBAcGFyYW0gbGVuMiAgbGVuZ3RoIG9mIHNlY29uZCBydW4gdG8gYmUgbWVyZ2VkIChtdXN0IGJlID4gMCkKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgbWVyZ2VMbyhpbnQgYmFzZTEsIGludCBsZW4xLCBpbnQgYmFzZTIsIGludCBsZW4yKSB7CisgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxlbjEgPiAwICYmIGxlbjIgPiAwICYmIGJhc2UxICsgbGVuMSA9PSBiYXNlMjsKKworICAgICAgICAvLyBDb3B5IGZpcnN0IHJ1biBpbnRvIHRlbXAgYXJyYXkKKyAgICAgICAgVFtdIGEgPSB0aGlzLmE7IC8vIEZvciBwZXJmb3JtYW5jZQorICAgICAgICBUW10gdG1wID0gZW5zdXJlQ2FwYWNpdHkobGVuMSk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYSwgYmFzZTEsIHRtcCwgMCwgbGVuMSk7CisKKyAgICAgICAgaW50IGN1cnNvcjEgPSAwOyAgICAgICAvLyBJbmRleGVzIGludG8gdG1wIGFycmF5CisgICAgICAgIGludCBjdXJzb3IyID0gYmFzZTI7ICAgLy8gSW5kZXhlcyBpbnQgYQorICAgICAgICBpbnQgZGVzdCA9IGJhc2UxOyAgICAgIC8vIEluZGV4ZXMgaW50IGEKKworICAgICAgICAvLyBNb3ZlIGZpcnN0IGVsZW1lbnQgb2Ygc2Vjb25kIHJ1biBhbmQgZGVhbCB3aXRoIGRlZ2VuZXJhdGUgY2FzZXMKKyAgICAgICAgYVtkZXN0KytdID0gYVtjdXJzb3IyKytdOworICAgICAgICBpZiAoLS1sZW4yID09IDApIHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodG1wLCBjdXJzb3IxLCBhLCBkZXN0LCBsZW4xKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAobGVuMSA9PSAxKSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIGN1cnNvcjIsIGEsIGRlc3QsIGxlbjIpOworICAgICAgICAgICAgYVtkZXN0ICsgbGVuMl0gPSB0bXBbY3Vyc29yMV07IC8vIExhc3QgZWx0IG9mIHJ1biAxIHRvIGVuZCBvZiBtZXJnZQorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgQ29tcGFyYXRvcjw/IHN1cGVyIFQ+IGMgPSB0aGlzLmM7ICAvLyBVc2UgbG9jYWwgdmFyaWFibGUgZm9yIHBlcmZvcm1hbmNlCisgICAgICAgIGludCBtaW5HYWxsb3AgPSB0aGlzLm1pbkdhbGxvcDsgICAgLy8gICIgICAgIiAgICAgICAiICAgICAiICAgICAgIgorICAgIG91dGVyOgorICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgaW50IGNvdW50MSA9IDA7IC8vIE51bWJlciBvZiB0aW1lcyBpbiBhIHJvdyB0aGF0IGZpcnN0IHJ1biB3b24KKyAgICAgICAgICAgIGludCBjb3VudDIgPSAwOyAvLyBOdW1iZXIgb2YgdGltZXMgaW4gYSByb3cgdGhhdCBzZWNvbmQgcnVuIHdvbgorCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogRG8gdGhlIHN0cmFpZ2h0Zm9yd2FyZCB0aGluZyB1bnRpbCAoaWYgZXZlcikgb25lIHJ1biBzdGFydHMKKyAgICAgICAgICAgICAqIHdpbm5pbmcgY29uc2lzdGVudGx5LgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbGVuMSA+IDEgJiYgbGVuMiA+IDA7CisgICAgICAgICAgICAgICAgaWYgKGMuY29tcGFyZShhW2N1cnNvcjJdLCB0bXBbY3Vyc29yMV0pIDwgMCkgeworICAgICAgICAgICAgICAgICAgICBhW2Rlc3QrK10gPSBhW2N1cnNvcjIrK107CisgICAgICAgICAgICAgICAgICAgIGNvdW50MisrOworICAgICAgICAgICAgICAgICAgICBjb3VudDEgPSAwOworICAgICAgICAgICAgICAgICAgICBpZiAoLS1sZW4yID09IDApCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBhW2Rlc3QrK10gPSB0bXBbY3Vyc29yMSsrXTsKKyAgICAgICAgICAgICAgICAgICAgY291bnQxKys7CisgICAgICAgICAgICAgICAgICAgIGNvdW50MiA9IDA7CisgICAgICAgICAgICAgICAgICAgIGlmICgtLWxlbjEgPT0gMSkKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gd2hpbGUgKChjb3VudDEgfCBjb3VudDIpIDwgbWluR2FsbG9wKTsKKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIE9uZSBydW4gaXMgd2lubmluZyBzbyBjb25zaXN0ZW50bHkgdGhhdCBnYWxsb3BpbmcgbWF5IGJlIGEKKyAgICAgICAgICAgICAqIGh1Z2Ugd2luLiBTbyB0cnkgdGhhdCwgYW5kIGNvbnRpbnVlIGdhbGxvcGluZyB1bnRpbCAoaWYgZXZlcikKKyAgICAgICAgICAgICAqIG5laXRoZXIgcnVuIGFwcGVhcnMgdG8gYmUgd2lubmluZyBjb25zaXN0ZW50bHkgYW55bW9yZS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxlbjEgPiAxICYmIGxlbjIgPiAwOworICAgICAgICAgICAgICAgIGNvdW50MSA9IGdhbGxvcFJpZ2h0KGFbY3Vyc29yMl0sIHRtcCwgY3Vyc29yMSwgbGVuMSwgMCwgYyk7CisgICAgICAgICAgICAgICAgaWYgKGNvdW50MSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodG1wLCBjdXJzb3IxLCBhLCBkZXN0LCBjb3VudDEpOworICAgICAgICAgICAgICAgICAgICBkZXN0ICs9IGNvdW50MTsKKyAgICAgICAgICAgICAgICAgICAgY3Vyc29yMSArPSBjb3VudDE7CisgICAgICAgICAgICAgICAgICAgIGxlbjEgLT0gY291bnQxOworICAgICAgICAgICAgICAgICAgICBpZiAobGVuMSA8PSAxKSAvLyBsZW4xID09IDEgfHwgbGVuMSA9PSAwCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYVtkZXN0KytdID0gYVtjdXJzb3IyKytdOworICAgICAgICAgICAgICAgIGlmICgtLWxlbjIgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7CisKKyAgICAgICAgICAgICAgICBjb3VudDIgPSBnYWxsb3BMZWZ0KHRtcFtjdXJzb3IxXSwgYSwgY3Vyc29yMiwgbGVuMiwgMCwgYyk7CisgICAgICAgICAgICAgICAgaWYgKGNvdW50MiAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYSwgY3Vyc29yMiwgYSwgZGVzdCwgY291bnQyKTsKKyAgICAgICAgICAgICAgICAgICAgZGVzdCArPSBjb3VudDI7CisgICAgICAgICAgICAgICAgICAgIGN1cnNvcjIgKz0gY291bnQyOworICAgICAgICAgICAgICAgICAgICBsZW4yIC09IGNvdW50MjsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGxlbjIgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhW2Rlc3QrK10gPSB0bXBbY3Vyc29yMSsrXTsKKyAgICAgICAgICAgICAgICBpZiAoLS1sZW4xID09IDEpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworICAgICAgICAgICAgICAgIG1pbkdhbGxvcC0tOworICAgICAgICAgICAgfSB3aGlsZSAoY291bnQxID49IE1JTl9HQUxMT1AgfCBjb3VudDIgPj0gTUlOX0dBTExPUCk7CisgICAgICAgICAgICBpZiAobWluR2FsbG9wIDwgMCkKKyAgICAgICAgICAgICAgICBtaW5HYWxsb3AgPSAwOworICAgICAgICAgICAgbWluR2FsbG9wICs9IDI7ICAvLyBQZW5hbGl6ZSBmb3IgbGVhdmluZyBnYWxsb3AgbW9kZQorICAgICAgICB9ICAvLyBFbmQgb2YgIm91dGVyIiBsb29wCisgICAgICAgIHRoaXMubWluR2FsbG9wID0gbWluR2FsbG9wIDwgMSA/IDEgOiBtaW5HYWxsb3A7ICAvLyBXcml0ZSBiYWNrIHRvIGZpZWxkCisKKyAgICAgICAgaWYgKGxlbjEgPT0gMSkgeworICAgICAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbGVuMiA+IDA7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIGN1cnNvcjIsIGEsIGRlc3QsIGxlbjIpOworICAgICAgICAgICAgYVtkZXN0ICsgbGVuMl0gPSB0bXBbY3Vyc29yMV07IC8vICBMYXN0IGVsdCBvZiBydW4gMSB0byBlbmQgb2YgbWVyZ2UKKyAgICAgICAgfSBlbHNlIGlmIChsZW4xID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgIkNvbXBhcmlzb24gbWV0aG9kIHZpb2xhdGVzIGl0cyBnZW5lcmFsIGNvbnRyYWN0ISIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbGVuMiA9PSAwOworICAgICAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbGVuMSA+IDE7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRtcCwgY3Vyc29yMSwgYSwgZGVzdCwgbGVuMSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMaWtlIG1lcmdlTG8sIGV4Y2VwdCB0aGF0IHRoaXMgbWV0aG9kIHNob3VsZCBiZSBjYWxsZWQgb25seSBpZgorICAgICAqIGxlbjEgPj0gbGVuMjsgbWVyZ2VMbyBzaG91bGQgYmUgY2FsbGVkIGlmIGxlbjEgPD0gbGVuMi4gIChFaXRoZXIgbWV0aG9kCisgICAgICogbWF5IGJlIGNhbGxlZCBpZiBsZW4xID09IGxlbjIuKQorICAgICAqCisgICAgICogQHBhcmFtIGJhc2UxIGluZGV4IG9mIGZpcnN0IGVsZW1lbnQgaW4gZmlyc3QgcnVuIHRvIGJlIG1lcmdlZAorICAgICAqIEBwYXJhbSBsZW4xICBsZW5ndGggb2YgZmlyc3QgcnVuIHRvIGJlIG1lcmdlZCAobXVzdCBiZSA+IDApCisgICAgICogQHBhcmFtIGJhc2UyIGluZGV4IG9mIGZpcnN0IGVsZW1lbnQgaW4gc2Vjb25kIHJ1biB0byBiZSBtZXJnZWQKKyAgICAgKiAgICAgICAgKG11c3QgYmUgYUJhc2UgKyBhTGVuKQorICAgICAqIEBwYXJhbSBsZW4yICBsZW5ndGggb2Ygc2Vjb25kIHJ1biB0byBiZSBtZXJnZWQgKG11c3QgYmUgPiAwKQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBtZXJnZUhpKGludCBiYXNlMSwgaW50IGxlbjEsIGludCBiYXNlMiwgaW50IGxlbjIpIHsKKyAgICAgICAgaWYgKERFQlVHKSBhc3NlcnQgbGVuMSA+IDAgJiYgbGVuMiA+IDAgJiYgYmFzZTEgKyBsZW4xID09IGJhc2UyOworCisgICAgICAgIC8vIENvcHkgc2Vjb25kIHJ1biBpbnRvIHRlbXAgYXJyYXkKKyAgICAgICAgVFtdIGEgPSB0aGlzLmE7IC8vIEZvciBwZXJmb3JtYW5jZQorICAgICAgICBUW10gdG1wID0gZW5zdXJlQ2FwYWNpdHkobGVuMik7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYSwgYmFzZTIsIHRtcCwgMCwgbGVuMik7CisKKyAgICAgICAgaW50IGN1cnNvcjEgPSBiYXNlMSArIGxlbjEgLSAxOyAgLy8gSW5kZXhlcyBpbnRvIGEKKyAgICAgICAgaW50IGN1cnNvcjIgPSBsZW4yIC0gMTsgICAgICAgICAgLy8gSW5kZXhlcyBpbnRvIHRtcCBhcnJheQorICAgICAgICBpbnQgZGVzdCA9IGJhc2UyICsgbGVuMiAtIDE7ICAgICAvLyBJbmRleGVzIGludG8gYQorCisgICAgICAgIC8vIE1vdmUgbGFzdCBlbGVtZW50IG9mIGZpcnN0IHJ1biBhbmQgZGVhbCB3aXRoIGRlZ2VuZXJhdGUgY2FzZXMKKyAgICAgICAgYVtkZXN0LS1dID0gYVtjdXJzb3IxLS1dOworICAgICAgICBpZiAoLS1sZW4xID09IDApIHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodG1wLCAwLCBhLCBkZXN0IC0gKGxlbjIgLSAxKSwgbGVuMik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxlbjIgPT0gMSkgeworICAgICAgICAgICAgZGVzdCAtPSBsZW4xOworICAgICAgICAgICAgY3Vyc29yMSAtPSBsZW4xOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhLCBjdXJzb3IxICsgMSwgYSwgZGVzdCArIDEsIGxlbjEpOworICAgICAgICAgICAgYVtkZXN0XSA9IHRtcFtjdXJzb3IyXTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIENvbXBhcmF0b3I8PyBzdXBlciBUPiBjID0gdGhpcy5jOyAgLy8gVXNlIGxvY2FsIHZhcmlhYmxlIGZvciBwZXJmb3JtYW5jZQorICAgICAgICBpbnQgbWluR2FsbG9wID0gdGhpcy5taW5HYWxsb3A7ICAgIC8vICAiICAgICIgICAgICAgIiAgICAgIiAgICAgICIKKyAgICBvdXRlcjoKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIGludCBjb3VudDEgPSAwOyAvLyBOdW1iZXIgb2YgdGltZXMgaW4gYSByb3cgdGhhdCBmaXJzdCBydW4gd29uCisgICAgICAgICAgICBpbnQgY291bnQyID0gMDsgLy8gTnVtYmVyIG9mIHRpbWVzIGluIGEgcm93IHRoYXQgc2Vjb25kIHJ1biB3b24KKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIERvIHRoZSBzdHJhaWdodGZvcndhcmQgdGhpbmcgdW50aWwgKGlmIGV2ZXIpIG9uZSBydW4KKyAgICAgICAgICAgICAqIGFwcGVhcnMgdG8gd2luIGNvbnNpc3RlbnRseS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxlbjEgPiAwICYmIGxlbjIgPiAxOworICAgICAgICAgICAgICAgIGlmIChjLmNvbXBhcmUodG1wW2N1cnNvcjJdLCBhW2N1cnNvcjFdKSA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgYVtkZXN0LS1dID0gYVtjdXJzb3IxLS1dOworICAgICAgICAgICAgICAgICAgICBjb3VudDErKzsKKyAgICAgICAgICAgICAgICAgICAgY291bnQyID0gMDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKC0tbGVuMSA9PSAwKQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYVtkZXN0LS1dID0gdG1wW2N1cnNvcjItLV07CisgICAgICAgICAgICAgICAgICAgIGNvdW50MisrOworICAgICAgICAgICAgICAgICAgICBjb3VudDEgPSAwOworICAgICAgICAgICAgICAgICAgICBpZiAoLS1sZW4yID09IDEpCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IHdoaWxlICgoY291bnQxIHwgY291bnQyKSA8IG1pbkdhbGxvcCk7CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBPbmUgcnVuIGlzIHdpbm5pbmcgc28gY29uc2lzdGVudGx5IHRoYXQgZ2FsbG9waW5nIG1heSBiZSBhCisgICAgICAgICAgICAgKiBodWdlIHdpbi4gU28gdHJ5IHRoYXQsIGFuZCBjb250aW51ZSBnYWxsb3BpbmcgdW50aWwgKGlmIGV2ZXIpCisgICAgICAgICAgICAgKiBuZWl0aGVyIHJ1biBhcHBlYXJzIHRvIGJlIHdpbm5pbmcgY29uc2lzdGVudGx5IGFueW1vcmUuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBsZW4xID4gMCAmJiBsZW4yID4gMTsKKyAgICAgICAgICAgICAgICBjb3VudDEgPSBsZW4xIC0gZ2FsbG9wUmlnaHQodG1wW2N1cnNvcjJdLCBhLCBiYXNlMSwgbGVuMSwgbGVuMSAtIDEsIGMpOworICAgICAgICAgICAgICAgIGlmIChjb3VudDEgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICBkZXN0IC09IGNvdW50MTsKKyAgICAgICAgICAgICAgICAgICAgY3Vyc29yMSAtPSBjb3VudDE7CisgICAgICAgICAgICAgICAgICAgIGxlbjEgLT0gY291bnQxOworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIGN1cnNvcjEgKyAxLCBhLCBkZXN0ICsgMSwgY291bnQxKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGxlbjEgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhW2Rlc3QtLV0gPSB0bXBbY3Vyc29yMi0tXTsKKyAgICAgICAgICAgICAgICBpZiAoLS1sZW4yID09IDEpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyOworCisgICAgICAgICAgICAgICAgY291bnQyID0gbGVuMiAtIGdhbGxvcExlZnQoYVtjdXJzb3IxXSwgdG1wLCAwLCBsZW4yLCBsZW4yIC0gMSwgYyk7CisgICAgICAgICAgICAgICAgaWYgKGNvdW50MiAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGRlc3QgLT0gY291bnQyOworICAgICAgICAgICAgICAgICAgICBjdXJzb3IyIC09IGNvdW50MjsKKyAgICAgICAgICAgICAgICAgICAgbGVuMiAtPSBjb3VudDI7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodG1wLCBjdXJzb3IyICsgMSwgYSwgZGVzdCArIDEsIGNvdW50Mik7CisgICAgICAgICAgICAgICAgICAgIGlmIChsZW4yIDw9IDEpICAvLyBsZW4yID09IDEgfHwgbGVuMiA9PSAwCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYVtkZXN0LS1dID0gYVtjdXJzb3IxLS1dOworICAgICAgICAgICAgICAgIGlmICgtLWxlbjEgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7CisgICAgICAgICAgICAgICAgbWluR2FsbG9wLS07CisgICAgICAgICAgICB9IHdoaWxlIChjb3VudDEgPj0gTUlOX0dBTExPUCB8IGNvdW50MiA+PSBNSU5fR0FMTE9QKTsKKyAgICAgICAgICAgIGlmIChtaW5HYWxsb3AgPCAwKQorICAgICAgICAgICAgICAgIG1pbkdhbGxvcCA9IDA7CisgICAgICAgICAgICBtaW5HYWxsb3AgKz0gMjsgIC8vIFBlbmFsaXplIGZvciBsZWF2aW5nIGdhbGxvcCBtb2RlCisgICAgICAgIH0gIC8vIEVuZCBvZiAib3V0ZXIiIGxvb3AKKyAgICAgICAgdGhpcy5taW5HYWxsb3AgPSBtaW5HYWxsb3AgPCAxID8gMSA6IG1pbkdhbGxvcDsgIC8vIFdyaXRlIGJhY2sgdG8gZmllbGQKKworICAgICAgICBpZiAobGVuMiA9PSAxKSB7CisgICAgICAgICAgICBpZiAoREVCVUcpIGFzc2VydCBsZW4xID4gMDsKKyAgICAgICAgICAgIGRlc3QgLT0gbGVuMTsKKyAgICAgICAgICAgIGN1cnNvcjEgLT0gbGVuMTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYSwgY3Vyc29yMSArIDEsIGEsIGRlc3QgKyAxLCBsZW4xKTsKKyAgICAgICAgICAgIGFbZGVzdF0gPSB0bXBbY3Vyc29yMl07ICAvLyBNb3ZlIGZpcnN0IGVsdCBvZiBydW4yIHRvIGZyb250IG9mIG1lcmdlCisgICAgICAgIH0gZWxzZSBpZiAobGVuMiA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJDb21wYXJpc29uIG1ldGhvZCB2aW9sYXRlcyBpdHMgZ2VuZXJhbCBjb250cmFjdCEiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxlbjEgPT0gMDsKKyAgICAgICAgICAgIGlmIChERUJVRykgYXNzZXJ0IGxlbjIgPiAwOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0bXAsIDAsIGEsIGRlc3QgLSAobGVuMiAtIDEpLCBsZW4yKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEVuc3VyZXMgdGhhdCB0aGUgZXh0ZXJuYWwgYXJyYXkgdG1wIGhhcyBhdCBsZWFzdCB0aGUgc3BlY2lmaWVkCisgICAgICogbnVtYmVyIG9mIGVsZW1lbnRzLCBpbmNyZWFzaW5nIGl0cyBzaXplIGlmIG5lY2Vzc2FyeS4gIFRoZSBzaXplCisgICAgICogaW5jcmVhc2VzIGV4cG9uZW50aWFsbHkgdG8gZW5zdXJlIGFtb3J0aXplZCBsaW5lYXIgdGltZSBjb21wbGV4aXR5LgorICAgICAqCisgICAgICogQHBhcmFtIG1pbkNhcGFjaXR5IHRoZSBtaW5pbXVtIHJlcXVpcmVkIGNhcGFjaXR5IG9mIHRoZSB0bXAgYXJyYXkKKyAgICAgKiBAcmV0dXJuIHRtcCwgd2hldGhlciBvciBub3QgaXQgZ3JldworICAgICAqLworICAgIHByaXZhdGUgVFtdIGVuc3VyZUNhcGFjaXR5KGludCBtaW5DYXBhY2l0eSkgeworICAgICAgICBpZiAodG1wLmxlbmd0aCA8IG1pbkNhcGFjaXR5KSB7CisgICAgICAgICAgICAvLyBDb21wdXRlIHNtYWxsZXN0IHBvd2VyIG9mIDIgPiBtaW5DYXBhY2l0eQorICAgICAgICAgICAgaW50IG5ld1NpemUgPSBtaW5DYXBhY2l0eTsKKyAgICAgICAgICAgIG5ld1NpemUgfD0gbmV3U2l6ZSA+PiAxOworICAgICAgICAgICAgbmV3U2l6ZSB8PSBuZXdTaXplID4+IDI7CisgICAgICAgICAgICBuZXdTaXplIHw9IG5ld1NpemUgPj4gNDsKKyAgICAgICAgICAgIG5ld1NpemUgfD0gbmV3U2l6ZSA+PiA4OworICAgICAgICAgICAgbmV3U2l6ZSB8PSBuZXdTaXplID4+IDE2OworICAgICAgICAgICAgbmV3U2l6ZSsrOworCisgICAgICAgICAgICBpZiAobmV3U2l6ZSA8IDApIC8vIE5vdCBibG9vZHkgbGlrZWx5IQorICAgICAgICAgICAgICAgIG5ld1NpemUgPSBtaW5DYXBhY2l0eTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBuZXdTaXplID0gTWF0aC5taW4obmV3U2l6ZSwgYS5sZW5ndGggPj4+IDEpOworCisgICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVuY2hlY2tlZCIsICJVbm5lY2Vzc2FyeUxvY2FsVmFyaWFibGUifSkKKyAgICAgICAgICAgIFRbXSBuZXdBcnJheSA9IChUW10pIG5ldyBPYmplY3RbbmV3U2l6ZV07CisgICAgICAgICAgICB0bXAgPSBuZXdBcnJheTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdG1wOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvVGltZVpvbmUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvVGltZVpvbmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYWJiNjA5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9UaW1lWm9uZS5qYXZhCkBAIC0wLDAgKzEsNDQwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGxpYmNvcmUuaWN1LlRpbWVab25lczsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuWm9uZUluZm9EQjsKKworLyoqCisgKiB7QGNvZGUgVGltZVpvbmV9IHJlcHJlc2VudHMgYSB0aW1lIHpvbmUsIHByaW1hcmlseSB1c2VkIGZvciBjb25maWd1cmluZyBhIHtAbGluayBDYWxlbmRhcn0gb3IKKyAqIHtAbGluayBqYXZhLnRleHQuU2ltcGxlRGF0ZUZvcm1hdH0gaW5zdGFuY2UuCisgKgorICogPHA+TW9zdCBhcHBsaWNhdGlvbnMgd2lsbCB1c2Uge0BsaW5rICNnZXREZWZhdWx0fSB3aGljaCByZXR1cm5zIGEge0Bjb2RlIFRpbWVab25lfSBiYXNlZCBvbgorICogdGhlIHRpbWUgem9uZSB3aGVyZSB0aGUgcHJvZ3JhbSBpcyBydW5uaW5nLgorICoKKyAqIDxwPllvdSBjYW4gYWxzbyBnZXQgYSBzcGVjaWZpYyB7QGNvZGUgVGltZVpvbmV9IHtAbGluayAjZ2V0VGltZVpvbmUgYnkgaWR9LgorICoKKyAqIDxwPkl0IGlzIGhpZ2hseSB1bmxpa2VseSB5b3UnbGwgZXZlciB3YW50IHRvIHVzZSBhbnl0aGluZyBidXQgdGhlIGZhY3RvcnkgbWV0aG9kcyB5b3Vyc2VsZi4KKyAqIExldCBjbGFzc2VzIGxpa2Uge0BsaW5rIENhbGVuZGFyfSBhbmQge0BsaW5rIGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0fSBkbyB0aGUgZGF0ZQorICogY29tcHV0YXRpb25zIGZvciB5b3UuCisgKgorICogPHA+SWYgeW91IGRvIG5lZWQgdG8gZG8gZGF0ZSBjb21wdXRhdGlvbnMgbWFudWFsbHksIHRoZXJlIGFyZSB0d28gY29tbW9uIGNhc2VzIHRvIHRha2UgaW50bworICogYWNjb3VudDoKKyAqIDx1bD4KKyAqIDxsaT5Tb21ld2hlcmUgbGlrZSBDYWxpZm9ybmlhLCB3aGVyZSBkYXlsaWdodCB0aW1lIGlzIHVzZWQuCisgKiBUaGUge0BsaW5rICN1c2VEYXlsaWdodFRpbWV9IG1ldGhvZCB3aWxsIGFsd2F5cyByZXR1cm4gdHJ1ZSwgYW5kIHtAbGluayAjaW5EYXlsaWdodFRpbWV9CisgKiBtdXN0IGJlIHVzZWQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgb3Igbm90IGRheWxpZ2h0IHRpbWUgYXBwbGllcyB0byBhIGdpdmVuIHtAY29kZSBEYXRlfS4KKyAqIFRoZSB7QGxpbmsgI2dldFJhd09mZnNldH0gbWV0aG9kIHdpbGwgcmV0dXJuIGEgcmF3IG9mZnNldCBvZiAoaW4gdGhpcyBjYXNlKSAtOCBob3VycyBmcm9tIFVUQywKKyAqIHdoaWNoIGlzbid0IHVzdWFsbHkgdmVyeSB1c2VmdWwuIE1vcmUgdXNlZnVsbHksIHRoZSB7QGxpbmsgI2dldE9mZnNldH0gbWV0aG9kcyByZXR1cm4gdGhlCisgKiBhY3R1YWwgb2Zmc2V0IGZyb20gVVRDIDxpPmZvciBhIGdpdmVuIHBvaW50IGluIHRpbWU8L2k+OyB0aGlzIGlzIHRoZSByYXcgb2Zmc2V0IHBsdXMgKGlmIHRoZQorICogcG9pbnQgaW4gdGltZSBpcyB7QGxpbmsgI2luRGF5bGlnaHRUaW1lIGluIGRheWxpZ2h0IHRpbWV9KSB0aGUgYXBwbGljYWJsZQorICoge0BsaW5rICNnZXREU1RTYXZpbmdzIERTVCBzYXZpbmdzfSAodXN1YWxseSwgYnV0IG5vdCBuZWNlc3NhcmlseSwgMSBob3VyKS4KKyAqIDxsaT5Tb21ld2hlcmUgbGlrZSBKYXBhbiwgd2hlcmUgZGF5bGlnaHQgdGltZSBpcyBub3QgdXNlZC4KKyAqIFRoZSB7QGxpbmsgI3VzZURheWxpZ2h0VGltZX0gYW5kIHtAbGluayAjaW5EYXlsaWdodFRpbWV9IG1ldGhvZHMgYm90aCBhbHdheXMgcmV0dXJuIGZhbHNlLAorICogYW5kIHRoZSByYXcgYW5kIGFjdHVhbCBvZmZzZXRzIHdpbGwgYWx3YXlzIGJlIHRoZSBzYW1lLgorICogPC91bD4KKyAqCisgKiA8cD5Ob3RlIHRoZSB0eXBlIHJldHVybmVkIGJ5IHRoZSBmYWN0b3J5IG1ldGhvZHMge0BsaW5rICNnZXREZWZhdWx0fSBhbmQge0BsaW5rICNnZXRUaW1lWm9uZX0gaXMKKyAqIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4gVGhpcyBtYXkgaW50cm9kdWNlIHNlcmlhbGl6YXRpb24gaW5jb21wYXRpYmlsaXR5IGlzc3VlcyBiZXR3ZWVuCisgKiBkaWZmZXJlbnQgaW1wbGVtZW50YXRpb25zLiBBbmRyb2lkIHJldHVybnMgaW5zdGFuY2VzIG9mIHtAbGluayBTaW1wbGVUaW1lWm9uZX0gc28gdGhhdAorICogdGhlIGJ5dGVzIHNlcmlhbGl6ZWQgYnkgQW5kcm9pZCBjYW4gYmUgZGVzZXJpYWxpemVkIHN1Y2Nlc3NmdWxseSBvbiBvdGhlcgorICogaW1wbGVtZW50YXRpb25zLCBidXQgdGhlIHJldmVyc2UgY29tcGF0aWJpbGl0eSBjYW5ub3QgYmUgZ3VhcmFudGVlZC4KKyAqCisgKiBAc2VlIENhbGVuZGFyCisgKiBAc2VlIEdyZWdvcmlhbkNhbGVuZGFyCisgKiBAc2VlIFNpbXBsZURhdGVGb3JtYXQKKyAqIEBzZWUgU2ltcGxlVGltZVpvbmUKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFRpbWVab25lIGltcGxlbWVudHMgU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDM1ODE0NjMzNjkxNjY5MjQ5NjFMOworCisgICAgLyoqCisgICAgICogVGhlIHNob3J0IGRpc3BsYXkgbmFtZSBzdHlsZSwgc3VjaCBhcyB7QGNvZGUgUERUfS4gUmVxdWVzdHMgZm9yIHRoaXMKKyAgICAgKiBzdHlsZSBtYXkgeWllbGQgR01UIG9mZnNldHMgbGlrZSB7QGNvZGUgR01ULTA4OjAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9SVCA9IDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbG9uZyBkaXNwbGF5IG5hbWUgc3R5bGUsIHN1Y2ggYXMge0Bjb2RlIFBhY2lmaWMgRGF5bGlnaHQgVGltZX0uCisgICAgICogUmVxdWVzdHMgZm9yIHRoaXMgc3R5bGUgbWF5IHlpZWxkIEdNVCBvZmZzZXRzIGxpa2Uge0Bjb2RlIEdNVC0wODowMH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9ORyA9IDE7CisKKyAgICBzdGF0aWMgZmluYWwgVGltZVpvbmUgR01UID0gbmV3IFNpbXBsZVRpbWVab25lKDAsICJHTVQiKTsgLy8gR3JlZW53aWNoIE1lYW4gVGltZQorCisgICAgcHJpdmF0ZSBzdGF0aWMgVGltZVpvbmUgZGVmYXVsdFRpbWVab25lOworCisgICAgcHJpdmF0ZSBTdHJpbmcgSUQ7CisKKyAgICBwdWJsaWMgVGltZVpvbmUoKSB7fQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB0aW1lIHpvbmUgd2l0aCB0aGUgc2FtZSBJRCwgcmF3IG9mZnNldCwgYW5kIGRheWxpZ2h0CisgICAgICogc2F2aW5ncyB0aW1lIHJ1bGVzIGFzIHRoaXMgdGltZSB6b25lLgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN5c3RlbSdzIGluc3RhbGxlZCB0aW1lIHpvbmUgSURzLiBBbnkgb2YgdGhlc2UgSURzIGNhbiBiZQorICAgICAqIHBhc3NlZCB0byB7QGxpbmsgI2dldFRpbWVab25lfSB0byBsb29rdXAgdGhlIGNvcnJlc3BvbmRpbmcgdGltZSB6b25lCisgICAgICogaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgU3RyaW5nW10gZ2V0QXZhaWxhYmxlSURzKCkgeworICAgICAgICByZXR1cm4gWm9uZUluZm9EQi5nZXRBdmFpbGFibGVJRHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBJRHMgb2YgdGhlIHRpbWUgem9uZXMgd2hvc2Ugb2Zmc2V0IGZyb20gVVRDIGlzIHtAY29kZQorICAgICAqIG9mZnNldE1pbGxpc30uIEFueSBvZiB0aGVzZSBJRHMgY2FuIGJlIHBhc3NlZCB0byB7QGxpbmsgI2dldFRpbWVab25lfSB0bworICAgICAqIGxvb2t1cCB0aGUgY29ycmVzcG9uZGluZyB0aW1lIHpvbmUgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcG9zc2libHktZW1wdHkgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgU3RyaW5nW10gZ2V0QXZhaWxhYmxlSURzKGludCBvZmZzZXRNaWxsaXMpIHsKKyAgICAgICAgcmV0dXJuIFpvbmVJbmZvREIuZ2V0QXZhaWxhYmxlSURzKG9mZnNldE1pbGxpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdXNlcidzIHByZWZlcnJlZCB0aW1lIHpvbmUuIFRoaXMgbWF5IGhhdmUgYmVlbiBvdmVycmlkZGVuIGZvcgorICAgICAqIHRoaXMgcHJvY2VzcyB3aXRoIHtAbGluayAjc2V0RGVmYXVsdH0uCisgICAgICoKKyAgICAgKiA8cD5TaW5jZSB0aGUgdXNlcidzIHRpbWUgem9uZSBjaGFuZ2VzIGR5bmFtaWNhbGx5LCBhdm9pZCBjYWNoaW5nIHRoaXMKKyAgICAgKiB2YWx1ZS4gSW5zdGVhZCwgdXNlIHRoaXMgbWV0aG9kIHRvIGxvb2sgaXQgdXAgZm9yIGVhY2ggdXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIFRpbWVab25lIGdldERlZmF1bHQoKSB7CisgICAgICAgIGlmIChkZWZhdWx0VGltZVpvbmUgPT0gbnVsbCkgeworICAgICAgICAgICAgZGVmYXVsdFRpbWVab25lID0gWm9uZUluZm9EQi5nZXRTeXN0ZW1EZWZhdWx0KCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChUaW1lWm9uZSkgZGVmYXVsdFRpbWVab25lLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgZ2V0RGlzcGxheU5hbWUoZmFsc2UsIFRpbWVab25lLkxPTkcsIExvY2FsZS5nZXREZWZhdWx0KCkpfS4KKyAgICAgKiA8YSBocmVmPSIuLi91dGlsL0xvY2FsZS5odG1sI2RlZmF1bHRfbG9jYWxlIj5CZSB3YXJ5IG9mIHRoZSBkZWZhdWx0IGxvY2FsZTwvYT4uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXREaXNwbGF5TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIGdldERpc3BsYXlOYW1lKGZhbHNlLCBMT05HLCBMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVpdmFsZW50IHRvIHtAY29kZSBnZXREaXNwbGF5TmFtZShmYWxzZSwgVGltZVpvbmUuTE9ORywgbG9jYWxlKX0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXREaXNwbGF5TmFtZShMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIHJldHVybiBnZXREaXNwbGF5TmFtZShmYWxzZSwgTE9ORywgbG9jYWxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVpdmFsZW50IHRvIHtAY29kZSBnZXREaXNwbGF5TmFtZShkYXlsaWdodFRpbWUsIHN0eWxlLCBMb2NhbGUuZ2V0RGVmYXVsdCgpKX0uCisgICAgICogPGEgaHJlZj0iLi4vdXRpbC9Mb2NhbGUuaHRtbCNkZWZhdWx0X2xvY2FsZSI+QmUgd2FyeSBvZiB0aGUgZGVmYXVsdCBsb2NhbGU8L2E+LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0RGlzcGxheU5hbWUoYm9vbGVhbiBkYXlsaWdodFRpbWUsIGludCBzdHlsZSkgeworICAgICAgICByZXR1cm4gZ2V0RGlzcGxheU5hbWUoZGF5bGlnaHRUaW1lLCBzdHlsZSwgTG9jYWxlLmdldERlZmF1bHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0BsaW5rICNTSE9SVCBzaG9ydH0gb3Ige0BsaW5rICNMT05HIGxvbmd9IG5hbWUgb2YgdGhpcyB0aW1lCisgICAgICogem9uZSB3aXRoIGVpdGhlciBzdGFuZGFyZCBvciBkYXlsaWdodCB0aW1lLCBhcyB3cml0dGVuIGluIHtAY29kZSBsb2NhbGV9LgorICAgICAqIElmIHRoZSBuYW1lIGlzIG5vdCBhdmFpbGFibGUsIHRoZSByZXN1bHQgaXMgaW4gdGhlIGZvcm1hdAorICAgICAqIHtAY29kZSBHTVRbKy1daGg6bW19LgorICAgICAqCisgICAgICogQHBhcmFtIGRheWxpZ2h0VGltZSB0cnVlIGZvciBkYXlsaWdodCB0aW1lLCBmYWxzZSBmb3Igc3RhbmRhcmQgdGltZS4KKyAgICAgKiBAcGFyYW0gc3R5bGUgZWl0aGVyIHtAbGluayBUaW1lWm9uZSNMT05HfSBvciB7QGxpbmsgVGltZVpvbmUjU0hPUlR9LgorICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGRpc3BsYXkgbG9jYWxlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGlzcGxheU5hbWUoYm9vbGVhbiBkYXlsaWdodFRpbWUsIGludCBzdHlsZSwgTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBpZiAoc3R5bGUgIT0gU0hPUlQgJiYgc3R5bGUgIT0gTE9ORykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiB1c2VEYXlsaWdodCA9IGRheWxpZ2h0VGltZSAmJiB1c2VEYXlsaWdodFRpbWUoKTsKKworICAgICAgICBTdHJpbmdbXVtdIHpvbmVTdHJpbmdzID0gVGltZVpvbmVzLmdldFpvbmVTdHJpbmdzKGxvY2FsZSk7CisgICAgICAgIFN0cmluZyByZXN1bHQgPSBUaW1lWm9uZXMuZ2V0RGlzcGxheU5hbWUoem9uZVN0cmluZ3MsIGdldElEKCksIGRheWxpZ2h0VGltZSwgc3R5bGUpOworICAgICAgICBpZiAocmVzdWx0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKworICAgICAgICAvLyBUT0RPOiBkbyB3ZSBldmVyIGdldCBoZXJlPworCisgICAgICAgIGludCBvZmZzZXQgPSBnZXRSYXdPZmZzZXQoKTsKKyAgICAgICAgaWYgKHVzZURheWxpZ2h0ICYmIHRoaXMgaW5zdGFuY2VvZiBTaW1wbGVUaW1lWm9uZSkgeworICAgICAgICAgICAgb2Zmc2V0ICs9IGdldERTVFNhdmluZ3MoKTsKKyAgICAgICAgfQorICAgICAgICBvZmZzZXQgLz0gNjAwMDA7CisgICAgICAgIGNoYXIgc2lnbiA9ICcrJzsKKyAgICAgICAgaWYgKG9mZnNldCA8IDApIHsKKyAgICAgICAgICAgIHNpZ24gPSAnLSc7CisgICAgICAgICAgICBvZmZzZXQgPSAtb2Zmc2V0OworICAgICAgICB9CisgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKDkpOworICAgICAgICBidWlsZGVyLmFwcGVuZCgiR01UIik7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKHNpZ24pOworICAgICAgICBhcHBlbmROdW1iZXIoYnVpbGRlciwgMiwgb2Zmc2V0IC8gNjApOworICAgICAgICBidWlsZGVyLmFwcGVuZCgnOicpOworICAgICAgICBhcHBlbmROdW1iZXIoYnVpbGRlciwgMiwgb2Zmc2V0ICUgNjApOworICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhcHBlbmROdW1iZXIoU3RyaW5nQnVpbGRlciBidWlsZGVyLCBpbnQgY291bnQsIGludCB2YWx1ZSkgeworICAgICAgICBTdHJpbmcgc3RyaW5nID0gSW50ZWdlci50b1N0cmluZyh2YWx1ZSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQgLSBzdHJpbmcubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoJzAnKTsKKyAgICAgICAgfQorICAgICAgICBidWlsZGVyLmFwcGVuZChzdHJpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIElEIG9mIHRoaXMge0Bjb2RlIFRpbWVab25lfSwgc3VjaCBhcworICAgICAqIHtAY29kZSBBbWVyaWNhL0xvc19BbmdlbGVzfSwge0Bjb2RlIEdNVC0wODowMH0gb3Ige0Bjb2RlIFVUQ30uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRJRCgpIHsKKyAgICAgICAgcmV0dXJuIElEOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRheWxpZ2h0IHNhdmluZ3Mgb2Zmc2V0IGluIG1pbGxpc2Vjb25kcyBmb3IgdGhpcyB0aW1lIHpvbmUuCisgICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gcmV0dXJucyB7QGNvZGUgMzYwMDAwMH0gKDEgaG91cikgZm9yIHRpbWUgem9uZXMKKyAgICAgKiB0aGF0IHVzZSBkYXlsaWdodCBzYXZpbmdzIHRpbWUgYW5kIHtAY29kZSAwfSBmb3IgdGltZXpvbmVzIHRoYXQgZG8gbm90LgorICAgICAqIFN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIGZvciBvdGhlciBkYXlsaWdodCBzYXZpbmdzCisgICAgICogb2Zmc2V0cy4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB0aGlzIG1ldGhvZCBkb2Vzbid0IHRlbGwgeW91IHdoZXRoZXIgb3Igbm90IHRvIGFwcGx5IHRoZQorICAgICAqIG9mZnNldDogeW91IG5lZWQgdG8gY2FsbCB7QGNvZGUgaW5EYXlsaWdodFRpbWV9IGZvciB0aGUgc3BlY2lmaWMgdGltZQorICAgICAqIHlvdSdyZSBpbnRlcmVzdGVkIGluLiBJZiB0aGlzIG1ldGhvZCByZXR1cm5zIGEgbm9uLXplcm8gb2Zmc2V0LCB0aGF0IG9ubHkKKyAgICAgKiB0ZWxscyB5b3UgdGhhdCB0aGlzIHtAY29kZSBUaW1lWm9uZX0gc29tZXRpbWVzIG9ic2VydmVzIGRheWxpZ2h0IHNhdmluZ3MuCisgICAgICovCisgICAgcHVibGljIGludCBnZXREU1RTYXZpbmdzKCkgeworICAgICAgICByZXR1cm4gdXNlRGF5bGlnaHRUaW1lKCkgPyAzNjAwMDAwIDogMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBvZmZzZXQgaW4gbWlsbGlzZWNvbmRzIGZyb20gVVRDIGZvciB0aGlzIHRpbWUgem9uZSBhdCB7QGNvZGUKKyAgICAgKiB0aW1lfS4gVGhlIG9mZnNldCBpbmNsdWRlcyBkYXlsaWdodCBzYXZpbmdzIHRpbWUgaWYgdGhlIHNwZWNpZmllZAorICAgICAqIGRhdGUgaXMgd2l0aGluIHRoZSBkYXlsaWdodCBzYXZpbmdzIHRpbWUgcGVyaW9kLgorICAgICAqCisgICAgICogQHBhcmFtIHRpbWUgdGhlIGRhdGUgaW4gbWlsbGlzZWNvbmRzIHNpbmNlIEphbnVhcnkgMSwgMTk3MCAwMDowMDowMCBVVEMKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE9mZnNldChsb25nIHRpbWUpIHsKKyAgICAgICAgaWYgKGluRGF5bGlnaHRUaW1lKG5ldyBEYXRlKHRpbWUpKSkgeworICAgICAgICAgICAgcmV0dXJuIGdldFJhd09mZnNldCgpICsgZ2V0RFNUU2F2aW5ncygpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRSYXdPZmZzZXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMgdGltZSB6b25lJ3Mgb2Zmc2V0IGluIG1pbGxpc2Vjb25kcyBmcm9tIFVUQyBhdCB0aGUgc3BlY2lmaWVkCisgICAgICogZGF0ZSBhbmQgdGltZS4gVGhlIG9mZnNldCBpbmNsdWRlcyBkYXlsaWdodCBzYXZpbmdzIHRpbWUgaWYgdGhlIGRhdGUKKyAgICAgKiBhbmQgdGltZSBpcyB3aXRoaW4gdGhlIGRheWxpZ2h0IHNhdmluZ3MgdGltZSBwZXJpb2QuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIGJ5IHtAbGluayBDYWxlbmRhcn0gdG8gY29tcHV0ZQorICAgICAqIHtAbGluayBDYWxlbmRhciNEU1RfT0ZGU0VUfSBhbmQge0BsaW5rIENhbGVuZGFyI1pPTkVfT0ZGU0VUfS4gQXBwbGljYXRpb24KKyAgICAgKiBjb2RlIHNob3VsZCBoYXZlIG5vIHJlYXNvbiB0byBjYWxsIHRoaXMgbWV0aG9kIGRpcmVjdGx5LiBFYWNoIHBhcmFtZXRlcgorICAgICAqIGlzIGludGVycHJldGVkIGluIHRoZSBzYW1lIHdheSBhcyB0aGUgY29ycmVzcG9uZGluZyB7QGNvZGUgQ2FsZW5kYXJ9CisgICAgICogZmllbGQuIFJlZmVyIHRvIHtAbGluayBDYWxlbmRhcn0gZm9yIHNwZWNpZmljIGRlZmluaXRpb25zIG9mIHRoaXMKKyAgICAgKiBtZXRob2QncyBwYXJhbWV0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0T2Zmc2V0KGludCBlcmEsIGludCB5ZWFyLCBpbnQgbW9udGgsIGludCBkYXksCisgICAgICAgICAgICBpbnQgZGF5T2ZXZWVrLCBpbnQgdGltZU9mRGF5TWlsbGlzKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG9mZnNldCBpbiBtaWxsaXNlY29uZHMgZnJvbSBVVEMgb2YgdGhpcyB0aW1lIHpvbmUncyBzdGFuZGFyZAorICAgICAqIHRpbWUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRSYXdPZmZzZXQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgVGltZVpvbmV9IHN1aXRhYmxlIGZvciB7QGNvZGUgaWR9LCBvciB7QGNvZGUgR01UfSBvbiBmYWlsdXJlLgorICAgICAqCisgICAgICogPHA+QW4gaWQgY2FuIGJlIGFuIE9sc29uIG5hbWUgb2YgdGhlIGZvcm0gPGk+QXJlYTwvaT4vPGk+TG9jYXRpb248L2k+LCBzdWNoCisgICAgICogYXMge0Bjb2RlIEFtZXJpY2EvTG9zX0FuZ2VsZXN9LiBUaGUge0BsaW5rICNnZXRBdmFpbGFibGVJRHN9IG1ldGhvZCByZXR1cm5zCisgICAgICogdGhlIHN1cHBvcnRlZCBuYW1lcy4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGNhbiBhbHNvIGNyZWF0ZSBhIGN1c3RvbSB7QGNvZGUgVGltZVpvbmV9IHVzaW5nIHRoZSBmb2xsb3dpbmcKKyAgICAgKiBzeW50YXg6IHtAY29kZSBHTVRbK3wtXWhoW1s6XW1tXX0uIEZvciBleGFtcGxlLCB7QGNvZGUgVGltZVpvbmUuZ2V0VGltZVpvbmUoIkdNVCsxNDowMCIpfQorICAgICAqIHdvdWxkIHJldHVybiBhbiBvYmplY3Qgd2l0aCBhIHJhdyBvZmZzZXQgb2YgKzE0IGhvdXJzIGZyb20gVVRDLCBhbmQgd2hpY2ggZG9lcyA8aT5ub3Q8L2k+CisgICAgICogdXNlIGRheWxpZ2h0IHNhdmluZ3MuIFRoZXNlIGFyZSByYXJlbHkgdXNlZnVsLCBiZWNhdXNlIHRoZXkgZG9uJ3QgY29ycmVzcG9uZCB0byB0aW1lCisgICAgICogem9uZXMgYWN0dWFsbHkgaW4gdXNlLgorICAgICAqCisgICAgICogPHA+T3RoZXIgdGhhbiB0aGUgc3BlY2lhbCBjYXNlcyAiVVRDIiBhbmQgIkdNVCIgKHdoaWNoIGFyZSBzeW5vbnltb3VzIGluIHRoaXMgY29udGV4dCwKKyAgICAgKiBib3RoIGNvcnJlc3BvbmRpbmcgdG8gVVRDKSwgQW5kcm9pZCBkb2VzIG5vdCBzdXBwb3J0IHRoZSBkZXByZWNhdGVkIHRocmVlLWxldHRlciB0aW1lCisgICAgICogem9uZSBJRHMgdXNlZCBpbiBKYXZhIDEuMS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBUaW1lWm9uZSBnZXRUaW1lWm9uZShTdHJpbmcgaWQpIHsKKyAgICAgICAgVGltZVpvbmUgem9uZSA9IFpvbmVJbmZvREIuZ2V0VGltZVpvbmUoaWQpOworICAgICAgICBpZiAoem9uZSAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gem9uZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoem9uZSA9PSBudWxsICYmIGlkLmxlbmd0aCgpID4gMyAmJiBpZC5zdGFydHNXaXRoKCJHTVQiKSkgeworICAgICAgICAgICAgem9uZSA9IGdldEN1c3RvbVRpbWVab25lKGlkKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoem9uZSA9PSBudWxsKSB7CisgICAgICAgICAgICB6b25lID0gKFRpbWVab25lKSBHTVQuY2xvbmUoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gem9uZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IFNpbXBsZVRpbWVab25lIGZvciBhbiBpZCBvZiB0aGUgZm9ybSAiR01UWyt8LV1oaFtbOl1tbV0iLCBvciBudWxsLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFRpbWVab25lIGdldEN1c3RvbVRpbWVab25lKFN0cmluZyBpZCkgeworICAgICAgICBjaGFyIHNpZ24gPSBpZC5jaGFyQXQoMyk7CisgICAgICAgIGlmIChzaWduICE9ICcrJyAmJiBzaWduICE9ICctJykgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgaW50W10gcG9zaXRpb24gPSBuZXcgaW50WzFdOworICAgICAgICBTdHJpbmcgZm9ybWF0dGVkTmFtZSA9IGZvcm1hdFRpbWVab25lTmFtZShpZCwgNCk7CisgICAgICAgIGludCBob3VyID0gcGFyc2VOdW1iZXIoZm9ybWF0dGVkTmFtZSwgNCwgcG9zaXRpb24pOworICAgICAgICBpZiAoaG91ciA8IDAgfHwgaG91ciA+IDIzKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpbnQgaW5kZXggPSBwb3NpdGlvblswXTsKKyAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpbnQgcmF3ID0gaG91ciAqIDM2MDAwMDA7CisgICAgICAgIGlmIChpbmRleCA8IGZvcm1hdHRlZE5hbWUubGVuZ3RoKCkgJiYgZm9ybWF0dGVkTmFtZS5jaGFyQXQoaW5kZXgpID09ICc6JykgeworICAgICAgICAgICAgaW50IG1pbnV0ZSA9IHBhcnNlTnVtYmVyKGZvcm1hdHRlZE5hbWUsIGluZGV4ICsgMSwgcG9zaXRpb24pOworICAgICAgICAgICAgaWYgKHBvc2l0aW9uWzBdID09IC0xIHx8IG1pbnV0ZSA8IDAgfHwgbWludXRlID4gNTkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJhdyArPSBtaW51dGUgKiA2MDAwMDsKKyAgICAgICAgfSBlbHNlIGlmIChob3VyID49IDMwIHx8IGluZGV4ID4gNikgeworICAgICAgICAgICAgcmF3ID0gKGhvdXIgLyAxMDAgKiAzNjAwMDAwKSArIChob3VyICUgMTAwICogNjAwMDApOworICAgICAgICB9CisgICAgICAgIGlmIChzaWduID09ICctJykgeworICAgICAgICAgICAgcmF3ID0gLXJhdzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFNpbXBsZVRpbWVab25lKHJhdywgZm9ybWF0dGVkTmFtZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGZvcm1hdFRpbWVab25lTmFtZShTdHJpbmcgbmFtZSwgaW50IG9mZnNldCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGludCBpbmRleCA9IG9mZnNldCwgbGVuZ3RoID0gbmFtZS5sZW5ndGgoKTsKKyAgICAgICAgYnVmLmFwcGVuZChuYW1lLnN1YnN0cmluZygwLCBvZmZzZXQpKTsKKworICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHsKKyAgICAgICAgICAgIGlmIChDaGFyYWN0ZXIuZGlnaXQobmFtZS5jaGFyQXQoaW5kZXgpLCAxMCkgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICBidWYuYXBwZW5kKG5hbWUuY2hhckF0KGluZGV4KSk7CisgICAgICAgICAgICAgICAgaWYgKChsZW5ndGggLSAoaW5kZXggKyAxKSkgPT0gMikgeworICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCc6Jyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmNoYXJBdChpbmRleCkgPT0gJzonKSB7CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnOicpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW5kZXgrKzsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChidWYudG9TdHJpbmcoKS5pbmRleE9mKCI6IikgPT0gLTEpIHsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJzonKTsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIjAwIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoYnVmLnRvU3RyaW5nKCkuaW5kZXhPZigiOiIpID09IDUpIHsKKyAgICAgICAgICAgIGJ1Zi5pbnNlcnQoNCwgJzAnKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYge0Bjb2RlIHRpbWVab25lfSBoYXMgdGhlIHNhbWUgcnVsZXMgYXMgdGhpcyB0aW1lIHpvbmUuCisgICAgICoKKyAgICAgKiA8cD5UaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHRydWUgaWYgYm90aCB0aW1lIHpvbmVzIGhhdmUgdGhlIHNhbWUKKyAgICAgKiByYXcgb2Zmc2V0LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc1NhbWVSdWxlcyhUaW1lWm9uZSB0aW1lWm9uZSkgeworICAgICAgICBpZiAodGltZVpvbmUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRSYXdPZmZzZXQoKSA9PSB0aW1lWm9uZS5nZXRSYXdPZmZzZXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYge0Bjb2RlIHRpbWV9IGlzIGluIGEgZGF5bGlnaHQgc2F2aW5ncyB0aW1lIHBlcmlvZCBmb3IKKyAgICAgKiB0aGlzIHRpbWUgem9uZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpbkRheWxpZ2h0VGltZShEYXRlIHRpbWUpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHBhcnNlTnVtYmVyKFN0cmluZyBzdHJpbmcsIGludCBvZmZzZXQsIGludFtdIHBvc2l0aW9uKSB7CisgICAgICAgIGludCBpbmRleCA9IG9mZnNldCwgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aCgpLCBkaWdpdCwgcmVzdWx0ID0gMDsKKyAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoCisgICAgICAgICAgICAgICAgJiYgKGRpZ2l0ID0gQ2hhcmFjdGVyLmRpZ2l0KHN0cmluZy5jaGFyQXQoaW5kZXgpLCAxMCkpICE9IC0xKSB7CisgICAgICAgICAgICBpbmRleCsrOworICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICogMTAgKyBkaWdpdDsKKyAgICAgICAgfQorICAgICAgICBwb3NpdGlvblswXSA9IGluZGV4ID09IG9mZnNldCA/IC0xIDogaW5kZXg7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3ZlcnJpZGVzIHRoZSBkZWZhdWx0IHRpbWUgem9uZSBmb3IgdGhlIGN1cnJlbnQgcHJvY2VzcyBvbmx5LgorICAgICAqCisgICAgICogPHA+PHN0cm9uZz5XYXJuaW5nPC9zdHJvbmc+OiBhdm9pZCB1c2luZyB0aGlzIG1ldGhvZCB0byB1c2UgYSBjdXN0b20gdGltZQorICAgICAqIHpvbmUgaW4geW91ciBwcm9jZXNzLiBUaGlzIHZhbHVlIG1heSBiZSBjbGVhcmVkIG9yIG92ZXJ3cml0dGVuIGF0IGFueQorICAgICAqIHRpbWUsIHdoaWNoIGNhbiBjYXVzZSB1bmV4cGVjdGVkIGJlaGF2aW9yLiBJbnN0ZWFkLCBtYW51YWxseSBzdXBwbHkgYQorICAgICAqIGN1c3RvbSB0aW1lIHpvbmUgYXMgbmVlZGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHRpbWVab25lIGEgY3VzdG9tIHRpbWUgem9uZSwgb3Ige0Bjb2RlIG51bGx9IHRvIHNldCB0aGUgZGVmYXVsdCB0bworICAgICAqICAgICB0aGUgdXNlcidzIHByZWZlcnJlZCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCB2b2lkIHNldERlZmF1bHQoVGltZVpvbmUgdGltZVpvbmUpIHsKKyAgICAgICAgZGVmYXVsdFRpbWVab25lID0gdGltZVpvbmUgIT0gbnVsbCA/IChUaW1lWm9uZSkgdGltZVpvbmUuY2xvbmUoKSA6IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgSUQgb2YgdGhpcyB7QGNvZGUgVGltZVpvbmV9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldElEKFN0cmluZyBpZCkgeworICAgICAgICBpZiAoaWQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgSUQgPSBpZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBvZmZzZXQgaW4gbWlsbGlzZWNvbmRzIGZyb20gVVRDIG9mIHRoaXMgdGltZSB6b25lJ3Mgc3RhbmRhcmQKKyAgICAgKiB0aW1lLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFJhd09mZnNldChpbnQgb2Zmc2V0TWlsbGlzKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHRpbWUgem9uZSBoYXMgYSBmdXR1cmUgdHJhbnNpdGlvbiB0byBvciBmcm9tCisgICAgICogZGF5bGlnaHQgc2F2aW5ncyB0aW1lLgorICAgICAqCisgICAgICogPHA+PHN0cm9uZz5XYXJuaW5nOjwvc3Ryb25nPiB0aGlzIHJldHVybnMgZmFsc2UgZm9yIHRpbWUgem9uZXMgbGlrZQorICAgICAqIHtAY29kZSBBc2lhL0t1YWxhX0x1bXB1cn0gdGhhdCBoYXZlIHByZXZpb3VzbHkgdXNlZCBEU1QgYnV0IGRvIG5vdAorICAgICAqIGN1cnJlbnRseS4gQSBoeXBvdGhldGljYWwgY291bnRyeSB0aGF0IGhhcyBuZXZlciBvYnNlcnZlZCBkYXlsaWdodAorICAgICAqIHNhdmluZ3MgYmVmb3JlIGJ1dCBwbGFucyB0byBzdGFydCBuZXh0IHllYXIgd291bGQgcmV0dXJuIHRydWUuCisgICAgICoKKyAgICAgKiA8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IHRoaXMgcmV0dXJucyB0cnVlIGZvciB0aW1lIHpvbmVzIHRoYXQgdXNlCisgICAgICogRFNULCBldmVuIHdoZW4gaXQgaXMgbm90IGFjdGl2ZS4KKyAgICAgKgorICAgICAqIDxwPlVzZSB7QGxpbmsgI2luRGF5bGlnaHRUaW1lfSB0byBmaW5kIG91dCB3aGV0aGVyIGRheWxpZ2h0IHNhdmluZ3MgaXMKKyAgICAgKiBpbiBlZmZlY3QgYXQgYSBzcGVjaWZpYyB0aW1lLgorICAgICAqCisgICAgICogPHA+TW9zdCBhcHBsaWNhdGlvbnMgc2hvdWxkIG5vdCB1c2UgdGhpcyBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gdXNlRGF5bGlnaHRUaW1lKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1RpbWVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1RpbWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjRmN2E4MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvVGltZXIuamF2YQpAQCAtMCwwICsxLDU4OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKKy8qKgorICogVGltZXJzIHNjaGVkdWxlIG9uZS1zaG90IG9yIHJlY3VycmluZyB7QGxpbmsgVGltZXJUYXNrIHRhc2tzfSBmb3IgZXhlY3V0aW9uLgorICogUHJlZmVyIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5TY2hlZHVsZWRUaHJlYWRQb29sRXhlY3V0b3IKKyAqIFNjaGVkdWxlZFRocmVhZFBvb2xFeGVjdXRvcn0gZm9yIG5ldyBjb2RlLgorICoKKyAqIDxwPkVhY2ggdGltZXIgaGFzIG9uZSB0aHJlYWQgb24gd2hpY2ggdGFza3MgYXJlIGV4ZWN1dGVkIHNlcXVlbnRpYWxseS4gV2hlbgorICogdGhpcyB0aHJlYWQgaXMgYnVzeSBydW5uaW5nIGEgdGFzaywgcnVubmFibGUgdGFza3MgbWF5IGJlIHN1YmplY3QgdG8gZGVsYXlzLgorICoKKyAqIDxwPk9uZS1zaG90IGFyZSBzY2hlZHVsZWQgdG8gcnVuIGF0IGFuIGFic29sdXRlIHRpbWUgb3IgYWZ0ZXIgYSByZWxhdGl2ZQorICogZGVsYXkuCisgKgorICogPHA+UmVjdXJyaW5nIHRhc2tzIGFyZSBzY2hlZHVsZWQgd2l0aCBlaXRoZXIgYSBmaXhlZCBwZXJpb2Qgb3IgYSBmaXhlZCByYXRlOgorICogPHVsPgorICogICA8bGk+V2l0aCB0aGUgZGVmYXVsdCA8c3Ryb25nPmZpeGVkLXBlcmlvZCBleGVjdXRpb248L3N0cm9uZz4sIGVhY2gKKyAqICAgICAgIHN1Y2Nlc3NpdmUgcnVuIG9mIGEgdGFzayBpcyBzY2hlZHVsZWQgcmVsYXRpdmUgdG8gdGhlIHN0YXJ0IHRpbWUgb2YKKyAqICAgICAgIHRoZSBwcmV2aW91cyBydW4sIHNvIHR3byBydW5zIGFyZSBuZXZlciBmaXJlZCBjbG9zZXIgdG9nZXRoZXIgaW4gdGltZQorICogICAgICAgdGhhbiB0aGUgc3BlY2lmaWVkIHtAY29kZSBwZXJpb2R9LgorICogICA8bGk+V2l0aCA8c3Ryb25nPmZpeGVkLXJhdGUgZXhlY3V0aW9uPC9zdHJvbmc+LCB0aGUgc3RhcnQgdGltZSBvZiBlYWNoCisgKiAgICAgICBzdWNjZXNzaXZlIHJ1biBvZiBhIHRhc2sgaXMgc2NoZWR1bGVkIHdpdGhvdXQgcmVnYXJkIGZvciB3aGVuIHRoZQorICogICAgICAgcHJldmlvdXMgcnVuIHRvb2sgcGxhY2UuIFRoaXMgbWF5IHJlc3VsdCBpbiBhIHNlcmllcyBvZiBidW5jaGVkLXVwIHJ1bnMKKyAqICAgICAgIChvbmUgbGF1bmNoZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgYW5vdGhlcikgaWYgZGVsYXlzIHByZXZlbnQgdGhlIHRpbWVyCisgKiAgICAgICBmcm9tIHN0YXJ0aW5nIHRhc2tzIG9uIHRpbWUuCisgKiA8L3VsPgorICoKKyAqIDxwPldoZW4gYSB0aW1lciBpcyBubyBsb25nZXIgbmVlZGVkLCB1c2VycyBzaG91bGQgY2FsbCB7QGxpbmsgI2NhbmNlbH0sIHdoaWNoCisgKiByZWxlYXNlcyB0aGUgdGltZXIncyB0aHJlYWQgYW5kIG90aGVyIHJlc291cmNlcy4gVGltZXJzIG5vdCBleHBsaWNpdGx5CisgKiBjYW5jZWxsZWQgbWF5IGhvbGQgcmVzb3VyY2VzIGluZGVmaW5pdGVseS4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGRvZXMgbm90IG9mZmVyIGd1YXJhbnRlZXMgYWJvdXQgdGhlIHJlYWwtdGltZSBuYXR1cmUgb2YgdGFzaworICogc2NoZWR1bGluZy4gTXVsdGlwbGUgdGhyZWFkcyBjYW4gc2hhcmUgYSBzaW5nbGUgdGltZXIgd2l0aG91dAorICogc3luY2hyb25pemF0aW9uLgorICovCitwdWJsaWMgY2xhc3MgVGltZXIgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVGltZXJJbXBsIGV4dGVuZHMgVGhyZWFkIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBUaW1lckhlYXAgeworICAgICAgICAgICAgcHJpdmF0ZSBpbnQgREVGQVVMVF9IRUFQX1NJWkUgPSAyNTY7CisKKyAgICAgICAgICAgIHByaXZhdGUgVGltZXJUYXNrW10gdGltZXJzID0gbmV3IFRpbWVyVGFza1tERUZBVUxUX0hFQVBfU0laRV07CisKKyAgICAgICAgICAgIHByaXZhdGUgaW50IHNpemUgPSAwOworCisgICAgICAgICAgICBwcml2YXRlIGludCBkZWxldGVkQ2FuY2VsbGVkTnVtYmVyID0gMDsKKworICAgICAgICAgICAgcHVibGljIFRpbWVyVGFzayBtaW5pbXVtKCkgeworICAgICAgICAgICAgICAgIHJldHVybiB0aW1lcnNbMF07CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHNpemUgPT0gMDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHZvaWQgaW5zZXJ0KFRpbWVyVGFzayB0YXNrKSB7CisgICAgICAgICAgICAgICAgaWYgKHRpbWVycy5sZW5ndGggPT0gc2l6ZSkgeworICAgICAgICAgICAgICAgICAgICBUaW1lclRhc2tbXSBhcHBlbmRlZFRpbWVycyA9IG5ldyBUaW1lclRhc2tbc2l6ZSAqIDJdOworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRpbWVycywgMCwgYXBwZW5kZWRUaW1lcnMsIDAsIHNpemUpOworICAgICAgICAgICAgICAgICAgICB0aW1lcnMgPSBhcHBlbmRlZFRpbWVyczsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGltZXJzW3NpemUrK10gPSB0YXNrOworICAgICAgICAgICAgICAgIHVwSGVhcCgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBkZWxldGUoaW50IHBvcykgeworICAgICAgICAgICAgICAgIC8vIHBvc2libGUgdG8gZGVsZXRlIGFueSBwb3NpdGlvbiBvZiB0aGUgaGVhcAorICAgICAgICAgICAgICAgIGlmIChwb3MgPj0gMCAmJiBwb3MgPCBzaXplKSB7CisgICAgICAgICAgICAgICAgICAgIHRpbWVyc1twb3NdID0gdGltZXJzWy0tc2l6ZV07CisgICAgICAgICAgICAgICAgICAgIHRpbWVyc1tzaXplXSA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgIGRvd25IZWFwKHBvcyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwcml2YXRlIHZvaWQgdXBIZWFwKCkgeworICAgICAgICAgICAgICAgIGludCBjdXJyZW50ID0gc2l6ZSAtIDE7CisgICAgICAgICAgICAgICAgaW50IHBhcmVudCA9IChjdXJyZW50IC0gMSkgLyAyOworCisgICAgICAgICAgICAgICAgd2hpbGUgKHRpbWVyc1tjdXJyZW50XS53aGVuIDwgdGltZXJzW3BhcmVudF0ud2hlbikgeworICAgICAgICAgICAgICAgICAgICAvLyBzd2FwIHRoZSB0d28KKyAgICAgICAgICAgICAgICAgICAgVGltZXJUYXNrIHRtcCA9IHRpbWVyc1tjdXJyZW50XTsKKyAgICAgICAgICAgICAgICAgICAgdGltZXJzW2N1cnJlbnRdID0gdGltZXJzW3BhcmVudF07CisgICAgICAgICAgICAgICAgICAgIHRpbWVyc1twYXJlbnRdID0gdG1wOworCisgICAgICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSBwb3MgYW5kIGN1cnJlbnQKKyAgICAgICAgICAgICAgICAgICAgY3VycmVudCA9IHBhcmVudDsKKyAgICAgICAgICAgICAgICAgICAgcGFyZW50ID0gKGN1cnJlbnQgLSAxKSAvIDI7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwcml2YXRlIHZvaWQgZG93bkhlYXAoaW50IHBvcykgeworICAgICAgICAgICAgICAgIGludCBjdXJyZW50ID0gcG9zOworICAgICAgICAgICAgICAgIGludCBjaGlsZCA9IDIgKiBjdXJyZW50ICsgMTsKKworICAgICAgICAgICAgICAgIHdoaWxlIChjaGlsZCA8IHNpemUgJiYgc2l6ZSA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gY29tcGFyZSB0aGUgY2hpbGRyZW4gaWYgdGhleSBleGlzdAorICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQgKyAxIDwgc2l6ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHRpbWVyc1tjaGlsZCArIDFdLndoZW4gPCB0aW1lcnNbY2hpbGRdLndoZW4pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkKys7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAvLyBjb21wYXJlIHNlbGVjdGVkIGNoaWxkIHdpdGggcGFyZW50CisgICAgICAgICAgICAgICAgICAgIGlmICh0aW1lcnNbY3VycmVudF0ud2hlbiA8IHRpbWVyc1tjaGlsZF0ud2hlbikgeworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAvLyBzd2FwIHRoZSB0d28KKyAgICAgICAgICAgICAgICAgICAgVGltZXJUYXNrIHRtcCA9IHRpbWVyc1tjdXJyZW50XTsKKyAgICAgICAgICAgICAgICAgICAgdGltZXJzW2N1cnJlbnRdID0gdGltZXJzW2NoaWxkXTsKKyAgICAgICAgICAgICAgICAgICAgdGltZXJzW2NoaWxkXSA9IHRtcDsKKworICAgICAgICAgICAgICAgICAgICAvLyB1cGRhdGUgcG9zIGFuZCBjdXJyZW50CisgICAgICAgICAgICAgICAgICAgIGN1cnJlbnQgPSBjaGlsZDsKKyAgICAgICAgICAgICAgICAgICAgY2hpbGQgPSAyICogY3VycmVudCArIDE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKKyAgICAgICAgICAgICAgICB0aW1lcnMgPSBuZXcgVGltZXJUYXNrW0RFRkFVTFRfSEVBUF9TSVpFXTsKKyAgICAgICAgICAgICAgICBzaXplID0gMDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHZvaWQgYWRqdXN0TWluaW11bSgpIHsKKyAgICAgICAgICAgICAgICBkb3duSGVhcCgwKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHZvaWQgZGVsZXRlSWZDYW5jZWxsZWQoKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHRpbWVyc1tpXS5jYW5jZWxsZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZWRDYW5jZWxsZWROdW1iZXIrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZShpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlLXRyeSB0aGlzIHBvaW50CisgICAgICAgICAgICAgICAgICAgICAgICBpLS07CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHByaXZhdGUgaW50IGdldFRhc2soVGltZXJUYXNrIHRhc2spIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRpbWVycy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBpZiAodGltZXJzW2ldID09IHRhc2spIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRydWUgaWYgdGhlIG1ldGhvZCBjYW5jZWwoKSBvZiB0aGUgVGltZXIgd2FzIGNhbGxlZCBvciB0aGUgISEhc3RvcCgpCisgICAgICAgICAqIG1ldGhvZCB3YXMgaW52b2tlZAorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGNhbmNlbGxlZDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVHJ1ZSBpZiB0aGUgVGltZXIgaGFzIGJlY29tZSBnYXJiYWdlCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGJvb2xlYW4gZmluaXNoZWQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbnRhaW5zIHNjaGVkdWxlZCBldmVudHMsIHNvcnRlZCBhY2NvcmRpbmcgdG8KKyAgICAgICAgICoge0Bjb2RlIHdoZW59IGZpZWxkIG9mIFRhc2tTY2hlZHVsZWQgb2JqZWN0LgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBUaW1lckhlYXAgdGFza3MgPSBuZXcgVGltZXJIZWFwKCk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFN0YXJ0cyBhIG5ldyB0aW1lci4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG5hbWUgdGhyZWFkJ3MgbmFtZQorICAgICAgICAgKiBAcGFyYW0gaXNEYWVtb24gZGFlbW9uIHRocmVhZCBvciBub3QKKyAgICAgICAgICovCisgICAgICAgIFRpbWVySW1wbChTdHJpbmcgbmFtZSwgYm9vbGVhbiBpc0RhZW1vbikgeworICAgICAgICAgICAgdGhpcy5zZXROYW1lKG5hbWUpOworICAgICAgICAgICAgdGhpcy5zZXREYWVtb24oaXNEYWVtb24pOworICAgICAgICAgICAgdGhpcy5zdGFydCgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoaXMgbWV0aG9kIHdpbGwgYmUgbGF1bmNoZWQgb24gc2VwYXJhdGUgdGhyZWFkIGZvciBlYWNoIFRpbWVyCisgICAgICAgICAqIG9iamVjdC4KKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgIFRpbWVyVGFzayB0YXNrOworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgICAgICAgICAvLyBuZWVkIHRvIGNoZWNrIGNhbmNlbGxlZCBpbnNpZGUgdGhlIHN5bmNocm9uaXplZCBibG9jaworICAgICAgICAgICAgICAgICAgICBpZiAoY2FuY2VsbGVkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKHRhc2tzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmlzaGVkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm8gdGFza3Mgc2NoZWR1bGVkIC0tIHNsZWVwIHVudGlsIGFueSB0YXNrIGFwcGVhcgorICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndhaXQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgbG9uZyBjdXJyZW50VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworCisgICAgICAgICAgICAgICAgICAgIHRhc2sgPSB0YXNrcy5taW5pbXVtKCk7CisgICAgICAgICAgICAgICAgICAgIGxvbmcgdGltZVRvU2xlZXA7CisKKyAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICh0YXNrLmxvY2spIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXNrLmNhbmNlbGxlZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tzLmRlbGV0ZSgwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhlIHRpbWUgdG8gc2xlZXAgZm9yIHRoZSBmaXJzdCB0YXNrIHNjaGVkdWxlZAorICAgICAgICAgICAgICAgICAgICAgICAgdGltZVRvU2xlZXAgPSB0YXNrLndoZW4gLSBjdXJyZW50VGltZTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGlmICh0aW1lVG9TbGVlcCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNsZWVwIQorICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndhaXQodGltZVRvU2xlZXApOworICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAvLyBubyBzbGVlcCBpcyBuZWNlc3NhcnkgYmVmb3JlIGxhdW5jaGluZyB0aGUgdGFzaworCisgICAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGFzay5sb2NrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnQgcG9zID0gMDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXNrcy5taW5pbXVtKCkud2hlbiAhPSB0YXNrLndoZW4pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MgPSB0YXNrcy5nZXRUYXNrKHRhc2spOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRhc2suY2FuY2VsbGVkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFza3MuZGVsZXRlKHRhc2tzLmdldFRhc2sodGFzaykpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBzZXQgdGltZSB0byBzY2hlZHVsZQorICAgICAgICAgICAgICAgICAgICAgICAgdGFzay5zZXRTY2hlZHVsZWRUaW1lKHRhc2sud2hlbik7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB0YXNrIGZyb20gcXVldWUKKyAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tzLmRlbGV0ZShwb3MpOworCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBzZXQgd2hlbiB0aGUgbmV4dCB0YXNrIHNob3VsZCBiZSBsYXVuY2hlZAorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRhc2sucGVyaW9kID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIGEgcmVwZWF0aW5nIHRhc2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRhc2suZml4ZWRSYXRlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRhc2sgaXMgc2NoZWR1bGVkIGF0IGZpeGVkIHJhdGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFzay53aGVuID0gdGFzay53aGVuICsgdGFzay5wZXJpb2Q7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGFzayBpcyBzY2hlZHVsZWQgYXQgZml4ZWQgZGVsYXkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFzay53aGVuID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHRhc2sucGVyaW9kOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluc2VydCB0aGlzIHRhc2sgaW50byBxdWV1ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc2VydFRhc2sodGFzayk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhc2sud2hlbiA9IDA7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBib29sZWFuIHRhc2tDb21wbGV0ZWROb3JtYWxseSA9IGZhbHNlOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHRhc2sucnVuKCk7CisgICAgICAgICAgICAgICAgICAgIHRhc2tDb21wbGV0ZWROb3JtYWxseSA9IHRydWU7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCF0YXNrQ29tcGxldGVkTm9ybWFsbHkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbmNlbGxlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgaW5zZXJ0VGFzayhUaW1lclRhc2sgbmV3VGFzaykgeworICAgICAgICAgICAgLy8gY2FsbGVycyBhcmUgc3luY2hyb25pemVkCisgICAgICAgICAgICB0YXNrcy5pbnNlcnQobmV3VGFzayk7CisgICAgICAgICAgICB0aGlzLm5vdGlmeSgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENhbmNlbHMgdGltZXIuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2FuY2VsKCkgeworICAgICAgICAgICAgY2FuY2VsbGVkID0gdHJ1ZTsKKyAgICAgICAgICAgIHRhc2tzLnJlc2V0KCk7CisgICAgICAgICAgICB0aGlzLm5vdGlmeSgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBwdXJnZSgpIHsKKyAgICAgICAgICAgIGlmICh0YXNrcy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIGNhbGxlcnMgYXJlIHN5bmNocm9uaXplZAorICAgICAgICAgICAgdGFza3MuZGVsZXRlZENhbmNlbGxlZE51bWJlciA9IDA7CisgICAgICAgICAgICB0YXNrcy5kZWxldGVJZkNhbmNlbGxlZCgpOworICAgICAgICAgICAgcmV0dXJuIHRhc2tzLmRlbGV0ZWRDYW5jZWxsZWROdW1iZXI7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpbmFsaXplckhlbHBlciB7CisgICAgICAgIHByaXZhdGUgZmluYWwgVGltZXJJbXBsIGltcGw7CisKKyAgICAgICAgRmluYWxpemVySGVscGVyKFRpbWVySW1wbCBpbXBsKSB7CisgICAgICAgICAgICB0aGlzLmltcGwgPSBpbXBsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoaW1wbCkgeworICAgICAgICAgICAgICAgICAgICBpbXBsLmZpbmlzaGVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgaW1wbC5ub3RpZnkoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHN1cGVyLmZpbmFsaXplKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBsb25nIHRpbWVySWQ7CisKKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCBzdGF0aWMgbG9uZyBuZXh0SWQoKSB7CisgICAgICAgIHJldHVybiB0aW1lcklkKys7CisgICAgfQorCisgICAgLyogVGhpcyBvYmplY3Qgd2lsbCBiZSB1c2VkIGluIHN5bmNocm9uaXphdGlvbiBwdXJwb3NlcyAqLworICAgIHByaXZhdGUgZmluYWwgVGltZXJJbXBsIGltcGw7CisKKyAgICAvLyBVc2VkIHRvIGZpbmFsaXplIHRocmVhZAorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgIHByaXZhdGUgZmluYWwgRmluYWxpemVySGVscGVyIGZpbmFsaXplcjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgbmFtZWQge0Bjb2RlIFRpbWVyfSB3aGljaCBtYXkgYmUgc3BlY2lmaWVkIHRvIGJlIHJ1biBhcyBhCisgICAgICogZGFlbW9uIHRocmVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSB7QGNvZGUgVGltZXJ9LgorICAgICAqIEBwYXJhbSBpc0RhZW1vbiB0cnVlIGlmIHtAY29kZSBUaW1lcn0ncyB0aHJlYWQgc2hvdWxkIGJlIGEgZGFlbW9uIHRocmVhZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlzIHtAY29kZSBuYW1lfSBpcyB7QGNvZGUgbnVsbH0KKyAgICAgKi8KKyAgICBwdWJsaWMgVGltZXIoU3RyaW5nIG5hbWUsIGJvb2xlYW4gaXNEYWVtb24pIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJuYW1lIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmltcGwgPSBuZXcgVGltZXJJbXBsKG5hbWUsIGlzRGFlbW9uKTsKKyAgICAgICAgdGhpcy5maW5hbGl6ZXIgPSBuZXcgRmluYWxpemVySGVscGVyKGltcGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgbmFtZWQge0Bjb2RlIFRpbWVyfSB3aGljaCBkb2VzIG5vdCBydW4gYXMgYSBkYWVtb24gdGhyZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhlIFRpbWVyLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaXMge0Bjb2RlIG5hbWV9IGlzIHtAY29kZSBudWxsfQorICAgICAqLworICAgIHB1YmxpYyBUaW1lcihTdHJpbmcgbmFtZSkgeworICAgICAgICB0aGlzKG5hbWUsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBUaW1lcn0gd2hpY2ggbWF5IGJlIHNwZWNpZmllZCB0byBiZSBydW4gYXMgYSBkYWVtb24gdGhyZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIGlzRGFlbW9uIHtAY29kZSB0cnVlfSBpZiB0aGUge0Bjb2RlIFRpbWVyfSdzIHRocmVhZCBzaG91bGQgYmUgYSBkYWVtb24gdGhyZWFkLgorICAgICAqLworICAgIHB1YmxpYyBUaW1lcihib29sZWFuIGlzRGFlbW9uKSB7CisgICAgICAgIHRoaXMoIlRpbWVyLSIgKyBUaW1lci5uZXh0SWQoKSwgaXNEYWVtb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgbm9uLWRhZW1vbiB7QGNvZGUgVGltZXJ9LgorICAgICAqLworICAgIHB1YmxpYyBUaW1lcigpIHsKKyAgICAgICAgdGhpcyhmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FuY2VscyB0aGUge0Bjb2RlIFRpbWVyfSBhbmQgYWxsIHNjaGVkdWxlZCB0YXNrcy4gSWYgdGhlcmUgaXMgYQorICAgICAqIGN1cnJlbnRseSBydW5uaW5nIHRhc2sgaXQgaXMgbm90IGFmZmVjdGVkLiBObyBtb3JlIHRhc2tzIG1heSBiZSBzY2hlZHVsZWQKKyAgICAgKiBvbiB0aGlzIHtAY29kZSBUaW1lcn0uIFN1YnNlcXVlbnQgY2FsbHMgZG8gbm90aGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjYW5jZWwoKSB7CisgICAgICAgIGltcGwuY2FuY2VsKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhbGwgY2FuY2VsZWQgdGFza3MgZnJvbSB0aGUgdGFzayBxdWV1ZS4gSWYgdGhlcmUgYXJlIG5vCisgICAgICogb3RoZXIgcmVmZXJlbmNlcyBvbiB0aGUgdGFza3MsIHRoZW4gYWZ0ZXIgdGhpcyBjYWxsIHRoZXkgYXJlIGZyZWUKKyAgICAgKiB0byBiZSBnYXJiYWdlIGNvbGxlY3RlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBjYW5jZWxlZCB0YXNrcyB0aGF0IHdlcmUgcmVtb3ZlZCBmcm9tIHRoZSB0YXNrCisgICAgICogICAgICAgICBxdWV1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHB1cmdlKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGltcGwpIHsKKyAgICAgICAgICAgIHJldHVybiBpbXBsLnB1cmdlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTY2hlZHVsZSBhIHRhc2sgZm9yIHNpbmdsZSBleGVjdXRpb24uIElmIHtAY29kZSB3aGVufSBpcyBsZXNzIHRoYW4gdGhlCisgICAgICogY3VycmVudCB0aW1lLCBpdCB3aWxsIGJlIHNjaGVkdWxlZCB0byBiZSBleGVjdXRlZCBhcyBzb29uIGFzIHBvc3NpYmxlLgorICAgICAqCisgICAgICogQHBhcmFtIHRhc2sKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXNrIHRvIHNjaGVkdWxlLgorICAgICAqIEBwYXJhbSB3aGVuCisgICAgICogICAgICAgICAgICB0aW1lIG9mIGV4ZWN1dGlvbi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSB3aGVuLmdldFRpbWUoKSA8IDB9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBUaW1lcn0gaGFzIGJlZW4gY2FuY2VsZWQsIG9yIGlmIHRoZSB0YXNrIGhhcyBiZWVuCisgICAgICogICAgICAgICAgICAgICAgc2NoZWR1bGVkIG9yIGNhbmNlbGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNjaGVkdWxlKFRpbWVyVGFzayB0YXNrLCBEYXRlIHdoZW4pIHsKKyAgICAgICAgaWYgKHdoZW4uZ2V0VGltZSgpIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGxvbmcgZGVsYXkgPSB3aGVuLmdldFRpbWUoKSAtIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICBzY2hlZHVsZUltcGwodGFzaywgZGVsYXkgPCAwID8gMCA6IGRlbGF5LCAtMSwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNjaGVkdWxlIGEgdGFzayBmb3Igc2luZ2xlIGV4ZWN1dGlvbiBhZnRlciBhIHNwZWNpZmllZCBkZWxheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YXNrCisgICAgICogICAgICAgICAgICB0aGUgdGFzayB0byBzY2hlZHVsZS4KKyAgICAgKiBAcGFyYW0gZGVsYXkKKyAgICAgKiAgICAgICAgICAgIGFtb3VudCBvZiB0aW1lIGluIG1pbGxpc2Vjb25kcyBiZWZvcmUgZXhlY3V0aW9uLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGRlbGF5IDwgMH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIFRpbWVyfSBoYXMgYmVlbiBjYW5jZWxlZCwgb3IgaWYgdGhlIHRhc2sgaGFzIGJlZW4KKyAgICAgKiAgICAgICAgICAgICAgICBzY2hlZHVsZWQgb3IgY2FuY2VsZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2NoZWR1bGUoVGltZXJUYXNrIHRhc2ssIGxvbmcgZGVsYXkpIHsKKyAgICAgICAgaWYgKGRlbGF5IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHNjaGVkdWxlSW1wbCh0YXNrLCBkZWxheSwgLTEsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTY2hlZHVsZSBhIHRhc2sgZm9yIHJlcGVhdGVkIGZpeGVkLWRlbGF5IGV4ZWN1dGlvbiBhZnRlciBhIHNwZWNpZmljIGRlbGF5LgorICAgICAqCisgICAgICogQHBhcmFtIHRhc2sKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXNrIHRvIHNjaGVkdWxlLgorICAgICAqIEBwYXJhbSBkZWxheQorICAgICAqICAgICAgICAgICAgYW1vdW50IG9mIHRpbWUgaW4gbWlsbGlzZWNvbmRzIGJlZm9yZSBmaXJzdCBleGVjdXRpb24uCisgICAgICogQHBhcmFtIHBlcmlvZAorICAgICAqICAgICAgICAgICAgYW1vdW50IG9mIHRpbWUgaW4gbWlsbGlzZWNvbmRzIGJldHdlZW4gc3Vic2VxdWVudCBleGVjdXRpb25zLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGRlbGF5IDwgMH0gb3Ige0Bjb2RlIHBlcmlvZCA8PSAwfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgVGltZXJ9IGhhcyBiZWVuIGNhbmNlbGVkLCBvciBpZiB0aGUgdGFzayBoYXMgYmVlbgorICAgICAqICAgICAgICAgICAgICAgIHNjaGVkdWxlZCBvciBjYW5jZWxlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzY2hlZHVsZShUaW1lclRhc2sgdGFzaywgbG9uZyBkZWxheSwgbG9uZyBwZXJpb2QpIHsKKyAgICAgICAgaWYgKGRlbGF5IDwgMCB8fCBwZXJpb2QgPD0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHNjaGVkdWxlSW1wbCh0YXNrLCBkZWxheSwgcGVyaW9kLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2NoZWR1bGUgYSB0YXNrIGZvciByZXBlYXRlZCBmaXhlZC1kZWxheSBleGVjdXRpb24gYWZ0ZXIgYSBzcGVjaWZpYyB0aW1lCisgICAgICogaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YXNrCisgICAgICogICAgICAgICAgICB0aGUgdGFzayB0byBzY2hlZHVsZS4KKyAgICAgKiBAcGFyYW0gd2hlbgorICAgICAqICAgICAgICAgICAgdGltZSBvZiBmaXJzdCBleGVjdXRpb24uCisgICAgICogQHBhcmFtIHBlcmlvZAorICAgICAqICAgICAgICAgICAgYW1vdW50IG9mIHRpbWUgaW4gbWlsbGlzZWNvbmRzIGJldHdlZW4gc3Vic2VxdWVudCBleGVjdXRpb25zLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHdoZW4uZ2V0VGltZSgpIDwgMH0gb3Ige0Bjb2RlIHBlcmlvZCA8PSAwfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgVGltZXJ9IGhhcyBiZWVuIGNhbmNlbGVkLCBvciBpZiB0aGUgdGFzayBoYXMgYmVlbgorICAgICAqICAgICAgICAgICAgICAgIHNjaGVkdWxlZCBvciBjYW5jZWxlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzY2hlZHVsZShUaW1lclRhc2sgdGFzaywgRGF0ZSB3aGVuLCBsb25nIHBlcmlvZCkgeworICAgICAgICBpZiAocGVyaW9kIDw9IDAgfHwgd2hlbi5nZXRUaW1lKCkgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgbG9uZyBkZWxheSA9IHdoZW4uZ2V0VGltZSgpIC0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgIHNjaGVkdWxlSW1wbCh0YXNrLCBkZWxheSA8IDAgPyAwIDogZGVsYXksIHBlcmlvZCwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNjaGVkdWxlIGEgdGFzayBmb3IgcmVwZWF0ZWQgZml4ZWQtcmF0ZSBleGVjdXRpb24gYWZ0ZXIgYSBzcGVjaWZpYyBkZWxheQorICAgICAqIGhhcyBwYXNzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGFzaworICAgICAqICAgICAgICAgICAgdGhlIHRhc2sgdG8gc2NoZWR1bGUuCisgICAgICogQHBhcmFtIGRlbGF5CisgICAgICogICAgICAgICAgICBhbW91bnQgb2YgdGltZSBpbiBtaWxsaXNlY29uZHMgYmVmb3JlIGZpcnN0IGV4ZWN1dGlvbi4KKyAgICAgKiBAcGFyYW0gcGVyaW9kCisgICAgICogICAgICAgICAgICBhbW91bnQgb2YgdGltZSBpbiBtaWxsaXNlY29uZHMgYmV0d2VlbiBzdWJzZXF1ZW50IGV4ZWN1dGlvbnMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgZGVsYXkgPCAwfSBvciB7QGNvZGUgcGVyaW9kIDw9IDB9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBUaW1lcn0gaGFzIGJlZW4gY2FuY2VsZWQsIG9yIGlmIHRoZSB0YXNrIGhhcyBiZWVuCisgICAgICogICAgICAgICAgICAgICAgc2NoZWR1bGVkIG9yIGNhbmNlbGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNjaGVkdWxlQXRGaXhlZFJhdGUoVGltZXJUYXNrIHRhc2ssIGxvbmcgZGVsYXksIGxvbmcgcGVyaW9kKSB7CisgICAgICAgIGlmIChkZWxheSA8IDAgfHwgcGVyaW9kIDw9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBzY2hlZHVsZUltcGwodGFzaywgZGVsYXksIHBlcmlvZCwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2NoZWR1bGUgYSB0YXNrIGZvciByZXBlYXRlZCBmaXhlZC1yYXRlIGV4ZWN1dGlvbiBhZnRlciBhIHNwZWNpZmljIHRpbWUKKyAgICAgKiBoYXMgYmVlbiByZWFjaGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHRhc2sKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXNrIHRvIHNjaGVkdWxlLgorICAgICAqIEBwYXJhbSB3aGVuCisgICAgICogICAgICAgICAgICB0aW1lIG9mIGZpcnN0IGV4ZWN1dGlvbi4KKyAgICAgKiBAcGFyYW0gcGVyaW9kCisgICAgICogICAgICAgICAgICBhbW91bnQgb2YgdGltZSBpbiBtaWxsaXNlY29uZHMgYmV0d2VlbiBzdWJzZXF1ZW50IGV4ZWN1dGlvbnMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgd2hlbi5nZXRUaW1lKCkgPCAwfSBvciB7QGNvZGUgcGVyaW9kIDw9IDB9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBUaW1lcn0gaGFzIGJlZW4gY2FuY2VsZWQsIG9yIGlmIHRoZSB0YXNrIGhhcyBiZWVuCisgICAgICogICAgICAgICAgICAgICAgc2NoZWR1bGVkIG9yIGNhbmNlbGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNjaGVkdWxlQXRGaXhlZFJhdGUoVGltZXJUYXNrIHRhc2ssIERhdGUgd2hlbiwgbG9uZyBwZXJpb2QpIHsKKyAgICAgICAgaWYgKHBlcmlvZCA8PSAwIHx8IHdoZW4uZ2V0VGltZSgpIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGxvbmcgZGVsYXkgPSB3aGVuLmdldFRpbWUoKSAtIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICBzY2hlZHVsZUltcGwodGFzaywgZGVsYXksIHBlcmlvZCwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBTY2hlZHVsZSBhIHRhc2suCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNjaGVkdWxlSW1wbChUaW1lclRhc2sgdGFzaywgbG9uZyBkZWxheSwgbG9uZyBwZXJpb2QsIGJvb2xlYW4gZml4ZWQpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChpbXBsKSB7CisgICAgICAgICAgICBpZiAoaW1wbC5jYW5jZWxsZWQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJUaW1lciB3YXMgY2FuY2VsZWQiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgbG9uZyB3aGVuID0gZGVsYXkgKyBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKworICAgICAgICAgICAgaWYgKHdoZW4gPCAwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSWxsZWdhbCBkZWxheSB0byBzdGFydCB0aGUgVGltZXJUYXNrOiAiICsgd2hlbik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGFzay5sb2NrKSB7CisgICAgICAgICAgICAgICAgaWYgKHRhc2suaXNTY2hlZHVsZWQoKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJUaW1lclRhc2sgaXMgc2NoZWR1bGVkIGFscmVhZHkiKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAodGFzay5jYW5jZWxsZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVGltZXJUYXNrIGlzIGNhbmNlbGVkIik7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdGFzay53aGVuID0gd2hlbjsKKyAgICAgICAgICAgICAgICB0YXNrLnBlcmlvZCA9IHBlcmlvZDsKKyAgICAgICAgICAgICAgICB0YXNrLmZpeGVkUmF0ZSA9IGZpeGVkOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBpbnNlcnQgdGhlIG5ld1Rhc2sgaW50byBxdWV1ZQorICAgICAgICAgICAgaW1wbC5pbnNlcnRUYXNrKHRhc2spOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9UaW1lclRhc2suamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvVGltZXJUYXNrLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmIxMjE2OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvVGltZXJUYXNrLmphdmEKQEAgLTAsMCArMSwxMTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCisvKioKKyAqIFRoZSB7QGNvZGUgVGltZXJUYXNrfSBjbGFzcyByZXByZXNlbnRzIGEgdGFzayB0byBydW4gYXQgYSBzcGVjaWZpZWQgdGltZS4gVGhlIHRhc2sKKyAqIG1heSBiZSBydW4gb25jZSBvciByZXBlYXRlZGx5LgorICoKKyAqIEBzZWUgVGltZXIKKyAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCN3YWl0KGxvbmcpCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBUaW1lclRhc2sgaW1wbGVtZW50cyBSdW5uYWJsZSB7CisgICAgLyogTG9jayBvYmplY3QgZm9yIHN5bmNocm9uaXphdGlvbi4gSXQncyBhbHNvIHVzZWQgYnkgVGltZXIgY2xhc3MuICovCisgICAgZmluYWwgT2JqZWN0IGxvY2sgPSBuZXcgT2JqZWN0KCk7CisKKyAgICAvKiBJZiB0aW1lciB3YXMgY2FuY2VsbGVkICovCisgICAgYm9vbGVhbiBjYW5jZWxsZWQ7CisKKyAgICAvKiBTbG90cyB1c2VkIGJ5IFRpbWVyICovCisgICAgbG9uZyB3aGVuOworCisgICAgbG9uZyBwZXJpb2Q7CisKKyAgICBib29sZWFuIGZpeGVkUmF0ZTsKKworICAgIC8qCisgICAgICogVGhlIHRpbWUgd2hlbiB0YXNrIHdpbGwgYmUgZXhlY3V0ZWQsIG9yIHRoZSB0aW1lIHdoZW4gdGFzayB3YXMgbGF1bmNoZWQKKyAgICAgKiBpZiB0aGlzIGlzIHRhc2sgaW4gcHJvZ3Jlc3MuCisgICAgICovCisgICAgcHJpdmF0ZSBsb25nIHNjaGVkdWxlZFRpbWU7CisKKyAgICAvKgorICAgICAqIE1ldGhvZCBjYWxsZWQgZnJvbSB0aGUgVGltZXIgZm9yIHN5bmNocm9uaXplZCBnZXR0aW5nIG9mIHdoZW4gZmllbGQuCisgICAgICovCisgICAgbG9uZyBnZXRXaGVuKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIHJldHVybiB3aGVuOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBNZXRob2QgY2FsbGVkIGZyb20gdGhlIFRpbWVyIG9iamVjdCB3aGVuIHNjaGVkdWxpbmcgYW4gZXZlbnQgQHBhcmFtIHRpbWUKKyAgICAgKi8KKyAgICB2b2lkIHNldFNjaGVkdWxlZFRpbWUobG9uZyB0aW1lKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgc2NoZWR1bGVkVGltZSA9IHRpbWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIElzIFRpbWVyVGFzayBzY2hlZHVsZWQgaW50byBhbnkgdGltZXI/CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgdGltZXIgdGFzayBpcyBzY2hlZHVsZWQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiBvdGhlcndpc2UuCisgICAgICovCisgICAgYm9vbGVhbiBpc1NjaGVkdWxlZCgpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICByZXR1cm4gd2hlbiA+IDAgfHwgc2NoZWR1bGVkVGltZSA+IDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBUaW1lclRhc2t9LgorICAgICAqLworICAgIHByb3RlY3RlZCBUaW1lclRhc2soKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FuY2VscyB0aGUge0Bjb2RlIFRpbWVyVGFza30gYW5kIHJlbW92ZXMgaXQgZnJvbSB0aGUge0Bjb2RlIFRpbWVyfSdzIHF1ZXVlLiBHZW5lcmFsbHksIGl0CisgICAgICogcmV0dXJucyB7QGNvZGUgZmFsc2V9IGlmIHRoZSBjYWxsIGRpZCBub3QgcHJldmVudCBhIHtAY29kZSBUaW1lclRhc2t9IGZyb20gcnVubmluZyBhdAorICAgICAqIGxlYXN0IG9uY2UuIFN1YnNlcXVlbnQgY2FsbHMgaGF2ZSBubyBlZmZlY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgY2FsbCBwcmV2ZW50ZWQgYSBzY2hlZHVsZWQgZXhlY3V0aW9uCisgICAgICogICAgICAgICBmcm9tIHRha2luZyBwbGFjZSwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY2FuY2VsKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGJvb2xlYW4gd2lsbFJ1biA9ICFjYW5jZWxsZWQgJiYgd2hlbiA+IDA7CisgICAgICAgICAgICBjYW5jZWxsZWQgPSB0cnVlOworICAgICAgICAgICAgcmV0dXJuIHdpbGxSdW47CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzY2hlZHVsZWQgZXhlY3V0aW9uIHRpbWUuIElmIHRoZSB0YXNrIGV4ZWN1dGlvbiBpcyBpbgorICAgICAqIHByb2dyZXNzIGl0IHJldHVybnMgdGhlIGV4ZWN1dGlvbiB0aW1lIG9mIHRoZSBvbmdvaW5nIHRhc2suIFRhc2tzIHdoaWNoCisgICAgICogaGF2ZSBub3QgeWV0IHJ1biByZXR1cm4gYW4gdW5kZWZpbmVkIHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbW9zdCByZWNlbnQgZXhlY3V0aW9uIHRpbWUuCisgICAgICovCisgICAgcHVibGljIGxvbmcgc2NoZWR1bGVkRXhlY3V0aW9uVGltZSgpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICByZXR1cm4gc2NoZWR1bGVkVGltZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSB0YXNrIHRvIHJ1biBzaG91bGQgYmUgc3BlY2lmaWVkIGluIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUge0Bjb2RlIHJ1bigpfQorICAgICAqIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBydW4oKTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9Ub29NYW55TGlzdGVuZXJzRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1Rvb01hbnlMaXN0ZW5lcnNFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMjExNDY3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9Ub29NYW55TGlzdGVuZXJzRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKKworLyoqCisgKiBBIHtAY29kZSBUb29NYW55TGlzdGVuZXJzRXhjZXB0aW9ufSBpcyB0aHJvd24gd2hlbiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gYWRkCisgKiBtb3JlIHRoYW4gb25lIGxpc3RlbmVyIHRvIGFuIGV2ZW50IHNvdXJjZSB3aGljaCBvbmx5IHN1cHBvcnRzIGEgc2luZ2xlCisgKiBsaXN0ZW5lci4gSXQgaXMgYWxzbyB0aHJvd24gd2hlbiB0aGUgc2FtZSBsaXN0ZW5lciBpcyBhZGRlZCBtb3JlIHRoYW4gb25jZS4KKyAqLworcHVibGljIGNsYXNzIFRvb01hbnlMaXN0ZW5lcnNFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTA3NDY0MDU0NDc3MDY4NzgzMUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBUb29NYW55TGlzdGVuZXJzRXhjZXB0aW9ufSB3aXRoIHRoZSBjdXJyZW50IHN0YWNrCisgICAgICogdHJhY2UgZmlsbGVkIGluLgorICAgICAqLworICAgIHB1YmxpYyBUb29NYW55TGlzdGVuZXJzRXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFRvb01hbnlMaXN0ZW5lcnNFeGNlcHRpb259IHdpdGggdGhlIHN0YWNrIHRyYWNlCisgICAgICogYW5kIG1lc3NhZ2UgZmlsbGVkIGluLgorICAgICAqCisgICAgICogQHBhcmFtIGRldGFpbE1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgVG9vTWFueUxpc3RlbmVyc0V4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvVHJlZU1hcC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9UcmVlTWFwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzgwOTExMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvVHJlZU1hcC5qYXZhCkBAIC0wLDAgKzEsMTc1NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0uR2V0RmllbGQ7CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgc3RhdGljIGphdmEudXRpbC5UcmVlTWFwLkJvdW5kLio7CitpbXBvcnQgc3RhdGljIGphdmEudXRpbC5UcmVlTWFwLlJlbGF0aW9uLio7CitpbXBvcnQgbGliY29yZS51dGlsLk9iamVjdHM7CisKKy8qKgorICogQSBtYXAgd2hvc2UgZW50cmllcyBhcmUgc29ydGVkIGJ5IHRoZWlyIGtleXMuIEFsbCBvcHRpb25hbCBvcGVyYXRpb25zIHN1Y2ggYXMKKyAqIHtAbGluayAjcHV0fSBhbmQge0BsaW5rICNyZW1vdmV9IGFyZSBzdXBwb3J0ZWQuCisgKgorICogPHA+VGhpcyBtYXAgc29ydHMga2V5cyB1c2luZyBlaXRoZXIgYSB1c2VyLXN1cHBsaWVkIGNvbXBhcmF0b3Igb3IgdGhlIGtleSdzCisgKiBuYXR1cmFsIG9yZGVyOgorICogPHVsPgorICogICA8bGk+VXNlciBzdXBwbGllZCBjb21wYXJhdG9ycyBtdXN0IGJlIGFibGUgdG8gY29tcGFyZSBhbnkgcGFpciBvZiBrZXlzIGluCisgKiAgICAgICB0aGlzIG1hcC4gSWYgYSB1c2VyLXN1cHBsaWVkIGNvbXBhcmF0b3IgaXMgaW4gdXNlLCBpdCB3aWxsIGJlIHJldHVybmVkCisgKiAgICAgICBieSB7QGxpbmsgI2NvbXBhcmF0b3J9LgorICogICA8bGk+SWYgbm8gdXNlci1zdXBwbGllZCBjb21wYXJhdG9yIGlzIHN1cHBsaWVkLCBrZXlzIHdpbGwgYmUgc29ydGVkIGJ5CisgKiAgICAgICB0aGVpciBuYXR1cmFsIG9yZGVyLiBLZXlzIG11c3QgYmUgPGk+bXV0dWFsbHkgY29tcGFyYWJsZTwvaT46IHRoZXkgbXVzdAorICogICAgICAgaW1wbGVtZW50IHtAbGluayBDb21wYXJhYmxlfSBhbmQge0BsaW5rIENvbXBhcmFibGUjY29tcGFyZVRvCisgKiAgICAgICBjb21wYXJlVG8oKX0gbXVzdCBiZSBhYmxlIHRvIGNvbXBhcmUgZWFjaCBrZXkgd2l0aCBhbnkgb3RoZXIga2V5IGluCisgKiAgICAgICB0aGlzIG1hcC4gSW4gdGhpcyBjYXNlIHtAbGluayAjY29tcGFyYXRvcn0gd2lsbCByZXR1cm4gbnVsbC4KKyAqIDwvdWw+CisgKiBXaXRoIGVpdGhlciBhIGNvbXBhcmF0b3Igb3IgYSBuYXR1cmFsIG9yZGVyaW5nLCBjb21wYXJpc29ucyBzaG91bGQgYmUKKyAqIDxpPmNvbnNpc3RlbnQgd2l0aCBlcXVhbHM8L2k+LiBBbiBvcmRlcmluZyBpcyBjb25zaXN0ZW50IHdpdGggZXF1YWxzIGlmIGZvcgorICogZXZlcnkgcGFpciBvZiBrZXlzIHtAY29kZSBhfSBhbmQge0Bjb2RlIGJ9LCB7QGNvZGUgYS5lcXVhbHMoYil9IGlmIGFuZCBvbmx5CisgKiBpZiB7QGNvZGUgY29tcGFyZShhLCBiKSA9PSAwfS4KKyAqCisgKiA8cD5XaGVuIHRoZSBvcmRlcmluZyBpcyBub3QgY29uc2lzdGVudCB3aXRoIGVxdWFscyB0aGUgYmVoYXZpb3Igb2YgdGhpcworICogY2xhc3MgaXMgd2VsbCBkZWZpbmVkIGJ1dCBkb2VzIG5vdCBob25vciB0aGUgY29udHJhY3Qgc3BlY2lmaWVkIGJ5IHtAbGluaworICogTWFwfS4gQ29uc2lkZXIgYSB0cmVlIG1hcCBvZiBjYXNlLWluc2Vuc2l0aXZlIHN0cmluZ3MsIGFuIG9yZGVyaW5nIHRoYXQgaXMKKyAqIG5vdCBjb25zaXN0ZW50IHdpdGggZXF1YWxzOiA8cHJlPiAgIHtAY29kZQorICogICBUcmVlTWFwPFN0cmluZywgU3RyaW5nPiBtYXAgPSBuZXcgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4oU3RyaW5nLkNBU0VfSU5TRU5TSVRJVkVfT1JERVIpOworICogICBtYXAucHV0KCJhIiwgImFuZHJvaWQiKTsKKyAqCisgKiAgIC8vIFRoZSBNYXAgQVBJIHNwZWNpZmllcyB0aGF0IHRoZSBuZXh0IGxpbmUgc2hvdWxkIHByaW50ICJudWxsIiBiZWNhdXNlCisgKiAgIC8vICJhIi5lcXVhbHMoIkEiKSBpcyBmYWxzZSBhbmQgdGhlcmUgaXMgbm8gbWFwcGluZyBmb3IgdXBwZXIgY2FzZSAiQSIuCisgKiAgIC8vIEJ1dCB0aGUgY2FzZSBpbnNlbnNpdGl2ZSBvcmRlcmluZyBzYXlzIGNvbXBhcmUoImEiLCAiQSIpID09IDAuIFRyZWVNYXAKKyAqICAgLy8gdXNlcyBvbmx5IGNvbXBhcmF0b3JzL2NvbXBhcmFibGUgb24ga2V5cyBhbmQgc28gdGhpcyBwcmludHMgImFuZHJvaWQiLgorICogICBTeXN0ZW0ub3V0LnByaW50bG4obWFwLmdldCgiQSIpKTsKKyAqIH08L3ByZT4KKyAqCisgKiBAc2luY2UgMS4yCisgKi8KK3B1YmxpYyBjbGFzcyBUcmVlTWFwPEssIFY+IGV4dGVuZHMgQWJzdHJhY3RNYXA8SywgVj4KKyAgICAgICAgaW1wbGVtZW50cyBTb3J0ZWRNYXA8SywgVj4sIE5hdmlnYWJsZU1hcDxLLCBWPiwgQ2xvbmVhYmxlLCBTZXJpYWxpemFibGUgeworCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIC8vIHRvIGF2b2lkIENvbXBhcmFibGU8Q29tcGFyYWJsZTxDb21wYXJhYmxlPC4uLj4+PgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbXBhcmF0b3I8Q29tcGFyYWJsZT4gTkFUVVJBTF9PUkRFUiA9IG5ldyBDb21wYXJhdG9yPENvbXBhcmFibGU+KCkgeworICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoQ29tcGFyYWJsZSBhLCBDb21wYXJhYmxlIGIpIHsKKyAgICAgICAgICAgIHJldHVybiBhLmNvbXBhcmVUbyhiKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBDb21wYXJhdG9yPD8gc3VwZXIgSz4gY29tcGFyYXRvcjsKKyAgICBOb2RlPEssIFY+IHJvb3Q7CisgICAgaW50IHNpemUgPSAwOworICAgIGludCBtb2RDb3VudCA9IDA7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuYXR1cmFsIG9yZGVyLCBlbXB0eSB0cmVlIG1hcCB3aG9zZSBrZXlzIG11c3QgYmUgbXV0dWFsbHkKKyAgICAgKiBjb21wYXJhYmxlIGFuZCBub24tbnVsbC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikgLy8gdW5zYWZlISB0aGlzIGFzc3VtZXMgSyBpcyBjb21wYXJhYmxlCisgICAgcHVibGljIFRyZWVNYXAoKSB7CisgICAgICAgIHRoaXMuY29tcGFyYXRvciA9IChDb21wYXJhdG9yPD8gc3VwZXIgSz4pIE5BVFVSQUxfT1JERVI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmF0dXJhbCBvcmRlciB0cmVlIG1hcCBwb3B1bGF0ZWQgd2l0aCB0aGUga2V5L3ZhbHVlIHBhaXJzIG9mCisgICAgICoge0Bjb2RlIGNvcHlGcm9tfS4gVGhpcyBtYXAncyBrZXlzIG11c3QgYmUgbXV0dWFsbHkgY29tcGFyYWJsZSBhbmQKKyAgICAgKiBub24tbnVsbC4KKyAgICAgKgorICAgICAqIDxwPkV2ZW4gaWYge0Bjb2RlIGNvcHlGcm9tfSBpcyBhIHtAY29kZSBTb3J0ZWRNYXB9LCB0aGUgY29uc3RydWN0ZWQgbWFwCisgICAgICogPHN0cm9uZz53aWxsIG5vdDwvc3Ryb25nPiB1c2Uge0Bjb2RlIGNvcHlGcm9tfSdzIG9yZGVyaW5nLiBUaGlzCisgICAgICogY29uc3RydWN0b3IgYWx3YXlzIGNyZWF0ZXMgYSBuYXR1cmFsbHktb3JkZXJlZCBtYXAuIEJlY2F1c2UgdGhlIHtAY29kZQorICAgICAqIFRyZWVNYXB9IGNvbnN0cnVjdG9yIG92ZXJsb2FkcyBhcmUgYW1iaWd1b3VzLCBwcmVmZXIgdG8gY29uc3RydWN0IGEgbWFwCisgICAgICogYW5kIHBvcHVsYXRlIGl0IGluIHR3byBzdGVwczogPHByZT4gICB7QGNvZGUKKyAgICAgKiAgIFRyZWVNYXA8U3RyaW5nLCBJbnRlZ2VyPiBjdXN0b21PcmRlcmVkTWFwCisgICAgICogICAgICAgPSBuZXcgVHJlZU1hcDxTdHJpbmcsIEludGVnZXI+KGNvcHlGcm9tLmNvbXBhcmF0b3IoKSk7CisgICAgICogICBjdXN0b21PcmRlcmVkTWFwLnB1dEFsbChjb3B5RnJvbSk7CisgICAgICogfTwvcHJlPgorICAgICAqLworICAgIHB1YmxpYyBUcmVlTWFwKE1hcDw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+IGNvcHlGcm9tKSB7CisgICAgICAgIHRoaXMoKTsKKyAgICAgICAgZm9yIChNYXAuRW50cnk8PyBleHRlbmRzIEssID8gZXh0ZW5kcyBWPiBlbnRyeSA6IGNvcHlGcm9tLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIHB1dEludGVybmFsKGVudHJ5LmdldEtleSgpLCBlbnRyeS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIHRyZWUgbWFwIG9yZGVyZWQgYnkge0Bjb2RlIGNvbXBhcmF0b3J9LiBUaGlzIG1hcCdzIGtleXMgbWF5IG9ubHkKKyAgICAgKiBiZSBudWxsIGlmIHtAY29kZSBjb21wYXJhdG9yfSBwZXJtaXRzLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbXBhcmF0b3IgdGhlIGNvbXBhcmF0b3IgdG8gb3JkZXIgZWxlbWVudHMgd2l0aCwgb3Ige0Bjb2RlIG51bGx9IHRvIHVzZSB0aGUgbmF0dXJhbAorICAgICAqIG9yZGVyaW5nLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSAvLyB1bnNhZmUhIGlmIGNvbXBhcmF0b3IgaXMgbnVsbCwgdGhpcyBhc3N1bWVzIEsgaXMgY29tcGFyYWJsZQorICAgIHB1YmxpYyBUcmVlTWFwKENvbXBhcmF0b3I8PyBzdXBlciBLPiBjb21wYXJhdG9yKSB7CisgICAgICAgIGlmIChjb21wYXJhdG9yICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMuY29tcGFyYXRvciA9IGNvbXBhcmF0b3I7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aGlzLmNvbXBhcmF0b3IgPSAoQ29tcGFyYXRvcjw/IHN1cGVyIEs+KSBOQVRVUkFMX09SREVSOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgdHJlZSBtYXAgd2l0aCB0aGUgb3JkZXJpbmcgYW5kIGtleS92YWx1ZSBwYWlycyBvZiB7QGNvZGUKKyAgICAgKiBjb3B5RnJvbX0uIFRoaXMgbWFwJ3Mga2V5cyBtYXkgb25seSBiZSBudWxsIGlmIHRoZSB7QGNvZGUgY29weUZyb219J3MKKyAgICAgKiBvcmRlcmluZyBwZXJtaXRzLgorICAgICAqCisgICAgICogPHA+VGhlIGNvbnN0cnVjdGVkIG1hcCA8c3Ryb25nPndpbGwgYWx3YXlzIHVzZTwvc3Ryb25nPiB7QGNvZGUKKyAgICAgKiBjb3B5RnJvbX0ncyBvcmRlcmluZy4gQmVjYXVzZSB0aGUge0Bjb2RlIFRyZWVNYXB9IGNvbnN0cnVjdG9yIG92ZXJsb2FkcworICAgICAqIGFyZSBhbWJpZ291cywgcHJlZmVyIHRvIGNvbnN0cnVjdCBhIG1hcCBhbmQgcG9wdWxhdGUgaXQgaW4gdHdvIHN0ZXBzOgorICAgICAqIDxwcmU+ICAge0Bjb2RlCisgICAgICogICBUcmVlTWFwPFN0cmluZywgSW50ZWdlcj4gY3VzdG9tT3JkZXJlZE1hcAorICAgICAqICAgICAgID0gbmV3IFRyZWVNYXA8U3RyaW5nLCBJbnRlZ2VyPihjb3B5RnJvbS5jb21wYXJhdG9yKCkpOworICAgICAqICAgY3VzdG9tT3JkZXJlZE1hcC5wdXRBbGwoY29weUZyb20pOworICAgICAqIH08L3ByZT4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikgLy8gaWYgY29weUZyb20ncyBrZXlzIGFyZSBjb21wYXJhYmxlIHRoaXMgbWFwJ3Mga2V5cyBtdXN0IGJlIGFsc28KKyAgICBwdWJsaWMgVHJlZU1hcChTb3J0ZWRNYXA8SywgPyBleHRlbmRzIFY+IGNvcHlGcm9tKSB7CisgICAgICAgIENvbXBhcmF0b3I8PyBzdXBlciBLPiBzb3VyY2VDb21wYXJhdG9yID0gY29weUZyb20uY29tcGFyYXRvcigpOworICAgICAgICBpZiAoc291cmNlQ29tcGFyYXRvciAhPSBudWxsKSB7CisgICAgICAgICAgICB0aGlzLmNvbXBhcmF0b3IgPSBzb3VyY2VDb21wYXJhdG9yOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhpcy5jb21wYXJhdG9yID0gKENvbXBhcmF0b3I8PyBzdXBlciBLPikgTkFUVVJBTF9PUkRFUjsKKyAgICAgICAgfQorICAgICAgICBmb3IgKE1hcC5FbnRyeTxLLCA/IGV4dGVuZHMgVj4gZW50cnkgOiBjb3B5RnJvbS5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICBwdXRJbnRlcm5hbChlbnRyeS5nZXRLZXkoKSwgZW50cnkuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSAvLyBzdXBlci5jbG9uZSgpIG11c3QgcmV0dXJuIHRoZSBzYW1lIHR5cGUKKyAgICAgICAgICAgIFRyZWVNYXA8SywgVj4gbWFwID0gKFRyZWVNYXA8SywgVj4pIHN1cGVyLmNsb25lKCk7CisgICAgICAgICAgICBtYXAucm9vdCA9IHJvb3QgIT0gbnVsbCA/IHJvb3QuY29weShudWxsKSA6IG51bGw7CisgICAgICAgICAgICBtYXAuZW50cnlTZXQgPSBudWxsOworICAgICAgICAgICAgbWFwLmtleVNldCA9IG51bGw7CisgICAgICAgICAgICByZXR1cm4gbWFwOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgIHJldHVybiBzaXplOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICByZXR1cm4gc2l6ZSA9PSAwOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgViBnZXQoT2JqZWN0IGtleSkgeworICAgICAgICBFbnRyeTxLLCBWPiBlbnRyeSA9IGZpbmRCeU9iamVjdChrZXkpOworICAgICAgICByZXR1cm4gZW50cnkgIT0gbnVsbCA/IGVudHJ5LmdldFZhbHVlKCkgOiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBjb250YWluc0tleShPYmplY3Qga2V5KSB7CisgICAgICAgIHJldHVybiBmaW5kQnlPYmplY3Qoa2V5KSAhPSBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgViBwdXQoSyBrZXksIFYgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIHB1dEludGVybmFsKGtleSwgdmFsdWUpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgcm9vdCA9IG51bGw7CisgICAgICAgIHNpemUgPSAwOworICAgICAgICBtb2RDb3VudCsrOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgViByZW1vdmUoT2JqZWN0IGtleSkgeworICAgICAgICBOb2RlPEssIFY+IG5vZGUgPSByZW1vdmVJbnRlcm5hbEJ5S2V5KGtleSk7CisgICAgICAgIHJldHVybiBub2RlICE9IG51bGwgPyBub2RlLnZhbHVlIDogbnVsbDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEFWTCBtZXRob2RzCisgICAgICovCisKKyAgICBlbnVtIFJlbGF0aW9uIHsKKyAgICAgICAgTE9XRVIsCisgICAgICAgIEZMT09SLAorICAgICAgICBFUVVBTCwKKyAgICAgICAgQ1JFQVRFLAorICAgICAgICBDRUlMSU5HLAorICAgICAgICBISUdIRVI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgYSBwb3NzaWJseS1mbGlwcGVkIHJlbGF0aW9uIGZvciB1c2UgaW4gZGVzY2VuZGluZyB2aWV3cy4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIGFzY2VuZGluZyBmYWxzZSB0byBmbGlwOyB0cnVlIHRvIHJldHVybiB0aGlzLgorICAgICAgICAgKi8KKyAgICAgICAgUmVsYXRpb24gZm9yT3JkZXIoYm9vbGVhbiBhc2NlbmRpbmcpIHsKKyAgICAgICAgICAgIGlmIChhc2NlbmRpbmcpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc3dpdGNoICh0aGlzKSB7CisgICAgICAgICAgICAgICAgY2FzZSBMT1dFUjoKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEhJR0hFUjsKKyAgICAgICAgICAgICAgICBjYXNlIEZMT09SOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ0VJTElORzsKKyAgICAgICAgICAgICAgICBjYXNlIEVRVUFMOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gRVFVQUw7CisgICAgICAgICAgICAgICAgY2FzZSBDRUlMSU5HOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gRkxPT1I7CisgICAgICAgICAgICAgICAgY2FzZSBISUdIRVI6CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBMT1dFUjsKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBWIHB1dEludGVybmFsKEsga2V5LCBWIHZhbHVlKSB7CisgICAgICAgIE5vZGU8SywgVj4gY3JlYXRlZCA9IGZpbmQoa2V5LCBSZWxhdGlvbi5DUkVBVEUpOworICAgICAgICBWIHJlc3VsdCA9IGNyZWF0ZWQudmFsdWU7CisgICAgICAgIGNyZWF0ZWQudmFsdWUgPSB2YWx1ZTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBub2RlIGF0IG9yIGFkamFjZW50IHRvIHRoZSBnaXZlbiBrZXksIGNyZWF0aW5nIGl0IGlmIHJlcXVlc3RlZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHtAY29kZSBrZXl9IGFuZCB0aGUgdHJlZSdzIGtleXMgYXJlbid0IG11dHVhbGx5IGNvbXBhcmFibGUuCisgICAgICovCisgICAgTm9kZTxLLCBWPiBmaW5kKEsga2V5LCBSZWxhdGlvbiByZWxhdGlvbikgeworICAgICAgICBpZiAocm9vdCA9PSBudWxsKSB7CisgICAgICAgICAgICBpZiAoY29tcGFyYXRvciA9PSBOQVRVUkFMX09SREVSICYmICEoa2V5IGluc3RhbmNlb2YgQ29tcGFyYWJsZSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xhc3NDYXN0RXhjZXB0aW9uKGtleS5nZXRDbGFzcygpLmdldE5hbWUoKSArICIgaXMgbm90IENvbXBhcmFibGUiKTsgLy8gTnVsbFBvaW50ZXJFeGNlcHRpb24gb2sKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChyZWxhdGlvbiA9PSBSZWxhdGlvbi5DUkVBVEUpIHsKKyAgICAgICAgICAgICAgICByb290ID0gbmV3IE5vZGU8SywgVj4obnVsbCwga2V5KTsKKyAgICAgICAgICAgICAgICBzaXplID0gMTsKKyAgICAgICAgICAgICAgICBtb2RDb3VudCsrOworICAgICAgICAgICAgICAgIHJldHVybiByb290OworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIE1pY3JvLW9wdGltaXphdGlvbjogYXZvaWQgcG9seW1vcnBoaWMgY2FsbHMgdG8gQ29tcGFyYXRvci5jb21wYXJlKCkuCisgICAgICAgICAqIFRoaXMgaXMgMTAlIGZhc3RlciBmb3IgbmF0dXJhbGx5IG9yZGVyZWQgdHJlZXMuCisgICAgICAgICAqLworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikgLy8gd2lsbCB0aHJvdyBhIENsYXNzQ2FzdEV4Y2VwdGlvbiBiZWxvdyBpZiB0aGVyZSdzIHRyb3VibGUKKyAgICAgICAgQ29tcGFyYWJsZTxPYmplY3Q+IGNvbXBhcmFibGVLZXkgPSAoY29tcGFyYXRvciA9PSBOQVRVUkFMX09SREVSKQorICAgICAgICAgICAgICAgID8gKENvbXBhcmFibGU8T2JqZWN0Pikga2V5CisgICAgICAgICAgICAgICAgOiBudWxsOworCisgICAgICAgIE5vZGU8SywgVj4gbmVhcmVzdCA9IHJvb3Q7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBpbnQgY29tcGFyaXNvbiA9IChjb21wYXJhYmxlS2V5ICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgID8gY29tcGFyYWJsZUtleS5jb21wYXJlVG8obmVhcmVzdC5rZXkpCisgICAgICAgICAgICAgICAgICAgIDogY29tcGFyYXRvci5jb21wYXJlKGtleSwgbmVhcmVzdC5rZXkpOworCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogV2UgZm91bmQgdGhlIHJlcXVlc3RlZCBrZXkuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGlmIChjb21wYXJpc29uID09IDApIHsKKyAgICAgICAgICAgICAgICBzd2l0Y2ggKHJlbGF0aW9uKSB7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgTE9XRVI6CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmVhcmVzdC5wcmV2KCk7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgRkxPT1I6CisgICAgICAgICAgICAgICAgICAgIGNhc2UgRVFVQUw6CisgICAgICAgICAgICAgICAgICAgIGNhc2UgQ1JFQVRFOgorICAgICAgICAgICAgICAgICAgICBjYXNlIENFSUxJTkc6CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmVhcmVzdDsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBISUdIRVI6CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmVhcmVzdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBOb2RlPEssIFY+IGNoaWxkID0gKGNvbXBhcmlzb24gPCAwKSA/IG5lYXJlc3QubGVmdCA6IG5lYXJlc3QucmlnaHQ7CisgICAgICAgICAgICBpZiAoY2hpbGQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG5lYXJlc3QgPSBjaGlsZDsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFdlIGZvdW5kIGEgbmVhcmVzdCBub2RlLiBFdmVyeSBrZXkgbm90IGluIHRoZSB0cmVlIGhhcyB1cCB0byB0d28KKyAgICAgICAgICAgICAqIG5lYXJlc3Qgbm9kZXMsIG9uZSBsb3dlciBhbmQgb25lIGhpZ2hlci4KKyAgICAgICAgICAgICAqLworCisgICAgICAgICAgICBpZiAoY29tcGFyaXNvbiA8IDApIHsgLy8gbmVhcmVzdC5rZXkgaXMgaGlnaGVyCisgICAgICAgICAgICAgICAgc3dpdGNoIChyZWxhdGlvbikgeworICAgICAgICAgICAgICAgICAgICBjYXNlIExPV0VSOgorICAgICAgICAgICAgICAgICAgICBjYXNlIEZMT09SOgorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5lYXJlc3QucHJldigpOworICAgICAgICAgICAgICAgICAgICBjYXNlIENFSUxJTkc6CisgICAgICAgICAgICAgICAgICAgIGNhc2UgSElHSEVSOgorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5lYXJlc3Q7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgRVFVQUw6CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBDUkVBVEU6CisgICAgICAgICAgICAgICAgICAgICAgICBOb2RlPEssIFY+IGNyZWF0ZWQgPSBuZXcgTm9kZTxLLCBWPihuZWFyZXN0LCBrZXkpOworICAgICAgICAgICAgICAgICAgICAgICAgbmVhcmVzdC5sZWZ0ID0gY3JlYXRlZDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNpemUrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1vZENvdW50Kys7CisgICAgICAgICAgICAgICAgICAgICAgICByZWJhbGFuY2UobmVhcmVzdCwgdHJ1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlZDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeyAvLyBjb21wYXJpc29uID4gMCwgbmVhcmVzdC5rZXkgaXMgbG93ZXIKKyAgICAgICAgICAgICAgICBzd2l0Y2ggKHJlbGF0aW9uKSB7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgTE9XRVI6CisgICAgICAgICAgICAgICAgICAgIGNhc2UgRkxPT1I6CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmVhcmVzdDsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBDRUlMSU5HOgorICAgICAgICAgICAgICAgICAgICBjYXNlIEhJR0hFUjoKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZWFyZXN0Lm5leHQoKTsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBFUVVBTDoKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICBjYXNlIENSRUFURToKKyAgICAgICAgICAgICAgICAgICAgICAgIE5vZGU8SywgVj4gY3JlYXRlZCA9IG5ldyBOb2RlPEssIFY+KG5lYXJlc3QsIGtleSk7CisgICAgICAgICAgICAgICAgICAgICAgICBuZWFyZXN0LnJpZ2h0ID0gY3JlYXRlZDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNpemUrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1vZENvdW50Kys7CisgICAgICAgICAgICAgICAgICAgICAgICByZWJhbGFuY2UobmVhcmVzdCwgdHJ1ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlZDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikgLy8gdGhpcyBtZXRob2QgdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbnMhCisgICAgTm9kZTxLLCBWPiBmaW5kQnlPYmplY3QoT2JqZWN0IGtleSkgeworICAgICAgICByZXR1cm4gZmluZCgoSykga2V5LCBFUVVBTCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIG1hcCdzIGVudHJ5IHRoYXQgaGFzIHRoZSBzYW1lIGtleSBhbmQgdmFsdWUgYXMge0Bjb2RlCisgICAgICogZW50cnl9LCBvciBudWxsIGlmIHRoaXMgbWFwIGhhcyBubyBzdWNoIGVudHJ5LgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgdXNlcyB0aGUgY29tcGFyYXRvciBmb3Iga2V5IGVxdWFsaXR5IHJhdGhlciB0aGFuIHtAY29kZQorICAgICAqIGVxdWFsc30uIElmIHRoaXMgbWFwJ3MgY29tcGFyYXRvciBpc24ndCBjb25zaXN0ZW50IHdpdGggZXF1YWxzIChzdWNoIGFzCisgICAgICoge0Bjb2RlIFN0cmluZy5DQVNFX0lOU0VOU0lUSVZFX09SREVSfSksIHRoZW4ge0Bjb2RlIHJlbW92ZSgpfSBhbmQge0Bjb2RlCisgICAgICogY29udGFpbnMoKX0gd2lsbCB2aW9sYXRlIHRoZSBjb2xsZWN0aW9ucyBBUEkuCisgICAgICovCisgICAgTm9kZTxLLCBWPiBmaW5kQnlFbnRyeShFbnRyeTw/LCA/PiBlbnRyeSkgeworICAgICAgICBOb2RlPEssIFY+IG1pbmUgPSBmaW5kQnlPYmplY3QoZW50cnkuZ2V0S2V5KCkpOworICAgICAgICBib29sZWFuIHZhbHVlc0VxdWFsID0gbWluZSAhPSBudWxsICYmIE9iamVjdHMuZXF1YWwobWluZS52YWx1ZSwgZW50cnkuZ2V0VmFsdWUoKSk7CisgICAgICAgIHJldHVybiB2YWx1ZXNFcXVhbCA/IG1pbmUgOiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMge0Bjb2RlIG5vZGV9IGZyb20gdGhpcyB0cmVlLCByZWFycmFuZ2luZyB0aGUgdHJlZSdzIHN0cnVjdHVyZSBhcworICAgICAqIG5lY2Vzc2FyeS4KKyAgICAgKi8KKyAgICB2b2lkIHJlbW92ZUludGVybmFsKE5vZGU8SywgVj4gbm9kZSkgeworICAgICAgICBOb2RlPEssIFY+IGxlZnQgPSBub2RlLmxlZnQ7CisgICAgICAgIE5vZGU8SywgVj4gcmlnaHQgPSBub2RlLnJpZ2h0OworICAgICAgICBOb2RlPEssIFY+IG9yaWdpbmFsUGFyZW50ID0gbm9kZS5wYXJlbnQ7CisgICAgICAgIGlmIChsZWZ0ICE9IG51bGwgJiYgcmlnaHQgIT0gbnVsbCkgeworCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogVG8gcmVtb3ZlIGEgbm9kZSB3aXRoIGJvdGggbGVmdCBhbmQgcmlnaHQgc3VidHJlZXMsIG1vdmUgYW4KKyAgICAgICAgICAgICAqIGFkamFjZW50IG5vZGUgZnJvbSBvbmUgb2YgdGhvc2Ugc3VidHJlZXMgaW50byB0aGlzIG5vZGUncyBwbGFjZS4KKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBSZW1vdmluZyB0aGUgYWRqYWNlbnQgbm9kZSBtYXkgY2hhbmdlIHRoaXMgbm9kZSdzIHN1YnRyZWVzLiBUaGlzCisgICAgICAgICAgICAgKiBub2RlIG1heSBubyBsb25nZXIgaGF2ZSB0d28gc3VidHJlZXMgb25jZSB0aGUgYWRqYWNlbnQgbm9kZSBpcworICAgICAgICAgICAgICogZ29uZSEKKyAgICAgICAgICAgICAqLworCisgICAgICAgICAgICBOb2RlPEssIFY+IGFkamFjZW50ID0gKGxlZnQuaGVpZ2h0ID4gcmlnaHQuaGVpZ2h0KSA/IGxlZnQubGFzdCgpIDogcmlnaHQuZmlyc3QoKTsKKyAgICAgICAgICAgIHJlbW92ZUludGVybmFsKGFkamFjZW50KTsgLy8gdGFrZXMgY2FyZSBvZiByZWJhbGFuY2UgYW5kIHNpemUtLQorCisgICAgICAgICAgICBpbnQgbGVmdEhlaWdodCA9IDA7CisgICAgICAgICAgICBsZWZ0ID0gbm9kZS5sZWZ0OworICAgICAgICAgICAgaWYgKGxlZnQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGxlZnRIZWlnaHQgPSBsZWZ0LmhlaWdodDsKKyAgICAgICAgICAgICAgICBhZGphY2VudC5sZWZ0ID0gbGVmdDsKKyAgICAgICAgICAgICAgICBsZWZ0LnBhcmVudCA9IGFkamFjZW50OworICAgICAgICAgICAgICAgIG5vZGUubGVmdCA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgcmlnaHRIZWlnaHQgPSAwOworICAgICAgICAgICAgcmlnaHQgPSBub2RlLnJpZ2h0OworICAgICAgICAgICAgaWYgKHJpZ2h0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByaWdodEhlaWdodCA9IHJpZ2h0LmhlaWdodDsKKyAgICAgICAgICAgICAgICBhZGphY2VudC5yaWdodCA9IHJpZ2h0OworICAgICAgICAgICAgICAgIHJpZ2h0LnBhcmVudCA9IGFkamFjZW50OworICAgICAgICAgICAgICAgIG5vZGUucmlnaHQgPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYWRqYWNlbnQuaGVpZ2h0ID0gTWF0aC5tYXgobGVmdEhlaWdodCwgcmlnaHRIZWlnaHQpICsgMTsKKyAgICAgICAgICAgIHJlcGxhY2VJblBhcmVudChub2RlLCBhZGphY2VudCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0gZWxzZSBpZiAobGVmdCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXBsYWNlSW5QYXJlbnQobm9kZSwgbGVmdCk7CisgICAgICAgICAgICBub2RlLmxlZnQgPSBudWxsOworICAgICAgICB9IGVsc2UgaWYgKHJpZ2h0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlcGxhY2VJblBhcmVudChub2RlLCByaWdodCk7CisgICAgICAgICAgICBub2RlLnJpZ2h0ID0gbnVsbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlcGxhY2VJblBhcmVudChub2RlLCBudWxsKTsKKyAgICAgICAgfQorCisgICAgICAgIHJlYmFsYW5jZShvcmlnaW5hbFBhcmVudCwgZmFsc2UpOworICAgICAgICBzaXplLS07CisgICAgICAgIG1vZENvdW50Kys7CisgICAgfQorCisgICAgTm9kZTxLLCBWPiByZW1vdmVJbnRlcm5hbEJ5S2V5KE9iamVjdCBrZXkpIHsKKyAgICAgICAgTm9kZTxLLCBWPiBub2RlID0gZmluZEJ5T2JqZWN0KGtleSk7CisgICAgICAgIGlmIChub2RlICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlbW92ZUludGVybmFsKG5vZGUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBub2RlOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZXBsYWNlSW5QYXJlbnQoTm9kZTxLLCBWPiBub2RlLCBOb2RlPEssIFY+IHJlcGxhY2VtZW50KSB7CisgICAgICAgIE5vZGU8SywgVj4gcGFyZW50ID0gbm9kZS5wYXJlbnQ7CisgICAgICAgIG5vZGUucGFyZW50ID0gbnVsbDsKKyAgICAgICAgaWYgKHJlcGxhY2VtZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlcGxhY2VtZW50LnBhcmVudCA9IHBhcmVudDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChwYXJlbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKHBhcmVudC5sZWZ0ID09IG5vZGUpIHsKKyAgICAgICAgICAgICAgICBwYXJlbnQubGVmdCA9IHJlcGxhY2VtZW50OworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnQgKHBhcmVudC5yaWdodCA9PSBub2RlKTsKKyAgICAgICAgICAgICAgICBwYXJlbnQucmlnaHQgPSByZXBsYWNlbWVudDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJvb3QgPSByZXBsYWNlbWVudDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYmFsYW5jZXMgdGhlIHRyZWUgYnkgbWFraW5nIGFueSBBVkwgcm90YXRpb25zIG5lY2Vzc2FyeSBiZXR3ZWVuIHRoZQorICAgICAqIG5ld2x5LXVuYmFsYW5jZWQgbm9kZSBhbmQgdGhlIHRyZWUncyByb290LgorICAgICAqCisgICAgICogQHBhcmFtIGluc2VydCB0cnVlIGlmIHRoZSBub2RlIHdhcyB1bmJhbGFuY2VkIGJ5IGFuIGluc2VydDsgZmFsc2UgaWYgaXQKKyAgICAgKiAgICAgd2FzIGJ5IGEgcmVtb3ZhbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmViYWxhbmNlKE5vZGU8SywgVj4gdW5iYWxhbmNlZCwgYm9vbGVhbiBpbnNlcnQpIHsKKyAgICAgICAgZm9yIChOb2RlPEssIFY+IG5vZGUgPSB1bmJhbGFuY2VkOyBub2RlICE9IG51bGw7IG5vZGUgPSBub2RlLnBhcmVudCkgeworICAgICAgICAgICAgTm9kZTxLLCBWPiBsZWZ0ID0gbm9kZS5sZWZ0OworICAgICAgICAgICAgTm9kZTxLLCBWPiByaWdodCA9IG5vZGUucmlnaHQ7CisgICAgICAgICAgICBpbnQgbGVmdEhlaWdodCA9IGxlZnQgIT0gbnVsbCA/IGxlZnQuaGVpZ2h0IDogMDsKKyAgICAgICAgICAgIGludCByaWdodEhlaWdodCA9IHJpZ2h0ICE9IG51bGwgPyByaWdodC5oZWlnaHQgOiAwOworCisgICAgICAgICAgICBpbnQgZGVsdGEgPSBsZWZ0SGVpZ2h0IC0gcmlnaHRIZWlnaHQ7CisgICAgICAgICAgICBpZiAoZGVsdGEgPT0gLTIpIHsKKyAgICAgICAgICAgICAgICBOb2RlPEssIFY+IHJpZ2h0TGVmdCA9IHJpZ2h0LmxlZnQ7CisgICAgICAgICAgICAgICAgTm9kZTxLLCBWPiByaWdodFJpZ2h0ID0gcmlnaHQucmlnaHQ7CisgICAgICAgICAgICAgICAgaW50IHJpZ2h0UmlnaHRIZWlnaHQgPSByaWdodFJpZ2h0ICE9IG51bGwgPyByaWdodFJpZ2h0LmhlaWdodCA6IDA7CisgICAgICAgICAgICAgICAgaW50IHJpZ2h0TGVmdEhlaWdodCA9IHJpZ2h0TGVmdCAhPSBudWxsID8gcmlnaHRMZWZ0LmhlaWdodCA6IDA7CisKKyAgICAgICAgICAgICAgICBpbnQgcmlnaHREZWx0YSA9IHJpZ2h0TGVmdEhlaWdodCAtIHJpZ2h0UmlnaHRIZWlnaHQ7CisgICAgICAgICAgICAgICAgaWYgKHJpZ2h0RGVsdGEgPT0gLTEgfHwgKHJpZ2h0RGVsdGEgPT0gMCAmJiAhaW5zZXJ0KSkgeworICAgICAgICAgICAgICAgICAgICByb3RhdGVMZWZ0KG5vZGUpOyAvLyBBVkwgcmlnaHQgcmlnaHQKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnQgKHJpZ2h0RGVsdGEgPT0gMSk7CisgICAgICAgICAgICAgICAgICAgIHJvdGF0ZVJpZ2h0KHJpZ2h0KTsgLy8gQVZMIHJpZ2h0IGxlZnQKKyAgICAgICAgICAgICAgICAgICAgcm90YXRlTGVmdChub2RlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGluc2VydCkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsgLy8gbm8gZnVydGhlciByb3RhdGlvbnMgd2lsbCBiZSBuZWNlc3NhcnkKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZGVsdGEgPT0gMikgeworICAgICAgICAgICAgICAgIE5vZGU8SywgVj4gbGVmdExlZnQgPSBsZWZ0LmxlZnQ7CisgICAgICAgICAgICAgICAgTm9kZTxLLCBWPiBsZWZ0UmlnaHQgPSBsZWZ0LnJpZ2h0OworICAgICAgICAgICAgICAgIGludCBsZWZ0UmlnaHRIZWlnaHQgPSBsZWZ0UmlnaHQgIT0gbnVsbCA/IGxlZnRSaWdodC5oZWlnaHQgOiAwOworICAgICAgICAgICAgICAgIGludCBsZWZ0TGVmdEhlaWdodCA9IGxlZnRMZWZ0ICE9IG51bGwgPyBsZWZ0TGVmdC5oZWlnaHQgOiAwOworCisgICAgICAgICAgICAgICAgaW50IGxlZnREZWx0YSA9IGxlZnRMZWZ0SGVpZ2h0IC0gbGVmdFJpZ2h0SGVpZ2h0OworICAgICAgICAgICAgICAgIGlmIChsZWZ0RGVsdGEgPT0gMSB8fCAobGVmdERlbHRhID09IDAgJiYgIWluc2VydCkpIHsKKyAgICAgICAgICAgICAgICAgICAgcm90YXRlUmlnaHQobm9kZSk7IC8vIEFWTCBsZWZ0IGxlZnQKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnQgKGxlZnREZWx0YSA9PSAtMSk7CisgICAgICAgICAgICAgICAgICAgIHJvdGF0ZUxlZnQobGVmdCk7IC8vIEFWTCBsZWZ0IHJpZ2h0CisgICAgICAgICAgICAgICAgICAgIHJvdGF0ZVJpZ2h0KG5vZGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoaW5zZXJ0KSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOyAvLyBubyBmdXJ0aGVyIHJvdGF0aW9ucyB3aWxsIGJlIG5lY2Vzc2FyeQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgfSBlbHNlIGlmIChkZWx0YSA9PSAwKSB7CisgICAgICAgICAgICAgICAgbm9kZS5oZWlnaHQgPSBsZWZ0SGVpZ2h0ICsgMTsgLy8gbGVmdEhlaWdodCA9PSByaWdodEhlaWdodAorICAgICAgICAgICAgICAgIGlmIChpbnNlcnQpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7IC8vIHRoZSBpbnNlcnQgY2F1c2VkIGJhbGFuY2UsIHNvIHJlYmFsYW5jaW5nIGlzIGRvbmUhCisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFzc2VydCAoZGVsdGEgPT0gLTEgfHwgZGVsdGEgPT0gMSk7CisgICAgICAgICAgICAgICAgbm9kZS5oZWlnaHQgPSBNYXRoLm1heChsZWZ0SGVpZ2h0LCByaWdodEhlaWdodCkgKyAxOworICAgICAgICAgICAgICAgIGlmICghaW5zZXJ0KSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOyAvLyB0aGUgaGVpZ2h0IGhhc24ndCBjaGFuZ2VkLCBzbyByZWJhbGFuY2luZyBpcyBkb25lIQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJvdGF0ZXMgdGhlIHN1YnRyZWUgc28gdGhhdCBpdHMgcm9vdCdzIHJpZ2h0IGNoaWxkIGlzIHRoZSBuZXcgcm9vdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcm90YXRlTGVmdChOb2RlPEssIFY+IHJvb3QpIHsKKyAgICAgICAgTm9kZTxLLCBWPiBsZWZ0ID0gcm9vdC5sZWZ0OworICAgICAgICBOb2RlPEssIFY+IHBpdm90ID0gcm9vdC5yaWdodDsKKyAgICAgICAgTm9kZTxLLCBWPiBwaXZvdExlZnQgPSBwaXZvdC5sZWZ0OworICAgICAgICBOb2RlPEssIFY+IHBpdm90UmlnaHQgPSBwaXZvdC5yaWdodDsKKworICAgICAgICAvLyBtb3ZlIHRoZSBwaXZvdCdzIGxlZnQgY2hpbGQgdG8gdGhlIHJvb3QncyByaWdodAorICAgICAgICByb290LnJpZ2h0ID0gcGl2b3RMZWZ0OworICAgICAgICBpZiAocGl2b3RMZWZ0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHBpdm90TGVmdC5wYXJlbnQgPSByb290OworICAgICAgICB9CisKKyAgICAgICAgcmVwbGFjZUluUGFyZW50KHJvb3QsIHBpdm90KTsKKworICAgICAgICAvLyBtb3ZlIHRoZSByb290IHRvIHRoZSBwaXZvdCdzIGxlZnQKKyAgICAgICAgcGl2b3QubGVmdCA9IHJvb3Q7CisgICAgICAgIHJvb3QucGFyZW50ID0gcGl2b3Q7CisKKyAgICAgICAgLy8gZml4IGhlaWdodHMKKyAgICAgICAgcm9vdC5oZWlnaHQgPSBNYXRoLm1heChsZWZ0ICE9IG51bGwgPyBsZWZ0LmhlaWdodCA6IDAsCisgICAgICAgICAgICAgICAgcGl2b3RMZWZ0ICE9IG51bGwgPyBwaXZvdExlZnQuaGVpZ2h0IDogMCkgKyAxOworICAgICAgICBwaXZvdC5oZWlnaHQgPSBNYXRoLm1heChyb290LmhlaWdodCwKKyAgICAgICAgICAgICAgICBwaXZvdFJpZ2h0ICE9IG51bGwgPyBwaXZvdFJpZ2h0LmhlaWdodCA6IDApICsgMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSb3RhdGVzIHRoZSBzdWJ0cmVlIHNvIHRoYXQgaXRzIHJvb3QncyBsZWZ0IGNoaWxkIGlzIHRoZSBuZXcgcm9vdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcm90YXRlUmlnaHQoTm9kZTxLLCBWPiByb290KSB7CisgICAgICAgIE5vZGU8SywgVj4gcGl2b3QgPSByb290LmxlZnQ7CisgICAgICAgIE5vZGU8SywgVj4gcmlnaHQgPSByb290LnJpZ2h0OworICAgICAgICBOb2RlPEssIFY+IHBpdm90TGVmdCA9IHBpdm90LmxlZnQ7CisgICAgICAgIE5vZGU8SywgVj4gcGl2b3RSaWdodCA9IHBpdm90LnJpZ2h0OworCisgICAgICAgIC8vIG1vdmUgdGhlIHBpdm90J3MgcmlnaHQgY2hpbGQgdG8gdGhlIHJvb3QncyBsZWZ0CisgICAgICAgIHJvb3QubGVmdCA9IHBpdm90UmlnaHQ7CisgICAgICAgIGlmIChwaXZvdFJpZ2h0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHBpdm90UmlnaHQucGFyZW50ID0gcm9vdDsKKyAgICAgICAgfQorCisgICAgICAgIHJlcGxhY2VJblBhcmVudChyb290LCBwaXZvdCk7CisKKyAgICAgICAgLy8gbW92ZSB0aGUgcm9vdCB0byB0aGUgcGl2b3QncyByaWdodAorICAgICAgICBwaXZvdC5yaWdodCA9IHJvb3Q7CisgICAgICAgIHJvb3QucGFyZW50ID0gcGl2b3Q7CisKKyAgICAgICAgLy8gZml4dXAgaGVpZ2h0cworICAgICAgICByb290LmhlaWdodCA9IE1hdGgubWF4KHJpZ2h0ICE9IG51bGwgPyByaWdodC5oZWlnaHQgOiAwLAorICAgICAgICAgICAgICAgIHBpdm90UmlnaHQgIT0gbnVsbCA/IHBpdm90UmlnaHQuaGVpZ2h0IDogMCkgKyAxOworICAgICAgICBwaXZvdC5oZWlnaHQgPSBNYXRoLm1heChyb290LmhlaWdodCwKKyAgICAgICAgICAgICAgICBwaXZvdExlZnQgIT0gbnVsbCA/IHBpdm90TGVmdC5oZWlnaHQgOiAwKSArIDE7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBOYXZpZ2FibGUgbWV0aG9kcy4KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW1tdXRhYmxlIHZlcnNpb24gb2Yge0BwYXJhbSBlbnRyeX0uIE5lZWQgdGhpcyBiZWNhdXNlIHdlIGFsbG93IGVudHJ5IHRvIGJlIG51bGwsCisgICAgICogaW4gd2hpY2ggY2FzZSB3ZSByZXR1cm4gYSBudWxsIFNpbXBsZUltbXV0YWJsZUVudHJ5LgorICAgICAqLworICAgIHByaXZhdGUgU2ltcGxlSW1tdXRhYmxlRW50cnk8SywgVj4gaW1tdXRhYmxlQ29weShFbnRyeTxLLCBWPiBlbnRyeSkgeworICAgICAgICByZXR1cm4gZW50cnkgPT0gbnVsbCA/IG51bGwgOiBuZXcgU2ltcGxlSW1tdXRhYmxlRW50cnk8SywgVj4oZW50cnkpOworICAgIH0KKworICAgIHB1YmxpYyBFbnRyeTxLLCBWPiBmaXJzdEVudHJ5KCkgeworICAgICAgICByZXR1cm4gaW1tdXRhYmxlQ29weShyb290ID09IG51bGwgPyBudWxsIDogcm9vdC5maXJzdCgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIEVudHJ5PEssIFY+IGludGVybmFsUG9sbEZpcnN0RW50cnkoKSB7CisgICAgICAgIGlmIChyb290ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIE5vZGU8SywgVj4gcmVzdWx0ID0gcm9vdC5maXJzdCgpOworICAgICAgICByZW1vdmVJbnRlcm5hbChyZXN1bHQpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBFbnRyeTxLLCBWPiBwb2xsRmlyc3RFbnRyeSgpIHsKKyAgICAgICAgcmV0dXJuIGltbXV0YWJsZUNvcHkoaW50ZXJuYWxQb2xsRmlyc3RFbnRyeSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgSyBmaXJzdEtleSgpIHsKKyAgICAgICAgaWYgKHJvb3QgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcm9vdC5maXJzdCgpLmdldEtleSgpOworICAgIH0KKworICAgIHB1YmxpYyBFbnRyeTxLLCBWPiBsYXN0RW50cnkoKSB7CisgICAgICAgIHJldHVybiBpbW11dGFibGVDb3B5KHJvb3QgPT0gbnVsbCA/IG51bGwgOiByb290Lmxhc3QoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBFbnRyeTxLLCBWPiBpbnRlcm5hbFBvbGxMYXN0RW50cnkoKSB7CisgICAgICAgIGlmIChyb290ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIE5vZGU8SywgVj4gcmVzdWx0ID0gcm9vdC5sYXN0KCk7CisgICAgICAgIHJlbW92ZUludGVybmFsKHJlc3VsdCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIEVudHJ5PEssIFY+IHBvbGxMYXN0RW50cnkoKSB7CisgICAgICAgIHJldHVybiBpbW11dGFibGVDb3B5KGludGVybmFsUG9sbExhc3RFbnRyeSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgSyBsYXN0S2V5KCkgeworICAgICAgICBpZiAocm9vdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByb290Lmxhc3QoKS5nZXRLZXkoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRW50cnk8SywgVj4gbG93ZXJFbnRyeShLIGtleSkgeworICAgICAgICByZXR1cm4gaW1tdXRhYmxlQ29weShmaW5kKGtleSwgTE9XRVIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgSyBsb3dlcktleShLIGtleSkgeworICAgICAgICBFbnRyeTxLLCBWPiBlbnRyeSA9IGZpbmQoa2V5LCBMT1dFUik7CisgICAgICAgIHJldHVybiBlbnRyeSAhPSBudWxsID8gZW50cnkuZ2V0S2V5KCkgOiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBFbnRyeTxLLCBWPiBmbG9vckVudHJ5KEsga2V5KSB7CisgICAgICAgIHJldHVybiBpbW11dGFibGVDb3B5KGZpbmQoa2V5LCBGTE9PUikpOworICAgIH0KKworICAgIHB1YmxpYyBLIGZsb29yS2V5KEsga2V5KSB7CisgICAgICAgIEVudHJ5PEssIFY+IGVudHJ5ID0gZmluZChrZXksIEZMT09SKTsKKyAgICAgICAgcmV0dXJuIGVudHJ5ICE9IG51bGwgPyBlbnRyeS5nZXRLZXkoKSA6IG51bGw7CisgICAgfQorCisgICAgcHVibGljIEVudHJ5PEssIFY+IGNlaWxpbmdFbnRyeShLIGtleSkgeworICAgICAgICByZXR1cm4gaW1tdXRhYmxlQ29weShmaW5kKGtleSwgQ0VJTElORykpOworICAgIH0KKworICAgIHB1YmxpYyBLIGNlaWxpbmdLZXkoSyBrZXkpIHsKKyAgICAgICAgRW50cnk8SywgVj4gZW50cnkgPSBmaW5kKGtleSwgQ0VJTElORyk7CisgICAgICAgIHJldHVybiBlbnRyeSAhPSBudWxsID8gZW50cnkuZ2V0S2V5KCkgOiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBFbnRyeTxLLCBWPiBoaWdoZXJFbnRyeShLIGtleSkgeworICAgICAgICByZXR1cm4gaW1tdXRhYmxlQ29weShmaW5kKGtleSwgSElHSEVSKSk7CisgICAgfQorCisgICAgcHVibGljIEsgaGlnaGVyS2V5KEsga2V5KSB7CisgICAgICAgIEVudHJ5PEssIFY+IGVudHJ5ID0gZmluZChrZXksIEhJR0hFUik7CisgICAgICAgIHJldHVybiBlbnRyeSAhPSBudWxsID8gZW50cnkuZ2V0S2V5KCkgOiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBDb21wYXJhdG9yPD8gc3VwZXIgSz4gY29tcGFyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIGNvbXBhcmF0b3IgIT0gTkFUVVJBTF9PUkRFUiA/IGNvbXBhcmF0b3IgOiBudWxsOworICAgIH0KKworICAgIC8qCisgICAgICogVmlldyBmYWN0b3J5IG1ldGhvZHMuCisgICAgICovCisKKyAgICBwcml2YXRlIEVudHJ5U2V0IGVudHJ5U2V0OworICAgIHByaXZhdGUgS2V5U2V0IGtleVNldDsKKworICAgIEBPdmVycmlkZSBwdWJsaWMgU2V0PEVudHJ5PEssIFY+PiBlbnRyeVNldCgpIHsKKyAgICAgICAgRW50cnlTZXQgcmVzdWx0ID0gZW50cnlTZXQ7CisgICAgICAgIHJldHVybiByZXN1bHQgIT0gbnVsbCA/IHJlc3VsdCA6IChlbnRyeVNldCA9IG5ldyBFbnRyeVNldCgpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFNldDxLPiBrZXlTZXQoKSB7CisgICAgICAgIEtleVNldCByZXN1bHQgPSBrZXlTZXQ7CisgICAgICAgIHJldHVybiByZXN1bHQgIT0gbnVsbCA/IHJlc3VsdCA6IChrZXlTZXQgPSBuZXcgS2V5U2V0KCkpOworICAgIH0KKworICAgIHB1YmxpYyBOYXZpZ2FibGVTZXQ8Sz4gbmF2aWdhYmxlS2V5U2V0KCkgeworICAgICAgICBLZXlTZXQgcmVzdWx0ID0ga2V5U2V0OworICAgICAgICByZXR1cm4gcmVzdWx0ICE9IG51bGwgPyByZXN1bHQgOiAoa2V5U2V0ID0gbmV3IEtleVNldCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTmF2aWdhYmxlTWFwPEssIFY+IHN1Yk1hcChLIGZyb20sIGJvb2xlYW4gZnJvbUluY2x1c2l2ZSwgSyB0bywgYm9vbGVhbiB0b0luY2x1c2l2ZSkgeworICAgICAgICBCb3VuZCBmcm9tQm91bmQgPSBmcm9tSW5jbHVzaXZlID8gSU5DTFVTSVZFIDogRVhDTFVTSVZFOworICAgICAgICBCb3VuZCB0b0JvdW5kID0gdG9JbmNsdXNpdmUgPyBJTkNMVVNJVkUgOiBFWENMVVNJVkU7CisgICAgICAgIHJldHVybiBuZXcgQm91bmRlZE1hcCh0cnVlLCBmcm9tLCBmcm9tQm91bmQsIHRvLCB0b0JvdW5kKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU29ydGVkTWFwPEssIFY+IHN1Yk1hcChLIGZyb21JbmNsdXNpdmUsIEsgdG9FeGNsdXNpdmUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBCb3VuZGVkTWFwKHRydWUsIGZyb21JbmNsdXNpdmUsIElOQ0xVU0lWRSwgdG9FeGNsdXNpdmUsIEVYQ0xVU0lWRSk7CisgICAgfQorCisgICAgcHVibGljIE5hdmlnYWJsZU1hcDxLLCBWPiBoZWFkTWFwKEsgdG8sIGJvb2xlYW4gaW5jbHVzaXZlKSB7CisgICAgICAgIEJvdW5kIHRvQm91bmQgPSBpbmNsdXNpdmUgPyBJTkNMVVNJVkUgOiBFWENMVVNJVkU7CisgICAgICAgIHJldHVybiBuZXcgQm91bmRlZE1hcCh0cnVlLCBudWxsLCBOT19CT1VORCwgdG8sIHRvQm91bmQpOworICAgIH0KKworICAgIHB1YmxpYyBTb3J0ZWRNYXA8SywgVj4gaGVhZE1hcChLIHRvRXhjbHVzaXZlKSB7CisgICAgICAgIHJldHVybiBuZXcgQm91bmRlZE1hcCh0cnVlLCBudWxsLCBOT19CT1VORCwgdG9FeGNsdXNpdmUsIEVYQ0xVU0lWRSk7CisgICAgfQorCisgICAgcHVibGljIE5hdmlnYWJsZU1hcDxLLCBWPiB0YWlsTWFwKEsgZnJvbSwgYm9vbGVhbiBpbmNsdXNpdmUpIHsKKyAgICAgICAgQm91bmQgZnJvbUJvdW5kID0gaW5jbHVzaXZlID8gSU5DTFVTSVZFIDogRVhDTFVTSVZFOworICAgICAgICByZXR1cm4gbmV3IEJvdW5kZWRNYXAodHJ1ZSwgZnJvbSwgZnJvbUJvdW5kLCBudWxsLCBOT19CT1VORCk7CisgICAgfQorCisgICAgcHVibGljIFNvcnRlZE1hcDxLLCBWPiB0YWlsTWFwKEsgZnJvbUluY2x1c2l2ZSkgeworICAgICAgICByZXR1cm4gbmV3IEJvdW5kZWRNYXAodHJ1ZSwgZnJvbUluY2x1c2l2ZSwgSU5DTFVTSVZFLCBudWxsLCBOT19CT1VORCk7CisgICAgfQorCisgICAgcHVibGljIE5hdmlnYWJsZU1hcDxLLCBWPiBkZXNjZW5kaW5nTWFwKCkgeworICAgICAgICByZXR1cm4gbmV3IEJvdW5kZWRNYXAoZmFsc2UsIG51bGwsIE5PX0JPVU5ELCBudWxsLCBOT19CT1VORCk7CisgICAgfQorCisgICAgcHVibGljIE5hdmlnYWJsZVNldDxLPiBkZXNjZW5kaW5nS2V5U2V0KCkgeworICAgICAgICByZXR1cm4gbmV3IEJvdW5kZWRNYXAoZmFsc2UsIG51bGwsIE5PX0JPVU5ELCBudWxsLCBOT19CT1VORCkubmF2aWdhYmxlS2V5U2V0KCk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIE5vZGU8SywgVj4gaW1wbGVtZW50cyBNYXAuRW50cnk8SywgVj4geworICAgICAgICBOb2RlPEssIFY+IHBhcmVudDsKKyAgICAgICAgTm9kZTxLLCBWPiBsZWZ0OworICAgICAgICBOb2RlPEssIFY+IHJpZ2h0OworICAgICAgICBmaW5hbCBLIGtleTsKKyAgICAgICAgViB2YWx1ZTsKKyAgICAgICAgaW50IGhlaWdodDsKKworICAgICAgICBOb2RlKE5vZGU8SywgVj4gcGFyZW50LCBLIGtleSkgeworICAgICAgICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CisgICAgICAgICAgICB0aGlzLmtleSA9IGtleTsKKyAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gMTsKKyAgICAgICAgfQorCisgICAgICAgIE5vZGU8SywgVj4gY29weShOb2RlPEssIFY+IHBhcmVudCkgeworICAgICAgICAgICAgTm9kZTxLLCBWPiByZXN1bHQgPSBuZXcgTm9kZTxLLCBWPihwYXJlbnQsIGtleSk7CisgICAgICAgICAgICBpZiAobGVmdCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmxlZnQgPSBsZWZ0LmNvcHkocmVzdWx0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChyaWdodCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LnJpZ2h0ID0gcmlnaHQuY29weShyZXN1bHQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0LnZhbHVlID0gdmFsdWU7CisgICAgICAgICAgICByZXN1bHQuaGVpZ2h0ID0gaGVpZ2h0OworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBLIGdldEtleSgpIHsKKyAgICAgICAgICAgIHJldHVybiBrZXk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgViBnZXRWYWx1ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBWIHNldFZhbHVlKFYgdmFsdWUpIHsKKyAgICAgICAgICAgIFYgb2xkVmFsdWUgPSB0aGlzLnZhbHVlOworICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgICAgICAgICAgcmV0dXJuIG9sZFZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICAgICAgaWYgKG8gaW5zdGFuY2VvZiBNYXAuRW50cnkpIHsKKyAgICAgICAgICAgICAgICBNYXAuRW50cnkgb3RoZXIgPSAoTWFwLkVudHJ5KSBvOworICAgICAgICAgICAgICAgIHJldHVybiAoa2V5ID09IG51bGwgPyBvdGhlci5nZXRLZXkoKSA9PSBudWxsIDoga2V5LmVxdWFscyhvdGhlci5nZXRLZXkoKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAmJiAodmFsdWUgPT0gbnVsbCA/IG90aGVyLmdldFZhbHVlKCkgPT0gbnVsbCA6IHZhbHVlLmVxdWFscyhvdGhlci5nZXRWYWx1ZSgpKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiAoa2V5ID09IG51bGwgPyAwIDoga2V5Lmhhc2hDb2RlKCkpCisgICAgICAgICAgICAgICAgICAgIF4gKHZhbHVlID09IG51bGwgPyAwIDogdmFsdWUuaGFzaENvZGUoKSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBrZXkgKyAiPSIgKyB2YWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IG5vZGUgaW4gYW4gaW5vcmRlciB0cmF2ZXJzYWwsIG9yIG51bGwgaWYgdGhpcyBpcyB0aGUKKyAgICAgICAgICogbGFzdCBub2RlIGluIHRoZSB0cmVlLgorICAgICAgICAgKi8KKyAgICAgICAgTm9kZTxLLCBWPiBuZXh0KCkgeworICAgICAgICAgICAgaWYgKHJpZ2h0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmlnaHQuZmlyc3QoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgTm9kZTxLLCBWPiBub2RlID0gdGhpczsKKyAgICAgICAgICAgIE5vZGU8SywgVj4gcGFyZW50ID0gbm9kZS5wYXJlbnQ7CisgICAgICAgICAgICB3aGlsZSAocGFyZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZiAocGFyZW50LmxlZnQgPT0gbm9kZSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBub2RlID0gcGFyZW50OworICAgICAgICAgICAgICAgIHBhcmVudCA9IG5vZGUucGFyZW50OworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgcHJldmlvdXMgbm9kZSBpbiBhbiBpbm9yZGVyIHRyYXZlcnNhbCwgb3IgbnVsbCBpZiB0aGlzIGlzCisgICAgICAgICAqIHRoZSBmaXJzdCBub2RlIGluIHRoZSB0cmVlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIE5vZGU8SywgVj4gcHJldigpIHsKKyAgICAgICAgICAgIGlmIChsZWZ0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbGVmdC5sYXN0KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIE5vZGU8SywgVj4gbm9kZSA9IHRoaXM7CisgICAgICAgICAgICBOb2RlPEssIFY+IHBhcmVudCA9IG5vZGUucGFyZW50OworICAgICAgICAgICAgd2hpbGUgKHBhcmVudCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWYgKHBhcmVudC5yaWdodCA9PSBub2RlKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJlbnQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG5vZGUgPSBwYXJlbnQ7CisgICAgICAgICAgICAgICAgcGFyZW50ID0gbm9kZS5wYXJlbnQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRoZSBmaXJzdCBub2RlIGluIHRoaXMgc3VidHJlZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBOb2RlPEssIFY+IGZpcnN0KCkgeworICAgICAgICAgICAgTm9kZTxLLCBWPiBub2RlID0gdGhpczsKKyAgICAgICAgICAgIE5vZGU8SywgVj4gY2hpbGQgPSBub2RlLmxlZnQ7CisgICAgICAgICAgICB3aGlsZSAoY2hpbGQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG5vZGUgPSBjaGlsZDsKKyAgICAgICAgICAgICAgICBjaGlsZCA9IG5vZGUubGVmdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBub2RlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIGxhc3Qgbm9kZSBpbiB0aGlzIHN1YnRyZWUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgTm9kZTxLLCBWPiBsYXN0KCkgeworICAgICAgICAgICAgTm9kZTxLLCBWPiBub2RlID0gdGhpczsKKyAgICAgICAgICAgIE5vZGU8SywgVj4gY2hpbGQgPSBub2RlLnJpZ2h0OworICAgICAgICAgICAgd2hpbGUgKGNoaWxkICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBub2RlID0gY2hpbGQ7CisgICAgICAgICAgICAgICAgY2hpbGQgPSBub2RlLnJpZ2h0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5vZGU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXYWxrIHRoZSBub2RlcyBvZiB0aGUgdHJlZSBsZWZ0LXRvLXJpZ2h0IG9yIHJpZ2h0LXRvLWxlZnQuIE5vdGUgdGhhdCBpbgorICAgICAqIGRlc2NlbmRpbmcgaXRlcmF0aW9ucywge0Bjb2RlIG5leHR9IHdpbGwgcmV0dXJuIHRoZSBwcmV2aW91cyBub2RlLgorICAgICAqLworICAgIGFic3RyYWN0IGNsYXNzIE1hcEl0ZXJhdG9yPFQ+IGltcGxlbWVudHMgSXRlcmF0b3I8VD4geworICAgICAgICBwcm90ZWN0ZWQgTm9kZTxLLCBWPiBuZXh0OworICAgICAgICBwcm90ZWN0ZWQgTm9kZTxLLCBWPiBsYXN0OworICAgICAgICBwcm90ZWN0ZWQgaW50IGV4cGVjdGVkTW9kQ291bnQgPSBtb2RDb3VudDsKKworICAgICAgICBNYXBJdGVyYXRvcihOb2RlPEssIFY+IG5leHQpIHsKKyAgICAgICAgICAgIHRoaXMubmV4dCA9IG5leHQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgcmV0dXJuIG5leHQgIT0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCBOb2RlPEssIFY+IHN0ZXBGb3J3YXJkKCkgeworICAgICAgICAgICAgaWYgKG5leHQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobW9kQ291bnQgIT0gZXhwZWN0ZWRNb2RDb3VudCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsYXN0ID0gbmV4dDsKKyAgICAgICAgICAgIG5leHQgPSBuZXh0Lm5leHQoKTsKKyAgICAgICAgICAgIHJldHVybiBsYXN0OworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIE5vZGU8SywgVj4gc3RlcEJhY2t3YXJkKCkgeworICAgICAgICAgICAgaWYgKG5leHQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobW9kQ291bnQgIT0gZXhwZWN0ZWRNb2RDb3VudCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsYXN0ID0gbmV4dDsKKyAgICAgICAgICAgIG5leHQgPSBuZXh0LnByZXYoKTsKKyAgICAgICAgICAgIHJldHVybiBsYXN0OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICAgICAgaWYgKGxhc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlbW92ZUludGVybmFsKGxhc3QpOworICAgICAgICAgICAgZXhwZWN0ZWRNb2RDb3VudCA9IG1vZENvdW50OworICAgICAgICAgICAgbGFzdCA9IG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFZpZXcgaW1wbGVtZW50YXRpb25zLgorICAgICAqLworCisgICAgY2xhc3MgRW50cnlTZXQgZXh0ZW5kcyBBYnN0cmFjdFNldDxNYXAuRW50cnk8SywgVj4+IHsKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBzaXplOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBJdGVyYXRvcjxFbnRyeTxLLCBWPj4gaXRlcmF0b3IoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IE1hcEl0ZXJhdG9yPEVudHJ5PEssIFY+Pihyb290ID09IG51bGwgPyBudWxsIDogcm9vdC5maXJzdCgpKSB7CisgICAgICAgICAgICAgICAgcHVibGljIEVudHJ5PEssIFY+IG5leHQoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdGVwRm9yd2FyZCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIHJldHVybiBvIGluc3RhbmNlb2YgRW50cnkgJiYgZmluZEJ5RW50cnkoKEVudHJ5PD8sID8+KSBvKSAhPSBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3QgbykgeworICAgICAgICAgICAgaWYgKCEobyBpbnN0YW5jZW9mIEVudHJ5KSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgTm9kZTxLLCBWPiBub2RlID0gZmluZEJ5RW50cnkoKEVudHJ5PD8sID8+KSBvKTsKKyAgICAgICAgICAgIGlmIChub2RlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZW1vdmVJbnRlcm5hbChub2RlKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICAgICAgVHJlZU1hcC50aGlzLmNsZWFyKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBLZXlTZXQgZXh0ZW5kcyBBYnN0cmFjdFNldDxLPiBpbXBsZW1lbnRzIE5hdmlnYWJsZVNldDxLPiB7CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gc2l6ZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgSXRlcmF0b3I8Sz4gaXRlcmF0b3IoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IE1hcEl0ZXJhdG9yPEs+KHJvb3QgPT0gbnVsbCA/IG51bGwgOiByb290LmZpcnN0KCkpIHsKKyAgICAgICAgICAgICAgICBwdWJsaWMgSyBuZXh0KCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RlcEZvcndhcmQoKS5rZXk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBJdGVyYXRvcjxLPiBkZXNjZW5kaW5nSXRlcmF0b3IoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IE1hcEl0ZXJhdG9yPEs+KHJvb3QgPT0gbnVsbCA/IG51bGwgOiByb290Lmxhc3QoKSkgeworICAgICAgICAgICAgICAgIHB1YmxpYyBLIG5leHQoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdGVwQmFja3dhcmQoKS5rZXk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3QgbykgeworICAgICAgICAgICAgcmV0dXJuIGNvbnRhaW5zS2V5KG8pOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3Qga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gcmVtb3ZlSW50ZXJuYWxCeUtleShrZXkpICE9IG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICBUcmVlTWFwLnRoaXMuY2xlYXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBDb21wYXJhdG9yPD8gc3VwZXIgSz4gY29tcGFyYXRvcigpIHsKKyAgICAgICAgICAgIHJldHVybiBUcmVlTWFwLnRoaXMuY29tcGFyYXRvcigpOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogTmF2aWdhYmxlIG1ldGhvZHMuCisgICAgICAgICAqLworCisgICAgICAgIHB1YmxpYyBLIGZpcnN0KCkgeworICAgICAgICAgICAgcmV0dXJuIGZpcnN0S2V5KCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSyBsYXN0KCkgeworICAgICAgICAgICAgcmV0dXJuIGxhc3RLZXkoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBLIGxvd2VyKEsga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gbG93ZXJLZXkoa2V5KTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBLIGZsb29yKEsga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gZmxvb3JLZXkoa2V5KTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBLIGNlaWxpbmcoSyBrZXkpIHsKKyAgICAgICAgICAgIHJldHVybiBjZWlsaW5nS2V5KGtleSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSyBoaWdoZXIoSyBrZXkpIHsKKyAgICAgICAgICAgIHJldHVybiBoaWdoZXJLZXkoa2V5KTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBLIHBvbGxGaXJzdCgpIHsKKyAgICAgICAgICAgIEVudHJ5PEssIFY+IGVudHJ5ID0gaW50ZXJuYWxQb2xsRmlyc3RFbnRyeSgpOworICAgICAgICAgICAgcmV0dXJuIGVudHJ5ICE9IG51bGwgPyBlbnRyeS5nZXRLZXkoKSA6IG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSyBwb2xsTGFzdCgpIHsKKyAgICAgICAgICAgIEVudHJ5PEssIFY+IGVudHJ5ID0gaW50ZXJuYWxQb2xsTGFzdEVudHJ5KCk7CisgICAgICAgICAgICByZXR1cm4gZW50cnkgIT0gbnVsbCA/IGVudHJ5LmdldEtleSgpIDogbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIFZpZXcgZmFjdG9yeSBtZXRob2RzLgorICAgICAgICAgKi8KKworICAgICAgICBwdWJsaWMgTmF2aWdhYmxlU2V0PEs+IHN1YlNldChLIGZyb20sIGJvb2xlYW4gZnJvbUluY2x1c2l2ZSwgSyB0bywgYm9vbGVhbiB0b0luY2x1c2l2ZSkgeworICAgICAgICAgICAgcmV0dXJuIFRyZWVNYXAudGhpcy5zdWJNYXAoZnJvbSwgZnJvbUluY2x1c2l2ZSwgdG8sIHRvSW5jbHVzaXZlKS5uYXZpZ2FibGVLZXlTZXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTb3J0ZWRTZXQ8Sz4gc3ViU2V0KEsgZnJvbUluY2x1c2l2ZSwgSyB0b0V4Y2x1c2l2ZSkgeworICAgICAgICAgICAgcmV0dXJuIFRyZWVNYXAudGhpcy5zdWJNYXAoZnJvbUluY2x1c2l2ZSwgdHJ1ZSwgdG9FeGNsdXNpdmUsIGZhbHNlKS5uYXZpZ2FibGVLZXlTZXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBOYXZpZ2FibGVTZXQ8Sz4gaGVhZFNldChLIHRvLCBib29sZWFuIGluY2x1c2l2ZSkgeworICAgICAgICAgICAgcmV0dXJuIFRyZWVNYXAudGhpcy5oZWFkTWFwKHRvLCBpbmNsdXNpdmUpLm5hdmlnYWJsZUtleVNldCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFNvcnRlZFNldDxLPiBoZWFkU2V0KEsgdG9FeGNsdXNpdmUpIHsKKyAgICAgICAgICAgIHJldHVybiBUcmVlTWFwLnRoaXMuaGVhZE1hcCh0b0V4Y2x1c2l2ZSwgZmFsc2UpLm5hdmlnYWJsZUtleVNldCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE5hdmlnYWJsZVNldDxLPiB0YWlsU2V0KEsgZnJvbSwgYm9vbGVhbiBpbmNsdXNpdmUpIHsKKyAgICAgICAgICAgIHJldHVybiBUcmVlTWFwLnRoaXMudGFpbE1hcChmcm9tLCBpbmNsdXNpdmUpLm5hdmlnYWJsZUtleVNldCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFNvcnRlZFNldDxLPiB0YWlsU2V0KEsgZnJvbUluY2x1c2l2ZSkgeworICAgICAgICAgICAgcmV0dXJuIFRyZWVNYXAudGhpcy50YWlsTWFwKGZyb21JbmNsdXNpdmUsIHRydWUpLm5hdmlnYWJsZUtleVNldCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE5hdmlnYWJsZVNldDxLPiBkZXNjZW5kaW5nU2V0KCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBCb3VuZGVkTWFwKGZhbHNlLCBudWxsLCBOT19CT1VORCwgbnVsbCwgTk9fQk9VTkQpLm5hdmlnYWJsZUtleVNldCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBCb3VuZGVkIHZpZXdzIGltcGxlbWVudGF0aW9ucy4KKyAgICAgKi8KKworICAgIGVudW0gQm91bmQgeworICAgICAgICBJTkNMVVNJVkUgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgbGVmdENhcChPYmplY3QgZnJvbSkgeworICAgICAgICAgICAgICAgIHJldHVybiAiWyIgKyBmcm9tOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgcmlnaHRDYXAoT2JqZWN0IHRvKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRvICsgIl0iOworICAgICAgICAgICAgfQorICAgICAgICB9LAorICAgICAgICBFWENMVVNJVkUgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgbGVmdENhcChPYmplY3QgZnJvbSkgeworICAgICAgICAgICAgICAgIHJldHVybiAiKCIgKyBmcm9tOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgcmlnaHRDYXAoT2JqZWN0IHRvKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRvICsgIikiOworICAgICAgICAgICAgfQorICAgICAgICB9LAorICAgICAgICBOT19CT1VORCB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyBsZWZ0Q2FwKE9iamVjdCBmcm9tKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuICIuIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHJpZ2h0Q2FwKE9iamVjdCB0bykgeworICAgICAgICAgICAgICAgIHJldHVybiAiLiI7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBsZWZ0Q2FwKE9iamVjdCBmcm9tKTsKKyAgICAgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyByaWdodENhcChPYmplY3QgdG8pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgbWFwIHdpdGggb3B0aW9uYWwgbGltaXRzIG9uIGl0cyByYW5nZS4KKyAgICAgKi8KKyAgICBmaW5hbCBjbGFzcyBCb3VuZGVkTWFwIGV4dGVuZHMgQWJzdHJhY3RNYXA8SywgVj4gaW1wbGVtZW50cyBOYXZpZ2FibGVNYXA8SywgVj4sIFNlcmlhbGl6YWJsZSB7CisgICAgICAgIHByaXZhdGUgZmluYWwgdHJhbnNpZW50IGJvb2xlYW4gYXNjZW5kaW5nOworICAgICAgICBwcml2YXRlIGZpbmFsIHRyYW5zaWVudCBLIGZyb207CisgICAgICAgIHByaXZhdGUgZmluYWwgdHJhbnNpZW50IEJvdW5kIGZyb21Cb3VuZDsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCB0cmFuc2llbnQgSyB0bzsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCB0cmFuc2llbnQgQm91bmQgdG9Cb3VuZDsKKworICAgICAgICBCb3VuZGVkTWFwKGJvb2xlYW4gYXNjZW5kaW5nLCBLIGZyb20sIEJvdW5kIGZyb21Cb3VuZCwgSyB0bywgQm91bmQgdG9Cb3VuZCkgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFZhbGlkYXRlIHRoZSBib3VuZHMuIEluIGFkZGl0aW9uIHRvIGNoZWNraW5nIHRoYXQgZnJvbSA8PSB0bywgd2UKKyAgICAgICAgICAgICAqIHZlcmlmeSB0aGF0IHRoZSBjb21wYXJhdG9yIHN1cHBvcnRzIG91ciBib3VuZCBvYmplY3RzLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAoZnJvbUJvdW5kICE9IE5PX0JPVU5EICYmIHRvQm91bmQgIT0gTk9fQk9VTkQpIHsKKyAgICAgICAgICAgICAgICBpZiAoY29tcGFyYXRvci5jb21wYXJlKGZyb20sIHRvKSA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihmcm9tICsgIiA+ICIgKyB0byk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmIChmcm9tQm91bmQgIT0gTk9fQk9VTkQpIHsKKyAgICAgICAgICAgICAgICBjb21wYXJhdG9yLmNvbXBhcmUoZnJvbSwgZnJvbSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHRvQm91bmQgIT0gTk9fQk9VTkQpIHsKKyAgICAgICAgICAgICAgICBjb21wYXJhdG9yLmNvbXBhcmUodG8sIHRvKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdGhpcy5hc2NlbmRpbmcgPSBhc2NlbmRpbmc7CisgICAgICAgICAgICB0aGlzLmZyb20gPSBmcm9tOworICAgICAgICAgICAgdGhpcy5mcm9tQm91bmQgPSBmcm9tQm91bmQ7CisgICAgICAgICAgICB0aGlzLnRvID0gdG87CisgICAgICAgICAgICB0aGlzLnRvQm91bmQgPSB0b0JvdW5kOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBjb3VudChlbnRyeVNldCgpLml0ZXJhdG9yKCkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICByZXR1cm4gZW5kcG9pbnQodHJ1ZSkgPT0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgViBnZXQoT2JqZWN0IGtleSkgeworICAgICAgICAgICAgcmV0dXJuIGlzSW5Cb3VuZHMoa2V5KSA/IFRyZWVNYXAudGhpcy5nZXQoa2V5KSA6IG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnNLZXkoT2JqZWN0IGtleSkgeworICAgICAgICAgICAgcmV0dXJuIGlzSW5Cb3VuZHMoa2V5KSAmJiBUcmVlTWFwLnRoaXMuY29udGFpbnNLZXkoa2V5KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgViBwdXQoSyBrZXksIFYgdmFsdWUpIHsKKyAgICAgICAgICAgIGlmICghaXNJbkJvdW5kcyhrZXkpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgb3V0T2ZCb3VuZHMoa2V5LCBmcm9tQm91bmQsIHRvQm91bmQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHB1dEludGVybmFsKGtleSwgdmFsdWUpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBWIHJlbW92ZShPYmplY3Qga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gaXNJbkJvdW5kcyhrZXkpID8gVHJlZU1hcC50aGlzLnJlbW92ZShrZXkpIDogbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGtleSBpcyBpbiBib3VuZHMuCisgICAgICAgICAqLworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikgLy8gdGhpcyBtZXRob2QgdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbnMhCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc0luQm91bmRzKE9iamVjdCBrZXkpIHsKKyAgICAgICAgICAgIHJldHVybiBpc0luQm91bmRzKChLKSBrZXksIGZyb21Cb3VuZCwgdG9Cb3VuZCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBrZXkgaXMgaW4gYm91bmRzLiBVc2UgdGhpcyBvdmVybG9hZCB3aXRoCisgICAgICAgICAqIE5PX0JPVU5EIHRvIHNraXAgYm91bmRzIGNoZWNraW5nIG9uIGVpdGhlciBlbmQuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNJbkJvdW5kcyhLIGtleSwgQm91bmQgZnJvbUJvdW5kLCBCb3VuZCB0b0JvdW5kKSB7CisgICAgICAgICAgICBpZiAoZnJvbUJvdW5kID09IElOQ0xVU0lWRSkgeworICAgICAgICAgICAgICAgIGlmIChjb21wYXJhdG9yLmNvbXBhcmUoa2V5LCBmcm9tKSA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBsZXNzIHRoYW4gZnJvbQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZnJvbUJvdW5kID09IEVYQ0xVU0lWRSkgeworICAgICAgICAgICAgICAgIGlmIChjb21wYXJhdG9yLmNvbXBhcmUoa2V5LCBmcm9tKSA8PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGZyb20KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICh0b0JvdW5kID09IElOQ0xVU0lWRSkgeworICAgICAgICAgICAgICAgIGlmIChjb21wYXJhdG9yLmNvbXBhcmUoa2V5LCB0bykgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gZ3JlYXRlciB0aGFuICd0bycKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKHRvQm91bmQgPT0gRVhDTFVTSVZFKSB7CisgICAgICAgICAgICAgICAgaWYgKGNvbXBhcmF0b3IuY29tcGFyZShrZXksIHRvKSA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICd0bycKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIGVudHJ5IGlmIGl0IGlzIGluIGJvdW5kcywgb3IgbnVsbCBpZiBpdCBpcyBvdXQgb2YgYm91bmRzLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBOb2RlPEssIFY+IGJvdW5kKE5vZGU8SywgVj4gbm9kZSwgQm91bmQgZnJvbUJvdW5kLCBCb3VuZCB0b0JvdW5kKSB7CisgICAgICAgICAgICByZXR1cm4gbm9kZSAhPSBudWxsICYmIGlzSW5Cb3VuZHMobm9kZS5nZXRLZXkoKSwgZnJvbUJvdW5kLCB0b0JvdW5kKSA/IG5vZGUgOiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogTmF2aWdhYmxlIG1ldGhvZHMuCisgICAgICAgICAqLworCisgICAgICAgIHB1YmxpYyBFbnRyeTxLLCBWPiBmaXJzdEVudHJ5KCkgeworICAgICAgICAgICAgcmV0dXJuIGltbXV0YWJsZUNvcHkoZW5kcG9pbnQodHJ1ZSkpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEVudHJ5PEssIFY+IHBvbGxGaXJzdEVudHJ5KCkgeworICAgICAgICAgICAgTm9kZTxLLCBWPiByZXN1bHQgPSBlbmRwb2ludCh0cnVlKTsKKyAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJlbW92ZUludGVybmFsKHJlc3VsdCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gaW1tdXRhYmxlQ29weShyZXN1bHQpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEsgZmlyc3RLZXkoKSB7CisgICAgICAgICAgICBFbnRyeTxLLCBWPiBlbnRyeSA9IGVuZHBvaW50KHRydWUpOworICAgICAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGVudHJ5LmdldEtleSgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEVudHJ5PEssIFY+IGxhc3RFbnRyeSgpIHsKKyAgICAgICAgICAgIHJldHVybiBpbW11dGFibGVDb3B5KGVuZHBvaW50KGZhbHNlKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgRW50cnk8SywgVj4gcG9sbExhc3RFbnRyeSgpIHsKKyAgICAgICAgICAgIE5vZGU8SywgVj4gcmVzdWx0ID0gZW5kcG9pbnQoZmFsc2UpOworICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmVtb3ZlSW50ZXJuYWwocmVzdWx0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBpbW11dGFibGVDb3B5KHJlc3VsdCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSyBsYXN0S2V5KCkgeworICAgICAgICAgICAgRW50cnk8SywgVj4gZW50cnkgPSBlbmRwb2ludChmYWxzZSk7CisgICAgICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZW50cnkuZ2V0S2V5KCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQHBhcmFtIGZpcnN0IHRydWUgZm9yIHRoZSBmaXJzdCBlbGVtZW50LCBmYWxzZSBmb3IgdGhlIGxhc3QuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIE5vZGU8SywgVj4gZW5kcG9pbnQoYm9vbGVhbiBmaXJzdCkgeworICAgICAgICAgICAgTm9kZTxLLCBWPiBub2RlOworICAgICAgICAgICAgaWYgKGFzY2VuZGluZyA9PSBmaXJzdCkgeworICAgICAgICAgICAgICAgIHN3aXRjaCAoZnJvbUJvdW5kKSB7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgTk9fQk9VTkQ6CisgICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gcm9vdCA9PSBudWxsID8gbnVsbCA6IHJvb3QuZmlyc3QoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIElOQ0xVU0lWRToKKyAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBmaW5kKGZyb20sIENFSUxJTkcpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgRVhDTFVTSVZFOgorICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IGZpbmQoZnJvbSwgSElHSEVSKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBib3VuZChub2RlLCBOT19CT1VORCwgdG9Cb3VuZCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHN3aXRjaCAodG9Cb3VuZCkgeworICAgICAgICAgICAgICAgICAgICBjYXNlIE5PX0JPVU5EOgorICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IHJvb3QgPT0gbnVsbCA/IG51bGwgOiByb290Lmxhc3QoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIElOQ0xVU0lWRToKKyAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBmaW5kKHRvLCBGTE9PUik7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBFWENMVVNJVkU6CisgICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gZmluZCh0bywgTE9XRVIpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGJvdW5kKG5vZGUsIGZyb21Cb3VuZCwgTk9fQk9VTkQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFBlcmZvcm1zIGEgZmluZCBvbiB0aGUgdW5kZXJseWluZyB0cmVlIGFmdGVyIGNvbnN0cmFpbmluZyBpdCB0byB0aGUKKyAgICAgICAgICogYm91bmRzIG9mIHRoaXMgdmlldy4gRXhhbXBsZXM6CisgICAgICAgICAqCisgICAgICAgICAqICAgYm91bmQgaXMgKEEuLkMpCisgICAgICAgICAqICAgZmluZEJvdW5kZWQoQiwgRkxPT1IpIHN0YXlzIHNvdXJjZS5maW5kKEIsIEZMT09SKQorICAgICAgICAgKgorICAgICAgICAgKiAgIGJvdW5kIGlzIChBLi5DKQorICAgICAgICAgKiAgIGZpbmRCb3VuZGVkKEMsIEZMT09SKSBiZWNvbWVzIHNvdXJjZS5maW5kKEMsIExPV0VSKQorICAgICAgICAgKgorICAgICAgICAgKiAgIGJvdW5kIGlzIChBLi5DKQorICAgICAgICAgKiAgIGZpbmRCb3VuZGVkKEQsIExPV0VSKSBiZWNvbWVzIHNvdXJjZS5maW5kKEMsIExPV0VSKQorICAgICAgICAgKgorICAgICAgICAgKiAgIGJvdW5kIGlzIChBLi5DXQorICAgICAgICAgKiAgIGZpbmRCb3VuZGVkKEQsIEZMT09SKSBiZWNvbWVzIHNvdXJjZS5maW5kKEMsIEZMT09SKQorICAgICAgICAgKgorICAgICAgICAgKiAgIGJvdW5kIGlzIChBLi5DXQorICAgICAgICAgKiAgIGZpbmRCb3VuZGVkKEQsIExPV0VSKSBiZWNvbWVzIHNvdXJjZS5maW5kKEMsIEZMT09SKQorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBFbnRyeTxLLCBWPiBmaW5kQm91bmRlZChLIGtleSwgUmVsYXRpb24gcmVsYXRpb24pIHsKKyAgICAgICAgICAgIHJlbGF0aW9uID0gcmVsYXRpb24uZm9yT3JkZXIoYXNjZW5kaW5nKTsKKyAgICAgICAgICAgIEJvdW5kIGZyb21Cb3VuZEZvckNoZWNrID0gZnJvbUJvdW5kOworICAgICAgICAgICAgQm91bmQgdG9Cb3VuZEZvckNoZWNrID0gdG9Cb3VuZDsKKworICAgICAgICAgICAgaWYgKHRvQm91bmQgIT0gTk9fQk9VTkQgJiYgKHJlbGF0aW9uID09IExPV0VSIHx8IHJlbGF0aW9uID09IEZMT09SKSkgeworICAgICAgICAgICAgICAgIGludCBjb21wYXJpc29uID0gY29tcGFyYXRvci5jb21wYXJlKHRvLCBrZXkpOworICAgICAgICAgICAgICAgIGlmIChjb21wYXJpc29uIDw9IDApIHsKKyAgICAgICAgICAgICAgICAgICAga2V5ID0gdG87CisgICAgICAgICAgICAgICAgICAgIGlmICh0b0JvdW5kID09IEVYQ0xVU0lWRSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRpb24gPSBMT1dFUjsgLy8gJ3RvJyBpcyB0b28gaGlnaAorICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbXBhcmlzb24gPCAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZWxhdGlvbiA9IEZMT09SOyAvLyB3ZSBhbHJlYWR5IHdlbnQgbG93ZXIKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0b0JvdW5kRm9yQ2hlY2sgPSBOT19CT1VORDsgLy8gd2UndmUgYWxyZWFkeSBjaGVja2VkIHRoZSB1cHBlciBib3VuZAorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZnJvbUJvdW5kICE9IE5PX0JPVU5EICYmIChyZWxhdGlvbiA9PSBDRUlMSU5HIHx8IHJlbGF0aW9uID09IEhJR0hFUikpIHsKKyAgICAgICAgICAgICAgICBpbnQgY29tcGFyaXNvbiA9IGNvbXBhcmF0b3IuY29tcGFyZShmcm9tLCBrZXkpOworICAgICAgICAgICAgICAgIGlmIChjb21wYXJpc29uID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAga2V5ID0gZnJvbTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZyb21Cb3VuZCA9PSBFWENMVVNJVkUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlbGF0aW9uID0gSElHSEVSOyAvLyAnZnJvbScgaXMgdG9vIGxvdworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbXBhcmlzb24gPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZWxhdGlvbiA9IENFSUxJTkc7IC8vIHdlIGFscmVhZHkgd2VudCBoaWdoZXIKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmcm9tQm91bmRGb3JDaGVjayA9IE5PX0JPVU5EOyAvLyB3ZSd2ZSBhbHJlYWR5IGNoZWNrZWQgdGhlIGxvd2VyIGJvdW5kCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBib3VuZChmaW5kKGtleSwgcmVsYXRpb24pLCBmcm9tQm91bmRGb3JDaGVjaywgdG9Cb3VuZEZvckNoZWNrKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFbnRyeTxLLCBWPiBsb3dlckVudHJ5KEsga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gaW1tdXRhYmxlQ29weShmaW5kQm91bmRlZChrZXksIExPV0VSKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSyBsb3dlcktleShLIGtleSkgeworICAgICAgICAgICAgRW50cnk8SywgVj4gZW50cnkgPSBmaW5kQm91bmRlZChrZXksIExPV0VSKTsKKyAgICAgICAgICAgIHJldHVybiBlbnRyeSAhPSBudWxsID8gZW50cnkuZ2V0S2V5KCkgOiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEVudHJ5PEssIFY+IGZsb29yRW50cnkoSyBrZXkpIHsKKyAgICAgICAgICAgIHJldHVybiBpbW11dGFibGVDb3B5KGZpbmRCb3VuZGVkKGtleSwgRkxPT1IpKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBLIGZsb29yS2V5KEsga2V5KSB7CisgICAgICAgICAgICBFbnRyeTxLLCBWPiBlbnRyeSA9IGZpbmRCb3VuZGVkKGtleSwgRkxPT1IpOworICAgICAgICAgICAgcmV0dXJuIGVudHJ5ICE9IG51bGwgPyBlbnRyeS5nZXRLZXkoKSA6IG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgRW50cnk8SywgVj4gY2VpbGluZ0VudHJ5KEsga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gaW1tdXRhYmxlQ29weShmaW5kQm91bmRlZChrZXksIENFSUxJTkcpKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBLIGNlaWxpbmdLZXkoSyBrZXkpIHsKKyAgICAgICAgICAgIEVudHJ5PEssIFY+IGVudHJ5ID0gZmluZEJvdW5kZWQoa2V5LCBDRUlMSU5HKTsKKyAgICAgICAgICAgIHJldHVybiBlbnRyeSAhPSBudWxsID8gZW50cnkuZ2V0S2V5KCkgOiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEVudHJ5PEssIFY+IGhpZ2hlckVudHJ5KEsga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gaW1tdXRhYmxlQ29weShmaW5kQm91bmRlZChrZXksIEhJR0hFUikpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEsgaGlnaGVyS2V5KEsga2V5KSB7CisgICAgICAgICAgICBFbnRyeTxLLCBWPiBlbnRyeSA9IGZpbmRCb3VuZGVkKGtleSwgSElHSEVSKTsKKyAgICAgICAgICAgIHJldHVybiBlbnRyeSAhPSBudWxsID8gZW50cnkuZ2V0S2V5KCkgOiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIENvbXBhcmF0b3I8PyBzdXBlciBLPiBjb21wYXJhdG9yKCkgeworICAgICAgICAgIGlmIChhc2NlbmRpbmcpIHsKKyAgICAgICAgICAgIHJldHVybiBUcmVlTWFwLnRoaXMuY29tcGFyYXRvcigpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMucmV2ZXJzZU9yZGVyKGNvbXBhcmF0b3IpOworICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIFZpZXcgZmFjdG9yeSBtZXRob2RzLgorICAgICAgICAgKi8KKworICAgICAgICBwcml2YXRlIHRyYW5zaWVudCBCb3VuZGVkRW50cnlTZXQgZW50cnlTZXQ7CisgICAgICAgIHByaXZhdGUgdHJhbnNpZW50IEJvdW5kZWRLZXlTZXQga2V5U2V0OworCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU2V0PEVudHJ5PEssIFY+PiBlbnRyeVNldCgpIHsKKyAgICAgICAgICAgIEJvdW5kZWRFbnRyeVNldCByZXN1bHQgPSBlbnRyeVNldDsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQgIT0gbnVsbCA/IHJlc3VsdCA6IChlbnRyeVNldCA9IG5ldyBCb3VuZGVkRW50cnlTZXQoKSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFNldDxLPiBrZXlTZXQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmF2aWdhYmxlS2V5U2V0KCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTmF2aWdhYmxlU2V0PEs+IG5hdmlnYWJsZUtleVNldCgpIHsKKyAgICAgICAgICAgIEJvdW5kZWRLZXlTZXQgcmVzdWx0ID0ga2V5U2V0OworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCAhPSBudWxsID8gcmVzdWx0IDogKGtleVNldCA9IG5ldyBCb3VuZGVkS2V5U2V0KCkpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE5hdmlnYWJsZU1hcDxLLCBWPiBkZXNjZW5kaW5nTWFwKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBCb3VuZGVkTWFwKCFhc2NlbmRpbmcsIGZyb20sIGZyb21Cb3VuZCwgdG8sIHRvQm91bmQpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE5hdmlnYWJsZVNldDxLPiBkZXNjZW5kaW5nS2V5U2V0KCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBCb3VuZGVkTWFwKCFhc2NlbmRpbmcsIGZyb20sIGZyb21Cb3VuZCwgdG8sIHRvQm91bmQpLm5hdmlnYWJsZUtleVNldCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE5hdmlnYWJsZU1hcDxLLCBWPiBzdWJNYXAoSyBmcm9tLCBib29sZWFuIGZyb21JbmNsdXNpdmUsIEsgdG8sIGJvb2xlYW4gdG9JbmNsdXNpdmUpIHsKKyAgICAgICAgICAgIEJvdW5kIGZyb21Cb3VuZCA9IGZyb21JbmNsdXNpdmUgPyBJTkNMVVNJVkUgOiBFWENMVVNJVkU7CisgICAgICAgICAgICBCb3VuZCB0b0JvdW5kID0gdG9JbmNsdXNpdmUgPyBJTkNMVVNJVkUgOiBFWENMVVNJVkU7CisgICAgICAgICAgICByZXR1cm4gc3ViTWFwKGZyb20sIGZyb21Cb3VuZCwgdG8sIHRvQm91bmQpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE5hdmlnYWJsZU1hcDxLLCBWPiBzdWJNYXAoSyBmcm9tSW5jbHVzaXZlLCBLIHRvRXhjbHVzaXZlKSB7CisgICAgICAgICAgICByZXR1cm4gc3ViTWFwKGZyb21JbmNsdXNpdmUsIElOQ0xVU0lWRSwgdG9FeGNsdXNpdmUsIEVYQ0xVU0lWRSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTmF2aWdhYmxlTWFwPEssIFY+IGhlYWRNYXAoSyB0bywgYm9vbGVhbiBpbmNsdXNpdmUpIHsKKyAgICAgICAgICAgIEJvdW5kIHRvQm91bmQgPSBpbmNsdXNpdmUgPyBJTkNMVVNJVkUgOiBFWENMVVNJVkU7CisgICAgICAgICAgICByZXR1cm4gc3ViTWFwKG51bGwsIE5PX0JPVU5ELCB0bywgdG9Cb3VuZCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTmF2aWdhYmxlTWFwPEssIFY+IGhlYWRNYXAoSyB0b0V4Y2x1c2l2ZSkgeworICAgICAgICAgICAgcmV0dXJuIHN1Yk1hcChudWxsLCBOT19CT1VORCwgdG9FeGNsdXNpdmUsIEVYQ0xVU0lWRSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTmF2aWdhYmxlTWFwPEssIFY+IHRhaWxNYXAoSyBmcm9tLCBib29sZWFuIGluY2x1c2l2ZSkgeworICAgICAgICAgICAgQm91bmQgZnJvbUJvdW5kID0gaW5jbHVzaXZlID8gSU5DTFVTSVZFIDogRVhDTFVTSVZFOworICAgICAgICAgICAgcmV0dXJuIHN1Yk1hcChmcm9tLCBmcm9tQm91bmQsIG51bGwsIE5PX0JPVU5EKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBOYXZpZ2FibGVNYXA8SywgVj4gdGFpbE1hcChLIGZyb21JbmNsdXNpdmUpIHsKKyAgICAgICAgICAgIHJldHVybiBzdWJNYXAoZnJvbUluY2x1c2l2ZSwgSU5DTFVTSVZFLCBudWxsLCBOT19CT1VORCk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIE5hdmlnYWJsZU1hcDxLLCBWPiBzdWJNYXAoSyBmcm9tLCBCb3VuZCBmcm9tQm91bmQsIEsgdG8sIEJvdW5kIHRvQm91bmQpIHsKKyAgICAgICAgICAgIGlmICghYXNjZW5kaW5nKSB7CisgICAgICAgICAgICAgICAgSyBmcm9tVG1wID0gZnJvbTsKKyAgICAgICAgICAgICAgICBCb3VuZCBmcm9tQm91bmRUbXAgPSBmcm9tQm91bmQ7CisgICAgICAgICAgICAgICAgZnJvbSA9IHRvOworICAgICAgICAgICAgICAgIGZyb21Cb3VuZCA9IHRvQm91bmQ7CisgICAgICAgICAgICAgICAgdG8gPSBmcm9tVG1wOworICAgICAgICAgICAgICAgIHRvQm91bmQgPSBmcm9tQm91bmRUbXA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBJZiBib3RoIHRoZSBjdXJyZW50IGFuZCByZXF1ZXN0ZWQgYm91bmRzIGFyZSBleGNsdXNpdmUsIHRoZSBpc0luQm91bmRzIGNoZWNrIG11c3QgYmUKKyAgICAgICAgICAgICAqIGluY2x1c2l2ZS4gRm9yIGV4YW1wbGUsIHRvIGNyZWF0ZSAoQy4uRikgZnJvbSAoQS4uRiksIHRoZSBib3VuZCAnRicgaXMgaW4gYm91bmRzLgorICAgICAgICAgICAgICovCisKKyAgICAgICAgICAgIGlmIChmcm9tQm91bmQgPT0gTk9fQk9VTkQpIHsKKyAgICAgICAgICAgICAgICBmcm9tID0gdGhpcy5mcm9tOworICAgICAgICAgICAgICAgIGZyb21Cb3VuZCA9IHRoaXMuZnJvbUJvdW5kOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBCb3VuZCBmcm9tQm91bmRUb0NoZWNrID0gZnJvbUJvdW5kID09IHRoaXMuZnJvbUJvdW5kID8gSU5DTFVTSVZFIDogdGhpcy5mcm9tQm91bmQ7CisgICAgICAgICAgICAgICAgaWYgKCFpc0luQm91bmRzKGZyb20sIGZyb21Cb3VuZFRvQ2hlY2ssIHRoaXMudG9Cb3VuZCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgb3V0T2ZCb3VuZHModG8sIGZyb21Cb3VuZFRvQ2hlY2ssIHRoaXMudG9Cb3VuZCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAodG9Cb3VuZCA9PSBOT19CT1VORCkgeworICAgICAgICAgICAgICAgIHRvID0gdGhpcy50bzsKKyAgICAgICAgICAgICAgICB0b0JvdW5kID0gdGhpcy50b0JvdW5kOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBCb3VuZCB0b0JvdW5kVG9DaGVjayA9IHRvQm91bmQgPT0gdGhpcy50b0JvdW5kID8gSU5DTFVTSVZFIDogdGhpcy50b0JvdW5kOworICAgICAgICAgICAgICAgIGlmICghaXNJbkJvdW5kcyh0bywgdGhpcy5mcm9tQm91bmQsIHRvQm91bmRUb0NoZWNrKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBvdXRPZkJvdW5kcyh0bywgdGhpcy5mcm9tQm91bmQsIHRvQm91bmRUb0NoZWNrKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBuZXcgQm91bmRlZE1hcChhc2NlbmRpbmcsIGZyb20sIGZyb21Cb3VuZCwgdG8sIHRvQm91bmQpOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gb3V0T2ZCb3VuZHMoT2JqZWN0IHZhbHVlLCBCb3VuZCBmcm9tQm91bmQsIEJvdW5kIHRvQm91bmQpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKHZhbHVlICsgIiBub3QgaW4gcmFuZ2UgIgorICAgICAgICAgICAgICAgICAgICArIGZyb21Cb3VuZC5sZWZ0Q2FwKGZyb20pICsgIi4uIiArIHRvQm91bmQucmlnaHRDYXAodG8pKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIEJvdW5kZWQgdmlldyBpbXBsZW1lbnRhdGlvbnMuCisgICAgICAgICAqLworCisgICAgICAgIGFic3RyYWN0IGNsYXNzIEJvdW5kZWRJdGVyYXRvcjxUPiBleHRlbmRzIE1hcEl0ZXJhdG9yPFQ+IHsKKyAgICAgICAgICAgIHByb3RlY3RlZCBCb3VuZGVkSXRlcmF0b3IoTm9kZTxLLCBWPiBuZXh0KSB7CisgICAgICAgICAgICAgICAgc3VwZXIobmV4dCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgTm9kZTxLLCBWPiBzdGVwRm9yd2FyZCgpIHsKKyAgICAgICAgICAgICAgICBOb2RlPEssIFY+IHJlc3VsdCA9IHN1cGVyLnN0ZXBGb3J3YXJkKCk7CisgICAgICAgICAgICAgICAgaWYgKG5leHQgIT0gbnVsbCAmJiAhaXNJbkJvdW5kcyhuZXh0LmtleSwgTk9fQk9VTkQsIHRvQm91bmQpKSB7CisgICAgICAgICAgICAgICAgICAgIG5leHQgPSBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIE5vZGU8SywgVj4gc3RlcEJhY2t3YXJkKCkgeworICAgICAgICAgICAgICAgIE5vZGU8SywgVj4gcmVzdWx0ID0gc3VwZXIuc3RlcEJhY2t3YXJkKCk7CisgICAgICAgICAgICAgICAgaWYgKG5leHQgIT0gbnVsbCAmJiAhaXNJbkJvdW5kcyhuZXh0LmtleSwgZnJvbUJvdW5kLCBOT19CT1VORCkpIHsKKyAgICAgICAgICAgICAgICAgICAgbmV4dCA9IG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBjbGFzcyBCb3VuZGVkRW50cnlTZXQgZXh0ZW5kcyBBYnN0cmFjdFNldDxFbnRyeTxLLCBWPj4geworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gQm91bmRlZE1hcC50aGlzLnNpemUoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIEJvdW5kZWRNYXAudGhpcy5pc0VtcHR5KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgSXRlcmF0b3I8RW50cnk8SywgVj4+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQm91bmRlZEl0ZXJhdG9yPEVudHJ5PEssIFY+PihlbmRwb2ludCh0cnVlKSkgeworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgRW50cnk8SywgVj4gbmV4dCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhc2NlbmRpbmcgPyBzdGVwRm9yd2FyZCgpIDogc3RlcEJhY2t3YXJkKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgICAgICBpZiAoIShvIGluc3RhbmNlb2YgRW50cnkpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgRW50cnk8PywgPz4gZW50cnkgPSAoRW50cnk8PywgPz4pIG87CisgICAgICAgICAgICAgICAgcmV0dXJuIGlzSW5Cb3VuZHMoZW50cnkuZ2V0S2V5KCkpICYmIGZpbmRCeUVudHJ5KGVudHJ5KSAhPSBudWxsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvKSB7CisgICAgICAgICAgICAgICAgaWYgKCEobyBpbnN0YW5jZW9mIEVudHJ5KSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIEVudHJ5PD8sID8+IGVudHJ5ID0gKEVudHJ5PD8sID8+KSBvOworICAgICAgICAgICAgICAgIHJldHVybiBpc0luQm91bmRzKGVudHJ5LmdldEtleSgpKSAmJiBUcmVlTWFwLnRoaXMuZW50cnlTZXQoKS5yZW1vdmUoZW50cnkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZmluYWwgY2xhc3MgQm91bmRlZEtleVNldCBleHRlbmRzIEFic3RyYWN0U2V0PEs+IGltcGxlbWVudHMgTmF2aWdhYmxlU2V0PEs+IHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIEJvdW5kZWRNYXAudGhpcy5zaXplKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICAgICAgICAgIHJldHVybiBCb3VuZGVkTWFwLnRoaXMuaXNFbXB0eSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEl0ZXJhdG9yPEs+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQm91bmRlZEl0ZXJhdG9yPEs+KGVuZHBvaW50KHRydWUpKSB7CisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBLIG5leHQoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGFzY2VuZGluZyA/IHN0ZXBGb3J3YXJkKCkgOiBzdGVwQmFja3dhcmQoKSkua2V5OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIEl0ZXJhdG9yPEs+IGRlc2NlbmRpbmdJdGVyYXRvcigpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJvdW5kZWRJdGVyYXRvcjxLPihlbmRwb2ludChmYWxzZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIEsgbmV4dCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoYXNjZW5kaW5nID8gc3RlcEJhY2t3YXJkKCkgOiBzdGVwRm9yd2FyZCgpKS5rZXk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IGtleSkgeworICAgICAgICAgICAgICAgIHJldHVybiBpc0luQm91bmRzKGtleSkgJiYgZmluZEJ5T2JqZWN0KGtleSkgIT0gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3Qga2V5KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGlzSW5Cb3VuZHMoa2V5KSAmJiByZW1vdmVJbnRlcm5hbEJ5S2V5KGtleSkgIT0gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIE5hdmlnYWJsZSBtZXRob2RzLgorICAgICAgICAgICAgICovCisKKyAgICAgICAgICAgIHB1YmxpYyBLIGZpcnN0KCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmaXJzdEtleSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgSyBwb2xsRmlyc3QoKSB7CisgICAgICAgICAgICAgICAgRW50cnk8SywgPz4gZW50cnkgPSBwb2xsRmlyc3RFbnRyeSgpOworICAgICAgICAgICAgICAgIHJldHVybiBlbnRyeSAhPSBudWxsID8gZW50cnkuZ2V0S2V5KCkgOiBudWxsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgSyBsYXN0KCkgeworICAgICAgICAgICAgICAgIHJldHVybiBsYXN0S2V5KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBLIHBvbGxMYXN0KCkgeworICAgICAgICAgICAgICAgIEVudHJ5PEssID8+IGVudHJ5ID0gcG9sbExhc3RFbnRyeSgpOworICAgICAgICAgICAgICAgIHJldHVybiBlbnRyeSAhPSBudWxsID8gZW50cnkuZ2V0S2V5KCkgOiBudWxsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgSyBsb3dlcihLIGtleSkgeworICAgICAgICAgICAgICAgIHJldHVybiBsb3dlcktleShrZXkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgSyBmbG9vcihLIGtleSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmbG9vcktleShrZXkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgSyBjZWlsaW5nKEsga2V5KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNlaWxpbmdLZXkoa2V5KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIEsgaGlnaGVyKEsga2V5KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGhpZ2hlcktleShrZXkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgQ29tcGFyYXRvcjw/IHN1cGVyIEs+IGNvbXBhcmF0b3IoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIEJvdW5kZWRNYXAudGhpcy5jb21wYXJhdG9yKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBWaWV3IGZhY3RvcnkgbWV0aG9kcy4KKyAgICAgICAgICAgICAqLworCisgICAgICAgICAgICBwdWJsaWMgTmF2aWdhYmxlU2V0PEs+IHN1YlNldChLIGZyb20sIGJvb2xlYW4gZnJvbUluY2x1c2l2ZSwgSyB0bywgYm9vbGVhbiB0b0luY2x1c2l2ZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBzdWJNYXAoZnJvbSwgZnJvbUluY2x1c2l2ZSwgdG8sIHRvSW5jbHVzaXZlKS5uYXZpZ2FibGVLZXlTZXQoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIFNvcnRlZFNldDxLPiBzdWJTZXQoSyBmcm9tSW5jbHVzaXZlLCBLIHRvRXhjbHVzaXZlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1Yk1hcChmcm9tSW5jbHVzaXZlLCB0b0V4Y2x1c2l2ZSkubmF2aWdhYmxlS2V5U2V0KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBOYXZpZ2FibGVTZXQ8Sz4gaGVhZFNldChLIHRvLCBib29sZWFuIGluY2x1c2l2ZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBoZWFkTWFwKHRvLCBpbmNsdXNpdmUpLm5hdmlnYWJsZUtleVNldCgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgU29ydGVkU2V0PEs+IGhlYWRTZXQoSyB0b0V4Y2x1c2l2ZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBoZWFkTWFwKHRvRXhjbHVzaXZlKS5uYXZpZ2FibGVLZXlTZXQoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIE5hdmlnYWJsZVNldDxLPiB0YWlsU2V0KEsgZnJvbSwgYm9vbGVhbiBpbmNsdXNpdmUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdGFpbE1hcChmcm9tLCBpbmNsdXNpdmUpLm5hdmlnYWJsZUtleVNldCgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgU29ydGVkU2V0PEs+IHRhaWxTZXQoSyBmcm9tSW5jbHVzaXZlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRhaWxNYXAoZnJvbUluY2x1c2l2ZSkubmF2aWdhYmxlS2V5U2V0KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBOYXZpZ2FibGVTZXQ8Sz4gZGVzY2VuZGluZ1NldCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJvdW5kZWRNYXAoIWFzY2VuZGluZywgZnJvbSwgZnJvbUJvdW5kLCB0bywgdG9Cb3VuZCkubmF2aWdhYmxlS2V5U2V0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBPYmplY3Qgd3JpdGVSZXBsYWNlKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gYXNjZW5kaW5nCisgICAgICAgICAgICAgICAgICAgID8gbmV3IEFzY2VuZGluZ1N1Yk1hcDxLLCBWPihUcmVlTWFwLnRoaXMsIGZyb20sIGZyb21Cb3VuZCwgdG8sIHRvQm91bmQpCisgICAgICAgICAgICAgICAgICAgIDogbmV3IERlc2NlbmRpbmdTdWJNYXA8SywgVj4oVHJlZU1hcC50aGlzLCBmcm9tLCBmcm9tQm91bmQsIHRvLCB0b0JvdW5kKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgaXRlcmF0aW9uLgorICAgICAqLworICAgIHN0YXRpYyBpbnQgY291bnQoSXRlcmF0b3I8Pz4gaXRlcmF0b3IpIHsKKyAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgeworICAgICAgICAgICAgaXRlcmF0b3IubmV4dCgpOworICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY291bnQ7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBTZXJpYWxpemF0aW9uCisgICAgICovCisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA5MTkyODY1NDU4NjYxMjQwMDZMOworCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN0cmVhbS5wdXRGaWVsZHMoKS5wdXQoImNvbXBhcmF0b3IiLCBjb21wYXJhdG9yICE9IE5BVFVSQUxfT1JERVIgPyBjb21wYXJhdG9yIDogbnVsbCk7CisgICAgICAgIHN0cmVhbS53cml0ZUZpZWxkcygpOworICAgICAgICBzdHJlYW0ud3JpdGVJbnQoc2l6ZSk7CisgICAgICAgIGZvciAoTWFwLkVudHJ5PEssIFY+IGVudHJ5IDogZW50cnlTZXQoKSkgeworICAgICAgICAgICAgc3RyZWFtLndyaXRlT2JqZWN0KGVudHJ5LmdldEtleSgpKTsKKyAgICAgICAgICAgIHN0cmVhbS53cml0ZU9iamVjdChlbnRyeS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSAvLyB3ZSBoYXZlIHRvIHRydXN0IHRoYXQga2V5cyBhcmUgS3MgYW5kIHZhbHVlcyBhcmUgVnMKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIEdldEZpZWxkIGZpZWxkcyA9IHN0cmVhbS5yZWFkRmllbGRzKCk7CisgICAgICAgIGNvbXBhcmF0b3IgPSAoQ29tcGFyYXRvcjw/IHN1cGVyIEs+KSBmaWVsZHMuZ2V0KCJjb21wYXJhdG9yIiwgbnVsbCk7CisgICAgICAgIGlmIChjb21wYXJhdG9yID09IG51bGwpIHsKKyAgICAgICAgICAgIGNvbXBhcmF0b3IgPSAoQ29tcGFyYXRvcjw/IHN1cGVyIEs+KSBOQVRVUkFMX09SREVSOworICAgICAgICB9CisgICAgICAgIGludCBzaXplID0gc3RyZWFtLnJlYWRJbnQoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgICAgIHB1dEludGVybmFsKChLKSBzdHJlYW0ucmVhZE9iamVjdCgpLCAoVikgc3RyZWFtLnJlYWRPYmplY3QoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgTmF2aWdhYmxlU3ViTWFwPEssIFY+IGV4dGVuZHMgQWJzdHJhY3RNYXA8SywgVj4gaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjEwMjk5NzM0NTczMDc1MzAxNkw7CisgICAgICAgIFRyZWVNYXA8SywgVj4gbTsKKyAgICAgICAgT2JqZWN0IGxvOworICAgICAgICBPYmplY3QgaGk7CisgICAgICAgIGJvb2xlYW4gZnJvbVN0YXJ0OworICAgICAgICBib29sZWFuIHRvRW5kOworICAgICAgICBib29sZWFuIGxvSW5jbHVzaXZlOworICAgICAgICBib29sZWFuIGhpSW5jbHVzaXZlOworCisgICAgICAgIE5hdmlnYWJsZVN1Yk1hcChUcmVlTWFwPEssIFY+IGRlbGVnYXRlLCBLIGZyb20sIEJvdW5kIGZyb21Cb3VuZCwgSyB0bywgQm91bmQgdG9Cb3VuZCkgeworICAgICAgICAgICAgdGhpcy5tID0gZGVsZWdhdGU7CisgICAgICAgICAgICB0aGlzLmxvID0gZnJvbTsKKyAgICAgICAgICAgIHRoaXMuaGkgPSB0bzsKKyAgICAgICAgICAgIHRoaXMuZnJvbVN0YXJ0ID0gZnJvbUJvdW5kID09IE5PX0JPVU5EOworICAgICAgICAgICAgdGhpcy50b0VuZCA9IHRvQm91bmQgPT0gTk9fQk9VTkQ7CisgICAgICAgICAgICB0aGlzLmxvSW5jbHVzaXZlID0gZnJvbUJvdW5kID09IElOQ0xVU0lWRTsKKyAgICAgICAgICAgIHRoaXMuaGlJbmNsdXNpdmUgPSB0b0JvdW5kID09IElOQ0xVU0lWRTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU2V0PEVudHJ5PEssIFY+PiBlbnRyeVNldCgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIC8vIHdlIGhhdmUgdG8gdHJ1c3QgdGhhdCB0aGUgYm91bmRzIGFyZSBLcworICAgICAgICBwcm90ZWN0ZWQgT2JqZWN0IHJlYWRSZXNvbHZlKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBCb3VuZCBmcm9tQm91bmQgPSBmcm9tU3RhcnQgPyBOT19CT1VORCA6IChsb0luY2x1c2l2ZSA/IElOQ0xVU0lWRSA6IEVYQ0xVU0lWRSk7CisgICAgICAgICAgICBCb3VuZCB0b0JvdW5kID0gdG9FbmQgPyBOT19CT1VORCA6IChoaUluY2x1c2l2ZSA/IElOQ0xVU0lWRSA6IEVYQ0xVU0lWRSk7CisgICAgICAgICAgICBib29sZWFuIGFzY2VuZGluZyA9ICEodGhpcyBpbnN0YW5jZW9mIERlc2NlbmRpbmdTdWJNYXApOworICAgICAgICAgICAgcmV0dXJuIG0ubmV3IEJvdW5kZWRNYXAoYXNjZW5kaW5nLCAoSykgbG8sIGZyb21Cb3VuZCwgKEspIGhpLCB0b0JvdW5kKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBEZXNjZW5kaW5nU3ViTWFwPEssIFY+IGV4dGVuZHMgTmF2aWdhYmxlU3ViTWFwPEssIFY+IHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gOTEyOTg2NTQ1ODY2MTIwNDYwTDsKKyAgICAgICAgQ29tcGFyYXRvcjxLPiByZXZlcnNlQ29tcGFyYXRvcjsKKyAgICAgICAgRGVzY2VuZGluZ1N1Yk1hcChUcmVlTWFwPEssIFY+IGRlbGVnYXRlLCBLIGZyb20sIEJvdW5kIGZyb21Cb3VuZCwgSyB0bywgQm91bmQgdG9Cb3VuZCkgeworICAgICAgICAgICAgc3VwZXIoZGVsZWdhdGUsIGZyb20sIGZyb21Cb3VuZCwgdG8sIHRvQm91bmQpOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIEFzY2VuZGluZ1N1Yk1hcDxLLCBWPiBleHRlbmRzIE5hdmlnYWJsZVN1Yk1hcDxLLCBWPiB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDkxMjk4NjU0NTg2NjEyNDA2MEw7CisgICAgICAgIEFzY2VuZGluZ1N1Yk1hcChUcmVlTWFwPEssIFY+IGRlbGVnYXRlLCBLIGZyb20sIEJvdW5kIGZyb21Cb3VuZCwgSyB0bywgQm91bmQgdG9Cb3VuZCkgeworICAgICAgICAgICAgc3VwZXIoZGVsZWdhdGUsIGZyb20sIGZyb21Cb3VuZCwgdG8sIHRvQm91bmQpOworICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgU3ViTWFwIGV4dGVuZHMgQWJzdHJhY3RNYXA8SywgVj4gaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjUyMDc4NjQ1ODk1MDUxNjA5N0w7CisgICAgICAgIE9iamVjdCBmcm9tS2V5OworICAgICAgICBPYmplY3QgdG9LZXk7CisgICAgICAgIGJvb2xlYW4gZnJvbVN0YXJ0OworICAgICAgICBib29sZWFuIHRvRW5kOworCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU2V0PEVudHJ5PEssIFY+PiBlbnRyeVNldCgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIC8vIHdlIGhhdmUgdG8gdHJ1c3QgdGhhdCB0aGUgYm91bmRzIGFyZSBLcworICAgICAgICBwcm90ZWN0ZWQgT2JqZWN0IHJlYWRSZXNvbHZlKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBCb3VuZCBmcm9tQm91bmQgPSBmcm9tU3RhcnQgPyBOT19CT1VORCA6IElOQ0xVU0lWRTsKKyAgICAgICAgICAgIEJvdW5kIHRvQm91bmQgPSB0b0VuZCA/IE5PX0JPVU5EIDogRVhDTFVTSVZFOworICAgICAgICAgICAgcmV0dXJuIG5ldyBCb3VuZGVkTWFwKHRydWUsIChLKSBmcm9tS2V5LCBmcm9tQm91bmQsIChLKSB0b0tleSwgdG9Cb3VuZCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1RyZWVTZXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvVHJlZVNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUwMjMyOWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1RyZWVTZXQuamF2YQpAQCAtMCwwICsxLDUwMCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CisKKy8qKgorICogVHJlZVNldCBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiBTb3J0ZWRTZXQuIEFsbCBvcHRpb25hbCBvcGVyYXRpb25zIChhZGRpbmcKKyAqIGFuZCByZW1vdmluZykgYXJlIHN1cHBvcnRlZC4gVGhlIGVsZW1lbnRzIGNhbiBiZSBhbnkgb2JqZWN0cyB3aGljaCBhcmUKKyAqIGNvbXBhcmFibGUgdG8gZWFjaCBvdGhlciBlaXRoZXIgdXNpbmcgdGhlaXIgbmF0dXJhbCBvcmRlciBvciBhIHNwZWNpZmllZAorICogQ29tcGFyYXRvci4KKyAqCisgKiBAc2luY2UgMS4yCisgKi8KK3B1YmxpYyBjbGFzcyBUcmVlU2V0PEU+IGV4dGVuZHMgQWJzdHJhY3RTZXQ8RT4gaW1wbGVtZW50cyBOYXZpZ2FibGVTZXQ8RT4sCisgICAgICAgIENsb25lYWJsZSwgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yNDc5MTQzMDAwMDYxNjcxNTg5TDsKKworICAgIC8qKiBLZXlzIGFyZSB0aGlzIHNldCdzIGVsZW1lbnRzLiBWYWx1ZXMgYXJlIGFsd2F5cyBCb29sZWFuLlRSVUUgKi8KKyAgICBwcml2YXRlIHRyYW5zaWVudCBOYXZpZ2FibGVNYXA8RSwgT2JqZWN0PiBiYWNraW5nTWFwOworCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgTmF2aWdhYmxlU2V0PEU+IGRlc2NlbmRpbmdTZXQ7CisKKyAgICBUcmVlU2V0KE5hdmlnYWJsZU1hcDxFLCBPYmplY3Q+IG1hcCkgeworICAgICAgICBiYWNraW5nTWFwID0gbWFwOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgZW1wdHkgaW5zdGFuY2Ugb2Yge0Bjb2RlIFRyZWVTZXR9IHdoaWNoIHVzZXMgbmF0dXJhbAorICAgICAqIG9yZGVyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBUcmVlU2V0KCkgeworICAgICAgICBiYWNraW5nTWFwID0gbmV3IFRyZWVNYXA8RSwgT2JqZWN0PigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFRyZWVTZXR9IHdoaWNoIHVzZXMgbmF0dXJhbCBvcmRlcmluZworICAgICAqIGFuZCBjb250YWluaW5nIHRoZSB1bmlxdWUgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIG9mIGVsZW1lbnRzIHRvIGFkZC4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIHdoZW4gYW4gZWxlbWVudCBpbiB0aGUgY29sbGVjdGlvbiBkb2VzIG5vdCBpbXBsZW1lbnQgdGhlCisgICAgICogICAgICAgICAgICAgICAgQ29tcGFyYWJsZSBpbnRlcmZhY2UsIG9yIHRoZSBlbGVtZW50cyBpbiB0aGUgY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGNhbm5vdCBiZSBjb21wYXJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVHJlZVNldChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjb2xsZWN0aW9uKSB7CisgICAgICAgIHRoaXMoKTsKKyAgICAgICAgYWRkQWxsKGNvbGxlY3Rpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgZW1wdHkgaW5zdGFuY2Ugb2Yge0Bjb2RlIFRyZWVTZXR9IHdoaWNoIHVzZXMgdGhlCisgICAgICogc3BlY2lmaWVkIGNvbXBhcmF0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29tcGFyYXRvcgorICAgICAqICAgICAgICAgICAgdGhlIGNvbXBhcmF0b3IgdG8gdXNlLgorICAgICAqLworICAgIHB1YmxpYyBUcmVlU2V0KENvbXBhcmF0b3I8PyBzdXBlciBFPiBjb21wYXJhdG9yKSB7CisgICAgICAgIGJhY2tpbmdNYXAgPSBuZXcgVHJlZU1hcDxFLCBPYmplY3Q+KGNvbXBhcmF0b3IpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFRyZWVTZXR9IGNvbnRhaW5pbmcgdGhlIGVsZW1lbnRzIG9mCisgICAgICogdGhlIHNwZWNpZmllZCBTb3J0ZWRTZXQgYW5kIHVzaW5nIHRoZSBzYW1lIENvbXBhcmF0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2V0CisgICAgICogICAgICAgICAgICB0aGUgU29ydGVkU2V0IG9mIGVsZW1lbnRzIHRvIGFkZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVHJlZVNldChTb3J0ZWRTZXQ8RT4gc2V0KSB7CisgICAgICAgIHRoaXMoc2V0LmNvbXBhcmF0b3IoKSk7CisgICAgICAgIEl0ZXJhdG9yPEU+IGl0ID0gc2V0Lml0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIGFkZChpdC5uZXh0KCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIG9iamVjdCB0byB0aGlzIHtAY29kZSBUcmVlU2V0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYWRkLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IHdoZW4gdGhpcyB7QGNvZGUgVHJlZVNldH0gZGlkIG5vdCBhbHJlYWR5IGNvbnRhaW4KKyAgICAgKiAgICAgICAgIHRoZSBvYmplY3QsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiB0aGUgb2JqZWN0IGNhbm5vdCBiZSBjb21wYXJlZCB3aXRoIHRoZSBlbGVtZW50cyBpbiB0aGlzCisgICAgICogICAgICAgICAgICAge0Bjb2RlIFRyZWVTZXR9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHRoZSBvYmplY3QgaXMgbnVsbCBhbmQgdGhlIGNvbXBhcmF0b3IgY2Fubm90IGhhbmRsZQorICAgICAqICAgICAgICAgICAgIG51bGwuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gYWRkKEUgb2JqZWN0KSB7CisgICAgICAgIHJldHVybiBiYWNraW5nTWFwLnB1dChvYmplY3QsIEJvb2xlYW4uVFJVRSkgPT0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBvYmplY3RzIGluIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiB0byB0aGlzIHtAY29kZSBUcmVlU2V0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2xsZWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgY29sbGVjdGlvbiBvZiBvYmplY3RzIHRvIGFkZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBUcmVlU2V0fSB3YXMgbW9kaWZpZWQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHdoZW4gYW4gb2JqZWN0IGluIHRoZSBjb2xsZWN0aW9uIGNhbm5vdCBiZSBjb21wYXJlZCB3aXRoIHRoZQorICAgICAqICAgICAgICAgICAgIGVsZW1lbnRzIGluIHRoaXMge0Bjb2RlIFRyZWVTZXR9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIGFuIG9iamVjdCBpbiB0aGUgY29sbGVjdGlvbiBpcyBudWxsIGFuZCB0aGUgY29tcGFyYXRvcgorICAgICAqICAgICAgICAgICAgIGNhbm5vdCBoYW5kbGUgbnVsbC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBhZGRBbGwoQ29sbGVjdGlvbjw/IGV4dGVuZHMgRT4gY29sbGVjdGlvbikgeworICAgICAgICByZXR1cm4gc3VwZXIuYWRkQWxsKGNvbGxlY3Rpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIGVsZW1lbnRzIGZyb20gdGhpcyB7QGNvZGUgVHJlZVNldH0sIGxlYXZpbmcgaXQgZW1wdHkuCisgICAgICoKKyAgICAgKiBAc2VlICNpc0VtcHR5CisgICAgICogQHNlZSAjc2l6ZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBiYWNraW5nTWFwLmNsZWFyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgVHJlZVNldH0gd2l0aCB0aGUgc2FtZSBlbGVtZW50cywgc2l6ZSBhbmQgY29tcGFyYXRvcgorICAgICAqIGFzIHRoaXMge0Bjb2RlIFRyZWVTZXR9LgorICAgICAqCisgICAgICogQHJldHVybiBhIHNoYWxsb3cgY29weSBvZiB0aGlzIHtAY29kZSBUcmVlU2V0fS4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5DbG9uZWFibGUKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgVHJlZVNldDxFPiBjbG9uZSA9IChUcmVlU2V0PEU+KSBzdXBlci5jbG9uZSgpOworICAgICAgICAgICAgaWYgKGJhY2tpbmdNYXAgaW5zdGFuY2VvZiBUcmVlTWFwKSB7CisgICAgICAgICAgICAgICAgY2xvbmUuYmFja2luZ01hcCA9IChOYXZpZ2FibGVNYXA8RSwgT2JqZWN0PikgKChUcmVlTWFwPEUsIE9iamVjdD4pIGJhY2tpbmdNYXApCisgICAgICAgICAgICAgICAgICAgICAgICAuY2xvbmUoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgY2xvbmUuYmFja2luZ01hcCA9IG5ldyBUcmVlTWFwPEUsIE9iamVjdD4oYmFja2luZ01hcCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gY2xvbmU7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNvbXBhcmF0b3IgdXNlZCB0byBjb21wYXJlIGVsZW1lbnRzIGluIHRoaXMge0Bjb2RlIFRyZWVTZXR9LgorICAgICAqCisgICAgICogQHJldHVybiBhIENvbXBhcmF0b3Igb3IgbnVsbCBpZiB0aGUgbmF0dXJhbCBvcmRlcmluZyBpcyB1c2VkCisgICAgICovCisgICAgcHVibGljIENvbXBhcmF0b3I8PyBzdXBlciBFPiBjb21wYXJhdG9yKCkgeworICAgICAgICByZXR1cm4gYmFja2luZ01hcC5jb21wYXJhdG9yKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VhcmNoZXMgdGhpcyB7QGNvZGUgVHJlZVNldH0gZm9yIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBzZWFyY2ggZm9yLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBvYmplY3R9IGlzIGFuIGVsZW1lbnQgb2YgdGhpcworICAgICAqICAgICAgICAge0Bjb2RlIFRyZWVTZXR9LCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHdoZW4gdGhlIG9iamVjdCBjYW5ub3QgYmUgY29tcGFyZWQgd2l0aCB0aGUgZWxlbWVudHMgaW4gdGhpcworICAgICAqICAgICAgICAgICAgIHtAY29kZSBUcmVlU2V0fS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiB0aGUgb2JqZWN0IGlzIG51bGwgYW5kIHRoZSBjb21wYXJhdG9yIGNhbm5vdCBoYW5kbGUKKyAgICAgKiAgICAgICAgICAgICBudWxsLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgcmV0dXJuIGJhY2tpbmdNYXAuY29udGFpbnNLZXkob2JqZWN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyB7QGNvZGUgVHJlZVNldH0gaGFzIG5vIGVsZW1lbnQsIG90aGVyd2lzZSBmYWxzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIHtAY29kZSBUcmVlU2V0fSBoYXMgbm8gZWxlbWVudC4KKyAgICAgKiBAc2VlICNzaXplCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgcmV0dXJuIGJhY2tpbmdNYXAuaXNFbXB0eSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gSXRlcmF0b3Igb24gdGhlIGVsZW1lbnRzIG9mIHRoaXMge0Bjb2RlIFRyZWVTZXR9LgorICAgICAqCisgICAgICogQHJldHVybiBhbiBJdGVyYXRvciBvbiB0aGUgZWxlbWVudHMgb2YgdGhpcyB7QGNvZGUgVHJlZVNldH0uCisgICAgICogQHNlZSBJdGVyYXRvcgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJdGVyYXRvcjxFPiBpdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIGJhY2tpbmdNYXAua2V5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiBAc2VlIGphdmEudXRpbC5OYXZpZ2FibGVTZXQjZGVzY2VuZGluZ0l0ZXJhdG9yKCkKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIEl0ZXJhdG9yPEU+IGRlc2NlbmRpbmdJdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIGRlc2NlbmRpbmdTZXQoKS5pdGVyYXRvcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYW4gb2NjdXJyZW5jZSBvZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBmcm9tIHRoaXMge0Bjb2RlIFRyZWVTZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byByZW1vdmUuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB7QGNvZGUgVHJlZVNldH0gd2FzIG1vZGlmaWVkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHRoZSBvYmplY3QgY2Fubm90IGJlIGNvbXBhcmVkIHdpdGggdGhlIGVsZW1lbnRzIGluIHRoaXMKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgVHJlZVNldH0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHdoZW4gdGhlIG9iamVjdCBpcyBudWxsIGFuZCB0aGUgY29tcGFyYXRvciBjYW5ub3QgaGFuZGxlCisgICAgICogICAgICAgICAgICAgbnVsbC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG9iamVjdCkgeworICAgICAgICByZXR1cm4gYmFja2luZ01hcC5yZW1vdmUob2JqZWN0KSAhPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIHtAY29kZSBUcmVlU2V0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIHtAY29kZSBUcmVlU2V0fS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgIHJldHVybiBiYWNraW5nTWFwLnNpemUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBmaXJzdCBlbGVtZW50IGluIHRoaXMgc2V0LgorICAgICAqIEBleGNlcHRpb24gTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiB3aGVuIHRoaXMgVHJlZVNldCBpcyBlbXB0eQorICAgICAqLworICAgIHB1YmxpYyBFIGZpcnN0KCkgeworICAgICAgICByZXR1cm4gYmFja2luZ01hcC5maXJzdEtleSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxhc3QgZWxlbWVudCBpbiB0aGlzIHNldC4KKyAgICAgKiBAZXhjZXB0aW9uIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gd2hlbiB0aGlzIFRyZWVTZXQgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgRSBsYXN0KCkgeworICAgICAgICByZXR1cm4gYmFja2luZ01hcC5sYXN0S2V5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogQHNlZSBqYXZhLnV0aWwuTmF2aWdhYmxlU2V0I3BvbGxGaXJzdCgpCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBFIHBvbGxGaXJzdCgpIHsKKyAgICAgICAgTWFwLkVudHJ5PEUsIE9iamVjdD4gZW50cnkgPSBiYWNraW5nTWFwLnBvbGxGaXJzdEVudHJ5KCk7CisgICAgICAgIHJldHVybiAoZW50cnkgPT0gbnVsbCkgPyBudWxsIDogZW50cnkuZ2V0S2V5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogQHNlZSBqYXZhLnV0aWwuTmF2aWdhYmxlU2V0I3BvbGxMYXN0KCkKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIEUgcG9sbExhc3QoKSB7CisgICAgICAgIE1hcC5FbnRyeTxFLCBPYmplY3Q+IGVudHJ5ID0gYmFja2luZ01hcC5wb2xsTGFzdEVudHJ5KCk7CisgICAgICAgIHJldHVybiAoZW50cnkgPT0gbnVsbCkgPyBudWxsIDogZW50cnkuZ2V0S2V5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogQHNlZSBqYXZhLnV0aWwuTmF2aWdhYmxlU2V0I2hpZ2hlcihqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgRSBoaWdoZXIoRSBlKSB7CisgICAgICAgIHJldHVybiBiYWNraW5nTWFwLmhpZ2hlcktleShlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiBAc2VlIGphdmEudXRpbC5OYXZpZ2FibGVTZXQjbG93ZXIoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIEUgbG93ZXIoRSBlKSB7CisgICAgICAgIHJldHVybiBiYWNraW5nTWFwLmxvd2VyS2V5KGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIEBzZWUgamF2YS51dGlsLk5hdmlnYWJsZVNldCNjZWlsaW5nKGphdmEubGFuZy5PYmplY3QpCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBFIGNlaWxpbmcoRSBlKSB7CisgICAgICAgIHJldHVybiBiYWNraW5nTWFwLmNlaWxpbmdLZXkoZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogQHNlZSBqYXZhLnV0aWwuTmF2aWdhYmxlU2V0I2Zsb29yKGphdmEubGFuZy5PYmplY3QpCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBFIGZsb29yKEUgZSkgeworICAgICAgICByZXR1cm4gYmFja2luZ01hcC5mbG9vcktleShlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiBAc2VlIGphdmEudXRpbC5OYXZpZ2FibGVTZXQjZGVzY2VuZGluZ1NldCgpCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBOYXZpZ2FibGVTZXQ8RT4gZGVzY2VuZGluZ1NldCgpIHsKKyAgICAgICAgcmV0dXJuIChkZXNjZW5kaW5nU2V0ICE9IG51bGwpID8gZGVzY2VuZGluZ1NldAorICAgICAgICAgICAgICAgIDogKGRlc2NlbmRpbmdTZXQgPSBuZXcgVHJlZVNldDxFPihiYWNraW5nTWFwLmRlc2NlbmRpbmdNYXAoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIEBzZWUgamF2YS51dGlsLk5hdmlnYWJsZVNldCNzdWJTZXQoT2JqZWN0LCBib29sZWFuLCBPYmplY3QsIGJvb2xlYW4pCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBOYXZpZ2FibGVTZXQ8RT4gc3ViU2V0KEUgc3RhcnQsIGJvb2xlYW4gc3RhcnRJbmNsdXNpdmUsIEUgZW5kLAorICAgICAgICAgICAgYm9vbGVhbiBlbmRJbmNsdXNpdmUpIHsKKyAgICAgICAgQ29tcGFyYXRvcjw/IHN1cGVyIEU+IGMgPSBiYWNraW5nTWFwLmNvbXBhcmF0b3IoKTsKKyAgICAgICAgaW50IGNvbXBhcmUgPSAoYyA9PSBudWxsKSA/ICgoQ29tcGFyYWJsZTxFPikgc3RhcnQpLmNvbXBhcmVUbyhlbmQpIDogYworICAgICAgICAgICAgICAgIC5jb21wYXJlKHN0YXJ0LCBlbmQpOworICAgICAgICBpZiAoY29tcGFyZSA8PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFRyZWVTZXQ8RT4oYmFja2luZ01hcC5zdWJNYXAoc3RhcnQsIHN0YXJ0SW5jbHVzaXZlLCBlbmQsCisgICAgICAgICAgICAgICAgICAgIGVuZEluY2x1c2l2ZSkpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiBAc2VlIGphdmEudXRpbC5OYXZpZ2FibGVTZXQjaGVhZFNldChPYmplY3QsIGJvb2xlYW4pCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBOYXZpZ2FibGVTZXQ8RT4gaGVhZFNldChFIGVuZCwgYm9vbGVhbiBlbmRJbmNsdXNpdmUpIHsKKyAgICAgICAgLy8gQ2hlY2sgZm9yIGVycm9ycworICAgICAgICBDb21wYXJhdG9yPD8gc3VwZXIgRT4gYyA9IGJhY2tpbmdNYXAuY29tcGFyYXRvcigpOworICAgICAgICBpZiAoYyA9PSBudWxsKSB7CisgICAgICAgICAgICAoKENvbXBhcmFibGU8RT4pIGVuZCkuY29tcGFyZVRvKGVuZCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjLmNvbXBhcmUoZW5kLCBlbmQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgVHJlZVNldDxFPihiYWNraW5nTWFwLmhlYWRNYXAoZW5kLCBlbmRJbmNsdXNpdmUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiBAc2VlIGphdmEudXRpbC5OYXZpZ2FibGVTZXQjdGFpbFNldChPYmplY3QsIGJvb2xlYW4pCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBOYXZpZ2FibGVTZXQ8RT4gdGFpbFNldChFIHN0YXJ0LCBib29sZWFuIHN0YXJ0SW5jbHVzaXZlKSB7CisgICAgICAgIC8vIENoZWNrIGZvciBlcnJvcnMKKyAgICAgICAgQ29tcGFyYXRvcjw/IHN1cGVyIEU+IGMgPSBiYWNraW5nTWFwLmNvbXBhcmF0b3IoKTsKKyAgICAgICAgaWYgKGMgPT0gbnVsbCkgeworICAgICAgICAgICAgKChDb21wYXJhYmxlPEU+KSBzdGFydCkuY29tcGFyZVRvKHN0YXJ0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGMuY29tcGFyZShzdGFydCwgc3RhcnQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgVHJlZVNldDxFPihiYWNraW5nTWFwLnRhaWxNYXAoc3RhcnQsIHN0YXJ0SW5jbHVzaXZlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBTb3J0ZWRTZXR9IG9mIHRoZSBzcGVjaWZpZWQgcG9ydGlvbiBvZiB0aGlzIHtAY29kZSBUcmVlU2V0fSB3aGljaAorICAgICAqIGNvbnRhaW5zIGVsZW1lbnRzIGdyZWF0ZXIgb3IgZXF1YWwgdG8gdGhlIHN0YXJ0IGVsZW1lbnQgYnV0IGxlc3MgdGhhbiB0aGUKKyAgICAgKiBlbmQgZWxlbWVudC4gVGhlIHJldHVybmVkIFNvcnRlZFNldCBpcyBiYWNrZWQgYnkgdGhpcyBUcmVlU2V0IHNvIGNoYW5nZXMKKyAgICAgKiB0byBvbmUgYXJlIHJlZmxlY3RlZCBieSB0aGUgb3RoZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGFydCBlbGVtZW50CisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGVuZCBlbGVtZW50CisgICAgICogQHJldHVybiBhIHN1YnNldCB3aGVyZSB0aGUgZWxlbWVudHMgYXJlIGdyZWF0ZXIgb3IgZXF1YWwgdG8KKyAgICAgKiAgICAgICAgIDxjb2RlPnN0YXJ0PC9jb2RlPiBhbmQgbGVzcyB0aGFuIDxjb2RlPmVuZDwvY29kZT4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgd2hlbiB0aGUgc3RhcnQgb3IgZW5kIG9iamVjdCBjYW5ub3QgYmUgY29tcGFyZWQgd2l0aCB0aGUKKyAgICAgKiAgICAgICAgICAgICAgICBlbGVtZW50cyBpbiB0aGlzIFRyZWVTZXQKKyAgICAgKiBAZXhjZXB0aW9uIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgd2hlbiB0aGUgc3RhcnQgb3IgZW5kIG9iamVjdCBpcyBudWxsIGFuZCB0aGUgY29tcGFyYXRvcgorICAgICAqICAgICAgICAgICAgICAgIGNhbm5vdCBoYW5kbGUgbnVsbAorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBTb3J0ZWRTZXQ8RT4gc3ViU2V0KEUgc3RhcnQsIEUgZW5kKSB7CisgICAgICAgIHJldHVybiBzdWJTZXQoc3RhcnQsIHRydWUsIGVuZCwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgU29ydGVkU2V0fSBvZiB0aGUgc3BlY2lmaWVkIHBvcnRpb24gb2YgdGhpcyB7QGNvZGUgVHJlZVNldH0gd2hpY2gKKyAgICAgKiBjb250YWlucyBlbGVtZW50cyBsZXNzIHRoYW4gdGhlIGVuZCBlbGVtZW50LiBUaGUgcmV0dXJuZWQgU29ydGVkU2V0IGlzCisgICAgICogYmFja2VkIGJ5IHRoaXMgVHJlZVNldCBzbyBjaGFuZ2VzIHRvIG9uZSBhcmUgcmVmbGVjdGVkIGJ5IHRoZSBvdGhlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmQgZWxlbWVudAorICAgICAqIEByZXR1cm4gYSBzdWJzZXQgd2hlcmUgdGhlIGVsZW1lbnRzIGFyZSBsZXNzIHRoYW4gPGNvZGU+ZW5kPC9jb2RlPgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICB3aGVuIHRoZSBlbmQgb2JqZWN0IGNhbm5vdCBiZSBjb21wYXJlZCB3aXRoIHRoZSBlbGVtZW50cworICAgICAqICAgICAgICAgICAgICAgIGluIHRoaXMgVHJlZVNldAorICAgICAqIEBleGNlcHRpb24gTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICB3aGVuIHRoZSBlbmQgb2JqZWN0IGlzIG51bGwgYW5kIHRoZSBjb21wYXJhdG9yIGNhbm5vdAorICAgICAqICAgICAgICAgICAgICAgIGhhbmRsZSBudWxsCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIFNvcnRlZFNldDxFPiBoZWFkU2V0KEUgZW5kKSB7CisgICAgICAgIHJldHVybiBoZWFkU2V0KGVuZCwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgU29ydGVkU2V0fSBvZiB0aGUgc3BlY2lmaWVkIHBvcnRpb24gb2YgdGhpcyB7QGNvZGUgVHJlZVNldH0gd2hpY2gKKyAgICAgKiBjb250YWlucyBlbGVtZW50cyBncmVhdGVyIG9yIGVxdWFsIHRvIHRoZSBzdGFydCBlbGVtZW50LiBUaGUgcmV0dXJuZWQKKyAgICAgKiBTb3J0ZWRTZXQgaXMgYmFja2VkIGJ5IHRoaXMgVHJlZVNldCBzbyBjaGFuZ2VzIHRvIG9uZSBhcmUgcmVmbGVjdGVkIGJ5CisgICAgICogdGhlIG90aGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgZWxlbWVudAorICAgICAqIEByZXR1cm4gYSBzdWJzZXQgd2hlcmUgdGhlIGVsZW1lbnRzIGFyZSBncmVhdGVyIG9yIGVxdWFsIHRvCisgICAgICogICAgICAgICA8Y29kZT5zdGFydDwvY29kZT4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgd2hlbiB0aGUgc3RhcnQgb2JqZWN0IGNhbm5vdCBiZSBjb21wYXJlZCB3aXRoIHRoZSBlbGVtZW50cworICAgICAqICAgICAgICAgICAgICAgIGluIHRoaXMgVHJlZVNldAorICAgICAqIEBleGNlcHRpb24gTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICB3aGVuIHRoZSBzdGFydCBvYmplY3QgaXMgbnVsbCBhbmQgdGhlIGNvbXBhcmF0b3IgY2Fubm90CisgICAgICogICAgICAgICAgICAgICAgaGFuZGxlIG51bGwKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgU29ydGVkU2V0PEU+IHRhaWxTZXQoRSBzdGFydCkgeworICAgICAgICByZXR1cm4gdGFpbFNldChzdGFydCwgdHJ1ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN0cmVhbS5kZWZhdWx0V3JpdGVPYmplY3QoKTsKKyAgICAgICAgc3RyZWFtLndyaXRlT2JqZWN0KGJhY2tpbmdNYXAuY29tcGFyYXRvcigpKTsKKyAgICAgICAgaW50IHNpemUgPSBiYWNraW5nTWFwLnNpemUoKTsKKyAgICAgICAgc3RyZWFtLndyaXRlSW50KHNpemUpOworICAgICAgICBpZiAoc2l6ZSA+IDApIHsKKyAgICAgICAgICAgIEl0ZXJhdG9yPEU+IGl0ID0gYmFja2luZ01hcC5rZXlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIHN0cmVhbS53cml0ZU9iamVjdChpdC5uZXh0KCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgICAgICBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgc3RyZWFtLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisgICAgICAgIFRyZWVNYXA8RSwgT2JqZWN0PiBtYXAgPSBuZXcgVHJlZU1hcDxFLCBPYmplY3Q+KAorICAgICAgICAgICAgICAgIChDb21wYXJhdG9yPD8gc3VwZXIgRT4pIHN0cmVhbS5yZWFkT2JqZWN0KCkpOworICAgICAgICBpbnQgc2l6ZSA9IHN0cmVhbS5yZWFkSW50KCk7CisgICAgICAgIGlmIChzaXplID4gMCkgeworICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPHNpemU7IGkrKykgeworICAgICAgICAgICAgICAgIEUgZWxlbSA9IChFKXN0cmVhbS5yZWFkT2JqZWN0KCk7CisgICAgICAgICAgICAgICAgbWFwLnB1dChlbGVtLCBCb29sZWFuLlRSVUUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGJhY2tpbmdNYXAgPSBtYXA7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9VVUlELmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1VVSUQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOTMyYmIyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9VVUlELmphdmEKQEAgLTAsMCArMSw0NjEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEubmlvLkJ5dGVPcmRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgbGliY29yZS5pby5NZW1vcnk7CisKKy8qKgorICogVVVJRCBpcyBhbiBpbW11dGFibGUgcmVwcmVzZW50YXRpb24gb2YgYSAxMjgtYml0IHVuaXZlcnNhbGx5IHVuaXF1ZQorICogaWRlbnRpZmllciAoVVVJRCkuCisgKiA8cD4KKyAqIFRoZXJlIGFyZSBtdWx0aXBsZSwgdmFyaWFudCBsYXlvdXRzIG9mIFVVSURzLCBidXQgdGhpcyBjbGFzcyBpcyBiYXNlZCB1cG9uCisgKiB2YXJpYW50IDIgb2YgPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjNDEyMi50eHQiPlJGQyA0MTIyPC9hPiwgdGhlCisgKiBMZWFjaC1TYWx6IHZhcmlhbnQuIFRoaXMgY2xhc3MgY2FuIGJlIHVzZWQgdG8gbW9kZWwgYWx0ZXJuYXRlIHZhcmlhbnRzLCBidXQKKyAqIG1vc3Qgb2YgdGhlIG1ldGhvZHMgd2lsbCBiZSB1bnN1cHBvcnRlZCBpbiB0aG9zZSBjYXNlczsgc2VlIGVhY2ggbWV0aG9kIGZvcgorICogZGV0YWlscy4KKyAqCisgKiBAc2luY2UgMS41CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBVVUlEIGltcGxlbWVudHMgU2VyaWFsaXphYmxlLCBDb21wYXJhYmxlPFVVSUQ+IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00ODU2ODQ2MzYxMTkzMjQ5NDg5TDsKKworICAgIHByaXZhdGUgc3RhdGljIFNlY3VyZVJhbmRvbSBybmc7CisKKyAgICBwcml2YXRlIGxvbmcgbW9zdFNpZ0JpdHM7CisgICAgcHJpdmF0ZSBsb25nIGxlYXN0U2lnQml0czsKKworICAgIHByaXZhdGUgdHJhbnNpZW50IGludCB2YXJpYW50OworICAgIHByaXZhdGUgdHJhbnNpZW50IGludCB2ZXJzaW9uOworICAgIHByaXZhdGUgdHJhbnNpZW50IGxvbmcgdGltZXN0YW1wOworICAgIHByaXZhdGUgdHJhbnNpZW50IGludCBjbG9ja1NlcXVlbmNlOworICAgIHByaXZhdGUgdHJhbnNpZW50IGxvbmcgbm9kZTsKKyAgICBwcml2YXRlIHRyYW5zaWVudCBpbnQgaGFzaDsKKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIENvbnN0cnVjdHMgYW4gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGJpdHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbW9zdFNpZ0JpdHMKKyAgICAgKiAgICAgICAgICAgIFRoZSA2NCBtb3N0IHNpZ25pZmljYW50IGJpdHMgb2YgdGhlIFVVSUQuCisgICAgICogQHBhcmFtIGxlYXN0U2lnQml0cworICAgICAqICAgICAgICAgICAgVGhlIDY0IGxlYXN0IHNpZ25pZmljYW50IGJpdHMgb2YgdGhlIFVVSUQuCisgICAgICovCisgICAgcHVibGljIFVVSUQobG9uZyBtb3N0U2lnQml0cywgbG9uZyBsZWFzdFNpZ0JpdHMpIHsKKyAgICAgICAgdGhpcy5tb3N0U2lnQml0cyA9IG1vc3RTaWdCaXRzOworICAgICAgICB0aGlzLmxlYXN0U2lnQml0cyA9IGxlYXN0U2lnQml0czsKKyAgICAgICAgaW5pdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIFNldHMgdXAgdGhlIHRyYW5zaWVudCBmaWVsZHMgb2YgdGhpcyBpbnN0YW5jZSBiYXNlZCBvbiB0aGUgY3VycmVudCB2YWx1ZXMKKyAgICAgKiBvZiB0aGUge0Bjb2RlIG1vc3RTaWdCaXRzfSBhbmQge0Bjb2RlIGxlYXN0U2lnQml0c30gZmllbGRzLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpbml0KCkgeworICAgICAgICAvLyBzZXR1cCBoYXNoIGZpZWxkCisgICAgICAgIGludCBtc2JIYXNoID0gKGludCkgKG1vc3RTaWdCaXRzIF4gKG1vc3RTaWdCaXRzID4+PiAzMikpOworICAgICAgICBpbnQgbHNiSGFzaCA9IChpbnQpIChsZWFzdFNpZ0JpdHMgXiAobGVhc3RTaWdCaXRzID4+PiAzMikpOworICAgICAgICBoYXNoID0gbXNiSGFzaCBeIGxzYkhhc2g7CisKKyAgICAgICAgLy8gc2V0dXAgdmFyaWFudCBmaWVsZAorICAgICAgICBpZiAoKGxlYXN0U2lnQml0cyAmIDB4ODAwMDAwMDAwMDAwMDAwMEwpID09IDApIHsKKyAgICAgICAgICAgIC8vIE1TQjAgbm90IHNldCwgTkNTIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHZhcmlhbnQKKyAgICAgICAgICAgIHZhcmlhbnQgPSAwOworICAgICAgICB9IGVsc2UgaWYgKChsZWFzdFNpZ0JpdHMgJiAweDQwMDAwMDAwMDAwMDAwMDBMKSAhPSAwKSB7CisgICAgICAgICAgICAvLyBNU0IxIHNldCwgZWl0aGVyIE1TIHJlc2VydmVkIG9yIGZ1dHVyZSByZXNlcnZlZAorICAgICAgICAgICAgdmFyaWFudCA9IChpbnQpICgobGVhc3RTaWdCaXRzICYgMHhFMDAwMDAwMDAwMDAwMDAwTCkgPj4+IDYxKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIE1TQjEgbm90IHNldCwgUkZDIDQxMjIgdmFyaWFudAorICAgICAgICAgICAgdmFyaWFudCA9IDI7CisgICAgICAgIH0KKworICAgICAgICAvLyBzZXR1cCB2ZXJzaW9uIGZpZWxkCisgICAgICAgIHZlcnNpb24gPSAoaW50KSAoKG1vc3RTaWdCaXRzICYgMHgwMDAwMDAwMDAwMDBGMDAwKSA+Pj4gMTIpOworCisgICAgICAgIGlmICh2YXJpYW50ICE9IDIgJiYgdmVyc2lvbiAhPSAxKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICAvLyBzZXR1cCB0aW1lc3RhbXAgZmllbGQKKyAgICAgICAgbG9uZyB0aW1lTG93ID0gKG1vc3RTaWdCaXRzICYgMHhGRkZGRkZGRjAwMDAwMDAwTCkgPj4+IDMyOworICAgICAgICBsb25nIHRpbWVNaWQgPSAobW9zdFNpZ0JpdHMgJiAweDAwMDAwMDAwRkZGRjAwMDBMKSA8PCAxNjsKKyAgICAgICAgbG9uZyB0aW1lSGlnaCA9IChtb3N0U2lnQml0cyAmIDB4MDAwMDAwMDAwMDAwMEZGRkwpIDw8IDQ4OworICAgICAgICB0aW1lc3RhbXAgPSB0aW1lTG93IHwgdGltZU1pZCB8IHRpbWVIaWdoOworCisgICAgICAgIC8vIHNldHVwIGNsb2NrIHNlcXVlbmNlIGZpZWxkCisgICAgICAgIGNsb2NrU2VxdWVuY2UgPSAoaW50KSAoKGxlYXN0U2lnQml0cyAmIDB4M0ZGRjAwMDAwMDAwMDAwMEwpID4+PiA0OCk7CisKKyAgICAgICAgLy8gc2V0dXAgbm9kZSBmaWVsZAorICAgICAgICBub2RlID0gKGxlYXN0U2lnQml0cyAmIDB4MDAwMEZGRkZGRkZGRkZGRkwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIEdlbmVyYXRlcyBhIHZhcmlhbnQgMiwgdmVyc2lvbiA0IChyYW5kb21seSBnZW5lcmF0ZWQgbnVtYmVyKSBVVUlEIGFzIHBlcgorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzQxMjIudHh0Ij5SRkMgNDEyMjwvYT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIFVVSUQgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBVVUlEIHJhbmRvbVVVSUQoKSB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbMTZdOworICAgICAgICAvLyBsb2NrIG9uIHRoZSBjbGFzcyB0byBwcm90ZWN0IGxhenkgaW5pdAorICAgICAgICBzeW5jaHJvbml6ZWQgKFVVSUQuY2xhc3MpIHsKKyAgICAgICAgICAgIGlmIChybmcgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJuZyA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBybmcubmV4dEJ5dGVzKGRhdGEpOworICAgICAgICByZXR1cm4gbWFrZVV1aWQoZGF0YSwgNCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogR2VuZXJhdGVzIGEgdmFyaWFudCAyLCB2ZXJzaW9uIDMgKG5hbWUtYmFzZWQsIE1ENS1oYXNoZWQpIFVVSUQgYXMgcGVyIDxhCisgICAgICogaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjNDEyMi50eHQiPlJGQyA0MTIyPC9hPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSB1c2VkIGFzIGJ5dGUgYXJyYXkgdG8gY3JlYXRlIGFuIFVVSUQuCisgICAgICogQHJldHVybiBhbiBVVUlEIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVVVJRCBuYW1lVVVJREZyb21CeXRlcyhieXRlW10gbmFtZSkgeworICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBtZCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoIk1ENSIpOworICAgICAgICAgICAgcmV0dXJuIG1ha2VVdWlkKG1kLmRpZ2VzdChuYW1lKSwgMyk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBVVUlEIG1ha2VVdWlkKGJ5dGVbXSBoYXNoLCBpbnQgdmVyc2lvbikgeworICAgICAgICBsb25nIG1zYiA9IE1lbW9yeS5wZWVrTG9uZyhoYXNoLCAwLCBCeXRlT3JkZXIuQklHX0VORElBTik7CisgICAgICAgIGxvbmcgbHNiID0gTWVtb3J5LnBlZWtMb25nKGhhc2gsIDgsIEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICAgICAgLy8gU2V0IHRoZSB2ZXJzaW9uIGZpZWxkLgorICAgICAgICBtc2IgJj0gfigweGZMIDw8IDEyKTsKKyAgICAgICAgbXNiIHw9ICgobG9uZykgdmVyc2lvbikgPDwgMTI7CisgICAgICAgIC8vIFNldCB0aGUgdmFyaWFudCBmaWVsZCB0byAyLiBOb3RlIHRoYXQgdGhlIHZhcmlhbnQgZmllbGQgaXMgdmFyaWFibGUtd2lkdGgsCisgICAgICAgIC8vIHNvIHN1cHBvcnRpbmcgb3RoZXIgdmFyaWFudHMgaXMgbm90IGp1c3QgYSBtYXR0ZXIgb2YgY2hhbmdpbmcgdGhlIGNvbnN0YW50IDIgYmVsb3chCisgICAgICAgIGxzYiAmPSB+KDB4M0wgPDwgNjIpOworICAgICAgICBsc2IgfD0gMkwgPDwgNjI7CisgICAgICAgIHJldHVybiBuZXcgVVVJRChtc2IsIGxzYik7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogUGFyc2VzIGEgVVVJRCBzdHJpbmcgd2l0aCB0aGUgZm9ybWF0IGRlZmluZWQgYnkge0BsaW5rICN0b1N0cmluZygpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1dWlkCisgICAgICogICAgICAgICAgICB0aGUgVVVJRCBzdHJpbmcgdG8gcGFyc2UuCisgICAgICogQHJldHVybiBhbiBVVUlEIGluc3RhbmNlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgdXVpZH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHV1aWR9IGlzIG5vdCBmb3JtYXR0ZWQgY29ycmVjdGx5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVVVJRCBmcm9tU3RyaW5nKFN0cmluZyB1dWlkKSB7CisgICAgICAgIGlmICh1dWlkID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaW50W10gcG9zaXRpb24gPSBuZXcgaW50WzVdOworICAgICAgICBpbnQgbGFzdFBvc2l0aW9uID0gMTsKKyAgICAgICAgaW50IHN0YXJ0UG9zaXRpb24gPSAwOworCisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgZm9yICg7IGkgPCBwb3NpdGlvbi5sZW5ndGggJiYgbGFzdFBvc2l0aW9uID4gMDsgaSsrKSB7CisgICAgICAgICAgICBwb3NpdGlvbltpXSA9IHV1aWQuaW5kZXhPZigiLSIsIHN0YXJ0UG9zaXRpb24pOworICAgICAgICAgICAgbGFzdFBvc2l0aW9uID0gcG9zaXRpb25baV07CisgICAgICAgICAgICBzdGFydFBvc2l0aW9uID0gcG9zaXRpb25baV0gKyAxOworICAgICAgICB9CisKKyAgICAgICAgLy8gc2hvdWxkIGhhdmUgYW5kIG9ubHkgY2FuIGhhdmUgZm91ciAiLSIgaW4gVVVJRAorICAgICAgICBpZiAoaSAhPSBwb3NpdGlvbi5sZW5ndGggfHwgbGFzdFBvc2l0aW9uICE9IC0xKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIFVVSUQ6ICIgKyB1dWlkKTsKKyAgICAgICAgfQorCisgICAgICAgIGxvbmcgbTEgPSBMb25nLnBhcnNlTG9uZyh1dWlkLnN1YnN0cmluZygwLCBwb3NpdGlvblswXSksIDE2KTsKKyAgICAgICAgbG9uZyBtMiA9IExvbmcucGFyc2VMb25nKHV1aWQuc3Vic3RyaW5nKHBvc2l0aW9uWzBdICsgMSwgcG9zaXRpb25bMV0pLCAxNik7CisgICAgICAgIGxvbmcgbTMgPSBMb25nLnBhcnNlTG9uZyh1dWlkLnN1YnN0cmluZyhwb3NpdGlvblsxXSArIDEsIHBvc2l0aW9uWzJdKSwgMTYpOworCisgICAgICAgIGxvbmcgbHNiMSA9IExvbmcucGFyc2VMb25nKHV1aWQuc3Vic3RyaW5nKHBvc2l0aW9uWzJdICsgMSwgcG9zaXRpb25bM10pLCAxNik7CisgICAgICAgIGxvbmcgbHNiMiA9IExvbmcucGFyc2VMb25nKHV1aWQuc3Vic3RyaW5nKHBvc2l0aW9uWzNdICsgMSksIDE2KTsKKworICAgICAgICBsb25nIG1zYiA9IChtMSA8PCAzMikgfCAobTIgPDwgMTYpIHwgbTM7CisgICAgICAgIGxvbmcgbHNiID0gKGxzYjEgPDwgNDgpIHwgbHNiMjsKKworICAgICAgICByZXR1cm4gbmV3IFVVSUQobXNiLCBsc2IpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIFRoZSA2NCBsZWFzdCBzaWduaWZpY2FudCBiaXRzIG9mIHRoZSBVVUlELgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgNjQgbGVhc3Qgc2lnbmlmaWNhbnQgYml0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRMZWFzdFNpZ25pZmljYW50Qml0cygpIHsKKyAgICAgICAgcmV0dXJuIGxlYXN0U2lnQml0czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgNjQgbW9zdCBzaWduaWZpY2FudCBiaXRzIG9mIHRoZSBVVUlELgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgNjQgbW9zdCBzaWduaWZpY2FudCBiaXRzLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldE1vc3RTaWduaWZpY2FudEJpdHMoKSB7CisgICAgICAgIHJldHVybiBtb3N0U2lnQml0czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGUgdmFyaWFudCAyIFVVSUQgYXMgcGVyIDxhCisgICAgICogaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjNDEyMi50eHQiPlJGQyA0MTIyPC9hPi4gSWYgdGhlIHZhcmlhbnQKKyAgICAgKiBpcyBub3QgMiwgdGhlbiB0aGUgdmVyc2lvbiB3aWxsIGJlIDAuCisgICAgICogPHVsPgorICAgICAqIDxsaT4xIC0gVGltZS1iYXNlZCBVVUlEPC9saT4KKyAgICAgKiA8bGk+MiAtIERDRSBTZWN1cml0eSBVVUlEPC9saT4KKyAgICAgKiA8bGk+MyAtIE5hbWUtYmFzZWQgd2l0aCBNRDUgaGFzaGluZyBVVUlEICh7QGxpbmsgI25hbWVVVUlERnJvbUJ5dGVzKGJ5dGVbXSl9KTwvbGk+CisgICAgICogPGxpPjQgLSBSYW5kb21seSBnZW5lcmF0ZWQgVVVJRCAoe0BsaW5rICNyYW5kb21VVUlEKCl9KTwvbGk+CisgICAgICogPGxpPjUgLSBOYW1lLWJhc2VkIHdpdGggU0hBLTEgaGFzaGluZyBVVUlEPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHJldHVybiBhbiB7QGNvZGUgaW50fSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHZlcnNpb24oKSB7CisgICAgICAgIHJldHVybiB2ZXJzaW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIFRoZSB2YXJpYW50IG9mIHRoZSBVVUlEIGFzIHBlciA8YQorICAgICAqIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzQxMjIudHh0Ij5SRkMgNDEyMjwvYT4uCisgICAgICogPHVsPgorICAgICAqIDxsaT4wIC0gUmVzZXJ2ZWQgZm9yIE5DUyBjb21wYXRpYmlsaXR5PC9saT4KKyAgICAgKiA8bGk+MiAtIFJGQyA0MTIyL0xlYWNoLVNhbHo8L2xpPgorICAgICAqIDxsaT42IC0gUmVzZXJ2ZWQgZm9yIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbiBjb21wYXRpYmlsaXR5PC9saT4KKyAgICAgKiA8bGk+NyAtIFJlc2VydmVkIGZvciBmdXR1cmUgdXNlPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHJldHVybiBhbiB7QGNvZGUgaW50fSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHZhcmlhbnQoKSB7CisgICAgICAgIHJldHVybiB2YXJpYW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIFRoZSB0aW1lc3RhbXAgdmFsdWUgb2YgdGhlIHZlcnNpb24gMSwgdmFyaWFudCAyIFVVSUQgYXMgcGVyIDxhCisgICAgICogaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjNDEyMi50eHQiPlJGQyA0MTIyPC9hPi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgbG9uZ30gdmFsdWUuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAbGluayAjdmVyc2lvbigpfSBpcyBub3QgMS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyB0aW1lc3RhbXAoKSB7CisgICAgICAgIGlmICh2ZXJzaW9uICE9IDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0aW1lc3RhbXA7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogVGhlIGNsb2NrIHNlcXVlbmNlIHZhbHVlIG9mIHRoZSB2ZXJzaW9uIDEsIHZhcmlhbnQgMiBVVUlEIGFzIHBlciA8YQorICAgICAqIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzQxMjIudHh0Ij5SRkMgNDEyMjwvYT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIGxvbmd9IHZhbHVlLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGxpbmsgI3ZlcnNpb24oKX0gaXMgbm90IDEuCisgICAgICovCisgICAgcHVibGljIGludCBjbG9ja1NlcXVlbmNlKCkgeworICAgICAgICBpZiAodmVyc2lvbiAhPSAxKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2xvY2tTZXF1ZW5jZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbm9kZSB2YWx1ZSBvZiB0aGUgdmVyc2lvbiAxLCB2YXJpYW50IDIgVVVJRCBhcyBwZXIgPGEKKyAgICAgKiBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM0MTIyLnR4dCI+UkZDIDQxMjI8L2E+LgorICAgICAqCisgICAgICogQHJldHVybiBhIHtAY29kZSBsb25nfSB2YWx1ZS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0BsaW5rICN2ZXJzaW9uKCl9IGlzIG5vdCAxLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIG5vZGUoKSB7CisgICAgICAgIGlmICh2ZXJzaW9uICE9IDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBub2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIENvbXBhcmVzIHRoaXMgVVVJRCB0byB0aGUgc3BlY2lmaWVkIFVVSUQuIFRoZSBuYXR1cmFsIG9yZGVyaW5nIG9mIFVVSURzCisgICAgICogaXMgYmFzZWQgdXBvbiB0aGUgdmFsdWUgb2YgdGhlIGJpdHMgZnJvbSBtb3N0IHNpZ25pZmljYW50IHRvIGxlYXN0CisgICAgICogc2lnbmlmaWNhbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXVpZAorICAgICAqICAgICAgICAgICAgdGhlIFVVSUQgdG8gY29tcGFyZSB0by4KKyAgICAgKiBAcmV0dXJuIGEgdmFsdWUgb2YgLTEsIDAgb3IgMSBpZiB0aGlzIFVVSUQgaXMgbGVzcyB0aGFuLCBlcXVhbCB0byBvcgorICAgICAqICAgICAgICAgZ3JlYXRlciB0aGFuIHtAY29kZSB1dWlkfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhVVUlEIHV1aWQpIHsKKyAgICAgICAgaWYgKHV1aWQgPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBpZiAodGhpcy5tb3N0U2lnQml0cyAhPSB1dWlkLm1vc3RTaWdCaXRzKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpcy5tb3N0U2lnQml0cyA8IHV1aWQubW9zdFNpZ0JpdHMgPyAtMSA6IDE7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnQgdGhpcy5tb3N0U2lnQml0cyA9PSB1dWlkLm1vc3RTaWdCaXRzOworCisgICAgICAgIGlmICh0aGlzLmxlYXN0U2lnQml0cyAhPSB1dWlkLmxlYXN0U2lnQml0cykgeworICAgICAgICAgICAgcmV0dXJuIHRoaXMubGVhc3RTaWdCaXRzIDwgdXVpZC5sZWFzdFNpZ0JpdHMgPyAtMSA6IDE7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnQgdGhpcy5sZWFzdFNpZ0JpdHMgPT0gdXVpZC5sZWFzdFNpZ0JpdHM7CisKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogQ29tcGFyZXMgdGhpcyBVVUlEIHRvIGFub3RoZXIgb2JqZWN0IGZvciBlcXVhbGl0eS4gSWYge0Bjb2RlIG9iamVjdH0KKyAgICAgKiBpcyBub3Qge0Bjb2RlIG51bGx9LCBpcyBhIFVVSUQgaW5zdGFuY2UsIGFuZCBhbGwgYml0cyBhcmUgZXF1YWwsIHRoZW4KKyAgICAgKiB7QGNvZGUgdHJ1ZX0gaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIE9iamVjdH0gdG8gY29tcGFyZSB0by4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIFVVSUQgaXMgZXF1YWwgdG8ge0Bjb2RlIG9iamVjdH0KKyAgICAgKiAgICAgICAgIG9yIHtAY29kZSBmYWxzZX0gaWYgbm90LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHRoaXMgPT0gb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghKG9iamVjdCBpbnN0YW5jZW9mIFVVSUQpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBVVUlEIHRoYXQgPSAoVVVJRCkgb2JqZWN0OworCisgICAgICAgIHJldHVybiAodGhpcy5sZWFzdFNpZ0JpdHMgPT0gdGhhdC5sZWFzdFNpZ0JpdHMpCisgICAgICAgICAgICAgICAgJiYgKHRoaXMubW9zdFNpZ0JpdHMgPT0gdGhhdC5tb3N0U2lnQml0cyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+CisgICAgICogUmV0dXJucyBhIGhhc2ggdmFsdWUgZm9yIHRoaXMgVVVJRCB0aGF0IGlzIGNvbnNpc3RlbnQgd2l0aCB0aGUKKyAgICAgKiB7QGxpbmsgI2VxdWFscyhPYmplY3QpfSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBpbnR9IHZhbHVlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiBoYXNoOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBVVUlEIGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0LCBhcworICAgICAqIHBlciA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM0MTIyLnR4dCI+UkZDIDQxMjI8L2E+LgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiAgICAgICAgICAgIFVVSUQgICAgICAgICAgICAgICAgICAgPSB0aW1lLWxvdyAmcXVvdDstJnF1b3Q7IHRpbWUtbWlkICZxdW90Oy0mcXVvdDsKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lLWhpZ2gtYW5kLXZlcnNpb24gJnF1b3Q7LSZxdW90OworICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLXNlcS1hbmQtcmVzZXJ2ZWQKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay1zZXEtbG93ICZxdW90Oy0mcXVvdDsgbm9kZQorICAgICAqICAgICAgICAgICAgdGltZS1sb3cgICAgICAgICAgICAgICA9IDRoZXhPY3RldAorICAgICAqICAgICAgICAgICAgdGltZS1taWQgICAgICAgICAgICAgICA9IDJoZXhPY3RldAorICAgICAqICAgICAgICAgICAgdGltZS1oaWdoLWFuZC12ZXJzaW9uICA9IDJoZXhPY3RldAorICAgICAqICAgICAgICAgICAgY2xvY2stc2VxLWFuZC1yZXNlcnZlZCA9IGhleE9jdGV0CisgICAgICogICAgICAgICAgICBjbG9jay1zZXEtbG93ICAgICAgICAgID0gaGV4T2N0ZXQKKyAgICAgKiAgICAgICAgICAgIG5vZGUgICAgICAgICAgICAgICAgICAgPSA2aGV4T2N0ZXQKKyAgICAgKiAgICAgICAgICAgIGhleE9jdGV0ICAgICAgICAgICAgICAgPSBoZXhEaWdpdCBoZXhEaWdpdAorICAgICAqICAgICAgICAgICAgaGV4RGlnaXQgPQorICAgICAqICAgICAgICAgICAgICAgICZxdW90OzAmcXVvdDsgLyAmcXVvdDsxJnF1b3Q7IC8gJnF1b3Q7MiZxdW90OyAvICZxdW90OzMmcXVvdDsgLyAmcXVvdDs0JnF1b3Q7IC8gJnF1b3Q7NSZxdW90OyAvICZxdW90OzYmcXVvdDsgLyAmcXVvdDs3JnF1b3Q7IC8gJnF1b3Q7OCZxdW90OyAvICZxdW90OzkmcXVvdDsgLworICAgICAqICAgICAgICAgICAgICAgICZxdW90O2EmcXVvdDsgLyAmcXVvdDtiJnF1b3Q7IC8gJnF1b3Q7YyZxdW90OyAvICZxdW90O2QmcXVvdDsgLyAmcXVvdDtlJnF1b3Q7IC8gJnF1b3Q7ZiZxdW90OyAvCisgICAgICogICAgICAgICAgICAgICAgJnF1b3Q7QSZxdW90OyAvICZxdW90O0ImcXVvdDsgLyAmcXVvdDtDJnF1b3Q7IC8gJnF1b3Q7RCZxdW90OyAvICZxdW90O0UmcXVvdDsgLyAmcXVvdDtGJnF1b3Q7CisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgU3RyaW5nIGluc3RhbmNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKDM2KTsKKyAgICAgICAgU3RyaW5nIG1zYlN0ciA9IExvbmcudG9IZXhTdHJpbmcobW9zdFNpZ0JpdHMpOworICAgICAgICBpZiAobXNiU3RyLmxlbmd0aCgpIDwgMTYpIHsKKyAgICAgICAgICAgIGludCBkaWZmID0gMTYgLSBtc2JTdHIubGVuZ3RoKCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRpZmY7IGkrKykgeworICAgICAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCcwJyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYnVpbGRlci5hcHBlbmQobXNiU3RyKTsKKyAgICAgICAgYnVpbGRlci5pbnNlcnQoOCwgJy0nKTsKKyAgICAgICAgYnVpbGRlci5pbnNlcnQoMTMsICctJyk7CisgICAgICAgIGJ1aWxkZXIuYXBwZW5kKCctJyk7CisgICAgICAgIFN0cmluZyBsc2JTdHIgPSBMb25nLnRvSGV4U3RyaW5nKGxlYXN0U2lnQml0cyk7CisgICAgICAgIGlmIChsc2JTdHIubGVuZ3RoKCkgPCAxNikgeworICAgICAgICAgICAgaW50IGRpZmYgPSAxNiAtIGxzYlN0ci5sZW5ndGgoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGlmZjsgaSsrKSB7CisgICAgICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoJzAnKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBidWlsZGVyLmFwcGVuZChsc2JTdHIpOworICAgICAgICBidWlsZGVyLmluc2VydCgyMywgJy0nKTsKKyAgICAgICAgcmV0dXJuIGJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD4KKyAgICAgKiBSZXNldHMgdGhlIHRyYW5zaWVudCBmaWVsZHMgdG8gbWF0Y2ggdGhlIGJlaGF2aW9yIG9mIHRoZSBjb25zdHJ1Y3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBJbnB1dFN0cmVhbX0gdG8gcmVhZCBmcm9tLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW59IHRocm93cyBpdC4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW59IHRocm93cyBpdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIHJlYWQgaW4gbm9uLXRyYW5zaWVudCBmaWVsZHMKKyAgICAgICAgaW4uZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgLy8gc2V0dXAgdHJhbnNpZW50IGZpZWxkcworICAgICAgICBpbml0KCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9Vbmtub3duRm9ybWF0Q29udmVyc2lvbkV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9Vbmtub3duRm9ybWF0Q29udmVyc2lvbkV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUyNmRlOTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1Vua25vd25Gb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1NiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgamF2YS51dGlsOworCisvKioKKyAqIEFuIHtAY29kZSBVbmtub3duRm9ybWF0Q29udmVyc2lvbkV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGZvcm1hdAorICogY29udmVyc2lvbiBpcyB1bmtub3duLgorICoKKyAqIEBzZWUgamF2YS5sYW5nLlJ1bnRpbWVFeGNlcHRpb24KKyAqLworcHVibGljIGNsYXNzIFVua25vd25Gb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9uIGV4dGVuZHMgSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbiB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTkwNjA0MThMOworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgczsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4ge0Bjb2RlIFVua25vd25Gb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9ufSB3aXRoIHRoZSB1bmtub3duCisgICAgICogZm9ybWF0IGNvbnZlcnNpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICB0aGUgdW5rbm93biBmb3JtYXQgY29udmVyc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5rbm93bkZvcm1hdENvbnZlcnNpb25FeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICAgICAgaWYgKHMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zID0gczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb252ZXJzaW9uIGFzc29jaWF0ZWQgd2l0aCB0aGUgZXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29udmVyc2lvbiBhc3NvY2lhdGVkIHdpdGggdGhlIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnZlcnNpb24oKSB7CisgICAgICAgIHJldHVybiBzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKyAgICAgICAgcmV0dXJuICJDb252ZXJzaW9uOiAiICsgczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1Vua25vd25Gb3JtYXRGbGFnc0V4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9Vbmtub3duRm9ybWF0RmxhZ3NFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZGFhM2YxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9Vbmtub3duRm9ybWF0RmxhZ3NFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDU4IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbDsKKworLyoqCisgKiBBbiB7QGNvZGUgVW5rbm93bkZvcm1hdEZsYWdzRXhjZXB0aW9ufSB3aWxsIGJlIHRocm93biBpZiB0aGVyZSBpcworICogYW4gdW5rbm93biBmbGFnLgorICoKKyAqIEBzZWUgamF2YS5sYW5nLlJ1bnRpbWVFeGNlcHRpb24KKyAqLworcHVibGljIGNsYXNzIFVua25vd25Gb3JtYXRGbGFnc0V4Y2VwdGlvbiBleHRlbmRzIElsbGVnYWxGb3JtYXRFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTkzNzA1MDZMOworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZmxhZ3M7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBVbmtub3duRm9ybWF0RmxhZ3NFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIGZsYWdzLgorICAgICAqCisgICAgICogQHBhcmFtIGYKKyAgICAgKiAgICAgICAgICAgdGhlIHNwZWNpZmllZCBmbGFncy4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5rbm93bkZvcm1hdEZsYWdzRXhjZXB0aW9uKFN0cmluZyBmKSB7CisgICAgICAgIGlmIChmID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGZsYWdzID0gZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBmbGFncyBhc3NvY2lhdGVkIHdpdGggdGhlIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGZsYWdzIGFzc29jaWF0ZWQgd2l0aCB0aGUgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RmxhZ3MoKSB7CisgICAgICAgIHJldHVybiBmbGFnczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2UoKSB7CisgICAgICAgIHJldHVybiAiRmxhZ3M6ICIgKyBmbGFnczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1Vuc2FmZUFycmF5TGlzdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9VbnNhZmVBcnJheUxpc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMDZlNzNlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9VbnNhZmVBcnJheUxpc3QuamF2YQpAQCAtMCwwICsxLDU4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5BcnJheTsKKworLyoqCisgKiBBbiBhcnJheS1iYWNrZWQgbGlzdCB0aGF0IGV4cG9zZXMgaXRzIGFycmF5LgorICoKKyAqIEBoaWRlCisgKi8KK3B1YmxpYyBjbGFzcyBVbnNhZmVBcnJheUxpc3Q8VD4gZXh0ZW5kcyBBYnN0cmFjdExpc3Q8VD4geworICAgIHByaXZhdGUgZmluYWwgQ2xhc3M8VD4gZWxlbWVudFR5cGU7CisgICAgcHJpdmF0ZSBUW10gYXJyYXk7CisgICAgcHJpdmF0ZSBpbnQgc2l6ZTsKKworICAgIHB1YmxpYyBVbnNhZmVBcnJheUxpc3QoQ2xhc3M8VD4gZWxlbWVudFR5cGUsIGludCBpbml0aWFsQ2FwYWNpdHkpIHsKKyAgICAgICAgdGhpcy5hcnJheSA9IChUW10pIEFycmF5Lm5ld0luc3RhbmNlKGVsZW1lbnRUeXBlLCBpbml0aWFsQ2FwYWNpdHkpOworICAgICAgICB0aGlzLmVsZW1lbnRUeXBlID0gZWxlbWVudFR5cGU7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGFkZChUIGVsZW1lbnQpIHsKKyAgICAgICAgaWYgKHNpemUgPT0gYXJyYXkubGVuZ3RoKSB7CisgICAgICAgICAgICBUW10gbmV3QXJyYXkgPSAoVFtdKSBBcnJheS5uZXdJbnN0YW5jZShlbGVtZW50VHlwZSwgc2l6ZSAqIDIpOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhcnJheSwgMCwgbmV3QXJyYXksIDAsIHNpemUpOworICAgICAgICAgICAgYXJyYXkgPSBuZXdBcnJheTsKKyAgICAgICAgfQorICAgICAgICBhcnJheVtzaXplKytdID0gZWxlbWVudDsKKyAgICAgICAgKyttb2RDb3VudDsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgcHVibGljIFRbXSBhcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIGFycmF5OworICAgIH0KKworICAgIHB1YmxpYyBUIGdldChpbnQgaSkgeworICAgICAgICByZXR1cm4gYXJyYXlbaV07CisgICAgfQorCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICByZXR1cm4gc2l6ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1ZlY3Rvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9WZWN0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMjM2YmUwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9WZWN0b3IuamF2YQpAQCAtMCwwICsxLDEwNTMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5BcnJheTsKKworLyoqCisgKiBWZWN0b3IgaXMgYW4gaW1wbGVtZW50YXRpb24gb2Yge0BsaW5rIExpc3R9LCBiYWNrZWQgYnkgYW4gYXJyYXkgYW5kIHN5bmNocm9uaXplZC4KKyAqIEFsbCBvcHRpb25hbCBvcGVyYXRpb25zIGluY2x1ZGluZyBhZGRpbmcsIHJlbW92aW5nLCBhbmQgcmVwbGFjaW5nIGVsZW1lbnRzIGFyZSBzdXBwb3J0ZWQuCisgKgorICogPHA+QWxsIGVsZW1lbnRzIGFyZSBwZXJtaXR0ZWQsIGluY2x1ZGluZyBudWxsLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgaXMgZXF1aXZhbGVudCB0byB7QGxpbmsgQXJyYXlMaXN0fSB3aXRoIHN5bmNocm9uaXplZCBvcGVyYXRpb25zLiBUaGlzIGhhcyBhCisgKiBwZXJmb3JtYW5jZSBjb3N0LCBhbmQgdGhlIHN5bmNocm9uaXphdGlvbiBpcyBub3QgbmVjZXNzYXJpbHkgbWVhbmluZ2Z1bCB0byB5b3VyIGFwcGxpY2F0aW9uOgorICogc3luY2hyb25pemluZyBlYWNoIGNhbGwgdG8ge0Bjb2RlIGdldH0sIGZvciBleGFtcGxlLCBpcyBub3QgZXF1aXZhbGVudCB0byBzeW5jaHJvbml6aW5nIG9uIHRoZQorICogbGlzdCBhbmQgaXRlcmF0aW5nIG92ZXIgaXQgKHdoaWNoIGlzIHByb2JhYmx5IHdoYXQgeW91IGludGVuZGVkKS4gSWYgeW91IGRvIG5lZWQgdmVyeSBoaWdobHkKKyAqIGNvbmN1cnJlbnQgYWNjZXNzLCB5b3Ugc2hvdWxkIGFsc28gY29uc2lkZXIge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LkNvcHlPbldyaXRlQXJyYXlMaXN0fS4KKyAqCisgKiBAcGFyYW0gPEU+IFRoZSBlbGVtZW50IHR5cGUgb2YgdGhpcyBsaXN0LgorICovCitwdWJsaWMgY2xhc3MgVmVjdG9yPEU+IGV4dGVuZHMgQWJzdHJhY3RMaXN0PEU+IGltcGxlbWVudHMgTGlzdDxFPiwKKyAgICAgICAgUmFuZG9tQWNjZXNzLCBDbG9uZWFibGUsIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjc2NzYwNTYxNDA0ODk4OTQzOUw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIG9yIHRoZSBzaXplIG9mIHRoZSB2ZWN0b3IuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBlbGVtZW50Q291bnQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZWxlbWVudHMgb2YgdGhlIHZlY3Rvci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgT2JqZWN0W10gZWxlbWVudERhdGE7CisKKyAgICAvKioKKyAgICAgKiBIb3cgbWFueSBlbGVtZW50cyBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIHZlY3RvciB3aGVuIGl0IGlzIGRldGVjdGVkIHRoYXQKKyAgICAgKiBpdCBuZWVkcyB0byBncm93IHRvIGFjY29tbW9kYXRlIGV4dHJhIGVudHJpZXMuIElmIHRoaXMgdmFsdWUgaXMgemVybyBvcgorICAgICAqIG5lZ2F0aXZlIHRoZSBzaXplIHdpbGwgYmUgZG91YmxlZCBpZiBhbiBpbmNyZWFzZSBpcyBuZWVkZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBjYXBhY2l0eUluY3JlbWVudDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1NJWkUgPSAxMDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgdmVjdG9yIHVzaW5nIHRoZSBkZWZhdWx0IGNhcGFjaXR5LgorICAgICAqLworICAgIHB1YmxpYyBWZWN0b3IoKSB7CisgICAgICAgIHRoaXMoREVGQVVMVF9TSVpFLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHZlY3RvciB1c2luZyB0aGUgc3BlY2lmaWVkIGNhcGFjaXR5LgorICAgICAqCisgICAgICogQHBhcmFtIGNhcGFjaXR5CisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbCBjYXBhY2l0eSBvZiB0aGUgbmV3IHZlY3Rvci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBjYXBhY2l0eX0gaXMgbmVnYXRpdmUuCisgICAgICovCisgICAgcHVibGljIFZlY3RvcihpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgdGhpcyhjYXBhY2l0eSwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB2ZWN0b3IgdXNpbmcgdGhlIHNwZWNpZmllZCBjYXBhY2l0eSBhbmQgY2FwYWNpdHkKKyAgICAgKiBpbmNyZW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2FwYWNpdHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIGNhcGFjaXR5IG9mIHRoZSBuZXcgdmVjdG9yLgorICAgICAqIEBwYXJhbSBjYXBhY2l0eUluY3JlbWVudAorICAgICAqICAgICAgICAgICAgdGhlIGFtb3VudCB0byBpbmNyZWFzZSB0aGUgY2FwYWNpdHkgd2hlbiB0aGlzIHZlY3RvciBpcyBmdWxsLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGNhcGFjaXR5fSBpcyBuZWdhdGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVmVjdG9yKGludCBjYXBhY2l0eSwgaW50IGNhcGFjaXR5SW5jcmVtZW50KSB7CisgICAgICAgIGlmIChjYXBhY2l0eSA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBlbGVtZW50RGF0YSA9IG5ld0VsZW1lbnRBcnJheShjYXBhY2l0eSk7CisgICAgICAgIGVsZW1lbnRDb3VudCA9IDA7CisgICAgICAgIHRoaXMuY2FwYWNpdHlJbmNyZW1lbnQgPSBjYXBhY2l0eUluY3JlbWVudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBWZWN0b3J9IGNvbnRhaW5pbmcgdGhlIGVsZW1lbnRzIGluCisgICAgICoge0Bjb2RlIGNvbGxlY3Rpb259LiBUaGUgb3JkZXIgb2YgdGhlIGVsZW1lbnRzIGluIHRoZSBuZXcge0Bjb2RlIFZlY3Rvcn0KKyAgICAgKiBpcyBkZXBlbmRlbnQgb24gdGhlIGl0ZXJhdGlvbiBvcmRlciBvZiB0aGUgc2VlZCBjb2xsZWN0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIG9mIGVsZW1lbnRzIHRvIGFkZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVmVjdG9yKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgdGhpcyhjb2xsZWN0aW9uLnNpemUoKSwgMCk7CisgICAgICAgIEl0ZXJhdG9yPD8gZXh0ZW5kcyBFPiBpdCA9IGNvbGxlY3Rpb24uaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgZWxlbWVudERhdGFbZWxlbWVudENvdW50KytdID0gaXQubmV4dCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHJpdmF0ZSBFW10gbmV3RWxlbWVudEFycmF5KGludCBzaXplKSB7CisgICAgICAgIHJldHVybiAoRVtdKSBuZXcgT2JqZWN0W3NpemVdOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIHNwZWNpZmllZCBvYmplY3QgaW50byB0aGlzIHZlY3RvciBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uLiBUaGUKKyAgICAgKiBvYmplY3QgaXMgaW5zZXJ0ZWQgYmVmb3JlIGFueSBlbGVtZW50IHdpdGggdGhlIHNhbWUgb3IgYSBoaWdoZXIgaW5kZXgKKyAgICAgKiBpbmNyZWFzaW5nIHRoZWlyIGluZGV4IGJ5IDEuIElmIHRoZSBsb2NhdGlvbiBpcyBlcXVhbCB0byB0aGUgc2l6ZSBvZiB0aGlzCisgICAgICogdmVjdG9yLCB0aGUgb2JqZWN0IGlzIGFkZGVkIGF0IHRoZSBlbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhdCB3aGljaCB0byBpbnNlcnQgdGhlIGVsZW1lbnQuCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBpbnNlcnQgaW4gdGhpcyB2ZWN0b3IuCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgbG9jYXRpb24gPCAwIHx8IGxvY2F0aW9uID4gc2l6ZSgpfS4KKyAgICAgKiBAc2VlICNhZGRFbGVtZW50CisgICAgICogQHNlZSAjc2l6ZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGFkZChpbnQgbG9jYXRpb24sIEUgb2JqZWN0KSB7CisgICAgICAgIGluc2VydEVsZW1lbnRBdChvYmplY3QsIGxvY2F0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGF0IHRoZSBlbmQgb2YgdGhpcyB2ZWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFkZCB0byB0aGUgdmVjdG9yLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGFkZChFIG9iamVjdCkgeworICAgICAgICBpZiAoZWxlbWVudENvdW50ID09IGVsZW1lbnREYXRhLmxlbmd0aCkgeworICAgICAgICAgICAgZ3Jvd0J5T25lKCk7CisgICAgICAgIH0KKyAgICAgICAgZWxlbWVudERhdGFbZWxlbWVudENvdW50KytdID0gb2JqZWN0OworICAgICAgICBtb2RDb3VudCsrOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBvYmplY3RzIGluIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uCisgICAgICogaW4gdGhpcyB2ZWN0b3IuIFRoZSBvYmplY3RzIGFyZSBpbnNlcnRlZCBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmUKKyAgICAgKiByZXR1cm5lZCBmcm9tIHRoZSBDb2xsZWN0aW9uIGl0ZXJhdG9yLiBUaGUgZWxlbWVudHMgd2l0aCBhbiBpbmRleCBlcXVhbAorICAgICAqIG9yIGhpZ2hlciB0aGFuIHtAY29kZSBsb2NhdGlvbn0gaGF2ZSB0aGVpciBpbmRleCBpbmNyZWFzZWQgYnkgdGhlIHNpemUgb2YKKyAgICAgKiB0aGUgYWRkZWQgY29sbGVjdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGxvY2F0aW9uIHRvIGluc2VydCB0aGUgb2JqZWN0cy4KKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cy4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHZlY3RvciBpcyBtb2RpZmllZCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgbG9jYXRpb24gPCAwfSBvciB7QGNvZGUgbG9jYXRpb24gPiBzaXplKCl9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBhZGRBbGwoaW50IGxvY2F0aW9uLCBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjb2xsZWN0aW9uKSB7CisgICAgICAgIGlmIChsb2NhdGlvbiA+PSAwICYmIGxvY2F0aW9uIDw9IGVsZW1lbnRDb3VudCkgeworICAgICAgICAgICAgaW50IHNpemUgPSBjb2xsZWN0aW9uLnNpemUoKTsKKyAgICAgICAgICAgIGlmIChzaXplID09IDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgcmVxdWlyZWQgPSBzaXplIC0gKGVsZW1lbnREYXRhLmxlbmd0aCAtIGVsZW1lbnRDb3VudCk7CisgICAgICAgICAgICBpZiAocmVxdWlyZWQgPiAwKSB7CisgICAgICAgICAgICAgICAgZ3Jvd0J5KHJlcXVpcmVkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBjb3VudCA9IGVsZW1lbnRDb3VudCAtIGxvY2F0aW9uOworICAgICAgICAgICAgaWYgKGNvdW50ID4gMCkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZWxlbWVudERhdGEsIGxvY2F0aW9uLCBlbGVtZW50RGF0YSwgbG9jYXRpb24KKyAgICAgICAgICAgICAgICAgICAgICAgICsgc2l6ZSwgY291bnQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgSXRlcmF0b3I8PyBleHRlbmRzIEU+IGl0ID0gY29sbGVjdGlvbi5pdGVyYXRvcigpOworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIGVsZW1lbnREYXRhW2xvY2F0aW9uKytdID0gaXQubmV4dCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxlbWVudENvdW50ICs9IHNpemU7CisgICAgICAgICAgICBtb2RDb3VudCsrOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgYXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKGxvY2F0aW9uLCBlbGVtZW50Q291bnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIG9iamVjdHMgaW4gdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIHRvIHRoZSBlbmQgb2YgdGhpcyB2ZWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cy4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHZlY3RvciBpcyBtb2RpZmllZCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGFkZEFsbChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjb2xsZWN0aW9uKSB7CisgICAgICAgIHJldHVybiBhZGRBbGwoZWxlbWVudENvdW50LCBjb2xsZWN0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGF0IHRoZSBlbmQgb2YgdGhpcyB2ZWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGFkZCB0byB0aGUgdmVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhZGRFbGVtZW50KEUgb2JqZWN0KSB7CisgICAgICAgIGlmIChlbGVtZW50Q291bnQgPT0gZWxlbWVudERhdGEubGVuZ3RoKSB7CisgICAgICAgICAgICBncm93QnlPbmUoKTsKKyAgICAgICAgfQorICAgICAgICBlbGVtZW50RGF0YVtlbGVtZW50Q291bnQrK10gPSBvYmplY3Q7CisgICAgICAgIG1vZENvdW50Kys7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRoaXMgdmVjdG9yIGNhbiBob2xkIHdpdGhvdXQgZ3Jvd2luZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNhcGFjaXR5IG9mIHRoaXMgdmVjdG9yLgorICAgICAqIEBzZWUgI2Vuc3VyZUNhcGFjaXR5CisgICAgICogQHNlZSAjc2l6ZQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGNhcGFjaXR5KCkgeworICAgICAgICByZXR1cm4gZWxlbWVudERhdGEubGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIGVsZW1lbnRzIGZyb20gdGhpcyB2ZWN0b3IsIGxlYXZpbmcgaXQgZW1wdHkuCisgICAgICoKKyAgICAgKiBAc2VlICNpc0VtcHR5CisgICAgICogQHNlZSAjc2l6ZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICByZW1vdmVBbGxFbGVtZW50cygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgdmVjdG9yIHdpdGggdGhlIHNhbWUgZWxlbWVudHMsIHNpemUsIGNhcGFjaXR5IGFuZCBjYXBhY2l0eQorICAgICAqIGluY3JlbWVudCBhcyB0aGlzIHZlY3Rvci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzaGFsbG93IGNvcHkgb2YgdGhpcyB2ZWN0b3IuCisgICAgICogQHNlZSBqYXZhLmxhbmcuQ2xvbmVhYmxlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN5bmNocm9uaXplZCBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBWZWN0b3I8RT4gdmVjdG9yID0gKFZlY3RvcjxFPikgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgICAgIHZlY3Rvci5lbGVtZW50RGF0YSA9IGVsZW1lbnREYXRhLmNsb25lKCk7CisgICAgICAgICAgICByZXR1cm4gdmVjdG9yOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyB0aGlzIHZlY3RvciBmb3IgdGhlIHNwZWNpZmllZCBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGxvb2sgZm9yIGluIHRoaXMgdmVjdG9yLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIG9iamVjdCBpcyBhbiBlbGVtZW50IG9mIHRoaXMgdmVjdG9yLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHNlZSAjaW5kZXhPZihPYmplY3QpCisgICAgICogQHNlZSAjaW5kZXhPZihPYmplY3QsIGludCkKKyAgICAgKiBAc2VlIGphdmEubGFuZy5PYmplY3QjZXF1YWxzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICByZXR1cm4gaW5kZXhPZihvYmplY3QsIDApICE9IC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlYXJjaGVzIHRoaXMgdmVjdG9yIGZvciBhbGwgb2JqZWN0cyBpbiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sbGVjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cy4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBhbGwgb2JqZWN0cyBpbiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gYXJlCisgICAgICogICAgICAgICBlbGVtZW50cyBvZiB0aGlzIHZlY3Rvciwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGNvbnRhaW5zQWxsKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbikgeworICAgICAgICByZXR1cm4gc3VwZXIuY29udGFpbnNBbGwoY29sbGVjdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gY29weSBlbGVtZW50cyBjb250YWluZWQgYnkgdGhpcyB7QGNvZGUgVmVjdG9yfSBpbnRvIHRoZQorICAgICAqIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMgb2YgdGhlIHN1cHBsaWVkIHtAY29kZSBPYmplY3R9IGFycmF5LgorICAgICAqCisgICAgICogQHBhcmFtIGVsZW1lbnRzCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIE9iamVjdH0gYXJyYXkgaW50byB3aGljaCB0aGUgZWxlbWVudHMgb2YgdGhpcworICAgICAqICAgICAgICAgICAgdmVjdG9yIGFyZSBjb3BpZWQuCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGVsZW1lbnRzfSBpcyBub3QgYmlnIGVub3VnaC4KKyAgICAgKiBAc2VlICNjbG9uZQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjb3B5SW50byhPYmplY3RbXSBlbGVtZW50cykgeworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVsZW1lbnREYXRhLCAwLCBlbGVtZW50cywgMCwgZWxlbWVudENvdW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgbG9jYXRpb24gaW4gdGhpcyB2ZWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4gaW4gdGhpcyB2ZWN0b3IuCisgICAgICogQHJldHVybiB0aGUgZWxlbWVudCBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uLgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGxvY2F0aW9uIDwgMCB8fCBsb2NhdGlvbiA+PSBzaXplKCl9LgorICAgICAqIEBzZWUgI3NpemUKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEUgZWxlbWVudEF0KGludCBsb2NhdGlvbikgeworICAgICAgICBpZiAobG9jYXRpb24gPCBlbGVtZW50Q291bnQpIHsKKyAgICAgICAgICAgIHJldHVybiAoRSkgZWxlbWVudERhdGFbbG9jYXRpb25dOworICAgICAgICB9CisgICAgICAgIHRocm93IGFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihsb2NhdGlvbiwgZWxlbWVudENvdW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGVudW1lcmF0aW9uIG9uIHRoZSBlbGVtZW50cyBvZiB0aGlzIHZlY3Rvci4gVGhlIHJlc3VsdHMgb2YgdGhlCisgICAgICogZW51bWVyYXRpb24gbWF5IGJlIGFmZmVjdGVkIGlmIHRoZSBjb250ZW50cyBvZiB0aGlzIHZlY3RvciBpcyBtb2RpZmllZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gZW51bWVyYXRpb24gb2YgdGhlIGVsZW1lbnRzIG9mIHRoaXMgdmVjdG9yLgorICAgICAqIEBzZWUgI2VsZW1lbnRBdAorICAgICAqIEBzZWUgRW51bWVyYXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bWVyYXRpb248RT4gZWxlbWVudHMoKSB7CisgICAgICAgIHJldHVybiBuZXcgRW51bWVyYXRpb248RT4oKSB7CisgICAgICAgICAgICBpbnQgcG9zID0gMDsKKworICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTW9yZUVsZW1lbnRzKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBwb3MgPCBlbGVtZW50Q291bnQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICAgICAgcHVibGljIEUgbmV4dEVsZW1lbnQoKSB7CisgICAgICAgICAgICAgICAgc3luY2hyb25pemVkIChWZWN0b3IudGhpcykgeworICAgICAgICAgICAgICAgICAgICBpZiAocG9zIDwgZWxlbWVudENvdW50KSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKEUpIGVsZW1lbnREYXRhW3BvcysrXTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuc3VyZXMgdGhhdCB0aGlzIHZlY3RvciBjYW4gaG9sZCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBlbGVtZW50cworICAgICAqIHdpdGhvdXQgZ3Jvd2luZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtaW5pbXVtQ2FwYWNpdHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBtaW5pbXVtIG51bWJlciBvZiBlbGVtZW50cyB0aGF0IHRoaXMgdmVjdG9yIHdpbGwgaG9sZAorICAgICAqICAgICAgICAgICAgYmVmb3JlIGdyb3dpbmcuCisgICAgICogQHNlZSAjY2FwYWNpdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgZW5zdXJlQ2FwYWNpdHkoaW50IG1pbmltdW1DYXBhY2l0eSkgeworICAgICAgICBpZiAoZWxlbWVudERhdGEubGVuZ3RoIDwgbWluaW11bUNhcGFjaXR5KSB7CisgICAgICAgICAgICBpbnQgbmV4dCA9IChjYXBhY2l0eUluY3JlbWVudCA8PSAwID8gZWxlbWVudERhdGEubGVuZ3RoCisgICAgICAgICAgICAgICAgICAgIDogY2FwYWNpdHlJbmNyZW1lbnQpCisgICAgICAgICAgICAgICAgICAgICsgZWxlbWVudERhdGEubGVuZ3RoOworICAgICAgICAgICAgZ3JvdyhtaW5pbXVtQ2FwYWNpdHkgPiBuZXh0ID8gbWluaW11bUNhcGFjaXR5IDogbmV4dCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIG9iamVjdCB0byB0aGlzIHZlY3RvciBhbmQgcmV0dXJucyBpZiB0aGV5IGFyZQorICAgICAqIGVxdWFsLiBUaGUgb2JqZWN0IG11c3QgYmUgYSBMaXN0IHdoaWNoIGNvbnRhaW5zIHRoZSBzYW1lIG9iamVjdHMgaW4gdGhlCisgICAgICogc2FtZSBvcmRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB3aXRoIHRoaXMgb2JqZWN0CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgZXF1YWwgdG8gdGhpcyB2ZWN0b3IsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNoYXNoQ29kZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBpZiAodGhpcyA9PSBvYmplY3QpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBMaXN0KSB7CisgICAgICAgICAgICBMaXN0PD8+IGxpc3QgPSAoTGlzdDw/Pikgb2JqZWN0OworICAgICAgICAgICAgaWYgKGxpc3Quc2l6ZSgpICE9IGVsZW1lbnRDb3VudCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IGluZGV4ID0gMDsKKyAgICAgICAgICAgIEl0ZXJhdG9yPD8+IGl0ID0gbGlzdC5pdGVyYXRvcigpOworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIE9iamVjdCBlMSA9IGVsZW1lbnREYXRhW2luZGV4KytdLCBlMiA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgICAgICBpZiAoIShlMSA9PSBudWxsID8gZTIgPT0gbnVsbCA6IGUxLmVxdWFscyhlMikpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZmlyc3QgZWxlbWVudCBpbiB0aGlzIHZlY3Rvci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnQgYXQgdGhlIGZpcnN0IHBvc2l0aW9uLgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHRoaXMgdmVjdG9yIGlzIGVtcHR5LgorICAgICAqIEBzZWUgI2VsZW1lbnRBdAorICAgICAqIEBzZWUgI2xhc3RFbGVtZW50CisgICAgICogQHNlZSAjc2l6ZQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgRSBmaXJzdEVsZW1lbnQoKSB7CisgICAgICAgIGlmIChlbGVtZW50Q291bnQgPiAwKSB7CisgICAgICAgICAgICByZXR1cm4gKEUpIGVsZW1lbnREYXRhWzBdOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZWxlbWVudCBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uIGluIHRoaXMgdmVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2F0aW9uCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuIGluIHRoaXMgdmVjdG9yLgorICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnQgYXQgdGhlIHNwZWNpZmllZCBsb2NhdGlvbi4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBsb2NhdGlvbiA8IDAgfHwgbG9jYXRpb24gPj0gc2l6ZSgpfS4KKyAgICAgKiBAc2VlICNzaXplCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEUgZ2V0KGludCBsb2NhdGlvbikgeworICAgICAgICByZXR1cm4gZWxlbWVudEF0KGxvY2F0aW9uKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZ3JvdyhpbnQgbmV3Q2FwYWNpdHkpIHsKKyAgICAgICAgRVtdIG5ld0RhdGEgPSBuZXdFbGVtZW50QXJyYXkobmV3Q2FwYWNpdHkpOworICAgICAgICAvLyBBc3N1bWVzIGVsZW1lbnRDb3VudCBpcyA8PSBuZXdDYXBhY2l0eQorICAgICAgICBhc3NlcnQgZWxlbWVudENvdW50IDw9IG5ld0NhcGFjaXR5OworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVsZW1lbnREYXRhLCAwLCBuZXdEYXRhLCAwLCBlbGVtZW50Q291bnQpOworICAgICAgICBlbGVtZW50RGF0YSA9IG5ld0RhdGE7CisgICAgfQorCisgICAgLyoqCisgICAgICogSklUIG9wdGltaXphdGlvbgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBncm93QnlPbmUoKSB7CisgICAgICAgIGludCBhZGRpbmcgPSAwOworICAgICAgICBpZiAoY2FwYWNpdHlJbmNyZW1lbnQgPD0gMCkgeworICAgICAgICAgICAgaWYgKChhZGRpbmcgPSBlbGVtZW50RGF0YS5sZW5ndGgpID09IDApIHsKKyAgICAgICAgICAgICAgICBhZGRpbmcgPSAxOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYWRkaW5nID0gY2FwYWNpdHlJbmNyZW1lbnQ7CisgICAgICAgIH0KKworICAgICAgICBFW10gbmV3RGF0YSA9IG5ld0VsZW1lbnRBcnJheShlbGVtZW50RGF0YS5sZW5ndGggKyBhZGRpbmcpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVsZW1lbnREYXRhLCAwLCBuZXdEYXRhLCAwLCBlbGVtZW50Q291bnQpOworICAgICAgICBlbGVtZW50RGF0YSA9IG5ld0RhdGE7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGdyb3dCeShpbnQgcmVxdWlyZWQpIHsKKyAgICAgICAgaW50IGFkZGluZyA9IDA7CisgICAgICAgIGlmIChjYXBhY2l0eUluY3JlbWVudCA8PSAwKSB7CisgICAgICAgICAgICBpZiAoKGFkZGluZyA9IGVsZW1lbnREYXRhLmxlbmd0aCkgPT0gMCkgeworICAgICAgICAgICAgICAgIGFkZGluZyA9IHJlcXVpcmVkOworICAgICAgICAgICAgfQorICAgICAgICAgICAgd2hpbGUgKGFkZGluZyA8IHJlcXVpcmVkKSB7CisgICAgICAgICAgICAgICAgYWRkaW5nICs9IGFkZGluZzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFkZGluZyA9IChyZXF1aXJlZCAvIGNhcGFjaXR5SW5jcmVtZW50KSAqIGNhcGFjaXR5SW5jcmVtZW50OworICAgICAgICAgICAgaWYgKGFkZGluZyA8IHJlcXVpcmVkKSB7CisgICAgICAgICAgICAgICAgYWRkaW5nICs9IGNhcGFjaXR5SW5jcmVtZW50OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIEVbXSBuZXdEYXRhID0gbmV3RWxlbWVudEFycmF5KGVsZW1lbnREYXRhLmxlbmd0aCArIGFkZGluZyk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZWxlbWVudERhdGEsIDAsIG5ld0RhdGEsIDAsIGVsZW1lbnRDb3VudCk7CisgICAgICAgIGVsZW1lbnREYXRhID0gbmV3RGF0YTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGludGVnZXIgaGFzaCBjb2RlIGZvciB0aGUgcmVjZWl2ZXIuIE9iamVjdHMgd2hpY2ggYXJlIGVxdWFsCisgICAgICogcmV0dXJuIHRoZSBzYW1lIHZhbHVlIGZvciB0aGlzIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgaGFzaC4KKyAgICAgKiBAc2VlICNlcXVhbHMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IHJlc3VsdCA9IDE7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZWxlbWVudENvdW50OyBpKyspIHsKKyAgICAgICAgICAgIHJlc3VsdCA9ICgzMSAqIHJlc3VsdCkKKyAgICAgICAgICAgICAgICAgICAgKyAoZWxlbWVudERhdGFbaV0gPT0gbnVsbCA/IDAgOiBlbGVtZW50RGF0YVtpXS5oYXNoQ29kZSgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlYXJjaGVzIGluIHRoaXMgdmVjdG9yIGZvciB0aGUgaW5kZXggb2YgdGhlIHNwZWNpZmllZCBvYmplY3QuIFRoZSBzZWFyY2gKKyAgICAgKiBmb3IgdGhlIG9iamVjdCBzdGFydHMgYXQgdGhlIGJlZ2lubmluZyBhbmQgbW92ZXMgdG93YXJkcyB0aGUgZW5kIG9mIHRoaXMKKyAgICAgKiB2ZWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGZpbmQgaW4gdGhpcyB2ZWN0b3IuCisgICAgICogQHJldHVybiB0aGUgaW5kZXggaW4gdGhpcyB2ZWN0b3Igb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50LCAtMSBpZiB0aGUKKyAgICAgKiAgICAgICAgIGVsZW1lbnQgaXNuJ3QgZm91bmQuCisgICAgICogQHNlZSAjY29udGFpbnMKKyAgICAgKiBAc2VlICNsYXN0SW5kZXhPZihPYmplY3QpCisgICAgICogQHNlZSAjbGFzdEluZGV4T2YoT2JqZWN0LCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBpbmRleE9mKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgcmV0dXJuIGluZGV4T2Yob2JqZWN0LCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyBpbiB0aGlzIHZlY3RvciBmb3IgdGhlIGluZGV4IG9mIHRoZSBzcGVjaWZpZWQgb2JqZWN0LiBUaGUgc2VhcmNoCisgICAgICogZm9yIHRoZSBvYmplY3Qgc3RhcnRzIGF0IHRoZSBzcGVjaWZpZWQgbG9jYXRpb24gYW5kIG1vdmVzIHRvd2FyZHMgdGhlIGVuZAorICAgICAqIG9mIHRoaXMgdmVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBmaW5kIGluIHRoaXMgdmVjdG9yLgorICAgICAqIEBwYXJhbSBsb2NhdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGF0IHdoaWNoIHRvIHN0YXJ0IHNlYXJjaGluZy4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBpbiB0aGlzIHZlY3RvciBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQsIC0xIGlmIHRoZQorICAgICAqICAgICAgICAgZWxlbWVudCBpc24ndCBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBsb2NhdGlvbiA8IDB9LgorICAgICAqIEBzZWUgI2NvbnRhaW5zCisgICAgICogQHNlZSAjbGFzdEluZGV4T2YoT2JqZWN0KQorICAgICAqIEBzZWUgI2xhc3RJbmRleE9mKE9iamVjdCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGluZGV4T2YoT2JqZWN0IG9iamVjdCwgaW50IGxvY2F0aW9uKSB7CisgICAgICAgIGlmIChvYmplY3QgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IGxvY2F0aW9uOyBpIDwgZWxlbWVudENvdW50OyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAob2JqZWN0LmVxdWFscyhlbGVtZW50RGF0YVtpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IGxvY2F0aW9uOyBpIDwgZWxlbWVudENvdW50OyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoZWxlbWVudERhdGFbaV0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBvYmplY3QgaW50byB0aGlzIHZlY3RvciBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uLgorICAgICAqIFRoaXMgb2JqZWN0IGlzIGluc2VydGVkIGJlZm9yZSBhbnkgcHJldmlvdXMgZWxlbWVudCBhdCB0aGUgc3BlY2lmaWVkCisgICAgICogbG9jYXRpb24uIEFsbCBlbGVtZW50cyB3aXRoIGFuIGluZGV4IGVxdWFsIG9yIGdyZWF0ZXIgdGhhbgorICAgICAqIHtAY29kZSBsb2NhdGlvbn0gaGF2ZSB0aGVpciBpbmRleCBpbmNyZWFzZWQgYnkgMS4gSWYgdGhlIGxvY2F0aW9uIGlzCisgICAgICogZXF1YWwgdG8gdGhlIHNpemUgb2YgdGhpcyB2ZWN0b3IsIHRoZSBvYmplY3QgaXMgYWRkZWQgYXQgdGhlIGVuZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gaW5zZXJ0IGluIHRoaXMgdmVjdG9yLgorICAgICAqIEBwYXJhbSBsb2NhdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGF0IHdoaWNoIHRvIGluc2VydCB0aGUgZWxlbWVudC4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBsb2NhdGlvbiA8IDAgfHwgbG9jYXRpb24gPiBzaXplKCl9LgorICAgICAqIEBzZWUgI2FkZEVsZW1lbnQKKyAgICAgKiBAc2VlICNzaXplCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGluc2VydEVsZW1lbnRBdChFIG9iamVjdCwgaW50IGxvY2F0aW9uKSB7CisgICAgICAgIGlmIChsb2NhdGlvbiA+PSAwICYmIGxvY2F0aW9uIDw9IGVsZW1lbnRDb3VudCkgeworICAgICAgICAgICAgaWYgKGVsZW1lbnRDb3VudCA9PSBlbGVtZW50RGF0YS5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBncm93QnlPbmUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBjb3VudCA9IGVsZW1lbnRDb3VudCAtIGxvY2F0aW9uOworICAgICAgICAgICAgaWYgKGNvdW50ID4gMCkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZWxlbWVudERhdGEsIGxvY2F0aW9uLCBlbGVtZW50RGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uICsgMSwgY291bnQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxlbWVudERhdGFbbG9jYXRpb25dID0gb2JqZWN0OworICAgICAgICAgICAgZWxlbWVudENvdW50Kys7CisgICAgICAgICAgICBtb2RDb3VudCsrOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgYXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKGxvY2F0aW9uLCBlbGVtZW50Q291bnQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBpZiB0aGlzIHZlY3RvciBoYXMgbm8gZWxlbWVudHMsIGEgc2l6ZSBvZiB6ZXJvLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyB2ZWN0b3IgaGFzIG5vIGVsZW1lbnRzLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHNlZSAjc2l6ZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICByZXR1cm4gZWxlbWVudENvdW50ID09IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGFzdCBlbGVtZW50IGluIHRoaXMgdmVjdG9yLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZWxlbWVudCBhdCB0aGUgbGFzdCBwb3NpdGlvbi4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGlzIHZlY3RvciBpcyBlbXB0eS4KKyAgICAgKiBAc2VlICNlbGVtZW50QXQKKyAgICAgKiBAc2VlICNmaXJzdEVsZW1lbnQKKyAgICAgKiBAc2VlICNzaXplCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN5bmNocm9uaXplZCBFIGxhc3RFbGVtZW50KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIChFKSBlbGVtZW50RGF0YVtlbGVtZW50Q291bnQgLSAxXTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VhcmNoZXMgaW4gdGhpcyB2ZWN0b3IgZm9yIHRoZSBpbmRleCBvZiB0aGUgc3BlY2lmaWVkIG9iamVjdC4gVGhlIHNlYXJjaAorICAgICAqIGZvciB0aGUgb2JqZWN0IHN0YXJ0cyBhdCB0aGUgZW5kIGFuZCBtb3ZlcyB0b3dhcmRzIHRoZSBzdGFydCBvZiB0aGlzCisgICAgICogdmVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBmaW5kIGluIHRoaXMgdmVjdG9yLgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IGluIHRoaXMgdmVjdG9yIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudCwgLTEgaWYgdGhlCisgICAgICogICAgICAgICBlbGVtZW50IGlzbid0IGZvdW5kLgorICAgICAqIEBzZWUgI2NvbnRhaW5zCisgICAgICogQHNlZSAjaW5kZXhPZihPYmplY3QpCisgICAgICogQHNlZSAjaW5kZXhPZihPYmplY3QsIGludCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBsYXN0SW5kZXhPZihPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIHJldHVybiBsYXN0SW5kZXhPZihvYmplY3QsIGVsZW1lbnRDb3VudCAtIDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlYXJjaGVzIGluIHRoaXMgdmVjdG9yIGZvciB0aGUgaW5kZXggb2YgdGhlIHNwZWNpZmllZCBvYmplY3QuIFRoZSBzZWFyY2gKKyAgICAgKiBmb3IgdGhlIG9iamVjdCBzdGFydHMgYXQgdGhlIHNwZWNpZmllZCBsb2NhdGlvbiBhbmQgbW92ZXMgdG93YXJkcyB0aGUKKyAgICAgKiBzdGFydCBvZiB0aGlzIHZlY3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gZmluZCBpbiB0aGlzIHZlY3Rvci4KKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhdCB3aGljaCB0byBzdGFydCBzZWFyY2hpbmcuCisgICAgICogQHJldHVybiB0aGUgaW5kZXggaW4gdGhpcyB2ZWN0b3Igb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50LCAtMSBpZiB0aGUKKyAgICAgKiAgICAgICAgIGVsZW1lbnQgaXNuJ3QgZm91bmQuCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgbG9jYXRpb24gPj0gc2l6ZSgpfS4KKyAgICAgKiBAc2VlICNjb250YWlucworICAgICAqIEBzZWUgI2luZGV4T2YoT2JqZWN0KQorICAgICAqIEBzZWUgI2luZGV4T2YoT2JqZWN0LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgbGFzdEluZGV4T2YoT2JqZWN0IG9iamVjdCwgaW50IGxvY2F0aW9uKSB7CisgICAgICAgIGlmIChsb2NhdGlvbiA8IGVsZW1lbnRDb3VudCkgeworICAgICAgICAgICAgaWYgKG9iamVjdCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGxvY2F0aW9uOyBpID49IDA7IGktLSkgeworICAgICAgICAgICAgICAgICAgICBpZiAob2JqZWN0LmVxdWFscyhlbGVtZW50RGF0YVtpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gbG9jYXRpb247IGkgPj0gMDsgaS0tKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50RGF0YVtpXSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBhcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24obG9jYXRpb24sIGVsZW1lbnRDb3VudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgb2JqZWN0IGF0IHRoZSBzcGVjaWZpZWQgbG9jYXRpb24gZnJvbSB0aGlzIHZlY3Rvci4gQWxsCisgICAgICogZWxlbWVudHMgd2l0aCBhbiBpbmRleCBiaWdnZXIgdGhhbiB7QGNvZGUgbG9jYXRpb259IGhhdmUgdGhlaXIgaW5kZXgKKyAgICAgKiBkZWNyZWFzZWQgYnkgMS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBvYmplY3QgdG8gcmVtb3ZlLgorICAgICAqIEByZXR1cm4gdGhlIHJlbW92ZWQgb2JqZWN0LgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBsb2NhdGlvbiA8IDAgfHwgbG9jYXRpb24gPj0gc2l6ZSgpfS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEUgcmVtb3ZlKGludCBsb2NhdGlvbikgeworICAgICAgICBpZiAobG9jYXRpb24gPCBlbGVtZW50Q291bnQpIHsKKyAgICAgICAgICAgIEUgcmVzdWx0ID0gKEUpIGVsZW1lbnREYXRhW2xvY2F0aW9uXTsKKyAgICAgICAgICAgIGVsZW1lbnRDb3VudC0tOworICAgICAgICAgICAgaW50IHNpemUgPSBlbGVtZW50Q291bnQgLSBsb2NhdGlvbjsKKyAgICAgICAgICAgIGlmIChzaXplID4gMCkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZWxlbWVudERhdGEsIGxvY2F0aW9uICsgMSwgZWxlbWVudERhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbiwgc2l6ZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbGVtZW50RGF0YVtlbGVtZW50Q291bnRdID0gbnVsbDsKKyAgICAgICAgICAgIG1vZENvdW50Kys7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgICAgIHRocm93IGFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihsb2NhdGlvbiwgZWxlbWVudENvdW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBmaXJzdCBvY2N1cnJlbmNlLCBzdGFydGluZyBhdCB0aGUgYmVnaW5uaW5nIGFuZCBtb3ZpbmcKKyAgICAgKiB0b3dhcmRzIHRoZSBlbmQsIG9mIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGZyb20gdGhpcyB2ZWN0b3IuIEFsbCBlbGVtZW50cworICAgICAqIHdpdGggYW4gaW5kZXggYmlnZ2VyIHRoYW4gdGhlIGVsZW1lbnQgdGhhdCBnZXRzIHJlbW92ZWQgaGF2ZSB0aGVpciBpbmRleAorICAgICAqIGRlY3JlYXNlZCBieSAxLgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byByZW1vdmUgZnJvbSB0aGlzIHZlY3Rvci4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCB3YXMgZm91bmQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNyZW1vdmVBbGxFbGVtZW50cworICAgICAqIEBzZWUgI3JlbW92ZUVsZW1lbnRBdAorICAgICAqIEBzZWUgI3NpemUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG9iamVjdCkgeworICAgICAgICByZXR1cm4gcmVtb3ZlRWxlbWVudChvYmplY3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIG9jY3VycmVuY2VzIGluIHRoaXMgdmVjdG9yIG9mIGVhY2ggb2JqZWN0IGluIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBDb2xsZWN0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIG9mIG9iamVjdHMgdG8gcmVtb3ZlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgdmVjdG9yIGlzIG1vZGlmaWVkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNyZW1vdmUoT2JqZWN0KQorICAgICAqIEBzZWUgI2NvbnRhaW5zKE9iamVjdCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gcmVtb3ZlQWxsKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbikgeworICAgICAgICByZXR1cm4gc3VwZXIucmVtb3ZlQWxsKGNvbGxlY3Rpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIGVsZW1lbnRzIGZyb20gdGhpcyB2ZWN0b3IsIGxlYXZpbmcgdGhlIHNpemUgemVybyBhbmQgdGhlCisgICAgICogY2FwYWNpdHkgdW5jaGFuZ2VkLgorICAgICAqCisgICAgICogQHNlZSAjaXNFbXB0eQorICAgICAqIEBzZWUgI3NpemUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVtb3ZlQWxsRWxlbWVudHMoKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZWxlbWVudENvdW50OyBpKyspIHsKKyAgICAgICAgICAgIGVsZW1lbnREYXRhW2ldID0gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBtb2RDb3VudCsrOworICAgICAgICBlbGVtZW50Q291bnQgPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGZpcnN0IG9jY3VycmVuY2UsIHN0YXJ0aW5nIGF0IHRoZSBiZWdpbm5pbmcgYW5kIG1vdmluZworICAgICAqIHRvd2FyZHMgdGhlIGVuZCwgb2YgdGhlIHNwZWNpZmllZCBvYmplY3QgZnJvbSB0aGlzIHZlY3Rvci4gQWxsIGVsZW1lbnRzCisgICAgICogd2l0aCBhbiBpbmRleCBiaWdnZXIgdGhhbiB0aGUgZWxlbWVudCB0aGF0IGdldHMgcmVtb3ZlZCBoYXZlIHRoZWlyIGluZGV4CisgICAgICogZGVjcmVhc2VkIGJ5IDEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIHJlbW92ZSBmcm9tIHRoaXMgdmVjdG9yLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHdhcyBmb3VuZCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgI3JlbW92ZUFsbEVsZW1lbnRzCisgICAgICogQHNlZSAjcmVtb3ZlRWxlbWVudEF0CisgICAgICogQHNlZSAjc2l6ZQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiByZW1vdmVFbGVtZW50KE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgaW50IGluZGV4OworICAgICAgICBpZiAoKGluZGV4ID0gaW5kZXhPZihvYmplY3QsIDApKSA9PSAtMSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJlbW92ZUVsZW1lbnRBdChpbmRleCk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGVsZW1lbnQgZm91bmQgYXQgaW5kZXggcG9zaXRpb24ge0Bjb2RlIGxvY2F0aW9ufSBmcm9tCisgICAgICogdGhpcyB7QGNvZGUgVmVjdG9yfS4gQWxsIGVsZW1lbnRzIHdpdGggYW4gaW5kZXggYmlnZ2VyIHRoYW4KKyAgICAgKiB7QGNvZGUgbG9jYXRpb259IGhhdmUgdGhlaXIgaW5kZXggZGVjcmVhc2VkIGJ5IDEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZW1vdmUuCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgbG9jYXRpb24gPCAwIHx8IGxvY2F0aW9uID49IHNpemUoKX0uCisgICAgICogQHNlZSAjcmVtb3ZlRWxlbWVudAorICAgICAqIEBzZWUgI3JlbW92ZUFsbEVsZW1lbnRzCisgICAgICogQHNlZSAjc2l6ZQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZW1vdmVFbGVtZW50QXQoaW50IGxvY2F0aW9uKSB7CisgICAgICAgIGlmIChsb2NhdGlvbiA+PSAwICYmIGxvY2F0aW9uIDwgZWxlbWVudENvdW50KSB7CisgICAgICAgICAgICBlbGVtZW50Q291bnQtLTsKKyAgICAgICAgICAgIGludCBzaXplID0gZWxlbWVudENvdW50IC0gbG9jYXRpb247CisgICAgICAgICAgICBpZiAoc2l6ZSA+IDApIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVsZW1lbnREYXRhLCBsb2NhdGlvbiArIDEsIGVsZW1lbnREYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24sIHNpemUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxlbWVudERhdGFbZWxlbWVudENvdW50XSA9IG51bGw7CisgICAgICAgICAgICBtb2RDb3VudCsrOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgYXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKGxvY2F0aW9uLCBlbGVtZW50Q291bnQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgb2JqZWN0cyBpbiB0aGUgc3BlY2lmaWVkIHJhbmdlIGZyb20gdGhlIHN0YXJ0IHRvIHRoZSwgYnV0IG5vdAorICAgICAqIGluY2x1ZGluZywgZW5kIGluZGV4LiBBbGwgZWxlbWVudHMgd2l0aCBhbiBpbmRleCBiaWdnZXIgdGhhbiBvciBlcXVhbCB0bworICAgICAqIHtAY29kZSBlbmR9IGhhdmUgdGhlaXIgaW5kZXggZGVjcmVhc2VkIGJ5IHtAY29kZSBlbmQgLSBzdGFydH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhdCB3aGljaCB0byBzdGFydCByZW1vdmluZy4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb25lIHBhc3QgdGhlIGVuZCBvZiB0aGUgcmFuZ2UgdG8gcmVtb3ZlLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA8IDAsIHN0YXJ0ID4gZW5kfSBvcgorICAgICAqICAgICAgICAgICAgICAgIHtAY29kZSBlbmQgPiBzaXplKCl9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHJlbW92ZVJhbmdlKGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBpZiAoc3RhcnQgPj0gMCAmJiBzdGFydCA8PSBlbmQgJiYgZW5kIDw9IGVsZW1lbnRDb3VudCkgeworICAgICAgICAgICAgaWYgKHN0YXJ0ID09IGVuZCkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChlbmQgIT0gZWxlbWVudENvdW50KSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShlbGVtZW50RGF0YSwgZW5kLCBlbGVtZW50RGF0YSwgc3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50Q291bnQgLSBlbmQpOworICAgICAgICAgICAgICAgIGludCBuZXdDb3VudCA9IGVsZW1lbnRDb3VudCAtIChlbmQgLSBzdGFydCk7CisgICAgICAgICAgICAgICAgQXJyYXlzLmZpbGwoZWxlbWVudERhdGEsIG5ld0NvdW50LCBlbGVtZW50Q291bnQsIG51bGwpOworICAgICAgICAgICAgICAgIGVsZW1lbnRDb3VudCA9IG5ld0NvdW50OworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBBcnJheXMuZmlsbChlbGVtZW50RGF0YSwgc3RhcnQsIGVsZW1lbnRDb3VudCwgbnVsbCk7CisgICAgICAgICAgICAgICAgZWxlbWVudENvdW50ID0gc3RhcnQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtb2RDb3VudCsrOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIG9iamVjdHMgZnJvbSB0aGlzIHZlY3RvciB0aGF0IGFyZSBub3QgY29udGFpbmVkIGluIHRoZQorICAgICAqIHNwZWNpZmllZCBjb2xsZWN0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2xsZWN0aW9uIG9mIG9iamVjdHMgdG8gcmV0YWluLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgdmVjdG9yIGlzIG1vZGlmaWVkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAc2VlICNyZW1vdmUoT2JqZWN0KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiByZXRhaW5BbGwoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKSB7CisgICAgICAgIHJldHVybiBzdXBlci5yZXRhaW5BbGwoY29sbGVjdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwbGFjZXMgdGhlIGVsZW1lbnQgYXQgdGhlIHNwZWNpZmllZCBsb2NhdGlvbiBpbiB0aGlzIHZlY3RvciB3aXRoIHRoZQorICAgICAqIHNwZWNpZmllZCBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBhdCB3aGljaCB0byBwdXQgdGhlIHNwZWNpZmllZCBvYmplY3QuCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBhZGQgdG8gdGhpcyB2ZWN0b3IuCisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgZWxlbWVudCBhdCB0aGUgbG9jYXRpb24uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB7QGNvZGUgbG9jYXRpb24gPCAwIHx8IGxvY2F0aW9uID49IHNpemUoKX0uCisgICAgICogQHNlZSAjc2l6ZQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgRSBzZXQoaW50IGxvY2F0aW9uLCBFIG9iamVjdCkgeworICAgICAgICBpZiAobG9jYXRpb24gPCBlbGVtZW50Q291bnQpIHsKKyAgICAgICAgICAgIEUgcmVzdWx0ID0gKEUpIGVsZW1lbnREYXRhW2xvY2F0aW9uXTsKKyAgICAgICAgICAgIGVsZW1lbnREYXRhW2xvY2F0aW9uXSA9IG9iamVjdDsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgYXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKGxvY2F0aW9uLCBlbGVtZW50Q291bnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2VzIHRoZSBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgbG9jYXRpb24gaW4gdGhpcyB2ZWN0b3Igd2l0aCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBhZGQgdG8gdGhpcyB2ZWN0b3IuCisgICAgICogQHBhcmFtIGxvY2F0aW9uCisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggYXQgd2hpY2ggdG8gcHV0IHRoZSBzcGVjaWZpZWQgb2JqZWN0LgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIGxvY2F0aW9uIDwgMCB8fCBsb2NhdGlvbiA+PSBzaXplKCl9LgorICAgICAqIEBzZWUgI3NpemUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0RWxlbWVudEF0KEUgb2JqZWN0LCBpbnQgbG9jYXRpb24pIHsKKyAgICAgICAgaWYgKGxvY2F0aW9uIDwgZWxlbWVudENvdW50KSB7CisgICAgICAgICAgICBlbGVtZW50RGF0YVtsb2NhdGlvbl0gPSBvYmplY3Q7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBhcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24obG9jYXRpb24sIGVsZW1lbnRDb3VudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3YXMgZXh0cmFjdGVkIHRvIGVuY291cmFnZSBWTSB0byBpbmxpbmUgY2FsbGVycy4KKyAgICAgKiBUT0RPOiB3aGVuIHdlIGhhdmUgYSBWTSB0aGF0IGNhbiBhY3R1YWxseSBpbmxpbmUsIG1vdmUgdGhlIHRlc3QgaW4gaGVyZSB0b28hCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihpbnQgaW5kZXgsIGludCBzaXplKSB7CisgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oc2l6ZSwgaW5kZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHNpemUgb2YgdGhpcyB2ZWN0b3IgdG8gdGhlIHNwZWNpZmllZCBzaXplLiBJZiB0aGVyZSBhcmUgbW9yZQorICAgICAqIHRoYW4gbGVuZ3RoIGVsZW1lbnRzIGluIHRoaXMgdmVjdG9yLCB0aGUgZWxlbWVudHMgYXQgZW5kIGFyZSBsb3N0LiBJZgorICAgICAqIHRoZXJlIGFyZSBsZXNzIHRoYW4gbGVuZ3RoIGVsZW1lbnRzIGluIHRoZSB2ZWN0b3IsIHRoZSBhZGRpdGlvbmFsCisgICAgICogZWxlbWVudHMgY29udGFpbiBudWxsLgorICAgICAqCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBzaXplIG9mIHRoaXMgdmVjdG9yLgorICAgICAqIEBzZWUgI3NpemUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0U2l6ZShpbnQgbGVuZ3RoKSB7CisgICAgICAgIGlmIChsZW5ndGggPT0gZWxlbWVudENvdW50KSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZW5zdXJlQ2FwYWNpdHkobGVuZ3RoKTsKKyAgICAgICAgaWYgKGVsZW1lbnRDb3VudCA+IGxlbmd0aCkgeworICAgICAgICAgICAgQXJyYXlzLmZpbGwoZWxlbWVudERhdGEsIGxlbmd0aCwgZWxlbWVudENvdW50LCBudWxsKTsKKyAgICAgICAgfQorICAgICAgICBlbGVtZW50Q291bnQgPSBsZW5ndGg7CisgICAgICAgIG1vZENvdW50Kys7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgdmVjdG9yLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgdmVjdG9yLgorICAgICAqIEBzZWUgI2VsZW1lbnRDb3VudAorICAgICAqIEBzZWUgI2xhc3RFbGVtZW50CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgc2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIGVsZW1lbnRDb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgTGlzdCBvZiB0aGUgc3BlY2lmaWVkIHBvcnRpb24gb2YgdGhpcyB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQKKyAgICAgKiBpbmRleCB0byBvbmUgbGVzcyB0aGFuIHRoZSBlbmQgaW5kZXguIFRoZSByZXR1cm5lZCBMaXN0IGlzIGJhY2tlZCBieSB0aGlzCisgICAgICogdmVjdG9yIHNvIGNoYW5nZXMgdG8gb25lIGFyZSByZWZsZWN0ZWQgYnkgdGhlIG90aGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggYXQgd2hpY2ggdG8gc3RhcnQgdGhlIHN1Ymxpc3QuCisgICAgICogQHBhcmFtIGVuZAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9uZSBwYXN0IHRoZSBlbmQgb2YgdGhlIHN1Ymxpc3QuCisgICAgICogQHJldHVybiBhIExpc3Qgb2YgYSBwb3J0aW9uIG9mIHRoaXMgdmVjdG9yLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIHtAY29kZSBzdGFydCA8IDB9IG9yIHtAY29kZSBlbmQgPiBzaXplKCl9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYge0Bjb2RlIHN0YXJ0ID4gZW5kfS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIExpc3Q8RT4gc3ViTGlzdChpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBDb2xsZWN0aW9ucy5TeW5jaHJvbml6ZWRSYW5kb21BY2Nlc3NMaXN0PEU+KHN1cGVyLnN1Ykxpc3QoCisgICAgICAgICAgICAgICAgc3RhcnQsIGVuZCksIHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgYXJyYXkgY29udGFpbmluZyBhbGwgZWxlbWVudHMgY29udGFpbmVkIGluIHRoaXMgdmVjdG9yLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiB0aGUgZWxlbWVudHMgZnJvbSB0aGlzIHZlY3Rvci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIE9iamVjdFtdIHRvQXJyYXkoKSB7CisgICAgICAgIE9iamVjdFtdIHJlc3VsdCA9IG5ldyBPYmplY3RbZWxlbWVudENvdW50XTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShlbGVtZW50RGF0YSwgMCwgcmVzdWx0LCAwLCBlbGVtZW50Q291bnQpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgZWxlbWVudHMgY29udGFpbmVkIGluIHRoaXMgdmVjdG9yLiBJZiB0aGUKKyAgICAgKiBzcGVjaWZpZWQgYXJyYXkgaXMgbGFyZ2UgZW5vdWdoIHRvIGhvbGQgdGhlIGVsZW1lbnRzLCB0aGUgc3BlY2lmaWVkIGFycmF5CisgICAgICogaXMgdXNlZCwgb3RoZXJ3aXNlIGFuIGFycmF5IG9mIHRoZSBzYW1lIHR5cGUgaXMgY3JlYXRlZC4gSWYgdGhlIHNwZWNpZmllZAorICAgICAqIGFycmF5IGlzIHVzZWQgYW5kIGlzIGxhcmdlciB0aGFuIHRoaXMgdmVjdG9yLCB0aGUgYXJyYXkgZWxlbWVudCBmb2xsb3dpbmcKKyAgICAgKiB0aGUgY29sbGVjdGlvbiBlbGVtZW50cyBpcyBzZXQgdG8gbnVsbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb250ZW50cworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IHRvIGZpbGwuCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiB0aGUgZWxlbWVudHMgZnJvbSB0aGlzIHZlY3Rvci4KKyAgICAgKiBAdGhyb3dzIEFycmF5U3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgdHlwZSBvZiBhbiBlbGVtZW50IGluIHRoaXMgdmVjdG9yIGNhbm5vdCBiZQorICAgICAqICAgICAgICAgICAgICAgIHN0b3JlZCBpbiB0aGUgdHlwZSBvZiB0aGUgc3BlY2lmaWVkIGFycmF5LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgPFQ+IFRbXSB0b0FycmF5KFRbXSBjb250ZW50cykgeworICAgICAgICBpZiAoZWxlbWVudENvdW50ID4gY29udGVudHMubGVuZ3RoKSB7CisgICAgICAgICAgICBDbGFzczw/PiBjdCA9IGNvbnRlbnRzLmdldENsYXNzKCkuZ2V0Q29tcG9uZW50VHlwZSgpOworICAgICAgICAgICAgY29udGVudHMgPSAoVFtdKSBBcnJheS5uZXdJbnN0YW5jZShjdCwgZWxlbWVudENvdW50KTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVsZW1lbnREYXRhLCAwLCBjb250ZW50cywgMCwgZWxlbWVudENvdW50KTsKKyAgICAgICAgaWYgKGVsZW1lbnRDb3VudCA8IGNvbnRlbnRzLmxlbmd0aCkgeworICAgICAgICAgICAgY29udGVudHNbZWxlbWVudENvdW50XSA9IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvbnRlbnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHZlY3Rvci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHZlY3Rvci4KKyAgICAgKiBAc2VlICNlbGVtZW50cworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBpZiAoZWxlbWVudENvdW50ID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAiW10iOworICAgICAgICB9CisgICAgICAgIGludCBsZW5ndGggPSBlbGVtZW50Q291bnQgLSAxOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWlsZGVyKGVsZW1lbnRDb3VudCAqIDE2KTsKKyAgICAgICAgYnVmZmVyLmFwcGVuZCgnWycpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoZWxlbWVudERhdGFbaV0gPT0gdGhpcykgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIih0aGlzIENvbGxlY3Rpb24pIik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZWxlbWVudERhdGFbaV0pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiLCAiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZWxlbWVudERhdGFbbGVuZ3RoXSA9PSB0aGlzKSB7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCIodGhpcyBDb2xsZWN0aW9uKSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChlbGVtZW50RGF0YVtsZW5ndGhdKTsKKyAgICAgICAgfQorICAgICAgICBidWZmZXIuYXBwZW5kKCddJyk7CisgICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjYXBhY2l0eSBvZiB0aGlzIHZlY3RvciB0byBiZSB0aGUgc2FtZSBhcyB0aGUgc2l6ZS4KKyAgICAgKgorICAgICAqIEBzZWUgI2NhcGFjaXR5CisgICAgICogQHNlZSAjZW5zdXJlQ2FwYWNpdHkKKyAgICAgKiBAc2VlICNzaXplCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHRyaW1Ub1NpemUoKSB7CisgICAgICAgIGlmIChlbGVtZW50RGF0YS5sZW5ndGggIT0gZWxlbWVudENvdW50KSB7CisgICAgICAgICAgICBncm93KGVsZW1lbnRDb3VudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBzdHJlYW0pCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdHJlYW0uZGVmYXVsdFdyaXRlT2JqZWN0KCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9XZWFrSGFzaE1hcC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9XZWFrSGFzaE1hcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY0MTc2NzkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL1dlYWtIYXNoTWFwLmphdmEKQEAgLTAsMCArMSw3MzIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsOworCitpbXBvcnQgamF2YS5sYW5nLnJlZi5SZWZlcmVuY2VRdWV1ZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmLldlYWtSZWZlcmVuY2U7CisKKy8qKgorICogV2Vha0hhc2hNYXAgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgTWFwIHdpdGgga2V5cyB3aGljaCBhcmUgV2Vha1JlZmVyZW5jZXMuIEEKKyAqIGtleS92YWx1ZSBtYXBwaW5nIGlzIHJlbW92ZWQgd2hlbiB0aGUga2V5IGlzIG5vIGxvbmdlciByZWZlcmVuY2VkLiBBbGwKKyAqIG9wdGlvbmFsIG9wZXJhdGlvbnMgKGFkZGluZyBhbmQgcmVtb3ZpbmcpIGFyZSBzdXBwb3J0ZWQuIEtleXMgYW5kIHZhbHVlcyBjYW4KKyAqIGJlIGFueSBvYmplY3RzLiBOb3RlIHRoYXQgdGhlIGdhcmJhZ2UgY29sbGVjdG9yIGFjdHMgc2ltaWxhciB0byBhIHNlY29uZAorICogdGhyZWFkIG9uIHRoaXMgY29sbGVjdGlvbiwgcG9zc2libHkgcmVtb3Zpbmcga2V5cy4KKyAqCisgKiBAc2luY2UgMS4yCisgKiBAc2VlIEhhc2hNYXAKKyAqIEBzZWUgV2Vha1JlZmVyZW5jZQorICovCitwdWJsaWMgY2xhc3MgV2Vha0hhc2hNYXA8SywgVj4gZXh0ZW5kcyBBYnN0cmFjdE1hcDxLLCBWPiBpbXBsZW1lbnRzIE1hcDxLLCBWPiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9TSVpFID0gMTY7CisKKyAgICBwcml2YXRlIGZpbmFsIFJlZmVyZW5jZVF1ZXVlPEs+IHJlZmVyZW5jZVF1ZXVlOworCisgICAgaW50IGVsZW1lbnRDb3VudDsKKworICAgIEVudHJ5PEssIFY+W10gZWxlbWVudERhdGE7CisKKyAgICBwcml2YXRlIGZpbmFsIGludCBsb2FkRmFjdG9yOworCisgICAgcHJpdmF0ZSBpbnQgdGhyZXNob2xkOworCisgICAgdm9sYXRpbGUgaW50IG1vZENvdW50OworCisgICAgLy8gU2ltcGxlIHV0aWxpdHkgbWV0aG9kIHRvIGlzb2xhdGUgdW5jaGVja2VkIGNhc3QgZm9yIGFycmF5IGNyZWF0aW9uCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHJpdmF0ZSBzdGF0aWMgPEssIFY+IEVudHJ5PEssIFY+W10gbmV3RW50cnlBcnJheShpbnQgc2l6ZSkgeworICAgICAgICByZXR1cm4gbmV3IEVudHJ5W3NpemVdOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEVudHJ5PEssIFY+IGV4dGVuZHMgV2Vha1JlZmVyZW5jZTxLPiBpbXBsZW1lbnRzCisgICAgICAgICAgICBNYXAuRW50cnk8SywgVj4geworICAgICAgICBpbnQgaGFzaDsKKworICAgICAgICBib29sZWFuIGlzTnVsbDsKKworICAgICAgICBWIHZhbHVlOworCisgICAgICAgIEVudHJ5PEssIFY+IG5leHQ7CisKKyAgICAgICAgaW50ZXJmYWNlIFR5cGU8UiwgSywgVj4geworICAgICAgICAgICAgUiBnZXQoTWFwLkVudHJ5PEssIFY+IGVudHJ5KTsKKyAgICAgICAgfQorCisgICAgICAgIEVudHJ5KEsga2V5LCBWIG9iamVjdCwgUmVmZXJlbmNlUXVldWU8Sz4gcXVldWUpIHsKKyAgICAgICAgICAgIHN1cGVyKGtleSwgcXVldWUpOworICAgICAgICAgICAgaXNOdWxsID0ga2V5ID09IG51bGw7CisgICAgICAgICAgICBoYXNoID0gaXNOdWxsID8gMCA6IGtleS5oYXNoQ29kZSgpOworICAgICAgICAgICAgdmFsdWUgPSBvYmplY3Q7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSyBnZXRLZXkoKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0KCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgViBnZXRWYWx1ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBWIHNldFZhbHVlKFYgb2JqZWN0KSB7CisgICAgICAgICAgICBWIHJlc3VsdCA9IHZhbHVlOworICAgICAgICAgICAgdmFsdWUgPSBvYmplY3Q7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKKyAgICAgICAgICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgTWFwLkVudHJ5KSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIE1hcC5FbnRyeTw/LCA/PiBlbnRyeSA9IChNYXAuRW50cnk8PywgPz4pIG90aGVyOworICAgICAgICAgICAgT2JqZWN0IGtleSA9IHN1cGVyLmdldCgpOworICAgICAgICAgICAgcmV0dXJuIChrZXkgPT0gbnVsbCA/IGtleSA9PSBlbnRyeS5nZXRLZXkoKSA6IGtleS5lcXVhbHMoZW50cnkKKyAgICAgICAgICAgICAgICAgICAgLmdldEtleSgpKSkKKyAgICAgICAgICAgICAgICAgICAgJiYgKHZhbHVlID09IG51bGwgPyB2YWx1ZSA9PSBlbnRyeS5nZXRWYWx1ZSgpIDogdmFsdWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKGVudHJ5LmdldFZhbHVlKCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgcmV0dXJuIGhhc2ggKyAodmFsdWUgPT0gbnVsbCA/IDAgOiB2YWx1ZS5oYXNoQ29kZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldCgpICsgIj0iICsgdmFsdWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBIYXNoSXRlcmF0b3I8Uj4gaW1wbGVtZW50cyBJdGVyYXRvcjxSPiB7CisgICAgICAgIHByaXZhdGUgaW50IHBvc2l0aW9uID0gMCwgZXhwZWN0ZWRNb2RDb3VudDsKKworICAgICAgICBwcml2YXRlIEVudHJ5PEssIFY+IGN1cnJlbnRFbnRyeSwgbmV4dEVudHJ5OworCisgICAgICAgIHByaXZhdGUgSyBuZXh0S2V5OworCisgICAgICAgIGZpbmFsIEVudHJ5LlR5cGU8UiwgSywgVj4gdHlwZTsKKworICAgICAgICBIYXNoSXRlcmF0b3IoRW50cnkuVHlwZTxSLCBLLCBWPiB0eXBlKSB7CisgICAgICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgICAgICAgICAgZXhwZWN0ZWRNb2RDb3VudCA9IG1vZENvdW50OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIGlmIChuZXh0RW50cnkgIT0gbnVsbCAmJiAobmV4dEtleSAhPSBudWxsIHx8IG5leHRFbnRyeS5pc051bGwpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgIGlmIChuZXh0RW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB3aGlsZSAocG9zaXRpb24gPCBlbGVtZW50RGF0YS5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICgobmV4dEVudHJ5ID0gZWxlbWVudERhdGFbcG9zaXRpb24rK10pICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAobmV4dEVudHJ5ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBlbnN1cmUga2V5IG9mIG5leHQgZW50cnkgaXMgbm90IGdjJ2VkCisgICAgICAgICAgICAgICAgbmV4dEtleSA9IG5leHRFbnRyeS5nZXQoKTsKKyAgICAgICAgICAgICAgICBpZiAobmV4dEtleSAhPSBudWxsIHx8IG5leHRFbnRyeS5pc051bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG5leHRFbnRyeSA9IG5leHRFbnRyeS5uZXh0OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFIgbmV4dCgpIHsKKyAgICAgICAgICAgIGlmIChleHBlY3RlZE1vZENvdW50ID09IG1vZENvdW50KSB7CisgICAgICAgICAgICAgICAgaWYgKGhhc05leHQoKSkgeworICAgICAgICAgICAgICAgICAgICBjdXJyZW50RW50cnkgPSBuZXh0RW50cnk7CisgICAgICAgICAgICAgICAgICAgIG5leHRFbnRyeSA9IGN1cnJlbnRFbnRyeS5uZXh0OworICAgICAgICAgICAgICAgICAgICBSIHJlc3VsdCA9IHR5cGUuZ2V0KGN1cnJlbnRFbnRyeSk7CisgICAgICAgICAgICAgICAgICAgIC8vIGZyZWUgdGhlIGtleQorICAgICAgICAgICAgICAgICAgICBuZXh0S2V5ID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICBpZiAoZXhwZWN0ZWRNb2RDb3VudCA9PSBtb2RDb3VudCkgeworICAgICAgICAgICAgICAgIGlmIChjdXJyZW50RW50cnkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZW1vdmVFbnRyeShjdXJyZW50RW50cnkpOworICAgICAgICAgICAgICAgICAgICBjdXJyZW50RW50cnkgPSBudWxsOworICAgICAgICAgICAgICAgICAgICBleHBlY3RlZE1vZENvdW50Kys7CisgICAgICAgICAgICAgICAgICAgIC8vIGNhbm5vdCBwb2xsKCkgYXMgdGhhdCB3b3VsZCBjaGFuZ2UgdGhlIGV4cGVjdGVkTW9kQ291bnQKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBlbXB0eSB7QGNvZGUgV2Vha0hhc2hNYXB9IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBXZWFrSGFzaE1hcCgpIHsKKyAgICAgICAgdGhpcyhERUZBVUxUX1NJWkUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFdlYWtIYXNoTWFwfSBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjYXBhY2l0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXBhY2l0eQorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgY2FwYWNpdHkgb2YgdGhpcyBtYXAuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiB0aGUgY2FwYWNpdHkgaXMgbGVzcyB0aGFuIHplcm8uCisgICAgICovCisgICAgcHVibGljIFdlYWtIYXNoTWFwKGludCBjYXBhY2l0eSkgeworICAgICAgICBpZiAoY2FwYWNpdHkgPj0gMCkgeworICAgICAgICAgICAgZWxlbWVudENvdW50ID0gMDsKKyAgICAgICAgICAgIGVsZW1lbnREYXRhID0gbmV3RW50cnlBcnJheShjYXBhY2l0eSA9PSAwID8gMSA6IGNhcGFjaXR5KTsKKyAgICAgICAgICAgIGxvYWRGYWN0b3IgPSA3NTAwOyAvLyBEZWZhdWx0IGxvYWQgZmFjdG9yIG9mIDAuNzUKKyAgICAgICAgICAgIGNvbXB1dGVNYXhTaXplKCk7CisgICAgICAgICAgICByZWZlcmVuY2VRdWV1ZSA9IG5ldyBSZWZlcmVuY2VRdWV1ZTxLPigpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgV2Vha0hhc2hNYXB9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBjYXBhY2l0eQorICAgICAqIGFuZCBsb2FkIGZhY3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXBhY2l0eQorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWwgY2FwYWNpdHkgb2YgdGhpcyBtYXAuCisgICAgICogQHBhcmFtIGxvYWRGYWN0b3IKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIGxvYWQgZmFjdG9yLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNhcGFjaXR5IGlzIGxlc3MgdGhhbiB6ZXJvIG9yIHRoZSBsb2FkIGZhY3RvciBpcyBsZXNzCisgICAgICogICAgICAgICAgICAgb3IgZXF1YWwgdG8gemVyby4KKyAgICAgKi8KKyAgICBwdWJsaWMgV2Vha0hhc2hNYXAoaW50IGNhcGFjaXR5LCBmbG9hdCBsb2FkRmFjdG9yKSB7CisgICAgICAgIGlmIChjYXBhY2l0eSA+PSAwICYmIGxvYWRGYWN0b3IgPiAwKSB7CisgICAgICAgICAgICBlbGVtZW50Q291bnQgPSAwOworICAgICAgICAgICAgZWxlbWVudERhdGEgPSBuZXdFbnRyeUFycmF5KGNhcGFjaXR5ID09IDAgPyAxIDogY2FwYWNpdHkpOworICAgICAgICAgICAgdGhpcy5sb2FkRmFjdG9yID0gKGludCkgKGxvYWRGYWN0b3IgKiAxMDAwMCk7CisgICAgICAgICAgICBjb21wdXRlTWF4U2l6ZSgpOworICAgICAgICAgICAgcmVmZXJlbmNlUXVldWUgPSBuZXcgUmVmZXJlbmNlUXVldWU8Sz4oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFdlYWtIYXNoTWFwfSBpbnN0YW5jZSBjb250YWluaW5nIHRoZSBtYXBwaW5ncworICAgICAqIGZyb20gdGhlIHNwZWNpZmllZCBtYXAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWFwCisgICAgICogICAgICAgICAgICB0aGUgbWFwcGluZ3MgdG8gYWRkLgorICAgICAqLworICAgIHB1YmxpYyBXZWFrSGFzaE1hcChNYXA8PyBleHRlbmRzIEssID8gZXh0ZW5kcyBWPiBtYXApIHsKKyAgICAgICAgdGhpcyhtYXAuc2l6ZSgpIDwgNiA/IDExIDogbWFwLnNpemUoKSAqIDIpOworICAgICAgICBwdXRBbGxJbXBsKG1hcCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhbGwgbWFwcGluZ3MgZnJvbSB0aGlzIG1hcCwgbGVhdmluZyBpdCBlbXB0eS4KKyAgICAgKgorICAgICAqIEBzZWUgI2lzRW1wdHkoKQorICAgICAqIEBzZWUgI3NpemUoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBpZiAoZWxlbWVudENvdW50ID4gMCkgeworICAgICAgICAgICAgZWxlbWVudENvdW50ID0gMDsKKyAgICAgICAgICAgIEFycmF5cy5maWxsKGVsZW1lbnREYXRhLCBudWxsKTsKKyAgICAgICAgICAgIG1vZENvdW50Kys7CisgICAgICAgICAgICB3aGlsZSAocmVmZXJlbmNlUXVldWUucG9sbCgpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyBkbyBub3RoaW5nCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY29tcHV0ZU1heFNpemUoKSB7CisgICAgICAgIHRocmVzaG9sZCA9IChpbnQpICgobG9uZykgZWxlbWVudERhdGEubGVuZ3RoICogbG9hZEZhY3RvciAvIDEwMDAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBtYXAgY29udGFpbnMgdGhlIHNwZWNpZmllZCBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IHRvIHNlYXJjaCBmb3IuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBtYXAgY29udGFpbnMgdGhlIHNwZWNpZmllZCBrZXksCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0tleShPYmplY3Qga2V5KSB7CisgICAgICAgIHJldHVybiBnZXRFbnRyeShrZXkpICE9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNldCBjb250YWluaW5nIGFsbCBvZiB0aGUgbWFwcGluZ3MgaW4gdGhpcyBtYXAuIEVhY2ggbWFwcGluZyBpcworICAgICAqIGFuIGluc3RhbmNlIG9mIHtAbGluayBNYXAuRW50cnl9LiBBcyB0aGUgc2V0IGlzIGJhY2tlZCBieSB0aGlzIG1hcCwKKyAgICAgKiBjaGFuZ2VzIGluIG9uZSB3aWxsIGJlIHJlZmxlY3RlZCBpbiB0aGUgb3RoZXIuIEl0IGRvZXMgbm90IHN1cHBvcnQgYWRkaW5nCisgICAgICogb3BlcmF0aW9ucy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzZXQgb2YgdGhlIG1hcHBpbmdzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTZXQ8TWFwLkVudHJ5PEssIFY+PiBlbnRyeVNldCgpIHsKKyAgICAgICAgcG9sbCgpOworICAgICAgICByZXR1cm4gbmV3IEFic3RyYWN0U2V0PE1hcC5FbnRyeTxLLCBWPj4oKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gV2Vha0hhc2hNYXAudGhpcy5zaXplKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICAgICAgV2Vha0hhc2hNYXAudGhpcy5jbGVhcigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICAgICAgaWYgKGNvbnRhaW5zKG9iamVjdCkpIHsKKyAgICAgICAgICAgICAgICAgICAgV2Vha0hhc2hNYXAudGhpcworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZW1vdmUoKChNYXAuRW50cnk8PywgPz4pIG9iamVjdCkuZ2V0S2V5KCkpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgTWFwLkVudHJ5KSB7CisgICAgICAgICAgICAgICAgICAgIEVudHJ5PD8sID8+IGVudHJ5ID0gZ2V0RW50cnkoKChNYXAuRW50cnk8PywgPz4pIG9iamVjdCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0S2V5KCkpOworICAgICAgICAgICAgICAgICAgICBpZiAoZW50cnkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IGtleSA9IGVudHJ5LmdldCgpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGtleSAhPSBudWxsIHx8IGVudHJ5LmlzTnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3QuZXF1YWxzKGVudHJ5KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIEl0ZXJhdG9yPE1hcC5FbnRyeTxLLCBWPj4gaXRlcmF0b3IoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBIYXNoSXRlcmF0b3I8TWFwLkVudHJ5PEssIFY+PigKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbnRyeS5UeXBlPE1hcC5FbnRyeTxLLCBWPiwgSywgVj4oKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIE1hcC5FbnRyeTxLLCBWPiBnZXQoTWFwLkVudHJ5PEssIFY+IGVudHJ5KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbnRyeTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc2V0IG9mIHRoZSBrZXlzIGNvbnRhaW5lZCBpbiB0aGlzIG1hcC4gVGhlIHNldCBpcyBiYWNrZWQgYnkKKyAgICAgKiB0aGlzIG1hcCBzbyBjaGFuZ2VzIHRvIG9uZSBhcmUgcmVmbGVjdGVkIGJ5IHRoZSBvdGhlci4gVGhlIHNldCBkb2VzIG5vdAorICAgICAqIHN1cHBvcnQgYWRkaW5nLgorICAgICAqCisgICAgICogQHJldHVybiBhIHNldCBvZiB0aGUga2V5cy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2V0PEs+IGtleVNldCgpIHsKKyAgICAgICAgcG9sbCgpOworICAgICAgICBpZiAoa2V5U2V0ID09IG51bGwpIHsKKyAgICAgICAgICAgIGtleVNldCA9IG5ldyBBYnN0cmFjdFNldDxLPigpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250YWluc0tleShvYmplY3QpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFdlYWtIYXNoTWFwLnRoaXMuc2l6ZSgpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICAgICAgICAgICAgICBXZWFrSGFzaE1hcC50aGlzLmNsZWFyKCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBrZXkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRhaW5zS2V5KGtleSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFdlYWtIYXNoTWFwLnRoaXMucmVtb3ZlKGtleSk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIEl0ZXJhdG9yPEs+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEhhc2hJdGVyYXRvcjxLPihuZXcgRW50cnkuVHlwZTxLLCBLLCBWPigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBLIGdldChNYXAuRW50cnk8SywgVj4gZW50cnkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW50cnkuZ2V0S2V5KCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0pOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3RbXSB0b0FycmF5KCkgeworICAgICAgICAgICAgICAgICAgICBDb2xsZWN0aW9uPEs+IGNvbGwgPSBuZXcgQXJyYXlMaXN0PEs+KHNpemUoKSk7CisKKyAgICAgICAgICAgICAgICAgICAgZm9yIChJdGVyYXRvcjxLPiBpdGVyID0gaXRlcmF0b3IoKTsgaXRlci5oYXNOZXh0KCk7KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb2xsLmFkZChpdGVyLm5leHQoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbGwudG9BcnJheSgpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyA8VD4gVFtdIHRvQXJyYXkoVFtdIGNvbnRlbnRzKSB7CisgICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb248Sz4gY29sbCA9IG5ldyBBcnJheUxpc3Q8Sz4oc2l6ZSgpKTsKKworICAgICAgICAgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yPEs+IGl0ZXIgPSBpdGVyYXRvcigpOyBpdGVyLmhhc05leHQoKTspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbGwuYWRkKGl0ZXIubmV4dCgpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29sbC50b0FycmF5KGNvbnRlbnRzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9OworICAgICAgICB9CisgICAgICAgIHJldHVybiBrZXlTZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvbGxlY3Rpb24gb2YgdGhlIHZhbHVlcyBjb250YWluZWQgaW4gdGhpcyBtYXAuIFRoZSBjb2xsZWN0aW9uCisgICAgICogaXMgYmFja2VkIGJ5IHRoaXMgbWFwIHNvIGNoYW5nZXMgdG8gb25lIGFyZSByZWZsZWN0ZWQgYnkgdGhlIG90aGVyLiBUaGUKKyAgICAgKiBjb2xsZWN0aW9uIHN1cHBvcnRzIHJlbW92ZSwgcmVtb3ZlQWxsLCByZXRhaW5BbGwgYW5kIGNsZWFyIG9wZXJhdGlvbnMsCisgICAgICogYW5kIGl0IGRvZXMgbm90IHN1cHBvcnQgYWRkIG9yIGFkZEFsbCBvcGVyYXRpb25zLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBjb2xsZWN0aW9uIHdoaWNoIGlzIHRoZSBzdWJjbGFzcyBvZgorICAgICAqIEFic3RyYWN0Q29sbGVjdGlvbi4gVGhlIGl0ZXJhdG9yIG1ldGhvZCBvZiB0aGlzIHN1YmNsYXNzIHJldHVybnMgYQorICAgICAqICJ3cmFwcGVyIG9iamVjdCIgb3ZlciB0aGUgaXRlcmF0b3Igb2YgbWFwJ3MgZW50cnlTZXQoKS4gVGhlIHNpemUgbWV0aG9kCisgICAgICogd3JhcHMgdGhlIG1hcCdzIHNpemUgbWV0aG9kIGFuZCB0aGUgY29udGFpbnMgbWV0aG9kIHdyYXBzIHRoZSBtYXAncworICAgICAqIGNvbnRhaW5zVmFsdWUgbWV0aG9kLgorICAgICAqIDxwPgorICAgICAqIFRoZSBjb2xsZWN0aW9uIGlzIGNyZWF0ZWQgd2hlbiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgYXQgZmlyc3QgdGltZSBhbmQKKyAgICAgKiByZXR1cm5lZCBpbiByZXNwb25zZSB0byBhbGwgc3Vic2VxdWVudCBjYWxscy4gVGhpcyBtZXRob2QgbWF5IHJldHVybgorICAgICAqIGRpZmZlcmVudCBDb2xsZWN0aW9uIHdoZW4gbXVsdGlwbGUgY2FsbHMgdG8gdGhpcyBtZXRob2QsIHNpbmNlIGl0IGhhcyBubworICAgICAqIHN5bmNocm9uaXphdGlvbiBwZXJmb3JtZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29sbGVjdGlvbiBvZiB0aGUgdmFsdWVzIGNvbnRhaW5lZCBpbiB0aGlzIG1hcC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ29sbGVjdGlvbjxWPiB2YWx1ZXMoKSB7CisgICAgICAgIHBvbGwoKTsKKyAgICAgICAgaWYgKHZhbHVlc0NvbGxlY3Rpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgdmFsdWVzQ29sbGVjdGlvbiA9IG5ldyBBYnN0cmFjdENvbGxlY3Rpb248Vj4oKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gV2Vha0hhc2hNYXAudGhpcy5zaXplKCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICAgICAgICAgIFdlYWtIYXNoTWFwLnRoaXMuY2xlYXIoKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250YWluc1ZhbHVlKG9iamVjdCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIEl0ZXJhdG9yPFY+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEhhc2hJdGVyYXRvcjxWPihuZXcgRW50cnkuVHlwZTxWLCBLLCBWPigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBWIGdldChNYXAuRW50cnk8SywgVj4gZW50cnkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdmFsdWVzQ29sbGVjdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgbWFwcGluZyB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleS4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgbWFwcGluZyB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LCBvciB7QGNvZGUgbnVsbH0KKyAgICAgKiAgICAgICAgIGlmIG5vIG1hcHBpbmcgZm9yIHRoZSBzcGVjaWZpZWQga2V5IGlzIGZvdW5kLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBWIGdldChPYmplY3Qga2V5KSB7CisgICAgICAgIHBvbGwoKTsKKyAgICAgICAgaWYgKGtleSAhPSBudWxsKSB7CisgICAgICAgICAgICBpbnQgaW5kZXggPSAoa2V5Lmhhc2hDb2RlKCkgJiAweDdGRkZGRkZGKSAlIGVsZW1lbnREYXRhLmxlbmd0aDsKKyAgICAgICAgICAgIEVudHJ5PEssIFY+IGVudHJ5ID0gZWxlbWVudERhdGFbaW5kZXhdOworICAgICAgICAgICAgd2hpbGUgKGVudHJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZiAoa2V5LmVxdWFscyhlbnRyeS5nZXQoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVudHJ5LnZhbHVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBFbnRyeTxLLCBWPiBlbnRyeSA9IGVsZW1lbnREYXRhWzBdOworICAgICAgICB3aGlsZSAoZW50cnkgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKGVudHJ5LmlzTnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBlbnRyeS52YWx1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVudHJ5ID0gZW50cnkubmV4dDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBFbnRyeTxLLCBWPiBnZXRFbnRyeShPYmplY3Qga2V5KSB7CisgICAgICAgIHBvbGwoKTsKKyAgICAgICAgaWYgKGtleSAhPSBudWxsKSB7CisgICAgICAgICAgICBpbnQgaW5kZXggPSAoa2V5Lmhhc2hDb2RlKCkgJiAweDdGRkZGRkZGKSAlIGVsZW1lbnREYXRhLmxlbmd0aDsKKyAgICAgICAgICAgIEVudHJ5PEssIFY+IGVudHJ5ID0gZWxlbWVudERhdGFbaW5kZXhdOworICAgICAgICAgICAgd2hpbGUgKGVudHJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZiAoa2V5LmVxdWFscyhlbnRyeS5nZXQoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVudHJ5OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBFbnRyeTxLLCBWPiBlbnRyeSA9IGVsZW1lbnREYXRhWzBdOworICAgICAgICB3aGlsZSAoZW50cnkgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKGVudHJ5LmlzTnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBlbnRyeTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVudHJ5ID0gZW50cnkubmV4dDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBtYXAgY29udGFpbnMgdGhlIHNwZWNpZmllZCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBtYXAgY29udGFpbnMgdGhlIHNwZWNpZmllZCB2YWx1ZSwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVmFsdWUoT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIHBvbGwoKTsKKyAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBlbGVtZW50RGF0YS5sZW5ndGg7IC0taSA+PSAwOykgeworICAgICAgICAgICAgICAgIEVudHJ5PEssIFY+IGVudHJ5ID0gZWxlbWVudERhdGFbaV07CisgICAgICAgICAgICAgICAgd2hpbGUgKGVudHJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgSyBrZXkgPSBlbnRyeS5nZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKChrZXkgIT0gbnVsbCB8fCBlbnRyeS5pc051bGwpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgdmFsdWUuZXF1YWxzKGVudHJ5LnZhbHVlKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZW50cnkgPSBlbnRyeS5uZXh0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBlbGVtZW50RGF0YS5sZW5ndGg7IC0taSA+PSAwOykgeworICAgICAgICAgICAgICAgIEVudHJ5PEssIFY+IGVudHJ5ID0gZWxlbWVudERhdGFbaV07CisgICAgICAgICAgICAgICAgd2hpbGUgKGVudHJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgSyBrZXkgPSBlbnRyeS5nZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKChrZXkgIT0gbnVsbCB8fCBlbnRyeS5pc051bGwpICYmIGVudHJ5LnZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGVudHJ5ID0gZW50cnkubmV4dDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIG1hcC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIG1hcC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICByZXR1cm4gc2l6ZSgpID09IDA7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgdm9pZCBwb2xsKCkgeworICAgICAgICBFbnRyeTxLLCBWPiB0b1JlbW92ZTsKKyAgICAgICAgd2hpbGUgKCh0b1JlbW92ZSA9IChFbnRyeTxLLCBWPikgcmVmZXJlbmNlUXVldWUucG9sbCgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICByZW1vdmVFbnRyeSh0b1JlbW92ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICB2b2lkIHJlbW92ZUVudHJ5KEVudHJ5PEssIFY+IHRvUmVtb3ZlKSB7CisgICAgICAgIEVudHJ5PEssIFY+IGVudHJ5LCBsYXN0ID0gbnVsbDsKKyAgICAgICAgaW50IGluZGV4ID0gKHRvUmVtb3ZlLmhhc2ggJiAweDdGRkZGRkZGKSAlIGVsZW1lbnREYXRhLmxlbmd0aDsKKyAgICAgICAgZW50cnkgPSBlbGVtZW50RGF0YVtpbmRleF07CisgICAgICAgIC8vIElnbm9yZSBxdWV1ZWQgZW50cmllcyB3aGljaCBjYW5ub3QgYmUgZm91bmQsIHRoZSB1c2VyIGNvdWxkCisgICAgICAgIC8vIGhhdmUgcmVtb3ZlZCB0aGVtIGJlZm9yZSB0aGV5IHdlcmUgcXVldWVkLCBpLmUuIHVzaW5nIGNsZWFyKCkKKyAgICAgICAgd2hpbGUgKGVudHJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmICh0b1JlbW92ZSA9PSBlbnRyeSkgeworICAgICAgICAgICAgICAgIG1vZENvdW50Kys7CisgICAgICAgICAgICAgICAgaWYgKGxhc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBlbGVtZW50RGF0YVtpbmRleF0gPSBlbnRyeS5uZXh0OworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGxhc3QubmV4dCA9IGVudHJ5Lm5leHQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsZW1lbnRDb3VudC0tOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbGFzdCA9IGVudHJ5OworICAgICAgICAgICAgZW50cnkgPSBlbnRyeS5uZXh0OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFwcyB0aGUgc3BlY2lmaWVkIGtleSB0byB0aGUgc3BlY2lmaWVkIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleS4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiBhbnkgcHJldmlvdXMgbWFwcGluZyB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IG9yCisgICAgICogICAgICAgICB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgd2FzIG5vIG1hcHBpbmcuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFYgcHV0KEsga2V5LCBWIHZhbHVlKSB7CisgICAgICAgIHBvbGwoKTsKKyAgICAgICAgaW50IGluZGV4ID0gMDsKKyAgICAgICAgRW50cnk8SywgVj4gZW50cnk7CisgICAgICAgIGlmIChrZXkgIT0gbnVsbCkgeworICAgICAgICAgICAgaW5kZXggPSAoa2V5Lmhhc2hDb2RlKCkgJiAweDdGRkZGRkZGKSAlIGVsZW1lbnREYXRhLmxlbmd0aDsKKyAgICAgICAgICAgIGVudHJ5ID0gZWxlbWVudERhdGFbaW5kZXhdOworICAgICAgICAgICAgd2hpbGUgKGVudHJ5ICE9IG51bGwgJiYgIWtleS5lcXVhbHMoZW50cnkuZ2V0KCkpKSB7CisgICAgICAgICAgICAgICAgZW50cnkgPSBlbnRyeS5uZXh0OworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZW50cnkgPSBlbGVtZW50RGF0YVswXTsKKyAgICAgICAgICAgIHdoaWxlIChlbnRyeSAhPSBudWxsICYmICFlbnRyeS5pc051bGwpIHsKKyAgICAgICAgICAgICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKKyAgICAgICAgICAgIG1vZENvdW50Kys7CisgICAgICAgICAgICBpZiAoKytlbGVtZW50Q291bnQgPiB0aHJlc2hvbGQpIHsKKyAgICAgICAgICAgICAgICByZWhhc2goKTsKKyAgICAgICAgICAgICAgICBpbmRleCA9IGtleSA9PSBudWxsID8gMCA6IChrZXkuaGFzaENvZGUoKSAmIDB4N0ZGRkZGRkYpCisgICAgICAgICAgICAgICAgICAgICAgICAlIGVsZW1lbnREYXRhLmxlbmd0aDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVudHJ5ID0gbmV3IEVudHJ5PEssIFY+KGtleSwgdmFsdWUsIHJlZmVyZW5jZVF1ZXVlKTsKKyAgICAgICAgICAgIGVudHJ5Lm5leHQgPSBlbGVtZW50RGF0YVtpbmRleF07CisgICAgICAgICAgICBlbGVtZW50RGF0YVtpbmRleF0gPSBlbnRyeTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIFYgcmVzdWx0ID0gZW50cnkudmFsdWU7CisgICAgICAgIGVudHJ5LnZhbHVlID0gdmFsdWU7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlaGFzaCgpIHsKKyAgICAgICAgaW50IGxlbmd0aCA9IGVsZW1lbnREYXRhLmxlbmd0aCAqIDI7CisgICAgICAgIGlmIChsZW5ndGggPT0gMCkgeworICAgICAgICAgICAgbGVuZ3RoID0gMTsKKyAgICAgICAgfQorICAgICAgICBFbnRyeTxLLCBWPltdIG5ld0RhdGEgPSBuZXdFbnRyeUFycmF5KGxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZWxlbWVudERhdGEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIEVudHJ5PEssIFY+IGVudHJ5ID0gZWxlbWVudERhdGFbaV07CisgICAgICAgICAgICB3aGlsZSAoZW50cnkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGludCBpbmRleCA9IGVudHJ5LmlzTnVsbCA/IDAgOiAoZW50cnkuaGFzaCAmIDB4N0ZGRkZGRkYpCisgICAgICAgICAgICAgICAgICAgICAgICAlIGxlbmd0aDsKKyAgICAgICAgICAgICAgICBFbnRyeTxLLCBWPiBuZXh0ID0gZW50cnkubmV4dDsKKyAgICAgICAgICAgICAgICBlbnRyeS5uZXh0ID0gbmV3RGF0YVtpbmRleF07CisgICAgICAgICAgICAgICAgbmV3RGF0YVtpbmRleF0gPSBlbnRyeTsKKyAgICAgICAgICAgICAgICBlbnRyeSA9IG5leHQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZWxlbWVudERhdGEgPSBuZXdEYXRhOworICAgICAgICBjb21wdXRlTWF4U2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyBhbGwgdGhlIG1hcHBpbmdzIGluIHRoZSBnaXZlbiBtYXAgdG8gdGhpcyBtYXAuIFRoZXNlIG1hcHBpbmdzIHdpbGwKKyAgICAgKiByZXBsYWNlIGFsbCBtYXBwaW5ncyB0aGF0IHRoaXMgbWFwIGhhZCBmb3IgYW55IG9mIHRoZSBrZXlzIGN1cnJlbnRseSBpbgorICAgICAqIHRoZSBnaXZlbiBtYXAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWFwCisgICAgICogICAgICAgICAgICB0aGUgbWFwIHRvIGNvcHkgbWFwcGluZ3MgZnJvbS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG1hcH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHB1dEFsbChNYXA8PyBleHRlbmRzIEssID8gZXh0ZW5kcyBWPiBtYXApIHsKKyAgICAgICAgcHV0QWxsSW1wbChtYXApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIG1hcHBpbmcgd2l0aCB0aGUgc3BlY2lmaWVkIGtleSBmcm9tIHRoaXMgbWFwLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBvZiB0aGUgbWFwcGluZyB0byByZW1vdmUuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHJlbW92ZWQgbWFwcGluZyBvciB7QGNvZGUgbnVsbH0gaWYgbm8gbWFwcGluZworICAgICAqICAgICAgICAgZm9yIHRoZSBzcGVjaWZpZWQga2V5IHdhcyBmb3VuZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgViByZW1vdmUoT2JqZWN0IGtleSkgeworICAgICAgICBwb2xsKCk7CisgICAgICAgIGludCBpbmRleCA9IDA7CisgICAgICAgIEVudHJ5PEssIFY+IGVudHJ5LCBsYXN0ID0gbnVsbDsKKyAgICAgICAgaWYgKGtleSAhPSBudWxsKSB7CisgICAgICAgICAgICBpbmRleCA9IChrZXkuaGFzaENvZGUoKSAmIDB4N0ZGRkZGRkYpICUgZWxlbWVudERhdGEubGVuZ3RoOworICAgICAgICAgICAgZW50cnkgPSBlbGVtZW50RGF0YVtpbmRleF07CisgICAgICAgICAgICB3aGlsZSAoZW50cnkgIT0gbnVsbCAmJiAha2V5LmVxdWFscyhlbnRyeS5nZXQoKSkpIHsKKyAgICAgICAgICAgICAgICBsYXN0ID0gZW50cnk7CisgICAgICAgICAgICAgICAgZW50cnkgPSBlbnRyeS5uZXh0OworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZW50cnkgPSBlbGVtZW50RGF0YVswXTsKKyAgICAgICAgICAgIHdoaWxlIChlbnRyeSAhPSBudWxsICYmICFlbnRyeS5pc051bGwpIHsKKyAgICAgICAgICAgICAgICBsYXN0ID0gZW50cnk7CisgICAgICAgICAgICAgICAgZW50cnkgPSBlbnRyeS5uZXh0OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CisgICAgICAgICAgICBtb2RDb3VudCsrOworICAgICAgICAgICAgaWYgKGxhc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGVsZW1lbnREYXRhW2luZGV4XSA9IGVudHJ5Lm5leHQ7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGxhc3QubmV4dCA9IGVudHJ5Lm5leHQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbGVtZW50Q291bnQtLTsKKyAgICAgICAgICAgIHJldHVybiBlbnRyeS52YWx1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBtYXAuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBtYXAuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICBwb2xsKCk7CisgICAgICAgIHJldHVybiBlbGVtZW50Q291bnQ7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHB1dEFsbEltcGwoTWFwPD8gZXh0ZW5kcyBLLCA/IGV4dGVuZHMgVj4gbWFwKSB7CisgICAgICAgIGlmIChtYXAuZW50cnlTZXQoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBzdXBlci5wdXRBbGwobWFwKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9BYnN0cmFjdEV4ZWN1dG9yU2VydmljZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0Fic3RyYWN0RXhlY3V0b3JTZXJ2aWNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzZmY2VjYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9BYnN0cmFjdEV4ZWN1dG9yU2VydmljZS5qYXZhCkBAIC0wLDAgKzEsMjgwIEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CitpbXBvcnQgamF2YS51dGlsLio7CisKKy8qKgorICogUHJvdmlkZXMgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbnMgb2Yge0BsaW5rIEV4ZWN1dG9yU2VydmljZX0KKyAqIGV4ZWN1dGlvbiBtZXRob2RzLiBUaGlzIGNsYXNzIGltcGxlbWVudHMgdGhlIDx0dD5zdWJtaXQ8L3R0PiwKKyAqIDx0dD5pbnZva2VBbnk8L3R0PiBhbmQgPHR0Pmludm9rZUFsbDwvdHQ+IG1ldGhvZHMgdXNpbmcgYQorICoge0BsaW5rIFJ1bm5hYmxlRnV0dXJlfSByZXR1cm5lZCBieSA8dHQ+bmV3VGFza0ZvcjwvdHQ+LCB3aGljaCBkZWZhdWx0cworICogdG8gdGhlIHtAbGluayBGdXR1cmVUYXNrfSBjbGFzcyBwcm92aWRlZCBpbiB0aGlzIHBhY2thZ2UuICBGb3IgZXhhbXBsZSwKKyAqIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiA8dHQ+c3VibWl0KFJ1bm5hYmxlKTwvdHQ+IGNyZWF0ZXMgYW4KKyAqIGFzc29jaWF0ZWQgPHR0PlJ1bm5hYmxlRnV0dXJlPC90dD4gdGhhdCBpcyBleGVjdXRlZCBhbmQKKyAqIHJldHVybmVkLiBTdWJjbGFzc2VzIG1heSBvdmVycmlkZSB0aGUgPHR0Pm5ld1Rhc2tGb3I8L3R0PiBtZXRob2RzCisgKiB0byByZXR1cm4gPHR0PlJ1bm5hYmxlRnV0dXJlPC90dD4gaW1wbGVtZW50YXRpb25zIG90aGVyIHRoYW4KKyAqIDx0dD5GdXR1cmVUYXNrPC90dD4uCisgKgorICogPHA+IDxiPkV4dGVuc2lvbiBleGFtcGxlPC9iPi4gSGVyZSBpcyBhIHNrZXRjaCBvZiBhIGNsYXNzCisgKiB0aGF0IGN1c3RvbWl6ZXMge0BsaW5rIFRocmVhZFBvb2xFeGVjdXRvcn0gdG8gdXNlCisgKiBhIDx0dD5DdXN0b21UYXNrPC90dD4gY2xhc3MgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCA8dHQ+RnV0dXJlVGFzazwvdHQ+OgorICogIDxwcmU+IHtAY29kZQorICogcHVibGljIGNsYXNzIEN1c3RvbVRocmVhZFBvb2xFeGVjdXRvciBleHRlbmRzIFRocmVhZFBvb2xFeGVjdXRvciB7CisgKgorICogICBzdGF0aWMgY2xhc3MgQ3VzdG9tVGFzazxWPiBpbXBsZW1lbnRzIFJ1bm5hYmxlRnV0dXJlPFY+IHsuLi59CisgKgorICogICBwcm90ZWN0ZWQgPFY+IFJ1bm5hYmxlRnV0dXJlPFY+IG5ld1Rhc2tGb3IoQ2FsbGFibGU8Vj4gYykgeworICogICAgICAgcmV0dXJuIG5ldyBDdXN0b21UYXNrPFY+KGMpOworICogICB9CisgKiAgIHByb3RlY3RlZCA8Vj4gUnVubmFibGVGdXR1cmU8Vj4gbmV3VGFza0ZvcihSdW5uYWJsZSByLCBWIHYpIHsKKyAqICAgICAgIHJldHVybiBuZXcgQ3VzdG9tVGFzazxWPihyLCB2KTsKKyAqICAgfQorICogICAvLyAuLi4gYWRkIGNvbnN0cnVjdG9ycywgZXRjLgorICogfX08L3ByZT4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdEV4ZWN1dG9yU2VydmljZSBpbXBsZW1lbnRzIEV4ZWN1dG9yU2VydmljZSB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgPHR0PlJ1bm5hYmxlRnV0dXJlPC90dD4gZm9yIHRoZSBnaXZlbiBydW5uYWJsZSBhbmQgZGVmYXVsdAorICAgICAqIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHJ1bm5hYmxlIHRoZSBydW5uYWJsZSB0YXNrIGJlaW5nIHdyYXBwZWQKKyAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRoZSByZXR1cm5lZCBmdXR1cmUKKyAgICAgKiBAcmV0dXJuIGEgPHR0PlJ1bm5hYmxlRnV0dXJlPC90dD4gd2hpY2ggd2hlbiBydW4gd2lsbCBydW4gdGhlCisgICAgICogdW5kZXJseWluZyBydW5uYWJsZSBhbmQgd2hpY2gsIGFzIGEgPHR0PkZ1dHVyZTwvdHQ+LCB3aWxsIHlpZWxkCisgICAgICogdGhlIGdpdmVuIHZhbHVlIGFzIGl0cyByZXN1bHQgYW5kIHByb3ZpZGUgZm9yIGNhbmNlbGxhdGlvbiBvZgorICAgICAqIHRoZSB1bmRlcmx5aW5nIHRhc2suCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHByb3RlY3RlZCA8VD4gUnVubmFibGVGdXR1cmU8VD4gbmV3VGFza0ZvcihSdW5uYWJsZSBydW5uYWJsZSwgVCB2YWx1ZSkgeworICAgICAgICByZXR1cm4gbmV3IEZ1dHVyZVRhc2s8VD4ocnVubmFibGUsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgPHR0PlJ1bm5hYmxlRnV0dXJlPC90dD4gZm9yIHRoZSBnaXZlbiBjYWxsYWJsZSB0YXNrLgorICAgICAqCisgICAgICogQHBhcmFtIGNhbGxhYmxlIHRoZSBjYWxsYWJsZSB0YXNrIGJlaW5nIHdyYXBwZWQKKyAgICAgKiBAcmV0dXJuIGEgPHR0PlJ1bm5hYmxlRnV0dXJlPC90dD4gd2hpY2ggd2hlbiBydW4gd2lsbCBjYWxsIHRoZQorICAgICAqIHVuZGVybHlpbmcgY2FsbGFibGUgYW5kIHdoaWNoLCBhcyBhIDx0dD5GdXR1cmU8L3R0Piwgd2lsbCB5aWVsZAorICAgICAqIHRoZSBjYWxsYWJsZSdzIHJlc3VsdCBhcyBpdHMgcmVzdWx0IGFuZCBwcm92aWRlIGZvcgorICAgICAqIGNhbmNlbGxhdGlvbiBvZiB0aGUgdW5kZXJseWluZyB0YXNrLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgPFQ+IFJ1bm5hYmxlRnV0dXJlPFQ+IG5ld1Rhc2tGb3IoQ2FsbGFibGU8VD4gY2FsbGFibGUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBGdXR1cmVUYXNrPFQ+KGNhbGxhYmxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIFJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgRnV0dXJlPD8+IHN1Ym1pdChSdW5uYWJsZSB0YXNrKSB7CisgICAgICAgIGlmICh0YXNrID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBSdW5uYWJsZUZ1dHVyZTxWb2lkPiBmdGFzayA9IG5ld1Rhc2tGb3IodGFzaywgbnVsbCk7CisgICAgICAgIGV4ZWN1dGUoZnRhc2spOworICAgICAgICByZXR1cm4gZnRhc2s7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgICAgICB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIDxUPiBGdXR1cmU8VD4gc3VibWl0KFJ1bm5hYmxlIHRhc2ssIFQgcmVzdWx0KSB7CisgICAgICAgIGlmICh0YXNrID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBSdW5uYWJsZUZ1dHVyZTxUPiBmdGFzayA9IG5ld1Rhc2tGb3IodGFzaywgcmVzdWx0KTsKKyAgICAgICAgZXhlY3V0ZShmdGFzayk7CisgICAgICAgIHJldHVybiBmdGFzazsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIFJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgPFQ+IEZ1dHVyZTxUPiBzdWJtaXQoQ2FsbGFibGU8VD4gdGFzaykgeworICAgICAgICBpZiAodGFzayA9PSBudWxsKSB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgUnVubmFibGVGdXR1cmU8VD4gZnRhc2sgPSBuZXdUYXNrRm9yKHRhc2spOworICAgICAgICBleGVjdXRlKGZ0YXNrKTsKKyAgICAgICAgcmV0dXJuIGZ0YXNrOworICAgIH0KKworICAgIC8qKgorICAgICAqIHRoZSBtYWluIG1lY2hhbmljcyBvZiBpbnZva2VBbnkuCisgICAgICovCisgICAgcHJpdmF0ZSA8VD4gVCBkb0ludm9rZUFueShDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDYWxsYWJsZTxUPj4gdGFza3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiB0aW1lZCwgbG9uZyBuYW5vcykKKyAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24sIFRpbWVvdXRFeGNlcHRpb24geworICAgICAgICBpZiAodGFza3MgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBpbnQgbnRhc2tzID0gdGFza3Muc2l6ZSgpOworICAgICAgICBpZiAobnRhc2tzID09IDApCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIExpc3Q8RnV0dXJlPFQ+PiBmdXR1cmVzPSBuZXcgQXJyYXlMaXN0PEZ1dHVyZTxUPj4obnRhc2tzKTsKKyAgICAgICAgRXhlY3V0b3JDb21wbGV0aW9uU2VydmljZTxUPiBlY3MgPQorICAgICAgICAgICAgbmV3IEV4ZWN1dG9yQ29tcGxldGlvblNlcnZpY2U8VD4odGhpcyk7CisKKyAgICAgICAgLy8gRm9yIGVmZmljaWVuY3ksIGVzcGVjaWFsbHkgaW4gZXhlY3V0b3JzIHdpdGggbGltaXRlZAorICAgICAgICAvLyBwYXJhbGxlbGlzbSwgY2hlY2sgdG8gc2VlIGlmIHByZXZpb3VzbHkgc3VibWl0dGVkIHRhc2tzIGFyZQorICAgICAgICAvLyBkb25lIGJlZm9yZSBzdWJtaXR0aW5nIG1vcmUgb2YgdGhlbS4gVGhpcyBpbnRlcmxlYXZpbmcKKyAgICAgICAgLy8gcGx1cyB0aGUgZXhjZXB0aW9uIG1lY2hhbmljcyBhY2NvdW50IGZvciBtZXNzaW5lc3Mgb2YgbWFpbgorICAgICAgICAvLyBsb29wLgorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBSZWNvcmQgZXhjZXB0aW9ucyBzbyB0aGF0IGlmIHdlIGZhaWwgdG8gb2J0YWluIGFueQorICAgICAgICAgICAgLy8gcmVzdWx0LCB3ZSBjYW4gdGhyb3cgdGhlIGxhc3QgZXhjZXB0aW9uIHdlIGdvdC4KKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBlZSA9IG51bGw7CisgICAgICAgICAgICBsb25nIGxhc3RUaW1lID0gdGltZWQgPyBTeXN0ZW0ubmFub1RpbWUoKSA6IDA7CisgICAgICAgICAgICBJdGVyYXRvcjw/IGV4dGVuZHMgQ2FsbGFibGU8VD4+IGl0ID0gdGFza3MuaXRlcmF0b3IoKTsKKworICAgICAgICAgICAgLy8gU3RhcnQgb25lIHRhc2sgZm9yIHN1cmU7IHRoZSByZXN0IGluY3JlbWVudGFsbHkKKyAgICAgICAgICAgIGZ1dHVyZXMuYWRkKGVjcy5zdWJtaXQoaXQubmV4dCgpKSk7CisgICAgICAgICAgICAtLW50YXNrczsKKyAgICAgICAgICAgIGludCBhY3RpdmUgPSAxOworCisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgRnV0dXJlPFQ+IGYgPSBlY3MucG9sbCgpOworICAgICAgICAgICAgICAgIGlmIChmID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG50YXNrcyA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC0tbnRhc2tzOworICAgICAgICAgICAgICAgICAgICAgICAgZnV0dXJlcy5hZGQoZWNzLnN1Ym1pdChpdC5uZXh0KCkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICsrYWN0aXZlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGFjdGl2ZSA9PSAwKQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRpbWVkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmID0gZWNzLnBvbGwobmFub3MsIFRpbWVVbml0Lk5BTk9TRUNPTkRTKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRpbWVvdXRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgbm93ID0gU3lzdGVtLm5hbm9UaW1lKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBuYW5vcyAtPSBub3cgLSBsYXN0VGltZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RUaW1lID0gbm93OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgICAgIGYgPSBlY3MudGFrZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoZiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIC0tYWN0aXZlOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGYuZ2V0KCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4ZWN1dGlvbkV4Y2VwdGlvbiBlZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGVlID0gZWV4OworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJleCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZWUgPSBuZXcgRXhlY3V0aW9uRXhjZXB0aW9uKHJleCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChlZSA9PSBudWxsKQorICAgICAgICAgICAgICAgIGVlID0gbmV3IEV4ZWN1dGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgdGhyb3cgZWU7CisKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGZvciAoRnV0dXJlPFQ+IGYgOiBmdXR1cmVzKQorICAgICAgICAgICAgICAgIGYuY2FuY2VsKHRydWUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIDxUPiBUIGludm9rZUFueShDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDYWxsYWJsZTxUPj4gdGFza3MpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBkb0ludm9rZUFueSh0YXNrcywgZmFsc2UsIDApOworICAgICAgICB9IGNhdGNoIChUaW1lb3V0RXhjZXB0aW9uIGNhbm5vdEhhcHBlbikgeworICAgICAgICAgICAgYXNzZXJ0IGZhbHNlOworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgPFQ+IFQgaW52b2tlQW55KENvbGxlY3Rpb248PyBleHRlbmRzIENhbGxhYmxlPFQ+PiB0YXNrcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24sIFRpbWVvdXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZG9JbnZva2VBbnkodGFza3MsIHRydWUsIHVuaXQudG9OYW5vcyh0aW1lb3V0KSk7CisgICAgfQorCisgICAgcHVibGljIDxUPiBMaXN0PEZ1dHVyZTxUPj4gaW52b2tlQWxsKENvbGxlY3Rpb248PyBleHRlbmRzIENhbGxhYmxlPFQ+PiB0YXNrcykKKyAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRhc2tzID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgTGlzdDxGdXR1cmU8VD4+IGZ1dHVyZXMgPSBuZXcgQXJyYXlMaXN0PEZ1dHVyZTxUPj4odGFza3Muc2l6ZSgpKTsKKyAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKENhbGxhYmxlPFQ+IHQgOiB0YXNrcykgeworICAgICAgICAgICAgICAgIFJ1bm5hYmxlRnV0dXJlPFQ+IGYgPSBuZXdUYXNrRm9yKHQpOworICAgICAgICAgICAgICAgIGZ1dHVyZXMuYWRkKGYpOworICAgICAgICAgICAgICAgIGV4ZWN1dGUoZik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKEZ1dHVyZTxUPiBmIDogZnV0dXJlcykgeworICAgICAgICAgICAgICAgIGlmICghZi5pc0RvbmUoKSkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgZi5nZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoQ2FuY2VsbGF0aW9uRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGVjdXRpb25FeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkb25lID0gdHJ1ZTsKKyAgICAgICAgICAgIHJldHVybiBmdXR1cmVzOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKCFkb25lKQorICAgICAgICAgICAgICAgIGZvciAoRnV0dXJlPFQ+IGYgOiBmdXR1cmVzKQorICAgICAgICAgICAgICAgICAgICBmLmNhbmNlbCh0cnVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyA8VD4gTGlzdDxGdXR1cmU8VD4+IGludm9rZUFsbChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDYWxsYWJsZTxUPj4gdGFza3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRhc2tzID09IG51bGwgfHwgdW5pdCA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGxvbmcgbmFub3MgPSB1bml0LnRvTmFub3ModGltZW91dCk7CisgICAgICAgIExpc3Q8RnV0dXJlPFQ+PiBmdXR1cmVzID0gbmV3IEFycmF5TGlzdDxGdXR1cmU8VD4+KHRhc2tzLnNpemUoKSk7CisgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yIChDYWxsYWJsZTxUPiB0IDogdGFza3MpCisgICAgICAgICAgICAgICAgZnV0dXJlcy5hZGQobmV3VGFza0Zvcih0KSk7CisKKyAgICAgICAgICAgIGxvbmcgbGFzdFRpbWUgPSBTeXN0ZW0ubmFub1RpbWUoKTsKKworICAgICAgICAgICAgLy8gSW50ZXJsZWF2ZSB0aW1lIGNoZWNrcyBhbmQgY2FsbHMgdG8gZXhlY3V0ZSBpbiBjYXNlCisgICAgICAgICAgICAvLyBleGVjdXRvciBkb2Vzbid0IGhhdmUgYW55L211Y2ggcGFyYWxsZWxpc20uCisgICAgICAgICAgICBJdGVyYXRvcjxGdXR1cmU8VD4+IGl0ID0gZnV0dXJlcy5pdGVyYXRvcigpOworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIGV4ZWN1dGUoKFJ1bm5hYmxlKShpdC5uZXh0KCkpKTsKKyAgICAgICAgICAgICAgICBsb25nIG5vdyA9IFN5c3RlbS5uYW5vVGltZSgpOworICAgICAgICAgICAgICAgIG5hbm9zIC09IG5vdyAtIGxhc3RUaW1lOworICAgICAgICAgICAgICAgIGxhc3RUaW1lID0gbm93OworICAgICAgICAgICAgICAgIGlmIChuYW5vcyA8PSAwKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnV0dXJlczsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZm9yIChGdXR1cmU8VD4gZiA6IGZ1dHVyZXMpIHsKKyAgICAgICAgICAgICAgICBpZiAoIWYuaXNEb25lKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5hbm9zIDw9IDApCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnV0dXJlczsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGYuZ2V0KG5hbm9zLCBUaW1lVW5pdC5OQU5PU0VDT05EUyk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENhbmNlbGxhdGlvbkV4Y2VwdGlvbiBpZ25vcmUpIHsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhlY3V0aW9uRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChUaW1lb3V0RXhjZXB0aW9uIHRvZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZ1dHVyZXM7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgbG9uZyBub3cgPSBTeXN0ZW0ubmFub1RpbWUoKTsKKyAgICAgICAgICAgICAgICAgICAgbmFub3MgLT0gbm93IC0gbGFzdFRpbWU7CisgICAgICAgICAgICAgICAgICAgIGxhc3RUaW1lID0gbm93OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGRvbmUgPSB0cnVlOworICAgICAgICAgICAgcmV0dXJuIGZ1dHVyZXM7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoIWRvbmUpCisgICAgICAgICAgICAgICAgZm9yIChGdXR1cmU8VD4gZiA6IGZ1dHVyZXMpCisgICAgICAgICAgICAgICAgICAgIGYuY2FuY2VsKHRydWUpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQXJyYXlCbG9ja2luZ1F1ZXVlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQXJyYXlCbG9ja2luZ1F1ZXVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTYyMjgzMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9BcnJheUJsb2NraW5nUXVldWUuamF2YQpAQCAtMCwwICsxLDc3NiBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLio7CitpbXBvcnQgamF2YS51dGlsLio7CisKKy8vIEJFR0lOIGFuZHJvaWQtbm90ZQorLy8gcmVtb3ZlZCBsaW5rIHRvIGNvbGxlY3Rpb25zIGZyYW1ld29yayBkb2NzCisvLyBFTkQgYW5kcm9pZC1ub3RlCisKKy8qKgorICogQSBib3VuZGVkIHtAbGlua3BsYWluIEJsb2NraW5nUXVldWUgYmxvY2tpbmcgcXVldWV9IGJhY2tlZCBieSBhbgorICogYXJyYXkuICBUaGlzIHF1ZXVlIG9yZGVycyBlbGVtZW50cyBGSUZPIChmaXJzdC1pbi1maXJzdC1vdXQpLiAgVGhlCisgKiA8ZW0+aGVhZDwvZW0+IG9mIHRoZSBxdWV1ZSBpcyB0aGF0IGVsZW1lbnQgdGhhdCBoYXMgYmVlbiBvbiB0aGUKKyAqIHF1ZXVlIHRoZSBsb25nZXN0IHRpbWUuICBUaGUgPGVtPnRhaWw8L2VtPiBvZiB0aGUgcXVldWUgaXMgdGhhdAorICogZWxlbWVudCB0aGF0IGhhcyBiZWVuIG9uIHRoZSBxdWV1ZSB0aGUgc2hvcnRlc3QgdGltZS4gTmV3IGVsZW1lbnRzCisgKiBhcmUgaW5zZXJ0ZWQgYXQgdGhlIHRhaWwgb2YgdGhlIHF1ZXVlLCBhbmQgdGhlIHF1ZXVlIHJldHJpZXZhbAorICogb3BlcmF0aW9ucyBvYnRhaW4gZWxlbWVudHMgYXQgdGhlIGhlYWQgb2YgdGhlIHF1ZXVlLgorICoKKyAqIDxwPlRoaXMgaXMgYSBjbGFzc2ljICZxdW90O2JvdW5kZWQgYnVmZmVyJnF1b3Q7LCBpbiB3aGljaCBhCisgKiBmaXhlZC1zaXplZCBhcnJheSBob2xkcyBlbGVtZW50cyBpbnNlcnRlZCBieSBwcm9kdWNlcnMgYW5kCisgKiBleHRyYWN0ZWQgYnkgY29uc3VtZXJzLiAgT25jZSBjcmVhdGVkLCB0aGUgY2FwYWNpdHkgY2Fubm90IGJlCisgKiBjaGFuZ2VkLiAgQXR0ZW1wdHMgdG8ge0Bjb2RlIHB1dH0gYW4gZWxlbWVudCBpbnRvIGEgZnVsbCBxdWV1ZQorICogd2lsbCByZXN1bHQgaW4gdGhlIG9wZXJhdGlvbiBibG9ja2luZzsgYXR0ZW1wdHMgdG8ge0Bjb2RlIHRha2V9IGFuCisgKiBlbGVtZW50IGZyb20gYW4gZW1wdHkgcXVldWUgd2lsbCBzaW1pbGFybHkgYmxvY2suCisgKgorICogPHA+VGhpcyBjbGFzcyBzdXBwb3J0cyBhbiBvcHRpb25hbCBmYWlybmVzcyBwb2xpY3kgZm9yIG9yZGVyaW5nCisgKiB3YWl0aW5nIHByb2R1Y2VyIGFuZCBjb25zdW1lciB0aHJlYWRzLiAgQnkgZGVmYXVsdCwgdGhpcyBvcmRlcmluZworICogaXMgbm90IGd1YXJhbnRlZWQuIEhvd2V2ZXIsIGEgcXVldWUgY29uc3RydWN0ZWQgd2l0aCBmYWlybmVzcyBzZXQKKyAqIHRvIHtAY29kZSB0cnVlfSBncmFudHMgdGhyZWFkcyBhY2Nlc3MgaW4gRklGTyBvcmRlci4gRmFpcm5lc3MKKyAqIGdlbmVyYWxseSBkZWNyZWFzZXMgdGhyb3VnaHB1dCBidXQgcmVkdWNlcyB2YXJpYWJpbGl0eSBhbmQgYXZvaWRzCisgKiBzdGFydmF0aW9uLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgYW5kIGl0cyBpdGVyYXRvciBpbXBsZW1lbnQgYWxsIG9mIHRoZQorICogPGVtPm9wdGlvbmFsPC9lbT4gbWV0aG9kcyBvZiB0aGUge0BsaW5rIENvbGxlY3Rpb259IGFuZCB7QGxpbmsKKyAqIEl0ZXJhdG9yfSBpbnRlcmZhY2VzLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqIEBwYXJhbSA8RT4gdGhlIHR5cGUgb2YgZWxlbWVudHMgaGVsZCBpbiB0aGlzIGNvbGxlY3Rpb24KKyAqLworcHVibGljIGNsYXNzIEFycmF5QmxvY2tpbmdRdWV1ZTxFPiBleHRlbmRzIEFic3RyYWN0UXVldWU8RT4KKyAgICAgICAgaW1wbGVtZW50cyBCbG9ja2luZ1F1ZXVlPEU+LCBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBTZXJpYWxpemF0aW9uIElELiBUaGlzIGNsYXNzIHJlbGllcyBvbiBkZWZhdWx0IHNlcmlhbGl6YXRpb24KKyAgICAgKiBldmVuIGZvciB0aGUgaXRlbXMgYXJyYXksIHdoaWNoIGlzIGRlZmF1bHQtc2VyaWFsaXplZCwgZXZlbiBpZgorICAgICAqIGl0IGlzIGVtcHR5LiBPdGhlcndpc2UgaXQgY291bGQgbm90IGJlIGRlY2xhcmVkIGZpbmFsLCB3aGljaCBpcworICAgICAqIG5lY2Vzc2FyeSBoZXJlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04MTc5MTE2MzI2NTI4OTg0MjZMOworCisgICAgLyoqIFRoZSBxdWV1ZWQgaXRlbXMgKi8KKyAgICBmaW5hbCBPYmplY3RbXSBpdGVtczsKKworICAgIC8qKiBpdGVtcyBpbmRleCBmb3IgbmV4dCB0YWtlLCBwb2xsLCBwZWVrIG9yIHJlbW92ZSAqLworICAgIGludCB0YWtlSW5kZXg7CisKKyAgICAvKiogaXRlbXMgaW5kZXggZm9yIG5leHQgcHV0LCBvZmZlciwgb3IgYWRkICovCisgICAgaW50IHB1dEluZGV4OworCisgICAgLyoqIE51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgcXVldWUgKi8KKyAgICBpbnQgY291bnQ7CisKKyAgICAvKgorICAgICAqIENvbmN1cnJlbmN5IGNvbnRyb2wgdXNlcyB0aGUgY2xhc3NpYyB0d28tY29uZGl0aW9uIGFsZ29yaXRobQorICAgICAqIGZvdW5kIGluIGFueSB0ZXh0Ym9vay4KKyAgICAgKi8KKworICAgIC8qKiBNYWluIGxvY2sgZ3VhcmRpbmcgYWxsIGFjY2VzcyAqLworICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jazsKKyAgICAvKiogQ29uZGl0aW9uIGZvciB3YWl0aW5nIHRha2VzICovCisgICAgcHJpdmF0ZSBmaW5hbCBDb25kaXRpb24gbm90RW1wdHk7CisgICAgLyoqIENvbmRpdGlvbiBmb3Igd2FpdGluZyBwdXRzICovCisgICAgcHJpdmF0ZSBmaW5hbCBDb25kaXRpb24gbm90RnVsbDsKKworICAgIC8vIEludGVybmFsIGhlbHBlciBtZXRob2RzCisKKyAgICAvKioKKyAgICAgKiBDaXJjdWxhcmx5IGluY3JlbWVudCBpLgorICAgICAqLworICAgIGZpbmFsIGludCBpbmMoaW50IGkpIHsKKyAgICAgICAgcmV0dXJuICgrK2kgPT0gaXRlbXMubGVuZ3RoKSA/IDAgOiBpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENpcmN1bGFybHkgZGVjcmVtZW50IGkuCisgICAgICovCisgICAgZmluYWwgaW50IGRlYyhpbnQgaSkgeworICAgICAgICByZXR1cm4gKChpID09IDApID8gaXRlbXMubGVuZ3RoIDogaSkgLSAxOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHN0YXRpYyA8RT4gRSBjYXN0KE9iamVjdCBpdGVtKSB7CisgICAgICAgIHJldHVybiAoRSkgaXRlbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGl0ZW0gYXQgaW5kZXggaS4KKyAgICAgKi8KKyAgICBmaW5hbCBFIGl0ZW1BdChpbnQgaSkgeworICAgICAgICByZXR1cm4gdGhpcy48RT5jYXN0KGl0ZW1zW2ldKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgYXJndW1lbnQgaXMgbnVsbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2IHRoZSBlbGVtZW50CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja05vdE51bGwoT2JqZWN0IHYpIHsKKyAgICAgICAgaWYgKHYgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgZWxlbWVudCBhdCBjdXJyZW50IHB1dCBwb3NpdGlvbiwgYWR2YW5jZXMsIGFuZCBzaWduYWxzLgorICAgICAqIENhbGwgb25seSB3aGVuIGhvbGRpbmcgbG9jay4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5zZXJ0KEUgeCkgeworICAgICAgICBpdGVtc1twdXRJbmRleF0gPSB4OworICAgICAgICBwdXRJbmRleCA9IGluYyhwdXRJbmRleCk7CisgICAgICAgICsrY291bnQ7CisgICAgICAgIG5vdEVtcHR5LnNpZ25hbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4dHJhY3RzIGVsZW1lbnQgYXQgY3VycmVudCB0YWtlIHBvc2l0aW9uLCBhZHZhbmNlcywgYW5kIHNpZ25hbHMuCisgICAgICogQ2FsbCBvbmx5IHdoZW4gaG9sZGluZyBsb2NrLgorICAgICAqLworICAgIHByaXZhdGUgRSBleHRyYWN0KCkgeworICAgICAgICBmaW5hbCBPYmplY3RbXSBpdGVtcyA9IHRoaXMuaXRlbXM7CisgICAgICAgIEUgeCA9IHRoaXMuPEU+Y2FzdChpdGVtc1t0YWtlSW5kZXhdKTsKKyAgICAgICAgaXRlbXNbdGFrZUluZGV4XSA9IG51bGw7CisgICAgICAgIHRha2VJbmRleCA9IGluYyh0YWtlSW5kZXgpOworICAgICAgICAtLWNvdW50OworICAgICAgICBub3RGdWxsLnNpZ25hbCgpOworICAgICAgICByZXR1cm4geDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWxldGVzIGl0ZW0gYXQgcG9zaXRpb24gaS4KKyAgICAgKiBVdGlsaXR5IGZvciByZW1vdmUgYW5kIGl0ZXJhdG9yLnJlbW92ZS4KKyAgICAgKiBDYWxsIG9ubHkgd2hlbiBob2xkaW5nIGxvY2suCisgICAgICovCisgICAgdm9pZCByZW1vdmVBdChpbnQgaSkgeworICAgICAgICBmaW5hbCBPYmplY3RbXSBpdGVtcyA9IHRoaXMuaXRlbXM7CisgICAgICAgIC8vIGlmIHJlbW92aW5nIGZyb250IGl0ZW0sIGp1c3QgYWR2YW5jZQorICAgICAgICBpZiAoaSA9PSB0YWtlSW5kZXgpIHsKKyAgICAgICAgICAgIGl0ZW1zW3Rha2VJbmRleF0gPSBudWxsOworICAgICAgICAgICAgdGFrZUluZGV4ID0gaW5jKHRha2VJbmRleCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBzbGlkZSBvdmVyIGFsbCBvdGhlcnMgdXAgdGhyb3VnaCBwdXRJbmRleC4KKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBpbnQgbmV4dGkgPSBpbmMoaSk7CisgICAgICAgICAgICAgICAgaWYgKG5leHRpICE9IHB1dEluZGV4KSB7CisgICAgICAgICAgICAgICAgICAgIGl0ZW1zW2ldID0gaXRlbXNbbmV4dGldOworICAgICAgICAgICAgICAgICAgICBpID0gbmV4dGk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaXRlbXNbaV0gPSBudWxsOworICAgICAgICAgICAgICAgICAgICBwdXRJbmRleCA9IGk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAtLWNvdW50OworICAgICAgICBub3RGdWxsLnNpZ25hbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4ge0Bjb2RlIEFycmF5QmxvY2tpbmdRdWV1ZX0gd2l0aCB0aGUgZ2l2ZW4gKGZpeGVkKQorICAgICAqIGNhcGFjaXR5IGFuZCBkZWZhdWx0IGFjY2VzcyBwb2xpY3kuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2FwYWNpdHkgdGhlIGNhcGFjaXR5IG9mIHRoaXMgcXVldWUKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgY2FwYWNpdHkgPCAxfQorICAgICAqLworICAgIHB1YmxpYyBBcnJheUJsb2NraW5nUXVldWUoaW50IGNhcGFjaXR5KSB7CisgICAgICAgIHRoaXMoY2FwYWNpdHksIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIHtAY29kZSBBcnJheUJsb2NraW5nUXVldWV9IHdpdGggdGhlIGdpdmVuIChmaXhlZCkKKyAgICAgKiBjYXBhY2l0eSBhbmQgdGhlIHNwZWNpZmllZCBhY2Nlc3MgcG9saWN5LgorICAgICAqCisgICAgICogQHBhcmFtIGNhcGFjaXR5IHRoZSBjYXBhY2l0eSBvZiB0aGlzIHF1ZXVlCisgICAgICogQHBhcmFtIGZhaXIgaWYge0Bjb2RlIHRydWV9IHRoZW4gcXVldWUgYWNjZXNzZXMgZm9yIHRocmVhZHMgYmxvY2tlZAorICAgICAqICAgICAgICBvbiBpbnNlcnRpb24gb3IgcmVtb3ZhbCwgYXJlIHByb2Nlc3NlZCBpbiBGSUZPIG9yZGVyOworICAgICAqICAgICAgICBpZiB7QGNvZGUgZmFsc2V9IHRoZSBhY2Nlc3Mgb3JkZXIgaXMgdW5zcGVjaWZpZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGNhcGFjaXR5IDwgMX0KKyAgICAgKi8KKyAgICBwdWJsaWMgQXJyYXlCbG9ja2luZ1F1ZXVlKGludCBjYXBhY2l0eSwgYm9vbGVhbiBmYWlyKSB7CisgICAgICAgIGlmIChjYXBhY2l0eSA8PSAwKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB0aGlzLml0ZW1zID0gbmV3IE9iamVjdFtjYXBhY2l0eV07CisgICAgICAgIGxvY2sgPSBuZXcgUmVlbnRyYW50TG9jayhmYWlyKTsKKyAgICAgICAgbm90RW1wdHkgPSBsb2NrLm5ld0NvbmRpdGlvbigpOworICAgICAgICBub3RGdWxsID0gIGxvY2submV3Q29uZGl0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiB7QGNvZGUgQXJyYXlCbG9ja2luZ1F1ZXVlfSB3aXRoIHRoZSBnaXZlbiAoZml4ZWQpCisgICAgICogY2FwYWNpdHksIHRoZSBzcGVjaWZpZWQgYWNjZXNzIHBvbGljeSBhbmQgaW5pdGlhbGx5IGNvbnRhaW5pbmcgdGhlCisgICAgICogZWxlbWVudHMgb2YgdGhlIGdpdmVuIGNvbGxlY3Rpb24sCisgICAgICogYWRkZWQgaW4gdHJhdmVyc2FsIG9yZGVyIG9mIHRoZSBjb2xsZWN0aW9uJ3MgaXRlcmF0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2FwYWNpdHkgdGhlIGNhcGFjaXR5IG9mIHRoaXMgcXVldWUKKyAgICAgKiBAcGFyYW0gZmFpciBpZiB7QGNvZGUgdHJ1ZX0gdGhlbiBxdWV1ZSBhY2Nlc3NlcyBmb3IgdGhyZWFkcyBibG9ja2VkCisgICAgICogICAgICAgIG9uIGluc2VydGlvbiBvciByZW1vdmFsLCBhcmUgcHJvY2Vzc2VkIGluIEZJRk8gb3JkZXI7CisgICAgICogICAgICAgIGlmIHtAY29kZSBmYWxzZX0gdGhlIGFjY2VzcyBvcmRlciBpcyB1bnNwZWNpZmllZC4KKyAgICAgKiBAcGFyYW0gYyB0aGUgY29sbGVjdGlvbiBvZiBlbGVtZW50cyB0byBpbml0aWFsbHkgY29udGFpbgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBjYXBhY2l0eX0gaXMgbGVzcyB0aGFuCisgICAgICogICAgICAgICB7QGNvZGUgYy5zaXplKCl9LCBvciBsZXNzIHRoYW4gMS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiBvciBhbnkKKyAgICAgKiAgICAgICAgIG9mIGl0cyBlbGVtZW50cyBhcmUgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBBcnJheUJsb2NraW5nUXVldWUoaW50IGNhcGFjaXR5LCBib29sZWFuIGZhaXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjKSB7CisgICAgICAgIHRoaXMoY2FwYWNpdHksIGZhaXIpOworCisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7IC8vIExvY2sgb25seSBmb3IgdmlzaWJpbGl0eSwgbm90IG11dHVhbCBleGNsdXNpb24KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZm9yIChFIGUgOiBjKSB7CisgICAgICAgICAgICAgICAgICAgIGNoZWNrTm90TnVsbChlKTsKKyAgICAgICAgICAgICAgICAgICAgaXRlbXNbaSsrXSA9IGU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY291bnQgPSBpOworICAgICAgICAgICAgcHV0SW5kZXggPSAoaSA9PSBjYXBhY2l0eSkgPyAwIDogaTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBhdCB0aGUgdGFpbCBvZiB0aGlzIHF1ZXVlIGlmIGl0IGlzCisgICAgICogcG9zc2libGUgdG8gZG8gc28gaW1tZWRpYXRlbHkgd2l0aG91dCBleGNlZWRpbmcgdGhlIHF1ZXVlJ3MgY2FwYWNpdHksCisgICAgICogcmV0dXJuaW5nIHtAY29kZSB0cnVlfSB1cG9uIHN1Y2Nlc3MgYW5kIHRocm93aW5nIGFuCisgICAgICoge0Bjb2RlIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbn0gaWYgdGhpcyBxdWV1ZSBpcyBmdWxsLgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gKGFzIHNwZWNpZmllZCBieSB7QGxpbmsgQ29sbGVjdGlvbiNhZGR9KQorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgcXVldWUgaXMgZnVsbAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBhZGQoRSBlKSB7CisgICAgICAgIHJldHVybiBzdXBlci5hZGQoZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgYXQgdGhlIHRhaWwgb2YgdGhpcyBxdWV1ZSBpZiBpdCBpcworICAgICAqIHBvc3NpYmxlIHRvIGRvIHNvIGltbWVkaWF0ZWx5IHdpdGhvdXQgZXhjZWVkaW5nIHRoZSBxdWV1ZSdzIGNhcGFjaXR5LAorICAgICAqIHJldHVybmluZyB7QGNvZGUgdHJ1ZX0gdXBvbiBzdWNjZXNzIGFuZCB7QGNvZGUgZmFsc2V9IGlmIHRoaXMgcXVldWUKKyAgICAgKiBpcyBmdWxsLiAgVGhpcyBtZXRob2QgaXMgZ2VuZXJhbGx5IHByZWZlcmFibGUgdG8gbWV0aG9kIHtAbGluayAjYWRkfSwKKyAgICAgKiB3aGljaCBjYW4gZmFpbCB0byBpbnNlcnQgYW4gZWxlbWVudCBvbmx5IGJ5IHRocm93aW5nIGFuIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBvZmZlcihFIGUpIHsKKyAgICAgICAgY2hlY2tOb3ROdWxsKGUpOworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGNvdW50ID09IGl0ZW1zLmxlbmd0aCkKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICBpbnNlcnQoZSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgYXQgdGhlIHRhaWwgb2YgdGhpcyBxdWV1ZSwgd2FpdGluZworICAgICAqIGZvciBzcGFjZSB0byBiZWNvbWUgYXZhaWxhYmxlIGlmIHRoZSBxdWV1ZSBpcyBmdWxsLgorICAgICAqCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIHZvaWQgcHV0KEUgZSkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tOb3ROdWxsKGUpOworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9ja0ludGVycnVwdGlibHkoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdoaWxlIChjb3VudCA9PSBpdGVtcy5sZW5ndGgpCisgICAgICAgICAgICAgICAgbm90RnVsbC5hd2FpdCgpOworICAgICAgICAgICAgaW5zZXJ0KGUpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGF0IHRoZSB0YWlsIG9mIHRoaXMgcXVldWUsIHdhaXRpbmcKKyAgICAgKiB1cCB0byB0aGUgc3BlY2lmaWVkIHdhaXQgdGltZSBmb3Igc3BhY2UgdG8gYmVjb21lIGF2YWlsYWJsZSBpZgorICAgICAqIHRoZSBxdWV1ZSBpcyBmdWxsLgorICAgICAqCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gb2ZmZXIoRSBlLCBsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisKKyAgICAgICAgY2hlY2tOb3ROdWxsKGUpOworICAgICAgICBsb25nIG5hbm9zID0gdW5pdC50b05hbm9zKHRpbWVvdXQpOworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9ja0ludGVycnVwdGlibHkoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdoaWxlIChjb3VudCA9PSBpdGVtcy5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBpZiAobmFub3MgPD0gMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIG5hbm9zID0gbm90RnVsbC5hd2FpdE5hbm9zKG5hbm9zKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGluc2VydChlKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBFIHBvbGwoKSB7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gKGNvdW50ID09IDApID8gbnVsbCA6IGV4dHJhY3QoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgRSB0YWtlKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2tJbnRlcnJ1cHRpYmx5KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3aGlsZSAoY291bnQgPT0gMCkKKyAgICAgICAgICAgICAgICBub3RFbXB0eS5hd2FpdCgpOworICAgICAgICAgICAgcmV0dXJuIGV4dHJhY3QoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgRSBwb2xsKGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgbG9uZyBuYW5vcyA9IHVuaXQudG9OYW5vcyh0aW1lb3V0KTsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2tJbnRlcnJ1cHRpYmx5KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3aGlsZSAoY291bnQgPT0gMCkgeworICAgICAgICAgICAgICAgIGlmIChuYW5vcyA8PSAwKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICBuYW5vcyA9IG5vdEVtcHR5LmF3YWl0TmFub3MobmFub3MpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGV4dHJhY3QoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgRSBwZWVrKCkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIChjb3VudCA9PSAwKSA/IG51bGwgOiBpdGVtQXQodGFrZUluZGV4KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyB0aGlzIGRvYyBjb21tZW50IGlzIG92ZXJyaWRkZW4gdG8gcmVtb3ZlIHRoZSByZWZlcmVuY2UgdG8gY29sbGVjdGlvbnMKKyAgICAvLyBncmVhdGVyIGluIHNpemUgdGhhbiBJbnRlZ2VyLk1BWF9WQUxVRQorICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIHF1ZXVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgcXVldWUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gY291bnQ7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gdGhpcyBkb2MgY29tbWVudCBpcyBhIG1vZGlmaWVkIGNvcHkgb2YgdGhlIGluaGVyaXRlZCBkb2MgY29tbWVudCwKKyAgICAvLyB3aXRob3V0IHRoZSByZWZlcmVuY2UgdG8gdW5saW1pdGVkIHF1ZXVlcy4KKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYWRkaXRpb25hbCBlbGVtZW50cyB0aGF0IHRoaXMgcXVldWUgY2FuIGlkZWFsbHkKKyAgICAgKiAoaW4gdGhlIGFic2VuY2Ugb2YgbWVtb3J5IG9yIHJlc291cmNlIGNvbnN0cmFpbnRzKSBhY2NlcHQgd2l0aG91dAorICAgICAqIGJsb2NraW5nLiBUaGlzIGlzIGFsd2F5cyBlcXVhbCB0byB0aGUgaW5pdGlhbCBjYXBhY2l0eSBvZiB0aGlzIHF1ZXVlCisgICAgICogbGVzcyB0aGUgY3VycmVudCB7QGNvZGUgc2l6ZX0gb2YgdGhpcyBxdWV1ZS4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB5b3UgPGVtPmNhbm5vdDwvZW0+IGFsd2F5cyB0ZWxsIGlmIGFuIGF0dGVtcHQgdG8gaW5zZXJ0CisgICAgICogYW4gZWxlbWVudCB3aWxsIHN1Y2NlZWQgYnkgaW5zcGVjdGluZyB7QGNvZGUgcmVtYWluaW5nQ2FwYWNpdHl9CisgICAgICogYmVjYXVzZSBpdCBtYXkgYmUgdGhlIGNhc2UgdGhhdCBhbm90aGVyIHRocmVhZCBpcyBhYm91dCB0bworICAgICAqIGluc2VydCBvciByZW1vdmUgYW4gZWxlbWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHJlbWFpbmluZ0NhcGFjaXR5KCkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGl0ZW1zLmxlbmd0aCAtIGNvdW50OworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYSBzaW5nbGUgaW5zdGFuY2Ugb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50IGZyb20gdGhpcyBxdWV1ZSwKKyAgICAgKiBpZiBpdCBpcyBwcmVzZW50LiAgTW9yZSBmb3JtYWxseSwgcmVtb3ZlcyBhbiBlbGVtZW50IHtAY29kZSBlfSBzdWNoCisgICAgICogdGhhdCB7QGNvZGUgby5lcXVhbHMoZSl9LCBpZiB0aGlzIHF1ZXVlIGNvbnRhaW5zIG9uZSBvciBtb3JlIHN1Y2gKKyAgICAgKiBlbGVtZW50cy4KKyAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGlzIHF1ZXVlIGNvbnRhaW5lZCB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKiAob3IgZXF1aXZhbGVudGx5LCBpZiB0aGlzIHF1ZXVlIGNoYW5nZWQgYXMgYSByZXN1bHQgb2YgdGhlIGNhbGwpLgorICAgICAqCisgICAgICogPHA+UmVtb3ZhbCBvZiBpbnRlcmlvciBlbGVtZW50cyBpbiBjaXJjdWxhciBhcnJheSBiYXNlZCBxdWV1ZXMKKyAgICAgKiBpcyBhbiBpbnRyaW5zaWNhbGx5IHNsb3cgYW5kIGRpc3J1cHRpdmUgb3BlcmF0aW9uLCBzbyBzaG91bGQKKyAgICAgKiBiZSB1bmRlcnRha2VuIG9ubHkgaW4gZXhjZXB0aW9uYWwgY2lyY3Vtc3RhbmNlcywgaWRlYWxseQorICAgICAqIG9ubHkgd2hlbiB0aGUgcXVldWUgaXMga25vd24gbm90IHRvIGJlIGFjY2Vzc2libGUgYnkgb3RoZXIKKyAgICAgKiB0aHJlYWRzLgorICAgICAqCisgICAgICogQHBhcmFtIG8gZWxlbWVudCB0byBiZSByZW1vdmVkIGZyb20gdGhpcyBxdWV1ZSwgaWYgcHJlc2VudAorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgcXVldWUgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3QgbykgeworICAgICAgICBpZiAobyA9PSBudWxsKSByZXR1cm4gZmFsc2U7CisgICAgICAgIGZpbmFsIE9iamVjdFtdIGl0ZW1zID0gdGhpcy5pdGVtczsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSB0YWtlSW5kZXgsIGsgPSBjb3VudDsgayA+IDA7IGkgPSBpbmMoaSksIGstLSkgeworICAgICAgICAgICAgICAgIGlmIChvLmVxdWFscyhpdGVtc1tpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQXQoaSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGlzIHF1ZXVlIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgZWxlbWVudC4KKyAgICAgKiBNb3JlIGZvcm1hbGx5LCByZXR1cm5zIHtAY29kZSB0cnVlfSBpZiBhbmQgb25seSBpZiB0aGlzIHF1ZXVlIGNvbnRhaW5zCisgICAgICogYXQgbGVhc3Qgb25lIGVsZW1lbnQge0Bjb2RlIGV9IHN1Y2ggdGhhdCB7QGNvZGUgby5lcXVhbHMoZSl9LgorICAgICAqCisgICAgICogQHBhcmFtIG8gb2JqZWN0IHRvIGJlIGNoZWNrZWQgZm9yIGNvbnRhaW5tZW50IGluIHRoaXMgcXVldWUKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHF1ZXVlIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvID09IG51bGwpIHJldHVybiBmYWxzZTsKKyAgICAgICAgZmluYWwgT2JqZWN0W10gaXRlbXMgPSB0aGlzLml0ZW1zOworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IHRha2VJbmRleCwgayA9IGNvdW50OyBrID4gMDsgaSA9IGluYyhpKSwgay0tKQorICAgICAgICAgICAgICAgIGlmIChvLmVxdWFscyhpdGVtc1tpXSkpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoaXMgcXVldWUsIGluCisgICAgICogcHJvcGVyIHNlcXVlbmNlLgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybmVkIGFycmF5IHdpbGwgYmUgInNhZmUiIGluIHRoYXQgbm8gcmVmZXJlbmNlcyB0byBpdCBhcmUKKyAgICAgKiBtYWludGFpbmVkIGJ5IHRoaXMgcXVldWUuICAoSW4gb3RoZXIgd29yZHMsIHRoaXMgbWV0aG9kIG11c3QgYWxsb2NhdGUKKyAgICAgKiBhIG5ldyBhcnJheSkuICBUaGUgY2FsbGVyIGlzIHRodXMgZnJlZSB0byBtb2RpZnkgdGhlIHJldHVybmVkIGFycmF5LgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgYWN0cyBhcyBicmlkZ2UgYmV0d2VlbiBhcnJheS1iYXNlZCBhbmQgY29sbGVjdGlvbi1iYXNlZAorICAgICAqIEFQSXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IGNvbnRhaW5pbmcgYWxsIG9mIHRoZSBlbGVtZW50cyBpbiB0aGlzIHF1ZXVlCisgICAgICovCisgICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSB7CisgICAgICAgIGZpbmFsIE9iamVjdFtdIGl0ZW1zID0gdGhpcy5pdGVtczsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmFsIGludCBjb3VudCA9IHRoaXMuY291bnQ7CisgICAgICAgICAgICBPYmplY3RbXSBhID0gbmV3IE9iamVjdFtjb3VudF07CisgICAgICAgICAgICBmb3IgKGludCBpID0gdGFrZUluZGV4LCBrID0gMDsgayA8IGNvdW50OyBpID0gaW5jKGkpLCBrKyspCisgICAgICAgICAgICAgICAgYVtrXSA9IGl0ZW1zW2ldOworICAgICAgICAgICAgcmV0dXJuIGE7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIGFsbCBvZiB0aGUgZWxlbWVudHMgaW4gdGhpcyBxdWV1ZSwgaW4KKyAgICAgKiBwcm9wZXIgc2VxdWVuY2U7IHRoZSBydW50aW1lIHR5cGUgb2YgdGhlIHJldHVybmVkIGFycmF5IGlzIHRoYXQgb2YKKyAgICAgKiB0aGUgc3BlY2lmaWVkIGFycmF5LiAgSWYgdGhlIHF1ZXVlIGZpdHMgaW4gdGhlIHNwZWNpZmllZCBhcnJheSwgaXQKKyAgICAgKiBpcyByZXR1cm5lZCB0aGVyZWluLiAgT3RoZXJ3aXNlLCBhIG5ldyBhcnJheSBpcyBhbGxvY2F0ZWQgd2l0aCB0aGUKKyAgICAgKiBydW50aW1lIHR5cGUgb2YgdGhlIHNwZWNpZmllZCBhcnJheSBhbmQgdGhlIHNpemUgb2YgdGhpcyBxdWV1ZS4KKyAgICAgKgorICAgICAqIDxwPklmIHRoaXMgcXVldWUgZml0cyBpbiB0aGUgc3BlY2lmaWVkIGFycmF5IHdpdGggcm9vbSB0byBzcGFyZQorICAgICAqIChpLmUuLCB0aGUgYXJyYXkgaGFzIG1vcmUgZWxlbWVudHMgdGhhbiB0aGlzIHF1ZXVlKSwgdGhlIGVsZW1lbnQgaW4KKyAgICAgKiB0aGUgYXJyYXkgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZSBlbmQgb2YgdGhlIHF1ZXVlIGlzIHNldCB0bworICAgICAqIHtAY29kZSBudWxsfS4KKyAgICAgKgorICAgICAqIDxwPkxpa2UgdGhlIHtAbGluayAjdG9BcnJheSgpfSBtZXRob2QsIHRoaXMgbWV0aG9kIGFjdHMgYXMgYnJpZGdlIGJldHdlZW4KKyAgICAgKiBhcnJheS1iYXNlZCBhbmQgY29sbGVjdGlvbi1iYXNlZCBBUElzLiAgRnVydGhlciwgdGhpcyBtZXRob2QgYWxsb3dzCisgICAgICogcHJlY2lzZSBjb250cm9sIG92ZXIgdGhlIHJ1bnRpbWUgdHlwZSBvZiB0aGUgb3V0cHV0IGFycmF5LCBhbmQgbWF5LAorICAgICAqIHVuZGVyIGNlcnRhaW4gY2lyY3Vtc3RhbmNlcywgYmUgdXNlZCB0byBzYXZlIGFsbG9jYXRpb24gY29zdHMuCisgICAgICoKKyAgICAgKiA8cD5TdXBwb3NlIHtAY29kZSB4fSBpcyBhIHF1ZXVlIGtub3duIHRvIGNvbnRhaW4gb25seSBzdHJpbmdzLgorICAgICAqIFRoZSBmb2xsb3dpbmcgY29kZSBjYW4gYmUgdXNlZCB0byBkdW1wIHRoZSBxdWV1ZSBpbnRvIGEgbmV3bHkKKyAgICAgKiBhbGxvY2F0ZWQgYXJyYXkgb2Yge0Bjb2RlIFN0cmluZ306CisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqICAgICBTdHJpbmdbXSB5ID0geC50b0FycmF5KG5ldyBTdHJpbmdbMF0pOzwvcHJlPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IHtAY29kZSB0b0FycmF5KG5ldyBPYmplY3RbMF0pfSBpcyBpZGVudGljYWwgaW4gZnVuY3Rpb24gdG8KKyAgICAgKiB7QGNvZGUgdG9BcnJheSgpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSBpbnRvIHdoaWNoIHRoZSBlbGVtZW50cyBvZiB0aGUgcXVldWUgYXJlIHRvCisgICAgICogICAgICAgICAgYmUgc3RvcmVkLCBpZiBpdCBpcyBiaWcgZW5vdWdoOyBvdGhlcndpc2UsIGEgbmV3IGFycmF5IG9mIHRoZQorICAgICAqICAgICAgICAgIHNhbWUgcnVudGltZSB0eXBlIGlzIGFsbG9jYXRlZCBmb3IgdGhpcyBwdXJwb3NlCisgICAgICogQHJldHVybiBhbiBhcnJheSBjb250YWluaW5nIGFsbCBvZiB0aGUgZWxlbWVudHMgaW4gdGhpcyBxdWV1ZQorICAgICAqIEB0aHJvd3MgQXJyYXlTdG9yZUV4Y2VwdGlvbiBpZiB0aGUgcnVudGltZSB0eXBlIG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkKKyAgICAgKiAgICAgICAgIGlzIG5vdCBhIHN1cGVydHlwZSBvZiB0aGUgcnVudGltZSB0eXBlIG9mIGV2ZXJ5IGVsZW1lbnQgaW4KKyAgICAgKiAgICAgICAgIHRoaXMgcXVldWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgYXJyYXkgaXMgbnVsbAorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyA8VD4gVFtdIHRvQXJyYXkoVFtdIGEpIHsKKyAgICAgICAgZmluYWwgT2JqZWN0W10gaXRlbXMgPSB0aGlzLml0ZW1zOworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgaW50IGNvdW50ID0gdGhpcy5jb3VudDsKKyAgICAgICAgICAgIGZpbmFsIGludCBsZW4gPSBhLmxlbmd0aDsKKyAgICAgICAgICAgIGlmIChsZW4gPCBjb3VudCkKKyAgICAgICAgICAgICAgICBhID0gKFRbXSlqYXZhLmxhbmcucmVmbGVjdC5BcnJheS5uZXdJbnN0YW5jZSgKKyAgICAgICAgICAgICAgICAgICAgYS5nZXRDbGFzcygpLmdldENvbXBvbmVudFR5cGUoKSwgY291bnQpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IHRha2VJbmRleCwgayA9IDA7IGsgPCBjb3VudDsgaSA9IGluYyhpKSwgaysrKQorICAgICAgICAgICAgICAgIGFba10gPSAoVCkgaXRlbXNbaV07CisgICAgICAgICAgICBpZiAobGVuID4gY291bnQpCisgICAgICAgICAgICAgICAgYVtjb3VudF0gPSBudWxsOworICAgICAgICAgICAgcmV0dXJuIGE7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBrID0gY291bnQ7CisgICAgICAgICAgICBpZiAoayA9PSAwKQorICAgICAgICAgICAgICAgIHJldHVybiAiW10iOworCisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgnWycpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IHRha2VJbmRleDsgOyBpID0gaW5jKGkpKSB7CisgICAgICAgICAgICAgICAgT2JqZWN0IGUgPSBpdGVtc1tpXTsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoZSA9PSB0aGlzID8gIih0aGlzIENvbGxlY3Rpb24pIiA6IGUpOworICAgICAgICAgICAgICAgIGlmICgtLWsgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNiLmFwcGVuZCgnXScpLnRvU3RyaW5nKCk7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCcsJykuYXBwZW5kKCcgJyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSByZW1vdmVzIGFsbCBvZiB0aGUgZWxlbWVudHMgZnJvbSB0aGlzIHF1ZXVlLgorICAgICAqIFRoZSBxdWV1ZSB3aWxsIGJlIGVtcHR5IGFmdGVyIHRoaXMgY2FsbCByZXR1cm5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBmaW5hbCBPYmplY3RbXSBpdGVtcyA9IHRoaXMuaXRlbXM7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gdGFrZUluZGV4LCBrID0gY291bnQ7IGsgPiAwOyBpID0gaW5jKGkpLCBrLS0pCisgICAgICAgICAgICAgICAgaXRlbXNbaV0gPSBudWxsOworICAgICAgICAgICAgY291bnQgPSAwOworICAgICAgICAgICAgcHV0SW5kZXggPSAwOworICAgICAgICAgICAgdGFrZUluZGV4ID0gMDsKKyAgICAgICAgICAgIG5vdEZ1bGwuc2lnbmFsQWxsKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gICAgICAgICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgICAgICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gICAgICB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIGludCBkcmFpblRvKENvbGxlY3Rpb248PyBzdXBlciBFPiBjKSB7CisgICAgICAgIGNoZWNrTm90TnVsbChjKTsKKyAgICAgICAgaWYgKGMgPT0gdGhpcykKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgZmluYWwgT2JqZWN0W10gaXRlbXMgPSB0aGlzLml0ZW1zOworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IGkgPSB0YWtlSW5kZXg7CisgICAgICAgICAgICBpbnQgbiA9IDA7CisgICAgICAgICAgICBpbnQgbWF4ID0gY291bnQ7CisgICAgICAgICAgICB3aGlsZSAobiA8IG1heCkgeworICAgICAgICAgICAgICAgIGMuYWRkKHRoaXMuPEU+Y2FzdChpdGVtc1tpXSkpOworICAgICAgICAgICAgICAgIGl0ZW1zW2ldID0gbnVsbDsKKyAgICAgICAgICAgICAgICBpID0gaW5jKGkpOworICAgICAgICAgICAgICAgICsrbjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChuID4gMCkgeworICAgICAgICAgICAgICAgIGNvdW50ID0gMDsKKyAgICAgICAgICAgICAgICBwdXRJbmRleCA9IDA7CisgICAgICAgICAgICAgICAgdGFrZUluZGV4ID0gMDsKKyAgICAgICAgICAgICAgICBub3RGdWxsLnNpZ25hbEFsbCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG47CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gICAgICAgICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgICAgICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gICAgICB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIGludCBkcmFpblRvKENvbGxlY3Rpb248PyBzdXBlciBFPiBjLCBpbnQgbWF4RWxlbWVudHMpIHsKKyAgICAgICAgY2hlY2tOb3ROdWxsKGMpOworICAgICAgICBpZiAoYyA9PSB0aGlzKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICBpZiAobWF4RWxlbWVudHMgPD0gMCkKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICBmaW5hbCBPYmplY3RbXSBpdGVtcyA9IHRoaXMuaXRlbXM7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgaSA9IHRha2VJbmRleDsKKyAgICAgICAgICAgIGludCBuID0gMDsKKyAgICAgICAgICAgIGludCBtYXggPSAobWF4RWxlbWVudHMgPCBjb3VudCkgPyBtYXhFbGVtZW50cyA6IGNvdW50OworICAgICAgICAgICAgd2hpbGUgKG4gPCBtYXgpIHsKKyAgICAgICAgICAgICAgICBjLmFkZCh0aGlzLjxFPmNhc3QoaXRlbXNbaV0pKTsKKyAgICAgICAgICAgICAgICBpdGVtc1tpXSA9IG51bGw7CisgICAgICAgICAgICAgICAgaSA9IGluYyhpKTsKKyAgICAgICAgICAgICAgICArK247CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobiA+IDApIHsKKyAgICAgICAgICAgICAgICBjb3VudCAtPSBuOworICAgICAgICAgICAgICAgIHRha2VJbmRleCA9IGk7CisgICAgICAgICAgICAgICAgbm90RnVsbC5zaWduYWxBbGwoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMgaW4gdGhpcyBxdWV1ZSBpbiBwcm9wZXIgc2VxdWVuY2UuCisgICAgICogVGhlIGVsZW1lbnRzIHdpbGwgYmUgcmV0dXJuZWQgaW4gb3JkZXIgZnJvbSBmaXJzdCAoaGVhZCkgdG8gbGFzdCAodGFpbCkuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQge0Bjb2RlIEl0ZXJhdG9yfSBpcyBhICJ3ZWFrbHkgY29uc2lzdGVudCIgaXRlcmF0b3IgdGhhdAorICAgICAqIHdpbGwgbmV2ZXIgdGhyb3cge0BsaW5rIGphdmEudXRpbC5Db25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uCisgICAgICogQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0sCisgICAgICogYW5kIGd1YXJhbnRlZXMgdG8gdHJhdmVyc2UgZWxlbWVudHMgYXMgdGhleSBleGlzdGVkIHVwb24KKyAgICAgKiBjb25zdHJ1Y3Rpb24gb2YgdGhlIGl0ZXJhdG9yLCBhbmQgbWF5IChidXQgaXMgbm90IGd1YXJhbnRlZWQgdG8pCisgICAgICogcmVmbGVjdCBhbnkgbW9kaWZpY2F0aW9ucyBzdWJzZXF1ZW50IHRvIGNvbnN0cnVjdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMgaW4gdGhpcyBxdWV1ZSBpbiBwcm9wZXIgc2VxdWVuY2UKKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3I8RT4gaXRlcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBuZXcgSXRyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXRlcmF0b3IgZm9yIEFycmF5QmxvY2tpbmdRdWV1ZS4gVG8gbWFpbnRhaW4gd2VhayBjb25zaXN0ZW5jeQorICAgICAqIHdpdGggcmVzcGVjdCB0byBwdXRzIGFuZCB0YWtlcywgd2UgKDEpIHJlYWQgYWhlYWQgb25lIHNsb3QsIHNvCisgICAgICogYXMgdG8gbm90IHJlcG9ydCBoYXNOZXh0IHRydWUgYnV0IHRoZW4gbm90IGhhdmUgYW4gZWxlbWVudCB0bworICAgICAqIHJldHVybiAtLSBob3dldmVyIHdlIGxhdGVyIHJlY2hlY2sgdGhpcyBzbG90IHRvIHVzZSB0aGUgbW9zdAorICAgICAqIGN1cnJlbnQgdmFsdWU7ICgyKSBlbnN1cmUgdGhhdCBlYWNoIGFycmF5IHNsb3QgaXMgdHJhdmVyc2VkIGF0CisgICAgICogbW9zdCBvbmNlIChieSB0cmFja2luZyAicmVtYWluaW5nIiBlbGVtZW50cyk7ICgzKSBza2lwIG92ZXIKKyAgICAgKiBudWxsIHNsb3RzLCB3aGljaCBjYW4gb2NjdXIgaWYgdGFrZXMgcmFjZSBhaGVhZCBvZiBpdGVyYXRvcnMuCisgICAgICogSG93ZXZlciwgZm9yIGNpcmN1bGFyIGFycmF5LWJhc2VkIHF1ZXVlcywgd2UgY2Fubm90IHJlbHkgb24gYW55CisgICAgICogd2VsbCBlc3RhYmxpc2hlZCBkZWZpbml0aW9uIG9mIHdoYXQgaXQgbWVhbnMgdG8gYmUgd2Vha2x5CisgICAgICogY29uc2lzdGVudCB3aXRoIHJlc3BlY3QgdG8gaW50ZXJpb3IgcmVtb3ZlcyBzaW5jZSB0aGVzZSBtYXkKKyAgICAgKiByZXF1aXJlIHNsb3Qgb3ZlcndyaXRlcyBpbiB0aGUgcHJvY2VzcyBvZiBzbGlkaW5nIGVsZW1lbnRzIHRvCisgICAgICogY292ZXIgZ2Fwcy4gU28gd2Ugc2V0dGxlIGZvciByZXNpbGllbmN5LCBvcGVyYXRpbmcgb24KKyAgICAgKiBlc3RhYmxpc2hlZCBhcHBhcmVudCBuZXh0cywgd2hpY2ggbWF5IG1pc3Mgc29tZSBlbGVtZW50cyB0aGF0CisgICAgICogaGF2ZSBtb3ZlZCBiZXR3ZWVuIGNhbGxzIHRvIG5leHQuCisgICAgICovCisgICAgcHJpdmF0ZSBjbGFzcyBJdHIgaW1wbGVtZW50cyBJdGVyYXRvcjxFPiB7CisgICAgICAgIHByaXZhdGUgaW50IHJlbWFpbmluZzsgLy8gTnVtYmVyIG9mIGVsZW1lbnRzIHlldCB0byBiZSByZXR1cm5lZAorICAgICAgICBwcml2YXRlIGludCBuZXh0SW5kZXg7IC8vIEluZGV4IG9mIGVsZW1lbnQgdG8gYmUgcmV0dXJuZWQgYnkgbmV4dAorICAgICAgICBwcml2YXRlIEUgbmV4dEl0ZW07ICAgIC8vIEVsZW1lbnQgdG8gYmUgcmV0dXJuZWQgYnkgbmV4dCBjYWxsIHRvIG5leHQKKyAgICAgICAgcHJpdmF0ZSBFIGxhc3RJdGVtOyAgICAvLyBFbGVtZW50IHJldHVybmVkIGJ5IGxhc3QgY2FsbCB0byBuZXh0CisgICAgICAgIHByaXZhdGUgaW50IGxhc3RSZXQ7ICAgLy8gSW5kZXggb2YgbGFzdCBlbGVtZW50IHJldHVybmVkLCBvciAtMSBpZiBub25lCisKKyAgICAgICAgSXRyKCkgeworICAgICAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gQXJyYXlCbG9ja2luZ1F1ZXVlLnRoaXMubG9jazsKKyAgICAgICAgICAgIGxvY2subG9jaygpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBsYXN0UmV0ID0gLTE7CisgICAgICAgICAgICAgICAgaWYgKChyZW1haW5pbmcgPSBjb3VudCkgPiAwKQorICAgICAgICAgICAgICAgICAgICBuZXh0SXRlbSA9IGl0ZW1BdChuZXh0SW5kZXggPSB0YWtlSW5kZXgpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiByZW1haW5pbmcgPiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEUgbmV4dCgpIHsKKyAgICAgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IEFycmF5QmxvY2tpbmdRdWV1ZS50aGlzLmxvY2s7CisgICAgICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKHJlbWFpbmluZyA8PSAwKQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIGxhc3RSZXQgPSBuZXh0SW5kZXg7CisgICAgICAgICAgICAgICAgRSB4ID0gaXRlbUF0KG5leHRJbmRleCk7ICAvLyBjaGVjayBmb3IgZnJlc2hlciB2YWx1ZQorICAgICAgICAgICAgICAgIGlmICh4ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgeCA9IG5leHRJdGVtOyAgICAgICAgIC8vIHdlIGFyZSBmb3JjZWQgdG8gcmVwb3J0IG9sZCB2YWx1ZQorICAgICAgICAgICAgICAgICAgICBsYXN0SXRlbSA9IG51bGw7ICAgICAgLy8gYnV0IGVuc3VyZSByZW1vdmUgZmFpbHMKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBsYXN0SXRlbSA9IHg7CisgICAgICAgICAgICAgICAgd2hpbGUgKC0tcmVtYWluaW5nID4gMCAmJiAvLyBza2lwIG92ZXIgbnVsbHMKKyAgICAgICAgICAgICAgICAgICAgICAgKG5leHRJdGVtID0gaXRlbUF0KG5leHRJbmRleCA9IGluYyhuZXh0SW5kZXgpKSkgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgOworICAgICAgICAgICAgICAgIHJldHVybiB4OworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gQXJyYXlCbG9ja2luZ1F1ZXVlLnRoaXMubG9jazsKKyAgICAgICAgICAgIGxvY2subG9jaygpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpbnQgaSA9IGxhc3RSZXQ7CisgICAgICAgICAgICAgICAgaWYgKGkgPT0gLTEpCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICBsYXN0UmV0ID0gLTE7CisgICAgICAgICAgICAgICAgRSB4ID0gbGFzdEl0ZW07CisgICAgICAgICAgICAgICAgbGFzdEl0ZW0gPSBudWxsOworICAgICAgICAgICAgICAgIC8vIG9ubHkgcmVtb3ZlIGlmIGl0ZW0gc3RpbGwgYXQgaW5kZXgKKyAgICAgICAgICAgICAgICBpZiAoeCAhPSBudWxsICYmIHggPT0gaXRlbXNbaV0pIHsKKyAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiByZW1vdmluZ0hlYWQgPSAoaSA9PSB0YWtlSW5kZXgpOworICAgICAgICAgICAgICAgICAgICByZW1vdmVBdChpKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFyZW1vdmluZ0hlYWQpCisgICAgICAgICAgICAgICAgICAgICAgICBuZXh0SW5kZXggPSBkZWMobmV4dEluZGV4KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9CbG9ja2luZ0RlcXVlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQmxvY2tpbmdEZXF1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEzNmRmOWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQmxvY2tpbmdEZXF1ZS5qYXZhCkBAIC0wLDAgKzEsNjEzIEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CitpbXBvcnQgamF2YS51dGlsLio7CisKKy8qKgorICogQSB7QGxpbmsgRGVxdWV9IHRoYXQgYWRkaXRpb25hbGx5IHN1cHBvcnRzIGJsb2NraW5nIG9wZXJhdGlvbnMgdGhhdCB3YWl0CisgKiBmb3IgdGhlIGRlcXVlIHRvIGJlY29tZSBub24tZW1wdHkgd2hlbiByZXRyaWV2aW5nIGFuIGVsZW1lbnQsIGFuZCB3YWl0IGZvcgorICogc3BhY2UgdG8gYmVjb21lIGF2YWlsYWJsZSBpbiB0aGUgZGVxdWUgd2hlbiBzdG9yaW5nIGFuIGVsZW1lbnQuCisgKgorICogPHA+PHR0PkJsb2NraW5nRGVxdWU8L3R0PiBtZXRob2RzIGNvbWUgaW4gZm91ciBmb3Jtcywgd2l0aCBkaWZmZXJlbnQgd2F5cworICogb2YgaGFuZGxpbmcgb3BlcmF0aW9ucyB0aGF0IGNhbm5vdCBiZSBzYXRpc2ZpZWQgaW1tZWRpYXRlbHksIGJ1dCBtYXkgYmUKKyAqIHNhdGlzZmllZCBhdCBzb21lIHBvaW50IGluIHRoZSBmdXR1cmU6CisgKiBvbmUgdGhyb3dzIGFuIGV4Y2VwdGlvbiwgdGhlIHNlY29uZCByZXR1cm5zIGEgc3BlY2lhbCB2YWx1ZSAoZWl0aGVyCisgKiA8dHQ+bnVsbDwvdHQ+IG9yIDx0dD5mYWxzZTwvdHQ+LCBkZXBlbmRpbmcgb24gdGhlIG9wZXJhdGlvbiksIHRoZSB0aGlyZAorICogYmxvY2tzIHRoZSBjdXJyZW50IHRocmVhZCBpbmRlZmluaXRlbHkgdW50aWwgdGhlIG9wZXJhdGlvbiBjYW4gc3VjY2VlZCwKKyAqIGFuZCB0aGUgZm91cnRoIGJsb2NrcyBmb3Igb25seSBhIGdpdmVuIG1heGltdW0gdGltZSBsaW1pdCBiZWZvcmUgZ2l2aW5nCisgKiB1cC4gIFRoZXNlIG1ldGhvZHMgYXJlIHN1bW1hcml6ZWQgaW4gdGhlIGZvbGxvd2luZyB0YWJsZToKKyAqCisgKiA8cD4KKyAqIDx0YWJsZSBCT1JERVIgQ0VMTFBBRERJTkc9MyBDRUxMU1BBQ0lORz0xPgorICogIDx0cj4KKyAqICAgIDx0ZCBBTElHTj1DRU5URVIgQ09MU1BBTiA9IDU+IDxiPkZpcnN0IEVsZW1lbnQgKEhlYWQpPC9iPjwvdGQ+CisgKiAgPC90cj4KKyAqICA8dHI+CisgKiAgICA8dGQ+PC90ZD4KKyAqICAgIDx0ZCBBTElHTj1DRU5URVI+PGVtPlRocm93cyBleGNlcHRpb248L2VtPjwvdGQ+CisgKiAgICA8dGQgQUxJR049Q0VOVEVSPjxlbT5TcGVjaWFsIHZhbHVlPC9lbT48L3RkPgorICogICAgPHRkIEFMSUdOPUNFTlRFUj48ZW0+QmxvY2tzPC9lbT48L3RkPgorICogICAgPHRkIEFMSUdOPUNFTlRFUj48ZW0+VGltZXMgb3V0PC9lbT48L3RkPgorICogIDwvdHI+CisgKiAgPHRyPgorICogICAgPHRkPjxiPkluc2VydDwvYj48L3RkPgorICogICAgPHRkPntAbGluayAjYWRkRmlyc3QgYWRkRmlyc3QoZSl9PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI29mZmVyRmlyc3Qgb2ZmZXJGaXJzdChlKX08L3RkPgorICogICAgPHRkPntAbGluayAjcHV0Rmlyc3QgcHV0Rmlyc3QoZSl9PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI29mZmVyRmlyc3Qgb2ZmZXJGaXJzdChlLCB0aW1lLCB1bml0KX08L3RkPgorICogIDwvdHI+CisgKiAgPHRyPgorICogICAgPHRkPjxiPlJlbW92ZTwvYj48L3RkPgorICogICAgPHRkPntAbGluayAjcmVtb3ZlRmlyc3QgcmVtb3ZlRmlyc3QoKX08L3RkPgorICogICAgPHRkPntAbGluayAjcG9sbEZpcnN0IHBvbGxGaXJzdCgpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICN0YWtlRmlyc3QgdGFrZUZpcnN0KCl9PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI3BvbGxGaXJzdChsb25nLCBUaW1lVW5pdCkgcG9sbEZpcnN0KHRpbWUsIHVuaXQpfTwvdGQ+CisgKiAgPC90cj4KKyAqICA8dHI+CisgKiAgICA8dGQ+PGI+RXhhbWluZTwvYj48L3RkPgorICogICAgPHRkPntAbGluayAjZ2V0Rmlyc3QgZ2V0Rmlyc3QoKX08L3RkPgorICogICAgPHRkPntAbGluayAjcGVla0ZpcnN0IHBlZWtGaXJzdCgpfTwvdGQ+CisgKiAgICA8dGQ+PGVtPm5vdCBhcHBsaWNhYmxlPC9lbT48L3RkPgorICogICAgPHRkPjxlbT5ub3QgYXBwbGljYWJsZTwvZW0+PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZCBBTElHTj1DRU5URVIgQ09MU1BBTiA9IDU+IDxiPkxhc3QgRWxlbWVudCAoVGFpbCk8L2I+PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZD48L3RkPgorICogICAgPHRkIEFMSUdOPUNFTlRFUj48ZW0+VGhyb3dzIGV4Y2VwdGlvbjwvZW0+PC90ZD4KKyAqICAgIDx0ZCBBTElHTj1DRU5URVI+PGVtPlNwZWNpYWwgdmFsdWU8L2VtPjwvdGQ+CisgKiAgICA8dGQgQUxJR049Q0VOVEVSPjxlbT5CbG9ja3M8L2VtPjwvdGQ+CisgKiAgICA8dGQgQUxJR049Q0VOVEVSPjxlbT5UaW1lcyBvdXQ8L2VtPjwvdGQ+CisgKiAgPC90cj4KKyAqICA8dHI+CisgKiAgICA8dGQ+PGI+SW5zZXJ0PC9iPjwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNhZGRMYXN0IGFkZExhc3QoZSl9PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI29mZmVyTGFzdCBvZmZlckxhc3QoZSl9PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI3B1dExhc3QgcHV0TGFzdChlKX08L3RkPgorICogICAgPHRkPntAbGluayAjb2ZmZXJMYXN0IG9mZmVyTGFzdChlLCB0aW1lLCB1bml0KX08L3RkPgorICogIDwvdHI+CisgKiAgPHRyPgorICogICAgPHRkPjxiPlJlbW92ZTwvYj48L3RkPgorICogICAgPHRkPntAbGluayAjcmVtb3ZlTGFzdCgpIHJlbW92ZUxhc3QoKX08L3RkPgorICogICAgPHRkPntAbGluayAjcG9sbExhc3QoKSBwb2xsTGFzdCgpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICN0YWtlTGFzdCB0YWtlTGFzdCgpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNwb2xsTGFzdChsb25nLCBUaW1lVW5pdCkgcG9sbExhc3QodGltZSwgdW5pdCl9PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZD48Yj5FeGFtaW5lPC9iPjwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNnZXRMYXN0IGdldExhc3QoKX08L3RkPgorICogICAgPHRkPntAbGluayAjcGVla0xhc3QgcGVla0xhc3QoKX08L3RkPgorICogICAgPHRkPjxlbT5ub3QgYXBwbGljYWJsZTwvZW0+PC90ZD4KKyAqICAgIDx0ZD48ZW0+bm90IGFwcGxpY2FibGU8L2VtPjwvdGQ+CisgKiAgPC90cj4KKyAqIDwvdGFibGU+CisgKgorICogPHA+TGlrZSBhbnkge0BsaW5rIEJsb2NraW5nUXVldWV9LCBhIDx0dD5CbG9ja2luZ0RlcXVlPC90dD4gaXMgdGhyZWFkIHNhZmUsCisgKiBkb2VzIG5vdCBwZXJtaXQgbnVsbCBlbGVtZW50cywgYW5kIG1heSAob3IgbWF5IG5vdCkgYmUKKyAqIGNhcGFjaXR5LWNvbnN0cmFpbmVkLgorICoKKyAqIDxwPkEgPHR0PkJsb2NraW5nRGVxdWU8L3R0PiBpbXBsZW1lbnRhdGlvbiBtYXkgYmUgdXNlZCBkaXJlY3RseSBhcyBhIEZJRk8KKyAqIDx0dD5CbG9ja2luZ1F1ZXVlPC90dD4uIFRoZSBtZXRob2RzIGluaGVyaXRlZCBmcm9tIHRoZQorICogPHR0PkJsb2NraW5nUXVldWU8L3R0PiBpbnRlcmZhY2UgYXJlIHByZWNpc2VseSBlcXVpdmFsZW50IHRvCisgKiA8dHQ+QmxvY2tpbmdEZXF1ZTwvdHQ+IG1ldGhvZHMgYXMgaW5kaWNhdGVkIGluIHRoZSBmb2xsb3dpbmcgdGFibGU6CisgKgorICogPHA+CisgKiA8dGFibGUgQk9SREVSIENFTExQQURESU5HPTMgQ0VMTFNQQUNJTkc9MT4KKyAqICA8dHI+CisgKiAgICA8dGQgQUxJR049Q0VOVEVSPiA8Yj48dHQ+QmxvY2tpbmdRdWV1ZTwvdHQ+IE1ldGhvZDwvYj48L3RkPgorICogICAgPHRkIEFMSUdOPUNFTlRFUj4gPGI+RXF1aXZhbGVudCA8dHQ+QmxvY2tpbmdEZXF1ZTwvdHQ+IE1ldGhvZDwvYj48L3RkPgorICogIDwvdHI+CisgKiAgPHRyPgorICogICAgPHRkIEFMSUdOPUNFTlRFUiBDT0xTUEFOID0gMj4gPGI+SW5zZXJ0PC9iPjwvdGQ+CisgKiAgPC90cj4KKyAqICA8dHI+CisgKiAgICA8dGQ+e0BsaW5rICNhZGQgYWRkKGUpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNhZGRMYXN0IGFkZExhc3QoZSl9PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZD57QGxpbmsgI29mZmVyIG9mZmVyKGUpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNvZmZlckxhc3Qgb2ZmZXJMYXN0KGUpfTwvdGQ+CisgKiAgPC90cj4KKyAqICA8dHI+CisgKiAgICA8dGQ+e0BsaW5rICNwdXQgcHV0KGUpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNwdXRMYXN0IHB1dExhc3QoZSl9PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZD57QGxpbmsgI29mZmVyIG9mZmVyKGUsIHRpbWUsIHVuaXQpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNvZmZlckxhc3Qgb2ZmZXJMYXN0KGUsIHRpbWUsIHVuaXQpfTwvdGQ+CisgKiAgPC90cj4KKyAqICA8dHI+CisgKiAgICA8dGQgQUxJR049Q0VOVEVSIENPTFNQQU4gPSAyPiA8Yj5SZW1vdmU8L2I+PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZD57QGxpbmsgI3JlbW92ZSgpIHJlbW92ZSgpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNyZW1vdmVGaXJzdCgpIHJlbW92ZUZpcnN0KCl9PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZD57QGxpbmsgI3BvbGwoKSBwb2xsKCl9PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI3BvbGxGaXJzdCgpIHBvbGxGaXJzdCgpfTwvdGQ+CisgKiAgPC90cj4KKyAqICA8dHI+CisgKiAgICA8dGQ+e0BsaW5rICN0YWtlKCkgdGFrZSgpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICN0YWtlRmlyc3QoKSB0YWtlRmlyc3QoKX08L3RkPgorICogIDwvdHI+CisgKiAgPHRyPgorICogICAgPHRkPntAbGluayAjcG9sbChsb25nLCBUaW1lVW5pdCkgcG9sbCh0aW1lLCB1bml0KX08L3RkPgorICogICAgPHRkPntAbGluayAjcG9sbEZpcnN0KGxvbmcsIFRpbWVVbml0KSBwb2xsRmlyc3QodGltZSwgdW5pdCl9PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZCBBTElHTj1DRU5URVIgQ09MU1BBTiA9IDI+IDxiPkV4YW1pbmU8L2I+PC90ZD4KKyAqICA8L3RyPgorICogIDx0cj4KKyAqICAgIDx0ZD57QGxpbmsgI2VsZW1lbnQoKSBlbGVtZW50KCl9PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI2dldEZpcnN0KCkgZ2V0Rmlyc3QoKX08L3RkPgorICogIDwvdHI+CisgKiAgPHRyPgorICogICAgPHRkPntAbGluayAjcGVlaygpIHBlZWsoKX08L3RkPgorICogICAgPHRkPntAbGluayAjcGVla0ZpcnN0KCkgcGVla0ZpcnN0KCl9PC90ZD4KKyAqICA8L3RyPgorICogPC90YWJsZT4KKyAqCisgKiA8cD5NZW1vcnkgY29uc2lzdGVuY3kgZWZmZWN0czogQXMgd2l0aCBvdGhlciBjb25jdXJyZW50CisgKiBjb2xsZWN0aW9ucywgYWN0aW9ucyBpbiBhIHRocmVhZCBwcmlvciB0byBwbGFjaW5nIGFuIG9iamVjdCBpbnRvIGEKKyAqIHtAY29kZSBCbG9ja2luZ0RlcXVlfQorICogPGEgaHJlZj0icGFja2FnZS1zdW1tYXJ5Lmh0bWwjTWVtb3J5VmlzaWJpbGl0eSI+PGk+aGFwcGVuLWJlZm9yZTwvaT48L2E+CisgKiBhY3Rpb25zIHN1YnNlcXVlbnQgdG8gdGhlIGFjY2VzcyBvciByZW1vdmFsIG9mIHRoYXQgZWxlbWVudCBmcm9tCisgKiB0aGUge0Bjb2RlIEJsb2NraW5nRGVxdWV9IGluIGFub3RoZXIgdGhyZWFkLgorICoKKyAqIDxwPlRoaXMgaW50ZXJmYWNlIGlzIGEgbWVtYmVyIG9mIHRoZQorICogPGEgaHJlZj0ie0Bkb2NSb290fS8uLi90ZWNobm90ZXMvZ3VpZGVzL2NvbGxlY3Rpb25zL2luZGV4Lmh0bWwiPgorICogSmF2YSBDb2xsZWN0aW9ucyBGcmFtZXdvcms8L2E+LgorICoKKyAqIEBzaW5jZSAxLjYKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqIEBwYXJhbSA8RT4gdGhlIHR5cGUgb2YgZWxlbWVudHMgaGVsZCBpbiB0aGlzIGNvbGxlY3Rpb24KKyAqLworcHVibGljIGludGVyZmFjZSBCbG9ja2luZ0RlcXVlPEU+IGV4dGVuZHMgQmxvY2tpbmdRdWV1ZTxFPiwgRGVxdWU8RT4geworICAgIC8qCisgICAgICogV2UgaGF2ZSAiZGlhbW9uZCIgbXVsdGlwbGUgaW50ZXJmYWNlIGluaGVyaXRhbmNlIGhlcmUsIGFuZCB0aGF0CisgICAgICogaW50cm9kdWNlcyBhbWJpZ3VpdGllcy4gIE1ldGhvZHMgbWlnaHQgZW5kIHVwIHdpdGggZGlmZmVyZW50CisgICAgICogc3BlY3MgZGVwZW5kaW5nIG9uIHRoZSBicmFuY2ggY2hvc2VuIGJ5IGphdmFkb2MuICBUaHVzIGEgbG90IG9mCisgICAgICogbWV0aG9kcyBzcGVjcyBoZXJlIGFyZSBjb3BpZWQgZnJvbSBzdXBlcmludGVyZmFjZXMuCisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBhdCB0aGUgZnJvbnQgb2YgdGhpcyBkZXF1ZSBpZiBpdCBpcworICAgICAqIHBvc3NpYmxlIHRvIGRvIHNvIGltbWVkaWF0ZWx5IHdpdGhvdXQgdmlvbGF0aW5nIGNhcGFjaXR5IHJlc3RyaWN0aW9ucywKKyAgICAgKiB0aHJvd2luZyBhbiA8dHQ+SWxsZWdhbFN0YXRlRXhjZXB0aW9uPC90dD4gaWYgbm8gc3BhY2UgaXMgY3VycmVudGx5CisgICAgICogYXZhaWxhYmxlLiAgV2hlbiB1c2luZyBhIGNhcGFjaXR5LXJlc3RyaWN0ZWQgZGVxdWUsIGl0IGlzIGdlbmVyYWxseQorICAgICAqIHByZWZlcmFibGUgdG8gdXNlIHtAbGluayAjb2ZmZXJGaXJzdCBvZmZlckZpcnN0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIHRoZSBlbGVtZW50IHRvIGFkZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICB2b2lkIGFkZEZpcnN0KEUgZSk7CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBhdCB0aGUgZW5kIG9mIHRoaXMgZGVxdWUgaWYgaXQgaXMKKyAgICAgKiBwb3NzaWJsZSB0byBkbyBzbyBpbW1lZGlhdGVseSB3aXRob3V0IHZpb2xhdGluZyBjYXBhY2l0eSByZXN0cmljdGlvbnMsCisgICAgICogdGhyb3dpbmcgYW4gPHR0PklsbGVnYWxTdGF0ZUV4Y2VwdGlvbjwvdHQ+IGlmIG5vIHNwYWNlIGlzIGN1cnJlbnRseQorICAgICAqIGF2YWlsYWJsZS4gIFdoZW4gdXNpbmcgYSBjYXBhY2l0eS1yZXN0cmljdGVkIGRlcXVlLCBpdCBpcyBnZW5lcmFsbHkKKyAgICAgKiBwcmVmZXJhYmxlIHRvIHVzZSB7QGxpbmsgI29mZmVyTGFzdCBvZmZlckxhc3R9LgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHZvaWQgYWRkTGFzdChFIGUpOworCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgYXQgdGhlIGZyb250IG9mIHRoaXMgZGVxdWUgaWYgaXQgaXMKKyAgICAgKiBwb3NzaWJsZSB0byBkbyBzbyBpbW1lZGlhdGVseSB3aXRob3V0IHZpb2xhdGluZyBjYXBhY2l0eSByZXN0cmljdGlvbnMsCisgICAgICogcmV0dXJuaW5nIDx0dD50cnVlPC90dD4gdXBvbiBzdWNjZXNzIGFuZCA8dHQ+ZmFsc2U8L3R0PiBpZiBubyBzcGFjZSBpcworICAgICAqIGN1cnJlbnRseSBhdmFpbGFibGUuCisgICAgICogV2hlbiB1c2luZyBhIGNhcGFjaXR5LXJlc3RyaWN0ZWQgZGVxdWUsIHRoaXMgbWV0aG9kIGlzIGdlbmVyYWxseQorICAgICAqIHByZWZlcmFibGUgdG8gdGhlIHtAbGluayAjYWRkRmlyc3QgYWRkRmlyc3R9IG1ldGhvZCwgd2hpY2ggY2FuCisgICAgICogZmFpbCB0byBpbnNlcnQgYW4gZWxlbWVudCBvbmx5IGJ5IHRocm93aW5nIGFuIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIHRoZSBlbGVtZW50IHRvIGFkZAorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIGJvb2xlYW4gb2ZmZXJGaXJzdChFIGUpOworCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgYXQgdGhlIGVuZCBvZiB0aGlzIGRlcXVlIGlmIGl0IGlzCisgICAgICogcG9zc2libGUgdG8gZG8gc28gaW1tZWRpYXRlbHkgd2l0aG91dCB2aW9sYXRpbmcgY2FwYWNpdHkgcmVzdHJpY3Rpb25zLAorICAgICAqIHJldHVybmluZyA8dHQ+dHJ1ZTwvdHQ+IHVwb24gc3VjY2VzcyBhbmQgPHR0PmZhbHNlPC90dD4gaWYgbm8gc3BhY2UgaXMKKyAgICAgKiBjdXJyZW50bHkgYXZhaWxhYmxlLgorICAgICAqIFdoZW4gdXNpbmcgYSBjYXBhY2l0eS1yZXN0cmljdGVkIGRlcXVlLCB0aGlzIG1ldGhvZCBpcyBnZW5lcmFsbHkKKyAgICAgKiBwcmVmZXJhYmxlIHRvIHRoZSB7QGxpbmsgI2FkZExhc3QgYWRkTGFzdH0gbWV0aG9kLCB3aGljaCBjYW4KKyAgICAgKiBmYWlsIHRvIGluc2VydCBhbiBlbGVtZW50IG9ubHkgYnkgdGhyb3dpbmcgYW4gZXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgYm9vbGVhbiBvZmZlckxhc3QoRSBlKTsKKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGF0IHRoZSBmcm9udCBvZiB0aGlzIGRlcXVlLAorICAgICAqIHdhaXRpbmcgaWYgbmVjZXNzYXJ5IGZvciBzcGFjZSB0byBiZWNvbWUgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiBpbnRlcnJ1cHRlZCB3aGlsZSB3YWl0aW5nCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqICAgICAgICAgcHJldmVudHMgaXQgZnJvbSBiZWluZyBhZGRlZCB0byB0aGlzIGRlcXVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNvbWUgcHJvcGVydHkgb2YgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgZWxlbWVudCBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgZGVxdWUKKyAgICAgKi8KKyAgICB2b2lkIHB1dEZpcnN0KEUgZSkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgYXQgdGhlIGVuZCBvZiB0aGlzIGRlcXVlLAorICAgICAqIHdhaXRpbmcgaWYgbmVjZXNzYXJ5IGZvciBzcGFjZSB0byBiZWNvbWUgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiBpbnRlcnJ1cHRlZCB3aGlsZSB3YWl0aW5nCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqICAgICAgICAgcHJldmVudHMgaXQgZnJvbSBiZWluZyBhZGRlZCB0byB0aGlzIGRlcXVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNvbWUgcHJvcGVydHkgb2YgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgZWxlbWVudCBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgZGVxdWUKKyAgICAgKi8KKyAgICB2b2lkIHB1dExhc3QoRSBlKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBhdCB0aGUgZnJvbnQgb2YgdGhpcyBkZXF1ZSwKKyAgICAgKiB3YWl0aW5nIHVwIHRvIHRoZSBzcGVjaWZpZWQgd2FpdCB0aW1lIGlmIG5lY2Vzc2FyeSBmb3Igc3BhY2UgdG8KKyAgICAgKiBiZWNvbWUgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHBhcmFtIHRpbWVvdXQgaG93IGxvbmcgdG8gd2FpdCBiZWZvcmUgZ2l2aW5nIHVwLCBpbiB1bml0cyBvZgorICAgICAqICAgICAgICA8dHQ+dW5pdDwvdHQ+CisgICAgICogQHBhcmFtIHVuaXQgYSA8dHQ+VGltZVVuaXQ8L3R0PiBkZXRlcm1pbmluZyBob3cgdG8gaW50ZXJwcmV0IHRoZQorICAgICAqICAgICAgICA8dHQ+dGltZW91dDwvdHQ+IHBhcmFtZXRlcgorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiBzdWNjZXNzZnVsLCBvciA8dHQ+ZmFsc2U8L3R0PiBpZgorICAgICAqICAgICAgICAgdGhlIHNwZWNpZmllZCB3YWl0aW5nIHRpbWUgZWxhcHNlcyBiZWZvcmUgc3BhY2UgaXMgYXZhaWxhYmxlCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiBpbnRlcnJ1cHRlZCB3aGlsZSB3YWl0aW5nCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqICAgICAgICAgcHJldmVudHMgaXQgZnJvbSBiZWluZyBhZGRlZCB0byB0aGlzIGRlcXVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNvbWUgcHJvcGVydHkgb2YgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgZWxlbWVudCBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgZGVxdWUKKyAgICAgKi8KKyAgICBib29sZWFuIG9mZmVyRmlyc3QoRSBlLCBsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGF0IHRoZSBlbmQgb2YgdGhpcyBkZXF1ZSwKKyAgICAgKiB3YWl0aW5nIHVwIHRvIHRoZSBzcGVjaWZpZWQgd2FpdCB0aW1lIGlmIG5lY2Vzc2FyeSBmb3Igc3BhY2UgdG8KKyAgICAgKiBiZWNvbWUgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHBhcmFtIHRpbWVvdXQgaG93IGxvbmcgdG8gd2FpdCBiZWZvcmUgZ2l2aW5nIHVwLCBpbiB1bml0cyBvZgorICAgICAqICAgICAgICA8dHQ+dW5pdDwvdHQ+CisgICAgICogQHBhcmFtIHVuaXQgYSA8dHQ+VGltZVVuaXQ8L3R0PiBkZXRlcm1pbmluZyBob3cgdG8gaW50ZXJwcmV0IHRoZQorICAgICAqICAgICAgICA8dHQ+dGltZW91dDwvdHQ+IHBhcmFtZXRlcgorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiBzdWNjZXNzZnVsLCBvciA8dHQ+ZmFsc2U8L3R0PiBpZgorICAgICAqICAgICAgICAgdGhlIHNwZWNpZmllZCB3YWl0aW5nIHRpbWUgZWxhcHNlcyBiZWZvcmUgc3BhY2UgaXMgYXZhaWxhYmxlCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiBpbnRlcnJ1cHRlZCB3aGlsZSB3YWl0aW5nCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqICAgICAgICAgcHJldmVudHMgaXQgZnJvbSBiZWluZyBhZGRlZCB0byB0aGlzIGRlcXVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNvbWUgcHJvcGVydHkgb2YgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgZWxlbWVudCBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgZGVxdWUKKyAgICAgKi8KKyAgICBib29sZWFuIG9mZmVyTGFzdChFIGUsIGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGFuZCByZW1vdmVzIHRoZSBmaXJzdCBlbGVtZW50IG9mIHRoaXMgZGVxdWUsIHdhaXRpbmcKKyAgICAgKiBpZiBuZWNlc3NhcnkgdW50aWwgYW4gZWxlbWVudCBiZWNvbWVzIGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhlYWQgb2YgdGhpcyBkZXF1ZQorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgaW50ZXJydXB0ZWQgd2hpbGUgd2FpdGluZworICAgICAqLworICAgIEUgdGFrZUZpcnN0KCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGFuZCByZW1vdmVzIHRoZSBsYXN0IGVsZW1lbnQgb2YgdGhpcyBkZXF1ZSwgd2FpdGluZworICAgICAqIGlmIG5lY2Vzc2FyeSB1bnRpbCBhbiBlbGVtZW50IGJlY29tZXMgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdGFpbCBvZiB0aGlzIGRlcXVlCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiBpbnRlcnJ1cHRlZCB3aGlsZSB3YWl0aW5nCisgICAgICovCisgICAgRSB0YWtlTGFzdCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhbmQgcmVtb3ZlcyB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGlzIGRlcXVlLCB3YWl0aW5nCisgICAgICogdXAgdG8gdGhlIHNwZWNpZmllZCB3YWl0IHRpbWUgaWYgbmVjZXNzYXJ5IGZvciBhbiBlbGVtZW50IHRvCisgICAgICogYmVjb21lIGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aW1lb3V0IGhvdyBsb25nIHRvIHdhaXQgYmVmb3JlIGdpdmluZyB1cCwgaW4gdW5pdHMgb2YKKyAgICAgKiAgICAgICAgPHR0PnVuaXQ8L3R0PgorICAgICAqIEBwYXJhbSB1bml0IGEgPHR0PlRpbWVVbml0PC90dD4gZGV0ZXJtaW5pbmcgaG93IHRvIGludGVycHJldCB0aGUKKyAgICAgKiAgICAgICAgPHR0PnRpbWVvdXQ8L3R0PiBwYXJhbWV0ZXIKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWFkIG9mIHRoaXMgZGVxdWUsIG9yIDx0dD5udWxsPC90dD4gaWYgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgd2FpdGluZyB0aW1lIGVsYXBzZXMgYmVmb3JlIGFuIGVsZW1lbnQgaXMgYXZhaWxhYmxlCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiBpbnRlcnJ1cHRlZCB3aGlsZSB3YWl0aW5nCisgICAgICovCisgICAgRSBwb2xsRmlyc3QobG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KQorICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYW5kIHJlbW92ZXMgdGhlIGxhc3QgZWxlbWVudCBvZiB0aGlzIGRlcXVlLCB3YWl0aW5nCisgICAgICogdXAgdG8gdGhlIHNwZWNpZmllZCB3YWl0IHRpbWUgaWYgbmVjZXNzYXJ5IGZvciBhbiBlbGVtZW50IHRvCisgICAgICogYmVjb21lIGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aW1lb3V0IGhvdyBsb25nIHRvIHdhaXQgYmVmb3JlIGdpdmluZyB1cCwgaW4gdW5pdHMgb2YKKyAgICAgKiAgICAgICAgPHR0PnVuaXQ8L3R0PgorICAgICAqIEBwYXJhbSB1bml0IGEgPHR0PlRpbWVVbml0PC90dD4gZGV0ZXJtaW5pbmcgaG93IHRvIGludGVycHJldCB0aGUKKyAgICAgKiAgICAgICAgPHR0PnRpbWVvdXQ8L3R0PiBwYXJhbWV0ZXIKKyAgICAgKiBAcmV0dXJuIHRoZSB0YWlsIG9mIHRoaXMgZGVxdWUsIG9yIDx0dD5udWxsPC90dD4gaWYgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgd2FpdGluZyB0aW1lIGVsYXBzZXMgYmVmb3JlIGFuIGVsZW1lbnQgaXMgYXZhaWxhYmxlCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiBpbnRlcnJ1cHRlZCB3aGlsZSB3YWl0aW5nCisgICAgICovCisgICAgRSBwb2xsTGFzdChsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50IGZyb20gdGhpcyBkZXF1ZS4KKyAgICAgKiBJZiB0aGUgZGVxdWUgZG9lcyBub3QgY29udGFpbiB0aGUgZWxlbWVudCwgaXQgaXMgdW5jaGFuZ2VkLgorICAgICAqIE1vcmUgZm9ybWFsbHksIHJlbW92ZXMgdGhlIGZpcnN0IGVsZW1lbnQgPHR0PmU8L3R0PiBzdWNoIHRoYXQKKyAgICAgKiA8dHQ+by5lcXVhbHMoZSk8L3R0PiAoaWYgc3VjaCBhbiBlbGVtZW50IGV4aXN0cykuCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgZGVxdWUgY29udGFpbmVkIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqIChvciBlcXVpdmFsZW50bHksIGlmIHRoaXMgZGVxdWUgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBlbGVtZW50IHRvIGJlIHJlbW92ZWQgZnJvbSB0aGlzIGRlcXVlLCBpZiBwcmVzZW50CisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIGFuIGVsZW1lbnQgd2FzIHJlbW92ZWQgYXMgYSByZXN1bHQgb2YgdGhpcyBjYWxsCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqICAgICAgICAgaXMgaW5jb21wYXRpYmxlIHdpdGggdGhpcyBkZXF1ZSAob3B0aW9uYWwpCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbCAob3B0aW9uYWwpCisgICAgICovCisgICAgYm9vbGVhbiByZW1vdmVGaXJzdE9jY3VycmVuY2UoT2JqZWN0IG8pOworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBmcm9tIHRoaXMgZGVxdWUuCisgICAgICogSWYgdGhlIGRlcXVlIGRvZXMgbm90IGNvbnRhaW4gdGhlIGVsZW1lbnQsIGl0IGlzIHVuY2hhbmdlZC4KKyAgICAgKiBNb3JlIGZvcm1hbGx5LCByZW1vdmVzIHRoZSBsYXN0IGVsZW1lbnQgPHR0PmU8L3R0PiBzdWNoIHRoYXQKKyAgICAgKiA8dHQ+by5lcXVhbHMoZSk8L3R0PiAoaWYgc3VjaCBhbiBlbGVtZW50IGV4aXN0cykuCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgZGVxdWUgY29udGFpbmVkIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqIChvciBlcXVpdmFsZW50bHksIGlmIHRoaXMgZGVxdWUgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBlbGVtZW50IHRvIGJlIHJlbW92ZWQgZnJvbSB0aGlzIGRlcXVlLCBpZiBwcmVzZW50CisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIGFuIGVsZW1lbnQgd2FzIHJlbW92ZWQgYXMgYSByZXN1bHQgb2YgdGhpcyBjYWxsCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqICAgICAgICAgaXMgaW5jb21wYXRpYmxlIHdpdGggdGhpcyBkZXF1ZSAob3B0aW9uYWwpCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbCAob3B0aW9uYWwpCisgICAgICovCisgICAgYm9vbGVhbiByZW1vdmVMYXN0T2NjdXJyZW5jZShPYmplY3Qgbyk7CisKKyAgICAvLyAqKiogQmxvY2tpbmdRdWV1ZSBtZXRob2RzICoqKgorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaW50byB0aGUgcXVldWUgcmVwcmVzZW50ZWQgYnkgdGhpcyBkZXF1ZQorICAgICAqIChpbiBvdGhlciB3b3JkcywgYXQgdGhlIHRhaWwgb2YgdGhpcyBkZXF1ZSkgaWYgaXQgaXMgcG9zc2libGUgdG8gZG8gc28KKyAgICAgKiBpbW1lZGlhdGVseSB3aXRob3V0IHZpb2xhdGluZyBjYXBhY2l0eSByZXN0cmljdGlvbnMsIHJldHVybmluZworICAgICAqIDx0dD50cnVlPC90dD4gdXBvbiBzdWNjZXNzIGFuZCB0aHJvd2luZyBhbgorICAgICAqIDx0dD5JbGxlZ2FsU3RhdGVFeGNlcHRpb248L3R0PiBpZiBubyBzcGFjZSBpcyBjdXJyZW50bHkgYXZhaWxhYmxlLgorICAgICAqIFdoZW4gdXNpbmcgYSBjYXBhY2l0eS1yZXN0cmljdGVkIGRlcXVlLCBpdCBpcyBnZW5lcmFsbHkgcHJlZmVyYWJsZSB0bworICAgICAqIHVzZSB7QGxpbmsgI29mZmVyIG9mZmVyfS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8ge0BsaW5rICNhZGRMYXN0IGFkZExhc3R9LgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKiAgICAgICAgIHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBkZXF1ZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBzb21lIHByb3BlcnR5IG9mIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIGVsZW1lbnQgcHJldmVudHMgaXQgZnJvbSBiZWluZyBhZGRlZCB0byB0aGlzIGRlcXVlCisgICAgICovCisgICAgYm9vbGVhbiBhZGQoRSBlKTsKKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGludG8gdGhlIHF1ZXVlIHJlcHJlc2VudGVkIGJ5IHRoaXMgZGVxdWUKKyAgICAgKiAoaW4gb3RoZXIgd29yZHMsIGF0IHRoZSB0YWlsIG9mIHRoaXMgZGVxdWUpIGlmIGl0IGlzIHBvc3NpYmxlIHRvIGRvIHNvCisgICAgICogaW1tZWRpYXRlbHkgd2l0aG91dCB2aW9sYXRpbmcgY2FwYWNpdHkgcmVzdHJpY3Rpb25zLCByZXR1cm5pbmcKKyAgICAgKiA8dHQ+dHJ1ZTwvdHQ+IHVwb24gc3VjY2VzcyBhbmQgPHR0PmZhbHNlPC90dD4gaWYgbm8gc3BhY2UgaXMgY3VycmVudGx5CisgICAgICogYXZhaWxhYmxlLiAgV2hlbiB1c2luZyBhIGNhcGFjaXR5LXJlc3RyaWN0ZWQgZGVxdWUsIHRoaXMgbWV0aG9kIGlzCisgICAgICogZ2VuZXJhbGx5IHByZWZlcmFibGUgdG8gdGhlIHtAbGluayAjYWRkfSBtZXRob2QsIHdoaWNoIGNhbiBmYWlsIHRvCisgICAgICogaW5zZXJ0IGFuIGVsZW1lbnQgb25seSBieSB0aHJvd2luZyBhbiBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAbGluayAjb2ZmZXJMYXN0IG9mZmVyTGFzdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byBhZGQKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3Mgb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICogICAgICAgICBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgZGVxdWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc29tZSBwcm9wZXJ0eSBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBlbGVtZW50IHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBkZXF1ZQorICAgICAqLworICAgIGJvb2xlYW4gb2ZmZXIoRSBlKTsKKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGludG8gdGhlIHF1ZXVlIHJlcHJlc2VudGVkIGJ5IHRoaXMgZGVxdWUKKyAgICAgKiAoaW4gb3RoZXIgd29yZHMsIGF0IHRoZSB0YWlsIG9mIHRoaXMgZGVxdWUpLCB3YWl0aW5nIGlmIG5lY2Vzc2FyeSBmb3IKKyAgICAgKiBzcGFjZSB0byBiZWNvbWUgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byB7QGxpbmsgI3B1dExhc3QgcHV0TGFzdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byBhZGQKKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3Mgb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICogICAgICAgICBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgZGVxdWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc29tZSBwcm9wZXJ0eSBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBlbGVtZW50IHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBkZXF1ZQorICAgICAqLworICAgIHZvaWQgcHV0KEUgZSkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaW50byB0aGUgcXVldWUgcmVwcmVzZW50ZWQgYnkgdGhpcyBkZXF1ZQorICAgICAqIChpbiBvdGhlciB3b3JkcywgYXQgdGhlIHRhaWwgb2YgdGhpcyBkZXF1ZSksIHdhaXRpbmcgdXAgdG8gdGhlCisgICAgICogc3BlY2lmaWVkIHdhaXQgdGltZSBpZiBuZWNlc3NhcnkgZm9yIHNwYWNlIHRvIGJlY29tZSBhdmFpbGFibGUuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvCisgICAgICoge0BsaW5rICNvZmZlckxhc3Qgb2ZmZXJMYXN0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIHRoZSBlbGVtZW50IHRvIGFkZAorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGUgZWxlbWVudCB3YXMgYWRkZWQgdG8gdGhpcyBkZXF1ZSwgZWxzZQorICAgICAqICAgICAgICAgPHR0PmZhbHNlPC90dD4KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3Mgb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICogICAgICAgICBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgZGVxdWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc29tZSBwcm9wZXJ0eSBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBlbGVtZW50IHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBkZXF1ZQorICAgICAqLworICAgIGJvb2xlYW4gb2ZmZXIoRSBlLCBsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhbmQgcmVtb3ZlcyB0aGUgaGVhZCBvZiB0aGUgcXVldWUgcmVwcmVzZW50ZWQgYnkgdGhpcyBkZXF1ZQorICAgICAqIChpbiBvdGhlciB3b3JkcywgdGhlIGZpcnN0IGVsZW1lbnQgb2YgdGhpcyBkZXF1ZSkuCisgICAgICogVGhpcyBtZXRob2QgZGlmZmVycyBmcm9tIHtAbGluayAjcG9sbCBwb2xsfSBvbmx5IGluIHRoYXQgaXQKKyAgICAgKiB0aHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAbGluayAjcmVtb3ZlRmlyc3QoKSByZW1vdmVGaXJzdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWFkIG9mIHRoZSBxdWV1ZSByZXByZXNlbnRlZCBieSB0aGlzIGRlcXVlCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBFIHJlbW92ZSgpOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGFuZCByZW1vdmVzIHRoZSBoZWFkIG9mIHRoZSBxdWV1ZSByZXByZXNlbnRlZCBieSB0aGlzIGRlcXVlCisgICAgICogKGluIG90aGVyIHdvcmRzLCB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGlzIGRlcXVlKSwgb3IgcmV0dXJucworICAgICAqIDx0dD5udWxsPC90dD4gaWYgdGhpcyBkZXF1ZSBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8ge0BsaW5rICNwb2xsRmlyc3QoKX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWFkIG9mIHRoaXMgZGVxdWUsIG9yIDx0dD5udWxsPC90dD4gaWYgdGhpcyBkZXF1ZSBpcyBlbXB0eQorICAgICAqLworICAgIEUgcG9sbCgpOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGFuZCByZW1vdmVzIHRoZSBoZWFkIG9mIHRoZSBxdWV1ZSByZXByZXNlbnRlZCBieSB0aGlzIGRlcXVlCisgICAgICogKGluIG90aGVyIHdvcmRzLCB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGlzIGRlcXVlKSwgd2FpdGluZyBpZgorICAgICAqIG5lY2Vzc2FyeSB1bnRpbCBhbiBlbGVtZW50IGJlY29tZXMgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byB7QGxpbmsgI3Rha2VGaXJzdCgpIHRha2VGaXJzdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWFkIG9mIHRoaXMgZGVxdWUKKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIGludGVycnVwdGVkIHdoaWxlIHdhaXRpbmcKKyAgICAgKi8KKyAgICBFIHRha2UoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYW5kIHJlbW92ZXMgdGhlIGhlYWQgb2YgdGhlIHF1ZXVlIHJlcHJlc2VudGVkIGJ5IHRoaXMgZGVxdWUKKyAgICAgKiAoaW4gb3RoZXIgd29yZHMsIHRoZSBmaXJzdCBlbGVtZW50IG9mIHRoaXMgZGVxdWUpLCB3YWl0aW5nIHVwIHRvIHRoZQorICAgICAqIHNwZWNpZmllZCB3YWl0IHRpbWUgaWYgbmVjZXNzYXJ5IGZvciBhbiBlbGVtZW50IHRvIGJlY29tZSBhdmFpbGFibGUuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvCisgICAgICoge0BsaW5rICNwb2xsRmlyc3QobG9uZyxUaW1lVW5pdCkgcG9sbEZpcnN0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhlYWQgb2YgdGhpcyBkZXF1ZSwgb3IgPHR0Pm51bGw8L3R0PiBpZiB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCB3YWl0aW5nIHRpbWUgZWxhcHNlcyBiZWZvcmUgYW4gZWxlbWVudCBpcyBhdmFpbGFibGUKKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIGludGVycnVwdGVkIHdoaWxlIHdhaXRpbmcKKyAgICAgKi8KKyAgICBFIHBvbGwobG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KQorICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMsIGJ1dCBkb2VzIG5vdCByZW1vdmUsIHRoZSBoZWFkIG9mIHRoZSBxdWV1ZSByZXByZXNlbnRlZCBieQorICAgICAqIHRoaXMgZGVxdWUgKGluIG90aGVyIHdvcmRzLCB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGlzIGRlcXVlKS4KKyAgICAgKiBUaGlzIG1ldGhvZCBkaWZmZXJzIGZyb20ge0BsaW5rICNwZWVrIHBlZWt9IG9ubHkgaW4gdGhhdCBpdCB0aHJvd3MgYW4KKyAgICAgKiBleGNlcHRpb24gaWYgdGhpcyBkZXF1ZSBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8ge0BsaW5rICNnZXRGaXJzdCgpIGdldEZpcnN0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhlYWQgb2YgdGhpcyBkZXF1ZQorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBpZiB0aGlzIGRlcXVlIGlzIGVtcHR5CisgICAgICovCisgICAgRSBlbGVtZW50KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMsIGJ1dCBkb2VzIG5vdCByZW1vdmUsIHRoZSBoZWFkIG9mIHRoZSBxdWV1ZSByZXByZXNlbnRlZCBieQorICAgICAqIHRoaXMgZGVxdWUgKGluIG90aGVyIHdvcmRzLCB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGlzIGRlcXVlKSwgb3IKKyAgICAgKiByZXR1cm5zIDx0dD5udWxsPC90dD4gaWYgdGhpcyBkZXF1ZSBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8ge0BsaW5rICNwZWVrRmlyc3QoKSBwZWVrRmlyc3R9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGlzIGRlcXVlLCBvciA8dHQ+bnVsbDwvdHQ+IGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBFIHBlZWsoKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50IGZyb20gdGhpcyBkZXF1ZS4KKyAgICAgKiBJZiB0aGUgZGVxdWUgZG9lcyBub3QgY29udGFpbiB0aGUgZWxlbWVudCwgaXQgaXMgdW5jaGFuZ2VkLgorICAgICAqIE1vcmUgZm9ybWFsbHksIHJlbW92ZXMgdGhlIGZpcnN0IGVsZW1lbnQgPHR0PmU8L3R0PiBzdWNoIHRoYXQKKyAgICAgKiA8dHQ+by5lcXVhbHMoZSk8L3R0PiAoaWYgc3VjaCBhbiBlbGVtZW50IGV4aXN0cykuCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgZGVxdWUgY29udGFpbmVkIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqIChvciBlcXVpdmFsZW50bHksIGlmIHRoaXMgZGVxdWUgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbCkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvCisgICAgICoge0BsaW5rICNyZW1vdmVGaXJzdE9jY3VycmVuY2UgcmVtb3ZlRmlyc3RPY2N1cnJlbmNlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvIGVsZW1lbnQgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoaXMgZGVxdWUsIGlmIHByZXNlbnQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBkZXF1ZSBjaGFuZ2VkIGFzIGEgcmVzdWx0IG9mIHRoZSBjYWxsCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqICAgICAgICAgaXMgaW5jb21wYXRpYmxlIHdpdGggdGhpcyBkZXF1ZSAob3B0aW9uYWwpCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbCAob3B0aW9uYWwpCisgICAgICovCisgICAgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG8pOworCisgICAgLyoqCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgZGVxdWUgY29udGFpbnMgdGhlIHNwZWNpZmllZCBlbGVtZW50LgorICAgICAqIE1vcmUgZm9ybWFsbHksIHJldHVybnMgPHR0PnRydWU8L3R0PiBpZiBhbmQgb25seSBpZiB0aGlzIGRlcXVlIGNvbnRhaW5zCisgICAgICogYXQgbGVhc3Qgb25lIGVsZW1lbnQgPHR0PmU8L3R0PiBzdWNoIHRoYXQgPHR0Pm8uZXF1YWxzKGUpPC90dD4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBvYmplY3QgdG8gYmUgY2hlY2tlZCBmb3IgY29udGFpbm1lbnQgaW4gdGhpcyBkZXF1ZQorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGlzIGRlcXVlIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKiAgICAgICAgIGlzIGluY29tcGF0aWJsZSB3aXRoIHRoaXMgZGVxdWUgKG9wdGlvbmFsKQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwgKG9wdGlvbmFsKQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIGRlcXVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgZGVxdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNpemUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMgaW4gdGhpcyBkZXF1ZSBpbiBwcm9wZXIgc2VxdWVuY2UuCisgICAgICogVGhlIGVsZW1lbnRzIHdpbGwgYmUgcmV0dXJuZWQgaW4gb3JkZXIgZnJvbSBmaXJzdCAoaGVhZCkgdG8gbGFzdCAodGFpbCkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzIGluIHRoaXMgZGVxdWUgaW4gcHJvcGVyIHNlcXVlbmNlCisgICAgICovCisgICAgSXRlcmF0b3I8RT4gaXRlcmF0b3IoKTsKKworICAgIC8vICoqKiBTdGFjayBtZXRob2RzICoqKgorCisgICAgLyoqCisgICAgICogUHVzaGVzIGFuIGVsZW1lbnQgb250byB0aGUgc3RhY2sgcmVwcmVzZW50ZWQgYnkgdGhpcyBkZXF1ZS4gIEluIG90aGVyCisgICAgICogd29yZHMsIGluc2VydHMgdGhlIGVsZW1lbnQgYXQgdGhlIGZyb250IG9mIHRoaXMgZGVxdWUgdW5sZXNzIGl0IHdvdWxkCisgICAgICogdmlvbGF0ZSBjYXBhY2l0eSByZXN0cmljdGlvbnMuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAbGluayAjYWRkRmlyc3QgYWRkRmlyc3R9LgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHZvaWQgcHVzaChFIGUpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0Jsb2NraW5nUXVldWUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9CbG9ja2luZ1F1ZXVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDAxYzA5NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9CbG9ja2luZ1F1ZXVlLmphdmEKQEAgLTAsMCArMSwzNDQgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudDsKKworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5RdWV1ZTsKKworLy8gQkVHSU4gYW5kcm9pZC1ub3RlCisvLyByZW1vdmVkIGxpbmsgdG8gY29sbGVjdGlvbnMgZnJhbWV3b3JrIGRvY3MKKy8vIEVORCBhbmRyb2lkLW5vdGUKKworLyoqCisgKiBBIHtAbGluayBqYXZhLnV0aWwuUXVldWV9IHRoYXQgYWRkaXRpb25hbGx5IHN1cHBvcnRzIG9wZXJhdGlvbnMKKyAqIHRoYXQgd2FpdCBmb3IgdGhlIHF1ZXVlIHRvIGJlY29tZSBub24tZW1wdHkgd2hlbiByZXRyaWV2aW5nIGFuCisgKiBlbGVtZW50LCBhbmQgd2FpdCBmb3Igc3BhY2UgdG8gYmVjb21lIGF2YWlsYWJsZSBpbiB0aGUgcXVldWUgd2hlbgorICogc3RvcmluZyBhbiBlbGVtZW50LgorICoKKyAqIDxwPjx0dD5CbG9ja2luZ1F1ZXVlPC90dD4gbWV0aG9kcyBjb21lIGluIGZvdXIgZm9ybXMsIHdpdGggZGlmZmVyZW50IHdheXMKKyAqIG9mIGhhbmRsaW5nIG9wZXJhdGlvbnMgdGhhdCBjYW5ub3QgYmUgc2F0aXNmaWVkIGltbWVkaWF0ZWx5LCBidXQgbWF5IGJlCisgKiBzYXRpc2ZpZWQgYXQgc29tZSBwb2ludCBpbiB0aGUgZnV0dXJlOgorICogb25lIHRocm93cyBhbiBleGNlcHRpb24sIHRoZSBzZWNvbmQgcmV0dXJucyBhIHNwZWNpYWwgdmFsdWUgKGVpdGhlcgorICogPHR0Pm51bGw8L3R0PiBvciA8dHQ+ZmFsc2U8L3R0PiwgZGVwZW5kaW5nIG9uIHRoZSBvcGVyYXRpb24pLCB0aGUgdGhpcmQKKyAqIGJsb2NrcyB0aGUgY3VycmVudCB0aHJlYWQgaW5kZWZpbml0ZWx5IHVudGlsIHRoZSBvcGVyYXRpb24gY2FuIHN1Y2NlZWQsCisgKiBhbmQgdGhlIGZvdXJ0aCBibG9ja3MgZm9yIG9ubHkgYSBnaXZlbiBtYXhpbXVtIHRpbWUgbGltaXQgYmVmb3JlIGdpdmluZworICogdXAuICBUaGVzZSBtZXRob2RzIGFyZSBzdW1tYXJpemVkIGluIHRoZSBmb2xsb3dpbmcgdGFibGU6CisgKgorICogPHA+CisgKiA8dGFibGUgQk9SREVSIENFTExQQURESU5HPTMgQ0VMTFNQQUNJTkc9MT4KKyAqICA8dHI+CisgKiAgICA8dGQ+PC90ZD4KKyAqICAgIDx0ZCBBTElHTj1DRU5URVI+PGVtPlRocm93cyBleGNlcHRpb248L2VtPjwvdGQ+CisgKiAgICA8dGQgQUxJR049Q0VOVEVSPjxlbT5TcGVjaWFsIHZhbHVlPC9lbT48L3RkPgorICogICAgPHRkIEFMSUdOPUNFTlRFUj48ZW0+QmxvY2tzPC9lbT48L3RkPgorICogICAgPHRkIEFMSUdOPUNFTlRFUj48ZW0+VGltZXMgb3V0PC9lbT48L3RkPgorICogIDwvdHI+CisgKiAgPHRyPgorICogICAgPHRkPjxiPkluc2VydDwvYj48L3RkPgorICogICAgPHRkPntAbGluayAjYWRkIGFkZChlKX08L3RkPgorICogICAgPHRkPntAbGluayAjb2ZmZXIgb2ZmZXIoZSl9PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI3B1dCBwdXQoZSl9PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI29mZmVyIG9mZmVyKGUsIHRpbWUsIHVuaXQpfTwvdGQ+CisgKiAgPC90cj4KKyAqICA8dHI+CisgKiAgICA8dGQ+PGI+UmVtb3ZlPC9iPjwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNyZW1vdmUgcmVtb3ZlKCl9PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI3BvbGwgcG9sbCgpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICN0YWtlIHRha2UoKX08L3RkPgorICogICAgPHRkPntAbGluayAjcG9sbChsb25nLCBUaW1lVW5pdCkgcG9sbCh0aW1lLCB1bml0KX08L3RkPgorICogIDwvdHI+CisgKiAgPHRyPgorICogICAgPHRkPjxiPkV4YW1pbmU8L2I+PC90ZD4KKyAqICAgIDx0ZD57QGxpbmsgI2VsZW1lbnQgZWxlbWVudCgpfTwvdGQ+CisgKiAgICA8dGQ+e0BsaW5rICNwZWVrIHBlZWsoKX08L3RkPgorICogICAgPHRkPjxlbT5ub3QgYXBwbGljYWJsZTwvZW0+PC90ZD4KKyAqICAgIDx0ZD48ZW0+bm90IGFwcGxpY2FibGU8L2VtPjwvdGQ+CisgKiAgPC90cj4KKyAqIDwvdGFibGU+CisgKgorICogPHA+QSA8dHQ+QmxvY2tpbmdRdWV1ZTwvdHQ+IGRvZXMgbm90IGFjY2VwdCA8dHQ+bnVsbDwvdHQ+IGVsZW1lbnRzLgorICogSW1wbGVtZW50YXRpb25zIHRocm93IDx0dD5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvdHQ+IG9uIGF0dGVtcHRzCisgKiB0byA8dHQ+YWRkPC90dD4sIDx0dD5wdXQ8L3R0PiBvciA8dHQ+b2ZmZXI8L3R0PiBhIDx0dD5udWxsPC90dD4uICBBCisgKiA8dHQ+bnVsbDwvdHQ+IGlzIHVzZWQgYXMgYSBzZW50aW5lbCB2YWx1ZSB0byBpbmRpY2F0ZSBmYWlsdXJlIG9mCisgKiA8dHQ+cG9sbDwvdHQ+IG9wZXJhdGlvbnMuCisgKgorICogPHA+QSA8dHQ+QmxvY2tpbmdRdWV1ZTwvdHQ+IG1heSBiZSBjYXBhY2l0eSBib3VuZGVkLiBBdCBhbnkgZ2l2ZW4KKyAqIHRpbWUgaXQgbWF5IGhhdmUgYSA8dHQ+cmVtYWluaW5nQ2FwYWNpdHk8L3R0PiBiZXlvbmQgd2hpY2ggbm8KKyAqIGFkZGl0aW9uYWwgZWxlbWVudHMgY2FuIGJlIDx0dD5wdXQ8L3R0PiB3aXRob3V0IGJsb2NraW5nLgorICogQSA8dHQ+QmxvY2tpbmdRdWV1ZTwvdHQ+IHdpdGhvdXQgYW55IGludHJpbnNpYyBjYXBhY2l0eSBjb25zdHJhaW50cyBhbHdheXMKKyAqIHJlcG9ydHMgYSByZW1haW5pbmcgY2FwYWNpdHkgb2YgPHR0PkludGVnZXIuTUFYX1ZBTFVFPC90dD4uCisgKgorICogPHA+IDx0dD5CbG9ja2luZ1F1ZXVlPC90dD4gaW1wbGVtZW50YXRpb25zIGFyZSBkZXNpZ25lZCB0byBiZSB1c2VkCisgKiBwcmltYXJpbHkgZm9yIHByb2R1Y2VyLWNvbnN1bWVyIHF1ZXVlcywgYnV0IGFkZGl0aW9uYWxseSBzdXBwb3J0CisgKiB0aGUge0BsaW5rIGphdmEudXRpbC5Db2xsZWN0aW9ufSBpbnRlcmZhY2UuICBTbywgZm9yIGV4YW1wbGUsIGl0IGlzCisgKiBwb3NzaWJsZSB0byByZW1vdmUgYW4gYXJiaXRyYXJ5IGVsZW1lbnQgZnJvbSBhIHF1ZXVlIHVzaW5nCisgKiA8dHQ+cmVtb3ZlKHgpPC90dD4uIEhvd2V2ZXIsIHN1Y2ggb3BlcmF0aW9ucyBhcmUgaW4gZ2VuZXJhbAorICogPGVtPm5vdDwvZW0+IHBlcmZvcm1lZCB2ZXJ5IGVmZmljaWVudGx5LCBhbmQgYXJlIGludGVuZGVkIGZvciBvbmx5CisgKiBvY2Nhc2lvbmFsIHVzZSwgc3VjaCBhcyB3aGVuIGEgcXVldWVkIG1lc3NhZ2UgaXMgY2FuY2VsbGVkLgorICoKKyAqIDxwPiA8dHQ+QmxvY2tpbmdRdWV1ZTwvdHQ+IGltcGxlbWVudGF0aW9ucyBhcmUgdGhyZWFkLXNhZmUuICBBbGwKKyAqIHF1ZXVpbmcgbWV0aG9kcyBhY2hpZXZlIHRoZWlyIGVmZmVjdHMgYXRvbWljYWxseSB1c2luZyBpbnRlcm5hbAorICogbG9ja3Mgb3Igb3RoZXIgZm9ybXMgb2YgY29uY3VycmVuY3kgY29udHJvbC4gSG93ZXZlciwgdGhlCisgKiA8ZW0+YnVsazwvZW0+IENvbGxlY3Rpb24gb3BlcmF0aW9ucyA8dHQ+YWRkQWxsPC90dD4sCisgKiA8dHQ+Y29udGFpbnNBbGw8L3R0PiwgPHR0PnJldGFpbkFsbDwvdHQ+IGFuZCA8dHQ+cmVtb3ZlQWxsPC90dD4gYXJlCisgKiA8ZW0+bm90PC9lbT4gbmVjZXNzYXJpbHkgcGVyZm9ybWVkIGF0b21pY2FsbHkgdW5sZXNzIHNwZWNpZmllZAorICogb3RoZXJ3aXNlIGluIGFuIGltcGxlbWVudGF0aW9uLiBTbyBpdCBpcyBwb3NzaWJsZSwgZm9yIGV4YW1wbGUsIGZvcgorICogPHR0PmFkZEFsbChjKTwvdHQ+IHRvIGZhaWwgKHRocm93aW5nIGFuIGV4Y2VwdGlvbikgYWZ0ZXIgYWRkaW5nCisgKiBvbmx5IHNvbWUgb2YgdGhlIGVsZW1lbnRzIGluIDx0dD5jPC90dD4uCisgKgorICogPHA+QSA8dHQ+QmxvY2tpbmdRdWV1ZTwvdHQ+IGRvZXMgPGVtPm5vdDwvZW0+IGludHJpbnNpY2FsbHkgc3VwcG9ydAorICogYW55IGtpbmQgb2YgJnF1b3Q7Y2xvc2UmcXVvdDsgb3IgJnF1b3Q7c2h1dGRvd24mcXVvdDsgb3BlcmF0aW9uIHRvCisgKiBpbmRpY2F0ZSB0aGF0IG5vIG1vcmUgaXRlbXMgd2lsbCBiZSBhZGRlZC4gIFRoZSBuZWVkcyBhbmQgdXNhZ2Ugb2YKKyAqIHN1Y2ggZmVhdHVyZXMgdGVuZCB0byBiZSBpbXBsZW1lbnRhdGlvbi1kZXBlbmRlbnQuIEZvciBleGFtcGxlLCBhCisgKiBjb21tb24gdGFjdGljIGlzIGZvciBwcm9kdWNlcnMgdG8gaW5zZXJ0IHNwZWNpYWwKKyAqIDxlbT5lbmQtb2Ytc3RyZWFtPC9lbT4gb3IgPGVtPnBvaXNvbjwvZW0+IG9iamVjdHMsIHRoYXQgYXJlCisgKiBpbnRlcnByZXRlZCBhY2NvcmRpbmdseSB3aGVuIHRha2VuIGJ5IGNvbnN1bWVycy4KKyAqCisgKiA8cD4KKyAqIFVzYWdlIGV4YW1wbGUsIGJhc2VkIG9uIGEgdHlwaWNhbCBwcm9kdWNlci1jb25zdW1lciBzY2VuYXJpby4KKyAqIE5vdGUgdGhhdCBhIDx0dD5CbG9ja2luZ1F1ZXVlPC90dD4gY2FuIHNhZmVseSBiZSB1c2VkIHdpdGggbXVsdGlwbGUKKyAqIHByb2R1Y2VycyBhbmQgbXVsdGlwbGUgY29uc3VtZXJzLgorICogPHByZT4KKyAqIGNsYXNzIFByb2R1Y2VyIGltcGxlbWVudHMgUnVubmFibGUgeworICogICBwcml2YXRlIGZpbmFsIEJsb2NraW5nUXVldWUgcXVldWU7CisgKiAgIFByb2R1Y2VyKEJsb2NraW5nUXVldWUgcSkgeyBxdWV1ZSA9IHE7IH0KKyAqICAgcHVibGljIHZvaWQgcnVuKCkgeworICogICAgIHRyeSB7CisgKiAgICAgICB3aGlsZSAodHJ1ZSkgeyBxdWV1ZS5wdXQocHJvZHVjZSgpKTsgfQorICogICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7IC4uLiBoYW5kbGUgLi4ufQorICogICB9CisgKiAgIE9iamVjdCBwcm9kdWNlKCkgeyAuLi4gfQorICogfQorICoKKyAqIGNsYXNzIENvbnN1bWVyIGltcGxlbWVudHMgUnVubmFibGUgeworICogICBwcml2YXRlIGZpbmFsIEJsb2NraW5nUXVldWUgcXVldWU7CisgKiAgIENvbnN1bWVyKEJsb2NraW5nUXVldWUgcSkgeyBxdWV1ZSA9IHE7IH0KKyAqICAgcHVibGljIHZvaWQgcnVuKCkgeworICogICAgIHRyeSB7CisgKiAgICAgICB3aGlsZSAodHJ1ZSkgeyBjb25zdW1lKHF1ZXVlLnRha2UoKSk7IH0KKyAqICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeyAuLi4gaGFuZGxlIC4uLn0KKyAqICAgfQorICogICB2b2lkIGNvbnN1bWUoT2JqZWN0IHgpIHsgLi4uIH0KKyAqIH0KKyAqCisgKiBjbGFzcyBTZXR1cCB7CisgKiAgIHZvaWQgbWFpbigpIHsKKyAqICAgICBCbG9ja2luZ1F1ZXVlIHEgPSBuZXcgU29tZVF1ZXVlSW1wbGVtZW50YXRpb24oKTsKKyAqICAgICBQcm9kdWNlciBwID0gbmV3IFByb2R1Y2VyKHEpOworICogICAgIENvbnN1bWVyIGMxID0gbmV3IENvbnN1bWVyKHEpOworICogICAgIENvbnN1bWVyIGMyID0gbmV3IENvbnN1bWVyKHEpOworICogICAgIG5ldyBUaHJlYWQocCkuc3RhcnQoKTsKKyAqICAgICBuZXcgVGhyZWFkKGMxKS5zdGFydCgpOworICogICAgIG5ldyBUaHJlYWQoYzIpLnN0YXJ0KCk7CisgKiAgIH0KKyAqIH0KKyAqIDwvcHJlPgorICoKKyAqIDxwPk1lbW9yeSBjb25zaXN0ZW5jeSBlZmZlY3RzOiBBcyB3aXRoIG90aGVyIGNvbmN1cnJlbnQKKyAqIGNvbGxlY3Rpb25zLCBhY3Rpb25zIGluIGEgdGhyZWFkIHByaW9yIHRvIHBsYWNpbmcgYW4gb2JqZWN0IGludG8gYQorICoge0Bjb2RlIEJsb2NraW5nUXVldWV9CisgKiA8YSBocmVmPSJwYWNrYWdlLXN1bW1hcnkuaHRtbCNNZW1vcnlWaXNpYmlsaXR5Ij48aT5oYXBwZW4tYmVmb3JlPC9pPjwvYT4KKyAqIGFjdGlvbnMgc3Vic2VxdWVudCB0byB0aGUgYWNjZXNzIG9yIHJlbW92YWwgb2YgdGhhdCBlbGVtZW50IGZyb20KKyAqIHRoZSB7QGNvZGUgQmxvY2tpbmdRdWV1ZX0gaW4gYW5vdGhlciB0aHJlYWQuCisgKgorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICogQHBhcmFtIDxFPiB0aGUgdHlwZSBvZiBlbGVtZW50cyBoZWxkIGluIHRoaXMgY29sbGVjdGlvbgorICovCitwdWJsaWMgaW50ZXJmYWNlIEJsb2NraW5nUXVldWU8RT4gZXh0ZW5kcyBRdWV1ZTxFPiB7CisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaW50byB0aGlzIHF1ZXVlIGlmIGl0IGlzIHBvc3NpYmxlIHRvIGRvCisgICAgICogc28gaW1tZWRpYXRlbHkgd2l0aG91dCB2aW9sYXRpbmcgY2FwYWNpdHkgcmVzdHJpY3Rpb25zLCByZXR1cm5pbmcKKyAgICAgKiA8dHQ+dHJ1ZTwvdHQ+IHVwb24gc3VjY2VzcyBhbmQgdGhyb3dpbmcgYW4KKyAgICAgKiA8dHQ+SWxsZWdhbFN0YXRlRXhjZXB0aW9uPC90dD4gaWYgbm8gc3BhY2UgaXMgY3VycmVudGx5IGF2YWlsYWJsZS4KKyAgICAgKiBXaGVuIHVzaW5nIGEgY2FwYWNpdHktcmVzdHJpY3RlZCBxdWV1ZSwgaXQgaXMgZ2VuZXJhbGx5IHByZWZlcmFibGUgdG8KKyAgICAgKiB1c2Uge0BsaW5rICNvZmZlciBvZmZlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byBhZGQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gKGFzIHNwZWNpZmllZCBieSB7QGxpbmsgQ29sbGVjdGlvbiNhZGR9KQorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZSBlbGVtZW50IGNhbm5vdCBiZSBhZGRlZCBhdCB0aGlzCisgICAgICogICAgICAgICB0aW1lIGR1ZSB0byBjYXBhY2l0eSByZXN0cmljdGlvbnMKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3Mgb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICogICAgICAgICBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgcXVldWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc29tZSBwcm9wZXJ0eSBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBlbGVtZW50IHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBxdWV1ZQorICAgICAqLworICAgIGJvb2xlYW4gYWRkKEUgZSk7CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpbnRvIHRoaXMgcXVldWUgaWYgaXQgaXMgcG9zc2libGUgdG8gZG8KKyAgICAgKiBzbyBpbW1lZGlhdGVseSB3aXRob3V0IHZpb2xhdGluZyBjYXBhY2l0eSByZXN0cmljdGlvbnMsIHJldHVybmluZworICAgICAqIDx0dD50cnVlPC90dD4gdXBvbiBzdWNjZXNzIGFuZCA8dHQ+ZmFsc2U8L3R0PiBpZiBubyBzcGFjZSBpcyBjdXJyZW50bHkKKyAgICAgKiBhdmFpbGFibGUuICBXaGVuIHVzaW5nIGEgY2FwYWNpdHktcmVzdHJpY3RlZCBxdWV1ZSwgdGhpcyBtZXRob2QgaXMKKyAgICAgKiBnZW5lcmFsbHkgcHJlZmVyYWJsZSB0byB7QGxpbmsgI2FkZH0sIHdoaWNoIGNhbiBmYWlsIHRvIGluc2VydCBhbgorICAgICAqIGVsZW1lbnQgb25seSBieSB0aHJvd2luZyBhbiBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byBhZGQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhlIGVsZW1lbnQgd2FzIGFkZGVkIHRvIHRoaXMgcXVldWUsIGVsc2UKKyAgICAgKiAgICAgICAgIDx0dD5mYWxzZTwvdHQ+CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqICAgICAgICAgcHJldmVudHMgaXQgZnJvbSBiZWluZyBhZGRlZCB0byB0aGlzIHF1ZXVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNvbWUgcHJvcGVydHkgb2YgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgZWxlbWVudCBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgcXVldWUKKyAgICAgKi8KKyAgICBib29sZWFuIG9mZmVyKEUgZSk7CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpbnRvIHRoaXMgcXVldWUsIHdhaXRpbmcgaWYgbmVjZXNzYXJ5CisgICAgICogZm9yIHNwYWNlIHRvIGJlY29tZSBhdmFpbGFibGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byBhZGQKKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIGludGVycnVwdGVkIHdoaWxlIHdhaXRpbmcKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3Mgb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICogICAgICAgICBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgcXVldWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc29tZSBwcm9wZXJ0eSBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICBlbGVtZW50IHByZXZlbnRzIGl0IGZyb20gYmVpbmcgYWRkZWQgdG8gdGhpcyBxdWV1ZQorICAgICAqLworICAgIHZvaWQgcHV0KEUgZSkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaW50byB0aGlzIHF1ZXVlLCB3YWl0aW5nIHVwIHRvIHRoZQorICAgICAqIHNwZWNpZmllZCB3YWl0IHRpbWUgaWYgbmVjZXNzYXJ5IGZvciBzcGFjZSB0byBiZWNvbWUgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHBhcmFtIHRpbWVvdXQgaG93IGxvbmcgdG8gd2FpdCBiZWZvcmUgZ2l2aW5nIHVwLCBpbiB1bml0cyBvZgorICAgICAqICAgICAgICA8dHQ+dW5pdDwvdHQ+CisgICAgICogQHBhcmFtIHVuaXQgYSA8dHQ+VGltZVVuaXQ8L3R0PiBkZXRlcm1pbmluZyBob3cgdG8gaW50ZXJwcmV0IHRoZQorICAgICAqICAgICAgICA8dHQ+dGltZW91dDwvdHQ+IHBhcmFtZXRlcgorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiBzdWNjZXNzZnVsLCBvciA8dHQ+ZmFsc2U8L3R0PiBpZgorICAgICAqICAgICAgICAgdGhlIHNwZWNpZmllZCB3YWl0aW5nIHRpbWUgZWxhcHNlcyBiZWZvcmUgc3BhY2UgaXMgYXZhaWxhYmxlCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiBpbnRlcnJ1cHRlZCB3aGlsZSB3YWl0aW5nCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqICAgICAgICAgcHJldmVudHMgaXQgZnJvbSBiZWluZyBhZGRlZCB0byB0aGlzIHF1ZXVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNvbWUgcHJvcGVydHkgb2YgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgZWxlbWVudCBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoaXMgcXVldWUKKyAgICAgKi8KKyAgICBib29sZWFuIG9mZmVyKEUgZSwgbG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KQorICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYW5kIHJlbW92ZXMgdGhlIGhlYWQgb2YgdGhpcyBxdWV1ZSwgd2FpdGluZyBpZiBuZWNlc3NhcnkKKyAgICAgKiB1bnRpbCBhbiBlbGVtZW50IGJlY29tZXMgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGlzIHF1ZXVlCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiBpbnRlcnJ1cHRlZCB3aGlsZSB3YWl0aW5nCisgICAgICovCisgICAgRSB0YWtlKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGFuZCByZW1vdmVzIHRoZSBoZWFkIG9mIHRoaXMgcXVldWUsIHdhaXRpbmcgdXAgdG8gdGhlCisgICAgICogc3BlY2lmaWVkIHdhaXQgdGltZSBpZiBuZWNlc3NhcnkgZm9yIGFuIGVsZW1lbnQgdG8gYmVjb21lIGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aW1lb3V0IGhvdyBsb25nIHRvIHdhaXQgYmVmb3JlIGdpdmluZyB1cCwgaW4gdW5pdHMgb2YKKyAgICAgKiAgICAgICAgPHR0PnVuaXQ8L3R0PgorICAgICAqIEBwYXJhbSB1bml0IGEgPHR0PlRpbWVVbml0PC90dD4gZGV0ZXJtaW5pbmcgaG93IHRvIGludGVycHJldCB0aGUKKyAgICAgKiAgICAgICAgPHR0PnRpbWVvdXQ8L3R0PiBwYXJhbWV0ZXIKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWFkIG9mIHRoaXMgcXVldWUsIG9yIDx0dD5udWxsPC90dD4gaWYgdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgd2FpdGluZyB0aW1lIGVsYXBzZXMgYmVmb3JlIGFuIGVsZW1lbnQgaXMgYXZhaWxhYmxlCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiBpbnRlcnJ1cHRlZCB3aGlsZSB3YWl0aW5nCisgICAgICovCisgICAgRSBwb2xsKGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGFkZGl0aW9uYWwgZWxlbWVudHMgdGhhdCB0aGlzIHF1ZXVlIGNhbiBpZGVhbGx5CisgICAgICogKGluIHRoZSBhYnNlbmNlIG9mIG1lbW9yeSBvciByZXNvdXJjZSBjb25zdHJhaW50cykgYWNjZXB0IHdpdGhvdXQKKyAgICAgKiBibG9ja2luZywgb3IgPHR0PkludGVnZXIuTUFYX1ZBTFVFPC90dD4gaWYgdGhlcmUgaXMgbm8gaW50cmluc2ljCisgICAgICogbGltaXQuCisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoYXQgeW91IDxlbT5jYW5ub3Q8L2VtPiBhbHdheXMgdGVsbCBpZiBhbiBhdHRlbXB0IHRvIGluc2VydAorICAgICAqIGFuIGVsZW1lbnQgd2lsbCBzdWNjZWVkIGJ5IGluc3BlY3RpbmcgPHR0PnJlbWFpbmluZ0NhcGFjaXR5PC90dD4KKyAgICAgKiBiZWNhdXNlIGl0IG1heSBiZSB0aGUgY2FzZSB0aGF0IGFub3RoZXIgdGhyZWFkIGlzIGFib3V0IHRvCisgICAgICogaW5zZXJ0IG9yIHJlbW92ZSBhbiBlbGVtZW50LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVtYWluaW5nIGNhcGFjaXR5CisgICAgICovCisgICAgaW50IHJlbWFpbmluZ0NhcGFjaXR5KCk7CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGEgc2luZ2xlIGluc3RhbmNlIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBmcm9tIHRoaXMgcXVldWUsCisgICAgICogaWYgaXQgaXMgcHJlc2VudC4gIE1vcmUgZm9ybWFsbHksIHJlbW92ZXMgYW4gZWxlbWVudCA8dHQ+ZTwvdHQ+IHN1Y2gKKyAgICAgKiB0aGF0IDx0dD5vLmVxdWFscyhlKTwvdHQ+LCBpZiB0aGlzIHF1ZXVlIGNvbnRhaW5zIG9uZSBvciBtb3JlIHN1Y2gKKyAgICAgKiBlbGVtZW50cy4KKyAgICAgKiBSZXR1cm5zIDx0dD50cnVlPC90dD4gaWYgdGhpcyBxdWV1ZSBjb250YWluZWQgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICogKG9yIGVxdWl2YWxlbnRseSwgaWYgdGhpcyBxdWV1ZSBjaGFuZ2VkIGFzIGEgcmVzdWx0IG9mIHRoZSBjYWxsKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvIGVsZW1lbnQgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoaXMgcXVldWUsIGlmIHByZXNlbnQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBxdWV1ZSBjaGFuZ2VkIGFzIGEgcmVzdWx0IG9mIHRoZSBjYWxsCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqICAgICAgICAgaXMgaW5jb21wYXRpYmxlIHdpdGggdGhpcyBxdWV1ZSAob3B0aW9uYWwpCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbCAob3B0aW9uYWwpCisgICAgICovCisgICAgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG8pOworCisgICAgLyoqCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgcXVldWUgY29udGFpbnMgdGhlIHNwZWNpZmllZCBlbGVtZW50LgorICAgICAqIE1vcmUgZm9ybWFsbHksIHJldHVybnMgPHR0PnRydWU8L3R0PiBpZiBhbmQgb25seSBpZiB0aGlzIHF1ZXVlIGNvbnRhaW5zCisgICAgICogYXQgbGVhc3Qgb25lIGVsZW1lbnQgPHR0PmU8L3R0PiBzdWNoIHRoYXQgPHR0Pm8uZXF1YWxzKGUpPC90dD4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBvYmplY3QgdG8gYmUgY2hlY2tlZCBmb3IgY29udGFpbm1lbnQgaW4gdGhpcyBxdWV1ZQorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGlzIHF1ZXVlIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKiAgICAgICAgIGlzIGluY29tcGF0aWJsZSB3aXRoIHRoaXMgcXVldWUgKG9wdGlvbmFsKQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwgKG9wdGlvbmFsKQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIGF2YWlsYWJsZSBlbGVtZW50cyBmcm9tIHRoaXMgcXVldWUgYW5kIGFkZHMgdGhlbQorICAgICAqIHRvIHRoZSBnaXZlbiBjb2xsZWN0aW9uLiAgVGhpcyBvcGVyYXRpb24gbWF5IGJlIG1vcmUKKyAgICAgKiBlZmZpY2llbnQgdGhhbiByZXBlYXRlZGx5IHBvbGxpbmcgdGhpcyBxdWV1ZS4gIEEgZmFpbHVyZQorICAgICAqIGVuY291bnRlcmVkIHdoaWxlIGF0dGVtcHRpbmcgdG8gYWRkIGVsZW1lbnRzIHRvCisgICAgICogY29sbGVjdGlvbiA8dHQ+YzwvdHQ+IG1heSByZXN1bHQgaW4gZWxlbWVudHMgYmVpbmcgaW4gbmVpdGhlciwKKyAgICAgKiBlaXRoZXIgb3IgYm90aCBjb2xsZWN0aW9ucyB3aGVuIHRoZSBhc3NvY2lhdGVkIGV4Y2VwdGlvbiBpcworICAgICAqIHRocm93bi4gIEF0dGVtcHRzIHRvIGRyYWluIGEgcXVldWUgdG8gaXRzZWxmIHJlc3VsdCBpbgorICAgICAqIDx0dD5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L3R0Pi4gRnVydGhlciwgdGhlIGJlaGF2aW9yIG9mCisgICAgICogdGhpcyBvcGVyYXRpb24gaXMgdW5kZWZpbmVkIGlmIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiBpcworICAgICAqIG1vZGlmaWVkIHdoaWxlIHRoZSBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYyB0aGUgY29sbGVjdGlvbiB0byB0cmFuc2ZlciBlbGVtZW50cyBpbnRvCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRyYW5zZmVycmVkCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiBhZGRpdGlvbiBvZiBlbGVtZW50cworICAgICAqICAgICAgICAgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3Mgb2YgYW4gZWxlbWVudCBvZiB0aGlzIHF1ZXVlCisgICAgICogICAgICAgICBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGlzIG51bGwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gaXMgdGhpcworICAgICAqICAgICAgICAgcXVldWUsIG9yIHNvbWUgcHJvcGVydHkgb2YgYW4gZWxlbWVudCBvZiB0aGlzIHF1ZXVlIHByZXZlbnRzCisgICAgICogICAgICAgICBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbgorICAgICAqLworICAgIGludCBkcmFpblRvKENvbGxlY3Rpb248PyBzdXBlciBFPiBjKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYXQgbW9zdCB0aGUgZ2l2ZW4gbnVtYmVyIG9mIGF2YWlsYWJsZSBlbGVtZW50cyBmcm9tCisgICAgICogdGhpcyBxdWV1ZSBhbmQgYWRkcyB0aGVtIHRvIHRoZSBnaXZlbiBjb2xsZWN0aW9uLiAgQSBmYWlsdXJlCisgICAgICogZW5jb3VudGVyZWQgd2hpbGUgYXR0ZW1wdGluZyB0byBhZGQgZWxlbWVudHMgdG8KKyAgICAgKiBjb2xsZWN0aW9uIDx0dD5jPC90dD4gbWF5IHJlc3VsdCBpbiBlbGVtZW50cyBiZWluZyBpbiBuZWl0aGVyLAorICAgICAqIGVpdGhlciBvciBib3RoIGNvbGxlY3Rpb25zIHdoZW4gdGhlIGFzc29jaWF0ZWQgZXhjZXB0aW9uIGlzCisgICAgICogdGhyb3duLiAgQXR0ZW1wdHMgdG8gZHJhaW4gYSBxdWV1ZSB0byBpdHNlbGYgcmVzdWx0IGluCisgICAgICogPHR0PklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvdHQ+LiBGdXJ0aGVyLCB0aGUgYmVoYXZpb3Igb2YKKyAgICAgKiB0aGlzIG9wZXJhdGlvbiBpcyB1bmRlZmluZWQgaWYgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGlzCisgICAgICogbW9kaWZpZWQgd2hpbGUgdGhlIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjIHRoZSBjb2xsZWN0aW9uIHRvIHRyYW5zZmVyIGVsZW1lbnRzIGludG8KKyAgICAgKiBAcGFyYW0gbWF4RWxlbWVudHMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGVsZW1lbnRzIHRvIHRyYW5zZmVyCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRyYW5zZmVycmVkCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiBhZGRpdGlvbiBvZiBlbGVtZW50cworICAgICAqICAgICAgICAgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3Mgb2YgYW4gZWxlbWVudCBvZiB0aGlzIHF1ZXVlCisgICAgICogICAgICAgICBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGlzIG51bGwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gaXMgdGhpcworICAgICAqICAgICAgICAgcXVldWUsIG9yIHNvbWUgcHJvcGVydHkgb2YgYW4gZWxlbWVudCBvZiB0aGlzIHF1ZXVlIHByZXZlbnRzCisgICAgICogICAgICAgICBpdCBmcm9tIGJlaW5nIGFkZGVkIHRvIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbgorICAgICAqLworICAgIGludCBkcmFpblRvKENvbGxlY3Rpb248PyBzdXBlciBFPiBjLCBpbnQgbWF4RWxlbWVudHMpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0Jyb2tlbkJhcnJpZXJFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Ccm9rZW5CYXJyaWVyRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2Y5M2ZiYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Ccm9rZW5CYXJyaWVyRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzOCBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50OworCisvKioKKyAqIEV4Y2VwdGlvbiB0aHJvd24gd2hlbiBhIHRocmVhZCB0cmllcyB0byB3YWl0IHVwb24gYSBiYXJyaWVyIHRoYXQgaXMKKyAqIGluIGEgYnJva2VuIHN0YXRlLCBvciB3aGljaCBlbnRlcnMgdGhlIGJyb2tlbiBzdGF0ZSB3aGlsZSB0aGUgdGhyZWFkCisgKiBpcyB3YWl0aW5nLgorICoKKyAqIEBzZWUgQ3ljbGljQmFycmllcgorICoKKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBCcm9rZW5CYXJyaWVyRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3MTE3Mzk0NjE4ODIzMjU0MjQ0TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSA8dHQ+QnJva2VuQmFycmllckV4Y2VwdGlvbjwvdHQ+IHdpdGggbm8gc3BlY2lmaWVkIGRldGFpbAorICAgICAqIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIEJyb2tlbkJhcnJpZXJFeGNlcHRpb24oKSB7fQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIDx0dD5Ccm9rZW5CYXJyaWVyRXhjZXB0aW9uPC90dD4gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZSB0aGUgZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgQnJva2VuQmFycmllckV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQ2FsbGFibGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9DYWxsYWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiYzRkMDQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQ2FsbGFibGUuamF2YQpAQCAtMCwwICsxLDM2IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CisKKy8qKgorICogQSB0YXNrIHRoYXQgcmV0dXJucyBhIHJlc3VsdCBhbmQgbWF5IHRocm93IGFuIGV4Y2VwdGlvbi4KKyAqIEltcGxlbWVudG9ycyBkZWZpbmUgYSBzaW5nbGUgbWV0aG9kIHdpdGggbm8gYXJndW1lbnRzIGNhbGxlZAorICogPHR0PmNhbGw8L3R0Pi4KKyAqCisgKiA8cD5UaGUgPHR0PkNhbGxhYmxlPC90dD4gaW50ZXJmYWNlIGlzIHNpbWlsYXIgdG8ge0BsaW5rCisgKiBqYXZhLmxhbmcuUnVubmFibGV9LCBpbiB0aGF0IGJvdGggYXJlIGRlc2lnbmVkIGZvciBjbGFzc2VzIHdob3NlCisgKiBpbnN0YW5jZXMgYXJlIHBvdGVudGlhbGx5IGV4ZWN1dGVkIGJ5IGFub3RoZXIgdGhyZWFkLiAgQQorICogPHR0PlJ1bm5hYmxlPC90dD4sIGhvd2V2ZXIsIGRvZXMgbm90IHJldHVybiBhIHJlc3VsdCBhbmQgY2Fubm90CisgKiB0aHJvdyBhIGNoZWNrZWQgZXhjZXB0aW9uLgorICoKKyAqIDxwPiBUaGUge0BsaW5rIEV4ZWN1dG9yc30gY2xhc3MgY29udGFpbnMgdXRpbGl0eSBtZXRob2RzIHRvCisgKiBjb252ZXJ0IGZyb20gb3RoZXIgY29tbW9uIGZvcm1zIHRvIDx0dD5DYWxsYWJsZTwvdHQ+IGNsYXNzZXMuCisgKgorICogQHNlZSBFeGVjdXRvcgorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICogQHBhcmFtIDxWPiB0aGUgcmVzdWx0IHR5cGUgb2YgbWV0aG9kIDx0dD5jYWxsPC90dD4KKyAqLworcHVibGljIGludGVyZmFjZSBDYWxsYWJsZTxWPiB7CisgICAgLyoqCisgICAgICogQ29tcHV0ZXMgYSByZXN1bHQsIG9yIHRocm93cyBhbiBleGNlcHRpb24gaWYgdW5hYmxlIHRvIGRvIHNvLgorICAgICAqCisgICAgICogQHJldHVybiBjb21wdXRlZCByZXN1bHQKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbiBpZiB1bmFibGUgdG8gY29tcHV0ZSBhIHJlc3VsdAorICAgICAqLworICAgIFYgY2FsbCgpIHRocm93cyBFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQ2FuY2VsbGF0aW9uRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQ2FuY2VsbGF0aW9uRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmMyOTU0NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9DYW5jZWxsYXRpb25FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDM0IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CisKKy8qKgorICogRXhjZXB0aW9uIGluZGljYXRpbmcgdGhhdCB0aGUgcmVzdWx0IG9mIGEgdmFsdWUtcHJvZHVjaW5nIHRhc2ssCisgKiBzdWNoIGFzIGEge0BsaW5rIEZ1dHVyZVRhc2t9LCBjYW5ub3QgYmUgcmV0cmlldmVkIGJlY2F1c2UgdGhlIHRhc2sKKyAqIHdhcyBjYW5jZWxsZWQuCisgKgorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICovCitwdWJsaWMgY2xhc3MgQ2FuY2VsbGF0aW9uRXhjZXB0aW9uIGV4dGVuZHMgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtOTIwMjE3MzAwNjkyODk5MjIzMUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgPHR0PkNhbmNlbGxhdGlvbkV4Y2VwdGlvbjwvdHQ+IHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIENhbmNlbGxhdGlvbkV4Y2VwdGlvbigpIHt9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgPHR0PkNhbmNlbGxhdGlvbkV4Y2VwdGlvbjwvdHQ+IHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwKKyAgICAgKiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UgdGhlIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIENhbmNlbGxhdGlvbkV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQ29tcGxldGlvblNlcnZpY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Db21wbGV0aW9uU2VydmljZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmOWY3MTkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQ29tcGxldGlvblNlcnZpY2UuamF2YQpAQCAtMCwwICsxLDk3IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CisKKy8qKgorICogQSBzZXJ2aWNlIHRoYXQgZGVjb3VwbGVzIHRoZSBwcm9kdWN0aW9uIG9mIG5ldyBhc3luY2hyb25vdXMgdGFza3MKKyAqIGZyb20gdGhlIGNvbnN1bXB0aW9uIG9mIHRoZSByZXN1bHRzIG9mIGNvbXBsZXRlZCB0YXNrcy4gIFByb2R1Y2VycworICogPHR0PnN1Ym1pdDwvdHQ+IHRhc2tzIGZvciBleGVjdXRpb24uIENvbnN1bWVycyA8dHQ+dGFrZTwvdHQ+CisgKiBjb21wbGV0ZWQgdGFza3MgYW5kIHByb2Nlc3MgdGhlaXIgcmVzdWx0cyBpbiB0aGUgb3JkZXIgdGhleQorICogY29tcGxldGUuICBBIDx0dD5Db21wbGV0aW9uU2VydmljZTwvdHQ+IGNhbiBmb3IgZXhhbXBsZSBiZSB1c2VkIHRvCisgKiBtYW5hZ2UgYXN5bmNocm9ub3VzIElPLCBpbiB3aGljaCB0YXNrcyB0aGF0IHBlcmZvcm0gcmVhZHMgYXJlCisgKiBzdWJtaXR0ZWQgaW4gb25lIHBhcnQgb2YgYSBwcm9ncmFtIG9yIHN5c3RlbSwgYW5kIHRoZW4gYWN0ZWQgdXBvbgorICogaW4gYSBkaWZmZXJlbnQgcGFydCBvZiB0aGUgcHJvZ3JhbSB3aGVuIHRoZSByZWFkcyBjb21wbGV0ZSwKKyAqIHBvc3NpYmx5IGluIGEgZGlmZmVyZW50IG9yZGVyIHRoYW4gdGhleSB3ZXJlIHJlcXVlc3RlZC4KKyAqCisgKiA8cD5UeXBpY2FsbHksIGEgPHR0PkNvbXBsZXRpb25TZXJ2aWNlPC90dD4gcmVsaWVzIG9uIGEgc2VwYXJhdGUKKyAqIHtAbGluayBFeGVjdXRvcn0gdG8gYWN0dWFsbHkgZXhlY3V0ZSB0aGUgdGFza3MsIGluIHdoaWNoIGNhc2UgdGhlCisgKiA8dHQ+Q29tcGxldGlvblNlcnZpY2U8L3R0PiBvbmx5IG1hbmFnZXMgYW4gaW50ZXJuYWwgY29tcGxldGlvbgorICogcXVldWUuIFRoZSB7QGxpbmsgRXhlY3V0b3JDb21wbGV0aW9uU2VydmljZX0gY2xhc3MgcHJvdmlkZXMgYW4KKyAqIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgYXBwcm9hY2guCisgKgorICogPHA+TWVtb3J5IGNvbnNpc3RlbmN5IGVmZmVjdHM6IEFjdGlvbnMgaW4gYSB0aHJlYWQgcHJpb3IgdG8KKyAqIHN1Ym1pdHRpbmcgYSB0YXNrIHRvIGEge0Bjb2RlIENvbXBsZXRpb25TZXJ2aWNlfQorICogPGEgaHJlZj0icGFja2FnZS1zdW1tYXJ5Lmh0bWwjTWVtb3J5VmlzaWJpbGl0eSI+PGk+aGFwcGVuLWJlZm9yZTwvaT48L2E+CisgKiBhY3Rpb25zIHRha2VuIGJ5IHRoYXQgdGFzaywgd2hpY2ggaW4gdHVybiA8aT5oYXBwZW4tYmVmb3JlPC9pPgorICogYWN0aW9ucyBmb2xsb3dpbmcgYSBzdWNjZXNzZnVsIHJldHVybiBmcm9tIHRoZSBjb3JyZXNwb25kaW5nIHtAY29kZSB0YWtlKCl9LgorICoKKyAqLworcHVibGljIGludGVyZmFjZSBDb21wbGV0aW9uU2VydmljZTxWPiB7CisgICAgLyoqCisgICAgICogU3VibWl0cyBhIHZhbHVlLXJldHVybmluZyB0YXNrIGZvciBleGVjdXRpb24gYW5kIHJldHVybnMgYSBGdXR1cmUKKyAgICAgKiByZXByZXNlbnRpbmcgdGhlIHBlbmRpbmcgcmVzdWx0cyBvZiB0aGUgdGFzay4gIFVwb24gY29tcGxldGlvbiwKKyAgICAgKiB0aGlzIHRhc2sgbWF5IGJlIHRha2VuIG9yIHBvbGxlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YXNrIHRoZSB0YXNrIHRvIHN1Ym1pdAorICAgICAqIEByZXR1cm4gYSBGdXR1cmUgcmVwcmVzZW50aW5nIHBlbmRpbmcgY29tcGxldGlvbiBvZiB0aGUgdGFzaworICAgICAqIEB0aHJvd3MgUmVqZWN0ZWRFeGVjdXRpb25FeGNlcHRpb24gaWYgdGhlIHRhc2sgY2Fubm90IGJlCisgICAgICogICAgICAgICBzY2hlZHVsZWQgZm9yIGV4ZWN1dGlvbgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHRhc2sgaXMgbnVsbAorICAgICAqLworICAgIEZ1dHVyZTxWPiBzdWJtaXQoQ2FsbGFibGU8Vj4gdGFzayk7CisKKyAgICAvKioKKyAgICAgKiBTdWJtaXRzIGEgUnVubmFibGUgdGFzayBmb3IgZXhlY3V0aW9uIGFuZCByZXR1cm5zIGEgRnV0dXJlCisgICAgICogcmVwcmVzZW50aW5nIHRoYXQgdGFzay4gIFVwb24gY29tcGxldGlvbiwgdGhpcyB0YXNrIG1heSBiZQorICAgICAqIHRha2VuIG9yIHBvbGxlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YXNrIHRoZSB0YXNrIHRvIHN1Ym1pdAorICAgICAqIEBwYXJhbSByZXN1bHQgdGhlIHJlc3VsdCB0byByZXR1cm4gdXBvbiBzdWNjZXNzZnVsIGNvbXBsZXRpb24KKyAgICAgKiBAcmV0dXJuIGEgRnV0dXJlIHJlcHJlc2VudGluZyBwZW5kaW5nIGNvbXBsZXRpb24gb2YgdGhlIHRhc2ssCisgICAgICogICAgICAgICBhbmQgd2hvc2UgPHR0PmdldCgpPC90dD4gbWV0aG9kIHdpbGwgcmV0dXJuIHRoZSBnaXZlbgorICAgICAqICAgICAgICAgcmVzdWx0IHZhbHVlIHVwb24gY29tcGxldGlvbgorICAgICAqIEB0aHJvd3MgUmVqZWN0ZWRFeGVjdXRpb25FeGNlcHRpb24gaWYgdGhlIHRhc2sgY2Fubm90IGJlCisgICAgICogICAgICAgICBzY2hlZHVsZWQgZm9yIGV4ZWN1dGlvbgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHRhc2sgaXMgbnVsbAorICAgICAqLworICAgIEZ1dHVyZTxWPiBzdWJtaXQoUnVubmFibGUgdGFzaywgViByZXN1bHQpOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGFuZCByZW1vdmVzIHRoZSBGdXR1cmUgcmVwcmVzZW50aW5nIHRoZSBuZXh0CisgICAgICogY29tcGxldGVkIHRhc2ssIHdhaXRpbmcgaWYgbm9uZSBhcmUgeWV0IHByZXNlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBGdXR1cmUgcmVwcmVzZW50aW5nIHRoZSBuZXh0IGNvbXBsZXRlZCB0YXNrCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiBpbnRlcnJ1cHRlZCB3aGlsZSB3YWl0aW5nCisgICAgICovCisgICAgRnV0dXJlPFY+IHRha2UoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhbmQgcmVtb3ZlcyB0aGUgRnV0dXJlIHJlcHJlc2VudGluZyB0aGUgbmV4dAorICAgICAqIGNvbXBsZXRlZCB0YXNrIG9yIDx0dD5udWxsPC90dD4gaWYgbm9uZSBhcmUgcHJlc2VudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIEZ1dHVyZSByZXByZXNlbnRpbmcgdGhlIG5leHQgY29tcGxldGVkIHRhc2ssIG9yCisgICAgICogICAgICAgICA8dHQ+bnVsbDwvdHQ+IGlmIG5vbmUgYXJlIHByZXNlbnQKKyAgICAgKi8KKyAgICBGdXR1cmU8Vj4gcG9sbCgpOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGFuZCByZW1vdmVzIHRoZSBGdXR1cmUgcmVwcmVzZW50aW5nIHRoZSBuZXh0CisgICAgICogY29tcGxldGVkIHRhc2ssIHdhaXRpbmcgaWYgbmVjZXNzYXJ5IHVwIHRvIHRoZSBzcGVjaWZpZWQgd2FpdAorICAgICAqIHRpbWUgaWYgbm9uZSBhcmUgeWV0IHByZXNlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGltZW91dCBob3cgbG9uZyB0byB3YWl0IGJlZm9yZSBnaXZpbmcgdXAsIGluIHVuaXRzIG9mCisgICAgICogICAgICAgIDx0dD51bml0PC90dD4KKyAgICAgKiBAcGFyYW0gdW5pdCBhIDx0dD5UaW1lVW5pdDwvdHQ+IGRldGVybWluaW5nIGhvdyB0byBpbnRlcnByZXQgdGhlCisgICAgICogICAgICAgIDx0dD50aW1lb3V0PC90dD4gcGFyYW1ldGVyCisgICAgICogQHJldHVybiB0aGUgRnV0dXJlIHJlcHJlc2VudGluZyB0aGUgbmV4dCBjb21wbGV0ZWQgdGFzayBvcgorICAgICAqICAgICAgICAgPHR0Pm51bGw8L3R0PiBpZiB0aGUgc3BlY2lmaWVkIHdhaXRpbmcgdGltZSBlbGFwc2VzCisgICAgICogICAgICAgICBiZWZvcmUgb25lIGlzIHByZXNlbnQKKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIGludGVycnVwdGVkIHdoaWxlIHdhaXRpbmcKKyAgICAgKi8KKyAgICBGdXR1cmU8Vj4gcG9sbChsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Db25jdXJyZW50SGFzaE1hcC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0NvbmN1cnJlbnRIYXNoTWFwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzE0MmUyYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Db25jdXJyZW50SGFzaE1hcC5qYXZhCkBAIC0wLDAgKzEsMTI4OSBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLio7CitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworCisvLyBCRUdJTiBhbmRyb2lkLW5vdGUKKy8vIHJlbW92ZWQgbGluayB0byBjb2xsZWN0aW9ucyBmcmFtZXdvcmsgZG9jcworLy8gRU5EIGFuZHJvaWQtbm90ZQorCisvKioKKyAqIEEgaGFzaCB0YWJsZSBzdXBwb3J0aW5nIGZ1bGwgY29uY3VycmVuY3kgb2YgcmV0cmlldmFscyBhbmQKKyAqIGFkanVzdGFibGUgZXhwZWN0ZWQgY29uY3VycmVuY3kgZm9yIHVwZGF0ZXMuIFRoaXMgY2xhc3Mgb2JleXMgdGhlCisgKiBzYW1lIGZ1bmN0aW9uYWwgc3BlY2lmaWNhdGlvbiBhcyB7QGxpbmsgamF2YS51dGlsLkhhc2h0YWJsZX0sIGFuZAorICogaW5jbHVkZXMgdmVyc2lvbnMgb2YgbWV0aG9kcyBjb3JyZXNwb25kaW5nIHRvIGVhY2ggbWV0aG9kIG9mCisgKiA8dHQ+SGFzaHRhYmxlPC90dD4uIEhvd2V2ZXIsIGV2ZW4gdGhvdWdoIGFsbCBvcGVyYXRpb25zIGFyZQorICogdGhyZWFkLXNhZmUsIHJldHJpZXZhbCBvcGVyYXRpb25zIGRvIDxlbT5ub3Q8L2VtPiBlbnRhaWwgbG9ja2luZywKKyAqIGFuZCB0aGVyZSBpcyA8ZW0+bm90PC9lbT4gYW55IHN1cHBvcnQgZm9yIGxvY2tpbmcgdGhlIGVudGlyZSB0YWJsZQorICogaW4gYSB3YXkgdGhhdCBwcmV2ZW50cyBhbGwgYWNjZXNzLiAgVGhpcyBjbGFzcyBpcyBmdWxseQorICogaW50ZXJvcGVyYWJsZSB3aXRoIDx0dD5IYXNodGFibGU8L3R0PiBpbiBwcm9ncmFtcyB0aGF0IHJlbHkgb24gaXRzCisgKiB0aHJlYWQgc2FmZXR5IGJ1dCBub3Qgb24gaXRzIHN5bmNocm9uaXphdGlvbiBkZXRhaWxzLgorICoKKyAqIDxwPiBSZXRyaWV2YWwgb3BlcmF0aW9ucyAoaW5jbHVkaW5nIDx0dD5nZXQ8L3R0PikgZ2VuZXJhbGx5IGRvIG5vdAorICogYmxvY2ssIHNvIG1heSBvdmVybGFwIHdpdGggdXBkYXRlIG9wZXJhdGlvbnMgKGluY2x1ZGluZworICogPHR0PnB1dDwvdHQ+IGFuZCA8dHQ+cmVtb3ZlPC90dD4pLiBSZXRyaWV2YWxzIHJlZmxlY3QgdGhlIHJlc3VsdHMKKyAqIG9mIHRoZSBtb3N0IHJlY2VudGx5IDxlbT5jb21wbGV0ZWQ8L2VtPiB1cGRhdGUgb3BlcmF0aW9ucyBob2xkaW5nCisgKiB1cG9uIHRoZWlyIG9uc2V0LiAgRm9yIGFnZ3JlZ2F0ZSBvcGVyYXRpb25zIHN1Y2ggYXMgPHR0PnB1dEFsbDwvdHQ+CisgKiBhbmQgPHR0PmNsZWFyPC90dD4sIGNvbmN1cnJlbnQgcmV0cmlldmFscyBtYXkgcmVmbGVjdCBpbnNlcnRpb24gb3IKKyAqIHJlbW92YWwgb2Ygb25seSBzb21lIGVudHJpZXMuICBTaW1pbGFybHksIEl0ZXJhdG9ycyBhbmQKKyAqIEVudW1lcmF0aW9ucyByZXR1cm4gZWxlbWVudHMgcmVmbGVjdGluZyB0aGUgc3RhdGUgb2YgdGhlIGhhc2ggdGFibGUKKyAqIGF0IHNvbWUgcG9pbnQgYXQgb3Igc2luY2UgdGhlIGNyZWF0aW9uIG9mIHRoZSBpdGVyYXRvci9lbnVtZXJhdGlvbi4KKyAqIFRoZXkgZG8gPGVtPm5vdDwvZW0+IHRocm93IHtAbGluayBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9ufS4KKyAqIEhvd2V2ZXIsIGl0ZXJhdG9ycyBhcmUgZGVzaWduZWQgdG8gYmUgdXNlZCBieSBvbmx5IG9uZSB0aHJlYWQgYXQgYSB0aW1lLgorICoKKyAqIDxwPiBUaGUgYWxsb3dlZCBjb25jdXJyZW5jeSBhbW9uZyB1cGRhdGUgb3BlcmF0aW9ucyBpcyBndWlkZWQgYnkKKyAqIHRoZSBvcHRpb25hbCA8dHQ+Y29uY3VycmVuY3lMZXZlbDwvdHQ+IGNvbnN0cnVjdG9yIGFyZ3VtZW50CisgKiAoZGVmYXVsdCA8dHQ+MTY8L3R0PiksIHdoaWNoIGlzIHVzZWQgYXMgYSBoaW50IGZvciBpbnRlcm5hbCBzaXppbmcuICBUaGUKKyAqIHRhYmxlIGlzIGludGVybmFsbHkgcGFydGl0aW9uZWQgdG8gdHJ5IHRvIHBlcm1pdCB0aGUgaW5kaWNhdGVkCisgKiBudW1iZXIgb2YgY29uY3VycmVudCB1cGRhdGVzIHdpdGhvdXQgY29udGVudGlvbi4gQmVjYXVzZSBwbGFjZW1lbnQKKyAqIGluIGhhc2ggdGFibGVzIGlzIGVzc2VudGlhbGx5IHJhbmRvbSwgdGhlIGFjdHVhbCBjb25jdXJyZW5jeSB3aWxsCisgKiB2YXJ5LiAgSWRlYWxseSwgeW91IHNob3VsZCBjaG9vc2UgYSB2YWx1ZSB0byBhY2NvbW1vZGF0ZSBhcyBtYW55CisgKiB0aHJlYWRzIGFzIHdpbGwgZXZlciBjb25jdXJyZW50bHkgbW9kaWZ5IHRoZSB0YWJsZS4gVXNpbmcgYQorICogc2lnbmlmaWNhbnRseSBoaWdoZXIgdmFsdWUgdGhhbiB5b3UgbmVlZCBjYW4gd2FzdGUgc3BhY2UgYW5kIHRpbWUsCisgKiBhbmQgYSBzaWduaWZpY2FudGx5IGxvd2VyIHZhbHVlIGNhbiBsZWFkIHRvIHRocmVhZCBjb250ZW50aW9uLiBCdXQKKyAqIG92ZXJlc3RpbWF0ZXMgYW5kIHVuZGVyZXN0aW1hdGVzIHdpdGhpbiBhbiBvcmRlciBvZiBtYWduaXR1ZGUgZG8KKyAqIG5vdCB1c3VhbGx5IGhhdmUgbXVjaCBub3RpY2VhYmxlIGltcGFjdC4gQSB2YWx1ZSBvZiBvbmUgaXMKKyAqIGFwcHJvcHJpYXRlIHdoZW4gaXQgaXMga25vd24gdGhhdCBvbmx5IG9uZSB0aHJlYWQgd2lsbCBtb2RpZnkgYW5kCisgKiBhbGwgb3RoZXJzIHdpbGwgb25seSByZWFkLiBBbHNvLCByZXNpemluZyB0aGlzIG9yIGFueSBvdGhlciBraW5kIG9mCisgKiBoYXNoIHRhYmxlIGlzIGEgcmVsYXRpdmVseSBzbG93IG9wZXJhdGlvbiwgc28sIHdoZW4gcG9zc2libGUsIGl0IGlzCisgKiBhIGdvb2QgaWRlYSB0byBwcm92aWRlIGVzdGltYXRlcyBvZiBleHBlY3RlZCB0YWJsZSBzaXplcyBpbgorICogY29uc3RydWN0b3JzLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgYW5kIGl0cyB2aWV3cyBhbmQgaXRlcmF0b3JzIGltcGxlbWVudCBhbGwgb2YgdGhlCisgKiA8ZW0+b3B0aW9uYWw8L2VtPiBtZXRob2RzIG9mIHRoZSB7QGxpbmsgTWFwfSBhbmQge0BsaW5rIEl0ZXJhdG9yfQorICogaW50ZXJmYWNlcy4KKyAqCisgKiA8cD4gTGlrZSB7QGxpbmsgSGFzaHRhYmxlfSBidXQgdW5saWtlIHtAbGluayBIYXNoTWFwfSwgdGhpcyBjbGFzcworICogZG9lcyA8ZW0+bm90PC9lbT4gYWxsb3cgPHR0Pm51bGw8L3R0PiB0byBiZSB1c2VkIGFzIGEga2V5IG9yIHZhbHVlLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqIEBwYXJhbSA8Sz4gdGhlIHR5cGUgb2Yga2V5cyBtYWludGFpbmVkIGJ5IHRoaXMgbWFwCisgKiBAcGFyYW0gPFY+IHRoZSB0eXBlIG9mIG1hcHBlZCB2YWx1ZXMKKyAqLworcHVibGljIGNsYXNzIENvbmN1cnJlbnRIYXNoTWFwPEssIFY+IGV4dGVuZHMgQWJzdHJhY3RNYXA8SywgVj4KKyAgICAgICAgaW1wbGVtZW50cyBDb25jdXJyZW50TWFwPEssIFY+LCBTZXJpYWxpemFibGUgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDcyNDkwNjkyNDY3NjMxODIzOTdMOworCisgICAgLyoKKyAgICAgKiBUaGUgYmFzaWMgc3RyYXRlZ3kgaXMgdG8gc3ViZGl2aWRlIHRoZSB0YWJsZSBhbW9uZyBTZWdtZW50cywKKyAgICAgKiBlYWNoIG9mIHdoaWNoIGl0c2VsZiBpcyBhIGNvbmN1cnJlbnRseSByZWFkYWJsZSBoYXNoIHRhYmxlLgorICAgICAqLworCisgICAgLyogLS0tLS0tLS0tLS0tLS0tLSBDb25zdGFudHMgLS0tLS0tLS0tLS0tLS0gKi8KKworICAgIC8qKgorICAgICAqIFRoZSBkZWZhdWx0IGluaXRpYWwgY2FwYWNpdHkgZm9yIHRoaXMgdGFibGUsCisgICAgICogdXNlZCB3aGVuIG5vdCBvdGhlcndpc2Ugc3BlY2lmaWVkIGluIGEgY29uc3RydWN0b3IuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0lOSVRJQUxfQ0FQQUNJVFkgPSAxNjsKKworICAgIC8qKgorICAgICAqIFRoZSBkZWZhdWx0IGxvYWQgZmFjdG9yIGZvciB0aGlzIHRhYmxlLCB1c2VkIHdoZW4gbm90CisgICAgICogb3RoZXJ3aXNlIHNwZWNpZmllZCBpbiBhIGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBmbG9hdCBERUZBVUxUX0xPQURfRkFDVE9SID0gMC43NWY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGVmYXVsdCBjb25jdXJyZW5jeSBsZXZlbCBmb3IgdGhpcyB0YWJsZSwgdXNlZCB3aGVuIG5vdAorICAgICAqIG90aGVyd2lzZSBzcGVjaWZpZWQgaW4gYSBjb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfQ09OQ1VSUkVOQ1lfTEVWRUwgPSAxNjsKKworICAgIC8qKgorICAgICAqIFRoZSBtYXhpbXVtIGNhcGFjaXR5LCB1c2VkIGlmIGEgaGlnaGVyIHZhbHVlIGlzIGltcGxpY2l0bHkKKyAgICAgKiBzcGVjaWZpZWQgYnkgZWl0aGVyIG9mIHRoZSBjb25zdHJ1Y3RvcnMgd2l0aCBhcmd1bWVudHMuICBNVVNUCisgICAgICogYmUgYSBwb3dlciBvZiB0d28gPD0gMTw8MzAgdG8gZW5zdXJlIHRoYXQgZW50cmllcyBhcmUgaW5kZXhhYmxlCisgICAgICogdXNpbmcgaW50cy4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgaW50IE1BWElNVU1fQ0FQQUNJVFkgPSAxIDw8IDMwOworCisgICAgLyoqCisgICAgICogVGhlIG1heGltdW0gbnVtYmVyIG9mIHNlZ21lbnRzIHRvIGFsbG93OyB1c2VkIHRvIGJvdW5kCisgICAgICogY29uc3RydWN0b3IgYXJndW1lbnRzLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1NFR01FTlRTID0gMSA8PCAxNjsgLy8gc2xpZ2h0bHkgY29uc2VydmF0aXZlCisKKyAgICAvKioKKyAgICAgKiBOdW1iZXIgb2YgdW5zeW5jaHJvbml6ZWQgcmV0cmllcyBpbiBzaXplIGFuZCBjb250YWluc1ZhbHVlCisgICAgICogbWV0aG9kcyBiZWZvcmUgcmVzb3J0aW5nIHRvIGxvY2tpbmcuIFRoaXMgaXMgdXNlZCB0byBhdm9pZAorICAgICAqIHVuYm91bmRlZCByZXRyaWVzIGlmIHRhYmxlcyB1bmRlcmdvIGNvbnRpbnVvdXMgbW9kaWZpY2F0aW9uCisgICAgICogd2hpY2ggd291bGQgbWFrZSBpdCBpbXBvc3NpYmxlIHRvIG9idGFpbiBhbiBhY2N1cmF0ZSByZXN1bHQuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGludCBSRVRSSUVTX0JFRk9SRV9MT0NLID0gMjsKKworICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0gRmllbGRzIC0tLS0tLS0tLS0tLS0tICovCisKKyAgICAvKioKKyAgICAgKiBNYXNrIHZhbHVlIGZvciBpbmRleGluZyBpbnRvIHNlZ21lbnRzLiBUaGUgdXBwZXIgYml0cyBvZiBhCisgICAgICoga2V5J3MgaGFzaCBjb2RlIGFyZSB1c2VkIHRvIGNob29zZSB0aGUgc2VnbWVudC4KKyAgICAgKi8KKyAgICBmaW5hbCBpbnQgc2VnbWVudE1hc2s7CisKKyAgICAvKioKKyAgICAgKiBTaGlmdCB2YWx1ZSBmb3IgaW5kZXhpbmcgd2l0aGluIHNlZ21lbnRzLgorICAgICAqLworICAgIGZpbmFsIGludCBzZWdtZW50U2hpZnQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc2VnbWVudHMsIGVhY2ggb2Ygd2hpY2ggaXMgYSBzcGVjaWFsaXplZCBoYXNoIHRhYmxlCisgICAgICovCisgICAgZmluYWwgU2VnbWVudDxLLFY+W10gc2VnbWVudHM7CisKKyAgICB0cmFuc2llbnQgU2V0PEs+IGtleVNldDsKKyAgICB0cmFuc2llbnQgU2V0PE1hcC5FbnRyeTxLLFY+PiBlbnRyeVNldDsKKyAgICB0cmFuc2llbnQgQ29sbGVjdGlvbjxWPiB2YWx1ZXM7CisKKyAgICAvKiAtLS0tLS0tLS0tLS0tLS0tIFNtYWxsIFV0aWxpdGllcyAtLS0tLS0tLS0tLS0tLSAqLworCisgICAgLyoqCisgICAgICogQXBwbGllcyBhIHN1cHBsZW1lbnRhbCBoYXNoIGZ1bmN0aW9uIHRvIGEgZ2l2ZW4gaGFzaENvZGUsIHdoaWNoCisgICAgICogZGVmZW5kcyBhZ2FpbnN0IHBvb3IgcXVhbGl0eSBoYXNoIGZ1bmN0aW9ucy4gIFRoaXMgaXMgY3JpdGljYWwKKyAgICAgKiBiZWNhdXNlIENvbmN1cnJlbnRIYXNoTWFwIHVzZXMgcG93ZXItb2YtdHdvIGxlbmd0aCBoYXNoIHRhYmxlcywKKyAgICAgKiB0aGF0IG90aGVyd2lzZSBlbmNvdW50ZXIgY29sbGlzaW9ucyBmb3IgaGFzaENvZGVzIHRoYXQgZG8gbm90CisgICAgICogZGlmZmVyIGluIGxvd2VyIG9yIHVwcGVyIGJpdHMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGhhc2goaW50IGgpIHsKKyAgICAgICAgLy8gU3ByZWFkIGJpdHMgdG8gcmVndWxhcml6ZSBib3RoIHNlZ21lbnQgYW5kIGluZGV4IGxvY2F0aW9ucywKKyAgICAgICAgLy8gdXNpbmcgdmFyaWFudCBvZiBzaW5nbGUtd29yZCBXYW5nL0plbmtpbnMgaGFzaC4KKyAgICAgICAgaCArPSAoaCA8PCAgMTUpIF4gMHhmZmZmY2Q3ZDsKKyAgICAgICAgaCBePSAoaCA+Pj4gMTApOworICAgICAgICBoICs9IChoIDw8ICAgMyk7CisgICAgICAgIGggXj0gKGggPj4+ICA2KTsKKyAgICAgICAgaCArPSAoaCA8PCAgIDIpICsgKGggPDwgMTQpOworICAgICAgICByZXR1cm4gaCBeIChoID4+PiAxNik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2VnbWVudCB0aGF0IHNob3VsZCBiZSB1c2VkIGZvciBrZXkgd2l0aCBnaXZlbiBoYXNoCisgICAgICogQHBhcmFtIGhhc2ggdGhlIGhhc2ggY29kZSBmb3IgdGhlIGtleQorICAgICAqIEByZXR1cm4gdGhlIHNlZ21lbnQKKyAgICAgKi8KKyAgICBmaW5hbCBTZWdtZW50PEssVj4gc2VnbWVudEZvcihpbnQgaGFzaCkgeworICAgICAgICByZXR1cm4gc2VnbWVudHNbKGhhc2ggPj4+IHNlZ21lbnRTaGlmdCkgJiBzZWdtZW50TWFza107CisgICAgfQorCisgICAgLyogLS0tLS0tLS0tLS0tLS0tLSBJbm5lciBDbGFzc2VzIC0tLS0tLS0tLS0tLS0tICovCisKKyAgICAvKioKKyAgICAgKiBDb25jdXJyZW50SGFzaE1hcCBsaXN0IGVudHJ5LiBOb3RlIHRoYXQgdGhpcyBpcyBuZXZlciBleHBvcnRlZAorICAgICAqIG91dCBhcyBhIHVzZXItdmlzaWJsZSBNYXAuRW50cnkuCisgICAgICoKKyAgICAgKiBCZWNhdXNlIHRoZSB2YWx1ZSBmaWVsZCBpcyB2b2xhdGlsZSwgbm90IGZpbmFsLCBpdCBpcyBsZWdhbCB3cnQKKyAgICAgKiB0aGUgSmF2YSBNZW1vcnkgTW9kZWwgZm9yIGFuIHVuc3luY2hyb25pemVkIHJlYWRlciB0byBzZWUgbnVsbAorICAgICAqIGluc3RlYWQgb2YgaW5pdGlhbCB2YWx1ZSB3aGVuIHJlYWQgdmlhIGEgZGF0YSByYWNlLiAgQWx0aG91Z2ggYQorICAgICAqIHJlb3JkZXJpbmcgbGVhZGluZyB0byB0aGlzIGlzIG5vdCBsaWtlbHkgdG8gZXZlciBhY3R1YWxseQorICAgICAqIG9jY3VyLCB0aGUgU2VnbWVudC5yZWFkVmFsdWVVbmRlckxvY2sgbWV0aG9kIGlzIHVzZWQgYXMgYQorICAgICAqIGJhY2t1cCBpbiBjYXNlIGEgbnVsbCAocHJlLWluaXRpYWxpemVkKSB2YWx1ZSBpcyBldmVyIHNlZW4gaW4KKyAgICAgKiBhbiB1bnN5bmNocm9uaXplZCBhY2Nlc3MgbWV0aG9kLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBIYXNoRW50cnk8SyxWPiB7CisgICAgICAgIGZpbmFsIEsga2V5OworICAgICAgICBmaW5hbCBpbnQgaGFzaDsKKyAgICAgICAgdm9sYXRpbGUgViB2YWx1ZTsKKyAgICAgICAgZmluYWwgSGFzaEVudHJ5PEssVj4gbmV4dDsKKworICAgICAgICBIYXNoRW50cnkoSyBrZXksIGludCBoYXNoLCBIYXNoRW50cnk8SyxWPiBuZXh0LCBWIHZhbHVlKSB7CisgICAgICAgICAgICB0aGlzLmtleSA9IGtleTsKKyAgICAgICAgICAgIHRoaXMuaGFzaCA9IGhhc2g7CisgICAgICAgICAgICB0aGlzLm5leHQgPSBuZXh0OworICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgICAgIHN0YXRpYyBmaW5hbCA8SyxWPiBIYXNoRW50cnk8SyxWPltdIG5ld0FycmF5KGludCBpKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEhhc2hFbnRyeVtpXTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNlZ21lbnRzIGFyZSBzcGVjaWFsaXplZCB2ZXJzaW9ucyBvZiBoYXNoIHRhYmxlcy4gIFRoaXMKKyAgICAgKiBzdWJjbGFzc2VzIGZyb20gUmVlbnRyYW50TG9jayBvcHBvcnR1bmlzdGljYWxseSwganVzdCB0bworICAgICAqIHNpbXBsaWZ5IHNvbWUgbG9ja2luZyBhbmQgYXZvaWQgc2VwYXJhdGUgY29uc3RydWN0aW9uLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBTZWdtZW50PEssVj4gZXh0ZW5kcyBSZWVudHJhbnRMb2NrIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogU2VnbWVudHMgbWFpbnRhaW4gYSB0YWJsZSBvZiBlbnRyeSBsaXN0cyB0aGF0IGFyZSBBTFdBWVMKKyAgICAgICAgICoga2VwdCBpbiBhIGNvbnNpc3RlbnQgc3RhdGUsIHNvIGNhbiBiZSByZWFkIHdpdGhvdXQgbG9ja2luZy4KKyAgICAgICAgICogTmV4dCBmaWVsZHMgb2Ygbm9kZXMgYXJlIGltbXV0YWJsZSAoZmluYWwpLiAgQWxsIGxpc3QKKyAgICAgICAgICogYWRkaXRpb25zIGFyZSBwZXJmb3JtZWQgYXQgdGhlIGZyb250IG9mIGVhY2ggYmluLiBUaGlzCisgICAgICAgICAqIG1ha2VzIGl0IGVhc3kgdG8gY2hlY2sgY2hhbmdlcywgYW5kIGFsc28gZmFzdCB0byB0cmF2ZXJzZS4KKyAgICAgICAgICogV2hlbiBub2RlcyB3b3VsZCBvdGhlcndpc2UgYmUgY2hhbmdlZCwgbmV3IG5vZGVzIGFyZQorICAgICAgICAgKiBjcmVhdGVkIHRvIHJlcGxhY2UgdGhlbS4gVGhpcyB3b3JrcyB3ZWxsIGZvciBoYXNoIHRhYmxlcworICAgICAgICAgKiBzaW5jZSB0aGUgYmluIGxpc3RzIHRlbmQgdG8gYmUgc2hvcnQuIChUaGUgYXZlcmFnZSBsZW5ndGgKKyAgICAgICAgICogaXMgbGVzcyB0aGFuIHR3byBmb3IgdGhlIGRlZmF1bHQgbG9hZCBmYWN0b3IgdGhyZXNob2xkLikKKyAgICAgICAgICoKKyAgICAgICAgICogUmVhZCBvcGVyYXRpb25zIGNhbiB0aHVzIHByb2NlZWQgd2l0aG91dCBsb2NraW5nLCBidXQgcmVseQorICAgICAgICAgKiBvbiBzZWxlY3RlZCB1c2VzIG9mIHZvbGF0aWxlcyB0byBlbnN1cmUgdGhhdCBjb21wbGV0ZWQKKyAgICAgICAgICogd3JpdGUgb3BlcmF0aW9ucyBwZXJmb3JtZWQgYnkgb3RoZXIgdGhyZWFkcyBhcmUKKyAgICAgICAgICogbm90aWNlZC4gRm9yIG1vc3QgcHVycG9zZXMsIHRoZSAiY291bnQiIGZpZWxkLCB0cmFja2luZyB0aGUKKyAgICAgICAgICogbnVtYmVyIG9mIGVsZW1lbnRzLCBzZXJ2ZXMgYXMgdGhhdCB2b2xhdGlsZSB2YXJpYWJsZQorICAgICAgICAgKiBlbnN1cmluZyB2aXNpYmlsaXR5LiAgVGhpcyBpcyBjb252ZW5pZW50IGJlY2F1c2UgdGhpcyBmaWVsZAorICAgICAgICAgKiBuZWVkcyB0byBiZSByZWFkIGluIG1hbnkgcmVhZCBvcGVyYXRpb25zIGFueXdheToKKyAgICAgICAgICoKKyAgICAgICAgICogICAtIEFsbCAodW5zeW5jaHJvbml6ZWQpIHJlYWQgb3BlcmF0aW9ucyBtdXN0IGZpcnN0IHJlYWQgdGhlCisgICAgICAgICAqICAgICAiY291bnQiIGZpZWxkLCBhbmQgc2hvdWxkIG5vdCBsb29rIGF0IHRhYmxlIGVudHJpZXMgaWYKKyAgICAgICAgICogICAgIGl0IGlzIDAuCisgICAgICAgICAqCisgICAgICAgICAqICAgLSBBbGwgKHN5bmNocm9uaXplZCkgd3JpdGUgb3BlcmF0aW9ucyBzaG91bGQgd3JpdGUgdG8KKyAgICAgICAgICogICAgIHRoZSAiY291bnQiIGZpZWxkIGFmdGVyIHN0cnVjdHVyYWxseSBjaGFuZ2luZyBhbnkgYmluLgorICAgICAgICAgKiAgICAgVGhlIG9wZXJhdGlvbnMgbXVzdCBub3QgdGFrZSBhbnkgYWN0aW9uIHRoYXQgY291bGQgZXZlbgorICAgICAgICAgKiAgICAgbW9tZW50YXJpbHkgY2F1c2UgYSBjb25jdXJyZW50IHJlYWQgb3BlcmF0aW9uIHRvIHNlZQorICAgICAgICAgKiAgICAgaW5jb25zaXN0ZW50IGRhdGEuIFRoaXMgaXMgbWFkZSBlYXNpZXIgYnkgdGhlIG5hdHVyZSBvZgorICAgICAgICAgKiAgICAgdGhlIHJlYWQgb3BlcmF0aW9ucyBpbiBNYXAuIEZvciBleGFtcGxlLCBubyBvcGVyYXRpb24KKyAgICAgICAgICogICAgIGNhbiByZXZlYWwgdGhhdCB0aGUgdGFibGUgaGFzIGdyb3duIGJ1dCB0aGUgdGhyZXNob2xkCisgICAgICAgICAqICAgICBoYXMgbm90IHlldCBiZWVuIHVwZGF0ZWQsIHNvIHRoZXJlIGFyZSBubyBhdG9taWNpdHkKKyAgICAgICAgICogICAgIHJlcXVpcmVtZW50cyBmb3IgdGhpcyB3aXRoIHJlc3BlY3QgdG8gcmVhZHMuCisgICAgICAgICAqCisgICAgICAgICAqIEFzIGEgZ3VpZGUsIGFsbCBjcml0aWNhbCB2b2xhdGlsZSByZWFkcyBhbmQgd3JpdGVzIHRvIHRoZQorICAgICAgICAgKiBjb3VudCBmaWVsZCBhcmUgbWFya2VkIGluIGNvZGUgY29tbWVudHMuCisgICAgICAgICAqLworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDIyNDkwNjkyNDY3NjMxODIzOTdMOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgc2VnbWVudCdzIHJlZ2lvbi4KKyAgICAgICAgICovCisgICAgICAgIHRyYW5zaWVudCB2b2xhdGlsZSBpbnQgY291bnQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE51bWJlciBvZiB1cGRhdGVzIHRoYXQgYWx0ZXIgdGhlIHNpemUgb2YgdGhlIHRhYmxlLiBUaGlzIGlzCisgICAgICAgICAqIHVzZWQgZHVyaW5nIGJ1bGstcmVhZCBtZXRob2RzIHRvIG1ha2Ugc3VyZSB0aGV5IHNlZSBhCisgICAgICAgICAqIGNvbnNpc3RlbnQgc25hcHNob3Q6IElmIG1vZENvdW50cyBjaGFuZ2UgZHVyaW5nIGEgdHJhdmVyc2FsCisgICAgICAgICAqIG9mIHNlZ21lbnRzIGNvbXB1dGluZyBzaXplIG9yIGNoZWNraW5nIGNvbnRhaW5zVmFsdWUsIHRoZW4KKyAgICAgICAgICogd2UgbWlnaHQgaGF2ZSBhbiBpbmNvbnNpc3RlbnQgdmlldyBvZiBzdGF0ZSBzbyAodXN1YWxseSkKKyAgICAgICAgICogbXVzdCByZXRyeS4KKyAgICAgICAgICovCisgICAgICAgIHRyYW5zaWVudCBpbnQgbW9kQ291bnQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB0YWJsZSBpcyByZWhhc2hlZCB3aGVuIGl0cyBzaXplIGV4Y2VlZHMgdGhpcyB0aHJlc2hvbGQuCisgICAgICAgICAqIChUaGUgdmFsdWUgb2YgdGhpcyBmaWVsZCBpcyBhbHdheXMgPHR0PihpbnQpKGNhcGFjaXR5ICoKKyAgICAgICAgICogbG9hZEZhY3Rvcik8L3R0Pi4pCisgICAgICAgICAqLworICAgICAgICB0cmFuc2llbnQgaW50IHRocmVzaG9sZDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHBlci1zZWdtZW50IHRhYmxlLgorICAgICAgICAgKi8KKyAgICAgICAgdHJhbnNpZW50IHZvbGF0aWxlIEhhc2hFbnRyeTxLLFY+W10gdGFibGU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBsb2FkIGZhY3RvciBmb3IgdGhlIGhhc2ggdGFibGUuICBFdmVuIHRob3VnaCB0aGlzIHZhbHVlCisgICAgICAgICAqIGlzIHNhbWUgZm9yIGFsbCBzZWdtZW50cywgaXQgaXMgcmVwbGljYXRlZCB0byBhdm9pZCBuZWVkaW5nCisgICAgICAgICAqIGxpbmtzIHRvIG91dGVyIG9iamVjdC4KKyAgICAgICAgICogQHNlcmlhbAorICAgICAgICAgKi8KKyAgICAgICAgZmluYWwgZmxvYXQgbG9hZEZhY3RvcjsKKworICAgICAgICBTZWdtZW50KGludCBpbml0aWFsQ2FwYWNpdHksIGZsb2F0IGxmKSB7CisgICAgICAgICAgICBsb2FkRmFjdG9yID0gbGY7CisgICAgICAgICAgICBzZXRUYWJsZShIYXNoRW50cnkuPEssVj5uZXdBcnJheShpbml0aWFsQ2FwYWNpdHkpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICBzdGF0aWMgZmluYWwgPEssVj4gU2VnbWVudDxLLFY+W10gbmV3QXJyYXkoaW50IGkpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgU2VnbWVudFtpXTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTZXRzIHRhYmxlIHRvIG5ldyBIYXNoRW50cnkgYXJyYXkuCisgICAgICAgICAqIENhbGwgb25seSB3aGlsZSBob2xkaW5nIGxvY2sgb3IgaW4gY29uc3RydWN0b3IuCisgICAgICAgICAqLworICAgICAgICB2b2lkIHNldFRhYmxlKEhhc2hFbnRyeTxLLFY+W10gbmV3VGFibGUpIHsKKyAgICAgICAgICAgIHRocmVzaG9sZCA9IChpbnQpKG5ld1RhYmxlLmxlbmd0aCAqIGxvYWRGYWN0b3IpOworICAgICAgICAgICAgdGFibGUgPSBuZXdUYWJsZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHByb3Blcmx5IGNhc3RlZCBmaXJzdCBlbnRyeSBvZiBiaW4gZm9yIGdpdmVuIGhhc2guCisgICAgICAgICAqLworICAgICAgICBIYXNoRW50cnk8SyxWPiBnZXRGaXJzdChpbnQgaGFzaCkgeworICAgICAgICAgICAgSGFzaEVudHJ5PEssVj5bXSB0YWIgPSB0YWJsZTsKKyAgICAgICAgICAgIHJldHVybiB0YWJbaGFzaCAmICh0YWIubGVuZ3RoIC0gMSldOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJlYWRzIHZhbHVlIGZpZWxkIG9mIGFuIGVudHJ5IHVuZGVyIGxvY2suIENhbGxlZCBpZiB2YWx1ZQorICAgICAgICAgKiBmaWVsZCBldmVyIGFwcGVhcnMgdG8gYmUgbnVsbC4gVGhpcyBpcyBwb3NzaWJsZSBvbmx5IGlmIGEKKyAgICAgICAgICogY29tcGlsZXIgaGFwcGVucyB0byByZW9yZGVyIGEgSGFzaEVudHJ5IGluaXRpYWxpemF0aW9uIHdpdGgKKyAgICAgICAgICogaXRzIHRhYmxlIGFzc2lnbm1lbnQsIHdoaWNoIGlzIGxlZ2FsIHVuZGVyIG1lbW9yeSBtb2RlbAorICAgICAgICAgKiBidXQgaXMgbm90IGtub3duIHRvIGV2ZXIgb2NjdXIuCisgICAgICAgICAqLworICAgICAgICBWIHJlYWRWYWx1ZVVuZGVyTG9jayhIYXNoRW50cnk8SyxWPiBlKSB7CisgICAgICAgICAgICBsb2NrKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiBlLnZhbHVlOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB1bmxvY2soKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qIFNwZWNpYWxpemVkIGltcGxlbWVudGF0aW9ucyBvZiBtYXAgbWV0aG9kcyAqLworCisgICAgICAgIFYgZ2V0KE9iamVjdCBrZXksIGludCBoYXNoKSB7CisgICAgICAgICAgICBpZiAoY291bnQgIT0gMCkgeyAvLyByZWFkLXZvbGF0aWxlCisgICAgICAgICAgICAgICAgSGFzaEVudHJ5PEssVj4gZSA9IGdldEZpcnN0KGhhc2gpOworICAgICAgICAgICAgICAgIHdoaWxlIChlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGUuaGFzaCA9PSBoYXNoICYmIGtleS5lcXVhbHMoZS5rZXkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBWIHYgPSBlLnZhbHVlOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHYgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdjsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWFkVmFsdWVVbmRlckxvY2soZSk7IC8vIHJlY2hlY2sKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBlID0gZS5uZXh0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBjb250YWluc0tleShPYmplY3Qga2V5LCBpbnQgaGFzaCkgeworICAgICAgICAgICAgaWYgKGNvdW50ICE9IDApIHsgLy8gcmVhZC12b2xhdGlsZQorICAgICAgICAgICAgICAgIEhhc2hFbnRyeTxLLFY+IGUgPSBnZXRGaXJzdChoYXNoKTsKKyAgICAgICAgICAgICAgICB3aGlsZSAoZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChlLmhhc2ggPT0gaGFzaCAmJiBrZXkuZXF1YWxzKGUua2V5KSkKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgICAgICBlID0gZS5uZXh0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gY29udGFpbnNWYWx1ZShPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgICAgIGlmIChjb3VudCAhPSAwKSB7IC8vIHJlYWQtdm9sYXRpbGUKKyAgICAgICAgICAgICAgICBIYXNoRW50cnk8SyxWPltdIHRhYiA9IHRhYmxlOworICAgICAgICAgICAgICAgIGludCBsZW4gPSB0YWIubGVuZ3RoOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwIDsgaSA8IGxlbjsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoSGFzaEVudHJ5PEssVj4gZSA9IHRhYltpXTsgZSAhPSBudWxsOyBlID0gZS5uZXh0KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBWIHYgPSBlLnZhbHVlOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHYgPT0gbnVsbCkgLy8gcmVjaGVjaworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHYgPSByZWFkVmFsdWVVbmRlckxvY2soZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUuZXF1YWxzKHYpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiByZXBsYWNlKEsga2V5LCBpbnQgaGFzaCwgViBvbGRWYWx1ZSwgViBuZXdWYWx1ZSkgeworICAgICAgICAgICAgbG9jaygpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBIYXNoRW50cnk8SyxWPiBlID0gZ2V0Rmlyc3QoaGFzaCk7CisgICAgICAgICAgICAgICAgd2hpbGUgKGUgIT0gbnVsbCAmJiAoZS5oYXNoICE9IGhhc2ggfHwgIWtleS5lcXVhbHMoZS5rZXkpKSkKKyAgICAgICAgICAgICAgICAgICAgZSA9IGUubmV4dDsKKworICAgICAgICAgICAgICAgIGJvb2xlYW4gcmVwbGFjZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBpZiAoZSAhPSBudWxsICYmIG9sZFZhbHVlLmVxdWFscyhlLnZhbHVlKSkgeworICAgICAgICAgICAgICAgICAgICByZXBsYWNlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIGUudmFsdWUgPSBuZXdWYWx1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlcGxhY2VkOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB1bmxvY2soKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFYgcmVwbGFjZShLIGtleSwgaW50IGhhc2gsIFYgbmV3VmFsdWUpIHsKKyAgICAgICAgICAgIGxvY2soKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgSGFzaEVudHJ5PEssVj4gZSA9IGdldEZpcnN0KGhhc2gpOworICAgICAgICAgICAgICAgIHdoaWxlIChlICE9IG51bGwgJiYgKGUuaGFzaCAhPSBoYXNoIHx8ICFrZXkuZXF1YWxzKGUua2V5KSkpCisgICAgICAgICAgICAgICAgICAgIGUgPSBlLm5leHQ7CisKKyAgICAgICAgICAgICAgICBWIG9sZFZhbHVlID0gbnVsbDsKKyAgICAgICAgICAgICAgICBpZiAoZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIG9sZFZhbHVlID0gZS52YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgZS52YWx1ZSA9IG5ld1ZhbHVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gb2xkVmFsdWU7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHVubG9jaygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKworICAgICAgICBWIHB1dChLIGtleSwgaW50IGhhc2gsIFYgdmFsdWUsIGJvb2xlYW4gb25seUlmQWJzZW50KSB7CisgICAgICAgICAgICBsb2NrKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGludCBjID0gY291bnQ7CisgICAgICAgICAgICAgICAgaWYgKGMrKyA+IHRocmVzaG9sZCkgLy8gZW5zdXJlIGNhcGFjaXR5CisgICAgICAgICAgICAgICAgICAgIHJlaGFzaCgpOworICAgICAgICAgICAgICAgIEhhc2hFbnRyeTxLLFY+W10gdGFiID0gdGFibGU7CisgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gaGFzaCAmICh0YWIubGVuZ3RoIC0gMSk7CisgICAgICAgICAgICAgICAgSGFzaEVudHJ5PEssVj4gZmlyc3QgPSB0YWJbaW5kZXhdOworICAgICAgICAgICAgICAgIEhhc2hFbnRyeTxLLFY+IGUgPSBmaXJzdDsKKyAgICAgICAgICAgICAgICB3aGlsZSAoZSAhPSBudWxsICYmIChlLmhhc2ggIT0gaGFzaCB8fCAha2V5LmVxdWFscyhlLmtleSkpKQorICAgICAgICAgICAgICAgICAgICBlID0gZS5uZXh0OworCisgICAgICAgICAgICAgICAgViBvbGRWYWx1ZTsKKyAgICAgICAgICAgICAgICBpZiAoZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIG9sZFZhbHVlID0gZS52YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFvbmx5SWZBYnNlbnQpCisgICAgICAgICAgICAgICAgICAgICAgICBlLnZhbHVlID0gdmFsdWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgICsrbW9kQ291bnQ7CisgICAgICAgICAgICAgICAgICAgIHRhYltpbmRleF0gPSBuZXcgSGFzaEVudHJ5PEssVj4oa2V5LCBoYXNoLCBmaXJzdCwgdmFsdWUpOworICAgICAgICAgICAgICAgICAgICBjb3VudCA9IGM7IC8vIHdyaXRlLXZvbGF0aWxlCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBvbGRWYWx1ZTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdW5sb2NrKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB2b2lkIHJlaGFzaCgpIHsKKyAgICAgICAgICAgIEhhc2hFbnRyeTxLLFY+W10gb2xkVGFibGUgPSB0YWJsZTsKKyAgICAgICAgICAgIGludCBvbGRDYXBhY2l0eSA9IG9sZFRhYmxlLmxlbmd0aDsKKyAgICAgICAgICAgIGlmIChvbGRDYXBhY2l0eSA+PSBNQVhJTVVNX0NBUEFDSVRZKQorICAgICAgICAgICAgICAgIHJldHVybjsKKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFJlY2xhc3NpZnkgbm9kZXMgaW4gZWFjaCBsaXN0IHRvIG5ldyBNYXAuICBCZWNhdXNlIHdlIGFyZQorICAgICAgICAgICAgICogdXNpbmcgcG93ZXItb2YtdHdvIGV4cGFuc2lvbiwgdGhlIGVsZW1lbnRzIGZyb20gZWFjaCBiaW4KKyAgICAgICAgICAgICAqIG11c3QgZWl0aGVyIHN0YXkgYXQgc2FtZSBpbmRleCwgb3IgbW92ZSB3aXRoIGEgcG93ZXIgb2YgdHdvCisgICAgICAgICAgICAgKiBvZmZzZXQuIFdlIGVsaW1pbmF0ZSB1bm5lY2Vzc2FyeSBub2RlIGNyZWF0aW9uIGJ5IGNhdGNoaW5nCisgICAgICAgICAgICAgKiBjYXNlcyB3aGVyZSBvbGQgbm9kZXMgY2FuIGJlIHJldXNlZCBiZWNhdXNlIHRoZWlyIG5leHQKKyAgICAgICAgICAgICAqIGZpZWxkcyB3b24ndCBjaGFuZ2UuIFN0YXRpc3RpY2FsbHksIGF0IHRoZSBkZWZhdWx0CisgICAgICAgICAgICAgKiB0aHJlc2hvbGQsIG9ubHkgYWJvdXQgb25lLXNpeHRoIG9mIHRoZW0gbmVlZCBjbG9uaW5nIHdoZW4KKyAgICAgICAgICAgICAqIGEgdGFibGUgZG91Ymxlcy4gVGhlIG5vZGVzIHRoZXkgcmVwbGFjZSB3aWxsIGJlIGdhcmJhZ2UKKyAgICAgICAgICAgICAqIGNvbGxlY3RhYmxlIGFzIHNvb24gYXMgdGhleSBhcmUgbm8gbG9uZ2VyIHJlZmVyZW5jZWQgYnkgYW55CisgICAgICAgICAgICAgKiByZWFkZXIgdGhyZWFkIHRoYXQgbWF5IGJlIGluIHRoZSBtaWRzdCBvZiB0cmF2ZXJzaW5nIHRhYmxlCisgICAgICAgICAgICAgKiByaWdodCBub3cuCisgICAgICAgICAgICAgKi8KKworICAgICAgICAgICAgSGFzaEVudHJ5PEssVj5bXSBuZXdUYWJsZSA9IEhhc2hFbnRyeS5uZXdBcnJheShvbGRDYXBhY2l0eTw8MSk7CisgICAgICAgICAgICB0aHJlc2hvbGQgPSAoaW50KShuZXdUYWJsZS5sZW5ndGggKiBsb2FkRmFjdG9yKTsKKyAgICAgICAgICAgIGludCBzaXplTWFzayA9IG5ld1RhYmxlLmxlbmd0aCAtIDE7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9sZENhcGFjaXR5IDsgaSsrKSB7CisgICAgICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBndWFyYW50ZWUgdGhhdCBhbnkgZXhpc3RpbmcgcmVhZHMgb2Ygb2xkIE1hcCBjYW4KKyAgICAgICAgICAgICAgICAvLyAgcHJvY2VlZC4gU28gd2UgY2Fubm90IHlldCBudWxsIG91dCBlYWNoIGJpbi4KKyAgICAgICAgICAgICAgICBIYXNoRW50cnk8SyxWPiBlID0gb2xkVGFibGVbaV07CisKKyAgICAgICAgICAgICAgICBpZiAoZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIEhhc2hFbnRyeTxLLFY+IG5leHQgPSBlLm5leHQ7CisgICAgICAgICAgICAgICAgICAgIGludCBpZHggPSBlLmhhc2ggJiBzaXplTWFzazsKKworICAgICAgICAgICAgICAgICAgICAvLyAgU2luZ2xlIG5vZGUgb24gbGlzdAorICAgICAgICAgICAgICAgICAgICBpZiAobmV4dCA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgbmV3VGFibGVbaWR4XSA9IGU7CisKKyAgICAgICAgICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXVzZSB0cmFpbGluZyBjb25zZWN1dGl2ZSBzZXF1ZW5jZSBhdCBzYW1lIHNsb3QKKyAgICAgICAgICAgICAgICAgICAgICAgIEhhc2hFbnRyeTxLLFY+IGxhc3RSdW4gPSBlOworICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxhc3RJZHggPSBpZHg7CisgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKEhhc2hFbnRyeTxLLFY+IGxhc3QgPSBuZXh0OworICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0ICE9IG51bGw7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3QgPSBsYXN0Lm5leHQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgayA9IGxhc3QuaGFzaCAmIHNpemVNYXNrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrICE9IGxhc3RJZHgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdElkeCA9IGs7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RSdW4gPSBsYXN0OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIG5ld1RhYmxlW2xhc3RJZHhdID0gbGFzdFJ1bjsKKworICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2xvbmUgYWxsIHJlbWFpbmluZyBub2RlcworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChIYXNoRW50cnk8SyxWPiBwID0gZTsgcCAhPSBsYXN0UnVuOyBwID0gcC5uZXh0KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGsgPSBwLmhhc2ggJiBzaXplTWFzazsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBIYXNoRW50cnk8SyxWPiBuID0gbmV3VGFibGVba107CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3VGFibGVba10gPSBuZXcgSGFzaEVudHJ5PEssVj4ocC5rZXksIHAuaGFzaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuLCBwLnZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRhYmxlID0gbmV3VGFibGU7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmVtb3ZlOyBtYXRjaCBvbiBrZXkgb25seSBpZiB2YWx1ZSBudWxsLCBlbHNlIG1hdGNoIGJvdGguCisgICAgICAgICAqLworICAgICAgICBWIHJlbW92ZShPYmplY3Qga2V5LCBpbnQgaGFzaCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgICAgICBsb2NrKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGludCBjID0gY291bnQgLSAxOworICAgICAgICAgICAgICAgIEhhc2hFbnRyeTxLLFY+W10gdGFiID0gdGFibGU7CisgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gaGFzaCAmICh0YWIubGVuZ3RoIC0gMSk7CisgICAgICAgICAgICAgICAgSGFzaEVudHJ5PEssVj4gZmlyc3QgPSB0YWJbaW5kZXhdOworICAgICAgICAgICAgICAgIEhhc2hFbnRyeTxLLFY+IGUgPSBmaXJzdDsKKyAgICAgICAgICAgICAgICB3aGlsZSAoZSAhPSBudWxsICYmIChlLmhhc2ggIT0gaGFzaCB8fCAha2V5LmVxdWFscyhlLmtleSkpKQorICAgICAgICAgICAgICAgICAgICBlID0gZS5uZXh0OworCisgICAgICAgICAgICAgICAgViBvbGRWYWx1ZSA9IG51bGw7CisgICAgICAgICAgICAgICAgaWYgKGUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBWIHYgPSBlLnZhbHVlOworICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCB8fCB2YWx1ZS5lcXVhbHModikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG9sZFZhbHVlID0gdjsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFsbCBlbnRyaWVzIGZvbGxvd2luZyByZW1vdmVkIG5vZGUgY2FuIHN0YXkKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluIGxpc3QsIGJ1dCBhbGwgcHJlY2VkaW5nIG9uZXMgbmVlZCB0byBiZQorICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2xvbmVkLgorICAgICAgICAgICAgICAgICAgICAgICAgKyttb2RDb3VudDsKKyAgICAgICAgICAgICAgICAgICAgICAgIEhhc2hFbnRyeTxLLFY+IG5ld0ZpcnN0ID0gZS5uZXh0OworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChIYXNoRW50cnk8SyxWPiBwID0gZmlyc3Q7IHAgIT0gZTsgcCA9IHAubmV4dCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGaXJzdCA9IG5ldyBIYXNoRW50cnk8SyxWPihwLmtleSwgcC5oYXNoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0ZpcnN0LCBwLnZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRhYltpbmRleF0gPSBuZXdGaXJzdDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gYzsgLy8gd3JpdGUtdm9sYXRpbGUKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gb2xkVmFsdWU7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHVubG9jaygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgICAgIGlmIChjb3VudCAhPSAwKSB7CisgICAgICAgICAgICAgICAgbG9jaygpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIEhhc2hFbnRyeTxLLFY+W10gdGFiID0gdGFibGU7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGFiLmxlbmd0aCA7IGkrKykKKyAgICAgICAgICAgICAgICAgICAgICAgIHRhYltpXSA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgICsrbW9kQ291bnQ7CisgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gMDsgLy8gd3JpdGUtdm9sYXRpbGUKKyAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICB1bmxvY2soKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKworCisgICAgLyogLS0tLS0tLS0tLS0tLS0tLSBQdWJsaWMgb3BlcmF0aW9ucyAtLS0tLS0tLS0tLS0tLSAqLworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldywgZW1wdHkgbWFwIHdpdGggdGhlIHNwZWNpZmllZCBpbml0aWFsCisgICAgICogY2FwYWNpdHksIGxvYWQgZmFjdG9yIGFuZCBjb25jdXJyZW5jeSBsZXZlbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbml0aWFsQ2FwYWNpdHkgdGhlIGluaXRpYWwgY2FwYWNpdHkuIFRoZSBpbXBsZW1lbnRhdGlvbgorICAgICAqIHBlcmZvcm1zIGludGVybmFsIHNpemluZyB0byBhY2NvbW1vZGF0ZSB0aGlzIG1hbnkgZWxlbWVudHMuCisgICAgICogQHBhcmFtIGxvYWRGYWN0b3IgIHRoZSBsb2FkIGZhY3RvciB0aHJlc2hvbGQsIHVzZWQgdG8gY29udHJvbCByZXNpemluZy4KKyAgICAgKiBSZXNpemluZyBtYXkgYmUgcGVyZm9ybWVkIHdoZW4gdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGVsZW1lbnRzIHBlcgorICAgICAqIGJpbiBleGNlZWRzIHRoaXMgdGhyZXNob2xkLgorICAgICAqIEBwYXJhbSBjb25jdXJyZW5jeUxldmVsIHRoZSBlc3RpbWF0ZWQgbnVtYmVyIG9mIGNvbmN1cnJlbnRseQorICAgICAqIHVwZGF0aW5nIHRocmVhZHMuIFRoZSBpbXBsZW1lbnRhdGlvbiBwZXJmb3JtcyBpbnRlcm5hbCBzaXppbmcKKyAgICAgKiB0byB0cnkgdG8gYWNjb21tb2RhdGUgdGhpcyBtYW55IHRocmVhZHMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGluaXRpYWwgY2FwYWNpdHkgaXMKKyAgICAgKiBuZWdhdGl2ZSBvciB0aGUgbG9hZCBmYWN0b3Igb3IgY29uY3VycmVuY3lMZXZlbCBhcmUKKyAgICAgKiBub25wb3NpdGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29uY3VycmVudEhhc2hNYXAoaW50IGluaXRpYWxDYXBhY2l0eSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgbG9hZEZhY3RvciwgaW50IGNvbmN1cnJlbmN5TGV2ZWwpIHsKKyAgICAgICAgaWYgKCEobG9hZEZhY3RvciA+IDApIHx8IGluaXRpYWxDYXBhY2l0eSA8IDAgfHwgY29uY3VycmVuY3lMZXZlbCA8PSAwKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworCisgICAgICAgIGlmIChjb25jdXJyZW5jeUxldmVsID4gTUFYX1NFR01FTlRTKQorICAgICAgICAgICAgY29uY3VycmVuY3lMZXZlbCA9IE1BWF9TRUdNRU5UUzsKKworICAgICAgICAvLyBGaW5kIHBvd2VyLW9mLXR3byBzaXplcyBiZXN0IG1hdGNoaW5nIGFyZ3VtZW50cworICAgICAgICBpbnQgc3NoaWZ0ID0gMDsKKyAgICAgICAgaW50IHNzaXplID0gMTsKKyAgICAgICAgd2hpbGUgKHNzaXplIDwgY29uY3VycmVuY3lMZXZlbCkgeworICAgICAgICAgICAgKytzc2hpZnQ7CisgICAgICAgICAgICBzc2l6ZSA8PD0gMTsKKyAgICAgICAgfQorICAgICAgICBzZWdtZW50U2hpZnQgPSAzMiAtIHNzaGlmdDsKKyAgICAgICAgc2VnbWVudE1hc2sgPSBzc2l6ZSAtIDE7CisgICAgICAgIHRoaXMuc2VnbWVudHMgPSBTZWdtZW50Lm5ld0FycmF5KHNzaXplKTsKKworICAgICAgICBpZiAoaW5pdGlhbENhcGFjaXR5ID4gTUFYSU1VTV9DQVBBQ0lUWSkKKyAgICAgICAgICAgIGluaXRpYWxDYXBhY2l0eSA9IE1BWElNVU1fQ0FQQUNJVFk7CisgICAgICAgIGludCBjID0gaW5pdGlhbENhcGFjaXR5IC8gc3NpemU7CisgICAgICAgIGlmIChjICogc3NpemUgPCBpbml0aWFsQ2FwYWNpdHkpCisgICAgICAgICAgICArK2M7CisgICAgICAgIGludCBjYXAgPSAxOworICAgICAgICB3aGlsZSAoY2FwIDwgYykKKyAgICAgICAgICAgIGNhcCA8PD0gMTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMuc2VnbWVudHMubGVuZ3RoOyArK2kpCisgICAgICAgICAgICB0aGlzLnNlZ21lbnRzW2ldID0gbmV3IFNlZ21lbnQ8SyxWPihjYXAsIGxvYWRGYWN0b3IpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcsIGVtcHR5IG1hcCB3aXRoIHRoZSBzcGVjaWZpZWQgaW5pdGlhbCBjYXBhY2l0eQorICAgICAqIGFuZCBsb2FkIGZhY3RvciBhbmQgd2l0aCB0aGUgZGVmYXVsdCBjb25jdXJyZW5jeUxldmVsICgxNikuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5pdGlhbENhcGFjaXR5IFRoZSBpbXBsZW1lbnRhdGlvbiBwZXJmb3JtcyBpbnRlcm5hbAorICAgICAqIHNpemluZyB0byBhY2NvbW1vZGF0ZSB0aGlzIG1hbnkgZWxlbWVudHMuCisgICAgICogQHBhcmFtIGxvYWRGYWN0b3IgIHRoZSBsb2FkIGZhY3RvciB0aHJlc2hvbGQsIHVzZWQgdG8gY29udHJvbCByZXNpemluZy4KKyAgICAgKiBSZXNpemluZyBtYXkgYmUgcGVyZm9ybWVkIHdoZW4gdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGVsZW1lbnRzIHBlcgorICAgICAqIGJpbiBleGNlZWRzIHRoaXMgdGhyZXNob2xkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBpbml0aWFsIGNhcGFjaXR5IG9mCisgICAgICogZWxlbWVudHMgaXMgbmVnYXRpdmUgb3IgdGhlIGxvYWQgZmFjdG9yIGlzIG5vbnBvc2l0aXZlCisgICAgICoKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIENvbmN1cnJlbnRIYXNoTWFwKGludCBpbml0aWFsQ2FwYWNpdHksIGZsb2F0IGxvYWRGYWN0b3IpIHsKKyAgICAgICAgdGhpcyhpbml0aWFsQ2FwYWNpdHksIGxvYWRGYWN0b3IsIERFRkFVTFRfQ09OQ1VSUkVOQ1lfTEVWRUwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcsIGVtcHR5IG1hcCB3aXRoIHRoZSBzcGVjaWZpZWQgaW5pdGlhbCBjYXBhY2l0eSwKKyAgICAgKiBhbmQgd2l0aCBkZWZhdWx0IGxvYWQgZmFjdG9yICgwLjc1KSBhbmQgY29uY3VycmVuY3lMZXZlbCAoMTYpLgorICAgICAqCisgICAgICogQHBhcmFtIGluaXRpYWxDYXBhY2l0eSB0aGUgaW5pdGlhbCBjYXBhY2l0eS4gVGhlIGltcGxlbWVudGF0aW9uCisgICAgICogcGVyZm9ybXMgaW50ZXJuYWwgc2l6aW5nIHRvIGFjY29tbW9kYXRlIHRoaXMgbWFueSBlbGVtZW50cy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgaW5pdGlhbCBjYXBhY2l0eSBvZgorICAgICAqIGVsZW1lbnRzIGlzIG5lZ2F0aXZlLgorICAgICAqLworICAgIHB1YmxpYyBDb25jdXJyZW50SGFzaE1hcChpbnQgaW5pdGlhbENhcGFjaXR5KSB7CisgICAgICAgIHRoaXMoaW5pdGlhbENhcGFjaXR5LCBERUZBVUxUX0xPQURfRkFDVE9SLCBERUZBVUxUX0NPTkNVUlJFTkNZX0xFVkVMKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3LCBlbXB0eSBtYXAgd2l0aCBhIGRlZmF1bHQgaW5pdGlhbCBjYXBhY2l0eSAoMTYpLAorICAgICAqIGxvYWQgZmFjdG9yICgwLjc1KSBhbmQgY29uY3VycmVuY3lMZXZlbCAoMTYpLgorICAgICAqLworICAgIHB1YmxpYyBDb25jdXJyZW50SGFzaE1hcCgpIHsKKyAgICAgICAgdGhpcyhERUZBVUxUX0lOSVRJQUxfQ0FQQUNJVFksIERFRkFVTFRfTE9BRF9GQUNUT1IsIERFRkFVTFRfQ09OQ1VSUkVOQ1lfTEVWRUwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgbWFwIHdpdGggdGhlIHNhbWUgbWFwcGluZ3MgYXMgdGhlIGdpdmVuIG1hcC4KKyAgICAgKiBUaGUgbWFwIGlzIGNyZWF0ZWQgd2l0aCBhIGNhcGFjaXR5IG9mIDEuNSB0aW1lcyB0aGUgbnVtYmVyCisgICAgICogb2YgbWFwcGluZ3MgaW4gdGhlIGdpdmVuIG1hcCBvciAxNiAod2hpY2hldmVyIGlzIGdyZWF0ZXIpLAorICAgICAqIGFuZCBhIGRlZmF1bHQgbG9hZCBmYWN0b3IgKDAuNzUpIGFuZCBjb25jdXJyZW5jeUxldmVsICgxNikuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbSB0aGUgbWFwCisgICAgICovCisgICAgcHVibGljIENvbmN1cnJlbnRIYXNoTWFwKE1hcDw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+IG0pIHsKKyAgICAgICAgdGhpcyhNYXRoLm1heCgoaW50KSAobS5zaXplKCkgLyBERUZBVUxUX0xPQURfRkFDVE9SKSArIDEsCisgICAgICAgICAgICAgICAgICAgICAgREVGQVVMVF9JTklUSUFMX0NBUEFDSVRZKSwKKyAgICAgICAgICAgICBERUZBVUxUX0xPQURfRkFDVE9SLCBERUZBVUxUX0NPTkNVUlJFTkNZX0xFVkVMKTsKKyAgICAgICAgcHV0QWxsKG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBpZiB0aGlzIG1hcCBjb250YWlucyBubyBrZXktdmFsdWUgbWFwcGluZ3MuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBtYXAgY29udGFpbnMgbm8ga2V5LXZhbHVlIG1hcHBpbmdzCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgZmluYWwgU2VnbWVudDxLLFY+W10gc2VnbWVudHMgPSB0aGlzLnNlZ21lbnRzOworICAgICAgICAvKgorICAgICAgICAgKiBXZSBrZWVwIHRyYWNrIG9mIHBlci1zZWdtZW50IG1vZENvdW50cyB0byBhdm9pZCBBQkEKKyAgICAgICAgICogcHJvYmxlbXMgaW4gd2hpY2ggYW4gZWxlbWVudCBpbiBvbmUgc2VnbWVudCB3YXMgYWRkZWQgYW5kCisgICAgICAgICAqIGluIGFub3RoZXIgcmVtb3ZlZCBkdXJpbmcgdHJhdmVyc2FsLCBpbiB3aGljaCBjYXNlIHRoZQorICAgICAgICAgKiB0YWJsZSB3YXMgbmV2ZXIgYWN0dWFsbHkgZW1wdHkgYXQgYW55IHBvaW50LiBOb3RlIHRoZQorICAgICAgICAgKiBzaW1pbGFyIHVzZSBvZiBtb2RDb3VudHMgaW4gdGhlIHNpemUoKSBhbmQgY29udGFpbnNWYWx1ZSgpCisgICAgICAgICAqIG1ldGhvZHMsIHdoaWNoIGFyZSB0aGUgb25seSBvdGhlciBtZXRob2RzIGFsc28gc3VzY2VwdGlibGUKKyAgICAgICAgICogdG8gQUJBIHByb2JsZW1zLgorICAgICAgICAgKi8KKyAgICAgICAgaW50W10gbWMgPSBuZXcgaW50W3NlZ21lbnRzLmxlbmd0aF07CisgICAgICAgIGludCBtY3N1bSA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2VnbWVudHMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIGlmIChzZWdtZW50c1tpXS5jb3VudCAhPSAwKQorICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBtY3N1bSArPSBtY1tpXSA9IHNlZ21lbnRzW2ldLm1vZENvdW50OworICAgICAgICB9CisgICAgICAgIC8vIElmIG1jc3VtIGhhcHBlbnMgdG8gYmUgemVybywgdGhlbiB3ZSBrbm93IHdlIGdvdCBhIHNuYXBzaG90CisgICAgICAgIC8vIGJlZm9yZSBhbnkgbW9kaWZpY2F0aW9ucyBhdCBhbGwgd2VyZSBtYWRlLiAgVGhpcyBpcworICAgICAgICAvLyBwcm9iYWJseSBjb21tb24gZW5vdWdoIHRvIGJvdGhlciB0cmFja2luZy4KKyAgICAgICAgaWYgKG1jc3VtICE9IDApIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2VnbWVudHMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICBpZiAoc2VnbWVudHNbaV0uY291bnQgIT0gMCB8fAorICAgICAgICAgICAgICAgICAgICBtY1tpXSAhPSBzZWdtZW50c1tpXS5tb2RDb3VudCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBrZXktdmFsdWUgbWFwcGluZ3MgaW4gdGhpcyBtYXAuICBJZiB0aGUKKyAgICAgKiBtYXAgY29udGFpbnMgbW9yZSB0aGFuIDx0dD5JbnRlZ2VyLk1BWF9WQUxVRTwvdHQ+IGVsZW1lbnRzLCByZXR1cm5zCisgICAgICogPHR0PkludGVnZXIuTUFYX1ZBTFVFPC90dD4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2Yga2V5LXZhbHVlIG1hcHBpbmdzIGluIHRoaXMgbWFwCisgICAgICovCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICBmaW5hbCBTZWdtZW50PEssVj5bXSBzZWdtZW50cyA9IHRoaXMuc2VnbWVudHM7CisgICAgICAgIGxvbmcgc3VtID0gMDsKKyAgICAgICAgbG9uZyBjaGVjayA9IDA7CisgICAgICAgIGludFtdIG1jID0gbmV3IGludFtzZWdtZW50cy5sZW5ndGhdOworICAgICAgICAvLyBUcnkgYSBmZXcgdGltZXMgdG8gZ2V0IGFjY3VyYXRlIGNvdW50LiBPbiBmYWlsdXJlIGR1ZSB0bworICAgICAgICAvLyBjb250aW51b3VzIGFzeW5jIGNoYW5nZXMgaW4gdGFibGUsIHJlc29ydCB0byBsb2NraW5nLgorICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IFJFVFJJRVNfQkVGT1JFX0xPQ0s7ICsraykgeworICAgICAgICAgICAgY2hlY2sgPSAwOworICAgICAgICAgICAgc3VtID0gMDsKKyAgICAgICAgICAgIGludCBtY3N1bSA9IDA7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNlZ21lbnRzLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICAgICAgc3VtICs9IHNlZ21lbnRzW2ldLmNvdW50OworICAgICAgICAgICAgICAgIG1jc3VtICs9IG1jW2ldID0gc2VnbWVudHNbaV0ubW9kQ291bnQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobWNzdW0gIT0gMCkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2VnbWVudHMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICAgICAgY2hlY2sgKz0gc2VnbWVudHNbaV0uY291bnQ7CisgICAgICAgICAgICAgICAgICAgIGlmIChtY1tpXSAhPSBzZWdtZW50c1tpXS5tb2RDb3VudCkgeworICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2sgPSAtMTsgLy8gZm9yY2UgcmV0cnkKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGNoZWNrID09IHN1bSkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2hlY2sgIT0gc3VtKSB7IC8vIFJlc29ydCB0byBsb2NraW5nIGFsbCBzZWdtZW50cworICAgICAgICAgICAgc3VtID0gMDsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2VnbWVudHMubGVuZ3RoOyArK2kpCisgICAgICAgICAgICAgICAgc2VnbWVudHNbaV0ubG9jaygpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGg7ICsraSkKKyAgICAgICAgICAgICAgICBzdW0gKz0gc2VnbWVudHNbaV0uY291bnQ7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNlZ21lbnRzLmxlbmd0aDsgKytpKQorICAgICAgICAgICAgICAgIHNlZ21lbnRzW2ldLnVubG9jaygpOworICAgICAgICB9CisgICAgICAgIGlmIChzdW0gPiBJbnRlZ2VyLk1BWF9WQUxVRSkKKyAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcmV0dXJuIChpbnQpc3VtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIHRvIHdoaWNoIHRoZSBzcGVjaWZpZWQga2V5IGlzIG1hcHBlZCwKKyAgICAgKiBvciB7QGNvZGUgbnVsbH0gaWYgdGhpcyBtYXAgY29udGFpbnMgbm8gbWFwcGluZyBmb3IgdGhlIGtleS4KKyAgICAgKgorICAgICAqIDxwPk1vcmUgZm9ybWFsbHksIGlmIHRoaXMgbWFwIGNvbnRhaW5zIGEgbWFwcGluZyBmcm9tIGEga2V5CisgICAgICoge0Bjb2RlIGt9IHRvIGEgdmFsdWUge0Bjb2RlIHZ9IHN1Y2ggdGhhdCB7QGNvZGUga2V5LmVxdWFscyhrKX0sCisgICAgICogdGhlbiB0aGlzIG1ldGhvZCByZXR1cm5zIHtAY29kZSB2fTsgb3RoZXJ3aXNlIGl0IHJldHVybnMKKyAgICAgKiB7QGNvZGUgbnVsbH0uICAoVGhlcmUgY2FuIGJlIGF0IG1vc3Qgb25lIHN1Y2ggbWFwcGluZy4pCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQga2V5IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgViBnZXQoT2JqZWN0IGtleSkgeworICAgICAgICBpbnQgaGFzaCA9IGhhc2goa2V5Lmhhc2hDb2RlKCkpOworICAgICAgICByZXR1cm4gc2VnbWVudEZvcihoYXNoKS5nZXQoa2V5LCBoYXNoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBhIGtleSBpbiB0aGlzIHRhYmxlLgorICAgICAqCisgICAgICogQHBhcmFtICBrZXkgICBwb3NzaWJsZSBrZXkKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgYW5kIG9ubHkgaWYgdGhlIHNwZWNpZmllZCBvYmplY3QKKyAgICAgKiAgICAgICAgIGlzIGEga2V5IGluIHRoaXMgdGFibGUsIGFzIGRldGVybWluZWQgYnkgdGhlCisgICAgICogICAgICAgICA8dHQ+ZXF1YWxzPC90dD4gbWV0aG9kOyA8dHQ+ZmFsc2U8L3R0PiBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNLZXkoT2JqZWN0IGtleSkgeworICAgICAgICBpbnQgaGFzaCA9IGhhc2goa2V5Lmhhc2hDb2RlKCkpOworICAgICAgICByZXR1cm4gc2VnbWVudEZvcihoYXNoKS5jb250YWluc0tleShrZXksIGhhc2gpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBpZiB0aGlzIG1hcCBtYXBzIG9uZSBvciBtb3JlIGtleXMgdG8gdGhlCisgICAgICogc3BlY2lmaWVkIHZhbHVlLiBOb3RlOiBUaGlzIG1ldGhvZCByZXF1aXJlcyBhIGZ1bGwgaW50ZXJuYWwKKyAgICAgKiB0cmF2ZXJzYWwgb2YgdGhlIGhhc2ggdGFibGUsIGFuZCBzbyBpcyBtdWNoIHNsb3dlciB0aGFuCisgICAgICogbWV0aG9kIDx0dD5jb250YWluc0tleTwvdHQ+LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlIHZhbHVlIHdob3NlIHByZXNlbmNlIGluIHRoaXMgbWFwIGlzIHRvIGJlIHRlc3RlZAorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGlzIG1hcCBtYXBzIG9uZSBvciBtb3JlIGtleXMgdG8gdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgdmFsdWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVmFsdWUoT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisKKyAgICAgICAgLy8gU2VlIGV4cGxhbmF0aW9uIG9mIG1vZENvdW50IHVzZSBhYm92ZQorCisgICAgICAgIGZpbmFsIFNlZ21lbnQ8SyxWPltdIHNlZ21lbnRzID0gdGhpcy5zZWdtZW50czsKKyAgICAgICAgaW50W10gbWMgPSBuZXcgaW50W3NlZ21lbnRzLmxlbmd0aF07CisKKyAgICAgICAgLy8gVHJ5IGEgZmV3IHRpbWVzIHdpdGhvdXQgbG9ja2luZworICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IFJFVFJJRVNfQkVGT1JFX0xPQ0s7ICsraykgeworICAgICAgICAgICAgaW50IHN1bSA9IDA7CisgICAgICAgICAgICBpbnQgbWNzdW0gPSAwOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgICAgIGludCBjID0gc2VnbWVudHNbaV0uY291bnQ7CisgICAgICAgICAgICAgICAgbWNzdW0gKz0gbWNbaV0gPSBzZWdtZW50c1tpXS5tb2RDb3VudDsKKyAgICAgICAgICAgICAgICBpZiAoc2VnbWVudHNbaV0uY29udGFpbnNWYWx1ZSh2YWx1ZSkpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYm9vbGVhbiBjbGVhblN3ZWVwID0gdHJ1ZTsKKyAgICAgICAgICAgIGlmIChtY3N1bSAhPSAwKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgICAgICAgICBpbnQgYyA9IHNlZ21lbnRzW2ldLmNvdW50OworICAgICAgICAgICAgICAgICAgICBpZiAobWNbaV0gIT0gc2VnbWVudHNbaV0ubW9kQ291bnQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFuU3dlZXAgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGNsZWFuU3dlZXApCisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIC8vIFJlc29ydCB0byBsb2NraW5nIGFsbCBzZWdtZW50cworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNlZ21lbnRzLmxlbmd0aDsgKytpKQorICAgICAgICAgICAgc2VnbWVudHNbaV0ubG9jaygpOworICAgICAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNlZ21lbnRzLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICAgICAgaWYgKHNlZ21lbnRzW2ldLmNvbnRhaW5zVmFsdWUodmFsdWUpKSB7CisgICAgICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGg7ICsraSkKKyAgICAgICAgICAgICAgICBzZWdtZW50c1tpXS51bmxvY2soKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZm91bmQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogTGVnYWN5IG1ldGhvZCB0ZXN0aW5nIGlmIHNvbWUga2V5IG1hcHMgaW50byB0aGUgc3BlY2lmaWVkIHZhbHVlCisgICAgICogaW4gdGhpcyB0YWJsZS4gIFRoaXMgbWV0aG9kIGlzIGlkZW50aWNhbCBpbiBmdW5jdGlvbmFsaXR5IHRvCisgICAgICoge0BsaW5rICNjb250YWluc1ZhbHVlfSwgYW5kIGV4aXN0cyBzb2xlbHkgdG8gZW5zdXJlCisgICAgICogZnVsbCBjb21wYXRpYmlsaXR5IHdpdGggY2xhc3Mge0BsaW5rIGphdmEudXRpbC5IYXNodGFibGV9LAorICAgICAqIHdoaWNoIHN1cHBvcnRlZCB0aGlzIG1ldGhvZCBwcmlvciB0byBpbnRyb2R1Y3Rpb24gb2YgdGhlCisgICAgICogSmF2YSBDb2xsZWN0aW9ucyBmcmFtZXdvcmsuCisKKyAgICAgKiBAcGFyYW0gIHZhbHVlIGEgdmFsdWUgdG8gc2VhcmNoIGZvcgorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiBhbmQgb25seSBpZiBzb21lIGtleSBtYXBzIHRvIHRoZQorICAgICAqICAgICAgICAgPHR0PnZhbHVlPC90dD4gYXJndW1lbnQgaW4gdGhpcyB0YWJsZSBhcworICAgICAqICAgICAgICAgZGV0ZXJtaW5lZCBieSB0aGUgPHR0PmVxdWFsczwvdHQ+IG1ldGhvZDsKKyAgICAgKiAgICAgICAgIDx0dD5mYWxzZTwvdHQ+IG90aGVyd2lzZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIHJldHVybiBjb250YWluc1ZhbHVlKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXBzIHRoZSBzcGVjaWZpZWQga2V5IHRvIHRoZSBzcGVjaWZpZWQgdmFsdWUgaW4gdGhpcyB0YWJsZS4KKyAgICAgKiBOZWl0aGVyIHRoZSBrZXkgbm9yIHRoZSB2YWx1ZSBjYW4gYmUgbnVsbC4KKyAgICAgKgorICAgICAqIDxwPiBUaGUgdmFsdWUgY2FuIGJlIHJldHJpZXZlZCBieSBjYWxsaW5nIHRoZSA8dHQ+Z2V0PC90dD4gbWV0aG9kCisgICAgICogd2l0aCBhIGtleSB0aGF0IGlzIGVxdWFsIHRvIHRoZSBvcmlnaW5hbCBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5IGtleSB3aXRoIHdoaWNoIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgdG8gYmUgYXNzb2NpYXRlZAorICAgICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSB0byBiZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBrZXkKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggPHR0PmtleTwvdHQ+LCBvcgorICAgICAqICAgICAgICAgPHR0Pm51bGw8L3R0PiBpZiB0aGVyZSB3YXMgbm8gbWFwcGluZyBmb3IgPHR0PmtleTwvdHQ+CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBvciB2YWx1ZSBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIFYgcHV0KEsga2V5LCBWIHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGludCBoYXNoID0gaGFzaChrZXkuaGFzaENvZGUoKSk7CisgICAgICAgIHJldHVybiBzZWdtZW50Rm9yKGhhc2gpLnB1dChrZXksIGhhc2gsIHZhbHVlLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LAorICAgICAqICAgICAgICAgb3IgPHR0Pm51bGw8L3R0PiBpZiB0aGVyZSB3YXMgbm8gbWFwcGluZyBmb3IgdGhlIGtleQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgb3IgdmFsdWUgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBWIHB1dElmQWJzZW50KEsga2V5LCBWIHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGludCBoYXNoID0gaGFzaChrZXkuaGFzaENvZGUoKSk7CisgICAgICAgIHJldHVybiBzZWdtZW50Rm9yKGhhc2gpLnB1dChrZXksIGhhc2gsIHZhbHVlLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgYWxsIG9mIHRoZSBtYXBwaW5ncyBmcm9tIHRoZSBzcGVjaWZpZWQgbWFwIHRvIHRoaXMgb25lLgorICAgICAqIFRoZXNlIG1hcHBpbmdzIHJlcGxhY2UgYW55IG1hcHBpbmdzIHRoYXQgdGhpcyBtYXAgaGFkIGZvciBhbnkgb2YgdGhlCisgICAgICoga2V5cyBjdXJyZW50bHkgaW4gdGhlIHNwZWNpZmllZCBtYXAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbSBtYXBwaW5ncyB0byBiZSBzdG9yZWQgaW4gdGhpcyBtYXAKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXRBbGwoTWFwPD8gZXh0ZW5kcyBLLCA/IGV4dGVuZHMgVj4gbSkgeworICAgICAgICBmb3IgKE1hcC5FbnRyeTw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+IGUgOiBtLmVudHJ5U2V0KCkpCisgICAgICAgICAgICBwdXQoZS5nZXRLZXkoKSwgZS5nZXRWYWx1ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBrZXkgKGFuZCBpdHMgY29ycmVzcG9uZGluZyB2YWx1ZSkgZnJvbSB0aGlzIG1hcC4KKyAgICAgKiBUaGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcgaWYgdGhlIGtleSBpcyBub3QgaW4gdGhlIG1hcC4KKyAgICAgKgorICAgICAqIEBwYXJhbSAga2V5IHRoZSBrZXkgdGhhdCBuZWVkcyB0byBiZSByZW1vdmVkCisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIDx0dD5rZXk8L3R0Piwgb3IKKyAgICAgKiAgICAgICAgIDx0dD5udWxsPC90dD4gaWYgdGhlcmUgd2FzIG5vIG1hcHBpbmcgZm9yIDx0dD5rZXk8L3R0PgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBWIHJlbW92ZShPYmplY3Qga2V5KSB7CisgICAgICAgIGludCBoYXNoID0gaGFzaChrZXkuaGFzaENvZGUoKSk7CisgICAgICAgIHJldHVybiBzZWdtZW50Rm9yKGhhc2gpLnJlbW92ZShrZXksIGhhc2gsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3Qga2V5LCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaW50IGhhc2ggPSBoYXNoKGtleS5oYXNoQ29kZSgpKTsKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIHJldHVybiBzZWdtZW50Rm9yKGhhc2gpLnJlbW92ZShrZXksIGhhc2gsIHZhbHVlKSAhPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgYW55IG9mIHRoZSBhcmd1bWVudHMgYXJlIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiByZXBsYWNlKEsga2V5LCBWIG9sZFZhbHVlLCBWIG5ld1ZhbHVlKSB7CisgICAgICAgIGlmIChvbGRWYWx1ZSA9PSBudWxsIHx8IG5ld1ZhbHVlID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgaW50IGhhc2ggPSBoYXNoKGtleS5oYXNoQ29kZSgpKTsKKyAgICAgICAgcmV0dXJuIHNlZ21lbnRGb3IoaGFzaCkucmVwbGFjZShrZXksIGhhc2gsIG9sZFZhbHVlLCBuZXdWYWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LAorICAgICAqICAgICAgICAgb3IgPHR0Pm51bGw8L3R0PiBpZiB0aGVyZSB3YXMgbm8gbWFwcGluZyBmb3IgdGhlIGtleQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgb3IgdmFsdWUgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBWIHJlcGxhY2UoSyBrZXksIFYgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgaW50IGhhc2ggPSBoYXNoKGtleS5oYXNoQ29kZSgpKTsKKyAgICAgICAgcmV0dXJuIHNlZ21lbnRGb3IoaGFzaCkucmVwbGFjZShrZXksIGhhc2gsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGFsbCBvZiB0aGUgbWFwcGluZ3MgZnJvbSB0aGlzIG1hcC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGg7ICsraSkKKyAgICAgICAgICAgIHNlZ21lbnRzW2ldLmNsZWFyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAbGluayBTZXR9IHZpZXcgb2YgdGhlIGtleXMgY29udGFpbmVkIGluIHRoaXMgbWFwLgorICAgICAqIFRoZSBzZXQgaXMgYmFja2VkIGJ5IHRoZSBtYXAsIHNvIGNoYW5nZXMgdG8gdGhlIG1hcCBhcmUKKyAgICAgKiByZWZsZWN0ZWQgaW4gdGhlIHNldCwgYW5kIHZpY2UtdmVyc2EuICBUaGUgc2V0IHN1cHBvcnRzIGVsZW1lbnQKKyAgICAgKiByZW1vdmFsLCB3aGljaCByZW1vdmVzIHRoZSBjb3JyZXNwb25kaW5nIG1hcHBpbmcgZnJvbSB0aGlzIG1hcCwKKyAgICAgKiB2aWEgdGhlIDx0dD5JdGVyYXRvci5yZW1vdmU8L3R0PiwgPHR0PlNldC5yZW1vdmU8L3R0PiwKKyAgICAgKiA8dHQ+cmVtb3ZlQWxsPC90dD4sIDx0dD5yZXRhaW5BbGw8L3R0PiwgYW5kIDx0dD5jbGVhcjwvdHQ+CisgICAgICogb3BlcmF0aW9ucy4gIEl0IGRvZXMgbm90IHN1cHBvcnQgdGhlIDx0dD5hZGQ8L3R0PiBvcgorICAgICAqIDx0dD5hZGRBbGw8L3R0PiBvcGVyYXRpb25zLgorICAgICAqCisgICAgICogPHA+VGhlIHZpZXcncyA8dHQ+aXRlcmF0b3I8L3R0PiBpcyBhICJ3ZWFrbHkgY29uc2lzdGVudCIgaXRlcmF0b3IKKyAgICAgKiB0aGF0IHdpbGwgbmV2ZXIgdGhyb3cge0BsaW5rIENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb259LAorICAgICAqIGFuZCBndWFyYW50ZWVzIHRvIHRyYXZlcnNlIGVsZW1lbnRzIGFzIHRoZXkgZXhpc3RlZCB1cG9uCisgICAgICogY29uc3RydWN0aW9uIG9mIHRoZSBpdGVyYXRvciwgYW5kIG1heSAoYnV0IGlzIG5vdCBndWFyYW50ZWVkIHRvKQorICAgICAqIHJlZmxlY3QgYW55IG1vZGlmaWNhdGlvbnMgc3Vic2VxdWVudCB0byBjb25zdHJ1Y3Rpb24uCisgICAgICovCisgICAgcHVibGljIFNldDxLPiBrZXlTZXQoKSB7CisgICAgICAgIFNldDxLPiBrcyA9IGtleVNldDsKKyAgICAgICAgcmV0dXJuIChrcyAhPSBudWxsKSA/IGtzIDogKGtleVNldCA9IG5ldyBLZXlTZXQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAbGluayBDb2xsZWN0aW9ufSB2aWV3IG9mIHRoZSB2YWx1ZXMgY29udGFpbmVkIGluIHRoaXMgbWFwLgorICAgICAqIFRoZSBjb2xsZWN0aW9uIGlzIGJhY2tlZCBieSB0aGUgbWFwLCBzbyBjaGFuZ2VzIHRvIHRoZSBtYXAgYXJlCisgICAgICogcmVmbGVjdGVkIGluIHRoZSBjb2xsZWN0aW9uLCBhbmQgdmljZS12ZXJzYS4gIFRoZSBjb2xsZWN0aW9uCisgICAgICogc3VwcG9ydHMgZWxlbWVudCByZW1vdmFsLCB3aGljaCByZW1vdmVzIHRoZSBjb3JyZXNwb25kaW5nCisgICAgICogbWFwcGluZyBmcm9tIHRoaXMgbWFwLCB2aWEgdGhlIDx0dD5JdGVyYXRvci5yZW1vdmU8L3R0PiwKKyAgICAgKiA8dHQ+Q29sbGVjdGlvbi5yZW1vdmU8L3R0PiwgPHR0PnJlbW92ZUFsbDwvdHQ+LAorICAgICAqIDx0dD5yZXRhaW5BbGw8L3R0PiwgYW5kIDx0dD5jbGVhcjwvdHQ+IG9wZXJhdGlvbnMuICBJdCBkb2VzIG5vdAorICAgICAqIHN1cHBvcnQgdGhlIDx0dD5hZGQ8L3R0PiBvciA8dHQ+YWRkQWxsPC90dD4gb3BlcmF0aW9ucy4KKyAgICAgKgorICAgICAqIDxwPlRoZSB2aWV3J3MgPHR0Pml0ZXJhdG9yPC90dD4gaXMgYSAid2Vha2x5IGNvbnNpc3RlbnQiIGl0ZXJhdG9yCisgICAgICogdGhhdCB3aWxsIG5ldmVyIHRocm93IHtAbGluayBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9ufSwKKyAgICAgKiBhbmQgZ3VhcmFudGVlcyB0byB0cmF2ZXJzZSBlbGVtZW50cyBhcyB0aGV5IGV4aXN0ZWQgdXBvbgorICAgICAqIGNvbnN0cnVjdGlvbiBvZiB0aGUgaXRlcmF0b3IsIGFuZCBtYXkgKGJ1dCBpcyBub3QgZ3VhcmFudGVlZCB0bykKKyAgICAgKiByZWZsZWN0IGFueSBtb2RpZmljYXRpb25zIHN1YnNlcXVlbnQgdG8gY29uc3RydWN0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBDb2xsZWN0aW9uPFY+IHZhbHVlcygpIHsKKyAgICAgICAgQ29sbGVjdGlvbjxWPiB2cyA9IHZhbHVlczsKKyAgICAgICAgcmV0dXJuICh2cyAhPSBudWxsKSA/IHZzIDogKHZhbHVlcyA9IG5ldyBWYWx1ZXMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAbGluayBTZXR9IHZpZXcgb2YgdGhlIG1hcHBpbmdzIGNvbnRhaW5lZCBpbiB0aGlzIG1hcC4KKyAgICAgKiBUaGUgc2V0IGlzIGJhY2tlZCBieSB0aGUgbWFwLCBzbyBjaGFuZ2VzIHRvIHRoZSBtYXAgYXJlCisgICAgICogcmVmbGVjdGVkIGluIHRoZSBzZXQsIGFuZCB2aWNlLXZlcnNhLiAgVGhlIHNldCBzdXBwb3J0cyBlbGVtZW50CisgICAgICogcmVtb3ZhbCwgd2hpY2ggcmVtb3ZlcyB0aGUgY29ycmVzcG9uZGluZyBtYXBwaW5nIGZyb20gdGhlIG1hcCwKKyAgICAgKiB2aWEgdGhlIDx0dD5JdGVyYXRvci5yZW1vdmU8L3R0PiwgPHR0PlNldC5yZW1vdmU8L3R0PiwKKyAgICAgKiA8dHQ+cmVtb3ZlQWxsPC90dD4sIDx0dD5yZXRhaW5BbGw8L3R0PiwgYW5kIDx0dD5jbGVhcjwvdHQ+CisgICAgICogb3BlcmF0aW9ucy4gIEl0IGRvZXMgbm90IHN1cHBvcnQgdGhlIDx0dD5hZGQ8L3R0PiBvcgorICAgICAqIDx0dD5hZGRBbGw8L3R0PiBvcGVyYXRpb25zLgorICAgICAqCisgICAgICogPHA+VGhlIHZpZXcncyA8dHQ+aXRlcmF0b3I8L3R0PiBpcyBhICJ3ZWFrbHkgY29uc2lzdGVudCIgaXRlcmF0b3IKKyAgICAgKiB0aGF0IHdpbGwgbmV2ZXIgdGhyb3cge0BsaW5rIENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb259LAorICAgICAqIGFuZCBndWFyYW50ZWVzIHRvIHRyYXZlcnNlIGVsZW1lbnRzIGFzIHRoZXkgZXhpc3RlZCB1cG9uCisgICAgICogY29uc3RydWN0aW9uIG9mIHRoZSBpdGVyYXRvciwgYW5kIG1heSAoYnV0IGlzIG5vdCBndWFyYW50ZWVkIHRvKQorICAgICAqIHJlZmxlY3QgYW55IG1vZGlmaWNhdGlvbnMgc3Vic2VxdWVudCB0byBjb25zdHJ1Y3Rpb24uCisgICAgICovCisgICAgcHVibGljIFNldDxNYXAuRW50cnk8SyxWPj4gZW50cnlTZXQoKSB7CisgICAgICAgIFNldDxNYXAuRW50cnk8SyxWPj4gZXMgPSBlbnRyeVNldDsKKyAgICAgICAgcmV0dXJuIChlcyAhPSBudWxsKSA/IGVzIDogKGVudHJ5U2V0ID0gbmV3IEVudHJ5U2V0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gZW51bWVyYXRpb24gb2YgdGhlIGtleXMgaW4gdGhpcyB0YWJsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gZW51bWVyYXRpb24gb2YgdGhlIGtleXMgaW4gdGhpcyB0YWJsZQorICAgICAqIEBzZWUgI2tleVNldCgpCisgICAgICovCisgICAgcHVibGljIEVudW1lcmF0aW9uPEs+IGtleXMoKSB7CisgICAgICAgIHJldHVybiBuZXcgS2V5SXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGVudW1lcmF0aW9uIG9mIHRoZSB2YWx1ZXMgaW4gdGhpcyB0YWJsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gZW51bWVyYXRpb24gb2YgdGhlIHZhbHVlcyBpbiB0aGlzIHRhYmxlCisgICAgICogQHNlZSAjdmFsdWVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bWVyYXRpb248Vj4gZWxlbWVudHMoKSB7CisgICAgICAgIHJldHVybiBuZXcgVmFsdWVJdGVyYXRvcigpOworICAgIH0KKworICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0gSXRlcmF0b3IgU3VwcG9ydCAtLS0tLS0tLS0tLS0tLSAqLworCisgICAgYWJzdHJhY3QgY2xhc3MgSGFzaEl0ZXJhdG9yIHsKKyAgICAgICAgaW50IG5leHRTZWdtZW50SW5kZXg7CisgICAgICAgIGludCBuZXh0VGFibGVJbmRleDsKKyAgICAgICAgSGFzaEVudHJ5PEssVj5bXSBjdXJyZW50VGFibGU7CisgICAgICAgIEhhc2hFbnRyeTxLLCBWPiBuZXh0RW50cnk7CisgICAgICAgIEhhc2hFbnRyeTxLLCBWPiBsYXN0UmV0dXJuZWQ7CisKKyAgICAgICAgSGFzaEl0ZXJhdG9yKCkgeworICAgICAgICAgICAgbmV4dFNlZ21lbnRJbmRleCA9IHNlZ21lbnRzLmxlbmd0aCAtIDE7CisgICAgICAgICAgICBuZXh0VGFibGVJbmRleCA9IC0xOworICAgICAgICAgICAgYWR2YW5jZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTW9yZUVsZW1lbnRzKCkgeyByZXR1cm4gaGFzTmV4dCgpOyB9CisKKyAgICAgICAgZmluYWwgdm9pZCBhZHZhbmNlKCkgeworICAgICAgICAgICAgaWYgKG5leHRFbnRyeSAhPSBudWxsICYmIChuZXh0RW50cnkgPSBuZXh0RW50cnkubmV4dCkgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICByZXR1cm47CisKKyAgICAgICAgICAgIHdoaWxlIChuZXh0VGFibGVJbmRleCA+PSAwKSB7CisgICAgICAgICAgICAgICAgaWYgKCAobmV4dEVudHJ5ID0gY3VycmVudFRhYmxlW25leHRUYWJsZUluZGV4LS1dKSAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHdoaWxlIChuZXh0U2VnbWVudEluZGV4ID49IDApIHsKKyAgICAgICAgICAgICAgICBTZWdtZW50PEssVj4gc2VnID0gc2VnbWVudHNbbmV4dFNlZ21lbnRJbmRleC0tXTsKKyAgICAgICAgICAgICAgICBpZiAoc2VnLmNvdW50ICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgY3VycmVudFRhYmxlID0gc2VnLnRhYmxlOworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gY3VycmVudFRhYmxlLmxlbmd0aCAtIDE7IGogPj0gMDsgLS1qKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIChuZXh0RW50cnkgPSBjdXJyZW50VGFibGVbal0pICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0VGFibGVJbmRleCA9IGogLSAxOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7IHJldHVybiBuZXh0RW50cnkgIT0gbnVsbDsgfQorCisgICAgICAgIEhhc2hFbnRyeTxLLFY+IG5leHRFbnRyeSgpIHsKKyAgICAgICAgICAgIGlmIChuZXh0RW50cnkgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgbGFzdFJldHVybmVkID0gbmV4dEVudHJ5OworICAgICAgICAgICAgYWR2YW5jZSgpOworICAgICAgICAgICAgcmV0dXJuIGxhc3RSZXR1cm5lZDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgIGlmIChsYXN0UmV0dXJuZWQgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBDb25jdXJyZW50SGFzaE1hcC50aGlzLnJlbW92ZShsYXN0UmV0dXJuZWQua2V5KTsKKyAgICAgICAgICAgIGxhc3RSZXR1cm5lZCA9IG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBmaW5hbCBjbGFzcyBLZXlJdGVyYXRvcgorICAgICAgICBleHRlbmRzIEhhc2hJdGVyYXRvcgorICAgICAgICBpbXBsZW1lbnRzIEl0ZXJhdG9yPEs+LCBFbnVtZXJhdGlvbjxLPgorICAgIHsKKyAgICAgICAgcHVibGljIEsgbmV4dCgpICAgICAgICB7IHJldHVybiBzdXBlci5uZXh0RW50cnkoKS5rZXk7IH0KKyAgICAgICAgcHVibGljIEsgbmV4dEVsZW1lbnQoKSB7IHJldHVybiBzdXBlci5uZXh0RW50cnkoKS5rZXk7IH0KKyAgICB9CisKKyAgICBmaW5hbCBjbGFzcyBWYWx1ZUl0ZXJhdG9yCisgICAgICAgIGV4dGVuZHMgSGFzaEl0ZXJhdG9yCisgICAgICAgIGltcGxlbWVudHMgSXRlcmF0b3I8Vj4sIEVudW1lcmF0aW9uPFY+CisgICAgeworICAgICAgICBwdWJsaWMgViBuZXh0KCkgICAgICAgIHsgcmV0dXJuIHN1cGVyLm5leHRFbnRyeSgpLnZhbHVlOyB9CisgICAgICAgIHB1YmxpYyBWIG5leHRFbGVtZW50KCkgeyByZXR1cm4gc3VwZXIubmV4dEVudHJ5KCkudmFsdWU7IH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDdXN0b20gRW50cnkgY2xhc3MgdXNlZCBieSBFbnRyeUl0ZXJhdG9yLm5leHQoKSwgdGhhdCByZWxheXMKKyAgICAgKiBzZXRWYWx1ZSBjaGFuZ2VzIHRvIHRoZSB1bmRlcmx5aW5nIG1hcC4KKyAgICAgKi8KKyAgICBmaW5hbCBjbGFzcyBXcml0ZVRocm91Z2hFbnRyeQorICAgICAgICBleHRlbmRzIEFic3RyYWN0TWFwLlNpbXBsZUVudHJ5PEssVj4KKyAgICB7CisgICAgICAgIFdyaXRlVGhyb3VnaEVudHJ5KEsgaywgViB2KSB7CisgICAgICAgICAgICBzdXBlcihrLHYpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNldCBvdXIgZW50cnkncyB2YWx1ZSBhbmQgd3JpdGUgdGhyb3VnaCB0byB0aGUgbWFwLiBUaGUKKyAgICAgICAgICogdmFsdWUgdG8gcmV0dXJuIGlzIHNvbWV3aGF0IGFyYml0cmFyeSBoZXJlLiBTaW5jZSBhCisgICAgICAgICAqIFdyaXRlVGhyb3VnaEVudHJ5IGRvZXMgbm90IG5lY2Vzc2FyaWx5IHRyYWNrIGFzeW5jaHJvbm91cworICAgICAgICAgKiBjaGFuZ2VzLCB0aGUgbW9zdCByZWNlbnQgInByZXZpb3VzIiB2YWx1ZSBjb3VsZCBiZQorICAgICAgICAgKiBkaWZmZXJlbnQgZnJvbSB3aGF0IHdlIHJldHVybiAob3IgY291bGQgZXZlbiBoYXZlIGJlZW4KKyAgICAgICAgICogcmVtb3ZlZCBpbiB3aGljaCBjYXNlIHRoZSBwdXQgd2lsbCByZS1lc3RhYmxpc2gpLiBXZSBkbyBub3QKKyAgICAgICAgICogYW5kIGNhbm5vdCBndWFyYW50ZWUgbW9yZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBWIHNldFZhbHVlKFYgdmFsdWUpIHsKKyAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIFYgdiA9IHN1cGVyLnNldFZhbHVlKHZhbHVlKTsKKyAgICAgICAgICAgIENvbmN1cnJlbnRIYXNoTWFwLnRoaXMucHV0KGdldEtleSgpLCB2YWx1ZSk7CisgICAgICAgICAgICByZXR1cm4gdjsKKyAgICAgICAgfQorICAgIH0KKworICAgIGZpbmFsIGNsYXNzIEVudHJ5SXRlcmF0b3IKKyAgICAgICAgZXh0ZW5kcyBIYXNoSXRlcmF0b3IKKyAgICAgICAgaW1wbGVtZW50cyBJdGVyYXRvcjxFbnRyeTxLLFY+PgorICAgIHsKKyAgICAgICAgcHVibGljIE1hcC5FbnRyeTxLLFY+IG5leHQoKSB7CisgICAgICAgICAgICBIYXNoRW50cnk8SyxWPiBlID0gc3VwZXIubmV4dEVudHJ5KCk7CisgICAgICAgICAgICByZXR1cm4gbmV3IFdyaXRlVGhyb3VnaEVudHJ5KGUua2V5LCBlLnZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGZpbmFsIGNsYXNzIEtleVNldCBleHRlbmRzIEFic3RyYWN0U2V0PEs+IHsKKyAgICAgICAgcHVibGljIEl0ZXJhdG9yPEs+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBLZXlJdGVyYXRvcigpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBDb25jdXJyZW50SGFzaE1hcC50aGlzLnNpemUoKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICAgICAgcmV0dXJuIENvbmN1cnJlbnRIYXNoTWFwLnRoaXMuaXNFbXB0eSgpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKSB7CisgICAgICAgICAgICByZXR1cm4gQ29uY3VycmVudEhhc2hNYXAudGhpcy5jb250YWluc0tleShvKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIHJldHVybiBDb25jdXJyZW50SGFzaE1hcC50aGlzLnJlbW92ZShvKSAhPSBudWxsOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICAgICAgQ29uY3VycmVudEhhc2hNYXAudGhpcy5jbGVhcigpOworICAgICAgICB9CisgICAgfQorCisgICAgZmluYWwgY2xhc3MgVmFsdWVzIGV4dGVuZHMgQWJzdHJhY3RDb2xsZWN0aW9uPFY+IHsKKyAgICAgICAgcHVibGljIEl0ZXJhdG9yPFY+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBWYWx1ZUl0ZXJhdG9yKCk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgcmV0dXJuIENvbmN1cnJlbnRIYXNoTWFwLnRoaXMuc2l6ZSgpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICByZXR1cm4gQ29uY3VycmVudEhhc2hNYXAudGhpcy5pc0VtcHR5KCk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIHJldHVybiBDb25jdXJyZW50SGFzaE1hcC50aGlzLmNvbnRhaW5zVmFsdWUobyk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICBDb25jdXJyZW50SGFzaE1hcC50aGlzLmNsZWFyKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBmaW5hbCBjbGFzcyBFbnRyeVNldCBleHRlbmRzIEFic3RyYWN0U2V0PE1hcC5FbnRyeTxLLFY+PiB7CisgICAgICAgIHB1YmxpYyBJdGVyYXRvcjxNYXAuRW50cnk8SyxWPj4gaXRlcmF0b3IoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEVudHJ5SXRlcmF0b3IoKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3QgbykgeworICAgICAgICAgICAgaWYgKCEobyBpbnN0YW5jZW9mIE1hcC5FbnRyeSkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgTWFwLkVudHJ5PD8sPz4gZSA9IChNYXAuRW50cnk8Pyw/PilvOworICAgICAgICAgICAgViB2ID0gQ29uY3VycmVudEhhc2hNYXAudGhpcy5nZXQoZS5nZXRLZXkoKSk7CisgICAgICAgICAgICByZXR1cm4gdiAhPSBudWxsICYmIHYuZXF1YWxzKGUuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvKSB7CisgICAgICAgICAgICBpZiAoIShvIGluc3RhbmNlb2YgTWFwLkVudHJ5KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICBNYXAuRW50cnk8Pyw/PiBlID0gKE1hcC5FbnRyeTw/LD8+KW87CisgICAgICAgICAgICByZXR1cm4gQ29uY3VycmVudEhhc2hNYXAudGhpcy5yZW1vdmUoZS5nZXRLZXkoKSwgZS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gQ29uY3VycmVudEhhc2hNYXAudGhpcy5zaXplKCk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgICAgIHJldHVybiBDb25jdXJyZW50SGFzaE1hcC50aGlzLmlzRW1wdHkoKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgICAgIENvbmN1cnJlbnRIYXNoTWFwLnRoaXMuY2xlYXIoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0gU2VyaWFsaXphdGlvbiBTdXBwb3J0IC0tLS0tLS0tLS0tLS0tICovCisKKyAgICAvKioKKyAgICAgKiBTYXZlIHRoZSBzdGF0ZSBvZiB0aGUgPHR0PkNvbmN1cnJlbnRIYXNoTWFwPC90dD4gaW5zdGFuY2UgdG8gYQorICAgICAqIHN0cmVhbSAoaS5lLiwgc2VyaWFsaXplIGl0KS4KKyAgICAgKiBAcGFyYW0gcyB0aGUgc3RyZWFtCisgICAgICogQHNlcmlhbERhdGEKKyAgICAgKiB0aGUga2V5IChPYmplY3QpIGFuZCB2YWx1ZSAoT2JqZWN0KQorICAgICAqIGZvciBlYWNoIGtleS12YWx1ZSBtYXBwaW5nLCBmb2xsb3dlZCBieSBhIG51bGwgcGFpci4KKyAgICAgKiBUaGUga2V5LXZhbHVlIG1hcHBpbmdzIGFyZSBlbWl0dGVkIGluIG5vIHBhcnRpY3VsYXIgb3JkZXIuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtIHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHMuZGVmYXVsdFdyaXRlT2JqZWN0KCk7CisKKyAgICAgICAgZm9yIChpbnQgayA9IDA7IGsgPCBzZWdtZW50cy5sZW5ndGg7ICsraykgeworICAgICAgICAgICAgU2VnbWVudDxLLFY+IHNlZyA9IHNlZ21lbnRzW2tdOworICAgICAgICAgICAgc2VnLmxvY2soKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgSGFzaEVudHJ5PEssVj5bXSB0YWIgPSBzZWcudGFibGU7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0YWIubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChIYXNoRW50cnk8SyxWPiBlID0gdGFiW2ldOyBlICE9IG51bGw7IGUgPSBlLm5leHQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHMud3JpdGVPYmplY3QoZS5rZXkpOworICAgICAgICAgICAgICAgICAgICAgICAgcy53cml0ZU9iamVjdChlLnZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgc2VnLnVubG9jaygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHMud3JpdGVPYmplY3QobnVsbCk7CisgICAgICAgIHMud3JpdGVPYmplY3QobnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVjb25zdGl0dXRlIHRoZSA8dHQ+Q29uY3VycmVudEhhc2hNYXA8L3R0PiBpbnN0YW5jZSBmcm9tIGEKKyAgICAgKiBzdHJlYW0gKGkuZS4sIGRlc2VyaWFsaXplIGl0KS4KKyAgICAgKiBAcGFyYW0gcyB0aGUgc3RyZWFtCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSBzKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBzLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisKKyAgICAgICAgLy8gSW5pdGlhbGl6ZSBlYWNoIHNlZ21lbnQgdG8gYmUgbWluaW1hbGx5IHNpemVkLCBhbmQgbGV0IGdyb3cuCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2VnbWVudHMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIHNlZ21lbnRzW2ldLnNldFRhYmxlKG5ldyBIYXNoRW50cnlbMV0pOworICAgICAgICB9CisKKyAgICAgICAgLy8gUmVhZCB0aGUga2V5cyBhbmQgdmFsdWVzLCBhbmQgcHV0IHRoZSBtYXBwaW5ncyBpbiB0aGUgdGFibGUKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgSyBrZXkgPSAoSykgcy5yZWFkT2JqZWN0KCk7CisgICAgICAgICAgICBWIHZhbHVlID0gKFYpIHMucmVhZE9iamVjdCgpOworICAgICAgICAgICAgaWYgKGtleSA9PSBudWxsKQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgcHV0KGtleSwgdmFsdWUpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0NvbmN1cnJlbnRMaW5rZWREZXF1ZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0NvbmN1cnJlbnRMaW5rZWREZXF1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcyYzJlMDgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQ29uY3VycmVudExpbmtlZERlcXVlLmphdmEKQEAgLTAsMCArMSwxNDI2IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSBhbmQgTWFydGluIEJ1Y2hob2x6IHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YKKyAqIEpDUCBKU1ItMTY2IEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZAorICogYXQgaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudDsKKworaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdENvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuRGVxdWU7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5RdWV1ZTsKKworLy8gQkVHSU4gYW5kcm9pZC1ub3RlCisvLyByZW1vdmVkIGxpbmsgdG8gY29sbGVjdGlvbnMgZnJhbWV3b3JrIGRvY3MKKy8vIEVORCBhbmRyb2lkLW5vdGUKKworLyoqCisgKiBBbiB1bmJvdW5kZWQgY29uY3VycmVudCB7QGxpbmtwbGFpbiBEZXF1ZSBkZXF1ZX0gYmFzZWQgb24gbGlua2VkIG5vZGVzLgorICogQ29uY3VycmVudCBpbnNlcnRpb24sIHJlbW92YWwsIGFuZCBhY2Nlc3Mgb3BlcmF0aW9ucyBleGVjdXRlIHNhZmVseQorICogYWNyb3NzIG11bHRpcGxlIHRocmVhZHMuCisgKiBBIHtAY29kZSBDb25jdXJyZW50TGlua2VkRGVxdWV9IGlzIGFuIGFwcHJvcHJpYXRlIGNob2ljZSB3aGVuCisgKiBtYW55IHRocmVhZHMgd2lsbCBzaGFyZSBhY2Nlc3MgdG8gYSBjb21tb24gY29sbGVjdGlvbi4KKyAqIExpa2UgbW9zdCBvdGhlciBjb25jdXJyZW50IGNvbGxlY3Rpb24gaW1wbGVtZW50YXRpb25zLCB0aGlzIGNsYXNzCisgKiBkb2VzIG5vdCBwZXJtaXQgdGhlIHVzZSBvZiB7QGNvZGUgbnVsbH0gZWxlbWVudHMuCisgKgorICogPHA+SXRlcmF0b3JzIGFyZSA8aT53ZWFrbHkgY29uc2lzdGVudDwvaT4sIHJldHVybmluZyBlbGVtZW50cworICogcmVmbGVjdGluZyB0aGUgc3RhdGUgb2YgdGhlIGRlcXVlIGF0IHNvbWUgcG9pbnQgYXQgb3Igc2luY2UgdGhlCisgKiBjcmVhdGlvbiBvZiB0aGUgaXRlcmF0b3IuICBUaGV5IGRvIDxlbT5ub3Q8L2VtPiB0aHJvdyB7QGxpbmsKKyAqIGphdmEudXRpbC5Db25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uCisgKiBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9ufSwgYW5kIG1heSBwcm9jZWVkIGNvbmN1cnJlbnRseSB3aXRoCisgKiBvdGhlciBvcGVyYXRpb25zLgorICoKKyAqIDxwPkJld2FyZSB0aGF0LCB1bmxpa2UgaW4gbW9zdCBjb2xsZWN0aW9ucywgdGhlIHtAY29kZSBzaXplfQorICogbWV0aG9kIGlzIDxlbT5OT1Q8L2VtPiBhIGNvbnN0YW50LXRpbWUgb3BlcmF0aW9uLiBCZWNhdXNlIG9mIHRoZQorICogYXN5bmNocm9ub3VzIG5hdHVyZSBvZiB0aGVzZSBkZXF1ZXMsIGRldGVybWluaW5nIHRoZSBjdXJyZW50IG51bWJlcgorICogb2YgZWxlbWVudHMgcmVxdWlyZXMgYSB0cmF2ZXJzYWwgb2YgdGhlIGVsZW1lbnRzLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgYW5kIGl0cyBpdGVyYXRvciBpbXBsZW1lbnQgYWxsIG9mIHRoZSA8ZW0+b3B0aW9uYWw8L2VtPgorICogbWV0aG9kcyBvZiB0aGUge0BsaW5rIERlcXVlfSBhbmQge0BsaW5rIEl0ZXJhdG9yfSBpbnRlcmZhY2VzLgorICoKKyAqIDxwPk1lbW9yeSBjb25zaXN0ZW5jeSBlZmZlY3RzOiBBcyB3aXRoIG90aGVyIGNvbmN1cnJlbnQgY29sbGVjdGlvbnMsCisgKiBhY3Rpb25zIGluIGEgdGhyZWFkIHByaW9yIHRvIHBsYWNpbmcgYW4gb2JqZWN0IGludG8gYQorICoge0Bjb2RlIENvbmN1cnJlbnRMaW5rZWREZXF1ZX0KKyAqIDxhIGhyZWY9InBhY2thZ2Utc3VtbWFyeS5odG1sI01lbW9yeVZpc2liaWxpdHkiPjxpPmhhcHBlbi1iZWZvcmU8L2k+PC9hPgorICogYWN0aW9ucyBzdWJzZXF1ZW50IHRvIHRoZSBhY2Nlc3Mgb3IgcmVtb3ZhbCBvZiB0aGF0IGVsZW1lbnQgZnJvbQorICogdGhlIHtAY29kZSBDb25jdXJyZW50TGlua2VkRGVxdWV9IGluIGFub3RoZXIgdGhyZWFkLgorICoKKyAqIEBoaWRlCisgKgorICogQHNpbmNlIDEuNworICogQGF1dGhvciBEb3VnIExlYQorICogQGF1dGhvciBNYXJ0aW4gQnVjaGhvbHoKKyAqIEBwYXJhbSA8RT4gdGhlIHR5cGUgb2YgZWxlbWVudHMgaGVsZCBpbiB0aGlzIGNvbGxlY3Rpb24KKyAqLworCitwdWJsaWMgY2xhc3MgQ29uY3VycmVudExpbmtlZERlcXVlPEU+CisgICAgZXh0ZW5kcyBBYnN0cmFjdENvbGxlY3Rpb248RT4KKyAgICBpbXBsZW1lbnRzIERlcXVlPEU+LCBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisKKyAgICAvKgorICAgICAqIFRoaXMgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgYSBjb25jdXJyZW50IGxvY2stZnJlZSBkZXF1ZQorICAgICAqIHN1cHBvcnRpbmcgaW50ZXJpb3IgcmVtb3ZlcyBidXQgbm90IGludGVyaW9yIGluc2VydGlvbnMsIGFzCisgICAgICogcmVxdWlyZWQgdG8gc3VwcG9ydCB0aGUgZW50aXJlIERlcXVlIGludGVyZmFjZS4KKyAgICAgKgorICAgICAqIFdlIGV4dGVuZCB0aGUgdGVjaG5pcXVlcyBkZXZlbG9wZWQgZm9yIENvbmN1cnJlbnRMaW5rZWRRdWV1ZSBhbmQKKyAgICAgKiBMaW5rZWRUcmFuc2ZlclF1ZXVlIChzZWUgdGhlIGludGVybmFsIGRvY3MgZm9yIHRob3NlIGNsYXNzZXMpLgorICAgICAqIFVuZGVyc3RhbmRpbmcgdGhlIENvbmN1cnJlbnRMaW5rZWRRdWV1ZSBpbXBsZW1lbnRhdGlvbiBpcyBhCisgICAgICogcHJlcmVxdWlzaXRlIGZvciB1bmRlcnN0YW5kaW5nIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGNsYXNzLgorICAgICAqCisgICAgICogVGhlIGRhdGEgc3RydWN0dXJlIGlzIGEgc3ltbWV0cmljYWwgZG91Ymx5LWxpbmtlZCAiR0Mtcm9idXN0IgorICAgICAqIGxpbmtlZCBsaXN0IG9mIG5vZGVzLiAgV2UgbWluaW1pemUgdGhlIG51bWJlciBvZiB2b2xhdGlsZSB3cml0ZXMKKyAgICAgKiB1c2luZyB0d28gdGVjaG5pcXVlczogYWR2YW5jaW5nIG11bHRpcGxlIGhvcHMgd2l0aCBhIHNpbmdsZSBDQVMKKyAgICAgKiBhbmQgbWl4aW5nIHZvbGF0aWxlIGFuZCBub24tdm9sYXRpbGUgd3JpdGVzIG9mIHRoZSBzYW1lIG1lbW9yeQorICAgICAqIGxvY2F0aW9ucy4KKyAgICAgKgorICAgICAqIEEgbm9kZSBjb250YWlucyB0aGUgZXhwZWN0ZWQgRSAoIml0ZW0iKSBhbmQgbGlua3MgdG8gcHJlZGVjZXNzb3IKKyAgICAgKiAoInByZXYiKSBhbmQgc3VjY2Vzc29yICgibmV4dCIpIG5vZGVzOgorICAgICAqCisgICAgICogY2xhc3MgTm9kZTxFPiB7IHZvbGF0aWxlIE5vZGU8RT4gcHJldiwgbmV4dDsgdm9sYXRpbGUgRSBpdGVtOyB9CisgICAgICoKKyAgICAgKiBBIG5vZGUgcCBpcyBjb25zaWRlcmVkICJsaXZlIiBpZiBpdCBjb250YWlucyBhIG5vbi1udWxsIGl0ZW0KKyAgICAgKiAocC5pdGVtICE9IG51bGwpLiAgV2hlbiBhbiBpdGVtIGlzIENBU2VkIHRvIG51bGwsIHRoZSBpdGVtIGlzCisgICAgICogYXRvbWljYWxseSBsb2dpY2FsbHkgZGVsZXRlZCBmcm9tIHRoZSBjb2xsZWN0aW9uLgorICAgICAqCisgICAgICogQXQgYW55IHRpbWUsIHRoZXJlIGlzIHByZWNpc2VseSBvbmUgImZpcnN0IiBub2RlIHdpdGggYSBudWxsCisgICAgICogcHJldiByZWZlcmVuY2UgdGhhdCB0ZXJtaW5hdGVzIGFueSBjaGFpbiBvZiBwcmV2IHJlZmVyZW5jZXMKKyAgICAgKiBzdGFydGluZyBhdCBhIGxpdmUgbm9kZS4gIFNpbWlsYXJseSB0aGVyZSBpcyBwcmVjaXNlbHkgb25lCisgICAgICogImxhc3QiIG5vZGUgdGVybWluYXRpbmcgYW55IGNoYWluIG9mIG5leHQgcmVmZXJlbmNlcyBzdGFydGluZyBhdAorICAgICAqIGEgbGl2ZSBub2RlLiAgVGhlICJmaXJzdCIgYW5kICJsYXN0IiBub2RlcyBtYXkgb3IgbWF5IG5vdCBiZSBsaXZlLgorICAgICAqIFRoZSAiZmlyc3QiIGFuZCAibGFzdCIgbm9kZXMgYXJlIGFsd2F5cyBtdXR1YWxseSByZWFjaGFibGUuCisgICAgICoKKyAgICAgKiBBIG5ldyBlbGVtZW50IGlzIGFkZGVkIGF0b21pY2FsbHkgYnkgQ0FTaW5nIHRoZSBudWxsIHByZXYgb3IKKyAgICAgKiBuZXh0IHJlZmVyZW5jZSBpbiB0aGUgZmlyc3Qgb3IgbGFzdCBub2RlIHRvIGEgZnJlc2ggbm9kZQorICAgICAqIGNvbnRhaW5pbmcgdGhlIGVsZW1lbnQuICBUaGUgZWxlbWVudCdzIG5vZGUgYXRvbWljYWxseSBiZWNvbWVzCisgICAgICogImxpdmUiIGF0IHRoYXQgcG9pbnQuCisgICAgICoKKyAgICAgKiBBIG5vZGUgaXMgY29uc2lkZXJlZCAiYWN0aXZlIiBpZiBpdCBpcyBhIGxpdmUgbm9kZSwgb3IgdGhlCisgICAgICogZmlyc3Qgb3IgbGFzdCBub2RlLiAgQWN0aXZlIG5vZGVzIGNhbm5vdCBiZSB1bmxpbmtlZC4KKyAgICAgKgorICAgICAqIEEgInNlbGYtbGluayIgaXMgYSBuZXh0IG9yIHByZXYgcmVmZXJlbmNlIHRoYXQgaXMgdGhlIHNhbWUgbm9kZToKKyAgICAgKiAgIHAucHJldiA9PSBwICBvciAgcC5uZXh0ID09IHAKKyAgICAgKiBTZWxmLWxpbmtzIGFyZSB1c2VkIGluIHRoZSBub2RlIHVubGlua2luZyBwcm9jZXNzLiAgQWN0aXZlIG5vZGVzCisgICAgICogbmV2ZXIgaGF2ZSBzZWxmLWxpbmtzLgorICAgICAqCisgICAgICogQSBub2RlIHAgaXMgYWN0aXZlIGlmIGFuZCBvbmx5IGlmOgorICAgICAqCisgICAgICogcC5pdGVtICE9IG51bGwgfHwKKyAgICAgKiAocC5wcmV2ID09IG51bGwgJiYgcC5uZXh0ICE9IHApIHx8CisgICAgICogKHAubmV4dCA9PSBudWxsICYmIHAucHJldiAhPSBwKQorICAgICAqCisgICAgICogVGhlIGRlcXVlIG9iamVjdCBoYXMgdHdvIG5vZGUgcmVmZXJlbmNlcywgImhlYWQiIGFuZCAidGFpbCIuCisgICAgICogVGhlIGhlYWQgYW5kIHRhaWwgYXJlIG9ubHkgYXBwcm94aW1hdGlvbnMgdG8gdGhlIGZpcnN0IGFuZCBsYXN0CisgICAgICogbm9kZXMgb2YgdGhlIGRlcXVlLiAgVGhlIGZpcnN0IG5vZGUgY2FuIGFsd2F5cyBiZSBmb3VuZCBieQorICAgICAqIGZvbGxvd2luZyBwcmV2IHBvaW50ZXJzIGZyb20gaGVhZDsgbGlrZXdpc2UgZm9yIHRhaWwuICBIb3dldmVyLAorICAgICAqIGl0IGlzIHBlcm1pc3NpYmxlIGZvciBoZWFkIGFuZCB0YWlsIHRvIGJlIHJlZmVycmluZyB0byBkZWxldGVkCisgICAgICogbm9kZXMgdGhhdCBoYXZlIGJlZW4gdW5saW5rZWQgYW5kIHNvIG1heSBub3QgYmUgcmVhY2hhYmxlIGZyb20KKyAgICAgKiBhbnkgbGl2ZSBub2RlLgorICAgICAqCisgICAgICogVGhlcmUgYXJlIDMgc3RhZ2VzIG9mIG5vZGUgZGVsZXRpb247CisgICAgICogImxvZ2ljYWwgZGVsZXRpb24iLCAidW5saW5raW5nIiwgYW5kICJnYy11bmxpbmtpbmciLgorICAgICAqCisgICAgICogMS4gImxvZ2ljYWwgZGVsZXRpb24iIGJ5IENBU2luZyBpdGVtIHRvIG51bGwgYXRvbWljYWxseSByZW1vdmVzCisgICAgICogdGhlIGVsZW1lbnQgZnJvbSB0aGUgY29sbGVjdGlvbiwgYW5kIG1ha2VzIHRoZSBjb250YWluaW5nIG5vZGUKKyAgICAgKiBlbGlnaWJsZSBmb3IgdW5saW5raW5nLgorICAgICAqCisgICAgICogMi4gInVubGlua2luZyIgbWFrZXMgYSBkZWxldGVkIG5vZGUgdW5yZWFjaGFibGUgZnJvbSBhY3RpdmUKKyAgICAgKiBub2RlcywgYW5kIHRodXMgZXZlbnR1YWxseSByZWNsYWltYWJsZSBieSBHQy4gIFVubGlua2VkIG5vZGVzCisgICAgICogbWF5IHJlbWFpbiByZWFjaGFibGUgaW5kZWZpbml0ZWx5IGZyb20gYW4gaXRlcmF0b3IuCisgICAgICoKKyAgICAgKiBQaHlzaWNhbCBub2RlIHVubGlua2luZyBpcyBtZXJlbHkgYW4gb3B0aW1pemF0aW9uIChhbGJlaXQgYQorICAgICAqIGNyaXRpY2FsIG9uZSksIGFuZCBzbyBjYW4gYmUgcGVyZm9ybWVkIGF0IG91ciBjb252ZW5pZW5jZS4gIEF0CisgICAgICogYW55IHRpbWUsIHRoZSBzZXQgb2YgbGl2ZSBub2RlcyBtYWludGFpbmVkIGJ5IHByZXYgYW5kIG5leHQKKyAgICAgKiBsaW5rcyBhcmUgaWRlbnRpY2FsLCB0aGF0IGlzLCB0aGUgbGl2ZSBub2RlcyBmb3VuZCB2aWEgbmV4dAorICAgICAqIGxpbmtzIGZyb20gdGhlIGZpcnN0IG5vZGUgaXMgZXF1YWwgdG8gdGhlIGVsZW1lbnRzIGZvdW5kIHZpYQorICAgICAqIHByZXYgbGlua3MgZnJvbSB0aGUgbGFzdCBub2RlLiAgSG93ZXZlciwgdGhpcyBpcyBub3QgdHJ1ZSBmb3IKKyAgICAgKiBub2RlcyB0aGF0IGhhdmUgYWxyZWFkeSBiZWVuIGxvZ2ljYWxseSBkZWxldGVkIC0gc3VjaCBub2RlcyBtYXkKKyAgICAgKiBiZSByZWFjaGFibGUgaW4gb25lIGRpcmVjdGlvbiBvbmx5LgorICAgICAqCisgICAgICogMy4gImdjLXVubGlua2luZyIgdGFrZXMgdW5saW5raW5nIGZ1cnRoZXIgYnkgbWFraW5nIGFjdGl2ZQorICAgICAqIG5vZGVzIHVucmVhY2hhYmxlIGZyb20gZGVsZXRlZCBub2RlcywgbWFraW5nIGl0IGVhc2llciBmb3IgdGhlCisgICAgICogR0MgdG8gcmVjbGFpbSBmdXR1cmUgZGVsZXRlZCBub2Rlcy4gIFRoaXMgc3RlcCBtYWtlcyB0aGUgZGF0YQorICAgICAqIHN0cnVjdHVyZSAiZ2Mtcm9idXN0IiwgYXMgZmlyc3QgZGVzY3JpYmVkIGluIGRldGFpbCBieSBCb2VobQorICAgICAqIChodHRwOi8vcG9ydGFsLmFjbS5vcmcvY2l0YXRpb24uY2ZtP2RvaWQ9NTAzMjcyLjUwMzI4MikuCisgICAgICoKKyAgICAgKiBHQy11bmxpbmtlZCBub2RlcyBtYXkgcmVtYWluIHJlYWNoYWJsZSBpbmRlZmluaXRlbHkgZnJvbSBhbgorICAgICAqIGl0ZXJhdG9yLCBidXQgdW5saWtlIHVubGlua2VkIG5vZGVzLCBhcmUgbmV2ZXIgcmVhY2hhYmxlIGZyb20KKyAgICAgKiBoZWFkIG9yIHRhaWwuCisgICAgICoKKyAgICAgKiBNYWtpbmcgdGhlIGRhdGEgc3RydWN0dXJlIEdDLXJvYnVzdCB3aWxsIGVsaW1pbmF0ZSB0aGUgcmlzayBvZgorICAgICAqIHVuYm91bmRlZCBtZW1vcnkgcmV0ZW50aW9uIHdpdGggY29uc2VydmF0aXZlIEdDcyBhbmQgaXMgbGlrZWx5CisgICAgICogdG8gaW1wcm92ZSBwZXJmb3JtYW5jZSB3aXRoIGdlbmVyYXRpb25hbCBHQ3MuCisgICAgICoKKyAgICAgKiBXaGVuIGEgbm9kZSBpcyBkZXF1ZXVlZCBhdCBlaXRoZXIgZW5kLCBlLmcuIHZpYSBwb2xsKCksIHdlIHdvdWxkCisgICAgICogbGlrZSB0byBicmVhayBhbnkgcmVmZXJlbmNlcyBmcm9tIHRoZSBub2RlIHRvIGFjdGl2ZSBub2Rlcy4gIFdlCisgICAgICogZGV2ZWxvcCBmdXJ0aGVyIHRoZSB1c2Ugb2Ygc2VsZi1saW5rcyB0aGF0IHdhcyB2ZXJ5IGVmZmVjdGl2ZSBpbgorICAgICAqIG90aGVyIGNvbmN1cnJlbnQgY29sbGVjdGlvbiBjbGFzc2VzLiAgVGhlIGlkZWEgaXMgdG8gcmVwbGFjZQorICAgICAqIHByZXYgYW5kIG5leHQgcG9pbnRlcnMgd2l0aCBzcGVjaWFsIHZhbHVlcyB0aGF0IGFyZSBpbnRlcnByZXRlZAorICAgICAqIHRvIG1lYW4gb2ZmLXRoZS1saXN0LWF0LW9uZS1lbmQuICBUaGVzZSBhcmUgYXBwcm94aW1hdGlvbnMsIGJ1dAorICAgICAqIGdvb2QgZW5vdWdoIHRvIHByZXNlcnZlIHRoZSBwcm9wZXJ0aWVzIHdlIHdhbnQgaW4gb3VyCisgICAgICogdHJhdmVyc2FscywgZS5nLiB3ZSBndWFyYW50ZWUgdGhhdCBhIHRyYXZlcnNhbCB3aWxsIG5ldmVyIHZpc2l0CisgICAgICogdGhlIHNhbWUgZWxlbWVudCB0d2ljZSwgYnV0IHdlIGRvbid0IGd1YXJhbnRlZSB3aGV0aGVyIGEKKyAgICAgKiB0cmF2ZXJzYWwgdGhhdCBydW5zIG91dCBvZiBlbGVtZW50cyB3aWxsIGJlIGFibGUgdG8gc2VlIG1vcmUKKyAgICAgKiBlbGVtZW50cyBsYXRlciBhZnRlciBlbnF1ZXVlcyBhdCB0aGF0IGVuZC4gIERvaW5nIGdjLXVubGlua2luZworICAgICAqIHNhZmVseSBpcyBwYXJ0aWN1bGFybHkgdHJpY2t5LCBzaW5jZSBhbnkgbm9kZSBjYW4gYmUgaW4gdXNlCisgICAgICogaW5kZWZpbml0ZWx5IChmb3IgZXhhbXBsZSBieSBhbiBpdGVyYXRvcikuICBXZSBtdXN0IGVuc3VyZSB0aGF0CisgICAgICogdGhlIG5vZGVzIHBvaW50ZWQgYXQgYnkgaGVhZC90YWlsIG5ldmVyIGdldCBnYy11bmxpbmtlZCwgc2luY2UKKyAgICAgKiBoZWFkL3RhaWwgYXJlIG5lZWRlZCB0byBnZXQgImJhY2sgb24gdHJhY2siIGJ5IG90aGVyIG5vZGVzIHRoYXQKKyAgICAgKiBhcmUgZ2MtdW5saW5rZWQuICBnYy11bmxpbmtpbmcgYWNjb3VudHMgZm9yIG11Y2ggb2YgdGhlCisgICAgICogaW1wbGVtZW50YXRpb24gY29tcGxleGl0eS4KKyAgICAgKgorICAgICAqIFNpbmNlIG5laXRoZXIgdW5saW5raW5nIG5vciBnYy11bmxpbmtpbmcgYXJlIG5lY2Vzc2FyeSBmb3IKKyAgICAgKiBjb3JyZWN0bmVzcywgdGhlcmUgYXJlIG1hbnkgaW1wbGVtZW50YXRpb24gY2hvaWNlcyByZWdhcmRpbmcKKyAgICAgKiBmcmVxdWVuY3kgKGVhZ2VybmVzcykgb2YgdGhlc2Ugb3BlcmF0aW9ucy4gIFNpbmNlIHZvbGF0aWxlCisgICAgICogcmVhZHMgYXJlIGxpa2VseSB0byBiZSBtdWNoIGNoZWFwZXIgdGhhbiBDQVNlcywgc2F2aW5nIENBU2VzIGJ5CisgICAgICogdW5saW5raW5nIG11bHRpcGxlIGFkamFjZW50IG5vZGVzIGF0IGEgdGltZSBtYXkgYmUgYSB3aW4uCisgICAgICogZ2MtdW5saW5raW5nIGNhbiBiZSBwZXJmb3JtZWQgcmFyZWx5IGFuZCBzdGlsbCBiZSBlZmZlY3RpdmUsCisgICAgICogc2luY2UgaXQgaXMgbW9zdCBpbXBvcnRhbnQgdGhhdCBsb25nIGNoYWlucyBvZiBkZWxldGVkIG5vZGVzCisgICAgICogYXJlIG9jY2FzaW9uYWxseSBicm9rZW4uCisgICAgICoKKyAgICAgKiBUaGUgYWN0dWFsIHJlcHJlc2VudGF0aW9uIHdlIHVzZSBpcyB0aGF0IHAubmV4dCA9PSBwIG1lYW5zIHRvCisgICAgICogZ290byB0aGUgZmlyc3Qgbm9kZSAod2hpY2ggaW4gdHVybiBpcyByZWFjaGVkIGJ5IGZvbGxvd2luZyBwcmV2CisgICAgICogcG9pbnRlcnMgZnJvbSBoZWFkKSwgYW5kIHAubmV4dCA9PSBudWxsICYmIHAucHJldiA9PSBwIG1lYW5zCisgICAgICogdGhhdCB0aGUgaXRlcmF0aW9uIGlzIGF0IGFuIGVuZCBhbmQgdGhhdCBwIGlzIGEgKHN0YXRpYyBmaW5hbCkKKyAgICAgKiBkdW1teSBub2RlLCBORVhUX1RFUk1JTkFUT1IsIGFuZCBub3QgdGhlIGxhc3QgYWN0aXZlIG5vZGUuCisgICAgICogRmluaXNoaW5nIHRoZSBpdGVyYXRpb24gd2hlbiBlbmNvdW50ZXJpbmcgc3VjaCBhIFRFUk1JTkFUT1IgaXMKKyAgICAgKiBnb29kIGVub3VnaCBmb3IgcmVhZC1vbmx5IHRyYXZlcnNhbHMsIHNvIHN1Y2ggdHJhdmVyc2FscyBjYW4gdXNlCisgICAgICogcC5uZXh0ID09IG51bGwgYXMgdGhlIHRlcm1pbmF0aW9uIGNvbmRpdGlvbi4gIFdoZW4gd2UgbmVlZCB0bworICAgICAqIGZpbmQgdGhlIGxhc3QgKGFjdGl2ZSkgbm9kZSwgZm9yIGVucXVldWVpbmcgYSBuZXcgbm9kZSwgd2UgbmVlZAorICAgICAqIHRvIGNoZWNrIHdoZXRoZXIgd2UgaGF2ZSByZWFjaGVkIGEgVEVSTUlOQVRPUiBub2RlOyBpZiBzbywKKyAgICAgKiByZXN0YXJ0IHRyYXZlcnNhbCBmcm9tIHRhaWwuCisgICAgICoKKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gaXMgY29tcGxldGVseSBkaXJlY3Rpb25hbGx5IHN5bW1ldHJpY2FsLAorICAgICAqIGV4Y2VwdCB0aGF0IG1vc3QgcHVibGljIG1ldGhvZHMgdGhhdCBpdGVyYXRlIHRocm91Z2ggdGhlIGxpc3QKKyAgICAgKiBmb2xsb3cgbmV4dCBwb2ludGVycyAoImZvcndhcmQiIGRpcmVjdGlvbikuCisgICAgICoKKyAgICAgKiBXZSBiZWxpZXZlICh3aXRob3V0IGZ1bGwgcHJvb2YpIHRoYXQgYWxsIHNpbmdsZS1lbGVtZW50IGRlcXVlCisgICAgICogb3BlcmF0aW9ucyAoZS5nLiwgYWRkRmlyc3QsIHBlZWtMYXN0LCBwb2xsTGFzdCkgYXJlIGxpbmVhcml6YWJsZQorICAgICAqIChzZWUgSGVybGloeSBhbmQgU2hhdml0J3MgYm9vaykuICBIb3dldmVyLCBzb21lIGNvbWJpbmF0aW9ucyBvZgorICAgICAqIG9wZXJhdGlvbnMgYXJlIGtub3duIG5vdCB0byBiZSBsaW5lYXJpemFibGUuICBJbiBwYXJ0aWN1bGFyLAorICAgICAqIHdoZW4gYW4gYWRkRmlyc3QoQSkgaXMgcmFjaW5nIHdpdGggcG9sbEZpcnN0KCkgcmVtb3ZpbmcgQiwgaXQgaXMKKyAgICAgKiBwb3NzaWJsZSBmb3IgYW4gb2JzZXJ2ZXIgaXRlcmF0aW5nIG92ZXIgdGhlIGVsZW1lbnRzIHRvIG9ic2VydmUKKyAgICAgKiBBIEIgQyBhbmQgc3Vic2VxdWVudGx5IG9ic2VydmUgQSBDLCBldmVuIHRob3VnaCBubyBpbnRlcmlvcgorICAgICAqIHJlbW92ZXMgYXJlIGV2ZXIgcGVyZm9ybWVkLiAgTmV2ZXJ0aGVsZXNzLCBpdGVyYXRvcnMgYmVoYXZlCisgICAgICogcmVhc29uYWJseSwgcHJvdmlkaW5nIHRoZSAid2Vha2x5IGNvbnNpc3RlbnQiIGd1YXJhbnRlZXMuCisgICAgICoKKyAgICAgKiBFbXBpcmljYWxseSwgbWljcm9iZW5jaG1hcmtzIHN1Z2dlc3QgdGhhdCB0aGlzIGNsYXNzIGFkZHMgYWJvdXQKKyAgICAgKiA0MCUgb3ZlcmhlYWQgcmVsYXRpdmUgdG8gQ29uY3VycmVudExpbmtlZFF1ZXVlLCB3aGljaCBmZWVscyBhcworICAgICAqIGdvb2QgYXMgd2UgY2FuIGhvcGUgZm9yLgorICAgICAqLworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODc2MzIzMjYyNjQ1MTc2MzU0TDsKKworICAgIC8qKgorICAgICAqIEEgbm9kZSBmcm9tIHdoaWNoIHRoZSBmaXJzdCBub2RlIG9uIGxpc3QgKHRoYXQgaXMsIHRoZSB1bmlxdWUgbm9kZSBwCisgICAgICogd2l0aCBwLnByZXYgPT0gbnVsbCAmJiBwLm5leHQgIT0gcCkgY2FuIGJlIHJlYWNoZWQgaW4gTygxKSB0aW1lLgorICAgICAqIEludmFyaWFudHM6CisgICAgICogLSB0aGUgZmlyc3Qgbm9kZSBpcyBhbHdheXMgTygxKSByZWFjaGFibGUgZnJvbSBoZWFkIHZpYSBwcmV2IGxpbmtzCisgICAgICogLSBhbGwgbGl2ZSBub2RlcyBhcmUgcmVhY2hhYmxlIGZyb20gdGhlIGZpcnN0IG5vZGUgdmlhIHN1Y2MoKQorICAgICAqIC0gaGVhZCAhPSBudWxsCisgICAgICogLSAodG1wID0gaGVhZCkubmV4dCAhPSB0bXAgfHwgdG1wICE9IGhlYWQKKyAgICAgKiAtIGhlYWQgaXMgbmV2ZXIgZ2MtdW5saW5rZWQgKGJ1dCBtYXkgYmUgdW5saW5rZWQpCisgICAgICogTm9uLWludmFyaWFudHM6CisgICAgICogLSBoZWFkLml0ZW0gbWF5IG9yIG1heSBub3QgYmUgbnVsbAorICAgICAqIC0gaGVhZCBtYXkgbm90IGJlIHJlYWNoYWJsZSBmcm9tIHRoZSBmaXJzdCBvciBsYXN0IG5vZGUsIG9yIGZyb20gdGFpbAorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IHZvbGF0aWxlIE5vZGU8RT4gaGVhZDsKKworICAgIC8qKgorICAgICAqIEEgbm9kZSBmcm9tIHdoaWNoIHRoZSBsYXN0IG5vZGUgb24gbGlzdCAodGhhdCBpcywgdGhlIHVuaXF1ZSBub2RlIHAKKyAgICAgKiB3aXRoIHAubmV4dCA9PSBudWxsICYmIHAucHJldiAhPSBwKSBjYW4gYmUgcmVhY2hlZCBpbiBPKDEpIHRpbWUuCisgICAgICogSW52YXJpYW50czoKKyAgICAgKiAtIHRoZSBsYXN0IG5vZGUgaXMgYWx3YXlzIE8oMSkgcmVhY2hhYmxlIGZyb20gdGFpbCB2aWEgbmV4dCBsaW5rcworICAgICAqIC0gYWxsIGxpdmUgbm9kZXMgYXJlIHJlYWNoYWJsZSBmcm9tIHRoZSBsYXN0IG5vZGUgdmlhIHByZWQoKQorICAgICAqIC0gdGFpbCAhPSBudWxsCisgICAgICogLSB0YWlsIGlzIG5ldmVyIGdjLXVubGlua2VkIChidXQgbWF5IGJlIHVubGlua2VkKQorICAgICAqIE5vbi1pbnZhcmlhbnRzOgorICAgICAqIC0gdGFpbC5pdGVtIG1heSBvciBtYXkgbm90IGJlIG51bGwKKyAgICAgKiAtIHRhaWwgbWF5IG5vdCBiZSByZWFjaGFibGUgZnJvbSB0aGUgZmlyc3Qgb3IgbGFzdCBub2RlLCBvciBmcm9tIGhlYWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHRyYW5zaWVudCB2b2xhdGlsZSBOb2RlPEU+IHRhaWw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBOb2RlPE9iamVjdD4gUFJFVl9URVJNSU5BVE9SLCBORVhUX1RFUk1JTkFUT1I7CisKKyAgICBzdGF0aWMgeworICAgICAgICBQUkVWX1RFUk1JTkFUT1IgPSBuZXcgTm9kZTxPYmplY3Q+KG51bGwpOworICAgICAgICBQUkVWX1RFUk1JTkFUT1IubmV4dCA9IFBSRVZfVEVSTUlOQVRPUjsKKyAgICAgICAgTkVYVF9URVJNSU5BVE9SID0gbmV3IE5vZGU8T2JqZWN0PihudWxsKTsKKyAgICAgICAgTkVYVF9URVJNSU5BVE9SLnByZXYgPSBORVhUX1RFUk1JTkFUT1I7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgTm9kZTxFPiBwcmV2VGVybWluYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIChOb2RlPEU+KSBQUkVWX1RFUk1JTkFUT1I7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgTm9kZTxFPiBuZXh0VGVybWluYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIChOb2RlPEU+KSBORVhUX1RFUk1JTkFUT1I7CisgICAgfQorCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIE5vZGU8RT4geworICAgICAgICB2b2xhdGlsZSBOb2RlPEU+IHByZXY7CisgICAgICAgIHZvbGF0aWxlIEUgaXRlbTsKKyAgICAgICAgdm9sYXRpbGUgTm9kZTxFPiBuZXh0OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IG5vZGUuICBVc2VzIHJlbGF4ZWQgd3JpdGUgYmVjYXVzZSBpdGVtIGNhbgorICAgICAgICAgKiBvbmx5IGJlIHNlZW4gYWZ0ZXIgcHVibGljYXRpb24gdmlhIGNhc05leHQgb3IgY2FzUHJldi4KKyAgICAgICAgICovCisgICAgICAgIE5vZGUoRSBpdGVtKSB7CisgICAgICAgICAgICBVTlNBRkUucHV0T2JqZWN0KHRoaXMsIGl0ZW1PZmZzZXQsIGl0ZW0pOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBjYXNJdGVtKEUgY21wLCBFIHZhbCkgeworICAgICAgICAgICAgcmV0dXJuIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCBpdGVtT2Zmc2V0LCBjbXAsIHZhbCk7CisgICAgICAgIH0KKworICAgICAgICB2b2lkIGxhenlTZXROZXh0KE5vZGU8RT4gdmFsKSB7CisgICAgICAgICAgICBVTlNBRkUucHV0T3JkZXJlZE9iamVjdCh0aGlzLCBuZXh0T2Zmc2V0LCB2YWwpOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBjYXNOZXh0KE5vZGU8RT4gY21wLCBOb2RlPEU+IHZhbCkgeworICAgICAgICAgICAgcmV0dXJuIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCBuZXh0T2Zmc2V0LCBjbXAsIHZhbCk7CisgICAgICAgIH0KKworICAgICAgICB2b2lkIGxhenlTZXRQcmV2KE5vZGU8RT4gdmFsKSB7CisgICAgICAgICAgICBVTlNBRkUucHV0T3JkZXJlZE9iamVjdCh0aGlzLCBwcmV2T2Zmc2V0LCB2YWwpOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBjYXNQcmV2KE5vZGU8RT4gY21wLCBOb2RlPEU+IHZhbCkgeworICAgICAgICAgICAgcmV0dXJuIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCBwcmV2T2Zmc2V0LCBjbXAsIHZhbCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBVbnNhZmUgbWVjaGFuaWNzCisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgc3VuLm1pc2MuVW5zYWZlIFVOU0FGRSA9CisgICAgICAgICAgICBzdW4ubWlzYy5VbnNhZmUuZ2V0VW5zYWZlKCk7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgcHJldk9mZnNldCA9CisgICAgICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJwcmV2IiwgTm9kZS5jbGFzcyk7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgaXRlbU9mZnNldCA9CisgICAgICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJpdGVtIiwgTm9kZS5jbGFzcyk7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgbmV4dE9mZnNldCA9CisgICAgICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJuZXh0IiwgTm9kZS5jbGFzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTGlua3MgZSBhcyBmaXJzdCBlbGVtZW50LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBsaW5rRmlyc3QoRSBlKSB7CisgICAgICAgIGNoZWNrTm90TnVsbChlKTsKKyAgICAgICAgZmluYWwgTm9kZTxFPiBuZXdOb2RlID0gbmV3IE5vZGU8RT4oZSk7CisKKyAgICAgICAgcmVzdGFydEZyb21IZWFkOgorICAgICAgICBmb3IgKDs7KQorICAgICAgICAgICAgZm9yIChOb2RlPEU+IGggPSBoZWFkLCBwID0gaCwgcTs7KSB7CisgICAgICAgICAgICAgICAgaWYgKChxID0gcC5wcmV2KSAhPSBudWxsICYmCisgICAgICAgICAgICAgICAgICAgIChxID0gKHAgPSBxKS5wcmV2KSAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3IgaGVhZCB1cGRhdGVzIGV2ZXJ5IG90aGVyIGhvcC4KKyAgICAgICAgICAgICAgICAgICAgLy8gSWYgcCA9PSBxLCB3ZSBhcmUgc3VyZSB0byBmb2xsb3cgaGVhZCBpbnN0ZWFkLgorICAgICAgICAgICAgICAgICAgICBwID0gKGggIT0gKGggPSBoZWFkKSkgPyBoIDogcTsKKyAgICAgICAgICAgICAgICBlbHNlIGlmIChwLm5leHQgPT0gcCkgLy8gUFJFVl9URVJNSU5BVE9SCisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHJlc3RhcnRGcm9tSGVhZDsKKyAgICAgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gcCBpcyBmaXJzdCBub2RlCisgICAgICAgICAgICAgICAgICAgIG5ld05vZGUubGF6eVNldE5leHQocCk7IC8vIENBUyBwaWdneWJhY2sKKyAgICAgICAgICAgICAgICAgICAgaWYgKHAuY2FzUHJldihudWxsLCBuZXdOb2RlKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3VjY2Vzc2Z1bCBDQVMgaXMgdGhlIGxpbmVhcml6YXRpb24gcG9pbnQKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBlIHRvIGJlY29tZSBhbiBlbGVtZW50IG9mIHRoaXMgZGVxdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbmQgZm9yIG5ld05vZGUgdG8gYmVjb21lICJsaXZlIi4KKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwICE9IGgpIC8vIGhvcCB0d28gbm9kZXMgYXQgYSB0aW1lCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzSGVhZChoLCBuZXdOb2RlKTsgIC8vIEZhaWx1cmUgaXMgT0suCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgLy8gTG9zdCBDQVMgcmFjZSB0byBhbm90aGVyIHRocmVhZDsgcmUtcmVhZCBwcmV2CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIExpbmtzIGUgYXMgbGFzdCBlbGVtZW50LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBsaW5rTGFzdChFIGUpIHsKKyAgICAgICAgY2hlY2tOb3ROdWxsKGUpOworICAgICAgICBmaW5hbCBOb2RlPEU+IG5ld05vZGUgPSBuZXcgTm9kZTxFPihlKTsKKworICAgICAgICByZXN0YXJ0RnJvbVRhaWw6CisgICAgICAgIGZvciAoOzspCisgICAgICAgICAgICBmb3IgKE5vZGU8RT4gdCA9IHRhaWwsIHAgPSB0LCBxOzspIHsKKyAgICAgICAgICAgICAgICBpZiAoKHEgPSBwLm5leHQpICE9IG51bGwgJiYKKyAgICAgICAgICAgICAgICAgICAgKHEgPSAocCA9IHEpLm5leHQpICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGZvciB0YWlsIHVwZGF0ZXMgZXZlcnkgb3RoZXIgaG9wLgorICAgICAgICAgICAgICAgICAgICAvLyBJZiBwID09IHEsIHdlIGFyZSBzdXJlIHRvIGZvbGxvdyB0YWlsIGluc3RlYWQuCisgICAgICAgICAgICAgICAgICAgIHAgPSAodCAhPSAodCA9IHRhaWwpKSA/IHQgOiBxOworICAgICAgICAgICAgICAgIGVsc2UgaWYgKHAucHJldiA9PSBwKSAvLyBORVhUX1RFUk1JTkFUT1IKKyAgICAgICAgICAgICAgICAgICAgY29udGludWUgcmVzdGFydEZyb21UYWlsOworICAgICAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgICAgICAvLyBwIGlzIGxhc3Qgbm9kZQorICAgICAgICAgICAgICAgICAgICBuZXdOb2RlLmxhenlTZXRQcmV2KHApOyAvLyBDQVMgcGlnZ3liYWNrCisgICAgICAgICAgICAgICAgICAgIGlmIChwLmNhc05leHQobnVsbCwgbmV3Tm9kZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN1Y2Nlc3NmdWwgQ0FTIGlzIHRoZSBsaW5lYXJpemF0aW9uIHBvaW50CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgZSB0byBiZWNvbWUgYW4gZWxlbWVudCBvZiB0aGlzIGRlcXVlLAorICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIGZvciBuZXdOb2RlIHRvIGJlY29tZSAibGl2ZSIuCisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocCAhPSB0KSAvLyBob3AgdHdvIG5vZGVzIGF0IGEgdGltZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc1RhaWwodCwgbmV3Tm9kZSk7ICAvLyBGYWlsdXJlIGlzIE9LLgorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8vIExvc3QgQ0FTIHJhY2UgdG8gYW5vdGhlciB0aHJlYWQ7IHJlLXJlYWQgbmV4dAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSE9QUyA9IDI7CisKKyAgICAvKioKKyAgICAgKiBVbmxpbmtzIG5vbi1udWxsIG5vZGUgeC4KKyAgICAgKi8KKyAgICB2b2lkIHVubGluayhOb2RlPEU+IHgpIHsKKyAgICAgICAgLy8gYXNzZXJ0IHggIT0gbnVsbDsKKyAgICAgICAgLy8gYXNzZXJ0IHguaXRlbSA9PSBudWxsOworICAgICAgICAvLyBhc3NlcnQgeCAhPSBQUkVWX1RFUk1JTkFUT1I7CisgICAgICAgIC8vIGFzc2VydCB4ICE9IE5FWFRfVEVSTUlOQVRPUjsKKworICAgICAgICBmaW5hbCBOb2RlPEU+IHByZXYgPSB4LnByZXY7CisgICAgICAgIGZpbmFsIE5vZGU8RT4gbmV4dCA9IHgubmV4dDsKKyAgICAgICAgaWYgKHByZXYgPT0gbnVsbCkgeworICAgICAgICAgICAgdW5saW5rRmlyc3QoeCwgbmV4dCk7CisgICAgICAgIH0gZWxzZSBpZiAobmV4dCA9PSBudWxsKSB7CisgICAgICAgICAgICB1bmxpbmtMYXN0KHgsIHByZXYpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gVW5saW5rIGludGVyaW9yIG5vZGUuCisgICAgICAgICAgICAvLworICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgY29tbW9uIGNhc2UsIHNpbmNlIGEgc2VyaWVzIG9mIHBvbGxzIGF0IHRoZQorICAgICAgICAgICAgLy8gc2FtZSBlbmQgd2lsbCBiZSAiaW50ZXJpb3IiIHJlbW92ZXMsIGV4Y2VwdCBwZXJoYXBzIGZvcgorICAgICAgICAgICAgLy8gdGhlIGZpcnN0IG9uZSwgc2luY2UgZW5kIG5vZGVzIGNhbm5vdCBiZSB1bmxpbmtlZC4KKyAgICAgICAgICAgIC8vCisgICAgICAgICAgICAvLyBBdCBhbnkgdGltZSwgYWxsIGFjdGl2ZSBub2RlcyBhcmUgbXV0dWFsbHkgcmVhY2hhYmxlIGJ5CisgICAgICAgICAgICAvLyBmb2xsb3dpbmcgYSBzZXF1ZW5jZSBvZiBlaXRoZXIgbmV4dCBvciBwcmV2IHBvaW50ZXJzLgorICAgICAgICAgICAgLy8KKyAgICAgICAgICAgIC8vIE91ciBzdHJhdGVneSBpcyB0byBmaW5kIHRoZSB1bmlxdWUgYWN0aXZlIHByZWRlY2Vzc29yCisgICAgICAgICAgICAvLyBhbmQgc3VjY2Vzc29yIG9mIHguICBUcnkgdG8gZml4IHVwIHRoZWlyIGxpbmtzIHNvIHRoYXQKKyAgICAgICAgICAgIC8vIHRoZXkgcG9pbnQgdG8gZWFjaCBvdGhlciwgbGVhdmluZyB4IHVucmVhY2hhYmxlIGZyb20KKyAgICAgICAgICAgIC8vIGFjdGl2ZSBub2Rlcy4gIElmIHN1Y2Nlc3NmdWwsIGFuZCBpZiB4IGhhcyBubyBsaXZlCisgICAgICAgICAgICAvLyBwcmVkZWNlc3Nvci9zdWNjZXNzb3IsIHdlIGFkZGl0aW9uYWxseSB0cnkgdG8gZ2MtdW5saW5rLAorICAgICAgICAgICAgLy8gbGVhdmluZyBhY3RpdmUgbm9kZXMgdW5yZWFjaGFibGUgZnJvbSB4LCBieSByZWNoZWNraW5nCisgICAgICAgICAgICAvLyB0aGF0IHRoZSBzdGF0dXMgb2YgcHJlZGVjZXNzb3IgYW5kIHN1Y2Nlc3NvciBhcmUKKyAgICAgICAgICAgIC8vIHVuY2hhbmdlZCBhbmQgZW5zdXJpbmcgdGhhdCB4IGlzIG5vdCByZWFjaGFibGUgZnJvbQorICAgICAgICAgICAgLy8gdGFpbC9oZWFkLCBiZWZvcmUgc2V0dGluZyB4J3MgcHJldi9uZXh0IGxpbmtzIHRvIHRoZWlyCisgICAgICAgICAgICAvLyBsb2dpY2FsIGFwcHJveGltYXRlIHJlcGxhY2VtZW50cywgc2VsZi9URVJNSU5BVE9SLgorICAgICAgICAgICAgTm9kZTxFPiBhY3RpdmVQcmVkLCBhY3RpdmVTdWNjOworICAgICAgICAgICAgYm9vbGVhbiBpc0ZpcnN0LCBpc0xhc3Q7CisgICAgICAgICAgICBpbnQgaG9wcyA9IDE7CisKKyAgICAgICAgICAgIC8vIEZpbmQgYWN0aXZlIHByZWRlY2Vzc29yCisgICAgICAgICAgICBmb3IgKE5vZGU8RT4gcCA9IHByZXY7IDsgKytob3BzKSB7CisgICAgICAgICAgICAgICAgaWYgKHAuaXRlbSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGFjdGl2ZVByZWQgPSBwOworICAgICAgICAgICAgICAgICAgICBpc0ZpcnN0ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBOb2RlPEU+IHEgPSBwLnByZXY7CisgICAgICAgICAgICAgICAgaWYgKHEgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpZiAocC5uZXh0ID09IHApCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIGFjdGl2ZVByZWQgPSBwOworICAgICAgICAgICAgICAgICAgICBpc0ZpcnN0ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UgaWYgKHAgPT0gcSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgcCA9IHE7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIEZpbmQgYWN0aXZlIHN1Y2Nlc3NvcgorICAgICAgICAgICAgZm9yIChOb2RlPEU+IHAgPSBuZXh0OyA7ICsraG9wcykgeworICAgICAgICAgICAgICAgIGlmIChwLml0ZW0gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBhY3RpdmVTdWNjID0gcDsKKyAgICAgICAgICAgICAgICAgICAgaXNMYXN0ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBOb2RlPEU+IHEgPSBwLm5leHQ7CisgICAgICAgICAgICAgICAgaWYgKHEgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpZiAocC5wcmV2ID09IHApCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIGFjdGl2ZVN1Y2MgPSBwOworICAgICAgICAgICAgICAgICAgICBpc0xhc3QgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZSBpZiAocCA9PSBxKQorICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBwID0gcTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gVE9ETzogYmV0dGVyIEhPUCBoZXVyaXN0aWNzCisgICAgICAgICAgICBpZiAoaG9wcyA8IEhPUFMKKyAgICAgICAgICAgICAgICAvLyBhbHdheXMgc3F1ZWV6ZSBvdXQgaW50ZXJpb3IgZGVsZXRlZCBub2RlcworICAgICAgICAgICAgICAgICYmIChpc0ZpcnN0IHwgaXNMYXN0KSkKKyAgICAgICAgICAgICAgICByZXR1cm47CisKKyAgICAgICAgICAgIC8vIFNxdWVlemUgb3V0IGRlbGV0ZWQgbm9kZXMgYmV0d2VlbiBhY3RpdmVQcmVkIGFuZAorICAgICAgICAgICAgLy8gYWN0aXZlU3VjYywgaW5jbHVkaW5nIHguCisgICAgICAgICAgICBza2lwRGVsZXRlZFN1Y2Nlc3NvcnMoYWN0aXZlUHJlZCk7CisgICAgICAgICAgICBza2lwRGVsZXRlZFByZWRlY2Vzc29ycyhhY3RpdmVTdWNjKTsKKworICAgICAgICAgICAgLy8gVHJ5IHRvIGdjLXVubGluaywgaWYgcG9zc2libGUKKyAgICAgICAgICAgIGlmICgoaXNGaXJzdCB8IGlzTGFzdCkgJiYKKworICAgICAgICAgICAgICAgIC8vIFJlY2hlY2sgZXhwZWN0ZWQgc3RhdGUgb2YgcHJlZGVjZXNzb3IgYW5kIHN1Y2Nlc3NvcgorICAgICAgICAgICAgICAgIChhY3RpdmVQcmVkLm5leHQgPT0gYWN0aXZlU3VjYykgJiYKKyAgICAgICAgICAgICAgICAoYWN0aXZlU3VjYy5wcmV2ID09IGFjdGl2ZVByZWQpICYmCisgICAgICAgICAgICAgICAgKGlzRmlyc3QgPyBhY3RpdmVQcmVkLnByZXYgPT0gbnVsbCA6IGFjdGl2ZVByZWQuaXRlbSAhPSBudWxsKSAmJgorICAgICAgICAgICAgICAgIChpc0xhc3QgID8gYWN0aXZlU3VjYy5uZXh0ID09IG51bGwgOiBhY3RpdmVTdWNjLml0ZW0gIT0gbnVsbCkpIHsKKworICAgICAgICAgICAgICAgIHVwZGF0ZUhlYWQoKTsgLy8gRW5zdXJlIHggaXMgbm90IHJlYWNoYWJsZSBmcm9tIGhlYWQKKyAgICAgICAgICAgICAgICB1cGRhdGVUYWlsKCk7IC8vIEVuc3VyZSB4IGlzIG5vdCByZWFjaGFibGUgZnJvbSB0YWlsCisKKyAgICAgICAgICAgICAgICAvLyBGaW5hbGx5LCBhY3R1YWxseSBnYy11bmxpbmsKKyAgICAgICAgICAgICAgICB4LmxhenlTZXRQcmV2KGlzRmlyc3QgPyBwcmV2VGVybWluYXRvcigpIDogeCk7CisgICAgICAgICAgICAgICAgeC5sYXp5U2V0TmV4dChpc0xhc3QgID8gbmV4dFRlcm1pbmF0b3IoKSA6IHgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVW5saW5rcyBub24tbnVsbCBmaXJzdCBub2RlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB1bmxpbmtGaXJzdChOb2RlPEU+IGZpcnN0LCBOb2RlPEU+IG5leHQpIHsKKyAgICAgICAgLy8gYXNzZXJ0IGZpcnN0ICE9IG51bGw7CisgICAgICAgIC8vIGFzc2VydCBuZXh0ICE9IG51bGw7CisgICAgICAgIC8vIGFzc2VydCBmaXJzdC5pdGVtID09IG51bGw7CisgICAgICAgIGZvciAoTm9kZTxFPiBvID0gbnVsbCwgcCA9IG5leHQsIHE7OykgeworICAgICAgICAgICAgaWYgKHAuaXRlbSAhPSBudWxsIHx8IChxID0gcC5uZXh0KSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWYgKG8gIT0gbnVsbCAmJiBwLnByZXYgIT0gcCAmJiBmaXJzdC5jYXNOZXh0KG5leHQsIHApKSB7CisgICAgICAgICAgICAgICAgICAgIHNraXBEZWxldGVkUHJlZGVjZXNzb3JzKHApOworICAgICAgICAgICAgICAgICAgICBpZiAoZmlyc3QucHJldiA9PSBudWxsICYmCisgICAgICAgICAgICAgICAgICAgICAgICAocC5uZXh0ID09IG51bGwgfHwgcC5pdGVtICE9IG51bGwpICYmCisgICAgICAgICAgICAgICAgICAgICAgICBwLnByZXYgPT0gZmlyc3QpIHsKKworICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlSGVhZCgpOyAvLyBFbnN1cmUgbyBpcyBub3QgcmVhY2hhYmxlIGZyb20gaGVhZAorICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlVGFpbCgpOyAvLyBFbnN1cmUgbyBpcyBub3QgcmVhY2hhYmxlIGZyb20gdGFpbAorCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBGaW5hbGx5LCBhY3R1YWxseSBnYy11bmxpbmsKKyAgICAgICAgICAgICAgICAgICAgICAgIG8ubGF6eVNldE5leHQobyk7CisgICAgICAgICAgICAgICAgICAgICAgICBvLmxhenlTZXRQcmV2KHByZXZUZXJtaW5hdG9yKCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgaWYgKHAgPT0gcSkKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICBvID0gcDsKKyAgICAgICAgICAgICAgICBwID0gcTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFVubGlua3Mgbm9uLW51bGwgbGFzdCBub2RlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB1bmxpbmtMYXN0KE5vZGU8RT4gbGFzdCwgTm9kZTxFPiBwcmV2KSB7CisgICAgICAgIC8vIGFzc2VydCBsYXN0ICE9IG51bGw7CisgICAgICAgIC8vIGFzc2VydCBwcmV2ICE9IG51bGw7CisgICAgICAgIC8vIGFzc2VydCBsYXN0Lml0ZW0gPT0gbnVsbDsKKyAgICAgICAgZm9yIChOb2RlPEU+IG8gPSBudWxsLCBwID0gcHJldiwgcTs7KSB7CisgICAgICAgICAgICBpZiAocC5pdGVtICE9IG51bGwgfHwgKHEgPSBwLnByZXYpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZiAobyAhPSBudWxsICYmIHAubmV4dCAhPSBwICYmIGxhc3QuY2FzUHJldihwcmV2LCBwKSkgeworICAgICAgICAgICAgICAgICAgICBza2lwRGVsZXRlZFN1Y2Nlc3NvcnMocCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChsYXN0Lm5leHQgPT0gbnVsbCAmJgorICAgICAgICAgICAgICAgICAgICAgICAgKHAucHJldiA9PSBudWxsIHx8IHAuaXRlbSAhPSBudWxsKSAmJgorICAgICAgICAgICAgICAgICAgICAgICAgcC5uZXh0ID09IGxhc3QpIHsKKworICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlSGVhZCgpOyAvLyBFbnN1cmUgbyBpcyBub3QgcmVhY2hhYmxlIGZyb20gaGVhZAorICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlVGFpbCgpOyAvLyBFbnN1cmUgbyBpcyBub3QgcmVhY2hhYmxlIGZyb20gdGFpbAorCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBGaW5hbGx5LCBhY3R1YWxseSBnYy11bmxpbmsKKyAgICAgICAgICAgICAgICAgICAgICAgIG8ubGF6eVNldFByZXYobyk7CisgICAgICAgICAgICAgICAgICAgICAgICBvLmxhenlTZXROZXh0KG5leHRUZXJtaW5hdG9yKCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgaWYgKHAgPT0gcSkKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICBvID0gcDsKKyAgICAgICAgICAgICAgICBwID0gcTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEd1YXJhbnRlZXMgdGhhdCBhbnkgbm9kZSB3aGljaCB3YXMgdW5saW5rZWQgYmVmb3JlIGEgY2FsbCB0bworICAgICAqIHRoaXMgbWV0aG9kIHdpbGwgYmUgdW5yZWFjaGFibGUgZnJvbSBoZWFkIGFmdGVyIGl0IHJldHVybnMuCisgICAgICogRG9lcyBub3QgZ3VhcmFudGVlIHRvIGVsaW1pbmF0ZSBzbGFjaywgb25seSB0aGF0IGhlYWQgd2lsbAorICAgICAqIHBvaW50IHRvIGEgbm9kZSB0aGF0IHdhcyBhY3RpdmUgd2hpbGUgdGhpcyBtZXRob2Qgd2FzIHJ1bm5pbmcuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCB2b2lkIHVwZGF0ZUhlYWQoKSB7CisgICAgICAgIC8vIEVpdGhlciBoZWFkIGFscmVhZHkgcG9pbnRzIHRvIGFuIGFjdGl2ZSBub2RlLCBvciB3ZSBrZWVwCisgICAgICAgIC8vIHRyeWluZyB0byBjYXMgaXQgdG8gdGhlIGZpcnN0IG5vZGUgdW50aWwgaXQgZG9lcy4KKyAgICAgICAgTm9kZTxFPiBoLCBwLCBxOworICAgICAgICByZXN0YXJ0RnJvbUhlYWQ6CisgICAgICAgIHdoaWxlICgoaCA9IGhlYWQpLml0ZW0gPT0gbnVsbCAmJiAocCA9IGgucHJldikgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIGlmICgocSA9IHAucHJldikgPT0gbnVsbCB8fAorICAgICAgICAgICAgICAgICAgICAocSA9IChwID0gcSkucHJldikgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAvLyBJdCBpcyBwb3NzaWJsZSB0aGF0IHAgaXMgUFJFVl9URVJNSU5BVE9SLAorICAgICAgICAgICAgICAgICAgICAvLyBidXQgaWYgc28sIHRoZSBDQVMgaXMgZ3VhcmFudGVlZCB0byBmYWlsLgorICAgICAgICAgICAgICAgICAgICBpZiAoY2FzSGVhZChoLCBwKSkKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgcmVzdGFydEZyb21IZWFkOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbHNlIGlmIChoICE9IGhlYWQpCisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHJlc3RhcnRGcm9tSGVhZDsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIHAgPSBxOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR3VhcmFudGVlcyB0aGF0IGFueSBub2RlIHdoaWNoIHdhcyB1bmxpbmtlZCBiZWZvcmUgYSBjYWxsIHRvCisgICAgICogdGhpcyBtZXRob2Qgd2lsbCBiZSB1bnJlYWNoYWJsZSBmcm9tIHRhaWwgYWZ0ZXIgaXQgcmV0dXJucy4KKyAgICAgKiBEb2VzIG5vdCBndWFyYW50ZWUgdG8gZWxpbWluYXRlIHNsYWNrLCBvbmx5IHRoYXQgdGFpbCB3aWxsCisgICAgICogcG9pbnQgdG8gYSBub2RlIHRoYXQgd2FzIGFjdGl2ZSB3aGlsZSB0aGlzIG1ldGhvZCB3YXMgcnVubmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIHZvaWQgdXBkYXRlVGFpbCgpIHsKKyAgICAgICAgLy8gRWl0aGVyIHRhaWwgYWxyZWFkeSBwb2ludHMgdG8gYW4gYWN0aXZlIG5vZGUsIG9yIHdlIGtlZXAKKyAgICAgICAgLy8gdHJ5aW5nIHRvIGNhcyBpdCB0byB0aGUgbGFzdCBub2RlIHVudGlsIGl0IGRvZXMuCisgICAgICAgIE5vZGU8RT4gdCwgcCwgcTsKKyAgICAgICAgcmVzdGFydEZyb21UYWlsOgorICAgICAgICB3aGlsZSAoKHQgPSB0YWlsKS5pdGVtID09IG51bGwgJiYgKHAgPSB0Lm5leHQpICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBpZiAoKHEgPSBwLm5leHQpID09IG51bGwgfHwKKyAgICAgICAgICAgICAgICAgICAgKHEgPSAocCA9IHEpLm5leHQpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gSXQgaXMgcG9zc2libGUgdGhhdCBwIGlzIE5FWFRfVEVSTUlOQVRPUiwKKyAgICAgICAgICAgICAgICAgICAgLy8gYnV0IGlmIHNvLCB0aGUgQ0FTIGlzIGd1YXJhbnRlZWQgdG8gZmFpbC4KKyAgICAgICAgICAgICAgICAgICAgaWYgKGNhc1RhaWwodCwgcCkpCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHJlc3RhcnRGcm9tVGFpbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZSBpZiAodCAhPSB0YWlsKQorICAgICAgICAgICAgICAgICAgICBjb250aW51ZSByZXN0YXJ0RnJvbVRhaWw7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBwID0gcTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBza2lwRGVsZXRlZFByZWRlY2Vzc29ycyhOb2RlPEU+IHgpIHsKKyAgICAgICAgd2hpbGVBY3RpdmU6CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIE5vZGU8RT4gcHJldiA9IHgucHJldjsKKyAgICAgICAgICAgIC8vIGFzc2VydCBwcmV2ICE9IG51bGw7CisgICAgICAgICAgICAvLyBhc3NlcnQgeCAhPSBORVhUX1RFUk1JTkFUT1I7CisgICAgICAgICAgICAvLyBhc3NlcnQgeCAhPSBQUkVWX1RFUk1JTkFUT1I7CisgICAgICAgICAgICBOb2RlPEU+IHAgPSBwcmV2OworICAgICAgICAgICAgZmluZEFjdGl2ZToKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBpZiAocC5pdGVtICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrIGZpbmRBY3RpdmU7CisgICAgICAgICAgICAgICAgTm9kZTxFPiBxID0gcC5wcmV2OworICAgICAgICAgICAgICAgIGlmIChxID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHAubmV4dCA9PSBwKQorICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgd2hpbGVBY3RpdmU7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrIGZpbmRBY3RpdmU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UgaWYgKHAgPT0gcSkKKyAgICAgICAgICAgICAgICAgICAgY29udGludWUgd2hpbGVBY3RpdmU7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBwID0gcTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gZm91bmQgYWN0aXZlIENBUyB0YXJnZXQKKyAgICAgICAgICAgIGlmIChwcmV2ID09IHAgfHwgeC5jYXNQcmV2KHByZXYsIHApKQorICAgICAgICAgICAgICAgIHJldHVybjsKKworICAgICAgICB9IHdoaWxlICh4Lml0ZW0gIT0gbnVsbCB8fCB4Lm5leHQgPT0gbnVsbCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNraXBEZWxldGVkU3VjY2Vzc29ycyhOb2RlPEU+IHgpIHsKKyAgICAgICAgd2hpbGVBY3RpdmU6CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIE5vZGU8RT4gbmV4dCA9IHgubmV4dDsKKyAgICAgICAgICAgIC8vIGFzc2VydCBuZXh0ICE9IG51bGw7CisgICAgICAgICAgICAvLyBhc3NlcnQgeCAhPSBORVhUX1RFUk1JTkFUT1I7CisgICAgICAgICAgICAvLyBhc3NlcnQgeCAhPSBQUkVWX1RFUk1JTkFUT1I7CisgICAgICAgICAgICBOb2RlPEU+IHAgPSBuZXh0OworICAgICAgICAgICAgZmluZEFjdGl2ZToKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBpZiAocC5pdGVtICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrIGZpbmRBY3RpdmU7CisgICAgICAgICAgICAgICAgTm9kZTxFPiBxID0gcC5uZXh0OworICAgICAgICAgICAgICAgIGlmIChxID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHAucHJldiA9PSBwKQorICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgd2hpbGVBY3RpdmU7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrIGZpbmRBY3RpdmU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UgaWYgKHAgPT0gcSkKKyAgICAgICAgICAgICAgICAgICAgY29udGludWUgd2hpbGVBY3RpdmU7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBwID0gcTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gZm91bmQgYWN0aXZlIENBUyB0YXJnZXQKKyAgICAgICAgICAgIGlmIChuZXh0ID09IHAgfHwgeC5jYXNOZXh0KG5leHQsIHApKQorICAgICAgICAgICAgICAgIHJldHVybjsKKworICAgICAgICB9IHdoaWxlICh4Lml0ZW0gIT0gbnVsbCB8fCB4LnByZXYgPT0gbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3VjY2Vzc29yIG9mIHAsIG9yIHRoZSBmaXJzdCBub2RlIGlmIHAubmV4dCBoYXMgYmVlbgorICAgICAqIGxpbmtlZCB0byBzZWxmLCB3aGljaCB3aWxsIG9ubHkgYmUgdHJ1ZSBpZiB0cmF2ZXJzaW5nIHdpdGggYQorICAgICAqIHN0YWxlIHBvaW50ZXIgdGhhdCBpcyBub3cgb2ZmIHRoZSBsaXN0LgorICAgICAqLworICAgIGZpbmFsIE5vZGU8RT4gc3VjYyhOb2RlPEU+IHApIHsKKyAgICAgICAgLy8gVE9ETzogc2hvdWxkIHdlIHNraXAgZGVsZXRlZCBub2RlcyBoZXJlPworICAgICAgICBOb2RlPEU+IHEgPSBwLm5leHQ7CisgICAgICAgIHJldHVybiAocCA9PSBxKSA/IGZpcnN0KCkgOiBxOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByZWRlY2Vzc29yIG9mIHAsIG9yIHRoZSBsYXN0IG5vZGUgaWYgcC5wcmV2IGhhcyBiZWVuCisgICAgICogbGlua2VkIHRvIHNlbGYsIHdoaWNoIHdpbGwgb25seSBiZSB0cnVlIGlmIHRyYXZlcnNpbmcgd2l0aCBhCisgICAgICogc3RhbGUgcG9pbnRlciB0aGF0IGlzIG5vdyBvZmYgdGhlIGxpc3QuCisgICAgICovCisgICAgZmluYWwgTm9kZTxFPiBwcmVkKE5vZGU8RT4gcCkgeworICAgICAgICBOb2RlPEU+IHEgPSBwLnByZXY7CisgICAgICAgIHJldHVybiAocCA9PSBxKSA/IGxhc3QoKSA6IHE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZmlyc3Qgbm9kZSwgdGhlIHVuaXF1ZSBub2RlIHAgZm9yIHdoaWNoOgorICAgICAqICAgICBwLnByZXYgPT0gbnVsbCAmJiBwLm5leHQgIT0gcAorICAgICAqIFRoZSByZXR1cm5lZCBub2RlIG1heSBvciBtYXkgbm90IGJlIGxvZ2ljYWxseSBkZWxldGVkLgorICAgICAqIEd1YXJhbnRlZXMgdGhhdCBoZWFkIGlzIHNldCB0byB0aGUgcmV0dXJuZWQgbm9kZS4KKyAgICAgKi8KKyAgICBOb2RlPEU+IGZpcnN0KCkgeworICAgICAgICByZXN0YXJ0RnJvbUhlYWQ6CisgICAgICAgIGZvciAoOzspCisgICAgICAgICAgICBmb3IgKE5vZGU8RT4gaCA9IGhlYWQsIHAgPSBoLCBxOzspIHsKKyAgICAgICAgICAgICAgICBpZiAoKHEgPSBwLnByZXYpICE9IG51bGwgJiYKKyAgICAgICAgICAgICAgICAgICAgKHEgPSAocCA9IHEpLnByZXYpICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGZvciBoZWFkIHVwZGF0ZXMgZXZlcnkgb3RoZXIgaG9wLgorICAgICAgICAgICAgICAgICAgICAvLyBJZiBwID09IHEsIHdlIGFyZSBzdXJlIHRvIGZvbGxvdyBoZWFkIGluc3RlYWQuCisgICAgICAgICAgICAgICAgICAgIHAgPSAoaCAhPSAoaCA9IGhlYWQpKSA/IGggOiBxOworICAgICAgICAgICAgICAgIGVsc2UgaWYgKHAgPT0gaAorICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEl0IGlzIHBvc3NpYmxlIHRoYXQgcCBpcyBQUkVWX1RFUk1JTkFUT1IsCisgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IGlmIHNvLCB0aGUgQ0FTIGlzIGd1YXJhbnRlZWQgdG8gZmFpbC4KKyAgICAgICAgICAgICAgICAgICAgICAgICB8fCBjYXNIZWFkKGgsIHApKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gcDsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHJlc3RhcnRGcm9tSGVhZDsKKyAgICAgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsYXN0IG5vZGUsIHRoZSB1bmlxdWUgbm9kZSBwIGZvciB3aGljaDoKKyAgICAgKiAgICAgcC5uZXh0ID09IG51bGwgJiYgcC5wcmV2ICE9IHAKKyAgICAgKiBUaGUgcmV0dXJuZWQgbm9kZSBtYXkgb3IgbWF5IG5vdCBiZSBsb2dpY2FsbHkgZGVsZXRlZC4KKyAgICAgKiBHdWFyYW50ZWVzIHRoYXQgdGFpbCBpcyBzZXQgdG8gdGhlIHJldHVybmVkIG5vZGUuCisgICAgICovCisgICAgTm9kZTxFPiBsYXN0KCkgeworICAgICAgICByZXN0YXJ0RnJvbVRhaWw6CisgICAgICAgIGZvciAoOzspCisgICAgICAgICAgICBmb3IgKE5vZGU8RT4gdCA9IHRhaWwsIHAgPSB0LCBxOzspIHsKKyAgICAgICAgICAgICAgICBpZiAoKHEgPSBwLm5leHQpICE9IG51bGwgJiYKKyAgICAgICAgICAgICAgICAgICAgKHEgPSAocCA9IHEpLm5leHQpICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGZvciB0YWlsIHVwZGF0ZXMgZXZlcnkgb3RoZXIgaG9wLgorICAgICAgICAgICAgICAgICAgICAvLyBJZiBwID09IHEsIHdlIGFyZSBzdXJlIHRvIGZvbGxvdyB0YWlsIGluc3RlYWQuCisgICAgICAgICAgICAgICAgICAgIHAgPSAodCAhPSAodCA9IHRhaWwpKSA/IHQgOiBxOworICAgICAgICAgICAgICAgIGVsc2UgaWYgKHAgPT0gdAorICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEl0IGlzIHBvc3NpYmxlIHRoYXQgcCBpcyBORVhUX1RFUk1JTkFUT1IsCisgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IGlmIHNvLCB0aGUgQ0FTIGlzIGd1YXJhbnRlZWQgdG8gZmFpbC4KKyAgICAgICAgICAgICAgICAgICAgICAgICB8fCBjYXNUYWlsKHQsIHApKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gcDsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHJlc3RhcnRGcm9tVGFpbDsKKyAgICAgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBNaW5vciBjb252ZW5pZW5jZSB1dGlsaXRpZXMKKworICAgIC8qKgorICAgICAqIFRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBhcmd1bWVudCBpcyBudWxsLgorICAgICAqCisgICAgICogQHBhcmFtIHYgdGhlIGVsZW1lbnQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNoZWNrTm90TnVsbChPYmplY3QgdikgeworICAgICAgICBpZiAodiA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBlbGVtZW50IHVubGVzcyBpdCBpcyBudWxsLCBpbiB3aGljaCBjYXNlIHRocm93cworICAgICAqIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdiB0aGUgZWxlbWVudAorICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnQKKyAgICAgKi8KKyAgICBwcml2YXRlIEUgc2NyZWVuTnVsbFJlc3VsdChFIHYpIHsKKyAgICAgICAgaWYgKHYgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiB2OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgbGlzdCBhbmQgZmlsbHMgaXQgd2l0aCBlbGVtZW50cyBvZiB0aGlzIGxpc3QuCisgICAgICogVXNlZCBieSB0b0FycmF5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYXJyYXlMaXN0CisgICAgICovCisgICAgcHJpdmF0ZSBBcnJheUxpc3Q8RT4gdG9BcnJheUxpc3QoKSB7CisgICAgICAgIEFycmF5TGlzdDxFPiBsaXN0ID0gbmV3IEFycmF5TGlzdDxFPigpOworICAgICAgICBmb3IgKE5vZGU8RT4gcCA9IGZpcnN0KCk7IHAgIT0gbnVsbDsgcCA9IHN1Y2MocCkpIHsKKyAgICAgICAgICAgIEUgaXRlbSA9IHAuaXRlbTsKKyAgICAgICAgICAgIGlmIChpdGVtICE9IG51bGwpCisgICAgICAgICAgICAgICAgbGlzdC5hZGQoaXRlbSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGxpc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBlbXB0eSBkZXF1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29uY3VycmVudExpbmtlZERlcXVlKCkgeworICAgICAgICBoZWFkID0gdGFpbCA9IG5ldyBOb2RlPEU+KG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBkZXF1ZSBpbml0aWFsbHkgY29udGFpbmluZyB0aGUgZWxlbWVudHMgb2YKKyAgICAgKiB0aGUgZ2l2ZW4gY29sbGVjdGlvbiwgYWRkZWQgaW4gdHJhdmVyc2FsIG9yZGVyIG9mIHRoZQorICAgICAqIGNvbGxlY3Rpb24ncyBpdGVyYXRvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjIHRoZSBjb2xsZWN0aW9uIG9mIGVsZW1lbnRzIHRvIGluaXRpYWxseSBjb250YWluCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gb3IgYW55CisgICAgICogICAgICAgICBvZiBpdHMgZWxlbWVudHMgYXJlIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29uY3VycmVudExpbmtlZERlcXVlKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGMpIHsKKyAgICAgICAgLy8gQ29weSBjIGludG8gYSBwcml2YXRlIGNoYWluIG9mIE5vZGVzCisgICAgICAgIE5vZGU8RT4gaCA9IG51bGwsIHQgPSBudWxsOworICAgICAgICBmb3IgKEUgZSA6IGMpIHsKKyAgICAgICAgICAgIGNoZWNrTm90TnVsbChlKTsKKyAgICAgICAgICAgIE5vZGU8RT4gbmV3Tm9kZSA9IG5ldyBOb2RlPEU+KGUpOworICAgICAgICAgICAgaWYgKGggPT0gbnVsbCkKKyAgICAgICAgICAgICAgICBoID0gdCA9IG5ld05vZGU7CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICB0LmxhenlTZXROZXh0KG5ld05vZGUpOworICAgICAgICAgICAgICAgIG5ld05vZGUubGF6eVNldFByZXYodCk7CisgICAgICAgICAgICAgICAgdCA9IG5ld05vZGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaW5pdEhlYWRUYWlsKGgsIHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIGhlYWQgYW5kIHRhaWwsIGVuc3VyaW5nIGludmFyaWFudHMgaG9sZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdEhlYWRUYWlsKE5vZGU8RT4gaCwgTm9kZTxFPiB0KSB7CisgICAgICAgIGlmIChoID09IHQpIHsKKyAgICAgICAgICAgIGlmIChoID09IG51bGwpCisgICAgICAgICAgICAgICAgaCA9IHQgPSBuZXcgTm9kZTxFPihudWxsKTsKKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIC8vIEF2b2lkIGVkZ2UgY2FzZSBvZiBhIHNpbmdsZSBOb2RlIHdpdGggbm9uLW51bGwgaXRlbS4KKyAgICAgICAgICAgICAgICBOb2RlPEU+IG5ld05vZGUgPSBuZXcgTm9kZTxFPihudWxsKTsKKyAgICAgICAgICAgICAgICB0LmxhenlTZXROZXh0KG5ld05vZGUpOworICAgICAgICAgICAgICAgIG5ld05vZGUubGF6eVNldFByZXYodCk7CisgICAgICAgICAgICAgICAgdCA9IG5ld05vZGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaGVhZCA9IGg7CisgICAgICAgIHRhaWwgPSB0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGF0IHRoZSBmcm9udCBvZiB0aGlzIGRlcXVlLgorICAgICAqIEFzIHRoZSBkZXF1ZSBpcyB1bmJvdW5kZWQsIHRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIgdGhyb3cKKyAgICAgKiB7QGxpbmsgSWxsZWdhbFN0YXRlRXhjZXB0aW9ufS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRGaXJzdChFIGUpIHsKKyAgICAgICAgbGlua0ZpcnN0KGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGF0IHRoZSBlbmQgb2YgdGhpcyBkZXF1ZS4KKyAgICAgKiBBcyB0aGUgZGVxdWUgaXMgdW5ib3VuZGVkLCB0aGlzIG1ldGhvZCB3aWxsIG5ldmVyIHRocm93CisgICAgICoge0BsaW5rIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbn0uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAbGluayAjYWRkfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRMYXN0KEUgZSkgeworICAgICAgICBsaW5rTGFzdChlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBhdCB0aGUgZnJvbnQgb2YgdGhpcyBkZXF1ZS4KKyAgICAgKiBBcyB0aGUgZGVxdWUgaXMgdW5ib3VuZGVkLCB0aGlzIG1ldGhvZCB3aWxsIG5ldmVyIHJldHVybiB7QGNvZGUgZmFsc2V9LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gKGFzIHNwZWNpZmllZCBieSB7QGxpbmsgRGVxdWUjb2ZmZXJGaXJzdH0pCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG9mZmVyRmlyc3QoRSBlKSB7CisgICAgICAgIGxpbmtGaXJzdChlKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgYXQgdGhlIGVuZCBvZiB0aGlzIGRlcXVlLgorICAgICAqIEFzIHRoZSBkZXF1ZSBpcyB1bmJvdW5kZWQsIHRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIgcmV0dXJuIHtAY29kZSBmYWxzZX0uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAbGluayAjYWRkfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IChhcyBzcGVjaWZpZWQgYnkge0BsaW5rIERlcXVlI29mZmVyTGFzdH0pCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG9mZmVyTGFzdChFIGUpIHsKKyAgICAgICAgbGlua0xhc3QoZSk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIHB1YmxpYyBFIHBlZWtGaXJzdCgpIHsKKyAgICAgICAgZm9yIChOb2RlPEU+IHAgPSBmaXJzdCgpOyBwICE9IG51bGw7IHAgPSBzdWNjKHApKSB7CisgICAgICAgICAgICBFIGl0ZW0gPSBwLml0ZW07CisgICAgICAgICAgICBpZiAoaXRlbSAhPSBudWxsKQorICAgICAgICAgICAgICAgIHJldHVybiBpdGVtOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBFIHBlZWtMYXN0KCkgeworICAgICAgICBmb3IgKE5vZGU8RT4gcCA9IGxhc3QoKTsgcCAhPSBudWxsOyBwID0gcHJlZChwKSkgeworICAgICAgICAgICAgRSBpdGVtID0gcC5pdGVtOworICAgICAgICAgICAgaWYgKGl0ZW0gIT0gbnVsbCkKKyAgICAgICAgICAgICAgICByZXR1cm4gaXRlbTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBFIGdldEZpcnN0KCkgeworICAgICAgICByZXR1cm4gc2NyZWVuTnVsbFJlc3VsdChwZWVrRmlyc3QoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgRSBnZXRMYXN0KCkgeworICAgICAgICByZXR1cm4gc2NyZWVuTnVsbFJlc3VsdChwZWVrTGFzdCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRSBwb2xsRmlyc3QoKSB7CisgICAgICAgIGZvciAoTm9kZTxFPiBwID0gZmlyc3QoKTsgcCAhPSBudWxsOyBwID0gc3VjYyhwKSkgeworICAgICAgICAgICAgRSBpdGVtID0gcC5pdGVtOworICAgICAgICAgICAgaWYgKGl0ZW0gIT0gbnVsbCAmJiBwLmNhc0l0ZW0oaXRlbSwgbnVsbCkpIHsKKyAgICAgICAgICAgICAgICB1bmxpbmsocCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIEUgcG9sbExhc3QoKSB7CisgICAgICAgIGZvciAoTm9kZTxFPiBwID0gbGFzdCgpOyBwICE9IG51bGw7IHAgPSBwcmVkKHApKSB7CisgICAgICAgICAgICBFIGl0ZW0gPSBwLml0ZW07CisgICAgICAgICAgICBpZiAoaXRlbSAhPSBudWxsICYmIHAuY2FzSXRlbShpdGVtLCBudWxsKSkgeworICAgICAgICAgICAgICAgIHVubGluayhwKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gaXRlbTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBFIHJlbW92ZUZpcnN0KCkgeworICAgICAgICByZXR1cm4gc2NyZWVuTnVsbFJlc3VsdChwb2xsRmlyc3QoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgRSByZW1vdmVMYXN0KCkgeworICAgICAgICByZXR1cm4gc2NyZWVuTnVsbFJlc3VsdChwb2xsTGFzdCgpKTsKKyAgICB9CisKKyAgICAvLyAqKiogUXVldWUgYW5kIHN0YWNrIG1ldGhvZHMgKioqCisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBhdCB0aGUgdGFpbCBvZiB0aGlzIGRlcXVlLgorICAgICAqIEFzIHRoZSBkZXF1ZSBpcyB1bmJvdW5kZWQsIHRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIgcmV0dXJuIHtAY29kZSBmYWxzZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSAoYXMgc3BlY2lmaWVkIGJ5IHtAbGluayBRdWV1ZSNvZmZlcn0pCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG9mZmVyKEUgZSkgeworICAgICAgICByZXR1cm4gb2ZmZXJMYXN0KGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGF0IHRoZSB0YWlsIG9mIHRoaXMgZGVxdWUuCisgICAgICogQXMgdGhlIGRlcXVlIGlzIHVuYm91bmRlZCwgdGhpcyBtZXRob2Qgd2lsbCBuZXZlciB0aHJvdworICAgICAqIHtAbGluayBJbGxlZ2FsU3RhdGVFeGNlcHRpb259IG9yIHJldHVybiB7QGNvZGUgZmFsc2V9LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gKGFzIHNwZWNpZmllZCBieSB7QGxpbmsgQ29sbGVjdGlvbiNhZGR9KQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBhZGQoRSBlKSB7CisgICAgICAgIHJldHVybiBvZmZlckxhc3QoZSk7CisgICAgfQorCisgICAgcHVibGljIEUgcG9sbCgpICAgICAgICAgICB7IHJldHVybiBwb2xsRmlyc3QoKTsgfQorICAgIHB1YmxpYyBFIHJlbW92ZSgpICAgICAgICAgeyByZXR1cm4gcmVtb3ZlRmlyc3QoKTsgfQorICAgIHB1YmxpYyBFIHBlZWsoKSAgICAgICAgICAgeyByZXR1cm4gcGVla0ZpcnN0KCk7IH0KKyAgICBwdWJsaWMgRSBlbGVtZW50KCkgICAgICAgIHsgcmV0dXJuIGdldEZpcnN0KCk7IH0KKyAgICBwdWJsaWMgdm9pZCBwdXNoKEUgZSkgICAgIHsgYWRkRmlyc3QoZSk7IH0KKyAgICBwdWJsaWMgRSBwb3AoKSAgICAgICAgICAgIHsgcmV0dXJuIHJlbW92ZUZpcnN0KCk7IH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGZpcnN0IGVsZW1lbnQge0Bjb2RlIGV9IHN1Y2ggdGhhdAorICAgICAqIHtAY29kZSBvLmVxdWFscyhlKX0sIGlmIHN1Y2ggYW4gZWxlbWVudCBleGlzdHMgaW4gdGhpcyBkZXF1ZS4KKyAgICAgKiBJZiB0aGUgZGVxdWUgZG9lcyBub3QgY29udGFpbiB0aGUgZWxlbWVudCwgaXQgaXMgdW5jaGFuZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIG8gZWxlbWVudCB0byBiZSByZW1vdmVkIGZyb20gdGhpcyBkZXF1ZSwgaWYgcHJlc2VudAorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBkZXF1ZSBjb250YWluZWQgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZUZpcnN0T2NjdXJyZW5jZShPYmplY3QgbykgeworICAgICAgICBjaGVja05vdE51bGwobyk7CisgICAgICAgIGZvciAoTm9kZTxFPiBwID0gZmlyc3QoKTsgcCAhPSBudWxsOyBwID0gc3VjYyhwKSkgeworICAgICAgICAgICAgRSBpdGVtID0gcC5pdGVtOworICAgICAgICAgICAgaWYgKGl0ZW0gIT0gbnVsbCAmJiBvLmVxdWFscyhpdGVtKSAmJiBwLmNhc0l0ZW0oaXRlbSwgbnVsbCkpIHsKKyAgICAgICAgICAgICAgICB1bmxpbmsocCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGxhc3QgZWxlbWVudCB7QGNvZGUgZX0gc3VjaCB0aGF0CisgICAgICoge0Bjb2RlIG8uZXF1YWxzKGUpfSwgaWYgc3VjaCBhbiBlbGVtZW50IGV4aXN0cyBpbiB0aGlzIGRlcXVlLgorICAgICAqIElmIHRoZSBkZXF1ZSBkb2VzIG5vdCBjb250YWluIHRoZSBlbGVtZW50LCBpdCBpcyB1bmNoYW5nZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBlbGVtZW50IHRvIGJlIHJlbW92ZWQgZnJvbSB0aGlzIGRlcXVlLCBpZiBwcmVzZW50CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGRlcXVlIGNvbnRhaW5lZCB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlTGFzdE9jY3VycmVuY2UoT2JqZWN0IG8pIHsKKyAgICAgICAgY2hlY2tOb3ROdWxsKG8pOworICAgICAgICBmb3IgKE5vZGU8RT4gcCA9IGxhc3QoKTsgcCAhPSBudWxsOyBwID0gcHJlZChwKSkgeworICAgICAgICAgICAgRSBpdGVtID0gcC5pdGVtOworICAgICAgICAgICAgaWYgKGl0ZW0gIT0gbnVsbCAmJiBvLmVxdWFscyhpdGVtKSAmJiBwLmNhc0l0ZW0oaXRlbSwgbnVsbCkpIHsKKyAgICAgICAgICAgICAgICB1bmxpbmsocCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoaXMgZGVxdWUgY29udGFpbnMgYXQgbGVhc3Qgb25lCisgICAgICogZWxlbWVudCB7QGNvZGUgZX0gc3VjaCB0aGF0IHtAY29kZSBvLmVxdWFscyhlKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBlbGVtZW50IHdob3NlIHByZXNlbmNlIGluIHRoaXMgZGVxdWUgaXMgdG8gYmUgdGVzdGVkCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBkZXF1ZSBjb250YWlucyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3QgbykgeworICAgICAgICBpZiAobyA9PSBudWxsKSByZXR1cm4gZmFsc2U7CisgICAgICAgIGZvciAoTm9kZTxFPiBwID0gZmlyc3QoKTsgcCAhPSBudWxsOyBwID0gc3VjYyhwKSkgeworICAgICAgICAgICAgRSBpdGVtID0gcC5pdGVtOworICAgICAgICAgICAgaWYgKGl0ZW0gIT0gbnVsbCAmJiBvLmVxdWFscyhpdGVtKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBjb2xsZWN0aW9uIGNvbnRhaW5zIG5vIGVsZW1lbnRzLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBjb2xsZWN0aW9uIGNvbnRhaW5zIG5vIGVsZW1lbnRzCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgcmV0dXJuIHBlZWtGaXJzdCgpID09IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgZGVxdWUuICBJZiB0aGlzIGRlcXVlCisgICAgICogY29udGFpbnMgbW9yZSB0aGFuIHtAY29kZSBJbnRlZ2VyLk1BWF9WQUxVRX0gZWxlbWVudHMsIGl0CisgICAgICogcmV0dXJucyB7QGNvZGUgSW50ZWdlci5NQVhfVkFMVUV9LgorICAgICAqCisgICAgICogPHA+QmV3YXJlIHRoYXQsIHVubGlrZSBpbiBtb3N0IGNvbGxlY3Rpb25zLCB0aGlzIG1ldGhvZCBpcworICAgICAqIDxlbT5OT1Q8L2VtPiBhIGNvbnN0YW50LXRpbWUgb3BlcmF0aW9uLiBCZWNhdXNlIG9mIHRoZQorICAgICAqIGFzeW5jaHJvbm91cyBuYXR1cmUgb2YgdGhlc2UgZGVxdWVzLCBkZXRlcm1pbmluZyB0aGUgY3VycmVudAorICAgICAqIG51bWJlciBvZiBlbGVtZW50cyByZXF1aXJlcyB0cmF2ZXJzaW5nIHRoZW0gYWxsIHRvIGNvdW50IHRoZW0uCisgICAgICogQWRkaXRpb25hbGx5LCBpdCBpcyBwb3NzaWJsZSBmb3IgdGhlIHNpemUgdG8gY2hhbmdlIGR1cmluZworICAgICAqIGV4ZWN1dGlvbiBvZiB0aGlzIG1ldGhvZCwgaW4gd2hpY2ggY2FzZSB0aGUgcmV0dXJuZWQgcmVzdWx0CisgICAgICogd2lsbCBiZSBpbmFjY3VyYXRlLiBUaHVzLCB0aGlzIG1ldGhvZCBpcyB0eXBpY2FsbHkgbm90IHZlcnkKKyAgICAgKiB1c2VmdWwgaW4gY29uY3VycmVudCBhcHBsaWNhdGlvbnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBkZXF1ZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgZm9yIChOb2RlPEU+IHAgPSBmaXJzdCgpOyBwICE9IG51bGw7IHAgPSBzdWNjKHApKQorICAgICAgICAgICAgaWYgKHAuaXRlbSAhPSBudWxsKQorICAgICAgICAgICAgICAgIC8vIENvbGxlY3Rpb24uc2l6ZSgpIHNwZWMgc2F5cyB0byBtYXggb3V0CisgICAgICAgICAgICAgICAgaWYgKCsrY291bnQgPT0gSW50ZWdlci5NQVhfVkFMVUUpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICByZXR1cm4gY291bnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgZmlyc3QgZWxlbWVudCB7QGNvZGUgZX0gc3VjaCB0aGF0CisgICAgICoge0Bjb2RlIG8uZXF1YWxzKGUpfSwgaWYgc3VjaCBhbiBlbGVtZW50IGV4aXN0cyBpbiB0aGlzIGRlcXVlLgorICAgICAqIElmIHRoZSBkZXF1ZSBkb2VzIG5vdCBjb250YWluIHRoZSBlbGVtZW50LCBpdCBpcyB1bmNoYW5nZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBlbGVtZW50IHRvIGJlIHJlbW92ZWQgZnJvbSB0aGlzIGRlcXVlLCBpZiBwcmVzZW50CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGRlcXVlIGNvbnRhaW5lZCB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvKSB7CisgICAgICAgIHJldHVybiByZW1vdmVGaXJzdE9jY3VycmVuY2Uobyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiB0byB0aGUgZW5kIG9mCisgICAgICogdGhpcyBkZXF1ZSwgaW4gdGhlIG9yZGVyIHRoYXQgdGhleSBhcmUgcmV0dXJuZWQgYnkgdGhlIHNwZWNpZmllZAorICAgICAqIGNvbGxlY3Rpb24ncyBpdGVyYXRvci4gIEF0dGVtcHRzIHRvIHtAY29kZSBhZGRBbGx9IG9mIGEgZGVxdWUgdG8KKyAgICAgKiBpdHNlbGYgcmVzdWx0IGluIHtAY29kZSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259LgorICAgICAqCisgICAgICogQHBhcmFtIGMgdGhlIGVsZW1lbnRzIHRvIGJlIGluc2VydGVkIGludG8gdGhpcyBkZXF1ZQorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgZGVxdWUgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIG9yIGFueQorICAgICAqICAgICAgICAgb2YgaXRzIGVsZW1lbnRzIGFyZSBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGNvbGxlY3Rpb24gaXMgdGhpcyBkZXF1ZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGFkZEFsbChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjKSB7CisgICAgICAgIGlmIChjID09IHRoaXMpCisgICAgICAgICAgICAvLyBBcyBoaXN0b3JpY2FsbHkgc3BlY2lmaWVkIGluIEFic3RyYWN0UXVldWUjYWRkQWxsCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisKKyAgICAgICAgLy8gQ29weSBjIGludG8gYSBwcml2YXRlIGNoYWluIG9mIE5vZGVzCisgICAgICAgIE5vZGU8RT4gYmVnaW5uaW5nT2ZUaGVFbmQgPSBudWxsLCBsYXN0ID0gbnVsbDsKKyAgICAgICAgZm9yIChFIGUgOiBjKSB7CisgICAgICAgICAgICBjaGVja05vdE51bGwoZSk7CisgICAgICAgICAgICBOb2RlPEU+IG5ld05vZGUgPSBuZXcgTm9kZTxFPihlKTsKKyAgICAgICAgICAgIGlmIChiZWdpbm5pbmdPZlRoZUVuZCA9PSBudWxsKQorICAgICAgICAgICAgICAgIGJlZ2lubmluZ09mVGhlRW5kID0gbGFzdCA9IG5ld05vZGU7CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICBsYXN0LmxhenlTZXROZXh0KG5ld05vZGUpOworICAgICAgICAgICAgICAgIG5ld05vZGUubGF6eVNldFByZXYobGFzdCk7CisgICAgICAgICAgICAgICAgbGFzdCA9IG5ld05vZGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJlZ2lubmluZ09mVGhlRW5kID09IG51bGwpCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgICAgLy8gQXRvbWljYWxseSBhcHBlbmQgdGhlIGNoYWluIGF0IHRoZSB0YWlsIG9mIHRoaXMgY29sbGVjdGlvbgorICAgICAgICByZXN0YXJ0RnJvbVRhaWw6CisgICAgICAgIGZvciAoOzspCisgICAgICAgICAgICBmb3IgKE5vZGU8RT4gdCA9IHRhaWwsIHAgPSB0LCBxOzspIHsKKyAgICAgICAgICAgICAgICBpZiAoKHEgPSBwLm5leHQpICE9IG51bGwgJiYKKyAgICAgICAgICAgICAgICAgICAgKHEgPSAocCA9IHEpLm5leHQpICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGZvciB0YWlsIHVwZGF0ZXMgZXZlcnkgb3RoZXIgaG9wLgorICAgICAgICAgICAgICAgICAgICAvLyBJZiBwID09IHEsIHdlIGFyZSBzdXJlIHRvIGZvbGxvdyB0YWlsIGluc3RlYWQuCisgICAgICAgICAgICAgICAgICAgIHAgPSAodCAhPSAodCA9IHRhaWwpKSA/IHQgOiBxOworICAgICAgICAgICAgICAgIGVsc2UgaWYgKHAucHJldiA9PSBwKSAvLyBORVhUX1RFUk1JTkFUT1IKKyAgICAgICAgICAgICAgICAgICAgY29udGludWUgcmVzdGFydEZyb21UYWlsOworICAgICAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgICAgICAvLyBwIGlzIGxhc3Qgbm9kZQorICAgICAgICAgICAgICAgICAgICBiZWdpbm5pbmdPZlRoZUVuZC5sYXp5U2V0UHJldihwKTsgLy8gQ0FTIHBpZ2d5YmFjaworICAgICAgICAgICAgICAgICAgICBpZiAocC5jYXNOZXh0KG51bGwsIGJlZ2lubmluZ09mVGhlRW5kKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3VjY2Vzc2Z1bCBDQVMgaXMgdGhlIGxpbmVhcml6YXRpb24gcG9pbnQKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBhbGwgZWxlbWVudHMgdG8gYmUgYWRkZWQgdG8gdGhpcyBkZXF1ZS4KKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY2FzVGFpbCh0LCBsYXN0KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRyeSBhIGxpdHRsZSBoYXJkZXIgdG8gdXBkYXRlIHRhaWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2luY2Ugd2UgbWF5IGJlIGFkZGluZyBtYW55IGVsZW1lbnRzLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQgPSB0YWlsOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsYXN0Lm5leHQgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzVGFpbCh0LCBsYXN0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8vIExvc3QgQ0FTIHJhY2UgdG8gYW5vdGhlciB0aHJlYWQ7IHJlLXJlYWQgbmV4dAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGFsbCBvZiB0aGUgZWxlbWVudHMgZnJvbSB0aGlzIGRlcXVlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICB3aGlsZSAocG9sbEZpcnN0KCkgIT0gbnVsbCkKKyAgICAgICAgICAgIDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcgYWxsIG9mIHRoZSBlbGVtZW50cyBpbiB0aGlzIGRlcXVlLCBpbgorICAgICAqIHByb3BlciBzZXF1ZW5jZSAoZnJvbSBmaXJzdCB0byBsYXN0IGVsZW1lbnQpLgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybmVkIGFycmF5IHdpbGwgYmUgInNhZmUiIGluIHRoYXQgbm8gcmVmZXJlbmNlcyB0byBpdCBhcmUKKyAgICAgKiBtYWludGFpbmVkIGJ5IHRoaXMgZGVxdWUuICAoSW4gb3RoZXIgd29yZHMsIHRoaXMgbWV0aG9kIG11c3QgYWxsb2NhdGUKKyAgICAgKiBhIG5ldyBhcnJheSkuICBUaGUgY2FsbGVyIGlzIHRodXMgZnJlZSB0byBtb2RpZnkgdGhlIHJldHVybmVkIGFycmF5LgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgYWN0cyBhcyBicmlkZ2UgYmV0d2VlbiBhcnJheS1iYXNlZCBhbmQgY29sbGVjdGlvbi1iYXNlZAorICAgICAqIEFQSXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IGNvbnRhaW5pbmcgYWxsIG9mIHRoZSBlbGVtZW50cyBpbiB0aGlzIGRlcXVlCisgICAgICovCisgICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSB7CisgICAgICAgIHJldHVybiB0b0FycmF5TGlzdCgpLnRvQXJyYXkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcgYWxsIG9mIHRoZSBlbGVtZW50cyBpbiB0aGlzIGRlcXVlLAorICAgICAqIGluIHByb3BlciBzZXF1ZW5jZSAoZnJvbSBmaXJzdCB0byBsYXN0IGVsZW1lbnQpOyB0aGUgcnVudGltZQorICAgICAqIHR5cGUgb2YgdGhlIHJldHVybmVkIGFycmF5IGlzIHRoYXQgb2YgdGhlIHNwZWNpZmllZCBhcnJheS4gIElmCisgICAgICogdGhlIGRlcXVlIGZpdHMgaW4gdGhlIHNwZWNpZmllZCBhcnJheSwgaXQgaXMgcmV0dXJuZWQgdGhlcmVpbi4KKyAgICAgKiBPdGhlcndpc2UsIGEgbmV3IGFycmF5IGlzIGFsbG9jYXRlZCB3aXRoIHRoZSBydW50aW1lIHR5cGUgb2YKKyAgICAgKiB0aGUgc3BlY2lmaWVkIGFycmF5IGFuZCB0aGUgc2l6ZSBvZiB0aGlzIGRlcXVlLgorICAgICAqCisgICAgICogPHA+SWYgdGhpcyBkZXF1ZSBmaXRzIGluIHRoZSBzcGVjaWZpZWQgYXJyYXkgd2l0aCByb29tIHRvIHNwYXJlCisgICAgICogKGkuZS4sIHRoZSBhcnJheSBoYXMgbW9yZSBlbGVtZW50cyB0aGFuIHRoaXMgZGVxdWUpLCB0aGUgZWxlbWVudCBpbgorICAgICAqIHRoZSBhcnJheSBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlIGVuZCBvZiB0aGUgZGVxdWUgaXMgc2V0IHRvCisgICAgICoge0Bjb2RlIG51bGx9LgorICAgICAqCisgICAgICogPHA+TGlrZSB0aGUge0BsaW5rICN0b0FycmF5KCl9IG1ldGhvZCwgdGhpcyBtZXRob2QgYWN0cyBhcworICAgICAqIGJyaWRnZSBiZXR3ZWVuIGFycmF5LWJhc2VkIGFuZCBjb2xsZWN0aW9uLWJhc2VkIEFQSXMuICBGdXJ0aGVyLAorICAgICAqIHRoaXMgbWV0aG9kIGFsbG93cyBwcmVjaXNlIGNvbnRyb2wgb3ZlciB0aGUgcnVudGltZSB0eXBlIG9mIHRoZQorICAgICAqIG91dHB1dCBhcnJheSwgYW5kIG1heSwgdW5kZXIgY2VydGFpbiBjaXJjdW1zdGFuY2VzLCBiZSB1c2VkIHRvCisgICAgICogc2F2ZSBhbGxvY2F0aW9uIGNvc3RzLgorICAgICAqCisgICAgICogPHA+U3VwcG9zZSB7QGNvZGUgeH0gaXMgYSBkZXF1ZSBrbm93biB0byBjb250YWluIG9ubHkgc3RyaW5ncy4KKyAgICAgKiBUaGUgZm9sbG93aW5nIGNvZGUgY2FuIGJlIHVzZWQgdG8gZHVtcCB0aGUgZGVxdWUgaW50byBhIG5ld2x5CisgICAgICogYWxsb2NhdGVkIGFycmF5IG9mIHtAY29kZSBTdHJpbmd9OgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiAgICAgU3RyaW5nW10geSA9IHgudG9BcnJheShuZXcgU3RyaW5nWzBdKTs8L3ByZT4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCB7QGNvZGUgdG9BcnJheShuZXcgT2JqZWN0WzBdKX0gaXMgaWRlbnRpY2FsIGluIGZ1bmN0aW9uIHRvCisgICAgICoge0Bjb2RlIHRvQXJyYXkoKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgaW50byB3aGljaCB0aGUgZWxlbWVudHMgb2YgdGhlIGRlcXVlIGFyZSB0bworICAgICAqICAgICAgICAgIGJlIHN0b3JlZCwgaWYgaXQgaXMgYmlnIGVub3VnaDsgb3RoZXJ3aXNlLCBhIG5ldyBhcnJheSBvZiB0aGUKKyAgICAgKiAgICAgICAgICBzYW1lIHJ1bnRpbWUgdHlwZSBpcyBhbGxvY2F0ZWQgZm9yIHRoaXMgcHVycG9zZQorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoaXMgZGVxdWUKKyAgICAgKiBAdGhyb3dzIEFycmF5U3RvcmVFeGNlcHRpb24gaWYgdGhlIHJ1bnRpbWUgdHlwZSBvZiB0aGUgc3BlY2lmaWVkIGFycmF5CisgICAgICogICAgICAgICBpcyBub3QgYSBzdXBlcnR5cGUgb2YgdGhlIHJ1bnRpbWUgdHlwZSBvZiBldmVyeSBlbGVtZW50IGluCisgICAgICogICAgICAgICB0aGlzIGRlcXVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGFycmF5IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgPFQ+IFRbXSB0b0FycmF5KFRbXSBhKSB7CisgICAgICAgIHJldHVybiB0b0FycmF5TGlzdCgpLnRvQXJyYXkoYSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cyBpbiB0aGlzIGRlcXVlIGluIHByb3BlciBzZXF1ZW5jZS4KKyAgICAgKiBUaGUgZWxlbWVudHMgd2lsbCBiZSByZXR1cm5lZCBpbiBvcmRlciBmcm9tIGZpcnN0IChoZWFkKSB0byBsYXN0ICh0YWlsKS4KKyAgICAgKgorICAgICAqIDxwPlRoZSByZXR1cm5lZCBpdGVyYXRvciBpcyBhICJ3ZWFrbHkgY29uc2lzdGVudCIgaXRlcmF0b3IgdGhhdAorICAgICAqIHdpbGwgbmV2ZXIgdGhyb3cge0BsaW5rIGphdmEudXRpbC5Db25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uCisgICAgICogQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0sIGFuZCBndWFyYW50ZWVzIHRvIHRyYXZlcnNlCisgICAgICogZWxlbWVudHMgYXMgdGhleSBleGlzdGVkIHVwb24gY29uc3RydWN0aW9uIG9mIHRoZSBpdGVyYXRvciwgYW5kCisgICAgICogbWF5IChidXQgaXMgbm90IGd1YXJhbnRlZWQgdG8pIHJlZmxlY3QgYW55IG1vZGlmaWNhdGlvbnMKKyAgICAgKiBzdWJzZXF1ZW50IHRvIGNvbnN0cnVjdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMgaW4gdGhpcyBkZXF1ZSBpbiBwcm9wZXIgc2VxdWVuY2UKKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3I8RT4gaXRlcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBuZXcgSXRyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cyBpbiB0aGlzIGRlcXVlIGluIHJldmVyc2UKKyAgICAgKiBzZXF1ZW50aWFsIG9yZGVyLiAgVGhlIGVsZW1lbnRzIHdpbGwgYmUgcmV0dXJuZWQgaW4gb3JkZXIgZnJvbQorICAgICAqIGxhc3QgKHRhaWwpIHRvIGZpcnN0IChoZWFkKS4KKyAgICAgKgorICAgICAqIDxwPlRoZSByZXR1cm5lZCBpdGVyYXRvciBpcyBhICJ3ZWFrbHkgY29uc2lzdGVudCIgaXRlcmF0b3IgdGhhdAorICAgICAqIHdpbGwgbmV2ZXIgdGhyb3cge0BsaW5rIGphdmEudXRpbC5Db25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uCisgICAgICogQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0sIGFuZCBndWFyYW50ZWVzIHRvIHRyYXZlcnNlCisgICAgICogZWxlbWVudHMgYXMgdGhleSBleGlzdGVkIHVwb24gY29uc3RydWN0aW9uIG9mIHRoZSBpdGVyYXRvciwgYW5kCisgICAgICogbWF5IChidXQgaXMgbm90IGd1YXJhbnRlZWQgdG8pIHJlZmxlY3QgYW55IG1vZGlmaWNhdGlvbnMKKyAgICAgKiBzdWJzZXF1ZW50IHRvIGNvbnN0cnVjdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMgaW4gdGhpcyBkZXF1ZSBpbiByZXZlcnNlIG9yZGVyCisgICAgICovCisgICAgcHVibGljIEl0ZXJhdG9yPEU+IGRlc2NlbmRpbmdJdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBEZXNjZW5kaW5nSXRyKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdEl0ciBpbXBsZW1lbnRzIEl0ZXJhdG9yPEU+IHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIE5leHQgbm9kZSB0byByZXR1cm4gaXRlbSBmb3IuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIE5vZGU8RT4gbmV4dE5vZGU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIG5leHRJdGVtIGhvbGRzIG9uIHRvIGl0ZW0gZmllbGRzIGJlY2F1c2Ugb25jZSB3ZSBjbGFpbQorICAgICAgICAgKiB0aGF0IGFuIGVsZW1lbnQgZXhpc3RzIGluIGhhc05leHQoKSwgd2UgbXVzdCByZXR1cm4gaXQgaW4KKyAgICAgICAgICogdGhlIGZvbGxvd2luZyBuZXh0KCkgY2FsbCBldmVuIGlmIGl0IHdhcyBpbiB0aGUgcHJvY2VzcyBvZgorICAgICAgICAgKiBiZWluZyByZW1vdmVkIHdoZW4gaGFzTmV4dCgpIHdhcyBjYWxsZWQuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIEUgbmV4dEl0ZW07CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE5vZGUgcmV0dXJuZWQgYnkgbW9zdCByZWNlbnQgY2FsbCB0byBuZXh0LiBOZWVkZWQgYnkgcmVtb3ZlLgorICAgICAgICAgKiBSZXNldCB0byBudWxsIGlmIHRoaXMgZWxlbWVudCBpcyBkZWxldGVkIGJ5IGEgY2FsbCB0byByZW1vdmUuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIE5vZGU8RT4gbGFzdFJldDsKKworICAgICAgICBhYnN0cmFjdCBOb2RlPEU+IHN0YXJ0Tm9kZSgpOworICAgICAgICBhYnN0cmFjdCBOb2RlPEU+IG5leHROb2RlKE5vZGU8RT4gcCk7CisKKyAgICAgICAgQWJzdHJhY3RJdHIoKSB7CisgICAgICAgICAgICBhZHZhbmNlKCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogU2V0cyBuZXh0Tm9kZSBhbmQgbmV4dEl0ZW0gdG8gbmV4dCB2YWxpZCBub2RlLCBvciB0byBudWxsCisgICAgICAgICAqIGlmIG5vIHN1Y2guCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIHZvaWQgYWR2YW5jZSgpIHsKKyAgICAgICAgICAgIGxhc3RSZXQgPSBuZXh0Tm9kZTsKKworICAgICAgICAgICAgTm9kZTxFPiBwID0gKG5leHROb2RlID09IG51bGwpID8gc3RhcnROb2RlKCkgOiBuZXh0Tm9kZShuZXh0Tm9kZSk7CisgICAgICAgICAgICBmb3IgKDs7IHAgPSBuZXh0Tm9kZShwKSkgeworICAgICAgICAgICAgICAgIGlmIChwID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gcCBtaWdodCBiZSBhY3RpdmUgZW5kIG9yIFRFUk1JTkFUT1Igbm9kZTsgYm90aCBhcmUgT0sKKyAgICAgICAgICAgICAgICAgICAgbmV4dE5vZGUgPSBudWxsOworICAgICAgICAgICAgICAgICAgICBuZXh0SXRlbSA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBFIGl0ZW0gPSBwLml0ZW07CisgICAgICAgICAgICAgICAgaWYgKGl0ZW0gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBuZXh0Tm9kZSA9IHA7CisgICAgICAgICAgICAgICAgICAgIG5leHRJdGVtID0gaXRlbTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXh0SXRlbSAhPSBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEUgbmV4dCgpIHsKKyAgICAgICAgICAgIEUgaXRlbSA9IG5leHRJdGVtOworICAgICAgICAgICAgaWYgKGl0ZW0gPT0gbnVsbCkgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGFkdmFuY2UoKTsKKyAgICAgICAgICAgIHJldHVybiBpdGVtOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICAgICAgTm9kZTxFPiBsID0gbGFzdFJldDsKKyAgICAgICAgICAgIGlmIChsID09IG51bGwpIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGwuaXRlbSA9IG51bGw7CisgICAgICAgICAgICB1bmxpbmsobCk7CisgICAgICAgICAgICBsYXN0UmV0ID0gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKiBGb3J3YXJkIGl0ZXJhdG9yICovCisgICAgcHJpdmF0ZSBjbGFzcyBJdHIgZXh0ZW5kcyBBYnN0cmFjdEl0ciB7CisgICAgICAgIE5vZGU8RT4gc3RhcnROb2RlKCkgeyByZXR1cm4gZmlyc3QoKTsgfQorICAgICAgICBOb2RlPEU+IG5leHROb2RlKE5vZGU8RT4gcCkgeyByZXR1cm4gc3VjYyhwKTsgfQorICAgIH0KKworICAgIC8qKiBEZXNjZW5kaW5nIGl0ZXJhdG9yICovCisgICAgcHJpdmF0ZSBjbGFzcyBEZXNjZW5kaW5nSXRyIGV4dGVuZHMgQWJzdHJhY3RJdHIgeworICAgICAgICBOb2RlPEU+IHN0YXJ0Tm9kZSgpIHsgcmV0dXJuIGxhc3QoKTsgfQorICAgICAgICBOb2RlPEU+IG5leHROb2RlKE5vZGU8RT4gcCkgeyByZXR1cm4gcHJlZChwKTsgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNhdmVzIHRoZSBzdGF0ZSB0byBhIHN0cmVhbSAodGhhdCBpcywgc2VyaWFsaXplcyBpdCkuCisgICAgICoKKyAgICAgKiBAc2VyaWFsRGF0YSBBbGwgb2YgdGhlIGVsZW1lbnRzIChlYWNoIGFuIHtAY29kZSBFfSkgaW4KKyAgICAgKiB0aGUgcHJvcGVyIG9yZGVyLCBmb2xsb3dlZCBieSBhIG51bGwKKyAgICAgKiBAcGFyYW0gcyB0aGUgc3RyZWFtCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtIHMpCisgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKKworICAgICAgICAvLyBXcml0ZSBvdXQgYW55IGhpZGRlbiBzdHVmZgorICAgICAgICBzLmRlZmF1bHRXcml0ZU9iamVjdCgpOworCisgICAgICAgIC8vIFdyaXRlIG91dCBhbGwgZWxlbWVudHMgaW4gdGhlIHByb3BlciBvcmRlci4KKyAgICAgICAgZm9yIChOb2RlPEU+IHAgPSBmaXJzdCgpOyBwICE9IG51bGw7IHAgPSBzdWNjKHApKSB7CisgICAgICAgICAgICBFIGl0ZW0gPSBwLml0ZW07CisgICAgICAgICAgICBpZiAoaXRlbSAhPSBudWxsKQorICAgICAgICAgICAgICAgIHMud3JpdGVPYmplY3QoaXRlbSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBVc2UgdHJhaWxpbmcgbnVsbCBhcyBzZW50aW5lbAorICAgICAgICBzLndyaXRlT2JqZWN0KG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlY29uc3RpdHV0ZXMgdGhlIGluc3RhbmNlIGZyb20gYSBzdHJlYW0gKHRoYXQgaXMsIGRlc2VyaWFsaXplcyBpdCkuCisgICAgICogQHBhcmFtIHMgdGhlIHN0cmVhbQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0gcykKKyAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBzLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisKKyAgICAgICAgLy8gUmVhZCBpbiBlbGVtZW50cyB1bnRpbCB0cmFpbGluZyBudWxsIHNlbnRpbmVsIGZvdW5kCisgICAgICAgIE5vZGU8RT4gaCA9IG51bGwsIHQgPSBudWxsOworICAgICAgICBPYmplY3QgaXRlbTsKKyAgICAgICAgd2hpbGUgKChpdGVtID0gcy5yZWFkT2JqZWN0KCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICAgICAgTm9kZTxFPiBuZXdOb2RlID0gbmV3IE5vZGU8RT4oKEUpIGl0ZW0pOworICAgICAgICAgICAgaWYgKGggPT0gbnVsbCkKKyAgICAgICAgICAgICAgICBoID0gdCA9IG5ld05vZGU7CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICB0LmxhenlTZXROZXh0KG5ld05vZGUpOworICAgICAgICAgICAgICAgIG5ld05vZGUubGF6eVNldFByZXYodCk7CisgICAgICAgICAgICAgICAgdCA9IG5ld05vZGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaW5pdEhlYWRUYWlsKGgsIHQpOworICAgIH0KKworICAgIC8vIFVuc2FmZSBtZWNoYW5pY3MKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHN1bi5taXNjLlVuc2FmZSBVTlNBRkUgPQorICAgICAgICBzdW4ubWlzYy5VbnNhZmUuZ2V0VW5zYWZlKCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBoZWFkT2Zmc2V0ID0KKyAgICAgICAgb2JqZWN0RmllbGRPZmZzZXQoVU5TQUZFLCAiaGVhZCIsIENvbmN1cnJlbnRMaW5rZWREZXF1ZS5jbGFzcyk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyB0YWlsT2Zmc2V0ID0KKyAgICAgICAgb2JqZWN0RmllbGRPZmZzZXQoVU5TQUZFLCAidGFpbCIsIENvbmN1cnJlbnRMaW5rZWREZXF1ZS5jbGFzcyk7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gY2FzSGVhZChOb2RlPEU+IGNtcCwgTm9kZTxFPiB2YWwpIHsKKyAgICAgICAgcmV0dXJuIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCBoZWFkT2Zmc2V0LCBjbXAsIHZhbCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGNhc1RhaWwoTm9kZTxFPiBjbXAsIE5vZGU8RT4gdmFsKSB7CisgICAgICAgIHJldHVybiBVTlNBRkUuY29tcGFyZUFuZFN3YXBPYmplY3QodGhpcywgdGFpbE9mZnNldCwgY21wLCB2YWwpOworICAgIH0KKworICAgIHN0YXRpYyBsb25nIG9iamVjdEZpZWxkT2Zmc2V0KHN1bi5taXNjLlVuc2FmZSBVTlNBRkUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGZpZWxkLCBDbGFzczw/PiBrbGF6eikgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIFVOU0FGRS5vYmplY3RGaWVsZE9mZnNldChrbGF6ei5nZXREZWNsYXJlZEZpZWxkKGZpZWxkKSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEZpZWxkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvbnZlcnQgRXhjZXB0aW9uIHRvIGNvcnJlc3BvbmRpbmcgRXJyb3IKKyAgICAgICAgICAgIE5vU3VjaEZpZWxkRXJyb3IgZXJyb3IgPSBuZXcgTm9TdWNoRmllbGRFcnJvcihmaWVsZCk7CisgICAgICAgICAgICBlcnJvci5pbml0Q2F1c2UoZSk7CisgICAgICAgICAgICB0aHJvdyBlcnJvcjsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Db25jdXJyZW50TGlua2VkUXVldWUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Db25jdXJyZW50TGlua2VkUXVldWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZWQwYTdjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0NvbmN1cnJlbnRMaW5rZWRRdWV1ZS5qYXZhCkBAIC0wLDAgKzEsNzkxIEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSBhbmQgTWFydGluIEJ1Y2hob2x6IHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YKKyAqIEpDUCBKU1ItMTY2IEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZAorICogYXQgaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudDsKKworaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdFF1ZXVlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5RdWV1ZTsKKworLy8gQkVHSU4gYW5kcm9pZC1ub3RlCisvLyByZW1vdmVkIGxpbmsgdG8gY29sbGVjdGlvbnMgZnJhbWV3b3JrIGRvY3MKKy8vIEVORCBhbmRyb2lkLW5vdGUKKworLyoqCisgKiBBbiB1bmJvdW5kZWQgdGhyZWFkLXNhZmUge0BsaW5rcGxhaW4gUXVldWUgcXVldWV9IGJhc2VkIG9uIGxpbmtlZCBub2Rlcy4KKyAqIFRoaXMgcXVldWUgb3JkZXJzIGVsZW1lbnRzIEZJRk8gKGZpcnN0LWluLWZpcnN0LW91dCkuCisgKiBUaGUgPGVtPmhlYWQ8L2VtPiBvZiB0aGUgcXVldWUgaXMgdGhhdCBlbGVtZW50IHRoYXQgaGFzIGJlZW4gb24gdGhlCisgKiBxdWV1ZSB0aGUgbG9uZ2VzdCB0aW1lLgorICogVGhlIDxlbT50YWlsPC9lbT4gb2YgdGhlIHF1ZXVlIGlzIHRoYXQgZWxlbWVudCB0aGF0IGhhcyBiZWVuIG9uIHRoZQorICogcXVldWUgdGhlIHNob3J0ZXN0IHRpbWUuIE5ldyBlbGVtZW50cworICogYXJlIGluc2VydGVkIGF0IHRoZSB0YWlsIG9mIHRoZSBxdWV1ZSwgYW5kIHRoZSBxdWV1ZSByZXRyaWV2YWwKKyAqIG9wZXJhdGlvbnMgb2J0YWluIGVsZW1lbnRzIGF0IHRoZSBoZWFkIG9mIHRoZSBxdWV1ZS4KKyAqIEEge0Bjb2RlIENvbmN1cnJlbnRMaW5rZWRRdWV1ZX0gaXMgYW4gYXBwcm9wcmlhdGUgY2hvaWNlIHdoZW4KKyAqIG1hbnkgdGhyZWFkcyB3aWxsIHNoYXJlIGFjY2VzcyB0byBhIGNvbW1vbiBjb2xsZWN0aW9uLgorICogTGlrZSBtb3N0IG90aGVyIGNvbmN1cnJlbnQgY29sbGVjdGlvbiBpbXBsZW1lbnRhdGlvbnMsIHRoaXMgY2xhc3MKKyAqIGRvZXMgbm90IHBlcm1pdCB0aGUgdXNlIG9mIHtAY29kZSBudWxsfSBlbGVtZW50cy4KKyAqCisgKiA8cD5UaGlzIGltcGxlbWVudGF0aW9uIGVtcGxveXMgYW4gZWZmaWNpZW50ICZxdW90O3dhaXQtZnJlZSZxdW90OworICogYWxnb3JpdGhtIGJhc2VkIG9uIG9uZSBkZXNjcmliZWQgaW4gPGEKKyAqIGhyZWY9Imh0dHA6Ly93d3cuY3Mucm9jaGVzdGVyLmVkdS91L21pY2hhZWwvUE9EQzk2Lmh0bWwiPiBTaW1wbGUsCisgKiBGYXN0LCBhbmQgUHJhY3RpY2FsIE5vbi1CbG9ja2luZyBhbmQgQmxvY2tpbmcgQ29uY3VycmVudCBRdWV1ZQorICogQWxnb3JpdGhtczwvYT4gYnkgTWFnZWQgTS4gTWljaGFlbCBhbmQgTWljaGFlbCBMLiBTY290dC4KKyAqCisgKiA8cD5JdGVyYXRvcnMgYXJlIDxpPndlYWtseSBjb25zaXN0ZW50PC9pPiwgcmV0dXJuaW5nIGVsZW1lbnRzCisgKiByZWZsZWN0aW5nIHRoZSBzdGF0ZSBvZiB0aGUgcXVldWUgYXQgc29tZSBwb2ludCBhdCBvciBzaW5jZSB0aGUKKyAqIGNyZWF0aW9uIG9mIHRoZSBpdGVyYXRvci4gIFRoZXkgZG8gPGVtPm5vdDwvZW0+IHRocm93IHtAbGluaworICogamF2YS51dGlsLkNvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb259LCBhbmQgbWF5IHByb2NlZWQgY29uY3VycmVudGx5CisgKiB3aXRoIG90aGVyIG9wZXJhdGlvbnMuICBFbGVtZW50cyBjb250YWluZWQgaW4gdGhlIHF1ZXVlIHNpbmNlIHRoZSBjcmVhdGlvbgorICogb2YgdGhlIGl0ZXJhdG9yIHdpbGwgYmUgcmV0dXJuZWQgZXhhY3RseSBvbmNlLgorICoKKyAqIDxwPkJld2FyZSB0aGF0LCB1bmxpa2UgaW4gbW9zdCBjb2xsZWN0aW9ucywgdGhlIHtAY29kZSBzaXplfSBtZXRob2QKKyAqIGlzIDxlbT5OT1Q8L2VtPiBhIGNvbnN0YW50LXRpbWUgb3BlcmF0aW9uLiBCZWNhdXNlIG9mIHRoZQorICogYXN5bmNocm9ub3VzIG5hdHVyZSBvZiB0aGVzZSBxdWV1ZXMsIGRldGVybWluaW5nIHRoZSBjdXJyZW50IG51bWJlcgorICogb2YgZWxlbWVudHMgcmVxdWlyZXMgYSB0cmF2ZXJzYWwgb2YgdGhlIGVsZW1lbnRzLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgYW5kIGl0cyBpdGVyYXRvciBpbXBsZW1lbnQgYWxsIG9mIHRoZSA8ZW0+b3B0aW9uYWw8L2VtPgorICogbWV0aG9kcyBvZiB0aGUge0BsaW5rIFF1ZXVlfSBhbmQge0BsaW5rIEl0ZXJhdG9yfSBpbnRlcmZhY2VzLgorICoKKyAqIDxwPk1lbW9yeSBjb25zaXN0ZW5jeSBlZmZlY3RzOiBBcyB3aXRoIG90aGVyIGNvbmN1cnJlbnQKKyAqIGNvbGxlY3Rpb25zLCBhY3Rpb25zIGluIGEgdGhyZWFkIHByaW9yIHRvIHBsYWNpbmcgYW4gb2JqZWN0IGludG8gYQorICoge0Bjb2RlIENvbmN1cnJlbnRMaW5rZWRRdWV1ZX0KKyAqIDxhIGhyZWY9InBhY2thZ2Utc3VtbWFyeS5odG1sI01lbW9yeVZpc2liaWxpdHkiPjxpPmhhcHBlbi1iZWZvcmU8L2k+PC9hPgorICogYWN0aW9ucyBzdWJzZXF1ZW50IHRvIHRoZSBhY2Nlc3Mgb3IgcmVtb3ZhbCBvZiB0aGF0IGVsZW1lbnQgZnJvbQorICogdGhlIHtAY29kZSBDb25jdXJyZW50TGlua2VkUXVldWV9IGluIGFub3RoZXIgdGhyZWFkLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqIEBwYXJhbSA8RT4gdGhlIHR5cGUgb2YgZWxlbWVudHMgaGVsZCBpbiB0aGlzIGNvbGxlY3Rpb24KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBDb25jdXJyZW50TGlua2VkUXVldWU8RT4gZXh0ZW5kcyBBYnN0cmFjdFF1ZXVlPEU+CisgICAgICAgIGltcGxlbWVudHMgUXVldWU8RT4sIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxOTY3NDU2OTMyNjc1MjE2NzZMOworCisgICAgLyoKKyAgICAgKiBUaGlzIGlzIGEgbW9kaWZpY2F0aW9uIG9mIHRoZSBNaWNoYWVsICYgU2NvdHQgYWxnb3JpdGhtLAorICAgICAqIGFkYXB0ZWQgZm9yIGEgZ2FyYmFnZS1jb2xsZWN0ZWQgZW52aXJvbm1lbnQsIHdpdGggc3VwcG9ydCBmb3IKKyAgICAgKiBpbnRlcmlvciBub2RlIGRlbGV0aW9uICh0byBzdXBwb3J0IHJlbW92ZShPYmplY3QpKS4gIEZvcgorICAgICAqIGV4cGxhbmF0aW9uLCByZWFkIHRoZSBwYXBlci4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCBsaWtlIG1vc3Qgbm9uLWJsb2NraW5nIGFsZ29yaXRobXMgaW4gdGhpcyBwYWNrYWdlLAorICAgICAqIHRoaXMgaW1wbGVtZW50YXRpb24gcmVsaWVzIG9uIHRoZSBmYWN0IHRoYXQgaW4gZ2FyYmFnZQorICAgICAqIGNvbGxlY3RlZCBzeXN0ZW1zLCB0aGVyZSBpcyBubyBwb3NzaWJpbGl0eSBvZiBBQkEgcHJvYmxlbXMgZHVlCisgICAgICogdG8gcmVjeWNsZWQgbm9kZXMsIHNvIHRoZXJlIGlzIG5vIG5lZWQgdG8gdXNlICJjb3VudGVkCisgICAgICogcG9pbnRlcnMiIG9yIHJlbGF0ZWQgdGVjaG5pcXVlcyBzZWVuIGluIHZlcnNpb25zIHVzZWQgaW4KKyAgICAgKiBub24tR0MnZWQgc2V0dGluZ3MuCisgICAgICoKKyAgICAgKiBUaGUgZnVuZGFtZW50YWwgaW52YXJpYW50cyBhcmU6CisgICAgICogLSBUaGVyZSBpcyBleGFjdGx5IG9uZSAobGFzdCkgTm9kZSB3aXRoIGEgbnVsbCBuZXh0IHJlZmVyZW5jZSwKKyAgICAgKiAgIHdoaWNoIGlzIENBU2VkIHdoZW4gZW5xdWV1ZWluZy4gIFRoaXMgbGFzdCBOb2RlIGNhbiBiZQorICAgICAqICAgcmVhY2hlZCBpbiBPKDEpIHRpbWUgZnJvbSB0YWlsLCBidXQgdGFpbCBpcyBtZXJlbHkgYW4KKyAgICAgKiAgIG9wdGltaXphdGlvbiAtIGl0IGNhbiBhbHdheXMgYmUgcmVhY2hlZCBpbiBPKE4pIHRpbWUgZnJvbQorICAgICAqICAgaGVhZCBhcyB3ZWxsLgorICAgICAqIC0gVGhlIGVsZW1lbnRzIGNvbnRhaW5lZCBpbiB0aGUgcXVldWUgYXJlIHRoZSBub24tbnVsbCBpdGVtcyBpbgorICAgICAqICAgTm9kZXMgdGhhdCBhcmUgcmVhY2hhYmxlIGZyb20gaGVhZC4gIENBU2luZyB0aGUgaXRlbQorICAgICAqICAgcmVmZXJlbmNlIG9mIGEgTm9kZSB0byBudWxsIGF0b21pY2FsbHkgcmVtb3ZlcyBpdCBmcm9tIHRoZQorICAgICAqICAgcXVldWUuICBSZWFjaGFiaWxpdHkgb2YgYWxsIGVsZW1lbnRzIGZyb20gaGVhZCBtdXN0IHJlbWFpbgorICAgICAqICAgdHJ1ZSBldmVuIGluIHRoZSBjYXNlIG9mIGNvbmN1cnJlbnQgbW9kaWZpY2F0aW9ucyB0aGF0IGNhdXNlCisgICAgICogICBoZWFkIHRvIGFkdmFuY2UuICBBIGRlcXVldWVkIE5vZGUgbWF5IHJlbWFpbiBpbiB1c2UKKyAgICAgKiAgIGluZGVmaW5pdGVseSBkdWUgdG8gY3JlYXRpb24gb2YgYW4gSXRlcmF0b3Igb3Igc2ltcGx5IGEKKyAgICAgKiAgIHBvbGwoKSB0aGF0IGhhcyBsb3N0IGl0cyB0aW1lIHNsaWNlLgorICAgICAqCisgICAgICogVGhlIGFib3ZlIG1pZ2h0IGFwcGVhciB0byBpbXBseSB0aGF0IGFsbCBOb2RlcyBhcmUgR0MtcmVhY2hhYmxlCisgICAgICogZnJvbSBhIHByZWRlY2Vzc29yIGRlcXVldWVkIE5vZGUuICBUaGF0IHdvdWxkIGNhdXNlIHR3byBwcm9ibGVtczoKKyAgICAgKiAtIGFsbG93IGEgcm9ndWUgSXRlcmF0b3IgdG8gY2F1c2UgdW5ib3VuZGVkIG1lbW9yeSByZXRlbnRpb24KKyAgICAgKiAtIGNhdXNlIGNyb3NzLWdlbmVyYXRpb25hbCBsaW5raW5nIG9mIG9sZCBOb2RlcyB0byBuZXcgTm9kZXMgaWYKKyAgICAgKiAgIGEgTm9kZSB3YXMgdGVudXJlZCB3aGlsZSBsaXZlLCB3aGljaCBnZW5lcmF0aW9uYWwgR0NzIGhhdmUgYQorICAgICAqICAgaGFyZCB0aW1lIGRlYWxpbmcgd2l0aCwgY2F1c2luZyByZXBlYXRlZCBtYWpvciBjb2xsZWN0aW9ucy4KKyAgICAgKiBIb3dldmVyLCBvbmx5IG5vbi1kZWxldGVkIE5vZGVzIG5lZWQgdG8gYmUgcmVhY2hhYmxlIGZyb20KKyAgICAgKiBkZXF1ZXVlZCBOb2RlcywgYW5kIHJlYWNoYWJpbGl0eSBkb2VzIG5vdCBuZWNlc3NhcmlseSBoYXZlIHRvCisgICAgICogYmUgb2YgdGhlIGtpbmQgdW5kZXJzdG9vZCBieSB0aGUgR0MuICBXZSB1c2UgdGhlIHRyaWNrIG9mCisgICAgICogbGlua2luZyBhIE5vZGUgdGhhdCBoYXMganVzdCBiZWVuIGRlcXVldWVkIHRvIGl0c2VsZi4gIFN1Y2ggYQorICAgICAqIHNlbGYtbGluayBpbXBsaWNpdGx5IG1lYW5zIHRvIGFkdmFuY2UgdG8gaGVhZC4KKyAgICAgKgorICAgICAqIEJvdGggaGVhZCBhbmQgdGFpbCBhcmUgcGVybWl0dGVkIHRvIGxhZy4gIEluIGZhY3QsIGZhaWxpbmcgdG8KKyAgICAgKiB1cGRhdGUgdGhlbSBldmVyeSB0aW1lIG9uZSBjb3VsZCBpcyBhIHNpZ25pZmljYW50IG9wdGltaXphdGlvbgorICAgICAqIChmZXdlciBDQVNlcykuIEFzIHdpdGggTGlua2VkVHJhbnNmZXJRdWV1ZSAoc2VlIHRoZSBpbnRlcm5hbAorICAgICAqIGRvY3VtZW50YXRpb24gZm9yIHRoYXQgY2xhc3MpLCB3ZSB1c2UgYSBzbGFjayB0aHJlc2hvbGQgb2YgdHdvOworICAgICAqIHRoYXQgaXMsIHdlIHVwZGF0ZSBoZWFkL3RhaWwgd2hlbiB0aGUgY3VycmVudCBwb2ludGVyIGFwcGVhcnMKKyAgICAgKiB0byBiZSB0d28gb3IgbW9yZSBzdGVwcyBhd2F5IGZyb20gdGhlIGZpcnN0L2xhc3Qgbm9kZS4KKyAgICAgKgorICAgICAqIFNpbmNlIGhlYWQgYW5kIHRhaWwgYXJlIHVwZGF0ZWQgY29uY3VycmVudGx5IGFuZCBpbmRlcGVuZGVudGx5LAorICAgICAqIGl0IGlzIHBvc3NpYmxlIGZvciB0YWlsIHRvIGxhZyBiZWhpbmQgaGVhZCAod2h5IG5vdCk/CisgICAgICoKKyAgICAgKiBDQVNpbmcgYSBOb2RlJ3MgaXRlbSByZWZlcmVuY2UgdG8gbnVsbCBhdG9taWNhbGx5IHJlbW92ZXMgdGhlCisgICAgICogZWxlbWVudCBmcm9tIHRoZSBxdWV1ZS4gIEl0ZXJhdG9ycyBza2lwIG92ZXIgTm9kZXMgd2l0aCBudWxsCisgICAgICogaXRlbXMuICBQcmlvciBpbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBjbGFzcyBoYWQgYSByYWNlIGJldHdlZW4KKyAgICAgKiBwb2xsKCkgYW5kIHJlbW92ZShPYmplY3QpIHdoZXJlIHRoZSBzYW1lIGVsZW1lbnQgd291bGQgYXBwZWFyCisgICAgICogdG8gYmUgc3VjY2Vzc2Z1bGx5IHJlbW92ZWQgYnkgdHdvIGNvbmN1cnJlbnQgb3BlcmF0aW9ucy4gIFRoZQorICAgICAqIG1ldGhvZCByZW1vdmUoT2JqZWN0KSBhbHNvIGxhemlseSB1bmxpbmtzIGRlbGV0ZWQgTm9kZXMsIGJ1dAorICAgICAqIHRoaXMgaXMgbWVyZWx5IGFuIG9wdGltaXphdGlvbi4KKyAgICAgKgorICAgICAqIFdoZW4gY29uc3RydWN0aW5nIGEgTm9kZSAoYmVmb3JlIGVucXVldWluZyBpdCkgd2UgYXZvaWQgcGF5aW5nCisgICAgICogZm9yIGEgdm9sYXRpbGUgd3JpdGUgdG8gaXRlbSBieSB1c2luZyBVbnNhZmUucHV0T2JqZWN0IGluc3RlYWQKKyAgICAgKiBvZiBhIG5vcm1hbCB3cml0ZS4gIFRoaXMgYWxsb3dzIHRoZSBjb3N0IG9mIGVucXVldWUgdG8gYmUKKyAgICAgKiAib25lLWFuZC1hLWhhbGYiIENBU2VzLgorICAgICAqCisgICAgICogQm90aCBoZWFkIGFuZCB0YWlsIG1heSBvciBtYXkgbm90IHBvaW50IHRvIGEgTm9kZSB3aXRoIGEKKyAgICAgKiBub24tbnVsbCBpdGVtLiAgSWYgdGhlIHF1ZXVlIGlzIGVtcHR5LCBhbGwgaXRlbXMgbXVzdCBvZiBjb3Vyc2UKKyAgICAgKiBiZSBudWxsLiAgVXBvbiBjcmVhdGlvbiwgYm90aCBoZWFkIGFuZCB0YWlsIHJlZmVyIHRvIGEgZHVtbXkKKyAgICAgKiBOb2RlIHdpdGggbnVsbCBpdGVtLiAgQm90aCBoZWFkIGFuZCB0YWlsIGFyZSBvbmx5IHVwZGF0ZWQgdXNpbmcKKyAgICAgKiBDQVMsIHNvIHRoZXkgbmV2ZXIgcmVncmVzcywgYWx0aG91Z2ggYWdhaW4gdGhpcyBpcyBtZXJlbHkgYW4KKyAgICAgKiBvcHRpbWl6YXRpb24uCisgICAgICovCisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBOb2RlPEU+IHsKKyAgICAgICAgdm9sYXRpbGUgRSBpdGVtOworICAgICAgICB2b2xhdGlsZSBOb2RlPEU+IG5leHQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgbm9kZS4gIFVzZXMgcmVsYXhlZCB3cml0ZSBiZWNhdXNlIGl0ZW0gY2FuCisgICAgICAgICAqIG9ubHkgYmUgc2VlbiBhZnRlciBwdWJsaWNhdGlvbiB2aWEgY2FzTmV4dC4KKyAgICAgICAgICovCisgICAgICAgIE5vZGUoRSBpdGVtKSB7CisgICAgICAgICAgICBVTlNBRkUucHV0T2JqZWN0KHRoaXMsIGl0ZW1PZmZzZXQsIGl0ZW0pOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBjYXNJdGVtKEUgY21wLCBFIHZhbCkgeworICAgICAgICAgICAgcmV0dXJuIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCBpdGVtT2Zmc2V0LCBjbXAsIHZhbCk7CisgICAgICAgIH0KKworICAgICAgICB2b2lkIGxhenlTZXROZXh0KE5vZGU8RT4gdmFsKSB7CisgICAgICAgICAgICBVTlNBRkUucHV0T3JkZXJlZE9iamVjdCh0aGlzLCBuZXh0T2Zmc2V0LCB2YWwpOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBjYXNOZXh0KE5vZGU8RT4gY21wLCBOb2RlPEU+IHZhbCkgeworICAgICAgICAgICAgcmV0dXJuIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCBuZXh0T2Zmc2V0LCBjbXAsIHZhbCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBVbnNhZmUgbWVjaGFuaWNzCisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgc3VuLm1pc2MuVW5zYWZlIFVOU0FGRSA9CisgICAgICAgICAgICBzdW4ubWlzYy5VbnNhZmUuZ2V0VW5zYWZlKCk7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgbmV4dE9mZnNldCA9CisgICAgICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJuZXh0IiwgTm9kZS5jbGFzcyk7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgaXRlbU9mZnNldCA9CisgICAgICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJpdGVtIiwgTm9kZS5jbGFzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBub2RlIGZyb20gd2hpY2ggdGhlIGZpcnN0IGxpdmUgKG5vbi1kZWxldGVkKSBub2RlIChpZiBhbnkpCisgICAgICogY2FuIGJlIHJlYWNoZWQgaW4gTygxKSB0aW1lLgorICAgICAqIEludmFyaWFudHM6CisgICAgICogLSBhbGwgbGl2ZSBub2RlcyBhcmUgcmVhY2hhYmxlIGZyb20gaGVhZCB2aWEgc3VjYygpCisgICAgICogLSBoZWFkICE9IG51bGwKKyAgICAgKiAtICh0bXAgPSBoZWFkKS5uZXh0ICE9IHRtcCB8fCB0bXAgIT0gaGVhZAorICAgICAqIE5vbi1pbnZhcmlhbnRzOgorICAgICAqIC0gaGVhZC5pdGVtIG1heSBvciBtYXkgbm90IGJlIG51bGwuCisgICAgICogLSBpdCBpcyBwZXJtaXR0ZWQgZm9yIHRhaWwgdG8gbGFnIGJlaGluZCBoZWFkLCB0aGF0IGlzLCBmb3IgdGFpbAorICAgICAqICAgdG8gbm90IGJlIHJlYWNoYWJsZSBmcm9tIGhlYWQhCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgdm9sYXRpbGUgTm9kZTxFPiBoZWFkOworCisgICAgLyoqCisgICAgICogQSBub2RlIGZyb20gd2hpY2ggdGhlIGxhc3Qgbm9kZSBvbiBsaXN0ICh0aGF0IGlzLCB0aGUgdW5pcXVlCisgICAgICogbm9kZSB3aXRoIG5vZGUubmV4dCA9PSBudWxsKSBjYW4gYmUgcmVhY2hlZCBpbiBPKDEpIHRpbWUuCisgICAgICogSW52YXJpYW50czoKKyAgICAgKiAtIHRoZSBsYXN0IG5vZGUgaXMgYWx3YXlzIHJlYWNoYWJsZSBmcm9tIHRhaWwgdmlhIHN1Y2MoKQorICAgICAqIC0gdGFpbCAhPSBudWxsCisgICAgICogTm9uLWludmFyaWFudHM6CisgICAgICogLSB0YWlsLml0ZW0gbWF5IG9yIG1heSBub3QgYmUgbnVsbC4KKyAgICAgKiAtIGl0IGlzIHBlcm1pdHRlZCBmb3IgdGFpbCB0byBsYWcgYmVoaW5kIGhlYWQsIHRoYXQgaXMsIGZvciB0YWlsCisgICAgICogICB0byBub3QgYmUgcmVhY2hhYmxlIGZyb20gaGVhZCEKKyAgICAgKiAtIHRhaWwubmV4dCBtYXkgb3IgbWF5IG5vdCBiZSBzZWxmLXBvaW50aW5nIHRvIHRhaWwuCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgdm9sYXRpbGUgTm9kZTxFPiB0YWlsOworCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIENvbmN1cnJlbnRMaW5rZWRRdWV1ZX0gdGhhdCBpcyBpbml0aWFsbHkgZW1wdHkuCisgICAgICovCisgICAgcHVibGljIENvbmN1cnJlbnRMaW5rZWRRdWV1ZSgpIHsKKyAgICAgICAgaGVhZCA9IHRhaWwgPSBuZXcgTm9kZTxFPihudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIENvbmN1cnJlbnRMaW5rZWRRdWV1ZX0KKyAgICAgKiBpbml0aWFsbHkgY29udGFpbmluZyB0aGUgZWxlbWVudHMgb2YgdGhlIGdpdmVuIGNvbGxlY3Rpb24sCisgICAgICogYWRkZWQgaW4gdHJhdmVyc2FsIG9yZGVyIG9mIHRoZSBjb2xsZWN0aW9uJ3MgaXRlcmF0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYyB0aGUgY29sbGVjdGlvbiBvZiBlbGVtZW50cyB0byBpbml0aWFsbHkgY29udGFpbgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIG9yIGFueQorICAgICAqICAgICAgICAgb2YgaXRzIGVsZW1lbnRzIGFyZSBudWxsCisgICAgICovCisgICAgcHVibGljIENvbmN1cnJlbnRMaW5rZWRRdWV1ZShDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjKSB7CisgICAgICAgIE5vZGU8RT4gaCA9IG51bGwsIHQgPSBudWxsOworICAgICAgICBmb3IgKEUgZSA6IGMpIHsKKyAgICAgICAgICAgIGNoZWNrTm90TnVsbChlKTsKKyAgICAgICAgICAgIE5vZGU8RT4gbmV3Tm9kZSA9IG5ldyBOb2RlPEU+KGUpOworICAgICAgICAgICAgaWYgKGggPT0gbnVsbCkKKyAgICAgICAgICAgICAgICBoID0gdCA9IG5ld05vZGU7CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICB0LmxhenlTZXROZXh0KG5ld05vZGUpOworICAgICAgICAgICAgICAgIHQgPSBuZXdOb2RlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChoID09IG51bGwpCisgICAgICAgICAgICBoID0gdCA9IG5ldyBOb2RlPEU+KG51bGwpOworICAgICAgICBoZWFkID0gaDsKKyAgICAgICAgdGFpbCA9IHQ7CisgICAgfQorCisgICAgLy8gSGF2ZSB0byBvdmVycmlkZSBqdXN0IHRvIHVwZGF0ZSB0aGUgamF2YWRvYworCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgYXQgdGhlIHRhaWwgb2YgdGhpcyBxdWV1ZS4KKyAgICAgKiBBcyB0aGUgcXVldWUgaXMgdW5ib3VuZGVkLCB0aGlzIG1ldGhvZCB3aWxsIG5ldmVyIHRocm93CisgICAgICoge0BsaW5rIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbn0gb3IgcmV0dXJuIHtAY29kZSBmYWxzZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSAoYXMgc3BlY2lmaWVkIGJ5IHtAbGluayBDb2xsZWN0aW9uI2FkZH0pCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGFkZChFIGUpIHsKKyAgICAgICAgcmV0dXJuIG9mZmVyKGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyeSB0byBDQVMgaGVhZCB0byBwLiBJZiBzdWNjZXNzZnVsLCByZXBvaW50IG9sZCBoZWFkIHRvIGl0c2VsZgorICAgICAqIGFzIHNlbnRpbmVsIGZvciBzdWNjKCksIGJlbG93LgorICAgICAqLworICAgIGZpbmFsIHZvaWQgdXBkYXRlSGVhZChOb2RlPEU+IGgsIE5vZGU8RT4gcCkgeworICAgICAgICBpZiAoaCAhPSBwICYmIGNhc0hlYWQoaCwgcCkpCisgICAgICAgICAgICBoLmxhenlTZXROZXh0KGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN1Y2Nlc3NvciBvZiBwLCBvciB0aGUgaGVhZCBub2RlIGlmIHAubmV4dCBoYXMgYmVlbgorICAgICAqIGxpbmtlZCB0byBzZWxmLCB3aGljaCB3aWxsIG9ubHkgYmUgdHJ1ZSBpZiB0cmF2ZXJzaW5nIHdpdGggYQorICAgICAqIHN0YWxlIHBvaW50ZXIgdGhhdCBpcyBub3cgb2ZmIHRoZSBsaXN0LgorICAgICAqLworICAgIGZpbmFsIE5vZGU8RT4gc3VjYyhOb2RlPEU+IHApIHsKKyAgICAgICAgTm9kZTxFPiBuZXh0ID0gcC5uZXh0OworICAgICAgICByZXR1cm4gKHAgPT0gbmV4dCkgPyBoZWFkIDogbmV4dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBhdCB0aGUgdGFpbCBvZiB0aGlzIHF1ZXVlLgorICAgICAqIEFzIHRoZSBxdWV1ZSBpcyB1bmJvdW5kZWQsIHRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIgcmV0dXJuIHtAY29kZSBmYWxzZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSAoYXMgc3BlY2lmaWVkIGJ5IHtAbGluayBRdWV1ZSNvZmZlcn0pCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG9mZmVyKEUgZSkgeworICAgICAgICBjaGVja05vdE51bGwoZSk7CisgICAgICAgIGZpbmFsIE5vZGU8RT4gbmV3Tm9kZSA9IG5ldyBOb2RlPEU+KGUpOworCisgICAgICAgIGZvciAoTm9kZTxFPiB0ID0gdGFpbCwgcCA9IHQ7OykgeworICAgICAgICAgICAgTm9kZTxFPiBxID0gcC5uZXh0OworICAgICAgICAgICAgaWYgKHEgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIHAgaXMgbGFzdCBub2RlCisgICAgICAgICAgICAgICAgaWYgKHAuY2FzTmV4dChudWxsLCBuZXdOb2RlKSkgeworICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzZnVsIENBUyBpcyB0aGUgbGluZWFyaXphdGlvbiBwb2ludAorICAgICAgICAgICAgICAgICAgICAvLyBmb3IgZSB0byBiZWNvbWUgYW4gZWxlbWVudCBvZiB0aGlzIHF1ZXVlLAorICAgICAgICAgICAgICAgICAgICAvLyBhbmQgZm9yIG5ld05vZGUgdG8gYmVjb21lICJsaXZlIi4KKyAgICAgICAgICAgICAgICAgICAgaWYgKHAgIT0gdCkgLy8gaG9wIHR3byBub2RlcyBhdCBhIHRpbWUKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc1RhaWwodCwgbmV3Tm9kZSk7ICAvLyBGYWlsdXJlIGlzIE9LLgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gTG9zdCBDQVMgcmFjZSB0byBhbm90aGVyIHRocmVhZDsgcmUtcmVhZCBuZXh0CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIGlmIChwID09IHEpCisgICAgICAgICAgICAgICAgLy8gV2UgaGF2ZSBmYWxsZW4gb2ZmIGxpc3QuICBJZiB0YWlsIGlzIHVuY2hhbmdlZCwgaXQKKyAgICAgICAgICAgICAgICAvLyB3aWxsIGFsc28gYmUgb2ZmLWxpc3QsIGluIHdoaWNoIGNhc2Ugd2UgbmVlZCB0bworICAgICAgICAgICAgICAgIC8vIGp1bXAgdG8gaGVhZCwgZnJvbSB3aGljaCBhbGwgbGl2ZSBub2RlcyBhcmUgYWx3YXlzCisgICAgICAgICAgICAgICAgLy8gcmVhY2hhYmxlLiAgRWxzZSB0aGUgbmV3IHRhaWwgaXMgYSBiZXR0ZXIgYmV0LgorICAgICAgICAgICAgICAgIHAgPSAodCAhPSAodCA9IHRhaWwpKSA/IHQgOiBoZWFkOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIC8vIENoZWNrIGZvciB0YWlsIHVwZGF0ZXMgYWZ0ZXIgdHdvIGhvcHMuCisgICAgICAgICAgICAgICAgcCA9IChwICE9IHQgJiYgdCAhPSAodCA9IHRhaWwpKSA/IHQgOiBxOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIEUgcG9sbCgpIHsKKyAgICAgICAgcmVzdGFydEZyb21IZWFkOgorICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBmb3IgKE5vZGU8RT4gaCA9IGhlYWQsIHAgPSBoLCBxOzspIHsKKyAgICAgICAgICAgICAgICBFIGl0ZW0gPSBwLml0ZW07CisKKyAgICAgICAgICAgICAgICBpZiAoaXRlbSAhPSBudWxsICYmIHAuY2FzSXRlbShpdGVtLCBudWxsKSkgeworICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzZnVsIENBUyBpcyB0aGUgbGluZWFyaXphdGlvbiBwb2ludAorICAgICAgICAgICAgICAgICAgICAvLyBmb3IgaXRlbSB0byBiZSByZW1vdmVkIGZyb20gdGhpcyBxdWV1ZS4KKyAgICAgICAgICAgICAgICAgICAgaWYgKHAgIT0gaCkgLy8gaG9wIHR3byBub2RlcyBhdCBhIHRpbWUKKyAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZUhlYWQoaCwgKChxID0gcC5uZXh0KSAhPSBudWxsKSA/IHEgOiBwKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UgaWYgKChxID0gcC5uZXh0KSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHVwZGF0ZUhlYWQoaCwgcCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbHNlIGlmIChwID09IHEpCisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHJlc3RhcnRGcm9tSGVhZDsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIHAgPSBxOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIEUgcGVlaygpIHsKKyAgICAgICAgcmVzdGFydEZyb21IZWFkOgorICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBmb3IgKE5vZGU8RT4gaCA9IGhlYWQsIHAgPSBoLCBxOzspIHsKKyAgICAgICAgICAgICAgICBFIGl0ZW0gPSBwLml0ZW07CisgICAgICAgICAgICAgICAgaWYgKGl0ZW0gIT0gbnVsbCB8fCAocSA9IHAubmV4dCkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB1cGRhdGVIZWFkKGgsIHApOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlbTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZSBpZiAocCA9PSBxKQorICAgICAgICAgICAgICAgICAgICBjb250aW51ZSByZXN0YXJ0RnJvbUhlYWQ7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBwID0gcTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZpcnN0IGxpdmUgKG5vbi1kZWxldGVkKSBub2RlIG9uIGxpc3QsIG9yIG51bGwgaWYgbm9uZS4KKyAgICAgKiBUaGlzIGlzIHlldCBhbm90aGVyIHZhcmlhbnQgb2YgcG9sbC9wZWVrOyBoZXJlIHJldHVybmluZyB0aGUKKyAgICAgKiBmaXJzdCBub2RlLCBub3QgZWxlbWVudC4gIFdlIGNvdWxkIG1ha2UgcGVlaygpIGEgd3JhcHBlciBhcm91bmQKKyAgICAgKiBmaXJzdCgpLCBidXQgdGhhdCB3b3VsZCBjb3N0IGFuIGV4dHJhIHZvbGF0aWxlIHJlYWQgb2YgaXRlbSwKKyAgICAgKiBhbmQgdGhlIG5lZWQgdG8gYWRkIGEgcmV0cnkgbG9vcCB0byBkZWFsIHdpdGggdGhlIHBvc3NpYmlsaXR5CisgICAgICogb2YgbG9zaW5nIGEgcmFjZSB0byBhIGNvbmN1cnJlbnQgcG9sbCgpLgorICAgICAqLworICAgIE5vZGU8RT4gZmlyc3QoKSB7CisgICAgICAgIHJlc3RhcnRGcm9tSGVhZDoKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgZm9yIChOb2RlPEU+IGggPSBoZWFkLCBwID0gaCwgcTs7KSB7CisgICAgICAgICAgICAgICAgYm9vbGVhbiBoYXNJdGVtID0gKHAuaXRlbSAhPSBudWxsKTsKKyAgICAgICAgICAgICAgICBpZiAoaGFzSXRlbSB8fCAocSA9IHAubmV4dCkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB1cGRhdGVIZWFkKGgsIHApOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gaGFzSXRlbSA/IHAgOiBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbHNlIGlmIChwID09IHEpCisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHJlc3RhcnRGcm9tSGVhZDsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIHAgPSBxOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBxdWV1ZSBjb250YWlucyBubyBlbGVtZW50cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgcXVldWUgY29udGFpbnMgbm8gZWxlbWVudHMKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICByZXR1cm4gZmlyc3QoKSA9PSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIHF1ZXVlLiAgSWYgdGhpcyBxdWV1ZQorICAgICAqIGNvbnRhaW5zIG1vcmUgdGhhbiB7QGNvZGUgSW50ZWdlci5NQVhfVkFMVUV9IGVsZW1lbnRzLCByZXR1cm5zCisgICAgICoge0Bjb2RlIEludGVnZXIuTUFYX1ZBTFVFfS4KKyAgICAgKgorICAgICAqIDxwPkJld2FyZSB0aGF0LCB1bmxpa2UgaW4gbW9zdCBjb2xsZWN0aW9ucywgdGhpcyBtZXRob2QgaXMKKyAgICAgKiA8ZW0+Tk9UPC9lbT4gYSBjb25zdGFudC10aW1lIG9wZXJhdGlvbi4gQmVjYXVzZSBvZiB0aGUKKyAgICAgKiBhc3luY2hyb25vdXMgbmF0dXJlIG9mIHRoZXNlIHF1ZXVlcywgZGV0ZXJtaW5pbmcgdGhlIGN1cnJlbnQKKyAgICAgKiBudW1iZXIgb2YgZWxlbWVudHMgcmVxdWlyZXMgYW4gTyhuKSB0cmF2ZXJzYWwuCisgICAgICogQWRkaXRpb25hbGx5LCBpZiBlbGVtZW50cyBhcmUgYWRkZWQgb3IgcmVtb3ZlZCBkdXJpbmcgZXhlY3V0aW9uCisgICAgICogb2YgdGhpcyBtZXRob2QsIHRoZSByZXR1cm5lZCByZXN1bHQgbWF5IGJlIGluYWNjdXJhdGUuICBUaHVzLAorICAgICAqIHRoaXMgbWV0aG9kIGlzIHR5cGljYWxseSBub3QgdmVyeSB1c2VmdWwgaW4gY29uY3VycmVudAorICAgICAqIGFwcGxpY2F0aW9ucy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIHF1ZXVlCisgICAgICovCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICBpbnQgY291bnQgPSAwOworICAgICAgICBmb3IgKE5vZGU8RT4gcCA9IGZpcnN0KCk7IHAgIT0gbnVsbDsgcCA9IHN1Y2MocCkpCisgICAgICAgICAgICBpZiAocC5pdGVtICE9IG51bGwpCisgICAgICAgICAgICAgICAgLy8gQ29sbGVjdGlvbi5zaXplKCkgc3BlYyBzYXlzIHRvIG1heCBvdXQKKyAgICAgICAgICAgICAgICBpZiAoKytjb3VudCA9PSBJbnRlZ2VyLk1BWF9WQUxVRSkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIHJldHVybiBjb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGlzIHF1ZXVlIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgZWxlbWVudC4KKyAgICAgKiBNb3JlIGZvcm1hbGx5LCByZXR1cm5zIHtAY29kZSB0cnVlfSBpZiBhbmQgb25seSBpZiB0aGlzIHF1ZXVlIGNvbnRhaW5zCisgICAgICogYXQgbGVhc3Qgb25lIGVsZW1lbnQge0Bjb2RlIGV9IHN1Y2ggdGhhdCB7QGNvZGUgby5lcXVhbHMoZSl9LgorICAgICAqCisgICAgICogQHBhcmFtIG8gb2JqZWN0IHRvIGJlIGNoZWNrZWQgZm9yIGNvbnRhaW5tZW50IGluIHRoaXMgcXVldWUKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHF1ZXVlIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvID09IG51bGwpIHJldHVybiBmYWxzZTsKKyAgICAgICAgZm9yIChOb2RlPEU+IHAgPSBmaXJzdCgpOyBwICE9IG51bGw7IHAgPSBzdWNjKHApKSB7CisgICAgICAgICAgICBFIGl0ZW0gPSBwLml0ZW07CisgICAgICAgICAgICBpZiAoaXRlbSAhPSBudWxsICYmIG8uZXF1YWxzKGl0ZW0pKQorICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGEgc2luZ2xlIGluc3RhbmNlIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBmcm9tIHRoaXMgcXVldWUsCisgICAgICogaWYgaXQgaXMgcHJlc2VudC4gIE1vcmUgZm9ybWFsbHksIHJlbW92ZXMgYW4gZWxlbWVudCB7QGNvZGUgZX0gc3VjaAorICAgICAqIHRoYXQge0Bjb2RlIG8uZXF1YWxzKGUpfSwgaWYgdGhpcyBxdWV1ZSBjb250YWlucyBvbmUgb3IgbW9yZSBzdWNoCisgICAgICogZWxlbWVudHMuCisgICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBxdWV1ZSBjb250YWluZWQgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICogKG9yIGVxdWl2YWxlbnRseSwgaWYgdGhpcyBxdWV1ZSBjaGFuZ2VkIGFzIGEgcmVzdWx0IG9mIHRoZSBjYWxsKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvIGVsZW1lbnQgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoaXMgcXVldWUsIGlmIHByZXNlbnQKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHF1ZXVlIGNoYW5nZWQgYXMgYSByZXN1bHQgb2YgdGhlIGNhbGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG8pIHsKKyAgICAgICAgaWYgKG8gPT0gbnVsbCkgcmV0dXJuIGZhbHNlOworICAgICAgICBOb2RlPEU+IHByZWQgPSBudWxsOworICAgICAgICBmb3IgKE5vZGU8RT4gcCA9IGZpcnN0KCk7IHAgIT0gbnVsbDsgcCA9IHN1Y2MocCkpIHsKKyAgICAgICAgICAgIEUgaXRlbSA9IHAuaXRlbTsKKyAgICAgICAgICAgIGlmIChpdGVtICE9IG51bGwgJiYKKyAgICAgICAgICAgICAgICBvLmVxdWFscyhpdGVtKSAmJgorICAgICAgICAgICAgICAgIHAuY2FzSXRlbShpdGVtLCBudWxsKSkgeworICAgICAgICAgICAgICAgIE5vZGU8RT4gbmV4dCA9IHN1Y2MocCk7CisgICAgICAgICAgICAgICAgaWYgKHByZWQgIT0gbnVsbCAmJiBuZXh0ICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIHByZWQuY2FzTmV4dChwLCBuZXh0KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHByZWQgPSBwOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIGFsbCBvZiB0aGUgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIHRvIHRoZSBlbmQgb2YKKyAgICAgKiB0aGlzIHF1ZXVlLCBpbiB0aGUgb3JkZXIgdGhhdCB0aGV5IGFyZSByZXR1cm5lZCBieSB0aGUgc3BlY2lmaWVkCisgICAgICogY29sbGVjdGlvbidzIGl0ZXJhdG9yLiAgQXR0ZW1wdHMgdG8ge0Bjb2RlIGFkZEFsbH0gb2YgYSBxdWV1ZSB0bworICAgICAqIGl0c2VsZiByZXN1bHQgaW4ge0Bjb2RlIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYyB0aGUgZWxlbWVudHMgdG8gYmUgaW5zZXJ0ZWQgaW50byB0aGlzIHF1ZXVlCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBxdWV1ZSBjaGFuZ2VkIGFzIGEgcmVzdWx0IG9mIHRoZSBjYWxsCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gb3IgYW55CisgICAgICogICAgICAgICBvZiBpdHMgZWxlbWVudHMgYXJlIG51bGwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgY29sbGVjdGlvbiBpcyB0aGlzIHF1ZXVlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYWRkQWxsKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGMpIHsKKyAgICAgICAgaWYgKGMgPT0gdGhpcykKKyAgICAgICAgICAgIC8vIEFzIGhpc3RvcmljYWxseSBzcGVjaWZpZWQgaW4gQWJzdHJhY3RRdWV1ZSNhZGRBbGwKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKworICAgICAgICAvLyBDb3B5IGMgaW50byBhIHByaXZhdGUgY2hhaW4gb2YgTm9kZXMKKyAgICAgICAgTm9kZTxFPiBiZWdpbm5pbmdPZlRoZUVuZCA9IG51bGwsIGxhc3QgPSBudWxsOworICAgICAgICBmb3IgKEUgZSA6IGMpIHsKKyAgICAgICAgICAgIGNoZWNrTm90TnVsbChlKTsKKyAgICAgICAgICAgIE5vZGU8RT4gbmV3Tm9kZSA9IG5ldyBOb2RlPEU+KGUpOworICAgICAgICAgICAgaWYgKGJlZ2lubmluZ09mVGhlRW5kID09IG51bGwpCisgICAgICAgICAgICAgICAgYmVnaW5uaW5nT2ZUaGVFbmQgPSBsYXN0ID0gbmV3Tm9kZTsKKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIGxhc3QubGF6eVNldE5leHQobmV3Tm9kZSk7CisgICAgICAgICAgICAgICAgbGFzdCA9IG5ld05vZGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJlZ2lubmluZ09mVGhlRW5kID09IG51bGwpCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgICAgLy8gQXRvbWljYWxseSBhcHBlbmQgdGhlIGNoYWluIGF0IHRoZSB0YWlsIG9mIHRoaXMgY29sbGVjdGlvbgorICAgICAgICBmb3IgKE5vZGU8RT4gdCA9IHRhaWwsIHAgPSB0OzspIHsKKyAgICAgICAgICAgIE5vZGU8RT4gcSA9IHAubmV4dDsKKyAgICAgICAgICAgIGlmIChxID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyBwIGlzIGxhc3Qgbm9kZQorICAgICAgICAgICAgICAgIGlmIChwLmNhc05leHQobnVsbCwgYmVnaW5uaW5nT2ZUaGVFbmQpKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFN1Y2Nlc3NmdWwgQ0FTIGlzIHRoZSBsaW5lYXJpemF0aW9uIHBvaW50CisgICAgICAgICAgICAgICAgICAgIC8vIGZvciBhbGwgZWxlbWVudHMgdG8gYmUgYWRkZWQgdG8gdGhpcyBxdWV1ZS4KKyAgICAgICAgICAgICAgICAgICAgaWYgKCFjYXNUYWlsKHQsIGxhc3QpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBUcnkgYSBsaXR0bGUgaGFyZGVyIHRvIHVwZGF0ZSB0YWlsLAorICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2luY2Ugd2UgbWF5IGJlIGFkZGluZyBtYW55IGVsZW1lbnRzLgorICAgICAgICAgICAgICAgICAgICAgICAgdCA9IHRhaWw7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGFzdC5uZXh0ID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzVGFpbCh0LCBsYXN0KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gTG9zdCBDQVMgcmFjZSB0byBhbm90aGVyIHRocmVhZDsgcmUtcmVhZCBuZXh0CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIGlmIChwID09IHEpCisgICAgICAgICAgICAgICAgLy8gV2UgaGF2ZSBmYWxsZW4gb2ZmIGxpc3QuICBJZiB0YWlsIGlzIHVuY2hhbmdlZCwgaXQKKyAgICAgICAgICAgICAgICAvLyB3aWxsIGFsc28gYmUgb2ZmLWxpc3QsIGluIHdoaWNoIGNhc2Ugd2UgbmVlZCB0bworICAgICAgICAgICAgICAgIC8vIGp1bXAgdG8gaGVhZCwgZnJvbSB3aGljaCBhbGwgbGl2ZSBub2RlcyBhcmUgYWx3YXlzCisgICAgICAgICAgICAgICAgLy8gcmVhY2hhYmxlLiAgRWxzZSB0aGUgbmV3IHRhaWwgaXMgYSBiZXR0ZXIgYmV0LgorICAgICAgICAgICAgICAgIHAgPSAodCAhPSAodCA9IHRhaWwpKSA/IHQgOiBoZWFkOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIC8vIENoZWNrIGZvciB0YWlsIHVwZGF0ZXMgYWZ0ZXIgdHdvIGhvcHMuCisgICAgICAgICAgICAgICAgcCA9IChwICE9IHQgJiYgdCAhPSAodCA9IHRhaWwpKSA/IHQgOiBxOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIGFsbCBvZiB0aGUgZWxlbWVudHMgaW4gdGhpcyBxdWV1ZSwgaW4KKyAgICAgKiBwcm9wZXIgc2VxdWVuY2UuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQgYXJyYXkgd2lsbCBiZSAic2FmZSIgaW4gdGhhdCBubyByZWZlcmVuY2VzIHRvIGl0IGFyZQorICAgICAqIG1haW50YWluZWQgYnkgdGhpcyBxdWV1ZS4gIChJbiBvdGhlciB3b3JkcywgdGhpcyBtZXRob2QgbXVzdCBhbGxvY2F0ZQorICAgICAqIGEgbmV3IGFycmF5KS4gIFRoZSBjYWxsZXIgaXMgdGh1cyBmcmVlIHRvIG1vZGlmeSB0aGUgcmV0dXJuZWQgYXJyYXkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBhY3RzIGFzIGJyaWRnZSBiZXR3ZWVuIGFycmF5LWJhc2VkIGFuZCBjb2xsZWN0aW9uLWJhc2VkCisgICAgICogQVBJcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoaXMgcXVldWUKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKKyAgICAgICAgLy8gVXNlIEFycmF5TGlzdCB0byBkZWFsIHdpdGggcmVzaXppbmcuCisgICAgICAgIEFycmF5TGlzdDxFPiBhbCA9IG5ldyBBcnJheUxpc3Q8RT4oKTsKKyAgICAgICAgZm9yIChOb2RlPEU+IHAgPSBmaXJzdCgpOyBwICE9IG51bGw7IHAgPSBzdWNjKHApKSB7CisgICAgICAgICAgICBFIGl0ZW0gPSBwLml0ZW07CisgICAgICAgICAgICBpZiAoaXRlbSAhPSBudWxsKQorICAgICAgICAgICAgICAgIGFsLmFkZChpdGVtKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYWwudG9BcnJheSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoaXMgcXVldWUsIGluCisgICAgICogcHJvcGVyIHNlcXVlbmNlOyB0aGUgcnVudGltZSB0eXBlIG9mIHRoZSByZXR1cm5lZCBhcnJheSBpcyB0aGF0IG9mCisgICAgICogdGhlIHNwZWNpZmllZCBhcnJheS4gIElmIHRoZSBxdWV1ZSBmaXRzIGluIHRoZSBzcGVjaWZpZWQgYXJyYXksIGl0CisgICAgICogaXMgcmV0dXJuZWQgdGhlcmVpbi4gIE90aGVyd2lzZSwgYSBuZXcgYXJyYXkgaXMgYWxsb2NhdGVkIHdpdGggdGhlCisgICAgICogcnVudGltZSB0eXBlIG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkgYW5kIHRoZSBzaXplIG9mIHRoaXMgcXVldWUuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGlzIHF1ZXVlIGZpdHMgaW4gdGhlIHNwZWNpZmllZCBhcnJheSB3aXRoIHJvb20gdG8gc3BhcmUKKyAgICAgKiAoaS5lLiwgdGhlIGFycmF5IGhhcyBtb3JlIGVsZW1lbnRzIHRoYW4gdGhpcyBxdWV1ZSksIHRoZSBlbGVtZW50IGluCisgICAgICogdGhlIGFycmF5IGltbWVkaWF0ZWx5IGZvbGxvd2luZyB0aGUgZW5kIG9mIHRoZSBxdWV1ZSBpcyBzZXQgdG8KKyAgICAgKiB7QGNvZGUgbnVsbH0uCisgICAgICoKKyAgICAgKiA8cD5MaWtlIHRoZSB7QGxpbmsgI3RvQXJyYXkoKX0gbWV0aG9kLCB0aGlzIG1ldGhvZCBhY3RzIGFzIGJyaWRnZSBiZXR3ZWVuCisgICAgICogYXJyYXktYmFzZWQgYW5kIGNvbGxlY3Rpb24tYmFzZWQgQVBJcy4gIEZ1cnRoZXIsIHRoaXMgbWV0aG9kIGFsbG93cworICAgICAqIHByZWNpc2UgY29udHJvbCBvdmVyIHRoZSBydW50aW1lIHR5cGUgb2YgdGhlIG91dHB1dCBhcnJheSwgYW5kIG1heSwKKyAgICAgKiB1bmRlciBjZXJ0YWluIGNpcmN1bXN0YW5jZXMsIGJlIHVzZWQgdG8gc2F2ZSBhbGxvY2F0aW9uIGNvc3RzLgorICAgICAqCisgICAgICogPHA+U3VwcG9zZSB7QGNvZGUgeH0gaXMgYSBxdWV1ZSBrbm93biB0byBjb250YWluIG9ubHkgc3RyaW5ncy4KKyAgICAgKiBUaGUgZm9sbG93aW5nIGNvZGUgY2FuIGJlIHVzZWQgdG8gZHVtcCB0aGUgcXVldWUgaW50byBhIG5ld2x5CisgICAgICogYWxsb2NhdGVkIGFycmF5IG9mIHtAY29kZSBTdHJpbmd9OgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiAgICAgU3RyaW5nW10geSA9IHgudG9BcnJheShuZXcgU3RyaW5nWzBdKTs8L3ByZT4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCB7QGNvZGUgdG9BcnJheShuZXcgT2JqZWN0WzBdKX0gaXMgaWRlbnRpY2FsIGluIGZ1bmN0aW9uIHRvCisgICAgICoge0Bjb2RlIHRvQXJyYXkoKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgaW50byB3aGljaCB0aGUgZWxlbWVudHMgb2YgdGhlIHF1ZXVlIGFyZSB0bworICAgICAqICAgICAgICAgIGJlIHN0b3JlZCwgaWYgaXQgaXMgYmlnIGVub3VnaDsgb3RoZXJ3aXNlLCBhIG5ldyBhcnJheSBvZiB0aGUKKyAgICAgKiAgICAgICAgICBzYW1lIHJ1bnRpbWUgdHlwZSBpcyBhbGxvY2F0ZWQgZm9yIHRoaXMgcHVycG9zZQorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoaXMgcXVldWUKKyAgICAgKiBAdGhyb3dzIEFycmF5U3RvcmVFeGNlcHRpb24gaWYgdGhlIHJ1bnRpbWUgdHlwZSBvZiB0aGUgc3BlY2lmaWVkIGFycmF5CisgICAgICogICAgICAgICBpcyBub3QgYSBzdXBlcnR5cGUgb2YgdGhlIHJ1bnRpbWUgdHlwZSBvZiBldmVyeSBlbGVtZW50IGluCisgICAgICogICAgICAgICB0aGlzIHF1ZXVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGFycmF5IGlzIG51bGwKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgPFQ+IFRbXSB0b0FycmF5KFRbXSBhKSB7CisgICAgICAgIC8vIHRyeSB0byB1c2Ugc2VudC1pbiBhcnJheQorICAgICAgICBpbnQgayA9IDA7CisgICAgICAgIE5vZGU8RT4gcDsKKyAgICAgICAgZm9yIChwID0gZmlyc3QoKTsgcCAhPSBudWxsICYmIGsgPCBhLmxlbmd0aDsgcCA9IHN1Y2MocCkpIHsKKyAgICAgICAgICAgIEUgaXRlbSA9IHAuaXRlbTsKKyAgICAgICAgICAgIGlmIChpdGVtICE9IG51bGwpCisgICAgICAgICAgICAgICAgYVtrKytdID0gKFQpaXRlbTsKKyAgICAgICAgfQorICAgICAgICBpZiAocCA9PSBudWxsKSB7CisgICAgICAgICAgICBpZiAoayA8IGEubGVuZ3RoKQorICAgICAgICAgICAgICAgIGFba10gPSBudWxsOworICAgICAgICAgICAgcmV0dXJuIGE7CisgICAgICAgIH0KKworICAgICAgICAvLyBJZiB3b24ndCBmaXQsIHVzZSBBcnJheUxpc3QgdmVyc2lvbgorICAgICAgICBBcnJheUxpc3Q8RT4gYWwgPSBuZXcgQXJyYXlMaXN0PEU+KCk7CisgICAgICAgIGZvciAoTm9kZTxFPiBxID0gZmlyc3QoKTsgcSAhPSBudWxsOyBxID0gc3VjYyhxKSkgeworICAgICAgICAgICAgRSBpdGVtID0gcS5pdGVtOworICAgICAgICAgICAgaWYgKGl0ZW0gIT0gbnVsbCkKKyAgICAgICAgICAgICAgICBhbC5hZGQoaXRlbSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGFsLnRvQXJyYXkoYSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cyBpbiB0aGlzIHF1ZXVlIGluIHByb3BlciBzZXF1ZW5jZS4KKyAgICAgKiBUaGUgZWxlbWVudHMgd2lsbCBiZSByZXR1cm5lZCBpbiBvcmRlciBmcm9tIGZpcnN0IChoZWFkKSB0byBsYXN0ICh0YWlsKS4KKyAgICAgKgorICAgICAqIDxwPlRoZSByZXR1cm5lZCBpdGVyYXRvciBpcyBhICJ3ZWFrbHkgY29uc2lzdGVudCIgaXRlcmF0b3IgdGhhdAorICAgICAqIHdpbGwgbmV2ZXIgdGhyb3cge0BsaW5rIGphdmEudXRpbC5Db25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uCisgICAgICogQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0sIGFuZCBndWFyYW50ZWVzIHRvIHRyYXZlcnNlCisgICAgICogZWxlbWVudHMgYXMgdGhleSBleGlzdGVkIHVwb24gY29uc3RydWN0aW9uIG9mIHRoZSBpdGVyYXRvciwgYW5kCisgICAgICogbWF5IChidXQgaXMgbm90IGd1YXJhbnRlZWQgdG8pIHJlZmxlY3QgYW55IG1vZGlmaWNhdGlvbnMKKyAgICAgKiBzdWJzZXF1ZW50IHRvIGNvbnN0cnVjdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMgaW4gdGhpcyBxdWV1ZSBpbiBwcm9wZXIgc2VxdWVuY2UKKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3I8RT4gaXRlcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBuZXcgSXRyKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBJdHIgaW1wbGVtZW50cyBJdGVyYXRvcjxFPiB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBOZXh0IG5vZGUgdG8gcmV0dXJuIGl0ZW0gZm9yLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBOb2RlPEU+IG5leHROb2RlOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBuZXh0SXRlbSBob2xkcyBvbiB0byBpdGVtIGZpZWxkcyBiZWNhdXNlIG9uY2Ugd2UgY2xhaW0KKyAgICAgICAgICogdGhhdCBhbiBlbGVtZW50IGV4aXN0cyBpbiBoYXNOZXh0KCksIHdlIG11c3QgcmV0dXJuIGl0IGluCisgICAgICAgICAqIHRoZSBmb2xsb3dpbmcgbmV4dCgpIGNhbGwgZXZlbiBpZiBpdCB3YXMgaW4gdGhlIHByb2Nlc3Mgb2YKKyAgICAgICAgICogYmVpbmcgcmVtb3ZlZCB3aGVuIGhhc05leHQoKSB3YXMgY2FsbGVkLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBFIG5leHRJdGVtOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBOb2RlIG9mIHRoZSBsYXN0IHJldHVybmVkIGl0ZW0sIHRvIHN1cHBvcnQgcmVtb3ZlLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBOb2RlPEU+IGxhc3RSZXQ7CisKKyAgICAgICAgSXRyKCkgeworICAgICAgICAgICAgYWR2YW5jZSgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE1vdmVzIHRvIG5leHQgdmFsaWQgbm9kZSBhbmQgcmV0dXJucyBpdGVtIHRvIHJldHVybiBmb3IKKyAgICAgICAgICogbmV4dCgpLCBvciBudWxsIGlmIG5vIHN1Y2guCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIEUgYWR2YW5jZSgpIHsKKyAgICAgICAgICAgIGxhc3RSZXQgPSBuZXh0Tm9kZTsKKyAgICAgICAgICAgIEUgeCA9IG5leHRJdGVtOworCisgICAgICAgICAgICBOb2RlPEU+IHByZWQsIHA7CisgICAgICAgICAgICBpZiAobmV4dE5vZGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHAgPSBmaXJzdCgpOworICAgICAgICAgICAgICAgIHByZWQgPSBudWxsOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBwcmVkID0gbmV4dE5vZGU7CisgICAgICAgICAgICAgICAgcCA9IHN1Y2MobmV4dE5vZGUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgaWYgKHAgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBuZXh0Tm9kZSA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgIG5leHRJdGVtID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHg7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIEUgaXRlbSA9IHAuaXRlbTsKKyAgICAgICAgICAgICAgICBpZiAoaXRlbSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIG5leHROb2RlID0gcDsKKyAgICAgICAgICAgICAgICAgICAgbmV4dEl0ZW0gPSBpdGVtOworICAgICAgICAgICAgICAgICAgICByZXR1cm4geDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAvLyBza2lwIG92ZXIgbnVsbHMKKyAgICAgICAgICAgICAgICAgICAgTm9kZTxFPiBuZXh0ID0gc3VjYyhwKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHByZWQgIT0gbnVsbCAmJiBuZXh0ICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgICAgICBwcmVkLmNhc05leHQocCwgbmV4dCk7CisgICAgICAgICAgICAgICAgICAgIHAgPSBuZXh0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV4dE5vZGUgIT0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFIG5leHQoKSB7CisgICAgICAgICAgICBpZiAobmV4dE5vZGUgPT0gbnVsbCkgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIHJldHVybiBhZHZhbmNlKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICBOb2RlPEU+IGwgPSBsYXN0UmV0OworICAgICAgICAgICAgaWYgKGwgPT0gbnVsbCkgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgLy8gcmVseSBvbiBhIGZ1dHVyZSB0cmF2ZXJzYWwgdG8gcmVsaW5rLgorICAgICAgICAgICAgbC5pdGVtID0gbnVsbDsKKyAgICAgICAgICAgIGxhc3RSZXQgPSBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2F2ZXMgdGhlIHN0YXRlIHRvIGEgc3RyZWFtICh0aGF0IGlzLCBzZXJpYWxpemVzIGl0KS4KKyAgICAgKgorICAgICAqIEBzZXJpYWxEYXRhIEFsbCBvZiB0aGUgZWxlbWVudHMgKGVhY2ggYW4ge0Bjb2RlIEV9KSBpbgorICAgICAqIHRoZSBwcm9wZXIgb3JkZXIsIGZvbGxvd2VkIGJ5IGEgbnVsbAorICAgICAqIEBwYXJhbSBzIHRoZSBzdHJlYW0KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW0gcykKKyAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24geworCisgICAgICAgIC8vIFdyaXRlIG91dCBhbnkgaGlkZGVuIHN0dWZmCisgICAgICAgIHMuZGVmYXVsdFdyaXRlT2JqZWN0KCk7CisKKyAgICAgICAgLy8gV3JpdGUgb3V0IGFsbCBlbGVtZW50cyBpbiB0aGUgcHJvcGVyIG9yZGVyLgorICAgICAgICBmb3IgKE5vZGU8RT4gcCA9IGZpcnN0KCk7IHAgIT0gbnVsbDsgcCA9IHN1Y2MocCkpIHsKKyAgICAgICAgICAgIE9iamVjdCBpdGVtID0gcC5pdGVtOworICAgICAgICAgICAgaWYgKGl0ZW0gIT0gbnVsbCkKKyAgICAgICAgICAgICAgICBzLndyaXRlT2JqZWN0KGl0ZW0pOworICAgICAgICB9CisKKyAgICAgICAgLy8gVXNlIHRyYWlsaW5nIG51bGwgYXMgc2VudGluZWwKKyAgICAgICAgcy53cml0ZU9iamVjdChudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWNvbnN0aXR1dGVzIHRoZSBpbnN0YW5jZSBmcm9tIGEgc3RyZWFtICh0aGF0IGlzLCBkZXNlcmlhbGl6ZXMgaXQpLgorICAgICAqIEBwYXJhbSBzIHRoZSBzdHJlYW0KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtIHMpCisgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgcy5kZWZhdWx0UmVhZE9iamVjdCgpOworCisgICAgICAgIC8vIFJlYWQgaW4gZWxlbWVudHMgdW50aWwgdHJhaWxpbmcgbnVsbCBzZW50aW5lbCBmb3VuZAorICAgICAgICBOb2RlPEU+IGggPSBudWxsLCB0ID0gbnVsbDsKKyAgICAgICAgT2JqZWN0IGl0ZW07CisgICAgICAgIHdoaWxlICgoaXRlbSA9IHMucmVhZE9iamVjdCgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgICAgIE5vZGU8RT4gbmV3Tm9kZSA9IG5ldyBOb2RlPEU+KChFKSBpdGVtKTsKKyAgICAgICAgICAgIGlmIChoID09IG51bGwpCisgICAgICAgICAgICAgICAgaCA9IHQgPSBuZXdOb2RlOworICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgdC5sYXp5U2V0TmV4dChuZXdOb2RlKTsKKyAgICAgICAgICAgICAgICB0ID0gbmV3Tm9kZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoaCA9PSBudWxsKQorICAgICAgICAgICAgaCA9IHQgPSBuZXcgTm9kZTxFPihudWxsKTsKKyAgICAgICAgaGVhZCA9IGg7CisgICAgICAgIHRhaWwgPSB0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBhcmd1bWVudCBpcyBudWxsLgorICAgICAqCisgICAgICogQHBhcmFtIHYgdGhlIGVsZW1lbnQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNoZWNrTm90TnVsbChPYmplY3QgdikgeworICAgICAgICBpZiAodiA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLy8gVW5zYWZlIG1lY2hhbmljcworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgc3VuLm1pc2MuVW5zYWZlIFVOU0FGRSA9IHN1bi5taXNjLlVuc2FmZS5nZXRVbnNhZmUoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIGhlYWRPZmZzZXQgPQorICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJoZWFkIiwgQ29uY3VycmVudExpbmtlZFF1ZXVlLmNsYXNzKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHRhaWxPZmZzZXQgPQorICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJ0YWlsIiwgQ29uY3VycmVudExpbmtlZFF1ZXVlLmNsYXNzKTsKKworICAgIHByaXZhdGUgYm9vbGVhbiBjYXNUYWlsKE5vZGU8RT4gY21wLCBOb2RlPEU+IHZhbCkgeworICAgICAgICByZXR1cm4gVU5TQUZFLmNvbXBhcmVBbmRTd2FwT2JqZWN0KHRoaXMsIHRhaWxPZmZzZXQsIGNtcCwgdmFsKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gY2FzSGVhZChOb2RlPEU+IGNtcCwgTm9kZTxFPiB2YWwpIHsKKyAgICAgICAgcmV0dXJuIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCBoZWFkT2Zmc2V0LCBjbXAsIHZhbCk7CisgICAgfQorCisgICAgc3RhdGljIGxvbmcgb2JqZWN0RmllbGRPZmZzZXQoc3VuLm1pc2MuVW5zYWZlIFVOU0FGRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZmllbGQsIENsYXNzPD8+IGtsYXp6KSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gVU5TQUZFLm9iamVjdEZpZWxkT2Zmc2V0KGtsYXp6LmdldERlY2xhcmVkRmllbGQoZmllbGQpKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRmllbGRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29udmVydCBFeGNlcHRpb24gdG8gY29ycmVzcG9uZGluZyBFcnJvcgorICAgICAgICAgICAgTm9TdWNoRmllbGRFcnJvciBlcnJvciA9IG5ldyBOb1N1Y2hGaWVsZEVycm9yKGZpZWxkKTsKKyAgICAgICAgICAgIGVycm9yLmluaXRDYXVzZShlKTsKKyAgICAgICAgICAgIHRocm93IGVycm9yOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0NvbmN1cnJlbnRNYXAuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Db25jdXJyZW50TWFwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmRhZWJjNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Db25jdXJyZW50TWFwLmphdmEKQEAgLTAsMCArMSwxMzQgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCisvLyBCRUdJTiBhbmRyb2lkLW5vdGUKKy8vIHJlbW92ZWQgbGluayB0byBjb2xsZWN0aW9ucyBmcmFtZXdvcmsgZG9jcworLy8gRU5EIGFuZHJvaWQtbm90ZQorCisvKioKKyAqIEEge0BsaW5rIGphdmEudXRpbC5NYXB9IHByb3ZpZGluZyBhZGRpdGlvbmFsIGF0b21pYworICogPHR0PnB1dElmQWJzZW50PC90dD4sIDx0dD5yZW1vdmU8L3R0PiwgYW5kIDx0dD5yZXBsYWNlPC90dD4gbWV0aG9kcy4KKyAqCisgKiA8cD5NZW1vcnkgY29uc2lzdGVuY3kgZWZmZWN0czogQXMgd2l0aCBvdGhlciBjb25jdXJyZW50CisgKiBjb2xsZWN0aW9ucywgYWN0aW9ucyBpbiBhIHRocmVhZCBwcmlvciB0byBwbGFjaW5nIGFuIG9iamVjdCBpbnRvIGEKKyAqIHtAY29kZSBDb25jdXJyZW50TWFwfSBhcyBhIGtleSBvciB2YWx1ZQorICogPGEgaHJlZj0icGFja2FnZS1zdW1tYXJ5Lmh0bWwjTWVtb3J5VmlzaWJpbGl0eSI+PGk+aGFwcGVuLWJlZm9yZTwvaT48L2E+CisgKiBhY3Rpb25zIHN1YnNlcXVlbnQgdG8gdGhlIGFjY2VzcyBvciByZW1vdmFsIG9mIHRoYXQgb2JqZWN0IGZyb20KKyAqIHRoZSB7QGNvZGUgQ29uY3VycmVudE1hcH0gaW4gYW5vdGhlciB0aHJlYWQuCisgKgorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICogQHBhcmFtIDxLPiB0aGUgdHlwZSBvZiBrZXlzIG1haW50YWluZWQgYnkgdGhpcyBtYXAKKyAqIEBwYXJhbSA8Vj4gdGhlIHR5cGUgb2YgbWFwcGVkIHZhbHVlcworICovCitwdWJsaWMgaW50ZXJmYWNlIENvbmN1cnJlbnRNYXA8SywgVj4gZXh0ZW5kcyBNYXA8SywgVj4geworICAgIC8qKgorICAgICAqIElmIHRoZSBzcGVjaWZpZWQga2V5IGlzIG5vdCBhbHJlYWR5IGFzc29jaWF0ZWQKKyAgICAgKiB3aXRoIGEgdmFsdWUsIGFzc29jaWF0ZSBpdCB3aXRoIHRoZSBnaXZlbiB2YWx1ZS4KKyAgICAgKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8KKyAgICAgKiA8cHJlPgorICAgICAqICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkKKyAgICAgKiAgICAgICByZXR1cm4gbWFwLnB1dChrZXksIHZhbHVlKTsKKyAgICAgKiAgIGVsc2UKKyAgICAgKiAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOzwvcHJlPgorICAgICAqIGV4Y2VwdCB0aGF0IHRoZSBhY3Rpb24gaXMgcGVyZm9ybWVkIGF0b21pY2FsbHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5IGtleSB3aXRoIHdoaWNoIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgdG8gYmUgYXNzb2NpYXRlZAorICAgICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSB0byBiZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBrZXkKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBrZXksIG9yCisgICAgICogICAgICAgICA8dHQ+bnVsbDwvdHQ+IGlmIHRoZXJlIHdhcyBubyBtYXBwaW5nIGZvciB0aGUga2V5LgorICAgICAqICAgICAgICAgKEEgPHR0Pm51bGw8L3R0PiByZXR1cm4gY2FuIGFsc28gaW5kaWNhdGUgdGhhdCB0aGUgbWFwCisgICAgICogICAgICAgICBwcmV2aW91c2x5IGFzc29jaWF0ZWQgPHR0Pm51bGw8L3R0PiB3aXRoIHRoZSBrZXksCisgICAgICogICAgICAgICBpZiB0aGUgaW1wbGVtZW50YXRpb24gc3VwcG9ydHMgbnVsbCB2YWx1ZXMuKQorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhlIDx0dD5wdXQ8L3R0PiBvcGVyYXRpb24KKyAgICAgKiAgICAgICAgIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBtYXAKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3Mgb2YgdGhlIHNwZWNpZmllZCBrZXkgb3IgdmFsdWUKKyAgICAgKiAgICAgICAgIHByZXZlbnRzIGl0IGZyb20gYmVpbmcgc3RvcmVkIGluIHRoaXMgbWFwCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBvciB2YWx1ZSBpcyBudWxsLAorICAgICAqICAgICAgICAgYW5kIHRoaXMgbWFwIGRvZXMgbm90IHBlcm1pdCBudWxsIGtleXMgb3IgdmFsdWVzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc29tZSBwcm9wZXJ0eSBvZiB0aGUgc3BlY2lmaWVkIGtleQorICAgICAqICAgICAgICAgb3IgdmFsdWUgcHJldmVudHMgaXQgZnJvbSBiZWluZyBzdG9yZWQgaW4gdGhpcyBtYXAKKyAgICAgKgorICAgICAqLworICAgIFYgcHV0SWZBYnNlbnQoSyBrZXksIFYgdmFsdWUpOworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgZW50cnkgZm9yIGEga2V5IG9ubHkgaWYgY3VycmVudGx5IG1hcHBlZCB0byBhIGdpdmVuIHZhbHVlLgorICAgICAqIFRoaXMgaXMgZXF1aXZhbGVudCB0bworICAgICAqIDxwcmU+CisgICAgICogICBpZiAobWFwLmNvbnRhaW5zS2V5KGtleSkgJmFtcDsmYW1wOyBtYXAuZ2V0KGtleSkuZXF1YWxzKHZhbHVlKSkgeworICAgICAqICAgICAgIG1hcC5yZW1vdmUoa2V5KTsKKyAgICAgKiAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgKiAgIH0gZWxzZSByZXR1cm4gZmFsc2U7PC9wcmU+CisgICAgICogZXhjZXB0IHRoYXQgdGhlIGFjdGlvbiBpcyBwZXJmb3JtZWQgYXRvbWljYWxseS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkga2V5IHdpdGggd2hpY2ggdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhc3NvY2lhdGVkCisgICAgICogQHBhcmFtIHZhbHVlIHZhbHVlIGV4cGVjdGVkIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGtleQorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGUgdmFsdWUgd2FzIHJlbW92ZWQKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoZSA8dHQ+cmVtb3ZlPC90dD4gb3BlcmF0aW9uCisgICAgICogICAgICAgICBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgbWFwCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGtleSBvciB2YWx1ZSBpcyBvZiBhbiBpbmFwcHJvcHJpYXRlCisgICAgICogICAgICAgICB0eXBlIGZvciB0aGlzIG1hcCAob3B0aW9uYWwpCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBvciB2YWx1ZSBpcyBudWxsLAorICAgICAqICAgICAgICAgYW5kIHRoaXMgbWFwIGRvZXMgbm90IHBlcm1pdCBudWxsIGtleXMgb3IgdmFsdWVzIChvcHRpb25hbCkKKyAgICAgKi8KKyAgICBib29sZWFuIHJlbW92ZShPYmplY3Qga2V5LCBPYmplY3QgdmFsdWUpOworCisgICAgLyoqCisgICAgICogUmVwbGFjZXMgdGhlIGVudHJ5IGZvciBhIGtleSBvbmx5IGlmIGN1cnJlbnRseSBtYXBwZWQgdG8gYSBnaXZlbiB2YWx1ZS4KKyAgICAgKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8KKyAgICAgKiA8cHJlPgorICAgICAqICAgaWYgKG1hcC5jb250YWluc0tleShrZXkpICZhbXA7JmFtcDsgbWFwLmdldChrZXkpLmVxdWFscyhvbGRWYWx1ZSkpIHsKKyAgICAgKiAgICAgICBtYXAucHV0KGtleSwgbmV3VmFsdWUpOworICAgICAqICAgICAgIHJldHVybiB0cnVlOworICAgICAqICAgfSBlbHNlIHJldHVybiBmYWxzZTs8L3ByZT4KKyAgICAgKiBleGNlcHQgdGhhdCB0aGUgYWN0aW9uIGlzIHBlcmZvcm1lZCBhdG9taWNhbGx5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleSBrZXkgd2l0aCB3aGljaCB0aGUgc3BlY2lmaWVkIHZhbHVlIGlzIGFzc29jaWF0ZWQKKyAgICAgKiBAcGFyYW0gb2xkVmFsdWUgdmFsdWUgZXhwZWN0ZWQgdG8gYmUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQga2V5CisgICAgICogQHBhcmFtIG5ld1ZhbHVlIHZhbHVlIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGtleQorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGUgdmFsdWUgd2FzIHJlcGxhY2VkCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGUgPHR0PnB1dDwvdHQ+IG9wZXJhdGlvbgorICAgICAqICAgICAgICAgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIG1hcAorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBvZiBhIHNwZWNpZmllZCBrZXkgb3IgdmFsdWUKKyAgICAgKiAgICAgICAgIHByZXZlbnRzIGl0IGZyb20gYmVpbmcgc3RvcmVkIGluIHRoaXMgbWFwCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBhIHNwZWNpZmllZCBrZXkgb3IgdmFsdWUgaXMgbnVsbCwKKyAgICAgKiAgICAgICAgIGFuZCB0aGlzIG1hcCBkb2VzIG5vdCBwZXJtaXQgbnVsbCBrZXlzIG9yIHZhbHVlcworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNvbWUgcHJvcGVydHkgb2YgYSBzcGVjaWZpZWQga2V5CisgICAgICogICAgICAgICBvciB2YWx1ZSBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIHN0b3JlZCBpbiB0aGlzIG1hcAorICAgICAqLworICAgIGJvb2xlYW4gcmVwbGFjZShLIGtleSwgViBvbGRWYWx1ZSwgViBuZXdWYWx1ZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyB0aGUgZW50cnkgZm9yIGEga2V5IG9ubHkgaWYgY3VycmVudGx5IG1hcHBlZCB0byBzb21lIHZhbHVlLgorICAgICAqIFRoaXMgaXMgZXF1aXZhbGVudCB0bworICAgICAqIDxwcmU+CisgICAgICogICBpZiAobWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKKyAgICAgKiAgICAgICByZXR1cm4gbWFwLnB1dChrZXksIHZhbHVlKTsKKyAgICAgKiAgIH0gZWxzZSByZXR1cm4gbnVsbDs8L3ByZT4KKyAgICAgKiBleGNlcHQgdGhhdCB0aGUgYWN0aW9uIGlzIHBlcmZvcm1lZCBhdG9taWNhbGx5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleSBrZXkgd2l0aCB3aGljaCB0aGUgc3BlY2lmaWVkIHZhbHVlIGlzIGFzc29jaWF0ZWQKKyAgICAgKiBAcGFyYW0gdmFsdWUgdmFsdWUgdG8gYmUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQga2V5CisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LCBvcgorICAgICAqICAgICAgICAgPHR0Pm51bGw8L3R0PiBpZiB0aGVyZSB3YXMgbm8gbWFwcGluZyBmb3IgdGhlIGtleS4KKyAgICAgKiAgICAgICAgIChBIDx0dD5udWxsPC90dD4gcmV0dXJuIGNhbiBhbHNvIGluZGljYXRlIHRoYXQgdGhlIG1hcAorICAgICAqICAgICAgICAgcHJldmlvdXNseSBhc3NvY2lhdGVkIDx0dD5udWxsPC90dD4gd2l0aCB0aGUga2V5LAorICAgICAqICAgICAgICAgaWYgdGhlIGltcGxlbWVudGF0aW9uIHN1cHBvcnRzIG51bGwgdmFsdWVzLikKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoZSA8dHQ+cHV0PC90dD4gb3BlcmF0aW9uCisgICAgICogICAgICAgICBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgbWFwCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQga2V5IG9yIHZhbHVlCisgICAgICogICAgICAgICBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIHN0b3JlZCBpbiB0aGlzIG1hcAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgb3IgdmFsdWUgaXMgbnVsbCwKKyAgICAgKiAgICAgICAgIGFuZCB0aGlzIG1hcCBkb2VzIG5vdCBwZXJtaXQgbnVsbCBrZXlzIG9yIHZhbHVlcworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNvbWUgcHJvcGVydHkgb2YgdGhlIHNwZWNpZmllZCBrZXkKKyAgICAgKiAgICAgICAgIG9yIHZhbHVlIHByZXZlbnRzIGl0IGZyb20gYmVpbmcgc3RvcmVkIGluIHRoaXMgbWFwCisgICAgICovCisgICAgViByZXBsYWNlKEsga2V5LCBWIHZhbHVlKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Db25jdXJyZW50TmF2aWdhYmxlTWFwLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQ29uY3VycmVudE5hdmlnYWJsZU1hcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdkODZhZmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQ29uY3VycmVudE5hdmlnYWJsZU1hcC5qYXZhCkBAIC0wLDAgKzEsMTQ4IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CitpbXBvcnQgamF2YS51dGlsLio7CisKKy8qKgorICogQSB7QGxpbmsgQ29uY3VycmVudE1hcH0gc3VwcG9ydGluZyB7QGxpbmsgTmF2aWdhYmxlTWFwfSBvcGVyYXRpb25zLAorICogYW5kIHJlY3Vyc2l2ZWx5IHNvIGZvciBpdHMgbmF2aWdhYmxlIHN1Yi1tYXBzLgorICoKKyAqIDxwPlRoaXMgaW50ZXJmYWNlIGlzIGEgbWVtYmVyIG9mIHRoZQorICogPGEgaHJlZj0ie0Bkb2NSb290fS8uLi90ZWNobm90ZXMvZ3VpZGVzL2NvbGxlY3Rpb25zL2luZGV4Lmh0bWwiPgorICogSmF2YSBDb2xsZWN0aW9ucyBGcmFtZXdvcms8L2E+LgorICoKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqIEBwYXJhbSA8Sz4gdGhlIHR5cGUgb2Yga2V5cyBtYWludGFpbmVkIGJ5IHRoaXMgbWFwCisgKiBAcGFyYW0gPFY+IHRoZSB0eXBlIG9mIG1hcHBlZCB2YWx1ZXMKKyAqIEBzaW5jZSAxLjYKKyAqLworcHVibGljIGludGVyZmFjZSBDb25jdXJyZW50TmF2aWdhYmxlTWFwPEssVj4KKyAgICBleHRlbmRzIENvbmN1cnJlbnRNYXA8SyxWPiwgTmF2aWdhYmxlTWFwPEssVj4KK3sKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiAgICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBDb25jdXJyZW50TmF2aWdhYmxlTWFwPEssVj4gc3ViTWFwKEsgZnJvbUtleSwgYm9vbGVhbiBmcm9tSW5jbHVzaXZlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSyB0b0tleSwgICBib29sZWFuIHRvSW5jbHVzaXZlKTsKKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIENvbmN1cnJlbnROYXZpZ2FibGVNYXA8SyxWPiBoZWFkTWFwKEsgdG9LZXksIGJvb2xlYW4gaW5jbHVzaXZlKTsKKworCisgICAgLyoqCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgQ29uY3VycmVudE5hdmlnYWJsZU1hcDxLLFY+IHRhaWxNYXAoSyBmcm9tS2V5LCBib29sZWFuIGluY2x1c2l2ZSk7CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiAgICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBDb25jdXJyZW50TmF2aWdhYmxlTWFwPEssVj4gc3ViTWFwKEsgZnJvbUtleSwgSyB0b0tleSk7CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiAgICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBDb25jdXJyZW50TmF2aWdhYmxlTWFwPEssVj4gaGVhZE1hcChLIHRvS2V5KTsKKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIENvbmN1cnJlbnROYXZpZ2FibGVNYXA8SyxWPiB0YWlsTWFwKEsgZnJvbUtleSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcmV2ZXJzZSBvcmRlciB2aWV3IG9mIHRoZSBtYXBwaW5ncyBjb250YWluZWQgaW4gdGhpcyBtYXAuCisgICAgICogVGhlIGRlc2NlbmRpbmcgbWFwIGlzIGJhY2tlZCBieSB0aGlzIG1hcCwgc28gY2hhbmdlcyB0byB0aGUgbWFwIGFyZQorICAgICAqIHJlZmxlY3RlZCBpbiB0aGUgZGVzY2VuZGluZyBtYXAsIGFuZCB2aWNlLXZlcnNhLgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybmVkIG1hcCBoYXMgYW4gb3JkZXJpbmcgZXF1aXZhbGVudCB0bworICAgICAqIDx0dD57QGxpbmsgQ29sbGVjdGlvbnMjcmV2ZXJzZU9yZGVyKENvbXBhcmF0b3IpIENvbGxlY3Rpb25zLnJldmVyc2VPcmRlcn0oY29tcGFyYXRvcigpKTwvdHQ+LgorICAgICAqIFRoZSBleHByZXNzaW9uIHtAY29kZSBtLmRlc2NlbmRpbmdNYXAoKS5kZXNjZW5kaW5nTWFwKCl9IHJldHVybnMgYQorICAgICAqIHZpZXcgb2Yge0Bjb2RlIG19IGVzc2VudGlhbGx5IGVxdWl2YWxlbnQgdG8ge0Bjb2RlIG19LgorICAgICAqCisgICAgICogQHJldHVybiBhIHJldmVyc2Ugb3JkZXIgdmlldyBvZiB0aGlzIG1hcAorICAgICAqLworICAgIENvbmN1cnJlbnROYXZpZ2FibGVNYXA8SyxWPiBkZXNjZW5kaW5nTWFwKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0BsaW5rIE5hdmlnYWJsZVNldH0gdmlldyBvZiB0aGUga2V5cyBjb250YWluZWQgaW4gdGhpcyBtYXAuCisgICAgICogVGhlIHNldCdzIGl0ZXJhdG9yIHJldHVybnMgdGhlIGtleXMgaW4gYXNjZW5kaW5nIG9yZGVyLgorICAgICAqIFRoZSBzZXQgaXMgYmFja2VkIGJ5IHRoZSBtYXAsIHNvIGNoYW5nZXMgdG8gdGhlIG1hcCBhcmUKKyAgICAgKiByZWZsZWN0ZWQgaW4gdGhlIHNldCwgYW5kIHZpY2UtdmVyc2EuICBUaGUgc2V0IHN1cHBvcnRzIGVsZW1lbnQKKyAgICAgKiByZW1vdmFsLCB3aGljaCByZW1vdmVzIHRoZSBjb3JyZXNwb25kaW5nIG1hcHBpbmcgZnJvbSB0aGUgbWFwLAorICAgICAqIHZpYSB0aGUge0Bjb2RlIEl0ZXJhdG9yLnJlbW92ZX0sIHtAY29kZSBTZXQucmVtb3ZlfSwKKyAgICAgKiB7QGNvZGUgcmVtb3ZlQWxsfSwge0Bjb2RlIHJldGFpbkFsbH0sIGFuZCB7QGNvZGUgY2xlYXJ9CisgICAgICogb3BlcmF0aW9ucy4gIEl0IGRvZXMgbm90IHN1cHBvcnQgdGhlIHtAY29kZSBhZGR9IG9yIHtAY29kZSBhZGRBbGx9CisgICAgICogb3BlcmF0aW9ucy4KKyAgICAgKgorICAgICAqIDxwPlRoZSB2aWV3J3Mge0Bjb2RlIGl0ZXJhdG9yfSBpcyBhICJ3ZWFrbHkgY29uc2lzdGVudCIgaXRlcmF0b3IKKyAgICAgKiB0aGF0IHdpbGwgbmV2ZXIgdGhyb3cge0BsaW5rIENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb259LAorICAgICAqIGFuZCBndWFyYW50ZWVzIHRvIHRyYXZlcnNlIGVsZW1lbnRzIGFzIHRoZXkgZXhpc3RlZCB1cG9uCisgICAgICogY29uc3RydWN0aW9uIG9mIHRoZSBpdGVyYXRvciwgYW5kIG1heSAoYnV0IGlzIG5vdCBndWFyYW50ZWVkIHRvKQorICAgICAqIHJlZmxlY3QgYW55IG1vZGlmaWNhdGlvbnMgc3Vic2VxdWVudCB0byBjb25zdHJ1Y3Rpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgbmF2aWdhYmxlIHNldCB2aWV3IG9mIHRoZSBrZXlzIGluIHRoaXMgbWFwCisgICAgICovCisgICAgcHVibGljIE5hdmlnYWJsZVNldDxLPiBuYXZpZ2FibGVLZXlTZXQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGxpbmsgTmF2aWdhYmxlU2V0fSB2aWV3IG9mIHRoZSBrZXlzIGNvbnRhaW5lZCBpbiB0aGlzIG1hcC4KKyAgICAgKiBUaGUgc2V0J3MgaXRlcmF0b3IgcmV0dXJucyB0aGUga2V5cyBpbiBhc2NlbmRpbmcgb3JkZXIuCisgICAgICogVGhlIHNldCBpcyBiYWNrZWQgYnkgdGhlIG1hcCwgc28gY2hhbmdlcyB0byB0aGUgbWFwIGFyZQorICAgICAqIHJlZmxlY3RlZCBpbiB0aGUgc2V0LCBhbmQgdmljZS12ZXJzYS4gIFRoZSBzZXQgc3VwcG9ydHMgZWxlbWVudAorICAgICAqIHJlbW92YWwsIHdoaWNoIHJlbW92ZXMgdGhlIGNvcnJlc3BvbmRpbmcgbWFwcGluZyBmcm9tIHRoZSBtYXAsCisgICAgICogdmlhIHRoZSB7QGNvZGUgSXRlcmF0b3IucmVtb3ZlfSwge0Bjb2RlIFNldC5yZW1vdmV9LAorICAgICAqIHtAY29kZSByZW1vdmVBbGx9LCB7QGNvZGUgcmV0YWluQWxsfSwgYW5kIHtAY29kZSBjbGVhcn0KKyAgICAgKiBvcGVyYXRpb25zLiAgSXQgZG9lcyBub3Qgc3VwcG9ydCB0aGUge0Bjb2RlIGFkZH0gb3Ige0Bjb2RlIGFkZEFsbH0KKyAgICAgKiBvcGVyYXRpb25zLgorICAgICAqCisgICAgICogPHA+VGhlIHZpZXcncyB7QGNvZGUgaXRlcmF0b3J9IGlzIGEgIndlYWtseSBjb25zaXN0ZW50IiBpdGVyYXRvcgorICAgICAqIHRoYXQgd2lsbCBuZXZlciB0aHJvdyB7QGxpbmsgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0sCisgICAgICogYW5kIGd1YXJhbnRlZXMgdG8gdHJhdmVyc2UgZWxlbWVudHMgYXMgdGhleSBleGlzdGVkIHVwb24KKyAgICAgKiBjb25zdHJ1Y3Rpb24gb2YgdGhlIGl0ZXJhdG9yLCBhbmQgbWF5IChidXQgaXMgbm90IGd1YXJhbnRlZWQgdG8pCisgICAgICogcmVmbGVjdCBhbnkgbW9kaWZpY2F0aW9ucyBzdWJzZXF1ZW50IHRvIGNvbnN0cnVjdGlvbi4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8gbWV0aG9kIHtAY29kZSBuYXZpZ2FibGVLZXlTZXR9LgorICAgICAqCisgICAgICogQHJldHVybiBhIG5hdmlnYWJsZSBzZXQgdmlldyBvZiB0aGUga2V5cyBpbiB0aGlzIG1hcAorICAgICAqLworICAgIE5hdmlnYWJsZVNldDxLPiBrZXlTZXQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSByZXZlcnNlIG9yZGVyIHtAbGluayBOYXZpZ2FibGVTZXR9IHZpZXcgb2YgdGhlIGtleXMgY29udGFpbmVkIGluIHRoaXMgbWFwLgorICAgICAqIFRoZSBzZXQncyBpdGVyYXRvciByZXR1cm5zIHRoZSBrZXlzIGluIGRlc2NlbmRpbmcgb3JkZXIuCisgICAgICogVGhlIHNldCBpcyBiYWNrZWQgYnkgdGhlIG1hcCwgc28gY2hhbmdlcyB0byB0aGUgbWFwIGFyZQorICAgICAqIHJlZmxlY3RlZCBpbiB0aGUgc2V0LCBhbmQgdmljZS12ZXJzYS4gIFRoZSBzZXQgc3VwcG9ydHMgZWxlbWVudAorICAgICAqIHJlbW92YWwsIHdoaWNoIHJlbW92ZXMgdGhlIGNvcnJlc3BvbmRpbmcgbWFwcGluZyBmcm9tIHRoZSBtYXAsCisgICAgICogdmlhIHRoZSB7QGNvZGUgSXRlcmF0b3IucmVtb3ZlfSwge0Bjb2RlIFNldC5yZW1vdmV9LAorICAgICAqIHtAY29kZSByZW1vdmVBbGx9LCB7QGNvZGUgcmV0YWluQWxsfSwgYW5kIHtAY29kZSBjbGVhcn0KKyAgICAgKiBvcGVyYXRpb25zLiAgSXQgZG9lcyBub3Qgc3VwcG9ydCB0aGUge0Bjb2RlIGFkZH0gb3Ige0Bjb2RlIGFkZEFsbH0KKyAgICAgKiBvcGVyYXRpb25zLgorICAgICAqCisgICAgICogPHA+VGhlIHZpZXcncyB7QGNvZGUgaXRlcmF0b3J9IGlzIGEgIndlYWtseSBjb25zaXN0ZW50IiBpdGVyYXRvcgorICAgICAqIHRoYXQgd2lsbCBuZXZlciB0aHJvdyB7QGxpbmsgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0sCisgICAgICogYW5kIGd1YXJhbnRlZXMgdG8gdHJhdmVyc2UgZWxlbWVudHMgYXMgdGhleSBleGlzdGVkIHVwb24KKyAgICAgKiBjb25zdHJ1Y3Rpb24gb2YgdGhlIGl0ZXJhdG9yLCBhbmQgbWF5IChidXQgaXMgbm90IGd1YXJhbnRlZWQgdG8pCisgICAgICogcmVmbGVjdCBhbnkgbW9kaWZpY2F0aW9ucyBzdWJzZXF1ZW50IHRvIGNvbnN0cnVjdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSByZXZlcnNlIG9yZGVyIG5hdmlnYWJsZSBzZXQgdmlldyBvZiB0aGUga2V5cyBpbiB0aGlzIG1hcAorICAgICAqLworICAgIHB1YmxpYyBOYXZpZ2FibGVTZXQ8Sz4gZGVzY2VuZGluZ0tleVNldCgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0NvbmN1cnJlbnRTa2lwTGlzdE1hcC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0NvbmN1cnJlbnRTa2lwTGlzdE1hcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZiZDEwODMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQ29uY3VycmVudFNraXBMaXN0TWFwLmphdmEKQEAgLTAsMCArMSwzMDcyIEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLio7CisKKy8qKgorICogQSBzY2FsYWJsZSBjb25jdXJyZW50IHtAbGluayBDb25jdXJyZW50TmF2aWdhYmxlTWFwfSBpbXBsZW1lbnRhdGlvbi4KKyAqIFRoZSBtYXAgaXMgc29ydGVkIGFjY29yZGluZyB0byB0aGUge0BsaW5rcGxhaW4gQ29tcGFyYWJsZSBuYXR1cmFsCisgKiBvcmRlcmluZ30gb2YgaXRzIGtleXMsIG9yIGJ5IGEge0BsaW5rIENvbXBhcmF0b3J9IHByb3ZpZGVkIGF0IG1hcAorICogY3JlYXRpb24gdGltZSwgZGVwZW5kaW5nIG9uIHdoaWNoIGNvbnN0cnVjdG9yIGlzIHVzZWQuCisgKgorICogPHA+VGhpcyBjbGFzcyBpbXBsZW1lbnRzIGEgY29uY3VycmVudCB2YXJpYW50IG9mIDxhCisgKiBocmVmPSJodHRwOi8vd3d3LmNzLnVtZC5lZHUvfnB1Z2gvIj5Ta2lwTGlzdHM8L2E+IHByb3ZpZGluZworICogZXhwZWN0ZWQgYXZlcmFnZSA8aT5sb2cobik8L2k+IHRpbWUgY29zdCBmb3IgdGhlCisgKiA8dHQ+Y29udGFpbnNLZXk8L3R0PiwgPHR0PmdldDwvdHQ+LCA8dHQ+cHV0PC90dD4gYW5kCisgKiA8dHQ+cmVtb3ZlPC90dD4gb3BlcmF0aW9ucyBhbmQgdGhlaXIgdmFyaWFudHMuICBJbnNlcnRpb24sIHJlbW92YWwsCisgKiB1cGRhdGUsIGFuZCBhY2Nlc3Mgb3BlcmF0aW9ucyBzYWZlbHkgZXhlY3V0ZSBjb25jdXJyZW50bHkgYnkKKyAqIG11bHRpcGxlIHRocmVhZHMuICBJdGVyYXRvcnMgYXJlIDxpPndlYWtseSBjb25zaXN0ZW50PC9pPiwgcmV0dXJuaW5nCisgKiBlbGVtZW50cyByZWZsZWN0aW5nIHRoZSBzdGF0ZSBvZiB0aGUgbWFwIGF0IHNvbWUgcG9pbnQgYXQgb3Igc2luY2UKKyAqIHRoZSBjcmVhdGlvbiBvZiB0aGUgaXRlcmF0b3IuICBUaGV5IGRvIDxlbT5ub3Q8L2VtPiB0aHJvdyB7QGxpbmsKKyAqIENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb259LCBhbmQgbWF5IHByb2NlZWQgY29uY3VycmVudGx5IHdpdGgKKyAqIG90aGVyIG9wZXJhdGlvbnMuIEFzY2VuZGluZyBrZXkgb3JkZXJlZCB2aWV3cyBhbmQgdGhlaXIgaXRlcmF0b3JzCisgKiBhcmUgZmFzdGVyIHRoYW4gZGVzY2VuZGluZyBvbmVzLgorICoKKyAqIDxwPkFsbCA8dHQ+TWFwLkVudHJ5PC90dD4gcGFpcnMgcmV0dXJuZWQgYnkgbWV0aG9kcyBpbiB0aGlzIGNsYXNzCisgKiBhbmQgaXRzIHZpZXdzIHJlcHJlc2VudCBzbmFwc2hvdHMgb2YgbWFwcGluZ3MgYXQgdGhlIHRpbWUgdGhleSB3ZXJlCisgKiBwcm9kdWNlZC4gVGhleSBkbyA8ZW0+bm90PC9lbT4gc3VwcG9ydCB0aGUgPHR0PkVudHJ5LnNldFZhbHVlPC90dD4KKyAqIG1ldGhvZC4gKE5vdGUgaG93ZXZlciB0aGF0IGl0IGlzIHBvc3NpYmxlIHRvIGNoYW5nZSBtYXBwaW5ncyBpbiB0aGUKKyAqIGFzc29jaWF0ZWQgbWFwIHVzaW5nIDx0dD5wdXQ8L3R0PiwgPHR0PnB1dElmQWJzZW50PC90dD4sIG9yCisgKiA8dHQ+cmVwbGFjZTwvdHQ+LCBkZXBlbmRpbmcgb24gZXhhY3RseSB3aGljaCBlZmZlY3QgeW91IG5lZWQuKQorICoKKyAqIDxwPkJld2FyZSB0aGF0LCB1bmxpa2UgaW4gbW9zdCBjb2xsZWN0aW9ucywgdGhlIDx0dD5zaXplPC90dD4KKyAqIG1ldGhvZCBpcyA8ZW0+bm90PC9lbT4gYSBjb25zdGFudC10aW1lIG9wZXJhdGlvbi4gQmVjYXVzZSBvZiB0aGUKKyAqIGFzeW5jaHJvbm91cyBuYXR1cmUgb2YgdGhlc2UgbWFwcywgZGV0ZXJtaW5pbmcgdGhlIGN1cnJlbnQgbnVtYmVyCisgKiBvZiBlbGVtZW50cyByZXF1aXJlcyBhIHRyYXZlcnNhbCBvZiB0aGUgZWxlbWVudHMuICBBZGRpdGlvbmFsbHksCisgKiB0aGUgYnVsayBvcGVyYXRpb25zIDx0dD5wdXRBbGw8L3R0PiwgPHR0PmVxdWFsczwvdHQ+LCBhbmQKKyAqIDx0dD5jbGVhcjwvdHQ+IGFyZSA8ZW0+bm90PC9lbT4gZ3VhcmFudGVlZCB0byBiZSBwZXJmb3JtZWQKKyAqIGF0b21pY2FsbHkuIEZvciBleGFtcGxlLCBhbiBpdGVyYXRvciBvcGVyYXRpbmcgY29uY3VycmVudGx5IHdpdGggYQorICogPHR0PnB1dEFsbDwvdHQ+IG9wZXJhdGlvbiBtaWdodCB2aWV3IG9ubHkgc29tZSBvZiB0aGUgYWRkZWQKKyAqIGVsZW1lbnRzLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgYW5kIGl0cyB2aWV3cyBhbmQgaXRlcmF0b3JzIGltcGxlbWVudCBhbGwgb2YgdGhlCisgKiA8ZW0+b3B0aW9uYWw8L2VtPiBtZXRob2RzIG9mIHRoZSB7QGxpbmsgTWFwfSBhbmQge0BsaW5rIEl0ZXJhdG9yfQorICogaW50ZXJmYWNlcy4gTGlrZSBtb3N0IG90aGVyIGNvbmN1cnJlbnQgY29sbGVjdGlvbnMsIHRoaXMgY2xhc3MgZG9lcworICogPGVtPm5vdDwvZW0+IHBlcm1pdCB0aGUgdXNlIG9mIDx0dD5udWxsPC90dD4ga2V5cyBvciB2YWx1ZXMgYmVjYXVzZSBzb21lCisgKiBudWxsIHJldHVybiB2YWx1ZXMgY2Fubm90IGJlIHJlbGlhYmx5IGRpc3Rpbmd1aXNoZWQgZnJvbSB0aGUgYWJzZW5jZSBvZgorICogZWxlbWVudHMuCisgKgorICogPHA+VGhpcyBjbGFzcyBpcyBhIG1lbWJlciBvZiB0aGUKKyAqIDxhIGhyZWY9IntAZG9jUm9vdH0vLi4vdGVjaG5vdGVzL2d1aWRlcy9jb2xsZWN0aW9ucy9pbmRleC5odG1sIj4KKyAqIEphdmEgQ29sbGVjdGlvbnMgRnJhbWV3b3JrPC9hPi4KKyAqCisgKiBAYXV0aG9yIERvdWcgTGVhCisgKiBAcGFyYW0gPEs+IHRoZSB0eXBlIG9mIGtleXMgbWFpbnRhaW5lZCBieSB0aGlzIG1hcAorICogQHBhcmFtIDxWPiB0aGUgdHlwZSBvZiBtYXBwZWQgdmFsdWVzCisgKiBAc2luY2UgMS42CisgKi8KK3B1YmxpYyBjbGFzcyBDb25jdXJyZW50U2tpcExpc3RNYXA8SyxWPiBleHRlbmRzIEFic3RyYWN0TWFwPEssVj4KKyAgICBpbXBsZW1lbnRzIENvbmN1cnJlbnROYXZpZ2FibGVNYXA8SyxWPiwKKyAgICAgICAgICAgICAgIENsb25lYWJsZSwKKyAgICAgICAgICAgICAgIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAvKgorICAgICAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIHRyZWUtbGlrZSB0d28tZGltZW5zaW9uYWxseSBsaW5rZWQgc2tpcAorICAgICAqIGxpc3QgaW4gd2hpY2ggdGhlIGluZGV4IGxldmVscyBhcmUgcmVwcmVzZW50ZWQgaW4gc2VwYXJhdGUKKyAgICAgKiBub2RlcyBmcm9tIHRoZSBiYXNlIG5vZGVzIGhvbGRpbmcgZGF0YS4gIFRoZXJlIGFyZSB0d28gcmVhc29ucworICAgICAqIGZvciB0YWtpbmcgdGhpcyBhcHByb2FjaCBpbnN0ZWFkIG9mIHRoZSB1c3VhbCBhcnJheS1iYXNlZAorICAgICAqIHN0cnVjdHVyZTogMSkgQXJyYXkgYmFzZWQgaW1wbGVtZW50YXRpb25zIHNlZW0gdG8gZW5jb3VudGVyCisgICAgICogbW9yZSBjb21wbGV4aXR5IGFuZCBvdmVyaGVhZCAyKSBXZSBjYW4gdXNlIGNoZWFwZXIgYWxnb3JpdGhtcworICAgICAqIGZvciB0aGUgaGVhdmlseS10cmF2ZXJzZWQgaW5kZXggbGlzdHMgdGhhbiBjYW4gYmUgdXNlZCBmb3IgdGhlCisgICAgICogYmFzZSBsaXN0cy4gIEhlcmUncyBhIHBpY3R1cmUgb2Ygc29tZSBvZiB0aGUgYmFzaWNzIGZvciBhCisgICAgICogcG9zc2libGUgbGlzdCB3aXRoIDIgbGV2ZWxzIG9mIGluZGV4OgorICAgICAqCisgICAgICogSGVhZCBub2RlcyAgICAgICAgICBJbmRleCBub2RlcworICAgICAqICstKyAgICByaWdodCAgICAgICAgKy0rICAgICAgICAgICAgICAgICAgICAgICstKworICAgICAqIHwyfC0tLS0tLS0tLS0tLS0tLS0+fCB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tPnwgfC0+bnVsbAorICAgICAqICstKyAgICAgICAgICAgICAgICAgKy0rICAgICAgICAgICAgICAgICAgICAgICstKworICAgICAqICB8IGRvd24gICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICB8CisgICAgICogIHYgICAgICAgICAgICAgICAgICAgdiAgICAgICAgICAgICAgICAgICAgICAgIHYKKyAgICAgKiArLSsgICAgICAgICAgICArLSsgICstKyAgICAgICArLSsgICAgICAgICAgICArLSsgICAgICAgKy0rCisgICAgICogfDF8LS0tLS0tLS0tLS0+fCB8LT58IHwtLS0tLS0+fCB8LS0tLS0tLS0tLS0+fCB8LS0tLS0tPnwgfC0+bnVsbAorICAgICAqICstKyAgICAgICAgICAgICstKyAgKy0rICAgICAgICstKyAgICAgICAgICAgICstKyAgICAgICArLSsKKyAgICAgKiAgdiAgICAgICAgICAgICAgfCAgICB8ICAgICAgICAgfCAgICAgICAgICAgICAgfCAgICAgICAgIHwKKyAgICAgKiBOb2RlcyAgbmV4dCAgICAgdiAgICB2ICAgICAgICAgdiAgICAgICAgICAgICAgdiAgICAgICAgIHYKKyAgICAgKiArLSsgICstKyAgKy0rICArLSsgICstKyAgKy0rICArLSsgICstKyAgKy0rICArLSsgICstKyAgKy0rCisgICAgICogfCB8LT58QXwtPnxCfC0+fEN8LT58RHwtPnxFfC0+fEZ8LT58R3wtPnxIfC0+fEl8LT58SnwtPnxLfC0+bnVsbAorICAgICAqICstKyAgKy0rICArLSsgICstKyAgKy0rICArLSsgICstKyAgKy0rICArLSsgICstKyAgKy0rICArLSsKKyAgICAgKgorICAgICAqIFRoZSBiYXNlIGxpc3RzIHVzZSBhIHZhcmlhbnQgb2YgdGhlIEhNIGxpbmtlZCBvcmRlcmVkIHNldAorICAgICAqIGFsZ29yaXRobS4gU2VlIFRpbSBIYXJyaXMsICJBIHByYWdtYXRpYyBpbXBsZW1lbnRhdGlvbiBvZgorICAgICAqIG5vbi1ibG9ja2luZyBsaW5rZWQgbGlzdHMiCisgICAgICogaHR0cDovL3d3dy5jbC5jYW0uYWMudWsvfnRsaDIwL3B1YmxpY2F0aW9ucy5odG1sIGFuZCBNYWdlZAorICAgICAqIE1pY2hhZWwgIkhpZ2ggUGVyZm9ybWFuY2UgRHluYW1pYyBMb2NrLUZyZWUgSGFzaCBUYWJsZXMgYW5kCisgICAgICogTGlzdC1CYXNlZCBTZXRzIgorICAgICAqIGh0dHA6Ly93d3cucmVzZWFyY2guaWJtLmNvbS9wZW9wbGUvbS9taWNoYWVsL3B1YnMuaHRtLiAgVGhlCisgICAgICogYmFzaWMgaWRlYSBpbiB0aGVzZSBsaXN0cyBpcyB0byBtYXJrIHRoZSAibmV4dCIgcG9pbnRlcnMgb2YKKyAgICAgKiBkZWxldGVkIG5vZGVzIHdoZW4gZGVsZXRpbmcgdG8gYXZvaWQgY29uZmxpY3RzIHdpdGggY29uY3VycmVudAorICAgICAqIGluc2VydGlvbnMsIGFuZCB3aGVuIHRyYXZlcnNpbmcgdG8ga2VlcCB0cmFjayBvZiB0cmlwbGVzCisgICAgICogKHByZWRlY2Vzc29yLCBub2RlLCBzdWNjZXNzb3IpIGluIG9yZGVyIHRvIGRldGVjdCB3aGVuIGFuZCBob3cKKyAgICAgKiB0byB1bmxpbmsgdGhlc2UgZGVsZXRlZCBub2Rlcy4KKyAgICAgKgorICAgICAqIFJhdGhlciB0aGFuIHVzaW5nIG1hcmstYml0cyB0byBtYXJrIGxpc3QgZGVsZXRpb25zICh3aGljaCBjYW4KKyAgICAgKiBiZSBzbG93IGFuZCBzcGFjZS1pbnRlbnNpdmUgdXNpbmcgQXRvbWljTWFya2VkUmVmZXJlbmNlKSwgbm9kZXMKKyAgICAgKiB1c2UgZGlyZWN0IENBUydhYmxlIG5leHQgcG9pbnRlcnMuICBPbiBkZWxldGlvbiwgaW5zdGVhZCBvZgorICAgICAqIG1hcmtpbmcgYSBwb2ludGVyLCB0aGV5IHNwbGljZSBpbiBhbm90aGVyIG5vZGUgdGhhdCBjYW4gYmUKKyAgICAgKiB0aG91Z2h0IG9mIGFzIHN0YW5kaW5nIGZvciBhIG1hcmtlZCBwb2ludGVyIChpbmRpY2F0aW5nIHRoaXMgYnkKKyAgICAgKiB1c2luZyBvdGhlcndpc2UgaW1wb3NzaWJsZSBmaWVsZCB2YWx1ZXMpLiAgVXNpbmcgcGxhaW4gbm9kZXMKKyAgICAgKiBhY3RzIHJvdWdobHkgbGlrZSAiYm94ZWQiIGltcGxlbWVudGF0aW9ucyBvZiBtYXJrZWQgcG9pbnRlcnMsCisgICAgICogYnV0IHVzZXMgbmV3IG5vZGVzIG9ubHkgd2hlbiBub2RlcyBhcmUgZGVsZXRlZCwgbm90IGZvciBldmVyeQorICAgICAqIGxpbmsuICBUaGlzIHJlcXVpcmVzIGxlc3Mgc3BhY2UgYW5kIHN1cHBvcnRzIGZhc3RlcgorICAgICAqIHRyYXZlcnNhbC4gRXZlbiBpZiBtYXJrZWQgcmVmZXJlbmNlcyB3ZXJlIGJldHRlciBzdXBwb3J0ZWQgYnkKKyAgICAgKiBKVk1zLCB0cmF2ZXJzYWwgdXNpbmcgdGhpcyB0ZWNobmlxdWUgbWlnaHQgc3RpbGwgYmUgZmFzdGVyCisgICAgICogYmVjYXVzZSBhbnkgc2VhcmNoIG5lZWQgb25seSByZWFkIGFoZWFkIG9uZSBtb3JlIG5vZGUgdGhhbgorICAgICAqIG90aGVyd2lzZSByZXF1aXJlZCAodG8gY2hlY2sgZm9yIHRyYWlsaW5nIG1hcmtlcikgcmF0aGVyIHRoYW4KKyAgICAgKiB1bm1hc2tpbmcgbWFyayBiaXRzIG9yIHdoYXRldmVyIG9uIGVhY2ggcmVhZC4KKyAgICAgKgorICAgICAqIFRoaXMgYXBwcm9hY2ggbWFpbnRhaW5zIHRoZSBlc3NlbnRpYWwgcHJvcGVydHkgbmVlZGVkIGluIHRoZSBITQorICAgICAqIGFsZ29yaXRobSBvZiBjaGFuZ2luZyB0aGUgbmV4dC1wb2ludGVyIG9mIGEgZGVsZXRlZCBub2RlIHNvCisgICAgICogdGhhdCBhbnkgb3RoZXIgQ0FTIG9mIGl0IHdpbGwgZmFpbCwgYnV0IGltcGxlbWVudHMgdGhlIGlkZWEgYnkKKyAgICAgKiBjaGFuZ2luZyB0aGUgcG9pbnRlciB0byBwb2ludCB0byBhIGRpZmZlcmVudCBub2RlLCBub3QgYnkKKyAgICAgKiBtYXJraW5nIGl0LiAgV2hpbGUgaXQgd291bGQgYmUgcG9zc2libGUgdG8gZnVydGhlciBzcXVlZXplCisgICAgICogc3BhY2UgYnkgZGVmaW5pbmcgbWFya2VyIG5vZGVzIG5vdCB0byBoYXZlIGtleS92YWx1ZSBmaWVsZHMsIGl0CisgICAgICogaXNuJ3Qgd29ydGggdGhlIGV4dHJhIHR5cGUtdGVzdGluZyBvdmVyaGVhZC4gIFRoZSBkZWxldGlvbgorICAgICAqIG1hcmtlcnMgYXJlIHJhcmVseSBlbmNvdW50ZXJlZCBkdXJpbmcgdHJhdmVyc2FsIGFuZCBhcmUKKyAgICAgKiBub3JtYWxseSBxdWlja2x5IGdhcmJhZ2UgY29sbGVjdGVkLiAoTm90ZSB0aGF0IHRoaXMgdGVjaG5pcXVlCisgICAgICogd291bGQgbm90IHdvcmsgd2VsbCBpbiBzeXN0ZW1zIHdpdGhvdXQgZ2FyYmFnZSBjb2xsZWN0aW9uLikKKyAgICAgKgorICAgICAqIEluIGFkZGl0aW9uIHRvIHVzaW5nIGRlbGV0aW9uIG1hcmtlcnMsIHRoZSBsaXN0cyBhbHNvIHVzZQorICAgICAqIG51bGxuZXNzIG9mIHZhbHVlIGZpZWxkcyB0byBpbmRpY2F0ZSBkZWxldGlvbiwgaW4gYSBzdHlsZQorICAgICAqIHNpbWlsYXIgdG8gdHlwaWNhbCBsYXp5LWRlbGV0aW9uIHNjaGVtZXMuICBJZiBhIG5vZGUncyB2YWx1ZSBpcworICAgICAqIG51bGwsIHRoZW4gaXQgaXMgY29uc2lkZXJlZCBsb2dpY2FsbHkgZGVsZXRlZCBhbmQgaWdub3JlZCBldmVuCisgICAgICogdGhvdWdoIGl0IGlzIHN0aWxsIHJlYWNoYWJsZS4gVGhpcyBtYWludGFpbnMgcHJvcGVyIGNvbnRyb2wgb2YKKyAgICAgKiBjb25jdXJyZW50IHJlcGxhY2UgdnMgZGVsZXRlIG9wZXJhdGlvbnMgLS0gYW4gYXR0ZW1wdGVkIHJlcGxhY2UKKyAgICAgKiBtdXN0IGZhaWwgaWYgYSBkZWxldGUgYmVhdCBpdCBieSBudWxsaW5nIGZpZWxkLCBhbmQgYSBkZWxldGUKKyAgICAgKiBtdXN0IHJldHVybiB0aGUgbGFzdCBub24tbnVsbCB2YWx1ZSBoZWxkIGluIHRoZSBmaWVsZC4gKE5vdGU6CisgICAgICogTnVsbCwgcmF0aGVyIHRoYW4gc29tZSBzcGVjaWFsIG1hcmtlciwgaXMgdXNlZCBmb3IgdmFsdWUgZmllbGRzCisgICAgICogaGVyZSBiZWNhdXNlIGl0IGp1c3Qgc28gaGFwcGVucyB0byBtZXNoIHdpdGggdGhlIE1hcCBBUEkKKyAgICAgKiByZXF1aXJlbWVudCB0aGF0IG1ldGhvZCBnZXQgcmV0dXJucyBudWxsIGlmIHRoZXJlIGlzIG5vCisgICAgICogbWFwcGluZywgd2hpY2ggYWxsb3dzIG5vZGVzIHRvIHJlbWFpbiBjb25jdXJyZW50bHkgcmVhZGFibGUKKyAgICAgKiBldmVuIHdoZW4gZGVsZXRlZC4gVXNpbmcgYW55IG90aGVyIG1hcmtlciB2YWx1ZSBoZXJlIHdvdWxkIGJlCisgICAgICogbWVzc3kgYXQgYmVzdC4pCisgICAgICoKKyAgICAgKiBIZXJlJ3MgdGhlIHNlcXVlbmNlIG9mIGV2ZW50cyBmb3IgYSBkZWxldGlvbiBvZiBub2RlIG4gd2l0aAorICAgICAqIHByZWRlY2Vzc29yIGIgYW5kIHN1Y2Nlc3NvciBmLCBpbml0aWFsbHk6CisgICAgICoKKyAgICAgKiAgICAgICAgKy0tLS0tLSsgICAgICAgKy0tLS0tLSsgICAgICArLS0tLS0tKworICAgICAqICAgLi4uICB8ICAgYiAgfC0tLS0tLT58ICAgbiAgfC0tLS0tPnwgICBmICB8IC4uLgorICAgICAqICAgICAgICArLS0tLS0tKyAgICAgICArLS0tLS0tKyAgICAgICstLS0tLS0rCisgICAgICoKKyAgICAgKiAxLiBDQVMgbidzIHZhbHVlIGZpZWxkIGZyb20gbm9uLW51bGwgdG8gbnVsbC4KKyAgICAgKiAgICBGcm9tIHRoaXMgcG9pbnQgb24sIG5vIHB1YmxpYyBvcGVyYXRpb25zIGVuY291bnRlcmluZworICAgICAqICAgIHRoZSBub2RlIGNvbnNpZGVyIHRoaXMgbWFwcGluZyB0byBleGlzdC4gSG93ZXZlciwgb3RoZXIKKyAgICAgKiAgICBvbmdvaW5nIGluc2VydGlvbnMgYW5kIGRlbGV0aW9ucyBtaWdodCBzdGlsbCBtb2RpZnkKKyAgICAgKiAgICBuJ3MgbmV4dCBwb2ludGVyLgorICAgICAqCisgICAgICogMi4gQ0FTIG4ncyBuZXh0IHBvaW50ZXIgdG8gcG9pbnQgdG8gYSBuZXcgbWFya2VyIG5vZGUuCisgICAgICogICAgRnJvbSB0aGlzIHBvaW50IG9uLCBubyBvdGhlciBub2RlcyBjYW4gYmUgYXBwZW5kZWQgdG8gbi4KKyAgICAgKiAgICB3aGljaCBhdm9pZHMgZGVsZXRpb24gZXJyb3JzIGluIENBUy1iYXNlZCBsaW5rZWQgbGlzdHMuCisgICAgICoKKyAgICAgKiAgICAgICAgKy0tLS0tLSsgICAgICAgKy0tLS0tLSsgICAgICArLS0tLS0tKyAgICAgICArLS0tLS0tKworICAgICAqICAgLi4uICB8ICAgYiAgfC0tLS0tLT58ICAgbiAgfC0tLS0tPnxtYXJrZXJ8LS0tLS0tPnwgICBmICB8IC4uLgorICAgICAqICAgICAgICArLS0tLS0tKyAgICAgICArLS0tLS0tKyAgICAgICstLS0tLS0rICAgICAgICstLS0tLS0rCisgICAgICoKKyAgICAgKiAzLiBDQVMgYidzIG5leHQgcG9pbnRlciBvdmVyIGJvdGggbiBhbmQgaXRzIG1hcmtlci4KKyAgICAgKiAgICBGcm9tIHRoaXMgcG9pbnQgb24sIG5vIG5ldyB0cmF2ZXJzYWxzIHdpbGwgZW5jb3VudGVyIG4sCisgICAgICogICAgYW5kIGl0IGNhbiBldmVudHVhbGx5IGJlIEdDZWQuCisgICAgICogICAgICAgICstLS0tLS0rICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLS0tLSsKKyAgICAgKiAgIC4uLiAgfCAgIGIgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT58ICAgZiAgfCAuLi4KKyAgICAgKiAgICAgICAgKy0tLS0tLSsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0tKworICAgICAqCisgICAgICogQSBmYWlsdXJlIGF0IHN0ZXAgMSBsZWFkcyB0byBzaW1wbGUgcmV0cnkgZHVlIHRvIGEgbG9zdCByYWNlCisgICAgICogd2l0aCBhbm90aGVyIG9wZXJhdGlvbi4gU3RlcHMgMi0zIGNhbiBmYWlsIGJlY2F1c2Ugc29tZSBvdGhlcgorICAgICAqIHRocmVhZCBub3RpY2VkIGR1cmluZyBhIHRyYXZlcnNhbCBhIG5vZGUgd2l0aCBudWxsIHZhbHVlIGFuZAorICAgICAqIGhlbHBlZCBvdXQgYnkgbWFya2luZyBhbmQvb3IgdW5saW5raW5nLiAgVGhpcyBoZWxwaW5nLW91dAorICAgICAqIGVuc3VyZXMgdGhhdCBubyB0aHJlYWQgY2FuIGJlY29tZSBzdHVjayB3YWl0aW5nIGZvciBwcm9ncmVzcyBvZgorICAgICAqIHRoZSBkZWxldGluZyB0aHJlYWQuICBUaGUgdXNlIG9mIG1hcmtlciBub2RlcyBzbGlnaHRseQorICAgICAqIGNvbXBsaWNhdGVzIGhlbHBpbmctb3V0IGNvZGUgYmVjYXVzZSB0cmF2ZXJzYWxzIG11c3QgdHJhY2sKKyAgICAgKiBjb25zaXN0ZW50IHJlYWRzIG9mIHVwIHRvIGZvdXIgbm9kZXMgKGIsIG4sIG1hcmtlciwgZiksIG5vdAorICAgICAqIGp1c3QgKGIsIG4sIGYpLCBhbHRob3VnaCB0aGUgbmV4dCBmaWVsZCBvZiBhIG1hcmtlciBpcworICAgICAqIGltbXV0YWJsZSwgYW5kIG9uY2UgYSBuZXh0IGZpZWxkIGlzIENBUydlZCB0byBwb2ludCB0byBhCisgICAgICogbWFya2VyLCBpdCBuZXZlciBhZ2FpbiBjaGFuZ2VzLCBzbyB0aGlzIHJlcXVpcmVzIGxlc3MgY2FyZS4KKyAgICAgKgorICAgICAqIFNraXAgbGlzdHMgYWRkIGluZGV4aW5nIHRvIHRoaXMgc2NoZW1lLCBzbyB0aGF0IHRoZSBiYXNlLWxldmVsCisgICAgICogdHJhdmVyc2FscyBzdGFydCBjbG9zZSB0byB0aGUgbG9jYXRpb25zIGJlaW5nIGZvdW5kLCBpbnNlcnRlZAorICAgICAqIG9yIGRlbGV0ZWQgLS0gdXN1YWxseSBiYXNlIGxldmVsIHRyYXZlcnNhbHMgb25seSB0cmF2ZXJzZSBhIGZldworICAgICAqIG5vZGVzLiBUaGlzIGRvZXNuJ3QgY2hhbmdlIHRoZSBiYXNpYyBhbGdvcml0aG0gZXhjZXB0IGZvciB0aGUKKyAgICAgKiBuZWVkIHRvIG1ha2Ugc3VyZSBiYXNlIHRyYXZlcnNhbHMgc3RhcnQgYXQgcHJlZGVjZXNzb3JzIChoZXJlLAorICAgICAqIGIpIHRoYXQgYXJlIG5vdCAoc3RydWN0dXJhbGx5KSBkZWxldGVkLCBvdGhlcndpc2UgcmV0cnlpbmcKKyAgICAgKiBhZnRlciBwcm9jZXNzaW5nIHRoZSBkZWxldGlvbi4KKyAgICAgKgorICAgICAqIEluZGV4IGxldmVscyBhcmUgbWFpbnRhaW5lZCBhcyBsaXN0cyB3aXRoIHZvbGF0aWxlIG5leHQgZmllbGRzLAorICAgICAqIHVzaW5nIENBUyB0byBsaW5rIGFuZCB1bmxpbmsuICBSYWNlcyBhcmUgYWxsb3dlZCBpbiBpbmRleC1saXN0CisgICAgICogb3BlcmF0aW9ucyB0aGF0IGNhbiAocmFyZWx5KSBmYWlsIHRvIGxpbmsgaW4gYSBuZXcgaW5kZXggbm9kZQorICAgICAqIG9yIGRlbGV0ZSBvbmUuIChXZSBjYW4ndCBkbyB0aGlzIG9mIGNvdXJzZSBmb3IgZGF0YSBub2Rlcy4pCisgICAgICogSG93ZXZlciwgZXZlbiB3aGVuIHRoaXMgaGFwcGVucywgdGhlIGluZGV4IGxpc3RzIHJlbWFpbiBzb3J0ZWQsCisgICAgICogc28gY29ycmVjdGx5IHNlcnZlIGFzIGluZGljZXMuICBUaGlzIGNhbiBpbXBhY3QgcGVyZm9ybWFuY2UsCisgICAgICogYnV0IHNpbmNlIHNraXAgbGlzdHMgYXJlIHByb2JhYmlsaXN0aWMgYW55d2F5LCB0aGUgbmV0IHJlc3VsdAorICAgICAqIGlzIHRoYXQgdW5kZXIgY29udGVudGlvbiwgdGhlIGVmZmVjdGl2ZSAicCIgdmFsdWUgbWF5IGJlIGxvd2VyCisgICAgICogdGhhbiBpdHMgbm9taW5hbCB2YWx1ZS4gQW5kIHJhY2Ugd2luZG93cyBhcmUga2VwdCBzbWFsbCBlbm91Z2gKKyAgICAgKiB0aGF0IGluIHByYWN0aWNlIHRoZXNlIGZhaWx1cmVzIGFyZSByYXJlLCBldmVuIHVuZGVyIGEgbG90IG9mCisgICAgICogY29udGVudGlvbi4KKyAgICAgKgorICAgICAqIFRoZSBmYWN0IHRoYXQgcmV0cmllcyAoZm9yIGJvdGggYmFzZSBhbmQgaW5kZXggbGlzdHMpIGFyZQorICAgICAqIHJlbGF0aXZlbHkgY2hlYXAgZHVlIHRvIGluZGV4aW5nIGFsbG93cyBzb21lIG1pbm9yCisgICAgICogc2ltcGxpZmljYXRpb25zIG9mIHJldHJ5IGxvZ2ljLiBUcmF2ZXJzYWwgcmVzdGFydHMgYXJlCisgICAgICogcGVyZm9ybWVkIGFmdGVyIG1vc3QgImhlbHBpbmctb3V0IiBDQVNlcy4gVGhpcyBpc24ndCBhbHdheXMKKyAgICAgKiBzdHJpY3RseSBuZWNlc3NhcnksIGJ1dCB0aGUgaW1wbGljaXQgYmFja29mZnMgdGVuZCB0byBoZWxwCisgICAgICogcmVkdWNlIG90aGVyIGRvd25zdHJlYW0gZmFpbGVkIENBUydzIGVub3VnaCB0byBvdXR3ZWlnaCByZXN0YXJ0CisgICAgICogY29zdC4gIFRoaXMgd29yc2VucyB0aGUgd29yc3QgY2FzZSwgYnV0IHNlZW1zIHRvIGltcHJvdmUgZXZlbgorICAgICAqIGhpZ2hseSBjb250ZW5kZWQgY2FzZXMuCisgICAgICoKKyAgICAgKiBVbmxpa2UgbW9zdCBza2lwLWxpc3QgaW1wbGVtZW50YXRpb25zLCBpbmRleCBpbnNlcnRpb24gYW5kCisgICAgICogZGVsZXRpb24gaGVyZSByZXF1aXJlIGEgc2VwYXJhdGUgdHJhdmVyc2FsIHBhc3Mgb2NjdXJpbmcgYWZ0ZXIKKyAgICAgKiB0aGUgYmFzZS1sZXZlbCBhY3Rpb24sIHRvIGFkZCBvciByZW1vdmUgaW5kZXggbm9kZXMuICBUaGlzIGFkZHMKKyAgICAgKiB0byBzaW5nbGUtdGhyZWFkZWQgb3ZlcmhlYWQsIGJ1dCBpbXByb3ZlcyBjb250ZW5kZWQKKyAgICAgKiBtdWx0aXRocmVhZGVkIHBlcmZvcm1hbmNlIGJ5IG5hcnJvd2luZyBpbnRlcmZlcmVuY2Ugd2luZG93cywKKyAgICAgKiBhbmQgYWxsb3dzIGRlbGV0aW9uIHRvIGVuc3VyZSB0aGF0IGFsbCBpbmRleCBub2RlcyB3aWxsIGJlIG1hZGUKKyAgICAgKiB1bnJlYWNoYWJsZSB1cG9uIHJldHVybiBmcm9tIGEgcHVibGljIHJlbW92ZSBvcGVyYXRpb24sIHRodXMKKyAgICAgKiBhdm9pZGluZyB1bndhbnRlZCBnYXJiYWdlIHJldGVudGlvbi4gVGhpcyBpcyBtb3JlIGltcG9ydGFudAorICAgICAqIGhlcmUgdGhhbiBpbiBzb21lIG90aGVyIGRhdGEgc3RydWN0dXJlcyBiZWNhdXNlIHdlIGNhbm5vdCBudWxsCisgICAgICogb3V0IG5vZGUgZmllbGRzIHJlZmVyZW5jaW5nIHVzZXIga2V5cyBzaW5jZSB0aGV5IG1pZ2h0IHN0aWxsIGJlCisgICAgICogcmVhZCBieSBvdGhlciBvbmdvaW5nIHRyYXZlcnNhbHMuCisgICAgICoKKyAgICAgKiBJbmRleGluZyB1c2VzIHNraXAgbGlzdCBwYXJhbWV0ZXJzIHRoYXQgbWFpbnRhaW4gZ29vZCBzZWFyY2gKKyAgICAgKiBwZXJmb3JtYW5jZSB3aGlsZSB1c2luZyBzcGFyc2VyLXRoYW4tdXN1YWwgaW5kaWNlczogVGhlCisgICAgICogaGFyZHdpcmVkIHBhcmFtZXRlcnMgaz0xLCBwPTAuNSAoc2VlIG1ldGhvZCByYW5kb21MZXZlbCkgbWVhbgorICAgICAqIHRoYXQgYWJvdXQgb25lLXF1YXJ0ZXIgb2YgdGhlIG5vZGVzIGhhdmUgaW5kaWNlcy4gT2YgdGhvc2UgdGhhdAorICAgICAqIGRvLCBoYWxmIGhhdmUgb25lIGxldmVsLCBhIHF1YXJ0ZXIgaGF2ZSB0d28sIGFuZCBzbyBvbiAoc2VlCisgICAgICogUHVnaCdzIFNraXAgTGlzdCBDb29rYm9vaywgc2VjIDMuNCkuICBUaGUgZXhwZWN0ZWQgdG90YWwgc3BhY2UKKyAgICAgKiByZXF1aXJlbWVudCBmb3IgYSBtYXAgaXMgc2xpZ2h0bHkgbGVzcyB0aGFuIGZvciB0aGUgY3VycmVudAorICAgICAqIGltcGxlbWVudGF0aW9uIG9mIGphdmEudXRpbC5UcmVlTWFwLgorICAgICAqCisgICAgICogQ2hhbmdpbmcgdGhlIGxldmVsIG9mIHRoZSBpbmRleCAoaS5lLCB0aGUgaGVpZ2h0IG9mIHRoZQorICAgICAqIHRyZWUtbGlrZSBzdHJ1Y3R1cmUpIGFsc28gdXNlcyBDQVMuIFRoZSBoZWFkIGluZGV4IGhhcyBpbml0aWFsCisgICAgICogbGV2ZWwvaGVpZ2h0IG9mIG9uZS4gQ3JlYXRpb24gb2YgYW4gaW5kZXggd2l0aCBoZWlnaHQgZ3JlYXRlcgorICAgICAqIHRoYW4gdGhlIGN1cnJlbnQgbGV2ZWwgYWRkcyBhIGxldmVsIHRvIHRoZSBoZWFkIGluZGV4IGJ5CisgICAgICogQ0FTJ2luZyBvbiBhIG5ldyB0b3AtbW9zdCBoZWFkLiBUbyBtYWludGFpbiBnb29kIHBlcmZvcm1hbmNlCisgICAgICogYWZ0ZXIgYSBsb3Qgb2YgcmVtb3ZhbHMsIGRlbGV0aW9uIG1ldGhvZHMgaGV1cmlzdGljYWxseSB0cnkgdG8KKyAgICAgKiByZWR1Y2UgdGhlIGhlaWdodCBpZiB0aGUgdG9wbW9zdCBsZXZlbHMgYXBwZWFyIHRvIGJlIGVtcHR5LgorICAgICAqIFRoaXMgbWF5IGVuY291bnRlciByYWNlcyBpbiB3aGljaCBpdCBwb3NzaWJsZSAoYnV0IHJhcmUpIHRvCisgICAgICogcmVkdWNlIGFuZCAibG9zZSIgYSBsZXZlbCBqdXN0IGFzIGl0IGlzIGFib3V0IHRvIGNvbnRhaW4gYW4KKyAgICAgKiBpbmRleCAodGhhdCB3aWxsIHRoZW4gbmV2ZXIgYmUgZW5jb3VudGVyZWQpLiBUaGlzIGRvZXMgbm8KKyAgICAgKiBzdHJ1Y3R1cmFsIGhhcm0sIGFuZCBpbiBwcmFjdGljZSBhcHBlYXJzIHRvIGJlIGEgYmV0dGVyIG9wdGlvbgorICAgICAqIHRoYW4gYWxsb3dpbmcgdW5yZXN0cmFpbmVkIGdyb3d0aCBvZiBsZXZlbHMuCisgICAgICoKKyAgICAgKiBUaGUgY29kZSBmb3IgYWxsIHRoaXMgaXMgbW9yZSB2ZXJib3NlIHRoYW4geW91J2QgbGlrZS4gTW9zdAorICAgICAqIG9wZXJhdGlvbnMgZW50YWlsIGxvY2F0aW5nIGFuIGVsZW1lbnQgKG9yIHBvc2l0aW9uIHRvIGluc2VydCBhbgorICAgICAqIGVsZW1lbnQpLiBUaGUgY29kZSB0byBkbyB0aGlzIGNhbid0IGJlIG5pY2VseSBmYWN0b3JlZCBvdXQKKyAgICAgKiBiZWNhdXNlIHN1YnNlcXVlbnQgdXNlcyByZXF1aXJlIGEgc25hcHNob3Qgb2YgcHJlZGVjZXNzb3IKKyAgICAgKiBhbmQvb3Igc3VjY2Vzc29yIGFuZC9vciB2YWx1ZSBmaWVsZHMgd2hpY2ggY2FuJ3QgYmUgcmV0dXJuZWQKKyAgICAgKiBhbGwgYXQgb25jZSwgYXQgbGVhc3Qgbm90IHdpdGhvdXQgY3JlYXRpbmcgeWV0IGFub3RoZXIgb2JqZWN0CisgICAgICogdG8gaG9sZCB0aGVtIC0tIGNyZWF0aW5nIHN1Y2ggbGl0dGxlIG9iamVjdHMgaXMgYW4gZXNwZWNpYWxseQorICAgICAqIGJhZCBpZGVhIGZvciBiYXNpYyBpbnRlcm5hbCBzZWFyY2ggb3BlcmF0aW9ucyBiZWNhdXNlIGl0IGFkZHMKKyAgICAgKiB0byBHQyBvdmVyaGVhZC4gIChUaGlzIGlzIG9uZSBvZiB0aGUgZmV3IHRpbWVzIEkndmUgd2lzaGVkIEphdmEKKyAgICAgKiBoYWQgbWFjcm9zLikgSW5zdGVhZCwgc29tZSB0cmF2ZXJzYWwgY29kZSBpcyBpbnRlcmxlYXZlZCB3aXRoaW4KKyAgICAgKiBpbnNlcnRpb24gYW5kIHJlbW92YWwgb3BlcmF0aW9ucy4gIFRoZSBjb250cm9sIGxvZ2ljIHRvIGhhbmRsZQorICAgICAqIGFsbCB0aGUgcmV0cnkgY29uZGl0aW9ucyBpcyBzb21ldGltZXMgdHdpc3R5LiBNb3N0IHNlYXJjaCBpcworICAgICAqIGJyb2tlbiBpbnRvIDIgcGFydHMuIGZpbmRQcmVkZWNlc3NvcigpIHNlYXJjaGVzIGluZGV4IG5vZGVzCisgICAgICogb25seSwgcmV0dXJuaW5nIGEgYmFzZS1sZXZlbCBwcmVkZWNlc3NvciBvZiB0aGUga2V5LiBmaW5kTm9kZSgpCisgICAgICogZmluaXNoZXMgb3V0IHRoZSBiYXNlLWxldmVsIHNlYXJjaC4gRXZlbiB3aXRoIHRoaXMgZmFjdG9yaW5nLAorICAgICAqIHRoZXJlIGlzIGEgZmFpciBhbW91bnQgb2YgbmVhci1kdXBsaWNhdGlvbiBvZiBjb2RlIHRvIGhhbmRsZQorICAgICAqIHZhcmlhbnRzLgorICAgICAqCisgICAgICogRm9yIGV4cGxhbmF0aW9uIG9mIGFsZ29yaXRobXMgc2hhcmluZyBhdCBsZWFzdCBhIGNvdXBsZSBvZgorICAgICAqIGZlYXR1cmVzIHdpdGggdGhpcyBvbmUsIHNlZSBNaWtoYWlsIEZvbWl0Y2hldidzIHRoZXNpcworICAgICAqIChodHRwOi8vd3d3LmNzLnlvcmt1LmNhL35taWtoYWlsLyksIEtlaXIgRnJhc2VyJ3MgdGhlc2lzCisgICAgICogKGh0dHA6Ly93d3cuY2wuY2FtLmFjLnVrL3VzZXJzL2thZjI0LyksIGFuZCBIYWthbiBTdW5kZWxsJ3MKKyAgICAgKiB0aGVzaXMgKGh0dHA6Ly93d3cuY3MuY2hhbG1lcnMuc2UvfnBocy8pLgorICAgICAqCisgICAgICogR2l2ZW4gdGhlIHVzZSBvZiB0cmVlLWxpa2UgaW5kZXggbm9kZXMsIHlvdSBtaWdodCB3b25kZXIgd2h5CisgICAgICogdGhpcyBkb2Vzbid0IHVzZSBzb21lIGtpbmQgb2Ygc2VhcmNoIHRyZWUgaW5zdGVhZCwgd2hpY2ggd291bGQKKyAgICAgKiBzdXBwb3J0IHNvbWV3aGF0IGZhc3RlciBzZWFyY2ggb3BlcmF0aW9ucy4gVGhlIHJlYXNvbiBpcyB0aGF0CisgICAgICogdGhlcmUgYXJlIG5vIGtub3duIGVmZmljaWVudCBsb2NrLWZyZWUgaW5zZXJ0aW9uIGFuZCBkZWxldGlvbgorICAgICAqIGFsZ29yaXRobXMgZm9yIHNlYXJjaCB0cmVlcy4gVGhlIGltbXV0YWJpbGl0eSBvZiB0aGUgImRvd24iCisgICAgICogbGlua3Mgb2YgaW5kZXggbm9kZXMgKGFzIG9wcG9zZWQgdG8gbXV0YWJsZSAibGVmdCIgZmllbGRzIGluCisgICAgICogdHJ1ZSB0cmVlcykgbWFrZXMgdGhpcyB0cmFjdGFibGUgdXNpbmcgb25seSBDQVMgb3BlcmF0aW9ucy4KKyAgICAgKgorICAgICAqIE5vdGF0aW9uIGd1aWRlIGZvciBsb2NhbCB2YXJpYWJsZXMKKyAgICAgKiBOb2RlOiAgICAgICAgIGIsIG4sIGYgICAgZm9yICBwcmVkZWNlc3Nvciwgbm9kZSwgc3VjY2Vzc29yCisgICAgICogSW5kZXg6ICAgICAgICBxLCByLCBkICAgIGZvciBpbmRleCBub2RlLCByaWdodCwgZG93bi4KKyAgICAgKiAgICAgICAgICAgICAgIHQgICAgICAgICAgZm9yIGFub3RoZXIgaW5kZXggbm9kZQorICAgICAqIEhlYWQ6ICAgICAgICAgaAorICAgICAqIExldmVsczogICAgICAgagorICAgICAqIEtleXM6ICAgICAgICAgaywga2V5CisgICAgICogVmFsdWVzOiAgICAgICB2LCB2YWx1ZQorICAgICAqIENvbXBhcmlzb25zOiAgYworICAgICAqLworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTg2MjcwNzg2NDU4OTUwNTE2MDlMOworCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIHRoZSBpbml0aWFsIHJhbmRvbSBzZWVkIGZvciB0aGUgY2hlYXBlciBwZXItaW5zdGFuY2UKKyAgICAgKiByYW5kb20gbnVtYmVyIGdlbmVyYXRvcnMgdXNlZCBpbiByYW5kb21MZXZlbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBSYW5kb20gc2VlZEdlbmVyYXRvciA9IG5ldyBSYW5kb20oKTsKKworICAgIC8qKgorICAgICAqIFNwZWNpYWwgdmFsdWUgdXNlZCB0byBpZGVudGlmeSBiYXNlLWxldmVsIGhlYWRlcgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdCBCQVNFX0hFQURFUiA9IG5ldyBPYmplY3QoKTsKKworICAgIC8qKgorICAgICAqIFRoZSB0b3Btb3N0IGhlYWQgaW5kZXggb2YgdGhlIHNraXBsaXN0LgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IHZvbGF0aWxlIEhlYWRJbmRleDxLLFY+IGhlYWQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29tcGFyYXRvciB1c2VkIHRvIG1haW50YWluIG9yZGVyIGluIHRoaXMgbWFwLCBvciBudWxsCisgICAgICogaWYgdXNpbmcgbmF0dXJhbCBvcmRlcmluZy4KKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBDb21wYXJhdG9yPD8gc3VwZXIgSz4gY29tcGFyYXRvcjsKKworICAgIC8qKgorICAgICAqIFNlZWQgZm9yIHNpbXBsZSByYW5kb20gbnVtYmVyIGdlbmVyYXRvci4gIE5vdCB2b2xhdGlsZSBzaW5jZSBpdAorICAgICAqIGRvZXNuJ3QgbWF0dGVyIHRvbyBtdWNoIGlmIGRpZmZlcmVudCB0aHJlYWRzIGRvbid0IHNlZSB1cGRhdGVzLgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IGludCByYW5kb21TZWVkOworCisgICAgLyoqIExhemlseSBpbml0aWFsaXplZCBrZXkgc2V0ICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgS2V5U2V0IGtleVNldDsKKyAgICAvKiogTGF6aWx5IGluaXRpYWxpemVkIGVudHJ5IHNldCAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IEVudHJ5U2V0IGVudHJ5U2V0OworICAgIC8qKiBMYXppbHkgaW5pdGlhbGl6ZWQgdmFsdWVzIGNvbGxlY3Rpb24gKi8KKyAgICBwcml2YXRlIHRyYW5zaWVudCBWYWx1ZXMgdmFsdWVzOworICAgIC8qKiBMYXppbHkgaW5pdGlhbGl6ZWQgZGVzY2VuZGluZyBrZXkgc2V0ICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgQ29uY3VycmVudE5hdmlnYWJsZU1hcDxLLFY+IGRlc2NlbmRpbmdNYXA7CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyBvciByZXNldHMgc3RhdGUuIE5lZWRlZCBieSBjb25zdHJ1Y3RvcnMsIGNsb25lLAorICAgICAqIGNsZWFyLCByZWFkT2JqZWN0LiBhbmQgQ29uY3VycmVudFNraXBMaXN0U2V0LmNsb25lLgorICAgICAqIChOb3RlIHRoYXQgY29tcGFyYXRvciBtdXN0IGJlIHNlcGFyYXRlbHkgaW5pdGlhbGl6ZWQuKQorICAgICAqLworICAgIGZpbmFsIHZvaWQgaW5pdGlhbGl6ZSgpIHsKKyAgICAgICAga2V5U2V0ID0gbnVsbDsKKyAgICAgICAgZW50cnlTZXQgPSBudWxsOworICAgICAgICB2YWx1ZXMgPSBudWxsOworICAgICAgICBkZXNjZW5kaW5nTWFwID0gbnVsbDsKKyAgICAgICAgcmFuZG9tU2VlZCA9IHNlZWRHZW5lcmF0b3IubmV4dEludCgpIHwgMHgwMTAwOyAvLyBlbnN1cmUgbm9uemVybworICAgICAgICBoZWFkID0gbmV3IEhlYWRJbmRleDxLLFY+KG5ldyBOb2RlPEssVj4obnVsbCwgQkFTRV9IRUFERVIsIG51bGwpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwsIDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGNvbXBhcmVBbmRTZXQgaGVhZCBub2RlCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGNhc0hlYWQoSGVhZEluZGV4PEssVj4gY21wLCBIZWFkSW5kZXg8SyxWPiB2YWwpIHsKKyAgICAgICAgcmV0dXJuIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCBoZWFkT2Zmc2V0LCBjbXAsIHZhbCk7CisgICAgfQorCisgICAgLyogLS0tLS0tLS0tLS0tLS0tLSBOb2RlcyAtLS0tLS0tLS0tLS0tLSAqLworCisgICAgLyoqCisgICAgICogTm9kZXMgaG9sZCBrZXlzIGFuZCB2YWx1ZXMsIGFuZCBhcmUgc2luZ2x5IGxpbmtlZCBpbiBzb3J0ZWQKKyAgICAgKiBvcmRlciwgcG9zc2libHkgd2l0aCBzb21lIGludGVydmVuaW5nIG1hcmtlciBub2Rlcy4gVGhlIGxpc3QgaXMKKyAgICAgKiBoZWFkZWQgYnkgYSBkdW1teSBub2RlIGFjY2Vzc2libGUgYXMgaGVhZC5ub2RlLiBUaGUgdmFsdWUgZmllbGQKKyAgICAgKiBpcyBkZWNsYXJlZCBvbmx5IGFzIE9iamVjdCBiZWNhdXNlIGl0IHRha2VzIHNwZWNpYWwgbm9uLVYKKyAgICAgKiB2YWx1ZXMgZm9yIG1hcmtlciBhbmQgaGVhZGVyIG5vZGVzLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBOb2RlPEssVj4geworICAgICAgICBmaW5hbCBLIGtleTsKKyAgICAgICAgdm9sYXRpbGUgT2JqZWN0IHZhbHVlOworICAgICAgICB2b2xhdGlsZSBOb2RlPEssVj4gbmV4dDsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBhIG5ldyByZWd1bGFyIG5vZGUuCisgICAgICAgICAqLworICAgICAgICBOb2RlKEsga2V5LCBPYmplY3QgdmFsdWUsIE5vZGU8SyxWPiBuZXh0KSB7CisgICAgICAgICAgICB0aGlzLmtleSA9IGtleTsKKyAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICAgICAgICAgIHRoaXMubmV4dCA9IG5leHQ7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBtYXJrZXIgbm9kZS4gQSBtYXJrZXIgaXMgZGlzdGluZ3Vpc2hlZCBieQorICAgICAgICAgKiBoYXZpbmcgaXRzIHZhbHVlIGZpZWxkIHBvaW50IHRvIGl0c2VsZi4gIE1hcmtlciBub2RlcyBhbHNvCisgICAgICAgICAqIGhhdmUgbnVsbCBrZXlzLCBhIGZhY3QgdGhhdCBpcyBleHBsb2l0ZWQgaW4gYSBmZXcgcGxhY2VzLAorICAgICAgICAgKiBidXQgdGhpcyBkb2Vzbid0IGRpc3Rpbmd1aXNoIG1hcmtlcnMgZnJvbSB0aGUgYmFzZS1sZXZlbAorICAgICAgICAgKiBoZWFkZXIgbm9kZSAoaGVhZC5ub2RlKSwgd2hpY2ggYWxzbyBoYXMgYSBudWxsIGtleS4KKyAgICAgICAgICovCisgICAgICAgIE5vZGUoTm9kZTxLLFY+IG5leHQpIHsKKyAgICAgICAgICAgIHRoaXMua2V5ID0gbnVsbDsKKyAgICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzOworICAgICAgICAgICAgdGhpcy5uZXh0ID0gbmV4dDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBjb21wYXJlQW5kU2V0IHZhbHVlIGZpZWxkCisgICAgICAgICAqLworICAgICAgICBib29sZWFuIGNhc1ZhbHVlKE9iamVjdCBjbXAsIE9iamVjdCB2YWwpIHsKKyAgICAgICAgICAgIHJldHVybiBVTlNBRkUuY29tcGFyZUFuZFN3YXBPYmplY3QodGhpcywgdmFsdWVPZmZzZXQsIGNtcCwgdmFsKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBjb21wYXJlQW5kU2V0IG5leHQgZmllbGQKKyAgICAgICAgICovCisgICAgICAgIGJvb2xlYW4gY2FzTmV4dChOb2RlPEssVj4gY21wLCBOb2RlPEssVj4gdmFsKSB7CisgICAgICAgICAgICByZXR1cm4gVU5TQUZFLmNvbXBhcmVBbmRTd2FwT2JqZWN0KHRoaXMsIG5leHRPZmZzZXQsIGNtcCwgdmFsKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBub2RlIGlzIGEgbWFya2VyLiBUaGlzIG1ldGhvZCBpc24ndAorICAgICAgICAgKiBhY3R1YWxseSBjYWxsZWQgaW4gYW55IGN1cnJlbnQgY29kZSBjaGVja2luZyBmb3IgbWFya2VycworICAgICAgICAgKiBiZWNhdXNlIGNhbGxlcnMgd2lsbCBoYXZlIGFscmVhZHkgcmVhZCB2YWx1ZSBmaWVsZCBhbmQgbmVlZAorICAgICAgICAgKiB0byB1c2UgdGhhdCByZWFkIChub3QgYW5vdGhlciBkb25lIGhlcmUpIGFuZCBzbyBkaXJlY3RseQorICAgICAgICAgKiB0ZXN0IGlmIHZhbHVlIHBvaW50cyB0byBub2RlLgorICAgICAgICAgKiBAcGFyYW0gbiBhIHBvc3NpYmx5IG51bGwgcmVmZXJlbmNlIHRvIGEgbm9kZQorICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBub2RlIGlzIGEgbWFya2VyIG5vZGUKKyAgICAgICAgICovCisgICAgICAgIGJvb2xlYW4gaXNNYXJrZXIoKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsdWUgPT0gdGhpczsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBub2RlIGlzIHRoZSBoZWFkZXIgb2YgYmFzZS1sZXZlbCBsaXN0LgorICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBub2RlIGlzIGhlYWRlciBub2RlCisgICAgICAgICAqLworICAgICAgICBib29sZWFuIGlzQmFzZUhlYWRlcigpIHsKKyAgICAgICAgICAgIHJldHVybiB2YWx1ZSA9PSBCQVNFX0hFQURFUjsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBUcmllcyB0byBhcHBlbmQgYSBkZWxldGlvbiBtYXJrZXIgdG8gdGhpcyBub2RlLgorICAgICAgICAgKiBAcGFyYW0gZiB0aGUgYXNzdW1lZCBjdXJyZW50IHN1Y2Nlc3NvciBvZiB0aGlzIG5vZGUKKyAgICAgICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwKKyAgICAgICAgICovCisgICAgICAgIGJvb2xlYW4gYXBwZW5kTWFya2VyKE5vZGU8SyxWPiBmKSB7CisgICAgICAgICAgICByZXR1cm4gY2FzTmV4dChmLCBuZXcgTm9kZTxLLFY+KGYpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBIZWxwcyBvdXQgYSBkZWxldGlvbiBieSBhcHBlbmRpbmcgbWFya2VyIG9yIHVubGlua2luZyBmcm9tCisgICAgICAgICAqIHByZWRlY2Vzc29yLiBUaGlzIGlzIGNhbGxlZCBkdXJpbmcgdHJhdmVyc2FscyB3aGVuIHZhbHVlCisgICAgICAgICAqIGZpZWxkIHNlZW4gdG8gYmUgbnVsbC4KKyAgICAgICAgICogQHBhcmFtIGIgcHJlZGVjZXNzb3IKKyAgICAgICAgICogQHBhcmFtIGYgc3VjY2Vzc29yCisgICAgICAgICAqLworICAgICAgICB2b2lkIGhlbHBEZWxldGUoTm9kZTxLLFY+IGIsIE5vZGU8SyxWPiBmKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogUmVjaGVja2luZyBsaW5rcyBhbmQgdGhlbiBkb2luZyBvbmx5IG9uZSBvZiB0aGUKKyAgICAgICAgICAgICAqIGhlbHAtb3V0IHN0YWdlcyBwZXIgY2FsbCB0ZW5kcyB0byBtaW5pbWl6ZSBDQVMKKyAgICAgICAgICAgICAqIGludGVyZmVyZW5jZSBhbW9uZyBoZWxwaW5nIHRocmVhZHMuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGlmIChmID09IG5leHQgJiYgdGhpcyA9PSBiLm5leHQpIHsKKyAgICAgICAgICAgICAgICBpZiAoZiA9PSBudWxsIHx8IGYudmFsdWUgIT0gZikgLy8gbm90IGFscmVhZHkgbWFya2VkCisgICAgICAgICAgICAgICAgICAgIGFwcGVuZE1hcmtlcihmKTsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIGIuY2FzTmV4dCh0aGlzLCBmLm5leHQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdmFsdWUgaWYgdGhpcyBub2RlIGNvbnRhaW5zIGEgdmFsaWQga2V5LXZhbHVlIHBhaXIsCisgICAgICAgICAqIGVsc2UgbnVsbC4KKyAgICAgICAgICogQHJldHVybiB0aGlzIG5vZGUncyB2YWx1ZSBpZiBpdCBpc24ndCBhIG1hcmtlciBvciBoZWFkZXIgb3IKKyAgICAgICAgICogaXMgZGVsZXRlZCwgZWxzZSBudWxsLgorICAgICAgICAgKi8KKyAgICAgICAgViBnZXRWYWxpZFZhbHVlKCkgeworICAgICAgICAgICAgT2JqZWN0IHYgPSB2YWx1ZTsKKyAgICAgICAgICAgIGlmICh2ID09IHRoaXMgfHwgdiA9PSBCQVNFX0hFQURFUikKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIHJldHVybiAoVil2OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENyZWF0ZXMgYW5kIHJldHVybnMgYSBuZXcgU2ltcGxlSW1tdXRhYmxlRW50cnkgaG9sZGluZyBjdXJyZW50CisgICAgICAgICAqIG1hcHBpbmcgaWYgdGhpcyBub2RlIGhvbGRzIGEgdmFsaWQgdmFsdWUsIGVsc2UgbnVsbC4KKyAgICAgICAgICogQHJldHVybiBuZXcgZW50cnkgb3IgbnVsbAorICAgICAgICAgKi8KKyAgICAgICAgQWJzdHJhY3RNYXAuU2ltcGxlSW1tdXRhYmxlRW50cnk8SyxWPiBjcmVhdGVTbmFwc2hvdCgpIHsKKyAgICAgICAgICAgIFYgdiA9IGdldFZhbGlkVmFsdWUoKTsKKyAgICAgICAgICAgIGlmICh2ID09IG51bGwpCisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICByZXR1cm4gbmV3IEFic3RyYWN0TWFwLlNpbXBsZUltbXV0YWJsZUVudHJ5PEssVj4oa2V5LCB2KTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFVuc2FmZSBtZWNoYW5pY3MKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgc3VuLm1pc2MuVW5zYWZlIFVOU0FGRSA9IHN1bi5taXNjLlVuc2FmZS5nZXRVbnNhZmUoKTsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyB2YWx1ZU9mZnNldCA9CisgICAgICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJ2YWx1ZSIsIE5vZGUuY2xhc3MpOworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIG5leHRPZmZzZXQgPQorICAgICAgICAgICAgb2JqZWN0RmllbGRPZmZzZXQoVU5TQUZFLCAibmV4dCIsIE5vZGUuY2xhc3MpOworCisgICAgfQorCisgICAgLyogLS0tLS0tLS0tLS0tLS0tLSBJbmRleGluZyAtLS0tLS0tLS0tLS0tLSAqLworCisgICAgLyoqCisgICAgICogSW5kZXggbm9kZXMgcmVwcmVzZW50IHRoZSBsZXZlbHMgb2YgdGhlIHNraXAgbGlzdC4gIE5vdGUgdGhhdAorICAgICAqIGV2ZW4gdGhvdWdoIGJvdGggTm9kZXMgYW5kIEluZGV4ZXMgaGF2ZSBmb3J3YXJkLXBvaW50aW5nCisgICAgICogZmllbGRzLCB0aGV5IGhhdmUgZGlmZmVyZW50IHR5cGVzIGFuZCBhcmUgaGFuZGxlZCBpbiBkaWZmZXJlbnQKKyAgICAgKiB3YXlzLCB0aGF0IGNhbid0IG5pY2VseSBiZSBjYXB0dXJlZCBieSBwbGFjaW5nIGZpZWxkIGluIGEKKyAgICAgKiBzaGFyZWQgYWJzdHJhY3QgY2xhc3MuCisgICAgICovCisgICAgc3RhdGljIGNsYXNzIEluZGV4PEssVj4geworICAgICAgICBmaW5hbCBOb2RlPEssVj4gbm9kZTsKKyAgICAgICAgZmluYWwgSW5kZXg8SyxWPiBkb3duOworICAgICAgICB2b2xhdGlsZSBJbmRleDxLLFY+IHJpZ2h0OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDcmVhdGVzIGluZGV4IG5vZGUgd2l0aCBnaXZlbiB2YWx1ZXMuCisgICAgICAgICAqLworICAgICAgICBJbmRleChOb2RlPEssVj4gbm9kZSwgSW5kZXg8SyxWPiBkb3duLCBJbmRleDxLLFY+IHJpZ2h0KSB7CisgICAgICAgICAgICB0aGlzLm5vZGUgPSBub2RlOworICAgICAgICAgICAgdGhpcy5kb3duID0gZG93bjsKKyAgICAgICAgICAgIHRoaXMucmlnaHQgPSByaWdodDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBjb21wYXJlQW5kU2V0IHJpZ2h0IGZpZWxkCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBib29sZWFuIGNhc1JpZ2h0KEluZGV4PEssVj4gY21wLCBJbmRleDxLLFY+IHZhbCkgeworICAgICAgICAgICAgcmV0dXJuIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCByaWdodE9mZnNldCwgY21wLCB2YWwpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgbm9kZSB0aGlzIGluZGV4ZXMgaGFzIGJlZW4gZGVsZXRlZC4KKyAgICAgICAgICogQHJldHVybiB0cnVlIGlmIGluZGV4ZWQgbm9kZSBpcyBrbm93biB0byBiZSBkZWxldGVkCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBib29sZWFuIGluZGV4ZXNEZWxldGVkTm9kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBub2RlLnZhbHVlID09IG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogVHJpZXMgdG8gQ0FTIG5ld1N1Y2MgYXMgc3VjY2Vzc29yLiAgVG8gbWluaW1pemUgcmFjZXMgd2l0aAorICAgICAgICAgKiB1bmxpbmsgdGhhdCBtYXkgbG9zZSB0aGlzIGluZGV4IG5vZGUsIGlmIHRoZSBub2RlIGJlaW5nCisgICAgICAgICAqIGluZGV4ZWQgaXMga25vd24gdG8gYmUgZGVsZXRlZCwgaXQgZG9lc24ndCB0cnkgdG8gbGluayBpbi4KKyAgICAgICAgICogQHBhcmFtIHN1Y2MgdGhlIGV4cGVjdGVkIGN1cnJlbnQgc3VjY2Vzc29yCisgICAgICAgICAqIEBwYXJhbSBuZXdTdWNjIHRoZSBuZXcgc3VjY2Vzc29yCisgICAgICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBib29sZWFuIGxpbmsoSW5kZXg8SyxWPiBzdWNjLCBJbmRleDxLLFY+IG5ld1N1Y2MpIHsKKyAgICAgICAgICAgIE5vZGU8SyxWPiBuID0gbm9kZTsKKyAgICAgICAgICAgIG5ld1N1Y2MucmlnaHQgPSBzdWNjOworICAgICAgICAgICAgcmV0dXJuIG4udmFsdWUgIT0gbnVsbCAmJiBjYXNSaWdodChzdWNjLCBuZXdTdWNjKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBUcmllcyB0byBDQVMgcmlnaHQgZmllbGQgdG8gc2tpcCBvdmVyIGFwcGFyZW50IHN1Y2Nlc3NvcgorICAgICAgICAgKiBzdWNjLiAgRmFpbHMgKGZvcmNpbmcgYSByZXRyYXZlcnNhbCBieSBjYWxsZXIpIGlmIHRoaXMgbm9kZQorICAgICAgICAgKiBpcyBrbm93biB0byBiZSBkZWxldGVkLgorICAgICAgICAgKiBAcGFyYW0gc3VjYyB0aGUgZXhwZWN0ZWQgY3VycmVudCBzdWNjZXNzb3IKKyAgICAgICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwKKyAgICAgICAgICovCisgICAgICAgIGZpbmFsIGJvb2xlYW4gdW5saW5rKEluZGV4PEssVj4gc3VjYykgeworICAgICAgICAgICAgcmV0dXJuICFpbmRleGVzRGVsZXRlZE5vZGUoKSAmJiBjYXNSaWdodChzdWNjLCBzdWNjLnJpZ2h0KTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFVuc2FmZSBtZWNoYW5pY3MKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgc3VuLm1pc2MuVW5zYWZlIFVOU0FGRSA9IHN1bi5taXNjLlVuc2FmZS5nZXRVbnNhZmUoKTsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyByaWdodE9mZnNldCA9CisgICAgICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJyaWdodCIsIEluZGV4LmNsYXNzKTsKKworICAgIH0KKworICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0gSGVhZCBub2RlcyAtLS0tLS0tLS0tLS0tLSAqLworCisgICAgLyoqCisgICAgICogTm9kZXMgaGVhZGluZyBlYWNoIGxldmVsIGtlZXAgdHJhY2sgb2YgdGhlaXIgbGV2ZWwuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIEhlYWRJbmRleDxLLFY+IGV4dGVuZHMgSW5kZXg8SyxWPiB7CisgICAgICAgIGZpbmFsIGludCBsZXZlbDsKKyAgICAgICAgSGVhZEluZGV4KE5vZGU8SyxWPiBub2RlLCBJbmRleDxLLFY+IGRvd24sIEluZGV4PEssVj4gcmlnaHQsIGludCBsZXZlbCkgeworICAgICAgICAgICAgc3VwZXIobm9kZSwgZG93biwgcmlnaHQpOworICAgICAgICAgICAgdGhpcy5sZXZlbCA9IGxldmVsOworICAgICAgICB9CisgICAgfQorCisgICAgLyogLS0tLS0tLS0tLS0tLS0tLSBDb21wYXJpc29uIHV0aWxpdGllcyAtLS0tLS0tLS0tLS0tLSAqLworCisgICAgLyoqCisgICAgICogUmVwcmVzZW50cyBhIGtleSB3aXRoIGEgY29tcGFyYXRvciBhcyBhIENvbXBhcmFibGUuCisgICAgICoKKyAgICAgKiBCZWNhdXNlIG1vc3Qgc29ydGVkIGNvbGxlY3Rpb25zIHNlZW0gdG8gdXNlIG5hdHVyYWwgb3JkZXJpbmcgb24KKyAgICAgKiBDb21wYXJhYmxlcyAoU3RyaW5ncywgSW50ZWdlcnMsIGV0YyksIG1vc3QgaW50ZXJuYWwgbWV0aG9kcyBhcmUKKyAgICAgKiBnZWFyZWQgdG8gdXNlIHRoZW0uIFRoaXMgaXMgZ2VuZXJhbGx5IGZhc3RlciB0aGFuIGNoZWNraW5nCisgICAgICogcGVyLWNvbXBhcmlzb24gd2hldGhlciB0byB1c2UgY29tcGFyYXRvciBvciBjb21wYXJhYmxlIGJlY2F1c2UKKyAgICAgKiBpdCBkb2Vzbid0IHJlcXVpcmUgYSAoQ29tcGFyYWJsZSkgY2FzdCBmb3IgZWFjaCBjb21wYXJpc29uLgorICAgICAqIChPcHRpbWl6ZXJzIGNhbiBvbmx5IHNvbWV0aW1lcyByZW1vdmUgc3VjaCByZWR1bmRhbnQgY2hlY2tzCisgICAgICogdGhlbXNlbHZlcy4pIFdoZW4gQ29tcGFyYXRvcnMgYXJlIHVzZWQsCisgICAgICogQ29tcGFyYWJsZVVzaW5nQ29tcGFyYXRvcnMgYXJlIGNyZWF0ZWQgc28gdGhhdCB0aGV5IGFjdCBpbiB0aGUKKyAgICAgKiBzYW1lIHdheSBhcyBuYXR1cmFsIG9yZGVyaW5ncy4gVGhpcyBwZW5hbGl6ZXMgdXNlIG9mCisgICAgICogQ29tcGFyYXRvcnMgdnMgQ29tcGFyYWJsZXMsIHdoaWNoIHNlZW1zIGxpa2UgdGhlIHJpZ2h0CisgICAgICogdHJhZGVvZmYuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIENvbXBhcmFibGVVc2luZ0NvbXBhcmF0b3I8Sz4gaW1wbGVtZW50cyBDb21wYXJhYmxlPEs+IHsKKyAgICAgICAgZmluYWwgSyBhY3R1YWxLZXk7CisgICAgICAgIGZpbmFsIENvbXBhcmF0b3I8PyBzdXBlciBLPiBjbXA7CisgICAgICAgIENvbXBhcmFibGVVc2luZ0NvbXBhcmF0b3IoSyBrZXksIENvbXBhcmF0b3I8PyBzdXBlciBLPiBjbXApIHsKKyAgICAgICAgICAgIHRoaXMuYWN0dWFsS2V5ID0ga2V5OworICAgICAgICAgICAgdGhpcy5jbXAgPSBjbXA7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGludCBjb21wYXJlVG8oSyBrMikgeworICAgICAgICAgICAgcmV0dXJuIGNtcC5jb21wYXJlKGFjdHVhbEtleSwgazIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgdXNpbmcgY29tcGFyYXRvciwgcmV0dXJuIGEgQ29tcGFyYWJsZVVzaW5nQ29tcGFyYXRvciwgZWxzZQorICAgICAqIGNhc3Qga2V5IGFzIENvbXBhcmFibGUsIHdoaWNoIG1heSBjYXVzZSBDbGFzc0Nhc3RFeGNlcHRpb24sCisgICAgICogd2hpY2ggaXMgcHJvcGFnYXRlZCBiYWNrIHRvIGNhbGxlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIENvbXBhcmFibGU8PyBzdXBlciBLPiBjb21wYXJhYmxlKE9iamVjdCBrZXkpCisgICAgICAgICAgICB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGlmIChjb21wYXJhdG9yICE9IG51bGwpCisgICAgICAgICAgICByZXR1cm4gbmV3IENvbXBhcmFibGVVc2luZ0NvbXBhcmF0b3I8Sz4oKEspa2V5LCBjb21wYXJhdG9yKTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcmV0dXJuIChDb21wYXJhYmxlPD8gc3VwZXIgSz4pa2V5OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHVzaW5nIGNvbXBhcmF0b3Igb3IgbmF0dXJhbCBvcmRlcmluZy4gVXNlZCB3aGVuIHRoZQorICAgICAqIENvbXBhcmFibGVVc2luZ0NvbXBhcmF0b3IgYXBwcm9hY2ggZG9lc24ndCBhcHBseS4KKyAgICAgKi8KKyAgICBpbnQgY29tcGFyZShLIGsxLCBLIGsyKSB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIHsKKyAgICAgICAgQ29tcGFyYXRvcjw/IHN1cGVyIEs+IGNtcCA9IGNvbXBhcmF0b3I7CisgICAgICAgIGlmIChjbXAgIT0gbnVsbCkKKyAgICAgICAgICAgIHJldHVybiBjbXAuY29tcGFyZShrMSwgazIpOworICAgICAgICBlbHNlCisgICAgICAgICAgICByZXR1cm4gKChDb21wYXJhYmxlPD8gc3VwZXIgSz4pazEpLmNvbXBhcmVUbyhrMik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIGdpdmVuIGtleSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gbGVhc3QgYW5kCisgICAgICogc3RyaWN0bHkgbGVzcyB0aGFuIGZlbmNlLCBieXBhc3NpbmcgZWl0aGVyIHRlc3QgaWYgbGVhc3Qgb3IKKyAgICAgKiBmZW5jZSBhcmUgbnVsbC4gTmVlZGVkIG1haW5seSBpbiBzdWJtYXAgb3BlcmF0aW9ucy4KKyAgICAgKi8KKyAgICBib29sZWFuIGluSGFsZk9wZW5SYW5nZShLIGtleSwgSyBsZWFzdCwgSyBmZW5jZSkgeworICAgICAgICBpZiAoa2V5ID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgcmV0dXJuICgobGVhc3QgPT0gbnVsbCB8fCBjb21wYXJlKGtleSwgbGVhc3QpID49IDApICYmCisgICAgICAgICAgICAgICAgKGZlbmNlID09IG51bGwgfHwgY29tcGFyZShrZXksIGZlbmNlKSA8ICAwKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIGdpdmVuIGtleSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gbGVhc3QgYW5kIGxlc3MKKyAgICAgKiBvciBlcXVhbCB0byBmZW5jZS4gTmVlZGVkIG1haW5seSBpbiBzdWJtYXAgb3BlcmF0aW9ucy4KKyAgICAgKi8KKyAgICBib29sZWFuIGluT3BlblJhbmdlKEsga2V5LCBLIGxlYXN0LCBLIGZlbmNlKSB7CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICByZXR1cm4gKChsZWFzdCA9PSBudWxsIHx8IGNvbXBhcmUoa2V5LCBsZWFzdCkgPj0gMCkgJiYKKyAgICAgICAgICAgICAgICAoZmVuY2UgPT0gbnVsbCB8fCBjb21wYXJlKGtleSwgZmVuY2UpIDw9IDApKTsKKyAgICB9CisKKyAgICAvKiAtLS0tLS0tLS0tLS0tLS0tIFRyYXZlcnNhbCAtLS0tLS0tLS0tLS0tLSAqLworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGJhc2UtbGV2ZWwgbm9kZSB3aXRoIGtleSBzdHJpY3RseSBsZXNzIHRoYW4gZ2l2ZW4ga2V5LAorICAgICAqIG9yIHRoZSBiYXNlLWxldmVsIGhlYWRlciBpZiB0aGVyZSBpcyBubyBzdWNoIG5vZGUuICBBbHNvCisgICAgICogdW5saW5rcyBpbmRleGVzIHRvIGRlbGV0ZWQgbm9kZXMgZm91bmQgYWxvbmcgdGhlIHdheS4gIENhbGxlcnMKKyAgICAgKiByZWx5IG9uIHRoaXMgc2lkZS1lZmZlY3Qgb2YgY2xlYXJpbmcgaW5kaWNlcyB0byBkZWxldGVkIG5vZGVzLgorICAgICAqIEBwYXJhbSBrZXkgdGhlIGtleQorICAgICAqIEByZXR1cm4gYSBwcmVkZWNlc3NvciBvZiBrZXkKKyAgICAgKi8KKyAgICBwcml2YXRlIE5vZGU8SyxWPiBmaW5kUHJlZGVjZXNzb3IoQ29tcGFyYWJsZTw/IHN1cGVyIEs+IGtleSkgeworICAgICAgICBpZiAoa2V5ID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgLy8gZG9uJ3QgcG9zdHBvbmUgZXJyb3JzCisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIEluZGV4PEssVj4gcSA9IGhlYWQ7CisgICAgICAgICAgICBJbmRleDxLLFY+IHIgPSBxLnJpZ2h0OworICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIGlmIChyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgTm9kZTxLLFY+IG4gPSByLm5vZGU7CisgICAgICAgICAgICAgICAgICAgIEsgayA9IG4ua2V5OworICAgICAgICAgICAgICAgICAgICBpZiAobi52YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXEudW5saW5rKHIpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOyAgICAgICAgICAgLy8gcmVzdGFydAorICAgICAgICAgICAgICAgICAgICAgICAgciA9IHEucmlnaHQ7ICAgICAgICAgLy8gcmVyZWFkIHIKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChrZXkuY29tcGFyZVRvKGspID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcSA9IHI7CisgICAgICAgICAgICAgICAgICAgICAgICByID0gci5yaWdodDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIEluZGV4PEssVj4gZCA9IHEuZG93bjsKKyAgICAgICAgICAgICAgICBpZiAoZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHEgPSBkOworICAgICAgICAgICAgICAgICAgICByID0gZC5yaWdodDsKKyAgICAgICAgICAgICAgICB9IGVsc2UKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHEubm9kZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgbm9kZSBob2xkaW5nIGtleSBvciBudWxsIGlmIG5vIHN1Y2gsIGNsZWFyaW5nIG91dCBhbnkKKyAgICAgKiBkZWxldGVkIG5vZGVzIHNlZW4gYWxvbmcgdGhlIHdheS4gIFJlcGVhdGVkbHkgdHJhdmVyc2VzIGF0CisgICAgICogYmFzZS1sZXZlbCBsb29raW5nIGZvciBrZXkgc3RhcnRpbmcgYXQgcHJlZGVjZXNzb3IgcmV0dXJuZWQKKyAgICAgKiBmcm9tIGZpbmRQcmVkZWNlc3NvciwgcHJvY2Vzc2luZyBiYXNlLWxldmVsIGRlbGV0aW9ucyBhcworICAgICAqIGVuY291bnRlcmVkLiBTb21lIGNhbGxlcnMgcmVseSBvbiB0aGlzIHNpZGUtZWZmZWN0IG9mIGNsZWFyaW5nCisgICAgICogZGVsZXRlZCBub2Rlcy4KKyAgICAgKgorICAgICAqIFJlc3RhcnRzIG9jY3VyLCBhdCB0cmF2ZXJzYWwgc3RlcCBjZW50ZXJlZCBvbiBub2RlIG4sIGlmOgorICAgICAqCisgICAgICogICAoMSkgQWZ0ZXIgcmVhZGluZyBuJ3MgbmV4dCBmaWVsZCwgbiBpcyBubyBsb25nZXIgYXNzdW1lZAorICAgICAqICAgICAgIHByZWRlY2Vzc29yIGIncyBjdXJyZW50IHN1Y2Nlc3Nvciwgd2hpY2ggbWVhbnMgdGhhdAorICAgICAqICAgICAgIHdlIGRvbid0IGhhdmUgYSBjb25zaXN0ZW50IDMtbm9kZSBzbmFwc2hvdCBhbmQgc28gY2Fubm90CisgICAgICogICAgICAgdW5saW5rIGFueSBzdWJzZXF1ZW50IGRlbGV0ZWQgbm9kZXMgZW5jb3VudGVyZWQuCisgICAgICoKKyAgICAgKiAgICgyKSBuJ3MgdmFsdWUgZmllbGQgaXMgbnVsbCwgaW5kaWNhdGluZyBuIGlzIGRlbGV0ZWQsIGluCisgICAgICogICAgICAgd2hpY2ggY2FzZSB3ZSBoZWxwIG91dCBhbiBvbmdvaW5nIHN0cnVjdHVyYWwgZGVsZXRpb24KKyAgICAgKiAgICAgICBiZWZvcmUgcmV0cnlpbmcuICBFdmVuIHRob3VnaCB0aGVyZSBhcmUgY2FzZXMgd2hlcmUgc3VjaAorICAgICAqICAgICAgIHVubGlua2luZyBkb2Vzbid0IHJlcXVpcmUgcmVzdGFydCwgdGhleSBhcmVuJ3Qgc29ydGVkIG91dAorICAgICAqICAgICAgIGhlcmUgYmVjYXVzZSBkb2luZyBzbyB3b3VsZCBub3QgdXN1YWxseSBvdXR3ZWlnaCBjb3N0IG9mCisgICAgICogICAgICAgcmVzdGFydGluZy4KKyAgICAgKgorICAgICAqICAgKDMpIG4gaXMgYSBtYXJrZXIgb3IgbidzIHByZWRlY2Vzc29yJ3MgdmFsdWUgZmllbGQgaXMgbnVsbCwKKyAgICAgKiAgICAgICBpbmRpY2F0aW5nIChhbW9uZyBvdGhlciBwb3NzaWJpbGl0aWVzKSB0aGF0CisgICAgICogICAgICAgZmluZFByZWRlY2Vzc29yIHJldHVybmVkIGEgZGVsZXRlZCBub2RlLiBXZSBjYW4ndCB1bmxpbmsKKyAgICAgKiAgICAgICB0aGUgbm9kZSBiZWNhdXNlIHdlIGRvbid0IGtub3cgaXRzIHByZWRlY2Vzc29yLCBzbyByZWx5CisgICAgICogICAgICAgb24gYW5vdGhlciBjYWxsIHRvIGZpbmRQcmVkZWNlc3NvciB0byBub3RpY2UgYW5kIHJldHVybgorICAgICAqICAgICAgIHNvbWUgZWFybGllciBwcmVkZWNlc3Nvciwgd2hpY2ggaXQgd2lsbCBkby4gVGhpcyBjaGVjayBpcworICAgICAqICAgICAgIG9ubHkgc3RyaWN0bHkgbmVlZGVkIGF0IGJlZ2lubmluZyBvZiBsb29wLCAoYW5kIHRoZQorICAgICAqICAgICAgIGIudmFsdWUgY2hlY2sgaXNuJ3Qgc3RyaWN0bHkgbmVlZGVkIGF0IGFsbCkgYnV0IGlzIGRvbmUKKyAgICAgKiAgICAgICBlYWNoIGl0ZXJhdGlvbiB0byBoZWxwIGF2b2lkIGNvbnRlbnRpb24gd2l0aCBvdGhlcgorICAgICAqICAgICAgIHRocmVhZHMgYnkgY2FsbGVycyB0aGF0IHdpbGwgZmFpbCB0byBiZSBhYmxlIHRvIGNoYW5nZQorICAgICAqICAgICAgIGxpbmtzLCBhbmQgc28gd2lsbCByZXRyeSBhbnl3YXkuCisgICAgICoKKyAgICAgKiBUaGUgdHJhdmVyc2FsIGxvb3BzIGluIGRvUHV0LCBkb1JlbW92ZSwgYW5kIGZpbmROZWFyIGFsbAorICAgICAqIGluY2x1ZGUgdGhlIHNhbWUgdGhyZWUga2luZHMgb2YgY2hlY2tzLiBBbmQgc3BlY2lhbGl6ZWQKKyAgICAgKiB2ZXJzaW9ucyBhcHBlYXIgaW4gZmluZEZpcnN0LCBhbmQgZmluZExhc3QgYW5kIHRoZWlyCisgICAgICogdmFyaWFudHMuIFRoZXkgY2FuJ3QgZWFzaWx5IHNoYXJlIGNvZGUgYmVjYXVzZSBlYWNoIHVzZXMgdGhlCisgICAgICogcmVhZHMgb2YgZmllbGRzIGhlbGQgaW4gbG9jYWxzIG9jY3VycmluZyBpbiB0aGUgb3JkZXJzIHRoZXkKKyAgICAgKiB3ZXJlIHBlcmZvcm1lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkgdGhlIGtleQorICAgICAqIEByZXR1cm4gbm9kZSBob2xkaW5nIGtleSwgb3IgbnVsbCBpZiBubyBzdWNoCisgICAgICovCisgICAgcHJpdmF0ZSBOb2RlPEssVj4gZmluZE5vZGUoQ29tcGFyYWJsZTw/IHN1cGVyIEs+IGtleSkgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBOb2RlPEssVj4gYiA9IGZpbmRQcmVkZWNlc3NvcihrZXkpOworICAgICAgICAgICAgTm9kZTxLLFY+IG4gPSBiLm5leHQ7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgaWYgKG4gPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgTm9kZTxLLFY+IGYgPSBuLm5leHQ7CisgICAgICAgICAgICAgICAgaWYgKG4gIT0gYi5uZXh0KSAgICAgICAgICAgICAgICAvLyBpbmNvbnNpc3RlbnQgcmVhZAorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBPYmplY3QgdiA9IG4udmFsdWU7CisgICAgICAgICAgICAgICAgaWYgKHYgPT0gbnVsbCkgeyAgICAgICAgICAgICAgICAvLyBuIGlzIGRlbGV0ZWQKKyAgICAgICAgICAgICAgICAgICAgbi5oZWxwRGVsZXRlKGIsIGYpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHYgPT0gbiB8fCBiLnZhbHVlID09IG51bGwpICAvLyBiIGlzIGRlbGV0ZWQKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgaW50IGMgPSBrZXkuY29tcGFyZVRvKG4ua2V5KTsKKyAgICAgICAgICAgICAgICBpZiAoYyA9PSAwKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gbjsKKyAgICAgICAgICAgICAgICBpZiAoYyA8IDApCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIGIgPSBuOworICAgICAgICAgICAgICAgIG4gPSBmOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB2YWx1ZSBmb3Iga2V5IHVzaW5nIGZpbmROb2RlLgorICAgICAqIEBwYXJhbSBva2V5IHRoZSBrZXkKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSwgb3IgbnVsbCBpZiBhYnNlbnQKKyAgICAgKi8KKyAgICBwcml2YXRlIFYgZG9HZXQoT2JqZWN0IG9rZXkpIHsKKyAgICAgICAgQ29tcGFyYWJsZTw/IHN1cGVyIEs+IGtleSA9IGNvbXBhcmFibGUob2tleSk7CisgICAgICAgIC8qCisgICAgICAgICAqIExvb3AgbmVlZGVkIGhlcmUgYW5kIGVsc2V3aGVyZSBpbiBjYXNlIHZhbHVlIGZpZWxkIGdvZXMKKyAgICAgICAgICogbnVsbCBqdXN0IGFzIGl0IGlzIGFib3V0IHRvIGJlIHJldHVybmVkLCBpbiB3aGljaCBjYXNlIHdlCisgICAgICAgICAqIGxvc3QgYSByYWNlIHdpdGggYSBkZWxldGlvbiwgc28gbXVzdCByZXRyeS4KKyAgICAgICAgICovCisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIE5vZGU8SyxWPiBuID0gZmluZE5vZGUoa2V5KTsKKyAgICAgICAgICAgIGlmIChuID09IG51bGwpCisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICBPYmplY3QgdiA9IG4udmFsdWU7CisgICAgICAgICAgICBpZiAodiAhPSBudWxsKQorICAgICAgICAgICAgICAgIHJldHVybiAoVil2OworICAgICAgICB9CisgICAgfQorCisgICAgLyogLS0tLS0tLS0tLS0tLS0tLSBJbnNlcnRpb24gLS0tLS0tLS0tLS0tLS0gKi8KKworICAgIC8qKgorICAgICAqIE1haW4gaW5zZXJ0aW9uIG1ldGhvZC4gIEFkZHMgZWxlbWVudCBpZiBub3QgcHJlc2VudCwgb3IKKyAgICAgKiByZXBsYWNlcyB2YWx1ZSBpZiBwcmVzZW50IGFuZCBvbmx5SWZBYnNlbnQgaXMgZmFsc2UuCisgICAgICogQHBhcmFtIGtrZXkgdGhlIGtleQorICAgICAqIEBwYXJhbSB2YWx1ZSAgdGhlIHZhbHVlIHRoYXQgbXVzdCBiZSBhc3NvY2lhdGVkIHdpdGgga2V5CisgICAgICogQHBhcmFtIG9ubHlJZkFic2VudCBpZiBzaG91bGQgbm90IGluc2VydCBpZiBhbHJlYWR5IHByZXNlbnQKKyAgICAgKiBAcmV0dXJuIHRoZSBvbGQgdmFsdWUsIG9yIG51bGwgaWYgbmV3bHkgaW5zZXJ0ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIFYgZG9QdXQoSyBra2V5LCBWIHZhbHVlLCBib29sZWFuIG9ubHlJZkFic2VudCkgeworICAgICAgICBDb21wYXJhYmxlPD8gc3VwZXIgSz4ga2V5ID0gY29tcGFyYWJsZShra2V5KTsKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgTm9kZTxLLFY+IGIgPSBmaW5kUHJlZGVjZXNzb3Ioa2V5KTsKKyAgICAgICAgICAgIE5vZGU8SyxWPiBuID0gYi5uZXh0OworICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIGlmIChuICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgTm9kZTxLLFY+IGYgPSBuLm5leHQ7CisgICAgICAgICAgICAgICAgICAgIGlmIChuICE9IGIubmV4dCkgICAgICAgICAgICAgICAvLyBpbmNvbnNpc3RlbnQgcmVhZAorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIE9iamVjdCB2ID0gbi52YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHYgPT0gbnVsbCkgeyAgICAgICAgICAgICAgIC8vIG4gaXMgZGVsZXRlZAorICAgICAgICAgICAgICAgICAgICAgICAgbi5oZWxwRGVsZXRlKGIsIGYpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKHYgPT0gbiB8fCBiLnZhbHVlID09IG51bGwpIC8vIGIgaXMgZGVsZXRlZAorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGludCBjID0ga2V5LmNvbXBhcmVUbyhuLmtleSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChjID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgYiA9IG47CisgICAgICAgICAgICAgICAgICAgICAgICBuID0gZjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChjID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbmx5SWZBYnNlbnQgfHwgbi5jYXNWYWx1ZSh2LCB2YWx1ZSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChWKXY7CisgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7IC8vIHJlc3RhcnQgaWYgbG9zdCByYWNlIHRvIHJlcGxhY2UgdmFsdWUKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAvLyBlbHNlIGMgPCAwOyBmYWxsIHRocm91Z2gKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBOb2RlPEssVj4geiA9IG5ldyBOb2RlPEssVj4oa2tleSwgdmFsdWUsIG4pOworICAgICAgICAgICAgICAgIGlmICghYi5jYXNOZXh0KG4sIHopKQorICAgICAgICAgICAgICAgICAgICBicmVhazsgICAgICAgICAvLyByZXN0YXJ0IGlmIGxvc3QgcmFjZSB0byBhcHBlbmQgdG8gYgorICAgICAgICAgICAgICAgIGludCBsZXZlbCA9IHJhbmRvbUxldmVsKCk7CisgICAgICAgICAgICAgICAgaWYgKGxldmVsID4gMCkKKyAgICAgICAgICAgICAgICAgICAgaW5zZXJ0SW5kZXgoeiwgbGV2ZWwpOworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHJhbmRvbSBsZXZlbCBmb3IgaW5zZXJ0aW5nIGEgbmV3IG5vZGUuCisgICAgICogSGFyZHdpcmVkIHRvIGs9MSwgcD0wLjUsIG1heCAzMSAoc2VlIGFib3ZlIGFuZAorICAgICAqIFB1Z2gncyAiU2tpcCBMaXN0IENvb2tib29rIiwgc2VjIDMuNCkuCisgICAgICoKKyAgICAgKiBUaGlzIHVzZXMgdGhlIHNpbXBsZXN0IG9mIHRoZSBnZW5lcmF0b3JzIGRlc2NyaWJlZCBpbiBHZW9yZ2UKKyAgICAgKiBNYXJzYWdsaWEncyAiWG9yc2hpZnQgUk5HcyIgcGFwZXIuICBUaGlzIGlzIG5vdCBhIGhpZ2gtcXVhbGl0eQorICAgICAqIGdlbmVyYXRvciBidXQgaXMgYWNjZXB0YWJsZSBoZXJlLgorICAgICAqLworICAgIHByaXZhdGUgaW50IHJhbmRvbUxldmVsKCkgeworICAgICAgICBpbnQgeCA9IHJhbmRvbVNlZWQ7CisgICAgICAgIHggXj0geCA8PCAxMzsKKyAgICAgICAgeCBePSB4ID4+PiAxNzsKKyAgICAgICAgcmFuZG9tU2VlZCA9IHggXj0geCA8PCA1OworICAgICAgICBpZiAoKHggJiAweDgwMDAwMDAxKSAhPSAwKSAvLyB0ZXN0IGhpZ2hlc3QgYW5kIGxvd2VzdCBiaXRzCisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgaW50IGxldmVsID0gMTsKKyAgICAgICAgd2hpbGUgKCgoeCA+Pj49IDEpICYgMSkgIT0gMCkgKytsZXZlbDsKKyAgICAgICAgcmV0dXJuIGxldmVsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW5kIGFkZHMgaW5kZXggbm9kZXMgZm9yIHRoZSBnaXZlbiBub2RlLgorICAgICAqIEBwYXJhbSB6IHRoZSBub2RlCisgICAgICogQHBhcmFtIGxldmVsIHRoZSBsZXZlbCBvZiB0aGUgaW5kZXgKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5zZXJ0SW5kZXgoTm9kZTxLLFY+IHosIGludCBsZXZlbCkgeworICAgICAgICBIZWFkSW5kZXg8SyxWPiBoID0gaGVhZDsKKyAgICAgICAgaW50IG1heCA9IGgubGV2ZWw7CisKKyAgICAgICAgaWYgKGxldmVsIDw9IG1heCkgeworICAgICAgICAgICAgSW5kZXg8SyxWPiBpZHggPSBudWxsOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gbGV2ZWw7ICsraSkKKyAgICAgICAgICAgICAgICBpZHggPSBuZXcgSW5kZXg8SyxWPih6LCBpZHgsIG51bGwpOworICAgICAgICAgICAgYWRkSW5kZXgoaWR4LCBoLCBsZXZlbCk7CisKKyAgICAgICAgfSBlbHNlIHsgLy8gQWRkIGEgbmV3IGxldmVsCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogVG8gcmVkdWNlIGludGVyZmVyZW5jZSBieSBvdGhlciB0aHJlYWRzIGNoZWNraW5nIGZvcgorICAgICAgICAgICAgICogZW1wdHkgbGV2ZWxzIGluIHRyeVJlZHVjZUxldmVsLCBuZXcgbGV2ZWxzIGFyZSBhZGRlZAorICAgICAgICAgICAgICogd2l0aCBpbml0aWFsaXplZCByaWdodCBwb2ludGVycy4gV2hpY2ggaW4gdHVybiByZXF1aXJlcworICAgICAgICAgICAgICoga2VlcGluZyBsZXZlbHMgaW4gYW4gYXJyYXkgdG8gYWNjZXNzIHRoZW0gd2hpbGUKKyAgICAgICAgICAgICAqIGNyZWF0aW5nIG5ldyBoZWFkIGluZGV4IG5vZGVzIGZyb20gdGhlIG9wcG9zaXRlCisgICAgICAgICAgICAgKiBkaXJlY3Rpb24uCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGxldmVsID0gbWF4ICsgMTsKKyAgICAgICAgICAgIEluZGV4PEssVj5bXSBpZHhzID0gKEluZGV4PEssVj5bXSluZXcgSW5kZXhbbGV2ZWwrMV07CisgICAgICAgICAgICBJbmRleDxLLFY+IGlkeCA9IG51bGw7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBsZXZlbDsgKytpKQorICAgICAgICAgICAgICAgIGlkeHNbaV0gPSBpZHggPSBuZXcgSW5kZXg8SyxWPih6LCBpZHgsIG51bGwpOworCisgICAgICAgICAgICBIZWFkSW5kZXg8SyxWPiBvbGRoOworICAgICAgICAgICAgaW50IGs7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgb2xkaCA9IGhlYWQ7CisgICAgICAgICAgICAgICAgaW50IG9sZExldmVsID0gb2xkaC5sZXZlbDsKKyAgICAgICAgICAgICAgICBpZiAobGV2ZWwgPD0gb2xkTGV2ZWwpIHsgLy8gbG9zdCByYWNlIHRvIGFkZCBsZXZlbAorICAgICAgICAgICAgICAgICAgICBrID0gbGV2ZWw7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBIZWFkSW5kZXg8SyxWPiBuZXdoID0gb2xkaDsKKyAgICAgICAgICAgICAgICBOb2RlPEssVj4gb2xkYmFzZSA9IG9sZGgubm9kZTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gb2xkTGV2ZWwrMTsgaiA8PSBsZXZlbDsgKytqKQorICAgICAgICAgICAgICAgICAgICBuZXdoID0gbmV3IEhlYWRJbmRleDxLLFY+KG9sZGJhc2UsIG5ld2gsIGlkeHNbal0sIGopOworICAgICAgICAgICAgICAgIGlmIChjYXNIZWFkKG9sZGgsIG5ld2gpKSB7CisgICAgICAgICAgICAgICAgICAgIGsgPSBvbGRMZXZlbDsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYWRkSW5kZXgoaWR4c1trXSwgb2xkaCwgayk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGdpdmVuIGluZGV4IG5vZGVzIGZyb20gZ2l2ZW4gbGV2ZWwgZG93biB0byAxLgorICAgICAqIEBwYXJhbSBpZHggdGhlIHRvcG1vc3QgaW5kZXggbm9kZSBiZWluZyBpbnNlcnRlZAorICAgICAqIEBwYXJhbSBoIHRoZSB2YWx1ZSBvZiBoZWFkIHRvIHVzZSB0byBpbnNlcnQuIFRoaXMgbXVzdCBiZQorICAgICAqIHNuYXBzaG90dGVkIGJ5IGNhbGxlcnMgdG8gcHJvdmlkZSBjb3JyZWN0IGluc2VydGlvbiBsZXZlbAorICAgICAqIEBwYXJhbSBpbmRleExldmVsIHRoZSBsZXZlbCBvZiB0aGUgaW5kZXgKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYWRkSW5kZXgoSW5kZXg8SyxWPiBpZHgsIEhlYWRJbmRleDxLLFY+IGgsIGludCBpbmRleExldmVsKSB7CisgICAgICAgIC8vIFRyYWNrIG5leHQgbGV2ZWwgdG8gaW5zZXJ0IGluIGNhc2Ugb2YgcmV0cmllcworICAgICAgICBpbnQgaW5zZXJ0aW9uTGV2ZWwgPSBpbmRleExldmVsOworICAgICAgICBDb21wYXJhYmxlPD8gc3VwZXIgSz4ga2V5ID0gY29tcGFyYWJsZShpZHgubm9kZS5rZXkpOworICAgICAgICBpZiAoa2V5ID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworCisgICAgICAgIC8vIFNpbWlsYXIgdG8gZmluZFByZWRlY2Vzc29yLCBidXQgYWRkaW5nIGluZGV4IG5vZGVzIGFsb25nCisgICAgICAgIC8vIHBhdGggdG8ga2V5LgorICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBpbnQgaiA9IGgubGV2ZWw7CisgICAgICAgICAgICBJbmRleDxLLFY+IHEgPSBoOworICAgICAgICAgICAgSW5kZXg8SyxWPiByID0gcS5yaWdodDsKKyAgICAgICAgICAgIEluZGV4PEssVj4gdCA9IGlkeDsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBpZiAociAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIE5vZGU8SyxWPiBuID0gci5ub2RlOworICAgICAgICAgICAgICAgICAgICAvLyBjb21wYXJlIGJlZm9yZSBkZWxldGlvbiBjaGVjayBhdm9pZHMgbmVlZGluZyByZWNoZWNrCisgICAgICAgICAgICAgICAgICAgIGludCBjID0ga2V5LmNvbXBhcmVUbyhuLmtleSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChuLnZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcS51bmxpbmsocikpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICByID0gcS5yaWdodDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChjID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcSA9IHI7CisgICAgICAgICAgICAgICAgICAgICAgICByID0gci5yaWdodDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGogPT0gaW5zZXJ0aW9uTGV2ZWwpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gRG9uJ3QgaW5zZXJ0IGluZGV4IGlmIG5vZGUgYWxyZWFkeSBkZWxldGVkCisgICAgICAgICAgICAgICAgICAgIGlmICh0LmluZGV4ZXNEZWxldGVkTm9kZSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmaW5kTm9kZShrZXkpOyAvLyBjbGVhbnMgdXAKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoIXEubGluayhyLCB0KSkKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOyAvLyByZXN0YXJ0CisgICAgICAgICAgICAgICAgICAgIGlmICgtLWluc2VydGlvbkxldmVsID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5lZWQgZmluYWwgZGVsZXRpb24gY2hlY2sgYmVmb3JlIHJldHVybgorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHQuaW5kZXhlc0RlbGV0ZWROb2RlKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluZE5vZGUoa2V5KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmICgtLWogPj0gaW5zZXJ0aW9uTGV2ZWwgJiYgaiA8IGluZGV4TGV2ZWwpCisgICAgICAgICAgICAgICAgICAgIHQgPSB0LmRvd247CisgICAgICAgICAgICAgICAgcSA9IHEuZG93bjsKKyAgICAgICAgICAgICAgICByID0gcS5yaWdodDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0gRGVsZXRpb24gLS0tLS0tLS0tLS0tLS0gKi8KKworICAgIC8qKgorICAgICAqIE1haW4gZGVsZXRpb24gbWV0aG9kLiBMb2NhdGVzIG5vZGUsIG51bGxzIHZhbHVlLCBhcHBlbmRzIGEKKyAgICAgKiBkZWxldGlvbiBtYXJrZXIsIHVubGlua3MgcHJlZGVjZXNzb3IsIHJlbW92ZXMgYXNzb2NpYXRlZCBpbmRleAorICAgICAqIG5vZGVzLCBhbmQgcG9zc2libHkgcmVkdWNlcyBoZWFkIGluZGV4IGxldmVsLgorICAgICAqCisgICAgICogSW5kZXggbm9kZXMgYXJlIGNsZWFyZWQgb3V0IHNpbXBseSBieSBjYWxsaW5nIGZpbmRQcmVkZWNlc3Nvci4KKyAgICAgKiB3aGljaCB1bmxpbmtzIGluZGV4ZXMgdG8gZGVsZXRlZCBub2RlcyBmb3VuZCBhbG9uZyBwYXRoIHRvIGtleSwKKyAgICAgKiB3aGljaCB3aWxsIGluY2x1ZGUgdGhlIGluZGV4ZXMgdG8gdGhpcyBub2RlLiAgVGhpcyBpcyBkb25lCisgICAgICogdW5jb25kaXRpb25hbGx5LiBXZSBjYW4ndCBjaGVjayBiZWZvcmVoYW5kIHdoZXRoZXIgdGhlcmUgYXJlCisgICAgICogaW5kZXggbm9kZXMgYmVjYXVzZSBpdCBtaWdodCBiZSB0aGUgY2FzZSB0aGF0IHNvbWUgb3IgYWxsCisgICAgICogaW5kZXhlcyBoYWRuJ3QgYmVlbiBpbnNlcnRlZCB5ZXQgZm9yIHRoaXMgbm9kZSBkdXJpbmcgaW5pdGlhbAorICAgICAqIHNlYXJjaCBmb3IgaXQsIGFuZCB3ZSdkIGxpa2UgdG8gZW5zdXJlIGxhY2sgb2YgZ2FyYmFnZQorICAgICAqIHJldGVudGlvbiwgc28gbXVzdCBjYWxsIHRvIGJlIHN1cmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2tleSB0aGUga2V5CisgICAgICogQHBhcmFtIHZhbHVlIGlmIG5vbi1udWxsLCB0aGUgdmFsdWUgdGhhdCBtdXN0IGJlCisgICAgICogYXNzb2NpYXRlZCB3aXRoIGtleQorICAgICAqIEByZXR1cm4gdGhlIG5vZGUsIG9yIG51bGwgaWYgbm90IGZvdW5kCisgICAgICovCisgICAgZmluYWwgViBkb1JlbW92ZShPYmplY3Qgb2tleSwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIENvbXBhcmFibGU8PyBzdXBlciBLPiBrZXkgPSBjb21wYXJhYmxlKG9rZXkpOworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBOb2RlPEssVj4gYiA9IGZpbmRQcmVkZWNlc3NvcihrZXkpOworICAgICAgICAgICAgTm9kZTxLLFY+IG4gPSBiLm5leHQ7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgaWYgKG4gPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgTm9kZTxLLFY+IGYgPSBuLm5leHQ7CisgICAgICAgICAgICAgICAgaWYgKG4gIT0gYi5uZXh0KSAgICAgICAgICAgICAgICAgICAgLy8gaW5jb25zaXN0ZW50IHJlYWQKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgT2JqZWN0IHYgPSBuLnZhbHVlOworICAgICAgICAgICAgICAgIGlmICh2ID09IG51bGwpIHsgICAgICAgICAgICAgICAgICAgIC8vIG4gaXMgZGVsZXRlZAorICAgICAgICAgICAgICAgICAgICBuLmhlbHBEZWxldGUoYiwgZik7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAodiA9PSBuIHx8IGIudmFsdWUgPT0gbnVsbCkgICAgICAvLyBiIGlzIGRlbGV0ZWQKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgaW50IGMgPSBrZXkuY29tcGFyZVRvKG4ua2V5KTsKKyAgICAgICAgICAgICAgICBpZiAoYyA8IDApCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIGlmIChjID4gMCkgeworICAgICAgICAgICAgICAgICAgICBiID0gbjsKKyAgICAgICAgICAgICAgICAgICAgbiA9IGY7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCAmJiAhdmFsdWUuZXF1YWxzKHYpKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICBpZiAoIW4uY2FzVmFsdWUodiwgbnVsbCkpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGlmICghbi5hcHBlbmRNYXJrZXIoZikgfHwgIWIuY2FzTmV4dChuLCBmKSkKKyAgICAgICAgICAgICAgICAgICAgZmluZE5vZGUoa2V5KTsgICAgICAgICAgICAgICAgICAvLyBSZXRyeSB2aWEgZmluZE5vZGUKKyAgICAgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZmluZFByZWRlY2Vzc29yKGtleSk7ICAgICAgICAgICAvLyBDbGVhbiBpbmRleAorICAgICAgICAgICAgICAgICAgICBpZiAoaGVhZC5yaWdodCA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgdHJ5UmVkdWNlTGV2ZWwoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIChWKXY7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQb3NzaWJseSByZWR1Y2UgaGVhZCBsZXZlbCBpZiBpdCBoYXMgbm8gbm9kZXMuICBUaGlzIG1ldGhvZCBjYW4KKyAgICAgKiAocmFyZWx5KSBtYWtlIG1pc3Rha2VzLCBpbiB3aGljaCBjYXNlIGxldmVscyBjYW4gZGlzYXBwZWFyIGV2ZW4KKyAgICAgKiB0aG91Z2ggdGhleSBhcmUgYWJvdXQgdG8gY29udGFpbiBpbmRleCBub2Rlcy4gVGhpcyBpbXBhY3RzCisgICAgICogcGVyZm9ybWFuY2UsIG5vdCBjb3JyZWN0bmVzcy4gIFRvIG1pbmltaXplIG1pc3Rha2VzIGFzIHdlbGwgYXMKKyAgICAgKiB0byByZWR1Y2UgaHlzdGVyZXNpcywgdGhlIGxldmVsIGlzIHJlZHVjZWQgYnkgb25lIG9ubHkgaWYgdGhlCisgICAgICogdG9wbW9zdCB0aHJlZSBsZXZlbHMgbG9vayBlbXB0eS4gQWxzbywgaWYgdGhlIHJlbW92ZWQgbGV2ZWwKKyAgICAgKiBsb29rcyBub24tZW1wdHkgYWZ0ZXIgQ0FTLCB3ZSB0cnkgdG8gY2hhbmdlIGl0IGJhY2sgcXVpY2sKKyAgICAgKiBiZWZvcmUgYW55b25lIG5vdGljZXMgb3VyIG1pc3Rha2UhIChUaGlzIHRyaWNrIHdvcmtzIHByZXR0eQorICAgICAqIHdlbGwgYmVjYXVzZSB0aGlzIG1ldGhvZCB3aWxsIHByYWN0aWNhbGx5IG5ldmVyIG1ha2UgbWlzdGFrZXMKKyAgICAgKiB1bmxlc3MgY3VycmVudCB0aHJlYWQgc3RhbGxzIGltbWVkaWF0ZWx5IGJlZm9yZSBmaXJzdCBDQVMsIGluCisgICAgICogd2hpY2ggY2FzZSBpdCBpcyB2ZXJ5IHVubGlrZWx5IHRvIHN0YWxsIGFnYWluIGltbWVkaWF0ZWx5CisgICAgICogYWZ0ZXJ3YXJkcywgc28gd2lsbCByZWNvdmVyLikKKyAgICAgKgorICAgICAqIFdlIHB1dCB1cCB3aXRoIGFsbCB0aGlzIHJhdGhlciB0aGFuIGp1c3QgbGV0IGxldmVscyBncm93CisgICAgICogYmVjYXVzZSBvdGhlcndpc2UsIGV2ZW4gYSBzbWFsbCBtYXAgdGhhdCBoYXMgdW5kZXJnb25lIGEgbGFyZ2UKKyAgICAgKiBudW1iZXIgb2YgaW5zZXJ0aW9ucyBhbmQgcmVtb3ZhbHMgd2lsbCBoYXZlIGEgbG90IG9mIGxldmVscywKKyAgICAgKiBzbG93aW5nIGRvd24gYWNjZXNzIG1vcmUgdGhhbiB3b3VsZCBhbiBvY2Nhc2lvbmFsIHVud2FudGVkCisgICAgICogcmVkdWN0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB0cnlSZWR1Y2VMZXZlbCgpIHsKKyAgICAgICAgSGVhZEluZGV4PEssVj4gaCA9IGhlYWQ7CisgICAgICAgIEhlYWRJbmRleDxLLFY+IGQ7CisgICAgICAgIEhlYWRJbmRleDxLLFY+IGU7CisgICAgICAgIGlmIChoLmxldmVsID4gMyAmJgorICAgICAgICAgICAgKGQgPSAoSGVhZEluZGV4PEssVj4paC5kb3duKSAhPSBudWxsICYmCisgICAgICAgICAgICAoZSA9IChIZWFkSW5kZXg8SyxWPilkLmRvd24pICE9IG51bGwgJiYKKyAgICAgICAgICAgIGUucmlnaHQgPT0gbnVsbCAmJgorICAgICAgICAgICAgZC5yaWdodCA9PSBudWxsICYmCisgICAgICAgICAgICBoLnJpZ2h0ID09IG51bGwgJiYKKyAgICAgICAgICAgIGNhc0hlYWQoaCwgZCkgJiYgLy8gdHJ5IHRvIHNldAorICAgICAgICAgICAgaC5yaWdodCAhPSBudWxsKSAvLyByZWNoZWNrCisgICAgICAgICAgICBjYXNIZWFkKGQsIGgpOyAgIC8vIHRyeSB0byBiYWNrb3V0CisgICAgfQorCisgICAgLyogLS0tLS0tLS0tLS0tLS0tLSBGaW5kaW5nIGFuZCByZW1vdmluZyBmaXJzdCBlbGVtZW50IC0tLS0tLS0tLS0tLS0tICovCisKKyAgICAvKioKKyAgICAgKiBTcGVjaWFsaXplZCB2YXJpYW50IG9mIGZpbmROb2RlIHRvIGdldCBmaXJzdCB2YWxpZCBub2RlLgorICAgICAqIEByZXR1cm4gZmlyc3Qgbm9kZSBvciBudWxsIGlmIGVtcHR5CisgICAgICovCisgICAgTm9kZTxLLFY+IGZpbmRGaXJzdCgpIHsKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgTm9kZTxLLFY+IGIgPSBoZWFkLm5vZGU7CisgICAgICAgICAgICBOb2RlPEssVj4gbiA9IGIubmV4dDsKKyAgICAgICAgICAgIGlmIChuID09IG51bGwpCisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICBpZiAobi52YWx1ZSAhPSBudWxsKQorICAgICAgICAgICAgICAgIHJldHVybiBuOworICAgICAgICAgICAgbi5oZWxwRGVsZXRlKGIsIG4ubmV4dCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGZpcnN0IGVudHJ5OyByZXR1cm5zIGl0cyBzbmFwc2hvdC4KKyAgICAgKiBAcmV0dXJuIG51bGwgaWYgZW1wdHksIGVsc2Ugc25hcHNob3Qgb2YgZmlyc3QgZW50cnkKKyAgICAgKi8KKyAgICBNYXAuRW50cnk8SyxWPiBkb1JlbW92ZUZpcnN0RW50cnkoKSB7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIE5vZGU8SyxWPiBiID0gaGVhZC5ub2RlOworICAgICAgICAgICAgTm9kZTxLLFY+IG4gPSBiLm5leHQ7CisgICAgICAgICAgICBpZiAobiA9PSBudWxsKQorICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgTm9kZTxLLFY+IGYgPSBuLm5leHQ7CisgICAgICAgICAgICBpZiAobiAhPSBiLm5leHQpCisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICBPYmplY3QgdiA9IG4udmFsdWU7CisgICAgICAgICAgICBpZiAodiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgbi5oZWxwRGVsZXRlKGIsIGYpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFuLmNhc1ZhbHVlKHYsIG51bGwpKQorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgaWYgKCFuLmFwcGVuZE1hcmtlcihmKSB8fCAhYi5jYXNOZXh0KG4sIGYpKQorICAgICAgICAgICAgICAgIGZpbmRGaXJzdCgpOyAvLyByZXRyeQorICAgICAgICAgICAgY2xlYXJJbmRleFRvRmlyc3QoKTsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQWJzdHJhY3RNYXAuU2ltcGxlSW1tdXRhYmxlRW50cnk8SyxWPihuLmtleSwgKFYpdik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbGVhcnMgb3V0IGluZGV4IG5vZGVzIGFzc29jaWF0ZWQgd2l0aCBkZWxldGVkIGZpcnN0IGVudHJ5LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjbGVhckluZGV4VG9GaXJzdCgpIHsKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgSW5kZXg8SyxWPiBxID0gaGVhZDsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBJbmRleDxLLFY+IHIgPSBxLnJpZ2h0OworICAgICAgICAgICAgICAgIGlmIChyICE9IG51bGwgJiYgci5pbmRleGVzRGVsZXRlZE5vZGUoKSAmJiAhcS51bmxpbmsocikpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGlmICgocSA9IHEuZG93bikgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoaGVhZC5yaWdodCA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgdHJ5UmVkdWNlTGV2ZWwoKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworCisgICAgLyogLS0tLS0tLS0tLS0tLS0tLSBGaW5kaW5nIGFuZCByZW1vdmluZyBsYXN0IGVsZW1lbnQgLS0tLS0tLS0tLS0tLS0gKi8KKworICAgIC8qKgorICAgICAqIFNwZWNpYWxpemVkIHZlcnNpb24gb2YgZmluZCB0byBnZXQgbGFzdCB2YWxpZCBub2RlLgorICAgICAqIEByZXR1cm4gbGFzdCBub2RlIG9yIG51bGwgaWYgZW1wdHkKKyAgICAgKi8KKyAgICBOb2RlPEssVj4gZmluZExhc3QoKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIGZpbmRQcmVkZWNlc3NvciBjYW4ndCBiZSB1c2VkIHRvIHRyYXZlcnNlIGluZGV4IGxldmVsCisgICAgICAgICAqIGJlY2F1c2UgdGhpcyBkb2Vzbid0IHVzZSBjb21wYXJpc29ucy4gIFNvIHRyYXZlcnNhbHMgb2YKKyAgICAgICAgICogYm90aCBsZXZlbHMgYXJlIGZvbGRlZCB0b2dldGhlci4KKyAgICAgICAgICovCisgICAgICAgIEluZGV4PEssVj4gcSA9IGhlYWQ7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIEluZGV4PEssVj4gZCwgcjsKKyAgICAgICAgICAgIGlmICgociA9IHEucmlnaHQpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZiAoci5pbmRleGVzRGVsZXRlZE5vZGUoKSkgeworICAgICAgICAgICAgICAgICAgICBxLnVubGluayhyKTsKKyAgICAgICAgICAgICAgICAgICAgcSA9IGhlYWQ7IC8vIHJlc3RhcnQKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBxID0gcjsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoKGQgPSBxLmRvd24pICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBxID0gZDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgTm9kZTxLLFY+IGIgPSBxLm5vZGU7CisgICAgICAgICAgICAgICAgTm9kZTxLLFY+IG4gPSBiLm5leHQ7CisgICAgICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgICAgICBpZiAobiA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGIuaXNCYXNlSGVhZGVyKCkgPyBudWxsIDogYjsKKyAgICAgICAgICAgICAgICAgICAgTm9kZTxLLFY+IGYgPSBuLm5leHQ7ICAgICAgICAgICAgLy8gaW5jb25zaXN0ZW50IHJlYWQKKyAgICAgICAgICAgICAgICAgICAgaWYgKG4gIT0gYi5uZXh0KQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIE9iamVjdCB2ID0gbi52YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHYgPT0gbnVsbCkgeyAgICAgICAgICAgICAgICAgLy8gbiBpcyBkZWxldGVkCisgICAgICAgICAgICAgICAgICAgICAgICBuLmhlbHBEZWxldGUoYiwgZik7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAodiA9PSBuIHx8IGIudmFsdWUgPT0gbnVsbCkgICAvLyBiIGlzIGRlbGV0ZWQKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBiID0gbjsKKyAgICAgICAgICAgICAgICAgICAgbiA9IGY7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHEgPSBoZWFkOyAvLyByZXN0YXJ0CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWFsaXplZCB2YXJpYW50IG9mIGZpbmRQcmVkZWNlc3NvciB0byBnZXQgcHJlZGVjZXNzb3Igb2YgbGFzdAorICAgICAqIHZhbGlkIG5vZGUuICBOZWVkZWQgd2hlbiByZW1vdmluZyB0aGUgbGFzdCBlbnRyeS4gIEl0IGlzIHBvc3NpYmxlCisgICAgICogdGhhdCBhbGwgc3VjY2Vzc29ycyBvZiByZXR1cm5lZCBub2RlIHdpbGwgaGF2ZSBiZWVuIGRlbGV0ZWQgdXBvbgorICAgICAqIHJldHVybiwgaW4gd2hpY2ggY2FzZSB0aGlzIG1ldGhvZCBjYW4gYmUgcmV0cmllZC4KKyAgICAgKiBAcmV0dXJuIGxpa2VseSBwcmVkZWNlc3NvciBvZiBsYXN0IG5vZGUKKyAgICAgKi8KKyAgICBwcml2YXRlIE5vZGU8SyxWPiBmaW5kUHJlZGVjZXNzb3JPZkxhc3QoKSB7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIEluZGV4PEssVj4gcSA9IGhlYWQ7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgSW5kZXg8SyxWPiBkLCByOworICAgICAgICAgICAgICAgIGlmICgociA9IHEucmlnaHQpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHIuaW5kZXhlc0RlbGV0ZWROb2RlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHEudW5saW5rKHIpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7ICAgIC8vIG11c3QgcmVzdGFydAorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8vIHByb2NlZWQgYXMgZmFyIGFjcm9zcyBhcyBwb3NzaWJsZSB3aXRob3V0IG92ZXJzaG9vdGluZworICAgICAgICAgICAgICAgICAgICBpZiAoci5ub2RlLm5leHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcSA9IHI7CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoKGQgPSBxLmRvd24pICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIHEgPSBkOworICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHEubm9kZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgbGFzdCBlbnRyeTsgcmV0dXJucyBpdHMgc25hcHNob3QuCisgICAgICogU3BlY2lhbGl6ZWQgdmFyaWFudCBvZiBkb1JlbW92ZS4KKyAgICAgKiBAcmV0dXJuIG51bGwgaWYgZW1wdHksIGVsc2Ugc25hcHNob3Qgb2YgbGFzdCBlbnRyeQorICAgICAqLworICAgIE1hcC5FbnRyeTxLLFY+IGRvUmVtb3ZlTGFzdEVudHJ5KCkgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBOb2RlPEssVj4gYiA9IGZpbmRQcmVkZWNlc3Nvck9mTGFzdCgpOworICAgICAgICAgICAgTm9kZTxLLFY+IG4gPSBiLm5leHQ7CisgICAgICAgICAgICBpZiAobiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWYgKGIuaXNCYXNlSGVhZGVyKCkpICAgICAgICAgICAgICAgLy8gZW1wdHkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsgLy8gYWxsIGIncyBzdWNjZXNzb3JzIGFyZSBkZWxldGVkOyByZXRyeQorICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIE5vZGU8SyxWPiBmID0gbi5uZXh0OworICAgICAgICAgICAgICAgIGlmIChuICE9IGIubmV4dCkgICAgICAgICAgICAgICAgICAgIC8vIGluY29uc2lzdGVudCByZWFkCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIE9iamVjdCB2ID0gbi52YWx1ZTsKKyAgICAgICAgICAgICAgICBpZiAodiA9PSBudWxsKSB7ICAgICAgICAgICAgICAgICAgICAvLyBuIGlzIGRlbGV0ZWQKKyAgICAgICAgICAgICAgICAgICAgbi5oZWxwRGVsZXRlKGIsIGYpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHYgPT0gbiB8fCBiLnZhbHVlID09IG51bGwpICAgICAgLy8gYiBpcyBkZWxldGVkCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGlmIChmICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYiA9IG47CisgICAgICAgICAgICAgICAgICAgIG4gPSBmOworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKCFuLmNhc1ZhbHVlKHYsIG51bGwpKQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBLIGtleSA9IG4ua2V5OworICAgICAgICAgICAgICAgIENvbXBhcmFibGU8PyBzdXBlciBLPiBjayA9IGNvbXBhcmFibGUoa2V5KTsKKyAgICAgICAgICAgICAgICBpZiAoIW4uYXBwZW5kTWFya2VyKGYpIHx8ICFiLmNhc05leHQobiwgZikpCisgICAgICAgICAgICAgICAgICAgIGZpbmROb2RlKGNrKTsgICAgICAgICAgICAgICAgICAvLyBSZXRyeSB2aWEgZmluZE5vZGUKKyAgICAgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZmluZFByZWRlY2Vzc29yKGNrKTsgICAgICAgICAgIC8vIENsZWFuIGluZGV4CisgICAgICAgICAgICAgICAgICAgIGlmIChoZWFkLnJpZ2h0ID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgICAgICB0cnlSZWR1Y2VMZXZlbCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFic3RyYWN0TWFwLlNpbXBsZUltbXV0YWJsZUVudHJ5PEssVj4oa2V5LCAoVil2KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0gUmVsYXRpb25hbCBvcGVyYXRpb25zIC0tLS0tLS0tLS0tLS0tICovCisKKyAgICAvLyBDb250cm9sIHZhbHVlcyBPUidlZCBhcyBhcmd1bWVudHMgdG8gZmluZE5lYXIKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBFUSA9IDE7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExUID0gMjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgR1QgPSAwOyAvLyBBY3R1YWxseSBjaGVja2VkIGFzICFMVAorCisgICAgLyoqCisgICAgICogVXRpbGl0eSBmb3IgY2VpbGluZywgZmxvb3IsIGxvd2VyLCBoaWdoZXIgbWV0aG9kcy4KKyAgICAgKiBAcGFyYW0ga2tleSB0aGUga2V5CisgICAgICogQHBhcmFtIHJlbCB0aGUgcmVsYXRpb24gLS0gT1InZWQgY29tYmluYXRpb24gb2YgRVEsIExULCBHVAorICAgICAqIEByZXR1cm4gbmVhcmVzdCBub2RlIGZpdHRpbmcgcmVsYXRpb24sIG9yIG51bGwgaWYgbm8gc3VjaAorICAgICAqLworICAgIE5vZGU8SyxWPiBmaW5kTmVhcihLIGtrZXksIGludCByZWwpIHsKKyAgICAgICAgQ29tcGFyYWJsZTw/IHN1cGVyIEs+IGtleSA9IGNvbXBhcmFibGUoa2tleSk7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIE5vZGU8SyxWPiBiID0gZmluZFByZWRlY2Vzc29yKGtleSk7CisgICAgICAgICAgICBOb2RlPEssVj4gbiA9IGIubmV4dDsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBpZiAobiA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChyZWwgJiBMVCkgPT0gMCB8fCBiLmlzQmFzZUhlYWRlcigpKSA/IG51bGwgOiBiOworICAgICAgICAgICAgICAgIE5vZGU8SyxWPiBmID0gbi5uZXh0OworICAgICAgICAgICAgICAgIGlmIChuICE9IGIubmV4dCkgICAgICAgICAgICAgICAgICAvLyBpbmNvbnNpc3RlbnQgcmVhZAorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBPYmplY3QgdiA9IG4udmFsdWU7CisgICAgICAgICAgICAgICAgaWYgKHYgPT0gbnVsbCkgeyAgICAgICAgICAgICAgICAgIC8vIG4gaXMgZGVsZXRlZAorICAgICAgICAgICAgICAgICAgICBuLmhlbHBEZWxldGUoYiwgZik7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAodiA9PSBuIHx8IGIudmFsdWUgPT0gbnVsbCkgICAgLy8gYiBpcyBkZWxldGVkCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGludCBjID0ga2V5LmNvbXBhcmVUbyhuLmtleSk7CisgICAgICAgICAgICAgICAgaWYgKChjID09IDAgJiYgKHJlbCAmIEVRKSAhPSAwKSB8fAorICAgICAgICAgICAgICAgICAgICAoYyA8ICAwICYmIChyZWwgJiBMVCkgPT0gMCkpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuOworICAgICAgICAgICAgICAgIGlmICggYyA8PSAwICYmIChyZWwgJiBMVCkgIT0gMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGIuaXNCYXNlSGVhZGVyKCkgPyBudWxsIDogYjsKKyAgICAgICAgICAgICAgICBiID0gbjsKKyAgICAgICAgICAgICAgICBuID0gZjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgU2ltcGxlSW1tdXRhYmxlRW50cnkgZm9yIHJlc3VsdHMgb2YgZmluZE5lYXIuCisgICAgICogQHBhcmFtIGtleSB0aGUga2V5CisgICAgICogQHBhcmFtIHJlbCB0aGUgcmVsYXRpb24gLS0gT1InZWQgY29tYmluYXRpb24gb2YgRVEsIExULCBHVAorICAgICAqIEByZXR1cm4gRW50cnkgZml0dGluZyByZWxhdGlvbiwgb3IgbnVsbCBpZiBubyBzdWNoCisgICAgICovCisgICAgQWJzdHJhY3RNYXAuU2ltcGxlSW1tdXRhYmxlRW50cnk8SyxWPiBnZXROZWFyKEsga2V5LCBpbnQgcmVsKSB7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIE5vZGU8SyxWPiBuID0gZmluZE5lYXIoa2V5LCByZWwpOworICAgICAgICAgICAgaWYgKG4gPT0gbnVsbCkKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIEFic3RyYWN0TWFwLlNpbXBsZUltbXV0YWJsZUVudHJ5PEssVj4gZSA9IG4uY3JlYXRlU25hcHNob3QoKTsKKyAgICAgICAgICAgIGlmIChlICE9IG51bGwpCisgICAgICAgICAgICAgICAgcmV0dXJuIGU7CisgICAgICAgIH0KKyAgICB9CisKKworICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0gQ29uc3RydWN0b3JzIC0tLS0tLS0tLS0tLS0tICovCisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3LCBlbXB0eSBtYXAsIHNvcnRlZCBhY2NvcmRpbmcgdG8gdGhlCisgICAgICoge0BsaW5rcGxhaW4gQ29tcGFyYWJsZSBuYXR1cmFsIG9yZGVyaW5nfSBvZiB0aGUga2V5cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29uY3VycmVudFNraXBMaXN0TWFwKCkgeworICAgICAgICB0aGlzLmNvbXBhcmF0b3IgPSBudWxsOworICAgICAgICBpbml0aWFsaXplKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldywgZW1wdHkgbWFwLCBzb3J0ZWQgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjb21wYXJhdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbXBhcmF0b3IgdGhlIGNvbXBhcmF0b3IgdGhhdCB3aWxsIGJlIHVzZWQgdG8gb3JkZXIgdGhpcyBtYXAuCisgICAgICogICAgICAgIElmIDx0dD5udWxsPC90dD4sIHRoZSB7QGxpbmtwbGFpbiBDb21wYXJhYmxlIG5hdHVyYWwKKyAgICAgKiAgICAgICAgb3JkZXJpbmd9IG9mIHRoZSBrZXlzIHdpbGwgYmUgdXNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29uY3VycmVudFNraXBMaXN0TWFwKENvbXBhcmF0b3I8PyBzdXBlciBLPiBjb21wYXJhdG9yKSB7CisgICAgICAgIHRoaXMuY29tcGFyYXRvciA9IGNvbXBhcmF0b3I7CisgICAgICAgIGluaXRpYWxpemUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IG1hcCBjb250YWluaW5nIHRoZSBzYW1lIG1hcHBpbmdzIGFzIHRoZSBnaXZlbiBtYXAsCisgICAgICogc29ydGVkIGFjY29yZGluZyB0byB0aGUge0BsaW5rcGxhaW4gQ29tcGFyYWJsZSBuYXR1cmFsIG9yZGVyaW5nfSBvZgorICAgICAqIHRoZSBrZXlzLgorICAgICAqCisgICAgICogQHBhcmFtICBtIHRoZSBtYXAgd2hvc2UgbWFwcGluZ3MgYXJlIHRvIGJlIHBsYWNlZCBpbiB0aGlzIG1hcAorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBrZXlzIGluIDx0dD5tPC90dD4gYXJlIG5vdAorICAgICAqICAgICAgICAge0BsaW5rIENvbXBhcmFibGV9LCBvciBhcmUgbm90IG11dHVhbGx5IGNvbXBhcmFibGUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgbWFwIG9yIGFueSBvZiBpdHMga2V5cworICAgICAqICAgICAgICAgb3IgdmFsdWVzIGFyZSBudWxsCisgICAgICovCisgICAgcHVibGljIENvbmN1cnJlbnRTa2lwTGlzdE1hcChNYXA8PyBleHRlbmRzIEssID8gZXh0ZW5kcyBWPiBtKSB7CisgICAgICAgIHRoaXMuY29tcGFyYXRvciA9IG51bGw7CisgICAgICAgIGluaXRpYWxpemUoKTsKKyAgICAgICAgcHV0QWxsKG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgbWFwIGNvbnRhaW5pbmcgdGhlIHNhbWUgbWFwcGluZ3MgYW5kIHVzaW5nIHRoZQorICAgICAqIHNhbWUgb3JkZXJpbmcgYXMgdGhlIHNwZWNpZmllZCBzb3J0ZWQgbWFwLgorICAgICAqCisgICAgICogQHBhcmFtIG0gdGhlIHNvcnRlZCBtYXAgd2hvc2UgbWFwcGluZ3MgYXJlIHRvIGJlIHBsYWNlZCBpbiB0aGlzCisgICAgICogICAgICAgIG1hcCwgYW5kIHdob3NlIGNvbXBhcmF0b3IgaXMgdG8gYmUgdXNlZCB0byBzb3J0IHRoaXMgbWFwCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIHNvcnRlZCBtYXAgb3IgYW55IG9mCisgICAgICogICAgICAgICBpdHMga2V5cyBvciB2YWx1ZXMgYXJlIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29uY3VycmVudFNraXBMaXN0TWFwKFNvcnRlZE1hcDxLLCA/IGV4dGVuZHMgVj4gbSkgeworICAgICAgICB0aGlzLmNvbXBhcmF0b3IgPSBtLmNvbXBhcmF0b3IoKTsKKyAgICAgICAgaW5pdGlhbGl6ZSgpOworICAgICAgICBidWlsZEZyb21Tb3J0ZWQobSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNoYWxsb3cgY29weSBvZiB0aGlzIDx0dD5Db25jdXJyZW50U2tpcExpc3RNYXA8L3R0PgorICAgICAqIGluc3RhbmNlLiAoVGhlIGtleXMgYW5kIHZhbHVlcyB0aGVtc2VsdmVzIGFyZSBub3QgY2xvbmVkLikKKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzaGFsbG93IGNvcHkgb2YgdGhpcyBtYXAKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29uY3VycmVudFNraXBMaXN0TWFwPEssVj4gY2xvbmUoKSB7CisgICAgICAgIENvbmN1cnJlbnRTa2lwTGlzdE1hcDxLLFY+IGNsb25lID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNsb25lID0gKENvbmN1cnJlbnRTa2lwTGlzdE1hcDxLLFY+KSBzdXBlci5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcigpOworICAgICAgICB9CisKKyAgICAgICAgY2xvbmUuaW5pdGlhbGl6ZSgpOworICAgICAgICBjbG9uZS5idWlsZEZyb21Tb3J0ZWQodGhpcyk7CisgICAgICAgIHJldHVybiBjbG9uZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdHJlYW1saW5lZCBidWxrIGluc2VydGlvbiB0byBpbml0aWFsaXplIGZyb20gZWxlbWVudHMgb2YKKyAgICAgKiBnaXZlbiBzb3J0ZWQgbWFwLiAgQ2FsbCBvbmx5IGZyb20gY29uc3RydWN0b3Igb3IgY2xvbmUKKyAgICAgKiBtZXRob2QuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkRnJvbVNvcnRlZChTb3J0ZWRNYXA8SywgPyBleHRlbmRzIFY+IG1hcCkgeworICAgICAgICBpZiAobWFwID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKworICAgICAgICBIZWFkSW5kZXg8SyxWPiBoID0gaGVhZDsKKyAgICAgICAgTm9kZTxLLFY+IGJhc2VwcmVkID0gaC5ub2RlOworCisgICAgICAgIC8vIFRyYWNrIHRoZSBjdXJyZW50IHJpZ2h0bW9zdCBub2RlIGF0IGVhY2ggbGV2ZWwuIFVzZXMgYW4KKyAgICAgICAgLy8gQXJyYXlMaXN0IHRvIGF2b2lkIGNvbW1pdHRpbmcgdG8gaW5pdGlhbCBvciBtYXhpbXVtIGxldmVsLgorICAgICAgICBBcnJheUxpc3Q8SW5kZXg8SyxWPj4gcHJlZHMgPSBuZXcgQXJyYXlMaXN0PEluZGV4PEssVj4+KCk7CisKKyAgICAgICAgLy8gaW5pdGlhbGl6ZQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8PSBoLmxldmVsOyArK2kpCisgICAgICAgICAgICBwcmVkcy5hZGQobnVsbCk7CisgICAgICAgIEluZGV4PEssVj4gcSA9IGg7CisgICAgICAgIGZvciAoaW50IGkgPSBoLmxldmVsOyBpID4gMDsgLS1pKSB7CisgICAgICAgICAgICBwcmVkcy5zZXQoaSwgcSk7CisgICAgICAgICAgICBxID0gcS5kb3duOworICAgICAgICB9CisKKyAgICAgICAgSXRlcmF0b3I8PyBleHRlbmRzIE1hcC5FbnRyeTw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+PiBpdCA9CisgICAgICAgICAgICBtYXAuZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBNYXAuRW50cnk8PyBleHRlbmRzIEssID8gZXh0ZW5kcyBWPiBlID0gaXQubmV4dCgpOworICAgICAgICAgICAgaW50IGogPSByYW5kb21MZXZlbCgpOworICAgICAgICAgICAgaWYgKGogPiBoLmxldmVsKSBqID0gaC5sZXZlbCArIDE7CisgICAgICAgICAgICBLIGsgPSBlLmdldEtleSgpOworICAgICAgICAgICAgViB2ID0gZS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgaWYgKGsgPT0gbnVsbCB8fCB2ID09IG51bGwpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBOb2RlPEssVj4geiA9IG5ldyBOb2RlPEssVj4oaywgdiwgbnVsbCk7CisgICAgICAgICAgICBiYXNlcHJlZC5uZXh0ID0gejsKKyAgICAgICAgICAgIGJhc2VwcmVkID0gejsKKyAgICAgICAgICAgIGlmIChqID4gMCkgeworICAgICAgICAgICAgICAgIEluZGV4PEssVj4gaWR4ID0gbnVsbDsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBqOyArK2kpIHsKKyAgICAgICAgICAgICAgICAgICAgaWR4ID0gbmV3IEluZGV4PEssVj4oeiwgaWR4LCBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiBoLmxldmVsKQorICAgICAgICAgICAgICAgICAgICAgICAgaCA9IG5ldyBIZWFkSW5kZXg8SyxWPihoLm5vZGUsIGgsIGlkeCwgaSk7CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCBwcmVkcy5zaXplKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHByZWRzLmdldChpKS5yaWdodCA9IGlkeDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHByZWRzLnNldChpLCBpZHgpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UKKyAgICAgICAgICAgICAgICAgICAgICAgIHByZWRzLmFkZChpZHgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBoZWFkID0gaDsKKyAgICB9CisKKyAgICAvKiAtLS0tLS0tLS0tLS0tLS0tIFNlcmlhbGl6YXRpb24gLS0tLS0tLS0tLS0tLS0gKi8KKworICAgIC8qKgorICAgICAqIFNhdmUgdGhlIHN0YXRlIG9mIHRoaXMgbWFwIHRvIGEgc3RyZWFtLgorICAgICAqCisgICAgICogQHNlcmlhbERhdGEgVGhlIGtleSAoT2JqZWN0KSBhbmQgdmFsdWUgKE9iamVjdCkgZm9yIGVhY2gKKyAgICAgKiBrZXktdmFsdWUgbWFwcGluZyByZXByZXNlbnRlZCBieSB0aGUgbWFwLCBmb2xsb3dlZCBieQorICAgICAqIDx0dD5udWxsPC90dD4uIFRoZSBrZXktdmFsdWUgbWFwcGluZ3MgYXJlIGVtaXR0ZWQgaW4ga2V5LW9yZGVyCisgICAgICogKGFzIGRldGVybWluZWQgYnkgdGhlIENvbXBhcmF0b3IsIG9yIGJ5IHRoZSBrZXlzJyBuYXR1cmFsCisgICAgICogb3JkZXJpbmcgaWYgbm8gQ29tcGFyYXRvcikuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtIHMpCisgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gV3JpdGUgb3V0IHRoZSBDb21wYXJhdG9yIGFuZCBhbnkgaGlkZGVuIHN0dWZmCisgICAgICAgIHMuZGVmYXVsdFdyaXRlT2JqZWN0KCk7CisKKyAgICAgICAgLy8gV3JpdGUgb3V0IGtleXMgYW5kIHZhbHVlcyAoYWx0ZXJuYXRpbmcpCisgICAgICAgIGZvciAoTm9kZTxLLFY+IG4gPSBmaW5kRmlyc3QoKTsgbiAhPSBudWxsOyBuID0gbi5uZXh0KSB7CisgICAgICAgICAgICBWIHYgPSBuLmdldFZhbGlkVmFsdWUoKTsKKyAgICAgICAgICAgIGlmICh2ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzLndyaXRlT2JqZWN0KG4ua2V5KTsKKyAgICAgICAgICAgICAgICBzLndyaXRlT2JqZWN0KHYpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHMud3JpdGVPYmplY3QobnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVjb25zdGl0dXRlIHRoZSBtYXAgZnJvbSBhIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChmaW5hbCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtIHMpCisgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gUmVhZCBpbiB0aGUgQ29tcGFyYXRvciBhbmQgYW55IGhpZGRlbiBzdHVmZgorICAgICAgICBzLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisgICAgICAgIC8vIFJlc2V0IHRyYW5zaWVudHMKKyAgICAgICAgaW5pdGlhbGl6ZSgpOworCisgICAgICAgIC8qCisgICAgICAgICAqIFRoaXMgaXMgbmVhcmx5IGlkZW50aWNhbCB0byBidWlsZEZyb21Tb3J0ZWQsIGJ1dCBpcworICAgICAgICAgKiBkaXN0aW5jdCBiZWNhdXNlIHJlYWRPYmplY3QgY2FsbHMgY2FuJ3QgYmUgbmljZWx5IGFkYXB0ZWQKKyAgICAgICAgICogYXMgdGhlIGtpbmQgb2YgaXRlcmF0b3IgbmVlZGVkIGJ5IGJ1aWxkRnJvbVNvcnRlZC4gKFRoZXkKKyAgICAgICAgICogY2FuIGJlLCBidXQgZG9pbmcgc28gcmVxdWlyZXMgdHlwZSBjaGVhdHMgYW5kL29yIGNyZWF0aW9uCisgICAgICAgICAqIG9mIGFkYXB0b3IgY2xhc3Nlcy4pIEl0IGlzIHNpbXBsZXIgdG8ganVzdCBhZGFwdCB0aGUgY29kZS4KKyAgICAgICAgICovCisKKyAgICAgICAgSGVhZEluZGV4PEssVj4gaCA9IGhlYWQ7CisgICAgICAgIE5vZGU8SyxWPiBiYXNlcHJlZCA9IGgubm9kZTsKKyAgICAgICAgQXJyYXlMaXN0PEluZGV4PEssVj4+IHByZWRzID0gbmV3IEFycmF5TGlzdDxJbmRleDxLLFY+PigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8PSBoLmxldmVsOyArK2kpCisgICAgICAgICAgICBwcmVkcy5hZGQobnVsbCk7CisgICAgICAgIEluZGV4PEssVj4gcSA9IGg7CisgICAgICAgIGZvciAoaW50IGkgPSBoLmxldmVsOyBpID4gMDsgLS1pKSB7CisgICAgICAgICAgICBwcmVkcy5zZXQoaSwgcSk7CisgICAgICAgICAgICBxID0gcS5kb3duOworICAgICAgICB9CisKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgT2JqZWN0IGsgPSBzLnJlYWRPYmplY3QoKTsKKyAgICAgICAgICAgIGlmIChrID09IG51bGwpCisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBPYmplY3QgdiA9IHMucmVhZE9iamVjdCgpOworICAgICAgICAgICAgaWYgKHYgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIEsga2V5ID0gKEspIGs7CisgICAgICAgICAgICBWIHZhbCA9IChWKSB2OworICAgICAgICAgICAgaW50IGogPSByYW5kb21MZXZlbCgpOworICAgICAgICAgICAgaWYgKGogPiBoLmxldmVsKSBqID0gaC5sZXZlbCArIDE7CisgICAgICAgICAgICBOb2RlPEssVj4geiA9IG5ldyBOb2RlPEssVj4oa2V5LCB2YWwsIG51bGwpOworICAgICAgICAgICAgYmFzZXByZWQubmV4dCA9IHo7CisgICAgICAgICAgICBiYXNlcHJlZCA9IHo7CisgICAgICAgICAgICBpZiAoaiA+IDApIHsKKyAgICAgICAgICAgICAgICBJbmRleDxLLFY+IGlkeCA9IG51bGw7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gajsgKytpKSB7CisgICAgICAgICAgICAgICAgICAgIGlkeCA9IG5ldyBJbmRleDxLLFY+KHosIGlkeCwgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChpID4gaC5sZXZlbCkKKyAgICAgICAgICAgICAgICAgICAgICAgIGggPSBuZXcgSGVhZEluZGV4PEssVj4oaC5ub2RlLCBoLCBpZHgsIGkpOworCisgICAgICAgICAgICAgICAgICAgIGlmIChpIDwgcHJlZHMuc2l6ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwcmVkcy5nZXQoaSkucmlnaHQgPSBpZHg7CisgICAgICAgICAgICAgICAgICAgICAgICBwcmVkcy5zZXQoaSwgaWR4KTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlCisgICAgICAgICAgICAgICAgICAgICAgICBwcmVkcy5hZGQoaWR4KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaGVhZCA9IGg7CisgICAgfQorCisgICAgLyogLS0tLS0tIE1hcCBBUEkgbWV0aG9kcyAtLS0tLS0gKi8KKworICAgIC8qKgorICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBpZiB0aGlzIG1hcCBjb250YWlucyBhIG1hcHBpbmcgZm9yIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5IGtleSB3aG9zZSBwcmVzZW5jZSBpbiB0aGlzIG1hcCBpcyB0byBiZSB0ZXN0ZWQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBtYXAgY29udGFpbnMgYSBtYXBwaW5nIGZvciB0aGUgc3BlY2lmaWVkIGtleQorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbm5vdCBiZSBjb21wYXJlZAorICAgICAqICAgICAgICAgd2l0aCB0aGUga2V5cyBjdXJyZW50bHkgaW4gdGhlIG1hcAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrZXkpIHsKKyAgICAgICAgcmV0dXJuIGRvR2V0KGtleSkgIT0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSB0byB3aGljaCB0aGUgc3BlY2lmaWVkIGtleSBpcyBtYXBwZWQsCisgICAgICogb3Ige0Bjb2RlIG51bGx9IGlmIHRoaXMgbWFwIGNvbnRhaW5zIG5vIG1hcHBpbmcgZm9yIHRoZSBrZXkuCisgICAgICoKKyAgICAgKiA8cD5Nb3JlIGZvcm1hbGx5LCBpZiB0aGlzIG1hcCBjb250YWlucyBhIG1hcHBpbmcgZnJvbSBhIGtleQorICAgICAqIHtAY29kZSBrfSB0byBhIHZhbHVlIHtAY29kZSB2fSBzdWNoIHRoYXQge0Bjb2RlIGtleX0gY29tcGFyZXMKKyAgICAgKiBlcXVhbCB0byB7QGNvZGUga30gYWNjb3JkaW5nIHRvIHRoZSBtYXAncyBvcmRlcmluZywgdGhlbiB0aGlzCisgICAgICogbWV0aG9kIHJldHVybnMge0Bjb2RlIHZ9OyBvdGhlcndpc2UgaXQgcmV0dXJucyB7QGNvZGUgbnVsbH0uCisgICAgICogKFRoZXJlIGNhbiBiZSBhdCBtb3N0IG9uZSBzdWNoIG1hcHBpbmcuKQorICAgICAqCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIGNvbXBhcmVkCisgICAgICogICAgICAgICB3aXRoIHRoZSBrZXlzIGN1cnJlbnRseSBpbiB0aGUgbWFwCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIFYgZ2V0KE9iamVjdCBrZXkpIHsKKyAgICAgICAgcmV0dXJuIGRvR2V0KGtleSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzb2NpYXRlcyB0aGUgc3BlY2lmaWVkIHZhbHVlIHdpdGggdGhlIHNwZWNpZmllZCBrZXkgaW4gdGhpcyBtYXAuCisgICAgICogSWYgdGhlIG1hcCBwcmV2aW91c2x5IGNvbnRhaW5lZCBhIG1hcHBpbmcgZm9yIHRoZSBrZXksIHRoZSBvbGQKKyAgICAgKiB2YWx1ZSBpcyByZXBsYWNlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkga2V5IHdpdGggd2hpY2ggdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyB0byBiZSBhc3NvY2lhdGVkCisgICAgICogQHBhcmFtIHZhbHVlIHZhbHVlIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGtleQorICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGtleSwgb3IKKyAgICAgKiAgICAgICAgIDx0dD5udWxsPC90dD4gaWYgdGhlcmUgd2FzIG5vIG1hcHBpbmcgZm9yIHRoZSBrZXkKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgY29tcGFyZWQKKyAgICAgKiAgICAgICAgIHdpdGggdGhlIGtleXMgY3VycmVudGx5IGluIHRoZSBtYXAKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQga2V5IG9yIHZhbHVlIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgViBwdXQoSyBrZXksIFYgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgcmV0dXJuIGRvUHV0KGtleSwgdmFsdWUsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBtYXBwaW5nIGZvciB0aGUgc3BlY2lmaWVkIGtleSBmcm9tIHRoaXMgbWFwIGlmIHByZXNlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gIGtleSBrZXkgZm9yIHdoaWNoIG1hcHBpbmcgc2hvdWxkIGJlIHJlbW92ZWQKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBrZXksIG9yCisgICAgICogICAgICAgICA8dHQ+bnVsbDwvdHQ+IGlmIHRoZXJlIHdhcyBubyBtYXBwaW5nIGZvciB0aGUga2V5CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIGNvbXBhcmVkCisgICAgICogICAgICAgICB3aXRoIHRoZSBrZXlzIGN1cnJlbnRseSBpbiB0aGUgbWFwCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIFYgcmVtb3ZlKE9iamVjdCBrZXkpIHsKKyAgICAgICAgcmV0dXJuIGRvUmVtb3ZlKGtleSwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgbWFwIG1hcHMgb25lIG9yIG1vcmUga2V5cyB0byB0aGUKKyAgICAgKiBzcGVjaWZpZWQgdmFsdWUuICBUaGlzIG9wZXJhdGlvbiByZXF1aXJlcyB0aW1lIGxpbmVhciBpbiB0aGUKKyAgICAgKiBtYXAgc2l6ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSB3aG9zZSBwcmVzZW5jZSBpbiB0aGlzIG1hcCBpcyB0byBiZSB0ZXN0ZWQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgYSBtYXBwaW5nIHRvIDx0dD52YWx1ZTwvdHQ+IGV4aXN0czsKKyAgICAgKiAgICAgICAgIDx0dD5mYWxzZTwvdHQ+IG90aGVyd2lzZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNWYWx1ZShPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgZm9yIChOb2RlPEssVj4gbiA9IGZpbmRGaXJzdCgpOyBuICE9IG51bGw7IG4gPSBuLm5leHQpIHsKKyAgICAgICAgICAgIFYgdiA9IG4uZ2V0VmFsaWRWYWx1ZSgpOworICAgICAgICAgICAgaWYgKHYgIT0gbnVsbCAmJiB2YWx1ZS5lcXVhbHModikpCisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBrZXktdmFsdWUgbWFwcGluZ3MgaW4gdGhpcyBtYXAuICBJZiB0aGlzIG1hcAorICAgICAqIGNvbnRhaW5zIG1vcmUgdGhhbiA8dHQ+SW50ZWdlci5NQVhfVkFMVUU8L3R0PiBlbGVtZW50cywgaXQKKyAgICAgKiByZXR1cm5zIDx0dD5JbnRlZ2VyLk1BWF9WQUxVRTwvdHQ+LgorICAgICAqCisgICAgICogPHA+QmV3YXJlIHRoYXQsIHVubGlrZSBpbiBtb3N0IGNvbGxlY3Rpb25zLCB0aGlzIG1ldGhvZCBpcworICAgICAqIDxlbT5OT1Q8L2VtPiBhIGNvbnN0YW50LXRpbWUgb3BlcmF0aW9uLiBCZWNhdXNlIG9mIHRoZQorICAgICAqIGFzeW5jaHJvbm91cyBuYXR1cmUgb2YgdGhlc2UgbWFwcywgZGV0ZXJtaW5pbmcgdGhlIGN1cnJlbnQKKyAgICAgKiBudW1iZXIgb2YgZWxlbWVudHMgcmVxdWlyZXMgdHJhdmVyc2luZyB0aGVtIGFsbCB0byBjb3VudCB0aGVtLgorICAgICAqIEFkZGl0aW9uYWxseSwgaXQgaXMgcG9zc2libGUgZm9yIHRoZSBzaXplIHRvIGNoYW5nZSBkdXJpbmcKKyAgICAgKiBleGVjdXRpb24gb2YgdGhpcyBtZXRob2QsIGluIHdoaWNoIGNhc2UgdGhlIHJldHVybmVkIHJlc3VsdAorICAgICAqIHdpbGwgYmUgaW5hY2N1cmF0ZS4gVGh1cywgdGhpcyBtZXRob2QgaXMgdHlwaWNhbGx5IG5vdCB2ZXJ5CisgICAgICogdXNlZnVsIGluIGNvbmN1cnJlbnQgYXBwbGljYXRpb25zLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgbWFwCisgICAgICovCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICBsb25nIGNvdW50ID0gMDsKKyAgICAgICAgZm9yIChOb2RlPEssVj4gbiA9IGZpbmRGaXJzdCgpOyBuICE9IG51bGw7IG4gPSBuLm5leHQpIHsKKyAgICAgICAgICAgIGlmIChuLmdldFZhbGlkVmFsdWUoKSAhPSBudWxsKQorICAgICAgICAgICAgICAgICsrY291bnQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChjb3VudCA+PSBJbnRlZ2VyLk1BWF9WQUxVRSkgPyBJbnRlZ2VyLk1BWF9WQUxVRSA6IChpbnQpIGNvdW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBpZiB0aGlzIG1hcCBjb250YWlucyBubyBrZXktdmFsdWUgbWFwcGluZ3MuCisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgbWFwIGNvbnRhaW5zIG5vIGtleS12YWx1ZSBtYXBwaW5ncworICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgIHJldHVybiBmaW5kRmlyc3QoKSA9PSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIG9mIHRoZSBtYXBwaW5ncyBmcm9tIHRoaXMgbWFwLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBpbml0aWFsaXplKCk7CisgICAgfQorCisgICAgLyogLS0tLS0tLS0tLS0tLS0tLSBWaWV3IG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0gKi8KKworICAgIC8qCisgICAgICogTm90ZTogTGF6eSBpbml0aWFsaXphdGlvbiB3b3JrcyBmb3Igdmlld3MgYmVjYXVzZSB2aWV3IGNsYXNzZXMKKyAgICAgKiBhcmUgc3RhdGVsZXNzL2ltbXV0YWJsZSBzbyBpdCBkb2Vzbid0IG1hdHRlciB3cnQgY29ycmVjdG5lc3MgaWYKKyAgICAgKiBtb3JlIHRoYW4gb25lIGlzIGNyZWF0ZWQgKHdoaWNoIHdpbGwgb25seSByYXJlbHkgaGFwcGVuKS4gIEV2ZW4KKyAgICAgKiBzbywgdGhlIGZvbGxvd2luZyBpZGlvbSBjb25zZXJ2YXRpdmVseSBlbnN1cmVzIHRoYXQgdGhlIG1ldGhvZAorICAgICAqIHJldHVybnMgdGhlIG9uZSBpdCBjcmVhdGVkIGlmIGl0IGRvZXMgc28sIG5vdCBvbmUgY3JlYXRlZCBieQorICAgICAqIGFub3RoZXIgcmFjaW5nIHRocmVhZC4KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGxpbmsgTmF2aWdhYmxlU2V0fSB2aWV3IG9mIHRoZSBrZXlzIGNvbnRhaW5lZCBpbiB0aGlzIG1hcC4KKyAgICAgKiBUaGUgc2V0J3MgaXRlcmF0b3IgcmV0dXJucyB0aGUga2V5cyBpbiBhc2NlbmRpbmcgb3JkZXIuCisgICAgICogVGhlIHNldCBpcyBiYWNrZWQgYnkgdGhlIG1hcCwgc28gY2hhbmdlcyB0byB0aGUgbWFwIGFyZQorICAgICAqIHJlZmxlY3RlZCBpbiB0aGUgc2V0LCBhbmQgdmljZS12ZXJzYS4gIFRoZSBzZXQgc3VwcG9ydHMgZWxlbWVudAorICAgICAqIHJlbW92YWwsIHdoaWNoIHJlbW92ZXMgdGhlIGNvcnJlc3BvbmRpbmcgbWFwcGluZyBmcm9tIHRoZSBtYXAsCisgICAgICogdmlhIHRoZSB7QGNvZGUgSXRlcmF0b3IucmVtb3ZlfSwge0Bjb2RlIFNldC5yZW1vdmV9LAorICAgICAqIHtAY29kZSByZW1vdmVBbGx9LCB7QGNvZGUgcmV0YWluQWxsfSwgYW5kIHtAY29kZSBjbGVhcn0KKyAgICAgKiBvcGVyYXRpb25zLiAgSXQgZG9lcyBub3Qgc3VwcG9ydCB0aGUge0Bjb2RlIGFkZH0gb3Ige0Bjb2RlIGFkZEFsbH0KKyAgICAgKiBvcGVyYXRpb25zLgorICAgICAqCisgICAgICogPHA+VGhlIHZpZXcncyB7QGNvZGUgaXRlcmF0b3J9IGlzIGEgIndlYWtseSBjb25zaXN0ZW50IiBpdGVyYXRvcgorICAgICAqIHRoYXQgd2lsbCBuZXZlciB0aHJvdyB7QGxpbmsgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0sCisgICAgICogYW5kIGd1YXJhbnRlZXMgdG8gdHJhdmVyc2UgZWxlbWVudHMgYXMgdGhleSBleGlzdGVkIHVwb24KKyAgICAgKiBjb25zdHJ1Y3Rpb24gb2YgdGhlIGl0ZXJhdG9yLCBhbmQgbWF5IChidXQgaXMgbm90IGd1YXJhbnRlZWQgdG8pCisgICAgICogcmVmbGVjdCBhbnkgbW9kaWZpY2F0aW9ucyBzdWJzZXF1ZW50IHRvIGNvbnN0cnVjdGlvbi4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8gbWV0aG9kIHtAY29kZSBuYXZpZ2FibGVLZXlTZXR9LgorICAgICAqCisgICAgICogQHJldHVybiBhIG5hdmlnYWJsZSBzZXQgdmlldyBvZiB0aGUga2V5cyBpbiB0aGlzIG1hcAorICAgICAqLworICAgICBwdWJsaWMgTmF2aWdhYmxlU2V0PEs+IGtleVNldCgpIHsKKyAgICAgICAgS2V5U2V0IGtzID0ga2V5U2V0OworICAgICAgICByZXR1cm4gKGtzICE9IG51bGwpID8ga3MgOiAoa2V5U2V0ID0gbmV3IEtleVNldCh0aGlzKSk7CisgICAgfQorCisgICAgcHVibGljIE5hdmlnYWJsZVNldDxLPiBuYXZpZ2FibGVLZXlTZXQoKSB7CisgICAgICAgIEtleVNldCBrcyA9IGtleVNldDsKKyAgICAgICAgcmV0dXJuIChrcyAhPSBudWxsKSA/IGtzIDogKGtleVNldCA9IG5ldyBLZXlTZXQodGhpcykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGxpbmsgQ29sbGVjdGlvbn0gdmlldyBvZiB0aGUgdmFsdWVzIGNvbnRhaW5lZCBpbiB0aGlzIG1hcC4KKyAgICAgKiBUaGUgY29sbGVjdGlvbidzIGl0ZXJhdG9yIHJldHVybnMgdGhlIHZhbHVlcyBpbiBhc2NlbmRpbmcgb3JkZXIKKyAgICAgKiBvZiB0aGUgY29ycmVzcG9uZGluZyBrZXlzLgorICAgICAqIFRoZSBjb2xsZWN0aW9uIGlzIGJhY2tlZCBieSB0aGUgbWFwLCBzbyBjaGFuZ2VzIHRvIHRoZSBtYXAgYXJlCisgICAgICogcmVmbGVjdGVkIGluIHRoZSBjb2xsZWN0aW9uLCBhbmQgdmljZS12ZXJzYS4gIFRoZSBjb2xsZWN0aW9uCisgICAgICogc3VwcG9ydHMgZWxlbWVudCByZW1vdmFsLCB3aGljaCByZW1vdmVzIHRoZSBjb3JyZXNwb25kaW5nCisgICAgICogbWFwcGluZyBmcm9tIHRoZSBtYXAsIHZpYSB0aGUgPHR0Pkl0ZXJhdG9yLnJlbW92ZTwvdHQ+LAorICAgICAqIDx0dD5Db2xsZWN0aW9uLnJlbW92ZTwvdHQ+LCA8dHQ+cmVtb3ZlQWxsPC90dD4sCisgICAgICogPHR0PnJldGFpbkFsbDwvdHQ+IGFuZCA8dHQ+Y2xlYXI8L3R0PiBvcGVyYXRpb25zLiAgSXQgZG9lcyBub3QKKyAgICAgKiBzdXBwb3J0IHRoZSA8dHQ+YWRkPC90dD4gb3IgPHR0PmFkZEFsbDwvdHQ+IG9wZXJhdGlvbnMuCisgICAgICoKKyAgICAgKiA8cD5UaGUgdmlldydzIDx0dD5pdGVyYXRvcjwvdHQ+IGlzIGEgIndlYWtseSBjb25zaXN0ZW50IiBpdGVyYXRvcgorICAgICAqIHRoYXQgd2lsbCBuZXZlciB0aHJvdyB7QGxpbmsgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0sCisgICAgICogYW5kIGd1YXJhbnRlZXMgdG8gdHJhdmVyc2UgZWxlbWVudHMgYXMgdGhleSBleGlzdGVkIHVwb24KKyAgICAgKiBjb25zdHJ1Y3Rpb24gb2YgdGhlIGl0ZXJhdG9yLCBhbmQgbWF5IChidXQgaXMgbm90IGd1YXJhbnRlZWQgdG8pCisgICAgICogcmVmbGVjdCBhbnkgbW9kaWZpY2F0aW9ucyBzdWJzZXF1ZW50IHRvIGNvbnN0cnVjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sbGVjdGlvbjxWPiB2YWx1ZXMoKSB7CisgICAgICAgIFZhbHVlcyB2cyA9IHZhbHVlczsKKyAgICAgICAgcmV0dXJuICh2cyAhPSBudWxsKSA/IHZzIDogKHZhbHVlcyA9IG5ldyBWYWx1ZXModGhpcykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGxpbmsgU2V0fSB2aWV3IG9mIHRoZSBtYXBwaW5ncyBjb250YWluZWQgaW4gdGhpcyBtYXAuCisgICAgICogVGhlIHNldCdzIGl0ZXJhdG9yIHJldHVybnMgdGhlIGVudHJpZXMgaW4gYXNjZW5kaW5nIGtleSBvcmRlci4KKyAgICAgKiBUaGUgc2V0IGlzIGJhY2tlZCBieSB0aGUgbWFwLCBzbyBjaGFuZ2VzIHRvIHRoZSBtYXAgYXJlCisgICAgICogcmVmbGVjdGVkIGluIHRoZSBzZXQsIGFuZCB2aWNlLXZlcnNhLiAgVGhlIHNldCBzdXBwb3J0cyBlbGVtZW50CisgICAgICogcmVtb3ZhbCwgd2hpY2ggcmVtb3ZlcyB0aGUgY29ycmVzcG9uZGluZyBtYXBwaW5nIGZyb20gdGhlIG1hcCwKKyAgICAgKiB2aWEgdGhlIDx0dD5JdGVyYXRvci5yZW1vdmU8L3R0PiwgPHR0PlNldC5yZW1vdmU8L3R0PiwKKyAgICAgKiA8dHQ+cmVtb3ZlQWxsPC90dD4sIDx0dD5yZXRhaW5BbGw8L3R0PiBhbmQgPHR0PmNsZWFyPC90dD4KKyAgICAgKiBvcGVyYXRpb25zLiAgSXQgZG9lcyBub3Qgc3VwcG9ydCB0aGUgPHR0PmFkZDwvdHQ+IG9yCisgICAgICogPHR0PmFkZEFsbDwvdHQ+IG9wZXJhdGlvbnMuCisgICAgICoKKyAgICAgKiA8cD5UaGUgdmlldydzIDx0dD5pdGVyYXRvcjwvdHQ+IGlzIGEgIndlYWtseSBjb25zaXN0ZW50IiBpdGVyYXRvcgorICAgICAqIHRoYXQgd2lsbCBuZXZlciB0aHJvdyB7QGxpbmsgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0sCisgICAgICogYW5kIGd1YXJhbnRlZXMgdG8gdHJhdmVyc2UgZWxlbWVudHMgYXMgdGhleSBleGlzdGVkIHVwb24KKyAgICAgKiBjb25zdHJ1Y3Rpb24gb2YgdGhlIGl0ZXJhdG9yLCBhbmQgbWF5IChidXQgaXMgbm90IGd1YXJhbnRlZWQgdG8pCisgICAgICogcmVmbGVjdCBhbnkgbW9kaWZpY2F0aW9ucyBzdWJzZXF1ZW50IHRvIGNvbnN0cnVjdGlvbi4KKyAgICAgKgorICAgICAqIDxwPlRoZSA8dHQ+TWFwLkVudHJ5PC90dD4gZWxlbWVudHMgcmV0dXJuZWQgYnkKKyAgICAgKiA8dHQ+aXRlcmF0b3IubmV4dCgpPC90dD4gZG8gPGVtPm5vdDwvZW0+IHN1cHBvcnQgdGhlCisgICAgICogPHR0PnNldFZhbHVlPC90dD4gb3BlcmF0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBhIHNldCB2aWV3IG9mIHRoZSBtYXBwaW5ncyBjb250YWluZWQgaW4gdGhpcyBtYXAsCisgICAgICogICAgICAgICBzb3J0ZWQgaW4gYXNjZW5kaW5nIGtleSBvcmRlcgorICAgICAqLworICAgIHB1YmxpYyBTZXQ8TWFwLkVudHJ5PEssVj4+IGVudHJ5U2V0KCkgeworICAgICAgICBFbnRyeVNldCBlcyA9IGVudHJ5U2V0OworICAgICAgICByZXR1cm4gKGVzICE9IG51bGwpID8gZXMgOiAoZW50cnlTZXQgPSBuZXcgRW50cnlTZXQodGhpcykpOworICAgIH0KKworICAgIHB1YmxpYyBDb25jdXJyZW50TmF2aWdhYmxlTWFwPEssVj4gZGVzY2VuZGluZ01hcCgpIHsKKyAgICAgICAgQ29uY3VycmVudE5hdmlnYWJsZU1hcDxLLFY+IGRtID0gZGVzY2VuZGluZ01hcDsKKyAgICAgICAgcmV0dXJuIChkbSAhPSBudWxsKSA/IGRtIDogKGRlc2NlbmRpbmdNYXAgPSBuZXcgU3ViTWFwPEssVj4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzLCBudWxsLCBmYWxzZSwgbnVsbCwgZmFsc2UsIHRydWUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTmF2aWdhYmxlU2V0PEs+IGRlc2NlbmRpbmdLZXlTZXQoKSB7CisgICAgICAgIHJldHVybiBkZXNjZW5kaW5nTWFwKCkubmF2aWdhYmxlS2V5U2V0KCk7CisgICAgfQorCisgICAgLyogLS0tLS0tLS0tLS0tLS0tLSBBYnN0cmFjdE1hcCBPdmVycmlkZXMgLS0tLS0tLS0tLS0tLS0gKi8KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHdpdGggdGhpcyBtYXAgZm9yIGVxdWFsaXR5LgorICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBpZiB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGFsc28gYSBtYXAgYW5kIHRoZQorICAgICAqIHR3byBtYXBzIHJlcHJlc2VudCB0aGUgc2FtZSBtYXBwaW5ncy4gIE1vcmUgZm9ybWFsbHksIHR3byBtYXBzCisgICAgICogPHR0Pm0xPC90dD4gYW5kIDx0dD5tMjwvdHQ+IHJlcHJlc2VudCB0aGUgc2FtZSBtYXBwaW5ncyBpZgorICAgICAqIDx0dD5tMS5lbnRyeVNldCgpLmVxdWFscyhtMi5lbnRyeVNldCgpKTwvdHQ+LiAgVGhpcworICAgICAqIG9wZXJhdGlvbiBtYXkgcmV0dXJuIG1pc2xlYWRpbmcgcmVzdWx0cyBpZiBlaXRoZXIgbWFwIGlzCisgICAgICogY29uY3VycmVudGx5IG1vZGlmaWVkIGR1cmluZyBleGVjdXRpb24gb2YgdGhpcyBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBvYmplY3QgdG8gYmUgY29tcGFyZWQgZm9yIGVxdWFsaXR5IHdpdGggdGhpcyBtYXAKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgZXF1YWwgdG8gdGhpcyBtYXAKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgaWYgKG8gPT0gdGhpcykKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBpZiAoIShvIGluc3RhbmNlb2YgTWFwKSkKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgTWFwPD8sPz4gbSA9IChNYXA8Pyw/PikgbzsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PEssVj4gZSA6IHRoaXMuZW50cnlTZXQoKSkKKyAgICAgICAgICAgICAgICBpZiAoISBlLmdldFZhbHVlKCkuZXF1YWxzKG0uZ2V0KGUuZ2V0S2V5KCkpKSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgZm9yIChNYXAuRW50cnk8Pyw/PiBlIDogbS5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICAgICAgT2JqZWN0IGsgPSBlLmdldEtleSgpOworICAgICAgICAgICAgICAgIE9iamVjdCB2ID0gZS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgICAgIGlmIChrID09IG51bGwgfHwgdiA9PSBudWxsIHx8ICF2LmVxdWFscyhnZXQoaykpKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIHVudXNlZCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiB1bnVzZWQpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIC0tLS0tLSBDb25jdXJyZW50TWFwIEFQSSBtZXRob2RzIC0tLS0tLSAqLworCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LAorICAgICAqICAgICAgICAgb3IgPHR0Pm51bGw8L3R0PiBpZiB0aGVyZSB3YXMgbm8gbWFwcGluZyBmb3IgdGhlIGtleQorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbm5vdCBiZSBjb21wYXJlZAorICAgICAqICAgICAgICAgd2l0aCB0aGUga2V5cyBjdXJyZW50bHkgaW4gdGhlIG1hcAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgb3IgdmFsdWUgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBWIHB1dElmQWJzZW50KEsga2V5LCBWIHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiBkb1B1dChrZXksIHZhbHVlLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICoKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgY29tcGFyZWQKKyAgICAgKiAgICAgICAgIHdpdGggdGhlIGtleXMgY3VycmVudGx5IGluIHRoZSBtYXAKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQga2V5IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IGtleSwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgcmV0dXJuIGRvUmVtb3ZlKGtleSwgdmFsdWUpICE9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIGNvbXBhcmVkCisgICAgICogICAgICAgICB3aXRoIHRoZSBrZXlzIGN1cnJlbnRseSBpbiB0aGUgbWFwCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBhbnkgb2YgdGhlIGFyZ3VtZW50cyBhcmUgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlcGxhY2UoSyBrZXksIFYgb2xkVmFsdWUsIFYgbmV3VmFsdWUpIHsKKyAgICAgICAgaWYgKG9sZFZhbHVlID09IG51bGwgfHwgbmV3VmFsdWUgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBDb21wYXJhYmxlPD8gc3VwZXIgSz4gayA9IGNvbXBhcmFibGUoa2V5KTsKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgTm9kZTxLLFY+IG4gPSBmaW5kTm9kZShrKTsKKyAgICAgICAgICAgIGlmIChuID09IG51bGwpCisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgT2JqZWN0IHYgPSBuLnZhbHVlOworICAgICAgICAgICAgaWYgKHYgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmICghb2xkVmFsdWUuZXF1YWxzKHYpKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgaWYgKG4uY2FzVmFsdWUodiwgbmV3VmFsdWUpKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGtleSwKKyAgICAgKiAgICAgICAgIG9yIDx0dD5udWxsPC90dD4gaWYgdGhlcmUgd2FzIG5vIG1hcHBpbmcgZm9yIHRoZSBrZXkKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgY29tcGFyZWQKKyAgICAgKiAgICAgICAgIHdpdGggdGhlIGtleXMgY3VycmVudGx5IGluIHRoZSBtYXAKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQga2V5IG9yIHZhbHVlIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgViByZXBsYWNlKEsga2V5LCBWIHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIENvbXBhcmFibGU8PyBzdXBlciBLPiBrID0gY29tcGFyYWJsZShrZXkpOworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBOb2RlPEssVj4gbiA9IGZpbmROb2RlKGspOworICAgICAgICAgICAgaWYgKG4gPT0gbnVsbCkKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIE9iamVjdCB2ID0gbi52YWx1ZTsKKyAgICAgICAgICAgIGlmICh2ICE9IG51bGwgJiYgbi5jYXNWYWx1ZSh2LCB2YWx1ZSkpCisgICAgICAgICAgICAgICAgcmV0dXJuIChWKXY7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKiAtLS0tLS0gU29ydGVkTWFwIEFQSSBtZXRob2RzIC0tLS0tLSAqLworCisgICAgcHVibGljIENvbXBhcmF0b3I8PyBzdXBlciBLPiBjb21wYXJhdG9yKCkgeworICAgICAgICByZXR1cm4gY29tcGFyYXRvcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBLIGZpcnN0S2V5KCkgeworICAgICAgICBOb2RlPEssVj4gbiA9IGZpbmRGaXJzdCgpOworICAgICAgICBpZiAobiA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgcmV0dXJuIG4ua2V5OworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIEsgbGFzdEtleSgpIHsKKyAgICAgICAgTm9kZTxLLFY+IG4gPSBmaW5kTGFzdCgpOworICAgICAgICBpZiAobiA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgcmV0dXJuIG4ua2V5OworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBmcm9tS2V5fSBvciB7QGNvZGUgdG9LZXl9IGlzIG51bGwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIENvbmN1cnJlbnROYXZpZ2FibGVNYXA8SyxWPiBzdWJNYXAoSyBmcm9tS2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZnJvbUluY2x1c2l2ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLIHRvS2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gdG9JbmNsdXNpdmUpIHsKKyAgICAgICAgaWYgKGZyb21LZXkgPT0gbnVsbCB8fCB0b0tleSA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiBuZXcgU3ViTWFwPEssVj4KKyAgICAgICAgICAgICh0aGlzLCBmcm9tS2V5LCBmcm9tSW5jbHVzaXZlLCB0b0tleSwgdG9JbmNsdXNpdmUsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgdG9LZXl9IGlzIG51bGwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIENvbmN1cnJlbnROYXZpZ2FibGVNYXA8SyxWPiBoZWFkTWFwKEsgdG9LZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaW5jbHVzaXZlKSB7CisgICAgICAgIGlmICh0b0tleSA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiBuZXcgU3ViTWFwPEssVj4KKyAgICAgICAgICAgICh0aGlzLCBudWxsLCBmYWxzZSwgdG9LZXksIGluY2x1c2l2ZSwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBmcm9tS2V5fSBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBDb25jdXJyZW50TmF2aWdhYmxlTWFwPEssVj4gdGFpbE1hcChLIGZyb21LZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaW5jbHVzaXZlKSB7CisgICAgICAgIGlmIChmcm9tS2V5ID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgcmV0dXJuIG5ldyBTdWJNYXA8SyxWPgorICAgICAgICAgICAgKHRoaXMsIGZyb21LZXksIGluY2x1c2l2ZSwgbnVsbCwgZmFsc2UsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgZnJvbUtleX0gb3Ige0Bjb2RlIHRvS2V5fSBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBDb25jdXJyZW50TmF2aWdhYmxlTWFwPEssVj4gc3ViTWFwKEsgZnJvbUtleSwgSyB0b0tleSkgeworICAgICAgICByZXR1cm4gc3ViTWFwKGZyb21LZXksIHRydWUsIHRvS2V5LCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIHRvS2V5fSBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBDb25jdXJyZW50TmF2aWdhYmxlTWFwPEssVj4gaGVhZE1hcChLIHRvS2V5KSB7CisgICAgICAgIHJldHVybiBoZWFkTWFwKHRvS2V5LCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIGZyb21LZXl9IGlzIG51bGwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIENvbmN1cnJlbnROYXZpZ2FibGVNYXA8SyxWPiB0YWlsTWFwKEsgZnJvbUtleSkgeworICAgICAgICByZXR1cm4gdGFpbE1hcChmcm9tS2V5LCB0cnVlKTsKKyAgICB9CisKKyAgICAvKiAtLS0tLS0tLS0tLS0tLS0tIFJlbGF0aW9uYWwgb3BlcmF0aW9ucyAtLS0tLS0tLS0tLS0tLSAqLworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGtleS12YWx1ZSBtYXBwaW5nIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ3JlYXRlc3Qga2V5CisgICAgICogc3RyaWN0bHkgbGVzcyB0aGFuIHRoZSBnaXZlbiBrZXksIG9yIDx0dD5udWxsPC90dD4gaWYgdGhlcmUgaXMKKyAgICAgKiBubyBzdWNoIGtleS4gVGhlIHJldHVybmVkIGVudHJ5IGRvZXMgPGVtPm5vdDwvZW0+IHN1cHBvcnQgdGhlCisgICAgICogPHR0PkVudHJ5LnNldFZhbHVlPC90dD4gbWV0aG9kLgorICAgICAqCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBNYXAuRW50cnk8SyxWPiBsb3dlckVudHJ5KEsga2V5KSB7CisgICAgICAgIHJldHVybiBnZXROZWFyKGtleSwgTFQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQga2V5IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgSyBsb3dlcktleShLIGtleSkgeworICAgICAgICBOb2RlPEssVj4gbiA9IGZpbmROZWFyKGtleSwgTFQpOworICAgICAgICByZXR1cm4gKG4gPT0gbnVsbCkgPyBudWxsIDogbi5rZXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGtleS12YWx1ZSBtYXBwaW5nIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ3JlYXRlc3Qga2V5CisgICAgICogbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiBrZXksIG9yIDx0dD5udWxsPC90dD4gaWYgdGhlcmUKKyAgICAgKiBpcyBubyBzdWNoIGtleS4gVGhlIHJldHVybmVkIGVudHJ5IGRvZXMgPGVtPm5vdDwvZW0+IHN1cHBvcnQKKyAgICAgKiB0aGUgPHR0PkVudHJ5LnNldFZhbHVlPC90dD4gbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIGtleSB0aGUga2V5CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBNYXAuRW50cnk8SyxWPiBmbG9vckVudHJ5KEsga2V5KSB7CisgICAgICAgIHJldHVybiBnZXROZWFyKGtleSwgTFR8RVEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBrZXkgdGhlIGtleQorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQga2V5IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgSyBmbG9vcktleShLIGtleSkgeworICAgICAgICBOb2RlPEssVj4gbiA9IGZpbmROZWFyKGtleSwgTFR8RVEpOworICAgICAgICByZXR1cm4gKG4gPT0gbnVsbCkgPyBudWxsIDogbi5rZXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGtleS12YWx1ZSBtYXBwaW5nIGFzc29jaWF0ZWQgd2l0aCB0aGUgbGVhc3Qga2V5CisgICAgICogZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiBrZXksIG9yIDx0dD5udWxsPC90dD4gaWYKKyAgICAgKiB0aGVyZSBpcyBubyBzdWNoIGVudHJ5LiBUaGUgcmV0dXJuZWQgZW50cnkgZG9lcyA8ZW0+bm90PC9lbT4KKyAgICAgKiBzdXBwb3J0IHRoZSA8dHQ+RW50cnkuc2V0VmFsdWU8L3R0PiBtZXRob2QuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIE1hcC5FbnRyeTxLLFY+IGNlaWxpbmdFbnRyeShLIGtleSkgeworICAgICAgICByZXR1cm4gZ2V0TmVhcihrZXksIEdUfEVRKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIEsgY2VpbGluZ0tleShLIGtleSkgeworICAgICAgICBOb2RlPEssVj4gbiA9IGZpbmROZWFyKGtleSwgR1R8RVEpOworICAgICAgICByZXR1cm4gKG4gPT0gbnVsbCkgPyBudWxsIDogbi5rZXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGtleS12YWx1ZSBtYXBwaW5nIGFzc29jaWF0ZWQgd2l0aCB0aGUgbGVhc3Qga2V5CisgICAgICogc3RyaWN0bHkgZ3JlYXRlciB0aGFuIHRoZSBnaXZlbiBrZXksIG9yIDx0dD5udWxsPC90dD4gaWYgdGhlcmUKKyAgICAgKiBpcyBubyBzdWNoIGtleS4gVGhlIHJldHVybmVkIGVudHJ5IGRvZXMgPGVtPm5vdDwvZW0+IHN1cHBvcnQKKyAgICAgKiB0aGUgPHR0PkVudHJ5LnNldFZhbHVlPC90dD4gbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIGtleSB0aGUga2V5CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBrZXkgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBNYXAuRW50cnk8SyxWPiBoaWdoZXJFbnRyeShLIGtleSkgeworICAgICAgICByZXR1cm4gZ2V0TmVhcihrZXksIEdUKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGtleSBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIEsgaGlnaGVyS2V5KEsga2V5KSB7CisgICAgICAgIE5vZGU8SyxWPiBuID0gZmluZE5lYXIoa2V5LCBHVCk7CisgICAgICAgIHJldHVybiAobiA9PSBudWxsKSA/IG51bGwgOiBuLmtleTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEga2V5LXZhbHVlIG1hcHBpbmcgYXNzb2NpYXRlZCB3aXRoIHRoZSBsZWFzdAorICAgICAqIGtleSBpbiB0aGlzIG1hcCwgb3IgPHR0Pm51bGw8L3R0PiBpZiB0aGUgbWFwIGlzIGVtcHR5LgorICAgICAqIFRoZSByZXR1cm5lZCBlbnRyeSBkb2VzIDxlbT5ub3Q8L2VtPiBzdXBwb3J0CisgICAgICogdGhlIDx0dD5FbnRyeS5zZXRWYWx1ZTwvdHQ+IG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWFwLkVudHJ5PEssVj4gZmlyc3RFbnRyeSgpIHsKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgTm9kZTxLLFY+IG4gPSBmaW5kRmlyc3QoKTsKKyAgICAgICAgICAgIGlmIChuID09IG51bGwpCisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICBBYnN0cmFjdE1hcC5TaW1wbGVJbW11dGFibGVFbnRyeTxLLFY+IGUgPSBuLmNyZWF0ZVNuYXBzaG90KCk7CisgICAgICAgICAgICBpZiAoZSAhPSBudWxsKQorICAgICAgICAgICAgICAgIHJldHVybiBlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGtleS12YWx1ZSBtYXBwaW5nIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ3JlYXRlc3QKKyAgICAgKiBrZXkgaW4gdGhpcyBtYXAsIG9yIDx0dD5udWxsPC90dD4gaWYgdGhlIG1hcCBpcyBlbXB0eS4KKyAgICAgKiBUaGUgcmV0dXJuZWQgZW50cnkgZG9lcyA8ZW0+bm90PC9lbT4gc3VwcG9ydAorICAgICAqIHRoZSA8dHQ+RW50cnkuc2V0VmFsdWU8L3R0PiBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIE1hcC5FbnRyeTxLLFY+IGxhc3RFbnRyeSgpIHsKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgTm9kZTxLLFY+IG4gPSBmaW5kTGFzdCgpOworICAgICAgICAgICAgaWYgKG4gPT0gbnVsbCkKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIEFic3RyYWN0TWFwLlNpbXBsZUltbXV0YWJsZUVudHJ5PEssVj4gZSA9IG4uY3JlYXRlU25hcHNob3QoKTsKKyAgICAgICAgICAgIGlmIChlICE9IG51bGwpCisgICAgICAgICAgICAgICAgcmV0dXJuIGU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGFuZCByZXR1cm5zIGEga2V5LXZhbHVlIG1hcHBpbmcgYXNzb2NpYXRlZCB3aXRoCisgICAgICogdGhlIGxlYXN0IGtleSBpbiB0aGlzIG1hcCwgb3IgPHR0Pm51bGw8L3R0PiBpZiB0aGUgbWFwIGlzIGVtcHR5LgorICAgICAqIFRoZSByZXR1cm5lZCBlbnRyeSBkb2VzIDxlbT5ub3Q8L2VtPiBzdXBwb3J0CisgICAgICogdGhlIDx0dD5FbnRyeS5zZXRWYWx1ZTwvdHQ+IG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWFwLkVudHJ5PEssVj4gcG9sbEZpcnN0RW50cnkoKSB7CisgICAgICAgIHJldHVybiBkb1JlbW92ZUZpcnN0RW50cnkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGFuZCByZXR1cm5zIGEga2V5LXZhbHVlIG1hcHBpbmcgYXNzb2NpYXRlZCB3aXRoCisgICAgICogdGhlIGdyZWF0ZXN0IGtleSBpbiB0aGlzIG1hcCwgb3IgPHR0Pm51bGw8L3R0PiBpZiB0aGUgbWFwIGlzIGVtcHR5LgorICAgICAqIFRoZSByZXR1cm5lZCBlbnRyeSBkb2VzIDxlbT5ub3Q8L2VtPiBzdXBwb3J0CisgICAgICogdGhlIDx0dD5FbnRyeS5zZXRWYWx1ZTwvdHQ+IG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWFwLkVudHJ5PEssVj4gcG9sbExhc3RFbnRyeSgpIHsKKyAgICAgICAgcmV0dXJuIGRvUmVtb3ZlTGFzdEVudHJ5KCk7CisgICAgfQorCisKKyAgICAvKiAtLS0tLS0tLS0tLS0tLS0tIEl0ZXJhdG9ycyAtLS0tLS0tLS0tLS0tLSAqLworCisgICAgLyoqCisgICAgICogQmFzZSBvZiBpdGVyYXRvciBjbGFzc2VzOgorICAgICAqLworICAgIGFic3RyYWN0IGNsYXNzIEl0ZXI8VD4gaW1wbGVtZW50cyBJdGVyYXRvcjxUPiB7CisgICAgICAgIC8qKiB0aGUgbGFzdCBub2RlIHJldHVybmVkIGJ5IG5leHQoKSAqLworICAgICAgICBOb2RlPEssVj4gbGFzdFJldHVybmVkOworICAgICAgICAvKiogdGhlIG5leHQgbm9kZSB0byByZXR1cm4gZnJvbSBuZXh0KCk7ICovCisgICAgICAgIE5vZGU8SyxWPiBuZXh0OworICAgICAgICAvKiogQ2FjaGUgb2YgbmV4dCB2YWx1ZSBmaWVsZCB0byBtYWludGFpbiB3ZWFrIGNvbnNpc3RlbmN5ICovCisgICAgICAgIFYgbmV4dFZhbHVlOworCisgICAgICAgIC8qKiBJbml0aWFsaXplcyBhc2NlbmRpbmcgaXRlcmF0b3IgZm9yIGVudGlyZSByYW5nZS4gKi8KKyAgICAgICAgSXRlcigpIHsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBuZXh0ID0gZmluZEZpcnN0KCk7CisgICAgICAgICAgICAgICAgaWYgKG5leHQgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgT2JqZWN0IHggPSBuZXh0LnZhbHVlOworICAgICAgICAgICAgICAgIGlmICh4ICE9IG51bGwgJiYgeCAhPSBuZXh0KSB7CisgICAgICAgICAgICAgICAgICAgIG5leHRWYWx1ZSA9IChWKSB4OworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgcmV0dXJuIG5leHQgIT0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKiBBZHZhbmNlcyBuZXh0IHRvIGhpZ2hlciBlbnRyeS4gKi8KKyAgICAgICAgZmluYWwgdm9pZCBhZHZhbmNlKCkgeworICAgICAgICAgICAgaWYgKG5leHQgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgbGFzdFJldHVybmVkID0gbmV4dDsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBuZXh0ID0gbmV4dC5uZXh0OworICAgICAgICAgICAgICAgIGlmIChuZXh0ID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIE9iamVjdCB4ID0gbmV4dC52YWx1ZTsKKyAgICAgICAgICAgICAgICBpZiAoeCAhPSBudWxsICYmIHggIT0gbmV4dCkgeworICAgICAgICAgICAgICAgICAgICBuZXh0VmFsdWUgPSAoVikgeDsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICAgICAgTm9kZTxLLFY+IGwgPSBsYXN0UmV0dXJuZWQ7CisgICAgICAgICAgICBpZiAobCA9PSBudWxsKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIC8vIEl0IHdvdWxkIG5vdCBiZSB3b3J0aCBhbGwgb2YgdGhlIG92ZXJoZWFkIHRvIGRpcmVjdGx5CisgICAgICAgICAgICAvLyB1bmxpbmsgZnJvbSBoZXJlLiBVc2luZyByZW1vdmUgaXMgZmFzdCBlbm91Z2guCisgICAgICAgICAgICBDb25jdXJyZW50U2tpcExpc3RNYXAudGhpcy5yZW1vdmUobC5rZXkpOworICAgICAgICAgICAgbGFzdFJldHVybmVkID0gbnVsbDsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgZmluYWwgY2xhc3MgVmFsdWVJdGVyYXRvciBleHRlbmRzIEl0ZXI8Vj4geworICAgICAgICBwdWJsaWMgViBuZXh0KCkgeworICAgICAgICAgICAgViB2ID0gbmV4dFZhbHVlOworICAgICAgICAgICAgYWR2YW5jZSgpOworICAgICAgICAgICAgcmV0dXJuIHY7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBmaW5hbCBjbGFzcyBLZXlJdGVyYXRvciBleHRlbmRzIEl0ZXI8Sz4geworICAgICAgICBwdWJsaWMgSyBuZXh0KCkgeworICAgICAgICAgICAgTm9kZTxLLFY+IG4gPSBuZXh0OworICAgICAgICAgICAgYWR2YW5jZSgpOworICAgICAgICAgICAgcmV0dXJuIG4ua2V5OworICAgICAgICB9CisgICAgfQorCisgICAgZmluYWwgY2xhc3MgRW50cnlJdGVyYXRvciBleHRlbmRzIEl0ZXI8TWFwLkVudHJ5PEssVj4+IHsKKyAgICAgICAgcHVibGljIE1hcC5FbnRyeTxLLFY+IG5leHQoKSB7CisgICAgICAgICAgICBOb2RlPEssVj4gbiA9IG5leHQ7CisgICAgICAgICAgICBWIHYgPSBuZXh0VmFsdWU7CisgICAgICAgICAgICBhZHZhbmNlKCk7CisgICAgICAgICAgICByZXR1cm4gbmV3IEFic3RyYWN0TWFwLlNpbXBsZUltbXV0YWJsZUVudHJ5PEssVj4obi5rZXksIHYpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gRmFjdG9yeSBtZXRob2RzIGZvciBpdGVyYXRvcnMgbmVlZGVkIGJ5IENvbmN1cnJlbnRTa2lwTGlzdFNldCBldGMKKworICAgIEl0ZXJhdG9yPEs+IGtleUl0ZXJhdG9yKCkgeworICAgICAgICByZXR1cm4gbmV3IEtleUl0ZXJhdG9yKCk7CisgICAgfQorCisgICAgSXRlcmF0b3I8Vj4gdmFsdWVJdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBWYWx1ZUl0ZXJhdG9yKCk7CisgICAgfQorCisgICAgSXRlcmF0b3I8TWFwLkVudHJ5PEssVj4+IGVudHJ5SXRlcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBuZXcgRW50cnlJdGVyYXRvcigpOworICAgIH0KKworICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0gVmlldyBDbGFzc2VzIC0tLS0tLS0tLS0tLS0tICovCisKKyAgICAvKgorICAgICAqIFZpZXcgY2xhc3NlcyBhcmUgc3RhdGljLCBkZWxlZ2F0aW5nIHRvIGEgQ29uY3VycmVudE5hdmlnYWJsZU1hcAorICAgICAqIHRvIGFsbG93IHVzZSBieSBTdWJNYXBzLCB3aGljaCBvdXR3ZWlnaHMgdGhlIHVnbGluZXNzIG9mCisgICAgICogbmVlZGluZyB0eXBlLXRlc3RzIGZvciBJdGVyYXRvciBtZXRob2RzLgorICAgICAqLworCisgICAgc3RhdGljIGZpbmFsIDxFPiBMaXN0PEU+IHRvTGlzdChDb2xsZWN0aW9uPEU+IGMpIHsKKyAgICAgICAgLy8gVXNpbmcgc2l6ZSgpIGhlcmUgd291bGQgYmUgYSBwZXNzaW1pemF0aW9uLgorICAgICAgICBMaXN0PEU+IGxpc3QgPSBuZXcgQXJyYXlMaXN0PEU+KCk7CisgICAgICAgIGZvciAoRSBlIDogYykKKyAgICAgICAgICAgIGxpc3QuYWRkKGUpOworICAgICAgICByZXR1cm4gbGlzdDsKKyAgICB9CisKKyAgICBzdGF0aWMgZmluYWwgY2xhc3MgS2V5U2V0PEU+CisgICAgICAgICAgICBleHRlbmRzIEFic3RyYWN0U2V0PEU+IGltcGxlbWVudHMgTmF2aWdhYmxlU2V0PEU+IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBDb25jdXJyZW50TmF2aWdhYmxlTWFwPEUsT2JqZWN0PiBtOworICAgICAgICBLZXlTZXQoQ29uY3VycmVudE5hdmlnYWJsZU1hcDxFLE9iamVjdD4gbWFwKSB7IG0gPSBtYXA7IH0KKyAgICAgICAgcHVibGljIGludCBzaXplKCkgeyByZXR1cm4gbS5zaXplKCk7IH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsgcmV0dXJuIG0uaXNFbXB0eSgpOyB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKSB7IHJldHVybiBtLmNvbnRhaW5zS2V5KG8pOyB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3QgbykgeyByZXR1cm4gbS5yZW1vdmUobykgIT0gbnVsbDsgfQorICAgICAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsgbS5jbGVhcigpOyB9CisgICAgICAgIHB1YmxpYyBFIGxvd2VyKEUgZSkgeyByZXR1cm4gbS5sb3dlcktleShlKTsgfQorICAgICAgICBwdWJsaWMgRSBmbG9vcihFIGUpIHsgcmV0dXJuIG0uZmxvb3JLZXkoZSk7IH0KKyAgICAgICAgcHVibGljIEUgY2VpbGluZyhFIGUpIHsgcmV0dXJuIG0uY2VpbGluZ0tleShlKTsgfQorICAgICAgICBwdWJsaWMgRSBoaWdoZXIoRSBlKSB7IHJldHVybiBtLmhpZ2hlcktleShlKTsgfQorICAgICAgICBwdWJsaWMgQ29tcGFyYXRvcjw/IHN1cGVyIEU+IGNvbXBhcmF0b3IoKSB7IHJldHVybiBtLmNvbXBhcmF0b3IoKTsgfQorICAgICAgICBwdWJsaWMgRSBmaXJzdCgpIHsgcmV0dXJuIG0uZmlyc3RLZXkoKTsgfQorICAgICAgICBwdWJsaWMgRSBsYXN0KCkgeyByZXR1cm4gbS5sYXN0S2V5KCk7IH0KKyAgICAgICAgcHVibGljIEUgcG9sbEZpcnN0KCkgeworICAgICAgICAgICAgTWFwLkVudHJ5PEUsT2JqZWN0PiBlID0gbS5wb2xsRmlyc3RFbnRyeSgpOworICAgICAgICAgICAgcmV0dXJuIChlID09IG51bGwpID8gbnVsbCA6IGUuZ2V0S2V5KCk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIEUgcG9sbExhc3QoKSB7CisgICAgICAgICAgICBNYXAuRW50cnk8RSxPYmplY3Q+IGUgPSBtLnBvbGxMYXN0RW50cnkoKTsKKyAgICAgICAgICAgIHJldHVybiAoZSA9PSBudWxsKSA/IG51bGwgOiBlLmdldEtleSgpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBJdGVyYXRvcjxFPiBpdGVyYXRvcigpIHsKKyAgICAgICAgICAgIGlmIChtIGluc3RhbmNlb2YgQ29uY3VycmVudFNraXBMaXN0TWFwKQorICAgICAgICAgICAgICAgIHJldHVybiAoKENvbmN1cnJlbnRTa2lwTGlzdE1hcDxFLE9iamVjdD4pbSkua2V5SXRlcmF0b3IoKTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICByZXR1cm4gKChDb25jdXJyZW50U2tpcExpc3RNYXAuU3ViTWFwPEUsT2JqZWN0PiltKS5rZXlJdGVyYXRvcigpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICAgICAgaWYgKG8gPT0gdGhpcykKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBTZXQpKQorICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIENvbGxlY3Rpb248Pz4gYyA9IChDb2xsZWN0aW9uPD8+KSBvOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY29udGFpbnNBbGwoYykgJiYgYy5jb250YWluc0FsbCh0aGlzKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiB1bnVzZWQpICAgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIHVudXNlZCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpICAgICB7IHJldHVybiB0b0xpc3QodGhpcykudG9BcnJheSgpOyAgfQorICAgICAgICBwdWJsaWMgPFQ+IFRbXSB0b0FycmF5KFRbXSBhKSB7IHJldHVybiB0b0xpc3QodGhpcykudG9BcnJheShhKTsgfQorICAgICAgICBwdWJsaWMgSXRlcmF0b3I8RT4gZGVzY2VuZGluZ0l0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIGRlc2NlbmRpbmdTZXQoKS5pdGVyYXRvcigpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBOYXZpZ2FibGVTZXQ8RT4gc3ViU2V0KEUgZnJvbUVsZW1lbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZnJvbUluY2x1c2l2ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRSB0b0VsZW1lbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gdG9JbmNsdXNpdmUpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgS2V5U2V0PEU+KG0uc3ViTWFwKGZyb21FbGVtZW50LCBmcm9tSW5jbHVzaXZlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9FbGVtZW50LCAgIHRvSW5jbHVzaXZlKSk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIE5hdmlnYWJsZVNldDxFPiBoZWFkU2V0KEUgdG9FbGVtZW50LCBib29sZWFuIGluY2x1c2l2ZSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBLZXlTZXQ8RT4obS5oZWFkTWFwKHRvRWxlbWVudCwgaW5jbHVzaXZlKSk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIE5hdmlnYWJsZVNldDxFPiB0YWlsU2V0KEUgZnJvbUVsZW1lbnQsIGJvb2xlYW4gaW5jbHVzaXZlKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEtleVNldDxFPihtLnRhaWxNYXAoZnJvbUVsZW1lbnQsIGluY2x1c2l2ZSkpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBOYXZpZ2FibGVTZXQ8RT4gc3ViU2V0KEUgZnJvbUVsZW1lbnQsIEUgdG9FbGVtZW50KSB7CisgICAgICAgICAgICByZXR1cm4gc3ViU2V0KGZyb21FbGVtZW50LCB0cnVlLCB0b0VsZW1lbnQsIGZhbHNlKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgTmF2aWdhYmxlU2V0PEU+IGhlYWRTZXQoRSB0b0VsZW1lbnQpIHsKKyAgICAgICAgICAgIHJldHVybiBoZWFkU2V0KHRvRWxlbWVudCwgZmFsc2UpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBOYXZpZ2FibGVTZXQ8RT4gdGFpbFNldChFIGZyb21FbGVtZW50KSB7CisgICAgICAgICAgICByZXR1cm4gdGFpbFNldChmcm9tRWxlbWVudCwgdHJ1ZSk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIE5hdmlnYWJsZVNldDxFPiBkZXNjZW5kaW5nU2V0KCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBLZXlTZXQobS5kZXNjZW5kaW5nTWFwKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIFZhbHVlczxFPiBleHRlbmRzIEFic3RyYWN0Q29sbGVjdGlvbjxFPiB7CisgICAgICAgIHByaXZhdGUgZmluYWwgQ29uY3VycmVudE5hdmlnYWJsZU1hcDxPYmplY3QsIEU+IG07CisgICAgICAgIFZhbHVlcyhDb25jdXJyZW50TmF2aWdhYmxlTWFwPE9iamVjdCwgRT4gbWFwKSB7CisgICAgICAgICAgICBtID0gbWFwOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBJdGVyYXRvcjxFPiBpdGVyYXRvcigpIHsKKyAgICAgICAgICAgIGlmIChtIGluc3RhbmNlb2YgQ29uY3VycmVudFNraXBMaXN0TWFwKQorICAgICAgICAgICAgICAgIHJldHVybiAoKENvbmN1cnJlbnRTa2lwTGlzdE1hcDxPYmplY3QsRT4pbSkudmFsdWVJdGVyYXRvcigpOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHJldHVybiAoKFN1Yk1hcDxPYmplY3QsRT4pbSkudmFsdWVJdGVyYXRvcigpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICByZXR1cm4gbS5pc0VtcHR5KCk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgcmV0dXJuIG0uc2l6ZSgpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKSB7CisgICAgICAgICAgICByZXR1cm4gbS5jb250YWluc1ZhbHVlKG8pOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICAgICAgbS5jbGVhcigpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBPYmplY3RbXSB0b0FycmF5KCkgICAgIHsgcmV0dXJuIHRvTGlzdCh0aGlzKS50b0FycmF5KCk7ICB9CisgICAgICAgIHB1YmxpYyA8VD4gVFtdIHRvQXJyYXkoVFtdIGEpIHsgcmV0dXJuIHRvTGlzdCh0aGlzKS50b0FycmF5KGEpOyB9CisgICAgfQorCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIEVudHJ5U2V0PEsxLFYxPiBleHRlbmRzIEFic3RyYWN0U2V0PE1hcC5FbnRyeTxLMSxWMT4+IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBDb25jdXJyZW50TmF2aWdhYmxlTWFwPEsxLCBWMT4gbTsKKyAgICAgICAgRW50cnlTZXQoQ29uY3VycmVudE5hdmlnYWJsZU1hcDxLMSwgVjE+IG1hcCkgeworICAgICAgICAgICAgbSA9IG1hcDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBJdGVyYXRvcjxNYXAuRW50cnk8SzEsVjE+PiBpdGVyYXRvcigpIHsKKyAgICAgICAgICAgIGlmIChtIGluc3RhbmNlb2YgQ29uY3VycmVudFNraXBMaXN0TWFwKQorICAgICAgICAgICAgICAgIHJldHVybiAoKENvbmN1cnJlbnRTa2lwTGlzdE1hcDxLMSxWMT4pbSkuZW50cnlJdGVyYXRvcigpOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHJldHVybiAoKFN1Yk1hcDxLMSxWMT4pbSkuZW50cnlJdGVyYXRvcigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBNYXAuRW50cnkpKQorICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIE1hcC5FbnRyeTxLMSxWMT4gZSA9IChNYXAuRW50cnk8SzEsVjE+KW87CisgICAgICAgICAgICBWMSB2ID0gbS5nZXQoZS5nZXRLZXkoKSk7CisgICAgICAgICAgICByZXR1cm4gdiAhPSBudWxsICYmIHYuZXF1YWxzKGUuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvKSB7CisgICAgICAgICAgICBpZiAoIShvIGluc3RhbmNlb2YgTWFwLkVudHJ5KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICBNYXAuRW50cnk8SzEsVjE+IGUgPSAoTWFwLkVudHJ5PEsxLFYxPilvOworICAgICAgICAgICAgcmV0dXJuIG0ucmVtb3ZlKGUuZ2V0S2V5KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICAgICAgcmV0dXJuIG0uaXNFbXB0eSgpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBtLnNpemUoKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgICAgIG0uY2xlYXIoKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIGlmIChvID09IHRoaXMpCisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICBpZiAoIShvIGluc3RhbmNlb2YgU2V0KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICBDb2xsZWN0aW9uPD8+IGMgPSAoQ29sbGVjdGlvbjw/PikgbzsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRhaW5zQWxsKGMpICYmIGMuY29udGFpbnNBbGwodGhpcyk7CisgICAgICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gdW51c2VkKSAgIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiB1bnVzZWQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSAgICAgeyByZXR1cm4gdG9MaXN0KHRoaXMpLnRvQXJyYXkoKTsgIH0KKyAgICAgICAgcHVibGljIDxUPiBUW10gdG9BcnJheShUW10gYSkgeyByZXR1cm4gdG9MaXN0KHRoaXMpLnRvQXJyYXkoYSk7IH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdWJtYXBzIHJldHVybmVkIGJ5IHtAbGluayBDb25jdXJyZW50U2tpcExpc3RNYXB9IHN1Ym1hcCBvcGVyYXRpb25zCisgICAgICogcmVwcmVzZW50IGEgc3VicmFuZ2Ugb2YgbWFwcGluZ3Mgb2YgdGhlaXIgdW5kZXJseWluZworICAgICAqIG1hcHMuIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIHN1cHBvcnQgYWxsIG1ldGhvZHMgb2YgdGhlaXIKKyAgICAgKiB1bmRlcmx5aW5nIG1hcHMsIGRpZmZlcmluZyBpbiB0aGF0IG1hcHBpbmdzIG91dHNpZGUgdGhlaXIgcmFuZ2UgYXJlCisgICAgICogaWdub3JlZCwgYW5kIGF0dGVtcHRzIHRvIGFkZCBtYXBwaW5ncyBvdXRzaWRlIHRoZWlyIHJhbmdlcyByZXN1bHQKKyAgICAgKiBpbiB7QGxpbmsgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufS4gIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIGFyZQorICAgICAqIGNvbnN0cnVjdGVkIG9ubHkgdXNpbmcgdGhlIDx0dD5zdWJNYXA8L3R0PiwgPHR0PmhlYWRNYXA8L3R0PiwgYW5kCisgICAgICogPHR0PnRhaWxNYXA8L3R0PiBtZXRob2RzIG9mIHRoZWlyIHVuZGVybHlpbmcgbWFwcy4KKyAgICAgKgorICAgICAqIEBzZXJpYWwgaW5jbHVkZQorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBTdWJNYXA8SyxWPiBleHRlbmRzIEFic3RyYWN0TWFwPEssVj4KKyAgICAgICAgaW1wbGVtZW50cyBDb25jdXJyZW50TmF2aWdhYmxlTWFwPEssVj4sIENsb25lYWJsZSwKKyAgICAgICAgICAgICAgICAgICBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03NjQ3MDc4NjQ1ODk1MDUxNjA5TDsKKworICAgICAgICAvKiogVW5kZXJseWluZyBtYXAgKi8KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBDb25jdXJyZW50U2tpcExpc3RNYXA8SyxWPiBtOworICAgICAgICAvKiogbG93ZXIgYm91bmQga2V5LCBvciBudWxsIGlmIGZyb20gc3RhcnQgKi8KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBLIGxvOworICAgICAgICAvKiogdXBwZXIgYm91bmQga2V5LCBvciBudWxsIGlmIHRvIGVuZCAqLworICAgICAgICBwcml2YXRlIGZpbmFsIEsgaGk7CisgICAgICAgIC8qKiBpbmNsdXNpb24gZmxhZyBmb3IgbG8gKi8KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGxvSW5jbHVzaXZlOworICAgICAgICAvKiogaW5jbHVzaW9uIGZsYWcgZm9yIGhpICovCisgICAgICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBoaUluY2x1c2l2ZTsKKyAgICAgICAgLyoqIGRpcmVjdGlvbiAqLworICAgICAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gaXNEZXNjZW5kaW5nOworCisgICAgICAgIC8vIExhemlseSBpbml0aWFsaXplZCB2aWV3IGhvbGRlcnMKKyAgICAgICAgcHJpdmF0ZSB0cmFuc2llbnQgS2V5U2V0PEs+IGtleVNldFZpZXc7CisgICAgICAgIHByaXZhdGUgdHJhbnNpZW50IFNldDxNYXAuRW50cnk8SyxWPj4gZW50cnlTZXRWaWV3OworICAgICAgICBwcml2YXRlIHRyYW5zaWVudCBDb2xsZWN0aW9uPFY+IHZhbHVlc1ZpZXc7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENyZWF0ZXMgYSBuZXcgc3VibWFwLCBpbml0aWFsaXppbmcgYWxsIGZpZWxkcworICAgICAgICAgKi8KKyAgICAgICAgU3ViTWFwKENvbmN1cnJlbnRTa2lwTGlzdE1hcDxLLFY+IG1hcCwKKyAgICAgICAgICAgICAgIEsgZnJvbUtleSwgYm9vbGVhbiBmcm9tSW5jbHVzaXZlLAorICAgICAgICAgICAgICAgSyB0b0tleSwgYm9vbGVhbiB0b0luY2x1c2l2ZSwKKyAgICAgICAgICAgICAgIGJvb2xlYW4gaXNEZXNjZW5kaW5nKSB7CisgICAgICAgICAgICBpZiAoZnJvbUtleSAhPSBudWxsICYmIHRvS2V5ICE9IG51bGwgJiYKKyAgICAgICAgICAgICAgICBtYXAuY29tcGFyZShmcm9tS2V5LCB0b0tleSkgPiAwKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImluY29uc2lzdGVudCByYW5nZSIpOworICAgICAgICAgICAgdGhpcy5tID0gbWFwOworICAgICAgICAgICAgdGhpcy5sbyA9IGZyb21LZXk7CisgICAgICAgICAgICB0aGlzLmhpID0gdG9LZXk7CisgICAgICAgICAgICB0aGlzLmxvSW5jbHVzaXZlID0gZnJvbUluY2x1c2l2ZTsKKyAgICAgICAgICAgIHRoaXMuaGlJbmNsdXNpdmUgPSB0b0luY2x1c2l2ZTsKKyAgICAgICAgICAgIHRoaXMuaXNEZXNjZW5kaW5nID0gaXNEZXNjZW5kaW5nOworICAgICAgICB9CisKKyAgICAgICAgLyogLS0tLS0tLS0tLS0tLS0tLSAgVXRpbGl0aWVzIC0tLS0tLS0tLS0tLS0tICovCisKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIHRvb0xvdyhLIGtleSkgeworICAgICAgICAgICAgaWYgKGxvICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpbnQgYyA9IG0uY29tcGFyZShrZXksIGxvKTsKKyAgICAgICAgICAgICAgICBpZiAoYyA8IDAgfHwgKGMgPT0gMCAmJiAhbG9JbmNsdXNpdmUpKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiB0b29IaWdoKEsga2V5KSB7CisgICAgICAgICAgICBpZiAoaGkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGludCBjID0gbS5jb21wYXJlKGtleSwgaGkpOworICAgICAgICAgICAgICAgIGlmIChjID4gMCB8fCAoYyA9PSAwICYmICFoaUluY2x1c2l2ZSkpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGluQm91bmRzKEsga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gIXRvb0xvdyhrZXkpICYmICF0b29IaWdoKGtleSk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgY2hlY2tLZXlCb3VuZHMoSyBrZXkpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKGtleSA9PSBudWxsKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgaWYgKCFpbkJvdW5kcyhrZXkpKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImtleSBvdXQgb2YgcmFuZ2UiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgbm9kZSBrZXkgaXMgbGVzcyB0aGFuIHVwcGVyIGJvdW5kIG9mIHJhbmdlCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNCZWZvcmVFbmQoQ29uY3VycmVudFNraXBMaXN0TWFwLk5vZGU8SyxWPiBuKSB7CisgICAgICAgICAgICBpZiAobiA9PSBudWxsKQorICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIGlmIChoaSA9PSBudWxsKQorICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgSyBrID0gbi5rZXk7CisgICAgICAgICAgICBpZiAoayA9PSBudWxsKSAvLyBwYXNzIGJ5IG1hcmtlcnMgYW5kIGhlYWRlcnMKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIGludCBjID0gbS5jb21wYXJlKGssIGhpKTsKKyAgICAgICAgICAgIGlmIChjID4gMCB8fCAoYyA9PSAwICYmICFoaUluY2x1c2l2ZSkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyBsb3dlc3Qgbm9kZS4gVGhpcyBub2RlIG1pZ2h0IG5vdCBiZSBpbiByYW5nZSwgc28KKyAgICAgICAgICogbW9zdCB1c2FnZXMgbmVlZCB0byBjaGVjayBib3VuZHMKKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgQ29uY3VycmVudFNraXBMaXN0TWFwLk5vZGU8SyxWPiBsb05vZGUoKSB7CisgICAgICAgICAgICBpZiAobG8gPT0gbnVsbCkKKyAgICAgICAgICAgICAgICByZXR1cm4gbS5maW5kRmlyc3QoKTsKKyAgICAgICAgICAgIGVsc2UgaWYgKGxvSW5jbHVzaXZlKQorICAgICAgICAgICAgICAgIHJldHVybiBtLmZpbmROZWFyKGxvLCBtLkdUfG0uRVEpOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHJldHVybiBtLmZpbmROZWFyKGxvLCBtLkdUKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGhpZ2hlc3Qgbm9kZS4gVGhpcyBub2RlIG1pZ2h0IG5vdCBiZSBpbiByYW5nZSwgc28KKyAgICAgICAgICogbW9zdCB1c2FnZXMgbmVlZCB0byBjaGVjayBib3VuZHMKKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgQ29uY3VycmVudFNraXBMaXN0TWFwLk5vZGU8SyxWPiBoaU5vZGUoKSB7CisgICAgICAgICAgICBpZiAoaGkgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICByZXR1cm4gbS5maW5kTGFzdCgpOworICAgICAgICAgICAgZWxzZSBpZiAoaGlJbmNsdXNpdmUpCisgICAgICAgICAgICAgICAgcmV0dXJuIG0uZmluZE5lYXIoaGksIG0uTFR8bS5FUSk7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgcmV0dXJuIG0uZmluZE5lYXIoaGksIG0uTFQpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgbG93ZXN0IGFic29sdXRlIGtleSAoaWdub3JpbmcgZGlyZWN0b25hbGl0eSkKKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgSyBsb3dlc3RLZXkoKSB7CisgICAgICAgICAgICBDb25jdXJyZW50U2tpcExpc3RNYXAuTm9kZTxLLFY+IG4gPSBsb05vZGUoKTsKKyAgICAgICAgICAgIGlmIChpc0JlZm9yZUVuZChuKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gbi5rZXk7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGhpZ2hlc3QgYWJzb2x1dGUga2V5IChpZ25vcmluZyBkaXJlY3RvbmFsaXR5KQorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBLIGhpZ2hlc3RLZXkoKSB7CisgICAgICAgICAgICBDb25jdXJyZW50U2tpcExpc3RNYXAuTm9kZTxLLFY+IG4gPSBoaU5vZGUoKTsKKyAgICAgICAgICAgIGlmIChuICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBLIGxhc3QgPSBuLmtleTsKKyAgICAgICAgICAgICAgICBpZiAoaW5Cb3VuZHMobGFzdCkpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBsYXN0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgTWFwLkVudHJ5PEssVj4gbG93ZXN0RW50cnkoKSB7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgQ29uY3VycmVudFNraXBMaXN0TWFwLk5vZGU8SyxWPiBuID0gbG9Ob2RlKCk7CisgICAgICAgICAgICAgICAgaWYgKCFpc0JlZm9yZUVuZChuKSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgTWFwLkVudHJ5PEssVj4gZSA9IG4uY3JlYXRlU25hcHNob3QoKTsKKyAgICAgICAgICAgICAgICBpZiAoZSAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgTWFwLkVudHJ5PEssVj4gaGlnaGVzdEVudHJ5KCkgeworICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIENvbmN1cnJlbnRTa2lwTGlzdE1hcC5Ob2RlPEssVj4gbiA9IGhpTm9kZSgpOworICAgICAgICAgICAgICAgIGlmIChuID09IG51bGwgfHwgIWluQm91bmRzKG4ua2V5KSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgTWFwLkVudHJ5PEssVj4gZSA9IG4uY3JlYXRlU25hcHNob3QoKTsKKyAgICAgICAgICAgICAgICBpZiAoZSAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgTWFwLkVudHJ5PEssVj4gcmVtb3ZlTG93ZXN0KCkgeworICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIE5vZGU8SyxWPiBuID0gbG9Ob2RlKCk7CisgICAgICAgICAgICAgICAgaWYgKG4gPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgSyBrID0gbi5rZXk7CisgICAgICAgICAgICAgICAgaWYgKCFpbkJvdW5kcyhrKSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgViB2ID0gbS5kb1JlbW92ZShrLCBudWxsKTsKKyAgICAgICAgICAgICAgICBpZiAodiAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFic3RyYWN0TWFwLlNpbXBsZUltbXV0YWJsZUVudHJ5PEssVj4oaywgdik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIE1hcC5FbnRyeTxLLFY+IHJlbW92ZUhpZ2hlc3QoKSB7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgTm9kZTxLLFY+IG4gPSBoaU5vZGUoKTsKKyAgICAgICAgICAgICAgICBpZiAobiA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICBLIGsgPSBuLmtleTsKKyAgICAgICAgICAgICAgICBpZiAoIWluQm91bmRzKGspKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICBWIHYgPSBtLmRvUmVtb3ZlKGssIG51bGwpOworICAgICAgICAgICAgICAgIGlmICh2ICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQWJzdHJhY3RNYXAuU2ltcGxlSW1tdXRhYmxlRW50cnk8SyxWPihrLCB2KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTdWJtYXAgdmVyc2lvbiBvZiBDb25jdXJyZW50U2tpcExpc3RNYXAuZ2V0TmVhckVudHJ5CisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIE1hcC5FbnRyeTxLLFY+IGdldE5lYXJFbnRyeShLIGtleSwgaW50IHJlbCkgeworICAgICAgICAgICAgaWYgKGlzRGVzY2VuZGluZykgeyAvLyBhZGp1c3QgcmVsYXRpb24gZm9yIGRpcmVjdGlvbgorICAgICAgICAgICAgICAgIGlmICgocmVsICYgbS5MVCkgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgcmVsIHw9IG0uTFQ7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICByZWwgJj0gfm0uTFQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodG9vTG93KGtleSkpCisgICAgICAgICAgICAgICAgcmV0dXJuICgocmVsICYgbS5MVCkgIT0gMCkgPyBudWxsIDogbG93ZXN0RW50cnkoKTsKKyAgICAgICAgICAgIGlmICh0b29IaWdoKGtleSkpCisgICAgICAgICAgICAgICAgcmV0dXJuICgocmVsICYgbS5MVCkgIT0gMCkgPyBoaWdoZXN0RW50cnkoKSA6IG51bGw7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgTm9kZTxLLFY+IG4gPSBtLmZpbmROZWFyKGtleSwgcmVsKTsKKyAgICAgICAgICAgICAgICBpZiAobiA9PSBudWxsIHx8ICFpbkJvdW5kcyhuLmtleSkpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIEsgayA9IG4ua2V5OworICAgICAgICAgICAgICAgIFYgdiA9IG4uZ2V0VmFsaWRWYWx1ZSgpOworICAgICAgICAgICAgICAgIGlmICh2ICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQWJzdHJhY3RNYXAuU2ltcGxlSW1tdXRhYmxlRW50cnk8SyxWPihrLCB2KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIEFsbW9zdCB0aGUgc2FtZSBhcyBnZXROZWFyRW50cnksIGV4Y2VwdCBmb3Iga2V5cworICAgICAgICBwcml2YXRlIEsgZ2V0TmVhcktleShLIGtleSwgaW50IHJlbCkgeworICAgICAgICAgICAgaWYgKGlzRGVzY2VuZGluZykgeyAvLyBhZGp1c3QgcmVsYXRpb24gZm9yIGRpcmVjdGlvbgorICAgICAgICAgICAgICAgIGlmICgocmVsICYgbS5MVCkgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgcmVsIHw9IG0uTFQ7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICByZWwgJj0gfm0uTFQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodG9vTG93KGtleSkpIHsKKyAgICAgICAgICAgICAgICBpZiAoKHJlbCAmIG0uTFQpID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgQ29uY3VycmVudFNraXBMaXN0TWFwLk5vZGU8SyxWPiBuID0gbG9Ob2RlKCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChpc0JlZm9yZUVuZChuKSkKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuLmtleTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodG9vSGlnaChrZXkpKSB7CisgICAgICAgICAgICAgICAgaWYgKChyZWwgJiBtLkxUKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIENvbmN1cnJlbnRTa2lwTGlzdE1hcC5Ob2RlPEssVj4gbiA9IGhpTm9kZSgpOworICAgICAgICAgICAgICAgICAgICBpZiAobiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBLIGxhc3QgPSBuLmtleTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbkJvdW5kcyhsYXN0KSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGFzdDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBOb2RlPEssVj4gbiA9IG0uZmluZE5lYXIoa2V5LCByZWwpOworICAgICAgICAgICAgICAgIGlmIChuID09IG51bGwgfHwgIWluQm91bmRzKG4ua2V5KSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgSyBrID0gbi5rZXk7CisgICAgICAgICAgICAgICAgViB2ID0gbi5nZXRWYWxpZFZhbHVlKCk7CisgICAgICAgICAgICAgICAgaWYgKHYgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKiAtLS0tLS0tLS0tLS0tLS0tICBNYXAgQVBJIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0gKi8KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0tleShPYmplY3Qga2V5KSB7CisgICAgICAgICAgICBpZiAoa2V5ID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgSyBrID0gKEspa2V5OworICAgICAgICAgICAgcmV0dXJuIGluQm91bmRzKGspICYmIG0uY29udGFpbnNLZXkoayk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgViBnZXQoT2JqZWN0IGtleSkgeworICAgICAgICAgICAgaWYgKGtleSA9PSBudWxsKSB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIEsgayA9IChLKWtleTsKKyAgICAgICAgICAgIHJldHVybiAoKCFpbkJvdW5kcyhrKSkgPyBudWxsIDogbS5nZXQoaykpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFYgcHV0KEsga2V5LCBWIHZhbHVlKSB7CisgICAgICAgICAgICBjaGVja0tleUJvdW5kcyhrZXkpOworICAgICAgICAgICAgcmV0dXJuIG0ucHV0KGtleSwgdmFsdWUpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFYgcmVtb3ZlKE9iamVjdCBrZXkpIHsKKyAgICAgICAgICAgIEsgayA9IChLKWtleTsKKyAgICAgICAgICAgIHJldHVybiAoIWluQm91bmRzKGspKSA/IG51bGwgOiBtLnJlbW92ZShrKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIGxvbmcgY291bnQgPSAwOworICAgICAgICAgICAgZm9yIChDb25jdXJyZW50U2tpcExpc3RNYXAuTm9kZTxLLFY+IG4gPSBsb05vZGUoKTsKKyAgICAgICAgICAgICAgICAgaXNCZWZvcmVFbmQobik7CisgICAgICAgICAgICAgICAgIG4gPSBuLm5leHQpIHsKKyAgICAgICAgICAgICAgICBpZiAobi5nZXRWYWxpZFZhbHVlKCkgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgKytjb3VudDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBjb3VudCA+PSBJbnRlZ2VyLk1BWF9WQUxVRSA/IEludGVnZXIuTUFYX1ZBTFVFIDogKGludCljb3VudDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICByZXR1cm4gIWlzQmVmb3JlRW5kKGxvTm9kZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVmFsdWUoT2JqZWN0IHZhbHVlKSB7CisgICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGZvciAoQ29uY3VycmVudFNraXBMaXN0TWFwLk5vZGU8SyxWPiBuID0gbG9Ob2RlKCk7CisgICAgICAgICAgICAgICAgIGlzQmVmb3JlRW5kKG4pOworICAgICAgICAgICAgICAgICBuID0gbi5uZXh0KSB7CisgICAgICAgICAgICAgICAgViB2ID0gbi5nZXRWYWxpZFZhbHVlKCk7CisgICAgICAgICAgICAgICAgaWYgKHYgIT0gbnVsbCAmJiB2YWx1ZS5lcXVhbHModikpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICBmb3IgKENvbmN1cnJlbnRTa2lwTGlzdE1hcC5Ob2RlPEssVj4gbiA9IGxvTm9kZSgpOworICAgICAgICAgICAgICAgICBpc0JlZm9yZUVuZChuKTsKKyAgICAgICAgICAgICAgICAgbiA9IG4ubmV4dCkgeworICAgICAgICAgICAgICAgIGlmIChuLmdldFZhbGlkVmFsdWUoKSAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICBtLnJlbW92ZShuLmtleSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKiAtLS0tLS0tLS0tLS0tLS0tICBDb25jdXJyZW50TWFwIEFQSSBtZXRob2RzIC0tLS0tLS0tLS0tLS0tICovCisKKyAgICAgICAgcHVibGljIFYgcHV0SWZBYnNlbnQoSyBrZXksIFYgdmFsdWUpIHsKKyAgICAgICAgICAgIGNoZWNrS2V5Qm91bmRzKGtleSk7CisgICAgICAgICAgICByZXR1cm4gbS5wdXRJZkFic2VudChrZXksIHZhbHVlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3Qga2V5LCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgICAgIEsgayA9IChLKWtleTsKKyAgICAgICAgICAgIHJldHVybiBpbkJvdW5kcyhrKSAmJiBtLnJlbW92ZShrLCB2YWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiByZXBsYWNlKEsga2V5LCBWIG9sZFZhbHVlLCBWIG5ld1ZhbHVlKSB7CisgICAgICAgICAgICBjaGVja0tleUJvdW5kcyhrZXkpOworICAgICAgICAgICAgcmV0dXJuIG0ucmVwbGFjZShrZXksIG9sZFZhbHVlLCBuZXdWYWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgViByZXBsYWNlKEsga2V5LCBWIHZhbHVlKSB7CisgICAgICAgICAgICBjaGVja0tleUJvdW5kcyhrZXkpOworICAgICAgICAgICAgcmV0dXJuIG0ucmVwbGFjZShrZXksIHZhbHVlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0gIFNvcnRlZE1hcCBBUEkgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLSAqLworCisgICAgICAgIHB1YmxpYyBDb21wYXJhdG9yPD8gc3VwZXIgSz4gY29tcGFyYXRvcigpIHsKKyAgICAgICAgICAgIENvbXBhcmF0b3I8PyBzdXBlciBLPiBjbXAgPSBtLmNvbXBhcmF0b3IoKTsKKyAgICAgICAgICAgIGlmIChpc0Rlc2NlbmRpbmcpCisgICAgICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnJldmVyc2VPcmRlcihjbXApOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHJldHVybiBjbXA7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogVXRpbGl0eSB0byBjcmVhdGUgc3VibWFwcywgd2hlcmUgZ2l2ZW4gYm91bmRzIG92ZXJyaWRlCisgICAgICAgICAqIHVuYm91bmRlZChudWxsKSBvbmVzIGFuZC9vciBhcmUgY2hlY2tlZCBhZ2FpbnN0IGJvdW5kZWQgb25lcy4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgU3ViTWFwPEssVj4gbmV3U3ViTWFwKEsgZnJvbUtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBmcm9tSW5jbHVzaXZlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLIHRvS2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHRvSW5jbHVzaXZlKSB7CisgICAgICAgICAgICBpZiAoaXNEZXNjZW5kaW5nKSB7IC8vIGZsaXAgc2Vuc2VzCisgICAgICAgICAgICAgICAgSyB0ayA9IGZyb21LZXk7CisgICAgICAgICAgICAgICAgZnJvbUtleSA9IHRvS2V5OworICAgICAgICAgICAgICAgIHRvS2V5ID0gdGs7CisgICAgICAgICAgICAgICAgYm9vbGVhbiB0aSA9IGZyb21JbmNsdXNpdmU7CisgICAgICAgICAgICAgICAgZnJvbUluY2x1c2l2ZSA9IHRvSW5jbHVzaXZlOworICAgICAgICAgICAgICAgIHRvSW5jbHVzaXZlID0gdGk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobG8gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmIChmcm9tS2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgZnJvbUtleSA9IGxvOworICAgICAgICAgICAgICAgICAgICBmcm9tSW5jbHVzaXZlID0gbG9JbmNsdXNpdmU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpbnQgYyA9IG0uY29tcGFyZShmcm9tS2V5LCBsbyk7CisgICAgICAgICAgICAgICAgICAgIGlmIChjIDwgMCB8fCAoYyA9PSAwICYmICFsb0luY2x1c2l2ZSAmJiBmcm9tSW5jbHVzaXZlKSkKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImtleSBvdXQgb2YgcmFuZ2UiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaGkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmICh0b0tleSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRvS2V5ID0gaGk7CisgICAgICAgICAgICAgICAgICAgIHRvSW5jbHVzaXZlID0gaGlJbmNsdXNpdmU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpbnQgYyA9IG0uY29tcGFyZSh0b0tleSwgaGkpOworICAgICAgICAgICAgICAgICAgICBpZiAoYyA+IDAgfHwgKGMgPT0gMCAmJiAhaGlJbmNsdXNpdmUgJiYgdG9JbmNsdXNpdmUpKQorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigia2V5IG91dCBvZiByYW5nZSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuZXcgU3ViTWFwPEssVj4obSwgZnJvbUtleSwgZnJvbUluY2x1c2l2ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9LZXksIHRvSW5jbHVzaXZlLCBpc0Rlc2NlbmRpbmcpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN1Yk1hcDxLLFY+IHN1Yk1hcChLIGZyb21LZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBmcm9tSW5jbHVzaXZlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEsgdG9LZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiB0b0luY2x1c2l2ZSkgeworICAgICAgICAgICAgaWYgKGZyb21LZXkgPT0gbnVsbCB8fCB0b0tleSA9PSBudWxsKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgcmV0dXJuIG5ld1N1Yk1hcChmcm9tS2V5LCBmcm9tSW5jbHVzaXZlLCB0b0tleSwgdG9JbmNsdXNpdmUpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN1Yk1hcDxLLFY+IGhlYWRNYXAoSyB0b0tleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpbmNsdXNpdmUpIHsKKyAgICAgICAgICAgIGlmICh0b0tleSA9PSBudWxsKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgcmV0dXJuIG5ld1N1Yk1hcChudWxsLCBmYWxzZSwgdG9LZXksIGluY2x1c2l2ZSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3ViTWFwPEssVj4gdGFpbE1hcChLIGZyb21LZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaW5jbHVzaXZlKSB7CisgICAgICAgICAgICBpZiAoZnJvbUtleSA9PSBudWxsKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgcmV0dXJuIG5ld1N1Yk1hcChmcm9tS2V5LCBpbmNsdXNpdmUsIG51bGwsIGZhbHNlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdWJNYXA8SyxWPiBzdWJNYXAoSyBmcm9tS2V5LCBLIHRvS2V5KSB7CisgICAgICAgICAgICByZXR1cm4gc3ViTWFwKGZyb21LZXksIHRydWUsIHRvS2V5LCBmYWxzZSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3ViTWFwPEssVj4gaGVhZE1hcChLIHRvS2V5KSB7CisgICAgICAgICAgICByZXR1cm4gaGVhZE1hcCh0b0tleSwgZmFsc2UpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN1Yk1hcDxLLFY+IHRhaWxNYXAoSyBmcm9tS2V5KSB7CisgICAgICAgICAgICByZXR1cm4gdGFpbE1hcChmcm9tS2V5LCB0cnVlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdWJNYXA8SyxWPiBkZXNjZW5kaW5nTWFwKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBTdWJNYXA8SyxWPihtLCBsbywgbG9JbmNsdXNpdmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpLCBoaUluY2x1c2l2ZSwgIWlzRGVzY2VuZGluZyk7CisgICAgICAgIH0KKworICAgICAgICAvKiAtLS0tLS0tLS0tLS0tLS0tICBSZWxhdGlvbmFsIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0gKi8KKworICAgICAgICBwdWJsaWMgTWFwLkVudHJ5PEssVj4gY2VpbGluZ0VudHJ5KEsga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0TmVhckVudHJ5KGtleSwgKG0uR1R8bS5FUSkpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEsgY2VpbGluZ0tleShLIGtleSkgeworICAgICAgICAgICAgcmV0dXJuIGdldE5lYXJLZXkoa2V5LCAobS5HVHxtLkVRKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTWFwLkVudHJ5PEssVj4gbG93ZXJFbnRyeShLIGtleSkgeworICAgICAgICAgICAgcmV0dXJuIGdldE5lYXJFbnRyeShrZXksIChtLkxUKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSyBsb3dlcktleShLIGtleSkgeworICAgICAgICAgICAgcmV0dXJuIGdldE5lYXJLZXkoa2V5LCAobS5MVCkpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE1hcC5FbnRyeTxLLFY+IGZsb29yRW50cnkoSyBrZXkpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXROZWFyRW50cnkoa2V5LCAobS5MVHxtLkVRKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSyBmbG9vcktleShLIGtleSkgeworICAgICAgICAgICAgcmV0dXJuIGdldE5lYXJLZXkoa2V5LCAobS5MVHxtLkVRKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTWFwLkVudHJ5PEssVj4gaGlnaGVyRW50cnkoSyBrZXkpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXROZWFyRW50cnkoa2V5LCAobS5HVCkpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEsgaGlnaGVyS2V5KEsga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0TmVhcktleShrZXksIChtLkdUKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSyBmaXJzdEtleSgpIHsKKyAgICAgICAgICAgIHJldHVybiBpc0Rlc2NlbmRpbmcgPyBoaWdoZXN0S2V5KCkgOiBsb3dlc3RLZXkoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBLIGxhc3RLZXkoKSB7CisgICAgICAgICAgICByZXR1cm4gaXNEZXNjZW5kaW5nID8gbG93ZXN0S2V5KCkgOiBoaWdoZXN0S2V5KCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTWFwLkVudHJ5PEssVj4gZmlyc3RFbnRyeSgpIHsKKyAgICAgICAgICAgIHJldHVybiBpc0Rlc2NlbmRpbmcgPyBoaWdoZXN0RW50cnkoKSA6IGxvd2VzdEVudHJ5KCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTWFwLkVudHJ5PEssVj4gbGFzdEVudHJ5KCkgeworICAgICAgICAgICAgcmV0dXJuIGlzRGVzY2VuZGluZyA/IGxvd2VzdEVudHJ5KCkgOiBoaWdoZXN0RW50cnkoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBNYXAuRW50cnk8SyxWPiBwb2xsRmlyc3RFbnRyeSgpIHsKKyAgICAgICAgICAgIHJldHVybiBpc0Rlc2NlbmRpbmcgPyByZW1vdmVIaWdoZXN0KCkgOiByZW1vdmVMb3dlc3QoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBNYXAuRW50cnk8SyxWPiBwb2xsTGFzdEVudHJ5KCkgeworICAgICAgICAgICAgcmV0dXJuIGlzRGVzY2VuZGluZyA/IHJlbW92ZUxvd2VzdCgpIDogcmVtb3ZlSGlnaGVzdCgpOworICAgICAgICB9CisKKyAgICAgICAgLyogLS0tLS0tLS0tLS0tLS0tLSBTdWJtYXAgVmlld3MgLS0tLS0tLS0tLS0tLS0gKi8KKworICAgICAgICBwdWJsaWMgTmF2aWdhYmxlU2V0PEs+IGtleVNldCgpIHsKKyAgICAgICAgICAgIEtleVNldDxLPiBrcyA9IGtleVNldFZpZXc7CisgICAgICAgICAgICByZXR1cm4gKGtzICE9IG51bGwpID8ga3MgOiAoa2V5U2V0VmlldyA9IG5ldyBLZXlTZXQodGhpcykpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE5hdmlnYWJsZVNldDxLPiBuYXZpZ2FibGVLZXlTZXQoKSB7CisgICAgICAgICAgICBLZXlTZXQ8Sz4ga3MgPSBrZXlTZXRWaWV3OworICAgICAgICAgICAgcmV0dXJuIChrcyAhPSBudWxsKSA/IGtzIDogKGtleVNldFZpZXcgPSBuZXcgS2V5U2V0KHRoaXMpKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBDb2xsZWN0aW9uPFY+IHZhbHVlcygpIHsKKyAgICAgICAgICAgIENvbGxlY3Rpb248Vj4gdnMgPSB2YWx1ZXNWaWV3OworICAgICAgICAgICAgcmV0dXJuICh2cyAhPSBudWxsKSA/IHZzIDogKHZhbHVlc1ZpZXcgPSBuZXcgVmFsdWVzKHRoaXMpKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTZXQ8TWFwLkVudHJ5PEssVj4+IGVudHJ5U2V0KCkgeworICAgICAgICAgICAgU2V0PE1hcC5FbnRyeTxLLFY+PiBlcyA9IGVudHJ5U2V0VmlldzsKKyAgICAgICAgICAgIHJldHVybiAoZXMgIT0gbnVsbCkgPyBlcyA6IChlbnRyeVNldFZpZXcgPSBuZXcgRW50cnlTZXQodGhpcykpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE5hdmlnYWJsZVNldDxLPiBkZXNjZW5kaW5nS2V5U2V0KCkgeworICAgICAgICAgICAgcmV0dXJuIGRlc2NlbmRpbmdNYXAoKS5uYXZpZ2FibGVLZXlTZXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIEl0ZXJhdG9yPEs+IGtleUl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBTdWJNYXBLZXlJdGVyYXRvcigpOworICAgICAgICB9CisKKyAgICAgICAgSXRlcmF0b3I8Vj4gdmFsdWVJdGVyYXRvcigpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgU3ViTWFwVmFsdWVJdGVyYXRvcigpOworICAgICAgICB9CisKKyAgICAgICAgSXRlcmF0b3I8TWFwLkVudHJ5PEssVj4+IGVudHJ5SXRlcmF0b3IoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFN1Yk1hcEVudHJ5SXRlcmF0b3IoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBWYXJpYW50IG9mIG1haW4gSXRlciBjbGFzcyB0byB0cmF2ZXJzZSB0aHJvdWdoIHN1Ym1hcHMuCisgICAgICAgICAqLworICAgICAgICBhYnN0cmFjdCBjbGFzcyBTdWJNYXBJdGVyPFQ+IGltcGxlbWVudHMgSXRlcmF0b3I8VD4geworICAgICAgICAgICAgLyoqIHRoZSBsYXN0IG5vZGUgcmV0dXJuZWQgYnkgbmV4dCgpICovCisgICAgICAgICAgICBOb2RlPEssVj4gbGFzdFJldHVybmVkOworICAgICAgICAgICAgLyoqIHRoZSBuZXh0IG5vZGUgdG8gcmV0dXJuIGZyb20gbmV4dCgpOyAqLworICAgICAgICAgICAgTm9kZTxLLFY+IG5leHQ7CisgICAgICAgICAgICAvKiogQ2FjaGUgb2YgbmV4dCB2YWx1ZSBmaWVsZCB0byBtYWludGFpbiB3ZWFrIGNvbnNpc3RlbmN5ICovCisgICAgICAgICAgICBWIG5leHRWYWx1ZTsKKworICAgICAgICAgICAgU3ViTWFwSXRlcigpIHsKKyAgICAgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgICAgIG5leHQgPSBpc0Rlc2NlbmRpbmcgPyBoaU5vZGUoKSA6IGxvTm9kZSgpOworICAgICAgICAgICAgICAgICAgICBpZiAobmV4dCA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIE9iamVjdCB4ID0gbmV4dC52YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHggIT0gbnVsbCAmJiB4ICE9IG5leHQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIGluQm91bmRzKG5leHQua2V5KSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0ID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0VmFsdWUgPSAoVikgeDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXh0ICE9IG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGZpbmFsIHZvaWQgYWR2YW5jZSgpIHsKKyAgICAgICAgICAgICAgICBpZiAobmV4dCA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIGxhc3RSZXR1cm5lZCA9IG5leHQ7CisgICAgICAgICAgICAgICAgaWYgKGlzRGVzY2VuZGluZykKKyAgICAgICAgICAgICAgICAgICAgZGVzY2VuZCgpOworICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgYXNjZW5kKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHByaXZhdGUgdm9pZCBhc2NlbmQoKSB7CisgICAgICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgICAgICBuZXh0ID0gbmV4dC5uZXh0OworICAgICAgICAgICAgICAgICAgICBpZiAobmV4dCA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIE9iamVjdCB4ID0gbmV4dC52YWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHggIT0gbnVsbCAmJiB4ICE9IG5leHQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0b29IaWdoKG5leHQua2V5KSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0ID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0VmFsdWUgPSAoVikgeDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwcml2YXRlIHZvaWQgZGVzY2VuZCgpIHsKKyAgICAgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgICAgIG5leHQgPSBtLmZpbmROZWFyKGxhc3RSZXR1cm5lZC5rZXksIExUKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBPYmplY3QgeCA9IG5leHQudmFsdWU7CisgICAgICAgICAgICAgICAgICAgIGlmICh4ICE9IG51bGwgJiYgeCAhPSBuZXh0KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAodG9vTG93KG5leHQua2V5KSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0ID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0VmFsdWUgPSAoVikgeDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICAgICAgTm9kZTxLLFY+IGwgPSBsYXN0UmV0dXJuZWQ7CisgICAgICAgICAgICAgICAgaWYgKGwgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIG0ucmVtb3ZlKGwua2V5KTsKKyAgICAgICAgICAgICAgICBsYXN0UmV0dXJuZWQgPSBudWxsOworICAgICAgICAgICAgfQorCisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBjbGFzcyBTdWJNYXBWYWx1ZUl0ZXJhdG9yIGV4dGVuZHMgU3ViTWFwSXRlcjxWPiB7CisgICAgICAgICAgICBwdWJsaWMgViBuZXh0KCkgeworICAgICAgICAgICAgICAgIFYgdiA9IG5leHRWYWx1ZTsKKyAgICAgICAgICAgICAgICBhZHZhbmNlKCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHY7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBjbGFzcyBTdWJNYXBLZXlJdGVyYXRvciBleHRlbmRzIFN1Yk1hcEl0ZXI8Sz4geworICAgICAgICAgICAgcHVibGljIEsgbmV4dCgpIHsKKyAgICAgICAgICAgICAgICBOb2RlPEssVj4gbiA9IG5leHQ7CisgICAgICAgICAgICAgICAgYWR2YW5jZSgpOworICAgICAgICAgICAgICAgIHJldHVybiBuLmtleTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGNsYXNzIFN1Yk1hcEVudHJ5SXRlcmF0b3IgZXh0ZW5kcyBTdWJNYXBJdGVyPE1hcC5FbnRyeTxLLFY+PiB7CisgICAgICAgICAgICBwdWJsaWMgTWFwLkVudHJ5PEssVj4gbmV4dCgpIHsKKyAgICAgICAgICAgICAgICBOb2RlPEssVj4gbiA9IG5leHQ7CisgICAgICAgICAgICAgICAgViB2ID0gbmV4dFZhbHVlOworICAgICAgICAgICAgICAgIGFkdmFuY2UoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFic3RyYWN0TWFwLlNpbXBsZUltbXV0YWJsZUVudHJ5PEssVj4obi5rZXksIHYpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gVW5zYWZlIG1lY2hhbmljcworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHN1bi5taXNjLlVuc2FmZSBVTlNBRkUgPSBzdW4ubWlzYy5VbnNhZmUuZ2V0VW5zYWZlKCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBoZWFkT2Zmc2V0ID0KKyAgICAgICAgb2JqZWN0RmllbGRPZmZzZXQoVU5TQUZFLCAiaGVhZCIsIENvbmN1cnJlbnRTa2lwTGlzdE1hcC5jbGFzcyk7CisKKyAgICBzdGF0aWMgbG9uZyBvYmplY3RGaWVsZE9mZnNldChzdW4ubWlzYy5VbnNhZmUgVU5TQUZFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBmaWVsZCwgQ2xhc3M8Pz4ga2xhenopIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBVTlNBRkUub2JqZWN0RmllbGRPZmZzZXQoa2xhenouZ2V0RGVjbGFyZWRGaWVsZChmaWVsZCkpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hGaWVsZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb252ZXJ0IEV4Y2VwdGlvbiB0byBjb3JyZXNwb25kaW5nIEVycm9yCisgICAgICAgICAgICBOb1N1Y2hGaWVsZEVycm9yIGVycm9yID0gbmV3IE5vU3VjaEZpZWxkRXJyb3IoZmllbGQpOworICAgICAgICAgICAgZXJyb3IuaW5pdENhdXNlKGUpOworICAgICAgICAgICAgdGhyb3cgZXJyb3I7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Db25jdXJyZW50U2tpcExpc3RTZXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Db25jdXJyZW50U2tpcExpc3RTZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMjQ4NzZmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0NvbmN1cnJlbnRTa2lwTGlzdFNldC5qYXZhCkBAIC0wLDAgKzEsNDU2IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgc3VuLm1pc2MuVW5zYWZlOworCisvKioKKyAqIEEgc2NhbGFibGUgY29uY3VycmVudCB7QGxpbmsgTmF2aWdhYmxlU2V0fSBpbXBsZW1lbnRhdGlvbiBiYXNlZCBvbgorICogYSB7QGxpbmsgQ29uY3VycmVudFNraXBMaXN0TWFwfS4gIFRoZSBlbGVtZW50cyBvZiB0aGUgc2V0IGFyZSBrZXB0CisgKiBzb3J0ZWQgYWNjb3JkaW5nIHRvIHRoZWlyIHtAbGlua3BsYWluIENvbXBhcmFibGUgbmF0dXJhbCBvcmRlcmluZ30sCisgKiBvciBieSBhIHtAbGluayBDb21wYXJhdG9yfSBwcm92aWRlZCBhdCBzZXQgY3JlYXRpb24gdGltZSwgZGVwZW5kaW5nCisgKiBvbiB3aGljaCBjb25zdHJ1Y3RvciBpcyB1c2VkLgorICoKKyAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gcHJvdmlkZXMgZXhwZWN0ZWQgYXZlcmFnZSA8aT5sb2cobik8L2k+IHRpbWUKKyAqIGNvc3QgZm9yIHRoZSA8dHQ+Y29udGFpbnM8L3R0PiwgPHR0PmFkZDwvdHQ+LCBhbmQgPHR0PnJlbW92ZTwvdHQ+CisgKiBvcGVyYXRpb25zIGFuZCB0aGVpciB2YXJpYW50cy4gIEluc2VydGlvbiwgcmVtb3ZhbCwgYW5kIGFjY2VzcworICogb3BlcmF0aW9ucyBzYWZlbHkgZXhlY3V0ZSBjb25jdXJyZW50bHkgYnkgbXVsdGlwbGUgdGhyZWFkcy4KKyAqIEl0ZXJhdG9ycyBhcmUgPGk+d2Vha2x5IGNvbnNpc3RlbnQ8L2k+LCByZXR1cm5pbmcgZWxlbWVudHMKKyAqIHJlZmxlY3RpbmcgdGhlIHN0YXRlIG9mIHRoZSBzZXQgYXQgc29tZSBwb2ludCBhdCBvciBzaW5jZSB0aGUKKyAqIGNyZWF0aW9uIG9mIHRoZSBpdGVyYXRvci4gIFRoZXkgZG8gPGVtPm5vdDwvZW0+IHRocm93IHtAbGluaworICogQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0sIGFuZCBtYXkgcHJvY2VlZCBjb25jdXJyZW50bHkgd2l0aAorICogb3RoZXIgb3BlcmF0aW9ucy4gIEFzY2VuZGluZyBvcmRlcmVkIHZpZXdzIGFuZCB0aGVpciBpdGVyYXRvcnMgYXJlCisgKiBmYXN0ZXIgdGhhbiBkZXNjZW5kaW5nIG9uZXMuCisgKgorICogPHA+QmV3YXJlIHRoYXQsIHVubGlrZSBpbiBtb3N0IGNvbGxlY3Rpb25zLCB0aGUgPHR0PnNpemU8L3R0PgorICogbWV0aG9kIGlzIDxlbT5ub3Q8L2VtPiBhIGNvbnN0YW50LXRpbWUgb3BlcmF0aW9uLiBCZWNhdXNlIG9mIHRoZQorICogYXN5bmNocm9ub3VzIG5hdHVyZSBvZiB0aGVzZSBzZXRzLCBkZXRlcm1pbmluZyB0aGUgY3VycmVudCBudW1iZXIKKyAqIG9mIGVsZW1lbnRzIHJlcXVpcmVzIGEgdHJhdmVyc2FsIG9mIHRoZSBlbGVtZW50cy4gQWRkaXRpb25hbGx5LCB0aGUKKyAqIGJ1bGsgb3BlcmF0aW9ucyA8dHQ+YWRkQWxsPC90dD4sIDx0dD5yZW1vdmVBbGw8L3R0PiwKKyAqIDx0dD5yZXRhaW5BbGw8L3R0PiwgYW5kIDx0dD5jb250YWluc0FsbDwvdHQ+IGFyZSA8ZW0+bm90PC9lbT4KKyAqIGd1YXJhbnRlZWQgdG8gYmUgcGVyZm9ybWVkIGF0b21pY2FsbHkuIEZvciBleGFtcGxlLCBhbiBpdGVyYXRvcgorICogb3BlcmF0aW5nIGNvbmN1cnJlbnRseSB3aXRoIGFuIDx0dD5hZGRBbGw8L3R0PiBvcGVyYXRpb24gbWlnaHQgdmlldworICogb25seSBzb21lIG9mIHRoZSBhZGRlZCBlbGVtZW50cy4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGFuZCBpdHMgaXRlcmF0b3JzIGltcGxlbWVudCBhbGwgb2YgdGhlCisgKiA8ZW0+b3B0aW9uYWw8L2VtPiBtZXRob2RzIG9mIHRoZSB7QGxpbmsgU2V0fSBhbmQge0BsaW5rIEl0ZXJhdG9yfQorICogaW50ZXJmYWNlcy4gTGlrZSBtb3N0IG90aGVyIGNvbmN1cnJlbnQgY29sbGVjdGlvbiBpbXBsZW1lbnRhdGlvbnMsCisgKiB0aGlzIGNsYXNzIGRvZXMgbm90IHBlcm1pdCB0aGUgdXNlIG9mIDx0dD5udWxsPC90dD4gZWxlbWVudHMsCisgKiBiZWNhdXNlIDx0dD5udWxsPC90dD4gYXJndW1lbnRzIGFuZCByZXR1cm4gdmFsdWVzIGNhbm5vdCBiZSByZWxpYWJseQorICogZGlzdGluZ3Vpc2hlZCBmcm9tIHRoZSBhYnNlbmNlIG9mIGVsZW1lbnRzLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgaXMgYSBtZW1iZXIgb2YgdGhlCisgKiA8YSBocmVmPSJ7QGRvY1Jvb3R9Ly4uL3RlY2hub3Rlcy9ndWlkZXMvY29sbGVjdGlvbnMvaW5kZXguaHRtbCI+CisgKiBKYXZhIENvbGxlY3Rpb25zIEZyYW1ld29yazwvYT4uCisgKgorICogQGF1dGhvciBEb3VnIExlYQorICogQHBhcmFtIDxFPiB0aGUgdHlwZSBvZiBlbGVtZW50cyBtYWludGFpbmVkIGJ5IHRoaXMgc2V0CisgKiBAc2luY2UgMS42CisgKi8KK3B1YmxpYyBjbGFzcyBDb25jdXJyZW50U2tpcExpc3RTZXQ8RT4KKyAgICBleHRlbmRzIEFic3RyYWN0U2V0PEU+CisgICAgaW1wbGVtZW50cyBOYXZpZ2FibGVTZXQ8RT4sIENsb25lYWJsZSwgamF2YS5pby5TZXJpYWxpemFibGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTI0NzkxNDMxMTEwNjE2NzE1ODlMOworCisgICAgLyoqCisgICAgICogVGhlIHVuZGVybHlpbmcgbWFwLiBVc2VzIEJvb2xlYW4uVFJVRSBhcyB2YWx1ZSBmb3IgZWFjaAorICAgICAqIGVsZW1lbnQuICBUaGlzIGZpZWxkIGlzIGRlY2xhcmVkIGZpbmFsIGZvciB0aGUgc2FrZSBvZiB0aHJlYWQKKyAgICAgKiBzYWZldHksIHdoaWNoIGVudGFpbHMgc29tZSB1Z2xpbmVzcyBpbiBjbG9uZSgpCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBDb25jdXJyZW50TmF2aWdhYmxlTWFwPEUsT2JqZWN0PiBtOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldywgZW1wdHkgc2V0IHRoYXQgb3JkZXJzIGl0cyBlbGVtZW50cyBhY2NvcmRpbmcgdG8KKyAgICAgKiB0aGVpciB7QGxpbmtwbGFpbiBDb21wYXJhYmxlIG5hdHVyYWwgb3JkZXJpbmd9LgorICAgICAqLworICAgIHB1YmxpYyBDb25jdXJyZW50U2tpcExpc3RTZXQoKSB7CisgICAgICAgIG0gPSBuZXcgQ29uY3VycmVudFNraXBMaXN0TWFwPEUsT2JqZWN0PigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcsIGVtcHR5IHNldCB0aGF0IG9yZGVycyBpdHMgZWxlbWVudHMgYWNjb3JkaW5nIHRvCisgICAgICogdGhlIHNwZWNpZmllZCBjb21wYXJhdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbXBhcmF0b3IgdGhlIGNvbXBhcmF0b3IgdGhhdCB3aWxsIGJlIHVzZWQgdG8gb3JkZXIgdGhpcyBzZXQuCisgICAgICogICAgICAgIElmIDx0dD5udWxsPC90dD4sIHRoZSB7QGxpbmtwbGFpbiBDb21wYXJhYmxlIG5hdHVyYWwKKyAgICAgKiAgICAgICAgb3JkZXJpbmd9IG9mIHRoZSBlbGVtZW50cyB3aWxsIGJlIHVzZWQuCisgICAgICovCisgICAgcHVibGljIENvbmN1cnJlbnRTa2lwTGlzdFNldChDb21wYXJhdG9yPD8gc3VwZXIgRT4gY29tcGFyYXRvcikgeworICAgICAgICBtID0gbmV3IENvbmN1cnJlbnRTa2lwTGlzdE1hcDxFLE9iamVjdD4oY29tcGFyYXRvcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBzZXQgY29udGFpbmluZyB0aGUgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZAorICAgICAqIGNvbGxlY3Rpb24sIHRoYXQgb3JkZXJzIGl0cyBlbGVtZW50cyBhY2NvcmRpbmcgdG8gdGhlaXIKKyAgICAgKiB7QGxpbmtwbGFpbiBDb21wYXJhYmxlIG5hdHVyYWwgb3JkZXJpbmd9LgorICAgICAqCisgICAgICogQHBhcmFtIGMgVGhlIGVsZW1lbnRzIHRoYXQgd2lsbCBjb21wcmlzZSB0aGUgbmV3IHNldAorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBlbGVtZW50cyBpbiA8dHQ+YzwvdHQ+IGFyZQorICAgICAqICAgICAgICAgbm90IHtAbGluayBDb21wYXJhYmxlfSwgb3IgYXJlIG5vdCBtdXR1YWxseSBjb21wYXJhYmxlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gb3IgYW55CisgICAgICogICAgICAgICBvZiBpdHMgZWxlbWVudHMgYXJlIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29uY3VycmVudFNraXBMaXN0U2V0KENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGMpIHsKKyAgICAgICAgbSA9IG5ldyBDb25jdXJyZW50U2tpcExpc3RNYXA8RSxPYmplY3Q+KCk7CisgICAgICAgIGFkZEFsbChjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHNldCBjb250YWluaW5nIHRoZSBzYW1lIGVsZW1lbnRzIGFuZCB1c2luZyB0aGUKKyAgICAgKiBzYW1lIG9yZGVyaW5nIGFzIHRoZSBzcGVjaWZpZWQgc29ydGVkIHNldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzIHNvcnRlZCBzZXQgd2hvc2UgZWxlbWVudHMgd2lsbCBjb21wcmlzZSB0aGUgbmV3IHNldAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBzb3J0ZWQgc2V0IG9yIGFueQorICAgICAqICAgICAgICAgb2YgaXRzIGVsZW1lbnRzIGFyZSBudWxsCisgICAgICovCisgICAgcHVibGljIENvbmN1cnJlbnRTa2lwTGlzdFNldChTb3J0ZWRTZXQ8RT4gcykgeworICAgICAgICBtID0gbmV3IENvbmN1cnJlbnRTa2lwTGlzdE1hcDxFLE9iamVjdD4ocy5jb21wYXJhdG9yKCkpOworICAgICAgICBhZGRBbGwocyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRm9yIHVzZSBieSBzdWJtYXBzCisgICAgICovCisgICAgQ29uY3VycmVudFNraXBMaXN0U2V0KENvbmN1cnJlbnROYXZpZ2FibGVNYXA8RSxPYmplY3Q+IG0pIHsKKyAgICAgICAgdGhpcy5tID0gbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc2hhbGxvdyBjb3B5IG9mIHRoaXMgPHR0PkNvbmN1cnJlbnRTa2lwTGlzdFNldDwvdHQ+CisgICAgICogaW5zdGFuY2UuIChUaGUgZWxlbWVudHMgdGhlbXNlbHZlcyBhcmUgbm90IGNsb25lZC4pCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc2hhbGxvdyBjb3B5IG9mIHRoaXMgc2V0CisgICAgICovCisgICAgcHVibGljIENvbmN1cnJlbnRTa2lwTGlzdFNldDxFPiBjbG9uZSgpIHsKKyAgICAgICAgQ29uY3VycmVudFNraXBMaXN0U2V0PEU+IGNsb25lID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNsb25lID0gKENvbmN1cnJlbnRTa2lwTGlzdFNldDxFPikgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgICAgIGNsb25lLnNldE1hcChuZXcgQ29uY3VycmVudFNraXBMaXN0TWFwKG0pKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjbG9uZTsKKyAgICB9CisKKyAgICAvKiAtLS0tLS0tLS0tLS0tLS0tIFNldCBvcGVyYXRpb25zIC0tLS0tLS0tLS0tLS0tICovCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBzZXQuICBJZiB0aGlzIHNldAorICAgICAqIGNvbnRhaW5zIG1vcmUgdGhhbiA8dHQ+SW50ZWdlci5NQVhfVkFMVUU8L3R0PiBlbGVtZW50cywgaXQKKyAgICAgKiByZXR1cm5zIDx0dD5JbnRlZ2VyLk1BWF9WQUxVRTwvdHQ+LgorICAgICAqCisgICAgICogPHA+QmV3YXJlIHRoYXQsIHVubGlrZSBpbiBtb3N0IGNvbGxlY3Rpb25zLCB0aGlzIG1ldGhvZCBpcworICAgICAqIDxlbT5OT1Q8L2VtPiBhIGNvbnN0YW50LXRpbWUgb3BlcmF0aW9uLiBCZWNhdXNlIG9mIHRoZQorICAgICAqIGFzeW5jaHJvbm91cyBuYXR1cmUgb2YgdGhlc2Ugc2V0cywgZGV0ZXJtaW5pbmcgdGhlIGN1cnJlbnQKKyAgICAgKiBudW1iZXIgb2YgZWxlbWVudHMgcmVxdWlyZXMgdHJhdmVyc2luZyB0aGVtIGFsbCB0byBjb3VudCB0aGVtLgorICAgICAqIEFkZGl0aW9uYWxseSwgaXQgaXMgcG9zc2libGUgZm9yIHRoZSBzaXplIHRvIGNoYW5nZSBkdXJpbmcKKyAgICAgKiBleGVjdXRpb24gb2YgdGhpcyBtZXRob2QsIGluIHdoaWNoIGNhc2UgdGhlIHJldHVybmVkIHJlc3VsdAorICAgICAqIHdpbGwgYmUgaW5hY2N1cmF0ZS4gVGh1cywgdGhpcyBtZXRob2QgaXMgdHlwaWNhbGx5IG5vdCB2ZXJ5CisgICAgICogdXNlZnVsIGluIGNvbmN1cnJlbnQgYXBwbGljYXRpb25zLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgc2V0CisgICAgICovCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICByZXR1cm4gbS5zaXplKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgc2V0IGNvbnRhaW5zIG5vIGVsZW1lbnRzLgorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGlzIHNldCBjb250YWlucyBubyBlbGVtZW50cworICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgIHJldHVybiBtLmlzRW1wdHkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIDx0dD50cnVlPC90dD4gaWYgdGhpcyBzZXQgY29udGFpbnMgdGhlIHNwZWNpZmllZCBlbGVtZW50LgorICAgICAqIE1vcmUgZm9ybWFsbHksIHJldHVybnMgPHR0PnRydWU8L3R0PiBpZiBhbmQgb25seSBpZiB0aGlzIHNldAorICAgICAqIGNvbnRhaW5zIGFuIGVsZW1lbnQgPHR0PmU8L3R0PiBzdWNoIHRoYXQgPHR0Pm8uZXF1YWxzKGUpPC90dD4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBvYmplY3QgdG8gYmUgY2hlY2tlZCBmb3IgY29udGFpbm1lbnQgaW4gdGhpcyBzZXQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBzZXQgY29udGFpbnMgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGNhbm5vdCBiZQorICAgICAqICAgICAgICAgY29tcGFyZWQgd2l0aCB0aGUgZWxlbWVudHMgY3VycmVudGx5IGluIHRoaXMgc2V0CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKSB7CisgICAgICAgIHJldHVybiBtLmNvbnRhaW5zS2V5KG8pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IHRvIHRoaXMgc2V0IGlmIGl0IGlzIG5vdCBhbHJlYWR5IHByZXNlbnQuCisgICAgICogTW9yZSBmb3JtYWxseSwgYWRkcyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgPHR0PmU8L3R0PiB0byB0aGlzIHNldCBpZgorICAgICAqIHRoZSBzZXQgY29udGFpbnMgbm8gZWxlbWVudCA8dHQ+ZTI8L3R0PiBzdWNoIHRoYXQgPHR0PmUuZXF1YWxzKGUyKTwvdHQ+LgorICAgICAqIElmIHRoaXMgc2V0IGFscmVhZHkgY29udGFpbnMgdGhlIGVsZW1lbnQsIHRoZSBjYWxsIGxlYXZlcyB0aGUgc2V0CisgICAgICogdW5jaGFuZ2VkIGFuZCByZXR1cm5zIDx0dD5mYWxzZTwvdHQ+LgorICAgICAqCisgICAgICogQHBhcmFtIGUgZWxlbWVudCB0byBiZSBhZGRlZCB0byB0aGlzIHNldAorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGlzIHNldCBkaWQgbm90IGFscmVhZHkgY29udGFpbiB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBlbGVtZW50CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgPHR0PmU8L3R0PiBjYW5ub3QgYmUgY29tcGFyZWQKKyAgICAgKiAgICAgICAgIHdpdGggdGhlIGVsZW1lbnRzIGN1cnJlbnRseSBpbiB0aGlzIHNldAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBhZGQoRSBlKSB7CisgICAgICAgIHJldHVybiBtLnB1dElmQWJzZW50KGUsIEJvb2xlYW4uVFJVRSkgPT0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBmcm9tIHRoaXMgc2V0IGlmIGl0IGlzIHByZXNlbnQuCisgICAgICogTW9yZSBmb3JtYWxseSwgcmVtb3ZlcyBhbiBlbGVtZW50IDx0dD5lPC90dD4gc3VjaCB0aGF0CisgICAgICogPHR0Pm8uZXF1YWxzKGUpPC90dD4sIGlmIHRoaXMgc2V0IGNvbnRhaW5zIHN1Y2ggYW4gZWxlbWVudC4KKyAgICAgKiBSZXR1cm5zIDx0dD50cnVlPC90dD4gaWYgdGhpcyBzZXQgY29udGFpbmVkIHRoZSBlbGVtZW50IChvcgorICAgICAqIGVxdWl2YWxlbnRseSwgaWYgdGhpcyBzZXQgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbCkuCisgICAgICogKFRoaXMgc2V0IHdpbGwgbm90IGNvbnRhaW4gdGhlIGVsZW1lbnQgb25jZSB0aGUgY2FsbCByZXR1cm5zLikKKyAgICAgKgorICAgICAqIEBwYXJhbSBvIG9iamVjdCB0byBiZSByZW1vdmVkIGZyb20gdGhpcyBzZXQsIGlmIHByZXNlbnQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBzZXQgY29udGFpbmVkIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIDx0dD5vPC90dD4gY2Fubm90IGJlIGNvbXBhcmVkCisgICAgICogICAgICAgICB3aXRoIHRoZSBlbGVtZW50cyBjdXJyZW50bHkgaW4gdGhpcyBzZXQKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvKSB7CisgICAgICAgIHJldHVybiBtLnJlbW92ZShvLCBCb29sZWFuLlRSVUUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIG9mIHRoZSBlbGVtZW50cyBmcm9tIHRoaXMgc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBtLmNsZWFyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cyBpbiB0aGlzIHNldCBpbiBhc2NlbmRpbmcgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzIGluIHRoaXMgc2V0IGluIGFzY2VuZGluZyBvcmRlcgorICAgICAqLworICAgIHB1YmxpYyBJdGVyYXRvcjxFPiBpdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIG0ubmF2aWdhYmxlS2V5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzIGluIHRoaXMgc2V0IGluIGRlc2NlbmRpbmcgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzIGluIHRoaXMgc2V0IGluIGRlc2NlbmRpbmcgb3JkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3I8RT4gZGVzY2VuZGluZ0l0ZXJhdG9yKCkgeworICAgICAgICByZXR1cm4gbS5kZXNjZW5kaW5nS2V5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICB9CisKKworICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0gQWJzdHJhY3RTZXQgT3ZlcnJpZGVzIC0tLS0tLS0tLS0tLS0tICovCisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIG9iamVjdCB3aXRoIHRoaXMgc2V0IGZvciBlcXVhbGl0eS4gIFJldHVybnMKKyAgICAgKiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGFsc28gYSBzZXQsIHRoZSB0d28gc2V0cworICAgICAqIGhhdmUgdGhlIHNhbWUgc2l6ZSwgYW5kIGV2ZXJ5IG1lbWJlciBvZiB0aGUgc3BlY2lmaWVkIHNldCBpcworICAgICAqIGNvbnRhaW5lZCBpbiB0aGlzIHNldCAob3IgZXF1aXZhbGVudGx5LCBldmVyeSBtZW1iZXIgb2YgdGhpcyBzZXQgaXMKKyAgICAgKiBjb250YWluZWQgaW4gdGhlIHNwZWNpZmllZCBzZXQpLiAgVGhpcyBkZWZpbml0aW9uIGVuc3VyZXMgdGhhdCB0aGUKKyAgICAgKiBlcXVhbHMgbWV0aG9kIHdvcmtzIHByb3Blcmx5IGFjcm9zcyBkaWZmZXJlbnQgaW1wbGVtZW50YXRpb25zIG9mIHRoZQorICAgICAqIHNldCBpbnRlcmZhY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyB0aGUgb2JqZWN0IHRvIGJlIGNvbXBhcmVkIGZvciBlcXVhbGl0eSB3aXRoIHRoaXMgc2V0CisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoaXMgc2V0CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgIC8vIE92ZXJyaWRlIEFic3RyYWN0U2V0IHZlcnNpb24gdG8gYXZvaWQgY2FsbGluZyBzaXplKCkKKyAgICAgICAgaWYgKG8gPT0gdGhpcykKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBpZiAoIShvIGluc3RhbmNlb2YgU2V0KSkKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgQ29sbGVjdGlvbjw/PiBjID0gKENvbGxlY3Rpb248Pz4pIG87CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gY29udGFpbnNBbGwoYykgJiYgYy5jb250YWluc0FsbCh0aGlzKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIHVudXNlZCkgICB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIHVudXNlZCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBmcm9tIHRoaXMgc2V0IGFsbCBvZiBpdHMgZWxlbWVudHMgdGhhdCBhcmUgY29udGFpbmVkIGluCisgICAgICogdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uLiAgSWYgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGlzIGFsc28KKyAgICAgKiBhIHNldCwgdGhpcyBvcGVyYXRpb24gZWZmZWN0aXZlbHkgbW9kaWZpZXMgdGhpcyBzZXQgc28gdGhhdCBpdHMKKyAgICAgKiB2YWx1ZSBpcyB0aGUgPGk+YXN5bW1ldHJpYyBzZXQgZGlmZmVyZW5jZTwvaT4gb2YgdGhlIHR3byBzZXRzLgorICAgICAqCisgICAgICogQHBhcmFtICBjIGNvbGxlY3Rpb24gY29udGFpbmluZyBlbGVtZW50cyB0byBiZSByZW1vdmVkIGZyb20gdGhpcyBzZXQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBzZXQgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbAorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSB0eXBlcyBvZiBvbmUgb3IgbW9yZSBlbGVtZW50cyBpbiB0aGlzCisgICAgICogICAgICAgICBzZXQgYXJlIGluY29tcGF0aWJsZSB3aXRoIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIG9yIGFueQorICAgICAqICAgICAgICAgb2YgaXRzIGVsZW1lbnRzIGFyZSBudWxsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlQWxsKENvbGxlY3Rpb248Pz4gYykgeworICAgICAgICAvLyBPdmVycmlkZSBBYnN0cmFjdFNldCB2ZXJzaW9uIHRvIGF2b2lkIHVubmVjZXNzYXJ5IGNhbGwgdG8gc2l6ZSgpCisgICAgICAgIGJvb2xlYW4gbW9kaWZpZWQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChJdGVyYXRvcjw/PiBpID0gYy5pdGVyYXRvcigpOyBpLmhhc05leHQoKTsgKQorICAgICAgICAgICAgaWYgKHJlbW92ZShpLm5leHQoKSkpCisgICAgICAgICAgICAgICAgbW9kaWZpZWQgPSB0cnVlOworICAgICAgICByZXR1cm4gbW9kaWZpZWQ7CisgICAgfQorCisgICAgLyogLS0tLS0tLS0tLS0tLS0tLSBSZWxhdGlvbmFsIG9wZXJhdGlvbnMgLS0tLS0tLS0tLS0tLS0gKi8KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIEUgbG93ZXIoRSBlKSB7CisgICAgICAgIHJldHVybiBtLmxvd2VyS2V5KGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIEUgZmxvb3IoRSBlKSB7CisgICAgICAgIHJldHVybiBtLmZsb29yS2V5KGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIEUgY2VpbGluZyhFIGUpIHsKKyAgICAgICAgcmV0dXJuIG0uY2VpbGluZ0tleShlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBFIGhpZ2hlcihFIGUpIHsKKyAgICAgICAgcmV0dXJuIG0uaGlnaGVyS2V5KGUpOworICAgIH0KKworICAgIHB1YmxpYyBFIHBvbGxGaXJzdCgpIHsKKyAgICAgICAgTWFwLkVudHJ5PEUsT2JqZWN0PiBlID0gbS5wb2xsRmlyc3RFbnRyeSgpOworICAgICAgICByZXR1cm4gKGUgPT0gbnVsbCkgPyBudWxsIDogZS5nZXRLZXkoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRSBwb2xsTGFzdCgpIHsKKyAgICAgICAgTWFwLkVudHJ5PEUsT2JqZWN0PiBlID0gbS5wb2xsTGFzdEVudHJ5KCk7CisgICAgICAgIHJldHVybiAoZSA9PSBudWxsKSA/IG51bGwgOiBlLmdldEtleSgpOworICAgIH0KKworCisgICAgLyogLS0tLS0tLS0tLS0tLS0tLSBTb3J0ZWRTZXQgb3BlcmF0aW9ucyAtLS0tLS0tLS0tLS0tLSAqLworCisKKyAgICBwdWJsaWMgQ29tcGFyYXRvcjw/IHN1cGVyIEU+IGNvbXBhcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBtLmNvbXBhcmF0b3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBFIGZpcnN0KCkgeworICAgICAgICByZXR1cm4gbS5maXJzdEtleSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIEUgbGFzdCgpIHsKKyAgICAgICAgcmV0dXJuIG0ubGFzdEtleSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBmcm9tRWxlbWVudH0gb3IKKyAgICAgKiAgICAgICAgIHtAY29kZSB0b0VsZW1lbnR9IGlzIG51bGwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIE5hdmlnYWJsZVNldDxFPiBzdWJTZXQoRSBmcm9tRWxlbWVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGZyb21JbmNsdXNpdmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRSB0b0VsZW1lbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiB0b0luY2x1c2l2ZSkgeworICAgICAgICByZXR1cm4gbmV3IENvbmN1cnJlbnRTa2lwTGlzdFNldDxFPgorICAgICAgICAgICAgKG0uc3ViTWFwKGZyb21FbGVtZW50LCBmcm9tSW5jbHVzaXZlLAorICAgICAgICAgICAgICAgICAgICAgIHRvRWxlbWVudCwgICB0b0luY2x1c2l2ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSB0b0VsZW1lbnR9IGlzIG51bGwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIE5hdmlnYWJsZVNldDxFPiBoZWFkU2V0KEUgdG9FbGVtZW50LCBib29sZWFuIGluY2x1c2l2ZSkgeworICAgICAgICByZXR1cm4gbmV3IENvbmN1cnJlbnRTa2lwTGlzdFNldDxFPihtLmhlYWRNYXAodG9FbGVtZW50LCBpbmNsdXNpdmUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgZnJvbUVsZW1lbnR9IGlzIG51bGwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIE5hdmlnYWJsZVNldDxFPiB0YWlsU2V0KEUgZnJvbUVsZW1lbnQsIGJvb2xlYW4gaW5jbHVzaXZlKSB7CisgICAgICAgIHJldHVybiBuZXcgQ29uY3VycmVudFNraXBMaXN0U2V0PEU+KG0udGFpbE1hcChmcm9tRWxlbWVudCwgaW5jbHVzaXZlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIGZyb21FbGVtZW50fSBvcgorICAgICAqICAgICAgICAge0Bjb2RlIHRvRWxlbWVudH0gaXMgbnVsbAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgTmF2aWdhYmxlU2V0PEU+IHN1YlNldChFIGZyb21FbGVtZW50LCBFIHRvRWxlbWVudCkgeworICAgICAgICByZXR1cm4gc3ViU2V0KGZyb21FbGVtZW50LCB0cnVlLCB0b0VsZW1lbnQsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgdG9FbGVtZW50fSBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBOYXZpZ2FibGVTZXQ8RT4gaGVhZFNldChFIHRvRWxlbWVudCkgeworICAgICAgICByZXR1cm4gaGVhZFNldCh0b0VsZW1lbnQsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgZnJvbUVsZW1lbnR9IGlzIG51bGwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIE5hdmlnYWJsZVNldDxFPiB0YWlsU2V0KEUgZnJvbUVsZW1lbnQpIHsKKyAgICAgICAgcmV0dXJuIHRhaWxTZXQoZnJvbUVsZW1lbnQsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSByZXZlcnNlIG9yZGVyIHZpZXcgb2YgdGhlIGVsZW1lbnRzIGNvbnRhaW5lZCBpbiB0aGlzIHNldC4KKyAgICAgKiBUaGUgZGVzY2VuZGluZyBzZXQgaXMgYmFja2VkIGJ5IHRoaXMgc2V0LCBzbyBjaGFuZ2VzIHRvIHRoZSBzZXQgYXJlCisgICAgICogcmVmbGVjdGVkIGluIHRoZSBkZXNjZW5kaW5nIHNldCwgYW5kIHZpY2UtdmVyc2EuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQgc2V0IGhhcyBhbiBvcmRlcmluZyBlcXVpdmFsZW50IHRvCisgICAgICogPHR0PntAbGluayBDb2xsZWN0aW9ucyNyZXZlcnNlT3JkZXIoQ29tcGFyYXRvcikgQ29sbGVjdGlvbnMucmV2ZXJzZU9yZGVyfShjb21wYXJhdG9yKCkpPC90dD4uCisgICAgICogVGhlIGV4cHJlc3Npb24ge0Bjb2RlIHMuZGVzY2VuZGluZ1NldCgpLmRlc2NlbmRpbmdTZXQoKX0gcmV0dXJucyBhCisgICAgICogdmlldyBvZiB7QGNvZGUgc30gZXNzZW50aWFsbHkgZXF1aXZhbGVudCB0byB7QGNvZGUgc30uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcmV2ZXJzZSBvcmRlciB2aWV3IG9mIHRoaXMgc2V0CisgICAgICovCisgICAgcHVibGljIE5hdmlnYWJsZVNldDxFPiBkZXNjZW5kaW5nU2V0KCkgeworICAgICAgICByZXR1cm4gbmV3IENvbmN1cnJlbnRTa2lwTGlzdFNldChtLmRlc2NlbmRpbmdNYXAoKSk7CisgICAgfQorCisgICAgLy8gU3VwcG9ydCBmb3IgcmVzZXR0aW5nIG1hcCBpbiBjbG9uZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFVuc2FmZSB1bnNhZmUgPSBVbnNhZmUuZ2V0VW5zYWZlKCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBtYXBPZmZzZXQ7CisgICAgc3RhdGljIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1hcE9mZnNldCA9IHVuc2FmZS5vYmplY3RGaWVsZE9mZnNldAorICAgICAgICAgICAgICAgIChDb25jdXJyZW50U2tpcExpc3RTZXQuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgibSIpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7IHRocm93IG5ldyBFcnJvcihleCk7IH0KKyAgICB9CisgICAgcHJpdmF0ZSB2b2lkIHNldE1hcChDb25jdXJyZW50TmF2aWdhYmxlTWFwPEUsT2JqZWN0PiBtYXApIHsKKyAgICAgICAgdW5zYWZlLnB1dE9iamVjdFZvbGF0aWxlKHRoaXMsIG1hcE9mZnNldCwgbWFwKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Db3B5T25Xcml0ZUFycmF5TGlzdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0NvcHlPbldyaXRlQXJyYXlMaXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWNmMjU5NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Db3B5T25Xcml0ZUFycmF5TGlzdC5qYXZhCkBAIC0wLDAgKzEsNzcwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQWJzdHJhY3RMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0SXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlJhbmRvbUFjY2VzczsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuRW1wdHlBcnJheTsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuT2JqZWN0czsKKworLyoqCisgKiBBIHRocmVhZC1zYWZlIHJhbmRvbS1hY2Nlc3MgbGlzdC4KKyAqCisgKiA8cD5SZWFkIG9wZXJhdGlvbnMgKGluY2x1ZGluZyB7QGxpbmsgI2dldH0pIGRvIG5vdCBibG9jayBhbmQgbWF5IG92ZXJsYXAgd2l0aAorICogdXBkYXRlIG9wZXJhdGlvbnMuIFJlYWRzIHJlZmxlY3QgdGhlIHJlc3VsdHMgb2YgdGhlIG1vc3QgcmVjZW50bHkgY29tcGxldGVkCisgKiBvcGVyYXRpb25zLiBBZ2dyZWdhdGUgb3BlcmF0aW9ucyBsaWtlIHtAbGluayAjYWRkQWxsfSBhbmQge0BsaW5rICNjbGVhcn0gYXJlCisgKiBhdG9taWM7IHRoZXkgbmV2ZXIgZXhwb3NlIGFuIGludGVybWVkaWF0ZSBzdGF0ZS4KKyAqCisgKiA8cD5JdGVyYXRvcnMgb2YgdGhpcyBsaXN0IG5ldmVyIHRocm93IHtAbGluaworICogQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0uIFdoZW4gYW4gaXRlcmF0b3IgaXMgY3JlYXRlZCwgaXQga2VlcHMgYQorICogY29weSBvZiB0aGUgbGlzdCdzIGNvbnRlbnRzLiBJdCBpcyBhbHdheXMgc2FmZSB0byBpdGVyYXRlIHRoaXMgbGlzdCwgYnV0CisgKiBpdGVyYXRpb25zIG1heSBub3QgcmVmbGVjdCB0aGUgbGF0ZXN0IHN0YXRlIG9mIHRoZSBsaXN0LgorICoKKyAqIDxwPkl0ZXJhdG9ycyByZXR1cm5lZCBieSB0aGlzIGxpc3QgYW5kIGl0cyBzdWIgbGlzdHMgY2Fubm90IG1vZGlmeSB0aGUKKyAqIHVuZGVybHlpbmcgbGlzdC4gSW4gcGFydGljdWxhciwge0BsaW5rIEl0ZXJhdG9yI3JlbW92ZX0sIHtAbGluaworICogTGlzdEl0ZXJhdG9yI2FkZH0gYW5kIHtAbGluayBMaXN0SXRlcmF0b3Ijc2V0fSBhbGwgdGhyb3cge0BsaW5rCisgKiBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0uCisgKgorICogPHA+VGhpcyBjbGFzcyBvZmZlcnMgZXh0ZW5kZWQgQVBJIGJleW9uZCB0aGUge0BsaW5rIExpc3R9IGludGVyZmFjZS4gSXQKKyAqIGluY2x1ZGVzIGFkZGl0aW9uYWwgb3ZlcmxvYWRzIGZvciBpbmRleGVkIHNlYXJjaCAoe0BsaW5rICNpbmRleE9mfSBhbmQge0BsaW5rCisgKiAjbGFzdEluZGV4T2Z9KSBhbmQgbWV0aG9kcyBmb3IgY29uZGl0aW9uYWwgYWRkcyAoe0BsaW5rICNhZGRJZkFic2VudH0gYW5kCisgKiB7QGxpbmsgI2FkZEFsbEFic2VudH0pLgorICovCitwdWJsaWMgY2xhc3MgQ29weU9uV3JpdGVBcnJheUxpc3Q8RT4gaW1wbGVtZW50cyBMaXN0PEU+LCBSYW5kb21BY2Nlc3MsIENsb25lYWJsZSwgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDg2NzMyNjQxOTU3NDc5NDI1OTVMOworCisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIGxhdGVzdCBzbmFwc2hvdCBvZiB0aGUgbGlzdCdzIGRhdGEuIFRoaXMgZmllbGQgaXMgdm9sYXRpbGUgc28KKyAgICAgKiB0aGF0IGRhdGEgY2FuIGJlIHJlYWQgd2l0aG91dCBzeW5jaHJvbml6YXRpb24uIEFzIGEgY29uc2VxdWVuY2UsIGFsbAorICAgICAqIHdyaXRlcyB0byB0aGlzIGZpZWxkIG11c3QgYmUgYXRvbWljOyBpdCBpcyBhbiBlcnJvciB0byBtb2RpZnkgdGhlCisgICAgICogY29udGVudHMgb2YgYW4gYXJyYXkgYWZ0ZXIgaXQgaGFzIGJlZW4gYXNzaWduZWQgdG8gdGhpcyBmaWVsZC4KKyAgICAgKgorICAgICAqIFN5bmNocm9uaXphdGlvbiBpcyByZXF1aXJlZCBieSBhbGwgdXBkYXRlIG9wZXJhdGlvbnMuIFRoaXMgZGVmZW5kcworICAgICAqIGFnYWluc3Qgb25lIHVwZGF0ZSBjbG9iYmVyaW5nIHRoZSByZXN1bHQgb2YgYW5vdGhlciBvcGVyYXRpb24uIEZvcgorICAgICAqIGV4YW1wbGUsIDEwMCB0aHJlYWRzIHNpbXVsdGFuZW91c2x5IGNhbGxpbmcgYWRkKCkgd2lsbCBncm93IHRoZSBsaXN0J3MKKyAgICAgKiBzaXplIGJ5IDEwMCB3aGVuIHRoZXkgaGF2ZSBjb21wbGV0ZWQuIE5vIHVwZGF0ZSBvcGVyYXRpb25zIGFyZSBsb3N0IQorICAgICAqCisgICAgICogTWFpbnRhaW5lcnMgc2hvdWxkIGJlIGNhcmVmdWwgdG8gcmVhZCB0aGlzIGZpZWxkIG9ubHkgb25jZSBpbgorICAgICAqIG5vbi1ibG9ja2luZyByZWFkIG1ldGhvZHMuIFdyaXRlIG1ldGhvZHMgbXVzdCBiZSBzeW5jaHJvbml6ZWQgdG8gYXZvaWQKKyAgICAgKiBjbG9iYmVyaW5nIGNvbmN1cnJlbnQgd3JpdGVzLgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IHZvbGF0aWxlIE9iamVjdFtdIGVsZW1lbnRzOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBlbXB0eSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29weU9uV3JpdGVBcnJheUxpc3QoKSB7CisgICAgICAgIGVsZW1lbnRzID0gRW1wdHlBcnJheS5PQkpFQ1Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBjb250YWluaW5nIHRoZSBlbGVtZW50cyBvZiB7QGNvZGUgY29sbGVjdGlvbn0uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIENvcHlPbldyaXRlQXJyYXlMaXN0KENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgdGhpcygoRVtdKSBjb2xsZWN0aW9uLnRvQXJyYXkoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBjb250YWluaW5nIHRoZSBlbGVtZW50cyBvZiB7QGNvZGUgYXJyYXl9LgorICAgICAqLworICAgIHB1YmxpYyBDb3B5T25Xcml0ZUFycmF5TGlzdChFW10gYXJyYXkpIHsKKyAgICAgICAgdGhpcy5lbGVtZW50cyA9IEFycmF5cy5jb3B5T2YoYXJyYXksIGFycmF5Lmxlbmd0aCwgT2JqZWN0W10uY2xhc3MpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29weU9uV3JpdGVBcnJheUxpc3QgcmVzdWx0ID0gKENvcHlPbldyaXRlQXJyYXlMaXN0KSBzdXBlci5jbG9uZSgpOworICAgICAgICAgICAgcmVzdWx0LmVsZW1lbnRzID0gcmVzdWx0LmVsZW1lbnRzLmNsb25lKCk7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgIHJldHVybiBlbGVtZW50cy5sZW5ndGg7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIEUgZ2V0KGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gKEUpIGVsZW1lbnRzW2luZGV4XTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3QgbykgeworICAgICAgICByZXR1cm4gaW5kZXhPZihvKSAhPSAtMTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0FsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgT2JqZWN0W10gc25hcHNob3QgPSBlbGVtZW50czsKKyAgICAgICAgcmV0dXJuIGNvbnRhaW5zQWxsKGNvbGxlY3Rpb24sIHNuYXBzaG90LCAwLCBzbmFwc2hvdC5sZW5ndGgpOworICAgIH0KKworICAgIHN0YXRpYyBib29sZWFuIGNvbnRhaW5zQWxsKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbiwgT2JqZWN0W10gc25hcHNob3QsIGludCBmcm9tLCBpbnQgdG8pIHsKKyAgICAgICAgZm9yIChPYmplY3QgbyA6IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIGlmIChpbmRleE9mKG8sIHNuYXBzaG90LCBmcm9tLCB0bykgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VhcmNoZXMgdGhpcyBsaXN0IGZvciB7QGNvZGUgb2JqZWN0fSBhbmQgcmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0CisgICAgICogb2NjdXJyZW5jZSB0aGF0IGlzIGF0IG9yIGFmdGVyIHtAY29kZSBmcm9tfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9yIC0xIGlmIHRoZSBvYmplY3Qgd2FzIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGluZGV4T2YoRSBvYmplY3QsIGludCBmcm9tKSB7CisgICAgICAgIE9iamVjdFtdIHNuYXBzaG90ID0gZWxlbWVudHM7CisgICAgICAgIHJldHVybiBpbmRleE9mKG9iamVjdCwgc25hcHNob3QsIGZyb20sIHNuYXBzaG90Lmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIGludCBpbmRleE9mKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgT2JqZWN0W10gc25hcHNob3QgPSBlbGVtZW50czsKKyAgICAgICAgcmV0dXJuIGluZGV4T2Yob2JqZWN0LCBzbmFwc2hvdCwgMCwgc25hcHNob3QubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyB0aGlzIGxpc3QgZm9yIHtAY29kZSBvYmplY3R9IGFuZCByZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbGFzdAorICAgICAqIG9jY3VycmVuY2UgdGhhdCBpcyBiZWZvcmUge0Bjb2RlIHRvfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9yIC0xIGlmIHRoZSBvYmplY3Qgd2FzIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGxhc3RJbmRleE9mKEUgb2JqZWN0LCBpbnQgdG8pIHsKKyAgICAgICAgT2JqZWN0W10gc25hcHNob3QgPSBlbGVtZW50czsKKyAgICAgICAgcmV0dXJuIGxhc3RJbmRleE9mKG9iamVjdCwgc25hcHNob3QsIDAsIHRvKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGxhc3RJbmRleE9mKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgT2JqZWN0W10gc25hcHNob3QgPSBlbGVtZW50czsKKyAgICAgICAgcmV0dXJuIGxhc3RJbmRleE9mKG9iamVjdCwgc25hcHNob3QsIDAsIHNuYXBzaG90Lmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgcmV0dXJuIGVsZW1lbnRzLmxlbmd0aCA9PSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4ge0BsaW5rIEl0ZXJhdG9yfSB0aGF0IGl0ZXJhdGVzIG92ZXIgdGhlIGVsZW1lbnRzIG9mIHRoaXMgbGlzdAorICAgICAqIGFzIHRoZXkgd2VyZSBhdCB0aGUgdGltZSBvZiB0aGlzIG1ldGhvZCBjYWxsLiBDaGFuZ2VzIHRvIHRoZSBsaXN0IG1hZGUKKyAgICAgKiBhZnRlciB0aGlzIG1ldGhvZCBjYWxsIHdpbGwgbm90IGJlIHJlZmxlY3RlZCBieSB0aGUgaXRlcmF0b3IsIG5vciB3aWxsCisgICAgICogdGhleSB0cmlnZ2VyIGEge0BsaW5rIENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb259LgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybmVkIGl0ZXJhdG9yIGRvZXMgbm90IHN1cHBvcnQge0BsaW5rIEl0ZXJhdG9yI3JlbW92ZSgpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3I8RT4gaXRlcmF0b3IoKSB7CisgICAgICAgIE9iamVjdFtdIHNuYXBzaG90ID0gZWxlbWVudHM7CisgICAgICAgIHJldHVybiBuZXcgQ293SXRlcmF0b3I8RT4oc25hcHNob3QsIDAsIHNuYXBzaG90Lmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAbGluayBMaXN0SXRlcmF0b3J9IHRoYXQgaXRlcmF0ZXMgb3ZlciB0aGUgZWxlbWVudHMgb2YgdGhpcworICAgICAqIGxpc3QgYXMgdGhleSB3ZXJlIGF0IHRoZSB0aW1lIG9mIHRoaXMgbWV0aG9kIGNhbGwuIENoYW5nZXMgdG8gdGhlIGxpc3QKKyAgICAgKiBtYWRlIGFmdGVyIHRoaXMgbWV0aG9kIGNhbGwgd2lsbCBub3QgYmUgcmVmbGVjdGVkIGJ5IHRoZSBpdGVyYXRvciwgbm9yCisgICAgICogd2lsbCB0aGV5IHRyaWdnZXIgYSB7QGxpbmsgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0uCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQgaXRlcmF0b3IgZG9lcyBub3Qgc3VwcG9ydCB7QGxpbmsgTGlzdEl0ZXJhdG9yI2FkZH0sCisgICAgICoge0BsaW5rIExpc3RJdGVyYXRvciNzZXR9IG9yIHtAbGluayBJdGVyYXRvciNyZW1vdmUoKX0sCisgICAgICovCisgICAgcHVibGljIExpc3RJdGVyYXRvcjxFPiBsaXN0SXRlcmF0b3IoaW50IGluZGV4KSB7CisgICAgICAgIE9iamVjdFtdIHNuYXBzaG90ID0gZWxlbWVudHM7CisgICAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPiBzbmFwc2hvdC5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJpbmRleD0iICsgaW5kZXggKyAiLCBsZW5ndGg9IiArIHNuYXBzaG90Lmxlbmd0aCk7CisgICAgICAgIH0KKyAgICAgICAgQ293SXRlcmF0b3I8RT4gcmVzdWx0ID0gbmV3IENvd0l0ZXJhdG9yPEU+KHNuYXBzaG90LCAwLCBzbmFwc2hvdC5sZW5ndGgpOworICAgICAgICByZXN1bHQuaW5kZXggPSBpbmRleDsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVpdmFsZW50IHRvIHtAY29kZSBsaXN0SXRlcmF0b3IoMCl9LgorICAgICAqLworICAgIHB1YmxpYyBMaXN0SXRlcmF0b3I8RT4gbGlzdEl0ZXJhdG9yKCkgeworICAgICAgICBPYmplY3RbXSBzbmFwc2hvdCA9IGVsZW1lbnRzOworICAgICAgICByZXR1cm4gbmV3IENvd0l0ZXJhdG9yPEU+KHNuYXBzaG90LCAwLCBzbmFwc2hvdC5sZW5ndGgpOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PEU+IHN1Ykxpc3QoaW50IGZyb20sIGludCB0bykgeworICAgICAgICBPYmplY3RbXSBzbmFwc2hvdCA9IGVsZW1lbnRzOworICAgICAgICBpZiAoZnJvbSA8IDAgfHwgZnJvbSA+IHRvIHx8IHRvID4gc25hcHNob3QubGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiZnJvbT0iICsgZnJvbSArICIsIHRvPSIgKyB0byArCisgICAgICAgICAgICAgICAgICAgICIsIGxpc3Qgc2l6ZT0iICsgc25hcHNob3QubGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IENvd1N1Ykxpc3Qoc25hcHNob3QsIGZyb20sIHRvKTsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKKyAgICAgICAgcmV0dXJuIGVsZW1lbnRzLmNsb25lKCk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bmNoZWNrZWQiLCJTdXNwaWNpb3VzU3lzdGVtQXJyYXljb3B5In0pCisgICAgcHVibGljIDxUPiBUW10gdG9BcnJheShUW10gY29udGVudHMpIHsKKyAgICAgICAgT2JqZWN0W10gc25hcHNob3QgPSBlbGVtZW50czsKKyAgICAgICAgaWYgKHNuYXBzaG90Lmxlbmd0aCA+IGNvbnRlbnRzLmxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIChUW10pIEFycmF5cy5jb3B5T2Yoc25hcHNob3QsIHNuYXBzaG90Lmxlbmd0aCwgY29udGVudHMuZ2V0Q2xhc3MoKSk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzbmFwc2hvdCwgMCwgY29udGVudHMsIDAsIHNuYXBzaG90Lmxlbmd0aCk7CisgICAgICAgIGlmIChzbmFwc2hvdC5sZW5ndGggPCBjb250ZW50cy5sZW5ndGgpIHsKKyAgICAgICAgICAgIGNvbnRlbnRzW3NuYXBzaG90Lmxlbmd0aF0gPSBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb250ZW50czsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgeworICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBDb3B5T25Xcml0ZUFycmF5TGlzdCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXMgPT0gb3RoZXIKKyAgICAgICAgICAgICAgICAgICAgfHwgQXJyYXlzLmVxdWFscyhlbGVtZW50cywgKChDb3B5T25Xcml0ZUFycmF5TGlzdDw/Pikgb3RoZXIpLmVsZW1lbnRzKTsKKyAgICAgICAgfSBlbHNlIGlmIChvdGhlciBpbnN0YW5jZW9mIExpc3QpIHsKKyAgICAgICAgICAgIE9iamVjdFtdIHNuYXBzaG90ID0gZWxlbWVudHM7CisgICAgICAgICAgICBJdGVyYXRvcjw/PiBpID0gKChMaXN0PD8+KSBvdGhlcikuaXRlcmF0b3IoKTsKKyAgICAgICAgICAgIGZvciAoT2JqZWN0IG8gOiBzbmFwc2hvdCkgeworICAgICAgICAgICAgICAgIGlmICghaS5oYXNOZXh0KCkgfHwgIU9iamVjdHMuZXF1YWwobywgaS5uZXh0KCkpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gIWkuaGFzTmV4dCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiBBcnJheXMuaGFzaENvZGUoZWxlbWVudHMpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gQXJyYXlzLnRvU3RyaW5nKGVsZW1lbnRzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gYWRkKEUgZSkgeworICAgICAgICBPYmplY3RbXSBuZXdFbGVtZW50cyA9IG5ldyBPYmplY3RbZWxlbWVudHMubGVuZ3RoICsgMV07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZWxlbWVudHMsIDAsIG5ld0VsZW1lbnRzLCAwLCBlbGVtZW50cy5sZW5ndGgpOworICAgICAgICBuZXdFbGVtZW50c1tlbGVtZW50cy5sZW5ndGhdID0gZTsKKyAgICAgICAgZWxlbWVudHMgPSBuZXdFbGVtZW50czsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFkZChpbnQgaW5kZXgsIEUgZSkgeworICAgICAgICBPYmplY3RbXSBuZXdFbGVtZW50cyA9IG5ldyBPYmplY3RbZWxlbWVudHMubGVuZ3RoICsgMV07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZWxlbWVudHMsIDAsIG5ld0VsZW1lbnRzLCAwLCBpbmRleCk7CisgICAgICAgIG5ld0VsZW1lbnRzW2luZGV4XSA9IGU7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZWxlbWVudHMsIGluZGV4LCBuZXdFbGVtZW50cywgaW5kZXggKyAxLCBlbGVtZW50cy5sZW5ndGggLSBpbmRleCk7CisgICAgICAgIGVsZW1lbnRzID0gbmV3RWxlbWVudHM7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGFkZEFsbChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjb2xsZWN0aW9uKSB7CisgICAgICAgIHJldHVybiBhZGRBbGwoZWxlbWVudHMubGVuZ3RoLCBjb2xsZWN0aW9uKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gYWRkQWxsKGludCBpbmRleCwgQ29sbGVjdGlvbjw/IGV4dGVuZHMgRT4gY29sbGVjdGlvbikgeworICAgICAgICBPYmplY3RbXSB0b0FkZCA9IGNvbGxlY3Rpb24udG9BcnJheSgpOworICAgICAgICBPYmplY3RbXSBuZXdFbGVtZW50cyA9IG5ldyBPYmplY3RbZWxlbWVudHMubGVuZ3RoICsgdG9BZGQubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShlbGVtZW50cywgMCwgbmV3RWxlbWVudHMsIDAsIGluZGV4KTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0b0FkZCwgMCwgbmV3RWxlbWVudHMsIGluZGV4LCB0b0FkZC5sZW5ndGgpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVsZW1lbnRzLCBpbmRleCwKKyAgICAgICAgICAgICAgICBuZXdFbGVtZW50cywgaW5kZXggKyB0b0FkZC5sZW5ndGgsIGVsZW1lbnRzLmxlbmd0aCAtIGluZGV4KTsKKyAgICAgICAgZWxlbWVudHMgPSBuZXdFbGVtZW50czsKKyAgICAgICAgcmV0dXJuIHRvQWRkLmxlbmd0aCA+IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgZWxlbWVudHMgb2Yge0Bjb2RlIGNvbGxlY3Rpb259IHRoYXQgYXJlIG5vdCBhbHJlYWR5IHByZXNlbnQgaW4KKyAgICAgKiB0aGlzIGxpc3QuIElmIHtAY29kZSBjb2xsZWN0aW9ufSBpbmNsdWRlcyBhIHJlcGVhdGVkIHZhbHVlLCBhdCBtb3N0IG9uZQorICAgICAqIG9jY3VycmVuY2Ugb2YgdGhhdCB2YWx1ZSB3aWxsIGJlIGFkZGVkIHRvIHRoaXMgbGlzdC4gRWxlbWVudHMgYXJlIGFkZGVkCisgICAgICogYXQgdGhlIGVuZCBvZiB0aGlzIGxpc3QuCisgICAgICoKKyAgICAgKiA8cD5DYWxsZXJzIG9mIHRoaXMgbWV0aG9kIG1heSBwcmVmZXIge0BsaW5rIENvcHlPbldyaXRlQXJyYXlTZXR9LCB3aG9zZQorICAgICAqIEFQSSBpcyBtb3JlIGFwcHJvcHJpYXRlIGZvciBzZXQgb3BlcmF0aW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBhZGRBbGxBYnNlbnQoQ29sbGVjdGlvbjw/IGV4dGVuZHMgRT4gY29sbGVjdGlvbikgeworICAgICAgICBPYmplY3RbXSB0b0FkZCA9IGNvbGxlY3Rpb24udG9BcnJheSgpOworICAgICAgICBPYmplY3RbXSBuZXdFbGVtZW50cyA9IG5ldyBPYmplY3RbZWxlbWVudHMubGVuZ3RoICsgdG9BZGQubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShlbGVtZW50cywgMCwgbmV3RWxlbWVudHMsIDAsIGVsZW1lbnRzLmxlbmd0aCk7CisgICAgICAgIGludCBhZGRlZENvdW50ID0gMDsKKyAgICAgICAgZm9yIChPYmplY3QgbyA6IHRvQWRkKSB7CisgICAgICAgICAgICBpZiAoaW5kZXhPZihvLCBuZXdFbGVtZW50cywgMCwgZWxlbWVudHMubGVuZ3RoICsgYWRkZWRDb3VudCkgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICBuZXdFbGVtZW50c1tlbGVtZW50cy5sZW5ndGggKyBhZGRlZENvdW50KytdID0gbzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoYWRkZWRDb3VudCA8IHRvQWRkLmxlbmd0aCkgeworICAgICAgICAgICAgbmV3RWxlbWVudHMgPSBBcnJheXMuY29weU9mUmFuZ2UoCisgICAgICAgICAgICAgICAgICAgIG5ld0VsZW1lbnRzLCAwLCBlbGVtZW50cy5sZW5ndGggKyBhZGRlZENvdW50KTsgLy8gdHJpbSB0byBzaXplCisgICAgICAgIH0KKyAgICAgICAgZWxlbWVudHMgPSBuZXdFbGVtZW50czsKKyAgICAgICAgcmV0dXJuIGFkZGVkQ291bnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyB7QGNvZGUgb2JqZWN0fSB0byB0aGUgZW5kIG9mIHRoaXMgbGlzdCBpZiBpdCBpcyBub3QgYWxyZWFkeSBwcmVzZW50LgorICAgICAqCisgICAgICogPHA+Q2FsbGVycyBvZiB0aGlzIG1ldGhvZCBtYXkgcHJlZmVyIHtAbGluayBDb3B5T25Xcml0ZUFycmF5U2V0fSwgd2hvc2UKKyAgICAgKiBBUEkgaXMgbW9yZSBhcHByb3ByaWF0ZSBmb3Igc2V0IG9wZXJhdGlvbnMuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGFkZElmQWJzZW50KEUgb2JqZWN0KSB7CisgICAgICAgIGlmIChjb250YWlucyhvYmplY3QpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgYWRkKG9iamVjdCk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2xlYXIoKSB7CisgICAgICAgIGVsZW1lbnRzID0gRW1wdHlBcnJheS5PQkpFQ1Q7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCBFIHJlbW92ZShpbnQgaW5kZXgpIHsKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgICAgIEUgcmVtb3ZlZCA9IChFKSBlbGVtZW50c1tpbmRleF07CisgICAgICAgIHJlbW92ZVJhbmdlKGluZGV4LCBpbmRleCArIDEpOworICAgICAgICByZXR1cm4gcmVtb3ZlZDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvKSB7CisgICAgICAgIGludCBpbmRleCA9IGluZGV4T2Yobyk7CisgICAgICAgIGlmIChpbmRleCA9PSAtMSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJlbW92ZShpbmRleCk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiByZW1vdmVBbGwoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKSB7CisgICAgICAgIHJldHVybiByZW1vdmVPclJldGFpbihjb2xsZWN0aW9uLCBmYWxzZSwgMCwgZWxlbWVudHMubGVuZ3RoKSAhPSAwOworICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiByZXRhaW5BbGwoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKSB7CisgICAgICAgIHJldHVybiByZW1vdmVPclJldGFpbihjb2xsZWN0aW9uLCB0cnVlLCAwLCBlbGVtZW50cy5sZW5ndGgpICE9IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBvciByZXRhaW5zIHRoZSBlbGVtZW50cyBpbiB7QGNvZGUgY29sbGVjdGlvbn0uIFJldHVybnMgdGhlIG51bWJlcgorICAgICAqIG9mIGVsZW1lbnRzIHJlbW92ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgcmVtb3ZlT3JSZXRhaW4oQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uLCBib29sZWFuIHJldGFpbiwgaW50IGZyb20sIGludCB0bykgeworICAgICAgICBmb3IgKGludCBpID0gZnJvbTsgaSA8IHRvOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChjb2xsZWN0aW9uLmNvbnRhaW5zKGVsZW1lbnRzW2ldKSA9PSByZXRhaW4pIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFdlJ3ZlIGVuY291bnRlcmVkIGFuIGVsZW1lbnQgdGhhdCBtdXN0IGJlIHJlbW92ZWQhIENyZWF0ZSBhIG5ldworICAgICAgICAgICAgICogYXJyYXkgYW5kIGNvcHkgaW4gdGhlIHN1cnZpdmluZyBlbGVtZW50cyBvbmUgYnkgb25lLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBPYmplY3RbXSBuZXdFbGVtZW50cyA9IG5ldyBPYmplY3RbZWxlbWVudHMubGVuZ3RoIC0gMV07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVsZW1lbnRzLCAwLCBuZXdFbGVtZW50cywgMCwgaSk7CisgICAgICAgICAgICBpbnQgbmV3U2l6ZSA9IGk7CisgICAgICAgICAgICBmb3IgKGludCBqID0gaSArIDE7IGogPCB0bzsgaisrKSB7CisgICAgICAgICAgICAgICAgaWYgKGNvbGxlY3Rpb24uY29udGFpbnMoZWxlbWVudHNbal0pID09IHJldGFpbikgeworICAgICAgICAgICAgICAgICAgICBuZXdFbGVtZW50c1tuZXdTaXplKytdID0gZWxlbWVudHNbal07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogQ29weSB0aGUgZWxlbWVudHMgYWZ0ZXIgJ3RvJy4gVGhpcyBpcyBvbmx5IHVzZWZ1bCBmb3Igc3ViIGxpc3RzLAorICAgICAgICAgICAgICogd2hlcmUgJ3RvJyB3aWxsIGJlIGxlc3MgdGhhbiBlbGVtZW50cy5sZW5ndGguCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZWxlbWVudHMsIHRvLCBuZXdFbGVtZW50cywgbmV3U2l6ZSwgZWxlbWVudHMubGVuZ3RoIC0gdG8pOworICAgICAgICAgICAgbmV3U2l6ZSArPSAoZWxlbWVudHMubGVuZ3RoIC0gdG8pOworCisgICAgICAgICAgICBpZiAobmV3U2l6ZSA8IG5ld0VsZW1lbnRzLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIG5ld0VsZW1lbnRzID0gQXJyYXlzLmNvcHlPZlJhbmdlKG5ld0VsZW1lbnRzLCAwLCBuZXdTaXplKTsgLy8gdHJpbSB0byBzaXplCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgcmVtb3ZlZCA9IGVsZW1lbnRzLmxlbmd0aCAtIG5ld0VsZW1lbnRzLmxlbmd0aDsKKyAgICAgICAgICAgIGVsZW1lbnRzID0gbmV3RWxlbWVudHM7CisgICAgICAgICAgICByZXR1cm4gcmVtb3ZlZDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHdlIG1hZGUgaXQgYWxsIHRoZSB3YXkgdGhyb3VnaCB0aGUgbG9vcCB3aXRob3V0IG1ha2luZyBhbnkgY2hhbmdlcworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEUgc2V0KGludCBpbmRleCwgRSBlKSB7CisgICAgICAgIE9iamVjdFtdIG5ld0VsZW1lbnRzID0gZWxlbWVudHMuY2xvbmUoKTsKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgICAgIEUgcmVzdWx0ID0gKEUpIG5ld0VsZW1lbnRzW2luZGV4XTsKKyAgICAgICAgbmV3RWxlbWVudHNbaW5kZXhdID0gZTsKKyAgICAgICAgZWxlbWVudHMgPSBuZXdFbGVtZW50czsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVtb3ZlUmFuZ2UoaW50IGZyb20sIGludCB0bykgeworICAgICAgICBPYmplY3RbXSBuZXdFbGVtZW50cyA9IG5ldyBPYmplY3RbZWxlbWVudHMubGVuZ3RoIC0gKHRvIC0gZnJvbSldOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVsZW1lbnRzLCAwLCBuZXdFbGVtZW50cywgMCwgZnJvbSk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZWxlbWVudHMsIHRvLCBuZXdFbGVtZW50cywgZnJvbSwgZWxlbWVudHMubGVuZ3RoIC0gdG8pOworICAgICAgICBlbGVtZW50cyA9IG5ld0VsZW1lbnRzOworICAgIH0KKworICAgIHN0YXRpYyBpbnQgbGFzdEluZGV4T2YoT2JqZWN0IG8sIE9iamVjdFtdIGRhdGEsIGludCBmcm9tLCBpbnQgdG8pIHsKKyAgICAgICAgaWYgKG8gPT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IHRvIC0gMTsgaSA+PSBmcm9tOyBpLS0pIHsKKyAgICAgICAgICAgICAgICBpZiAoZGF0YVtpXSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSB0byAtIDE7IGkgPj0gZnJvbTsgaS0tKSB7CisgICAgICAgICAgICAgICAgaWYgKG8uZXF1YWxzKGRhdGFbaV0pKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgc3RhdGljIGludCBpbmRleE9mKE9iamVjdCBvLCBPYmplY3RbXSBkYXRhLCBpbnQgZnJvbSwgaW50IHRvKSB7CisgICAgICAgIGlmIChvID09IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBmcm9tOyBpIDwgdG87IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChkYXRhW2ldID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IGZyb207IGkgPCB0bzsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKG8uZXF1YWxzKGRhdGFbaV0pKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgZmluYWwgT2JqZWN0W10gZ2V0QXJyYXkoKSB7CisgICAgICAgIC8vIENvcHlPbldyaXRlQXJyYXlTZXQgbmVlZHMgdGhpcy4KKyAgICAgICAgcmV0dXJuIGVsZW1lbnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBzdWIgbGlzdCBpcyB0aHJlYWQgc2FmZSBhbmQgc3VwcG9ydHMgbm9uLWJsb2NraW5nIHJlYWRzLiBEb2luZyBzbyBpcworICAgICAqIG1vcmUgZGlmZmljdWx0IHRoYW4gaW4gdGhlIGZ1bGwgbGlzdCwgYmVjYXVzZSBlYWNoIHJlYWQgbmVlZHMgdG8gZXhhbWluZQorICAgICAqIGZvdXIgZmllbGRzIHdvcnRoIG9mIHN0YXRlOgorICAgICAqICAtIHRoZSBlbGVtZW50cyBhcnJheSBvZiB0aGUgZnVsbCBsaXN0CisgICAgICogIC0gdHdvIGludGVnZXJzIGZvciB0aGUgYm91bmRzIG9mIHRoaXMgc3ViIGxpc3QKKyAgICAgKiAgLSB0aGUgZXhwZWN0ZWQgZWxlbWVudHMgYXJyYXkgKHRvIGRldGVjdCBjb25jdXJyZW50IG1vZGlmaWNhdGlvbikKKyAgICAgKgorICAgICAqIFRoaXMgaXMgYWNjb21wbGlzaGVkIGJ5IGFnZ3JlZ2F0aW5nIHRoZSBzdWIgbGlzdCdzIHRocmVlIGZpZWxkcyBpbnRvIGEKKyAgICAgKiBzaW5nbGUgc25hcHNob3Qgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBzbGljZS4gVGhpcyBwZXJtaXRzIHJlYWRzCisgICAgICogdG8gYmUgaW50ZXJuYWxseSBjb25zaXN0ZW50IHdpdGhvdXQgc3luY2hyb25pemF0aW9uLiBUaGlzIHRha2VzIGFkdmFudGFnZQorICAgICAqIG9mIEphdmEncyBjb25jdXJyZW5jeSBzZW1hbnRpY3MgZm9yIGZpbmFsIGZpZWxkcy4KKyAgICAgKi8KKyAgICBjbGFzcyBDb3dTdWJMaXN0IGV4dGVuZHMgQWJzdHJhY3RMaXN0PEU+IHsKKworICAgICAgICAvKgorICAgICAgICAgKiBBbiBpbW11dGFibGUgc25hcHNob3Qgb2YgYSBzdWIgbGlzdCdzIHN0YXRlLiBCeSBnYXRoZXJpbmcgYWxsIHRocmVlCisgICAgICAgICAqIG9mIHRoZSBzdWIgbGlzdCdzIGZpZWxkcyBpbiBhbiBpbW11dGFibGUgb2JqZWN0LAorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSB2b2xhdGlsZSBTbGljZSBzbGljZTsKKworICAgICAgICBwdWJsaWMgQ293U3ViTGlzdChPYmplY3RbXSBleHBlY3RlZEVsZW1lbnRzLCBpbnQgZnJvbSwgaW50IHRvKSB7CisgICAgICAgICAgICB0aGlzLnNsaWNlID0gbmV3IFNsaWNlKGV4cGVjdGVkRWxlbWVudHMsIGZyb20sIHRvKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICBTbGljZSBzbGljZSA9IHRoaXMuc2xpY2U7CisgICAgICAgICAgICByZXR1cm4gc2xpY2UudG8gLSBzbGljZS5mcm9tOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICBTbGljZSBzbGljZSA9IHRoaXMuc2xpY2U7CisgICAgICAgICAgICByZXR1cm4gc2xpY2UuZnJvbSA9PSBzbGljZS50bzsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEUgZ2V0KGludCBpbmRleCkgeworICAgICAgICAgICAgU2xpY2Ugc2xpY2UgPSB0aGlzLnNsaWNlOworICAgICAgICAgICAgT2JqZWN0W10gc25hcHNob3QgPSBlbGVtZW50czsKKyAgICAgICAgICAgIHNsaWNlLmNoZWNrRWxlbWVudEluZGV4KGluZGV4KTsKKyAgICAgICAgICAgIHNsaWNlLmNoZWNrQ29uY3VycmVudE1vZGlmaWNhdGlvbihzbmFwc2hvdCk7CisgICAgICAgICAgICByZXR1cm4gKEUpIHNuYXBzaG90W2luZGV4ICsgc2xpY2UuZnJvbV07CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEl0ZXJhdG9yPEU+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIGxpc3RJdGVyYXRvcigwKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgTGlzdEl0ZXJhdG9yPEU+IGxpc3RJdGVyYXRvcigpIHsKKyAgICAgICAgICAgIHJldHVybiBsaXN0SXRlcmF0b3IoMCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIExpc3RJdGVyYXRvcjxFPiBsaXN0SXRlcmF0b3IoaW50IGluZGV4KSB7CisgICAgICAgICAgICBTbGljZSBzbGljZSA9IHRoaXMuc2xpY2U7CisgICAgICAgICAgICBPYmplY3RbXSBzbmFwc2hvdCA9IGVsZW1lbnRzOworICAgICAgICAgICAgc2xpY2UuY2hlY2tQb3NpdGlvbkluZGV4KGluZGV4KTsKKyAgICAgICAgICAgIHNsaWNlLmNoZWNrQ29uY3VycmVudE1vZGlmaWNhdGlvbihzbmFwc2hvdCk7CisgICAgICAgICAgICBDb3dJdGVyYXRvcjxFPiByZXN1bHQgPSBuZXcgQ293SXRlcmF0b3I8RT4oc25hcHNob3QsIHNsaWNlLmZyb20sIHNsaWNlLnRvKTsKKyAgICAgICAgICAgIHJlc3VsdC5pbmRleCA9IHNsaWNlLmZyb20gKyBpbmRleDsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBpbmRleE9mKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIFNsaWNlIHNsaWNlID0gdGhpcy5zbGljZTsKKyAgICAgICAgICAgIE9iamVjdFtdIHNuYXBzaG90ID0gZWxlbWVudHM7CisgICAgICAgICAgICBzbGljZS5jaGVja0NvbmN1cnJlbnRNb2RpZmljYXRpb24oc25hcHNob3QpOworICAgICAgICAgICAgaW50IHJlc3VsdCA9IENvcHlPbldyaXRlQXJyYXlMaXN0LmluZGV4T2Yob2JqZWN0LCBzbmFwc2hvdCwgc2xpY2UuZnJvbSwgc2xpY2UudG8pOworICAgICAgICAgICAgcmV0dXJuIChyZXN1bHQgIT0gLTEpID8gKHJlc3VsdCAtIHNsaWNlLmZyb20pIDogLTE7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBsYXN0SW5kZXhPZihPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICBTbGljZSBzbGljZSA9IHRoaXMuc2xpY2U7CisgICAgICAgICAgICBPYmplY3RbXSBzbmFwc2hvdCA9IGVsZW1lbnRzOworICAgICAgICAgICAgc2xpY2UuY2hlY2tDb25jdXJyZW50TW9kaWZpY2F0aW9uKHNuYXBzaG90KTsKKyAgICAgICAgICAgIGludCByZXN1bHQgPSBDb3B5T25Xcml0ZUFycmF5TGlzdC5sYXN0SW5kZXhPZihvYmplY3QsIHNuYXBzaG90LCBzbGljZS5mcm9tLCBzbGljZS50byk7CisgICAgICAgICAgICByZXR1cm4gKHJlc3VsdCAhPSAtMSkgPyAocmVzdWx0IC0gc2xpY2UuZnJvbSkgOiAtMTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gaW5kZXhPZihvYmplY3QpICE9IC0xOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQWxsKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbikgeworICAgICAgICAgICAgU2xpY2Ugc2xpY2UgPSB0aGlzLnNsaWNlOworICAgICAgICAgICAgT2JqZWN0W10gc25hcHNob3QgPSBlbGVtZW50czsKKyAgICAgICAgICAgIHNsaWNlLmNoZWNrQ29uY3VycmVudE1vZGlmaWNhdGlvbihzbmFwc2hvdCk7CisgICAgICAgICAgICByZXR1cm4gQ29weU9uV3JpdGVBcnJheUxpc3QuY29udGFpbnNBbGwoY29sbGVjdGlvbiwgc25hcHNob3QsIHNsaWNlLmZyb20sIHNsaWNlLnRvKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgTGlzdDxFPiBzdWJMaXN0KGludCBmcm9tLCBpbnQgdG8pIHsKKyAgICAgICAgICAgIFNsaWNlIHNsaWNlID0gdGhpcy5zbGljZTsKKyAgICAgICAgICAgIGlmIChmcm9tIDwgMCB8fCBmcm9tID4gdG8gfHwgdG8gPiBzaXplKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiZnJvbT0iICsgZnJvbSArICIsIHRvPSIgKyB0byArCisgICAgICAgICAgICAgICAgICAgICAgICAiLCBsaXN0IHNpemU9IiArIHNpemUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IENvd1N1Ykxpc3Qoc2xpY2UuZXhwZWN0ZWRFbGVtZW50cywgc2xpY2UuZnJvbSArIGZyb20sIHNsaWNlLmZyb20gKyB0byk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEUgcmVtb3ZlKGludCBpbmRleCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChDb3B5T25Xcml0ZUFycmF5TGlzdC50aGlzKSB7CisgICAgICAgICAgICAgICAgc2xpY2UuY2hlY2tFbGVtZW50SW5kZXgoaW5kZXgpOworICAgICAgICAgICAgICAgIHNsaWNlLmNoZWNrQ29uY3VycmVudE1vZGlmaWNhdGlvbihlbGVtZW50cyk7CisgICAgICAgICAgICAgICAgRSByZW1vdmVkID0gQ29weU9uV3JpdGVBcnJheUxpc3QudGhpcy5yZW1vdmUoc2xpY2UuZnJvbSArIGluZGV4KTsKKyAgICAgICAgICAgICAgICBzbGljZSA9IG5ldyBTbGljZShlbGVtZW50cywgc2xpY2UuZnJvbSwgc2xpY2UudG8gLSAxKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVtb3ZlZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoQ29weU9uV3JpdGVBcnJheUxpc3QudGhpcykgeworICAgICAgICAgICAgICAgIHNsaWNlLmNoZWNrQ29uY3VycmVudE1vZGlmaWNhdGlvbihlbGVtZW50cyk7CisgICAgICAgICAgICAgICAgQ29weU9uV3JpdGVBcnJheUxpc3QudGhpcy5yZW1vdmVSYW5nZShzbGljZS5mcm9tLCBzbGljZS50byk7CisgICAgICAgICAgICAgICAgc2xpY2UgPSBuZXcgU2xpY2UoZWxlbWVudHMsIHNsaWNlLmZyb20sIHNsaWNlLmZyb20pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGFkZChpbnQgaW5kZXgsIEUgb2JqZWN0KSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKENvcHlPbldyaXRlQXJyYXlMaXN0LnRoaXMpIHsKKyAgICAgICAgICAgICAgICBzbGljZS5jaGVja1Bvc2l0aW9uSW5kZXgoaW5kZXgpOworICAgICAgICAgICAgICAgIHNsaWNlLmNoZWNrQ29uY3VycmVudE1vZGlmaWNhdGlvbihlbGVtZW50cyk7CisgICAgICAgICAgICAgICAgQ29weU9uV3JpdGVBcnJheUxpc3QudGhpcy5hZGQoaW5kZXggKyBzbGljZS5mcm9tLCBvYmplY3QpOworICAgICAgICAgICAgICAgIHNsaWNlID0gbmV3IFNsaWNlKGVsZW1lbnRzLCBzbGljZS5mcm9tLCBzbGljZS50byArIDEpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGFkZChFIG9iamVjdCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChDb3B5T25Xcml0ZUFycmF5TGlzdC50aGlzKSB7CisgICAgICAgICAgICAgICAgYWRkKHNsaWNlLnRvIC0gc2xpY2UuZnJvbSwgb2JqZWN0KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBhZGRBbGwoaW50IGluZGV4LCBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjb2xsZWN0aW9uKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKENvcHlPbldyaXRlQXJyYXlMaXN0LnRoaXMpIHsKKyAgICAgICAgICAgICAgICBzbGljZS5jaGVja1Bvc2l0aW9uSW5kZXgoaW5kZXgpOworICAgICAgICAgICAgICAgIHNsaWNlLmNoZWNrQ29uY3VycmVudE1vZGlmaWNhdGlvbihlbGVtZW50cyk7CisgICAgICAgICAgICAgICAgaW50IG9sZFNpemUgPSBlbGVtZW50cy5sZW5ndGg7CisgICAgICAgICAgICAgICAgYm9vbGVhbiByZXN1bHQgPSBDb3B5T25Xcml0ZUFycmF5TGlzdC50aGlzLmFkZEFsbChpbmRleCArIHNsaWNlLmZyb20sIGNvbGxlY3Rpb24pOworICAgICAgICAgICAgICAgIHNsaWNlID0gbmV3IFNsaWNlKGVsZW1lbnRzLCBzbGljZS5mcm9tLCBzbGljZS50byArIChlbGVtZW50cy5sZW5ndGggLSBvbGRTaXplKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBhZGRBbGwoQ29sbGVjdGlvbjw/IGV4dGVuZHMgRT4gY29sbGVjdGlvbikgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChDb3B5T25Xcml0ZUFycmF5TGlzdC50aGlzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGFkZEFsbChzaXplKCksIGNvbGxlY3Rpb24pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBFIHNldChpbnQgaW5kZXgsIEUgb2JqZWN0KSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKENvcHlPbldyaXRlQXJyYXlMaXN0LnRoaXMpIHsKKyAgICAgICAgICAgICAgICBzbGljZS5jaGVja0VsZW1lbnRJbmRleChpbmRleCk7CisgICAgICAgICAgICAgICAgc2xpY2UuY2hlY2tDb25jdXJyZW50TW9kaWZpY2F0aW9uKGVsZW1lbnRzKTsKKyAgICAgICAgICAgICAgICBFIHJlc3VsdCA9IENvcHlPbldyaXRlQXJyYXlMaXN0LnRoaXMuc2V0KGluZGV4ICsgc2xpY2UuZnJvbSwgb2JqZWN0KTsKKyAgICAgICAgICAgICAgICBzbGljZSA9IG5ldyBTbGljZShlbGVtZW50cywgc2xpY2UuZnJvbSwgc2xpY2UudG8pOworICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoQ29weU9uV3JpdGVBcnJheUxpc3QudGhpcykgeworICAgICAgICAgICAgICAgIGludCBpbmRleCA9IGluZGV4T2Yob2JqZWN0KTsKKyAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZW1vdmUoaW5kZXgpOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIHJlbW92ZUFsbChDb2xsZWN0aW9uPD8+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoQ29weU9uV3JpdGVBcnJheUxpc3QudGhpcykgeworICAgICAgICAgICAgICAgIHNsaWNlLmNoZWNrQ29uY3VycmVudE1vZGlmaWNhdGlvbihlbGVtZW50cyk7CisgICAgICAgICAgICAgICAgaW50IHJlbW92ZWQgPSByZW1vdmVPclJldGFpbihjb2xsZWN0aW9uLCBmYWxzZSwgc2xpY2UuZnJvbSwgc2xpY2UudG8pOworICAgICAgICAgICAgICAgIHNsaWNlID0gbmV3IFNsaWNlKGVsZW1lbnRzLCBzbGljZS5mcm9tLCBzbGljZS50byAtIHJlbW92ZWQpOworICAgICAgICAgICAgICAgIHJldHVybiByZW1vdmVkICE9IDA7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gcmV0YWluQWxsKENvbGxlY3Rpb248Pz4gY29sbGVjdGlvbikgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChDb3B5T25Xcml0ZUFycmF5TGlzdC50aGlzKSB7CisgICAgICAgICAgICAgICAgc2xpY2UuY2hlY2tDb25jdXJyZW50TW9kaWZpY2F0aW9uKGVsZW1lbnRzKTsKKyAgICAgICAgICAgICAgICBpbnQgcmVtb3ZlZCA9IHJlbW92ZU9yUmV0YWluKGNvbGxlY3Rpb24sIHRydWUsIHNsaWNlLmZyb20sIHNsaWNlLnRvKTsKKyAgICAgICAgICAgICAgICBzbGljZSA9IG5ldyBTbGljZShlbGVtZW50cywgc2xpY2UuZnJvbSwgc2xpY2UudG8gLSByZW1vdmVkKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVtb3ZlZCAhPSAwOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFNsaWNlIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3RbXSBleHBlY3RlZEVsZW1lbnRzOworICAgICAgICBwcml2YXRlIGZpbmFsIGludCBmcm9tOworICAgICAgICBwcml2YXRlIGZpbmFsIGludCB0bzsKKworICAgICAgICBTbGljZShPYmplY3RbXSBleHBlY3RlZEVsZW1lbnRzLCBpbnQgZnJvbSwgaW50IHRvKSB7CisgICAgICAgICAgICB0aGlzLmV4cGVjdGVkRWxlbWVudHMgPSBleHBlY3RlZEVsZW1lbnRzOworICAgICAgICAgICAgdGhpcy5mcm9tID0gZnJvbTsKKyAgICAgICAgICAgIHRoaXMudG8gPSB0bzsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaHJvd3MgaWYge0Bjb2RlIGluZGV4fSBkb2Vzbid0IGlkZW50aWZ5IGFuIGVsZW1lbnQgaW4gdGhlIGFycmF5LgorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBjaGVja0VsZW1lbnRJbmRleChpbnQgaW5kZXgpIHsKKyAgICAgICAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gdG8gLSBmcm9tKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oImluZGV4PSIgKyBpbmRleCArICIsIHNpemU9IiArICh0byAtIGZyb20pKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaHJvd3MgaWYge0Bjb2RlIGluZGV4fSBkb2Vzbid0IGlkZW50aWZ5IGFuIGluc2VydGlvbiBwb2ludCBpbiB0aGUKKyAgICAgICAgICogYXJyYXkuIFVubGlrZSBlbGVtZW50IGluZGV4LCBpdCdzIG9rYXkgdG8gYWRkIG9yIGl0ZXJhdGUgYXQgc2l6ZSgpLgorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBjaGVja1Bvc2l0aW9uSW5kZXgoaW50IGluZGV4KSB7CisgICAgICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID4gdG8gLSBmcm9tKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oImluZGV4PSIgKyBpbmRleCArICIsIHNpemU9IiArICh0byAtIGZyb20pKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHZvaWQgY2hlY2tDb25jdXJyZW50TW9kaWZpY2F0aW9uKE9iamVjdFtdIHNuYXBzaG90KSB7CisgICAgICAgICAgICBpZiAoZXhwZWN0ZWRFbGVtZW50cyAhPSBzbmFwc2hvdCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJdGVyYXRlcyBhbiBpbW11dGFibGUgc25hcHNob3Qgb2YgdGhlIGxpc3QuCisgICAgICovCisgICAgc3RhdGljIGNsYXNzIENvd0l0ZXJhdG9yPEU+IGltcGxlbWVudHMgTGlzdEl0ZXJhdG9yPEU+IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3RbXSBzbmFwc2hvdDsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgZnJvbTsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdG87CisgICAgICAgIHByaXZhdGUgaW50IGluZGV4ID0gMDsKKworICAgICAgICBDb3dJdGVyYXRvcihPYmplY3RbXSBzbmFwc2hvdCwgaW50IGZyb20sIGludCB0bykgeworICAgICAgICAgICAgdGhpcy5zbmFwc2hvdCA9IHNuYXBzaG90OworICAgICAgICAgICAgdGhpcy5mcm9tID0gZnJvbTsKKyAgICAgICAgICAgIHRoaXMudG8gPSB0bzsKKyAgICAgICAgICAgIHRoaXMuaW5kZXggPSBmcm9tOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgYWRkKEUgb2JqZWN0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICByZXR1cm4gaW5kZXggPCB0bzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc1ByZXZpb3VzKCkgeworICAgICAgICAgICAgcmV0dXJuIGluZGV4ID4gZnJvbTsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICBwdWJsaWMgRSBuZXh0KCkgeworICAgICAgICAgICAgaWYgKGluZGV4IDwgdG8pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gKEUpIHNuYXBzaG90W2luZGV4KytdOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBuZXh0SW5kZXgoKSB7CisgICAgICAgICAgICByZXR1cm4gaW5kZXg7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgcHVibGljIEUgcHJldmlvdXMoKSB7CisgICAgICAgICAgICBpZiAoaW5kZXggPiBmcm9tKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChFKSBzbmFwc2hvdFstLWluZGV4XTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgcHJldmlvdXNJbmRleCgpIHsKKyAgICAgICAgICAgIHJldHVybiBpbmRleCAtIDE7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldChFIG9iamVjdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0W10gc25hcHNob3QgPSBlbGVtZW50czsKKyAgICAgICAgb3V0LmRlZmF1bHRXcml0ZU9iamVjdCgpOworICAgICAgICBvdXQud3JpdGVJbnQoc25hcHNob3QubGVuZ3RoKTsKKyAgICAgICAgZm9yIChPYmplY3QgbyA6IHNuYXBzaG90KSB7CisgICAgICAgICAgICBvdXQud3JpdGVPYmplY3Qobyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gaW4pCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBpbi5kZWZhdWx0UmVhZE9iamVjdCgpOworICAgICAgICBPYmplY3RbXSBzbmFwc2hvdCA9IG5ldyBPYmplY3RbaW4ucmVhZEludCgpXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzbmFwc2hvdC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc25hcHNob3RbaV0gPSBpbi5yZWFkT2JqZWN0KCk7CisgICAgICAgIH0KKyAgICAgICAgZWxlbWVudHMgPSBzbmFwc2hvdDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQ29weU9uV3JpdGVBcnJheVNldC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0NvcHlPbldyaXRlQXJyYXlTZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NzQxOWZjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0NvcHlPbldyaXRlQXJyYXlTZXQuamF2YQpAQCAtMCwwICsxLDM2MyBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50OworaW1wb3J0IGphdmEudXRpbC4qOworCisvLyBCRUdJTiBhbmRyb2lkLW5vdGUKKy8vIHJlbW92ZWQgbGluayB0byBjb2xsZWN0aW9ucyBmcmFtZXdvcmsgZG9jcworLy8gRU5EIGFuZHJvaWQtbm90ZQorCisvKioKKyAqIEEge0BsaW5rIGphdmEudXRpbC5TZXR9IHRoYXQgdXNlcyBhbiBpbnRlcm5hbCB7QGxpbmsgQ29weU9uV3JpdGVBcnJheUxpc3R9CisgKiBmb3IgYWxsIG9mIGl0cyBvcGVyYXRpb25zLiAgVGh1cywgaXQgc2hhcmVzIHRoZSBzYW1lIGJhc2ljIHByb3BlcnRpZXM6CisgKiA8dWw+CisgKiAgPGxpPkl0IGlzIGJlc3Qgc3VpdGVkIGZvciBhcHBsaWNhdGlvbnMgaW4gd2hpY2ggc2V0IHNpemVzIGdlbmVyYWxseQorICogICAgICAgc3RheSBzbWFsbCwgcmVhZC1vbmx5IG9wZXJhdGlvbnMKKyAqICAgICAgIHZhc3RseSBvdXRudW1iZXIgbXV0YXRpdmUgb3BlcmF0aW9ucywgYW5kIHlvdSBuZWVkCisgKiAgICAgICB0byBwcmV2ZW50IGludGVyZmVyZW5jZSBhbW9uZyB0aHJlYWRzIGR1cmluZyB0cmF2ZXJzYWwuCisgKiAgPGxpPkl0IGlzIHRocmVhZC1zYWZlLgorICogIDxsaT5NdXRhdGl2ZSBvcGVyYXRpb25zICg8dHQ+YWRkPC90dD4sIDx0dD5zZXQ8L3R0PiwgPHR0PnJlbW92ZTwvdHQ+LCBldGMuKQorICogICAgICBhcmUgZXhwZW5zaXZlIHNpbmNlIHRoZXkgdXN1YWxseSBlbnRhaWwgY29weWluZyB0aGUgZW50aXJlIHVuZGVybHlpbmcKKyAqICAgICAgYXJyYXkuCisgKiAgPGxpPkl0ZXJhdG9ycyBkbyBub3Qgc3VwcG9ydCB0aGUgbXV0YXRpdmUgPHR0PnJlbW92ZTwvdHQ+IG9wZXJhdGlvbi4KKyAqICA8bGk+VHJhdmVyc2FsIHZpYSBpdGVyYXRvcnMgaXMgZmFzdCBhbmQgY2Fubm90IGVuY291bnRlcgorICogICAgICBpbnRlcmZlcmVuY2UgZnJvbSBvdGhlciB0aHJlYWRzLiBJdGVyYXRvcnMgcmVseSBvbgorICogICAgICB1bmNoYW5naW5nIHNuYXBzaG90cyBvZiB0aGUgYXJyYXkgYXQgdGhlIHRpbWUgdGhlIGl0ZXJhdG9ycyB3ZXJlCisgKiAgICAgIGNvbnN0cnVjdGVkLgorICogPC91bD4KKyAqCisgKiA8cD4gPGI+U2FtcGxlIFVzYWdlLjwvYj4gVGhlIGZvbGxvd2luZyBjb2RlIHNrZXRjaCB1c2VzIGEKKyAqIGNvcHktb24td3JpdGUgc2V0IHRvIG1haW50YWluIGEgc2V0IG9mIEhhbmRsZXIgb2JqZWN0cyB0aGF0CisgKiBwZXJmb3JtIHNvbWUgYWN0aW9uIHVwb24gc3RhdGUgdXBkYXRlcy4KKyAqCisgKiAgPHByZT4ge0Bjb2RlCisgKiBjbGFzcyBIYW5kbGVyIHsgdm9pZCBoYW5kbGUoKTsgLi4uIH0KKyAqCisgKiBjbGFzcyBYIHsKKyAqICAgcHJpdmF0ZSBmaW5hbCBDb3B5T25Xcml0ZUFycmF5U2V0PEhhbmRsZXI+IGhhbmRsZXJzCisgKiAgICAgPSBuZXcgQ29weU9uV3JpdGVBcnJheVNldDxIYW5kbGVyPigpOworICogICBwdWJsaWMgdm9pZCBhZGRIYW5kbGVyKEhhbmRsZXIgaCkgeyBoYW5kbGVycy5hZGQoaCk7IH0KKyAqCisgKiAgIHByaXZhdGUgbG9uZyBpbnRlcm5hbFN0YXRlOworICogICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIGNoYW5nZVN0YXRlKCkgeyBpbnRlcm5hbFN0YXRlID0gLi4uOyB9CisgKgorICogICBwdWJsaWMgdm9pZCB1cGRhdGUoKSB7CisgKiAgICAgY2hhbmdlU3RhdGUoKTsKKyAqICAgICBmb3IgKEhhbmRsZXIgaGFuZGxlciA6IGhhbmRsZXJzKQorICogICAgICAgIGhhbmRsZXIuaGFuZGxlKCk7CisgKiAgIH0KKyAqIH19PC9wcmU+CisgKgorICogQHNlZSBDb3B5T25Xcml0ZUFycmF5TGlzdAorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICogQHBhcmFtIDxFPiB0aGUgdHlwZSBvZiBlbGVtZW50cyBoZWxkIGluIHRoaXMgY29sbGVjdGlvbgorICovCitwdWJsaWMgY2xhc3MgQ29weU9uV3JpdGVBcnJheVNldDxFPiBleHRlbmRzIEFic3RyYWN0U2V0PEU+CisgICAgICAgIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDU0NTc3NDc2NTEzNDQwMzQyNjNMOworCisgICAgcHJpdmF0ZSBmaW5hbCBDb3B5T25Xcml0ZUFycmF5TGlzdDxFPiBhbDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gZW1wdHkgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBDb3B5T25Xcml0ZUFycmF5U2V0KCkgeworICAgICAgICBhbCA9IG5ldyBDb3B5T25Xcml0ZUFycmF5TGlzdDxFPigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBzZXQgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIG9mIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjb2xsZWN0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGMgdGhlIGNvbGxlY3Rpb24gb2YgZWxlbWVudHMgdG8gaW5pdGlhbGx5IGNvbnRhaW4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIENvcHlPbldyaXRlQXJyYXlTZXQoQ29sbGVjdGlvbjw/IGV4dGVuZHMgRT4gYykgeworICAgICAgICBhbCA9IG5ldyBDb3B5T25Xcml0ZUFycmF5TGlzdDxFPigpOworICAgICAgICBhbC5hZGRBbGxBYnNlbnQoYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgc2V0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgc2V0CisgICAgICovCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICByZXR1cm4gYWwuc2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBpZiB0aGlzIHNldCBjb250YWlucyBubyBlbGVtZW50cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGlzIHNldCBjb250YWlucyBubyBlbGVtZW50cworICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgIHJldHVybiBhbC5pc0VtcHR5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgc2V0IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgZWxlbWVudC4KKyAgICAgKiBNb3JlIGZvcm1hbGx5LCByZXR1cm5zIDx0dD50cnVlPC90dD4gaWYgYW5kIG9ubHkgaWYgdGhpcyBzZXQKKyAgICAgKiBjb250YWlucyBhbiBlbGVtZW50IDx0dD5lPC90dD4gc3VjaCB0aGF0CisgICAgICogPHR0PihvPT1udWxsJm5ic3A7PyZuYnNwO2U9PW51bGwmbmJzcDs6Jm5ic3A7by5lcXVhbHMoZSkpPC90dD4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBlbGVtZW50IHdob3NlIHByZXNlbmNlIGluIHRoaXMgc2V0IGlzIHRvIGJlIHRlc3RlZAorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGlzIHNldCBjb250YWlucyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3QgbykgeworICAgICAgICByZXR1cm4gYWwuY29udGFpbnMobyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIGFsbCBvZiB0aGUgZWxlbWVudHMgaW4gdGhpcyBzZXQuCisgICAgICogSWYgdGhpcyBzZXQgbWFrZXMgYW55IGd1YXJhbnRlZXMgYXMgdG8gd2hhdCBvcmRlciBpdHMgZWxlbWVudHMKKyAgICAgKiBhcmUgcmV0dXJuZWQgYnkgaXRzIGl0ZXJhdG9yLCB0aGlzIG1ldGhvZCBtdXN0IHJldHVybiB0aGUKKyAgICAgKiBlbGVtZW50cyBpbiB0aGUgc2FtZSBvcmRlci4KKyAgICAgKgorICAgICAqIDxwPlRoZSByZXR1cm5lZCBhcnJheSB3aWxsIGJlICJzYWZlIiBpbiB0aGF0IG5vIHJlZmVyZW5jZXMgdG8gaXQKKyAgICAgKiBhcmUgbWFpbnRhaW5lZCBieSB0aGlzIHNldC4gIChJbiBvdGhlciB3b3JkcywgdGhpcyBtZXRob2QgbXVzdAorICAgICAqIGFsbG9jYXRlIGEgbmV3IGFycmF5IGV2ZW4gaWYgdGhpcyBzZXQgaXMgYmFja2VkIGJ5IGFuIGFycmF5KS4KKyAgICAgKiBUaGUgY2FsbGVyIGlzIHRodXMgZnJlZSB0byBtb2RpZnkgdGhlIHJldHVybmVkIGFycmF5LgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgYWN0cyBhcyBicmlkZ2UgYmV0d2VlbiBhcnJheS1iYXNlZCBhbmQgY29sbGVjdGlvbi1iYXNlZAorICAgICAqIEFQSXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IGNvbnRhaW5pbmcgYWxsIHRoZSBlbGVtZW50cyBpbiB0aGlzIHNldAorICAgICAqLworICAgIHB1YmxpYyBPYmplY3RbXSB0b0FycmF5KCkgeworICAgICAgICByZXR1cm4gYWwudG9BcnJheSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoaXMgc2V0OyB0aGUKKyAgICAgKiBydW50aW1lIHR5cGUgb2YgdGhlIHJldHVybmVkIGFycmF5IGlzIHRoYXQgb2YgdGhlIHNwZWNpZmllZCBhcnJheS4KKyAgICAgKiBJZiB0aGUgc2V0IGZpdHMgaW4gdGhlIHNwZWNpZmllZCBhcnJheSwgaXQgaXMgcmV0dXJuZWQgdGhlcmVpbi4KKyAgICAgKiBPdGhlcndpc2UsIGEgbmV3IGFycmF5IGlzIGFsbG9jYXRlZCB3aXRoIHRoZSBydW50aW1lIHR5cGUgb2YgdGhlCisgICAgICogc3BlY2lmaWVkIGFycmF5IGFuZCB0aGUgc2l6ZSBvZiB0aGlzIHNldC4KKyAgICAgKgorICAgICAqIDxwPklmIHRoaXMgc2V0IGZpdHMgaW4gdGhlIHNwZWNpZmllZCBhcnJheSB3aXRoIHJvb20gdG8gc3BhcmUKKyAgICAgKiAoaS5lLiwgdGhlIGFycmF5IGhhcyBtb3JlIGVsZW1lbnRzIHRoYW4gdGhpcyBzZXQpLCB0aGUgZWxlbWVudCBpbgorICAgICAqIHRoZSBhcnJheSBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlIGVuZCBvZiB0aGUgc2V0IGlzIHNldCB0bworICAgICAqIDx0dD5udWxsPC90dD4uICAoVGhpcyBpcyB1c2VmdWwgaW4gZGV0ZXJtaW5pbmcgdGhlIGxlbmd0aCBvZiB0aGlzCisgICAgICogc2V0IDxpPm9ubHk8L2k+IGlmIHRoZSBjYWxsZXIga25vd3MgdGhhdCB0aGlzIHNldCBkb2VzIG5vdCBjb250YWluCisgICAgICogYW55IG51bGwgZWxlbWVudHMuKQorICAgICAqCisgICAgICogPHA+SWYgdGhpcyBzZXQgbWFrZXMgYW55IGd1YXJhbnRlZXMgYXMgdG8gd2hhdCBvcmRlciBpdHMgZWxlbWVudHMKKyAgICAgKiBhcmUgcmV0dXJuZWQgYnkgaXRzIGl0ZXJhdG9yLCB0aGlzIG1ldGhvZCBtdXN0IHJldHVybiB0aGUgZWxlbWVudHMKKyAgICAgKiBpbiB0aGUgc2FtZSBvcmRlci4KKyAgICAgKgorICAgICAqIDxwPkxpa2UgdGhlIHtAbGluayAjdG9BcnJheSgpfSBtZXRob2QsIHRoaXMgbWV0aG9kIGFjdHMgYXMgYnJpZGdlIGJldHdlZW4KKyAgICAgKiBhcnJheS1iYXNlZCBhbmQgY29sbGVjdGlvbi1iYXNlZCBBUElzLiAgRnVydGhlciwgdGhpcyBtZXRob2QgYWxsb3dzCisgICAgICogcHJlY2lzZSBjb250cm9sIG92ZXIgdGhlIHJ1bnRpbWUgdHlwZSBvZiB0aGUgb3V0cHV0IGFycmF5LCBhbmQgbWF5LAorICAgICAqIHVuZGVyIGNlcnRhaW4gY2lyY3Vtc3RhbmNlcywgYmUgdXNlZCB0byBzYXZlIGFsbG9jYXRpb24gY29zdHMuCisgICAgICoKKyAgICAgKiA8cD5TdXBwb3NlIDx0dD54PC90dD4gaXMgYSBzZXQga25vd24gdG8gY29udGFpbiBvbmx5IHN0cmluZ3MuCisgICAgICogVGhlIGZvbGxvd2luZyBjb2RlIGNhbiBiZSB1c2VkIHRvIGR1bXAgdGhlIHNldCBpbnRvIGEgbmV3bHkgYWxsb2NhdGVkCisgICAgICogYXJyYXkgb2YgPHR0PlN0cmluZzwvdHQ+OgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiAgICAgU3RyaW5nW10geSA9IHgudG9BcnJheShuZXcgU3RyaW5nWzBdKTs8L3ByZT4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCA8dHQ+dG9BcnJheShuZXcgT2JqZWN0WzBdKTwvdHQ+IGlzIGlkZW50aWNhbCBpbiBmdW5jdGlvbiB0bworICAgICAqIDx0dD50b0FycmF5KCk8L3R0Pi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSBpbnRvIHdoaWNoIHRoZSBlbGVtZW50cyBvZiB0aGlzIHNldCBhcmUgdG8gYmUKKyAgICAgKiAgICAgICAgc3RvcmVkLCBpZiBpdCBpcyBiaWcgZW5vdWdoOyBvdGhlcndpc2UsIGEgbmV3IGFycmF5IG9mIHRoZSBzYW1lCisgICAgICogICAgICAgIHJ1bnRpbWUgdHlwZSBpcyBhbGxvY2F0ZWQgZm9yIHRoaXMgcHVycG9zZS4KKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IGNvbnRhaW5pbmcgYWxsIHRoZSBlbGVtZW50cyBpbiB0aGlzIHNldAorICAgICAqIEB0aHJvd3MgQXJyYXlTdG9yZUV4Y2VwdGlvbiBpZiB0aGUgcnVudGltZSB0eXBlIG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkKKyAgICAgKiAgICAgICAgIGlzIG5vdCBhIHN1cGVydHlwZSBvZiB0aGUgcnVudGltZSB0eXBlIG9mIGV2ZXJ5IGVsZW1lbnQgaW4gdGhpcworICAgICAqICAgICAgICAgc2V0CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGFycmF5IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgPFQ+IFRbXSB0b0FycmF5KFRbXSBhKSB7CisgICAgICAgIHJldHVybiBhbC50b0FycmF5KGEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIG9mIHRoZSBlbGVtZW50cyBmcm9tIHRoaXMgc2V0LgorICAgICAqIFRoZSBzZXQgd2lsbCBiZSBlbXB0eSBhZnRlciB0aGlzIGNhbGwgcmV0dXJucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgYWwuY2xlYXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBmcm9tIHRoaXMgc2V0IGlmIGl0IGlzIHByZXNlbnQuCisgICAgICogTW9yZSBmb3JtYWxseSwgcmVtb3ZlcyBhbiBlbGVtZW50IDx0dD5lPC90dD4gc3VjaCB0aGF0CisgICAgICogPHR0PihvPT1udWxsJm5ic3A7PyZuYnNwO2U9PW51bGwmbmJzcDs6Jm5ic3A7by5lcXVhbHMoZSkpPC90dD4sCisgICAgICogaWYgdGhpcyBzZXQgY29udGFpbnMgc3VjaCBhbiBlbGVtZW50LiAgUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmCisgICAgICogdGhpcyBzZXQgY29udGFpbmVkIHRoZSBlbGVtZW50IChvciBlcXVpdmFsZW50bHksIGlmIHRoaXMgc2V0CisgICAgICogY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbCkuICAoVGhpcyBzZXQgd2lsbCBub3QgY29udGFpbiB0aGUKKyAgICAgKiBlbGVtZW50IG9uY2UgdGhlIGNhbGwgcmV0dXJucy4pCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBvYmplY3QgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoaXMgc2V0LCBpZiBwcmVzZW50CisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgc2V0IGNvbnRhaW5lZCB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG8pIHsKKyAgICAgICAgcmV0dXJuIGFsLnJlbW92ZShvKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCB0byB0aGlzIHNldCBpZiBpdCBpcyBub3QgYWxyZWFkeSBwcmVzZW50LgorICAgICAqIE1vcmUgZm9ybWFsbHksIGFkZHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IDx0dD5lPC90dD4gdG8gdGhpcyBzZXQgaWYKKyAgICAgKiB0aGUgc2V0IGNvbnRhaW5zIG5vIGVsZW1lbnQgPHR0PmUyPC90dD4gc3VjaCB0aGF0CisgICAgICogPHR0PihlPT1udWxsJm5ic3A7PyZuYnNwO2UyPT1udWxsJm5ic3A7OiZuYnNwO2UuZXF1YWxzKGUyKSk8L3R0Pi4KKyAgICAgKiBJZiB0aGlzIHNldCBhbHJlYWR5IGNvbnRhaW5zIHRoZSBlbGVtZW50LCB0aGUgY2FsbCBsZWF2ZXMgdGhlIHNldAorICAgICAqIHVuY2hhbmdlZCBhbmQgcmV0dXJucyA8dHQ+ZmFsc2U8L3R0Pi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIGVsZW1lbnQgdG8gYmUgYWRkZWQgdG8gdGhpcyBzZXQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBzZXQgZGlkIG5vdCBhbHJlYWR5IGNvbnRhaW4gdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgZWxlbWVudAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGFkZChFIGUpIHsKKyAgICAgICAgcmV0dXJuIGFsLmFkZElmQWJzZW50KGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBpZiB0aGlzIHNldCBjb250YWlucyBhbGwgb2YgdGhlIGVsZW1lbnRzIG9mIHRoZQorICAgICAqIHNwZWNpZmllZCBjb2xsZWN0aW9uLiAgSWYgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGlzIGFsc28gYSBzZXQsIHRoaXMKKyAgICAgKiBtZXRob2QgcmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIGl0IGlzIGEgPGk+c3Vic2V0PC9pPiBvZiB0aGlzIHNldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgYyBjb2xsZWN0aW9uIHRvIGJlIGNoZWNrZWQgZm9yIGNvbnRhaW5tZW50IGluIHRoaXMgc2V0CisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgc2V0IGNvbnRhaW5zIGFsbCBvZiB0aGUgZWxlbWVudHMgb2YgdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgY29sbGVjdGlvbgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGlzIG51bGwKKyAgICAgKiBAc2VlICNjb250YWlucyhPYmplY3QpCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNBbGwoQ29sbGVjdGlvbjw/PiBjKSB7CisgICAgICAgIHJldHVybiBhbC5jb250YWluc0FsbChjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGFsbCBvZiB0aGUgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIHRvIHRoaXMgc2V0IGlmCisgICAgICogdGhleSdyZSBub3QgYWxyZWFkeSBwcmVzZW50LiAgSWYgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGlzIGFsc28gYQorICAgICAqIHNldCwgdGhlIDx0dD5hZGRBbGw8L3R0PiBvcGVyYXRpb24gZWZmZWN0aXZlbHkgbW9kaWZpZXMgdGhpcyBzZXQgc28KKyAgICAgKiB0aGF0IGl0cyB2YWx1ZSBpcyB0aGUgPGk+dW5pb248L2k+IG9mIHRoZSB0d28gc2V0cy4gIFRoZSBiZWhhdmlvciBvZgorICAgICAqIHRoaXMgb3BlcmF0aW9uIGlzIHVuZGVmaW5lZCBpZiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gaXMgbW9kaWZpZWQKKyAgICAgKiB3aGlsZSB0aGUgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLgorICAgICAqCisgICAgICogQHBhcmFtICBjIGNvbGxlY3Rpb24gY29udGFpbmluZyBlbGVtZW50cyB0byBiZSBhZGRlZCB0byB0aGlzIHNldAorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGlzIHNldCBjaGFuZ2VkIGFzIGEgcmVzdWx0IG9mIHRoZSBjYWxsCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gaXMgbnVsbAorICAgICAqIEBzZWUgI2FkZChPYmplY3QpCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYWRkQWxsKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGMpIHsKKyAgICAgICAgcmV0dXJuIGFsLmFkZEFsbEFic2VudChjKSA+IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBmcm9tIHRoaXMgc2V0IGFsbCBvZiBpdHMgZWxlbWVudHMgdGhhdCBhcmUgY29udGFpbmVkIGluIHRoZQorICAgICAqIHNwZWNpZmllZCBjb2xsZWN0aW9uLiAgSWYgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGlzIGFsc28gYSBzZXQsCisgICAgICogdGhpcyBvcGVyYXRpb24gZWZmZWN0aXZlbHkgbW9kaWZpZXMgdGhpcyBzZXQgc28gdGhhdCBpdHMgdmFsdWUgaXMgdGhlCisgICAgICogPGk+YXN5bW1ldHJpYyBzZXQgZGlmZmVyZW5jZTwvaT4gb2YgdGhlIHR3byBzZXRzLgorICAgICAqCisgICAgICogQHBhcmFtICBjIGNvbGxlY3Rpb24gY29udGFpbmluZyBlbGVtZW50cyB0byBiZSByZW1vdmVkIGZyb20gdGhpcyBzZXQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBzZXQgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbAorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBvZiBhbiBlbGVtZW50IG9mIHRoaXMgc2V0CisgICAgICogICAgICAgICBpcyBpbmNvbXBhdGlibGUgd2l0aCB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gKG9wdGlvbmFsKQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhpcyBzZXQgY29udGFpbnMgYSBudWxsIGVsZW1lbnQgYW5kIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIGNvbGxlY3Rpb24gZG9lcyBub3QgcGVybWl0IG51bGwgZWxlbWVudHMgKG9wdGlvbmFsKSwKKyAgICAgKiAgICAgICAgIG9yIGlmIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiBpcyBudWxsCisgICAgICogQHNlZSAjcmVtb3ZlKE9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmVBbGwoQ29sbGVjdGlvbjw/PiBjKSB7CisgICAgICAgIHJldHVybiBhbC5yZW1vdmVBbGwoYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0YWlucyBvbmx5IHRoZSBlbGVtZW50cyBpbiB0aGlzIHNldCB0aGF0IGFyZSBjb250YWluZWQgaW4gdGhlCisgICAgICogc3BlY2lmaWVkIGNvbGxlY3Rpb24uICBJbiBvdGhlciB3b3JkcywgcmVtb3ZlcyBmcm9tIHRoaXMgc2V0IGFsbCBvZgorICAgICAqIGl0cyBlbGVtZW50cyB0aGF0IGFyZSBub3QgY29udGFpbmVkIGluIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbi4gIElmCisgICAgICogdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIGlzIGFsc28gYSBzZXQsIHRoaXMgb3BlcmF0aW9uIGVmZmVjdGl2ZWx5CisgICAgICogbW9kaWZpZXMgdGhpcyBzZXQgc28gdGhhdCBpdHMgdmFsdWUgaXMgdGhlIDxpPmludGVyc2VjdGlvbjwvaT4gb2YgdGhlCisgICAgICogdHdvIHNldHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gIGMgY29sbGVjdGlvbiBjb250YWluaW5nIGVsZW1lbnRzIHRvIGJlIHJldGFpbmVkIGluIHRoaXMgc2V0CisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgc2V0IGNoYW5nZWQgYXMgYSByZXN1bHQgb2YgdGhlIGNhbGwKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3Mgb2YgYW4gZWxlbWVudCBvZiB0aGlzIHNldAorICAgICAqICAgICAgICAgaXMgaW5jb21wYXRpYmxlIHdpdGggdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIChvcHRpb25hbCkKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoaXMgc2V0IGNvbnRhaW5zIGEgbnVsbCBlbGVtZW50IGFuZCB0aGUKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBjb2xsZWN0aW9uIGRvZXMgbm90IHBlcm1pdCBudWxsIGVsZW1lbnRzIChvcHRpb25hbCksCisgICAgICogICAgICAgICBvciBpZiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gaXMgbnVsbAorICAgICAqIEBzZWUgI3JlbW92ZShPYmplY3QpCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmV0YWluQWxsKENvbGxlY3Rpb248Pz4gYykgeworICAgICAgICByZXR1cm4gYWwucmV0YWluQWxsKGMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMgY29udGFpbmVkIGluIHRoaXMgc2V0CisgICAgICogaW4gdGhlIG9yZGVyIGluIHdoaWNoIHRoZXNlIGVsZW1lbnRzIHdlcmUgYWRkZWQuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQgaXRlcmF0b3IgcHJvdmlkZXMgYSBzbmFwc2hvdCBvZiB0aGUgc3RhdGUgb2YgdGhlIHNldAorICAgICAqIHdoZW4gdGhlIGl0ZXJhdG9yIHdhcyBjb25zdHJ1Y3RlZC4gTm8gc3luY2hyb25pemF0aW9uIGlzIG5lZWRlZCB3aGlsZQorICAgICAqIHRyYXZlcnNpbmcgdGhlIGl0ZXJhdG9yLiBUaGUgaXRlcmF0b3IgZG9lcyA8ZW0+Tk9UPC9lbT4gc3VwcG9ydCB0aGUKKyAgICAgKiA8dHQ+cmVtb3ZlPC90dD4gbWV0aG9kLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cyBpbiB0aGlzIHNldAorICAgICAqLworICAgIHB1YmxpYyBJdGVyYXRvcjxFPiBpdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIGFsLml0ZXJhdG9yKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBvYmplY3Qgd2l0aCB0aGlzIHNldCBmb3IgZXF1YWxpdHkuCisgICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgdGhlIHNhbWUgb2JqZWN0CisgICAgICogYXMgdGhpcyBvYmplY3QsIG9yIGlmIGl0IGlzIGFsc28gYSB7QGxpbmsgU2V0fSBhbmQgdGhlIGVsZW1lbnRzCisgICAgICogcmV0dXJuZWQgYnkgYW4ge0BsaW5rcGxhaW4gTGlzdCNpdGVyYXRvcigpIGl0ZXJhdG9yfSBvdmVyIHRoZQorICAgICAqIHNwZWNpZmllZCBzZXQgYXJlIHRoZSBzYW1lIGFzIHRoZSBlbGVtZW50cyByZXR1cm5lZCBieSBhbgorICAgICAqIGl0ZXJhdG9yIG92ZXIgdGhpcyBzZXQuICBNb3JlIGZvcm1hbGx5LCB0aGUgdHdvIGl0ZXJhdG9ycyBhcmUKKyAgICAgKiBjb25zaWRlcmVkIHRvIHJldHVybiB0aGUgc2FtZSBlbGVtZW50cyBpZiB0aGV5IHJldHVybiB0aGUgc2FtZQorICAgICAqIG51bWJlciBvZiBlbGVtZW50cyBhbmQgZm9yIGV2ZXJ5IGVsZW1lbnQge0Bjb2RlIGUxfSByZXR1cm5lZCBieQorICAgICAqIHRoZSBpdGVyYXRvciBvdmVyIHRoZSBzcGVjaWZpZWQgc2V0LCB0aGVyZSBpcyBhbiBlbGVtZW50CisgICAgICoge0Bjb2RlIGUyfSByZXR1cm5lZCBieSB0aGUgaXRlcmF0b3Igb3ZlciB0aGlzIHNldCBzdWNoIHRoYXQKKyAgICAgKiB7QGNvZGUgKGUxPT1udWxsID8gZTI9PW51bGwgOiBlMS5lcXVhbHMoZTIpKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBvYmplY3QgdG8gYmUgY29tcGFyZWQgZm9yIGVxdWFsaXR5IHdpdGggdGhpcyBzZXQKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBlcXVhbCB0byB0aGlzIHNldAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICBpZiAobyA9PSB0aGlzKQorICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBTZXQpKQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBTZXQ8Pz4gc2V0ID0gKFNldDw/Pikobyk7CisgICAgICAgIEl0ZXJhdG9yPD8+IGl0ID0gc2V0Lml0ZXJhdG9yKCk7CisKKyAgICAgICAgLy8gVXNlcyBPKG5eMikgYWxnb3JpdGhtIHRoYXQgaXMgb25seSBhcHByb3ByaWF0ZQorICAgICAgICAvLyBmb3Igc21hbGwgc2V0cywgd2hpY2ggQ29weU9uV3JpdGVBcnJheVNldHMgc2hvdWxkIGJlLgorCisgICAgICAgIC8vICBVc2UgYSBzaW5nbGUgc25hcHNob3Qgb2YgdW5kZXJseWluZyBhcnJheQorICAgICAgICBPYmplY3RbXSBlbGVtZW50cyA9IGFsLmdldEFycmF5KCk7CisgICAgICAgIGludCBsZW4gPSBlbGVtZW50cy5sZW5ndGg7CisgICAgICAgIC8vIE1hcmsgbWF0Y2hlZCBlbGVtZW50cyB0byBhdm9pZCByZS1jaGVja2luZworICAgICAgICBib29sZWFuW10gbWF0Y2hlZCA9IG5ldyBib29sZWFuW2xlbl07CisgICAgICAgIGludCBrID0gMDsKKyAgICAgICAgb3V0ZXI6IHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIGlmICgrK2sgPiBsZW4pCisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgT2JqZWN0IHggPSBpdC5uZXh0KCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgKytpKSB7CisgICAgICAgICAgICAgICAgaWYgKCFtYXRjaGVkW2ldICYmIGVxKHgsIGVsZW1lbnRzW2ldKSkgeworICAgICAgICAgICAgICAgICAgICBtYXRjaGVkW2ldID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWUgb3V0ZXI7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBrID09IGxlbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciBlcXVhbGl0eSwgY29waW5nIHdpdGggbnVsbHMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBlcShPYmplY3QgbzEsIE9iamVjdCBvMikgeworICAgICAgICByZXR1cm4gKG8xID09IG51bGwgPyBvMiA9PSBudWxsIDogbzEuZXF1YWxzKG8yKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0NvdW50RG93bkxhdGNoLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQ291bnREb3duTGF0Y2guamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xODg4Mjc5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0NvdW50RG93bkxhdGNoLmphdmEKQEAgLTAsMCArMSwyOTEgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy4qOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy4qOworCisvKioKKyAqIEEgc3luY2hyb25pemF0aW9uIGFpZCB0aGF0IGFsbG93cyBvbmUgb3IgbW9yZSB0aHJlYWRzIHRvIHdhaXQgdW50aWwKKyAqIGEgc2V0IG9mIG9wZXJhdGlvbnMgYmVpbmcgcGVyZm9ybWVkIGluIG90aGVyIHRocmVhZHMgY29tcGxldGVzLgorICoKKyAqIDxwPkEge0Bjb2RlIENvdW50RG93bkxhdGNofSBpcyBpbml0aWFsaXplZCB3aXRoIGEgZ2l2ZW4gPGVtPmNvdW50PC9lbT4uCisgKiBUaGUge0BsaW5rICNhd2FpdCBhd2FpdH0gbWV0aG9kcyBibG9jayB1bnRpbCB0aGUgY3VycmVudCBjb3VudCByZWFjaGVzCisgKiB6ZXJvIGR1ZSB0byBpbnZvY2F0aW9ucyBvZiB0aGUge0BsaW5rICNjb3VudERvd259IG1ldGhvZCwgYWZ0ZXIgd2hpY2gKKyAqIGFsbCB3YWl0aW5nIHRocmVhZHMgYXJlIHJlbGVhc2VkIGFuZCBhbnkgc3Vic2VxdWVudCBpbnZvY2F0aW9ucyBvZgorICoge0BsaW5rICNhd2FpdCBhd2FpdH0gcmV0dXJuIGltbWVkaWF0ZWx5LiAgVGhpcyBpcyBhIG9uZS1zaG90IHBoZW5vbWVub24KKyAqIC0tIHRoZSBjb3VudCBjYW5ub3QgYmUgcmVzZXQuICBJZiB5b3UgbmVlZCBhIHZlcnNpb24gdGhhdCByZXNldHMgdGhlCisgKiBjb3VudCwgY29uc2lkZXIgdXNpbmcgYSB7QGxpbmsgQ3ljbGljQmFycmllcn0uCisgKgorICogPHA+QSB7QGNvZGUgQ291bnREb3duTGF0Y2h9IGlzIGEgdmVyc2F0aWxlIHN5bmNocm9uaXphdGlvbiB0b29sCisgKiBhbmQgY2FuIGJlIHVzZWQgZm9yIGEgbnVtYmVyIG9mIHB1cnBvc2VzLiAgQQorICoge0Bjb2RlIENvdW50RG93bkxhdGNofSBpbml0aWFsaXplZCB3aXRoIGEgY291bnQgb2Ygb25lIHNlcnZlcyBhcyBhCisgKiBzaW1wbGUgb24vb2ZmIGxhdGNoLCBvciBnYXRlOiBhbGwgdGhyZWFkcyBpbnZva2luZyB7QGxpbmsgI2F3YWl0IGF3YWl0fQorICogd2FpdCBhdCB0aGUgZ2F0ZSB1bnRpbCBpdCBpcyBvcGVuZWQgYnkgYSB0aHJlYWQgaW52b2tpbmcge0BsaW5rCisgKiAjY291bnREb3dufS4gIEEge0Bjb2RlIENvdW50RG93bkxhdGNofSBpbml0aWFsaXplZCB0byA8ZW0+TjwvZW0+CisgKiBjYW4gYmUgdXNlZCB0byBtYWtlIG9uZSB0aHJlYWQgd2FpdCB1bnRpbCA8ZW0+TjwvZW0+IHRocmVhZHMgaGF2ZQorICogY29tcGxldGVkIHNvbWUgYWN0aW9uLCBvciBzb21lIGFjdGlvbiBoYXMgYmVlbiBjb21wbGV0ZWQgTiB0aW1lcy4KKyAqCisgKiA8cD5BIHVzZWZ1bCBwcm9wZXJ0eSBvZiBhIHtAY29kZSBDb3VudERvd25MYXRjaH0gaXMgdGhhdCBpdAorICogZG9lc24ndCByZXF1aXJlIHRoYXQgdGhyZWFkcyBjYWxsaW5nIHtAY29kZSBjb3VudERvd259IHdhaXQgZm9yCisgKiB0aGUgY291bnQgdG8gcmVhY2ggemVybyBiZWZvcmUgcHJvY2VlZGluZywgaXQgc2ltcGx5IHByZXZlbnRzIGFueQorICogdGhyZWFkIGZyb20gcHJvY2VlZGluZyBwYXN0IGFuIHtAbGluayAjYXdhaXQgYXdhaXR9IHVudGlsIGFsbAorICogdGhyZWFkcyBjb3VsZCBwYXNzLgorICoKKyAqIDxwPjxiPlNhbXBsZSB1c2FnZTo8L2I+IEhlcmUgaXMgYSBwYWlyIG9mIGNsYXNzZXMgaW4gd2hpY2ggYSBncm91cAorICogb2Ygd29ya2VyIHRocmVhZHMgdXNlIHR3byBjb3VudGRvd24gbGF0Y2hlczoKKyAqIDx1bD4KKyAqIDxsaT5UaGUgZmlyc3QgaXMgYSBzdGFydCBzaWduYWwgdGhhdCBwcmV2ZW50cyBhbnkgd29ya2VyIGZyb20gcHJvY2VlZGluZworICogdW50aWwgdGhlIGRyaXZlciBpcyByZWFkeSBmb3IgdGhlbSB0byBwcm9jZWVkOworICogPGxpPlRoZSBzZWNvbmQgaXMgYSBjb21wbGV0aW9uIHNpZ25hbCB0aGF0IGFsbG93cyB0aGUgZHJpdmVyIHRvIHdhaXQKKyAqIHVudGlsIGFsbCB3b3JrZXJzIGhhdmUgY29tcGxldGVkLgorICogPC91bD4KKyAqCisgKiA8cHJlPgorICogY2xhc3MgRHJpdmVyIHsgLy8gLi4uCisgKiAgIHZvaWQgbWFpbigpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgKiAgICAgQ291bnREb3duTGF0Y2ggc3RhcnRTaWduYWwgPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisgKiAgICAgQ291bnREb3duTGF0Y2ggZG9uZVNpZ25hbCA9IG5ldyBDb3VudERvd25MYXRjaChOKTsKKyAqCisgKiAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyArK2kpIC8vIGNyZWF0ZSBhbmQgc3RhcnQgdGhyZWFkcworICogICAgICAgbmV3IFRocmVhZChuZXcgV29ya2VyKHN0YXJ0U2lnbmFsLCBkb25lU2lnbmFsKSkuc3RhcnQoKTsKKyAqCisgKiAgICAgZG9Tb21ldGhpbmdFbHNlKCk7ICAgICAgICAgICAgLy8gZG9uJ3QgbGV0IHJ1biB5ZXQKKyAqICAgICBzdGFydFNpZ25hbC5jb3VudERvd24oKTsgICAgICAvLyBsZXQgYWxsIHRocmVhZHMgcHJvY2VlZAorICogICAgIGRvU29tZXRoaW5nRWxzZSgpOworICogICAgIGRvbmVTaWduYWwuYXdhaXQoKTsgICAgICAgICAgIC8vIHdhaXQgZm9yIGFsbCB0byBmaW5pc2gKKyAqICAgfQorICogfQorICoKKyAqIGNsYXNzIFdvcmtlciBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKyAqICAgcHJpdmF0ZSBmaW5hbCBDb3VudERvd25MYXRjaCBzdGFydFNpZ25hbDsKKyAqICAgcHJpdmF0ZSBmaW5hbCBDb3VudERvd25MYXRjaCBkb25lU2lnbmFsOworICogICBXb3JrZXIoQ291bnREb3duTGF0Y2ggc3RhcnRTaWduYWwsIENvdW50RG93bkxhdGNoIGRvbmVTaWduYWwpIHsKKyAqICAgICAgdGhpcy5zdGFydFNpZ25hbCA9IHN0YXJ0U2lnbmFsOworICogICAgICB0aGlzLmRvbmVTaWduYWwgPSBkb25lU2lnbmFsOworICogICB9CisgKiAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAqICAgICAgdHJ5IHsKKyAqICAgICAgICBzdGFydFNpZ25hbC5hd2FpdCgpOworICogICAgICAgIGRvV29yaygpOworICogICAgICAgIGRvbmVTaWduYWwuY291bnREb3duKCk7CisgKiAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7fSAvLyByZXR1cm47CisgKiAgIH0KKyAqCisgKiAgIHZvaWQgZG9Xb3JrKCkgeyAuLi4gfQorICogfQorICoKKyAqIDwvcHJlPgorICoKKyAqIDxwPkFub3RoZXIgdHlwaWNhbCB1c2FnZSB3b3VsZCBiZSB0byBkaXZpZGUgYSBwcm9ibGVtIGludG8gTiBwYXJ0cywKKyAqIGRlc2NyaWJlIGVhY2ggcGFydCB3aXRoIGEgUnVubmFibGUgdGhhdCBleGVjdXRlcyB0aGF0IHBvcnRpb24gYW5kCisgKiBjb3VudHMgZG93biBvbiB0aGUgbGF0Y2gsIGFuZCBxdWV1ZSBhbGwgdGhlIFJ1bm5hYmxlcyB0byBhbgorICogRXhlY3V0b3IuICBXaGVuIGFsbCBzdWItcGFydHMgYXJlIGNvbXBsZXRlLCB0aGUgY29vcmRpbmF0aW5nIHRocmVhZAorICogd2lsbCBiZSBhYmxlIHRvIHBhc3MgdGhyb3VnaCBhd2FpdC4gKFdoZW4gdGhyZWFkcyBtdXN0IHJlcGVhdGVkbHkKKyAqIGNvdW50IGRvd24gaW4gdGhpcyB3YXksIGluc3RlYWQgdXNlIGEge0BsaW5rIEN5Y2xpY0JhcnJpZXJ9LikKKyAqCisgKiA8cHJlPgorICogY2xhc3MgRHJpdmVyMiB7IC8vIC4uLgorICogICB2b2lkIG1haW4oKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICogICAgIENvdW50RG93bkxhdGNoIGRvbmVTaWduYWwgPSBuZXcgQ291bnREb3duTGF0Y2goTik7CisgKiAgICAgRXhlY3V0b3IgZSA9IC4uLgorICoKKyAqICAgICBmb3IgKGludCBpID0gMDsgaSA8IE47ICsraSkgLy8gY3JlYXRlIGFuZCBzdGFydCB0aHJlYWRzCisgKiAgICAgICBlLmV4ZWN1dGUobmV3IFdvcmtlclJ1bm5hYmxlKGRvbmVTaWduYWwsIGkpKTsKKyAqCisgKiAgICAgZG9uZVNpZ25hbC5hd2FpdCgpOyAgICAgICAgICAgLy8gd2FpdCBmb3IgYWxsIHRvIGZpbmlzaAorICogICB9CisgKiB9CisgKgorICogY2xhc3MgV29ya2VyUnVubmFibGUgaW1wbGVtZW50cyBSdW5uYWJsZSB7CisgKiAgIHByaXZhdGUgZmluYWwgQ291bnREb3duTGF0Y2ggZG9uZVNpZ25hbDsKKyAqICAgcHJpdmF0ZSBmaW5hbCBpbnQgaTsKKyAqICAgV29ya2VyUnVubmFibGUoQ291bnREb3duTGF0Y2ggZG9uZVNpZ25hbCwgaW50IGkpIHsKKyAqICAgICAgdGhpcy5kb25lU2lnbmFsID0gZG9uZVNpZ25hbDsKKyAqICAgICAgdGhpcy5pID0gaTsKKyAqICAgfQorICogICBwdWJsaWMgdm9pZCBydW4oKSB7CisgKiAgICAgIHRyeSB7CisgKiAgICAgICAgZG9Xb3JrKGkpOworICogICAgICAgIGRvbmVTaWduYWwuY291bnREb3duKCk7CisgKiAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7fSAvLyByZXR1cm47CisgKiAgIH0KKyAqCisgKiAgIHZvaWQgZG9Xb3JrKCkgeyAuLi4gfQorICogfQorICoKKyAqIDwvcHJlPgorICoKKyAqIDxwPk1lbW9yeSBjb25zaXN0ZW5jeSBlZmZlY3RzOiBVbnRpbCB0aGUgY291bnQgcmVhY2hlcworICogemVybywgYWN0aW9ucyBpbiBhIHRocmVhZCBwcmlvciB0byBjYWxsaW5nCisgKiB7QGNvZGUgY291bnREb3duKCl9CisgKiA8YSBocmVmPSJwYWNrYWdlLXN1bW1hcnkuaHRtbCNNZW1vcnlWaXNpYmlsaXR5Ij48aT5oYXBwZW4tYmVmb3JlPC9pPjwvYT4KKyAqIGFjdGlvbnMgZm9sbG93aW5nIGEgc3VjY2Vzc2Z1bCByZXR1cm4gZnJvbSBhIGNvcnJlc3BvbmRpbmcKKyAqIHtAY29kZSBhd2FpdCgpfSBpbiBhbm90aGVyIHRocmVhZC4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKi8KK3B1YmxpYyBjbGFzcyBDb3VudERvd25MYXRjaCB7CisgICAgLyoqCisgICAgICogU3luY2hyb25pemF0aW9uIGNvbnRyb2wgRm9yIENvdW50RG93bkxhdGNoLgorICAgICAqIFVzZXMgQVFTIHN0YXRlIHRvIHJlcHJlc2VudCBjb3VudC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTeW5jIGV4dGVuZHMgQWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXIgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0OTgyMjY0OTgxOTIyMDE0Mzc0TDsKKworICAgICAgICBTeW5jKGludCBjb3VudCkgeworICAgICAgICAgICAgc2V0U3RhdGUoY291bnQpOworICAgICAgICB9CisKKyAgICAgICAgaW50IGdldENvdW50KCkgeworICAgICAgICAgICAgcmV0dXJuIGdldFN0YXRlKCk7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgaW50IHRyeUFjcXVpcmVTaGFyZWQoaW50IGFjcXVpcmVzKSB7CisgICAgICAgICAgICByZXR1cm4gKGdldFN0YXRlKCkgPT0gMCkgPyAxIDogLTE7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiB0cnlSZWxlYXNlU2hhcmVkKGludCByZWxlYXNlcykgeworICAgICAgICAgICAgLy8gRGVjcmVtZW50IGNvdW50OyBzaWduYWwgd2hlbiB0cmFuc2l0aW9uIHRvIHplcm8KKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBpbnQgYyA9IGdldFN0YXRlKCk7CisgICAgICAgICAgICAgICAgaWYgKGMgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIGludCBuZXh0YyA9IGMtMTsKKyAgICAgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldFN0YXRlKGMsIG5leHRjKSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5leHRjID09IDA7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIFN5bmMgc3luYzsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgQ291bnREb3duTGF0Y2h9IGluaXRpYWxpemVkIHdpdGggdGhlIGdpdmVuIGNvdW50LgorICAgICAqCisgICAgICogQHBhcmFtIGNvdW50IHRoZSBudW1iZXIgb2YgdGltZXMge0BsaW5rICNjb3VudERvd259IG11c3QgYmUgaW52b2tlZAorICAgICAqICAgICAgICBiZWZvcmUgdGhyZWFkcyBjYW4gcGFzcyB0aHJvdWdoIHtAbGluayAjYXdhaXR9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGNvdW50fSBpcyBuZWdhdGl2ZQorICAgICAqLworICAgIHB1YmxpYyBDb3VudERvd25MYXRjaChpbnQgY291bnQpIHsKKyAgICAgICAgaWYgKGNvdW50IDwgMCkgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiY291bnQgPCAwIik7CisgICAgICAgIHRoaXMuc3luYyA9IG5ldyBTeW5jKGNvdW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYXVzZXMgdGhlIGN1cnJlbnQgdGhyZWFkIHRvIHdhaXQgdW50aWwgdGhlIGxhdGNoIGhhcyBjb3VudGVkIGRvd24gdG8KKyAgICAgKiB6ZXJvLCB1bmxlc3MgdGhlIHRocmVhZCBpcyB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfS4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBjdXJyZW50IGNvdW50IGlzIHplcm8gdGhlbiB0aGlzIG1ldGhvZCByZXR1cm5zIGltbWVkaWF0ZWx5LgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGN1cnJlbnQgY291bnQgaXMgZ3JlYXRlciB0aGFuIHplcm8gdGhlbiB0aGUgY3VycmVudAorICAgICAqIHRocmVhZCBiZWNvbWVzIGRpc2FibGVkIGZvciB0aHJlYWQgc2NoZWR1bGluZyBwdXJwb3NlcyBhbmQgbGllcworICAgICAqIGRvcm1hbnQgdW50aWwgb25lIG9mIHR3byB0aGluZ3MgaGFwcGVuOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+VGhlIGNvdW50IHJlYWNoZXMgemVybyBkdWUgdG8gaW52b2NhdGlvbnMgb2YgdGhlCisgICAgICoge0BsaW5rICNjb3VudERvd259IG1ldGhvZDsgb3IKKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRzfQorICAgICAqIHRoZSBjdXJyZW50IHRocmVhZC4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGN1cnJlbnQgdGhyZWFkOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+aGFzIGl0cyBpbnRlcnJ1cHRlZCBzdGF0dXMgc2V0IG9uIGVudHJ5IHRvIHRoaXMgbWV0aG9kOyBvcgorICAgICAqIDxsaT5pcyB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfSB3aGlsZSB3YWl0aW5nLAorICAgICAqIDwvdWw+CisgICAgICogdGhlbiB7QGxpbmsgSW50ZXJydXB0ZWRFeGNlcHRpb259IGlzIHRocm93biBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkJ3MKKyAgICAgKiBpbnRlcnJ1cHRlZCBzdGF0dXMgaXMgY2xlYXJlZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkCisgICAgICogICAgICAgICB3aGlsZSB3YWl0aW5nCisgICAgICovCisgICAgcHVibGljIHZvaWQgYXdhaXQoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBzeW5jLmFjcXVpcmVTaGFyZWRJbnRlcnJ1cHRpYmx5KDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhdXNlcyB0aGUgY3VycmVudCB0aHJlYWQgdG8gd2FpdCB1bnRpbCB0aGUgbGF0Y2ggaGFzIGNvdW50ZWQgZG93biB0bworICAgICAqIHplcm8sIHVubGVzcyB0aGUgdGhyZWFkIGlzIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0ZWR9LAorICAgICAqIG9yIHRoZSBzcGVjaWZpZWQgd2FpdGluZyB0aW1lIGVsYXBzZXMuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgY3VycmVudCBjb3VudCBpcyB6ZXJvIHRoZW4gdGhpcyBtZXRob2QgcmV0dXJucyBpbW1lZGlhdGVseQorICAgICAqIHdpdGggdGhlIHZhbHVlIHtAY29kZSB0cnVlfS4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBjdXJyZW50IGNvdW50IGlzIGdyZWF0ZXIgdGhhbiB6ZXJvIHRoZW4gdGhlIGN1cnJlbnQKKyAgICAgKiB0aHJlYWQgYmVjb21lcyBkaXNhYmxlZCBmb3IgdGhyZWFkIHNjaGVkdWxpbmcgcHVycG9zZXMgYW5kIGxpZXMKKyAgICAgKiBkb3JtYW50IHVudGlsIG9uZSBvZiB0aHJlZSB0aGluZ3MgaGFwcGVuOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+VGhlIGNvdW50IHJlYWNoZXMgemVybyBkdWUgdG8gaW52b2NhdGlvbnMgb2YgdGhlCisgICAgICoge0BsaW5rICNjb3VudERvd259IG1ldGhvZDsgb3IKKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRzfQorICAgICAqIHRoZSBjdXJyZW50IHRocmVhZDsgb3IKKyAgICAgKiA8bGk+VGhlIHNwZWNpZmllZCB3YWl0aW5nIHRpbWUgZWxhcHNlcy4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGNvdW50IHJlYWNoZXMgemVybyB0aGVuIHRoZSBtZXRob2QgcmV0dXJucyB3aXRoIHRoZQorICAgICAqIHZhbHVlIHtAY29kZSB0cnVlfS4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBjdXJyZW50IHRocmVhZDoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPmhhcyBpdHMgaW50ZXJydXB0ZWQgc3RhdHVzIHNldCBvbiBlbnRyeSB0byB0aGlzIG1ldGhvZDsgb3IKKyAgICAgKiA8bGk+aXMge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRlZH0gd2hpbGUgd2FpdGluZywKKyAgICAgKiA8L3VsPgorICAgICAqIHRoZW4ge0BsaW5rIEludGVycnVwdGVkRXhjZXB0aW9ufSBpcyB0aHJvd24gYW5kIHRoZSBjdXJyZW50IHRocmVhZCdzCisgICAgICogaW50ZXJydXB0ZWQgc3RhdHVzIGlzIGNsZWFyZWQuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgc3BlY2lmaWVkIHdhaXRpbmcgdGltZSBlbGFwc2VzIHRoZW4gdGhlIHZhbHVlIHtAY29kZSBmYWxzZX0KKyAgICAgKiBpcyByZXR1cm5lZC4gIElmIHRoZSB0aW1lIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB6ZXJvLCB0aGUgbWV0aG9kCisgICAgICogd2lsbCBub3Qgd2FpdCBhdCBhbGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGltZW91dCB0aGUgbWF4aW11bSB0aW1lIHRvIHdhaXQKKyAgICAgKiBAcGFyYW0gdW5pdCB0aGUgdGltZSB1bml0IG9mIHRoZSB7QGNvZGUgdGltZW91dH0gYXJndW1lbnQKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgY291bnQgcmVhY2hlZCB6ZXJvIGFuZCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBpZiB0aGUgd2FpdGluZyB0aW1lIGVsYXBzZWQgYmVmb3JlIHRoZSBjb3VudCByZWFjaGVkIHplcm8KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IHRocmVhZCBpcyBpbnRlcnJ1cHRlZAorICAgICAqICAgICAgICAgd2hpbGUgd2FpdGluZworICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGF3YWl0KGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHN5bmMudHJ5QWNxdWlyZVNoYXJlZE5hbm9zKDEsIHVuaXQudG9OYW5vcyh0aW1lb3V0KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVjcmVtZW50cyB0aGUgY291bnQgb2YgdGhlIGxhdGNoLCByZWxlYXNpbmcgYWxsIHdhaXRpbmcgdGhyZWFkcyBpZgorICAgICAqIHRoZSBjb3VudCByZWFjaGVzIHplcm8uCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgY3VycmVudCBjb3VudCBpcyBncmVhdGVyIHRoYW4gemVybyB0aGVuIGl0IGlzIGRlY3JlbWVudGVkLgorICAgICAqIElmIHRoZSBuZXcgY291bnQgaXMgemVybyB0aGVuIGFsbCB3YWl0aW5nIHRocmVhZHMgYXJlIHJlLWVuYWJsZWQgZm9yCisgICAgICogdGhyZWFkIHNjaGVkdWxpbmcgcHVycG9zZXMuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgY3VycmVudCBjb3VudCBlcXVhbHMgemVybyB0aGVuIG5vdGhpbmcgaGFwcGVucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjb3VudERvd24oKSB7CisgICAgICAgIHN5bmMucmVsZWFzZVNoYXJlZCgxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGNvdW50LgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgdHlwaWNhbGx5IHVzZWQgZm9yIGRlYnVnZ2luZyBhbmQgdGVzdGluZyBwdXJwb3Nlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgY291bnQKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRDb3VudCgpIHsKKyAgICAgICAgcmV0dXJuIHN5bmMuZ2V0Q291bnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGlkZW50aWZ5aW5nIHRoaXMgbGF0Y2gsIGFzIHdlbGwgYXMgaXRzIHN0YXRlLgorICAgICAqIFRoZSBzdGF0ZSwgaW4gYnJhY2tldHMsIGluY2x1ZGVzIHRoZSBTdHJpbmcge0Bjb2RlICJDb3VudCA9In0KKyAgICAgKiBmb2xsb3dlZCBieSB0aGUgY3VycmVudCBjb3VudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgaWRlbnRpZnlpbmcgdGhpcyBsYXRjaCwgYXMgd2VsbCBhcyBpdHMgc3RhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKSArICJbQ291bnQgPSAiICsgc3luYy5nZXRDb3VudCgpICsgIl0iOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9DeWNsaWNCYXJyaWVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQ3ljbGljQmFycmllci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ1NzM4YzUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvQ3ljbGljQmFycmllci5qYXZhCkBAIC0wLDAgKzEsNDU0IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3MuKjsKKworLyoqCisgKiBBIHN5bmNocm9uaXphdGlvbiBhaWQgdGhhdCBhbGxvd3MgYSBzZXQgb2YgdGhyZWFkcyB0byBhbGwgd2FpdCBmb3IKKyAqIGVhY2ggb3RoZXIgdG8gcmVhY2ggYSBjb21tb24gYmFycmllciBwb2ludC4gIEN5Y2xpY0JhcnJpZXJzIGFyZQorICogdXNlZnVsIGluIHByb2dyYW1zIGludm9sdmluZyBhIGZpeGVkIHNpemVkIHBhcnR5IG9mIHRocmVhZHMgdGhhdAorICogbXVzdCBvY2Nhc2lvbmFsbHkgd2FpdCBmb3IgZWFjaCBvdGhlci4gVGhlIGJhcnJpZXIgaXMgY2FsbGVkCisgKiA8ZW0+Y3ljbGljPC9lbT4gYmVjYXVzZSBpdCBjYW4gYmUgcmUtdXNlZCBhZnRlciB0aGUgd2FpdGluZyB0aHJlYWRzCisgKiBhcmUgcmVsZWFzZWQuCisgKgorICogPHA+QSA8dHQ+Q3ljbGljQmFycmllcjwvdHQ+IHN1cHBvcnRzIGFuIG9wdGlvbmFsIHtAbGluayBSdW5uYWJsZX0gY29tbWFuZAorICogdGhhdCBpcyBydW4gb25jZSBwZXIgYmFycmllciBwb2ludCwgYWZ0ZXIgdGhlIGxhc3QgdGhyZWFkIGluIHRoZSBwYXJ0eQorICogYXJyaXZlcywgYnV0IGJlZm9yZSBhbnkgdGhyZWFkcyBhcmUgcmVsZWFzZWQuCisgKiBUaGlzIDxlbT5iYXJyaWVyIGFjdGlvbjwvZW0+IGlzIHVzZWZ1bAorICogZm9yIHVwZGF0aW5nIHNoYXJlZC1zdGF0ZSBiZWZvcmUgYW55IG9mIHRoZSBwYXJ0aWVzIGNvbnRpbnVlLgorICoKKyAqIDxwPjxiPlNhbXBsZSB1c2FnZTo8L2I+IEhlcmUgaXMgYW4gZXhhbXBsZSBvZgorICogIHVzaW5nIGEgYmFycmllciBpbiBhIHBhcmFsbGVsIGRlY29tcG9zaXRpb24gZGVzaWduOgorICogPHByZT4KKyAqIGNsYXNzIFNvbHZlciB7CisgKiAgIGZpbmFsIGludCBOOworICogICBmaW5hbCBmbG9hdFtdW10gZGF0YTsKKyAqICAgZmluYWwgQ3ljbGljQmFycmllciBiYXJyaWVyOworICoKKyAqICAgY2xhc3MgV29ya2VyIGltcGxlbWVudHMgUnVubmFibGUgeworICogICAgIGludCBteVJvdzsKKyAqICAgICBXb3JrZXIoaW50IHJvdykgeyBteVJvdyA9IHJvdzsgfQorICogICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAqICAgICAgIHdoaWxlICghZG9uZSgpKSB7CisgKiAgICAgICAgIHByb2Nlc3NSb3cobXlSb3cpOworICoKKyAqICAgICAgICAgdHJ5IHsKKyAqICAgICAgICAgICBiYXJyaWVyLmF3YWl0KCk7CisgKiAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisgKiAgICAgICAgICAgcmV0dXJuOworICogICAgICAgICB9IGNhdGNoIChCcm9rZW5CYXJyaWVyRXhjZXB0aW9uIGV4KSB7CisgKiAgICAgICAgICAgcmV0dXJuOworICogICAgICAgICB9CisgKiAgICAgICB9CisgKiAgICAgfQorICogICB9CisgKgorICogICBwdWJsaWMgU29sdmVyKGZsb2F0W11bXSBtYXRyaXgpIHsKKyAqICAgICBkYXRhID0gbWF0cml4OworICogICAgIE4gPSBtYXRyaXgubGVuZ3RoOworICogICAgIGJhcnJpZXIgPSBuZXcgQ3ljbGljQmFycmllcihOLAorICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUnVubmFibGUoKSB7CisgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVyZ2VSb3dzKC4uLik7CisgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKKyAqICAgICBmb3IgKGludCBpID0gMDsgaSA8IE47ICsraSkKKyAqICAgICAgIG5ldyBUaHJlYWQobmV3IFdvcmtlcihpKSkuc3RhcnQoKTsKKyAqCisgKiAgICAgd2FpdFVudGlsRG9uZSgpOworICogICB9CisgKiB9CisgKiA8L3ByZT4KKyAqIEhlcmUsIGVhY2ggd29ya2VyIHRocmVhZCBwcm9jZXNzZXMgYSByb3cgb2YgdGhlIG1hdHJpeCB0aGVuIHdhaXRzIGF0IHRoZQorICogYmFycmllciB1bnRpbCBhbGwgcm93cyBoYXZlIGJlZW4gcHJvY2Vzc2VkLiBXaGVuIGFsbCByb3dzIGFyZSBwcm9jZXNzZWQKKyAqIHRoZSBzdXBwbGllZCB7QGxpbmsgUnVubmFibGV9IGJhcnJpZXIgYWN0aW9uIGlzIGV4ZWN1dGVkIGFuZCBtZXJnZXMgdGhlCisgKiByb3dzLiBJZiB0aGUgbWVyZ2VyCisgKiBkZXRlcm1pbmVzIHRoYXQgYSBzb2x1dGlvbiBoYXMgYmVlbiBmb3VuZCB0aGVuIDx0dD5kb25lKCk8L3R0PiB3aWxsIHJldHVybgorICogPHR0PnRydWU8L3R0PiBhbmQgZWFjaCB3b3JrZXIgd2lsbCB0ZXJtaW5hdGUuCisgKgorICogPHA+SWYgdGhlIGJhcnJpZXIgYWN0aW9uIGRvZXMgbm90IHJlbHkgb24gdGhlIHBhcnRpZXMgYmVpbmcgc3VzcGVuZGVkIHdoZW4KKyAqIGl0IGlzIGV4ZWN1dGVkLCB0aGVuIGFueSBvZiB0aGUgdGhyZWFkcyBpbiB0aGUgcGFydHkgY291bGQgZXhlY3V0ZSB0aGF0CisgKiBhY3Rpb24gd2hlbiBpdCBpcyByZWxlYXNlZC4gVG8gZmFjaWxpdGF0ZSB0aGlzLCBlYWNoIGludm9jYXRpb24gb2YKKyAqIHtAbGluayAjYXdhaXR9IHJldHVybnMgdGhlIGFycml2YWwgaW5kZXggb2YgdGhhdCB0aHJlYWQgYXQgdGhlIGJhcnJpZXIuCisgKiBZb3UgY2FuIHRoZW4gY2hvb3NlIHdoaWNoIHRocmVhZCBzaG91bGQgZXhlY3V0ZSB0aGUgYmFycmllciBhY3Rpb24sIGZvcgorICogZXhhbXBsZToKKyAqIDxwcmU+ICBpZiAoYmFycmllci5hd2FpdCgpID09IDApIHsKKyAqICAgICAvLyBsb2cgdGhlIGNvbXBsZXRpb24gb2YgdGhpcyBpdGVyYXRpb24KKyAqICAgfTwvcHJlPgorICoKKyAqIDxwPlRoZSA8dHQ+Q3ljbGljQmFycmllcjwvdHQ+IHVzZXMgYW4gYWxsLW9yLW5vbmUgYnJlYWthZ2UgbW9kZWwKKyAqIGZvciBmYWlsZWQgc3luY2hyb25pemF0aW9uIGF0dGVtcHRzOiBJZiBhIHRocmVhZCBsZWF2ZXMgYSBiYXJyaWVyCisgKiBwb2ludCBwcmVtYXR1cmVseSBiZWNhdXNlIG9mIGludGVycnVwdGlvbiwgZmFpbHVyZSwgb3IgdGltZW91dCwgYWxsCisgKiBvdGhlciB0aHJlYWRzIHdhaXRpbmcgYXQgdGhhdCBiYXJyaWVyIHBvaW50IHdpbGwgYWxzbyBsZWF2ZQorICogYWJub3JtYWxseSB2aWEge0BsaW5rIEJyb2tlbkJhcnJpZXJFeGNlcHRpb259IChvcgorICoge0BsaW5rIEludGVycnVwdGVkRXhjZXB0aW9ufSBpZiB0aGV5IHRvbyB3ZXJlIGludGVycnVwdGVkIGF0IGFib3V0CisgKiB0aGUgc2FtZSB0aW1lKS4KKyAqCisgKiA8cD5NZW1vcnkgY29uc2lzdGVuY3kgZWZmZWN0czogQWN0aW9ucyBpbiBhIHRocmVhZCBwcmlvciB0byBjYWxsaW5nCisgKiB7QGNvZGUgYXdhaXQoKX0KKyAqIDxhIGhyZWY9InBhY2thZ2Utc3VtbWFyeS5odG1sI01lbW9yeVZpc2liaWxpdHkiPjxpPmhhcHBlbi1iZWZvcmU8L2k+PC9hPgorICogYWN0aW9ucyB0aGF0IGFyZSBwYXJ0IG9mIHRoZSBiYXJyaWVyIGFjdGlvbiwgd2hpY2ggaW4gdHVybgorICogPGk+aGFwcGVuLWJlZm9yZTwvaT4gYWN0aW9ucyBmb2xsb3dpbmcgYSBzdWNjZXNzZnVsIHJldHVybiBmcm9tIHRoZQorICogY29ycmVzcG9uZGluZyB7QGNvZGUgYXdhaXQoKX0gaW4gb3RoZXIgdGhyZWFkcy4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAc2VlIENvdW50RG93bkxhdGNoCisgKgorICogQGF1dGhvciBEb3VnIExlYQorICovCitwdWJsaWMgY2xhc3MgQ3ljbGljQmFycmllciB7CisgICAgLyoqCisgICAgICogRWFjaCB1c2Ugb2YgdGhlIGJhcnJpZXIgaXMgcmVwcmVzZW50ZWQgYXMgYSBnZW5lcmF0aW9uIGluc3RhbmNlLgorICAgICAqIFRoZSBnZW5lcmF0aW9uIGNoYW5nZXMgd2hlbmV2ZXIgdGhlIGJhcnJpZXIgaXMgdHJpcHBlZCwgb3IKKyAgICAgKiBpcyByZXNldC4gVGhlcmUgY2FuIGJlIG1hbnkgZ2VuZXJhdGlvbnMgYXNzb2NpYXRlZCB3aXRoIHRocmVhZHMKKyAgICAgKiB1c2luZyB0aGUgYmFycmllciAtIGR1ZSB0byB0aGUgbm9uLWRldGVybWluaXN0aWMgd2F5IHRoZSBsb2NrCisgICAgICogbWF5IGJlIGFsbG9jYXRlZCB0byB3YWl0aW5nIHRocmVhZHMgLSBidXQgb25seSBvbmUgb2YgdGhlc2UKKyAgICAgKiBjYW4gYmUgYWN0aXZlIGF0IGEgdGltZSAodGhlIG9uZSB0byB3aGljaCA8dHQ+Y291bnQ8L3R0PiBhcHBsaWVzKQorICAgICAqIGFuZCBhbGwgdGhlIHJlc3QgYXJlIGVpdGhlciBicm9rZW4gb3IgdHJpcHBlZC4KKyAgICAgKiBUaGVyZSBuZWVkIG5vdCBiZSBhbiBhY3RpdmUgZ2VuZXJhdGlvbiBpZiB0aGVyZSBoYXMgYmVlbiBhIGJyZWFrCisgICAgICogYnV0IG5vIHN1YnNlcXVlbnQgcmVzZXQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgR2VuZXJhdGlvbiB7CisgICAgICAgIGJvb2xlYW4gYnJva2VuID0gZmFsc2U7CisgICAgfQorCisgICAgLyoqIFRoZSBsb2NrIGZvciBndWFyZGluZyBiYXJyaWVyIGVudHJ5ICovCisgICAgcHJpdmF0ZSBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSBuZXcgUmVlbnRyYW50TG9jaygpOworICAgIC8qKiBDb25kaXRpb24gdG8gd2FpdCBvbiB1bnRpbCB0cmlwcGVkICovCisgICAgcHJpdmF0ZSBmaW5hbCBDb25kaXRpb24gdHJpcCA9IGxvY2submV3Q29uZGl0aW9uKCk7CisgICAgLyoqIFRoZSBudW1iZXIgb2YgcGFydGllcyAqLworICAgIHByaXZhdGUgZmluYWwgaW50IHBhcnRpZXM7CisgICAgLyogVGhlIGNvbW1hbmQgdG8gcnVuIHdoZW4gdHJpcHBlZCAqLworICAgIHByaXZhdGUgZmluYWwgUnVubmFibGUgYmFycmllckNvbW1hbmQ7CisgICAgLyoqIFRoZSBjdXJyZW50IGdlbmVyYXRpb24gKi8KKyAgICBwcml2YXRlIEdlbmVyYXRpb24gZ2VuZXJhdGlvbiA9IG5ldyBHZW5lcmF0aW9uKCk7CisKKyAgICAvKioKKyAgICAgKiBOdW1iZXIgb2YgcGFydGllcyBzdGlsbCB3YWl0aW5nLiBDb3VudHMgZG93biBmcm9tIHBhcnRpZXMgdG8gMAorICAgICAqIG9uIGVhY2ggZ2VuZXJhdGlvbi4gIEl0IGlzIHJlc2V0IHRvIHBhcnRpZXMgb24gZWFjaCBuZXcKKyAgICAgKiBnZW5lcmF0aW9uIG9yIHdoZW4gYnJva2VuLgorICAgICAqLworICAgIHByaXZhdGUgaW50IGNvdW50OworCisgICAgLyoqCisgICAgICogVXBkYXRlcyBzdGF0ZSBvbiBiYXJyaWVyIHRyaXAgYW5kIHdha2VzIHVwIGV2ZXJ5b25lLgorICAgICAqIENhbGxlZCBvbmx5IHdoaWxlIGhvbGRpbmcgbG9jay4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgbmV4dEdlbmVyYXRpb24oKSB7CisgICAgICAgIC8vIHNpZ25hbCBjb21wbGV0aW9uIG9mIGxhc3QgZ2VuZXJhdGlvbgorICAgICAgICB0cmlwLnNpZ25hbEFsbCgpOworICAgICAgICAvLyBzZXQgdXAgbmV4dCBnZW5lcmF0aW9uCisgICAgICAgIGNvdW50ID0gcGFydGllczsKKyAgICAgICAgZ2VuZXJhdGlvbiA9IG5ldyBHZW5lcmF0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBjdXJyZW50IGJhcnJpZXIgZ2VuZXJhdGlvbiBhcyBicm9rZW4gYW5kIHdha2VzIHVwIGV2ZXJ5b25lLgorICAgICAqIENhbGxlZCBvbmx5IHdoaWxlIGhvbGRpbmcgbG9jay4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYnJlYWtCYXJyaWVyKCkgeworICAgICAgICBnZW5lcmF0aW9uLmJyb2tlbiA9IHRydWU7CisgICAgICAgIGNvdW50ID0gcGFydGllczsKKyAgICAgICAgdHJpcC5zaWduYWxBbGwoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYWluIGJhcnJpZXIgY29kZSwgY292ZXJpbmcgdGhlIHZhcmlvdXMgcG9saWNpZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgZG93YWl0KGJvb2xlYW4gdGltZWQsIGxvbmcgbmFub3MpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgQnJva2VuQmFycmllckV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgIFRpbWVvdXRFeGNlcHRpb24geworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgR2VuZXJhdGlvbiBnID0gZ2VuZXJhdGlvbjsKKworICAgICAgICAgICAgaWYgKGcuYnJva2VuKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBCcm9rZW5CYXJyaWVyRXhjZXB0aW9uKCk7CisKKyAgICAgICAgICAgIGlmIChUaHJlYWQuaW50ZXJydXB0ZWQoKSkgeworICAgICAgICAgICAgICAgIGJyZWFrQmFycmllcigpOworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgIGludCBpbmRleCA9IC0tY291bnQ7CisgICAgICAgICAgIGlmIChpbmRleCA9PSAwKSB7ICAvLyB0cmlwcGVkCisgICAgICAgICAgICAgICBib29sZWFuIHJhbkFjdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICBmaW5hbCBSdW5uYWJsZSBjb21tYW5kID0gYmFycmllckNvbW1hbmQ7CisgICAgICAgICAgICAgICAgICAgaWYgKGNvbW1hbmQgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgY29tbWFuZC5ydW4oKTsKKyAgICAgICAgICAgICAgICAgICByYW5BY3Rpb24gPSB0cnVlOworICAgICAgICAgICAgICAgICAgIG5leHRHZW5lcmF0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgIGlmICghcmFuQWN0aW9uKQorICAgICAgICAgICAgICAgICAgICAgICBicmVha0JhcnJpZXIoKTsKKyAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBsb29wIHVudGlsIHRyaXBwZWQsIGJyb2tlbiwgaW50ZXJydXB0ZWQsIG9yIHRpbWVkIG91dAorICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGlmICghdGltZWQpCisgICAgICAgICAgICAgICAgICAgICAgICB0cmlwLmF3YWl0KCk7CisgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbm9zID4gMEwpCisgICAgICAgICAgICAgICAgICAgICAgICBuYW5vcyA9IHRyaXAuYXdhaXROYW5vcyhuYW5vcyk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaWUpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGcgPT0gZ2VuZXJhdGlvbiAmJiAhIGcuYnJva2VuKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVha0JhcnJpZXIoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGllOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UncmUgYWJvdXQgdG8gZmluaXNoIHdhaXRpbmcgZXZlbiBpZiB3ZSBoYWQgbm90CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBiZWVuIGludGVycnVwdGVkLCBzbyB0aGlzIGludGVycnVwdCBpcyBkZWVtZWQgdG8KKyAgICAgICAgICAgICAgICAgICAgICAgIC8vICJiZWxvbmciIHRvIHN1YnNlcXVlbnQgZXhlY3V0aW9uLgorICAgICAgICAgICAgICAgICAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5pbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChnLmJyb2tlbikKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEJyb2tlbkJhcnJpZXJFeGNlcHRpb24oKTsKKworICAgICAgICAgICAgICAgIGlmIChnICE9IGdlbmVyYXRpb24pCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbmRleDsKKworICAgICAgICAgICAgICAgIGlmICh0aW1lZCAmJiBuYW5vcyA8PSAwTCkgeworICAgICAgICAgICAgICAgICAgICBicmVha0JhcnJpZXIoKTsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRpbWVvdXRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8dHQ+Q3ljbGljQmFycmllcjwvdHQ+IHRoYXQgd2lsbCB0cmlwIHdoZW4gdGhlCisgICAgICogZ2l2ZW4gbnVtYmVyIG9mIHBhcnRpZXMgKHRocmVhZHMpIGFyZSB3YWl0aW5nIHVwb24gaXQsIGFuZCB3aGljaAorICAgICAqIHdpbGwgZXhlY3V0ZSB0aGUgZ2l2ZW4gYmFycmllciBhY3Rpb24gd2hlbiB0aGUgYmFycmllciBpcyB0cmlwcGVkLAorICAgICAqIHBlcmZvcm1lZCBieSB0aGUgbGFzdCB0aHJlYWQgZW50ZXJpbmcgdGhlIGJhcnJpZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFydGllcyB0aGUgbnVtYmVyIG9mIHRocmVhZHMgdGhhdCBtdXN0IGludm9rZSB7QGxpbmsgI2F3YWl0fQorICAgICAqICAgICAgICBiZWZvcmUgdGhlIGJhcnJpZXIgaXMgdHJpcHBlZAorICAgICAqIEBwYXJhbSBiYXJyaWVyQWN0aW9uIHRoZSBjb21tYW5kIHRvIGV4ZWN1dGUgd2hlbiB0aGUgYmFycmllciBpcworICAgICAqICAgICAgICB0cmlwcGVkLCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgaXMgbm8gYWN0aW9uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHBhcnRpZXN9IGlzIGxlc3MgdGhhbiAxCisgICAgICovCisgICAgcHVibGljIEN5Y2xpY0JhcnJpZXIoaW50IHBhcnRpZXMsIFJ1bm5hYmxlIGJhcnJpZXJBY3Rpb24pIHsKKyAgICAgICAgaWYgKHBhcnRpZXMgPD0gMCkgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB0aGlzLnBhcnRpZXMgPSBwYXJ0aWVzOworICAgICAgICB0aGlzLmNvdW50ID0gcGFydGllczsKKyAgICAgICAgdGhpcy5iYXJyaWVyQ29tbWFuZCA9IGJhcnJpZXJBY3Rpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8dHQ+Q3ljbGljQmFycmllcjwvdHQ+IHRoYXQgd2lsbCB0cmlwIHdoZW4gdGhlCisgICAgICogZ2l2ZW4gbnVtYmVyIG9mIHBhcnRpZXMgKHRocmVhZHMpIGFyZSB3YWl0aW5nIHVwb24gaXQsIGFuZAorICAgICAqIGRvZXMgbm90IHBlcmZvcm0gYSBwcmVkZWZpbmVkIGFjdGlvbiB3aGVuIHRoZSBiYXJyaWVyIGlzIHRyaXBwZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFydGllcyB0aGUgbnVtYmVyIG9mIHRocmVhZHMgdGhhdCBtdXN0IGludm9rZSB7QGxpbmsgI2F3YWl0fQorICAgICAqICAgICAgICBiZWZvcmUgdGhlIGJhcnJpZXIgaXMgdHJpcHBlZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBwYXJ0aWVzfSBpcyBsZXNzIHRoYW4gMQorICAgICAqLworICAgIHB1YmxpYyBDeWNsaWNCYXJyaWVyKGludCBwYXJ0aWVzKSB7CisgICAgICAgIHRoaXMocGFydGllcywgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHBhcnRpZXMgcmVxdWlyZWQgdG8gdHJpcCB0aGlzIGJhcnJpZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgcGFydGllcyByZXF1aXJlZCB0byB0cmlwIHRoaXMgYmFycmllcgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UGFydGllcygpIHsKKyAgICAgICAgcmV0dXJuIHBhcnRpZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2FpdHMgdW50aWwgYWxsIHtAbGlua3BsYWluICNnZXRQYXJ0aWVzIHBhcnRpZXN9IGhhdmUgaW52b2tlZAorICAgICAqIDx0dD5hd2FpdDwvdHQ+IG9uIHRoaXMgYmFycmllci4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBjdXJyZW50IHRocmVhZCBpcyBub3QgdGhlIGxhc3QgdG8gYXJyaXZlIHRoZW4gaXQgaXMKKyAgICAgKiBkaXNhYmxlZCBmb3IgdGhyZWFkIHNjaGVkdWxpbmcgcHVycG9zZXMgYW5kIGxpZXMgZG9ybWFudCB1bnRpbAorICAgICAqIG9uZSBvZiB0aGUgZm9sbG93aW5nIHRoaW5ncyBoYXBwZW5zOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+VGhlIGxhc3QgdGhyZWFkIGFycml2ZXM7IG9yCisgICAgICogPGxpPlNvbWUgb3RoZXIgdGhyZWFkIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0c30KKyAgICAgKiB0aGUgY3VycmVudCB0aHJlYWQ7IG9yCisgICAgICogPGxpPlNvbWUgb3RoZXIgdGhyZWFkIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0c30KKyAgICAgKiBvbmUgb2YgdGhlIG90aGVyIHdhaXRpbmcgdGhyZWFkczsgb3IKKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQgdGltZXMgb3V0IHdoaWxlIHdhaXRpbmcgZm9yIGJhcnJpZXI7IG9yCisgICAgICogPGxpPlNvbWUgb3RoZXIgdGhyZWFkIGludm9rZXMge0BsaW5rICNyZXNldH0gb24gdGhpcyBiYXJyaWVyLgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgY3VycmVudCB0aHJlYWQ6CisgICAgICogPHVsPgorICAgICAqIDxsaT5oYXMgaXRzIGludGVycnVwdGVkIHN0YXR1cyBzZXQgb24gZW50cnkgdG8gdGhpcyBtZXRob2Q7IG9yCisgICAgICogPGxpPmlzIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0ZWR9IHdoaWxlIHdhaXRpbmcKKyAgICAgKiA8L3VsPgorICAgICAqIHRoZW4ge0BsaW5rIEludGVycnVwdGVkRXhjZXB0aW9ufSBpcyB0aHJvd24gYW5kIHRoZSBjdXJyZW50IHRocmVhZCdzCisgICAgICogaW50ZXJydXB0ZWQgc3RhdHVzIGlzIGNsZWFyZWQuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgYmFycmllciBpcyB7QGxpbmsgI3Jlc2V0fSB3aGlsZSBhbnkgdGhyZWFkIGlzIHdhaXRpbmcsCisgICAgICogb3IgaWYgdGhlIGJhcnJpZXIge0BsaW5rcGxhaW4gI2lzQnJva2VuIGlzIGJyb2tlbn0gd2hlbgorICAgICAqIDx0dD5hd2FpdDwvdHQ+IGlzIGludm9rZWQsIG9yIHdoaWxlIGFueSB0aHJlYWQgaXMgd2FpdGluZywgdGhlbgorICAgICAqIHtAbGluayBCcm9rZW5CYXJyaWVyRXhjZXB0aW9ufSBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiA8cD5JZiBhbnkgdGhyZWFkIGlzIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0ZWR9IHdoaWxlIHdhaXRpbmcsCisgICAgICogdGhlbiBhbGwgb3RoZXIgd2FpdGluZyB0aHJlYWRzIHdpbGwgdGhyb3cKKyAgICAgKiB7QGxpbmsgQnJva2VuQmFycmllckV4Y2VwdGlvbn0gYW5kIHRoZSBiYXJyaWVyIGlzIHBsYWNlZCBpbiB0aGUgYnJva2VuCisgICAgICogc3RhdGUuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgY3VycmVudCB0aHJlYWQgaXMgdGhlIGxhc3QgdGhyZWFkIHRvIGFycml2ZSwgYW5kIGEKKyAgICAgKiBub24tbnVsbCBiYXJyaWVyIGFjdGlvbiB3YXMgc3VwcGxpZWQgaW4gdGhlIGNvbnN0cnVjdG9yLCB0aGVuIHRoZQorICAgICAqIGN1cnJlbnQgdGhyZWFkIHJ1bnMgdGhlIGFjdGlvbiBiZWZvcmUgYWxsb3dpbmcgdGhlIG90aGVyIHRocmVhZHMgdG8KKyAgICAgKiBjb250aW51ZS4KKyAgICAgKiBJZiBhbiBleGNlcHRpb24gb2NjdXJzIGR1cmluZyB0aGUgYmFycmllciBhY3Rpb24gdGhlbiB0aGF0IGV4Y2VwdGlvbgorICAgICAqIHdpbGwgYmUgcHJvcGFnYXRlZCBpbiB0aGUgY3VycmVudCB0aHJlYWQgYW5kIHRoZSBiYXJyaWVyIGlzIHBsYWNlZCBpbgorICAgICAqIHRoZSBicm9rZW4gc3RhdGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBhcnJpdmFsIGluZGV4IG9mIHRoZSBjdXJyZW50IHRocmVhZCwgd2hlcmUgaW5kZXgKKyAgICAgKiAgICAgICAgIDx0dD57QGxpbmsgI2dldFBhcnRpZXMoKX0gLSAxPC90dD4gaW5kaWNhdGVzIHRoZSBmaXJzdAorICAgICAqICAgICAgICAgdG8gYXJyaXZlIGFuZCB6ZXJvIGluZGljYXRlcyB0aGUgbGFzdCB0byBhcnJpdmUKKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IHRocmVhZCB3YXMgaW50ZXJydXB0ZWQKKyAgICAgKiAgICAgICAgIHdoaWxlIHdhaXRpbmcKKyAgICAgKiBAdGhyb3dzIEJyb2tlbkJhcnJpZXJFeGNlcHRpb24gaWYgPGVtPmFub3RoZXI8L2VtPiB0aHJlYWQgd2FzCisgICAgICogICAgICAgICBpbnRlcnJ1cHRlZCBvciB0aW1lZCBvdXQgd2hpbGUgdGhlIGN1cnJlbnQgdGhyZWFkIHdhcworICAgICAqICAgICAgICAgd2FpdGluZywgb3IgdGhlIGJhcnJpZXIgd2FzIHJlc2V0LCBvciB0aGUgYmFycmllciB3YXMKKyAgICAgKiAgICAgICAgIGJyb2tlbiB3aGVuIHtAY29kZSBhd2FpdH0gd2FzIGNhbGxlZCwgb3IgdGhlIGJhcnJpZXIKKyAgICAgKiAgICAgICAgIGFjdGlvbiAoaWYgcHJlc2VudCkgZmFpbGVkIGR1ZSBhbiBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIGludCBhd2FpdCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgQnJva2VuQmFycmllckV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gZG93YWl0KGZhbHNlLCAwTCk7CisgICAgICAgIH0gY2F0Y2ggKFRpbWVvdXRFeGNlcHRpb24gdG9lKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IodG9lKTsgLy8gY2Fubm90IGhhcHBlbjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdhaXRzIHVudGlsIGFsbCB7QGxpbmtwbGFpbiAjZ2V0UGFydGllcyBwYXJ0aWVzfSBoYXZlIGludm9rZWQKKyAgICAgKiA8dHQ+YXdhaXQ8L3R0PiBvbiB0aGlzIGJhcnJpZXIsIG9yIHRoZSBzcGVjaWZpZWQgd2FpdGluZyB0aW1lIGVsYXBzZXMuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgY3VycmVudCB0aHJlYWQgaXMgbm90IHRoZSBsYXN0IHRvIGFycml2ZSB0aGVuIGl0IGlzCisgICAgICogZGlzYWJsZWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nIHB1cnBvc2VzIGFuZCBsaWVzIGRvcm1hbnQgdW50aWwKKyAgICAgKiBvbmUgb2YgdGhlIGZvbGxvd2luZyB0aGluZ3MgaGFwcGVuczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPlRoZSBsYXN0IHRocmVhZCBhcnJpdmVzOyBvcgorICAgICAqIDxsaT5UaGUgc3BlY2lmaWVkIHRpbWVvdXQgZWxhcHNlczsgb3IKKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRzfQorICAgICAqIHRoZSBjdXJyZW50IHRocmVhZDsgb3IKKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRzfQorICAgICAqIG9uZSBvZiB0aGUgb3RoZXIgd2FpdGluZyB0aHJlYWRzOyBvcgorICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCB0aW1lcyBvdXQgd2hpbGUgd2FpdGluZyBmb3IgYmFycmllcjsgb3IKKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQgaW52b2tlcyB7QGxpbmsgI3Jlc2V0fSBvbiB0aGlzIGJhcnJpZXIuCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBjdXJyZW50IHRocmVhZDoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPmhhcyBpdHMgaW50ZXJydXB0ZWQgc3RhdHVzIHNldCBvbiBlbnRyeSB0byB0aGlzIG1ldGhvZDsgb3IKKyAgICAgKiA8bGk+aXMge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRlZH0gd2hpbGUgd2FpdGluZworICAgICAqIDwvdWw+CisgICAgICogdGhlbiB7QGxpbmsgSW50ZXJydXB0ZWRFeGNlcHRpb259IGlzIHRocm93biBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkJ3MKKyAgICAgKiBpbnRlcnJ1cHRlZCBzdGF0dXMgaXMgY2xlYXJlZC4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBzcGVjaWZpZWQgd2FpdGluZyB0aW1lIGVsYXBzZXMgdGhlbiB7QGxpbmsgVGltZW91dEV4Y2VwdGlvbn0KKyAgICAgKiBpcyB0aHJvd24uIElmIHRoZSB0aW1lIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB6ZXJvLCB0aGUKKyAgICAgKiBtZXRob2Qgd2lsbCBub3Qgd2FpdCBhdCBhbGwuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgYmFycmllciBpcyB7QGxpbmsgI3Jlc2V0fSB3aGlsZSBhbnkgdGhyZWFkIGlzIHdhaXRpbmcsCisgICAgICogb3IgaWYgdGhlIGJhcnJpZXIge0BsaW5rcGxhaW4gI2lzQnJva2VuIGlzIGJyb2tlbn0gd2hlbgorICAgICAqIDx0dD5hd2FpdDwvdHQ+IGlzIGludm9rZWQsIG9yIHdoaWxlIGFueSB0aHJlYWQgaXMgd2FpdGluZywgdGhlbgorICAgICAqIHtAbGluayBCcm9rZW5CYXJyaWVyRXhjZXB0aW9ufSBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiA8cD5JZiBhbnkgdGhyZWFkIGlzIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0ZWR9IHdoaWxlCisgICAgICogd2FpdGluZywgdGhlbiBhbGwgb3RoZXIgd2FpdGluZyB0aHJlYWRzIHdpbGwgdGhyb3cge0BsaW5rCisgICAgICogQnJva2VuQmFycmllckV4Y2VwdGlvbn0gYW5kIHRoZSBiYXJyaWVyIGlzIHBsYWNlZCBpbiB0aGUgYnJva2VuCisgICAgICogc3RhdGUuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgY3VycmVudCB0aHJlYWQgaXMgdGhlIGxhc3QgdGhyZWFkIHRvIGFycml2ZSwgYW5kIGEKKyAgICAgKiBub24tbnVsbCBiYXJyaWVyIGFjdGlvbiB3YXMgc3VwcGxpZWQgaW4gdGhlIGNvbnN0cnVjdG9yLCB0aGVuIHRoZQorICAgICAqIGN1cnJlbnQgdGhyZWFkIHJ1bnMgdGhlIGFjdGlvbiBiZWZvcmUgYWxsb3dpbmcgdGhlIG90aGVyIHRocmVhZHMgdG8KKyAgICAgKiBjb250aW51ZS4KKyAgICAgKiBJZiBhbiBleGNlcHRpb24gb2NjdXJzIGR1cmluZyB0aGUgYmFycmllciBhY3Rpb24gdGhlbiB0aGF0IGV4Y2VwdGlvbgorICAgICAqIHdpbGwgYmUgcHJvcGFnYXRlZCBpbiB0aGUgY3VycmVudCB0aHJlYWQgYW5kIHRoZSBiYXJyaWVyIGlzIHBsYWNlZCBpbgorICAgICAqIHRoZSBicm9rZW4gc3RhdGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGltZW91dCB0aGUgdGltZSB0byB3YWl0IGZvciB0aGUgYmFycmllcgorICAgICAqIEBwYXJhbSB1bml0IHRoZSB0aW1lIHVuaXQgb2YgdGhlIHRpbWVvdXQgcGFyYW1ldGVyCisgICAgICogQHJldHVybiB0aGUgYXJyaXZhbCBpbmRleCBvZiB0aGUgY3VycmVudCB0aHJlYWQsIHdoZXJlIGluZGV4CisgICAgICogICAgICAgICA8dHQ+e0BsaW5rICNnZXRQYXJ0aWVzKCl9IC0gMTwvdHQ+IGluZGljYXRlcyB0aGUgZmlyc3QKKyAgICAgKiAgICAgICAgIHRvIGFycml2ZSBhbmQgemVybyBpbmRpY2F0ZXMgdGhlIGxhc3QgdG8gYXJyaXZlCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCB0aHJlYWQgd2FzIGludGVycnVwdGVkCisgICAgICogICAgICAgICB3aGlsZSB3YWl0aW5nCisgICAgICogQHRocm93cyBUaW1lb3V0RXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgdGltZW91dCBlbGFwc2VzCisgICAgICogQHRocm93cyBCcm9rZW5CYXJyaWVyRXhjZXB0aW9uIGlmIDxlbT5hbm90aGVyPC9lbT4gdGhyZWFkIHdhcworICAgICAqICAgICAgICAgaW50ZXJydXB0ZWQgb3IgdGltZWQgb3V0IHdoaWxlIHRoZSBjdXJyZW50IHRocmVhZCB3YXMKKyAgICAgKiAgICAgICAgIHdhaXRpbmcsIG9yIHRoZSBiYXJyaWVyIHdhcyByZXNldCwgb3IgdGhlIGJhcnJpZXIgd2FzIGJyb2tlbgorICAgICAqICAgICAgICAgd2hlbiB7QGNvZGUgYXdhaXR9IHdhcyBjYWxsZWQsIG9yIHRoZSBiYXJyaWVyIGFjdGlvbiAoaWYKKyAgICAgKiAgICAgICAgIHByZXNlbnQpIGZhaWxlZCBkdWUgYW4gZXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGludCBhd2FpdChsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgIEJyb2tlbkJhcnJpZXJFeGNlcHRpb24sCisgICAgICAgICAgICAgICBUaW1lb3V0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGRvd2FpdCh0cnVlLCB1bml0LnRvTmFub3ModGltZW91dCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFF1ZXJpZXMgaWYgdGhpcyBiYXJyaWVyIGlzIGluIGEgYnJva2VuIHN0YXRlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgb25lIG9yIG1vcmUgcGFydGllcyBicm9rZSBvdXQgb2YgdGhpcworICAgICAqICAgICAgICAgYmFycmllciBkdWUgdG8gaW50ZXJydXB0aW9uIG9yIHRpbWVvdXQgc2luY2UKKyAgICAgKiAgICAgICAgIGNvbnN0cnVjdGlvbiBvciB0aGUgbGFzdCByZXNldCwgb3IgYSBiYXJyaWVyIGFjdGlvbgorICAgICAqICAgICAgICAgZmFpbGVkIGR1ZSB0byBhbiBleGNlcHRpb247IHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQnJva2VuKCkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRpb24uYnJva2VuOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0cyB0aGUgYmFycmllciB0byBpdHMgaW5pdGlhbCBzdGF0ZS4gIElmIGFueSBwYXJ0aWVzIGFyZQorICAgICAqIGN1cnJlbnRseSB3YWl0aW5nIGF0IHRoZSBiYXJyaWVyLCB0aGV5IHdpbGwgcmV0dXJuIHdpdGggYQorICAgICAqIHtAbGluayBCcm9rZW5CYXJyaWVyRXhjZXB0aW9ufS4gTm90ZSB0aGF0IHJlc2V0cyA8ZW0+YWZ0ZXI8L2VtPgorICAgICAqIGEgYnJlYWthZ2UgaGFzIG9jY3VycmVkIGZvciBvdGhlciByZWFzb25zIGNhbiBiZSBjb21wbGljYXRlZCB0bworICAgICAqIGNhcnJ5IG91dDsgdGhyZWFkcyBuZWVkIHRvIHJlLXN5bmNocm9uaXplIGluIHNvbWUgb3RoZXIgd2F5LAorICAgICAqIGFuZCBjaG9vc2Ugb25lIHRvIHBlcmZvcm0gdGhlIHJlc2V0LiAgSXQgbWF5IGJlIHByZWZlcmFibGUgdG8KKyAgICAgKiBpbnN0ZWFkIGNyZWF0ZSBhIG5ldyBiYXJyaWVyIGZvciBzdWJzZXF1ZW50IHVzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJyZWFrQmFycmllcigpOyAgIC8vIGJyZWFrIHRoZSBjdXJyZW50IGdlbmVyYXRpb24KKyAgICAgICAgICAgIG5leHRHZW5lcmF0aW9uKCk7IC8vIHN0YXJ0IGEgbmV3IGdlbmVyYXRpb24KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgcGFydGllcyBjdXJyZW50bHkgd2FpdGluZyBhdCB0aGUgYmFycmllci4KKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBwcmltYXJpbHkgdXNlZnVsIGZvciBkZWJ1Z2dpbmcgYW5kIGFzc2VydGlvbnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgcGFydGllcyBjdXJyZW50bHkgYmxvY2tlZCBpbiB7QGxpbmsgI2F3YWl0fQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TnVtYmVyV2FpdGluZygpIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBwYXJ0aWVzIC0gY291bnQ7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0RlbGF5UXVldWUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9EZWxheVF1ZXVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGM0NGU4MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9EZWxheVF1ZXVlLmphdmEKQEAgLTAsMCArMSw1MTcgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLio7CitpbXBvcnQgamF2YS51dGlsLio7CisKKy8vIEJFR0lOIGFuZHJvaWQtbm90ZQorLy8gcmVtb3ZlZCBsaW5rIHRvIGNvbGxlY3Rpb25zIGZyYW1ld29yayBkb2NzCisvLyBFTkQgYW5kcm9pZC1ub3RlCisKKy8qKgorICogQW4gdW5ib3VuZGVkIHtAbGlua3BsYWluIEJsb2NraW5nUXVldWUgYmxvY2tpbmcgcXVldWV9IG9mCisgKiA8dHQ+RGVsYXllZDwvdHQ+IGVsZW1lbnRzLCBpbiB3aGljaCBhbiBlbGVtZW50IGNhbiBvbmx5IGJlIHRha2VuCisgKiB3aGVuIGl0cyBkZWxheSBoYXMgZXhwaXJlZC4gIFRoZSA8ZW0+aGVhZDwvZW0+IG9mIHRoZSBxdWV1ZSBpcyB0aGF0CisgKiA8dHQ+RGVsYXllZDwvdHQ+IGVsZW1lbnQgd2hvc2UgZGVsYXkgZXhwaXJlZCBmdXJ0aGVzdCBpbiB0aGUKKyAqIHBhc3QuICBJZiBubyBkZWxheSBoYXMgZXhwaXJlZCB0aGVyZSBpcyBubyBoZWFkIGFuZCA8dHQ+cG9sbDwvdHQ+CisgKiB3aWxsIHJldHVybiA8dHQ+bnVsbDwvdHQ+LiBFeHBpcmF0aW9uIG9jY3VycyB3aGVuIGFuIGVsZW1lbnQncworICogPHR0PmdldERlbGF5KFRpbWVVbml0Lk5BTk9TRUNPTkRTKTwvdHQ+IG1ldGhvZCByZXR1cm5zIGEgdmFsdWUgbGVzcworICogdGhhbiBvciBlcXVhbCB0byB6ZXJvLiAgRXZlbiB0aG91Z2ggdW5leHBpcmVkIGVsZW1lbnRzIGNhbm5vdCBiZQorICogcmVtb3ZlZCB1c2luZyA8dHQ+dGFrZTwvdHQ+IG9yIDx0dD5wb2xsPC90dD4sIHRoZXkgYXJlIG90aGVyd2lzZQorICogdHJlYXRlZCBhcyBub3JtYWwgZWxlbWVudHMuIEZvciBleGFtcGxlLCB0aGUgPHR0PnNpemU8L3R0PiBtZXRob2QKKyAqIHJldHVybnMgdGhlIGNvdW50IG9mIGJvdGggZXhwaXJlZCBhbmQgdW5leHBpcmVkIGVsZW1lbnRzLgorICogVGhpcyBxdWV1ZSBkb2VzIG5vdCBwZXJtaXQgbnVsbCBlbGVtZW50cy4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGFuZCBpdHMgaXRlcmF0b3IgaW1wbGVtZW50IGFsbCBvZiB0aGUKKyAqIDxlbT5vcHRpb25hbDwvZW0+IG1ldGhvZHMgb2YgdGhlIHtAbGluayBDb2xsZWN0aW9ufSBhbmQge0BsaW5rCisgKiBJdGVyYXRvcn0gaW50ZXJmYWNlcy4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKiBAcGFyYW0gPEU+IHRoZSB0eXBlIG9mIGVsZW1lbnRzIGhlbGQgaW4gdGhpcyBjb2xsZWN0aW9uCisgKi8KKworcHVibGljIGNsYXNzIERlbGF5UXVldWU8RSBleHRlbmRzIERlbGF5ZWQ+IGV4dGVuZHMgQWJzdHJhY3RRdWV1ZTxFPgorICAgIGltcGxlbWVudHMgQmxvY2tpbmdRdWV1ZTxFPiB7CisKKyAgICBwcml2YXRlIHRyYW5zaWVudCBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSBuZXcgUmVlbnRyYW50TG9jaygpOworICAgIHByaXZhdGUgZmluYWwgUHJpb3JpdHlRdWV1ZTxFPiBxID0gbmV3IFByaW9yaXR5UXVldWU8RT4oKTsKKworICAgIC8qKgorICAgICAqIFRocmVhZCBkZXNpZ25hdGVkIHRvIHdhaXQgZm9yIHRoZSBlbGVtZW50IGF0IHRoZSBoZWFkIG9mCisgICAgICogdGhlIHF1ZXVlLiAgVGhpcyB2YXJpYW50IG9mIHRoZSBMZWFkZXItRm9sbG93ZXIgcGF0dGVybgorICAgICAqIChodHRwOi8vd3d3LmNzLnd1c3RsLmVkdS9+c2NobWlkdC9QT1NBL1BPU0EyLykgc2VydmVzIHRvCisgICAgICogbWluaW1pemUgdW5uZWNlc3NhcnkgdGltZWQgd2FpdGluZy4gIFdoZW4gYSB0aHJlYWQgYmVjb21lcworICAgICAqIHRoZSBsZWFkZXIsIGl0IHdhaXRzIG9ubHkgZm9yIHRoZSBuZXh0IGRlbGF5IHRvIGVsYXBzZSwgYnV0CisgICAgICogb3RoZXIgdGhyZWFkcyBhd2FpdCBpbmRlZmluaXRlbHkuICBUaGUgbGVhZGVyIHRocmVhZCBtdXN0CisgICAgICogc2lnbmFsIHNvbWUgb3RoZXIgdGhyZWFkIGJlZm9yZSByZXR1cm5pbmcgZnJvbSB0YWtlKCkgb3IKKyAgICAgKiBwb2xsKC4uLiksIHVubGVzcyBzb21lIG90aGVyIHRocmVhZCBiZWNvbWVzIGxlYWRlciBpbiB0aGUKKyAgICAgKiBpbnRlcmltLiAgV2hlbmV2ZXIgdGhlIGhlYWQgb2YgdGhlIHF1ZXVlIGlzIHJlcGxhY2VkIHdpdGgKKyAgICAgKiBhbiBlbGVtZW50IHdpdGggYW4gZWFybGllciBleHBpcmF0aW9uIHRpbWUsIHRoZSBsZWFkZXIKKyAgICAgKiBmaWVsZCBpcyBpbnZhbGlkYXRlZCBieSBiZWluZyByZXNldCB0byBudWxsLCBhbmQgc29tZQorICAgICAqIHdhaXRpbmcgdGhyZWFkLCBidXQgbm90IG5lY2Vzc2FyaWx5IHRoZSBjdXJyZW50IGxlYWRlciwgaXMKKyAgICAgKiBzaWduYWxsZWQuICBTbyB3YWl0aW5nIHRocmVhZHMgbXVzdCBiZSBwcmVwYXJlZCB0byBhY3F1aXJlCisgICAgICogYW5kIGxvc2UgbGVhZGVyc2hpcCB3aGlsZSB3YWl0aW5nLgorICAgICAqLworICAgIHByaXZhdGUgVGhyZWFkIGxlYWRlciA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBDb25kaXRpb24gc2lnbmFsbGVkIHdoZW4gYSBuZXdlciBlbGVtZW50IGJlY29tZXMgYXZhaWxhYmxlCisgICAgICogYXQgdGhlIGhlYWQgb2YgdGhlIHF1ZXVlIG9yIGEgbmV3IHRocmVhZCBtYXkgbmVlZCB0bworICAgICAqIGJlY29tZSBsZWFkZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBDb25kaXRpb24gYXZhaWxhYmxlID0gbG9jay5uZXdDb25kaXRpb24oKTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgPHR0PkRlbGF5UXVldWU8L3R0PiB0aGF0IGlzIGluaXRpYWxseSBlbXB0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGVsYXlRdWV1ZSgpIHt9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgPHR0PkRlbGF5UXVldWU8L3R0PiBpbml0aWFsbHkgY29udGFpbmluZyB0aGUgZWxlbWVudHMgb2YgdGhlCisgICAgICogZ2l2ZW4gY29sbGVjdGlvbiBvZiB7QGxpbmsgRGVsYXllZH0gaW5zdGFuY2VzLgorICAgICAqCisgICAgICogQHBhcmFtIGMgdGhlIGNvbGxlY3Rpb24gb2YgZWxlbWVudHMgdG8gaW5pdGlhbGx5IGNvbnRhaW4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiBvciBhbnkKKyAgICAgKiAgICAgICAgIG9mIGl0cyBlbGVtZW50cyBhcmUgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBEZWxheVF1ZXVlKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGMpIHsKKyAgICAgICAgdGhpcy5hZGRBbGwoYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaW50byB0aGlzIGRlbGF5IHF1ZXVlLgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IChhcyBzcGVjaWZpZWQgYnkge0BsaW5rIENvbGxlY3Rpb24jYWRkfSkKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYWRkKEUgZSkgeworICAgICAgICByZXR1cm4gb2ZmZXIoZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaW50byB0aGlzIGRlbGF5IHF1ZXVlLgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG9mZmVyKEUgZSkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcS5vZmZlcihlKTsKKyAgICAgICAgICAgIGlmIChxLnBlZWsoKSA9PSBlKSB7CisgICAgICAgICAgICAgICAgbGVhZGVyID0gbnVsbDsKKyAgICAgICAgICAgICAgICBhdmFpbGFibGUuc2lnbmFsKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpbnRvIHRoaXMgZGVsYXkgcXVldWUuIEFzIHRoZSBxdWV1ZSBpcworICAgICAqIHVuYm91bmRlZCB0aGlzIG1ldGhvZCB3aWxsIG5ldmVyIGJsb2NrLgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIHZvaWQgcHV0KEUgZSkgeworICAgICAgICBvZmZlcihlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpbnRvIHRoaXMgZGVsYXkgcXVldWUuIEFzIHRoZSBxdWV1ZSBpcworICAgICAqIHVuYm91bmRlZCB0aGlzIG1ldGhvZCB3aWxsIG5ldmVyIGJsb2NrLgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHBhcmFtIHRpbWVvdXQgVGhpcyBwYXJhbWV0ZXIgaXMgaWdub3JlZCBhcyB0aGUgbWV0aG9kIG5ldmVyIGJsb2NrcworICAgICAqIEBwYXJhbSB1bml0IFRoaXMgcGFyYW1ldGVyIGlzIGlnbm9yZWQgYXMgdGhlIG1ldGhvZCBuZXZlciBibG9ja3MKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBvZmZlcihFIGUsIGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkgeworICAgICAgICByZXR1cm4gb2ZmZXIoZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGFuZCByZW1vdmVzIHRoZSBoZWFkIG9mIHRoaXMgcXVldWUsIG9yIHJldHVybnMgPHR0Pm51bGw8L3R0PgorICAgICAqIGlmIHRoaXMgcXVldWUgaGFzIG5vIGVsZW1lbnRzIHdpdGggYW4gZXhwaXJlZCBkZWxheS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhlYWQgb2YgdGhpcyBxdWV1ZSwgb3IgPHR0Pm51bGw8L3R0PiBpZiB0aGlzCisgICAgICogICAgICAgICBxdWV1ZSBoYXMgbm8gZWxlbWVudHMgd2l0aCBhbiBleHBpcmVkIGRlbGF5CisgICAgICovCisgICAgcHVibGljIEUgcG9sbCgpIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEUgZmlyc3QgPSBxLnBlZWsoKTsKKyAgICAgICAgICAgIGlmIChmaXJzdCA9PSBudWxsIHx8IGZpcnN0LmdldERlbGF5KFRpbWVVbml0Lk5BTk9TRUNPTkRTKSA+IDApCisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgcmV0dXJuIHEucG9sbCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhbmQgcmVtb3ZlcyB0aGUgaGVhZCBvZiB0aGlzIHF1ZXVlLCB3YWl0aW5nIGlmIG5lY2Vzc2FyeQorICAgICAqIHVudGlsIGFuIGVsZW1lbnQgd2l0aCBhbiBleHBpcmVkIGRlbGF5IGlzIGF2YWlsYWJsZSBvbiB0aGlzIHF1ZXVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGlzIHF1ZXVlCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIEUgdGFrZSgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrSW50ZXJydXB0aWJseSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIEUgZmlyc3QgPSBxLnBlZWsoKTsKKyAgICAgICAgICAgICAgICBpZiAoZmlyc3QgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgYXZhaWxhYmxlLmF3YWl0KCk7CisgICAgICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGxvbmcgZGVsYXkgPSBmaXJzdC5nZXREZWxheShUaW1lVW5pdC5OQU5PU0VDT05EUyk7CisgICAgICAgICAgICAgICAgICAgIGlmIChkZWxheSA8PSAwKQorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHEucG9sbCgpOworICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChsZWFkZXIgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgIGF2YWlsYWJsZS5hd2FpdCgpOworICAgICAgICAgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFRocmVhZCB0aGlzVGhyZWFkID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxlYWRlciA9IHRoaXNUaHJlYWQ7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF2YWlsYWJsZS5hd2FpdE5hbm9zKGRlbGF5KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxlYWRlciA9PSB0aGlzVGhyZWFkKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWFkZXIgPSBudWxsOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGxlYWRlciA9PSBudWxsICYmIHEucGVlaygpICE9IG51bGwpCisgICAgICAgICAgICAgICAgYXZhaWxhYmxlLnNpZ25hbCgpOworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhbmQgcmVtb3ZlcyB0aGUgaGVhZCBvZiB0aGlzIHF1ZXVlLCB3YWl0aW5nIGlmIG5lY2Vzc2FyeQorICAgICAqIHVudGlsIGFuIGVsZW1lbnQgd2l0aCBhbiBleHBpcmVkIGRlbGF5IGlzIGF2YWlsYWJsZSBvbiB0aGlzIHF1ZXVlLAorICAgICAqIG9yIHRoZSBzcGVjaWZpZWQgd2FpdCB0aW1lIGV4cGlyZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWFkIG9mIHRoaXMgcXVldWUsIG9yIDx0dD5udWxsPC90dD4gaWYgdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgd2FpdGluZyB0aW1lIGVsYXBzZXMgYmVmb3JlIGFuIGVsZW1lbnQgd2l0aAorICAgICAqICAgICAgICAgYW4gZXhwaXJlZCBkZWxheSBiZWNvbWVzIGF2YWlsYWJsZQorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBFIHBvbGwobG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBsb25nIG5hbm9zID0gdW5pdC50b05hbm9zKHRpbWVvdXQpOworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9ja0ludGVycnVwdGlibHkoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBFIGZpcnN0ID0gcS5wZWVrKCk7CisgICAgICAgICAgICAgICAgaWYgKGZpcnN0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5hbm9zIDw9IDApCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICAgICAgbmFub3MgPSBhdmFpbGFibGUuYXdhaXROYW5vcyhuYW5vcyk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgbG9uZyBkZWxheSA9IGZpcnN0LmdldERlbGF5KFRpbWVVbml0Lk5BTk9TRUNPTkRTKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGF5IDw9IDApCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcS5wb2xsKCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChuYW5vcyA8PSAwKQorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgIGlmIChuYW5vcyA8IGRlbGF5IHx8IGxlYWRlciAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgbmFub3MgPSBhdmFpbGFibGUuYXdhaXROYW5vcyhuYW5vcyk7CisgICAgICAgICAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgVGhyZWFkIHRoaXNUaHJlYWQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICAgICAgICAgICAgICAgICAgbGVhZGVyID0gdGhpc1RocmVhZDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyB0aW1lTGVmdCA9IGF2YWlsYWJsZS5hd2FpdE5hbm9zKGRlbGF5KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW5vcyAtPSBkZWxheSAtIHRpbWVMZWZ0OworICAgICAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGVhZGVyID09IHRoaXNUaHJlYWQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlYWRlciA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAobGVhZGVyID09IG51bGwgJiYgcS5wZWVrKCkgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICBhdmFpbGFibGUuc2lnbmFsKCk7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzLCBidXQgZG9lcyBub3QgcmVtb3ZlLCB0aGUgaGVhZCBvZiB0aGlzIHF1ZXVlLCBvcgorICAgICAqIHJldHVybnMgPHR0Pm51bGw8L3R0PiBpZiB0aGlzIHF1ZXVlIGlzIGVtcHR5LiAgVW5saWtlCisgICAgICogPHR0PnBvbGw8L3R0PiwgaWYgbm8gZXhwaXJlZCBlbGVtZW50cyBhcmUgYXZhaWxhYmxlIGluIHRoZSBxdWV1ZSwKKyAgICAgKiB0aGlzIG1ldGhvZCByZXR1cm5zIHRoZSBlbGVtZW50IHRoYXQgd2lsbCBleHBpcmUgbmV4dCwKKyAgICAgKiBpZiBvbmUgZXhpc3RzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGlzIHF1ZXVlLCBvciA8dHQ+bnVsbDwvdHQ+IGlmIHRoaXMKKyAgICAgKiAgICAgICAgIHF1ZXVlIGlzIGVtcHR5LgorICAgICAqLworICAgIHB1YmxpYyBFIHBlZWsoKSB7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gcS5wZWVrKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHEuc2l6ZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uICAgICAgICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gICAgICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZHJhaW5UbyhDb2xsZWN0aW9uPD8gc3VwZXIgRT4gYykgeworICAgICAgICBpZiAoYyA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGlmIChjID09IHRoaXMpCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgbiA9IDA7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgRSBmaXJzdCA9IHEucGVlaygpOworICAgICAgICAgICAgICAgIGlmIChmaXJzdCA9PSBudWxsIHx8IGZpcnN0LmdldERlbGF5KFRpbWVVbml0Lk5BTk9TRUNPTkRTKSA+IDApCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGMuYWRkKHEucG9sbCgpKTsKKyAgICAgICAgICAgICAgICArK247CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbjsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiAgICAgICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICAgICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGRyYWluVG8oQ29sbGVjdGlvbjw/IHN1cGVyIEU+IGMsIGludCBtYXhFbGVtZW50cykgeworICAgICAgICBpZiAoYyA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGlmIChjID09IHRoaXMpCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIGlmIChtYXhFbGVtZW50cyA8PSAwKQorICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgbiA9IDA7CisgICAgICAgICAgICB3aGlsZSAobiA8IG1heEVsZW1lbnRzKSB7CisgICAgICAgICAgICAgICAgRSBmaXJzdCA9IHEucGVlaygpOworICAgICAgICAgICAgICAgIGlmIChmaXJzdCA9PSBudWxsIHx8IGZpcnN0LmdldERlbGF5KFRpbWVVbml0Lk5BTk9TRUNPTkRTKSA+IDApCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGMuYWRkKHEucG9sbCgpKTsKKyAgICAgICAgICAgICAgICArK247CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbjsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHJlbW92ZXMgYWxsIG9mIHRoZSBlbGVtZW50cyBmcm9tIHRoaXMgZGVsYXkgcXVldWUuCisgICAgICogVGhlIHF1ZXVlIHdpbGwgYmUgZW1wdHkgYWZ0ZXIgdGhpcyBjYWxsIHJldHVybnMuCisgICAgICogRWxlbWVudHMgd2l0aCBhbiB1bmV4cGlyZWQgZGVsYXkgYXJlIG5vdCB3YWl0ZWQgZm9yOyB0aGV5IGFyZQorICAgICAqIHNpbXBseSBkaXNjYXJkZWQgZnJvbSB0aGUgcXVldWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBxLmNsZWFyKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQWx3YXlzIHJldHVybnMgPHR0PkludGVnZXIuTUFYX1ZBTFVFPC90dD4gYmVjYXVzZQorICAgICAqIGEgPHR0PkRlbGF5UXVldWU8L3R0PiBpcyBub3QgY2FwYWNpdHkgY29uc3RyYWluZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIDx0dD5JbnRlZ2VyLk1BWF9WQUxVRTwvdHQ+CisgICAgICovCisgICAgcHVibGljIGludCByZW1haW5pbmdDYXBhY2l0eSgpIHsKKyAgICAgICAgcmV0dXJuIEludGVnZXIuTUFYX1ZBTFVFOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoaXMgcXVldWUuCisgICAgICogVGhlIHJldHVybmVkIGFycmF5IGVsZW1lbnRzIGFyZSBpbiBubyBwYXJ0aWN1bGFyIG9yZGVyLgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybmVkIGFycmF5IHdpbGwgYmUgInNhZmUiIGluIHRoYXQgbm8gcmVmZXJlbmNlcyB0byBpdCBhcmUKKyAgICAgKiBtYWludGFpbmVkIGJ5IHRoaXMgcXVldWUuICAoSW4gb3RoZXIgd29yZHMsIHRoaXMgbWV0aG9kIG11c3QgYWxsb2NhdGUKKyAgICAgKiBhIG5ldyBhcnJheSkuICBUaGUgY2FsbGVyIGlzIHRodXMgZnJlZSB0byBtb2RpZnkgdGhlIHJldHVybmVkIGFycmF5LgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgYWN0cyBhcyBicmlkZ2UgYmV0d2VlbiBhcnJheS1iYXNlZCBhbmQgY29sbGVjdGlvbi1iYXNlZAorICAgICAqIEFQSXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IGNvbnRhaW5pbmcgYWxsIG9mIHRoZSBlbGVtZW50cyBpbiB0aGlzIHF1ZXVlCisgICAgICovCisgICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSB7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gcS50b0FycmF5KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIGFsbCBvZiB0aGUgZWxlbWVudHMgaW4gdGhpcyBxdWV1ZTsgdGhlCisgICAgICogcnVudGltZSB0eXBlIG9mIHRoZSByZXR1cm5lZCBhcnJheSBpcyB0aGF0IG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkuCisgICAgICogVGhlIHJldHVybmVkIGFycmF5IGVsZW1lbnRzIGFyZSBpbiBubyBwYXJ0aWN1bGFyIG9yZGVyLgorICAgICAqIElmIHRoZSBxdWV1ZSBmaXRzIGluIHRoZSBzcGVjaWZpZWQgYXJyYXksIGl0IGlzIHJldHVybmVkIHRoZXJlaW4uCisgICAgICogT3RoZXJ3aXNlLCBhIG5ldyBhcnJheSBpcyBhbGxvY2F0ZWQgd2l0aCB0aGUgcnVudGltZSB0eXBlIG9mIHRoZQorICAgICAqIHNwZWNpZmllZCBhcnJheSBhbmQgdGhlIHNpemUgb2YgdGhpcyBxdWV1ZS4KKyAgICAgKgorICAgICAqIDxwPklmIHRoaXMgcXVldWUgZml0cyBpbiB0aGUgc3BlY2lmaWVkIGFycmF5IHdpdGggcm9vbSB0byBzcGFyZQorICAgICAqIChpLmUuLCB0aGUgYXJyYXkgaGFzIG1vcmUgZWxlbWVudHMgdGhhbiB0aGlzIHF1ZXVlKSwgdGhlIGVsZW1lbnQgaW4KKyAgICAgKiB0aGUgYXJyYXkgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZSBlbmQgb2YgdGhlIHF1ZXVlIGlzIHNldCB0bworICAgICAqIDx0dD5udWxsPC90dD4uCisgICAgICoKKyAgICAgKiA8cD5MaWtlIHRoZSB7QGxpbmsgI3RvQXJyYXkoKX0gbWV0aG9kLCB0aGlzIG1ldGhvZCBhY3RzIGFzIGJyaWRnZSBiZXR3ZWVuCisgICAgICogYXJyYXktYmFzZWQgYW5kIGNvbGxlY3Rpb24tYmFzZWQgQVBJcy4gIEZ1cnRoZXIsIHRoaXMgbWV0aG9kIGFsbG93cworICAgICAqIHByZWNpc2UgY29udHJvbCBvdmVyIHRoZSBydW50aW1lIHR5cGUgb2YgdGhlIG91dHB1dCBhcnJheSwgYW5kIG1heSwKKyAgICAgKiB1bmRlciBjZXJ0YWluIGNpcmN1bXN0YW5jZXMsIGJlIHVzZWQgdG8gc2F2ZSBhbGxvY2F0aW9uIGNvc3RzLgorICAgICAqCisgICAgICogPHA+VGhlIGZvbGxvd2luZyBjb2RlIGNhbiBiZSB1c2VkIHRvIGR1bXAgYSBkZWxheSBxdWV1ZSBpbnRvIGEgbmV3bHkKKyAgICAgKiBhbGxvY2F0ZWQgYXJyYXkgb2YgPHR0PkRlbGF5ZWQ8L3R0PjoKKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogICAgIERlbGF5ZWRbXSBhID0gcS50b0FycmF5KG5ldyBEZWxheWVkWzBdKTs8L3ByZT4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCA8dHQ+dG9BcnJheShuZXcgT2JqZWN0WzBdKTwvdHQ+IGlzIGlkZW50aWNhbCBpbiBmdW5jdGlvbiB0bworICAgICAqIDx0dD50b0FycmF5KCk8L3R0Pi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSBpbnRvIHdoaWNoIHRoZSBlbGVtZW50cyBvZiB0aGUgcXVldWUgYXJlIHRvCisgICAgICogICAgICAgICAgYmUgc3RvcmVkLCBpZiBpdCBpcyBiaWcgZW5vdWdoOyBvdGhlcndpc2UsIGEgbmV3IGFycmF5IG9mIHRoZQorICAgICAqICAgICAgICAgIHNhbWUgcnVudGltZSB0eXBlIGlzIGFsbG9jYXRlZCBmb3IgdGhpcyBwdXJwb3NlCisgICAgICogQHJldHVybiBhbiBhcnJheSBjb250YWluaW5nIGFsbCBvZiB0aGUgZWxlbWVudHMgaW4gdGhpcyBxdWV1ZQorICAgICAqIEB0aHJvd3MgQXJyYXlTdG9yZUV4Y2VwdGlvbiBpZiB0aGUgcnVudGltZSB0eXBlIG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkKKyAgICAgKiAgICAgICAgIGlzIG5vdCBhIHN1cGVydHlwZSBvZiB0aGUgcnVudGltZSB0eXBlIG9mIGV2ZXJ5IGVsZW1lbnQgaW4KKyAgICAgKiAgICAgICAgIHRoaXMgcXVldWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgYXJyYXkgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyA8VD4gVFtdIHRvQXJyYXkoVFtdIGEpIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBxLnRvQXJyYXkoYSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhIHNpbmdsZSBpbnN0YW5jZSBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgZnJvbSB0aGlzCisgICAgICogcXVldWUsIGlmIGl0IGlzIHByZXNlbnQsIHdoZXRoZXIgb3Igbm90IGl0IGhhcyBleHBpcmVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3QgbykgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHEucmVtb3ZlKG8pOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igb3ZlciBhbGwgdGhlIGVsZW1lbnRzIChib3RoIGV4cGlyZWQgYW5kCisgICAgICogdW5leHBpcmVkKSBpbiB0aGlzIHF1ZXVlLiBUaGUgaXRlcmF0b3IgZG9lcyBub3QgcmV0dXJuIHRoZQorICAgICAqIGVsZW1lbnRzIGluIGFueSBwYXJ0aWN1bGFyIG9yZGVyLgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybmVkIGl0ZXJhdG9yIGlzIGEgIndlYWtseSBjb25zaXN0ZW50IiBpdGVyYXRvciB0aGF0CisgICAgICogd2lsbCBuZXZlciB0aHJvdyB7QGxpbmsgamF2YS51dGlsLkNvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24KKyAgICAgKiBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9ufSwgYW5kIGd1YXJhbnRlZXMgdG8gdHJhdmVyc2UKKyAgICAgKiBlbGVtZW50cyBhcyB0aGV5IGV4aXN0ZWQgdXBvbiBjb25zdHJ1Y3Rpb24gb2YgdGhlIGl0ZXJhdG9yLCBhbmQKKyAgICAgKiBtYXkgKGJ1dCBpcyBub3QgZ3VhcmFudGVlZCB0bykgcmVmbGVjdCBhbnkgbW9kaWZpY2F0aW9ucworICAgICAqIHN1YnNlcXVlbnQgdG8gY29uc3RydWN0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cyBpbiB0aGlzIHF1ZXVlCisgICAgICovCisgICAgcHVibGljIEl0ZXJhdG9yPEU+IGl0ZXJhdG9yKCkgeworICAgICAgICByZXR1cm4gbmV3IEl0cih0b0FycmF5KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNuYXBzaG90IGl0ZXJhdG9yIHRoYXQgd29ya3Mgb2ZmIGNvcHkgb2YgdW5kZXJseWluZyBxIGFycmF5LgorICAgICAqLworICAgIHByaXZhdGUgY2xhc3MgSXRyIGltcGxlbWVudHMgSXRlcmF0b3I8RT4geworICAgICAgICBmaW5hbCBPYmplY3RbXSBhcnJheTsgLy8gQXJyYXkgb2YgYWxsIGVsZW1lbnRzCisgICAgICAgIGludCBjdXJzb3I7ICAgICAgICAgICAvLyBpbmRleCBvZiBuZXh0IGVsZW1lbnQgdG8gcmV0dXJuOworICAgICAgICBpbnQgbGFzdFJldDsgICAgICAgICAgLy8gaW5kZXggb2YgbGFzdCBlbGVtZW50LCBvciAtMSBpZiBubyBzdWNoCisKKyAgICAgICAgSXRyKE9iamVjdFtdIGFycmF5KSB7CisgICAgICAgICAgICBsYXN0UmV0ID0gLTE7CisgICAgICAgICAgICB0aGlzLmFycmF5ID0gYXJyYXk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgcmV0dXJuIGN1cnNvciA8IGFycmF5Lmxlbmd0aDsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICBwdWJsaWMgRSBuZXh0KCkgeworICAgICAgICAgICAgaWYgKGN1cnNvciA+PSBhcnJheS5sZW5ndGgpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGxhc3RSZXQgPSBjdXJzb3I7CisgICAgICAgICAgICByZXR1cm4gKEUpYXJyYXlbY3Vyc29yKytdOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICAgICAgaWYgKGxhc3RSZXQgPCAwKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIE9iamVjdCB4ID0gYXJyYXlbbGFzdFJldF07CisgICAgICAgICAgICBsYXN0UmV0ID0gLTE7CisgICAgICAgICAgICAvLyBUcmF2ZXJzZSB1bmRlcmx5aW5nIHF1ZXVlIHRvIGZpbmQgPT0gZWxlbWVudCwKKyAgICAgICAgICAgIC8vIG5vdCBqdXN0IGEgLmVxdWFscyBlbGVtZW50LgorICAgICAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZvciAoSXRlcmF0b3IgaXQgPSBxLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTsgKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChpdC5uZXh0KCkgPT0geCkgeworICAgICAgICAgICAgICAgICAgICAgICAgaXQucmVtb3ZlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9EZWxheWVkLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvRGVsYXllZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxZmY0ZWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvRGVsYXllZC5qYXZhCkBAIC0wLDAgKzEsMzMgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudDsKKworaW1wb3J0IGphdmEudXRpbC4qOworCisvKioKKyAqIEEgbWl4LWluIHN0eWxlIGludGVyZmFjZSBmb3IgbWFya2luZyBvYmplY3RzIHRoYXQgc2hvdWxkIGJlCisgKiBhY3RlZCB1cG9uIGFmdGVyIGEgZ2l2ZW4gZGVsYXkuCisgKgorICogPHA+QW4gaW1wbGVtZW50YXRpb24gb2YgdGhpcyBpbnRlcmZhY2UgbXVzdCBkZWZpbmUgYQorICogPHR0PmNvbXBhcmVUbzwvdHQ+IG1ldGhvZCB0aGF0IHByb3ZpZGVzIGFuIG9yZGVyaW5nIGNvbnNpc3RlbnQgd2l0aAorICogaXRzIDx0dD5nZXREZWxheTwvdHQ+IG1ldGhvZC4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRGVsYXllZCBleHRlbmRzIENvbXBhcmFibGU8RGVsYXllZD4geworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmVtYWluaW5nIGRlbGF5IGFzc29jaWF0ZWQgd2l0aCB0aGlzIG9iamVjdCwgaW4gdGhlCisgICAgICogZ2l2ZW4gdGltZSB1bml0LgorICAgICAqCisgICAgICogQHBhcmFtIHVuaXQgdGhlIHRpbWUgdW5pdAorICAgICAqIEByZXR1cm4gdGhlIHJlbWFpbmluZyBkZWxheTsgemVybyBvciBuZWdhdGl2ZSB2YWx1ZXMgaW5kaWNhdGUKKyAgICAgKiB0aGF0IHRoZSBkZWxheSBoYXMgYWxyZWFkeSBlbGFwc2VkCisgICAgICovCisgICAgbG9uZyBnZXREZWxheShUaW1lVW5pdCB1bml0KTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9FeGNoYW5nZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9FeGNoYW5nZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYzIzMGJlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0V4Y2hhbmdlci5qYXZhCkBAIC0wLDAgKzEsNjU4IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSwgQmlsbCBTY2hlcmVyLCBhbmQgTWljaGFlbCBTY290dCB3aXRoCisgKiBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvCisgKiB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy4qOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLkxvY2tTdXBwb3J0OworCisvKioKKyAqIEEgc3luY2hyb25pemF0aW9uIHBvaW50IGF0IHdoaWNoIHRocmVhZHMgY2FuIHBhaXIgYW5kIHN3YXAgZWxlbWVudHMKKyAqIHdpdGhpbiBwYWlycy4gIEVhY2ggdGhyZWFkIHByZXNlbnRzIHNvbWUgb2JqZWN0IG9uIGVudHJ5IHRvIHRoZQorICoge0BsaW5rICNleGNoYW5nZSBleGNoYW5nZX0gbWV0aG9kLCBtYXRjaGVzIHdpdGggYSBwYXJ0bmVyIHRocmVhZCwKKyAqIGFuZCByZWNlaXZlcyBpdHMgcGFydG5lcidzIG9iamVjdCBvbiByZXR1cm4uICBBbiBFeGNoYW5nZXIgbWF5IGJlCisgKiB2aWV3ZWQgYXMgYSBiaWRpcmVjdGlvbmFsIGZvcm0gb2YgYSB7QGxpbmsgU3luY2hyb25vdXNRdWV1ZX0uCisgKiBFeGNoYW5nZXJzIG1heSBiZSB1c2VmdWwgaW4gYXBwbGljYXRpb25zIHN1Y2ggYXMgZ2VuZXRpYyBhbGdvcml0aG1zCisgKiBhbmQgcGlwZWxpbmUgZGVzaWducy4KKyAqCisgKiA8cD48Yj5TYW1wbGUgVXNhZ2U6PC9iPgorICogSGVyZSBhcmUgdGhlIGhpZ2hsaWdodHMgb2YgYSBjbGFzcyB0aGF0IHVzZXMgYW4ge0Bjb2RlIEV4Y2hhbmdlcn0KKyAqIHRvIHN3YXAgYnVmZmVycyBiZXR3ZWVuIHRocmVhZHMgc28gdGhhdCB0aGUgdGhyZWFkIGZpbGxpbmcgdGhlCisgKiBidWZmZXIgZ2V0cyBhIGZyZXNobHkgZW1wdGllZCBvbmUgd2hlbiBpdCBuZWVkcyBpdCwgaGFuZGluZyBvZmYgdGhlCisgKiBmaWxsZWQgb25lIHRvIHRoZSB0aHJlYWQgZW1wdHlpbmcgdGhlIGJ1ZmZlci4KKyAqIDxwcmU+e0Bjb2RlCisgKiBjbGFzcyBGaWxsQW5kRW1wdHkgeworICogICBFeGNoYW5nZXI8RGF0YUJ1ZmZlcj4gZXhjaGFuZ2VyID0gbmV3IEV4Y2hhbmdlcjxEYXRhQnVmZmVyPigpOworICogICBEYXRhQnVmZmVyIGluaXRpYWxFbXB0eUJ1ZmZlciA9IC4uLiBhIG1hZGUtdXAgdHlwZQorICogICBEYXRhQnVmZmVyIGluaXRpYWxGdWxsQnVmZmVyID0gLi4uCisgKgorICogICBjbGFzcyBGaWxsaW5nTG9vcCBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKyAqICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgKiAgICAgICBEYXRhQnVmZmVyIGN1cnJlbnRCdWZmZXIgPSBpbml0aWFsRW1wdHlCdWZmZXI7CisgKiAgICAgICB0cnkgeworICogICAgICAgICB3aGlsZSAoY3VycmVudEJ1ZmZlciAhPSBudWxsKSB7CisgKiAgICAgICAgICAgYWRkVG9CdWZmZXIoY3VycmVudEJ1ZmZlcik7CisgKiAgICAgICAgICAgaWYgKGN1cnJlbnRCdWZmZXIuaXNGdWxsKCkpCisgKiAgICAgICAgICAgICBjdXJyZW50QnVmZmVyID0gZXhjaGFuZ2VyLmV4Y2hhbmdlKGN1cnJlbnRCdWZmZXIpOworICogICAgICAgICB9CisgKiAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeyAuLi4gaGFuZGxlIC4uLiB9CisgKiAgICAgfQorICogICB9CisgKgorICogICBjbGFzcyBFbXB0eWluZ0xvb3AgaW1wbGVtZW50cyBSdW5uYWJsZSB7CisgKiAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICogICAgICAgRGF0YUJ1ZmZlciBjdXJyZW50QnVmZmVyID0gaW5pdGlhbEZ1bGxCdWZmZXI7CisgKiAgICAgICB0cnkgeworICogICAgICAgICB3aGlsZSAoY3VycmVudEJ1ZmZlciAhPSBudWxsKSB7CisgKiAgICAgICAgICAgdGFrZUZyb21CdWZmZXIoY3VycmVudEJ1ZmZlcik7CisgKiAgICAgICAgICAgaWYgKGN1cnJlbnRCdWZmZXIuaXNFbXB0eSgpKQorICogICAgICAgICAgICAgY3VycmVudEJ1ZmZlciA9IGV4Y2hhbmdlci5leGNoYW5nZShjdXJyZW50QnVmZmVyKTsKKyAqICAgICAgICAgfQorICogICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsgLi4uIGhhbmRsZSAuLi59CisgKiAgICAgfQorICogICB9CisgKgorICogICB2b2lkIHN0YXJ0KCkgeworICogICAgIG5ldyBUaHJlYWQobmV3IEZpbGxpbmdMb29wKCkpLnN0YXJ0KCk7CisgKiAgICAgbmV3IFRocmVhZChuZXcgRW1wdHlpbmdMb29wKCkpLnN0YXJ0KCk7CisgKiAgIH0KKyAqIH0KKyAqIH08L3ByZT4KKyAqCisgKiA8cD5NZW1vcnkgY29uc2lzdGVuY3kgZWZmZWN0czogRm9yIGVhY2ggcGFpciBvZiB0aHJlYWRzIHRoYXQKKyAqIHN1Y2Nlc3NmdWxseSBleGNoYW5nZSBvYmplY3RzIHZpYSBhbiB7QGNvZGUgRXhjaGFuZ2VyfSwgYWN0aW9ucworICogcHJpb3IgdG8gdGhlIHtAY29kZSBleGNoYW5nZSgpfSBpbiBlYWNoIHRocmVhZAorICogPGEgaHJlZj0icGFja2FnZS1zdW1tYXJ5Lmh0bWwjTWVtb3J5VmlzaWJpbGl0eSI+PGk+aGFwcGVuLWJlZm9yZTwvaT48L2E+CisgKiB0aG9zZSBzdWJzZXF1ZW50IHRvIGEgcmV0dXJuIGZyb20gdGhlIGNvcnJlc3BvbmRpbmcge0Bjb2RlIGV4Y2hhbmdlKCl9CisgKiBpbiB0aGUgb3RoZXIgdGhyZWFkLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEgYW5kIEJpbGwgU2NoZXJlciBhbmQgTWljaGFlbCBTY290dAorICogQHBhcmFtIDxWPiBUaGUgdHlwZSBvZiBvYmplY3RzIHRoYXQgbWF5IGJlIGV4Y2hhbmdlZAorICovCitwdWJsaWMgY2xhc3MgRXhjaGFuZ2VyPFY+IHsKKyAgICAvKgorICAgICAqIEFsZ29yaXRobSBEZXNjcmlwdGlvbjoKKyAgICAgKgorICAgICAqIFRoZSBiYXNpYyBpZGVhIGlzIHRvIG1haW50YWluIGEgInNsb3QiLCB3aGljaCBpcyBhIHJlZmVyZW5jZSB0bworICAgICAqIGEgTm9kZSBjb250YWluaW5nIGJvdGggYW4gSXRlbSB0byBvZmZlciBhbmQgYSAiaG9sZSIgd2FpdGluZyB0bworICAgICAqIGdldCBmaWxsZWQgaW4uICBJZiBhbiBpbmNvbWluZyAib2NjdXB5aW5nIiB0aHJlYWQgc2VlcyB0aGF0IHRoZQorICAgICAqIHNsb3QgaXMgbnVsbCwgaXQgQ0FTJ2VzIChjb21wYXJlQW5kU2V0cykgYSBOb2RlIHRoZXJlIGFuZCB3YWl0cworICAgICAqIGZvciBhbm90aGVyIHRvIGludm9rZSBleGNoYW5nZS4gIFRoYXQgc2Vjb25kICJmdWxmaWxsaW5nIiB0aHJlYWQKKyAgICAgKiBzZWVzIHRoYXQgdGhlIHNsb3QgaXMgbm9uLW51bGwsIGFuZCBzbyBDQVNlcyBpdCBiYWNrIHRvIG51bGwsCisgICAgICogYWxzbyBleGNoYW5naW5nIGl0ZW1zIGJ5IENBU2luZyB0aGUgaG9sZSwgcGx1cyB3YWtpbmcgdXAgdGhlCisgICAgICogb2NjdXB5aW5nIHRocmVhZCBpZiBpdCBpcyBibG9ja2VkLiAgSW4gZWFjaCBjYXNlIENBUydlcyBtYXkKKyAgICAgKiBmYWlsIGJlY2F1c2UgYSBzbG90IGF0IGZpcnN0IGFwcGVhcnMgbm9uLW51bGwgYnV0IGlzIG51bGwgdXBvbgorICAgICAqIENBUywgb3IgdmljZS12ZXJzYS4gIFNvIHRocmVhZHMgbWF5IG5lZWQgdG8gcmV0cnkgdGhlc2UKKyAgICAgKiBhY3Rpb25zLgorICAgICAqCisgICAgICogVGhpcyBzaW1wbGUgYXBwcm9hY2ggd29ya3MgZ3JlYXQgd2hlbiB0aGVyZSBhcmUgb25seSBhIGZldworICAgICAqIHRocmVhZHMgdXNpbmcgYW4gRXhjaGFuZ2VyLCBidXQgcGVyZm9ybWFuY2UgcmFwaWRseQorICAgICAqIGRldGVyaW9yYXRlcyBkdWUgdG8gQ0FTIGNvbnRlbnRpb24gb24gdGhlIHNpbmdsZSBzbG90IHdoZW4KKyAgICAgKiB0aGVyZSBhcmUgbG90cyBvZiB0aHJlYWRzIHVzaW5nIGFuIGV4Y2hhbmdlci4gIFNvIGluc3RlYWQgd2UgdXNlCisgICAgICogYW4gImFyZW5hIjsgYmFzaWNhbGx5IGEga2luZCBvZiBoYXNoIHRhYmxlIHdpdGggYSBkeW5hbWljYWxseQorICAgICAqIHZhcnlpbmcgbnVtYmVyIG9mIHNsb3RzLCBhbnkgb25lIG9mIHdoaWNoIGNhbiBiZSB1c2VkIGJ5CisgICAgICogdGhyZWFkcyBwZXJmb3JtaW5nIGFuIGV4Y2hhbmdlLiAgSW5jb21pbmcgdGhyZWFkcyBwaWNrIHNsb3RzCisgICAgICogYmFzZWQgb24gYSBoYXNoIG9mIHRoZWlyIFRocmVhZCBpZHMuICBJZiBhbiBpbmNvbWluZyB0aHJlYWQKKyAgICAgKiBmYWlscyB0byBDQVMgaW4gaXRzIGNob3NlbiBzbG90LCBpdCBwaWNrcyBhbiBhbHRlcm5hdGl2ZSBzbG90CisgICAgICogaW5zdGVhZC4gIEFuZCBzaW1pbGFybHkgZnJvbSB0aGVyZS4gIElmIGEgdGhyZWFkIHN1Y2Nlc3NmdWxseQorICAgICAqIENBU2VzIGludG8gYSBzbG90IGJ1dCBubyBvdGhlciB0aHJlYWQgYXJyaXZlcywgaXQgdHJpZXMKKyAgICAgKiBhbm90aGVyLCBoZWFkaW5nIHRvd2FyZCB0aGUgemVybyBzbG90LCB3aGljaCBhbHdheXMgZXhpc3RzIGV2ZW4KKyAgICAgKiBpZiB0aGUgdGFibGUgc2hyaW5rcy4gIFRoZSBwYXJ0aWN1bGFyIG1lY2hhbmljcyBjb250cm9sbGluZyB0aGlzCisgICAgICogYXJlIGFzIGZvbGxvd3M6CisgICAgICoKKyAgICAgKiBXYWl0aW5nOiBTbG90IHplcm8gaXMgc3BlY2lhbCBpbiB0aGF0IGl0IGlzIHRoZSBvbmx5IHNsb3QgdGhhdAorICAgICAqIGV4aXN0cyB3aGVuIHRoZXJlIGlzIG5vIGNvbnRlbnRpb24uICBBIHRocmVhZCBvY2N1cHlpbmcgc2xvdAorICAgICAqIHplcm8gd2lsbCBibG9jayBpZiBubyB0aHJlYWQgZnVsZmlsbHMgaXQgYWZ0ZXIgYSBzaG9ydCBzcGluLgorICAgICAqIEluIG90aGVyIGNhc2VzLCBvY2N1cHlpbmcgdGhyZWFkcyBldmVudHVhbGx5IGdpdmUgdXAgYW5kIHRyeQorICAgICAqIGFub3RoZXIgc2xvdC4gIFdhaXRpbmcgdGhyZWFkcyBzcGluIGZvciBhIHdoaWxlIChhIHBlcmlvZCB0aGF0CisgICAgICogc2hvdWxkIGJlIGEgbGl0dGxlIGxlc3MgdGhhbiBhIHR5cGljYWwgY29udGV4dC1zd2l0Y2ggdGltZSkKKyAgICAgKiBiZWZvcmUgZWl0aGVyIGJsb2NraW5nIChpZiBzbG90IHplcm8pIG9yIGdpdmluZyB1cCAoaWYgb3RoZXIKKyAgICAgKiBzbG90cykgYW5kIHJlc3RhcnRpbmcuICBUaGVyZSBpcyBubyByZWFzb24gZm9yIHRocmVhZHMgdG8gYmxvY2sKKyAgICAgKiB1bmxlc3MgdGhlcmUgYXJlIHVubGlrZWx5IHRvIGJlIGFueSBvdGhlciB0aHJlYWRzIHByZXNlbnQuCisgICAgICogT2NjdXBhbnRzIGFyZSBtYWlubHkgYXZvaWRpbmcgbWVtb3J5IGNvbnRlbnRpb24gc28gc2l0IHRoZXJlCisgICAgICogcXVpZXRseSBwb2xsaW5nIGZvciBhIHNob3J0ZXIgcGVyaW9kIHRoYW4gaXQgd291bGQgdGFrZSB0bworICAgICAqIGJsb2NrIGFuZCB0aGVuIHVuYmxvY2sgdGhlbS4gIE5vbi1zbG90LXplcm8gd2FpdHMgdGhhdCBlbGFwc2UKKyAgICAgKiBiZWNhdXNlIG9mIGxhY2sgb2Ygb3RoZXIgdGhyZWFkcyB3YXN0ZSBhcm91bmQgb25lIGV4dHJhCisgICAgICogY29udGV4dC1zd2l0Y2ggdGltZSBwZXIgdHJ5LCB3aGljaCBpcyBzdGlsbCBvbiBhdmVyYWdlIG11Y2gKKyAgICAgKiBmYXN0ZXIgdGhhbiBhbHRlcm5hdGl2ZSBhcHByb2FjaGVzLgorICAgICAqCisgICAgICogU2l6aW5nOiBVc3VhbGx5LCB1c2luZyBvbmx5IGEgZmV3IHNsb3RzIHN1ZmZpY2VzIHRvIHJlZHVjZQorICAgICAqIGNvbnRlbnRpb24uICBFc3BlY2lhbGx5IHdpdGggc21hbGwgbnVtYmVycyBvZiB0aHJlYWRzLCB1c2luZworICAgICAqIHRvbyBtYW55IHNsb3RzIGNhbiBsZWFkIHRvIGp1c3QgYXMgcG9vciBwZXJmb3JtYW5jZSBhcyB1c2luZworICAgICAqIHRvbyBmZXcgb2YgdGhlbSwgYW5kIHRoZXJlJ3Mgbm90IG11Y2ggcm9vbSBmb3IgZXJyb3IuICBUaGUKKyAgICAgKiB2YXJpYWJsZSAibWF4IiBtYWludGFpbnMgdGhlIG51bWJlciBvZiBzbG90cyBhY3R1YWxseSBpbgorICAgICAqIHVzZS4gIEl0IGlzIGluY3JlYXNlZCB3aGVuIGEgdGhyZWFkIHNlZXMgdG9vIG1hbnkgQ0FTCisgICAgICogZmFpbHVyZXMuICAoVGhpcyBpcyBhbmFsb2dvdXMgdG8gcmVzaXppbmcgYSByZWd1bGFyIGhhc2ggdGFibGUKKyAgICAgKiBiYXNlZCBvbiBhIHRhcmdldCBsb2FkIGZhY3RvciwgZXhjZXB0IGhlcmUsIGdyb3d0aCBzdGVwcyBhcmUKKyAgICAgKiBqdXN0IG9uZS1ieS1vbmUgcmF0aGVyIHRoYW4gcHJvcG9ydGlvbmFsLikgIEdyb3d0aCByZXF1aXJlcworICAgICAqIGNvbnRlbnRpb24gZmFpbHVyZXMgaW4gZWFjaCBvZiB0aHJlZSB0cmllZCBzbG90cy4gIFJlcXVpcmluZworICAgICAqIG11bHRpcGxlIGZhaWx1cmVzIGZvciBleHBhbnNpb24gY29wZXMgd2l0aCB0aGUgZmFjdCB0aGF0IHNvbWUKKyAgICAgKiBmYWlsZWQgQ0FTZXMgYXJlIG5vdCBkdWUgdG8gY29udGVudGlvbiBidXQgaW5zdGVhZCB0byBzaW1wbGUKKyAgICAgKiByYWNlcyBiZXR3ZWVuIHR3byB0aHJlYWRzIG9yIHRocmVhZCBwcmUtZW1wdGlvbnMgb2NjdXJyaW5nCisgICAgICogYmV0d2VlbiByZWFkaW5nIGFuZCBDQVNpbmcuICBBbHNvLCB2ZXJ5IHRyYW5zaWVudCBwZWFrCisgICAgICogY29udGVudGlvbiBjYW4gYmUgbXVjaCBoaWdoZXIgdGhhbiB0aGUgYXZlcmFnZSBzdXN0YWluYWJsZQorICAgICAqIGxldmVscy4gIFRoZSBtYXggbGltaXQgaXMgZGVjcmVhc2VkIG9uIGF2ZXJhZ2UgNTAlIG9mIHRoZSB0aW1lcworICAgICAqIHRoYXQgYSBub24tc2xvdC16ZXJvIHdhaXQgZWxhcHNlcyB3aXRob3V0IGJlaW5nIGZ1bGZpbGxlZC4KKyAgICAgKiBUaHJlYWRzIGV4cGVyaWVuY2luZyBlbGFwc2VkIHdhaXRzIG1vdmUgY2xvc2VyIHRvIHplcm8sIHNvCisgICAgICogZXZlbnR1YWxseSBmaW5kIGV4aXN0aW5nIChvciBmdXR1cmUpIHRocmVhZHMgZXZlbiBpZiB0aGUgdGFibGUKKyAgICAgKiBoYXMgYmVlbiBzaHJ1bmsgZHVlIHRvIGluYWN0aXZpdHkuICBUaGUgY2hvc2VuIG1lY2hhbmljcyBhbmQKKyAgICAgKiB0aHJlc2hvbGRzIGZvciBncm93aW5nIGFuZCBzaHJpbmtpbmcgYXJlIGludHJpbnNpY2FsbHkKKyAgICAgKiBlbnRhbmdsZWQgd2l0aCBpbmRleGluZyBhbmQgaGFzaGluZyBpbnNpZGUgdGhlIGV4Y2hhbmdlIGNvZGUsCisgICAgICogYW5kIGNhbid0IGJlIG5pY2VseSBhYnN0cmFjdGVkIG91dC4KKyAgICAgKgorICAgICAqIEhhc2hpbmc6IEVhY2ggdGhyZWFkIHBpY2tzIGl0cyBpbml0aWFsIHNsb3QgdG8gdXNlIGluIGFjY29yZAorICAgICAqIHdpdGggYSBzaW1wbGUgaGFzaGNvZGUuICBUaGUgc2VxdWVuY2UgaXMgdGhlIHNhbWUgb24gZWFjaAorICAgICAqIGVuY291bnRlciBieSBhbnkgZ2l2ZW4gdGhyZWFkLCBidXQgZWZmZWN0aXZlbHkgcmFuZG9tIGFjcm9zcworICAgICAqIHRocmVhZHMuICBVc2luZyBhcmVuYXMgZW5jb3VudGVycyB0aGUgY2xhc3NpYyBjb3N0IHZzIHF1YWxpdHkKKyAgICAgKiB0cmFkZW9mZnMgb2YgYWxsIGhhc2ggdGFibGVzLiAgSGVyZSwgd2UgdXNlIGEgb25lLXN0ZXAgRk5WLTFhCisgICAgICogaGFzaCBjb2RlIGJhc2VkIG9uIHRoZSBjdXJyZW50IHRocmVhZCdzIFRocmVhZC5nZXRJZCgpLCBhbG9uZworICAgICAqIHdpdGggYSBjaGVhcCBhcHByb3hpbWF0aW9uIHRvIGEgbW9kIG9wZXJhdGlvbiB0byBzZWxlY3QgYW4KKyAgICAgKiBpbmRleC4gIFRoZSBkb3duc2lkZSBvZiBvcHRpbWl6aW5nIGluZGV4IHNlbGVjdGlvbiBpbiB0aGlzIHdheQorICAgICAqIGlzIHRoYXQgdGhlIGNvZGUgaXMgaGFyZHdpcmVkIHRvIHVzZSBhIG1heGltdW0gdGFibGUgc2l6ZSBvZgorICAgICAqIDMyLiAgQnV0IHRoaXMgdmFsdWUgbW9yZSB0aGFuIHN1ZmZpY2VzIGZvciBrbm93biBwbGF0Zm9ybXMgYW5kCisgICAgICogYXBwbGljYXRpb25zLgorICAgICAqCisgICAgICogUHJvYmluZzogT24gc2Vuc2VkIGNvbnRlbnRpb24gb2YgYSBzZWxlY3RlZCBzbG90LCB3ZSBwcm9iZQorICAgICAqIHNlcXVlbnRpYWxseSB0aHJvdWdoIHRoZSB0YWJsZSwgYW5hbG9nb3VzbHkgdG8gbGluZWFyIHByb2JpbmcKKyAgICAgKiBhZnRlciBjb2xsaXNpb24gaW4gYSBoYXNoIHRhYmxlLiAgKFdlIG1vdmUgY2lyY3VsYXJseSwgaW4KKyAgICAgKiByZXZlcnNlIG9yZGVyLCB0byBtZXNoIGJlc3Qgd2l0aCB0YWJsZSBncm93dGggYW5kIHNocmlua2FnZQorICAgICAqIHJ1bGVzLikgIEV4Y2VwdCB0aGF0IHRvIG1pbmltaXplIHRoZSBlZmZlY3RzIG9mIGZhbHNlLWFsYXJtcworICAgICAqIGFuZCBjYWNoZSB0aHJhc2hpbmcsIHdlIHRyeSB0aGUgZmlyc3Qgc2VsZWN0ZWQgc2xvdCB0d2ljZQorICAgICAqIGJlZm9yZSBtb3ZpbmcuCisgICAgICoKKyAgICAgKiBQYWRkaW5nOiBFdmVuIHdpdGggY29udGVudGlvbiBtYW5hZ2VtZW50LCBzbG90cyBhcmUgaGVhdmlseQorICAgICAqIGNvbnRlbmRlZCwgc28gdXNlIGNhY2hlLXBhZGRpbmcgdG8gYXZvaWQgcG9vciBtZW1vcnkKKyAgICAgKiBwZXJmb3JtYW5jZS4gIEJlY2F1c2Ugb2YgdGhpcywgc2xvdHMgYXJlIGxhemlseSBjb25zdHJ1Y3RlZAorICAgICAqIG9ubHkgd2hlbiB1c2VkLCB0byBhdm9pZCB3YXN0aW5nIHRoaXMgc3BhY2UgdW5uZWNlc3NhcmlseS4KKyAgICAgKiBXaGlsZSBpc29sYXRpb24gb2YgbG9jYXRpb25zIGlzIG5vdCBtdWNoIG9mIGFuIGlzc3VlIGF0IGZpcnN0CisgICAgICogaW4gYW4gYXBwbGljYXRpb24sIGFzIHRpbWUgZ29lcyBvbiBhbmQgZ2FyYmFnZS1jb2xsZWN0b3JzCisgICAgICogcGVyZm9ybSBjb21wYWN0aW9uLCBzbG90cyBhcmUgdmVyeSBsaWtlbHkgdG8gYmUgbW92ZWQgYWRqYWNlbnQKKyAgICAgKiB0byBlYWNoIG90aGVyLCB3aGljaCBjYW4gY2F1c2UgbXVjaCB0aHJhc2hpbmcgb2YgY2FjaGUgbGluZXMgb24KKyAgICAgKiBNUHMgdW5sZXNzIHBhZGRpbmcgaXMgZW1wbG95ZWQuCisgICAgICoKKyAgICAgKiBUaGlzIGlzIGFuIGltcHJvdmVtZW50IG9mIHRoZSBhbGdvcml0aG0gZGVzY3JpYmVkIGluIHRoZSBwYXBlcgorICAgICAqICJBIFNjYWxhYmxlIEVsaW1pbmF0aW9uLWJhc2VkIEV4Y2hhbmdlIENoYW5uZWwiIGJ5IFdpbGxpYW0KKyAgICAgKiBTY2hlcmVyLCBEb3VnIExlYSwgYW5kIE1pY2hhZWwgU2NvdHQgaW4gUHJvY2VlZGluZ3Mgb2YgU0NPT0wwNQorICAgICAqIHdvcmtzaG9wLiAgQXZhaWxhYmxlIGF0OiBodHRwOi8vaGRsLmhhbmRsZS5uZXQvMTgwMi8yMTA0CisgICAgICovCisKKyAgICAvKiogVGhlIG51bWJlciBvZiBDUFVzLCBmb3Igc2l6aW5nIGFuZCBzcGluIGNvbnRyb2wgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTkNQVSA9IFJ1bnRpbWUuZ2V0UnVudGltZSgpLmF2YWlsYWJsZVByb2Nlc3NvcnMoKTsKKworICAgIC8qKgorICAgICAqIFRoZSBjYXBhY2l0eSBvZiB0aGUgYXJlbmEuICBTZXQgdG8gYSB2YWx1ZSB0aGF0IHByb3ZpZGVzIG1vcmUKKyAgICAgKiB0aGFuIGVub3VnaCBzcGFjZSB0byBoYW5kbGUgY29udGVudGlvbi4gIE9uIHNtYWxsIG1hY2hpbmVzCisgICAgICogbW9zdCBzbG90cyB3b24ndCBiZSB1c2VkLCBidXQgaXQgaXMgc3RpbGwgbm90IHdhc3RlZCBiZWNhdXNlCisgICAgICogdGhlIGV4dHJhIHNwYWNlIHByb3ZpZGVzIHNvbWUgbWFjaGluZS1sZXZlbCBhZGRyZXNzIHBhZGRpbmcKKyAgICAgKiB0byBtaW5pbWl6ZSBpbnRlcmZlcmVuY2Ugd2l0aCBoZWF2aWx5IENBUydlZCBTbG90IGxvY2F0aW9ucy4KKyAgICAgKiBBbmQgb24gdmVyeSBsYXJnZSBtYWNoaW5lcywgcGVyZm9ybWFuY2UgZXZlbnR1YWxseSBiZWNvbWVzCisgICAgICogYm91bmRlZCBieSBtZW1vcnkgYmFuZHdpZHRoLCBub3QgbnVtYmVycyBvZiB0aHJlYWRzL0NQVXMuCisgICAgICogVGhpcyBjb25zdGFudCBjYW5ub3QgYmUgY2hhbmdlZCB3aXRob3V0IGFsc28gbW9kaWZ5aW5nCisgICAgICogaW5kZXhpbmcgYW5kIGhhc2hpbmcgYWxnb3JpdGhtcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0FQQUNJVFkgPSAzMjsKKworICAgIC8qKgorICAgICAqIFRoZSB2YWx1ZSBvZiAibWF4IiB0aGF0IHdpbGwgaG9sZCBhbGwgdGhyZWFkcyB3aXRob3V0CisgICAgICogY29udGVudGlvbi4gIFdoZW4gdGhpcyB2YWx1ZSBpcyBsZXNzIHRoYW4gQ0FQQUNJVFksIHNvbWUKKyAgICAgKiBvdGhlcndpc2Ugd2FzdGVkIGV4cGFuc2lvbiBjYW4gYmUgYXZvaWRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRlVMTCA9CisgICAgICAgIE1hdGgubWF4KDAsIE1hdGgubWluKENBUEFDSVRZLCBOQ1BVIC8gMikgLSAxKTsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgdGltZXMgdG8gc3BpbiAoZG9pbmcgbm90aGluZyBleGNlcHQgcG9sbGluZyBhCisgICAgICogbWVtb3J5IGxvY2F0aW9uKSBiZWZvcmUgYmxvY2tpbmcgb3IgZ2l2aW5nIHVwIHdoaWxlIHdhaXRpbmcgdG8KKyAgICAgKiBiZSBmdWxmaWxsZWQuICBTaG91bGQgYmUgemVybyBvbiB1bmlwcm9jZXNzb3JzLiAgT24KKyAgICAgKiBtdWx0aXByb2Nlc3NvcnMsIHRoaXMgdmFsdWUgc2hvdWxkIGJlIGxhcmdlIGVub3VnaCBzbyB0aGF0IHR3bworICAgICAqIHRocmVhZHMgZXhjaGFuZ2luZyBpdGVtcyBhcyBmYXN0IGFzIHBvc3NpYmxlIGJsb2NrIG9ubHkgd2hlbgorICAgICAqIG9uZSBvZiB0aGVtIGlzIHN0YWxsZWQgKGR1ZSB0byBHQyBvciBwcmVlbXB0aW9uKSwgYnV0IG5vdCBtdWNoCisgICAgICogbG9uZ2VyLCB0byBhdm9pZCB3YXN0aW5nIENQVSByZXNvdXJjZXMuICBTZWVuIGRpZmZlcmVudGx5LCB0aGlzCisgICAgICogdmFsdWUgaXMgYSBsaXR0bGUgb3ZlciBoYWxmIHRoZSBudW1iZXIgb2YgY3ljbGVzIG9mIGFuIGF2ZXJhZ2UKKyAgICAgKiBjb250ZXh0IHN3aXRjaCB0aW1lIG9uIG1vc3Qgc3lzdGVtcy4gIFRoZSB2YWx1ZSBoZXJlIGlzCisgICAgICogYXBwcm94aW1hdGVseSB0aGUgYXZlcmFnZSBvZiB0aG9zZSBhY3Jvc3MgYSByYW5nZSBvZiB0ZXN0ZWQKKyAgICAgKiBzeXN0ZW1zLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTUElOUyA9IChOQ1BVID09IDEpID8gMCA6IDIwMDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIHNwaW4gYmVmb3JlIGJsb2NraW5nIGluIHRpbWVkIHdhaXRzLgorICAgICAqIFRpbWVkIHdhaXRzIHNwaW4gbW9yZSBzbG93bHkgYmVjYXVzZSBjaGVja2luZyB0aGUgdGltZSB0YWtlcworICAgICAqIHRpbWUuICBUaGUgYmVzdCB2YWx1ZSByZWxpZXMgbWFpbmx5IG9uIHRoZSByZWxhdGl2ZSByYXRlIG9mCisgICAgICogU3lzdGVtLm5hbm9UaW1lIHZzIG1lbW9yeSBhY2Nlc3Nlcy4gIFRoZSB2YWx1ZSBpcyBlbXBpcmljYWxseQorICAgICAqIGRlcml2ZWQgdG8gd29yayB3ZWxsIGFjcm9zcyBhIHZhcmlldHkgb2Ygc3lzdGVtcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVElNRURfU1BJTlMgPSBTUElOUyAvIDIwOworCisgICAgLyoqCisgICAgICogU2VudGluZWwgaXRlbSByZXByZXNlbnRpbmcgY2FuY2VsbGF0aW9uIG9mIGEgd2FpdCBkdWUgdG8KKyAgICAgKiBpbnRlcnJ1cHRpb24sIHRpbWVvdXQsIG9yIGVsYXBzZWQgc3Bpbi13YWl0cy4gIFRoaXMgdmFsdWUgaXMKKyAgICAgKiBwbGFjZWQgaW4gaG9sZXMgb24gY2FuY2VsbGF0aW9uLCBhbmQgdXNlZCBhcyBhIHJldHVybiB2YWx1ZQorICAgICAqIGZyb20gd2FpdGluZyBtZXRob2RzIHRvIGluZGljYXRlIGZhaWx1cmUgdG8gc2V0IG9yIGdldCBob2xlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdCBDQU5DRUwgPSBuZXcgT2JqZWN0KCk7CisKKyAgICAvKioKKyAgICAgKiBWYWx1ZSByZXByZXNlbnRpbmcgbnVsbCBhcmd1bWVudHMvcmV0dXJucyBmcm9tIHB1YmxpYworICAgICAqIG1ldGhvZHMuICBUaGlzIGRpc2FtYmlndWF0ZXMgZnJvbSBpbnRlcm5hbCByZXF1aXJlbWVudCB0aGF0CisgICAgICogaG9sZXMgc3RhcnQgb3V0IGFzIG51bGwgdG8gbWVhbiB0aGV5IGFyZSBub3QgeWV0IHNldC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3QgTlVMTF9JVEVNID0gbmV3IE9iamVjdCgpOworCisgICAgLyoqCisgICAgICogTm9kZXMgaG9sZCBwYXJ0aWFsbHkgZXhjaGFuZ2VkIGRhdGEuICBUaGlzIGNsYXNzCisgICAgICogb3Bwb3J0dW5pc3RpY2FsbHkgc3ViY2xhc3NlcyBBdG9taWNSZWZlcmVuY2UgdG8gcmVwcmVzZW50IHRoZQorICAgICAqIGhvbGUuICBTbyBnZXQoKSByZXR1cm5zIGhvbGUsIGFuZCBjb21wYXJlQW5kU2V0IENBUydlcyB2YWx1ZQorICAgICAqIGludG8gaG9sZS4gIFRoaXMgY2xhc3MgY2Fubm90IGJlIHBhcmFtZXRlcml6ZWQgYXMgIlYiIGJlY2F1c2UKKyAgICAgKiBvZiB0aGUgdXNlIG9mIG5vbi1WIENBTkNFTCBzZW50aW5lbHMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTm9kZSBleHRlbmRzIEF0b21pY1JlZmVyZW5jZTxPYmplY3Q+IHsKKyAgICAgICAgLyoqIFRoZSBlbGVtZW50IG9mZmVyZWQgYnkgdGhlIFRocmVhZCBjcmVhdGluZyB0aGlzIG5vZGUuICovCisgICAgICAgIHB1YmxpYyBmaW5hbCBPYmplY3QgaXRlbTsKKworICAgICAgICAvKiogVGhlIFRocmVhZCB3YWl0aW5nIHRvIGJlIHNpZ25hbGxlZDsgbnVsbCB1bnRpbCB3YWl0aW5nLiAqLworICAgICAgICBwdWJsaWMgdm9sYXRpbGUgVGhyZWFkIHdhaXRlcjsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBub2RlIHdpdGggZ2l2ZW4gaXRlbSBhbmQgZW1wdHkgaG9sZS4KKyAgICAgICAgICogQHBhcmFtIGl0ZW0gdGhlIGl0ZW0KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBOb2RlKE9iamVjdCBpdGVtKSB7CisgICAgICAgICAgICB0aGlzLml0ZW0gPSBpdGVtOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBTbG90IGlzIGFuIEF0b21pY1JlZmVyZW5jZSB3aXRoIGhldXJpc3RpYyBwYWRkaW5nIHRvIGxlc3NlbgorICAgICAqIGNhY2hlIGVmZmVjdHMgb2YgdGhpcyBoZWF2aWx5IENBUydlZCBsb2NhdGlvbi4gIFdoaWxlIHRoZQorICAgICAqIHBhZGRpbmcgYWRkcyBub3RpY2VhYmxlIHNwYWNlLCBhbGwgc2xvdHMgYXJlIGNyZWF0ZWQgb25seSBvbgorICAgICAqIGRlbWFuZCwgYW5kIHRoZXJlIHdpbGwgYmUgbW9yZSB0aGFuIG9uZSBvZiB0aGVtIG9ubHkgd2hlbiBpdAorICAgICAqIHdvdWxkIGltcHJvdmUgdGhyb3VnaHB1dCBtb3JlIHRoYW4gZW5vdWdoIHRvIG91dHdlaWdoIHVzaW5nCisgICAgICogZXh0cmEgc3BhY2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU2xvdCBleHRlbmRzIEF0b21pY1JlZmVyZW5jZTxPYmplY3Q+IHsKKyAgICAgICAgLy8gSW1wcm92ZSBsaWtlbGlob29kIG9mIGlzb2xhdGlvbiBvbiA8PSA2NCBieXRlIGNhY2hlIGxpbmVzCisgICAgICAgIGxvbmcgcTAsIHExLCBxMiwgcTMsIHE0LCBxNSwgcTYsIHE3LCBxOCwgcTksIHFhLCBxYiwgcWMsIHFkLCBxZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTbG90IGFycmF5LiAgRWxlbWVudHMgYXJlIGxhemlseSBpbml0aWFsaXplZCB3aGVuIG5lZWRlZC4KKyAgICAgKiBEZWNsYXJlZCB2b2xhdGlsZSB0byBlbmFibGUgZG91YmxlLWNoZWNrZWQgbGF6eSBjb25zdHJ1Y3Rpb24uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBTbG90W10gYXJlbmEgPSBuZXcgU2xvdFtDQVBBQ0lUWV07CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF4aW11bSBzbG90IGluZGV4IGJlaW5nIHVzZWQuICBUaGUgdmFsdWUgc29tZXRpbWVzCisgICAgICogaW5jcmVhc2VzIHdoZW4gYSB0aHJlYWQgZXhwZXJpZW5jZXMgdG9vIG1hbnkgQ0FTIGNvbnRlbnRpb25zLAorICAgICAqIGFuZCBzb21ldGltZXMgZGVjcmVhc2VzIHdoZW4gYSBzcGluLXdhaXQgZWxhcHNlcy4gIENoYW5nZXMKKyAgICAgKiBhcmUgcGVyZm9ybWVkIG9ubHkgdmlhIGNvbXBhcmVBbmRTZXQsIHRvIGF2b2lkIHN0YWxlIHZhbHVlcworICAgICAqIHdoZW4gYSB0aHJlYWQgaGFwcGVucyB0byBzdGFsbCByaWdodCBiZWZvcmUgc2V0dGluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIEF0b21pY0ludGVnZXIgbWF4ID0gbmV3IEF0b21pY0ludGVnZXIoKTsKKworICAgIC8qKgorICAgICAqIE1haW4gZXhjaGFuZ2UgZnVuY3Rpb24sIGhhbmRsaW5nIHRoZSBkaWZmZXJlbnQgcG9saWN5IHZhcmlhbnRzLgorICAgICAqIFVzZXMgT2JqZWN0LCBub3QgIlYiIGFzIGFyZ3VtZW50IGFuZCByZXR1cm4gdmFsdWUgdG8gc2ltcGxpZnkKKyAgICAgKiBoYW5kbGluZyBvZiBzZW50aW5lbCB2YWx1ZXMuICBDYWxsZXJzIGZyb20gcHVibGljIG1ldGhvZHMgZGVjb2RlCisgICAgICogYW5kIGNhc3QgYWNjb3JkaW5nbHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXRlbSB0aGUgKG5vbi1udWxsKSBpdGVtIHRvIGV4Y2hhbmdlCisgICAgICogQHBhcmFtIHRpbWVkIHRydWUgaWYgdGhlIHdhaXQgaXMgdGltZWQKKyAgICAgKiBAcGFyYW0gbmFub3MgaWYgdGltZWQsIHRoZSBtYXhpbXVtIHdhaXQgdGltZQorICAgICAqIEByZXR1cm4gdGhlIG90aGVyIHRocmVhZCdzIGl0ZW0sIG9yIENBTkNFTCBpZiBpbnRlcnJ1cHRlZCBvciB0aW1lZCBvdXQKKyAgICAgKi8KKyAgICBwcml2YXRlIE9iamVjdCBkb0V4Y2hhbmdlKE9iamVjdCBpdGVtLCBib29sZWFuIHRpbWVkLCBsb25nIG5hbm9zKSB7CisgICAgICAgIE5vZGUgbWUgPSBuZXcgTm9kZShpdGVtKTsgICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBpbiBjYXNlIG9jY3VweWluZworICAgICAgICBpbnQgaW5kZXggPSBoYXNoSW5kZXgoKTsgICAgICAgICAgICAgICAgICAvLyBJbmRleCBvZiBjdXJyZW50IHNsb3QKKyAgICAgICAgaW50IGZhaWxzID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVyIG9mIENBUyBmYWlsdXJlcworCisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIE9iamVjdCB5OyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29udGVudHMgb2YgY3VycmVudCBzbG90CisgICAgICAgICAgICBTbG90IHNsb3QgPSBhcmVuYVtpbmRleF07CisgICAgICAgICAgICBpZiAoc2xvdCA9PSBudWxsKSAgICAgICAgICAgICAgICAgICAgIC8vIExhemlseSBpbml0aWFsaXplIHNsb3RzCisgICAgICAgICAgICAgICAgY3JlYXRlU2xvdChpbmRleCk7ICAgICAgICAgICAgICAgIC8vIENvbnRpbnVlIGxvb3AgdG8gcmVyZWFkCisgICAgICAgICAgICBlbHNlIGlmICgoeSA9IHNsb3QuZ2V0KCkpICE9IG51bGwgJiYgIC8vIFRyeSB0byBmdWxmaWxsCisgICAgICAgICAgICAgICAgICAgICBzbG90LmNvbXBhcmVBbmRTZXQoeSwgbnVsbCkpIHsKKyAgICAgICAgICAgICAgICBOb2RlIHlvdSA9IChOb2RlKXk7ICAgICAgICAgICAgICAgLy8gVHJhbnNmZXIgaXRlbQorICAgICAgICAgICAgICAgIGlmICh5b3UuY29tcGFyZUFuZFNldChudWxsLCBpdGVtKSkgeworICAgICAgICAgICAgICAgICAgICBMb2NrU3VwcG9ydC51bnBhcmsoeW91LndhaXRlcik7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB5b3UuaXRlbTsKKyAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRWxzZSBjYW5jZWxsZWQ7IGNvbnRpbnVlCisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIGlmICh5ID09IG51bGwgJiYgICAgICAgICAgICAgICAgIC8vIFRyeSB0byBvY2N1cHkKKyAgICAgICAgICAgICAgICAgICAgIHNsb3QuY29tcGFyZUFuZFNldChudWxsLCBtZSkpIHsKKyAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgICAgICAgICAgICAgICAgICAgLy8gQmxvY2tpbmcgd2FpdCBmb3Igc2xvdCAwCisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aW1lZCA/CisgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdE5hbm9zKG1lLCBzbG90LCBuYW5vcykgOgorICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQobWUsIHNsb3QpOworICAgICAgICAgICAgICAgIE9iamVjdCB2ID0gc3BpbldhaXQobWUsIHNsb3QpOyAgICAvLyBTcGluIHdhaXQgZm9yIG5vbi0wCisgICAgICAgICAgICAgICAgaWYgKHYgIT0gQ0FOQ0VMKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gdjsKKyAgICAgICAgICAgICAgICBtZSA9IG5ldyBOb2RlKGl0ZW0pOyAgICAgICAgICAgICAgLy8gVGhyb3cgYXdheSBjYW5jZWxsZWQgbm9kZQorICAgICAgICAgICAgICAgIGludCBtID0gbWF4LmdldCgpOworICAgICAgICAgICAgICAgIGlmIChtID4gKGluZGV4ID4+Pj0gMSkpICAgICAgICAgICAvLyBEZWNyZWFzZSBpbmRleAorICAgICAgICAgICAgICAgICAgICBtYXguY29tcGFyZUFuZFNldChtLCBtIC0gMSk7ICAvLyBNYXliZSBzaHJpbmsgdGFibGUKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgaWYgKCsrZmFpbHMgPiAxKSB7ICAgICAgICAgICAgICAgLy8gQWxsb3cgMiBmYWlscyBvbiAxc3Qgc2xvdAorICAgICAgICAgICAgICAgIGludCBtID0gbWF4LmdldCgpOworICAgICAgICAgICAgICAgIGlmIChmYWlscyA+IDMgJiYgbSA8IEZVTEwgJiYgbWF4LmNvbXBhcmVBbmRTZXQobSwgbSArIDEpKQorICAgICAgICAgICAgICAgICAgICBpbmRleCA9IG0gKyAxOyAgICAgICAgICAgICAgICAvLyBHcm93IG9uIDNyZCBmYWlsZWQgc2xvdAorICAgICAgICAgICAgICAgIGVsc2UgaWYgKC0taW5kZXggPCAwKQorICAgICAgICAgICAgICAgICAgICBpbmRleCA9IG07ICAgICAgICAgICAgICAgICAgICAvLyBDaXJjdWxhcmx5IHRyYXZlcnNlCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgaGFzaCBpbmRleCBmb3IgdGhlIGN1cnJlbnQgdGhyZWFkLiAgVXNlcyBhIG9uZS1zdGVwCisgICAgICogRk5WLTFhIGhhc2ggY29kZSAoaHR0cDovL3d3dy5pc3RoZS5jb20vY2hvbmdvL3RlY2gvY29tcC9mbnYvKQorICAgICAqIGJhc2VkIG9uIHRoZSBjdXJyZW50IHRocmVhZCdzIFRocmVhZC5nZXRJZCgpLiAgVGhlc2UgaGFzaCBjb2RlcworICAgICAqIGhhdmUgbW9yZSB1bmlmb3JtIGRpc3RyaWJ1dGlvbiBwcm9wZXJ0aWVzIHdpdGggcmVzcGVjdCB0byBzbWFsbAorICAgICAqIG1vZHVsaSAoaGVyZSAxLTMxKSB0aGFuIGRvIG90aGVyIHNpbXBsZSBoYXNoaW5nIGZ1bmN0aW9ucy4KKyAgICAgKgorICAgICAqIDxwPlRvIHJldHVybiBhbiBpbmRleCBiZXR3ZWVuIDAgYW5kIG1heCwgd2UgdXNlIGEgY2hlYXAKKyAgICAgKiBhcHByb3hpbWF0aW9uIHRvIGEgbW9kIG9wZXJhdGlvbiwgdGhhdCBhbHNvIGNvcnJlY3RzIGZvciBiaWFzCisgICAgICogZHVlIHRvIG5vbi1wb3dlci1vZi0yIHJlbWFpbmRlcmluZyAoc2VlIHtAbGluaworICAgICAqIGphdmEudXRpbC5SYW5kb20jbmV4dEludH0pLiAgQml0cyBvZiB0aGUgaGFzaGNvZGUgYXJlIG1hc2tlZAorICAgICAqIHdpdGggIm5iaXRzIiwgdGhlIGNlaWxpbmcgcG93ZXIgb2YgdHdvIG9mIHRhYmxlIHNpemUgKGxvb2tlZCB1cAorICAgICAqIGluIGEgdGFibGUgcGFja2VkIGludG8gdGhyZWUgaW50cykuICBJZiB0b28gbGFyZ2UsIHRoaXMgaXMKKyAgICAgKiByZXRyaWVkIGFmdGVyIHJvdGF0aW5nIHRoZSBoYXNoIGJ5IG5iaXRzIGJpdHMsIHdoaWxlIGZvcmNpbmcgbmV3CisgICAgICogdG9wIGJpdCB0byAwLCB3aGljaCBndWFyYW50ZWVzIGV2ZW50dWFsIHRlcm1pbmF0aW9uIChhbHRob3VnaAorICAgICAqIHdpdGggYSBub24tcmFuZG9tLWJpYXMpLiAgVGhpcyByZXF1aXJlcyBhbiBhdmVyYWdlIG9mIGxlc3MgdGhhbgorICAgICAqIDIgdHJpZXMgZm9yIGFsbCB0YWJsZSBzaXplcywgYW5kIGhhcyBhIG1heGltdW0gMiUgZGlmZmVyZW5jZQorICAgICAqIGZyb20gcGVyZmVjdGx5IHVuaWZvcm0gc2xvdCBwcm9iYWJpbGl0aWVzIHdoZW4gYXBwbGllZCB0byBhbGwKKyAgICAgKiBwb3NzaWJsZSBoYXNoIGNvZGVzIGZvciBzaXplcyBsZXNzIHRoYW4gMzIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgcGVyLXRocmVhZC1yYW5kb20gaW5kZXgsIDAgPD0gaW5kZXggPCBtYXgKKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBoYXNoSW5kZXgoKSB7CisgICAgICAgIGxvbmcgaWQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldElkKCk7CisgICAgICAgIGludCBoYXNoID0gKCgoaW50KShpZCBeIChpZCA+Pj4gMzIpKSkgXiAweDgxMWM5ZGM1KSAqIDB4MDEwMDAxOTM7CisKKyAgICAgICAgaW50IG0gPSBtYXguZ2V0KCk7CisgICAgICAgIGludCBuYml0cyA9ICgoKDB4ZmZmZmZjMDAgID4+IG0pICYgNCkgfCAvLyBDb21wdXRlIGNlaWwobG9nMihtKzEpKQorICAgICAgICAgICAgICAgICAgICAgKCgweDAwMDAwMWY4ID4+PiBtKSAmIDIpIHwgLy8gVGhlIGNvbnN0YW50cyBob2xkCisgICAgICAgICAgICAgICAgICAgICAoKDB4ZmZmZjAwZjIgPj4+IG0pICYgMSkpOyAvLyBhIGxvb2t1cCB0YWJsZQorICAgICAgICBpbnQgaW5kZXg7CisgICAgICAgIHdoaWxlICgoaW5kZXggPSBoYXNoICYgKCgxIDw8IG5iaXRzKSAtIDEpKSA+IG0pICAgICAgIC8vIE1heSByZXRyeSBvbgorICAgICAgICAgICAgaGFzaCA9IChoYXNoID4+PiBuYml0cykgfCAoaGFzaCA8PCAoMzMgLSBuYml0cykpOyAvLyBub24tcG93ZXItMiBtCisgICAgICAgIHJldHVybiBpbmRleDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHNsb3QgYXQgZ2l2ZW4gaW5kZXguICBDYWxsZWQgb25seSB3aGVuIHRoZSBzbG90CisgICAgICogYXBwZWFycyB0byBiZSBudWxsLiAgUmVsaWVzIG9uIGRvdWJsZS1jaGVjayB1c2luZyBidWlsdGluCisgICAgICogbG9ja3MsIHNpbmNlIHRoZXkgcmFyZWx5IGNvbnRlbmQuICBUaGlzIGluIHR1cm4gcmVsaWVzIG9uIHRoZQorICAgICAqIGFyZW5hIGFycmF5IGJlaW5nIGRlY2xhcmVkIHZvbGF0aWxlLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCB0byBhZGQgc2xvdCBhdAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjcmVhdGVTbG90KGludCBpbmRleCkgeworICAgICAgICAvLyBDcmVhdGUgc2xvdCBvdXRzaWRlIG9mIGxvY2sgdG8gbmFycm93IHN5bmMgcmVnaW9uCisgICAgICAgIFNsb3QgbmV3U2xvdCA9IG5ldyBTbG90KCk7CisgICAgICAgIFNsb3RbXSBhID0gYXJlbmE7CisgICAgICAgIHN5bmNocm9uaXplZCAoYSkgeworICAgICAgICAgICAgaWYgKGFbaW5kZXhdID09IG51bGwpCisgICAgICAgICAgICAgICAgYVtpbmRleF0gPSBuZXdTbG90OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJpZXMgdG8gY2FuY2VsIGEgd2FpdCBmb3IgdGhlIGdpdmVuIG5vZGUgd2FpdGluZyBpbiB0aGUgZ2l2ZW4KKyAgICAgKiBzbG90LCBpZiBzbywgaGVscGluZyBjbGVhciB0aGUgbm9kZSBmcm9tIGl0cyBzbG90IHRvIGF2b2lkCisgICAgICogZ2FyYmFnZSByZXRlbnRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbm9kZSB0aGUgd2FpdGluZyBub2RlCisgICAgICogQHBhcmFtIHNsb3QgdGhlIHNsb3QgaXQgaXMgd2FpdGluZyBpbgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsbHkgY2FuY2VsbGVkCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiB0cnlDYW5jZWwoTm9kZSBub2RlLCBTbG90IHNsb3QpIHsKKyAgICAgICAgaWYgKCFub2RlLmNvbXBhcmVBbmRTZXQobnVsbCwgQ0FOQ0VMKSkKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKHNsb3QuZ2V0KCkgPT0gbm9kZSkgLy8gcHJlLWNoZWNrIHRvIG1pbmltaXplIGNvbnRlbnRpb24KKyAgICAgICAgICAgIHNsb3QuY29tcGFyZUFuZFNldChub2RlLCBudWxsKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLy8gVGhyZWUgZm9ybXMgb2Ygd2FpdGluZy4gRWFjaCBqdXN0IGRpZmZlcmVudCBlbm91Z2ggbm90IHRvIG1lcmdlCisgICAgLy8gY29kZSB3aXRoIG90aGVycy4KKworICAgIC8qKgorICAgICAqIFNwaW4td2FpdHMgZm9yIGhvbGUgZm9yIGEgbm9uLTAgc2xvdC4gIEZhaWxzIGlmIHNwaW4gZWxhcHNlcworICAgICAqIGJlZm9yZSBob2xlIGZpbGxlZC4gIERvZXMgbm90IGNoZWNrIGludGVycnVwdCwgcmVseWluZyBvbiBjaGVjaworICAgICAqIGluIHB1YmxpYyBleGNoYW5nZSBtZXRob2QgdG8gYWJvcnQgaWYgaW50ZXJydXB0ZWQgb24gZW50cnkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbm9kZSB0aGUgd2FpdGluZyBub2RlCisgICAgICogQHJldHVybiBvbiBzdWNjZXNzLCB0aGUgaG9sZTsgb24gZmFpbHVyZSwgQ0FOQ0VMCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgT2JqZWN0IHNwaW5XYWl0KE5vZGUgbm9kZSwgU2xvdCBzbG90KSB7CisgICAgICAgIGludCBzcGlucyA9IFNQSU5TOworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBPYmplY3QgdiA9IG5vZGUuZ2V0KCk7CisgICAgICAgICAgICBpZiAodiAhPSBudWxsKQorICAgICAgICAgICAgICAgIHJldHVybiB2OworICAgICAgICAgICAgZWxzZSBpZiAoc3BpbnMgPiAwKQorICAgICAgICAgICAgICAgIC0tc3BpbnM7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgdHJ5Q2FuY2VsKG5vZGUsIHNsb3QpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV2FpdHMgZm9yIChieSBzcGlubmluZyBhbmQvb3IgYmxvY2tpbmcpIGFuZCBnZXRzIHRoZSBob2xlCisgICAgICogZmlsbGVkIGluIGJ5IGFub3RoZXIgdGhyZWFkLiAgRmFpbHMgaWYgaW50ZXJydXB0ZWQgYmVmb3JlCisgICAgICogaG9sZSBmaWxsZWQuCisgICAgICoKKyAgICAgKiBXaGVuIGEgbm9kZS90aHJlYWQgaXMgYWJvdXQgdG8gYmxvY2ssIGl0IHNldHMgaXRzIHdhaXRlciBmaWVsZAorICAgICAqIGFuZCB0aGVuIHJlY2hlY2tzIHN0YXRlIGF0IGxlYXN0IG9uZSBtb3JlIHRpbWUgYmVmb3JlIGFjdHVhbGx5CisgICAgICogcGFya2luZywgdGh1cyBjb3ZlcmluZyByYWNlIHZzIGZ1bGZpbGxlciBub3RpY2luZyB0aGF0IHdhaXRlcgorICAgICAqIGlzIG5vbi1udWxsIHNvIHNob3VsZCBiZSB3b2tlbi4KKyAgICAgKgorICAgICAqIFRocmVhZCBpbnRlcnJ1cHRpb24gc3RhdHVzIGlzIGNoZWNrZWQgb25seSBzdXJyb3VuZGluZyBjYWxscyB0bworICAgICAqIHBhcmsuICBUaGUgY2FsbGVyIGlzIGFzc3VtZWQgdG8gaGF2ZSBjaGVja2VkIGludGVycnVwdCBzdGF0dXMKKyAgICAgKiBvbiBlbnRyeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBub2RlIHRoZSB3YWl0aW5nIG5vZGUKKyAgICAgKiBAcmV0dXJuIG9uIHN1Y2Nlc3MsIHRoZSBob2xlOyBvbiBmYWlsdXJlLCBDQU5DRUwKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBPYmplY3QgYXdhaXQoTm9kZSBub2RlLCBTbG90IHNsb3QpIHsKKyAgICAgICAgVGhyZWFkIHcgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICBpbnQgc3BpbnMgPSBTUElOUzsKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgT2JqZWN0IHYgPSBub2RlLmdldCgpOworICAgICAgICAgICAgaWYgKHYgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICByZXR1cm4gdjsKKyAgICAgICAgICAgIGVsc2UgaWYgKHNwaW5zID4gMCkgICAgICAgICAgICAgICAgIC8vIFNwaW4td2FpdCBwaGFzZQorICAgICAgICAgICAgICAgIC0tc3BpbnM7CisgICAgICAgICAgICBlbHNlIGlmIChub2RlLndhaXRlciA9PSBudWxsKSAgICAgICAvLyBTZXQgdXAgdG8gYmxvY2sgbmV4dAorICAgICAgICAgICAgICAgIG5vZGUud2FpdGVyID0gdzsKKyAgICAgICAgICAgIGVsc2UgaWYgKHcuaXNJbnRlcnJ1cHRlZCgpKSAgICAgICAgIC8vIEFib3J0IG9uIGludGVycnVwdAorICAgICAgICAgICAgICAgIHRyeUNhbmNlbChub2RlLCBzbG90KTsKKyAgICAgICAgICAgIGVsc2UgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJsb2NrCisgICAgICAgICAgICAgICAgTG9ja1N1cHBvcnQucGFyayhub2RlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdhaXRzIGZvciAoYXQgaW5kZXggMCkgYW5kIGdldHMgdGhlIGhvbGUgZmlsbGVkIGluIGJ5IGFub3RoZXIKKyAgICAgKiB0aHJlYWQuICBGYWlscyBpZiB0aW1lZCBvdXQgb3IgaW50ZXJydXB0ZWQgYmVmb3JlIGhvbGUgZmlsbGVkLgorICAgICAqIFNhbWUgYmFzaWMgbG9naWMgYXMgdW50aW1lZCB2ZXJzaW9uLCBidXQgYSBiaXQgbWVzc2llci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBub2RlIHRoZSB3YWl0aW5nIG5vZGUKKyAgICAgKiBAcGFyYW0gbmFub3MgdGhlIHdhaXQgdGltZQorICAgICAqIEByZXR1cm4gb24gc3VjY2VzcywgdGhlIGhvbGU7IG9uIGZhaWx1cmUsIENBTkNFTAorICAgICAqLworICAgIHByaXZhdGUgT2JqZWN0IGF3YWl0TmFub3MoTm9kZSBub2RlLCBTbG90IHNsb3QsIGxvbmcgbmFub3MpIHsKKyAgICAgICAgaW50IHNwaW5zID0gVElNRURfU1BJTlM7CisgICAgICAgIGxvbmcgbGFzdFRpbWUgPSAwOworICAgICAgICBUaHJlYWQgdyA9IG51bGw7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIE9iamVjdCB2ID0gbm9kZS5nZXQoKTsKKyAgICAgICAgICAgIGlmICh2ICE9IG51bGwpCisgICAgICAgICAgICAgICAgcmV0dXJuIHY7CisgICAgICAgICAgICBsb25nIG5vdyA9IFN5c3RlbS5uYW5vVGltZSgpOworICAgICAgICAgICAgaWYgKHcgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB3ID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBuYW5vcyAtPSBub3cgLSBsYXN0VGltZTsKKyAgICAgICAgICAgIGxhc3RUaW1lID0gbm93OworICAgICAgICAgICAgaWYgKG5hbm9zID4gMCkgeworICAgICAgICAgICAgICAgIGlmIChzcGlucyA+IDApCisgICAgICAgICAgICAgICAgICAgIC0tc3BpbnM7CisgICAgICAgICAgICAgICAgZWxzZSBpZiAobm9kZS53YWl0ZXIgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgbm9kZS53YWl0ZXIgPSB3OworICAgICAgICAgICAgICAgIGVsc2UgaWYgKHcuaXNJbnRlcnJ1cHRlZCgpKQorICAgICAgICAgICAgICAgICAgICB0cnlDYW5jZWwobm9kZSwgc2xvdCk7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBMb2NrU3VwcG9ydC5wYXJrTmFub3Mobm9kZSwgbmFub3MpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSBpZiAodHJ5Q2FuY2VsKG5vZGUsIHNsb3QpICYmICF3LmlzSW50ZXJydXB0ZWQoKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gc2Nhbk9uVGltZW91dChub2RlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFN3ZWVwcyB0aHJvdWdoIGFyZW5hIGNoZWNraW5nIGZvciBhbnkgd2FpdGluZyB0aHJlYWRzLiAgQ2FsbGVkCisgICAgICogb25seSB1cG9uIHJldHVybiBmcm9tIHRpbWVvdXQgd2hpbGUgd2FpdGluZyBpbiBzbG90IDAuICBXaGVuIGEKKyAgICAgKiB0aHJlYWQgZ2l2ZXMgdXAgb24gYSB0aW1lZCB3YWl0LCBpdCBpcyBwb3NzaWJsZSB0aGF0IGEKKyAgICAgKiBwcmV2aW91c2x5LWVudGVyZWQgdGhyZWFkIGlzIHN0aWxsIHdhaXRpbmcgaW4gc29tZSBvdGhlcgorICAgICAqIHNsb3QuICBTbyB3ZSBzY2FuIHRvIGNoZWNrIGZvciBhbnkuICBUaGlzIGlzIGFsbW9zdCBhbHdheXMKKyAgICAgKiBvdmVya2lsbCwgYnV0IGRlY3JlYXNlcyB0aGUgbGlrZWxpaG9vZCBvZiB0aW1lb3V0cyB3aGVuIHRoZXJlCisgICAgICogYXJlIG90aGVyIHRocmVhZHMgcHJlc2VudCB0byBmYXIgbGVzcyB0aGFuIHRoYXQgaW4gbG9jay1iYXNlZAorICAgICAqIGV4Y2hhbmdlcnMgaW4gd2hpY2ggZWFybGllci1hcnJpdmluZyB0aHJlYWRzIG1heSBzdGlsbCBiZQorICAgICAqIHdhaXRpbmcgb24gZW50cnkgbG9ja3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbm9kZSB0aGUgd2FpdGluZyBub2RlCisgICAgICogQHJldHVybiBhbm90aGVyIHRocmVhZCdzIGl0ZW0sIG9yIENBTkNFTAorICAgICAqLworICAgIHByaXZhdGUgT2JqZWN0IHNjYW5PblRpbWVvdXQoTm9kZSBub2RlKSB7CisgICAgICAgIE9iamVjdCB5OworICAgICAgICBmb3IgKGludCBqID0gYXJlbmEubGVuZ3RoIC0gMTsgaiA+PSAwOyAtLWopIHsKKyAgICAgICAgICAgIFNsb3Qgc2xvdCA9IGFyZW5hW2pdOworICAgICAgICAgICAgaWYgKHNsb3QgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHdoaWxlICgoeSA9IHNsb3QuZ2V0KCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNsb3QuY29tcGFyZUFuZFNldCh5LCBudWxsKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSB5b3UgPSAoTm9kZSl5OworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHlvdS5jb21wYXJlQW5kU2V0KG51bGwsIG5vZGUuaXRlbSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2NrU3VwcG9ydC51bnBhcmsoeW91LndhaXRlcik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHlvdS5pdGVtOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBDQU5DRUw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBFeGNoYW5nZXIuCisgICAgICovCisgICAgcHVibGljIEV4Y2hhbmdlcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXYWl0cyBmb3IgYW5vdGhlciB0aHJlYWQgdG8gYXJyaXZlIGF0IHRoaXMgZXhjaGFuZ2UgcG9pbnQgKHVubGVzcworICAgICAqIHRoZSBjdXJyZW50IHRocmVhZCBpcyB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfSksCisgICAgICogYW5kIHRoZW4gdHJhbnNmZXJzIHRoZSBnaXZlbiBvYmplY3QgdG8gaXQsIHJlY2VpdmluZyBpdHMgb2JqZWN0CisgICAgICogaW4gcmV0dXJuLgorICAgICAqCisgICAgICogPHA+SWYgYW5vdGhlciB0aHJlYWQgaXMgYWxyZWFkeSB3YWl0aW5nIGF0IHRoZSBleGNoYW5nZSBwb2ludCB0aGVuCisgICAgICogaXQgaXMgcmVzdW1lZCBmb3IgdGhyZWFkIHNjaGVkdWxpbmcgcHVycG9zZXMgYW5kIHJlY2VpdmVzIHRoZSBvYmplY3QKKyAgICAgKiBwYXNzZWQgaW4gYnkgdGhlIGN1cnJlbnQgdGhyZWFkLiAgVGhlIGN1cnJlbnQgdGhyZWFkIHJldHVybnMgaW1tZWRpYXRlbHksCisgICAgICogcmVjZWl2aW5nIHRoZSBvYmplY3QgcGFzc2VkIHRvIHRoZSBleGNoYW5nZSBieSB0aGF0IG90aGVyIHRocmVhZC4KKyAgICAgKgorICAgICAqIDxwPklmIG5vIG90aGVyIHRocmVhZCBpcyBhbHJlYWR5IHdhaXRpbmcgYXQgdGhlIGV4Y2hhbmdlIHRoZW4gdGhlCisgICAgICogY3VycmVudCB0aHJlYWQgaXMgZGlzYWJsZWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nIHB1cnBvc2VzIGFuZCBsaWVzCisgICAgICogZG9ybWFudCB1bnRpbCBvbmUgb2YgdHdvIHRoaW5ncyBoYXBwZW5zOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQgZW50ZXJzIHRoZSBleGNoYW5nZTsgb3IKKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRzfQorICAgICAqIHRoZSBjdXJyZW50IHRocmVhZC4KKyAgICAgKiA8L3VsPgorICAgICAqIDxwPklmIHRoZSBjdXJyZW50IHRocmVhZDoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPmhhcyBpdHMgaW50ZXJydXB0ZWQgc3RhdHVzIHNldCBvbiBlbnRyeSB0byB0aGlzIG1ldGhvZDsgb3IKKyAgICAgKiA8bGk+aXMge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRlZH0gd2hpbGUgd2FpdGluZworICAgICAqIGZvciB0aGUgZXhjaGFuZ2UsCisgICAgICogPC91bD4KKyAgICAgKiB0aGVuIHtAbGluayBJbnRlcnJ1cHRlZEV4Y2VwdGlvbn0gaXMgdGhyb3duIGFuZCB0aGUgY3VycmVudCB0aHJlYWQncworICAgICAqIGludGVycnVwdGVkIHN0YXR1cyBpcyBjbGVhcmVkLgorICAgICAqCisgICAgICogQHBhcmFtIHggdGhlIG9iamVjdCB0byBleGNoYW5nZQorICAgICAqIEByZXR1cm4gdGhlIG9iamVjdCBwcm92aWRlZCBieSB0aGUgb3RoZXIgdGhyZWFkCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCB0aHJlYWQgd2FzCisgICAgICogICAgICAgICBpbnRlcnJ1cHRlZCB3aGlsZSB3YWl0aW5nCisgICAgICovCisgICAgcHVibGljIFYgZXhjaGFuZ2UoViB4KSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBpZiAoIVRocmVhZC5pbnRlcnJ1cHRlZCgpKSB7CisgICAgICAgICAgICBPYmplY3QgdiA9IGRvRXhjaGFuZ2UoKHggPT0gbnVsbCkgPyBOVUxMX0lURU0gOiB4LCBmYWxzZSwgMCk7CisgICAgICAgICAgICBpZiAodiA9PSBOVUxMX0lURU0pCisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICBpZiAodiAhPSBDQU5DRUwpCisgICAgICAgICAgICAgICAgcmV0dXJuIChWKXY7CisgICAgICAgICAgICBUaHJlYWQuaW50ZXJydXB0ZWQoKTsgLy8gQ2xlYXIgaW50ZXJydXB0IHN0YXR1cyBvbiBJRSB0aHJvdworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdhaXRzIGZvciBhbm90aGVyIHRocmVhZCB0byBhcnJpdmUgYXQgdGhpcyBleGNoYW5nZSBwb2ludCAodW5sZXNzCisgICAgICogdGhlIGN1cnJlbnQgdGhyZWFkIGlzIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0ZWR9IG9yCisgICAgICogdGhlIHNwZWNpZmllZCB3YWl0aW5nIHRpbWUgZWxhcHNlcyksIGFuZCB0aGVuIHRyYW5zZmVycyB0aGUgZ2l2ZW4KKyAgICAgKiBvYmplY3QgdG8gaXQsIHJlY2VpdmluZyBpdHMgb2JqZWN0IGluIHJldHVybi4KKyAgICAgKgorICAgICAqIDxwPklmIGFub3RoZXIgdGhyZWFkIGlzIGFscmVhZHkgd2FpdGluZyBhdCB0aGUgZXhjaGFuZ2UgcG9pbnQgdGhlbgorICAgICAqIGl0IGlzIHJlc3VtZWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nIHB1cnBvc2VzIGFuZCByZWNlaXZlcyB0aGUgb2JqZWN0CisgICAgICogcGFzc2VkIGluIGJ5IHRoZSBjdXJyZW50IHRocmVhZC4gIFRoZSBjdXJyZW50IHRocmVhZCByZXR1cm5zIGltbWVkaWF0ZWx5LAorICAgICAqIHJlY2VpdmluZyB0aGUgb2JqZWN0IHBhc3NlZCB0byB0aGUgZXhjaGFuZ2UgYnkgdGhhdCBvdGhlciB0aHJlYWQuCisgICAgICoKKyAgICAgKiA8cD5JZiBubyBvdGhlciB0aHJlYWQgaXMgYWxyZWFkeSB3YWl0aW5nIGF0IHRoZSBleGNoYW5nZSB0aGVuIHRoZQorICAgICAqIGN1cnJlbnQgdGhyZWFkIGlzIGRpc2FibGVkIGZvciB0aHJlYWQgc2NoZWR1bGluZyBwdXJwb3NlcyBhbmQgbGllcworICAgICAqIGRvcm1hbnQgdW50aWwgb25lIG9mIHRocmVlIHRoaW5ncyBoYXBwZW5zOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQgZW50ZXJzIHRoZSBleGNoYW5nZTsgb3IKKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRzfQorICAgICAqIHRoZSBjdXJyZW50IHRocmVhZDsgb3IKKyAgICAgKiA8bGk+VGhlIHNwZWNpZmllZCB3YWl0aW5nIHRpbWUgZWxhcHNlcy4KKyAgICAgKiA8L3VsPgorICAgICAqIDxwPklmIHRoZSBjdXJyZW50IHRocmVhZDoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPmhhcyBpdHMgaW50ZXJydXB0ZWQgc3RhdHVzIHNldCBvbiBlbnRyeSB0byB0aGlzIG1ldGhvZDsgb3IKKyAgICAgKiA8bGk+aXMge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRlZH0gd2hpbGUgd2FpdGluZworICAgICAqIGZvciB0aGUgZXhjaGFuZ2UsCisgICAgICogPC91bD4KKyAgICAgKiB0aGVuIHtAbGluayBJbnRlcnJ1cHRlZEV4Y2VwdGlvbn0gaXMgdGhyb3duIGFuZCB0aGUgY3VycmVudCB0aHJlYWQncworICAgICAqIGludGVycnVwdGVkIHN0YXR1cyBpcyBjbGVhcmVkLgorICAgICAqCisgICAgICogPHA+SWYgdGhlIHNwZWNpZmllZCB3YWl0aW5nIHRpbWUgZWxhcHNlcyB0aGVuIHtAbGluaworICAgICAqIFRpbWVvdXRFeGNlcHRpb259IGlzIHRocm93bi4gIElmIHRoZSB0aW1lIGlzIGxlc3MgdGhhbiBvciBlcXVhbAorICAgICAqIHRvIHplcm8sIHRoZSBtZXRob2Qgd2lsbCBub3Qgd2FpdCBhdCBhbGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0geCB0aGUgb2JqZWN0IHRvIGV4Y2hhbmdlCisgICAgICogQHBhcmFtIHRpbWVvdXQgdGhlIG1heGltdW0gdGltZSB0byB3YWl0CisgICAgICogQHBhcmFtIHVuaXQgdGhlIHRpbWUgdW5pdCBvZiB0aGUgPHR0PnRpbWVvdXQ8L3R0PiBhcmd1bWVudAorICAgICAqIEByZXR1cm4gdGhlIG9iamVjdCBwcm92aWRlZCBieSB0aGUgb3RoZXIgdGhyZWFkCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCB0aHJlYWQgd2FzCisgICAgICogICAgICAgICBpbnRlcnJ1cHRlZCB3aGlsZSB3YWl0aW5nCisgICAgICogQHRocm93cyBUaW1lb3V0RXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgd2FpdGluZyB0aW1lIGVsYXBzZXMKKyAgICAgKiAgICAgICAgIGJlZm9yZSBhbm90aGVyIHRocmVhZCBlbnRlcnMgdGhlIGV4Y2hhbmdlCisgICAgICovCisgICAgcHVibGljIFYgZXhjaGFuZ2UoViB4LCBsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgVGltZW91dEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghVGhyZWFkLmludGVycnVwdGVkKCkpIHsKKyAgICAgICAgICAgIE9iamVjdCB2ID0gZG9FeGNoYW5nZSgoeCA9PSBudWxsKSA/IE5VTExfSVRFTSA6IHgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgdW5pdC50b05hbm9zKHRpbWVvdXQpKTsKKyAgICAgICAgICAgIGlmICh2ID09IE5VTExfSVRFTSkKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIGlmICh2ICE9IENBTkNFTCkKKyAgICAgICAgICAgICAgICByZXR1cm4gKFYpdjsKKyAgICAgICAgICAgIGlmICghVGhyZWFkLmludGVycnVwdGVkKCkpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRpbWVvdXRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgSW50ZXJydXB0ZWRFeGNlcHRpb24oKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvRXhlY3V0aW9uRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvRXhlY3V0aW9uRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmM1NjFlNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9FeGVjdXRpb25FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDY1IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CisKKy8qKgorICogRXhjZXB0aW9uIHRocm93biB3aGVuIGF0dGVtcHRpbmcgdG8gcmV0cmlldmUgdGhlIHJlc3VsdCBvZiBhIHRhc2sKKyAqIHRoYXQgYWJvcnRlZCBieSB0aHJvd2luZyBhbiBleGNlcHRpb24uIFRoaXMgZXhjZXB0aW9uIGNhbiBiZQorICogaW5zcGVjdGVkIHVzaW5nIHRoZSB7QGxpbmsgI2dldENhdXNlKCl9IG1ldGhvZC4KKyAqCisgKiBAc2VlIEZ1dHVyZQorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICovCitwdWJsaWMgY2xhc3MgRXhlY3V0aW9uRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3ODMwMjY2MDEyODMyNjg2MTg1TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gPHR0PkV4ZWN1dGlvbkV4Y2VwdGlvbjwvdHQ+IHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UuCisgICAgICogVGhlIGNhdXNlIGlzIG5vdCBpbml0aWFsaXplZCwgYW5kIG1heSBzdWJzZXF1ZW50bHkgYmUKKyAgICAgKiBpbml0aWFsaXplZCBieSBhIGNhbGwgdG8ge0BsaW5rICNpbml0Q2F1c2UoVGhyb3dhYmxlKSBpbml0Q2F1c2V9LgorICAgICAqLworICAgIHByb3RlY3RlZCBFeGVjdXRpb25FeGNlcHRpb24oKSB7IH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gPHR0PkV4ZWN1dGlvbkV4Y2VwdGlvbjwvdHQ+IHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwKKyAgICAgKiBtZXNzYWdlLiBUaGUgY2F1c2UgaXMgbm90IGluaXRpYWxpemVkLCBhbmQgbWF5IHN1YnNlcXVlbnRseSBiZQorICAgICAqIGluaXRpYWxpemVkIGJ5IGEgY2FsbCB0byB7QGxpbmsgI2luaXRDYXVzZShUaHJvd2FibGUpIGluaXRDYXVzZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZSB0aGUgZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRXhlY3V0aW9uRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gPHR0PkV4ZWN1dGlvbkV4Y2VwdGlvbjwvdHQ+IHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwKKyAgICAgKiBtZXNzYWdlIGFuZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgbWVzc2FnZSB0aGUgZGV0YWlsIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gIGNhdXNlIHRoZSBjYXVzZSAod2hpY2ggaXMgc2F2ZWQgZm9yIGxhdGVyIHJldHJpZXZhbCBieSB0aGUKKyAgICAgKiAgICAgICAgIHtAbGluayAjZ2V0Q2F1c2UoKX0gbWV0aG9kKQorICAgICAqLworICAgIHB1YmxpYyBFeGVjdXRpb25FeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlLCBjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiA8dHQ+RXhlY3V0aW9uRXhjZXB0aW9uPC90dD4gd2l0aCB0aGUgc3BlY2lmaWVkIGNhdXNlLgorICAgICAqIFRoZSBkZXRhaWwgbWVzc2FnZSBpcyBzZXQgdG86CisgICAgICogPHByZT4KKyAgICAgKiAgKGNhdXNlID09IG51bGwgPyBudWxsIDogY2F1c2UudG9TdHJpbmcoKSk8L3ByZT4KKyAgICAgKiAod2hpY2ggdHlwaWNhbGx5IGNvbnRhaW5zIHRoZSBjbGFzcyBhbmQgZGV0YWlsIG1lc3NhZ2Ugb2YKKyAgICAgKiA8dHQ+Y2F1c2U8L3R0PikuCisgICAgICoKKyAgICAgKiBAcGFyYW0gIGNhdXNlIHRoZSBjYXVzZSAod2hpY2ggaXMgc2F2ZWQgZm9yIGxhdGVyIHJldHJpZXZhbCBieSB0aGUKKyAgICAgKiAgICAgICAgIHtAbGluayAjZ2V0Q2F1c2UoKX0gbWV0aG9kKQorICAgICAqLworICAgIHB1YmxpYyBFeGVjdXRpb25FeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvRXhlY3V0b3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9FeGVjdXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZiYzRlNmYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvRXhlY3V0b3IuamF2YQpAQCAtMCwwICsxLDExMiBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50OworCisvKioKKyAqIEFuIG9iamVjdCB0aGF0IGV4ZWN1dGVzIHN1Ym1pdHRlZCB7QGxpbmsgUnVubmFibGV9IHRhc2tzLiBUaGlzCisgKiBpbnRlcmZhY2UgcHJvdmlkZXMgYSB3YXkgb2YgZGVjb3VwbGluZyB0YXNrIHN1Ym1pc3Npb24gZnJvbSB0aGUKKyAqIG1lY2hhbmljcyBvZiBob3cgZWFjaCB0YXNrIHdpbGwgYmUgcnVuLCBpbmNsdWRpbmcgZGV0YWlscyBvZiB0aHJlYWQKKyAqIHVzZSwgc2NoZWR1bGluZywgZXRjLiAgQW4gPHR0PkV4ZWN1dG9yPC90dD4gaXMgbm9ybWFsbHkgdXNlZAorICogaW5zdGVhZCBvZiBleHBsaWNpdGx5IGNyZWF0aW5nIHRocmVhZHMuIEZvciBleGFtcGxlLCByYXRoZXIgdGhhbgorICogaW52b2tpbmcgPHR0Pm5ldyBUaHJlYWQobmV3KFJ1bm5hYmxlVGFzaygpKSkuc3RhcnQoKTwvdHQ+IGZvciBlYWNoCisgKiBvZiBhIHNldCBvZiB0YXNrcywgeW91IG1pZ2h0IHVzZToKKyAqCisgKiA8cHJlPgorICogRXhlY3V0b3IgZXhlY3V0b3IgPSA8ZW0+YW5FeGVjdXRvcjwvZW0+OworICogZXhlY3V0b3IuZXhlY3V0ZShuZXcgUnVubmFibGVUYXNrMSgpKTsKKyAqIGV4ZWN1dG9yLmV4ZWN1dGUobmV3IFJ1bm5hYmxlVGFzazIoKSk7CisgKiAuLi4KKyAqIDwvcHJlPgorICoKKyAqIEhvd2V2ZXIsIHRoZSA8dHQ+RXhlY3V0b3I8L3R0PiBpbnRlcmZhY2UgZG9lcyBub3Qgc3RyaWN0bHkKKyAqIHJlcXVpcmUgdGhhdCBleGVjdXRpb24gYmUgYXN5bmNocm9ub3VzLiBJbiB0aGUgc2ltcGxlc3QgY2FzZSwgYW4KKyAqIGV4ZWN1dG9yIGNhbiBydW4gdGhlIHN1Ym1pdHRlZCB0YXNrIGltbWVkaWF0ZWx5IGluIHRoZSBjYWxsZXIncworICogdGhyZWFkOgorICoKKyAqIDxwcmU+CisgKiBjbGFzcyBEaXJlY3RFeGVjdXRvciBpbXBsZW1lbnRzIEV4ZWN1dG9yIHsKKyAqICAgICBwdWJsaWMgdm9pZCBleGVjdXRlKFJ1bm5hYmxlIHIpIHsKKyAqICAgICAgICAgci5ydW4oKTsKKyAqICAgICB9CisgKiB9PC9wcmU+CisgKgorICogTW9yZSB0eXBpY2FsbHksIHRhc2tzIGFyZSBleGVjdXRlZCBpbiBzb21lIHRocmVhZCBvdGhlcgorICogdGhhbiB0aGUgY2FsbGVyJ3MgdGhyZWFkLiAgVGhlIGV4ZWN1dG9yIGJlbG93IHNwYXducyBhIG5ldyB0aHJlYWQKKyAqIGZvciBlYWNoIHRhc2suCisgKgorICogPHByZT4KKyAqIGNsYXNzIFRocmVhZFBlclRhc2tFeGVjdXRvciBpbXBsZW1lbnRzIEV4ZWN1dG9yIHsKKyAqICAgICBwdWJsaWMgdm9pZCBleGVjdXRlKFJ1bm5hYmxlIHIpIHsKKyAqICAgICAgICAgbmV3IFRocmVhZChyKS5zdGFydCgpOworICogICAgIH0KKyAqIH08L3ByZT4KKyAqCisgKiBNYW55IDx0dD5FeGVjdXRvcjwvdHQ+IGltcGxlbWVudGF0aW9ucyBpbXBvc2Ugc29tZSBzb3J0IG9mCisgKiBsaW1pdGF0aW9uIG9uIGhvdyBhbmQgd2hlbiB0YXNrcyBhcmUgc2NoZWR1bGVkLiAgVGhlIGV4ZWN1dG9yIGJlbG93CisgKiBzZXJpYWxpemVzIHRoZSBzdWJtaXNzaW9uIG9mIHRhc2tzIHRvIGEgc2Vjb25kIGV4ZWN1dG9yLAorICogaWxsdXN0cmF0aW5nIGEgY29tcG9zaXRlIGV4ZWN1dG9yLgorICoKKyAqICA8cHJlPiB7QGNvZGUKKyAqIGNsYXNzIFNlcmlhbEV4ZWN1dG9yIGltcGxlbWVudHMgRXhlY3V0b3IgeworICogICBmaW5hbCBRdWV1ZTxSdW5uYWJsZT4gdGFza3MgPSBuZXcgQXJyYXlEZXF1ZTxSdW5uYWJsZT4oKTsKKyAqICAgZmluYWwgRXhlY3V0b3IgZXhlY3V0b3I7CisgKiAgIFJ1bm5hYmxlIGFjdGl2ZTsKKyAqCisgKiAgIFNlcmlhbEV4ZWN1dG9yKEV4ZWN1dG9yIGV4ZWN1dG9yKSB7CisgKiAgICAgdGhpcy5leGVjdXRvciA9IGV4ZWN1dG9yOworICogICB9CisgKgorICogICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgZXhlY3V0ZShmaW5hbCBSdW5uYWJsZSByKSB7CisgKiAgICAgdGFza3Mub2ZmZXIobmV3IFJ1bm5hYmxlKCkgeworICogICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICogICAgICAgICB0cnkgeworICogICAgICAgICAgIHIucnVuKCk7CisgKiAgICAgICAgIH0gZmluYWxseSB7CisgKiAgICAgICAgICAgc2NoZWR1bGVOZXh0KCk7CisgKiAgICAgICAgIH0KKyAqICAgICAgIH0KKyAqICAgICB9KTsKKyAqICAgICBpZiAoYWN0aXZlID09IG51bGwpIHsKKyAqICAgICAgIHNjaGVkdWxlTmV4dCgpOworICogICAgIH0KKyAqICAgfQorICoKKyAqICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIHNjaGVkdWxlTmV4dCgpIHsKKyAqICAgICBpZiAoKGFjdGl2ZSA9IHRhc2tzLnBvbGwoKSkgIT0gbnVsbCkgeworICogICAgICAgZXhlY3V0b3IuZXhlY3V0ZShhY3RpdmUpOworICogICAgIH0KKyAqICAgfQorICogfX08L3ByZT4KKyAqCisgKiBUaGUgPHR0PkV4ZWN1dG9yPC90dD4gaW1wbGVtZW50YXRpb25zIHByb3ZpZGVkIGluIHRoaXMgcGFja2FnZQorICogaW1wbGVtZW50IHtAbGluayBFeGVjdXRvclNlcnZpY2V9LCB3aGljaCBpcyBhIG1vcmUgZXh0ZW5zaXZlCisgKiBpbnRlcmZhY2UuICBUaGUge0BsaW5rIFRocmVhZFBvb2xFeGVjdXRvcn0gY2xhc3MgcHJvdmlkZXMgYW4KKyAqIGV4dGVuc2libGUgdGhyZWFkIHBvb2wgaW1wbGVtZW50YXRpb24uIFRoZSB7QGxpbmsgRXhlY3V0b3JzfSBjbGFzcworICogcHJvdmlkZXMgY29udmVuaWVudCBmYWN0b3J5IG1ldGhvZHMgZm9yIHRoZXNlIEV4ZWN1dG9ycy4KKyAqCisgKiA8cD5NZW1vcnkgY29uc2lzdGVuY3kgZWZmZWN0czogQWN0aW9ucyBpbiBhIHRocmVhZCBwcmlvciB0bworICogc3VibWl0dGluZyBhIHtAY29kZSBSdW5uYWJsZX0gb2JqZWN0IHRvIGFuIHtAY29kZSBFeGVjdXRvcn0KKyAqIDxhIGhyZWY9InBhY2thZ2Utc3VtbWFyeS5odG1sI01lbW9yeVZpc2liaWxpdHkiPjxpPmhhcHBlbi1iZWZvcmU8L2k+PC9hPgorICogaXRzIGV4ZWN1dGlvbiBiZWdpbnMsIHBlcmhhcHMgaW4gYW5vdGhlciB0aHJlYWQuCisgKgorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICovCitwdWJsaWMgaW50ZXJmYWNlIEV4ZWN1dG9yIHsKKworICAgIC8qKgorICAgICAqIEV4ZWN1dGVzIHRoZSBnaXZlbiBjb21tYW5kIGF0IHNvbWUgdGltZSBpbiB0aGUgZnV0dXJlLiAgVGhlIGNvbW1hbmQKKyAgICAgKiBtYXkgZXhlY3V0ZSBpbiBhIG5ldyB0aHJlYWQsIGluIGEgcG9vbGVkIHRocmVhZCwgb3IgaW4gdGhlIGNhbGxpbmcKKyAgICAgKiB0aHJlYWQsIGF0IHRoZSBkaXNjcmV0aW9uIG9mIHRoZSA8dHQ+RXhlY3V0b3I8L3R0PiBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb21tYW5kIHRoZSBydW5uYWJsZSB0YXNrCisgICAgICogQHRocm93cyBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbiBpZiB0aGlzIHRhc2sgY2Fubm90IGJlCisgICAgICogYWNjZXB0ZWQgZm9yIGV4ZWN1dGlvbi4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGNvbW1hbmQgaXMgbnVsbAorICAgICAqLworICAgIHZvaWQgZXhlY3V0ZShSdW5uYWJsZSBjb21tYW5kKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9FeGVjdXRvckNvbXBsZXRpb25TZXJ2aWNlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvRXhlY3V0b3JDb21wbGV0aW9uU2VydmljZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI0MTk1NWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvRXhlY3V0b3JDb21wbGV0aW9uU2VydmljZS5qYXZhCkBAIC0wLDAgKzEsMTc2IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CisKKy8qKgorICogQSB7QGxpbmsgQ29tcGxldGlvblNlcnZpY2V9IHRoYXQgdXNlcyBhIHN1cHBsaWVkIHtAbGluayBFeGVjdXRvcn0KKyAqIHRvIGV4ZWN1dGUgdGFza3MuICBUaGlzIGNsYXNzIGFycmFuZ2VzIHRoYXQgc3VibWl0dGVkIHRhc2tzIGFyZSwKKyAqIHVwb24gY29tcGxldGlvbiwgcGxhY2VkIG9uIGEgcXVldWUgYWNjZXNzaWJsZSB1c2luZyB7QGNvZGUgdGFrZX0uCisgKiBUaGUgY2xhc3MgaXMgbGlnaHR3ZWlnaHQgZW5vdWdoIHRvIGJlIHN1aXRhYmxlIGZvciB0cmFuc2llbnQgdXNlCisgKiB3aGVuIHByb2Nlc3NpbmcgZ3JvdXBzIG9mIHRhc2tzLgorICoKKyAqIDxwPgorICoKKyAqIDxiPlVzYWdlIEV4YW1wbGVzLjwvYj4KKyAqCisgKiBTdXBwb3NlIHlvdSBoYXZlIGEgc2V0IG9mIHNvbHZlcnMgZm9yIGEgY2VydGFpbiBwcm9ibGVtLCBlYWNoCisgKiByZXR1cm5pbmcgYSB2YWx1ZSBvZiBzb21lIHR5cGUge0Bjb2RlIFJlc3VsdH0sIGFuZCB3b3VsZCBsaWtlIHRvCisgKiBydW4gdGhlbSBjb25jdXJyZW50bHksIHByb2Nlc3NpbmcgdGhlIHJlc3VsdHMgb2YgZWFjaCBvZiB0aGVtIHRoYXQKKyAqIHJldHVybiBhIG5vbi1udWxsIHZhbHVlLCBpbiBzb21lIG1ldGhvZCB7QGNvZGUgdXNlKFJlc3VsdCByKX0uIFlvdQorICogY291bGQgd3JpdGUgdGhpcyBhczoKKyAqCisgKiA8cHJlPiB7QGNvZGUKKyAqIHZvaWQgc29sdmUoRXhlY3V0b3IgZSwKKyAqICAgICAgICAgICAgQ29sbGVjdGlvbjxDYWxsYWJsZTxSZXN1bHQ+PiBzb2x2ZXJzKQorICogICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uIHsKKyAqICAgICBDb21wbGV0aW9uU2VydmljZTxSZXN1bHQ+IGVjcworICogICAgICAgICA9IG5ldyBFeGVjdXRvckNvbXBsZXRpb25TZXJ2aWNlPFJlc3VsdD4oZSk7CisgKiAgICAgZm9yIChDYWxsYWJsZTxSZXN1bHQ+IHMgOiBzb2x2ZXJzKQorICogICAgICAgICBlY3Muc3VibWl0KHMpOworICogICAgIGludCBuID0gc29sdmVycy5zaXplKCk7CisgKiAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyArK2kpIHsKKyAqICAgICAgICAgUmVzdWx0IHIgPSBlY3MudGFrZSgpLmdldCgpOworICogICAgICAgICBpZiAociAhPSBudWxsKQorICogICAgICAgICAgICAgdXNlKHIpOworICogICAgIH0KKyAqIH19PC9wcmU+CisgKgorICogU3VwcG9zZSBpbnN0ZWFkIHRoYXQgeW91IHdvdWxkIGxpa2UgdG8gdXNlIHRoZSBmaXJzdCBub24tbnVsbCByZXN1bHQKKyAqIG9mIHRoZSBzZXQgb2YgdGFza3MsIGlnbm9yaW5nIGFueSB0aGF0IGVuY291bnRlciBleGNlcHRpb25zLAorICogYW5kIGNhbmNlbGxpbmcgYWxsIG90aGVyIHRhc2tzIHdoZW4gdGhlIGZpcnN0IG9uZSBpcyByZWFkeToKKyAqCisgKiA8cHJlPiB7QGNvZGUKKyAqIHZvaWQgc29sdmUoRXhlY3V0b3IgZSwKKyAqICAgICAgICAgICAgQ29sbGVjdGlvbjxDYWxsYWJsZTxSZXN1bHQ+PiBzb2x2ZXJzKQorICogICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgKiAgICAgQ29tcGxldGlvblNlcnZpY2U8UmVzdWx0PiBlY3MKKyAqICAgICAgICAgPSBuZXcgRXhlY3V0b3JDb21wbGV0aW9uU2VydmljZTxSZXN1bHQ+KGUpOworICogICAgIGludCBuID0gc29sdmVycy5zaXplKCk7CisgKiAgICAgTGlzdDxGdXR1cmU8UmVzdWx0Pj4gZnV0dXJlcworICogICAgICAgICA9IG5ldyBBcnJheUxpc3Q8RnV0dXJlPFJlc3VsdD4+KG4pOworICogICAgIFJlc3VsdCByZXN1bHQgPSBudWxsOworICogICAgIHRyeSB7CisgKiAgICAgICAgIGZvciAoQ2FsbGFibGU8UmVzdWx0PiBzIDogc29sdmVycykKKyAqICAgICAgICAgICAgIGZ1dHVyZXMuYWRkKGVjcy5zdWJtaXQocykpOworICogICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47ICsraSkgeworICogICAgICAgICAgICAgdHJ5IHsKKyAqICAgICAgICAgICAgICAgICBSZXN1bHQgciA9IGVjcy50YWtlKCkuZ2V0KCk7CisgKiAgICAgICAgICAgICAgICAgaWYgKHIgIT0gbnVsbCkgeworICogICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByOworICogICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAqICAgICAgICAgICAgICAgICB9CisgKiAgICAgICAgICAgICB9IGNhdGNoIChFeGVjdXRpb25FeGNlcHRpb24gaWdub3JlKSB7fQorICogICAgICAgICB9CisgKiAgICAgfQorICogICAgIGZpbmFsbHkgeworICogICAgICAgICBmb3IgKEZ1dHVyZTxSZXN1bHQ+IGYgOiBmdXR1cmVzKQorICogICAgICAgICAgICAgZi5jYW5jZWwodHJ1ZSk7CisgKiAgICAgfQorICoKKyAqICAgICBpZiAocmVzdWx0ICE9IG51bGwpCisgKiAgICAgICAgIHVzZShyZXN1bHQpOworICogfX08L3ByZT4KKyAqLworcHVibGljIGNsYXNzIEV4ZWN1dG9yQ29tcGxldGlvblNlcnZpY2U8Vj4gaW1wbGVtZW50cyBDb21wbGV0aW9uU2VydmljZTxWPiB7CisgICAgcHJpdmF0ZSBmaW5hbCBFeGVjdXRvciBleGVjdXRvcjsKKyAgICBwcml2YXRlIGZpbmFsIEFic3RyYWN0RXhlY3V0b3JTZXJ2aWNlIGFlczsKKyAgICBwcml2YXRlIGZpbmFsIEJsb2NraW5nUXVldWU8RnV0dXJlPFY+PiBjb21wbGV0aW9uUXVldWU7CisKKyAgICAvKioKKyAgICAgKiBGdXR1cmVUYXNrIGV4dGVuc2lvbiB0byBlbnF1ZXVlIHVwb24gY29tcGxldGlvbgorICAgICAqLworICAgIHByaXZhdGUgY2xhc3MgUXVldWVpbmdGdXR1cmUgZXh0ZW5kcyBGdXR1cmVUYXNrPFZvaWQ+IHsKKyAgICAgICAgUXVldWVpbmdGdXR1cmUoUnVubmFibGVGdXR1cmU8Vj4gdGFzaykgeworICAgICAgICAgICAgc3VwZXIodGFzaywgbnVsbCk7CisgICAgICAgICAgICB0aGlzLnRhc2sgPSB0YXNrOworICAgICAgICB9CisgICAgICAgIHByb3RlY3RlZCB2b2lkIGRvbmUoKSB7IGNvbXBsZXRpb25RdWV1ZS5hZGQodGFzayk7IH0KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBGdXR1cmU8Vj4gdGFzazsKKyAgICB9CisKKyAgICBwcml2YXRlIFJ1bm5hYmxlRnV0dXJlPFY+IG5ld1Rhc2tGb3IoQ2FsbGFibGU8Vj4gdGFzaykgeworICAgICAgICBpZiAoYWVzID09IG51bGwpCisgICAgICAgICAgICByZXR1cm4gbmV3IEZ1dHVyZVRhc2s8Vj4odGFzayk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldHVybiBhZXMubmV3VGFza0Zvcih0YXNrKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFJ1bm5hYmxlRnV0dXJlPFY+IG5ld1Rhc2tGb3IoUnVubmFibGUgdGFzaywgViByZXN1bHQpIHsKKyAgICAgICAgaWYgKGFlcyA9PSBudWxsKQorICAgICAgICAgICAgcmV0dXJuIG5ldyBGdXR1cmVUYXNrPFY+KHRhc2ssIHJlc3VsdCk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldHVybiBhZXMubmV3VGFza0Zvcih0YXNrLCByZXN1bHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gRXhlY3V0b3JDb21wbGV0aW9uU2VydmljZSB1c2luZyB0aGUgc3VwcGxpZWQKKyAgICAgKiBleGVjdXRvciBmb3IgYmFzZSB0YXNrIGV4ZWN1dGlvbiBhbmQgYQorICAgICAqIHtAbGluayBMaW5rZWRCbG9ja2luZ1F1ZXVlfSBhcyBhIGNvbXBsZXRpb24gcXVldWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhlY3V0b3IgdGhlIGV4ZWN1dG9yIHRvIHVzZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgZXhlY3V0b3IgaXMge0Bjb2RlIG51bGx9CisgICAgICovCisgICAgcHVibGljIEV4ZWN1dG9yQ29tcGxldGlvblNlcnZpY2UoRXhlY3V0b3IgZXhlY3V0b3IpIHsKKyAgICAgICAgaWYgKGV4ZWN1dG9yID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgdGhpcy5leGVjdXRvciA9IGV4ZWN1dG9yOworICAgICAgICB0aGlzLmFlcyA9IChleGVjdXRvciBpbnN0YW5jZW9mIEFic3RyYWN0RXhlY3V0b3JTZXJ2aWNlKSA/CisgICAgICAgICAgICAoQWJzdHJhY3RFeGVjdXRvclNlcnZpY2UpIGV4ZWN1dG9yIDogbnVsbDsKKyAgICAgICAgdGhpcy5jb21wbGV0aW9uUXVldWUgPSBuZXcgTGlua2VkQmxvY2tpbmdRdWV1ZTxGdXR1cmU8Vj4+KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBFeGVjdXRvckNvbXBsZXRpb25TZXJ2aWNlIHVzaW5nIHRoZSBzdXBwbGllZAorICAgICAqIGV4ZWN1dG9yIGZvciBiYXNlIHRhc2sgZXhlY3V0aW9uIGFuZCB0aGUgc3VwcGxpZWQgcXVldWUgYXMgaXRzCisgICAgICogY29tcGxldGlvbiBxdWV1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleGVjdXRvciB0aGUgZXhlY3V0b3IgdG8gdXNlCisgICAgICogQHBhcmFtIGNvbXBsZXRpb25RdWV1ZSB0aGUgcXVldWUgdG8gdXNlIGFzIHRoZSBjb21wbGV0aW9uIHF1ZXVlCisgICAgICogICAgICAgIG5vcm1hbGx5IG9uZSBkZWRpY2F0ZWQgZm9yIHVzZSBieSB0aGlzIHNlcnZpY2UuIFRoaXMKKyAgICAgKiAgICAgICAgcXVldWUgaXMgdHJlYXRlZCBhcyB1bmJvdW5kZWQgLS0gZmFpbGVkIGF0dGVtcHRlZAorICAgICAqICAgICAgICB7QGNvZGUgUXVldWUuYWRkfSBvcGVyYXRpb25zIGZvciBjb21wbGV0ZWQgdGFza2VzIGNhdXNlCisgICAgICogICAgICAgIHRoZW0gbm90IHRvIGJlIHJldHJpZXZhYmxlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgZXhlY3V0b3Igb3IgY29tcGxldGlvblF1ZXVlIGFyZSB7QGNvZGUgbnVsbH0KKyAgICAgKi8KKyAgICBwdWJsaWMgRXhlY3V0b3JDb21wbGV0aW9uU2VydmljZShFeGVjdXRvciBleGVjdXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCbG9ja2luZ1F1ZXVlPEZ1dHVyZTxWPj4gY29tcGxldGlvblF1ZXVlKSB7CisgICAgICAgIGlmIChleGVjdXRvciA9PSBudWxsIHx8IGNvbXBsZXRpb25RdWV1ZSA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIHRoaXMuZXhlY3V0b3IgPSBleGVjdXRvcjsKKyAgICAgICAgdGhpcy5hZXMgPSAoZXhlY3V0b3IgaW5zdGFuY2VvZiBBYnN0cmFjdEV4ZWN1dG9yU2VydmljZSkgPworICAgICAgICAgICAgKEFic3RyYWN0RXhlY3V0b3JTZXJ2aWNlKSBleGVjdXRvciA6IG51bGw7CisgICAgICAgIHRoaXMuY29tcGxldGlvblF1ZXVlID0gY29tcGxldGlvblF1ZXVlOworICAgIH0KKworICAgIHB1YmxpYyBGdXR1cmU8Vj4gc3VibWl0KENhbGxhYmxlPFY+IHRhc2spIHsKKyAgICAgICAgaWYgKHRhc2sgPT0gbnVsbCkgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIFJ1bm5hYmxlRnV0dXJlPFY+IGYgPSBuZXdUYXNrRm9yKHRhc2spOworICAgICAgICBleGVjdXRvci5leGVjdXRlKG5ldyBRdWV1ZWluZ0Z1dHVyZShmKSk7CisgICAgICAgIHJldHVybiBmOworICAgIH0KKworICAgIHB1YmxpYyBGdXR1cmU8Vj4gc3VibWl0KFJ1bm5hYmxlIHRhc2ssIFYgcmVzdWx0KSB7CisgICAgICAgIGlmICh0YXNrID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBSdW5uYWJsZUZ1dHVyZTxWPiBmID0gbmV3VGFza0Zvcih0YXNrLCByZXN1bHQpOworICAgICAgICBleGVjdXRvci5leGVjdXRlKG5ldyBRdWV1ZWluZ0Z1dHVyZShmKSk7CisgICAgICAgIHJldHVybiBmOworICAgIH0KKworICAgIHB1YmxpYyBGdXR1cmU8Vj4gdGFrZSgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBjb21wbGV0aW9uUXVldWUudGFrZSgpOworICAgIH0KKworICAgIHB1YmxpYyBGdXR1cmU8Vj4gcG9sbCgpIHsKKyAgICAgICAgcmV0dXJuIGNvbXBsZXRpb25RdWV1ZS5wb2xsKCk7CisgICAgfQorCisgICAgcHVibGljIEZ1dHVyZTxWPiBwb2xsKGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBjb21wbGV0aW9uUXVldWUucG9sbCh0aW1lb3V0LCB1bml0KTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9FeGVjdXRvclNlcnZpY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9FeGVjdXRvclNlcnZpY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OTY4OGU0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0V4ZWN1dG9yU2VydmljZS5qYXZhCkBAIC0wLDAgKzEsMzI2IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbjsKKworLyoqCisgKiBBbiB7QGxpbmsgRXhlY3V0b3J9IHRoYXQgcHJvdmlkZXMgbWV0aG9kcyB0byBtYW5hZ2UgdGVybWluYXRpb24gYW5kCisgKiBtZXRob2RzIHRoYXQgY2FuIHByb2R1Y2UgYSB7QGxpbmsgRnV0dXJlfSBmb3IgdHJhY2tpbmcgcHJvZ3Jlc3Mgb2YKKyAqIG9uZSBvciBtb3JlIGFzeW5jaHJvbm91cyB0YXNrcy4KKyAqCisgKiA8cD4gQW4gPHR0PkV4ZWN1dG9yU2VydmljZTwvdHQ+IGNhbiBiZSBzaHV0IGRvd24sIHdoaWNoIHdpbGwgY2F1c2UKKyAqIGl0IHRvIHJlamVjdCBuZXcgdGFza3MuICBUd28gZGlmZmVyZW50IG1ldGhvZHMgYXJlIHByb3ZpZGVkIGZvcgorICogc2h1dHRpbmcgZG93biBhbiA8dHQ+RXhlY3V0b3JTZXJ2aWNlPC90dD4uIFRoZSB7QGxpbmsgI3NodXRkb3dufQorICogbWV0aG9kIHdpbGwgYWxsb3cgcHJldmlvdXNseSBzdWJtaXR0ZWQgdGFza3MgdG8gZXhlY3V0ZSBiZWZvcmUKKyAqIHRlcm1pbmF0aW5nLCB3aGlsZSB0aGUge0BsaW5rICNzaHV0ZG93bk5vd30gbWV0aG9kIHByZXZlbnRzIHdhaXRpbmcKKyAqIHRhc2tzIGZyb20gc3RhcnRpbmcgYW5kIGF0dGVtcHRzIHRvIHN0b3AgY3VycmVudGx5IGV4ZWN1dGluZyB0YXNrcy4KKyAqIFVwb24gdGVybWluYXRpb24sIGFuIGV4ZWN1dG9yIGhhcyBubyB0YXNrcyBhY3RpdmVseSBleGVjdXRpbmcsIG5vCisgKiB0YXNrcyBhd2FpdGluZyBleGVjdXRpb24sIGFuZCBubyBuZXcgdGFza3MgY2FuIGJlIHN1Ym1pdHRlZC4gIEFuCisgKiB1bnVzZWQgPHR0PkV4ZWN1dG9yU2VydmljZTwvdHQ+IHNob3VsZCBiZSBzaHV0IGRvd24gdG8gYWxsb3cKKyAqIHJlY2xhbWF0aW9uIG9mIGl0cyByZXNvdXJjZXMuCisgKgorICogPHA+IE1ldGhvZCA8dHQ+c3VibWl0PC90dD4gZXh0ZW5kcyBiYXNlIG1ldGhvZCB7QGxpbmsKKyAqIEV4ZWN1dG9yI2V4ZWN1dGV9IGJ5IGNyZWF0aW5nIGFuZCByZXR1cm5pbmcgYSB7QGxpbmsgRnV0dXJlfSB0aGF0CisgKiBjYW4gYmUgdXNlZCB0byBjYW5jZWwgZXhlY3V0aW9uIGFuZC9vciB3YWl0IGZvciBjb21wbGV0aW9uLgorICogTWV0aG9kcyA8dHQ+aW52b2tlQW55PC90dD4gYW5kIDx0dD5pbnZva2VBbGw8L3R0PiBwZXJmb3JtIHRoZSBtb3N0CisgKiBjb21tb25seSB1c2VmdWwgZm9ybXMgb2YgYnVsayBleGVjdXRpb24sIGV4ZWN1dGluZyBhIGNvbGxlY3Rpb24gb2YKKyAqIHRhc2tzIGFuZCB0aGVuIHdhaXRpbmcgZm9yIGF0IGxlYXN0IG9uZSwgb3IgYWxsLCB0bworICogY29tcGxldGUuIChDbGFzcyB7QGxpbmsgRXhlY3V0b3JDb21wbGV0aW9uU2VydmljZX0gY2FuIGJlIHVzZWQgdG8KKyAqIHdyaXRlIGN1c3RvbWl6ZWQgdmFyaWFudHMgb2YgdGhlc2UgbWV0aG9kcy4pCisgKgorICogPHA+VGhlIHtAbGluayBFeGVjdXRvcnN9IGNsYXNzIHByb3ZpZGVzIGZhY3RvcnkgbWV0aG9kcyBmb3IgdGhlCisgKiBleGVjdXRvciBzZXJ2aWNlcyBwcm92aWRlZCBpbiB0aGlzIHBhY2thZ2UuCisgKgorICogPGgzPlVzYWdlIEV4YW1wbGVzPC9oMz4KKyAqCisgKiBIZXJlIGlzIGEgc2tldGNoIG9mIGEgbmV0d29yayBzZXJ2aWNlIGluIHdoaWNoIHRocmVhZHMgaW4gYSB0aHJlYWQKKyAqIHBvb2wgc2VydmljZSBpbmNvbWluZyByZXF1ZXN0cy4gSXQgdXNlcyB0aGUgcHJlY29uZmlndXJlZCB7QGxpbmsKKyAqIEV4ZWN1dG9ycyNuZXdGaXhlZFRocmVhZFBvb2x9IGZhY3RvcnkgbWV0aG9kOgorICoKKyAqIDxwcmU+CisgKiBjbGFzcyBOZXR3b3JrU2VydmljZSBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKyAqICAgcHJpdmF0ZSBmaW5hbCBTZXJ2ZXJTb2NrZXQgc2VydmVyU29ja2V0OworICogICBwcml2YXRlIGZpbmFsIEV4ZWN1dG9yU2VydmljZSBwb29sOworICoKKyAqICAgcHVibGljIE5ldHdvcmtTZXJ2aWNlKGludCBwb3J0LCBpbnQgcG9vbFNpemUpCisgKiAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICogICAgIHNlcnZlclNvY2tldCA9IG5ldyBTZXJ2ZXJTb2NrZXQocG9ydCk7CisgKiAgICAgcG9vbCA9IEV4ZWN1dG9ycy5uZXdGaXhlZFRocmVhZFBvb2wocG9vbFNpemUpOworICogICB9CisgKgorICogICBwdWJsaWMgdm9pZCBydW4oKSB7IC8vIHJ1biB0aGUgc2VydmljZQorICogICAgIHRyeSB7CisgKiAgICAgICBmb3IgKDs7KSB7CisgKiAgICAgICAgIHBvb2wuZXhlY3V0ZShuZXcgSGFuZGxlcihzZXJ2ZXJTb2NrZXQuYWNjZXB0KCkpKTsKKyAqICAgICAgIH0KKyAqICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICogICAgICAgcG9vbC5zaHV0ZG93bigpOworICogICAgIH0KKyAqICAgfQorICogfQorICoKKyAqIGNsYXNzIEhhbmRsZXIgaW1wbGVtZW50cyBSdW5uYWJsZSB7CisgKiAgIHByaXZhdGUgZmluYWwgU29ja2V0IHNvY2tldDsKKyAqICAgSGFuZGxlcihTb2NrZXQgc29ja2V0KSB7IHRoaXMuc29ja2V0ID0gc29ja2V0OyB9CisgKiAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAqICAgICAvLyByZWFkIGFuZCBzZXJ2aWNlIHJlcXVlc3Qgb24gc29ja2V0CisgKiAgIH0KKyAqIH0KKyAqIDwvcHJlPgorICoKKyAqIFRoZSBmb2xsb3dpbmcgbWV0aG9kIHNodXRzIGRvd24gYW4gPHR0PkV4ZWN1dG9yU2VydmljZTwvdHQ+IGluIHR3byBwaGFzZXMsCisgKiBmaXJzdCBieSBjYWxsaW5nIDx0dD5zaHV0ZG93bjwvdHQ+IHRvIHJlamVjdCBpbmNvbWluZyB0YXNrcywgYW5kIHRoZW4KKyAqIGNhbGxpbmcgPHR0PnNodXRkb3duTm93PC90dD4sIGlmIG5lY2Vzc2FyeSwgdG8gY2FuY2VsIGFueSBsaW5nZXJpbmcgdGFza3M6CisgKgorICogPHByZT4KKyAqIHZvaWQgc2h1dGRvd25BbmRBd2FpdFRlcm1pbmF0aW9uKEV4ZWN1dG9yU2VydmljZSBwb29sKSB7CisgKiAgIHBvb2wuc2h1dGRvd24oKTsgLy8gRGlzYWJsZSBuZXcgdGFza3MgZnJvbSBiZWluZyBzdWJtaXR0ZWQKKyAqICAgdHJ5IHsKKyAqICAgICAvLyBXYWl0IGEgd2hpbGUgZm9yIGV4aXN0aW5nIHRhc2tzIHRvIHRlcm1pbmF0ZQorICogICAgIGlmICghcG9vbC5hd2FpdFRlcm1pbmF0aW9uKDYwLCBUaW1lVW5pdC5TRUNPTkRTKSkgeworICogICAgICAgcG9vbC5zaHV0ZG93bk5vdygpOyAvLyBDYW5jZWwgY3VycmVudGx5IGV4ZWN1dGluZyB0YXNrcworICogICAgICAgLy8gV2FpdCBhIHdoaWxlIGZvciB0YXNrcyB0byByZXNwb25kIHRvIGJlaW5nIGNhbmNlbGxlZAorICogICAgICAgaWYgKCFwb29sLmF3YWl0VGVybWluYXRpb24oNjAsIFRpbWVVbml0LlNFQ09ORFMpKQorICogICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiUG9vbCBkaWQgbm90IHRlcm1pbmF0ZSIpOworICogICAgIH0KKyAqICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaWUpIHsKKyAqICAgICAvLyAoUmUtKUNhbmNlbCBpZiBjdXJyZW50IHRocmVhZCBhbHNvIGludGVycnVwdGVkCisgKiAgICAgcG9vbC5zaHV0ZG93bk5vdygpOworICogICAgIC8vIFByZXNlcnZlIGludGVycnVwdCBzdGF0dXMKKyAqICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLmludGVycnVwdCgpOworICogICB9CisgKiB9CisgKiA8L3ByZT4KKyAqCisgKiA8cD5NZW1vcnkgY29uc2lzdGVuY3kgZWZmZWN0czogQWN0aW9ucyBpbiBhIHRocmVhZCBwcmlvciB0byB0aGUKKyAqIHN1Ym1pc3Npb24gb2YgYSB7QGNvZGUgUnVubmFibGV9IG9yIHtAY29kZSBDYWxsYWJsZX0gdGFzayB0byBhbgorICoge0Bjb2RlIEV4ZWN1dG9yU2VydmljZX0KKyAqIDxhIGhyZWY9InBhY2thZ2Utc3VtbWFyeS5odG1sI01lbW9yeVZpc2liaWxpdHkiPjxpPmhhcHBlbi1iZWZvcmU8L2k+PC9hPgorICogYW55IGFjdGlvbnMgdGFrZW4gYnkgdGhhdCB0YXNrLCB3aGljaCBpbiB0dXJuIDxpPmhhcHBlbi1iZWZvcmU8L2k+IHRoZQorICogcmVzdWx0IGlzIHJldHJpZXZlZCB2aWEge0Bjb2RlIEZ1dHVyZS5nZXQoKX0uCisgKgorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICovCitwdWJsaWMgaW50ZXJmYWNlIEV4ZWN1dG9yU2VydmljZSBleHRlbmRzIEV4ZWN1dG9yIHsKKworICAgIC8qKgorICAgICAqIEluaXRpYXRlcyBhbiBvcmRlcmx5IHNodXRkb3duIGluIHdoaWNoIHByZXZpb3VzbHkgc3VibWl0dGVkCisgICAgICogdGFza3MgYXJlIGV4ZWN1dGVkLCBidXQgbm8gbmV3IHRhc2tzIHdpbGwgYmUgYWNjZXB0ZWQuCisgICAgICogSW52b2NhdGlvbiBoYXMgbm8gYWRkaXRpb25hbCBlZmZlY3QgaWYgYWxyZWFkeSBzaHV0IGRvd24uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBkb2VzIG5vdCB3YWl0IGZvciBwcmV2aW91c2x5IHN1Ym1pdHRlZCB0YXNrcyB0bworICAgICAqIGNvbXBsZXRlIGV4ZWN1dGlvbi4gIFVzZSB7QGxpbmsgI2F3YWl0VGVybWluYXRpb24gYXdhaXRUZXJtaW5hdGlvbn0KKyAgICAgKiB0byBkbyB0aGF0LgorICAgICAqLworICAgIHZvaWQgc2h1dGRvd24oKTsKKworICAgIC8qKgorICAgICAqIEF0dGVtcHRzIHRvIHN0b3AgYWxsIGFjdGl2ZWx5IGV4ZWN1dGluZyB0YXNrcywgaGFsdHMgdGhlCisgICAgICogcHJvY2Vzc2luZyBvZiB3YWl0aW5nIHRhc2tzLCBhbmQgcmV0dXJucyBhIGxpc3Qgb2YgdGhlIHRhc2tzCisgICAgICogdGhhdCB3ZXJlIGF3YWl0aW5nIGV4ZWN1dGlvbi4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGRvZXMgbm90IHdhaXQgZm9yIGFjdGl2ZWx5IGV4ZWN1dGluZyB0YXNrcyB0bworICAgICAqIHRlcm1pbmF0ZS4gIFVzZSB7QGxpbmsgI2F3YWl0VGVybWluYXRpb24gYXdhaXRUZXJtaW5hdGlvbn0gdG8KKyAgICAgKiBkbyB0aGF0LgorICAgICAqCisgICAgICogPHA+VGhlcmUgYXJlIG5vIGd1YXJhbnRlZXMgYmV5b25kIGJlc3QtZWZmb3J0IGF0dGVtcHRzIHRvIHN0b3AKKyAgICAgKiBwcm9jZXNzaW5nIGFjdGl2ZWx5IGV4ZWN1dGluZyB0YXNrcy4gIEZvciBleGFtcGxlLCB0eXBpY2FsCisgICAgICogaW1wbGVtZW50YXRpb25zIHdpbGwgY2FuY2VsIHZpYSB7QGxpbmsgVGhyZWFkI2ludGVycnVwdH0sIHNvIGFueQorICAgICAqIHRhc2sgdGhhdCBmYWlscyB0byByZXNwb25kIHRvIGludGVycnVwdHMgbWF5IG5ldmVyIHRlcm1pbmF0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gbGlzdCBvZiB0YXNrcyB0aGF0IG5ldmVyIGNvbW1lbmNlZCBleGVjdXRpb24KKyAgICAgKi8KKyAgICBMaXN0PFJ1bm5hYmxlPiBzaHV0ZG93bk5vdygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgZXhlY3V0b3IgaGFzIGJlZW4gc2h1dCBkb3duLgorICAgICAqCisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgZXhlY3V0b3IgaGFzIGJlZW4gc2h1dCBkb3duCisgICAgICovCisgICAgYm9vbGVhbiBpc1NodXRkb3duKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIDx0dD50cnVlPC90dD4gaWYgYWxsIHRhc2tzIGhhdmUgY29tcGxldGVkIGZvbGxvd2luZyBzaHV0IGRvd24uCisgICAgICogTm90ZSB0aGF0IDx0dD5pc1Rlcm1pbmF0ZWQ8L3R0PiBpcyBuZXZlciA8dHQ+dHJ1ZTwvdHQ+IHVubGVzcworICAgICAqIGVpdGhlciA8dHQ+c2h1dGRvd248L3R0PiBvciA8dHQ+c2h1dGRvd25Ob3c8L3R0PiB3YXMgY2FsbGVkIGZpcnN0LgorICAgICAqCisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIGFsbCB0YXNrcyBoYXZlIGNvbXBsZXRlZCBmb2xsb3dpbmcgc2h1dCBkb3duCisgICAgICovCisgICAgYm9vbGVhbiBpc1Rlcm1pbmF0ZWQoKTsKKworICAgIC8qKgorICAgICAqIEJsb2NrcyB1bnRpbCBhbGwgdGFza3MgaGF2ZSBjb21wbGV0ZWQgZXhlY3V0aW9uIGFmdGVyIGEgc2h1dGRvd24KKyAgICAgKiByZXF1ZXN0LCBvciB0aGUgdGltZW91dCBvY2N1cnMsIG9yIHRoZSBjdXJyZW50IHRocmVhZCBpcworICAgICAqIGludGVycnVwdGVkLCB3aGljaGV2ZXIgaGFwcGVucyBmaXJzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aW1lb3V0IHRoZSBtYXhpbXVtIHRpbWUgdG8gd2FpdAorICAgICAqIEBwYXJhbSB1bml0IHRoZSB0aW1lIHVuaXQgb2YgdGhlIHRpbWVvdXQgYXJndW1lbnQKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBleGVjdXRvciB0ZXJtaW5hdGVkIGFuZAorICAgICAqICAgICAgICAgPHR0PmZhbHNlPC90dD4gaWYgdGhlIHRpbWVvdXQgZWxhcHNlZCBiZWZvcmUgdGVybWluYXRpb24KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIGludGVycnVwdGVkIHdoaWxlIHdhaXRpbmcKKyAgICAgKi8KKyAgICBib29sZWFuIGF3YWl0VGVybWluYXRpb24obG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KQorICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFN1Ym1pdHMgYSB2YWx1ZS1yZXR1cm5pbmcgdGFzayBmb3IgZXhlY3V0aW9uIGFuZCByZXR1cm5zIGEKKyAgICAgKiBGdXR1cmUgcmVwcmVzZW50aW5nIHRoZSBwZW5kaW5nIHJlc3VsdHMgb2YgdGhlIHRhc2suIFRoZQorICAgICAqIEZ1dHVyZSdzIDx0dD5nZXQ8L3R0PiBtZXRob2Qgd2lsbCByZXR1cm4gdGhlIHRhc2sncyByZXN1bHQgdXBvbgorICAgICAqIHN1Y2Nlc3NmdWwgY29tcGxldGlvbi4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIElmIHlvdSB3b3VsZCBsaWtlIHRvIGltbWVkaWF0ZWx5IGJsb2NrIHdhaXRpbmcKKyAgICAgKiBmb3IgYSB0YXNrLCB5b3UgY2FuIHVzZSBjb25zdHJ1Y3Rpb25zIG9mIHRoZSBmb3JtCisgICAgICogPHR0PnJlc3VsdCA9IGV4ZWMuc3VibWl0KGFDYWxsYWJsZSkuZ2V0KCk7PC90dD4KKyAgICAgKgorICAgICAqIDxwPiBOb3RlOiBUaGUge0BsaW5rIEV4ZWN1dG9yc30gY2xhc3MgaW5jbHVkZXMgYSBzZXQgb2YgbWV0aG9kcworICAgICAqIHRoYXQgY2FuIGNvbnZlcnQgc29tZSBvdGhlciBjb21tb24gY2xvc3VyZS1saWtlIG9iamVjdHMsCisgICAgICogZm9yIGV4YW1wbGUsIHtAbGluayBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb259IHRvCisgICAgICoge0BsaW5rIENhbGxhYmxlfSBmb3JtIHNvIHRoZXkgY2FuIGJlIHN1Ym1pdHRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YXNrIHRoZSB0YXNrIHRvIHN1Ym1pdAorICAgICAqIEByZXR1cm4gYSBGdXR1cmUgcmVwcmVzZW50aW5nIHBlbmRpbmcgY29tcGxldGlvbiBvZiB0aGUgdGFzaworICAgICAqIEB0aHJvd3MgUmVqZWN0ZWRFeGVjdXRpb25FeGNlcHRpb24gaWYgdGhlIHRhc2sgY2Fubm90IGJlCisgICAgICogICAgICAgICBzY2hlZHVsZWQgZm9yIGV4ZWN1dGlvbgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHRhc2sgaXMgbnVsbAorICAgICAqLworICAgIDxUPiBGdXR1cmU8VD4gc3VibWl0KENhbGxhYmxlPFQ+IHRhc2spOworCisgICAgLyoqCisgICAgICogU3VibWl0cyBhIFJ1bm5hYmxlIHRhc2sgZm9yIGV4ZWN1dGlvbiBhbmQgcmV0dXJucyBhIEZ1dHVyZQorICAgICAqIHJlcHJlc2VudGluZyB0aGF0IHRhc2suIFRoZSBGdXR1cmUncyA8dHQ+Z2V0PC90dD4gbWV0aG9kIHdpbGwKKyAgICAgKiByZXR1cm4gdGhlIGdpdmVuIHJlc3VsdCB1cG9uIHN1Y2Nlc3NmdWwgY29tcGxldGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YXNrIHRoZSB0YXNrIHRvIHN1Ym1pdAorICAgICAqIEBwYXJhbSByZXN1bHQgdGhlIHJlc3VsdCB0byByZXR1cm4KKyAgICAgKiBAcmV0dXJuIGEgRnV0dXJlIHJlcHJlc2VudGluZyBwZW5kaW5nIGNvbXBsZXRpb24gb2YgdGhlIHRhc2sKKyAgICAgKiBAdGhyb3dzIFJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9uIGlmIHRoZSB0YXNrIGNhbm5vdCBiZQorICAgICAqICAgICAgICAgc2NoZWR1bGVkIGZvciBleGVjdXRpb24KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSB0YXNrIGlzIG51bGwKKyAgICAgKi8KKyAgICA8VD4gRnV0dXJlPFQ+IHN1Ym1pdChSdW5uYWJsZSB0YXNrLCBUIHJlc3VsdCk7CisKKyAgICAvKioKKyAgICAgKiBTdWJtaXRzIGEgUnVubmFibGUgdGFzayBmb3IgZXhlY3V0aW9uIGFuZCByZXR1cm5zIGEgRnV0dXJlCisgICAgICogcmVwcmVzZW50aW5nIHRoYXQgdGFzay4gVGhlIEZ1dHVyZSdzIDx0dD5nZXQ8L3R0PiBtZXRob2Qgd2lsbAorICAgICAqIHJldHVybiA8dHQ+bnVsbDwvdHQ+IHVwb24gPGVtPnN1Y2Nlc3NmdWw8L2VtPiBjb21wbGV0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHRhc2sgdGhlIHRhc2sgdG8gc3VibWl0CisgICAgICogQHJldHVybiBhIEZ1dHVyZSByZXByZXNlbnRpbmcgcGVuZGluZyBjb21wbGV0aW9uIG9mIHRoZSB0YXNrCisgICAgICogQHRocm93cyBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbiBpZiB0aGUgdGFzayBjYW5ub3QgYmUKKyAgICAgKiAgICAgICAgIHNjaGVkdWxlZCBmb3IgZXhlY3V0aW9uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgdGFzayBpcyBudWxsCisgICAgICovCisgICAgRnV0dXJlPD8+IHN1Ym1pdChSdW5uYWJsZSB0YXNrKTsKKworICAgIC8qKgorICAgICAqIEV4ZWN1dGVzIHRoZSBnaXZlbiB0YXNrcywgcmV0dXJuaW5nIGEgbGlzdCBvZiBGdXR1cmVzIGhvbGRpbmcKKyAgICAgKiB0aGVpciBzdGF0dXMgYW5kIHJlc3VsdHMgd2hlbiBhbGwgY29tcGxldGUuCisgICAgICoge0BsaW5rIEZ1dHVyZSNpc0RvbmV9IGlzIDx0dD50cnVlPC90dD4gZm9yIGVhY2gKKyAgICAgKiBlbGVtZW50IG9mIHRoZSByZXR1cm5lZCBsaXN0LgorICAgICAqIE5vdGUgdGhhdCBhIDxlbT5jb21wbGV0ZWQ8L2VtPiB0YXNrIGNvdWxkIGhhdmUKKyAgICAgKiB0ZXJtaW5hdGVkIGVpdGhlciBub3JtYWxseSBvciBieSB0aHJvd2luZyBhbiBleGNlcHRpb24uCisgICAgICogVGhlIHJlc3VsdHMgb2YgdGhpcyBtZXRob2QgYXJlIHVuZGVmaW5lZCBpZiB0aGUgZ2l2ZW4KKyAgICAgKiBjb2xsZWN0aW9uIGlzIG1vZGlmaWVkIHdoaWxlIHRoaXMgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLgorICAgICAqCisgICAgICogQHBhcmFtIHRhc2tzIHRoZSBjb2xsZWN0aW9uIG9mIHRhc2tzCisgICAgICogQHJldHVybiBBIGxpc3Qgb2YgRnV0dXJlcyByZXByZXNlbnRpbmcgdGhlIHRhc2tzLCBpbiB0aGUgc2FtZQorICAgICAqICAgICAgICAgc2VxdWVudGlhbCBvcmRlciBhcyBwcm9kdWNlZCBieSB0aGUgaXRlcmF0b3IgZm9yIHRoZQorICAgICAqICAgICAgICAgZ2l2ZW4gdGFzayBsaXN0LCBlYWNoIG9mIHdoaWNoIGhhcyBjb21wbGV0ZWQuCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiBpbnRlcnJ1cHRlZCB3aGlsZSB3YWl0aW5nLCBpbgorICAgICAqICAgICAgICAgd2hpY2ggY2FzZSB1bmZpbmlzaGVkIHRhc2tzIGFyZSBjYW5jZWxsZWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0YXNrcyBvciBhbnkgb2YgaXRzIGVsZW1lbnRzIGFyZSA8dHQ+bnVsbDwvdHQ+CisgICAgICogQHRocm93cyBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbiBpZiBhbnkgdGFzayBjYW5ub3QgYmUKKyAgICAgKiAgICAgICAgIHNjaGVkdWxlZCBmb3IgZXhlY3V0aW9uCisgICAgICovCisKKyAgICA8VD4gTGlzdDxGdXR1cmU8VD4+IGludm9rZUFsbChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDYWxsYWJsZTxUPj4gdGFza3MpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEV4ZWN1dGVzIHRoZSBnaXZlbiB0YXNrcywgcmV0dXJuaW5nIGEgbGlzdCBvZiBGdXR1cmVzIGhvbGRpbmcKKyAgICAgKiB0aGVpciBzdGF0dXMgYW5kIHJlc3VsdHMKKyAgICAgKiB3aGVuIGFsbCBjb21wbGV0ZSBvciB0aGUgdGltZW91dCBleHBpcmVzLCB3aGljaGV2ZXIgaGFwcGVucyBmaXJzdC4KKyAgICAgKiB7QGxpbmsgRnV0dXJlI2lzRG9uZX0gaXMgPHR0PnRydWU8L3R0PiBmb3IgZWFjaAorICAgICAqIGVsZW1lbnQgb2YgdGhlIHJldHVybmVkIGxpc3QuCisgICAgICogVXBvbiByZXR1cm4sIHRhc2tzIHRoYXQgaGF2ZSBub3QgY29tcGxldGVkIGFyZSBjYW5jZWxsZWQuCisgICAgICogTm90ZSB0aGF0IGEgPGVtPmNvbXBsZXRlZDwvZW0+IHRhc2sgY291bGQgaGF2ZQorICAgICAqIHRlcm1pbmF0ZWQgZWl0aGVyIG5vcm1hbGx5IG9yIGJ5IHRocm93aW5nIGFuIGV4Y2VwdGlvbi4KKyAgICAgKiBUaGUgcmVzdWx0cyBvZiB0aGlzIG1ldGhvZCBhcmUgdW5kZWZpbmVkIGlmIHRoZSBnaXZlbgorICAgICAqIGNvbGxlY3Rpb24gaXMgbW9kaWZpZWQgd2hpbGUgdGhpcyBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGFza3MgdGhlIGNvbGxlY3Rpb24gb2YgdGFza3MKKyAgICAgKiBAcGFyYW0gdGltZW91dCB0aGUgbWF4aW11bSB0aW1lIHRvIHdhaXQKKyAgICAgKiBAcGFyYW0gdW5pdCB0aGUgdGltZSB1bml0IG9mIHRoZSB0aW1lb3V0IGFyZ3VtZW50CisgICAgICogQHJldHVybiBhIGxpc3Qgb2YgRnV0dXJlcyByZXByZXNlbnRpbmcgdGhlIHRhc2tzLCBpbiB0aGUgc2FtZQorICAgICAqICAgICAgICAgc2VxdWVudGlhbCBvcmRlciBhcyBwcm9kdWNlZCBieSB0aGUgaXRlcmF0b3IgZm9yIHRoZQorICAgICAqICAgICAgICAgZ2l2ZW4gdGFzayBsaXN0LiBJZiB0aGUgb3BlcmF0aW9uIGRpZCBub3QgdGltZSBvdXQsCisgICAgICogICAgICAgICBlYWNoIHRhc2sgd2lsbCBoYXZlIGNvbXBsZXRlZC4gSWYgaXQgZGlkIHRpbWUgb3V0LCBzb21lCisgICAgICogICAgICAgICBvZiB0aGVzZSB0YXNrcyB3aWxsIG5vdCBoYXZlIGNvbXBsZXRlZC4KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIGludGVycnVwdGVkIHdoaWxlIHdhaXRpbmcsIGluCisgICAgICogICAgICAgICB3aGljaCBjYXNlIHVuZmluaXNoZWQgdGFza3MgYXJlIGNhbmNlbGxlZAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGFza3MsIGFueSBvZiBpdHMgZWxlbWVudHMsIG9yCisgICAgICogICAgICAgICB1bml0IGFyZSA8dHQ+bnVsbDwvdHQ+CisgICAgICogQHRocm93cyBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbiBpZiBhbnkgdGFzayBjYW5ub3QgYmUgc2NoZWR1bGVkCisgICAgICogICAgICAgICBmb3IgZXhlY3V0aW9uCisgICAgICovCisgICAgPFQ+IExpc3Q8RnV0dXJlPFQ+PiBpbnZva2VBbGwoQ29sbGVjdGlvbjw/IGV4dGVuZHMgQ2FsbGFibGU8VD4+IHRhc2tzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRXhlY3V0ZXMgdGhlIGdpdmVuIHRhc2tzLCByZXR1cm5pbmcgdGhlIHJlc3VsdAorICAgICAqIG9mIG9uZSB0aGF0IGhhcyBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5IChpLmUuLCB3aXRob3V0IHRocm93aW5nCisgICAgICogYW4gZXhjZXB0aW9uKSwgaWYgYW55IGRvLiBVcG9uIG5vcm1hbCBvciBleGNlcHRpb25hbCByZXR1cm4sCisgICAgICogdGFza3MgdGhhdCBoYXZlIG5vdCBjb21wbGV0ZWQgYXJlIGNhbmNlbGxlZC4KKyAgICAgKiBUaGUgcmVzdWx0cyBvZiB0aGlzIG1ldGhvZCBhcmUgdW5kZWZpbmVkIGlmIHRoZSBnaXZlbgorICAgICAqIGNvbGxlY3Rpb24gaXMgbW9kaWZpZWQgd2hpbGUgdGhpcyBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGFza3MgdGhlIGNvbGxlY3Rpb24gb2YgdGFza3MKKyAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgcmV0dXJuZWQgYnkgb25lIG9mIHRoZSB0YXNrcworICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgaW50ZXJydXB0ZWQgd2hpbGUgd2FpdGluZworICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGFza3Mgb3IgYW55IGVsZW1lbnQgdGFzaworICAgICAqICAgICAgICAgc3ViamVjdCB0byBleGVjdXRpb24gaXMgPHR0Pm51bGw8L3R0PgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRhc2tzIGlzIGVtcHR5CisgICAgICogQHRocm93cyBFeGVjdXRpb25FeGNlcHRpb24gaWYgbm8gdGFzayBzdWNjZXNzZnVsbHkgY29tcGxldGVzCisgICAgICogQHRocm93cyBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbiBpZiB0YXNrcyBjYW5ub3QgYmUgc2NoZWR1bGVkCisgICAgICogICAgICAgICBmb3IgZXhlY3V0aW9uCisgICAgICovCisgICAgPFQ+IFQgaW52b2tlQW55KENvbGxlY3Rpb248PyBleHRlbmRzIENhbGxhYmxlPFQ+PiB0YXNrcykKKyAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBFeGVjdXRlcyB0aGUgZ2l2ZW4gdGFza3MsIHJldHVybmluZyB0aGUgcmVzdWx0CisgICAgICogb2Ygb25lIHRoYXQgaGFzIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkgKGkuZS4sIHdpdGhvdXQgdGhyb3dpbmcKKyAgICAgKiBhbiBleGNlcHRpb24pLCBpZiBhbnkgZG8gYmVmb3JlIHRoZSBnaXZlbiB0aW1lb3V0IGVsYXBzZXMuCisgICAgICogVXBvbiBub3JtYWwgb3IgZXhjZXB0aW9uYWwgcmV0dXJuLCB0YXNrcyB0aGF0IGhhdmUgbm90CisgICAgICogY29tcGxldGVkIGFyZSBjYW5jZWxsZWQuCisgICAgICogVGhlIHJlc3VsdHMgb2YgdGhpcyBtZXRob2QgYXJlIHVuZGVmaW5lZCBpZiB0aGUgZ2l2ZW4KKyAgICAgKiBjb2xsZWN0aW9uIGlzIG1vZGlmaWVkIHdoaWxlIHRoaXMgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLgorICAgICAqCisgICAgICogQHBhcmFtIHRhc2tzIHRoZSBjb2xsZWN0aW9uIG9mIHRhc2tzCisgICAgICogQHBhcmFtIHRpbWVvdXQgdGhlIG1heGltdW0gdGltZSB0byB3YWl0CisgICAgICogQHBhcmFtIHVuaXQgdGhlIHRpbWUgdW5pdCBvZiB0aGUgdGltZW91dCBhcmd1bWVudAorICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCByZXR1cm5lZCBieSBvbmUgb2YgdGhlIHRhc2tzLgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgaW50ZXJydXB0ZWQgd2hpbGUgd2FpdGluZworICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGFza3MsIG9yIHVuaXQsIG9yIGFueSBlbGVtZW50CisgICAgICogICAgICAgICB0YXNrIHN1YmplY3QgdG8gZXhlY3V0aW9uIGlzIDx0dD5udWxsPC90dD4KKyAgICAgKiBAdGhyb3dzIFRpbWVvdXRFeGNlcHRpb24gaWYgdGhlIGdpdmVuIHRpbWVvdXQgZWxhcHNlcyBiZWZvcmUKKyAgICAgKiAgICAgICAgIGFueSB0YXNrIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZXMKKyAgICAgKiBAdGhyb3dzIEV4ZWN1dGlvbkV4Y2VwdGlvbiBpZiBubyB0YXNrIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZXMKKyAgICAgKiBAdGhyb3dzIFJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9uIGlmIHRhc2tzIGNhbm5vdCBiZSBzY2hlZHVsZWQKKyAgICAgKiAgICAgICAgIGZvciBleGVjdXRpb24KKyAgICAgKi8KKyAgICA8VD4gVCBpbnZva2VBbnkoQ29sbGVjdGlvbjw/IGV4dGVuZHMgQ2FsbGFibGU8VD4+IHRhc2tzLAorICAgICAgICAgICAgICAgICAgICBsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uLCBUaW1lb3V0RXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0V4ZWN1dG9ycy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0V4ZWN1dG9ycy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU0MmIwY2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvRXhlY3V0b3JzLmphdmEKQEAgLTAsMCArMSw2NzcgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudDsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xDb250ZXh0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xFeGNlcHRpb247CisvLyBpbXBvcnQgc3VuLnNlY3VyaXR5LnV0aWwuU2VjdXJpdHlDb25zdGFudHM7IC8vIGFuZHJvaWQtcmVtb3ZlZAorCisvKioKKyAqIEZhY3RvcnkgYW5kIHV0aWxpdHkgbWV0aG9kcyBmb3Ige0BsaW5rIEV4ZWN1dG9yfSwge0BsaW5rCisgKiBFeGVjdXRvclNlcnZpY2V9LCB7QGxpbmsgU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlfSwge0BsaW5rCisgKiBUaHJlYWRGYWN0b3J5fSwgYW5kIHtAbGluayBDYWxsYWJsZX0gY2xhc3NlcyBkZWZpbmVkIGluIHRoaXMKKyAqIHBhY2thZ2UuIFRoaXMgY2xhc3Mgc3VwcG9ydHMgdGhlIGZvbGxvd2luZyBraW5kcyBvZiBtZXRob2RzOgorICoKKyAqIDx1bD4KKyAqICAgPGxpPiBNZXRob2RzIHRoYXQgY3JlYXRlIGFuZCByZXR1cm4gYW4ge0BsaW5rIEV4ZWN1dG9yU2VydmljZX0KKyAqICAgICAgICBzZXQgdXAgd2l0aCBjb21tb25seSB1c2VmdWwgY29uZmlndXJhdGlvbiBzZXR0aW5ncy4KKyAqICAgPGxpPiBNZXRob2RzIHRoYXQgY3JlYXRlIGFuZCByZXR1cm4gYSB7QGxpbmsgU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlfQorICogICAgICAgIHNldCB1cCB3aXRoIGNvbW1vbmx5IHVzZWZ1bCBjb25maWd1cmF0aW9uIHNldHRpbmdzLgorICogICA8bGk+IE1ldGhvZHMgdGhhdCBjcmVhdGUgYW5kIHJldHVybiBhICJ3cmFwcGVkIiBFeGVjdXRvclNlcnZpY2UsIHRoYXQKKyAqICAgICAgICBkaXNhYmxlcyByZWNvbmZpZ3VyYXRpb24gYnkgbWFraW5nIGltcGxlbWVudGF0aW9uLXNwZWNpZmljIG1ldGhvZHMKKyAqICAgICAgICBpbmFjY2Vzc2libGUuCisgKiAgIDxsaT4gTWV0aG9kcyB0aGF0IGNyZWF0ZSBhbmQgcmV0dXJuIGEge0BsaW5rIFRocmVhZEZhY3Rvcnl9CisgKiAgICAgICAgdGhhdCBzZXRzIG5ld2x5IGNyZWF0ZWQgdGhyZWFkcyB0byBhIGtub3duIHN0YXRlLgorICogICA8bGk+IE1ldGhvZHMgdGhhdCBjcmVhdGUgYW5kIHJldHVybiBhIHtAbGluayBDYWxsYWJsZX0KKyAqICAgICAgICBvdXQgb2Ygb3RoZXIgY2xvc3VyZS1saWtlIGZvcm1zLCBzbyB0aGV5IGNhbiBiZSB1c2VkCisgKiAgICAgICAgaW4gZXhlY3V0aW9uIG1ldGhvZHMgcmVxdWlyaW5nIDx0dD5DYWxsYWJsZTwvdHQ+LgorICogPC91bD4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKi8KK3B1YmxpYyBjbGFzcyBFeGVjdXRvcnMgeworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHRocmVhZCBwb29sIHRoYXQgcmV1c2VzIGEgZml4ZWQgbnVtYmVyIG9mIHRocmVhZHMKKyAgICAgKiBvcGVyYXRpbmcgb2ZmIGEgc2hhcmVkIHVuYm91bmRlZCBxdWV1ZS4gIEF0IGFueSBwb2ludCwgYXQgbW9zdAorICAgICAqIDx0dD5uVGhyZWFkczwvdHQ+IHRocmVhZHMgd2lsbCBiZSBhY3RpdmUgcHJvY2Vzc2luZyB0YXNrcy4KKyAgICAgKiBJZiBhZGRpdGlvbmFsIHRhc2tzIGFyZSBzdWJtaXR0ZWQgd2hlbiBhbGwgdGhyZWFkcyBhcmUgYWN0aXZlLAorICAgICAqIHRoZXkgd2lsbCB3YWl0IGluIHRoZSBxdWV1ZSB1bnRpbCBhIHRocmVhZCBpcyBhdmFpbGFibGUuCisgICAgICogSWYgYW55IHRocmVhZCB0ZXJtaW5hdGVzIGR1ZSB0byBhIGZhaWx1cmUgZHVyaW5nIGV4ZWN1dGlvbgorICAgICAqIHByaW9yIHRvIHNodXRkb3duLCBhIG5ldyBvbmUgd2lsbCB0YWtlIGl0cyBwbGFjZSBpZiBuZWVkZWQgdG8KKyAgICAgKiBleGVjdXRlIHN1YnNlcXVlbnQgdGFza3MuICBUaGUgdGhyZWFkcyBpbiB0aGUgcG9vbCB3aWxsIGV4aXN0CisgICAgICogdW50aWwgaXQgaXMgZXhwbGljaXRseSB7QGxpbmsgRXhlY3V0b3JTZXJ2aWNlI3NodXRkb3duIHNodXRkb3dufS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuVGhyZWFkcyB0aGUgbnVtYmVyIG9mIHRocmVhZHMgaW4gdGhlIHBvb2wKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXdseSBjcmVhdGVkIHRocmVhZCBwb29sCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIG5UaHJlYWRzIDw9IDB9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBFeGVjdXRvclNlcnZpY2UgbmV3Rml4ZWRUaHJlYWRQb29sKGludCBuVGhyZWFkcykgeworICAgICAgICByZXR1cm4gbmV3IFRocmVhZFBvb2xFeGVjdXRvcihuVGhyZWFkcywgblRocmVhZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDBMLCBUaW1lVW5pdC5NSUxMSVNFQ09ORFMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBMaW5rZWRCbG9ja2luZ1F1ZXVlPFJ1bm5hYmxlPigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgdGhyZWFkIHBvb2wgdGhhdCByZXVzZXMgYSBmaXhlZCBudW1iZXIgb2YgdGhyZWFkcworICAgICAqIG9wZXJhdGluZyBvZmYgYSBzaGFyZWQgdW5ib3VuZGVkIHF1ZXVlLCB1c2luZyB0aGUgcHJvdmlkZWQKKyAgICAgKiBUaHJlYWRGYWN0b3J5IHRvIGNyZWF0ZSBuZXcgdGhyZWFkcyB3aGVuIG5lZWRlZC4gIEF0IGFueSBwb2ludCwKKyAgICAgKiBhdCBtb3N0IDx0dD5uVGhyZWFkczwvdHQ+IHRocmVhZHMgd2lsbCBiZSBhY3RpdmUgcHJvY2Vzc2luZworICAgICAqIHRhc2tzLiAgSWYgYWRkaXRpb25hbCB0YXNrcyBhcmUgc3VibWl0dGVkIHdoZW4gYWxsIHRocmVhZHMgYXJlCisgICAgICogYWN0aXZlLCB0aGV5IHdpbGwgd2FpdCBpbiB0aGUgcXVldWUgdW50aWwgYSB0aHJlYWQgaXMKKyAgICAgKiBhdmFpbGFibGUuICBJZiBhbnkgdGhyZWFkIHRlcm1pbmF0ZXMgZHVlIHRvIGEgZmFpbHVyZSBkdXJpbmcKKyAgICAgKiBleGVjdXRpb24gcHJpb3IgdG8gc2h1dGRvd24sIGEgbmV3IG9uZSB3aWxsIHRha2UgaXRzIHBsYWNlIGlmCisgICAgICogbmVlZGVkIHRvIGV4ZWN1dGUgc3Vic2VxdWVudCB0YXNrcy4gIFRoZSB0aHJlYWRzIGluIHRoZSBwb29sIHdpbGwKKyAgICAgKiBleGlzdCB1bnRpbCBpdCBpcyBleHBsaWNpdGx5IHtAbGluayBFeGVjdXRvclNlcnZpY2Ujc2h1dGRvd24KKyAgICAgKiBzaHV0ZG93bn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gblRocmVhZHMgdGhlIG51bWJlciBvZiB0aHJlYWRzIGluIHRoZSBwb29sCisgICAgICogQHBhcmFtIHRocmVhZEZhY3RvcnkgdGhlIGZhY3RvcnkgdG8gdXNlIHdoZW4gY3JlYXRpbmcgbmV3IHRocmVhZHMKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXdseSBjcmVhdGVkIHRocmVhZCBwb29sCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aHJlYWRGYWN0b3J5IGlzIG51bGwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgblRocmVhZHMgPD0gMH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEV4ZWN1dG9yU2VydmljZSBuZXdGaXhlZFRocmVhZFBvb2woaW50IG5UaHJlYWRzLCBUaHJlYWRGYWN0b3J5IHRocmVhZEZhY3RvcnkpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBUaHJlYWRQb29sRXhlY3V0b3IoblRocmVhZHMsIG5UaHJlYWRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwTCwgVGltZVVuaXQuTUlMTElTRUNPTkRTLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTGlua2VkQmxvY2tpbmdRdWV1ZTxSdW5uYWJsZT4oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyZWFkRmFjdG9yeSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBFeGVjdXRvciB0aGF0IHVzZXMgYSBzaW5nbGUgd29ya2VyIHRocmVhZCBvcGVyYXRpbmcKKyAgICAgKiBvZmYgYW4gdW5ib3VuZGVkIHF1ZXVlLiAoTm90ZSBob3dldmVyIHRoYXQgaWYgdGhpcyBzaW5nbGUKKyAgICAgKiB0aHJlYWQgdGVybWluYXRlcyBkdWUgdG8gYSBmYWlsdXJlIGR1cmluZyBleGVjdXRpb24gcHJpb3IgdG8KKyAgICAgKiBzaHV0ZG93biwgYSBuZXcgb25lIHdpbGwgdGFrZSBpdHMgcGxhY2UgaWYgbmVlZGVkIHRvIGV4ZWN1dGUKKyAgICAgKiBzdWJzZXF1ZW50IHRhc2tzLikgIFRhc2tzIGFyZSBndWFyYW50ZWVkIHRvIGV4ZWN1dGUKKyAgICAgKiBzZXF1ZW50aWFsbHksIGFuZCBubyBtb3JlIHRoYW4gb25lIHRhc2sgd2lsbCBiZSBhY3RpdmUgYXQgYW55CisgICAgICogZ2l2ZW4gdGltZS4gVW5saWtlIHRoZSBvdGhlcndpc2UgZXF1aXZhbGVudAorICAgICAqIDx0dD5uZXdGaXhlZFRocmVhZFBvb2woMSk8L3R0PiB0aGUgcmV0dXJuZWQgZXhlY3V0b3IgaXMKKyAgICAgKiBndWFyYW50ZWVkIG5vdCB0byBiZSByZWNvbmZpZ3VyYWJsZSB0byB1c2UgYWRkaXRpb25hbCB0aHJlYWRzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV3bHkgY3JlYXRlZCBzaW5nbGUtdGhyZWFkZWQgRXhlY3V0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEV4ZWN1dG9yU2VydmljZSBuZXdTaW5nbGVUaHJlYWRFeGVjdXRvcigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBGaW5hbGl6YWJsZURlbGVnYXRlZEV4ZWN1dG9yU2VydmljZQorICAgICAgICAgICAgKG5ldyBUaHJlYWRQb29sRXhlY3V0b3IoMSwgMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDBMLCBUaW1lVW5pdC5NSUxMSVNFQ09ORFMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTGlua2VkQmxvY2tpbmdRdWV1ZTxSdW5uYWJsZT4oKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gRXhlY3V0b3IgdGhhdCB1c2VzIGEgc2luZ2xlIHdvcmtlciB0aHJlYWQgb3BlcmF0aW5nCisgICAgICogb2ZmIGFuIHVuYm91bmRlZCBxdWV1ZSwgYW5kIHVzZXMgdGhlIHByb3ZpZGVkIFRocmVhZEZhY3RvcnkgdG8KKyAgICAgKiBjcmVhdGUgYSBuZXcgdGhyZWFkIHdoZW4gbmVlZGVkLiBVbmxpa2UgdGhlIG90aGVyd2lzZQorICAgICAqIGVxdWl2YWxlbnQgPHR0Pm5ld0ZpeGVkVGhyZWFkUG9vbCgxLCB0aHJlYWRGYWN0b3J5KTwvdHQ+IHRoZQorICAgICAqIHJldHVybmVkIGV4ZWN1dG9yIGlzIGd1YXJhbnRlZWQgbm90IHRvIGJlIHJlY29uZmlndXJhYmxlIHRvIHVzZQorICAgICAqIGFkZGl0aW9uYWwgdGhyZWFkcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aHJlYWRGYWN0b3J5IHRoZSBmYWN0b3J5IHRvIHVzZSB3aGVuIGNyZWF0aW5nIG5ldworICAgICAqIHRocmVhZHMKKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5ld2x5IGNyZWF0ZWQgc2luZ2xlLXRocmVhZGVkIEV4ZWN1dG9yCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aHJlYWRGYWN0b3J5IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEV4ZWN1dG9yU2VydmljZSBuZXdTaW5nbGVUaHJlYWRFeGVjdXRvcihUaHJlYWRGYWN0b3J5IHRocmVhZEZhY3RvcnkpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBGaW5hbGl6YWJsZURlbGVnYXRlZEV4ZWN1dG9yU2VydmljZQorICAgICAgICAgICAgKG5ldyBUaHJlYWRQb29sRXhlY3V0b3IoMSwgMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDBMLCBUaW1lVW5pdC5NSUxMSVNFQ09ORFMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTGlua2VkQmxvY2tpbmdRdWV1ZTxSdW5uYWJsZT4oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocmVhZEZhY3RvcnkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgdGhyZWFkIHBvb2wgdGhhdCBjcmVhdGVzIG5ldyB0aHJlYWRzIGFzIG5lZWRlZCwgYnV0CisgICAgICogd2lsbCByZXVzZSBwcmV2aW91c2x5IGNvbnN0cnVjdGVkIHRocmVhZHMgd2hlbiB0aGV5IGFyZQorICAgICAqIGF2YWlsYWJsZS4gIFRoZXNlIHBvb2xzIHdpbGwgdHlwaWNhbGx5IGltcHJvdmUgdGhlIHBlcmZvcm1hbmNlCisgICAgICogb2YgcHJvZ3JhbXMgdGhhdCBleGVjdXRlIG1hbnkgc2hvcnQtbGl2ZWQgYXN5bmNocm9ub3VzIHRhc2tzLgorICAgICAqIENhbGxzIHRvIDx0dD5leGVjdXRlPC90dD4gd2lsbCByZXVzZSBwcmV2aW91c2x5IGNvbnN0cnVjdGVkCisgICAgICogdGhyZWFkcyBpZiBhdmFpbGFibGUuIElmIG5vIGV4aXN0aW5nIHRocmVhZCBpcyBhdmFpbGFibGUsIGEgbmV3CisgICAgICogdGhyZWFkIHdpbGwgYmUgY3JlYXRlZCBhbmQgYWRkZWQgdG8gdGhlIHBvb2wuIFRocmVhZHMgdGhhdCBoYXZlCisgICAgICogbm90IGJlZW4gdXNlZCBmb3Igc2l4dHkgc2Vjb25kcyBhcmUgdGVybWluYXRlZCBhbmQgcmVtb3ZlZCBmcm9tCisgICAgICogdGhlIGNhY2hlLiBUaHVzLCBhIHBvb2wgdGhhdCByZW1haW5zIGlkbGUgZm9yIGxvbmcgZW5vdWdoIHdpbGwKKyAgICAgKiBub3QgY29uc3VtZSBhbnkgcmVzb3VyY2VzLiBOb3RlIHRoYXQgcG9vbHMgd2l0aCBzaW1pbGFyCisgICAgICogcHJvcGVydGllcyBidXQgZGlmZmVyZW50IGRldGFpbHMgKGZvciBleGFtcGxlLCB0aW1lb3V0IHBhcmFtZXRlcnMpCisgICAgICogbWF5IGJlIGNyZWF0ZWQgdXNpbmcge0BsaW5rIFRocmVhZFBvb2xFeGVjdXRvcn0gY29uc3RydWN0b3JzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV3bHkgY3JlYXRlZCB0aHJlYWQgcG9vbAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgRXhlY3V0b3JTZXJ2aWNlIG5ld0NhY2hlZFRocmVhZFBvb2woKSB7CisgICAgICAgIHJldHVybiBuZXcgVGhyZWFkUG9vbEV4ZWN1dG9yKDAsIEludGVnZXIuTUFYX1ZBTFVFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA2MEwsIFRpbWVVbml0LlNFQ09ORFMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTeW5jaHJvbm91c1F1ZXVlPFJ1bm5hYmxlPigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgdGhyZWFkIHBvb2wgdGhhdCBjcmVhdGVzIG5ldyB0aHJlYWRzIGFzIG5lZWRlZCwgYnV0CisgICAgICogd2lsbCByZXVzZSBwcmV2aW91c2x5IGNvbnN0cnVjdGVkIHRocmVhZHMgd2hlbiB0aGV5IGFyZQorICAgICAqIGF2YWlsYWJsZSwgYW5kIHVzZXMgdGhlIHByb3ZpZGVkCisgICAgICogVGhyZWFkRmFjdG9yeSB0byBjcmVhdGUgbmV3IHRocmVhZHMgd2hlbiBuZWVkZWQuCisgICAgICogQHBhcmFtIHRocmVhZEZhY3RvcnkgdGhlIGZhY3RvcnkgdG8gdXNlIHdoZW4gY3JlYXRpbmcgbmV3IHRocmVhZHMKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXdseSBjcmVhdGVkIHRocmVhZCBwb29sCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aHJlYWRGYWN0b3J5IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEV4ZWN1dG9yU2VydmljZSBuZXdDYWNoZWRUaHJlYWRQb29sKFRocmVhZEZhY3RvcnkgdGhyZWFkRmFjdG9yeSkgeworICAgICAgICByZXR1cm4gbmV3IFRocmVhZFBvb2xFeGVjdXRvcigwLCBJbnRlZ2VyLk1BWF9WQUxVRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNjBMLCBUaW1lVW5pdC5TRUNPTkRTLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3luY2hyb25vdXNRdWV1ZTxSdW5uYWJsZT4oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyZWFkRmFjdG9yeSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHNpbmdsZS10aHJlYWRlZCBleGVjdXRvciB0aGF0IGNhbiBzY2hlZHVsZSBjb21tYW5kcworICAgICAqIHRvIHJ1biBhZnRlciBhIGdpdmVuIGRlbGF5LCBvciB0byBleGVjdXRlIHBlcmlvZGljYWxseS4KKyAgICAgKiAoTm90ZSBob3dldmVyIHRoYXQgaWYgdGhpcyBzaW5nbGUKKyAgICAgKiB0aHJlYWQgdGVybWluYXRlcyBkdWUgdG8gYSBmYWlsdXJlIGR1cmluZyBleGVjdXRpb24gcHJpb3IgdG8KKyAgICAgKiBzaHV0ZG93biwgYSBuZXcgb25lIHdpbGwgdGFrZSBpdHMgcGxhY2UgaWYgbmVlZGVkIHRvIGV4ZWN1dGUKKyAgICAgKiBzdWJzZXF1ZW50IHRhc2tzLikgIFRhc2tzIGFyZSBndWFyYW50ZWVkIHRvIGV4ZWN1dGUKKyAgICAgKiBzZXF1ZW50aWFsbHksIGFuZCBubyBtb3JlIHRoYW4gb25lIHRhc2sgd2lsbCBiZSBhY3RpdmUgYXQgYW55CisgICAgICogZ2l2ZW4gdGltZS4gVW5saWtlIHRoZSBvdGhlcndpc2UgZXF1aXZhbGVudAorICAgICAqIDx0dD5uZXdTY2hlZHVsZWRUaHJlYWRQb29sKDEpPC90dD4gdGhlIHJldHVybmVkIGV4ZWN1dG9yIGlzCisgICAgICogZ3VhcmFudGVlZCBub3QgdG8gYmUgcmVjb25maWd1cmFibGUgdG8gdXNlIGFkZGl0aW9uYWwgdGhyZWFkcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXdseSBjcmVhdGVkIHNjaGVkdWxlZCBleGVjdXRvcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlIG5ld1NpbmdsZVRocmVhZFNjaGVkdWxlZEV4ZWN1dG9yKCkgeworICAgICAgICByZXR1cm4gbmV3IERlbGVnYXRlZFNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZQorICAgICAgICAgICAgKG5ldyBTY2hlZHVsZWRUaHJlYWRQb29sRXhlY3V0b3IoMSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBzaW5nbGUtdGhyZWFkZWQgZXhlY3V0b3IgdGhhdCBjYW4gc2NoZWR1bGUgY29tbWFuZHMKKyAgICAgKiB0byBydW4gYWZ0ZXIgYSBnaXZlbiBkZWxheSwgb3IgdG8gZXhlY3V0ZSBwZXJpb2RpY2FsbHkuICAoTm90ZQorICAgICAqIGhvd2V2ZXIgdGhhdCBpZiB0aGlzIHNpbmdsZSB0aHJlYWQgdGVybWluYXRlcyBkdWUgdG8gYSBmYWlsdXJlCisgICAgICogZHVyaW5nIGV4ZWN1dGlvbiBwcmlvciB0byBzaHV0ZG93biwgYSBuZXcgb25lIHdpbGwgdGFrZSBpdHMKKyAgICAgKiBwbGFjZSBpZiBuZWVkZWQgdG8gZXhlY3V0ZSBzdWJzZXF1ZW50IHRhc2tzLikgIFRhc2tzIGFyZQorICAgICAqIGd1YXJhbnRlZWQgdG8gZXhlY3V0ZSBzZXF1ZW50aWFsbHksIGFuZCBubyBtb3JlIHRoYW4gb25lIHRhc2sKKyAgICAgKiB3aWxsIGJlIGFjdGl2ZSBhdCBhbnkgZ2l2ZW4gdGltZS4gVW5saWtlIHRoZSBvdGhlcndpc2UKKyAgICAgKiBlcXVpdmFsZW50IDx0dD5uZXdTY2hlZHVsZWRUaHJlYWRQb29sKDEsIHRocmVhZEZhY3RvcnkpPC90dD4KKyAgICAgKiB0aGUgcmV0dXJuZWQgZXhlY3V0b3IgaXMgZ3VhcmFudGVlZCBub3QgdG8gYmUgcmVjb25maWd1cmFibGUgdG8KKyAgICAgKiB1c2UgYWRkaXRpb25hbCB0aHJlYWRzLgorICAgICAqIEBwYXJhbSB0aHJlYWRGYWN0b3J5IHRoZSBmYWN0b3J5IHRvIHVzZSB3aGVuIGNyZWF0aW5nIG5ldworICAgICAqIHRocmVhZHMKKyAgICAgKiBAcmV0dXJuIGEgbmV3bHkgY3JlYXRlZCBzY2hlZHVsZWQgZXhlY3V0b3IKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRocmVhZEZhY3RvcnkgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlIG5ld1NpbmdsZVRocmVhZFNjaGVkdWxlZEV4ZWN1dG9yKFRocmVhZEZhY3RvcnkgdGhyZWFkRmFjdG9yeSkgeworICAgICAgICByZXR1cm4gbmV3IERlbGVnYXRlZFNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZQorICAgICAgICAgICAgKG5ldyBTY2hlZHVsZWRUaHJlYWRQb29sRXhlY3V0b3IoMSwgdGhyZWFkRmFjdG9yeSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB0aHJlYWQgcG9vbCB0aGF0IGNhbiBzY2hlZHVsZSBjb21tYW5kcyB0byBydW4gYWZ0ZXIgYQorICAgICAqIGdpdmVuIGRlbGF5LCBvciB0byBleGVjdXRlIHBlcmlvZGljYWxseS4KKyAgICAgKiBAcGFyYW0gY29yZVBvb2xTaXplIHRoZSBudW1iZXIgb2YgdGhyZWFkcyB0byBrZWVwIGluIHRoZSBwb29sLAorICAgICAqIGV2ZW4gaWYgdGhleSBhcmUgaWRsZS4KKyAgICAgKiBAcmV0dXJuIGEgbmV3bHkgY3JlYXRlZCBzY2hlZHVsZWQgdGhyZWFkIHBvb2wKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgY29yZVBvb2xTaXplIDwgMH0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZSBuZXdTY2hlZHVsZWRUaHJlYWRQb29sKGludCBjb3JlUG9vbFNpemUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTY2hlZHVsZWRUaHJlYWRQb29sRXhlY3V0b3IoY29yZVBvb2xTaXplKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgdGhyZWFkIHBvb2wgdGhhdCBjYW4gc2NoZWR1bGUgY29tbWFuZHMgdG8gcnVuIGFmdGVyIGEKKyAgICAgKiBnaXZlbiBkZWxheSwgb3IgdG8gZXhlY3V0ZSBwZXJpb2RpY2FsbHkuCisgICAgICogQHBhcmFtIGNvcmVQb29sU2l6ZSB0aGUgbnVtYmVyIG9mIHRocmVhZHMgdG8ga2VlcCBpbiB0aGUgcG9vbCwKKyAgICAgKiBldmVuIGlmIHRoZXkgYXJlIGlkbGUuCisgICAgICogQHBhcmFtIHRocmVhZEZhY3RvcnkgdGhlIGZhY3RvcnkgdG8gdXNlIHdoZW4gdGhlIGV4ZWN1dG9yCisgICAgICogY3JlYXRlcyBhIG5ldyB0aHJlYWQuCisgICAgICogQHJldHVybiBhIG5ld2x5IGNyZWF0ZWQgc2NoZWR1bGVkIHRocmVhZCBwb29sCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGNvcmVQb29sU2l6ZSA8IDB9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aHJlYWRGYWN0b3J5IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZSBuZXdTY2hlZHVsZWRUaHJlYWRQb29sKAorICAgICAgICAgICAgaW50IGNvcmVQb29sU2l6ZSwgVGhyZWFkRmFjdG9yeSB0aHJlYWRGYWN0b3J5KSB7CisgICAgICAgIHJldHVybiBuZXcgU2NoZWR1bGVkVGhyZWFkUG9vbEV4ZWN1dG9yKGNvcmVQb29sU2l6ZSwgdGhyZWFkRmFjdG9yeSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIG9iamVjdCB0aGF0IGRlbGVnYXRlcyBhbGwgZGVmaW5lZCB7QGxpbmsKKyAgICAgKiBFeGVjdXRvclNlcnZpY2V9IG1ldGhvZHMgdG8gdGhlIGdpdmVuIGV4ZWN1dG9yLCBidXQgbm90IGFueQorICAgICAqIG90aGVyIG1ldGhvZHMgdGhhdCBtaWdodCBvdGhlcndpc2UgYmUgYWNjZXNzaWJsZSB1c2luZworICAgICAqIGNhc3RzLiBUaGlzIHByb3ZpZGVzIGEgd2F5IHRvIHNhZmVseSAiZnJlZXplIiBjb25maWd1cmF0aW9uIGFuZAorICAgICAqIGRpc2FsbG93IHR1bmluZyBvZiBhIGdpdmVuIGNvbmNyZXRlIGltcGxlbWVudGF0aW9uLgorICAgICAqIEBwYXJhbSBleGVjdXRvciB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbgorICAgICAqIEByZXR1cm4gYW4gPHR0PkV4ZWN1dG9yU2VydmljZTwvdHQ+IGluc3RhbmNlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBleGVjdXRvciBudWxsCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBFeGVjdXRvclNlcnZpY2UgdW5jb25maWd1cmFibGVFeGVjdXRvclNlcnZpY2UoRXhlY3V0b3JTZXJ2aWNlIGV4ZWN1dG9yKSB7CisgICAgICAgIGlmIChleGVjdXRvciA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiBuZXcgRGVsZWdhdGVkRXhlY3V0b3JTZXJ2aWNlKGV4ZWN1dG9yKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIG9iamVjdCB0aGF0IGRlbGVnYXRlcyBhbGwgZGVmaW5lZCB7QGxpbmsKKyAgICAgKiBTY2hlZHVsZWRFeGVjdXRvclNlcnZpY2V9IG1ldGhvZHMgdG8gdGhlIGdpdmVuIGV4ZWN1dG9yLCBidXQKKyAgICAgKiBub3QgYW55IG90aGVyIG1ldGhvZHMgdGhhdCBtaWdodCBvdGhlcndpc2UgYmUgYWNjZXNzaWJsZSB1c2luZworICAgICAqIGNhc3RzLiBUaGlzIHByb3ZpZGVzIGEgd2F5IHRvIHNhZmVseSAiZnJlZXplIiBjb25maWd1cmF0aW9uIGFuZAorICAgICAqIGRpc2FsbG93IHR1bmluZyBvZiBhIGdpdmVuIGNvbmNyZXRlIGltcGxlbWVudGF0aW9uLgorICAgICAqIEBwYXJhbSBleGVjdXRvciB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbgorICAgICAqIEByZXR1cm4gYSA8dHQ+U2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlPC90dD4gaW5zdGFuY2UKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGV4ZWN1dG9yIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZSB1bmNvbmZpZ3VyYWJsZVNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZShTY2hlZHVsZWRFeGVjdXRvclNlcnZpY2UgZXhlY3V0b3IpIHsKKyAgICAgICAgaWYgKGV4ZWN1dG9yID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgcmV0dXJuIG5ldyBEZWxlZ2F0ZWRTY2hlZHVsZWRFeGVjdXRvclNlcnZpY2UoZXhlY3V0b3IpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBkZWZhdWx0IHRocmVhZCBmYWN0b3J5IHVzZWQgdG8gY3JlYXRlIG5ldyB0aHJlYWRzLgorICAgICAqIFRoaXMgZmFjdG9yeSBjcmVhdGVzIGFsbCBuZXcgdGhyZWFkcyB1c2VkIGJ5IGFuIEV4ZWN1dG9yIGluIHRoZQorICAgICAqIHNhbWUge0BsaW5rIFRocmVhZEdyb3VwfS4gSWYgdGhlcmUgaXMgYSB7QGxpbmsKKyAgICAgKiBqYXZhLmxhbmcuU2VjdXJpdHlNYW5hZ2VyfSwgaXQgdXNlcyB0aGUgZ3JvdXAgb2Yge0BsaW5rCisgICAgICogU3lzdGVtI2dldFNlY3VyaXR5TWFuYWdlcn0sIGVsc2UgdGhlIGdyb3VwIG9mIHRoZSB0aHJlYWQKKyAgICAgKiBpbnZva2luZyB0aGlzIDx0dD5kZWZhdWx0VGhyZWFkRmFjdG9yeTwvdHQ+IG1ldGhvZC4gRWFjaCBuZXcKKyAgICAgKiB0aHJlYWQgaXMgY3JlYXRlZCBhcyBhIG5vbi1kYWVtb24gdGhyZWFkIHdpdGggcHJpb3JpdHkgc2V0IHRvCisgICAgICogdGhlIHNtYWxsZXIgb2YgPHR0PlRocmVhZC5OT1JNX1BSSU9SSVRZPC90dD4gYW5kIHRoZSBtYXhpbXVtCisgICAgICogcHJpb3JpdHkgcGVybWl0dGVkIGluIHRoZSB0aHJlYWQgZ3JvdXAuICBOZXcgdGhyZWFkcyBoYXZlIG5hbWVzCisgICAgICogYWNjZXNzaWJsZSB2aWEge0BsaW5rIFRocmVhZCNnZXROYW1lfSBvZgorICAgICAqIDxlbT5wb29sLU4tdGhyZWFkLU08L2VtPiwgd2hlcmUgPGVtPk48L2VtPiBpcyB0aGUgc2VxdWVuY2UKKyAgICAgKiBudW1iZXIgb2YgdGhpcyBmYWN0b3J5LCBhbmQgPGVtPk08L2VtPiBpcyB0aGUgc2VxdWVuY2UgbnVtYmVyCisgICAgICogb2YgdGhlIHRocmVhZCBjcmVhdGVkIGJ5IHRoaXMgZmFjdG9yeS4KKyAgICAgKiBAcmV0dXJuIGEgdGhyZWFkIGZhY3RvcnkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFRocmVhZEZhY3RvcnkgZGVmYXVsdFRocmVhZEZhY3RvcnkoKSB7CisgICAgICAgIHJldHVybiBuZXcgRGVmYXVsdFRocmVhZEZhY3RvcnkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgdGhyZWFkIGZhY3RvcnkgdXNlZCB0byBjcmVhdGUgbmV3IHRocmVhZHMgdGhhdAorICAgICAqIGhhdmUgdGhlIHNhbWUgcGVybWlzc2lvbnMgYXMgdGhlIGN1cnJlbnQgdGhyZWFkLgorICAgICAqIFRoaXMgZmFjdG9yeSBjcmVhdGVzIHRocmVhZHMgd2l0aCB0aGUgc2FtZSBzZXR0aW5ncyBhcyB7QGxpbmsKKyAgICAgKiBFeGVjdXRvcnMjZGVmYXVsdFRocmVhZEZhY3Rvcnl9LCBhZGRpdGlvbmFsbHkgc2V0dGluZyB0aGUKKyAgICAgKiBBY2Nlc3NDb250cm9sQ29udGV4dCBhbmQgY29udGV4dENsYXNzTG9hZGVyIG9mIG5ldyB0aHJlYWRzIHRvCisgICAgICogYmUgdGhlIHNhbWUgYXMgdGhlIHRocmVhZCBpbnZva2luZyB0aGlzCisgICAgICogPHR0PnByaXZpbGVnZWRUaHJlYWRGYWN0b3J5PC90dD4gbWV0aG9kLiAgQSBuZXcKKyAgICAgKiA8dHQ+cHJpdmlsZWdlZFRocmVhZEZhY3Rvcnk8L3R0PiBjYW4gYmUgY3JlYXRlZCB3aXRoaW4gYW4KKyAgICAgKiB7QGxpbmsgQWNjZXNzQ29udHJvbGxlciNkb1ByaXZpbGVnZWR9IGFjdGlvbiBzZXR0aW5nIHRoZQorICAgICAqIGN1cnJlbnQgdGhyZWFkJ3MgYWNjZXNzIGNvbnRyb2wgY29udGV4dCB0byBjcmVhdGUgdGhyZWFkcyB3aXRoCisgICAgICogdGhlIHNlbGVjdGVkIHBlcm1pc3Npb24gc2V0dGluZ3MgaG9sZGluZyB3aXRoaW4gdGhhdCBhY3Rpb24uCisgICAgICoKKyAgICAgKiA8cD4gTm90ZSB0aGF0IHdoaWxlIHRhc2tzIHJ1bm5pbmcgd2l0aGluIHN1Y2ggdGhyZWFkcyB3aWxsIGhhdmUKKyAgICAgKiB0aGUgc2FtZSBhY2Nlc3MgY29udHJvbCBhbmQgY2xhc3MgbG9hZGVyIHNldHRpbmdzIGFzIHRoZQorICAgICAqIGN1cnJlbnQgdGhyZWFkLCB0aGV5IG5lZWQgbm90IGhhdmUgdGhlIHNhbWUge0BsaW5rCisgICAgICogamF2YS5sYW5nLlRocmVhZExvY2FsfSBvciB7QGxpbmsKKyAgICAgKiBqYXZhLmxhbmcuSW5oZXJpdGFibGVUaHJlYWRMb2NhbH0gdmFsdWVzLiBJZiBuZWNlc3NhcnksCisgICAgICogcGFydGljdWxhciB2YWx1ZXMgb2YgdGhyZWFkIGxvY2FscyBjYW4gYmUgc2V0IG9yIHJlc2V0IGJlZm9yZQorICAgICAqIGFueSB0YXNrIHJ1bnMgaW4ge0BsaW5rIFRocmVhZFBvb2xFeGVjdXRvcn0gc3ViY2xhc3NlcyB1c2luZworICAgICAqIHtAbGluayBUaHJlYWRQb29sRXhlY3V0b3IjYmVmb3JlRXhlY3V0ZX0uIEFsc28sIGlmIGl0IGlzCisgICAgICogbmVjZXNzYXJ5IHRvIGluaXRpYWxpemUgd29ya2VyIHRocmVhZHMgdG8gaGF2ZSB0aGUgc2FtZQorICAgICAqIEluaGVyaXRhYmxlVGhyZWFkTG9jYWwgc2V0dGluZ3MgYXMgc29tZSBvdGhlciBkZXNpZ25hdGVkCisgICAgICogdGhyZWFkLCB5b3UgY2FuIGNyZWF0ZSBhIGN1c3RvbSBUaHJlYWRGYWN0b3J5IGluIHdoaWNoIHRoYXQKKyAgICAgKiB0aHJlYWQgd2FpdHMgZm9yIGFuZCBzZXJ2aWNlcyByZXF1ZXN0cyB0byBjcmVhdGUgb3RoZXJzIHRoYXQKKyAgICAgKiB3aWxsIGluaGVyaXQgaXRzIHZhbHVlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSB0aHJlYWQgZmFjdG9yeQorICAgICAqIEB0aHJvd3MgQWNjZXNzQ29udHJvbEV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCBhY2Nlc3MgY29udHJvbAorICAgICAqIGNvbnRleHQgZG9lcyBub3QgaGF2ZSBwZXJtaXNzaW9uIHRvIGJvdGggZ2V0IGFuZCBzZXQgY29udGV4dAorICAgICAqIGNsYXNzIGxvYWRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFRocmVhZEZhY3RvcnkgcHJpdmlsZWdlZFRocmVhZEZhY3RvcnkoKSB7CisgICAgICAgIHJldHVybiBuZXcgUHJpdmlsZWdlZFRocmVhZEZhY3RvcnkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0BsaW5rIENhbGxhYmxlfSBvYmplY3QgdGhhdCwgd2hlbgorICAgICAqIGNhbGxlZCwgcnVucyB0aGUgZ2l2ZW4gdGFzayBhbmQgcmV0dXJucyB0aGUgZ2l2ZW4gcmVzdWx0LiAgVGhpcworICAgICAqIGNhbiBiZSB1c2VmdWwgd2hlbiBhcHBseWluZyBtZXRob2RzIHJlcXVpcmluZyBhCisgICAgICogPHR0PkNhbGxhYmxlPC90dD4gdG8gYW4gb3RoZXJ3aXNlIHJlc3VsdGxlc3MgYWN0aW9uLgorICAgICAqIEBwYXJhbSB0YXNrIHRoZSB0YXNrIHRvIHJ1bgorICAgICAqIEBwYXJhbSByZXN1bHQgdGhlIHJlc3VsdCB0byByZXR1cm4KKyAgICAgKiBAcmV0dXJuIGEgY2FsbGFibGUgb2JqZWN0CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0YXNrIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUPiBDYWxsYWJsZTxUPiBjYWxsYWJsZShSdW5uYWJsZSB0YXNrLCBUIHJlc3VsdCkgeworICAgICAgICBpZiAodGFzayA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiBuZXcgUnVubmFibGVBZGFwdGVyPFQ+KHRhc2ssIHJlc3VsdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAbGluayBDYWxsYWJsZX0gb2JqZWN0IHRoYXQsIHdoZW4KKyAgICAgKiBjYWxsZWQsIHJ1bnMgdGhlIGdpdmVuIHRhc2sgYW5kIHJldHVybnMgPHR0Pm51bGw8L3R0Pi4KKyAgICAgKiBAcGFyYW0gdGFzayB0aGUgdGFzayB0byBydW4KKyAgICAgKiBAcmV0dXJuIGEgY2FsbGFibGUgb2JqZWN0CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0YXNrIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIENhbGxhYmxlPE9iamVjdD4gY2FsbGFibGUoUnVubmFibGUgdGFzaykgeworICAgICAgICBpZiAodGFzayA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiBuZXcgUnVubmFibGVBZGFwdGVyPE9iamVjdD4odGFzaywgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAbGluayBDYWxsYWJsZX0gb2JqZWN0IHRoYXQsIHdoZW4KKyAgICAgKiBjYWxsZWQsIHJ1bnMgdGhlIGdpdmVuIHByaXZpbGVnZWQgYWN0aW9uIGFuZCByZXR1cm5zIGl0cyByZXN1bHQuCisgICAgICogQHBhcmFtIGFjdGlvbiB0aGUgcHJpdmlsZWdlZCBhY3Rpb24gdG8gcnVuCisgICAgICogQHJldHVybiBhIGNhbGxhYmxlIG9iamVjdAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgYWN0aW9uIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIENhbGxhYmxlPE9iamVjdD4gY2FsbGFibGUoZmluYWwgUHJpdmlsZWdlZEFjdGlvbjw/PiBhY3Rpb24pIHsKKyAgICAgICAgaWYgKGFjdGlvbiA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiBuZXcgQ2FsbGFibGU8T2JqZWN0PigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgY2FsbCgpIHsgcmV0dXJuIGFjdGlvbi5ydW4oKTsgfX07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAbGluayBDYWxsYWJsZX0gb2JqZWN0IHRoYXQsIHdoZW4KKyAgICAgKiBjYWxsZWQsIHJ1bnMgdGhlIGdpdmVuIHByaXZpbGVnZWQgZXhjZXB0aW9uIGFjdGlvbiBhbmQgcmV0dXJucworICAgICAqIGl0cyByZXN1bHQuCisgICAgICogQHBhcmFtIGFjdGlvbiB0aGUgcHJpdmlsZWdlZCBleGNlcHRpb24gYWN0aW9uIHRvIHJ1bgorICAgICAqIEByZXR1cm4gYSBjYWxsYWJsZSBvYmplY3QKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGFjdGlvbiBudWxsCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDYWxsYWJsZTxPYmplY3Q+IGNhbGxhYmxlKGZpbmFsIFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb248Pz4gYWN0aW9uKSB7CisgICAgICAgIGlmIChhY3Rpb24gPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICByZXR1cm4gbmV3IENhbGxhYmxlPE9iamVjdD4oKSB7CisgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IGNhbGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsgcmV0dXJuIGFjdGlvbi5ydW4oKTsgfX07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAbGluayBDYWxsYWJsZX0gb2JqZWN0IHRoYXQgd2lsbCwgd2hlbgorICAgICAqIGNhbGxlZCwgZXhlY3V0ZSB0aGUgZ2l2ZW4gPHR0PmNhbGxhYmxlPC90dD4gdW5kZXIgdGhlIGN1cnJlbnQKKyAgICAgKiBhY2Nlc3MgY29udHJvbCBjb250ZXh0LiBUaGlzIG1ldGhvZCBzaG91bGQgbm9ybWFsbHkgYmUKKyAgICAgKiBpbnZva2VkIHdpdGhpbiBhbiB7QGxpbmsgQWNjZXNzQ29udHJvbGxlciNkb1ByaXZpbGVnZWR9IGFjdGlvbgorICAgICAqIHRvIGNyZWF0ZSBjYWxsYWJsZXMgdGhhdCB3aWxsLCBpZiBwb3NzaWJsZSwgZXhlY3V0ZSB1bmRlciB0aGUKKyAgICAgKiBzZWxlY3RlZCBwZXJtaXNzaW9uIHNldHRpbmdzIGhvbGRpbmcgd2l0aGluIHRoYXQgYWN0aW9uOyBvciBpZgorICAgICAqIG5vdCBwb3NzaWJsZSwgdGhyb3cgYW4gYXNzb2NpYXRlZCB7QGxpbmsKKyAgICAgKiBBY2Nlc3NDb250cm9sRXhjZXB0aW9ufS4KKyAgICAgKiBAcGFyYW0gY2FsbGFibGUgdGhlIHVuZGVybHlpbmcgdGFzaworICAgICAqIEByZXR1cm4gYSBjYWxsYWJsZSBvYmplY3QKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGNhbGxhYmxlIG51bGwKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFQ+IENhbGxhYmxlPFQ+IHByaXZpbGVnZWRDYWxsYWJsZShDYWxsYWJsZTxUPiBjYWxsYWJsZSkgeworICAgICAgICBpZiAoY2FsbGFibGUgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICByZXR1cm4gbmV3IFByaXZpbGVnZWRDYWxsYWJsZTxUPihjYWxsYWJsZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAbGluayBDYWxsYWJsZX0gb2JqZWN0IHRoYXQgd2lsbCwgd2hlbgorICAgICAqIGNhbGxlZCwgZXhlY3V0ZSB0aGUgZ2l2ZW4gPHR0PmNhbGxhYmxlPC90dD4gdW5kZXIgdGhlIGN1cnJlbnQKKyAgICAgKiBhY2Nlc3MgY29udHJvbCBjb250ZXh0LCB3aXRoIHRoZSBjdXJyZW50IGNvbnRleHQgY2xhc3MgbG9hZGVyCisgICAgICogYXMgdGhlIGNvbnRleHQgY2xhc3MgbG9hZGVyLiBUaGlzIG1ldGhvZCBzaG91bGQgbm9ybWFsbHkgYmUKKyAgICAgKiBpbnZva2VkIHdpdGhpbiBhbiB7QGxpbmsgQWNjZXNzQ29udHJvbGxlciNkb1ByaXZpbGVnZWR9IGFjdGlvbgorICAgICAqIHRvIGNyZWF0ZSBjYWxsYWJsZXMgdGhhdCB3aWxsLCBpZiBwb3NzaWJsZSwgZXhlY3V0ZSB1bmRlciB0aGUKKyAgICAgKiBzZWxlY3RlZCBwZXJtaXNzaW9uIHNldHRpbmdzIGhvbGRpbmcgd2l0aGluIHRoYXQgYWN0aW9uOyBvciBpZgorICAgICAqIG5vdCBwb3NzaWJsZSwgdGhyb3cgYW4gYXNzb2NpYXRlZCB7QGxpbmsKKyAgICAgKiBBY2Nlc3NDb250cm9sRXhjZXB0aW9ufS4KKyAgICAgKiBAcGFyYW0gY2FsbGFibGUgdGhlIHVuZGVybHlpbmcgdGFzaworICAgICAqCisgICAgICogQHJldHVybiBhIGNhbGxhYmxlIG9iamVjdAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgY2FsbGFibGUgbnVsbAorICAgICAqIEB0aHJvd3MgQWNjZXNzQ29udHJvbEV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCBhY2Nlc3MgY29udHJvbAorICAgICAqIGNvbnRleHQgZG9lcyBub3QgaGF2ZSBwZXJtaXNzaW9uIHRvIGJvdGggc2V0IGFuZCBnZXQgY29udGV4dAorICAgICAqIGNsYXNzIGxvYWRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUPiBDYWxsYWJsZTxUPiBwcml2aWxlZ2VkQ2FsbGFibGVVc2luZ0N1cnJlbnRDbGFzc0xvYWRlcihDYWxsYWJsZTxUPiBjYWxsYWJsZSkgeworICAgICAgICBpZiAoY2FsbGFibGUgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICByZXR1cm4gbmV3IFByaXZpbGVnZWRDYWxsYWJsZVVzaW5nQ3VycmVudENsYXNzTG9hZGVyPFQ+KGNhbGxhYmxlKTsKKyAgICB9CisKKyAgICAvLyBOb24tcHVibGljIGNsYXNzZXMgc3VwcG9ydGluZyB0aGUgcHVibGljIG1ldGhvZHMKKworICAgIC8qKgorICAgICAqIEEgY2FsbGFibGUgdGhhdCBydW5zIGdpdmVuIHRhc2sgYW5kIHJldHVybnMgZ2l2ZW4gcmVzdWx0CisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIFJ1bm5hYmxlQWRhcHRlcjxUPiBpbXBsZW1lbnRzIENhbGxhYmxlPFQ+IHsKKyAgICAgICAgZmluYWwgUnVubmFibGUgdGFzazsKKyAgICAgICAgZmluYWwgVCByZXN1bHQ7CisgICAgICAgIFJ1bm5hYmxlQWRhcHRlcihSdW5uYWJsZSB0YXNrLCBUIHJlc3VsdCkgeworICAgICAgICAgICAgdGhpcy50YXNrID0gdGFzazsKKyAgICAgICAgICAgIHRoaXMucmVzdWx0ID0gcmVzdWx0OworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBUIGNhbGwoKSB7CisgICAgICAgICAgICB0YXNrLnJ1bigpOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEEgY2FsbGFibGUgdGhhdCBydW5zIHVuZGVyIGVzdGFibGlzaGVkIGFjY2VzcyBjb250cm9sIHNldHRpbmdzCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIFByaXZpbGVnZWRDYWxsYWJsZTxUPiBpbXBsZW1lbnRzIENhbGxhYmxlPFQ+IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBDYWxsYWJsZTxUPiB0YXNrOworICAgICAgICBwcml2YXRlIGZpbmFsIEFjY2Vzc0NvbnRyb2xDb250ZXh0IGFjYzsKKworICAgICAgICBQcml2aWxlZ2VkQ2FsbGFibGUoQ2FsbGFibGU8VD4gdGFzaykgeworICAgICAgICAgICAgdGhpcy50YXNrID0gdGFzazsKKyAgICAgICAgICAgIHRoaXMuYWNjID0gQWNjZXNzQ29udHJvbGxlci5nZXRDb250ZXh0KCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgVCBjYWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZCgKKyAgICAgICAgICAgICAgICAgICAgbmV3IFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb248VD4oKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgVCBydW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFzay5jYWxsKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0sIGFjYyk7CisgICAgICAgICAgICB9IGNhdGNoIChQcml2aWxlZ2VkQWN0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBlLmdldEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBjYWxsYWJsZSB0aGF0IHJ1bnMgdW5kZXIgZXN0YWJsaXNoZWQgYWNjZXNzIGNvbnRyb2wgc2V0dGluZ3MgYW5kCisgICAgICogY3VycmVudCBDbGFzc0xvYWRlcgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBQcml2aWxlZ2VkQ2FsbGFibGVVc2luZ0N1cnJlbnRDbGFzc0xvYWRlcjxUPiBpbXBsZW1lbnRzIENhbGxhYmxlPFQ+IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBDYWxsYWJsZTxUPiB0YXNrOworICAgICAgICBwcml2YXRlIGZpbmFsIEFjY2Vzc0NvbnRyb2xDb250ZXh0IGFjYzsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBDbGFzc0xvYWRlciBjY2w7CisKKyAgICAgICAgUHJpdmlsZWdlZENhbGxhYmxlVXNpbmdDdXJyZW50Q2xhc3NMb2FkZXIoQ2FsbGFibGU8VD4gdGFzaykgeworICAgICAgICAgICAgU2VjdXJpdHlNYW5hZ2VyIHNtID0gU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpOworICAgICAgICAgICAgaWYgKHNtICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyBDYWxscyB0byBnZXRDb250ZXh0Q2xhc3NMb2FkZXIgZnJvbSB0aGlzIGNsYXNzCisgICAgICAgICAgICAgICAgLy8gbmV2ZXIgdHJpZ2dlciBhIHNlY3VyaXR5IGNoZWNrLCBidXQgd2UgY2hlY2sKKyAgICAgICAgICAgICAgICAvLyB3aGV0aGVyIG91ciBjYWxsZXJzIGhhdmUgdGhpcyBwZXJtaXNzaW9uIGFueXdheXMuCisgICAgICAgICAgICAgICAgc20uY2hlY2tQZXJtaXNzaW9uKG5ldyBSdW50aW1lUGVybWlzc2lvbigiZ2V0Q29udGV4dENsYXNzTG9hZGVyIikpOyAvLyBhbmRyb2lkLWNoYW5nZWQKKworICAgICAgICAgICAgICAgIC8vIFdoZXRoZXIgc2V0Q29udGV4dENsYXNzTG9hZGVyIHR1cm5zIG91dCB0byBiZSBuZWNlc3NhcnkKKyAgICAgICAgICAgICAgICAvLyBvciBub3QsIHdlIGZhaWwgZmFzdCBpZiBwZXJtaXNzaW9uIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICAgICAgICAgICAgc20uY2hlY2tQZXJtaXNzaW9uKG5ldyBSdW50aW1lUGVybWlzc2lvbigic2V0Q29udGV4dENsYXNzTG9hZGVyIikpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy50YXNrID0gdGFzazsKKyAgICAgICAgICAgIHRoaXMuYWNjID0gQWNjZXNzQ29udHJvbGxlci5nZXRDb250ZXh0KCk7CisgICAgICAgICAgICB0aGlzLmNjbCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgVCBjYWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZCgKKyAgICAgICAgICAgICAgICAgICAgbmV3IFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb248VD4oKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgVCBydW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzc0xvYWRlciBzYXZlZGNsID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaHJlYWQgdCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NMb2FkZXIgY2wgPSB0LmdldENvbnRleHRDbGFzc0xvYWRlcigpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2NsICE9IGNsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LnNldENvbnRleHRDbGFzc0xvYWRlcihjY2wpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2F2ZWRjbCA9IGNsOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0YXNrLmNhbGwoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2F2ZWRjbCAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC5zZXRDb250ZXh0Q2xhc3NMb2FkZXIoc2F2ZWRjbCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9LCBhY2MpOworICAgICAgICAgICAgfSBjYXRjaCAoUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgZS5nZXRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBkZWZhdWx0IHRocmVhZCBmYWN0b3J5CisgICAgICovCisgICAgc3RhdGljIGNsYXNzIERlZmF1bHRUaHJlYWRGYWN0b3J5IGltcGxlbWVudHMgVGhyZWFkRmFjdG9yeSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEF0b21pY0ludGVnZXIgcG9vbE51bWJlciA9IG5ldyBBdG9taWNJbnRlZ2VyKDEpOworICAgICAgICBwcml2YXRlIGZpbmFsIFRocmVhZEdyb3VwIGdyb3VwOworICAgICAgICBwcml2YXRlIGZpbmFsIEF0b21pY0ludGVnZXIgdGhyZWFkTnVtYmVyID0gbmV3IEF0b21pY0ludGVnZXIoMSk7CisgICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG5hbWVQcmVmaXg7CisKKyAgICAgICAgRGVmYXVsdFRocmVhZEZhY3RvcnkoKSB7CisgICAgICAgICAgICBTZWN1cml0eU1hbmFnZXIgcyA9IFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKTsKKyAgICAgICAgICAgIGdyb3VwID0gKHMgIT0gbnVsbCkgPyBzLmdldFRocmVhZEdyb3VwKCkgOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0VGhyZWFkR3JvdXAoKTsKKyAgICAgICAgICAgIG5hbWVQcmVmaXggPSAicG9vbC0iICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcG9vbE51bWJlci5nZXRBbmRJbmNyZW1lbnQoKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgIi10aHJlYWQtIjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBUaHJlYWQgbmV3VGhyZWFkKFJ1bm5hYmxlIHIpIHsKKyAgICAgICAgICAgIFRocmVhZCB0ID0gbmV3IFRocmVhZChncm91cCwgciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lUHJlZml4ICsgdGhyZWFkTnVtYmVyLmdldEFuZEluY3JlbWVudCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApOworICAgICAgICAgICAgaWYgKHQuaXNEYWVtb24oKSkKKyAgICAgICAgICAgICAgICB0LnNldERhZW1vbihmYWxzZSk7CisgICAgICAgICAgICBpZiAodC5nZXRQcmlvcml0eSgpICE9IFRocmVhZC5OT1JNX1BSSU9SSVRZKQorICAgICAgICAgICAgICAgIHQuc2V0UHJpb3JpdHkoVGhyZWFkLk5PUk1fUFJJT1JJVFkpOworICAgICAgICAgICAgcmV0dXJuIHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaHJlYWQgZmFjdG9yeSBjYXB0dXJpbmcgYWNjZXNzIGNvbnRyb2wgY29udGV4dCBhbmQgY2xhc3MgbG9hZGVyCisgICAgICovCisgICAgc3RhdGljIGNsYXNzIFByaXZpbGVnZWRUaHJlYWRGYWN0b3J5IGV4dGVuZHMgRGVmYXVsdFRocmVhZEZhY3RvcnkgeworICAgICAgICBwcml2YXRlIGZpbmFsIEFjY2Vzc0NvbnRyb2xDb250ZXh0IGFjYzsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBDbGFzc0xvYWRlciBjY2w7CisKKyAgICAgICAgUHJpdmlsZWdlZFRocmVhZEZhY3RvcnkoKSB7CisgICAgICAgICAgICBzdXBlcigpOworICAgICAgICAgICAgU2VjdXJpdHlNYW5hZ2VyIHNtID0gU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpOworICAgICAgICAgICAgaWYgKHNtICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyBDYWxscyB0byBnZXRDb250ZXh0Q2xhc3NMb2FkZXIgZnJvbSB0aGlzIGNsYXNzCisgICAgICAgICAgICAgICAgLy8gbmV2ZXIgdHJpZ2dlciBhIHNlY3VyaXR5IGNoZWNrLCBidXQgd2UgY2hlY2sKKyAgICAgICAgICAgICAgICAvLyB3aGV0aGVyIG91ciBjYWxsZXJzIGhhdmUgdGhpcyBwZXJtaXNzaW9uIGFueXdheXMuCisgICAgICAgICAgICAgICAgc20uY2hlY2tQZXJtaXNzaW9uKG5ldyBSdW50aW1lUGVybWlzc2lvbigiZ2V0Q29udGV4dENsYXNzTG9hZGVyIikpOyAvLyBhbmRyb2lkLWNoYW5nZWQKKworICAgICAgICAgICAgICAgIC8vIEZhaWwgZmFzdAorICAgICAgICAgICAgICAgIHNtLmNoZWNrUGVybWlzc2lvbihuZXcgUnVudGltZVBlcm1pc3Npb24oInNldENvbnRleHRDbGFzc0xvYWRlciIpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMuYWNjID0gQWNjZXNzQ29udHJvbGxlci5nZXRDb250ZXh0KCk7CisgICAgICAgICAgICB0aGlzLmNjbCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgVGhyZWFkIG5ld1RocmVhZChmaW5hbCBSdW5uYWJsZSByKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIubmV3VGhyZWFkKG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uPFZvaWQ+KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIFZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuc2V0Q29udGV4dENsYXNzTG9hZGVyKGNjbCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgci5ydW4oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSwgYWNjKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEEgd3JhcHBlciBjbGFzcyB0aGF0IGV4cG9zZXMgb25seSB0aGUgRXhlY3V0b3JTZXJ2aWNlIG1ldGhvZHMKKyAgICAgKiBvZiBhbiBFeGVjdXRvclNlcnZpY2UgaW1wbGVtZW50YXRpb24uCisgICAgICovCisgICAgc3RhdGljIGNsYXNzIERlbGVnYXRlZEV4ZWN1dG9yU2VydmljZSBleHRlbmRzIEFic3RyYWN0RXhlY3V0b3JTZXJ2aWNlIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBFeGVjdXRvclNlcnZpY2UgZTsKKyAgICAgICAgRGVsZWdhdGVkRXhlY3V0b3JTZXJ2aWNlKEV4ZWN1dG9yU2VydmljZSBleGVjdXRvcikgeyBlID0gZXhlY3V0b3I7IH0KKyAgICAgICAgcHVibGljIHZvaWQgZXhlY3V0ZShSdW5uYWJsZSBjb21tYW5kKSB7IGUuZXhlY3V0ZShjb21tYW5kKTsgfQorICAgICAgICBwdWJsaWMgdm9pZCBzaHV0ZG93bigpIHsgZS5zaHV0ZG93bigpOyB9CisgICAgICAgIHB1YmxpYyBMaXN0PFJ1bm5hYmxlPiBzaHV0ZG93bk5vdygpIHsgcmV0dXJuIGUuc2h1dGRvd25Ob3coKTsgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1NodXRkb3duKCkgeyByZXR1cm4gZS5pc1NodXRkb3duKCk7IH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNUZXJtaW5hdGVkKCkgeyByZXR1cm4gZS5pc1Rlcm1pbmF0ZWQoKTsgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBhd2FpdFRlcm1pbmF0aW9uKGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gZS5hd2FpdFRlcm1pbmF0aW9uKHRpbWVvdXQsIHVuaXQpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBGdXR1cmU8Pz4gc3VibWl0KFJ1bm5hYmxlIHRhc2spIHsKKyAgICAgICAgICAgIHJldHVybiBlLnN1Ym1pdCh0YXNrKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgPFQ+IEZ1dHVyZTxUPiBzdWJtaXQoQ2FsbGFibGU8VD4gdGFzaykgeworICAgICAgICAgICAgcmV0dXJuIGUuc3VibWl0KHRhc2spOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyA8VD4gRnV0dXJlPFQ+IHN1Ym1pdChSdW5uYWJsZSB0YXNrLCBUIHJlc3VsdCkgeworICAgICAgICAgICAgcmV0dXJuIGUuc3VibWl0KHRhc2ssIHJlc3VsdCk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIDxUPiBMaXN0PEZ1dHVyZTxUPj4gaW52b2tlQWxsKENvbGxlY3Rpb248PyBleHRlbmRzIENhbGxhYmxlPFQ+PiB0YXNrcykKKyAgICAgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gZS5pbnZva2VBbGwodGFza3MpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyA8VD4gTGlzdDxGdXR1cmU8VD4+IGludm9rZUFsbChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDYWxsYWJsZTxUPj4gdGFza3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpCisgICAgICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIGUuaW52b2tlQWxsKHRhc2tzLCB0aW1lb3V0LCB1bml0KTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgPFQ+IFQgaW52b2tlQW55KENvbGxlY3Rpb248PyBleHRlbmRzIENhbGxhYmxlPFQ+PiB0YXNrcykKKyAgICAgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBlLmludm9rZUFueSh0YXNrcyk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIDxUPiBUIGludm9rZUFueShDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDYWxsYWJsZTxUPj4gdGFza3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KQorICAgICAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24sIFRpbWVvdXRFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIGUuaW52b2tlQW55KHRhc2tzLCB0aW1lb3V0LCB1bml0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBGaW5hbGl6YWJsZURlbGVnYXRlZEV4ZWN1dG9yU2VydmljZQorICAgICAgICBleHRlbmRzIERlbGVnYXRlZEV4ZWN1dG9yU2VydmljZSB7CisgICAgICAgIEZpbmFsaXphYmxlRGVsZWdhdGVkRXhlY3V0b3JTZXJ2aWNlKEV4ZWN1dG9yU2VydmljZSBleGVjdXRvcikgeworICAgICAgICAgICAgc3VwZXIoZXhlY3V0b3IpOworICAgICAgICB9CisgICAgICAgIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgeworICAgICAgICAgICAgc3VwZXIuc2h1dGRvd24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEEgd3JhcHBlciBjbGFzcyB0aGF0IGV4cG9zZXMgb25seSB0aGUgU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlCisgICAgICogbWV0aG9kcyBvZiBhIFNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZSBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKi8KKyAgICBzdGF0aWMgY2xhc3MgRGVsZWdhdGVkU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlCisgICAgICAgICAgICBleHRlbmRzIERlbGVnYXRlZEV4ZWN1dG9yU2VydmljZQorICAgICAgICAgICAgaW1wbGVtZW50cyBTY2hlZHVsZWRFeGVjdXRvclNlcnZpY2UgeworICAgICAgICBwcml2YXRlIGZpbmFsIFNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZSBlOworICAgICAgICBEZWxlZ2F0ZWRTY2hlZHVsZWRFeGVjdXRvclNlcnZpY2UoU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlIGV4ZWN1dG9yKSB7CisgICAgICAgICAgICBzdXBlcihleGVjdXRvcik7CisgICAgICAgICAgICBlID0gZXhlY3V0b3I7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIFNjaGVkdWxlZEZ1dHVyZTw/PiBzY2hlZHVsZShSdW5uYWJsZSBjb21tYW5kLCBsb25nIGRlbGF5LCAgVGltZVVuaXQgdW5pdCkgeworICAgICAgICAgICAgcmV0dXJuIGUuc2NoZWR1bGUoY29tbWFuZCwgZGVsYXksIHVuaXQpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyA8Vj4gU2NoZWR1bGVkRnV0dXJlPFY+IHNjaGVkdWxlKENhbGxhYmxlPFY+IGNhbGxhYmxlLCBsb25nIGRlbGF5LCBUaW1lVW5pdCB1bml0KSB7CisgICAgICAgICAgICByZXR1cm4gZS5zY2hlZHVsZShjYWxsYWJsZSwgZGVsYXksIHVuaXQpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBTY2hlZHVsZWRGdXR1cmU8Pz4gc2NoZWR1bGVBdEZpeGVkUmF0ZShSdW5uYWJsZSBjb21tYW5kLCBsb25nIGluaXRpYWxEZWxheSwgIGxvbmcgcGVyaW9kLCBUaW1lVW5pdCB1bml0KSB7CisgICAgICAgICAgICByZXR1cm4gZS5zY2hlZHVsZUF0Rml4ZWRSYXRlKGNvbW1hbmQsIGluaXRpYWxEZWxheSwgcGVyaW9kLCB1bml0KTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgU2NoZWR1bGVkRnV0dXJlPD8+IHNjaGVkdWxlV2l0aEZpeGVkRGVsYXkoUnVubmFibGUgY29tbWFuZCwgbG9uZyBpbml0aWFsRGVsYXksICBsb25nIGRlbGF5LCBUaW1lVW5pdCB1bml0KSB7CisgICAgICAgICAgICByZXR1cm4gZS5zY2hlZHVsZVdpdGhGaXhlZERlbGF5KGNvbW1hbmQsIGluaXRpYWxEZWxheSwgZGVsYXksIHVuaXQpOworICAgICAgICB9CisgICAgfQorCisKKyAgICAvKiogQ2Fubm90IGluc3RhbnRpYXRlLiAqLworICAgIHByaXZhdGUgRXhlY3V0b3JzKCkge30KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9GdXR1cmUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9GdXR1cmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYjg0Nzk2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0Z1dHVyZS5qYXZhCkBAIC0wLDAgKzEsMTQwIEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CisKKy8qKgorICogQSA8dHQ+RnV0dXJlPC90dD4gcmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIGFuIGFzeW5jaHJvbm91cworICogY29tcHV0YXRpb24uICBNZXRob2RzIGFyZSBwcm92aWRlZCB0byBjaGVjayBpZiB0aGUgY29tcHV0YXRpb24gaXMKKyAqIGNvbXBsZXRlLCB0byB3YWl0IGZvciBpdHMgY29tcGxldGlvbiwgYW5kIHRvIHJldHJpZXZlIHRoZSByZXN1bHQgb2YKKyAqIHRoZSBjb21wdXRhdGlvbi4gIFRoZSByZXN1bHQgY2FuIG9ubHkgYmUgcmV0cmlldmVkIHVzaW5nIG1ldGhvZAorICogPHR0PmdldDwvdHQ+IHdoZW4gdGhlIGNvbXB1dGF0aW9uIGhhcyBjb21wbGV0ZWQsIGJsb2NraW5nIGlmCisgKiBuZWNlc3NhcnkgdW50aWwgaXQgaXMgcmVhZHkuICBDYW5jZWxsYXRpb24gaXMgcGVyZm9ybWVkIGJ5IHRoZQorICogPHR0PmNhbmNlbDwvdHQ+IG1ldGhvZC4gIEFkZGl0aW9uYWwgbWV0aG9kcyBhcmUgcHJvdmlkZWQgdG8KKyAqIGRldGVybWluZSBpZiB0aGUgdGFzayBjb21wbGV0ZWQgbm9ybWFsbHkgb3Igd2FzIGNhbmNlbGxlZC4gT25jZSBhCisgKiBjb21wdXRhdGlvbiBoYXMgY29tcGxldGVkLCB0aGUgY29tcHV0YXRpb24gY2Fubm90IGJlIGNhbmNlbGxlZC4KKyAqIElmIHlvdSB3b3VsZCBsaWtlIHRvIHVzZSBhIDx0dD5GdXR1cmU8L3R0PiBmb3IgdGhlIHNha2UKKyAqIG9mIGNhbmNlbGxhYmlsaXR5IGJ1dCBub3QgcHJvdmlkZSBhIHVzYWJsZSByZXN1bHQsIHlvdSBjYW4KKyAqIGRlY2xhcmUgdHlwZXMgb2YgdGhlIGZvcm0ge0Bjb2RlIEZ1dHVyZTw/Pn0gYW5kCisgKiByZXR1cm4gPHR0Pm51bGw8L3R0PiBhcyBhIHJlc3VsdCBvZiB0aGUgdW5kZXJseWluZyB0YXNrLgorICoKKyAqIDxwPgorICogPGI+U2FtcGxlIFVzYWdlPC9iPiAoTm90ZSB0aGF0IHRoZSBmb2xsb3dpbmcgY2xhc3NlcyBhcmUgYWxsCisgKiBtYWRlLXVwLikgPHA+CisgKiAgPHByZT4ge0Bjb2RlCisgKiBpbnRlcmZhY2UgQXJjaGl2ZVNlYXJjaGVyIHsgU3RyaW5nIHNlYXJjaChTdHJpbmcgdGFyZ2V0KTsgfQorICogY2xhc3MgQXBwIHsKKyAqICAgRXhlY3V0b3JTZXJ2aWNlIGV4ZWN1dG9yID0gLi4uCisgKiAgIEFyY2hpdmVTZWFyY2hlciBzZWFyY2hlciA9IC4uLgorICogICB2b2lkIHNob3dTZWFyY2goZmluYWwgU3RyaW5nIHRhcmdldCkKKyAqICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgKiAgICAgRnV0dXJlPFN0cmluZz4gZnV0dXJlCisgKiAgICAgICA9IGV4ZWN1dG9yLnN1Ym1pdChuZXcgQ2FsbGFibGU8U3RyaW5nPigpIHsKKyAqICAgICAgICAgcHVibGljIFN0cmluZyBjYWxsKCkgeworICogICAgICAgICAgICAgcmV0dXJuIHNlYXJjaGVyLnNlYXJjaCh0YXJnZXQpOworICogICAgICAgICB9fSk7CisgKiAgICAgZGlzcGxheU90aGVyVGhpbmdzKCk7IC8vIGRvIG90aGVyIHRoaW5ncyB3aGlsZSBzZWFyY2hpbmcKKyAqICAgICB0cnkgeworICogICAgICAgZGlzcGxheVRleHQoZnV0dXJlLmdldCgpKTsgLy8gdXNlIGZ1dHVyZQorICogICAgIH0gY2F0Y2ggKEV4ZWN1dGlvbkV4Y2VwdGlvbiBleCkgeyBjbGVhbnVwKCk7IHJldHVybjsgfQorICogICB9CisgKiB9fTwvcHJlPgorICoKKyAqIFRoZSB7QGxpbmsgRnV0dXJlVGFza30gY2xhc3MgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgPHR0PkZ1dHVyZTwvdHQ+IHRoYXQKKyAqIGltcGxlbWVudHMgPHR0PlJ1bm5hYmxlPC90dD4sIGFuZCBzbyBtYXkgYmUgZXhlY3V0ZWQgYnkgYW4gPHR0PkV4ZWN1dG9yPC90dD4uCisgKiBGb3IgZXhhbXBsZSwgdGhlIGFib3ZlIGNvbnN0cnVjdGlvbiB3aXRoIDx0dD5zdWJtaXQ8L3R0PiBjb3VsZCBiZSByZXBsYWNlZCBieToKKyAqICA8cHJlPiB7QGNvZGUKKyAqICAgICBGdXR1cmVUYXNrPFN0cmluZz4gZnV0dXJlID0KKyAqICAgICAgIG5ldyBGdXR1cmVUYXNrPFN0cmluZz4obmV3IENhbGxhYmxlPFN0cmluZz4oKSB7CisgKiAgICAgICAgIHB1YmxpYyBTdHJpbmcgY2FsbCgpIHsKKyAqICAgICAgICAgICByZXR1cm4gc2VhcmNoZXIuc2VhcmNoKHRhcmdldCk7CisgKiAgICAgICB9fSk7CisgKiAgICAgZXhlY3V0b3IuZXhlY3V0ZShmdXR1cmUpO308L3ByZT4KKyAqCisgKiA8cD5NZW1vcnkgY29uc2lzdGVuY3kgZWZmZWN0czogQWN0aW9ucyB0YWtlbiBieSB0aGUgYXN5bmNocm9ub3VzIGNvbXB1dGF0aW9uCisgKiA8YSBocmVmPSJwYWNrYWdlLXN1bW1hcnkuaHRtbCNNZW1vcnlWaXNpYmlsaXR5Ij4gPGk+aGFwcGVuLWJlZm9yZTwvaT48L2E+CisgKiBhY3Rpb25zIGZvbGxvd2luZyB0aGUgY29ycmVzcG9uZGluZyB7QGNvZGUgRnV0dXJlLmdldCgpfSBpbiBhbm90aGVyIHRocmVhZC4KKyAqCisgKiBAc2VlIEZ1dHVyZVRhc2sKKyAqIEBzZWUgRXhlY3V0b3IKKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqIEBwYXJhbSA8Vj4gVGhlIHJlc3VsdCB0eXBlIHJldHVybmVkIGJ5IHRoaXMgRnV0dXJlJ3MgPHR0PmdldDwvdHQ+IG1ldGhvZAorICovCitwdWJsaWMgaW50ZXJmYWNlIEZ1dHVyZTxWPiB7CisKKyAgICAvKioKKyAgICAgKiBBdHRlbXB0cyB0byBjYW5jZWwgZXhlY3V0aW9uIG9mIHRoaXMgdGFzay4gIFRoaXMgYXR0ZW1wdCB3aWxsCisgICAgICogZmFpbCBpZiB0aGUgdGFzayBoYXMgYWxyZWFkeSBjb21wbGV0ZWQsIGhhcyBhbHJlYWR5IGJlZW4gY2FuY2VsbGVkLAorICAgICAqIG9yIGNvdWxkIG5vdCBiZSBjYW5jZWxsZWQgZm9yIHNvbWUgb3RoZXIgcmVhc29uLiBJZiBzdWNjZXNzZnVsLAorICAgICAqIGFuZCB0aGlzIHRhc2sgaGFzIG5vdCBzdGFydGVkIHdoZW4gPHR0PmNhbmNlbDwvdHQ+IGlzIGNhbGxlZCwKKyAgICAgKiB0aGlzIHRhc2sgc2hvdWxkIG5ldmVyIHJ1bi4gIElmIHRoZSB0YXNrIGhhcyBhbHJlYWR5IHN0YXJ0ZWQsCisgICAgICogdGhlbiB0aGUgPHR0Pm1heUludGVycnVwdElmUnVubmluZzwvdHQ+IHBhcmFtZXRlciBkZXRlcm1pbmVzCisgICAgICogd2hldGhlciB0aGUgdGhyZWFkIGV4ZWN1dGluZyB0aGlzIHRhc2sgc2hvdWxkIGJlIGludGVycnVwdGVkIGluCisgICAgICogYW4gYXR0ZW1wdCB0byBzdG9wIHRoZSB0YXNrLgorICAgICAqCisgICAgICogPHA+QWZ0ZXIgdGhpcyBtZXRob2QgcmV0dXJucywgc3Vic2VxdWVudCBjYWxscyB0byB7QGxpbmsgI2lzRG9uZX0gd2lsbAorICAgICAqIGFsd2F5cyByZXR1cm4gPHR0PnRydWU8L3R0Pi4gIFN1YnNlcXVlbnQgY2FsbHMgdG8ge0BsaW5rICNpc0NhbmNlbGxlZH0KKyAgICAgKiB3aWxsIGFsd2F5cyByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGlzIG1ldGhvZCByZXR1cm5lZCA8dHQ+dHJ1ZTwvdHQ+LgorICAgICAqCisgICAgICogQHBhcmFtIG1heUludGVycnVwdElmUnVubmluZyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoZSB0aHJlYWQgZXhlY3V0aW5nIHRoaXMKKyAgICAgKiB0YXNrIHNob3VsZCBiZSBpbnRlcnJ1cHRlZDsgb3RoZXJ3aXNlLCBpbi1wcm9ncmVzcyB0YXNrcyBhcmUgYWxsb3dlZAorICAgICAqIHRvIGNvbXBsZXRlCisgICAgICogQHJldHVybiA8dHQ+ZmFsc2U8L3R0PiBpZiB0aGUgdGFzayBjb3VsZCBub3QgYmUgY2FuY2VsbGVkLAorICAgICAqIHR5cGljYWxseSBiZWNhdXNlIGl0IGhhcyBhbHJlYWR5IGNvbXBsZXRlZCBub3JtYWxseTsKKyAgICAgKiA8dHQ+dHJ1ZTwvdHQ+IG90aGVyd2lzZQorICAgICAqLworICAgIGJvb2xlYW4gY2FuY2VsKGJvb2xlYW4gbWF5SW50ZXJydXB0SWZSdW5uaW5nKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBpZiB0aGlzIHRhc2sgd2FzIGNhbmNlbGxlZCBiZWZvcmUgaXQgY29tcGxldGVkCisgICAgICogbm9ybWFsbHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyB0YXNrIHdhcyBjYW5jZWxsZWQgYmVmb3JlIGl0IGNvbXBsZXRlZAorICAgICAqLworICAgIGJvb2xlYW4gaXNDYW5jZWxsZWQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBpZiB0aGlzIHRhc2sgY29tcGxldGVkLgorICAgICAqCisgICAgICogQ29tcGxldGlvbiBtYXkgYmUgZHVlIHRvIG5vcm1hbCB0ZXJtaW5hdGlvbiwgYW4gZXhjZXB0aW9uLCBvcgorICAgICAqIGNhbmNlbGxhdGlvbiAtLSBpbiBhbGwgb2YgdGhlc2UgY2FzZXMsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuCisgICAgICogPHR0PnRydWU8L3R0Pi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGlzIHRhc2sgY29tcGxldGVkCisgICAgICovCisgICAgYm9vbGVhbiBpc0RvbmUoKTsKKworICAgIC8qKgorICAgICAqIFdhaXRzIGlmIG5lY2Vzc2FyeSBmb3IgdGhlIGNvbXB1dGF0aW9uIHRvIGNvbXBsZXRlLCBhbmQgdGhlbgorICAgICAqIHJldHJpZXZlcyBpdHMgcmVzdWx0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29tcHV0ZWQgcmVzdWx0CisgICAgICogQHRocm93cyBDYW5jZWxsYXRpb25FeGNlcHRpb24gaWYgdGhlIGNvbXB1dGF0aW9uIHdhcyBjYW5jZWxsZWQKKyAgICAgKiBAdGhyb3dzIEV4ZWN1dGlvbkV4Y2VwdGlvbiBpZiB0aGUgY29tcHV0YXRpb24gdGhyZXcgYW4KKyAgICAgKiBleGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IHRocmVhZCB3YXMgaW50ZXJydXB0ZWQKKyAgICAgKiB3aGlsZSB3YWl0aW5nCisgICAgICovCisgICAgViBnZXQoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24sIEV4ZWN1dGlvbkV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdhaXRzIGlmIG5lY2Vzc2FyeSBmb3IgYXQgbW9zdCB0aGUgZ2l2ZW4gdGltZSBmb3IgdGhlIGNvbXB1dGF0aW9uCisgICAgICogdG8gY29tcGxldGUsIGFuZCB0aGVuIHJldHJpZXZlcyBpdHMgcmVzdWx0LCBpZiBhdmFpbGFibGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGltZW91dCB0aGUgbWF4aW11bSB0aW1lIHRvIHdhaXQKKyAgICAgKiBAcGFyYW0gdW5pdCB0aGUgdGltZSB1bml0IG9mIHRoZSB0aW1lb3V0IGFyZ3VtZW50CisgICAgICogQHJldHVybiB0aGUgY29tcHV0ZWQgcmVzdWx0CisgICAgICogQHRocm93cyBDYW5jZWxsYXRpb25FeGNlcHRpb24gaWYgdGhlIGNvbXB1dGF0aW9uIHdhcyBjYW5jZWxsZWQKKyAgICAgKiBAdGhyb3dzIEV4ZWN1dGlvbkV4Y2VwdGlvbiBpZiB0aGUgY29tcHV0YXRpb24gdGhyZXcgYW4KKyAgICAgKiBleGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IHRocmVhZCB3YXMgaW50ZXJydXB0ZWQKKyAgICAgKiB3aGlsZSB3YWl0aW5nCisgICAgICogQHRocm93cyBUaW1lb3V0RXhjZXB0aW9uIGlmIHRoZSB3YWl0IHRpbWVkIG91dAorICAgICAqLworICAgIFYgZ2V0KGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24sIFRpbWVvdXRFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvRnV0dXJlVGFzay5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0Z1dHVyZVRhc2suamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZjIzMzVlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0Z1dHVyZVRhc2suamF2YQpAQCAtMCwwICsxLDMzMSBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLio7CisKKy8qKgorICogQSBjYW5jZWxsYWJsZSBhc3luY2hyb25vdXMgY29tcHV0YXRpb24uICBUaGlzIGNsYXNzIHByb3ZpZGVzIGEgYmFzZQorICogaW1wbGVtZW50YXRpb24gb2Yge0BsaW5rIEZ1dHVyZX0sIHdpdGggbWV0aG9kcyB0byBzdGFydCBhbmQgY2FuY2VsCisgKiBhIGNvbXB1dGF0aW9uLCBxdWVyeSB0byBzZWUgaWYgdGhlIGNvbXB1dGF0aW9uIGlzIGNvbXBsZXRlLCBhbmQKKyAqIHJldHJpZXZlIHRoZSByZXN1bHQgb2YgdGhlIGNvbXB1dGF0aW9uLiAgVGhlIHJlc3VsdCBjYW4gb25seSBiZQorICogcmV0cmlldmVkIHdoZW4gdGhlIGNvbXB1dGF0aW9uIGhhcyBjb21wbGV0ZWQ7IHRoZSA8dHQ+Z2V0PC90dD4KKyAqIG1ldGhvZCB3aWxsIGJsb2NrIGlmIHRoZSBjb21wdXRhdGlvbiBoYXMgbm90IHlldCBjb21wbGV0ZWQuICBPbmNlCisgKiB0aGUgY29tcHV0YXRpb24gaGFzIGNvbXBsZXRlZCwgdGhlIGNvbXB1dGF0aW9uIGNhbm5vdCBiZSByZXN0YXJ0ZWQKKyAqIG9yIGNhbmNlbGxlZC4KKyAqCisgKiA8cD5BIDx0dD5GdXR1cmVUYXNrPC90dD4gY2FuIGJlIHVzZWQgdG8gd3JhcCBhIHtAbGluayBDYWxsYWJsZX0gb3IKKyAqIHtAbGluayBqYXZhLmxhbmcuUnVubmFibGV9IG9iamVjdC4gIEJlY2F1c2UgPHR0PkZ1dHVyZVRhc2s8L3R0PgorICogaW1wbGVtZW50cyA8dHQ+UnVubmFibGU8L3R0PiwgYSA8dHQ+RnV0dXJlVGFzazwvdHQ+IGNhbiBiZQorICogc3VibWl0dGVkIHRvIGFuIHtAbGluayBFeGVjdXRvcn0gZm9yIGV4ZWN1dGlvbi4KKyAqCisgKiA8cD5JbiBhZGRpdGlvbiB0byBzZXJ2aW5nIGFzIGEgc3RhbmRhbG9uZSBjbGFzcywgdGhpcyBjbGFzcyBwcm92aWRlcworICogPHR0PnByb3RlY3RlZDwvdHQ+IGZ1bmN0aW9uYWxpdHkgdGhhdCBtYXkgYmUgdXNlZnVsIHdoZW4gY3JlYXRpbmcKKyAqIGN1c3RvbWl6ZWQgdGFzayBjbGFzc2VzLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqIEBwYXJhbSA8Vj4gVGhlIHJlc3VsdCB0eXBlIHJldHVybmVkIGJ5IHRoaXMgRnV0dXJlVGFzaydzIDx0dD5nZXQ8L3R0PiBtZXRob2QKKyAqLworcHVibGljIGNsYXNzIEZ1dHVyZVRhc2s8Vj4gaW1wbGVtZW50cyBSdW5uYWJsZUZ1dHVyZTxWPiB7CisgICAgLyoqIFN5bmNocm9uaXphdGlvbiBjb250cm9sIGZvciBGdXR1cmVUYXNrICovCisgICAgcHJpdmF0ZSBmaW5hbCBTeW5jIHN5bmM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgPHR0PkZ1dHVyZVRhc2s8L3R0PiB0aGF0IHdpbGwsIHVwb24gcnVubmluZywgZXhlY3V0ZSB0aGUKKyAgICAgKiBnaXZlbiA8dHQ+Q2FsbGFibGU8L3R0Pi4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgY2FsbGFibGUgdGhlIGNhbGxhYmxlIHRhc2sKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGNhbGxhYmxlIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgRnV0dXJlVGFzayhDYWxsYWJsZTxWPiBjYWxsYWJsZSkgeworICAgICAgICBpZiAoY2FsbGFibGUgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBzeW5jID0gbmV3IFN5bmMoY2FsbGFibGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSA8dHQ+RnV0dXJlVGFzazwvdHQ+IHRoYXQgd2lsbCwgdXBvbiBydW5uaW5nLCBleGVjdXRlIHRoZQorICAgICAqIGdpdmVuIDx0dD5SdW5uYWJsZTwvdHQ+LCBhbmQgYXJyYW5nZSB0aGF0IDx0dD5nZXQ8L3R0PiB3aWxsIHJldHVybiB0aGUKKyAgICAgKiBnaXZlbiByZXN1bHQgb24gc3VjY2Vzc2Z1bCBjb21wbGV0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHJ1bm5hYmxlIHRoZSBydW5uYWJsZSB0YXNrCisgICAgICogQHBhcmFtIHJlc3VsdCB0aGUgcmVzdWx0IHRvIHJldHVybiBvbiBzdWNjZXNzZnVsIGNvbXBsZXRpb24uIElmCisgICAgICogeW91IGRvbid0IG5lZWQgYSBwYXJ0aWN1bGFyIHJlc3VsdCwgY29uc2lkZXIgdXNpbmcKKyAgICAgKiBjb25zdHJ1Y3Rpb25zIG9mIHRoZSBmb3JtOgorICAgICAqIHtAY29kZSBGdXR1cmU8Pz4gZiA9IG5ldyBGdXR1cmVUYXNrPFZvaWQ+KHJ1bm5hYmxlLCBudWxsKX0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHJ1bm5hYmxlIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgRnV0dXJlVGFzayhSdW5uYWJsZSBydW5uYWJsZSwgViByZXN1bHQpIHsKKyAgICAgICAgc3luYyA9IG5ldyBTeW5jKEV4ZWN1dG9ycy5jYWxsYWJsZShydW5uYWJsZSwgcmVzdWx0KSk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNDYW5jZWxsZWQoKSB7CisgICAgICAgIHJldHVybiBzeW5jLmlubmVySXNDYW5jZWxsZWQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RvbmUoKSB7CisgICAgICAgIHJldHVybiBzeW5jLmlubmVySXNEb25lKCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gY2FuY2VsKGJvb2xlYW4gbWF5SW50ZXJydXB0SWZSdW5uaW5nKSB7CisgICAgICAgIHJldHVybiBzeW5jLmlubmVyQ2FuY2VsKG1heUludGVycnVwdElmUnVubmluZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBDYW5jZWxsYXRpb25FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBWIGdldCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHN5bmMuaW5uZXJHZXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIENhbmNlbGxhdGlvbkV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIFYgZ2V0KGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24sIFRpbWVvdXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc3luYy5pbm5lckdldCh1bml0LnRvTmFub3ModGltZW91dCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb3RlY3RlZCBtZXRob2QgaW52b2tlZCB3aGVuIHRoaXMgdGFzayB0cmFuc2l0aW9ucyB0byBzdGF0ZQorICAgICAqIDx0dD5pc0RvbmU8L3R0PiAod2hldGhlciBub3JtYWxseSBvciB2aWEgY2FuY2VsbGF0aW9uKS4gVGhlCisgICAgICogZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdGhpbmcuICBTdWJjbGFzc2VzIG1heSBvdmVycmlkZQorICAgICAqIHRoaXMgbWV0aG9kIHRvIGludm9rZSBjb21wbGV0aW9uIGNhbGxiYWNrcyBvciBwZXJmb3JtCisgICAgICogYm9va2tlZXBpbmcuIE5vdGUgdGhhdCB5b3UgY2FuIHF1ZXJ5IHN0YXR1cyBpbnNpZGUgdGhlCisgICAgICogaW1wbGVtZW50YXRpb24gb2YgdGhpcyBtZXRob2QgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyB0YXNrCisgICAgICogaGFzIGJlZW4gY2FuY2VsbGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGRvbmUoKSB7IH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHJlc3VsdCBvZiB0aGlzIEZ1dHVyZSB0byB0aGUgZ2l2ZW4gdmFsdWUgdW5sZXNzCisgICAgICogdGhpcyBmdXR1cmUgaGFzIGFscmVhZHkgYmVlbiBzZXQgb3IgaGFzIGJlZW4gY2FuY2VsbGVkLgorICAgICAqIFRoaXMgbWV0aG9kIGlzIGludm9rZWQgaW50ZXJuYWxseSBieSB0aGUgPHR0PnJ1bjwvdHQ+IG1ldGhvZAorICAgICAqIHVwb24gc3VjY2Vzc2Z1bCBjb21wbGV0aW9uIG9mIHRoZSBjb21wdXRhdGlvbi4KKyAgICAgKiBAcGFyYW0gdiB0aGUgdmFsdWUKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXQoViB2KSB7CisgICAgICAgIHN5bmMuaW5uZXJTZXQodik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2F1c2VzIHRoaXMgZnV0dXJlIHRvIHJlcG9ydCBhbiA8dHQ+RXhlY3V0aW9uRXhjZXB0aW9uPC90dD4KKyAgICAgKiB3aXRoIHRoZSBnaXZlbiB0aHJvd2FibGUgYXMgaXRzIGNhdXNlLCB1bmxlc3MgdGhpcyBGdXR1cmUgaGFzCisgICAgICogYWxyZWFkeSBiZWVuIHNldCBvciBoYXMgYmVlbiBjYW5jZWxsZWQuCisgICAgICogVGhpcyBtZXRob2QgaXMgaW52b2tlZCBpbnRlcm5hbGx5IGJ5IHRoZSA8dHQ+cnVuPC90dD4gbWV0aG9kCisgICAgICogdXBvbiBmYWlsdXJlIG9mIHRoZSBjb21wdXRhdGlvbi4KKyAgICAgKiBAcGFyYW0gdCB0aGUgY2F1c2Ugb2YgZmFpbHVyZQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldEV4Y2VwdGlvbihUaHJvd2FibGUgdCkgeworICAgICAgICBzeW5jLmlubmVyU2V0RXhjZXB0aW9uKHQpOworICAgIH0KKworICAgIC8vIFRoZSBmb2xsb3dpbmcgKGR1cGxpY2F0ZWQpIGRvYyBjb21tZW50IGNhbiBiZSByZW1vdmVkIG9uY2UKKyAgICAvLworICAgIC8vIDYyNzA2NDU6IEphdmFkb2MgY29tbWVudHMgc2hvdWxkIGJlIGluaGVyaXRlZCBmcm9tIG1vc3QgZGVyaXZlZAorICAgIC8vICAgICAgICAgIHN1cGVyaW50ZXJmYWNlIG9yIHN1cGVyY2xhc3MKKyAgICAvLyBpcyBmaXhlZC4KKyAgICAvKioKKyAgICAgKiBTZXRzIHRoaXMgRnV0dXJlIHRvIHRoZSByZXN1bHQgb2YgaXRzIGNvbXB1dGF0aW9uCisgICAgICogdW5sZXNzIGl0IGhhcyBiZWVuIGNhbmNlbGxlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgIHN5bmMuaW5uZXJSdW4oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeGVjdXRlcyB0aGUgY29tcHV0YXRpb24gd2l0aG91dCBzZXR0aW5nIGl0cyByZXN1bHQsIGFuZCB0aGVuCisgICAgICogcmVzZXRzIHRoaXMgRnV0dXJlIHRvIGluaXRpYWwgc3RhdGUsIGZhaWxpbmcgdG8gZG8gc28gaWYgdGhlCisgICAgICogY29tcHV0YXRpb24gZW5jb3VudGVycyBhbiBleGNlcHRpb24gb3IgaXMgY2FuY2VsbGVkLiAgVGhpcyBpcworICAgICAqIGRlc2lnbmVkIGZvciB1c2Ugd2l0aCB0YXNrcyB0aGF0IGludHJpbnNpY2FsbHkgZXhlY3V0ZSBtb3JlCisgICAgICogdGhhbiBvbmNlLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsbHkgcnVuIGFuZCByZXNldAorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIHJ1bkFuZFJlc2V0KCkgeworICAgICAgICByZXR1cm4gc3luYy5pbm5lclJ1bkFuZFJlc2V0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3luY2hyb25pemF0aW9uIGNvbnRyb2wgZm9yIEZ1dHVyZVRhc2suIE5vdGUgdGhhdCB0aGlzIG11c3QgYmUKKyAgICAgKiBhIG5vbi1zdGF0aWMgaW5uZXIgY2xhc3MgaW4gb3JkZXIgdG8gaW52b2tlIHRoZSBwcm90ZWN0ZWQKKyAgICAgKiA8dHQ+ZG9uZTwvdHQ+IG1ldGhvZC4gRm9yIGNsYXJpdHksIGFsbCBpbm5lciBjbGFzcyBzdXBwb3J0CisgICAgICogbWV0aG9kcyBhcmUgc2FtZSBhcyBvdXRlciwgcHJlZml4ZWQgd2l0aCAiaW5uZXIiLgorICAgICAqCisgICAgICogVXNlcyBBUVMgc3luYyBzdGF0ZSB0byByZXByZXNlbnQgcnVuIHN0YXR1cworICAgICAqLworICAgIHByaXZhdGUgZmluYWwgY2xhc3MgU3luYyBleHRlbmRzIEFic3RyYWN0UXVldWVkU3luY2hyb25pemVyIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTc4MjgxMTc0MDE3NjM3MDAzODVMOworCisgICAgICAgIC8qKiBTdGF0ZSB2YWx1ZSByZXByZXNlbnRpbmcgdGhhdCB0YXNrIGlzIHJlYWR5IHRvIHJ1biAqLworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUkVBRFkgICAgID0gMDsKKyAgICAgICAgLyoqIFN0YXRlIHZhbHVlIHJlcHJlc2VudGluZyB0aGF0IHRhc2sgaXMgcnVubmluZyAqLworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUlVOTklORyAgID0gMTsKKyAgICAgICAgLyoqIFN0YXRlIHZhbHVlIHJlcHJlc2VudGluZyB0aGF0IHRhc2sgcmFuICovCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBSQU4gICAgICAgPSAyOworICAgICAgICAvKiogU3RhdGUgdmFsdWUgcmVwcmVzZW50aW5nIHRoYXQgdGFzayB3YXMgY2FuY2VsbGVkICovCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDQU5DRUxMRUQgPSA0OworCisgICAgICAgIC8qKiBUaGUgdW5kZXJseWluZyBjYWxsYWJsZSAqLworICAgICAgICBwcml2YXRlIGZpbmFsIENhbGxhYmxlPFY+IGNhbGxhYmxlOworICAgICAgICAvKiogVGhlIHJlc3VsdCB0byByZXR1cm4gZnJvbSBnZXQoKSAqLworICAgICAgICBwcml2YXRlIFYgcmVzdWx0OworICAgICAgICAvKiogVGhlIGV4Y2VwdGlvbiB0byB0aHJvdyBmcm9tIGdldCgpICovCisgICAgICAgIHByaXZhdGUgVGhyb3dhYmxlIGV4Y2VwdGlvbjsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHRocmVhZCBydW5uaW5nIHRhc2suIFdoZW4gbnVsbGVkIGFmdGVyIHNldC9jYW5jZWwsIHRoaXMKKyAgICAgICAgICogaW5kaWNhdGVzIHRoYXQgdGhlIHJlc3VsdHMgYXJlIGFjY2Vzc2libGUuICBNdXN0IGJlCisgICAgICAgICAqIHZvbGF0aWxlLCB0byBlbnN1cmUgdmlzaWJpbGl0eSB1cG9uIGNvbXBsZXRpb24uCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIHZvbGF0aWxlIFRocmVhZCBydW5uZXI7CisKKyAgICAgICAgU3luYyhDYWxsYWJsZTxWPiBjYWxsYWJsZSkgeworICAgICAgICAgICAgdGhpcy5jYWxsYWJsZSA9IGNhbGxhYmxlOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIHJhbk9yQ2FuY2VsbGVkKGludCBzdGF0ZSkgeworICAgICAgICAgICAgcmV0dXJuIChzdGF0ZSAmIChSQU4gfCBDQU5DRUxMRUQpKSAhPSAwOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEltcGxlbWVudHMgQVFTIGJhc2UgYWNxdWlyZSB0byBzdWNjZWVkIGlmIHJhbiBvciBjYW5jZWxsZWQKKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBpbnQgdHJ5QWNxdWlyZVNoYXJlZChpbnQgaWdub3JlKSB7CisgICAgICAgICAgICByZXR1cm4gaW5uZXJJc0RvbmUoKSA/IDEgOiAtMTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbXBsZW1lbnRzIEFRUyBiYXNlIHJlbGVhc2UgdG8gYWx3YXlzIHNpZ25hbCBhZnRlciBzZXR0aW5nCisgICAgICAgICAqIGZpbmFsIGRvbmUgc3RhdHVzIGJ5IG51bGxpbmcgcnVubmVyIHRocmVhZC4KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBib29sZWFuIHRyeVJlbGVhc2VTaGFyZWQoaW50IGlnbm9yZSkgeworICAgICAgICAgICAgcnVubmVyID0gbnVsbDsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBpbm5lcklzQ2FuY2VsbGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIGdldFN0YXRlKCkgPT0gQ0FOQ0VMTEVEOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBpbm5lcklzRG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiByYW5PckNhbmNlbGxlZChnZXRTdGF0ZSgpKSAmJiBydW5uZXIgPT0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIFYgaW5uZXJHZXQoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24sIEV4ZWN1dGlvbkV4Y2VwdGlvbiB7CisgICAgICAgICAgICBhY3F1aXJlU2hhcmVkSW50ZXJydXB0aWJseSgwKTsKKyAgICAgICAgICAgIGlmIChnZXRTdGF0ZSgpID09IENBTkNFTExFRCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2FuY2VsbGF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBpZiAoZXhjZXB0aW9uICE9IG51bGwpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4ZWN1dGlvbkV4Y2VwdGlvbihleGNlcHRpb24pOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIFYgaW5uZXJHZXQobG9uZyBuYW5vc1RpbWVvdXQpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uLCBUaW1lb3V0RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmICghdHJ5QWNxdWlyZVNoYXJlZE5hbm9zKDAsIG5hbm9zVGltZW91dCkpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRpbWVvdXRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGlmIChnZXRTdGF0ZSgpID09IENBTkNFTExFRCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2FuY2VsbGF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBpZiAoZXhjZXB0aW9uICE9IG51bGwpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4ZWN1dGlvbkV4Y2VwdGlvbihleGNlcHRpb24pOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIHZvaWQgaW5uZXJTZXQoViB2KSB7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgaW50IHMgPSBnZXRTdGF0ZSgpOworICAgICAgICAgICAgICAgIGlmIChzID09IFJBTikKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIGlmIChzID09IENBTkNFTExFRCkgeworICAgICAgICAgICAgICAgICAgICAvLyBhZ2dyZXNzaXZlbHkgcmVsZWFzZSB0byBzZXQgcnVubmVyIHRvIG51bGwsCisgICAgICAgICAgICAgICAgICAgIC8vIGluIGNhc2Ugd2UgYXJlIHJhY2luZyB3aXRoIGEgY2FuY2VsIHJlcXVlc3QKKyAgICAgICAgICAgICAgICAgICAgLy8gdGhhdCB3aWxsIHRyeSB0byBpbnRlcnJ1cHQgcnVubmVyCisgICAgICAgICAgICAgICAgICAgIHJlbGVhc2VTaGFyZWQoMCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXRTdGF0ZShzLCBSQU4pKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHY7CisgICAgICAgICAgICAgICAgICAgIHJlbGVhc2VTaGFyZWQoMCk7CisgICAgICAgICAgICAgICAgICAgIGRvbmUoKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHZvaWQgaW5uZXJTZXRFeGNlcHRpb24oVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBpbnQgcyA9IGdldFN0YXRlKCk7CisgICAgICAgICAgICAgICAgaWYgKHMgPT0gUkFOKQorICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgaWYgKHMgPT0gQ0FOQ0VMTEVEKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGFnZ3Jlc3NpdmVseSByZWxlYXNlIHRvIHNldCBydW5uZXIgdG8gbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgLy8gaW4gY2FzZSB3ZSBhcmUgcmFjaW5nIHdpdGggYSBjYW5jZWwgcmVxdWVzdAorICAgICAgICAgICAgICAgICAgICAvLyB0aGF0IHdpbGwgdHJ5IHRvIGludGVycnVwdCBydW5uZXIKKyAgICAgICAgICAgICAgICAgICAgcmVsZWFzZVNoYXJlZCgwKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldFN0YXRlKHMsIFJBTikpIHsKKyAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdDsKKyAgICAgICAgICAgICAgICAgICAgcmVsZWFzZVNoYXJlZCgwKTsKKyAgICAgICAgICAgICAgICAgICAgZG9uZSgpOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBpbm5lckNhbmNlbChib29sZWFuIG1heUludGVycnVwdElmUnVubmluZykgeworICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIGludCBzID0gZ2V0U3RhdGUoKTsKKyAgICAgICAgICAgICAgICBpZiAocmFuT3JDYW5jZWxsZWQocykpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldFN0YXRlKHMsIENBTkNFTExFRCkpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG1heUludGVycnVwdElmUnVubmluZykgeworICAgICAgICAgICAgICAgIFRocmVhZCByID0gcnVubmVyOworICAgICAgICAgICAgICAgIGlmIChyICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIHIuaW50ZXJydXB0KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZWxlYXNlU2hhcmVkKDApOworICAgICAgICAgICAgZG9uZSgpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICB2b2lkIGlubmVyUnVuKCkgeworICAgICAgICAgICAgaWYgKCFjb21wYXJlQW5kU2V0U3RhdGUoUkVBRFksIFJVTk5JTkcpKQorICAgICAgICAgICAgICAgIHJldHVybjsKKworICAgICAgICAgICAgcnVubmVyID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKyAgICAgICAgICAgIGlmIChnZXRTdGF0ZSgpID09IFJVTk5JTkcpIHsgLy8gcmVjaGVjayBhZnRlciBzZXR0aW5nIHRocmVhZAorICAgICAgICAgICAgICAgIFYgcmVzdWx0OworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNhbGxhYmxlLmNhbGwoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgc2V0RXhjZXB0aW9uKGV4KTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzZXQocmVzdWx0KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmVsZWFzZVNoYXJlZCgwKTsgLy8gY2FuY2VsCisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIGlubmVyUnVuQW5kUmVzZXQoKSB7CisgICAgICAgICAgICBpZiAoIWNvbXBhcmVBbmRTZXRTdGF0ZShSRUFEWSwgUlVOTklORykpCisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBydW5uZXIgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICAgICAgICAgIGlmIChnZXRTdGF0ZSgpID09IFJVTk5JTkcpCisgICAgICAgICAgICAgICAgICAgIGNhbGxhYmxlLmNhbGwoKTsgLy8gZG9uJ3Qgc2V0IHJlc3VsdAorICAgICAgICAgICAgICAgIHJ1bm5lciA9IG51bGw7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNvbXBhcmVBbmRTZXRTdGF0ZShSVU5OSU5HLCBSRUFEWSk7CisgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZXgpIHsKKyAgICAgICAgICAgICAgICBzZXRFeGNlcHRpb24oZXgpOworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9MaW5rZWRCbG9ja2luZ0RlcXVlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvTGlua2VkQmxvY2tpbmdEZXF1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjMDFlNzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvTGlua2VkQmxvY2tpbmdEZXF1ZS5qYXZhCkBAIC0wLDAgKzEsMTE2OSBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50OworCitpbXBvcnQgamF2YS51dGlsLkFic3RyYWN0UXVldWU7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLkNvbmRpdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5SZWVudHJhbnRMb2NrOworCisvKioKKyAqIEFuIG9wdGlvbmFsbHktYm91bmRlZCB7QGxpbmtwbGFpbiBCbG9ja2luZ0RlcXVlIGJsb2NraW5nIGRlcXVlfSBiYXNlZCBvbgorICogbGlua2VkIG5vZGVzLgorICoKKyAqIDxwPiBUaGUgb3B0aW9uYWwgY2FwYWNpdHkgYm91bmQgY29uc3RydWN0b3IgYXJndW1lbnQgc2VydmVzIGFzIGEKKyAqIHdheSB0byBwcmV2ZW50IGV4Y2Vzc2l2ZSBleHBhbnNpb24uIFRoZSBjYXBhY2l0eSwgaWYgdW5zcGVjaWZpZWQsCisgKiBpcyBlcXVhbCB0byB7QGxpbmsgSW50ZWdlciNNQVhfVkFMVUV9LiAgTGlua2VkIG5vZGVzIGFyZQorICogZHluYW1pY2FsbHkgY3JlYXRlZCB1cG9uIGVhY2ggaW5zZXJ0aW9uIHVubGVzcyB0aGlzIHdvdWxkIGJyaW5nIHRoZQorICogZGVxdWUgYWJvdmUgY2FwYWNpdHkuCisgKgorICogPHA+TW9zdCBvcGVyYXRpb25zIHJ1biBpbiBjb25zdGFudCB0aW1lIChpZ25vcmluZyB0aW1lIHNwZW50CisgKiBibG9ja2luZykuICBFeGNlcHRpb25zIGluY2x1ZGUge0BsaW5rICNyZW1vdmUoT2JqZWN0KSByZW1vdmV9LAorICoge0BsaW5rICNyZW1vdmVGaXJzdE9jY3VycmVuY2UgcmVtb3ZlRmlyc3RPY2N1cnJlbmNlfSwge0BsaW5rCisgKiAjcmVtb3ZlTGFzdE9jY3VycmVuY2UgcmVtb3ZlTGFzdE9jY3VycmVuY2V9LCB7QGxpbmsgI2NvbnRhaW5zCisgKiBjb250YWluc30sIHtAbGluayAjaXRlcmF0b3IgaXRlcmF0b3IucmVtb3ZlKCl9LCBhbmQgdGhlIGJ1bGsKKyAqIG9wZXJhdGlvbnMsIGFsbCBvZiB3aGljaCBydW4gaW4gbGluZWFyIHRpbWUuCisgKgorICogPHA+VGhpcyBjbGFzcyBhbmQgaXRzIGl0ZXJhdG9yIGltcGxlbWVudCBhbGwgb2YgdGhlCisgKiA8ZW0+b3B0aW9uYWw8L2VtPiBtZXRob2RzIG9mIHRoZSB7QGxpbmsgQ29sbGVjdGlvbn0gYW5kIHtAbGluaworICogSXRlcmF0b3J9IGludGVyZmFjZXMuCisgKgorICogPHA+VGhpcyBjbGFzcyBpcyBhIG1lbWJlciBvZiB0aGUKKyAqIDxhIGhyZWY9IntAZG9jUm9vdH0vLi4vdGVjaG5vdGVzL2d1aWRlcy9jb2xsZWN0aW9ucy9pbmRleC5odG1sIj4KKyAqIEphdmEgQ29sbGVjdGlvbnMgRnJhbWV3b3JrPC9hPi4KKyAqCisgKiBAc2luY2UgMS42CisgKiBAYXV0aG9yICBEb3VnIExlYQorICogQHBhcmFtIDxFPiB0aGUgdHlwZSBvZiBlbGVtZW50cyBoZWxkIGluIHRoaXMgY29sbGVjdGlvbgorICovCitwdWJsaWMgY2xhc3MgTGlua2VkQmxvY2tpbmdEZXF1ZTxFPgorICAgIGV4dGVuZHMgQWJzdHJhY3RRdWV1ZTxFPgorICAgIGltcGxlbWVudHMgQmxvY2tpbmdEZXF1ZTxFPiwgIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKworICAgIC8qCisgICAgICogSW1wbGVtZW50ZWQgYXMgYSBzaW1wbGUgZG91Ymx5LWxpbmtlZCBsaXN0IHByb3RlY3RlZCBieSBhCisgICAgICogc2luZ2xlIGxvY2sgYW5kIHVzaW5nIGNvbmRpdGlvbnMgdG8gbWFuYWdlIGJsb2NraW5nLgorICAgICAqCisgICAgICogVG8gaW1wbGVtZW50IHdlYWtseSBjb25zaXN0ZW50IGl0ZXJhdG9ycywgaXQgYXBwZWFycyB3ZSBuZWVkIHRvCisgICAgICoga2VlcCBhbGwgTm9kZXMgR0MtcmVhY2hhYmxlIGZyb20gYSBwcmVkZWNlc3NvciBkZXF1ZXVlZCBOb2RlLgorICAgICAqIFRoYXQgd291bGQgY2F1c2UgdHdvIHByb2JsZW1zOgorICAgICAqIC0gYWxsb3cgYSByb2d1ZSBJdGVyYXRvciB0byBjYXVzZSB1bmJvdW5kZWQgbWVtb3J5IHJldGVudGlvbgorICAgICAqIC0gY2F1c2UgY3Jvc3MtZ2VuZXJhdGlvbmFsIGxpbmtpbmcgb2Ygb2xkIE5vZGVzIHRvIG5ldyBOb2RlcyBpZgorICAgICAqICAgYSBOb2RlIHdhcyB0ZW51cmVkIHdoaWxlIGxpdmUsIHdoaWNoIGdlbmVyYXRpb25hbCBHQ3MgaGF2ZSBhCisgICAgICogICBoYXJkIHRpbWUgZGVhbGluZyB3aXRoLCBjYXVzaW5nIHJlcGVhdGVkIG1ham9yIGNvbGxlY3Rpb25zLgorICAgICAqIEhvd2V2ZXIsIG9ubHkgbm9uLWRlbGV0ZWQgTm9kZXMgbmVlZCB0byBiZSByZWFjaGFibGUgZnJvbQorICAgICAqIGRlcXVldWVkIE5vZGVzLCBhbmQgcmVhY2hhYmlsaXR5IGRvZXMgbm90IG5lY2Vzc2FyaWx5IGhhdmUgdG8KKyAgICAgKiBiZSBvZiB0aGUga2luZCB1bmRlcnN0b29kIGJ5IHRoZSBHQy4gIFdlIHVzZSB0aGUgdHJpY2sgb2YKKyAgICAgKiBsaW5raW5nIGEgTm9kZSB0aGF0IGhhcyBqdXN0IGJlZW4gZGVxdWV1ZWQgdG8gaXRzZWxmLiAgU3VjaCBhCisgICAgICogc2VsZi1saW5rIGltcGxpY2l0bHkgbWVhbnMgdG8ganVtcCB0byAiZmlyc3QiIChmb3IgbmV4dCBsaW5rcykKKyAgICAgKiBvciAibGFzdCIgKGZvciBwcmV2IGxpbmtzKS4KKyAgICAgKi8KKworICAgIC8qCisgICAgICogV2UgaGF2ZSAiZGlhbW9uZCIgbXVsdGlwbGUgaW50ZXJmYWNlL2Fic3RyYWN0IGNsYXNzIGluaGVyaXRhbmNlCisgICAgICogaGVyZSwgYW5kIHRoYXQgaW50cm9kdWNlcyBhbWJpZ3VpdGllcy4gT2Z0ZW4gd2Ugd2FudCB0aGUKKyAgICAgKiBCbG9ja2luZ0RlcXVlIGphdmFkb2MgY29tYmluZWQgd2l0aCB0aGUgQWJzdHJhY3RRdWV1ZQorICAgICAqIGltcGxlbWVudGF0aW9uLCBzbyBhIGxvdCBvZiBtZXRob2Qgc3BlY3MgYXJlIGR1cGxpY2F0ZWQgaGVyZS4KKyAgICAgKi8KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0zODc5MTE2MzI2NzE5OTg0MjZMOworCisgICAgLyoqIERvdWJseS1saW5rZWQgbGlzdCBub2RlIGNsYXNzICovCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIE5vZGU8RT4geworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGl0ZW0sIG9yIG51bGwgaWYgdGhpcyBub2RlIGhhcyBiZWVuIHJlbW92ZWQuCisgICAgICAgICAqLworICAgICAgICBFIGl0ZW07CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE9uZSBvZjoKKyAgICAgICAgICogLSB0aGUgcmVhbCBwcmVkZWNlc3NvciBOb2RlCisgICAgICAgICAqIC0gdGhpcyBOb2RlLCBtZWFuaW5nIHRoZSBwcmVkZWNlc3NvciBpcyB0YWlsCisgICAgICAgICAqIC0gbnVsbCwgbWVhbmluZyB0aGVyZSBpcyBubyBwcmVkZWNlc3NvcgorICAgICAgICAgKi8KKyAgICAgICAgTm9kZTxFPiBwcmV2OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBPbmUgb2Y6CisgICAgICAgICAqIC0gdGhlIHJlYWwgc3VjY2Vzc29yIE5vZGUKKyAgICAgICAgICogLSB0aGlzIE5vZGUsIG1lYW5pbmcgdGhlIHN1Y2Nlc3NvciBpcyBoZWFkCisgICAgICAgICAqIC0gbnVsbCwgbWVhbmluZyB0aGVyZSBpcyBubyBzdWNjZXNzb3IKKyAgICAgICAgICovCisgICAgICAgIE5vZGU8RT4gbmV4dDsKKworICAgICAgICBOb2RlKEUgeCkgeworICAgICAgICAgICAgaXRlbSA9IHg7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQb2ludGVyIHRvIGZpcnN0IG5vZGUuCisgICAgICogSW52YXJpYW50OiAoZmlyc3QgPT0gbnVsbCAmJiBsYXN0ID09IG51bGwpIHx8CisgICAgICogICAgICAgICAgICAoZmlyc3QucHJldiA9PSBudWxsICYmIGZpcnN0Lml0ZW0gIT0gbnVsbCkKKyAgICAgKi8KKyAgICB0cmFuc2llbnQgTm9kZTxFPiBmaXJzdDsKKworICAgIC8qKgorICAgICAqIFBvaW50ZXIgdG8gbGFzdCBub2RlLgorICAgICAqIEludmFyaWFudDogKGZpcnN0ID09IG51bGwgJiYgbGFzdCA9PSBudWxsKSB8fAorICAgICAqICAgICAgICAgICAgKGxhc3QubmV4dCA9PSBudWxsICYmIGxhc3QuaXRlbSAhPSBudWxsKQorICAgICAqLworICAgIHRyYW5zaWVudCBOb2RlPEU+IGxhc3Q7CisKKyAgICAvKiogTnVtYmVyIG9mIGl0ZW1zIGluIHRoZSBkZXF1ZSAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IGludCBjb3VudDsKKworICAgIC8qKiBNYXhpbXVtIG51bWJlciBvZiBpdGVtcyBpbiB0aGUgZGVxdWUgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBjYXBhY2l0eTsKKworICAgIC8qKiBNYWluIGxvY2sgZ3VhcmRpbmcgYWxsIGFjY2VzcyAqLworICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IG5ldyBSZWVudHJhbnRMb2NrKCk7CisKKyAgICAvKiogQ29uZGl0aW9uIGZvciB3YWl0aW5nIHRha2VzICovCisgICAgcHJpdmF0ZSBmaW5hbCBDb25kaXRpb24gbm90RW1wdHkgPSBsb2NrLm5ld0NvbmRpdGlvbigpOworCisgICAgLyoqIENvbmRpdGlvbiBmb3Igd2FpdGluZyBwdXRzICovCisgICAgcHJpdmF0ZSBmaW5hbCBDb25kaXRpb24gbm90RnVsbCA9IGxvY2submV3Q29uZGl0aW9uKCk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIExpbmtlZEJsb2NraW5nRGVxdWV9IHdpdGggYSBjYXBhY2l0eSBvZgorICAgICAqIHtAbGluayBJbnRlZ2VyI01BWF9WQUxVRX0uCisgICAgICovCisgICAgcHVibGljIExpbmtlZEJsb2NraW5nRGVxdWUoKSB7CisgICAgICAgIHRoaXMoSW50ZWdlci5NQVhfVkFMVUUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgTGlua2VkQmxvY2tpbmdEZXF1ZX0gd2l0aCB0aGUgZ2l2ZW4gKGZpeGVkKSBjYXBhY2l0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXBhY2l0eSB0aGUgY2FwYWNpdHkgb2YgdGhpcyBkZXF1ZQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBjYXBhY2l0eX0gaXMgbGVzcyB0aGFuIDEKKyAgICAgKi8KKyAgICBwdWJsaWMgTGlua2VkQmxvY2tpbmdEZXF1ZShpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgaWYgKGNhcGFjaXR5IDw9IDApIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgdGhpcy5jYXBhY2l0eSA9IGNhcGFjaXR5OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgTGlua2VkQmxvY2tpbmdEZXF1ZX0gd2l0aCBhIGNhcGFjaXR5IG9mCisgICAgICoge0BsaW5rIEludGVnZXIjTUFYX1ZBTFVFfSwgaW5pdGlhbGx5IGNvbnRhaW5pbmcgdGhlIGVsZW1lbnRzIG9mCisgICAgICogdGhlIGdpdmVuIGNvbGxlY3Rpb24sIGFkZGVkIGluIHRyYXZlcnNhbCBvcmRlciBvZiB0aGUKKyAgICAgKiBjb2xsZWN0aW9uJ3MgaXRlcmF0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYyB0aGUgY29sbGVjdGlvbiBvZiBlbGVtZW50cyB0byBpbml0aWFsbHkgY29udGFpbgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIG9yIGFueQorICAgICAqICAgICAgICAgb2YgaXRzIGVsZW1lbnRzIGFyZSBudWxsCisgICAgICovCisgICAgcHVibGljIExpbmtlZEJsb2NraW5nRGVxdWUoQ29sbGVjdGlvbjw/IGV4dGVuZHMgRT4gYykgeworICAgICAgICB0aGlzKEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsgLy8gTmV2ZXIgY29udGVuZGVkLCBidXQgbmVjZXNzYXJ5IGZvciB2aXNpYmlsaXR5CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKEUgZSA6IGMpIHsKKyAgICAgICAgICAgICAgICBpZiAoZSA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICBpZiAoIWxpbmtMYXN0KG5ldyBOb2RlPEU+KGUpKSkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiRGVxdWUgZnVsbCIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgLy8gQmFzaWMgbGlua2luZyBhbmQgdW5saW5raW5nIG9wZXJhdGlvbnMsIGNhbGxlZCBvbmx5IHdoaWxlIGhvbGRpbmcgbG9jaworCisgICAgLyoqCisgICAgICogTGlua3Mgbm9kZSBhcyBmaXJzdCBlbGVtZW50LCBvciByZXR1cm5zIGZhbHNlIGlmIGZ1bGwuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGxpbmtGaXJzdChOb2RlPEU+IG5vZGUpIHsKKyAgICAgICAgLy8gYXNzZXJ0IGxvY2suaXNIZWxkQnlDdXJyZW50VGhyZWFkKCk7CisgICAgICAgIGlmIChjb3VudCA+PSBjYXBhY2l0eSkKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgTm9kZTxFPiBmID0gZmlyc3Q7CisgICAgICAgIG5vZGUubmV4dCA9IGY7CisgICAgICAgIGZpcnN0ID0gbm9kZTsKKyAgICAgICAgaWYgKGxhc3QgPT0gbnVsbCkKKyAgICAgICAgICAgIGxhc3QgPSBub2RlOworICAgICAgICBlbHNlCisgICAgICAgICAgICBmLnByZXYgPSBub2RlOworICAgICAgICArK2NvdW50OworICAgICAgICBub3RFbXB0eS5zaWduYWwoKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogTGlua3Mgbm9kZSBhcyBsYXN0IGVsZW1lbnQsIG9yIHJldHVybnMgZmFsc2UgaWYgZnVsbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gbGlua0xhc3QoTm9kZTxFPiBub2RlKSB7CisgICAgICAgIC8vIGFzc2VydCBsb2NrLmlzSGVsZEJ5Q3VycmVudFRocmVhZCgpOworICAgICAgICBpZiAoY291bnQgPj0gY2FwYWNpdHkpCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIE5vZGU8RT4gbCA9IGxhc3Q7CisgICAgICAgIG5vZGUucHJldiA9IGw7CisgICAgICAgIGxhc3QgPSBub2RlOworICAgICAgICBpZiAoZmlyc3QgPT0gbnVsbCkKKyAgICAgICAgICAgIGZpcnN0ID0gbm9kZTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgbC5uZXh0ID0gbm9kZTsKKyAgICAgICAgKytjb3VudDsKKyAgICAgICAgbm90RW1wdHkuc2lnbmFsKCk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYW5kIHJldHVybnMgZmlyc3QgZWxlbWVudCwgb3IgbnVsbCBpZiBlbXB0eS4KKyAgICAgKi8KKyAgICBwcml2YXRlIEUgdW5saW5rRmlyc3QoKSB7CisgICAgICAgIC8vIGFzc2VydCBsb2NrLmlzSGVsZEJ5Q3VycmVudFRocmVhZCgpOworICAgICAgICBOb2RlPEU+IGYgPSBmaXJzdDsKKyAgICAgICAgaWYgKGYgPT0gbnVsbCkKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICBOb2RlPEU+IG4gPSBmLm5leHQ7CisgICAgICAgIEUgaXRlbSA9IGYuaXRlbTsKKyAgICAgICAgZi5pdGVtID0gbnVsbDsKKyAgICAgICAgZi5uZXh0ID0gZjsgLy8gaGVscCBHQworICAgICAgICBmaXJzdCA9IG47CisgICAgICAgIGlmIChuID09IG51bGwpCisgICAgICAgICAgICBsYXN0ID0gbnVsbDsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgbi5wcmV2ID0gbnVsbDsKKyAgICAgICAgLS1jb3VudDsKKyAgICAgICAgbm90RnVsbC5zaWduYWwoKTsKKyAgICAgICAgcmV0dXJuIGl0ZW07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhbmQgcmV0dXJucyBsYXN0IGVsZW1lbnQsIG9yIG51bGwgaWYgZW1wdHkuCisgICAgICovCisgICAgcHJpdmF0ZSBFIHVubGlua0xhc3QoKSB7CisgICAgICAgIC8vIGFzc2VydCBsb2NrLmlzSGVsZEJ5Q3VycmVudFRocmVhZCgpOworICAgICAgICBOb2RlPEU+IGwgPSBsYXN0OworICAgICAgICBpZiAobCA9PSBudWxsKQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIE5vZGU8RT4gcCA9IGwucHJldjsKKyAgICAgICAgRSBpdGVtID0gbC5pdGVtOworICAgICAgICBsLml0ZW0gPSBudWxsOworICAgICAgICBsLnByZXYgPSBsOyAvLyBoZWxwIEdDCisgICAgICAgIGxhc3QgPSBwOworICAgICAgICBpZiAocCA9PSBudWxsKQorICAgICAgICAgICAgZmlyc3QgPSBudWxsOworICAgICAgICBlbHNlCisgICAgICAgICAgICBwLm5leHQgPSBudWxsOworICAgICAgICAtLWNvdW50OworICAgICAgICBub3RGdWxsLnNpZ25hbCgpOworICAgICAgICByZXR1cm4gaXRlbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVbmxpbmtzIHguCisgICAgICovCisgICAgdm9pZCB1bmxpbmsoTm9kZTxFPiB4KSB7CisgICAgICAgIC8vIGFzc2VydCBsb2NrLmlzSGVsZEJ5Q3VycmVudFRocmVhZCgpOworICAgICAgICBOb2RlPEU+IHAgPSB4LnByZXY7CisgICAgICAgIE5vZGU8RT4gbiA9IHgubmV4dDsKKyAgICAgICAgaWYgKHAgPT0gbnVsbCkgeworICAgICAgICAgICAgdW5saW5rRmlyc3QoKTsKKyAgICAgICAgfSBlbHNlIGlmIChuID09IG51bGwpIHsKKyAgICAgICAgICAgIHVubGlua0xhc3QoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHAubmV4dCA9IG47CisgICAgICAgICAgICBuLnByZXYgPSBwOworICAgICAgICAgICAgeC5pdGVtID0gbnVsbDsKKyAgICAgICAgICAgIC8vIERvbid0IG1lc3Mgd2l0aCB4J3MgbGlua3MuICBUaGV5IG1heSBzdGlsbCBiZSBpbiB1c2UgYnkKKyAgICAgICAgICAgIC8vIGFuIGl0ZXJhdG9yLgorICAgICAgICAgICAgLS1jb3VudDsKKyAgICAgICAgICAgIG5vdEZ1bGwuc2lnbmFsKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBCbG9ja2luZ0RlcXVlIG1ldGhvZHMKKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkRmlyc3QoRSBlKSB7CisgICAgICAgIGlmICghb2ZmZXJGaXJzdChlKSkKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkRlcXVlIGZ1bGwiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZExhc3QoRSBlKSB7CisgICAgICAgIGlmICghb2ZmZXJMYXN0KGUpKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiRGVxdWUgZnVsbCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG9mZmVyRmlyc3QoRSBlKSB7CisgICAgICAgIGlmIChlID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBOb2RlPEU+IG5vZGUgPSBuZXcgTm9kZTxFPihlKTsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBsaW5rRmlyc3Qobm9kZSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gb2ZmZXJMYXN0KEUgZSkgeworICAgICAgICBpZiAoZSA9PSBudWxsKSB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgTm9kZTxFPiBub2RlID0gbmV3IE5vZGU8RT4oZSk7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gbGlua0xhc3Qobm9kZSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIHZvaWQgcHV0Rmlyc3QoRSBlKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBpZiAoZSA9PSBudWxsKSB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgTm9kZTxFPiBub2RlID0gbmV3IE5vZGU8RT4oZSk7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3aGlsZSAoIWxpbmtGaXJzdChub2RlKSkKKyAgICAgICAgICAgICAgICBub3RGdWxsLmF3YWl0KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIHZvaWQgcHV0TGFzdChFIGUpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChlID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBOb2RlPEU+IG5vZGUgPSBuZXcgTm9kZTxFPihlKTsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdoaWxlICghbGlua0xhc3Qobm9kZSkpCisgICAgICAgICAgICAgICAgbm90RnVsbC5hd2FpdCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG9mZmVyRmlyc3QoRSBlLCBsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChlID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBOb2RlPEU+IG5vZGUgPSBuZXcgTm9kZTxFPihlKTsKKyAgICAgICAgbG9uZyBuYW5vcyA9IHVuaXQudG9OYW5vcyh0aW1lb3V0KTsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2tJbnRlcnJ1cHRpYmx5KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3aGlsZSAoIWxpbmtGaXJzdChub2RlKSkgeworICAgICAgICAgICAgICAgIGlmIChuYW5vcyA8PSAwKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgbmFub3MgPSBub3RGdWxsLmF3YWl0TmFub3MobmFub3MpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gb2ZmZXJMYXN0KEUgZSwgbG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KQorICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBpZiAoZSA9PSBudWxsKSB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgTm9kZTxFPiBub2RlID0gbmV3IE5vZGU8RT4oZSk7CisgICAgICAgIGxvbmcgbmFub3MgPSB1bml0LnRvTmFub3ModGltZW91dCk7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrSW50ZXJydXB0aWJseSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgd2hpbGUgKCFsaW5rTGFzdChub2RlKSkgeworICAgICAgICAgICAgICAgIGlmIChuYW5vcyA8PSAwKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgbmFub3MgPSBub3RGdWxsLmF3YWl0TmFub3MobmFub3MpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgRSByZW1vdmVGaXJzdCgpIHsKKyAgICAgICAgRSB4ID0gcG9sbEZpcnN0KCk7CisgICAgICAgIGlmICh4ID09IG51bGwpIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiB4OworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIEUgcmVtb3ZlTGFzdCgpIHsKKyAgICAgICAgRSB4ID0gcG9sbExhc3QoKTsKKyAgICAgICAgaWYgKHggPT0gbnVsbCkgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgcmV0dXJuIHg7CisgICAgfQorCisgICAgcHVibGljIEUgcG9sbEZpcnN0KCkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHVubGlua0ZpcnN0KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIEUgcG9sbExhc3QoKSB7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gdW5saW5rTGFzdCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBFIHRha2VGaXJzdCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFIHg7CisgICAgICAgICAgICB3aGlsZSAoICh4ID0gdW5saW5rRmlyc3QoKSkgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICBub3RFbXB0eS5hd2FpdCgpOworICAgICAgICAgICAgcmV0dXJuIHg7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIEUgdGFrZUxhc3QoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgRSB4OworICAgICAgICAgICAgd2hpbGUgKCAoeCA9IHVubGlua0xhc3QoKSkgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICBub3RFbXB0eS5hd2FpdCgpOworICAgICAgICAgICAgcmV0dXJuIHg7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIEUgcG9sbEZpcnN0KGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgbG9uZyBuYW5vcyA9IHVuaXQudG9OYW5vcyh0aW1lb3V0KTsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2tJbnRlcnJ1cHRpYmx5KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFIHg7CisgICAgICAgICAgICB3aGlsZSAoICh4ID0gdW5saW5rRmlyc3QoKSkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmIChuYW5vcyA8PSAwKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICBuYW5vcyA9IG5vdEVtcHR5LmF3YWl0TmFub3MobmFub3MpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHg7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIEUgcG9sbExhc3QobG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KQorICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBsb25nIG5hbm9zID0gdW5pdC50b05hbm9zKHRpbWVvdXQpOworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9ja0ludGVycnVwdGlibHkoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEUgeDsKKyAgICAgICAgICAgIHdoaWxlICggKHggPSB1bmxpbmtMYXN0KCkpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZiAobmFub3MgPD0gMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgbmFub3MgPSBub3RFbXB0eS5hd2FpdE5hbm9zKG5hbm9zKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB4OworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIEUgZ2V0Rmlyc3QoKSB7CisgICAgICAgIEUgeCA9IHBlZWtGaXJzdCgpOworICAgICAgICBpZiAoeCA9PSBudWxsKSB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICByZXR1cm4geDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBFIGdldExhc3QoKSB7CisgICAgICAgIEUgeCA9IHBlZWtMYXN0KCk7CisgICAgICAgIGlmICh4ID09IG51bGwpIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiB4OworICAgIH0KKworICAgIHB1YmxpYyBFIHBlZWtGaXJzdCgpIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiAoZmlyc3QgPT0gbnVsbCkgPyBudWxsIDogZmlyc3QuaXRlbTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgRSBwZWVrTGFzdCgpIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiAobGFzdCA9PSBudWxsKSA/IG51bGwgOiBsYXN0Lml0ZW07CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlRmlyc3RPY2N1cnJlbmNlKE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvID09IG51bGwpIHJldHVybiBmYWxzZTsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoTm9kZTxFPiBwID0gZmlyc3Q7IHAgIT0gbnVsbDsgcCA9IHAubmV4dCkgeworICAgICAgICAgICAgICAgIGlmIChvLmVxdWFscyhwLml0ZW0pKSB7CisgICAgICAgICAgICAgICAgICAgIHVubGluayhwKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZUxhc3RPY2N1cnJlbmNlKE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvID09IG51bGwpIHJldHVybiBmYWxzZTsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoTm9kZTxFPiBwID0gbGFzdDsgcCAhPSBudWxsOyBwID0gcC5wcmV2KSB7CisgICAgICAgICAgICAgICAgaWYgKG8uZXF1YWxzKHAuaXRlbSkpIHsKKyAgICAgICAgICAgICAgICAgICAgdW5saW5rKHApOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gQmxvY2tpbmdRdWV1ZSBtZXRob2RzCisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBhdCB0aGUgZW5kIG9mIHRoaXMgZGVxdWUgdW5sZXNzIGl0IHdvdWxkCisgICAgICogdmlvbGF0ZSBjYXBhY2l0eSByZXN0cmljdGlvbnMuICBXaGVuIHVzaW5nIGEgY2FwYWNpdHktcmVzdHJpY3RlZCBkZXF1ZSwKKyAgICAgKiBpdCBpcyBnZW5lcmFsbHkgcHJlZmVyYWJsZSB0byB1c2UgbWV0aG9kIHtAbGluayAjb2ZmZXIgb2ZmZXJ9LgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byB7QGxpbmsgI2FkZExhc3R9LgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlIGVsZW1lbnQgY2Fubm90IGJlIGFkZGVkIGF0IHRoaXMKKyAgICAgKiAgICAgICAgIHRpbWUgZHVlIHRvIGNhcGFjaXR5IHJlc3RyaWN0aW9ucworICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBhZGQoRSBlKSB7CisgICAgICAgIGFkZExhc3QoZSk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBvZmZlcihFIGUpIHsKKyAgICAgICAgcmV0dXJuIG9mZmVyTGFzdChlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXQoRSBlKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBwdXRMYXN0KGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG9mZmVyKEUgZSwgbG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KQorICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gb2ZmZXJMYXN0KGUsIHRpbWVvdXQsIHVuaXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhbmQgcmVtb3ZlcyB0aGUgaGVhZCBvZiB0aGUgcXVldWUgcmVwcmVzZW50ZWQgYnkgdGhpcyBkZXF1ZS4KKyAgICAgKiBUaGlzIG1ldGhvZCBkaWZmZXJzIGZyb20ge0BsaW5rICNwb2xsIHBvbGx9IG9ubHkgaW4gdGhhdCBpdCB0aHJvd3MgYW4KKyAgICAgKiBleGNlcHRpb24gaWYgdGhpcyBkZXF1ZSBpcyBlbXB0eS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8ge0BsaW5rICNyZW1vdmVGaXJzdCgpIHJlbW92ZUZpcnN0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhlYWQgb2YgdGhlIHF1ZXVlIHJlcHJlc2VudGVkIGJ5IHRoaXMgZGVxdWUKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gaWYgdGhpcyBkZXF1ZSBpcyBlbXB0eQorICAgICAqLworICAgIHB1YmxpYyBFIHJlbW92ZSgpIHsKKyAgICAgICAgcmV0dXJuIHJlbW92ZUZpcnN0KCk7CisgICAgfQorCisgICAgcHVibGljIEUgcG9sbCgpIHsKKyAgICAgICAgcmV0dXJuIHBvbGxGaXJzdCgpOworICAgIH0KKworICAgIHB1YmxpYyBFIHRha2UoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gdGFrZUZpcnN0KCk7CisgICAgfQorCisgICAgcHVibGljIEUgcG9sbChsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBwb2xsRmlyc3QodGltZW91dCwgdW5pdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzLCBidXQgZG9lcyBub3QgcmVtb3ZlLCB0aGUgaGVhZCBvZiB0aGUgcXVldWUgcmVwcmVzZW50ZWQgYnkKKyAgICAgKiB0aGlzIGRlcXVlLiAgVGhpcyBtZXRob2QgZGlmZmVycyBmcm9tIHtAbGluayAjcGVlayBwZWVrfSBvbmx5IGluIHRoYXQKKyAgICAgKiBpdCB0aHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIHtAbGluayAjZ2V0Rmlyc3QoKSBnZXRGaXJzdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoZWFkIG9mIHRoZSBxdWV1ZSByZXByZXNlbnRlZCBieSB0aGlzIGRlcXVlCisgICAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGlmIHRoaXMgZGVxdWUgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgRSBlbGVtZW50KCkgeworICAgICAgICByZXR1cm4gZ2V0Rmlyc3QoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRSBwZWVrKCkgeworICAgICAgICByZXR1cm4gcGVla0ZpcnN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGFkZGl0aW9uYWwgZWxlbWVudHMgdGhhdCB0aGlzIGRlcXVlIGNhbiBpZGVhbGx5CisgICAgICogKGluIHRoZSBhYnNlbmNlIG9mIG1lbW9yeSBvciByZXNvdXJjZSBjb25zdHJhaW50cykgYWNjZXB0IHdpdGhvdXQKKyAgICAgKiBibG9ja2luZy4gVGhpcyBpcyBhbHdheXMgZXF1YWwgdG8gdGhlIGluaXRpYWwgY2FwYWNpdHkgb2YgdGhpcyBkZXF1ZQorICAgICAqIGxlc3MgdGhlIGN1cnJlbnQge0Bjb2RlIHNpemV9IG9mIHRoaXMgZGVxdWUuCisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoYXQgeW91IDxlbT5jYW5ub3Q8L2VtPiBhbHdheXMgdGVsbCBpZiBhbiBhdHRlbXB0IHRvIGluc2VydAorICAgICAqIGFuIGVsZW1lbnQgd2lsbCBzdWNjZWVkIGJ5IGluc3BlY3Rpbmcge0Bjb2RlIHJlbWFpbmluZ0NhcGFjaXR5fQorICAgICAqIGJlY2F1c2UgaXQgbWF5IGJlIHRoZSBjYXNlIHRoYXQgYW5vdGhlciB0aHJlYWQgaXMgYWJvdXQgdG8KKyAgICAgKiBpbnNlcnQgb3IgcmVtb3ZlIGFuIGVsZW1lbnQuCisgICAgICovCisgICAgcHVibGljIGludCByZW1haW5pbmdDYXBhY2l0eSgpIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBjYXBhY2l0eSAtIGNvdW50OworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uICAgICAgICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gICAgICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZHJhaW5UbyhDb2xsZWN0aW9uPD8gc3VwZXIgRT4gYykgeworICAgICAgICByZXR1cm4gZHJhaW5UbyhjLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gICAgICAgICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgICAgICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gICAgICB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIGludCBkcmFpblRvKENvbGxlY3Rpb248PyBzdXBlciBFPiBjLCBpbnQgbWF4RWxlbWVudHMpIHsKKyAgICAgICAgaWYgKGMgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBpZiAoYyA9PSB0aGlzKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IG4gPSBNYXRoLm1pbihtYXhFbGVtZW50cywgY291bnQpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgICAgICAgICBjLmFkZChmaXJzdC5pdGVtKTsgICAvLyBJbiB0aGlzIG9yZGVyLCBpbiBjYXNlIGFkZCgpIHRocm93cy4KKyAgICAgICAgICAgICAgICB1bmxpbmtGaXJzdCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG47CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gU3RhY2sgbWV0aG9kcworCisgICAgLyoqCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXNoKEUgZSkgeworICAgICAgICBhZGRGaXJzdChlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBFIHBvcCgpIHsKKyAgICAgICAgcmV0dXJuIHJlbW92ZUZpcnN0KCk7CisgICAgfQorCisgICAgLy8gQ29sbGVjdGlvbiBtZXRob2RzCisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBmcm9tIHRoaXMgZGVxdWUuCisgICAgICogSWYgdGhlIGRlcXVlIGRvZXMgbm90IGNvbnRhaW4gdGhlIGVsZW1lbnQsIGl0IGlzIHVuY2hhbmdlZC4KKyAgICAgKiBNb3JlIGZvcm1hbGx5LCByZW1vdmVzIHRoZSBmaXJzdCBlbGVtZW50IHtAY29kZSBlfSBzdWNoIHRoYXQKKyAgICAgKiB7QGNvZGUgby5lcXVhbHMoZSl9IChpZiBzdWNoIGFuIGVsZW1lbnQgZXhpc3RzKS4KKyAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGlzIGRlcXVlIGNvbnRhaW5lZCB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKiAob3IgZXF1aXZhbGVudGx5LCBpZiB0aGlzIGRlcXVlIGNoYW5nZWQgYXMgYSByZXN1bHQgb2YgdGhlIGNhbGwpLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0bworICAgICAqIHtAbGluayAjcmVtb3ZlRmlyc3RPY2N1cnJlbmNlKE9iamVjdCkgcmVtb3ZlRmlyc3RPY2N1cnJlbmNlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvIGVsZW1lbnQgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoaXMgZGVxdWUsIGlmIHByZXNlbnQKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGRlcXVlIGNoYW5nZWQgYXMgYSByZXN1bHQgb2YgdGhlIGNhbGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG8pIHsKKyAgICAgICAgcmV0dXJuIHJlbW92ZUZpcnN0T2NjdXJyZW5jZShvKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBkZXF1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIGRlcXVlCisgICAgICovCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGNvdW50OworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoaXMgZGVxdWUgY29udGFpbnMgdGhlIHNwZWNpZmllZCBlbGVtZW50LgorICAgICAqIE1vcmUgZm9ybWFsbHksIHJldHVybnMge0Bjb2RlIHRydWV9IGlmIGFuZCBvbmx5IGlmIHRoaXMgZGVxdWUgY29udGFpbnMKKyAgICAgKiBhdCBsZWFzdCBvbmUgZWxlbWVudCB7QGNvZGUgZX0gc3VjaCB0aGF0IHtAY29kZSBvLmVxdWFscyhlKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBvYmplY3QgdG8gYmUgY2hlY2tlZCBmb3IgY29udGFpbm1lbnQgaW4gdGhpcyBkZXF1ZQorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgZGVxdWUgY29udGFpbnMgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG8pIHsKKyAgICAgICAgaWYgKG8gPT0gbnVsbCkgcmV0dXJuIGZhbHNlOworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yIChOb2RlPEU+IHAgPSBmaXJzdDsgcCAhPSBudWxsOyBwID0gcC5uZXh0KQorICAgICAgICAgICAgICAgIGlmIChvLmVxdWFscyhwLml0ZW0pKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFRPRE86IEFkZCBzdXBwb3J0IGZvciBtb3JlIGVmZmljaWVudCBidWxrIG9wZXJhdGlvbnMuCisgICAgICoKKyAgICAgKiBXZSBkb24ndCB3YW50IHRvIGFjcXVpcmUgdGhlIGxvY2sgZm9yIGV2ZXJ5IGl0ZXJhdGlvbiwgYnV0IHdlCisgICAgICogYWxzbyB3YW50IG90aGVyIHRocmVhZHMgYSBjaGFuY2UgdG8gaW50ZXJhY3Qgd2l0aCB0aGUKKyAgICAgKiBjb2xsZWN0aW9uLCBlc3BlY2lhbGx5IHdoZW4gY291bnQgaXMgY2xvc2UgdG8gY2FwYWNpdHkuCisgICAgICovCisKKy8vICAgICAvKioKKy8vICAgICAgKiBBZGRzIGFsbCBvZiB0aGUgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIHRvIHRoaXMKKy8vICAgICAgKiBxdWV1ZS4gIEF0dGVtcHRzIHRvIGFkZEFsbCBvZiBhIHF1ZXVlIHRvIGl0c2VsZiByZXN1bHQgaW4KKy8vICAgICAgKiB7QGNvZGUgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufS4gRnVydGhlciwgdGhlIGJlaGF2aW9yIG9mCisvLyAgICAgICogdGhpcyBvcGVyYXRpb24gaXMgdW5kZWZpbmVkIGlmIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiBpcworLy8gICAgICAqIG1vZGlmaWVkIHdoaWxlIHRoZSBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MuCisvLyAgICAgICoKKy8vICAgICAgKiBAcGFyYW0gYyBjb2xsZWN0aW9uIGNvbnRhaW5pbmcgZWxlbWVudHMgdG8gYmUgYWRkZWQgdG8gdGhpcyBxdWV1ZQorLy8gICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgcXVldWUgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbAorLy8gICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uICAgICAgICAgICAge0Bpbmhlcml0RG9jfQorLy8gICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gICAgICAgICAge0Bpbmhlcml0RG9jfQorLy8gICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICAgICAge0Bpbmhlcml0RG9jfQorLy8gICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uICAgICAgICAge0Bpbmhlcml0RG9jfQorLy8gICAgICAqIEBzZWUgI2FkZChPYmplY3QpCisvLyAgICAgICovCisvLyAgICAgcHVibGljIGJvb2xlYW4gYWRkQWxsKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGMpIHsKKy8vICAgICAgICAgaWYgKGMgPT0gbnVsbCkKKy8vICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworLy8gICAgICAgICBpZiAoYyA9PSB0aGlzKQorLy8gICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworLy8gICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisvLyAgICAgICAgIGxvY2subG9jaygpOworLy8gICAgICAgICB0cnkgeworLy8gICAgICAgICAgICAgYm9vbGVhbiBtb2RpZmllZCA9IGZhbHNlOworLy8gICAgICAgICAgICAgZm9yIChFIGUgOiBjKQorLy8gICAgICAgICAgICAgICAgIGlmIChsaW5rTGFzdChlKSkKKy8vICAgICAgICAgICAgICAgICAgICAgbW9kaWZpZWQgPSB0cnVlOworLy8gICAgICAgICAgICAgcmV0dXJuIG1vZGlmaWVkOworLy8gICAgICAgICB9IGZpbmFsbHkgeworLy8gICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKy8vICAgICAgICAgfQorLy8gICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoaXMgZGVxdWUsIGluCisgICAgICogcHJvcGVyIHNlcXVlbmNlIChmcm9tIGZpcnN0IHRvIGxhc3QgZWxlbWVudCkuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQgYXJyYXkgd2lsbCBiZSAic2FmZSIgaW4gdGhhdCBubyByZWZlcmVuY2VzIHRvIGl0IGFyZQorICAgICAqIG1haW50YWluZWQgYnkgdGhpcyBkZXF1ZS4gIChJbiBvdGhlciB3b3JkcywgdGhpcyBtZXRob2QgbXVzdCBhbGxvY2F0ZQorICAgICAqIGEgbmV3IGFycmF5KS4gIFRoZSBjYWxsZXIgaXMgdGh1cyBmcmVlIHRvIG1vZGlmeSB0aGUgcmV0dXJuZWQgYXJyYXkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBhY3RzIGFzIGJyaWRnZSBiZXR3ZWVuIGFycmF5LWJhc2VkIGFuZCBjb2xsZWN0aW9uLWJhc2VkCisgICAgICogQVBJcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoaXMgZGVxdWUKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE9iamVjdFtdIGEgPSBuZXcgT2JqZWN0W2NvdW50XTsKKyAgICAgICAgICAgIGludCBrID0gMDsKKyAgICAgICAgICAgIGZvciAoTm9kZTxFPiBwID0gZmlyc3Q7IHAgIT0gbnVsbDsgcCA9IHAubmV4dCkKKyAgICAgICAgICAgICAgICBhW2srK10gPSBwLml0ZW07CisgICAgICAgICAgICByZXR1cm4gYTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcgYWxsIG9mIHRoZSBlbGVtZW50cyBpbiB0aGlzIGRlcXVlLCBpbgorICAgICAqIHByb3BlciBzZXF1ZW5jZTsgdGhlIHJ1bnRpbWUgdHlwZSBvZiB0aGUgcmV0dXJuZWQgYXJyYXkgaXMgdGhhdCBvZgorICAgICAqIHRoZSBzcGVjaWZpZWQgYXJyYXkuICBJZiB0aGUgZGVxdWUgZml0cyBpbiB0aGUgc3BlY2lmaWVkIGFycmF5LCBpdAorICAgICAqIGlzIHJldHVybmVkIHRoZXJlaW4uICBPdGhlcndpc2UsIGEgbmV3IGFycmF5IGlzIGFsbG9jYXRlZCB3aXRoIHRoZQorICAgICAqIHJ1bnRpbWUgdHlwZSBvZiB0aGUgc3BlY2lmaWVkIGFycmF5IGFuZCB0aGUgc2l6ZSBvZiB0aGlzIGRlcXVlLgorICAgICAqCisgICAgICogPHA+SWYgdGhpcyBkZXF1ZSBmaXRzIGluIHRoZSBzcGVjaWZpZWQgYXJyYXkgd2l0aCByb29tIHRvIHNwYXJlCisgICAgICogKGkuZS4sIHRoZSBhcnJheSBoYXMgbW9yZSBlbGVtZW50cyB0aGFuIHRoaXMgZGVxdWUpLCB0aGUgZWxlbWVudCBpbgorICAgICAqIHRoZSBhcnJheSBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlIGVuZCBvZiB0aGUgZGVxdWUgaXMgc2V0IHRvCisgICAgICoge0Bjb2RlIG51bGx9LgorICAgICAqCisgICAgICogPHA+TGlrZSB0aGUge0BsaW5rICN0b0FycmF5KCl9IG1ldGhvZCwgdGhpcyBtZXRob2QgYWN0cyBhcyBicmlkZ2UgYmV0d2VlbgorICAgICAqIGFycmF5LWJhc2VkIGFuZCBjb2xsZWN0aW9uLWJhc2VkIEFQSXMuICBGdXJ0aGVyLCB0aGlzIG1ldGhvZCBhbGxvd3MKKyAgICAgKiBwcmVjaXNlIGNvbnRyb2wgb3ZlciB0aGUgcnVudGltZSB0eXBlIG9mIHRoZSBvdXRwdXQgYXJyYXksIGFuZCBtYXksCisgICAgICogdW5kZXIgY2VydGFpbiBjaXJjdW1zdGFuY2VzLCBiZSB1c2VkIHRvIHNhdmUgYWxsb2NhdGlvbiBjb3N0cy4KKyAgICAgKgorICAgICAqIDxwPlN1cHBvc2Uge0Bjb2RlIHh9IGlzIGEgZGVxdWUga25vd24gdG8gY29udGFpbiBvbmx5IHN0cmluZ3MuCisgICAgICogVGhlIGZvbGxvd2luZyBjb2RlIGNhbiBiZSB1c2VkIHRvIGR1bXAgdGhlIGRlcXVlIGludG8gYSBuZXdseQorICAgICAqIGFsbG9jYXRlZCBhcnJheSBvZiB7QGNvZGUgU3RyaW5nfToKKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogICAgIFN0cmluZ1tdIHkgPSB4LnRvQXJyYXkobmV3IFN0cmluZ1swXSk7PC9wcmU+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQge0Bjb2RlIHRvQXJyYXkobmV3IE9iamVjdFswXSl9IGlzIGlkZW50aWNhbCBpbiBmdW5jdGlvbiB0bworICAgICAqIHtAY29kZSB0b0FycmF5KCl9LgorICAgICAqCisgICAgICogQHBhcmFtIGEgdGhlIGFycmF5IGludG8gd2hpY2ggdGhlIGVsZW1lbnRzIG9mIHRoZSBkZXF1ZSBhcmUgdG8KKyAgICAgKiAgICAgICAgICBiZSBzdG9yZWQsIGlmIGl0IGlzIGJpZyBlbm91Z2g7IG90aGVyd2lzZSwgYSBuZXcgYXJyYXkgb2YgdGhlCisgICAgICogICAgICAgICAgc2FtZSBydW50aW1lIHR5cGUgaXMgYWxsb2NhdGVkIGZvciB0aGlzIHB1cnBvc2UKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IGNvbnRhaW5pbmcgYWxsIG9mIHRoZSBlbGVtZW50cyBpbiB0aGlzIGRlcXVlCisgICAgICogQHRocm93cyBBcnJheVN0b3JlRXhjZXB0aW9uIGlmIHRoZSBydW50aW1lIHR5cGUgb2YgdGhlIHNwZWNpZmllZCBhcnJheQorICAgICAqICAgICAgICAgaXMgbm90IGEgc3VwZXJ0eXBlIG9mIHRoZSBydW50aW1lIHR5cGUgb2YgZXZlcnkgZWxlbWVudCBpbgorICAgICAqICAgICAgICAgdGhpcyBkZXF1ZQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBhcnJheSBpcyBudWxsCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIDxUPiBUW10gdG9BcnJheShUW10gYSkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGEubGVuZ3RoIDwgY291bnQpCisgICAgICAgICAgICAgICAgYSA9IChUW10pamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkubmV3SW5zdGFuY2UKKyAgICAgICAgICAgICAgICAgICAgKGEuZ2V0Q2xhc3MoKS5nZXRDb21wb25lbnRUeXBlKCksIGNvdW50KTsKKworICAgICAgICAgICAgaW50IGsgPSAwOworICAgICAgICAgICAgZm9yIChOb2RlPEU+IHAgPSBmaXJzdDsgcCAhPSBudWxsOyBwID0gcC5uZXh0KQorICAgICAgICAgICAgICAgIGFbaysrXSA9IChUKXAuaXRlbTsKKyAgICAgICAgICAgIGlmIChhLmxlbmd0aCA+IGspCisgICAgICAgICAgICAgICAgYVtrXSA9IG51bGw7CisgICAgICAgICAgICByZXR1cm4gYTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgTm9kZTxFPiBwID0gZmlyc3Q7CisgICAgICAgICAgICBpZiAocCA9PSBudWxsKQorICAgICAgICAgICAgICAgIHJldHVybiAiW10iOworCisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgnWycpOworICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIEUgZSA9IHAuaXRlbTsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoZSA9PSB0aGlzID8gIih0aGlzIENvbGxlY3Rpb24pIiA6IGUpOworICAgICAgICAgICAgICAgIHAgPSBwLm5leHQ7CisgICAgICAgICAgICAgICAgaWYgKHAgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNiLmFwcGVuZCgnXScpLnRvU3RyaW5nKCk7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCcsJykuYXBwZW5kKCcgJyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSByZW1vdmVzIGFsbCBvZiB0aGUgZWxlbWVudHMgZnJvbSB0aGlzIGRlcXVlLgorICAgICAqIFRoZSBkZXF1ZSB3aWxsIGJlIGVtcHR5IGFmdGVyIHRoaXMgY2FsbCByZXR1cm5zLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yIChOb2RlPEU+IGYgPSBmaXJzdDsgZiAhPSBudWxsOyApIHsKKyAgICAgICAgICAgICAgICBmLml0ZW0gPSBudWxsOworICAgICAgICAgICAgICAgIE5vZGU8RT4gbiA9IGYubmV4dDsKKyAgICAgICAgICAgICAgICBmLnByZXYgPSBudWxsOworICAgICAgICAgICAgICAgIGYubmV4dCA9IG51bGw7CisgICAgICAgICAgICAgICAgZiA9IG47CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmaXJzdCA9IGxhc3QgPSBudWxsOworICAgICAgICAgICAgY291bnQgPSAwOworICAgICAgICAgICAgbm90RnVsbC5zaWduYWxBbGwoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzIGluIHRoaXMgZGVxdWUgaW4gcHJvcGVyIHNlcXVlbmNlLgorICAgICAqIFRoZSBlbGVtZW50cyB3aWxsIGJlIHJldHVybmVkIGluIG9yZGVyIGZyb20gZmlyc3QgKGhlYWQpIHRvIGxhc3QgKHRhaWwpLgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybmVkIGl0ZXJhdG9yIGlzIGEgIndlYWtseSBjb25zaXN0ZW50IiBpdGVyYXRvciB0aGF0CisgICAgICogd2lsbCBuZXZlciB0aHJvdyB7QGxpbmsgamF2YS51dGlsLkNvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24KKyAgICAgKiBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9ufSwgYW5kIGd1YXJhbnRlZXMgdG8gdHJhdmVyc2UKKyAgICAgKiBlbGVtZW50cyBhcyB0aGV5IGV4aXN0ZWQgdXBvbiBjb25zdHJ1Y3Rpb24gb2YgdGhlIGl0ZXJhdG9yLCBhbmQKKyAgICAgKiBtYXkgKGJ1dCBpcyBub3QgZ3VhcmFudGVlZCB0bykgcmVmbGVjdCBhbnkgbW9kaWZpY2F0aW9ucworICAgICAqIHN1YnNlcXVlbnQgdG8gY29uc3RydWN0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cyBpbiB0aGlzIGRlcXVlIGluIHByb3BlciBzZXF1ZW5jZQorICAgICAqLworICAgIHB1YmxpYyBJdGVyYXRvcjxFPiBpdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBJdHIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzIGluIHRoaXMgZGVxdWUgaW4gcmV2ZXJzZQorICAgICAqIHNlcXVlbnRpYWwgb3JkZXIuICBUaGUgZWxlbWVudHMgd2lsbCBiZSByZXR1cm5lZCBpbiBvcmRlciBmcm9tCisgICAgICogbGFzdCAodGFpbCkgdG8gZmlyc3QgKGhlYWQpLgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybmVkIGl0ZXJhdG9yIGlzIGEgIndlYWtseSBjb25zaXN0ZW50IiBpdGVyYXRvciB0aGF0CisgICAgICogd2lsbCBuZXZlciB0aHJvdyB7QGxpbmsgamF2YS51dGlsLkNvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24KKyAgICAgKiBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9ufSwgYW5kIGd1YXJhbnRlZXMgdG8gdHJhdmVyc2UKKyAgICAgKiBlbGVtZW50cyBhcyB0aGV5IGV4aXN0ZWQgdXBvbiBjb25zdHJ1Y3Rpb24gb2YgdGhlIGl0ZXJhdG9yLCBhbmQKKyAgICAgKiBtYXkgKGJ1dCBpcyBub3QgZ3VhcmFudGVlZCB0bykgcmVmbGVjdCBhbnkgbW9kaWZpY2F0aW9ucworICAgICAqIHN1YnNlcXVlbnQgdG8gY29uc3RydWN0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cyBpbiB0aGlzIGRlcXVlIGluIHJldmVyc2Ugb3JkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3I8RT4gZGVzY2VuZGluZ0l0ZXJhdG9yKCkgeworICAgICAgICByZXR1cm4gbmV3IERlc2NlbmRpbmdJdHIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBCYXNlIGNsYXNzIGZvciBJdGVyYXRvcnMgZm9yIExpbmtlZEJsb2NraW5nRGVxdWUKKyAgICAgKi8KKyAgICBwcml2YXRlIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0SXRyIGltcGxlbWVudHMgSXRlcmF0b3I8RT4geworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIG5leHQgbm9kZSB0byByZXR1cm4gaW4gbmV4dCgpCisgICAgICAgICAqLworICAgICAgICAgTm9kZTxFPiBuZXh0OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBuZXh0SXRlbSBob2xkcyBvbiB0byBpdGVtIGZpZWxkcyBiZWNhdXNlIG9uY2Ugd2UgY2xhaW0gdGhhdAorICAgICAgICAgKiBhbiBlbGVtZW50IGV4aXN0cyBpbiBoYXNOZXh0KCksIHdlIG11c3QgcmV0dXJuIGl0ZW0gcmVhZAorICAgICAgICAgKiB1bmRlciBsb2NrIChpbiBhZHZhbmNlKCkpIGV2ZW4gaWYgaXQgd2FzIGluIHRoZSBwcm9jZXNzIG9mCisgICAgICAgICAqIGJlaW5nIHJlbW92ZWQgd2hlbiBoYXNOZXh0KCkgd2FzIGNhbGxlZC4KKyAgICAgICAgICovCisgICAgICAgIEUgbmV4dEl0ZW07CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE5vZGUgcmV0dXJuZWQgYnkgbW9zdCByZWNlbnQgY2FsbCB0byBuZXh0LiBOZWVkZWQgYnkgcmVtb3ZlLgorICAgICAgICAgKiBSZXNldCB0byBudWxsIGlmIHRoaXMgZWxlbWVudCBpcyBkZWxldGVkIGJ5IGEgY2FsbCB0byByZW1vdmUuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIE5vZGU8RT4gbGFzdFJldDsKKworICAgICAgICBhYnN0cmFjdCBOb2RlPEU+IGZpcnN0Tm9kZSgpOworICAgICAgICBhYnN0cmFjdCBOb2RlPEU+IG5leHROb2RlKE5vZGU8RT4gbik7CisKKyAgICAgICAgQWJzdHJhY3RJdHIoKSB7CisgICAgICAgICAgICAvLyBzZXQgdG8gaW5pdGlhbCBwb3NpdGlvbgorICAgICAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gTGlua2VkQmxvY2tpbmdEZXF1ZS50aGlzLmxvY2s7CisgICAgICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbmV4dCA9IGZpcnN0Tm9kZSgpOworICAgICAgICAgICAgICAgIG5leHRJdGVtID0gKG5leHQgPT0gbnVsbCkgPyBudWxsIDogbmV4dC5pdGVtOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIHN1Y2Nlc3NvciBub2RlIG9mIHRoZSBnaXZlbiBub24tbnVsbCwgYnV0CisgICAgICAgICAqIHBvc3NpYmx5IHByZXZpb3VzbHkgZGVsZXRlZCwgbm9kZS4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgTm9kZTxFPiBzdWNjKE5vZGU8RT4gbikgeworICAgICAgICAgICAgLy8gQ2hhaW5zIG9mIGRlbGV0ZWQgbm9kZXMgZW5kaW5nIGluIG51bGwgb3Igc2VsZi1saW5rcworICAgICAgICAgICAgLy8gYXJlIHBvc3NpYmxlIGlmIG11bHRpcGxlIGludGVyaW9yIG5vZGVzIGFyZSByZW1vdmVkLgorICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIE5vZGU8RT4gcyA9IG5leHROb2RlKG4pOworICAgICAgICAgICAgICAgIGlmIChzID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIGVsc2UgaWYgKHMuaXRlbSAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gczsKKyAgICAgICAgICAgICAgICBlbHNlIGlmIChzID09IG4pCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmaXJzdE5vZGUoKTsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIG4gPSBzOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEFkdmFuY2VzIG5leHQuCisgICAgICAgICAqLworICAgICAgICB2b2lkIGFkdmFuY2UoKSB7CisgICAgICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSBMaW5rZWRCbG9ja2luZ0RlcXVlLnRoaXMubG9jazsKKyAgICAgICAgICAgIGxvY2subG9jaygpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAvLyBhc3NlcnQgbmV4dCAhPSBudWxsOworICAgICAgICAgICAgICAgIG5leHQgPSBzdWNjKG5leHQpOworICAgICAgICAgICAgICAgIG5leHRJdGVtID0gKG5leHQgPT0gbnVsbCkgPyBudWxsIDogbmV4dC5pdGVtOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXh0ICE9IG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgRSBuZXh0KCkgeworICAgICAgICAgICAgaWYgKG5leHQgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgbGFzdFJldCA9IG5leHQ7CisgICAgICAgICAgICBFIHggPSBuZXh0SXRlbTsKKyAgICAgICAgICAgIGFkdmFuY2UoKTsKKyAgICAgICAgICAgIHJldHVybiB4OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICAgICAgTm9kZTxFPiBuID0gbGFzdFJldDsKKyAgICAgICAgICAgIGlmIChuID09IG51bGwpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgbGFzdFJldCA9IG51bGw7CisgICAgICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSBMaW5rZWRCbG9ja2luZ0RlcXVlLnRoaXMubG9jazsKKyAgICAgICAgICAgIGxvY2subG9jaygpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAobi5pdGVtICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIHVubGluayhuKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKiBGb3J3YXJkIGl0ZXJhdG9yICovCisgICAgcHJpdmF0ZSBjbGFzcyBJdHIgZXh0ZW5kcyBBYnN0cmFjdEl0ciB7CisgICAgICAgIE5vZGU8RT4gZmlyc3ROb2RlKCkgeyByZXR1cm4gZmlyc3Q7IH0KKyAgICAgICAgTm9kZTxFPiBuZXh0Tm9kZShOb2RlPEU+IG4pIHsgcmV0dXJuIG4ubmV4dDsgfQorICAgIH0KKworICAgIC8qKiBEZXNjZW5kaW5nIGl0ZXJhdG9yICovCisgICAgcHJpdmF0ZSBjbGFzcyBEZXNjZW5kaW5nSXRyIGV4dGVuZHMgQWJzdHJhY3RJdHIgeworICAgICAgICBOb2RlPEU+IGZpcnN0Tm9kZSgpIHsgcmV0dXJuIGxhc3Q7IH0KKyAgICAgICAgTm9kZTxFPiBuZXh0Tm9kZShOb2RlPEU+IG4pIHsgcmV0dXJuIG4ucHJldjsgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNhdmUgdGhlIHN0YXRlIG9mIHRoaXMgZGVxdWUgdG8gYSBzdHJlYW0gKHRoYXQgaXMsIHNlcmlhbGl6ZSBpdCkuCisgICAgICoKKyAgICAgKiBAc2VyaWFsRGF0YSBUaGUgY2FwYWNpdHkgKGludCksIGZvbGxvd2VkIGJ5IGVsZW1lbnRzIChlYWNoIGFuCisgICAgICoge0Bjb2RlIE9iamVjdH0pIGluIHRoZSBwcm9wZXIgb3JkZXIsIGZvbGxvd2VkIGJ5IGEgbnVsbAorICAgICAqIEBwYXJhbSBzIHRoZSBzdHJlYW0KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW0gcykKKyAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gV3JpdGUgb3V0IGNhcGFjaXR5IGFuZCBhbnkgaGlkZGVuIHN0dWZmCisgICAgICAgICAgICBzLmRlZmF1bHRXcml0ZU9iamVjdCgpOworICAgICAgICAgICAgLy8gV3JpdGUgb3V0IGFsbCBlbGVtZW50cyBpbiB0aGUgcHJvcGVyIG9yZGVyLgorICAgICAgICAgICAgZm9yIChOb2RlPEU+IHAgPSBmaXJzdDsgcCAhPSBudWxsOyBwID0gcC5uZXh0KQorICAgICAgICAgICAgICAgIHMud3JpdGVPYmplY3QocC5pdGVtKTsKKyAgICAgICAgICAgIC8vIFVzZSB0cmFpbGluZyBudWxsIGFzIHNlbnRpbmVsCisgICAgICAgICAgICBzLndyaXRlT2JqZWN0KG51bGwpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlY29uc3RpdHV0ZSB0aGlzIGRlcXVlIGZyb20gYSBzdHJlYW0gKHRoYXQgaXMsCisgICAgICogZGVzZXJpYWxpemUgaXQpLgorICAgICAqIEBwYXJhbSBzIHRoZSBzdHJlYW0KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtIHMpCisgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgcy5kZWZhdWx0UmVhZE9iamVjdCgpOworICAgICAgICBjb3VudCA9IDA7CisgICAgICAgIGZpcnN0ID0gbnVsbDsKKyAgICAgICAgbGFzdCA9IG51bGw7CisgICAgICAgIC8vIFJlYWQgaW4gYWxsIGVsZW1lbnRzIGFuZCBwbGFjZSBpbiBxdWV1ZQorICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgICAgIEUgaXRlbSA9IChFKXMucmVhZE9iamVjdCgpOworICAgICAgICAgICAgaWYgKGl0ZW0gPT0gbnVsbCkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGFkZChpdGVtKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L0xpbmtlZEJsb2NraW5nUXVldWUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9MaW5rZWRCbG9ja2luZ1F1ZXVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDA2YzczNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9MaW5rZWRCbG9ja2luZ1F1ZXVlLmphdmEKQEAgLTAsMCArMSw4ODEgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudDsKKworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNJbnRlZ2VyOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLkNvbmRpdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5SZWVudHJhbnRMb2NrOworaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdFF1ZXVlOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKKworLy8gQkVHSU4gYW5kcm9pZC1ub3RlCisvLyByZW1vdmVkIGxpbmsgdG8gY29sbGVjdGlvbnMgZnJhbWV3b3JrIGRvY3MKKy8vIEVORCBhbmRyb2lkLW5vdGUKKworLyoqCisgKiBBbiBvcHRpb25hbGx5LWJvdW5kZWQge0BsaW5rcGxhaW4gQmxvY2tpbmdRdWV1ZSBibG9ja2luZyBxdWV1ZX0gYmFzZWQgb24KKyAqIGxpbmtlZCBub2Rlcy4KKyAqIFRoaXMgcXVldWUgb3JkZXJzIGVsZW1lbnRzIEZJRk8gKGZpcnN0LWluLWZpcnN0LW91dCkuCisgKiBUaGUgPGVtPmhlYWQ8L2VtPiBvZiB0aGUgcXVldWUgaXMgdGhhdCBlbGVtZW50IHRoYXQgaGFzIGJlZW4gb24gdGhlCisgKiBxdWV1ZSB0aGUgbG9uZ2VzdCB0aW1lLgorICogVGhlIDxlbT50YWlsPC9lbT4gb2YgdGhlIHF1ZXVlIGlzIHRoYXQgZWxlbWVudCB0aGF0IGhhcyBiZWVuIG9uIHRoZQorICogcXVldWUgdGhlIHNob3J0ZXN0IHRpbWUuIE5ldyBlbGVtZW50cworICogYXJlIGluc2VydGVkIGF0IHRoZSB0YWlsIG9mIHRoZSBxdWV1ZSwgYW5kIHRoZSBxdWV1ZSByZXRyaWV2YWwKKyAqIG9wZXJhdGlvbnMgb2J0YWluIGVsZW1lbnRzIGF0IHRoZSBoZWFkIG9mIHRoZSBxdWV1ZS4KKyAqIExpbmtlZCBxdWV1ZXMgdHlwaWNhbGx5IGhhdmUgaGlnaGVyIHRocm91Z2hwdXQgdGhhbiBhcnJheS1iYXNlZCBxdWV1ZXMgYnV0CisgKiBsZXNzIHByZWRpY3RhYmxlIHBlcmZvcm1hbmNlIGluIG1vc3QgY29uY3VycmVudCBhcHBsaWNhdGlvbnMuCisgKgorICogPHA+IFRoZSBvcHRpb25hbCBjYXBhY2l0eSBib3VuZCBjb25zdHJ1Y3RvciBhcmd1bWVudCBzZXJ2ZXMgYXMgYQorICogd2F5IHRvIHByZXZlbnQgZXhjZXNzaXZlIHF1ZXVlIGV4cGFuc2lvbi4gVGhlIGNhcGFjaXR5LCBpZiB1bnNwZWNpZmllZCwKKyAqIGlzIGVxdWFsIHRvIHtAbGluayBJbnRlZ2VyI01BWF9WQUxVRX0uICBMaW5rZWQgbm9kZXMgYXJlCisgKiBkeW5hbWljYWxseSBjcmVhdGVkIHVwb24gZWFjaCBpbnNlcnRpb24gdW5sZXNzIHRoaXMgd291bGQgYnJpbmcgdGhlCisgKiBxdWV1ZSBhYm92ZSBjYXBhY2l0eS4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGFuZCBpdHMgaXRlcmF0b3IgaW1wbGVtZW50IGFsbCBvZiB0aGUKKyAqIDxlbT5vcHRpb25hbDwvZW0+IG1ldGhvZHMgb2YgdGhlIHtAbGluayBDb2xsZWN0aW9ufSBhbmQge0BsaW5rCisgKiBJdGVyYXRvcn0gaW50ZXJmYWNlcy4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKiBAcGFyYW0gPEU+IHRoZSB0eXBlIG9mIGVsZW1lbnRzIGhlbGQgaW4gdGhpcyBjb2xsZWN0aW9uCisgKgorICovCitwdWJsaWMgY2xhc3MgTGlua2VkQmxvY2tpbmdRdWV1ZTxFPiBleHRlbmRzIEFic3RyYWN0UXVldWU8RT4KKyAgICAgICAgaW1wbGVtZW50cyBCbG9ja2luZ1F1ZXVlPEU+LCBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTY5MDM5MzM5Nzc1OTE3MDkxOTRMOworCisgICAgLyoKKyAgICAgKiBBIHZhcmlhbnQgb2YgdGhlICJ0d28gbG9jayBxdWV1ZSIgYWxnb3JpdGhtLiAgVGhlIHB1dExvY2sgZ2F0ZXMKKyAgICAgKiBlbnRyeSB0byBwdXQgKGFuZCBvZmZlciksIGFuZCBoYXMgYW4gYXNzb2NpYXRlZCBjb25kaXRpb24gZm9yCisgICAgICogd2FpdGluZyBwdXRzLiAgU2ltaWxhcmx5IGZvciB0aGUgdGFrZUxvY2suICBUaGUgImNvdW50IiBmaWVsZAorICAgICAqIHRoYXQgdGhleSBib3RoIHJlbHkgb24gaXMgbWFpbnRhaW5lZCBhcyBhbiBhdG9taWMgdG8gYXZvaWQKKyAgICAgKiBuZWVkaW5nIHRvIGdldCBib3RoIGxvY2tzIGluIG1vc3QgY2FzZXMuIEFsc28sIHRvIG1pbmltaXplIG5lZWQKKyAgICAgKiBmb3IgcHV0cyB0byBnZXQgdGFrZUxvY2sgYW5kIHZpY2UtdmVyc2EsIGNhc2NhZGluZyBub3RpZmllcyBhcmUKKyAgICAgKiB1c2VkLiBXaGVuIGEgcHV0IG5vdGljZXMgdGhhdCBpdCBoYXMgZW5hYmxlZCBhdCBsZWFzdCBvbmUgdGFrZSwKKyAgICAgKiBpdCBzaWduYWxzIHRha2VyLiBUaGF0IHRha2VyIGluIHR1cm4gc2lnbmFscyBvdGhlcnMgaWYgbW9yZQorICAgICAqIGl0ZW1zIGhhdmUgYmVlbiBlbnRlcmVkIHNpbmNlIHRoZSBzaWduYWwuIEFuZCBzeW1tZXRyaWNhbGx5IGZvcgorICAgICAqIHRha2VzIHNpZ25hbGxpbmcgcHV0cy4gT3BlcmF0aW9ucyBzdWNoIGFzIHJlbW92ZShPYmplY3QpIGFuZAorICAgICAqIGl0ZXJhdG9ycyBhY3F1aXJlIGJvdGggbG9ja3MuCisgICAgICoKKyAgICAgKiBWaXNpYmlsaXR5IGJldHdlZW4gd3JpdGVycyBhbmQgcmVhZGVycyBpcyBwcm92aWRlZCBhcyBmb2xsb3dzOgorICAgICAqCisgICAgICogV2hlbmV2ZXIgYW4gZWxlbWVudCBpcyBlbnF1ZXVlZCwgdGhlIHB1dExvY2sgaXMgYWNxdWlyZWQgYW5kCisgICAgICogY291bnQgdXBkYXRlZC4gIEEgc3Vic2VxdWVudCByZWFkZXIgZ3VhcmFudGVlcyB2aXNpYmlsaXR5IHRvIHRoZQorICAgICAqIGVucXVldWVkIE5vZGUgYnkgZWl0aGVyIGFjcXVpcmluZyB0aGUgcHV0TG9jayAodmlhIGZ1bGx5TG9jaykKKyAgICAgKiBvciBieSBhY3F1aXJpbmcgdGhlIHRha2VMb2NrLCBhbmQgdGhlbiByZWFkaW5nIG4gPSBjb3VudC5nZXQoKTsKKyAgICAgKiB0aGlzIGdpdmVzIHZpc2liaWxpdHkgdG8gdGhlIGZpcnN0IG4gaXRlbXMuCisgICAgICoKKyAgICAgKiBUbyBpbXBsZW1lbnQgd2Vha2x5IGNvbnNpc3RlbnQgaXRlcmF0b3JzLCBpdCBhcHBlYXJzIHdlIG5lZWQgdG8KKyAgICAgKiBrZWVwIGFsbCBOb2RlcyBHQy1yZWFjaGFibGUgZnJvbSBhIHByZWRlY2Vzc29yIGRlcXVldWVkIE5vZGUuCisgICAgICogVGhhdCB3b3VsZCBjYXVzZSB0d28gcHJvYmxlbXM6CisgICAgICogLSBhbGxvdyBhIHJvZ3VlIEl0ZXJhdG9yIHRvIGNhdXNlIHVuYm91bmRlZCBtZW1vcnkgcmV0ZW50aW9uCisgICAgICogLSBjYXVzZSBjcm9zcy1nZW5lcmF0aW9uYWwgbGlua2luZyBvZiBvbGQgTm9kZXMgdG8gbmV3IE5vZGVzIGlmCisgICAgICogICBhIE5vZGUgd2FzIHRlbnVyZWQgd2hpbGUgbGl2ZSwgd2hpY2ggZ2VuZXJhdGlvbmFsIEdDcyBoYXZlIGEKKyAgICAgKiAgIGhhcmQgdGltZSBkZWFsaW5nIHdpdGgsIGNhdXNpbmcgcmVwZWF0ZWQgbWFqb3IgY29sbGVjdGlvbnMuCisgICAgICogSG93ZXZlciwgb25seSBub24tZGVsZXRlZCBOb2RlcyBuZWVkIHRvIGJlIHJlYWNoYWJsZSBmcm9tCisgICAgICogZGVxdWV1ZWQgTm9kZXMsIGFuZCByZWFjaGFiaWxpdHkgZG9lcyBub3QgbmVjZXNzYXJpbHkgaGF2ZSB0bworICAgICAqIGJlIG9mIHRoZSBraW5kIHVuZGVyc3Rvb2QgYnkgdGhlIEdDLiAgV2UgdXNlIHRoZSB0cmljayBvZgorICAgICAqIGxpbmtpbmcgYSBOb2RlIHRoYXQgaGFzIGp1c3QgYmVlbiBkZXF1ZXVlZCB0byBpdHNlbGYuICBTdWNoIGEKKyAgICAgKiBzZWxmLWxpbmsgaW1wbGljaXRseSBtZWFucyB0byBhZHZhbmNlIHRvIGhlYWQubmV4dC4KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIExpbmtlZCBsaXN0IG5vZGUgY2xhc3MKKyAgICAgKi8KKyAgICBzdGF0aWMgY2xhc3MgTm9kZTxFPiB7CisgICAgICAgIEUgaXRlbTsKKworICAgICAgICAvKioKKyAgICAgICAgICogT25lIG9mOgorICAgICAgICAgKiAtIHRoZSByZWFsIHN1Y2Nlc3NvciBOb2RlCisgICAgICAgICAqIC0gdGhpcyBOb2RlLCBtZWFuaW5nIHRoZSBzdWNjZXNzb3IgaXMgaGVhZC5uZXh0CisgICAgICAgICAqIC0gbnVsbCwgbWVhbmluZyB0aGVyZSBpcyBubyBzdWNjZXNzb3IgKHRoaXMgaXMgdGhlIGxhc3Qgbm9kZSkKKyAgICAgICAgICovCisgICAgICAgIE5vZGU8RT4gbmV4dDsKKworICAgICAgICBOb2RlKEUgeCkgeyBpdGVtID0geDsgfQorICAgIH0KKworICAgIC8qKiBUaGUgY2FwYWNpdHkgYm91bmQsIG9yIEludGVnZXIuTUFYX1ZBTFVFIGlmIG5vbmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBjYXBhY2l0eTsKKworICAgIC8qKiBDdXJyZW50IG51bWJlciBvZiBlbGVtZW50cyAqLworICAgIHByaXZhdGUgZmluYWwgQXRvbWljSW50ZWdlciBjb3VudCA9IG5ldyBBdG9taWNJbnRlZ2VyKDApOworCisgICAgLyoqCisgICAgICogSGVhZCBvZiBsaW5rZWQgbGlzdC4KKyAgICAgKiBJbnZhcmlhbnQ6IGhlYWQuaXRlbSA9PSBudWxsCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgTm9kZTxFPiBoZWFkOworCisgICAgLyoqCisgICAgICogVGFpbCBvZiBsaW5rZWQgbGlzdC4KKyAgICAgKiBJbnZhcmlhbnQ6IGxhc3QubmV4dCA9PSBudWxsCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgTm9kZTxFPiBsYXN0OworCisgICAgLyoqIExvY2sgaGVsZCBieSB0YWtlLCBwb2xsLCBldGMgKi8KKyAgICBwcml2YXRlIGZpbmFsIFJlZW50cmFudExvY2sgdGFrZUxvY2sgPSBuZXcgUmVlbnRyYW50TG9jaygpOworCisgICAgLyoqIFdhaXQgcXVldWUgZm9yIHdhaXRpbmcgdGFrZXMgKi8KKyAgICBwcml2YXRlIGZpbmFsIENvbmRpdGlvbiBub3RFbXB0eSA9IHRha2VMb2NrLm5ld0NvbmRpdGlvbigpOworCisgICAgLyoqIExvY2sgaGVsZCBieSBwdXQsIG9mZmVyLCBldGMgKi8KKyAgICBwcml2YXRlIGZpbmFsIFJlZW50cmFudExvY2sgcHV0TG9jayA9IG5ldyBSZWVudHJhbnRMb2NrKCk7CisKKyAgICAvKiogV2FpdCBxdWV1ZSBmb3Igd2FpdGluZyBwdXRzICovCisgICAgcHJpdmF0ZSBmaW5hbCBDb25kaXRpb24gbm90RnVsbCA9IHB1dExvY2submV3Q29uZGl0aW9uKCk7CisKKyAgICAvKioKKyAgICAgKiBTaWduYWxzIGEgd2FpdGluZyB0YWtlLiBDYWxsZWQgb25seSBmcm9tIHB1dC9vZmZlciAod2hpY2ggZG8gbm90CisgICAgICogb3RoZXJ3aXNlIG9yZGluYXJpbHkgbG9jayB0YWtlTG9jay4pCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNpZ25hbE5vdEVtcHR5KCkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIHRha2VMb2NrID0gdGhpcy50YWtlTG9jazsKKyAgICAgICAgdGFrZUxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbm90RW1wdHkuc2lnbmFsKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0YWtlTG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNpZ25hbHMgYSB3YWl0aW5nIHB1dC4gQ2FsbGVkIG9ubHkgZnJvbSB0YWtlL3BvbGwuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNpZ25hbE5vdEZ1bGwoKSB7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgcHV0TG9jayA9IHRoaXMucHV0TG9jazsKKyAgICAgICAgcHV0TG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBub3RGdWxsLnNpZ25hbCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgcHV0TG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIExpbmtzIG5vZGUgYXQgZW5kIG9mIHF1ZXVlLgorICAgICAqCisgICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZW5xdWV1ZShOb2RlPEU+IG5vZGUpIHsKKyAgICAgICAgLy8gYXNzZXJ0IHB1dExvY2suaXNIZWxkQnlDdXJyZW50VGhyZWFkKCk7CisgICAgICAgIC8vIGFzc2VydCBsYXN0Lm5leHQgPT0gbnVsbDsKKyAgICAgICAgbGFzdCA9IGxhc3QubmV4dCA9IG5vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhIG5vZGUgZnJvbSBoZWFkIG9mIHF1ZXVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbm9kZQorICAgICAqLworICAgIHByaXZhdGUgRSBkZXF1ZXVlKCkgeworICAgICAgICAvLyBhc3NlcnQgdGFrZUxvY2suaXNIZWxkQnlDdXJyZW50VGhyZWFkKCk7CisgICAgICAgIC8vIGFzc2VydCBoZWFkLml0ZW0gPT0gbnVsbDsKKyAgICAgICAgTm9kZTxFPiBoID0gaGVhZDsKKyAgICAgICAgTm9kZTxFPiBmaXJzdCA9IGgubmV4dDsKKyAgICAgICAgaC5uZXh0ID0gaDsgLy8gaGVscCBHQworICAgICAgICBoZWFkID0gZmlyc3Q7CisgICAgICAgIEUgeCA9IGZpcnN0Lml0ZW07CisgICAgICAgIGZpcnN0Lml0ZW0gPSBudWxsOworICAgICAgICByZXR1cm4geDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2NrIHRvIHByZXZlbnQgYm90aCBwdXRzIGFuZCB0YWtlcy4KKyAgICAgKi8KKyAgICB2b2lkIGZ1bGx5TG9jaygpIHsKKyAgICAgICAgcHV0TG9jay5sb2NrKCk7CisgICAgICAgIHRha2VMb2NrLmxvY2soKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVbmxvY2sgdG8gYWxsb3cgYm90aCBwdXRzIGFuZCB0YWtlcy4KKyAgICAgKi8KKyAgICB2b2lkIGZ1bGx5VW5sb2NrKCkgeworICAgICAgICB0YWtlTG9jay51bmxvY2soKTsKKyAgICAgICAgcHV0TG9jay51bmxvY2soKTsKKyAgICB9CisKKy8vICAgICAvKioKKy8vICAgICAgKiBUZWxscyB3aGV0aGVyIGJvdGggbG9ja3MgYXJlIGhlbGQgYnkgY3VycmVudCB0aHJlYWQuCisvLyAgICAgICovCisvLyAgICAgYm9vbGVhbiBpc0Z1bGx5TG9ja2VkKCkgeworLy8gICAgICAgICByZXR1cm4gKHB1dExvY2suaXNIZWxkQnlDdXJyZW50VGhyZWFkKCkgJiYKKy8vICAgICAgICAgICAgICAgICB0YWtlTG9jay5pc0hlbGRCeUN1cnJlbnRUaHJlYWQoKSk7CisvLyAgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHtAY29kZSBMaW5rZWRCbG9ja2luZ1F1ZXVlfSB3aXRoIGEgY2FwYWNpdHkgb2YKKyAgICAgKiB7QGxpbmsgSW50ZWdlciNNQVhfVkFMVUV9LgorICAgICAqLworICAgIHB1YmxpYyBMaW5rZWRCbG9ja2luZ1F1ZXVlKCkgeworICAgICAgICB0aGlzKEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIExpbmtlZEJsb2NraW5nUXVldWV9IHdpdGggdGhlIGdpdmVuIChmaXhlZCkgY2FwYWNpdHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2FwYWNpdHkgdGhlIGNhcGFjaXR5IG9mIHRoaXMgcXVldWUKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgY2FwYWNpdHl9IGlzIG5vdCBncmVhdGVyCisgICAgICogICAgICAgICB0aGFuIHplcm8KKyAgICAgKi8KKyAgICBwdWJsaWMgTGlua2VkQmxvY2tpbmdRdWV1ZShpbnQgY2FwYWNpdHkpIHsKKyAgICAgICAgaWYgKGNhcGFjaXR5IDw9IDApIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgdGhpcy5jYXBhY2l0eSA9IGNhcGFjaXR5OworICAgICAgICBsYXN0ID0gaGVhZCA9IG5ldyBOb2RlPEU+KG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgTGlua2VkQmxvY2tpbmdRdWV1ZX0gd2l0aCBhIGNhcGFjaXR5IG9mCisgICAgICoge0BsaW5rIEludGVnZXIjTUFYX1ZBTFVFfSwgaW5pdGlhbGx5IGNvbnRhaW5pbmcgdGhlIGVsZW1lbnRzIG9mIHRoZQorICAgICAqIGdpdmVuIGNvbGxlY3Rpb24sCisgICAgICogYWRkZWQgaW4gdHJhdmVyc2FsIG9yZGVyIG9mIHRoZSBjb2xsZWN0aW9uJ3MgaXRlcmF0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYyB0aGUgY29sbGVjdGlvbiBvZiBlbGVtZW50cyB0byBpbml0aWFsbHkgY29udGFpbgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBjb2xsZWN0aW9uIG9yIGFueQorICAgICAqICAgICAgICAgb2YgaXRzIGVsZW1lbnRzIGFyZSBudWxsCisgICAgICovCisgICAgcHVibGljIExpbmtlZEJsb2NraW5nUXVldWUoQ29sbGVjdGlvbjw/IGV4dGVuZHMgRT4gYykgeworICAgICAgICB0aGlzKEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBwdXRMb2NrID0gdGhpcy5wdXRMb2NrOworICAgICAgICBwdXRMb2NrLmxvY2soKTsgLy8gTmV2ZXIgY29udGVuZGVkLCBidXQgbmVjZXNzYXJ5IGZvciB2aXNpYmlsaXR5CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgbiA9IDA7CisgICAgICAgICAgICBmb3IgKEUgZSA6IGMpIHsKKyAgICAgICAgICAgICAgICBpZiAoZSA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICBpZiAobiA9PSBjYXBhY2l0eSkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiUXVldWUgZnVsbCIpOworICAgICAgICAgICAgICAgIGVucXVldWUobmV3IE5vZGU8RT4oZSkpOworICAgICAgICAgICAgICAgICsrbjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvdW50LnNldChuKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHB1dExvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKworICAgIC8vIHRoaXMgZG9jIGNvbW1lbnQgaXMgb3ZlcnJpZGRlbiB0byByZW1vdmUgdGhlIHJlZmVyZW5jZSB0byBjb2xsZWN0aW9ucworICAgIC8vIGdyZWF0ZXIgaW4gc2l6ZSB0aGFuIEludGVnZXIuTUFYX1ZBTFVFCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgcXVldWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBxdWV1ZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIGNvdW50LmdldCgpOworICAgIH0KKworICAgIC8vIHRoaXMgZG9jIGNvbW1lbnQgaXMgYSBtb2RpZmllZCBjb3B5IG9mIHRoZSBpbmhlcml0ZWQgZG9jIGNvbW1lbnQsCisgICAgLy8gd2l0aG91dCB0aGUgcmVmZXJlbmNlIHRvIHVubGltaXRlZCBxdWV1ZXMuCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGFkZGl0aW9uYWwgZWxlbWVudHMgdGhhdCB0aGlzIHF1ZXVlIGNhbiBpZGVhbGx5CisgICAgICogKGluIHRoZSBhYnNlbmNlIG9mIG1lbW9yeSBvciByZXNvdXJjZSBjb25zdHJhaW50cykgYWNjZXB0IHdpdGhvdXQKKyAgICAgKiBibG9ja2luZy4gVGhpcyBpcyBhbHdheXMgZXF1YWwgdG8gdGhlIGluaXRpYWwgY2FwYWNpdHkgb2YgdGhpcyBxdWV1ZQorICAgICAqIGxlc3MgdGhlIGN1cnJlbnQge0Bjb2RlIHNpemV9IG9mIHRoaXMgcXVldWUuCisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoYXQgeW91IDxlbT5jYW5ub3Q8L2VtPiBhbHdheXMgdGVsbCBpZiBhbiBhdHRlbXB0IHRvIGluc2VydAorICAgICAqIGFuIGVsZW1lbnQgd2lsbCBzdWNjZWVkIGJ5IGluc3BlY3Rpbmcge0Bjb2RlIHJlbWFpbmluZ0NhcGFjaXR5fQorICAgICAqIGJlY2F1c2UgaXQgbWF5IGJlIHRoZSBjYXNlIHRoYXQgYW5vdGhlciB0aHJlYWQgaXMgYWJvdXQgdG8KKyAgICAgKiBpbnNlcnQgb3IgcmVtb3ZlIGFuIGVsZW1lbnQuCisgICAgICovCisgICAgcHVibGljIGludCByZW1haW5pbmdDYXBhY2l0eSgpIHsKKyAgICAgICAgcmV0dXJuIGNhcGFjaXR5IC0gY291bnQuZ2V0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgYXQgdGhlIHRhaWwgb2YgdGhpcyBxdWV1ZSwgd2FpdGluZyBpZgorICAgICAqIG5lY2Vzc2FyeSBmb3Igc3BhY2UgdG8gYmVjb21lIGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1dChFIGUpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChlID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAvLyBOb3RlOiBjb252ZW50aW9uIGluIGFsbCBwdXQvdGFrZS9ldGMgaXMgdG8gcHJlc2V0IGxvY2FsIHZhcgorICAgICAgICAvLyBob2xkaW5nIGNvdW50IG5lZ2F0aXZlIHRvIGluZGljYXRlIGZhaWx1cmUgdW5sZXNzIHNldC4KKyAgICAgICAgaW50IGMgPSAtMTsKKyAgICAgICAgTm9kZTxFPiBub2RlID0gbmV3IE5vZGUoZSk7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgcHV0TG9jayA9IHRoaXMucHV0TG9jazsKKyAgICAgICAgZmluYWwgQXRvbWljSW50ZWdlciBjb3VudCA9IHRoaXMuY291bnQ7CisgICAgICAgIHB1dExvY2subG9ja0ludGVycnVwdGlibHkoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBOb3RlIHRoYXQgY291bnQgaXMgdXNlZCBpbiB3YWl0IGd1YXJkIGV2ZW4gdGhvdWdoIGl0IGlzCisgICAgICAgICAgICAgKiBub3QgcHJvdGVjdGVkIGJ5IGxvY2suIFRoaXMgd29ya3MgYmVjYXVzZSBjb3VudCBjYW4KKyAgICAgICAgICAgICAqIG9ubHkgZGVjcmVhc2UgYXQgdGhpcyBwb2ludCAoYWxsIG90aGVyIHB1dHMgYXJlIHNodXQKKyAgICAgICAgICAgICAqIG91dCBieSBsb2NrKSwgYW5kIHdlIChvciBzb21lIG90aGVyIHdhaXRpbmcgcHV0KSBhcmUKKyAgICAgICAgICAgICAqIHNpZ25hbGxlZCBpZiBpdCBldmVyIGNoYW5nZXMgZnJvbSBjYXBhY2l0eS4gU2ltaWxhcmx5CisgICAgICAgICAgICAgKiBmb3IgYWxsIG90aGVyIHVzZXMgb2YgY291bnQgaW4gb3RoZXIgd2FpdCBndWFyZHMuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHdoaWxlIChjb3VudC5nZXQoKSA9PSBjYXBhY2l0eSkgeworICAgICAgICAgICAgICAgIG5vdEZ1bGwuYXdhaXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVucXVldWUobm9kZSk7CisgICAgICAgICAgICBjID0gY291bnQuZ2V0QW5kSW5jcmVtZW50KCk7CisgICAgICAgICAgICBpZiAoYyArIDEgPCBjYXBhY2l0eSkKKyAgICAgICAgICAgICAgICBub3RGdWxsLnNpZ25hbCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgcHV0TG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYyA9PSAwKQorICAgICAgICAgICAgc2lnbmFsTm90RW1wdHkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBhdCB0aGUgdGFpbCBvZiB0aGlzIHF1ZXVlLCB3YWl0aW5nIGlmCisgICAgICogbmVjZXNzYXJ5IHVwIHRvIHRoZSBzcGVjaWZpZWQgd2FpdCB0aW1lIGZvciBzcGFjZSB0byBiZWNvbWUgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgc3VjY2Vzc2Z1bCwgb3Ige0Bjb2RlIGZhbHNlfSBpZgorICAgICAqICAgICAgICAgdGhlIHNwZWNpZmllZCB3YWl0aW5nIHRpbWUgZWxhcHNlcyBiZWZvcmUgc3BhY2UgaXMgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG9mZmVyKEUgZSwgbG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KQorICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworCisgICAgICAgIGlmIChlID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBsb25nIG5hbm9zID0gdW5pdC50b05hbm9zKHRpbWVvdXQpOworICAgICAgICBpbnQgYyA9IC0xOworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIHB1dExvY2sgPSB0aGlzLnB1dExvY2s7CisgICAgICAgIGZpbmFsIEF0b21pY0ludGVnZXIgY291bnQgPSB0aGlzLmNvdW50OworICAgICAgICBwdXRMb2NrLmxvY2tJbnRlcnJ1cHRpYmx5KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3aGlsZSAoY291bnQuZ2V0KCkgPT0gY2FwYWNpdHkpIHsKKyAgICAgICAgICAgICAgICBpZiAobmFub3MgPD0gMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIG5hbm9zID0gbm90RnVsbC5hd2FpdE5hbm9zKG5hbm9zKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVucXVldWUobmV3IE5vZGU8RT4oZSkpOworICAgICAgICAgICAgYyA9IGNvdW50LmdldEFuZEluY3JlbWVudCgpOworICAgICAgICAgICAgaWYgKGMgKyAxIDwgY2FwYWNpdHkpCisgICAgICAgICAgICAgICAgbm90RnVsbC5zaWduYWwoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHB1dExvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGMgPT0gMCkKKyAgICAgICAgICAgIHNpZ25hbE5vdEVtcHR5KCk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IGF0IHRoZSB0YWlsIG9mIHRoaXMgcXVldWUgaWYgaXQgaXMKKyAgICAgKiBwb3NzaWJsZSB0byBkbyBzbyBpbW1lZGlhdGVseSB3aXRob3V0IGV4Y2VlZGluZyB0aGUgcXVldWUncyBjYXBhY2l0eSwKKyAgICAgKiByZXR1cm5pbmcge0Bjb2RlIHRydWV9IHVwb24gc3VjY2VzcyBhbmQge0Bjb2RlIGZhbHNlfSBpZiB0aGlzIHF1ZXVlCisgICAgICogaXMgZnVsbC4KKyAgICAgKiBXaGVuIHVzaW5nIGEgY2FwYWNpdHktcmVzdHJpY3RlZCBxdWV1ZSwgdGhpcyBtZXRob2QgaXMgZ2VuZXJhbGx5CisgICAgICogcHJlZmVyYWJsZSB0byBtZXRob2Qge0BsaW5rIEJsb2NraW5nUXVldWUjYWRkIGFkZH0sIHdoaWNoIGNhbiBmYWlsIHRvCisgICAgICogaW5zZXJ0IGFuIGVsZW1lbnQgb25seSBieSB0aHJvd2luZyBhbiBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gb2ZmZXIoRSBlKSB7CisgICAgICAgIGlmIChlID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBmaW5hbCBBdG9taWNJbnRlZ2VyIGNvdW50ID0gdGhpcy5jb3VudDsKKyAgICAgICAgaWYgKGNvdW50LmdldCgpID09IGNhcGFjaXR5KQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpbnQgYyA9IC0xOworICAgICAgICBOb2RlPEU+IG5vZGUgPSBuZXcgTm9kZShlKTsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBwdXRMb2NrID0gdGhpcy5wdXRMb2NrOworICAgICAgICBwdXRMb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChjb3VudC5nZXQoKSA8IGNhcGFjaXR5KSB7CisgICAgICAgICAgICAgICAgZW5xdWV1ZShub2RlKTsKKyAgICAgICAgICAgICAgICBjID0gY291bnQuZ2V0QW5kSW5jcmVtZW50KCk7CisgICAgICAgICAgICAgICAgaWYgKGMgKyAxIDwgY2FwYWNpdHkpCisgICAgICAgICAgICAgICAgICAgIG5vdEZ1bGwuc2lnbmFsKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBwdXRMb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgICAgIGlmIChjID09IDApCisgICAgICAgICAgICBzaWduYWxOb3RFbXB0eSgpOworICAgICAgICByZXR1cm4gYyA+PSAwOworICAgIH0KKworCisgICAgcHVibGljIEUgdGFrZSgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIEUgeDsKKyAgICAgICAgaW50IGMgPSAtMTsKKyAgICAgICAgZmluYWwgQXRvbWljSW50ZWdlciBjb3VudCA9IHRoaXMuY291bnQ7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgdGFrZUxvY2sgPSB0aGlzLnRha2VMb2NrOworICAgICAgICB0YWtlTG9jay5sb2NrSW50ZXJydXB0aWJseSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgd2hpbGUgKGNvdW50LmdldCgpID09IDApIHsKKyAgICAgICAgICAgICAgICBub3RFbXB0eS5hd2FpdCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgeCA9IGRlcXVldWUoKTsKKyAgICAgICAgICAgIGMgPSBjb3VudC5nZXRBbmREZWNyZW1lbnQoKTsKKyAgICAgICAgICAgIGlmIChjID4gMSkKKyAgICAgICAgICAgICAgICBub3RFbXB0eS5zaWduYWwoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRha2VMb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgICAgIGlmIChjID09IGNhcGFjaXR5KQorICAgICAgICAgICAgc2lnbmFsTm90RnVsbCgpOworICAgICAgICByZXR1cm4geDsKKyAgICB9CisKKyAgICBwdWJsaWMgRSBwb2xsKGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgRSB4ID0gbnVsbDsKKyAgICAgICAgaW50IGMgPSAtMTsKKyAgICAgICAgbG9uZyBuYW5vcyA9IHVuaXQudG9OYW5vcyh0aW1lb3V0KTsKKyAgICAgICAgZmluYWwgQXRvbWljSW50ZWdlciBjb3VudCA9IHRoaXMuY291bnQ7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgdGFrZUxvY2sgPSB0aGlzLnRha2VMb2NrOworICAgICAgICB0YWtlTG9jay5sb2NrSW50ZXJydXB0aWJseSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgd2hpbGUgKGNvdW50LmdldCgpID09IDApIHsKKyAgICAgICAgICAgICAgICBpZiAobmFub3MgPD0gMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgbmFub3MgPSBub3RFbXB0eS5hd2FpdE5hbm9zKG5hbm9zKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHggPSBkZXF1ZXVlKCk7CisgICAgICAgICAgICBjID0gY291bnQuZ2V0QW5kRGVjcmVtZW50KCk7CisgICAgICAgICAgICBpZiAoYyA+IDEpCisgICAgICAgICAgICAgICAgbm90RW1wdHkuc2lnbmFsKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0YWtlTG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYyA9PSBjYXBhY2l0eSkKKyAgICAgICAgICAgIHNpZ25hbE5vdEZ1bGwoKTsKKyAgICAgICAgcmV0dXJuIHg7CisgICAgfQorCisgICAgcHVibGljIEUgcG9sbCgpIHsKKyAgICAgICAgZmluYWwgQXRvbWljSW50ZWdlciBjb3VudCA9IHRoaXMuY291bnQ7CisgICAgICAgIGlmIChjb3VudC5nZXQoKSA9PSAwKQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIEUgeCA9IG51bGw7CisgICAgICAgIGludCBjID0gLTE7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgdGFrZUxvY2sgPSB0aGlzLnRha2VMb2NrOworICAgICAgICB0YWtlTG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoY291bnQuZ2V0KCkgPiAwKSB7CisgICAgICAgICAgICAgICAgeCA9IGRlcXVldWUoKTsKKyAgICAgICAgICAgICAgICBjID0gY291bnQuZ2V0QW5kRGVjcmVtZW50KCk7CisgICAgICAgICAgICAgICAgaWYgKGMgPiAxKQorICAgICAgICAgICAgICAgICAgICBub3RFbXB0eS5zaWduYWwoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRha2VMb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgICAgIGlmIChjID09IGNhcGFjaXR5KQorICAgICAgICAgICAgc2lnbmFsTm90RnVsbCgpOworICAgICAgICByZXR1cm4geDsKKyAgICB9CisKKyAgICBwdWJsaWMgRSBwZWVrKCkgeworICAgICAgICBpZiAoY291bnQuZ2V0KCkgPT0gMCkKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIHRha2VMb2NrID0gdGhpcy50YWtlTG9jazsKKyAgICAgICAgdGFrZUxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgTm9kZTxFPiBmaXJzdCA9IGhlYWQubmV4dDsKKyAgICAgICAgICAgIGlmIChmaXJzdCA9PSBudWxsKQorICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHJldHVybiBmaXJzdC5pdGVtOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdGFrZUxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVbmxpbmtzIGludGVyaW9yIE5vZGUgcCB3aXRoIHByZWRlY2Vzc29yIHRyYWlsLgorICAgICAqLworICAgIHZvaWQgdW5saW5rKE5vZGU8RT4gcCwgTm9kZTxFPiB0cmFpbCkgeworICAgICAgICAvLyBhc3NlcnQgaXNGdWxseUxvY2tlZCgpOworICAgICAgICAvLyBwLm5leHQgaXMgbm90IGNoYW5nZWQsIHRvIGFsbG93IGl0ZXJhdG9ycyB0aGF0IGFyZQorICAgICAgICAvLyB0cmF2ZXJzaW5nIHAgdG8gbWFpbnRhaW4gdGhlaXIgd2Vhay1jb25zaXN0ZW5jeSBndWFyYW50ZWUuCisgICAgICAgIHAuaXRlbSA9IG51bGw7CisgICAgICAgIHRyYWlsLm5leHQgPSBwLm5leHQ7CisgICAgICAgIGlmIChsYXN0ID09IHApCisgICAgICAgICAgICBsYXN0ID0gdHJhaWw7CisgICAgICAgIGlmIChjb3VudC5nZXRBbmREZWNyZW1lbnQoKSA9PSBjYXBhY2l0eSkKKyAgICAgICAgICAgIG5vdEZ1bGwuc2lnbmFsKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhIHNpbmdsZSBpbnN0YW5jZSBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgZnJvbSB0aGlzIHF1ZXVlLAorICAgICAqIGlmIGl0IGlzIHByZXNlbnQuICBNb3JlIGZvcm1hbGx5LCByZW1vdmVzIGFuIGVsZW1lbnQge0Bjb2RlIGV9IHN1Y2gKKyAgICAgKiB0aGF0IHtAY29kZSBvLmVxdWFscyhlKX0sIGlmIHRoaXMgcXVldWUgY29udGFpbnMgb25lIG9yIG1vcmUgc3VjaAorICAgICAqIGVsZW1lbnRzLgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoaXMgcXVldWUgY29udGFpbmVkIHRoZSBzcGVjaWZpZWQgZWxlbWVudAorICAgICAqIChvciBlcXVpdmFsZW50bHksIGlmIHRoaXMgcXVldWUgY2hhbmdlZCBhcyBhIHJlc3VsdCBvZiB0aGUgY2FsbCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBlbGVtZW50IHRvIGJlIHJlbW92ZWQgZnJvbSB0aGlzIHF1ZXVlLCBpZiBwcmVzZW50CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBxdWV1ZSBjaGFuZ2VkIGFzIGEgcmVzdWx0IG9mIHRoZSBjYWxsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvID09IG51bGwpIHJldHVybiBmYWxzZTsKKyAgICAgICAgZnVsbHlMb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKE5vZGU8RT4gdHJhaWwgPSBoZWFkLCBwID0gdHJhaWwubmV4dDsKKyAgICAgICAgICAgICAgICAgcCAhPSBudWxsOworICAgICAgICAgICAgICAgICB0cmFpbCA9IHAsIHAgPSBwLm5leHQpIHsKKyAgICAgICAgICAgICAgICBpZiAoby5lcXVhbHMocC5pdGVtKSkgeworICAgICAgICAgICAgICAgICAgICB1bmxpbmsocCwgdHJhaWwpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBmdWxseVVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBxdWV1ZSBjb250YWlucyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuCisgICAgICogTW9yZSBmb3JtYWxseSwgcmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgYW5kIG9ubHkgaWYgdGhpcyBxdWV1ZSBjb250YWlucworICAgICAqIGF0IGxlYXN0IG9uZSBlbGVtZW50IHtAY29kZSBlfSBzdWNoIHRoYXQge0Bjb2RlIG8uZXF1YWxzKGUpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvIG9iamVjdCB0byBiZSBjaGVja2VkIGZvciBjb250YWlubWVudCBpbiB0aGlzIHF1ZXVlCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBxdWV1ZSBjb250YWlucyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3QgbykgeworICAgICAgICBpZiAobyA9PSBudWxsKSByZXR1cm4gZmFsc2U7CisgICAgICAgIGZ1bGx5TG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yIChOb2RlPEU+IHAgPSBoZWFkLm5leHQ7IHAgIT0gbnVsbDsgcCA9IHAubmV4dCkKKyAgICAgICAgICAgICAgICBpZiAoby5lcXVhbHMocC5pdGVtKSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBmdWxseVVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIGFsbCBvZiB0aGUgZWxlbWVudHMgaW4gdGhpcyBxdWV1ZSwgaW4KKyAgICAgKiBwcm9wZXIgc2VxdWVuY2UuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQgYXJyYXkgd2lsbCBiZSAic2FmZSIgaW4gdGhhdCBubyByZWZlcmVuY2VzIHRvIGl0IGFyZQorICAgICAqIG1haW50YWluZWQgYnkgdGhpcyBxdWV1ZS4gIChJbiBvdGhlciB3b3JkcywgdGhpcyBtZXRob2QgbXVzdCBhbGxvY2F0ZQorICAgICAqIGEgbmV3IGFycmF5KS4gIFRoZSBjYWxsZXIgaXMgdGh1cyBmcmVlIHRvIG1vZGlmeSB0aGUgcmV0dXJuZWQgYXJyYXkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBhY3RzIGFzIGJyaWRnZSBiZXR3ZWVuIGFycmF5LWJhc2VkIGFuZCBjb2xsZWN0aW9uLWJhc2VkCisgICAgICogQVBJcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoaXMgcXVldWUKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKKyAgICAgICAgZnVsbHlMb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgc2l6ZSA9IGNvdW50LmdldCgpOworICAgICAgICAgICAgT2JqZWN0W10gYSA9IG5ldyBPYmplY3Rbc2l6ZV07CisgICAgICAgICAgICBpbnQgayA9IDA7CisgICAgICAgICAgICBmb3IgKE5vZGU8RT4gcCA9IGhlYWQubmV4dDsgcCAhPSBudWxsOyBwID0gcC5uZXh0KQorICAgICAgICAgICAgICAgIGFbaysrXSA9IHAuaXRlbTsKKyAgICAgICAgICAgIHJldHVybiBhOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZnVsbHlVbmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoaXMgcXVldWUsIGluCisgICAgICogcHJvcGVyIHNlcXVlbmNlOyB0aGUgcnVudGltZSB0eXBlIG9mIHRoZSByZXR1cm5lZCBhcnJheSBpcyB0aGF0IG9mCisgICAgICogdGhlIHNwZWNpZmllZCBhcnJheS4gIElmIHRoZSBxdWV1ZSBmaXRzIGluIHRoZSBzcGVjaWZpZWQgYXJyYXksIGl0CisgICAgICogaXMgcmV0dXJuZWQgdGhlcmVpbi4gIE90aGVyd2lzZSwgYSBuZXcgYXJyYXkgaXMgYWxsb2NhdGVkIHdpdGggdGhlCisgICAgICogcnVudGltZSB0eXBlIG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkgYW5kIHRoZSBzaXplIG9mIHRoaXMgcXVldWUuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGlzIHF1ZXVlIGZpdHMgaW4gdGhlIHNwZWNpZmllZCBhcnJheSB3aXRoIHJvb20gdG8gc3BhcmUKKyAgICAgKiAoaS5lLiwgdGhlIGFycmF5IGhhcyBtb3JlIGVsZW1lbnRzIHRoYW4gdGhpcyBxdWV1ZSksIHRoZSBlbGVtZW50IGluCisgICAgICogdGhlIGFycmF5IGltbWVkaWF0ZWx5IGZvbGxvd2luZyB0aGUgZW5kIG9mIHRoZSBxdWV1ZSBpcyBzZXQgdG8KKyAgICAgKiB7QGNvZGUgbnVsbH0uCisgICAgICoKKyAgICAgKiA8cD5MaWtlIHRoZSB7QGxpbmsgI3RvQXJyYXkoKX0gbWV0aG9kLCB0aGlzIG1ldGhvZCBhY3RzIGFzIGJyaWRnZSBiZXR3ZWVuCisgICAgICogYXJyYXktYmFzZWQgYW5kIGNvbGxlY3Rpb24tYmFzZWQgQVBJcy4gIEZ1cnRoZXIsIHRoaXMgbWV0aG9kIGFsbG93cworICAgICAqIHByZWNpc2UgY29udHJvbCBvdmVyIHRoZSBydW50aW1lIHR5cGUgb2YgdGhlIG91dHB1dCBhcnJheSwgYW5kIG1heSwKKyAgICAgKiB1bmRlciBjZXJ0YWluIGNpcmN1bXN0YW5jZXMsIGJlIHVzZWQgdG8gc2F2ZSBhbGxvY2F0aW9uIGNvc3RzLgorICAgICAqCisgICAgICogPHA+U3VwcG9zZSB7QGNvZGUgeH0gaXMgYSBxdWV1ZSBrbm93biB0byBjb250YWluIG9ubHkgc3RyaW5ncy4KKyAgICAgKiBUaGUgZm9sbG93aW5nIGNvZGUgY2FuIGJlIHVzZWQgdG8gZHVtcCB0aGUgcXVldWUgaW50byBhIG5ld2x5CisgICAgICogYWxsb2NhdGVkIGFycmF5IG9mIHtAY29kZSBTdHJpbmd9OgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiAgICAgU3RyaW5nW10geSA9IHgudG9BcnJheShuZXcgU3RyaW5nWzBdKTs8L3ByZT4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCB7QGNvZGUgdG9BcnJheShuZXcgT2JqZWN0WzBdKX0gaXMgaWRlbnRpY2FsIGluIGZ1bmN0aW9uIHRvCisgICAgICoge0Bjb2RlIHRvQXJyYXkoKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkgaW50byB3aGljaCB0aGUgZWxlbWVudHMgb2YgdGhlIHF1ZXVlIGFyZSB0bworICAgICAqICAgICAgICAgIGJlIHN0b3JlZCwgaWYgaXQgaXMgYmlnIGVub3VnaDsgb3RoZXJ3aXNlLCBhIG5ldyBhcnJheSBvZiB0aGUKKyAgICAgKiAgICAgICAgICBzYW1lIHJ1bnRpbWUgdHlwZSBpcyBhbGxvY2F0ZWQgZm9yIHRoaXMgcHVycG9zZQorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoaXMgcXVldWUKKyAgICAgKiBAdGhyb3dzIEFycmF5U3RvcmVFeGNlcHRpb24gaWYgdGhlIHJ1bnRpbWUgdHlwZSBvZiB0aGUgc3BlY2lmaWVkIGFycmF5CisgICAgICogICAgICAgICBpcyBub3QgYSBzdXBlcnR5cGUgb2YgdGhlIHJ1bnRpbWUgdHlwZSBvZiBldmVyeSBlbGVtZW50IGluCisgICAgICogICAgICAgICB0aGlzIHF1ZXVlCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGFycmF5IGlzIG51bGwKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgPFQ+IFRbXSB0b0FycmF5KFRbXSBhKSB7CisgICAgICAgIGZ1bGx5TG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IHNpemUgPSBjb3VudC5nZXQoKTsKKyAgICAgICAgICAgIGlmIChhLmxlbmd0aCA8IHNpemUpCisgICAgICAgICAgICAgICAgYSA9IChUW10pamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkubmV3SW5zdGFuY2UKKyAgICAgICAgICAgICAgICAgICAgKGEuZ2V0Q2xhc3MoKS5nZXRDb21wb25lbnRUeXBlKCksIHNpemUpOworCisgICAgICAgICAgICBpbnQgayA9IDA7CisgICAgICAgICAgICBmb3IgKE5vZGU8RT4gcCA9IGhlYWQubmV4dDsgcCAhPSBudWxsOyBwID0gcC5uZXh0KQorICAgICAgICAgICAgICAgIGFbaysrXSA9IChUKXAuaXRlbTsKKyAgICAgICAgICAgIGlmIChhLmxlbmd0aCA+IGspCisgICAgICAgICAgICAgICAgYVtrXSA9IG51bGw7CisgICAgICAgICAgICByZXR1cm4gYTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGZ1bGx5VW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBmdWxseUxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5vZGU8RT4gcCA9IGhlYWQubmV4dDsKKyAgICAgICAgICAgIGlmIChwID09IG51bGwpCisgICAgICAgICAgICAgICAgcmV0dXJuICJbXSI7CisKKyAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICAgICAgc2IuYXBwZW5kKCdbJyk7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgRSBlID0gcC5pdGVtOworICAgICAgICAgICAgICAgIHNiLmFwcGVuZChlID09IHRoaXMgPyAiKHRoaXMgQ29sbGVjdGlvbikiIDogZSk7CisgICAgICAgICAgICAgICAgcCA9IHAubmV4dDsKKyAgICAgICAgICAgICAgICBpZiAocCA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2IuYXBwZW5kKCddJykudG9TdHJpbmcoKTsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoJywnKS5hcHBlbmQoJyAnKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGZ1bGx5VW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHJlbW92ZXMgYWxsIG9mIHRoZSBlbGVtZW50cyBmcm9tIHRoaXMgcXVldWUuCisgICAgICogVGhlIHF1ZXVlIHdpbGwgYmUgZW1wdHkgYWZ0ZXIgdGhpcyBjYWxsIHJldHVybnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgIGZ1bGx5TG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yIChOb2RlPEU+IHAsIGggPSBoZWFkOyAocCA9IGgubmV4dCkgIT0gbnVsbDsgaCA9IHApIHsKKyAgICAgICAgICAgICAgICBoLm5leHQgPSBoOworICAgICAgICAgICAgICAgIHAuaXRlbSA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBoZWFkID0gbGFzdDsKKyAgICAgICAgICAgIC8vIGFzc2VydCBoZWFkLml0ZW0gPT0gbnVsbCAmJiBoZWFkLm5leHQgPT0gbnVsbDsKKyAgICAgICAgICAgIGlmIChjb3VudC5nZXRBbmRTZXQoMCkgPT0gY2FwYWNpdHkpCisgICAgICAgICAgICAgICAgbm90RnVsbC5zaWduYWwoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGZ1bGx5VW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiAgICAgICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICAgICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGRyYWluVG8oQ29sbGVjdGlvbjw/IHN1cGVyIEU+IGMpIHsKKyAgICAgICAgcmV0dXJuIGRyYWluVG8oYywgSW50ZWdlci5NQVhfVkFMVUUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uICAgICAgICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gICAgICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZHJhaW5UbyhDb2xsZWN0aW9uPD8gc3VwZXIgRT4gYywgaW50IG1heEVsZW1lbnRzKSB7CisgICAgICAgIGlmIChjID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgaWYgKGMgPT0gdGhpcykKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgYm9vbGVhbiBzaWduYWxOb3RGdWxsID0gZmFsc2U7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgdGFrZUxvY2sgPSB0aGlzLnRha2VMb2NrOworICAgICAgICB0YWtlTG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgbiA9IE1hdGgubWluKG1heEVsZW1lbnRzLCBjb3VudC5nZXQoKSk7CisgICAgICAgICAgICAvLyBjb3VudC5nZXQgcHJvdmlkZXMgdmlzaWJpbGl0eSB0byBmaXJzdCBuIE5vZGVzCisgICAgICAgICAgICBOb2RlPEU+IGggPSBoZWFkOworICAgICAgICAgICAgaW50IGkgPSAwOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB3aGlsZSAoaSA8IG4pIHsKKyAgICAgICAgICAgICAgICAgICAgTm9kZTxFPiBwID0gaC5uZXh0OworICAgICAgICAgICAgICAgICAgICBjLmFkZChwLml0ZW0pOworICAgICAgICAgICAgICAgICAgICBwLml0ZW0gPSBudWxsOworICAgICAgICAgICAgICAgICAgICBoLm5leHQgPSBoOworICAgICAgICAgICAgICAgICAgICBoID0gcDsKKyAgICAgICAgICAgICAgICAgICAgKytpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gbjsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgLy8gUmVzdG9yZSBpbnZhcmlhbnRzIGV2ZW4gaWYgYy5hZGQoKSB0aHJldworICAgICAgICAgICAgICAgIGlmIChpID4gMCkgeworICAgICAgICAgICAgICAgICAgICAvLyBhc3NlcnQgaC5pdGVtID09IG51bGw7CisgICAgICAgICAgICAgICAgICAgIGhlYWQgPSBoOworICAgICAgICAgICAgICAgICAgICBzaWduYWxOb3RGdWxsID0gKGNvdW50LmdldEFuZEFkZCgtaSkgPT0gY2FwYWNpdHkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRha2VMb2NrLnVubG9jaygpOworICAgICAgICAgICAgaWYgKHNpZ25hbE5vdEZ1bGwpCisgICAgICAgICAgICAgICAgc2lnbmFsTm90RnVsbCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cyBpbiB0aGlzIHF1ZXVlIGluIHByb3BlciBzZXF1ZW5jZS4KKyAgICAgKiBUaGUgZWxlbWVudHMgd2lsbCBiZSByZXR1cm5lZCBpbiBvcmRlciBmcm9tIGZpcnN0IChoZWFkKSB0byBsYXN0ICh0YWlsKS4KKyAgICAgKgorICAgICAqIDxwPlRoZSByZXR1cm5lZCBpdGVyYXRvciBpcyBhICJ3ZWFrbHkgY29uc2lzdGVudCIgaXRlcmF0b3IgdGhhdAorICAgICAqIHdpbGwgbmV2ZXIgdGhyb3cge0BsaW5rIGphdmEudXRpbC5Db25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uCisgICAgICogQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbn0sIGFuZCBndWFyYW50ZWVzIHRvIHRyYXZlcnNlCisgICAgICogZWxlbWVudHMgYXMgdGhleSBleGlzdGVkIHVwb24gY29uc3RydWN0aW9uIG9mIHRoZSBpdGVyYXRvciwgYW5kCisgICAgICogbWF5IChidXQgaXMgbm90IGd1YXJhbnRlZWQgdG8pIHJlZmxlY3QgYW55IG1vZGlmaWNhdGlvbnMKKyAgICAgKiBzdWJzZXF1ZW50IHRvIGNvbnN0cnVjdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMgaW4gdGhpcyBxdWV1ZSBpbiBwcm9wZXIgc2VxdWVuY2UKKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3I8RT4gaXRlcmF0b3IoKSB7CisgICAgICByZXR1cm4gbmV3IEl0cigpOworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgSXRyIGltcGxlbWVudHMgSXRlcmF0b3I8RT4geworICAgICAgICAvKgorICAgICAgICAgKiBCYXNpYyB3ZWFrbHktY29uc2lzdGVudCBpdGVyYXRvci4gIEF0IGFsbCB0aW1lcyBob2xkIHRoZSBuZXh0CisgICAgICAgICAqIGl0ZW0gdG8gaGFuZCBvdXQgc28gdGhhdCBpZiBoYXNOZXh0KCkgcmVwb3J0cyB0cnVlLCB3ZSB3aWxsCisgICAgICAgICAqIHN0aWxsIGhhdmUgaXQgdG8gcmV0dXJuIGV2ZW4gaWYgbG9zdCByYWNlIHdpdGggYSB0YWtlIGV0Yy4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgTm9kZTxFPiBjdXJyZW50OworICAgICAgICBwcml2YXRlIE5vZGU8RT4gbGFzdFJldDsKKyAgICAgICAgcHJpdmF0ZSBFIGN1cnJlbnRFbGVtZW50OworCisgICAgICAgIEl0cigpIHsKKyAgICAgICAgICAgIGZ1bGx5TG9jaygpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjdXJyZW50ID0gaGVhZC5uZXh0OworICAgICAgICAgICAgICAgIGlmIChjdXJyZW50ICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRFbGVtZW50ID0gY3VycmVudC5pdGVtOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBmdWxseVVubG9jaygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiBjdXJyZW50ICE9IG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgbmV4dCBsaXZlIHN1Y2Nlc3NvciBvZiBwLCBvciBudWxsIGlmIG5vIHN1Y2guCisgICAgICAgICAqCisgICAgICAgICAqIFVubGlrZSBvdGhlciB0cmF2ZXJzYWwgbWV0aG9kcywgaXRlcmF0b3JzIG5lZWQgdG8gaGFuZGxlIGJvdGg6CisgICAgICAgICAqIC0gZGVxdWV1ZWQgbm9kZXMgKHAubmV4dCA9PSBwKQorICAgICAgICAgKiAtIChwb3NzaWJseSBtdWx0aXBsZSkgaW50ZXJpb3IgcmVtb3ZlZCBub2RlcyAocC5pdGVtID09IG51bGwpCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIE5vZGU8RT4gbmV4dE5vZGUoTm9kZTxFPiBwKSB7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgTm9kZTxFPiBzID0gcC5uZXh0OworICAgICAgICAgICAgICAgIGlmIChzID09IHApCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBoZWFkLm5leHQ7CisgICAgICAgICAgICAgICAgaWYgKHMgPT0gbnVsbCB8fCBzLml0ZW0gIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHM7CisgICAgICAgICAgICAgICAgcCA9IHM7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgRSBuZXh0KCkgeworICAgICAgICAgICAgZnVsbHlMb2NrKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmIChjdXJyZW50ID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgRSB4ID0gY3VycmVudEVsZW1lbnQ7CisgICAgICAgICAgICAgICAgbGFzdFJldCA9IGN1cnJlbnQ7CisgICAgICAgICAgICAgICAgY3VycmVudCA9IG5leHROb2RlKGN1cnJlbnQpOworICAgICAgICAgICAgICAgIGN1cnJlbnRFbGVtZW50ID0gKGN1cnJlbnQgPT0gbnVsbCkgPyBudWxsIDogY3VycmVudC5pdGVtOworICAgICAgICAgICAgICAgIHJldHVybiB4OworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBmdWxseVVubG9jaygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICAgICAgaWYgKGxhc3RSZXQgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBmdWxseUxvY2soKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTm9kZTxFPiBub2RlID0gbGFzdFJldDsKKyAgICAgICAgICAgICAgICBsYXN0UmV0ID0gbnVsbDsKKyAgICAgICAgICAgICAgICBmb3IgKE5vZGU8RT4gdHJhaWwgPSBoZWFkLCBwID0gdHJhaWwubmV4dDsKKyAgICAgICAgICAgICAgICAgICAgIHAgIT0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgIHRyYWlsID0gcCwgcCA9IHAubmV4dCkgeworICAgICAgICAgICAgICAgICAgICBpZiAocCA9PSBub2RlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB1bmxpbmsocCwgdHJhaWwpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGZ1bGx5VW5sb2NrKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTYXZlIHRoZSBzdGF0ZSB0byBhIHN0cmVhbSAodGhhdCBpcywgc2VyaWFsaXplIGl0KS4KKyAgICAgKgorICAgICAqIEBzZXJpYWxEYXRhIFRoZSBjYXBhY2l0eSBpcyBlbWl0dGVkIChpbnQpLCBmb2xsb3dlZCBieSBhbGwgb2YKKyAgICAgKiBpdHMgZWxlbWVudHMgKGVhY2ggYW4ge0Bjb2RlIE9iamVjdH0pIGluIHRoZSBwcm9wZXIgb3JkZXIsCisgICAgICogZm9sbG93ZWQgYnkgYSBudWxsCisgICAgICogQHBhcmFtIHMgdGhlIHN0cmVhbQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbSBzKQorICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgZnVsbHlMb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBXcml0ZSBvdXQgYW55IGhpZGRlbiBzdHVmZiwgcGx1cyBjYXBhY2l0eQorICAgICAgICAgICAgcy5kZWZhdWx0V3JpdGVPYmplY3QoKTsKKworICAgICAgICAgICAgLy8gV3JpdGUgb3V0IGFsbCBlbGVtZW50cyBpbiB0aGUgcHJvcGVyIG9yZGVyLgorICAgICAgICAgICAgZm9yIChOb2RlPEU+IHAgPSBoZWFkLm5leHQ7IHAgIT0gbnVsbDsgcCA9IHAubmV4dCkKKyAgICAgICAgICAgICAgICBzLndyaXRlT2JqZWN0KHAuaXRlbSk7CisKKyAgICAgICAgICAgIC8vIFVzZSB0cmFpbGluZyBudWxsIGFzIHNlbnRpbmVsCisgICAgICAgICAgICBzLndyaXRlT2JqZWN0KG51bGwpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZnVsbHlVbmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlY29uc3RpdHV0ZSB0aGlzIHF1ZXVlIGluc3RhbmNlIGZyb20gYSBzdHJlYW0gKHRoYXQgaXMsCisgICAgICogZGVzZXJpYWxpemUgaXQpLgorICAgICAqCisgICAgICogQHBhcmFtIHMgdGhlIHN0cmVhbQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0gcykKKyAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICAvLyBSZWFkIGluIGNhcGFjaXR5LCBhbmQgYW55IGhpZGRlbiBzdHVmZgorICAgICAgICBzLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisKKyAgICAgICAgY291bnQuc2V0KDApOworICAgICAgICBsYXN0ID0gaGVhZCA9IG5ldyBOb2RlPEU+KG51bGwpOworCisgICAgICAgIC8vIFJlYWQgaW4gYWxsIGVsZW1lbnRzIGFuZCBwbGFjZSBpbiBxdWV1ZQorICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgICAgIEUgaXRlbSA9IChFKXMucmVhZE9iamVjdCgpOworICAgICAgICAgICAgaWYgKGl0ZW0gPT0gbnVsbCkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGFkZChpdGVtKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Qcmlvcml0eUJsb2NraW5nUXVldWUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9Qcmlvcml0eUJsb2NraW5nUXVldWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZmZiZTY0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L1ByaW9yaXR5QmxvY2tpbmdRdWV1ZS5qYXZhCkBAIC0wLDAgKzEsOTUzIEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy4qOworaW1wb3J0IGphdmEudXRpbC4qOworCisvLyBCRUdJTiBhbmRyb2lkLW5vdGUKKy8vIHJlbW92ZWQgbGluayB0byBjb2xsZWN0aW9ucyBmcmFtZXdvcmsgZG9jcworLy8gRU5EIGFuZHJvaWQtbm90ZQorCisvKioKKyAqIEFuIHVuYm91bmRlZCB7QGxpbmtwbGFpbiBCbG9ja2luZ1F1ZXVlIGJsb2NraW5nIHF1ZXVlfSB0aGF0IHVzZXMKKyAqIHRoZSBzYW1lIG9yZGVyaW5nIHJ1bGVzIGFzIGNsYXNzIHtAbGluayBQcmlvcml0eVF1ZXVlfSBhbmQgc3VwcGxpZXMKKyAqIGJsb2NraW5nIHJldHJpZXZhbCBvcGVyYXRpb25zLiAgV2hpbGUgdGhpcyBxdWV1ZSBpcyBsb2dpY2FsbHkKKyAqIHVuYm91bmRlZCwgYXR0ZW1wdGVkIGFkZGl0aW9ucyBtYXkgZmFpbCBkdWUgdG8gcmVzb3VyY2UgZXhoYXVzdGlvbgorICogKGNhdXNpbmcge0Bjb2RlIE91dE9mTWVtb3J5RXJyb3J9KS4gVGhpcyBjbGFzcyBkb2VzIG5vdCBwZXJtaXQKKyAqIHtAY29kZSBudWxsfSBlbGVtZW50cy4gIEEgcHJpb3JpdHkgcXVldWUgcmVseWluZyBvbiB7QGxpbmtwbGFpbgorICogQ29tcGFyYWJsZSBuYXR1cmFsIG9yZGVyaW5nfSBhbHNvIGRvZXMgbm90IHBlcm1pdCBpbnNlcnRpb24gb2YKKyAqIG5vbi1jb21wYXJhYmxlIG9iamVjdHMgKGRvaW5nIHNvIHJlc3VsdHMgaW4KKyAqIHtAY29kZSBDbGFzc0Nhc3RFeGNlcHRpb259KS4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGFuZCBpdHMgaXRlcmF0b3IgaW1wbGVtZW50IGFsbCBvZiB0aGUKKyAqIDxlbT5vcHRpb25hbDwvZW0+IG1ldGhvZHMgb2YgdGhlIHtAbGluayBDb2xsZWN0aW9ufSBhbmQge0BsaW5rCisgKiBJdGVyYXRvcn0gaW50ZXJmYWNlcy4gIFRoZSBJdGVyYXRvciBwcm92aWRlZCBpbiBtZXRob2Qge0BsaW5rCisgKiAjaXRlcmF0b3IoKX0gaXMgPGVtPm5vdDwvZW0+IGd1YXJhbnRlZWQgdG8gdHJhdmVyc2UgdGhlIGVsZW1lbnRzIG9mCisgKiB0aGUgUHJpb3JpdHlCbG9ja2luZ1F1ZXVlIGluIGFueSBwYXJ0aWN1bGFyIG9yZGVyLiBJZiB5b3UgbmVlZAorICogb3JkZXJlZCB0cmF2ZXJzYWwsIGNvbnNpZGVyIHVzaW5nCisgKiB7QGNvZGUgQXJyYXlzLnNvcnQocHEudG9BcnJheSgpKX0uICBBbHNvLCBtZXRob2Qge0Bjb2RlIGRyYWluVG99CisgKiBjYW4gYmUgdXNlZCB0byA8ZW0+cmVtb3ZlPC9lbT4gc29tZSBvciBhbGwgZWxlbWVudHMgaW4gcHJpb3JpdHkKKyAqIG9yZGVyIGFuZCBwbGFjZSB0aGVtIGluIGFub3RoZXIgY29sbGVjdGlvbi4KKyAqCisgKiA8cD5PcGVyYXRpb25zIG9uIHRoaXMgY2xhc3MgbWFrZSBubyBndWFyYW50ZWVzIGFib3V0IHRoZSBvcmRlcmluZworICogb2YgZWxlbWVudHMgd2l0aCBlcXVhbCBwcmlvcml0eS4gSWYgeW91IG5lZWQgdG8gZW5mb3JjZSBhbgorICogb3JkZXJpbmcsIHlvdSBjYW4gZGVmaW5lIGN1c3RvbSBjbGFzc2VzIG9yIGNvbXBhcmF0b3JzIHRoYXQgdXNlIGEKKyAqIHNlY29uZGFyeSBrZXkgdG8gYnJlYWsgdGllcyBpbiBwcmltYXJ5IHByaW9yaXR5IHZhbHVlcy4gIEZvcgorICogZXhhbXBsZSwgaGVyZSBpcyBhIGNsYXNzIHRoYXQgYXBwbGllcyBmaXJzdC1pbi1maXJzdC1vdXQKKyAqIHRpZS1icmVha2luZyB0byBjb21wYXJhYmxlIGVsZW1lbnRzLiBUbyB1c2UgaXQsIHlvdSB3b3VsZCBpbnNlcnQgYQorICoge0Bjb2RlIG5ldyBGSUZPRW50cnkoYW5FbnRyeSl9IGluc3RlYWQgb2YgYSBwbGFpbiBlbnRyeSBvYmplY3QuCisgKgorICogIDxwcmU+IHtAY29kZQorICogY2xhc3MgRklGT0VudHJ5PEUgZXh0ZW5kcyBDb21wYXJhYmxlPD8gc3VwZXIgRT4+CisgKiAgICAgaW1wbGVtZW50cyBDb21wYXJhYmxlPEZJRk9FbnRyeTxFPj4geworICogICBzdGF0aWMgZmluYWwgQXRvbWljTG9uZyBzZXEgPSBuZXcgQXRvbWljTG9uZygwKTsKKyAqICAgZmluYWwgbG9uZyBzZXFOdW07CisgKiAgIGZpbmFsIEUgZW50cnk7CisgKiAgIHB1YmxpYyBGSUZPRW50cnkoRSBlbnRyeSkgeworICogICAgIHNlcU51bSA9IHNlcS5nZXRBbmRJbmNyZW1lbnQoKTsKKyAqICAgICB0aGlzLmVudHJ5ID0gZW50cnk7CisgKiAgIH0KKyAqICAgcHVibGljIEUgZ2V0RW50cnkoKSB7IHJldHVybiBlbnRyeTsgfQorICogICBwdWJsaWMgaW50IGNvbXBhcmVUbyhGSUZPRW50cnk8RT4gb3RoZXIpIHsKKyAqICAgICBpbnQgcmVzID0gZW50cnkuY29tcGFyZVRvKG90aGVyLmVudHJ5KTsKKyAqICAgICBpZiAocmVzID09IDAgJiYgb3RoZXIuZW50cnkgIT0gdGhpcy5lbnRyeSkKKyAqICAgICAgIHJlcyA9IChzZXFOdW0gPCBvdGhlci5zZXFOdW0gPyAtMSA6IDEpOworICogICAgIHJldHVybiByZXM7CisgKiAgIH0KKyAqIH19PC9wcmU+CisgKgorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICogQHBhcmFtIDxFPiB0aGUgdHlwZSBvZiBlbGVtZW50cyBoZWxkIGluIHRoaXMgY29sbGVjdGlvbgorICovCitwdWJsaWMgY2xhc3MgUHJpb3JpdHlCbG9ja2luZ1F1ZXVlPEU+IGV4dGVuZHMgQWJzdHJhY3RRdWV1ZTxFPgorICAgIGltcGxlbWVudHMgQmxvY2tpbmdRdWV1ZTxFPiwgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDU1OTU1MTA5MTkyNDU0MDgyNzZMOworCisgICAgLyoKKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gdXNlcyBhbiBhcnJheS1iYXNlZCBiaW5hcnkgaGVhcCwgd2l0aCBwdWJsaWMKKyAgICAgKiBvcGVyYXRpb25zIHByb3RlY3RlZCB3aXRoIGEgc2luZ2xlIGxvY2suIEhvd2V2ZXIsIGFsbG9jYXRpb24KKyAgICAgKiBkdXJpbmcgcmVzaXppbmcgdXNlcyBhIHNpbXBsZSBzcGlubG9jayAodXNlZCBvbmx5IHdoaWxlIG5vdAorICAgICAqIGhvbGRpbmcgbWFpbiBsb2NrKSBpbiBvcmRlciB0byBhbGxvdyB0YWtlcyB0byBvcGVyYXRlCisgICAgICogY29uY3VycmVudGx5IHdpdGggYWxsb2NhdGlvbi4gIFRoaXMgYXZvaWRzIHJlcGVhdGVkCisgICAgICogcG9zdHBvbmVtZW50IG9mIHdhaXRpbmcgY29uc3VtZXJzIGFuZCBjb25zZXF1ZW50IGVsZW1lbnQKKyAgICAgKiBidWlsZC11cC4gVGhlIG5lZWQgdG8gYmFjayBhd2F5IGZyb20gbG9jayBkdXJpbmcgYWxsb2NhdGlvbgorICAgICAqIG1ha2VzIGl0IGltcG9zc2libGUgdG8gc2ltcGx5IHdyYXAgZGVsZWdhdGVkCisgICAgICogamF2YS51dGlsLlByaW9yaXR5UXVldWUgb3BlcmF0aW9ucyB3aXRoaW4gYSBsb2NrLCBhcyB3YXMgZG9uZQorICAgICAqIGluIGEgcHJldmlvdXMgdmVyc2lvbiBvZiB0aGlzIGNsYXNzLiBUbyBtYWludGFpbgorICAgICAqIGludGVyb3BlcmFiaWxpdHksIGEgcGxhaW4gUHJpb3JpdHlRdWV1ZSBpcyBzdGlsbCB1c2VkIGR1cmluZworICAgICAqIHNlcmlhbGl6YXRpb24sIHdoaWNoIG1haW50YWlucyBjb21wYXRpYmlsaXR5IGF0IHRoZSBlc3BlbnNlIG9mCisgICAgICogdHJhbnNpZW50bHkgZG91Ymxpbmcgb3ZlcmhlYWQuCisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBEZWZhdWx0IGFycmF5IGNhcGFjaXR5LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0lOSVRJQUxfQ0FQQUNJVFkgPSAxMTsKKworICAgIC8qKgorICAgICAqIFRoZSBtYXhpbXVtIHNpemUgb2YgYXJyYXkgdG8gYWxsb2NhdGUuCisgICAgICogU29tZSBWTXMgcmVzZXJ2ZSBzb21lIGhlYWRlciB3b3JkcyBpbiBhbiBhcnJheS4KKyAgICAgKiBBdHRlbXB0cyB0byBhbGxvY2F0ZSBsYXJnZXIgYXJyYXlzIG1heSByZXN1bHQgaW4KKyAgICAgKiBPdXRPZk1lbW9yeUVycm9yOiBSZXF1ZXN0ZWQgYXJyYXkgc2l6ZSBleGNlZWRzIFZNIGxpbWl0CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9BUlJBWV9TSVpFID0gSW50ZWdlci5NQVhfVkFMVUUgLSA4OworCisgICAgLyoqCisgICAgICogUHJpb3JpdHkgcXVldWUgcmVwcmVzZW50ZWQgYXMgYSBiYWxhbmNlZCBiaW5hcnkgaGVhcDogdGhlIHR3bworICAgICAqIGNoaWxkcmVuIG9mIHF1ZXVlW25dIGFyZSBxdWV1ZVsyKm4rMV0gYW5kIHF1ZXVlWzIqKG4rMSldLiAgVGhlCisgICAgICogcHJpb3JpdHkgcXVldWUgaXMgb3JkZXJlZCBieSBjb21wYXJhdG9yLCBvciBieSB0aGUgZWxlbWVudHMnCisgICAgICogbmF0dXJhbCBvcmRlcmluZywgaWYgY29tcGFyYXRvciBpcyBudWxsOiBGb3IgZWFjaCBub2RlIG4gaW4gdGhlCisgICAgICogaGVhcCBhbmQgZWFjaCBkZXNjZW5kYW50IGQgb2YgbiwgbiA8PSBkLiAgVGhlIGVsZW1lbnQgd2l0aCB0aGUKKyAgICAgKiBsb3dlc3QgdmFsdWUgaXMgaW4gcXVldWVbMF0sIGFzc3VtaW5nIHRoZSBxdWV1ZSBpcyBub25lbXB0eS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHRyYW5zaWVudCBPYmplY3RbXSBxdWV1ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIHByaW9yaXR5IHF1ZXVlLgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IGludCBzaXplOworCisgICAgLyoqCisgICAgICogVGhlIGNvbXBhcmF0b3IsIG9yIG51bGwgaWYgcHJpb3JpdHkgcXVldWUgdXNlcyBlbGVtZW50cycKKyAgICAgKiBuYXR1cmFsIG9yZGVyaW5nLgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IENvbXBhcmF0b3I8PyBzdXBlciBFPiBjb21wYXJhdG9yOworCisgICAgLyoqCisgICAgICogTG9jayB1c2VkIGZvciBhbGwgcHVibGljIG9wZXJhdGlvbnMKKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFJlZW50cmFudExvY2sgbG9jazsKKworICAgIC8qKgorICAgICAqIENvbmRpdGlvbiBmb3IgYmxvY2tpbmcgd2hlbiBlbXB0eQorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgQ29uZGl0aW9uIG5vdEVtcHR5OworCisgICAgLyoqCisgICAgICogU3BpbmxvY2sgZm9yIGFsbG9jYXRpb24sIGFjcXVpcmVkIHZpYSBDQVMuCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgdm9sYXRpbGUgaW50IGFsbG9jYXRpb25TcGluTG9jazsKKworICAgIC8qKgorICAgICAqIEEgcGxhaW4gUHJpb3JpdHlRdWV1ZSB1c2VkIG9ubHkgZm9yIHNlcmlhbGl6YXRpb24sCisgICAgICogdG8gbWFpbnRhaW4gY29tcGF0aWJpbGl0eSB3aXRoIHByZXZpb3VzIHZlcnNpb25zCisgICAgICogb2YgdGhpcyBjbGFzcy4gTm9uLW51bGwgb25seSBkdXJpbmcgc2VyaWFsaXphdGlvbi9kZXNlcmlhbGl6YXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBQcmlvcml0eVF1ZXVlIHE7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIFByaW9yaXR5QmxvY2tpbmdRdWV1ZX0gd2l0aCB0aGUgZGVmYXVsdAorICAgICAqIGluaXRpYWwgY2FwYWNpdHkgKDExKSB0aGF0IG9yZGVycyBpdHMgZWxlbWVudHMgYWNjb3JkaW5nIHRvCisgICAgICogdGhlaXIge0BsaW5rcGxhaW4gQ29tcGFyYWJsZSBuYXR1cmFsIG9yZGVyaW5nfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpb3JpdHlCbG9ja2luZ1F1ZXVlKCkgeworICAgICAgICB0aGlzKERFRkFVTFRfSU5JVElBTF9DQVBBQ0lUWSwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHtAY29kZSBQcmlvcml0eUJsb2NraW5nUXVldWV9IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIGluaXRpYWwgY2FwYWNpdHkgdGhhdCBvcmRlcnMgaXRzIGVsZW1lbnRzIGFjY29yZGluZyB0byB0aGVpcgorICAgICAqIHtAbGlua3BsYWluIENvbXBhcmFibGUgbmF0dXJhbCBvcmRlcmluZ30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5pdGlhbENhcGFjaXR5IHRoZSBpbml0aWFsIGNhcGFjaXR5IGZvciB0aGlzIHByaW9yaXR5IHF1ZXVlCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGluaXRpYWxDYXBhY2l0eX0gaXMgbGVzcworICAgICAqICAgICAgICAgdGhhbiAxCisgICAgICovCisgICAgcHVibGljIFByaW9yaXR5QmxvY2tpbmdRdWV1ZShpbnQgaW5pdGlhbENhcGFjaXR5KSB7CisgICAgICAgIHRoaXMoaW5pdGlhbENhcGFjaXR5LCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEge0Bjb2RlIFByaW9yaXR5QmxvY2tpbmdRdWV1ZX0gd2l0aCB0aGUgc3BlY2lmaWVkIGluaXRpYWwKKyAgICAgKiBjYXBhY2l0eSB0aGF0IG9yZGVycyBpdHMgZWxlbWVudHMgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjb21wYXJhdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGluaXRpYWxDYXBhY2l0eSB0aGUgaW5pdGlhbCBjYXBhY2l0eSBmb3IgdGhpcyBwcmlvcml0eSBxdWV1ZQorICAgICAqIEBwYXJhbSAgY29tcGFyYXRvciB0aGUgY29tcGFyYXRvciB0aGF0IHdpbGwgYmUgdXNlZCB0byBvcmRlciB0aGlzCisgICAgICogICAgICAgICBwcmlvcml0eSBxdWV1ZS4gIElmIHtAY29kZSBudWxsfSwgdGhlIHtAbGlua3BsYWluIENvbXBhcmFibGUKKyAgICAgKiAgICAgICAgIG5hdHVyYWwgb3JkZXJpbmd9IG9mIHRoZSBlbGVtZW50cyB3aWxsIGJlIHVzZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGluaXRpYWxDYXBhY2l0eX0gaXMgbGVzcworICAgICAqICAgICAgICAgdGhhbiAxCisgICAgICovCisgICAgcHVibGljIFByaW9yaXR5QmxvY2tpbmdRdWV1ZShpbnQgaW5pdGlhbENhcGFjaXR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29tcGFyYXRvcjw/IHN1cGVyIEU+IGNvbXBhcmF0b3IpIHsKKyAgICAgICAgaWYgKGluaXRpYWxDYXBhY2l0eSA8IDEpCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIHRoaXMubG9jayA9IG5ldyBSZWVudHJhbnRMb2NrKCk7CisgICAgICAgIHRoaXMubm90RW1wdHkgPSBsb2NrLm5ld0NvbmRpdGlvbigpOworICAgICAgICB0aGlzLmNvbXBhcmF0b3IgPSBjb21wYXJhdG9yOworICAgICAgICB0aGlzLnF1ZXVlID0gbmV3IE9iamVjdFtpbml0aWFsQ2FwYWNpdHldOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgUHJpb3JpdHlCbG9ja2luZ1F1ZXVlfSBjb250YWluaW5nIHRoZSBlbGVtZW50cworICAgICAqIGluIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbi4gIElmIHRoZSBzcGVjaWZpZWQgY29sbGVjdGlvbiBpcyBhCisgICAgICoge0BsaW5rIFNvcnRlZFNldH0gb3IgYSB7QGxpbmsgUHJpb3JpdHlRdWV1ZX0sICB0aGlzCisgICAgICogcHJpb3JpdHkgcXVldWUgd2lsbCBiZSBvcmRlcmVkIGFjY29yZGluZyB0byB0aGUgc2FtZSBvcmRlcmluZy4KKyAgICAgKiBPdGhlcndpc2UsIHRoaXMgcHJpb3JpdHkgcXVldWUgd2lsbCBiZSBvcmRlcmVkIGFjY29yZGluZyB0byB0aGUKKyAgICAgKiB7QGxpbmtwbGFpbiBDb21wYXJhYmxlIG5hdHVyYWwgb3JkZXJpbmd9IG9mIGl0cyBlbGVtZW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgYyB0aGUgY29sbGVjdGlvbiB3aG9zZSBlbGVtZW50cyBhcmUgdG8gYmUgcGxhY2VkCisgICAgICogICAgICAgICBpbnRvIHRoaXMgcHJpb3JpdHkgcXVldWUKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiBlbGVtZW50cyBvZiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24KKyAgICAgKiAgICAgICAgIGNhbm5vdCBiZSBjb21wYXJlZCB0byBvbmUgYW5vdGhlciBhY2NvcmRpbmcgdG8gdGhlIHByaW9yaXR5CisgICAgICogICAgICAgICBxdWV1ZSdzIG9yZGVyaW5nCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGNvbGxlY3Rpb24gb3IgYW55CisgICAgICogICAgICAgICBvZiBpdHMgZWxlbWVudHMgYXJlIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpb3JpdHlCbG9ja2luZ1F1ZXVlKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGMpIHsKKyAgICAgICAgdGhpcy5sb2NrID0gbmV3IFJlZW50cmFudExvY2soKTsKKyAgICAgICAgdGhpcy5ub3RFbXB0eSA9IGxvY2submV3Q29uZGl0aW9uKCk7CisgICAgICAgIGJvb2xlYW4gaGVhcGlmeSA9IHRydWU7IC8vIHRydWUgaWYgbm90IGtub3duIHRvIGJlIGluIGhlYXAgb3JkZXIKKyAgICAgICAgYm9vbGVhbiBzY3JlZW4gPSB0cnVlOyAgLy8gdHJ1ZSBpZiBtdXN0IHNjcmVlbiBmb3IgbnVsbHMKKyAgICAgICAgaWYgKGMgaW5zdGFuY2VvZiBTb3J0ZWRTZXQ8Pz4pIHsKKyAgICAgICAgICAgIFNvcnRlZFNldDw/IGV4dGVuZHMgRT4gc3MgPSAoU29ydGVkU2V0PD8gZXh0ZW5kcyBFPikgYzsKKyAgICAgICAgICAgIHRoaXMuY29tcGFyYXRvciA9IChDb21wYXJhdG9yPD8gc3VwZXIgRT4pIHNzLmNvbXBhcmF0b3IoKTsKKyAgICAgICAgICAgIGhlYXBpZnkgPSBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChjIGluc3RhbmNlb2YgUHJpb3JpdHlCbG9ja2luZ1F1ZXVlPD8+KSB7CisgICAgICAgICAgICBQcmlvcml0eUJsb2NraW5nUXVldWU8PyBleHRlbmRzIEU+IHBxID0KKyAgICAgICAgICAgICAgICAoUHJpb3JpdHlCbG9ja2luZ1F1ZXVlPD8gZXh0ZW5kcyBFPikgYzsKKyAgICAgICAgICAgIHRoaXMuY29tcGFyYXRvciA9IChDb21wYXJhdG9yPD8gc3VwZXIgRT4pIHBxLmNvbXBhcmF0b3IoKTsKKyAgICAgICAgICAgIHNjcmVlbiA9IGZhbHNlOworICAgICAgICAgICAgaWYgKHBxLmdldENsYXNzKCkgPT0gUHJpb3JpdHlCbG9ja2luZ1F1ZXVlLmNsYXNzKSAvLyBleGFjdCBtYXRjaAorICAgICAgICAgICAgICAgIGhlYXBpZnkgPSBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBPYmplY3RbXSBhID0gYy50b0FycmF5KCk7CisgICAgICAgIGludCBuID0gYS5sZW5ndGg7CisgICAgICAgIC8vIElmIGMudG9BcnJheSBpbmNvcnJlY3RseSBkb2Vzbid0IHJldHVybiBPYmplY3RbXSwgY29weSBpdC4KKyAgICAgICAgaWYgKGEuZ2V0Q2xhc3MoKSAhPSBPYmplY3RbXS5jbGFzcykKKyAgICAgICAgICAgIGEgPSBBcnJheXMuY29weU9mKGEsIG4sIE9iamVjdFtdLmNsYXNzKTsKKyAgICAgICAgaWYgKHNjcmVlbiAmJiAobiA9PSAxIHx8IHRoaXMuY29tcGFyYXRvciAhPSBudWxsKSkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyArK2kpCisgICAgICAgICAgICAgICAgaWYgKGFbaV0gPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5xdWV1ZSA9IGE7CisgICAgICAgIHRoaXMuc2l6ZSA9IG47CisgICAgICAgIGlmIChoZWFwaWZ5KQorICAgICAgICAgICAgaGVhcGlmeSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyaWVzIHRvIGdyb3cgYXJyYXkgdG8gYWNjb21tb2RhdGUgYXQgbGVhc3Qgb25lIG1vcmUgZWxlbWVudAorICAgICAqIChidXQgbm9ybWFsbHkgZXhwYW5kIGJ5IGFib3V0IDUwJSksIGdpdmluZyB1cCAoYWxsb3dpbmcgcmV0cnkpCisgICAgICogb24gY29udGVudGlvbiAod2hpY2ggd2UgZXhwZWN0IHRvIGJlIHJhcmUpLiBDYWxsIG9ubHkgd2hpbGUKKyAgICAgKiBob2xkaW5nIGxvY2suCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkgdGhlIGhlYXAgYXJyYXkKKyAgICAgKiBAcGFyYW0gb2xkQ2FwIHRoZSBsZW5ndGggb2YgdGhlIGFycmF5CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHRyeUdyb3coT2JqZWN0W10gYXJyYXksIGludCBvbGRDYXApIHsKKyAgICAgICAgbG9jay51bmxvY2soKTsgLy8gbXVzdCByZWxlYXNlIGFuZCB0aGVuIHJlLWFjcXVpcmUgbWFpbiBsb2NrCisgICAgICAgIE9iamVjdFtdIG5ld0FycmF5ID0gbnVsbDsKKyAgICAgICAgaWYgKGFsbG9jYXRpb25TcGluTG9jayA9PSAwICYmCisgICAgICAgICAgICBVTlNBRkUuY29tcGFyZUFuZFN3YXBJbnQodGhpcywgYWxsb2NhdGlvblNwaW5Mb2NrT2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDEpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGludCBuZXdDYXAgPSBvbGRDYXAgKyAoKG9sZENhcCA8IDY0KSA/CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob2xkQ2FwICsgMikgOiAvLyBncm93IGZhc3RlciBpZiBzbWFsbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9sZENhcCA+PiAxKSk7CisgICAgICAgICAgICAgICAgaWYgKG5ld0NhcCAtIE1BWF9BUlJBWV9TSVpFID4gMCkgeyAgICAvLyBwb3NzaWJsZSBvdmVyZmxvdworICAgICAgICAgICAgICAgICAgICBpbnQgbWluQ2FwID0gb2xkQ2FwICsgMTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG1pbkNhcCA8IDAgfHwgbWluQ2FwID4gTUFYX0FSUkFZX1NJWkUpCisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgT3V0T2ZNZW1vcnlFcnJvcigpOworICAgICAgICAgICAgICAgICAgICBuZXdDYXAgPSBNQVhfQVJSQVlfU0laRTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKG5ld0NhcCA+IG9sZENhcCAmJiBxdWV1ZSA9PSBhcnJheSkKKyAgICAgICAgICAgICAgICAgICAgbmV3QXJyYXkgPSBuZXcgT2JqZWN0W25ld0NhcF07CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGFsbG9jYXRpb25TcGluTG9jayA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKG5ld0FycmF5ID09IG51bGwpIC8vIGJhY2sgb2ZmIGlmIGFub3RoZXIgdGhyZWFkIGlzIGFsbG9jYXRpbmcKKyAgICAgICAgICAgIFRocmVhZC55aWVsZCgpOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgaWYgKG5ld0FycmF5ICE9IG51bGwgJiYgcXVldWUgPT0gYXJyYXkpIHsKKyAgICAgICAgICAgIHF1ZXVlID0gbmV3QXJyYXk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFycmF5LCAwLCBuZXdBcnJheSwgMCwgb2xkQ2FwKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIE1lY2hhbmljcyBmb3IgcG9sbCgpLiAgQ2FsbCBvbmx5IHdoaWxlIGhvbGRpbmcgbG9jay4KKyAgICAgKi8KKyAgICBwcml2YXRlIEUgZXh0cmFjdCgpIHsKKyAgICAgICAgRSByZXN1bHQ7CisgICAgICAgIGludCBuID0gc2l6ZSAtIDE7CisgICAgICAgIGlmIChuIDwgMCkKKyAgICAgICAgICAgIHJlc3VsdCA9IG51bGw7CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgT2JqZWN0W10gYXJyYXkgPSBxdWV1ZTsKKyAgICAgICAgICAgIHJlc3VsdCA9IChFKSBhcnJheVswXTsKKyAgICAgICAgICAgIEUgeCA9IChFKSBhcnJheVtuXTsKKyAgICAgICAgICAgIGFycmF5W25dID0gbnVsbDsKKyAgICAgICAgICAgIENvbXBhcmF0b3I8PyBzdXBlciBFPiBjbXAgPSBjb21wYXJhdG9yOworICAgICAgICAgICAgaWYgKGNtcCA9PSBudWxsKQorICAgICAgICAgICAgICAgIHNpZnREb3duQ29tcGFyYWJsZSgwLCB4LCBhcnJheSwgbik7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgc2lmdERvd25Vc2luZ0NvbXBhcmF0b3IoMCwgeCwgYXJyYXksIG4sIGNtcCk7CisgICAgICAgICAgICBzaXplID0gbjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMgaXRlbSB4IGF0IHBvc2l0aW9uIGssIG1haW50YWluaW5nIGhlYXAgaW52YXJpYW50IGJ5CisgICAgICogcHJvbW90aW5nIHggdXAgdGhlIHRyZWUgdW50aWwgaXQgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvCisgICAgICogaXRzIHBhcmVudCwgb3IgaXMgdGhlIHJvb3QuCisgICAgICoKKyAgICAgKiBUbyBzaW1wbGlmeSBhbmQgc3BlZWQgdXAgY29lcmNpb25zIGFuZCBjb21wYXJpc29ucy4gdGhlCisgICAgICogQ29tcGFyYWJsZSBhbmQgQ29tcGFyYXRvciB2ZXJzaW9ucyBhcmUgc2VwYXJhdGVkIGludG8gZGlmZmVyZW50CisgICAgICogbWV0aG9kcyB0aGF0IGFyZSBvdGhlcndpc2UgaWRlbnRpY2FsLiAoU2ltaWxhcmx5IGZvciBzaWZ0RG93bi4pCisgICAgICogVGhlc2UgbWV0aG9kcyBhcmUgc3RhdGljLCB3aXRoIGhlYXAgc3RhdGUgYXMgYXJndW1lbnRzLCB0bworICAgICAqIHNpbXBsaWZ5IHVzZSBpbiBsaWdodCBvZiBwb3NzaWJsZSBjb21wYXJhdG9yIGV4Y2VwdGlvbnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gayB0aGUgcG9zaXRpb24gdG8gZmlsbAorICAgICAqIEBwYXJhbSB4IHRoZSBpdGVtIHRvIGluc2VydAorICAgICAqIEBwYXJhbSBhcnJheSB0aGUgaGVhcCBhcnJheQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIDxUPiB2b2lkIHNpZnRVcENvbXBhcmFibGUoaW50IGssIFQgeCwgT2JqZWN0W10gYXJyYXkpIHsKKyAgICAgICAgQ29tcGFyYWJsZTw/IHN1cGVyIFQ+IGtleSA9IChDb21wYXJhYmxlPD8gc3VwZXIgVD4pIHg7CisgICAgICAgIHdoaWxlIChrID4gMCkgeworICAgICAgICAgICAgaW50IHBhcmVudCA9IChrIC0gMSkgPj4+IDE7CisgICAgICAgICAgICBPYmplY3QgZSA9IGFycmF5W3BhcmVudF07CisgICAgICAgICAgICBpZiAoa2V5LmNvbXBhcmVUbygoVCkgZSkgPj0gMCkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGFycmF5W2tdID0gZTsKKyAgICAgICAgICAgIGsgPSBwYXJlbnQ7CisgICAgICAgIH0KKyAgICAgICAgYXJyYXlba10gPSBrZXk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgPFQ+IHZvaWQgc2lmdFVwVXNpbmdDb21wYXJhdG9yKGludCBrLCBUIHgsIE9iamVjdFtdIGFycmF5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29tcGFyYXRvcjw/IHN1cGVyIFQ+IGNtcCkgeworICAgICAgICB3aGlsZSAoayA+IDApIHsKKyAgICAgICAgICAgIGludCBwYXJlbnQgPSAoayAtIDEpID4+PiAxOworICAgICAgICAgICAgT2JqZWN0IGUgPSBhcnJheVtwYXJlbnRdOworICAgICAgICAgICAgaWYgKGNtcC5jb21wYXJlKHgsIChUKSBlKSA+PSAwKQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgYXJyYXlba10gPSBlOworICAgICAgICAgICAgayA9IHBhcmVudDsKKyAgICAgICAgfQorICAgICAgICBhcnJheVtrXSA9IHg7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyBpdGVtIHggYXQgcG9zaXRpb24gaywgbWFpbnRhaW5pbmcgaGVhcCBpbnZhcmlhbnQgYnkKKyAgICAgKiBkZW1vdGluZyB4IGRvd24gdGhlIHRyZWUgcmVwZWF0ZWRseSB1bnRpbCBpdCBpcyBsZXNzIHRoYW4gb3IKKyAgICAgKiBlcXVhbCB0byBpdHMgY2hpbGRyZW4gb3IgaXMgYSBsZWFmLgorICAgICAqCisgICAgICogQHBhcmFtIGsgdGhlIHBvc2l0aW9uIHRvIGZpbGwKKyAgICAgKiBAcGFyYW0geCB0aGUgaXRlbSB0byBpbnNlcnQKKyAgICAgKiBAcGFyYW0gYXJyYXkgdGhlIGhlYXAgYXJyYXkKKyAgICAgKiBAcGFyYW0gbiBoZWFwIHNpemUKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyA8VD4gdm9pZCBzaWZ0RG93bkNvbXBhcmFibGUoaW50IGssIFQgeCwgT2JqZWN0W10gYXJyYXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuKSB7CisgICAgICAgIENvbXBhcmFibGU8PyBzdXBlciBUPiBrZXkgPSAoQ29tcGFyYWJsZTw/IHN1cGVyIFQ+KXg7CisgICAgICAgIGludCBoYWxmID0gbiA+Pj4gMTsgICAgICAgICAgIC8vIGxvb3Agd2hpbGUgYSBub24tbGVhZgorICAgICAgICB3aGlsZSAoayA8IGhhbGYpIHsKKyAgICAgICAgICAgIGludCBjaGlsZCA9IChrIDw8IDEpICsgMTsgLy8gYXNzdW1lIGxlZnQgY2hpbGQgaXMgbGVhc3QKKyAgICAgICAgICAgIE9iamVjdCBjID0gYXJyYXlbY2hpbGRdOworICAgICAgICAgICAgaW50IHJpZ2h0ID0gY2hpbGQgKyAxOworICAgICAgICAgICAgaWYgKHJpZ2h0IDwgbiAmJgorICAgICAgICAgICAgICAgICgoQ29tcGFyYWJsZTw/IHN1cGVyIFQ+KSBjKS5jb21wYXJlVG8oKFQpIGFycmF5W3JpZ2h0XSkgPiAwKQorICAgICAgICAgICAgICAgIGMgPSBhcnJheVtjaGlsZCA9IHJpZ2h0XTsKKyAgICAgICAgICAgIGlmIChrZXkuY29tcGFyZVRvKChUKSBjKSA8PSAwKQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgYXJyYXlba10gPSBjOworICAgICAgICAgICAgayA9IGNoaWxkOworICAgICAgICB9CisgICAgICAgIGFycmF5W2tdID0ga2V5OworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIDxUPiB2b2lkIHNpZnREb3duVXNpbmdDb21wYXJhdG9yKGludCBrLCBUIHgsIE9iamVjdFtdIGFycmF5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbXBhcmF0b3I8PyBzdXBlciBUPiBjbXApIHsKKyAgICAgICAgaW50IGhhbGYgPSBuID4+PiAxOworICAgICAgICB3aGlsZSAoayA8IGhhbGYpIHsKKyAgICAgICAgICAgIGludCBjaGlsZCA9IChrIDw8IDEpICsgMTsKKyAgICAgICAgICAgIE9iamVjdCBjID0gYXJyYXlbY2hpbGRdOworICAgICAgICAgICAgaW50IHJpZ2h0ID0gY2hpbGQgKyAxOworICAgICAgICAgICAgaWYgKHJpZ2h0IDwgbiAmJiBjbXAuY29tcGFyZSgoVCkgYywgKFQpIGFycmF5W3JpZ2h0XSkgPiAwKQorICAgICAgICAgICAgICAgIGMgPSBhcnJheVtjaGlsZCA9IHJpZ2h0XTsKKyAgICAgICAgICAgIGlmIChjbXAuY29tcGFyZSh4LCAoVCkgYykgPD0gMCkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGFycmF5W2tdID0gYzsKKyAgICAgICAgICAgIGsgPSBjaGlsZDsKKyAgICAgICAgfQorICAgICAgICBhcnJheVtrXSA9IHg7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXN0YWJsaXNoZXMgdGhlIGhlYXAgaW52YXJpYW50IChkZXNjcmliZWQgYWJvdmUpIGluIHRoZSBlbnRpcmUgdHJlZSwKKyAgICAgKiBhc3N1bWluZyBub3RoaW5nIGFib3V0IHRoZSBvcmRlciBvZiB0aGUgZWxlbWVudHMgcHJpb3IgdG8gdGhlIGNhbGwuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGhlYXBpZnkoKSB7CisgICAgICAgIE9iamVjdFtdIGFycmF5ID0gcXVldWU7CisgICAgICAgIGludCBuID0gc2l6ZTsKKyAgICAgICAgaW50IGhhbGYgPSAobiA+Pj4gMSkgLSAxOworICAgICAgICBDb21wYXJhdG9yPD8gc3VwZXIgRT4gY21wID0gY29tcGFyYXRvcjsKKyAgICAgICAgaWYgKGNtcCA9PSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gaGFsZjsgaSA+PSAwOyBpLS0pCisgICAgICAgICAgICAgICAgc2lmdERvd25Db21wYXJhYmxlKGksIChFKSBhcnJheVtpXSwgYXJyYXksIG4pOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IGhhbGY7IGkgPj0gMDsgaS0tKQorICAgICAgICAgICAgICAgIHNpZnREb3duVXNpbmdDb21wYXJhdG9yKGksIChFKSBhcnJheVtpXSwgYXJyYXksIG4sIGNtcCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpbnRvIHRoaXMgcHJpb3JpdHkgcXVldWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byBhZGQKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSAoYXMgc3BlY2lmaWVkIGJ5IHtAbGluayBDb2xsZWN0aW9uI2FkZH0pCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGNhbm5vdCBiZSBjb21wYXJlZAorICAgICAqICAgICAgICAgd2l0aCBlbGVtZW50cyBjdXJyZW50bHkgaW4gdGhlIHByaW9yaXR5IHF1ZXVlIGFjY29yZGluZyB0byB0aGUKKyAgICAgKiAgICAgICAgIHByaW9yaXR5IHF1ZXVlJ3Mgb3JkZXJpbmcKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYWRkKEUgZSkgeworICAgICAgICByZXR1cm4gb2ZmZXIoZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaW50byB0aGlzIHByaW9yaXR5IHF1ZXVlLgorICAgICAqIEFzIHRoZSBxdWV1ZSBpcyB1bmJvdW5kZWQsIHRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIgcmV0dXJuIHtAY29kZSBmYWxzZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byBhZGQKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSAoYXMgc3BlY2lmaWVkIGJ5IHtAbGluayBRdWV1ZSNvZmZlcn0pCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGNhbm5vdCBiZSBjb21wYXJlZAorICAgICAqICAgICAgICAgd2l0aCBlbGVtZW50cyBjdXJyZW50bHkgaW4gdGhlIHByaW9yaXR5IHF1ZXVlIGFjY29yZGluZyB0byB0aGUKKyAgICAgKiAgICAgICAgIHByaW9yaXR5IHF1ZXVlJ3Mgb3JkZXJpbmcKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gb2ZmZXIoRSBlKSB7CisgICAgICAgIGlmIChlID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgaW50IG4sIGNhcDsKKyAgICAgICAgT2JqZWN0W10gYXJyYXk7CisgICAgICAgIHdoaWxlICgobiA9IHNpemUpID49IChjYXAgPSAoYXJyYXkgPSBxdWV1ZSkubGVuZ3RoKSkKKyAgICAgICAgICAgIHRyeUdyb3coYXJyYXksIGNhcCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb21wYXJhdG9yPD8gc3VwZXIgRT4gY21wID0gY29tcGFyYXRvcjsKKyAgICAgICAgICAgIGlmIChjbXAgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICBzaWZ0VXBDb21wYXJhYmxlKG4sIGUsIGFycmF5KTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBzaWZ0VXBVc2luZ0NvbXBhcmF0b3IobiwgZSwgYXJyYXksIGNtcCk7CisgICAgICAgICAgICBzaXplID0gbiArIDE7CisgICAgICAgICAgICBub3RFbXB0eS5zaWduYWwoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaW50byB0aGlzIHByaW9yaXR5IHF1ZXVlLgorICAgICAqIEFzIHRoZSBxdWV1ZSBpcyB1bmJvdW5kZWQsIHRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIgYmxvY2suCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byBhZGQKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgY2Fubm90IGJlIGNvbXBhcmVkCisgICAgICogICAgICAgICB3aXRoIGVsZW1lbnRzIGN1cnJlbnRseSBpbiB0aGUgcHJpb3JpdHkgcXVldWUgYWNjb3JkaW5nIHRvIHRoZQorICAgICAqICAgICAgICAgcHJpb3JpdHkgcXVldWUncyBvcmRlcmluZworICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXQoRSBlKSB7CisgICAgICAgIG9mZmVyKGUpOyAvLyBuZXZlciBuZWVkIHRvIGJsb2NrCisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaW50byB0aGlzIHByaW9yaXR5IHF1ZXVlLgorICAgICAqIEFzIHRoZSBxdWV1ZSBpcyB1bmJvdW5kZWQsIHRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIgYmxvY2sgb3IKKyAgICAgKiByZXR1cm4ge0Bjb2RlIGZhbHNlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIHRoZSBlbGVtZW50IHRvIGFkZAorICAgICAqIEBwYXJhbSB0aW1lb3V0IFRoaXMgcGFyYW1ldGVyIGlzIGlnbm9yZWQgYXMgdGhlIG1ldGhvZCBuZXZlciBibG9ja3MKKyAgICAgKiBAcGFyYW0gdW5pdCBUaGlzIHBhcmFtZXRlciBpcyBpZ25vcmVkIGFzIHRoZSBtZXRob2QgbmV2ZXIgYmxvY2tzCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gKGFzIHNwZWNpZmllZCBieQorICAgICAqICB7QGxpbmsgQmxvY2tpbmdRdWV1ZSNvZmZlciBCbG9ja2luZ1F1ZXVlLm9mZmVyfSkKKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgY2Fubm90IGJlIGNvbXBhcmVkCisgICAgICogICAgICAgICB3aXRoIGVsZW1lbnRzIGN1cnJlbnRseSBpbiB0aGUgcHJpb3JpdHkgcXVldWUgYWNjb3JkaW5nIHRvIHRoZQorICAgICAqICAgICAgICAgcHJpb3JpdHkgcXVldWUncyBvcmRlcmluZworICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBvZmZlcihFIGUsIGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkgeworICAgICAgICByZXR1cm4gb2ZmZXIoZSk7IC8vIG5ldmVyIG5lZWQgdG8gYmxvY2sKKyAgICB9CisKKyAgICBwdWJsaWMgRSBwb2xsKCkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICBFIHJlc3VsdDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlc3VsdCA9IGV4dHJhY3QoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgRSB0YWtlKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2tJbnRlcnJ1cHRpYmx5KCk7CisgICAgICAgIEUgcmVzdWx0OworICAgICAgICB0cnkgeworICAgICAgICAgICAgd2hpbGUgKCAocmVzdWx0ID0gZXh0cmFjdCgpKSA9PSBudWxsKQorICAgICAgICAgICAgICAgIG5vdEVtcHR5LmF3YWl0KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIEUgcG9sbChsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgbmFub3MgPSB1bml0LnRvTmFub3ModGltZW91dCk7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrSW50ZXJydXB0aWJseSgpOworICAgICAgICBFIHJlc3VsdDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdoaWxlICggKHJlc3VsdCA9IGV4dHJhY3QoKSkgPT0gbnVsbCAmJiBuYW5vcyA+IDApCisgICAgICAgICAgICAgICAgbmFub3MgPSBub3RFbXB0eS5hd2FpdE5hbm9zKG5hbm9zKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgRSBwZWVrKCkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICBFIHJlc3VsdDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlc3VsdCA9IHNpemUgPiAwID8gKEUpIHF1ZXVlWzBdIDogbnVsbDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb21wYXJhdG9yIHVzZWQgdG8gb3JkZXIgdGhlIGVsZW1lbnRzIGluIHRoaXMgcXVldWUsCisgICAgICogb3Ige0Bjb2RlIG51bGx9IGlmIHRoaXMgcXVldWUgdXNlcyB0aGUge0BsaW5rcGxhaW4gQ29tcGFyYWJsZQorICAgICAqIG5hdHVyYWwgb3JkZXJpbmd9IG9mIGl0cyBlbGVtZW50cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNvbXBhcmF0b3IgdXNlZCB0byBvcmRlciB0aGUgZWxlbWVudHMgaW4gdGhpcyBxdWV1ZSwKKyAgICAgKiAgICAgICAgIG9yIHtAY29kZSBudWxsfSBpZiB0aGlzIHF1ZXVlIHVzZXMgdGhlIG5hdHVyYWwKKyAgICAgKiAgICAgICAgIG9yZGVyaW5nIG9mIGl0cyBlbGVtZW50cworICAgICAqLworICAgIHB1YmxpYyBDb21wYXJhdG9yPD8gc3VwZXIgRT4gY29tcGFyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIGNvbXBhcmF0b3I7CisgICAgfQorCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHNpemU7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQWx3YXlzIHJldHVybnMge0Bjb2RlIEludGVnZXIuTUFYX1ZBTFVFfSBiZWNhdXNlCisgICAgICogYSB7QGNvZGUgUHJpb3JpdHlCbG9ja2luZ1F1ZXVlfSBpcyBub3QgY2FwYWNpdHkgY29uc3RyYWluZWQuCisgICAgICogQHJldHVybiB7QGNvZGUgSW50ZWdlci5NQVhfVkFMVUV9IGFsd2F5cworICAgICAqLworICAgIHB1YmxpYyBpbnQgcmVtYWluaW5nQ2FwYWNpdHkoKSB7CisgICAgICAgIHJldHVybiBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBpbmRleE9mKE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvICE9IG51bGwpIHsKKyAgICAgICAgICAgIE9iamVjdFtdIGFycmF5ID0gcXVldWU7CisgICAgICAgICAgICBpbnQgbiA9IHNpemU7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKKyAgICAgICAgICAgICAgICBpZiAoby5lcXVhbHMoYXJyYXlbaV0pKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgaXRoIGVsZW1lbnQgZnJvbSBxdWV1ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVtb3ZlQXQoaW50IGkpIHsKKyAgICAgICAgT2JqZWN0W10gYXJyYXkgPSBxdWV1ZTsKKyAgICAgICAgaW50IG4gPSBzaXplIC0gMTsKKyAgICAgICAgaWYgKG4gPT0gaSkgLy8gcmVtb3ZlZCBsYXN0IGVsZW1lbnQKKyAgICAgICAgICAgIGFycmF5W2ldID0gbnVsbDsKKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBFIG1vdmVkID0gKEUpIGFycmF5W25dOworICAgICAgICAgICAgYXJyYXlbbl0gPSBudWxsOworICAgICAgICAgICAgQ29tcGFyYXRvcjw/IHN1cGVyIEU+IGNtcCA9IGNvbXBhcmF0b3I7CisgICAgICAgICAgICBpZiAoY21wID09IG51bGwpCisgICAgICAgICAgICAgICAgc2lmdERvd25Db21wYXJhYmxlKGksIG1vdmVkLCBhcnJheSwgbik7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgc2lmdERvd25Vc2luZ0NvbXBhcmF0b3IoaSwgbW92ZWQsIGFycmF5LCBuLCBjbXApOworICAgICAgICAgICAgaWYgKGFycmF5W2ldID09IG1vdmVkKSB7CisgICAgICAgICAgICAgICAgaWYgKGNtcCA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICBzaWZ0VXBDb21wYXJhYmxlKGksIG1vdmVkLCBhcnJheSk7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBzaWZ0VXBVc2luZ0NvbXBhcmF0b3IoaSwgbW92ZWQsIGFycmF5LCBjbXApOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHNpemUgPSBuOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYSBzaW5nbGUgaW5zdGFuY2Ugb2YgdGhlIHNwZWNpZmllZCBlbGVtZW50IGZyb20gdGhpcyBxdWV1ZSwKKyAgICAgKiBpZiBpdCBpcyBwcmVzZW50LiAgTW9yZSBmb3JtYWxseSwgcmVtb3ZlcyBhbiBlbGVtZW50IHtAY29kZSBlfSBzdWNoCisgICAgICogdGhhdCB7QGNvZGUgby5lcXVhbHMoZSl9LCBpZiB0aGlzIHF1ZXVlIGNvbnRhaW5zIG9uZSBvciBtb3JlIHN1Y2gKKyAgICAgKiBlbGVtZW50cy4gIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIGFuZCBvbmx5IGlmIHRoaXMgcXVldWUgY29udGFpbmVkCisgICAgICogdGhlIHNwZWNpZmllZCBlbGVtZW50IChvciBlcXVpdmFsZW50bHksIGlmIHRoaXMgcXVldWUgY2hhbmdlZCBhcyBhCisgICAgICogcmVzdWx0IG9mIHRoZSBjYWxsKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvIGVsZW1lbnQgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoaXMgcXVldWUsIGlmIHByZXNlbnQKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHF1ZXVlIGNoYW5nZWQgYXMgYSByZXN1bHQgb2YgdGhlIGNhbGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG8pIHsKKyAgICAgICAgYm9vbGVhbiByZW1vdmVkID0gZmFsc2U7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgaSA9IGluZGV4T2Yobyk7CisgICAgICAgICAgICBpZiAoaSAhPSAtMSkgeworICAgICAgICAgICAgICAgIHJlbW92ZUF0KGkpOworICAgICAgICAgICAgICAgIHJlbW92ZWQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVtb3ZlZDsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIElkZW50aXR5LWJhc2VkIHZlcnNpb24gZm9yIHVzZSBpbiBJdHIucmVtb3ZlCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlbW92ZUVRKE9iamVjdCBvKSB7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBPYmplY3RbXSBhcnJheSA9IHF1ZXVlOworICAgICAgICAgICAgaW50IG4gPSBzaXplOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAobyA9PSBhcnJheVtpXSkgeworICAgICAgICAgICAgICAgICAgICByZW1vdmVBdChpKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoaXMgcXVldWUgY29udGFpbnMgdGhlIHNwZWNpZmllZCBlbGVtZW50LgorICAgICAqIE1vcmUgZm9ybWFsbHksIHJldHVybnMge0Bjb2RlIHRydWV9IGlmIGFuZCBvbmx5IGlmIHRoaXMgcXVldWUgY29udGFpbnMKKyAgICAgKiBhdCBsZWFzdCBvbmUgZWxlbWVudCB7QGNvZGUgZX0gc3VjaCB0aGF0IHtAY29kZSBvLmVxdWFscyhlKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBvYmplY3QgdG8gYmUgY2hlY2tlZCBmb3IgY29udGFpbm1lbnQgaW4gdGhpcyBxdWV1ZQorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgcXVldWUgY29udGFpbnMgdGhlIHNwZWNpZmllZCBlbGVtZW50CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IG8pIHsKKyAgICAgICAgaW50IGluZGV4OworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5kZXggPSBpbmRleE9mKG8pOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW5kZXggIT0gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIGFsbCBvZiB0aGUgZWxlbWVudHMgaW4gdGhpcyBxdWV1ZS4KKyAgICAgKiBUaGUgcmV0dXJuZWQgYXJyYXkgZWxlbWVudHMgYXJlIGluIG5vIHBhcnRpY3VsYXIgb3JkZXIuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQgYXJyYXkgd2lsbCBiZSAic2FmZSIgaW4gdGhhdCBubyByZWZlcmVuY2VzIHRvIGl0IGFyZQorICAgICAqIG1haW50YWluZWQgYnkgdGhpcyBxdWV1ZS4gIChJbiBvdGhlciB3b3JkcywgdGhpcyBtZXRob2QgbXVzdCBhbGxvY2F0ZQorICAgICAqIGEgbmV3IGFycmF5KS4gIFRoZSBjYWxsZXIgaXMgdGh1cyBmcmVlIHRvIG1vZGlmeSB0aGUgcmV0dXJuZWQgYXJyYXkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBhY3RzIGFzIGJyaWRnZSBiZXR3ZWVuIGFycmF5LWJhc2VkIGFuZCBjb2xsZWN0aW9uLWJhc2VkCisgICAgICogQVBJcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgY29udGFpbmluZyBhbGwgb2YgdGhlIGVsZW1lbnRzIGluIHRoaXMgcXVldWUKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBBcnJheXMuY29weU9mKHF1ZXVlLCBzaXplKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgbiA9IHNpemU7CisgICAgICAgICAgICBpZiAobiA9PSAwKQorICAgICAgICAgICAgICAgIHJldHVybiAiW10iOworICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgICAgICBzYi5hcHBlbmQoJ1snKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgKytpKSB7CisgICAgICAgICAgICAgICAgRSBlID0gKEUpcXVldWVbaV07CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKGUgPT0gdGhpcyA/ICIodGhpcyBDb2xsZWN0aW9uKSIgOiBlKTsKKyAgICAgICAgICAgICAgICBpZiAoaSAhPSBuIC0gMSkKKyAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCcsJykuYXBwZW5kKCcgJyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gc2IuYXBwZW5kKCddJykudG9TdHJpbmcoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiAgICAgICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICAgICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGRyYWluVG8oQ29sbGVjdGlvbjw/IHN1cGVyIEU+IGMpIHsKKyAgICAgICAgaWYgKGMgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBpZiAoYyA9PSB0aGlzKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgIGxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IG4gPSAwOworICAgICAgICAgICAgRSBlOworICAgICAgICAgICAgd2hpbGUgKCAoZSA9IGV4dHJhY3QoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGMuYWRkKGUpOworICAgICAgICAgICAgICAgICsrbjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uICAgICAgICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gICAgICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZHJhaW5UbyhDb2xsZWN0aW9uPD8gc3VwZXIgRT4gYywgaW50IG1heEVsZW1lbnRzKSB7CisgICAgICAgIGlmIChjID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgaWYgKGMgPT0gdGhpcykKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgaWYgKG1heEVsZW1lbnRzIDw9IDApCisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBuID0gMDsKKyAgICAgICAgICAgIEUgZTsKKyAgICAgICAgICAgIHdoaWxlIChuIDwgbWF4RWxlbWVudHMgJiYgKGUgPSBleHRyYWN0KCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjLmFkZChlKTsKKyAgICAgICAgICAgICAgICArK247CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbjsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHJlbW92ZXMgYWxsIG9mIHRoZSBlbGVtZW50cyBmcm9tIHRoaXMgcXVldWUuCisgICAgICogVGhlIHF1ZXVlIHdpbGwgYmUgZW1wdHkgYWZ0ZXIgdGhpcyBjYWxsIHJldHVybnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IHRoaXMubG9jazsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBPYmplY3RbXSBhcnJheSA9IHF1ZXVlOworICAgICAgICAgICAgaW50IG4gPSBzaXplOworICAgICAgICAgICAgc2l6ZSA9IDA7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKKyAgICAgICAgICAgICAgICBhcnJheVtpXSA9IG51bGw7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIGFsbCBvZiB0aGUgZWxlbWVudHMgaW4gdGhpcyBxdWV1ZTsgdGhlCisgICAgICogcnVudGltZSB0eXBlIG9mIHRoZSByZXR1cm5lZCBhcnJheSBpcyB0aGF0IG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkuCisgICAgICogVGhlIHJldHVybmVkIGFycmF5IGVsZW1lbnRzIGFyZSBpbiBubyBwYXJ0aWN1bGFyIG9yZGVyLgorICAgICAqIElmIHRoZSBxdWV1ZSBmaXRzIGluIHRoZSBzcGVjaWZpZWQgYXJyYXksIGl0IGlzIHJldHVybmVkIHRoZXJlaW4uCisgICAgICogT3RoZXJ3aXNlLCBhIG5ldyBhcnJheSBpcyBhbGxvY2F0ZWQgd2l0aCB0aGUgcnVudGltZSB0eXBlIG9mIHRoZQorICAgICAqIHNwZWNpZmllZCBhcnJheSBhbmQgdGhlIHNpemUgb2YgdGhpcyBxdWV1ZS4KKyAgICAgKgorICAgICAqIDxwPklmIHRoaXMgcXVldWUgZml0cyBpbiB0aGUgc3BlY2lmaWVkIGFycmF5IHdpdGggcm9vbSB0byBzcGFyZQorICAgICAqIChpLmUuLCB0aGUgYXJyYXkgaGFzIG1vcmUgZWxlbWVudHMgdGhhbiB0aGlzIHF1ZXVlKSwgdGhlIGVsZW1lbnQgaW4KKyAgICAgKiB0aGUgYXJyYXkgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZSBlbmQgb2YgdGhlIHF1ZXVlIGlzIHNldCB0bworICAgICAqIHtAY29kZSBudWxsfS4KKyAgICAgKgorICAgICAqIDxwPkxpa2UgdGhlIHtAbGluayAjdG9BcnJheSgpfSBtZXRob2QsIHRoaXMgbWV0aG9kIGFjdHMgYXMgYnJpZGdlIGJldHdlZW4KKyAgICAgKiBhcnJheS1iYXNlZCBhbmQgY29sbGVjdGlvbi1iYXNlZCBBUElzLiAgRnVydGhlciwgdGhpcyBtZXRob2QgYWxsb3dzCisgICAgICogcHJlY2lzZSBjb250cm9sIG92ZXIgdGhlIHJ1bnRpbWUgdHlwZSBvZiB0aGUgb3V0cHV0IGFycmF5LCBhbmQgbWF5LAorICAgICAqIHVuZGVyIGNlcnRhaW4gY2lyY3Vtc3RhbmNlcywgYmUgdXNlZCB0byBzYXZlIGFsbG9jYXRpb24gY29zdHMuCisgICAgICoKKyAgICAgKiA8cD5TdXBwb3NlIHtAY29kZSB4fSBpcyBhIHF1ZXVlIGtub3duIHRvIGNvbnRhaW4gb25seSBzdHJpbmdzLgorICAgICAqIFRoZSBmb2xsb3dpbmcgY29kZSBjYW4gYmUgdXNlZCB0byBkdW1wIHRoZSBxdWV1ZSBpbnRvIGEgbmV3bHkKKyAgICAgKiBhbGxvY2F0ZWQgYXJyYXkgb2Yge0Bjb2RlIFN0cmluZ306CisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqICAgICBTdHJpbmdbXSB5ID0geC50b0FycmF5KG5ldyBTdHJpbmdbMF0pOzwvcHJlPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IHtAY29kZSB0b0FycmF5KG5ldyBPYmplY3RbMF0pfSBpcyBpZGVudGljYWwgaW4gZnVuY3Rpb24gdG8KKyAgICAgKiB7QGNvZGUgdG9BcnJheSgpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhIHRoZSBhcnJheSBpbnRvIHdoaWNoIHRoZSBlbGVtZW50cyBvZiB0aGUgcXVldWUgYXJlIHRvCisgICAgICogICAgICAgICAgYmUgc3RvcmVkLCBpZiBpdCBpcyBiaWcgZW5vdWdoOyBvdGhlcndpc2UsIGEgbmV3IGFycmF5IG9mIHRoZQorICAgICAqICAgICAgICAgIHNhbWUgcnVudGltZSB0eXBlIGlzIGFsbG9jYXRlZCBmb3IgdGhpcyBwdXJwb3NlCisgICAgICogQHJldHVybiBhbiBhcnJheSBjb250YWluaW5nIGFsbCBvZiB0aGUgZWxlbWVudHMgaW4gdGhpcyBxdWV1ZQorICAgICAqIEB0aHJvd3MgQXJyYXlTdG9yZUV4Y2VwdGlvbiBpZiB0aGUgcnVudGltZSB0eXBlIG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkKKyAgICAgKiAgICAgICAgIGlzIG5vdCBhIHN1cGVydHlwZSBvZiB0aGUgcnVudGltZSB0eXBlIG9mIGV2ZXJ5IGVsZW1lbnQgaW4KKyAgICAgKiAgICAgICAgIHRoaXMgcXVldWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgYXJyYXkgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyA8VD4gVFtdIHRvQXJyYXkoVFtdIGEpIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBuID0gc2l6ZTsKKyAgICAgICAgICAgIGlmIChhLmxlbmd0aCA8IG4pCisgICAgICAgICAgICAgICAgLy8gTWFrZSBhIG5ldyBhcnJheSBvZiBhJ3MgcnVudGltZSB0eXBlLCBidXQgbXkgY29udGVudHM6CisgICAgICAgICAgICAgICAgcmV0dXJuIChUW10pIEFycmF5cy5jb3B5T2YocXVldWUsIHNpemUsIGEuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHF1ZXVlLCAwLCBhLCAwLCBuKTsKKyAgICAgICAgICAgIGlmIChhLmxlbmd0aCA+IG4pCisgICAgICAgICAgICAgICAgYVtuXSA9IG51bGw7CisgICAgICAgICAgICByZXR1cm4gYTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzIGluIHRoaXMgcXVldWUuIFRoZQorICAgICAqIGl0ZXJhdG9yIGRvZXMgbm90IHJldHVybiB0aGUgZWxlbWVudHMgaW4gYW55IHBhcnRpY3VsYXIgb3JkZXIuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQgaXRlcmF0b3IgaXMgYSAid2Vha2x5IGNvbnNpc3RlbnQiIGl0ZXJhdG9yIHRoYXQKKyAgICAgKiB3aWxsIG5ldmVyIHRocm93IHtAbGluayBqYXZhLnV0aWwuQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbgorICAgICAqIENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb259LCBhbmQgZ3VhcmFudGVlcyB0byB0cmF2ZXJzZQorICAgICAqIGVsZW1lbnRzIGFzIHRoZXkgZXhpc3RlZCB1cG9uIGNvbnN0cnVjdGlvbiBvZiB0aGUgaXRlcmF0b3IsIGFuZAorICAgICAqIG1heSAoYnV0IGlzIG5vdCBndWFyYW50ZWVkIHRvKSByZWZsZWN0IGFueSBtb2RpZmljYXRpb25zCisgICAgICogc3Vic2VxdWVudCB0byBjb25zdHJ1Y3Rpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzIGluIHRoaXMgcXVldWUKKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3I8RT4gaXRlcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBuZXcgSXRyKHRvQXJyYXkoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU25hcHNob3QgaXRlcmF0b3IgdGhhdCB3b3JrcyBvZmYgY29weSBvZiB1bmRlcmx5aW5nIHEgYXJyYXkuCisgICAgICovCisgICAgZmluYWwgY2xhc3MgSXRyIGltcGxlbWVudHMgSXRlcmF0b3I8RT4geworICAgICAgICBmaW5hbCBPYmplY3RbXSBhcnJheTsgLy8gQXJyYXkgb2YgYWxsIGVsZW1lbnRzCisgICAgICAgIGludCBjdXJzb3I7ICAgICAgICAgICAvLyBpbmRleCBvZiBuZXh0IGVsZW1lbnQgdG8gcmV0dXJuOworICAgICAgICBpbnQgbGFzdFJldDsgICAgICAgICAgLy8gaW5kZXggb2YgbGFzdCBlbGVtZW50LCBvciAtMSBpZiBubyBzdWNoCisKKyAgICAgICAgSXRyKE9iamVjdFtdIGFycmF5KSB7CisgICAgICAgICAgICBsYXN0UmV0ID0gLTE7CisgICAgICAgICAgICB0aGlzLmFycmF5ID0gYXJyYXk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgcmV0dXJuIGN1cnNvciA8IGFycmF5Lmxlbmd0aDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFIG5leHQoKSB7CisgICAgICAgICAgICBpZiAoY3Vyc29yID49IGFycmF5Lmxlbmd0aCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgbGFzdFJldCA9IGN1cnNvcjsKKyAgICAgICAgICAgIHJldHVybiAoRSlhcnJheVtjdXJzb3IrK107CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICBpZiAobGFzdFJldCA8IDApCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgcmVtb3ZlRVEoYXJyYXlbbGFzdFJldF0pOworICAgICAgICAgICAgbGFzdFJldCA9IC0xOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2F2ZXMgdGhlIHN0YXRlIHRvIGEgc3RyZWFtICh0aGF0IGlzLCBzZXJpYWxpemVzIGl0KS4gIEZvcgorICAgICAqIGNvbXBhdGliaWxpdHkgd2l0aCBwcmV2aW91cyB2ZXJzaW9uIG9mIHRoaXMgY2xhc3MsCisgICAgICogZWxlbWVudHMgYXJlIGZpcnN0IGNvcGllZCB0byBhIGphdmEudXRpbC5Qcmlvcml0eVF1ZXVlLAorICAgICAqIHdoaWNoIGlzIHRoZW4gc2VyaWFsaXplZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW0gcykKKyAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24geworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBuID0gc2l6ZTsgLy8gYXZvaWQgemVybyBjYXBhY2l0eSBhcmd1bWVudAorICAgICAgICAgICAgcSA9IG5ldyBQcmlvcml0eVF1ZXVlPEU+KG4gPT0gMCA/IDEgOiBuLCBjb21wYXJhdG9yKTsKKyAgICAgICAgICAgIHEuYWRkQWxsKHRoaXMpOworICAgICAgICAgICAgcy5kZWZhdWx0V3JpdGVPYmplY3QoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHEgPSBudWxsOworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlY29uc3RpdHV0ZXMgdGhlIHtAY29kZSBQcmlvcml0eUJsb2NraW5nUXVldWV9IGluc3RhbmNlIGZyb20gYSBzdHJlYW0KKyAgICAgKiAodGhhdCBpcywgZGVzZXJpYWxpemVzIGl0KS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzIHRoZSBzdHJlYW0KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtIHMpCisgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMuZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgICAgIHRoaXMucXVldWUgPSBuZXcgT2JqZWN0W3Euc2l6ZSgpXTsKKyAgICAgICAgICAgIGNvbXBhcmF0b3IgPSBxLmNvbXBhcmF0b3IoKTsKKyAgICAgICAgICAgIGFkZEFsbChxKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHEgPSBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gVW5zYWZlIG1lY2hhbmljcworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHN1bi5taXNjLlVuc2FmZSBVTlNBRkUgPSBzdW4ubWlzYy5VbnNhZmUuZ2V0VW5zYWZlKCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBhbGxvY2F0aW9uU3BpbkxvY2tPZmZzZXQgPQorICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJhbGxvY2F0aW9uU3BpbkxvY2siLAorICAgICAgICAgICAgICAgICAgICAgICAgICBQcmlvcml0eUJsb2NraW5nUXVldWUuY2xhc3MpOworCisgICAgc3RhdGljIGxvbmcgb2JqZWN0RmllbGRPZmZzZXQoc3VuLm1pc2MuVW5zYWZlIFVOU0FGRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZmllbGQsIENsYXNzPD8+IGtsYXp6KSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gVU5TQUZFLm9iamVjdEZpZWxkT2Zmc2V0KGtsYXp6LmdldERlY2xhcmVkRmllbGQoZmllbGQpKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRmllbGRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29udmVydCBFeGNlcHRpb24gdG8gY29ycmVzcG9uZGluZyBFcnJvcgorICAgICAgICAgICAgTm9TdWNoRmllbGRFcnJvciBlcnJvciA9IG5ldyBOb1N1Y2hGaWVsZEVycm9yKGZpZWxkKTsKKyAgICAgICAgICAgIGVycm9yLmluaXRDYXVzZShlKTsKKyAgICAgICAgICAgIHRocm93IGVycm9yOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvUmVqZWN0ZWRFeGVjdXRpb25FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9SZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMwYjA0M2QKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvUmVqZWN0ZWRFeGVjdXRpb25FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDYyIEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CisKKy8qKgorICogRXhjZXB0aW9uIHRocm93biBieSBhbiB7QGxpbmsgRXhlY3V0b3J9IHdoZW4gYSB0YXNrIGNhbm5vdCBiZQorICogYWNjZXB0ZWQgZm9yIGV4ZWN1dGlvbi4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKi8KK3B1YmxpYyBjbGFzcyBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0zNzU4MDU3MDI3NjcwNjk1NDVMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIDx0dD5SZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbjwvdHQ+IHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UuCisgICAgICogVGhlIGNhdXNlIGlzIG5vdCBpbml0aWFsaXplZCwgYW5kIG1heSBzdWJzZXF1ZW50bHkgYmUKKyAgICAgKiBpbml0aWFsaXplZCBieSBhIGNhbGwgdG8ge0BsaW5rICNpbml0Q2F1c2UoVGhyb3dhYmxlKSBpbml0Q2F1c2V9LgorICAgICAqLworICAgIHB1YmxpYyBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbigpIHsgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIDx0dD5SZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbjwvdHQ+IHdpdGggdGhlCisgICAgICogc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLiBUaGUgY2F1c2UgaXMgbm90IGluaXRpYWxpemVkLCBhbmQgbWF5CisgICAgICogc3Vic2VxdWVudGx5IGJlIGluaXRpYWxpemVkIGJ5IGEgY2FsbCB0byB7QGxpbmsKKyAgICAgKiAjaW5pdENhdXNlKFRocm93YWJsZSkgaW5pdENhdXNlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlIHRoZSBkZXRhaWwgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgPHR0PlJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9uPC90dD4gd2l0aCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UgYW5kIGNhdXNlLgorICAgICAqCisgICAgICogQHBhcmFtICBtZXNzYWdlIHRoZSBkZXRhaWwgbWVzc2FnZQorICAgICAqIEBwYXJhbSAgY2F1c2UgdGhlIGNhdXNlICh3aGljaCBpcyBzYXZlZCBmb3IgbGF0ZXIgcmV0cmlldmFsIGJ5IHRoZQorICAgICAqICAgICAgICAge0BsaW5rICNnZXRDYXVzZSgpfSBtZXRob2QpCisgICAgICovCisgICAgcHVibGljIFJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSA8dHQ+UmVqZWN0ZWRFeGVjdXRpb25FeGNlcHRpb248L3R0PiB3aXRoIHRoZQorICAgICAqIHNwZWNpZmllZCBjYXVzZS4gIFRoZSBkZXRhaWwgbWVzc2FnZSBpcyBzZXQgdG86IDxwcmU+IChjYXVzZSA9PQorICAgICAqIG51bGwgPyBudWxsIDogY2F1c2UudG9TdHJpbmcoKSk8L3ByZT4gKHdoaWNoIHR5cGljYWxseSBjb250YWlucworICAgICAqIHRoZSBjbGFzcyBhbmQgZGV0YWlsIG1lc3NhZ2Ugb2YgPHR0PmNhdXNlPC90dD4pLgorICAgICAqCisgICAgICogQHBhcmFtICBjYXVzZSB0aGUgY2F1c2UgKHdoaWNoIGlzIHNhdmVkIGZvciBsYXRlciByZXRyaWV2YWwgYnkgdGhlCisgICAgICogICAgICAgICB7QGxpbmsgI2dldENhdXNlKCl9IG1ldGhvZCkKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVqZWN0ZWRFeGVjdXRpb25FeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvUmVqZWN0ZWRFeGVjdXRpb25IYW5kbGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvUmVqZWN0ZWRFeGVjdXRpb25IYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDE3YTI3YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9SZWplY3RlZEV4ZWN1dGlvbkhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDMzIEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CisKKy8qKgorICogQSBoYW5kbGVyIGZvciB0YXNrcyB0aGF0IGNhbm5vdCBiZSBleGVjdXRlZCBieSBhIHtAbGluayBUaHJlYWRQb29sRXhlY3V0b3J9LgorICoKKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqLworcHVibGljIGludGVyZmFjZSBSZWplY3RlZEV4ZWN1dGlvbkhhbmRsZXIgeworCisgICAgLyoqCisgICAgICogTWV0aG9kIHRoYXQgbWF5IGJlIGludm9rZWQgYnkgYSB7QGxpbmsgVGhyZWFkUG9vbEV4ZWN1dG9yfSB3aGVuCisgICAgICoge0BsaW5rIFRocmVhZFBvb2xFeGVjdXRvciNleGVjdXRlIGV4ZWN1dGV9IGNhbm5vdCBhY2NlcHQgYQorICAgICAqIHRhc2suICBUaGlzIG1heSBvY2N1ciB3aGVuIG5vIG1vcmUgdGhyZWFkcyBvciBxdWV1ZSBzbG90cyBhcmUKKyAgICAgKiBhdmFpbGFibGUgYmVjYXVzZSB0aGVpciBib3VuZHMgd291bGQgYmUgZXhjZWVkZWQsIG9yIHVwb24KKyAgICAgKiBzaHV0ZG93biBvZiB0aGUgRXhlY3V0b3IuCisgICAgICoKKyAgICAgKiA8cD5JbiB0aGUgYWJzZW5jZSBvZiBvdGhlciBhbHRlcm5hdGl2ZXMsIHRoZSBtZXRob2QgbWF5IHRocm93CisgICAgICogYW4gdW5jaGVja2VkIHtAbGluayBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbn0sIHdoaWNoIHdpbGwgYmUKKyAgICAgKiBwcm9wYWdhdGVkIHRvIHRoZSBjYWxsZXIgb2Yge0Bjb2RlIGV4ZWN1dGV9LgorICAgICAqCisgICAgICogQHBhcmFtIHIgdGhlIHJ1bm5hYmxlIHRhc2sgcmVxdWVzdGVkIHRvIGJlIGV4ZWN1dGVkCisgICAgICogQHBhcmFtIGV4ZWN1dG9yIHRoZSBleGVjdXRvciBhdHRlbXB0aW5nIHRvIGV4ZWN1dGUgdGhpcyB0YXNrCisgICAgICogQHRocm93cyBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBubyByZW1lZHkKKyAgICAgKi8KKyAgICB2b2lkIHJlamVjdGVkRXhlY3V0aW9uKFJ1bm5hYmxlIHIsIFRocmVhZFBvb2xFeGVjdXRvciBleGVjdXRvcik7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvUnVubmFibGVGdXR1cmUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9SdW5uYWJsZUZ1dHVyZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3NDIxMWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvUnVubmFibGVGdXR1cmUuamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CisKKy8qKgorICogQSB7QGxpbmsgRnV0dXJlfSB0aGF0IGlzIHtAbGluayBSdW5uYWJsZX0uIFN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mCisgKiB0aGUgPHR0PnJ1bjwvdHQ+IG1ldGhvZCBjYXVzZXMgY29tcGxldGlvbiBvZiB0aGUgPHR0PkZ1dHVyZTwvdHQ+CisgKiBhbmQgYWxsb3dzIGFjY2VzcyB0byBpdHMgcmVzdWx0cy4KKyAqIEBzZWUgRnV0dXJlVGFzaworICogQHNlZSBFeGVjdXRvcgorICogQHNpbmNlIDEuNgorICogQGF1dGhvciBEb3VnIExlYQorICogQHBhcmFtIDxWPiBUaGUgcmVzdWx0IHR5cGUgcmV0dXJuZWQgYnkgdGhpcyBGdXR1cmUncyA8dHQ+Z2V0PC90dD4gbWV0aG9kCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUnVubmFibGVGdXR1cmU8Vj4gZXh0ZW5kcyBSdW5uYWJsZSwgRnV0dXJlPFY+IHsKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoaXMgRnV0dXJlIHRvIHRoZSByZXN1bHQgb2YgaXRzIGNvbXB1dGF0aW9uCisgICAgICogdW5sZXNzIGl0IGhhcyBiZWVuIGNhbmNlbGxlZC4KKyAgICAgKi8KKyAgICB2b2lkIHJ1bigpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L1J1bm5hYmxlU2NoZWR1bGVkRnV0dXJlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvUnVubmFibGVTY2hlZHVsZWRGdXR1cmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZThjYzMyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L1J1bm5hYmxlU2NoZWR1bGVkRnV0dXJlLmphdmEKQEAgLTAsMCArMSwyOSBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50OworCisvKioKKyAqIEEge0BsaW5rIFNjaGVkdWxlZEZ1dHVyZX0gdGhhdCBpcyB7QGxpbmsgUnVubmFibGV9LiBTdWNjZXNzZnVsCisgKiBleGVjdXRpb24gb2YgdGhlIDx0dD5ydW48L3R0PiBtZXRob2QgY2F1c2VzIGNvbXBsZXRpb24gb2YgdGhlCisgKiA8dHQ+RnV0dXJlPC90dD4gYW5kIGFsbG93cyBhY2Nlc3MgdG8gaXRzIHJlc3VsdHMuCisgKiBAc2VlIEZ1dHVyZVRhc2sKKyAqIEBzZWUgRXhlY3V0b3IKKyAqIEBzaW5jZSAxLjYKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqIEBwYXJhbSA8Vj4gVGhlIHJlc3VsdCB0eXBlIHJldHVybmVkIGJ5IHRoaXMgRnV0dXJlJ3MgPHR0PmdldDwvdHQ+IG1ldGhvZAorICovCitwdWJsaWMgaW50ZXJmYWNlIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlPFY+IGV4dGVuZHMgUnVubmFibGVGdXR1cmU8Vj4sIFNjaGVkdWxlZEZ1dHVyZTxWPiB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhIHBlcmlvZGljIHRhc2suIEEgcGVyaW9kaWMgdGFzayBtYXkKKyAgICAgKiByZS1ydW4gYWNjb3JkaW5nIHRvIHNvbWUgc2NoZWR1bGUuIEEgbm9uLXBlcmlvZGljIHRhc2sgY2FuIGJlCisgICAgICogcnVuIG9ubHkgb25jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIHRhc2sgaXMgcGVyaW9kaWMKKyAgICAgKi8KKyAgICBib29sZWFuIGlzUGVyaW9kaWMoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9TY2hlZHVsZWRFeGVjdXRvclNlcnZpY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9TY2hlZHVsZWRFeGVjdXRvclNlcnZpY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42Y2I0ZTI3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L1NjaGVkdWxlZEV4ZWN1dG9yU2VydmljZS5qYXZhCkBAIC0wLDAgKzEsMTU4IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLio7CitpbXBvcnQgamF2YS51dGlsLio7CisKKy8qKgorICogQW4ge0BsaW5rIEV4ZWN1dG9yU2VydmljZX0gdGhhdCBjYW4gc2NoZWR1bGUgY29tbWFuZHMgdG8gcnVuIGFmdGVyIGEgZ2l2ZW4KKyAqIGRlbGF5LCBvciB0byBleGVjdXRlIHBlcmlvZGljYWxseS4KKyAqCisgKiA8cD4gVGhlIDx0dD5zY2hlZHVsZTwvdHQ+IG1ldGhvZHMgY3JlYXRlIHRhc2tzIHdpdGggdmFyaW91cyBkZWxheXMKKyAqIGFuZCByZXR1cm4gYSB0YXNrIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIGNhbmNlbCBvciBjaGVjaworICogZXhlY3V0aW9uLiBUaGUgPHR0PnNjaGVkdWxlQXRGaXhlZFJhdGU8L3R0PiBhbmQKKyAqIDx0dD5zY2hlZHVsZVdpdGhGaXhlZERlbGF5PC90dD4gbWV0aG9kcyBjcmVhdGUgYW5kIGV4ZWN1dGUgdGFza3MKKyAqIHRoYXQgcnVuIHBlcmlvZGljYWxseSB1bnRpbCBjYW5jZWxsZWQuCisgKgorICogPHA+IENvbW1hbmRzIHN1Ym1pdHRlZCB1c2luZyB0aGUge0BsaW5rIEV4ZWN1dG9yI2V4ZWN1dGV9IGFuZAorICoge0BsaW5rIEV4ZWN1dG9yU2VydmljZX0gPHR0PnN1Ym1pdDwvdHQ+IG1ldGhvZHMgYXJlIHNjaGVkdWxlZCB3aXRoCisgKiBhIHJlcXVlc3RlZCBkZWxheSBvZiB6ZXJvLiBaZXJvIGFuZCBuZWdhdGl2ZSBkZWxheXMgKGJ1dCBub3QKKyAqIHBlcmlvZHMpIGFyZSBhbHNvIGFsbG93ZWQgaW4gPHR0PnNjaGVkdWxlPC90dD4gbWV0aG9kcywgYW5kIGFyZQorICogdHJlYXRlZCBhcyByZXF1ZXN0cyBmb3IgaW1tZWRpYXRlIGV4ZWN1dGlvbi4KKyAqCisgKiA8cD5BbGwgPHR0PnNjaGVkdWxlPC90dD4gbWV0aG9kcyBhY2NlcHQgPGVtPnJlbGF0aXZlPC9lbT4gZGVsYXlzIGFuZAorICogcGVyaW9kcyBhcyBhcmd1bWVudHMsIG5vdCBhYnNvbHV0ZSB0aW1lcyBvciBkYXRlcy4gSXQgaXMgYSBzaW1wbGUKKyAqIG1hdHRlciB0byB0cmFuc2Zvcm0gYW4gYWJzb2x1dGUgdGltZSByZXByZXNlbnRlZCBhcyBhIHtAbGluaworICogamF2YS51dGlsLkRhdGV9IHRvIHRoZSByZXF1aXJlZCBmb3JtLiBGb3IgZXhhbXBsZSwgdG8gc2NoZWR1bGUgYXQKKyAqIGEgY2VydGFpbiBmdXR1cmUgPHR0PmRhdGU8L3R0PiwgeW91IGNhbiB1c2U6IDx0dD5zY2hlZHVsZSh0YXNrLAorICogZGF0ZS5nZXRUaW1lKCkgLSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSwKKyAqIFRpbWVVbml0Lk1JTExJU0VDT05EUyk8L3R0Pi4gQmV3YXJlIGhvd2V2ZXIgdGhhdCBleHBpcmF0aW9uIG9mIGEKKyAqIHJlbGF0aXZlIGRlbGF5IG5lZWQgbm90IGNvaW5jaWRlIHdpdGggdGhlIGN1cnJlbnQgPHR0PkRhdGU8L3R0PiBhdAorICogd2hpY2ggdGhlIHRhc2sgaXMgZW5hYmxlZCBkdWUgdG8gbmV0d29yayB0aW1lIHN5bmNocm9uaXphdGlvbgorICogcHJvdG9jb2xzLCBjbG9jayBkcmlmdCwgb3Igb3RoZXIgZmFjdG9ycy4KKyAqCisgKiBUaGUge0BsaW5rIEV4ZWN1dG9yc30gY2xhc3MgcHJvdmlkZXMgY29udmVuaWVudCBmYWN0b3J5IG1ldGhvZHMgZm9yCisgKiB0aGUgU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlIGltcGxlbWVudGF0aW9ucyBwcm92aWRlZCBpbiB0aGlzIHBhY2thZ2UuCisgKgorICogPGgzPlVzYWdlIEV4YW1wbGU8L2gzPgorICoKKyAqIEhlcmUgaXMgYSBjbGFzcyB3aXRoIGEgbWV0aG9kIHRoYXQgc2V0cyB1cCBhIFNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZQorICogdG8gYmVlcCBldmVyeSB0ZW4gc2Vjb25kcyBmb3IgYW4gaG91cjoKKyAqCisgKiAgPHByZT4ge0Bjb2RlCisgKiBpbXBvcnQgc3RhdGljIGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0Lio7CisgKiBjbGFzcyBCZWVwZXJDb250cm9sIHsKKyAqICAgcHJpdmF0ZSBmaW5hbCBTY2hlZHVsZWRFeGVjdXRvclNlcnZpY2Ugc2NoZWR1bGVyID0KKyAqICAgICBFeGVjdXRvcnMubmV3U2NoZWR1bGVkVGhyZWFkUG9vbCgxKTsKKyAqCisgKiAgIHB1YmxpYyB2b2lkIGJlZXBGb3JBbkhvdXIoKSB7CisgKiAgICAgZmluYWwgUnVubmFibGUgYmVlcGVyID0gbmV3IFJ1bm5hYmxlKCkgeworICogICAgICAgcHVibGljIHZvaWQgcnVuKCkgeyBTeXN0ZW0ub3V0LnByaW50bG4oImJlZXAiKTsgfQorICogICAgIH07CisgKiAgICAgZmluYWwgU2NoZWR1bGVkRnV0dXJlPD8+IGJlZXBlckhhbmRsZSA9CisgKiAgICAgICBzY2hlZHVsZXIuc2NoZWR1bGVBdEZpeGVkUmF0ZShiZWVwZXIsIDEwLCAxMCwgU0VDT05EUyk7CisgKiAgICAgc2NoZWR1bGVyLnNjaGVkdWxlKG5ldyBSdW5uYWJsZSgpIHsKKyAqICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsgYmVlcGVySGFuZGxlLmNhbmNlbCh0cnVlKTsgfQorICogICAgIH0sIDYwICogNjAsIFNFQ09ORFMpOworICogICB9CisgKiB9fTwvcHJlPgorICoKKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqLworcHVibGljIGludGVyZmFjZSBTY2hlZHVsZWRFeGVjdXRvclNlcnZpY2UgZXh0ZW5kcyBFeGVjdXRvclNlcnZpY2UgeworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbmQgZXhlY3V0ZXMgYSBvbmUtc2hvdCBhY3Rpb24gdGhhdCBiZWNvbWVzIGVuYWJsZWQKKyAgICAgKiBhZnRlciB0aGUgZ2l2ZW4gZGVsYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29tbWFuZCB0aGUgdGFzayB0byBleGVjdXRlCisgICAgICogQHBhcmFtIGRlbGF5IHRoZSB0aW1lIGZyb20gbm93IHRvIGRlbGF5IGV4ZWN1dGlvbgorICAgICAqIEBwYXJhbSB1bml0IHRoZSB0aW1lIHVuaXQgb2YgdGhlIGRlbGF5IHBhcmFtZXRlcgorICAgICAqIEByZXR1cm4gYSBTY2hlZHVsZWRGdXR1cmUgcmVwcmVzZW50aW5nIHBlbmRpbmcgY29tcGxldGlvbiBvZgorICAgICAqICAgICAgICAgdGhlIHRhc2sgYW5kIHdob3NlIDx0dD5nZXQoKTwvdHQ+IG1ldGhvZCB3aWxsIHJldHVybgorICAgICAqICAgICAgICAgPHR0Pm51bGw8L3R0PiB1cG9uIGNvbXBsZXRpb24KKyAgICAgKiBAdGhyb3dzIFJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9uIGlmIHRoZSB0YXNrIGNhbm5vdCBiZQorICAgICAqICAgICAgICAgc2NoZWR1bGVkIGZvciBleGVjdXRpb24KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGNvbW1hbmQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBTY2hlZHVsZWRGdXR1cmU8Pz4gc2NoZWR1bGUoUnVubmFibGUgY29tbWFuZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgZGVsYXksIFRpbWVVbml0IHVuaXQpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbmQgZXhlY3V0ZXMgYSBTY2hlZHVsZWRGdXR1cmUgdGhhdCBiZWNvbWVzIGVuYWJsZWQgYWZ0ZXIgdGhlCisgICAgICogZ2l2ZW4gZGVsYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2FsbGFibGUgdGhlIGZ1bmN0aW9uIHRvIGV4ZWN1dGUKKyAgICAgKiBAcGFyYW0gZGVsYXkgdGhlIHRpbWUgZnJvbSBub3cgdG8gZGVsYXkgZXhlY3V0aW9uCisgICAgICogQHBhcmFtIHVuaXQgdGhlIHRpbWUgdW5pdCBvZiB0aGUgZGVsYXkgcGFyYW1ldGVyCisgICAgICogQHJldHVybiBhIFNjaGVkdWxlZEZ1dHVyZSB0aGF0IGNhbiBiZSB1c2VkIHRvIGV4dHJhY3QgcmVzdWx0IG9yIGNhbmNlbAorICAgICAqIEB0aHJvd3MgUmVqZWN0ZWRFeGVjdXRpb25FeGNlcHRpb24gaWYgdGhlIHRhc2sgY2Fubm90IGJlCisgICAgICogICAgICAgICBzY2hlZHVsZWQgZm9yIGV4ZWN1dGlvbgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgY2FsbGFibGUgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyA8Vj4gU2NoZWR1bGVkRnV0dXJlPFY+IHNjaGVkdWxlKENhbGxhYmxlPFY+IGNhbGxhYmxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgZGVsYXksIFRpbWVVbml0IHVuaXQpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbmQgZXhlY3V0ZXMgYSBwZXJpb2RpYyBhY3Rpb24gdGhhdCBiZWNvbWVzIGVuYWJsZWQgZmlyc3QKKyAgICAgKiBhZnRlciB0aGUgZ2l2ZW4gaW5pdGlhbCBkZWxheSwgYW5kIHN1YnNlcXVlbnRseSB3aXRoIHRoZSBnaXZlbgorICAgICAqIHBlcmlvZDsgdGhhdCBpcyBleGVjdXRpb25zIHdpbGwgY29tbWVuY2UgYWZ0ZXIKKyAgICAgKiA8dHQ+aW5pdGlhbERlbGF5PC90dD4gdGhlbiA8dHQ+aW5pdGlhbERlbGF5K3BlcmlvZDwvdHQ+LCB0aGVuCisgICAgICogPHR0PmluaXRpYWxEZWxheSArIDIgKiBwZXJpb2Q8L3R0PiwgYW5kIHNvIG9uLgorICAgICAqIElmIGFueSBleGVjdXRpb24gb2YgdGhlIHRhc2sKKyAgICAgKiBlbmNvdW50ZXJzIGFuIGV4Y2VwdGlvbiwgc3Vic2VxdWVudCBleGVjdXRpb25zIGFyZSBzdXBwcmVzc2VkLgorICAgICAqIE90aGVyd2lzZSwgdGhlIHRhc2sgd2lsbCBvbmx5IHRlcm1pbmF0ZSB2aWEgY2FuY2VsbGF0aW9uIG9yCisgICAgICogdGVybWluYXRpb24gb2YgdGhlIGV4ZWN1dG9yLiAgSWYgYW55IGV4ZWN1dGlvbiBvZiB0aGlzIHRhc2sKKyAgICAgKiB0YWtlcyBsb25nZXIgdGhhbiBpdHMgcGVyaW9kLCB0aGVuIHN1YnNlcXVlbnQgZXhlY3V0aW9ucworICAgICAqIG1heSBzdGFydCBsYXRlLCBidXQgd2lsbCBub3QgY29uY3VycmVudGx5IGV4ZWN1dGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29tbWFuZCB0aGUgdGFzayB0byBleGVjdXRlCisgICAgICogQHBhcmFtIGluaXRpYWxEZWxheSB0aGUgdGltZSB0byBkZWxheSBmaXJzdCBleGVjdXRpb24KKyAgICAgKiBAcGFyYW0gcGVyaW9kIHRoZSBwZXJpb2QgYmV0d2VlbiBzdWNjZXNzaXZlIGV4ZWN1dGlvbnMKKyAgICAgKiBAcGFyYW0gdW5pdCB0aGUgdGltZSB1bml0IG9mIHRoZSBpbml0aWFsRGVsYXkgYW5kIHBlcmlvZCBwYXJhbWV0ZXJzCisgICAgICogQHJldHVybiBhIFNjaGVkdWxlZEZ1dHVyZSByZXByZXNlbnRpbmcgcGVuZGluZyBjb21wbGV0aW9uIG9mCisgICAgICogICAgICAgICB0aGUgdGFzaywgYW5kIHdob3NlIDx0dD5nZXQoKTwvdHQ+IG1ldGhvZCB3aWxsIHRocm93IGFuCisgICAgICogICAgICAgICBleGNlcHRpb24gdXBvbiBjYW5jZWxsYXRpb24KKyAgICAgKiBAdGhyb3dzIFJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9uIGlmIHRoZSB0YXNrIGNhbm5vdCBiZQorICAgICAqICAgICAgICAgc2NoZWR1bGVkIGZvciBleGVjdXRpb24KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGNvbW1hbmQgaXMgbnVsbAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHBlcmlvZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gemVybworICAgICAqLworICAgIHB1YmxpYyBTY2hlZHVsZWRGdXR1cmU8Pz4gc2NoZWR1bGVBdEZpeGVkUmF0ZShSdW5uYWJsZSBjb21tYW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb25nIGluaXRpYWxEZWxheSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBwZXJpb2QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVVbml0IHVuaXQpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbmQgZXhlY3V0ZXMgYSBwZXJpb2RpYyBhY3Rpb24gdGhhdCBiZWNvbWVzIGVuYWJsZWQgZmlyc3QKKyAgICAgKiBhZnRlciB0aGUgZ2l2ZW4gaW5pdGlhbCBkZWxheSwgYW5kIHN1YnNlcXVlbnRseSB3aXRoIHRoZQorICAgICAqIGdpdmVuIGRlbGF5IGJldHdlZW4gdGhlIHRlcm1pbmF0aW9uIG9mIG9uZSBleGVjdXRpb24gYW5kIHRoZQorICAgICAqIGNvbW1lbmNlbWVudCBvZiB0aGUgbmV4dC4gIElmIGFueSBleGVjdXRpb24gb2YgdGhlIHRhc2sKKyAgICAgKiBlbmNvdW50ZXJzIGFuIGV4Y2VwdGlvbiwgc3Vic2VxdWVudCBleGVjdXRpb25zIGFyZSBzdXBwcmVzc2VkLgorICAgICAqIE90aGVyd2lzZSwgdGhlIHRhc2sgd2lsbCBvbmx5IHRlcm1pbmF0ZSB2aWEgY2FuY2VsbGF0aW9uIG9yCisgICAgICogdGVybWluYXRpb24gb2YgdGhlIGV4ZWN1dG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbW1hbmQgdGhlIHRhc2sgdG8gZXhlY3V0ZQorICAgICAqIEBwYXJhbSBpbml0aWFsRGVsYXkgdGhlIHRpbWUgdG8gZGVsYXkgZmlyc3QgZXhlY3V0aW9uCisgICAgICogQHBhcmFtIGRlbGF5IHRoZSBkZWxheSBiZXR3ZWVuIHRoZSB0ZXJtaW5hdGlvbiBvZiBvbmUKKyAgICAgKiBleGVjdXRpb24gYW5kIHRoZSBjb21tZW5jZW1lbnQgb2YgdGhlIG5leHQKKyAgICAgKiBAcGFyYW0gdW5pdCB0aGUgdGltZSB1bml0IG9mIHRoZSBpbml0aWFsRGVsYXkgYW5kIGRlbGF5IHBhcmFtZXRlcnMKKyAgICAgKiBAcmV0dXJuIGEgU2NoZWR1bGVkRnV0dXJlIHJlcHJlc2VudGluZyBwZW5kaW5nIGNvbXBsZXRpb24gb2YKKyAgICAgKiAgICAgICAgIHRoZSB0YXNrLCBhbmQgd2hvc2UgPHR0PmdldCgpPC90dD4gbWV0aG9kIHdpbGwgdGhyb3cgYW4KKyAgICAgKiAgICAgICAgIGV4Y2VwdGlvbiB1cG9uIGNhbmNlbGxhdGlvbgorICAgICAqIEB0aHJvd3MgUmVqZWN0ZWRFeGVjdXRpb25FeGNlcHRpb24gaWYgdGhlIHRhc2sgY2Fubm90IGJlCisgICAgICogICAgICAgICBzY2hlZHVsZWQgZm9yIGV4ZWN1dGlvbgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgY29tbWFuZCBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgZGVsYXkgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8KKyAgICAgKi8KKyAgICBwdWJsaWMgU2NoZWR1bGVkRnV0dXJlPD8+IHNjaGVkdWxlV2l0aEZpeGVkRGVsYXkoUnVubmFibGUgY29tbWFuZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBpbml0aWFsRGVsYXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgZGVsYXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVVbml0IHVuaXQpOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvU2NoZWR1bGVkRnV0dXJlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvU2NoZWR1bGVkRnV0dXJlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjM5ZDY4MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9TY2hlZHVsZWRGdXR1cmUuamF2YQpAQCAtMCwwICsxLDE5IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CisKKy8qKgorICogQSBkZWxheWVkIHJlc3VsdC1iZWFyaW5nIGFjdGlvbiB0aGF0IGNhbiBiZSBjYW5jZWxsZWQuCisgKiBVc3VhbGx5IGEgc2NoZWR1bGVkIGZ1dHVyZSBpcyB0aGUgcmVzdWx0IG9mIHNjaGVkdWxpbmcKKyAqIGEgdGFzayB3aXRoIGEge0BsaW5rIFNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZX0uCisgKgorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICogQHBhcmFtIDxWPiBUaGUgcmVzdWx0IHR5cGUgcmV0dXJuZWQgYnkgdGhpcyBGdXR1cmUKKyAqLworcHVibGljIGludGVyZmFjZSBTY2hlZHVsZWRGdXR1cmU8Vj4gZXh0ZW5kcyBEZWxheWVkLCBGdXR1cmU8Vj4geworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L1NjaGVkdWxlZFRocmVhZFBvb2xFeGVjdXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L1NjaGVkdWxlZFRocmVhZFBvb2xFeGVjdXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyZWFlZGYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvU2NoZWR1bGVkVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmEKQEAgLTAsMCArMSwxMjQ5IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLio7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3MuKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKKworLy8gQkVHSU4gYW5kcm9pZC1ub3RlCisvLyBPbWl0IGNsYXNzLWxldmVsIGRvY3Mgb24gc2V0UmVtb3ZlT25DYW5jZWxQb2xpY3koKQorLy8gRU5EIGFuZHJvaWQtbm90ZQorCisvKioKKyAqIEEge0BsaW5rIFRocmVhZFBvb2xFeGVjdXRvcn0gdGhhdCBjYW4gYWRkaXRpb25hbGx5IHNjaGVkdWxlCisgKiBjb21tYW5kcyB0byBydW4gYWZ0ZXIgYSBnaXZlbiBkZWxheSwgb3IgdG8gZXhlY3V0ZQorICogcGVyaW9kaWNhbGx5LiBUaGlzIGNsYXNzIGlzIHByZWZlcmFibGUgdG8ge0BsaW5rIGphdmEudXRpbC5UaW1lcn0KKyAqIHdoZW4gbXVsdGlwbGUgd29ya2VyIHRocmVhZHMgYXJlIG5lZWRlZCwgb3Igd2hlbiB0aGUgYWRkaXRpb25hbAorICogZmxleGliaWxpdHkgb3IgY2FwYWJpbGl0aWVzIG9mIHtAbGluayBUaHJlYWRQb29sRXhlY3V0b3J9ICh3aGljaAorICogdGhpcyBjbGFzcyBleHRlbmRzKSBhcmUgcmVxdWlyZWQuCisgKgorICogPHA+RGVsYXllZCB0YXNrcyBleGVjdXRlIG5vIHNvb25lciB0aGFuIHRoZXkgYXJlIGVuYWJsZWQsIGJ1dAorICogd2l0aG91dCBhbnkgcmVhbC10aW1lIGd1YXJhbnRlZXMgYWJvdXQgd2hlbiwgYWZ0ZXIgdGhleSBhcmUKKyAqIGVuYWJsZWQsIHRoZXkgd2lsbCBjb21tZW5jZS4gVGFza3Mgc2NoZWR1bGVkIGZvciBleGFjdGx5IHRoZSBzYW1lCisgKiBleGVjdXRpb24gdGltZSBhcmUgZW5hYmxlZCBpbiBmaXJzdC1pbi1maXJzdC1vdXQgKEZJRk8pIG9yZGVyIG9mCisgKiBzdWJtaXNzaW9uLgorICoKKyAqIDxwPldoZW4gYSBzdWJtaXR0ZWQgdGFzayBpcyBjYW5jZWxsZWQgYmVmb3JlIGl0IGlzIHJ1biwgZXhlY3V0aW9uCisgKiBpcyBzdXBwcmVzc2VkLiBTdWNoIGEgY2FuY2VsbGVkIHRhc2sgaXMgbm90CisgKiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQgZnJvbSB0aGUgd29yayBxdWV1ZSB1bnRpbCBpdHMgZGVsYXkKKyAqIGVsYXBzZXMuIFdoaWxlIHRoaXMgZW5hYmxlcyBmdXJ0aGVyIGluc3BlY3Rpb24gYW5kIG1vbml0b3JpbmcsIGl0CisgKiBtYXkgYWxzbyBjYXVzZSB1bmJvdW5kZWQgcmV0ZW50aW9uIG9mIGNhbmNlbGxlZCB0YXNrcy4KKyAqCisgKiA8cD5TdWNjZXNzaXZlIGV4ZWN1dGlvbnMgb2YgYSB0YXNrIHNjaGVkdWxlZCB2aWEKKyAqIHtAY29kZSBzY2hlZHVsZUF0Rml4ZWRSYXRlfSBvcgorICoge0Bjb2RlIHNjaGVkdWxlV2l0aEZpeGVkRGVsYXl9IGRvIG5vdCBvdmVybGFwLiBXaGlsZSBkaWZmZXJlbnQKKyAqIGV4ZWN1dGlvbnMgbWF5IGJlIHBlcmZvcm1lZCBieSBkaWZmZXJlbnQgdGhyZWFkcywgdGhlIGVmZmVjdHMgb2YKKyAqIHByaW9yIGV4ZWN1dGlvbnMgPGEKKyAqIGhyZWY9InBhY2thZ2Utc3VtbWFyeS5odG1sI01lbW9yeVZpc2liaWxpdHkiPjxpPmhhcHBlbi1iZWZvcmU8L2k+PC9hPgorICogdGhvc2Ugb2Ygc3Vic2VxdWVudCBvbmVzLgorICoKKyAqIDxwPldoaWxlIHRoaXMgY2xhc3MgaW5oZXJpdHMgZnJvbSB7QGxpbmsgVGhyZWFkUG9vbEV4ZWN1dG9yfSwgYSBmZXcKKyAqIG9mIHRoZSBpbmhlcml0ZWQgdHVuaW5nIG1ldGhvZHMgYXJlIG5vdCB1c2VmdWwgZm9yIGl0LiBJbgorICogcGFydGljdWxhciwgYmVjYXVzZSBpdCBhY3RzIGFzIGEgZml4ZWQtc2l6ZWQgcG9vbCB1c2luZworICoge0Bjb2RlIGNvcmVQb29sU2l6ZX0gdGhyZWFkcyBhbmQgYW4gdW5ib3VuZGVkIHF1ZXVlLCBhZGp1c3RtZW50cworICogdG8ge0Bjb2RlIG1heGltdW1Qb29sU2l6ZX0gaGF2ZSBubyB1c2VmdWwgZWZmZWN0LiBBZGRpdGlvbmFsbHksIGl0CisgKiBpcyBhbG1vc3QgbmV2ZXIgYSBnb29kIGlkZWEgdG8gc2V0IHtAY29kZSBjb3JlUG9vbFNpemV9IHRvIHplcm8gb3IKKyAqIHVzZSB7QGNvZGUgYWxsb3dDb3JlVGhyZWFkVGltZU91dH0gYmVjYXVzZSB0aGlzIG1heSBsZWF2ZSB0aGUgcG9vbAorICogd2l0aG91dCB0aHJlYWRzIHRvIGhhbmRsZSB0YXNrcyBvbmNlIHRoZXkgYmVjb21lIGVsaWdpYmxlIHRvIHJ1bi4KKyAqCisgKiA8cD48Yj5FeHRlbnNpb24gbm90ZXM6PC9iPiBUaGlzIGNsYXNzIG92ZXJyaWRlcyB0aGUKKyAqIHtAbGluayBUaHJlYWRQb29sRXhlY3V0b3IjZXhlY3V0ZSBleGVjdXRlfSBhbmQKKyAqIHtAbGluayBBYnN0cmFjdEV4ZWN1dG9yU2VydmljZSNzdWJtaXQoUnVubmFibGUpIHN1Ym1pdH0KKyAqIG1ldGhvZHMgdG8gZ2VuZXJhdGUgaW50ZXJuYWwge0BsaW5rIFNjaGVkdWxlZEZ1dHVyZX0gb2JqZWN0cyB0bworICogY29udHJvbCBwZXItdGFzayBkZWxheXMgYW5kIHNjaGVkdWxpbmcuICBUbyBwcmVzZXJ2ZQorICogZnVuY3Rpb25hbGl0eSwgYW55IGZ1cnRoZXIgb3ZlcnJpZGVzIG9mIHRoZXNlIG1ldGhvZHMgaW4KKyAqIHN1YmNsYXNzZXMgbXVzdCBpbnZva2Ugc3VwZXJjbGFzcyB2ZXJzaW9ucywgd2hpY2ggZWZmZWN0aXZlbHkKKyAqIGRpc2FibGVzIGFkZGl0aW9uYWwgdGFzayBjdXN0b21pemF0aW9uLiAgSG93ZXZlciwgdGhpcyBjbGFzcworICogcHJvdmlkZXMgYWx0ZXJuYXRpdmUgcHJvdGVjdGVkIGV4dGVuc2lvbiBtZXRob2QKKyAqIHtAY29kZSBkZWNvcmF0ZVRhc2t9IChvbmUgdmVyc2lvbiBlYWNoIGZvciB7QGNvZGUgUnVubmFibGV9IGFuZAorICoge0Bjb2RlIENhbGxhYmxlfSkgdGhhdCBjYW4gYmUgdXNlZCB0byBjdXN0b21pemUgdGhlIGNvbmNyZXRlIHRhc2sKKyAqIHR5cGVzIHVzZWQgdG8gZXhlY3V0ZSBjb21tYW5kcyBlbnRlcmVkIHZpYSB7QGNvZGUgZXhlY3V0ZX0sCisgKiB7QGNvZGUgc3VibWl0fSwge0Bjb2RlIHNjaGVkdWxlfSwge0Bjb2RlIHNjaGVkdWxlQXRGaXhlZFJhdGV9LAorICogYW5kIHtAY29kZSBzY2hlZHVsZVdpdGhGaXhlZERlbGF5fS4gIEJ5IGRlZmF1bHQsIGEKKyAqIHtAY29kZSBTY2hlZHVsZWRUaHJlYWRQb29sRXhlY3V0b3J9IHVzZXMgYSB0YXNrIHR5cGUgZXh0ZW5kaW5nCisgKiB7QGxpbmsgRnV0dXJlVGFza30uIEhvd2V2ZXIsIHRoaXMgbWF5IGJlIG1vZGlmaWVkIG9yIHJlcGxhY2VkIHVzaW5nCisgKiBzdWJjbGFzc2VzIG9mIHRoZSBmb3JtOgorICoKKyAqICA8cHJlPiB7QGNvZGUKKyAqIHB1YmxpYyBjbGFzcyBDdXN0b21TY2hlZHVsZWRFeGVjdXRvciBleHRlbmRzIFNjaGVkdWxlZFRocmVhZFBvb2xFeGVjdXRvciB7CisgKgorICogICBzdGF0aWMgY2xhc3MgQ3VzdG9tVGFzazxWPiBpbXBsZW1lbnRzIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlPFY+IHsgLi4uIH0KKyAqCisgKiAgIHByb3RlY3RlZCA8Vj4gUnVubmFibGVTY2hlZHVsZWRGdXR1cmU8Vj4gZGVjb3JhdGVUYXNrKAorICogICAgICAgICAgICAgICAgUnVubmFibGUgciwgUnVubmFibGVTY2hlZHVsZWRGdXR1cmU8Vj4gdGFzaykgeworICogICAgICAgcmV0dXJuIG5ldyBDdXN0b21UYXNrPFY+KHIsIHRhc2spOworICogICB9CisgKgorICogICBwcm90ZWN0ZWQgPFY+IFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlPFY+IGRlY29yYXRlVGFzaygKKyAqICAgICAgICAgICAgICAgIENhbGxhYmxlPFY+IGMsIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlPFY+IHRhc2spIHsKKyAqICAgICAgIHJldHVybiBuZXcgQ3VzdG9tVGFzazxWPihjLCB0YXNrKTsKKyAqICAgfQorICogICAvLyAuLi4gYWRkIGNvbnN0cnVjdG9ycywgZXRjLgorICogfX08L3ByZT4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKi8KK3B1YmxpYyBjbGFzcyBTY2hlZHVsZWRUaHJlYWRQb29sRXhlY3V0b3IKKyAgICAgICAgZXh0ZW5kcyBUaHJlYWRQb29sRXhlY3V0b3IKKyAgICAgICAgaW1wbGVtZW50cyBTY2hlZHVsZWRFeGVjdXRvclNlcnZpY2UgeworCisgICAgLyoKKyAgICAgKiBUaGlzIGNsYXNzIHNwZWNpYWxpemVzIFRocmVhZFBvb2xFeGVjdXRvciBpbXBsZW1lbnRhdGlvbiBieQorICAgICAqCisgICAgICogMS4gVXNpbmcgYSBjdXN0b20gdGFzayB0eXBlLCBTY2hlZHVsZWRGdXR1cmVUYXNrIGZvcgorICAgICAqICAgIHRhc2tzLCBldmVuIHRob3NlIHRoYXQgZG9uJ3QgcmVxdWlyZSBzY2hlZHVsaW5nIChpLmUuLAorICAgICAqICAgIHRob3NlIHN1Ym1pdHRlZCB1c2luZyBFeGVjdXRvclNlcnZpY2UgZXhlY3V0ZSwgbm90CisgICAgICogICAgU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlIG1ldGhvZHMpIHdoaWNoIGFyZSB0cmVhdGVkIGFzCisgICAgICogICAgZGVsYXllZCB0YXNrcyB3aXRoIGEgZGVsYXkgb2YgemVyby4KKyAgICAgKgorICAgICAqIDIuIFVzaW5nIGEgY3VzdG9tIHF1ZXVlIChEZWxheWVkV29ya1F1ZXVlKSwgYSB2YXJpYW50IG9mCisgICAgICogICAgdW5ib3VuZGVkIERlbGF5UXVldWUuIFRoZSBsYWNrIG9mIGNhcGFjaXR5IGNvbnN0cmFpbnQgYW5kCisgICAgICogICAgdGhlIGZhY3QgdGhhdCBjb3JlUG9vbFNpemUgYW5kIG1heGltdW1Qb29sU2l6ZSBhcmUKKyAgICAgKiAgICBlZmZlY3RpdmVseSBpZGVudGljYWwgc2ltcGxpZmllcyBzb21lIGV4ZWN1dGlvbiBtZWNoYW5pY3MKKyAgICAgKiAgICAoc2VlIGRlbGF5ZWRFeGVjdXRlKSBjb21wYXJlZCB0byBUaHJlYWRQb29sRXhlY3V0b3IuCisgICAgICoKKyAgICAgKiAzLiBTdXBwb3J0aW5nIG9wdGlvbmFsIHJ1bi1hZnRlci1zaHV0ZG93biBwYXJhbWV0ZXJzLCB3aGljaAorICAgICAqICAgIGxlYWRzIHRvIG92ZXJyaWRlcyBvZiBzaHV0ZG93biBtZXRob2RzIHRvIHJlbW92ZSBhbmQgY2FuY2VsCisgICAgICogICAgdGFza3MgdGhhdCBzaG91bGQgTk9UIGJlIHJ1biBhZnRlciBzaHV0ZG93biwgYXMgd2VsbCBhcworICAgICAqICAgIGRpZmZlcmVudCByZWNoZWNrIGxvZ2ljIHdoZW4gdGFzayAocmUpc3VibWlzc2lvbiBvdmVybGFwcworICAgICAqICAgIHdpdGggYSBzaHV0ZG93bi4KKyAgICAgKgorICAgICAqIDQuIFRhc2sgZGVjb3JhdGlvbiBtZXRob2RzIHRvIGFsbG93IGludGVyY2VwdGlvbiBhbmQKKyAgICAgKiAgICBpbnN0cnVtZW50YXRpb24sIHdoaWNoIGFyZSBuZWVkZWQgYmVjYXVzZSBzdWJjbGFzc2VzIGNhbm5vdAorICAgICAqICAgIG90aGVyd2lzZSBvdmVycmlkZSBzdWJtaXQgbWV0aG9kcyB0byBnZXQgdGhpcyBlZmZlY3QuIFRoZXNlCisgICAgICogICAgZG9uJ3QgaGF2ZSBhbnkgaW1wYWN0IG9uIHBvb2wgY29udHJvbCBsb2dpYyB0aG91Z2guCisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBGYWxzZSBpZiBzaG91bGQgY2FuY2VsL3N1cHByZXNzIHBlcmlvZGljIHRhc2tzIG9uIHNodXRkb3duLgorICAgICAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiBjb250aW51ZUV4aXN0aW5nUGVyaW9kaWNUYXNrc0FmdGVyU2h1dGRvd247CisKKyAgICAvKioKKyAgICAgKiBGYWxzZSBpZiBzaG91bGQgY2FuY2VsIG5vbi1wZXJpb2RpYyB0YXNrcyBvbiBzaHV0ZG93bi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvbGF0aWxlIGJvb2xlYW4gZXhlY3V0ZUV4aXN0aW5nRGVsYXllZFRhc2tzQWZ0ZXJTaHV0ZG93biA9IHRydWU7CisKKyAgICAvKioKKyAgICAgKiBUcnVlIGlmIFNjaGVkdWxlZEZ1dHVyZVRhc2suY2FuY2VsIHNob3VsZCByZW1vdmUgZnJvbSBxdWV1ZQorICAgICAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiByZW1vdmVPbkNhbmNlbCA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogU2VxdWVuY2UgbnVtYmVyIHRvIGJyZWFrIHNjaGVkdWxpbmcgdGllcywgYW5kIGluIHR1cm4gdG8KKyAgICAgKiBndWFyYW50ZWUgRklGTyBvcmRlciBhbW9uZyB0aWVkIGVudHJpZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQXRvbWljTG9uZyBzZXF1ZW5jZXIgPSBuZXcgQXRvbWljTG9uZygwKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgY3VycmVudCBuYW5vc2Vjb25kIHRpbWUuCisgICAgICovCisgICAgZmluYWwgbG9uZyBub3coKSB7CisgICAgICAgIHJldHVybiBTeXN0ZW0ubmFub1RpbWUoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIFNjaGVkdWxlZEZ1dHVyZVRhc2s8Vj4KKyAgICAgICAgICAgIGV4dGVuZHMgRnV0dXJlVGFzazxWPiBpbXBsZW1lbnRzIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlPFY+IHsKKworICAgICAgICAvKiogU2VxdWVuY2UgbnVtYmVyIHRvIGJyZWFrIHRpZXMgRklGTyAqLworICAgICAgICBwcml2YXRlIGZpbmFsIGxvbmcgc2VxdWVuY2VOdW1iZXI7CisKKyAgICAgICAgLyoqIFRoZSB0aW1lIHRoZSB0YXNrIGlzIGVuYWJsZWQgdG8gZXhlY3V0ZSBpbiBuYW5vVGltZSB1bml0cyAqLworICAgICAgICBwcml2YXRlIGxvbmcgdGltZTsKKworICAgICAgICAvKioKKyAgICAgICAgICogUGVyaW9kIGluIG5hbm9zZWNvbmRzIGZvciByZXBlYXRpbmcgdGFza3MuICBBIHBvc2l0aXZlCisgICAgICAgICAqIHZhbHVlIGluZGljYXRlcyBmaXhlZC1yYXRlIGV4ZWN1dGlvbi4gIEEgbmVnYXRpdmUgdmFsdWUKKyAgICAgICAgICogaW5kaWNhdGVzIGZpeGVkLWRlbGF5IGV4ZWN1dGlvbi4gIEEgdmFsdWUgb2YgMCBpbmRpY2F0ZXMgYQorICAgICAgICAgKiBub24tcmVwZWF0aW5nIHRhc2suCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGZpbmFsIGxvbmcgcGVyaW9kOworCisgICAgICAgIC8qKiBUaGUgYWN0dWFsIHRhc2sgdG8gYmUgcmUtZW5xdWV1ZWQgYnkgcmVFeGVjdXRlUGVyaW9kaWMgKi8KKyAgICAgICAgUnVubmFibGVTY2hlZHVsZWRGdXR1cmU8Vj4gb3V0ZXJUYXNrID0gdGhpczsKKworICAgICAgICAvKioKKyAgICAgICAgICogSW5kZXggaW50byBkZWxheSBxdWV1ZSwgdG8gc3VwcG9ydCBmYXN0ZXIgY2FuY2VsbGF0aW9uLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IGhlYXBJbmRleDsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBhIG9uZS1zaG90IGFjdGlvbiB3aXRoIGdpdmVuIG5hbm9UaW1lLWJhc2VkIHRyaWdnZXIgdGltZS4KKyAgICAgICAgICovCisgICAgICAgIFNjaGVkdWxlZEZ1dHVyZVRhc2soUnVubmFibGUgciwgViByZXN1bHQsIGxvbmcgbnMpIHsKKyAgICAgICAgICAgIHN1cGVyKHIsIHJlc3VsdCk7CisgICAgICAgICAgICB0aGlzLnRpbWUgPSBuczsKKyAgICAgICAgICAgIHRoaXMucGVyaW9kID0gMDsKKyAgICAgICAgICAgIHRoaXMuc2VxdWVuY2VOdW1iZXIgPSBzZXF1ZW5jZXIuZ2V0QW5kSW5jcmVtZW50KCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBhIHBlcmlvZGljIGFjdGlvbiB3aXRoIGdpdmVuIG5hbm8gdGltZSBhbmQgcGVyaW9kLgorICAgICAgICAgKi8KKyAgICAgICAgU2NoZWR1bGVkRnV0dXJlVGFzayhSdW5uYWJsZSByLCBWIHJlc3VsdCwgbG9uZyBucywgbG9uZyBwZXJpb2QpIHsKKyAgICAgICAgICAgIHN1cGVyKHIsIHJlc3VsdCk7CisgICAgICAgICAgICB0aGlzLnRpbWUgPSBuczsKKyAgICAgICAgICAgIHRoaXMucGVyaW9kID0gcGVyaW9kOworICAgICAgICAgICAgdGhpcy5zZXF1ZW5jZU51bWJlciA9IHNlcXVlbmNlci5nZXRBbmRJbmNyZW1lbnQoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDcmVhdGVzIGEgb25lLXNob3QgYWN0aW9uIHdpdGggZ2l2ZW4gbmFub1RpbWUtYmFzZWQgdHJpZ2dlci4KKyAgICAgICAgICovCisgICAgICAgIFNjaGVkdWxlZEZ1dHVyZVRhc2soQ2FsbGFibGU8Vj4gY2FsbGFibGUsIGxvbmcgbnMpIHsKKyAgICAgICAgICAgIHN1cGVyKGNhbGxhYmxlKTsKKyAgICAgICAgICAgIHRoaXMudGltZSA9IG5zOworICAgICAgICAgICAgdGhpcy5wZXJpb2QgPSAwOworICAgICAgICAgICAgdGhpcy5zZXF1ZW5jZU51bWJlciA9IHNlcXVlbmNlci5nZXRBbmRJbmNyZW1lbnQoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBsb25nIGdldERlbGF5KFRpbWVVbml0IHVuaXQpIHsKKyAgICAgICAgICAgIHJldHVybiB1bml0LmNvbnZlcnQodGltZSAtIG5vdygpLCBUaW1lVW5pdC5OQU5PU0VDT05EUyk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhEZWxheWVkIG90aGVyKSB7CisgICAgICAgICAgICBpZiAob3RoZXIgPT0gdGhpcykgLy8gY29tcGFyZSB6ZXJvIE9OTFkgaWYgc2FtZSBvYmplY3QKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIFNjaGVkdWxlZEZ1dHVyZVRhc2spIHsKKyAgICAgICAgICAgICAgICBTY2hlZHVsZWRGdXR1cmVUYXNrPD8+IHggPSAoU2NoZWR1bGVkRnV0dXJlVGFzazw/PilvdGhlcjsKKyAgICAgICAgICAgICAgICBsb25nIGRpZmYgPSB0aW1lIC0geC50aW1lOworICAgICAgICAgICAgICAgIGlmIChkaWZmIDwgMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRpZmYgPiAwKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICAgICAgICBlbHNlIGlmIChzZXF1ZW5jZU51bWJlciA8IHguc2VxdWVuY2VOdW1iZXIpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbG9uZyBkID0gKGdldERlbGF5KFRpbWVVbml0Lk5BTk9TRUNPTkRTKSAtCisgICAgICAgICAgICAgICAgICAgICAgb3RoZXIuZ2V0RGVsYXkoVGltZVVuaXQuTkFOT1NFQ09ORFMpKTsKKyAgICAgICAgICAgIHJldHVybiAoZCA9PSAwKSA/IDAgOiAoKGQgPCAwKSA/IC0xIDogMSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYSBwZXJpb2RpYyAobm90IGEgb25lLXNob3QpIGFjdGlvbi4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0cnVlIGlmIHBlcmlvZGljCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1BlcmlvZGljKCkgeworICAgICAgICAgICAgcmV0dXJuIHBlcmlvZCAhPSAwOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNldHMgdGhlIG5leHQgdGltZSB0byBydW4gZm9yIGEgcGVyaW9kaWMgdGFzay4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgdm9pZCBzZXROZXh0UnVuVGltZSgpIHsKKyAgICAgICAgICAgIGxvbmcgcCA9IHBlcmlvZDsKKyAgICAgICAgICAgIGlmIChwID4gMCkKKyAgICAgICAgICAgICAgICB0aW1lICs9IHA7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgdGltZSA9IHRyaWdnZXJUaW1lKC1wKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGNhbmNlbChib29sZWFuIG1heUludGVycnVwdElmUnVubmluZykgeworICAgICAgICAgICAgYm9vbGVhbiBjYW5jZWxsZWQgPSBzdXBlci5jYW5jZWwobWF5SW50ZXJydXB0SWZSdW5uaW5nKTsKKyAgICAgICAgICAgIGlmIChjYW5jZWxsZWQgJiYgcmVtb3ZlT25DYW5jZWwgJiYgaGVhcEluZGV4ID49IDApCisgICAgICAgICAgICAgICAgcmVtb3ZlKHRoaXMpOworICAgICAgICAgICAgcmV0dXJuIGNhbmNlbGxlZDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBPdmVycmlkZXMgRnV0dXJlVGFzayB2ZXJzaW9uIHNvIGFzIHRvIHJlc2V0L3JlcXVldWUgaWYgcGVyaW9kaWMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICBib29sZWFuIHBlcmlvZGljID0gaXNQZXJpb2RpYygpOworICAgICAgICAgICAgaWYgKCFjYW5SdW5JbkN1cnJlbnRSdW5TdGF0ZShwZXJpb2RpYykpCisgICAgICAgICAgICAgICAgY2FuY2VsKGZhbHNlKTsKKyAgICAgICAgICAgIGVsc2UgaWYgKCFwZXJpb2RpYykKKyAgICAgICAgICAgICAgICBTY2hlZHVsZWRGdXR1cmVUYXNrLnN1cGVyLnJ1bigpOworICAgICAgICAgICAgZWxzZSBpZiAoU2NoZWR1bGVkRnV0dXJlVGFzay5zdXBlci5ydW5BbmRSZXNldCgpKSB7CisgICAgICAgICAgICAgICAgc2V0TmV4dFJ1blRpbWUoKTsKKyAgICAgICAgICAgICAgICByZUV4ZWN1dGVQZXJpb2RpYyhvdXRlclRhc2spOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIGNhbiBydW4gYSB0YXNrIGdpdmVuIGN1cnJlbnQgcnVuIHN0YXRlCisgICAgICogYW5kIHJ1bi1hZnRlci1zaHV0ZG93biBwYXJhbWV0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIHBlcmlvZGljIHRydWUgaWYgdGhpcyB0YXNrIHBlcmlvZGljLCBmYWxzZSBpZiBkZWxheWVkCisgICAgICovCisgICAgYm9vbGVhbiBjYW5SdW5JbkN1cnJlbnRSdW5TdGF0ZShib29sZWFuIHBlcmlvZGljKSB7CisgICAgICAgIHJldHVybiBpc1J1bm5pbmdPclNodXRkb3duKHBlcmlvZGljID8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWVFeGlzdGluZ1BlcmlvZGljVGFza3NBZnRlclNodXRkb3duIDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhlY3V0ZUV4aXN0aW5nRGVsYXllZFRhc2tzQWZ0ZXJTaHV0ZG93bik7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFpbiBleGVjdXRpb24gbWV0aG9kIGZvciBkZWxheWVkIG9yIHBlcmlvZGljIHRhc2tzLiAgSWYgcG9vbAorICAgICAqIGlzIHNodXQgZG93biwgcmVqZWN0cyB0aGUgdGFzay4gT3RoZXJ3aXNlIGFkZHMgdGFzayB0byBxdWV1ZQorICAgICAqIGFuZCBzdGFydHMgYSB0aHJlYWQsIGlmIG5lY2Vzc2FyeSwgdG8gcnVuIGl0LiAgKFdlIGNhbm5vdAorICAgICAqIHByZXN0YXJ0IHRoZSB0aHJlYWQgdG8gcnVuIHRoZSB0YXNrIGJlY2F1c2UgdGhlIHRhc2sgKHByb2JhYmx5KQorICAgICAqIHNob3VsZG4ndCBiZSBydW4geWV0LCkgSWYgdGhlIHBvb2wgaXMgc2h1dCBkb3duIHdoaWxlIHRoZSB0YXNrCisgICAgICogaXMgYmVpbmcgYWRkZWQsIGNhbmNlbCBhbmQgcmVtb3ZlIGl0IGlmIHJlcXVpcmVkIGJ5IHN0YXRlIGFuZAorICAgICAqIHJ1bi1hZnRlci1zaHV0ZG93biBwYXJhbWV0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIHRhc2sgdGhlIHRhc2sKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZGVsYXllZEV4ZWN1dGUoUnVubmFibGVTY2hlZHVsZWRGdXR1cmU8Pz4gdGFzaykgeworICAgICAgICBpZiAoaXNTaHV0ZG93bigpKQorICAgICAgICAgICAgcmVqZWN0KHRhc2spOworICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIHN1cGVyLmdldFF1ZXVlKCkuYWRkKHRhc2spOworICAgICAgICAgICAgaWYgKGlzU2h1dGRvd24oKSAmJgorICAgICAgICAgICAgICAgICFjYW5SdW5JbkN1cnJlbnRSdW5TdGF0ZSh0YXNrLmlzUGVyaW9kaWMoKSkgJiYKKyAgICAgICAgICAgICAgICByZW1vdmUodGFzaykpCisgICAgICAgICAgICAgICAgdGFzay5jYW5jZWwoZmFsc2UpOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHByZXN0YXJ0Q29yZVRocmVhZCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVxdWV1ZXMgYSBwZXJpb2RpYyB0YXNrIHVubGVzcyBjdXJyZW50IHJ1biBzdGF0ZSBwcmVjbHVkZXMgaXQuCisgICAgICogU2FtZSBpZGVhIGFzIGRlbGF5ZWRFeGVjdXRlIGV4Y2VwdCBkcm9wcyB0YXNrIHJhdGhlciB0aGFuIHJlamVjdGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YXNrIHRoZSB0YXNrCisgICAgICovCisgICAgdm9pZCByZUV4ZWN1dGVQZXJpb2RpYyhSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZTw/PiB0YXNrKSB7CisgICAgICAgIGlmIChjYW5SdW5JbkN1cnJlbnRSdW5TdGF0ZSh0cnVlKSkgeworICAgICAgICAgICAgc3VwZXIuZ2V0UXVldWUoKS5hZGQodGFzayk7CisgICAgICAgICAgICBpZiAoIWNhblJ1bkluQ3VycmVudFJ1blN0YXRlKHRydWUpICYmIHJlbW92ZSh0YXNrKSkKKyAgICAgICAgICAgICAgICB0YXNrLmNhbmNlbChmYWxzZSk7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgcHJlc3RhcnRDb3JlVGhyZWFkKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYW5jZWxzIGFuZCBjbGVhcnMgdGhlIHF1ZXVlIG9mIGFsbCB0YXNrcyB0aGF0IHNob3VsZCBub3QgYmUgcnVuCisgICAgICogZHVlIHRvIHNodXRkb3duIHBvbGljeS4gIEludm9rZWQgd2l0aGluIHN1cGVyLnNodXRkb3duLgorICAgICAqLworICAgIEBPdmVycmlkZSB2b2lkIG9uU2h1dGRvd24oKSB7CisgICAgICAgIEJsb2NraW5nUXVldWU8UnVubmFibGU+IHEgPSBzdXBlci5nZXRRdWV1ZSgpOworICAgICAgICBib29sZWFuIGtlZXBEZWxheWVkID0KKyAgICAgICAgICAgIGdldEV4ZWN1dGVFeGlzdGluZ0RlbGF5ZWRUYXNrc0FmdGVyU2h1dGRvd25Qb2xpY3koKTsKKyAgICAgICAgYm9vbGVhbiBrZWVwUGVyaW9kaWMgPQorICAgICAgICAgICAgZ2V0Q29udGludWVFeGlzdGluZ1BlcmlvZGljVGFza3NBZnRlclNodXRkb3duUG9saWN5KCk7CisgICAgICAgIGlmICgha2VlcERlbGF5ZWQgJiYgIWtlZXBQZXJpb2RpYykgeworICAgICAgICAgICAgZm9yIChPYmplY3QgZSA6IHEudG9BcnJheSgpKQorICAgICAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgUnVubmFibGVTY2hlZHVsZWRGdXR1cmU8Pz4pCisgICAgICAgICAgICAgICAgICAgICgoUnVubmFibGVTY2hlZHVsZWRGdXR1cmU8Pz4pIGUpLmNhbmNlbChmYWxzZSk7CisgICAgICAgICAgICBxLmNsZWFyKCk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAvLyBUcmF2ZXJzZSBzbmFwc2hvdCB0byBhdm9pZCBpdGVyYXRvciBleGNlcHRpb25zCisgICAgICAgICAgICBmb3IgKE9iamVjdCBlIDogcS50b0FycmF5KCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlKSB7CisgICAgICAgICAgICAgICAgICAgIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlPD8+IHQgPQorICAgICAgICAgICAgICAgICAgICAgICAgKFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlPD8+KWU7CisgICAgICAgICAgICAgICAgICAgIGlmICgodC5pc1BlcmlvZGljKCkgPyAha2VlcFBlcmlvZGljIDogIWtlZXBEZWxheWVkKSB8fAorICAgICAgICAgICAgICAgICAgICAgICAgdC5pc0NhbmNlbGxlZCgpKSB7IC8vIGFsc28gcmVtb3ZlIGlmIGFscmVhZHkgY2FuY2VsbGVkCisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocS5yZW1vdmUodCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC5jYW5jZWwoZmFsc2UpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRyeVRlcm1pbmF0ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1vZGlmaWVzIG9yIHJlcGxhY2VzIHRoZSB0YXNrIHVzZWQgdG8gZXhlY3V0ZSBhIHJ1bm5hYmxlLgorICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIG92ZXJyaWRlIHRoZSBjb25jcmV0ZQorICAgICAqIGNsYXNzIHVzZWQgZm9yIG1hbmFnaW5nIGludGVybmFsIHRhc2tzLgorICAgICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHNpbXBseSByZXR1cm5zIHRoZSBnaXZlbiB0YXNrLgorICAgICAqCisgICAgICogQHBhcmFtIHJ1bm5hYmxlIHRoZSBzdWJtaXR0ZWQgUnVubmFibGUKKyAgICAgKiBAcGFyYW0gdGFzayB0aGUgdGFzayBjcmVhdGVkIHRvIGV4ZWN1dGUgdGhlIHJ1bm5hYmxlCisgICAgICogQHJldHVybiBhIHRhc2sgdGhhdCBjYW4gZXhlY3V0ZSB0aGUgcnVubmFibGUKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHJvdGVjdGVkIDxWPiBSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZTxWPiBkZWNvcmF0ZVRhc2soCisgICAgICAgIFJ1bm5hYmxlIHJ1bm5hYmxlLCBSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZTxWPiB0YXNrKSB7CisgICAgICAgIHJldHVybiB0YXNrOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1vZGlmaWVzIG9yIHJlcGxhY2VzIHRoZSB0YXNrIHVzZWQgdG8gZXhlY3V0ZSBhIGNhbGxhYmxlLgorICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIG92ZXJyaWRlIHRoZSBjb25jcmV0ZQorICAgICAqIGNsYXNzIHVzZWQgZm9yIG1hbmFnaW5nIGludGVybmFsIHRhc2tzLgorICAgICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHNpbXBseSByZXR1cm5zIHRoZSBnaXZlbiB0YXNrLgorICAgICAqCisgICAgICogQHBhcmFtIGNhbGxhYmxlIHRoZSBzdWJtaXR0ZWQgQ2FsbGFibGUKKyAgICAgKiBAcGFyYW0gdGFzayB0aGUgdGFzayBjcmVhdGVkIHRvIGV4ZWN1dGUgdGhlIGNhbGxhYmxlCisgICAgICogQHJldHVybiBhIHRhc2sgdGhhdCBjYW4gZXhlY3V0ZSB0aGUgY2FsbGFibGUKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHJvdGVjdGVkIDxWPiBSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZTxWPiBkZWNvcmF0ZVRhc2soCisgICAgICAgIENhbGxhYmxlPFY+IGNhbGxhYmxlLCBSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZTxWPiB0YXNrKSB7CisgICAgICAgIHJldHVybiB0YXNrOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFNjaGVkdWxlZFRocmVhZFBvb2xFeGVjdXRvcn0gd2l0aCB0aGUKKyAgICAgKiBnaXZlbiBjb3JlIHBvb2wgc2l6ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb3JlUG9vbFNpemUgdGhlIG51bWJlciBvZiB0aHJlYWRzIHRvIGtlZXAgaW4gdGhlIHBvb2wsIGV2ZW4KKyAgICAgKiAgICAgICAgaWYgdGhleSBhcmUgaWRsZSwgdW5sZXNzIHtAY29kZSBhbGxvd0NvcmVUaHJlYWRUaW1lT3V0fSBpcyBzZXQKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgY29yZVBvb2xTaXplIDwgMH0KKyAgICAgKi8KKyAgICBwdWJsaWMgU2NoZWR1bGVkVGhyZWFkUG9vbEV4ZWN1dG9yKGludCBjb3JlUG9vbFNpemUpIHsKKyAgICAgICAgc3VwZXIoY29yZVBvb2xTaXplLCBJbnRlZ2VyLk1BWF9WQUxVRSwgMCwgVGltZVVuaXQuTkFOT1NFQ09ORFMsCisgICAgICAgICAgICAgIG5ldyBEZWxheWVkV29ya1F1ZXVlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFNjaGVkdWxlZFRocmVhZFBvb2xFeGVjdXRvcn0gd2l0aCB0aGUKKyAgICAgKiBnaXZlbiBpbml0aWFsIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29yZVBvb2xTaXplIHRoZSBudW1iZXIgb2YgdGhyZWFkcyB0byBrZWVwIGluIHRoZSBwb29sLCBldmVuCisgICAgICogICAgICAgIGlmIHRoZXkgYXJlIGlkbGUsIHVubGVzcyB7QGNvZGUgYWxsb3dDb3JlVGhyZWFkVGltZU91dH0gaXMgc2V0CisgICAgICogQHBhcmFtIHRocmVhZEZhY3RvcnkgdGhlIGZhY3RvcnkgdG8gdXNlIHdoZW4gdGhlIGV4ZWN1dG9yCisgICAgICogICAgICAgIGNyZWF0ZXMgYSBuZXcgdGhyZWFkCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGNvcmVQb29sU2l6ZSA8IDB9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgdGhyZWFkRmFjdG9yeX0gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBTY2hlZHVsZWRUaHJlYWRQb29sRXhlY3V0b3IoaW50IGNvcmVQb29sU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRocmVhZEZhY3RvcnkgdGhyZWFkRmFjdG9yeSkgeworICAgICAgICBzdXBlcihjb3JlUG9vbFNpemUsIEludGVnZXIuTUFYX1ZBTFVFLCAwLCBUaW1lVW5pdC5OQU5PU0VDT05EUywKKyAgICAgICAgICAgICAgbmV3IERlbGF5ZWRXb3JrUXVldWUoKSwgdGhyZWFkRmFjdG9yeSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBTY2hlZHVsZWRUaHJlYWRQb29sRXhlY3V0b3Igd2l0aCB0aGUgZ2l2ZW4KKyAgICAgKiBpbml0aWFsIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29yZVBvb2xTaXplIHRoZSBudW1iZXIgb2YgdGhyZWFkcyB0byBrZWVwIGluIHRoZSBwb29sLCBldmVuCisgICAgICogICAgICAgIGlmIHRoZXkgYXJlIGlkbGUsIHVubGVzcyB7QGNvZGUgYWxsb3dDb3JlVGhyZWFkVGltZU91dH0gaXMgc2V0CisgICAgICogQHBhcmFtIGhhbmRsZXIgdGhlIGhhbmRsZXIgdG8gdXNlIHdoZW4gZXhlY3V0aW9uIGlzIGJsb2NrZWQKKyAgICAgKiAgICAgICAgYmVjYXVzZSB0aGUgdGhyZWFkIGJvdW5kcyBhbmQgcXVldWUgY2FwYWNpdGllcyBhcmUgcmVhY2hlZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBjb3JlUG9vbFNpemUgPCAwfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIGhhbmRsZXJ9IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgU2NoZWR1bGVkVGhyZWFkUG9vbEV4ZWN1dG9yKGludCBjb3JlUG9vbFNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWplY3RlZEV4ZWN1dGlvbkhhbmRsZXIgaGFuZGxlcikgeworICAgICAgICBzdXBlcihjb3JlUG9vbFNpemUsIEludGVnZXIuTUFYX1ZBTFVFLCAwLCBUaW1lVW5pdC5OQU5PU0VDT05EUywKKyAgICAgICAgICAgICAgbmV3IERlbGF5ZWRXb3JrUXVldWUoKSwgaGFuZGxlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBTY2hlZHVsZWRUaHJlYWRQb29sRXhlY3V0b3Igd2l0aCB0aGUgZ2l2ZW4KKyAgICAgKiBpbml0aWFsIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29yZVBvb2xTaXplIHRoZSBudW1iZXIgb2YgdGhyZWFkcyB0byBrZWVwIGluIHRoZSBwb29sLCBldmVuCisgICAgICogICAgICAgIGlmIHRoZXkgYXJlIGlkbGUsIHVubGVzcyB7QGNvZGUgYWxsb3dDb3JlVGhyZWFkVGltZU91dH0gaXMgc2V0CisgICAgICogQHBhcmFtIHRocmVhZEZhY3RvcnkgdGhlIGZhY3RvcnkgdG8gdXNlIHdoZW4gdGhlIGV4ZWN1dG9yCisgICAgICogICAgICAgIGNyZWF0ZXMgYSBuZXcgdGhyZWFkCisgICAgICogQHBhcmFtIGhhbmRsZXIgdGhlIGhhbmRsZXIgdG8gdXNlIHdoZW4gZXhlY3V0aW9uIGlzIGJsb2NrZWQKKyAgICAgKiAgICAgICAgYmVjYXVzZSB0aGUgdGhyZWFkIGJvdW5kcyBhbmQgcXVldWUgY2FwYWNpdGllcyBhcmUgcmVhY2hlZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBjb3JlUG9vbFNpemUgPCAwfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYge0Bjb2RlIHRocmVhZEZhY3Rvcnl9IG9yCisgICAgICogICAgICAgICB7QGNvZGUgaGFuZGxlcn0gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBTY2hlZHVsZWRUaHJlYWRQb29sRXhlY3V0b3IoaW50IGNvcmVQb29sU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRocmVhZEZhY3RvcnkgdGhyZWFkRmFjdG9yeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlamVjdGVkRXhlY3V0aW9uSGFuZGxlciBoYW5kbGVyKSB7CisgICAgICAgIHN1cGVyKGNvcmVQb29sU2l6ZSwgSW50ZWdlci5NQVhfVkFMVUUsIDAsIFRpbWVVbml0Lk5BTk9TRUNPTkRTLAorICAgICAgICAgICAgICBuZXcgRGVsYXllZFdvcmtRdWV1ZSgpLCB0aHJlYWRGYWN0b3J5LCBoYW5kbGVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0cmlnZ2VyIHRpbWUgb2YgYSBkZWxheWVkIGFjdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGxvbmcgdHJpZ2dlclRpbWUobG9uZyBkZWxheSwgVGltZVVuaXQgdW5pdCkgeworICAgICAgICByZXR1cm4gdHJpZ2dlclRpbWUodW5pdC50b05hbm9zKChkZWxheSA8IDApID8gMCA6IGRlbGF5KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdHJpZ2dlciB0aW1lIG9mIGEgZGVsYXllZCBhY3Rpb24uCisgICAgICovCisgICAgbG9uZyB0cmlnZ2VyVGltZShsb25nIGRlbGF5KSB7CisgICAgICAgIHJldHVybiBub3coKSArCisgICAgICAgICAgICAoKGRlbGF5IDwgKExvbmcuTUFYX1ZBTFVFID4+IDEpKSA/IGRlbGF5IDogb3ZlcmZsb3dGcmVlKGRlbGF5KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RyYWlucyB0aGUgdmFsdWVzIG9mIGFsbCBkZWxheXMgaW4gdGhlIHF1ZXVlIHRvIGJlIHdpdGhpbgorICAgICAqIExvbmcuTUFYX1ZBTFVFIG9mIGVhY2ggb3RoZXIsIHRvIGF2b2lkIG92ZXJmbG93IGluIGNvbXBhcmVUby4KKyAgICAgKiBUaGlzIG1heSBvY2N1ciBpZiBhIHRhc2sgaXMgZWxpZ2libGUgdG8gYmUgZGVxdWV1ZWQsIGJ1dCBoYXMKKyAgICAgKiBub3QgeWV0IGJlZW4sIHdoaWxlIHNvbWUgb3RoZXIgdGFzayBpcyBhZGRlZCB3aXRoIGEgZGVsYXkgb2YKKyAgICAgKiBMb25nLk1BWF9WQUxVRS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGxvbmcgb3ZlcmZsb3dGcmVlKGxvbmcgZGVsYXkpIHsKKyAgICAgICAgRGVsYXllZCBoZWFkID0gKERlbGF5ZWQpIHN1cGVyLmdldFF1ZXVlKCkucGVlaygpOworICAgICAgICBpZiAoaGVhZCAhPSBudWxsKSB7CisgICAgICAgICAgICBsb25nIGhlYWREZWxheSA9IGhlYWQuZ2V0RGVsYXkoVGltZVVuaXQuTkFOT1NFQ09ORFMpOworICAgICAgICAgICAgaWYgKGhlYWREZWxheSA8IDAgJiYgKGRlbGF5IC0gaGVhZERlbGF5IDwgMCkpCisgICAgICAgICAgICAgICAgZGVsYXkgPSBMb25nLk1BWF9WQUxVRSArIGhlYWREZWxheTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZGVsYXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgICAgICB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIFNjaGVkdWxlZEZ1dHVyZTw/PiBzY2hlZHVsZShSdW5uYWJsZSBjb21tYW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBkZWxheSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVVbml0IHVuaXQpIHsKKyAgICAgICAgaWYgKGNvbW1hbmQgPT0gbnVsbCB8fCB1bml0ID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgUnVubmFibGVTY2hlZHVsZWRGdXR1cmU8Pz4gdCA9IGRlY29yYXRlVGFzayhjb21tYW5kLAorICAgICAgICAgICAgbmV3IFNjaGVkdWxlZEZ1dHVyZVRhc2s8Vm9pZD4oY29tbWFuZCwgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJUaW1lKGRlbGF5LCB1bml0KSkpOworICAgICAgICBkZWxheWVkRXhlY3V0ZSh0KTsKKyAgICAgICAgcmV0dXJuIHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgICAgICB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIDxWPiBTY2hlZHVsZWRGdXR1cmU8Vj4gc2NoZWR1bGUoQ2FsbGFibGU8Vj4gY2FsbGFibGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBkZWxheSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lVW5pdCB1bml0KSB7CisgICAgICAgIGlmIChjYWxsYWJsZSA9PSBudWxsIHx8IHVuaXQgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZTxWPiB0ID0gZGVjb3JhdGVUYXNrKGNhbGxhYmxlLAorICAgICAgICAgICAgbmV3IFNjaGVkdWxlZEZ1dHVyZVRhc2s8Vj4oY2FsbGFibGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyVGltZShkZWxheSwgdW5pdCkpKTsKKyAgICAgICAgZGVsYXllZEV4ZWN1dGUodCk7CisgICAgICAgIHJldHVybiB0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgUmVqZWN0ZWRFeGVjdXRpb25FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICAge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBTY2hlZHVsZWRGdXR1cmU8Pz4gc2NoZWR1bGVBdEZpeGVkUmF0ZShSdW5uYWJsZSBjb21tYW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb25nIGluaXRpYWxEZWxheSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBwZXJpb2QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVVbml0IHVuaXQpIHsKKyAgICAgICAgaWYgKGNvbW1hbmQgPT0gbnVsbCB8fCB1bml0ID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgaWYgKHBlcmlvZCA8PSAwKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICBTY2hlZHVsZWRGdXR1cmVUYXNrPFZvaWQ+IHNmdCA9CisgICAgICAgICAgICBuZXcgU2NoZWR1bGVkRnV0dXJlVGFzazxWb2lkPihjb21tYW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJUaW1lKGluaXRpYWxEZWxheSwgdW5pdCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0LnRvTmFub3MocGVyaW9kKSk7CisgICAgICAgIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlPFZvaWQ+IHQgPSBkZWNvcmF0ZVRhc2soY29tbWFuZCwgc2Z0KTsKKyAgICAgICAgc2Z0Lm91dGVyVGFzayA9IHQ7CisgICAgICAgIGRlbGF5ZWRFeGVjdXRlKHQpOworICAgICAgICByZXR1cm4gdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIFJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAgIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgU2NoZWR1bGVkRnV0dXJlPD8+IHNjaGVkdWxlV2l0aEZpeGVkRGVsYXkoUnVubmFibGUgY29tbWFuZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBpbml0aWFsRGVsYXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgZGVsYXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVVbml0IHVuaXQpIHsKKyAgICAgICAgaWYgKGNvbW1hbmQgPT0gbnVsbCB8fCB1bml0ID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgaWYgKGRlbGF5IDw9IDApCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIFNjaGVkdWxlZEZ1dHVyZVRhc2s8Vm9pZD4gc2Z0ID0KKyAgICAgICAgICAgIG5ldyBTY2hlZHVsZWRGdXR1cmVUYXNrPFZvaWQ+KGNvbW1hbmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJpZ2dlclRpbWUoaW5pdGlhbERlbGF5LCB1bml0KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXQudG9OYW5vcygtZGVsYXkpKTsKKyAgICAgICAgUnVubmFibGVTY2hlZHVsZWRGdXR1cmU8Vm9pZD4gdCA9IGRlY29yYXRlVGFzayhjb21tYW5kLCBzZnQpOworICAgICAgICBzZnQub3V0ZXJUYXNrID0gdDsKKyAgICAgICAgZGVsYXllZEV4ZWN1dGUodCk7CisgICAgICAgIHJldHVybiB0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4ZWN1dGVzIHtAY29kZSBjb21tYW5kfSB3aXRoIHplcm8gcmVxdWlyZWQgZGVsYXkuCisgICAgICogVGhpcyBoYXMgZWZmZWN0IGVxdWl2YWxlbnQgdG8KKyAgICAgKiB7QGxpbmsgI3NjaGVkdWxlKFJ1bm5hYmxlLGxvbmcsVGltZVVuaXQpIHNjaGVkdWxlKGNvbW1hbmQsIDAsIGFueVVuaXQpfS4KKyAgICAgKiBOb3RlIHRoYXQgaW5zcGVjdGlvbnMgb2YgdGhlIHF1ZXVlIGFuZCBvZiB0aGUgbGlzdCByZXR1cm5lZCBieQorICAgICAqIHtAY29kZSBzaHV0ZG93bk5vd30gd2lsbCBhY2Nlc3MgdGhlIHplcm8tZGVsYXllZAorICAgICAqIHtAbGluayBTY2hlZHVsZWRGdXR1cmV9LCBub3QgdGhlIHtAY29kZSBjb21tYW5kfSBpdHNlbGYuCisgICAgICoKKyAgICAgKiA8cD5BIGNvbnNlcXVlbmNlIG9mIHRoZSB1c2Ugb2Yge0Bjb2RlIFNjaGVkdWxlZEZ1dHVyZX0gb2JqZWN0cyBpcworICAgICAqIHRoYXQge0BsaW5rIFRocmVhZFBvb2xFeGVjdXRvciNhZnRlckV4ZWN1dGUgYWZ0ZXJFeGVjdXRlfSBpcyBhbHdheXMKKyAgICAgKiBjYWxsZWQgd2l0aCBhIG51bGwgc2Vjb25kIHtAY29kZSBUaHJvd2FibGV9IGFyZ3VtZW50LCBldmVuIGlmIHRoZQorICAgICAqIHtAY29kZSBjb21tYW5kfSB0ZXJtaW5hdGVkIGFicnVwdGx5LiAgSW5zdGVhZCwgdGhlIHtAY29kZSBUaHJvd2FibGV9CisgICAgICogdGhyb3duIGJ5IHN1Y2ggYSB0YXNrIGNhbiBiZSBvYnRhaW5lZCB2aWEge0BsaW5rIEZ1dHVyZSNnZXR9LgorICAgICAqCisgICAgICogQHRocm93cyBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbiBhdCBkaXNjcmV0aW9uIG9mCisgICAgICogICAgICAgICB7QGNvZGUgUmVqZWN0ZWRFeGVjdXRpb25IYW5kbGVyfSwgaWYgdGhlIHRhc2sKKyAgICAgKiAgICAgICAgIGNhbm5vdCBiZSBhY2NlcHRlZCBmb3IgZXhlY3V0aW9uIGJlY2F1c2UgdGhlCisgICAgICogICAgICAgICBleGVjdXRvciBoYXMgYmVlbiBzaHV0IGRvd24KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBleGVjdXRlKFJ1bm5hYmxlIGNvbW1hbmQpIHsKKyAgICAgICAgc2NoZWR1bGUoY29tbWFuZCwgMCwgVGltZVVuaXQuTkFOT1NFQ09ORFMpOworICAgIH0KKworICAgIC8vIE92ZXJyaWRlIEFic3RyYWN0RXhlY3V0b3JTZXJ2aWNlIG1ldGhvZHMKKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgUmVqZWN0ZWRFeGVjdXRpb25FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBGdXR1cmU8Pz4gc3VibWl0KFJ1bm5hYmxlIHRhc2spIHsKKyAgICAgICAgcmV0dXJuIHNjaGVkdWxlKHRhc2ssIDAsIFRpbWVVbml0Lk5BTk9TRUNPTkRTKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIFJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgPFQ+IEZ1dHVyZTxUPiBzdWJtaXQoUnVubmFibGUgdGFzaywgVCByZXN1bHQpIHsKKyAgICAgICAgcmV0dXJuIHNjaGVkdWxlKEV4ZWN1dG9ycy5jYWxsYWJsZSh0YXNrLCByZXN1bHQpLAorICAgICAgICAgICAgICAgICAgICAgICAgMCwgVGltZVVuaXQuTkFOT1NFQ09ORFMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgUmVqZWN0ZWRFeGVjdXRpb25FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gICAgICAge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyA8VD4gRnV0dXJlPFQ+IHN1Ym1pdChDYWxsYWJsZTxUPiB0YXNrKSB7CisgICAgICAgIHJldHVybiBzY2hlZHVsZSh0YXNrLCAwLCBUaW1lVW5pdC5OQU5PU0VDT05EUyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcG9saWN5IG9uIHdoZXRoZXIgdG8gY29udGludWUgZXhlY3V0aW5nIGV4aXN0aW5nCisgICAgICogcGVyaW9kaWMgdGFza3MgZXZlbiB3aGVuIHRoaXMgZXhlY3V0b3IgaGFzIGJlZW4ge0Bjb2RlIHNodXRkb3dufS4KKyAgICAgKiBJbiB0aGlzIGNhc2UsIHRoZXNlIHRhc2tzIHdpbGwgb25seSB0ZXJtaW5hdGUgdXBvbgorICAgICAqIHtAY29kZSBzaHV0ZG93bk5vd30gb3IgYWZ0ZXIgc2V0dGluZyB0aGUgcG9saWN5IHRvCisgICAgICoge0Bjb2RlIGZhbHNlfSB3aGVuIGFscmVhZHkgc2h1dGRvd24uCisgICAgICogVGhpcyB2YWx1ZSBpcyBieSBkZWZhdWx0IHtAY29kZSBmYWxzZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUgaWYge0Bjb2RlIHRydWV9LCBjb250aW51ZSBhZnRlciBzaHV0ZG93biwgZWxzZSBkb24ndC4KKyAgICAgKiBAc2VlICNnZXRDb250aW51ZUV4aXN0aW5nUGVyaW9kaWNUYXNrc0FmdGVyU2h1dGRvd25Qb2xpY3kKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb250aW51ZUV4aXN0aW5nUGVyaW9kaWNUYXNrc0FmdGVyU2h1dGRvd25Qb2xpY3koYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICBjb250aW51ZUV4aXN0aW5nUGVyaW9kaWNUYXNrc0FmdGVyU2h1dGRvd24gPSB2YWx1ZTsKKyAgICAgICAgaWYgKCF2YWx1ZSAmJiBpc1NodXRkb3duKCkpCisgICAgICAgICAgICBvblNodXRkb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcG9saWN5IG9uIHdoZXRoZXIgdG8gY29udGludWUgZXhlY3V0aW5nIGV4aXN0aW5nCisgICAgICogcGVyaW9kaWMgdGFza3MgZXZlbiB3aGVuIHRoaXMgZXhlY3V0b3IgaGFzIGJlZW4ge0Bjb2RlIHNodXRkb3dufS4KKyAgICAgKiBJbiB0aGlzIGNhc2UsIHRoZXNlIHRhc2tzIHdpbGwgb25seSB0ZXJtaW5hdGUgdXBvbgorICAgICAqIHtAY29kZSBzaHV0ZG93bk5vd30gb3IgYWZ0ZXIgc2V0dGluZyB0aGUgcG9saWN5IHRvCisgICAgICoge0Bjb2RlIGZhbHNlfSB3aGVuIGFscmVhZHkgc2h1dGRvd24uCisgICAgICogVGhpcyB2YWx1ZSBpcyBieSBkZWZhdWx0IHtAY29kZSBmYWxzZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB3aWxsIGNvbnRpbnVlIGFmdGVyIHNodXRkb3duCisgICAgICogQHNlZSAjc2V0Q29udGludWVFeGlzdGluZ1BlcmlvZGljVGFza3NBZnRlclNodXRkb3duUG9saWN5CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0Q29udGludWVFeGlzdGluZ1BlcmlvZGljVGFza3NBZnRlclNodXRkb3duUG9saWN5KCkgeworICAgICAgICByZXR1cm4gY29udGludWVFeGlzdGluZ1BlcmlvZGljVGFza3NBZnRlclNodXRkb3duOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHBvbGljeSBvbiB3aGV0aGVyIHRvIGV4ZWN1dGUgZXhpc3RpbmcgZGVsYXllZAorICAgICAqIHRhc2tzIGV2ZW4gd2hlbiB0aGlzIGV4ZWN1dG9yIGhhcyBiZWVuIHtAY29kZSBzaHV0ZG93bn0uCisgICAgICogSW4gdGhpcyBjYXNlLCB0aGVzZSB0YXNrcyB3aWxsIG9ubHkgdGVybWluYXRlIHVwb24KKyAgICAgKiB7QGNvZGUgc2h1dGRvd25Ob3d9LCBvciBhZnRlciBzZXR0aW5nIHRoZSBwb2xpY3kgdG8KKyAgICAgKiB7QGNvZGUgZmFsc2V9IHdoZW4gYWxyZWFkeSBzaHV0ZG93bi4KKyAgICAgKiBUaGlzIHZhbHVlIGlzIGJ5IGRlZmF1bHQge0Bjb2RlIHRydWV9LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlIGlmIHtAY29kZSB0cnVlfSwgZXhlY3V0ZSBhZnRlciBzaHV0ZG93biwgZWxzZSBkb24ndC4KKyAgICAgKiBAc2VlICNnZXRFeGVjdXRlRXhpc3RpbmdEZWxheWVkVGFza3NBZnRlclNodXRkb3duUG9saWN5CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RXhlY3V0ZUV4aXN0aW5nRGVsYXllZFRhc2tzQWZ0ZXJTaHV0ZG93blBvbGljeShib29sZWFuIHZhbHVlKSB7CisgICAgICAgIGV4ZWN1dGVFeGlzdGluZ0RlbGF5ZWRUYXNrc0FmdGVyU2h1dGRvd24gPSB2YWx1ZTsKKyAgICAgICAgaWYgKCF2YWx1ZSAmJiBpc1NodXRkb3duKCkpCisgICAgICAgICAgICBvblNodXRkb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcG9saWN5IG9uIHdoZXRoZXIgdG8gZXhlY3V0ZSBleGlzdGluZyBkZWxheWVkCisgICAgICogdGFza3MgZXZlbiB3aGVuIHRoaXMgZXhlY3V0b3IgaGFzIGJlZW4ge0Bjb2RlIHNodXRkb3dufS4KKyAgICAgKiBJbiB0aGlzIGNhc2UsIHRoZXNlIHRhc2tzIHdpbGwgb25seSB0ZXJtaW5hdGUgdXBvbgorICAgICAqIHtAY29kZSBzaHV0ZG93bk5vd30sIG9yIGFmdGVyIHNldHRpbmcgdGhlIHBvbGljeSB0bworICAgICAqIHtAY29kZSBmYWxzZX0gd2hlbiBhbHJlYWR5IHNodXRkb3duLgorICAgICAqIFRoaXMgdmFsdWUgaXMgYnkgZGVmYXVsdCB7QGNvZGUgdHJ1ZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB3aWxsIGV4ZWN1dGUgYWZ0ZXIgc2h1dGRvd24KKyAgICAgKiBAc2VlICNzZXRFeGVjdXRlRXhpc3RpbmdEZWxheWVkVGFza3NBZnRlclNodXRkb3duUG9saWN5CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0RXhlY3V0ZUV4aXN0aW5nRGVsYXllZFRhc2tzQWZ0ZXJTaHV0ZG93blBvbGljeSgpIHsKKyAgICAgICAgcmV0dXJuIGV4ZWN1dGVFeGlzdGluZ0RlbGF5ZWRUYXNrc0FmdGVyU2h1dGRvd247CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcG9saWN5IG9uIHdoZXRoZXIgY2FuY2VsbGVkIHRhc2tzIHNob3VsZCBiZSBpbW1lZGlhdGVseQorICAgICAqIHJlbW92ZWQgZnJvbSB0aGUgd29yayBxdWV1ZSBhdCB0aW1lIG9mIGNhbmNlbGxhdGlvbi4gIFRoaXMgdmFsdWUgaXMKKyAgICAgKiBieSBkZWZhdWx0IHtAY29kZSBmYWxzZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUgaWYge0Bjb2RlIHRydWV9LCByZW1vdmUgb24gY2FuY2VsbGF0aW9uLCBlbHNlIGRvbid0CisgICAgICogQHNlZSAjZ2V0UmVtb3ZlT25DYW5jZWxQb2xpY3kKKyAgICAgKiBAc2luY2UgMS43CisgICAgICovCisgICAgLypwdWJsaWMqLyB2b2lkIHNldFJlbW92ZU9uQ2FuY2VsUG9saWN5KGJvb2xlYW4gdmFsdWUpIHsgLy8gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIHJlbW92ZU9uQ2FuY2VsID0gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcG9saWN5IG9uIHdoZXRoZXIgY2FuY2VsbGVkIHRhc2tzIHNob3VsZCBiZSBpbW1lZGlhdGVseQorICAgICAqIHJlbW92ZWQgZnJvbSB0aGUgd29yayBxdWV1ZSBhdCB0aW1lIG9mIGNhbmNlbGxhdGlvbi4gIFRoaXMgdmFsdWUgaXMKKyAgICAgKiBieSBkZWZhdWx0IHtAY29kZSBmYWxzZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBjYW5jZWxsZWQgdGFza3MgYXJlIGltbWVkaWF0ZWx5IHJlbW92ZWQKKyAgICAgKiAgICAgICAgIGZyb20gdGhlIHF1ZXVlCisgICAgICogQHNlZSAjc2V0UmVtb3ZlT25DYW5jZWxQb2xpY3kKKyAgICAgKiBAc2luY2UgMS43CisgICAgICovCisgICAgLypwdWJsaWMqLyBib29sZWFuIGdldFJlbW92ZU9uQ2FuY2VsUG9saWN5KCkgeyAvLyBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgcmV0dXJuIHJlbW92ZU9uQ2FuY2VsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYXRlcyBhbiBvcmRlcmx5IHNodXRkb3duIGluIHdoaWNoIHByZXZpb3VzbHkgc3VibWl0dGVkCisgICAgICogdGFza3MgYXJlIGV4ZWN1dGVkLCBidXQgbm8gbmV3IHRhc2tzIHdpbGwgYmUgYWNjZXB0ZWQuCisgICAgICogSW52b2NhdGlvbiBoYXMgbm8gYWRkaXRpb25hbCBlZmZlY3QgaWYgYWxyZWFkeSBzaHV0IGRvd24uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBkb2VzIG5vdCB3YWl0IGZvciBwcmV2aW91c2x5IHN1Ym1pdHRlZCB0YXNrcyB0bworICAgICAqIGNvbXBsZXRlIGV4ZWN1dGlvbi4gIFVzZSB7QGxpbmsgI2F3YWl0VGVybWluYXRpb24gYXdhaXRUZXJtaW5hdGlvbn0KKyAgICAgKiB0byBkbyB0aGF0LgorICAgICAqCisgICAgICogPHA+SWYgdGhlIHtAY29kZSBFeGVjdXRlRXhpc3RpbmdEZWxheWVkVGFza3NBZnRlclNodXRkb3duUG9saWN5fQorICAgICAqIGhhcyBiZWVuIHNldCB7QGNvZGUgZmFsc2V9LCBleGlzdGluZyBkZWxheWVkIHRhc2tzIHdob3NlIGRlbGF5cworICAgICAqIGhhdmUgbm90IHlldCBlbGFwc2VkIGFyZSBjYW5jZWxsZWQuICBBbmQgdW5sZXNzIHRoZSB7QGNvZGUKKyAgICAgKiBDb250aW51ZUV4aXN0aW5nUGVyaW9kaWNUYXNrc0FmdGVyU2h1dGRvd25Qb2xpY3l9IGhhcyBiZWVuIHNldAorICAgICAqIHtAY29kZSB0cnVlfSwgZnV0dXJlIGV4ZWN1dGlvbnMgb2YgZXhpc3RpbmcgcGVyaW9kaWMgdGFza3Mgd2lsbAorICAgICAqIGJlIGNhbmNlbGxlZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNodXRkb3duKCkgeworICAgICAgICBzdXBlci5zaHV0ZG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0dGVtcHRzIHRvIHN0b3AgYWxsIGFjdGl2ZWx5IGV4ZWN1dGluZyB0YXNrcywgaGFsdHMgdGhlCisgICAgICogcHJvY2Vzc2luZyBvZiB3YWl0aW5nIHRhc2tzLCBhbmQgcmV0dXJucyBhIGxpc3Qgb2YgdGhlIHRhc2tzCisgICAgICogdGhhdCB3ZXJlIGF3YWl0aW5nIGV4ZWN1dGlvbi4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGRvZXMgbm90IHdhaXQgZm9yIGFjdGl2ZWx5IGV4ZWN1dGluZyB0YXNrcyB0bworICAgICAqIHRlcm1pbmF0ZS4gIFVzZSB7QGxpbmsgI2F3YWl0VGVybWluYXRpb24gYXdhaXRUZXJtaW5hdGlvbn0gdG8KKyAgICAgKiBkbyB0aGF0LgorICAgICAqCisgICAgICogPHA+VGhlcmUgYXJlIG5vIGd1YXJhbnRlZXMgYmV5b25kIGJlc3QtZWZmb3J0IGF0dGVtcHRzIHRvIHN0b3AKKyAgICAgKiBwcm9jZXNzaW5nIGFjdGl2ZWx5IGV4ZWN1dGluZyB0YXNrcy4gIFRoaXMgaW1wbGVtZW50YXRpb24KKyAgICAgKiBjYW5jZWxzIHRhc2tzIHZpYSB7QGxpbmsgVGhyZWFkI2ludGVycnVwdH0sIHNvIGFueSB0YXNrIHRoYXQKKyAgICAgKiBmYWlscyB0byByZXNwb25kIHRvIGludGVycnVwdHMgbWF5IG5ldmVyIHRlcm1pbmF0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gbGlzdCBvZiB0YXNrcyB0aGF0IG5ldmVyIGNvbW1lbmNlZCBleGVjdXRpb24uCisgICAgICogICAgICAgICBFYWNoIGVsZW1lbnQgb2YgdGhpcyBsaXN0IGlzIGEge0BsaW5rIFNjaGVkdWxlZEZ1dHVyZX0sCisgICAgICogICAgICAgICBpbmNsdWRpbmcgdGhvc2UgdGFza3Mgc3VibWl0dGVkIHVzaW5nIHtAY29kZSBleGVjdXRlfSwKKyAgICAgKiAgICAgICAgIHdoaWNoIGFyZSBmb3Igc2NoZWR1bGluZyBwdXJwb3NlcyB1c2VkIGFzIHRoZSBiYXNpcyBvZiBhCisgICAgICogICAgICAgICB6ZXJvLWRlbGF5IHtAY29kZSBTY2hlZHVsZWRGdXR1cmV9LgorICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBMaXN0PFJ1bm5hYmxlPiBzaHV0ZG93bk5vdygpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLnNodXRkb3duTm93KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGFzayBxdWV1ZSB1c2VkIGJ5IHRoaXMgZXhlY3V0b3IuICBFYWNoIGVsZW1lbnQgb2YKKyAgICAgKiB0aGlzIHF1ZXVlIGlzIGEge0BsaW5rIFNjaGVkdWxlZEZ1dHVyZX0sIGluY2x1ZGluZyB0aG9zZQorICAgICAqIHRhc2tzIHN1Ym1pdHRlZCB1c2luZyB7QGNvZGUgZXhlY3V0ZX0gd2hpY2ggYXJlIGZvciBzY2hlZHVsaW5nCisgICAgICogcHVycG9zZXMgdXNlZCBhcyB0aGUgYmFzaXMgb2YgYSB6ZXJvLWRlbGF5CisgICAgICoge0Bjb2RlIFNjaGVkdWxlZEZ1dHVyZX0uICBJdGVyYXRpb24gb3ZlciB0aGlzIHF1ZXVlIGlzCisgICAgICogPGVtPm5vdDwvZW0+IGd1YXJhbnRlZWQgdG8gdHJhdmVyc2UgdGFza3MgaW4gdGhlIG9yZGVyIGluCisgICAgICogd2hpY2ggdGhleSB3aWxsIGV4ZWN1dGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB0YXNrIHF1ZXVlCisgICAgICovCisgICAgcHVibGljIEJsb2NraW5nUXVldWU8UnVubmFibGU+IGdldFF1ZXVlKCkgeworICAgICAgICByZXR1cm4gc3VwZXIuZ2V0UXVldWUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWFsaXplZCBkZWxheSBxdWV1ZS4gVG8gbWVzaCB3aXRoIFRQRSBkZWNsYXJhdGlvbnMsIHRoaXMKKyAgICAgKiBjbGFzcyBtdXN0IGJlIGRlY2xhcmVkIGFzIGEgQmxvY2tpbmdRdWV1ZTxSdW5uYWJsZT4gZXZlbiB0aG91Z2gKKyAgICAgKiBpdCBjYW4gb25seSBob2xkIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlcy4KKyAgICAgKi8KKyAgICBzdGF0aWMgY2xhc3MgRGVsYXllZFdvcmtRdWV1ZSBleHRlbmRzIEFic3RyYWN0UXVldWU8UnVubmFibGU+CisgICAgICAgIGltcGxlbWVudHMgQmxvY2tpbmdRdWV1ZTxSdW5uYWJsZT4geworCisgICAgICAgIC8qCisgICAgICAgICAqIEEgRGVsYXllZFdvcmtRdWV1ZSBpcyBiYXNlZCBvbiBhIGhlYXAtYmFzZWQgZGF0YSBzdHJ1Y3R1cmUKKyAgICAgICAgICogbGlrZSB0aG9zZSBpbiBEZWxheVF1ZXVlIGFuZCBQcmlvcml0eVF1ZXVlLCBleGNlcHQgdGhhdAorICAgICAgICAgKiBldmVyeSBTY2hlZHVsZWRGdXR1cmVUYXNrIGFsc28gcmVjb3JkcyBpdHMgaW5kZXggaW50byB0aGUKKyAgICAgICAgICogaGVhcCBhcnJheS4gVGhpcyBlbGltaW5hdGVzIHRoZSBuZWVkIHRvIGZpbmQgYSB0YXNrIHVwb24KKyAgICAgICAgICogY2FuY2VsbGF0aW9uLCBncmVhdGx5IHNwZWVkaW5nIHVwIHJlbW92YWwgKGRvd24gZnJvbSBPKG4pCisgICAgICAgICAqIHRvIE8obG9nIG4pKSwgYW5kIHJlZHVjaW5nIGdhcmJhZ2UgcmV0ZW50aW9uIHRoYXQgd291bGQKKyAgICAgICAgICogb3RoZXJ3aXNlIG9jY3VyIGJ5IHdhaXRpbmcgZm9yIHRoZSBlbGVtZW50IHRvIHJpc2UgdG8gdG9wCisgICAgICAgICAqIGJlZm9yZSBjbGVhcmluZy4gQnV0IGJlY2F1c2UgdGhlIHF1ZXVlIG1heSBhbHNvIGhvbGQKKyAgICAgICAgICogUnVubmFibGVTY2hlZHVsZWRGdXR1cmVzIHRoYXQgYXJlIG5vdCBTY2hlZHVsZWRGdXR1cmVUYXNrcywKKyAgICAgICAgICogd2UgYXJlIG5vdCBndWFyYW50ZWVkIHRvIGhhdmUgc3VjaCBpbmRpY2VzIGF2YWlsYWJsZSwgaW4KKyAgICAgICAgICogd2hpY2ggY2FzZSB3ZSBmYWxsIGJhY2sgdG8gbGluZWFyIHNlYXJjaC4gKFdlIGV4cGVjdCB0aGF0CisgICAgICAgICAqIG1vc3QgdGFza3Mgd2lsbCBub3QgYmUgZGVjb3JhdGVkLCBhbmQgdGhhdCB0aGUgZmFzdGVyIGNhc2VzCisgICAgICAgICAqIHdpbGwgYmUgbXVjaCBtb3JlIGNvbW1vbi4pCisgICAgICAgICAqCisgICAgICAgICAqIEFsbCBoZWFwIG9wZXJhdGlvbnMgbXVzdCByZWNvcmQgaW5kZXggY2hhbmdlcyAtLSBtYWlubHkKKyAgICAgICAgICogd2l0aGluIHNpZnRVcCBhbmQgc2lmdERvd24uIFVwb24gcmVtb3ZhbCwgYSB0YXNrJ3MKKyAgICAgICAgICogaGVhcEluZGV4IGlzIHNldCB0byAtMS4gTm90ZSB0aGF0IFNjaGVkdWxlZEZ1dHVyZVRhc2tzIGNhbgorICAgICAgICAgKiBhcHBlYXIgYXQgbW9zdCBvbmNlIGluIHRoZSBxdWV1ZSAodGhpcyBuZWVkIG5vdCBiZSB0cnVlIGZvcgorICAgICAgICAgKiBvdGhlciBraW5kcyBvZiB0YXNrcyBvciB3b3JrIHF1ZXVlcyksIHNvIGFyZSB1bmlxdWVseQorICAgICAgICAgKiBpZGVudGlmaWVkIGJ5IGhlYXBJbmRleC4KKyAgICAgICAgICovCisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOSVRJQUxfQ0FQQUNJVFkgPSAxNjsKKyAgICAgICAgcHJpdmF0ZSBSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZVtdIHF1ZXVlID0KKyAgICAgICAgICAgIG5ldyBSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZVtJTklUSUFMX0NBUEFDSVRZXTsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSBuZXcgUmVlbnRyYW50TG9jaygpOworICAgICAgICBwcml2YXRlIGludCBzaXplID0gMDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhyZWFkIGRlc2lnbmF0ZWQgdG8gd2FpdCBmb3IgdGhlIHRhc2sgYXQgdGhlIGhlYWQgb2YgdGhlCisgICAgICAgICAqIHF1ZXVlLiAgVGhpcyB2YXJpYW50IG9mIHRoZSBMZWFkZXItRm9sbG93ZXIgcGF0dGVybgorICAgICAgICAgKiAoaHR0cDovL3d3dy5jcy53dXN0bC5lZHUvfnNjaG1pZHQvUE9TQS9QT1NBMi8pIHNlcnZlcyB0bworICAgICAgICAgKiBtaW5pbWl6ZSB1bm5lY2Vzc2FyeSB0aW1lZCB3YWl0aW5nLiAgV2hlbiBhIHRocmVhZCBiZWNvbWVzCisgICAgICAgICAqIHRoZSBsZWFkZXIsIGl0IHdhaXRzIG9ubHkgZm9yIHRoZSBuZXh0IGRlbGF5IHRvIGVsYXBzZSwgYnV0CisgICAgICAgICAqIG90aGVyIHRocmVhZHMgYXdhaXQgaW5kZWZpbml0ZWx5LiAgVGhlIGxlYWRlciB0aHJlYWQgbXVzdAorICAgICAgICAgKiBzaWduYWwgc29tZSBvdGhlciB0aHJlYWQgYmVmb3JlIHJldHVybmluZyBmcm9tIHRha2UoKSBvcgorICAgICAgICAgKiBwb2xsKC4uLiksIHVubGVzcyBzb21lIG90aGVyIHRocmVhZCBiZWNvbWVzIGxlYWRlciBpbiB0aGUKKyAgICAgICAgICogaW50ZXJpbS4gIFdoZW5ldmVyIHRoZSBoZWFkIG9mIHRoZSBxdWV1ZSBpcyByZXBsYWNlZCB3aXRoIGEKKyAgICAgICAgICogdGFzayB3aXRoIGFuIGVhcmxpZXIgZXhwaXJhdGlvbiB0aW1lLCB0aGUgbGVhZGVyIGZpZWxkIGlzCisgICAgICAgICAqIGludmFsaWRhdGVkIGJ5IGJlaW5nIHJlc2V0IHRvIG51bGwsIGFuZCBzb21lIHdhaXRpbmcKKyAgICAgICAgICogdGhyZWFkLCBidXQgbm90IG5lY2Vzc2FyaWx5IHRoZSBjdXJyZW50IGxlYWRlciwgaXMKKyAgICAgICAgICogc2lnbmFsbGVkLiAgU28gd2FpdGluZyB0aHJlYWRzIG11c3QgYmUgcHJlcGFyZWQgdG8gYWNxdWlyZQorICAgICAgICAgKiBhbmQgbG9zZSBsZWFkZXJzaGlwIHdoaWxlIHdhaXRpbmcuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIFRocmVhZCBsZWFkZXIgPSBudWxsOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb25kaXRpb24gc2lnbmFsbGVkIHdoZW4gYSBuZXdlciB0YXNrIGJlY29tZXMgYXZhaWxhYmxlIGF0IHRoZQorICAgICAgICAgKiBoZWFkIG9mIHRoZSBxdWV1ZSBvciBhIG5ldyB0aHJlYWQgbWF5IG5lZWQgdG8gYmVjb21lIGxlYWRlci4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgZmluYWwgQ29uZGl0aW9uIGF2YWlsYWJsZSA9IGxvY2submV3Q29uZGl0aW9uKCk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNldCBmJ3MgaGVhcEluZGV4IGlmIGl0IGlzIGEgU2NoZWR1bGVkRnV0dXJlVGFzay4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgdm9pZCBzZXRJbmRleChSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZSBmLCBpbnQgaWR4KSB7CisgICAgICAgICAgICBpZiAoZiBpbnN0YW5jZW9mIFNjaGVkdWxlZEZ1dHVyZVRhc2spCisgICAgICAgICAgICAgICAgKChTY2hlZHVsZWRGdXR1cmVUYXNrKWYpLmhlYXBJbmRleCA9IGlkeDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTaWZ0IGVsZW1lbnQgYWRkZWQgYXQgYm90dG9tIHVwIHRvIGl0cyBoZWFwLW9yZGVyZWQgc3BvdC4KKyAgICAgICAgICogQ2FsbCBvbmx5IHdoZW4gaG9sZGluZyBsb2NrLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSB2b2lkIHNpZnRVcChpbnQgaywgUnVubmFibGVTY2hlZHVsZWRGdXR1cmUga2V5KSB7CisgICAgICAgICAgICB3aGlsZSAoayA+IDApIHsKKyAgICAgICAgICAgICAgICBpbnQgcGFyZW50ID0gKGsgLSAxKSA+Pj4gMTsKKyAgICAgICAgICAgICAgICBSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZSBlID0gcXVldWVbcGFyZW50XTsKKyAgICAgICAgICAgICAgICBpZiAoa2V5LmNvbXBhcmVUbyhlKSA+PSAwKQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBxdWV1ZVtrXSA9IGU7CisgICAgICAgICAgICAgICAgc2V0SW5kZXgoZSwgayk7CisgICAgICAgICAgICAgICAgayA9IHBhcmVudDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHF1ZXVlW2tdID0ga2V5OworICAgICAgICAgICAgc2V0SW5kZXgoa2V5LCBrKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTaWZ0IGVsZW1lbnQgYWRkZWQgYXQgdG9wIGRvd24gdG8gaXRzIGhlYXAtb3JkZXJlZCBzcG90LgorICAgICAgICAgKiBDYWxsIG9ubHkgd2hlbiBob2xkaW5nIGxvY2suCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIHZvaWQgc2lmdERvd24oaW50IGssIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlIGtleSkgeworICAgICAgICAgICAgaW50IGhhbGYgPSBzaXplID4+PiAxOworICAgICAgICAgICAgd2hpbGUgKGsgPCBoYWxmKSB7CisgICAgICAgICAgICAgICAgaW50IGNoaWxkID0gKGsgPDwgMSkgKyAxOworICAgICAgICAgICAgICAgIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlIGMgPSBxdWV1ZVtjaGlsZF07CisgICAgICAgICAgICAgICAgaW50IHJpZ2h0ID0gY2hpbGQgKyAxOworICAgICAgICAgICAgICAgIGlmIChyaWdodCA8IHNpemUgJiYgYy5jb21wYXJlVG8ocXVldWVbcmlnaHRdKSA+IDApCisgICAgICAgICAgICAgICAgICAgIGMgPSBxdWV1ZVtjaGlsZCA9IHJpZ2h0XTsKKyAgICAgICAgICAgICAgICBpZiAoa2V5LmNvbXBhcmVUbyhjKSA8PSAwKQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBxdWV1ZVtrXSA9IGM7CisgICAgICAgICAgICAgICAgc2V0SW5kZXgoYywgayk7CisgICAgICAgICAgICAgICAgayA9IGNoaWxkOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcXVldWVba10gPSBrZXk7CisgICAgICAgICAgICBzZXRJbmRleChrZXksIGspOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJlc2l6ZSB0aGUgaGVhcCBhcnJheS4gIENhbGwgb25seSB3aGVuIGhvbGRpbmcgbG9jay4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgdm9pZCBncm93KCkgeworICAgICAgICAgICAgaW50IG9sZENhcGFjaXR5ID0gcXVldWUubGVuZ3RoOworICAgICAgICAgICAgaW50IG5ld0NhcGFjaXR5ID0gb2xkQ2FwYWNpdHkgKyAob2xkQ2FwYWNpdHkgPj4gMSk7IC8vIGdyb3cgNTAlCisgICAgICAgICAgICBpZiAobmV3Q2FwYWNpdHkgPCAwKSAvLyBvdmVyZmxvdworICAgICAgICAgICAgICAgIG5ld0NhcGFjaXR5ID0gSW50ZWdlci5NQVhfVkFMVUU7CisgICAgICAgICAgICBxdWV1ZSA9IEFycmF5cy5jb3B5T2YocXVldWUsIG5ld0NhcGFjaXR5KTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBGaW5kIGluZGV4IG9mIGdpdmVuIG9iamVjdCwgb3IgLTEgaWYgYWJzZW50CisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGludCBpbmRleE9mKE9iamVjdCB4KSB7CisgICAgICAgICAgICBpZiAoeCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWYgKHggaW5zdGFuY2VvZiBTY2hlZHVsZWRGdXR1cmVUYXNrKSB7CisgICAgICAgICAgICAgICAgICAgIGludCBpID0gKChTY2hlZHVsZWRGdXR1cmVUYXNrKSB4KS5oZWFwSW5kZXg7CisgICAgICAgICAgICAgICAgICAgIC8vIFNhbml0eSBjaGVjazsgeCBjb3VsZCBjb25jZWl2YWJseSBiZSBhCisgICAgICAgICAgICAgICAgICAgIC8vIFNjaGVkdWxlZEZ1dHVyZVRhc2sgZnJvbSBzb21lIG90aGVyIHBvb2wuCisgICAgICAgICAgICAgICAgICAgIGlmIChpID49IDAgJiYgaSA8IHNpemUgJiYgcXVldWVbaV0gPT0geCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKQorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHguZXF1YWxzKHF1ZXVlW2ldKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3QgeCkgeworICAgICAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiBpbmRleE9mKHgpICE9IC0xOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKE9iamVjdCB4KSB7CisgICAgICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaW50IGkgPSBpbmRleE9mKHgpOworICAgICAgICAgICAgICAgIGlmIChpIDwgMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICAgICAgICAgICAgc2V0SW5kZXgocXVldWVbaV0sIC0xKTsKKyAgICAgICAgICAgICAgICBpbnQgcyA9IC0tc2l6ZTsKKyAgICAgICAgICAgICAgICBSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZSByZXBsYWNlbWVudCA9IHF1ZXVlW3NdOworICAgICAgICAgICAgICAgIHF1ZXVlW3NdID0gbnVsbDsKKyAgICAgICAgICAgICAgICBpZiAocyAhPSBpKSB7CisgICAgICAgICAgICAgICAgICAgIHNpZnREb3duKGksIHJlcGxhY2VtZW50KTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHF1ZXVlW2ldID09IHJlcGxhY2VtZW50KQorICAgICAgICAgICAgICAgICAgICAgICAgc2lmdFVwKGksIHJlcGxhY2VtZW50KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHNpemU7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICAgICAgcmV0dXJuIHNpemUoKSA9PSAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCByZW1haW5pbmdDYXBhY2l0eSgpIHsKKyAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZSBwZWVrKCkgeworICAgICAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiBxdWV1ZVswXTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIG9mZmVyKFJ1bm5hYmxlIHgpIHsKKyAgICAgICAgICAgIGlmICh4ID09IG51bGwpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZSBlID0gKFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlKXg7CisgICAgICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaW50IGkgPSBzaXplOworICAgICAgICAgICAgICAgIGlmIChpID49IHF1ZXVlLmxlbmd0aCkKKyAgICAgICAgICAgICAgICAgICAgZ3JvdygpOworICAgICAgICAgICAgICAgIHNpemUgPSBpICsgMTsKKyAgICAgICAgICAgICAgICBpZiAoaSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHF1ZXVlWzBdID0gZTsKKyAgICAgICAgICAgICAgICAgICAgc2V0SW5kZXgoZSwgMCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgc2lmdFVwKGksIGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAocXVldWVbMF0gPT0gZSkgeworICAgICAgICAgICAgICAgICAgICBsZWFkZXIgPSBudWxsOworICAgICAgICAgICAgICAgICAgICBhdmFpbGFibGUuc2lnbmFsKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBwdXQoUnVubmFibGUgZSkgeworICAgICAgICAgICAgb2ZmZXIoZSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBhZGQoUnVubmFibGUgZSkgeworICAgICAgICAgICAgcmV0dXJuIG9mZmVyKGUpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gb2ZmZXIoUnVubmFibGUgZSwgbG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KSB7CisgICAgICAgICAgICByZXR1cm4gb2ZmZXIoZSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUGVyZm9ybXMgY29tbW9uIGJvb2trZWVwaW5nIGZvciBwb2xsIGFuZCB0YWtlOiBSZXBsYWNlcworICAgICAgICAgKiBmaXJzdCBlbGVtZW50IHdpdGggbGFzdCBhbmQgc2lmdHMgaXQgZG93bi4gIENhbGwgb25seSB3aGVuCisgICAgICAgICAqIGhvbGRpbmcgbG9jay4KKyAgICAgICAgICogQHBhcmFtIGYgdGhlIHRhc2sgdG8gcmVtb3ZlIGFuZCByZXR1cm4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgUnVubmFibGVTY2hlZHVsZWRGdXR1cmUgZmluaXNoUG9sbChSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZSBmKSB7CisgICAgICAgICAgICBpbnQgcyA9IC0tc2l6ZTsKKyAgICAgICAgICAgIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlIHggPSBxdWV1ZVtzXTsKKyAgICAgICAgICAgIHF1ZXVlW3NdID0gbnVsbDsKKyAgICAgICAgICAgIGlmIChzICE9IDApCisgICAgICAgICAgICAgICAgc2lmdERvd24oMCwgeCk7CisgICAgICAgICAgICBzZXRJbmRleChmLCAtMSk7CisgICAgICAgICAgICByZXR1cm4gZjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZSBwb2xsKCkgeworICAgICAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlIGZpcnN0ID0gcXVldWVbMF07CisgICAgICAgICAgICAgICAgaWYgKGZpcnN0ID09IG51bGwgfHwgZmlyc3QuZ2V0RGVsYXkoVGltZVVuaXQuTkFOT1NFQ09ORFMpID4gMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmluaXNoUG9sbChmaXJzdCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUnVubmFibGVTY2hlZHVsZWRGdXR1cmUgdGFrZSgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgICAgICBsb2NrLmxvY2tJbnRlcnJ1cHRpYmx5KCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICAgICAgUnVubmFibGVTY2hlZHVsZWRGdXR1cmUgZmlyc3QgPSBxdWV1ZVswXTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZpcnN0ID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgICAgICBhdmFpbGFibGUuYXdhaXQoKTsKKyAgICAgICAgICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBsb25nIGRlbGF5ID0gZmlyc3QuZ2V0RGVsYXkoVGltZVVuaXQuTkFOT1NFQ09ORFMpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGF5IDw9IDApCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbmlzaFBvbGwoZmlyc3QpOworICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobGVhZGVyICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZhaWxhYmxlLmF3YWl0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaHJlYWQgdGhpc1RocmVhZCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVhZGVyID0gdGhpc1RocmVhZDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdmFpbGFibGUuYXdhaXROYW5vcyhkZWxheSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxlYWRlciA9PSB0aGlzVGhyZWFkKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVhZGVyID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGlmIChsZWFkZXIgPT0gbnVsbCAmJiBxdWV1ZVswXSAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICBhdmFpbGFibGUuc2lnbmFsKCk7CisgICAgICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZSBwb2xsKGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBsb25nIG5hbm9zID0gdW5pdC50b05hbm9zKHRpbWVvdXQpOworICAgICAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICAgICAgbG9jay5sb2NrSW50ZXJydXB0aWJseSgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgICAgIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlIGZpcnN0ID0gcXVldWVbMF07CisgICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmFub3MgPD0gMCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW5vcyA9IGF2YWlsYWJsZS5hd2FpdE5hbm9zKG5hbm9zKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgZGVsYXkgPSBmaXJzdC5nZXREZWxheShUaW1lVW5pdC5OQU5PU0VDT05EUyk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVsYXkgPD0gMCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmluaXNoUG9sbChmaXJzdCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmFub3MgPD0gMCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuYW5vcyA8IGRlbGF5IHx8IGxlYWRlciAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbm9zID0gYXZhaWxhYmxlLmF3YWl0TmFub3MobmFub3MpOworICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhyZWFkIHRoaXNUaHJlYWQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlYWRlciA9IHRoaXNUaHJlYWQ7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyB0aW1lTGVmdCA9IGF2YWlsYWJsZS5hd2FpdE5hbm9zKGRlbGF5KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFub3MgLT0gZGVsYXkgLSB0aW1lTGVmdDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGVhZGVyID09IHRoaXNUaHJlYWQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWFkZXIgPSBudWxsOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgaWYgKGxlYWRlciA9PSBudWxsICYmIHF1ZXVlWzBdICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIGF2YWlsYWJsZS5zaWduYWwoKTsKKyAgICAgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgUnVubmFibGVTY2hlZHVsZWRGdXR1cmUgdCA9IHF1ZXVlW2ldOworICAgICAgICAgICAgICAgICAgICBpZiAodCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBxdWV1ZVtpXSA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgICAgICBzZXRJbmRleCh0LCAtMSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc2l6ZSA9IDA7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJuIGFuZCByZW1vdmUgZmlyc3QgZWxlbWVudCBvbmx5IGlmIGl0IGlzIGV4cGlyZWQuCisgICAgICAgICAqIFVzZWQgb25seSBieSBkcmFpblRvLiAgQ2FsbCBvbmx5IHdoZW4gaG9sZGluZyBsb2NrLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBSdW5uYWJsZVNjaGVkdWxlZEZ1dHVyZSBwb2xsRXhwaXJlZCgpIHsKKyAgICAgICAgICAgIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlIGZpcnN0ID0gcXVldWVbMF07CisgICAgICAgICAgICBpZiAoZmlyc3QgPT0gbnVsbCB8fCBmaXJzdC5nZXREZWxheShUaW1lVW5pdC5OQU5PU0VDT05EUykgPiAwKQorICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgcmV0dXJuIGZpbmlzaFBvbGwoZmlyc3QpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBkcmFpblRvKENvbGxlY3Rpb248PyBzdXBlciBSdW5uYWJsZT4gYykgeworICAgICAgICAgICAgaWYgKGMgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGlmIChjID09IHRoaXMpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlIGZpcnN0OworICAgICAgICAgICAgICAgIGludCBuID0gMDsKKyAgICAgICAgICAgICAgICB3aGlsZSAoKGZpcnN0ID0gcG9sbEV4cGlyZWQoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBjLmFkZChmaXJzdCk7CisgICAgICAgICAgICAgICAgICAgICsrbjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG47CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGRyYWluVG8oQ29sbGVjdGlvbjw/IHN1cGVyIFJ1bm5hYmxlPiBjLCBpbnQgbWF4RWxlbWVudHMpIHsKKyAgICAgICAgICAgIGlmIChjID09IG51bGwpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBpZiAoYyA9PSB0aGlzKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGlmIChtYXhFbGVtZW50cyA8PSAwKQorICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gdGhpcy5sb2NrOworICAgICAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlIGZpcnN0OworICAgICAgICAgICAgICAgIGludCBuID0gMDsKKyAgICAgICAgICAgICAgICB3aGlsZSAobiA8IG1heEVsZW1lbnRzICYmIChmaXJzdCA9IHBvbGxFeHBpcmVkKCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYy5hZGQoZmlyc3QpOworICAgICAgICAgICAgICAgICAgICArK247CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBuOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSB7CisgICAgICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIEFycmF5cy5jb3B5T2YocXVldWUsIHNpemUsIE9iamVjdFtdLmNsYXNzKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICBwdWJsaWMgPFQ+IFRbXSB0b0FycmF5KFRbXSBhKSB7CisgICAgICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSB0aGlzLmxvY2s7CisgICAgICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKGEubGVuZ3RoIDwgc2l6ZSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChUW10pIEFycmF5cy5jb3B5T2YocXVldWUsIHNpemUsIGEuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShxdWV1ZSwgMCwgYSwgMCwgc2l6ZSk7CisgICAgICAgICAgICAgICAgaWYgKGEubGVuZ3RoID4gc2l6ZSkKKyAgICAgICAgICAgICAgICAgICAgYVtzaXplXSA9IG51bGw7CisgICAgICAgICAgICAgICAgcmV0dXJuIGE7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSXRlcmF0b3I8UnVubmFibGU+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBJdHIoQXJyYXlzLmNvcHlPZihxdWV1ZSwgc2l6ZSkpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNuYXBzaG90IGl0ZXJhdG9yIHRoYXQgd29ya3Mgb2ZmIGNvcHkgb2YgdW5kZXJseWluZyBxIGFycmF5LgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBjbGFzcyBJdHIgaW1wbGVtZW50cyBJdGVyYXRvcjxSdW5uYWJsZT4geworICAgICAgICAgICAgZmluYWwgUnVubmFibGVTY2hlZHVsZWRGdXR1cmVbXSBhcnJheTsKKyAgICAgICAgICAgIGludCBjdXJzb3IgPSAwOyAgICAgLy8gaW5kZXggb2YgbmV4dCBlbGVtZW50IHRvIHJldHVybgorICAgICAgICAgICAgaW50IGxhc3RSZXQgPSAtMTsgICAvLyBpbmRleCBvZiBsYXN0IGVsZW1lbnQsIG9yIC0xIGlmIG5vIHN1Y2gKKworICAgICAgICAgICAgSXRyKFJ1bm5hYmxlU2NoZWR1bGVkRnV0dXJlW10gYXJyYXkpIHsKKyAgICAgICAgICAgICAgICB0aGlzLmFycmF5ID0gYXJyYXk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnNvciA8IGFycmF5Lmxlbmd0aDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIFJ1bm5hYmxlIG5leHQoKSB7CisgICAgICAgICAgICAgICAgaWYgKGN1cnNvciA+PSBhcnJheS5sZW5ndGgpCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgbGFzdFJldCA9IGN1cnNvcjsKKyAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlbY3Vyc29yKytdOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICAgICAgaWYgKGxhc3RSZXQgPCAwKQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgRGVsYXllZFdvcmtRdWV1ZS50aGlzLnJlbW92ZShhcnJheVtsYXN0UmV0XSk7CisgICAgICAgICAgICAgICAgbGFzdFJldCA9IC0xOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L1NlbWFwaG9yZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L1NlbWFwaG9yZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYyZGVhMWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvU2VtYXBob3JlLmphdmEKQEAgLTAsMCArMSw2ODQgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudDsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy4qOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy4qOworCisvKioKKyAqIEEgY291bnRpbmcgc2VtYXBob3JlLiAgQ29uY2VwdHVhbGx5LCBhIHNlbWFwaG9yZSBtYWludGFpbnMgYSBzZXQgb2YKKyAqIHBlcm1pdHMuICBFYWNoIHtAbGluayAjYWNxdWlyZX0gYmxvY2tzIGlmIG5lY2Vzc2FyeSB1bnRpbCBhIHBlcm1pdCBpcworICogYXZhaWxhYmxlLCBhbmQgdGhlbiB0YWtlcyBpdC4gIEVhY2gge0BsaW5rICNyZWxlYXNlfSBhZGRzIGEgcGVybWl0LAorICogcG90ZW50aWFsbHkgcmVsZWFzaW5nIGEgYmxvY2tpbmcgYWNxdWlyZXIuCisgKiBIb3dldmVyLCBubyBhY3R1YWwgcGVybWl0IG9iamVjdHMgYXJlIHVzZWQ7IHRoZSB7QGNvZGUgU2VtYXBob3JlfSBqdXN0CisgKiBrZWVwcyBhIGNvdW50IG9mIHRoZSBudW1iZXIgYXZhaWxhYmxlIGFuZCBhY3RzIGFjY29yZGluZ2x5LgorICoKKyAqIDxwPlNlbWFwaG9yZXMgYXJlIG9mdGVuIHVzZWQgdG8gcmVzdHJpY3QgdGhlIG51bWJlciBvZiB0aHJlYWRzIHRoYW4gY2FuCisgKiBhY2Nlc3Mgc29tZSAocGh5c2ljYWwgb3IgbG9naWNhbCkgcmVzb3VyY2UuIEZvciBleGFtcGxlLCBoZXJlIGlzCisgKiBhIGNsYXNzIHRoYXQgdXNlcyBhIHNlbWFwaG9yZSB0byBjb250cm9sIGFjY2VzcyB0byBhIHBvb2wgb2YgaXRlbXM6CisgKiA8cHJlPgorICogY2xhc3MgUG9vbCB7CisgKiAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfQVZBSUxBQkxFID0gMTAwOworICogICBwcml2YXRlIGZpbmFsIFNlbWFwaG9yZSBhdmFpbGFibGUgPSBuZXcgU2VtYXBob3JlKE1BWF9BVkFJTEFCTEUsIHRydWUpOworICoKKyAqICAgcHVibGljIE9iamVjdCBnZXRJdGVtKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAqICAgICBhdmFpbGFibGUuYWNxdWlyZSgpOworICogICAgIHJldHVybiBnZXROZXh0QXZhaWxhYmxlSXRlbSgpOworICogICB9CisgKgorICogICBwdWJsaWMgdm9pZCBwdXRJdGVtKE9iamVjdCB4KSB7CisgKiAgICAgaWYgKG1hcmtBc1VudXNlZCh4KSkKKyAqICAgICAgIGF2YWlsYWJsZS5yZWxlYXNlKCk7CisgKiAgIH0KKyAqCisgKiAgIC8vIE5vdCBhIHBhcnRpY3VsYXJseSBlZmZpY2llbnQgZGF0YSBzdHJ1Y3R1cmU7IGp1c3QgZm9yIGRlbW8KKyAqCisgKiAgIHByb3RlY3RlZCBPYmplY3RbXSBpdGVtcyA9IC4uLiB3aGF0ZXZlciBraW5kcyBvZiBpdGVtcyBiZWluZyBtYW5hZ2VkCisgKiAgIHByb3RlY3RlZCBib29sZWFuW10gdXNlZCA9IG5ldyBib29sZWFuW01BWF9BVkFJTEFCTEVdOworICoKKyAqICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCBPYmplY3QgZ2V0TmV4dEF2YWlsYWJsZUl0ZW0oKSB7CisgKiAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBNQVhfQVZBSUxBQkxFOyArK2kpIHsKKyAqICAgICAgIGlmICghdXNlZFtpXSkgeworICogICAgICAgICAgdXNlZFtpXSA9IHRydWU7CisgKiAgICAgICAgICByZXR1cm4gaXRlbXNbaV07CisgKiAgICAgICB9CisgKiAgICAgfQorICogICAgIHJldHVybiBudWxsOyAvLyBub3QgcmVhY2hlZAorICogICB9CisgKgorICogICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIGJvb2xlYW4gbWFya0FzVW51c2VkKE9iamVjdCBpdGVtKSB7CisgKiAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBNQVhfQVZBSUxBQkxFOyArK2kpIHsKKyAqICAgICAgIGlmIChpdGVtID09IGl0ZW1zW2ldKSB7CisgKiAgICAgICAgICBpZiAodXNlZFtpXSkgeworICogICAgICAgICAgICB1c2VkW2ldID0gZmFsc2U7CisgKiAgICAgICAgICAgIHJldHVybiB0cnVlOworICogICAgICAgICAgfSBlbHNlCisgKiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAqICAgICAgIH0KKyAqICAgICB9CisgKiAgICAgcmV0dXJuIGZhbHNlOworICogICB9CisgKgorICogfQorICogPC9wcmU+CisgKgorICogPHA+QmVmb3JlIG9idGFpbmluZyBhbiBpdGVtIGVhY2ggdGhyZWFkIG11c3QgYWNxdWlyZSBhIHBlcm1pdCBmcm9tCisgKiB0aGUgc2VtYXBob3JlLCBndWFyYW50ZWVpbmcgdGhhdCBhbiBpdGVtIGlzIGF2YWlsYWJsZSBmb3IgdXNlLiBXaGVuCisgKiB0aGUgdGhyZWFkIGhhcyBmaW5pc2hlZCB3aXRoIHRoZSBpdGVtIGl0IGlzIHJldHVybmVkIGJhY2sgdG8gdGhlCisgKiBwb29sIGFuZCBhIHBlcm1pdCBpcyByZXR1cm5lZCB0byB0aGUgc2VtYXBob3JlLCBhbGxvd2luZyBhbm90aGVyCisgKiB0aHJlYWQgdG8gYWNxdWlyZSB0aGF0IGl0ZW0uICBOb3RlIHRoYXQgbm8gc3luY2hyb25pemF0aW9uIGxvY2sgaXMKKyAqIGhlbGQgd2hlbiB7QGxpbmsgI2FjcXVpcmV9IGlzIGNhbGxlZCBhcyB0aGF0IHdvdWxkIHByZXZlbnQgYW4gaXRlbQorICogZnJvbSBiZWluZyByZXR1cm5lZCB0byB0aGUgcG9vbC4gIFRoZSBzZW1hcGhvcmUgZW5jYXBzdWxhdGVzIHRoZQorICogc3luY2hyb25pemF0aW9uIG5lZWRlZCB0byByZXN0cmljdCBhY2Nlc3MgdG8gdGhlIHBvb2wsIHNlcGFyYXRlbHkKKyAqIGZyb20gYW55IHN5bmNocm9uaXphdGlvbiBuZWVkZWQgdG8gbWFpbnRhaW4gdGhlIGNvbnNpc3RlbmN5IG9mIHRoZQorICogcG9vbCBpdHNlbGYuCisgKgorICogPHA+QSBzZW1hcGhvcmUgaW5pdGlhbGl6ZWQgdG8gb25lLCBhbmQgd2hpY2ggaXMgdXNlZCBzdWNoIHRoYXQgaXQKKyAqIG9ubHkgaGFzIGF0IG1vc3Qgb25lIHBlcm1pdCBhdmFpbGFibGUsIGNhbiBzZXJ2ZSBhcyBhIG11dHVhbAorICogZXhjbHVzaW9uIGxvY2suICBUaGlzIGlzIG1vcmUgY29tbW9ubHkga25vd24gYXMgYSA8ZW0+YmluYXJ5CisgKiBzZW1hcGhvcmU8L2VtPiwgYmVjYXVzZSBpdCBvbmx5IGhhcyB0d28gc3RhdGVzOiBvbmUgcGVybWl0CisgKiBhdmFpbGFibGUsIG9yIHplcm8gcGVybWl0cyBhdmFpbGFibGUuICBXaGVuIHVzZWQgaW4gdGhpcyB3YXksIHRoZQorICogYmluYXJ5IHNlbWFwaG9yZSBoYXMgdGhlIHByb3BlcnR5ICh1bmxpa2UgbWFueSB7QGxpbmsgTG9ja30KKyAqIGltcGxlbWVudGF0aW9ucyksIHRoYXQgdGhlICZxdW90O2xvY2smcXVvdDsgY2FuIGJlIHJlbGVhc2VkIGJ5IGEKKyAqIHRocmVhZCBvdGhlciB0aGFuIHRoZSBvd25lciAoYXMgc2VtYXBob3JlcyBoYXZlIG5vIG5vdGlvbiBvZgorICogb3duZXJzaGlwKS4gIFRoaXMgY2FuIGJlIHVzZWZ1bCBpbiBzb21lIHNwZWNpYWxpemVkIGNvbnRleHRzLCBzdWNoCisgKiBhcyBkZWFkbG9jayByZWNvdmVyeS4KKyAqCisgKiA8cD4gVGhlIGNvbnN0cnVjdG9yIGZvciB0aGlzIGNsYXNzIG9wdGlvbmFsbHkgYWNjZXB0cyBhCisgKiA8ZW0+ZmFpcm5lc3M8L2VtPiBwYXJhbWV0ZXIuIFdoZW4gc2V0IGZhbHNlLCB0aGlzIGNsYXNzIG1ha2VzIG5vCisgKiBndWFyYW50ZWVzIGFib3V0IHRoZSBvcmRlciBpbiB3aGljaCB0aHJlYWRzIGFjcXVpcmUgcGVybWl0cy4gSW4KKyAqIHBhcnRpY3VsYXIsIDxlbT5iYXJnaW5nPC9lbT4gaXMgcGVybWl0dGVkLCB0aGF0IGlzLCBhIHRocmVhZAorICogaW52b2tpbmcge0BsaW5rICNhY3F1aXJlfSBjYW4gYmUgYWxsb2NhdGVkIGEgcGVybWl0IGFoZWFkIG9mIGEKKyAqIHRocmVhZCB0aGF0IGhhcyBiZWVuIHdhaXRpbmcgLSBsb2dpY2FsbHkgdGhlIG5ldyB0aHJlYWQgcGxhY2VzIGl0c2VsZiBhdAorICogdGhlIGhlYWQgb2YgdGhlIHF1ZXVlIG9mIHdhaXRpbmcgdGhyZWFkcy4gV2hlbiBmYWlybmVzcyBpcyBzZXQgdHJ1ZSwgdGhlCisgKiBzZW1hcGhvcmUgZ3VhcmFudGVlcyB0aGF0IHRocmVhZHMgaW52b2tpbmcgYW55IG9mIHRoZSB7QGxpbmsKKyAqICNhY3F1aXJlKCkgYWNxdWlyZX0gbWV0aG9kcyBhcmUgc2VsZWN0ZWQgdG8gb2J0YWluIHBlcm1pdHMgaW4gdGhlIG9yZGVyIGluCisgKiB3aGljaCB0aGVpciBpbnZvY2F0aW9uIG9mIHRob3NlIG1ldGhvZHMgd2FzIHByb2Nlc3NlZAorICogKGZpcnN0LWluLWZpcnN0LW91dDsgRklGTykuIE5vdGUgdGhhdCBGSUZPIG9yZGVyaW5nIG5lY2Vzc2FyaWx5CisgKiBhcHBsaWVzIHRvIHNwZWNpZmljIGludGVybmFsIHBvaW50cyBvZiBleGVjdXRpb24gd2l0aGluIHRoZXNlCisgKiBtZXRob2RzLiAgU28sIGl0IGlzIHBvc3NpYmxlIGZvciBvbmUgdGhyZWFkIHRvIGludm9rZQorICoge0Bjb2RlIGFjcXVpcmV9IGJlZm9yZSBhbm90aGVyLCBidXQgcmVhY2ggdGhlIG9yZGVyaW5nIHBvaW50IGFmdGVyCisgKiB0aGUgb3RoZXIsIGFuZCBzaW1pbGFybHkgdXBvbiByZXR1cm4gZnJvbSB0aGUgbWV0aG9kLgorICogQWxzbyBub3RlIHRoYXQgdGhlIHVudGltZWQge0BsaW5rICN0cnlBY3F1aXJlKCkgdHJ5QWNxdWlyZX0gbWV0aG9kcyBkbyBub3QKKyAqIGhvbm9yIHRoZSBmYWlybmVzcyBzZXR0aW5nLCBidXQgd2lsbCB0YWtlIGFueSBwZXJtaXRzIHRoYXQgYXJlCisgKiBhdmFpbGFibGUuCisgKgorICogPHA+R2VuZXJhbGx5LCBzZW1hcGhvcmVzIHVzZWQgdG8gY29udHJvbCByZXNvdXJjZSBhY2Nlc3Mgc2hvdWxkIGJlCisgKiBpbml0aWFsaXplZCBhcyBmYWlyLCB0byBlbnN1cmUgdGhhdCBubyB0aHJlYWQgaXMgc3RhcnZlZCBvdXQgZnJvbQorICogYWNjZXNzaW5nIGEgcmVzb3VyY2UuIFdoZW4gdXNpbmcgc2VtYXBob3JlcyBmb3Igb3RoZXIga2luZHMgb2YKKyAqIHN5bmNocm9uaXphdGlvbiBjb250cm9sLCB0aGUgdGhyb3VnaHB1dCBhZHZhbnRhZ2VzIG9mIG5vbi1mYWlyCisgKiBvcmRlcmluZyBvZnRlbiBvdXR3ZWlnaCBmYWlybmVzcyBjb25zaWRlcmF0aW9ucy4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGFsc28gcHJvdmlkZXMgY29udmVuaWVuY2UgbWV0aG9kcyB0byB7QGxpbmsKKyAqICNhY3F1aXJlKGludCkgYWNxdWlyZX0gYW5kIHtAbGluayAjcmVsZWFzZShpbnQpIHJlbGVhc2V9IG11bHRpcGxlCisgKiBwZXJtaXRzIGF0IGEgdGltZS4gIEJld2FyZSBvZiB0aGUgaW5jcmVhc2VkIHJpc2sgb2YgaW5kZWZpbml0ZQorICogcG9zdHBvbmVtZW50IHdoZW4gdGhlc2UgbWV0aG9kcyBhcmUgdXNlZCB3aXRob3V0IGZhaXJuZXNzIHNldCB0cnVlLgorICoKKyAqIDxwPk1lbW9yeSBjb25zaXN0ZW5jeSBlZmZlY3RzOiBBY3Rpb25zIGluIGEgdGhyZWFkIHByaW9yIHRvIGNhbGxpbmcKKyAqIGEgInJlbGVhc2UiIG1ldGhvZCBzdWNoIGFzIHtAY29kZSByZWxlYXNlKCl9CisgKiA8YSBocmVmPSJwYWNrYWdlLXN1bW1hcnkuaHRtbCNNZW1vcnlWaXNpYmlsaXR5Ij48aT5oYXBwZW4tYmVmb3JlPC9pPjwvYT4KKyAqIGFjdGlvbnMgZm9sbG93aW5nIGEgc3VjY2Vzc2Z1bCAiYWNxdWlyZSIgbWV0aG9kIHN1Y2ggYXMge0Bjb2RlIGFjcXVpcmUoKX0KKyAqIGluIGFub3RoZXIgdGhyZWFkLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqCisgKi8KKworcHVibGljIGNsYXNzIFNlbWFwaG9yZSBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzIyMjU3ODY2MTYwMDY4MDIxMEw7CisgICAgLyoqIEFsbCBtZWNoYW5pY3MgdmlhIEFic3RyYWN0UXVldWVkU3luY2hyb25pemVyIHN1YmNsYXNzICovCisgICAgcHJpdmF0ZSBmaW5hbCBTeW5jIHN5bmM7CisKKyAgICAvKioKKyAgICAgKiBTeW5jaHJvbml6YXRpb24gaW1wbGVtZW50YXRpb24gZm9yIHNlbWFwaG9yZS4gIFVzZXMgQVFTIHN0YXRlCisgICAgICogdG8gcmVwcmVzZW50IHBlcm1pdHMuIFN1YmNsYXNzZWQgaW50byBmYWlyIGFuZCBub25mYWlyCisgICAgICogdmVyc2lvbnMuCisgICAgICovCisgICAgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIFN5bmMgZXh0ZW5kcyBBYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplciB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDExOTI0NTcyMTAwOTE5MTA5MzNMOworCisgICAgICAgIFN5bmMoaW50IHBlcm1pdHMpIHsKKyAgICAgICAgICAgIHNldFN0YXRlKHBlcm1pdHMpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgaW50IGdldFBlcm1pdHMoKSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0U3RhdGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGludCBub25mYWlyVHJ5QWNxdWlyZVNoYXJlZChpbnQgYWNxdWlyZXMpIHsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBpbnQgYXZhaWxhYmxlID0gZ2V0U3RhdGUoKTsKKyAgICAgICAgICAgICAgICBpbnQgcmVtYWluaW5nID0gYXZhaWxhYmxlIC0gYWNxdWlyZXM7CisgICAgICAgICAgICAgICAgaWYgKHJlbWFpbmluZyA8IDAgfHwKKyAgICAgICAgICAgICAgICAgICAgY29tcGFyZUFuZFNldFN0YXRlKGF2YWlsYWJsZSwgcmVtYWluaW5nKSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlbWFpbmluZzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIHRyeVJlbGVhc2VTaGFyZWQoaW50IHJlbGVhc2VzKSB7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgaW50IGN1cnJlbnQgPSBnZXRTdGF0ZSgpOworICAgICAgICAgICAgICAgIGludCBuZXh0ID0gY3VycmVudCArIHJlbGVhc2VzOworICAgICAgICAgICAgICAgIGlmIChuZXh0IDwgY3VycmVudCkgLy8gb3ZlcmZsb3cKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJNYXhpbXVtIHBlcm1pdCBjb3VudCBleGNlZWRlZCIpOworICAgICAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0U3RhdGUoY3VycmVudCwgbmV4dCkpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZmluYWwgdm9pZCByZWR1Y2VQZXJtaXRzKGludCByZWR1Y3Rpb25zKSB7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgaW50IGN1cnJlbnQgPSBnZXRTdGF0ZSgpOworICAgICAgICAgICAgICAgIGludCBuZXh0ID0gY3VycmVudCAtIHJlZHVjdGlvbnM7CisgICAgICAgICAgICAgICAgaWYgKG5leHQgPiBjdXJyZW50KSAvLyB1bmRlcmZsb3cKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJQZXJtaXQgY291bnQgdW5kZXJmbG93Iik7CisgICAgICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXRTdGF0ZShjdXJyZW50LCBuZXh0KSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZmluYWwgaW50IGRyYWluUGVybWl0cygpIHsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBpbnQgY3VycmVudCA9IGdldFN0YXRlKCk7CisgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnQgPT0gMCB8fCBjb21wYXJlQW5kU2V0U3RhdGUoY3VycmVudCwgMCkpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTm9uRmFpciB2ZXJzaW9uCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIE5vbmZhaXJTeW5jIGV4dGVuZHMgU3luYyB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yNjk0MTgzNjg0NDQzNTY3ODk4TDsKKworICAgICAgICBOb25mYWlyU3luYyhpbnQgcGVybWl0cykgeworICAgICAgICAgICAgc3VwZXIocGVybWl0cyk7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgaW50IHRyeUFjcXVpcmVTaGFyZWQoaW50IGFjcXVpcmVzKSB7CisgICAgICAgICAgICByZXR1cm4gbm9uZmFpclRyeUFjcXVpcmVTaGFyZWQoYWNxdWlyZXMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmFpciB2ZXJzaW9uCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIEZhaXJTeW5jIGV4dGVuZHMgU3luYyB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDIwMTQzMzg4MTg3OTYwMDA5NDRMOworCisgICAgICAgIEZhaXJTeW5jKGludCBwZXJtaXRzKSB7CisgICAgICAgICAgICBzdXBlcihwZXJtaXRzKTsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCBpbnQgdHJ5QWNxdWlyZVNoYXJlZChpbnQgYWNxdWlyZXMpIHsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBpZiAoaGFzUXVldWVkUHJlZGVjZXNzb3JzKCkpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgICAgICBpbnQgYXZhaWxhYmxlID0gZ2V0U3RhdGUoKTsKKyAgICAgICAgICAgICAgICBpbnQgcmVtYWluaW5nID0gYXZhaWxhYmxlIC0gYWNxdWlyZXM7CisgICAgICAgICAgICAgICAgaWYgKHJlbWFpbmluZyA8IDAgfHwKKyAgICAgICAgICAgICAgICAgICAgY29tcGFyZUFuZFNldFN0YXRlKGF2YWlsYWJsZSwgcmVtYWluaW5nKSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlbWFpbmluZzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgU2VtYXBob3JlfSB3aXRoIHRoZSBnaXZlbiBudW1iZXIgb2YKKyAgICAgKiBwZXJtaXRzIGFuZCBub25mYWlyIGZhaXJuZXNzIHNldHRpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGVybWl0cyB0aGUgaW5pdGlhbCBudW1iZXIgb2YgcGVybWl0cyBhdmFpbGFibGUuCisgICAgICogICAgICAgIFRoaXMgdmFsdWUgbWF5IGJlIG5lZ2F0aXZlLCBpbiB3aGljaCBjYXNlIHJlbGVhc2VzCisgICAgICogICAgICAgIG11c3Qgb2NjdXIgYmVmb3JlIGFueSBhY3F1aXJlcyB3aWxsIGJlIGdyYW50ZWQuCisgICAgICovCisgICAgcHVibGljIFNlbWFwaG9yZShpbnQgcGVybWl0cykgeworICAgICAgICBzeW5jID0gbmV3IE5vbmZhaXJTeW5jKHBlcm1pdHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgU2VtYXBob3JlfSB3aXRoIHRoZSBnaXZlbiBudW1iZXIgb2YKKyAgICAgKiBwZXJtaXRzIGFuZCB0aGUgZ2l2ZW4gZmFpcm5lc3Mgc2V0dGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwZXJtaXRzIHRoZSBpbml0aWFsIG51bWJlciBvZiBwZXJtaXRzIGF2YWlsYWJsZS4KKyAgICAgKiAgICAgICAgVGhpcyB2YWx1ZSBtYXkgYmUgbmVnYXRpdmUsIGluIHdoaWNoIGNhc2UgcmVsZWFzZXMKKyAgICAgKiAgICAgICAgbXVzdCBvY2N1ciBiZWZvcmUgYW55IGFjcXVpcmVzIHdpbGwgYmUgZ3JhbnRlZC4KKyAgICAgKiBAcGFyYW0gZmFpciB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBzZW1hcGhvcmUgd2lsbCBndWFyYW50ZWUKKyAgICAgKiAgICAgICAgZmlyc3QtaW4gZmlyc3Qtb3V0IGdyYW50aW5nIG9mIHBlcm1pdHMgdW5kZXIgY29udGVudGlvbiwKKyAgICAgKiAgICAgICAgZWxzZSB7QGNvZGUgZmFsc2V9CisgICAgICovCisgICAgcHVibGljIFNlbWFwaG9yZShpbnQgcGVybWl0cywgYm9vbGVhbiBmYWlyKSB7CisgICAgICAgIHN5bmMgPSBmYWlyID8gbmV3IEZhaXJTeW5jKHBlcm1pdHMpIDogbmV3IE5vbmZhaXJTeW5jKHBlcm1pdHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFjcXVpcmVzIGEgcGVybWl0IGZyb20gdGhpcyBzZW1hcGhvcmUsIGJsb2NraW5nIHVudGlsIG9uZSBpcworICAgICAqIGF2YWlsYWJsZSwgb3IgdGhlIHRocmVhZCBpcyB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfS4KKyAgICAgKgorICAgICAqIDxwPkFjcXVpcmVzIGEgcGVybWl0LCBpZiBvbmUgaXMgYXZhaWxhYmxlIGFuZCByZXR1cm5zIGltbWVkaWF0ZWx5LAorICAgICAqIHJlZHVjaW5nIHRoZSBudW1iZXIgb2YgYXZhaWxhYmxlIHBlcm1pdHMgYnkgb25lLgorICAgICAqCisgICAgICogPHA+SWYgbm8gcGVybWl0IGlzIGF2YWlsYWJsZSB0aGVuIHRoZSBjdXJyZW50IHRocmVhZCBiZWNvbWVzCisgICAgICogZGlzYWJsZWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nIHB1cnBvc2VzIGFuZCBsaWVzIGRvcm1hbnQgdW50aWwKKyAgICAgKiBvbmUgb2YgdHdvIHRoaW5ncyBoYXBwZW5zOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQgaW52b2tlcyB0aGUge0BsaW5rICNyZWxlYXNlfSBtZXRob2QgZm9yIHRoaXMKKyAgICAgKiBzZW1hcGhvcmUgYW5kIHRoZSBjdXJyZW50IHRocmVhZCBpcyBuZXh0IHRvIGJlIGFzc2lnbmVkIGEgcGVybWl0OyBvcgorICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdHN9CisgICAgICogdGhlIGN1cnJlbnQgdGhyZWFkLgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgY3VycmVudCB0aHJlYWQ6CisgICAgICogPHVsPgorICAgICAqIDxsaT5oYXMgaXRzIGludGVycnVwdGVkIHN0YXR1cyBzZXQgb24gZW50cnkgdG8gdGhpcyBtZXRob2Q7IG9yCisgICAgICogPGxpPmlzIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0ZWR9IHdoaWxlIHdhaXRpbmcKKyAgICAgKiBmb3IgYSBwZXJtaXQsCisgICAgICogPC91bD4KKyAgICAgKiB0aGVuIHtAbGluayBJbnRlcnJ1cHRlZEV4Y2VwdGlvbn0gaXMgdGhyb3duIGFuZCB0aGUgY3VycmVudCB0aHJlYWQncworICAgICAqIGludGVycnVwdGVkIHN0YXR1cyBpcyBjbGVhcmVkLgorICAgICAqCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCB0aHJlYWQgaXMgaW50ZXJydXB0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhY3F1aXJlKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgc3luYy5hY3F1aXJlU2hhcmVkSW50ZXJydXB0aWJseSgxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBY3F1aXJlcyBhIHBlcm1pdCBmcm9tIHRoaXMgc2VtYXBob3JlLCBibG9ja2luZyB1bnRpbCBvbmUgaXMKKyAgICAgKiBhdmFpbGFibGUuCisgICAgICoKKyAgICAgKiA8cD5BY3F1aXJlcyBhIHBlcm1pdCwgaWYgb25lIGlzIGF2YWlsYWJsZSBhbmQgcmV0dXJucyBpbW1lZGlhdGVseSwKKyAgICAgKiByZWR1Y2luZyB0aGUgbnVtYmVyIG9mIGF2YWlsYWJsZSBwZXJtaXRzIGJ5IG9uZS4KKyAgICAgKgorICAgICAqIDxwPklmIG5vIHBlcm1pdCBpcyBhdmFpbGFibGUgdGhlbiB0aGUgY3VycmVudCB0aHJlYWQgYmVjb21lcworICAgICAqIGRpc2FibGVkIGZvciB0aHJlYWQgc2NoZWR1bGluZyBwdXJwb3NlcyBhbmQgbGllcyBkb3JtYW50IHVudGlsCisgICAgICogc29tZSBvdGhlciB0aHJlYWQgaW52b2tlcyB0aGUge0BsaW5rICNyZWxlYXNlfSBtZXRob2QgZm9yIHRoaXMKKyAgICAgKiBzZW1hcGhvcmUgYW5kIHRoZSBjdXJyZW50IHRocmVhZCBpcyBuZXh0IHRvIGJlIGFzc2lnbmVkIGEgcGVybWl0LgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0ZWR9CisgICAgICogd2hpbGUgd2FpdGluZyBmb3IgYSBwZXJtaXQgdGhlbiBpdCB3aWxsIGNvbnRpbnVlIHRvIHdhaXQsIGJ1dCB0aGUKKyAgICAgKiB0aW1lIGF0IHdoaWNoIHRoZSB0aHJlYWQgaXMgYXNzaWduZWQgYSBwZXJtaXQgbWF5IGNoYW5nZSBjb21wYXJlZCB0bworICAgICAqIHRoZSB0aW1lIGl0IHdvdWxkIGhhdmUgcmVjZWl2ZWQgdGhlIHBlcm1pdCBoYWQgbm8gaW50ZXJydXB0aW9uCisgICAgICogb2NjdXJyZWQuICBXaGVuIHRoZSB0aHJlYWQgZG9lcyByZXR1cm4gZnJvbSB0aGlzIG1ldGhvZCBpdHMgaW50ZXJydXB0CisgICAgICogc3RhdHVzIHdpbGwgYmUgc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFjcXVpcmVVbmludGVycnVwdGlibHkoKSB7CisgICAgICAgIHN5bmMuYWNxdWlyZVNoYXJlZCgxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBY3F1aXJlcyBhIHBlcm1pdCBmcm9tIHRoaXMgc2VtYXBob3JlLCBvbmx5IGlmIG9uZSBpcyBhdmFpbGFibGUgYXQgdGhlCisgICAgICogdGltZSBvZiBpbnZvY2F0aW9uLgorICAgICAqCisgICAgICogPHA+QWNxdWlyZXMgYSBwZXJtaXQsIGlmIG9uZSBpcyBhdmFpbGFibGUgYW5kIHJldHVybnMgaW1tZWRpYXRlbHksCisgICAgICogd2l0aCB0aGUgdmFsdWUge0Bjb2RlIHRydWV9LAorICAgICAqIHJlZHVjaW5nIHRoZSBudW1iZXIgb2YgYXZhaWxhYmxlIHBlcm1pdHMgYnkgb25lLgorICAgICAqCisgICAgICogPHA+SWYgbm8gcGVybWl0IGlzIGF2YWlsYWJsZSB0aGVuIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuCisgICAgICogaW1tZWRpYXRlbHkgd2l0aCB0aGUgdmFsdWUge0Bjb2RlIGZhbHNlfS4KKyAgICAgKgorICAgICAqIDxwPkV2ZW4gd2hlbiB0aGlzIHNlbWFwaG9yZSBoYXMgYmVlbiBzZXQgdG8gdXNlIGEKKyAgICAgKiBmYWlyIG9yZGVyaW5nIHBvbGljeSwgYSBjYWxsIHRvIHtAY29kZSB0cnlBY3F1aXJlKCl9IDxlbT53aWxsPC9lbT4KKyAgICAgKiBpbW1lZGlhdGVseSBhY3F1aXJlIGEgcGVybWl0IGlmIG9uZSBpcyBhdmFpbGFibGUsIHdoZXRoZXIgb3Igbm90CisgICAgICogb3RoZXIgdGhyZWFkcyBhcmUgY3VycmVudGx5IHdhaXRpbmcuCisgICAgICogVGhpcyAmcXVvdDtiYXJnaW5nJnF1b3Q7IGJlaGF2aW9yIGNhbiBiZSB1c2VmdWwgaW4gY2VydGFpbgorICAgICAqIGNpcmN1bXN0YW5jZXMsIGV2ZW4gdGhvdWdoIGl0IGJyZWFrcyBmYWlybmVzcy4gSWYgeW91IHdhbnQgdG8gaG9ub3IKKyAgICAgKiB0aGUgZmFpcm5lc3Mgc2V0dGluZywgdGhlbiB1c2UKKyAgICAgKiB7QGxpbmsgI3RyeUFjcXVpcmUobG9uZywgVGltZVVuaXQpIHRyeUFjcXVpcmUoMCwgVGltZVVuaXQuU0VDT05EUykgfQorICAgICAqIHdoaWNoIGlzIGFsbW9zdCBlcXVpdmFsZW50IChpdCBhbHNvIGRldGVjdHMgaW50ZXJydXB0aW9uKS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGEgcGVybWl0IHdhcyBhY3F1aXJlZCBhbmQge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gdHJ5QWNxdWlyZSgpIHsKKyAgICAgICAgcmV0dXJuIHN5bmMubm9uZmFpclRyeUFjcXVpcmVTaGFyZWQoMSkgPj0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBY3F1aXJlcyBhIHBlcm1pdCBmcm9tIHRoaXMgc2VtYXBob3JlLCBpZiBvbmUgYmVjb21lcyBhdmFpbGFibGUKKyAgICAgKiB3aXRoaW4gdGhlIGdpdmVuIHdhaXRpbmcgdGltZSBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkIGhhcyBub3QKKyAgICAgKiBiZWVuIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0ZWR9LgorICAgICAqCisgICAgICogPHA+QWNxdWlyZXMgYSBwZXJtaXQsIGlmIG9uZSBpcyBhdmFpbGFibGUgYW5kIHJldHVybnMgaW1tZWRpYXRlbHksCisgICAgICogd2l0aCB0aGUgdmFsdWUge0Bjb2RlIHRydWV9LAorICAgICAqIHJlZHVjaW5nIHRoZSBudW1iZXIgb2YgYXZhaWxhYmxlIHBlcm1pdHMgYnkgb25lLgorICAgICAqCisgICAgICogPHA+SWYgbm8gcGVybWl0IGlzIGF2YWlsYWJsZSB0aGVuIHRoZSBjdXJyZW50IHRocmVhZCBiZWNvbWVzCisgICAgICogZGlzYWJsZWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nIHB1cnBvc2VzIGFuZCBsaWVzIGRvcm1hbnQgdW50aWwKKyAgICAgKiBvbmUgb2YgdGhyZWUgdGhpbmdzIGhhcHBlbnM6CisgICAgICogPHVsPgorICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCBpbnZva2VzIHRoZSB7QGxpbmsgI3JlbGVhc2V9IG1ldGhvZCBmb3IgdGhpcworICAgICAqIHNlbWFwaG9yZSBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIG5leHQgdG8gYmUgYXNzaWduZWQgYSBwZXJtaXQ7IG9yCisgICAgICogPGxpPlNvbWUgb3RoZXIgdGhyZWFkIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0c30KKyAgICAgKiB0aGUgY3VycmVudCB0aHJlYWQ7IG9yCisgICAgICogPGxpPlRoZSBzcGVjaWZpZWQgd2FpdGluZyB0aW1lIGVsYXBzZXMuCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPklmIGEgcGVybWl0IGlzIGFjcXVpcmVkIHRoZW4gdGhlIHZhbHVlIHtAY29kZSB0cnVlfSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBjdXJyZW50IHRocmVhZDoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPmhhcyBpdHMgaW50ZXJydXB0ZWQgc3RhdHVzIHNldCBvbiBlbnRyeSB0byB0aGlzIG1ldGhvZDsgb3IKKyAgICAgKiA8bGk+aXMge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRlZH0gd2hpbGUgd2FpdGluZworICAgICAqIHRvIGFjcXVpcmUgYSBwZXJtaXQsCisgICAgICogPC91bD4KKyAgICAgKiB0aGVuIHtAbGluayBJbnRlcnJ1cHRlZEV4Y2VwdGlvbn0gaXMgdGhyb3duIGFuZCB0aGUgY3VycmVudCB0aHJlYWQncworICAgICAqIGludGVycnVwdGVkIHN0YXR1cyBpcyBjbGVhcmVkLgorICAgICAqCisgICAgICogPHA+SWYgdGhlIHNwZWNpZmllZCB3YWl0aW5nIHRpbWUgZWxhcHNlcyB0aGVuIHRoZSB2YWx1ZSB7QGNvZGUgZmFsc2V9CisgICAgICogaXMgcmV0dXJuZWQuICBJZiB0aGUgdGltZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gemVybywgdGhlIG1ldGhvZAorICAgICAqIHdpbGwgbm90IHdhaXQgYXQgYWxsLgorICAgICAqCisgICAgICogQHBhcmFtIHRpbWVvdXQgdGhlIG1heGltdW0gdGltZSB0byB3YWl0IGZvciBhIHBlcm1pdAorICAgICAqIEBwYXJhbSB1bml0IHRoZSB0aW1lIHVuaXQgb2YgdGhlIHtAY29kZSB0aW1lb3V0fSBhcmd1bWVudAorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGEgcGVybWl0IHdhcyBhY3F1aXJlZCBhbmQge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgaWYgdGhlIHdhaXRpbmcgdGltZSBlbGFwc2VkIGJlZm9yZSBhIHBlcm1pdCB3YXMgYWNxdWlyZWQKKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IHRocmVhZCBpcyBpbnRlcnJ1cHRlZAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHRyeUFjcXVpcmUobG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KQorICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc3luYy50cnlBY3F1aXJlU2hhcmVkTmFub3MoMSwgdW5pdC50b05hbm9zKHRpbWVvdXQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWxlYXNlcyBhIHBlcm1pdCwgcmV0dXJuaW5nIGl0IHRvIHRoZSBzZW1hcGhvcmUuCisgICAgICoKKyAgICAgKiA8cD5SZWxlYXNlcyBhIHBlcm1pdCwgaW5jcmVhc2luZyB0aGUgbnVtYmVyIG9mIGF2YWlsYWJsZSBwZXJtaXRzIGJ5CisgICAgICogb25lLiAgSWYgYW55IHRocmVhZHMgYXJlIHRyeWluZyB0byBhY3F1aXJlIGEgcGVybWl0LCB0aGVuIG9uZSBpcworICAgICAqIHNlbGVjdGVkIGFuZCBnaXZlbiB0aGUgcGVybWl0IHRoYXQgd2FzIGp1c3QgcmVsZWFzZWQuICBUaGF0IHRocmVhZAorICAgICAqIGlzIChyZSllbmFibGVkIGZvciB0aHJlYWQgc2NoZWR1bGluZyBwdXJwb3Nlcy4KKyAgICAgKgorICAgICAqIDxwPlRoZXJlIGlzIG5vIHJlcXVpcmVtZW50IHRoYXQgYSB0aHJlYWQgdGhhdCByZWxlYXNlcyBhIHBlcm1pdCBtdXN0CisgICAgICogaGF2ZSBhY3F1aXJlZCB0aGF0IHBlcm1pdCBieSBjYWxsaW5nIHtAbGluayAjYWNxdWlyZX0uCisgICAgICogQ29ycmVjdCB1c2FnZSBvZiBhIHNlbWFwaG9yZSBpcyBlc3RhYmxpc2hlZCBieSBwcm9ncmFtbWluZyBjb252ZW50aW9uCisgICAgICogaW4gdGhlIGFwcGxpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbGVhc2UoKSB7CisgICAgICAgIHN5bmMucmVsZWFzZVNoYXJlZCgxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBY3F1aXJlcyB0aGUgZ2l2ZW4gbnVtYmVyIG9mIHBlcm1pdHMgZnJvbSB0aGlzIHNlbWFwaG9yZSwKKyAgICAgKiBibG9ja2luZyB1bnRpbCBhbGwgYXJlIGF2YWlsYWJsZSwKKyAgICAgKiBvciB0aGUgdGhyZWFkIGlzIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0ZWR9LgorICAgICAqCisgICAgICogPHA+QWNxdWlyZXMgdGhlIGdpdmVuIG51bWJlciBvZiBwZXJtaXRzLCBpZiB0aGV5IGFyZSBhdmFpbGFibGUsCisgICAgICogYW5kIHJldHVybnMgaW1tZWRpYXRlbHksIHJlZHVjaW5nIHRoZSBudW1iZXIgb2YgYXZhaWxhYmxlIHBlcm1pdHMKKyAgICAgKiBieSB0aGUgZ2l2ZW4gYW1vdW50LgorICAgICAqCisgICAgICogPHA+SWYgaW5zdWZmaWNpZW50IHBlcm1pdHMgYXJlIGF2YWlsYWJsZSB0aGVuIHRoZSBjdXJyZW50IHRocmVhZCBiZWNvbWVzCisgICAgICogZGlzYWJsZWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nIHB1cnBvc2VzIGFuZCBsaWVzIGRvcm1hbnQgdW50aWwKKyAgICAgKiBvbmUgb2YgdHdvIHRoaW5ncyBoYXBwZW5zOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQgaW52b2tlcyBvbmUgb2YgdGhlIHtAbGluayAjcmVsZWFzZSgpIHJlbGVhc2V9CisgICAgICogbWV0aG9kcyBmb3IgdGhpcyBzZW1hcGhvcmUsIHRoZSBjdXJyZW50IHRocmVhZCBpcyBuZXh0IHRvIGJlIGFzc2lnbmVkCisgICAgICogcGVybWl0cyBhbmQgdGhlIG51bWJlciBvZiBhdmFpbGFibGUgcGVybWl0cyBzYXRpc2ZpZXMgdGhpcyByZXF1ZXN0OyBvcgorICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdHN9CisgICAgICogdGhlIGN1cnJlbnQgdGhyZWFkLgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgY3VycmVudCB0aHJlYWQ6CisgICAgICogPHVsPgorICAgICAqIDxsaT5oYXMgaXRzIGludGVycnVwdGVkIHN0YXR1cyBzZXQgb24gZW50cnkgdG8gdGhpcyBtZXRob2Q7IG9yCisgICAgICogPGxpPmlzIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0ZWR9IHdoaWxlIHdhaXRpbmcKKyAgICAgKiBmb3IgYSBwZXJtaXQsCisgICAgICogPC91bD4KKyAgICAgKiB0aGVuIHtAbGluayBJbnRlcnJ1cHRlZEV4Y2VwdGlvbn0gaXMgdGhyb3duIGFuZCB0aGUgY3VycmVudCB0aHJlYWQncworICAgICAqIGludGVycnVwdGVkIHN0YXR1cyBpcyBjbGVhcmVkLgorICAgICAqIEFueSBwZXJtaXRzIHRoYXQgd2VyZSB0byBiZSBhc3NpZ25lZCB0byB0aGlzIHRocmVhZCBhcmUgaW5zdGVhZAorICAgICAqIGFzc2lnbmVkIHRvIG90aGVyIHRocmVhZHMgdHJ5aW5nIHRvIGFjcXVpcmUgcGVybWl0cywgYXMgaWYKKyAgICAgKiBwZXJtaXRzIGhhZCBiZWVuIG1hZGUgYXZhaWxhYmxlIGJ5IGEgY2FsbCB0byB7QGxpbmsgI3JlbGVhc2UoKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGVybWl0cyB0aGUgbnVtYmVyIG9mIHBlcm1pdHMgdG8gYWNxdWlyZQorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHBlcm1pdHN9IGlzIG5lZ2F0aXZlCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWNxdWlyZShpbnQgcGVybWl0cykgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBlcm1pdHMgPCAwKSB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIHN5bmMuYWNxdWlyZVNoYXJlZEludGVycnVwdGlibHkocGVybWl0cyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWNxdWlyZXMgdGhlIGdpdmVuIG51bWJlciBvZiBwZXJtaXRzIGZyb20gdGhpcyBzZW1hcGhvcmUsCisgICAgICogYmxvY2tpbmcgdW50aWwgYWxsIGFyZSBhdmFpbGFibGUuCisgICAgICoKKyAgICAgKiA8cD5BY3F1aXJlcyB0aGUgZ2l2ZW4gbnVtYmVyIG9mIHBlcm1pdHMsIGlmIHRoZXkgYXJlIGF2YWlsYWJsZSwKKyAgICAgKiBhbmQgcmV0dXJucyBpbW1lZGlhdGVseSwgcmVkdWNpbmcgdGhlIG51bWJlciBvZiBhdmFpbGFibGUgcGVybWl0cworICAgICAqIGJ5IHRoZSBnaXZlbiBhbW91bnQuCisgICAgICoKKyAgICAgKiA8cD5JZiBpbnN1ZmZpY2llbnQgcGVybWl0cyBhcmUgYXZhaWxhYmxlIHRoZW4gdGhlIGN1cnJlbnQgdGhyZWFkIGJlY29tZXMKKyAgICAgKiBkaXNhYmxlZCBmb3IgdGhyZWFkIHNjaGVkdWxpbmcgcHVycG9zZXMgYW5kIGxpZXMgZG9ybWFudCB1bnRpbAorICAgICAqIHNvbWUgb3RoZXIgdGhyZWFkIGludm9rZXMgb25lIG9mIHRoZSB7QGxpbmsgI3JlbGVhc2UoKSByZWxlYXNlfQorICAgICAqIG1ldGhvZHMgZm9yIHRoaXMgc2VtYXBob3JlLCB0aGUgY3VycmVudCB0aHJlYWQgaXMgbmV4dCB0byBiZSBhc3NpZ25lZAorICAgICAqIHBlcm1pdHMgYW5kIHRoZSBudW1iZXIgb2YgYXZhaWxhYmxlIHBlcm1pdHMgc2F0aXNmaWVzIHRoaXMgcmVxdWVzdC4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBjdXJyZW50IHRocmVhZCBpcyB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfQorICAgICAqIHdoaWxlIHdhaXRpbmcgZm9yIHBlcm1pdHMgdGhlbiBpdCB3aWxsIGNvbnRpbnVlIHRvIHdhaXQgYW5kIGl0cworICAgICAqIHBvc2l0aW9uIGluIHRoZSBxdWV1ZSBpcyBub3QgYWZmZWN0ZWQuICBXaGVuIHRoZSB0aHJlYWQgZG9lcyByZXR1cm4KKyAgICAgKiBmcm9tIHRoaXMgbWV0aG9kIGl0cyBpbnRlcnJ1cHQgc3RhdHVzIHdpbGwgYmUgc2V0LgorICAgICAqCisgICAgICogQHBhcmFtIHBlcm1pdHMgdGhlIG51bWJlciBvZiBwZXJtaXRzIHRvIGFjcXVpcmUKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgcGVybWl0c30gaXMgbmVnYXRpdmUKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFjcXVpcmVVbmludGVycnVwdGlibHkoaW50IHBlcm1pdHMpIHsKKyAgICAgICAgaWYgKHBlcm1pdHMgPCAwKSB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIHN5bmMuYWNxdWlyZVNoYXJlZChwZXJtaXRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBY3F1aXJlcyB0aGUgZ2l2ZW4gbnVtYmVyIG9mIHBlcm1pdHMgZnJvbSB0aGlzIHNlbWFwaG9yZSwgb25seQorICAgICAqIGlmIGFsbCBhcmUgYXZhaWxhYmxlIGF0IHRoZSB0aW1lIG9mIGludm9jYXRpb24uCisgICAgICoKKyAgICAgKiA8cD5BY3F1aXJlcyB0aGUgZ2l2ZW4gbnVtYmVyIG9mIHBlcm1pdHMsIGlmIHRoZXkgYXJlIGF2YWlsYWJsZSwgYW5kCisgICAgICogcmV0dXJucyBpbW1lZGlhdGVseSwgd2l0aCB0aGUgdmFsdWUge0Bjb2RlIHRydWV9LAorICAgICAqIHJlZHVjaW5nIHRoZSBudW1iZXIgb2YgYXZhaWxhYmxlIHBlcm1pdHMgYnkgdGhlIGdpdmVuIGFtb3VudC4KKyAgICAgKgorICAgICAqIDxwPklmIGluc3VmZmljaWVudCBwZXJtaXRzIGFyZSBhdmFpbGFibGUgdGhlbiB0aGlzIG1ldGhvZCB3aWxsIHJldHVybgorICAgICAqIGltbWVkaWF0ZWx5IHdpdGggdGhlIHZhbHVlIHtAY29kZSBmYWxzZX0gYW5kIHRoZSBudW1iZXIgb2YgYXZhaWxhYmxlCisgICAgICogcGVybWl0cyBpcyB1bmNoYW5nZWQuCisgICAgICoKKyAgICAgKiA8cD5FdmVuIHdoZW4gdGhpcyBzZW1hcGhvcmUgaGFzIGJlZW4gc2V0IHRvIHVzZSBhIGZhaXIgb3JkZXJpbmcKKyAgICAgKiBwb2xpY3ksIGEgY2FsbCB0byB7QGNvZGUgdHJ5QWNxdWlyZX0gPGVtPndpbGw8L2VtPgorICAgICAqIGltbWVkaWF0ZWx5IGFjcXVpcmUgYSBwZXJtaXQgaWYgb25lIGlzIGF2YWlsYWJsZSwgd2hldGhlciBvcgorICAgICAqIG5vdCBvdGhlciB0aHJlYWRzIGFyZSBjdXJyZW50bHkgd2FpdGluZy4gIFRoaXMKKyAgICAgKiAmcXVvdDtiYXJnaW5nJnF1b3Q7IGJlaGF2aW9yIGNhbiBiZSB1c2VmdWwgaW4gY2VydGFpbgorICAgICAqIGNpcmN1bXN0YW5jZXMsIGV2ZW4gdGhvdWdoIGl0IGJyZWFrcyBmYWlybmVzcy4gSWYgeW91IHdhbnQgdG8KKyAgICAgKiBob25vciB0aGUgZmFpcm5lc3Mgc2V0dGluZywgdGhlbiB1c2Uge0BsaW5rICN0cnlBY3F1aXJlKGludCwKKyAgICAgKiBsb25nLCBUaW1lVW5pdCkgdHJ5QWNxdWlyZShwZXJtaXRzLCAwLCBUaW1lVW5pdC5TRUNPTkRTKSB9CisgICAgICogd2hpY2ggaXMgYWxtb3N0IGVxdWl2YWxlbnQgKGl0IGFsc28gZGV0ZWN0cyBpbnRlcnJ1cHRpb24pLgorICAgICAqCisgICAgICogQHBhcmFtIHBlcm1pdHMgdGhlIG51bWJlciBvZiBwZXJtaXRzIHRvIGFjcXVpcmUKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgcGVybWl0cyB3ZXJlIGFjcXVpcmVkIGFuZAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgcGVybWl0c30gaXMgbmVnYXRpdmUKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB0cnlBY3F1aXJlKGludCBwZXJtaXRzKSB7CisgICAgICAgIGlmIChwZXJtaXRzIDwgMCkgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICByZXR1cm4gc3luYy5ub25mYWlyVHJ5QWNxdWlyZVNoYXJlZChwZXJtaXRzKSA+PSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFjcXVpcmVzIHRoZSBnaXZlbiBudW1iZXIgb2YgcGVybWl0cyBmcm9tIHRoaXMgc2VtYXBob3JlLCBpZiBhbGwKKyAgICAgKiBiZWNvbWUgYXZhaWxhYmxlIHdpdGhpbiB0aGUgZ2l2ZW4gd2FpdGluZyB0aW1lIGFuZCB0aGUgY3VycmVudAorICAgICAqIHRocmVhZCBoYXMgbm90IGJlZW4ge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRlZH0uCisgICAgICoKKyAgICAgKiA8cD5BY3F1aXJlcyB0aGUgZ2l2ZW4gbnVtYmVyIG9mIHBlcm1pdHMsIGlmIHRoZXkgYXJlIGF2YWlsYWJsZSBhbmQKKyAgICAgKiByZXR1cm5zIGltbWVkaWF0ZWx5LCB3aXRoIHRoZSB2YWx1ZSB7QGNvZGUgdHJ1ZX0sCisgICAgICogcmVkdWNpbmcgdGhlIG51bWJlciBvZiBhdmFpbGFibGUgcGVybWl0cyBieSB0aGUgZ2l2ZW4gYW1vdW50LgorICAgICAqCisgICAgICogPHA+SWYgaW5zdWZmaWNpZW50IHBlcm1pdHMgYXJlIGF2YWlsYWJsZSB0aGVuCisgICAgICogdGhlIGN1cnJlbnQgdGhyZWFkIGJlY29tZXMgZGlzYWJsZWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nCisgICAgICogcHVycG9zZXMgYW5kIGxpZXMgZG9ybWFudCB1bnRpbCBvbmUgb2YgdGhyZWUgdGhpbmdzIGhhcHBlbnM6CisgICAgICogPHVsPgorICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCBpbnZva2VzIG9uZSBvZiB0aGUge0BsaW5rICNyZWxlYXNlKCkgcmVsZWFzZX0KKyAgICAgKiBtZXRob2RzIGZvciB0aGlzIHNlbWFwaG9yZSwgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIG5leHQgdG8gYmUgYXNzaWduZWQKKyAgICAgKiBwZXJtaXRzIGFuZCB0aGUgbnVtYmVyIG9mIGF2YWlsYWJsZSBwZXJtaXRzIHNhdGlzZmllcyB0aGlzIHJlcXVlc3Q7IG9yCisgICAgICogPGxpPlNvbWUgb3RoZXIgdGhyZWFkIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0c30KKyAgICAgKiB0aGUgY3VycmVudCB0aHJlYWQ7IG9yCisgICAgICogPGxpPlRoZSBzcGVjaWZpZWQgd2FpdGluZyB0aW1lIGVsYXBzZXMuCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBwZXJtaXRzIGFyZSBhY3F1aXJlZCB0aGVuIHRoZSB2YWx1ZSB7QGNvZGUgdHJ1ZX0gaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgY3VycmVudCB0aHJlYWQ6CisgICAgICogPHVsPgorICAgICAqIDxsaT5oYXMgaXRzIGludGVycnVwdGVkIHN0YXR1cyBzZXQgb24gZW50cnkgdG8gdGhpcyBtZXRob2Q7IG9yCisgICAgICogPGxpPmlzIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0ZWR9IHdoaWxlIHdhaXRpbmcKKyAgICAgKiB0byBhY3F1aXJlIHRoZSBwZXJtaXRzLAorICAgICAqIDwvdWw+CisgICAgICogdGhlbiB7QGxpbmsgSW50ZXJydXB0ZWRFeGNlcHRpb259IGlzIHRocm93biBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkJ3MKKyAgICAgKiBpbnRlcnJ1cHRlZCBzdGF0dXMgaXMgY2xlYXJlZC4KKyAgICAgKiBBbnkgcGVybWl0cyB0aGF0IHdlcmUgdG8gYmUgYXNzaWduZWQgdG8gdGhpcyB0aHJlYWQsIGFyZSBpbnN0ZWFkCisgICAgICogYXNzaWduZWQgdG8gb3RoZXIgdGhyZWFkcyB0cnlpbmcgdG8gYWNxdWlyZSBwZXJtaXRzLCBhcyBpZgorICAgICAqIHRoZSBwZXJtaXRzIGhhZCBiZWVuIG1hZGUgYXZhaWxhYmxlIGJ5IGEgY2FsbCB0byB7QGxpbmsgI3JlbGVhc2UoKX0uCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgc3BlY2lmaWVkIHdhaXRpbmcgdGltZSBlbGFwc2VzIHRoZW4gdGhlIHZhbHVlIHtAY29kZSBmYWxzZX0KKyAgICAgKiBpcyByZXR1cm5lZC4gIElmIHRoZSB0aW1lIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB6ZXJvLCB0aGUgbWV0aG9kCisgICAgICogd2lsbCBub3Qgd2FpdCBhdCBhbGwuICBBbnkgcGVybWl0cyB0aGF0IHdlcmUgdG8gYmUgYXNzaWduZWQgdG8gdGhpcworICAgICAqIHRocmVhZCwgYXJlIGluc3RlYWQgYXNzaWduZWQgdG8gb3RoZXIgdGhyZWFkcyB0cnlpbmcgdG8gYWNxdWlyZQorICAgICAqIHBlcm1pdHMsIGFzIGlmIHRoZSBwZXJtaXRzIGhhZCBiZWVuIG1hZGUgYXZhaWxhYmxlIGJ5IGEgY2FsbCB0bworICAgICAqIHtAbGluayAjcmVsZWFzZSgpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwZXJtaXRzIHRoZSBudW1iZXIgb2YgcGVybWl0cyB0byBhY3F1aXJlCisgICAgICogQHBhcmFtIHRpbWVvdXQgdGhlIG1heGltdW0gdGltZSB0byB3YWl0IGZvciB0aGUgcGVybWl0cworICAgICAqIEBwYXJhbSB1bml0IHRoZSB0aW1lIHVuaXQgb2YgdGhlIHtAY29kZSB0aW1lb3V0fSBhcmd1bWVudAorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGFsbCBwZXJtaXRzIHdlcmUgYWNxdWlyZWQgYW5kIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIGlmIHRoZSB3YWl0aW5nIHRpbWUgZWxhcHNlZCBiZWZvcmUgYWxsIHBlcm1pdHMgd2VyZSBhY3F1aXJlZAorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHBlcm1pdHN9IGlzIG5lZ2F0aXZlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gdHJ5QWNxdWlyZShpbnQgcGVybWl0cywgbG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KQorICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBpZiAocGVybWl0cyA8IDApIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgcmV0dXJuIHN5bmMudHJ5QWNxdWlyZVNoYXJlZE5hbm9zKHBlcm1pdHMsIHVuaXQudG9OYW5vcyh0aW1lb3V0KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVsZWFzZXMgdGhlIGdpdmVuIG51bWJlciBvZiBwZXJtaXRzLCByZXR1cm5pbmcgdGhlbSB0byB0aGUgc2VtYXBob3JlLgorICAgICAqCisgICAgICogPHA+UmVsZWFzZXMgdGhlIGdpdmVuIG51bWJlciBvZiBwZXJtaXRzLCBpbmNyZWFzaW5nIHRoZSBudW1iZXIgb2YKKyAgICAgKiBhdmFpbGFibGUgcGVybWl0cyBieSB0aGF0IGFtb3VudC4KKyAgICAgKiBJZiBhbnkgdGhyZWFkcyBhcmUgdHJ5aW5nIHRvIGFjcXVpcmUgcGVybWl0cywgdGhlbiBvbmUKKyAgICAgKiBpcyBzZWxlY3RlZCBhbmQgZ2l2ZW4gdGhlIHBlcm1pdHMgdGhhdCB3ZXJlIGp1c3QgcmVsZWFzZWQuCisgICAgICogSWYgdGhlIG51bWJlciBvZiBhdmFpbGFibGUgcGVybWl0cyBzYXRpc2ZpZXMgdGhhdCB0aHJlYWQncyByZXF1ZXN0CisgICAgICogdGhlbiB0aGF0IHRocmVhZCBpcyAocmUpZW5hYmxlZCBmb3IgdGhyZWFkIHNjaGVkdWxpbmcgcHVycG9zZXM7CisgICAgICogb3RoZXJ3aXNlIHRoZSB0aHJlYWQgd2lsbCB3YWl0IHVudGlsIHN1ZmZpY2llbnQgcGVybWl0cyBhcmUgYXZhaWxhYmxlLgorICAgICAqIElmIHRoZXJlIGFyZSBzdGlsbCBwZXJtaXRzIGF2YWlsYWJsZQorICAgICAqIGFmdGVyIHRoaXMgdGhyZWFkJ3MgcmVxdWVzdCBoYXMgYmVlbiBzYXRpc2ZpZWQsIHRoZW4gdGhvc2UgcGVybWl0cworICAgICAqIGFyZSBhc3NpZ25lZCBpbiB0dXJuIHRvIG90aGVyIHRocmVhZHMgdHJ5aW5nIHRvIGFjcXVpcmUgcGVybWl0cy4KKyAgICAgKgorICAgICAqIDxwPlRoZXJlIGlzIG5vIHJlcXVpcmVtZW50IHRoYXQgYSB0aHJlYWQgdGhhdCByZWxlYXNlcyBhIHBlcm1pdCBtdXN0CisgICAgICogaGF2ZSBhY3F1aXJlZCB0aGF0IHBlcm1pdCBieSBjYWxsaW5nIHtAbGluayBTZW1hcGhvcmUjYWNxdWlyZSBhY3F1aXJlfS4KKyAgICAgKiBDb3JyZWN0IHVzYWdlIG9mIGEgc2VtYXBob3JlIGlzIGVzdGFibGlzaGVkIGJ5IHByb2dyYW1taW5nIGNvbnZlbnRpb24KKyAgICAgKiBpbiB0aGUgYXBwbGljYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGVybWl0cyB0aGUgbnVtYmVyIG9mIHBlcm1pdHMgdG8gcmVsZWFzZQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBwZXJtaXRzfSBpcyBuZWdhdGl2ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbGVhc2UoaW50IHBlcm1pdHMpIHsKKyAgICAgICAgaWYgKHBlcm1pdHMgPCAwKSB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIHN5bmMucmVsZWFzZVNoYXJlZChwZXJtaXRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IG51bWJlciBvZiBwZXJtaXRzIGF2YWlsYWJsZSBpbiB0aGlzIHNlbWFwaG9yZS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIHR5cGljYWxseSB1c2VkIGZvciBkZWJ1Z2dpbmcgYW5kIHRlc3RpbmcgcHVycG9zZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgcGVybWl0cyBhdmFpbGFibGUgaW4gdGhpcyBzZW1hcGhvcmUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGF2YWlsYWJsZVBlcm1pdHMoKSB7CisgICAgICAgIHJldHVybiBzeW5jLmdldFBlcm1pdHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBY3F1aXJlcyBhbmQgcmV0dXJucyBhbGwgcGVybWl0cyB0aGF0IGFyZSBpbW1lZGlhdGVseSBhdmFpbGFibGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgcGVybWl0cyBhY3F1aXJlZAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZHJhaW5QZXJtaXRzKCkgeworICAgICAgICByZXR1cm4gc3luYy5kcmFpblBlcm1pdHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTaHJpbmtzIHRoZSBudW1iZXIgb2YgYXZhaWxhYmxlIHBlcm1pdHMgYnkgdGhlIGluZGljYXRlZAorICAgICAqIHJlZHVjdGlvbi4gVGhpcyBtZXRob2QgY2FuIGJlIHVzZWZ1bCBpbiBzdWJjbGFzc2VzIHRoYXQgdXNlCisgICAgICogc2VtYXBob3JlcyB0byB0cmFjayByZXNvdXJjZXMgdGhhdCBiZWNvbWUgdW5hdmFpbGFibGUuIFRoaXMKKyAgICAgKiBtZXRob2QgZGlmZmVycyBmcm9tIHtAY29kZSBhY3F1aXJlfSBpbiB0aGF0IGl0IGRvZXMgbm90IGJsb2NrCisgICAgICogd2FpdGluZyBmb3IgcGVybWl0cyB0byBiZWNvbWUgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHBhcmFtIHJlZHVjdGlvbiB0aGUgbnVtYmVyIG9mIHBlcm1pdHMgdG8gcmVtb3ZlCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHJlZHVjdGlvbn0gaXMgbmVnYXRpdmUKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCByZWR1Y2VQZXJtaXRzKGludCByZWR1Y3Rpb24pIHsKKyAgICAgICAgaWYgKHJlZHVjdGlvbiA8IDApIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgc3luYy5yZWR1Y2VQZXJtaXRzKHJlZHVjdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBzZW1hcGhvcmUgaGFzIGZhaXJuZXNzIHNldCB0cnVlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBzZW1hcGhvcmUgaGFzIGZhaXJuZXNzIHNldCB0cnVlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNGYWlyKCkgeworICAgICAgICByZXR1cm4gc3luYyBpbnN0YW5jZW9mIEZhaXJTeW5jOworICAgIH0KKworICAgIC8qKgorICAgICAqIFF1ZXJpZXMgd2hldGhlciBhbnkgdGhyZWFkcyBhcmUgd2FpdGluZyB0byBhY3F1aXJlLiBOb3RlIHRoYXQKKyAgICAgKiBiZWNhdXNlIGNhbmNlbGxhdGlvbnMgbWF5IG9jY3VyIGF0IGFueSB0aW1lLCBhIHtAY29kZSB0cnVlfQorICAgICAqIHJldHVybiBkb2VzIG5vdCBndWFyYW50ZWUgdGhhdCBhbnkgb3RoZXIgdGhyZWFkIHdpbGwgZXZlcgorICAgICAqIGFjcXVpcmUuICBUaGlzIG1ldGhvZCBpcyBkZXNpZ25lZCBwcmltYXJpbHkgZm9yIHVzZSBpbgorICAgICAqIG1vbml0b3Jpbmcgb2YgdGhlIHN5c3RlbSBzdGF0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZXJlIG1heSBiZSBvdGhlciB0aHJlYWRzIHdhaXRpbmcgdG8KKyAgICAgKiAgICAgICAgIGFjcXVpcmUgdGhlIGxvY2sKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNRdWV1ZWRUaHJlYWRzKCkgeworICAgICAgICByZXR1cm4gc3luYy5oYXNRdWV1ZWRUaHJlYWRzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBlc3RpbWF0ZSBvZiB0aGUgbnVtYmVyIG9mIHRocmVhZHMgd2FpdGluZyB0byBhY3F1aXJlLgorICAgICAqIFRoZSB2YWx1ZSBpcyBvbmx5IGFuIGVzdGltYXRlIGJlY2F1c2UgdGhlIG51bWJlciBvZiB0aHJlYWRzIG1heQorICAgICAqIGNoYW5nZSBkeW5hbWljYWxseSB3aGlsZSB0aGlzIG1ldGhvZCB0cmF2ZXJzZXMgaW50ZXJuYWwgZGF0YQorICAgICAqIHN0cnVjdHVyZXMuICBUaGlzIG1ldGhvZCBpcyBkZXNpZ25lZCBmb3IgdXNlIGluIG1vbml0b3Jpbmcgb2YgdGhlCisgICAgICogc3lzdGVtIHN0YXRlLCBub3QgZm9yIHN5bmNocm9uaXphdGlvbiBjb250cm9sLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZXN0aW1hdGVkIG51bWJlciBvZiB0aHJlYWRzIHdhaXRpbmcgZm9yIHRoaXMgbG9jaworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UXVldWVMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBzeW5jLmdldFF1ZXVlTGVuZ3RoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvbGxlY3Rpb24gY29udGFpbmluZyB0aHJlYWRzIHRoYXQgbWF5IGJlIHdhaXRpbmcgdG8gYWNxdWlyZS4KKyAgICAgKiBCZWNhdXNlIHRoZSBhY3R1YWwgc2V0IG9mIHRocmVhZHMgbWF5IGNoYW5nZSBkeW5hbWljYWxseSB3aGlsZQorICAgICAqIGNvbnN0cnVjdGluZyB0aGlzIHJlc3VsdCwgdGhlIHJldHVybmVkIGNvbGxlY3Rpb24gaXMgb25seSBhIGJlc3QtZWZmb3J0CisgICAgICogZXN0aW1hdGUuICBUaGUgZWxlbWVudHMgb2YgdGhlIHJldHVybmVkIGNvbGxlY3Rpb24gYXJlIGluIG5vIHBhcnRpY3VsYXIKKyAgICAgKiBvcmRlci4gIFRoaXMgbWV0aG9kIGlzIGRlc2lnbmVkIHRvIGZhY2lsaXRhdGUgY29uc3RydWN0aW9uIG9mCisgICAgICogc3ViY2xhc3NlcyB0aGF0IHByb3ZpZGUgbW9yZSBleHRlbnNpdmUgbW9uaXRvcmluZyBmYWNpbGl0aWVzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29sbGVjdGlvbiBvZiB0aHJlYWRzCisgICAgICovCisgICAgcHJvdGVjdGVkIENvbGxlY3Rpb248VGhyZWFkPiBnZXRRdWV1ZWRUaHJlYWRzKCkgeworICAgICAgICByZXR1cm4gc3luYy5nZXRRdWV1ZWRUaHJlYWRzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBpZGVudGlmeWluZyB0aGlzIHNlbWFwaG9yZSwgYXMgd2VsbCBhcyBpdHMgc3RhdGUuCisgICAgICogVGhlIHN0YXRlLCBpbiBicmFja2V0cywgaW5jbHVkZXMgdGhlIFN0cmluZyB7QGNvZGUgIlBlcm1pdHMgPSJ9CisgICAgICogZm9sbG93ZWQgYnkgdGhlIG51bWJlciBvZiBwZXJtaXRzLgorICAgICAqCisgICAgICogQHJldHVybiBhIHN0cmluZyBpZGVudGlmeWluZyB0aGlzIHNlbWFwaG9yZSwgYXMgd2VsbCBhcyBpdHMgc3RhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKSArICJbUGVybWl0cyA9ICIgKyBzeW5jLmdldFBlcm1pdHMoKSArICJdIjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvU3luY2hyb25vdXNRdWV1ZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L1N5bmNocm9ub3VzUXVldWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MWQ0MGMwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L1N5bmNocm9ub3VzUXVldWUuamF2YQpAQCAtMCwwICsxLDExMjkgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhLCBCaWxsIFNjaGVyZXIsIGFuZCBNaWNoYWVsIFNjb3R0IHdpdGgKKyAqIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2IEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8KKyAqIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3MuKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuRW1wdHlBcnJheTsKKworLy8gQkVHSU4gYW5kcm9pZC1ub3RlCisvLyByZW1vdmVkIGxpbmsgdG8gY29sbGVjdGlvbnMgZnJhbWV3b3JrIGRvY3MKKy8vIEVORCBhbmRyb2lkLW5vdGUKKworLyoqCisgKiBBIHtAbGlua3BsYWluIEJsb2NraW5nUXVldWUgYmxvY2tpbmcgcXVldWV9IGluIHdoaWNoIGVhY2ggaW5zZXJ0CisgKiBvcGVyYXRpb24gbXVzdCB3YWl0IGZvciBhIGNvcnJlc3BvbmRpbmcgcmVtb3ZlIG9wZXJhdGlvbiBieSBhbm90aGVyCisgKiB0aHJlYWQsIGFuZCB2aWNlIHZlcnNhLiAgQSBzeW5jaHJvbm91cyBxdWV1ZSBkb2VzIG5vdCBoYXZlIGFueQorICogaW50ZXJuYWwgY2FwYWNpdHksIG5vdCBldmVuIGEgY2FwYWNpdHkgb2Ygb25lLiAgWW91IGNhbm5vdAorICogPHR0PnBlZWs8L3R0PiBhdCBhIHN5bmNocm9ub3VzIHF1ZXVlIGJlY2F1c2UgYW4gZWxlbWVudCBpcyBvbmx5CisgKiBwcmVzZW50IHdoZW4geW91IHRyeSB0byByZW1vdmUgaXQ7IHlvdSBjYW5ub3QgaW5zZXJ0IGFuIGVsZW1lbnQKKyAqICh1c2luZyBhbnkgbWV0aG9kKSB1bmxlc3MgYW5vdGhlciB0aHJlYWQgaXMgdHJ5aW5nIHRvIHJlbW92ZSBpdDsKKyAqIHlvdSBjYW5ub3QgaXRlcmF0ZSBhcyB0aGVyZSBpcyBub3RoaW5nIHRvIGl0ZXJhdGUuICBUaGUKKyAqIDxlbT5oZWFkPC9lbT4gb2YgdGhlIHF1ZXVlIGlzIHRoZSBlbGVtZW50IHRoYXQgdGhlIGZpcnN0IHF1ZXVlZAorICogaW5zZXJ0aW5nIHRocmVhZCBpcyB0cnlpbmcgdG8gYWRkIHRvIHRoZSBxdWV1ZTsgaWYgdGhlcmUgaXMgbm8gc3VjaAorICogcXVldWVkIHRocmVhZCB0aGVuIG5vIGVsZW1lbnQgaXMgYXZhaWxhYmxlIGZvciByZW1vdmFsIGFuZAorICogPHR0PnBvbGwoKTwvdHQ+IHdpbGwgcmV0dXJuIDx0dD5udWxsPC90dD4uICBGb3IgcHVycG9zZXMgb2Ygb3RoZXIKKyAqIDx0dD5Db2xsZWN0aW9uPC90dD4gbWV0aG9kcyAoZm9yIGV4YW1wbGUgPHR0PmNvbnRhaW5zPC90dD4pLCBhCisgKiA8dHQ+U3luY2hyb25vdXNRdWV1ZTwvdHQ+IGFjdHMgYXMgYW4gZW1wdHkgY29sbGVjdGlvbi4gIFRoaXMgcXVldWUKKyAqIGRvZXMgbm90IHBlcm1pdCA8dHQ+bnVsbDwvdHQ+IGVsZW1lbnRzLgorICoKKyAqIDxwPlN5bmNocm9ub3VzIHF1ZXVlcyBhcmUgc2ltaWxhciB0byByZW5kZXp2b3VzIGNoYW5uZWxzIHVzZWQgaW4KKyAqIENTUCBhbmQgQWRhLiBUaGV5IGFyZSB3ZWxsIHN1aXRlZCBmb3IgaGFuZG9mZiBkZXNpZ25zLCBpbiB3aGljaCBhbgorICogb2JqZWN0IHJ1bm5pbmcgaW4gb25lIHRocmVhZCBtdXN0IHN5bmMgdXAgd2l0aCBhbiBvYmplY3QgcnVubmluZworICogaW4gYW5vdGhlciB0aHJlYWQgaW4gb3JkZXIgdG8gaGFuZCBpdCBzb21lIGluZm9ybWF0aW9uLCBldmVudCwgb3IKKyAqIHRhc2suCisgKgorICogPHA+IFRoaXMgY2xhc3Mgc3VwcG9ydHMgYW4gb3B0aW9uYWwgZmFpcm5lc3MgcG9saWN5IGZvciBvcmRlcmluZworICogd2FpdGluZyBwcm9kdWNlciBhbmQgY29uc3VtZXIgdGhyZWFkcy4gIEJ5IGRlZmF1bHQsIHRoaXMgb3JkZXJpbmcKKyAqIGlzIG5vdCBndWFyYW50ZWVkLiBIb3dldmVyLCBhIHF1ZXVlIGNvbnN0cnVjdGVkIHdpdGggZmFpcm5lc3Mgc2V0CisgKiB0byA8dHQ+dHJ1ZTwvdHQ+IGdyYW50cyB0aHJlYWRzIGFjY2VzcyBpbiBGSUZPIG9yZGVyLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgYW5kIGl0cyBpdGVyYXRvciBpbXBsZW1lbnQgYWxsIG9mIHRoZQorICogPGVtPm9wdGlvbmFsPC9lbT4gbWV0aG9kcyBvZiB0aGUge0BsaW5rIENvbGxlY3Rpb259IGFuZCB7QGxpbmsKKyAqIEl0ZXJhdG9yfSBpbnRlcmZhY2VzLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEgYW5kIEJpbGwgU2NoZXJlciBhbmQgTWljaGFlbCBTY290dAorICogQHBhcmFtIDxFPiB0aGUgdHlwZSBvZiBlbGVtZW50cyBoZWxkIGluIHRoaXMgY29sbGVjdGlvbgorICovCitwdWJsaWMgY2xhc3MgU3luY2hyb25vdXNRdWV1ZTxFPiBleHRlbmRzIEFic3RyYWN0UXVldWU8RT4KKyAgICBpbXBsZW1lbnRzIEJsb2NraW5nUXVldWU8RT4sIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzIyMzExMzQxMDI0ODE2MzY4Nkw7CisKKyAgICAvKgorICAgICAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBleHRlbnNpb25zIG9mIHRoZSBkdWFsIHN0YWNrIGFuZCBkdWFsCisgICAgICogcXVldWUgYWxnb3JpdGhtcyBkZXNjcmliZWQgaW4gIk5vbmJsb2NraW5nIENvbmN1cnJlbnQgT2JqZWN0cworICAgICAqIHdpdGggQ29uZGl0aW9uIFN5bmNocm9uaXphdGlvbiIsIGJ5IFcuIE4uIFNjaGVyZXIgSUlJIGFuZAorICAgICAqIE0uIEwuIFNjb3R0LiAgMTh0aCBBbm51YWwgQ29uZi4gb24gRGlzdHJpYnV0ZWQgQ29tcHV0aW5nLAorICAgICAqIE9jdC4gMjAwNCAoc2VlIGFsc28KKyAgICAgKiBodHRwOi8vd3d3LmNzLnJvY2hlc3Rlci5lZHUvdS9zY290dC9zeW5jaHJvbml6YXRpb24vcHNldWRvY29kZS9kdWFscy5odG1sKS4KKyAgICAgKiBUaGUgKExpZm8pIHN0YWNrIGlzIHVzZWQgZm9yIG5vbi1mYWlyIG1vZGUsIGFuZCB0aGUgKEZpZm8pCisgICAgICogcXVldWUgZm9yIGZhaXIgbW9kZS4gVGhlIHBlcmZvcm1hbmNlIG9mIHRoZSB0d28gaXMgZ2VuZXJhbGx5CisgICAgICogc2ltaWxhci4gRmlmbyB1c3VhbGx5IHN1cHBvcnRzIGhpZ2hlciB0aHJvdWdocHV0IHVuZGVyCisgICAgICogY29udGVudGlvbiBidXQgTGlmbyBtYWludGFpbnMgaGlnaGVyIHRocmVhZCBsb2NhbGl0eSBpbiBjb21tb24KKyAgICAgKiBhcHBsaWNhdGlvbnMuCisgICAgICoKKyAgICAgKiBBIGR1YWwgcXVldWUgKGFuZCBzaW1pbGFybHkgc3RhY2spIGlzIG9uZSB0aGF0IGF0IGFueSBnaXZlbgorICAgICAqIHRpbWUgZWl0aGVyIGhvbGRzICJkYXRhIiAtLSBpdGVtcyBwcm92aWRlZCBieSBwdXQgb3BlcmF0aW9ucywKKyAgICAgKiBvciAicmVxdWVzdHMiIC0tIHNsb3RzIHJlcHJlc2VudGluZyB0YWtlIG9wZXJhdGlvbnMsIG9yIGlzCisgICAgICogZW1wdHkuIEEgY2FsbCB0byAiZnVsZmlsbCIgKGkuZS4sIGEgY2FsbCByZXF1ZXN0aW5nIGFuIGl0ZW0KKyAgICAgKiBmcm9tIGEgcXVldWUgaG9sZGluZyBkYXRhIG9yIHZpY2UgdmVyc2EpIGRlcXVldWVzIGEKKyAgICAgKiBjb21wbGVtZW50YXJ5IG5vZGUuICBUaGUgbW9zdCBpbnRlcmVzdGluZyBmZWF0dXJlIG9mIHRoZXNlCisgICAgICogcXVldWVzIGlzIHRoYXQgYW55IG9wZXJhdGlvbiBjYW4gZmlndXJlIG91dCB3aGljaCBtb2RlIHRoZQorICAgICAqIHF1ZXVlIGlzIGluLCBhbmQgYWN0IGFjY29yZGluZ2x5IHdpdGhvdXQgbmVlZGluZyBsb2Nrcy4KKyAgICAgKgorICAgICAqIEJvdGggdGhlIHF1ZXVlIGFuZCBzdGFjayBleHRlbmQgYWJzdHJhY3QgY2xhc3MgVHJhbnNmZXJlcgorICAgICAqIGRlZmluaW5nIHRoZSBzaW5nbGUgbWV0aG9kIHRyYW5zZmVyIHRoYXQgZG9lcyBhIHB1dCBvciBhCisgICAgICogdGFrZS4gVGhlc2UgYXJlIHVuaWZpZWQgaW50byBhIHNpbmdsZSBtZXRob2QgYmVjYXVzZSBpbiBkdWFsCisgICAgICogZGF0YSBzdHJ1Y3R1cmVzLCB0aGUgcHV0IGFuZCB0YWtlIG9wZXJhdGlvbnMgYXJlIHN5bW1ldHJpY2FsLAorICAgICAqIHNvIG5lYXJseSBhbGwgY29kZSBjYW4gYmUgY29tYmluZWQuIFRoZSByZXN1bHRpbmcgdHJhbnNmZXIKKyAgICAgKiBtZXRob2RzIGFyZSBvbiB0aGUgbG9uZyBzaWRlLCBidXQgYXJlIGVhc2llciB0byBmb2xsb3cgdGhhbgorICAgICAqIHRoZXkgd291bGQgYmUgaWYgYnJva2VuIHVwIGludG8gbmVhcmx5LWR1cGxpY2F0ZWQgcGFydHMuCisgICAgICoKKyAgICAgKiBUaGUgcXVldWUgYW5kIHN0YWNrIGRhdGEgc3RydWN0dXJlcyBzaGFyZSBtYW55IGNvbmNlcHR1YWwKKyAgICAgKiBzaW1pbGFyaXRpZXMgYnV0IHZlcnkgZmV3IGNvbmNyZXRlIGRldGFpbHMuIEZvciBzaW1wbGljaXR5LAorICAgICAqIHRoZXkgYXJlIGtlcHQgZGlzdGluY3Qgc28gdGhhdCB0aGV5IGNhbiBsYXRlciBldm9sdmUKKyAgICAgKiBzZXBhcmF0ZWx5LgorICAgICAqCisgICAgICogVGhlIGFsZ29yaXRobXMgaGVyZSBkaWZmZXIgZnJvbSB0aGUgdmVyc2lvbnMgaW4gdGhlIGFib3ZlIHBhcGVyCisgICAgICogaW4gZXh0ZW5kaW5nIHRoZW0gZm9yIHVzZSBpbiBzeW5jaHJvbm91cyBxdWV1ZXMsIGFzIHdlbGwgYXMKKyAgICAgKiBkZWFsaW5nIHdpdGggY2FuY2VsbGF0aW9uLiBUaGUgbWFpbiBkaWZmZXJlbmNlcyBpbmNsdWRlOgorICAgICAqCisgICAgICogIDEuIFRoZSBvcmlnaW5hbCBhbGdvcml0aG1zIHVzZWQgYml0LW1hcmtlZCBwb2ludGVycywgYnV0CisgICAgICogICAgIHRoZSBvbmVzIGhlcmUgdXNlIG1vZGUgYml0cyBpbiBub2RlcywgbGVhZGluZyB0byBhIG51bWJlcgorICAgICAqICAgICBvZiBmdXJ0aGVyIGFkYXB0YXRpb25zLgorICAgICAqICAyLiBTeW5jaHJvbm91c1F1ZXVlcyBtdXN0IGJsb2NrIHRocmVhZHMgd2FpdGluZyB0byBiZWNvbWUKKyAgICAgKiAgICAgZnVsZmlsbGVkLgorICAgICAqICAzLiBTdXBwb3J0IGZvciBjYW5jZWxsYXRpb24gdmlhIHRpbWVvdXQgYW5kIGludGVycnVwdHMsCisgICAgICogICAgIGluY2x1ZGluZyBjbGVhbmluZyBvdXQgY2FuY2VsbGVkIG5vZGVzL3RocmVhZHMKKyAgICAgKiAgICAgZnJvbSBsaXN0cyB0byBhdm9pZCBnYXJiYWdlIHJldGVudGlvbiBhbmQgbWVtb3J5IGRlcGxldGlvbi4KKyAgICAgKgorICAgICAqIEJsb2NraW5nIGlzIG1haW5seSBhY2NvbXBsaXNoZWQgdXNpbmcgTG9ja1N1cHBvcnQgcGFyay91bnBhcmssCisgICAgICogZXhjZXB0IHRoYXQgbm9kZXMgdGhhdCBhcHBlYXIgdG8gYmUgdGhlIG5leHQgb25lcyB0byBiZWNvbWUKKyAgICAgKiBmdWxmaWxsZWQgZmlyc3Qgc3BpbiBhIGJpdCAob24gbXVsdGlwcm9jZXNzb3JzIG9ubHkpLiBPbiB2ZXJ5CisgICAgICogYnVzeSBzeW5jaHJvbm91cyBxdWV1ZXMsIHNwaW5uaW5nIGNhbiBkcmFtYXRpY2FsbHkgaW1wcm92ZQorICAgICAqIHRocm91Z2hwdXQuIEFuZCBvbiBsZXNzIGJ1c3kgb25lcywgdGhlIGFtb3VudCBvZiBzcGlubmluZyBpcworICAgICAqIHNtYWxsIGVub3VnaCBub3QgdG8gYmUgbm90aWNlYWJsZS4KKyAgICAgKgorICAgICAqIENsZWFuaW5nIGlzIGRvbmUgaW4gZGlmZmVyZW50IHdheXMgaW4gcXVldWVzIHZzIHN0YWNrcy4gIEZvcgorICAgICAqIHF1ZXVlcywgd2UgY2FuIGFsbW9zdCBhbHdheXMgcmVtb3ZlIGEgbm9kZSBpbW1lZGlhdGVseSBpbiBPKDEpCisgICAgICogdGltZSAobW9kdWxvIHJldHJpZXMgZm9yIGNvbnNpc3RlbmN5IGNoZWNrcykgd2hlbiBpdCBpcworICAgICAqIGNhbmNlbGxlZC4gQnV0IGlmIGl0IG1heSBiZSBwaW5uZWQgYXMgdGhlIGN1cnJlbnQgdGFpbCwgaXQgbXVzdAorICAgICAqIHdhaXQgdW50aWwgc29tZSBzdWJzZXF1ZW50IGNhbmNlbGxhdGlvbi4gRm9yIHN0YWNrcywgd2UgbmVlZCBhCisgICAgICogcG90ZW50aWFsbHkgTyhuKSB0cmF2ZXJzYWwgdG8gYmUgc3VyZSB0aGF0IHdlIGNhbiByZW1vdmUgdGhlCisgICAgICogbm9kZSwgYnV0IHRoaXMgY2FuIHJ1biBjb25jdXJyZW50bHkgd2l0aCBvdGhlciB0aHJlYWRzCisgICAgICogYWNjZXNzaW5nIHRoZSBzdGFjay4KKyAgICAgKgorICAgICAqIFdoaWxlIGdhcmJhZ2UgY29sbGVjdGlvbiB0YWtlcyBjYXJlIG9mIG1vc3Qgbm9kZSByZWNsYW1hdGlvbgorICAgICAqIGlzc3VlcyB0aGF0IG90aGVyd2lzZSBjb21wbGljYXRlIG5vbmJsb2NraW5nIGFsZ29yaXRobXMsIGNhcmUKKyAgICAgKiBpcyB0YWtlbiB0byAiZm9yZ2V0IiByZWZlcmVuY2VzIHRvIGRhdGEsIG90aGVyIG5vZGVzLCBhbmQKKyAgICAgKiB0aHJlYWRzIHRoYXQgbWlnaHQgYmUgaGVsZCBvbiB0byBsb25nLXRlcm0gYnkgYmxvY2tlZAorICAgICAqIHRocmVhZHMuIEluIGNhc2VzIHdoZXJlIHNldHRpbmcgdG8gbnVsbCB3b3VsZCBvdGhlcndpc2UKKyAgICAgKiBjb25mbGljdCB3aXRoIG1haW4gYWxnb3JpdGhtcywgdGhpcyBpcyBkb25lIGJ5IGNoYW5naW5nIGEKKyAgICAgKiBub2RlJ3MgbGluayB0byBub3cgcG9pbnQgdG8gdGhlIG5vZGUgaXRzZWxmLiBUaGlzIGRvZXNuJ3QgYXJpc2UKKyAgICAgKiBtdWNoIGZvciBTdGFjayBub2RlcyAoYmVjYXVzZSBibG9ja2VkIHRocmVhZHMgZG8gbm90IGhhbmcgb24gdG8KKyAgICAgKiBvbGQgaGVhZCBwb2ludGVycyksIGJ1dCByZWZlcmVuY2VzIGluIFF1ZXVlIG5vZGVzIG11c3QgYmUKKyAgICAgKiBhZ2dyZXNzaXZlbHkgZm9yZ290dGVuIHRvIGF2b2lkIHJlYWNoYWJpbGl0eSBvZiBldmVyeXRoaW5nIGFueQorICAgICAqIG5vZGUgaGFzIGV2ZXIgcmVmZXJyZWQgdG8gc2luY2UgYXJyaXZhbC4KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIFNoYXJlZCBpbnRlcm5hbCBBUEkgZm9yIGR1YWwgc3RhY2tzIGFuZCBxdWV1ZXMuCisgICAgICovCisgICAgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIFRyYW5zZmVyZXIgeworICAgICAgICAvKioKKyAgICAgICAgICogUGVyZm9ybXMgYSBwdXQgb3IgdGFrZS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIGUgaWYgbm9uLW51bGwsIHRoZSBpdGVtIHRvIGJlIGhhbmRlZCB0byBhIGNvbnN1bWVyOworICAgICAgICAgKiAgICAgICAgICBpZiBudWxsLCByZXF1ZXN0cyB0aGF0IHRyYW5zZmVyIHJldHVybiBhbiBpdGVtCisgICAgICAgICAqICAgICAgICAgIG9mZmVyZWQgYnkgcHJvZHVjZXIuCisgICAgICAgICAqIEBwYXJhbSB0aW1lZCBpZiB0aGlzIG9wZXJhdGlvbiBzaG91bGQgdGltZW91dAorICAgICAgICAgKiBAcGFyYW0gbmFub3MgdGhlIHRpbWVvdXQsIGluIG5hbm9zZWNvbmRzCisgICAgICAgICAqIEByZXR1cm4gaWYgbm9uLW51bGwsIHRoZSBpdGVtIHByb3ZpZGVkIG9yIHJlY2VpdmVkOyBpZiBudWxsLAorICAgICAgICAgKiAgICAgICAgIHRoZSBvcGVyYXRpb24gZmFpbGVkIGR1ZSB0byB0aW1lb3V0IG9yIGludGVycnVwdCAtLQorICAgICAgICAgKiAgICAgICAgIHRoZSBjYWxsZXIgY2FuIGRpc3Rpbmd1aXNoIHdoaWNoIG9mIHRoZXNlIG9jY3VycmVkCisgICAgICAgICAqICAgICAgICAgYnkgY2hlY2tpbmcgVGhyZWFkLmludGVycnVwdGVkLgorICAgICAgICAgKi8KKyAgICAgICAgYWJzdHJhY3QgT2JqZWN0IHRyYW5zZmVyKE9iamVjdCBlLCBib29sZWFuIHRpbWVkLCBsb25nIG5hbm9zKTsKKyAgICB9CisKKyAgICAvKiogVGhlIG51bWJlciBvZiBDUFVzLCBmb3Igc3BpbiBjb250cm9sICovCisgICAgc3RhdGljIGZpbmFsIGludCBOQ1BVUyA9IFJ1bnRpbWUuZ2V0UnVudGltZSgpLmF2YWlsYWJsZVByb2Nlc3NvcnMoKTsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgdGltZXMgdG8gc3BpbiBiZWZvcmUgYmxvY2tpbmcgaW4gdGltZWQgd2FpdHMuCisgICAgICogVGhlIHZhbHVlIGlzIGVtcGlyaWNhbGx5IGRlcml2ZWQgLS0gaXQgd29ya3Mgd2VsbCBhY3Jvc3MgYQorICAgICAqIHZhcmlldHkgb2YgcHJvY2Vzc29ycyBhbmQgT1Nlcy4gRW1waXJpY2FsbHksIHRoZSBiZXN0IHZhbHVlCisgICAgICogc2VlbXMgbm90IHRvIHZhcnkgd2l0aCBudW1iZXIgb2YgQ1BVcyAoYmV5b25kIDIpIHNvIGlzIGp1c3QKKyAgICAgKiBhIGNvbnN0YW50LgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBpbnQgbWF4VGltZWRTcGlucyA9IChOQ1BVUyA8IDIpID8gMCA6IDMyOworCisgICAgLyoqCisgICAgICogVGhlIG51bWJlciBvZiB0aW1lcyB0byBzcGluIGJlZm9yZSBibG9ja2luZyBpbiB1bnRpbWVkIHdhaXRzLgorICAgICAqIFRoaXMgaXMgZ3JlYXRlciB0aGFuIHRpbWVkIHZhbHVlIGJlY2F1c2UgdW50aW1lZCB3YWl0cyBzcGluCisgICAgICogZmFzdGVyIHNpbmNlIHRoZXkgZG9uJ3QgbmVlZCB0byBjaGVjayB0aW1lcyBvbiBlYWNoIHNwaW4uCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGludCBtYXhVbnRpbWVkU3BpbnMgPSBtYXhUaW1lZFNwaW5zICogMTY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtYmVyIG9mIG5hbm9zZWNvbmRzIGZvciB3aGljaCBpdCBpcyBmYXN0ZXIgdG8gc3BpbgorICAgICAqIHJhdGhlciB0aGFuIHRvIHVzZSB0aW1lZCBwYXJrLiBBIHJvdWdoIGVzdGltYXRlIHN1ZmZpY2VzLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBsb25nIHNwaW5Gb3JUaW1lb3V0VGhyZXNob2xkID0gMTAwMEw7CisKKyAgICAvKiogRHVhbCBzdGFjayAqLworICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBUcmFuc2ZlclN0YWNrIGV4dGVuZHMgVHJhbnNmZXJlciB7CisgICAgICAgIC8qCisgICAgICAgICAqIFRoaXMgZXh0ZW5kcyBTY2hlcmVyLVNjb3R0IGR1YWwgc3RhY2sgYWxnb3JpdGhtLCBkaWZmZXJpbmcsCisgICAgICAgICAqIGFtb25nIG90aGVyIHdheXMsIGJ5IHVzaW5nICJjb3ZlcmluZyIgbm9kZXMgcmF0aGVyIHRoYW4KKyAgICAgICAgICogYml0LW1hcmtlZCBwb2ludGVyczogRnVsZmlsbGluZyBvcGVyYXRpb25zIHB1c2ggb24gbWFya2VyCisgICAgICAgICAqIG5vZGVzICh3aXRoIEZVTEZJTExJTkcgYml0IHNldCBpbiBtb2RlKSB0byByZXNlcnZlIGEgc3BvdAorICAgICAgICAgKiB0byBtYXRjaCBhIHdhaXRpbmcgbm9kZS4KKyAgICAgICAgICovCisKKyAgICAgICAgLyogTW9kZXMgZm9yIFNOb2RlcywgT1JlZCB0b2dldGhlciBpbiBub2RlIGZpZWxkcyAqLworICAgICAgICAvKiogTm9kZSByZXByZXNlbnRzIGFuIHVuZnVsZmlsbGVkIGNvbnN1bWVyICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgUkVRVUVTVCAgICA9IDA7CisgICAgICAgIC8qKiBOb2RlIHJlcHJlc2VudHMgYW4gdW5mdWxmaWxsZWQgcHJvZHVjZXIgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIGludCBEQVRBICAgICAgID0gMTsKKyAgICAgICAgLyoqIE5vZGUgaXMgZnVsZmlsbGluZyBhbm90aGVyIHVuZnVsZmlsbGVkIERBVEEgb3IgUkVRVUVTVCAqLworICAgICAgICBzdGF0aWMgZmluYWwgaW50IEZVTEZJTExJTkcgPSAyOworCisgICAgICAgIC8qKiBSZXR1cm4gdHJ1ZSBpZiBtIGhhcyBmdWxmaWxsaW5nIGJpdCBzZXQgKi8KKyAgICAgICAgc3RhdGljIGJvb2xlYW4gaXNGdWxmaWxsaW5nKGludCBtKSB7IHJldHVybiAobSAmIEZVTEZJTExJTkcpICE9IDA7IH0KKworICAgICAgICAvKiogTm9kZSBjbGFzcyBmb3IgVHJhbnNmZXJTdGFja3MuICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBTTm9kZSB7CisgICAgICAgICAgICB2b2xhdGlsZSBTTm9kZSBuZXh0OyAgICAgICAgLy8gbmV4dCBub2RlIGluIHN0YWNrCisgICAgICAgICAgICB2b2xhdGlsZSBTTm9kZSBtYXRjaDsgICAgICAgLy8gdGhlIG5vZGUgbWF0Y2hlZCB0byB0aGlzCisgICAgICAgICAgICB2b2xhdGlsZSBUaHJlYWQgd2FpdGVyOyAgICAgLy8gdG8gY29udHJvbCBwYXJrL3VucGFyaworICAgICAgICAgICAgT2JqZWN0IGl0ZW07ICAgICAgICAgICAgICAgIC8vIGRhdGE7IG9yIG51bGwgZm9yIFJFUVVFU1RzCisgICAgICAgICAgICBpbnQgbW9kZTsKKyAgICAgICAgICAgIC8vIE5vdGU6IGl0ZW0gYW5kIG1vZGUgZmllbGRzIGRvbid0IG5lZWQgdG8gYmUgdm9sYXRpbGUKKyAgICAgICAgICAgIC8vIHNpbmNlIHRoZXkgYXJlIGFsd2F5cyB3cml0dGVuIGJlZm9yZSwgYW5kIHJlYWQgYWZ0ZXIsCisgICAgICAgICAgICAvLyBvdGhlciB2b2xhdGlsZS9hdG9taWMgb3BlcmF0aW9ucy4KKworICAgICAgICAgICAgU05vZGUoT2JqZWN0IGl0ZW0pIHsKKyAgICAgICAgICAgICAgICB0aGlzLml0ZW0gPSBpdGVtOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBib29sZWFuIGNhc05leHQoU05vZGUgY21wLCBTTm9kZSB2YWwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY21wID09IG5leHQgJiYKKyAgICAgICAgICAgICAgICAgICAgVU5TQUZFLmNvbXBhcmVBbmRTd2FwT2JqZWN0KHRoaXMsIG5leHRPZmZzZXQsIGNtcCwgdmFsKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgKiBUcmllcyB0byBtYXRjaCBub2RlIHMgdG8gdGhpcyBub2RlLCBpZiBzbywgd2FraW5nIHVwIHRocmVhZC4KKyAgICAgICAgICAgICAqIEZ1bGZpbGxlcnMgY2FsbCB0cnlNYXRjaCB0byBpZGVudGlmeSB0aGVpciB3YWl0ZXJzLgorICAgICAgICAgICAgICogV2FpdGVycyBibG9jayB1bnRpbCB0aGV5IGhhdmUgYmVlbiBtYXRjaGVkLgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIEBwYXJhbSBzIHRoZSBub2RlIHRvIG1hdGNoCisgICAgICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgc3VjY2Vzc2Z1bGx5IG1hdGNoZWQgdG8gcworICAgICAgICAgICAgICovCisgICAgICAgICAgICBib29sZWFuIHRyeU1hdGNoKFNOb2RlIHMpIHsKKyAgICAgICAgICAgICAgICBpZiAobWF0Y2ggPT0gbnVsbCAmJgorICAgICAgICAgICAgICAgICAgICBVTlNBRkUuY29tcGFyZUFuZFN3YXBPYmplY3QodGhpcywgbWF0Y2hPZmZzZXQsIG51bGwsIHMpKSB7CisgICAgICAgICAgICAgICAgICAgIFRocmVhZCB3ID0gd2FpdGVyOworICAgICAgICAgICAgICAgICAgICBpZiAodyAhPSBudWxsKSB7ICAgIC8vIHdhaXRlcnMgbmVlZCBhdCBtb3N0IG9uZSB1bnBhcmsKKyAgICAgICAgICAgICAgICAgICAgICAgIHdhaXRlciA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgICAgICBMb2NrU3VwcG9ydC51bnBhcmsodyk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaCA9PSBzOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgICAqIFRyaWVzIHRvIGNhbmNlbCBhIHdhaXQgYnkgbWF0Y2hpbmcgbm9kZSB0byBpdHNlbGYuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHZvaWQgdHJ5Q2FuY2VsKCkgeworICAgICAgICAgICAgICAgIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCBtYXRjaE9mZnNldCwgbnVsbCwgdGhpcyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGJvb2xlYW4gaXNDYW5jZWxsZWQoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoID09IHRoaXM7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIFVuc2FmZSBtZWNoYW5pY3MKKyAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHN1bi5taXNjLlVuc2FmZSBVTlNBRkUgPSBzdW4ubWlzYy5VbnNhZmUuZ2V0VW5zYWZlKCk7CisgICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIG5leHRPZmZzZXQgPQorICAgICAgICAgICAgICAgIG9iamVjdEZpZWxkT2Zmc2V0KFVOU0FGRSwgIm5leHQiLCBTTm9kZS5jbGFzcyk7CisgICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIG1hdGNoT2Zmc2V0ID0KKyAgICAgICAgICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJtYXRjaCIsIFNOb2RlLmNsYXNzKTsKKworICAgICAgICB9CisKKyAgICAgICAgLyoqIFRoZSBoZWFkICh0b3ApIG9mIHRoZSBzdGFjayAqLworICAgICAgICB2b2xhdGlsZSBTTm9kZSBoZWFkOworCisgICAgICAgIGJvb2xlYW4gY2FzSGVhZChTTm9kZSBoLCBTTm9kZSBuaCkgeworICAgICAgICAgICAgcmV0dXJuIGggPT0gaGVhZCAmJgorICAgICAgICAgICAgICAgIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCBoZWFkT2Zmc2V0LCBoLCBuaCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBvciByZXNldHMgZmllbGRzIG9mIGEgbm9kZS4gQ2FsbGVkIG9ubHkgZnJvbSB0cmFuc2ZlcgorICAgICAgICAgKiB3aGVyZSB0aGUgbm9kZSB0byBwdXNoIG9uIHN0YWNrIGlzIGxhemlseSBjcmVhdGVkIGFuZAorICAgICAgICAgKiByZXVzZWQgd2hlbiBwb3NzaWJsZSB0byBoZWxwIHJlZHVjZSBpbnRlcnZhbHMgYmV0d2VlbiByZWFkcworICAgICAgICAgKiBhbmQgQ0FTZXMgb2YgaGVhZCBhbmQgdG8gYXZvaWQgc3VyZ2VzIG9mIGdhcmJhZ2Ugd2hlbiBDQVNlcworICAgICAgICAgKiB0byBwdXNoIG5vZGVzIGZhaWwgZHVlIHRvIGNvbnRlbnRpb24uCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgU05vZGUgc25vZGUoU05vZGUgcywgT2JqZWN0IGUsIFNOb2RlIG5leHQsIGludCBtb2RlKSB7CisgICAgICAgICAgICBpZiAocyA9PSBudWxsKSBzID0gbmV3IFNOb2RlKGUpOworICAgICAgICAgICAgcy5tb2RlID0gbW9kZTsKKyAgICAgICAgICAgIHMubmV4dCA9IG5leHQ7CisgICAgICAgICAgICByZXR1cm4gczsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBQdXRzIG9yIHRha2VzIGFuIGl0ZW0uCisgICAgICAgICAqLworICAgICAgICBPYmplY3QgdHJhbnNmZXIoT2JqZWN0IGUsIGJvb2xlYW4gdGltZWQsIGxvbmcgbmFub3MpIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBCYXNpYyBhbGdvcml0aG0gaXMgdG8gbG9vcCB0cnlpbmcgb25lIG9mIHRocmVlIGFjdGlvbnM6CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogMS4gSWYgYXBwYXJlbnRseSBlbXB0eSBvciBhbHJlYWR5IGNvbnRhaW5pbmcgbm9kZXMgb2Ygc2FtZQorICAgICAgICAgICAgICogICAgbW9kZSwgdHJ5IHRvIHB1c2ggbm9kZSBvbiBzdGFjayBhbmQgd2FpdCBmb3IgYSBtYXRjaCwKKyAgICAgICAgICAgICAqICAgIHJldHVybmluZyBpdCwgb3IgbnVsbCBpZiBjYW5jZWxsZWQuCisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogMi4gSWYgYXBwYXJlbnRseSBjb250YWluaW5nIG5vZGUgb2YgY29tcGxlbWVudGFyeSBtb2RlLAorICAgICAgICAgICAgICogICAgdHJ5IHRvIHB1c2ggYSBmdWxmaWxsaW5nIG5vZGUgb24gdG8gc3RhY2ssIG1hdGNoCisgICAgICAgICAgICAgKiAgICB3aXRoIGNvcnJlc3BvbmRpbmcgd2FpdGluZyBub2RlLCBwb3AgYm90aCBmcm9tCisgICAgICAgICAgICAgKiAgICBzdGFjaywgYW5kIHJldHVybiBtYXRjaGVkIGl0ZW0uIFRoZSBtYXRjaGluZyBvcgorICAgICAgICAgICAgICogICAgdW5saW5raW5nIG1pZ2h0IG5vdCBhY3R1YWxseSBiZSBuZWNlc3NhcnkgYmVjYXVzZSBvZgorICAgICAgICAgICAgICogICAgb3RoZXIgdGhyZWFkcyBwZXJmb3JtaW5nIGFjdGlvbiAzOgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIDMuIElmIHRvcCBvZiBzdGFjayBhbHJlYWR5IGhvbGRzIGFub3RoZXIgZnVsZmlsbGluZyBub2RlLAorICAgICAgICAgICAgICogICAgaGVscCBpdCBvdXQgYnkgZG9pbmcgaXRzIG1hdGNoIGFuZC9vciBwb3AKKyAgICAgICAgICAgICAqICAgIG9wZXJhdGlvbnMsIGFuZCB0aGVuIGNvbnRpbnVlLiBUaGUgY29kZSBmb3IgaGVscGluZworICAgICAgICAgICAgICogICAgaXMgZXNzZW50aWFsbHkgdGhlIHNhbWUgYXMgZm9yIGZ1bGZpbGxpbmcsIGV4Y2VwdAorICAgICAgICAgICAgICogICAgdGhhdCBpdCBkb2Vzbid0IHJldHVybiB0aGUgaXRlbS4KKyAgICAgICAgICAgICAqLworCisgICAgICAgICAgICBTTm9kZSBzID0gbnVsbDsgLy8gY29uc3RydWN0ZWQvcmV1c2VkIGFzIG5lZWRlZAorICAgICAgICAgICAgaW50IG1vZGUgPSAoZSA9PSBudWxsKSA/IFJFUVVFU1QgOiBEQVRBOworCisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgU05vZGUgaCA9IGhlYWQ7CisgICAgICAgICAgICAgICAgaWYgKGggPT0gbnVsbCB8fCBoLm1vZGUgPT0gbW9kZSkgeyAgLy8gZW1wdHkgb3Igc2FtZS1tb2RlCisgICAgICAgICAgICAgICAgICAgIGlmICh0aW1lZCAmJiBuYW5vcyA8PSAwKSB7ICAgICAgLy8gY2FuJ3Qgd2FpdAorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGggIT0gbnVsbCAmJiBoLmlzQ2FuY2VsbGVkKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzSGVhZChoLCBoLm5leHQpOyAgICAgLy8gcG9wIGNhbmNlbGxlZCBub2RlCisgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2FzSGVhZChoLCBzID0gc25vZGUocywgZSwgaCwgbW9kZSkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBTTm9kZSBtID0gYXdhaXRGdWxmaWxsKHMsIHRpbWVkLCBuYW5vcyk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAobSA9PSBzKSB7ICAgICAgICAgICAgICAgLy8gd2FpdCB3YXMgY2FuY2VsbGVkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYW4ocyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGggPSBoZWFkKSAhPSBudWxsICYmIGgubmV4dCA9PSBzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc0hlYWQoaCwgcy5uZXh0KTsgICAgIC8vIGhlbHAgcydzIGZ1bGZpbGxlcgorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChtb2RlID09IFJFUVVFU1QpID8gbS5pdGVtIDogcy5pdGVtOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNGdWxmaWxsaW5nKGgubW9kZSkpIHsgLy8gdHJ5IHRvIGZ1bGZpbGwKKyAgICAgICAgICAgICAgICAgICAgaWYgKGguaXNDYW5jZWxsZWQoKSkgICAgICAgICAgICAvLyBhbHJlYWR5IGNhbmNlbGxlZAorICAgICAgICAgICAgICAgICAgICAgICAgY2FzSGVhZChoLCBoLm5leHQpOyAgICAgICAgIC8vIHBvcCBhbmQgcmV0cnkKKyAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY2FzSGVhZChoLCBzPXNub2RlKHMsIGUsIGgsIEZVTEZJTExJTkd8bW9kZSkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDs7KSB7IC8vIGxvb3AgdW50aWwgbWF0Y2hlZCBvciB3YWl0ZXJzIGRpc2FwcGVhcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOb2RlIG0gPSBzLm5leHQ7ICAgICAgIC8vIG0gaXMgcydzIG1hdGNoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG0gPT0gbnVsbCkgeyAgICAgICAgLy8gYWxsIHdhaXRlcnMgYXJlIGdvbmUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzSGVhZChzLCBudWxsKTsgICAvLyBwb3AgZnVsZmlsbCBub2RlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBudWxsOyAgICAgICAgICAgLy8gdXNlIG5ldyBub2RlIG5leHQgdGltZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsgICAgICAgICAgICAgIC8vIHJlc3RhcnQgbWFpbiBsb29wCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOb2RlIG1uID0gbS5uZXh0OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtLnRyeU1hdGNoKHMpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc0hlYWQocywgbW4pOyAgICAgLy8gcG9wIGJvdGggcyBhbmQgbQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKG1vZGUgPT0gUkVRVUVTVCkgPyBtLml0ZW0gOiBzLml0ZW07CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlICAgICAgICAgICAgICAgICAgLy8gbG9zdCBtYXRjaAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzLmNhc05leHQobSwgbW4pOyAgIC8vIGhlbHAgdW5saW5rCisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBoZWxwIGEgZnVsZmlsbGVyCisgICAgICAgICAgICAgICAgICAgIFNOb2RlIG0gPSBoLm5leHQ7ICAgICAgICAgICAgICAgLy8gbSBpcyBoJ3MgbWF0Y2gKKyAgICAgICAgICAgICAgICAgICAgaWYgKG0gPT0gbnVsbCkgICAgICAgICAgICAgICAgICAvLyB3YWl0ZXIgaXMgZ29uZQorICAgICAgICAgICAgICAgICAgICAgICAgY2FzSGVhZChoLCBudWxsKTsgICAgICAgICAgIC8vIHBvcCBmdWxmaWxsaW5nIG5vZGUKKyAgICAgICAgICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBTTm9kZSBtbiA9IG0ubmV4dDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtLnRyeU1hdGNoKGgpKSAgICAgICAgICAvLyBoZWxwIG1hdGNoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzSGVhZChoLCBtbik7ICAgICAgICAgLy8gcG9wIGJvdGggaCBhbmQgbQorICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvc3QgbWF0Y2gKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBoLmNhc05leHQobSwgbW4pOyAgICAgICAvLyBoZWxwIHVubGluaworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNwaW5zL2Jsb2NrcyB1bnRpbCBub2RlIHMgaXMgbWF0Y2hlZCBieSBhIGZ1bGZpbGwgb3BlcmF0aW9uLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gcyB0aGUgd2FpdGluZyBub2RlCisgICAgICAgICAqIEBwYXJhbSB0aW1lZCB0cnVlIGlmIHRpbWVkIHdhaXQKKyAgICAgICAgICogQHBhcmFtIG5hbm9zIHRpbWVvdXQgdmFsdWUKKyAgICAgICAgICogQHJldHVybiBtYXRjaGVkIG5vZGUsIG9yIHMgaWYgY2FuY2VsbGVkCisgICAgICAgICAqLworICAgICAgICBTTm9kZSBhd2FpdEZ1bGZpbGwoU05vZGUgcywgYm9vbGVhbiB0aW1lZCwgbG9uZyBuYW5vcykgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFdoZW4gYSBub2RlL3RocmVhZCBpcyBhYm91dCB0byBibG9jaywgaXQgc2V0cyBpdHMgd2FpdGVyCisgICAgICAgICAgICAgKiBmaWVsZCBhbmQgdGhlbiByZWNoZWNrcyBzdGF0ZSBhdCBsZWFzdCBvbmUgbW9yZSB0aW1lCisgICAgICAgICAgICAgKiBiZWZvcmUgYWN0dWFsbHkgcGFya2luZywgdGh1cyBjb3ZlcmluZyByYWNlIHZzCisgICAgICAgICAgICAgKiBmdWxmaWxsZXIgbm90aWNpbmcgdGhhdCB3YWl0ZXIgaXMgbm9uLW51bGwgc28gc2hvdWxkIGJlCisgICAgICAgICAgICAgKiB3b2tlbi4KKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBXaGVuIGludm9rZWQgYnkgbm9kZXMgdGhhdCBhcHBlYXIgYXQgdGhlIHBvaW50IG9mIGNhbGwKKyAgICAgICAgICAgICAqIHRvIGJlIGF0IHRoZSBoZWFkIG9mIHRoZSBzdGFjaywgY2FsbHMgdG8gcGFyayBhcmUKKyAgICAgICAgICAgICAqIHByZWNlZGVkIGJ5IHNwaW5zIHRvIGF2b2lkIGJsb2NraW5nIHdoZW4gcHJvZHVjZXJzIGFuZAorICAgICAgICAgICAgICogY29uc3VtZXJzIGFyZSBhcnJpdmluZyB2ZXJ5IGNsb3NlIGluIHRpbWUuICBUaGlzIGNhbgorICAgICAgICAgICAgICogaGFwcGVuIGVub3VnaCB0byBib3RoZXIgb25seSBvbiBtdWx0aXByb2Nlc3NvcnMuCisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogVGhlIG9yZGVyIG9mIGNoZWNrcyBmb3IgcmV0dXJuaW5nIG91dCBvZiBtYWluIGxvb3AKKyAgICAgICAgICAgICAqIHJlZmxlY3RzIGZhY3QgdGhhdCBpbnRlcnJ1cHRzIGhhdmUgcHJlY2VkZW5jZSBvdmVyCisgICAgICAgICAgICAgKiBub3JtYWwgcmV0dXJucywgd2hpY2ggaGF2ZSBwcmVjZWRlbmNlIG92ZXIKKyAgICAgICAgICAgICAqIHRpbWVvdXRzLiAoU28sIG9uIHRpbWVvdXQsIG9uZSBsYXN0IGNoZWNrIGZvciBtYXRjaCBpcworICAgICAgICAgICAgICogZG9uZSBiZWZvcmUgZ2l2aW5nIHVwLikgRXhjZXB0IHRoYXQgY2FsbHMgZnJvbSB1bnRpbWVkCisgICAgICAgICAgICAgKiBTeW5jaHJvbm91c1F1ZXVlLntwb2xsL29mZmVyfSBkb24ndCBjaGVjayBpbnRlcnJ1cHRzCisgICAgICAgICAgICAgKiBhbmQgZG9uJ3Qgd2FpdCBhdCBhbGwsIHNvIGFyZSB0cmFwcGVkIGluIHRyYW5zZmVyCisgICAgICAgICAgICAgKiBtZXRob2QgcmF0aGVyIHRoYW4gY2FsbGluZyBhd2FpdEZ1bGZpbGwuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGxvbmcgbGFzdFRpbWUgPSB0aW1lZCA/IFN5c3RlbS5uYW5vVGltZSgpIDogMDsKKyAgICAgICAgICAgIFRocmVhZCB3ID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKyAgICAgICAgICAgIFNOb2RlIGggPSBoZWFkOworICAgICAgICAgICAgaW50IHNwaW5zID0gKHNob3VsZFNwaW4ocykgPworICAgICAgICAgICAgICAgICAgICAgICAgICh0aW1lZCA/IG1heFRpbWVkU3BpbnMgOiBtYXhVbnRpbWVkU3BpbnMpIDogMCk7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgaWYgKHcuaXNJbnRlcnJ1cHRlZCgpKQorICAgICAgICAgICAgICAgICAgICBzLnRyeUNhbmNlbCgpOworICAgICAgICAgICAgICAgIFNOb2RlIG0gPSBzLm1hdGNoOworICAgICAgICAgICAgICAgIGlmIChtICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBtOworICAgICAgICAgICAgICAgIGlmICh0aW1lZCkgeworICAgICAgICAgICAgICAgICAgICBsb25nIG5vdyA9IFN5c3RlbS5uYW5vVGltZSgpOworICAgICAgICAgICAgICAgICAgICBuYW5vcyAtPSBub3cgLSBsYXN0VGltZTsKKyAgICAgICAgICAgICAgICAgICAgbGFzdFRpbWUgPSBub3c7CisgICAgICAgICAgICAgICAgICAgIGlmIChuYW5vcyA8PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzLnRyeUNhbmNlbCgpOworICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHNwaW5zID4gMCkKKyAgICAgICAgICAgICAgICAgICAgc3BpbnMgPSBzaG91bGRTcGluKHMpID8gKHNwaW5zLTEpIDogMDsKKyAgICAgICAgICAgICAgICBlbHNlIGlmIChzLndhaXRlciA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICBzLndhaXRlciA9IHc7IC8vIGVzdGFibGlzaCB3YWl0ZXIgc28gY2FuIHBhcmsgbmV4dCBpdGVyCisgICAgICAgICAgICAgICAgZWxzZSBpZiAoIXRpbWVkKQorICAgICAgICAgICAgICAgICAgICBMb2NrU3VwcG9ydC5wYXJrKHRoaXMpOworICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbm9zID4gc3BpbkZvclRpbWVvdXRUaHJlc2hvbGQpCisgICAgICAgICAgICAgICAgICAgIExvY2tTdXBwb3J0LnBhcmtOYW5vcyh0aGlzLCBuYW5vcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIG5vZGUgcyBpcyBhdCBoZWFkIG9yIHRoZXJlIGlzIGFuIGFjdGl2ZQorICAgICAgICAgKiBmdWxmaWxsZXIuCisgICAgICAgICAqLworICAgICAgICBib29sZWFuIHNob3VsZFNwaW4oU05vZGUgcykgeworICAgICAgICAgICAgU05vZGUgaCA9IGhlYWQ7CisgICAgICAgICAgICByZXR1cm4gKGggPT0gcyB8fCBoID09IG51bGwgfHwgaXNGdWxmaWxsaW5nKGgubW9kZSkpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFVubGlua3MgcyBmcm9tIHRoZSBzdGFjay4KKyAgICAgICAgICovCisgICAgICAgIHZvaWQgY2xlYW4oU05vZGUgcykgeworICAgICAgICAgICAgcy5pdGVtID0gbnVsbDsgICAvLyBmb3JnZXQgaXRlbQorICAgICAgICAgICAgcy53YWl0ZXIgPSBudWxsOyAvLyBmb3JnZXQgdGhyZWFkCisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBBdCB3b3JzdCB3ZSBtYXkgbmVlZCB0byB0cmF2ZXJzZSBlbnRpcmUgc3RhY2sgdG8gdW5saW5rCisgICAgICAgICAgICAgKiBzLiBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgY29uY3VycmVudCBjYWxscyB0byBjbGVhbiwgd2UKKyAgICAgICAgICAgICAqIG1pZ2h0IG5vdCBzZWUgcyBpZiBhbm90aGVyIHRocmVhZCBoYXMgYWxyZWFkeSByZW1vdmVkCisgICAgICAgICAgICAgKiBpdC4gQnV0IHdlIGNhbiBzdG9wIHdoZW4gd2Ugc2VlIGFueSBub2RlIGtub3duIHRvCisgICAgICAgICAgICAgKiBmb2xsb3cgcy4gV2UgdXNlIHMubmV4dCB1bmxlc3MgaXQgdG9vIGlzIGNhbmNlbGxlZCwgaW4KKyAgICAgICAgICAgICAqIHdoaWNoIGNhc2Ugd2UgdHJ5IHRoZSBub2RlIG9uZSBwYXN0LiBXZSBkb24ndCBjaGVjayBhbnkKKyAgICAgICAgICAgICAqIGZ1cnRoZXIgYmVjYXVzZSB3ZSBkb24ndCB3YW50IHRvIGRvdWJseSB0cmF2ZXJzZSBqdXN0IHRvCisgICAgICAgICAgICAgKiBmaW5kIHNlbnRpbmVsLgorICAgICAgICAgICAgICovCisKKyAgICAgICAgICAgIFNOb2RlIHBhc3QgPSBzLm5leHQ7CisgICAgICAgICAgICBpZiAocGFzdCAhPSBudWxsICYmIHBhc3QuaXNDYW5jZWxsZWQoKSkKKyAgICAgICAgICAgICAgICBwYXN0ID0gcGFzdC5uZXh0OworCisgICAgICAgICAgICAvLyBBYnNvcmIgY2FuY2VsbGVkIG5vZGVzIGF0IGhlYWQKKyAgICAgICAgICAgIFNOb2RlIHA7CisgICAgICAgICAgICB3aGlsZSAoKHAgPSBoZWFkKSAhPSBudWxsICYmIHAgIT0gcGFzdCAmJiBwLmlzQ2FuY2VsbGVkKCkpCisgICAgICAgICAgICAgICAgY2FzSGVhZChwLCBwLm5leHQpOworCisgICAgICAgICAgICAvLyBVbnNwbGljZSBlbWJlZGRlZCBub2RlcworICAgICAgICAgICAgd2hpbGUgKHAgIT0gbnVsbCAmJiBwICE9IHBhc3QpIHsKKyAgICAgICAgICAgICAgICBTTm9kZSBuID0gcC5uZXh0OworICAgICAgICAgICAgICAgIGlmIChuICE9IG51bGwgJiYgbi5pc0NhbmNlbGxlZCgpKQorICAgICAgICAgICAgICAgICAgICBwLmNhc05leHQobiwgbi5uZXh0KTsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIHAgPSBuOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gVW5zYWZlIG1lY2hhbmljcworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBzdW4ubWlzYy5VbnNhZmUgVU5TQUZFID0gc3VuLm1pc2MuVW5zYWZlLmdldFVuc2FmZSgpOworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIGhlYWRPZmZzZXQgPQorICAgICAgICAgICAgb2JqZWN0RmllbGRPZmZzZXQoVU5TQUZFLCAiaGVhZCIsIFRyYW5zZmVyU3RhY2suY2xhc3MpOworCisgICAgfQorCisgICAgLyoqIER1YWwgUXVldWUgKi8KKyAgICBzdGF0aWMgZmluYWwgY2xhc3MgVHJhbnNmZXJRdWV1ZSBleHRlbmRzIFRyYW5zZmVyZXIgeworICAgICAgICAvKgorICAgICAgICAgKiBUaGlzIGV4dGVuZHMgU2NoZXJlci1TY290dCBkdWFsIHF1ZXVlIGFsZ29yaXRobSwgZGlmZmVyaW5nLAorICAgICAgICAgKiBhbW9uZyBvdGhlciB3YXlzLCBieSB1c2luZyBtb2RlcyB3aXRoaW4gbm9kZXMgcmF0aGVyIHRoYW4KKyAgICAgICAgICogbWFya2VkIHBvaW50ZXJzLiBUaGUgYWxnb3JpdGhtIGlzIGEgbGl0dGxlIHNpbXBsZXIgdGhhbgorICAgICAgICAgKiB0aGF0IGZvciBzdGFja3MgYmVjYXVzZSBmdWxmaWxsZXJzIGRvIG5vdCBuZWVkIGV4cGxpY2l0CisgICAgICAgICAqIG5vZGVzLCBhbmQgbWF0Y2hpbmcgaXMgZG9uZSBieSBDQVMnaW5nIFFOb2RlLml0ZW0gZmllbGQKKyAgICAgICAgICogZnJvbSBub24tbnVsbCB0byBudWxsIChmb3IgcHV0KSBvciB2aWNlIHZlcnNhIChmb3IgdGFrZSkuCisgICAgICAgICAqLworCisgICAgICAgIC8qKiBOb2RlIGNsYXNzIGZvciBUcmFuc2ZlclF1ZXVlLiAqLworICAgICAgICBzdGF0aWMgZmluYWwgY2xhc3MgUU5vZGUgeworICAgICAgICAgICAgdm9sYXRpbGUgUU5vZGUgbmV4dDsgICAgICAgICAgLy8gbmV4dCBub2RlIGluIHF1ZXVlCisgICAgICAgICAgICB2b2xhdGlsZSBPYmplY3QgaXRlbTsgICAgICAgICAvLyBDQVMnZWQgdG8gb3IgZnJvbSBudWxsCisgICAgICAgICAgICB2b2xhdGlsZSBUaHJlYWQgd2FpdGVyOyAgICAgICAvLyB0byBjb250cm9sIHBhcmsvdW5wYXJrCisgICAgICAgICAgICBmaW5hbCBib29sZWFuIGlzRGF0YTsKKworICAgICAgICAgICAgUU5vZGUoT2JqZWN0IGl0ZW0sIGJvb2xlYW4gaXNEYXRhKSB7CisgICAgICAgICAgICAgICAgdGhpcy5pdGVtID0gaXRlbTsKKyAgICAgICAgICAgICAgICB0aGlzLmlzRGF0YSA9IGlzRGF0YTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYm9vbGVhbiBjYXNOZXh0KFFOb2RlIGNtcCwgUU5vZGUgdmFsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5leHQgPT0gY21wICYmCisgICAgICAgICAgICAgICAgICAgIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCBuZXh0T2Zmc2V0LCBjbXAsIHZhbCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGJvb2xlYW4gY2FzSXRlbShPYmplY3QgY21wLCBPYmplY3QgdmFsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0gPT0gY21wICYmCisgICAgICAgICAgICAgICAgICAgIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCBpdGVtT2Zmc2V0LCBjbXAsIHZhbCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qKgorICAgICAgICAgICAgICogVHJpZXMgdG8gY2FuY2VsIGJ5IENBUydpbmcgcmVmIHRvIHRoaXMgYXMgaXRlbS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgdm9pZCB0cnlDYW5jZWwoT2JqZWN0IGNtcCkgeworICAgICAgICAgICAgICAgIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCBpdGVtT2Zmc2V0LCBjbXAsIHRoaXMpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBib29sZWFuIGlzQ2FuY2VsbGVkKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBpdGVtID09IHRoaXM7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qKgorICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgbm9kZSBpcyBrbm93biB0byBiZSBvZmYgdGhlIHF1ZXVlCisgICAgICAgICAgICAgKiBiZWNhdXNlIGl0cyBuZXh0IHBvaW50ZXIgaGFzIGJlZW4gZm9yZ290dGVuIGR1ZSB0bworICAgICAgICAgICAgICogYW4gYWR2YW5jZUhlYWQgb3BlcmF0aW9uLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBib29sZWFuIGlzT2ZmTGlzdCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV4dCA9PSB0aGlzOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBVbnNhZmUgbWVjaGFuaWNzCisgICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBzdW4ubWlzYy5VbnNhZmUgVU5TQUZFID0gc3VuLm1pc2MuVW5zYWZlLmdldFVuc2FmZSgpOworICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBuZXh0T2Zmc2V0ID0KKyAgICAgICAgICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJuZXh0IiwgUU5vZGUuY2xhc3MpOworICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBpdGVtT2Zmc2V0ID0KKyAgICAgICAgICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJpdGVtIiwgUU5vZGUuY2xhc3MpOworICAgICAgICB9CisKKyAgICAgICAgLyoqIEhlYWQgb2YgcXVldWUgKi8KKyAgICAgICAgdHJhbnNpZW50IHZvbGF0aWxlIFFOb2RlIGhlYWQ7CisgICAgICAgIC8qKiBUYWlsIG9mIHF1ZXVlICovCisgICAgICAgIHRyYW5zaWVudCB2b2xhdGlsZSBRTm9kZSB0YWlsOworICAgICAgICAvKioKKyAgICAgICAgICogUmVmZXJlbmNlIHRvIGEgY2FuY2VsbGVkIG5vZGUgdGhhdCBtaWdodCBub3QgeWV0IGhhdmUgYmVlbgorICAgICAgICAgKiB1bmxpbmtlZCBmcm9tIHF1ZXVlIGJlY2F1c2UgaXQgd2FzIHRoZSBsYXN0IGluc2VydGVkIG5vZGUKKyAgICAgICAgICogd2hlbiBpdCBjYW5jZWxsZWQuCisgICAgICAgICAqLworICAgICAgICB0cmFuc2llbnQgdm9sYXRpbGUgUU5vZGUgY2xlYW5NZTsKKworICAgICAgICBUcmFuc2ZlclF1ZXVlKCkgeworICAgICAgICAgICAgUU5vZGUgaCA9IG5ldyBRTm9kZShudWxsLCBmYWxzZSk7IC8vIGluaXRpYWxpemUgdG8gZHVtbXkgbm9kZS4KKyAgICAgICAgICAgIGhlYWQgPSBoOworICAgICAgICAgICAgdGFpbCA9IGg7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogVHJpZXMgdG8gY2FzIG5oIGFzIG5ldyBoZWFkOyBpZiBzdWNjZXNzZnVsLCB1bmxpbmsKKyAgICAgICAgICogb2xkIGhlYWQncyBuZXh0IG5vZGUgdG8gYXZvaWQgZ2FyYmFnZSByZXRlbnRpb24uCisgICAgICAgICAqLworICAgICAgICB2b2lkIGFkdmFuY2VIZWFkKFFOb2RlIGgsIFFOb2RlIG5oKSB7CisgICAgICAgICAgICBpZiAoaCA9PSBoZWFkICYmCisgICAgICAgICAgICAgICAgVU5TQUZFLmNvbXBhcmVBbmRTd2FwT2JqZWN0KHRoaXMsIGhlYWRPZmZzZXQsIGgsIG5oKSkKKyAgICAgICAgICAgICAgICBoLm5leHQgPSBoOyAvLyBmb3JnZXQgb2xkIG5leHQKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBUcmllcyB0byBjYXMgbnQgYXMgbmV3IHRhaWwuCisgICAgICAgICAqLworICAgICAgICB2b2lkIGFkdmFuY2VUYWlsKFFOb2RlIHQsIFFOb2RlIG50KSB7CisgICAgICAgICAgICBpZiAodGFpbCA9PSB0KQorICAgICAgICAgICAgICAgIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCB0YWlsT2Zmc2V0LCB0LCBudCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogVHJpZXMgdG8gQ0FTIGNsZWFuTWUgc2xvdC4KKyAgICAgICAgICovCisgICAgICAgIGJvb2xlYW4gY2FzQ2xlYW5NZShRTm9kZSBjbXAsIFFOb2RlIHZhbCkgeworICAgICAgICAgICAgcmV0dXJuIGNsZWFuTWUgPT0gY21wICYmCisgICAgICAgICAgICAgICAgVU5TQUZFLmNvbXBhcmVBbmRTd2FwT2JqZWN0KHRoaXMsIGNsZWFuTWVPZmZzZXQsIGNtcCwgdmFsKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBQdXRzIG9yIHRha2VzIGFuIGl0ZW0uCisgICAgICAgICAqLworICAgICAgICBPYmplY3QgdHJhbnNmZXIoT2JqZWN0IGUsIGJvb2xlYW4gdGltZWQsIGxvbmcgbmFub3MpIHsKKyAgICAgICAgICAgIC8qIEJhc2ljIGFsZ29yaXRobSBpcyB0byBsb29wIHRyeWluZyB0byB0YWtlIGVpdGhlciBvZgorICAgICAgICAgICAgICogdHdvIGFjdGlvbnM6CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogMS4gSWYgcXVldWUgYXBwYXJlbnRseSBlbXB0eSBvciBob2xkaW5nIHNhbWUtbW9kZSBub2RlcywKKyAgICAgICAgICAgICAqICAgIHRyeSB0byBhZGQgbm9kZSB0byBxdWV1ZSBvZiB3YWl0ZXJzLCB3YWl0IHRvIGJlCisgICAgICAgICAgICAgKiAgICBmdWxmaWxsZWQgKG9yIGNhbmNlbGxlZCkgYW5kIHJldHVybiBtYXRjaGluZyBpdGVtLgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIDIuIElmIHF1ZXVlIGFwcGFyZW50bHkgY29udGFpbnMgd2FpdGluZyBpdGVtcywgYW5kIHRoaXMKKyAgICAgICAgICAgICAqICAgIGNhbGwgaXMgb2YgY29tcGxlbWVudGFyeSBtb2RlLCB0cnkgdG8gZnVsZmlsbCBieSBDQVMnaW5nCisgICAgICAgICAgICAgKiAgICBpdGVtIGZpZWxkIG9mIHdhaXRpbmcgbm9kZSBhbmQgZGVxdWV1aW5nIGl0LCBhbmQgdGhlbgorICAgICAgICAgICAgICogICAgcmV0dXJuaW5nIG1hdGNoaW5nIGl0ZW0uCisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogSW4gZWFjaCBjYXNlLCBhbG9uZyB0aGUgd2F5LCBjaGVjayBmb3IgYW5kIHRyeSB0byBoZWxwCisgICAgICAgICAgICAgKiBhZHZhbmNlIGhlYWQgYW5kIHRhaWwgb24gYmVoYWxmIG9mIG90aGVyIHN0YWxsZWQvc2xvdworICAgICAgICAgICAgICogdGhyZWFkcy4KKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBUaGUgbG9vcCBzdGFydHMgb2ZmIHdpdGggYSBudWxsIGNoZWNrIGd1YXJkaW5nIGFnYWluc3QKKyAgICAgICAgICAgICAqIHNlZWluZyB1bmluaXRpYWxpemVkIGhlYWQgb3IgdGFpbCB2YWx1ZXMuIFRoaXMgbmV2ZXIKKyAgICAgICAgICAgICAqIGhhcHBlbnMgaW4gY3VycmVudCBTeW5jaHJvbm91c1F1ZXVlLCBidXQgY291bGQgaWYKKyAgICAgICAgICAgICAqIGNhbGxlcnMgaGVsZCBub24tdm9sYXRpbGUvZmluYWwgcmVmIHRvIHRoZQorICAgICAgICAgICAgICogdHJhbnNmZXJlci4gVGhlIGNoZWNrIGlzIGhlcmUgYW55d2F5IGJlY2F1c2UgaXQgcGxhY2VzCisgICAgICAgICAgICAgKiBudWxsIGNoZWNrcyBhdCB0b3Agb2YgbG9vcCwgd2hpY2ggaXMgdXN1YWxseSBmYXN0ZXIKKyAgICAgICAgICAgICAqIHRoYW4gaGF2aW5nIHRoZW0gaW1wbGljaXRseSBpbnRlcnNwZXJzZWQuCisgICAgICAgICAgICAgKi8KKworICAgICAgICAgICAgUU5vZGUgcyA9IG51bGw7IC8vIGNvbnN0cnVjdGVkL3JldXNlZCBhcyBuZWVkZWQKKyAgICAgICAgICAgIGJvb2xlYW4gaXNEYXRhID0gKGUgIT0gbnVsbCk7CisKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBRTm9kZSB0ID0gdGFpbDsKKyAgICAgICAgICAgICAgICBRTm9kZSBoID0gaGVhZDsKKyAgICAgICAgICAgICAgICBpZiAodCA9PSBudWxsIHx8IGggPT0gbnVsbCkgICAgICAgICAvLyBzYXcgdW5pbml0aWFsaXplZCB2YWx1ZQorICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsgICAgICAgICAgICAgICAgICAgICAgIC8vIHNwaW4KKworICAgICAgICAgICAgICAgIGlmIChoID09IHQgfHwgdC5pc0RhdGEgPT0gaXNEYXRhKSB7IC8vIGVtcHR5IG9yIHNhbWUtbW9kZQorICAgICAgICAgICAgICAgICAgICBRTm9kZSB0biA9IHQubmV4dDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHQgIT0gdGFpbCkgICAgICAgICAgICAgICAgICAvLyBpbmNvbnNpc3RlbnQgcmVhZAorICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgIGlmICh0biAhPSBudWxsKSB7ICAgICAgICAgICAgICAgLy8gbGFnZ2luZyB0YWlsCisgICAgICAgICAgICAgICAgICAgICAgICBhZHZhbmNlVGFpbCh0LCB0bik7CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAodGltZWQgJiYgbmFub3MgPD0gMCkgICAgICAgIC8vIGNhbid0IHdhaXQKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICBpZiAocyA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgcyA9IG5ldyBRTm9kZShlLCBpc0RhdGEpOworICAgICAgICAgICAgICAgICAgICBpZiAoIXQuY2FzTmV4dChudWxsLCBzKSkgICAgICAgIC8vIGZhaWxlZCB0byBsaW5rIGluCisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKworICAgICAgICAgICAgICAgICAgICBhZHZhbmNlVGFpbCh0LCBzKTsgICAgICAgICAgICAgIC8vIHN3aW5nIHRhaWwgYW5kIHdhaXQKKyAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHggPSBhd2FpdEZ1bGZpbGwocywgZSwgdGltZWQsIG5hbm9zKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHggPT0gcykgeyAgICAgICAgICAgICAgICAgICAvLyB3YWl0IHdhcyBjYW5jZWxsZWQKKyAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFuKHQsIHMpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBpZiAoIXMuaXNPZmZMaXN0KCkpIHsgICAgICAgICAgIC8vIG5vdCBhbHJlYWR5IHVubGlua2VkCisgICAgICAgICAgICAgICAgICAgICAgICBhZHZhbmNlSGVhZCh0LCBzKTsgICAgICAgICAgLy8gdW5saW5rIGlmIGhlYWQKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4ICE9IG51bGwpICAgICAgICAgICAgICAvLyBhbmQgZm9yZ2V0IGZpZWxkcworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMuaXRlbSA9IHM7CisgICAgICAgICAgICAgICAgICAgICAgICBzLndhaXRlciA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh4ICE9IG51bGwpID8geCA6IGU7CisKKyAgICAgICAgICAgICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb21wbGVtZW50YXJ5LW1vZGUKKyAgICAgICAgICAgICAgICAgICAgUU5vZGUgbSA9IGgubmV4dDsgICAgICAgICAgICAgICAvLyBub2RlIHRvIGZ1bGZpbGwKKyAgICAgICAgICAgICAgICAgICAgaWYgKHQgIT0gdGFpbCB8fCBtID09IG51bGwgfHwgaCAhPSBoZWFkKQorICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7ICAgICAgICAgICAgICAgICAgIC8vIGluY29uc2lzdGVudCByZWFkCisKKyAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHggPSBtLml0ZW07CisgICAgICAgICAgICAgICAgICAgIGlmIChpc0RhdGEgPT0gKHggIT0gbnVsbCkgfHwgICAgLy8gbSBhbHJlYWR5IGZ1bGZpbGxlZAorICAgICAgICAgICAgICAgICAgICAgICAgeCA9PSBtIHx8ICAgICAgICAgICAgICAgICAgIC8vIG0gY2FuY2VsbGVkCisgICAgICAgICAgICAgICAgICAgICAgICAhbS5jYXNJdGVtKHgsIGUpKSB7ICAgICAgICAgLy8gbG9zdCBDQVMKKyAgICAgICAgICAgICAgICAgICAgICAgIGFkdmFuY2VIZWFkKGgsIG0pOyAgICAgICAgICAvLyBkZXF1ZXVlIGFuZCByZXRyeQorICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBhZHZhbmNlSGVhZChoLCBtKTsgICAgICAgICAgICAgIC8vIHN1Y2Nlc3NmdWxseSBmdWxmaWxsZWQKKyAgICAgICAgICAgICAgICAgICAgTG9ja1N1cHBvcnQudW5wYXJrKG0ud2FpdGVyKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh4ICE9IG51bGwpID8geCA6IGU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNwaW5zL2Jsb2NrcyB1bnRpbCBub2RlIHMgaXMgZnVsZmlsbGVkLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gcyB0aGUgd2FpdGluZyBub2RlCisgICAgICAgICAqIEBwYXJhbSBlIHRoZSBjb21wYXJpc29uIHZhbHVlIGZvciBjaGVja2luZyBtYXRjaAorICAgICAgICAgKiBAcGFyYW0gdGltZWQgdHJ1ZSBpZiB0aW1lZCB3YWl0CisgICAgICAgICAqIEBwYXJhbSBuYW5vcyB0aW1lb3V0IHZhbHVlCisgICAgICAgICAqIEByZXR1cm4gbWF0Y2hlZCBpdGVtLCBvciBzIGlmIGNhbmNlbGxlZAorICAgICAgICAgKi8KKyAgICAgICAgT2JqZWN0IGF3YWl0RnVsZmlsbChRTm9kZSBzLCBPYmplY3QgZSwgYm9vbGVhbiB0aW1lZCwgbG9uZyBuYW5vcykgeworICAgICAgICAgICAgLyogU2FtZSBpZGVhIGFzIFRyYW5zZmVyU3RhY2suYXdhaXRGdWxmaWxsICovCisgICAgICAgICAgICBsb25nIGxhc3RUaW1lID0gdGltZWQgPyBTeXN0ZW0ubmFub1RpbWUoKSA6IDA7CisgICAgICAgICAgICBUaHJlYWQgdyA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisgICAgICAgICAgICBpbnQgc3BpbnMgPSAoKGhlYWQubmV4dCA9PSBzKSA/CisgICAgICAgICAgICAgICAgICAgICAgICAgKHRpbWVkID8gbWF4VGltZWRTcGlucyA6IG1heFVudGltZWRTcGlucykgOiAwKTsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBpZiAody5pc0ludGVycnVwdGVkKCkpCisgICAgICAgICAgICAgICAgICAgIHMudHJ5Q2FuY2VsKGUpOworICAgICAgICAgICAgICAgIE9iamVjdCB4ID0gcy5pdGVtOworICAgICAgICAgICAgICAgIGlmICh4ICE9IGUpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiB4OworICAgICAgICAgICAgICAgIGlmICh0aW1lZCkgeworICAgICAgICAgICAgICAgICAgICBsb25nIG5vdyA9IFN5c3RlbS5uYW5vVGltZSgpOworICAgICAgICAgICAgICAgICAgICBuYW5vcyAtPSBub3cgLSBsYXN0VGltZTsKKyAgICAgICAgICAgICAgICAgICAgbGFzdFRpbWUgPSBub3c7CisgICAgICAgICAgICAgICAgICAgIGlmIChuYW5vcyA8PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzLnRyeUNhbmNlbChlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChzcGlucyA+IDApCisgICAgICAgICAgICAgICAgICAgIC0tc3BpbnM7CisgICAgICAgICAgICAgICAgZWxzZSBpZiAocy53YWl0ZXIgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgcy53YWl0ZXIgPSB3OworICAgICAgICAgICAgICAgIGVsc2UgaWYgKCF0aW1lZCkKKyAgICAgICAgICAgICAgICAgICAgTG9ja1N1cHBvcnQucGFyayh0aGlzKTsKKyAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW5vcyA+IHNwaW5Gb3JUaW1lb3V0VGhyZXNob2xkKQorICAgICAgICAgICAgICAgICAgICBMb2NrU3VwcG9ydC5wYXJrTmFub3ModGhpcywgbmFub3MpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEdldHMgcmlkIG9mIGNhbmNlbGxlZCBub2RlIHMgd2l0aCBvcmlnaW5hbCBwcmVkZWNlc3NvciBwcmVkLgorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBjbGVhbihRTm9kZSBwcmVkLCBRTm9kZSBzKSB7CisgICAgICAgICAgICBzLndhaXRlciA9IG51bGw7IC8vIGZvcmdldCB0aHJlYWQKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBBdCBhbnkgZ2l2ZW4gdGltZSwgZXhhY3RseSBvbmUgbm9kZSBvbiBsaXN0IGNhbm5vdCBiZQorICAgICAgICAgICAgICogZGVsZXRlZCAtLSB0aGUgbGFzdCBpbnNlcnRlZCBub2RlLiBUbyBhY2NvbW1vZGF0ZSB0aGlzLAorICAgICAgICAgICAgICogaWYgd2UgY2Fubm90IGRlbGV0ZSBzLCB3ZSBzYXZlIGl0cyBwcmVkZWNlc3NvciBhcworICAgICAgICAgICAgICogImNsZWFuTWUiLCBkZWxldGluZyB0aGUgcHJldmlvdXNseSBzYXZlZCB2ZXJzaW9uCisgICAgICAgICAgICAgKiBmaXJzdC4gQXQgbGVhc3Qgb25lIG9mIG5vZGUgcyBvciB0aGUgbm9kZSBwcmV2aW91c2x5CisgICAgICAgICAgICAgKiBzYXZlZCBjYW4gYWx3YXlzIGJlIGRlbGV0ZWQsIHNvIHRoaXMgYWx3YXlzIHRlcm1pbmF0ZXMuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHdoaWxlIChwcmVkLm5leHQgPT0gcykgeyAvLyBSZXR1cm4gZWFybHkgaWYgYWxyZWFkeSB1bmxpbmtlZAorICAgICAgICAgICAgICAgIFFOb2RlIGggPSBoZWFkOworICAgICAgICAgICAgICAgIFFOb2RlIGhuID0gaC5uZXh0OyAgIC8vIEFic29yYiBjYW5jZWxsZWQgZmlyc3Qgbm9kZSBhcyBoZWFkCisgICAgICAgICAgICAgICAgaWYgKGhuICE9IG51bGwgJiYgaG4uaXNDYW5jZWxsZWQoKSkgeworICAgICAgICAgICAgICAgICAgICBhZHZhbmNlSGVhZChoLCBobik7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBRTm9kZSB0ID0gdGFpbDsgICAgICAvLyBFbnN1cmUgY29uc2lzdGVudCByZWFkIGZvciB0YWlsCisgICAgICAgICAgICAgICAgaWYgKHQgPT0gaCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIFFOb2RlIHRuID0gdC5uZXh0OworICAgICAgICAgICAgICAgIGlmICh0ICE9IHRhaWwpCisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIGlmICh0biAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGFkdmFuY2VUYWlsKHQsIHRuKTsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChzICE9IHQpIHsgICAgICAgIC8vIElmIG5vdCB0YWlsLCB0cnkgdG8gdW5zcGxpY2UKKyAgICAgICAgICAgICAgICAgICAgUU5vZGUgc24gPSBzLm5leHQ7CisgICAgICAgICAgICAgICAgICAgIGlmIChzbiA9PSBzIHx8IHByZWQuY2FzTmV4dChzLCBzbikpCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIFFOb2RlIGRwID0gY2xlYW5NZTsKKyAgICAgICAgICAgICAgICBpZiAoZHAgIT0gbnVsbCkgeyAgICAvLyBUcnkgdW5saW5raW5nIHByZXZpb3VzIGNhbmNlbGxlZCBub2RlCisgICAgICAgICAgICAgICAgICAgIFFOb2RlIGQgPSBkcC5uZXh0OworICAgICAgICAgICAgICAgICAgICBRTm9kZSBkbjsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGQgPT0gbnVsbCB8fCAgICAgICAgICAgICAgIC8vIGQgaXMgZ29uZSBvcgorICAgICAgICAgICAgICAgICAgICAgICAgZCA9PSBkcCB8fCAgICAgICAgICAgICAgICAgLy8gZCBpcyBvZmYgbGlzdCBvcgorICAgICAgICAgICAgICAgICAgICAgICAgIWQuaXNDYW5jZWxsZWQoKSB8fCAgICAgICAgLy8gZCBub3QgY2FuY2VsbGVkIG9yCisgICAgICAgICAgICAgICAgICAgICAgICAoZCAhPSB0ICYmICAgICAgICAgICAgICAgICAvLyBkIG5vdCB0YWlsIGFuZAorICAgICAgICAgICAgICAgICAgICAgICAgIChkbiA9IGQubmV4dCkgIT0gbnVsbCAmJiAgLy8gICBoYXMgc3VjY2Vzc29yCisgICAgICAgICAgICAgICAgICAgICAgICAgZG4gIT0gZCAmJiAgICAgICAgICAgICAgICAvLyAgIHRoYXQgaXMgb24gbGlzdAorICAgICAgICAgICAgICAgICAgICAgICAgIGRwLmNhc05leHQoZCwgZG4pKSkgICAgICAgLy8gZCB1bnNwbGljZWQKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc0NsZWFuTWUoZHAsIG51bGwpOworICAgICAgICAgICAgICAgICAgICBpZiAoZHAgPT0gcHJlZCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsgICAgICAvLyBzIGlzIGFscmVhZHkgc2F2ZWQgbm9kZQorICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2FzQ2xlYW5NZShudWxsLCBwcmVkKSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOyAgICAgICAgICAvLyBQb3N0cG9uZSBjbGVhbmluZyBzCisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyB1bnNhZmUgbWVjaGFuaWNzCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHN1bi5taXNjLlVuc2FmZSBVTlNBRkUgPSBzdW4ubWlzYy5VbnNhZmUuZ2V0VW5zYWZlKCk7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgaGVhZE9mZnNldCA9CisgICAgICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJoZWFkIiwgVHJhbnNmZXJRdWV1ZS5jbGFzcyk7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgdGFpbE9mZnNldCA9CisgICAgICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJ0YWlsIiwgVHJhbnNmZXJRdWV1ZS5jbGFzcyk7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgY2xlYW5NZU9mZnNldCA9CisgICAgICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJjbGVhbk1lIiwgVHJhbnNmZXJRdWV1ZS5jbGFzcyk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgdHJhbnNmZXJlci4gU2V0IG9ubHkgaW4gY29uc3RydWN0b3IsIGJ1dCBjYW5ub3QgYmUgZGVjbGFyZWQKKyAgICAgKiBhcyBmaW5hbCB3aXRob3V0IGZ1cnRoZXIgY29tcGxpY2F0aW5nIHNlcmlhbGl6YXRpb24uICBTaW5jZQorICAgICAqIHRoaXMgaXMgYWNjZXNzZWQgb25seSBhdCBtb3N0IG9uY2UgcGVyIHB1YmxpYyBtZXRob2QsIHRoZXJlCisgICAgICogaXNuJ3QgYSBub3RpY2VhYmxlIHBlcmZvcm1hbmNlIHBlbmFsdHkgZm9yIHVzaW5nIHZvbGF0aWxlCisgICAgICogaW5zdGVhZCBvZiBmaW5hbCBoZXJlLgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IHZvbGF0aWxlIFRyYW5zZmVyZXIgdHJhbnNmZXJlcjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSA8dHQ+U3luY2hyb25vdXNRdWV1ZTwvdHQ+IHdpdGggbm9uZmFpciBhY2Nlc3MgcG9saWN5LgorICAgICAqLworICAgIHB1YmxpYyBTeW5jaHJvbm91c1F1ZXVlKCkgeworICAgICAgICB0aGlzKGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgPHR0PlN5bmNocm9ub3VzUXVldWU8L3R0PiB3aXRoIHRoZSBzcGVjaWZpZWQgZmFpcm5lc3MgcG9saWN5LgorICAgICAqCisgICAgICogQHBhcmFtIGZhaXIgaWYgdHJ1ZSwgd2FpdGluZyB0aHJlYWRzIGNvbnRlbmQgaW4gRklGTyBvcmRlciBmb3IKKyAgICAgKiAgICAgICAgYWNjZXNzOyBvdGhlcndpc2UgdGhlIG9yZGVyIGlzIHVuc3BlY2lmaWVkLgorICAgICAqLworICAgIHB1YmxpYyBTeW5jaHJvbm91c1F1ZXVlKGJvb2xlYW4gZmFpcikgeworICAgICAgICB0cmFuc2ZlcmVyID0gZmFpciA/IG5ldyBUcmFuc2ZlclF1ZXVlKCkgOiBuZXcgVHJhbnNmZXJTdGFjaygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgdGhlIHNwZWNpZmllZCBlbGVtZW50IHRvIHRoaXMgcXVldWUsIHdhaXRpbmcgaWYgbmVjZXNzYXJ5IGZvcgorICAgICAqIGFub3RoZXIgdGhyZWFkIHRvIHJlY2VpdmUgaXQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXQoRSBvKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBpZiAobyA9PSBudWxsKSB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgaWYgKHRyYW5zZmVyZXIudHJhbnNmZXIobywgZmFsc2UsIDApID09IG51bGwpIHsKKyAgICAgICAgICAgIFRocmVhZC5pbnRlcnJ1cHRlZCgpOworICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpbnRvIHRoaXMgcXVldWUsIHdhaXRpbmcgaWYgbmVjZXNzYXJ5CisgICAgICogdXAgdG8gdGhlIHNwZWNpZmllZCB3YWl0IHRpbWUgZm9yIGFub3RoZXIgdGhyZWFkIHRvIHJlY2VpdmUgaXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgc3VjY2Vzc2Z1bCwgb3IgPHR0PmZhbHNlPC90dD4gaWYgdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgd2FpdGluZyB0aW1lIGVsYXBzZXMgYmVmb3JlIGEgY29uc3VtZXIgYXBwZWFycy4KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBvZmZlcihFIG8sIGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG8gPT0gbnVsbCkgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGlmICh0cmFuc2ZlcmVyLnRyYW5zZmVyKG8sIHRydWUsIHVuaXQudG9OYW5vcyh0aW1lb3V0KSkgIT0gbnVsbCkKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBpZiAoIVRocmVhZC5pbnRlcnJ1cHRlZCgpKQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB0aHJvdyBuZXcgSW50ZXJydXB0ZWRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpbnRvIHRoaXMgcXVldWUsIGlmIGFub3RoZXIgdGhyZWFkIGlzCisgICAgICogd2FpdGluZyB0byByZWNlaXZlIGl0LgorICAgICAqCisgICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gYWRkCisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoZSBlbGVtZW50IHdhcyBhZGRlZCB0byB0aGlzIHF1ZXVlLCBlbHNlCisgICAgICogICAgICAgICA8dHQ+ZmFsc2U8L3R0PgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBlbGVtZW50IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBvZmZlcihFIGUpIHsKKyAgICAgICAgaWYgKGUgPT0gbnVsbCkgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiB0cmFuc2ZlcmVyLnRyYW5zZmVyKGUsIHRydWUsIDApICE9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGFuZCByZW1vdmVzIHRoZSBoZWFkIG9mIHRoaXMgcXVldWUsIHdhaXRpbmcgaWYgbmVjZXNzYXJ5CisgICAgICogZm9yIGFub3RoZXIgdGhyZWFkIHRvIGluc2VydCBpdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhlYWQgb2YgdGhpcyBxdWV1ZQorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIHB1YmxpYyBFIHRha2UoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBPYmplY3QgZSA9IHRyYW5zZmVyZXIudHJhbnNmZXIobnVsbCwgZmFsc2UsIDApOworICAgICAgICBpZiAoZSAhPSBudWxsKQorICAgICAgICAgICAgcmV0dXJuIChFKWU7CisgICAgICAgIFRocmVhZC5pbnRlcnJ1cHRlZCgpOworICAgICAgICB0aHJvdyBuZXcgSW50ZXJydXB0ZWRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYW5kIHJlbW92ZXMgdGhlIGhlYWQgb2YgdGhpcyBxdWV1ZSwgd2FpdGluZworICAgICAqIGlmIG5lY2Vzc2FyeSB1cCB0byB0aGUgc3BlY2lmaWVkIHdhaXQgdGltZSwgZm9yIGFub3RoZXIgdGhyZWFkCisgICAgICogdG8gaW5zZXJ0IGl0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGlzIHF1ZXVlLCBvciA8dHQ+bnVsbDwvdHQ+IGlmIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIHdhaXRpbmcgdGltZSBlbGFwc2VzIGJlZm9yZSBhbiBlbGVtZW50IGlzIHByZXNlbnQuCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIEUgcG9sbChsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdCBlID0gdHJhbnNmZXJlci50cmFuc2ZlcihudWxsLCB0cnVlLCB1bml0LnRvTmFub3ModGltZW91dCkpOworICAgICAgICBpZiAoZSAhPSBudWxsIHx8ICFUaHJlYWQuaW50ZXJydXB0ZWQoKSkKKyAgICAgICAgICAgIHJldHVybiAoRSllOworICAgICAgICB0aHJvdyBuZXcgSW50ZXJydXB0ZWRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYW5kIHJlbW92ZXMgdGhlIGhlYWQgb2YgdGhpcyBxdWV1ZSwgaWYgYW5vdGhlciB0aHJlYWQKKyAgICAgKiBpcyBjdXJyZW50bHkgbWFraW5nIGFuIGVsZW1lbnQgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGlzIHF1ZXVlLCBvciA8dHQ+bnVsbDwvdHQ+IGlmIG5vCisgICAgICogICAgICAgICBlbGVtZW50IGlzIGF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRSBwb2xsKCkgeworICAgICAgICByZXR1cm4gKEUpdHJhbnNmZXJlci50cmFuc2ZlcihudWxsLCB0cnVlLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbHdheXMgcmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+LgorICAgICAqIEEgPHR0PlN5bmNocm9ub3VzUXVldWU8L3R0PiBoYXMgbm8gaW50ZXJuYWwgY2FwYWNpdHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbHdheXMgcmV0dXJucyB6ZXJvLgorICAgICAqIEEgPHR0PlN5bmNocm9ub3VzUXVldWU8L3R0PiBoYXMgbm8gaW50ZXJuYWwgY2FwYWNpdHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHplcm8uCisgICAgICovCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbHdheXMgcmV0dXJucyB6ZXJvLgorICAgICAqIEEgPHR0PlN5bmNocm9ub3VzUXVldWU8L3R0PiBoYXMgbm8gaW50ZXJuYWwgY2FwYWNpdHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHplcm8uCisgICAgICovCisgICAgcHVibGljIGludCByZW1haW5pbmdDYXBhY2l0eSgpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogRG9lcyBub3RoaW5nLgorICAgICAqIEEgPHR0PlN5bmNocm9ub3VzUXVldWU8L3R0PiBoYXMgbm8gaW50ZXJuYWwgY2FwYWNpdHkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWx3YXlzIHJldHVybnMgPHR0PmZhbHNlPC90dD4uCisgICAgICogQSA8dHQ+U3luY2hyb25vdXNRdWV1ZTwvdHQ+IGhhcyBubyBpbnRlcm5hbCBjYXBhY2l0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvIHRoZSBlbGVtZW50CisgICAgICogQHJldHVybiA8dHQ+ZmFsc2U8L3R0PgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbHdheXMgcmV0dXJucyA8dHQ+ZmFsc2U8L3R0Pi4KKyAgICAgKiBBIDx0dD5TeW5jaHJvbm91c1F1ZXVlPC90dD4gaGFzIG5vIGludGVybmFsIGNhcGFjaXR5LgorICAgICAqCisgICAgICogQHBhcmFtIG8gdGhlIGVsZW1lbnQgdG8gcmVtb3ZlCisgICAgICogQHJldHVybiA8dHQ+ZmFsc2U8L3R0PgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3QgbykgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyA8dHQ+ZmFsc2U8L3R0PiB1bmxlc3MgdGhlIGdpdmVuIGNvbGxlY3Rpb24gaXMgZW1wdHkuCisgICAgICogQSA8dHQ+U3luY2hyb25vdXNRdWV1ZTwvdHQ+IGhhcyBubyBpbnRlcm5hbCBjYXBhY2l0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjIHRoZSBjb2xsZWN0aW9uCisgICAgICogQHJldHVybiA8dHQ+ZmFsc2U8L3R0PiB1bmxlc3MgZ2l2ZW4gY29sbGVjdGlvbiBpcyBlbXB0eQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQWxsKENvbGxlY3Rpb248Pz4gYykgeworICAgICAgICByZXR1cm4gYy5pc0VtcHR5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWx3YXlzIHJldHVybnMgPHR0PmZhbHNlPC90dD4uCisgICAgICogQSA8dHQ+U3luY2hyb25vdXNRdWV1ZTwvdHQ+IGhhcyBubyBpbnRlcm5hbCBjYXBhY2l0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjIHRoZSBjb2xsZWN0aW9uCisgICAgICogQHJldHVybiA8dHQ+ZmFsc2U8L3R0PgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZUFsbChDb2xsZWN0aW9uPD8+IGMpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFsd2F5cyByZXR1cm5zIDx0dD5mYWxzZTwvdHQ+LgorICAgICAqIEEgPHR0PlN5bmNocm9ub3VzUXVldWU8L3R0PiBoYXMgbm8gaW50ZXJuYWwgY2FwYWNpdHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYyB0aGUgY29sbGVjdGlvbgorICAgICAqIEByZXR1cm4gPHR0PmZhbHNlPC90dD4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiByZXRhaW5BbGwoQ29sbGVjdGlvbjw/PiBjKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbHdheXMgcmV0dXJucyA8dHQ+bnVsbDwvdHQ+LgorICAgICAqIEEgPHR0PlN5bmNocm9ub3VzUXVldWU8L3R0PiBkb2VzIG5vdCByZXR1cm4gZWxlbWVudHMKKyAgICAgKiB1bmxlc3MgYWN0aXZlbHkgd2FpdGVkIG9uLgorICAgICAqCisgICAgICogQHJldHVybiA8dHQ+bnVsbDwvdHQ+CisgICAgICovCisgICAgcHVibGljIEUgcGVlaygpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBlbXB0eSBpdGVyYXRvciBpbiB3aGljaCA8dHQ+aGFzTmV4dDwvdHQ+IGFsd2F5cyByZXR1cm5zCisgICAgICogPHR0PmZhbHNlPC90dD4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGVtcHR5IGl0ZXJhdG9yCisgICAgICovCisgICAgcHVibGljIEl0ZXJhdG9yPEU+IGl0ZXJhdG9yKCkgeworICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuPEU+ZW1wdHlTZXQoKS5pdGVyYXRvcigpOyAvLyBhbmRyb2lkLWNoYW5nZWQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgemVyby1sZW5ndGggYXJyYXkuCisgICAgICogQHJldHVybiBhIHplcm8tbGVuZ3RoIGFycmF5CisgICAgICovCisgICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBFbXB0eUFycmF5Lk9CSkVDVDsgLy8gYW5kcm9pZC1jaGFuZ2VkCisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgemVyb2V0aCBlbGVtZW50IG9mIHRoZSBzcGVjaWZpZWQgYXJyYXkgdG8gPHR0Pm51bGw8L3R0PgorICAgICAqIChpZiB0aGUgYXJyYXkgaGFzIG5vbi16ZXJvIGxlbmd0aCkgYW5kIHJldHVybnMgaXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYSB0aGUgYXJyYXkKKyAgICAgKiBAcmV0dXJuIHRoZSBzcGVjaWZpZWQgYXJyYXkKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgYXJyYXkgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyA8VD4gVFtdIHRvQXJyYXkoVFtdIGEpIHsKKyAgICAgICAgaWYgKGEubGVuZ3RoID4gMCkKKyAgICAgICAgICAgIGFbMF0gPSBudWxsOworICAgICAgICByZXR1cm4gYTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiAgICAgICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICAgICAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAgICAgIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGRyYWluVG8oQ29sbGVjdGlvbjw/IHN1cGVyIEU+IGMpIHsKKyAgICAgICAgaWYgKGMgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBpZiAoYyA9PSB0aGlzKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICBpbnQgbiA9IDA7CisgICAgICAgIEUgZTsKKyAgICAgICAgd2hpbGUgKCAoZSA9IHBvbGwoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgYy5hZGQoZSk7CisgICAgICAgICAgICArK247CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG47CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gICAgICAgICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgICAgICAgICB7QGluaGVyaXREb2N9CisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gICAgICB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIGludCBkcmFpblRvKENvbGxlY3Rpb248PyBzdXBlciBFPiBjLCBpbnQgbWF4RWxlbWVudHMpIHsKKyAgICAgICAgaWYgKGMgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBpZiAoYyA9PSB0aGlzKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICBpbnQgbiA9IDA7CisgICAgICAgIEUgZTsKKyAgICAgICAgd2hpbGUgKG4gPCBtYXhFbGVtZW50cyAmJiAoZSA9IHBvbGwoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgYy5hZGQoZSk7CisgICAgICAgICAgICArK247CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG47CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUbyBjb3BlIHdpdGggc2VyaWFsaXphdGlvbiBzdHJhdGVneSBpbiB0aGUgMS41IHZlcnNpb24gb2YKKyAgICAgKiBTeW5jaHJvbm91c1F1ZXVlLCB3ZSBkZWNsYXJlIHNvbWUgdW51c2VkIGNsYXNzZXMgYW5kIGZpZWxkcworICAgICAqIHRoYXQgZXhpc3Qgc29sZWx5IHRvIGVuYWJsZSBzZXJpYWxpemFiaWxpdHkgYWNyb3NzIHZlcnNpb25zLgorICAgICAqIFRoZXNlIGZpZWxkcyBhcmUgbmV2ZXIgdXNlZCwgc28gYXJlIGluaXRpYWxpemVkIG9ubHkgaWYgdGhpcworICAgICAqIG9iamVjdCBpcyBldmVyIHNlcmlhbGl6ZWQgb3IgZGVzZXJpYWxpemVkLgorICAgICAqLworCisgICAgc3RhdGljIGNsYXNzIFdhaXRRdWV1ZSBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsgfQorICAgIHN0YXRpYyBjbGFzcyBMaWZvV2FpdFF1ZXVlIGV4dGVuZHMgV2FpdFF1ZXVlIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTM2MzMxMTM0MTAyNDgxNjM2ODZMOworICAgIH0KKyAgICBzdGF0aWMgY2xhc3MgRmlmb1dhaXRRdWV1ZSBleHRlbmRzIFdhaXRRdWV1ZSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0zNjIzMTEzNDEwMjQ4MTYzNjg2TDsKKyAgICB9CisgICAgcHJpdmF0ZSBSZWVudHJhbnRMb2NrIHFsb2NrOworICAgIHByaXZhdGUgV2FpdFF1ZXVlIHdhaXRpbmdQcm9kdWNlcnM7CisgICAgcHJpdmF0ZSBXYWl0UXVldWUgd2FpdGluZ0NvbnN1bWVyczsKKworICAgIC8qKgorICAgICAqIFNhdmUgdGhlIHN0YXRlIHRvIGEgc3RyZWFtICh0aGF0IGlzLCBzZXJpYWxpemUgaXQpLgorICAgICAqCisgICAgICogQHBhcmFtIHMgdGhlIHN0cmVhbQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbSBzKQorICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gZmFpciA9IHRyYW5zZmVyZXIgaW5zdGFuY2VvZiBUcmFuc2ZlclF1ZXVlOworICAgICAgICBpZiAoZmFpcikgeworICAgICAgICAgICAgcWxvY2sgPSBuZXcgUmVlbnRyYW50TG9jayh0cnVlKTsKKyAgICAgICAgICAgIHdhaXRpbmdQcm9kdWNlcnMgPSBuZXcgRmlmb1dhaXRRdWV1ZSgpOworICAgICAgICAgICAgd2FpdGluZ0NvbnN1bWVycyA9IG5ldyBGaWZvV2FpdFF1ZXVlKCk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBxbG9jayA9IG5ldyBSZWVudHJhbnRMb2NrKCk7CisgICAgICAgICAgICB3YWl0aW5nUHJvZHVjZXJzID0gbmV3IExpZm9XYWl0UXVldWUoKTsKKyAgICAgICAgICAgIHdhaXRpbmdDb25zdW1lcnMgPSBuZXcgTGlmb1dhaXRRdWV1ZSgpOworICAgICAgICB9CisgICAgICAgIHMuZGVmYXVsdFdyaXRlT2JqZWN0KCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoZmluYWwgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSBzKQorICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIHMuZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgaWYgKHdhaXRpbmdQcm9kdWNlcnMgaW5zdGFuY2VvZiBGaWZvV2FpdFF1ZXVlKQorICAgICAgICAgICAgdHJhbnNmZXJlciA9IG5ldyBUcmFuc2ZlclF1ZXVlKCk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHRyYW5zZmVyZXIgPSBuZXcgVHJhbnNmZXJTdGFjaygpOworICAgIH0KKworICAgIC8vIFVuc2FmZSBtZWNoYW5pY3MKKyAgICBzdGF0aWMgbG9uZyBvYmplY3RGaWVsZE9mZnNldChzdW4ubWlzYy5VbnNhZmUgVU5TQUZFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBmaWVsZCwgQ2xhc3M8Pz4ga2xhenopIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBVTlNBRkUub2JqZWN0RmllbGRPZmZzZXQoa2xhenouZ2V0RGVjbGFyZWRGaWVsZChmaWVsZCkpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hGaWVsZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb252ZXJ0IEV4Y2VwdGlvbiB0byBjb3JyZXNwb25kaW5nIEVycm9yCisgICAgICAgICAgICBOb1N1Y2hGaWVsZEVycm9yIGVycm9yID0gbmV3IE5vU3VjaEZpZWxkRXJyb3IoZmllbGQpOworICAgICAgICAgICAgZXJyb3IuaW5pdENhdXNlKGUpOworICAgICAgICAgICAgdGhyb3cgZXJyb3I7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9UaHJlYWRGYWN0b3J5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvVGhyZWFkRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJmMGZiMWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvVGhyZWFkRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsNDEgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudDsKKworLyoqCisgKiBBbiBvYmplY3QgdGhhdCBjcmVhdGVzIG5ldyB0aHJlYWRzIG9uIGRlbWFuZC4gIFVzaW5nIHRocmVhZCBmYWN0b3JpZXMKKyAqIHJlbW92ZXMgaGFyZHdpcmluZyBvZiBjYWxscyB0byB7QGxpbmsgVGhyZWFkI1RocmVhZChSdW5uYWJsZSkgbmV3IFRocmVhZH0sCisgKiBlbmFibGluZyBhcHBsaWNhdGlvbnMgdG8gdXNlIHNwZWNpYWwgdGhyZWFkIHN1YmNsYXNzZXMsIHByaW9yaXRpZXMsIGV0Yy4KKyAqCisgKiA8cD4KKyAqIFRoZSBzaW1wbGVzdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGludGVyZmFjZSBpcyBqdXN0OgorICogPHByZT4KKyAqIGNsYXNzIFNpbXBsZVRocmVhZEZhY3RvcnkgaW1wbGVtZW50cyBUaHJlYWRGYWN0b3J5IHsKKyAqICAgcHVibGljIFRocmVhZCBuZXdUaHJlYWQoUnVubmFibGUgcikgeworICogICAgIHJldHVybiBuZXcgVGhyZWFkKHIpOworICogICB9CisgKiB9CisgKiA8L3ByZT4KKyAqCisgKiBUaGUge0BsaW5rIEV4ZWN1dG9ycyNkZWZhdWx0VGhyZWFkRmFjdG9yeX0gbWV0aG9kIHByb3ZpZGVzIGEgbW9yZQorICogdXNlZnVsIHNpbXBsZSBpbXBsZW1lbnRhdGlvbiwgdGhhdCBzZXRzIHRoZSBjcmVhdGVkIHRocmVhZCBjb250ZXh0CisgKiB0byBrbm93biB2YWx1ZXMgYmVmb3JlIHJldHVybmluZyBpdC4KKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqLworcHVibGljIGludGVyZmFjZSBUaHJlYWRGYWN0b3J5IHsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFRocmVhZH0uICBJbXBsZW1lbnRhdGlvbnMgbWF5IGFsc28gaW5pdGlhbGl6ZQorICAgICAqIHByaW9yaXR5LCBuYW1lLCBkYWVtb24gc3RhdHVzLCB7QGNvZGUgVGhyZWFkR3JvdXB9LCBldGMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gciBhIHJ1bm5hYmxlIHRvIGJlIGV4ZWN1dGVkIGJ5IG5ldyB0aHJlYWQgaW5zdGFuY2UKKyAgICAgKiBAcmV0dXJuIGNvbnN0cnVjdGVkIHRocmVhZCwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZSByZXF1ZXN0IHRvCisgICAgICogICAgICAgICBjcmVhdGUgYSB0aHJlYWQgaXMgcmVqZWN0ZWQKKyAgICAgKi8KKyAgICBUaHJlYWQgbmV3VGhyZWFkKFJ1bm5hYmxlIHIpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L1RocmVhZFBvb2xFeGVjdXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L1RocmVhZFBvb2xFeGVjdXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY2MjJhZjgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmEKQEAgLTAsMCArMSwyMDIwIEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3MuKjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKKworLyoqCisgKiBBbiB7QGxpbmsgRXhlY3V0b3JTZXJ2aWNlfSB0aGF0IGV4ZWN1dGVzIGVhY2ggc3VibWl0dGVkIHRhc2sgdXNpbmcKKyAqIG9uZSBvZiBwb3NzaWJseSBzZXZlcmFsIHBvb2xlZCB0aHJlYWRzLCBub3JtYWxseSBjb25maWd1cmVkCisgKiB1c2luZyB7QGxpbmsgRXhlY3V0b3JzfSBmYWN0b3J5IG1ldGhvZHMuCisgKgorICogPHA+VGhyZWFkIHBvb2xzIGFkZHJlc3MgdHdvIGRpZmZlcmVudCBwcm9ibGVtczogdGhleSB1c3VhbGx5CisgKiBwcm92aWRlIGltcHJvdmVkIHBlcmZvcm1hbmNlIHdoZW4gZXhlY3V0aW5nIGxhcmdlIG51bWJlcnMgb2YKKyAqIGFzeW5jaHJvbm91cyB0YXNrcywgZHVlIHRvIHJlZHVjZWQgcGVyLXRhc2sgaW52b2NhdGlvbiBvdmVyaGVhZCwKKyAqIGFuZCB0aGV5IHByb3ZpZGUgYSBtZWFucyBvZiBib3VuZGluZyBhbmQgbWFuYWdpbmcgdGhlIHJlc291cmNlcywKKyAqIGluY2x1ZGluZyB0aHJlYWRzLCBjb25zdW1lZCB3aGVuIGV4ZWN1dGluZyBhIGNvbGxlY3Rpb24gb2YgdGFza3MuCisgKiBFYWNoIHtAY29kZSBUaHJlYWRQb29sRXhlY3V0b3J9IGFsc28gbWFpbnRhaW5zIHNvbWUgYmFzaWMKKyAqIHN0YXRpc3RpY3MsIHN1Y2ggYXMgdGhlIG51bWJlciBvZiBjb21wbGV0ZWQgdGFza3MuCisgKgorICogPHA+VG8gYmUgdXNlZnVsIGFjcm9zcyBhIHdpZGUgcmFuZ2Ugb2YgY29udGV4dHMsIHRoaXMgY2xhc3MKKyAqIHByb3ZpZGVzIG1hbnkgYWRqdXN0YWJsZSBwYXJhbWV0ZXJzIGFuZCBleHRlbnNpYmlsaXR5CisgKiBob29rcy4gSG93ZXZlciwgcHJvZ3JhbW1lcnMgYXJlIHVyZ2VkIHRvIHVzZSB0aGUgbW9yZSBjb252ZW5pZW50CisgKiB7QGxpbmsgRXhlY3V0b3JzfSBmYWN0b3J5IG1ldGhvZHMge0BsaW5rCisgKiBFeGVjdXRvcnMjbmV3Q2FjaGVkVGhyZWFkUG9vbH0gKHVuYm91bmRlZCB0aHJlYWQgcG9vbCwgd2l0aAorICogYXV0b21hdGljIHRocmVhZCByZWNsYW1hdGlvbiksIHtAbGluayBFeGVjdXRvcnMjbmV3Rml4ZWRUaHJlYWRQb29sfQorICogKGZpeGVkIHNpemUgdGhyZWFkIHBvb2wpIGFuZCB7QGxpbmsKKyAqIEV4ZWN1dG9ycyNuZXdTaW5nbGVUaHJlYWRFeGVjdXRvcn0gKHNpbmdsZSBiYWNrZ3JvdW5kIHRocmVhZCksIHRoYXQKKyAqIHByZWNvbmZpZ3VyZSBzZXR0aW5ncyBmb3IgdGhlIG1vc3QgY29tbW9uIHVzYWdlCisgKiBzY2VuYXJpb3MuIE90aGVyd2lzZSwgdXNlIHRoZSBmb2xsb3dpbmcgZ3VpZGUgd2hlbiBtYW51YWxseQorICogY29uZmlndXJpbmcgYW5kIHR1bmluZyB0aGlzIGNsYXNzOgorICoKKyAqIDxkbD4KKyAqCisgKiA8ZHQ+Q29yZSBhbmQgbWF4aW11bSBwb29sIHNpemVzPC9kdD4KKyAqCisgKiA8ZGQ+QSB7QGNvZGUgVGhyZWFkUG9vbEV4ZWN1dG9yfSB3aWxsIGF1dG9tYXRpY2FsbHkgYWRqdXN0IHRoZQorICogcG9vbCBzaXplIChzZWUge0BsaW5rICNnZXRQb29sU2l6ZX0pCisgKiBhY2NvcmRpbmcgdG8gdGhlIGJvdW5kcyBzZXQgYnkKKyAqIGNvcmVQb29sU2l6ZSAoc2VlIHtAbGluayAjZ2V0Q29yZVBvb2xTaXplfSkgYW5kCisgKiBtYXhpbXVtUG9vbFNpemUgKHNlZSB7QGxpbmsgI2dldE1heGltdW1Qb29sU2l6ZX0pLgorICoKKyAqIFdoZW4gYSBuZXcgdGFzayBpcyBzdWJtaXR0ZWQgaW4gbWV0aG9kIHtAbGluayAjZXhlY3V0ZX0sIGFuZCBmZXdlcgorICogdGhhbiBjb3JlUG9vbFNpemUgdGhyZWFkcyBhcmUgcnVubmluZywgYSBuZXcgdGhyZWFkIGlzIGNyZWF0ZWQgdG8KKyAqIGhhbmRsZSB0aGUgcmVxdWVzdCwgZXZlbiBpZiBvdGhlciB3b3JrZXIgdGhyZWFkcyBhcmUgaWRsZS4gIElmCisgKiB0aGVyZSBhcmUgbW9yZSB0aGFuIGNvcmVQb29sU2l6ZSBidXQgbGVzcyB0aGFuIG1heGltdW1Qb29sU2l6ZQorICogdGhyZWFkcyBydW5uaW5nLCBhIG5ldyB0aHJlYWQgd2lsbCBiZSBjcmVhdGVkIG9ubHkgaWYgdGhlIHF1ZXVlIGlzCisgKiBmdWxsLiAgQnkgc2V0dGluZyBjb3JlUG9vbFNpemUgYW5kIG1heGltdW1Qb29sU2l6ZSB0aGUgc2FtZSwgeW91CisgKiBjcmVhdGUgYSBmaXhlZC1zaXplIHRocmVhZCBwb29sLiBCeSBzZXR0aW5nIG1heGltdW1Qb29sU2l6ZSB0byBhbgorICogZXNzZW50aWFsbHkgdW5ib3VuZGVkIHZhbHVlIHN1Y2ggYXMge0Bjb2RlIEludGVnZXIuTUFYX1ZBTFVFfSwgeW91CisgKiBhbGxvdyB0aGUgcG9vbCB0byBhY2NvbW1vZGF0ZSBhbiBhcmJpdHJhcnkgbnVtYmVyIG9mIGNvbmN1cnJlbnQKKyAqIHRhc2tzLiBNb3N0IHR5cGljYWxseSwgY29yZSBhbmQgbWF4aW11bSBwb29sIHNpemVzIGFyZSBzZXQgb25seQorICogdXBvbiBjb25zdHJ1Y3Rpb24sIGJ1dCB0aGV5IG1heSBhbHNvIGJlIGNoYW5nZWQgZHluYW1pY2FsbHkgdXNpbmcKKyAqIHtAbGluayAjc2V0Q29yZVBvb2xTaXplfSBhbmQge0BsaW5rICNzZXRNYXhpbXVtUG9vbFNpemV9LiA8L2RkPgorICoKKyAqIDxkdD5Pbi1kZW1hbmQgY29uc3RydWN0aW9uPC9kdD4KKyAqCisgKiA8ZGQ+IEJ5IGRlZmF1bHQsIGV2ZW4gY29yZSB0aHJlYWRzIGFyZSBpbml0aWFsbHkgY3JlYXRlZCBhbmQKKyAqIHN0YXJ0ZWQgb25seSB3aGVuIG5ldyB0YXNrcyBhcnJpdmUsIGJ1dCB0aGlzIGNhbiBiZSBvdmVycmlkZGVuCisgKiBkeW5hbWljYWxseSB1c2luZyBtZXRob2Qge0BsaW5rICNwcmVzdGFydENvcmVUaHJlYWR9IG9yIHtAbGluaworICogI3ByZXN0YXJ0QWxsQ29yZVRocmVhZHN9LiAgWW91IHByb2JhYmx5IHdhbnQgdG8gcHJlc3RhcnQgdGhyZWFkcyBpZgorICogeW91IGNvbnN0cnVjdCB0aGUgcG9vbCB3aXRoIGEgbm9uLWVtcHR5IHF1ZXVlLiA8L2RkPgorICoKKyAqIDxkdD5DcmVhdGluZyBuZXcgdGhyZWFkczwvZHQ+CisgKgorICogPGRkPk5ldyB0aHJlYWRzIGFyZSBjcmVhdGVkIHVzaW5nIGEge0BsaW5rIFRocmVhZEZhY3Rvcnl9LiAgSWYgbm90CisgKiBvdGhlcndpc2Ugc3BlY2lmaWVkLCBhIHtAbGluayBFeGVjdXRvcnMjZGVmYXVsdFRocmVhZEZhY3Rvcnl9IGlzCisgKiB1c2VkLCB0aGF0IGNyZWF0ZXMgdGhyZWFkcyB0byBhbGwgYmUgaW4gdGhlIHNhbWUge0BsaW5rCisgKiBUaHJlYWRHcm91cH0gYW5kIHdpdGggdGhlIHNhbWUge0Bjb2RlIE5PUk1fUFJJT1JJVFl9IHByaW9yaXR5IGFuZAorICogbm9uLWRhZW1vbiBzdGF0dXMuIEJ5IHN1cHBseWluZyBhIGRpZmZlcmVudCBUaHJlYWRGYWN0b3J5LCB5b3UgY2FuCisgKiBhbHRlciB0aGUgdGhyZWFkJ3MgbmFtZSwgdGhyZWFkIGdyb3VwLCBwcmlvcml0eSwgZGFlbW9uIHN0YXR1cywKKyAqIGV0Yy4gSWYgYSB7QGNvZGUgVGhyZWFkRmFjdG9yeX0gZmFpbHMgdG8gY3JlYXRlIGEgdGhyZWFkIHdoZW4gYXNrZWQKKyAqIGJ5IHJldHVybmluZyBudWxsIGZyb20ge0Bjb2RlIG5ld1RocmVhZH0sIHRoZSBleGVjdXRvciB3aWxsCisgKiBjb250aW51ZSwgYnV0IG1pZ2h0IG5vdCBiZSBhYmxlIHRvIGV4ZWN1dGUgYW55IHRhc2tzLjwvZGQ+CisgKgorICogPGR0PktlZXAtYWxpdmUgdGltZXM8L2R0PgorICoKKyAqIDxkZD5JZiB0aGUgcG9vbCBjdXJyZW50bHkgaGFzIG1vcmUgdGhhbiBjb3JlUG9vbFNpemUgdGhyZWFkcywKKyAqIGV4Y2VzcyB0aHJlYWRzIHdpbGwgYmUgdGVybWluYXRlZCBpZiB0aGV5IGhhdmUgYmVlbiBpZGxlIGZvciBtb3JlCisgKiB0aGFuIHRoZSBrZWVwQWxpdmVUaW1lIChzZWUge0BsaW5rICNnZXRLZWVwQWxpdmVUaW1lfSkuIFRoaXMKKyAqIHByb3ZpZGVzIGEgbWVhbnMgb2YgcmVkdWNpbmcgcmVzb3VyY2UgY29uc3VtcHRpb24gd2hlbiB0aGUgcG9vbCBpcworICogbm90IGJlaW5nIGFjdGl2ZWx5IHVzZWQuIElmIHRoZSBwb29sIGJlY29tZXMgbW9yZSBhY3RpdmUgbGF0ZXIsIG5ldworICogdGhyZWFkcyB3aWxsIGJlIGNvbnN0cnVjdGVkLiBUaGlzIHBhcmFtZXRlciBjYW4gYWxzbyBiZSBjaGFuZ2VkCisgKiBkeW5hbWljYWxseSB1c2luZyBtZXRob2Qge0BsaW5rICNzZXRLZWVwQWxpdmVUaW1lfS4gVXNpbmcgYSB2YWx1ZQorICogb2Yge0Bjb2RlIExvbmcuTUFYX1ZBTFVFfSB7QGxpbmsgVGltZVVuaXQjTkFOT1NFQ09ORFN9IGVmZmVjdGl2ZWx5CisgKiBkaXNhYmxlcyBpZGxlIHRocmVhZHMgZnJvbSBldmVyIHRlcm1pbmF0aW5nIHByaW9yIHRvIHNodXQgZG93bi4gQnkKKyAqIGRlZmF1bHQsIHRoZSBrZWVwLWFsaXZlIHBvbGljeSBhcHBsaWVzIG9ubHkgd2hlbiB0aGVyZSBhcmUgbW9yZQorICogdGhhbiBjb3JlUG9vbFNpemVUaHJlYWRzLiBCdXQgbWV0aG9kIHtAbGluaworICogI2FsbG93Q29yZVRocmVhZFRpbWVPdXQoYm9vbGVhbil9IGNhbiBiZSB1c2VkIHRvIGFwcGx5IHRoaXMKKyAqIHRpbWUtb3V0IHBvbGljeSB0byBjb3JlIHRocmVhZHMgYXMgd2VsbCwgc28gbG9uZyBhcyB0aGUKKyAqIGtlZXBBbGl2ZVRpbWUgdmFsdWUgaXMgbm9uLXplcm8uIDwvZGQ+CisgKgorICogPGR0PlF1ZXVpbmc8L2R0PgorICoKKyAqIDxkZD5Bbnkge0BsaW5rIEJsb2NraW5nUXVldWV9IG1heSBiZSB1c2VkIHRvIHRyYW5zZmVyIGFuZCBob2xkCisgKiBzdWJtaXR0ZWQgdGFza3MuICBUaGUgdXNlIG9mIHRoaXMgcXVldWUgaW50ZXJhY3RzIHdpdGggcG9vbCBzaXppbmc6CisgKgorICogPHVsPgorICoKKyAqIDxsaT4gSWYgZmV3ZXIgdGhhbiBjb3JlUG9vbFNpemUgdGhyZWFkcyBhcmUgcnVubmluZywgdGhlIEV4ZWN1dG9yCisgKiBhbHdheXMgcHJlZmVycyBhZGRpbmcgYSBuZXcgdGhyZWFkCisgKiByYXRoZXIgdGhhbiBxdWV1aW5nLjwvbGk+CisgKgorICogPGxpPiBJZiBjb3JlUG9vbFNpemUgb3IgbW9yZSB0aHJlYWRzIGFyZSBydW5uaW5nLCB0aGUgRXhlY3V0b3IKKyAqIGFsd2F5cyBwcmVmZXJzIHF1ZXVpbmcgYSByZXF1ZXN0IHJhdGhlciB0aGFuIGFkZGluZyBhIG5ldworICogdGhyZWFkLjwvbGk+CisgKgorICogPGxpPiBJZiBhIHJlcXVlc3QgY2Fubm90IGJlIHF1ZXVlZCwgYSBuZXcgdGhyZWFkIGlzIGNyZWF0ZWQgdW5sZXNzCisgKiB0aGlzIHdvdWxkIGV4Y2VlZCBtYXhpbXVtUG9vbFNpemUsIGluIHdoaWNoIGNhc2UsIHRoZSB0YXNrIHdpbGwgYmUKKyAqIHJlamVjdGVkLjwvbGk+CisgKgorICogPC91bD4KKyAqCisgKiBUaGVyZSBhcmUgdGhyZWUgZ2VuZXJhbCBzdHJhdGVnaWVzIGZvciBxdWV1aW5nOgorICogPG9sPgorICoKKyAqIDxsaT4gPGVtPiBEaXJlY3QgaGFuZG9mZnMuPC9lbT4gQSBnb29kIGRlZmF1bHQgY2hvaWNlIGZvciBhIHdvcmsKKyAqIHF1ZXVlIGlzIGEge0BsaW5rIFN5bmNocm9ub3VzUXVldWV9IHRoYXQgaGFuZHMgb2ZmIHRhc2tzIHRvIHRocmVhZHMKKyAqIHdpdGhvdXQgb3RoZXJ3aXNlIGhvbGRpbmcgdGhlbS4gSGVyZSwgYW4gYXR0ZW1wdCB0byBxdWV1ZSBhIHRhc2sKKyAqIHdpbGwgZmFpbCBpZiBubyB0aHJlYWRzIGFyZSBpbW1lZGlhdGVseSBhdmFpbGFibGUgdG8gcnVuIGl0LCBzbyBhCisgKiBuZXcgdGhyZWFkIHdpbGwgYmUgY29uc3RydWN0ZWQuIFRoaXMgcG9saWN5IGF2b2lkcyBsb2NrdXBzIHdoZW4KKyAqIGhhbmRsaW5nIHNldHMgb2YgcmVxdWVzdHMgdGhhdCBtaWdodCBoYXZlIGludGVybmFsIGRlcGVuZGVuY2llcy4KKyAqIERpcmVjdCBoYW5kb2ZmcyBnZW5lcmFsbHkgcmVxdWlyZSB1bmJvdW5kZWQgbWF4aW11bVBvb2xTaXplcyB0bworICogYXZvaWQgcmVqZWN0aW9uIG9mIG5ldyBzdWJtaXR0ZWQgdGFza3MuIFRoaXMgaW4gdHVybiBhZG1pdHMgdGhlCisgKiBwb3NzaWJpbGl0eSBvZiB1bmJvdW5kZWQgdGhyZWFkIGdyb3d0aCB3aGVuIGNvbW1hbmRzIGNvbnRpbnVlIHRvCisgKiBhcnJpdmUgb24gYXZlcmFnZSBmYXN0ZXIgdGhhbiB0aGV5IGNhbiBiZSBwcm9jZXNzZWQuICA8L2xpPgorICoKKyAqIDxsaT48ZW0+IFVuYm91bmRlZCBxdWV1ZXMuPC9lbT4gVXNpbmcgYW4gdW5ib3VuZGVkIHF1ZXVlIChmb3IKKyAqIGV4YW1wbGUgYSB7QGxpbmsgTGlua2VkQmxvY2tpbmdRdWV1ZX0gd2l0aG91dCBhIHByZWRlZmluZWQKKyAqIGNhcGFjaXR5KSB3aWxsIGNhdXNlIG5ldyB0YXNrcyB0byB3YWl0IGluIHRoZSBxdWV1ZSB3aGVuIGFsbAorICogY29yZVBvb2xTaXplIHRocmVhZHMgYXJlIGJ1c3kuIFRodXMsIG5vIG1vcmUgdGhhbiBjb3JlUG9vbFNpemUKKyAqIHRocmVhZHMgd2lsbCBldmVyIGJlIGNyZWF0ZWQuIChBbmQgdGhlIHZhbHVlIG9mIHRoZSBtYXhpbXVtUG9vbFNpemUKKyAqIHRoZXJlZm9yZSBkb2Vzbid0IGhhdmUgYW55IGVmZmVjdC4pICBUaGlzIG1heSBiZSBhcHByb3ByaWF0ZSB3aGVuCisgKiBlYWNoIHRhc2sgaXMgY29tcGxldGVseSBpbmRlcGVuZGVudCBvZiBvdGhlcnMsIHNvIHRhc2tzIGNhbm5vdAorICogYWZmZWN0IGVhY2ggb3RoZXJzIGV4ZWN1dGlvbjsgZm9yIGV4YW1wbGUsIGluIGEgd2ViIHBhZ2Ugc2VydmVyLgorICogV2hpbGUgdGhpcyBzdHlsZSBvZiBxdWV1aW5nIGNhbiBiZSB1c2VmdWwgaW4gc21vb3RoaW5nIG91dAorICogdHJhbnNpZW50IGJ1cnN0cyBvZiByZXF1ZXN0cywgaXQgYWRtaXRzIHRoZSBwb3NzaWJpbGl0eSBvZgorICogdW5ib3VuZGVkIHdvcmsgcXVldWUgZ3Jvd3RoIHdoZW4gY29tbWFuZHMgY29udGludWUgdG8gYXJyaXZlIG9uCisgKiBhdmVyYWdlIGZhc3RlciB0aGFuIHRoZXkgY2FuIGJlIHByb2Nlc3NlZC4gIDwvbGk+CisgKgorICogPGxpPjxlbT5Cb3VuZGVkIHF1ZXVlcy48L2VtPiBBIGJvdW5kZWQgcXVldWUgKGZvciBleGFtcGxlLCBhbgorICoge0BsaW5rIEFycmF5QmxvY2tpbmdRdWV1ZX0pIGhlbHBzIHByZXZlbnQgcmVzb3VyY2UgZXhoYXVzdGlvbiB3aGVuCisgKiB1c2VkIHdpdGggZmluaXRlIG1heGltdW1Qb29sU2l6ZXMsIGJ1dCBjYW4gYmUgbW9yZSBkaWZmaWN1bHQgdG8KKyAqIHR1bmUgYW5kIGNvbnRyb2wuICBRdWV1ZSBzaXplcyBhbmQgbWF4aW11bSBwb29sIHNpemVzIG1heSBiZSB0cmFkZWQKKyAqIG9mZiBmb3IgZWFjaCBvdGhlcjogVXNpbmcgbGFyZ2UgcXVldWVzIGFuZCBzbWFsbCBwb29scyBtaW5pbWl6ZXMKKyAqIENQVSB1c2FnZSwgT1MgcmVzb3VyY2VzLCBhbmQgY29udGV4dC1zd2l0Y2hpbmcgb3ZlcmhlYWQsIGJ1dCBjYW4KKyAqIGxlYWQgdG8gYXJ0aWZpY2lhbGx5IGxvdyB0aHJvdWdocHV0LiAgSWYgdGFza3MgZnJlcXVlbnRseSBibG9jayAoZm9yCisgKiBleGFtcGxlIGlmIHRoZXkgYXJlIEkvTyBib3VuZCksIGEgc3lzdGVtIG1heSBiZSBhYmxlIHRvIHNjaGVkdWxlCisgKiB0aW1lIGZvciBtb3JlIHRocmVhZHMgdGhhbiB5b3Ugb3RoZXJ3aXNlIGFsbG93LiBVc2Ugb2Ygc21hbGwgcXVldWVzCisgKiBnZW5lcmFsbHkgcmVxdWlyZXMgbGFyZ2VyIHBvb2wgc2l6ZXMsIHdoaWNoIGtlZXBzIENQVXMgYnVzaWVyIGJ1dAorICogbWF5IGVuY291bnRlciB1bmFjY2VwdGFibGUgc2NoZWR1bGluZyBvdmVyaGVhZCwgd2hpY2ggYWxzbworICogZGVjcmVhc2VzIHRocm91Z2hwdXQuICA8L2xpPgorICoKKyAqIDwvb2w+CisgKgorICogPC9kZD4KKyAqCisgKiA8ZHQ+UmVqZWN0ZWQgdGFza3M8L2R0PgorICoKKyAqIDxkZD4gTmV3IHRhc2tzIHN1Ym1pdHRlZCBpbiBtZXRob2Qge0BsaW5rICNleGVjdXRlfSB3aWxsIGJlCisgKiA8ZW0+cmVqZWN0ZWQ8L2VtPiB3aGVuIHRoZSBFeGVjdXRvciBoYXMgYmVlbiBzaHV0IGRvd24sIGFuZCBhbHNvCisgKiB3aGVuIHRoZSBFeGVjdXRvciB1c2VzIGZpbml0ZSBib3VuZHMgZm9yIGJvdGggbWF4aW11bSB0aHJlYWRzIGFuZAorICogd29yayBxdWV1ZSBjYXBhY2l0eSwgYW5kIGlzIHNhdHVyYXRlZC4gIEluIGVpdGhlciBjYXNlLCB0aGUge0Bjb2RlCisgKiBleGVjdXRlfSBtZXRob2QgaW52b2tlcyB0aGUge0BsaW5rCisgKiBSZWplY3RlZEV4ZWN1dGlvbkhhbmRsZXIjcmVqZWN0ZWRFeGVjdXRpb259IG1ldGhvZCBvZiBpdHMge0BsaW5rCisgKiBSZWplY3RlZEV4ZWN1dGlvbkhhbmRsZXJ9LiAgRm91ciBwcmVkZWZpbmVkIGhhbmRsZXIgcG9saWNpZXMgYXJlCisgKiBwcm92aWRlZDoKKyAqCisgKiA8b2w+CisgKgorICogPGxpPiBJbiB0aGUgZGVmYXVsdCB7QGxpbmsgVGhyZWFkUG9vbEV4ZWN1dG9yLkFib3J0UG9saWN5fSwgdGhlCisgKiBoYW5kbGVyIHRocm93cyBhIHJ1bnRpbWUge0BsaW5rIFJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9ufSB1cG9uCisgKiByZWplY3Rpb24uIDwvbGk+CisgKgorICogPGxpPiBJbiB7QGxpbmsgVGhyZWFkUG9vbEV4ZWN1dG9yLkNhbGxlclJ1bnNQb2xpY3l9LCB0aGUgdGhyZWFkCisgKiB0aGF0IGludm9rZXMge0Bjb2RlIGV4ZWN1dGV9IGl0c2VsZiBydW5zIHRoZSB0YXNrLiBUaGlzIHByb3ZpZGVzIGEKKyAqIHNpbXBsZSBmZWVkYmFjayBjb250cm9sIG1lY2hhbmlzbSB0aGF0IHdpbGwgc2xvdyBkb3duIHRoZSByYXRlIHRoYXQKKyAqIG5ldyB0YXNrcyBhcmUgc3VibWl0dGVkLiA8L2xpPgorICoKKyAqIDxsaT4gSW4ge0BsaW5rIFRocmVhZFBvb2xFeGVjdXRvci5EaXNjYXJkUG9saWN5fSwgYSB0YXNrIHRoYXQKKyAqIGNhbm5vdCBiZSBleGVjdXRlZCBpcyBzaW1wbHkgZHJvcHBlZC4gIDwvbGk+CisgKgorICogPGxpPkluIHtAbGluayBUaHJlYWRQb29sRXhlY3V0b3IuRGlzY2FyZE9sZGVzdFBvbGljeX0sIGlmIHRoZQorICogZXhlY3V0b3IgaXMgbm90IHNodXQgZG93biwgdGhlIHRhc2sgYXQgdGhlIGhlYWQgb2YgdGhlIHdvcmsgcXVldWUKKyAqIGlzIGRyb3BwZWQsIGFuZCB0aGVuIGV4ZWN1dGlvbiBpcyByZXRyaWVkICh3aGljaCBjYW4gZmFpbCBhZ2FpbiwKKyAqIGNhdXNpbmcgdGhpcyB0byBiZSByZXBlYXRlZC4pIDwvbGk+CisgKgorICogPC9vbD4KKyAqCisgKiBJdCBpcyBwb3NzaWJsZSB0byBkZWZpbmUgYW5kIHVzZSBvdGhlciBraW5kcyBvZiB7QGxpbmsKKyAqIFJlamVjdGVkRXhlY3V0aW9uSGFuZGxlcn0gY2xhc3Nlcy4gRG9pbmcgc28gcmVxdWlyZXMgc29tZSBjYXJlCisgKiBlc3BlY2lhbGx5IHdoZW4gcG9saWNpZXMgYXJlIGRlc2lnbmVkIHRvIHdvcmsgb25seSB1bmRlciBwYXJ0aWN1bGFyCisgKiBjYXBhY2l0eSBvciBxdWV1aW5nIHBvbGljaWVzLiA8L2RkPgorICoKKyAqIDxkdD5Ib29rIG1ldGhvZHM8L2R0PgorICoKKyAqIDxkZD5UaGlzIGNsYXNzIHByb3ZpZGVzIHtAY29kZSBwcm90ZWN0ZWR9IG92ZXJyaWRhYmxlIHtAbGluaworICogI2JlZm9yZUV4ZWN1dGV9IGFuZCB7QGxpbmsgI2FmdGVyRXhlY3V0ZX0gbWV0aG9kcyB0aGF0IGFyZSBjYWxsZWQKKyAqIGJlZm9yZSBhbmQgYWZ0ZXIgZXhlY3V0aW9uIG9mIGVhY2ggdGFzay4gIFRoZXNlIGNhbiBiZSB1c2VkIHRvCisgKiBtYW5pcHVsYXRlIHRoZSBleGVjdXRpb24gZW52aXJvbm1lbnQ7IGZvciBleGFtcGxlLCByZWluaXRpYWxpemluZworICogVGhyZWFkTG9jYWxzLCBnYXRoZXJpbmcgc3RhdGlzdGljcywgb3IgYWRkaW5nIGxvZworICogZW50cmllcy4gQWRkaXRpb25hbGx5LCBtZXRob2Qge0BsaW5rICN0ZXJtaW5hdGVkfSBjYW4gYmUgb3ZlcnJpZGRlbgorICogdG8gcGVyZm9ybSBhbnkgc3BlY2lhbCBwcm9jZXNzaW5nIHRoYXQgbmVlZHMgdG8gYmUgZG9uZSBvbmNlIHRoZQorICogRXhlY3V0b3IgaGFzIGZ1bGx5IHRlcm1pbmF0ZWQuCisgKgorICogPHA+SWYgaG9vayBvciBjYWxsYmFjayBtZXRob2RzIHRocm93IGV4Y2VwdGlvbnMsIGludGVybmFsIHdvcmtlcgorICogdGhyZWFkcyBtYXkgaW4gdHVybiBmYWlsIGFuZCBhYnJ1cHRseSB0ZXJtaW5hdGUuPC9kZD4KKyAqCisgKiA8ZHQ+UXVldWUgbWFpbnRlbmFuY2U8L2R0PgorICoKKyAqIDxkZD4gTWV0aG9kIHtAbGluayAjZ2V0UXVldWV9IGFsbG93cyBhY2Nlc3MgdG8gdGhlIHdvcmsgcXVldWUgZm9yCisgKiBwdXJwb3NlcyBvZiBtb25pdG9yaW5nIGFuZCBkZWJ1Z2dpbmcuICBVc2Ugb2YgdGhpcyBtZXRob2QgZm9yIGFueQorICogb3RoZXIgcHVycG9zZSBpcyBzdHJvbmdseSBkaXNjb3VyYWdlZC4gIFR3byBzdXBwbGllZCBtZXRob2RzLAorICoge0BsaW5rICNyZW1vdmV9IGFuZCB7QGxpbmsgI3B1cmdlfSBhcmUgYXZhaWxhYmxlIHRvIGFzc2lzdCBpbgorICogc3RvcmFnZSByZWNsYW1hdGlvbiB3aGVuIGxhcmdlIG51bWJlcnMgb2YgcXVldWVkIHRhc2tzIGJlY29tZQorICogY2FuY2VsbGVkLjwvZGQ+CisgKgorICogPGR0PkZpbmFsaXphdGlvbjwvZHQ+CisgKgorICogPGRkPiBBIHBvb2wgdGhhdCBpcyBubyBsb25nZXIgcmVmZXJlbmNlZCBpbiBhIHByb2dyYW0gPGVtPkFORDwvZW0+CisgKiBoYXMgbm8gcmVtYWluaW5nIHRocmVhZHMgd2lsbCBiZSB7QGNvZGUgc2h1dGRvd259IGF1dG9tYXRpY2FsbHkuIElmCisgKiB5b3Ugd291bGQgbGlrZSB0byBlbnN1cmUgdGhhdCB1bnJlZmVyZW5jZWQgcG9vbHMgYXJlIHJlY2xhaW1lZCBldmVuCisgKiBpZiB1c2VycyBmb3JnZXQgdG8gY2FsbCB7QGxpbmsgI3NodXRkb3dufSwgdGhlbiB5b3UgbXVzdCBhcnJhbmdlCisgKiB0aGF0IHVudXNlZCB0aHJlYWRzIGV2ZW50dWFsbHkgZGllLCBieSBzZXR0aW5nIGFwcHJvcHJpYXRlCisgKiBrZWVwLWFsaXZlIHRpbWVzLCB1c2luZyBhIGxvd2VyIGJvdW5kIG9mIHplcm8gY29yZSB0aHJlYWRzIGFuZC9vcgorICogc2V0dGluZyB7QGxpbmsgI2FsbG93Q29yZVRocmVhZFRpbWVPdXQoYm9vbGVhbil9LiAgPC9kZD4KKyAqCisgKiA8L2RsPgorICoKKyAqIDxwPiA8Yj5FeHRlbnNpb24gZXhhbXBsZTwvYj4uIE1vc3QgZXh0ZW5zaW9ucyBvZiB0aGlzIGNsYXNzCisgKiBvdmVycmlkZSBvbmUgb3IgbW9yZSBvZiB0aGUgcHJvdGVjdGVkIGhvb2sgbWV0aG9kcy4gRm9yIGV4YW1wbGUsCisgKiBoZXJlIGlzIGEgc3ViY2xhc3MgdGhhdCBhZGRzIGEgc2ltcGxlIHBhdXNlL3Jlc3VtZSBmZWF0dXJlOgorICoKKyAqICA8cHJlPiB7QGNvZGUKKyAqIGNsYXNzIFBhdXNhYmxlVGhyZWFkUG9vbEV4ZWN1dG9yIGV4dGVuZHMgVGhyZWFkUG9vbEV4ZWN1dG9yIHsKKyAqICAgcHJpdmF0ZSBib29sZWFuIGlzUGF1c2VkOworICogICBwcml2YXRlIFJlZW50cmFudExvY2sgcGF1c2VMb2NrID0gbmV3IFJlZW50cmFudExvY2soKTsKKyAqICAgcHJpdmF0ZSBDb25kaXRpb24gdW5wYXVzZWQgPSBwYXVzZUxvY2submV3Q29uZGl0aW9uKCk7CisgKgorICogICBwdWJsaWMgUGF1c2FibGVUaHJlYWRQb29sRXhlY3V0b3IoLi4uKSB7IHN1cGVyKC4uLik7IH0KKyAqCisgKiAgIHByb3RlY3RlZCB2b2lkIGJlZm9yZUV4ZWN1dGUoVGhyZWFkIHQsIFJ1bm5hYmxlIHIpIHsKKyAqICAgICBzdXBlci5iZWZvcmVFeGVjdXRlKHQsIHIpOworICogICAgIHBhdXNlTG9jay5sb2NrKCk7CisgKiAgICAgdHJ5IHsKKyAqICAgICAgIHdoaWxlIChpc1BhdXNlZCkgdW5wYXVzZWQuYXdhaXQoKTsKKyAqICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSkgeworICogICAgICAgdC5pbnRlcnJ1cHQoKTsKKyAqICAgICB9IGZpbmFsbHkgeworICogICAgICAgcGF1c2VMb2NrLnVubG9jaygpOworICogICAgIH0KKyAqICAgfQorICoKKyAqICAgcHVibGljIHZvaWQgcGF1c2UoKSB7CisgKiAgICAgcGF1c2VMb2NrLmxvY2soKTsKKyAqICAgICB0cnkgeworICogICAgICAgaXNQYXVzZWQgPSB0cnVlOworICogICAgIH0gZmluYWxseSB7CisgKiAgICAgICBwYXVzZUxvY2sudW5sb2NrKCk7CisgKiAgICAgfQorICogICB9CisgKgorICogICBwdWJsaWMgdm9pZCByZXN1bWUoKSB7CisgKiAgICAgcGF1c2VMb2NrLmxvY2soKTsKKyAqICAgICB0cnkgeworICogICAgICAgaXNQYXVzZWQgPSBmYWxzZTsKKyAqICAgICAgIHVucGF1c2VkLnNpZ25hbEFsbCgpOworICogICAgIH0gZmluYWxseSB7CisgKiAgICAgICBwYXVzZUxvY2sudW5sb2NrKCk7CisgKiAgICAgfQorICogICB9CisgKiB9fTwvcHJlPgorICoKKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqLworcHVibGljIGNsYXNzIFRocmVhZFBvb2xFeGVjdXRvciBleHRlbmRzIEFic3RyYWN0RXhlY3V0b3JTZXJ2aWNlIHsKKyAgICAvKioKKyAgICAgKiBUaGUgbWFpbiBwb29sIGNvbnRyb2wgc3RhdGUsIGN0bCwgaXMgYW4gYXRvbWljIGludGVnZXIgcGFja2luZworICAgICAqIHR3byBjb25jZXB0dWFsIGZpZWxkcworICAgICAqICAgd29ya2VyQ291bnQsIGluZGljYXRpbmcgdGhlIGVmZmVjdGl2ZSBudW1iZXIgb2YgdGhyZWFkcworICAgICAqICAgcnVuU3RhdGUsICAgIGluZGljYXRpbmcgd2hldGhlciBydW5uaW5nLCBzaHV0dGluZyBkb3duIGV0YworICAgICAqCisgICAgICogSW4gb3JkZXIgdG8gcGFjayB0aGVtIGludG8gb25lIGludCwgd2UgbGltaXQgd29ya2VyQ291bnQgdG8KKyAgICAgKiAoMl4yOSktMSAoYWJvdXQgNTAwIG1pbGxpb24pIHRocmVhZHMgcmF0aGVyIHRoYW4gKDJeMzEpLTEgKDIKKyAgICAgKiBiaWxsaW9uKSBvdGhlcndpc2UgcmVwcmVzZW50YWJsZS4gSWYgdGhpcyBpcyBldmVyIGFuIGlzc3VlIGluCisgICAgICogdGhlIGZ1dHVyZSwgdGhlIHZhcmlhYmxlIGNhbiBiZSBjaGFuZ2VkIHRvIGJlIGFuIEF0b21pY0xvbmcsCisgICAgICogYW5kIHRoZSBzaGlmdC9tYXNrIGNvbnN0YW50cyBiZWxvdyBhZGp1c3RlZC4gQnV0IHVudGlsIHRoZSBuZWVkCisgICAgICogYXJpc2VzLCB0aGlzIGNvZGUgaXMgYSBiaXQgZmFzdGVyIGFuZCBzaW1wbGVyIHVzaW5nIGFuIGludC4KKyAgICAgKgorICAgICAqIFRoZSB3b3JrZXJDb3VudCBpcyB0aGUgbnVtYmVyIG9mIHdvcmtlcnMgdGhhdCBoYXZlIGJlZW4KKyAgICAgKiBwZXJtaXR0ZWQgdG8gc3RhcnQgYW5kIG5vdCBwZXJtaXR0ZWQgdG8gc3RvcC4gIFRoZSB2YWx1ZSBtYXkgYmUKKyAgICAgKiB0cmFuc2llbnRseSBkaWZmZXJlbnQgZnJvbSB0aGUgYWN0dWFsIG51bWJlciBvZiBsaXZlIHRocmVhZHMsCisgICAgICogZm9yIGV4YW1wbGUgd2hlbiBhIFRocmVhZEZhY3RvcnkgZmFpbHMgdG8gY3JlYXRlIGEgdGhyZWFkIHdoZW4KKyAgICAgKiBhc2tlZCwgYW5kIHdoZW4gZXhpdGluZyB0aHJlYWRzIGFyZSBzdGlsbCBwZXJmb3JtaW5nCisgICAgICogYm9va2tlZXBpbmcgYmVmb3JlIHRlcm1pbmF0aW5nLiBUaGUgdXNlci12aXNpYmxlIHBvb2wgc2l6ZSBpcworICAgICAqIHJlcG9ydGVkIGFzIHRoZSBjdXJyZW50IHNpemUgb2YgdGhlIHdvcmtlcnMgc2V0LgorICAgICAqCisgICAgICogVGhlIHJ1blN0YXRlIHByb3ZpZGVzIHRoZSBtYWluIGxpZmVjeWxlIGNvbnRyb2wsIHRha2luZyBvbiB2YWx1ZXM6CisgICAgICoKKyAgICAgKiAgIFJVTk5JTkc6ICBBY2NlcHQgbmV3IHRhc2tzIGFuZCBwcm9jZXNzIHF1ZXVlZCB0YXNrcworICAgICAqICAgU0hVVERPV046IERvbid0IGFjY2VwdCBuZXcgdGFza3MsIGJ1dCBwcm9jZXNzIHF1ZXVlZCB0YXNrcworICAgICAqICAgU1RPUDogICAgIERvbid0IGFjY2VwdCBuZXcgdGFza3MsIGRvbid0IHByb2Nlc3MgcXVldWVkIHRhc2tzLAorICAgICAqICAgICAgICAgICAgIGFuZCBpbnRlcnJ1cHQgaW4tcHJvZ3Jlc3MgdGFza3MKKyAgICAgKiAgIFRJRFlJTkc6ICBBbGwgdGFza3MgaGF2ZSB0ZXJtaW5hdGVkLCB3b3JrZXJDb3VudCBpcyB6ZXJvLAorICAgICAqICAgICAgICAgICAgIHRoZSB0aHJlYWQgdHJhbnNpdGlvbmluZyB0byBzdGF0ZSBUSURZSU5HCisgICAgICogICAgICAgICAgICAgd2lsbCBydW4gdGhlIHRlcm1pbmF0ZWQoKSBob29rIG1ldGhvZAorICAgICAqICAgVEVSTUlOQVRFRDogdGVybWluYXRlZCgpIGhhcyBjb21wbGV0ZWQKKyAgICAgKgorICAgICAqIFRoZSBudW1lcmljYWwgb3JkZXIgYW1vbmcgdGhlc2UgdmFsdWVzIG1hdHRlcnMsIHRvIGFsbG93CisgICAgICogb3JkZXJlZCBjb21wYXJpc29ucy4gVGhlIHJ1blN0YXRlIG1vbm90b25pY2FsbHkgaW5jcmVhc2VzIG92ZXIKKyAgICAgKiB0aW1lLCBidXQgbmVlZCBub3QgaGl0IGVhY2ggc3RhdGUuIFRoZSB0cmFuc2l0aW9ucyBhcmU6CisgICAgICoKKyAgICAgKiBSVU5OSU5HIC0+IFNIVVRET1dOCisgICAgICogICAgT24gaW52b2NhdGlvbiBvZiBzaHV0ZG93bigpLCBwZXJoYXBzIGltcGxpY2l0bHkgaW4gZmluYWxpemUoKQorICAgICAqIChSVU5OSU5HIG9yIFNIVVRET1dOKSAtPiBTVE9QCisgICAgICogICAgT24gaW52b2NhdGlvbiBvZiBzaHV0ZG93bk5vdygpCisgICAgICogU0hVVERPV04gLT4gVElEWUlORworICAgICAqICAgIFdoZW4gYm90aCBxdWV1ZSBhbmQgcG9vbCBhcmUgZW1wdHkKKyAgICAgKiBTVE9QIC0+IFRJRFlJTkcKKyAgICAgKiAgICBXaGVuIHBvb2wgaXMgZW1wdHkKKyAgICAgKiBUSURZSU5HIC0+IFRFUk1JTkFURUQKKyAgICAgKiAgICBXaGVuIHRoZSB0ZXJtaW5hdGVkKCkgaG9vayBtZXRob2QgaGFzIGNvbXBsZXRlZAorICAgICAqCisgICAgICogVGhyZWFkcyB3YWl0aW5nIGluIGF3YWl0VGVybWluYXRpb24oKSB3aWxsIHJldHVybiB3aGVuIHRoZQorICAgICAqIHN0YXRlIHJlYWNoZXMgVEVSTUlOQVRFRC4KKyAgICAgKgorICAgICAqIERldGVjdGluZyB0aGUgdHJhbnNpdGlvbiBmcm9tIFNIVVRET1dOIHRvIFRJRFlJTkcgaXMgbGVzcworICAgICAqIHN0cmFpZ2h0Zm9yd2FyZCB0aGFuIHlvdSdkIGxpa2UgYmVjYXVzZSB0aGUgcXVldWUgbWF5IGJlY29tZQorICAgICAqIGVtcHR5IGFmdGVyIG5vbi1lbXB0eSBhbmQgdmljZSB2ZXJzYSBkdXJpbmcgU0hVVERPV04gc3RhdGUsIGJ1dAorICAgICAqIHdlIGNhbiBvbmx5IHRlcm1pbmF0ZSBpZiwgYWZ0ZXIgc2VlaW5nIHRoYXQgaXQgaXMgZW1wdHksIHdlIHNlZQorICAgICAqIHRoYXQgd29ya2VyQ291bnQgaXMgMCAod2hpY2ggc29tZXRpbWVzIGVudGFpbHMgYSByZWNoZWNrIC0tIHNlZQorICAgICAqIGJlbG93KS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIEF0b21pY0ludGVnZXIgY3RsID0gbmV3IEF0b21pY0ludGVnZXIoY3RsT2YoUlVOTklORywgMCkpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDT1VOVF9CSVRTID0gSW50ZWdlci5TSVpFIC0gMzsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0FQQUNJVFkgICA9ICgxIDw8IENPVU5UX0JJVFMpIC0gMTsKKworICAgIC8vIHJ1blN0YXRlIGlzIHN0b3JlZCBpbiB0aGUgaGlnaC1vcmRlciBiaXRzCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJVTk5JTkcgICAgPSAtMSA8PCBDT1VOVF9CSVRTOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTSFVURE9XTiAgID0gIDAgPDwgQ09VTlRfQklUUzsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU1RPUCAgICAgICA9ICAxIDw8IENPVU5UX0JJVFM7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRJRFlJTkcgICAgPSAgMiA8PCBDT1VOVF9CSVRTOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBURVJNSU5BVEVEID0gIDMgPDwgQ09VTlRfQklUUzsKKworICAgIC8vIFBhY2tpbmcgYW5kIHVucGFja2luZyBjdGwKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgcnVuU3RhdGVPZihpbnQgYykgICAgIHsgcmV0dXJuIGMgJiB+Q0FQQUNJVFk7IH0KKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgd29ya2VyQ291bnRPZihpbnQgYykgIHsgcmV0dXJuIGMgJiBDQVBBQ0lUWTsgfQorICAgIHByaXZhdGUgc3RhdGljIGludCBjdGxPZihpbnQgcnMsIGludCB3YykgeyByZXR1cm4gcnMgfCB3YzsgfQorCisgICAgLyoKKyAgICAgKiBCaXQgZmllbGQgYWNjZXNzb3JzIHRoYXQgZG9uJ3QgcmVxdWlyZSB1bnBhY2tpbmcgY3RsLgorICAgICAqIFRoZXNlIGRlcGVuZCBvbiB0aGUgYml0IGxheW91dCBhbmQgb24gd29ya2VyQ291bnQgYmVpbmcgbmV2ZXIgbmVnYXRpdmUuCisgICAgICovCisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHJ1blN0YXRlTGVzc1RoYW4oaW50IGMsIGludCBzKSB7CisgICAgICAgIHJldHVybiBjIDwgczsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHJ1blN0YXRlQXRMZWFzdChpbnQgYywgaW50IHMpIHsKKyAgICAgICAgcmV0dXJuIGMgPj0gczsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzUnVubmluZyhpbnQgYykgeworICAgICAgICByZXR1cm4gYyA8IFNIVVRET1dOOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0dGVtcHQgdG8gQ0FTLWluY3JlbWVudCB0aGUgd29ya2VyQ291bnQgZmllbGQgb2YgY3RsLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBjb21wYXJlQW5kSW5jcmVtZW50V29ya2VyQ291bnQoaW50IGV4cGVjdCkgeworICAgICAgICByZXR1cm4gY3RsLmNvbXBhcmVBbmRTZXQoZXhwZWN0LCBleHBlY3QgKyAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdHRlbXB0IHRvIENBUy1kZWNyZW1lbnQgdGhlIHdvcmtlckNvdW50IGZpZWxkIG9mIGN0bC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gY29tcGFyZUFuZERlY3JlbWVudFdvcmtlckNvdW50KGludCBleHBlY3QpIHsKKyAgICAgICAgcmV0dXJuIGN0bC5jb21wYXJlQW5kU2V0KGV4cGVjdCwgZXhwZWN0IC0gMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVjcmVtZW50cyB0aGUgd29ya2VyQ291bnQgZmllbGQgb2YgY3RsLiBUaGlzIGlzIGNhbGxlZCBvbmx5IG9uCisgICAgICogYWJydXB0IHRlcm1pbmF0aW9uIG9mIGEgdGhyZWFkIChzZWUgcHJvY2Vzc1dvcmtlckV4aXQpLiBPdGhlcgorICAgICAqIGRlY3JlbWVudHMgYXJlIHBlcmZvcm1lZCB3aXRoaW4gZ2V0VGFzay4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZGVjcmVtZW50V29ya2VyQ291bnQoKSB7CisgICAgICAgIGRvIHt9IHdoaWxlICghIGNvbXBhcmVBbmREZWNyZW1lbnRXb3JrZXJDb3VudChjdGwuZ2V0KCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgcXVldWUgdXNlZCBmb3IgaG9sZGluZyB0YXNrcyBhbmQgaGFuZGluZyBvZmYgdG8gd29ya2VyCisgICAgICogdGhyZWFkcy4gIFdlIGRvIG5vdCByZXF1aXJlIHRoYXQgd29ya1F1ZXVlLnBvbGwoKSByZXR1cm5pbmcKKyAgICAgKiBudWxsIG5lY2Vzc2FyaWx5IG1lYW5zIHRoYXQgd29ya1F1ZXVlLmlzRW1wdHkoKSwgc28gcmVseQorICAgICAqIHNvbGVseSBvbiBpc0VtcHR5IHRvIHNlZSBpZiB0aGUgcXVldWUgaXMgZW1wdHkgKHdoaWNoIHdlIG11c3QKKyAgICAgKiBkbyBmb3IgZXhhbXBsZSB3aGVuIGRlY2lkaW5nIHdoZXRoZXIgdG8gdHJhbnNpdGlvbiBmcm9tCisgICAgICogU0hVVERPV04gdG8gVElEWUlORykuICBUaGlzIGFjY29tbW9kYXRlcyBzcGVjaWFsLXB1cnBvc2UKKyAgICAgKiBxdWV1ZXMgc3VjaCBhcyBEZWxheVF1ZXVlcyBmb3Igd2hpY2ggcG9sbCgpIGlzIGFsbG93ZWQgdG8KKyAgICAgKiByZXR1cm4gbnVsbCBldmVuIGlmIGl0IG1heSBsYXRlciByZXR1cm4gbm9uLW51bGwgd2hlbiBkZWxheXMKKyAgICAgKiBleHBpcmUuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBCbG9ja2luZ1F1ZXVlPFJ1bm5hYmxlPiB3b3JrUXVldWU7CisKKyAgICAvKioKKyAgICAgKiBMb2NrIGhlbGQgb24gYWNjZXNzIHRvIHdvcmtlcnMgc2V0IGFuZCByZWxhdGVkIGJvb2trZWVwaW5nLgorICAgICAqIFdoaWxlIHdlIGNvdWxkIHVzZSBhIGNvbmN1cnJlbnQgc2V0IG9mIHNvbWUgc29ydCwgaXQgdHVybnMgb3V0CisgICAgICogdG8gYmUgZ2VuZXJhbGx5IHByZWZlcmFibGUgdG8gdXNlIGEgbG9jay4gQW1vbmcgdGhlIHJlYXNvbnMgaXMKKyAgICAgKiB0aGF0IHRoaXMgc2VyaWFsaXplcyBpbnRlcnJ1cHRJZGxlV29ya2Vycywgd2hpY2ggYXZvaWRzCisgICAgICogdW5uZWNlc3NhcnkgaW50ZXJydXB0IHN0b3JtcywgZXNwZWNpYWxseSBkdXJpbmcgc2h1dGRvd24uCisgICAgICogT3RoZXJ3aXNlIGV4aXRpbmcgdGhyZWFkcyB3b3VsZCBjb25jdXJyZW50bHkgaW50ZXJydXB0IHRob3NlCisgICAgICogdGhhdCBoYXZlIG5vdCB5ZXQgaW50ZXJydXB0ZWQuIEl0IGFsc28gc2ltcGxpZmllcyBzb21lIG9mIHRoZQorICAgICAqIGFzc29jaWF0ZWQgc3RhdGlzdGljcyBib29ra2VlcGluZyBvZiBsYXJnZXN0UG9vbFNpemUgZXRjLiBXZQorICAgICAqIGFsc28gaG9sZCBtYWluTG9jayBvbiBzaHV0ZG93biBhbmQgc2h1dGRvd25Ob3csIGZvciB0aGUgc2FrZSBvZgorICAgICAqIGVuc3VyaW5nIHdvcmtlcnMgc2V0IGlzIHN0YWJsZSB3aGlsZSBzZXBhcmF0ZWx5IGNoZWNraW5nCisgICAgICogcGVybWlzc2lvbiB0byBpbnRlcnJ1cHQgYW5kIGFjdHVhbGx5IGludGVycnVwdGluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFJlZW50cmFudExvY2sgbWFpbkxvY2sgPSBuZXcgUmVlbnRyYW50TG9jaygpOworCisgICAgLyoqCisgICAgICogU2V0IGNvbnRhaW5pbmcgYWxsIHdvcmtlciB0aHJlYWRzIGluIHBvb2wuIEFjY2Vzc2VkIG9ubHkgd2hlbgorICAgICAqIGhvbGRpbmcgbWFpbkxvY2suCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBIYXNoU2V0PFdvcmtlcj4gd29ya2VycyA9IG5ldyBIYXNoU2V0PFdvcmtlcj4oKTsKKworICAgIC8qKgorICAgICAqIFdhaXQgY29uZGl0aW9uIHRvIHN1cHBvcnQgYXdhaXRUZXJtaW5hdGlvbgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgQ29uZGl0aW9uIHRlcm1pbmF0aW9uID0gbWFpbkxvY2submV3Q29uZGl0aW9uKCk7CisKKyAgICAvKioKKyAgICAgKiBUcmFja3MgbGFyZ2VzdCBhdHRhaW5lZCBwb29sIHNpemUuIEFjY2Vzc2VkIG9ubHkgdW5kZXIKKyAgICAgKiBtYWluTG9jay4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBsYXJnZXN0UG9vbFNpemU7CisKKyAgICAvKioKKyAgICAgKiBDb3VudGVyIGZvciBjb21wbGV0ZWQgdGFza3MuIFVwZGF0ZWQgb25seSBvbiB0ZXJtaW5hdGlvbiBvZgorICAgICAqIHdvcmtlciB0aHJlYWRzLiBBY2Nlc3NlZCBvbmx5IHVuZGVyIG1haW5Mb2NrLgorICAgICAqLworICAgIHByaXZhdGUgbG9uZyBjb21wbGV0ZWRUYXNrQ291bnQ7CisKKyAgICAvKgorICAgICAqIEFsbCB1c2VyIGNvbnRyb2wgcGFyYW1ldGVycyBhcmUgZGVjbGFyZWQgYXMgdm9sYXRpbGVzIHNvIHRoYXQKKyAgICAgKiBvbmdvaW5nIGFjdGlvbnMgYXJlIGJhc2VkIG9uIGZyZXNoZXN0IHZhbHVlcywgYnV0IHdpdGhvdXQgbmVlZAorICAgICAqIGZvciBsb2NraW5nLCBzaW5jZSBubyBpbnRlcm5hbCBpbnZhcmlhbnRzIGRlcGVuZCBvbiB0aGVtCisgICAgICogY2hhbmdpbmcgc3luY2hyb25vdXNseSB3aXRoIHJlc3BlY3QgdG8gb3RoZXIgYWN0aW9ucy4KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIEZhY3RvcnkgZm9yIG5ldyB0aHJlYWRzLiBBbGwgdGhyZWFkcyBhcmUgY3JlYXRlZCB1c2luZyB0aGlzCisgICAgICogZmFjdG9yeSAodmlhIG1ldGhvZCBhZGRXb3JrZXIpLiAgQWxsIGNhbGxlcnMgbXVzdCBiZSBwcmVwYXJlZAorICAgICAqIGZvciBhZGRXb3JrZXIgdG8gZmFpbCwgd2hpY2ggbWF5IHJlZmxlY3QgYSBzeXN0ZW0gb3IgdXNlcidzCisgICAgICogcG9saWN5IGxpbWl0aW5nIHRoZSBudW1iZXIgb2YgdGhyZWFkcy4gIEV2ZW4gdGhvdWdoIGl0IGlzIG5vdAorICAgICAqIHRyZWF0ZWQgYXMgYW4gZXJyb3IsIGZhaWx1cmUgdG8gY3JlYXRlIHRocmVhZHMgbWF5IHJlc3VsdCBpbgorICAgICAqIG5ldyB0YXNrcyBiZWluZyByZWplY3RlZCBvciBleGlzdGluZyBvbmVzIHJlbWFpbmluZyBzdHVjayBpbgorICAgICAqIHRoZSBxdWV1ZS4gT24gdGhlIG90aGVyIGhhbmQsIG5vIHNwZWNpYWwgcHJlY2F1dGlvbnMgZXhpc3QgdG8KKyAgICAgKiBoYW5kbGUgT3V0T2ZNZW1vcnlFcnJvcnMgdGhhdCBtaWdodCBiZSB0aHJvd24gd2hpbGUgdHJ5aW5nIHRvCisgICAgICogY3JlYXRlIHRocmVhZHMsIHNpbmNlIHRoZXJlIGlzIGdlbmVyYWxseSBubyByZWNvdXJzZSBmcm9tCisgICAgICogd2l0aGluIHRoaXMgY2xhc3MuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBUaHJlYWRGYWN0b3J5IHRocmVhZEZhY3Rvcnk7CisKKyAgICAvKioKKyAgICAgKiBIYW5kbGVyIGNhbGxlZCB3aGVuIHNhdHVyYXRlZCBvciBzaHV0ZG93biBpbiBleGVjdXRlLgorICAgICAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgUmVqZWN0ZWRFeGVjdXRpb25IYW5kbGVyIGhhbmRsZXI7CisKKyAgICAvKioKKyAgICAgKiBUaW1lb3V0IGluIG5hbm9zZWNvbmRzIGZvciBpZGxlIHRocmVhZHMgd2FpdGluZyBmb3Igd29yay4KKyAgICAgKiBUaHJlYWRzIHVzZSB0aGlzIHRpbWVvdXQgd2hlbiB0aGVyZSBhcmUgbW9yZSB0aGFuIGNvcmVQb29sU2l6ZQorICAgICAqIHByZXNlbnQgb3IgaWYgYWxsb3dDb3JlVGhyZWFkVGltZU91dC4gT3RoZXJ3aXNlIHRoZXkgd2FpdAorICAgICAqIGZvcmV2ZXIgZm9yIG5ldyB3b3JrLgorICAgICAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgbG9uZyBrZWVwQWxpdmVUaW1lOworCisgICAgLyoqCisgICAgICogSWYgZmFsc2UgKGRlZmF1bHQpLCBjb3JlIHRocmVhZHMgc3RheSBhbGl2ZSBldmVuIHdoZW4gaWRsZS4KKyAgICAgKiBJZiB0cnVlLCBjb3JlIHRocmVhZHMgdXNlIGtlZXBBbGl2ZVRpbWUgdG8gdGltZSBvdXQgd2FpdGluZworICAgICAqIGZvciB3b3JrLgorICAgICAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiBhbGxvd0NvcmVUaHJlYWRUaW1lT3V0OworCisgICAgLyoqCisgICAgICogQ29yZSBwb29sIHNpemUgaXMgdGhlIG1pbmltdW0gbnVtYmVyIG9mIHdvcmtlcnMgdG8ga2VlcCBhbGl2ZQorICAgICAqIChhbmQgbm90IGFsbG93IHRvIHRpbWUgb3V0IGV0YykgdW5sZXNzIGFsbG93Q29yZVRocmVhZFRpbWVPdXQKKyAgICAgKiBpcyBzZXQsIGluIHdoaWNoIGNhc2UgdGhlIG1pbmltdW0gaXMgemVyby4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvbGF0aWxlIGludCBjb3JlUG9vbFNpemU7CisKKyAgICAvKioKKyAgICAgKiBNYXhpbXVtIHBvb2wgc2l6ZS4gTm90ZSB0aGF0IHRoZSBhY3R1YWwgbWF4aW11bSBpcyBpbnRlcm5hbGx5CisgICAgICogYm91bmRlZCBieSBDQVBBQ0lUWS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvbGF0aWxlIGludCBtYXhpbXVtUG9vbFNpemU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGVmYXVsdCByZWplY3RlZCBleGVjdXRpb24gaGFuZGxlcgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFJlamVjdGVkRXhlY3V0aW9uSGFuZGxlciBkZWZhdWx0SGFuZGxlciA9CisgICAgICAgIG5ldyBBYm9ydFBvbGljeSgpOworCisgICAgLyoqCisgICAgICogUGVybWlzc2lvbiByZXF1aXJlZCBmb3IgY2FsbGVycyBvZiBzaHV0ZG93biBhbmQgc2h1dGRvd25Ob3cuCisgICAgICogV2UgYWRkaXRpb25hbGx5IHJlcXVpcmUgKHNlZSBjaGVja1NodXRkb3duQWNjZXNzKSB0aGF0IGNhbGxlcnMKKyAgICAgKiBoYXZlIHBlcm1pc3Npb24gdG8gYWN0dWFsbHkgaW50ZXJydXB0IHRocmVhZHMgaW4gdGhlIHdvcmtlciBzZXQKKyAgICAgKiAoYXMgZ292ZXJuZWQgYnkgVGhyZWFkLmludGVycnVwdCwgd2hpY2ggcmVsaWVzIG9uCisgICAgICogVGhyZWFkR3JvdXAuY2hlY2tBY2Nlc3MsIHdoaWNoIGluIHR1cm4gcmVsaWVzIG9uCisgICAgICogU2VjdXJpdHlNYW5hZ2VyLmNoZWNrQWNjZXNzKS4gU2h1dGRvd25zIGFyZSBhdHRlbXB0ZWQgb25seSBpZgorICAgICAqIHRoZXNlIGNoZWNrcyBwYXNzLgorICAgICAqCisgICAgICogQWxsIGFjdHVhbCBpbnZvY2F0aW9ucyBvZiBUaHJlYWQuaW50ZXJydXB0IChzZWUKKyAgICAgKiBpbnRlcnJ1cHRJZGxlV29ya2VycyBhbmQgaW50ZXJydXB0V29ya2VycykgaWdub3JlCisgICAgICogU2VjdXJpdHlFeGNlcHRpb25zLCBtZWFuaW5nIHRoYXQgdGhlIGF0dGVtcHRlZCBpbnRlcnJ1cHRzCisgICAgICogc2lsZW50bHkgZmFpbC4gSW4gdGhlIGNhc2Ugb2Ygc2h1dGRvd24sIHRoZXkgc2hvdWxkIG5vdCBmYWlsCisgICAgICogdW5sZXNzIHRoZSBTZWN1cml0eU1hbmFnZXIgaGFzIGluY29uc2lzdGVudCBwb2xpY2llcywgc29tZXRpbWVzCisgICAgICogYWxsb3dpbmcgYWNjZXNzIHRvIGEgdGhyZWFkIGFuZCBzb21ldGltZXMgbm90LiBJbiBzdWNoIGNhc2VzLAorICAgICAqIGZhaWx1cmUgdG8gYWN0dWFsbHkgaW50ZXJydXB0IHRocmVhZHMgbWF5IGRpc2FibGUgb3IgZGVsYXkgZnVsbAorICAgICAqIHRlcm1pbmF0aW9uLiBPdGhlciB1c2VzIG9mIGludGVycnVwdElkbGVXb3JrZXJzIGFyZSBhZHZpc29yeSwKKyAgICAgKiBhbmQgZmFpbHVyZSB0byBhY3R1YWxseSBpbnRlcnJ1cHQgd2lsbCBtZXJlbHkgZGVsYXkgcmVzcG9uc2UgdG8KKyAgICAgKiBjb25maWd1cmF0aW9uIGNoYW5nZXMgc28gaXMgbm90IGhhbmRsZWQgZXhjZXB0aW9uYWxseS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBSdW50aW1lUGVybWlzc2lvbiBzaHV0ZG93blBlcm0gPQorICAgICAgICBuZXcgUnVudGltZVBlcm1pc3Npb24oIm1vZGlmeVRocmVhZCIpOworCisgICAgLyoqCisgICAgICogQ2xhc3MgV29ya2VyIG1haW5seSBtYWludGFpbnMgaW50ZXJydXB0IGNvbnRyb2wgc3RhdGUgZm9yCisgICAgICogdGhyZWFkcyBydW5uaW5nIHRhc2tzLCBhbG9uZyB3aXRoIG90aGVyIG1pbm9yIGJvb2trZWVwaW5nLgorICAgICAqIFRoaXMgY2xhc3Mgb3Bwb3J0dW5pc3RpY2FsbHkgZXh0ZW5kcyBBYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplcgorICAgICAqIHRvIHNpbXBsaWZ5IGFjcXVpcmluZyBhbmQgcmVsZWFzaW5nIGEgbG9jayBzdXJyb3VuZGluZyBlYWNoCisgICAgICogdGFzayBleGVjdXRpb24uICBUaGlzIHByb3RlY3RzIGFnYWluc3QgaW50ZXJydXB0cyB0aGF0IGFyZQorICAgICAqIGludGVuZGVkIHRvIHdha2UgdXAgYSB3b3JrZXIgdGhyZWFkIHdhaXRpbmcgZm9yIGEgdGFzayBmcm9tCisgICAgICogaW5zdGVhZCBpbnRlcnJ1cHRpbmcgYSB0YXNrIGJlaW5nIHJ1bi4gIFdlIGltcGxlbWVudCBhIHNpbXBsZQorICAgICAqIG5vbi1yZWVudHJhbnQgbXV0dWFsIGV4Y2x1c2lvbiBsb2NrIHJhdGhlciB0aGFuIHVzZSBSZWVudHJhbnRMb2NrCisgICAgICogYmVjYXVzZSB3ZSBkbyBub3Qgd2FudCB3b3JrZXIgdGFza3MgdG8gYmUgYWJsZSB0byByZWFjcXVpcmUgdGhlCisgICAgICogbG9jayB3aGVuIHRoZXkgaW52b2tlIHBvb2wgY29udHJvbCBtZXRob2RzIGxpa2Ugc2V0Q29yZVBvb2xTaXplLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgY2xhc3MgV29ya2VyCisgICAgICAgIGV4dGVuZHMgQWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXIKKyAgICAgICAgaW1wbGVtZW50cyBSdW5uYWJsZQorICAgIHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoaXMgY2xhc3Mgd2lsbCBuZXZlciBiZSBzZXJpYWxpemVkLCBidXQgd2UgcHJvdmlkZSBhCisgICAgICAgICAqIHNlcmlhbFZlcnNpb25VSUQgdG8gc3VwcHJlc3MgYSBqYXZhYyB3YXJuaW5nLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjEzODI5NDgwNDU1MTgzODgzM0w7CisKKyAgICAgICAgLyoqIFRocmVhZCB0aGlzIHdvcmtlciBpcyBydW5uaW5nIGluLiAgTnVsbCBpZiBmYWN0b3J5IGZhaWxzLiAqLworICAgICAgICBmaW5hbCBUaHJlYWQgdGhyZWFkOworICAgICAgICAvKiogSW5pdGlhbCB0YXNrIHRvIHJ1bi4gIFBvc3NpYmx5IG51bGwuICovCisgICAgICAgIFJ1bm5hYmxlIGZpcnN0VGFzazsKKyAgICAgICAgLyoqIFBlci10aHJlYWQgdGFzayBjb3VudGVyICovCisgICAgICAgIHZvbGF0aWxlIGxvbmcgY29tcGxldGVkVGFza3M7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENyZWF0ZXMgd2l0aCBnaXZlbiBmaXJzdCB0YXNrIGFuZCB0aHJlYWQgZnJvbSBUaHJlYWRGYWN0b3J5LgorICAgICAgICAgKiBAcGFyYW0gZmlyc3RUYXNrIHRoZSBmaXJzdCB0YXNrIChudWxsIGlmIG5vbmUpCisgICAgICAgICAqLworICAgICAgICBXb3JrZXIoUnVubmFibGUgZmlyc3RUYXNrKSB7CisgICAgICAgICAgICB0aGlzLmZpcnN0VGFzayA9IGZpcnN0VGFzazsKKyAgICAgICAgICAgIHRoaXMudGhyZWFkID0gZ2V0VGhyZWFkRmFjdG9yeSgpLm5ld1RocmVhZCh0aGlzKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKiBEZWxlZ2F0ZXMgbWFpbiBydW4gbG9vcCB0byBvdXRlciBydW5Xb3JrZXIgICovCisgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIHJ1bldvcmtlcih0aGlzKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIExvY2sgbWV0aG9kcworICAgICAgICAvLworICAgICAgICAvLyBUaGUgdmFsdWUgMCByZXByZXNlbnRzIHRoZSB1bmxvY2tlZCBzdGF0ZS4KKyAgICAgICAgLy8gVGhlIHZhbHVlIDEgcmVwcmVzZW50cyB0aGUgbG9ja2VkIHN0YXRlLgorCisgICAgICAgIHByb3RlY3RlZCBib29sZWFuIGlzSGVsZEV4Y2x1c2l2ZWx5KCkgeworICAgICAgICAgICAgcmV0dXJuIGdldFN0YXRlKCkgPT0gMTsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCBib29sZWFuIHRyeUFjcXVpcmUoaW50IHVudXNlZCkgeworICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXRTdGF0ZSgwLCAxKSkgeworICAgICAgICAgICAgICAgIHNldEV4Y2x1c2l2ZU93bmVyVGhyZWFkKFRocmVhZC5jdXJyZW50VGhyZWFkKCkpOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gdHJ5UmVsZWFzZShpbnQgdW51c2VkKSB7CisgICAgICAgICAgICBzZXRFeGNsdXNpdmVPd25lclRocmVhZChudWxsKTsKKyAgICAgICAgICAgIHNldFN0YXRlKDApOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBsb2NrKCkgICAgICAgIHsgYWNxdWlyZSgxKTsgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiB0cnlMb2NrKCkgIHsgcmV0dXJuIHRyeUFjcXVpcmUoMSk7IH0KKyAgICAgICAgcHVibGljIHZvaWQgdW5sb2NrKCkgICAgICB7IHJlbGVhc2UoMSk7IH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNMb2NrZWQoKSB7IHJldHVybiBpc0hlbGRFeGNsdXNpdmVseSgpOyB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBNZXRob2RzIGZvciBzZXR0aW5nIGNvbnRyb2wgc3RhdGUKKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIFRyYW5zaXRpb25zIHJ1blN0YXRlIHRvIGdpdmVuIHRhcmdldCwgb3IgbGVhdmVzIGl0IGFsb25lIGlmCisgICAgICogYWxyZWFkeSBhdCBsZWFzdCB0aGUgZ2l2ZW4gdGFyZ2V0LgorICAgICAqCisgICAgICogQHBhcmFtIHRhcmdldFN0YXRlIHRoZSBkZXNpcmVkIHN0YXRlLCBlaXRoZXIgU0hVVERPV04gb3IgU1RPUAorICAgICAqICAgICAgICAoYnV0IG5vdCBUSURZSU5HIG9yIFRFUk1JTkFURUQgLS0gdXNlIHRyeVRlcm1pbmF0ZSBmb3IgdGhhdCkKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYWR2YW5jZVJ1blN0YXRlKGludCB0YXJnZXRTdGF0ZSkgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBpbnQgYyA9IGN0bC5nZXQoKTsKKyAgICAgICAgICAgIGlmIChydW5TdGF0ZUF0TGVhc3QoYywgdGFyZ2V0U3RhdGUpIHx8CisgICAgICAgICAgICAgICAgY3RsLmNvbXBhcmVBbmRTZXQoYywgY3RsT2YodGFyZ2V0U3RhdGUsIHdvcmtlckNvdW50T2YoYykpKSkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRyYW5zaXRpb25zIHRvIFRFUk1JTkFURUQgc3RhdGUgaWYgZWl0aGVyIChTSFVURE9XTiBhbmQgcG9vbAorICAgICAqIGFuZCBxdWV1ZSBlbXB0eSkgb3IgKFNUT1AgYW5kIHBvb2wgZW1wdHkpLiAgSWYgb3RoZXJ3aXNlCisgICAgICogZWxpZ2libGUgdG8gdGVybWluYXRlIGJ1dCB3b3JrZXJDb3VudCBpcyBub256ZXJvLCBpbnRlcnJ1cHRzIGFuCisgICAgICogaWRsZSB3b3JrZXIgdG8gZW5zdXJlIHRoYXQgc2h1dGRvd24gc2lnbmFscyBwcm9wYWdhdGUuIFRoaXMKKyAgICAgKiBtZXRob2QgbXVzdCBiZSBjYWxsZWQgZm9sbG93aW5nIGFueSBhY3Rpb24gdGhhdCBtaWdodCBtYWtlCisgICAgICogdGVybWluYXRpb24gcG9zc2libGUgLS0gcmVkdWNpbmcgd29ya2VyIGNvdW50IG9yIHJlbW92aW5nIHRhc2tzCisgICAgICogZnJvbSB0aGUgcXVldWUgZHVyaW5nIHNodXRkb3duLiBUaGUgbWV0aG9kIGlzIG5vbi1wcml2YXRlIHRvCisgICAgICogYWxsb3cgYWNjZXNzIGZyb20gU2NoZWR1bGVkVGhyZWFkUG9vbEV4ZWN1dG9yLgorICAgICAqLworICAgIGZpbmFsIHZvaWQgdHJ5VGVybWluYXRlKCkgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBpbnQgYyA9IGN0bC5nZXQoKTsKKyAgICAgICAgICAgIGlmIChpc1J1bm5pbmcoYykgfHwKKyAgICAgICAgICAgICAgICBydW5TdGF0ZUF0TGVhc3QoYywgVElEWUlORykgfHwKKyAgICAgICAgICAgICAgICAocnVuU3RhdGVPZihjKSA9PSBTSFVURE9XTiAmJiAhIHdvcmtRdWV1ZS5pc0VtcHR5KCkpKQorICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIGlmICh3b3JrZXJDb3VudE9mKGMpICE9IDApIHsgLy8gRWxpZ2libGUgdG8gdGVybWluYXRlCisgICAgICAgICAgICAgICAgaW50ZXJydXB0SWRsZVdvcmtlcnMoT05MWV9PTkUpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBtYWluTG9jayA9IHRoaXMubWFpbkxvY2s7CisgICAgICAgICAgICBtYWluTG9jay5sb2NrKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmIChjdGwuY29tcGFyZUFuZFNldChjLCBjdGxPZihUSURZSU5HLCAwKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRlcm1pbmF0ZWQoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGN0bC5zZXQoY3RsT2YoVEVSTUlOQVRFRCwgMCkpOworICAgICAgICAgICAgICAgICAgICAgICAgdGVybWluYXRpb24uc2lnbmFsQWxsKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgbWFpbkxvY2sudW5sb2NrKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBlbHNlIHJldHJ5IG9uIGZhaWxlZCBDQVMKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogTWV0aG9kcyBmb3IgY29udHJvbGxpbmcgaW50ZXJydXB0cyB0byB3b3JrZXIgdGhyZWFkcy4KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIElmIHRoZXJlIGlzIGEgc2VjdXJpdHkgbWFuYWdlciwgbWFrZXMgc3VyZSBjYWxsZXIgaGFzCisgICAgICogcGVybWlzc2lvbiB0byBzaHV0IGRvd24gdGhyZWFkcyBpbiBnZW5lcmFsIChzZWUgc2h1dGRvd25QZXJtKS4KKyAgICAgKiBJZiB0aGlzIHBhc3NlcywgYWRkaXRpb25hbGx5IG1ha2VzIHN1cmUgdGhlIGNhbGxlciBpcyBhbGxvd2VkCisgICAgICogdG8gaW50ZXJydXB0IGVhY2ggd29ya2VyIHRocmVhZC4gVGhpcyBtaWdodCBub3QgYmUgdHJ1ZSBldmVuIGlmCisgICAgICogZmlyc3QgY2hlY2sgcGFzc2VkLCBpZiB0aGUgU2VjdXJpdHlNYW5hZ2VyIHRyZWF0cyBzb21lIHRocmVhZHMKKyAgICAgKiBzcGVjaWFsbHkuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrU2h1dGRvd25BY2Nlc3MoKSB7CisgICAgICAgIFNlY3VyaXR5TWFuYWdlciBzZWN1cml0eSA9IFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKTsKKyAgICAgICAgaWYgKHNlY3VyaXR5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNlY3VyaXR5LmNoZWNrUGVybWlzc2lvbihzaHV0ZG93blBlcm0pOworICAgICAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBtYWluTG9jayA9IHRoaXMubWFpbkxvY2s7CisgICAgICAgICAgICBtYWluTG9jay5sb2NrKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZvciAoV29ya2VyIHcgOiB3b3JrZXJzKQorICAgICAgICAgICAgICAgICAgICBzZWN1cml0eS5jaGVja0FjY2Vzcyh3LnRocmVhZCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIG1haW5Mb2NrLnVubG9jaygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW50ZXJydXB0cyBhbGwgdGhyZWFkcywgZXZlbiBpZiBhY3RpdmUuIElnbm9yZXMgU2VjdXJpdHlFeGNlcHRpb25zCisgICAgICogKGluIHdoaWNoIGNhc2Ugc29tZSB0aHJlYWRzIG1heSByZW1haW4gdW5pbnRlcnJ1cHRlZCkuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGludGVycnVwdFdvcmtlcnMoKSB7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbWFpbkxvY2sgPSB0aGlzLm1haW5Mb2NrOworICAgICAgICBtYWluTG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKFdvcmtlciB3IDogd29ya2VycykgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHcudGhyZWFkLmludGVycnVwdCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1haW5Mb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW50ZXJydXB0cyB0aHJlYWRzIHRoYXQgbWlnaHQgYmUgd2FpdGluZyBmb3IgdGFza3MgKGFzCisgICAgICogaW5kaWNhdGVkIGJ5IG5vdCBiZWluZyBsb2NrZWQpIHNvIHRoZXkgY2FuIGNoZWNrIGZvcgorICAgICAqIHRlcm1pbmF0aW9uIG9yIGNvbmZpZ3VyYXRpb24gY2hhbmdlcy4gSWdub3JlcworICAgICAqIFNlY3VyaXR5RXhjZXB0aW9ucyAoaW4gd2hpY2ggY2FzZSBzb21lIHRocmVhZHMgbWF5IHJlbWFpbgorICAgICAqIHVuaW50ZXJydXB0ZWQpLgorICAgICAqCisgICAgICogQHBhcmFtIG9ubHlPbmUgSWYgdHJ1ZSwgaW50ZXJydXB0IGF0IG1vc3Qgb25lIHdvcmtlci4gVGhpcyBpcworICAgICAqIGNhbGxlZCBvbmx5IGZyb20gdHJ5VGVybWluYXRlIHdoZW4gdGVybWluYXRpb24gaXMgb3RoZXJ3aXNlCisgICAgICogZW5hYmxlZCBidXQgdGhlcmUgYXJlIHN0aWxsIG90aGVyIHdvcmtlcnMuICBJbiB0aGlzIGNhc2UsIGF0CisgICAgICogbW9zdCBvbmUgd2FpdGluZyB3b3JrZXIgaXMgaW50ZXJydXB0ZWQgdG8gcHJvcGFnYXRlIHNodXRkb3duCisgICAgICogc2lnbmFscyBpbiBjYXNlIGFsbCB0aHJlYWRzIGFyZSBjdXJyZW50bHkgd2FpdGluZy4KKyAgICAgKiBJbnRlcnJ1cHRpbmcgYW55IGFyYml0cmFyeSB0aHJlYWQgZW5zdXJlcyB0aGF0IG5ld2x5IGFycml2aW5nCisgICAgICogd29ya2VycyBzaW5jZSBzaHV0ZG93biBiZWdhbiB3aWxsIGFsc28gZXZlbnR1YWxseSBleGl0LgorICAgICAqIFRvIGd1YXJhbnRlZSBldmVudHVhbCB0ZXJtaW5hdGlvbiwgaXQgc3VmZmljZXMgdG8gYWx3YXlzCisgICAgICogaW50ZXJydXB0IG9ubHkgb25lIGlkbGUgd29ya2VyLCBidXQgc2h1dGRvd24oKSBpbnRlcnJ1cHRzIGFsbAorICAgICAqIGlkbGUgd29ya2VycyBzbyB0aGF0IHJlZHVuZGFudCB3b3JrZXJzIGV4aXQgcHJvbXB0bHksIG5vdAorICAgICAqIHdhaXRpbmcgZm9yIGEgc3RyYWdnbGVyIHRhc2sgdG8gZmluaXNoLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpbnRlcnJ1cHRJZGxlV29ya2Vycyhib29sZWFuIG9ubHlPbmUpIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBtYWluTG9jayA9IHRoaXMubWFpbkxvY2s7CisgICAgICAgIG1haW5Mb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoV29ya2VyIHcgOiB3b3JrZXJzKSB7CisgICAgICAgICAgICAgICAgVGhyZWFkIHQgPSB3LnRocmVhZDsKKyAgICAgICAgICAgICAgICBpZiAoIXQuaXNJbnRlcnJ1cHRlZCgpICYmIHcudHJ5TG9jaygpKSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0LmludGVycnVwdCgpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBpZ25vcmUpIHsKKyAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHcudW5sb2NrKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKG9ubHlPbmUpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbWFpbkxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21tb24gZm9ybSBvZiBpbnRlcnJ1cHRJZGxlV29ya2VycywgdG8gYXZvaWQgaGF2aW5nIHRvCisgICAgICogcmVtZW1iZXIgd2hhdCB0aGUgYm9vbGVhbiBhcmd1bWVudCBtZWFucy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW50ZXJydXB0SWRsZVdvcmtlcnMoKSB7CisgICAgICAgIGludGVycnVwdElkbGVXb3JrZXJzKGZhbHNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIE9OTFlfT05FID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIEVuc3VyZXMgdGhhdCB1bmxlc3MgdGhlIHBvb2wgaXMgc3RvcHBpbmcsIHRoZSBjdXJyZW50IHRocmVhZAorICAgICAqIGRvZXMgbm90IGhhdmUgaXRzIGludGVycnVwdCBzZXQuIFRoaXMgcmVxdWlyZXMgYSBkb3VibGUtY2hlY2sKKyAgICAgKiBvZiBzdGF0ZSBpbiBjYXNlIHRoZSBpbnRlcnJ1cHQgd2FzIGNsZWFyZWQgY29uY3VycmVudGx5IHdpdGggYQorICAgICAqIHNodXRkb3duTm93IC0tIGlmIHNvLCB0aGUgaW50ZXJydXB0IGlzIHJlLWVuYWJsZWQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNsZWFySW50ZXJydXB0c0ZvclRhc2tSdW4oKSB7CisgICAgICAgIGlmIChydW5TdGF0ZUxlc3NUaGFuKGN0bC5nZXQoKSwgU1RPUCkgJiYKKyAgICAgICAgICAgIFRocmVhZC5pbnRlcnJ1cHRlZCgpICYmCisgICAgICAgICAgICBydW5TdGF0ZUF0TGVhc3QoY3RsLmdldCgpLCBTVE9QKSkKKyAgICAgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuaW50ZXJydXB0KCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBNaXNjIHV0aWxpdGllcywgbW9zdCBvZiB3aGljaCBhcmUgYWxzbyBleHBvcnRlZCB0bworICAgICAqIFNjaGVkdWxlZFRocmVhZFBvb2xFeGVjdXRvcgorICAgICAqLworCisgICAgLyoqCisgICAgICogSW52b2tlcyB0aGUgcmVqZWN0ZWQgZXhlY3V0aW9uIGhhbmRsZXIgZm9yIHRoZSBnaXZlbiBjb21tYW5kLgorICAgICAqIFBhY2thZ2UtcHJvdGVjdGVkIGZvciB1c2UgYnkgU2NoZWR1bGVkVGhyZWFkUG9vbEV4ZWN1dG9yLgorICAgICAqLworICAgIGZpbmFsIHZvaWQgcmVqZWN0KFJ1bm5hYmxlIGNvbW1hbmQpIHsKKyAgICAgICAgaGFuZGxlci5yZWplY3RlZEV4ZWN1dGlvbihjb21tYW5kLCB0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhbnkgZnVydGhlciBjbGVhbnVwIGZvbGxvd2luZyBydW4gc3RhdGUgdHJhbnNpdGlvbiBvbgorICAgICAqIGludm9jYXRpb24gb2Ygc2h1dGRvd24uICBBIG5vLW9wIGhlcmUsIGJ1dCB1c2VkIGJ5CisgICAgICogU2NoZWR1bGVkVGhyZWFkUG9vbEV4ZWN1dG9yIHRvIGNhbmNlbCBkZWxheWVkIHRhc2tzLgorICAgICAqLworICAgIHZvaWQgb25TaHV0ZG93bigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdGF0ZSBjaGVjayBuZWVkZWQgYnkgU2NoZWR1bGVkVGhyZWFkUG9vbEV4ZWN1dG9yIHRvCisgICAgICogZW5hYmxlIHJ1bm5pbmcgdGFza3MgZHVyaW5nIHNodXRkb3duLgorICAgICAqCisgICAgICogQHBhcmFtIHNodXRkb3duT0sgdHJ1ZSBpZiBzaG91bGQgcmV0dXJuIHRydWUgaWYgU0hVVERPV04KKyAgICAgKi8KKyAgICBmaW5hbCBib29sZWFuIGlzUnVubmluZ09yU2h1dGRvd24oYm9vbGVhbiBzaHV0ZG93bk9LKSB7CisgICAgICAgIGludCBycyA9IHJ1blN0YXRlT2YoY3RsLmdldCgpKTsKKyAgICAgICAgcmV0dXJuIHJzID09IFJVTk5JTkcgfHwgKHJzID09IFNIVVRET1dOICYmIHNodXRkb3duT0spOworICAgIH0KKworICAgIC8qKgorICAgICAqIERyYWlucyB0aGUgdGFzayBxdWV1ZSBpbnRvIGEgbmV3IGxpc3QsIG5vcm1hbGx5IHVzaW5nCisgICAgICogZHJhaW5Uby4gQnV0IGlmIHRoZSBxdWV1ZSBpcyBhIERlbGF5UXVldWUgb3IgYW55IG90aGVyIGtpbmQgb2YKKyAgICAgKiBxdWV1ZSBmb3Igd2hpY2ggcG9sbCBvciBkcmFpblRvIG1heSBmYWlsIHRvIHJlbW92ZSBzb21lCisgICAgICogZWxlbWVudHMsIGl0IGRlbGV0ZXMgdGhlbSBvbmUgYnkgb25lLgorICAgICAqLworICAgIHByaXZhdGUgTGlzdDxSdW5uYWJsZT4gZHJhaW5RdWV1ZSgpIHsKKyAgICAgICAgQmxvY2tpbmdRdWV1ZTxSdW5uYWJsZT4gcSA9IHdvcmtRdWV1ZTsKKyAgICAgICAgTGlzdDxSdW5uYWJsZT4gdGFza0xpc3QgPSBuZXcgQXJyYXlMaXN0PFJ1bm5hYmxlPigpOworICAgICAgICBxLmRyYWluVG8odGFza0xpc3QpOworICAgICAgICBpZiAoIXEuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBmb3IgKFJ1bm5hYmxlIHIgOiBxLnRvQXJyYXkobmV3IFJ1bm5hYmxlWzBdKSkgeworICAgICAgICAgICAgICAgIGlmIChxLnJlbW92ZShyKSkKKyAgICAgICAgICAgICAgICAgICAgdGFza0xpc3QuYWRkKHIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0YXNrTGlzdDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIE1ldGhvZHMgZm9yIGNyZWF0aW5nLCBydW5uaW5nIGFuZCBjbGVhbmluZyB1cCBhZnRlciB3b3JrZXJzCisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgYSBuZXcgd29ya2VyIGNhbiBiZSBhZGRlZCB3aXRoIHJlc3BlY3QgdG8gY3VycmVudAorICAgICAqIHBvb2wgc3RhdGUgYW5kIHRoZSBnaXZlbiBib3VuZCAoZWl0aGVyIGNvcmUgb3IgbWF4aW11bSkuIElmIHNvLAorICAgICAqIHRoZSB3b3JrZXIgY291bnQgaXMgYWRqdXN0ZWQgYWNjb3JkaW5nbHksIGFuZCwgaWYgcG9zc2libGUsIGEKKyAgICAgKiBuZXcgd29ya2VyIGlzIGNyZWF0ZWQgYW5kIHN0YXJ0ZWQgcnVubmluZyBmaXJzdFRhc2sgYXMgaXRzCisgICAgICogZmlyc3QgdGFzay4gVGhpcyBtZXRob2QgcmV0dXJucyBmYWxzZSBpZiB0aGUgcG9vbCBpcyBzdG9wcGVkIG9yCisgICAgICogZWxpZ2libGUgdG8gc2h1dCBkb3duLiBJdCBhbHNvIHJldHVybnMgZmFsc2UgaWYgdGhlIHRocmVhZAorICAgICAqIGZhY3RvcnkgZmFpbHMgdG8gY3JlYXRlIGEgdGhyZWFkIHdoZW4gYXNrZWQsIHdoaWNoIHJlcXVpcmVzIGEKKyAgICAgKiBiYWNrb3V0IG9mIHdvcmtlckNvdW50LCBhbmQgYSByZWNoZWNrIGZvciB0ZXJtaW5hdGlvbiwgaW4gY2FzZQorICAgICAqIHRoZSBleGlzdGVuY2Ugb2YgdGhpcyB3b3JrZXIgd2FzIGhvbGRpbmcgdXAgdGVybWluYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlyc3RUYXNrIHRoZSB0YXNrIHRoZSBuZXcgdGhyZWFkIHNob3VsZCBydW4gZmlyc3QgKG9yCisgICAgICogbnVsbCBpZiBub25lKS4gV29ya2VycyBhcmUgY3JlYXRlZCB3aXRoIGFuIGluaXRpYWwgZmlyc3QgdGFzaworICAgICAqIChpbiBtZXRob2QgZXhlY3V0ZSgpKSB0byBieXBhc3MgcXVldWluZyB3aGVuIHRoZXJlIGFyZSBmZXdlcgorICAgICAqIHRoYW4gY29yZVBvb2xTaXplIHRocmVhZHMgKGluIHdoaWNoIGNhc2Ugd2UgYWx3YXlzIHN0YXJ0IG9uZSksCisgICAgICogb3Igd2hlbiB0aGUgcXVldWUgaXMgZnVsbCAoaW4gd2hpY2ggY2FzZSB3ZSBtdXN0IGJ5cGFzcyBxdWV1ZSkuCisgICAgICogSW5pdGlhbGx5IGlkbGUgdGhyZWFkcyBhcmUgdXN1YWxseSBjcmVhdGVkIHZpYQorICAgICAqIHByZXN0YXJ0Q29yZVRocmVhZCBvciB0byByZXBsYWNlIG90aGVyIGR5aW5nIHdvcmtlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29yZSBpZiB0cnVlIHVzZSBjb3JlUG9vbFNpemUgYXMgYm91bmQsIGVsc2UKKyAgICAgKiBtYXhpbXVtUG9vbFNpemUuIChBIGJvb2xlYW4gaW5kaWNhdG9yIGlzIHVzZWQgaGVyZSByYXRoZXIgdGhhbiBhCisgICAgICogdmFsdWUgdG8gZW5zdXJlIHJlYWRzIG9mIGZyZXNoIHZhbHVlcyBhZnRlciBjaGVja2luZyBvdGhlciBwb29sCisgICAgICogc3RhdGUpLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGFkZFdvcmtlcihSdW5uYWJsZSBmaXJzdFRhc2ssIGJvb2xlYW4gY29yZSkgeworICAgICAgICByZXRyeToKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgaW50IGMgPSBjdGwuZ2V0KCk7CisgICAgICAgICAgICBpbnQgcnMgPSBydW5TdGF0ZU9mKGMpOworCisgICAgICAgICAgICAvLyBDaGVjayBpZiBxdWV1ZSBlbXB0eSBvbmx5IGlmIG5lY2Vzc2FyeS4KKyAgICAgICAgICAgIGlmIChycyA+PSBTSFVURE9XTiAmJgorICAgICAgICAgICAgICAgICEgKHJzID09IFNIVVRET1dOICYmCisgICAgICAgICAgICAgICAgICAgZmlyc3RUYXNrID09IG51bGwgJiYKKyAgICAgICAgICAgICAgICAgICAhIHdvcmtRdWV1ZS5pc0VtcHR5KCkpKQorICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIGludCB3YyA9IHdvcmtlckNvdW50T2YoYyk7CisgICAgICAgICAgICAgICAgaWYgKHdjID49IENBUEFDSVRZIHx8CisgICAgICAgICAgICAgICAgICAgIHdjID49IChjb3JlID8gY29yZVBvb2xTaXplIDogbWF4aW11bVBvb2xTaXplKSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIGlmIChjb21wYXJlQW5kSW5jcmVtZW50V29ya2VyQ291bnQoYykpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrIHJldHJ5OworICAgICAgICAgICAgICAgIGMgPSBjdGwuZ2V0KCk7ICAvLyBSZS1yZWFkIGN0bAorICAgICAgICAgICAgICAgIGlmIChydW5TdGF0ZU9mKGMpICE9IHJzKQorICAgICAgICAgICAgICAgICAgICBjb250aW51ZSByZXRyeTsKKyAgICAgICAgICAgICAgICAvLyBlbHNlIENBUyBmYWlsZWQgZHVlIHRvIHdvcmtlckNvdW50IGNoYW5nZTsgcmV0cnkgaW5uZXIgbG9vcAorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgV29ya2VyIHcgPSBuZXcgV29ya2VyKGZpcnN0VGFzayk7CisgICAgICAgIFRocmVhZCB0ID0gdy50aHJlYWQ7CisKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBtYWluTG9jayA9IHRoaXMubWFpbkxvY2s7CisgICAgICAgIG1haW5Mb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFJlY2hlY2sgd2hpbGUgaG9sZGluZyBsb2NrLgorICAgICAgICAgICAgLy8gQmFjayBvdXQgb24gVGhyZWFkRmFjdG9yeSBmYWlsdXJlIG9yIGlmCisgICAgICAgICAgICAvLyBzaHV0IGRvd24gYmVmb3JlIGxvY2sgYWNxdWlyZWQuCisgICAgICAgICAgICBpbnQgYyA9IGN0bC5nZXQoKTsKKyAgICAgICAgICAgIGludCBycyA9IHJ1blN0YXRlT2YoYyk7CisKKyAgICAgICAgICAgIGlmICh0ID09IG51bGwgfHwKKyAgICAgICAgICAgICAgICAocnMgPj0gU0hVVERPV04gJiYKKyAgICAgICAgICAgICAgICAgISAocnMgPT0gU0hVVERPV04gJiYKKyAgICAgICAgICAgICAgICAgICAgZmlyc3RUYXNrID09IG51bGwpKSkgeworICAgICAgICAgICAgICAgIGRlY3JlbWVudFdvcmtlckNvdW50KCk7CisgICAgICAgICAgICAgICAgdHJ5VGVybWluYXRlKCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB3b3JrZXJzLmFkZCh3KTsKKworICAgICAgICAgICAgaW50IHMgPSB3b3JrZXJzLnNpemUoKTsKKyAgICAgICAgICAgIGlmIChzID4gbGFyZ2VzdFBvb2xTaXplKQorICAgICAgICAgICAgICAgIGxhcmdlc3RQb29sU2l6ZSA9IHM7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYWluTG9jay51bmxvY2soKTsKKyAgICAgICAgfQorCisgICAgICAgIHQuc3RhcnQoKTsKKyAgICAgICAgLy8gSXQgaXMgcG9zc2libGUgKGJ1dCB1bmxpa2VseSkgZm9yIGEgdGhyZWFkIHRvIGhhdmUgYmVlbgorICAgICAgICAvLyBhZGRlZCB0byB3b3JrZXJzLCBidXQgbm90IHlldCBzdGFydGVkLCBkdXJpbmcgdHJhbnNpdGlvbiB0bworICAgICAgICAvLyBTVE9QLCB3aGljaCBjb3VsZCByZXN1bHQgaW4gYSByYXJlIG1pc3NlZCBpbnRlcnJ1cHQsCisgICAgICAgIC8vIGJlY2F1c2UgVGhyZWFkLmludGVycnVwdCBpcyBub3QgZ3VhcmFudGVlZCB0byBoYXZlIGFueSBlZmZlY3QKKyAgICAgICAgLy8gb24gYSBub24teWV0LXN0YXJ0ZWQgVGhyZWFkIChzZWUgVGhyZWFkI2ludGVycnVwdCkuCisgICAgICAgIGlmIChydW5TdGF0ZU9mKGN0bC5nZXQoKSkgPT0gU1RPUCAmJiAhIHQuaXNJbnRlcnJ1cHRlZCgpKQorICAgICAgICAgICAgdC5pbnRlcnJ1cHQoKTsKKworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBjbGVhbnVwIGFuZCBib29ra2VlcGluZyBmb3IgYSBkeWluZyB3b3JrZXIuIENhbGxlZAorICAgICAqIG9ubHkgZnJvbSB3b3JrZXIgdGhyZWFkcy4gVW5sZXNzIGNvbXBsZXRlZEFicnVwdGx5IGlzIHNldCwKKyAgICAgKiBhc3N1bWVzIHRoYXQgd29ya2VyQ291bnQgaGFzIGFscmVhZHkgYmVlbiBhZGp1c3RlZCB0byBhY2NvdW50CisgICAgICogZm9yIGV4aXQuICBUaGlzIG1ldGhvZCByZW1vdmVzIHRocmVhZCBmcm9tIHdvcmtlciBzZXQsIGFuZAorICAgICAqIHBvc3NpYmx5IHRlcm1pbmF0ZXMgdGhlIHBvb2wgb3IgcmVwbGFjZXMgdGhlIHdvcmtlciBpZiBlaXRoZXIKKyAgICAgKiBpdCBleGl0ZWQgZHVlIHRvIHVzZXIgdGFzayBleGNlcHRpb24gb3IgaWYgZmV3ZXIgdGhhbgorICAgICAqIGNvcmVQb29sU2l6ZSB3b3JrZXJzIGFyZSBydW5uaW5nIG9yIHF1ZXVlIGlzIG5vbi1lbXB0eSBidXQKKyAgICAgKiB0aGVyZSBhcmUgbm8gd29ya2Vycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB3IHRoZSB3b3JrZXIKKyAgICAgKiBAcGFyYW0gY29tcGxldGVkQWJydXB0bHkgaWYgdGhlIHdvcmtlciBkaWVkIGR1ZSB0byB1c2VyIGV4Y2VwdGlvbgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwcm9jZXNzV29ya2VyRXhpdChXb3JrZXIgdywgYm9vbGVhbiBjb21wbGV0ZWRBYnJ1cHRseSkgeworICAgICAgICBpZiAoY29tcGxldGVkQWJydXB0bHkpIC8vIElmIGFicnVwdCwgdGhlbiB3b3JrZXJDb3VudCB3YXNuJ3QgYWRqdXN0ZWQKKyAgICAgICAgICAgIGRlY3JlbWVudFdvcmtlckNvdW50KCk7CisKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBtYWluTG9jayA9IHRoaXMubWFpbkxvY2s7CisgICAgICAgIG1haW5Mb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbXBsZXRlZFRhc2tDb3VudCArPSB3LmNvbXBsZXRlZFRhc2tzOworICAgICAgICAgICAgd29ya2Vycy5yZW1vdmUodyk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYWluTG9jay51bmxvY2soKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeVRlcm1pbmF0ZSgpOworCisgICAgICAgIGludCBjID0gY3RsLmdldCgpOworICAgICAgICBpZiAocnVuU3RhdGVMZXNzVGhhbihjLCBTVE9QKSkgeworICAgICAgICAgICAgaWYgKCFjb21wbGV0ZWRBYnJ1cHRseSkgeworICAgICAgICAgICAgICAgIGludCBtaW4gPSBhbGxvd0NvcmVUaHJlYWRUaW1lT3V0ID8gMCA6IGNvcmVQb29sU2l6ZTsKKyAgICAgICAgICAgICAgICBpZiAobWluID09IDAgJiYgISB3b3JrUXVldWUuaXNFbXB0eSgpKQorICAgICAgICAgICAgICAgICAgICBtaW4gPSAxOworICAgICAgICAgICAgICAgIGlmICh3b3JrZXJDb3VudE9mKGMpID49IG1pbikKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOyAvLyByZXBsYWNlbWVudCBub3QgbmVlZGVkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBhZGRXb3JrZXIobnVsbCwgZmFsc2UpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYmxvY2tpbmcgb3IgdGltZWQgd2FpdCBmb3IgYSB0YXNrLCBkZXBlbmRpbmcgb24KKyAgICAgKiBjdXJyZW50IGNvbmZpZ3VyYXRpb24gc2V0dGluZ3MsIG9yIHJldHVybnMgbnVsbCBpZiB0aGlzIHdvcmtlcgorICAgICAqIG11c3QgZXhpdCBiZWNhdXNlIG9mIGFueSBvZjoKKyAgICAgKiAxLiBUaGVyZSBhcmUgbW9yZSB0aGFuIG1heGltdW1Qb29sU2l6ZSB3b3JrZXJzIChkdWUgdG8KKyAgICAgKiAgICBhIGNhbGwgdG8gc2V0TWF4aW11bVBvb2xTaXplKS4KKyAgICAgKiAyLiBUaGUgcG9vbCBpcyBzdG9wcGVkLgorICAgICAqIDMuIFRoZSBwb29sIGlzIHNodXRkb3duIGFuZCB0aGUgcXVldWUgaXMgZW1wdHkuCisgICAgICogNC4gVGhpcyB3b3JrZXIgdGltZWQgb3V0IHdhaXRpbmcgZm9yIGEgdGFzaywgYW5kIHRpbWVkLW91dAorICAgICAqICAgIHdvcmtlcnMgYXJlIHN1YmplY3QgdG8gdGVybWluYXRpb24gKHRoYXQgaXMsCisgICAgICogICAge0Bjb2RlIGFsbG93Q29yZVRocmVhZFRpbWVPdXQgfHwgd29ya2VyQ291bnQgPiBjb3JlUG9vbFNpemV9KQorICAgICAqICAgIGJvdGggYmVmb3JlIGFuZCBhZnRlciB0aGUgdGltZWQgd2FpdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGFzaywgb3IgbnVsbCBpZiB0aGUgd29ya2VyIG11c3QgZXhpdCwgaW4gd2hpY2ggY2FzZQorICAgICAqICAgICAgICAgd29ya2VyQ291bnQgaXMgZGVjcmVtZW50ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIFJ1bm5hYmxlIGdldFRhc2soKSB7CisgICAgICAgIGJvb2xlYW4gdGltZWRPdXQgPSBmYWxzZTsgLy8gRGlkIHRoZSBsYXN0IHBvbGwoKSB0aW1lIG91dD8KKworICAgICAgICByZXRyeToKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgaW50IGMgPSBjdGwuZ2V0KCk7CisgICAgICAgICAgICBpbnQgcnMgPSBydW5TdGF0ZU9mKGMpOworCisgICAgICAgICAgICAvLyBDaGVjayBpZiBxdWV1ZSBlbXB0eSBvbmx5IGlmIG5lY2Vzc2FyeS4KKyAgICAgICAgICAgIGlmIChycyA+PSBTSFVURE9XTiAmJiAocnMgPj0gU1RPUCB8fCB3b3JrUXVldWUuaXNFbXB0eSgpKSkgeworICAgICAgICAgICAgICAgIGRlY3JlbWVudFdvcmtlckNvdW50KCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGJvb2xlYW4gdGltZWQ7ICAgICAgLy8gQXJlIHdvcmtlcnMgc3ViamVjdCB0byBjdWxsaW5nPworCisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgaW50IHdjID0gd29ya2VyQ291bnRPZihjKTsKKyAgICAgICAgICAgICAgICB0aW1lZCA9IGFsbG93Q29yZVRocmVhZFRpbWVPdXQgfHwgd2MgPiBjb3JlUG9vbFNpemU7CisKKyAgICAgICAgICAgICAgICBpZiAod2MgPD0gbWF4aW11bVBvb2xTaXplICYmICEgKHRpbWVkT3V0ICYmIHRpbWVkKSkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmREZWNyZW1lbnRXb3JrZXJDb3VudChjKSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgYyA9IGN0bC5nZXQoKTsgIC8vIFJlLXJlYWQgY3RsCisgICAgICAgICAgICAgICAgaWYgKHJ1blN0YXRlT2YoYykgIT0gcnMpCisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHJldHJ5OworICAgICAgICAgICAgICAgIC8vIGVsc2UgQ0FTIGZhaWxlZCBkdWUgdG8gd29ya2VyQ291bnQgY2hhbmdlOyByZXRyeSBpbm5lciBsb29wCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgUnVubmFibGUgciA9IHRpbWVkID8KKyAgICAgICAgICAgICAgICAgICAgd29ya1F1ZXVlLnBvbGwoa2VlcEFsaXZlVGltZSwgVGltZVVuaXQuTkFOT1NFQ09ORFMpIDoKKyAgICAgICAgICAgICAgICAgICAgd29ya1F1ZXVlLnRha2UoKTsKKyAgICAgICAgICAgICAgICBpZiAociAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gcjsKKyAgICAgICAgICAgICAgICB0aW1lZE91dCA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiByZXRyeSkgeworICAgICAgICAgICAgICAgIHRpbWVkT3V0ID0gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYWluIHdvcmtlciBydW4gbG9vcC4gIFJlcGVhdGVkbHkgZ2V0cyB0YXNrcyBmcm9tIHF1ZXVlIGFuZAorICAgICAqIGV4ZWN1dGVzIHRoZW0sIHdoaWxlIGNvcGluZyB3aXRoIGEgbnVtYmVyIG9mIGlzc3VlczoKKyAgICAgKgorICAgICAqIDEuIFdlIG1heSBzdGFydCBvdXQgd2l0aCBhbiBpbml0aWFsIHRhc2ssIGluIHdoaWNoIGNhc2Ugd2UKKyAgICAgKiBkb24ndCBuZWVkIHRvIGdldCB0aGUgZmlyc3Qgb25lLiBPdGhlcndpc2UsIGFzIGxvbmcgYXMgcG9vbCBpcworICAgICAqIHJ1bm5pbmcsIHdlIGdldCB0YXNrcyBmcm9tIGdldFRhc2suIElmIGl0IHJldHVybnMgbnVsbCB0aGVuIHRoZQorICAgICAqIHdvcmtlciBleGl0cyBkdWUgdG8gY2hhbmdlZCBwb29sIHN0YXRlIG9yIGNvbmZpZ3VyYXRpb24KKyAgICAgKiBwYXJhbWV0ZXJzLiAgT3RoZXIgZXhpdHMgcmVzdWx0IGZyb20gZXhjZXB0aW9uIHRocm93cyBpbgorICAgICAqIGV4dGVybmFsIGNvZGUsIGluIHdoaWNoIGNhc2UgY29tcGxldGVkQWJydXB0bHkgaG9sZHMsIHdoaWNoCisgICAgICogdXN1YWxseSBsZWFkcyBwcm9jZXNzV29ya2VyRXhpdCB0byByZXBsYWNlIHRoaXMgdGhyZWFkLgorICAgICAqCisgICAgICogMi4gQmVmb3JlIHJ1bm5pbmcgYW55IHRhc2ssIHRoZSBsb2NrIGlzIGFjcXVpcmVkIHRvIHByZXZlbnQKKyAgICAgKiBvdGhlciBwb29sIGludGVycnVwdHMgd2hpbGUgdGhlIHRhc2sgaXMgZXhlY3V0aW5nLCBhbmQKKyAgICAgKiBjbGVhckludGVycnVwdHNGb3JUYXNrUnVuIGNhbGxlZCB0byBlbnN1cmUgdGhhdCB1bmxlc3MgcG9vbCBpcworICAgICAqIHN0b3BwaW5nLCB0aGlzIHRocmVhZCBkb2VzIG5vdCBoYXZlIGl0cyBpbnRlcnJ1cHQgc2V0LgorICAgICAqCisgICAgICogMy4gRWFjaCB0YXNrIHJ1biBpcyBwcmVjZWRlZCBieSBhIGNhbGwgdG8gYmVmb3JlRXhlY3V0ZSwgd2hpY2gKKyAgICAgKiBtaWdodCB0aHJvdyBhbiBleGNlcHRpb24sIGluIHdoaWNoIGNhc2Ugd2UgY2F1c2UgdGhyZWFkIHRvIGRpZQorICAgICAqIChicmVha2luZyBsb29wIHdpdGggY29tcGxldGVkQWJydXB0bHkgdHJ1ZSkgd2l0aG91dCBwcm9jZXNzaW5nCisgICAgICogdGhlIHRhc2suCisgICAgICoKKyAgICAgKiA0LiBBc3N1bWluZyBiZWZvcmVFeGVjdXRlIGNvbXBsZXRlcyBub3JtYWxseSwgd2UgcnVuIHRoZSB0YXNrLAorICAgICAqIGdhdGhlcmluZyBhbnkgb2YgaXRzIHRocm93biBleGNlcHRpb25zIHRvIHNlbmQgdG8KKyAgICAgKiBhZnRlckV4ZWN1dGUuIFdlIHNlcGFyYXRlbHkgaGFuZGxlIFJ1bnRpbWVFeGNlcHRpb24sIEVycm9yCisgICAgICogKGJvdGggb2Ygd2hpY2ggdGhlIHNwZWNzIGd1YXJhbnRlZSB0aGF0IHdlIHRyYXApIGFuZCBhcmJpdHJhcnkKKyAgICAgKiBUaHJvd2FibGVzLiAgQmVjYXVzZSB3ZSBjYW5ub3QgcmV0aHJvdyBUaHJvd2FibGVzIHdpdGhpbgorICAgICAqIFJ1bm5hYmxlLnJ1biwgd2Ugd3JhcCB0aGVtIHdpdGhpbiBFcnJvcnMgb24gdGhlIHdheSBvdXQgKHRvIHRoZQorICAgICAqIHRocmVhZCdzIFVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlcikuICBBbnkgdGhyb3duIGV4Y2VwdGlvbiBhbHNvCisgICAgICogY29uc2VydmF0aXZlbHkgY2F1c2VzIHRocmVhZCB0byBkaWUuCisgICAgICoKKyAgICAgKiA1LiBBZnRlciB0YXNrLnJ1biBjb21wbGV0ZXMsIHdlIGNhbGwgYWZ0ZXJFeGVjdXRlLCB3aGljaCBtYXkKKyAgICAgKiBhbHNvIHRocm93IGFuIGV4Y2VwdGlvbiwgd2hpY2ggd2lsbCBhbHNvIGNhdXNlIHRocmVhZCB0bworICAgICAqIGRpZS4gQWNjb3JkaW5nIHRvIEpMUyBTZWMgMTQuMjAsIHRoaXMgZXhjZXB0aW9uIGlzIHRoZSBvbmUgdGhhdAorICAgICAqIHdpbGwgYmUgaW4gZWZmZWN0IGV2ZW4gaWYgdGFzay5ydW4gdGhyb3dzLgorICAgICAqCisgICAgICogVGhlIG5ldCBlZmZlY3Qgb2YgdGhlIGV4Y2VwdGlvbiBtZWNoYW5pY3MgaXMgdGhhdCBhZnRlckV4ZWN1dGUKKyAgICAgKiBhbmQgdGhlIHRocmVhZCdzIFVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlciBoYXZlIGFzIGFjY3VyYXRlCisgICAgICogaW5mb3JtYXRpb24gYXMgd2UgY2FuIHByb3ZpZGUgYWJvdXQgYW55IHByb2JsZW1zIGVuY291bnRlcmVkIGJ5CisgICAgICogdXNlciBjb2RlLgorICAgICAqCisgICAgICogQHBhcmFtIHcgdGhlIHdvcmtlcgorICAgICAqLworICAgIGZpbmFsIHZvaWQgcnVuV29ya2VyKFdvcmtlciB3KSB7CisgICAgICAgIFJ1bm5hYmxlIHRhc2sgPSB3LmZpcnN0VGFzazsKKyAgICAgICAgdy5maXJzdFRhc2sgPSBudWxsOworICAgICAgICBib29sZWFuIGNvbXBsZXRlZEFicnVwdGx5ID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdoaWxlICh0YXNrICE9IG51bGwgfHwgKHRhc2sgPSBnZXRUYXNrKCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB3LmxvY2soKTsKKyAgICAgICAgICAgICAgICBjbGVhckludGVycnVwdHNGb3JUYXNrUnVuKCk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgYmVmb3JlRXhlY3V0ZSh3LnRocmVhZCwgdGFzayk7CisgICAgICAgICAgICAgICAgICAgIFRocm93YWJsZSB0aHJvd24gPSBudWxsOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGFzay5ydW4oKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB4KSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd24gPSB4OyB0aHJvdyB4OworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFcnJvciB4KSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd24gPSB4OyB0aHJvdyB4OworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgeCkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3duID0geDsgdGhyb3cgbmV3IEVycm9yKHgpOworICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICAgICAgYWZ0ZXJFeGVjdXRlKHRhc2ssIHRocm93bik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICB0YXNrID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgdy5jb21wbGV0ZWRUYXNrcysrOworICAgICAgICAgICAgICAgICAgICB3LnVubG9jaygpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvbXBsZXRlZEFicnVwdGx5ID0gZmFsc2U7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBwcm9jZXNzV29ya2VyRXhpdCh3LCBjb21wbGV0ZWRBYnJ1cHRseSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBQdWJsaWMgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBUaHJlYWRQb29sRXhlY3V0b3J9IHdpdGggdGhlIGdpdmVuIGluaXRpYWwKKyAgICAgKiBwYXJhbWV0ZXJzIGFuZCBkZWZhdWx0IHRocmVhZCBmYWN0b3J5IGFuZCByZWplY3RlZCBleGVjdXRpb24gaGFuZGxlci4KKyAgICAgKiBJdCBtYXkgYmUgbW9yZSBjb252ZW5pZW50IHRvIHVzZSBvbmUgb2YgdGhlIHtAbGluayBFeGVjdXRvcnN9IGZhY3RvcnkKKyAgICAgKiBtZXRob2RzIGluc3RlYWQgb2YgdGhpcyBnZW5lcmFsIHB1cnBvc2UgY29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29yZVBvb2xTaXplIHRoZSBudW1iZXIgb2YgdGhyZWFkcyB0byBrZWVwIGluIHRoZSBwb29sLCBldmVuCisgICAgICogICAgICAgIGlmIHRoZXkgYXJlIGlkbGUsIHVubGVzcyB7QGNvZGUgYWxsb3dDb3JlVGhyZWFkVGltZU91dH0gaXMgc2V0CisgICAgICogQHBhcmFtIG1heGltdW1Qb29sU2l6ZSB0aGUgbWF4aW11bSBudW1iZXIgb2YgdGhyZWFkcyB0byBhbGxvdyBpbiB0aGUKKyAgICAgKiAgICAgICAgcG9vbAorICAgICAqIEBwYXJhbSBrZWVwQWxpdmVUaW1lIHdoZW4gdGhlIG51bWJlciBvZiB0aHJlYWRzIGlzIGdyZWF0ZXIgdGhhbgorICAgICAqICAgICAgICB0aGUgY29yZSwgdGhpcyBpcyB0aGUgbWF4aW11bSB0aW1lIHRoYXQgZXhjZXNzIGlkbGUgdGhyZWFkcworICAgICAqICAgICAgICB3aWxsIHdhaXQgZm9yIG5ldyB0YXNrcyBiZWZvcmUgdGVybWluYXRpbmcuCisgICAgICogQHBhcmFtIHVuaXQgdGhlIHRpbWUgdW5pdCBmb3IgdGhlIHtAY29kZSBrZWVwQWxpdmVUaW1lfSBhcmd1bWVudAorICAgICAqIEBwYXJhbSB3b3JrUXVldWUgdGhlIHF1ZXVlIHRvIHVzZSBmb3IgaG9sZGluZyB0YXNrcyBiZWZvcmUgdGhleSBhcmUKKyAgICAgKiAgICAgICAgZXhlY3V0ZWQuICBUaGlzIHF1ZXVlIHdpbGwgaG9sZCBvbmx5IHRoZSB7QGNvZGUgUnVubmFibGV9CisgICAgICogICAgICAgIHRhc2tzIHN1Ym1pdHRlZCBieSB0aGUge0Bjb2RlIGV4ZWN1dGV9IG1ldGhvZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBvbmUgb2YgdGhlIGZvbGxvd2luZyBob2xkczo8YnI+CisgICAgICogICAgICAgICB7QGNvZGUgY29yZVBvb2xTaXplIDwgMH08YnI+CisgICAgICogICAgICAgICB7QGNvZGUga2VlcEFsaXZlVGltZSA8IDB9PGJyPgorICAgICAqICAgICAgICAge0Bjb2RlIG1heGltdW1Qb29sU2l6ZSA8PSAwfTxicj4KKyAgICAgKiAgICAgICAgIHtAY29kZSBtYXhpbXVtUG9vbFNpemUgPCBjb3JlUG9vbFNpemV9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgd29ya1F1ZXVlfSBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIFRocmVhZFBvb2xFeGVjdXRvcihpbnQgY29yZVBvb2xTaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1heGltdW1Qb29sU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcga2VlcEFsaXZlVGltZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVVbml0IHVuaXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCbG9ja2luZ1F1ZXVlPFJ1bm5hYmxlPiB3b3JrUXVldWUpIHsKKyAgICAgICAgdGhpcyhjb3JlUG9vbFNpemUsIG1heGltdW1Qb29sU2l6ZSwga2VlcEFsaXZlVGltZSwgdW5pdCwgd29ya1F1ZXVlLAorICAgICAgICAgICAgIEV4ZWN1dG9ycy5kZWZhdWx0VGhyZWFkRmFjdG9yeSgpLCBkZWZhdWx0SGFuZGxlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgVGhyZWFkUG9vbEV4ZWN1dG9yfSB3aXRoIHRoZSBnaXZlbiBpbml0aWFsCisgICAgICogcGFyYW1ldGVycyBhbmQgZGVmYXVsdCByZWplY3RlZCBleGVjdXRpb24gaGFuZGxlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb3JlUG9vbFNpemUgdGhlIG51bWJlciBvZiB0aHJlYWRzIHRvIGtlZXAgaW4gdGhlIHBvb2wsIGV2ZW4KKyAgICAgKiAgICAgICAgaWYgdGhleSBhcmUgaWRsZSwgdW5sZXNzIHtAY29kZSBhbGxvd0NvcmVUaHJlYWRUaW1lT3V0fSBpcyBzZXQKKyAgICAgKiBAcGFyYW0gbWF4aW11bVBvb2xTaXplIHRoZSBtYXhpbXVtIG51bWJlciBvZiB0aHJlYWRzIHRvIGFsbG93IGluIHRoZQorICAgICAqICAgICAgICBwb29sCisgICAgICogQHBhcmFtIGtlZXBBbGl2ZVRpbWUgd2hlbiB0aGUgbnVtYmVyIG9mIHRocmVhZHMgaXMgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgIHRoZSBjb3JlLCB0aGlzIGlzIHRoZSBtYXhpbXVtIHRpbWUgdGhhdCBleGNlc3MgaWRsZSB0aHJlYWRzCisgICAgICogICAgICAgIHdpbGwgd2FpdCBmb3IgbmV3IHRhc2tzIGJlZm9yZSB0ZXJtaW5hdGluZy4KKyAgICAgKiBAcGFyYW0gdW5pdCB0aGUgdGltZSB1bml0IGZvciB0aGUge0Bjb2RlIGtlZXBBbGl2ZVRpbWV9IGFyZ3VtZW50CisgICAgICogQHBhcmFtIHdvcmtRdWV1ZSB0aGUgcXVldWUgdG8gdXNlIGZvciBob2xkaW5nIHRhc2tzIGJlZm9yZSB0aGV5IGFyZQorICAgICAqICAgICAgICBleGVjdXRlZC4gIFRoaXMgcXVldWUgd2lsbCBob2xkIG9ubHkgdGhlIHtAY29kZSBSdW5uYWJsZX0KKyAgICAgKiAgICAgICAgdGFza3Mgc3VibWl0dGVkIGJ5IHRoZSB7QGNvZGUgZXhlY3V0ZX0gbWV0aG9kLgorICAgICAqIEBwYXJhbSB0aHJlYWRGYWN0b3J5IHRoZSBmYWN0b3J5IHRvIHVzZSB3aGVuIHRoZSBleGVjdXRvcgorICAgICAqICAgICAgICBjcmVhdGVzIGEgbmV3IHRocmVhZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIG9uZSBvZiB0aGUgZm9sbG93aW5nIGhvbGRzOjxicj4KKyAgICAgKiAgICAgICAgIHtAY29kZSBjb3JlUG9vbFNpemUgPCAwfTxicj4KKyAgICAgKiAgICAgICAgIHtAY29kZSBrZWVwQWxpdmVUaW1lIDwgMH08YnI+CisgICAgICogICAgICAgICB7QGNvZGUgbWF4aW11bVBvb2xTaXplIDw9IDB9PGJyPgorICAgICAqICAgICAgICAge0Bjb2RlIG1heGltdW1Qb29sU2l6ZSA8IGNvcmVQb29sU2l6ZX0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSB3b3JrUXVldWV9CisgICAgICogICAgICAgICBvciB7QGNvZGUgdGhyZWFkRmFjdG9yeX0gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBUaHJlYWRQb29sRXhlY3V0b3IoaW50IGNvcmVQb29sU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtYXhpbXVtUG9vbFNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb25nIGtlZXBBbGl2ZVRpbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lVW5pdCB1bml0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmxvY2tpbmdRdWV1ZTxSdW5uYWJsZT4gd29ya1F1ZXVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhyZWFkRmFjdG9yeSB0aHJlYWRGYWN0b3J5KSB7CisgICAgICAgIHRoaXMoY29yZVBvb2xTaXplLCBtYXhpbXVtUG9vbFNpemUsIGtlZXBBbGl2ZVRpbWUsIHVuaXQsIHdvcmtRdWV1ZSwKKyAgICAgICAgICAgICB0aHJlYWRGYWN0b3J5LCBkZWZhdWx0SGFuZGxlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgVGhyZWFkUG9vbEV4ZWN1dG9yfSB3aXRoIHRoZSBnaXZlbiBpbml0aWFsCisgICAgICogcGFyYW1ldGVycyBhbmQgZGVmYXVsdCB0aHJlYWQgZmFjdG9yeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb3JlUG9vbFNpemUgdGhlIG51bWJlciBvZiB0aHJlYWRzIHRvIGtlZXAgaW4gdGhlIHBvb2wsIGV2ZW4KKyAgICAgKiAgICAgICAgaWYgdGhleSBhcmUgaWRsZSwgdW5sZXNzIHtAY29kZSBhbGxvd0NvcmVUaHJlYWRUaW1lT3V0fSBpcyBzZXQKKyAgICAgKiBAcGFyYW0gbWF4aW11bVBvb2xTaXplIHRoZSBtYXhpbXVtIG51bWJlciBvZiB0aHJlYWRzIHRvIGFsbG93IGluIHRoZQorICAgICAqICAgICAgICBwb29sCisgICAgICogQHBhcmFtIGtlZXBBbGl2ZVRpbWUgd2hlbiB0aGUgbnVtYmVyIG9mIHRocmVhZHMgaXMgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgIHRoZSBjb3JlLCB0aGlzIGlzIHRoZSBtYXhpbXVtIHRpbWUgdGhhdCBleGNlc3MgaWRsZSB0aHJlYWRzCisgICAgICogICAgICAgIHdpbGwgd2FpdCBmb3IgbmV3IHRhc2tzIGJlZm9yZSB0ZXJtaW5hdGluZy4KKyAgICAgKiBAcGFyYW0gdW5pdCB0aGUgdGltZSB1bml0IGZvciB0aGUge0Bjb2RlIGtlZXBBbGl2ZVRpbWV9IGFyZ3VtZW50CisgICAgICogQHBhcmFtIHdvcmtRdWV1ZSB0aGUgcXVldWUgdG8gdXNlIGZvciBob2xkaW5nIHRhc2tzIGJlZm9yZSB0aGV5IGFyZQorICAgICAqICAgICAgICBleGVjdXRlZC4gIFRoaXMgcXVldWUgd2lsbCBob2xkIG9ubHkgdGhlIHtAY29kZSBSdW5uYWJsZX0KKyAgICAgKiAgICAgICAgdGFza3Mgc3VibWl0dGVkIGJ5IHRoZSB7QGNvZGUgZXhlY3V0ZX0gbWV0aG9kLgorICAgICAqIEBwYXJhbSBoYW5kbGVyIHRoZSBoYW5kbGVyIHRvIHVzZSB3aGVuIGV4ZWN1dGlvbiBpcyBibG9ja2VkCisgICAgICogICAgICAgIGJlY2F1c2UgdGhlIHRocmVhZCBib3VuZHMgYW5kIHF1ZXVlIGNhcGFjaXRpZXMgYXJlIHJlYWNoZWQKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBvbmUgb2YgdGhlIGZvbGxvd2luZyBob2xkczo8YnI+CisgICAgICogICAgICAgICB7QGNvZGUgY29yZVBvb2xTaXplIDwgMH08YnI+CisgICAgICogICAgICAgICB7QGNvZGUga2VlcEFsaXZlVGltZSA8IDB9PGJyPgorICAgICAqICAgICAgICAge0Bjb2RlIG1heGltdW1Qb29sU2l6ZSA8PSAwfTxicj4KKyAgICAgKiAgICAgICAgIHtAY29kZSBtYXhpbXVtUG9vbFNpemUgPCBjb3JlUG9vbFNpemV9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgd29ya1F1ZXVlfQorICAgICAqICAgICAgICAgb3Ige0Bjb2RlIGhhbmRsZXJ9IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgVGhyZWFkUG9vbEV4ZWN1dG9yKGludCBjb3JlUG9vbFNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWF4aW11bVBvb2xTaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBrZWVwQWxpdmVUaW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZVVuaXQgdW5pdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJsb2NraW5nUXVldWU8UnVubmFibGU+IHdvcmtRdWV1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlamVjdGVkRXhlY3V0aW9uSGFuZGxlciBoYW5kbGVyKSB7CisgICAgICAgIHRoaXMoY29yZVBvb2xTaXplLCBtYXhpbXVtUG9vbFNpemUsIGtlZXBBbGl2ZVRpbWUsIHVuaXQsIHdvcmtRdWV1ZSwKKyAgICAgICAgICAgICBFeGVjdXRvcnMuZGVmYXVsdFRocmVhZEZhY3RvcnkoKSwgaGFuZGxlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgVGhyZWFkUG9vbEV4ZWN1dG9yfSB3aXRoIHRoZSBnaXZlbiBpbml0aWFsCisgICAgICogcGFyYW1ldGVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb3JlUG9vbFNpemUgdGhlIG51bWJlciBvZiB0aHJlYWRzIHRvIGtlZXAgaW4gdGhlIHBvb2wsIGV2ZW4KKyAgICAgKiAgICAgICAgaWYgdGhleSBhcmUgaWRsZSwgdW5sZXNzIHtAY29kZSBhbGxvd0NvcmVUaHJlYWRUaW1lT3V0fSBpcyBzZXQKKyAgICAgKiBAcGFyYW0gbWF4aW11bVBvb2xTaXplIHRoZSBtYXhpbXVtIG51bWJlciBvZiB0aHJlYWRzIHRvIGFsbG93IGluIHRoZQorICAgICAqICAgICAgICBwb29sCisgICAgICogQHBhcmFtIGtlZXBBbGl2ZVRpbWUgd2hlbiB0aGUgbnVtYmVyIG9mIHRocmVhZHMgaXMgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgIHRoZSBjb3JlLCB0aGlzIGlzIHRoZSBtYXhpbXVtIHRpbWUgdGhhdCBleGNlc3MgaWRsZSB0aHJlYWRzCisgICAgICogICAgICAgIHdpbGwgd2FpdCBmb3IgbmV3IHRhc2tzIGJlZm9yZSB0ZXJtaW5hdGluZy4KKyAgICAgKiBAcGFyYW0gdW5pdCB0aGUgdGltZSB1bml0IGZvciB0aGUge0Bjb2RlIGtlZXBBbGl2ZVRpbWV9IGFyZ3VtZW50CisgICAgICogQHBhcmFtIHdvcmtRdWV1ZSB0aGUgcXVldWUgdG8gdXNlIGZvciBob2xkaW5nIHRhc2tzIGJlZm9yZSB0aGV5IGFyZQorICAgICAqICAgICAgICBleGVjdXRlZC4gIFRoaXMgcXVldWUgd2lsbCBob2xkIG9ubHkgdGhlIHtAY29kZSBSdW5uYWJsZX0KKyAgICAgKiAgICAgICAgdGFza3Mgc3VibWl0dGVkIGJ5IHRoZSB7QGNvZGUgZXhlY3V0ZX0gbWV0aG9kLgorICAgICAqIEBwYXJhbSB0aHJlYWRGYWN0b3J5IHRoZSBmYWN0b3J5IHRvIHVzZSB3aGVuIHRoZSBleGVjdXRvcgorICAgICAqICAgICAgICBjcmVhdGVzIGEgbmV3IHRocmVhZAorICAgICAqIEBwYXJhbSBoYW5kbGVyIHRoZSBoYW5kbGVyIHRvIHVzZSB3aGVuIGV4ZWN1dGlvbiBpcyBibG9ja2VkCisgICAgICogICAgICAgIGJlY2F1c2UgdGhlIHRocmVhZCBib3VuZHMgYW5kIHF1ZXVlIGNhcGFjaXRpZXMgYXJlIHJlYWNoZWQKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBvbmUgb2YgdGhlIGZvbGxvd2luZyBob2xkczo8YnI+CisgICAgICogICAgICAgICB7QGNvZGUgY29yZVBvb2xTaXplIDwgMH08YnI+CisgICAgICogICAgICAgICB7QGNvZGUga2VlcEFsaXZlVGltZSA8IDB9PGJyPgorICAgICAqICAgICAgICAge0Bjb2RlIG1heGltdW1Qb29sU2l6ZSA8PSAwfTxicj4KKyAgICAgKiAgICAgICAgIHtAY29kZSBtYXhpbXVtUG9vbFNpemUgPCBjb3JlUG9vbFNpemV9CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB7QGNvZGUgd29ya1F1ZXVlfQorICAgICAqICAgICAgICAgb3Ige0Bjb2RlIHRocmVhZEZhY3Rvcnl9IG9yIHtAY29kZSBoYW5kbGVyfSBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIFRocmVhZFBvb2xFeGVjdXRvcihpbnQgY29yZVBvb2xTaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1heGltdW1Qb29sU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcga2VlcEFsaXZlVGltZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVVbml0IHVuaXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCbG9ja2luZ1F1ZXVlPFJ1bm5hYmxlPiB3b3JrUXVldWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaHJlYWRGYWN0b3J5IHRocmVhZEZhY3RvcnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWplY3RlZEV4ZWN1dGlvbkhhbmRsZXIgaGFuZGxlcikgeworICAgICAgICBpZiAoY29yZVBvb2xTaXplIDwgMCB8fAorICAgICAgICAgICAgbWF4aW11bVBvb2xTaXplIDw9IDAgfHwKKyAgICAgICAgICAgIG1heGltdW1Qb29sU2l6ZSA8IGNvcmVQb29sU2l6ZSB8fAorICAgICAgICAgICAga2VlcEFsaXZlVGltZSA8IDApCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIGlmICh3b3JrUXVldWUgPT0gbnVsbCB8fCB0aHJlYWRGYWN0b3J5ID09IG51bGwgfHwgaGFuZGxlciA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIHRoaXMuY29yZVBvb2xTaXplID0gY29yZVBvb2xTaXplOworICAgICAgICB0aGlzLm1heGltdW1Qb29sU2l6ZSA9IG1heGltdW1Qb29sU2l6ZTsKKyAgICAgICAgdGhpcy53b3JrUXVldWUgPSB3b3JrUXVldWU7CisgICAgICAgIHRoaXMua2VlcEFsaXZlVGltZSA9IHVuaXQudG9OYW5vcyhrZWVwQWxpdmVUaW1lKTsKKyAgICAgICAgdGhpcy50aHJlYWRGYWN0b3J5ID0gdGhyZWFkRmFjdG9yeTsKKyAgICAgICAgdGhpcy5oYW5kbGVyID0gaGFuZGxlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeGVjdXRlcyB0aGUgZ2l2ZW4gdGFzayBzb21ldGltZSBpbiB0aGUgZnV0dXJlLiAgVGhlIHRhc2sKKyAgICAgKiBtYXkgZXhlY3V0ZSBpbiBhIG5ldyB0aHJlYWQgb3IgaW4gYW4gZXhpc3RpbmcgcG9vbGVkIHRocmVhZC4KKyAgICAgKgorICAgICAqIElmIHRoZSB0YXNrIGNhbm5vdCBiZSBzdWJtaXR0ZWQgZm9yIGV4ZWN1dGlvbiwgZWl0aGVyIGJlY2F1c2UgdGhpcworICAgICAqIGV4ZWN1dG9yIGhhcyBiZWVuIHNodXRkb3duIG9yIGJlY2F1c2UgaXRzIGNhcGFjaXR5IGhhcyBiZWVuIHJlYWNoZWQsCisgICAgICogdGhlIHRhc2sgaXMgaGFuZGxlZCBieSB0aGUgY3VycmVudCB7QGNvZGUgUmVqZWN0ZWRFeGVjdXRpb25IYW5kbGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb21tYW5kIHRoZSB0YXNrIHRvIGV4ZWN1dGUKKyAgICAgKiBAdGhyb3dzIFJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9uIGF0IGRpc2NyZXRpb24gb2YKKyAgICAgKiAgICAgICAgIHtAY29kZSBSZWplY3RlZEV4ZWN1dGlvbkhhbmRsZXJ9LCBpZiB0aGUgdGFzaworICAgICAqICAgICAgICAgY2Fubm90IGJlIGFjY2VwdGVkIGZvciBleGVjdXRpb24KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBjb21tYW5kfSBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgZXhlY3V0ZShSdW5uYWJsZSBjb21tYW5kKSB7CisgICAgICAgIGlmIChjb21tYW5kID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgLyoKKyAgICAgICAgICogUHJvY2VlZCBpbiAzIHN0ZXBzOgorICAgICAgICAgKgorICAgICAgICAgKiAxLiBJZiBmZXdlciB0aGFuIGNvcmVQb29sU2l6ZSB0aHJlYWRzIGFyZSBydW5uaW5nLCB0cnkgdG8KKyAgICAgICAgICogc3RhcnQgYSBuZXcgdGhyZWFkIHdpdGggdGhlIGdpdmVuIGNvbW1hbmQgYXMgaXRzIGZpcnN0CisgICAgICAgICAqIHRhc2suICBUaGUgY2FsbCB0byBhZGRXb3JrZXIgYXRvbWljYWxseSBjaGVja3MgcnVuU3RhdGUgYW5kCisgICAgICAgICAqIHdvcmtlckNvdW50LCBhbmQgc28gcHJldmVudHMgZmFsc2UgYWxhcm1zIHRoYXQgd291bGQgYWRkCisgICAgICAgICAqIHRocmVhZHMgd2hlbiBpdCBzaG91bGRuJ3QsIGJ5IHJldHVybmluZyBmYWxzZS4KKyAgICAgICAgICoKKyAgICAgICAgICogMi4gSWYgYSB0YXNrIGNhbiBiZSBzdWNjZXNzZnVsbHkgcXVldWVkLCB0aGVuIHdlIHN0aWxsIG5lZWQKKyAgICAgICAgICogdG8gZG91YmxlLWNoZWNrIHdoZXRoZXIgd2Ugc2hvdWxkIGhhdmUgYWRkZWQgYSB0aHJlYWQKKyAgICAgICAgICogKGJlY2F1c2UgZXhpc3Rpbmcgb25lcyBkaWVkIHNpbmNlIGxhc3QgY2hlY2tpbmcpIG9yIHRoYXQKKyAgICAgICAgICogdGhlIHBvb2wgc2h1dCBkb3duIHNpbmNlIGVudHJ5IGludG8gdGhpcyBtZXRob2QuIFNvIHdlCisgICAgICAgICAqIHJlY2hlY2sgc3RhdGUgYW5kIGlmIG5lY2Vzc2FyeSByb2xsIGJhY2sgdGhlIGVucXVldWluZyBpZgorICAgICAgICAgKiBzdG9wcGVkLCBvciBzdGFydCBhIG5ldyB0aHJlYWQgaWYgdGhlcmUgYXJlIG5vbmUuCisgICAgICAgICAqCisgICAgICAgICAqIDMuIElmIHdlIGNhbm5vdCBxdWV1ZSB0YXNrLCB0aGVuIHdlIHRyeSB0byBhZGQgYSBuZXcKKyAgICAgICAgICogdGhyZWFkLiAgSWYgaXQgZmFpbHMsIHdlIGtub3cgd2UgYXJlIHNodXQgZG93biBvciBzYXR1cmF0ZWQKKyAgICAgICAgICogYW5kIHNvIHJlamVjdCB0aGUgdGFzay4KKyAgICAgICAgICovCisgICAgICAgIGludCBjID0gY3RsLmdldCgpOworICAgICAgICBpZiAod29ya2VyQ291bnRPZihjKSA8IGNvcmVQb29sU2l6ZSkgeworICAgICAgICAgICAgaWYgKGFkZFdvcmtlcihjb21tYW5kLCB0cnVlKSkKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICBjID0gY3RsLmdldCgpOworICAgICAgICB9CisgICAgICAgIGlmIChpc1J1bm5pbmcoYykgJiYgd29ya1F1ZXVlLm9mZmVyKGNvbW1hbmQpKSB7CisgICAgICAgICAgICBpbnQgcmVjaGVjayA9IGN0bC5nZXQoKTsKKyAgICAgICAgICAgIGlmICghIGlzUnVubmluZyhyZWNoZWNrKSAmJiByZW1vdmUoY29tbWFuZCkpCisgICAgICAgICAgICAgICAgcmVqZWN0KGNvbW1hbmQpOworICAgICAgICAgICAgZWxzZSBpZiAod29ya2VyQ291bnRPZihyZWNoZWNrKSA9PSAwKQorICAgICAgICAgICAgICAgIGFkZFdvcmtlcihudWxsLCBmYWxzZSk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoIWFkZFdvcmtlcihjb21tYW5kLCBmYWxzZSkpCisgICAgICAgICAgICByZWplY3QoY29tbWFuZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhdGVzIGFuIG9yZGVybHkgc2h1dGRvd24gaW4gd2hpY2ggcHJldmlvdXNseSBzdWJtaXR0ZWQKKyAgICAgKiB0YXNrcyBhcmUgZXhlY3V0ZWQsIGJ1dCBubyBuZXcgdGFza3Mgd2lsbCBiZSBhY2NlcHRlZC4KKyAgICAgKiBJbnZvY2F0aW9uIGhhcyBubyBhZGRpdGlvbmFsIGVmZmVjdCBpZiBhbHJlYWR5IHNodXQgZG93bi4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGRvZXMgbm90IHdhaXQgZm9yIHByZXZpb3VzbHkgc3VibWl0dGVkIHRhc2tzIHRvCisgICAgICogY29tcGxldGUgZXhlY3V0aW9uLiAgVXNlIHtAbGluayAjYXdhaXRUZXJtaW5hdGlvbiBhd2FpdFRlcm1pbmF0aW9ufQorICAgICAqIHRvIGRvIHRoYXQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzaHV0ZG93bigpIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBtYWluTG9jayA9IHRoaXMubWFpbkxvY2s7CisgICAgICAgIG1haW5Mb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNoZWNrU2h1dGRvd25BY2Nlc3MoKTsKKyAgICAgICAgICAgIGFkdmFuY2VSdW5TdGF0ZShTSFVURE9XTik7CisgICAgICAgICAgICBpbnRlcnJ1cHRJZGxlV29ya2VycygpOworICAgICAgICAgICAgb25TaHV0ZG93bigpOyAvLyBob29rIGZvciBTY2hlZHVsZWRUaHJlYWRQb29sRXhlY3V0b3IKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1haW5Mb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgICAgIHRyeVRlcm1pbmF0ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0dGVtcHRzIHRvIHN0b3AgYWxsIGFjdGl2ZWx5IGV4ZWN1dGluZyB0YXNrcywgaGFsdHMgdGhlCisgICAgICogcHJvY2Vzc2luZyBvZiB3YWl0aW5nIHRhc2tzLCBhbmQgcmV0dXJucyBhIGxpc3Qgb2YgdGhlIHRhc2tzCisgICAgICogdGhhdCB3ZXJlIGF3YWl0aW5nIGV4ZWN1dGlvbi4gVGhlc2UgdGFza3MgYXJlIGRyYWluZWQgKHJlbW92ZWQpCisgICAgICogZnJvbSB0aGUgdGFzayBxdWV1ZSB1cG9uIHJldHVybiBmcm9tIHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgZG9lcyBub3Qgd2FpdCBmb3IgYWN0aXZlbHkgZXhlY3V0aW5nIHRhc2tzIHRvCisgICAgICogdGVybWluYXRlLiAgVXNlIHtAbGluayAjYXdhaXRUZXJtaW5hdGlvbiBhd2FpdFRlcm1pbmF0aW9ufSB0bworICAgICAqIGRvIHRoYXQuCisgICAgICoKKyAgICAgKiA8cD5UaGVyZSBhcmUgbm8gZ3VhcmFudGVlcyBiZXlvbmQgYmVzdC1lZmZvcnQgYXR0ZW1wdHMgdG8gc3RvcAorICAgICAqIHByb2Nlc3NpbmcgYWN0aXZlbHkgZXhlY3V0aW5nIHRhc2tzLiAgVGhpcyBpbXBsZW1lbnRhdGlvbgorICAgICAqIGNhbmNlbHMgdGFza3MgdmlhIHtAbGluayBUaHJlYWQjaW50ZXJydXB0fSwgc28gYW55IHRhc2sgdGhhdAorICAgICAqIGZhaWxzIHRvIHJlc3BvbmQgdG8gaW50ZXJydXB0cyBtYXkgbmV2ZXIgdGVybWluYXRlLgorICAgICAqCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgcHVibGljIExpc3Q8UnVubmFibGU+IHNodXRkb3duTm93KCkgeworICAgICAgICBMaXN0PFJ1bm5hYmxlPiB0YXNrczsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBtYWluTG9jayA9IHRoaXMubWFpbkxvY2s7CisgICAgICAgIG1haW5Mb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNoZWNrU2h1dGRvd25BY2Nlc3MoKTsKKyAgICAgICAgICAgIGFkdmFuY2VSdW5TdGF0ZShTVE9QKTsKKyAgICAgICAgICAgIGludGVycnVwdFdvcmtlcnMoKTsKKyAgICAgICAgICAgIHRhc2tzID0gZHJhaW5RdWV1ZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbWFpbkxvY2sudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5VGVybWluYXRlKCk7CisgICAgICAgIHJldHVybiB0YXNrczsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NodXRkb3duKCkgeworICAgICAgICByZXR1cm4gISBpc1J1bm5pbmcoY3RsLmdldCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBleGVjdXRvciBpcyBpbiB0aGUgcHJvY2VzcyBvZiB0ZXJtaW5hdGluZworICAgICAqIGFmdGVyIHtAbGluayAjc2h1dGRvd259IG9yIHtAbGluayAjc2h1dGRvd25Ob3d9IGJ1dCBoYXMgbm90CisgICAgICogY29tcGxldGVseSB0ZXJtaW5hdGVkLiAgVGhpcyBtZXRob2QgbWF5IGJlIHVzZWZ1bCBmb3IKKyAgICAgKiBkZWJ1Z2dpbmcuIEEgcmV0dXJuIG9mIHtAY29kZSB0cnVlfSByZXBvcnRlZCBhIHN1ZmZpY2llbnQKKyAgICAgKiBwZXJpb2QgYWZ0ZXIgc2h1dGRvd24gbWF5IGluZGljYXRlIHRoYXQgc3VibWl0dGVkIHRhc2tzIGhhdmUKKyAgICAgKiBpZ25vcmVkIG9yIHN1cHByZXNzZWQgaW50ZXJydXB0aW9uLCBjYXVzaW5nIHRoaXMgZXhlY3V0b3Igbm90CisgICAgICogdG8gcHJvcGVybHkgdGVybWluYXRlLgorICAgICAqCisgICAgICogQHJldHVybiB0cnVlIGlmIHRlcm1pbmF0aW5nIGJ1dCBub3QgeWV0IHRlcm1pbmF0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1Rlcm1pbmF0aW5nKCkgeworICAgICAgICBpbnQgYyA9IGN0bC5nZXQoKTsKKyAgICAgICAgcmV0dXJuICEgaXNSdW5uaW5nKGMpICYmIHJ1blN0YXRlTGVzc1RoYW4oYywgVEVSTUlOQVRFRCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNUZXJtaW5hdGVkKCkgeworICAgICAgICByZXR1cm4gcnVuU3RhdGVBdExlYXN0KGN0bC5nZXQoKSwgVEVSTUlOQVRFRCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gYXdhaXRUZXJtaW5hdGlvbihsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgbmFub3MgPSB1bml0LnRvTmFub3ModGltZW91dCk7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbWFpbkxvY2sgPSB0aGlzLm1haW5Mb2NrOworICAgICAgICBtYWluTG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgaWYgKHJ1blN0YXRlQXRMZWFzdChjdGwuZ2V0KCksIFRFUk1JTkFURUQpKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICBpZiAobmFub3MgPD0gMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIG5hbm9zID0gdGVybWluYXRpb24uYXdhaXROYW5vcyhuYW5vcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYWluTG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEludm9rZXMge0Bjb2RlIHNodXRkb3dufSB3aGVuIHRoaXMgZXhlY3V0b3IgaXMgbm8gbG9uZ2VyCisgICAgICogcmVmZXJlbmNlZCBhbmQgaXQgaGFzIG5vIHRocmVhZHMuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB7CisgICAgICAgIHNodXRkb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdGhyZWFkIGZhY3RvcnkgdXNlZCB0byBjcmVhdGUgbmV3IHRocmVhZHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhyZWFkRmFjdG9yeSB0aGUgbmV3IHRocmVhZCBmYWN0b3J5CisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aHJlYWRGYWN0b3J5IGlzIG51bGwKKyAgICAgKiBAc2VlICNnZXRUaHJlYWRGYWN0b3J5CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VGhyZWFkRmFjdG9yeShUaHJlYWRGYWN0b3J5IHRocmVhZEZhY3RvcnkpIHsKKyAgICAgICAgaWYgKHRocmVhZEZhY3RvcnkgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB0aGlzLnRocmVhZEZhY3RvcnkgPSB0aHJlYWRGYWN0b3J5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRocmVhZCBmYWN0b3J5IHVzZWQgdG8gY3JlYXRlIG5ldyB0aHJlYWRzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY3VycmVudCB0aHJlYWQgZmFjdG9yeQorICAgICAqIEBzZWUgI3NldFRocmVhZEZhY3RvcnkKKyAgICAgKi8KKyAgICBwdWJsaWMgVGhyZWFkRmFjdG9yeSBnZXRUaHJlYWRGYWN0b3J5KCkgeworICAgICAgICByZXR1cm4gdGhyZWFkRmFjdG9yeTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGEgbmV3IGhhbmRsZXIgZm9yIHVuZXhlY3V0YWJsZSB0YXNrcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBoYW5kbGVyIHRoZSBuZXcgaGFuZGxlcgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgaGFuZGxlciBpcyBudWxsCisgICAgICogQHNlZSAjZ2V0UmVqZWN0ZWRFeGVjdXRpb25IYW5kbGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmVqZWN0ZWRFeGVjdXRpb25IYW5kbGVyKFJlamVjdGVkRXhlY3V0aW9uSGFuZGxlciBoYW5kbGVyKSB7CisgICAgICAgIGlmIChoYW5kbGVyID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgdGhpcy5oYW5kbGVyID0gaGFuZGxlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGhhbmRsZXIgZm9yIHVuZXhlY3V0YWJsZSB0YXNrcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgaGFuZGxlcgorICAgICAqIEBzZWUgI3NldFJlamVjdGVkRXhlY3V0aW9uSGFuZGxlcgorICAgICAqLworICAgIHB1YmxpYyBSZWplY3RlZEV4ZWN1dGlvbkhhbmRsZXIgZ2V0UmVqZWN0ZWRFeGVjdXRpb25IYW5kbGVyKCkgeworICAgICAgICByZXR1cm4gaGFuZGxlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjb3JlIG51bWJlciBvZiB0aHJlYWRzLiAgVGhpcyBvdmVycmlkZXMgYW55IHZhbHVlIHNldAorICAgICAqIGluIHRoZSBjb25zdHJ1Y3Rvci4gIElmIHRoZSBuZXcgdmFsdWUgaXMgc21hbGxlciB0aGFuIHRoZQorICAgICAqIGN1cnJlbnQgdmFsdWUsIGV4Y2VzcyBleGlzdGluZyB0aHJlYWRzIHdpbGwgYmUgdGVybWluYXRlZCB3aGVuCisgICAgICogdGhleSBuZXh0IGJlY29tZSBpZGxlLiAgSWYgbGFyZ2VyLCBuZXcgdGhyZWFkcyB3aWxsLCBpZiBuZWVkZWQsCisgICAgICogYmUgc3RhcnRlZCB0byBleGVjdXRlIGFueSBxdWV1ZWQgdGFza3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29yZVBvb2xTaXplIHRoZSBuZXcgY29yZSBzaXplCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGNvcmVQb29sU2l6ZSA8IDB9CisgICAgICogQHNlZSAjZ2V0Q29yZVBvb2xTaXplCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q29yZVBvb2xTaXplKGludCBjb3JlUG9vbFNpemUpIHsKKyAgICAgICAgaWYgKGNvcmVQb29sU2l6ZSA8IDApCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIGludCBkZWx0YSA9IGNvcmVQb29sU2l6ZSAtIHRoaXMuY29yZVBvb2xTaXplOworICAgICAgICB0aGlzLmNvcmVQb29sU2l6ZSA9IGNvcmVQb29sU2l6ZTsKKyAgICAgICAgaWYgKHdvcmtlckNvdW50T2YoY3RsLmdldCgpKSA+IGNvcmVQb29sU2l6ZSkKKyAgICAgICAgICAgIGludGVycnVwdElkbGVXb3JrZXJzKCk7CisgICAgICAgIGVsc2UgaWYgKGRlbHRhID4gMCkgeworICAgICAgICAgICAgLy8gV2UgZG9uJ3QgcmVhbGx5IGtub3cgaG93IG1hbnkgbmV3IHRocmVhZHMgYXJlICJuZWVkZWQiLgorICAgICAgICAgICAgLy8gQXMgYSBoZXVyaXN0aWMsIHByZXN0YXJ0IGVub3VnaCBuZXcgd29ya2VycyAodXAgdG8gbmV3CisgICAgICAgICAgICAvLyBjb3JlIHNpemUpIHRvIGhhbmRsZSB0aGUgY3VycmVudCBudW1iZXIgb2YgdGFza3MgaW4KKyAgICAgICAgICAgIC8vIHF1ZXVlLCBidXQgc3RvcCBpZiBxdWV1ZSBiZWNvbWVzIGVtcHR5IHdoaWxlIGRvaW5nIHNvLgorICAgICAgICAgICAgaW50IGsgPSBNYXRoLm1pbihkZWx0YSwgd29ya1F1ZXVlLnNpemUoKSk7CisgICAgICAgICAgICB3aGlsZSAoay0tID4gMCAmJiBhZGRXb3JrZXIobnVsbCwgdHJ1ZSkpIHsKKyAgICAgICAgICAgICAgICBpZiAod29ya1F1ZXVlLmlzRW1wdHkoKSkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb3JlIG51bWJlciBvZiB0aHJlYWRzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29yZSBudW1iZXIgb2YgdGhyZWFkcworICAgICAqIEBzZWUgI3NldENvcmVQb29sU2l6ZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Q29yZVBvb2xTaXplKCkgeworICAgICAgICByZXR1cm4gY29yZVBvb2xTaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0YXJ0cyBhIGNvcmUgdGhyZWFkLCBjYXVzaW5nIGl0IHRvIGlkbHkgd2FpdCBmb3Igd29yay4gVGhpcworICAgICAqIG92ZXJyaWRlcyB0aGUgZGVmYXVsdCBwb2xpY3kgb2Ygc3RhcnRpbmcgY29yZSB0aHJlYWRzIG9ubHkgd2hlbgorICAgICAqIG5ldyB0YXNrcyBhcmUgZXhlY3V0ZWQuIFRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIHtAY29kZSBmYWxzZX0KKyAgICAgKiBpZiBhbGwgY29yZSB0aHJlYWRzIGhhdmUgYWxyZWFkeSBiZWVuIHN0YXJ0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBhIHRocmVhZCB3YXMgc3RhcnRlZAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHByZXN0YXJ0Q29yZVRocmVhZCgpIHsKKyAgICAgICAgcmV0dXJuIHdvcmtlckNvdW50T2YoY3RsLmdldCgpKSA8IGNvcmVQb29sU2l6ZSAmJgorICAgICAgICAgICAgYWRkV29ya2VyKG51bGwsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0YXJ0cyBhbGwgY29yZSB0aHJlYWRzLCBjYXVzaW5nIHRoZW0gdG8gaWRseSB3YWl0IGZvciB3b3JrLiBUaGlzCisgICAgICogb3ZlcnJpZGVzIHRoZSBkZWZhdWx0IHBvbGljeSBvZiBzdGFydGluZyBjb3JlIHRocmVhZHMgb25seSB3aGVuCisgICAgICogbmV3IHRhc2tzIGFyZSBleGVjdXRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiB0aHJlYWRzIHN0YXJ0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHByZXN0YXJ0QWxsQ29yZVRocmVhZHMoKSB7CisgICAgICAgIGludCBuID0gMDsKKyAgICAgICAgd2hpbGUgKGFkZFdvcmtlcihudWxsLCB0cnVlKSkKKyAgICAgICAgICAgICsrbjsKKyAgICAgICAgcmV0dXJuIG47CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgcG9vbCBhbGxvd3MgY29yZSB0aHJlYWRzIHRvIHRpbWUgb3V0IGFuZAorICAgICAqIHRlcm1pbmF0ZSBpZiBubyB0YXNrcyBhcnJpdmUgd2l0aGluIHRoZSBrZWVwQWxpdmUgdGltZSwgYmVpbmcKKyAgICAgKiByZXBsYWNlZCBpZiBuZWVkZWQgd2hlbiBuZXcgdGFza3MgYXJyaXZlLiBXaGVuIHRydWUsIHRoZSBzYW1lCisgICAgICoga2VlcC1hbGl2ZSBwb2xpY3kgYXBwbHlpbmcgdG8gbm9uLWNvcmUgdGhyZWFkcyBhcHBsaWVzIGFsc28gdG8KKyAgICAgKiBjb3JlIHRocmVhZHMuIFdoZW4gZmFsc2UgKHRoZSBkZWZhdWx0KSwgY29yZSB0aHJlYWRzIGFyZSBuZXZlcgorICAgICAqIHRlcm1pbmF0ZWQgZHVlIHRvIGxhY2sgb2YgaW5jb21pbmcgdGFza3MuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBjb3JlIHRocmVhZHMgYXJlIGFsbG93ZWQgdG8gdGltZSBvdXQsCisgICAgICogICAgICAgICBlbHNlIHtAY29kZSBmYWxzZX0KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBhbGxvd3NDb3JlVGhyZWFkVGltZU91dCgpIHsKKyAgICAgICAgcmV0dXJuIGFsbG93Q29yZVRocmVhZFRpbWVPdXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcG9saWN5IGdvdmVybmluZyB3aGV0aGVyIGNvcmUgdGhyZWFkcyBtYXkgdGltZSBvdXQgYW5kCisgICAgICogdGVybWluYXRlIGlmIG5vIHRhc2tzIGFycml2ZSB3aXRoaW4gdGhlIGtlZXAtYWxpdmUgdGltZSwgYmVpbmcKKyAgICAgKiByZXBsYWNlZCBpZiBuZWVkZWQgd2hlbiBuZXcgdGFza3MgYXJyaXZlLiBXaGVuIGZhbHNlLCBjb3JlCisgICAgICogdGhyZWFkcyBhcmUgbmV2ZXIgdGVybWluYXRlZCBkdWUgdG8gbGFjayBvZiBpbmNvbWluZworICAgICAqIHRhc2tzLiBXaGVuIHRydWUsIHRoZSBzYW1lIGtlZXAtYWxpdmUgcG9saWN5IGFwcGx5aW5nIHRvCisgICAgICogbm9uLWNvcmUgdGhyZWFkcyBhcHBsaWVzIGFsc28gdG8gY29yZSB0aHJlYWRzLiBUbyBhdm9pZAorICAgICAqIGNvbnRpbnVhbCB0aHJlYWQgcmVwbGFjZW1lbnQsIHRoZSBrZWVwLWFsaXZlIHRpbWUgbXVzdCBiZQorICAgICAqIGdyZWF0ZXIgdGhhbiB6ZXJvIHdoZW4gc2V0dGluZyB7QGNvZGUgdHJ1ZX0uIFRoaXMgbWV0aG9kCisgICAgICogc2hvdWxkIGluIGdlbmVyYWwgYmUgY2FsbGVkIGJlZm9yZSB0aGUgcG9vbCBpcyBhY3RpdmVseSB1c2VkLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlIHtAY29kZSB0cnVlfSBpZiBzaG91bGQgdGltZSBvdXQsIGVsc2Uge0Bjb2RlIGZhbHNlfQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHZhbHVlIGlzIHtAY29kZSB0cnVlfQorICAgICAqICAgICAgICAgYW5kIHRoZSBjdXJyZW50IGtlZXAtYWxpdmUgdGltZSBpcyBub3QgZ3JlYXRlciB0aGFuIHplcm8KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhbGxvd0NvcmVUaHJlYWRUaW1lT3V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlICYmIGtlZXBBbGl2ZVRpbWUgPD0gMCkKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkNvcmUgdGhyZWFkcyBtdXN0IGhhdmUgbm9uemVybyBrZWVwIGFsaXZlIHRpbWVzIik7CisgICAgICAgIGlmICh2YWx1ZSAhPSBhbGxvd0NvcmVUaHJlYWRUaW1lT3V0KSB7CisgICAgICAgICAgICBhbGxvd0NvcmVUaHJlYWRUaW1lT3V0ID0gdmFsdWU7CisgICAgICAgICAgICBpZiAodmFsdWUpCisgICAgICAgICAgICAgICAgaW50ZXJydXB0SWRsZVdvcmtlcnMoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG1heGltdW0gYWxsb3dlZCBudW1iZXIgb2YgdGhyZWFkcy4gVGhpcyBvdmVycmlkZXMgYW55CisgICAgICogdmFsdWUgc2V0IGluIHRoZSBjb25zdHJ1Y3Rvci4gSWYgdGhlIG5ldyB2YWx1ZSBpcyBzbWFsbGVyIHRoYW4KKyAgICAgKiB0aGUgY3VycmVudCB2YWx1ZSwgZXhjZXNzIGV4aXN0aW5nIHRocmVhZHMgd2lsbCBiZQorICAgICAqIHRlcm1pbmF0ZWQgd2hlbiB0aGV5IG5leHQgYmVjb21lIGlkbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWF4aW11bVBvb2xTaXplIHRoZSBuZXcgbWF4aW11bQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBuZXcgbWF4aW11bSBpcworICAgICAqICAgICAgICAgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8sIG9yCisgICAgICogICAgICAgICBsZXNzIHRoYW4gdGhlIHtAbGlua3BsYWluICNnZXRDb3JlUG9vbFNpemUgY29yZSBwb29sIHNpemV9CisgICAgICogQHNlZSAjZ2V0TWF4aW11bVBvb2xTaXplCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TWF4aW11bVBvb2xTaXplKGludCBtYXhpbXVtUG9vbFNpemUpIHsKKyAgICAgICAgaWYgKG1heGltdW1Qb29sU2l6ZSA8PSAwIHx8IG1heGltdW1Qb29sU2l6ZSA8IGNvcmVQb29sU2l6ZSkKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgdGhpcy5tYXhpbXVtUG9vbFNpemUgPSBtYXhpbXVtUG9vbFNpemU7CisgICAgICAgIGlmICh3b3JrZXJDb3VudE9mKGN0bC5nZXQoKSkgPiBtYXhpbXVtUG9vbFNpemUpCisgICAgICAgICAgICBpbnRlcnJ1cHRJZGxlV29ya2VycygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1heGltdW0gYWxsb3dlZCBudW1iZXIgb2YgdGhyZWFkcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gYWxsb3dlZCBudW1iZXIgb2YgdGhyZWFkcworICAgICAqIEBzZWUgI3NldE1heGltdW1Qb29sU2l6ZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWF4aW11bVBvb2xTaXplKCkgeworICAgICAgICByZXR1cm4gbWF4aW11bVBvb2xTaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHRpbWUgbGltaXQgZm9yIHdoaWNoIHRocmVhZHMgbWF5IHJlbWFpbiBpZGxlIGJlZm9yZQorICAgICAqIGJlaW5nIHRlcm1pbmF0ZWQuICBJZiB0aGVyZSBhcmUgbW9yZSB0aGFuIHRoZSBjb3JlIG51bWJlciBvZgorICAgICAqIHRocmVhZHMgY3VycmVudGx5IGluIHRoZSBwb29sLCBhZnRlciB3YWl0aW5nIHRoaXMgYW1vdW50IG9mCisgICAgICogdGltZSB3aXRob3V0IHByb2Nlc3NpbmcgYSB0YXNrLCBleGNlc3MgdGhyZWFkcyB3aWxsIGJlCisgICAgICogdGVybWluYXRlZC4gIFRoaXMgb3ZlcnJpZGVzIGFueSB2YWx1ZSBzZXQgaW4gdGhlIGNvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIHRpbWUgdGhlIHRpbWUgdG8gd2FpdC4gIEEgdGltZSB2YWx1ZSBvZiB6ZXJvIHdpbGwgY2F1c2UKKyAgICAgKiAgICAgICAgZXhjZXNzIHRocmVhZHMgdG8gdGVybWluYXRlIGltbWVkaWF0ZWx5IGFmdGVyIGV4ZWN1dGluZyB0YXNrcy4KKyAgICAgKiBAcGFyYW0gdW5pdCB0aGUgdGltZSB1bml0IG9mIHRoZSB7QGNvZGUgdGltZX0gYXJndW1lbnQKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgdGltZX0gbGVzcyB0aGFuIHplcm8gb3IKKyAgICAgKiAgICAgICAgIGlmIHtAY29kZSB0aW1lfSBpcyB6ZXJvIGFuZCB7QGNvZGUgYWxsb3dzQ29yZVRocmVhZFRpbWVPdXR9CisgICAgICogQHNlZSAjZ2V0S2VlcEFsaXZlVGltZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEtlZXBBbGl2ZVRpbWUobG9uZyB0aW1lLCBUaW1lVW5pdCB1bml0KSB7CisgICAgICAgIGlmICh0aW1lIDwgMCkKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgaWYgKHRpbWUgPT0gMCAmJiBhbGxvd3NDb3JlVGhyZWFkVGltZU91dCgpKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQ29yZSB0aHJlYWRzIG11c3QgaGF2ZSBub256ZXJvIGtlZXAgYWxpdmUgdGltZXMiKTsKKyAgICAgICAgbG9uZyBrZWVwQWxpdmVUaW1lID0gdW5pdC50b05hbm9zKHRpbWUpOworICAgICAgICBsb25nIGRlbHRhID0ga2VlcEFsaXZlVGltZSAtIHRoaXMua2VlcEFsaXZlVGltZTsKKyAgICAgICAgdGhpcy5rZWVwQWxpdmVUaW1lID0ga2VlcEFsaXZlVGltZTsKKyAgICAgICAgaWYgKGRlbHRhIDwgMCkKKyAgICAgICAgICAgIGludGVycnVwdElkbGVXb3JrZXJzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGhyZWFkIGtlZXAtYWxpdmUgdGltZSwgd2hpY2ggaXMgdGhlIGFtb3VudCBvZiB0aW1lCisgICAgICogdGhhdCB0aHJlYWRzIGluIGV4Y2VzcyBvZiB0aGUgY29yZSBwb29sIHNpemUgbWF5IHJlbWFpbgorICAgICAqIGlkbGUgYmVmb3JlIGJlaW5nIHRlcm1pbmF0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdW5pdCB0aGUgZGVzaXJlZCB0aW1lIHVuaXQgb2YgdGhlIHJlc3VsdAorICAgICAqIEByZXR1cm4gdGhlIHRpbWUgbGltaXQKKyAgICAgKiBAc2VlICNzZXRLZWVwQWxpdmVUaW1lCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0S2VlcEFsaXZlVGltZShUaW1lVW5pdCB1bml0KSB7CisgICAgICAgIHJldHVybiB1bml0LmNvbnZlcnQoa2VlcEFsaXZlVGltZSwgVGltZVVuaXQuTkFOT1NFQ09ORFMpOworICAgIH0KKworICAgIC8qIFVzZXItbGV2ZWwgcXVldWUgdXRpbGl0aWVzICovCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0YXNrIHF1ZXVlIHVzZWQgYnkgdGhpcyBleGVjdXRvci4gQWNjZXNzIHRvIHRoZQorICAgICAqIHRhc2sgcXVldWUgaXMgaW50ZW5kZWQgcHJpbWFyaWx5IGZvciBkZWJ1Z2dpbmcgYW5kIG1vbml0b3JpbmcuCisgICAgICogVGhpcyBxdWV1ZSBtYXkgYmUgaW4gYWN0aXZlIHVzZS4gIFJldHJpZXZpbmcgdGhlIHRhc2sgcXVldWUKKyAgICAgKiBkb2VzIG5vdCBwcmV2ZW50IHF1ZXVlZCB0YXNrcyBmcm9tIGV4ZWN1dGluZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHRhc2sgcXVldWUKKyAgICAgKi8KKyAgICBwdWJsaWMgQmxvY2tpbmdRdWV1ZTxSdW5uYWJsZT4gZ2V0UXVldWUoKSB7CisgICAgICAgIHJldHVybiB3b3JrUXVldWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGlzIHRhc2sgZnJvbSB0aGUgZXhlY3V0b3IncyBpbnRlcm5hbCBxdWV1ZSBpZiBpdCBpcworICAgICAqIHByZXNlbnQsIHRodXMgY2F1c2luZyBpdCBub3QgdG8gYmUgcnVuIGlmIGl0IGhhcyBub3QgYWxyZWFkeQorICAgICAqIHN0YXJ0ZWQuCisgICAgICoKKyAgICAgKiA8cD4gVGhpcyBtZXRob2QgbWF5IGJlIHVzZWZ1bCBhcyBvbmUgcGFydCBvZiBhIGNhbmNlbGxhdGlvbgorICAgICAqIHNjaGVtZS4gIEl0IG1heSBmYWlsIHRvIHJlbW92ZSB0YXNrcyB0aGF0IGhhdmUgYmVlbiBjb252ZXJ0ZWQKKyAgICAgKiBpbnRvIG90aGVyIGZvcm1zIGJlZm9yZSBiZWluZyBwbGFjZWQgb24gdGhlIGludGVybmFsIHF1ZXVlLiBGb3IKKyAgICAgKiBleGFtcGxlLCBhIHRhc2sgZW50ZXJlZCB1c2luZyB7QGNvZGUgc3VibWl0fSBtaWdodCBiZQorICAgICAqIGNvbnZlcnRlZCBpbnRvIGEgZm9ybSB0aGF0IG1haW50YWlucyB7QGNvZGUgRnV0dXJlfSBzdGF0dXMuCisgICAgICogSG93ZXZlciwgaW4gc3VjaCBjYXNlcywgbWV0aG9kIHtAbGluayAjcHVyZ2V9IG1heSBiZSB1c2VkIHRvCisgICAgICogcmVtb3ZlIHRob3NlIEZ1dHVyZXMgdGhhdCBoYXZlIGJlZW4gY2FuY2VsbGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHRhc2sgdGhlIHRhc2sgdG8gcmVtb3ZlCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSB0YXNrIHdhcyByZW1vdmVkCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlKFJ1bm5hYmxlIHRhc2spIHsKKyAgICAgICAgYm9vbGVhbiByZW1vdmVkID0gd29ya1F1ZXVlLnJlbW92ZSh0YXNrKTsKKyAgICAgICAgdHJ5VGVybWluYXRlKCk7IC8vIEluIGNhc2UgU0hVVERPV04gYW5kIG5vdyBlbXB0eQorICAgICAgICByZXR1cm4gcmVtb3ZlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmllcyB0byByZW1vdmUgZnJvbSB0aGUgd29yayBxdWV1ZSBhbGwge0BsaW5rIEZ1dHVyZX0KKyAgICAgKiB0YXNrcyB0aGF0IGhhdmUgYmVlbiBjYW5jZWxsZWQuIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VmdWwgYXMgYQorICAgICAqIHN0b3JhZ2UgcmVjbGFtYXRpb24gb3BlcmF0aW9uLCB0aGF0IGhhcyBubyBvdGhlciBpbXBhY3Qgb24KKyAgICAgKiBmdW5jdGlvbmFsaXR5LiBDYW5jZWxsZWQgdGFza3MgYXJlIG5ldmVyIGV4ZWN1dGVkLCBidXQgbWF5CisgICAgICogYWNjdW11bGF0ZSBpbiB3b3JrIHF1ZXVlcyB1bnRpbCB3b3JrZXIgdGhyZWFkcyBjYW4gYWN0aXZlbHkKKyAgICAgKiByZW1vdmUgdGhlbS4gSW52b2tpbmcgdGhpcyBtZXRob2QgaW5zdGVhZCB0cmllcyB0byByZW1vdmUgdGhlbSBub3cuCisgICAgICogSG93ZXZlciwgdGhpcyBtZXRob2QgbWF5IGZhaWwgdG8gcmVtb3ZlIHRhc2tzIGluCisgICAgICogdGhlIHByZXNlbmNlIG9mIGludGVyZmVyZW5jZSBieSBvdGhlciB0aHJlYWRzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1cmdlKCkgeworICAgICAgICBmaW5hbCBCbG9ja2luZ1F1ZXVlPFJ1bm5hYmxlPiBxID0gd29ya1F1ZXVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgSXRlcmF0b3I8UnVubmFibGU+IGl0ID0gcS5pdGVyYXRvcigpOworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIFJ1bm5hYmxlIHIgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBGdXR1cmU8Pz4gJiYgKChGdXR1cmU8Pz4pcikuaXNDYW5jZWxsZWQoKSkKKyAgICAgICAgICAgICAgICAgICAgaXQucmVtb3ZlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24gZmFsbFRocm91Z2gpIHsKKyAgICAgICAgICAgIC8vIFRha2Ugc2xvdyBwYXRoIGlmIHdlIGVuY291bnRlciBpbnRlcmZlcmVuY2UgZHVyaW5nIHRyYXZlcnNhbC4KKyAgICAgICAgICAgIC8vIE1ha2UgY29weSBmb3IgdHJhdmVyc2FsIGFuZCBjYWxsIHJlbW92ZSBmb3IgY2FuY2VsbGVkIGVudHJpZXMuCisgICAgICAgICAgICAvLyBUaGUgc2xvdyBwYXRoIGlzIG1vcmUgbGlrZWx5IHRvIGJlIE8oTipOKS4KKyAgICAgICAgICAgIGZvciAoT2JqZWN0IHIgOiBxLnRvQXJyYXkoKSkKKyAgICAgICAgICAgICAgICBpZiAociBpbnN0YW5jZW9mIEZ1dHVyZTw/PiAmJiAoKEZ1dHVyZTw/PilyKS5pc0NhbmNlbGxlZCgpKQorICAgICAgICAgICAgICAgICAgICBxLnJlbW92ZShyKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeVRlcm1pbmF0ZSgpOyAvLyBJbiBjYXNlIFNIVVRET1dOIGFuZCBub3cgZW1wdHkKKyAgICB9CisKKyAgICAvKiBTdGF0aXN0aWNzICovCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IG51bWJlciBvZiB0aHJlYWRzIGluIHRoZSBwb29sLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHRocmVhZHMKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFBvb2xTaXplKCkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIG1haW5Mb2NrID0gdGhpcy5tYWluTG9jazsKKyAgICAgICAgbWFpbkxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gUmVtb3ZlIHJhcmUgYW5kIHN1cnByaXNpbmcgcG9zc2liaWxpdHkgb2YKKyAgICAgICAgICAgIC8vIGlzVGVybWluYXRlZCgpICYmIGdldFBvb2xTaXplKCkgPiAwCisgICAgICAgICAgICByZXR1cm4gcnVuU3RhdGVBdExlYXN0KGN0bC5nZXQoKSwgVElEWUlORykgPyAwCisgICAgICAgICAgICAgICAgOiB3b3JrZXJzLnNpemUoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1haW5Mb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXBwcm94aW1hdGUgbnVtYmVyIG9mIHRocmVhZHMgdGhhdCBhcmUgYWN0aXZlbHkKKyAgICAgKiBleGVjdXRpbmcgdGFza3MuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgdGhyZWFkcworICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0QWN0aXZlQ291bnQoKSB7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbWFpbkxvY2sgPSB0aGlzLm1haW5Mb2NrOworICAgICAgICBtYWluTG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgbiA9IDA7CisgICAgICAgICAgICBmb3IgKFdvcmtlciB3IDogd29ya2VycykKKyAgICAgICAgICAgICAgICBpZiAody5pc0xvY2tlZCgpKQorICAgICAgICAgICAgICAgICAgICArK247CisgICAgICAgICAgICByZXR1cm4gbjsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1haW5Mb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGFyZ2VzdCBudW1iZXIgb2YgdGhyZWFkcyB0aGF0IGhhdmUgZXZlcgorICAgICAqIHNpbXVsdGFuZW91c2x5IGJlZW4gaW4gdGhlIHBvb2wuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgdGhyZWFkcworICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TGFyZ2VzdFBvb2xTaXplKCkgeworICAgICAgICBmaW5hbCBSZWVudHJhbnRMb2NrIG1haW5Mb2NrID0gdGhpcy5tYWluTG9jazsKKyAgICAgICAgbWFpbkxvY2subG9jaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGxhcmdlc3RQb29sU2l6ZTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1haW5Mb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXBwcm94aW1hdGUgdG90YWwgbnVtYmVyIG9mIHRhc2tzIHRoYXQgaGF2ZSBldmVyIGJlZW4KKyAgICAgKiBzY2hlZHVsZWQgZm9yIGV4ZWN1dGlvbi4gQmVjYXVzZSB0aGUgc3RhdGVzIG9mIHRhc2tzIGFuZAorICAgICAqIHRocmVhZHMgbWF5IGNoYW5nZSBkeW5hbWljYWxseSBkdXJpbmcgY29tcHV0YXRpb24sIHRoZSByZXR1cm5lZAorICAgICAqIHZhbHVlIGlzIG9ubHkgYW4gYXBwcm94aW1hdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiB0YXNrcworICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFRhc2tDb3VudCgpIHsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBtYWluTG9jayA9IHRoaXMubWFpbkxvY2s7CisgICAgICAgIG1haW5Mb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxvbmcgbiA9IGNvbXBsZXRlZFRhc2tDb3VudDsKKyAgICAgICAgICAgIGZvciAoV29ya2VyIHcgOiB3b3JrZXJzKSB7CisgICAgICAgICAgICAgICAgbiArPSB3LmNvbXBsZXRlZFRhc2tzOworICAgICAgICAgICAgICAgIGlmICh3LmlzTG9ja2VkKCkpCisgICAgICAgICAgICAgICAgICAgICsrbjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuICsgd29ya1F1ZXVlLnNpemUoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1haW5Mb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXBwcm94aW1hdGUgdG90YWwgbnVtYmVyIG9mIHRhc2tzIHRoYXQgaGF2ZQorICAgICAqIGNvbXBsZXRlZCBleGVjdXRpb24uIEJlY2F1c2UgdGhlIHN0YXRlcyBvZiB0YXNrcyBhbmQgdGhyZWFkcworICAgICAqIG1heSBjaGFuZ2UgZHluYW1pY2FsbHkgZHVyaW5nIGNvbXB1dGF0aW9uLCB0aGUgcmV0dXJuZWQgdmFsdWUKKyAgICAgKiBpcyBvbmx5IGFuIGFwcHJveGltYXRpb24sIGJ1dCBvbmUgdGhhdCBkb2VzIG5vdCBldmVyIGRlY3JlYXNlCisgICAgICogYWNyb3NzIHN1Y2Nlc3NpdmUgY2FsbHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgdGFza3MKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRDb21wbGV0ZWRUYXNrQ291bnQoKSB7CisgICAgICAgIGZpbmFsIFJlZW50cmFudExvY2sgbWFpbkxvY2sgPSB0aGlzLm1haW5Mb2NrOworICAgICAgICBtYWluTG9jay5sb2NrKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsb25nIG4gPSBjb21wbGV0ZWRUYXNrQ291bnQ7CisgICAgICAgICAgICBmb3IgKFdvcmtlciB3IDogd29ya2VycykKKyAgICAgICAgICAgICAgICBuICs9IHcuY29tcGxldGVkVGFza3M7CisgICAgICAgICAgICByZXR1cm4gbjsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1haW5Mb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBpZGVudGlmeWluZyB0aGlzIHBvb2wsIGFzIHdlbGwgYXMgaXRzIHN0YXRlLAorICAgICAqIGluY2x1ZGluZyBpbmRpY2F0aW9ucyBvZiBydW4gc3RhdGUgYW5kIGVzdGltYXRlZCB3b3JrZXIgYW5kCisgICAgICogdGFzayBjb3VudHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIGlkZW50aWZ5aW5nIHRoaXMgcG9vbCwgYXMgd2VsbCBhcyBpdHMgc3RhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBsb25nIG5jb21wbGV0ZWQ7CisgICAgICAgIGludCBud29ya2VycywgbmFjdGl2ZTsKKyAgICAgICAgZmluYWwgUmVlbnRyYW50TG9jayBtYWluTG9jayA9IHRoaXMubWFpbkxvY2s7CisgICAgICAgIG1haW5Mb2NrLmxvY2soKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5jb21wbGV0ZWQgPSBjb21wbGV0ZWRUYXNrQ291bnQ7CisgICAgICAgICAgICBuYWN0aXZlID0gMDsKKyAgICAgICAgICAgIG53b3JrZXJzID0gd29ya2Vycy5zaXplKCk7CisgICAgICAgICAgICBmb3IgKFdvcmtlciB3IDogd29ya2VycykgeworICAgICAgICAgICAgICAgIG5jb21wbGV0ZWQgKz0gdy5jb21wbGV0ZWRUYXNrczsKKyAgICAgICAgICAgICAgICBpZiAody5pc0xvY2tlZCgpKQorICAgICAgICAgICAgICAgICAgICArK25hY3RpdmU7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYWluTG9jay51bmxvY2soKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgYyA9IGN0bC5nZXQoKTsKKyAgICAgICAgU3RyaW5nIHJzID0gKHJ1blN0YXRlTGVzc1RoYW4oYywgU0hVVERPV04pID8gIlJ1bm5pbmciIDoKKyAgICAgICAgICAgICAgICAgICAgIChydW5TdGF0ZUF0TGVhc3QoYywgVEVSTUlOQVRFRCkgPyAiVGVybWluYXRlZCIgOgorICAgICAgICAgICAgICAgICAgICAgICJTaHV0dGluZyBkb3duIikpOworICAgICAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKSArCisgICAgICAgICAgICAiWyIgKyBycyArCisgICAgICAgICAgICAiLCBwb29sIHNpemUgPSAiICsgbndvcmtlcnMgKworICAgICAgICAgICAgIiwgYWN0aXZlIHRocmVhZHMgPSAiICsgbmFjdGl2ZSArCisgICAgICAgICAgICAiLCBxdWV1ZWQgdGFza3MgPSAiICsgd29ya1F1ZXVlLnNpemUoKSArCisgICAgICAgICAgICAiLCBjb21wbGV0ZWQgdGFza3MgPSAiICsgbmNvbXBsZXRlZCArCisgICAgICAgICAgICAiXSI7CisgICAgfQorCisgICAgLyogRXh0ZW5zaW9uIGhvb2tzICovCisKKyAgICAvKioKKyAgICAgKiBNZXRob2QgaW52b2tlZCBwcmlvciB0byBleGVjdXRpbmcgdGhlIGdpdmVuIFJ1bm5hYmxlIGluIHRoZQorICAgICAqIGdpdmVuIHRocmVhZC4gIFRoaXMgbWV0aG9kIGlzIGludm9rZWQgYnkgdGhyZWFkIHtAY29kZSB0fSB0aGF0CisgICAgICogd2lsbCBleGVjdXRlIHRhc2sge0Bjb2RlIHJ9LCBhbmQgbWF5IGJlIHVzZWQgdG8gcmUtaW5pdGlhbGl6ZQorICAgICAqIFRocmVhZExvY2Fscywgb3IgdG8gcGVyZm9ybSBsb2dnaW5nLgorICAgICAqCisgICAgICogPHA+VGhpcyBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdGhpbmcsIGJ1dCBtYXkgYmUgY3VzdG9taXplZCBpbgorICAgICAqIHN1YmNsYXNzZXMuIE5vdGU6IFRvIHByb3Blcmx5IG5lc3QgbXVsdGlwbGUgb3ZlcnJpZGluZ3MsIHN1YmNsYXNzZXMKKyAgICAgKiBzaG91bGQgZ2VuZXJhbGx5IGludm9rZSB7QGNvZGUgc3VwZXIuYmVmb3JlRXhlY3V0ZX0gYXQgdGhlIGVuZCBvZgorICAgICAqIHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIHQgdGhlIHRocmVhZCB0aGF0IHdpbGwgcnVuIHRhc2sge0Bjb2RlIHJ9CisgICAgICogQHBhcmFtIHIgdGhlIHRhc2sgdGhhdCB3aWxsIGJlIGV4ZWN1dGVkCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgYmVmb3JlRXhlY3V0ZShUaHJlYWQgdCwgUnVubmFibGUgcikgeyB9CisKKyAgICAvKioKKyAgICAgKiBNZXRob2QgaW52b2tlZCB1cG9uIGNvbXBsZXRpb24gb2YgZXhlY3V0aW9uIG9mIHRoZSBnaXZlbiBSdW5uYWJsZS4KKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBpbnZva2VkIGJ5IHRoZSB0aHJlYWQgdGhhdCBleGVjdXRlZCB0aGUgdGFzay4gSWYKKyAgICAgKiBub24tbnVsbCwgdGhlIFRocm93YWJsZSBpcyB0aGUgdW5jYXVnaHQge0Bjb2RlIFJ1bnRpbWVFeGNlcHRpb259CisgICAgICogb3Ige0Bjb2RlIEVycm9yfSB0aGF0IGNhdXNlZCBleGVjdXRpb24gdG8gdGVybWluYXRlIGFicnVwdGx5LgorICAgICAqCisgICAgICogPHA+VGhpcyBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdGhpbmcsIGJ1dCBtYXkgYmUgY3VzdG9taXplZCBpbgorICAgICAqIHN1YmNsYXNzZXMuIE5vdGU6IFRvIHByb3Blcmx5IG5lc3QgbXVsdGlwbGUgb3ZlcnJpZGluZ3MsIHN1YmNsYXNzZXMKKyAgICAgKiBzaG91bGQgZ2VuZXJhbGx5IGludm9rZSB7QGNvZGUgc3VwZXIuYWZ0ZXJFeGVjdXRlfSBhdCB0aGUKKyAgICAgKiBiZWdpbm5pbmcgb2YgdGhpcyBtZXRob2QuCisgICAgICoKKyAgICAgKiA8cD48Yj5Ob3RlOjwvYj4gV2hlbiBhY3Rpb25zIGFyZSBlbmNsb3NlZCBpbiB0YXNrcyAoc3VjaCBhcworICAgICAqIHtAbGluayBGdXR1cmVUYXNrfSkgZWl0aGVyIGV4cGxpY2l0bHkgb3IgdmlhIG1ldGhvZHMgc3VjaCBhcworICAgICAqIHtAY29kZSBzdWJtaXR9LCB0aGVzZSB0YXNrIG9iamVjdHMgY2F0Y2ggYW5kIG1haW50YWluCisgICAgICogY29tcHV0YXRpb25hbCBleGNlcHRpb25zLCBhbmQgc28gdGhleSBkbyBub3QgY2F1c2UgYWJydXB0CisgICAgICogdGVybWluYXRpb24sIGFuZCB0aGUgaW50ZXJuYWwgZXhjZXB0aW9ucyBhcmUgPGVtPm5vdDwvZW0+CisgICAgICogcGFzc2VkIHRvIHRoaXMgbWV0aG9kLiBJZiB5b3Ugd291bGQgbGlrZSB0byB0cmFwIGJvdGgga2luZHMgb2YKKyAgICAgKiBmYWlsdXJlcyBpbiB0aGlzIG1ldGhvZCwgeW91IGNhbiBmdXJ0aGVyIHByb2JlIGZvciBzdWNoIGNhc2VzLAorICAgICAqIGFzIGluIHRoaXMgc2FtcGxlIHN1YmNsYXNzIHRoYXQgcHJpbnRzIGVpdGhlciB0aGUgZGlyZWN0IGNhdXNlCisgICAgICogb3IgdGhlIHVuZGVybHlpbmcgZXhjZXB0aW9uIGlmIGEgdGFzayBoYXMgYmVlbiBhYm9ydGVkOgorICAgICAqCisgICAgICogIDxwcmU+IHtAY29kZQorICAgICAqIGNsYXNzIEV4dGVuZGVkRXhlY3V0b3IgZXh0ZW5kcyBUaHJlYWRQb29sRXhlY3V0b3IgeworICAgICAqICAgLy8gLi4uCisgICAgICogICBwcm90ZWN0ZWQgdm9pZCBhZnRlckV4ZWN1dGUoUnVubmFibGUgciwgVGhyb3dhYmxlIHQpIHsKKyAgICAgKiAgICAgc3VwZXIuYWZ0ZXJFeGVjdXRlKHIsIHQpOworICAgICAqICAgICBpZiAodCA9PSBudWxsICYmIHIgaW5zdGFuY2VvZiBGdXR1cmU8Pz4pIHsKKyAgICAgKiAgICAgICB0cnkgeworICAgICAqICAgICAgICAgT2JqZWN0IHJlc3VsdCA9ICgoRnV0dXJlPD8+KSByKS5nZXQoKTsKKyAgICAgKiAgICAgICB9IGNhdGNoIChDYW5jZWxsYXRpb25FeGNlcHRpb24gY2UpIHsKKyAgICAgKiAgICAgICAgICAgdCA9IGNlOworICAgICAqICAgICAgIH0gY2F0Y2ggKEV4ZWN1dGlvbkV4Y2VwdGlvbiBlZSkgeworICAgICAqICAgICAgICAgICB0ID0gZWUuZ2V0Q2F1c2UoKTsKKyAgICAgKiAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSkgeworICAgICAqICAgICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLmludGVycnVwdCgpOyAvLyBpZ25vcmUvcmVzZXQKKyAgICAgKiAgICAgICB9CisgICAgICogICAgIH0KKyAgICAgKiAgICAgaWYgKHQgIT0gbnVsbCkKKyAgICAgKiAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4odCk7CisgICAgICogICB9CisgICAgICogfX08L3ByZT4KKyAgICAgKgorICAgICAqIEBwYXJhbSByIHRoZSBydW5uYWJsZSB0aGF0IGhhcyBjb21wbGV0ZWQKKyAgICAgKiBAcGFyYW0gdCB0aGUgZXhjZXB0aW9uIHRoYXQgY2F1c2VkIHRlcm1pbmF0aW9uLCBvciBudWxsIGlmCisgICAgICogZXhlY3V0aW9uIGNvbXBsZXRlZCBub3JtYWxseQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGFmdGVyRXhlY3V0ZShSdW5uYWJsZSByLCBUaHJvd2FibGUgdCkgeyB9CisKKyAgICAvKioKKyAgICAgKiBNZXRob2QgaW52b2tlZCB3aGVuIHRoZSBFeGVjdXRvciBoYXMgdGVybWluYXRlZC4gIERlZmF1bHQKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdGhpbmcuIE5vdGU6IFRvIHByb3Blcmx5IG5lc3QgbXVsdGlwbGUKKyAgICAgKiBvdmVycmlkaW5ncywgc3ViY2xhc3NlcyBzaG91bGQgZ2VuZXJhbGx5IGludm9rZQorICAgICAqIHtAY29kZSBzdXBlci50ZXJtaW5hdGVkfSB3aXRoaW4gdGhpcyBtZXRob2QuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVybWluYXRlZCgpIHsgfQorCisgICAgLyogUHJlZGVmaW5lZCBSZWplY3RlZEV4ZWN1dGlvbkhhbmRsZXJzICovCisKKyAgICAvKioKKyAgICAgKiBBIGhhbmRsZXIgZm9yIHJlamVjdGVkIHRhc2tzIHRoYXQgcnVucyB0aGUgcmVqZWN0ZWQgdGFzaworICAgICAqIGRpcmVjdGx5IGluIHRoZSBjYWxsaW5nIHRocmVhZCBvZiB0aGUge0Bjb2RlIGV4ZWN1dGV9IG1ldGhvZCwKKyAgICAgKiB1bmxlc3MgdGhlIGV4ZWN1dG9yIGhhcyBiZWVuIHNodXQgZG93biwgaW4gd2hpY2ggY2FzZSB0aGUgdGFzaworICAgICAqIGlzIGRpc2NhcmRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIENhbGxlclJ1bnNQb2xpY3kgaW1wbGVtZW50cyBSZWplY3RlZEV4ZWN1dGlvbkhhbmRsZXIgeworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBhIHtAY29kZSBDYWxsZXJSdW5zUG9saWN5fS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBDYWxsZXJSdW5zUG9saWN5KCkgeyB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEV4ZWN1dGVzIHRhc2sgciBpbiB0aGUgY2FsbGVyJ3MgdGhyZWFkLCB1bmxlc3MgdGhlIGV4ZWN1dG9yCisgICAgICAgICAqIGhhcyBiZWVuIHNodXQgZG93biwgaW4gd2hpY2ggY2FzZSB0aGUgdGFzayBpcyBkaXNjYXJkZWQuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSByIHRoZSBydW5uYWJsZSB0YXNrIHJlcXVlc3RlZCB0byBiZSBleGVjdXRlZAorICAgICAgICAgKiBAcGFyYW0gZSB0aGUgZXhlY3V0b3IgYXR0ZW1wdGluZyB0byBleGVjdXRlIHRoaXMgdGFzaworICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHZvaWQgcmVqZWN0ZWRFeGVjdXRpb24oUnVubmFibGUgciwgVGhyZWFkUG9vbEV4ZWN1dG9yIGUpIHsKKyAgICAgICAgICAgIGlmICghZS5pc1NodXRkb3duKCkpIHsKKyAgICAgICAgICAgICAgICByLnJ1bigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBoYW5kbGVyIGZvciByZWplY3RlZCB0YXNrcyB0aGF0IHRocm93cyBhCisgICAgICoge0Bjb2RlIFJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEFib3J0UG9saWN5IGltcGxlbWVudHMgUmVqZWN0ZWRFeGVjdXRpb25IYW5kbGVyIHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIENyZWF0ZXMgYW4ge0Bjb2RlIEFib3J0UG9saWN5fS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBBYm9ydFBvbGljeSgpIHsgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBBbHdheXMgdGhyb3dzIFJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9uLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gciB0aGUgcnVubmFibGUgdGFzayByZXF1ZXN0ZWQgdG8gYmUgZXhlY3V0ZWQKKyAgICAgICAgICogQHBhcmFtIGUgdGhlIGV4ZWN1dG9yIGF0dGVtcHRpbmcgdG8gZXhlY3V0ZSB0aGlzIHRhc2sKKyAgICAgICAgICogQHRocm93cyBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbiBhbHdheXMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCByZWplY3RlZEV4ZWN1dGlvbihSdW5uYWJsZSByLCBUaHJlYWRQb29sRXhlY3V0b3IgZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9uKCJUYXNrICIgKyByLnRvU3RyaW5nKCkgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgcmVqZWN0ZWQgZnJvbSAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBoYW5kbGVyIGZvciByZWplY3RlZCB0YXNrcyB0aGF0IHNpbGVudGx5IGRpc2NhcmRzIHRoZQorICAgICAqIHJlamVjdGVkIHRhc2suCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBEaXNjYXJkUG9saWN5IGltcGxlbWVudHMgUmVqZWN0ZWRFeGVjdXRpb25IYW5kbGVyIHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgRGlzY2FyZFBvbGljeX0uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgRGlzY2FyZFBvbGljeSgpIHsgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBEb2VzIG5vdGhpbmcsIHdoaWNoIGhhcyB0aGUgZWZmZWN0IG9mIGRpc2NhcmRpbmcgdGFzayByLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gciB0aGUgcnVubmFibGUgdGFzayByZXF1ZXN0ZWQgdG8gYmUgZXhlY3V0ZWQKKyAgICAgICAgICogQHBhcmFtIGUgdGhlIGV4ZWN1dG9yIGF0dGVtcHRpbmcgdG8gZXhlY3V0ZSB0aGlzIHRhc2sKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyB2b2lkIHJlamVjdGVkRXhlY3V0aW9uKFJ1bm5hYmxlIHIsIFRocmVhZFBvb2xFeGVjdXRvciBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBIGhhbmRsZXIgZm9yIHJlamVjdGVkIHRhc2tzIHRoYXQgZGlzY2FyZHMgdGhlIG9sZGVzdCB1bmhhbmRsZWQKKyAgICAgKiByZXF1ZXN0IGFuZCB0aGVuIHJldHJpZXMge0Bjb2RlIGV4ZWN1dGV9LCB1bmxlc3MgdGhlIGV4ZWN1dG9yCisgICAgICogaXMgc2h1dCBkb3duLCBpbiB3aGljaCBjYXNlIHRoZSB0YXNrIGlzIGRpc2NhcmRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIERpc2NhcmRPbGRlc3RQb2xpY3kgaW1wbGVtZW50cyBSZWplY3RlZEV4ZWN1dGlvbkhhbmRsZXIgeworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBhIHtAY29kZSBEaXNjYXJkT2xkZXN0UG9saWN5fSBmb3IgdGhlIGdpdmVuIGV4ZWN1dG9yLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIERpc2NhcmRPbGRlc3RQb2xpY3koKSB7IH0KKworICAgICAgICAvKioKKyAgICAgICAgICogT2J0YWlucyBhbmQgaWdub3JlcyB0aGUgbmV4dCB0YXNrIHRoYXQgdGhlIGV4ZWN1dG9yCisgICAgICAgICAqIHdvdWxkIG90aGVyd2lzZSBleGVjdXRlLCBpZiBvbmUgaXMgaW1tZWRpYXRlbHkgYXZhaWxhYmxlLAorICAgICAgICAgKiBhbmQgdGhlbiByZXRyaWVzIGV4ZWN1dGlvbiBvZiB0YXNrIHIsIHVubGVzcyB0aGUgZXhlY3V0b3IKKyAgICAgICAgICogaXMgc2h1dCBkb3duLCBpbiB3aGljaCBjYXNlIHRhc2sgciBpcyBpbnN0ZWFkIGRpc2NhcmRlZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIHIgdGhlIHJ1bm5hYmxlIHRhc2sgcmVxdWVzdGVkIHRvIGJlIGV4ZWN1dGVkCisgICAgICAgICAqIEBwYXJhbSBlIHRoZSBleGVjdXRvciBhdHRlbXB0aW5nIHRvIGV4ZWN1dGUgdGhpcyB0YXNrCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCByZWplY3RlZEV4ZWN1dGlvbihSdW5uYWJsZSByLCBUaHJlYWRQb29sRXhlY3V0b3IgZSkgeworICAgICAgICAgICAgaWYgKCFlLmlzU2h1dGRvd24oKSkgeworICAgICAgICAgICAgICAgIGUuZ2V0UXVldWUoKS5wb2xsKCk7CisgICAgICAgICAgICAgICAgZS5leGVjdXRlKHIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L1RpbWVVbml0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvVGltZVVuaXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMmUzMDYwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L1RpbWVVbml0LmphdmEKQEAgLTAsMCArMSwzMzUgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudDsKKworLyoqCisgKiBBIDx0dD5UaW1lVW5pdDwvdHQ+IHJlcHJlc2VudHMgdGltZSBkdXJhdGlvbnMgYXQgYSBnaXZlbiB1bml0IG9mCisgKiBncmFudWxhcml0eSBhbmQgcHJvdmlkZXMgdXRpbGl0eSBtZXRob2RzIHRvIGNvbnZlcnQgYWNyb3NzIHVuaXRzLAorICogYW5kIHRvIHBlcmZvcm0gdGltaW5nIGFuZCBkZWxheSBvcGVyYXRpb25zIGluIHRoZXNlIHVuaXRzLiAgQQorICogPHR0PlRpbWVVbml0PC90dD4gZG9lcyBub3QgbWFpbnRhaW4gdGltZSBpbmZvcm1hdGlvbiwgYnV0IG9ubHkKKyAqIGhlbHBzIG9yZ2FuaXplIGFuZCB1c2UgdGltZSByZXByZXNlbnRhdGlvbnMgdGhhdCBtYXkgYmUgbWFpbnRhaW5lZAorICogc2VwYXJhdGVseSBhY3Jvc3MgdmFyaW91cyBjb250ZXh0cy4gIEEgbmFub3NlY29uZCBpcyBkZWZpbmVkIGFzIG9uZQorICogdGhvdXNhbmR0aCBvZiBhIG1pY3Jvc2Vjb25kLCBhIG1pY3Jvc2Vjb25kIGFzIG9uZSB0aG91c2FuZHRoIG9mIGEKKyAqIG1pbGxpc2Vjb25kLCBhIG1pbGxpc2Vjb25kIGFzIG9uZSB0aG91c2FuZHRoIG9mIGEgc2Vjb25kLCBhIG1pbnV0ZQorICogYXMgc2l4dHkgc2Vjb25kcywgYW4gaG91ciBhcyBzaXh0eSBtaW51dGVzLCBhbmQgYSBkYXkgYXMgdHdlbnR5IGZvdXIKKyAqIGhvdXJzLgorICoKKyAqIDxwPkEgPHR0PlRpbWVVbml0PC90dD4gaXMgbWFpbmx5IHVzZWQgdG8gaW5mb3JtIHRpbWUtYmFzZWQgbWV0aG9kcworICogaG93IGEgZ2l2ZW4gdGltaW5nIHBhcmFtZXRlciBzaG91bGQgYmUgaW50ZXJwcmV0ZWQuIEZvciBleGFtcGxlLAorICogdGhlIGZvbGxvd2luZyBjb2RlIHdpbGwgdGltZW91dCBpbiA1MCBtaWxsaXNlY29uZHMgaWYgdGhlIHtAbGluaworICogamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3MuTG9jayBsb2NrfSBpcyBub3QgYXZhaWxhYmxlOgorICoKKyAqIDxwcmU+ICBMb2NrIGxvY2sgPSAuLi47CisgKiAgaWYgKGxvY2sudHJ5TG9jayg1MEwsIFRpbWVVbml0Lk1JTExJU0VDT05EUykpIC4uLgorICogPC9wcmU+CisgKiB3aGlsZSB0aGlzIGNvZGUgd2lsbCB0aW1lb3V0IGluIDUwIHNlY29uZHM6CisgKiA8cHJlPgorICogIExvY2sgbG9jayA9IC4uLjsKKyAqICBpZiAobG9jay50cnlMb2NrKDUwTCwgVGltZVVuaXQuU0VDT05EUykpIC4uLgorICogPC9wcmU+CisgKgorICogTm90ZSBob3dldmVyLCB0aGF0IHRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IGEgcGFydGljdWxhciB0aW1lb3V0CisgKiBpbXBsZW1lbnRhdGlvbiB3aWxsIGJlIGFibGUgdG8gbm90aWNlIHRoZSBwYXNzYWdlIG9mIHRpbWUgYXQgdGhlCisgKiBzYW1lIGdyYW51bGFyaXR5IGFzIHRoZSBnaXZlbiA8dHQ+VGltZVVuaXQ8L3R0Pi4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKi8KK3B1YmxpYyBlbnVtIFRpbWVVbml0IHsKKyAgICBOQU5PU0VDT05EUyB7CisgICAgICAgIHB1YmxpYyBsb25nIHRvTmFub3MobG9uZyBkKSAgIHsgcmV0dXJuIGQ7IH0KKyAgICAgICAgcHVibGljIGxvbmcgdG9NaWNyb3MobG9uZyBkKSAgeyByZXR1cm4gZC8oQzEvQzApOyB9CisgICAgICAgIHB1YmxpYyBsb25nIHRvTWlsbGlzKGxvbmcgZCkgIHsgcmV0dXJuIGQvKEMyL0MwKTsgfQorICAgICAgICBwdWJsaWMgbG9uZyB0b1NlY29uZHMobG9uZyBkKSB7IHJldHVybiBkLyhDMy9DMCk7IH0KKyAgICAgICAgcHVibGljIGxvbmcgdG9NaW51dGVzKGxvbmcgZCkgeyByZXR1cm4gZC8oQzQvQzApOyB9CisgICAgICAgIHB1YmxpYyBsb25nIHRvSG91cnMobG9uZyBkKSAgIHsgcmV0dXJuIGQvKEM1L0MwKTsgfQorICAgICAgICBwdWJsaWMgbG9uZyB0b0RheXMobG9uZyBkKSAgICB7IHJldHVybiBkLyhDNi9DMCk7IH0KKyAgICAgICAgcHVibGljIGxvbmcgY29udmVydChsb25nIGQsIFRpbWVVbml0IHUpIHsgcmV0dXJuIHUudG9OYW5vcyhkKTsgfQorICAgICAgICBpbnQgZXhjZXNzTmFub3MobG9uZyBkLCBsb25nIG0pIHsgcmV0dXJuIChpbnQpKGQgLSAobSpDMikpOyB9CisgICAgfSwKKyAgICBNSUNST1NFQ09ORFMgeworICAgICAgICBwdWJsaWMgbG9uZyB0b05hbm9zKGxvbmcgZCkgICB7IHJldHVybiB4KGQsIEMxL0MwLCBNQVgvKEMxL0MwKSk7IH0KKyAgICAgICAgcHVibGljIGxvbmcgdG9NaWNyb3MobG9uZyBkKSAgeyByZXR1cm4gZDsgfQorICAgICAgICBwdWJsaWMgbG9uZyB0b01pbGxpcyhsb25nIGQpICB7IHJldHVybiBkLyhDMi9DMSk7IH0KKyAgICAgICAgcHVibGljIGxvbmcgdG9TZWNvbmRzKGxvbmcgZCkgeyByZXR1cm4gZC8oQzMvQzEpOyB9CisgICAgICAgIHB1YmxpYyBsb25nIHRvTWludXRlcyhsb25nIGQpIHsgcmV0dXJuIGQvKEM0L0MxKTsgfQorICAgICAgICBwdWJsaWMgbG9uZyB0b0hvdXJzKGxvbmcgZCkgICB7IHJldHVybiBkLyhDNS9DMSk7IH0KKyAgICAgICAgcHVibGljIGxvbmcgdG9EYXlzKGxvbmcgZCkgICAgeyByZXR1cm4gZC8oQzYvQzEpOyB9CisgICAgICAgIHB1YmxpYyBsb25nIGNvbnZlcnQobG9uZyBkLCBUaW1lVW5pdCB1KSB7IHJldHVybiB1LnRvTWljcm9zKGQpOyB9CisgICAgICAgIGludCBleGNlc3NOYW5vcyhsb25nIGQsIGxvbmcgbSkgeyByZXR1cm4gKGludCkoKGQqQzEpIC0gKG0qQzIpKTsgfQorICAgIH0sCisgICAgTUlMTElTRUNPTkRTIHsKKyAgICAgICAgcHVibGljIGxvbmcgdG9OYW5vcyhsb25nIGQpICAgeyByZXR1cm4geChkLCBDMi9DMCwgTUFYLyhDMi9DMCkpOyB9CisgICAgICAgIHB1YmxpYyBsb25nIHRvTWljcm9zKGxvbmcgZCkgIHsgcmV0dXJuIHgoZCwgQzIvQzEsIE1BWC8oQzIvQzEpKTsgfQorICAgICAgICBwdWJsaWMgbG9uZyB0b01pbGxpcyhsb25nIGQpICB7IHJldHVybiBkOyB9CisgICAgICAgIHB1YmxpYyBsb25nIHRvU2Vjb25kcyhsb25nIGQpIHsgcmV0dXJuIGQvKEMzL0MyKTsgfQorICAgICAgICBwdWJsaWMgbG9uZyB0b01pbnV0ZXMobG9uZyBkKSB7IHJldHVybiBkLyhDNC9DMik7IH0KKyAgICAgICAgcHVibGljIGxvbmcgdG9Ib3Vycyhsb25nIGQpICAgeyByZXR1cm4gZC8oQzUvQzIpOyB9CisgICAgICAgIHB1YmxpYyBsb25nIHRvRGF5cyhsb25nIGQpICAgIHsgcmV0dXJuIGQvKEM2L0MyKTsgfQorICAgICAgICBwdWJsaWMgbG9uZyBjb252ZXJ0KGxvbmcgZCwgVGltZVVuaXQgdSkgeyByZXR1cm4gdS50b01pbGxpcyhkKTsgfQorICAgICAgICBpbnQgZXhjZXNzTmFub3MobG9uZyBkLCBsb25nIG0pIHsgcmV0dXJuIDA7IH0KKyAgICB9LAorICAgIFNFQ09ORFMgeworICAgICAgICBwdWJsaWMgbG9uZyB0b05hbm9zKGxvbmcgZCkgICB7IHJldHVybiB4KGQsIEMzL0MwLCBNQVgvKEMzL0MwKSk7IH0KKyAgICAgICAgcHVibGljIGxvbmcgdG9NaWNyb3MobG9uZyBkKSAgeyByZXR1cm4geChkLCBDMy9DMSwgTUFYLyhDMy9DMSkpOyB9CisgICAgICAgIHB1YmxpYyBsb25nIHRvTWlsbGlzKGxvbmcgZCkgIHsgcmV0dXJuIHgoZCwgQzMvQzIsIE1BWC8oQzMvQzIpKTsgfQorICAgICAgICBwdWJsaWMgbG9uZyB0b1NlY29uZHMobG9uZyBkKSB7IHJldHVybiBkOyB9CisgICAgICAgIHB1YmxpYyBsb25nIHRvTWludXRlcyhsb25nIGQpIHsgcmV0dXJuIGQvKEM0L0MzKTsgfQorICAgICAgICBwdWJsaWMgbG9uZyB0b0hvdXJzKGxvbmcgZCkgICB7IHJldHVybiBkLyhDNS9DMyk7IH0KKyAgICAgICAgcHVibGljIGxvbmcgdG9EYXlzKGxvbmcgZCkgICAgeyByZXR1cm4gZC8oQzYvQzMpOyB9CisgICAgICAgIHB1YmxpYyBsb25nIGNvbnZlcnQobG9uZyBkLCBUaW1lVW5pdCB1KSB7IHJldHVybiB1LnRvU2Vjb25kcyhkKTsgfQorICAgICAgICBpbnQgZXhjZXNzTmFub3MobG9uZyBkLCBsb25nIG0pIHsgcmV0dXJuIDA7IH0KKyAgICB9LAorICAgIE1JTlVURVMgeworICAgICAgICBwdWJsaWMgbG9uZyB0b05hbm9zKGxvbmcgZCkgICB7IHJldHVybiB4KGQsIEM0L0MwLCBNQVgvKEM0L0MwKSk7IH0KKyAgICAgICAgcHVibGljIGxvbmcgdG9NaWNyb3MobG9uZyBkKSAgeyByZXR1cm4geChkLCBDNC9DMSwgTUFYLyhDNC9DMSkpOyB9CisgICAgICAgIHB1YmxpYyBsb25nIHRvTWlsbGlzKGxvbmcgZCkgIHsgcmV0dXJuIHgoZCwgQzQvQzIsIE1BWC8oQzQvQzIpKTsgfQorICAgICAgICBwdWJsaWMgbG9uZyB0b1NlY29uZHMobG9uZyBkKSB7IHJldHVybiB4KGQsIEM0L0MzLCBNQVgvKEM0L0MzKSk7IH0KKyAgICAgICAgcHVibGljIGxvbmcgdG9NaW51dGVzKGxvbmcgZCkgeyByZXR1cm4gZDsgfQorICAgICAgICBwdWJsaWMgbG9uZyB0b0hvdXJzKGxvbmcgZCkgICB7IHJldHVybiBkLyhDNS9DNCk7IH0KKyAgICAgICAgcHVibGljIGxvbmcgdG9EYXlzKGxvbmcgZCkgICAgeyByZXR1cm4gZC8oQzYvQzQpOyB9CisgICAgICAgIHB1YmxpYyBsb25nIGNvbnZlcnQobG9uZyBkLCBUaW1lVW5pdCB1KSB7IHJldHVybiB1LnRvTWludXRlcyhkKTsgfQorICAgICAgICBpbnQgZXhjZXNzTmFub3MobG9uZyBkLCBsb25nIG0pIHsgcmV0dXJuIDA7IH0KKyAgICB9LAorICAgIEhPVVJTIHsKKyAgICAgICAgcHVibGljIGxvbmcgdG9OYW5vcyhsb25nIGQpICAgeyByZXR1cm4geChkLCBDNS9DMCwgTUFYLyhDNS9DMCkpOyB9CisgICAgICAgIHB1YmxpYyBsb25nIHRvTWljcm9zKGxvbmcgZCkgIHsgcmV0dXJuIHgoZCwgQzUvQzEsIE1BWC8oQzUvQzEpKTsgfQorICAgICAgICBwdWJsaWMgbG9uZyB0b01pbGxpcyhsb25nIGQpICB7IHJldHVybiB4KGQsIEM1L0MyLCBNQVgvKEM1L0MyKSk7IH0KKyAgICAgICAgcHVibGljIGxvbmcgdG9TZWNvbmRzKGxvbmcgZCkgeyByZXR1cm4geChkLCBDNS9DMywgTUFYLyhDNS9DMykpOyB9CisgICAgICAgIHB1YmxpYyBsb25nIHRvTWludXRlcyhsb25nIGQpIHsgcmV0dXJuIHgoZCwgQzUvQzQsIE1BWC8oQzUvQzQpKTsgfQorICAgICAgICBwdWJsaWMgbG9uZyB0b0hvdXJzKGxvbmcgZCkgICB7IHJldHVybiBkOyB9CisgICAgICAgIHB1YmxpYyBsb25nIHRvRGF5cyhsb25nIGQpICAgIHsgcmV0dXJuIGQvKEM2L0M1KTsgfQorICAgICAgICBwdWJsaWMgbG9uZyBjb252ZXJ0KGxvbmcgZCwgVGltZVVuaXQgdSkgeyByZXR1cm4gdS50b0hvdXJzKGQpOyB9CisgICAgICAgIGludCBleGNlc3NOYW5vcyhsb25nIGQsIGxvbmcgbSkgeyByZXR1cm4gMDsgfQorICAgIH0sCisgICAgREFZUyB7CisgICAgICAgIHB1YmxpYyBsb25nIHRvTmFub3MobG9uZyBkKSAgIHsgcmV0dXJuIHgoZCwgQzYvQzAsIE1BWC8oQzYvQzApKTsgfQorICAgICAgICBwdWJsaWMgbG9uZyB0b01pY3Jvcyhsb25nIGQpICB7IHJldHVybiB4KGQsIEM2L0MxLCBNQVgvKEM2L0MxKSk7IH0KKyAgICAgICAgcHVibGljIGxvbmcgdG9NaWxsaXMobG9uZyBkKSAgeyByZXR1cm4geChkLCBDNi9DMiwgTUFYLyhDNi9DMikpOyB9CisgICAgICAgIHB1YmxpYyBsb25nIHRvU2Vjb25kcyhsb25nIGQpIHsgcmV0dXJuIHgoZCwgQzYvQzMsIE1BWC8oQzYvQzMpKTsgfQorICAgICAgICBwdWJsaWMgbG9uZyB0b01pbnV0ZXMobG9uZyBkKSB7IHJldHVybiB4KGQsIEM2L0M0LCBNQVgvKEM2L0M0KSk7IH0KKyAgICAgICAgcHVibGljIGxvbmcgdG9Ib3Vycyhsb25nIGQpICAgeyByZXR1cm4geChkLCBDNi9DNSwgTUFYLyhDNi9DNSkpOyB9CisgICAgICAgIHB1YmxpYyBsb25nIHRvRGF5cyhsb25nIGQpICAgIHsgcmV0dXJuIGQ7IH0KKyAgICAgICAgcHVibGljIGxvbmcgY29udmVydChsb25nIGQsIFRpbWVVbml0IHUpIHsgcmV0dXJuIHUudG9EYXlzKGQpOyB9CisgICAgICAgIGludCBleGNlc3NOYW5vcyhsb25nIGQsIGxvbmcgbSkgeyByZXR1cm4gMDsgfQorICAgIH07CisKKyAgICAvLyBIYW5keSBjb25zdGFudHMgZm9yIGNvbnZlcnNpb24gbWV0aG9kcworICAgIHN0YXRpYyBmaW5hbCBsb25nIEMwID0gMUw7CisgICAgc3RhdGljIGZpbmFsIGxvbmcgQzEgPSBDMCAqIDEwMDBMOworICAgIHN0YXRpYyBmaW5hbCBsb25nIEMyID0gQzEgKiAxMDAwTDsKKyAgICBzdGF0aWMgZmluYWwgbG9uZyBDMyA9IEMyICogMTAwMEw7CisgICAgc3RhdGljIGZpbmFsIGxvbmcgQzQgPSBDMyAqIDYwTDsKKyAgICBzdGF0aWMgZmluYWwgbG9uZyBDNSA9IEM0ICogNjBMOworICAgIHN0YXRpYyBmaW5hbCBsb25nIEM2ID0gQzUgKiAyNEw7CisKKyAgICBzdGF0aWMgZmluYWwgbG9uZyBNQVggPSBMb25nLk1BWF9WQUxVRTsKKworICAgIC8qKgorICAgICAqIFNjYWxlIGQgYnkgbSwgY2hlY2tpbmcgZm9yIG92ZXJmbG93LgorICAgICAqIFRoaXMgaGFzIGEgc2hvcnQgbmFtZSB0byBtYWtlIGFib3ZlIGNvZGUgbW9yZSByZWFkYWJsZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgbG9uZyB4KGxvbmcgZCwgbG9uZyBtLCBsb25nIG92ZXIpIHsKKyAgICAgICAgaWYgKGQgPiAgb3ZlcikgcmV0dXJuIExvbmcuTUFYX1ZBTFVFOworICAgICAgICBpZiAoZCA8IC1vdmVyKSByZXR1cm4gTG9uZy5NSU5fVkFMVUU7CisgICAgICAgIHJldHVybiBkICogbTsKKyAgICB9CisKKyAgICAvLyBUbyBtYWludGFpbiBmdWxsIHNpZ25hdHVyZSBjb21wYXRpYmlsaXR5IHdpdGggMS41LCBhbmQgdG8gaW1wcm92ZSB0aGUKKyAgICAvLyBjbGFyaXR5IG9mIHRoZSBnZW5lcmF0ZWQgamF2YWRvYyAoc2VlIDYyODc2Mzk6IEFic3RyYWN0IG1ldGhvZHMgaW4KKyAgICAvLyBlbnVtIGNsYXNzZXMgc2hvdWxkIG5vdCBiZSBsaXN0ZWQgYXMgYWJzdHJhY3QpLCBtZXRob2QgY29udmVydAorICAgIC8vIGV0Yy4gYXJlIG5vdCBkZWNsYXJlZCBhYnN0cmFjdCBidXQgb3RoZXJ3aXNlIGFjdCBhcyBhYnN0cmFjdCBtZXRob2RzLgorCisgICAgLyoqCisgICAgICogQ29udmVydCB0aGUgZ2l2ZW4gdGltZSBkdXJhdGlvbiBpbiB0aGUgZ2l2ZW4gdW5pdCB0byB0aGlzCisgICAgICogdW5pdC4gIENvbnZlcnNpb25zIGZyb20gZmluZXIgdG8gY29hcnNlciBncmFudWxhcml0aWVzCisgICAgICogdHJ1bmNhdGUsIHNvIGxvc2UgcHJlY2lzaW9uLiBGb3IgZXhhbXBsZSBjb252ZXJ0aW5nCisgICAgICogPHR0Pjk5OTwvdHQ+IG1pbGxpc2Vjb25kcyB0byBzZWNvbmRzIHJlc3VsdHMgaW4KKyAgICAgKiA8dHQ+MDwvdHQ+LiBDb252ZXJzaW9ucyBmcm9tIGNvYXJzZXIgdG8gZmluZXIgZ3JhbnVsYXJpdGllcworICAgICAqIHdpdGggYXJndW1lbnRzIHRoYXQgd291bGQgbnVtZXJpY2FsbHkgb3ZlcmZsb3cgc2F0dXJhdGUgdG8KKyAgICAgKiA8dHQ+TG9uZy5NSU5fVkFMVUU8L3R0PiBpZiBuZWdhdGl2ZSBvciA8dHQ+TG9uZy5NQVhfVkFMVUU8L3R0PgorICAgICAqIGlmIHBvc2l0aXZlLgorICAgICAqCisgICAgICogPHA+Rm9yIGV4YW1wbGUsIHRvIGNvbnZlcnQgMTAgbWludXRlcyB0byBtaWxsaXNlY29uZHMsIHVzZToKKyAgICAgKiA8dHQ+VGltZVVuaXQuTUlMTElTRUNPTkRTLmNvbnZlcnQoMTBMLCBUaW1lVW5pdC5NSU5VVEVTKTwvdHQ+CisgICAgICoKKyAgICAgKiBAcGFyYW0gc291cmNlRHVyYXRpb24gdGhlIHRpbWUgZHVyYXRpb24gaW4gdGhlIGdpdmVuIDx0dD5zb3VyY2VVbml0PC90dD4KKyAgICAgKiBAcGFyYW0gc291cmNlVW5pdCB0aGUgdW5pdCBvZiB0aGUgPHR0PnNvdXJjZUR1cmF0aW9uPC90dD4gYXJndW1lbnQKKyAgICAgKiBAcmV0dXJuIHRoZSBjb252ZXJ0ZWQgZHVyYXRpb24gaW4gdGhpcyB1bml0LAorICAgICAqIG9yIDx0dD5Mb25nLk1JTl9WQUxVRTwvdHQ+IGlmIGNvbnZlcnNpb24gd291bGQgbmVnYXRpdmVseQorICAgICAqIG92ZXJmbG93LCBvciA8dHQ+TG9uZy5NQVhfVkFMVUU8L3R0PiBpZiBpdCB3b3VsZCBwb3NpdGl2ZWx5IG92ZXJmbG93LgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGNvbnZlcnQobG9uZyBzb3VyY2VEdXJhdGlvbiwgVGltZVVuaXQgc291cmNlVW5pdCkgeworICAgICAgICB0aHJvdyBuZXcgQWJzdHJhY3RNZXRob2RFcnJvcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8gPHR0Pk5BTk9TRUNPTkRTLmNvbnZlcnQoZHVyYXRpb24sIHRoaXMpPC90dD4uCisgICAgICogQHBhcmFtIGR1cmF0aW9uIHRoZSBkdXJhdGlvbgorICAgICAqIEByZXR1cm4gdGhlIGNvbnZlcnRlZCBkdXJhdGlvbiwKKyAgICAgKiBvciA8dHQ+TG9uZy5NSU5fVkFMVUU8L3R0PiBpZiBjb252ZXJzaW9uIHdvdWxkIG5lZ2F0aXZlbHkKKyAgICAgKiBvdmVyZmxvdywgb3IgPHR0PkxvbmcuTUFYX1ZBTFVFPC90dD4gaWYgaXQgd291bGQgcG9zaXRpdmVseSBvdmVyZmxvdy4KKyAgICAgKiBAc2VlICNjb252ZXJ0CisgICAgICovCisgICAgcHVibGljIGxvbmcgdG9OYW5vcyhsb25nIGR1cmF0aW9uKSB7CisgICAgICAgIHRocm93IG5ldyBBYnN0cmFjdE1ldGhvZEVycm9yKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byA8dHQ+TUlDUk9TRUNPTkRTLmNvbnZlcnQoZHVyYXRpb24sIHRoaXMpPC90dD4uCisgICAgICogQHBhcmFtIGR1cmF0aW9uIHRoZSBkdXJhdGlvbgorICAgICAqIEByZXR1cm4gdGhlIGNvbnZlcnRlZCBkdXJhdGlvbiwKKyAgICAgKiBvciA8dHQ+TG9uZy5NSU5fVkFMVUU8L3R0PiBpZiBjb252ZXJzaW9uIHdvdWxkIG5lZ2F0aXZlbHkKKyAgICAgKiBvdmVyZmxvdywgb3IgPHR0PkxvbmcuTUFYX1ZBTFVFPC90dD4gaWYgaXQgd291bGQgcG9zaXRpdmVseSBvdmVyZmxvdy4KKyAgICAgKiBAc2VlICNjb252ZXJ0CisgICAgICovCisgICAgcHVibGljIGxvbmcgdG9NaWNyb3MobG9uZyBkdXJhdGlvbikgeworICAgICAgICB0aHJvdyBuZXcgQWJzdHJhY3RNZXRob2RFcnJvcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8gPHR0Pk1JTExJU0VDT05EUy5jb252ZXJ0KGR1cmF0aW9uLCB0aGlzKTwvdHQ+LgorICAgICAqIEBwYXJhbSBkdXJhdGlvbiB0aGUgZHVyYXRpb24KKyAgICAgKiBAcmV0dXJuIHRoZSBjb252ZXJ0ZWQgZHVyYXRpb24sCisgICAgICogb3IgPHR0PkxvbmcuTUlOX1ZBTFVFPC90dD4gaWYgY29udmVyc2lvbiB3b3VsZCBuZWdhdGl2ZWx5CisgICAgICogb3ZlcmZsb3csIG9yIDx0dD5Mb25nLk1BWF9WQUxVRTwvdHQ+IGlmIGl0IHdvdWxkIHBvc2l0aXZlbHkgb3ZlcmZsb3cuCisgICAgICogQHNlZSAjY29udmVydAorICAgICAqLworICAgIHB1YmxpYyBsb25nIHRvTWlsbGlzKGxvbmcgZHVyYXRpb24pIHsKKyAgICAgICAgdGhyb3cgbmV3IEFic3RyYWN0TWV0aG9kRXJyb3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVpdmFsZW50IHRvIDx0dD5TRUNPTkRTLmNvbnZlcnQoZHVyYXRpb24sIHRoaXMpPC90dD4uCisgICAgICogQHBhcmFtIGR1cmF0aW9uIHRoZSBkdXJhdGlvbgorICAgICAqIEByZXR1cm4gdGhlIGNvbnZlcnRlZCBkdXJhdGlvbiwKKyAgICAgKiBvciA8dHQ+TG9uZy5NSU5fVkFMVUU8L3R0PiBpZiBjb252ZXJzaW9uIHdvdWxkIG5lZ2F0aXZlbHkKKyAgICAgKiBvdmVyZmxvdywgb3IgPHR0PkxvbmcuTUFYX1ZBTFVFPC90dD4gaWYgaXQgd291bGQgcG9zaXRpdmVseSBvdmVyZmxvdy4KKyAgICAgKiBAc2VlICNjb252ZXJ0CisgICAgICovCisgICAgcHVibGljIGxvbmcgdG9TZWNvbmRzKGxvbmcgZHVyYXRpb24pIHsKKyAgICAgICAgdGhyb3cgbmV3IEFic3RyYWN0TWV0aG9kRXJyb3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVpdmFsZW50IHRvIDx0dD5NSU5VVEVTLmNvbnZlcnQoZHVyYXRpb24sIHRoaXMpPC90dD4uCisgICAgICogQHBhcmFtIGR1cmF0aW9uIHRoZSBkdXJhdGlvbgorICAgICAqIEByZXR1cm4gdGhlIGNvbnZlcnRlZCBkdXJhdGlvbiwKKyAgICAgKiBvciA8dHQ+TG9uZy5NSU5fVkFMVUU8L3R0PiBpZiBjb252ZXJzaW9uIHdvdWxkIG5lZ2F0aXZlbHkKKyAgICAgKiBvdmVyZmxvdywgb3IgPHR0PkxvbmcuTUFYX1ZBTFVFPC90dD4gaWYgaXQgd291bGQgcG9zaXRpdmVseSBvdmVyZmxvdy4KKyAgICAgKiBAc2VlICNjb252ZXJ0CisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBsb25nIHRvTWludXRlcyhsb25nIGR1cmF0aW9uKSB7CisgICAgICAgIHRocm93IG5ldyBBYnN0cmFjdE1ldGhvZEVycm9yKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byA8dHQ+SE9VUlMuY29udmVydChkdXJhdGlvbiwgdGhpcyk8L3R0Pi4KKyAgICAgKiBAcGFyYW0gZHVyYXRpb24gdGhlIGR1cmF0aW9uCisgICAgICogQHJldHVybiB0aGUgY29udmVydGVkIGR1cmF0aW9uLAorICAgICAqIG9yIDx0dD5Mb25nLk1JTl9WQUxVRTwvdHQ+IGlmIGNvbnZlcnNpb24gd291bGQgbmVnYXRpdmVseQorICAgICAqIG92ZXJmbG93LCBvciA8dHQ+TG9uZy5NQVhfVkFMVUU8L3R0PiBpZiBpdCB3b3VsZCBwb3NpdGl2ZWx5IG92ZXJmbG93LgorICAgICAqIEBzZWUgI2NvbnZlcnQKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIGxvbmcgdG9Ib3Vycyhsb25nIGR1cmF0aW9uKSB7CisgICAgICAgIHRocm93IG5ldyBBYnN0cmFjdE1ldGhvZEVycm9yKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byA8dHQ+REFZUy5jb252ZXJ0KGR1cmF0aW9uLCB0aGlzKTwvdHQ+LgorICAgICAqIEBwYXJhbSBkdXJhdGlvbiB0aGUgZHVyYXRpb24KKyAgICAgKiBAcmV0dXJuIHRoZSBjb252ZXJ0ZWQgZHVyYXRpb24KKyAgICAgKiBAc2VlICNjb252ZXJ0CisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBsb25nIHRvRGF5cyhsb25nIGR1cmF0aW9uKSB7CisgICAgICAgIHRocm93IG5ldyBBYnN0cmFjdE1ldGhvZEVycm9yKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXRpbGl0eSB0byBjb21wdXRlIHRoZSBleGNlc3MtbmFub3NlY29uZCBhcmd1bWVudCB0byB3YWl0LAorICAgICAqIHNsZWVwLCBqb2luLgorICAgICAqIEBwYXJhbSBkIHRoZSBkdXJhdGlvbgorICAgICAqIEBwYXJhbSBtIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIG5hbm9zZWNvbmRzCisgICAgICovCisgICAgYWJzdHJhY3QgaW50IGV4Y2Vzc05hbm9zKGxvbmcgZCwgbG9uZyBtKTsKKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgdGltZWQge0BsaW5rIE9iamVjdCN3YWl0KGxvbmcsIGludCkgT2JqZWN0LndhaXR9CisgICAgICogdXNpbmcgdGhpcyB0aW1lIHVuaXQuCisgICAgICogVGhpcyBpcyBhIGNvbnZlbmllbmNlIG1ldGhvZCB0aGF0IGNvbnZlcnRzIHRpbWVvdXQgYXJndW1lbnRzCisgICAgICogaW50byB0aGUgZm9ybSByZXF1aXJlZCBieSB0aGUgPHR0Pk9iamVjdC53YWl0PC90dD4gbWV0aG9kLgorICAgICAqCisgICAgICogPHA+Rm9yIGV4YW1wbGUsIHlvdSBjb3VsZCBpbXBsZW1lbnQgYSBibG9ja2luZyA8dHQ+cG9sbDwvdHQ+CisgICAgICogbWV0aG9kIChzZWUge0BsaW5rIEJsb2NraW5nUXVldWUjcG9sbCBCbG9ja2luZ1F1ZXVlLnBvbGx9KQorICAgICAqIHVzaW5nOgorICAgICAqCisgICAgICogIDxwcmU+IHtAY29kZQorICAgICAqIHB1YmxpYyBzeW5jaHJvbml6ZWQgT2JqZWN0IHBvbGwobG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KQorICAgICAqICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAqICAgd2hpbGUgKGVtcHR5KSB7CisgICAgICogICAgIHVuaXQudGltZWRXYWl0KHRoaXMsIHRpbWVvdXQpOworICAgICAqICAgICAuLi4KKyAgICAgKiAgIH0KKyAgICAgKiB9fTwvcHJlPgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiB0aGUgb2JqZWN0IHRvIHdhaXQgb24KKyAgICAgKiBAcGFyYW0gdGltZW91dCB0aGUgbWF4aW11bSB0aW1lIHRvIHdhaXQuIElmIGxlc3MgdGhhbgorICAgICAqIG9yIGVxdWFsIHRvIHplcm8sIGRvIG5vdCB3YWl0IGF0IGFsbC4KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIGludGVycnVwdGVkIHdoaWxlIHdhaXRpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0aW1lZFdhaXQoT2JqZWN0IG9iaiwgbG9uZyB0aW1lb3V0KQorICAgICAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRpbWVvdXQgPiAwKSB7CisgICAgICAgICAgICBsb25nIG1zID0gdG9NaWxsaXModGltZW91dCk7CisgICAgICAgICAgICBpbnQgbnMgPSBleGNlc3NOYW5vcyh0aW1lb3V0LCBtcyk7CisgICAgICAgICAgICBvYmoud2FpdChtcywgbnMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSB0aW1lZCB7QGxpbmsgVGhyZWFkI2pvaW4obG9uZywgaW50KSBUaHJlYWQuam9pbn0KKyAgICAgKiB1c2luZyB0aGlzIHRpbWUgdW5pdC4KKyAgICAgKiBUaGlzIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kIHRoYXQgY29udmVydHMgdGltZSBhcmd1bWVudHMgaW50byB0aGUKKyAgICAgKiBmb3JtIHJlcXVpcmVkIGJ5IHRoZSA8dHQ+VGhyZWFkLmpvaW48L3R0PiBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhyZWFkIHRoZSB0aHJlYWQgdG8gd2FpdCBmb3IKKyAgICAgKiBAcGFyYW0gdGltZW91dCB0aGUgbWF4aW11bSB0aW1lIHRvIHdhaXQuIElmIGxlc3MgdGhhbgorICAgICAqIG9yIGVxdWFsIHRvIHplcm8sIGRvIG5vdCB3YWl0IGF0IGFsbC4KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIGludGVycnVwdGVkIHdoaWxlIHdhaXRpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0aW1lZEpvaW4oVGhyZWFkIHRocmVhZCwgbG9uZyB0aW1lb3V0KQorICAgICAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRpbWVvdXQgPiAwKSB7CisgICAgICAgICAgICBsb25nIG1zID0gdG9NaWxsaXModGltZW91dCk7CisgICAgICAgICAgICBpbnQgbnMgPSBleGNlc3NOYW5vcyh0aW1lb3V0LCBtcyk7CisgICAgICAgICAgICB0aHJlYWQuam9pbihtcywgbnMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSB7QGxpbmsgVGhyZWFkI3NsZWVwKGxvbmcsIGludCkgVGhyZWFkLnNsZWVwfSB1c2luZworICAgICAqIHRoaXMgdGltZSB1bml0LgorICAgICAqIFRoaXMgaXMgYSBjb252ZW5pZW5jZSBtZXRob2QgdGhhdCBjb252ZXJ0cyB0aW1lIGFyZ3VtZW50cyBpbnRvIHRoZQorICAgICAqIGZvcm0gcmVxdWlyZWQgYnkgdGhlIDx0dD5UaHJlYWQuc2xlZXA8L3R0PiBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGltZW91dCB0aGUgbWluaW11bSB0aW1lIHRvIHNsZWVwLiBJZiBsZXNzIHRoYW4KKyAgICAgKiBvciBlcXVhbCB0byB6ZXJvLCBkbyBub3Qgc2xlZXAgYXQgYWxsLgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgaW50ZXJydXB0ZWQgd2hpbGUgc2xlZXBpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzbGVlcChsb25nIHRpbWVvdXQpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0aW1lb3V0ID4gMCkgeworICAgICAgICAgICAgbG9uZyBtcyA9IHRvTWlsbGlzKHRpbWVvdXQpOworICAgICAgICAgICAgaW50IG5zID0gZXhjZXNzTmFub3ModGltZW91dCwgbXMpOworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKG1zLCBucyk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9UaW1lb3V0RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvVGltZW91dEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhiODRmMjgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvVGltZW91dEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzggQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudDsKKworLyoqCisgKiBFeGNlcHRpb24gdGhyb3duIHdoZW4gYSBibG9ja2luZyBvcGVyYXRpb24gdGltZXMgb3V0LiAgQmxvY2tpbmcKKyAqIG9wZXJhdGlvbnMgZm9yIHdoaWNoIGEgdGltZW91dCBpcyBzcGVjaWZpZWQgbmVlZCBhIG1lYW5zIHRvCisgKiBpbmRpY2F0ZSB0aGF0IHRoZSB0aW1lb3V0IGhhcyBvY2N1cnJlZC4gRm9yIG1hbnkgc3VjaCBvcGVyYXRpb25zIGl0CisgKiBpcyBwb3NzaWJsZSB0byByZXR1cm4gYSB2YWx1ZSB0aGF0IGluZGljYXRlcyB0aW1lb3V0OyB3aGVuIHRoYXQgaXMKKyAqIG5vdCBwb3NzaWJsZSBvciBkZXNpcmFibGUgdGhlbiA8dHQ+VGltZW91dEV4Y2VwdGlvbjwvdHQ+IHNob3VsZCBiZQorICogZGVjbGFyZWQgYW5kIHRocm93bi4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKi8KK3B1YmxpYyBjbGFzcyBUaW1lb3V0RXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxOTAwOTI2Njc3NDkwNjYwNzE0TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSA8dHQ+VGltZW91dEV4Y2VwdGlvbjwvdHQ+IHdpdGggbm8gc3BlY2lmaWVkIGRldGFpbAorICAgICAqIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIFRpbWVvdXRFeGNlcHRpb24oKSB7fQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIDx0dD5UaW1lb3V0RXhjZXB0aW9uPC90dD4gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbAorICAgICAqIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZSB0aGUgZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgVGltZW91dEV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvYXRvbWljL0F0b21pY0Jvb2xlYW4uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvQXRvbWljQm9vbGVhbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM3NzRkMjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvYXRvbWljL0F0b21pY0Jvb2xlYW4uamF2YQpAQCAtMCwwICsxLDEzNSBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYzsKK2ltcG9ydCBzdW4ubWlzYy5VbnNhZmU7CisKKy8qKgorICogQSB7QGNvZGUgYm9vbGVhbn0gdmFsdWUgdGhhdCBtYXkgYmUgdXBkYXRlZCBhdG9taWNhbGx5LiBTZWUgdGhlCisgKiB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljfSBwYWNrYWdlIHNwZWNpZmljYXRpb24gZm9yCisgKiBkZXNjcmlwdGlvbiBvZiB0aGUgcHJvcGVydGllcyBvZiBhdG9taWMgdmFyaWFibGVzLiBBbgorICoge0Bjb2RlIEF0b21pY0Jvb2xlYW59IGlzIHVzZWQgaW4gYXBwbGljYXRpb25zIHN1Y2ggYXMgYXRvbWljYWxseQorICogdXBkYXRlZCBmbGFncywgYW5kIGNhbm5vdCBiZSB1c2VkIGFzIGEgcmVwbGFjZW1lbnQgZm9yIGEKKyAqIHtAbGluayBqYXZhLmxhbmcuQm9vbGVhbn0uCisgKgorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICovCitwdWJsaWMgY2xhc3MgQXRvbWljQm9vbGVhbiBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0NjU0NjcxNDY5Nzk0NTU2OTc5TDsKKyAgICAvLyBzZXR1cCB0byB1c2UgVW5zYWZlLmNvbXBhcmVBbmRTd2FwSW50IGZvciB1cGRhdGVzCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVW5zYWZlIHVuc2FmZSA9IFVuc2FmZUFjY2Vzcy5USEVfT05FOyAvLyBhbmRyb2lkLWNoYW5nZWQKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHZhbHVlT2Zmc2V0OworCisgICAgc3RhdGljIHsKKyAgICAgIHRyeSB7CisgICAgICAgIHZhbHVlT2Zmc2V0ID0gdW5zYWZlLm9iamVjdEZpZWxkT2Zmc2V0CisgICAgICAgICAgICAoQXRvbWljQm9vbGVhbi5jbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJ2YWx1ZSIpKTsKKyAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeyB0aHJvdyBuZXcgRXJyb3IoZXgpOyB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBpbnQgdmFsdWU7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBBdG9taWNCb29sZWFufSB3aXRoIHRoZSBnaXZlbiBpbml0aWFsIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGluaXRpYWxWYWx1ZSB0aGUgaW5pdGlhbCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBBdG9taWNCb29sZWFuKGJvb2xlYW4gaW5pdGlhbFZhbHVlKSB7CisgICAgICAgIHZhbHVlID0gaW5pdGlhbFZhbHVlID8gMSA6IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQXRvbWljQm9vbGVhbn0gd2l0aCBpbml0aWFsIHZhbHVlIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgcHVibGljIEF0b21pY0Jvb2xlYW4oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3VycmVudCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBnZXQoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZSAhPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgc2V0cyB0aGUgdmFsdWUgdG8gdGhlIGdpdmVuIHVwZGF0ZWQgdmFsdWUKKyAgICAgKiBpZiB0aGUgY3VycmVudCB2YWx1ZSB7QGNvZGUgPT19IHRoZSBleHBlY3RlZCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleHBlY3QgdGhlIGV4cGVjdGVkIHZhbHVlCisgICAgICogQHBhcmFtIHVwZGF0ZSB0aGUgbmV3IHZhbHVlCisgICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwuIEZhbHNlIHJldHVybiBpbmRpY2F0ZXMgdGhhdAorICAgICAqIHRoZSBhY3R1YWwgdmFsdWUgd2FzIG5vdCBlcXVhbCB0byB0aGUgZXhwZWN0ZWQgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gY29tcGFyZUFuZFNldChib29sZWFuIGV4cGVjdCwgYm9vbGVhbiB1cGRhdGUpIHsKKyAgICAgICAgaW50IGUgPSBleHBlY3QgPyAxIDogMDsKKyAgICAgICAgaW50IHUgPSB1cGRhdGUgPyAxIDogMDsKKyAgICAgICAgcmV0dXJuIHVuc2FmZS5jb21wYXJlQW5kU3dhcEludCh0aGlzLCB2YWx1ZU9mZnNldCwgZSwgdSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBzZXRzIHRoZSB2YWx1ZSB0byB0aGUgZ2l2ZW4gdXBkYXRlZCB2YWx1ZQorICAgICAqIGlmIHRoZSBjdXJyZW50IHZhbHVlIHtAY29kZSA9PX0gdGhlIGV4cGVjdGVkIHZhbHVlLgorICAgICAqCisgICAgICogPHA+TWF5IDxhIGhyZWY9InBhY2thZ2Utc3VtbWFyeS5odG1sI1NwdXJpb3VzIj5mYWlsIHNwdXJpb3VzbHk8L2E+CisgICAgICogYW5kIGRvZXMgbm90IHByb3ZpZGUgb3JkZXJpbmcgZ3VhcmFudGVlcywgc28gaXMgb25seSByYXJlbHkgYW4KKyAgICAgKiBhcHByb3ByaWF0ZSBhbHRlcm5hdGl2ZSB0byB7QGNvZGUgY29tcGFyZUFuZFNldH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhwZWN0IHRoZSBleHBlY3RlZCB2YWx1ZQorICAgICAqIEBwYXJhbSB1cGRhdGUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHdlYWtDb21wYXJlQW5kU2V0KGJvb2xlYW4gZXhwZWN0LCBib29sZWFuIHVwZGF0ZSkgeworICAgICAgICBpbnQgZSA9IGV4cGVjdCA/IDEgOiAwOworICAgICAgICBpbnQgdSA9IHVwZGF0ZSA/IDEgOiAwOworICAgICAgICByZXR1cm4gdW5zYWZlLmNvbXBhcmVBbmRTd2FwSW50KHRoaXMsIHZhbHVlT2Zmc2V0LCBlLCB1KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVbmNvbmRpdGlvbmFsbHkgc2V0cyB0byB0aGUgZ2l2ZW4gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIG5ldyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldChib29sZWFuIG5ld1ZhbHVlKSB7CisgICAgICAgIHZhbHVlID0gbmV3VmFsdWUgPyAxIDogMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFdmVudHVhbGx5IHNldHMgdG8gdGhlIGdpdmVuIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIG5ld1ZhbHVlIHRoZSBuZXcgdmFsdWUKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgbGF6eVNldChib29sZWFuIG5ld1ZhbHVlKSB7CisgICAgICAgIGludCB2ID0gbmV3VmFsdWUgPyAxIDogMDsKKyAgICAgICAgdW5zYWZlLnB1dE9yZGVyZWRJbnQodGhpcywgdmFsdWVPZmZzZXQsIHYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgc2V0cyB0byB0aGUgZ2l2ZW4gdmFsdWUgYW5kIHJldHVybnMgdGhlIHByZXZpb3VzIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIG5ld1ZhbHVlIHRoZSBuZXcgdmFsdWUKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGdldEFuZFNldChib29sZWFuIG5ld1ZhbHVlKSB7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIGJvb2xlYW4gY3VycmVudCA9IGdldCgpOworICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXQoY3VycmVudCwgbmV3VmFsdWUpKQorICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjdXJyZW50IHZhbHVlLgorICAgICAqIEByZXR1cm4gdGhlIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY3VycmVudCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gQm9vbGVhbi50b1N0cmluZyhnZXQoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvYXRvbWljL0F0b21pY0ludGVnZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvQXRvbWljSW50ZWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE2ZGQ1NjgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvYXRvbWljL0F0b21pY0ludGVnZXIuamF2YQpAQCAtMCwwICsxLDIzNiBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYzsKK2ltcG9ydCBzdW4ubWlzYy5VbnNhZmU7CisKKy8qKgorICogQW4ge0Bjb2RlIGludH0gdmFsdWUgdGhhdCBtYXkgYmUgdXBkYXRlZCBhdG9taWNhbGx5LiAgU2VlIHRoZQorICoge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pY30gcGFja2FnZSBzcGVjaWZpY2F0aW9uIGZvcgorICogZGVzY3JpcHRpb24gb2YgdGhlIHByb3BlcnRpZXMgb2YgYXRvbWljIHZhcmlhYmxlcy4gQW4KKyAqIHtAY29kZSBBdG9taWNJbnRlZ2VyfSBpcyB1c2VkIGluIGFwcGxpY2F0aW9ucyBzdWNoIGFzIGF0b21pY2FsbHkKKyAqIGluY3JlbWVudGVkIGNvdW50ZXJzLCBhbmQgY2Fubm90IGJlIHVzZWQgYXMgYSByZXBsYWNlbWVudCBmb3IgYW4KKyAqIHtAbGluayBqYXZhLmxhbmcuSW50ZWdlcn0uIEhvd2V2ZXIsIHRoaXMgY2xhc3MgZG9lcyBleHRlbmQKKyAqIHtAY29kZSBOdW1iZXJ9IHRvIGFsbG93IHVuaWZvcm0gYWNjZXNzIGJ5IHRvb2xzIGFuZCB1dGlsaXRpZXMgdGhhdAorICogZGVhbCB3aXRoIG51bWVyaWNhbGx5LWJhc2VkIGNsYXNzZXMuCisgKgorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorKi8KK3B1YmxpYyBjbGFzcyBBdG9taWNJbnRlZ2VyIGV4dGVuZHMgTnVtYmVyIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDYyMTQ3OTAyNDM0MTY4MDcwNTBMOworCisgICAgLy8gc2V0dXAgdG8gdXNlIFVuc2FmZS5jb21wYXJlQW5kU3dhcEludCBmb3IgdXBkYXRlcworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFVuc2FmZSB1bnNhZmUgPSBVbnNhZmVBY2Nlc3MuVEhFX09ORTsgLy8gYW5kcm9pZC1jaGFuZ2VkCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyB2YWx1ZU9mZnNldDsKKworICAgIHN0YXRpYyB7CisgICAgICB0cnkgeworICAgICAgICB2YWx1ZU9mZnNldCA9IHVuc2FmZS5vYmplY3RGaWVsZE9mZnNldAorICAgICAgICAgICAgKEF0b21pY0ludGVnZXIuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgidmFsdWUiKSk7CisgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsgdGhyb3cgbmV3IEVycm9yKGV4KTsgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9sYXRpbGUgaW50IHZhbHVlOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBBdG9taWNJbnRlZ2VyIHdpdGggdGhlIGdpdmVuIGluaXRpYWwgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5pdGlhbFZhbHVlIHRoZSBpbml0aWFsIHZhbHVlCisgICAgICovCisgICAgcHVibGljIEF0b21pY0ludGVnZXIoaW50IGluaXRpYWxWYWx1ZSkgeworICAgICAgICB2YWx1ZSA9IGluaXRpYWxWYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IEF0b21pY0ludGVnZXIgd2l0aCBpbml0aWFsIHZhbHVlIHtAY29kZSAwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXRvbWljSW50ZWdlcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY3VycmVudCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0KCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0byB0aGUgZ2l2ZW4gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIG5ldyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldChpbnQgbmV3VmFsdWUpIHsKKyAgICAgICAgdmFsdWUgPSBuZXdWYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFdmVudHVhbGx5IHNldHMgdG8gdGhlIGdpdmVuIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIG5ld1ZhbHVlIHRoZSBuZXcgdmFsdWUKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgbGF6eVNldChpbnQgbmV3VmFsdWUpIHsKKyAgICAgICAgdW5zYWZlLnB1dE9yZGVyZWRJbnQodGhpcywgdmFsdWVPZmZzZXQsIG5ld1ZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdG8gdGhlIGdpdmVuIHZhbHVlIGFuZCByZXR1cm5zIHRoZSBvbGQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRBbmRTZXQoaW50IG5ld1ZhbHVlKSB7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIGludCBjdXJyZW50ID0gZ2V0KCk7CisgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldChjdXJyZW50LCBuZXdWYWx1ZSkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdGhlIHZhbHVlIHRvIHRoZSBnaXZlbiB1cGRhdGVkIHZhbHVlCisgICAgICogaWYgdGhlIGN1cnJlbnQgdmFsdWUge0Bjb2RlID09fSB0aGUgZXhwZWN0ZWQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhwZWN0IHRoZSBleHBlY3RlZCB2YWx1ZQorICAgICAqIEBwYXJhbSB1cGRhdGUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsLiBGYWxzZSByZXR1cm4gaW5kaWNhdGVzIHRoYXQKKyAgICAgKiB0aGUgYWN0dWFsIHZhbHVlIHdhcyBub3QgZXF1YWwgdG8gdGhlIGV4cGVjdGVkIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGNvbXBhcmVBbmRTZXQoaW50IGV4cGVjdCwgaW50IHVwZGF0ZSkgeworICAgICAgICByZXR1cm4gdW5zYWZlLmNvbXBhcmVBbmRTd2FwSW50KHRoaXMsIHZhbHVlT2Zmc2V0LCBleHBlY3QsIHVwZGF0ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBzZXRzIHRoZSB2YWx1ZSB0byB0aGUgZ2l2ZW4gdXBkYXRlZCB2YWx1ZQorICAgICAqIGlmIHRoZSBjdXJyZW50IHZhbHVlIHtAY29kZSA9PX0gdGhlIGV4cGVjdGVkIHZhbHVlLgorICAgICAqCisgICAgICogPHA+TWF5IDxhIGhyZWY9InBhY2thZ2Utc3VtbWFyeS5odG1sI1NwdXJpb3VzIj5mYWlsIHNwdXJpb3VzbHk8L2E+CisgICAgICogYW5kIGRvZXMgbm90IHByb3ZpZGUgb3JkZXJpbmcgZ3VhcmFudGVlcywgc28gaXMgb25seSByYXJlbHkgYW4KKyAgICAgKiBhcHByb3ByaWF0ZSBhbHRlcm5hdGl2ZSB0byB7QGNvZGUgY29tcGFyZUFuZFNldH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhwZWN0IHRoZSBleHBlY3RlZCB2YWx1ZQorICAgICAqIEBwYXJhbSB1cGRhdGUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIHdlYWtDb21wYXJlQW5kU2V0KGludCBleHBlY3QsIGludCB1cGRhdGUpIHsKKyAgICAgICAgcmV0dXJuIHVuc2FmZS5jb21wYXJlQW5kU3dhcEludCh0aGlzLCB2YWx1ZU9mZnNldCwgZXhwZWN0LCB1cGRhdGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgaW5jcmVtZW50cyBieSBvbmUgdGhlIGN1cnJlbnQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0QW5kSW5jcmVtZW50KCkgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBpbnQgY3VycmVudCA9IGdldCgpOworICAgICAgICAgICAgaW50IG5leHQgPSBjdXJyZW50ICsgMTsKKyAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0KGN1cnJlbnQsIG5leHQpKQorICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBkZWNyZW1lbnRzIGJ5IG9uZSB0aGUgY3VycmVudCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRBbmREZWNyZW1lbnQoKSB7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIGludCBjdXJyZW50ID0gZ2V0KCk7CisgICAgICAgICAgICBpbnQgbmV4dCA9IGN1cnJlbnQgLSAxOworICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXQoY3VycmVudCwgbmV4dCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGFkZHMgdGhlIGdpdmVuIHZhbHVlIHRvIHRoZSBjdXJyZW50IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGRlbHRhIHRoZSB2YWx1ZSB0byBhZGQKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0QW5kQWRkKGludCBkZWx0YSkgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBpbnQgY3VycmVudCA9IGdldCgpOworICAgICAgICAgICAgaW50IG5leHQgPSBjdXJyZW50ICsgZGVsdGE7CisgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldChjdXJyZW50LCBuZXh0KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgaW5jcmVtZW50cyBieSBvbmUgdGhlIGN1cnJlbnQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB1cGRhdGVkIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBpbmNyZW1lbnRBbmRHZXQoKSB7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIGludCBjdXJyZW50ID0gZ2V0KCk7CisgICAgICAgICAgICBpbnQgbmV4dCA9IGN1cnJlbnQgKyAxOworICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXQoY3VycmVudCwgbmV4dCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIG5leHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGRlY3JlbWVudHMgYnkgb25lIHRoZSBjdXJyZW50IHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdXBkYXRlZCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZGVjcmVtZW50QW5kR2V0KCkgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBpbnQgY3VycmVudCA9IGdldCgpOworICAgICAgICAgICAgaW50IG5leHQgPSBjdXJyZW50IC0gMTsKKyAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0KGN1cnJlbnQsIG5leHQpKQorICAgICAgICAgICAgICAgIHJldHVybiBuZXh0OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBhZGRzIHRoZSBnaXZlbiB2YWx1ZSB0byB0aGUgY3VycmVudCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZWx0YSB0aGUgdmFsdWUgdG8gYWRkCisgICAgICogQHJldHVybiB0aGUgdXBkYXRlZCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgYWRkQW5kR2V0KGludCBkZWx0YSkgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBpbnQgY3VycmVudCA9IGdldCgpOworICAgICAgICAgICAgaW50IG5leHQgPSBjdXJyZW50ICsgZGVsdGE7CisgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldChjdXJyZW50LCBuZXh0KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV4dDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY3VycmVudCB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGN1cnJlbnQgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIEludGVnZXIudG9TdHJpbmcoZ2V0KCkpOworICAgIH0KKworCisgICAgcHVibGljIGludCBpbnRWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIGdldCgpOworICAgIH0KKworICAgIHB1YmxpYyBsb25nIGxvbmdWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIChsb25nKWdldCgpOworICAgIH0KKworICAgIHB1YmxpYyBmbG9hdCBmbG9hdFZhbHVlKCkgeworICAgICAgICByZXR1cm4gKGZsb2F0KWdldCgpOworICAgIH0KKworICAgIHB1YmxpYyBkb3VibGUgZG91YmxlVmFsdWUoKSB7CisgICAgICAgIHJldHVybiAoZG91YmxlKWdldCgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2F0b21pYy9BdG9taWNJbnRlZ2VyQXJyYXkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvQXRvbWljSW50ZWdlckFycmF5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmRjZGZkMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvQXRvbWljSW50ZWdlckFycmF5LmphdmEKQEAgLTAsMCArMSwyNTUgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWM7CitpbXBvcnQgc3VuLm1pc2MuVW5zYWZlOworaW1wb3J0IGphdmEudXRpbC4qOworCisvKioKKyAqIEFuIHtAY29kZSBpbnR9IGFycmF5IGluIHdoaWNoIGVsZW1lbnRzIG1heSBiZSB1cGRhdGVkIGF0b21pY2FsbHkuCisgKiBTZWUgdGhlIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWN9IHBhY2thZ2UKKyAqIHNwZWNpZmljYXRpb24gZm9yIGRlc2NyaXB0aW9uIG9mIHRoZSBwcm9wZXJ0aWVzIG9mIGF0b21pYworICogdmFyaWFibGVzLgorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICovCitwdWJsaWMgY2xhc3MgQXRvbWljSW50ZWdlckFycmF5IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDI4NjIxMzM1Njk0NTM2MDQyMzVMOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVW5zYWZlIHVuc2FmZSA9IFVuc2FmZUFjY2Vzcy5USEVfT05FOyAvLyBhbmRyb2lkLWNoYW5nZWQKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgYmFzZSA9IHVuc2FmZS5hcnJheUJhc2VPZmZzZXQoaW50W10uY2xhc3MpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBzaGlmdDsKKyAgICBwcml2YXRlIGZpbmFsIGludFtdIGFycmF5OworCisgICAgc3RhdGljIHsKKyAgICAgICAgaW50IHNjYWxlID0gdW5zYWZlLmFycmF5SW5kZXhTY2FsZShpbnRbXS5jbGFzcyk7CisgICAgICAgIGlmICgoc2NhbGUgJiAoc2NhbGUgLSAxKSkgIT0gMCkKKyAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiZGF0YSB0eXBlIHNjYWxlIG5vdCBhIHBvd2VyIG9mIHR3byIpOworICAgICAgICBzaGlmdCA9IDMxIC0gSW50ZWdlci5udW1iZXJPZkxlYWRpbmdaZXJvcyhzY2FsZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBsb25nIGNoZWNrZWRCeXRlT2Zmc2V0KGludCBpKSB7CisgICAgICAgIGlmIChpIDwgMCB8fCBpID49IGFycmF5Lmxlbmd0aCkKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJpbmRleCAiICsgaSk7CisKKyAgICAgICAgcmV0dXJuIGJ5dGVPZmZzZXQoaSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgbG9uZyBieXRlT2Zmc2V0KGludCBpKSB7CisgICAgICAgIHJldHVybiAoKGxvbmcpIGkgPDwgc2hpZnQpICsgYmFzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IEF0b21pY0ludGVnZXJBcnJheSBvZiB0aGUgZ2l2ZW4gbGVuZ3RoLCB3aXRoIGFsbAorICAgICAqIGVsZW1lbnRzIGluaXRpYWxseSB6ZXJvLgorICAgICAqCisgICAgICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBhcnJheQorICAgICAqLworICAgIHB1YmxpYyBBdG9taWNJbnRlZ2VyQXJyYXkoaW50IGxlbmd0aCkgeworICAgICAgICBhcnJheSA9IG5ldyBpbnRbbGVuZ3RoXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IEF0b21pY0ludGVnZXJBcnJheSB3aXRoIHRoZSBzYW1lIGxlbmd0aCBhcywgYW5kCisgICAgICogYWxsIGVsZW1lbnRzIGNvcGllZCBmcm9tLCB0aGUgZ2l2ZW4gYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkgdGhlIGFycmF5IHRvIGNvcHkgZWxlbWVudHMgZnJvbQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgYXJyYXkgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBBdG9taWNJbnRlZ2VyQXJyYXkoaW50W10gYXJyYXkpIHsKKyAgICAgICAgLy8gVmlzaWJpbGl0eSBndWFyYW50ZWVkIGJ5IGZpbmFsIGZpZWxkIGd1YXJhbnRlZXMKKyAgICAgICAgdGhpcy5hcnJheSA9IGFycmF5LmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBhcnJheS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgYXJyYXkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGxlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIGFycmF5Lmxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHZhbHVlIGF0IHBvc2l0aW9uIHtAY29kZSBpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIHRoZSBpbmRleAorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdldChpbnQgaSkgeworICAgICAgICByZXR1cm4gZ2V0UmF3KGNoZWNrZWRCeXRlT2Zmc2V0KGkpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBnZXRSYXcobG9uZyBvZmZzZXQpIHsKKyAgICAgICAgcmV0dXJuIHVuc2FmZS5nZXRJbnRWb2xhdGlsZShhcnJheSwgb2Zmc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBlbGVtZW50IGF0IHBvc2l0aW9uIHtAY29kZSBpfSB0byB0aGUgZ2l2ZW4gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaSB0aGUgaW5kZXgKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIG5ldyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldChpbnQgaSwgaW50IG5ld1ZhbHVlKSB7CisgICAgICAgIHVuc2FmZS5wdXRJbnRWb2xhdGlsZShhcnJheSwgY2hlY2tlZEJ5dGVPZmZzZXQoaSksIG5ld1ZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFdmVudHVhbGx5IHNldHMgdGhlIGVsZW1lbnQgYXQgcG9zaXRpb24ge0Bjb2RlIGl9IHRvIHRoZSBnaXZlbiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIHRoZSBpbmRleAorICAgICAqIEBwYXJhbSBuZXdWYWx1ZSB0aGUgbmV3IHZhbHVlCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGxhenlTZXQoaW50IGksIGludCBuZXdWYWx1ZSkgeworICAgICAgICB1bnNhZmUucHV0T3JkZXJlZEludChhcnJheSwgY2hlY2tlZEJ5dGVPZmZzZXQoaSksIG5ld1ZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdGhlIGVsZW1lbnQgYXQgcG9zaXRpb24ge0Bjb2RlIGl9IHRvIHRoZSBnaXZlbgorICAgICAqIHZhbHVlIGFuZCByZXR1cm5zIHRoZSBvbGQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaSB0aGUgaW5kZXgKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRBbmRTZXQoaW50IGksIGludCBuZXdWYWx1ZSkgeworICAgICAgICBsb25nIG9mZnNldCA9IGNoZWNrZWRCeXRlT2Zmc2V0KGkpOworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgaW50IGN1cnJlbnQgPSBnZXRSYXcob2Zmc2V0KTsKKyAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0UmF3KG9mZnNldCwgY3VycmVudCwgbmV3VmFsdWUpKQorICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBzZXRzIHRoZSBlbGVtZW50IGF0IHBvc2l0aW9uIHtAY29kZSBpfSB0byB0aGUgZ2l2ZW4KKyAgICAgKiB1cGRhdGVkIHZhbHVlIGlmIHRoZSBjdXJyZW50IHZhbHVlIHtAY29kZSA9PX0gdGhlIGV4cGVjdGVkIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGkgdGhlIGluZGV4CisgICAgICogQHBhcmFtIGV4cGVjdCB0aGUgZXhwZWN0ZWQgdmFsdWUKKyAgICAgKiBAcGFyYW0gdXBkYXRlIHRoZSBuZXcgdmFsdWUKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgc3VjY2Vzc2Z1bC4gRmFsc2UgcmV0dXJuIGluZGljYXRlcyB0aGF0CisgICAgICogdGhlIGFjdHVhbCB2YWx1ZSB3YXMgbm90IGVxdWFsIHRvIHRoZSBleHBlY3RlZCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBjb21wYXJlQW5kU2V0KGludCBpLCBpbnQgZXhwZWN0LCBpbnQgdXBkYXRlKSB7CisgICAgICAgIHJldHVybiBjb21wYXJlQW5kU2V0UmF3KGNoZWNrZWRCeXRlT2Zmc2V0KGkpLCBleHBlY3QsIHVwZGF0ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGNvbXBhcmVBbmRTZXRSYXcobG9uZyBvZmZzZXQsIGludCBleHBlY3QsIGludCB1cGRhdGUpIHsKKyAgICAgICAgcmV0dXJuIHVuc2FmZS5jb21wYXJlQW5kU3dhcEludChhcnJheSwgb2Zmc2V0LCBleHBlY3QsIHVwZGF0ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBzZXRzIHRoZSBlbGVtZW50IGF0IHBvc2l0aW9uIHtAY29kZSBpfSB0byB0aGUgZ2l2ZW4KKyAgICAgKiB1cGRhdGVkIHZhbHVlIGlmIHRoZSBjdXJyZW50IHZhbHVlIHtAY29kZSA9PX0gdGhlIGV4cGVjdGVkIHZhbHVlLgorICAgICAqCisgICAgICogPHA+TWF5IDxhIGhyZWY9InBhY2thZ2Utc3VtbWFyeS5odG1sI1NwdXJpb3VzIj5mYWlsIHNwdXJpb3VzbHk8L2E+CisgICAgICogYW5kIGRvZXMgbm90IHByb3ZpZGUgb3JkZXJpbmcgZ3VhcmFudGVlcywgc28gaXMgb25seSByYXJlbHkgYW4KKyAgICAgKiBhcHByb3ByaWF0ZSBhbHRlcm5hdGl2ZSB0byB7QGNvZGUgY29tcGFyZUFuZFNldH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaSB0aGUgaW5kZXgKKyAgICAgKiBAcGFyYW0gZXhwZWN0IHRoZSBleHBlY3RlZCB2YWx1ZQorICAgICAqIEBwYXJhbSB1cGRhdGUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIHdlYWtDb21wYXJlQW5kU2V0KGludCBpLCBpbnQgZXhwZWN0LCBpbnQgdXBkYXRlKSB7CisgICAgICAgIHJldHVybiBjb21wYXJlQW5kU2V0KGksIGV4cGVjdCwgdXBkYXRlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGluY3JlbWVudHMgYnkgb25lIHRoZSBlbGVtZW50IGF0IGluZGV4IHtAY29kZSBpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIHRoZSBpbmRleAorICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRBbmRJbmNyZW1lbnQoaW50IGkpIHsKKyAgICAgICAgcmV0dXJuIGdldEFuZEFkZChpLCAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGRlY3JlbWVudHMgYnkgb25lIHRoZSBlbGVtZW50IGF0IGluZGV4IHtAY29kZSBpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIHRoZSBpbmRleAorICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRBbmREZWNyZW1lbnQoaW50IGkpIHsKKyAgICAgICAgcmV0dXJuIGdldEFuZEFkZChpLCAtMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBhZGRzIHRoZSBnaXZlbiB2YWx1ZSB0byB0aGUgZWxlbWVudCBhdCBpbmRleCB7QGNvZGUgaX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaSB0aGUgaW5kZXgKKyAgICAgKiBAcGFyYW0gZGVsdGEgdGhlIHZhbHVlIHRvIGFkZAorICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRBbmRBZGQoaW50IGksIGludCBkZWx0YSkgeworICAgICAgICBsb25nIG9mZnNldCA9IGNoZWNrZWRCeXRlT2Zmc2V0KGkpOworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgaW50IGN1cnJlbnQgPSBnZXRSYXcob2Zmc2V0KTsKKyAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0UmF3KG9mZnNldCwgY3VycmVudCwgY3VycmVudCArIGRlbHRhKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgaW5jcmVtZW50cyBieSBvbmUgdGhlIGVsZW1lbnQgYXQgaW5kZXgge0Bjb2RlIGl9LgorICAgICAqCisgICAgICogQHBhcmFtIGkgdGhlIGluZGV4CisgICAgICogQHJldHVybiB0aGUgdXBkYXRlZCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgaW5jcmVtZW50QW5kR2V0KGludCBpKSB7CisgICAgICAgIHJldHVybiBhZGRBbmRHZXQoaSwgMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBkZWNyZW1lbnRzIGJ5IG9uZSB0aGUgZWxlbWVudCBhdCBpbmRleCB7QGNvZGUgaX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaSB0aGUgaW5kZXgKKyAgICAgKiBAcmV0dXJuIHRoZSB1cGRhdGVkIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBkZWNyZW1lbnRBbmRHZXQoaW50IGkpIHsKKyAgICAgICAgcmV0dXJuIGFkZEFuZEdldChpLCAtMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBhZGRzIHRoZSBnaXZlbiB2YWx1ZSB0byB0aGUgZWxlbWVudCBhdCBpbmRleCB7QGNvZGUgaX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaSB0aGUgaW5kZXgKKyAgICAgKiBAcGFyYW0gZGVsdGEgdGhlIHZhbHVlIHRvIGFkZAorICAgICAqIEByZXR1cm4gdGhlIHVwZGF0ZWQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGFkZEFuZEdldChpbnQgaSwgaW50IGRlbHRhKSB7CisgICAgICAgIGxvbmcgb2Zmc2V0ID0gY2hlY2tlZEJ5dGVPZmZzZXQoaSk7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBpbnQgY3VycmVudCA9IGdldFJhdyhvZmZzZXQpOworICAgICAgICAgICAgaW50IG5leHQgPSBjdXJyZW50ICsgZGVsdGE7CisgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldFJhdyhvZmZzZXQsIGN1cnJlbnQsIG5leHQpKQorICAgICAgICAgICAgICAgIHJldHVybiBuZXh0OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjdXJyZW50IHZhbHVlcyBvZiBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHRoZSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGN1cnJlbnQgdmFsdWVzIG9mIGFycmF5CisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgaW50IGlNYXggPSBhcnJheS5sZW5ndGggLSAxOworICAgICAgICBpZiAoaU1heCA9PSAtMSkKKyAgICAgICAgICAgIHJldHVybiAiW10iOworCisgICAgICAgIFN0cmluZ0J1aWxkZXIgYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGIuYXBwZW5kKCdbJyk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyA7IGkrKykgeworICAgICAgICAgICAgYi5hcHBlbmQoZ2V0UmF3KGJ5dGVPZmZzZXQoaSkpKTsKKyAgICAgICAgICAgIGlmIChpID09IGlNYXgpCisgICAgICAgICAgICAgICAgcmV0dXJuIGIuYXBwZW5kKCddJykudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGIuYXBwZW5kKCcsJykuYXBwZW5kKCcgJyk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvQXRvbWljSW50ZWdlckZpZWxkVXBkYXRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2F0b21pYy9BdG9taWNJbnRlZ2VyRmllbGRVcGRhdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZThhMGQ1NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvQXRvbWljSW50ZWdlckZpZWxkVXBkYXRlci5qYXZhCkBAIC0wLDAgKzEsMzI1IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljOworCitpbXBvcnQgZGFsdmlrLnN5c3RlbS5WTVN0YWNrOyAvLyBhbmRyb2lkLWFkZGVkCitpbXBvcnQgc3VuLm1pc2MuVW5zYWZlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lio7CisKKy8qKgorICogQSByZWZsZWN0aW9uLWJhc2VkIHV0aWxpdHkgdGhhdCBlbmFibGVzIGF0b21pYyB1cGRhdGVzIHRvCisgKiBkZXNpZ25hdGVkIHtAY29kZSB2b2xhdGlsZSBpbnR9IGZpZWxkcyBvZiBkZXNpZ25hdGVkIGNsYXNzZXMuCisgKiBUaGlzIGNsYXNzIGlzIGRlc2lnbmVkIGZvciB1c2UgaW4gYXRvbWljIGRhdGEgc3RydWN0dXJlcyBpbiB3aGljaAorICogc2V2ZXJhbCBmaWVsZHMgb2YgdGhlIHNhbWUgbm9kZSBhcmUgaW5kZXBlbmRlbnRseSBzdWJqZWN0IHRvIGF0b21pYworICogdXBkYXRlcy4KKyAqCisgKiA8cD5Ob3RlIHRoYXQgdGhlIGd1YXJhbnRlZXMgb2YgdGhlIHtAY29kZSBjb21wYXJlQW5kU2V0fQorICogbWV0aG9kIGluIHRoaXMgY2xhc3MgYXJlIHdlYWtlciB0aGFuIGluIG90aGVyIGF0b21pYyBjbGFzc2VzLgorICogQmVjYXVzZSB0aGlzIGNsYXNzIGNhbm5vdCBlbnN1cmUgdGhhdCBhbGwgdXNlcyBvZiB0aGUgZmllbGQKKyAqIGFyZSBhcHByb3ByaWF0ZSBmb3IgcHVycG9zZXMgb2YgYXRvbWljIGFjY2VzcywgaXQgY2FuCisgKiBndWFyYW50ZWUgYXRvbWljaXR5IG9ubHkgd2l0aCByZXNwZWN0IHRvIG90aGVyIGludm9jYXRpb25zIG9mCisgKiB7QGNvZGUgY29tcGFyZUFuZFNldH0gYW5kIHtAY29kZSBzZXR9IG9uIHRoZSBzYW1lIHVwZGF0ZXIuCisgKgorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICogQHBhcmFtIDxUPiBUaGUgdHlwZSBvZiB0aGUgb2JqZWN0IGhvbGRpbmcgdGhlIHVwZGF0YWJsZSBmaWVsZAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgIEF0b21pY0ludGVnZXJGaWVsZFVwZGF0ZXI8VD4geworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW5kIHJldHVybnMgYW4gdXBkYXRlciBmb3Igb2JqZWN0cyB3aXRoIHRoZSBnaXZlbiBmaWVsZC4KKyAgICAgKiBUaGUgQ2xhc3MgYXJndW1lbnQgaXMgbmVlZGVkIHRvIGNoZWNrIHRoYXQgcmVmbGVjdGl2ZSB0eXBlcyBhbmQKKyAgICAgKiBnZW5lcmljIHR5cGVzIG1hdGNoLgorICAgICAqCisgICAgICogQHBhcmFtIHRjbGFzcyB0aGUgY2xhc3Mgb2YgdGhlIG9iamVjdHMgaG9sZGluZyB0aGUgZmllbGQKKyAgICAgKiBAcGFyYW0gZmllbGROYW1lIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBiZSB1cGRhdGVkCisgICAgICogQHJldHVybiB0aGUgdXBkYXRlcgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBmaWVsZCBpcyBub3QgYQorICAgICAqIHZvbGF0aWxlIGludGVnZXIgdHlwZQorICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB3aXRoIGEgbmVzdGVkIHJlZmxlY3Rpb24tYmFzZWQKKyAgICAgKiBleGNlcHRpb24gaWYgdGhlIGNsYXNzIGRvZXMgbm90IGhvbGQgZmllbGQgb3IgaXMgdGhlIHdyb25nIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxVPiBBdG9taWNJbnRlZ2VyRmllbGRVcGRhdGVyPFU+IG5ld1VwZGF0ZXIoQ2xhc3M8VT4gdGNsYXNzLCBTdHJpbmcgZmllbGROYW1lKSB7CisgICAgICAgIHJldHVybiBuZXcgQXRvbWljSW50ZWdlckZpZWxkVXBkYXRlckltcGw8VT4odGNsYXNzLCBmaWVsZE5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb3RlY3RlZCBkby1ub3RoaW5nIGNvbnN0cnVjdG9yIGZvciB1c2UgYnkgc3ViY2xhc3Nlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQXRvbWljSW50ZWdlckZpZWxkVXBkYXRlcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdGhlIGZpZWxkIG9mIHRoZSBnaXZlbiBvYmplY3QgbWFuYWdlZCBieSB0aGlzIHVwZGF0ZXIKKyAgICAgKiB0byB0aGUgZ2l2ZW4gdXBkYXRlZCB2YWx1ZSBpZiB0aGUgY3VycmVudCB2YWx1ZSB7QGNvZGUgPT19IHRoZQorICAgICAqIGV4cGVjdGVkIHZhbHVlLiBUaGlzIG1ldGhvZCBpcyBndWFyYW50ZWVkIHRvIGJlIGF0b21pYyB3aXRoIHJlc3BlY3QgdG8KKyAgICAgKiBvdGhlciBjYWxscyB0byB7QGNvZGUgY29tcGFyZUFuZFNldH0gYW5kIHtAY29kZSBzZXR9LCBidXQgbm90CisgICAgICogbmVjZXNzYXJpbHkgd2l0aCByZXNwZWN0IHRvIG90aGVyIGNoYW5nZXMgaW4gdGhlIGZpZWxkLgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBBbiBvYmplY3Qgd2hvc2UgZmllbGQgdG8gY29uZGl0aW9uYWxseSBzZXQKKyAgICAgKiBAcGFyYW0gZXhwZWN0IHRoZSBleHBlY3RlZCB2YWx1ZQorICAgICAqIEBwYXJhbSB1cGRhdGUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYge0Bjb2RlIG9ian0gaXMgbm90IGFuIGluc3RhbmNlCisgICAgICogb2YgdGhlIGNsYXNzIHBvc3Nlc3NpbmcgdGhlIGZpZWxkIGVzdGFibGlzaGVkIGluIHRoZSBjb25zdHJ1Y3RvcgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGNvbXBhcmVBbmRTZXQoVCBvYmosIGludCBleHBlY3QsIGludCB1cGRhdGUpOworCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBzZXRzIHRoZSBmaWVsZCBvZiB0aGUgZ2l2ZW4gb2JqZWN0IG1hbmFnZWQgYnkgdGhpcyB1cGRhdGVyCisgICAgICogdG8gdGhlIGdpdmVuIHVwZGF0ZWQgdmFsdWUgaWYgdGhlIGN1cnJlbnQgdmFsdWUge0Bjb2RlID09fSB0aGUKKyAgICAgKiBleHBlY3RlZCB2YWx1ZS4gVGhpcyBtZXRob2QgaXMgZ3VhcmFudGVlZCB0byBiZSBhdG9taWMgd2l0aCByZXNwZWN0IHRvCisgICAgICogb3RoZXIgY2FsbHMgdG8ge0Bjb2RlIGNvbXBhcmVBbmRTZXR9IGFuZCB7QGNvZGUgc2V0fSwgYnV0IG5vdAorICAgICAqIG5lY2Vzc2FyaWx5IHdpdGggcmVzcGVjdCB0byBvdGhlciBjaGFuZ2VzIGluIHRoZSBmaWVsZC4KKyAgICAgKgorICAgICAqIDxwPk1heSA8YSBocmVmPSJwYWNrYWdlLXN1bW1hcnkuaHRtbCNTcHVyaW91cyI+ZmFpbCBzcHVyaW91c2x5PC9hPgorICAgICAqIGFuZCBkb2VzIG5vdCBwcm92aWRlIG9yZGVyaW5nIGd1YXJhbnRlZXMsIHNvIGlzIG9ubHkgcmFyZWx5IGFuCisgICAgICogYXBwcm9wcmlhdGUgYWx0ZXJuYXRpdmUgdG8ge0Bjb2RlIGNvbXBhcmVBbmRTZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBBbiBvYmplY3Qgd2hvc2UgZmllbGQgdG8gY29uZGl0aW9uYWxseSBzZXQKKyAgICAgKiBAcGFyYW0gZXhwZWN0IHRoZSBleHBlY3RlZCB2YWx1ZQorICAgICAqIEBwYXJhbSB1cGRhdGUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYge0Bjb2RlIG9ian0gaXMgbm90IGFuIGluc3RhbmNlCisgICAgICogb2YgdGhlIGNsYXNzIHBvc3Nlc3NpbmcgdGhlIGZpZWxkIGVzdGFibGlzaGVkIGluIHRoZSBjb25zdHJ1Y3RvcgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIHdlYWtDb21wYXJlQW5kU2V0KFQgb2JqLCBpbnQgZXhwZWN0LCBpbnQgdXBkYXRlKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZpZWxkIG9mIHRoZSBnaXZlbiBvYmplY3QgbWFuYWdlZCBieSB0aGlzIHVwZGF0ZXIgdG8gdGhlCisgICAgICogZ2l2ZW4gdXBkYXRlZCB2YWx1ZS4gVGhpcyBvcGVyYXRpb24gaXMgZ3VhcmFudGVlZCB0byBhY3QgYXMgYSB2b2xhdGlsZQorICAgICAqIHN0b3JlIHdpdGggcmVzcGVjdCB0byBzdWJzZXF1ZW50IGludm9jYXRpb25zIG9mIHtAY29kZSBjb21wYXJlQW5kU2V0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmogQW4gb2JqZWN0IHdob3NlIGZpZWxkIHRvIHNldAorICAgICAqIEBwYXJhbSBuZXdWYWx1ZSB0aGUgbmV3IHZhbHVlCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0KFQgb2JqLCBpbnQgbmV3VmFsdWUpOworCisgICAgLyoqCisgICAgICogRXZlbnR1YWxseSBzZXRzIHRoZSBmaWVsZCBvZiB0aGUgZ2l2ZW4gb2JqZWN0IG1hbmFnZWQgYnkgdGhpcworICAgICAqIHVwZGF0ZXIgdG8gdGhlIGdpdmVuIHVwZGF0ZWQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIEFuIG9iamVjdCB3aG9zZSBmaWVsZCB0byBzZXQKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBsYXp5U2V0KFQgb2JqLCBpbnQgbmV3VmFsdWUpOworCisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHZhbHVlIGhlbGQgaW4gdGhlIGZpZWxkIG9mIHRoZSBnaXZlbiBvYmplY3QgbWFuYWdlZAorICAgICAqIGJ5IHRoaXMgdXBkYXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmogQW4gb2JqZWN0IHdob3NlIGZpZWxkIHRvIGdldAorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldChUIG9iaik7CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdGhlIGZpZWxkIG9mIHRoZSBnaXZlbiBvYmplY3QgbWFuYWdlZCBieSB0aGlzIHVwZGF0ZXIKKyAgICAgKiB0byB0aGUgZ2l2ZW4gdmFsdWUgYW5kIHJldHVybnMgdGhlIG9sZCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmogQW4gb2JqZWN0IHdob3NlIGZpZWxkIHRvIGdldCBhbmQgc2V0CisgICAgICogQHBhcmFtIG5ld1ZhbHVlIHRoZSBuZXcgdmFsdWUKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0QW5kU2V0KFQgb2JqLCBpbnQgbmV3VmFsdWUpIHsKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgaW50IGN1cnJlbnQgPSBnZXQob2JqKTsKKyAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0KG9iaiwgY3VycmVudCwgbmV3VmFsdWUpKQorICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBpbmNyZW1lbnRzIGJ5IG9uZSB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZmllbGQgb2YgdGhlCisgICAgICogZ2l2ZW4gb2JqZWN0IG1hbmFnZWQgYnkgdGhpcyB1cGRhdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBBbiBvYmplY3Qgd2hvc2UgZmllbGQgdG8gZ2V0IGFuZCBzZXQKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0QW5kSW5jcmVtZW50KFQgb2JqKSB7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIGludCBjdXJyZW50ID0gZ2V0KG9iaik7CisgICAgICAgICAgICBpbnQgbmV4dCA9IGN1cnJlbnQgKyAxOworICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXQob2JqLCBjdXJyZW50LCBuZXh0KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgZGVjcmVtZW50cyBieSBvbmUgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGZpZWxkIG9mIHRoZQorICAgICAqIGdpdmVuIG9iamVjdCBtYW5hZ2VkIGJ5IHRoaXMgdXBkYXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmogQW4gb2JqZWN0IHdob3NlIGZpZWxkIHRvIGdldCBhbmQgc2V0CisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEFuZERlY3JlbWVudChUIG9iaikgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBpbnQgY3VycmVudCA9IGdldChvYmopOworICAgICAgICAgICAgaW50IG5leHQgPSBjdXJyZW50IC0gMTsKKyAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0KG9iaiwgY3VycmVudCwgbmV4dCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGFkZHMgdGhlIGdpdmVuIHZhbHVlIHRvIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBmaWVsZCBvZgorICAgICAqIHRoZSBnaXZlbiBvYmplY3QgbWFuYWdlZCBieSB0aGlzIHVwZGF0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIEFuIG9iamVjdCB3aG9zZSBmaWVsZCB0byBnZXQgYW5kIHNldAorICAgICAqIEBwYXJhbSBkZWx0YSB0aGUgdmFsdWUgdG8gYWRkCisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEFuZEFkZChUIG9iaiwgaW50IGRlbHRhKSB7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIGludCBjdXJyZW50ID0gZ2V0KG9iaik7CisgICAgICAgICAgICBpbnQgbmV4dCA9IGN1cnJlbnQgKyBkZWx0YTsKKyAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0KG9iaiwgY3VycmVudCwgbmV4dCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGluY3JlbWVudHMgYnkgb25lIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBmaWVsZCBvZiB0aGUKKyAgICAgKiBnaXZlbiBvYmplY3QgbWFuYWdlZCBieSB0aGlzIHVwZGF0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIEFuIG9iamVjdCB3aG9zZSBmaWVsZCB0byBnZXQgYW5kIHNldAorICAgICAqIEByZXR1cm4gdGhlIHVwZGF0ZWQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGluY3JlbWVudEFuZEdldChUIG9iaikgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBpbnQgY3VycmVudCA9IGdldChvYmopOworICAgICAgICAgICAgaW50IG5leHQgPSBjdXJyZW50ICsgMTsKKyAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0KG9iaiwgY3VycmVudCwgbmV4dCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIG5leHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGRlY3JlbWVudHMgYnkgb25lIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBmaWVsZCBvZiB0aGUKKyAgICAgKiBnaXZlbiBvYmplY3QgbWFuYWdlZCBieSB0aGlzIHVwZGF0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIEFuIG9iamVjdCB3aG9zZSBmaWVsZCB0byBnZXQgYW5kIHNldAorICAgICAqIEByZXR1cm4gdGhlIHVwZGF0ZWQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGRlY3JlbWVudEFuZEdldChUIG9iaikgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBpbnQgY3VycmVudCA9IGdldChvYmopOworICAgICAgICAgICAgaW50IG5leHQgPSBjdXJyZW50IC0gMTsKKyAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0KG9iaiwgY3VycmVudCwgbmV4dCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIG5leHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGFkZHMgdGhlIGdpdmVuIHZhbHVlIHRvIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBmaWVsZCBvZgorICAgICAqIHRoZSBnaXZlbiBvYmplY3QgbWFuYWdlZCBieSB0aGlzIHVwZGF0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIEFuIG9iamVjdCB3aG9zZSBmaWVsZCB0byBnZXQgYW5kIHNldAorICAgICAqIEBwYXJhbSBkZWx0YSB0aGUgdmFsdWUgdG8gYWRkCisgICAgICogQHJldHVybiB0aGUgdXBkYXRlZCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgYWRkQW5kR2V0KFQgb2JqLCBpbnQgZGVsdGEpIHsKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgaW50IGN1cnJlbnQgPSBnZXQob2JqKTsKKyAgICAgICAgICAgIGludCBuZXh0ID0gY3VycmVudCArIGRlbHRhOworICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXQob2JqLCBjdXJyZW50LCBuZXh0KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV4dDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFN0YW5kYXJkIGhvdHNwb3QgaW1wbGVtZW50YXRpb24gdXNpbmcgaW50cmluc2ljcworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEF0b21pY0ludGVnZXJGaWVsZFVwZGF0ZXJJbXBsPFQ+IGV4dGVuZHMgQXRvbWljSW50ZWdlckZpZWxkVXBkYXRlcjxUPiB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFVuc2FmZSB1bnNhZmUgPSBVbnNhZmVBY2Nlc3MuVEhFX09ORTsgLy8gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIHByaXZhdGUgZmluYWwgbG9uZyBvZmZzZXQ7CisgICAgICAgIHByaXZhdGUgZmluYWwgQ2xhc3M8VD4gdGNsYXNzOworICAgICAgICBwcml2YXRlIGZpbmFsIENsYXNzIGNjbGFzczsKKworICAgICAgICBBdG9taWNJbnRlZ2VyRmllbGRVcGRhdGVySW1wbChDbGFzczxUPiB0Y2xhc3MsIFN0cmluZyBmaWVsZE5hbWUpIHsKKyAgICAgICAgICAgIEZpZWxkIGZpZWxkID0gbnVsbDsKKyAgICAgICAgICAgIENsYXNzIGNhbGxlciA9IG51bGw7CisgICAgICAgICAgICBpbnQgbW9kaWZpZXJzID0gMDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZmllbGQgPSB0Y2xhc3MuZ2V0RGVjbGFyZWRGaWVsZChmaWVsZE5hbWUpOworICAgICAgICAgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICAgICAgICAgIGNhbGxlciA9IFZNU3RhY2suZ2V0U3RhY2tDbGFzczIoKTsKKyAgICAgICAgICAgICAgICAvLyBFTkQgYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgICAgICAgICAgbW9kaWZpZXJzID0gZmllbGQuZ2V0TW9kaWZpZXJzKCk7CisKKyAgICAgICAgICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLXJlbW92ZWQKKyAgICAgICAgICAgICAgICAvLyBtb2RpZmllcnMgPSBmaWVsZC5nZXRNb2RpZmllcnMoKTsKKyAgICAgICAgICAgICAgICAvLyBzdW4ucmVmbGVjdC5taXNjLlJlZmxlY3RVdGlsLmVuc3VyZU1lbWJlckFjY2VzcygKKyAgICAgICAgICAgICAgICAvLyAgICAgY2FsbGVyLCB0Y2xhc3MsIG51bGwsIG1vZGlmaWVycyk7CisgICAgICAgICAgICAgICAgLy8gc3VuLnJlZmxlY3QubWlzYy5SZWZsZWN0VXRpbC5jaGVja1BhY2thZ2VBY2Nlc3ModGNsYXNzKTsKKyAgICAgICAgICAgICAgICAvLyBFTkQgYW5kcm9pZC1yZW1vdmVkCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihleCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIENsYXNzIGZpZWxkdCA9IGZpZWxkLmdldFR5cGUoKTsKKyAgICAgICAgICAgIGlmIChmaWVsZHQgIT0gaW50LmNsYXNzKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk11c3QgYmUgaW50ZWdlciB0eXBlIik7CisKKyAgICAgICAgICAgIGlmICghTW9kaWZpZXIuaXNWb2xhdGlsZShtb2RpZmllcnMpKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk11c3QgYmUgdm9sYXRpbGUgdHlwZSIpOworCisgICAgICAgICAgICB0aGlzLmNjbGFzcyA9IChNb2RpZmllci5pc1Byb3RlY3RlZChtb2RpZmllcnMpICYmCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsZXIgIT0gdGNsYXNzKSA/IGNhbGxlciA6IG51bGw7CisgICAgICAgICAgICB0aGlzLnRjbGFzcyA9IHRjbGFzczsKKyAgICAgICAgICAgIG9mZnNldCA9IHVuc2FmZS5vYmplY3RGaWVsZE9mZnNldChmaWVsZCk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgZnVsbENoZWNrKFQgb2JqKSB7CisgICAgICAgICAgICBpZiAoIXRjbGFzcy5pc0luc3RhbmNlKG9iaikpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzQ2FzdEV4Y2VwdGlvbigpOworICAgICAgICAgICAgaWYgKGNjbGFzcyAhPSBudWxsKQorICAgICAgICAgICAgICAgIGVuc3VyZVByb3RlY3RlZEFjY2VzcyhvYmopOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gY29tcGFyZUFuZFNldChUIG9iaiwgaW50IGV4cGVjdCwgaW50IHVwZGF0ZSkgeworICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsIHx8IG9iai5nZXRDbGFzcygpICE9IHRjbGFzcyB8fCBjY2xhc3MgIT0gbnVsbCkgZnVsbENoZWNrKG9iaik7CisgICAgICAgICAgICByZXR1cm4gdW5zYWZlLmNvbXBhcmVBbmRTd2FwSW50KG9iaiwgb2Zmc2V0LCBleHBlY3QsIHVwZGF0ZSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiB3ZWFrQ29tcGFyZUFuZFNldChUIG9iaiwgaW50IGV4cGVjdCwgaW50IHVwZGF0ZSkgeworICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsIHx8IG9iai5nZXRDbGFzcygpICE9IHRjbGFzcyB8fCBjY2xhc3MgIT0gbnVsbCkgZnVsbENoZWNrKG9iaik7CisgICAgICAgICAgICByZXR1cm4gdW5zYWZlLmNvbXBhcmVBbmRTd2FwSW50KG9iaiwgb2Zmc2V0LCBleHBlY3QsIHVwZGF0ZSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXQoVCBvYmosIGludCBuZXdWYWx1ZSkgeworICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsIHx8IG9iai5nZXRDbGFzcygpICE9IHRjbGFzcyB8fCBjY2xhc3MgIT0gbnVsbCkgZnVsbENoZWNrKG9iaik7CisgICAgICAgICAgICB1bnNhZmUucHV0SW50Vm9sYXRpbGUob2JqLCBvZmZzZXQsIG5ld1ZhbHVlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGxhenlTZXQoVCBvYmosIGludCBuZXdWYWx1ZSkgeworICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsIHx8IG9iai5nZXRDbGFzcygpICE9IHRjbGFzcyB8fCBjY2xhc3MgIT0gbnVsbCkgZnVsbENoZWNrKG9iaik7CisgICAgICAgICAgICB1bnNhZmUucHV0T3JkZXJlZEludChvYmosIG9mZnNldCwgbmV3VmFsdWUpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGZpbmFsIGludCBnZXQoVCBvYmopIHsKKyAgICAgICAgICAgIGlmIChvYmogPT0gbnVsbCB8fCBvYmouZ2V0Q2xhc3MoKSAhPSB0Y2xhc3MgfHwgY2NsYXNzICE9IG51bGwpIGZ1bGxDaGVjayhvYmopOworICAgICAgICAgICAgcmV0dXJuIHVuc2FmZS5nZXRJbnRWb2xhdGlsZShvYmosIG9mZnNldCk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUHJvdGVjdGVkQWNjZXNzKFQgb2JqKSB7CisgICAgICAgICAgICBpZiAoY2NsYXNzLmlzSW5zdGFuY2Uob2JqKSkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgIG5ldyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uKCJDbGFzcyAiICsKKyAgICAgICAgICAgICAgICAgICAgY2NsYXNzLmdldE5hbWUoKSArCisgICAgICAgICAgICAgICAgICAgICIgY2FuIG5vdCBhY2Nlc3MgYSBwcm90ZWN0ZWQgbWVtYmVyIG9mIGNsYXNzICIgKworICAgICAgICAgICAgICAgICAgICB0Y2xhc3MuZ2V0TmFtZSgpICsKKyAgICAgICAgICAgICAgICAgICAgIiB1c2luZyBhbiBpbnN0YW5jZSBvZiAiICsKKyAgICAgICAgICAgICAgICAgICAgb2JqLmdldENsYXNzKCkuZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgKQorICAgICAgICAgICAgKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvQXRvbWljTG9uZy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2F0b21pYy9BdG9taWNMb25nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTJkNmNkMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvQXRvbWljTG9uZy5qYXZhCkBAIC0wLDAgKzEsMjUwIEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljOworaW1wb3J0IHN1bi5taXNjLlVuc2FmZTsKKworLyoqCisgKiBBIHtAY29kZSBsb25nfSB2YWx1ZSB0aGF0IG1heSBiZSB1cGRhdGVkIGF0b21pY2FsbHkuICBTZWUgdGhlCisgKiB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljfSBwYWNrYWdlIHNwZWNpZmljYXRpb24gZm9yCisgKiBkZXNjcmlwdGlvbiBvZiB0aGUgcHJvcGVydGllcyBvZiBhdG9taWMgdmFyaWFibGVzLiBBbgorICoge0Bjb2RlIEF0b21pY0xvbmd9IGlzIHVzZWQgaW4gYXBwbGljYXRpb25zIHN1Y2ggYXMgYXRvbWljYWxseQorICogaW5jcmVtZW50ZWQgc2VxdWVuY2UgbnVtYmVycywgYW5kIGNhbm5vdCBiZSB1c2VkIGFzIGEgcmVwbGFjZW1lbnQKKyAqIGZvciBhIHtAbGluayBqYXZhLmxhbmcuTG9uZ30uIEhvd2V2ZXIsIHRoaXMgY2xhc3MgZG9lcyBleHRlbmQKKyAqIHtAY29kZSBOdW1iZXJ9IHRvIGFsbG93IHVuaWZvcm0gYWNjZXNzIGJ5IHRvb2xzIGFuZCB1dGlsaXRpZXMgdGhhdAorICogZGVhbCB3aXRoIG51bWVyaWNhbGx5LWJhc2VkIGNsYXNzZXMuCisgKgorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICovCitwdWJsaWMgY2xhc3MgQXRvbWljTG9uZyBleHRlbmRzIE51bWJlciBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxOTI3ODE2MjkzNTEyMTI0MTg0TDsKKworICAgIC8vIHNldHVwIHRvIHVzZSBVbnNhZmUuY29tcGFyZUFuZFN3YXBMb25nIGZvciB1cGRhdGVzCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVW5zYWZlIHVuc2FmZSA9IFVuc2FmZUFjY2Vzcy5USEVfT05FOyAvLyBhbmRyb2lkLWNoYW5nZWQKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHZhbHVlT2Zmc2V0OworCisgICAgLyoqCisgICAgICogUmVjb3JkcyB3aGV0aGVyIHRoZSB1bmRlcmx5aW5nIEpWTSBzdXBwb3J0cyBsb2NrbGVzcworICAgICAqIGNvbXBhcmVBbmRTd2FwIGZvciBsb25ncy4gV2hpbGUgdGhlIFVuc2FmZS5jb21wYXJlQW5kU3dhcExvbmcKKyAgICAgKiBtZXRob2Qgd29ya3MgaW4gZWl0aGVyIGNhc2UsIHNvbWUgY29uc3RydWN0aW9ucyBzaG91bGQgYmUKKyAgICAgKiBoYW5kbGVkIGF0IEphdmEgbGV2ZWwgdG8gYXZvaWQgbG9ja2luZyB1c2VyLXZpc2libGUgbG9ja3MuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGJvb2xlYW4gVk1fU1VQUE9SVFNfTE9OR19DQVMgPSBWTVN1cHBvcnRzQ1M4KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdW5kZXJseWluZyBKVk0gc3VwcG9ydHMgbG9ja2xlc3MgQ29tcGFyZUFuZFNldAorICAgICAqIGZvciBsb25ncy4gQ2FsbGVkIG9ubHkgb25jZSBhbmQgY2FjaGVkIGluIFZNX1NVUFBPUlRTX0xPTkdfQ0FTLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBib29sZWFuIFZNU3VwcG9ydHNDUzgoKTsKKworICAgIHN0YXRpYyB7CisgICAgICB0cnkgeworICAgICAgICB2YWx1ZU9mZnNldCA9IHVuc2FmZS5vYmplY3RGaWVsZE9mZnNldAorICAgICAgICAgICAgKEF0b21pY0xvbmcuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgidmFsdWUiKSk7CisgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsgdGhyb3cgbmV3IEVycm9yKGV4KTsgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9sYXRpbGUgbG9uZyB2YWx1ZTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgQXRvbWljTG9uZyB3aXRoIHRoZSBnaXZlbiBpbml0aWFsIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGluaXRpYWxWYWx1ZSB0aGUgaW5pdGlhbCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBBdG9taWNMb25nKGxvbmcgaW5pdGlhbFZhbHVlKSB7CisgICAgICAgIHZhbHVlID0gaW5pdGlhbFZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgQXRvbWljTG9uZyB3aXRoIGluaXRpYWwgdmFsdWUge0Bjb2RlIDB9LgorICAgICAqLworICAgIHB1YmxpYyBBdG9taWNMb25nKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGN1cnJlbnQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgZ2V0KCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0byB0aGUgZ2l2ZW4gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIG5ldyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldChsb25nIG5ld1ZhbHVlKSB7CisgICAgICAgIHZhbHVlID0gbmV3VmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXZlbnR1YWxseSBzZXRzIHRvIHRoZSBnaXZlbiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdWYWx1ZSB0aGUgbmV3IHZhbHVlCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGxhenlTZXQobG9uZyBuZXdWYWx1ZSkgeworICAgICAgICB1bnNhZmUucHV0T3JkZXJlZExvbmcodGhpcywgdmFsdWVPZmZzZXQsIG5ld1ZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdG8gdGhlIGdpdmVuIHZhbHVlIGFuZCByZXR1cm5zIHRoZSBvbGQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgZ2V0QW5kU2V0KGxvbmcgbmV3VmFsdWUpIHsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIGxvbmcgY3VycmVudCA9IGdldCgpOworICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXQoY3VycmVudCwgbmV3VmFsdWUpKQorICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBzZXRzIHRoZSB2YWx1ZSB0byB0aGUgZ2l2ZW4gdXBkYXRlZCB2YWx1ZQorICAgICAqIGlmIHRoZSBjdXJyZW50IHZhbHVlIHtAY29kZSA9PX0gdGhlIGV4cGVjdGVkIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGV4cGVjdCB0aGUgZXhwZWN0ZWQgdmFsdWUKKyAgICAgKiBAcGFyYW0gdXBkYXRlIHRoZSBuZXcgdmFsdWUKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgc3VjY2Vzc2Z1bC4gRmFsc2UgcmV0dXJuIGluZGljYXRlcyB0aGF0CisgICAgICogdGhlIGFjdHVhbCB2YWx1ZSB3YXMgbm90IGVxdWFsIHRvIHRoZSBleHBlY3RlZCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBjb21wYXJlQW5kU2V0KGxvbmcgZXhwZWN0LCBsb25nIHVwZGF0ZSkgeworICAgICAgICByZXR1cm4gdW5zYWZlLmNvbXBhcmVBbmRTd2FwTG9uZyh0aGlzLCB2YWx1ZU9mZnNldCwgZXhwZWN0LCB1cGRhdGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgc2V0cyB0aGUgdmFsdWUgdG8gdGhlIGdpdmVuIHVwZGF0ZWQgdmFsdWUKKyAgICAgKiBpZiB0aGUgY3VycmVudCB2YWx1ZSB7QGNvZGUgPT19IHRoZSBleHBlY3RlZCB2YWx1ZS4KKyAgICAgKgorICAgICAqIDxwPk1heSA8YSBocmVmPSJwYWNrYWdlLXN1bW1hcnkuaHRtbCNTcHVyaW91cyI+ZmFpbCBzcHVyaW91c2x5PC9hPgorICAgICAqIGFuZCBkb2VzIG5vdCBwcm92aWRlIG9yZGVyaW5nIGd1YXJhbnRlZXMsIHNvIGlzIG9ubHkgcmFyZWx5IGFuCisgICAgICogYXBwcm9wcmlhdGUgYWx0ZXJuYXRpdmUgdG8ge0Bjb2RlIGNvbXBhcmVBbmRTZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIGV4cGVjdCB0aGUgZXhwZWN0ZWQgdmFsdWUKKyAgICAgKiBAcGFyYW0gdXBkYXRlIHRoZSBuZXcgdmFsdWUKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgc3VjY2Vzc2Z1bC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiB3ZWFrQ29tcGFyZUFuZFNldChsb25nIGV4cGVjdCwgbG9uZyB1cGRhdGUpIHsKKyAgICAgICAgcmV0dXJuIHVuc2FmZS5jb21wYXJlQW5kU3dhcExvbmcodGhpcywgdmFsdWVPZmZzZXQsIGV4cGVjdCwgdXBkYXRlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGluY3JlbWVudHMgYnkgb25lIHRoZSBjdXJyZW50IHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgbG9uZyBnZXRBbmRJbmNyZW1lbnQoKSB7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBsb25nIGN1cnJlbnQgPSBnZXQoKTsKKyAgICAgICAgICAgIGxvbmcgbmV4dCA9IGN1cnJlbnQgKyAxOworICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXQoY3VycmVudCwgbmV4dCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGRlY3JlbWVudHMgYnkgb25lIHRoZSBjdXJyZW50IHZhbHVlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgbG9uZyBnZXRBbmREZWNyZW1lbnQoKSB7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBsb25nIGN1cnJlbnQgPSBnZXQoKTsKKyAgICAgICAgICAgIGxvbmcgbmV4dCA9IGN1cnJlbnQgLSAxOworICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXQoY3VycmVudCwgbmV4dCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGFkZHMgdGhlIGdpdmVuIHZhbHVlIHRvIHRoZSBjdXJyZW50IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGRlbHRhIHRoZSB2YWx1ZSB0byBhZGQKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBsb25nIGdldEFuZEFkZChsb25nIGRlbHRhKSB7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBsb25nIGN1cnJlbnQgPSBnZXQoKTsKKyAgICAgICAgICAgIGxvbmcgbmV4dCA9IGN1cnJlbnQgKyBkZWx0YTsKKyAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0KGN1cnJlbnQsIG5leHQpKQorICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBpbmNyZW1lbnRzIGJ5IG9uZSB0aGUgY3VycmVudCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHVwZGF0ZWQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgbG9uZyBpbmNyZW1lbnRBbmRHZXQoKSB7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIGxvbmcgY3VycmVudCA9IGdldCgpOworICAgICAgICAgICAgbG9uZyBuZXh0ID0gY3VycmVudCArIDE7CisgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldChjdXJyZW50LCBuZXh0KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV4dDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgZGVjcmVtZW50cyBieSBvbmUgdGhlIGN1cnJlbnQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB1cGRhdGVkIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgZGVjcmVtZW50QW5kR2V0KCkgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBsb25nIGN1cnJlbnQgPSBnZXQoKTsKKyAgICAgICAgICAgIGxvbmcgbmV4dCA9IGN1cnJlbnQgLSAxOworICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXQoY3VycmVudCwgbmV4dCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIG5leHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGFkZHMgdGhlIGdpdmVuIHZhbHVlIHRvIHRoZSBjdXJyZW50IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGRlbHRhIHRoZSB2YWx1ZSB0byBhZGQKKyAgICAgKiBAcmV0dXJuIHRoZSB1cGRhdGVkIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgYWRkQW5kR2V0KGxvbmcgZGVsdGEpIHsKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgbG9uZyBjdXJyZW50ID0gZ2V0KCk7CisgICAgICAgICAgICBsb25nIG5leHQgPSBjdXJyZW50ICsgZGVsdGE7CisgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldChjdXJyZW50LCBuZXh0KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV4dDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY3VycmVudCB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGN1cnJlbnQgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIExvbmcudG9TdHJpbmcoZ2V0KCkpOworICAgIH0KKworCisgICAgcHVibGljIGludCBpbnRWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIChpbnQpZ2V0KCk7CisgICAgfQorCisgICAgcHVibGljIGxvbmcgbG9uZ1ZhbHVlKCkgeworICAgICAgICByZXR1cm4gZ2V0KCk7CisgICAgfQorCisgICAgcHVibGljIGZsb2F0IGZsb2F0VmFsdWUoKSB7CisgICAgICAgIHJldHVybiAoZmxvYXQpZ2V0KCk7CisgICAgfQorCisgICAgcHVibGljIGRvdWJsZSBkb3VibGVWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIChkb3VibGUpZ2V0KCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvYXRvbWljL0F0b21pY0xvbmdBcnJheS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2F0b21pYy9BdG9taWNMb25nQXJyYXkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZTJkMjVmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2F0b21pYy9BdG9taWNMb25nQXJyYXkuamF2YQpAQCAtMCwwICsxLDI1NSBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYzsKK2ltcG9ydCBzdW4ubWlzYy5VbnNhZmU7CitpbXBvcnQgamF2YS51dGlsLio7CisKKy8qKgorICogQSB7QGNvZGUgbG9uZ30gYXJyYXkgaW4gd2hpY2ggZWxlbWVudHMgbWF5IGJlIHVwZGF0ZWQgYXRvbWljYWxseS4KKyAqIFNlZSB0aGUge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pY30gcGFja2FnZSBzcGVjaWZpY2F0aW9uCisgKiBmb3IgZGVzY3JpcHRpb24gb2YgdGhlIHByb3BlcnRpZXMgb2YgYXRvbWljIHZhcmlhYmxlcy4KKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqLworcHVibGljIGNsYXNzIEF0b21pY0xvbmdBcnJheSBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjMwODQzMTIxNDk3Njc3ODI0OEw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBVbnNhZmUgdW5zYWZlID0gVW5zYWZlQWNjZXNzLlRIRV9PTkU7IC8vIGFuZHJvaWQtY2hhbmdlZAorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBiYXNlID0gdW5zYWZlLmFycmF5QmFzZU9mZnNldChsb25nW10uY2xhc3MpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBzaGlmdDsKKyAgICBwcml2YXRlIGZpbmFsIGxvbmdbXSBhcnJheTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIGludCBzY2FsZSA9IHVuc2FmZS5hcnJheUluZGV4U2NhbGUobG9uZ1tdLmNsYXNzKTsKKyAgICAgICAgaWYgKChzY2FsZSAmIChzY2FsZSAtIDEpKSAhPSAwKQorICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJkYXRhIHR5cGUgc2NhbGUgbm90IGEgcG93ZXIgb2YgdHdvIik7CisgICAgICAgIHNoaWZ0ID0gMzEgLSBJbnRlZ2VyLm51bWJlck9mTGVhZGluZ1plcm9zKHNjYWxlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGxvbmcgY2hlY2tlZEJ5dGVPZmZzZXQoaW50IGkpIHsKKyAgICAgICAgaWYgKGkgPCAwIHx8IGkgPj0gYXJyYXkubGVuZ3RoKQorICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oImluZGV4ICIgKyBpKTsKKworICAgICAgICByZXR1cm4gYnl0ZU9mZnNldChpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBsb25nIGJ5dGVPZmZzZXQoaW50IGkpIHsKKyAgICAgICAgcmV0dXJuICgobG9uZykgaSA8PCBzaGlmdCkgKyBiYXNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgQXRvbWljTG9uZ0FycmF5IG9mIHRoZSBnaXZlbiBsZW5ndGgsIHdpdGggYWxsCisgICAgICogZWxlbWVudHMgaW5pdGlhbGx5IHplcm8uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIGFycmF5CisgICAgICovCisgICAgcHVibGljIEF0b21pY0xvbmdBcnJheShpbnQgbGVuZ3RoKSB7CisgICAgICAgIGFycmF5ID0gbmV3IGxvbmdbbGVuZ3RoXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IEF0b21pY0xvbmdBcnJheSB3aXRoIHRoZSBzYW1lIGxlbmd0aCBhcywgYW5kCisgICAgICogYWxsIGVsZW1lbnRzIGNvcGllZCBmcm9tLCB0aGUgZ2l2ZW4gYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkgdGhlIGFycmF5IHRvIGNvcHkgZWxlbWVudHMgZnJvbQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgYXJyYXkgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBBdG9taWNMb25nQXJyYXkobG9uZ1tdIGFycmF5KSB7CisgICAgICAgIC8vIFZpc2liaWxpdHkgZ3VhcmFudGVlZCBieSBmaW5hbCBmaWVsZCBndWFyYW50ZWVzCisgICAgICAgIHRoaXMuYXJyYXkgPSBhcnJheS5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGFycmF5CisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBsZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBhcnJheS5sZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY3VycmVudCB2YWx1ZSBhdCBwb3NpdGlvbiB7QGNvZGUgaX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaSB0aGUgaW5kZXgKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgZ2V0KGludCBpKSB7CisgICAgICAgIHJldHVybiBnZXRSYXcoY2hlY2tlZEJ5dGVPZmZzZXQoaSkpOworICAgIH0KKworICAgIHByaXZhdGUgbG9uZyBnZXRSYXcobG9uZyBvZmZzZXQpIHsKKyAgICAgICAgcmV0dXJuIHVuc2FmZS5nZXRMb25nVm9sYXRpbGUoYXJyYXksIG9mZnNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZWxlbWVudCBhdCBwb3NpdGlvbiB7QGNvZGUgaX0gdG8gdGhlIGdpdmVuIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGkgdGhlIGluZGV4CisgICAgICogQHBhcmFtIG5ld1ZhbHVlIHRoZSBuZXcgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXQoaW50IGksIGxvbmcgbmV3VmFsdWUpIHsKKyAgICAgICAgdW5zYWZlLnB1dExvbmdWb2xhdGlsZShhcnJheSwgY2hlY2tlZEJ5dGVPZmZzZXQoaSksIG5ld1ZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFdmVudHVhbGx5IHNldHMgdGhlIGVsZW1lbnQgYXQgcG9zaXRpb24ge0Bjb2RlIGl9IHRvIHRoZSBnaXZlbiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIHRoZSBpbmRleAorICAgICAqIEBwYXJhbSBuZXdWYWx1ZSB0aGUgbmV3IHZhbHVlCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGxhenlTZXQoaW50IGksIGxvbmcgbmV3VmFsdWUpIHsKKyAgICAgICAgdW5zYWZlLnB1dE9yZGVyZWRMb25nKGFycmF5LCBjaGVja2VkQnl0ZU9mZnNldChpKSwgbmV3VmFsdWUpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBzZXRzIHRoZSBlbGVtZW50IGF0IHBvc2l0aW9uIHtAY29kZSBpfSB0byB0aGUgZ2l2ZW4gdmFsdWUKKyAgICAgKiBhbmQgcmV0dXJucyB0aGUgb2xkIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGkgdGhlIGluZGV4CisgICAgICogQHBhcmFtIG5ld1ZhbHVlIHRoZSBuZXcgdmFsdWUKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBsb25nIGdldEFuZFNldChpbnQgaSwgbG9uZyBuZXdWYWx1ZSkgeworICAgICAgICBsb25nIG9mZnNldCA9IGNoZWNrZWRCeXRlT2Zmc2V0KGkpOworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgbG9uZyBjdXJyZW50ID0gZ2V0UmF3KG9mZnNldCk7CisgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldFJhdyhvZmZzZXQsIGN1cnJlbnQsIG5ld1ZhbHVlKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgc2V0cyB0aGUgZWxlbWVudCBhdCBwb3NpdGlvbiB7QGNvZGUgaX0gdG8gdGhlIGdpdmVuCisgICAgICogdXBkYXRlZCB2YWx1ZSBpZiB0aGUgY3VycmVudCB2YWx1ZSB7QGNvZGUgPT19IHRoZSBleHBlY3RlZCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIHRoZSBpbmRleAorICAgICAqIEBwYXJhbSBleHBlY3QgdGhlIGV4cGVjdGVkIHZhbHVlCisgICAgICogQHBhcmFtIHVwZGF0ZSB0aGUgbmV3IHZhbHVlCisgICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwuIEZhbHNlIHJldHVybiBpbmRpY2F0ZXMgdGhhdAorICAgICAqIHRoZSBhY3R1YWwgdmFsdWUgd2FzIG5vdCBlcXVhbCB0byB0aGUgZXhwZWN0ZWQgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gY29tcGFyZUFuZFNldChpbnQgaSwgbG9uZyBleHBlY3QsIGxvbmcgdXBkYXRlKSB7CisgICAgICAgIHJldHVybiBjb21wYXJlQW5kU2V0UmF3KGNoZWNrZWRCeXRlT2Zmc2V0KGkpLCBleHBlY3QsIHVwZGF0ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGNvbXBhcmVBbmRTZXRSYXcobG9uZyBvZmZzZXQsIGxvbmcgZXhwZWN0LCBsb25nIHVwZGF0ZSkgeworICAgICAgICByZXR1cm4gdW5zYWZlLmNvbXBhcmVBbmRTd2FwTG9uZyhhcnJheSwgb2Zmc2V0LCBleHBlY3QsIHVwZGF0ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBzZXRzIHRoZSBlbGVtZW50IGF0IHBvc2l0aW9uIHtAY29kZSBpfSB0byB0aGUgZ2l2ZW4KKyAgICAgKiB1cGRhdGVkIHZhbHVlIGlmIHRoZSBjdXJyZW50IHZhbHVlIHtAY29kZSA9PX0gdGhlIGV4cGVjdGVkIHZhbHVlLgorICAgICAqCisgICAgICogPHA+TWF5IDxhIGhyZWY9InBhY2thZ2Utc3VtbWFyeS5odG1sI1NwdXJpb3VzIj5mYWlsIHNwdXJpb3VzbHk8L2E+CisgICAgICogYW5kIGRvZXMgbm90IHByb3ZpZGUgb3JkZXJpbmcgZ3VhcmFudGVlcywgc28gaXMgb25seSByYXJlbHkgYW4KKyAgICAgKiBhcHByb3ByaWF0ZSBhbHRlcm5hdGl2ZSB0byB7QGNvZGUgY29tcGFyZUFuZFNldH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaSB0aGUgaW5kZXgKKyAgICAgKiBAcGFyYW0gZXhwZWN0IHRoZSBleHBlY3RlZCB2YWx1ZQorICAgICAqIEBwYXJhbSB1cGRhdGUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIHdlYWtDb21wYXJlQW5kU2V0KGludCBpLCBsb25nIGV4cGVjdCwgbG9uZyB1cGRhdGUpIHsKKyAgICAgICAgcmV0dXJuIGNvbXBhcmVBbmRTZXQoaSwgZXhwZWN0LCB1cGRhdGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgaW5jcmVtZW50cyBieSBvbmUgdGhlIGVsZW1lbnQgYXQgaW5kZXgge0Bjb2RlIGl9LgorICAgICAqCisgICAgICogQHBhcmFtIGkgdGhlIGluZGV4CisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgbG9uZyBnZXRBbmRJbmNyZW1lbnQoaW50IGkpIHsKKyAgICAgICAgcmV0dXJuIGdldEFuZEFkZChpLCAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGRlY3JlbWVudHMgYnkgb25lIHRoZSBlbGVtZW50IGF0IGluZGV4IHtAY29kZSBpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIHRoZSBpbmRleAorICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgZ2V0QW5kRGVjcmVtZW50KGludCBpKSB7CisgICAgICAgIHJldHVybiBnZXRBbmRBZGQoaSwgLTEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgYWRkcyB0aGUgZ2l2ZW4gdmFsdWUgdG8gdGhlIGVsZW1lbnQgYXQgaW5kZXgge0Bjb2RlIGl9LgorICAgICAqCisgICAgICogQHBhcmFtIGkgdGhlIGluZGV4CisgICAgICogQHBhcmFtIGRlbHRhIHRoZSB2YWx1ZSB0byBhZGQKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBsb25nIGdldEFuZEFkZChpbnQgaSwgbG9uZyBkZWx0YSkgeworICAgICAgICBsb25nIG9mZnNldCA9IGNoZWNrZWRCeXRlT2Zmc2V0KGkpOworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgbG9uZyBjdXJyZW50ID0gZ2V0UmF3KG9mZnNldCk7CisgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldFJhdyhvZmZzZXQsIGN1cnJlbnQsIGN1cnJlbnQgKyBkZWx0YSkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGluY3JlbWVudHMgYnkgb25lIHRoZSBlbGVtZW50IGF0IGluZGV4IHtAY29kZSBpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIHRoZSBpbmRleAorICAgICAqIEByZXR1cm4gdGhlIHVwZGF0ZWQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgbG9uZyBpbmNyZW1lbnRBbmRHZXQoaW50IGkpIHsKKyAgICAgICAgcmV0dXJuIGFkZEFuZEdldChpLCAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGRlY3JlbWVudHMgYnkgb25lIHRoZSBlbGVtZW50IGF0IGluZGV4IHtAY29kZSBpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIHRoZSBpbmRleAorICAgICAqIEByZXR1cm4gdGhlIHVwZGF0ZWQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgbG9uZyBkZWNyZW1lbnRBbmRHZXQoaW50IGkpIHsKKyAgICAgICAgcmV0dXJuIGFkZEFuZEdldChpLCAtMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBhZGRzIHRoZSBnaXZlbiB2YWx1ZSB0byB0aGUgZWxlbWVudCBhdCBpbmRleCB7QGNvZGUgaX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaSB0aGUgaW5kZXgKKyAgICAgKiBAcGFyYW0gZGVsdGEgdGhlIHZhbHVlIHRvIGFkZAorICAgICAqIEByZXR1cm4gdGhlIHVwZGF0ZWQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBhZGRBbmRHZXQoaW50IGksIGxvbmcgZGVsdGEpIHsKKyAgICAgICAgbG9uZyBvZmZzZXQgPSBjaGVja2VkQnl0ZU9mZnNldChpKTsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIGxvbmcgY3VycmVudCA9IGdldFJhdyhvZmZzZXQpOworICAgICAgICAgICAgbG9uZyBuZXh0ID0gY3VycmVudCArIGRlbHRhOworICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXRSYXcob2Zmc2V0LCBjdXJyZW50LCBuZXh0KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV4dDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY3VycmVudCB2YWx1ZXMgb2YgYXJyYXkuCisgICAgICogQHJldHVybiB0aGUgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjdXJyZW50IHZhbHVlcyBvZiBhcnJheQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIGludCBpTWF4ID0gYXJyYXkubGVuZ3RoIC0gMTsKKyAgICAgICAgaWYgKGlNYXggPT0gLTEpCisgICAgICAgICAgICByZXR1cm4gIltdIjsKKworICAgICAgICBTdHJpbmdCdWlsZGVyIGIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBiLmFwcGVuZCgnWycpOworICAgICAgICBmb3IgKGludCBpID0gMDsgOyBpKyspIHsKKyAgICAgICAgICAgIGIuYXBwZW5kKGdldFJhdyhieXRlT2Zmc2V0KGkpKSk7CisgICAgICAgICAgICBpZiAoaSA9PSBpTWF4KQorICAgICAgICAgICAgICAgIHJldHVybiBiLmFwcGVuZCgnXScpLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBiLmFwcGVuZCgnLCcpLmFwcGVuZCgnICcpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvYXRvbWljL0F0b21pY0xvbmdGaWVsZFVwZGF0ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvQXRvbWljTG9uZ0ZpZWxkVXBkYXRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIxZWY3NDgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvYXRvbWljL0F0b21pY0xvbmdGaWVsZFVwZGF0ZXIuamF2YQpAQCAtMCwwICsxLDQxMyBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYzsKKworaW1wb3J0IGRhbHZpay5zeXN0ZW0uVk1TdGFjazsgLy8gYW5kcm9pZC1hZGRlZAoraW1wb3J0IHN1bi5taXNjLlVuc2FmZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC4qOworCisvKioKKyAqIEEgcmVmbGVjdGlvbi1iYXNlZCB1dGlsaXR5IHRoYXQgZW5hYmxlcyBhdG9taWMgdXBkYXRlcyB0bworICogZGVzaWduYXRlZCB7QGNvZGUgdm9sYXRpbGUgbG9uZ30gZmllbGRzIG9mIGRlc2lnbmF0ZWQgY2xhc3Nlcy4KKyAqIFRoaXMgY2xhc3MgaXMgZGVzaWduZWQgZm9yIHVzZSBpbiBhdG9taWMgZGF0YSBzdHJ1Y3R1cmVzIGluIHdoaWNoCisgKiBzZXZlcmFsIGZpZWxkcyBvZiB0aGUgc2FtZSBub2RlIGFyZSBpbmRlcGVuZGVudGx5IHN1YmplY3QgdG8gYXRvbWljCisgKiB1cGRhdGVzLgorICoKKyAqIDxwPk5vdGUgdGhhdCB0aGUgZ3VhcmFudGVlcyBvZiB0aGUge0Bjb2RlIGNvbXBhcmVBbmRTZXR9CisgKiBtZXRob2QgaW4gdGhpcyBjbGFzcyBhcmUgd2Vha2VyIHRoYW4gaW4gb3RoZXIgYXRvbWljIGNsYXNzZXMuCisgKiBCZWNhdXNlIHRoaXMgY2xhc3MgY2Fubm90IGVuc3VyZSB0aGF0IGFsbCB1c2VzIG9mIHRoZSBmaWVsZAorICogYXJlIGFwcHJvcHJpYXRlIGZvciBwdXJwb3NlcyBvZiBhdG9taWMgYWNjZXNzLCBpdCBjYW4KKyAqIGd1YXJhbnRlZSBhdG9taWNpdHkgb25seSB3aXRoIHJlc3BlY3QgdG8gb3RoZXIgaW52b2NhdGlvbnMgb2YKKyAqIHtAY29kZSBjb21wYXJlQW5kU2V0fSBhbmQge0Bjb2RlIHNldH0gb24gdGhlIHNhbWUgdXBkYXRlci4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKiBAcGFyYW0gPFQ+IFRoZSB0eXBlIG9mIHRoZSBvYmplY3QgaG9sZGluZyB0aGUgdXBkYXRhYmxlIGZpZWxkCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyAgQXRvbWljTG9uZ0ZpZWxkVXBkYXRlcjxUPiB7CisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbmQgcmV0dXJucyBhbiB1cGRhdGVyIGZvciBvYmplY3RzIHdpdGggdGhlIGdpdmVuIGZpZWxkLgorICAgICAqIFRoZSBDbGFzcyBhcmd1bWVudCBpcyBuZWVkZWQgdG8gY2hlY2sgdGhhdCByZWZsZWN0aXZlIHR5cGVzIGFuZAorICAgICAqIGdlbmVyaWMgdHlwZXMgbWF0Y2guCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGNsYXNzIHRoZSBjbGFzcyBvZiB0aGUgb2JqZWN0cyBob2xkaW5nIHRoZSBmaWVsZAorICAgICAqIEBwYXJhbSBmaWVsZE5hbWUgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGJlIHVwZGF0ZWQuCisgICAgICogQHJldHVybiB0aGUgdXBkYXRlcgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBmaWVsZCBpcyBub3QgYQorICAgICAqIHZvbGF0aWxlIGxvbmcgdHlwZS4KKyAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gd2l0aCBhIG5lc3RlZCByZWZsZWN0aW9uLWJhc2VkCisgICAgICogZXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBkb2VzIG5vdCBob2xkIGZpZWxkIG9yIGlzIHRoZSB3cm9uZyB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFU+IEF0b21pY0xvbmdGaWVsZFVwZGF0ZXI8VT4gbmV3VXBkYXRlcihDbGFzczxVPiB0Y2xhc3MsIFN0cmluZyBmaWVsZE5hbWUpIHsKKyAgICAgICAgaWYgKEF0b21pY0xvbmcuVk1fU1VQUE9SVFNfTE9OR19DQVMpCisgICAgICAgICAgICByZXR1cm4gbmV3IENBU1VwZGF0ZXI8VT4odGNsYXNzLCBmaWVsZE5hbWUpOworICAgICAgICBlbHNlCisgICAgICAgICAgICByZXR1cm4gbmV3IExvY2tlZFVwZGF0ZXI8VT4odGNsYXNzLCBmaWVsZE5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb3RlY3RlZCBkby1ub3RoaW5nIGNvbnN0cnVjdG9yIGZvciB1c2UgYnkgc3ViY2xhc3Nlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQXRvbWljTG9uZ0ZpZWxkVXBkYXRlcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdGhlIGZpZWxkIG9mIHRoZSBnaXZlbiBvYmplY3QgbWFuYWdlZCBieSB0aGlzIHVwZGF0ZXIKKyAgICAgKiB0byB0aGUgZ2l2ZW4gdXBkYXRlZCB2YWx1ZSBpZiB0aGUgY3VycmVudCB2YWx1ZSB7QGNvZGUgPT19IHRoZQorICAgICAqIGV4cGVjdGVkIHZhbHVlLiBUaGlzIG1ldGhvZCBpcyBndWFyYW50ZWVkIHRvIGJlIGF0b21pYyB3aXRoIHJlc3BlY3QgdG8KKyAgICAgKiBvdGhlciBjYWxscyB0byB7QGNvZGUgY29tcGFyZUFuZFNldH0gYW5kIHtAY29kZSBzZXR9LCBidXQgbm90CisgICAgICogbmVjZXNzYXJpbHkgd2l0aCByZXNwZWN0IHRvIG90aGVyIGNoYW5nZXMgaW4gdGhlIGZpZWxkLgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBBbiBvYmplY3Qgd2hvc2UgZmllbGQgdG8gY29uZGl0aW9uYWxseSBzZXQKKyAgICAgKiBAcGFyYW0gZXhwZWN0IHRoZSBleHBlY3RlZCB2YWx1ZQorICAgICAqIEBwYXJhbSB1cGRhdGUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIHtAY29kZSBvYmp9IGlzIG5vdCBhbiBpbnN0YW5jZQorICAgICAqIG9mIHRoZSBjbGFzcyBwb3NzZXNzaW5nIHRoZSBmaWVsZCBlc3RhYmxpc2hlZCBpbiB0aGUgY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gY29tcGFyZUFuZFNldChUIG9iaiwgbG9uZyBleHBlY3QsIGxvbmcgdXBkYXRlKTsKKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgc2V0cyB0aGUgZmllbGQgb2YgdGhlIGdpdmVuIG9iamVjdCBtYW5hZ2VkIGJ5IHRoaXMgdXBkYXRlcgorICAgICAqIHRvIHRoZSBnaXZlbiB1cGRhdGVkIHZhbHVlIGlmIHRoZSBjdXJyZW50IHZhbHVlIHtAY29kZSA9PX0gdGhlCisgICAgICogZXhwZWN0ZWQgdmFsdWUuIFRoaXMgbWV0aG9kIGlzIGd1YXJhbnRlZWQgdG8gYmUgYXRvbWljIHdpdGggcmVzcGVjdCB0bworICAgICAqIG90aGVyIGNhbGxzIHRvIHtAY29kZSBjb21wYXJlQW5kU2V0fSBhbmQge0Bjb2RlIHNldH0sIGJ1dCBub3QKKyAgICAgKiBuZWNlc3NhcmlseSB3aXRoIHJlc3BlY3QgdG8gb3RoZXIgY2hhbmdlcyBpbiB0aGUgZmllbGQuCisgICAgICoKKyAgICAgKiA8cD5NYXkgPGEgaHJlZj0icGFja2FnZS1zdW1tYXJ5Lmh0bWwjU3B1cmlvdXMiPmZhaWwgc3B1cmlvdXNseTwvYT4KKyAgICAgKiBhbmQgZG9lcyBub3QgcHJvdmlkZSBvcmRlcmluZyBndWFyYW50ZWVzLCBzbyBpcyBvbmx5IHJhcmVseSBhbgorICAgICAqIGFwcHJvcHJpYXRlIGFsdGVybmF0aXZlIHRvIHtAY29kZSBjb21wYXJlQW5kU2V0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmogQW4gb2JqZWN0IHdob3NlIGZpZWxkIHRvIGNvbmRpdGlvbmFsbHkgc2V0CisgICAgICogQHBhcmFtIGV4cGVjdCB0aGUgZXhwZWN0ZWQgdmFsdWUKKyAgICAgKiBAcGFyYW0gdXBkYXRlIHRoZSBuZXcgdmFsdWUKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgc3VjY2Vzc2Z1bC4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB7QGNvZGUgb2JqfSBpcyBub3QgYW4gaW5zdGFuY2UKKyAgICAgKiBvZiB0aGUgY2xhc3MgcG9zc2Vzc2luZyB0aGUgZmllbGQgZXN0YWJsaXNoZWQgaW4gdGhlIGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIHdlYWtDb21wYXJlQW5kU2V0KFQgb2JqLCBsb25nIGV4cGVjdCwgbG9uZyB1cGRhdGUpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZmllbGQgb2YgdGhlIGdpdmVuIG9iamVjdCBtYW5hZ2VkIGJ5IHRoaXMgdXBkYXRlciB0byB0aGUKKyAgICAgKiBnaXZlbiB1cGRhdGVkIHZhbHVlLiBUaGlzIG9wZXJhdGlvbiBpcyBndWFyYW50ZWVkIHRvIGFjdCBhcyBhIHZvbGF0aWxlCisgICAgICogc3RvcmUgd2l0aCByZXNwZWN0IHRvIHN1YnNlcXVlbnQgaW52b2NhdGlvbnMgb2Yge0Bjb2RlIGNvbXBhcmVBbmRTZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBBbiBvYmplY3Qgd2hvc2UgZmllbGQgdG8gc2V0CisgICAgICogQHBhcmFtIG5ld1ZhbHVlIHRoZSBuZXcgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXQoVCBvYmosIGxvbmcgbmV3VmFsdWUpOworCisgICAgLyoqCisgICAgICogRXZlbnR1YWxseSBzZXRzIHRoZSBmaWVsZCBvZiB0aGUgZ2l2ZW4gb2JqZWN0IG1hbmFnZWQgYnkgdGhpcworICAgICAqIHVwZGF0ZXIgdG8gdGhlIGdpdmVuIHVwZGF0ZWQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIEFuIG9iamVjdCB3aG9zZSBmaWVsZCB0byBzZXQKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBsYXp5U2V0KFQgb2JqLCBsb25nIG5ld1ZhbHVlKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGN1cnJlbnQgdmFsdWUgaGVsZCBpbiB0aGUgZmllbGQgb2YgdGhlIGdpdmVuIG9iamVjdCBtYW5hZ2VkCisgICAgICogYnkgdGhpcyB1cGRhdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBBbiBvYmplY3Qgd2hvc2UgZmllbGQgdG8gZ2V0CisgICAgICogQHJldHVybiB0aGUgY3VycmVudCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBsb25nIGdldChUIG9iaik7CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdGhlIGZpZWxkIG9mIHRoZSBnaXZlbiBvYmplY3QgbWFuYWdlZCBieSB0aGlzIHVwZGF0ZXIKKyAgICAgKiB0byB0aGUgZ2l2ZW4gdmFsdWUgYW5kIHJldHVybnMgdGhlIG9sZCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmogQW4gb2JqZWN0IHdob3NlIGZpZWxkIHRvIGdldCBhbmQgc2V0CisgICAgICogQHBhcmFtIG5ld1ZhbHVlIHRoZSBuZXcgdmFsdWUKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldEFuZFNldChUIG9iaiwgbG9uZyBuZXdWYWx1ZSkgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBsb25nIGN1cnJlbnQgPSBnZXQob2JqKTsKKyAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0KG9iaiwgY3VycmVudCwgbmV3VmFsdWUpKQorICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBpbmNyZW1lbnRzIGJ5IG9uZSB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZmllbGQgb2YgdGhlCisgICAgICogZ2l2ZW4gb2JqZWN0IG1hbmFnZWQgYnkgdGhpcyB1cGRhdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBBbiBvYmplY3Qgd2hvc2UgZmllbGQgdG8gZ2V0IGFuZCBzZXQKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldEFuZEluY3JlbWVudChUIG9iaikgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBsb25nIGN1cnJlbnQgPSBnZXQob2JqKTsKKyAgICAgICAgICAgIGxvbmcgbmV4dCA9IGN1cnJlbnQgKyAxOworICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXQob2JqLCBjdXJyZW50LCBuZXh0KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgZGVjcmVtZW50cyBieSBvbmUgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGZpZWxkIG9mIHRoZQorICAgICAqIGdpdmVuIG9iamVjdCBtYW5hZ2VkIGJ5IHRoaXMgdXBkYXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmogQW4gb2JqZWN0IHdob3NlIGZpZWxkIHRvIGdldCBhbmQgc2V0CisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRBbmREZWNyZW1lbnQoVCBvYmopIHsKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgbG9uZyBjdXJyZW50ID0gZ2V0KG9iaik7CisgICAgICAgICAgICBsb25nIG5leHQgPSBjdXJyZW50IC0gMTsKKyAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0KG9iaiwgY3VycmVudCwgbmV4dCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IGFkZHMgdGhlIGdpdmVuIHZhbHVlIHRvIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBmaWVsZCBvZgorICAgICAqIHRoZSBnaXZlbiBvYmplY3QgbWFuYWdlZCBieSB0aGlzIHVwZGF0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIEFuIG9iamVjdCB3aG9zZSBmaWVsZCB0byBnZXQgYW5kIHNldAorICAgICAqIEBwYXJhbSBkZWx0YSB0aGUgdmFsdWUgdG8gYWRkCisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRBbmRBZGQoVCBvYmosIGxvbmcgZGVsdGEpIHsKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgbG9uZyBjdXJyZW50ID0gZ2V0KG9iaik7CisgICAgICAgICAgICBsb25nIG5leHQgPSBjdXJyZW50ICsgZGVsdGE7CisgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldChvYmosIGN1cnJlbnQsIG5leHQpKQorICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBpbmNyZW1lbnRzIGJ5IG9uZSB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZmllbGQgb2YgdGhlCisgICAgICogZ2l2ZW4gb2JqZWN0IG1hbmFnZWQgYnkgdGhpcyB1cGRhdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBBbiBvYmplY3Qgd2hvc2UgZmllbGQgdG8gZ2V0IGFuZCBzZXQKKyAgICAgKiBAcmV0dXJuIHRoZSB1cGRhdGVkIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGxvbmcgaW5jcmVtZW50QW5kR2V0KFQgb2JqKSB7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIGxvbmcgY3VycmVudCA9IGdldChvYmopOworICAgICAgICAgICAgbG9uZyBuZXh0ID0gY3VycmVudCArIDE7CisgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldChvYmosIGN1cnJlbnQsIG5leHQpKQorICAgICAgICAgICAgICAgIHJldHVybiBuZXh0OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBkZWNyZW1lbnRzIGJ5IG9uZSB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZmllbGQgb2YgdGhlCisgICAgICogZ2l2ZW4gb2JqZWN0IG1hbmFnZWQgYnkgdGhpcyB1cGRhdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBBbiBvYmplY3Qgd2hvc2UgZmllbGQgdG8gZ2V0IGFuZCBzZXQKKyAgICAgKiBAcmV0dXJuIHRoZSB1cGRhdGVkIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGxvbmcgZGVjcmVtZW50QW5kR2V0KFQgb2JqKSB7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIGxvbmcgY3VycmVudCA9IGdldChvYmopOworICAgICAgICAgICAgbG9uZyBuZXh0ID0gY3VycmVudCAtIDE7CisgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldChvYmosIGN1cnJlbnQsIG5leHQpKQorICAgICAgICAgICAgICAgIHJldHVybiBuZXh0OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBhZGRzIHRoZSBnaXZlbiB2YWx1ZSB0byB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZmllbGQgb2YKKyAgICAgKiB0aGUgZ2l2ZW4gb2JqZWN0IG1hbmFnZWQgYnkgdGhpcyB1cGRhdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBBbiBvYmplY3Qgd2hvc2UgZmllbGQgdG8gZ2V0IGFuZCBzZXQKKyAgICAgKiBAcGFyYW0gZGVsdGEgdGhlIHZhbHVlIHRvIGFkZAorICAgICAqIEByZXR1cm4gdGhlIHVwZGF0ZWQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBhZGRBbmRHZXQoVCBvYmosIGxvbmcgZGVsdGEpIHsKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgbG9uZyBjdXJyZW50ID0gZ2V0KG9iaik7CisgICAgICAgICAgICBsb25nIG5leHQgPSBjdXJyZW50ICsgZGVsdGE7CisgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldChvYmosIGN1cnJlbnQsIG5leHQpKQorICAgICAgICAgICAgICAgIHJldHVybiBuZXh0OworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQ0FTVXBkYXRlcjxUPiBleHRlbmRzIEF0b21pY0xvbmdGaWVsZFVwZGF0ZXI8VD4geworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBVbnNhZmUgdW5zYWZlID0gVW5zYWZlQWNjZXNzLlRIRV9PTkU7IC8vIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICBwcml2YXRlIGZpbmFsIGxvbmcgb2Zmc2V0OworICAgICAgICBwcml2YXRlIGZpbmFsIENsYXNzPFQ+IHRjbGFzczsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBDbGFzcyBjY2xhc3M7CisKKyAgICAgICAgQ0FTVXBkYXRlcihDbGFzczxUPiB0Y2xhc3MsIFN0cmluZyBmaWVsZE5hbWUpIHsKKyAgICAgICAgICAgIEZpZWxkIGZpZWxkID0gbnVsbDsKKyAgICAgICAgICAgIENsYXNzIGNhbGxlciA9IG51bGw7CisgICAgICAgICAgICBpbnQgbW9kaWZpZXJzID0gMDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZmllbGQgPSB0Y2xhc3MuZ2V0RGVjbGFyZWRGaWVsZChmaWVsZE5hbWUpOworICAgICAgICAgICAgICAgIGNhbGxlciA9IFZNU3RhY2suZ2V0U3RhY2tDbGFzczIoKTsgLy8gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgICAgICAgICAgbW9kaWZpZXJzID0gZmllbGQuZ2V0TW9kaWZpZXJzKCk7CisgICAgICAgICAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1yZW1vdmVkCisgICAgICAgICAgICAgICAgLy8gc3VuLnJlZmxlY3QubWlzYy5SZWZsZWN0VXRpbC5lbnN1cmVNZW1iZXJBY2Nlc3MoCisgICAgICAgICAgICAgICAgLy8gICAgIGNhbGxlciwgdGNsYXNzLCBudWxsLCBtb2RpZmllcnMpOworICAgICAgICAgICAgICAgIC8vIHN1bi5yZWZsZWN0Lm1pc2MuUmVmbGVjdFV0aWwuY2hlY2tQYWNrYWdlQWNjZXNzKHRjbGFzcyk7CisgICAgICAgICAgICAgICAgLy8gRU5EIGFuZHJvaWQtcmVtb3ZlZAorICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZXgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBDbGFzcyBmaWVsZHQgPSBmaWVsZC5nZXRUeXBlKCk7CisgICAgICAgICAgICBpZiAoZmllbGR0ICE9IGxvbmcuY2xhc3MpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTXVzdCBiZSBsb25nIHR5cGUiKTsKKworICAgICAgICAgICAgaWYgKCFNb2RpZmllci5pc1ZvbGF0aWxlKG1vZGlmaWVycykpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTXVzdCBiZSB2b2xhdGlsZSB0eXBlIik7CisKKyAgICAgICAgICAgIHRoaXMuY2NsYXNzID0gKE1vZGlmaWVyLmlzUHJvdGVjdGVkKG1vZGlmaWVycykgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxlciAhPSB0Y2xhc3MpID8gY2FsbGVyIDogbnVsbDsKKyAgICAgICAgICAgIHRoaXMudGNsYXNzID0gdGNsYXNzOworICAgICAgICAgICAgb2Zmc2V0ID0gdW5zYWZlLm9iamVjdEZpZWxkT2Zmc2V0KGZpZWxkKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCBmdWxsQ2hlY2soVCBvYmopIHsKKyAgICAgICAgICAgIGlmICghdGNsYXNzLmlzSW5zdGFuY2Uob2JqKSkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xhc3NDYXN0RXhjZXB0aW9uKCk7CisgICAgICAgICAgICBpZiAoY2NsYXNzICE9IG51bGwpCisgICAgICAgICAgICAgICAgZW5zdXJlUHJvdGVjdGVkQWNjZXNzKG9iaik7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb21wYXJlQW5kU2V0KFQgb2JqLCBsb25nIGV4cGVjdCwgbG9uZyB1cGRhdGUpIHsKKyAgICAgICAgICAgIGlmIChvYmogPT0gbnVsbCB8fCBvYmouZ2V0Q2xhc3MoKSAhPSB0Y2xhc3MgfHwgY2NsYXNzICE9IG51bGwpIGZ1bGxDaGVjayhvYmopOworICAgICAgICAgICAgcmV0dXJuIHVuc2FmZS5jb21wYXJlQW5kU3dhcExvbmcob2JqLCBvZmZzZXQsIGV4cGVjdCwgdXBkYXRlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIHdlYWtDb21wYXJlQW5kU2V0KFQgb2JqLCBsb25nIGV4cGVjdCwgbG9uZyB1cGRhdGUpIHsKKyAgICAgICAgICAgIGlmIChvYmogPT0gbnVsbCB8fCBvYmouZ2V0Q2xhc3MoKSAhPSB0Y2xhc3MgfHwgY2NsYXNzICE9IG51bGwpIGZ1bGxDaGVjayhvYmopOworICAgICAgICAgICAgcmV0dXJuIHVuc2FmZS5jb21wYXJlQW5kU3dhcExvbmcob2JqLCBvZmZzZXQsIGV4cGVjdCwgdXBkYXRlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldChUIG9iaiwgbG9uZyBuZXdWYWx1ZSkgeworICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsIHx8IG9iai5nZXRDbGFzcygpICE9IHRjbGFzcyB8fCBjY2xhc3MgIT0gbnVsbCkgZnVsbENoZWNrKG9iaik7CisgICAgICAgICAgICB1bnNhZmUucHV0TG9uZ1ZvbGF0aWxlKG9iaiwgb2Zmc2V0LCBuZXdWYWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBsYXp5U2V0KFQgb2JqLCBsb25nIG5ld1ZhbHVlKSB7CisgICAgICAgICAgICBpZiAob2JqID09IG51bGwgfHwgb2JqLmdldENsYXNzKCkgIT0gdGNsYXNzIHx8IGNjbGFzcyAhPSBudWxsKSBmdWxsQ2hlY2sob2JqKTsKKyAgICAgICAgICAgIHVuc2FmZS5wdXRPcmRlcmVkTG9uZyhvYmosIG9mZnNldCwgbmV3VmFsdWUpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGxvbmcgZ2V0KFQgb2JqKSB7CisgICAgICAgICAgICBpZiAob2JqID09IG51bGwgfHwgb2JqLmdldENsYXNzKCkgIT0gdGNsYXNzIHx8IGNjbGFzcyAhPSBudWxsKSBmdWxsQ2hlY2sob2JqKTsKKyAgICAgICAgICAgIHJldHVybiB1bnNhZmUuZ2V0TG9uZ1ZvbGF0aWxlKG9iaiwgb2Zmc2V0KTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQcm90ZWN0ZWRBY2Nlc3MoVCBvYmopIHsKKyAgICAgICAgICAgIGlmIChjY2xhc3MuaXNJbnN0YW5jZShvYmopKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgbmV3IElsbGVnYWxBY2Nlc3NFeGNlcHRpb24oIkNsYXNzICIgKworICAgICAgICAgICAgICAgICAgICBjY2xhc3MuZ2V0TmFtZSgpICsKKyAgICAgICAgICAgICAgICAgICAgIiBjYW4gbm90IGFjY2VzcyBhIHByb3RlY3RlZCBtZW1iZXIgb2YgY2xhc3MgIiArCisgICAgICAgICAgICAgICAgICAgIHRjbGFzcy5nZXROYW1lKCkgKworICAgICAgICAgICAgICAgICAgICAiIHVzaW5nIGFuIGluc3RhbmNlIG9mICIgKworICAgICAgICAgICAgICAgICAgICBvYmouZ2V0Q2xhc3MoKS5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICApCisgICAgICAgICAgICApOworICAgICAgICB9CisgICAgfQorCisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBMb2NrZWRVcGRhdGVyPFQ+IGV4dGVuZHMgQXRvbWljTG9uZ0ZpZWxkVXBkYXRlcjxUPiB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFVuc2FmZSB1bnNhZmUgPSBVbnNhZmVBY2Nlc3MuVEhFX09ORTsgLy8gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIHByaXZhdGUgZmluYWwgbG9uZyBvZmZzZXQ7CisgICAgICAgIHByaXZhdGUgZmluYWwgQ2xhc3M8VD4gdGNsYXNzOworICAgICAgICBwcml2YXRlIGZpbmFsIENsYXNzIGNjbGFzczsKKworICAgICAgICBMb2NrZWRVcGRhdGVyKENsYXNzPFQ+IHRjbGFzcywgU3RyaW5nIGZpZWxkTmFtZSkgeworICAgICAgICAgICAgRmllbGQgZmllbGQgPSBudWxsOworICAgICAgICAgICAgQ2xhc3MgY2FsbGVyID0gbnVsbDsKKyAgICAgICAgICAgIGludCBtb2RpZmllcnMgPSAwOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmaWVsZCA9IHRjbGFzcy5nZXREZWNsYXJlZEZpZWxkKGZpZWxkTmFtZSk7CisgICAgICAgICAgICAgICAgY2FsbGVyID0gVk1TdGFjay5nZXRTdGFja0NsYXNzMigpOyAvLyBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgICAgICAgICBtb2RpZmllcnMgPSBmaWVsZC5nZXRNb2RpZmllcnMoKTsKKyAgICAgICAgICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLXJlbW92ZWQKKyAgICAgICAgICAgICAgICAvLyBzdW4ucmVmbGVjdC5taXNjLlJlZmxlY3RVdGlsLmVuc3VyZU1lbWJlckFjY2VzcygKKyAgICAgICAgICAgICAgICAvLyAgICAgY2FsbGVyLCB0Y2xhc3MsIG51bGwsIG1vZGlmaWVycyk7CisgICAgICAgICAgICAgICAgLy8gc3VuLnJlZmxlY3QubWlzYy5SZWZsZWN0VXRpbC5jaGVja1BhY2thZ2VBY2Nlc3ModGNsYXNzKTsKKyAgICAgICAgICAgICAgICAvLyBFTkQgYW5kcm9pZC1yZW1vdmVkCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihleCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIENsYXNzIGZpZWxkdCA9IGZpZWxkLmdldFR5cGUoKTsKKyAgICAgICAgICAgIGlmIChmaWVsZHQgIT0gbG9uZy5jbGFzcykKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJNdXN0IGJlIGxvbmcgdHlwZSIpOworCisgICAgICAgICAgICBpZiAoIU1vZGlmaWVyLmlzVm9sYXRpbGUobW9kaWZpZXJzKSkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJNdXN0IGJlIHZvbGF0aWxlIHR5cGUiKTsKKworICAgICAgICAgICAgdGhpcy5jY2xhc3MgPSAoTW9kaWZpZXIuaXNQcm90ZWN0ZWQobW9kaWZpZXJzKSAmJgorICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGVyICE9IHRjbGFzcykgPyBjYWxsZXIgOiBudWxsOworICAgICAgICAgICAgdGhpcy50Y2xhc3MgPSB0Y2xhc3M7CisgICAgICAgICAgICBvZmZzZXQgPSB1bnNhZmUub2JqZWN0RmllbGRPZmZzZXQoZmllbGQpOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSB2b2lkIGZ1bGxDaGVjayhUIG9iaikgeworICAgICAgICAgICAgaWYgKCF0Y2xhc3MuaXNJbnN0YW5jZShvYmopKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc0Nhc3RFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGlmIChjY2xhc3MgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICBlbnN1cmVQcm90ZWN0ZWRBY2Nlc3Mob2JqKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbXBhcmVBbmRTZXQoVCBvYmosIGxvbmcgZXhwZWN0LCBsb25nIHVwZGF0ZSkgeworICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsIHx8IG9iai5nZXRDbGFzcygpICE9IHRjbGFzcyB8fCBjY2xhc3MgIT0gbnVsbCkgZnVsbENoZWNrKG9iaik7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgICAgICBsb25nIHYgPSB1bnNhZmUuZ2V0TG9uZyhvYmosIG9mZnNldCk7CisgICAgICAgICAgICAgICAgaWYgKHYgIT0gZXhwZWN0KQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgdW5zYWZlLnB1dExvbmcob2JqLCBvZmZzZXQsIHVwZGF0ZSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiB3ZWFrQ29tcGFyZUFuZFNldChUIG9iaiwgbG9uZyBleHBlY3QsIGxvbmcgdXBkYXRlKSB7CisgICAgICAgICAgICByZXR1cm4gY29tcGFyZUFuZFNldChvYmosIGV4cGVjdCwgdXBkYXRlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldChUIG9iaiwgbG9uZyBuZXdWYWx1ZSkgeworICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsIHx8IG9iai5nZXRDbGFzcygpICE9IHRjbGFzcyB8fCBjY2xhc3MgIT0gbnVsbCkgZnVsbENoZWNrKG9iaik7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgICAgICB1bnNhZmUucHV0TG9uZyhvYmosIG9mZnNldCwgbmV3VmFsdWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgbGF6eVNldChUIG9iaiwgbG9uZyBuZXdWYWx1ZSkgeworICAgICAgICAgICAgc2V0KG9iaiwgbmV3VmFsdWUpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGxvbmcgZ2V0KFQgb2JqKSB7CisgICAgICAgICAgICBpZiAob2JqID09IG51bGwgfHwgb2JqLmdldENsYXNzKCkgIT0gdGNsYXNzIHx8IGNjbGFzcyAhPSBudWxsKSBmdWxsQ2hlY2sob2JqKTsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgICAgIHJldHVybiB1bnNhZmUuZ2V0TG9uZyhvYmosIG9mZnNldCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUHJvdGVjdGVkQWNjZXNzKFQgb2JqKSB7CisgICAgICAgICAgICBpZiAoY2NsYXNzLmlzSW5zdGFuY2Uob2JqKSkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgIG5ldyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uKCJDbGFzcyAiICsKKyAgICAgICAgICAgICAgICAgICAgY2NsYXNzLmdldE5hbWUoKSArCisgICAgICAgICAgICAgICAgICAgICIgY2FuIG5vdCBhY2Nlc3MgYSBwcm90ZWN0ZWQgbWVtYmVyIG9mIGNsYXNzICIgKworICAgICAgICAgICAgICAgICAgICB0Y2xhc3MuZ2V0TmFtZSgpICsKKyAgICAgICAgICAgICAgICAgICAgIiB1c2luZyBhbiBpbnN0YW5jZSBvZiAiICsKKyAgICAgICAgICAgICAgICAgICAgb2JqLmdldENsYXNzKCkuZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgKQorICAgICAgICAgICAgKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvQXRvbWljTWFya2FibGVSZWZlcmVuY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvQXRvbWljTWFya2FibGVSZWZlcmVuY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42M2Y0NmQ2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2F0b21pYy9BdG9taWNNYXJrYWJsZVJlZmVyZW5jZS5qYXZhCkBAIC0wLDAgKzEsMTg1IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljOworCitpbXBvcnQgc3VuLm1pc2MuVW5zYWZlOworCisvKioKKyAqIEFuIHtAY29kZSBBdG9taWNNYXJrYWJsZVJlZmVyZW5jZX0gbWFpbnRhaW5zIGFuIG9iamVjdCByZWZlcmVuY2UKKyAqIGFsb25nIHdpdGggYSBtYXJrIGJpdCwgdGhhdCBjYW4gYmUgdXBkYXRlZCBhdG9taWNhbGx5LgorICoKKyAqIDxwPkltcGxlbWVudGF0aW9uIG5vdGU6IFRoaXMgaW1wbGVtZW50YXRpb24gbWFpbnRhaW5zIG1hcmthYmxlCisgKiByZWZlcmVuY2VzIGJ5IGNyZWF0aW5nIGludGVybmFsIG9iamVjdHMgcmVwcmVzZW50aW5nICJib3hlZCIKKyAqIFtyZWZlcmVuY2UsIGJvb2xlYW5dIHBhaXJzLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqIEBwYXJhbSA8Vj4gVGhlIHR5cGUgb2Ygb2JqZWN0IHJlZmVycmVkIHRvIGJ5IHRoaXMgcmVmZXJlbmNlCisgKi8KK3B1YmxpYyBjbGFzcyBBdG9taWNNYXJrYWJsZVJlZmVyZW5jZTxWPiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBQYWlyPFQ+IHsKKyAgICAgICAgZmluYWwgVCByZWZlcmVuY2U7CisgICAgICAgIGZpbmFsIGJvb2xlYW4gbWFyazsKKyAgICAgICAgcHJpdmF0ZSBQYWlyKFQgcmVmZXJlbmNlLCBib29sZWFuIG1hcmspIHsKKyAgICAgICAgICAgIHRoaXMucmVmZXJlbmNlID0gcmVmZXJlbmNlOworICAgICAgICAgICAgdGhpcy5tYXJrID0gbWFyazsKKyAgICAgICAgfQorICAgICAgICBzdGF0aWMgPFQ+IFBhaXI8VD4gb2YoVCByZWZlcmVuY2UsIGJvb2xlYW4gbWFyaykgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBQYWlyPFQ+KHJlZmVyZW5jZSwgbWFyayk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvbGF0aWxlIFBhaXI8Vj4gcGFpcjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEF0b21pY01hcmthYmxlUmVmZXJlbmNlfSB3aXRoIHRoZSBnaXZlbgorICAgICAqIGluaXRpYWwgdmFsdWVzLgorICAgICAqCisgICAgICogQHBhcmFtIGluaXRpYWxSZWYgdGhlIGluaXRpYWwgcmVmZXJlbmNlCisgICAgICogQHBhcmFtIGluaXRpYWxNYXJrIHRoZSBpbml0aWFsIG1hcmsKKyAgICAgKi8KKyAgICBwdWJsaWMgQXRvbWljTWFya2FibGVSZWZlcmVuY2UoViBpbml0aWFsUmVmLCBib29sZWFuIGluaXRpYWxNYXJrKSB7CisgICAgICAgIHBhaXIgPSBQYWlyLm9mKGluaXRpYWxSZWYsIGluaXRpYWxNYXJrKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSByZWZlcmVuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSByZWZlcmVuY2UKKyAgICAgKi8KKyAgICBwdWJsaWMgViBnZXRSZWZlcmVuY2UoKSB7CisgICAgICAgIHJldHVybiBwYWlyLnJlZmVyZW5jZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBtYXJrLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgbWFyaworICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzTWFya2VkKCkgeworICAgICAgICByZXR1cm4gcGFpci5tYXJrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgdmFsdWVzIG9mIGJvdGggdGhlIHJlZmVyZW5jZSBhbmQgdGhlIG1hcmsuCisgICAgICogVHlwaWNhbCB1c2FnZSBpcyB7QGNvZGUgYm9vbGVhblsxXSBob2xkZXI7IHJlZiA9IHYuZ2V0KGhvbGRlcik7IH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWFya0hvbGRlciBhbiBhcnJheSBvZiBzaXplIG9mIGF0IGxlYXN0IG9uZS4gT24gcmV0dXJuLAorICAgICAqIHtAY29kZSBtYXJraG9sZGVyWzBdfSB3aWxsIGhvbGQgdGhlIHZhbHVlIG9mIHRoZSBtYXJrLgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHJlZmVyZW5jZQorICAgICAqLworICAgIHB1YmxpYyBWIGdldChib29sZWFuW10gbWFya0hvbGRlcikgeworICAgICAgICBQYWlyPFY+IHBhaXIgPSB0aGlzLnBhaXI7CisgICAgICAgIG1hcmtIb2xkZXJbMF0gPSBwYWlyLm1hcms7CisgICAgICAgIHJldHVybiBwYWlyLnJlZmVyZW5jZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdGhlIHZhbHVlIG9mIGJvdGggdGhlIHJlZmVyZW5jZSBhbmQgbWFyaworICAgICAqIHRvIHRoZSBnaXZlbiB1cGRhdGUgdmFsdWVzIGlmIHRoZQorICAgICAqIGN1cnJlbnQgcmVmZXJlbmNlIGlzIHtAY29kZSA9PX0gdG8gdGhlIGV4cGVjdGVkIHJlZmVyZW5jZQorICAgICAqIGFuZCB0aGUgY3VycmVudCBtYXJrIGlzIGVxdWFsIHRvIHRoZSBleHBlY3RlZCBtYXJrLgorICAgICAqCisgICAgICogPHA+TWF5IDxhIGhyZWY9InBhY2thZ2Utc3VtbWFyeS5odG1sI1NwdXJpb3VzIj5mYWlsIHNwdXJpb3VzbHk8L2E+CisgICAgICogYW5kIGRvZXMgbm90IHByb3ZpZGUgb3JkZXJpbmcgZ3VhcmFudGVlcywgc28gaXMgb25seSByYXJlbHkgYW4KKyAgICAgKiBhcHByb3ByaWF0ZSBhbHRlcm5hdGl2ZSB0byB7QGNvZGUgY29tcGFyZUFuZFNldH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWRSZWZlcmVuY2UgdGhlIGV4cGVjdGVkIHZhbHVlIG9mIHRoZSByZWZlcmVuY2UKKyAgICAgKiBAcGFyYW0gbmV3UmVmZXJlbmNlIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSByZWZlcmVuY2UKKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWRNYXJrIHRoZSBleHBlY3RlZCB2YWx1ZSBvZiB0aGUgbWFyaworICAgICAqIEBwYXJhbSBuZXdNYXJrIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBtYXJrCisgICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB3ZWFrQ29tcGFyZUFuZFNldChWICAgICAgIGV4cGVjdGVkUmVmZXJlbmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFYgICAgICAgbmV3UmVmZXJlbmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZXhwZWN0ZWRNYXJrLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gbmV3TWFyaykgeworICAgICAgICByZXR1cm4gY29tcGFyZUFuZFNldChleHBlY3RlZFJlZmVyZW5jZSwgbmV3UmVmZXJlbmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RlZE1hcmssIG5ld01hcmspOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgc2V0cyB0aGUgdmFsdWUgb2YgYm90aCB0aGUgcmVmZXJlbmNlIGFuZCBtYXJrCisgICAgICogdG8gdGhlIGdpdmVuIHVwZGF0ZSB2YWx1ZXMgaWYgdGhlCisgICAgICogY3VycmVudCByZWZlcmVuY2UgaXMge0Bjb2RlID09fSB0byB0aGUgZXhwZWN0ZWQgcmVmZXJlbmNlCisgICAgICogYW5kIHRoZSBjdXJyZW50IG1hcmsgaXMgZXF1YWwgdG8gdGhlIGV4cGVjdGVkIG1hcmsuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWRSZWZlcmVuY2UgdGhlIGV4cGVjdGVkIHZhbHVlIG9mIHRoZSByZWZlcmVuY2UKKyAgICAgKiBAcGFyYW0gbmV3UmVmZXJlbmNlIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSByZWZlcmVuY2UKKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWRNYXJrIHRoZSBleHBlY3RlZCB2YWx1ZSBvZiB0aGUgbWFyaworICAgICAqIEBwYXJhbSBuZXdNYXJrIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBtYXJrCisgICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb21wYXJlQW5kU2V0KFYgICAgICAgZXhwZWN0ZWRSZWZlcmVuY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWICAgICAgIG5ld1JlZmVyZW5jZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZXhwZWN0ZWRNYXJrLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBuZXdNYXJrKSB7CisgICAgICAgIFBhaXI8Vj4gY3VycmVudCA9IHBhaXI7CisgICAgICAgIHJldHVybgorICAgICAgICAgICAgZXhwZWN0ZWRSZWZlcmVuY2UgPT0gY3VycmVudC5yZWZlcmVuY2UgJiYKKyAgICAgICAgICAgIGV4cGVjdGVkTWFyayA9PSBjdXJyZW50Lm1hcmsgJiYKKyAgICAgICAgICAgICgobmV3UmVmZXJlbmNlID09IGN1cnJlbnQucmVmZXJlbmNlICYmCisgICAgICAgICAgICAgIG5ld01hcmsgPT0gY3VycmVudC5tYXJrKSB8fAorICAgICAgICAgICAgIGNhc1BhaXIoY3VycmVudCwgUGFpci5vZihuZXdSZWZlcmVuY2UsIG5ld01hcmspKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVW5jb25kaXRpb25hbGx5IHNldHMgdGhlIHZhbHVlIG9mIGJvdGggdGhlIHJlZmVyZW5jZSBhbmQgbWFyay4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdSZWZlcmVuY2UgdGhlIG5ldyB2YWx1ZSBmb3IgdGhlIHJlZmVyZW5jZQorICAgICAqIEBwYXJhbSBuZXdNYXJrIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBtYXJrCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0KFYgbmV3UmVmZXJlbmNlLCBib29sZWFuIG5ld01hcmspIHsKKyAgICAgICAgUGFpcjxWPiBjdXJyZW50ID0gcGFpcjsKKyAgICAgICAgaWYgKG5ld1JlZmVyZW5jZSAhPSBjdXJyZW50LnJlZmVyZW5jZSB8fCBuZXdNYXJrICE9IGN1cnJlbnQubWFyaykKKyAgICAgICAgICAgIHRoaXMucGFpciA9IFBhaXIub2YobmV3UmVmZXJlbmNlLCBuZXdNYXJrKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdGhlIHZhbHVlIG9mIHRoZSBtYXJrIHRvIHRoZSBnaXZlbiB1cGRhdGUgdmFsdWUKKyAgICAgKiBpZiB0aGUgY3VycmVudCByZWZlcmVuY2UgaXMge0Bjb2RlID09fSB0byB0aGUgZXhwZWN0ZWQKKyAgICAgKiByZWZlcmVuY2UuICBBbnkgZ2l2ZW4gaW52b2NhdGlvbiBvZiB0aGlzIG9wZXJhdGlvbiBtYXkgZmFpbAorICAgICAqIChyZXR1cm4ge0Bjb2RlIGZhbHNlfSkgc3B1cmlvdXNseSwgYnV0IHJlcGVhdGVkIGludm9jYXRpb24KKyAgICAgKiB3aGVuIHRoZSBjdXJyZW50IHZhbHVlIGhvbGRzIHRoZSBleHBlY3RlZCB2YWx1ZSBhbmQgbm8gb3RoZXIKKyAgICAgKiB0aHJlYWQgaXMgYWxzbyBhdHRlbXB0aW5nIHRvIHNldCB0aGUgdmFsdWUgd2lsbCBldmVudHVhbGx5CisgICAgICogc3VjY2VlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleHBlY3RlZFJlZmVyZW5jZSB0aGUgZXhwZWN0ZWQgdmFsdWUgb2YgdGhlIHJlZmVyZW5jZQorICAgICAqIEBwYXJhbSBuZXdNYXJrIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBtYXJrCisgICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBhdHRlbXB0TWFyayhWIGV4cGVjdGVkUmVmZXJlbmNlLCBib29sZWFuIG5ld01hcmspIHsKKyAgICAgICAgUGFpcjxWPiBjdXJyZW50ID0gcGFpcjsKKyAgICAgICAgcmV0dXJuCisgICAgICAgICAgICBleHBlY3RlZFJlZmVyZW5jZSA9PSBjdXJyZW50LnJlZmVyZW5jZSAmJgorICAgICAgICAgICAgKG5ld01hcmsgPT0gY3VycmVudC5tYXJrIHx8CisgICAgICAgICAgICAgY2FzUGFpcihjdXJyZW50LCBQYWlyLm9mKGV4cGVjdGVkUmVmZXJlbmNlLCBuZXdNYXJrKSkpOworICAgIH0KKworICAgIC8vIFVuc2FmZSBtZWNoYW5pY3MKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHN1bi5taXNjLlVuc2FmZSBVTlNBRkUgPSBVbnNhZmVBY2Nlc3MuVEhFX09ORTsgLy8gYW5kcm9pZC1jaGFuZ2VkCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBwYWlyT2Zmc2V0ID0KKyAgICAgICAgb2JqZWN0RmllbGRPZmZzZXQoVU5TQUZFLCAicGFpciIsIEF0b21pY01hcmthYmxlUmVmZXJlbmNlLmNsYXNzKTsKKworICAgIHByaXZhdGUgYm9vbGVhbiBjYXNQYWlyKFBhaXI8Vj4gY21wLCBQYWlyPFY+IHZhbCkgeworICAgICAgICByZXR1cm4gVU5TQUZFLmNvbXBhcmVBbmRTd2FwT2JqZWN0KHRoaXMsIHBhaXJPZmZzZXQsIGNtcCwgdmFsKTsKKyAgICB9CisKKyAgICBzdGF0aWMgbG9uZyBvYmplY3RGaWVsZE9mZnNldChzdW4ubWlzYy5VbnNhZmUgVU5TQUZFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBmaWVsZCwgQ2xhc3M8Pz4ga2xhenopIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBVTlNBRkUub2JqZWN0RmllbGRPZmZzZXQoa2xhenouZ2V0RGVjbGFyZWRGaWVsZChmaWVsZCkpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hGaWVsZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb252ZXJ0IEV4Y2VwdGlvbiB0byBjb3JyZXNwb25kaW5nIEVycm9yCisgICAgICAgICAgICBOb1N1Y2hGaWVsZEVycm9yIGVycm9yID0gbmV3IE5vU3VjaEZpZWxkRXJyb3IoZmllbGQpOworICAgICAgICAgICAgZXJyb3IuaW5pdENhdXNlKGUpOworICAgICAgICAgICAgdGhyb3cgZXJyb3I7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvYXRvbWljL0F0b21pY1JlZmVyZW5jZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2F0b21pYy9BdG9taWNSZWZlcmVuY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMDQxYmJkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2F0b21pYy9BdG9taWNSZWZlcmVuY2UuamF2YQpAQCAtMCwwICsxLDEyNiBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYzsKK2ltcG9ydCBzdW4ubWlzYy5VbnNhZmU7CisKKy8qKgorICogQW4gb2JqZWN0IHJlZmVyZW5jZSB0aGF0IG1heSBiZSB1cGRhdGVkIGF0b21pY2FsbHkuIFNlZSB0aGUge0BsaW5rCisgKiBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWN9IHBhY2thZ2Ugc3BlY2lmaWNhdGlvbiBmb3IgZGVzY3JpcHRpb24KKyAqIG9mIHRoZSBwcm9wZXJ0aWVzIG9mIGF0b21pYyB2YXJpYWJsZXMuCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKiBAcGFyYW0gPFY+IFRoZSB0eXBlIG9mIG9iamVjdCByZWZlcnJlZCB0byBieSB0aGlzIHJlZmVyZW5jZQorICovCitwdWJsaWMgY2xhc3MgQXRvbWljUmVmZXJlbmNlPFY+ICBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTg0ODg4Mzk2NTIzMTM0NDQ0Mkw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBVbnNhZmUgdW5zYWZlID0gVW5zYWZlQWNjZXNzLlRIRV9PTkU7IC8vIGFuZHJvaWQtY2hhbmdlZAorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgdmFsdWVPZmZzZXQ7CisKKyAgICBzdGF0aWMgeworICAgICAgdHJ5IHsKKyAgICAgICAgdmFsdWVPZmZzZXQgPSB1bnNhZmUub2JqZWN0RmllbGRPZmZzZXQKKyAgICAgICAgICAgIChBdG9taWNSZWZlcmVuY2UuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgidmFsdWUiKSk7CisgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsgdGhyb3cgbmV3IEVycm9yKGV4KTsgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9sYXRpbGUgViB2YWx1ZTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgQXRvbWljUmVmZXJlbmNlIHdpdGggdGhlIGdpdmVuIGluaXRpYWwgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5pdGlhbFZhbHVlIHRoZSBpbml0aWFsIHZhbHVlCisgICAgICovCisgICAgcHVibGljIEF0b21pY1JlZmVyZW5jZShWIGluaXRpYWxWYWx1ZSkgeworICAgICAgICB2YWx1ZSA9IGluaXRpYWxWYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IEF0b21pY1JlZmVyZW5jZSB3aXRoIG51bGwgaW5pdGlhbCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXRvbWljUmVmZXJlbmNlKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGN1cnJlbnQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFYgZ2V0KCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0byB0aGUgZ2l2ZW4gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIG5ldyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldChWIG5ld1ZhbHVlKSB7CisgICAgICAgIHZhbHVlID0gbmV3VmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXZlbnR1YWxseSBzZXRzIHRvIHRoZSBnaXZlbiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdWYWx1ZSB0aGUgbmV3IHZhbHVlCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGxhenlTZXQoViBuZXdWYWx1ZSkgeworICAgICAgICB1bnNhZmUucHV0T3JkZXJlZE9iamVjdCh0aGlzLCB2YWx1ZU9mZnNldCwgbmV3VmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgc2V0cyB0aGUgdmFsdWUgdG8gdGhlIGdpdmVuIHVwZGF0ZWQgdmFsdWUKKyAgICAgKiBpZiB0aGUgY3VycmVudCB2YWx1ZSB7QGNvZGUgPT19IHRoZSBleHBlY3RlZCB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gZXhwZWN0IHRoZSBleHBlY3RlZCB2YWx1ZQorICAgICAqIEBwYXJhbSB1cGRhdGUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsLiBGYWxzZSByZXR1cm4gaW5kaWNhdGVzIHRoYXQKKyAgICAgKiB0aGUgYWN0dWFsIHZhbHVlIHdhcyBub3QgZXF1YWwgdG8gdGhlIGV4cGVjdGVkIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGNvbXBhcmVBbmRTZXQoViBleHBlY3QsIFYgdXBkYXRlKSB7CisgICAgICAgIHJldHVybiB1bnNhZmUuY29tcGFyZUFuZFN3YXBPYmplY3QodGhpcywgdmFsdWVPZmZzZXQsIGV4cGVjdCwgdXBkYXRlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdGhlIHZhbHVlIHRvIHRoZSBnaXZlbiB1cGRhdGVkIHZhbHVlCisgICAgICogaWYgdGhlIGN1cnJlbnQgdmFsdWUge0Bjb2RlID09fSB0aGUgZXhwZWN0ZWQgdmFsdWUuCisgICAgICoKKyAgICAgKiA8cD5NYXkgPGEgaHJlZj0icGFja2FnZS1zdW1tYXJ5Lmh0bWwjU3B1cmlvdXMiPmZhaWwgc3B1cmlvdXNseTwvYT4KKyAgICAgKiBhbmQgZG9lcyBub3QgcHJvdmlkZSBvcmRlcmluZyBndWFyYW50ZWVzLCBzbyBpcyBvbmx5IHJhcmVseSBhbgorICAgICAqIGFwcHJvcHJpYXRlIGFsdGVybmF0aXZlIHRvIHtAY29kZSBjb21wYXJlQW5kU2V0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleHBlY3QgdGhlIGV4cGVjdGVkIHZhbHVlCisgICAgICogQHBhcmFtIHVwZGF0ZSB0aGUgbmV3IHZhbHVlCisgICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gd2Vha0NvbXBhcmVBbmRTZXQoViBleHBlY3QsIFYgdXBkYXRlKSB7CisgICAgICAgIHJldHVybiB1bnNhZmUuY29tcGFyZUFuZFN3YXBPYmplY3QodGhpcywgdmFsdWVPZmZzZXQsIGV4cGVjdCwgdXBkYXRlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdG8gdGhlIGdpdmVuIHZhbHVlIGFuZCByZXR1cm5zIHRoZSBvbGQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFYgZ2V0QW5kU2V0KFYgbmV3VmFsdWUpIHsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIFYgeCA9IGdldCgpOworICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXQoeCwgbmV3VmFsdWUpKQorICAgICAgICAgICAgICAgIHJldHVybiB4OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjdXJyZW50IHZhbHVlLgorICAgICAqIEByZXR1cm4gdGhlIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY3VycmVudCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gU3RyaW5nLnZhbHVlT2YoZ2V0KCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2F0b21pYy9BdG9taWNSZWZlcmVuY2VBcnJheS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2F0b21pYy9BdG9taWNSZWZlcmVuY2VBcnJheS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiYzU4ODYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvYXRvbWljL0F0b21pY1JlZmVyZW5jZUFycmF5LmphdmEKQEAgLTAsMCArMSwxODQgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWM7CitpbXBvcnQgc3VuLm1pc2MuVW5zYWZlOworaW1wb3J0IGphdmEudXRpbC4qOworCisvKioKKyAqIEFuIGFycmF5IG9mIG9iamVjdCByZWZlcmVuY2VzIGluIHdoaWNoIGVsZW1lbnRzIG1heSBiZSB1cGRhdGVkCisgKiBhdG9taWNhbGx5LiAgU2VlIHRoZSB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljfSBwYWNrYWdlCisgKiBzcGVjaWZpY2F0aW9uIGZvciBkZXNjcmlwdGlvbiBvZiB0aGUgcHJvcGVydGllcyBvZiBhdG9taWMKKyAqIHZhcmlhYmxlcy4KKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqIEBwYXJhbSA8RT4gVGhlIGJhc2UgY2xhc3Mgb2YgZWxlbWVudHMgaGVsZCBpbiB0aGlzIGFycmF5CisgKi8KK3B1YmxpYyBjbGFzcyBBdG9taWNSZWZlcmVuY2VBcnJheTxFPiBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjIwOTY1NjE0OTkyNTA3Njk4MEw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBVbnNhZmUgdW5zYWZlID0gVW5zYWZlQWNjZXNzLlRIRV9PTkU7IC8vIGFuZHJvaWQtY2hhbmdlZAorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBiYXNlID0gdW5zYWZlLmFycmF5QmFzZU9mZnNldChPYmplY3RbXS5jbGFzcyk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IHNoaWZ0OworICAgIHByaXZhdGUgZmluYWwgT2JqZWN0W10gYXJyYXk7CisKKyAgICBzdGF0aWMgeworICAgICAgICBpbnQgc2NhbGUgPSB1bnNhZmUuYXJyYXlJbmRleFNjYWxlKE9iamVjdFtdLmNsYXNzKTsKKyAgICAgICAgaWYgKChzY2FsZSAmIChzY2FsZSAtIDEpKSAhPSAwKQorICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJkYXRhIHR5cGUgc2NhbGUgbm90IGEgcG93ZXIgb2YgdHdvIik7CisgICAgICAgIHNoaWZ0ID0gMzEgLSBJbnRlZ2VyLm51bWJlck9mTGVhZGluZ1plcm9zKHNjYWxlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGxvbmcgY2hlY2tlZEJ5dGVPZmZzZXQoaW50IGkpIHsKKyAgICAgICAgaWYgKGkgPCAwIHx8IGkgPj0gYXJyYXkubGVuZ3RoKQorICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oImluZGV4ICIgKyBpKTsKKworICAgICAgICByZXR1cm4gYnl0ZU9mZnNldChpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBsb25nIGJ5dGVPZmZzZXQoaW50IGkpIHsKKyAgICAgICAgcmV0dXJuICgobG9uZykgaSA8PCBzaGlmdCkgKyBiYXNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgQXRvbWljUmVmZXJlbmNlQXJyYXkgb2YgdGhlIGdpdmVuIGxlbmd0aCwgd2l0aCBhbGwKKyAgICAgKiBlbGVtZW50cyBpbml0aWFsbHkgemVyby4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgYXJyYXkKKyAgICAgKi8KKyAgICBwdWJsaWMgQXRvbWljUmVmZXJlbmNlQXJyYXkoaW50IGxlbmd0aCkgeworICAgICAgICBhcnJheSA9IG5ldyBPYmplY3RbbGVuZ3RoXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IEF0b21pY1JlZmVyZW5jZUFycmF5IHdpdGggdGhlIHNhbWUgbGVuZ3RoIGFzLCBhbmQKKyAgICAgKiBhbGwgZWxlbWVudHMgY29waWVkIGZyb20sIHRoZSBnaXZlbiBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcnJheSB0aGUgYXJyYXkgdG8gY29weSBlbGVtZW50cyBmcm9tCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBhcnJheSBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIEF0b21pY1JlZmVyZW5jZUFycmF5KEVbXSBhcnJheSkgeworICAgICAgICAvLyBWaXNpYmlsaXR5IGd1YXJhbnRlZWQgYnkgZmluYWwgZmllbGQgZ3VhcmFudGVlcworICAgICAgICB0aGlzLmFycmF5ID0gYXJyYXkuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhlIGFycmF5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSBhcnJheQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgbGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gYXJyYXkubGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGN1cnJlbnQgdmFsdWUgYXQgcG9zaXRpb24ge0Bjb2RlIGl9LgorICAgICAqCisgICAgICogQHBhcmFtIGkgdGhlIGluZGV4CisgICAgICogQHJldHVybiB0aGUgY3VycmVudCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBFIGdldChpbnQgaSkgeworICAgICAgICByZXR1cm4gZ2V0UmF3KGNoZWNrZWRCeXRlT2Zmc2V0KGkpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIEUgZ2V0UmF3KGxvbmcgb2Zmc2V0KSB7CisgICAgICAgIHJldHVybiAoRSkgdW5zYWZlLmdldE9iamVjdFZvbGF0aWxlKGFycmF5LCBvZmZzZXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGVsZW1lbnQgYXQgcG9zaXRpb24ge0Bjb2RlIGl9IHRvIHRoZSBnaXZlbiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIHRoZSBpbmRleAorICAgICAqIEBwYXJhbSBuZXdWYWx1ZSB0aGUgbmV3IHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgc2V0KGludCBpLCBFIG5ld1ZhbHVlKSB7CisgICAgICAgIHVuc2FmZS5wdXRPYmplY3RWb2xhdGlsZShhcnJheSwgY2hlY2tlZEJ5dGVPZmZzZXQoaSksIG5ld1ZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFdmVudHVhbGx5IHNldHMgdGhlIGVsZW1lbnQgYXQgcG9zaXRpb24ge0Bjb2RlIGl9IHRvIHRoZSBnaXZlbiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIHRoZSBpbmRleAorICAgICAqIEBwYXJhbSBuZXdWYWx1ZSB0aGUgbmV3IHZhbHVlCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGxhenlTZXQoaW50IGksIEUgbmV3VmFsdWUpIHsKKyAgICAgICAgdW5zYWZlLnB1dE9yZGVyZWRPYmplY3QoYXJyYXksIGNoZWNrZWRCeXRlT2Zmc2V0KGkpLCBuZXdWYWx1ZSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdGhlIGVsZW1lbnQgYXQgcG9zaXRpb24ge0Bjb2RlIGl9IHRvIHRoZSBnaXZlbgorICAgICAqIHZhbHVlIGFuZCByZXR1cm5zIHRoZSBvbGQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaSB0aGUgaW5kZXgKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEUgZ2V0QW5kU2V0KGludCBpLCBFIG5ld1ZhbHVlKSB7CisgICAgICAgIGxvbmcgb2Zmc2V0ID0gY2hlY2tlZEJ5dGVPZmZzZXQoaSk7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBFIGN1cnJlbnQgPSAoRSkgZ2V0UmF3KG9mZnNldCk7CisgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldFJhdyhvZmZzZXQsIGN1cnJlbnQsIG5ld1ZhbHVlKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgc2V0cyB0aGUgZWxlbWVudCBhdCBwb3NpdGlvbiB7QGNvZGUgaX0gdG8gdGhlIGdpdmVuCisgICAgICogdXBkYXRlZCB2YWx1ZSBpZiB0aGUgY3VycmVudCB2YWx1ZSB7QGNvZGUgPT19IHRoZSBleHBlY3RlZCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIHRoZSBpbmRleAorICAgICAqIEBwYXJhbSBleHBlY3QgdGhlIGV4cGVjdGVkIHZhbHVlCisgICAgICogQHBhcmFtIHVwZGF0ZSB0aGUgbmV3IHZhbHVlCisgICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwuIEZhbHNlIHJldHVybiBpbmRpY2F0ZXMgdGhhdAorICAgICAqIHRoZSBhY3R1YWwgdmFsdWUgd2FzIG5vdCBlcXVhbCB0byB0aGUgZXhwZWN0ZWQgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gY29tcGFyZUFuZFNldChpbnQgaSwgRSBleHBlY3QsIEUgdXBkYXRlKSB7CisgICAgICAgIHJldHVybiBjb21wYXJlQW5kU2V0UmF3KGNoZWNrZWRCeXRlT2Zmc2V0KGkpLCBleHBlY3QsIHVwZGF0ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGNvbXBhcmVBbmRTZXRSYXcobG9uZyBvZmZzZXQsIEUgZXhwZWN0LCBFIHVwZGF0ZSkgeworICAgICAgICByZXR1cm4gdW5zYWZlLmNvbXBhcmVBbmRTd2FwT2JqZWN0KGFycmF5LCBvZmZzZXQsIGV4cGVjdCwgdXBkYXRlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdGhlIGVsZW1lbnQgYXQgcG9zaXRpb24ge0Bjb2RlIGl9IHRvIHRoZSBnaXZlbgorICAgICAqIHVwZGF0ZWQgdmFsdWUgaWYgdGhlIGN1cnJlbnQgdmFsdWUge0Bjb2RlID09fSB0aGUgZXhwZWN0ZWQgdmFsdWUuCisgICAgICoKKyAgICAgKiA8cD5NYXkgPGEgaHJlZj0icGFja2FnZS1zdW1tYXJ5Lmh0bWwjU3B1cmlvdXMiPmZhaWwgc3B1cmlvdXNseTwvYT4KKyAgICAgKiBhbmQgZG9lcyBub3QgcHJvdmlkZSBvcmRlcmluZyBndWFyYW50ZWVzLCBzbyBpcyBvbmx5IHJhcmVseSBhbgorICAgICAqIGFwcHJvcHJpYXRlIGFsdGVybmF0aXZlIHRvIHtAY29kZSBjb21wYXJlQW5kU2V0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIHRoZSBpbmRleAorICAgICAqIEBwYXJhbSBleHBlY3QgdGhlIGV4cGVjdGVkIHZhbHVlCisgICAgICogQHBhcmFtIHVwZGF0ZSB0aGUgbmV3IHZhbHVlCisgICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gd2Vha0NvbXBhcmVBbmRTZXQoaW50IGksIEUgZXhwZWN0LCBFIHVwZGF0ZSkgeworICAgICAgICByZXR1cm4gY29tcGFyZUFuZFNldChpLCBleHBlY3QsIHVwZGF0ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjdXJyZW50IHZhbHVlcyBvZiBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHRoZSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGN1cnJlbnQgdmFsdWVzIG9mIGFycmF5CisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgaW50IGlNYXggPSBhcnJheS5sZW5ndGggLSAxOworICAgICAgICBpZiAoaU1heCA9PSAtMSkKKyAgICAgICAgICAgIHJldHVybiAiW10iOworCisgICAgICAgIFN0cmluZ0J1aWxkZXIgYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGIuYXBwZW5kKCdbJyk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyA7IGkrKykgeworICAgICAgICAgICAgYi5hcHBlbmQoZ2V0UmF3KGJ5dGVPZmZzZXQoaSkpKTsKKyAgICAgICAgICAgIGlmIChpID09IGlNYXgpCisgICAgICAgICAgICAgICAgcmV0dXJuIGIuYXBwZW5kKCddJykudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGIuYXBwZW5kKCcsJykuYXBwZW5kKCcgJyk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvQXRvbWljUmVmZXJlbmNlRmllbGRVcGRhdGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvYXRvbWljL0F0b21pY1JlZmVyZW5jZUZpZWxkVXBkYXRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhiM2RhMGIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvYXRvbWljL0F0b21pY1JlZmVyZW5jZUZpZWxkVXBkYXRlci5qYXZhCkBAIC0wLDAgKzEsMjc4IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljOworaW1wb3J0IGRhbHZpay5zeXN0ZW0uVk1TdGFjazsKK2ltcG9ydCBzdW4ubWlzYy5VbnNhZmU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuKjsKKworLyoqCisgKiBBIHJlZmxlY3Rpb24tYmFzZWQgdXRpbGl0eSB0aGF0IGVuYWJsZXMgYXRvbWljIHVwZGF0ZXMgdG8KKyAqIGRlc2lnbmF0ZWQge0Bjb2RlIHZvbGF0aWxlfSByZWZlcmVuY2UgZmllbGRzIG9mIGRlc2lnbmF0ZWQKKyAqIGNsYXNzZXMuICBUaGlzIGNsYXNzIGlzIGRlc2lnbmVkIGZvciB1c2UgaW4gYXRvbWljIGRhdGEgc3RydWN0dXJlcworICogaW4gd2hpY2ggc2V2ZXJhbCByZWZlcmVuY2UgZmllbGRzIG9mIHRoZSBzYW1lIG5vZGUgYXJlCisgKiBpbmRlcGVuZGVudGx5IHN1YmplY3QgdG8gYXRvbWljIHVwZGF0ZXMuIEZvciBleGFtcGxlLCBhIHRyZWUgbm9kZQorICogbWlnaHQgYmUgZGVjbGFyZWQgYXMKKyAqCisgKiAgPHByZT4ge0Bjb2RlCisgKiBjbGFzcyBOb2RlIHsKKyAqICAgcHJpdmF0ZSB2b2xhdGlsZSBOb2RlIGxlZnQsIHJpZ2h0OworICoKKyAqICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQXRvbWljUmVmZXJlbmNlRmllbGRVcGRhdGVyPE5vZGUsIE5vZGU+IGxlZnRVcGRhdGVyID0KKyAqICAgICBBdG9taWNSZWZlcmVuY2VGaWVsZFVwZGF0ZXIubmV3VXBkYXRlcihOb2RlLmNsYXNzLCBOb2RlLmNsYXNzLCAibGVmdCIpOworICogICBwcml2YXRlIHN0YXRpYyBBdG9taWNSZWZlcmVuY2VGaWVsZFVwZGF0ZXI8Tm9kZSwgTm9kZT4gcmlnaHRVcGRhdGVyID0KKyAqICAgICBBdG9taWNSZWZlcmVuY2VGaWVsZFVwZGF0ZXIubmV3VXBkYXRlcihOb2RlLmNsYXNzLCBOb2RlLmNsYXNzLCAicmlnaHQiKTsKKyAqCisgKiAgIE5vZGUgZ2V0TGVmdCgpIHsgcmV0dXJuIGxlZnQ7ICB9CisgKiAgIGJvb2xlYW4gY29tcGFyZUFuZFNldExlZnQoTm9kZSBleHBlY3QsIE5vZGUgdXBkYXRlKSB7CisgKiAgICAgcmV0dXJuIGxlZnRVcGRhdGVyLmNvbXBhcmVBbmRTZXQodGhpcywgZXhwZWN0LCB1cGRhdGUpOworICogICB9CisgKiAgIC8vIC4uLiBhbmQgc28gb24KKyAqIH19PC9wcmU+CisgKgorICogPHA+Tm90ZSB0aGF0IHRoZSBndWFyYW50ZWVzIG9mIHRoZSB7QGNvZGUgY29tcGFyZUFuZFNldH0KKyAqIG1ldGhvZCBpbiB0aGlzIGNsYXNzIGFyZSB3ZWFrZXIgdGhhbiBpbiBvdGhlciBhdG9taWMgY2xhc3Nlcy4KKyAqIEJlY2F1c2UgdGhpcyBjbGFzcyBjYW5ub3QgZW5zdXJlIHRoYXQgYWxsIHVzZXMgb2YgdGhlIGZpZWxkCisgKiBhcmUgYXBwcm9wcmlhdGUgZm9yIHB1cnBvc2VzIG9mIGF0b21pYyBhY2Nlc3MsIGl0IGNhbgorICogZ3VhcmFudGVlIGF0b21pY2l0eSBvbmx5IHdpdGggcmVzcGVjdCB0byBvdGhlciBpbnZvY2F0aW9ucyBvZgorICoge0Bjb2RlIGNvbXBhcmVBbmRTZXR9IGFuZCB7QGNvZGUgc2V0fSBvbiB0aGUgc2FtZSB1cGRhdGVyLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqIEBwYXJhbSA8VD4gVGhlIHR5cGUgb2YgdGhlIG9iamVjdCBob2xkaW5nIHRoZSB1cGRhdGFibGUgZmllbGQKKyAqIEBwYXJhbSA8Vj4gVGhlIHR5cGUgb2YgdGhlIGZpZWxkCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBBdG9taWNSZWZlcmVuY2VGaWVsZFVwZGF0ZXI8VCwgVj4geworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbmQgcmV0dXJucyBhbiB1cGRhdGVyIGZvciBvYmplY3RzIHdpdGggdGhlIGdpdmVuIGZpZWxkLgorICAgICAqIFRoZSBDbGFzcyBhcmd1bWVudHMgYXJlIG5lZWRlZCB0byBjaGVjayB0aGF0IHJlZmxlY3RpdmUgdHlwZXMgYW5kCisgICAgICogZ2VuZXJpYyB0eXBlcyBtYXRjaC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0Y2xhc3MgdGhlIGNsYXNzIG9mIHRoZSBvYmplY3RzIGhvbGRpbmcgdGhlIGZpZWxkLgorICAgICAqIEBwYXJhbSB2Y2xhc3MgdGhlIGNsYXNzIG9mIHRoZSBmaWVsZAorICAgICAqIEBwYXJhbSBmaWVsZE5hbWUgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGJlIHVwZGF0ZWQuCisgICAgICogQHJldHVybiB0aGUgdXBkYXRlcgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBmaWVsZCBpcyBub3QgYSB2b2xhdGlsZSByZWZlcmVuY2UgdHlwZS4KKyAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gd2l0aCBhIG5lc3RlZCByZWZsZWN0aW9uLWJhc2VkCisgICAgICogZXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBkb2VzIG5vdCBob2xkIGZpZWxkIG9yIGlzIHRoZSB3cm9uZyB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFUsIFc+IEF0b21pY1JlZmVyZW5jZUZpZWxkVXBkYXRlcjxVLFc+IG5ld1VwZGF0ZXIoQ2xhc3M8VT4gdGNsYXNzLCBDbGFzczxXPiB2Y2xhc3MsIFN0cmluZyBmaWVsZE5hbWUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBBdG9taWNSZWZlcmVuY2VGaWVsZFVwZGF0ZXJJbXBsPFUsVz4odGNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2Y2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkTmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvdGVjdGVkIGRvLW5vdGhpbmcgY29uc3RydWN0b3IgZm9yIHVzZSBieSBzdWJjbGFzc2VzLgorICAgICAqLworICAgIHByb3RlY3RlZCBBdG9taWNSZWZlcmVuY2VGaWVsZFVwZGF0ZXIoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBzZXRzIHRoZSBmaWVsZCBvZiB0aGUgZ2l2ZW4gb2JqZWN0IG1hbmFnZWQgYnkgdGhpcyB1cGRhdGVyCisgICAgICogdG8gdGhlIGdpdmVuIHVwZGF0ZWQgdmFsdWUgaWYgdGhlIGN1cnJlbnQgdmFsdWUge0Bjb2RlID09fSB0aGUKKyAgICAgKiBleHBlY3RlZCB2YWx1ZS4gVGhpcyBtZXRob2QgaXMgZ3VhcmFudGVlZCB0byBiZSBhdG9taWMgd2l0aCByZXNwZWN0IHRvCisgICAgICogb3RoZXIgY2FsbHMgdG8ge0Bjb2RlIGNvbXBhcmVBbmRTZXR9IGFuZCB7QGNvZGUgc2V0fSwgYnV0IG5vdAorICAgICAqIG5lY2Vzc2FyaWx5IHdpdGggcmVzcGVjdCB0byBvdGhlciBjaGFuZ2VzIGluIHRoZSBmaWVsZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmogQW4gb2JqZWN0IHdob3NlIGZpZWxkIHRvIGNvbmRpdGlvbmFsbHkgc2V0CisgICAgICogQHBhcmFtIGV4cGVjdCB0aGUgZXhwZWN0ZWQgdmFsdWUKKyAgICAgKiBAcGFyYW0gdXBkYXRlIHRoZSBuZXcgdmFsdWUKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgc3VjY2Vzc2Z1bC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBjb21wYXJlQW5kU2V0KFQgb2JqLCBWIGV4cGVjdCwgViB1cGRhdGUpOworCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBzZXRzIHRoZSBmaWVsZCBvZiB0aGUgZ2l2ZW4gb2JqZWN0IG1hbmFnZWQgYnkgdGhpcyB1cGRhdGVyCisgICAgICogdG8gdGhlIGdpdmVuIHVwZGF0ZWQgdmFsdWUgaWYgdGhlIGN1cnJlbnQgdmFsdWUge0Bjb2RlID09fSB0aGUKKyAgICAgKiBleHBlY3RlZCB2YWx1ZS4gVGhpcyBtZXRob2QgaXMgZ3VhcmFudGVlZCB0byBiZSBhdG9taWMgd2l0aCByZXNwZWN0IHRvCisgICAgICogb3RoZXIgY2FsbHMgdG8ge0Bjb2RlIGNvbXBhcmVBbmRTZXR9IGFuZCB7QGNvZGUgc2V0fSwgYnV0IG5vdAorICAgICAqIG5lY2Vzc2FyaWx5IHdpdGggcmVzcGVjdCB0byBvdGhlciBjaGFuZ2VzIGluIHRoZSBmaWVsZC4KKyAgICAgKgorICAgICAqIDxwPk1heSA8YSBocmVmPSJwYWNrYWdlLXN1bW1hcnkuaHRtbCNTcHVyaW91cyI+ZmFpbCBzcHVyaW91c2x5PC9hPgorICAgICAqIGFuZCBkb2VzIG5vdCBwcm92aWRlIG9yZGVyaW5nIGd1YXJhbnRlZXMsIHNvIGlzIG9ubHkgcmFyZWx5IGFuCisgICAgICogYXBwcm9wcmlhdGUgYWx0ZXJuYXRpdmUgdG8ge0Bjb2RlIGNvbXBhcmVBbmRTZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBBbiBvYmplY3Qgd2hvc2UgZmllbGQgdG8gY29uZGl0aW9uYWxseSBzZXQKKyAgICAgKiBAcGFyYW0gZXhwZWN0IHRoZSBleHBlY3RlZCB2YWx1ZQorICAgICAqIEBwYXJhbSB1cGRhdGUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIHdlYWtDb21wYXJlQW5kU2V0KFQgb2JqLCBWIGV4cGVjdCwgViB1cGRhdGUpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZmllbGQgb2YgdGhlIGdpdmVuIG9iamVjdCBtYW5hZ2VkIGJ5IHRoaXMgdXBkYXRlciB0byB0aGUKKyAgICAgKiBnaXZlbiB1cGRhdGVkIHZhbHVlLiBUaGlzIG9wZXJhdGlvbiBpcyBndWFyYW50ZWVkIHRvIGFjdCBhcyBhIHZvbGF0aWxlCisgICAgICogc3RvcmUgd2l0aCByZXNwZWN0IHRvIHN1YnNlcXVlbnQgaW52b2NhdGlvbnMgb2Yge0Bjb2RlIGNvbXBhcmVBbmRTZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBBbiBvYmplY3Qgd2hvc2UgZmllbGQgdG8gc2V0CisgICAgICogQHBhcmFtIG5ld1ZhbHVlIHRoZSBuZXcgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXQoVCBvYmosIFYgbmV3VmFsdWUpOworCisgICAgLyoqCisgICAgICogRXZlbnR1YWxseSBzZXRzIHRoZSBmaWVsZCBvZiB0aGUgZ2l2ZW4gb2JqZWN0IG1hbmFnZWQgYnkgdGhpcworICAgICAqIHVwZGF0ZXIgdG8gdGhlIGdpdmVuIHVwZGF0ZWQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIEFuIG9iamVjdCB3aG9zZSBmaWVsZCB0byBzZXQKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIG5ldyB2YWx1ZQorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBsYXp5U2V0KFQgb2JqLCBWIG5ld1ZhbHVlKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGN1cnJlbnQgdmFsdWUgaGVsZCBpbiB0aGUgZmllbGQgb2YgdGhlIGdpdmVuIG9iamVjdCBtYW5hZ2VkCisgICAgICogYnkgdGhpcyB1cGRhdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBBbiBvYmplY3Qgd2hvc2UgZmllbGQgdG8gZ2V0CisgICAgICogQHJldHVybiB0aGUgY3VycmVudCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBWIGdldChUIG9iaik7CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdGhlIGZpZWxkIG9mIHRoZSBnaXZlbiBvYmplY3QgbWFuYWdlZCBieSB0aGlzIHVwZGF0ZXIKKyAgICAgKiB0byB0aGUgZ2l2ZW4gdmFsdWUgYW5kIHJldHVybnMgdGhlIG9sZCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmogQW4gb2JqZWN0IHdob3NlIGZpZWxkIHRvIGdldCBhbmQgc2V0CisgICAgICogQHBhcmFtIG5ld1ZhbHVlIHRoZSBuZXcgdmFsdWUKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBWIGdldEFuZFNldChUIG9iaiwgViBuZXdWYWx1ZSkgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBWIGN1cnJlbnQgPSBnZXQob2JqKTsKKyAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0KG9iaiwgY3VycmVudCwgbmV3VmFsdWUpKQorICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50OworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgQXRvbWljUmVmZXJlbmNlRmllbGRVcGRhdGVySW1wbDxULFY+CisgICAgICAgIGV4dGVuZHMgQXRvbWljUmVmZXJlbmNlRmllbGRVcGRhdGVyPFQsVj4geworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBVbnNhZmUgdW5zYWZlID0gVW5zYWZlLmdldFVuc2FmZSgpOworICAgICAgICBwcml2YXRlIGZpbmFsIGxvbmcgb2Zmc2V0OworICAgICAgICBwcml2YXRlIGZpbmFsIENsYXNzPFQ+IHRjbGFzczsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBDbGFzczxWPiB2Y2xhc3M7CisgICAgICAgIHByaXZhdGUgZmluYWwgQ2xhc3MgY2NsYXNzOworCisgICAgICAgIC8qCisgICAgICAgICAqIEludGVybmFsIHR5cGUgY2hlY2tzIHdpdGhpbiBhbGwgdXBkYXRlIG1ldGhvZHMgY29udGFpbgorICAgICAgICAgKiBpbnRlcm5hbCBpbmxpbmVkIG9wdGltaXphdGlvbnMgY2hlY2tpbmcgZm9yIHRoZSBjb21tb24KKyAgICAgICAgICogY2FzZXMgd2hlcmUgdGhlIGNsYXNzIGlzIGZpbmFsIChpbiB3aGljaCBjYXNlIGEgc2ltcGxlCisgICAgICAgICAqIGdldENsYXNzIGNvbXBhcmlzb24gc3VmZmljZXMpIG9yIGlzIG9mIHR5cGUgT2JqZWN0IChpbgorICAgICAgICAgKiB3aGljaCBjYXNlIG5vIGNoZWNrIGlzIG5lZWRlZCBiZWNhdXNlIGFsbCBvYmplY3RzIGFyZQorICAgICAgICAgKiBpbnN0YW5jZXMgb2YgT2JqZWN0KS4gVGhlIE9iamVjdCBjYXNlIGlzIGhhbmRsZWQgc2ltcGx5IGJ5CisgICAgICAgICAqIHNldHRpbmcgdmNsYXNzIHRvIG51bGwgaW4gY29uc3RydWN0b3IuICBUaGUgdGFyZ2V0Q2hlY2sgYW5kCisgICAgICAgICAqIHVwZGF0ZUNoZWNrIG1ldGhvZHMgYXJlIGludm9rZWQgd2hlbiB0aGVzZSBmYXN0ZXIKKyAgICAgICAgICogc2NyZWVuaW5ncyBmYWlsLgorICAgICAgICAgKi8KKworICAgICAgICBBdG9taWNSZWZlcmVuY2VGaWVsZFVwZGF0ZXJJbXBsKENsYXNzPFQ+IHRjbGFzcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzczxWPiB2Y2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGZpZWxkTmFtZSkgeworICAgICAgICAgICAgRmllbGQgZmllbGQgPSBudWxsOworICAgICAgICAgICAgQ2xhc3MgZmllbGRDbGFzcyA9IG51bGw7CisgICAgICAgICAgICBDbGFzcyBjYWxsZXIgPSBudWxsOworICAgICAgICAgICAgaW50IG1vZGlmaWVycyA9IDA7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZpZWxkID0gdGNsYXNzLmdldERlY2xhcmVkRmllbGQoZmllbGROYW1lKTsKKyAgICAgICAgICAgICAgICBjYWxsZXIgPSBWTVN0YWNrLmdldFN0YWNrQ2xhc3MyKCk7IC8vIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICAgICAgICAgIG1vZGlmaWVycyA9IGZpZWxkLmdldE1vZGlmaWVycygpOworICAgICAgICAgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtcmVtb3ZlZAorICAgICAgICAgICAgICAgIC8vIHN1bi5yZWZsZWN0Lm1pc2MuUmVmbGVjdFV0aWwuZW5zdXJlTWVtYmVyQWNjZXNzKAorICAgICAgICAgICAgICAgIC8vICAgICBjYWxsZXIsIHRjbGFzcywgbnVsbCwgbW9kaWZpZXJzKTsKKyAgICAgICAgICAgICAgICAvLyBzdW4ucmVmbGVjdC5taXNjLlJlZmxlY3RVdGlsLmNoZWNrUGFja2FnZUFjY2Vzcyh0Y2xhc3MpOworICAgICAgICAgICAgICAgIC8vIEVORCBhbmRyb2lkLXJlbW92ZWQKKyAgICAgICAgICAgICAgICBmaWVsZENsYXNzID0gZmllbGQuZ2V0VHlwZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZXgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAodmNsYXNzICE9IGZpZWxkQ2xhc3MpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzQ2FzdEV4Y2VwdGlvbigpOworCisgICAgICAgICAgICBpZiAoIU1vZGlmaWVyLmlzVm9sYXRpbGUobW9kaWZpZXJzKSkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJNdXN0IGJlIHZvbGF0aWxlIHR5cGUiKTsKKworICAgICAgICAgICAgdGhpcy5jY2xhc3MgPSAoTW9kaWZpZXIuaXNQcm90ZWN0ZWQobW9kaWZpZXJzKSAmJgorICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGVyICE9IHRjbGFzcykgPyBjYWxsZXIgOiBudWxsOworICAgICAgICAgICAgdGhpcy50Y2xhc3MgPSB0Y2xhc3M7CisgICAgICAgICAgICBpZiAodmNsYXNzID09IE9iamVjdC5jbGFzcykKKyAgICAgICAgICAgICAgICB0aGlzLnZjbGFzcyA9IG51bGw7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgdGhpcy52Y2xhc3MgPSB2Y2xhc3M7CisgICAgICAgICAgICBvZmZzZXQgPSB1bnNhZmUub2JqZWN0RmllbGRPZmZzZXQoZmllbGQpOworICAgICAgICB9CisKKyAgICAgICAgdm9pZCB0YXJnZXRDaGVjayhUIG9iaikgeworICAgICAgICAgICAgaWYgKCF0Y2xhc3MuaXNJbnN0YW5jZShvYmopKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc0Nhc3RFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGlmIChjY2xhc3MgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICBlbnN1cmVQcm90ZWN0ZWRBY2Nlc3Mob2JqKTsKKyAgICAgICAgfQorCisgICAgICAgIHZvaWQgdXBkYXRlQ2hlY2soVCBvYmosIFYgdXBkYXRlKSB7CisgICAgICAgICAgICBpZiAoIXRjbGFzcy5pc0luc3RhbmNlKG9iaikgfHwKKyAgICAgICAgICAgICAgICAodXBkYXRlICE9IG51bGwgJiYgdmNsYXNzICE9IG51bGwgJiYgIXZjbGFzcy5pc0luc3RhbmNlKHVwZGF0ZSkpKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc0Nhc3RFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGlmIChjY2xhc3MgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICBlbnN1cmVQcm90ZWN0ZWRBY2Nlc3Mob2JqKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbXBhcmVBbmRTZXQoVCBvYmosIFYgZXhwZWN0LCBWIHVwZGF0ZSkgeworICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsIHx8IG9iai5nZXRDbGFzcygpICE9IHRjbGFzcyB8fCBjY2xhc3MgIT0gbnVsbCB8fAorICAgICAgICAgICAgICAgICh1cGRhdGUgIT0gbnVsbCAmJiB2Y2xhc3MgIT0gbnVsbCAmJgorICAgICAgICAgICAgICAgICB2Y2xhc3MgIT0gdXBkYXRlLmdldENsYXNzKCkpKQorICAgICAgICAgICAgICAgIHVwZGF0ZUNoZWNrKG9iaiwgdXBkYXRlKTsKKyAgICAgICAgICAgIHJldHVybiB1bnNhZmUuY29tcGFyZUFuZFN3YXBPYmplY3Qob2JqLCBvZmZzZXQsIGV4cGVjdCwgdXBkYXRlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIHdlYWtDb21wYXJlQW5kU2V0KFQgb2JqLCBWIGV4cGVjdCwgViB1cGRhdGUpIHsKKyAgICAgICAgICAgIC8vIHNhbWUgaW1wbGVtZW50YXRpb24gYXMgc3Ryb25nIGZvcm0gZm9yIG5vdworICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsIHx8IG9iai5nZXRDbGFzcygpICE9IHRjbGFzcyB8fCBjY2xhc3MgIT0gbnVsbCB8fAorICAgICAgICAgICAgICAgICh1cGRhdGUgIT0gbnVsbCAmJiB2Y2xhc3MgIT0gbnVsbCAmJgorICAgICAgICAgICAgICAgICB2Y2xhc3MgIT0gdXBkYXRlLmdldENsYXNzKCkpKQorICAgICAgICAgICAgICAgIHVwZGF0ZUNoZWNrKG9iaiwgdXBkYXRlKTsKKyAgICAgICAgICAgIHJldHVybiB1bnNhZmUuY29tcGFyZUFuZFN3YXBPYmplY3Qob2JqLCBvZmZzZXQsIGV4cGVjdCwgdXBkYXRlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldChUIG9iaiwgViBuZXdWYWx1ZSkgeworICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsIHx8IG9iai5nZXRDbGFzcygpICE9IHRjbGFzcyB8fCBjY2xhc3MgIT0gbnVsbCB8fAorICAgICAgICAgICAgICAgIChuZXdWYWx1ZSAhPSBudWxsICYmIHZjbGFzcyAhPSBudWxsICYmCisgICAgICAgICAgICAgICAgIHZjbGFzcyAhPSBuZXdWYWx1ZS5nZXRDbGFzcygpKSkKKyAgICAgICAgICAgICAgICB1cGRhdGVDaGVjayhvYmosIG5ld1ZhbHVlKTsKKyAgICAgICAgICAgIHVuc2FmZS5wdXRPYmplY3RWb2xhdGlsZShvYmosIG9mZnNldCwgbmV3VmFsdWUpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgbGF6eVNldChUIG9iaiwgViBuZXdWYWx1ZSkgeworICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsIHx8IG9iai5nZXRDbGFzcygpICE9IHRjbGFzcyB8fCBjY2xhc3MgIT0gbnVsbCB8fAorICAgICAgICAgICAgICAgIChuZXdWYWx1ZSAhPSBudWxsICYmIHZjbGFzcyAhPSBudWxsICYmCisgICAgICAgICAgICAgICAgIHZjbGFzcyAhPSBuZXdWYWx1ZS5nZXRDbGFzcygpKSkKKyAgICAgICAgICAgICAgICB1cGRhdGVDaGVjayhvYmosIG5ld1ZhbHVlKTsKKyAgICAgICAgICAgIHVuc2FmZS5wdXRPcmRlcmVkT2JqZWN0KG9iaiwgb2Zmc2V0LCBuZXdWYWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgViBnZXQoVCBvYmopIHsKKyAgICAgICAgICAgIGlmIChvYmogPT0gbnVsbCB8fCBvYmouZ2V0Q2xhc3MoKSAhPSB0Y2xhc3MgfHwgY2NsYXNzICE9IG51bGwpCisgICAgICAgICAgICAgICAgdGFyZ2V0Q2hlY2sob2JqKTsKKyAgICAgICAgICAgIHJldHVybiAoVil1bnNhZmUuZ2V0T2JqZWN0Vm9sYXRpbGUob2JqLCBvZmZzZXQpOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVByb3RlY3RlZEFjY2VzcyhUIG9iaikgeworICAgICAgICAgICAgaWYgKGNjbGFzcy5pc0luc3RhbmNlKG9iaikpIHsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICBuZXcgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbigiQ2xhc3MgIiArCisgICAgICAgICAgICAgICAgICAgIGNjbGFzcy5nZXROYW1lKCkgKworICAgICAgICAgICAgICAgICAgICAiIGNhbiBub3QgYWNjZXNzIGEgcHJvdGVjdGVkIG1lbWJlciBvZiBjbGFzcyAiICsKKyAgICAgICAgICAgICAgICAgICAgdGNsYXNzLmdldE5hbWUoKSArCisgICAgICAgICAgICAgICAgICAgICIgdXNpbmcgYW4gaW5zdGFuY2Ugb2YgIiArCisgICAgICAgICAgICAgICAgICAgIG9iai5nZXRDbGFzcygpLmdldE5hbWUoKQorICAgICAgICAgICAgICAgICkKKyAgICAgICAgICAgICk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvYXRvbWljL0F0b21pY1N0YW1wZWRSZWZlcmVuY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvQXRvbWljU3RhbXBlZFJlZmVyZW5jZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlODI2ZjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvYXRvbWljL0F0b21pY1N0YW1wZWRSZWZlcmVuY2UuamF2YQpAQCAtMCwwICsxLDE4NCBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYzsKKworLyoqCisgKiBBbiB7QGNvZGUgQXRvbWljU3RhbXBlZFJlZmVyZW5jZX0gbWFpbnRhaW5zIGFuIG9iamVjdCByZWZlcmVuY2UKKyAqIGFsb25nIHdpdGggYW4gaW50ZWdlciAic3RhbXAiLCB0aGF0IGNhbiBiZSB1cGRhdGVkIGF0b21pY2FsbHkuCisgKgorICogPHA+SW1wbGVtZW50YXRpb24gbm90ZTogVGhpcyBpbXBsZW1lbnRhdGlvbiBtYWludGFpbnMgc3RhbXBlZAorICogcmVmZXJlbmNlcyBieSBjcmVhdGluZyBpbnRlcm5hbCBvYmplY3RzIHJlcHJlc2VudGluZyAiYm94ZWQiCisgKiBbcmVmZXJlbmNlLCBpbnRlZ2VyXSBwYWlycy4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKiBAcGFyYW0gPFY+IFRoZSB0eXBlIG9mIG9iamVjdCByZWZlcnJlZCB0byBieSB0aGlzIHJlZmVyZW5jZQorICovCitwdWJsaWMgY2xhc3MgQXRvbWljU3RhbXBlZFJlZmVyZW5jZTxWPiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBQYWlyPFQ+IHsKKyAgICAgICAgZmluYWwgVCByZWZlcmVuY2U7CisgICAgICAgIGZpbmFsIGludCBzdGFtcDsKKyAgICAgICAgcHJpdmF0ZSBQYWlyKFQgcmVmZXJlbmNlLCBpbnQgc3RhbXApIHsKKyAgICAgICAgICAgIHRoaXMucmVmZXJlbmNlID0gcmVmZXJlbmNlOworICAgICAgICAgICAgdGhpcy5zdGFtcCA9IHN0YW1wOworICAgICAgICB9CisgICAgICAgIHN0YXRpYyA8VD4gUGFpcjxUPiBvZihUIHJlZmVyZW5jZSwgaW50IHN0YW1wKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFBhaXI8VD4ocmVmZXJlbmNlLCBzdGFtcCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvbGF0aWxlIFBhaXI8Vj4gcGFpcjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEF0b21pY1N0YW1wZWRSZWZlcmVuY2V9IHdpdGggdGhlIGdpdmVuCisgICAgICogaW5pdGlhbCB2YWx1ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5pdGlhbFJlZiB0aGUgaW5pdGlhbCByZWZlcmVuY2UKKyAgICAgKiBAcGFyYW0gaW5pdGlhbFN0YW1wIHRoZSBpbml0aWFsIHN0YW1wCisgICAgICovCisgICAgcHVibGljIEF0b21pY1N0YW1wZWRSZWZlcmVuY2UoViBpbml0aWFsUmVmLCBpbnQgaW5pdGlhbFN0YW1wKSB7CisgICAgICAgIHBhaXIgPSBQYWlyLm9mKGluaXRpYWxSZWYsIGluaXRpYWxTdGFtcCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcmVmZXJlbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcmVmZXJlbmNlCisgICAgICovCisgICAgcHVibGljIFYgZ2V0UmVmZXJlbmNlKCkgeworICAgICAgICByZXR1cm4gcGFpci5yZWZlcmVuY2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgc3RhbXAuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBzdGFtcAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U3RhbXAoKSB7CisgICAgICAgIHJldHVybiBwYWlyLnN0YW1wOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgdmFsdWVzIG9mIGJvdGggdGhlIHJlZmVyZW5jZSBhbmQgdGhlIHN0YW1wLgorICAgICAqIFR5cGljYWwgdXNhZ2UgaXMge0Bjb2RlIGludFsxXSBob2xkZXI7IHJlZiA9IHYuZ2V0KGhvbGRlcik7IH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhbXBIb2xkZXIgYW4gYXJyYXkgb2Ygc2l6ZSBvZiBhdCBsZWFzdCBvbmUuICBPbiByZXR1cm4sCisgICAgICoge0Bjb2RlIHN0YW1waG9sZGVyWzBdfSB3aWxsIGhvbGQgdGhlIHZhbHVlIG9mIHRoZSBzdGFtcC4KKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSByZWZlcmVuY2UKKyAgICAgKi8KKyAgICBwdWJsaWMgViBnZXQoaW50W10gc3RhbXBIb2xkZXIpIHsKKyAgICAgICAgUGFpcjxWPiBwYWlyID0gdGhpcy5wYWlyOworICAgICAgICBzdGFtcEhvbGRlclswXSA9IHBhaXIuc3RhbXA7CisgICAgICAgIHJldHVybiBwYWlyLnJlZmVyZW5jZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdGhlIHZhbHVlIG9mIGJvdGggdGhlIHJlZmVyZW5jZSBhbmQgc3RhbXAKKyAgICAgKiB0byB0aGUgZ2l2ZW4gdXBkYXRlIHZhbHVlcyBpZiB0aGUKKyAgICAgKiBjdXJyZW50IHJlZmVyZW5jZSBpcyB7QGNvZGUgPT19IHRvIHRoZSBleHBlY3RlZCByZWZlcmVuY2UKKyAgICAgKiBhbmQgdGhlIGN1cnJlbnQgc3RhbXAgaXMgZXF1YWwgdG8gdGhlIGV4cGVjdGVkIHN0YW1wLgorICAgICAqCisgICAgICogPHA+TWF5IDxhIGhyZWY9InBhY2thZ2Utc3VtbWFyeS5odG1sI1NwdXJpb3VzIj5mYWlsIHNwdXJpb3VzbHk8L2E+CisgICAgICogYW5kIGRvZXMgbm90IHByb3ZpZGUgb3JkZXJpbmcgZ3VhcmFudGVlcywgc28gaXMgb25seSByYXJlbHkgYW4KKyAgICAgKiBhcHByb3ByaWF0ZSBhbHRlcm5hdGl2ZSB0byB7QGNvZGUgY29tcGFyZUFuZFNldH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWRSZWZlcmVuY2UgdGhlIGV4cGVjdGVkIHZhbHVlIG9mIHRoZSByZWZlcmVuY2UKKyAgICAgKiBAcGFyYW0gbmV3UmVmZXJlbmNlIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSByZWZlcmVuY2UKKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWRTdGFtcCB0aGUgZXhwZWN0ZWQgdmFsdWUgb2YgdGhlIHN0YW1wCisgICAgICogQHBhcmFtIG5ld1N0YW1wIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzdGFtcAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gd2Vha0NvbXBhcmVBbmRTZXQoViAgIGV4cGVjdGVkUmVmZXJlbmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFYgICBuZXdSZWZlcmVuY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGV4cGVjdGVkU3RhbXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5ld1N0YW1wKSB7CisgICAgICAgIHJldHVybiBjb21wYXJlQW5kU2V0KGV4cGVjdGVkUmVmZXJlbmNlLCBuZXdSZWZlcmVuY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkU3RhbXAsIG5ld1N0YW1wKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdG9taWNhbGx5IHNldHMgdGhlIHZhbHVlIG9mIGJvdGggdGhlIHJlZmVyZW5jZSBhbmQgc3RhbXAKKyAgICAgKiB0byB0aGUgZ2l2ZW4gdXBkYXRlIHZhbHVlcyBpZiB0aGUKKyAgICAgKiBjdXJyZW50IHJlZmVyZW5jZSBpcyB7QGNvZGUgPT19IHRvIHRoZSBleHBlY3RlZCByZWZlcmVuY2UKKyAgICAgKiBhbmQgdGhlIGN1cnJlbnQgc3RhbXAgaXMgZXF1YWwgdG8gdGhlIGV4cGVjdGVkIHN0YW1wLgorICAgICAqCisgICAgICogQHBhcmFtIGV4cGVjdGVkUmVmZXJlbmNlIHRoZSBleHBlY3RlZCB2YWx1ZSBvZiB0aGUgcmVmZXJlbmNlCisgICAgICogQHBhcmFtIG5ld1JlZmVyZW5jZSB0aGUgbmV3IHZhbHVlIGZvciB0aGUgcmVmZXJlbmNlCisgICAgICogQHBhcmFtIGV4cGVjdGVkU3RhbXAgdGhlIGV4cGVjdGVkIHZhbHVlIG9mIHRoZSBzdGFtcAorICAgICAqIEBwYXJhbSBuZXdTdGFtcCB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc3RhbXAKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgc3VjY2Vzc2Z1bAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbXBhcmVBbmRTZXQoViAgIGV4cGVjdGVkUmVmZXJlbmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgViAgIG5ld1JlZmVyZW5jZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBleHBlY3RlZFN0YW1wLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5ld1N0YW1wKSB7CisgICAgICAgIFBhaXI8Vj4gY3VycmVudCA9IHBhaXI7CisgICAgICAgIHJldHVybgorICAgICAgICAgICAgZXhwZWN0ZWRSZWZlcmVuY2UgPT0gY3VycmVudC5yZWZlcmVuY2UgJiYKKyAgICAgICAgICAgIGV4cGVjdGVkU3RhbXAgPT0gY3VycmVudC5zdGFtcCAmJgorICAgICAgICAgICAgKChuZXdSZWZlcmVuY2UgPT0gY3VycmVudC5yZWZlcmVuY2UgJiYKKyAgICAgICAgICAgICAgbmV3U3RhbXAgPT0gY3VycmVudC5zdGFtcCkgfHwKKyAgICAgICAgICAgICBjYXNQYWlyKGN1cnJlbnQsIFBhaXIub2YobmV3UmVmZXJlbmNlLCBuZXdTdGFtcCkpKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFVuY29uZGl0aW9uYWxseSBzZXRzIHRoZSB2YWx1ZSBvZiBib3RoIHRoZSByZWZlcmVuY2UgYW5kIHN0YW1wLgorICAgICAqCisgICAgICogQHBhcmFtIG5ld1JlZmVyZW5jZSB0aGUgbmV3IHZhbHVlIGZvciB0aGUgcmVmZXJlbmNlCisgICAgICogQHBhcmFtIG5ld1N0YW1wIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzdGFtcAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldChWIG5ld1JlZmVyZW5jZSwgaW50IG5ld1N0YW1wKSB7CisgICAgICAgIFBhaXI8Vj4gY3VycmVudCA9IHBhaXI7CisgICAgICAgIGlmIChuZXdSZWZlcmVuY2UgIT0gY3VycmVudC5yZWZlcmVuY2UgfHwgbmV3U3RhbXAgIT0gY3VycmVudC5zdGFtcCkKKyAgICAgICAgICAgIHRoaXMucGFpciA9IFBhaXIub2YobmV3UmVmZXJlbmNlLCBuZXdTdGFtcCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBzZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3RhbXAgdG8gdGhlIGdpdmVuIHVwZGF0ZSB2YWx1ZQorICAgICAqIGlmIHRoZSBjdXJyZW50IHJlZmVyZW5jZSBpcyB7QGNvZGUgPT19IHRvIHRoZSBleHBlY3RlZAorICAgICAqIHJlZmVyZW5jZS4gIEFueSBnaXZlbiBpbnZvY2F0aW9uIG9mIHRoaXMgb3BlcmF0aW9uIG1heSBmYWlsCisgICAgICogKHJldHVybiB7QGNvZGUgZmFsc2V9KSBzcHVyaW91c2x5LCBidXQgcmVwZWF0ZWQgaW52b2NhdGlvbgorICAgICAqIHdoZW4gdGhlIGN1cnJlbnQgdmFsdWUgaG9sZHMgdGhlIGV4cGVjdGVkIHZhbHVlIGFuZCBubyBvdGhlcgorICAgICAqIHRocmVhZCBpcyBhbHNvIGF0dGVtcHRpbmcgdG8gc2V0IHRoZSB2YWx1ZSB3aWxsIGV2ZW50dWFsbHkKKyAgICAgKiBzdWNjZWVkLgorICAgICAqCisgICAgICogQHBhcmFtIGV4cGVjdGVkUmVmZXJlbmNlIHRoZSBleHBlY3RlZCB2YWx1ZSBvZiB0aGUgcmVmZXJlbmNlCisgICAgICogQHBhcmFtIG5ld1N0YW1wIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzdGFtcAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYXR0ZW1wdFN0YW1wKFYgZXhwZWN0ZWRSZWZlcmVuY2UsIGludCBuZXdTdGFtcCkgeworICAgICAgICBQYWlyPFY+IGN1cnJlbnQgPSBwYWlyOworICAgICAgICByZXR1cm4KKyAgICAgICAgICAgIGV4cGVjdGVkUmVmZXJlbmNlID09IGN1cnJlbnQucmVmZXJlbmNlICYmCisgICAgICAgICAgICAobmV3U3RhbXAgPT0gY3VycmVudC5zdGFtcCB8fAorICAgICAgICAgICAgIGNhc1BhaXIoY3VycmVudCwgUGFpci5vZihleHBlY3RlZFJlZmVyZW5jZSwgbmV3U3RhbXApKSk7CisgICAgfQorCisgICAgLy8gVW5zYWZlIG1lY2hhbmljcworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgc3VuLm1pc2MuVW5zYWZlIFVOU0FGRSA9IFVuc2FmZUFjY2Vzcy5USEVfT05FOyAvLyBhbmRyb2lkLWNoYW5nZWQKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHBhaXJPZmZzZXQgPQorICAgICAgICBvYmplY3RGaWVsZE9mZnNldChVTlNBRkUsICJwYWlyIiwgQXRvbWljU3RhbXBlZFJlZmVyZW5jZS5jbGFzcyk7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gY2FzUGFpcihQYWlyPFY+IGNtcCwgUGFpcjxWPiB2YWwpIHsKKyAgICAgICAgcmV0dXJuIFVOU0FGRS5jb21wYXJlQW5kU3dhcE9iamVjdCh0aGlzLCBwYWlyT2Zmc2V0LCBjbXAsIHZhbCk7CisgICAgfQorCisgICAgc3RhdGljIGxvbmcgb2JqZWN0RmllbGRPZmZzZXQoc3VuLm1pc2MuVW5zYWZlIFVOU0FGRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZmllbGQsIENsYXNzPD8+IGtsYXp6KSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gVU5TQUZFLm9iamVjdEZpZWxkT2Zmc2V0KGtsYXp6LmdldERlY2xhcmVkRmllbGQoZmllbGQpKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRmllbGRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29udmVydCBFeGNlcHRpb24gdG8gY29ycmVzcG9uZGluZyBFcnJvcgorICAgICAgICAgICAgTm9TdWNoRmllbGRFcnJvciBlcnJvciA9IG5ldyBOb1N1Y2hGaWVsZEVycm9yKGZpZWxkKTsKKyAgICAgICAgICAgIGVycm9yLmluaXRDYXVzZShlKTsKKyAgICAgICAgICAgIHRocm93IGVycm9yOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2F0b21pYy9VbnNhZmVBY2Nlc3MuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvVW5zYWZlQWNjZXNzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTZmZmYxNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvVW5zYWZlQWNjZXNzLmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljOworCitpbXBvcnQgc3VuLm1pc2MuVW5zYWZlOworCisvKioKKyAqIEVhc3kgYWNjZXNzIHRvIHtAbGluayBVbnNhZmV9IGZvciB0aGUgcmVzdCBvZiB0aGlzIHBhY2thZ2UuCisgKi8KKy8qcGFja2FnZSovIGZpbmFsIGNsYXNzIFVuc2FmZUFjY2VzcyB7CisgICAgLyoqIG5vbi1udWxsOyB1bmlxdWUgaW5zdGFuY2Ugb2Yge0BsaW5rIFVuc2FmZX0gKi8KKyAgICAvKnBhY2thZ2UqLyBzdGF0aWMgZmluYWwgVW5zYWZlIFRIRV9PTkUgPSBVbnNhZmUuZ2V0VW5zYWZlKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNsYXNzIGlzIHVuaW5zdGFudGlhYmxlLgorICAgICAqLworICAgIHByaXZhdGUgVW5zYWZlQWNjZXNzKCkgeworICAgICAgICAvLyBUaGlzIHNwYWNlIGludGVudGlvbmFsbHkgbGVmdCBibGFuay4KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvYXRvbWljL3BhY2thZ2UtaW5mby5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2F0b21pYy9wYWNrYWdlLWluZm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YTQzNzVkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2F0b21pYy9wYWNrYWdlLWluZm8uamF2YQpAQCAtMCwwICsxLDE3MSBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCisvKioKKyAqIEEgc21hbGwgdG9vbGtpdCBvZiBjbGFzc2VzIHRoYXQgc3VwcG9ydCBsb2NrLWZyZWUgdGhyZWFkLXNhZmUKKyAqIHByb2dyYW1taW5nIG9uIHNpbmdsZSB2YXJpYWJsZXMuICBJbiBlc3NlbmNlLCB0aGUgY2xhc3NlcyBpbiB0aGlzCisgKiBwYWNrYWdlIGV4dGVuZCB0aGUgbm90aW9uIG9mIHtAY29kZSB2b2xhdGlsZX0gdmFsdWVzLCBmaWVsZHMsIGFuZAorICogYXJyYXkgZWxlbWVudHMgdG8gdGhvc2UgdGhhdCBhbHNvIHByb3ZpZGUgYW4gYXRvbWljIGNvbmRpdGlvbmFsIHVwZGF0ZQorICogb3BlcmF0aW9uIG9mIHRoZSBmb3JtOgorICoKKyAqIDxwcmU+CisgKiAgIGJvb2xlYW4gY29tcGFyZUFuZFNldChleHBlY3RlZFZhbHVlLCB1cGRhdGVWYWx1ZSk7CisgKiA8L3ByZT4KKyAqCisgKiA8cD5UaGlzIG1ldGhvZCAod2hpY2ggdmFyaWVzIGluIGFyZ3VtZW50IHR5cGVzIGFjcm9zcyBkaWZmZXJlbnQKKyAqIGNsYXNzZXMpIGF0b21pY2FsbHkgc2V0cyBhIHZhcmlhYmxlIHRvIHRoZSB7QGNvZGUgdXBkYXRlVmFsdWV9IGlmIGl0CisgKiBjdXJyZW50bHkgaG9sZHMgdGhlIHtAY29kZSBleHBlY3RlZFZhbHVlfSwgcmVwb3J0aW5nIHtAY29kZSB0cnVlfSBvbgorICogc3VjY2Vzcy4gIFRoZSBjbGFzc2VzIGluIHRoaXMgcGFja2FnZSBhbHNvIGNvbnRhaW4gbWV0aG9kcyB0byBnZXQgYW5kCisgKiB1bmNvbmRpdGlvbmFsbHkgc2V0IHZhbHVlcywgYXMgd2VsbCBhcyBhIHdlYWtlciBjb25kaXRpb25hbCBhdG9taWMKKyAqIHVwZGF0ZSBvcGVyYXRpb24ge0Bjb2RlIHdlYWtDb21wYXJlQW5kU2V0fSBkZXNjcmliZWQgYmVsb3cuCisgKgorICogPHA+VGhlIHNwZWNpZmljYXRpb25zIG9mIHRoZXNlIG1ldGhvZHMgZW5hYmxlIGltcGxlbWVudGF0aW9ucyB0bworICogZW1wbG95IGVmZmljaWVudCBtYWNoaW5lLWxldmVsIGF0b21pYyBpbnN0cnVjdGlvbnMgdGhhdCBhcmUgYXZhaWxhYmxlCisgKiBvbiBjb250ZW1wb3JhcnkgcHJvY2Vzc29ycy4gIEhvd2V2ZXIgb24gc29tZSBwbGF0Zm9ybXMsIHN1cHBvcnQgbWF5CisgKiBlbnRhaWwgc29tZSBmb3JtIG9mIGludGVybmFsIGxvY2tpbmcuICBUaHVzIHRoZSBtZXRob2RzIGFyZSBub3QKKyAqIHN0cmljdGx5IGd1YXJhbnRlZWQgdG8gYmUgbm9uLWJsb2NraW5nIC0tCisgKiBhIHRocmVhZCBtYXkgYmxvY2sgdHJhbnNpZW50bHkgYmVmb3JlIHBlcmZvcm1pbmcgdGhlIG9wZXJhdGlvbi4KKyAqCisgKiA8cD5JbnN0YW5jZXMgb2YgY2xhc3NlcworICoge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNCb29sZWFufSwKKyAqIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljSW50ZWdlcn0sCisgKiB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0xvbmd9LCBhbmQKKyAqIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljUmVmZXJlbmNlfQorICogZWFjaCBwcm92aWRlIGFjY2VzcyBhbmQgdXBkYXRlcyB0byBhIHNpbmdsZSB2YXJpYWJsZSBvZiB0aGUKKyAqIGNvcnJlc3BvbmRpbmcgdHlwZS4gIEVhY2ggY2xhc3MgYWxzbyBwcm92aWRlcyBhcHByb3ByaWF0ZSB1dGlsaXR5CisgKiBtZXRob2RzIGZvciB0aGF0IHR5cGUuICBGb3IgZXhhbXBsZSwgY2xhc3NlcyB7QGNvZGUgQXRvbWljTG9uZ30gYW5kCisgKiB7QGNvZGUgQXRvbWljSW50ZWdlcn0gcHJvdmlkZSBhdG9taWMgaW5jcmVtZW50IG1ldGhvZHMuICBPbmUKKyAqIGFwcGxpY2F0aW9uIGlzIHRvIGdlbmVyYXRlIHNlcXVlbmNlIG51bWJlcnMsIGFzIGluOgorICoKKyAqIDxwcmU+CisgKiBjbGFzcyBTZXF1ZW5jZXIgeworICogICBwcml2YXRlIGZpbmFsIEF0b21pY0xvbmcgc2VxdWVuY2VOdW1iZXIKKyAqICAgICA9IG5ldyBBdG9taWNMb25nKDApOworICogICBwdWJsaWMgbG9uZyBuZXh0KCkgeworICogICAgIHJldHVybiBzZXF1ZW5jZU51bWJlci5nZXRBbmRJbmNyZW1lbnQoKTsKKyAqICAgfQorICogfQorICogPC9wcmU+CisgKgorICogPHA+VGhlIG1lbW9yeSBlZmZlY3RzIGZvciBhY2Nlc3NlcyBhbmQgdXBkYXRlcyBvZiBhdG9taWNzIGdlbmVyYWxseQorICogZm9sbG93IHRoZSBydWxlcyBmb3Igdm9sYXRpbGVzLCBhcyBzdGF0ZWQgaW4KKyAqIDxhIGhyZWY9Imh0dHA6Ly9qYXZhLnN1bi5jb20vZG9jcy9ib29rcy9qbHMvIj4gVGhlIEphdmEgTGFuZ3VhZ2UKKyAqIFNwZWNpZmljYXRpb24sIFRoaXJkIEVkaXRpb24gKDE3LjQgTWVtb3J5IE1vZGVsKTwvYT46CisgKgorICogPHVsPgorICoKKyAqICAgPGxpPiB7QGNvZGUgZ2V0fSBoYXMgdGhlIG1lbW9yeSBlZmZlY3RzIG9mIHJlYWRpbmcgYQorICoge0Bjb2RlIHZvbGF0aWxlfSB2YXJpYWJsZS4KKyAqCisgKiAgIDxsaT4ge0Bjb2RlIHNldH0gaGFzIHRoZSBtZW1vcnkgZWZmZWN0cyBvZiB3cml0aW5nIChhc3NpZ25pbmcpIGEKKyAqIHtAY29kZSB2b2xhdGlsZX0gdmFyaWFibGUuCisgKgorICogICA8bGk+IHtAY29kZSBsYXp5U2V0fSBoYXMgdGhlIG1lbW9yeSBlZmZlY3RzIG9mIHdyaXRpbmcgKGFzc2lnbmluZykKKyAqICAgYSB7QGNvZGUgdm9sYXRpbGV9IHZhcmlhYmxlIGV4Y2VwdCB0aGF0IGl0IHBlcm1pdHMgcmVvcmRlcmluZ3Mgd2l0aAorICogICBzdWJzZXF1ZW50IChidXQgbm90IHByZXZpb3VzKSBtZW1vcnkgYWN0aW9ucyB0aGF0IGRvIG5vdCB0aGVtc2VsdmVzCisgKiAgIGltcG9zZSByZW9yZGVyaW5nIGNvbnN0cmFpbnRzIHdpdGggb3JkaW5hcnkgbm9uLXtAY29kZSB2b2xhdGlsZX0KKyAqICAgd3JpdGVzLiAgQW1vbmcgb3RoZXIgdXNhZ2UgY29udGV4dHMsIHtAY29kZSBsYXp5U2V0fSBtYXkgYXBwbHkgd2hlbgorICogICBudWxsaW5nIG91dCwgZm9yIHRoZSBzYWtlIG9mIGdhcmJhZ2UgY29sbGVjdGlvbiwgYSByZWZlcmVuY2UgdGhhdCBpcworICogICBuZXZlciBhY2Nlc3NlZCBhZ2Fpbi4KKyAqCisgKiAgIDxsaT57QGNvZGUgd2Vha0NvbXBhcmVBbmRTZXR9IGF0b21pY2FsbHkgcmVhZHMgYW5kIGNvbmRpdGlvbmFsbHkKKyAqICAgd3JpdGVzIGEgdmFyaWFibGUgYnV0IGRvZXMgPGVtPm5vdDwvZW0+CisgKiAgIGNyZWF0ZSBhbnkgaGFwcGVucy1iZWZvcmUgb3JkZXJpbmdzLCBzbyBwcm92aWRlcyBubyBndWFyYW50ZWVzCisgKiAgIHdpdGggcmVzcGVjdCB0byBwcmV2aW91cyBvciBzdWJzZXF1ZW50IHJlYWRzIGFuZCB3cml0ZXMgb2YgYW55CisgKiAgIHZhcmlhYmxlcyBvdGhlciB0aGFuIHRoZSB0YXJnZXQgb2YgdGhlIHtAY29kZSB3ZWFrQ29tcGFyZUFuZFNldH0uCisgKgorICogICA8bGk+IHtAY29kZSBjb21wYXJlQW5kU2V0fQorICogICBhbmQgYWxsIG90aGVyIHJlYWQtYW5kLXVwZGF0ZSBvcGVyYXRpb25zIHN1Y2ggYXMge0Bjb2RlIGdldEFuZEluY3JlbWVudH0KKyAqICAgaGF2ZSB0aGUgbWVtb3J5IGVmZmVjdHMgb2YgYm90aCByZWFkaW5nIGFuZAorICogICB3cml0aW5nIHtAY29kZSB2b2xhdGlsZX0gdmFyaWFibGVzLgorICogPC91bD4KKyAqCisgKiA8cD5JbiBhZGRpdGlvbiB0byBjbGFzc2VzIHJlcHJlc2VudGluZyBzaW5nbGUgdmFsdWVzLCB0aGlzIHBhY2thZ2UKKyAqIGNvbnRhaW5zIDxlbT5VcGRhdGVyPC9lbT4gY2xhc3NlcyB0aGF0IGNhbiBiZSB1c2VkIHRvIG9idGFpbgorICoge0Bjb2RlIGNvbXBhcmVBbmRTZXR9IG9wZXJhdGlvbnMgb24gYW55IHNlbGVjdGVkIHtAY29kZSB2b2xhdGlsZX0KKyAqIGZpZWxkIG9mIGFueSBzZWxlY3RlZCBjbGFzcy4KKyAqCisgKiB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY1JlZmVyZW5jZUZpZWxkVXBkYXRlcn0sCisgKiB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0ludGVnZXJGaWVsZFVwZGF0ZXJ9LCBhbmQKKyAqIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljTG9uZ0ZpZWxkVXBkYXRlcn0gYXJlCisgKiByZWZsZWN0aW9uLWJhc2VkIHV0aWxpdGllcyB0aGF0IHByb3ZpZGUgYWNjZXNzIHRvIHRoZSBhc3NvY2lhdGVkCisgKiBmaWVsZCB0eXBlcy4gIFRoZXNlIGFyZSBtYWlubHkgb2YgdXNlIGluIGF0b21pYyBkYXRhIHN0cnVjdHVyZXMgaW4KKyAqIHdoaWNoIHNldmVyYWwge0Bjb2RlIHZvbGF0aWxlfSBmaWVsZHMgb2YgdGhlIHNhbWUgbm9kZSAoZm9yCisgKiBleGFtcGxlLCB0aGUgbGlua3Mgb2YgYSB0cmVlIG5vZGUpIGFyZSBpbmRlcGVuZGVudGx5IHN1YmplY3QgdG8KKyAqIGF0b21pYyB1cGRhdGVzLiAgVGhlc2UgY2xhc3NlcyBlbmFibGUgZ3JlYXRlciBmbGV4aWJpbGl0eSBpbiBob3cKKyAqIGFuZCB3aGVuIHRvIHVzZSBhdG9taWMgdXBkYXRlcywgYXQgdGhlIGV4cGVuc2Ugb2YgbW9yZSBhd2t3YXJkCisgKiByZWZsZWN0aW9uLWJhc2VkIHNldHVwLCBsZXNzIGNvbnZlbmllbnQgdXNhZ2UsIGFuZCB3ZWFrZXIKKyAqIGd1YXJhbnRlZXMuCisgKgorICogPHA+VGhlCisgKiB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0ludGVnZXJBcnJheX0sCisgKiB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0xvbmdBcnJheX0sIGFuZAorICoge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNSZWZlcmVuY2VBcnJheX0gY2xhc3NlcworICogZnVydGhlciBleHRlbmQgYXRvbWljIG9wZXJhdGlvbiBzdXBwb3J0IHRvIGFycmF5cyBvZiB0aGVzZSB0eXBlcy4KKyAqIFRoZXNlIGNsYXNzZXMgYXJlIGFsc28gbm90YWJsZSBpbiBwcm92aWRpbmcge0Bjb2RlIHZvbGF0aWxlfSBhY2Nlc3MKKyAqIHNlbWFudGljcyBmb3IgdGhlaXIgYXJyYXkgZWxlbWVudHMsIHdoaWNoIGlzIG5vdCBzdXBwb3J0ZWQgZm9yCisgKiBvcmRpbmFyeSBhcnJheXMuCisgKgorICogPGEgbmFtZT0iU3B1cmlvdXMiPgorICogPHA+VGhlIGF0b21pYyBjbGFzc2VzIGFsc28gc3VwcG9ydCBtZXRob2Qge0Bjb2RlIHdlYWtDb21wYXJlQW5kU2V0fSwKKyAqIHdoaWNoIGhhcyBsaW1pdGVkIGFwcGxpY2FiaWxpdHkuICBPbiBzb21lIHBsYXRmb3JtcywgdGhlIHdlYWsgdmVyc2lvbgorICogbWF5IGJlIG1vcmUgZWZmaWNpZW50IHRoYW4ge0Bjb2RlIGNvbXBhcmVBbmRTZXR9IGluIHRoZSBub3JtYWwgY2FzZSwKKyAqIGJ1dCBkaWZmZXJzIGluIHRoYXQgYW55IGdpdmVuIGludm9jYXRpb24gb2YgdGhlCisgKiB7QGNvZGUgd2Vha0NvbXBhcmVBbmRTZXR9IG1ldGhvZCBtYXkgcmV0dXJuIHtAY29kZSBmYWxzZX0KKyAqIDxlbT5zcHVyaW91c2x5PC9lbT4gKHRoYXQgaXMsIGZvciBubyBhcHBhcmVudCByZWFzb24pPC9hPi4gIEEKKyAqIHtAY29kZSBmYWxzZX0gcmV0dXJuIG1lYW5zIG9ubHkgdGhhdCB0aGUgb3BlcmF0aW9uIG1heSBiZSByZXRyaWVkIGlmCisgKiBkZXNpcmVkLCByZWx5aW5nIG9uIHRoZSBndWFyYW50ZWUgdGhhdCByZXBlYXRlZCBpbnZvY2F0aW9uIHdoZW4gdGhlCisgKiB2YXJpYWJsZSBob2xkcyB7QGNvZGUgZXhwZWN0ZWRWYWx1ZX0gYW5kIG5vIG90aGVyIHRocmVhZCBpcyBhbHNvCisgKiBhdHRlbXB0aW5nIHRvIHNldCB0aGUgdmFyaWFibGUgd2lsbCBldmVudHVhbGx5IHN1Y2NlZWQuICAoU3VjaAorICogc3B1cmlvdXMgZmFpbHVyZXMgbWF5IGZvciBleGFtcGxlIGJlIGR1ZSB0byBtZW1vcnkgY29udGVudGlvbiBlZmZlY3RzCisgKiB0aGF0IGFyZSB1bnJlbGF0ZWQgdG8gd2hldGhlciB0aGUgZXhwZWN0ZWQgYW5kIGN1cnJlbnQgdmFsdWVzIGFyZQorICogZXF1YWwuKSAgQWRkaXRpb25hbGx5IHtAY29kZSB3ZWFrQ29tcGFyZUFuZFNldH0gZG9lcyBub3QgcHJvdmlkZQorICogb3JkZXJpbmcgZ3VhcmFudGVlcyB0aGF0IGFyZSB1c3VhbGx5IG5lZWRlZCBmb3Igc3luY2hyb25pemF0aW9uCisgKiBjb250cm9sLiAgSG93ZXZlciwgdGhlIG1ldGhvZCBtYXkgYmUgdXNlZnVsIGZvciB1cGRhdGluZyBjb3VudGVycyBhbmQKKyAqIHN0YXRpc3RpY3Mgd2hlbiBzdWNoIHVwZGF0ZXMgYXJlIHVucmVsYXRlZCB0byB0aGUgb3RoZXIKKyAqIGhhcHBlbnMtYmVmb3JlIG9yZGVyaW5ncyBvZiBhIHByb2dyYW0uICBXaGVuIGEgdGhyZWFkIHNlZXMgYW4gdXBkYXRlCisgKiB0byBhbiBhdG9taWMgdmFyaWFibGUgY2F1c2VkIGJ5IGEge0Bjb2RlIHdlYWtDb21wYXJlQW5kU2V0fSwgaXQgZG9lcworICogbm90IG5lY2Vzc2FyaWx5IHNlZSB1cGRhdGVzIHRvIGFueSA8ZW0+b3RoZXI8L2VtPiB2YXJpYWJsZXMgdGhhdAorICogb2NjdXJyZWQgYmVmb3JlIHRoZSB7QGNvZGUgd2Vha0NvbXBhcmVBbmRTZXR9LiAgVGhpcyBtYXkgYmUKKyAqIGFjY2VwdGFibGUgd2hlbiwgZm9yIGV4YW1wbGUsIHVwZGF0aW5nIHBlcmZvcm1hbmNlIHN0YXRpc3RpY3MsIGJ1dAorICogcmFyZWx5IG90aGVyd2lzZS4KKyAqCisgKiA8cD5UaGUge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNNYXJrYWJsZVJlZmVyZW5jZX0KKyAqIGNsYXNzIGFzc29jaWF0ZXMgYSBzaW5nbGUgYm9vbGVhbiB3aXRoIGEgcmVmZXJlbmNlLiAgRm9yIGV4YW1wbGUsIHRoaXMKKyAqIGJpdCBtaWdodCBiZSB1c2VkIGluc2lkZSBhIGRhdGEgc3RydWN0dXJlIHRvIG1lYW4gdGhhdCB0aGUgb2JqZWN0CisgKiBiZWluZyByZWZlcmVuY2VkIGhhcyBsb2dpY2FsbHkgYmVlbiBkZWxldGVkLgorICoKKyAqIFRoZSB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY1N0YW1wZWRSZWZlcmVuY2V9CisgKiBjbGFzcyBhc3NvY2lhdGVzIGFuIGludGVnZXIgdmFsdWUgd2l0aCBhIHJlZmVyZW5jZS4gIFRoaXMgbWF5IGJlCisgKiB1c2VkIGZvciBleGFtcGxlLCB0byByZXByZXNlbnQgdmVyc2lvbiBudW1iZXJzIGNvcnJlc3BvbmRpbmcgdG8KKyAqIHNlcmllcyBvZiB1cGRhdGVzLgorICoKKyAqIDxwPkF0b21pYyBjbGFzc2VzIGFyZSBkZXNpZ25lZCBwcmltYXJpbHkgYXMgYnVpbGRpbmcgYmxvY2tzIGZvcgorICogaW1wbGVtZW50aW5nIG5vbi1ibG9ja2luZyBkYXRhIHN0cnVjdHVyZXMgYW5kIHJlbGF0ZWQgaW5mcmFzdHJ1Y3R1cmUKKyAqIGNsYXNzZXMuICBUaGUge0Bjb2RlIGNvbXBhcmVBbmRTZXR9IG1ldGhvZCBpcyBub3QgYSBnZW5lcmFsCisgKiByZXBsYWNlbWVudCBmb3IgbG9ja2luZy4gIEl0IGFwcGxpZXMgb25seSB3aGVuIGNyaXRpY2FsIHVwZGF0ZXMgZm9yIGFuCisgKiBvYmplY3QgYXJlIGNvbmZpbmVkIHRvIGEgPGVtPnNpbmdsZTwvZW0+IHZhcmlhYmxlLgorICoKKyAqIDxwPkF0b21pYyBjbGFzc2VzIGFyZSBub3QgZ2VuZXJhbCBwdXJwb3NlIHJlcGxhY2VtZW50cyBmb3IKKyAqIHtAY29kZSBqYXZhLmxhbmcuSW50ZWdlcn0gYW5kIHJlbGF0ZWQgY2xhc3Nlcy4gIFRoZXkgZG8gPGVtPm5vdDwvZW0+CisgKiBkZWZpbmUgbWV0aG9kcyBzdWNoIGFzIHtAY29kZSBoYXNoQ29kZX0gYW5kCisgKiB7QGNvZGUgY29tcGFyZVRvfS4gIChCZWNhdXNlIGF0b21pYyB2YXJpYWJsZXMgYXJlIGV4cGVjdGVkIHRvIGJlCisgKiBtdXRhdGVkLCB0aGV5IGFyZSBwb29yIGNob2ljZXMgZm9yIGhhc2ggdGFibGUga2V5cy4pICBBZGRpdGlvbmFsbHksCisgKiBjbGFzc2VzIGFyZSBwcm92aWRlZCBvbmx5IGZvciB0aG9zZSB0eXBlcyB0aGF0IGFyZSBjb21tb25seSB1c2VmdWwgaW4KKyAqIGludGVuZGVkIGFwcGxpY2F0aW9ucy4gIEZvciBleGFtcGxlLCB0aGVyZSBpcyBubyBhdG9taWMgY2xhc3MgZm9yCisgKiByZXByZXNlbnRpbmcge0Bjb2RlIGJ5dGV9LiAgSW4gdGhvc2UgaW5mcmVxdWVudCBjYXNlcyB3aGVyZSB5b3Ugd291bGQKKyAqIGxpa2UgdG8gZG8gc28sIHlvdSBjYW4gdXNlIGFuIHtAY29kZSBBdG9taWNJbnRlZ2VyfSB0byBob2xkCisgKiB7QGNvZGUgYnl0ZX0gdmFsdWVzLCBhbmQgY2FzdCBhcHByb3ByaWF0ZWx5LgorICoKKyAqIFlvdSBjYW4gYWxzbyBob2xkIGZsb2F0cyB1c2luZworICoge0BsaW5rIGphdmEubGFuZy5GbG9hdCNmbG9hdFRvSW50Qml0c30gYW5kCisgKiB7QGxpbmsgamF2YS5sYW5nLkZsb2F0I2ludEJpdHNUb0Zsb2F0fSBjb252ZXJzaW9ucywgYW5kIGRvdWJsZXMgdXNpbmcKKyAqIHtAbGluayBqYXZhLmxhbmcuRG91YmxlI2RvdWJsZVRvTG9uZ0JpdHN9IGFuZAorICoge0BsaW5rIGphdmEubGFuZy5Eb3VibGUjbG9uZ0JpdHNUb0RvdWJsZX0gY29udmVyc2lvbnMuCisgKgorICogQHNpbmNlIDEuNQorICovCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYzsKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9sb2Nrcy9BYnN0cmFjdE93bmFibGVTeW5jaHJvbml6ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9sb2Nrcy9BYnN0cmFjdE93bmFibGVTeW5jaHJvbml6ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMzc4MGU1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL0Fic3RyYWN0T3duYWJsZVN5bmNocm9uaXplci5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudC5sb2NrczsKKworLyoqCisgKiBBIHN5bmNocm9uaXplciB0aGF0IG1heSBiZSBleGNsdXNpdmVseSBvd25lZCBieSBhIHRocmVhZC4gIFRoaXMKKyAqIGNsYXNzIHByb3ZpZGVzIGEgYmFzaXMgZm9yIGNyZWF0aW5nIGxvY2tzIGFuZCByZWxhdGVkIHN5bmNocm9uaXplcnMKKyAqIHRoYXQgbWF5IGVudGFpbCBhIG5vdGlvbiBvZiBvd25lcnNoaXAuICBUaGUKKyAqIDx0dD5BYnN0cmFjdE93bmFibGVTeW5jaHJvbml6ZXI8L3R0PiBjbGFzcyBpdHNlbGYgZG9lcyBub3QgbWFuYWdlIG9yCisgKiB1c2UgdGhpcyBpbmZvcm1hdGlvbi4gSG93ZXZlciwgc3ViY2xhc3NlcyBhbmQgdG9vbHMgbWF5IHVzZQorICogYXBwcm9wcmlhdGVseSBtYWludGFpbmVkIHZhbHVlcyB0byBoZWxwIGNvbnRyb2wgYW5kIG1vbml0b3IgYWNjZXNzCisgKiBhbmQgcHJvdmlkZSBkaWFnbm9zdGljcy4KKyAqCisgKiBAc2luY2UgMS42CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdE93bmFibGVTeW5jaHJvbml6ZXIKKyAgICBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKworICAgIC8qKiBVc2Ugc2VyaWFsIElEIGV2ZW4gdGhvdWdoIGFsbCBmaWVsZHMgdHJhbnNpZW50LiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDM3Mzc4OTk0Mjc3NTQyNDE5NjFMOworCisgICAgLyoqCisgICAgICogRW1wdHkgY29uc3RydWN0b3IgZm9yIHVzZSBieSBzdWJjbGFzc2VzLgorICAgICAqLworICAgIHByb3RlY3RlZCBBYnN0cmFjdE93bmFibGVTeW5jaHJvbml6ZXIoKSB7IH0KKworICAgIC8qKgorICAgICAqIFRoZSBjdXJyZW50IG93bmVyIG9mIGV4Y2x1c2l2ZSBtb2RlIHN5bmNocm9uaXphdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHRyYW5zaWVudCBUaHJlYWQgZXhjbHVzaXZlT3duZXJUaHJlYWQ7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB0aHJlYWQgdGhhdCBjdXJyZW50bHkgb3ducyBleGNsdXNpdmUgYWNjZXNzLiBBCisgICAgICogPHR0Pm51bGw8L3R0PiBhcmd1bWVudCBpbmRpY2F0ZXMgdGhhdCBubyB0aHJlYWQgb3ducyBhY2Nlc3MuCisgICAgICogVGhpcyBtZXRob2QgZG9lcyBub3Qgb3RoZXJ3aXNlIGltcG9zZSBhbnkgc3luY2hyb25pemF0aW9uIG9yCisgICAgICogPHR0PnZvbGF0aWxlPC90dD4gZmllbGQgYWNjZXNzZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0RXhjbHVzaXZlT3duZXJUaHJlYWQoVGhyZWFkIHQpIHsKKyAgICAgICAgZXhjbHVzaXZlT3duZXJUaHJlYWQgPSB0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRocmVhZCBsYXN0IHNldCBieQorICAgICAqIDx0dD5zZXRFeGNsdXNpdmVPd25lclRocmVhZDwvdHQ+LCBvciA8dHQ+bnVsbDwvdHQ+IGlmIG5ldmVyCisgICAgICogc2V0LiAgVGhpcyBtZXRob2QgZG9lcyBub3Qgb3RoZXJ3aXNlIGltcG9zZSBhbnkgc3luY2hyb25pemF0aW9uCisgICAgICogb3IgPHR0PnZvbGF0aWxlPC90dD4gZmllbGQgYWNjZXNzZXMuCisgICAgICogQHJldHVybiB0aGUgb3duZXIgdGhyZWFkCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIFRocmVhZCBnZXRFeGNsdXNpdmVPd25lclRocmVhZCgpIHsKKyAgICAgICAgcmV0dXJuIGV4Y2x1c2l2ZU93bmVyVGhyZWFkOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9sb2Nrcy9BYnN0cmFjdFF1ZXVlZExvbmdTeW5jaHJvbml6ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9sb2Nrcy9BYnN0cmFjdFF1ZXVlZExvbmdTeW5jaHJvbml6ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YzgxMTFjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL0Fic3RyYWN0UXVldWVkTG9uZ1N5bmNocm9uaXplci5qYXZhCkBAIC0wLDAgKzEsMjA3OSBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzOworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50Lio7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLio7CitpbXBvcnQgc3VuLm1pc2MuVW5zYWZlOworCisvKioKKyAqIEEgdmVyc2lvbiBvZiB7QGxpbmsgQWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXJ9IGluCisgKiB3aGljaCBzeW5jaHJvbml6YXRpb24gc3RhdGUgaXMgbWFpbnRhaW5lZCBhcyBhIDx0dD5sb25nPC90dD4uCisgKiBUaGlzIGNsYXNzIGhhcyBleGFjdGx5IHRoZSBzYW1lIHN0cnVjdHVyZSwgcHJvcGVydGllcywgYW5kIG1ldGhvZHMKKyAqIGFzIDx0dD5BYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplcjwvdHQ+IHdpdGggdGhlIGV4Y2VwdGlvbgorICogdGhhdCBhbGwgc3RhdGUtcmVsYXRlZCBwYXJhbWV0ZXJzIGFuZCByZXN1bHRzIGFyZSBkZWZpbmVkCisgKiBhcyA8dHQ+bG9uZzwvdHQ+IHJhdGhlciB0aGFuIDx0dD5pbnQ8L3R0Pi4gVGhpcyBjbGFzcworICogbWF5IGJlIHVzZWZ1bCB3aGVuIGNyZWF0aW5nIHN5bmNocm9uaXplcnMgc3VjaCBhcworICogbXVsdGlsZXZlbCBsb2NrcyBhbmQgYmFycmllcnMgdGhhdCByZXF1aXJlCisgKiA2NCBiaXRzIG9mIHN0YXRlLgorICoKKyAqIDxwPlNlZSB7QGxpbmsgQWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXJ9IGZvciB1c2FnZQorICogbm90ZXMgYW5kIGV4YW1wbGVzLgorICoKKyAqIEBzaW5jZSAxLjYKKyAqIEBhdXRob3IgRG91ZyBMZWEKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0UXVldWVkTG9uZ1N5bmNocm9uaXplcgorICAgIGV4dGVuZHMgQWJzdHJhY3RPd25hYmxlU3luY2hyb25pemVyCisgICAgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3MzczOTg0OTcyNTcyNDE0NjkyTDsKKworICAgIC8qCisgICAgICBUbyBrZWVwIHNvdXJjZXMgaW4gc3luYywgdGhlIHJlbWFpbmRlciBvZiB0aGlzIHNvdXJjZSBmaWxlIGlzCisgICAgICBleGFjdGx5IGNsb25lZCBmcm9tIEFic3RyYWN0UXVldWVkU3luY2hyb25pemVyLCByZXBsYWNpbmcgY2xhc3MKKyAgICAgIG5hbWUgYW5kIGNoYW5naW5nIGludHMgcmVsYXRlZCB3aXRoIHN5bmMgc3RhdGUgdG8gbG9uZ3MuIFBsZWFzZQorICAgICAga2VlcCBpdCB0aGF0IHdheS4KKyAgICAqLworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8dHQ+QWJzdHJhY3RRdWV1ZWRMb25nU3luY2hyb25pemVyPC90dD4gaW5zdGFuY2UKKyAgICAgKiB3aXRoIGluaXRpYWwgc3luY2hyb25pemF0aW9uIHN0YXRlIG9mIHplcm8uCisgICAgICovCisgICAgcHJvdGVjdGVkIEFic3RyYWN0UXVldWVkTG9uZ1N5bmNocm9uaXplcigpIHsgfQorCisgICAgLyoqCisgICAgICogV2FpdCBxdWV1ZSBub2RlIGNsYXNzLgorICAgICAqCisgICAgICogPHA+VGhlIHdhaXQgcXVldWUgaXMgYSB2YXJpYW50IG9mIGEgIkNMSCIgKENyYWlnLCBMYW5kaW4sIGFuZAorICAgICAqIEhhZ2Vyc3RlbikgbG9jayBxdWV1ZS4gQ0xIIGxvY2tzIGFyZSBub3JtYWxseSB1c2VkIGZvcgorICAgICAqIHNwaW5sb2Nrcy4gIFdlIGluc3RlYWQgdXNlIHRoZW0gZm9yIGJsb2NraW5nIHN5bmNocm9uaXplcnMsIGJ1dAorICAgICAqIHVzZSB0aGUgc2FtZSBiYXNpYyB0YWN0aWMgb2YgaG9sZGluZyBzb21lIG9mIHRoZSBjb250cm9sCisgICAgICogaW5mb3JtYXRpb24gYWJvdXQgYSB0aHJlYWQgaW4gdGhlIHByZWRlY2Vzc29yIG9mIGl0cyBub2RlLiAgQQorICAgICAqICJzdGF0dXMiIGZpZWxkIGluIGVhY2ggbm9kZSBrZWVwcyB0cmFjayBvZiB3aGV0aGVyIGEgdGhyZWFkCisgICAgICogc2hvdWxkIGJsb2NrLiAgQSBub2RlIGlzIHNpZ25hbGxlZCB3aGVuIGl0cyBwcmVkZWNlc3NvcgorICAgICAqIHJlbGVhc2VzLiAgRWFjaCBub2RlIG9mIHRoZSBxdWV1ZSBvdGhlcndpc2Ugc2VydmVzIGFzIGEKKyAgICAgKiBzcGVjaWZpYy1ub3RpZmljYXRpb24tc3R5bGUgbW9uaXRvciBob2xkaW5nIGEgc2luZ2xlIHdhaXRpbmcKKyAgICAgKiB0aHJlYWQuIFRoZSBzdGF0dXMgZmllbGQgZG9lcyBOT1QgY29udHJvbCB3aGV0aGVyIHRocmVhZHMgYXJlCisgICAgICogZ3JhbnRlZCBsb2NrcyBldGMgdGhvdWdoLiAgQSB0aHJlYWQgbWF5IHRyeSB0byBhY3F1aXJlIGlmIGl0IGlzCisgICAgICogZmlyc3QgaW4gdGhlIHF1ZXVlLiBCdXQgYmVpbmcgZmlyc3QgZG9lcyBub3QgZ3VhcmFudGVlIHN1Y2Nlc3M7CisgICAgICogaXQgb25seSBnaXZlcyB0aGUgcmlnaHQgdG8gY29udGVuZC4gIFNvIHRoZSBjdXJyZW50bHkgcmVsZWFzZWQKKyAgICAgKiBjb250ZW5kZXIgdGhyZWFkIG1heSBuZWVkIHRvIHJld2FpdC4KKyAgICAgKgorICAgICAqIDxwPlRvIGVucXVldWUgaW50byBhIENMSCBsb2NrLCB5b3UgYXRvbWljYWxseSBzcGxpY2UgaXQgaW4gYXMgbmV3CisgICAgICogdGFpbC4gVG8gZGVxdWV1ZSwgeW91IGp1c3Qgc2V0IHRoZSBoZWFkIGZpZWxkLgorICAgICAqIDxwcmU+CisgICAgICogICAgICArLS0tLS0tKyAgcHJldiArLS0tLS0rICAgICAgICstLS0tLSsKKyAgICAgKiBoZWFkIHwgICAgICB8IDwtLS0tIHwgICAgIHwgPC0tLS0gfCAgICAgfCAgdGFpbAorICAgICAqICAgICAgKy0tLS0tLSsgICAgICAgKy0tLS0tKyAgICAgICArLS0tLS0rCisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiA8cD5JbnNlcnRpb24gaW50byBhIENMSCBxdWV1ZSByZXF1aXJlcyBvbmx5IGEgc2luZ2xlIGF0b21pYworICAgICAqIG9wZXJhdGlvbiBvbiAidGFpbCIsIHNvIHRoZXJlIGlzIGEgc2ltcGxlIGF0b21pYyBwb2ludCBvZgorICAgICAqIGRlbWFyY2F0aW9uIGZyb20gdW5xdWV1ZWQgdG8gcXVldWVkLiBTaW1pbGFybHksIGRlcXVlaW5nCisgICAgICogaW52b2x2ZXMgb25seSB1cGRhdGluZyB0aGUgImhlYWQiLiBIb3dldmVyLCBpdCB0YWtlcyBhIGJpdAorICAgICAqIG1vcmUgd29yayBmb3Igbm9kZXMgdG8gZGV0ZXJtaW5lIHdobyB0aGVpciBzdWNjZXNzb3JzIGFyZSwKKyAgICAgKiBpbiBwYXJ0IHRvIGRlYWwgd2l0aCBwb3NzaWJsZSBjYW5jZWxsYXRpb24gZHVlIHRvIHRpbWVvdXRzCisgICAgICogYW5kIGludGVycnVwdHMuCisgICAgICoKKyAgICAgKiA8cD5UaGUgInByZXYiIGxpbmtzIChub3QgdXNlZCBpbiBvcmlnaW5hbCBDTEggbG9ja3MpLCBhcmUgbWFpbmx5CisgICAgICogbmVlZGVkIHRvIGhhbmRsZSBjYW5jZWxsYXRpb24uIElmIGEgbm9kZSBpcyBjYW5jZWxsZWQsIGl0cworICAgICAqIHN1Y2Nlc3NvciBpcyAobm9ybWFsbHkpIHJlbGlua2VkIHRvIGEgbm9uLWNhbmNlbGxlZAorICAgICAqIHByZWRlY2Vzc29yLiBGb3IgZXhwbGFuYXRpb24gb2Ygc2ltaWxhciBtZWNoYW5pY3MgaW4gdGhlIGNhc2UKKyAgICAgKiBvZiBzcGluIGxvY2tzLCBzZWUgdGhlIHBhcGVycyBieSBTY290dCBhbmQgU2NoZXJlciBhdAorICAgICAqIGh0dHA6Ly93d3cuY3Mucm9jaGVzdGVyLmVkdS91L3Njb3R0L3N5bmNocm9uaXphdGlvbi8KKyAgICAgKgorICAgICAqIDxwPldlIGFsc28gdXNlICJuZXh0IiBsaW5rcyB0byBpbXBsZW1lbnQgYmxvY2tpbmcgbWVjaGFuaWNzLgorICAgICAqIFRoZSB0aHJlYWQgaWQgZm9yIGVhY2ggbm9kZSBpcyBrZXB0IGluIGl0cyBvd24gbm9kZSwgc28gYQorICAgICAqIHByZWRlY2Vzc29yIHNpZ25hbHMgdGhlIG5leHQgbm9kZSB0byB3YWtlIHVwIGJ5IHRyYXZlcnNpbmcKKyAgICAgKiBuZXh0IGxpbmsgdG8gZGV0ZXJtaW5lIHdoaWNoIHRocmVhZCBpdCBpcy4gIERldGVybWluYXRpb24gb2YKKyAgICAgKiBzdWNjZXNzb3IgbXVzdCBhdm9pZCByYWNlcyB3aXRoIG5ld2x5IHF1ZXVlZCBub2RlcyB0byBzZXQKKyAgICAgKiB0aGUgIm5leHQiIGZpZWxkcyBvZiB0aGVpciBwcmVkZWNlc3NvcnMuICBUaGlzIGlzIHNvbHZlZAorICAgICAqIHdoZW4gbmVjZXNzYXJ5IGJ5IGNoZWNraW5nIGJhY2t3YXJkcyBmcm9tIHRoZSBhdG9taWNhbGx5CisgICAgICogdXBkYXRlZCAidGFpbCIgd2hlbiBhIG5vZGUncyBzdWNjZXNzb3IgYXBwZWFycyB0byBiZSBudWxsLgorICAgICAqIChPciwgc2FpZCBkaWZmZXJlbnRseSwgdGhlIG5leHQtbGlua3MgYXJlIGFuIG9wdGltaXphdGlvbgorICAgICAqIHNvIHRoYXQgd2UgZG9uJ3QgdXN1YWxseSBuZWVkIGEgYmFja3dhcmQgc2Nhbi4pCisgICAgICoKKyAgICAgKiA8cD5DYW5jZWxsYXRpb24gaW50cm9kdWNlcyBzb21lIGNvbnNlcnZhdGlzbSB0byB0aGUgYmFzaWMKKyAgICAgKiBhbGdvcml0aG1zLiAgU2luY2Ugd2UgbXVzdCBwb2xsIGZvciBjYW5jZWxsYXRpb24gb2Ygb3RoZXIKKyAgICAgKiBub2Rlcywgd2UgY2FuIG1pc3Mgbm90aWNpbmcgd2hldGhlciBhIGNhbmNlbGxlZCBub2RlIGlzCisgICAgICogYWhlYWQgb3IgYmVoaW5kIHVzLiBUaGlzIGlzIGRlYWx0IHdpdGggYnkgYWx3YXlzIHVucGFya2luZworICAgICAqIHN1Y2Nlc3NvcnMgdXBvbiBjYW5jZWxsYXRpb24sIGFsbG93aW5nIHRoZW0gdG8gc3RhYmlsaXplIG9uCisgICAgICogYSBuZXcgcHJlZGVjZXNzb3IsIHVubGVzcyB3ZSBjYW4gaWRlbnRpZnkgYW4gdW5jYW5jZWxsZWQKKyAgICAgKiBwcmVkZWNlc3NvciB3aG8gd2lsbCBjYXJyeSB0aGlzIHJlc3BvbnNpYmlsaXR5LgorICAgICAqCisgICAgICogPHA+Q0xIIHF1ZXVlcyBuZWVkIGEgZHVtbXkgaGVhZGVyIG5vZGUgdG8gZ2V0IHN0YXJ0ZWQuIEJ1dAorICAgICAqIHdlIGRvbid0IGNyZWF0ZSB0aGVtIG9uIGNvbnN0cnVjdGlvbiwgYmVjYXVzZSBpdCB3b3VsZCBiZSB3YXN0ZWQKKyAgICAgKiBlZmZvcnQgaWYgdGhlcmUgaXMgbmV2ZXIgY29udGVudGlvbi4gSW5zdGVhZCwgdGhlIG5vZGUKKyAgICAgKiBpcyBjb25zdHJ1Y3RlZCBhbmQgaGVhZCBhbmQgdGFpbCBwb2ludGVycyBhcmUgc2V0IHVwb24gZmlyc3QKKyAgICAgKiBjb250ZW50aW9uLgorICAgICAqCisgICAgICogPHA+VGhyZWFkcyB3YWl0aW5nIG9uIENvbmRpdGlvbnMgdXNlIHRoZSBzYW1lIG5vZGVzLCBidXQKKyAgICAgKiB1c2UgYW4gYWRkaXRpb25hbCBsaW5rLiBDb25kaXRpb25zIG9ubHkgbmVlZCB0byBsaW5rIG5vZGVzCisgICAgICogaW4gc2ltcGxlIChub24tY29uY3VycmVudCkgbGlua2VkIHF1ZXVlcyBiZWNhdXNlIHRoZXkgYXJlCisgICAgICogb25seSBhY2Nlc3NlZCB3aGVuIGV4Y2x1c2l2ZWx5IGhlbGQuICBVcG9uIGF3YWl0LCBhIG5vZGUgaXMKKyAgICAgKiBpbnNlcnRlZCBpbnRvIGEgY29uZGl0aW9uIHF1ZXVlLiAgVXBvbiBzaWduYWwsIHRoZSBub2RlIGlzCisgICAgICogdHJhbnNmZXJyZWQgdG8gdGhlIG1haW4gcXVldWUuICBBIHNwZWNpYWwgdmFsdWUgb2Ygc3RhdHVzCisgICAgICogZmllbGQgaXMgdXNlZCB0byBtYXJrIHdoaWNoIHF1ZXVlIGEgbm9kZSBpcyBvbi4KKyAgICAgKgorICAgICAqIDxwPlRoYW5rcyBnbyB0byBEYXZlIERpY2UsIE1hcmsgTW9pciwgVmljdG9yIEx1Y2hhbmdjbywgQmlsbAorICAgICAqIFNjaGVyZXIgYW5kIE1pY2hhZWwgU2NvdHQsIGFsb25nIHdpdGggbWVtYmVycyBvZiBKU1ItMTY2CisgICAgICogZXhwZXJ0IGdyb3VwLCBmb3IgaGVscGZ1bCBpZGVhcywgZGlzY3Vzc2lvbnMsIGFuZCBjcml0aXF1ZXMKKyAgICAgKiBvbiB0aGUgZGVzaWduIG9mIHRoaXMgY2xhc3MuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIE5vZGUgeworICAgICAgICAvKiogTWFya2VyIHRvIGluZGljYXRlIGEgbm9kZSBpcyB3YWl0aW5nIGluIHNoYXJlZCBtb2RlICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBOb2RlIFNIQVJFRCA9IG5ldyBOb2RlKCk7CisgICAgICAgIC8qKiBNYXJrZXIgdG8gaW5kaWNhdGUgYSBub2RlIGlzIHdhaXRpbmcgaW4gZXhjbHVzaXZlIG1vZGUgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIE5vZGUgRVhDTFVTSVZFID0gbnVsbDsKKworICAgICAgICAvKiogd2FpdFN0YXR1cyB2YWx1ZSB0byBpbmRpY2F0ZSB0aHJlYWQgaGFzIGNhbmNlbGxlZCAqLworICAgICAgICBzdGF0aWMgZmluYWwgaW50IENBTkNFTExFRCA9ICAxOworICAgICAgICAvKiogd2FpdFN0YXR1cyB2YWx1ZSB0byBpbmRpY2F0ZSBzdWNjZXNzb3IncyB0aHJlYWQgbmVlZHMgdW5wYXJraW5nICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgU0lHTkFMICAgID0gLTE7CisgICAgICAgIC8qKiB3YWl0U3RhdHVzIHZhbHVlIHRvIGluZGljYXRlIHRocmVhZCBpcyB3YWl0aW5nIG9uIGNvbmRpdGlvbiAqLworICAgICAgICBzdGF0aWMgZmluYWwgaW50IENPTkRJVElPTiA9IC0yOworICAgICAgICAvKioKKyAgICAgICAgICogd2FpdFN0YXR1cyB2YWx1ZSB0byBpbmRpY2F0ZSB0aGUgbmV4dCBhY3F1aXJlU2hhcmVkIHNob3VsZAorICAgICAgICAgKiB1bmNvbmRpdGlvbmFsbHkgcHJvcGFnYXRlCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgZmluYWwgaW50IFBST1BBR0FURSA9IC0zOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBTdGF0dXMgZmllbGQsIHRha2luZyBvbiBvbmx5IHRoZSB2YWx1ZXM6CisgICAgICAgICAqICAgU0lHTkFMOiAgICAgVGhlIHN1Y2Nlc3NvciBvZiB0aGlzIG5vZGUgaXMgKG9yIHdpbGwgc29vbiBiZSkKKyAgICAgICAgICogICAgICAgICAgICAgICBibG9ja2VkICh2aWEgcGFyayksIHNvIHRoZSBjdXJyZW50IG5vZGUgbXVzdAorICAgICAgICAgKiAgICAgICAgICAgICAgIHVucGFyayBpdHMgc3VjY2Vzc29yIHdoZW4gaXQgcmVsZWFzZXMgb3IKKyAgICAgICAgICogICAgICAgICAgICAgICBjYW5jZWxzLiBUbyBhdm9pZCByYWNlcywgYWNxdWlyZSBtZXRob2RzIG11c3QKKyAgICAgICAgICogICAgICAgICAgICAgICBmaXJzdCBpbmRpY2F0ZSB0aGV5IG5lZWQgYSBzaWduYWwsCisgICAgICAgICAqICAgICAgICAgICAgICAgdGhlbiByZXRyeSB0aGUgYXRvbWljIGFjcXVpcmUsIGFuZCB0aGVuLAorICAgICAgICAgKiAgICAgICAgICAgICAgIG9uIGZhaWx1cmUsIGJsb2NrLgorICAgICAgICAgKiAgIENBTkNFTExFRDogIFRoaXMgbm9kZSBpcyBjYW5jZWxsZWQgZHVlIHRvIHRpbWVvdXQgb3IgaW50ZXJydXB0LgorICAgICAgICAgKiAgICAgICAgICAgICAgIE5vZGVzIG5ldmVyIGxlYXZlIHRoaXMgc3RhdGUuIEluIHBhcnRpY3VsYXIsCisgICAgICAgICAqICAgICAgICAgICAgICAgYSB0aHJlYWQgd2l0aCBjYW5jZWxsZWQgbm9kZSBuZXZlciBhZ2FpbiBibG9ja3MuCisgICAgICAgICAqICAgQ09ORElUSU9OOiAgVGhpcyBub2RlIGlzIGN1cnJlbnRseSBvbiBhIGNvbmRpdGlvbiBxdWV1ZS4KKyAgICAgICAgICogICAgICAgICAgICAgICBJdCB3aWxsIG5vdCBiZSB1c2VkIGFzIGEgc3luYyBxdWV1ZSBub2RlCisgICAgICAgICAqICAgICAgICAgICAgICAgdW50aWwgdHJhbnNmZXJyZWQsIGF0IHdoaWNoIHRpbWUgdGhlIHN0YXR1cworICAgICAgICAgKiAgICAgICAgICAgICAgIHdpbGwgYmUgc2V0IHRvIDAuIChVc2Ugb2YgdGhpcyB2YWx1ZSBoZXJlIGhhcworICAgICAgICAgKiAgICAgICAgICAgICAgIG5vdGhpbmcgdG8gZG8gd2l0aCB0aGUgb3RoZXIgdXNlcyBvZiB0aGUKKyAgICAgICAgICogICAgICAgICAgICAgICBmaWVsZCwgYnV0IHNpbXBsaWZpZXMgbWVjaGFuaWNzLikKKyAgICAgICAgICogICBQUk9QQUdBVEU6ICBBIHJlbGVhc2VTaGFyZWQgc2hvdWxkIGJlIHByb3BhZ2F0ZWQgdG8gb3RoZXIKKyAgICAgICAgICogICAgICAgICAgICAgICBub2Rlcy4gVGhpcyBpcyBzZXQgKGZvciBoZWFkIG5vZGUgb25seSkgaW4KKyAgICAgICAgICogICAgICAgICAgICAgICBkb1JlbGVhc2VTaGFyZWQgdG8gZW5zdXJlIHByb3BhZ2F0aW9uCisgICAgICAgICAqICAgICAgICAgICAgICAgY29udGludWVzLCBldmVuIGlmIG90aGVyIG9wZXJhdGlvbnMgaGF2ZQorICAgICAgICAgKiAgICAgICAgICAgICAgIHNpbmNlIGludGVydmVuZWQuCisgICAgICAgICAqICAgMDogICAgICAgICAgTm9uZSBvZiB0aGUgYWJvdmUKKyAgICAgICAgICoKKyAgICAgICAgICogVGhlIHZhbHVlcyBhcmUgYXJyYW5nZWQgbnVtZXJpY2FsbHkgdG8gc2ltcGxpZnkgdXNlLgorICAgICAgICAgKiBOb24tbmVnYXRpdmUgdmFsdWVzIG1lYW4gdGhhdCBhIG5vZGUgZG9lc24ndCBuZWVkIHRvCisgICAgICAgICAqIHNpZ25hbC4gU28sIG1vc3QgY29kZSBkb2Vzbid0IG5lZWQgdG8gY2hlY2sgZm9yIHBhcnRpY3VsYXIKKyAgICAgICAgICogdmFsdWVzLCBqdXN0IGZvciBzaWduLgorICAgICAgICAgKgorICAgICAgICAgKiBUaGUgZmllbGQgaXMgaW5pdGlhbGl6ZWQgdG8gMCBmb3Igbm9ybWFsIHN5bmMgbm9kZXMsIGFuZAorICAgICAgICAgKiBDT05ESVRJT04gZm9yIGNvbmRpdGlvbiBub2Rlcy4gIEl0IGlzIG1vZGlmaWVkIHVzaW5nIENBUworICAgICAgICAgKiAob3Igd2hlbiBwb3NzaWJsZSwgdW5jb25kaXRpb25hbCB2b2xhdGlsZSB3cml0ZXMpLgorICAgICAgICAgKi8KKyAgICAgICAgdm9sYXRpbGUgaW50IHdhaXRTdGF0dXM7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIExpbmsgdG8gcHJlZGVjZXNzb3Igbm9kZSB0aGF0IGN1cnJlbnQgbm9kZS90aHJlYWQgcmVsaWVzIG9uCisgICAgICAgICAqIGZvciBjaGVja2luZyB3YWl0U3RhdHVzLiBBc3NpZ25lZCBkdXJpbmcgZW5xdWVpbmcsIGFuZCBudWxsZWQKKyAgICAgICAgICogb3V0IChmb3Igc2FrZSBvZiBHQykgb25seSB1cG9uIGRlcXVldWluZy4gIEFsc28sIHVwb24KKyAgICAgICAgICogY2FuY2VsbGF0aW9uIG9mIGEgcHJlZGVjZXNzb3IsIHdlIHNob3J0LWNpcmN1aXQgd2hpbGUKKyAgICAgICAgICogZmluZGluZyBhIG5vbi1jYW5jZWxsZWQgb25lLCB3aGljaCB3aWxsIGFsd2F5cyBleGlzdAorICAgICAgICAgKiBiZWNhdXNlIHRoZSBoZWFkIG5vZGUgaXMgbmV2ZXIgY2FuY2VsbGVkOiBBIG5vZGUgYmVjb21lcworICAgICAgICAgKiBoZWFkIG9ubHkgYXMgYSByZXN1bHQgb2Ygc3VjY2Vzc2Z1bCBhY3F1aXJlLiBBCisgICAgICAgICAqIGNhbmNlbGxlZCB0aHJlYWQgbmV2ZXIgc3VjY2VlZHMgaW4gYWNxdWlyaW5nLCBhbmQgYSB0aHJlYWQgb25seQorICAgICAgICAgKiBjYW5jZWxzIGl0c2VsZiwgbm90IGFueSBvdGhlciBub2RlLgorICAgICAgICAgKi8KKyAgICAgICAgdm9sYXRpbGUgTm9kZSBwcmV2OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBMaW5rIHRvIHRoZSBzdWNjZXNzb3Igbm9kZSB0aGF0IHRoZSBjdXJyZW50IG5vZGUvdGhyZWFkCisgICAgICAgICAqIHVucGFya3MgdXBvbiByZWxlYXNlLiBBc3NpZ25lZCBkdXJpbmcgZW5xdWV1aW5nLCBhZGp1c3RlZAorICAgICAgICAgKiB3aGVuIGJ5cGFzc2luZyBjYW5jZWxsZWQgcHJlZGVjZXNzb3JzLCBhbmQgbnVsbGVkIG91dCAoZm9yCisgICAgICAgICAqIHNha2Ugb2YgR0MpIHdoZW4gZGVxdWV1ZWQuICBUaGUgZW5xIG9wZXJhdGlvbiBkb2VzIG5vdAorICAgICAgICAgKiBhc3NpZ24gbmV4dCBmaWVsZCBvZiBhIHByZWRlY2Vzc29yIHVudGlsIGFmdGVyIGF0dGFjaG1lbnQsCisgICAgICAgICAqIHNvIHNlZWluZyBhIG51bGwgbmV4dCBmaWVsZCBkb2VzIG5vdCBuZWNlc3NhcmlseSBtZWFuIHRoYXQKKyAgICAgICAgICogbm9kZSBpcyBhdCBlbmQgb2YgcXVldWUuIEhvd2V2ZXIsIGlmIGEgbmV4dCBmaWVsZCBhcHBlYXJzCisgICAgICAgICAqIHRvIGJlIG51bGwsIHdlIGNhbiBzY2FuIHByZXYncyBmcm9tIHRoZSB0YWlsIHRvCisgICAgICAgICAqIGRvdWJsZS1jaGVjay4gIFRoZSBuZXh0IGZpZWxkIG9mIGNhbmNlbGxlZCBub2RlcyBpcyBzZXQgdG8KKyAgICAgICAgICogcG9pbnQgdG8gdGhlIG5vZGUgaXRzZWxmIGluc3RlYWQgb2YgbnVsbCwgdG8gbWFrZSBsaWZlCisgICAgICAgICAqIGVhc2llciBmb3IgaXNPblN5bmNRdWV1ZS4KKyAgICAgICAgICovCisgICAgICAgIHZvbGF0aWxlIE5vZGUgbmV4dDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHRocmVhZCB0aGF0IGVucXVldWVkIHRoaXMgbm9kZS4gIEluaXRpYWxpemVkIG9uCisgICAgICAgICAqIGNvbnN0cnVjdGlvbiBhbmQgbnVsbGVkIG91dCBhZnRlciB1c2UuCisgICAgICAgICAqLworICAgICAgICB2b2xhdGlsZSBUaHJlYWQgdGhyZWFkOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBMaW5rIHRvIG5leHQgbm9kZSB3YWl0aW5nIG9uIGNvbmRpdGlvbiwgb3IgdGhlIHNwZWNpYWwKKyAgICAgICAgICogdmFsdWUgU0hBUkVELiAgQmVjYXVzZSBjb25kaXRpb24gcXVldWVzIGFyZSBhY2Nlc3NlZCBvbmx5CisgICAgICAgICAqIHdoZW4gaG9sZGluZyBpbiBleGNsdXNpdmUgbW9kZSwgd2UganVzdCBuZWVkIGEgc2ltcGxlCisgICAgICAgICAqIGxpbmtlZCBxdWV1ZSB0byBob2xkIG5vZGVzIHdoaWxlIHRoZXkgYXJlIHdhaXRpbmcgb24KKyAgICAgICAgICogY29uZGl0aW9ucy4gVGhleSBhcmUgdGhlbiB0cmFuc2ZlcnJlZCB0byB0aGUgcXVldWUgdG8KKyAgICAgICAgICogcmUtYWNxdWlyZS4gQW5kIGJlY2F1c2UgY29uZGl0aW9ucyBjYW4gb25seSBiZSBleGNsdXNpdmUsCisgICAgICAgICAqIHdlIHNhdmUgYSBmaWVsZCBieSB1c2luZyBzcGVjaWFsIHZhbHVlIHRvIGluZGljYXRlIHNoYXJlZAorICAgICAgICAgKiBtb2RlLgorICAgICAgICAgKi8KKyAgICAgICAgTm9kZSBuZXh0V2FpdGVyOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgbm9kZSBpcyB3YWl0aW5nIGluIHNoYXJlZCBtb2RlCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBib29sZWFuIGlzU2hhcmVkKCkgeworICAgICAgICAgICAgcmV0dXJuIG5leHRXYWl0ZXIgPT0gU0hBUkVEOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgcHJldmlvdXMgbm9kZSwgb3IgdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIG51bGwuCisgICAgICAgICAqIFVzZSB3aGVuIHByZWRlY2Vzc29yIGNhbm5vdCBiZSBudWxsLiAgVGhlIG51bGwgY2hlY2sgY291bGQKKyAgICAgICAgICogYmUgZWxpZGVkLCBidXQgaXMgcHJlc2VudCB0byBoZWxwIHRoZSBWTS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUgcHJlZGVjZXNzb3Igb2YgdGhpcyBub2RlCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBOb2RlIHByZWRlY2Vzc29yKCkgdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIE5vZGUgcCA9IHByZXY7CisgICAgICAgICAgICBpZiAocCA9PSBudWxsKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHJldHVybiBwOworICAgICAgICB9CisKKyAgICAgICAgTm9kZSgpIHsgICAgLy8gVXNlZCB0byBlc3RhYmxpc2ggaW5pdGlhbCBoZWFkIG9yIFNIQVJFRCBtYXJrZXIKKyAgICAgICAgfQorCisgICAgICAgIE5vZGUoVGhyZWFkIHRocmVhZCwgTm9kZSBtb2RlKSB7ICAgICAvLyBVc2VkIGJ5IGFkZFdhaXRlcgorICAgICAgICAgICAgdGhpcy5uZXh0V2FpdGVyID0gbW9kZTsKKyAgICAgICAgICAgIHRoaXMudGhyZWFkID0gdGhyZWFkOworICAgICAgICB9CisKKyAgICAgICAgTm9kZShUaHJlYWQgdGhyZWFkLCBpbnQgd2FpdFN0YXR1cykgeyAvLyBVc2VkIGJ5IENvbmRpdGlvbgorICAgICAgICAgICAgdGhpcy53YWl0U3RhdHVzID0gd2FpdFN0YXR1czsKKyAgICAgICAgICAgIHRoaXMudGhyZWFkID0gdGhyZWFkOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSGVhZCBvZiB0aGUgd2FpdCBxdWV1ZSwgbGF6aWx5IGluaXRpYWxpemVkLiAgRXhjZXB0IGZvcgorICAgICAqIGluaXRpYWxpemF0aW9uLCBpdCBpcyBtb2RpZmllZCBvbmx5IHZpYSBtZXRob2Qgc2V0SGVhZC4gIE5vdGU6CisgICAgICogSWYgaGVhZCBleGlzdHMsIGl0cyB3YWl0U3RhdHVzIGlzIGd1YXJhbnRlZWQgbm90IHRvIGJlCisgICAgICogQ0FOQ0VMTEVELgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IHZvbGF0aWxlIE5vZGUgaGVhZDsKKworICAgIC8qKgorICAgICAqIFRhaWwgb2YgdGhlIHdhaXQgcXVldWUsIGxhemlseSBpbml0aWFsaXplZC4gIE1vZGlmaWVkIG9ubHkgdmlhCisgICAgICogbWV0aG9kIGVucSB0byBhZGQgbmV3IHdhaXQgbm9kZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHRyYW5zaWVudCB2b2xhdGlsZSBOb2RlIHRhaWw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3luY2hyb25pemF0aW9uIHN0YXRlLgorICAgICAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgbG9uZyBzdGF0ZTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgdmFsdWUgb2Ygc3luY2hyb25pemF0aW9uIHN0YXRlLgorICAgICAqIFRoaXMgb3BlcmF0aW9uIGhhcyBtZW1vcnkgc2VtYW50aWNzIG9mIGEgPHR0PnZvbGF0aWxlPC90dD4gcmVhZC4KKyAgICAgKiBAcmV0dXJuIGN1cnJlbnQgc3RhdGUgdmFsdWUKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgbG9uZyBnZXRTdGF0ZSgpIHsKKyAgICAgICAgcmV0dXJuIHN0YXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHN5bmNocm9uaXphdGlvbiBzdGF0ZS4KKyAgICAgKiBUaGlzIG9wZXJhdGlvbiBoYXMgbWVtb3J5IHNlbWFudGljcyBvZiBhIDx0dD52b2xhdGlsZTwvdHQ+IHdyaXRlLgorICAgICAqIEBwYXJhbSBuZXdTdGF0ZSB0aGUgbmV3IHN0YXRlIHZhbHVlCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0U3RhdGUobG9uZyBuZXdTdGF0ZSkgeworICAgICAgICBzdGF0ZSA9IG5ld1N0YXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0b21pY2FsbHkgc2V0cyBzeW5jaHJvbml6YXRpb24gc3RhdGUgdG8gdGhlIGdpdmVuIHVwZGF0ZWQKKyAgICAgKiB2YWx1ZSBpZiB0aGUgY3VycmVudCBzdGF0ZSB2YWx1ZSBlcXVhbHMgdGhlIGV4cGVjdGVkIHZhbHVlLgorICAgICAqIFRoaXMgb3BlcmF0aW9uIGhhcyBtZW1vcnkgc2VtYW50aWNzIG9mIGEgPHR0PnZvbGF0aWxlPC90dD4gcmVhZAorICAgICAqIGFuZCB3cml0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleHBlY3QgdGhlIGV4cGVjdGVkIHZhbHVlCisgICAgICogQHBhcmFtIHVwZGF0ZSB0aGUgbmV3IHZhbHVlCisgICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwuIEZhbHNlIHJldHVybiBpbmRpY2F0ZXMgdGhhdCB0aGUgYWN0dWFsCisgICAgICogICAgICAgICB2YWx1ZSB3YXMgbm90IGVxdWFsIHRvIHRoZSBleHBlY3RlZCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiBjb21wYXJlQW5kU2V0U3RhdGUobG9uZyBleHBlY3QsIGxvbmcgdXBkYXRlKSB7CisgICAgICAgIC8vIFNlZSBiZWxvdyBmb3IgaW50cmluc2ljcyBzZXR1cCB0byBzdXBwb3J0IHRoaXMKKyAgICAgICAgcmV0dXJuIHVuc2FmZS5jb21wYXJlQW5kU3dhcExvbmcodGhpcywgc3RhdGVPZmZzZXQsIGV4cGVjdCwgdXBkYXRlKTsKKyAgICB9CisKKyAgICAvLyBRdWV1aW5nIHV0aWxpdGllcworCisgICAgLyoqCisgICAgICogVGhlIG51bWJlciBvZiBuYW5vc2Vjb25kcyBmb3Igd2hpY2ggaXQgaXMgZmFzdGVyIHRvIHNwaW4KKyAgICAgKiByYXRoZXIgdGhhbiB0byB1c2UgdGltZWQgcGFyay4gQSByb3VnaCBlc3RpbWF0ZSBzdWZmaWNlcworICAgICAqIHRvIGltcHJvdmUgcmVzcG9uc2l2ZW5lc3Mgd2l0aCB2ZXJ5IHNob3J0IHRpbWVvdXRzLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBsb25nIHNwaW5Gb3JUaW1lb3V0VGhyZXNob2xkID0gMTAwMEw7CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIG5vZGUgaW50byBxdWV1ZSwgaW5pdGlhbGl6aW5nIGlmIG5lY2Vzc2FyeS4gU2VlIHBpY3R1cmUgYWJvdmUuCisgICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgdG8gaW5zZXJ0CisgICAgICogQHJldHVybiBub2RlJ3MgcHJlZGVjZXNzb3IKKyAgICAgKi8KKyAgICBwcml2YXRlIE5vZGUgZW5xKGZpbmFsIE5vZGUgbm9kZSkgeworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBOb2RlIHQgPSB0YWlsOworICAgICAgICAgICAgaWYgKHQgPT0gbnVsbCkgeyAvLyBNdXN0IGluaXRpYWxpemUKKyAgICAgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldEhlYWQobmV3IE5vZGUoKSkpCisgICAgICAgICAgICAgICAgICAgIHRhaWwgPSBoZWFkOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBub2RlLnByZXYgPSB0OworICAgICAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0VGFpbCh0LCBub2RlKSkgeworICAgICAgICAgICAgICAgICAgICB0Lm5leHQgPSBub2RlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuZCBlbnF1ZXVlcyBub2RlIGZvciBjdXJyZW50IHRocmVhZCBhbmQgZ2l2ZW4gbW9kZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb2RlIE5vZGUuRVhDTFVTSVZFIGZvciBleGNsdXNpdmUsIE5vZGUuU0hBUkVEIGZvciBzaGFyZWQKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcgbm9kZQorICAgICAqLworICAgIHByaXZhdGUgTm9kZSBhZGRXYWl0ZXIoTm9kZSBtb2RlKSB7CisgICAgICAgIE5vZGUgbm9kZSA9IG5ldyBOb2RlKFRocmVhZC5jdXJyZW50VGhyZWFkKCksIG1vZGUpOworICAgICAgICAvLyBUcnkgdGhlIGZhc3QgcGF0aCBvZiBlbnE7IGJhY2t1cCB0byBmdWxsIGVucSBvbiBmYWlsdXJlCisgICAgICAgIE5vZGUgcHJlZCA9IHRhaWw7CisgICAgICAgIGlmIChwcmVkICE9IG51bGwpIHsKKyAgICAgICAgICAgIG5vZGUucHJldiA9IHByZWQ7CisgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldFRhaWwocHJlZCwgbm9kZSkpIHsKKyAgICAgICAgICAgICAgICBwcmVkLm5leHQgPSBub2RlOworICAgICAgICAgICAgICAgIHJldHVybiBub2RlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVucShub2RlKTsKKyAgICAgICAgcmV0dXJuIG5vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBoZWFkIG9mIHF1ZXVlIHRvIGJlIG5vZGUsIHRodXMgZGVxdWV1aW5nLiBDYWxsZWQgb25seSBieQorICAgICAqIGFjcXVpcmUgbWV0aG9kcy4gIEFsc28gbnVsbHMgb3V0IHVudXNlZCBmaWVsZHMgZm9yIHNha2Ugb2YgR0MKKyAgICAgKiBhbmQgdG8gc3VwcHJlc3MgdW5uZWNlc3Nhcnkgc2lnbmFscyBhbmQgdHJhdmVyc2Fscy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNldEhlYWQoTm9kZSBub2RlKSB7CisgICAgICAgIGhlYWQgPSBub2RlOworICAgICAgICBub2RlLnRocmVhZCA9IG51bGw7CisgICAgICAgIG5vZGUucHJldiA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2FrZXMgdXAgbm9kZSdzIHN1Y2Nlc3NvciwgaWYgb25lIGV4aXN0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHVucGFya1N1Y2Nlc3NvcihOb2RlIG5vZGUpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogSWYgc3RhdHVzIGlzIG5lZ2F0aXZlIChpLmUuLCBwb3NzaWJseSBuZWVkaW5nIHNpZ25hbCkgdHJ5CisgICAgICAgICAqIHRvIGNsZWFyIGluIGFudGljaXBhdGlvbiBvZiBzaWduYWxsaW5nLiAgSXQgaXMgT0sgaWYgdGhpcworICAgICAgICAgKiBmYWlscyBvciBpZiBzdGF0dXMgaXMgY2hhbmdlZCBieSB3YWl0aW5nIHRocmVhZC4KKyAgICAgICAgICovCisgICAgICAgIGludCB3cyA9IG5vZGUud2FpdFN0YXR1czsKKyAgICAgICAgaWYgKHdzIDwgMCkKKyAgICAgICAgICAgIGNvbXBhcmVBbmRTZXRXYWl0U3RhdHVzKG5vZGUsIHdzLCAwKTsKKworICAgICAgICAvKgorICAgICAgICAgKiBUaHJlYWQgdG8gdW5wYXJrIGlzIGhlbGQgaW4gc3VjY2Vzc29yLCB3aGljaCBpcyBub3JtYWxseQorICAgICAgICAgKiBqdXN0IHRoZSBuZXh0IG5vZGUuICBCdXQgaWYgY2FuY2VsbGVkIG9yIGFwcGFyZW50bHkgbnVsbCwKKyAgICAgICAgICogdHJhdmVyc2UgYmFja3dhcmRzIGZyb20gdGFpbCB0byBmaW5kIHRoZSBhY3R1YWwKKyAgICAgICAgICogbm9uLWNhbmNlbGxlZCBzdWNjZXNzb3IuCisgICAgICAgICAqLworICAgICAgICBOb2RlIHMgPSBub2RlLm5leHQ7CisgICAgICAgIGlmIChzID09IG51bGwgfHwgcy53YWl0U3RhdHVzID4gMCkgeworICAgICAgICAgICAgcyA9IG51bGw7CisgICAgICAgICAgICBmb3IgKE5vZGUgdCA9IHRhaWw7IHQgIT0gbnVsbCAmJiB0ICE9IG5vZGU7IHQgPSB0LnByZXYpCisgICAgICAgICAgICAgICAgaWYgKHQud2FpdFN0YXR1cyA8PSAwKQorICAgICAgICAgICAgICAgICAgICBzID0gdDsKKyAgICAgICAgfQorICAgICAgICBpZiAocyAhPSBudWxsKQorICAgICAgICAgICAgTG9ja1N1cHBvcnQudW5wYXJrKHMudGhyZWFkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWxlYXNlIGFjdGlvbiBmb3Igc2hhcmVkIG1vZGUgLS0gc2lnbmFsIHN1Y2Nlc3NvciBhbmQgZW5zdXJlCisgICAgICogcHJvcGFnYXRpb24uIChOb3RlOiBGb3IgZXhjbHVzaXZlIG1vZGUsIHJlbGVhc2UganVzdCBhbW91bnRzCisgICAgICogdG8gY2FsbGluZyB1bnBhcmtTdWNjZXNzb3Igb2YgaGVhZCBpZiBpdCBuZWVkcyBzaWduYWwuKQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBkb1JlbGVhc2VTaGFyZWQoKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIEVuc3VyZSB0aGF0IGEgcmVsZWFzZSBwcm9wYWdhdGVzLCBldmVuIGlmIHRoZXJlIGFyZSBvdGhlcgorICAgICAgICAgKiBpbi1wcm9ncmVzcyBhY3F1aXJlcy9yZWxlYXNlcy4gIFRoaXMgcHJvY2VlZHMgaW4gdGhlIHVzdWFsCisgICAgICAgICAqIHdheSBvZiB0cnlpbmcgdG8gdW5wYXJrU3VjY2Vzc29yIG9mIGhlYWQgaWYgaXQgbmVlZHMKKyAgICAgICAgICogc2lnbmFsLiBCdXQgaWYgaXQgZG9lcyBub3QsIHN0YXR1cyBpcyBzZXQgdG8gUFJPUEFHQVRFIHRvCisgICAgICAgICAqIGVuc3VyZSB0aGF0IHVwb24gcmVsZWFzZSwgcHJvcGFnYXRpb24gY29udGludWVzLgorICAgICAgICAgKiBBZGRpdGlvbmFsbHksIHdlIG11c3QgbG9vcCBpbiBjYXNlIGEgbmV3IG5vZGUgaXMgYWRkZWQKKyAgICAgICAgICogd2hpbGUgd2UgYXJlIGRvaW5nIHRoaXMuIEFsc28sIHVubGlrZSBvdGhlciB1c2VzIG9mCisgICAgICAgICAqIHVucGFya1N1Y2Nlc3Nvciwgd2UgbmVlZCB0byBrbm93IGlmIENBUyB0byByZXNldCBzdGF0dXMKKyAgICAgICAgICogZmFpbHMsIGlmIHNvIHJlY2hlY2tpbmcuCisgICAgICAgICAqLworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBOb2RlIGggPSBoZWFkOworICAgICAgICAgICAgaWYgKGggIT0gbnVsbCAmJiBoICE9IHRhaWwpIHsKKyAgICAgICAgICAgICAgICBpbnQgd3MgPSBoLndhaXRTdGF0dXM7CisgICAgICAgICAgICAgICAgaWYgKHdzID09IE5vZGUuU0lHTkFMKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICghY29tcGFyZUFuZFNldFdhaXRTdGF0dXMoaCwgTm9kZS5TSUdOQUwsIDApKQorICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7ICAgICAgICAgICAgLy8gbG9vcCB0byByZWNoZWNrIGNhc2VzCisgICAgICAgICAgICAgICAgICAgIHVucGFya1N1Y2Nlc3NvcihoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZSBpZiAod3MgPT0gMCAmJgorICAgICAgICAgICAgICAgICAgICAgICAgICFjb21wYXJlQW5kU2V0V2FpdFN0YXR1cyhoLCAwLCBOb2RlLlBST1BBR0FURSkpCisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOyAgICAgICAgICAgICAgICAvLyBsb29wIG9uIGZhaWxlZCBDQVMKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChoID09IGhlYWQpICAgICAgICAgICAgICAgICAgIC8vIGxvb3AgaWYgaGVhZCBjaGFuZ2VkCisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGhlYWQgb2YgcXVldWUsIGFuZCBjaGVja3MgaWYgc3VjY2Vzc29yIG1heSBiZSB3YWl0aW5nCisgICAgICogaW4gc2hhcmVkIG1vZGUsIGlmIHNvIHByb3BhZ2F0aW5nIGlmIGVpdGhlciBwcm9wYWdhdGUgPiAwIG9yCisgICAgICogUFJPUEFHQVRFIHN0YXR1cyB3YXMgc2V0LgorICAgICAqCisgICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUKKyAgICAgKiBAcGFyYW0gcHJvcGFnYXRlIHRoZSByZXR1cm4gdmFsdWUgZnJvbSBhIHRyeUFjcXVpcmVTaGFyZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0SGVhZEFuZFByb3BhZ2F0ZShOb2RlIG5vZGUsIGxvbmcgcHJvcGFnYXRlKSB7CisgICAgICAgIE5vZGUgaCA9IGhlYWQ7IC8vIFJlY29yZCBvbGQgaGVhZCBmb3IgY2hlY2sgYmVsb3cKKyAgICAgICAgc2V0SGVhZChub2RlKTsKKyAgICAgICAgLyoKKyAgICAgICAgICogVHJ5IHRvIHNpZ25hbCBuZXh0IHF1ZXVlZCBub2RlIGlmOgorICAgICAgICAgKiAgIFByb3BhZ2F0aW9uIHdhcyBpbmRpY2F0ZWQgYnkgY2FsbGVyLAorICAgICAgICAgKiAgICAgb3Igd2FzIHJlY29yZGVkIChhcyBoLndhaXRTdGF0dXMpIGJ5IGEgcHJldmlvdXMgb3BlcmF0aW9uCisgICAgICAgICAqICAgICAobm90ZTogdGhpcyB1c2VzIHNpZ24tY2hlY2sgb2Ygd2FpdFN0YXR1cyBiZWNhdXNlCisgICAgICAgICAqICAgICAgUFJPUEFHQVRFIHN0YXR1cyBtYXkgdHJhbnNpdGlvbiB0byBTSUdOQUwuKQorICAgICAgICAgKiBhbmQKKyAgICAgICAgICogICBUaGUgbmV4dCBub2RlIGlzIHdhaXRpbmcgaW4gc2hhcmVkIG1vZGUsCisgICAgICAgICAqICAgICBvciB3ZSBkb24ndCBrbm93LCBiZWNhdXNlIGl0IGFwcGVhcnMgbnVsbAorICAgICAgICAgKgorICAgICAgICAgKiBUaGUgY29uc2VydmF0aXNtIGluIGJvdGggb2YgdGhlc2UgY2hlY2tzIG1heSBjYXVzZQorICAgICAgICAgKiB1bm5lY2Vzc2FyeSB3YWtlLXVwcywgYnV0IG9ubHkgd2hlbiB0aGVyZSBhcmUgbXVsdGlwbGUKKyAgICAgICAgICogcmFjaW5nIGFjcXVpcmVzL3JlbGVhc2VzLCBzbyBtb3N0IG5lZWQgc2lnbmFscyBub3cgb3Igc29vbgorICAgICAgICAgKiBhbnl3YXkuCisgICAgICAgICAqLworICAgICAgICBpZiAocHJvcGFnYXRlID4gMCB8fCBoID09IG51bGwgfHwgaC53YWl0U3RhdHVzIDwgMCkgeworICAgICAgICAgICAgTm9kZSBzID0gbm9kZS5uZXh0OworICAgICAgICAgICAgaWYgKHMgPT0gbnVsbCB8fCBzLmlzU2hhcmVkKCkpCisgICAgICAgICAgICAgICAgZG9SZWxlYXNlU2hhcmVkKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBVdGlsaXRpZXMgZm9yIHZhcmlvdXMgdmVyc2lvbnMgb2YgYWNxdWlyZQorCisgICAgLyoqCisgICAgICogQ2FuY2VscyBhbiBvbmdvaW5nIGF0dGVtcHQgdG8gYWNxdWlyZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNhbmNlbEFjcXVpcmUoTm9kZSBub2RlKSB7CisgICAgICAgIC8vIElnbm9yZSBpZiBub2RlIGRvZXNuJ3QgZXhpc3QKKyAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkKKyAgICAgICAgICAgIHJldHVybjsKKworICAgICAgICBub2RlLnRocmVhZCA9IG51bGw7CisKKyAgICAgICAgLy8gU2tpcCBjYW5jZWxsZWQgcHJlZGVjZXNzb3JzCisgICAgICAgIE5vZGUgcHJlZCA9IG5vZGUucHJldjsKKyAgICAgICAgd2hpbGUgKHByZWQud2FpdFN0YXR1cyA+IDApCisgICAgICAgICAgICBub2RlLnByZXYgPSBwcmVkID0gcHJlZC5wcmV2OworCisgICAgICAgIC8vIHByZWROZXh0IGlzIHRoZSBhcHBhcmVudCBub2RlIHRvIHVuc3BsaWNlLiBDQVNlcyBiZWxvdyB3aWxsCisgICAgICAgIC8vIGZhaWwgaWYgbm90LCBpbiB3aGljaCBjYXNlLCB3ZSBsb3N0IHJhY2UgdnMgYW5vdGhlciBjYW5jZWwKKyAgICAgICAgLy8gb3Igc2lnbmFsLCBzbyBubyBmdXJ0aGVyIGFjdGlvbiBpcyBuZWNlc3NhcnkuCisgICAgICAgIE5vZGUgcHJlZE5leHQgPSBwcmVkLm5leHQ7CisKKyAgICAgICAgLy8gQ2FuIHVzZSB1bmNvbmRpdGlvbmFsIHdyaXRlIGluc3RlYWQgb2YgQ0FTIGhlcmUuCisgICAgICAgIC8vIEFmdGVyIHRoaXMgYXRvbWljIHN0ZXAsIG90aGVyIE5vZGVzIGNhbiBza2lwIHBhc3QgdXMuCisgICAgICAgIC8vIEJlZm9yZSwgd2UgYXJlIGZyZWUgb2YgaW50ZXJmZXJlbmNlIGZyb20gb3RoZXIgdGhyZWFkcy4KKyAgICAgICAgbm9kZS53YWl0U3RhdHVzID0gTm9kZS5DQU5DRUxMRUQ7CisKKyAgICAgICAgLy8gSWYgd2UgYXJlIHRoZSB0YWlsLCByZW1vdmUgb3Vyc2VsdmVzLgorICAgICAgICBpZiAobm9kZSA9PSB0YWlsICYmIGNvbXBhcmVBbmRTZXRUYWlsKG5vZGUsIHByZWQpKSB7CisgICAgICAgICAgICBjb21wYXJlQW5kU2V0TmV4dChwcmVkLCBwcmVkTmV4dCwgbnVsbCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBJZiBzdWNjZXNzb3IgbmVlZHMgc2lnbmFsLCB0cnkgdG8gc2V0IHByZWQncyBuZXh0LWxpbmsKKyAgICAgICAgICAgIC8vIHNvIGl0IHdpbGwgZ2V0IG9uZS4gT3RoZXJ3aXNlIHdha2UgaXQgdXAgdG8gcHJvcGFnYXRlLgorICAgICAgICAgICAgaW50IHdzOworICAgICAgICAgICAgaWYgKHByZWQgIT0gaGVhZCAmJgorICAgICAgICAgICAgICAgICgod3MgPSBwcmVkLndhaXRTdGF0dXMpID09IE5vZGUuU0lHTkFMIHx8CisgICAgICAgICAgICAgICAgICh3cyA8PSAwICYmIGNvbXBhcmVBbmRTZXRXYWl0U3RhdHVzKHByZWQsIHdzLCBOb2RlLlNJR05BTCkpKSAmJgorICAgICAgICAgICAgICAgIHByZWQudGhyZWFkICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBOb2RlIG5leHQgPSBub2RlLm5leHQ7CisgICAgICAgICAgICAgICAgaWYgKG5leHQgIT0gbnVsbCAmJiBuZXh0LndhaXRTdGF0dXMgPD0gMCkKKyAgICAgICAgICAgICAgICAgICAgY29tcGFyZUFuZFNldE5leHQocHJlZCwgcHJlZE5leHQsIG5leHQpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB1bnBhcmtTdWNjZXNzb3Iobm9kZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIG5vZGUubmV4dCA9IG5vZGU7IC8vIGhlbHAgR0MKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBhbmQgdXBkYXRlcyBzdGF0dXMgZm9yIGEgbm9kZSB0aGF0IGZhaWxlZCB0byBhY3F1aXJlLgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aHJlYWQgc2hvdWxkIGJsb2NrLiBUaGlzIGlzIHRoZSBtYWluIHNpZ25hbAorICAgICAqIGNvbnRyb2wgaW4gYWxsIGFjcXVpcmUgbG9vcHMuICBSZXF1aXJlcyB0aGF0IHByZWQgPT0gbm9kZS5wcmV2CisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJlZCBub2RlJ3MgcHJlZGVjZXNzb3IgaG9sZGluZyBzdGF0dXMKKyAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZQorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRocmVhZCBzaG91bGQgYmxvY2sKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHNob3VsZFBhcmtBZnRlckZhaWxlZEFjcXVpcmUoTm9kZSBwcmVkLCBOb2RlIG5vZGUpIHsKKyAgICAgICAgaW50IHdzID0gcHJlZC53YWl0U3RhdHVzOworICAgICAgICBpZiAod3MgPT0gTm9kZS5TSUdOQUwpCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogVGhpcyBub2RlIGhhcyBhbHJlYWR5IHNldCBzdGF0dXMgYXNraW5nIGEgcmVsZWFzZQorICAgICAgICAgICAgICogdG8gc2lnbmFsIGl0LCBzbyBpdCBjYW4gc2FmZWx5IHBhcmsuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBpZiAod3MgPiAwKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogUHJlZGVjZXNzb3Igd2FzIGNhbmNlbGxlZC4gU2tpcCBvdmVyIHByZWRlY2Vzc29ycyBhbmQKKyAgICAgICAgICAgICAqIGluZGljYXRlIHJldHJ5LgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgbm9kZS5wcmV2ID0gcHJlZCA9IHByZWQucHJldjsKKyAgICAgICAgICAgIH0gd2hpbGUgKHByZWQud2FpdFN0YXR1cyA+IDApOworICAgICAgICAgICAgcHJlZC5uZXh0ID0gbm9kZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiB3YWl0U3RhdHVzIG11c3QgYmUgMCBvciBQUk9QQUdBVEUuICBJbmRpY2F0ZSB0aGF0IHdlCisgICAgICAgICAgICAgKiBuZWVkIGEgc2lnbmFsLCBidXQgZG9uJ3QgcGFyayB5ZXQuICBDYWxsZXIgd2lsbCBuZWVkIHRvCisgICAgICAgICAgICAgKiByZXRyeSB0byBtYWtlIHN1cmUgaXQgY2Fubm90IGFjcXVpcmUgYmVmb3JlIHBhcmtpbmcuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGNvbXBhcmVBbmRTZXRXYWl0U3RhdHVzKHByZWQsIHdzLCBOb2RlLlNJR05BTCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCB0byBpbnRlcnJ1cHQgY3VycmVudCB0aHJlYWQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBzZWxmSW50ZXJydXB0KCkgeworICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLmludGVycnVwdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCB0byBwYXJrIGFuZCB0aGVuIGNoZWNrIGlmIGludGVycnVwdGVkCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBpbnRlcnJ1cHRlZAorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBwYXJrQW5kQ2hlY2tJbnRlcnJ1cHQoKSB7CisgICAgICAgIExvY2tTdXBwb3J0LnBhcmsodGhpcyk7CisgICAgICAgIHJldHVybiBUaHJlYWQuaW50ZXJydXB0ZWQoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFZhcmlvdXMgZmxhdm9ycyBvZiBhY3F1aXJlLCB2YXJ5aW5nIGluIGV4Y2x1c2l2ZS9zaGFyZWQgYW5kCisgICAgICogY29udHJvbCBtb2Rlcy4gIEVhY2ggaXMgbW9zdGx5IHRoZSBzYW1lLCBidXQgYW5ub3lpbmdseQorICAgICAqIGRpZmZlcmVudC4gIE9ubHkgYSBsaXR0bGUgYml0IG9mIGZhY3RvcmluZyBpcyBwb3NzaWJsZSBkdWUgdG8KKyAgICAgKiBpbnRlcmFjdGlvbnMgb2YgZXhjZXB0aW9uIG1lY2hhbmljcyAoaW5jbHVkaW5nIGVuc3VyaW5nIHRoYXQgd2UKKyAgICAgKiBjYW5jZWwgaWYgdHJ5QWNxdWlyZSB0aHJvd3MgZXhjZXB0aW9uKSBhbmQgb3RoZXIgY29udHJvbCwgYXQKKyAgICAgKiBsZWFzdCBub3Qgd2l0aG91dCBodXJ0aW5nIHBlcmZvcm1hbmNlIHRvbyBtdWNoLgorICAgICAqLworCisgICAgLyoqCisgICAgICogQWNxdWlyZXMgaW4gZXhjbHVzaXZlIHVuaW50ZXJydXB0aWJsZSBtb2RlIGZvciB0aHJlYWQgYWxyZWFkeSBpbgorICAgICAqIHF1ZXVlLiBVc2VkIGJ5IGNvbmRpdGlvbiB3YWl0IG1ldGhvZHMgYXMgd2VsbCBhcyBhY3F1aXJlLgorICAgICAqCisgICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUKKyAgICAgKiBAcGFyYW0gYXJnIHRoZSBhY3F1aXJlIGFyZ3VtZW50CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgaW50ZXJydXB0ZWQgd2hpbGUgd2FpdGluZworICAgICAqLworICAgIGZpbmFsIGJvb2xlYW4gYWNxdWlyZVF1ZXVlZChmaW5hbCBOb2RlIG5vZGUsIGxvbmcgYXJnKSB7CisgICAgICAgIGJvb2xlYW4gZmFpbGVkID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJvb2xlYW4gaW50ZXJydXB0ZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBOb2RlIHAgPSBub2RlLnByZWRlY2Vzc29yKCk7CisgICAgICAgICAgICAgICAgaWYgKHAgPT0gaGVhZCAmJiB0cnlBY3F1aXJlKGFyZykpIHsKKyAgICAgICAgICAgICAgICAgICAgc2V0SGVhZChub2RlKTsKKyAgICAgICAgICAgICAgICAgICAgcC5uZXh0ID0gbnVsbDsgLy8gaGVscCBHQworICAgICAgICAgICAgICAgICAgICBmYWlsZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGludGVycnVwdGVkOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoc2hvdWxkUGFya0FmdGVyRmFpbGVkQWNxdWlyZShwLCBub2RlKSAmJgorICAgICAgICAgICAgICAgICAgICBwYXJrQW5kQ2hlY2tJbnRlcnJ1cHQoKSkKKyAgICAgICAgICAgICAgICAgICAgaW50ZXJydXB0ZWQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGZhaWxlZCkKKyAgICAgICAgICAgICAgICBjYW5jZWxBY3F1aXJlKG5vZGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQWNxdWlyZXMgaW4gZXhjbHVzaXZlIGludGVycnVwdGlibGUgbW9kZS4KKyAgICAgKiBAcGFyYW0gYXJnIHRoZSBhY3F1aXJlIGFyZ3VtZW50CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGRvQWNxdWlyZUludGVycnVwdGlibHkobG9uZyBhcmcpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIE5vZGUgbm9kZSA9IGFkZFdhaXRlcihOb2RlLkVYQ0xVU0lWRSk7CisgICAgICAgIGJvb2xlYW4gZmFpbGVkID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBOb2RlIHAgPSBub2RlLnByZWRlY2Vzc29yKCk7CisgICAgICAgICAgICAgICAgaWYgKHAgPT0gaGVhZCAmJiB0cnlBY3F1aXJlKGFyZykpIHsKKyAgICAgICAgICAgICAgICAgICAgc2V0SGVhZChub2RlKTsKKyAgICAgICAgICAgICAgICAgICAgcC5uZXh0ID0gbnVsbDsgLy8gaGVscCBHQworICAgICAgICAgICAgICAgICAgICBmYWlsZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoc2hvdWxkUGFya0FmdGVyRmFpbGVkQWNxdWlyZShwLCBub2RlKSAmJgorICAgICAgICAgICAgICAgICAgICBwYXJrQW5kQ2hlY2tJbnRlcnJ1cHQoKSkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoZmFpbGVkKQorICAgICAgICAgICAgICAgIGNhbmNlbEFjcXVpcmUobm9kZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBY3F1aXJlcyBpbiBleGNsdXNpdmUgdGltZWQgbW9kZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmcgdGhlIGFjcXVpcmUgYXJndW1lbnQKKyAgICAgKiBAcGFyYW0gbmFub3NUaW1lb3V0IG1heCB3YWl0IHRpbWUKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBhY3F1aXJlZAorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBkb0FjcXVpcmVOYW5vcyhsb25nIGFyZywgbG9uZyBuYW5vc1RpbWVvdXQpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgbGFzdFRpbWUgPSBTeXN0ZW0ubmFub1RpbWUoKTsKKyAgICAgICAgZmluYWwgTm9kZSBub2RlID0gYWRkV2FpdGVyKE5vZGUuRVhDTFVTSVZFKTsKKyAgICAgICAgYm9vbGVhbiBmYWlsZWQgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgcCA9IG5vZGUucHJlZGVjZXNzb3IoKTsKKyAgICAgICAgICAgICAgICBpZiAocCA9PSBoZWFkICYmIHRyeUFjcXVpcmUoYXJnKSkgeworICAgICAgICAgICAgICAgICAgICBzZXRIZWFkKG5vZGUpOworICAgICAgICAgICAgICAgICAgICBwLm5leHQgPSBudWxsOyAvLyBoZWxwIEdDCisgICAgICAgICAgICAgICAgICAgIGZhaWxlZCA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKG5hbm9zVGltZW91dCA8PSAwKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgaWYgKHNob3VsZFBhcmtBZnRlckZhaWxlZEFjcXVpcmUocCwgbm9kZSkgJiYKKyAgICAgICAgICAgICAgICAgICAgbmFub3NUaW1lb3V0ID4gc3BpbkZvclRpbWVvdXRUaHJlc2hvbGQpCisgICAgICAgICAgICAgICAgICAgIExvY2tTdXBwb3J0LnBhcmtOYW5vcyh0aGlzLCBuYW5vc1RpbWVvdXQpOworICAgICAgICAgICAgICAgIGxvbmcgbm93ID0gU3lzdGVtLm5hbm9UaW1lKCk7CisgICAgICAgICAgICAgICAgbmFub3NUaW1lb3V0IC09IG5vdyAtIGxhc3RUaW1lOworICAgICAgICAgICAgICAgIGxhc3RUaW1lID0gbm93OworICAgICAgICAgICAgICAgIGlmIChUaHJlYWQuaW50ZXJydXB0ZWQoKSkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoZmFpbGVkKQorICAgICAgICAgICAgICAgIGNhbmNlbEFjcXVpcmUobm9kZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBY3F1aXJlcyBpbiBzaGFyZWQgdW5pbnRlcnJ1cHRpYmxlIG1vZGUuCisgICAgICogQHBhcmFtIGFyZyB0aGUgYWNxdWlyZSBhcmd1bWVudAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBkb0FjcXVpcmVTaGFyZWQobG9uZyBhcmcpIHsKKyAgICAgICAgZmluYWwgTm9kZSBub2RlID0gYWRkV2FpdGVyKE5vZGUuU0hBUkVEKTsKKyAgICAgICAgYm9vbGVhbiBmYWlsZWQgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYm9vbGVhbiBpbnRlcnJ1cHRlZCA9IGZhbHNlOworICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgcCA9IG5vZGUucHJlZGVjZXNzb3IoKTsKKyAgICAgICAgICAgICAgICBpZiAocCA9PSBoZWFkKSB7CisgICAgICAgICAgICAgICAgICAgIGxvbmcgciA9IHRyeUFjcXVpcmVTaGFyZWQoYXJnKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHIgPj0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgc2V0SGVhZEFuZFByb3BhZ2F0ZShub2RlLCByKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHAubmV4dCA9IG51bGw7IC8vIGhlbHAgR0MKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnRlcnJ1cHRlZCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmSW50ZXJydXB0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoc2hvdWxkUGFya0FmdGVyRmFpbGVkQWNxdWlyZShwLCBub2RlKSAmJgorICAgICAgICAgICAgICAgICAgICBwYXJrQW5kQ2hlY2tJbnRlcnJ1cHQoKSkKKyAgICAgICAgICAgICAgICAgICAgaW50ZXJydXB0ZWQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGZhaWxlZCkKKyAgICAgICAgICAgICAgICBjYW5jZWxBY3F1aXJlKG5vZGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQWNxdWlyZXMgaW4gc2hhcmVkIGludGVycnVwdGlibGUgbW9kZS4KKyAgICAgKiBAcGFyYW0gYXJnIHRoZSBhY3F1aXJlIGFyZ3VtZW50CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGRvQWNxdWlyZVNoYXJlZEludGVycnVwdGlibHkobG9uZyBhcmcpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIE5vZGUgbm9kZSA9IGFkZFdhaXRlcihOb2RlLlNIQVJFRCk7CisgICAgICAgIGJvb2xlYW4gZmFpbGVkID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBOb2RlIHAgPSBub2RlLnByZWRlY2Vzc29yKCk7CisgICAgICAgICAgICAgICAgaWYgKHAgPT0gaGVhZCkgeworICAgICAgICAgICAgICAgICAgICBsb25nIHIgPSB0cnlBY3F1aXJlU2hhcmVkKGFyZyk7CisgICAgICAgICAgICAgICAgICAgIGlmIChyID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNldEhlYWRBbmRQcm9wYWdhdGUobm9kZSwgcik7CisgICAgICAgICAgICAgICAgICAgICAgICBwLm5leHQgPSBudWxsOyAvLyBoZWxwIEdDCisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoc2hvdWxkUGFya0FmdGVyRmFpbGVkQWNxdWlyZShwLCBub2RlKSAmJgorICAgICAgICAgICAgICAgICAgICBwYXJrQW5kQ2hlY2tJbnRlcnJ1cHQoKSkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoZmFpbGVkKQorICAgICAgICAgICAgICAgIGNhbmNlbEFjcXVpcmUobm9kZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBY3F1aXJlcyBpbiBzaGFyZWQgdGltZWQgbW9kZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmcgdGhlIGFjcXVpcmUgYXJndW1lbnQKKyAgICAgKiBAcGFyYW0gbmFub3NUaW1lb3V0IG1heCB3YWl0IHRpbWUKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBhY3F1aXJlZAorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBkb0FjcXVpcmVTaGFyZWROYW5vcyhsb25nIGFyZywgbG9uZyBuYW5vc1RpbWVvdXQpCisgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisKKyAgICAgICAgbG9uZyBsYXN0VGltZSA9IFN5c3RlbS5uYW5vVGltZSgpOworICAgICAgICBmaW5hbCBOb2RlIG5vZGUgPSBhZGRXYWl0ZXIoTm9kZS5TSEFSRUQpOworICAgICAgICBib29sZWFuIGZhaWxlZCA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgZmluYWwgTm9kZSBwID0gbm9kZS5wcmVkZWNlc3NvcigpOworICAgICAgICAgICAgICAgIGlmIChwID09IGhlYWQpIHsKKyAgICAgICAgICAgICAgICAgICAgbG9uZyByID0gdHJ5QWNxdWlyZVNoYXJlZChhcmcpOworICAgICAgICAgICAgICAgICAgICBpZiAociA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzZXRIZWFkQW5kUHJvcGFnYXRlKG5vZGUsIHIpOworICAgICAgICAgICAgICAgICAgICAgICAgcC5uZXh0ID0gbnVsbDsgLy8gaGVscCBHQworICAgICAgICAgICAgICAgICAgICAgICAgZmFpbGVkID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAobmFub3NUaW1lb3V0IDw9IDApCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICBpZiAoc2hvdWxkUGFya0FmdGVyRmFpbGVkQWNxdWlyZShwLCBub2RlKSAmJgorICAgICAgICAgICAgICAgICAgICBuYW5vc1RpbWVvdXQgPiBzcGluRm9yVGltZW91dFRocmVzaG9sZCkKKyAgICAgICAgICAgICAgICAgICAgTG9ja1N1cHBvcnQucGFya05hbm9zKHRoaXMsIG5hbm9zVGltZW91dCk7CisgICAgICAgICAgICAgICAgbG9uZyBub3cgPSBTeXN0ZW0ubmFub1RpbWUoKTsKKyAgICAgICAgICAgICAgICBuYW5vc1RpbWVvdXQgLT0gbm93IC0gbGFzdFRpbWU7CisgICAgICAgICAgICAgICAgbGFzdFRpbWUgPSBub3c7CisgICAgICAgICAgICAgICAgaWYgKFRocmVhZC5pbnRlcnJ1cHRlZCgpKQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJydXB0ZWRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChmYWlsZWQpCisgICAgICAgICAgICAgICAgY2FuY2VsQWNxdWlyZShub2RlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIE1haW4gZXhwb3J0ZWQgbWV0aG9kcworCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gYWNxdWlyZSBpbiBleGNsdXNpdmUgbW9kZS4gVGhpcyBtZXRob2Qgc2hvdWxkIHF1ZXJ5CisgICAgICogaWYgdGhlIHN0YXRlIG9mIHRoZSBvYmplY3QgcGVybWl0cyBpdCB0byBiZSBhY3F1aXJlZCBpbiB0aGUKKyAgICAgKiBleGNsdXNpdmUgbW9kZSwgYW5kIGlmIHNvIHRvIGFjcXVpcmUgaXQuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBhbHdheXMgaW52b2tlZCBieSB0aGUgdGhyZWFkIHBlcmZvcm1pbmcKKyAgICAgKiBhY3F1aXJlLiAgSWYgdGhpcyBtZXRob2QgcmVwb3J0cyBmYWlsdXJlLCB0aGUgYWNxdWlyZSBtZXRob2QKKyAgICAgKiBtYXkgcXVldWUgdGhlIHRocmVhZCwgaWYgaXQgaXMgbm90IGFscmVhZHkgcXVldWVkLCB1bnRpbCBpdCBpcworICAgICAqIHNpZ25hbGxlZCBieSBhIHJlbGVhc2UgZnJvbSBzb21lIG90aGVyIHRocmVhZC4gVGhpcyBjYW4gYmUgdXNlZAorICAgICAqIHRvIGltcGxlbWVudCBtZXRob2Qge0BsaW5rIExvY2sjdHJ5TG9jaygpfS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBkZWZhdWx0CisgICAgICogaW1wbGVtZW50YXRpb24gdGhyb3dzIHtAbGluayBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJnIHRoZSBhY3F1aXJlIGFyZ3VtZW50LiBUaGlzIHZhbHVlIGlzIGFsd2F5cyB0aGUgb25lCisgICAgICogICAgICAgIHBhc3NlZCB0byBhbiBhY3F1aXJlIG1ldGhvZCwgb3IgaXMgdGhlIHZhbHVlIHNhdmVkIG9uIGVudHJ5CisgICAgICogICAgICAgIHRvIGEgY29uZGl0aW9uIHdhaXQuICBUaGUgdmFsdWUgaXMgb3RoZXJ3aXNlIHVuaW50ZXJwcmV0ZWQKKyAgICAgKiAgICAgICAgYW5kIGNhbiByZXByZXNlbnQgYW55dGhpbmcgeW91IGxpa2UuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgc3VjY2Vzc2Z1bC4gVXBvbiBzdWNjZXNzLCB0aGlzIG9iamVjdCBoYXMKKyAgICAgKiAgICAgICAgIGJlZW4gYWNxdWlyZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIGFjcXVpcmluZyB3b3VsZCBwbGFjZSB0aGlzCisgICAgICogICAgICAgICBzeW5jaHJvbml6ZXIgaW4gYW4gaWxsZWdhbCBzdGF0ZS4gVGhpcyBleGNlcHRpb24gbXVzdCBiZQorICAgICAqICAgICAgICAgdGhyb3duIGluIGEgY29uc2lzdGVudCBmYXNoaW9uIGZvciBzeW5jaHJvbml6YXRpb24gdG8gd29yaworICAgICAqICAgICAgICAgY29ycmVjdGx5LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgZXhjbHVzaXZlIG1vZGUgaXMgbm90IHN1cHBvcnRlZAorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIHRyeUFjcXVpcmUobG9uZyBhcmcpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gc2V0IHRoZSBzdGF0ZSB0byByZWZsZWN0IGEgcmVsZWFzZSBpbiBleGNsdXNpdmUKKyAgICAgKiBtb2RlLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgYWx3YXlzIGludm9rZWQgYnkgdGhlIHRocmVhZCBwZXJmb3JtaW5nIHJlbGVhc2UuCisgICAgICoKKyAgICAgKiA8cD5UaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB0aHJvd3MKKyAgICAgKiB7QGxpbmsgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259LgorICAgICAqCisgICAgICogQHBhcmFtIGFyZyB0aGUgcmVsZWFzZSBhcmd1bWVudC4gVGhpcyB2YWx1ZSBpcyBhbHdheXMgdGhlIG9uZQorICAgICAqICAgICAgICBwYXNzZWQgdG8gYSByZWxlYXNlIG1ldGhvZCwgb3IgdGhlIGN1cnJlbnQgc3RhdGUgdmFsdWUgdXBvbgorICAgICAqICAgICAgICBlbnRyeSB0byBhIGNvbmRpdGlvbiB3YWl0LiAgVGhlIHZhbHVlIGlzIG90aGVyd2lzZQorICAgICAqICAgICAgICB1bmludGVycHJldGVkIGFuZCBjYW4gcmVwcmVzZW50IGFueXRoaW5nIHlvdSBsaWtlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgb2JqZWN0IGlzIG5vdyBpbiBhIGZ1bGx5IHJlbGVhc2VkCisgICAgICogICAgICAgICBzdGF0ZSwgc28gdGhhdCBhbnkgd2FpdGluZyB0aHJlYWRzIG1heSBhdHRlbXB0IHRvIGFjcXVpcmU7CisgICAgICogICAgICAgICBhbmQge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIHJlbGVhc2luZyB3b3VsZCBwbGFjZSB0aGlzCisgICAgICogICAgICAgICBzeW5jaHJvbml6ZXIgaW4gYW4gaWxsZWdhbCBzdGF0ZS4gVGhpcyBleGNlcHRpb24gbXVzdCBiZQorICAgICAqICAgICAgICAgdGhyb3duIGluIGEgY29uc2lzdGVudCBmYXNoaW9uIGZvciBzeW5jaHJvbml6YXRpb24gdG8gd29yaworICAgICAqICAgICAgICAgY29ycmVjdGx5LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgZXhjbHVzaXZlIG1vZGUgaXMgbm90IHN1cHBvcnRlZAorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIHRyeVJlbGVhc2UobG9uZyBhcmcpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gYWNxdWlyZSBpbiBzaGFyZWQgbW9kZS4gVGhpcyBtZXRob2Qgc2hvdWxkIHF1ZXJ5IGlmCisgICAgICogdGhlIHN0YXRlIG9mIHRoZSBvYmplY3QgcGVybWl0cyBpdCB0byBiZSBhY3F1aXJlZCBpbiB0aGUgc2hhcmVkCisgICAgICogbW9kZSwgYW5kIGlmIHNvIHRvIGFjcXVpcmUgaXQuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBhbHdheXMgaW52b2tlZCBieSB0aGUgdGhyZWFkIHBlcmZvcm1pbmcKKyAgICAgKiBhY3F1aXJlLiAgSWYgdGhpcyBtZXRob2QgcmVwb3J0cyBmYWlsdXJlLCB0aGUgYWNxdWlyZSBtZXRob2QKKyAgICAgKiBtYXkgcXVldWUgdGhlIHRocmVhZCwgaWYgaXQgaXMgbm90IGFscmVhZHkgcXVldWVkLCB1bnRpbCBpdCBpcworICAgICAqIHNpZ25hbGxlZCBieSBhIHJlbGVhc2UgZnJvbSBzb21lIG90aGVyIHRocmVhZC4KKyAgICAgKgorICAgICAqIDxwPlRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHRocm93cyB7QGxpbmsKKyAgICAgKiBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJnIHRoZSBhY3F1aXJlIGFyZ3VtZW50LiBUaGlzIHZhbHVlIGlzIGFsd2F5cyB0aGUgb25lCisgICAgICogICAgICAgIHBhc3NlZCB0byBhbiBhY3F1aXJlIG1ldGhvZCwgb3IgaXMgdGhlIHZhbHVlIHNhdmVkIG9uIGVudHJ5CisgICAgICogICAgICAgIHRvIGEgY29uZGl0aW9uIHdhaXQuICBUaGUgdmFsdWUgaXMgb3RoZXJ3aXNlIHVuaW50ZXJwcmV0ZWQKKyAgICAgKiAgICAgICAgYW5kIGNhbiByZXByZXNlbnQgYW55dGhpbmcgeW91IGxpa2UuCisgICAgICogQHJldHVybiBhIG5lZ2F0aXZlIHZhbHVlIG9uIGZhaWx1cmU7IHplcm8gaWYgYWNxdWlzaXRpb24gaW4gc2hhcmVkCisgICAgICogICAgICAgICBtb2RlIHN1Y2NlZWRlZCBidXQgbm8gc3Vic2VxdWVudCBzaGFyZWQtbW9kZSBhY3F1aXJlIGNhbgorICAgICAqICAgICAgICAgc3VjY2VlZDsgYW5kIGEgcG9zaXRpdmUgdmFsdWUgaWYgYWNxdWlzaXRpb24gaW4gc2hhcmVkCisgICAgICogICAgICAgICBtb2RlIHN1Y2NlZWRlZCBhbmQgc3Vic2VxdWVudCBzaGFyZWQtbW9kZSBhY3F1aXJlcyBtaWdodAorICAgICAqICAgICAgICAgYWxzbyBzdWNjZWVkLCBpbiB3aGljaCBjYXNlIGEgc3Vic2VxdWVudCB3YWl0aW5nIHRocmVhZAorICAgICAqICAgICAgICAgbXVzdCBjaGVjayBhdmFpbGFiaWxpdHkuIChTdXBwb3J0IGZvciB0aHJlZSBkaWZmZXJlbnQKKyAgICAgKiAgICAgICAgIHJldHVybiB2YWx1ZXMgZW5hYmxlcyB0aGlzIG1ldGhvZCB0byBiZSB1c2VkIGluIGNvbnRleHRzCisgICAgICogICAgICAgICB3aGVyZSBhY3F1aXJlcyBvbmx5IHNvbWV0aW1lcyBhY3QgZXhjbHVzaXZlbHkuKSAgVXBvbgorICAgICAqICAgICAgICAgc3VjY2VzcywgdGhpcyBvYmplY3QgaGFzIGJlZW4gYWNxdWlyZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIGFjcXVpcmluZyB3b3VsZCBwbGFjZSB0aGlzCisgICAgICogICAgICAgICBzeW5jaHJvbml6ZXIgaW4gYW4gaWxsZWdhbCBzdGF0ZS4gVGhpcyBleGNlcHRpb24gbXVzdCBiZQorICAgICAqICAgICAgICAgdGhyb3duIGluIGEgY29uc2lzdGVudCBmYXNoaW9uIGZvciBzeW5jaHJvbml6YXRpb24gdG8gd29yaworICAgICAqICAgICAgICAgY29ycmVjdGx5LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgc2hhcmVkIG1vZGUgaXMgbm90IHN1cHBvcnRlZAorICAgICAqLworICAgIHByb3RlY3RlZCBsb25nIHRyeUFjcXVpcmVTaGFyZWQobG9uZyBhcmcpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gc2V0IHRoZSBzdGF0ZSB0byByZWZsZWN0IGEgcmVsZWFzZSBpbiBzaGFyZWQgbW9kZS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGFsd2F5cyBpbnZva2VkIGJ5IHRoZSB0aHJlYWQgcGVyZm9ybWluZyByZWxlYXNlLgorICAgICAqCisgICAgICogPHA+VGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gdGhyb3dzCisgICAgICoge0BsaW5rIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmcgdGhlIHJlbGVhc2UgYXJndW1lbnQuIFRoaXMgdmFsdWUgaXMgYWx3YXlzIHRoZSBvbmUKKyAgICAgKiAgICAgICAgcGFzc2VkIHRvIGEgcmVsZWFzZSBtZXRob2QsIG9yIHRoZSBjdXJyZW50IHN0YXRlIHZhbHVlIHVwb24KKyAgICAgKiAgICAgICAgZW50cnkgdG8gYSBjb25kaXRpb24gd2FpdC4gIFRoZSB2YWx1ZSBpcyBvdGhlcndpc2UKKyAgICAgKiAgICAgICAgdW5pbnRlcnByZXRlZCBhbmQgY2FuIHJlcHJlc2VudCBhbnl0aGluZyB5b3UgbGlrZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHJlbGVhc2Ugb2Ygc2hhcmVkIG1vZGUgbWF5IHBlcm1pdCBhCisgICAgICogICAgICAgICB3YWl0aW5nIGFjcXVpcmUgKHNoYXJlZCBvciBleGNsdXNpdmUpIHRvIHN1Y2NlZWQ7IGFuZAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gaWYgcmVsZWFzaW5nIHdvdWxkIHBsYWNlIHRoaXMKKyAgICAgKiAgICAgICAgIHN5bmNocm9uaXplciBpbiBhbiBpbGxlZ2FsIHN0YXRlLiBUaGlzIGV4Y2VwdGlvbiBtdXN0IGJlCisgICAgICogICAgICAgICB0aHJvd24gaW4gYSBjb25zaXN0ZW50IGZhc2hpb24gZm9yIHN5bmNocm9uaXphdGlvbiB0byB3b3JrCisgICAgICogICAgICAgICBjb3JyZWN0bHkuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiBzaGFyZWQgbW9kZSBpcyBub3Qgc3VwcG9ydGVkCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gdHJ5UmVsZWFzZVNoYXJlZChsb25nIGFyZykgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiBzeW5jaHJvbml6YXRpb24gaXMgaGVsZCBleGNsdXNpdmVseSB3aXRoCisgICAgICogcmVzcGVjdCB0byB0aGUgY3VycmVudCAoY2FsbGluZykgdGhyZWFkLiAgVGhpcyBtZXRob2QgaXMgaW52b2tlZAorICAgICAqIHVwb24gZWFjaCBjYWxsIHRvIGEgbm9uLXdhaXRpbmcge0BsaW5rIENvbmRpdGlvbk9iamVjdH0gbWV0aG9kLgorICAgICAqIChXYWl0aW5nIG1ldGhvZHMgaW5zdGVhZCBpbnZva2Uge0BsaW5rICNyZWxlYXNlfS4pCisgICAgICoKKyAgICAgKiA8cD5UaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB0aHJvd3Mge0BsaW5rCisgICAgICogVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259LiBUaGlzIG1ldGhvZCBpcyBpbnZva2VkCisgICAgICogaW50ZXJuYWxseSBvbmx5IHdpdGhpbiB7QGxpbmsgQ29uZGl0aW9uT2JqZWN0fSBtZXRob2RzLCBzbyBuZWVkCisgICAgICogbm90IGJlIGRlZmluZWQgaWYgY29uZGl0aW9ucyBhcmUgbm90IHVzZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBzeW5jaHJvbml6YXRpb24gaXMgaGVsZCBleGNsdXNpdmVseTsKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiBjb25kaXRpb25zIGFyZSBub3Qgc3VwcG9ydGVkCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNIZWxkRXhjbHVzaXZlbHkoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFjcXVpcmVzIGluIGV4Y2x1c2l2ZSBtb2RlLCBpZ25vcmluZyBpbnRlcnJ1cHRzLiAgSW1wbGVtZW50ZWQKKyAgICAgKiBieSBpbnZva2luZyBhdCBsZWFzdCBvbmNlIHtAbGluayAjdHJ5QWNxdWlyZX0sCisgICAgICogcmV0dXJuaW5nIG9uIHN1Y2Nlc3MuICBPdGhlcndpc2UgdGhlIHRocmVhZCBpcyBxdWV1ZWQsIHBvc3NpYmx5CisgICAgICogcmVwZWF0ZWRseSBibG9ja2luZyBhbmQgdW5ibG9ja2luZywgaW52b2tpbmcge0BsaW5rCisgICAgICogI3RyeUFjcXVpcmV9IHVudGlsIHN1Y2Nlc3MuICBUaGlzIG1ldGhvZCBjYW4gYmUgdXNlZAorICAgICAqIHRvIGltcGxlbWVudCBtZXRob2Qge0BsaW5rIExvY2sjbG9ja30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJnIHRoZSBhY3F1aXJlIGFyZ3VtZW50LiAgVGhpcyB2YWx1ZSBpcyBjb252ZXllZCB0bworICAgICAqICAgICAgICB7QGxpbmsgI3RyeUFjcXVpcmV9IGJ1dCBpcyBvdGhlcndpc2UgdW5pbnRlcnByZXRlZCBhbmQKKyAgICAgKiAgICAgICAgY2FuIHJlcHJlc2VudCBhbnl0aGluZyB5b3UgbGlrZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBhY3F1aXJlKGxvbmcgYXJnKSB7CisgICAgICAgIGlmICghdHJ5QWNxdWlyZShhcmcpICYmCisgICAgICAgICAgICBhY3F1aXJlUXVldWVkKGFkZFdhaXRlcihOb2RlLkVYQ0xVU0lWRSksIGFyZykpCisgICAgICAgICAgICBzZWxmSW50ZXJydXB0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWNxdWlyZXMgaW4gZXhjbHVzaXZlIG1vZGUsIGFib3J0aW5nIGlmIGludGVycnVwdGVkLgorICAgICAqIEltcGxlbWVudGVkIGJ5IGZpcnN0IGNoZWNraW5nIGludGVycnVwdCBzdGF0dXMsIHRoZW4gaW52b2tpbmcKKyAgICAgKiBhdCBsZWFzdCBvbmNlIHtAbGluayAjdHJ5QWNxdWlyZX0sIHJldHVybmluZyBvbgorICAgICAqIHN1Y2Nlc3MuICBPdGhlcndpc2UgdGhlIHRocmVhZCBpcyBxdWV1ZWQsIHBvc3NpYmx5IHJlcGVhdGVkbHkKKyAgICAgKiBibG9ja2luZyBhbmQgdW5ibG9ja2luZywgaW52b2tpbmcge0BsaW5rICN0cnlBY3F1aXJlfQorICAgICAqIHVudGlsIHN1Y2Nlc3Mgb3IgdGhlIHRocmVhZCBpcyBpbnRlcnJ1cHRlZC4gIFRoaXMgbWV0aG9kIGNhbiBiZQorICAgICAqIHVzZWQgdG8gaW1wbGVtZW50IG1ldGhvZCB7QGxpbmsgTG9jayNsb2NrSW50ZXJydXB0aWJseX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJnIHRoZSBhY3F1aXJlIGFyZ3VtZW50LiAgVGhpcyB2YWx1ZSBpcyBjb252ZXllZCB0bworICAgICAqICAgICAgICB7QGxpbmsgI3RyeUFjcXVpcmV9IGJ1dCBpcyBvdGhlcndpc2UgdW5pbnRlcnByZXRlZCBhbmQKKyAgICAgKiAgICAgICAgY2FuIHJlcHJlc2VudCBhbnl0aGluZyB5b3UgbGlrZS4KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IHRocmVhZCBpcyBpbnRlcnJ1cHRlZAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGFjcXVpcmVJbnRlcnJ1cHRpYmx5KGxvbmcgYXJnKQorICAgICAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKFRocmVhZC5pbnRlcnJ1cHRlZCgpKQorICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkRXhjZXB0aW9uKCk7CisgICAgICAgIGlmICghdHJ5QWNxdWlyZShhcmcpKQorICAgICAgICAgICAgZG9BY3F1aXJlSW50ZXJydXB0aWJseShhcmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0dGVtcHRzIHRvIGFjcXVpcmUgaW4gZXhjbHVzaXZlIG1vZGUsIGFib3J0aW5nIGlmIGludGVycnVwdGVkLAorICAgICAqIGFuZCBmYWlsaW5nIGlmIHRoZSBnaXZlbiB0aW1lb3V0IGVsYXBzZXMuICBJbXBsZW1lbnRlZCBieSBmaXJzdAorICAgICAqIGNoZWNraW5nIGludGVycnVwdCBzdGF0dXMsIHRoZW4gaW52b2tpbmcgYXQgbGVhc3Qgb25jZSB7QGxpbmsKKyAgICAgKiAjdHJ5QWNxdWlyZX0sIHJldHVybmluZyBvbiBzdWNjZXNzLiAgT3RoZXJ3aXNlLCB0aGUgdGhyZWFkIGlzCisgICAgICogcXVldWVkLCBwb3NzaWJseSByZXBlYXRlZGx5IGJsb2NraW5nIGFuZCB1bmJsb2NraW5nLCBpbnZva2luZworICAgICAqIHtAbGluayAjdHJ5QWNxdWlyZX0gdW50aWwgc3VjY2VzcyBvciB0aGUgdGhyZWFkIGlzIGludGVycnVwdGVkCisgICAgICogb3IgdGhlIHRpbWVvdXQgZWxhcHNlcy4gIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIGltcGxlbWVudAorICAgICAqIG1ldGhvZCB7QGxpbmsgTG9jayN0cnlMb2NrKGxvbmcsIFRpbWVVbml0KX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJnIHRoZSBhY3F1aXJlIGFyZ3VtZW50LiAgVGhpcyB2YWx1ZSBpcyBjb252ZXllZCB0bworICAgICAqICAgICAgICB7QGxpbmsgI3RyeUFjcXVpcmV9IGJ1dCBpcyBvdGhlcndpc2UgdW5pbnRlcnByZXRlZCBhbmQKKyAgICAgKiAgICAgICAgY2FuIHJlcHJlc2VudCBhbnl0aGluZyB5b3UgbGlrZS4KKyAgICAgKiBAcGFyYW0gbmFub3NUaW1lb3V0IHRoZSBtYXhpbXVtIG51bWJlciBvZiBuYW5vc2Vjb25kcyB0byB3YWl0CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYWNxdWlyZWQ7IHtAY29kZSBmYWxzZX0gaWYgdGltZWQgb3V0CisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCB0aHJlYWQgaXMgaW50ZXJydXB0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiB0cnlBY3F1aXJlTmFub3MobG9uZyBhcmcsIGxvbmcgbmFub3NUaW1lb3V0KQorICAgICAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKFRocmVhZC5pbnRlcnJ1cHRlZCgpKQorICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkRXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiB0cnlBY3F1aXJlKGFyZykgfHwKKyAgICAgICAgICAgIGRvQWNxdWlyZU5hbm9zKGFyZywgbmFub3NUaW1lb3V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWxlYXNlcyBpbiBleGNsdXNpdmUgbW9kZS4gIEltcGxlbWVudGVkIGJ5IHVuYmxvY2tpbmcgb25lIG9yCisgICAgICogbW9yZSB0aHJlYWRzIGlmIHtAbGluayAjdHJ5UmVsZWFzZX0gcmV0dXJucyB0cnVlLgorICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIGltcGxlbWVudCBtZXRob2Qge0BsaW5rIExvY2sjdW5sb2NrfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmcgdGhlIHJlbGVhc2UgYXJndW1lbnQuICBUaGlzIHZhbHVlIGlzIGNvbnZleWVkIHRvCisgICAgICogICAgICAgIHtAbGluayAjdHJ5UmVsZWFzZX0gYnV0IGlzIG90aGVyd2lzZSB1bmludGVycHJldGVkIGFuZAorICAgICAqICAgICAgICBjYW4gcmVwcmVzZW50IGFueXRoaW5nIHlvdSBsaWtlLgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIHJldHVybmVkIGZyb20ge0BsaW5rICN0cnlSZWxlYXNlfQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIHJlbGVhc2UobG9uZyBhcmcpIHsKKyAgICAgICAgaWYgKHRyeVJlbGVhc2UoYXJnKSkgeworICAgICAgICAgICAgTm9kZSBoID0gaGVhZDsKKyAgICAgICAgICAgIGlmIChoICE9IG51bGwgJiYgaC53YWl0U3RhdHVzICE9IDApCisgICAgICAgICAgICAgICAgdW5wYXJrU3VjY2Vzc29yKGgpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFjcXVpcmVzIGluIHNoYXJlZCBtb2RlLCBpZ25vcmluZyBpbnRlcnJ1cHRzLiAgSW1wbGVtZW50ZWQgYnkKKyAgICAgKiBmaXJzdCBpbnZva2luZyBhdCBsZWFzdCBvbmNlIHtAbGluayAjdHJ5QWNxdWlyZVNoYXJlZH0sCisgICAgICogcmV0dXJuaW5nIG9uIHN1Y2Nlc3MuICBPdGhlcndpc2UgdGhlIHRocmVhZCBpcyBxdWV1ZWQsIHBvc3NpYmx5CisgICAgICogcmVwZWF0ZWRseSBibG9ja2luZyBhbmQgdW5ibG9ja2luZywgaW52b2tpbmcge0BsaW5rCisgICAgICogI3RyeUFjcXVpcmVTaGFyZWR9IHVudGlsIHN1Y2Nlc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJnIHRoZSBhY3F1aXJlIGFyZ3VtZW50LiAgVGhpcyB2YWx1ZSBpcyBjb252ZXllZCB0bworICAgICAqICAgICAgICB7QGxpbmsgI3RyeUFjcXVpcmVTaGFyZWR9IGJ1dCBpcyBvdGhlcndpc2UgdW5pbnRlcnByZXRlZAorICAgICAqICAgICAgICBhbmQgY2FuIHJlcHJlc2VudCBhbnl0aGluZyB5b3UgbGlrZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBhY3F1aXJlU2hhcmVkKGxvbmcgYXJnKSB7CisgICAgICAgIGlmICh0cnlBY3F1aXJlU2hhcmVkKGFyZykgPCAwKQorICAgICAgICAgICAgZG9BY3F1aXJlU2hhcmVkKGFyZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWNxdWlyZXMgaW4gc2hhcmVkIG1vZGUsIGFib3J0aW5nIGlmIGludGVycnVwdGVkLiAgSW1wbGVtZW50ZWQKKyAgICAgKiBieSBmaXJzdCBjaGVja2luZyBpbnRlcnJ1cHQgc3RhdHVzLCB0aGVuIGludm9raW5nIGF0IGxlYXN0IG9uY2UKKyAgICAgKiB7QGxpbmsgI3RyeUFjcXVpcmVTaGFyZWR9LCByZXR1cm5pbmcgb24gc3VjY2Vzcy4gIE90aGVyd2lzZSB0aGUKKyAgICAgKiB0aHJlYWQgaXMgcXVldWVkLCBwb3NzaWJseSByZXBlYXRlZGx5IGJsb2NraW5nIGFuZCB1bmJsb2NraW5nLAorICAgICAqIGludm9raW5nIHtAbGluayAjdHJ5QWNxdWlyZVNoYXJlZH0gdW50aWwgc3VjY2VzcyBvciB0aGUgdGhyZWFkCisgICAgICogaXMgaW50ZXJydXB0ZWQuCisgICAgICogQHBhcmFtIGFyZyB0aGUgYWNxdWlyZSBhcmd1bWVudAorICAgICAqIFRoaXMgdmFsdWUgaXMgY29udmV5ZWQgdG8ge0BsaW5rICN0cnlBY3F1aXJlU2hhcmVkfSBidXQgaXMKKyAgICAgKiBvdGhlcndpc2UgdW5pbnRlcnByZXRlZCBhbmQgY2FuIHJlcHJlc2VudCBhbnl0aGluZworICAgICAqIHlvdSBsaWtlLgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgYWNxdWlyZVNoYXJlZEludGVycnVwdGlibHkobG9uZyBhcmcpCisgICAgICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBpZiAoVGhyZWFkLmludGVycnVwdGVkKCkpCisgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJydXB0ZWRFeGNlcHRpb24oKTsKKyAgICAgICAgaWYgKHRyeUFjcXVpcmVTaGFyZWQoYXJnKSA8IDApCisgICAgICAgICAgICBkb0FjcXVpcmVTaGFyZWRJbnRlcnJ1cHRpYmx5KGFyZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gYWNxdWlyZSBpbiBzaGFyZWQgbW9kZSwgYWJvcnRpbmcgaWYgaW50ZXJydXB0ZWQsIGFuZAorICAgICAqIGZhaWxpbmcgaWYgdGhlIGdpdmVuIHRpbWVvdXQgZWxhcHNlcy4gIEltcGxlbWVudGVkIGJ5IGZpcnN0CisgICAgICogY2hlY2tpbmcgaW50ZXJydXB0IHN0YXR1cywgdGhlbiBpbnZva2luZyBhdCBsZWFzdCBvbmNlIHtAbGluaworICAgICAqICN0cnlBY3F1aXJlU2hhcmVkfSwgcmV0dXJuaW5nIG9uIHN1Y2Nlc3MuICBPdGhlcndpc2UsIHRoZQorICAgICAqIHRocmVhZCBpcyBxdWV1ZWQsIHBvc3NpYmx5IHJlcGVhdGVkbHkgYmxvY2tpbmcgYW5kIHVuYmxvY2tpbmcsCisgICAgICogaW52b2tpbmcge0BsaW5rICN0cnlBY3F1aXJlU2hhcmVkfSB1bnRpbCBzdWNjZXNzIG9yIHRoZSB0aHJlYWQKKyAgICAgKiBpcyBpbnRlcnJ1cHRlZCBvciB0aGUgdGltZW91dCBlbGFwc2VzLgorICAgICAqCisgICAgICogQHBhcmFtIGFyZyB0aGUgYWNxdWlyZSBhcmd1bWVudC4gIFRoaXMgdmFsdWUgaXMgY29udmV5ZWQgdG8KKyAgICAgKiAgICAgICAge0BsaW5rICN0cnlBY3F1aXJlU2hhcmVkfSBidXQgaXMgb3RoZXJ3aXNlIHVuaW50ZXJwcmV0ZWQKKyAgICAgKiAgICAgICAgYW5kIGNhbiByZXByZXNlbnQgYW55dGhpbmcgeW91IGxpa2UuCisgICAgICogQHBhcmFtIG5hbm9zVGltZW91dCB0aGUgbWF4aW11bSBudW1iZXIgb2YgbmFub3NlY29uZHMgdG8gd2FpdAorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGFjcXVpcmVkOyB7QGNvZGUgZmFsc2V9IGlmIHRpbWVkIG91dAorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gdHJ5QWNxdWlyZVNoYXJlZE5hbm9zKGxvbmcgYXJnLCBsb25nIG5hbm9zVGltZW91dCkKKyAgICAgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChUaHJlYWQuaW50ZXJydXB0ZWQoKSkKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbigpOworICAgICAgICByZXR1cm4gdHJ5QWNxdWlyZVNoYXJlZChhcmcpID49IDAgfHwKKyAgICAgICAgICAgIGRvQWNxdWlyZVNoYXJlZE5hbm9zKGFyZywgbmFub3NUaW1lb3V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWxlYXNlcyBpbiBzaGFyZWQgbW9kZS4gIEltcGxlbWVudGVkIGJ5IHVuYmxvY2tpbmcgb25lIG9yIG1vcmUKKyAgICAgKiB0aHJlYWRzIGlmIHtAbGluayAjdHJ5UmVsZWFzZVNoYXJlZH0gcmV0dXJucyB0cnVlLgorICAgICAqCisgICAgICogQHBhcmFtIGFyZyB0aGUgcmVsZWFzZSBhcmd1bWVudC4gIFRoaXMgdmFsdWUgaXMgY29udmV5ZWQgdG8KKyAgICAgKiAgICAgICAge0BsaW5rICN0cnlSZWxlYXNlU2hhcmVkfSBidXQgaXMgb3RoZXJ3aXNlIHVuaW50ZXJwcmV0ZWQKKyAgICAgKiAgICAgICAgYW5kIGNhbiByZXByZXNlbnQgYW55dGhpbmcgeW91IGxpa2UuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgcmV0dXJuZWQgZnJvbSB7QGxpbmsgI3RyeVJlbGVhc2VTaGFyZWR9CisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gcmVsZWFzZVNoYXJlZChsb25nIGFyZykgeworICAgICAgICBpZiAodHJ5UmVsZWFzZVNoYXJlZChhcmcpKSB7CisgICAgICAgICAgICBkb1JlbGVhc2VTaGFyZWQoKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvLyBRdWV1ZSBpbnNwZWN0aW9uIG1ldGhvZHMKKworICAgIC8qKgorICAgICAqIFF1ZXJpZXMgd2hldGhlciBhbnkgdGhyZWFkcyBhcmUgd2FpdGluZyB0byBhY3F1aXJlLiBOb3RlIHRoYXQKKyAgICAgKiBiZWNhdXNlIGNhbmNlbGxhdGlvbnMgZHVlIHRvIGludGVycnVwdHMgYW5kIHRpbWVvdXRzIG1heSBvY2N1cgorICAgICAqIGF0IGFueSB0aW1lLCBhIHtAY29kZSB0cnVlfSByZXR1cm4gZG9lcyBub3QgZ3VhcmFudGVlIHRoYXQgYW55CisgICAgICogb3RoZXIgdGhyZWFkIHdpbGwgZXZlciBhY3F1aXJlLgorICAgICAqCisgICAgICogPHA+SW4gdGhpcyBpbXBsZW1lbnRhdGlvbiwgdGhpcyBvcGVyYXRpb24gcmV0dXJucyBpbgorICAgICAqIGNvbnN0YW50IHRpbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGVyZSBtYXkgYmUgb3RoZXIgdGhyZWFkcyB3YWl0aW5nIHRvIGFjcXVpcmUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNRdWV1ZWRUaHJlYWRzKCkgeworICAgICAgICByZXR1cm4gaGVhZCAhPSB0YWlsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFF1ZXJpZXMgd2hldGhlciBhbnkgdGhyZWFkcyBoYXZlIGV2ZXIgY29udGVuZGVkIHRvIGFjcXVpcmUgdGhpcworICAgICAqIHN5bmNocm9uaXplcjsgdGhhdCBpcyBpZiBhbiBhY3F1aXJlIG1ldGhvZCBoYXMgZXZlciBibG9ja2VkLgorICAgICAqCisgICAgICogPHA+SW4gdGhpcyBpbXBsZW1lbnRhdGlvbiwgdGhpcyBvcGVyYXRpb24gcmV0dXJucyBpbgorICAgICAqIGNvbnN0YW50IHRpbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGVyZSBoYXMgZXZlciBiZWVuIGNvbnRlbnRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNDb250ZW5kZWQoKSB7CisgICAgICAgIHJldHVybiBoZWFkICE9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZmlyc3QgKGxvbmdlc3Qtd2FpdGluZykgdGhyZWFkIGluIHRoZSBxdWV1ZSwgb3IKKyAgICAgKiB7QGNvZGUgbnVsbH0gaWYgbm8gdGhyZWFkcyBhcmUgY3VycmVudGx5IHF1ZXVlZC4KKyAgICAgKgorICAgICAqIDxwPkluIHRoaXMgaW1wbGVtZW50YXRpb24sIHRoaXMgb3BlcmF0aW9uIG5vcm1hbGx5IHJldHVybnMgaW4KKyAgICAgKiBjb25zdGFudCB0aW1lLCBidXQgbWF5IGl0ZXJhdGUgdXBvbiBjb250ZW50aW9uIGlmIG90aGVyIHRocmVhZHMgYXJlCisgICAgICogY29uY3VycmVudGx5IG1vZGlmeWluZyB0aGUgcXVldWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBmaXJzdCAobG9uZ2VzdC13YWl0aW5nKSB0aHJlYWQgaW4gdGhlIHF1ZXVlLCBvcgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlmIG5vIHRocmVhZHMgYXJlIGN1cnJlbnRseSBxdWV1ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgVGhyZWFkIGdldEZpcnN0UXVldWVkVGhyZWFkKCkgeworICAgICAgICAvLyBoYW5kbGUgb25seSBmYXN0IHBhdGgsIGVsc2UgcmVsYXkKKyAgICAgICAgcmV0dXJuIChoZWFkID09IHRhaWwpID8gbnVsbCA6IGZ1bGxHZXRGaXJzdFF1ZXVlZFRocmVhZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFZlcnNpb24gb2YgZ2V0Rmlyc3RRdWV1ZWRUaHJlYWQgY2FsbGVkIHdoZW4gZmFzdHBhdGggZmFpbHMKKyAgICAgKi8KKyAgICBwcml2YXRlIFRocmVhZCBmdWxsR2V0Rmlyc3RRdWV1ZWRUaHJlYWQoKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFRoZSBmaXJzdCBub2RlIGlzIG5vcm1hbGx5IGhlYWQubmV4dC4gVHJ5IHRvIGdldCBpdHMKKyAgICAgICAgICogdGhyZWFkIGZpZWxkLCBlbnN1cmluZyBjb25zaXN0ZW50IHJlYWRzOiBJZiB0aHJlYWQKKyAgICAgICAgICogZmllbGQgaXMgbnVsbGVkIG91dCBvciBzLnByZXYgaXMgbm8gbG9uZ2VyIGhlYWQsIHRoZW4KKyAgICAgICAgICogc29tZSBvdGhlciB0aHJlYWQocykgY29uY3VycmVudGx5IHBlcmZvcm1lZCBzZXRIZWFkIGluCisgICAgICAgICAqIGJldHdlZW4gc29tZSBvZiBvdXIgcmVhZHMuIFdlIHRyeSB0aGlzIHR3aWNlIGJlZm9yZQorICAgICAgICAgKiByZXNvcnRpbmcgdG8gdHJhdmVyc2FsLgorICAgICAgICAgKi8KKyAgICAgICAgTm9kZSBoLCBzOworICAgICAgICBUaHJlYWQgc3Q7CisgICAgICAgIGlmICgoKGggPSBoZWFkKSAhPSBudWxsICYmIChzID0gaC5uZXh0KSAhPSBudWxsICYmCisgICAgICAgICAgICAgcy5wcmV2ID09IGhlYWQgJiYgKHN0ID0gcy50aHJlYWQpICE9IG51bGwpIHx8CisgICAgICAgICAgICAoKGggPSBoZWFkKSAhPSBudWxsICYmIChzID0gaC5uZXh0KSAhPSBudWxsICYmCisgICAgICAgICAgICAgcy5wcmV2ID09IGhlYWQgJiYgKHN0ID0gcy50aHJlYWQpICE9IG51bGwpKQorICAgICAgICAgICAgcmV0dXJuIHN0OworCisgICAgICAgIC8qCisgICAgICAgICAqIEhlYWQncyBuZXh0IGZpZWxkIG1pZ2h0IG5vdCBoYXZlIGJlZW4gc2V0IHlldCwgb3IgbWF5IGhhdmUKKyAgICAgICAgICogYmVlbiB1bnNldCBhZnRlciBzZXRIZWFkLiBTbyB3ZSBtdXN0IGNoZWNrIHRvIHNlZSBpZiB0YWlsCisgICAgICAgICAqIGlzIGFjdHVhbGx5IGZpcnN0IG5vZGUuIElmIG5vdCwgd2UgY29udGludWUgb24sIHNhZmVseQorICAgICAgICAgKiB0cmF2ZXJzaW5nIGZyb20gdGFpbCBiYWNrIHRvIGhlYWQgdG8gZmluZCBmaXJzdCwKKyAgICAgICAgICogZ3VhcmFudGVlaW5nIHRlcm1pbmF0aW9uLgorICAgICAgICAgKi8KKworICAgICAgICBOb2RlIHQgPSB0YWlsOworICAgICAgICBUaHJlYWQgZmlyc3RUaHJlYWQgPSBudWxsOworICAgICAgICB3aGlsZSAodCAhPSBudWxsICYmIHQgIT0gaGVhZCkgeworICAgICAgICAgICAgVGhyZWFkIHR0ID0gdC50aHJlYWQ7CisgICAgICAgICAgICBpZiAodHQgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICBmaXJzdFRocmVhZCA9IHR0OworICAgICAgICAgICAgdCA9IHQucHJldjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmlyc3RUaHJlYWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiB0aHJlYWQgaXMgY3VycmVudGx5IHF1ZXVlZC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gdHJhdmVyc2VzIHRoZSBxdWV1ZSB0byBkZXRlcm1pbmUKKyAgICAgKiBwcmVzZW5jZSBvZiB0aGUgZ2l2ZW4gdGhyZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIHRocmVhZCB0aGUgdGhyZWFkCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGdpdmVuIHRocmVhZCBpcyBvbiB0aGUgcXVldWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSB0aHJlYWQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzUXVldWVkKFRocmVhZCB0aHJlYWQpIHsKKyAgICAgICAgaWYgKHRocmVhZCA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGZvciAoTm9kZSBwID0gdGFpbDsgcCAhPSBudWxsOyBwID0gcC5wcmV2KQorICAgICAgICAgICAgaWYgKHAudGhyZWFkID09IHRocmVhZCkKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoZSBhcHBhcmVudCBmaXJzdCBxdWV1ZWQgdGhyZWFkLCBpZiBvbmUKKyAgICAgKiBleGlzdHMsIGlzIHdhaXRpbmcgaW4gZXhjbHVzaXZlIG1vZGUuICBJZiB0aGlzIG1ldGhvZCByZXR1cm5zCisgICAgICoge0Bjb2RlIHRydWV9LCBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGF0dGVtcHRpbmcgdG8gYWNxdWlyZSBpbgorICAgICAqIHNoYXJlZCBtb2RlICh0aGF0IGlzLCB0aGlzIG1ldGhvZCBpcyBpbnZva2VkIGZyb20ge0BsaW5rCisgICAgICogI3RyeUFjcXVpcmVTaGFyZWR9KSB0aGVuIGl0IGlzIGd1YXJhbnRlZWQgdGhhdCB0aGUgY3VycmVudCB0aHJlYWQKKyAgICAgKiBpcyBub3QgdGhlIGZpcnN0IHF1ZXVlZCB0aHJlYWQuICBVc2VkIG9ubHkgYXMgYSBoZXVyaXN0aWMgaW4KKyAgICAgKiBSZWVudHJhbnRSZWFkV3JpdGVMb2NrLgorICAgICAqLworICAgIGZpbmFsIGJvb2xlYW4gYXBwYXJlbnRseUZpcnN0UXVldWVkSXNFeGNsdXNpdmUoKSB7CisgICAgICAgIE5vZGUgaCwgczsKKyAgICAgICAgcmV0dXJuIChoID0gaGVhZCkgIT0gbnVsbCAmJgorICAgICAgICAgICAgKHMgPSBoLm5leHQpICAhPSBudWxsICYmCisgICAgICAgICAgICAhcy5pc1NoYXJlZCgpICAgICAgICAgJiYKKyAgICAgICAgICAgIHMudGhyZWFkICE9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUXVlcmllcyB3aGV0aGVyIGFueSB0aHJlYWRzIGhhdmUgYmVlbiB3YWl0aW5nIHRvIGFjcXVpcmUgbG9uZ2VyCisgICAgICogdGhhbiB0aGUgY3VycmVudCB0aHJlYWQuCisgICAgICoKKyAgICAgKiA8cD5BbiBpbnZvY2F0aW9uIG9mIHRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtYXkgYmUKKyAgICAgKiBtb3JlIGVmZmljaWVudCB0aGFuKToKKyAgICAgKiAgPHByZT4ge0Bjb2RlCisgICAgICogZ2V0Rmlyc3RRdWV1ZWRUaHJlYWQoKSAhPSBUaHJlYWQuY3VycmVudFRocmVhZCgpICYmCisgICAgICogaGFzUXVldWVkVGhyZWFkcygpfTwvcHJlPgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IGJlY2F1c2UgY2FuY2VsbGF0aW9ucyBkdWUgdG8gaW50ZXJydXB0cyBhbmQKKyAgICAgKiB0aW1lb3V0cyBtYXkgb2NjdXIgYXQgYW55IHRpbWUsIGEge0Bjb2RlIHRydWV9IHJldHVybiBkb2VzIG5vdAorICAgICAqIGd1YXJhbnRlZSB0aGF0IHNvbWUgb3RoZXIgdGhyZWFkIHdpbGwgYWNxdWlyZSBiZWZvcmUgdGhlIGN1cnJlbnQKKyAgICAgKiB0aHJlYWQuICBMaWtld2lzZSwgaXQgaXMgcG9zc2libGUgZm9yIGFub3RoZXIgdGhyZWFkIHRvIHdpbiBhCisgICAgICogcmFjZSB0byBlbnF1ZXVlIGFmdGVyIHRoaXMgbWV0aG9kIGhhcyByZXR1cm5lZCB7QGNvZGUgZmFsc2V9LAorICAgICAqIGR1ZSB0byB0aGUgcXVldWUgYmVpbmcgZW1wdHkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGJ5IGEgZmFpciBzeW5jaHJvbml6ZXIgdG8KKyAgICAgKiBhdm9pZCA8YSBocmVmPSJBYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplciNiYXJnaW5nIj5iYXJnaW5nPC9hPi4KKyAgICAgKiBTdWNoIGEgc3luY2hyb25pemVyJ3Mge0BsaW5rICN0cnlBY3F1aXJlfSBtZXRob2Qgc2hvdWxkIHJldHVybgorICAgICAqIHtAY29kZSBmYWxzZX0sIGFuZCBpdHMge0BsaW5rICN0cnlBY3F1aXJlU2hhcmVkfSBtZXRob2Qgc2hvdWxkCisgICAgICogcmV0dXJuIGEgbmVnYXRpdmUgdmFsdWUsIGlmIHRoaXMgbWV0aG9kIHJldHVybnMge0Bjb2RlIHRydWV9CisgICAgICogKHVubGVzcyB0aGlzIGlzIGEgcmVlbnRyYW50IGFjcXVpcmUpLiAgRm9yIGV4YW1wbGUsIHRoZSB7QGNvZGUKKyAgICAgKiB0cnlBY3F1aXJlfSBtZXRob2QgZm9yIGEgZmFpciwgcmVlbnRyYW50LCBleGNsdXNpdmUgbW9kZQorICAgICAqIHN5bmNocm9uaXplciBtaWdodCBsb29rIGxpa2UgdGhpczoKKyAgICAgKgorICAgICAqICA8cHJlPiB7QGNvZGUKKyAgICAgKiBwcm90ZWN0ZWQgYm9vbGVhbiB0cnlBY3F1aXJlKGludCBhcmcpIHsKKyAgICAgKiAgIGlmIChpc0hlbGRFeGNsdXNpdmVseSgpKSB7CisgICAgICogICAgIC8vIEEgcmVlbnRyYW50IGFjcXVpcmU7IGluY3JlbWVudCBob2xkIGNvdW50CisgICAgICogICAgIHJldHVybiB0cnVlOworICAgICAqICAgfSBlbHNlIGlmIChoYXNRdWV1ZWRQcmVkZWNlc3NvcnMoKSkgeworICAgICAqICAgICByZXR1cm4gZmFsc2U7CisgICAgICogICB9IGVsc2UgeworICAgICAqICAgICAvLyB0cnkgdG8gYWNxdWlyZSBub3JtYWxseQorICAgICAqICAgfQorICAgICAqIH19PC9wcmU+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGVyZSBpcyBhIHF1ZXVlZCB0aHJlYWQgcHJlY2VkaW5nIHRoZQorICAgICAqICAgICAgICAgY3VycmVudCB0aHJlYWQsIGFuZCB7QGNvZGUgZmFsc2V9IGlmIHRoZSBjdXJyZW50IHRocmVhZAorICAgICAqICAgICAgICAgaXMgYXQgdGhlIGhlYWQgb2YgdGhlIHF1ZXVlIG9yIHRoZSBxdWV1ZSBpcyBlbXB0eQorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKi8KKyAgICAvKnB1YmxpYyovIGZpbmFsIGJvb2xlYW4gaGFzUXVldWVkUHJlZGVjZXNzb3JzKCkgeyAvLyBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgLy8gVGhlIGNvcnJlY3RuZXNzIG9mIHRoaXMgZGVwZW5kcyBvbiBoZWFkIGJlaW5nIGluaXRpYWxpemVkCisgICAgICAgIC8vIGJlZm9yZSB0YWlsIGFuZCBvbiBoZWFkLm5leHQgYmVpbmcgYWNjdXJhdGUgaWYgdGhlIGN1cnJlbnQKKyAgICAgICAgLy8gdGhyZWFkIGlzIGZpcnN0IGluIHF1ZXVlLgorICAgICAgICBOb2RlIHQgPSB0YWlsOyAvLyBSZWFkIGZpZWxkcyBpbiByZXZlcnNlIGluaXRpYWxpemF0aW9uIG9yZGVyCisgICAgICAgIE5vZGUgaCA9IGhlYWQ7CisgICAgICAgIE5vZGUgczsKKyAgICAgICAgcmV0dXJuIGggIT0gdCAmJgorICAgICAgICAgICAgKChzID0gaC5uZXh0KSA9PSBudWxsIHx8IHMudGhyZWFkICE9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkpOworICAgIH0KKworCisgICAgLy8gSW5zdHJ1bWVudGF0aW9uIGFuZCBtb25pdG9yaW5nIG1ldGhvZHMKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gZXN0aW1hdGUgb2YgdGhlIG51bWJlciBvZiB0aHJlYWRzIHdhaXRpbmcgdG8KKyAgICAgKiBhY3F1aXJlLiAgVGhlIHZhbHVlIGlzIG9ubHkgYW4gZXN0aW1hdGUgYmVjYXVzZSB0aGUgbnVtYmVyIG9mCisgICAgICogdGhyZWFkcyBtYXkgY2hhbmdlIGR5bmFtaWNhbGx5IHdoaWxlIHRoaXMgbWV0aG9kIHRyYXZlcnNlcworICAgICAqIGludGVybmFsIGRhdGEgc3RydWN0dXJlcy4gIFRoaXMgbWV0aG9kIGlzIGRlc2lnbmVkIGZvciB1c2UgaW4KKyAgICAgKiBtb25pdG9yaW5nIHN5c3RlbSBzdGF0ZSwgbm90IGZvciBzeW5jaHJvbml6YXRpb24KKyAgICAgKiBjb250cm9sLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZXN0aW1hdGVkIG51bWJlciBvZiB0aHJlYWRzIHdhaXRpbmcgdG8gYWNxdWlyZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UXVldWVMZW5ndGgoKSB7CisgICAgICAgIGludCBuID0gMDsKKyAgICAgICAgZm9yIChOb2RlIHAgPSB0YWlsOyBwICE9IG51bGw7IHAgPSBwLnByZXYpIHsKKyAgICAgICAgICAgIGlmIChwLnRocmVhZCAhPSBudWxsKQorICAgICAgICAgICAgICAgICsrbjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29sbGVjdGlvbiBjb250YWluaW5nIHRocmVhZHMgdGhhdCBtYXkgYmUgd2FpdGluZyB0bworICAgICAqIGFjcXVpcmUuICBCZWNhdXNlIHRoZSBhY3R1YWwgc2V0IG9mIHRocmVhZHMgbWF5IGNoYW5nZQorICAgICAqIGR5bmFtaWNhbGx5IHdoaWxlIGNvbnN0cnVjdGluZyB0aGlzIHJlc3VsdCwgdGhlIHJldHVybmVkCisgICAgICogY29sbGVjdGlvbiBpcyBvbmx5IGEgYmVzdC1lZmZvcnQgZXN0aW1hdGUuICBUaGUgZWxlbWVudHMgb2YgdGhlCisgICAgICogcmV0dXJuZWQgY29sbGVjdGlvbiBhcmUgaW4gbm8gcGFydGljdWxhciBvcmRlci4gIFRoaXMgbWV0aG9kIGlzCisgICAgICogZGVzaWduZWQgdG8gZmFjaWxpdGF0ZSBjb25zdHJ1Y3Rpb24gb2Ygc3ViY2xhc3NlcyB0aGF0IHByb3ZpZGUKKyAgICAgKiBtb3JlIGV4dGVuc2l2ZSBtb25pdG9yaW5nIGZhY2lsaXRpZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb2xsZWN0aW9uIG9mIHRocmVhZHMKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQ29sbGVjdGlvbjxUaHJlYWQ+IGdldFF1ZXVlZFRocmVhZHMoKSB7CisgICAgICAgIEFycmF5TGlzdDxUaHJlYWQ+IGxpc3QgPSBuZXcgQXJyYXlMaXN0PFRocmVhZD4oKTsKKyAgICAgICAgZm9yIChOb2RlIHAgPSB0YWlsOyBwICE9IG51bGw7IHAgPSBwLnByZXYpIHsKKyAgICAgICAgICAgIFRocmVhZCB0ID0gcC50aHJlYWQ7CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKQorICAgICAgICAgICAgICAgIGxpc3QuYWRkKHQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBsaXN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb2xsZWN0aW9uIGNvbnRhaW5pbmcgdGhyZWFkcyB0aGF0IG1heSBiZSB3YWl0aW5nIHRvCisgICAgICogYWNxdWlyZSBpbiBleGNsdXNpdmUgbW9kZS4gVGhpcyBoYXMgdGhlIHNhbWUgcHJvcGVydGllcworICAgICAqIGFzIHtAbGluayAjZ2V0UXVldWVkVGhyZWFkc30gZXhjZXB0IHRoYXQgaXQgb25seSByZXR1cm5zCisgICAgICogdGhvc2UgdGhyZWFkcyB3YWl0aW5nIGR1ZSB0byBhbiBleGNsdXNpdmUgYWNxdWlyZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNvbGxlY3Rpb24gb2YgdGhyZWFkcworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBDb2xsZWN0aW9uPFRocmVhZD4gZ2V0RXhjbHVzaXZlUXVldWVkVGhyZWFkcygpIHsKKyAgICAgICAgQXJyYXlMaXN0PFRocmVhZD4gbGlzdCA9IG5ldyBBcnJheUxpc3Q8VGhyZWFkPigpOworICAgICAgICBmb3IgKE5vZGUgcCA9IHRhaWw7IHAgIT0gbnVsbDsgcCA9IHAucHJldikgeworICAgICAgICAgICAgaWYgKCFwLmlzU2hhcmVkKCkpIHsKKyAgICAgICAgICAgICAgICBUaHJlYWQgdCA9IHAudGhyZWFkOworICAgICAgICAgICAgICAgIGlmICh0ICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIGxpc3QuYWRkKHQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBsaXN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb2xsZWN0aW9uIGNvbnRhaW5pbmcgdGhyZWFkcyB0aGF0IG1heSBiZSB3YWl0aW5nIHRvCisgICAgICogYWNxdWlyZSBpbiBzaGFyZWQgbW9kZS4gVGhpcyBoYXMgdGhlIHNhbWUgcHJvcGVydGllcworICAgICAqIGFzIHtAbGluayAjZ2V0UXVldWVkVGhyZWFkc30gZXhjZXB0IHRoYXQgaXQgb25seSByZXR1cm5zCisgICAgICogdGhvc2UgdGhyZWFkcyB3YWl0aW5nIGR1ZSB0byBhIHNoYXJlZCBhY3F1aXJlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29sbGVjdGlvbiBvZiB0aHJlYWRzCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENvbGxlY3Rpb248VGhyZWFkPiBnZXRTaGFyZWRRdWV1ZWRUaHJlYWRzKCkgeworICAgICAgICBBcnJheUxpc3Q8VGhyZWFkPiBsaXN0ID0gbmV3IEFycmF5TGlzdDxUaHJlYWQ+KCk7CisgICAgICAgIGZvciAoTm9kZSBwID0gdGFpbDsgcCAhPSBudWxsOyBwID0gcC5wcmV2KSB7CisgICAgICAgICAgICBpZiAocC5pc1NoYXJlZCgpKSB7CisgICAgICAgICAgICAgICAgVGhyZWFkIHQgPSBwLnRocmVhZDsKKyAgICAgICAgICAgICAgICBpZiAodCAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICBsaXN0LmFkZCh0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbGlzdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGlkZW50aWZ5aW5nIHRoaXMgc3luY2hyb25pemVyLCBhcyB3ZWxsIGFzIGl0cyBzdGF0ZS4KKyAgICAgKiBUaGUgc3RhdGUsIGluIGJyYWNrZXRzLCBpbmNsdWRlcyB0aGUgU3RyaW5nIHtAY29kZSAiU3RhdGUgPSJ9CisgICAgICogZm9sbG93ZWQgYnkgdGhlIGN1cnJlbnQgdmFsdWUgb2Yge0BsaW5rICNnZXRTdGF0ZX0sIGFuZCBlaXRoZXIKKyAgICAgKiB7QGNvZGUgIm5vbmVtcHR5In0gb3Ige0Bjb2RlICJlbXB0eSJ9IGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZQorICAgICAqIHF1ZXVlIGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHJldHVybiBhIHN0cmluZyBpZGVudGlmeWluZyB0aGlzIHN5bmNocm9uaXplciwgYXMgd2VsbCBhcyBpdHMgc3RhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBsb25nIHMgPSBnZXRTdGF0ZSgpOworICAgICAgICBTdHJpbmcgcSAgPSBoYXNRdWV1ZWRUaHJlYWRzKCkgPyAibm9uIiA6ICIiOworICAgICAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKSArCisgICAgICAgICAgICAiW1N0YXRlID0gIiArIHMgKyAiLCAiICsgcSArICJlbXB0eSBxdWV1ZV0iOworICAgIH0KKworCisgICAgLy8gSW50ZXJuYWwgc3VwcG9ydCBtZXRob2RzIGZvciBDb25kaXRpb25zCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgYSBub2RlLCBhbHdheXMgb25lIHRoYXQgd2FzIGluaXRpYWxseSBwbGFjZWQgb24KKyAgICAgKiBhIGNvbmRpdGlvbiBxdWV1ZSwgaXMgbm93IHdhaXRpbmcgdG8gcmVhY3F1aXJlIG9uIHN5bmMgcXVldWUuCisgICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgaXMgcmVhY3F1aXJpbmcKKyAgICAgKi8KKyAgICBmaW5hbCBib29sZWFuIGlzT25TeW5jUXVldWUoTm9kZSBub2RlKSB7CisgICAgICAgIGlmIChub2RlLndhaXRTdGF0dXMgPT0gTm9kZS5DT05ESVRJT04gfHwgbm9kZS5wcmV2ID09IG51bGwpCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmIChub2RlLm5leHQgIT0gbnVsbCkgLy8gSWYgaGFzIHN1Y2Nlc3NvciwgaXQgbXVzdCBiZSBvbiBxdWV1ZQorICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIC8qCisgICAgICAgICAqIG5vZGUucHJldiBjYW4gYmUgbm9uLW51bGwsIGJ1dCBub3QgeWV0IG9uIHF1ZXVlIGJlY2F1c2UKKyAgICAgICAgICogdGhlIENBUyB0byBwbGFjZSBpdCBvbiBxdWV1ZSBjYW4gZmFpbC4gU28gd2UgaGF2ZSB0bworICAgICAgICAgKiB0cmF2ZXJzZSBmcm9tIHRhaWwgdG8gbWFrZSBzdXJlIGl0IGFjdHVhbGx5IG1hZGUgaXQuICBJdAorICAgICAgICAgKiB3aWxsIGFsd2F5cyBiZSBuZWFyIHRoZSB0YWlsIGluIGNhbGxzIHRvIHRoaXMgbWV0aG9kLCBhbmQKKyAgICAgICAgICogdW5sZXNzIHRoZSBDQVMgZmFpbGVkICh3aGljaCBpcyB1bmxpa2VseSksIGl0IHdpbGwgYmUKKyAgICAgICAgICogdGhlcmUsIHNvIHdlIGhhcmRseSBldmVyIHRyYXZlcnNlIG11Y2guCisgICAgICAgICAqLworICAgICAgICByZXR1cm4gZmluZE5vZGVGcm9tVGFpbChub2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgbm9kZSBpcyBvbiBzeW5jIHF1ZXVlIGJ5IHNlYXJjaGluZyBiYWNrd2FyZHMgZnJvbSB0YWlsLgorICAgICAqIENhbGxlZCBvbmx5IHdoZW4gbmVlZGVkIGJ5IGlzT25TeW5jUXVldWUuCisgICAgICogQHJldHVybiB0cnVlIGlmIHByZXNlbnQKKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gZmluZE5vZGVGcm9tVGFpbChOb2RlIG5vZGUpIHsKKyAgICAgICAgTm9kZSB0ID0gdGFpbDsKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgaWYgKHQgPT0gbm9kZSkKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIGlmICh0ID09IG51bGwpCisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgdCA9IHQucHJldjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRyYW5zZmVycyBhIG5vZGUgZnJvbSBhIGNvbmRpdGlvbiBxdWV1ZSBvbnRvIHN5bmMgcXVldWUuCisgICAgICogUmV0dXJucyB0cnVlIGlmIHN1Y2Nlc3NmdWwuCisgICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgc3VjY2Vzc2Z1bGx5IHRyYW5zZmVycmVkIChlbHNlIHRoZSBub2RlIHdhcworICAgICAqIGNhbmNlbGxlZCBiZWZvcmUgc2lnbmFsKS4KKyAgICAgKi8KKyAgICBmaW5hbCBib29sZWFuIHRyYW5zZmVyRm9yU2lnbmFsKE5vZGUgbm9kZSkgeworICAgICAgICAvKgorICAgICAgICAgKiBJZiBjYW5ub3QgY2hhbmdlIHdhaXRTdGF0dXMsIHRoZSBub2RlIGhhcyBiZWVuIGNhbmNlbGxlZC4KKyAgICAgICAgICovCisgICAgICAgIGlmICghY29tcGFyZUFuZFNldFdhaXRTdGF0dXMobm9kZSwgTm9kZS5DT05ESVRJT04sIDApKQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICAgIC8qCisgICAgICAgICAqIFNwbGljZSBvbnRvIHF1ZXVlIGFuZCB0cnkgdG8gc2V0IHdhaXRTdGF0dXMgb2YgcHJlZGVjZXNzb3IgdG8KKyAgICAgICAgICogaW5kaWNhdGUgdGhhdCB0aHJlYWQgaXMgKHByb2JhYmx5KSB3YWl0aW5nLiBJZiBjYW5jZWxsZWQgb3IKKyAgICAgICAgICogYXR0ZW1wdCB0byBzZXQgd2FpdFN0YXR1cyBmYWlscywgd2FrZSB1cCB0byByZXN5bmMgKGluIHdoaWNoCisgICAgICAgICAqIGNhc2UgdGhlIHdhaXRTdGF0dXMgY2FuIGJlIHRyYW5zaWVudGx5IGFuZCBoYXJtbGVzc2x5IHdyb25nKS4KKyAgICAgICAgICovCisgICAgICAgIE5vZGUgcCA9IGVucShub2RlKTsKKyAgICAgICAgaW50IHdzID0gcC53YWl0U3RhdHVzOworICAgICAgICBpZiAod3MgPiAwIHx8ICFjb21wYXJlQW5kU2V0V2FpdFN0YXR1cyhwLCB3cywgTm9kZS5TSUdOQUwpKQorICAgICAgICAgICAgTG9ja1N1cHBvcnQudW5wYXJrKG5vZGUudGhyZWFkKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJhbnNmZXJzIG5vZGUsIGlmIG5lY2Vzc2FyeSwgdG8gc3luYyBxdWV1ZSBhZnRlciBhIGNhbmNlbGxlZAorICAgICAqIHdhaXQuIFJldHVybnMgdHJ1ZSBpZiB0aHJlYWQgd2FzIGNhbmNlbGxlZCBiZWZvcmUgYmVpbmcKKyAgICAgKiBzaWduYWxsZWQuCisgICAgICogQHBhcmFtIG5vZGUgaXRzIG5vZGUKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgY2FuY2VsbGVkIGJlZm9yZSB0aGUgbm9kZSB3YXMgc2lnbmFsbGVkCisgICAgICovCisgICAgZmluYWwgYm9vbGVhbiB0cmFuc2ZlckFmdGVyQ2FuY2VsbGVkV2FpdChOb2RlIG5vZGUpIHsKKyAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXRXYWl0U3RhdHVzKG5vZGUsIE5vZGUuQ09ORElUSU9OLCAwKSkgeworICAgICAgICAgICAgZW5xKG5vZGUpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgLyoKKyAgICAgICAgICogSWYgd2UgbG9zdCBvdXQgdG8gYSBzaWduYWwoKSwgdGhlbiB3ZSBjYW4ndCBwcm9jZWVkCisgICAgICAgICAqIHVudGlsIGl0IGZpbmlzaGVzIGl0cyBlbnEoKS4gIENhbmNlbGxpbmcgZHVyaW5nIGFuCisgICAgICAgICAqIGluY29tcGxldGUgdHJhbnNmZXIgaXMgYm90aCByYXJlIGFuZCB0cmFuc2llbnQsIHNvIGp1c3QKKyAgICAgICAgICogc3Bpbi4KKyAgICAgICAgICovCisgICAgICAgIHdoaWxlICghaXNPblN5bmNRdWV1ZShub2RlKSkKKyAgICAgICAgICAgIFRocmVhZC55aWVsZCgpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW52b2tlcyByZWxlYXNlIHdpdGggY3VycmVudCBzdGF0ZSB2YWx1ZTsgcmV0dXJucyBzYXZlZCBzdGF0ZS4KKyAgICAgKiBDYW5jZWxzIG5vZGUgYW5kIHRocm93cyBleGNlcHRpb24gb24gZmFpbHVyZS4KKyAgICAgKiBAcGFyYW0gbm9kZSB0aGUgY29uZGl0aW9uIG5vZGUgZm9yIHRoaXMgd2FpdAorICAgICAqIEByZXR1cm4gcHJldmlvdXMgc3luYyBzdGF0ZQorICAgICAqLworICAgIGZpbmFsIGxvbmcgZnVsbHlSZWxlYXNlKE5vZGUgbm9kZSkgeworICAgICAgICBib29sZWFuIGZhaWxlZCA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsb25nIHNhdmVkU3RhdGUgPSBnZXRTdGF0ZSgpOworICAgICAgICAgICAgaWYgKHJlbGVhc2Uoc2F2ZWRTdGF0ZSkpIHsKKyAgICAgICAgICAgICAgICBmYWlsZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICByZXR1cm4gc2F2ZWRTdGF0ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChmYWlsZWQpCisgICAgICAgICAgICAgICAgbm9kZS53YWl0U3RhdHVzID0gTm9kZS5DQU5DRUxMRUQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBJbnN0cnVtZW50YXRpb24gbWV0aG9kcyBmb3IgY29uZGl0aW9ucworCisgICAgLyoqCisgICAgICogUXVlcmllcyB3aGV0aGVyIHRoZSBnaXZlbiBDb25kaXRpb25PYmplY3QKKyAgICAgKiB1c2VzIHRoaXMgc3luY2hyb25pemVyIGFzIGl0cyBsb2NrLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbmRpdGlvbiB0aGUgY29uZGl0aW9uCisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIG93bmVkCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgY29uZGl0aW9uIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBvd25zKENvbmRpdGlvbk9iamVjdCBjb25kaXRpb24pIHsKKyAgICAgICAgaWYgKGNvbmRpdGlvbiA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiBjb25kaXRpb24uaXNPd25lZEJ5KHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFF1ZXJpZXMgd2hldGhlciBhbnkgdGhyZWFkcyBhcmUgd2FpdGluZyBvbiB0aGUgZ2l2ZW4gY29uZGl0aW9uCisgICAgICogYXNzb2NpYXRlZCB3aXRoIHRoaXMgc3luY2hyb25pemVyLiBOb3RlIHRoYXQgYmVjYXVzZSB0aW1lb3V0cworICAgICAqIGFuZCBpbnRlcnJ1cHRzIG1heSBvY2N1ciBhdCBhbnkgdGltZSwgYSA8dHQ+dHJ1ZTwvdHQ+IHJldHVybgorICAgICAqIGRvZXMgbm90IGd1YXJhbnRlZSB0aGF0IGEgZnV0dXJlIDx0dD5zaWduYWw8L3R0PiB3aWxsIGF3YWtlbgorICAgICAqIGFueSB0aHJlYWRzLiAgVGhpcyBtZXRob2QgaXMgZGVzaWduZWQgcHJpbWFyaWx5IGZvciB1c2UgaW4KKyAgICAgKiBtb25pdG9yaW5nIG9mIHRoZSBzeXN0ZW0gc3RhdGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29uZGl0aW9uIHRoZSBjb25kaXRpb24KKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhlcmUgYXJlIGFueSB3YWl0aW5nIHRocmVhZHMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gaWYgZXhjbHVzaXZlIHN5bmNocm9uaXphdGlvbgorICAgICAqICAgICAgICAgaXMgbm90IGhlbGQKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gY29uZGl0aW9uIGlzCisgICAgICogICAgICAgICBub3QgYXNzb2NpYXRlZCB3aXRoIHRoaXMgc3luY2hyb25pemVyCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgY29uZGl0aW9uIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNXYWl0ZXJzKENvbmRpdGlvbk9iamVjdCBjb25kaXRpb24pIHsKKyAgICAgICAgaWYgKCFvd25zKGNvbmRpdGlvbikpCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJOb3Qgb3duZXIiKTsKKyAgICAgICAgcmV0dXJuIGNvbmRpdGlvbi5oYXNXYWl0ZXJzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBlc3RpbWF0ZSBvZiB0aGUgbnVtYmVyIG9mIHRocmVhZHMgd2FpdGluZyBvbiB0aGUKKyAgICAgKiBnaXZlbiBjb25kaXRpb24gYXNzb2NpYXRlZCB3aXRoIHRoaXMgc3luY2hyb25pemVyLiBOb3RlIHRoYXQKKyAgICAgKiBiZWNhdXNlIHRpbWVvdXRzIGFuZCBpbnRlcnJ1cHRzIG1heSBvY2N1ciBhdCBhbnkgdGltZSwgdGhlCisgICAgICogZXN0aW1hdGUgc2VydmVzIG9ubHkgYXMgYW4gdXBwZXIgYm91bmQgb24gdGhlIGFjdHVhbCBudW1iZXIgb2YKKyAgICAgKiB3YWl0ZXJzLiAgVGhpcyBtZXRob2QgaXMgZGVzaWduZWQgZm9yIHVzZSBpbiBtb25pdG9yaW5nIG9mIHRoZQorICAgICAqIHN5c3RlbSBzdGF0ZSwgbm90IGZvciBzeW5jaHJvbml6YXRpb24gY29udHJvbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb25kaXRpb24gdGhlIGNvbmRpdGlvbgorICAgICAqIEByZXR1cm4gdGhlIGVzdGltYXRlZCBudW1iZXIgb2Ygd2FpdGluZyB0aHJlYWRzCisgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIGV4Y2x1c2l2ZSBzeW5jaHJvbml6YXRpb24KKyAgICAgKiAgICAgICAgIGlzIG5vdCBoZWxkCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGNvbmRpdGlvbiBpcworICAgICAqICAgICAgICAgbm90IGFzc29jaWF0ZWQgd2l0aCB0aGlzIHN5bmNocm9uaXplcgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGNvbmRpdGlvbiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRXYWl0UXVldWVMZW5ndGgoQ29uZGl0aW9uT2JqZWN0IGNvbmRpdGlvbikgeworICAgICAgICBpZiAoIW93bnMoY29uZGl0aW9uKSkKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5vdCBvd25lciIpOworICAgICAgICByZXR1cm4gY29uZGl0aW9uLmdldFdhaXRRdWV1ZUxlbmd0aCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb2xsZWN0aW9uIGNvbnRhaW5pbmcgdGhvc2UgdGhyZWFkcyB0aGF0IG1heSBiZQorICAgICAqIHdhaXRpbmcgb24gdGhlIGdpdmVuIGNvbmRpdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhpcworICAgICAqIHN5bmNocm9uaXplci4gIEJlY2F1c2UgdGhlIGFjdHVhbCBzZXQgb2YgdGhyZWFkcyBtYXkgY2hhbmdlCisgICAgICogZHluYW1pY2FsbHkgd2hpbGUgY29uc3RydWN0aW5nIHRoaXMgcmVzdWx0LCB0aGUgcmV0dXJuZWQKKyAgICAgKiBjb2xsZWN0aW9uIGlzIG9ubHkgYSBiZXN0LWVmZm9ydCBlc3RpbWF0ZS4gVGhlIGVsZW1lbnRzIG9mIHRoZQorICAgICAqIHJldHVybmVkIGNvbGxlY3Rpb24gYXJlIGluIG5vIHBhcnRpY3VsYXIgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29uZGl0aW9uIHRoZSBjb25kaXRpb24KKyAgICAgKiBAcmV0dXJuIHRoZSBjb2xsZWN0aW9uIG9mIHRocmVhZHMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gaWYgZXhjbHVzaXZlIHN5bmNocm9uaXphdGlvbgorICAgICAqICAgICAgICAgaXMgbm90IGhlbGQKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gY29uZGl0aW9uIGlzCisgICAgICogICAgICAgICBub3QgYXNzb2NpYXRlZCB3aXRoIHRoaXMgc3luY2hyb25pemVyCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgY29uZGl0aW9uIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQ29sbGVjdGlvbjxUaHJlYWQ+IGdldFdhaXRpbmdUaHJlYWRzKENvbmRpdGlvbk9iamVjdCBjb25kaXRpb24pIHsKKyAgICAgICAgaWYgKCFvd25zKGNvbmRpdGlvbikpCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJOb3Qgb3duZXIiKTsKKyAgICAgICAgcmV0dXJuIGNvbmRpdGlvbi5nZXRXYWl0aW5nVGhyZWFkcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbmRpdGlvbiBpbXBsZW1lbnRhdGlvbiBmb3IgYSB7QGxpbmsKKyAgICAgKiBBYnN0cmFjdFF1ZXVlZExvbmdTeW5jaHJvbml6ZXJ9IHNlcnZpbmcgYXMgdGhlIGJhc2lzIG9mIGEge0BsaW5rCisgICAgICogTG9ja30gaW1wbGVtZW50YXRpb24uCisgICAgICoKKyAgICAgKiA8cD5NZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgdGhpcyBjbGFzcyBkZXNjcmliZXMgbWVjaGFuaWNzLAorICAgICAqIG5vdCBiZWhhdmlvcmFsIHNwZWNpZmljYXRpb25zIGZyb20gdGhlIHBvaW50IG9mIHZpZXcgb2YgTG9jaworICAgICAqIGFuZCBDb25kaXRpb24gdXNlcnMuIEV4cG9ydGVkIHZlcnNpb25zIG9mIHRoaXMgY2xhc3Mgd2lsbCBpbgorICAgICAqIGdlbmVyYWwgbmVlZCB0byBiZSBhY2NvbXBhbmllZCBieSBkb2N1bWVudGF0aW9uIGRlc2NyaWJpbmcKKyAgICAgKiBjb25kaXRpb24gc2VtYW50aWNzIHRoYXQgcmVseSBvbiB0aG9zZSBvZiB0aGUgYXNzb2NpYXRlZAorICAgICAqIDx0dD5BYnN0cmFjdFF1ZXVlZExvbmdTeW5jaHJvbml6ZXI8L3R0Pi4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgY2xhc3MgaXMgU2VyaWFsaXphYmxlLCBidXQgYWxsIGZpZWxkcyBhcmUgdHJhbnNpZW50LAorICAgICAqIHNvIGRlc2VyaWFsaXplZCBjb25kaXRpb25zIGhhdmUgbm8gd2FpdGVycy4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgY2xhc3MgQ29uZGl0aW9uT2JqZWN0IGltcGxlbWVudHMgQ29uZGl0aW9uLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDExNzM5ODQ4NzI1NzI0MTQ2OTlMOworICAgICAgICAvKiogRmlyc3Qgbm9kZSBvZiBjb25kaXRpb24gcXVldWUuICovCisgICAgICAgIHByaXZhdGUgdHJhbnNpZW50IE5vZGUgZmlyc3RXYWl0ZXI7CisgICAgICAgIC8qKiBMYXN0IG5vZGUgb2YgY29uZGl0aW9uIHF1ZXVlLiAqLworICAgICAgICBwcml2YXRlIHRyYW5zaWVudCBOb2RlIGxhc3RXYWl0ZXI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENyZWF0ZXMgYSBuZXcgPHR0PkNvbmRpdGlvbk9iamVjdDwvdHQ+IGluc3RhbmNlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIENvbmRpdGlvbk9iamVjdCgpIHsgfQorCisgICAgICAgIC8vIEludGVybmFsIG1ldGhvZHMKKworICAgICAgICAvKioKKyAgICAgICAgICogQWRkcyBhIG5ldyB3YWl0ZXIgdG8gd2FpdCBxdWV1ZS4KKyAgICAgICAgICogQHJldHVybiBpdHMgbmV3IHdhaXQgbm9kZQorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBOb2RlIGFkZENvbmRpdGlvbldhaXRlcigpIHsKKyAgICAgICAgICAgIE5vZGUgdCA9IGxhc3RXYWl0ZXI7CisgICAgICAgICAgICAvLyBJZiBsYXN0V2FpdGVyIGlzIGNhbmNlbGxlZCwgY2xlYW4gb3V0LgorICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCAmJiB0LndhaXRTdGF0dXMgIT0gTm9kZS5DT05ESVRJT04pIHsKKyAgICAgICAgICAgICAgICB1bmxpbmtDYW5jZWxsZWRXYWl0ZXJzKCk7CisgICAgICAgICAgICAgICAgdCA9IGxhc3RXYWl0ZXI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBOb2RlIG5vZGUgPSBuZXcgTm9kZShUaHJlYWQuY3VycmVudFRocmVhZCgpLCBOb2RlLkNPTkRJVElPTik7CisgICAgICAgICAgICBpZiAodCA9PSBudWxsKQorICAgICAgICAgICAgICAgIGZpcnN0V2FpdGVyID0gbm9kZTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICB0Lm5leHRXYWl0ZXIgPSBub2RlOworICAgICAgICAgICAgbGFzdFdhaXRlciA9IG5vZGU7CisgICAgICAgICAgICByZXR1cm4gbm9kZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZW1vdmVzIGFuZCB0cmFuc2ZlcnMgbm9kZXMgdW50aWwgaGl0IG5vbi1jYW5jZWxsZWQgb25lIG9yCisgICAgICAgICAqIG51bGwuIFNwbGl0IG91dCBmcm9tIHNpZ25hbCBpbiBwYXJ0IHRvIGVuY291cmFnZSBjb21waWxlcnMKKyAgICAgICAgICogdG8gaW5saW5lIHRoZSBjYXNlIG9mIG5vIHdhaXRlcnMuCisgICAgICAgICAqIEBwYXJhbSBmaXJzdCAobm9uLW51bGwpIHRoZSBmaXJzdCBub2RlIG9uIGNvbmRpdGlvbiBxdWV1ZQorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSB2b2lkIGRvU2lnbmFsKE5vZGUgZmlyc3QpIHsKKyAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICBpZiAoIChmaXJzdFdhaXRlciA9IGZpcnN0Lm5leHRXYWl0ZXIpID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgIGxhc3RXYWl0ZXIgPSBudWxsOworICAgICAgICAgICAgICAgIGZpcnN0Lm5leHRXYWl0ZXIgPSBudWxsOworICAgICAgICAgICAgfSB3aGlsZSAoIXRyYW5zZmVyRm9yU2lnbmFsKGZpcnN0KSAmJgorICAgICAgICAgICAgICAgICAgICAgKGZpcnN0ID0gZmlyc3RXYWl0ZXIpICE9IG51bGwpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJlbW92ZXMgYW5kIHRyYW5zZmVycyBhbGwgbm9kZXMuCisgICAgICAgICAqIEBwYXJhbSBmaXJzdCAobm9uLW51bGwpIHRoZSBmaXJzdCBub2RlIG9uIGNvbmRpdGlvbiBxdWV1ZQorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSB2b2lkIGRvU2lnbmFsQWxsKE5vZGUgZmlyc3QpIHsKKyAgICAgICAgICAgIGxhc3RXYWl0ZXIgPSBmaXJzdFdhaXRlciA9IG51bGw7CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgTm9kZSBuZXh0ID0gZmlyc3QubmV4dFdhaXRlcjsKKyAgICAgICAgICAgICAgICBmaXJzdC5uZXh0V2FpdGVyID0gbnVsbDsKKyAgICAgICAgICAgICAgICB0cmFuc2ZlckZvclNpZ25hbChmaXJzdCk7CisgICAgICAgICAgICAgICAgZmlyc3QgPSBuZXh0OworICAgICAgICAgICAgfSB3aGlsZSAoZmlyc3QgIT0gbnVsbCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogVW5saW5rcyBjYW5jZWxsZWQgd2FpdGVyIG5vZGVzIGZyb20gY29uZGl0aW9uIHF1ZXVlLgorICAgICAgICAgKiBDYWxsZWQgb25seSB3aGlsZSBob2xkaW5nIGxvY2suIFRoaXMgaXMgY2FsbGVkIHdoZW4KKyAgICAgICAgICogY2FuY2VsbGF0aW9uIG9jY3VycmVkIGR1cmluZyBjb25kaXRpb24gd2FpdCwgYW5kIHVwb24KKyAgICAgICAgICogaW5zZXJ0aW9uIG9mIGEgbmV3IHdhaXRlciB3aGVuIGxhc3RXYWl0ZXIgaXMgc2VlbiB0byBoYXZlCisgICAgICAgICAqIGJlZW4gY2FuY2VsbGVkLiBUaGlzIG1ldGhvZCBpcyBuZWVkZWQgdG8gYXZvaWQgZ2FyYmFnZQorICAgICAgICAgKiByZXRlbnRpb24gaW4gdGhlIGFic2VuY2Ugb2Ygc2lnbmFscy4gU28gZXZlbiB0aG91Z2ggaXQgbWF5CisgICAgICAgICAqIHJlcXVpcmUgYSBmdWxsIHRyYXZlcnNhbCwgaXQgY29tZXMgaW50byBwbGF5IG9ubHkgd2hlbgorICAgICAgICAgKiB0aW1lb3V0cyBvciBjYW5jZWxsYXRpb25zIG9jY3VyIGluIHRoZSBhYnNlbmNlIG9mCisgICAgICAgICAqIHNpZ25hbHMuIEl0IHRyYXZlcnNlcyBhbGwgbm9kZXMgcmF0aGVyIHRoYW4gc3RvcHBpbmcgYXQgYQorICAgICAgICAgKiBwYXJ0aWN1bGFyIHRhcmdldCB0byB1bmxpbmsgYWxsIHBvaW50ZXJzIHRvIGdhcmJhZ2Ugbm9kZXMKKyAgICAgICAgICogd2l0aG91dCByZXF1aXJpbmcgbWFueSByZS10cmF2ZXJzYWxzIGR1cmluZyBjYW5jZWxsYXRpb24KKyAgICAgICAgICogc3Rvcm1zLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSB2b2lkIHVubGlua0NhbmNlbGxlZFdhaXRlcnMoKSB7CisgICAgICAgICAgICBOb2RlIHQgPSBmaXJzdFdhaXRlcjsKKyAgICAgICAgICAgIE5vZGUgdHJhaWwgPSBudWxsOworICAgICAgICAgICAgd2hpbGUgKHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIE5vZGUgbmV4dCA9IHQubmV4dFdhaXRlcjsKKyAgICAgICAgICAgICAgICBpZiAodC53YWl0U3RhdHVzICE9IE5vZGUuQ09ORElUSU9OKSB7CisgICAgICAgICAgICAgICAgICAgIHQubmV4dFdhaXRlciA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgIGlmICh0cmFpbCA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RXYWl0ZXIgPSBuZXh0OworICAgICAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgICAgICB0cmFpbC5uZXh0V2FpdGVyID0gbmV4dDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RXYWl0ZXIgPSB0cmFpbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICB0cmFpbCA9IHQ7CisgICAgICAgICAgICAgICAgdCA9IG5leHQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBwdWJsaWMgbWV0aG9kcworCisgICAgICAgIC8qKgorICAgICAgICAgKiBNb3ZlcyB0aGUgbG9uZ2VzdC13YWl0aW5nIHRocmVhZCwgaWYgb25lIGV4aXN0cywgZnJvbSB0aGUKKyAgICAgICAgICogd2FpdCBxdWV1ZSBmb3IgdGhpcyBjb25kaXRpb24gdG8gdGhlIHdhaXQgcXVldWUgZm9yIHRoZQorICAgICAgICAgKiBvd25pbmcgbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIHtAbGluayAjaXNIZWxkRXhjbHVzaXZlbHl9CisgICAgICAgICAqICAgICAgICAgcmV0dXJucyB7QGNvZGUgZmFsc2V9CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmluYWwgdm9pZCBzaWduYWwoKSB7CisgICAgICAgICAgICBpZiAoIWlzSGVsZEV4Y2x1c2l2ZWx5KCkpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIE5vZGUgZmlyc3QgPSBmaXJzdFdhaXRlcjsKKyAgICAgICAgICAgIGlmIChmaXJzdCAhPSBudWxsKQorICAgICAgICAgICAgICAgIGRvU2lnbmFsKGZpcnN0KTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBNb3ZlcyBhbGwgdGhyZWFkcyBmcm9tIHRoZSB3YWl0IHF1ZXVlIGZvciB0aGlzIGNvbmRpdGlvbiB0bworICAgICAgICAgKiB0aGUgd2FpdCBxdWV1ZSBmb3IgdGhlIG93bmluZyBsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gaWYge0BsaW5rICNpc0hlbGRFeGNsdXNpdmVseX0KKyAgICAgICAgICogICAgICAgICByZXR1cm5zIHtAY29kZSBmYWxzZX0KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNpZ25hbEFsbCgpIHsKKyAgICAgICAgICAgIGlmICghaXNIZWxkRXhjbHVzaXZlbHkoKSkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgTm9kZSBmaXJzdCA9IGZpcnN0V2FpdGVyOworICAgICAgICAgICAgaWYgKGZpcnN0ICE9IG51bGwpCisgICAgICAgICAgICAgICAgZG9TaWduYWxBbGwoZmlyc3QpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEltcGxlbWVudHMgdW5pbnRlcnJ1cHRpYmxlIGNvbmRpdGlvbiB3YWl0LgorICAgICAgICAgKiA8b2w+CisgICAgICAgICAqIDxsaT4gU2F2ZSBsb2NrIHN0YXRlIHJldHVybmVkIGJ5IHtAbGluayAjZ2V0U3RhdGV9LgorICAgICAgICAgKiA8bGk+IEludm9rZSB7QGxpbmsgI3JlbGVhc2V9IHdpdGgKKyAgICAgICAgICogICAgICBzYXZlZCBzdGF0ZSBhcyBhcmd1bWVudCwgdGhyb3dpbmcKKyAgICAgICAgICogICAgICBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIGl0IGZhaWxzLgorICAgICAgICAgKiA8bGk+IEJsb2NrIHVudGlsIHNpZ25hbGxlZC4KKyAgICAgICAgICogPGxpPiBSZWFjcXVpcmUgYnkgaW52b2tpbmcgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZgorICAgICAgICAgKiAgICAgIHtAbGluayAjYWNxdWlyZX0gd2l0aCBzYXZlZCBzdGF0ZSBhcyBhcmd1bWVudC4KKyAgICAgICAgICogPC9vbD4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmaW5hbCB2b2lkIGF3YWl0VW5pbnRlcnJ1cHRpYmx5KCkgeworICAgICAgICAgICAgTm9kZSBub2RlID0gYWRkQ29uZGl0aW9uV2FpdGVyKCk7CisgICAgICAgICAgICBsb25nIHNhdmVkU3RhdGUgPSBmdWxseVJlbGVhc2Uobm9kZSk7CisgICAgICAgICAgICBib29sZWFuIGludGVycnVwdGVkID0gZmFsc2U7CisgICAgICAgICAgICB3aGlsZSAoIWlzT25TeW5jUXVldWUobm9kZSkpIHsKKyAgICAgICAgICAgICAgICBMb2NrU3VwcG9ydC5wYXJrKHRoaXMpOworICAgICAgICAgICAgICAgIGlmIChUaHJlYWQuaW50ZXJydXB0ZWQoKSkKKyAgICAgICAgICAgICAgICAgICAgaW50ZXJydXB0ZWQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFjcXVpcmVRdWV1ZWQobm9kZSwgc2F2ZWRTdGF0ZSkgfHwgaW50ZXJydXB0ZWQpCisgICAgICAgICAgICAgICAgc2VsZkludGVycnVwdCgpOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogRm9yIGludGVycnVwdGlibGUgd2FpdHMsIHdlIG5lZWQgdG8gdHJhY2sgd2hldGhlciB0byB0aHJvdworICAgICAgICAgKiBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgaWYgaW50ZXJydXB0ZWQgd2hpbGUgYmxvY2tlZCBvbgorICAgICAgICAgKiBjb25kaXRpb24sIHZlcnN1cyByZWludGVycnVwdCBjdXJyZW50IHRocmVhZCwgaWYKKyAgICAgICAgICogaW50ZXJydXB0ZWQgd2hpbGUgYmxvY2tlZCB3YWl0aW5nIHRvIHJlLWFjcXVpcmUuCisgICAgICAgICAqLworCisgICAgICAgIC8qKiBNb2RlIG1lYW5pbmcgdG8gcmVpbnRlcnJ1cHQgb24gZXhpdCBmcm9tIHdhaXQgKi8KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJFSU5URVJSVVBUID0gIDE7CisgICAgICAgIC8qKiBNb2RlIG1lYW5pbmcgdG8gdGhyb3cgSW50ZXJydXB0ZWRFeGNlcHRpb24gb24gZXhpdCBmcm9tIHdhaXQgKi8KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRIUk9XX0lFICAgID0gLTE7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENoZWNrcyBmb3IgaW50ZXJydXB0LCByZXR1cm5pbmcgVEhST1dfSUUgaWYgaW50ZXJydXB0ZWQKKyAgICAgICAgICogYmVmb3JlIHNpZ25hbGxlZCwgUkVJTlRFUlJVUFQgaWYgYWZ0ZXIgc2lnbmFsbGVkLCBvcgorICAgICAgICAgKiAwIGlmIG5vdCBpbnRlcnJ1cHRlZC4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgaW50IGNoZWNrSW50ZXJydXB0V2hpbGVXYWl0aW5nKE5vZGUgbm9kZSkgeworICAgICAgICAgICAgcmV0dXJuIFRocmVhZC5pbnRlcnJ1cHRlZCgpID8KKyAgICAgICAgICAgICAgICAodHJhbnNmZXJBZnRlckNhbmNlbGxlZFdhaXQobm9kZSkgPyBUSFJPV19JRSA6IFJFSU5URVJSVVBUKSA6CisgICAgICAgICAgICAgICAgMDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24sIHJlaW50ZXJydXB0cyBjdXJyZW50IHRocmVhZCwgb3IKKyAgICAgICAgICogZG9lcyBub3RoaW5nLCBkZXBlbmRpbmcgb24gbW9kZS4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgdm9pZCByZXBvcnRJbnRlcnJ1cHRBZnRlcldhaXQoaW50IGludGVycnVwdE1vZGUpCisgICAgICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKGludGVycnVwdE1vZGUgPT0gVEhST1dfSUUpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBlbHNlIGlmIChpbnRlcnJ1cHRNb2RlID09IFJFSU5URVJSVVBUKQorICAgICAgICAgICAgICAgIHNlbGZJbnRlcnJ1cHQoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbXBsZW1lbnRzIGludGVycnVwdGlibGUgY29uZGl0aW9uIHdhaXQuCisgICAgICAgICAqIDxvbD4KKyAgICAgICAgICogPGxpPiBJZiBjdXJyZW50IHRocmVhZCBpcyBpbnRlcnJ1cHRlZCwgdGhyb3cgSW50ZXJydXB0ZWRFeGNlcHRpb24uCisgICAgICAgICAqIDxsaT4gU2F2ZSBsb2NrIHN0YXRlIHJldHVybmVkIGJ5IHtAbGluayAjZ2V0U3RhdGV9LgorICAgICAgICAgKiA8bGk+IEludm9rZSB7QGxpbmsgI3JlbGVhc2V9IHdpdGgKKyAgICAgICAgICogICAgICBzYXZlZCBzdGF0ZSBhcyBhcmd1bWVudCwgdGhyb3dpbmcKKyAgICAgICAgICogICAgICBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIGl0IGZhaWxzLgorICAgICAgICAgKiA8bGk+IEJsb2NrIHVudGlsIHNpZ25hbGxlZCBvciBpbnRlcnJ1cHRlZC4KKyAgICAgICAgICogPGxpPiBSZWFjcXVpcmUgYnkgaW52b2tpbmcgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZgorICAgICAgICAgKiAgICAgIHtAbGluayAjYWNxdWlyZX0gd2l0aCBzYXZlZCBzdGF0ZSBhcyBhcmd1bWVudC4KKyAgICAgICAgICogPGxpPiBJZiBpbnRlcnJ1cHRlZCB3aGlsZSBibG9ja2VkIGluIHN0ZXAgNCwgdGhyb3cgSW50ZXJydXB0ZWRFeGNlcHRpb24uCisgICAgICAgICAqIDwvb2w+CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmluYWwgdm9pZCBhd2FpdCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoVGhyZWFkLmludGVycnVwdGVkKCkpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBOb2RlIG5vZGUgPSBhZGRDb25kaXRpb25XYWl0ZXIoKTsKKyAgICAgICAgICAgIGxvbmcgc2F2ZWRTdGF0ZSA9IGZ1bGx5UmVsZWFzZShub2RlKTsKKyAgICAgICAgICAgIGludCBpbnRlcnJ1cHRNb2RlID0gMDsKKyAgICAgICAgICAgIHdoaWxlICghaXNPblN5bmNRdWV1ZShub2RlKSkgeworICAgICAgICAgICAgICAgIExvY2tTdXBwb3J0LnBhcmsodGhpcyk7CisgICAgICAgICAgICAgICAgaWYgKChpbnRlcnJ1cHRNb2RlID0gY2hlY2tJbnRlcnJ1cHRXaGlsZVdhaXRpbmcobm9kZSkpICE9IDApCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFjcXVpcmVRdWV1ZWQobm9kZSwgc2F2ZWRTdGF0ZSkgJiYgaW50ZXJydXB0TW9kZSAhPSBUSFJPV19JRSkKKyAgICAgICAgICAgICAgICBpbnRlcnJ1cHRNb2RlID0gUkVJTlRFUlJVUFQ7CisgICAgICAgICAgICBpZiAobm9kZS5uZXh0V2FpdGVyICE9IG51bGwpIC8vIGNsZWFuIHVwIGlmIGNhbmNlbGxlZAorICAgICAgICAgICAgICAgIHVubGlua0NhbmNlbGxlZFdhaXRlcnMoKTsKKyAgICAgICAgICAgIGlmIChpbnRlcnJ1cHRNb2RlICE9IDApCisgICAgICAgICAgICAgICAgcmVwb3J0SW50ZXJydXB0QWZ0ZXJXYWl0KGludGVycnVwdE1vZGUpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEltcGxlbWVudHMgdGltZWQgY29uZGl0aW9uIHdhaXQuCisgICAgICAgICAqIDxvbD4KKyAgICAgICAgICogPGxpPiBJZiBjdXJyZW50IHRocmVhZCBpcyBpbnRlcnJ1cHRlZCwgdGhyb3cgSW50ZXJydXB0ZWRFeGNlcHRpb24uCisgICAgICAgICAqIDxsaT4gU2F2ZSBsb2NrIHN0YXRlIHJldHVybmVkIGJ5IHtAbGluayAjZ2V0U3RhdGV9LgorICAgICAgICAgKiA8bGk+IEludm9rZSB7QGxpbmsgI3JlbGVhc2V9IHdpdGgKKyAgICAgICAgICogICAgICBzYXZlZCBzdGF0ZSBhcyBhcmd1bWVudCwgdGhyb3dpbmcKKyAgICAgICAgICogICAgICBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIGl0IGZhaWxzLgorICAgICAgICAgKiA8bGk+IEJsb2NrIHVudGlsIHNpZ25hbGxlZCwgaW50ZXJydXB0ZWQsIG9yIHRpbWVkIG91dC4KKyAgICAgICAgICogPGxpPiBSZWFjcXVpcmUgYnkgaW52b2tpbmcgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZgorICAgICAgICAgKiAgICAgIHtAbGluayAjYWNxdWlyZX0gd2l0aCBzYXZlZCBzdGF0ZSBhcyBhcmd1bWVudC4KKyAgICAgICAgICogPGxpPiBJZiBpbnRlcnJ1cHRlZCB3aGlsZSBibG9ja2VkIGluIHN0ZXAgNCwgdGhyb3cgSW50ZXJydXB0ZWRFeGNlcHRpb24uCisgICAgICAgICAqIDwvb2w+CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmluYWwgbG9uZyBhd2FpdE5hbm9zKGxvbmcgbmFub3NUaW1lb3V0KQorICAgICAgICAgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoVGhyZWFkLmludGVycnVwdGVkKCkpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBOb2RlIG5vZGUgPSBhZGRDb25kaXRpb25XYWl0ZXIoKTsKKyAgICAgICAgICAgIGxvbmcgc2F2ZWRTdGF0ZSA9IGZ1bGx5UmVsZWFzZShub2RlKTsKKyAgICAgICAgICAgIGxvbmcgbGFzdFRpbWUgPSBTeXN0ZW0ubmFub1RpbWUoKTsKKyAgICAgICAgICAgIGludCBpbnRlcnJ1cHRNb2RlID0gMDsKKyAgICAgICAgICAgIHdoaWxlICghaXNPblN5bmNRdWV1ZShub2RlKSkgeworICAgICAgICAgICAgICAgIGlmIChuYW5vc1RpbWVvdXQgPD0gMEwpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJhbnNmZXJBZnRlckNhbmNlbGxlZFdhaXQobm9kZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBMb2NrU3VwcG9ydC5wYXJrTmFub3ModGhpcywgbmFub3NUaW1lb3V0KTsKKyAgICAgICAgICAgICAgICBpZiAoKGludGVycnVwdE1vZGUgPSBjaGVja0ludGVycnVwdFdoaWxlV2FpdGluZyhub2RlKSkgIT0gMCkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICBsb25nIG5vdyA9IFN5c3RlbS5uYW5vVGltZSgpOworICAgICAgICAgICAgICAgIG5hbm9zVGltZW91dCAtPSBub3cgLSBsYXN0VGltZTsKKyAgICAgICAgICAgICAgICBsYXN0VGltZSA9IG5vdzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhY3F1aXJlUXVldWVkKG5vZGUsIHNhdmVkU3RhdGUpICYmIGludGVycnVwdE1vZGUgIT0gVEhST1dfSUUpCisgICAgICAgICAgICAgICAgaW50ZXJydXB0TW9kZSA9IFJFSU5URVJSVVBUOworICAgICAgICAgICAgaWYgKG5vZGUubmV4dFdhaXRlciAhPSBudWxsKQorICAgICAgICAgICAgICAgIHVubGlua0NhbmNlbGxlZFdhaXRlcnMoKTsKKyAgICAgICAgICAgIGlmIChpbnRlcnJ1cHRNb2RlICE9IDApCisgICAgICAgICAgICAgICAgcmVwb3J0SW50ZXJydXB0QWZ0ZXJXYWl0KGludGVycnVwdE1vZGUpOworICAgICAgICAgICAgcmV0dXJuIG5hbm9zVGltZW91dCAtIChTeXN0ZW0ubmFub1RpbWUoKSAtIGxhc3RUaW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbXBsZW1lbnRzIGFic29sdXRlIHRpbWVkIGNvbmRpdGlvbiB3YWl0LgorICAgICAgICAgKiA8b2w+CisgICAgICAgICAqIDxsaT4gSWYgY3VycmVudCB0aHJlYWQgaXMgaW50ZXJydXB0ZWQsIHRocm93IEludGVycnVwdGVkRXhjZXB0aW9uLgorICAgICAgICAgKiA8bGk+IFNhdmUgbG9jayBzdGF0ZSByZXR1cm5lZCBieSB7QGxpbmsgI2dldFN0YXRlfS4KKyAgICAgICAgICogPGxpPiBJbnZva2Uge0BsaW5rICNyZWxlYXNlfSB3aXRoCisgICAgICAgICAqICAgICAgc2F2ZWQgc3RhdGUgYXMgYXJndW1lbnQsIHRocm93aW5nCisgICAgICAgICAqICAgICAgSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbiBpZiBpdCBmYWlscy4KKyAgICAgICAgICogPGxpPiBCbG9jayB1bnRpbCBzaWduYWxsZWQsIGludGVycnVwdGVkLCBvciB0aW1lZCBvdXQuCisgICAgICAgICAqIDxsaT4gUmVhY3F1aXJlIGJ5IGludm9raW5nIHNwZWNpYWxpemVkIHZlcnNpb24gb2YKKyAgICAgICAgICogICAgICB7QGxpbmsgI2FjcXVpcmV9IHdpdGggc2F2ZWQgc3RhdGUgYXMgYXJndW1lbnQuCisgICAgICAgICAqIDxsaT4gSWYgaW50ZXJydXB0ZWQgd2hpbGUgYmxvY2tlZCBpbiBzdGVwIDQsIHRocm93IEludGVycnVwdGVkRXhjZXB0aW9uLgorICAgICAgICAgKiA8bGk+IElmIHRpbWVkIG91dCB3aGlsZSBibG9ja2VkIGluIHN0ZXAgNCwgcmV0dXJuIGZhbHNlLCBlbHNlIHRydWUuCisgICAgICAgICAqIDwvb2w+CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBhd2FpdFVudGlsKERhdGUgZGVhZGxpbmUpCisgICAgICAgICAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChkZWFkbGluZSA9PSBudWxsKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgbG9uZyBhYnN0aW1lID0gZGVhZGxpbmUuZ2V0VGltZSgpOworICAgICAgICAgICAgaWYgKFRocmVhZC5pbnRlcnJ1cHRlZCgpKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbigpOworICAgICAgICAgICAgTm9kZSBub2RlID0gYWRkQ29uZGl0aW9uV2FpdGVyKCk7CisgICAgICAgICAgICBsb25nIHNhdmVkU3RhdGUgPSBmdWxseVJlbGVhc2Uobm9kZSk7CisgICAgICAgICAgICBib29sZWFuIHRpbWVkb3V0ID0gZmFsc2U7CisgICAgICAgICAgICBpbnQgaW50ZXJydXB0TW9kZSA9IDA7CisgICAgICAgICAgICB3aGlsZSAoIWlzT25TeW5jUXVldWUobm9kZSkpIHsKKyAgICAgICAgICAgICAgICBpZiAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgPiBhYnN0aW1lKSB7CisgICAgICAgICAgICAgICAgICAgIHRpbWVkb3V0ID0gdHJhbnNmZXJBZnRlckNhbmNlbGxlZFdhaXQobm9kZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBMb2NrU3VwcG9ydC5wYXJrVW50aWwodGhpcywgYWJzdGltZSk7CisgICAgICAgICAgICAgICAgaWYgKChpbnRlcnJ1cHRNb2RlID0gY2hlY2tJbnRlcnJ1cHRXaGlsZVdhaXRpbmcobm9kZSkpICE9IDApCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFjcXVpcmVRdWV1ZWQobm9kZSwgc2F2ZWRTdGF0ZSkgJiYgaW50ZXJydXB0TW9kZSAhPSBUSFJPV19JRSkKKyAgICAgICAgICAgICAgICBpbnRlcnJ1cHRNb2RlID0gUkVJTlRFUlJVUFQ7CisgICAgICAgICAgICBpZiAobm9kZS5uZXh0V2FpdGVyICE9IG51bGwpCisgICAgICAgICAgICAgICAgdW5saW5rQ2FuY2VsbGVkV2FpdGVycygpOworICAgICAgICAgICAgaWYgKGludGVycnVwdE1vZGUgIT0gMCkKKyAgICAgICAgICAgICAgICByZXBvcnRJbnRlcnJ1cHRBZnRlcldhaXQoaW50ZXJydXB0TW9kZSk7CisgICAgICAgICAgICByZXR1cm4gIXRpbWVkb3V0OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEltcGxlbWVudHMgdGltZWQgY29uZGl0aW9uIHdhaXQuCisgICAgICAgICAqIDxvbD4KKyAgICAgICAgICogPGxpPiBJZiBjdXJyZW50IHRocmVhZCBpcyBpbnRlcnJ1cHRlZCwgdGhyb3cgSW50ZXJydXB0ZWRFeGNlcHRpb24uCisgICAgICAgICAqIDxsaT4gU2F2ZSBsb2NrIHN0YXRlIHJldHVybmVkIGJ5IHtAbGluayAjZ2V0U3RhdGV9LgorICAgICAgICAgKiA8bGk+IEludm9rZSB7QGxpbmsgI3JlbGVhc2V9IHdpdGgKKyAgICAgICAgICogICAgICBzYXZlZCBzdGF0ZSBhcyBhcmd1bWVudCwgdGhyb3dpbmcKKyAgICAgICAgICogICAgICBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIGl0IGZhaWxzLgorICAgICAgICAgKiA8bGk+IEJsb2NrIHVudGlsIHNpZ25hbGxlZCwgaW50ZXJydXB0ZWQsIG9yIHRpbWVkIG91dC4KKyAgICAgICAgICogPGxpPiBSZWFjcXVpcmUgYnkgaW52b2tpbmcgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZgorICAgICAgICAgKiAgICAgIHtAbGluayAjYWNxdWlyZX0gd2l0aCBzYXZlZCBzdGF0ZSBhcyBhcmd1bWVudC4KKyAgICAgICAgICogPGxpPiBJZiBpbnRlcnJ1cHRlZCB3aGlsZSBibG9ja2VkIGluIHN0ZXAgNCwgdGhyb3cgSW50ZXJydXB0ZWRFeGNlcHRpb24uCisgICAgICAgICAqIDxsaT4gSWYgdGltZWQgb3V0IHdoaWxlIGJsb2NrZWQgaW4gc3RlcCA0LCByZXR1cm4gZmFsc2UsIGVsc2UgdHJ1ZS4KKyAgICAgICAgICogPC9vbD4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGF3YWl0KGxvbmcgdGltZSwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKHVuaXQgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGxvbmcgbmFub3NUaW1lb3V0ID0gdW5pdC50b05hbm9zKHRpbWUpOworICAgICAgICAgICAgaWYgKFRocmVhZC5pbnRlcnJ1cHRlZCgpKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbigpOworICAgICAgICAgICAgTm9kZSBub2RlID0gYWRkQ29uZGl0aW9uV2FpdGVyKCk7CisgICAgICAgICAgICBsb25nIHNhdmVkU3RhdGUgPSBmdWxseVJlbGVhc2Uobm9kZSk7CisgICAgICAgICAgICBsb25nIGxhc3RUaW1lID0gU3lzdGVtLm5hbm9UaW1lKCk7CisgICAgICAgICAgICBib29sZWFuIHRpbWVkb3V0ID0gZmFsc2U7CisgICAgICAgICAgICBpbnQgaW50ZXJydXB0TW9kZSA9IDA7CisgICAgICAgICAgICB3aGlsZSAoIWlzT25TeW5jUXVldWUobm9kZSkpIHsKKyAgICAgICAgICAgICAgICBpZiAobmFub3NUaW1lb3V0IDw9IDBMKSB7CisgICAgICAgICAgICAgICAgICAgIHRpbWVkb3V0ID0gdHJhbnNmZXJBZnRlckNhbmNlbGxlZFdhaXQobm9kZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAobmFub3NUaW1lb3V0ID49IHNwaW5Gb3JUaW1lb3V0VGhyZXNob2xkKQorICAgICAgICAgICAgICAgICAgICBMb2NrU3VwcG9ydC5wYXJrTmFub3ModGhpcywgbmFub3NUaW1lb3V0KTsKKyAgICAgICAgICAgICAgICBpZiAoKGludGVycnVwdE1vZGUgPSBjaGVja0ludGVycnVwdFdoaWxlV2FpdGluZyhub2RlKSkgIT0gMCkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgbG9uZyBub3cgPSBTeXN0ZW0ubmFub1RpbWUoKTsKKyAgICAgICAgICAgICAgICBuYW5vc1RpbWVvdXQgLT0gbm93IC0gbGFzdFRpbWU7CisgICAgICAgICAgICAgICAgbGFzdFRpbWUgPSBub3c7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYWNxdWlyZVF1ZXVlZChub2RlLCBzYXZlZFN0YXRlKSAmJiBpbnRlcnJ1cHRNb2RlICE9IFRIUk9XX0lFKQorICAgICAgICAgICAgICAgIGludGVycnVwdE1vZGUgPSBSRUlOVEVSUlVQVDsKKyAgICAgICAgICAgIGlmIChub2RlLm5leHRXYWl0ZXIgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICB1bmxpbmtDYW5jZWxsZWRXYWl0ZXJzKCk7CisgICAgICAgICAgICBpZiAoaW50ZXJydXB0TW9kZSAhPSAwKQorICAgICAgICAgICAgICAgIHJlcG9ydEludGVycnVwdEFmdGVyV2FpdChpbnRlcnJ1cHRNb2RlKTsKKyAgICAgICAgICAgIHJldHVybiAhdGltZWRvdXQ7CisgICAgICAgIH0KKworICAgICAgICAvLyAgc3VwcG9ydCBmb3IgaW5zdHJ1bWVudGF0aW9uCisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGNvbmRpdGlvbiB3YXMgY3JlYXRlZCBieSB0aGUgZ2l2ZW4KKyAgICAgICAgICogc3luY2hyb25pemF0aW9uIG9iamVjdC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgb3duZWQKKyAgICAgICAgICovCisgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNPd25lZEJ5KEFic3RyYWN0UXVldWVkTG9uZ1N5bmNocm9uaXplciBzeW5jKSB7CisgICAgICAgICAgICByZXR1cm4gc3luYyA9PSBBYnN0cmFjdFF1ZXVlZExvbmdTeW5jaHJvbml6ZXIudGhpczsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBRdWVyaWVzIHdoZXRoZXIgYW55IHRocmVhZHMgYXJlIHdhaXRpbmcgb24gdGhpcyBjb25kaXRpb24uCisgICAgICAgICAqIEltcGxlbWVudHMge0BsaW5rIEFic3RyYWN0UXVldWVkTG9uZ1N5bmNocm9uaXplciNoYXNXYWl0ZXJzfS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlcmUgYXJlIGFueSB3YWl0aW5nIHRocmVhZHMKKyAgICAgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIHtAbGluayAjaXNIZWxkRXhjbHVzaXZlbHl9CisgICAgICAgICAqICAgICAgICAgcmV0dXJucyB7QGNvZGUgZmFsc2V9CisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiBoYXNXYWl0ZXJzKCkgeworICAgICAgICAgICAgaWYgKCFpc0hlbGRFeGNsdXNpdmVseSgpKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBmb3IgKE5vZGUgdyA9IGZpcnN0V2FpdGVyOyB3ICE9IG51bGw7IHcgPSB3Lm5leHRXYWl0ZXIpIHsKKyAgICAgICAgICAgICAgICBpZiAody53YWl0U3RhdHVzID09IE5vZGUuQ09ORElUSU9OKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGFuIGVzdGltYXRlIG9mIHRoZSBudW1iZXIgb2YgdGhyZWFkcyB3YWl0aW5nIG9uCisgICAgICAgICAqIHRoaXMgY29uZGl0aW9uLgorICAgICAgICAgKiBJbXBsZW1lbnRzIHtAbGluayBBYnN0cmFjdFF1ZXVlZExvbmdTeW5jaHJvbml6ZXIjZ2V0V2FpdFF1ZXVlTGVuZ3RofS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUgZXN0aW1hdGVkIG51bWJlciBvZiB3YWl0aW5nIHRocmVhZHMKKyAgICAgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIHtAbGluayAjaXNIZWxkRXhjbHVzaXZlbHl9CisgICAgICAgICAqICAgICAgICAgcmV0dXJucyB7QGNvZGUgZmFsc2V9CisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgZmluYWwgaW50IGdldFdhaXRRdWV1ZUxlbmd0aCgpIHsKKyAgICAgICAgICAgIGlmICghaXNIZWxkRXhjbHVzaXZlbHkoKSkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgaW50IG4gPSAwOworICAgICAgICAgICAgZm9yIChOb2RlIHcgPSBmaXJzdFdhaXRlcjsgdyAhPSBudWxsOyB3ID0gdy5uZXh0V2FpdGVyKSB7CisgICAgICAgICAgICAgICAgaWYgKHcud2FpdFN0YXR1cyA9PSBOb2RlLkNPTkRJVElPTikKKyAgICAgICAgICAgICAgICAgICAgKytuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG47CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyBhIGNvbGxlY3Rpb24gY29udGFpbmluZyB0aG9zZSB0aHJlYWRzIHRoYXQgbWF5IGJlCisgICAgICAgICAqIHdhaXRpbmcgb24gdGhpcyBDb25kaXRpb24uCisgICAgICAgICAqIEltcGxlbWVudHMge0BsaW5rIEFic3RyYWN0UXVldWVkTG9uZ1N5bmNocm9uaXplciNnZXRXYWl0aW5nVGhyZWFkc30uCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gdGhlIGNvbGxlY3Rpb24gb2YgdGhyZWFkcworICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gaWYge0BsaW5rICNpc0hlbGRFeGNsdXNpdmVseX0KKyAgICAgICAgICogICAgICAgICByZXR1cm5zIHtAY29kZSBmYWxzZX0KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBmaW5hbCBDb2xsZWN0aW9uPFRocmVhZD4gZ2V0V2FpdGluZ1RocmVhZHMoKSB7CisgICAgICAgICAgICBpZiAoIWlzSGVsZEV4Y2x1c2l2ZWx5KCkpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIEFycmF5TGlzdDxUaHJlYWQ+IGxpc3QgPSBuZXcgQXJyYXlMaXN0PFRocmVhZD4oKTsKKyAgICAgICAgICAgIGZvciAoTm9kZSB3ID0gZmlyc3RXYWl0ZXI7IHcgIT0gbnVsbDsgdyA9IHcubmV4dFdhaXRlcikgeworICAgICAgICAgICAgICAgIGlmICh3LndhaXRTdGF0dXMgPT0gTm9kZS5DT05ESVRJT04pIHsKKyAgICAgICAgICAgICAgICAgICAgVGhyZWFkIHQgPSB3LnRocmVhZDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QuYWRkKHQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBsaXN0OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0dXAgdG8gc3VwcG9ydCBjb21wYXJlQW5kU2V0LiBXZSBuZWVkIHRvIG5hdGl2ZWx5IGltcGxlbWVudAorICAgICAqIHRoaXMgaGVyZTogRm9yIHRoZSBzYWtlIG9mIHBlcm1pdHRpbmcgZnV0dXJlIGVuaGFuY2VtZW50cywgd2UKKyAgICAgKiBjYW5ub3QgZXhwbGljaXRseSBzdWJjbGFzcyBBdG9taWNMb25nLCB3aGljaCB3b3VsZCBiZQorICAgICAqIGVmZmljaWVudCBhbmQgdXNlZnVsIG90aGVyd2lzZS4gU28sIGFzIHRoZSBsZXNzZXIgb2YgZXZpbHMsIHdlCisgICAgICogbmF0aXZlbHkgaW1wbGVtZW50IHVzaW5nIGhvdHNwb3QgaW50cmluc2ljcyBBUEkuIEFuZCB3aGlsZSB3ZQorICAgICAqIGFyZSBhdCBpdCwgd2UgZG8gdGhlIHNhbWUgZm9yIG90aGVyIENBU2FibGUgZmllbGRzICh3aGljaCBjb3VsZAorICAgICAqIG90aGVyd2lzZSBiZSBkb25lIHdpdGggYXRvbWljIGZpZWxkIHVwZGF0ZXJzKS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBVbnNhZmUgdW5zYWZlID0gVW5zYWZlLmdldFVuc2FmZSgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc3RhdGVPZmZzZXQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBoZWFkT2Zmc2V0OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgdGFpbE9mZnNldDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHdhaXRTdGF0dXNPZmZzZXQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBuZXh0T2Zmc2V0OworCisgICAgc3RhdGljIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0YXRlT2Zmc2V0ID0gdW5zYWZlLm9iamVjdEZpZWxkT2Zmc2V0CisgICAgICAgICAgICAgICAgKEFic3RyYWN0UXVldWVkTG9uZ1N5bmNocm9uaXplci5jbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJzdGF0ZSIpKTsKKyAgICAgICAgICAgIGhlYWRPZmZzZXQgPSB1bnNhZmUub2JqZWN0RmllbGRPZmZzZXQKKyAgICAgICAgICAgICAgICAoQWJzdHJhY3RRdWV1ZWRMb25nU3luY2hyb25pemVyLmNsYXNzLmdldERlY2xhcmVkRmllbGQoImhlYWQiKSk7CisgICAgICAgICAgICB0YWlsT2Zmc2V0ID0gdW5zYWZlLm9iamVjdEZpZWxkT2Zmc2V0CisgICAgICAgICAgICAgICAgKEFic3RyYWN0UXVldWVkTG9uZ1N5bmNocm9uaXplci5jbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJ0YWlsIikpOworICAgICAgICAgICAgd2FpdFN0YXR1c09mZnNldCA9IHVuc2FmZS5vYmplY3RGaWVsZE9mZnNldAorICAgICAgICAgICAgICAgIChOb2RlLmNsYXNzLmdldERlY2xhcmVkRmllbGQoIndhaXRTdGF0dXMiKSk7CisgICAgICAgICAgICBuZXh0T2Zmc2V0ID0gdW5zYWZlLm9iamVjdEZpZWxkT2Zmc2V0CisgICAgICAgICAgICAgICAgKE5vZGUuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgibmV4dCIpKTsKKworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsgdGhyb3cgbmV3IEVycm9yKGV4KTsgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENBUyBoZWFkIGZpZWxkLiBVc2VkIG9ubHkgYnkgZW5xLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBjb21wYXJlQW5kU2V0SGVhZChOb2RlIHVwZGF0ZSkgeworICAgICAgICByZXR1cm4gdW5zYWZlLmNvbXBhcmVBbmRTd2FwT2JqZWN0KHRoaXMsIGhlYWRPZmZzZXQsIG51bGwsIHVwZGF0ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ0FTIHRhaWwgZmllbGQuIFVzZWQgb25seSBieSBlbnEuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGNvbXBhcmVBbmRTZXRUYWlsKE5vZGUgZXhwZWN0LCBOb2RlIHVwZGF0ZSkgeworICAgICAgICByZXR1cm4gdW5zYWZlLmNvbXBhcmVBbmRTd2FwT2JqZWN0KHRoaXMsIHRhaWxPZmZzZXQsIGV4cGVjdCwgdXBkYXRlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDQVMgd2FpdFN0YXR1cyBmaWVsZCBvZiBhIG5vZGUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBjb21wYXJlQW5kU2V0V2FpdFN0YXR1cyhOb2RlIG5vZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZXhwZWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHVwZGF0ZSkgeworICAgICAgICByZXR1cm4gdW5zYWZlLmNvbXBhcmVBbmRTd2FwSW50KG5vZGUsIHdhaXRTdGF0dXNPZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0LCB1cGRhdGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENBUyBuZXh0IGZpZWxkIG9mIGEgbm9kZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGNvbXBhcmVBbmRTZXROZXh0KE5vZGUgbm9kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgZXhwZWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSB1cGRhdGUpIHsKKyAgICAgICAgcmV0dXJuIHVuc2FmZS5jb21wYXJlQW5kU3dhcE9iamVjdChub2RlLCBuZXh0T2Zmc2V0LCBleHBlY3QsIHVwZGF0ZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL0Fic3RyYWN0UXVldWVkU3luY2hyb25pemVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvbG9ja3MvQWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNjVmMTMwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL0Fic3RyYWN0UXVldWVkU3luY2hyb25pemVyLmphdmEKQEAgLTAsMCArMSwyMzExIEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3M7CitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuKjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuKjsKK2ltcG9ydCBzdW4ubWlzYy5VbnNhZmU7CisKKy8vIEJFR0lOIGFuZHJvaWQtbm90ZQorLy8gVXNlIG9sZGVyIGNsYXNzIGxldmVsIGRvY3VtZW50YXRpb24gdG8gbm90IEBsaW5rIHRvIGhhc1F1ZXVlZFByZWRlY2Vzc29ycworLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorCisvKioKKyAqIFByb3ZpZGVzIGEgZnJhbWV3b3JrIGZvciBpbXBsZW1lbnRpbmcgYmxvY2tpbmcgbG9ja3MgYW5kIHJlbGF0ZWQKKyAqIHN5bmNocm9uaXplcnMgKHNlbWFwaG9yZXMsIGV2ZW50cywgZXRjKSB0aGF0IHJlbHkgb24KKyAqIGZpcnN0LWluLWZpcnN0LW91dCAoRklGTykgd2FpdCBxdWV1ZXMuICBUaGlzIGNsYXNzIGlzIGRlc2lnbmVkIHRvCisgKiBiZSBhIHVzZWZ1bCBiYXNpcyBmb3IgbW9zdCBraW5kcyBvZiBzeW5jaHJvbml6ZXJzIHRoYXQgcmVseSBvbiBhCisgKiBzaW5nbGUgYXRvbWljIDx0dD5pbnQ8L3R0PiB2YWx1ZSB0byByZXByZXNlbnQgc3RhdGUuIFN1YmNsYXNzZXMKKyAqIG11c3QgZGVmaW5lIHRoZSBwcm90ZWN0ZWQgbWV0aG9kcyB0aGF0IGNoYW5nZSB0aGlzIHN0YXRlLCBhbmQgd2hpY2gKKyAqIGRlZmluZSB3aGF0IHRoYXQgc3RhdGUgbWVhbnMgaW4gdGVybXMgb2YgdGhpcyBvYmplY3QgYmVpbmcgYWNxdWlyZWQKKyAqIG9yIHJlbGVhc2VkLiAgR2l2ZW4gdGhlc2UsIHRoZSBvdGhlciBtZXRob2RzIGluIHRoaXMgY2xhc3MgY2FycnkKKyAqIG91dCBhbGwgcXVldWluZyBhbmQgYmxvY2tpbmcgbWVjaGFuaWNzLiBTdWJjbGFzc2VzIGNhbiBtYWludGFpbgorICogb3RoZXIgc3RhdGUgZmllbGRzLCBidXQgb25seSB0aGUgYXRvbWljYWxseSB1cGRhdGVkIDx0dD5pbnQ8L3R0PgorICogdmFsdWUgbWFuaXB1bGF0ZWQgdXNpbmcgbWV0aG9kcyB7QGxpbmsgI2dldFN0YXRlfSwge0BsaW5rCisgKiAjc2V0U3RhdGV9IGFuZCB7QGxpbmsgI2NvbXBhcmVBbmRTZXRTdGF0ZX0gaXMgdHJhY2tlZCB3aXRoIHJlc3BlY3QKKyAqIHRvIHN5bmNocm9uaXphdGlvbi4KKyAqCisgKiA8cD5TdWJjbGFzc2VzIHNob3VsZCBiZSBkZWZpbmVkIGFzIG5vbi1wdWJsaWMgaW50ZXJuYWwgaGVscGVyCisgKiBjbGFzc2VzIHRoYXQgYXJlIHVzZWQgdG8gaW1wbGVtZW50IHRoZSBzeW5jaHJvbml6YXRpb24gcHJvcGVydGllcworICogb2YgdGhlaXIgZW5jbG9zaW5nIGNsYXNzLiAgQ2xhc3MKKyAqIDx0dD5BYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplcjwvdHQ+IGRvZXMgbm90IGltcGxlbWVudCBhbnkKKyAqIHN5bmNocm9uaXphdGlvbiBpbnRlcmZhY2UuICBJbnN0ZWFkIGl0IGRlZmluZXMgbWV0aG9kcyBzdWNoIGFzCisgKiB7QGxpbmsgI2FjcXVpcmVJbnRlcnJ1cHRpYmx5fSB0aGF0IGNhbiBiZSBpbnZva2VkIGFzCisgKiBhcHByb3ByaWF0ZSBieSBjb25jcmV0ZSBsb2NrcyBhbmQgcmVsYXRlZCBzeW5jaHJvbml6ZXJzIHRvCisgKiBpbXBsZW1lbnQgdGhlaXIgcHVibGljIG1ldGhvZHMuCisgKgorICogPHA+VGhpcyBjbGFzcyBzdXBwb3J0cyBlaXRoZXIgb3IgYm90aCBhIGRlZmF1bHQgPGVtPmV4Y2x1c2l2ZTwvZW0+CisgKiBtb2RlIGFuZCBhIDxlbT5zaGFyZWQ8L2VtPiBtb2RlLiBXaGVuIGFjcXVpcmVkIGluIGV4Y2x1c2l2ZSBtb2RlLAorICogYXR0ZW1wdGVkIGFjcXVpcmVzIGJ5IG90aGVyIHRocmVhZHMgY2Fubm90IHN1Y2NlZWQuIFNoYXJlZCBtb2RlCisgKiBhY3F1aXJlcyBieSBtdWx0aXBsZSB0aHJlYWRzIG1heSAoYnV0IG5lZWQgbm90KSBzdWNjZWVkLiBUaGlzIGNsYXNzCisgKiBkb2VzIG5vdCAmcXVvdDt1bmRlcnN0YW5kJnF1b3Q7IHRoZXNlIGRpZmZlcmVuY2VzIGV4Y2VwdCBpbiB0aGUKKyAqIG1lY2hhbmljYWwgc2Vuc2UgdGhhdCB3aGVuIGEgc2hhcmVkIG1vZGUgYWNxdWlyZSBzdWNjZWVkcywgdGhlIG5leHQKKyAqIHdhaXRpbmcgdGhyZWFkIChpZiBvbmUgZXhpc3RzKSBtdXN0IGFsc28gZGV0ZXJtaW5lIHdoZXRoZXIgaXQgY2FuCisgKiBhY3F1aXJlIGFzIHdlbGwuIFRocmVhZHMgd2FpdGluZyBpbiB0aGUgZGlmZmVyZW50IG1vZGVzIHNoYXJlIHRoZQorICogc2FtZSBGSUZPIHF1ZXVlLiBVc3VhbGx5LCBpbXBsZW1lbnRhdGlvbiBzdWJjbGFzc2VzIHN1cHBvcnQgb25seQorICogb25lIG9mIHRoZXNlIG1vZGVzLCBidXQgYm90aCBjYW4gY29tZSBpbnRvIHBsYXkgZm9yIGV4YW1wbGUgaW4gYQorICoge0BsaW5rIFJlYWRXcml0ZUxvY2t9LiBTdWJjbGFzc2VzIHRoYXQgc3VwcG9ydCBvbmx5IGV4Y2x1c2l2ZSBvcgorICogb25seSBzaGFyZWQgbW9kZXMgbmVlZCBub3QgZGVmaW5lIHRoZSBtZXRob2RzIHN1cHBvcnRpbmcgdGhlIHVudXNlZCBtb2RlLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgZGVmaW5lcyBhIG5lc3RlZCB7QGxpbmsgQ29uZGl0aW9uT2JqZWN0fSBjbGFzcyB0aGF0CisgKiBjYW4gYmUgdXNlZCBhcyBhIHtAbGluayBDb25kaXRpb259IGltcGxlbWVudGF0aW9uIGJ5IHN1YmNsYXNzZXMKKyAqIHN1cHBvcnRpbmcgZXhjbHVzaXZlIG1vZGUgZm9yIHdoaWNoIG1ldGhvZCB7QGxpbmsKKyAqICNpc0hlbGRFeGNsdXNpdmVseX0gcmVwb3J0cyB3aGV0aGVyIHN5bmNocm9uaXphdGlvbiBpcyBleGNsdXNpdmVseQorICogaGVsZCB3aXRoIHJlc3BlY3QgdG8gdGhlIGN1cnJlbnQgdGhyZWFkLCBtZXRob2Qge0BsaW5rICNyZWxlYXNlfQorICogaW52b2tlZCB3aXRoIHRoZSBjdXJyZW50IHtAbGluayAjZ2V0U3RhdGV9IHZhbHVlIGZ1bGx5IHJlbGVhc2VzCisgKiB0aGlzIG9iamVjdCwgYW5kIHtAbGluayAjYWNxdWlyZX0sIGdpdmVuIHRoaXMgc2F2ZWQgc3RhdGUgdmFsdWUsCisgKiBldmVudHVhbGx5IHJlc3RvcmVzIHRoaXMgb2JqZWN0IHRvIGl0cyBwcmV2aW91cyBhY3F1aXJlZCBzdGF0ZS4gIE5vCisgKiA8dHQ+QWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXI8L3R0PiBtZXRob2Qgb3RoZXJ3aXNlIGNyZWF0ZXMgc3VjaCBhCisgKiBjb25kaXRpb24sIHNvIGlmIHRoaXMgY29uc3RyYWludCBjYW5ub3QgYmUgbWV0LCBkbyBub3QgdXNlIGl0LiAgVGhlCisgKiBiZWhhdmlvciBvZiB7QGxpbmsgQ29uZGl0aW9uT2JqZWN0fSBkZXBlbmRzIG9mIGNvdXJzZSBvbiB0aGUKKyAqIHNlbWFudGljcyBvZiBpdHMgc3luY2hyb25pemVyIGltcGxlbWVudGF0aW9uLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgcHJvdmlkZXMgaW5zcGVjdGlvbiwgaW5zdHJ1bWVudGF0aW9uLCBhbmQgbW9uaXRvcmluZworICogbWV0aG9kcyBmb3IgdGhlIGludGVybmFsIHF1ZXVlLCBhcyB3ZWxsIGFzIHNpbWlsYXIgbWV0aG9kcyBmb3IKKyAqIGNvbmRpdGlvbiBvYmplY3RzLiBUaGVzZSBjYW4gYmUgZXhwb3J0ZWQgYXMgZGVzaXJlZCBpbnRvIGNsYXNzZXMKKyAqIHVzaW5nIGFuIDx0dD5BYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplcjwvdHQ+IGZvciB0aGVpcgorICogc3luY2hyb25pemF0aW9uIG1lY2hhbmljcy4KKyAqCisgKiA8cD5TZXJpYWxpemF0aW9uIG9mIHRoaXMgY2xhc3Mgc3RvcmVzIG9ubHkgdGhlIHVuZGVybHlpbmcgYXRvbWljCisgKiBpbnRlZ2VyIG1haW50YWluaW5nIHN0YXRlLCBzbyBkZXNlcmlhbGl6ZWQgb2JqZWN0cyBoYXZlIGVtcHR5CisgKiB0aHJlYWQgcXVldWVzLiBUeXBpY2FsIHN1YmNsYXNzZXMgcmVxdWlyaW5nIHNlcmlhbGl6YWJpbGl0eSB3aWxsCisgKiBkZWZpbmUgYSA8dHQ+cmVhZE9iamVjdDwvdHQ+IG1ldGhvZCB0aGF0IHJlc3RvcmVzIHRoaXMgdG8gYSBrbm93bgorICogaW5pdGlhbCBzdGF0ZSB1cG9uIGRlc2VyaWFsaXphdGlvbi4KKyAqCisgKiA8aDM+VXNhZ2U8L2gzPgorICoKKyAqIDxwPlRvIHVzZSB0aGlzIGNsYXNzIGFzIHRoZSBiYXNpcyBvZiBhIHN5bmNocm9uaXplciwgcmVkZWZpbmUgdGhlCisgKiBmb2xsb3dpbmcgbWV0aG9kcywgYXMgYXBwbGljYWJsZSwgYnkgaW5zcGVjdGluZyBhbmQvb3IgbW9kaWZ5aW5nCisgKiB0aGUgc3luY2hyb25pemF0aW9uIHN0YXRlIHVzaW5nIHtAbGluayAjZ2V0U3RhdGV9LCB7QGxpbmsKKyAqICNzZXRTdGF0ZX0gYW5kL29yIHtAbGluayAjY29tcGFyZUFuZFNldFN0YXRlfToKKyAqCisgKiA8dWw+CisgKiA8bGk+IHtAbGluayAjdHJ5QWNxdWlyZX0KKyAqIDxsaT4ge0BsaW5rICN0cnlSZWxlYXNlfQorICogPGxpPiB7QGxpbmsgI3RyeUFjcXVpcmVTaGFyZWR9CisgKiA8bGk+IHtAbGluayAjdHJ5UmVsZWFzZVNoYXJlZH0KKyAqIDxsaT4ge0BsaW5rICNpc0hlbGRFeGNsdXNpdmVseX0KKyAqPC91bD4KKyAqCisgKiBFYWNoIG9mIHRoZXNlIG1ldGhvZHMgYnkgZGVmYXVsdCB0aHJvd3Mge0BsaW5rCisgKiBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0uICBJbXBsZW1lbnRhdGlvbnMgb2YgdGhlc2UgbWV0aG9kcworICogbXVzdCBiZSBpbnRlcm5hbGx5IHRocmVhZC1zYWZlLCBhbmQgc2hvdWxkIGluIGdlbmVyYWwgYmUgc2hvcnQgYW5kCisgKiBub3QgYmxvY2suIERlZmluaW5nIHRoZXNlIG1ldGhvZHMgaXMgdGhlIDxlbT5vbmx5PC9lbT4gc3VwcG9ydGVkCisgKiBtZWFucyBvZiB1c2luZyB0aGlzIGNsYXNzLiBBbGwgb3RoZXIgbWV0aG9kcyBhcmUgZGVjbGFyZWQKKyAqIDx0dD5maW5hbDwvdHQ+IGJlY2F1c2UgdGhleSBjYW5ub3QgYmUgaW5kZXBlbmRlbnRseSB2YXJpZWQuCisgKgorICogPHA+WW91IG1heSBhbHNvIGZpbmQgdGhlIGluaGVyaXRlZCBtZXRob2RzIGZyb20ge0BsaW5rCisgKiBBYnN0cmFjdE93bmFibGVTeW5jaHJvbml6ZXJ9IHVzZWZ1bCB0byBrZWVwIHRyYWNrIG9mIHRoZSB0aHJlYWQKKyAqIG93bmluZyBhbiBleGNsdXNpdmUgc3luY2hyb25pemVyLiAgWW91IGFyZSBlbmNvdXJhZ2VkIHRvIHVzZSB0aGVtCisgKiAtLSB0aGlzIGVuYWJsZXMgbW9uaXRvcmluZyBhbmQgZGlhZ25vc3RpYyB0b29scyB0byBhc3Npc3QgdXNlcnMgaW4KKyAqIGRldGVybWluaW5nIHdoaWNoIHRocmVhZHMgaG9sZCBsb2Nrcy4KKyAqCisgKiA8cD5FdmVuIHRob3VnaCB0aGlzIGNsYXNzIGlzIGJhc2VkIG9uIGFuIGludGVybmFsIEZJRk8gcXVldWUsIGl0CisgKiBkb2VzIG5vdCBhdXRvbWF0aWNhbGx5IGVuZm9yY2UgRklGTyBhY3F1aXNpdGlvbiBwb2xpY2llcy4gIFRoZSBjb3JlCisgKiBvZiBleGNsdXNpdmUgc3luY2hyb25pemF0aW9uIHRha2VzIHRoZSBmb3JtOgorICoKKyAqIDxwcmU+CisgKiBBY3F1aXJlOgorICogICAgIHdoaWxlICghdHJ5QWNxdWlyZShhcmcpKSB7CisgKiAgICAgICAgPGVtPmVucXVldWUgdGhyZWFkIGlmIGl0IGlzIG5vdCBhbHJlYWR5IHF1ZXVlZDwvZW0+OworICogICAgICAgIDxlbT5wb3NzaWJseSBibG9jayBjdXJyZW50IHRocmVhZDwvZW0+OworICogICAgIH0KKyAqCisgKiBSZWxlYXNlOgorICogICAgIGlmICh0cnlSZWxlYXNlKGFyZykpCisgKiAgICAgICAgPGVtPnVuYmxvY2sgdGhlIGZpcnN0IHF1ZXVlZCB0aHJlYWQ8L2VtPjsKKyAqIDwvcHJlPgorICoKKyAqIChTaGFyZWQgbW9kZSBpcyBzaW1pbGFyIGJ1dCBtYXkgaW52b2x2ZSBjYXNjYWRpbmcgc2lnbmFscy4pCisgKgorICogPHA+PGEgbmFtZT0iYmFyZ2luZyI+QmVjYXVzZSBjaGVja3MgaW4gYWNxdWlyZSBhcmUgaW52b2tlZCBiZWZvcmUKKyAqIGVucXVldWluZywgYSBuZXdseSBhY3F1aXJpbmcgdGhyZWFkIG1heSA8ZW0+YmFyZ2U8L2VtPiBhaGVhZCBvZgorICogb3RoZXJzIHRoYXQgYXJlIGJsb2NrZWQgYW5kIHF1ZXVlZC4gSG93ZXZlciwgeW91IGNhbiwgaWYgZGVzaXJlZCwKKyAqIGRlZmluZSA8dHQ+dHJ5QWNxdWlyZTwvdHQ+IGFuZC9vciA8dHQ+dHJ5QWNxdWlyZVNoYXJlZDwvdHQ+IHRvCisgKiBkaXNhYmxlIGJhcmdpbmcgYnkgaW50ZXJuYWxseSBpbnZva2luZyBvbmUgb3IgbW9yZSBvZiB0aGUgaW5zcGVjdGlvbgorICogbWV0aG9kcy4gSW4gcGFydGljdWxhciwgYSBzdHJpY3QgRklGTyBsb2NrIGNhbiBkZWZpbmUKKyAqIDx0dD50cnlBY3F1aXJlPC90dD4gdG8gaW1tZWRpYXRlbHkgcmV0dXJuIDx0dD5mYWxzZTwvdHQ+IGlmIHtAbGluaworICogI2dldEZpcnN0UXVldWVkVGhyZWFkfSBkb2VzIG5vdCByZXR1cm4gdGhlIGN1cnJlbnQgdGhyZWFkLiAgQQorICogbm9ybWFsbHkgcHJlZmVyYWJsZSBub24tc3RyaWN0IGZhaXIgdmVyc2lvbiBjYW4gaW1tZWRpYXRlbHkgcmV0dXJuCisgKiA8dHQ+ZmFsc2U8L3R0PiBvbmx5IGlmIHtAbGluayAjaGFzUXVldWVkVGhyZWFkc30gcmV0dXJucworICogPHR0PnRydWU8L3R0PiBhbmQgPHR0PmdldEZpcnN0UXVldWVkVGhyZWFkPC90dD4gaXMgbm90IHRoZSBjdXJyZW50CisgKiB0aHJlYWQ7IG9yIGVxdWl2YWxlbnRseSwgdGhhdCA8dHQ+Z2V0Rmlyc3RRdWV1ZWRUaHJlYWQ8L3R0PiBpcyBib3RoCisgKiBub24tbnVsbCBhbmQgbm90IHRoZSBjdXJyZW50IHRocmVhZC4gIEZ1cnRoZXIgdmFyaWF0aW9ucyBhcmUKKyAqIHBvc3NpYmxlLgorICoKKyAqIDxwPlRocm91Z2hwdXQgYW5kIHNjYWxhYmlsaXR5IGFyZSBnZW5lcmFsbHkgaGlnaGVzdCBmb3IgdGhlCisgKiBkZWZhdWx0IGJhcmdpbmcgKGFsc28ga25vd24gYXMgPGVtPmdyZWVkeTwvZW0+LAorICogPGVtPnJlbm91bmNlbWVudDwvZW0+LCBhbmQgPGVtPmNvbnZveS1hdm9pZGFuY2U8L2VtPikgc3RyYXRlZ3kuCisgKiBXaGlsZSB0aGlzIGlzIG5vdCBndWFyYW50ZWVkIHRvIGJlIGZhaXIgb3Igc3RhcnZhdGlvbi1mcmVlLCBlYXJsaWVyCisgKiBxdWV1ZWQgdGhyZWFkcyBhcmUgYWxsb3dlZCB0byByZWNvbnRlbmQgYmVmb3JlIGxhdGVyIHF1ZXVlZAorICogdGhyZWFkcywgYW5kIGVhY2ggcmVjb250ZW50aW9uIGhhcyBhbiB1bmJpYXNlZCBjaGFuY2UgdG8gc3VjY2VlZAorICogYWdhaW5zdCBpbmNvbWluZyB0aHJlYWRzLiAgQWxzbywgd2hpbGUgYWNxdWlyZXMgZG8gbm90CisgKiAmcXVvdDtzcGluJnF1b3Q7IGluIHRoZSB1c3VhbCBzZW5zZSwgdGhleSBtYXkgcGVyZm9ybSBtdWx0aXBsZQorICogaW52b2NhdGlvbnMgb2YgPHR0PnRyeUFjcXVpcmU8L3R0PiBpbnRlcnNwZXJzZWQgd2l0aCBvdGhlcgorICogY29tcHV0YXRpb25zIGJlZm9yZSBibG9ja2luZy4gIFRoaXMgZ2l2ZXMgbW9zdCBvZiB0aGUgYmVuZWZpdHMgb2YKKyAqIHNwaW5zIHdoZW4gZXhjbHVzaXZlIHN5bmNocm9uaXphdGlvbiBpcyBvbmx5IGJyaWVmbHkgaGVsZCwgd2l0aG91dAorICogbW9zdCBvZiB0aGUgbGlhYmlsaXRpZXMgd2hlbiBpdCBpc24ndC4gSWYgc28gZGVzaXJlZCwgeW91IGNhbgorICogYXVnbWVudCB0aGlzIGJ5IHByZWNlZGluZyBjYWxscyB0byBhY3F1aXJlIG1ldGhvZHMgd2l0aAorICogImZhc3QtcGF0aCIgY2hlY2tzLCBwb3NzaWJseSBwcmVjaGVja2luZyB7QGxpbmsgI2hhc0NvbnRlbmRlZH0KKyAqIGFuZC9vciB7QGxpbmsgI2hhc1F1ZXVlZFRocmVhZHN9IHRvIG9ubHkgZG8gc28gaWYgdGhlIHN5bmNocm9uaXplcgorICogaXMgbGlrZWx5IG5vdCB0byBiZSBjb250ZW5kZWQuCisgKgorICogPHA+VGhpcyBjbGFzcyBwcm92aWRlcyBhbiBlZmZpY2llbnQgYW5kIHNjYWxhYmxlIGJhc2lzIGZvcgorICogc3luY2hyb25pemF0aW9uIGluIHBhcnQgYnkgc3BlY2lhbGl6aW5nIGl0cyByYW5nZSBvZiB1c2UgdG8KKyAqIHN5bmNocm9uaXplcnMgdGhhdCBjYW4gcmVseSBvbiA8dHQ+aW50PC90dD4gc3RhdGUsIGFjcXVpcmUsIGFuZAorICogcmVsZWFzZSBwYXJhbWV0ZXJzLCBhbmQgYW4gaW50ZXJuYWwgRklGTyB3YWl0IHF1ZXVlLiBXaGVuIHRoaXMgZG9lcworICogbm90IHN1ZmZpY2UsIHlvdSBjYW4gYnVpbGQgc3luY2hyb25pemVycyBmcm9tIGEgbG93ZXIgbGV2ZWwgdXNpbmcKKyAqIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMgYXRvbWljfSBjbGFzc2VzLCB5b3VyIG93biBjdXN0b20KKyAqIHtAbGluayBqYXZhLnV0aWwuUXVldWV9IGNsYXNzZXMsIGFuZCB7QGxpbmsgTG9ja1N1cHBvcnR9IGJsb2NraW5nCisgKiBzdXBwb3J0LgorICoKKyAqIDxoMz5Vc2FnZSBFeGFtcGxlczwvaDM+CisgKgorICogPHA+SGVyZSBpcyBhIG5vbi1yZWVudHJhbnQgbXV0dWFsIGV4Y2x1c2lvbiBsb2NrIGNsYXNzIHRoYXQgdXNlcworICogdGhlIHZhbHVlIHplcm8gdG8gcmVwcmVzZW50IHRoZSB1bmxvY2tlZCBzdGF0ZSwgYW5kIG9uZSB0bworICogcmVwcmVzZW50IHRoZSBsb2NrZWQgc3RhdGUuIFdoaWxlIGEgbm9uLXJlZW50cmFudCBsb2NrCisgKiBkb2VzIG5vdCBzdHJpY3RseSByZXF1aXJlIHJlY29yZGluZyBvZiB0aGUgY3VycmVudCBvd25lcgorICogdGhyZWFkLCB0aGlzIGNsYXNzIGRvZXMgc28gYW55d2F5IHRvIG1ha2UgdXNhZ2UgZWFzaWVyIHRvIG1vbml0b3IuCisgKiBJdCBhbHNvIHN1cHBvcnRzIGNvbmRpdGlvbnMgYW5kIGV4cG9zZXMKKyAqIG9uZSBvZiB0aGUgaW5zdHJ1bWVudGF0aW9uIG1ldGhvZHM6CisgKgorICogPHByZT4KKyAqIGNsYXNzIE11dGV4IGltcGxlbWVudHMgTG9jaywgamF2YS5pby5TZXJpYWxpemFibGUgeworICoKKyAqICAgLy8gT3VyIGludGVybmFsIGhlbHBlciBjbGFzcworICogICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTeW5jIGV4dGVuZHMgQWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXIgeworICogICAgIC8vIFJlcG9ydCB3aGV0aGVyIGluIGxvY2tlZCBzdGF0ZQorICogICAgIHByb3RlY3RlZCBib29sZWFuIGlzSGVsZEV4Y2x1c2l2ZWx5KCkgeworICogICAgICAgcmV0dXJuIGdldFN0YXRlKCkgPT0gMTsKKyAqICAgICB9CisgKgorICogICAgIC8vIEFjcXVpcmUgdGhlIGxvY2sgaWYgc3RhdGUgaXMgemVybworICogICAgIHB1YmxpYyBib29sZWFuIHRyeUFjcXVpcmUoaW50IGFjcXVpcmVzKSB7CisgKiAgICAgICBhc3NlcnQgYWNxdWlyZXMgPT0gMTsgLy8gT3RoZXJ3aXNlIHVudXNlZAorICogICAgICAgaWYgKGNvbXBhcmVBbmRTZXRTdGF0ZSgwLCAxKSkgeworICogICAgICAgICBzZXRFeGNsdXNpdmVPd25lclRocmVhZChUaHJlYWQuY3VycmVudFRocmVhZCgpKTsKKyAqICAgICAgICAgcmV0dXJuIHRydWU7CisgKiAgICAgICB9CisgKiAgICAgICByZXR1cm4gZmFsc2U7CisgKiAgICAgfQorICoKKyAqICAgICAvLyBSZWxlYXNlIHRoZSBsb2NrIGJ5IHNldHRpbmcgc3RhdGUgdG8gemVybworICogICAgIHByb3RlY3RlZCBib29sZWFuIHRyeVJlbGVhc2UoaW50IHJlbGVhc2VzKSB7CisgKiAgICAgICBhc3NlcnQgcmVsZWFzZXMgPT0gMTsgLy8gT3RoZXJ3aXNlIHVudXNlZAorICogICAgICAgaWYgKGdldFN0YXRlKCkgPT0gMCkgdGhyb3cgbmV3IElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24oKTsKKyAqICAgICAgIHNldEV4Y2x1c2l2ZU93bmVyVGhyZWFkKG51bGwpOworICogICAgICAgc2V0U3RhdGUoMCk7CisgKiAgICAgICByZXR1cm4gdHJ1ZTsKKyAqICAgICB9CisgKgorICogICAgIC8vIFByb3ZpZGUgYSBDb25kaXRpb24KKyAqICAgICBDb25kaXRpb24gbmV3Q29uZGl0aW9uKCkgeyByZXR1cm4gbmV3IENvbmRpdGlvbk9iamVjdCgpOyB9CisgKgorICogICAgIC8vIERlc2VyaWFsaXplIHByb3Blcmx5CisgKiAgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gcykKKyAqICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAqICAgICAgIHMuZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAqICAgICAgIHNldFN0YXRlKDApOyAvLyByZXNldCB0byB1bmxvY2tlZCBzdGF0ZQorICogICAgIH0KKyAqICAgfQorICoKKyAqICAgLy8gVGhlIHN5bmMgb2JqZWN0IGRvZXMgYWxsIHRoZSBoYXJkIHdvcmsuIFdlIGp1c3QgZm9yd2FyZCB0byBpdC4KKyAqICAgcHJpdmF0ZSBmaW5hbCBTeW5jIHN5bmMgPSBuZXcgU3luYygpOworICoKKyAqICAgcHVibGljIHZvaWQgbG9jaygpICAgICAgICAgICAgICAgIHsgc3luYy5hY3F1aXJlKDEpOyB9CisgKiAgIHB1YmxpYyBib29sZWFuIHRyeUxvY2soKSAgICAgICAgICB7IHJldHVybiBzeW5jLnRyeUFjcXVpcmUoMSk7IH0KKyAqICAgcHVibGljIHZvaWQgdW5sb2NrKCkgICAgICAgICAgICAgIHsgc3luYy5yZWxlYXNlKDEpOyB9CisgKiAgIHB1YmxpYyBDb25kaXRpb24gbmV3Q29uZGl0aW9uKCkgICB7IHJldHVybiBzeW5jLm5ld0NvbmRpdGlvbigpOyB9CisgKiAgIHB1YmxpYyBib29sZWFuIGlzTG9ja2VkKCkgICAgICAgICB7IHJldHVybiBzeW5jLmlzSGVsZEV4Y2x1c2l2ZWx5KCk7IH0KKyAqICAgcHVibGljIGJvb2xlYW4gaGFzUXVldWVkVGhyZWFkcygpIHsgcmV0dXJuIHN5bmMuaGFzUXVldWVkVGhyZWFkcygpOyB9CisgKiAgIHB1YmxpYyB2b2lkIGxvY2tJbnRlcnJ1cHRpYmx5KCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAqICAgICBzeW5jLmFjcXVpcmVJbnRlcnJ1cHRpYmx5KDEpOworICogICB9CisgKiAgIHB1YmxpYyBib29sZWFuIHRyeUxvY2sobG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KQorICogICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAqICAgICByZXR1cm4gc3luYy50cnlBY3F1aXJlTmFub3MoMSwgdW5pdC50b05hbm9zKHRpbWVvdXQpKTsKKyAqICAgfQorICogfQorICogPC9wcmU+CisgKgorICogPHA+SGVyZSBpcyBhIGxhdGNoIGNsYXNzIHRoYXQgaXMgbGlrZSBhIHtAbGluayBDb3VudERvd25MYXRjaH0KKyAqIGV4Y2VwdCB0aGF0IGl0IG9ubHkgcmVxdWlyZXMgYSBzaW5nbGUgPHR0PnNpZ25hbDwvdHQ+IHRvCisgKiBmaXJlLiBCZWNhdXNlIGEgbGF0Y2ggaXMgbm9uLWV4Y2x1c2l2ZSwgaXQgdXNlcyB0aGUgPHR0PnNoYXJlZDwvdHQ+CisgKiBhY3F1aXJlIGFuZCByZWxlYXNlIG1ldGhvZHMuCisgKgorICogPHByZT4KKyAqIGNsYXNzIEJvb2xlYW5MYXRjaCB7CisgKgorICogICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTeW5jIGV4dGVuZHMgQWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXIgeworICogICAgIGJvb2xlYW4gaXNTaWduYWxsZWQoKSB7IHJldHVybiBnZXRTdGF0ZSgpICE9IDA7IH0KKyAqCisgKiAgICAgcHJvdGVjdGVkIGludCB0cnlBY3F1aXJlU2hhcmVkKGludCBpZ25vcmUpIHsKKyAqICAgICAgIHJldHVybiBpc1NpZ25hbGxlZCgpID8gMSA6IC0xOworICogICAgIH0KKyAqCisgKiAgICAgcHJvdGVjdGVkIGJvb2xlYW4gdHJ5UmVsZWFzZVNoYXJlZChpbnQgaWdub3JlKSB7CisgKiAgICAgICBzZXRTdGF0ZSgxKTsKKyAqICAgICAgIHJldHVybiB0cnVlOworICogICAgIH0KKyAqICAgfQorICoKKyAqICAgcHJpdmF0ZSBmaW5hbCBTeW5jIHN5bmMgPSBuZXcgU3luYygpOworICogICBwdWJsaWMgYm9vbGVhbiBpc1NpZ25hbGxlZCgpIHsgcmV0dXJuIHN5bmMuaXNTaWduYWxsZWQoKTsgfQorICogICBwdWJsaWMgdm9pZCBzaWduYWwoKSAgICAgICAgIHsgc3luYy5yZWxlYXNlU2hhcmVkKDEpOyB9CisgKiAgIHB1YmxpYyB2b2lkIGF3YWl0KCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAqICAgICBzeW5jLmFjcXVpcmVTaGFyZWRJbnRlcnJ1cHRpYmx5KDEpOworICogICB9CisgKiB9CisgKiA8L3ByZT4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplcgorICAgIGV4dGVuZHMgQWJzdHJhY3RPd25hYmxlU3luY2hyb25pemVyCisgICAgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3MzczOTg0OTcyNTcyNDE0NjkxTDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgPHR0PkFic3RyYWN0UXVldWVkU3luY2hyb25pemVyPC90dD4gaW5zdGFuY2UKKyAgICAgKiB3aXRoIGluaXRpYWwgc3luY2hyb25pemF0aW9uIHN0YXRlIG9mIHplcm8uCisgICAgICovCisgICAgcHJvdGVjdGVkIEFic3RyYWN0UXVldWVkU3luY2hyb25pemVyKCkgeyB9CisKKyAgICAvKioKKyAgICAgKiBXYWl0IHF1ZXVlIG5vZGUgY2xhc3MuCisgICAgICoKKyAgICAgKiA8cD5UaGUgd2FpdCBxdWV1ZSBpcyBhIHZhcmlhbnQgb2YgYSAiQ0xIIiAoQ3JhaWcsIExhbmRpbiwgYW5kCisgICAgICogSGFnZXJzdGVuKSBsb2NrIHF1ZXVlLiBDTEggbG9ja3MgYXJlIG5vcm1hbGx5IHVzZWQgZm9yCisgICAgICogc3BpbmxvY2tzLiAgV2UgaW5zdGVhZCB1c2UgdGhlbSBmb3IgYmxvY2tpbmcgc3luY2hyb25pemVycywgYnV0CisgICAgICogdXNlIHRoZSBzYW1lIGJhc2ljIHRhY3RpYyBvZiBob2xkaW5nIHNvbWUgb2YgdGhlIGNvbnRyb2wKKyAgICAgKiBpbmZvcm1hdGlvbiBhYm91dCBhIHRocmVhZCBpbiB0aGUgcHJlZGVjZXNzb3Igb2YgaXRzIG5vZGUuICBBCisgICAgICogInN0YXR1cyIgZmllbGQgaW4gZWFjaCBub2RlIGtlZXBzIHRyYWNrIG9mIHdoZXRoZXIgYSB0aHJlYWQKKyAgICAgKiBzaG91bGQgYmxvY2suICBBIG5vZGUgaXMgc2lnbmFsbGVkIHdoZW4gaXRzIHByZWRlY2Vzc29yCisgICAgICogcmVsZWFzZXMuICBFYWNoIG5vZGUgb2YgdGhlIHF1ZXVlIG90aGVyd2lzZSBzZXJ2ZXMgYXMgYQorICAgICAqIHNwZWNpZmljLW5vdGlmaWNhdGlvbi1zdHlsZSBtb25pdG9yIGhvbGRpbmcgYSBzaW5nbGUgd2FpdGluZworICAgICAqIHRocmVhZC4gVGhlIHN0YXR1cyBmaWVsZCBkb2VzIE5PVCBjb250cm9sIHdoZXRoZXIgdGhyZWFkcyBhcmUKKyAgICAgKiBncmFudGVkIGxvY2tzIGV0YyB0aG91Z2guICBBIHRocmVhZCBtYXkgdHJ5IHRvIGFjcXVpcmUgaWYgaXQgaXMKKyAgICAgKiBmaXJzdCBpbiB0aGUgcXVldWUuIEJ1dCBiZWluZyBmaXJzdCBkb2VzIG5vdCBndWFyYW50ZWUgc3VjY2VzczsKKyAgICAgKiBpdCBvbmx5IGdpdmVzIHRoZSByaWdodCB0byBjb250ZW5kLiAgU28gdGhlIGN1cnJlbnRseSByZWxlYXNlZAorICAgICAqIGNvbnRlbmRlciB0aHJlYWQgbWF5IG5lZWQgdG8gcmV3YWl0LgorICAgICAqCisgICAgICogPHA+VG8gZW5xdWV1ZSBpbnRvIGEgQ0xIIGxvY2ssIHlvdSBhdG9taWNhbGx5IHNwbGljZSBpdCBpbiBhcyBuZXcKKyAgICAgKiB0YWlsLiBUbyBkZXF1ZXVlLCB5b3UganVzdCBzZXQgdGhlIGhlYWQgZmllbGQuCisgICAgICogPHByZT4KKyAgICAgKiAgICAgICstLS0tLS0rICBwcmV2ICstLS0tLSsgICAgICAgKy0tLS0tKworICAgICAqIGhlYWQgfCAgICAgIHwgPC0tLS0gfCAgICAgfCA8LS0tLSB8ICAgICB8ICB0YWlsCisgICAgICogICAgICArLS0tLS0tKyAgICAgICArLS0tLS0rICAgICAgICstLS0tLSsKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIDxwPkluc2VydGlvbiBpbnRvIGEgQ0xIIHF1ZXVlIHJlcXVpcmVzIG9ubHkgYSBzaW5nbGUgYXRvbWljCisgICAgICogb3BlcmF0aW9uIG9uICJ0YWlsIiwgc28gdGhlcmUgaXMgYSBzaW1wbGUgYXRvbWljIHBvaW50IG9mCisgICAgICogZGVtYXJjYXRpb24gZnJvbSB1bnF1ZXVlZCB0byBxdWV1ZWQuIFNpbWlsYXJseSwgZGVxdWVpbmcKKyAgICAgKiBpbnZvbHZlcyBvbmx5IHVwZGF0aW5nIHRoZSAiaGVhZCIuIEhvd2V2ZXIsIGl0IHRha2VzIGEgYml0CisgICAgICogbW9yZSB3b3JrIGZvciBub2RlcyB0byBkZXRlcm1pbmUgd2hvIHRoZWlyIHN1Y2Nlc3NvcnMgYXJlLAorICAgICAqIGluIHBhcnQgdG8gZGVhbCB3aXRoIHBvc3NpYmxlIGNhbmNlbGxhdGlvbiBkdWUgdG8gdGltZW91dHMKKyAgICAgKiBhbmQgaW50ZXJydXB0cy4KKyAgICAgKgorICAgICAqIDxwPlRoZSAicHJldiIgbGlua3MgKG5vdCB1c2VkIGluIG9yaWdpbmFsIENMSCBsb2NrcyksIGFyZSBtYWlubHkKKyAgICAgKiBuZWVkZWQgdG8gaGFuZGxlIGNhbmNlbGxhdGlvbi4gSWYgYSBub2RlIGlzIGNhbmNlbGxlZCwgaXRzCisgICAgICogc3VjY2Vzc29yIGlzIChub3JtYWxseSkgcmVsaW5rZWQgdG8gYSBub24tY2FuY2VsbGVkCisgICAgICogcHJlZGVjZXNzb3IuIEZvciBleHBsYW5hdGlvbiBvZiBzaW1pbGFyIG1lY2hhbmljcyBpbiB0aGUgY2FzZQorICAgICAqIG9mIHNwaW4gbG9ja3MsIHNlZSB0aGUgcGFwZXJzIGJ5IFNjb3R0IGFuZCBTY2hlcmVyIGF0CisgICAgICogaHR0cDovL3d3dy5jcy5yb2NoZXN0ZXIuZWR1L3Uvc2NvdHQvc3luY2hyb25pemF0aW9uLworICAgICAqCisgICAgICogPHA+V2UgYWxzbyB1c2UgIm5leHQiIGxpbmtzIHRvIGltcGxlbWVudCBibG9ja2luZyBtZWNoYW5pY3MuCisgICAgICogVGhlIHRocmVhZCBpZCBmb3IgZWFjaCBub2RlIGlzIGtlcHQgaW4gaXRzIG93biBub2RlLCBzbyBhCisgICAgICogcHJlZGVjZXNzb3Igc2lnbmFscyB0aGUgbmV4dCBub2RlIHRvIHdha2UgdXAgYnkgdHJhdmVyc2luZworICAgICAqIG5leHQgbGluayB0byBkZXRlcm1pbmUgd2hpY2ggdGhyZWFkIGl0IGlzLiAgRGV0ZXJtaW5hdGlvbiBvZgorICAgICAqIHN1Y2Nlc3NvciBtdXN0IGF2b2lkIHJhY2VzIHdpdGggbmV3bHkgcXVldWVkIG5vZGVzIHRvIHNldAorICAgICAqIHRoZSAibmV4dCIgZmllbGRzIG9mIHRoZWlyIHByZWRlY2Vzc29ycy4gIFRoaXMgaXMgc29sdmVkCisgICAgICogd2hlbiBuZWNlc3NhcnkgYnkgY2hlY2tpbmcgYmFja3dhcmRzIGZyb20gdGhlIGF0b21pY2FsbHkKKyAgICAgKiB1cGRhdGVkICJ0YWlsIiB3aGVuIGEgbm9kZSdzIHN1Y2Nlc3NvciBhcHBlYXJzIHRvIGJlIG51bGwuCisgICAgICogKE9yLCBzYWlkIGRpZmZlcmVudGx5LCB0aGUgbmV4dC1saW5rcyBhcmUgYW4gb3B0aW1pemF0aW9uCisgICAgICogc28gdGhhdCB3ZSBkb24ndCB1c3VhbGx5IG5lZWQgYSBiYWNrd2FyZCBzY2FuLikKKyAgICAgKgorICAgICAqIDxwPkNhbmNlbGxhdGlvbiBpbnRyb2R1Y2VzIHNvbWUgY29uc2VydmF0aXNtIHRvIHRoZSBiYXNpYworICAgICAqIGFsZ29yaXRobXMuICBTaW5jZSB3ZSBtdXN0IHBvbGwgZm9yIGNhbmNlbGxhdGlvbiBvZiBvdGhlcgorICAgICAqIG5vZGVzLCB3ZSBjYW4gbWlzcyBub3RpY2luZyB3aGV0aGVyIGEgY2FuY2VsbGVkIG5vZGUgaXMKKyAgICAgKiBhaGVhZCBvciBiZWhpbmQgdXMuIFRoaXMgaXMgZGVhbHQgd2l0aCBieSBhbHdheXMgdW5wYXJraW5nCisgICAgICogc3VjY2Vzc29ycyB1cG9uIGNhbmNlbGxhdGlvbiwgYWxsb3dpbmcgdGhlbSB0byBzdGFiaWxpemUgb24KKyAgICAgKiBhIG5ldyBwcmVkZWNlc3NvciwgdW5sZXNzIHdlIGNhbiBpZGVudGlmeSBhbiB1bmNhbmNlbGxlZAorICAgICAqIHByZWRlY2Vzc29yIHdobyB3aWxsIGNhcnJ5IHRoaXMgcmVzcG9uc2liaWxpdHkuCisgICAgICoKKyAgICAgKiA8cD5DTEggcXVldWVzIG5lZWQgYSBkdW1teSBoZWFkZXIgbm9kZSB0byBnZXQgc3RhcnRlZC4gQnV0CisgICAgICogd2UgZG9uJ3QgY3JlYXRlIHRoZW0gb24gY29uc3RydWN0aW9uLCBiZWNhdXNlIGl0IHdvdWxkIGJlIHdhc3RlZAorICAgICAqIGVmZm9ydCBpZiB0aGVyZSBpcyBuZXZlciBjb250ZW50aW9uLiBJbnN0ZWFkLCB0aGUgbm9kZQorICAgICAqIGlzIGNvbnN0cnVjdGVkIGFuZCBoZWFkIGFuZCB0YWlsIHBvaW50ZXJzIGFyZSBzZXQgdXBvbiBmaXJzdAorICAgICAqIGNvbnRlbnRpb24uCisgICAgICoKKyAgICAgKiA8cD5UaHJlYWRzIHdhaXRpbmcgb24gQ29uZGl0aW9ucyB1c2UgdGhlIHNhbWUgbm9kZXMsIGJ1dAorICAgICAqIHVzZSBhbiBhZGRpdGlvbmFsIGxpbmsuIENvbmRpdGlvbnMgb25seSBuZWVkIHRvIGxpbmsgbm9kZXMKKyAgICAgKiBpbiBzaW1wbGUgKG5vbi1jb25jdXJyZW50KSBsaW5rZWQgcXVldWVzIGJlY2F1c2UgdGhleSBhcmUKKyAgICAgKiBvbmx5IGFjY2Vzc2VkIHdoZW4gZXhjbHVzaXZlbHkgaGVsZC4gIFVwb24gYXdhaXQsIGEgbm9kZSBpcworICAgICAqIGluc2VydGVkIGludG8gYSBjb25kaXRpb24gcXVldWUuICBVcG9uIHNpZ25hbCwgdGhlIG5vZGUgaXMKKyAgICAgKiB0cmFuc2ZlcnJlZCB0byB0aGUgbWFpbiBxdWV1ZS4gIEEgc3BlY2lhbCB2YWx1ZSBvZiBzdGF0dXMKKyAgICAgKiBmaWVsZCBpcyB1c2VkIHRvIG1hcmsgd2hpY2ggcXVldWUgYSBub2RlIGlzIG9uLgorICAgICAqCisgICAgICogPHA+VGhhbmtzIGdvIHRvIERhdmUgRGljZSwgTWFyayBNb2lyLCBWaWN0b3IgTHVjaGFuZ2NvLCBCaWxsCisgICAgICogU2NoZXJlciBhbmQgTWljaGFlbCBTY290dCwgYWxvbmcgd2l0aCBtZW1iZXJzIG9mIEpTUi0xNjYKKyAgICAgKiBleHBlcnQgZ3JvdXAsIGZvciBoZWxwZnVsIGlkZWFzLCBkaXNjdXNzaW9ucywgYW5kIGNyaXRpcXVlcworICAgICAqIG9uIHRoZSBkZXNpZ24gb2YgdGhpcyBjbGFzcy4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgY2xhc3MgTm9kZSB7CisgICAgICAgIC8qKiBNYXJrZXIgdG8gaW5kaWNhdGUgYSBub2RlIGlzIHdhaXRpbmcgaW4gc2hhcmVkIG1vZGUgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIE5vZGUgU0hBUkVEID0gbmV3IE5vZGUoKTsKKyAgICAgICAgLyoqIE1hcmtlciB0byBpbmRpY2F0ZSBhIG5vZGUgaXMgd2FpdGluZyBpbiBleGNsdXNpdmUgbW9kZSAqLworICAgICAgICBzdGF0aWMgZmluYWwgTm9kZSBFWENMVVNJVkUgPSBudWxsOworCisgICAgICAgIC8qKiB3YWl0U3RhdHVzIHZhbHVlIHRvIGluZGljYXRlIHRocmVhZCBoYXMgY2FuY2VsbGVkICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgQ0FOQ0VMTEVEID0gIDE7CisgICAgICAgIC8qKiB3YWl0U3RhdHVzIHZhbHVlIHRvIGluZGljYXRlIHN1Y2Nlc3NvcidzIHRocmVhZCBuZWVkcyB1bnBhcmtpbmcgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIGludCBTSUdOQUwgICAgPSAtMTsKKyAgICAgICAgLyoqIHdhaXRTdGF0dXMgdmFsdWUgdG8gaW5kaWNhdGUgdGhyZWFkIGlzIHdhaXRpbmcgb24gY29uZGl0aW9uICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgQ09ORElUSU9OID0gLTI7CisgICAgICAgIC8qKgorICAgICAgICAgKiB3YWl0U3RhdHVzIHZhbHVlIHRvIGluZGljYXRlIHRoZSBuZXh0IGFjcXVpcmVTaGFyZWQgc2hvdWxkCisgICAgICAgICAqIHVuY29uZGl0aW9uYWxseSBwcm9wYWdhdGUKKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgUFJPUEFHQVRFID0gLTM7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFN0YXR1cyBmaWVsZCwgdGFraW5nIG9uIG9ubHkgdGhlIHZhbHVlczoKKyAgICAgICAgICogICBTSUdOQUw6ICAgICBUaGUgc3VjY2Vzc29yIG9mIHRoaXMgbm9kZSBpcyAob3Igd2lsbCBzb29uIGJlKQorICAgICAgICAgKiAgICAgICAgICAgICAgIGJsb2NrZWQgKHZpYSBwYXJrKSwgc28gdGhlIGN1cnJlbnQgbm9kZSBtdXN0CisgICAgICAgICAqICAgICAgICAgICAgICAgdW5wYXJrIGl0cyBzdWNjZXNzb3Igd2hlbiBpdCByZWxlYXNlcyBvcgorICAgICAgICAgKiAgICAgICAgICAgICAgIGNhbmNlbHMuIFRvIGF2b2lkIHJhY2VzLCBhY3F1aXJlIG1ldGhvZHMgbXVzdAorICAgICAgICAgKiAgICAgICAgICAgICAgIGZpcnN0IGluZGljYXRlIHRoZXkgbmVlZCBhIHNpZ25hbCwKKyAgICAgICAgICogICAgICAgICAgICAgICB0aGVuIHJldHJ5IHRoZSBhdG9taWMgYWNxdWlyZSwgYW5kIHRoZW4sCisgICAgICAgICAqICAgICAgICAgICAgICAgb24gZmFpbHVyZSwgYmxvY2suCisgICAgICAgICAqICAgQ0FOQ0VMTEVEOiAgVGhpcyBub2RlIGlzIGNhbmNlbGxlZCBkdWUgdG8gdGltZW91dCBvciBpbnRlcnJ1cHQuCisgICAgICAgICAqICAgICAgICAgICAgICAgTm9kZXMgbmV2ZXIgbGVhdmUgdGhpcyBzdGF0ZS4gSW4gcGFydGljdWxhciwKKyAgICAgICAgICogICAgICAgICAgICAgICBhIHRocmVhZCB3aXRoIGNhbmNlbGxlZCBub2RlIG5ldmVyIGFnYWluIGJsb2Nrcy4KKyAgICAgICAgICogICBDT05ESVRJT046ICBUaGlzIG5vZGUgaXMgY3VycmVudGx5IG9uIGEgY29uZGl0aW9uIHF1ZXVlLgorICAgICAgICAgKiAgICAgICAgICAgICAgIEl0IHdpbGwgbm90IGJlIHVzZWQgYXMgYSBzeW5jIHF1ZXVlIG5vZGUKKyAgICAgICAgICogICAgICAgICAgICAgICB1bnRpbCB0cmFuc2ZlcnJlZCwgYXQgd2hpY2ggdGltZSB0aGUgc3RhdHVzCisgICAgICAgICAqICAgICAgICAgICAgICAgd2lsbCBiZSBzZXQgdG8gMC4gKFVzZSBvZiB0aGlzIHZhbHVlIGhlcmUgaGFzCisgICAgICAgICAqICAgICAgICAgICAgICAgbm90aGluZyB0byBkbyB3aXRoIHRoZSBvdGhlciB1c2VzIG9mIHRoZQorICAgICAgICAgKiAgICAgICAgICAgICAgIGZpZWxkLCBidXQgc2ltcGxpZmllcyBtZWNoYW5pY3MuKQorICAgICAgICAgKiAgIFBST1BBR0FURTogIEEgcmVsZWFzZVNoYXJlZCBzaG91bGQgYmUgcHJvcGFnYXRlZCB0byBvdGhlcgorICAgICAgICAgKiAgICAgICAgICAgICAgIG5vZGVzLiBUaGlzIGlzIHNldCAoZm9yIGhlYWQgbm9kZSBvbmx5KSBpbgorICAgICAgICAgKiAgICAgICAgICAgICAgIGRvUmVsZWFzZVNoYXJlZCB0byBlbnN1cmUgcHJvcGFnYXRpb24KKyAgICAgICAgICogICAgICAgICAgICAgICBjb250aW51ZXMsIGV2ZW4gaWYgb3RoZXIgb3BlcmF0aW9ucyBoYXZlCisgICAgICAgICAqICAgICAgICAgICAgICAgc2luY2UgaW50ZXJ2ZW5lZC4KKyAgICAgICAgICogICAwOiAgICAgICAgICBOb25lIG9mIHRoZSBhYm92ZQorICAgICAgICAgKgorICAgICAgICAgKiBUaGUgdmFsdWVzIGFyZSBhcnJhbmdlZCBudW1lcmljYWxseSB0byBzaW1wbGlmeSB1c2UuCisgICAgICAgICAqIE5vbi1uZWdhdGl2ZSB2YWx1ZXMgbWVhbiB0aGF0IGEgbm9kZSBkb2Vzbid0IG5lZWQgdG8KKyAgICAgICAgICogc2lnbmFsLiBTbywgbW9zdCBjb2RlIGRvZXNuJ3QgbmVlZCB0byBjaGVjayBmb3IgcGFydGljdWxhcgorICAgICAgICAgKiB2YWx1ZXMsIGp1c3QgZm9yIHNpZ24uCisgICAgICAgICAqCisgICAgICAgICAqIFRoZSBmaWVsZCBpcyBpbml0aWFsaXplZCB0byAwIGZvciBub3JtYWwgc3luYyBub2RlcywgYW5kCisgICAgICAgICAqIENPTkRJVElPTiBmb3IgY29uZGl0aW9uIG5vZGVzLiAgSXQgaXMgbW9kaWZpZWQgdXNpbmcgQ0FTCisgICAgICAgICAqIChvciB3aGVuIHBvc3NpYmxlLCB1bmNvbmRpdGlvbmFsIHZvbGF0aWxlIHdyaXRlcykuCisgICAgICAgICAqLworICAgICAgICB2b2xhdGlsZSBpbnQgd2FpdFN0YXR1czsKKworICAgICAgICAvKioKKyAgICAgICAgICogTGluayB0byBwcmVkZWNlc3NvciBub2RlIHRoYXQgY3VycmVudCBub2RlL3RocmVhZCByZWxpZXMgb24KKyAgICAgICAgICogZm9yIGNoZWNraW5nIHdhaXRTdGF0dXMuIEFzc2lnbmVkIGR1cmluZyBlbnF1ZWluZywgYW5kIG51bGxlZAorICAgICAgICAgKiBvdXQgKGZvciBzYWtlIG9mIEdDKSBvbmx5IHVwb24gZGVxdWV1aW5nLiAgQWxzbywgdXBvbgorICAgICAgICAgKiBjYW5jZWxsYXRpb24gb2YgYSBwcmVkZWNlc3Nvciwgd2Ugc2hvcnQtY2lyY3VpdCB3aGlsZQorICAgICAgICAgKiBmaW5kaW5nIGEgbm9uLWNhbmNlbGxlZCBvbmUsIHdoaWNoIHdpbGwgYWx3YXlzIGV4aXN0CisgICAgICAgICAqIGJlY2F1c2UgdGhlIGhlYWQgbm9kZSBpcyBuZXZlciBjYW5jZWxsZWQ6IEEgbm9kZSBiZWNvbWVzCisgICAgICAgICAqIGhlYWQgb25seSBhcyBhIHJlc3VsdCBvZiBzdWNjZXNzZnVsIGFjcXVpcmUuIEEKKyAgICAgICAgICogY2FuY2VsbGVkIHRocmVhZCBuZXZlciBzdWNjZWVkcyBpbiBhY3F1aXJpbmcsIGFuZCBhIHRocmVhZCBvbmx5CisgICAgICAgICAqIGNhbmNlbHMgaXRzZWxmLCBub3QgYW55IG90aGVyIG5vZGUuCisgICAgICAgICAqLworICAgICAgICB2b2xhdGlsZSBOb2RlIHByZXY7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIExpbmsgdG8gdGhlIHN1Y2Nlc3NvciBub2RlIHRoYXQgdGhlIGN1cnJlbnQgbm9kZS90aHJlYWQKKyAgICAgICAgICogdW5wYXJrcyB1cG9uIHJlbGVhc2UuIEFzc2lnbmVkIGR1cmluZyBlbnF1ZXVpbmcsIGFkanVzdGVkCisgICAgICAgICAqIHdoZW4gYnlwYXNzaW5nIGNhbmNlbGxlZCBwcmVkZWNlc3NvcnMsIGFuZCBudWxsZWQgb3V0IChmb3IKKyAgICAgICAgICogc2FrZSBvZiBHQykgd2hlbiBkZXF1ZXVlZC4gIFRoZSBlbnEgb3BlcmF0aW9uIGRvZXMgbm90CisgICAgICAgICAqIGFzc2lnbiBuZXh0IGZpZWxkIG9mIGEgcHJlZGVjZXNzb3IgdW50aWwgYWZ0ZXIgYXR0YWNobWVudCwKKyAgICAgICAgICogc28gc2VlaW5nIGEgbnVsbCBuZXh0IGZpZWxkIGRvZXMgbm90IG5lY2Vzc2FyaWx5IG1lYW4gdGhhdAorICAgICAgICAgKiBub2RlIGlzIGF0IGVuZCBvZiBxdWV1ZS4gSG93ZXZlciwgaWYgYSBuZXh0IGZpZWxkIGFwcGVhcnMKKyAgICAgICAgICogdG8gYmUgbnVsbCwgd2UgY2FuIHNjYW4gcHJldidzIGZyb20gdGhlIHRhaWwgdG8KKyAgICAgICAgICogZG91YmxlLWNoZWNrLiAgVGhlIG5leHQgZmllbGQgb2YgY2FuY2VsbGVkIG5vZGVzIGlzIHNldCB0bworICAgICAgICAgKiBwb2ludCB0byB0aGUgbm9kZSBpdHNlbGYgaW5zdGVhZCBvZiBudWxsLCB0byBtYWtlIGxpZmUKKyAgICAgICAgICogZWFzaWVyIGZvciBpc09uU3luY1F1ZXVlLgorICAgICAgICAgKi8KKyAgICAgICAgdm9sYXRpbGUgTm9kZSBuZXh0OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgdGhyZWFkIHRoYXQgZW5xdWV1ZWQgdGhpcyBub2RlLiAgSW5pdGlhbGl6ZWQgb24KKyAgICAgICAgICogY29uc3RydWN0aW9uIGFuZCBudWxsZWQgb3V0IGFmdGVyIHVzZS4KKyAgICAgICAgICovCisgICAgICAgIHZvbGF0aWxlIFRocmVhZCB0aHJlYWQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIExpbmsgdG8gbmV4dCBub2RlIHdhaXRpbmcgb24gY29uZGl0aW9uLCBvciB0aGUgc3BlY2lhbAorICAgICAgICAgKiB2YWx1ZSBTSEFSRUQuICBCZWNhdXNlIGNvbmRpdGlvbiBxdWV1ZXMgYXJlIGFjY2Vzc2VkIG9ubHkKKyAgICAgICAgICogd2hlbiBob2xkaW5nIGluIGV4Y2x1c2l2ZSBtb2RlLCB3ZSBqdXN0IG5lZWQgYSBzaW1wbGUKKyAgICAgICAgICogbGlua2VkIHF1ZXVlIHRvIGhvbGQgbm9kZXMgd2hpbGUgdGhleSBhcmUgd2FpdGluZyBvbgorICAgICAgICAgKiBjb25kaXRpb25zLiBUaGV5IGFyZSB0aGVuIHRyYW5zZmVycmVkIHRvIHRoZSBxdWV1ZSB0bworICAgICAgICAgKiByZS1hY3F1aXJlLiBBbmQgYmVjYXVzZSBjb25kaXRpb25zIGNhbiBvbmx5IGJlIGV4Y2x1c2l2ZSwKKyAgICAgICAgICogd2Ugc2F2ZSBhIGZpZWxkIGJ5IHVzaW5nIHNwZWNpYWwgdmFsdWUgdG8gaW5kaWNhdGUgc2hhcmVkCisgICAgICAgICAqIG1vZGUuCisgICAgICAgICAqLworICAgICAgICBOb2RlIG5leHRXYWl0ZXI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiBub2RlIGlzIHdhaXRpbmcgaW4gc2hhcmVkIG1vZGUKKyAgICAgICAgICovCisgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNTaGFyZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV4dFdhaXRlciA9PSBTSEFSRUQ7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyBwcmV2aW91cyBub2RlLCBvciB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgbnVsbC4KKyAgICAgICAgICogVXNlIHdoZW4gcHJlZGVjZXNzb3IgY2Fubm90IGJlIG51bGwuICBUaGUgbnVsbCBjaGVjayBjb3VsZAorICAgICAgICAgKiBiZSBlbGlkZWQsIGJ1dCBpcyBwcmVzZW50IHRvIGhlbHAgdGhlIFZNLgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBwcmVkZWNlc3NvciBvZiB0aGlzIG5vZGUKKyAgICAgICAgICovCisgICAgICAgIGZpbmFsIE5vZGUgcHJlZGVjZXNzb3IoKSB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24geworICAgICAgICAgICAgTm9kZSBwID0gcHJldjsKKyAgICAgICAgICAgIGlmIChwID09IG51bGwpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgcmV0dXJuIHA7CisgICAgICAgIH0KKworICAgICAgICBOb2RlKCkgeyAgICAvLyBVc2VkIHRvIGVzdGFibGlzaCBpbml0aWFsIGhlYWQgb3IgU0hBUkVEIG1hcmtlcgorICAgICAgICB9CisKKyAgICAgICAgTm9kZShUaHJlYWQgdGhyZWFkLCBOb2RlIG1vZGUpIHsgICAgIC8vIFVzZWQgYnkgYWRkV2FpdGVyCisgICAgICAgICAgICB0aGlzLm5leHRXYWl0ZXIgPSBtb2RlOworICAgICAgICAgICAgdGhpcy50aHJlYWQgPSB0aHJlYWQ7CisgICAgICAgIH0KKworICAgICAgICBOb2RlKFRocmVhZCB0aHJlYWQsIGludCB3YWl0U3RhdHVzKSB7IC8vIFVzZWQgYnkgQ29uZGl0aW9uCisgICAgICAgICAgICB0aGlzLndhaXRTdGF0dXMgPSB3YWl0U3RhdHVzOworICAgICAgICAgICAgdGhpcy50aHJlYWQgPSB0aHJlYWQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBIZWFkIG9mIHRoZSB3YWl0IHF1ZXVlLCBsYXppbHkgaW5pdGlhbGl6ZWQuICBFeGNlcHQgZm9yCisgICAgICogaW5pdGlhbGl6YXRpb24sIGl0IGlzIG1vZGlmaWVkIG9ubHkgdmlhIG1ldGhvZCBzZXRIZWFkLiAgTm90ZToKKyAgICAgKiBJZiBoZWFkIGV4aXN0cywgaXRzIHdhaXRTdGF0dXMgaXMgZ3VhcmFudGVlZCBub3QgdG8gYmUKKyAgICAgKiBDQU5DRUxMRUQuCisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgdm9sYXRpbGUgTm9kZSBoZWFkOworCisgICAgLyoqCisgICAgICogVGFpbCBvZiB0aGUgd2FpdCBxdWV1ZSwgbGF6aWx5IGluaXRpYWxpemVkLiAgTW9kaWZpZWQgb25seSB2aWEKKyAgICAgKiBtZXRob2QgZW5xIHRvIGFkZCBuZXcgd2FpdCBub2RlLgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IHZvbGF0aWxlIE5vZGUgdGFpbDsKKworICAgIC8qKgorICAgICAqIFRoZSBzeW5jaHJvbml6YXRpb24gc3RhdGUuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBpbnQgc3RhdGU7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHZhbHVlIG9mIHN5bmNocm9uaXphdGlvbiBzdGF0ZS4KKyAgICAgKiBUaGlzIG9wZXJhdGlvbiBoYXMgbWVtb3J5IHNlbWFudGljcyBvZiBhIDx0dD52b2xhdGlsZTwvdHQ+IHJlYWQuCisgICAgICogQHJldHVybiBjdXJyZW50IHN0YXRlIHZhbHVlCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIGludCBnZXRTdGF0ZSgpIHsKKyAgICAgICAgcmV0dXJuIHN0YXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHN5bmNocm9uaXphdGlvbiBzdGF0ZS4KKyAgICAgKiBUaGlzIG9wZXJhdGlvbiBoYXMgbWVtb3J5IHNlbWFudGljcyBvZiBhIDx0dD52b2xhdGlsZTwvdHQ+IHdyaXRlLgorICAgICAqIEBwYXJhbSBuZXdTdGF0ZSB0aGUgbmV3IHN0YXRlIHZhbHVlCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0U3RhdGUoaW50IG5ld1N0YXRlKSB7CisgICAgICAgIHN0YXRlID0gbmV3U3RhdGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBzZXRzIHN5bmNocm9uaXphdGlvbiBzdGF0ZSB0byB0aGUgZ2l2ZW4gdXBkYXRlZAorICAgICAqIHZhbHVlIGlmIHRoZSBjdXJyZW50IHN0YXRlIHZhbHVlIGVxdWFscyB0aGUgZXhwZWN0ZWQgdmFsdWUuCisgICAgICogVGhpcyBvcGVyYXRpb24gaGFzIG1lbW9yeSBzZW1hbnRpY3Mgb2YgYSA8dHQ+dm9sYXRpbGU8L3R0PiByZWFkCisgICAgICogYW5kIHdyaXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGV4cGVjdCB0aGUgZXhwZWN0ZWQgdmFsdWUKKyAgICAgKiBAcGFyYW0gdXBkYXRlIHRoZSBuZXcgdmFsdWUKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgc3VjY2Vzc2Z1bC4gRmFsc2UgcmV0dXJuIGluZGljYXRlcyB0aGF0IHRoZSBhY3R1YWwKKyAgICAgKiAgICAgICAgIHZhbHVlIHdhcyBub3QgZXF1YWwgdG8gdGhlIGV4cGVjdGVkIHZhbHVlLgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIGNvbXBhcmVBbmRTZXRTdGF0ZShpbnQgZXhwZWN0LCBpbnQgdXBkYXRlKSB7CisgICAgICAgIC8vIFNlZSBiZWxvdyBmb3IgaW50cmluc2ljcyBzZXR1cCB0byBzdXBwb3J0IHRoaXMKKyAgICAgICAgcmV0dXJuIHVuc2FmZS5jb21wYXJlQW5kU3dhcEludCh0aGlzLCBzdGF0ZU9mZnNldCwgZXhwZWN0LCB1cGRhdGUpOworICAgIH0KKworICAgIC8vIFF1ZXVpbmcgdXRpbGl0aWVzCisKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtYmVyIG9mIG5hbm9zZWNvbmRzIGZvciB3aGljaCBpdCBpcyBmYXN0ZXIgdG8gc3BpbgorICAgICAqIHJhdGhlciB0aGFuIHRvIHVzZSB0aW1lZCBwYXJrLiBBIHJvdWdoIGVzdGltYXRlIHN1ZmZpY2VzCisgICAgICogdG8gaW1wcm92ZSByZXNwb25zaXZlbmVzcyB3aXRoIHZlcnkgc2hvcnQgdGltZW91dHMuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGxvbmcgc3BpbkZvclRpbWVvdXRUaHJlc2hvbGQgPSAxMDAwTDsKKworICAgIC8qKgorICAgICAqIEluc2VydHMgbm9kZSBpbnRvIHF1ZXVlLCBpbml0aWFsaXppbmcgaWYgbmVjZXNzYXJ5LiBTZWUgcGljdHVyZSBhYm92ZS4KKyAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSB0byBpbnNlcnQKKyAgICAgKiBAcmV0dXJuIG5vZGUncyBwcmVkZWNlc3NvcgorICAgICAqLworICAgIHByaXZhdGUgTm9kZSBlbnEoZmluYWwgTm9kZSBub2RlKSB7CisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIE5vZGUgdCA9IHRhaWw7CisgICAgICAgICAgICBpZiAodCA9PSBudWxsKSB7IC8vIE11c3QgaW5pdGlhbGl6ZQorICAgICAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0SGVhZChuZXcgTm9kZSgpKSkKKyAgICAgICAgICAgICAgICAgICAgdGFpbCA9IGhlYWQ7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG5vZGUucHJldiA9IHQ7CisgICAgICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXRUYWlsKHQsIG5vZGUpKSB7CisgICAgICAgICAgICAgICAgICAgIHQubmV4dCA9IG5vZGU7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW5kIGVucXVldWVzIG5vZGUgZm9yIGN1cnJlbnQgdGhyZWFkIGFuZCBnaXZlbiBtb2RlLgorICAgICAqCisgICAgICogQHBhcmFtIG1vZGUgTm9kZS5FWENMVVNJVkUgZm9yIGV4Y2x1c2l2ZSwgTm9kZS5TSEFSRUQgZm9yIHNoYXJlZAorICAgICAqIEByZXR1cm4gdGhlIG5ldyBub2RlCisgICAgICovCisgICAgcHJpdmF0ZSBOb2RlIGFkZFdhaXRlcihOb2RlIG1vZGUpIHsKKyAgICAgICAgTm9kZSBub2RlID0gbmV3IE5vZGUoVGhyZWFkLmN1cnJlbnRUaHJlYWQoKSwgbW9kZSk7CisgICAgICAgIC8vIFRyeSB0aGUgZmFzdCBwYXRoIG9mIGVucTsgYmFja3VwIHRvIGZ1bGwgZW5xIG9uIGZhaWx1cmUKKyAgICAgICAgTm9kZSBwcmVkID0gdGFpbDsKKyAgICAgICAgaWYgKHByZWQgIT0gbnVsbCkgeworICAgICAgICAgICAgbm9kZS5wcmV2ID0gcHJlZDsKKyAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0VGFpbChwcmVkLCBub2RlKSkgeworICAgICAgICAgICAgICAgIHByZWQubmV4dCA9IG5vZGU7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZW5xKG5vZGUpOworICAgICAgICByZXR1cm4gbm9kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGhlYWQgb2YgcXVldWUgdG8gYmUgbm9kZSwgdGh1cyBkZXF1ZXVpbmcuIENhbGxlZCBvbmx5IGJ5CisgICAgICogYWNxdWlyZSBtZXRob2RzLiAgQWxzbyBudWxscyBvdXQgdW51c2VkIGZpZWxkcyBmb3Igc2FrZSBvZiBHQworICAgICAqIGFuZCB0byBzdXBwcmVzcyB1bm5lY2Vzc2FyeSBzaWduYWxzIGFuZCB0cmF2ZXJzYWxzLgorICAgICAqCisgICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0SGVhZChOb2RlIG5vZGUpIHsKKyAgICAgICAgaGVhZCA9IG5vZGU7CisgICAgICAgIG5vZGUudGhyZWFkID0gbnVsbDsKKyAgICAgICAgbm9kZS5wcmV2ID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXYWtlcyB1cCBub2RlJ3Mgc3VjY2Vzc29yLCBpZiBvbmUgZXhpc3RzLgorICAgICAqCisgICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgdW5wYXJrU3VjY2Vzc29yKE5vZGUgbm9kZSkgeworICAgICAgICAvKgorICAgICAgICAgKiBJZiBzdGF0dXMgaXMgbmVnYXRpdmUgKGkuZS4sIHBvc3NpYmx5IG5lZWRpbmcgc2lnbmFsKSB0cnkKKyAgICAgICAgICogdG8gY2xlYXIgaW4gYW50aWNpcGF0aW9uIG9mIHNpZ25hbGxpbmcuICBJdCBpcyBPSyBpZiB0aGlzCisgICAgICAgICAqIGZhaWxzIG9yIGlmIHN0YXR1cyBpcyBjaGFuZ2VkIGJ5IHdhaXRpbmcgdGhyZWFkLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IHdzID0gbm9kZS53YWl0U3RhdHVzOworICAgICAgICBpZiAod3MgPCAwKQorICAgICAgICAgICAgY29tcGFyZUFuZFNldFdhaXRTdGF0dXMobm9kZSwgd3MsIDApOworCisgICAgICAgIC8qCisgICAgICAgICAqIFRocmVhZCB0byB1bnBhcmsgaXMgaGVsZCBpbiBzdWNjZXNzb3IsIHdoaWNoIGlzIG5vcm1hbGx5CisgICAgICAgICAqIGp1c3QgdGhlIG5leHQgbm9kZS4gIEJ1dCBpZiBjYW5jZWxsZWQgb3IgYXBwYXJlbnRseSBudWxsLAorICAgICAgICAgKiB0cmF2ZXJzZSBiYWNrd2FyZHMgZnJvbSB0YWlsIHRvIGZpbmQgdGhlIGFjdHVhbAorICAgICAgICAgKiBub24tY2FuY2VsbGVkIHN1Y2Nlc3Nvci4KKyAgICAgICAgICovCisgICAgICAgIE5vZGUgcyA9IG5vZGUubmV4dDsKKyAgICAgICAgaWYgKHMgPT0gbnVsbCB8fCBzLndhaXRTdGF0dXMgPiAwKSB7CisgICAgICAgICAgICBzID0gbnVsbDsKKyAgICAgICAgICAgIGZvciAoTm9kZSB0ID0gdGFpbDsgdCAhPSBudWxsICYmIHQgIT0gbm9kZTsgdCA9IHQucHJldikKKyAgICAgICAgICAgICAgICBpZiAodC53YWl0U3RhdHVzIDw9IDApCisgICAgICAgICAgICAgICAgICAgIHMgPSB0OworICAgICAgICB9CisgICAgICAgIGlmIChzICE9IG51bGwpCisgICAgICAgICAgICBMb2NrU3VwcG9ydC51bnBhcmsocy50aHJlYWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbGVhc2UgYWN0aW9uIGZvciBzaGFyZWQgbW9kZSAtLSBzaWduYWwgc3VjY2Vzc29yIGFuZCBlbnN1cmUKKyAgICAgKiBwcm9wYWdhdGlvbi4gKE5vdGU6IEZvciBleGNsdXNpdmUgbW9kZSwgcmVsZWFzZSBqdXN0IGFtb3VudHMKKyAgICAgKiB0byBjYWxsaW5nIHVucGFya1N1Y2Nlc3NvciBvZiBoZWFkIGlmIGl0IG5lZWRzIHNpZ25hbC4pCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGRvUmVsZWFzZVNoYXJlZCgpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogRW5zdXJlIHRoYXQgYSByZWxlYXNlIHByb3BhZ2F0ZXMsIGV2ZW4gaWYgdGhlcmUgYXJlIG90aGVyCisgICAgICAgICAqIGluLXByb2dyZXNzIGFjcXVpcmVzL3JlbGVhc2VzLiAgVGhpcyBwcm9jZWVkcyBpbiB0aGUgdXN1YWwKKyAgICAgICAgICogd2F5IG9mIHRyeWluZyB0byB1bnBhcmtTdWNjZXNzb3Igb2YgaGVhZCBpZiBpdCBuZWVkcworICAgICAgICAgKiBzaWduYWwuIEJ1dCBpZiBpdCBkb2VzIG5vdCwgc3RhdHVzIGlzIHNldCB0byBQUk9QQUdBVEUgdG8KKyAgICAgICAgICogZW5zdXJlIHRoYXQgdXBvbiByZWxlYXNlLCBwcm9wYWdhdGlvbiBjb250aW51ZXMuCisgICAgICAgICAqIEFkZGl0aW9uYWxseSwgd2UgbXVzdCBsb29wIGluIGNhc2UgYSBuZXcgbm9kZSBpcyBhZGRlZAorICAgICAgICAgKiB3aGlsZSB3ZSBhcmUgZG9pbmcgdGhpcy4gQWxzbywgdW5saWtlIG90aGVyIHVzZXMgb2YKKyAgICAgICAgICogdW5wYXJrU3VjY2Vzc29yLCB3ZSBuZWVkIHRvIGtub3cgaWYgQ0FTIHRvIHJlc2V0IHN0YXR1cworICAgICAgICAgKiBmYWlscywgaWYgc28gcmVjaGVja2luZy4KKyAgICAgICAgICovCisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIE5vZGUgaCA9IGhlYWQ7CisgICAgICAgICAgICBpZiAoaCAhPSBudWxsICYmIGggIT0gdGFpbCkgeworICAgICAgICAgICAgICAgIGludCB3cyA9IGgud2FpdFN0YXR1czsKKyAgICAgICAgICAgICAgICBpZiAod3MgPT0gTm9kZS5TSUdOQUwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFjb21wYXJlQW5kU2V0V2FpdFN0YXR1cyhoLCBOb2RlLlNJR05BTCwgMCkpCisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsgICAgICAgICAgICAvLyBsb29wIHRvIHJlY2hlY2sgY2FzZXMKKyAgICAgICAgICAgICAgICAgICAgdW5wYXJrU3VjY2Vzc29yKGgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbHNlIGlmICh3cyA9PSAwICYmCisgICAgICAgICAgICAgICAgICAgICAgICAgIWNvbXBhcmVBbmRTZXRXYWl0U3RhdHVzKGgsIDAsIE5vZGUuUFJPUEFHQVRFKSkKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7ICAgICAgICAgICAgICAgIC8vIGxvb3Agb24gZmFpbGVkIENBUworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGggPT0gaGVhZCkgICAgICAgICAgICAgICAgICAgLy8gbG9vcCBpZiBoZWFkIGNoYW5nZWQKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgaGVhZCBvZiBxdWV1ZSwgYW5kIGNoZWNrcyBpZiBzdWNjZXNzb3IgbWF5IGJlIHdhaXRpbmcKKyAgICAgKiBpbiBzaGFyZWQgbW9kZSwgaWYgc28gcHJvcGFnYXRpbmcgaWYgZWl0aGVyIHByb3BhZ2F0ZSA+IDAgb3IKKyAgICAgKiBQUk9QQUdBVEUgc3RhdHVzIHdhcyBzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZQorICAgICAqIEBwYXJhbSBwcm9wYWdhdGUgdGhlIHJldHVybiB2YWx1ZSBmcm9tIGEgdHJ5QWNxdWlyZVNoYXJlZAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRIZWFkQW5kUHJvcGFnYXRlKE5vZGUgbm9kZSwgaW50IHByb3BhZ2F0ZSkgeworICAgICAgICBOb2RlIGggPSBoZWFkOyAvLyBSZWNvcmQgb2xkIGhlYWQgZm9yIGNoZWNrIGJlbG93CisgICAgICAgIHNldEhlYWQobm9kZSk7CisgICAgICAgIC8qCisgICAgICAgICAqIFRyeSB0byBzaWduYWwgbmV4dCBxdWV1ZWQgbm9kZSBpZjoKKyAgICAgICAgICogICBQcm9wYWdhdGlvbiB3YXMgaW5kaWNhdGVkIGJ5IGNhbGxlciwKKyAgICAgICAgICogICAgIG9yIHdhcyByZWNvcmRlZCAoYXMgaC53YWl0U3RhdHVzKSBieSBhIHByZXZpb3VzIG9wZXJhdGlvbgorICAgICAgICAgKiAgICAgKG5vdGU6IHRoaXMgdXNlcyBzaWduLWNoZWNrIG9mIHdhaXRTdGF0dXMgYmVjYXVzZQorICAgICAgICAgKiAgICAgIFBST1BBR0FURSBzdGF0dXMgbWF5IHRyYW5zaXRpb24gdG8gU0lHTkFMLikKKyAgICAgICAgICogYW5kCisgICAgICAgICAqICAgVGhlIG5leHQgbm9kZSBpcyB3YWl0aW5nIGluIHNoYXJlZCBtb2RlLAorICAgICAgICAgKiAgICAgb3Igd2UgZG9uJ3Qga25vdywgYmVjYXVzZSBpdCBhcHBlYXJzIG51bGwKKyAgICAgICAgICoKKyAgICAgICAgICogVGhlIGNvbnNlcnZhdGlzbSBpbiBib3RoIG9mIHRoZXNlIGNoZWNrcyBtYXkgY2F1c2UKKyAgICAgICAgICogdW5uZWNlc3Nhcnkgd2FrZS11cHMsIGJ1dCBvbmx5IHdoZW4gdGhlcmUgYXJlIG11bHRpcGxlCisgICAgICAgICAqIHJhY2luZyBhY3F1aXJlcy9yZWxlYXNlcywgc28gbW9zdCBuZWVkIHNpZ25hbHMgbm93IG9yIHNvb24KKyAgICAgICAgICogYW55d2F5LgorICAgICAgICAgKi8KKyAgICAgICAgaWYgKHByb3BhZ2F0ZSA+IDAgfHwgaCA9PSBudWxsIHx8IGgud2FpdFN0YXR1cyA8IDApIHsKKyAgICAgICAgICAgIE5vZGUgcyA9IG5vZGUubmV4dDsKKyAgICAgICAgICAgIGlmIChzID09IG51bGwgfHwgcy5pc1NoYXJlZCgpKQorICAgICAgICAgICAgICAgIGRvUmVsZWFzZVNoYXJlZCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gVXRpbGl0aWVzIGZvciB2YXJpb3VzIHZlcnNpb25zIG9mIGFjcXVpcmUKKworICAgIC8qKgorICAgICAqIENhbmNlbHMgYW4gb25nb2luZyBhdHRlbXB0IHRvIGFjcXVpcmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjYW5jZWxBY3F1aXJlKE5vZGUgbm9kZSkgeworICAgICAgICAvLyBJZ25vcmUgaWYgbm9kZSBkb2Vzbid0IGV4aXN0CisgICAgICAgIGlmIChub2RlID09IG51bGwpCisgICAgICAgICAgICByZXR1cm47CisKKyAgICAgICAgbm9kZS50aHJlYWQgPSBudWxsOworCisgICAgICAgIC8vIFNraXAgY2FuY2VsbGVkIHByZWRlY2Vzc29ycworICAgICAgICBOb2RlIHByZWQgPSBub2RlLnByZXY7CisgICAgICAgIHdoaWxlIChwcmVkLndhaXRTdGF0dXMgPiAwKQorICAgICAgICAgICAgbm9kZS5wcmV2ID0gcHJlZCA9IHByZWQucHJldjsKKworICAgICAgICAvLyBwcmVkTmV4dCBpcyB0aGUgYXBwYXJlbnQgbm9kZSB0byB1bnNwbGljZS4gQ0FTZXMgYmVsb3cgd2lsbAorICAgICAgICAvLyBmYWlsIGlmIG5vdCwgaW4gd2hpY2ggY2FzZSwgd2UgbG9zdCByYWNlIHZzIGFub3RoZXIgY2FuY2VsCisgICAgICAgIC8vIG9yIHNpZ25hbCwgc28gbm8gZnVydGhlciBhY3Rpb24gaXMgbmVjZXNzYXJ5LgorICAgICAgICBOb2RlIHByZWROZXh0ID0gcHJlZC5uZXh0OworCisgICAgICAgIC8vIENhbiB1c2UgdW5jb25kaXRpb25hbCB3cml0ZSBpbnN0ZWFkIG9mIENBUyBoZXJlLgorICAgICAgICAvLyBBZnRlciB0aGlzIGF0b21pYyBzdGVwLCBvdGhlciBOb2RlcyBjYW4gc2tpcCBwYXN0IHVzLgorICAgICAgICAvLyBCZWZvcmUsIHdlIGFyZSBmcmVlIG9mIGludGVyZmVyZW5jZSBmcm9tIG90aGVyIHRocmVhZHMuCisgICAgICAgIG5vZGUud2FpdFN0YXR1cyA9IE5vZGUuQ0FOQ0VMTEVEOworCisgICAgICAgIC8vIElmIHdlIGFyZSB0aGUgdGFpbCwgcmVtb3ZlIG91cnNlbHZlcy4KKyAgICAgICAgaWYgKG5vZGUgPT0gdGFpbCAmJiBjb21wYXJlQW5kU2V0VGFpbChub2RlLCBwcmVkKSkgeworICAgICAgICAgICAgY29tcGFyZUFuZFNldE5leHQocHJlZCwgcHJlZE5leHQsIG51bGwpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gSWYgc3VjY2Vzc29yIG5lZWRzIHNpZ25hbCwgdHJ5IHRvIHNldCBwcmVkJ3MgbmV4dC1saW5rCisgICAgICAgICAgICAvLyBzbyBpdCB3aWxsIGdldCBvbmUuIE90aGVyd2lzZSB3YWtlIGl0IHVwIHRvIHByb3BhZ2F0ZS4KKyAgICAgICAgICAgIGludCB3czsKKyAgICAgICAgICAgIGlmIChwcmVkICE9IGhlYWQgJiYKKyAgICAgICAgICAgICAgICAoKHdzID0gcHJlZC53YWl0U3RhdHVzKSA9PSBOb2RlLlNJR05BTCB8fAorICAgICAgICAgICAgICAgICAod3MgPD0gMCAmJiBjb21wYXJlQW5kU2V0V2FpdFN0YXR1cyhwcmVkLCB3cywgTm9kZS5TSUdOQUwpKSkgJiYKKyAgICAgICAgICAgICAgICBwcmVkLnRocmVhZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgTm9kZSBuZXh0ID0gbm9kZS5uZXh0OworICAgICAgICAgICAgICAgIGlmIChuZXh0ICE9IG51bGwgJiYgbmV4dC53YWl0U3RhdHVzIDw9IDApCisgICAgICAgICAgICAgICAgICAgIGNvbXBhcmVBbmRTZXROZXh0KHByZWQsIHByZWROZXh0LCBuZXh0KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdW5wYXJrU3VjY2Vzc29yKG5vZGUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBub2RlLm5leHQgPSBub2RlOyAvLyBoZWxwIEdDCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgYW5kIHVwZGF0ZXMgc3RhdHVzIGZvciBhIG5vZGUgdGhhdCBmYWlsZWQgdG8gYWNxdWlyZS4KKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhyZWFkIHNob3VsZCBibG9jay4gVGhpcyBpcyB0aGUgbWFpbiBzaWduYWwKKyAgICAgKiBjb250cm9sIGluIGFsbCBhY3F1aXJlIGxvb3BzLiAgUmVxdWlyZXMgdGhhdCBwcmVkID09IG5vZGUucHJldgorICAgICAqCisgICAgICogQHBhcmFtIHByZWQgbm9kZSdzIHByZWRlY2Vzc29yIGhvbGRpbmcgc3RhdHVzCisgICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aHJlYWQgc2hvdWxkIGJsb2NrCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBzaG91bGRQYXJrQWZ0ZXJGYWlsZWRBY3F1aXJlKE5vZGUgcHJlZCwgTm9kZSBub2RlKSB7CisgICAgICAgIGludCB3cyA9IHByZWQud2FpdFN0YXR1czsKKyAgICAgICAgaWYgKHdzID09IE5vZGUuU0lHTkFMKQorICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFRoaXMgbm9kZSBoYXMgYWxyZWFkeSBzZXQgc3RhdHVzIGFza2luZyBhIHJlbGVhc2UKKyAgICAgICAgICAgICAqIHRvIHNpZ25hbCBpdCwgc28gaXQgY2FuIHNhZmVseSBwYXJrLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgaWYgKHdzID4gMCkgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFByZWRlY2Vzc29yIHdhcyBjYW5jZWxsZWQuIFNraXAgb3ZlciBwcmVkZWNlc3NvcnMgYW5kCisgICAgICAgICAgICAgKiBpbmRpY2F0ZSByZXRyeS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIG5vZGUucHJldiA9IHByZWQgPSBwcmVkLnByZXY7CisgICAgICAgICAgICB9IHdoaWxlIChwcmVkLndhaXRTdGF0dXMgPiAwKTsKKyAgICAgICAgICAgIHByZWQubmV4dCA9IG5vZGU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogd2FpdFN0YXR1cyBtdXN0IGJlIDAgb3IgUFJPUEFHQVRFLiAgSW5kaWNhdGUgdGhhdCB3ZQorICAgICAgICAgICAgICogbmVlZCBhIHNpZ25hbCwgYnV0IGRvbid0IHBhcmsgeWV0LiAgQ2FsbGVyIHdpbGwgbmVlZCB0bworICAgICAgICAgICAgICogcmV0cnkgdG8gbWFrZSBzdXJlIGl0IGNhbm5vdCBhY3F1aXJlIGJlZm9yZSBwYXJraW5nLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBjb21wYXJlQW5kU2V0V2FpdFN0YXR1cyhwcmVkLCB3cywgTm9kZS5TSUdOQUwpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QgdG8gaW50ZXJydXB0IGN1cnJlbnQgdGhyZWFkLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgc2VsZkludGVycnVwdCgpIHsKKyAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5pbnRlcnJ1cHQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QgdG8gcGFyayBhbmQgdGhlbiBjaGVjayBpZiBpbnRlcnJ1cHRlZAorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgaW50ZXJydXB0ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gcGFya0FuZENoZWNrSW50ZXJydXB0KCkgeworICAgICAgICBMb2NrU3VwcG9ydC5wYXJrKHRoaXMpOworICAgICAgICByZXR1cm4gVGhyZWFkLmludGVycnVwdGVkKCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBWYXJpb3VzIGZsYXZvcnMgb2YgYWNxdWlyZSwgdmFyeWluZyBpbiBleGNsdXNpdmUvc2hhcmVkIGFuZAorICAgICAqIGNvbnRyb2wgbW9kZXMuICBFYWNoIGlzIG1vc3RseSB0aGUgc2FtZSwgYnV0IGFubm95aW5nbHkKKyAgICAgKiBkaWZmZXJlbnQuICBPbmx5IGEgbGl0dGxlIGJpdCBvZiBmYWN0b3JpbmcgaXMgcG9zc2libGUgZHVlIHRvCisgICAgICogaW50ZXJhY3Rpb25zIG9mIGV4Y2VwdGlvbiBtZWNoYW5pY3MgKGluY2x1ZGluZyBlbnN1cmluZyB0aGF0IHdlCisgICAgICogY2FuY2VsIGlmIHRyeUFjcXVpcmUgdGhyb3dzIGV4Y2VwdGlvbikgYW5kIG90aGVyIGNvbnRyb2wsIGF0CisgICAgICogbGVhc3Qgbm90IHdpdGhvdXQgaHVydGluZyBwZXJmb3JtYW5jZSB0b28gbXVjaC4KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIEFjcXVpcmVzIGluIGV4Y2x1c2l2ZSB1bmludGVycnVwdGlibGUgbW9kZSBmb3IgdGhyZWFkIGFscmVhZHkgaW4KKyAgICAgKiBxdWV1ZS4gVXNlZCBieSBjb25kaXRpb24gd2FpdCBtZXRob2RzIGFzIHdlbGwgYXMgYWNxdWlyZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlCisgICAgICogQHBhcmFtIGFyZyB0aGUgYWNxdWlyZSBhcmd1bWVudAorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGludGVycnVwdGVkIHdoaWxlIHdhaXRpbmcKKyAgICAgKi8KKyAgICBmaW5hbCBib29sZWFuIGFjcXVpcmVRdWV1ZWQoZmluYWwgTm9kZSBub2RlLCBpbnQgYXJnKSB7CisgICAgICAgIGJvb2xlYW4gZmFpbGVkID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJvb2xlYW4gaW50ZXJydXB0ZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBOb2RlIHAgPSBub2RlLnByZWRlY2Vzc29yKCk7CisgICAgICAgICAgICAgICAgaWYgKHAgPT0gaGVhZCAmJiB0cnlBY3F1aXJlKGFyZykpIHsKKyAgICAgICAgICAgICAgICAgICAgc2V0SGVhZChub2RlKTsKKyAgICAgICAgICAgICAgICAgICAgcC5uZXh0ID0gbnVsbDsgLy8gaGVscCBHQworICAgICAgICAgICAgICAgICAgICBmYWlsZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGludGVycnVwdGVkOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoc2hvdWxkUGFya0FmdGVyRmFpbGVkQWNxdWlyZShwLCBub2RlKSAmJgorICAgICAgICAgICAgICAgICAgICBwYXJrQW5kQ2hlY2tJbnRlcnJ1cHQoKSkKKyAgICAgICAgICAgICAgICAgICAgaW50ZXJydXB0ZWQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGZhaWxlZCkKKyAgICAgICAgICAgICAgICBjYW5jZWxBY3F1aXJlKG5vZGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQWNxdWlyZXMgaW4gZXhjbHVzaXZlIGludGVycnVwdGlibGUgbW9kZS4KKyAgICAgKiBAcGFyYW0gYXJnIHRoZSBhY3F1aXJlIGFyZ3VtZW50CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGRvQWNxdWlyZUludGVycnVwdGlibHkoaW50IGFyZykKKyAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgTm9kZSBub2RlID0gYWRkV2FpdGVyKE5vZGUuRVhDTFVTSVZFKTsKKyAgICAgICAgYm9vbGVhbiBmYWlsZWQgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgcCA9IG5vZGUucHJlZGVjZXNzb3IoKTsKKyAgICAgICAgICAgICAgICBpZiAocCA9PSBoZWFkICYmIHRyeUFjcXVpcmUoYXJnKSkgeworICAgICAgICAgICAgICAgICAgICBzZXRIZWFkKG5vZGUpOworICAgICAgICAgICAgICAgICAgICBwLm5leHQgPSBudWxsOyAvLyBoZWxwIEdDCisgICAgICAgICAgICAgICAgICAgIGZhaWxlZCA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChzaG91bGRQYXJrQWZ0ZXJGYWlsZWRBY3F1aXJlKHAsIG5vZGUpICYmCisgICAgICAgICAgICAgICAgICAgIHBhcmtBbmRDaGVja0ludGVycnVwdCgpKQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJydXB0ZWRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChmYWlsZWQpCisgICAgICAgICAgICAgICAgY2FuY2VsQWNxdWlyZShub2RlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFjcXVpcmVzIGluIGV4Y2x1c2l2ZSB0aW1lZCBtb2RlLgorICAgICAqCisgICAgICogQHBhcmFtIGFyZyB0aGUgYWNxdWlyZSBhcmd1bWVudAorICAgICAqIEBwYXJhbSBuYW5vc1RpbWVvdXQgbWF4IHdhaXQgdGltZQorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGFjcXVpcmVkCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGRvQWNxdWlyZU5hbm9zKGludCBhcmcsIGxvbmcgbmFub3NUaW1lb3V0KQorICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBsb25nIGxhc3RUaW1lID0gU3lzdGVtLm5hbm9UaW1lKCk7CisgICAgICAgIGZpbmFsIE5vZGUgbm9kZSA9IGFkZFdhaXRlcihOb2RlLkVYQ0xVU0lWRSk7CisgICAgICAgIGJvb2xlYW4gZmFpbGVkID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBOb2RlIHAgPSBub2RlLnByZWRlY2Vzc29yKCk7CisgICAgICAgICAgICAgICAgaWYgKHAgPT0gaGVhZCAmJiB0cnlBY3F1aXJlKGFyZykpIHsKKyAgICAgICAgICAgICAgICAgICAgc2V0SGVhZChub2RlKTsKKyAgICAgICAgICAgICAgICAgICAgcC5uZXh0ID0gbnVsbDsgLy8gaGVscCBHQworICAgICAgICAgICAgICAgICAgICBmYWlsZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChuYW5vc1RpbWVvdXQgPD0gMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIGlmIChzaG91bGRQYXJrQWZ0ZXJGYWlsZWRBY3F1aXJlKHAsIG5vZGUpICYmCisgICAgICAgICAgICAgICAgICAgIG5hbm9zVGltZW91dCA+IHNwaW5Gb3JUaW1lb3V0VGhyZXNob2xkKQorICAgICAgICAgICAgICAgICAgICBMb2NrU3VwcG9ydC5wYXJrTmFub3ModGhpcywgbmFub3NUaW1lb3V0KTsKKyAgICAgICAgICAgICAgICBsb25nIG5vdyA9IFN5c3RlbS5uYW5vVGltZSgpOworICAgICAgICAgICAgICAgIG5hbm9zVGltZW91dCAtPSBub3cgLSBsYXN0VGltZTsKKyAgICAgICAgICAgICAgICBsYXN0VGltZSA9IG5vdzsKKyAgICAgICAgICAgICAgICBpZiAoVGhyZWFkLmludGVycnVwdGVkKCkpCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGZhaWxlZCkKKyAgICAgICAgICAgICAgICBjYW5jZWxBY3F1aXJlKG5vZGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQWNxdWlyZXMgaW4gc2hhcmVkIHVuaW50ZXJydXB0aWJsZSBtb2RlLgorICAgICAqIEBwYXJhbSBhcmcgdGhlIGFjcXVpcmUgYXJndW1lbnQKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZG9BY3F1aXJlU2hhcmVkKGludCBhcmcpIHsKKyAgICAgICAgZmluYWwgTm9kZSBub2RlID0gYWRkV2FpdGVyKE5vZGUuU0hBUkVEKTsKKyAgICAgICAgYm9vbGVhbiBmYWlsZWQgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYm9vbGVhbiBpbnRlcnJ1cHRlZCA9IGZhbHNlOworICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgcCA9IG5vZGUucHJlZGVjZXNzb3IoKTsKKyAgICAgICAgICAgICAgICBpZiAocCA9PSBoZWFkKSB7CisgICAgICAgICAgICAgICAgICAgIGludCByID0gdHJ5QWNxdWlyZVNoYXJlZChhcmcpOworICAgICAgICAgICAgICAgICAgICBpZiAociA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzZXRIZWFkQW5kUHJvcGFnYXRlKG5vZGUsIHIpOworICAgICAgICAgICAgICAgICAgICAgICAgcC5uZXh0ID0gbnVsbDsgLy8gaGVscCBHQworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGludGVycnVwdGVkKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGZJbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWxlZCA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChzaG91bGRQYXJrQWZ0ZXJGYWlsZWRBY3F1aXJlKHAsIG5vZGUpICYmCisgICAgICAgICAgICAgICAgICAgIHBhcmtBbmRDaGVja0ludGVycnVwdCgpKQorICAgICAgICAgICAgICAgICAgICBpbnRlcnJ1cHRlZCA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoZmFpbGVkKQorICAgICAgICAgICAgICAgIGNhbmNlbEFjcXVpcmUobm9kZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBY3F1aXJlcyBpbiBzaGFyZWQgaW50ZXJydXB0aWJsZSBtb2RlLgorICAgICAqIEBwYXJhbSBhcmcgdGhlIGFjcXVpcmUgYXJndW1lbnQKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZG9BY3F1aXJlU2hhcmVkSW50ZXJydXB0aWJseShpbnQgYXJnKQorICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBmaW5hbCBOb2RlIG5vZGUgPSBhZGRXYWl0ZXIoTm9kZS5TSEFSRUQpOworICAgICAgICBib29sZWFuIGZhaWxlZCA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgZmluYWwgTm9kZSBwID0gbm9kZS5wcmVkZWNlc3NvcigpOworICAgICAgICAgICAgICAgIGlmIChwID09IGhlYWQpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHIgPSB0cnlBY3F1aXJlU2hhcmVkKGFyZyk7CisgICAgICAgICAgICAgICAgICAgIGlmIChyID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNldEhlYWRBbmRQcm9wYWdhdGUobm9kZSwgcik7CisgICAgICAgICAgICAgICAgICAgICAgICBwLm5leHQgPSBudWxsOyAvLyBoZWxwIEdDCisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoc2hvdWxkUGFya0FmdGVyRmFpbGVkQWNxdWlyZShwLCBub2RlKSAmJgorICAgICAgICAgICAgICAgICAgICBwYXJrQW5kQ2hlY2tJbnRlcnJ1cHQoKSkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoZmFpbGVkKQorICAgICAgICAgICAgICAgIGNhbmNlbEFjcXVpcmUobm9kZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBY3F1aXJlcyBpbiBzaGFyZWQgdGltZWQgbW9kZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmcgdGhlIGFjcXVpcmUgYXJndW1lbnQKKyAgICAgKiBAcGFyYW0gbmFub3NUaW1lb3V0IG1heCB3YWl0IHRpbWUKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBhY3F1aXJlZAorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBkb0FjcXVpcmVTaGFyZWROYW5vcyhpbnQgYXJnLCBsb25nIG5hbm9zVGltZW91dCkKKyAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKworICAgICAgICBsb25nIGxhc3RUaW1lID0gU3lzdGVtLm5hbm9UaW1lKCk7CisgICAgICAgIGZpbmFsIE5vZGUgbm9kZSA9IGFkZFdhaXRlcihOb2RlLlNIQVJFRCk7CisgICAgICAgIGJvb2xlYW4gZmFpbGVkID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBOb2RlIHAgPSBub2RlLnByZWRlY2Vzc29yKCk7CisgICAgICAgICAgICAgICAgaWYgKHAgPT0gaGVhZCkgeworICAgICAgICAgICAgICAgICAgICBpbnQgciA9IHRyeUFjcXVpcmVTaGFyZWQoYXJnKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHIgPj0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgc2V0SGVhZEFuZFByb3BhZ2F0ZShub2RlLCByKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHAubmV4dCA9IG51bGw7IC8vIGhlbHAgR0MKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWxlZCA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKG5hbm9zVGltZW91dCA8PSAwKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgaWYgKHNob3VsZFBhcmtBZnRlckZhaWxlZEFjcXVpcmUocCwgbm9kZSkgJiYKKyAgICAgICAgICAgICAgICAgICAgbmFub3NUaW1lb3V0ID4gc3BpbkZvclRpbWVvdXRUaHJlc2hvbGQpCisgICAgICAgICAgICAgICAgICAgIExvY2tTdXBwb3J0LnBhcmtOYW5vcyh0aGlzLCBuYW5vc1RpbWVvdXQpOworICAgICAgICAgICAgICAgIGxvbmcgbm93ID0gU3lzdGVtLm5hbm9UaW1lKCk7CisgICAgICAgICAgICAgICAgbmFub3NUaW1lb3V0IC09IG5vdyAtIGxhc3RUaW1lOworICAgICAgICAgICAgICAgIGxhc3RUaW1lID0gbm93OworICAgICAgICAgICAgICAgIGlmIChUaHJlYWQuaW50ZXJydXB0ZWQoKSkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoZmFpbGVkKQorICAgICAgICAgICAgICAgIGNhbmNlbEFjcXVpcmUobm9kZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBNYWluIGV4cG9ydGVkIG1ldGhvZHMKKworICAgIC8qKgorICAgICAqIEF0dGVtcHRzIHRvIGFjcXVpcmUgaW4gZXhjbHVzaXZlIG1vZGUuIFRoaXMgbWV0aG9kIHNob3VsZCBxdWVyeQorICAgICAqIGlmIHRoZSBzdGF0ZSBvZiB0aGUgb2JqZWN0IHBlcm1pdHMgaXQgdG8gYmUgYWNxdWlyZWQgaW4gdGhlCisgICAgICogZXhjbHVzaXZlIG1vZGUsIGFuZCBpZiBzbyB0byBhY3F1aXJlIGl0LgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgYWx3YXlzIGludm9rZWQgYnkgdGhlIHRocmVhZCBwZXJmb3JtaW5nCisgICAgICogYWNxdWlyZS4gIElmIHRoaXMgbWV0aG9kIHJlcG9ydHMgZmFpbHVyZSwgdGhlIGFjcXVpcmUgbWV0aG9kCisgICAgICogbWF5IHF1ZXVlIHRoZSB0aHJlYWQsIGlmIGl0IGlzIG5vdCBhbHJlYWR5IHF1ZXVlZCwgdW50aWwgaXQgaXMKKyAgICAgKiBzaWduYWxsZWQgYnkgYSByZWxlYXNlIGZyb20gc29tZSBvdGhlciB0aHJlYWQuIFRoaXMgY2FuIGJlIHVzZWQKKyAgICAgKiB0byBpbXBsZW1lbnQgbWV0aG9kIHtAbGluayBMb2NrI3RyeUxvY2soKX0uCisgICAgICoKKyAgICAgKiA8cD5UaGUgZGVmYXVsdAorICAgICAqIGltcGxlbWVudGF0aW9uIHRocm93cyB7QGxpbmsgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259LgorICAgICAqCisgICAgICogQHBhcmFtIGFyZyB0aGUgYWNxdWlyZSBhcmd1bWVudC4gVGhpcyB2YWx1ZSBpcyBhbHdheXMgdGhlIG9uZQorICAgICAqICAgICAgICBwYXNzZWQgdG8gYW4gYWNxdWlyZSBtZXRob2QsIG9yIGlzIHRoZSB2YWx1ZSBzYXZlZCBvbiBlbnRyeQorICAgICAqICAgICAgICB0byBhIGNvbmRpdGlvbiB3YWl0LiAgVGhlIHZhbHVlIGlzIG90aGVyd2lzZSB1bmludGVycHJldGVkCisgICAgICogICAgICAgIGFuZCBjYW4gcmVwcmVzZW50IGFueXRoaW5nIHlvdSBsaWtlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHN1Y2Nlc3NmdWwuIFVwb24gc3VjY2VzcywgdGhpcyBvYmplY3QgaGFzCisgICAgICogICAgICAgICBiZWVuIGFjcXVpcmVkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbiBpZiBhY3F1aXJpbmcgd291bGQgcGxhY2UgdGhpcworICAgICAqICAgICAgICAgc3luY2hyb25pemVyIGluIGFuIGlsbGVnYWwgc3RhdGUuIFRoaXMgZXhjZXB0aW9uIG11c3QgYmUKKyAgICAgKiAgICAgICAgIHRocm93biBpbiBhIGNvbnNpc3RlbnQgZmFzaGlvbiBmb3Igc3luY2hyb25pemF0aW9uIHRvIHdvcmsKKyAgICAgKiAgICAgICAgIGNvcnJlY3RseS4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIGV4Y2x1c2l2ZSBtb2RlIGlzIG5vdCBzdXBwb3J0ZWQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiB0cnlBY3F1aXJlKGludCBhcmcpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gc2V0IHRoZSBzdGF0ZSB0byByZWZsZWN0IGEgcmVsZWFzZSBpbiBleGNsdXNpdmUKKyAgICAgKiBtb2RlLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgYWx3YXlzIGludm9rZWQgYnkgdGhlIHRocmVhZCBwZXJmb3JtaW5nIHJlbGVhc2UuCisgICAgICoKKyAgICAgKiA8cD5UaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB0aHJvd3MKKyAgICAgKiB7QGxpbmsgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259LgorICAgICAqCisgICAgICogQHBhcmFtIGFyZyB0aGUgcmVsZWFzZSBhcmd1bWVudC4gVGhpcyB2YWx1ZSBpcyBhbHdheXMgdGhlIG9uZQorICAgICAqICAgICAgICBwYXNzZWQgdG8gYSByZWxlYXNlIG1ldGhvZCwgb3IgdGhlIGN1cnJlbnQgc3RhdGUgdmFsdWUgdXBvbgorICAgICAqICAgICAgICBlbnRyeSB0byBhIGNvbmRpdGlvbiB3YWl0LiAgVGhlIHZhbHVlIGlzIG90aGVyd2lzZQorICAgICAqICAgICAgICB1bmludGVycHJldGVkIGFuZCBjYW4gcmVwcmVzZW50IGFueXRoaW5nIHlvdSBsaWtlLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgb2JqZWN0IGlzIG5vdyBpbiBhIGZ1bGx5IHJlbGVhc2VkCisgICAgICogICAgICAgICBzdGF0ZSwgc28gdGhhdCBhbnkgd2FpdGluZyB0aHJlYWRzIG1heSBhdHRlbXB0IHRvIGFjcXVpcmU7CisgICAgICogICAgICAgICBhbmQge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIHJlbGVhc2luZyB3b3VsZCBwbGFjZSB0aGlzCisgICAgICogICAgICAgICBzeW5jaHJvbml6ZXIgaW4gYW4gaWxsZWdhbCBzdGF0ZS4gVGhpcyBleGNlcHRpb24gbXVzdCBiZQorICAgICAqICAgICAgICAgdGhyb3duIGluIGEgY29uc2lzdGVudCBmYXNoaW9uIGZvciBzeW5jaHJvbml6YXRpb24gdG8gd29yaworICAgICAqICAgICAgICAgY29ycmVjdGx5LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgZXhjbHVzaXZlIG1vZGUgaXMgbm90IHN1cHBvcnRlZAorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIHRyeVJlbGVhc2UoaW50IGFyZykgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdHRlbXB0cyB0byBhY3F1aXJlIGluIHNoYXJlZCBtb2RlLiBUaGlzIG1ldGhvZCBzaG91bGQgcXVlcnkgaWYKKyAgICAgKiB0aGUgc3RhdGUgb2YgdGhlIG9iamVjdCBwZXJtaXRzIGl0IHRvIGJlIGFjcXVpcmVkIGluIHRoZSBzaGFyZWQKKyAgICAgKiBtb2RlLCBhbmQgaWYgc28gdG8gYWNxdWlyZSBpdC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGFsd2F5cyBpbnZva2VkIGJ5IHRoZSB0aHJlYWQgcGVyZm9ybWluZworICAgICAqIGFjcXVpcmUuICBJZiB0aGlzIG1ldGhvZCByZXBvcnRzIGZhaWx1cmUsIHRoZSBhY3F1aXJlIG1ldGhvZAorICAgICAqIG1heSBxdWV1ZSB0aGUgdGhyZWFkLCBpZiBpdCBpcyBub3QgYWxyZWFkeSBxdWV1ZWQsIHVudGlsIGl0IGlzCisgICAgICogc2lnbmFsbGVkIGJ5IGEgcmVsZWFzZSBmcm9tIHNvbWUgb3RoZXIgdGhyZWFkLgorICAgICAqCisgICAgICogPHA+VGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gdGhyb3dzIHtAbGluaworICAgICAqIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmcgdGhlIGFjcXVpcmUgYXJndW1lbnQuIFRoaXMgdmFsdWUgaXMgYWx3YXlzIHRoZSBvbmUKKyAgICAgKiAgICAgICAgcGFzc2VkIHRvIGFuIGFjcXVpcmUgbWV0aG9kLCBvciBpcyB0aGUgdmFsdWUgc2F2ZWQgb24gZW50cnkKKyAgICAgKiAgICAgICAgdG8gYSBjb25kaXRpb24gd2FpdC4gIFRoZSB2YWx1ZSBpcyBvdGhlcndpc2UgdW5pbnRlcnByZXRlZAorICAgICAqICAgICAgICBhbmQgY2FuIHJlcHJlc2VudCBhbnl0aGluZyB5b3UgbGlrZS4KKyAgICAgKiBAcmV0dXJuIGEgbmVnYXRpdmUgdmFsdWUgb24gZmFpbHVyZTsgemVybyBpZiBhY3F1aXNpdGlvbiBpbiBzaGFyZWQKKyAgICAgKiAgICAgICAgIG1vZGUgc3VjY2VlZGVkIGJ1dCBubyBzdWJzZXF1ZW50IHNoYXJlZC1tb2RlIGFjcXVpcmUgY2FuCisgICAgICogICAgICAgICBzdWNjZWVkOyBhbmQgYSBwb3NpdGl2ZSB2YWx1ZSBpZiBhY3F1aXNpdGlvbiBpbiBzaGFyZWQKKyAgICAgKiAgICAgICAgIG1vZGUgc3VjY2VlZGVkIGFuZCBzdWJzZXF1ZW50IHNoYXJlZC1tb2RlIGFjcXVpcmVzIG1pZ2h0CisgICAgICogICAgICAgICBhbHNvIHN1Y2NlZWQsIGluIHdoaWNoIGNhc2UgYSBzdWJzZXF1ZW50IHdhaXRpbmcgdGhyZWFkCisgICAgICogICAgICAgICBtdXN0IGNoZWNrIGF2YWlsYWJpbGl0eS4gKFN1cHBvcnQgZm9yIHRocmVlIGRpZmZlcmVudAorICAgICAqICAgICAgICAgcmV0dXJuIHZhbHVlcyBlbmFibGVzIHRoaXMgbWV0aG9kIHRvIGJlIHVzZWQgaW4gY29udGV4dHMKKyAgICAgKiAgICAgICAgIHdoZXJlIGFjcXVpcmVzIG9ubHkgc29tZXRpbWVzIGFjdCBleGNsdXNpdmVseS4pICBVcG9uCisgICAgICogICAgICAgICBzdWNjZXNzLCB0aGlzIG9iamVjdCBoYXMgYmVlbiBhY3F1aXJlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gaWYgYWNxdWlyaW5nIHdvdWxkIHBsYWNlIHRoaXMKKyAgICAgKiAgICAgICAgIHN5bmNocm9uaXplciBpbiBhbiBpbGxlZ2FsIHN0YXRlLiBUaGlzIGV4Y2VwdGlvbiBtdXN0IGJlCisgICAgICogICAgICAgICB0aHJvd24gaW4gYSBjb25zaXN0ZW50IGZhc2hpb24gZm9yIHN5bmNocm9uaXphdGlvbiB0byB3b3JrCisgICAgICogICAgICAgICBjb3JyZWN0bHkuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiBzaGFyZWQgbW9kZSBpcyBub3Qgc3VwcG9ydGVkCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCB0cnlBY3F1aXJlU2hhcmVkKGludCBhcmcpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gc2V0IHRoZSBzdGF0ZSB0byByZWZsZWN0IGEgcmVsZWFzZSBpbiBzaGFyZWQgbW9kZS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGFsd2F5cyBpbnZva2VkIGJ5IHRoZSB0aHJlYWQgcGVyZm9ybWluZyByZWxlYXNlLgorICAgICAqCisgICAgICogPHA+VGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gdGhyb3dzCisgICAgICoge0BsaW5rIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmcgdGhlIHJlbGVhc2UgYXJndW1lbnQuIFRoaXMgdmFsdWUgaXMgYWx3YXlzIHRoZSBvbmUKKyAgICAgKiAgICAgICAgcGFzc2VkIHRvIGEgcmVsZWFzZSBtZXRob2QsIG9yIHRoZSBjdXJyZW50IHN0YXRlIHZhbHVlIHVwb24KKyAgICAgKiAgICAgICAgZW50cnkgdG8gYSBjb25kaXRpb24gd2FpdC4gIFRoZSB2YWx1ZSBpcyBvdGhlcndpc2UKKyAgICAgKiAgICAgICAgdW5pbnRlcnByZXRlZCBhbmQgY2FuIHJlcHJlc2VudCBhbnl0aGluZyB5b3UgbGlrZS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHJlbGVhc2Ugb2Ygc2hhcmVkIG1vZGUgbWF5IHBlcm1pdCBhCisgICAgICogICAgICAgICB3YWl0aW5nIGFjcXVpcmUgKHNoYXJlZCBvciBleGNsdXNpdmUpIHRvIHN1Y2NlZWQ7IGFuZAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gaWYgcmVsZWFzaW5nIHdvdWxkIHBsYWNlIHRoaXMKKyAgICAgKiAgICAgICAgIHN5bmNocm9uaXplciBpbiBhbiBpbGxlZ2FsIHN0YXRlLiBUaGlzIGV4Y2VwdGlvbiBtdXN0IGJlCisgICAgICogICAgICAgICB0aHJvd24gaW4gYSBjb25zaXN0ZW50IGZhc2hpb24gZm9yIHN5bmNocm9uaXphdGlvbiB0byB3b3JrCisgICAgICogICAgICAgICBjb3JyZWN0bHkuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiBzaGFyZWQgbW9kZSBpcyBub3Qgc3VwcG9ydGVkCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gdHJ5UmVsZWFzZVNoYXJlZChpbnQgYXJnKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHN5bmNocm9uaXphdGlvbiBpcyBoZWxkIGV4Y2x1c2l2ZWx5IHdpdGgKKyAgICAgKiByZXNwZWN0IHRvIHRoZSBjdXJyZW50IChjYWxsaW5nKSB0aHJlYWQuICBUaGlzIG1ldGhvZCBpcyBpbnZva2VkCisgICAgICogdXBvbiBlYWNoIGNhbGwgdG8gYSBub24td2FpdGluZyB7QGxpbmsgQ29uZGl0aW9uT2JqZWN0fSBtZXRob2QuCisgICAgICogKFdhaXRpbmcgbWV0aG9kcyBpbnN0ZWFkIGludm9rZSB7QGxpbmsgI3JlbGVhc2V9LikKKyAgICAgKgorICAgICAqIDxwPlRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHRocm93cyB7QGxpbmsKKyAgICAgKiBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0uIFRoaXMgbWV0aG9kIGlzIGludm9rZWQKKyAgICAgKiBpbnRlcm5hbGx5IG9ubHkgd2l0aGluIHtAbGluayBDb25kaXRpb25PYmplY3R9IG1ldGhvZHMsIHNvIG5lZWQKKyAgICAgKiBub3QgYmUgZGVmaW5lZCBpZiBjb25kaXRpb25zIGFyZSBub3QgdXNlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHN5bmNocm9uaXphdGlvbiBpcyBoZWxkIGV4Y2x1c2l2ZWx5OworICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIGNvbmRpdGlvbnMgYXJlIG5vdCBzdXBwb3J0ZWQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0hlbGRFeGNsdXNpdmVseSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWNxdWlyZXMgaW4gZXhjbHVzaXZlIG1vZGUsIGlnbm9yaW5nIGludGVycnVwdHMuICBJbXBsZW1lbnRlZAorICAgICAqIGJ5IGludm9raW5nIGF0IGxlYXN0IG9uY2Uge0BsaW5rICN0cnlBY3F1aXJlfSwKKyAgICAgKiByZXR1cm5pbmcgb24gc3VjY2Vzcy4gIE90aGVyd2lzZSB0aGUgdGhyZWFkIGlzIHF1ZXVlZCwgcG9zc2libHkKKyAgICAgKiByZXBlYXRlZGx5IGJsb2NraW5nIGFuZCB1bmJsb2NraW5nLCBpbnZva2luZyB7QGxpbmsKKyAgICAgKiAjdHJ5QWNxdWlyZX0gdW50aWwgc3VjY2Vzcy4gIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkCisgICAgICogdG8gaW1wbGVtZW50IG1ldGhvZCB7QGxpbmsgTG9jayNsb2NrfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmcgdGhlIGFjcXVpcmUgYXJndW1lbnQuICBUaGlzIHZhbHVlIGlzIGNvbnZleWVkIHRvCisgICAgICogICAgICAgIHtAbGluayAjdHJ5QWNxdWlyZX0gYnV0IGlzIG90aGVyd2lzZSB1bmludGVycHJldGVkIGFuZAorICAgICAqICAgICAgICBjYW4gcmVwcmVzZW50IGFueXRoaW5nIHlvdSBsaWtlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGFjcXVpcmUoaW50IGFyZykgeworICAgICAgICBpZiAoIXRyeUFjcXVpcmUoYXJnKSAmJgorICAgICAgICAgICAgYWNxdWlyZVF1ZXVlZChhZGRXYWl0ZXIoTm9kZS5FWENMVVNJVkUpLCBhcmcpKQorICAgICAgICAgICAgc2VsZkludGVycnVwdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFjcXVpcmVzIGluIGV4Y2x1c2l2ZSBtb2RlLCBhYm9ydGluZyBpZiBpbnRlcnJ1cHRlZC4KKyAgICAgKiBJbXBsZW1lbnRlZCBieSBmaXJzdCBjaGVja2luZyBpbnRlcnJ1cHQgc3RhdHVzLCB0aGVuIGludm9raW5nCisgICAgICogYXQgbGVhc3Qgb25jZSB7QGxpbmsgI3RyeUFjcXVpcmV9LCByZXR1cm5pbmcgb24KKyAgICAgKiBzdWNjZXNzLiAgT3RoZXJ3aXNlIHRoZSB0aHJlYWQgaXMgcXVldWVkLCBwb3NzaWJseSByZXBlYXRlZGx5CisgICAgICogYmxvY2tpbmcgYW5kIHVuYmxvY2tpbmcsIGludm9raW5nIHtAbGluayAjdHJ5QWNxdWlyZX0KKyAgICAgKiB1bnRpbCBzdWNjZXNzIG9yIHRoZSB0aHJlYWQgaXMgaW50ZXJydXB0ZWQuICBUaGlzIG1ldGhvZCBjYW4gYmUKKyAgICAgKiB1c2VkIHRvIGltcGxlbWVudCBtZXRob2Qge0BsaW5rIExvY2sjbG9ja0ludGVycnVwdGlibHl9LgorICAgICAqCisgICAgICogQHBhcmFtIGFyZyB0aGUgYWNxdWlyZSBhcmd1bWVudC4gIFRoaXMgdmFsdWUgaXMgY29udmV5ZWQgdG8KKyAgICAgKiAgICAgICAge0BsaW5rICN0cnlBY3F1aXJlfSBidXQgaXMgb3RoZXJ3aXNlIHVuaW50ZXJwcmV0ZWQgYW5kCisgICAgICogICAgICAgIGNhbiByZXByZXNlbnQgYW55dGhpbmcgeW91IGxpa2UuCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCB0aHJlYWQgaXMgaW50ZXJydXB0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBhY3F1aXJlSW50ZXJydXB0aWJseShpbnQgYXJnKQorICAgICAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKFRocmVhZC5pbnRlcnJ1cHRlZCgpKQorICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkRXhjZXB0aW9uKCk7CisgICAgICAgIGlmICghdHJ5QWNxdWlyZShhcmcpKQorICAgICAgICAgICAgZG9BY3F1aXJlSW50ZXJydXB0aWJseShhcmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF0dGVtcHRzIHRvIGFjcXVpcmUgaW4gZXhjbHVzaXZlIG1vZGUsIGFib3J0aW5nIGlmIGludGVycnVwdGVkLAorICAgICAqIGFuZCBmYWlsaW5nIGlmIHRoZSBnaXZlbiB0aW1lb3V0IGVsYXBzZXMuICBJbXBsZW1lbnRlZCBieSBmaXJzdAorICAgICAqIGNoZWNraW5nIGludGVycnVwdCBzdGF0dXMsIHRoZW4gaW52b2tpbmcgYXQgbGVhc3Qgb25jZSB7QGxpbmsKKyAgICAgKiAjdHJ5QWNxdWlyZX0sIHJldHVybmluZyBvbiBzdWNjZXNzLiAgT3RoZXJ3aXNlLCB0aGUgdGhyZWFkIGlzCisgICAgICogcXVldWVkLCBwb3NzaWJseSByZXBlYXRlZGx5IGJsb2NraW5nIGFuZCB1bmJsb2NraW5nLCBpbnZva2luZworICAgICAqIHtAbGluayAjdHJ5QWNxdWlyZX0gdW50aWwgc3VjY2VzcyBvciB0aGUgdGhyZWFkIGlzIGludGVycnVwdGVkCisgICAgICogb3IgdGhlIHRpbWVvdXQgZWxhcHNlcy4gIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIGltcGxlbWVudAorICAgICAqIG1ldGhvZCB7QGxpbmsgTG9jayN0cnlMb2NrKGxvbmcsIFRpbWVVbml0KX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJnIHRoZSBhY3F1aXJlIGFyZ3VtZW50LiAgVGhpcyB2YWx1ZSBpcyBjb252ZXllZCB0bworICAgICAqICAgICAgICB7QGxpbmsgI3RyeUFjcXVpcmV9IGJ1dCBpcyBvdGhlcndpc2UgdW5pbnRlcnByZXRlZCBhbmQKKyAgICAgKiAgICAgICAgY2FuIHJlcHJlc2VudCBhbnl0aGluZyB5b3UgbGlrZS4KKyAgICAgKiBAcGFyYW0gbmFub3NUaW1lb3V0IHRoZSBtYXhpbXVtIG51bWJlciBvZiBuYW5vc2Vjb25kcyB0byB3YWl0CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYWNxdWlyZWQ7IHtAY29kZSBmYWxzZX0gaWYgdGltZWQgb3V0CisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCB0aHJlYWQgaXMgaW50ZXJydXB0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiB0cnlBY3F1aXJlTmFub3MoaW50IGFyZywgbG9uZyBuYW5vc1RpbWVvdXQpCisgICAgICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBpZiAoVGhyZWFkLmludGVycnVwdGVkKCkpCisgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJydXB0ZWRFeGNlcHRpb24oKTsKKyAgICAgICAgcmV0dXJuIHRyeUFjcXVpcmUoYXJnKSB8fAorICAgICAgICAgICAgZG9BY3F1aXJlTmFub3MoYXJnLCBuYW5vc1RpbWVvdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbGVhc2VzIGluIGV4Y2x1c2l2ZSBtb2RlLiAgSW1wbGVtZW50ZWQgYnkgdW5ibG9ja2luZyBvbmUgb3IKKyAgICAgKiBtb3JlIHRocmVhZHMgaWYge0BsaW5rICN0cnlSZWxlYXNlfSByZXR1cm5zIHRydWUuCisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gaW1wbGVtZW50IG1ldGhvZCB7QGxpbmsgTG9jayN1bmxvY2t9LgorICAgICAqCisgICAgICogQHBhcmFtIGFyZyB0aGUgcmVsZWFzZSBhcmd1bWVudC4gIFRoaXMgdmFsdWUgaXMgY29udmV5ZWQgdG8KKyAgICAgKiAgICAgICAge0BsaW5rICN0cnlSZWxlYXNlfSBidXQgaXMgb3RoZXJ3aXNlIHVuaW50ZXJwcmV0ZWQgYW5kCisgICAgICogICAgICAgIGNhbiByZXByZXNlbnQgYW55dGhpbmcgeW91IGxpa2UuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgcmV0dXJuZWQgZnJvbSB7QGxpbmsgI3RyeVJlbGVhc2V9CisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gcmVsZWFzZShpbnQgYXJnKSB7CisgICAgICAgIGlmICh0cnlSZWxlYXNlKGFyZykpIHsKKyAgICAgICAgICAgIE5vZGUgaCA9IGhlYWQ7CisgICAgICAgICAgICBpZiAoaCAhPSBudWxsICYmIGgud2FpdFN0YXR1cyAhPSAwKQorICAgICAgICAgICAgICAgIHVucGFya1N1Y2Nlc3NvcihoKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBY3F1aXJlcyBpbiBzaGFyZWQgbW9kZSwgaWdub3JpbmcgaW50ZXJydXB0cy4gIEltcGxlbWVudGVkIGJ5CisgICAgICogZmlyc3QgaW52b2tpbmcgYXQgbGVhc3Qgb25jZSB7QGxpbmsgI3RyeUFjcXVpcmVTaGFyZWR9LAorICAgICAqIHJldHVybmluZyBvbiBzdWNjZXNzLiAgT3RoZXJ3aXNlIHRoZSB0aHJlYWQgaXMgcXVldWVkLCBwb3NzaWJseQorICAgICAqIHJlcGVhdGVkbHkgYmxvY2tpbmcgYW5kIHVuYmxvY2tpbmcsIGludm9raW5nIHtAbGluaworICAgICAqICN0cnlBY3F1aXJlU2hhcmVkfSB1bnRpbCBzdWNjZXNzLgorICAgICAqCisgICAgICogQHBhcmFtIGFyZyB0aGUgYWNxdWlyZSBhcmd1bWVudC4gIFRoaXMgdmFsdWUgaXMgY29udmV5ZWQgdG8KKyAgICAgKiAgICAgICAge0BsaW5rICN0cnlBY3F1aXJlU2hhcmVkfSBidXQgaXMgb3RoZXJ3aXNlIHVuaW50ZXJwcmV0ZWQKKyAgICAgKiAgICAgICAgYW5kIGNhbiByZXByZXNlbnQgYW55dGhpbmcgeW91IGxpa2UuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgYWNxdWlyZVNoYXJlZChpbnQgYXJnKSB7CisgICAgICAgIGlmICh0cnlBY3F1aXJlU2hhcmVkKGFyZykgPCAwKQorICAgICAgICAgICAgZG9BY3F1aXJlU2hhcmVkKGFyZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWNxdWlyZXMgaW4gc2hhcmVkIG1vZGUsIGFib3J0aW5nIGlmIGludGVycnVwdGVkLiAgSW1wbGVtZW50ZWQKKyAgICAgKiBieSBmaXJzdCBjaGVja2luZyBpbnRlcnJ1cHQgc3RhdHVzLCB0aGVuIGludm9raW5nIGF0IGxlYXN0IG9uY2UKKyAgICAgKiB7QGxpbmsgI3RyeUFjcXVpcmVTaGFyZWR9LCByZXR1cm5pbmcgb24gc3VjY2Vzcy4gIE90aGVyd2lzZSB0aGUKKyAgICAgKiB0aHJlYWQgaXMgcXVldWVkLCBwb3NzaWJseSByZXBlYXRlZGx5IGJsb2NraW5nIGFuZCB1bmJsb2NraW5nLAorICAgICAqIGludm9raW5nIHtAbGluayAjdHJ5QWNxdWlyZVNoYXJlZH0gdW50aWwgc3VjY2VzcyBvciB0aGUgdGhyZWFkCisgICAgICogaXMgaW50ZXJydXB0ZWQuCisgICAgICogQHBhcmFtIGFyZyB0aGUgYWNxdWlyZSBhcmd1bWVudAorICAgICAqIFRoaXMgdmFsdWUgaXMgY29udmV5ZWQgdG8ge0BsaW5rICN0cnlBY3F1aXJlU2hhcmVkfSBidXQgaXMKKyAgICAgKiBvdGhlcndpc2UgdW5pbnRlcnByZXRlZCBhbmQgY2FuIHJlcHJlc2VudCBhbnl0aGluZworICAgICAqIHlvdSBsaWtlLgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgYWNxdWlyZVNoYXJlZEludGVycnVwdGlibHkoaW50IGFyZykKKyAgICAgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChUaHJlYWQuaW50ZXJydXB0ZWQoKSkKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbigpOworICAgICAgICBpZiAodHJ5QWNxdWlyZVNoYXJlZChhcmcpIDwgMCkKKyAgICAgICAgICAgIGRvQWNxdWlyZVNoYXJlZEludGVycnVwdGlibHkoYXJnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdHRlbXB0cyB0byBhY3F1aXJlIGluIHNoYXJlZCBtb2RlLCBhYm9ydGluZyBpZiBpbnRlcnJ1cHRlZCwgYW5kCisgICAgICogZmFpbGluZyBpZiB0aGUgZ2l2ZW4gdGltZW91dCBlbGFwc2VzLiAgSW1wbGVtZW50ZWQgYnkgZmlyc3QKKyAgICAgKiBjaGVja2luZyBpbnRlcnJ1cHQgc3RhdHVzLCB0aGVuIGludm9raW5nIGF0IGxlYXN0IG9uY2Uge0BsaW5rCisgICAgICogI3RyeUFjcXVpcmVTaGFyZWR9LCByZXR1cm5pbmcgb24gc3VjY2Vzcy4gIE90aGVyd2lzZSwgdGhlCisgICAgICogdGhyZWFkIGlzIHF1ZXVlZCwgcG9zc2libHkgcmVwZWF0ZWRseSBibG9ja2luZyBhbmQgdW5ibG9ja2luZywKKyAgICAgKiBpbnZva2luZyB7QGxpbmsgI3RyeUFjcXVpcmVTaGFyZWR9IHVudGlsIHN1Y2Nlc3Mgb3IgdGhlIHRocmVhZAorICAgICAqIGlzIGludGVycnVwdGVkIG9yIHRoZSB0aW1lb3V0IGVsYXBzZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJnIHRoZSBhY3F1aXJlIGFyZ3VtZW50LiAgVGhpcyB2YWx1ZSBpcyBjb252ZXllZCB0bworICAgICAqICAgICAgICB7QGxpbmsgI3RyeUFjcXVpcmVTaGFyZWR9IGJ1dCBpcyBvdGhlcndpc2UgdW5pbnRlcnByZXRlZAorICAgICAqICAgICAgICBhbmQgY2FuIHJlcHJlc2VudCBhbnl0aGluZyB5b3UgbGlrZS4KKyAgICAgKiBAcGFyYW0gbmFub3NUaW1lb3V0IHRoZSBtYXhpbXVtIG51bWJlciBvZiBuYW5vc2Vjb25kcyB0byB3YWl0CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYWNxdWlyZWQ7IHtAY29kZSBmYWxzZX0gaWYgdGltZWQgb3V0CisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCB0aHJlYWQgaXMgaW50ZXJydXB0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiB0cnlBY3F1aXJlU2hhcmVkTmFub3MoaW50IGFyZywgbG9uZyBuYW5vc1RpbWVvdXQpCisgICAgICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBpZiAoVGhyZWFkLmludGVycnVwdGVkKCkpCisgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJydXB0ZWRFeGNlcHRpb24oKTsKKyAgICAgICAgcmV0dXJuIHRyeUFjcXVpcmVTaGFyZWQoYXJnKSA+PSAwIHx8CisgICAgICAgICAgICBkb0FjcXVpcmVTaGFyZWROYW5vcyhhcmcsIG5hbm9zVGltZW91dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVsZWFzZXMgaW4gc2hhcmVkIG1vZGUuICBJbXBsZW1lbnRlZCBieSB1bmJsb2NraW5nIG9uZSBvciBtb3JlCisgICAgICogdGhyZWFkcyBpZiB7QGxpbmsgI3RyeVJlbGVhc2VTaGFyZWR9IHJldHVybnMgdHJ1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmcgdGhlIHJlbGVhc2UgYXJndW1lbnQuICBUaGlzIHZhbHVlIGlzIGNvbnZleWVkIHRvCisgICAgICogICAgICAgIHtAbGluayAjdHJ5UmVsZWFzZVNoYXJlZH0gYnV0IGlzIG90aGVyd2lzZSB1bmludGVycHJldGVkCisgICAgICogICAgICAgIGFuZCBjYW4gcmVwcmVzZW50IGFueXRoaW5nIHlvdSBsaWtlLgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIHJldHVybmVkIGZyb20ge0BsaW5rICN0cnlSZWxlYXNlU2hhcmVkfQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIHJlbGVhc2VTaGFyZWQoaW50IGFyZykgeworICAgICAgICBpZiAodHJ5UmVsZWFzZVNoYXJlZChhcmcpKSB7CisgICAgICAgICAgICBkb1JlbGVhc2VTaGFyZWQoKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvLyBRdWV1ZSBpbnNwZWN0aW9uIG1ldGhvZHMKKworICAgIC8qKgorICAgICAqIFF1ZXJpZXMgd2hldGhlciBhbnkgdGhyZWFkcyBhcmUgd2FpdGluZyB0byBhY3F1aXJlLiBOb3RlIHRoYXQKKyAgICAgKiBiZWNhdXNlIGNhbmNlbGxhdGlvbnMgZHVlIHRvIGludGVycnVwdHMgYW5kIHRpbWVvdXRzIG1heSBvY2N1cgorICAgICAqIGF0IGFueSB0aW1lLCBhIHtAY29kZSB0cnVlfSByZXR1cm4gZG9lcyBub3QgZ3VhcmFudGVlIHRoYXQgYW55CisgICAgICogb3RoZXIgdGhyZWFkIHdpbGwgZXZlciBhY3F1aXJlLgorICAgICAqCisgICAgICogPHA+SW4gdGhpcyBpbXBsZW1lbnRhdGlvbiwgdGhpcyBvcGVyYXRpb24gcmV0dXJucyBpbgorICAgICAqIGNvbnN0YW50IHRpbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGVyZSBtYXkgYmUgb3RoZXIgdGhyZWFkcyB3YWl0aW5nIHRvIGFjcXVpcmUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNRdWV1ZWRUaHJlYWRzKCkgeworICAgICAgICByZXR1cm4gaGVhZCAhPSB0YWlsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFF1ZXJpZXMgd2hldGhlciBhbnkgdGhyZWFkcyBoYXZlIGV2ZXIgY29udGVuZGVkIHRvIGFjcXVpcmUgdGhpcworICAgICAqIHN5bmNocm9uaXplcjsgdGhhdCBpcyBpZiBhbiBhY3F1aXJlIG1ldGhvZCBoYXMgZXZlciBibG9ja2VkLgorICAgICAqCisgICAgICogPHA+SW4gdGhpcyBpbXBsZW1lbnRhdGlvbiwgdGhpcyBvcGVyYXRpb24gcmV0dXJucyBpbgorICAgICAqIGNvbnN0YW50IHRpbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGVyZSBoYXMgZXZlciBiZWVuIGNvbnRlbnRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNDb250ZW5kZWQoKSB7CisgICAgICAgIHJldHVybiBoZWFkICE9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZmlyc3QgKGxvbmdlc3Qtd2FpdGluZykgdGhyZWFkIGluIHRoZSBxdWV1ZSwgb3IKKyAgICAgKiB7QGNvZGUgbnVsbH0gaWYgbm8gdGhyZWFkcyBhcmUgY3VycmVudGx5IHF1ZXVlZC4KKyAgICAgKgorICAgICAqIDxwPkluIHRoaXMgaW1wbGVtZW50YXRpb24sIHRoaXMgb3BlcmF0aW9uIG5vcm1hbGx5IHJldHVybnMgaW4KKyAgICAgKiBjb25zdGFudCB0aW1lLCBidXQgbWF5IGl0ZXJhdGUgdXBvbiBjb250ZW50aW9uIGlmIG90aGVyIHRocmVhZHMgYXJlCisgICAgICogY29uY3VycmVudGx5IG1vZGlmeWluZyB0aGUgcXVldWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBmaXJzdCAobG9uZ2VzdC13YWl0aW5nKSB0aHJlYWQgaW4gdGhlIHF1ZXVlLCBvcgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlmIG5vIHRocmVhZHMgYXJlIGN1cnJlbnRseSBxdWV1ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgVGhyZWFkIGdldEZpcnN0UXVldWVkVGhyZWFkKCkgeworICAgICAgICAvLyBoYW5kbGUgb25seSBmYXN0IHBhdGgsIGVsc2UgcmVsYXkKKyAgICAgICAgcmV0dXJuIChoZWFkID09IHRhaWwpID8gbnVsbCA6IGZ1bGxHZXRGaXJzdFF1ZXVlZFRocmVhZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFZlcnNpb24gb2YgZ2V0Rmlyc3RRdWV1ZWRUaHJlYWQgY2FsbGVkIHdoZW4gZmFzdHBhdGggZmFpbHMKKyAgICAgKi8KKyAgICBwcml2YXRlIFRocmVhZCBmdWxsR2V0Rmlyc3RRdWV1ZWRUaHJlYWQoKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFRoZSBmaXJzdCBub2RlIGlzIG5vcm1hbGx5IGhlYWQubmV4dC4gVHJ5IHRvIGdldCBpdHMKKyAgICAgICAgICogdGhyZWFkIGZpZWxkLCBlbnN1cmluZyBjb25zaXN0ZW50IHJlYWRzOiBJZiB0aHJlYWQKKyAgICAgICAgICogZmllbGQgaXMgbnVsbGVkIG91dCBvciBzLnByZXYgaXMgbm8gbG9uZ2VyIGhlYWQsIHRoZW4KKyAgICAgICAgICogc29tZSBvdGhlciB0aHJlYWQocykgY29uY3VycmVudGx5IHBlcmZvcm1lZCBzZXRIZWFkIGluCisgICAgICAgICAqIGJldHdlZW4gc29tZSBvZiBvdXIgcmVhZHMuIFdlIHRyeSB0aGlzIHR3aWNlIGJlZm9yZQorICAgICAgICAgKiByZXNvcnRpbmcgdG8gdHJhdmVyc2FsLgorICAgICAgICAgKi8KKyAgICAgICAgTm9kZSBoLCBzOworICAgICAgICBUaHJlYWQgc3Q7CisgICAgICAgIGlmICgoKGggPSBoZWFkKSAhPSBudWxsICYmIChzID0gaC5uZXh0KSAhPSBudWxsICYmCisgICAgICAgICAgICAgcy5wcmV2ID09IGhlYWQgJiYgKHN0ID0gcy50aHJlYWQpICE9IG51bGwpIHx8CisgICAgICAgICAgICAoKGggPSBoZWFkKSAhPSBudWxsICYmIChzID0gaC5uZXh0KSAhPSBudWxsICYmCisgICAgICAgICAgICAgcy5wcmV2ID09IGhlYWQgJiYgKHN0ID0gcy50aHJlYWQpICE9IG51bGwpKQorICAgICAgICAgICAgcmV0dXJuIHN0OworCisgICAgICAgIC8qCisgICAgICAgICAqIEhlYWQncyBuZXh0IGZpZWxkIG1pZ2h0IG5vdCBoYXZlIGJlZW4gc2V0IHlldCwgb3IgbWF5IGhhdmUKKyAgICAgICAgICogYmVlbiB1bnNldCBhZnRlciBzZXRIZWFkLiBTbyB3ZSBtdXN0IGNoZWNrIHRvIHNlZSBpZiB0YWlsCisgICAgICAgICAqIGlzIGFjdHVhbGx5IGZpcnN0IG5vZGUuIElmIG5vdCwgd2UgY29udGludWUgb24sIHNhZmVseQorICAgICAgICAgKiB0cmF2ZXJzaW5nIGZyb20gdGFpbCBiYWNrIHRvIGhlYWQgdG8gZmluZCBmaXJzdCwKKyAgICAgICAgICogZ3VhcmFudGVlaW5nIHRlcm1pbmF0aW9uLgorICAgICAgICAgKi8KKworICAgICAgICBOb2RlIHQgPSB0YWlsOworICAgICAgICBUaHJlYWQgZmlyc3RUaHJlYWQgPSBudWxsOworICAgICAgICB3aGlsZSAodCAhPSBudWxsICYmIHQgIT0gaGVhZCkgeworICAgICAgICAgICAgVGhyZWFkIHR0ID0gdC50aHJlYWQ7CisgICAgICAgICAgICBpZiAodHQgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICBmaXJzdFRocmVhZCA9IHR0OworICAgICAgICAgICAgdCA9IHQucHJldjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmlyc3RUaHJlYWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiB0aHJlYWQgaXMgY3VycmVudGx5IHF1ZXVlZC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gdHJhdmVyc2VzIHRoZSBxdWV1ZSB0byBkZXRlcm1pbmUKKyAgICAgKiBwcmVzZW5jZSBvZiB0aGUgZ2l2ZW4gdGhyZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIHRocmVhZCB0aGUgdGhyZWFkCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGdpdmVuIHRocmVhZCBpcyBvbiB0aGUgcXVldWUKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSB0aHJlYWQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzUXVldWVkKFRocmVhZCB0aHJlYWQpIHsKKyAgICAgICAgaWYgKHRocmVhZCA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGZvciAoTm9kZSBwID0gdGFpbDsgcCAhPSBudWxsOyBwID0gcC5wcmV2KQorICAgICAgICAgICAgaWYgKHAudGhyZWFkID09IHRocmVhZCkKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoZSBhcHBhcmVudCBmaXJzdCBxdWV1ZWQgdGhyZWFkLCBpZiBvbmUKKyAgICAgKiBleGlzdHMsIGlzIHdhaXRpbmcgaW4gZXhjbHVzaXZlIG1vZGUuICBJZiB0aGlzIG1ldGhvZCByZXR1cm5zCisgICAgICoge0Bjb2RlIHRydWV9LCBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGF0dGVtcHRpbmcgdG8gYWNxdWlyZSBpbgorICAgICAqIHNoYXJlZCBtb2RlICh0aGF0IGlzLCB0aGlzIG1ldGhvZCBpcyBpbnZva2VkIGZyb20ge0BsaW5rCisgICAgICogI3RyeUFjcXVpcmVTaGFyZWR9KSB0aGVuIGl0IGlzIGd1YXJhbnRlZWQgdGhhdCB0aGUgY3VycmVudCB0aHJlYWQKKyAgICAgKiBpcyBub3QgdGhlIGZpcnN0IHF1ZXVlZCB0aHJlYWQuICBVc2VkIG9ubHkgYXMgYSBoZXVyaXN0aWMgaW4KKyAgICAgKiBSZWVudHJhbnRSZWFkV3JpdGVMb2NrLgorICAgICAqLworICAgIGZpbmFsIGJvb2xlYW4gYXBwYXJlbnRseUZpcnN0UXVldWVkSXNFeGNsdXNpdmUoKSB7CisgICAgICAgIE5vZGUgaCwgczsKKyAgICAgICAgcmV0dXJuIChoID0gaGVhZCkgIT0gbnVsbCAmJgorICAgICAgICAgICAgKHMgPSBoLm5leHQpICAhPSBudWxsICYmCisgICAgICAgICAgICAhcy5pc1NoYXJlZCgpICAgICAgICAgJiYKKyAgICAgICAgICAgIHMudGhyZWFkICE9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUXVlcmllcyB3aGV0aGVyIGFueSB0aHJlYWRzIGhhdmUgYmVlbiB3YWl0aW5nIHRvIGFjcXVpcmUgbG9uZ2VyCisgICAgICogdGhhbiB0aGUgY3VycmVudCB0aHJlYWQuCisgICAgICoKKyAgICAgKiA8cD5BbiBpbnZvY2F0aW9uIG9mIHRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtYXkgYmUKKyAgICAgKiBtb3JlIGVmZmljaWVudCB0aGFuKToKKyAgICAgKiAgPHByZT4ge0Bjb2RlCisgICAgICogZ2V0Rmlyc3RRdWV1ZWRUaHJlYWQoKSAhPSBUaHJlYWQuY3VycmVudFRocmVhZCgpICYmCisgICAgICogaGFzUXVldWVkVGhyZWFkcygpfTwvcHJlPgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IGJlY2F1c2UgY2FuY2VsbGF0aW9ucyBkdWUgdG8gaW50ZXJydXB0cyBhbmQKKyAgICAgKiB0aW1lb3V0cyBtYXkgb2NjdXIgYXQgYW55IHRpbWUsIGEge0Bjb2RlIHRydWV9IHJldHVybiBkb2VzIG5vdAorICAgICAqIGd1YXJhbnRlZSB0aGF0IHNvbWUgb3RoZXIgdGhyZWFkIHdpbGwgYWNxdWlyZSBiZWZvcmUgdGhlIGN1cnJlbnQKKyAgICAgKiB0aHJlYWQuICBMaWtld2lzZSwgaXQgaXMgcG9zc2libGUgZm9yIGFub3RoZXIgdGhyZWFkIHRvIHdpbiBhCisgICAgICogcmFjZSB0byBlbnF1ZXVlIGFmdGVyIHRoaXMgbWV0aG9kIGhhcyByZXR1cm5lZCB7QGNvZGUgZmFsc2V9LAorICAgICAqIGR1ZSB0byB0aGUgcXVldWUgYmVpbmcgZW1wdHkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGJ5IGEgZmFpciBzeW5jaHJvbml6ZXIgdG8KKyAgICAgKiBhdm9pZCA8YSBocmVmPSJBYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplciNiYXJnaW5nIj5iYXJnaW5nPC9hPi4KKyAgICAgKiBTdWNoIGEgc3luY2hyb25pemVyJ3Mge0BsaW5rICN0cnlBY3F1aXJlfSBtZXRob2Qgc2hvdWxkIHJldHVybgorICAgICAqIHtAY29kZSBmYWxzZX0sIGFuZCBpdHMge0BsaW5rICN0cnlBY3F1aXJlU2hhcmVkfSBtZXRob2Qgc2hvdWxkCisgICAgICogcmV0dXJuIGEgbmVnYXRpdmUgdmFsdWUsIGlmIHRoaXMgbWV0aG9kIHJldHVybnMge0Bjb2RlIHRydWV9CisgICAgICogKHVubGVzcyB0aGlzIGlzIGEgcmVlbnRyYW50IGFjcXVpcmUpLiAgRm9yIGV4YW1wbGUsIHRoZSB7QGNvZGUKKyAgICAgKiB0cnlBY3F1aXJlfSBtZXRob2QgZm9yIGEgZmFpciwgcmVlbnRyYW50LCBleGNsdXNpdmUgbW9kZQorICAgICAqIHN5bmNocm9uaXplciBtaWdodCBsb29rIGxpa2UgdGhpczoKKyAgICAgKgorICAgICAqICA8cHJlPiB7QGNvZGUKKyAgICAgKiBwcm90ZWN0ZWQgYm9vbGVhbiB0cnlBY3F1aXJlKGludCBhcmcpIHsKKyAgICAgKiAgIGlmIChpc0hlbGRFeGNsdXNpdmVseSgpKSB7CisgICAgICogICAgIC8vIEEgcmVlbnRyYW50IGFjcXVpcmU7IGluY3JlbWVudCBob2xkIGNvdW50CisgICAgICogICAgIHJldHVybiB0cnVlOworICAgICAqICAgfSBlbHNlIGlmIChoYXNRdWV1ZWRQcmVkZWNlc3NvcnMoKSkgeworICAgICAqICAgICByZXR1cm4gZmFsc2U7CisgICAgICogICB9IGVsc2UgeworICAgICAqICAgICAvLyB0cnkgdG8gYWNxdWlyZSBub3JtYWxseQorICAgICAqICAgfQorICAgICAqIH19PC9wcmU+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGVyZSBpcyBhIHF1ZXVlZCB0aHJlYWQgcHJlY2VkaW5nIHRoZQorICAgICAqICAgICAgICAgY3VycmVudCB0aHJlYWQsIGFuZCB7QGNvZGUgZmFsc2V9IGlmIHRoZSBjdXJyZW50IHRocmVhZAorICAgICAqICAgICAgICAgaXMgYXQgdGhlIGhlYWQgb2YgdGhlIHF1ZXVlIG9yIHRoZSBxdWV1ZSBpcyBlbXB0eQorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc1F1ZXVlZFByZWRlY2Vzc29ycygpIHsKKyAgICAgICAgLy8gVGhlIGNvcnJlY3RuZXNzIG9mIHRoaXMgZGVwZW5kcyBvbiBoZWFkIGJlaW5nIGluaXRpYWxpemVkCisgICAgICAgIC8vIGJlZm9yZSB0YWlsIGFuZCBvbiBoZWFkLm5leHQgYmVpbmcgYWNjdXJhdGUgaWYgdGhlIGN1cnJlbnQKKyAgICAgICAgLy8gdGhyZWFkIGlzIGZpcnN0IGluIHF1ZXVlLgorICAgICAgICBOb2RlIHQgPSB0YWlsOyAvLyBSZWFkIGZpZWxkcyBpbiByZXZlcnNlIGluaXRpYWxpemF0aW9uIG9yZGVyCisgICAgICAgIE5vZGUgaCA9IGhlYWQ7CisgICAgICAgIE5vZGUgczsKKyAgICAgICAgcmV0dXJuIGggIT0gdCAmJgorICAgICAgICAgICAgKChzID0gaC5uZXh0KSA9PSBudWxsIHx8IHMudGhyZWFkICE9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkpOworICAgIH0KKworCisgICAgLy8gSW5zdHJ1bWVudGF0aW9uIGFuZCBtb25pdG9yaW5nIG1ldGhvZHMKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gZXN0aW1hdGUgb2YgdGhlIG51bWJlciBvZiB0aHJlYWRzIHdhaXRpbmcgdG8KKyAgICAgKiBhY3F1aXJlLiAgVGhlIHZhbHVlIGlzIG9ubHkgYW4gZXN0aW1hdGUgYmVjYXVzZSB0aGUgbnVtYmVyIG9mCisgICAgICogdGhyZWFkcyBtYXkgY2hhbmdlIGR5bmFtaWNhbGx5IHdoaWxlIHRoaXMgbWV0aG9kIHRyYXZlcnNlcworICAgICAqIGludGVybmFsIGRhdGEgc3RydWN0dXJlcy4gIFRoaXMgbWV0aG9kIGlzIGRlc2lnbmVkIGZvciB1c2UgaW4KKyAgICAgKiBtb25pdG9yaW5nIHN5c3RlbSBzdGF0ZSwgbm90IGZvciBzeW5jaHJvbml6YXRpb24KKyAgICAgKiBjb250cm9sLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZXN0aW1hdGVkIG51bWJlciBvZiB0aHJlYWRzIHdhaXRpbmcgdG8gYWNxdWlyZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UXVldWVMZW5ndGgoKSB7CisgICAgICAgIGludCBuID0gMDsKKyAgICAgICAgZm9yIChOb2RlIHAgPSB0YWlsOyBwICE9IG51bGw7IHAgPSBwLnByZXYpIHsKKyAgICAgICAgICAgIGlmIChwLnRocmVhZCAhPSBudWxsKQorICAgICAgICAgICAgICAgICsrbjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29sbGVjdGlvbiBjb250YWluaW5nIHRocmVhZHMgdGhhdCBtYXkgYmUgd2FpdGluZyB0bworICAgICAqIGFjcXVpcmUuICBCZWNhdXNlIHRoZSBhY3R1YWwgc2V0IG9mIHRocmVhZHMgbWF5IGNoYW5nZQorICAgICAqIGR5bmFtaWNhbGx5IHdoaWxlIGNvbnN0cnVjdGluZyB0aGlzIHJlc3VsdCwgdGhlIHJldHVybmVkCisgICAgICogY29sbGVjdGlvbiBpcyBvbmx5IGEgYmVzdC1lZmZvcnQgZXN0aW1hdGUuICBUaGUgZWxlbWVudHMgb2YgdGhlCisgICAgICogcmV0dXJuZWQgY29sbGVjdGlvbiBhcmUgaW4gbm8gcGFydGljdWxhciBvcmRlci4gIFRoaXMgbWV0aG9kIGlzCisgICAgICogZGVzaWduZWQgdG8gZmFjaWxpdGF0ZSBjb25zdHJ1Y3Rpb24gb2Ygc3ViY2xhc3NlcyB0aGF0IHByb3ZpZGUKKyAgICAgKiBtb3JlIGV4dGVuc2l2ZSBtb25pdG9yaW5nIGZhY2lsaXRpZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb2xsZWN0aW9uIG9mIHRocmVhZHMKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQ29sbGVjdGlvbjxUaHJlYWQ+IGdldFF1ZXVlZFRocmVhZHMoKSB7CisgICAgICAgIEFycmF5TGlzdDxUaHJlYWQ+IGxpc3QgPSBuZXcgQXJyYXlMaXN0PFRocmVhZD4oKTsKKyAgICAgICAgZm9yIChOb2RlIHAgPSB0YWlsOyBwICE9IG51bGw7IHAgPSBwLnByZXYpIHsKKyAgICAgICAgICAgIFRocmVhZCB0ID0gcC50aHJlYWQ7CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKQorICAgICAgICAgICAgICAgIGxpc3QuYWRkKHQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBsaXN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb2xsZWN0aW9uIGNvbnRhaW5pbmcgdGhyZWFkcyB0aGF0IG1heSBiZSB3YWl0aW5nIHRvCisgICAgICogYWNxdWlyZSBpbiBleGNsdXNpdmUgbW9kZS4gVGhpcyBoYXMgdGhlIHNhbWUgcHJvcGVydGllcworICAgICAqIGFzIHtAbGluayAjZ2V0UXVldWVkVGhyZWFkc30gZXhjZXB0IHRoYXQgaXQgb25seSByZXR1cm5zCisgICAgICogdGhvc2UgdGhyZWFkcyB3YWl0aW5nIGR1ZSB0byBhbiBleGNsdXNpdmUgYWNxdWlyZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNvbGxlY3Rpb24gb2YgdGhyZWFkcworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBDb2xsZWN0aW9uPFRocmVhZD4gZ2V0RXhjbHVzaXZlUXVldWVkVGhyZWFkcygpIHsKKyAgICAgICAgQXJyYXlMaXN0PFRocmVhZD4gbGlzdCA9IG5ldyBBcnJheUxpc3Q8VGhyZWFkPigpOworICAgICAgICBmb3IgKE5vZGUgcCA9IHRhaWw7IHAgIT0gbnVsbDsgcCA9IHAucHJldikgeworICAgICAgICAgICAgaWYgKCFwLmlzU2hhcmVkKCkpIHsKKyAgICAgICAgICAgICAgICBUaHJlYWQgdCA9IHAudGhyZWFkOworICAgICAgICAgICAgICAgIGlmICh0ICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIGxpc3QuYWRkKHQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBsaXN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb2xsZWN0aW9uIGNvbnRhaW5pbmcgdGhyZWFkcyB0aGF0IG1heSBiZSB3YWl0aW5nIHRvCisgICAgICogYWNxdWlyZSBpbiBzaGFyZWQgbW9kZS4gVGhpcyBoYXMgdGhlIHNhbWUgcHJvcGVydGllcworICAgICAqIGFzIHtAbGluayAjZ2V0UXVldWVkVGhyZWFkc30gZXhjZXB0IHRoYXQgaXQgb25seSByZXR1cm5zCisgICAgICogdGhvc2UgdGhyZWFkcyB3YWl0aW5nIGR1ZSB0byBhIHNoYXJlZCBhY3F1aXJlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29sbGVjdGlvbiBvZiB0aHJlYWRzCisgICAgICovCisgICAgcHVibGljIGZpbmFsIENvbGxlY3Rpb248VGhyZWFkPiBnZXRTaGFyZWRRdWV1ZWRUaHJlYWRzKCkgeworICAgICAgICBBcnJheUxpc3Q8VGhyZWFkPiBsaXN0ID0gbmV3IEFycmF5TGlzdDxUaHJlYWQ+KCk7CisgICAgICAgIGZvciAoTm9kZSBwID0gdGFpbDsgcCAhPSBudWxsOyBwID0gcC5wcmV2KSB7CisgICAgICAgICAgICBpZiAocC5pc1NoYXJlZCgpKSB7CisgICAgICAgICAgICAgICAgVGhyZWFkIHQgPSBwLnRocmVhZDsKKyAgICAgICAgICAgICAgICBpZiAodCAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICBsaXN0LmFkZCh0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbGlzdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGlkZW50aWZ5aW5nIHRoaXMgc3luY2hyb25pemVyLCBhcyB3ZWxsIGFzIGl0cyBzdGF0ZS4KKyAgICAgKiBUaGUgc3RhdGUsIGluIGJyYWNrZXRzLCBpbmNsdWRlcyB0aGUgU3RyaW5nIHtAY29kZSAiU3RhdGUgPSJ9CisgICAgICogZm9sbG93ZWQgYnkgdGhlIGN1cnJlbnQgdmFsdWUgb2Yge0BsaW5rICNnZXRTdGF0ZX0sIGFuZCBlaXRoZXIKKyAgICAgKiB7QGNvZGUgIm5vbmVtcHR5In0gb3Ige0Bjb2RlICJlbXB0eSJ9IGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZQorICAgICAqIHF1ZXVlIGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHJldHVybiBhIHN0cmluZyBpZGVudGlmeWluZyB0aGlzIHN5bmNocm9uaXplciwgYXMgd2VsbCBhcyBpdHMgc3RhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBpbnQgcyA9IGdldFN0YXRlKCk7CisgICAgICAgIFN0cmluZyBxICA9IGhhc1F1ZXVlZFRocmVhZHMoKSA/ICJub24iIDogIiI7CisgICAgICAgIHJldHVybiBzdXBlci50b1N0cmluZygpICsKKyAgICAgICAgICAgICJbU3RhdGUgPSAiICsgcyArICIsICIgKyBxICsgImVtcHR5IHF1ZXVlXSI7CisgICAgfQorCisKKyAgICAvLyBJbnRlcm5hbCBzdXBwb3J0IG1ldGhvZHMgZm9yIENvbmRpdGlvbnMKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiBhIG5vZGUsIGFsd2F5cyBvbmUgdGhhdCB3YXMgaW5pdGlhbGx5IHBsYWNlZCBvbgorICAgICAqIGEgY29uZGl0aW9uIHF1ZXVlLCBpcyBub3cgd2FpdGluZyB0byByZWFjcXVpcmUgb24gc3luYyBxdWV1ZS4KKyAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBpcyByZWFjcXVpcmluZworICAgICAqLworICAgIGZpbmFsIGJvb2xlYW4gaXNPblN5bmNRdWV1ZShOb2RlIG5vZGUpIHsKKyAgICAgICAgaWYgKG5vZGUud2FpdFN0YXR1cyA9PSBOb2RlLkNPTkRJVElPTiB8fCBub2RlLnByZXYgPT0gbnVsbCkKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKG5vZGUubmV4dCAhPSBudWxsKSAvLyBJZiBoYXMgc3VjY2Vzc29yLCBpdCBtdXN0IGJlIG9uIHF1ZXVlCisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgLyoKKyAgICAgICAgICogbm9kZS5wcmV2IGNhbiBiZSBub24tbnVsbCwgYnV0IG5vdCB5ZXQgb24gcXVldWUgYmVjYXVzZQorICAgICAgICAgKiB0aGUgQ0FTIHRvIHBsYWNlIGl0IG9uIHF1ZXVlIGNhbiBmYWlsLiBTbyB3ZSBoYXZlIHRvCisgICAgICAgICAqIHRyYXZlcnNlIGZyb20gdGFpbCB0byBtYWtlIHN1cmUgaXQgYWN0dWFsbHkgbWFkZSBpdC4gIEl0CisgICAgICAgICAqIHdpbGwgYWx3YXlzIGJlIG5lYXIgdGhlIHRhaWwgaW4gY2FsbHMgdG8gdGhpcyBtZXRob2QsIGFuZAorICAgICAgICAgKiB1bmxlc3MgdGhlIENBUyBmYWlsZWQgKHdoaWNoIGlzIHVubGlrZWx5KSwgaXQgd2lsbCBiZQorICAgICAgICAgKiB0aGVyZSwgc28gd2UgaGFyZGx5IGV2ZXIgdHJhdmVyc2UgbXVjaC4KKyAgICAgICAgICovCisgICAgICAgIHJldHVybiBmaW5kTm9kZUZyb21UYWlsKG5vZGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiBub2RlIGlzIG9uIHN5bmMgcXVldWUgYnkgc2VhcmNoaW5nIGJhY2t3YXJkcyBmcm9tIHRhaWwuCisgICAgICogQ2FsbGVkIG9ubHkgd2hlbiBuZWVkZWQgYnkgaXNPblN5bmNRdWV1ZS4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgcHJlc2VudAorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBmaW5kTm9kZUZyb21UYWlsKE5vZGUgbm9kZSkgeworICAgICAgICBOb2RlIHQgPSB0YWlsOworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICBpZiAodCA9PSBub2RlKQorICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgaWYgKHQgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB0ID0gdC5wcmV2OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJhbnNmZXJzIGEgbm9kZSBmcm9tIGEgY29uZGl0aW9uIHF1ZXVlIG9udG8gc3luYyBxdWV1ZS4KKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgc3VjY2Vzc2Z1bC4KKyAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsbHkgdHJhbnNmZXJyZWQgKGVsc2UgdGhlIG5vZGUgd2FzCisgICAgICogY2FuY2VsbGVkIGJlZm9yZSBzaWduYWwpLgorICAgICAqLworICAgIGZpbmFsIGJvb2xlYW4gdHJhbnNmZXJGb3JTaWduYWwoTm9kZSBub2RlKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIElmIGNhbm5vdCBjaGFuZ2Ugd2FpdFN0YXR1cywgdGhlIG5vZGUgaGFzIGJlZW4gY2FuY2VsbGVkLgorICAgICAgICAgKi8KKyAgICAgICAgaWYgKCFjb21wYXJlQW5kU2V0V2FpdFN0YXR1cyhub2RlLCBOb2RlLkNPTkRJVElPTiwgMCkpCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogU3BsaWNlIG9udG8gcXVldWUgYW5kIHRyeSB0byBzZXQgd2FpdFN0YXR1cyBvZiBwcmVkZWNlc3NvciB0bworICAgICAgICAgKiBpbmRpY2F0ZSB0aGF0IHRocmVhZCBpcyAocHJvYmFibHkpIHdhaXRpbmcuIElmIGNhbmNlbGxlZCBvcgorICAgICAgICAgKiBhdHRlbXB0IHRvIHNldCB3YWl0U3RhdHVzIGZhaWxzLCB3YWtlIHVwIHRvIHJlc3luYyAoaW4gd2hpY2gKKyAgICAgICAgICogY2FzZSB0aGUgd2FpdFN0YXR1cyBjYW4gYmUgdHJhbnNpZW50bHkgYW5kIGhhcm1sZXNzbHkgd3JvbmcpLgorICAgICAgICAgKi8KKyAgICAgICAgTm9kZSBwID0gZW5xKG5vZGUpOworICAgICAgICBpbnQgd3MgPSBwLndhaXRTdGF0dXM7CisgICAgICAgIGlmICh3cyA+IDAgfHwgIWNvbXBhcmVBbmRTZXRXYWl0U3RhdHVzKHAsIHdzLCBOb2RlLlNJR05BTCkpCisgICAgICAgICAgICBMb2NrU3VwcG9ydC51bnBhcmsobm9kZS50aHJlYWQpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmFuc2ZlcnMgbm9kZSwgaWYgbmVjZXNzYXJ5LCB0byBzeW5jIHF1ZXVlIGFmdGVyIGEgY2FuY2VsbGVkCisgICAgICogd2FpdC4gUmV0dXJucyB0cnVlIGlmIHRocmVhZCB3YXMgY2FuY2VsbGVkIGJlZm9yZSBiZWluZworICAgICAqIHNpZ25hbGxlZC4KKyAgICAgKiBAcGFyYW0gbm9kZSBpdHMgbm9kZQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBjYW5jZWxsZWQgYmVmb3JlIHRoZSBub2RlIHdhcyBzaWduYWxsZWQKKyAgICAgKi8KKyAgICBmaW5hbCBib29sZWFuIHRyYW5zZmVyQWZ0ZXJDYW5jZWxsZWRXYWl0KE5vZGUgbm9kZSkgeworICAgICAgICBpZiAoY29tcGFyZUFuZFNldFdhaXRTdGF0dXMobm9kZSwgTm9kZS5DT05ESVRJT04sIDApKSB7CisgICAgICAgICAgICBlbnEobm9kZSk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICAvKgorICAgICAgICAgKiBJZiB3ZSBsb3N0IG91dCB0byBhIHNpZ25hbCgpLCB0aGVuIHdlIGNhbid0IHByb2NlZWQKKyAgICAgICAgICogdW50aWwgaXQgZmluaXNoZXMgaXRzIGVucSgpLiAgQ2FuY2VsbGluZyBkdXJpbmcgYW4KKyAgICAgICAgICogaW5jb21wbGV0ZSB0cmFuc2ZlciBpcyBib3RoIHJhcmUgYW5kIHRyYW5zaWVudCwgc28ganVzdAorICAgICAgICAgKiBzcGluLgorICAgICAgICAgKi8KKyAgICAgICAgd2hpbGUgKCFpc09uU3luY1F1ZXVlKG5vZGUpKQorICAgICAgICAgICAgVGhyZWFkLnlpZWxkKCk7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnZva2VzIHJlbGVhc2Ugd2l0aCBjdXJyZW50IHN0YXRlIHZhbHVlOyByZXR1cm5zIHNhdmVkIHN0YXRlLgorICAgICAqIENhbmNlbHMgbm9kZSBhbmQgdGhyb3dzIGV4Y2VwdGlvbiBvbiBmYWlsdXJlLgorICAgICAqIEBwYXJhbSBub2RlIHRoZSBjb25kaXRpb24gbm9kZSBmb3IgdGhpcyB3YWl0CisgICAgICogQHJldHVybiBwcmV2aW91cyBzeW5jIHN0YXRlCisgICAgICovCisgICAgZmluYWwgaW50IGZ1bGx5UmVsZWFzZShOb2RlIG5vZGUpIHsKKyAgICAgICAgYm9vbGVhbiBmYWlsZWQgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IHNhdmVkU3RhdGUgPSBnZXRTdGF0ZSgpOworICAgICAgICAgICAgaWYgKHJlbGVhc2Uoc2F2ZWRTdGF0ZSkpIHsKKyAgICAgICAgICAgICAgICBmYWlsZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICByZXR1cm4gc2F2ZWRTdGF0ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChmYWlsZWQpCisgICAgICAgICAgICAgICAgbm9kZS53YWl0U3RhdHVzID0gTm9kZS5DQU5DRUxMRUQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBJbnN0cnVtZW50YXRpb24gbWV0aG9kcyBmb3IgY29uZGl0aW9ucworCisgICAgLyoqCisgICAgICogUXVlcmllcyB3aGV0aGVyIHRoZSBnaXZlbiBDb25kaXRpb25PYmplY3QKKyAgICAgKiB1c2VzIHRoaXMgc3luY2hyb25pemVyIGFzIGl0cyBsb2NrLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbmRpdGlvbiB0aGUgY29uZGl0aW9uCisgICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIG93bmVkCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgY29uZGl0aW9uIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBvd25zKENvbmRpdGlvbk9iamVjdCBjb25kaXRpb24pIHsKKyAgICAgICAgaWYgKGNvbmRpdGlvbiA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIHJldHVybiBjb25kaXRpb24uaXNPd25lZEJ5KHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFF1ZXJpZXMgd2hldGhlciBhbnkgdGhyZWFkcyBhcmUgd2FpdGluZyBvbiB0aGUgZ2l2ZW4gY29uZGl0aW9uCisgICAgICogYXNzb2NpYXRlZCB3aXRoIHRoaXMgc3luY2hyb25pemVyLiBOb3RlIHRoYXQgYmVjYXVzZSB0aW1lb3V0cworICAgICAqIGFuZCBpbnRlcnJ1cHRzIG1heSBvY2N1ciBhdCBhbnkgdGltZSwgYSA8dHQ+dHJ1ZTwvdHQ+IHJldHVybgorICAgICAqIGRvZXMgbm90IGd1YXJhbnRlZSB0aGF0IGEgZnV0dXJlIDx0dD5zaWduYWw8L3R0PiB3aWxsIGF3YWtlbgorICAgICAqIGFueSB0aHJlYWRzLiAgVGhpcyBtZXRob2QgaXMgZGVzaWduZWQgcHJpbWFyaWx5IGZvciB1c2UgaW4KKyAgICAgKiBtb25pdG9yaW5nIG9mIHRoZSBzeXN0ZW0gc3RhdGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29uZGl0aW9uIHRoZSBjb25kaXRpb24KKyAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhlcmUgYXJlIGFueSB3YWl0aW5nIHRocmVhZHMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gaWYgZXhjbHVzaXZlIHN5bmNocm9uaXphdGlvbgorICAgICAqICAgICAgICAgaXMgbm90IGhlbGQKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gY29uZGl0aW9uIGlzCisgICAgICogICAgICAgICBub3QgYXNzb2NpYXRlZCB3aXRoIHRoaXMgc3luY2hyb25pemVyCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgY29uZGl0aW9uIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNXYWl0ZXJzKENvbmRpdGlvbk9iamVjdCBjb25kaXRpb24pIHsKKyAgICAgICAgaWYgKCFvd25zKGNvbmRpdGlvbikpCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJOb3Qgb3duZXIiKTsKKyAgICAgICAgcmV0dXJuIGNvbmRpdGlvbi5oYXNXYWl0ZXJzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBlc3RpbWF0ZSBvZiB0aGUgbnVtYmVyIG9mIHRocmVhZHMgd2FpdGluZyBvbiB0aGUKKyAgICAgKiBnaXZlbiBjb25kaXRpb24gYXNzb2NpYXRlZCB3aXRoIHRoaXMgc3luY2hyb25pemVyLiBOb3RlIHRoYXQKKyAgICAgKiBiZWNhdXNlIHRpbWVvdXRzIGFuZCBpbnRlcnJ1cHRzIG1heSBvY2N1ciBhdCBhbnkgdGltZSwgdGhlCisgICAgICogZXN0aW1hdGUgc2VydmVzIG9ubHkgYXMgYW4gdXBwZXIgYm91bmQgb24gdGhlIGFjdHVhbCBudW1iZXIgb2YKKyAgICAgKiB3YWl0ZXJzLiAgVGhpcyBtZXRob2QgaXMgZGVzaWduZWQgZm9yIHVzZSBpbiBtb25pdG9yaW5nIG9mIHRoZQorICAgICAqIHN5c3RlbSBzdGF0ZSwgbm90IGZvciBzeW5jaHJvbml6YXRpb24gY29udHJvbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb25kaXRpb24gdGhlIGNvbmRpdGlvbgorICAgICAqIEByZXR1cm4gdGhlIGVzdGltYXRlZCBudW1iZXIgb2Ygd2FpdGluZyB0aHJlYWRzCisgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIGV4Y2x1c2l2ZSBzeW5jaHJvbml6YXRpb24KKyAgICAgKiAgICAgICAgIGlzIG5vdCBoZWxkCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGNvbmRpdGlvbiBpcworICAgICAqICAgICAgICAgbm90IGFzc29jaWF0ZWQgd2l0aCB0aGlzIHN5bmNocm9uaXplcgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGNvbmRpdGlvbiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRXYWl0UXVldWVMZW5ndGgoQ29uZGl0aW9uT2JqZWN0IGNvbmRpdGlvbikgeworICAgICAgICBpZiAoIW93bnMoY29uZGl0aW9uKSkKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5vdCBvd25lciIpOworICAgICAgICByZXR1cm4gY29uZGl0aW9uLmdldFdhaXRRdWV1ZUxlbmd0aCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb2xsZWN0aW9uIGNvbnRhaW5pbmcgdGhvc2UgdGhyZWFkcyB0aGF0IG1heSBiZQorICAgICAqIHdhaXRpbmcgb24gdGhlIGdpdmVuIGNvbmRpdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhpcworICAgICAqIHN5bmNocm9uaXplci4gIEJlY2F1c2UgdGhlIGFjdHVhbCBzZXQgb2YgdGhyZWFkcyBtYXkgY2hhbmdlCisgICAgICogZHluYW1pY2FsbHkgd2hpbGUgY29uc3RydWN0aW5nIHRoaXMgcmVzdWx0LCB0aGUgcmV0dXJuZWQKKyAgICAgKiBjb2xsZWN0aW9uIGlzIG9ubHkgYSBiZXN0LWVmZm9ydCBlc3RpbWF0ZS4gVGhlIGVsZW1lbnRzIG9mIHRoZQorICAgICAqIHJldHVybmVkIGNvbGxlY3Rpb24gYXJlIGluIG5vIHBhcnRpY3VsYXIgb3JkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29uZGl0aW9uIHRoZSBjb25kaXRpb24KKyAgICAgKiBAcmV0dXJuIHRoZSBjb2xsZWN0aW9uIG9mIHRocmVhZHMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gaWYgZXhjbHVzaXZlIHN5bmNocm9uaXphdGlvbgorICAgICAqICAgICAgICAgaXMgbm90IGhlbGQKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gY29uZGl0aW9uIGlzCisgICAgICogICAgICAgICBub3QgYXNzb2NpYXRlZCB3aXRoIHRoaXMgc3luY2hyb25pemVyCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgY29uZGl0aW9uIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgQ29sbGVjdGlvbjxUaHJlYWQ+IGdldFdhaXRpbmdUaHJlYWRzKENvbmRpdGlvbk9iamVjdCBjb25kaXRpb24pIHsKKyAgICAgICAgaWYgKCFvd25zKGNvbmRpdGlvbikpCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJOb3Qgb3duZXIiKTsKKyAgICAgICAgcmV0dXJuIGNvbmRpdGlvbi5nZXRXYWl0aW5nVGhyZWFkcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbmRpdGlvbiBpbXBsZW1lbnRhdGlvbiBmb3IgYSB7QGxpbmsKKyAgICAgKiBBYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplcn0gc2VydmluZyBhcyB0aGUgYmFzaXMgb2YgYSB7QGxpbmsKKyAgICAgKiBMb2NrfSBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKgorICAgICAqIDxwPk1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciB0aGlzIGNsYXNzIGRlc2NyaWJlcyBtZWNoYW5pY3MsCisgICAgICogbm90IGJlaGF2aW9yYWwgc3BlY2lmaWNhdGlvbnMgZnJvbSB0aGUgcG9pbnQgb2YgdmlldyBvZiBMb2NrCisgICAgICogYW5kIENvbmRpdGlvbiB1c2Vycy4gRXhwb3J0ZWQgdmVyc2lvbnMgb2YgdGhpcyBjbGFzcyB3aWxsIGluCisgICAgICogZ2VuZXJhbCBuZWVkIHRvIGJlIGFjY29tcGFuaWVkIGJ5IGRvY3VtZW50YXRpb24gZGVzY3JpYmluZworICAgICAqIGNvbmRpdGlvbiBzZW1hbnRpY3MgdGhhdCByZWx5IG9uIHRob3NlIG9mIHRoZSBhc3NvY2lhdGVkCisgICAgICogPHR0PkFic3RyYWN0UXVldWVkU3luY2hyb25pemVyPC90dD4uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGNsYXNzIGlzIFNlcmlhbGl6YWJsZSwgYnV0IGFsbCBmaWVsZHMgYXJlIHRyYW5zaWVudCwKKyAgICAgKiBzbyBkZXNlcmlhbGl6ZWQgY29uZGl0aW9ucyBoYXZlIG5vIHdhaXRlcnMuCisgICAgICovCisgICAgcHVibGljIGNsYXNzIENvbmRpdGlvbk9iamVjdCBpbXBsZW1lbnRzIENvbmRpdGlvbiwgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxMTczOTg0ODcyNTcyNDE0Njk5TDsKKyAgICAgICAgLyoqIEZpcnN0IG5vZGUgb2YgY29uZGl0aW9uIHF1ZXVlLiAqLworICAgICAgICBwcml2YXRlIHRyYW5zaWVudCBOb2RlIGZpcnN0V2FpdGVyOworICAgICAgICAvKiogTGFzdCBub2RlIG9mIGNvbmRpdGlvbiBxdWV1ZS4gKi8KKyAgICAgICAgcHJpdmF0ZSB0cmFuc2llbnQgTm9kZSBsYXN0V2FpdGVyOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IDx0dD5Db25kaXRpb25PYmplY3Q8L3R0PiBpbnN0YW5jZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBDb25kaXRpb25PYmplY3QoKSB7IH0KKworICAgICAgICAvLyBJbnRlcm5hbCBtZXRob2RzCisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEFkZHMgYSBuZXcgd2FpdGVyIHRvIHdhaXQgcXVldWUuCisgICAgICAgICAqIEByZXR1cm4gaXRzIG5ldyB3YWl0IG5vZGUKKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgTm9kZSBhZGRDb25kaXRpb25XYWl0ZXIoKSB7CisgICAgICAgICAgICBOb2RlIHQgPSBsYXN0V2FpdGVyOworICAgICAgICAgICAgLy8gSWYgbGFzdFdhaXRlciBpcyBjYW5jZWxsZWQsIGNsZWFuIG91dC4KKyAgICAgICAgICAgIGlmICh0ICE9IG51bGwgJiYgdC53YWl0U3RhdHVzICE9IE5vZGUuQ09ORElUSU9OKSB7CisgICAgICAgICAgICAgICAgdW5saW5rQ2FuY2VsbGVkV2FpdGVycygpOworICAgICAgICAgICAgICAgIHQgPSBsYXN0V2FpdGVyOworICAgICAgICAgICAgfQorICAgICAgICAgICAgTm9kZSBub2RlID0gbmV3IE5vZGUoVGhyZWFkLmN1cnJlbnRUaHJlYWQoKSwgTm9kZS5DT05ESVRJT04pOworICAgICAgICAgICAgaWYgKHQgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICBmaXJzdFdhaXRlciA9IG5vZGU7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgdC5uZXh0V2FpdGVyID0gbm9kZTsKKyAgICAgICAgICAgIGxhc3RXYWl0ZXIgPSBub2RlOworICAgICAgICAgICAgcmV0dXJuIG5vZGU7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmVtb3ZlcyBhbmQgdHJhbnNmZXJzIG5vZGVzIHVudGlsIGhpdCBub24tY2FuY2VsbGVkIG9uZSBvcgorICAgICAgICAgKiBudWxsLiBTcGxpdCBvdXQgZnJvbSBzaWduYWwgaW4gcGFydCB0byBlbmNvdXJhZ2UgY29tcGlsZXJzCisgICAgICAgICAqIHRvIGlubGluZSB0aGUgY2FzZSBvZiBubyB3YWl0ZXJzLgorICAgICAgICAgKiBAcGFyYW0gZmlyc3QgKG5vbi1udWxsKSB0aGUgZmlyc3Qgbm9kZSBvbiBjb25kaXRpb24gcXVldWUKKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgdm9pZCBkb1NpZ25hbChOb2RlIGZpcnN0KSB7CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgaWYgKCAoZmlyc3RXYWl0ZXIgPSBmaXJzdC5uZXh0V2FpdGVyKSA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICBsYXN0V2FpdGVyID0gbnVsbDsKKyAgICAgICAgICAgICAgICBmaXJzdC5uZXh0V2FpdGVyID0gbnVsbDsKKyAgICAgICAgICAgIH0gd2hpbGUgKCF0cmFuc2ZlckZvclNpZ25hbChmaXJzdCkgJiYKKyAgICAgICAgICAgICAgICAgICAgIChmaXJzdCA9IGZpcnN0V2FpdGVyKSAhPSBudWxsKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZW1vdmVzIGFuZCB0cmFuc2ZlcnMgYWxsIG5vZGVzLgorICAgICAgICAgKiBAcGFyYW0gZmlyc3QgKG5vbi1udWxsKSB0aGUgZmlyc3Qgbm9kZSBvbiBjb25kaXRpb24gcXVldWUKKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgdm9pZCBkb1NpZ25hbEFsbChOb2RlIGZpcnN0KSB7CisgICAgICAgICAgICBsYXN0V2FpdGVyID0gZmlyc3RXYWl0ZXIgPSBudWxsOworICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIE5vZGUgbmV4dCA9IGZpcnN0Lm5leHRXYWl0ZXI7CisgICAgICAgICAgICAgICAgZmlyc3QubmV4dFdhaXRlciA9IG51bGw7CisgICAgICAgICAgICAgICAgdHJhbnNmZXJGb3JTaWduYWwoZmlyc3QpOworICAgICAgICAgICAgICAgIGZpcnN0ID0gbmV4dDsKKyAgICAgICAgICAgIH0gd2hpbGUgKGZpcnN0ICE9IG51bGwpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFVubGlua3MgY2FuY2VsbGVkIHdhaXRlciBub2RlcyBmcm9tIGNvbmRpdGlvbiBxdWV1ZS4KKyAgICAgICAgICogQ2FsbGVkIG9ubHkgd2hpbGUgaG9sZGluZyBsb2NrLiBUaGlzIGlzIGNhbGxlZCB3aGVuCisgICAgICAgICAqIGNhbmNlbGxhdGlvbiBvY2N1cnJlZCBkdXJpbmcgY29uZGl0aW9uIHdhaXQsIGFuZCB1cG9uCisgICAgICAgICAqIGluc2VydGlvbiBvZiBhIG5ldyB3YWl0ZXIgd2hlbiBsYXN0V2FpdGVyIGlzIHNlZW4gdG8gaGF2ZQorICAgICAgICAgKiBiZWVuIGNhbmNlbGxlZC4gVGhpcyBtZXRob2QgaXMgbmVlZGVkIHRvIGF2b2lkIGdhcmJhZ2UKKyAgICAgICAgICogcmV0ZW50aW9uIGluIHRoZSBhYnNlbmNlIG9mIHNpZ25hbHMuIFNvIGV2ZW4gdGhvdWdoIGl0IG1heQorICAgICAgICAgKiByZXF1aXJlIGEgZnVsbCB0cmF2ZXJzYWwsIGl0IGNvbWVzIGludG8gcGxheSBvbmx5IHdoZW4KKyAgICAgICAgICogdGltZW91dHMgb3IgY2FuY2VsbGF0aW9ucyBvY2N1ciBpbiB0aGUgYWJzZW5jZSBvZgorICAgICAgICAgKiBzaWduYWxzLiBJdCB0cmF2ZXJzZXMgYWxsIG5vZGVzIHJhdGhlciB0aGFuIHN0b3BwaW5nIGF0IGEKKyAgICAgICAgICogcGFydGljdWxhciB0YXJnZXQgdG8gdW5saW5rIGFsbCBwb2ludGVycyB0byBnYXJiYWdlIG5vZGVzCisgICAgICAgICAqIHdpdGhvdXQgcmVxdWlyaW5nIG1hbnkgcmUtdHJhdmVyc2FscyBkdXJpbmcgY2FuY2VsbGF0aW9uCisgICAgICAgICAqIHN0b3Jtcy4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgdm9pZCB1bmxpbmtDYW5jZWxsZWRXYWl0ZXJzKCkgeworICAgICAgICAgICAgTm9kZSB0ID0gZmlyc3RXYWl0ZXI7CisgICAgICAgICAgICBOb2RlIHRyYWlsID0gbnVsbDsKKyAgICAgICAgICAgIHdoaWxlICh0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBOb2RlIG5leHQgPSB0Lm5leHRXYWl0ZXI7CisgICAgICAgICAgICAgICAgaWYgKHQud2FpdFN0YXR1cyAhPSBOb2RlLkNPTkRJVElPTikgeworICAgICAgICAgICAgICAgICAgICB0Lm5leHRXYWl0ZXIgPSBudWxsOworICAgICAgICAgICAgICAgICAgICBpZiAodHJhaWwgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0V2FpdGVyID0gbmV4dDsKKyAgICAgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICAgICAgdHJhaWwubmV4dFdhaXRlciA9IG5leHQ7CisgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0ID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgICAgICBsYXN0V2FpdGVyID0gdHJhaWw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgdHJhaWwgPSB0OworICAgICAgICAgICAgICAgIHQgPSBuZXh0OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gcHVibGljIG1ldGhvZHMKKworICAgICAgICAvKioKKyAgICAgICAgICogTW92ZXMgdGhlIGxvbmdlc3Qtd2FpdGluZyB0aHJlYWQsIGlmIG9uZSBleGlzdHMsIGZyb20gdGhlCisgICAgICAgICAqIHdhaXQgcXVldWUgZm9yIHRoaXMgY29uZGl0aW9uIHRvIHRoZSB3YWl0IHF1ZXVlIGZvciB0aGUKKyAgICAgICAgICogb3duaW5nIGxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbiBpZiB7QGxpbmsgI2lzSGVsZEV4Y2x1c2l2ZWx5fQorICAgICAgICAgKiAgICAgICAgIHJldHVybnMge0Bjb2RlIGZhbHNlfQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZpbmFsIHZvaWQgc2lnbmFsKCkgeworICAgICAgICAgICAgaWYgKCFpc0hlbGRFeGNsdXNpdmVseSgpKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBOb2RlIGZpcnN0ID0gZmlyc3RXYWl0ZXI7CisgICAgICAgICAgICBpZiAoZmlyc3QgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICBkb1NpZ25hbChmaXJzdCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogTW92ZXMgYWxsIHRocmVhZHMgZnJvbSB0aGUgd2FpdCBxdWV1ZSBmb3IgdGhpcyBjb25kaXRpb24gdG8KKyAgICAgICAgICogdGhlIHdhaXQgcXVldWUgZm9yIHRoZSBvd25pbmcgbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIHtAbGluayAjaXNIZWxkRXhjbHVzaXZlbHl9CisgICAgICAgICAqICAgICAgICAgcmV0dXJucyB7QGNvZGUgZmFsc2V9CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmluYWwgdm9pZCBzaWduYWxBbGwoKSB7CisgICAgICAgICAgICBpZiAoIWlzSGVsZEV4Y2x1c2l2ZWx5KCkpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIE5vZGUgZmlyc3QgPSBmaXJzdFdhaXRlcjsKKyAgICAgICAgICAgIGlmIChmaXJzdCAhPSBudWxsKQorICAgICAgICAgICAgICAgIGRvU2lnbmFsQWxsKGZpcnN0KTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbXBsZW1lbnRzIHVuaW50ZXJydXB0aWJsZSBjb25kaXRpb24gd2FpdC4KKyAgICAgICAgICogPG9sPgorICAgICAgICAgKiA8bGk+IFNhdmUgbG9jayBzdGF0ZSByZXR1cm5lZCBieSB7QGxpbmsgI2dldFN0YXRlfS4KKyAgICAgICAgICogPGxpPiBJbnZva2Uge0BsaW5rICNyZWxlYXNlfSB3aXRoCisgICAgICAgICAqICAgICAgc2F2ZWQgc3RhdGUgYXMgYXJndW1lbnQsIHRocm93aW5nCisgICAgICAgICAqICAgICAgSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbiBpZiBpdCBmYWlscy4KKyAgICAgICAgICogPGxpPiBCbG9jayB1bnRpbCBzaWduYWxsZWQuCisgICAgICAgICAqIDxsaT4gUmVhY3F1aXJlIGJ5IGludm9raW5nIHNwZWNpYWxpemVkIHZlcnNpb24gb2YKKyAgICAgICAgICogICAgICB7QGxpbmsgI2FjcXVpcmV9IHdpdGggc2F2ZWQgc3RhdGUgYXMgYXJndW1lbnQuCisgICAgICAgICAqIDwvb2w+CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmluYWwgdm9pZCBhd2FpdFVuaW50ZXJydXB0aWJseSgpIHsKKyAgICAgICAgICAgIE5vZGUgbm9kZSA9IGFkZENvbmRpdGlvbldhaXRlcigpOworICAgICAgICAgICAgaW50IHNhdmVkU3RhdGUgPSBmdWxseVJlbGVhc2Uobm9kZSk7CisgICAgICAgICAgICBib29sZWFuIGludGVycnVwdGVkID0gZmFsc2U7CisgICAgICAgICAgICB3aGlsZSAoIWlzT25TeW5jUXVldWUobm9kZSkpIHsKKyAgICAgICAgICAgICAgICBMb2NrU3VwcG9ydC5wYXJrKHRoaXMpOworICAgICAgICAgICAgICAgIGlmIChUaHJlYWQuaW50ZXJydXB0ZWQoKSkKKyAgICAgICAgICAgICAgICAgICAgaW50ZXJydXB0ZWQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFjcXVpcmVRdWV1ZWQobm9kZSwgc2F2ZWRTdGF0ZSkgfHwgaW50ZXJydXB0ZWQpCisgICAgICAgICAgICAgICAgc2VsZkludGVycnVwdCgpOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogRm9yIGludGVycnVwdGlibGUgd2FpdHMsIHdlIG5lZWQgdG8gdHJhY2sgd2hldGhlciB0byB0aHJvdworICAgICAgICAgKiBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgaWYgaW50ZXJydXB0ZWQgd2hpbGUgYmxvY2tlZCBvbgorICAgICAgICAgKiBjb25kaXRpb24sIHZlcnN1cyByZWludGVycnVwdCBjdXJyZW50IHRocmVhZCwgaWYKKyAgICAgICAgICogaW50ZXJydXB0ZWQgd2hpbGUgYmxvY2tlZCB3YWl0aW5nIHRvIHJlLWFjcXVpcmUuCisgICAgICAgICAqLworCisgICAgICAgIC8qKiBNb2RlIG1lYW5pbmcgdG8gcmVpbnRlcnJ1cHQgb24gZXhpdCBmcm9tIHdhaXQgKi8KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJFSU5URVJSVVBUID0gIDE7CisgICAgICAgIC8qKiBNb2RlIG1lYW5pbmcgdG8gdGhyb3cgSW50ZXJydXB0ZWRFeGNlcHRpb24gb24gZXhpdCBmcm9tIHdhaXQgKi8KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRIUk9XX0lFICAgID0gLTE7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENoZWNrcyBmb3IgaW50ZXJydXB0LCByZXR1cm5pbmcgVEhST1dfSUUgaWYgaW50ZXJydXB0ZWQKKyAgICAgICAgICogYmVmb3JlIHNpZ25hbGxlZCwgUkVJTlRFUlJVUFQgaWYgYWZ0ZXIgc2lnbmFsbGVkLCBvcgorICAgICAgICAgKiAwIGlmIG5vdCBpbnRlcnJ1cHRlZC4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgaW50IGNoZWNrSW50ZXJydXB0V2hpbGVXYWl0aW5nKE5vZGUgbm9kZSkgeworICAgICAgICAgICAgcmV0dXJuIFRocmVhZC5pbnRlcnJ1cHRlZCgpID8KKyAgICAgICAgICAgICAgICAodHJhbnNmZXJBZnRlckNhbmNlbGxlZFdhaXQobm9kZSkgPyBUSFJPV19JRSA6IFJFSU5URVJSVVBUKSA6CisgICAgICAgICAgICAgICAgMDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24sIHJlaW50ZXJydXB0cyBjdXJyZW50IHRocmVhZCwgb3IKKyAgICAgICAgICogZG9lcyBub3RoaW5nLCBkZXBlbmRpbmcgb24gbW9kZS4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgdm9pZCByZXBvcnRJbnRlcnJ1cHRBZnRlcldhaXQoaW50IGludGVycnVwdE1vZGUpCisgICAgICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKGludGVycnVwdE1vZGUgPT0gVEhST1dfSUUpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBlbHNlIGlmIChpbnRlcnJ1cHRNb2RlID09IFJFSU5URVJSVVBUKQorICAgICAgICAgICAgICAgIHNlbGZJbnRlcnJ1cHQoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBJbXBsZW1lbnRzIGludGVycnVwdGlibGUgY29uZGl0aW9uIHdhaXQuCisgICAgICAgICAqIDxvbD4KKyAgICAgICAgICogPGxpPiBJZiBjdXJyZW50IHRocmVhZCBpcyBpbnRlcnJ1cHRlZCwgdGhyb3cgSW50ZXJydXB0ZWRFeGNlcHRpb24uCisgICAgICAgICAqIDxsaT4gU2F2ZSBsb2NrIHN0YXRlIHJldHVybmVkIGJ5IHtAbGluayAjZ2V0U3RhdGV9LgorICAgICAgICAgKiA8bGk+IEludm9rZSB7QGxpbmsgI3JlbGVhc2V9IHdpdGgKKyAgICAgICAgICogICAgICBzYXZlZCBzdGF0ZSBhcyBhcmd1bWVudCwgdGhyb3dpbmcKKyAgICAgICAgICogICAgICBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIGl0IGZhaWxzLgorICAgICAgICAgKiA8bGk+IEJsb2NrIHVudGlsIHNpZ25hbGxlZCBvciBpbnRlcnJ1cHRlZC4KKyAgICAgICAgICogPGxpPiBSZWFjcXVpcmUgYnkgaW52b2tpbmcgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZgorICAgICAgICAgKiAgICAgIHtAbGluayAjYWNxdWlyZX0gd2l0aCBzYXZlZCBzdGF0ZSBhcyBhcmd1bWVudC4KKyAgICAgICAgICogPGxpPiBJZiBpbnRlcnJ1cHRlZCB3aGlsZSBibG9ja2VkIGluIHN0ZXAgNCwgdGhyb3cgSW50ZXJydXB0ZWRFeGNlcHRpb24uCisgICAgICAgICAqIDwvb2w+CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgZmluYWwgdm9pZCBhd2FpdCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoVGhyZWFkLmludGVycnVwdGVkKCkpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVycnVwdGVkRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBOb2RlIG5vZGUgPSBhZGRDb25kaXRpb25XYWl0ZXIoKTsKKyAgICAgICAgICAgIGludCBzYXZlZFN0YXRlID0gZnVsbHlSZWxlYXNlKG5vZGUpOworICAgICAgICAgICAgaW50IGludGVycnVwdE1vZGUgPSAwOworICAgICAgICAgICAgd2hpbGUgKCFpc09uU3luY1F1ZXVlKG5vZGUpKSB7CisgICAgICAgICAgICAgICAgTG9ja1N1cHBvcnQucGFyayh0aGlzKTsKKyAgICAgICAgICAgICAgICBpZiAoKGludGVycnVwdE1vZGUgPSBjaGVja0ludGVycnVwdFdoaWxlV2FpdGluZyhub2RlKSkgIT0gMCkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYWNxdWlyZVF1ZXVlZChub2RlLCBzYXZlZFN0YXRlKSAmJiBpbnRlcnJ1cHRNb2RlICE9IFRIUk9XX0lFKQorICAgICAgICAgICAgICAgIGludGVycnVwdE1vZGUgPSBSRUlOVEVSUlVQVDsKKyAgICAgICAgICAgIGlmIChub2RlLm5leHRXYWl0ZXIgIT0gbnVsbCkgLy8gY2xlYW4gdXAgaWYgY2FuY2VsbGVkCisgICAgICAgICAgICAgICAgdW5saW5rQ2FuY2VsbGVkV2FpdGVycygpOworICAgICAgICAgICAgaWYgKGludGVycnVwdE1vZGUgIT0gMCkKKyAgICAgICAgICAgICAgICByZXBvcnRJbnRlcnJ1cHRBZnRlcldhaXQoaW50ZXJydXB0TW9kZSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogSW1wbGVtZW50cyB0aW1lZCBjb25kaXRpb24gd2FpdC4KKyAgICAgICAgICogPG9sPgorICAgICAgICAgKiA8bGk+IElmIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkLCB0aHJvdyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbi4KKyAgICAgICAgICogPGxpPiBTYXZlIGxvY2sgc3RhdGUgcmV0dXJuZWQgYnkge0BsaW5rICNnZXRTdGF0ZX0uCisgICAgICAgICAqIDxsaT4gSW52b2tlIHtAbGluayAjcmVsZWFzZX0gd2l0aAorICAgICAgICAgKiAgICAgIHNhdmVkIHN0YXRlIGFzIGFyZ3VtZW50LCB0aHJvd2luZworICAgICAgICAgKiAgICAgIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gaWYgaXQgZmFpbHMuCisgICAgICAgICAqIDxsaT4gQmxvY2sgdW50aWwgc2lnbmFsbGVkLCBpbnRlcnJ1cHRlZCwgb3IgdGltZWQgb3V0LgorICAgICAgICAgKiA8bGk+IFJlYWNxdWlyZSBieSBpbnZva2luZyBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mCisgICAgICAgICAqICAgICAge0BsaW5rICNhY3F1aXJlfSB3aXRoIHNhdmVkIHN0YXRlIGFzIGFyZ3VtZW50LgorICAgICAgICAgKiA8bGk+IElmIGludGVycnVwdGVkIHdoaWxlIGJsb2NrZWQgaW4gc3RlcCA0LCB0aHJvdyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbi4KKyAgICAgICAgICogPC9vbD4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmaW5hbCBsb25nIGF3YWl0TmFub3MobG9uZyBuYW5vc1RpbWVvdXQpCisgICAgICAgICAgICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChUaHJlYWQuaW50ZXJydXB0ZWQoKSkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJydXB0ZWRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIE5vZGUgbm9kZSA9IGFkZENvbmRpdGlvbldhaXRlcigpOworICAgICAgICAgICAgaW50IHNhdmVkU3RhdGUgPSBmdWxseVJlbGVhc2Uobm9kZSk7CisgICAgICAgICAgICBsb25nIGxhc3RUaW1lID0gU3lzdGVtLm5hbm9UaW1lKCk7CisgICAgICAgICAgICBpbnQgaW50ZXJydXB0TW9kZSA9IDA7CisgICAgICAgICAgICB3aGlsZSAoIWlzT25TeW5jUXVldWUobm9kZSkpIHsKKyAgICAgICAgICAgICAgICBpZiAobmFub3NUaW1lb3V0IDw9IDBMKSB7CisgICAgICAgICAgICAgICAgICAgIHRyYW5zZmVyQWZ0ZXJDYW5jZWxsZWRXYWl0KG5vZGUpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgTG9ja1N1cHBvcnQucGFya05hbm9zKHRoaXMsIG5hbm9zVGltZW91dCk7CisgICAgICAgICAgICAgICAgaWYgKChpbnRlcnJ1cHRNb2RlID0gY2hlY2tJbnRlcnJ1cHRXaGlsZVdhaXRpbmcobm9kZSkpICE9IDApCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICAgICAgbG9uZyBub3cgPSBTeXN0ZW0ubmFub1RpbWUoKTsKKyAgICAgICAgICAgICAgICBuYW5vc1RpbWVvdXQgLT0gbm93IC0gbGFzdFRpbWU7CisgICAgICAgICAgICAgICAgbGFzdFRpbWUgPSBub3c7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYWNxdWlyZVF1ZXVlZChub2RlLCBzYXZlZFN0YXRlKSAmJiBpbnRlcnJ1cHRNb2RlICE9IFRIUk9XX0lFKQorICAgICAgICAgICAgICAgIGludGVycnVwdE1vZGUgPSBSRUlOVEVSUlVQVDsKKyAgICAgICAgICAgIGlmIChub2RlLm5leHRXYWl0ZXIgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICB1bmxpbmtDYW5jZWxsZWRXYWl0ZXJzKCk7CisgICAgICAgICAgICBpZiAoaW50ZXJydXB0TW9kZSAhPSAwKQorICAgICAgICAgICAgICAgIHJlcG9ydEludGVycnVwdEFmdGVyV2FpdChpbnRlcnJ1cHRNb2RlKTsKKyAgICAgICAgICAgIHJldHVybiBuYW5vc1RpbWVvdXQgLSAoU3lzdGVtLm5hbm9UaW1lKCkgLSBsYXN0VGltZSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogSW1wbGVtZW50cyBhYnNvbHV0ZSB0aW1lZCBjb25kaXRpb24gd2FpdC4KKyAgICAgICAgICogPG9sPgorICAgICAgICAgKiA8bGk+IElmIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkLCB0aHJvdyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbi4KKyAgICAgICAgICogPGxpPiBTYXZlIGxvY2sgc3RhdGUgcmV0dXJuZWQgYnkge0BsaW5rICNnZXRTdGF0ZX0uCisgICAgICAgICAqIDxsaT4gSW52b2tlIHtAbGluayAjcmVsZWFzZX0gd2l0aAorICAgICAgICAgKiAgICAgIHNhdmVkIHN0YXRlIGFzIGFyZ3VtZW50LCB0aHJvd2luZworICAgICAgICAgKiAgICAgIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gaWYgaXQgZmFpbHMuCisgICAgICAgICAqIDxsaT4gQmxvY2sgdW50aWwgc2lnbmFsbGVkLCBpbnRlcnJ1cHRlZCwgb3IgdGltZWQgb3V0LgorICAgICAgICAgKiA8bGk+IFJlYWNxdWlyZSBieSBpbnZva2luZyBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mCisgICAgICAgICAqICAgICAge0BsaW5rICNhY3F1aXJlfSB3aXRoIHNhdmVkIHN0YXRlIGFzIGFyZ3VtZW50LgorICAgICAgICAgKiA8bGk+IElmIGludGVycnVwdGVkIHdoaWxlIGJsb2NrZWQgaW4gc3RlcCA0LCB0aHJvdyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbi4KKyAgICAgICAgICogPGxpPiBJZiB0aW1lZCBvdXQgd2hpbGUgYmxvY2tlZCBpbiBzdGVwIDQsIHJldHVybiBmYWxzZSwgZWxzZSB0cnVlLgorICAgICAgICAgKiA8L29sPgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gYXdhaXRVbnRpbChEYXRlIGRlYWRsaW5lKQorICAgICAgICAgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoZGVhZGxpbmUgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGxvbmcgYWJzdGltZSA9IGRlYWRsaW5lLmdldFRpbWUoKTsKKyAgICAgICAgICAgIGlmIChUaHJlYWQuaW50ZXJydXB0ZWQoKSkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJydXB0ZWRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIE5vZGUgbm9kZSA9IGFkZENvbmRpdGlvbldhaXRlcigpOworICAgICAgICAgICAgaW50IHNhdmVkU3RhdGUgPSBmdWxseVJlbGVhc2Uobm9kZSk7CisgICAgICAgICAgICBib29sZWFuIHRpbWVkb3V0ID0gZmFsc2U7CisgICAgICAgICAgICBpbnQgaW50ZXJydXB0TW9kZSA9IDA7CisgICAgICAgICAgICB3aGlsZSAoIWlzT25TeW5jUXVldWUobm9kZSkpIHsKKyAgICAgICAgICAgICAgICBpZiAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgPiBhYnN0aW1lKSB7CisgICAgICAgICAgICAgICAgICAgIHRpbWVkb3V0ID0gdHJhbnNmZXJBZnRlckNhbmNlbGxlZFdhaXQobm9kZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBMb2NrU3VwcG9ydC5wYXJrVW50aWwodGhpcywgYWJzdGltZSk7CisgICAgICAgICAgICAgICAgaWYgKChpbnRlcnJ1cHRNb2RlID0gY2hlY2tJbnRlcnJ1cHRXaGlsZVdhaXRpbmcobm9kZSkpICE9IDApCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFjcXVpcmVRdWV1ZWQobm9kZSwgc2F2ZWRTdGF0ZSkgJiYgaW50ZXJydXB0TW9kZSAhPSBUSFJPV19JRSkKKyAgICAgICAgICAgICAgICBpbnRlcnJ1cHRNb2RlID0gUkVJTlRFUlJVUFQ7CisgICAgICAgICAgICBpZiAobm9kZS5uZXh0V2FpdGVyICE9IG51bGwpCisgICAgICAgICAgICAgICAgdW5saW5rQ2FuY2VsbGVkV2FpdGVycygpOworICAgICAgICAgICAgaWYgKGludGVycnVwdE1vZGUgIT0gMCkKKyAgICAgICAgICAgICAgICByZXBvcnRJbnRlcnJ1cHRBZnRlcldhaXQoaW50ZXJydXB0TW9kZSk7CisgICAgICAgICAgICByZXR1cm4gIXRpbWVkb3V0OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEltcGxlbWVudHMgdGltZWQgY29uZGl0aW9uIHdhaXQuCisgICAgICAgICAqIDxvbD4KKyAgICAgICAgICogPGxpPiBJZiBjdXJyZW50IHRocmVhZCBpcyBpbnRlcnJ1cHRlZCwgdGhyb3cgSW50ZXJydXB0ZWRFeGNlcHRpb24uCisgICAgICAgICAqIDxsaT4gU2F2ZSBsb2NrIHN0YXRlIHJldHVybmVkIGJ5IHtAbGluayAjZ2V0U3RhdGV9LgorICAgICAgICAgKiA8bGk+IEludm9rZSB7QGxpbmsgI3JlbGVhc2V9IHdpdGgKKyAgICAgICAgICogICAgICBzYXZlZCBzdGF0ZSBhcyBhcmd1bWVudCwgdGhyb3dpbmcKKyAgICAgICAgICogICAgICBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIGl0IGZhaWxzLgorICAgICAgICAgKiA8bGk+IEJsb2NrIHVudGlsIHNpZ25hbGxlZCwgaW50ZXJydXB0ZWQsIG9yIHRpbWVkIG91dC4KKyAgICAgICAgICogPGxpPiBSZWFjcXVpcmUgYnkgaW52b2tpbmcgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZgorICAgICAgICAgKiAgICAgIHtAbGluayAjYWNxdWlyZX0gd2l0aCBzYXZlZCBzdGF0ZSBhcyBhcmd1bWVudC4KKyAgICAgICAgICogPGxpPiBJZiBpbnRlcnJ1cHRlZCB3aGlsZSBibG9ja2VkIGluIHN0ZXAgNCwgdGhyb3cgSW50ZXJydXB0ZWRFeGNlcHRpb24uCisgICAgICAgICAqIDxsaT4gSWYgdGltZWQgb3V0IHdoaWxlIGJsb2NrZWQgaW4gc3RlcCA0LCByZXR1cm4gZmFsc2UsIGVsc2UgdHJ1ZS4KKyAgICAgICAgICogPC9vbD4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGF3YWl0KGxvbmcgdGltZSwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKHVuaXQgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGxvbmcgbmFub3NUaW1lb3V0ID0gdW5pdC50b05hbm9zKHRpbWUpOworICAgICAgICAgICAgaWYgKFRocmVhZC5pbnRlcnJ1cHRlZCgpKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbigpOworICAgICAgICAgICAgTm9kZSBub2RlID0gYWRkQ29uZGl0aW9uV2FpdGVyKCk7CisgICAgICAgICAgICBpbnQgc2F2ZWRTdGF0ZSA9IGZ1bGx5UmVsZWFzZShub2RlKTsKKyAgICAgICAgICAgIGxvbmcgbGFzdFRpbWUgPSBTeXN0ZW0ubmFub1RpbWUoKTsKKyAgICAgICAgICAgIGJvb2xlYW4gdGltZWRvdXQgPSBmYWxzZTsKKyAgICAgICAgICAgIGludCBpbnRlcnJ1cHRNb2RlID0gMDsKKyAgICAgICAgICAgIHdoaWxlICghaXNPblN5bmNRdWV1ZShub2RlKSkgeworICAgICAgICAgICAgICAgIGlmIChuYW5vc1RpbWVvdXQgPD0gMEwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGltZWRvdXQgPSB0cmFuc2ZlckFmdGVyQ2FuY2VsbGVkV2FpdChub2RlKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChuYW5vc1RpbWVvdXQgPj0gc3BpbkZvclRpbWVvdXRUaHJlc2hvbGQpCisgICAgICAgICAgICAgICAgICAgIExvY2tTdXBwb3J0LnBhcmtOYW5vcyh0aGlzLCBuYW5vc1RpbWVvdXQpOworICAgICAgICAgICAgICAgIGlmICgoaW50ZXJydXB0TW9kZSA9IGNoZWNrSW50ZXJydXB0V2hpbGVXYWl0aW5nKG5vZGUpKSAhPSAwKQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBsb25nIG5vdyA9IFN5c3RlbS5uYW5vVGltZSgpOworICAgICAgICAgICAgICAgIG5hbm9zVGltZW91dCAtPSBub3cgLSBsYXN0VGltZTsKKyAgICAgICAgICAgICAgICBsYXN0VGltZSA9IG5vdzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhY3F1aXJlUXVldWVkKG5vZGUsIHNhdmVkU3RhdGUpICYmIGludGVycnVwdE1vZGUgIT0gVEhST1dfSUUpCisgICAgICAgICAgICAgICAgaW50ZXJydXB0TW9kZSA9IFJFSU5URVJSVVBUOworICAgICAgICAgICAgaWYgKG5vZGUubmV4dFdhaXRlciAhPSBudWxsKQorICAgICAgICAgICAgICAgIHVubGlua0NhbmNlbGxlZFdhaXRlcnMoKTsKKyAgICAgICAgICAgIGlmIChpbnRlcnJ1cHRNb2RlICE9IDApCisgICAgICAgICAgICAgICAgcmVwb3J0SW50ZXJydXB0QWZ0ZXJXYWl0KGludGVycnVwdE1vZGUpOworICAgICAgICAgICAgcmV0dXJuICF0aW1lZG91dDsKKyAgICAgICAgfQorCisgICAgICAgIC8vICBzdXBwb3J0IGZvciBpbnN0cnVtZW50YXRpb24KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgY29uZGl0aW9uIHdhcyBjcmVhdGVkIGJ5IHRoZSBnaXZlbgorICAgICAgICAgKiBzeW5jaHJvbml6YXRpb24gb2JqZWN0LgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBvd25lZAorICAgICAgICAgKi8KKyAgICAgICAgZmluYWwgYm9vbGVhbiBpc093bmVkQnkoQWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXIgc3luYykgeworICAgICAgICAgICAgcmV0dXJuIHN5bmMgPT0gQWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXIudGhpczsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBRdWVyaWVzIHdoZXRoZXIgYW55IHRocmVhZHMgYXJlIHdhaXRpbmcgb24gdGhpcyBjb25kaXRpb24uCisgICAgICAgICAqIEltcGxlbWVudHMge0BsaW5rIEFic3RyYWN0UXVldWVkU3luY2hyb25pemVyI2hhc1dhaXRlcnN9LgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGVyZSBhcmUgYW55IHdhaXRpbmcgdGhyZWFkcworICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gaWYge0BsaW5rICNpc0hlbGRFeGNsdXNpdmVseX0KKyAgICAgICAgICogICAgICAgICByZXR1cm5zIHtAY29kZSBmYWxzZX0KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIGhhc1dhaXRlcnMoKSB7CisgICAgICAgICAgICBpZiAoIWlzSGVsZEV4Y2x1c2l2ZWx5KCkpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGZvciAoTm9kZSB3ID0gZmlyc3RXYWl0ZXI7IHcgIT0gbnVsbDsgdyA9IHcubmV4dFdhaXRlcikgeworICAgICAgICAgICAgICAgIGlmICh3LndhaXRTdGF0dXMgPT0gTm9kZS5DT05ESVRJT04pCisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgYW4gZXN0aW1hdGUgb2YgdGhlIG51bWJlciBvZiB0aHJlYWRzIHdhaXRpbmcgb24KKyAgICAgICAgICogdGhpcyBjb25kaXRpb24uCisgICAgICAgICAqIEltcGxlbWVudHMge0BsaW5rIEFic3RyYWN0UXVldWVkU3luY2hyb25pemVyI2dldFdhaXRRdWV1ZUxlbmd0aH0uCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gdGhlIGVzdGltYXRlZCBudW1iZXIgb2Ygd2FpdGluZyB0aHJlYWRzCisgICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbiBpZiB7QGxpbmsgI2lzSGVsZEV4Y2x1c2l2ZWx5fQorICAgICAgICAgKiAgICAgICAgIHJldHVybnMge0Bjb2RlIGZhbHNlfQorICAgICAgICAgKi8KKyAgICAgICAgcHJvdGVjdGVkIGZpbmFsIGludCBnZXRXYWl0UXVldWVMZW5ndGgoKSB7CisgICAgICAgICAgICBpZiAoIWlzSGVsZEV4Y2x1c2l2ZWx5KCkpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGludCBuID0gMDsKKyAgICAgICAgICAgIGZvciAoTm9kZSB3ID0gZmlyc3RXYWl0ZXI7IHcgIT0gbnVsbDsgdyA9IHcubmV4dFdhaXRlcikgeworICAgICAgICAgICAgICAgIGlmICh3LndhaXRTdGF0dXMgPT0gTm9kZS5DT05ESVRJT04pCisgICAgICAgICAgICAgICAgICAgICsrbjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgYSBjb2xsZWN0aW9uIGNvbnRhaW5pbmcgdGhvc2UgdGhyZWFkcyB0aGF0IG1heSBiZQorICAgICAgICAgKiB3YWl0aW5nIG9uIHRoaXMgQ29uZGl0aW9uLgorICAgICAgICAgKiBJbXBsZW1lbnRzIHtAbGluayBBYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplciNnZXRXYWl0aW5nVGhyZWFkc30uCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gdGhlIGNvbGxlY3Rpb24gb2YgdGhyZWFkcworICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gaWYge0BsaW5rICNpc0hlbGRFeGNsdXNpdmVseX0KKyAgICAgICAgICogICAgICAgICByZXR1cm5zIHtAY29kZSBmYWxzZX0KKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBmaW5hbCBDb2xsZWN0aW9uPFRocmVhZD4gZ2V0V2FpdGluZ1RocmVhZHMoKSB7CisgICAgICAgICAgICBpZiAoIWlzSGVsZEV4Y2x1c2l2ZWx5KCkpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIEFycmF5TGlzdDxUaHJlYWQ+IGxpc3QgPSBuZXcgQXJyYXlMaXN0PFRocmVhZD4oKTsKKyAgICAgICAgICAgIGZvciAoTm9kZSB3ID0gZmlyc3RXYWl0ZXI7IHcgIT0gbnVsbDsgdyA9IHcubmV4dFdhaXRlcikgeworICAgICAgICAgICAgICAgIGlmICh3LndhaXRTdGF0dXMgPT0gTm9kZS5DT05ESVRJT04pIHsKKyAgICAgICAgICAgICAgICAgICAgVGhyZWFkIHQgPSB3LnRocmVhZDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QuYWRkKHQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBsaXN0OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0dXAgdG8gc3VwcG9ydCBjb21wYXJlQW5kU2V0LiBXZSBuZWVkIHRvIG5hdGl2ZWx5IGltcGxlbWVudAorICAgICAqIHRoaXMgaGVyZTogRm9yIHRoZSBzYWtlIG9mIHBlcm1pdHRpbmcgZnV0dXJlIGVuaGFuY2VtZW50cywgd2UKKyAgICAgKiBjYW5ub3QgZXhwbGljaXRseSBzdWJjbGFzcyBBdG9taWNJbnRlZ2VyLCB3aGljaCB3b3VsZCBiZQorICAgICAqIGVmZmljaWVudCBhbmQgdXNlZnVsIG90aGVyd2lzZS4gU28sIGFzIHRoZSBsZXNzZXIgb2YgZXZpbHMsIHdlCisgICAgICogbmF0aXZlbHkgaW1wbGVtZW50IHVzaW5nIGhvdHNwb3QgaW50cmluc2ljcyBBUEkuIEFuZCB3aGlsZSB3ZQorICAgICAqIGFyZSBhdCBpdCwgd2UgZG8gdGhlIHNhbWUgZm9yIG90aGVyIENBU2FibGUgZmllbGRzICh3aGljaCBjb3VsZAorICAgICAqIG90aGVyd2lzZSBiZSBkb25lIHdpdGggYXRvbWljIGZpZWxkIHVwZGF0ZXJzKS4KKyAgICAgKi8KKyAgICAvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBVbnNhZmUgdW5zYWZlID0gVW5zYWZlQWNjZXNzLlRIRV9PTkU7CisgICAgLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc3RhdGVPZmZzZXQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBoZWFkT2Zmc2V0OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgdGFpbE9mZnNldDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHdhaXRTdGF0dXNPZmZzZXQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBuZXh0T2Zmc2V0OworCisgICAgc3RhdGljIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0YXRlT2Zmc2V0ID0gdW5zYWZlLm9iamVjdEZpZWxkT2Zmc2V0CisgICAgICAgICAgICAgICAgKEFic3RyYWN0UXVldWVkU3luY2hyb25pemVyLmNsYXNzLmdldERlY2xhcmVkRmllbGQoInN0YXRlIikpOworICAgICAgICAgICAgaGVhZE9mZnNldCA9IHVuc2FmZS5vYmplY3RGaWVsZE9mZnNldAorICAgICAgICAgICAgICAgIChBYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplci5jbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJoZWFkIikpOworICAgICAgICAgICAgdGFpbE9mZnNldCA9IHVuc2FmZS5vYmplY3RGaWVsZE9mZnNldAorICAgICAgICAgICAgICAgIChBYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplci5jbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJ0YWlsIikpOworICAgICAgICAgICAgd2FpdFN0YXR1c09mZnNldCA9IHVuc2FmZS5vYmplY3RGaWVsZE9mZnNldAorICAgICAgICAgICAgICAgIChOb2RlLmNsYXNzLmdldERlY2xhcmVkRmllbGQoIndhaXRTdGF0dXMiKSk7CisgICAgICAgICAgICBuZXh0T2Zmc2V0ID0gdW5zYWZlLm9iamVjdEZpZWxkT2Zmc2V0CisgICAgICAgICAgICAgICAgKE5vZGUuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgibmV4dCIpKTsKKworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsgdGhyb3cgbmV3IEVycm9yKGV4KTsgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENBUyBoZWFkIGZpZWxkLiBVc2VkIG9ubHkgYnkgZW5xLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBjb21wYXJlQW5kU2V0SGVhZChOb2RlIHVwZGF0ZSkgeworICAgICAgICByZXR1cm4gdW5zYWZlLmNvbXBhcmVBbmRTd2FwT2JqZWN0KHRoaXMsIGhlYWRPZmZzZXQsIG51bGwsIHVwZGF0ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ0FTIHRhaWwgZmllbGQuIFVzZWQgb25seSBieSBlbnEuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGNvbXBhcmVBbmRTZXRUYWlsKE5vZGUgZXhwZWN0LCBOb2RlIHVwZGF0ZSkgeworICAgICAgICByZXR1cm4gdW5zYWZlLmNvbXBhcmVBbmRTd2FwT2JqZWN0KHRoaXMsIHRhaWxPZmZzZXQsIGV4cGVjdCwgdXBkYXRlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDQVMgd2FpdFN0YXR1cyBmaWVsZCBvZiBhIG5vZGUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBjb21wYXJlQW5kU2V0V2FpdFN0YXR1cyhOb2RlIG5vZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZXhwZWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHVwZGF0ZSkgeworICAgICAgICByZXR1cm4gdW5zYWZlLmNvbXBhcmVBbmRTd2FwSW50KG5vZGUsIHdhaXRTdGF0dXNPZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0LCB1cGRhdGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENBUyBuZXh0IGZpZWxkIG9mIGEgbm9kZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGNvbXBhcmVBbmRTZXROZXh0KE5vZGUgbm9kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgZXhwZWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSB1cGRhdGUpIHsKKyAgICAgICAgcmV0dXJuIHVuc2FmZS5jb21wYXJlQW5kU3dhcE9iamVjdChub2RlLCBuZXh0T2Zmc2V0LCBleHBlY3QsIHVwZGF0ZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL0NvbmRpdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL0NvbmRpdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg1MDRlMWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvbG9ja3MvQ29uZGl0aW9uLmphdmEKQEAgLTAsMCArMSw0NTkgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudC5sb2NrczsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC4qOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworCisvKioKKyAqIHtAY29kZSBDb25kaXRpb259IGZhY3RvcnMgb3V0IHRoZSB7QGNvZGUgT2JqZWN0fSBtb25pdG9yCisgKiBtZXRob2RzICh7QGxpbmsgT2JqZWN0I3dhaXQoKSB3YWl0fSwge0BsaW5rIE9iamVjdCNub3RpZnkgbm90aWZ5fQorICogYW5kIHtAbGluayBPYmplY3Qjbm90aWZ5QWxsIG5vdGlmeUFsbH0pIGludG8gZGlzdGluY3Qgb2JqZWN0cyB0bworICogZ2l2ZSB0aGUgZWZmZWN0IG9mIGhhdmluZyBtdWx0aXBsZSB3YWl0LXNldHMgcGVyIG9iamVjdCwgYnkKKyAqIGNvbWJpbmluZyB0aGVtIHdpdGggdGhlIHVzZSBvZiBhcmJpdHJhcnkge0BsaW5rIExvY2t9IGltcGxlbWVudGF0aW9ucy4KKyAqIFdoZXJlIGEge0Bjb2RlIExvY2t9IHJlcGxhY2VzIHRoZSB1c2Ugb2Yge0Bjb2RlIHN5bmNocm9uaXplZH0gbWV0aG9kcworICogYW5kIHN0YXRlbWVudHMsIGEge0Bjb2RlIENvbmRpdGlvbn0gcmVwbGFjZXMgdGhlIHVzZSBvZiB0aGUgT2JqZWN0CisgKiBtb25pdG9yIG1ldGhvZHMuCisgKgorICogPHA+Q29uZGl0aW9ucyAoYWxzbyBrbm93biBhcyA8ZW0+Y29uZGl0aW9uIHF1ZXVlczwvZW0+IG9yCisgKiA8ZW0+Y29uZGl0aW9uIHZhcmlhYmxlczwvZW0+KSBwcm92aWRlIGEgbWVhbnMgZm9yIG9uZSB0aHJlYWQgdG8KKyAqIHN1c3BlbmQgZXhlY3V0aW9uICh0byAmcXVvdDt3YWl0JnF1b3Q7KSB1bnRpbCBub3RpZmllZCBieSBhbm90aGVyCisgKiB0aHJlYWQgdGhhdCBzb21lIHN0YXRlIGNvbmRpdGlvbiBtYXkgbm93IGJlIHRydWUuICBCZWNhdXNlIGFjY2VzcworICogdG8gdGhpcyBzaGFyZWQgc3RhdGUgaW5mb3JtYXRpb24gb2NjdXJzIGluIGRpZmZlcmVudCB0aHJlYWRzLCBpdAorICogbXVzdCBiZSBwcm90ZWN0ZWQsIHNvIGEgbG9jayBvZiBzb21lIGZvcm0gaXMgYXNzb2NpYXRlZCB3aXRoIHRoZQorICogY29uZGl0aW9uLiBUaGUga2V5IHByb3BlcnR5IHRoYXQgd2FpdGluZyBmb3IgYSBjb25kaXRpb24gcHJvdmlkZXMKKyAqIGlzIHRoYXQgaXQgPGVtPmF0b21pY2FsbHk8L2VtPiByZWxlYXNlcyB0aGUgYXNzb2NpYXRlZCBsb2NrIGFuZAorICogc3VzcGVuZHMgdGhlIGN1cnJlbnQgdGhyZWFkLCBqdXN0IGxpa2Uge0Bjb2RlIE9iamVjdC53YWl0fS4KKyAqCisgKiA8cD5BIHtAY29kZSBDb25kaXRpb259IGluc3RhbmNlIGlzIGludHJpbnNpY2FsbHkgYm91bmQgdG8gYSBsb2NrLgorICogVG8gb2J0YWluIGEge0Bjb2RlIENvbmRpdGlvbn0gaW5zdGFuY2UgZm9yIGEgcGFydGljdWxhciB7QGxpbmsgTG9ja30KKyAqIGluc3RhbmNlIHVzZSBpdHMge0BsaW5rIExvY2sjbmV3Q29uZGl0aW9uIG5ld0NvbmRpdGlvbigpfSBtZXRob2QuCisgKgorICogPHA+QXMgYW4gZXhhbXBsZSwgc3VwcG9zZSB3ZSBoYXZlIGEgYm91bmRlZCBidWZmZXIgd2hpY2ggc3VwcG9ydHMKKyAqIHtAY29kZSBwdXR9IGFuZCB7QGNvZGUgdGFrZX0gbWV0aG9kcy4gIElmIGEKKyAqIHtAY29kZSB0YWtlfSBpcyBhdHRlbXB0ZWQgb24gYW4gZW1wdHkgYnVmZmVyLCB0aGVuIHRoZSB0aHJlYWQgd2lsbCBibG9jaworICogdW50aWwgYW4gaXRlbSBiZWNvbWVzIGF2YWlsYWJsZTsgaWYgYSB7QGNvZGUgcHV0fSBpcyBhdHRlbXB0ZWQgb24gYQorICogZnVsbCBidWZmZXIsIHRoZW4gdGhlIHRocmVhZCB3aWxsIGJsb2NrIHVudGlsIGEgc3BhY2UgYmVjb21lcyBhdmFpbGFibGUuCisgKiBXZSB3b3VsZCBsaWtlIHRvIGtlZXAgd2FpdGluZyB7QGNvZGUgcHV0fSB0aHJlYWRzIGFuZCB7QGNvZGUgdGFrZX0KKyAqIHRocmVhZHMgaW4gc2VwYXJhdGUgd2FpdC1zZXRzIHNvIHRoYXQgd2UgY2FuIHVzZSB0aGUgb3B0aW1pemF0aW9uIG9mCisgKiBvbmx5IG5vdGlmeWluZyBhIHNpbmdsZSB0aHJlYWQgYXQgYSB0aW1lIHdoZW4gaXRlbXMgb3Igc3BhY2VzIGJlY29tZQorICogYXZhaWxhYmxlIGluIHRoZSBidWZmZXIuIFRoaXMgY2FuIGJlIGFjaGlldmVkIHVzaW5nIHR3bworICoge0BsaW5rIENvbmRpdGlvbn0gaW5zdGFuY2VzLgorICogPHByZT4KKyAqIGNsYXNzIEJvdW5kZWRCdWZmZXIgeworICogICA8Yj5maW5hbCBMb2NrIGxvY2sgPSBuZXcgUmVlbnRyYW50TG9jaygpOzwvYj4KKyAqICAgZmluYWwgQ29uZGl0aW9uIG5vdEZ1bGwgID0gPGI+bG9jay5uZXdDb25kaXRpb24oKTsgPC9iPgorICogICBmaW5hbCBDb25kaXRpb24gbm90RW1wdHkgPSA8Yj5sb2NrLm5ld0NvbmRpdGlvbigpOyA8L2I+CisgKgorICogICBmaW5hbCBPYmplY3RbXSBpdGVtcyA9IG5ldyBPYmplY3RbMTAwXTsKKyAqICAgaW50IHB1dHB0ciwgdGFrZXB0ciwgY291bnQ7CisgKgorICogICBwdWJsaWMgdm9pZCBwdXQoT2JqZWN0IHgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgKiAgICAgPGI+bG9jay5sb2NrKCk7CisgKiAgICAgdHJ5IHs8L2I+CisgKiAgICAgICB3aGlsZSAoY291bnQgPT0gaXRlbXMubGVuZ3RoKQorICogICAgICAgICA8Yj5ub3RGdWxsLmF3YWl0KCk7PC9iPgorICogICAgICAgaXRlbXNbcHV0cHRyXSA9IHg7CisgKiAgICAgICBpZiAoKytwdXRwdHIgPT0gaXRlbXMubGVuZ3RoKSBwdXRwdHIgPSAwOworICogICAgICAgKytjb3VudDsKKyAqICAgICAgIDxiPm5vdEVtcHR5LnNpZ25hbCgpOzwvYj4KKyAqICAgICA8Yj59IGZpbmFsbHkgeworICogICAgICAgbG9jay51bmxvY2soKTsKKyAqICAgICB9PC9iPgorICogICB9CisgKgorICogICBwdWJsaWMgT2JqZWN0IHRha2UoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICogICAgIDxiPmxvY2subG9jaygpOworICogICAgIHRyeSB7PC9iPgorICogICAgICAgd2hpbGUgKGNvdW50ID09IDApCisgKiAgICAgICAgIDxiPm5vdEVtcHR5LmF3YWl0KCk7PC9iPgorICogICAgICAgT2JqZWN0IHggPSBpdGVtc1t0YWtlcHRyXTsKKyAqICAgICAgIGlmICgrK3Rha2VwdHIgPT0gaXRlbXMubGVuZ3RoKSB0YWtlcHRyID0gMDsKKyAqICAgICAgIC0tY291bnQ7CisgKiAgICAgICA8Yj5ub3RGdWxsLnNpZ25hbCgpOzwvYj4KKyAqICAgICAgIHJldHVybiB4OworICogICAgIDxiPn0gZmluYWxseSB7CisgKiAgICAgICBsb2NrLnVubG9jaygpOworICogICAgIH08L2I+CisgKiAgIH0KKyAqIH0KKyAqIDwvcHJlPgorICoKKyAqIChUaGUge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LkFycmF5QmxvY2tpbmdRdWV1ZX0gY2xhc3MgcHJvdmlkZXMKKyAqIHRoaXMgZnVuY3Rpb25hbGl0eSwgc28gdGhlcmUgaXMgbm8gcmVhc29uIHRvIGltcGxlbWVudCB0aGlzCisgKiBzYW1wbGUgdXNhZ2UgY2xhc3MuKQorICoKKyAqIDxwPkEge0Bjb2RlIENvbmRpdGlvbn0gaW1wbGVtZW50YXRpb24gY2FuIHByb3ZpZGUgYmVoYXZpb3IgYW5kIHNlbWFudGljcworICogdGhhdCBpcworICogZGlmZmVyZW50IGZyb20gdGhhdCBvZiB0aGUge0Bjb2RlIE9iamVjdH0gbW9uaXRvciBtZXRob2RzLCBzdWNoIGFzCisgKiBndWFyYW50ZWVkIG9yZGVyaW5nIGZvciBub3RpZmljYXRpb25zLCBvciBub3QgcmVxdWlyaW5nIGEgbG9jayB0byBiZSBoZWxkCisgKiB3aGVuIHBlcmZvcm1pbmcgbm90aWZpY2F0aW9ucy4KKyAqIElmIGFuIGltcGxlbWVudGF0aW9uIHByb3ZpZGVzIHN1Y2ggc3BlY2lhbGl6ZWQgc2VtYW50aWNzIHRoZW4gdGhlCisgKiBpbXBsZW1lbnRhdGlvbiBtdXN0IGRvY3VtZW50IHRob3NlIHNlbWFudGljcy4KKyAqCisgKiA8cD5Ob3RlIHRoYXQge0Bjb2RlIENvbmRpdGlvbn0gaW5zdGFuY2VzIGFyZSBqdXN0IG5vcm1hbCBvYmplY3RzIGFuZCBjYW4KKyAqIHRoZW1zZWx2ZXMgYmUgdXNlZCBhcyB0aGUgdGFyZ2V0IGluIGEge0Bjb2RlIHN5bmNocm9uaXplZH0gc3RhdGVtZW50LAorICogYW5kIGNhbiBoYXZlIHRoZWlyIG93biBtb25pdG9yIHtAbGluayBPYmplY3Qjd2FpdCB3YWl0fSBhbmQKKyAqIHtAbGluayBPYmplY3Qjbm90aWZ5IG5vdGlmaWNhdGlvbn0gbWV0aG9kcyBpbnZva2VkLgorICogQWNxdWlyaW5nIHRoZSBtb25pdG9yIGxvY2sgb2YgYSB7QGNvZGUgQ29uZGl0aW9ufSBpbnN0YW5jZSwgb3IgdXNpbmcgaXRzCisgKiBtb25pdG9yIG1ldGhvZHMsIGhhcyBubyBzcGVjaWZpZWQgcmVsYXRpb25zaGlwIHdpdGggYWNxdWlyaW5nIHRoZQorICoge0BsaW5rIExvY2t9IGFzc29jaWF0ZWQgd2l0aCB0aGF0IHtAY29kZSBDb25kaXRpb259IG9yIHRoZSB1c2Ugb2YgaXRzCisgKiB7QGxpbmtwbGFpbiAjYXdhaXQgd2FpdGluZ30gYW5kIHtAbGlua3BsYWluICNzaWduYWwgc2lnbmFsbGluZ30gbWV0aG9kcy4KKyAqIEl0IGlzIHJlY29tbWVuZGVkIHRoYXQgdG8gYXZvaWQgY29uZnVzaW9uIHlvdSBuZXZlciB1c2Uge0Bjb2RlIENvbmRpdGlvbn0KKyAqIGluc3RhbmNlcyBpbiB0aGlzIHdheSwgZXhjZXB0IHBlcmhhcHMgd2l0aGluIHRoZWlyIG93biBpbXBsZW1lbnRhdGlvbi4KKyAqCisgKiA8cD5FeGNlcHQgd2hlcmUgbm90ZWQsIHBhc3NpbmcgYSB7QGNvZGUgbnVsbH0gdmFsdWUgZm9yIGFueSBwYXJhbWV0ZXIKKyAqIHdpbGwgcmVzdWx0IGluIGEge0BsaW5rIE51bGxQb2ludGVyRXhjZXB0aW9ufSBiZWluZyB0aHJvd24uCisgKgorICogPGgzPkltcGxlbWVudGF0aW9uIENvbnNpZGVyYXRpb25zPC9oMz4KKyAqCisgKiA8cD5XaGVuIHdhaXRpbmcgdXBvbiBhIHtAY29kZSBDb25kaXRpb259LCBhICZxdW90OzxlbT5zcHVyaW91cworICogd2FrZXVwPC9lbT4mcXVvdDsgaXMgcGVybWl0dGVkIHRvIG9jY3VyLCBpbgorICogZ2VuZXJhbCwgYXMgYSBjb25jZXNzaW9uIHRvIHRoZSB1bmRlcmx5aW5nIHBsYXRmb3JtIHNlbWFudGljcy4KKyAqIFRoaXMgaGFzIGxpdHRsZSBwcmFjdGljYWwgaW1wYWN0IG9uIG1vc3QgYXBwbGljYXRpb24gcHJvZ3JhbXMgYXMgYQorICoge0Bjb2RlIENvbmRpdGlvbn0gc2hvdWxkIGFsd2F5cyBiZSB3YWl0ZWQgdXBvbiBpbiBhIGxvb3AsIHRlc3RpbmcKKyAqIHRoZSBzdGF0ZSBwcmVkaWNhdGUgdGhhdCBpcyBiZWluZyB3YWl0ZWQgZm9yLiAgQW4gaW1wbGVtZW50YXRpb24gaXMKKyAqIGZyZWUgdG8gcmVtb3ZlIHRoZSBwb3NzaWJpbGl0eSBvZiBzcHVyaW91cyB3YWtldXBzIGJ1dCBpdCBpcworICogcmVjb21tZW5kZWQgdGhhdCBhcHBsaWNhdGlvbnMgcHJvZ3JhbW1lcnMgYWx3YXlzIGFzc3VtZSB0aGF0IHRoZXkgY2FuCisgKiBvY2N1ciBhbmQgc28gYWx3YXlzIHdhaXQgaW4gYSBsb29wLgorICoKKyAqIDxwPlRoZSB0aHJlZSBmb3JtcyBvZiBjb25kaXRpb24gd2FpdGluZworICogKGludGVycnVwdGlibGUsIG5vbi1pbnRlcnJ1cHRpYmxlLCBhbmQgdGltZWQpIG1heSBkaWZmZXIgaW4gdGhlaXIgZWFzZSBvZgorICogaW1wbGVtZW50YXRpb24gb24gc29tZSBwbGF0Zm9ybXMgYW5kIGluIHRoZWlyIHBlcmZvcm1hbmNlIGNoYXJhY3RlcmlzdGljcy4KKyAqIEluIHBhcnRpY3VsYXIsIGl0IG1heSBiZSBkaWZmaWN1bHQgdG8gcHJvdmlkZSB0aGVzZSBmZWF0dXJlcyBhbmQgbWFpbnRhaW4KKyAqIHNwZWNpZmljIHNlbWFudGljcyBzdWNoIGFzIG9yZGVyaW5nIGd1YXJhbnRlZXMuCisgKiBGdXJ0aGVyLCB0aGUgYWJpbGl0eSB0byBpbnRlcnJ1cHQgdGhlIGFjdHVhbCBzdXNwZW5zaW9uIG9mIHRoZSB0aHJlYWQgbWF5CisgKiBub3QgYWx3YXlzIGJlIGZlYXNpYmxlIHRvIGltcGxlbWVudCBvbiBhbGwgcGxhdGZvcm1zLgorICoKKyAqIDxwPkNvbnNlcXVlbnRseSwgYW4gaW1wbGVtZW50YXRpb24gaXMgbm90IHJlcXVpcmVkIHRvIGRlZmluZSBleGFjdGx5IHRoZQorICogc2FtZSBndWFyYW50ZWVzIG9yIHNlbWFudGljcyBmb3IgYWxsIHRocmVlIGZvcm1zIG9mIHdhaXRpbmcsIG5vciBpcyBpdAorICogcmVxdWlyZWQgdG8gc3VwcG9ydCBpbnRlcnJ1cHRpb24gb2YgdGhlIGFjdHVhbCBzdXNwZW5zaW9uIG9mIHRoZSB0aHJlYWQuCisgKgorICogPHA+QW4gaW1wbGVtZW50YXRpb24gaXMgcmVxdWlyZWQgdG8KKyAqIGNsZWFybHkgZG9jdW1lbnQgdGhlIHNlbWFudGljcyBhbmQgZ3VhcmFudGVlcyBwcm92aWRlZCBieSBlYWNoIG9mIHRoZQorICogd2FpdGluZyBtZXRob2RzLCBhbmQgd2hlbiBhbiBpbXBsZW1lbnRhdGlvbiBkb2VzIHN1cHBvcnQgaW50ZXJydXB0aW9uIG9mCisgKiB0aHJlYWQgc3VzcGVuc2lvbiB0aGVuIGl0IG11c3Qgb2JleSB0aGUgaW50ZXJydXB0aW9uIHNlbWFudGljcyBhcyBkZWZpbmVkCisgKiBpbiB0aGlzIGludGVyZmFjZS4KKyAqCisgKiA8cD5BcyBpbnRlcnJ1cHRpb24gZ2VuZXJhbGx5IGltcGxpZXMgY2FuY2VsbGF0aW9uLCBhbmQgY2hlY2tzIGZvcgorICogaW50ZXJydXB0aW9uIGFyZSBvZnRlbiBpbmZyZXF1ZW50LCBhbiBpbXBsZW1lbnRhdGlvbiBjYW4gZmF2b3IgcmVzcG9uZGluZworICogdG8gYW4gaW50ZXJydXB0IG92ZXIgbm9ybWFsIG1ldGhvZCByZXR1cm4uIFRoaXMgaXMgdHJ1ZSBldmVuIGlmIGl0IGNhbiBiZQorICogc2hvd24gdGhhdCB0aGUgaW50ZXJydXB0IG9jY3VycmVkIGFmdGVyIGFub3RoZXIgYWN0aW9uIHRoYXQgbWF5IGhhdmUKKyAqIHVuYmxvY2tlZCB0aGUgdGhyZWFkLiBBbiBpbXBsZW1lbnRhdGlvbiBzaG91bGQgZG9jdW1lbnQgdGhpcyBiZWhhdmlvci4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQ29uZGl0aW9uIHsKKworICAgIC8qKgorICAgICAqIENhdXNlcyB0aGUgY3VycmVudCB0aHJlYWQgdG8gd2FpdCB1bnRpbCBpdCBpcyBzaWduYWxsZWQgb3IKKyAgICAgKiB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBsb2NrIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHtAY29kZSBDb25kaXRpb259IGlzIGF0b21pY2FsbHkKKyAgICAgKiByZWxlYXNlZCBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkIGJlY29tZXMgZGlzYWJsZWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nCisgICAgICogcHVycG9zZXMgYW5kIGxpZXMgZG9ybWFudCB1bnRpbCA8ZW0+b25lPC9lbT4gb2YgZm91ciB0aGluZ3MgaGFwcGVuczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPlNvbWUgb3RoZXIgdGhyZWFkIGludm9rZXMgdGhlIHtAbGluayAjc2lnbmFsfSBtZXRob2QgZm9yIHRoaXMKKyAgICAgKiB7QGNvZGUgQ29uZGl0aW9ufSBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkIGhhcHBlbnMgdG8gYmUgY2hvc2VuIGFzIHRoZQorICAgICAqIHRocmVhZCB0byBiZSBhd2FrZW5lZDsgb3IKKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQgaW52b2tlcyB0aGUge0BsaW5rICNzaWduYWxBbGx9IG1ldGhvZCBmb3IgdGhpcworICAgICAqIHtAY29kZSBDb25kaXRpb259OyBvcgorICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdHN9IHRoZQorICAgICAqIGN1cnJlbnQgdGhyZWFkLCBhbmQgaW50ZXJydXB0aW9uIG9mIHRocmVhZCBzdXNwZW5zaW9uIGlzIHN1cHBvcnRlZDsgb3IKKyAgICAgKiA8bGk+QSAmcXVvdDs8ZW0+c3B1cmlvdXMgd2FrZXVwPC9lbT4mcXVvdDsgb2NjdXJzLgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiA8cD5JbiBhbGwgY2FzZXMsIGJlZm9yZSB0aGlzIG1ldGhvZCBjYW4gcmV0dXJuIHRoZSBjdXJyZW50IHRocmVhZCBtdXN0CisgICAgICogcmUtYWNxdWlyZSB0aGUgbG9jayBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb25kaXRpb24uIFdoZW4gdGhlCisgICAgICogdGhyZWFkIHJldHVybnMgaXQgaXMgPGVtPmd1YXJhbnRlZWQ8L2VtPiB0byBob2xkIHRoaXMgbG9jay4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBjdXJyZW50IHRocmVhZDoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPmhhcyBpdHMgaW50ZXJydXB0ZWQgc3RhdHVzIHNldCBvbiBlbnRyeSB0byB0aGlzIG1ldGhvZDsgb3IKKyAgICAgKiA8bGk+aXMge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRlZH0gd2hpbGUgd2FpdGluZworICAgICAqIGFuZCBpbnRlcnJ1cHRpb24gb2YgdGhyZWFkIHN1c3BlbnNpb24gaXMgc3VwcG9ydGVkLAorICAgICAqIDwvdWw+CisgICAgICogdGhlbiB7QGxpbmsgSW50ZXJydXB0ZWRFeGNlcHRpb259IGlzIHRocm93biBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkJ3MKKyAgICAgKiBpbnRlcnJ1cHRlZCBzdGF0dXMgaXMgY2xlYXJlZC4gSXQgaXMgbm90IHNwZWNpZmllZCwgaW4gdGhlIGZpcnN0CisgICAgICogY2FzZSwgd2hldGhlciBvciBub3QgdGhlIHRlc3QgZm9yIGludGVycnVwdGlvbiBvY2N1cnMgYmVmb3JlIHRoZSBsb2NrCisgICAgICogaXMgcmVsZWFzZWQuCisgICAgICoKKyAgICAgKiA8cD48Yj5JbXBsZW1lbnRhdGlvbiBDb25zaWRlcmF0aW9uczwvYj4KKyAgICAgKgorICAgICAqIDxwPlRoZSBjdXJyZW50IHRocmVhZCBpcyBhc3N1bWVkIHRvIGhvbGQgdGhlIGxvY2sgYXNzb2NpYXRlZCB3aXRoIHRoaXMKKyAgICAgKiB7QGNvZGUgQ29uZGl0aW9ufSB3aGVuIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC4KKyAgICAgKiBJdCBpcyB1cCB0byB0aGUgaW1wbGVtZW50YXRpb24gdG8gZGV0ZXJtaW5lIGlmIHRoaXMgaXMKKyAgICAgKiB0aGUgY2FzZSBhbmQgaWYgbm90LCBob3cgdG8gcmVzcG9uZC4gVHlwaWNhbGx5LCBhbiBleGNlcHRpb24gd2lsbCBiZQorICAgICAqIHRocm93biAoc3VjaCBhcyB7QGxpbmsgSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbn0pIGFuZCB0aGUKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBtdXN0IGRvY3VtZW50IHRoYXQgZmFjdC4KKyAgICAgKgorICAgICAqIDxwPkFuIGltcGxlbWVudGF0aW9uIGNhbiBmYXZvciByZXNwb25kaW5nIHRvIGFuIGludGVycnVwdCBvdmVyIG5vcm1hbAorICAgICAqIG1ldGhvZCByZXR1cm4gaW4gcmVzcG9uc2UgdG8gYSBzaWduYWwuIEluIHRoYXQgY2FzZSB0aGUgaW1wbGVtZW50YXRpb24KKyAgICAgKiBtdXN0IGVuc3VyZSB0aGF0IHRoZSBzaWduYWwgaXMgcmVkaXJlY3RlZCB0byBhbm90aGVyIHdhaXRpbmcgdGhyZWFkLCBpZgorICAgICAqIHRoZXJlIGlzIG9uZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkCisgICAgICogICAgICAgICAoYW5kIGludGVycnVwdGlvbiBvZiB0aHJlYWQgc3VzcGVuc2lvbiBpcyBzdXBwb3J0ZWQpCisgICAgICovCisgICAgdm9pZCBhd2FpdCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENhdXNlcyB0aGUgY3VycmVudCB0aHJlYWQgdG8gd2FpdCB1bnRpbCBpdCBpcyBzaWduYWxsZWQuCisgICAgICoKKyAgICAgKiA8cD5UaGUgbG9jayBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb25kaXRpb24gaXMgYXRvbWljYWxseQorICAgICAqIHJlbGVhc2VkIGFuZCB0aGUgY3VycmVudCB0aHJlYWQgYmVjb21lcyBkaXNhYmxlZCBmb3IgdGhyZWFkIHNjaGVkdWxpbmcKKyAgICAgKiBwdXJwb3NlcyBhbmQgbGllcyBkb3JtYW50IHVudGlsIDxlbT5vbmU8L2VtPiBvZiB0aHJlZSB0aGluZ3MgaGFwcGVuczoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPlNvbWUgb3RoZXIgdGhyZWFkIGludm9rZXMgdGhlIHtAbGluayAjc2lnbmFsfSBtZXRob2QgZm9yIHRoaXMKKyAgICAgKiB7QGNvZGUgQ29uZGl0aW9ufSBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkIGhhcHBlbnMgdG8gYmUgY2hvc2VuIGFzIHRoZQorICAgICAqIHRocmVhZCB0byBiZSBhd2FrZW5lZDsgb3IKKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQgaW52b2tlcyB0aGUge0BsaW5rICNzaWduYWxBbGx9IG1ldGhvZCBmb3IgdGhpcworICAgICAqIHtAY29kZSBDb25kaXRpb259OyBvcgorICAgICAqIDxsaT5BICZxdW90OzxlbT5zcHVyaW91cyB3YWtldXA8L2VtPiZxdW90OyBvY2N1cnMuCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPkluIGFsbCBjYXNlcywgYmVmb3JlIHRoaXMgbWV0aG9kIGNhbiByZXR1cm4gdGhlIGN1cnJlbnQgdGhyZWFkIG11c3QKKyAgICAgKiByZS1hY3F1aXJlIHRoZSBsb2NrIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGNvbmRpdGlvbi4gV2hlbiB0aGUKKyAgICAgKiB0aHJlYWQgcmV0dXJucyBpdCBpcyA8ZW0+Z3VhcmFudGVlZDwvZW0+IHRvIGhvbGQgdGhpcyBsb2NrLgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGN1cnJlbnQgdGhyZWFkJ3MgaW50ZXJydXB0ZWQgc3RhdHVzIGlzIHNldCB3aGVuIGl0IGVudGVycworICAgICAqIHRoaXMgbWV0aG9kLCBvciBpdCBpcyB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfQorICAgICAqIHdoaWxlIHdhaXRpbmcsIGl0IHdpbGwgY29udGludWUgdG8gd2FpdCB1bnRpbCBzaWduYWxsZWQuIFdoZW4gaXQgZmluYWxseQorICAgICAqIHJldHVybnMgZnJvbSB0aGlzIG1ldGhvZCBpdHMgaW50ZXJydXB0ZWQgc3RhdHVzIHdpbGwgc3RpbGwKKyAgICAgKiBiZSBzZXQuCisgICAgICoKKyAgICAgKiA8cD48Yj5JbXBsZW1lbnRhdGlvbiBDb25zaWRlcmF0aW9uczwvYj4KKyAgICAgKgorICAgICAqIDxwPlRoZSBjdXJyZW50IHRocmVhZCBpcyBhc3N1bWVkIHRvIGhvbGQgdGhlIGxvY2sgYXNzb2NpYXRlZCB3aXRoIHRoaXMKKyAgICAgKiB7QGNvZGUgQ29uZGl0aW9ufSB3aGVuIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC4KKyAgICAgKiBJdCBpcyB1cCB0byB0aGUgaW1wbGVtZW50YXRpb24gdG8gZGV0ZXJtaW5lIGlmIHRoaXMgaXMKKyAgICAgKiB0aGUgY2FzZSBhbmQgaWYgbm90LCBob3cgdG8gcmVzcG9uZC4gVHlwaWNhbGx5LCBhbiBleGNlcHRpb24gd2lsbCBiZQorICAgICAqIHRocm93biAoc3VjaCBhcyB7QGxpbmsgSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbn0pIGFuZCB0aGUKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBtdXN0IGRvY3VtZW50IHRoYXQgZmFjdC4KKyAgICAgKi8KKyAgICB2b2lkIGF3YWl0VW5pbnRlcnJ1cHRpYmx5KCk7CisKKyAgICAvKioKKyAgICAgKiBDYXVzZXMgdGhlIGN1cnJlbnQgdGhyZWFkIHRvIHdhaXQgdW50aWwgaXQgaXMgc2lnbmFsbGVkIG9yIGludGVycnVwdGVkLAorICAgICAqIG9yIHRoZSBzcGVjaWZpZWQgd2FpdGluZyB0aW1lIGVsYXBzZXMuCisgICAgICoKKyAgICAgKiA8cD5UaGUgbG9jayBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb25kaXRpb24gaXMgYXRvbWljYWxseQorICAgICAqIHJlbGVhc2VkIGFuZCB0aGUgY3VycmVudCB0aHJlYWQgYmVjb21lcyBkaXNhYmxlZCBmb3IgdGhyZWFkIHNjaGVkdWxpbmcKKyAgICAgKiBwdXJwb3NlcyBhbmQgbGllcyBkb3JtYW50IHVudGlsIDxlbT5vbmU8L2VtPiBvZiBmaXZlIHRoaW5ncyBoYXBwZW5zOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQgaW52b2tlcyB0aGUge0BsaW5rICNzaWduYWx9IG1ldGhvZCBmb3IgdGhpcworICAgICAqIHtAY29kZSBDb25kaXRpb259IGFuZCB0aGUgY3VycmVudCB0aHJlYWQgaGFwcGVucyB0byBiZSBjaG9zZW4gYXMgdGhlCisgICAgICogdGhyZWFkIHRvIGJlIGF3YWtlbmVkOyBvcgorICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCBpbnZva2VzIHRoZSB7QGxpbmsgI3NpZ25hbEFsbH0gbWV0aG9kIGZvciB0aGlzCisgICAgICoge0Bjb2RlIENvbmRpdGlvbn07IG9yCisgICAgICogPGxpPlNvbWUgb3RoZXIgdGhyZWFkIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0c30gdGhlCisgICAgICogY3VycmVudCB0aHJlYWQsIGFuZCBpbnRlcnJ1cHRpb24gb2YgdGhyZWFkIHN1c3BlbnNpb24gaXMgc3VwcG9ydGVkOyBvcgorICAgICAqIDxsaT5UaGUgc3BlY2lmaWVkIHdhaXRpbmcgdGltZSBlbGFwc2VzOyBvcgorICAgICAqIDxsaT5BICZxdW90OzxlbT5zcHVyaW91cyB3YWtldXA8L2VtPiZxdW90OyBvY2N1cnMuCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPkluIGFsbCBjYXNlcywgYmVmb3JlIHRoaXMgbWV0aG9kIGNhbiByZXR1cm4gdGhlIGN1cnJlbnQgdGhyZWFkIG11c3QKKyAgICAgKiByZS1hY3F1aXJlIHRoZSBsb2NrIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGNvbmRpdGlvbi4gV2hlbiB0aGUKKyAgICAgKiB0aHJlYWQgcmV0dXJucyBpdCBpcyA8ZW0+Z3VhcmFudGVlZDwvZW0+IHRvIGhvbGQgdGhpcyBsb2NrLgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGN1cnJlbnQgdGhyZWFkOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+aGFzIGl0cyBpbnRlcnJ1cHRlZCBzdGF0dXMgc2V0IG9uIGVudHJ5IHRvIHRoaXMgbWV0aG9kOyBvcgorICAgICAqIDxsaT5pcyB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfSB3aGlsZSB3YWl0aW5nCisgICAgICogYW5kIGludGVycnVwdGlvbiBvZiB0aHJlYWQgc3VzcGVuc2lvbiBpcyBzdXBwb3J0ZWQsCisgICAgICogPC91bD4KKyAgICAgKiB0aGVuIHtAbGluayBJbnRlcnJ1cHRlZEV4Y2VwdGlvbn0gaXMgdGhyb3duIGFuZCB0aGUgY3VycmVudCB0aHJlYWQncworICAgICAqIGludGVycnVwdGVkIHN0YXR1cyBpcyBjbGVhcmVkLiBJdCBpcyBub3Qgc3BlY2lmaWVkLCBpbiB0aGUgZmlyc3QKKyAgICAgKiBjYXNlLCB3aGV0aGVyIG9yIG5vdCB0aGUgdGVzdCBmb3IgaW50ZXJydXB0aW9uIG9jY3VycyBiZWZvcmUgdGhlIGxvY2sKKyAgICAgKiBpcyByZWxlYXNlZC4KKyAgICAgKgorICAgICAqIDxwPlRoZSBtZXRob2QgcmV0dXJucyBhbiBlc3RpbWF0ZSBvZiB0aGUgbnVtYmVyIG9mIG5hbm9zZWNvbmRzCisgICAgICogcmVtYWluaW5nIHRvIHdhaXQgZ2l2ZW4gdGhlIHN1cHBsaWVkIHtAY29kZSBuYW5vc1RpbWVvdXR9CisgICAgICogdmFsdWUgdXBvbiByZXR1cm4sIG9yIGEgdmFsdWUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8gaWYgaXQKKyAgICAgKiB0aW1lZCBvdXQuIFRoaXMgdmFsdWUgY2FuIGJlIHVzZWQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgYW5kIGhvdworICAgICAqIGxvbmcgdG8gcmUtd2FpdCBpbiBjYXNlcyB3aGVyZSB0aGUgd2FpdCByZXR1cm5zIGJ1dCBhbiBhd2FpdGVkCisgICAgICogY29uZGl0aW9uIHN0aWxsIGRvZXMgbm90IGhvbGQuIFR5cGljYWwgdXNlcyBvZiB0aGlzIG1ldGhvZCB0YWtlCisgICAgICogdGhlIGZvbGxvd2luZyBmb3JtOgorICAgICAqCisgICAgICogIDxwcmU+IHtAY29kZQorICAgICAqIGJvb2xlYW4gYU1ldGhvZChsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpIHsKKyAgICAgKiAgIGxvbmcgbmFub3MgPSB1bml0LnRvTmFub3ModGltZW91dCk7CisgICAgICogICBsb2NrLmxvY2soKTsKKyAgICAgKiAgIHRyeSB7CisgICAgICogICAgIHdoaWxlICghY29uZGl0aW9uQmVpbmdXYWl0ZWRGb3IoKSkgeworICAgICAqICAgICAgIGlmIChuYW5vcyA8PSAwTCkKKyAgICAgKiAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgKiAgICAgICBuYW5vcyA9IHRoZUNvbmRpdGlvbi5hd2FpdE5hbm9zKG5hbm9zKTsKKyAgICAgKiAgICAgfQorICAgICAqICAgICAvLyAuLi4KKyAgICAgKiAgIH0gZmluYWxseSB7CisgICAgICogICAgIGxvY2sudW5sb2NrKCk7CisgICAgICogICB9CisgICAgICogfX08L3ByZT4KKyAgICAgKgorICAgICAqIDxwPiBEZXNpZ24gbm90ZTogVGhpcyBtZXRob2QgcmVxdWlyZXMgYSBuYW5vc2Vjb25kIGFyZ3VtZW50IHNvCisgICAgICogYXMgdG8gYXZvaWQgdHJ1bmNhdGlvbiBlcnJvcnMgaW4gcmVwb3J0aW5nIHJlbWFpbmluZyB0aW1lcy4KKyAgICAgKiBTdWNoIHByZWNpc2lvbiBsb3NzIHdvdWxkIG1ha2UgaXQgZGlmZmljdWx0IGZvciBwcm9ncmFtbWVycyB0bworICAgICAqIGVuc3VyZSB0aGF0IHRvdGFsIHdhaXRpbmcgdGltZXMgYXJlIG5vdCBzeXN0ZW1hdGljYWxseSBzaG9ydGVyCisgICAgICogdGhhbiBzcGVjaWZpZWQgd2hlbiByZS13YWl0cyBvY2N1ci4KKyAgICAgKgorICAgICAqIDxwPjxiPkltcGxlbWVudGF0aW9uIENvbnNpZGVyYXRpb25zPC9iPgorICAgICAqCisgICAgICogPHA+VGhlIGN1cnJlbnQgdGhyZWFkIGlzIGFzc3VtZWQgdG8gaG9sZCB0aGUgbG9jayBhc3NvY2lhdGVkIHdpdGggdGhpcworICAgICAqIHtAY29kZSBDb25kaXRpb259IHdoZW4gdGhpcyBtZXRob2QgaXMgY2FsbGVkLgorICAgICAqIEl0IGlzIHVwIHRvIHRoZSBpbXBsZW1lbnRhdGlvbiB0byBkZXRlcm1pbmUgaWYgdGhpcyBpcworICAgICAqIHRoZSBjYXNlIGFuZCBpZiBub3QsIGhvdyB0byByZXNwb25kLiBUeXBpY2FsbHksIGFuIGV4Y2VwdGlvbiB3aWxsIGJlCisgICAgICogdGhyb3duIChzdWNoIGFzIHtAbGluayBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9ufSkgYW5kIHRoZQorICAgICAqIGltcGxlbWVudGF0aW9uIG11c3QgZG9jdW1lbnQgdGhhdCBmYWN0LgorICAgICAqCisgICAgICogPHA+QW4gaW1wbGVtZW50YXRpb24gY2FuIGZhdm9yIHJlc3BvbmRpbmcgdG8gYW4gaW50ZXJydXB0IG92ZXIgbm9ybWFsCisgICAgICogbWV0aG9kIHJldHVybiBpbiByZXNwb25zZSB0byBhIHNpZ25hbCwgb3Igb3ZlciBpbmRpY2F0aW5nIHRoZSBlbGFwc2UKKyAgICAgKiBvZiB0aGUgc3BlY2lmaWVkIHdhaXRpbmcgdGltZS4gSW4gZWl0aGVyIGNhc2UgdGhlIGltcGxlbWVudGF0aW9uCisgICAgICogbXVzdCBlbnN1cmUgdGhhdCB0aGUgc2lnbmFsIGlzIHJlZGlyZWN0ZWQgdG8gYW5vdGhlciB3YWl0aW5nIHRocmVhZCwgaWYKKyAgICAgKiB0aGVyZSBpcyBvbmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFub3NUaW1lb3V0IHRoZSBtYXhpbXVtIHRpbWUgdG8gd2FpdCwgaW4gbmFub3NlY29uZHMKKyAgICAgKiBAcmV0dXJuIGFuIGVzdGltYXRlIG9mIHRoZSB7QGNvZGUgbmFub3NUaW1lb3V0fSB2YWx1ZSBtaW51cworICAgICAqICAgICAgICAgdGhlIHRpbWUgc3BlbnQgd2FpdGluZyB1cG9uIHJldHVybiBmcm9tIHRoaXMgbWV0aG9kLgorICAgICAqICAgICAgICAgQSBwb3NpdGl2ZSB2YWx1ZSBtYXkgYmUgdXNlZCBhcyB0aGUgYXJndW1lbnQgdG8gYQorICAgICAqICAgICAgICAgc3Vic2VxdWVudCBjYWxsIHRvIHRoaXMgbWV0aG9kIHRvIGZpbmlzaCB3YWl0aW5nIG91dAorICAgICAqICAgICAgICAgdGhlIGRlc2lyZWQgdGltZS4gIEEgdmFsdWUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8KKyAgICAgKiAgICAgICAgIGluZGljYXRlcyB0aGF0IG5vIHRpbWUgcmVtYWlucy4KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IHRocmVhZCBpcyBpbnRlcnJ1cHRlZAorICAgICAqICAgICAgICAgKGFuZCBpbnRlcnJ1cHRpb24gb2YgdGhyZWFkIHN1c3BlbnNpb24gaXMgc3VwcG9ydGVkKQorICAgICAqLworICAgIGxvbmcgYXdhaXROYW5vcyhsb25nIG5hbm9zVGltZW91dCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ2F1c2VzIHRoZSBjdXJyZW50IHRocmVhZCB0byB3YWl0IHVudGlsIGl0IGlzIHNpZ25hbGxlZCBvciBpbnRlcnJ1cHRlZCwKKyAgICAgKiBvciB0aGUgc3BlY2lmaWVkIHdhaXRpbmcgdGltZSBlbGFwc2VzLiBUaGlzIG1ldGhvZCBpcyBiZWhhdmlvcmFsbHkKKyAgICAgKiBlcXVpdmFsZW50IHRvOjxicj4KKyAgICAgKiA8cHJlPgorICAgICAqICAgYXdhaXROYW5vcyh1bml0LnRvTmFub3ModGltZSkpICZndDsgMAorICAgICAqIDwvcHJlPgorICAgICAqIEBwYXJhbSB0aW1lIHRoZSBtYXhpbXVtIHRpbWUgdG8gd2FpdAorICAgICAqIEBwYXJhbSB1bml0IHRoZSB0aW1lIHVuaXQgb2YgdGhlIHtAY29kZSB0aW1lfSBhcmd1bWVudAorICAgICAqIEByZXR1cm4ge0Bjb2RlIGZhbHNlfSBpZiB0aGUgd2FpdGluZyB0aW1lIGRldGVjdGFibHkgZWxhcHNlZAorICAgICAqICAgICAgICAgYmVmb3JlIHJldHVybiBmcm9tIHRoZSBtZXRob2QsIGVsc2Uge0Bjb2RlIHRydWV9CisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCB0aHJlYWQgaXMgaW50ZXJydXB0ZWQKKyAgICAgKiAgICAgICAgIChhbmQgaW50ZXJydXB0aW9uIG9mIHRocmVhZCBzdXNwZW5zaW9uIGlzIHN1cHBvcnRlZCkKKyAgICAgKi8KKyAgICBib29sZWFuIGF3YWl0KGxvbmcgdGltZSwgVGltZVVuaXQgdW5pdCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ2F1c2VzIHRoZSBjdXJyZW50IHRocmVhZCB0byB3YWl0IHVudGlsIGl0IGlzIHNpZ25hbGxlZCBvciBpbnRlcnJ1cHRlZCwKKyAgICAgKiBvciB0aGUgc3BlY2lmaWVkIGRlYWRsaW5lIGVsYXBzZXMuCisgICAgICoKKyAgICAgKiA8cD5UaGUgbG9jayBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb25kaXRpb24gaXMgYXRvbWljYWxseQorICAgICAqIHJlbGVhc2VkIGFuZCB0aGUgY3VycmVudCB0aHJlYWQgYmVjb21lcyBkaXNhYmxlZCBmb3IgdGhyZWFkIHNjaGVkdWxpbmcKKyAgICAgKiBwdXJwb3NlcyBhbmQgbGllcyBkb3JtYW50IHVudGlsIDxlbT5vbmU8L2VtPiBvZiBmaXZlIHRoaW5ncyBoYXBwZW5zOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQgaW52b2tlcyB0aGUge0BsaW5rICNzaWduYWx9IG1ldGhvZCBmb3IgdGhpcworICAgICAqIHtAY29kZSBDb25kaXRpb259IGFuZCB0aGUgY3VycmVudCB0aHJlYWQgaGFwcGVucyB0byBiZSBjaG9zZW4gYXMgdGhlCisgICAgICogdGhyZWFkIHRvIGJlIGF3YWtlbmVkOyBvcgorICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCBpbnZva2VzIHRoZSB7QGxpbmsgI3NpZ25hbEFsbH0gbWV0aG9kIGZvciB0aGlzCisgICAgICoge0Bjb2RlIENvbmRpdGlvbn07IG9yCisgICAgICogPGxpPlNvbWUgb3RoZXIgdGhyZWFkIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0c30gdGhlCisgICAgICogY3VycmVudCB0aHJlYWQsIGFuZCBpbnRlcnJ1cHRpb24gb2YgdGhyZWFkIHN1c3BlbnNpb24gaXMgc3VwcG9ydGVkOyBvcgorICAgICAqIDxsaT5UaGUgc3BlY2lmaWVkIGRlYWRsaW5lIGVsYXBzZXM7IG9yCisgICAgICogPGxpPkEgJnF1b3Q7PGVtPnNwdXJpb3VzIHdha2V1cDwvZW0+JnF1b3Q7IG9jY3Vycy4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogPHA+SW4gYWxsIGNhc2VzLCBiZWZvcmUgdGhpcyBtZXRob2QgY2FuIHJldHVybiB0aGUgY3VycmVudCB0aHJlYWQgbXVzdAorICAgICAqIHJlLWFjcXVpcmUgdGhlIGxvY2sgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29uZGl0aW9uLiBXaGVuIHRoZQorICAgICAqIHRocmVhZCByZXR1cm5zIGl0IGlzIDxlbT5ndWFyYW50ZWVkPC9lbT4gdG8gaG9sZCB0aGlzIGxvY2suCisgICAgICoKKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBjdXJyZW50IHRocmVhZDoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPmhhcyBpdHMgaW50ZXJydXB0ZWQgc3RhdHVzIHNldCBvbiBlbnRyeSB0byB0aGlzIG1ldGhvZDsgb3IKKyAgICAgKiA8bGk+aXMge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRlZH0gd2hpbGUgd2FpdGluZworICAgICAqIGFuZCBpbnRlcnJ1cHRpb24gb2YgdGhyZWFkIHN1c3BlbnNpb24gaXMgc3VwcG9ydGVkLAorICAgICAqIDwvdWw+CisgICAgICogdGhlbiB7QGxpbmsgSW50ZXJydXB0ZWRFeGNlcHRpb259IGlzIHRocm93biBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkJ3MKKyAgICAgKiBpbnRlcnJ1cHRlZCBzdGF0dXMgaXMgY2xlYXJlZC4gSXQgaXMgbm90IHNwZWNpZmllZCwgaW4gdGhlIGZpcnN0CisgICAgICogY2FzZSwgd2hldGhlciBvciBub3QgdGhlIHRlc3QgZm9yIGludGVycnVwdGlvbiBvY2N1cnMgYmVmb3JlIHRoZSBsb2NrCisgICAgICogaXMgcmVsZWFzZWQuCisgICAgICoKKyAgICAgKgorICAgICAqIDxwPlRoZSByZXR1cm4gdmFsdWUgaW5kaWNhdGVzIHdoZXRoZXIgdGhlIGRlYWRsaW5lIGhhcyBlbGFwc2VkLAorICAgICAqIHdoaWNoIGNhbiBiZSB1c2VkIGFzIGZvbGxvd3M6CisgICAgICogIDxwcmU+IHtAY29kZQorICAgICAqIGJvb2xlYW4gYU1ldGhvZChEYXRlIGRlYWRsaW5lKSB7CisgICAgICogICBib29sZWFuIHN0aWxsV2FpdGluZyA9IHRydWU7CisgICAgICogICBsb2NrLmxvY2soKTsKKyAgICAgKiAgIHRyeSB7CisgICAgICogICAgIHdoaWxlICghY29uZGl0aW9uQmVpbmdXYWl0ZWRGb3IoKSkgeworICAgICAqICAgICAgIGlmICghc3RpbGxXYWl0aW5nKQorICAgICAqICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAqICAgICAgIHN0aWxsV2FpdGluZyA9IHRoZUNvbmRpdGlvbi5hd2FpdFVudGlsKGRlYWRsaW5lKTsKKyAgICAgKiAgICAgfQorICAgICAqICAgICAvLyAuLi4KKyAgICAgKiAgIH0gZmluYWxseSB7CisgICAgICogICAgIGxvY2sudW5sb2NrKCk7CisgICAgICogICB9CisgICAgICogfX08L3ByZT4KKyAgICAgKgorICAgICAqIDxwPjxiPkltcGxlbWVudGF0aW9uIENvbnNpZGVyYXRpb25zPC9iPgorICAgICAqCisgICAgICogPHA+VGhlIGN1cnJlbnQgdGhyZWFkIGlzIGFzc3VtZWQgdG8gaG9sZCB0aGUgbG9jayBhc3NvY2lhdGVkIHdpdGggdGhpcworICAgICAqIHtAY29kZSBDb25kaXRpb259IHdoZW4gdGhpcyBtZXRob2QgaXMgY2FsbGVkLgorICAgICAqIEl0IGlzIHVwIHRvIHRoZSBpbXBsZW1lbnRhdGlvbiB0byBkZXRlcm1pbmUgaWYgdGhpcyBpcworICAgICAqIHRoZSBjYXNlIGFuZCBpZiBub3QsIGhvdyB0byByZXNwb25kLiBUeXBpY2FsbHksIGFuIGV4Y2VwdGlvbiB3aWxsIGJlCisgICAgICogdGhyb3duIChzdWNoIGFzIHtAbGluayBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9ufSkgYW5kIHRoZQorICAgICAqIGltcGxlbWVudGF0aW9uIG11c3QgZG9jdW1lbnQgdGhhdCBmYWN0LgorICAgICAqCisgICAgICogPHA+QW4gaW1wbGVtZW50YXRpb24gY2FuIGZhdm9yIHJlc3BvbmRpbmcgdG8gYW4gaW50ZXJydXB0IG92ZXIgbm9ybWFsCisgICAgICogbWV0aG9kIHJldHVybiBpbiByZXNwb25zZSB0byBhIHNpZ25hbCwgb3Igb3ZlciBpbmRpY2F0aW5nIHRoZSBwYXNzaW5nCisgICAgICogb2YgdGhlIHNwZWNpZmllZCBkZWFkbGluZS4gSW4gZWl0aGVyIGNhc2UgdGhlIGltcGxlbWVudGF0aW9uCisgICAgICogbXVzdCBlbnN1cmUgdGhhdCB0aGUgc2lnbmFsIGlzIHJlZGlyZWN0ZWQgdG8gYW5vdGhlciB3YWl0aW5nIHRocmVhZCwgaWYKKyAgICAgKiB0aGVyZSBpcyBvbmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGVhZGxpbmUgdGhlIGFic29sdXRlIHRpbWUgdG8gd2FpdCB1bnRpbAorICAgICAqIEByZXR1cm4ge0Bjb2RlIGZhbHNlfSBpZiB0aGUgZGVhZGxpbmUgaGFzIGVsYXBzZWQgdXBvbiByZXR1cm4sIGVsc2UKKyAgICAgKiAgICAgICAgIHtAY29kZSB0cnVlfQorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkCisgICAgICogICAgICAgICAoYW5kIGludGVycnVwdGlvbiBvZiB0aHJlYWQgc3VzcGVuc2lvbiBpcyBzdXBwb3J0ZWQpCisgICAgICovCisgICAgYm9vbGVhbiBhd2FpdFVudGlsKERhdGUgZGVhZGxpbmUpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdha2VzIHVwIG9uZSB3YWl0aW5nIHRocmVhZC4KKyAgICAgKgorICAgICAqIDxwPklmIGFueSB0aHJlYWRzIGFyZSB3YWl0aW5nIG9uIHRoaXMgY29uZGl0aW9uIHRoZW4gb25lCisgICAgICogaXMgc2VsZWN0ZWQgZm9yIHdha2luZyB1cC4gVGhhdCB0aHJlYWQgbXVzdCB0aGVuIHJlLWFjcXVpcmUgdGhlCisgICAgICogbG9jayBiZWZvcmUgcmV0dXJuaW5nIGZyb20ge0Bjb2RlIGF3YWl0fS4KKyAgICAgKgorICAgICAqIDxwPjxiPkltcGxlbWVudGF0aW9uIENvbnNpZGVyYXRpb25zPC9iPgorICAgICAqCisgICAgICogPHA+QW4gaW1wbGVtZW50YXRpb24gbWF5IChhbmQgdHlwaWNhbGx5IGRvZXMpIHJlcXVpcmUgdGhhdCB0aGUKKyAgICAgKiBjdXJyZW50IHRocmVhZCBob2xkIHRoZSBsb2NrIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHtAY29kZQorICAgICAqIENvbmRpdGlvbn0gd2hlbiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuIEltcGxlbWVudGF0aW9ucyBtdXN0CisgICAgICogZG9jdW1lbnQgdGhpcyBwcmVjb25kaXRpb24gYW5kIGFueSBhY3Rpb25zIHRha2VuIGlmIHRoZSBsb2NrIGlzCisgICAgICogbm90IGhlbGQuIFR5cGljYWxseSwgYW4gZXhjZXB0aW9uIHN1Y2ggYXMge0BsaW5rCisgICAgICogSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24uCisgICAgICovCisgICAgdm9pZCBzaWduYWwoKTsKKworICAgIC8qKgorICAgICAqIFdha2VzIHVwIGFsbCB3YWl0aW5nIHRocmVhZHMuCisgICAgICoKKyAgICAgKiA8cD5JZiBhbnkgdGhyZWFkcyBhcmUgd2FpdGluZyBvbiB0aGlzIGNvbmRpdGlvbiB0aGVuIHRoZXkgYXJlCisgICAgICogYWxsIHdva2VuIHVwLiBFYWNoIHRocmVhZCBtdXN0IHJlLWFjcXVpcmUgdGhlIGxvY2sgYmVmb3JlIGl0IGNhbgorICAgICAqIHJldHVybiBmcm9tIHtAY29kZSBhd2FpdH0uCisgICAgICoKKyAgICAgKiA8cD48Yj5JbXBsZW1lbnRhdGlvbiBDb25zaWRlcmF0aW9uczwvYj4KKyAgICAgKgorICAgICAqIDxwPkFuIGltcGxlbWVudGF0aW9uIG1heSAoYW5kIHR5cGljYWxseSBkb2VzKSByZXF1aXJlIHRoYXQgdGhlCisgICAgICogY3VycmVudCB0aHJlYWQgaG9sZCB0aGUgbG9jayBhc3NvY2lhdGVkIHdpdGggdGhpcyB7QGNvZGUKKyAgICAgKiBDb25kaXRpb259IHdoZW4gdGhpcyBtZXRob2QgaXMgY2FsbGVkLiBJbXBsZW1lbnRhdGlvbnMgbXVzdAorICAgICAqIGRvY3VtZW50IHRoaXMgcHJlY29uZGl0aW9uIGFuZCBhbnkgYWN0aW9ucyB0YWtlbiBpZiB0aGUgbG9jayBpcworICAgICAqIG5vdCBoZWxkLiBUeXBpY2FsbHksIGFuIGV4Y2VwdGlvbiBzdWNoIGFzIHtAbGluaworICAgICAqIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb259IHdpbGwgYmUgdGhyb3duLgorICAgICAqLworICAgIHZvaWQgc2lnbmFsQWxsKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvbG9ja3MvTG9jay5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL0xvY2suamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YjlhYmQ2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL0xvY2suamF2YQpAQCAtMCwwICsxLDMyNyBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0OworCisvKioKKyAqIHtAY29kZSBMb2NrfSBpbXBsZW1lbnRhdGlvbnMgcHJvdmlkZSBtb3JlIGV4dGVuc2l2ZSBsb2NraW5nCisgKiBvcGVyYXRpb25zIHRoYW4gY2FuIGJlIG9idGFpbmVkIHVzaW5nIHtAY29kZSBzeW5jaHJvbml6ZWR9IG1ldGhvZHMKKyAqIGFuZCBzdGF0ZW1lbnRzLiAgVGhleSBhbGxvdyBtb3JlIGZsZXhpYmxlIHN0cnVjdHVyaW5nLCBtYXkgaGF2ZQorICogcXVpdGUgZGlmZmVyZW50IHByb3BlcnRpZXMsIGFuZCBtYXkgc3VwcG9ydCBtdWx0aXBsZSBhc3NvY2lhdGVkCisgKiB7QGxpbmsgQ29uZGl0aW9ufSBvYmplY3RzLgorICoKKyAqIDxwPkEgbG9jayBpcyBhIHRvb2wgZm9yIGNvbnRyb2xsaW5nIGFjY2VzcyB0byBhIHNoYXJlZCByZXNvdXJjZSBieQorICogbXVsdGlwbGUgdGhyZWFkcy4gQ29tbW9ubHksIGEgbG9jayBwcm92aWRlcyBleGNsdXNpdmUgYWNjZXNzIHRvIGEKKyAqIHNoYXJlZCByZXNvdXJjZTogb25seSBvbmUgdGhyZWFkIGF0IGEgdGltZSBjYW4gYWNxdWlyZSB0aGUgbG9jayBhbmQKKyAqIGFsbCBhY2Nlc3MgdG8gdGhlIHNoYXJlZCByZXNvdXJjZSByZXF1aXJlcyB0aGF0IHRoZSBsb2NrIGJlCisgKiBhY3F1aXJlZCBmaXJzdC4gSG93ZXZlciwgc29tZSBsb2NrcyBtYXkgYWxsb3cgY29uY3VycmVudCBhY2Nlc3MgdG8KKyAqIGEgc2hhcmVkIHJlc291cmNlLCBzdWNoIGFzIHRoZSByZWFkIGxvY2sgb2YgYSB7QGxpbmsgUmVhZFdyaXRlTG9ja30uCisgKgorICogPHA+VGhlIHVzZSBvZiB7QGNvZGUgc3luY2hyb25pemVkfSBtZXRob2RzIG9yIHN0YXRlbWVudHMgcHJvdmlkZXMKKyAqIGFjY2VzcyB0byB0aGUgaW1wbGljaXQgbW9uaXRvciBsb2NrIGFzc29jaWF0ZWQgd2l0aCBldmVyeSBvYmplY3QsIGJ1dAorICogZm9yY2VzIGFsbCBsb2NrIGFjcXVpc2l0aW9uIGFuZCByZWxlYXNlIHRvIG9jY3VyIGluIGEgYmxvY2stc3RydWN0dXJlZCB3YXk6CisgKiB3aGVuIG11bHRpcGxlIGxvY2tzIGFyZSBhY3F1aXJlZCB0aGV5IG11c3QgYmUgcmVsZWFzZWQgaW4gdGhlIG9wcG9zaXRlCisgKiBvcmRlciwgYW5kIGFsbCBsb2NrcyBtdXN0IGJlIHJlbGVhc2VkIGluIHRoZSBzYW1lIGxleGljYWwgc2NvcGUgaW4gd2hpY2gKKyAqIHRoZXkgd2VyZSBhY3F1aXJlZC4KKyAqCisgKiA8cD5XaGlsZSB0aGUgc2NvcGluZyBtZWNoYW5pc20gZm9yIHtAY29kZSBzeW5jaHJvbml6ZWR9IG1ldGhvZHMKKyAqIGFuZCBzdGF0ZW1lbnRzIG1ha2VzIGl0IG11Y2ggZWFzaWVyIHRvIHByb2dyYW0gd2l0aCBtb25pdG9yIGxvY2tzLAorICogYW5kIGhlbHBzIGF2b2lkIG1hbnkgY29tbW9uIHByb2dyYW1taW5nIGVycm9ycyBpbnZvbHZpbmcgbG9ja3MsCisgKiB0aGVyZSBhcmUgb2NjYXNpb25zIHdoZXJlIHlvdSBuZWVkIHRvIHdvcmsgd2l0aCBsb2NrcyBpbiBhIG1vcmUKKyAqIGZsZXhpYmxlIHdheS4gRm9yIGV4YW1wbGUsIHNvbWUgYWxnb3JpdGhtcyBmb3IgdHJhdmVyc2luZworICogY29uY3VycmVudGx5IGFjY2Vzc2VkIGRhdGEgc3RydWN0dXJlcyByZXF1aXJlIHRoZSB1c2Ugb2YKKyAqICZxdW90O2hhbmQtb3Zlci1oYW5kJnF1b3Q7IG9yICZxdW90O2NoYWluIGxvY2tpbmcmcXVvdDs6IHlvdQorICogYWNxdWlyZSB0aGUgbG9jayBvZiBub2RlIEEsIHRoZW4gbm9kZSBCLCB0aGVuIHJlbGVhc2UgQSBhbmQgYWNxdWlyZQorICogQywgdGhlbiByZWxlYXNlIEIgYW5kIGFjcXVpcmUgRCBhbmQgc28gb24uICBJbXBsZW1lbnRhdGlvbnMgb2YgdGhlCisgKiB7QGNvZGUgTG9ja30gaW50ZXJmYWNlIGVuYWJsZSB0aGUgdXNlIG9mIHN1Y2ggdGVjaG5pcXVlcyBieQorICogYWxsb3dpbmcgYSBsb2NrIHRvIGJlIGFjcXVpcmVkIGFuZCByZWxlYXNlZCBpbiBkaWZmZXJlbnQgc2NvcGVzLAorICogYW5kIGFsbG93aW5nIG11bHRpcGxlIGxvY2tzIHRvIGJlIGFjcXVpcmVkIGFuZCByZWxlYXNlZCBpbiBhbnkKKyAqIG9yZGVyLgorICoKKyAqIDxwPldpdGggdGhpcyBpbmNyZWFzZWQgZmxleGliaWxpdHkgY29tZXMgYWRkaXRpb25hbAorICogcmVzcG9uc2liaWxpdHkuIFRoZSBhYnNlbmNlIG9mIGJsb2NrLXN0cnVjdHVyZWQgbG9ja2luZyByZW1vdmVzIHRoZQorICogYXV0b21hdGljIHJlbGVhc2Ugb2YgbG9ja3MgdGhhdCBvY2N1cnMgd2l0aCB7QGNvZGUgc3luY2hyb25pemVkfQorICogbWV0aG9kcyBhbmQgc3RhdGVtZW50cy4gSW4gbW9zdCBjYXNlcywgdGhlIGZvbGxvd2luZyBpZGlvbQorICogc2hvdWxkIGJlIHVzZWQ6CisgKgorICogPHByZT48dHQ+ICAgICBMb2NrIGwgPSAuLi47CisgKiAgICAgbC5sb2NrKCk7CisgKiAgICAgdHJ5IHsKKyAqICAgICAgICAgLy8gYWNjZXNzIHRoZSByZXNvdXJjZSBwcm90ZWN0ZWQgYnkgdGhpcyBsb2NrCisgKiAgICAgfSBmaW5hbGx5IHsKKyAqICAgICAgICAgbC51bmxvY2soKTsKKyAqICAgICB9CisgKiA8L3R0PjwvcHJlPgorICoKKyAqIFdoZW4gbG9ja2luZyBhbmQgdW5sb2NraW5nIG9jY3VyIGluIGRpZmZlcmVudCBzY29wZXMsIGNhcmUgbXVzdCBiZQorICogdGFrZW4gdG8gZW5zdXJlIHRoYXQgYWxsIGNvZGUgdGhhdCBpcyBleGVjdXRlZCB3aGlsZSB0aGUgbG9jayBpcworICogaGVsZCBpcyBwcm90ZWN0ZWQgYnkgdHJ5LWZpbmFsbHkgb3IgdHJ5LWNhdGNoIHRvIGVuc3VyZSB0aGF0IHRoZQorICogbG9jayBpcyByZWxlYXNlZCB3aGVuIG5lY2Vzc2FyeS4KKyAqCisgKiA8cD57QGNvZGUgTG9ja30gaW1wbGVtZW50YXRpb25zIHByb3ZpZGUgYWRkaXRpb25hbCBmdW5jdGlvbmFsaXR5CisgKiBvdmVyIHRoZSB1c2Ugb2Yge0Bjb2RlIHN5bmNocm9uaXplZH0gbWV0aG9kcyBhbmQgc3RhdGVtZW50cyBieQorICogcHJvdmlkaW5nIGEgbm9uLWJsb2NraW5nIGF0dGVtcHQgdG8gYWNxdWlyZSBhIGxvY2sgKHtAbGluaworICogI3RyeUxvY2soKX0pLCBhbiBhdHRlbXB0IHRvIGFjcXVpcmUgdGhlIGxvY2sgdGhhdCBjYW4gYmUKKyAqIGludGVycnVwdGVkICh7QGxpbmsgI2xvY2tJbnRlcnJ1cHRpYmx5fSwgYW5kIGFuIGF0dGVtcHQgdG8gYWNxdWlyZQorICogdGhlIGxvY2sgdGhhdCBjYW4gdGltZW91dCAoe0BsaW5rICN0cnlMb2NrKGxvbmcsIFRpbWVVbml0KX0pLgorICoKKyAqIDxwPkEge0Bjb2RlIExvY2t9IGNsYXNzIGNhbiBhbHNvIHByb3ZpZGUgYmVoYXZpb3IgYW5kIHNlbWFudGljcworICogdGhhdCBpcyBxdWl0ZSBkaWZmZXJlbnQgZnJvbSB0aGF0IG9mIHRoZSBpbXBsaWNpdCBtb25pdG9yIGxvY2ssCisgKiBzdWNoIGFzIGd1YXJhbnRlZWQgb3JkZXJpbmcsIG5vbi1yZWVudHJhbnQgdXNhZ2UsIG9yIGRlYWRsb2NrCisgKiBkZXRlY3Rpb24uIElmIGFuIGltcGxlbWVudGF0aW9uIHByb3ZpZGVzIHN1Y2ggc3BlY2lhbGl6ZWQgc2VtYW50aWNzCisgKiB0aGVuIHRoZSBpbXBsZW1lbnRhdGlvbiBtdXN0IGRvY3VtZW50IHRob3NlIHNlbWFudGljcy4KKyAqCisgKiA8cD5Ob3RlIHRoYXQge0Bjb2RlIExvY2t9IGluc3RhbmNlcyBhcmUganVzdCBub3JtYWwgb2JqZWN0cyBhbmQgY2FuCisgKiB0aGVtc2VsdmVzIGJlIHVzZWQgYXMgdGhlIHRhcmdldCBpbiBhIHtAY29kZSBzeW5jaHJvbml6ZWR9IHN0YXRlbWVudC4KKyAqIEFjcXVpcmluZyB0aGUKKyAqIG1vbml0b3IgbG9jayBvZiBhIHtAY29kZSBMb2NrfSBpbnN0YW5jZSBoYXMgbm8gc3BlY2lmaWVkIHJlbGF0aW9uc2hpcAorICogd2l0aCBpbnZva2luZyBhbnkgb2YgdGhlIHtAbGluayAjbG9ja30gbWV0aG9kcyBvZiB0aGF0IGluc3RhbmNlLgorICogSXQgaXMgcmVjb21tZW5kZWQgdGhhdCB0byBhdm9pZCBjb25mdXNpb24geW91IG5ldmVyIHVzZSB7QGNvZGUgTG9ja30KKyAqIGluc3RhbmNlcyBpbiB0aGlzIHdheSwgZXhjZXB0IHdpdGhpbiB0aGVpciBvd24gaW1wbGVtZW50YXRpb24uCisgKgorICogPHA+RXhjZXB0IHdoZXJlIG5vdGVkLCBwYXNzaW5nIGEge0Bjb2RlIG51bGx9IHZhbHVlIGZvciBhbnkKKyAqIHBhcmFtZXRlciB3aWxsIHJlc3VsdCBpbiBhIHtAbGluayBOdWxsUG9pbnRlckV4Y2VwdGlvbn0gYmVpbmcKKyAqIHRocm93bi4KKyAqCisgKiA8aDM+TWVtb3J5IFN5bmNocm9uaXphdGlvbjwvaDM+CisgKgorICogPHA+QWxsIHtAY29kZSBMb2NrfSBpbXBsZW1lbnRhdGlvbnMgPGVtPm11c3Q8L2VtPiBlbmZvcmNlIHRoZSBzYW1lCisgKiBtZW1vcnkgc3luY2hyb25pemF0aW9uIHNlbWFudGljcyBhcyBwcm92aWRlZCBieSB0aGUgYnVpbHQtaW4gbW9uaXRvcgorICogbG9jaywgYXMgZGVzY3JpYmVkIGluIDxhIGhyZWY9Imh0dHA6Ly9qYXZhLnN1bi5jb20vZG9jcy9ib29rcy9qbHMvIj4KKyAqIFRoZSBKYXZhIExhbmd1YWdlIFNwZWNpZmljYXRpb24sIFRoaXJkIEVkaXRpb24gKDE3LjQgTWVtb3J5IE1vZGVsKTwvYT46CisgKiA8dWw+CisgKiA8bGk+QSBzdWNjZXNzZnVsIHtAY29kZSBsb2NrfSBvcGVyYXRpb24gaGFzIHRoZSBzYW1lIG1lbW9yeQorICogc3luY2hyb25pemF0aW9uIGVmZmVjdHMgYXMgYSBzdWNjZXNzZnVsIDxlbT5Mb2NrPC9lbT4gYWN0aW9uLgorICogPGxpPkEgc3VjY2Vzc2Z1bCB7QGNvZGUgdW5sb2NrfSBvcGVyYXRpb24gaGFzIHRoZSBzYW1lCisgKiBtZW1vcnkgc3luY2hyb25pemF0aW9uIGVmZmVjdHMgYXMgYSBzdWNjZXNzZnVsIDxlbT5VbmxvY2s8L2VtPiBhY3Rpb24uCisgKiA8L3VsPgorICoKKyAqIFVuc3VjY2Vzc2Z1bCBsb2NraW5nIGFuZCB1bmxvY2tpbmcgb3BlcmF0aW9ucywgYW5kIHJlZW50cmFudAorICogbG9ja2luZy91bmxvY2tpbmcgb3BlcmF0aW9ucywgZG8gbm90IHJlcXVpcmUgYW55IG1lbW9yeQorICogc3luY2hyb25pemF0aW9uIGVmZmVjdHMuCisgKgorICogPGgzPkltcGxlbWVudGF0aW9uIENvbnNpZGVyYXRpb25zPC9oMz4KKyAqCisgKiA8cD4gVGhlIHRocmVlIGZvcm1zIG9mIGxvY2sgYWNxdWlzaXRpb24gKGludGVycnVwdGlibGUsCisgKiBub24taW50ZXJydXB0aWJsZSwgYW5kIHRpbWVkKSBtYXkgZGlmZmVyIGluIHRoZWlyIHBlcmZvcm1hbmNlCisgKiBjaGFyYWN0ZXJpc3RpY3MsIG9yZGVyaW5nIGd1YXJhbnRlZXMsIG9yIG90aGVyIGltcGxlbWVudGF0aW9uCisgKiBxdWFsaXRpZXMuICBGdXJ0aGVyLCB0aGUgYWJpbGl0eSB0byBpbnRlcnJ1cHQgdGhlIDxlbT5vbmdvaW5nPC9lbT4KKyAqIGFjcXVpc2l0aW9uIG9mIGEgbG9jayBtYXkgbm90IGJlIGF2YWlsYWJsZSBpbiBhIGdpdmVuIHtAY29kZSBMb2NrfQorICogY2xhc3MuICBDb25zZXF1ZW50bHksIGFuIGltcGxlbWVudGF0aW9uIGlzIG5vdCByZXF1aXJlZCB0byBkZWZpbmUKKyAqIGV4YWN0bHkgdGhlIHNhbWUgZ3VhcmFudGVlcyBvciBzZW1hbnRpY3MgZm9yIGFsbCB0aHJlZSBmb3JtcyBvZgorICogbG9jayBhY3F1aXNpdGlvbiwgbm9yIGlzIGl0IHJlcXVpcmVkIHRvIHN1cHBvcnQgaW50ZXJydXB0aW9uIG9mIGFuCisgKiBvbmdvaW5nIGxvY2sgYWNxdWlzaXRpb24uICBBbiBpbXBsZW1lbnRhdGlvbiBpcyByZXF1aXJlZCB0byBjbGVhcmx5CisgKiBkb2N1bWVudCB0aGUgc2VtYW50aWNzIGFuZCBndWFyYW50ZWVzIHByb3ZpZGVkIGJ5IGVhY2ggb2YgdGhlCisgKiBsb2NraW5nIG1ldGhvZHMuIEl0IG11c3QgYWxzbyBvYmV5IHRoZSBpbnRlcnJ1cHRpb24gc2VtYW50aWNzIGFzCisgKiBkZWZpbmVkIGluIHRoaXMgaW50ZXJmYWNlLCB0byB0aGUgZXh0ZW50IHRoYXQgaW50ZXJydXB0aW9uIG9mIGxvY2sKKyAqIGFjcXVpc2l0aW9uIGlzIHN1cHBvcnRlZDogd2hpY2ggaXMgZWl0aGVyIHRvdGFsbHksIG9yIG9ubHkgb24KKyAqIG1ldGhvZCBlbnRyeS4KKyAqCisgKiA8cD5BcyBpbnRlcnJ1cHRpb24gZ2VuZXJhbGx5IGltcGxpZXMgY2FuY2VsbGF0aW9uLCBhbmQgY2hlY2tzIGZvcgorICogaW50ZXJydXB0aW9uIGFyZSBvZnRlbiBpbmZyZXF1ZW50LCBhbiBpbXBsZW1lbnRhdGlvbiBjYW4gZmF2b3IgcmVzcG9uZGluZworICogdG8gYW4gaW50ZXJydXB0IG92ZXIgbm9ybWFsIG1ldGhvZCByZXR1cm4uIFRoaXMgaXMgdHJ1ZSBldmVuIGlmIGl0IGNhbiBiZQorICogc2hvd24gdGhhdCB0aGUgaW50ZXJydXB0IG9jY3VycmVkIGFmdGVyIGFub3RoZXIgYWN0aW9uIG1heSBoYXZlIHVuYmxvY2tlZAorICogdGhlIHRocmVhZC4gQW4gaW1wbGVtZW50YXRpb24gc2hvdWxkIGRvY3VtZW50IHRoaXMgYmVoYXZpb3IuCisgKgorICogQHNlZSBSZWVudHJhbnRMb2NrCisgKiBAc2VlIENvbmRpdGlvbgorICogQHNlZSBSZWFkV3JpdGVMb2NrCisgKgorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICovCitwdWJsaWMgaW50ZXJmYWNlIExvY2sgeworCisgICAgLyoqCisgICAgICogQWNxdWlyZXMgdGhlIGxvY2suCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgbG9jayBpcyBub3QgYXZhaWxhYmxlIHRoZW4gdGhlIGN1cnJlbnQgdGhyZWFkIGJlY29tZXMKKyAgICAgKiBkaXNhYmxlZCBmb3IgdGhyZWFkIHNjaGVkdWxpbmcgcHVycG9zZXMgYW5kIGxpZXMgZG9ybWFudCB1bnRpbCB0aGUKKyAgICAgKiBsb2NrIGhhcyBiZWVuIGFjcXVpcmVkLgorICAgICAqCisgICAgICogPHA+PGI+SW1wbGVtZW50YXRpb24gQ29uc2lkZXJhdGlvbnM8L2I+CisgICAgICoKKyAgICAgKiA8cD5BIHtAY29kZSBMb2NrfSBpbXBsZW1lbnRhdGlvbiBtYXkgYmUgYWJsZSB0byBkZXRlY3QgZXJyb25lb3VzIHVzZQorICAgICAqIG9mIHRoZSBsb2NrLCBzdWNoIGFzIGFuIGludm9jYXRpb24gdGhhdCB3b3VsZCBjYXVzZSBkZWFkbG9jaywgYW5kCisgICAgICogbWF5IHRocm93IGFuICh1bmNoZWNrZWQpIGV4Y2VwdGlvbiBpbiBzdWNoIGNpcmN1bXN0YW5jZXMuICBUaGUKKyAgICAgKiBjaXJjdW1zdGFuY2VzIGFuZCB0aGUgZXhjZXB0aW9uIHR5cGUgbXVzdCBiZSBkb2N1bWVudGVkIGJ5IHRoYXQKKyAgICAgKiB7QGNvZGUgTG9ja30gaW1wbGVtZW50YXRpb24uCisgICAgICovCisgICAgdm9pZCBsb2NrKCk7CisKKyAgICAvKioKKyAgICAgKiBBY3F1aXJlcyB0aGUgbG9jayB1bmxlc3MgdGhlIGN1cnJlbnQgdGhyZWFkIGlzCisgICAgICoge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRlZH0uCisgICAgICoKKyAgICAgKiA8cD5BY3F1aXJlcyB0aGUgbG9jayBpZiBpdCBpcyBhdmFpbGFibGUgYW5kIHJldHVybnMgaW1tZWRpYXRlbHkuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgbG9jayBpcyBub3QgYXZhaWxhYmxlIHRoZW4gdGhlIGN1cnJlbnQgdGhyZWFkIGJlY29tZXMKKyAgICAgKiBkaXNhYmxlZCBmb3IgdGhyZWFkIHNjaGVkdWxpbmcgcHVycG9zZXMgYW5kIGxpZXMgZG9ybWFudCB1bnRpbAorICAgICAqIG9uZSBvZiB0d28gdGhpbmdzIGhhcHBlbnM6CisgICAgICoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPlRoZSBsb2NrIGlzIGFjcXVpcmVkIGJ5IHRoZSBjdXJyZW50IHRocmVhZDsgb3IKKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRzfSB0aGUKKyAgICAgKiBjdXJyZW50IHRocmVhZCwgYW5kIGludGVycnVwdGlvbiBvZiBsb2NrIGFjcXVpc2l0aW9uIGlzIHN1cHBvcnRlZC4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGN1cnJlbnQgdGhyZWFkOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+aGFzIGl0cyBpbnRlcnJ1cHRlZCBzdGF0dXMgc2V0IG9uIGVudHJ5IHRvIHRoaXMgbWV0aG9kOyBvcgorICAgICAqIDxsaT5pcyB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfSB3aGlsZSBhY3F1aXJpbmcgdGhlCisgICAgICogbG9jaywgYW5kIGludGVycnVwdGlvbiBvZiBsb2NrIGFjcXVpc2l0aW9uIGlzIHN1cHBvcnRlZCwKKyAgICAgKiA8L3VsPgorICAgICAqIHRoZW4ge0BsaW5rIEludGVycnVwdGVkRXhjZXB0aW9ufSBpcyB0aHJvd24gYW5kIHRoZSBjdXJyZW50IHRocmVhZCdzCisgICAgICogaW50ZXJydXB0ZWQgc3RhdHVzIGlzIGNsZWFyZWQuCisgICAgICoKKyAgICAgKiA8cD48Yj5JbXBsZW1lbnRhdGlvbiBDb25zaWRlcmF0aW9uczwvYj4KKyAgICAgKgorICAgICAqIDxwPlRoZSBhYmlsaXR5IHRvIGludGVycnVwdCBhIGxvY2sgYWNxdWlzaXRpb24gaW4gc29tZQorICAgICAqIGltcGxlbWVudGF0aW9ucyBtYXkgbm90IGJlIHBvc3NpYmxlLCBhbmQgaWYgcG9zc2libGUgbWF5IGJlIGFuCisgICAgICogZXhwZW5zaXZlIG9wZXJhdGlvbi4gIFRoZSBwcm9ncmFtbWVyIHNob3VsZCBiZSBhd2FyZSB0aGF0IHRoaXMKKyAgICAgKiBtYXkgYmUgdGhlIGNhc2UuIEFuIGltcGxlbWVudGF0aW9uIHNob3VsZCBkb2N1bWVudCB3aGVuIHRoaXMgaXMKKyAgICAgKiB0aGUgY2FzZS4KKyAgICAgKgorICAgICAqIDxwPkFuIGltcGxlbWVudGF0aW9uIGNhbiBmYXZvciByZXNwb25kaW5nIHRvIGFuIGludGVycnVwdCBvdmVyCisgICAgICogbm9ybWFsIG1ldGhvZCByZXR1cm4uCisgICAgICoKKyAgICAgKiA8cD5BIHtAY29kZSBMb2NrfSBpbXBsZW1lbnRhdGlvbiBtYXkgYmUgYWJsZSB0byBkZXRlY3QKKyAgICAgKiBlcnJvbmVvdXMgdXNlIG9mIHRoZSBsb2NrLCBzdWNoIGFzIGFuIGludm9jYXRpb24gdGhhdCB3b3VsZAorICAgICAqIGNhdXNlIGRlYWRsb2NrLCBhbmQgbWF5IHRocm93IGFuICh1bmNoZWNrZWQpIGV4Y2VwdGlvbiBpbiBzdWNoCisgICAgICogY2lyY3Vtc3RhbmNlcy4gIFRoZSBjaXJjdW1zdGFuY2VzIGFuZCB0aGUgZXhjZXB0aW9uIHR5cGUgbXVzdAorICAgICAqIGJlIGRvY3VtZW50ZWQgYnkgdGhhdCB7QGNvZGUgTG9ja30gaW1wbGVtZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IHRocmVhZCBpcworICAgICAqICAgICAgICAgaW50ZXJydXB0ZWQgd2hpbGUgYWNxdWlyaW5nIHRoZSBsb2NrIChhbmQgaW50ZXJydXB0aW9uCisgICAgICogICAgICAgICBvZiBsb2NrIGFjcXVpc2l0aW9uIGlzIHN1cHBvcnRlZCkuCisgICAgICovCisgICAgdm9pZCBsb2NrSW50ZXJydXB0aWJseSgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEFjcXVpcmVzIHRoZSBsb2NrIG9ubHkgaWYgaXQgaXMgZnJlZSBhdCB0aGUgdGltZSBvZiBpbnZvY2F0aW9uLgorICAgICAqCisgICAgICogPHA+QWNxdWlyZXMgdGhlIGxvY2sgaWYgaXQgaXMgYXZhaWxhYmxlIGFuZCByZXR1cm5zIGltbWVkaWF0ZWx5CisgICAgICogd2l0aCB0aGUgdmFsdWUge0Bjb2RlIHRydWV9LgorICAgICAqIElmIHRoZSBsb2NrIGlzIG5vdCBhdmFpbGFibGUgdGhlbiB0aGlzIG1ldGhvZCB3aWxsIHJldHVybgorICAgICAqIGltbWVkaWF0ZWx5IHdpdGggdGhlIHZhbHVlIHtAY29kZSBmYWxzZX0uCisgICAgICoKKyAgICAgKiA8cD5BIHR5cGljYWwgdXNhZ2UgaWRpb20gZm9yIHRoaXMgbWV0aG9kIHdvdWxkIGJlOgorICAgICAqIDxwcmU+CisgICAgICogICAgICBMb2NrIGxvY2sgPSAuLi47CisgICAgICogICAgICBpZiAobG9jay50cnlMb2NrKCkpIHsKKyAgICAgKiAgICAgICAgICB0cnkgeworICAgICAqICAgICAgICAgICAgICAvLyBtYW5pcHVsYXRlIHByb3RlY3RlZCBzdGF0ZQorICAgICAqICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICogICAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICogICAgICAgICAgfQorICAgICAqICAgICAgfSBlbHNlIHsKKyAgICAgKiAgICAgICAgICAvLyBwZXJmb3JtIGFsdGVybmF0aXZlIGFjdGlvbnMKKyAgICAgKiAgICAgIH0KKyAgICAgKiA8L3ByZT4KKyAgICAgKiBUaGlzIHVzYWdlIGVuc3VyZXMgdGhhdCB0aGUgbG9jayBpcyB1bmxvY2tlZCBpZiBpdCB3YXMgYWNxdWlyZWQsIGFuZAorICAgICAqIGRvZXNuJ3QgdHJ5IHRvIHVubG9jayBpZiB0aGUgbG9jayB3YXMgbm90IGFjcXVpcmVkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGxvY2sgd2FzIGFjcXVpcmVkIGFuZAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBib29sZWFuIHRyeUxvY2soKTsKKworICAgIC8qKgorICAgICAqIEFjcXVpcmVzIHRoZSBsb2NrIGlmIGl0IGlzIGZyZWUgd2l0aGluIHRoZSBnaXZlbiB3YWl0aW5nIHRpbWUgYW5kIHRoZQorICAgICAqIGN1cnJlbnQgdGhyZWFkIGhhcyBub3QgYmVlbiB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfS4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBsb2NrIGlzIGF2YWlsYWJsZSB0aGlzIG1ldGhvZCByZXR1cm5zIGltbWVkaWF0ZWx5CisgICAgICogd2l0aCB0aGUgdmFsdWUge0Bjb2RlIHRydWV9LgorICAgICAqIElmIHRoZSBsb2NrIGlzIG5vdCBhdmFpbGFibGUgdGhlbgorICAgICAqIHRoZSBjdXJyZW50IHRocmVhZCBiZWNvbWVzIGRpc2FibGVkIGZvciB0aHJlYWQgc2NoZWR1bGluZworICAgICAqIHB1cnBvc2VzIGFuZCBsaWVzIGRvcm1hbnQgdW50aWwgb25lIG9mIHRocmVlIHRoaW5ncyBoYXBwZW5zOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+VGhlIGxvY2sgaXMgYWNxdWlyZWQgYnkgdGhlIGN1cnJlbnQgdGhyZWFkOyBvcgorICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdHN9IHRoZQorICAgICAqIGN1cnJlbnQgdGhyZWFkLCBhbmQgaW50ZXJydXB0aW9uIG9mIGxvY2sgYWNxdWlzaXRpb24gaXMgc3VwcG9ydGVkOyBvcgorICAgICAqIDxsaT5UaGUgc3BlY2lmaWVkIHdhaXRpbmcgdGltZSBlbGFwc2VzCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBsb2NrIGlzIGFjcXVpcmVkIHRoZW4gdGhlIHZhbHVlIHtAY29kZSB0cnVlfSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBjdXJyZW50IHRocmVhZDoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPmhhcyBpdHMgaW50ZXJydXB0ZWQgc3RhdHVzIHNldCBvbiBlbnRyeSB0byB0aGlzIG1ldGhvZDsgb3IKKyAgICAgKiA8bGk+aXMge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRlZH0gd2hpbGUgYWNxdWlyaW5nCisgICAgICogdGhlIGxvY2ssIGFuZCBpbnRlcnJ1cHRpb24gb2YgbG9jayBhY3F1aXNpdGlvbiBpcyBzdXBwb3J0ZWQsCisgICAgICogPC91bD4KKyAgICAgKiB0aGVuIHtAbGluayBJbnRlcnJ1cHRlZEV4Y2VwdGlvbn0gaXMgdGhyb3duIGFuZCB0aGUgY3VycmVudCB0aHJlYWQncworICAgICAqIGludGVycnVwdGVkIHN0YXR1cyBpcyBjbGVhcmVkLgorICAgICAqCisgICAgICogPHA+SWYgdGhlIHNwZWNpZmllZCB3YWl0aW5nIHRpbWUgZWxhcHNlcyB0aGVuIHRoZSB2YWx1ZSB7QGNvZGUgZmFsc2V9CisgICAgICogaXMgcmV0dXJuZWQuCisgICAgICogSWYgdGhlIHRpbWUgaXMKKyAgICAgKiBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gemVybywgdGhlIG1ldGhvZCB3aWxsIG5vdCB3YWl0IGF0IGFsbC4KKyAgICAgKgorICAgICAqIDxwPjxiPkltcGxlbWVudGF0aW9uIENvbnNpZGVyYXRpb25zPC9iPgorICAgICAqCisgICAgICogPHA+VGhlIGFiaWxpdHkgdG8gaW50ZXJydXB0IGEgbG9jayBhY3F1aXNpdGlvbiBpbiBzb21lIGltcGxlbWVudGF0aW9ucworICAgICAqIG1heSBub3QgYmUgcG9zc2libGUsIGFuZCBpZiBwb3NzaWJsZSBtYXkKKyAgICAgKiBiZSBhbiBleHBlbnNpdmUgb3BlcmF0aW9uLgorICAgICAqIFRoZSBwcm9ncmFtbWVyIHNob3VsZCBiZSBhd2FyZSB0aGF0IHRoaXMgbWF5IGJlIHRoZSBjYXNlLiBBbgorICAgICAqIGltcGxlbWVudGF0aW9uIHNob3VsZCBkb2N1bWVudCB3aGVuIHRoaXMgaXMgdGhlIGNhc2UuCisgICAgICoKKyAgICAgKiA8cD5BbiBpbXBsZW1lbnRhdGlvbiBjYW4gZmF2b3IgcmVzcG9uZGluZyB0byBhbiBpbnRlcnJ1cHQgb3ZlciBub3JtYWwKKyAgICAgKiBtZXRob2QgcmV0dXJuLCBvciByZXBvcnRpbmcgYSB0aW1lb3V0LgorICAgICAqCisgICAgICogPHA+QSB7QGNvZGUgTG9ja30gaW1wbGVtZW50YXRpb24gbWF5IGJlIGFibGUgdG8gZGV0ZWN0CisgICAgICogZXJyb25lb3VzIHVzZSBvZiB0aGUgbG9jaywgc3VjaCBhcyBhbiBpbnZvY2F0aW9uIHRoYXQgd291bGQgY2F1c2UKKyAgICAgKiBkZWFkbG9jaywgYW5kIG1heSB0aHJvdyBhbiAodW5jaGVja2VkKSBleGNlcHRpb24gaW4gc3VjaCBjaXJjdW1zdGFuY2VzLgorICAgICAqIFRoZSBjaXJjdW1zdGFuY2VzIGFuZCB0aGUgZXhjZXB0aW9uIHR5cGUgbXVzdCBiZSBkb2N1bWVudGVkIGJ5IHRoYXQKKyAgICAgKiB7QGNvZGUgTG9ja30gaW1wbGVtZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGltZSB0aGUgbWF4aW11bSB0aW1lIHRvIHdhaXQgZm9yIHRoZSBsb2NrCisgICAgICogQHBhcmFtIHVuaXQgdGhlIHRpbWUgdW5pdCBvZiB0aGUge0Bjb2RlIHRpbWV9IGFyZ3VtZW50CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGxvY2sgd2FzIGFjcXVpcmVkIGFuZCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBpZiB0aGUgd2FpdGluZyB0aW1lIGVsYXBzZWQgYmVmb3JlIHRoZSBsb2NrIHdhcyBhY3F1aXJlZAorICAgICAqCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCB0aHJlYWQgaXMgaW50ZXJydXB0ZWQKKyAgICAgKiAgICAgICAgIHdoaWxlIGFjcXVpcmluZyB0aGUgbG9jayAoYW5kIGludGVycnVwdGlvbiBvZiBsb2NrCisgICAgICogICAgICAgICBhY3F1aXNpdGlvbiBpcyBzdXBwb3J0ZWQpCisgICAgICovCisgICAgYm9vbGVhbiB0cnlMb2NrKGxvbmcgdGltZSwgVGltZVVuaXQgdW5pdCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVsZWFzZXMgdGhlIGxvY2suCisgICAgICoKKyAgICAgKiA8cD48Yj5JbXBsZW1lbnRhdGlvbiBDb25zaWRlcmF0aW9uczwvYj4KKyAgICAgKgorICAgICAqIDxwPkEge0Bjb2RlIExvY2t9IGltcGxlbWVudGF0aW9uIHdpbGwgdXN1YWxseSBpbXBvc2UKKyAgICAgKiByZXN0cmljdGlvbnMgb24gd2hpY2ggdGhyZWFkIGNhbiByZWxlYXNlIGEgbG9jayAodHlwaWNhbGx5IG9ubHkgdGhlCisgICAgICogaG9sZGVyIG9mIHRoZSBsb2NrIGNhbiByZWxlYXNlIGl0KSBhbmQgbWF5IHRocm93CisgICAgICogYW4gKHVuY2hlY2tlZCkgZXhjZXB0aW9uIGlmIHRoZSByZXN0cmljdGlvbiBpcyB2aW9sYXRlZC4KKyAgICAgKiBBbnkgcmVzdHJpY3Rpb25zIGFuZCB0aGUgZXhjZXB0aW9uCisgICAgICogdHlwZSBtdXN0IGJlIGRvY3VtZW50ZWQgYnkgdGhhdCB7QGNvZGUgTG9ja30gaW1wbGVtZW50YXRpb24uCisgICAgICovCisgICAgdm9pZCB1bmxvY2soKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcge0BsaW5rIENvbmRpdGlvbn0gaW5zdGFuY2UgdGhhdCBpcyBib3VuZCB0byB0aGlzCisgICAgICoge0Bjb2RlIExvY2t9IGluc3RhbmNlLgorICAgICAqCisgICAgICogPHA+QmVmb3JlIHdhaXRpbmcgb24gdGhlIGNvbmRpdGlvbiB0aGUgbG9jayBtdXN0IGJlIGhlbGQgYnkgdGhlCisgICAgICogY3VycmVudCB0aHJlYWQuCisgICAgICogQSBjYWxsIHRvIHtAbGluayBDb25kaXRpb24jYXdhaXQoKX0gd2lsbCBhdG9taWNhbGx5IHJlbGVhc2UgdGhlIGxvY2sKKyAgICAgKiBiZWZvcmUgd2FpdGluZyBhbmQgcmUtYWNxdWlyZSB0aGUgbG9jayBiZWZvcmUgdGhlIHdhaXQgcmV0dXJucy4KKyAgICAgKgorICAgICAqIDxwPjxiPkltcGxlbWVudGF0aW9uIENvbnNpZGVyYXRpb25zPC9iPgorICAgICAqCisgICAgICogPHA+VGhlIGV4YWN0IG9wZXJhdGlvbiBvZiB0aGUge0BsaW5rIENvbmRpdGlvbn0gaW5zdGFuY2UgZGVwZW5kcyBvbgorICAgICAqIHRoZSB7QGNvZGUgTG9ja30gaW1wbGVtZW50YXRpb24gYW5kIG11c3QgYmUgZG9jdW1lbnRlZCBieSB0aGF0CisgICAgICogaW1wbGVtZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEgbmV3IHtAbGluayBDb25kaXRpb259IGluc3RhbmNlIGZvciB0aGlzIHtAY29kZSBMb2NrfSBpbnN0YW5jZQorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhpcyB7QGNvZGUgTG9ja30KKyAgICAgKiAgICAgICAgIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgY29uZGl0aW9ucworICAgICAqLworICAgIENvbmRpdGlvbiBuZXdDb25kaXRpb24oKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9sb2Nrcy9Mb2NrU3VwcG9ydC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL0xvY2tTdXBwb3J0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGMwZjA3ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9sb2Nrcy9Mb2NrU3VwcG9ydC5qYXZhCkBAIC0wLDAgKzEsMzUyIEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3M7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuKjsKK2ltcG9ydCBzdW4ubWlzYy5VbnNhZmU7CisKKworLyoqCisgKiBCYXNpYyB0aHJlYWQgYmxvY2tpbmcgcHJpbWl0aXZlcyBmb3IgY3JlYXRpbmcgbG9ja3MgYW5kIG90aGVyCisgKiBzeW5jaHJvbml6YXRpb24gY2xhc3Nlcy4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGFzc29jaWF0ZXMsIHdpdGggZWFjaCB0aHJlYWQgdGhhdCB1c2VzIGl0LCBhIHBlcm1pdAorICogKGluIHRoZSBzZW5zZSBvZiB0aGUge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LlNlbWFwaG9yZQorICogU2VtYXBob3JlfSBjbGFzcykuIEEgY2FsbCB0byB7QGNvZGUgcGFya30gd2lsbCByZXR1cm4gaW1tZWRpYXRlbHkKKyAqIGlmIHRoZSBwZXJtaXQgaXMgYXZhaWxhYmxlLCBjb25zdW1pbmcgaXQgaW4gdGhlIHByb2Nlc3M7IG90aGVyd2lzZQorICogaXQgPGVtPm1heTwvZW0+IGJsb2NrLiAgQSBjYWxsIHRvIHtAY29kZSB1bnBhcmt9IG1ha2VzIHRoZSBwZXJtaXQKKyAqIGF2YWlsYWJsZSwgaWYgaXQgd2FzIG5vdCBhbHJlYWR5IGF2YWlsYWJsZS4gKFVubGlrZSB3aXRoIFNlbWFwaG9yZXMKKyAqIHRob3VnaCwgcGVybWl0cyBkbyBub3QgYWNjdW11bGF0ZS4gVGhlcmUgaXMgYXQgbW9zdCBvbmUuKQorICoKKyAqIDxwPk1ldGhvZHMge0Bjb2RlIHBhcmt9IGFuZCB7QGNvZGUgdW5wYXJrfSBwcm92aWRlIGVmZmljaWVudAorICogbWVhbnMgb2YgYmxvY2tpbmcgYW5kIHVuYmxvY2tpbmcgdGhyZWFkcyB0aGF0IGRvIG5vdCBlbmNvdW50ZXIgdGhlCisgKiBwcm9ibGVtcyB0aGF0IGNhdXNlIHRoZSBkZXByZWNhdGVkIG1ldGhvZHMge0Bjb2RlIFRocmVhZC5zdXNwZW5kfQorICogYW5kIHtAY29kZSBUaHJlYWQucmVzdW1lfSB0byBiZSB1bnVzYWJsZSBmb3Igc3VjaCBwdXJwb3NlczogUmFjZXMKKyAqIGJldHdlZW4gb25lIHRocmVhZCBpbnZva2luZyB7QGNvZGUgcGFya30gYW5kIGFub3RoZXIgdGhyZWFkIHRyeWluZworICogdG8ge0Bjb2RlIHVucGFya30gaXQgd2lsbCBwcmVzZXJ2ZSBsaXZlbmVzcywgZHVlIHRvIHRoZQorICogcGVybWl0LiBBZGRpdGlvbmFsbHksIHtAY29kZSBwYXJrfSB3aWxsIHJldHVybiBpZiB0aGUgY2FsbGVyJ3MKKyAqIHRocmVhZCB3YXMgaW50ZXJydXB0ZWQsIGFuZCB0aW1lb3V0IHZlcnNpb25zIGFyZSBzdXBwb3J0ZWQuIFRoZQorICoge0Bjb2RlIHBhcmt9IG1ldGhvZCBtYXkgYWxzbyByZXR1cm4gYXQgYW55IG90aGVyIHRpbWUsIGZvciAibm8KKyAqIHJlYXNvbiIsIHNvIGluIGdlbmVyYWwgbXVzdCBiZSBpbnZva2VkIHdpdGhpbiBhIGxvb3AgdGhhdCByZWNoZWNrcworICogY29uZGl0aW9ucyB1cG9uIHJldHVybi4gSW4gdGhpcyBzZW5zZSB7QGNvZGUgcGFya30gc2VydmVzIGFzIGFuCisgKiBvcHRpbWl6YXRpb24gb2YgYSAiYnVzeSB3YWl0IiB0aGF0IGRvZXMgbm90IHdhc3RlIGFzIG11Y2ggdGltZQorICogc3Bpbm5pbmcsIGJ1dCBtdXN0IGJlIHBhaXJlZCB3aXRoIGFuIHtAY29kZSB1bnBhcmt9IHRvIGJlCisgKiBlZmZlY3RpdmUuCisgKgorICogPHA+VGhlIHRocmVlIGZvcm1zIG9mIHtAY29kZSBwYXJrfSBlYWNoIGFsc28gc3VwcG9ydCBhCisgKiB7QGNvZGUgYmxvY2tlcn0gb2JqZWN0IHBhcmFtZXRlci4gVGhpcyBvYmplY3QgaXMgcmVjb3JkZWQgd2hpbGUKKyAqIHRoZSB0aHJlYWQgaXMgYmxvY2tlZCB0byBwZXJtaXQgbW9uaXRvcmluZyBhbmQgZGlhZ25vc3RpYyB0b29scyB0bworICogaWRlbnRpZnkgdGhlIHJlYXNvbnMgdGhhdCB0aHJlYWRzIGFyZSBibG9ja2VkLiAoU3VjaCB0b29scyBtYXkKKyAqIGFjY2VzcyBibG9ja2VycyB1c2luZyBtZXRob2Qge0BsaW5rICNnZXRCbG9ja2VyfS4pIFRoZSB1c2Ugb2YgdGhlc2UKKyAqIGZvcm1zIHJhdGhlciB0aGFuIHRoZSBvcmlnaW5hbCBmb3JtcyB3aXRob3V0IHRoaXMgcGFyYW1ldGVyIGlzCisgKiBzdHJvbmdseSBlbmNvdXJhZ2VkLiBUaGUgbm9ybWFsIGFyZ3VtZW50IHRvIHN1cHBseSBhcyBhCisgKiB7QGNvZGUgYmxvY2tlcn0gd2l0aGluIGEgbG9jayBpbXBsZW1lbnRhdGlvbiBpcyB7QGNvZGUgdGhpc30uCisgKgorICogPHA+VGhlc2UgbWV0aG9kcyBhcmUgZGVzaWduZWQgdG8gYmUgdXNlZCBhcyB0b29scyBmb3IgY3JlYXRpbmcKKyAqIGhpZ2hlci1sZXZlbCBzeW5jaHJvbml6YXRpb24gdXRpbGl0aWVzLCBhbmQgYXJlIG5vdCBpbiB0aGVtc2VsdmVzCisgKiB1c2VmdWwgZm9yIG1vc3QgY29uY3VycmVuY3kgY29udHJvbCBhcHBsaWNhdGlvbnMuICBUaGUge0Bjb2RlIHBhcmt9CisgKiBtZXRob2QgaXMgZGVzaWduZWQgZm9yIHVzZSBvbmx5IGluIGNvbnN0cnVjdGlvbnMgb2YgdGhlIGZvcm06CisgKiA8cHJlPndoaWxlICghY2FuUHJvY2VlZCgpKSB7IC4uLiBMb2NrU3VwcG9ydC5wYXJrKHRoaXMpOyB9PC9wcmU+CisgKiB3aGVyZSBuZWl0aGVyIHtAY29kZSBjYW5Qcm9jZWVkfSBub3IgYW55IG90aGVyIGFjdGlvbnMgcHJpb3IgdG8gdGhlCisgKiBjYWxsIHRvIHtAY29kZSBwYXJrfSBlbnRhaWwgbG9ja2luZyBvciBibG9ja2luZy4gIEJlY2F1c2Ugb25seSBvbmUKKyAqIHBlcm1pdCBpcyBhc3NvY2lhdGVkIHdpdGggZWFjaCB0aHJlYWQsIGFueSBpbnRlcm1lZGlhcnkgdXNlcyBvZgorICoge0Bjb2RlIHBhcmt9IGNvdWxkIGludGVyZmVyZSB3aXRoIGl0cyBpbnRlbmRlZCBlZmZlY3RzLgorICoKKyAqIDxwPjxiPlNhbXBsZSBVc2FnZS48L2I+IEhlcmUgaXMgYSBza2V0Y2ggb2YgYSBmaXJzdC1pbi1maXJzdC1vdXQKKyAqIG5vbi1yZWVudHJhbnQgbG9jayBjbGFzczoKKyAqIDxwcmU+e0Bjb2RlCisgKiBjbGFzcyBGSUZPTXV0ZXggeworICogICBwcml2YXRlIGZpbmFsIEF0b21pY0Jvb2xlYW4gbG9ja2VkID0gbmV3IEF0b21pY0Jvb2xlYW4oZmFsc2UpOworICogICBwcml2YXRlIGZpbmFsIFF1ZXVlPFRocmVhZD4gd2FpdGVycworICogICAgID0gbmV3IENvbmN1cnJlbnRMaW5rZWRRdWV1ZTxUaHJlYWQ+KCk7CisgKgorICogICBwdWJsaWMgdm9pZCBsb2NrKCkgeworICogICAgIGJvb2xlYW4gd2FzSW50ZXJydXB0ZWQgPSBmYWxzZTsKKyAqICAgICBUaHJlYWQgY3VycmVudCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisgKiAgICAgd2FpdGVycy5hZGQoY3VycmVudCk7CisgKgorICogICAgIC8vIEJsb2NrIHdoaWxlIG5vdCBmaXJzdCBpbiBxdWV1ZSBvciBjYW5ub3QgYWNxdWlyZSBsb2NrCisgKiAgICAgd2hpbGUgKHdhaXRlcnMucGVlaygpICE9IGN1cnJlbnQgfHwKKyAqICAgICAgICAgICAgIWxvY2tlZC5jb21wYXJlQW5kU2V0KGZhbHNlLCB0cnVlKSkgeworICogICAgICAgIExvY2tTdXBwb3J0LnBhcmsodGhpcyk7CisgKiAgICAgICAgaWYgKFRocmVhZC5pbnRlcnJ1cHRlZCgpKSAvLyBpZ25vcmUgaW50ZXJydXB0cyB3aGlsZSB3YWl0aW5nCisgKiAgICAgICAgICB3YXNJbnRlcnJ1cHRlZCA9IHRydWU7CisgKiAgICAgfQorICoKKyAqICAgICB3YWl0ZXJzLnJlbW92ZSgpOworICogICAgIGlmICh3YXNJbnRlcnJ1cHRlZCkgICAgICAgICAgLy8gcmVhc3NlcnQgaW50ZXJydXB0IHN0YXR1cyBvbiBleGl0CisgKiAgICAgICAgY3VycmVudC5pbnRlcnJ1cHQoKTsKKyAqICAgfQorICoKKyAqICAgcHVibGljIHZvaWQgdW5sb2NrKCkgeworICogICAgIGxvY2tlZC5zZXQoZmFsc2UpOworICogICAgIExvY2tTdXBwb3J0LnVucGFyayh3YWl0ZXJzLnBlZWsoKSk7CisgKiAgIH0KKyAqIH19PC9wcmU+CisgKi8KKworcHVibGljIGNsYXNzIExvY2tTdXBwb3J0IHsKKyAgICBwcml2YXRlIExvY2tTdXBwb3J0KCkge30gLy8gQ2Fubm90IGJlIGluc3RhbnRpYXRlZC4KKworICAgIC8vIEhvdHNwb3QgaW1wbGVtZW50YXRpb24gdmlhIGludHJpbnNpY3MgQVBJCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVW5zYWZlIHVuc2FmZSA9IFVuc2FmZUFjY2Vzcy5USEVfT05FOyAvLyBhbmRyb2lkLWNoYW5nZWQKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHBhcmtCbG9ja2VyT2Zmc2V0OworCisgICAgc3RhdGljIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmtCbG9ja2VyT2Zmc2V0ID0gdW5zYWZlLm9iamVjdEZpZWxkT2Zmc2V0CisgICAgICAgICAgICAgICAgKGphdmEubGFuZy5UaHJlYWQuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgicGFya0Jsb2NrZXIiKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeyB0aHJvdyBuZXcgRXJyb3IoZXgpOyB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBzZXRCbG9ja2VyKFRocmVhZCB0LCBPYmplY3QgYXJnKSB7CisgICAgICAgIC8vIEV2ZW4gdGhvdWdoIHZvbGF0aWxlLCBob3RzcG90IGRvZXNuJ3QgbmVlZCBhIHdyaXRlIGJhcnJpZXIgaGVyZS4KKyAgICAgICAgdW5zYWZlLnB1dE9iamVjdCh0LCBwYXJrQmxvY2tlck9mZnNldCwgYXJnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYWtlcyBhdmFpbGFibGUgdGhlIHBlcm1pdCBmb3IgdGhlIGdpdmVuIHRocmVhZCwgaWYgaXQKKyAgICAgKiB3YXMgbm90IGFscmVhZHkgYXZhaWxhYmxlLiAgSWYgdGhlIHRocmVhZCB3YXMgYmxvY2tlZCBvbgorICAgICAqIHtAY29kZSBwYXJrfSB0aGVuIGl0IHdpbGwgdW5ibG9jay4gIE90aGVyd2lzZSwgaXRzIG5leHQgY2FsbAorICAgICAqIHRvIHtAY29kZSBwYXJrfSBpcyBndWFyYW50ZWVkIG5vdCB0byBibG9jay4gVGhpcyBvcGVyYXRpb24KKyAgICAgKiBpcyBub3QgZ3VhcmFudGVlZCB0byBoYXZlIGFueSBlZmZlY3QgYXQgYWxsIGlmIHRoZSBnaXZlbgorICAgICAqIHRocmVhZCBoYXMgbm90IGJlZW4gc3RhcnRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aHJlYWQgdGhlIHRocmVhZCB0byB1bnBhcmssIG9yIHtAY29kZSBudWxsfSwgaW4gd2hpY2ggY2FzZQorICAgICAqICAgICAgICB0aGlzIG9wZXJhdGlvbiBoYXMgbm8gZWZmZWN0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHVucGFyayhUaHJlYWQgdGhyZWFkKSB7CisgICAgICAgIGlmICh0aHJlYWQgIT0gbnVsbCkKKyAgICAgICAgICAgIHVuc2FmZS51bnBhcmsodGhyZWFkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEaXNhYmxlcyB0aGUgY3VycmVudCB0aHJlYWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nIHB1cnBvc2VzIHVubGVzcyB0aGUKKyAgICAgKiBwZXJtaXQgaXMgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogPHA+SWYgdGhlIHBlcm1pdCBpcyBhdmFpbGFibGUgdGhlbiBpdCBpcyBjb25zdW1lZCBhbmQgdGhlIGNhbGwgcmV0dXJucworICAgICAqIGltbWVkaWF0ZWx5OyBvdGhlcndpc2UKKyAgICAgKiB0aGUgY3VycmVudCB0aHJlYWQgYmVjb21lcyBkaXNhYmxlZCBmb3IgdGhyZWFkIHNjaGVkdWxpbmcKKyAgICAgKiBwdXJwb3NlcyBhbmQgbGllcyBkb3JtYW50IHVudGlsIG9uZSBvZiB0aHJlZSB0aGluZ3MgaGFwcGVuczoKKyAgICAgKgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQgaW52b2tlcyB7QGxpbmsgI3VucGFyayB1bnBhcmt9IHdpdGggdGhlCisgICAgICogY3VycmVudCB0aHJlYWQgYXMgdGhlIHRhcmdldDsgb3IKKyAgICAgKgorICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdHN9CisgICAgICogdGhlIGN1cnJlbnQgdGhyZWFkOyBvcgorICAgICAqCisgICAgICogPGxpPlRoZSBjYWxsIHNwdXJpb3VzbHkgKHRoYXQgaXMsIGZvciBubyByZWFzb24pIHJldHVybnMuCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGRvZXMgPGVtPm5vdDwvZW0+IHJlcG9ydCB3aGljaCBvZiB0aGVzZSBjYXVzZWQgdGhlCisgICAgICogbWV0aG9kIHRvIHJldHVybi4gQ2FsbGVycyBzaG91bGQgcmUtY2hlY2sgdGhlIGNvbmRpdGlvbnMgd2hpY2ggY2F1c2VkCisgICAgICogdGhlIHRocmVhZCB0byBwYXJrIGluIHRoZSBmaXJzdCBwbGFjZS4gQ2FsbGVycyBtYXkgYWxzbyBkZXRlcm1pbmUsCisgICAgICogZm9yIGV4YW1wbGUsIHRoZSBpbnRlcnJ1cHQgc3RhdHVzIG9mIHRoZSB0aHJlYWQgdXBvbiByZXR1cm4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYmxvY2tlciB0aGUgc3luY2hyb25pemF0aW9uIG9iamVjdCByZXNwb25zaWJsZSBmb3IgdGhpcworICAgICAqICAgICAgICB0aHJlYWQgcGFya2luZworICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcGFyayhPYmplY3QgYmxvY2tlcikgeworICAgICAgICBUaHJlYWQgdCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisgICAgICAgIHNldEJsb2NrZXIodCwgYmxvY2tlcik7CisgICAgICAgIHVuc2FmZS5wYXJrKGZhbHNlLCAwTCk7CisgICAgICAgIHNldEJsb2NrZXIodCwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGlzYWJsZXMgdGhlIGN1cnJlbnQgdGhyZWFkIGZvciB0aHJlYWQgc2NoZWR1bGluZyBwdXJwb3NlcywgZm9yIHVwIHRvCisgICAgICogdGhlIHNwZWNpZmllZCB3YWl0aW5nIHRpbWUsIHVubGVzcyB0aGUgcGVybWl0IGlzIGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBwZXJtaXQgaXMgYXZhaWxhYmxlIHRoZW4gaXQgaXMgY29uc3VtZWQgYW5kIHRoZSBjYWxsCisgICAgICogcmV0dXJucyBpbW1lZGlhdGVseTsgb3RoZXJ3aXNlIHRoZSBjdXJyZW50IHRocmVhZCBiZWNvbWVzIGRpc2FibGVkCisgICAgICogZm9yIHRocmVhZCBzY2hlZHVsaW5nIHB1cnBvc2VzIGFuZCBsaWVzIGRvcm1hbnQgdW50aWwgb25lIG9mIGZvdXIKKyAgICAgKiB0aGluZ3MgaGFwcGVuczoKKyAgICAgKgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQgaW52b2tlcyB7QGxpbmsgI3VucGFyayB1bnBhcmt9IHdpdGggdGhlCisgICAgICogY3VycmVudCB0aHJlYWQgYXMgdGhlIHRhcmdldDsgb3IKKyAgICAgKgorICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdHN9CisgICAgICogdGhlIGN1cnJlbnQgdGhyZWFkOyBvcgorICAgICAqCisgICAgICogPGxpPlRoZSBzcGVjaWZpZWQgd2FpdGluZyB0aW1lIGVsYXBzZXM7IG9yCisgICAgICoKKyAgICAgKiA8bGk+VGhlIGNhbGwgc3B1cmlvdXNseSAodGhhdCBpcywgZm9yIG5vIHJlYXNvbikgcmV0dXJucy4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgZG9lcyA8ZW0+bm90PC9lbT4gcmVwb3J0IHdoaWNoIG9mIHRoZXNlIGNhdXNlZCB0aGUKKyAgICAgKiBtZXRob2QgdG8gcmV0dXJuLiBDYWxsZXJzIHNob3VsZCByZS1jaGVjayB0aGUgY29uZGl0aW9ucyB3aGljaCBjYXVzZWQKKyAgICAgKiB0aGUgdGhyZWFkIHRvIHBhcmsgaW4gdGhlIGZpcnN0IHBsYWNlLiBDYWxsZXJzIG1heSBhbHNvIGRldGVybWluZSwKKyAgICAgKiBmb3IgZXhhbXBsZSwgdGhlIGludGVycnVwdCBzdGF0dXMgb2YgdGhlIHRocmVhZCwgb3IgdGhlIGVsYXBzZWQgdGltZQorICAgICAqIHVwb24gcmV0dXJuLgorICAgICAqCisgICAgICogQHBhcmFtIGJsb2NrZXIgdGhlIHN5bmNocm9uaXphdGlvbiBvYmplY3QgcmVzcG9uc2libGUgZm9yIHRoaXMKKyAgICAgKiAgICAgICAgdGhyZWFkIHBhcmtpbmcKKyAgICAgKiBAcGFyYW0gbmFub3MgdGhlIG1heGltdW0gbnVtYmVyIG9mIG5hbm9zZWNvbmRzIHRvIHdhaXQKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHBhcmtOYW5vcyhPYmplY3QgYmxvY2tlciwgbG9uZyBuYW5vcykgeworICAgICAgICBpZiAobmFub3MgPiAwKSB7CisgICAgICAgICAgICBUaHJlYWQgdCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisgICAgICAgICAgICBzZXRCbG9ja2VyKHQsIGJsb2NrZXIpOworICAgICAgICAgICAgdW5zYWZlLnBhcmsoZmFsc2UsIG5hbm9zKTsKKyAgICAgICAgICAgIHNldEJsb2NrZXIodCwgbnVsbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEaXNhYmxlcyB0aGUgY3VycmVudCB0aHJlYWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nIHB1cnBvc2VzLCB1bnRpbAorICAgICAqIHRoZSBzcGVjaWZpZWQgZGVhZGxpbmUsIHVubGVzcyB0aGUgcGVybWl0IGlzIGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBwZXJtaXQgaXMgYXZhaWxhYmxlIHRoZW4gaXQgaXMgY29uc3VtZWQgYW5kIHRoZSBjYWxsCisgICAgICogcmV0dXJucyBpbW1lZGlhdGVseTsgb3RoZXJ3aXNlIHRoZSBjdXJyZW50IHRocmVhZCBiZWNvbWVzIGRpc2FibGVkCisgICAgICogZm9yIHRocmVhZCBzY2hlZHVsaW5nIHB1cnBvc2VzIGFuZCBsaWVzIGRvcm1hbnQgdW50aWwgb25lIG9mIGZvdXIKKyAgICAgKiB0aGluZ3MgaGFwcGVuczoKKyAgICAgKgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQgaW52b2tlcyB7QGxpbmsgI3VucGFyayB1bnBhcmt9IHdpdGggdGhlCisgICAgICogY3VycmVudCB0aHJlYWQgYXMgdGhlIHRhcmdldDsgb3IKKyAgICAgKgorICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdHN9IHRoZQorICAgICAqIGN1cnJlbnQgdGhyZWFkOyBvcgorICAgICAqCisgICAgICogPGxpPlRoZSBzcGVjaWZpZWQgZGVhZGxpbmUgcGFzc2VzOyBvcgorICAgICAqCisgICAgICogPGxpPlRoZSBjYWxsIHNwdXJpb3VzbHkgKHRoYXQgaXMsIGZvciBubyByZWFzb24pIHJldHVybnMuCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGRvZXMgPGVtPm5vdDwvZW0+IHJlcG9ydCB3aGljaCBvZiB0aGVzZSBjYXVzZWQgdGhlCisgICAgICogbWV0aG9kIHRvIHJldHVybi4gQ2FsbGVycyBzaG91bGQgcmUtY2hlY2sgdGhlIGNvbmRpdGlvbnMgd2hpY2ggY2F1c2VkCisgICAgICogdGhlIHRocmVhZCB0byBwYXJrIGluIHRoZSBmaXJzdCBwbGFjZS4gQ2FsbGVycyBtYXkgYWxzbyBkZXRlcm1pbmUsCisgICAgICogZm9yIGV4YW1wbGUsIHRoZSBpbnRlcnJ1cHQgc3RhdHVzIG9mIHRoZSB0aHJlYWQsIG9yIHRoZSBjdXJyZW50IHRpbWUKKyAgICAgKiB1cG9uIHJldHVybi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBibG9ja2VyIHRoZSBzeW5jaHJvbml6YXRpb24gb2JqZWN0IHJlc3BvbnNpYmxlIGZvciB0aGlzCisgICAgICogICAgICAgIHRocmVhZCBwYXJraW5nCisgICAgICogQHBhcmFtIGRlYWRsaW5lIHRoZSBhYnNvbHV0ZSB0aW1lLCBpbiBtaWxsaXNlY29uZHMgZnJvbSB0aGUgRXBvY2gsCisgICAgICogICAgICAgIHRvIHdhaXQgdW50aWwKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHBhcmtVbnRpbChPYmplY3QgYmxvY2tlciwgbG9uZyBkZWFkbGluZSkgeworICAgICAgICBUaHJlYWQgdCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisgICAgICAgIHNldEJsb2NrZXIodCwgYmxvY2tlcik7CisgICAgICAgIHVuc2FmZS5wYXJrKHRydWUsIGRlYWRsaW5lKTsKKyAgICAgICAgc2V0QmxvY2tlcih0LCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBibG9ja2VyIG9iamVjdCBzdXBwbGllZCB0byB0aGUgbW9zdCByZWNlbnQKKyAgICAgKiBpbnZvY2F0aW9uIG9mIGEgcGFyayBtZXRob2QgdGhhdCBoYXMgbm90IHlldCB1bmJsb2NrZWQsIG9yIG51bGwKKyAgICAgKiBpZiBub3QgYmxvY2tlZC4gIFRoZSB2YWx1ZSByZXR1cm5lZCBpcyBqdXN0IGEgbW9tZW50YXJ5CisgICAgICogc25hcHNob3QgLS0gdGhlIHRocmVhZCBtYXkgaGF2ZSBzaW5jZSB1bmJsb2NrZWQgb3IgYmxvY2tlZCBvbiBhCisgICAgICogZGlmZmVyZW50IGJsb2NrZXIgb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYmxvY2tlcgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIE9iamVjdCBnZXRCbG9ja2VyKFRocmVhZCB0KSB7CisgICAgICAgIHJldHVybiB1bnNhZmUuZ2V0T2JqZWN0Vm9sYXRpbGUodCwgcGFya0Jsb2NrZXJPZmZzZXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERpc2FibGVzIHRoZSBjdXJyZW50IHRocmVhZCBmb3IgdGhyZWFkIHNjaGVkdWxpbmcgcHVycG9zZXMgdW5sZXNzIHRoZQorICAgICAqIHBlcm1pdCBpcyBhdmFpbGFibGUuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgcGVybWl0IGlzIGF2YWlsYWJsZSB0aGVuIGl0IGlzIGNvbnN1bWVkIGFuZCB0aGUgY2FsbAorICAgICAqIHJldHVybnMgaW1tZWRpYXRlbHk7IG90aGVyd2lzZSB0aGUgY3VycmVudCB0aHJlYWQgYmVjb21lcyBkaXNhYmxlZAorICAgICAqIGZvciB0aHJlYWQgc2NoZWR1bGluZyBwdXJwb3NlcyBhbmQgbGllcyBkb3JtYW50IHVudGlsIG9uZSBvZiB0aHJlZQorICAgICAqIHRoaW5ncyBoYXBwZW5zOgorICAgICAqCisgICAgICogPHVsPgorICAgICAqCisgICAgICogPGxpPlNvbWUgb3RoZXIgdGhyZWFkIGludm9rZXMge0BsaW5rICN1bnBhcmsgdW5wYXJrfSB3aXRoIHRoZQorICAgICAqIGN1cnJlbnQgdGhyZWFkIGFzIHRoZSB0YXJnZXQ7IG9yCisgICAgICoKKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRzfQorICAgICAqIHRoZSBjdXJyZW50IHRocmVhZDsgb3IKKyAgICAgKgorICAgICAqIDxsaT5UaGUgY2FsbCBzcHVyaW91c2x5ICh0aGF0IGlzLCBmb3Igbm8gcmVhc29uKSByZXR1cm5zLgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBkb2VzIDxlbT5ub3Q8L2VtPiByZXBvcnQgd2hpY2ggb2YgdGhlc2UgY2F1c2VkIHRoZQorICAgICAqIG1ldGhvZCB0byByZXR1cm4uIENhbGxlcnMgc2hvdWxkIHJlLWNoZWNrIHRoZSBjb25kaXRpb25zIHdoaWNoIGNhdXNlZAorICAgICAqIHRoZSB0aHJlYWQgdG8gcGFyayBpbiB0aGUgZmlyc3QgcGxhY2UuIENhbGxlcnMgbWF5IGFsc28gZGV0ZXJtaW5lLAorICAgICAqIGZvciBleGFtcGxlLCB0aGUgaW50ZXJydXB0IHN0YXR1cyBvZiB0aGUgdGhyZWFkIHVwb24gcmV0dXJuLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBwYXJrKCkgeworICAgICAgICB1bnNhZmUucGFyayhmYWxzZSwgMEwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERpc2FibGVzIHRoZSBjdXJyZW50IHRocmVhZCBmb3IgdGhyZWFkIHNjaGVkdWxpbmcgcHVycG9zZXMsIGZvciB1cCB0bworICAgICAqIHRoZSBzcGVjaWZpZWQgd2FpdGluZyB0aW1lLCB1bmxlc3MgdGhlIHBlcm1pdCBpcyBhdmFpbGFibGUuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgcGVybWl0IGlzIGF2YWlsYWJsZSB0aGVuIGl0IGlzIGNvbnN1bWVkIGFuZCB0aGUgY2FsbAorICAgICAqIHJldHVybnMgaW1tZWRpYXRlbHk7IG90aGVyd2lzZSB0aGUgY3VycmVudCB0aHJlYWQgYmVjb21lcyBkaXNhYmxlZAorICAgICAqIGZvciB0aHJlYWQgc2NoZWR1bGluZyBwdXJwb3NlcyBhbmQgbGllcyBkb3JtYW50IHVudGlsIG9uZSBvZiBmb3VyCisgICAgICogdGhpbmdzIGhhcHBlbnM6CisgICAgICoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPlNvbWUgb3RoZXIgdGhyZWFkIGludm9rZXMge0BsaW5rICN1bnBhcmsgdW5wYXJrfSB3aXRoIHRoZQorICAgICAqIGN1cnJlbnQgdGhyZWFkIGFzIHRoZSB0YXJnZXQ7IG9yCisgICAgICoKKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRzfQorICAgICAqIHRoZSBjdXJyZW50IHRocmVhZDsgb3IKKyAgICAgKgorICAgICAqIDxsaT5UaGUgc3BlY2lmaWVkIHdhaXRpbmcgdGltZSBlbGFwc2VzOyBvcgorICAgICAqCisgICAgICogPGxpPlRoZSBjYWxsIHNwdXJpb3VzbHkgKHRoYXQgaXMsIGZvciBubyByZWFzb24pIHJldHVybnMuCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGRvZXMgPGVtPm5vdDwvZW0+IHJlcG9ydCB3aGljaCBvZiB0aGVzZSBjYXVzZWQgdGhlCisgICAgICogbWV0aG9kIHRvIHJldHVybi4gQ2FsbGVycyBzaG91bGQgcmUtY2hlY2sgdGhlIGNvbmRpdGlvbnMgd2hpY2ggY2F1c2VkCisgICAgICogdGhlIHRocmVhZCB0byBwYXJrIGluIHRoZSBmaXJzdCBwbGFjZS4gQ2FsbGVycyBtYXkgYWxzbyBkZXRlcm1pbmUsCisgICAgICogZm9yIGV4YW1wbGUsIHRoZSBpbnRlcnJ1cHQgc3RhdHVzIG9mIHRoZSB0aHJlYWQsIG9yIHRoZSBlbGFwc2VkIHRpbWUKKyAgICAgKiB1cG9uIHJldHVybi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW5vcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgbmFub3NlY29uZHMgdG8gd2FpdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBwYXJrTmFub3MobG9uZyBuYW5vcykgeworICAgICAgICBpZiAobmFub3MgPiAwKQorICAgICAgICAgICAgdW5zYWZlLnBhcmsoZmFsc2UsIG5hbm9zKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEaXNhYmxlcyB0aGUgY3VycmVudCB0aHJlYWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nIHB1cnBvc2VzLCB1bnRpbAorICAgICAqIHRoZSBzcGVjaWZpZWQgZGVhZGxpbmUsIHVubGVzcyB0aGUgcGVybWl0IGlzIGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBwZXJtaXQgaXMgYXZhaWxhYmxlIHRoZW4gaXQgaXMgY29uc3VtZWQgYW5kIHRoZSBjYWxsCisgICAgICogcmV0dXJucyBpbW1lZGlhdGVseTsgb3RoZXJ3aXNlIHRoZSBjdXJyZW50IHRocmVhZCBiZWNvbWVzIGRpc2FibGVkCisgICAgICogZm9yIHRocmVhZCBzY2hlZHVsaW5nIHB1cnBvc2VzIGFuZCBsaWVzIGRvcm1hbnQgdW50aWwgb25lIG9mIGZvdXIKKyAgICAgKiB0aGluZ3MgaGFwcGVuczoKKyAgICAgKgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQgaW52b2tlcyB7QGxpbmsgI3VucGFyayB1bnBhcmt9IHdpdGggdGhlCisgICAgICogY3VycmVudCB0aHJlYWQgYXMgdGhlIHRhcmdldDsgb3IKKyAgICAgKgorICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdHN9CisgICAgICogdGhlIGN1cnJlbnQgdGhyZWFkOyBvcgorICAgICAqCisgICAgICogPGxpPlRoZSBzcGVjaWZpZWQgZGVhZGxpbmUgcGFzc2VzOyBvcgorICAgICAqCisgICAgICogPGxpPlRoZSBjYWxsIHNwdXJpb3VzbHkgKHRoYXQgaXMsIGZvciBubyByZWFzb24pIHJldHVybnMuCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGRvZXMgPGVtPm5vdDwvZW0+IHJlcG9ydCB3aGljaCBvZiB0aGVzZSBjYXVzZWQgdGhlCisgICAgICogbWV0aG9kIHRvIHJldHVybi4gQ2FsbGVycyBzaG91bGQgcmUtY2hlY2sgdGhlIGNvbmRpdGlvbnMgd2hpY2ggY2F1c2VkCisgICAgICogdGhlIHRocmVhZCB0byBwYXJrIGluIHRoZSBmaXJzdCBwbGFjZS4gQ2FsbGVycyBtYXkgYWxzbyBkZXRlcm1pbmUsCisgICAgICogZm9yIGV4YW1wbGUsIHRoZSBpbnRlcnJ1cHQgc3RhdHVzIG9mIHRoZSB0aHJlYWQsIG9yIHRoZSBjdXJyZW50IHRpbWUKKyAgICAgKiB1cG9uIHJldHVybi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZWFkbGluZSB0aGUgYWJzb2x1dGUgdGltZSwgaW4gbWlsbGlzZWNvbmRzIGZyb20gdGhlIEVwb2NoLAorICAgICAqICAgICAgICB0byB3YWl0IHVudGlsCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHBhcmtVbnRpbChsb25nIGRlYWRsaW5lKSB7CisgICAgICAgIHVuc2FmZS5wYXJrKHRydWUsIGRlYWRsaW5lKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvbG9ja3MvUmVhZFdyaXRlTG9jay5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL1JlYWRXcml0ZUxvY2suamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ODRmNjhkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL1JlYWRXcml0ZUxvY2suamF2YQpAQCAtMCwwICsxLDEwNCBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzOworCisvKioKKyAqIEEgPHR0PlJlYWRXcml0ZUxvY2s8L3R0PiBtYWludGFpbnMgYSBwYWlyIG9mIGFzc29jaWF0ZWQge0BsaW5rCisgKiBMb2NrIGxvY2tzfSwgb25lIGZvciByZWFkLW9ubHkgb3BlcmF0aW9ucyBhbmQgb25lIGZvciB3cml0aW5nLgorICogVGhlIHtAbGluayAjcmVhZExvY2sgcmVhZCBsb2NrfSBtYXkgYmUgaGVsZCBzaW11bHRhbmVvdXNseSBieQorICogbXVsdGlwbGUgcmVhZGVyIHRocmVhZHMsIHNvIGxvbmcgYXMgdGhlcmUgYXJlIG5vIHdyaXRlcnMuICBUaGUKKyAqIHtAbGluayAjd3JpdGVMb2NrIHdyaXRlIGxvY2t9IGlzIGV4Y2x1c2l2ZS4KKyAqCisgKiA8cD5BbGwgPHR0PlJlYWRXcml0ZUxvY2s8L3R0PiBpbXBsZW1lbnRhdGlvbnMgbXVzdCBndWFyYW50ZWUgdGhhdAorICogdGhlIG1lbW9yeSBzeW5jaHJvbml6YXRpb24gZWZmZWN0cyBvZiA8dHQ+d3JpdGVMb2NrPC90dD4gb3BlcmF0aW9ucworICogKGFzIHNwZWNpZmllZCBpbiB0aGUge0BsaW5rIExvY2t9IGludGVyZmFjZSkgYWxzbyBob2xkIHdpdGggcmVzcGVjdAorICogdG8gdGhlIGFzc29jaWF0ZWQgPHR0PnJlYWRMb2NrPC90dD4uIFRoYXQgaXMsIGEgdGhyZWFkIHN1Y2Nlc3NmdWxseQorICogYWNxdWlyaW5nIHRoZSByZWFkIGxvY2sgd2lsbCBzZWUgYWxsIHVwZGF0ZXMgbWFkZSB1cG9uIHByZXZpb3VzCisgKiByZWxlYXNlIG9mIHRoZSB3cml0ZSBsb2NrLgorICoKKyAqIDxwPkEgcmVhZC13cml0ZSBsb2NrIGFsbG93cyBmb3IgYSBncmVhdGVyIGxldmVsIG9mIGNvbmN1cnJlbmN5IGluCisgKiBhY2Nlc3Npbmcgc2hhcmVkIGRhdGEgdGhhbiB0aGF0IHBlcm1pdHRlZCBieSBhIG11dHVhbCBleGNsdXNpb24gbG9jay4KKyAqIEl0IGV4cGxvaXRzIHRoZSBmYWN0IHRoYXQgd2hpbGUgb25seSBhIHNpbmdsZSB0aHJlYWQgYXQgYSB0aW1lIChhCisgKiA8ZW0+d3JpdGVyPC9lbT4gdGhyZWFkKSBjYW4gbW9kaWZ5IHRoZSBzaGFyZWQgZGF0YSwgaW4gbWFueSBjYXNlcyBhbnkKKyAqIG51bWJlciBvZiB0aHJlYWRzIGNhbiBjb25jdXJyZW50bHkgcmVhZCB0aGUgZGF0YSAoaGVuY2UgPGVtPnJlYWRlcjwvZW0+CisgKiB0aHJlYWRzKS4KKyAqIEluIHRoZW9yeSwgdGhlIGluY3JlYXNlIGluIGNvbmN1cnJlbmN5IHBlcm1pdHRlZCBieSB0aGUgdXNlIG9mIGEgcmVhZC13cml0ZQorICogbG9jayB3aWxsIGxlYWQgdG8gcGVyZm9ybWFuY2UgaW1wcm92ZW1lbnRzIG92ZXIgdGhlIHVzZSBvZiBhIG11dHVhbAorICogZXhjbHVzaW9uIGxvY2suIEluIHByYWN0aWNlIHRoaXMgaW5jcmVhc2UgaW4gY29uY3VycmVuY3kgd2lsbCBvbmx5IGJlIGZ1bGx5CisgKiByZWFsaXplZCBvbiBhIG11bHRpLXByb2Nlc3NvciwgYW5kIHRoZW4gb25seSBpZiB0aGUgYWNjZXNzIHBhdHRlcm5zIGZvcgorICogdGhlIHNoYXJlZCBkYXRhIGFyZSBzdWl0YWJsZS4KKyAqCisgKiA8cD5XaGV0aGVyIG9yIG5vdCBhIHJlYWQtd3JpdGUgbG9jayB3aWxsIGltcHJvdmUgcGVyZm9ybWFuY2Ugb3ZlciB0aGUgdXNlCisgKiBvZiBhIG11dHVhbCBleGNsdXNpb24gbG9jayBkZXBlbmRzIG9uIHRoZSBmcmVxdWVuY3kgdGhhdCB0aGUgZGF0YSBpcworICogcmVhZCBjb21wYXJlZCB0byBiZWluZyBtb2RpZmllZCwgdGhlIGR1cmF0aW9uIG9mIHRoZSByZWFkIGFuZCB3cml0ZQorICogb3BlcmF0aW9ucywgYW5kIHRoZSBjb250ZW50aW9uIGZvciB0aGUgZGF0YSAtIHRoYXQgaXMsIHRoZSBudW1iZXIgb2YKKyAqIHRocmVhZHMgdGhhdCB3aWxsIHRyeSB0byByZWFkIG9yIHdyaXRlIHRoZSBkYXRhIGF0IHRoZSBzYW1lIHRpbWUuCisgKiBGb3IgZXhhbXBsZSwgYSBjb2xsZWN0aW9uIHRoYXQgaXMgaW5pdGlhbGx5IHBvcHVsYXRlZCB3aXRoIGRhdGEgYW5kCisgKiB0aGVyZWFmdGVyIGluZnJlcXVlbnRseSBtb2RpZmllZCwgd2hpbGUgYmVpbmcgZnJlcXVlbnRseSBzZWFyY2hlZAorICogKHN1Y2ggYXMgYSBkaXJlY3Rvcnkgb2Ygc29tZSBraW5kKSBpcyBhbiBpZGVhbCBjYW5kaWRhdGUgZm9yIHRoZSB1c2Ugb2YKKyAqIGEgcmVhZC13cml0ZSBsb2NrLiBIb3dldmVyLCBpZiB1cGRhdGVzIGJlY29tZSBmcmVxdWVudCB0aGVuIHRoZSBkYXRhCisgKiBzcGVuZHMgbW9zdCBvZiBpdHMgdGltZSBiZWluZyBleGNsdXNpdmVseSBsb2NrZWQgYW5kIHRoZXJlIGlzIGxpdHRsZSwgaWYgYW55CisgKiBpbmNyZWFzZSBpbiBjb25jdXJyZW5jeS4gRnVydGhlciwgaWYgdGhlIHJlYWQgb3BlcmF0aW9ucyBhcmUgdG9vIHNob3J0CisgKiB0aGUgb3ZlcmhlYWQgb2YgdGhlIHJlYWQtd3JpdGUgbG9jayBpbXBsZW1lbnRhdGlvbiAod2hpY2ggaXMgaW5oZXJlbnRseQorICogbW9yZSBjb21wbGV4IHRoYW4gYSBtdXR1YWwgZXhjbHVzaW9uIGxvY2spIGNhbiBkb21pbmF0ZSB0aGUgZXhlY3V0aW9uCisgKiBjb3N0LCBwYXJ0aWN1bGFybHkgYXMgbWFueSByZWFkLXdyaXRlIGxvY2sgaW1wbGVtZW50YXRpb25zIHN0aWxsIHNlcmlhbGl6ZQorICogYWxsIHRocmVhZHMgdGhyb3VnaCBhIHNtYWxsIHNlY3Rpb24gb2YgY29kZS4gVWx0aW1hdGVseSwgb25seSBwcm9maWxpbmcKKyAqIGFuZCBtZWFzdXJlbWVudCB3aWxsIGVzdGFibGlzaCB3aGV0aGVyIHRoZSB1c2Ugb2YgYSByZWFkLXdyaXRlIGxvY2sgaXMKKyAqIHN1aXRhYmxlIGZvciB5b3VyIGFwcGxpY2F0aW9uLgorICoKKyAqCisgKiA8cD5BbHRob3VnaCB0aGUgYmFzaWMgb3BlcmF0aW9uIG9mIGEgcmVhZC13cml0ZSBsb2NrIGlzIHN0cmFpZ2h0LWZvcndhcmQsCisgKiB0aGVyZSBhcmUgbWFueSBwb2xpY3kgZGVjaXNpb25zIHRoYXQgYW4gaW1wbGVtZW50YXRpb24gbXVzdCBtYWtlLCB3aGljaAorICogbWF5IGFmZmVjdCB0aGUgZWZmZWN0aXZlbmVzcyBvZiB0aGUgcmVhZC13cml0ZSBsb2NrIGluIGEgZ2l2ZW4gYXBwbGljYXRpb24uCisgKiBFeGFtcGxlcyBvZiB0aGVzZSBwb2xpY2llcyBpbmNsdWRlOgorICogPHVsPgorICogPGxpPkRldGVybWluaW5nIHdoZXRoZXIgdG8gZ3JhbnQgdGhlIHJlYWQgbG9jayBvciB0aGUgd3JpdGUgbG9jaywgd2hlbgorICogYm90aCByZWFkZXJzIGFuZCB3cml0ZXJzIGFyZSB3YWl0aW5nLCBhdCB0aGUgdGltZSB0aGF0IGEgd3JpdGVyIHJlbGVhc2VzCisgKiB0aGUgd3JpdGUgbG9jay4gV3JpdGVyIHByZWZlcmVuY2UgaXMgY29tbW9uLCBhcyB3cml0ZXMgYXJlIGV4cGVjdGVkIHRvIGJlCisgKiBzaG9ydCBhbmQgaW5mcmVxdWVudC4gUmVhZGVyIHByZWZlcmVuY2UgaXMgbGVzcyBjb21tb24gYXMgaXQgY2FuIGxlYWQgdG8KKyAqIGxlbmd0aHkgZGVsYXlzIGZvciBhIHdyaXRlIGlmIHRoZSByZWFkZXJzIGFyZSBmcmVxdWVudCBhbmQgbG9uZy1saXZlZCBhcworICogZXhwZWN0ZWQuIEZhaXIsIG9yICZxdW90O2luLW9yZGVyJnF1b3Q7IGltcGxlbWVudGF0aW9ucyBhcmUgYWxzbyBwb3NzaWJsZS4KKyAqCisgKiA8bGk+RGV0ZXJtaW5pbmcgd2hldGhlciByZWFkZXJzIHRoYXQgcmVxdWVzdCB0aGUgcmVhZCBsb2NrIHdoaWxlIGEKKyAqIHJlYWRlciBpcyBhY3RpdmUgYW5kIGEgd3JpdGVyIGlzIHdhaXRpbmcsIGFyZSBncmFudGVkIHRoZSByZWFkIGxvY2suCisgKiBQcmVmZXJlbmNlIHRvIHRoZSByZWFkZXIgY2FuIGRlbGF5IHRoZSB3cml0ZXIgaW5kZWZpbml0ZWx5LCB3aGlsZQorICogcHJlZmVyZW5jZSB0byB0aGUgd3JpdGVyIGNhbiByZWR1Y2UgdGhlIHBvdGVudGlhbCBmb3IgY29uY3VycmVuY3kuCisgKgorICogPGxpPkRldGVybWluaW5nIHdoZXRoZXIgdGhlIGxvY2tzIGFyZSByZWVudHJhbnQ6IGNhbiBhIHRocmVhZCB3aXRoIHRoZQorICogd3JpdGUgbG9jayByZWFjcXVpcmUgaXQ/IENhbiBpdCBhY3F1aXJlIGEgcmVhZCBsb2NrIHdoaWxlIGhvbGRpbmcgdGhlCisgKiB3cml0ZSBsb2NrPyBJcyB0aGUgcmVhZCBsb2NrIGl0c2VsZiByZWVudHJhbnQ/CisgKgorICogPGxpPkNhbiB0aGUgd3JpdGUgbG9jayBiZSBkb3duZ3JhZGVkIHRvIGEgcmVhZCBsb2NrIHdpdGhvdXQgYWxsb3dpbmcKKyAqIGFuIGludGVydmVuaW5nIHdyaXRlcj8gQ2FuIGEgcmVhZCBsb2NrIGJlIHVwZ3JhZGVkIHRvIGEgd3JpdGUgbG9jaywKKyAqIGluIHByZWZlcmVuY2UgdG8gb3RoZXIgd2FpdGluZyByZWFkZXJzIG9yIHdyaXRlcnM/CisgKgorICogPC91bD4KKyAqIFlvdSBzaG91bGQgY29uc2lkZXIgYWxsIG9mIHRoZXNlIHRoaW5ncyB3aGVuIGV2YWx1YXRpbmcgdGhlIHN1aXRhYmlsaXR5CisgKiBvZiBhIGdpdmVuIGltcGxlbWVudGF0aW9uIGZvciB5b3VyIGFwcGxpY2F0aW9uLgorICoKKyAqIEBzZWUgUmVlbnRyYW50UmVhZFdyaXRlTG9jaworICogQHNlZSBMb2NrCisgKiBAc2VlIFJlZW50cmFudExvY2sKKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUmVhZFdyaXRlTG9jayB7CisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbG9jayB1c2VkIGZvciByZWFkaW5nLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbG9jayB1c2VkIGZvciByZWFkaW5nLgorICAgICAqLworICAgIExvY2sgcmVhZExvY2soKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxvY2sgdXNlZCBmb3Igd3JpdGluZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxvY2sgdXNlZCBmb3Igd3JpdGluZy4KKyAgICAgKi8KKyAgICBMb2NrIHdyaXRlTG9jaygpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL1JlZW50cmFudExvY2suamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9sb2Nrcy9SZWVudHJhbnRMb2NrLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2Y3ODdjYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9sb2Nrcy9SZWVudHJhbnRMb2NrLmphdmEKQEAgLTAsMCArMSw3NDEgQEAKKy8qCisgKiBXcml0dGVuIGJ5IERvdWcgTGVhIHdpdGggYXNzaXN0YW5jZSBmcm9tIG1lbWJlcnMgb2YgSkNQIEpTUi0xNjYKKyAqIEV4cGVydCBHcm91cCBhbmQgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIGFzIGV4cGxhaW5lZCBhdAorICogaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvcHVibGljZG9tYWluCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuY29uY3VycmVudC5sb2NrczsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC4qOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy4qOworCisvKioKKyAqIEEgcmVlbnRyYW50IG11dHVhbCBleGNsdXNpb24ge0BsaW5rIExvY2t9IHdpdGggdGhlIHNhbWUgYmFzaWMKKyAqIGJlaGF2aW9yIGFuZCBzZW1hbnRpY3MgYXMgdGhlIGltcGxpY2l0IG1vbml0b3IgbG9jayBhY2Nlc3NlZCB1c2luZworICoge0Bjb2RlIHN5bmNocm9uaXplZH0gbWV0aG9kcyBhbmQgc3RhdGVtZW50cywgYnV0IHdpdGggZXh0ZW5kZWQKKyAqIGNhcGFiaWxpdGllcy4KKyAqCisgKiA8cD5BIHtAY29kZSBSZWVudHJhbnRMb2NrfSBpcyA8ZW0+b3duZWQ8L2VtPiBieSB0aGUgdGhyZWFkIGxhc3QKKyAqIHN1Y2Nlc3NmdWxseSBsb2NraW5nLCBidXQgbm90IHlldCB1bmxvY2tpbmcgaXQuIEEgdGhyZWFkIGludm9raW5nCisgKiB7QGNvZGUgbG9ja30gd2lsbCByZXR1cm4sIHN1Y2Nlc3NmdWxseSBhY3F1aXJpbmcgdGhlIGxvY2ssIHdoZW4KKyAqIHRoZSBsb2NrIGlzIG5vdCBvd25lZCBieSBhbm90aGVyIHRocmVhZC4gVGhlIG1ldGhvZCB3aWxsIHJldHVybgorICogaW1tZWRpYXRlbHkgaWYgdGhlIGN1cnJlbnQgdGhyZWFkIGFscmVhZHkgb3ducyB0aGUgbG9jay4gVGhpcyBjYW4KKyAqIGJlIGNoZWNrZWQgdXNpbmcgbWV0aG9kcyB7QGxpbmsgI2lzSGVsZEJ5Q3VycmVudFRocmVhZH0sIGFuZCB7QGxpbmsKKyAqICNnZXRIb2xkQ291bnR9LgorICoKKyAqIDxwPlRoZSBjb25zdHJ1Y3RvciBmb3IgdGhpcyBjbGFzcyBhY2NlcHRzIGFuIG9wdGlvbmFsCisgKiA8ZW0+ZmFpcm5lc3M8L2VtPiBwYXJhbWV0ZXIuICBXaGVuIHNldCB7QGNvZGUgdHJ1ZX0sIHVuZGVyCisgKiBjb250ZW50aW9uLCBsb2NrcyBmYXZvciBncmFudGluZyBhY2Nlc3MgdG8gdGhlIGxvbmdlc3Qtd2FpdGluZworICogdGhyZWFkLiAgT3RoZXJ3aXNlIHRoaXMgbG9jayBkb2VzIG5vdCBndWFyYW50ZWUgYW55IHBhcnRpY3VsYXIKKyAqIGFjY2VzcyBvcmRlci4gIFByb2dyYW1zIHVzaW5nIGZhaXIgbG9ja3MgYWNjZXNzZWQgYnkgbWFueSB0aHJlYWRzCisgKiBtYXkgZGlzcGxheSBsb3dlciBvdmVyYWxsIHRocm91Z2hwdXQgKGkuZS4sIGFyZSBzbG93ZXI7IG9mdGVuIG11Y2gKKyAqIHNsb3dlcikgdGhhbiB0aG9zZSB1c2luZyB0aGUgZGVmYXVsdCBzZXR0aW5nLCBidXQgaGF2ZSBzbWFsbGVyCisgKiB2YXJpYW5jZXMgaW4gdGltZXMgdG8gb2J0YWluIGxvY2tzIGFuZCBndWFyYW50ZWUgbGFjayBvZgorICogc3RhcnZhdGlvbi4gTm90ZSBob3dldmVyLCB0aGF0IGZhaXJuZXNzIG9mIGxvY2tzIGRvZXMgbm90IGd1YXJhbnRlZQorICogZmFpcm5lc3Mgb2YgdGhyZWFkIHNjaGVkdWxpbmcuIFRodXMsIG9uZSBvZiBtYW55IHRocmVhZHMgdXNpbmcgYQorICogZmFpciBsb2NrIG1heSBvYnRhaW4gaXQgbXVsdGlwbGUgdGltZXMgaW4gc3VjY2Vzc2lvbiB3aGlsZSBvdGhlcgorICogYWN0aXZlIHRocmVhZHMgYXJlIG5vdCBwcm9ncmVzc2luZyBhbmQgbm90IGN1cnJlbnRseSBob2xkaW5nIHRoZQorICogbG9jay4KKyAqIEFsc28gbm90ZSB0aGF0IHRoZSB1bnRpbWVkIHtAbGluayAjdHJ5TG9jaygpIHRyeUxvY2t9IG1ldGhvZCBkb2VzIG5vdAorICogaG9ub3IgdGhlIGZhaXJuZXNzIHNldHRpbmcuIEl0IHdpbGwgc3VjY2VlZCBpZiB0aGUgbG9jaworICogaXMgYXZhaWxhYmxlIGV2ZW4gaWYgb3RoZXIgdGhyZWFkcyBhcmUgd2FpdGluZy4KKyAqCisgKiA8cD5JdCBpcyByZWNvbW1lbmRlZCBwcmFjdGljZSB0byA8ZW0+YWx3YXlzPC9lbT4gaW1tZWRpYXRlbHkKKyAqIGZvbGxvdyBhIGNhbGwgdG8ge0Bjb2RlIGxvY2t9IHdpdGggYSB7QGNvZGUgdHJ5fSBibG9jaywgbW9zdAorICogdHlwaWNhbGx5IGluIGEgYmVmb3JlL2FmdGVyIGNvbnN0cnVjdGlvbiBzdWNoIGFzOgorICoKKyAqIDxwcmU+CisgKiBjbGFzcyBYIHsKKyAqICAgcHJpdmF0ZSBmaW5hbCBSZWVudHJhbnRMb2NrIGxvY2sgPSBuZXcgUmVlbnRyYW50TG9jaygpOworICogICAvLyAuLi4KKyAqCisgKiAgIHB1YmxpYyB2b2lkIG0oKSB7CisgKiAgICAgbG9jay5sb2NrKCk7ICAvLyBibG9jayB1bnRpbCBjb25kaXRpb24gaG9sZHMKKyAqICAgICB0cnkgeworICogICAgICAgLy8gLi4uIG1ldGhvZCBib2R5CisgKiAgICAgfSBmaW5hbGx5IHsKKyAqICAgICAgIGxvY2sudW5sb2NrKCkKKyAqICAgICB9CisgKiAgIH0KKyAqIH0KKyAqIDwvcHJlPgorICoKKyAqIDxwPkluIGFkZGl0aW9uIHRvIGltcGxlbWVudGluZyB0aGUge0BsaW5rIExvY2t9IGludGVyZmFjZSwgdGhpcworICogY2xhc3MgZGVmaW5lcyBtZXRob2RzIHtAY29kZSBpc0xvY2tlZH0gYW5kCisgKiB7QGNvZGUgZ2V0TG9ja1F1ZXVlTGVuZ3RofSwgYXMgd2VsbCBhcyBzb21lIGFzc29jaWF0ZWQKKyAqIHtAY29kZSBwcm90ZWN0ZWR9IGFjY2VzcyBtZXRob2RzIHRoYXQgbWF5IGJlIHVzZWZ1bCBmb3IKKyAqIGluc3RydW1lbnRhdGlvbiBhbmQgbW9uaXRvcmluZy4KKyAqCisgKiA8cD5TZXJpYWxpemF0aW9uIG9mIHRoaXMgY2xhc3MgYmVoYXZlcyBpbiB0aGUgc2FtZSB3YXkgYXMgYnVpbHQtaW4KKyAqIGxvY2tzOiBhIGRlc2VyaWFsaXplZCBsb2NrIGlzIGluIHRoZSB1bmxvY2tlZCBzdGF0ZSwgcmVnYXJkbGVzcyBvZgorICogaXRzIHN0YXRlIHdoZW4gc2VyaWFsaXplZC4KKyAqCisgKiA8cD5UaGlzIGxvY2sgc3VwcG9ydHMgYSBtYXhpbXVtIG9mIDIxNDc0ODM2NDcgcmVjdXJzaXZlIGxvY2tzIGJ5CisgKiB0aGUgc2FtZSB0aHJlYWQuIEF0dGVtcHRzIHRvIGV4Y2VlZCB0aGlzIGxpbWl0IHJlc3VsdCBpbgorICoge0BsaW5rIEVycm9yfSB0aHJvd3MgZnJvbSBsb2NraW5nIG1ldGhvZHMuCisgKgorICogQHNpbmNlIDEuNQorICogQGF1dGhvciBEb3VnIExlYQorICovCitwdWJsaWMgY2xhc3MgUmVlbnRyYW50TG9jayBpbXBsZW1lbnRzIExvY2ssIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3MzczOTg0ODcyNTcyNDE0Njk5TDsKKyAgICAvKiogU3luY2hyb25pemVyIHByb3ZpZGluZyBhbGwgaW1wbGVtZW50YXRpb24gbWVjaGFuaWNzICovCisgICAgcHJpdmF0ZSBmaW5hbCBTeW5jIHN5bmM7CisKKyAgICAvKioKKyAgICAgKiBCYXNlIG9mIHN5bmNocm9uaXphdGlvbiBjb250cm9sIGZvciB0aGlzIGxvY2suIFN1YmNsYXNzZWQKKyAgICAgKiBpbnRvIGZhaXIgYW5kIG5vbmZhaXIgdmVyc2lvbnMgYmVsb3cuIFVzZXMgQVFTIHN0YXRlIHRvCisgICAgICogcmVwcmVzZW50IHRoZSBudW1iZXIgb2YgaG9sZHMgb24gdGhlIGxvY2suCisgICAgICovCisgICAgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIFN5bmMgZXh0ZW5kcyBBYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplciB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC01MTc5NTIzNzYyMDM0MDI1ODYwTDsKKworICAgICAgICAvKioKKyAgICAgICAgICogUGVyZm9ybXMge0BsaW5rIExvY2sjbG9ja30uIFRoZSBtYWluIHJlYXNvbiBmb3Igc3ViY2xhc3NpbmcKKyAgICAgICAgICogaXMgdG8gYWxsb3cgZmFzdCBwYXRoIGZvciBub25mYWlyIHZlcnNpb24uCisgICAgICAgICAqLworICAgICAgICBhYnN0cmFjdCB2b2lkIGxvY2soKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogUGVyZm9ybXMgbm9uLWZhaXIgdHJ5TG9jay4gIHRyeUFjcXVpcmUgaXMKKyAgICAgICAgICogaW1wbGVtZW50ZWQgaW4gc3ViY2xhc3NlcywgYnV0IGJvdGggbmVlZCBub25mYWlyCisgICAgICAgICAqIHRyeSBmb3IgdHJ5bG9jayBtZXRob2QuCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBib29sZWFuIG5vbmZhaXJUcnlBY3F1aXJlKGludCBhY3F1aXJlcykgeworICAgICAgICAgICAgZmluYWwgVGhyZWFkIGN1cnJlbnQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICAgICAgaW50IGMgPSBnZXRTdGF0ZSgpOworICAgICAgICAgICAgaWYgKGMgPT0gMCkgeworICAgICAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0U3RhdGUoMCwgYWNxdWlyZXMpKSB7CisgICAgICAgICAgICAgICAgICAgIHNldEV4Y2x1c2l2ZU93bmVyVGhyZWFkKGN1cnJlbnQpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIGlmIChjdXJyZW50ID09IGdldEV4Y2x1c2l2ZU93bmVyVGhyZWFkKCkpIHsKKyAgICAgICAgICAgICAgICBpbnQgbmV4dGMgPSBjICsgYWNxdWlyZXM7CisgICAgICAgICAgICAgICAgaWYgKG5leHRjIDwgMCkgLy8gb3ZlcmZsb3cKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJNYXhpbXVtIGxvY2sgY291bnQgZXhjZWVkZWQiKTsKKyAgICAgICAgICAgICAgICBzZXRTdGF0ZShuZXh0Yyk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiB0cnlSZWxlYXNlKGludCByZWxlYXNlcykgeworICAgICAgICAgICAgaW50IGMgPSBnZXRTdGF0ZSgpIC0gcmVsZWFzZXM7CisgICAgICAgICAgICBpZiAoVGhyZWFkLmN1cnJlbnRUaHJlYWQoKSAhPSBnZXRFeGNsdXNpdmVPd25lclRocmVhZCgpKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBib29sZWFuIGZyZWUgPSBmYWxzZTsKKyAgICAgICAgICAgIGlmIChjID09IDApIHsKKyAgICAgICAgICAgICAgICBmcmVlID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBzZXRFeGNsdXNpdmVPd25lclRocmVhZChudWxsKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNldFN0YXRlKGMpOworICAgICAgICAgICAgcmV0dXJuIGZyZWU7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiBpc0hlbGRFeGNsdXNpdmVseSgpIHsKKyAgICAgICAgICAgIC8vIFdoaWxlIHdlIG11c3QgaW4gZ2VuZXJhbCByZWFkIHN0YXRlIGJlZm9yZSBvd25lciwKKyAgICAgICAgICAgIC8vIHdlIGRvbid0IG5lZWQgdG8gZG8gc28gdG8gY2hlY2sgaWYgY3VycmVudCB0aHJlYWQgaXMgb3duZXIKKyAgICAgICAgICAgIHJldHVybiBnZXRFeGNsdXNpdmVPd25lclRocmVhZCgpID09IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBDb25kaXRpb25PYmplY3QgbmV3Q29uZGl0aW9uKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBDb25kaXRpb25PYmplY3QoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIE1ldGhvZHMgcmVsYXllZCBmcm9tIG91dGVyIGNsYXNzCisKKyAgICAgICAgZmluYWwgVGhyZWFkIGdldE93bmVyKCkgeworICAgICAgICAgICAgcmV0dXJuIGdldFN0YXRlKCkgPT0gMCA/IG51bGwgOiBnZXRFeGNsdXNpdmVPd25lclRocmVhZCgpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgaW50IGdldEhvbGRDb3VudCgpIHsKKyAgICAgICAgICAgIHJldHVybiBpc0hlbGRFeGNsdXNpdmVseSgpID8gZ2V0U3RhdGUoKSA6IDA7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBib29sZWFuIGlzTG9ja2VkKCkgeworICAgICAgICAgICAgcmV0dXJuIGdldFN0YXRlKCkgIT0gMDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZWNvbnN0aXR1dGVzIHRoaXMgbG9jayBpbnN0YW5jZSBmcm9tIGEgc3RyZWFtLgorICAgICAgICAgKiBAcGFyYW0gcyB0aGUgc3RyZWFtCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtIHMpCisgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisgICAgICAgICAgICBzZXRTdGF0ZSgwKTsgLy8gcmVzZXQgdG8gdW5sb2NrZWQgc3RhdGUKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFN5bmMgb2JqZWN0IGZvciBub24tZmFpciBsb2NrcworICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBOb25mYWlyU3luYyBleHRlbmRzIFN5bmMgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3MzE2MTUzNTYzNzgyODIzNjkxTDsKKworICAgICAgICAvKioKKyAgICAgICAgICogUGVyZm9ybXMgbG9jay4gIFRyeSBpbW1lZGlhdGUgYmFyZ2UsIGJhY2tpbmcgdXAgdG8gbm9ybWFsCisgICAgICAgICAqIGFjcXVpcmUgb24gZmFpbHVyZS4KKyAgICAgICAgICovCisgICAgICAgIGZpbmFsIHZvaWQgbG9jaygpIHsKKyAgICAgICAgICAgIGlmIChjb21wYXJlQW5kU2V0U3RhdGUoMCwgMSkpCisgICAgICAgICAgICAgICAgc2V0RXhjbHVzaXZlT3duZXJUaHJlYWQoVGhyZWFkLmN1cnJlbnRUaHJlYWQoKSk7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgYWNxdWlyZSgxKTsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIHRyeUFjcXVpcmUoaW50IGFjcXVpcmVzKSB7CisgICAgICAgICAgICByZXR1cm4gbm9uZmFpclRyeUFjcXVpcmUoYWNxdWlyZXMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU3luYyBvYmplY3QgZm9yIGZhaXIgbG9ja3MKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgY2xhc3MgRmFpclN5bmMgZXh0ZW5kcyBTeW5jIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTMwMDA4OTc4OTcwOTA0NjY1NDBMOworCisgICAgICAgIGZpbmFsIHZvaWQgbG9jaygpIHsKKyAgICAgICAgICAgIGFjcXVpcmUoMSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogRmFpciB2ZXJzaW9uIG9mIHRyeUFjcXVpcmUuICBEb24ndCBncmFudCBhY2Nlc3MgdW5sZXNzCisgICAgICAgICAqIHJlY3Vyc2l2ZSBjYWxsIG9yIG5vIHdhaXRlcnMgb3IgaXMgZmlyc3QuCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiB0cnlBY3F1aXJlKGludCBhY3F1aXJlcykgeworICAgICAgICAgICAgZmluYWwgVGhyZWFkIGN1cnJlbnQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICAgICAgaW50IGMgPSBnZXRTdGF0ZSgpOworICAgICAgICAgICAgaWYgKGMgPT0gMCkgeworICAgICAgICAgICAgICAgIGlmICghaGFzUXVldWVkUHJlZGVjZXNzb3JzKCkgJiYKKyAgICAgICAgICAgICAgICAgICAgY29tcGFyZUFuZFNldFN0YXRlKDAsIGFjcXVpcmVzKSkgeworICAgICAgICAgICAgICAgICAgICBzZXRFeGNsdXNpdmVPd25lclRocmVhZChjdXJyZW50KTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSBpZiAoY3VycmVudCA9PSBnZXRFeGNsdXNpdmVPd25lclRocmVhZCgpKSB7CisgICAgICAgICAgICAgICAgaW50IG5leHRjID0gYyArIGFjcXVpcmVzOworICAgICAgICAgICAgICAgIGlmIChuZXh0YyA8IDApCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiTWF4aW11bSBsb2NrIGNvdW50IGV4Y2VlZGVkIik7CisgICAgICAgICAgICAgICAgc2V0U3RhdGUobmV4dGMpOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgUmVlbnRyYW50TG9ja30uCisgICAgICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIHVzaW5nIHtAY29kZSBSZWVudHJhbnRMb2NrKGZhbHNlKX0uCisgICAgICovCisgICAgcHVibGljIFJlZW50cmFudExvY2soKSB7CisgICAgICAgIHN5bmMgPSBuZXcgTm9uZmFpclN5bmMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIHtAY29kZSBSZWVudHJhbnRMb2NrfSB3aXRoIHRoZQorICAgICAqIGdpdmVuIGZhaXJuZXNzIHBvbGljeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmYWlyIHtAY29kZSB0cnVlfSBpZiB0aGlzIGxvY2sgc2hvdWxkIHVzZSBhIGZhaXIgb3JkZXJpbmcgcG9saWN5CisgICAgICovCisgICAgcHVibGljIFJlZW50cmFudExvY2soYm9vbGVhbiBmYWlyKSB7CisgICAgICAgIHN5bmMgPSBmYWlyID8gbmV3IEZhaXJTeW5jKCkgOiBuZXcgTm9uZmFpclN5bmMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBY3F1aXJlcyB0aGUgbG9jay4KKyAgICAgKgorICAgICAqIDxwPkFjcXVpcmVzIHRoZSBsb2NrIGlmIGl0IGlzIG5vdCBoZWxkIGJ5IGFub3RoZXIgdGhyZWFkIGFuZCByZXR1cm5zCisgICAgICogaW1tZWRpYXRlbHksIHNldHRpbmcgdGhlIGxvY2sgaG9sZCBjb3VudCB0byBvbmUuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgY3VycmVudCB0aHJlYWQgYWxyZWFkeSBob2xkcyB0aGUgbG9jayB0aGVuIHRoZSBob2xkCisgICAgICogY291bnQgaXMgaW5jcmVtZW50ZWQgYnkgb25lIGFuZCB0aGUgbWV0aG9kIHJldHVybnMgaW1tZWRpYXRlbHkuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgbG9jayBpcyBoZWxkIGJ5IGFub3RoZXIgdGhyZWFkIHRoZW4gdGhlCisgICAgICogY3VycmVudCB0aHJlYWQgYmVjb21lcyBkaXNhYmxlZCBmb3IgdGhyZWFkIHNjaGVkdWxpbmcKKyAgICAgKiBwdXJwb3NlcyBhbmQgbGllcyBkb3JtYW50IHVudGlsIHRoZSBsb2NrIGhhcyBiZWVuIGFjcXVpcmVkLAorICAgICAqIGF0IHdoaWNoIHRpbWUgdGhlIGxvY2sgaG9sZCBjb3VudCBpcyBzZXQgdG8gb25lLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvY2soKSB7CisgICAgICAgIHN5bmMubG9jaygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFjcXVpcmVzIHRoZSBsb2NrIHVubGVzcyB0aGUgY3VycmVudCB0aHJlYWQgaXMKKyAgICAgKiB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfS4KKyAgICAgKgorICAgICAqIDxwPkFjcXVpcmVzIHRoZSBsb2NrIGlmIGl0IGlzIG5vdCBoZWxkIGJ5IGFub3RoZXIgdGhyZWFkIGFuZCByZXR1cm5zCisgICAgICogaW1tZWRpYXRlbHksIHNldHRpbmcgdGhlIGxvY2sgaG9sZCBjb3VudCB0byBvbmUuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgY3VycmVudCB0aHJlYWQgYWxyZWFkeSBob2xkcyB0aGlzIGxvY2sgdGhlbiB0aGUgaG9sZCBjb3VudAorICAgICAqIGlzIGluY3JlbWVudGVkIGJ5IG9uZSBhbmQgdGhlIG1ldGhvZCByZXR1cm5zIGltbWVkaWF0ZWx5LgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGxvY2sgaXMgaGVsZCBieSBhbm90aGVyIHRocmVhZCB0aGVuIHRoZQorICAgICAqIGN1cnJlbnQgdGhyZWFkIGJlY29tZXMgZGlzYWJsZWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nCisgICAgICogcHVycG9zZXMgYW5kIGxpZXMgZG9ybWFudCB1bnRpbCBvbmUgb2YgdHdvIHRoaW5ncyBoYXBwZW5zOgorICAgICAqCisgICAgICogPHVsPgorICAgICAqCisgICAgICogPGxpPlRoZSBsb2NrIGlzIGFjcXVpcmVkIGJ5IHRoZSBjdXJyZW50IHRocmVhZDsgb3IKKyAgICAgKgorICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdHN9IHRoZQorICAgICAqIGN1cnJlbnQgdGhyZWFkLgorICAgICAqCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBsb2NrIGlzIGFjcXVpcmVkIGJ5IHRoZSBjdXJyZW50IHRocmVhZCB0aGVuIHRoZSBsb2NrIGhvbGQKKyAgICAgKiBjb3VudCBpcyBzZXQgdG8gb25lLgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGN1cnJlbnQgdGhyZWFkOgorICAgICAqCisgICAgICogPHVsPgorICAgICAqCisgICAgICogPGxpPmhhcyBpdHMgaW50ZXJydXB0ZWQgc3RhdHVzIHNldCBvbiBlbnRyeSB0byB0aGlzIG1ldGhvZDsgb3IKKyAgICAgKgorICAgICAqIDxsaT5pcyB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfSB3aGlsZSBhY3F1aXJpbmcKKyAgICAgKiB0aGUgbG9jaywKKyAgICAgKgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiB0aGVuIHtAbGluayBJbnRlcnJ1cHRlZEV4Y2VwdGlvbn0gaXMgdGhyb3duIGFuZCB0aGUgY3VycmVudCB0aHJlYWQncworICAgICAqIGludGVycnVwdGVkIHN0YXR1cyBpcyBjbGVhcmVkLgorICAgICAqCisgICAgICogPHA+SW4gdGhpcyBpbXBsZW1lbnRhdGlvbiwgYXMgdGhpcyBtZXRob2QgaXMgYW4gZXhwbGljaXQKKyAgICAgKiBpbnRlcnJ1cHRpb24gcG9pbnQsIHByZWZlcmVuY2UgaXMgZ2l2ZW4gdG8gcmVzcG9uZGluZyB0byB0aGUKKyAgICAgKiBpbnRlcnJ1cHQgb3ZlciBub3JtYWwgb3IgcmVlbnRyYW50IGFjcXVpc2l0aW9uIG9mIHRoZSBsb2NrLgorICAgICAqCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCB0aHJlYWQgaXMgaW50ZXJydXB0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBsb2NrSW50ZXJydXB0aWJseSgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHN5bmMuYWNxdWlyZUludGVycnVwdGlibHkoMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWNxdWlyZXMgdGhlIGxvY2sgb25seSBpZiBpdCBpcyBub3QgaGVsZCBieSBhbm90aGVyIHRocmVhZCBhdCB0aGUgdGltZQorICAgICAqIG9mIGludm9jYXRpb24uCisgICAgICoKKyAgICAgKiA8cD5BY3F1aXJlcyB0aGUgbG9jayBpZiBpdCBpcyBub3QgaGVsZCBieSBhbm90aGVyIHRocmVhZCBhbmQKKyAgICAgKiByZXR1cm5zIGltbWVkaWF0ZWx5IHdpdGggdGhlIHZhbHVlIHtAY29kZSB0cnVlfSwgc2V0dGluZyB0aGUKKyAgICAgKiBsb2NrIGhvbGQgY291bnQgdG8gb25lLiBFdmVuIHdoZW4gdGhpcyBsb2NrIGhhcyBiZWVuIHNldCB0byB1c2UgYQorICAgICAqIGZhaXIgb3JkZXJpbmcgcG9saWN5LCBhIGNhbGwgdG8ge0Bjb2RlIHRyeUxvY2soKX0gPGVtPndpbGw8L2VtPgorICAgICAqIGltbWVkaWF0ZWx5IGFjcXVpcmUgdGhlIGxvY2sgaWYgaXQgaXMgYXZhaWxhYmxlLCB3aGV0aGVyIG9yIG5vdAorICAgICAqIG90aGVyIHRocmVhZHMgYXJlIGN1cnJlbnRseSB3YWl0aW5nIGZvciB0aGUgbG9jay4KKyAgICAgKiBUaGlzICZxdW90O2JhcmdpbmcmcXVvdDsgYmVoYXZpb3IgY2FuIGJlIHVzZWZ1bCBpbiBjZXJ0YWluCisgICAgICogY2lyY3Vtc3RhbmNlcywgZXZlbiB0aG91Z2ggaXQgYnJlYWtzIGZhaXJuZXNzLiBJZiB5b3Ugd2FudCB0byBob25vcgorICAgICAqIHRoZSBmYWlybmVzcyBzZXR0aW5nIGZvciB0aGlzIGxvY2ssIHRoZW4gdXNlCisgICAgICoge0BsaW5rICN0cnlMb2NrKGxvbmcsIFRpbWVVbml0KSB0cnlMb2NrKDAsIFRpbWVVbml0LlNFQ09ORFMpIH0KKyAgICAgKiB3aGljaCBpcyBhbG1vc3QgZXF1aXZhbGVudCAoaXQgYWxzbyBkZXRlY3RzIGludGVycnVwdGlvbikuCisgICAgICoKKyAgICAgKiA8cD4gSWYgdGhlIGN1cnJlbnQgdGhyZWFkIGFscmVhZHkgaG9sZHMgdGhpcyBsb2NrIHRoZW4gdGhlIGhvbGQKKyAgICAgKiBjb3VudCBpcyBpbmNyZW1lbnRlZCBieSBvbmUgYW5kIHRoZSBtZXRob2QgcmV0dXJucyB7QGNvZGUgdHJ1ZX0uCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgbG9jayBpcyBoZWxkIGJ5IGFub3RoZXIgdGhyZWFkIHRoZW4gdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4KKyAgICAgKiBpbW1lZGlhdGVseSB3aXRoIHRoZSB2YWx1ZSB7QGNvZGUgZmFsc2V9LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGxvY2sgd2FzIGZyZWUgYW5kIHdhcyBhY3F1aXJlZCBieSB0aGUKKyAgICAgKiAgICAgICAgIGN1cnJlbnQgdGhyZWFkLCBvciB0aGUgbG9jayB3YXMgYWxyZWFkeSBoZWxkIGJ5IHRoZSBjdXJyZW50CisgICAgICogICAgICAgICB0aHJlYWQ7IGFuZCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHRyeUxvY2soKSB7CisgICAgICAgIHJldHVybiBzeW5jLm5vbmZhaXJUcnlBY3F1aXJlKDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFjcXVpcmVzIHRoZSBsb2NrIGlmIGl0IGlzIG5vdCBoZWxkIGJ5IGFub3RoZXIgdGhyZWFkIHdpdGhpbiB0aGUgZ2l2ZW4KKyAgICAgKiB3YWl0aW5nIHRpbWUgYW5kIHRoZSBjdXJyZW50IHRocmVhZCBoYXMgbm90IGJlZW4KKyAgICAgKiB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfS4KKyAgICAgKgorICAgICAqIDxwPkFjcXVpcmVzIHRoZSBsb2NrIGlmIGl0IGlzIG5vdCBoZWxkIGJ5IGFub3RoZXIgdGhyZWFkIGFuZCByZXR1cm5zCisgICAgICogaW1tZWRpYXRlbHkgd2l0aCB0aGUgdmFsdWUge0Bjb2RlIHRydWV9LCBzZXR0aW5nIHRoZSBsb2NrIGhvbGQgY291bnQKKyAgICAgKiB0byBvbmUuIElmIHRoaXMgbG9jayBoYXMgYmVlbiBzZXQgdG8gdXNlIGEgZmFpciBvcmRlcmluZyBwb2xpY3kgdGhlbgorICAgICAqIGFuIGF2YWlsYWJsZSBsb2NrIDxlbT53aWxsIG5vdDwvZW0+IGJlIGFjcXVpcmVkIGlmIGFueSBvdGhlciB0aHJlYWRzCisgICAgICogYXJlIHdhaXRpbmcgZm9yIHRoZSBsb2NrLiBUaGlzIGlzIGluIGNvbnRyYXN0IHRvIHRoZSB7QGxpbmsgI3RyeUxvY2soKX0KKyAgICAgKiBtZXRob2QuIElmIHlvdSB3YW50IGEgdGltZWQge0Bjb2RlIHRyeUxvY2t9IHRoYXQgZG9lcyBwZXJtaXQgYmFyZ2luZyBvbgorICAgICAqIGEgZmFpciBsb2NrIHRoZW4gY29tYmluZSB0aGUgdGltZWQgYW5kIHVuLXRpbWVkIGZvcm1zIHRvZ2V0aGVyOgorICAgICAqCisgICAgICogPHByZT5pZiAobG9jay50cnlMb2NrKCkgfHwgbG9jay50cnlMb2NrKHRpbWVvdXQsIHVuaXQpICkgeyAuLi4gfQorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGN1cnJlbnQgdGhyZWFkCisgICAgICogYWxyZWFkeSBob2xkcyB0aGlzIGxvY2sgdGhlbiB0aGUgaG9sZCBjb3VudCBpcyBpbmNyZW1lbnRlZCBieSBvbmUgYW5kCisgICAgICogdGhlIG1ldGhvZCByZXR1cm5zIHtAY29kZSB0cnVlfS4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBsb2NrIGlzIGhlbGQgYnkgYW5vdGhlciB0aHJlYWQgdGhlbiB0aGUKKyAgICAgKiBjdXJyZW50IHRocmVhZCBiZWNvbWVzIGRpc2FibGVkIGZvciB0aHJlYWQgc2NoZWR1bGluZworICAgICAqIHB1cnBvc2VzIGFuZCBsaWVzIGRvcm1hbnQgdW50aWwgb25lIG9mIHRocmVlIHRoaW5ncyBoYXBwZW5zOgorICAgICAqCisgICAgICogPHVsPgorICAgICAqCisgICAgICogPGxpPlRoZSBsb2NrIGlzIGFjcXVpcmVkIGJ5IHRoZSBjdXJyZW50IHRocmVhZDsgb3IKKyAgICAgKgorICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdHN9CisgICAgICogdGhlIGN1cnJlbnQgdGhyZWFkOyBvcgorICAgICAqCisgICAgICogPGxpPlRoZSBzcGVjaWZpZWQgd2FpdGluZyB0aW1lIGVsYXBzZXMKKyAgICAgKgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgbG9jayBpcyBhY3F1aXJlZCB0aGVuIHRoZSB2YWx1ZSB7QGNvZGUgdHJ1ZX0gaXMgcmV0dXJuZWQgYW5kCisgICAgICogdGhlIGxvY2sgaG9sZCBjb3VudCBpcyBzZXQgdG8gb25lLgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGN1cnJlbnQgdGhyZWFkOgorICAgICAqCisgICAgICogPHVsPgorICAgICAqCisgICAgICogPGxpPmhhcyBpdHMgaW50ZXJydXB0ZWQgc3RhdHVzIHNldCBvbiBlbnRyeSB0byB0aGlzIG1ldGhvZDsgb3IKKyAgICAgKgorICAgICAqIDxsaT5pcyB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfSB3aGlsZQorICAgICAqIGFjcXVpcmluZyB0aGUgbG9jaywKKyAgICAgKgorICAgICAqIDwvdWw+CisgICAgICogdGhlbiB7QGxpbmsgSW50ZXJydXB0ZWRFeGNlcHRpb259IGlzIHRocm93biBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkJ3MKKyAgICAgKiBpbnRlcnJ1cHRlZCBzdGF0dXMgaXMgY2xlYXJlZC4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBzcGVjaWZpZWQgd2FpdGluZyB0aW1lIGVsYXBzZXMgdGhlbiB0aGUgdmFsdWUge0Bjb2RlIGZhbHNlfQorICAgICAqIGlzIHJldHVybmVkLiAgSWYgdGhlIHRpbWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHplcm8sIHRoZSBtZXRob2QKKyAgICAgKiB3aWxsIG5vdCB3YWl0IGF0IGFsbC4KKyAgICAgKgorICAgICAqIDxwPkluIHRoaXMgaW1wbGVtZW50YXRpb24sIGFzIHRoaXMgbWV0aG9kIGlzIGFuIGV4cGxpY2l0CisgICAgICogaW50ZXJydXB0aW9uIHBvaW50LCBwcmVmZXJlbmNlIGlzIGdpdmVuIHRvIHJlc3BvbmRpbmcgdG8gdGhlCisgICAgICogaW50ZXJydXB0IG92ZXIgbm9ybWFsIG9yIHJlZW50cmFudCBhY3F1aXNpdGlvbiBvZiB0aGUgbG9jaywgYW5kCisgICAgICogb3ZlciByZXBvcnRpbmcgdGhlIGVsYXBzZSBvZiB0aGUgd2FpdGluZyB0aW1lLgorICAgICAqCisgICAgICogQHBhcmFtIHRpbWVvdXQgdGhlIHRpbWUgdG8gd2FpdCBmb3IgdGhlIGxvY2sKKyAgICAgKiBAcGFyYW0gdW5pdCB0aGUgdGltZSB1bml0IG9mIHRoZSB0aW1lb3V0IGFyZ3VtZW50CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGxvY2sgd2FzIGZyZWUgYW5kIHdhcyBhY3F1aXJlZCBieSB0aGUKKyAgICAgKiAgICAgICAgIGN1cnJlbnQgdGhyZWFkLCBvciB0aGUgbG9jayB3YXMgYWxyZWFkeSBoZWxkIGJ5IHRoZSBjdXJyZW50CisgICAgICogICAgICAgICB0aHJlYWQ7IGFuZCB7QGNvZGUgZmFsc2V9IGlmIHRoZSB3YWl0aW5nIHRpbWUgZWxhcHNlZCBiZWZvcmUKKyAgICAgKiAgICAgICAgIHRoZSBsb2NrIGNvdWxkIGJlIGFjcXVpcmVkCisgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCB0aHJlYWQgaXMgaW50ZXJydXB0ZWQKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSB0aW1lIHVuaXQgaXMgbnVsbAorICAgICAqCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gdHJ5TG9jayhsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpCisgICAgICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc3luYy50cnlBY3F1aXJlTmFub3MoMSwgdW5pdC50b05hbm9zKHRpbWVvdXQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdHRlbXB0cyB0byByZWxlYXNlIHRoaXMgbG9jay4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBjdXJyZW50IHRocmVhZCBpcyB0aGUgaG9sZGVyIG9mIHRoaXMgbG9jayB0aGVuIHRoZSBob2xkCisgICAgICogY291bnQgaXMgZGVjcmVtZW50ZWQuICBJZiB0aGUgaG9sZCBjb3VudCBpcyBub3cgemVybyB0aGVuIHRoZSBsb2NrCisgICAgICogaXMgcmVsZWFzZWQuICBJZiB0aGUgY3VycmVudCB0aHJlYWQgaXMgbm90IHRoZSBob2xkZXIgb2YgdGhpcworICAgICAqIGxvY2sgdGhlbiB7QGxpbmsgSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbn0gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IHRocmVhZCBkb2VzIG5vdAorICAgICAqICAgICAgICAgaG9sZCB0aGlzIGxvY2sKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1bmxvY2soKSB7CisgICAgICAgIHN5bmMucmVsZWFzZSgxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0BsaW5rIENvbmRpdGlvbn0gaW5zdGFuY2UgZm9yIHVzZSB3aXRoIHRoaXMKKyAgICAgKiB7QGxpbmsgTG9ja30gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQge0BsaW5rIENvbmRpdGlvbn0gaW5zdGFuY2Ugc3VwcG9ydHMgdGhlIHNhbWUKKyAgICAgKiB1c2FnZXMgYXMgZG8gdGhlIHtAbGluayBPYmplY3R9IG1vbml0b3IgbWV0aG9kcyAoe0BsaW5rCisgICAgICogT2JqZWN0I3dhaXQoKSB3YWl0fSwge0BsaW5rIE9iamVjdCNub3RpZnkgbm90aWZ5fSwgYW5kIHtAbGluaworICAgICAqIE9iamVjdCNub3RpZnlBbGwgbm90aWZ5QWxsfSkgd2hlbiB1c2VkIHdpdGggdGhlIGJ1aWx0LWluCisgICAgICogbW9uaXRvciBsb2NrLgorICAgICAqCisgICAgICogPHVsPgorICAgICAqCisgICAgICogPGxpPklmIHRoaXMgbG9jayBpcyBub3QgaGVsZCB3aGVuIGFueSBvZiB0aGUge0BsaW5rIENvbmRpdGlvbn0KKyAgICAgKiB7QGxpbmtwbGFpbiBDb25kaXRpb24jYXdhaXQoKSB3YWl0aW5nfSBvciB7QGxpbmtwbGFpbgorICAgICAqIENvbmRpdGlvbiNzaWduYWwgc2lnbmFsbGluZ30gbWV0aG9kcyBhcmUgY2FsbGVkLCB0aGVuIGFuIHtAbGluaworICAgICAqIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb259IGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIDxsaT5XaGVuIHRoZSBjb25kaXRpb24ge0BsaW5rcGxhaW4gQ29uZGl0aW9uI2F3YWl0KCkgd2FpdGluZ30KKyAgICAgKiBtZXRob2RzIGFyZSBjYWxsZWQgdGhlIGxvY2sgaXMgcmVsZWFzZWQgYW5kLCBiZWZvcmUgdGhleQorICAgICAqIHJldHVybiwgdGhlIGxvY2sgaXMgcmVhY3F1aXJlZCBhbmQgdGhlIGxvY2sgaG9sZCBjb3VudCByZXN0b3JlZAorICAgICAqIHRvIHdoYXQgaXQgd2FzIHdoZW4gdGhlIG1ldGhvZCB3YXMgY2FsbGVkLgorICAgICAqCisgICAgICogPGxpPklmIGEgdGhyZWFkIGlzIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0ZWR9CisgICAgICogd2hpbGUgd2FpdGluZyB0aGVuIHRoZSB3YWl0IHdpbGwgdGVybWluYXRlLCBhbiB7QGxpbmsKKyAgICAgKiBJbnRlcnJ1cHRlZEV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24sIGFuZCB0aGUgdGhyZWFkJ3MKKyAgICAgKiBpbnRlcnJ1cHRlZCBzdGF0dXMgd2lsbCBiZSBjbGVhcmVkLgorICAgICAqCisgICAgICogPGxpPiBXYWl0aW5nIHRocmVhZHMgYXJlIHNpZ25hbGxlZCBpbiBGSUZPIG9yZGVyLgorICAgICAqCisgICAgICogPGxpPlRoZSBvcmRlcmluZyBvZiBsb2NrIHJlYWNxdWlzaXRpb24gZm9yIHRocmVhZHMgcmV0dXJuaW5nCisgICAgICogZnJvbSB3YWl0aW5nIG1ldGhvZHMgaXMgdGhlIHNhbWUgYXMgZm9yIHRocmVhZHMgaW5pdGlhbGx5CisgICAgICogYWNxdWlyaW5nIHRoZSBsb2NrLCB3aGljaCBpcyBpbiB0aGUgZGVmYXVsdCBjYXNlIG5vdCBzcGVjaWZpZWQsCisgICAgICogYnV0IGZvciA8ZW0+ZmFpcjwvZW0+IGxvY2tzIGZhdm9ycyB0aG9zZSB0aHJlYWRzIHRoYXQgaGF2ZSBiZWVuCisgICAgICogd2FpdGluZyB0aGUgbG9uZ2VzdC4KKyAgICAgKgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBDb25kaXRpb24gb2JqZWN0CisgICAgICovCisgICAgcHVibGljIENvbmRpdGlvbiBuZXdDb25kaXRpb24oKSB7CisgICAgICAgIHJldHVybiBzeW5jLm5ld0NvbmRpdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFF1ZXJpZXMgdGhlIG51bWJlciBvZiBob2xkcyBvbiB0aGlzIGxvY2sgYnkgdGhlIGN1cnJlbnQgdGhyZWFkLgorICAgICAqCisgICAgICogPHA+QSB0aHJlYWQgaGFzIGEgaG9sZCBvbiBhIGxvY2sgZm9yIGVhY2ggbG9jayBhY3Rpb24gdGhhdCBpcyBub3QKKyAgICAgKiBtYXRjaGVkIGJ5IGFuIHVubG9jayBhY3Rpb24uCisgICAgICoKKyAgICAgKiA8cD5UaGUgaG9sZCBjb3VudCBpbmZvcm1hdGlvbiBpcyB0eXBpY2FsbHkgb25seSB1c2VkIGZvciB0ZXN0aW5nIGFuZAorICAgICAqIGRlYnVnZ2luZyBwdXJwb3Nlcy4gRm9yIGV4YW1wbGUsIGlmIGEgY2VydGFpbiBzZWN0aW9uIG9mIGNvZGUgc2hvdWxkCisgICAgICogbm90IGJlIGVudGVyZWQgd2l0aCB0aGUgbG9jayBhbHJlYWR5IGhlbGQgdGhlbiB3ZSBjYW4gYXNzZXJ0IHRoYXQKKyAgICAgKiBmYWN0OgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiBjbGFzcyBYIHsKKyAgICAgKiAgIFJlZW50cmFudExvY2sgbG9jayA9IG5ldyBSZWVudHJhbnRMb2NrKCk7CisgICAgICogICAvLyAuLi4KKyAgICAgKiAgIHB1YmxpYyB2b2lkIG0oKSB7CisgICAgICogICAgIGFzc2VydCBsb2NrLmdldEhvbGRDb3VudCgpID09IDA7CisgICAgICogICAgIGxvY2subG9jaygpOworICAgICAqICAgICB0cnkgeworICAgICAqICAgICAgIC8vIC4uLiBtZXRob2QgYm9keQorICAgICAqICAgICB9IGZpbmFsbHkgeworICAgICAqICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICogICAgIH0KKyAgICAgKiAgIH0KKyAgICAgKiB9CisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgaG9sZHMgb24gdGhpcyBsb2NrIGJ5IHRoZSBjdXJyZW50IHRocmVhZCwKKyAgICAgKiAgICAgICAgIG9yIHplcm8gaWYgdGhpcyBsb2NrIGlzIG5vdCBoZWxkIGJ5IHRoZSBjdXJyZW50IHRocmVhZAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SG9sZENvdW50KCkgeworICAgICAgICByZXR1cm4gc3luYy5nZXRIb2xkQ291bnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBRdWVyaWVzIGlmIHRoaXMgbG9jayBpcyBoZWxkIGJ5IHRoZSBjdXJyZW50IHRocmVhZC4KKyAgICAgKgorICAgICAqIDxwPkFuYWxvZ291cyB0byB0aGUge0BsaW5rIFRocmVhZCNob2xkc0xvY2t9IG1ldGhvZCBmb3IgYnVpbHQtaW4KKyAgICAgKiBtb25pdG9yIGxvY2tzLCB0aGlzIG1ldGhvZCBpcyB0eXBpY2FsbHkgdXNlZCBmb3IgZGVidWdnaW5nIGFuZAorICAgICAqIHRlc3RpbmcuIEZvciBleGFtcGxlLCBhIG1ldGhvZCB0aGF0IHNob3VsZCBvbmx5IGJlIGNhbGxlZCB3aGlsZQorICAgICAqIGEgbG9jayBpcyBoZWxkIGNhbiBhc3NlcnQgdGhhdCB0aGlzIGlzIHRoZSBjYXNlOgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiBjbGFzcyBYIHsKKyAgICAgKiAgIFJlZW50cmFudExvY2sgbG9jayA9IG5ldyBSZWVudHJhbnRMb2NrKCk7CisgICAgICogICAvLyAuLi4KKyAgICAgKgorICAgICAqICAgcHVibGljIHZvaWQgbSgpIHsKKyAgICAgKiAgICAgICBhc3NlcnQgbG9jay5pc0hlbGRCeUN1cnJlbnRUaHJlYWQoKTsKKyAgICAgKiAgICAgICAvLyAuLi4gbWV0aG9kIGJvZHkKKyAgICAgKiAgIH0KKyAgICAgKiB9CisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiA8cD5JdCBjYW4gYWxzbyBiZSB1c2VkIHRvIGVuc3VyZSB0aGF0IGEgcmVlbnRyYW50IGxvY2sgaXMgdXNlZAorICAgICAqIGluIGEgbm9uLXJlZW50cmFudCBtYW5uZXIsIGZvciBleGFtcGxlOgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiBjbGFzcyBYIHsKKyAgICAgKiAgIFJlZW50cmFudExvY2sgbG9jayA9IG5ldyBSZWVudHJhbnRMb2NrKCk7CisgICAgICogICAvLyAuLi4KKyAgICAgKgorICAgICAqICAgcHVibGljIHZvaWQgbSgpIHsKKyAgICAgKiAgICAgICBhc3NlcnQgIWxvY2suaXNIZWxkQnlDdXJyZW50VGhyZWFkKCk7CisgICAgICogICAgICAgbG9jay5sb2NrKCk7CisgICAgICogICAgICAgdHJ5IHsKKyAgICAgKiAgICAgICAgICAgLy8gLi4uIG1ldGhvZCBib2R5CisgICAgICogICAgICAgfSBmaW5hbGx5IHsKKyAgICAgKiAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgKiAgICAgICB9CisgICAgICogICB9CisgICAgICogfQorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgY3VycmVudCB0aHJlYWQgaG9sZHMgdGhpcyBsb2NrIGFuZAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0hlbGRCeUN1cnJlbnRUaHJlYWQoKSB7CisgICAgICAgIHJldHVybiBzeW5jLmlzSGVsZEV4Y2x1c2l2ZWx5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUXVlcmllcyBpZiB0aGlzIGxvY2sgaXMgaGVsZCBieSBhbnkgdGhyZWFkLiBUaGlzIG1ldGhvZCBpcworICAgICAqIGRlc2lnbmVkIGZvciB1c2UgaW4gbW9uaXRvcmluZyBvZiB0aGUgc3lzdGVtIHN0YXRlLAorICAgICAqIG5vdCBmb3Igc3luY2hyb25pemF0aW9uIGNvbnRyb2wuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBhbnkgdGhyZWFkIGhvbGRzIHRoaXMgbG9jayBhbmQKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNMb2NrZWQoKSB7CisgICAgICAgIHJldHVybiBzeW5jLmlzTG9ja2VkKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBsb2NrIGhhcyBmYWlybmVzcyBzZXQgdHJ1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgbG9jayBoYXMgZmFpcm5lc3Mgc2V0IHRydWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0ZhaXIoKSB7CisgICAgICAgIHJldHVybiBzeW5jIGluc3RhbmNlb2YgRmFpclN5bmM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGhyZWFkIHRoYXQgY3VycmVudGx5IG93bnMgdGhpcyBsb2NrLCBvcgorICAgICAqIHtAY29kZSBudWxsfSBpZiBub3Qgb3duZWQuIFdoZW4gdGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IGEKKyAgICAgKiB0aHJlYWQgdGhhdCBpcyBub3QgdGhlIG93bmVyLCB0aGUgcmV0dXJuIHZhbHVlIHJlZmxlY3RzIGEKKyAgICAgKiBiZXN0LWVmZm9ydCBhcHByb3hpbWF0aW9uIG9mIGN1cnJlbnQgbG9jayBzdGF0dXMuIEZvciBleGFtcGxlLAorICAgICAqIHRoZSBvd25lciBtYXkgYmUgbW9tZW50YXJpbHkge0Bjb2RlIG51bGx9IGV2ZW4gaWYgdGhlcmUgYXJlCisgICAgICogdGhyZWFkcyB0cnlpbmcgdG8gYWNxdWlyZSB0aGUgbG9jayBidXQgaGF2ZSBub3QgeWV0IGRvbmUgc28uCisgICAgICogVGhpcyBtZXRob2QgaXMgZGVzaWduZWQgdG8gZmFjaWxpdGF0ZSBjb25zdHJ1Y3Rpb24gb2YKKyAgICAgKiBzdWJjbGFzc2VzIHRoYXQgcHJvdmlkZSBtb3JlIGV4dGVuc2l2ZSBsb2NrIG1vbml0b3JpbmcKKyAgICAgKiBmYWNpbGl0aWVzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgb3duZXIsIG9yIHtAY29kZSBudWxsfSBpZiBub3Qgb3duZWQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgVGhyZWFkIGdldE93bmVyKCkgeworICAgICAgICByZXR1cm4gc3luYy5nZXRPd25lcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFF1ZXJpZXMgd2hldGhlciBhbnkgdGhyZWFkcyBhcmUgd2FpdGluZyB0byBhY3F1aXJlIHRoaXMgbG9jay4gTm90ZSB0aGF0CisgICAgICogYmVjYXVzZSBjYW5jZWxsYXRpb25zIG1heSBvY2N1ciBhdCBhbnkgdGltZSwgYSB7QGNvZGUgdHJ1ZX0KKyAgICAgKiByZXR1cm4gZG9lcyBub3QgZ3VhcmFudGVlIHRoYXQgYW55IG90aGVyIHRocmVhZCB3aWxsIGV2ZXIKKyAgICAgKiBhY3F1aXJlIHRoaXMgbG9jay4gIFRoaXMgbWV0aG9kIGlzIGRlc2lnbmVkIHByaW1hcmlseSBmb3IgdXNlIGluCisgICAgICogbW9uaXRvcmluZyBvZiB0aGUgc3lzdGVtIHN0YXRlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlcmUgbWF5IGJlIG90aGVyIHRocmVhZHMgd2FpdGluZyB0bworICAgICAqICAgICAgICAgYWNxdWlyZSB0aGUgbG9jaworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc1F1ZXVlZFRocmVhZHMoKSB7CisgICAgICAgIHJldHVybiBzeW5jLmhhc1F1ZXVlZFRocmVhZHMoKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFF1ZXJpZXMgd2hldGhlciB0aGUgZ2l2ZW4gdGhyZWFkIGlzIHdhaXRpbmcgdG8gYWNxdWlyZSB0aGlzCisgICAgICogbG9jay4gTm90ZSB0aGF0IGJlY2F1c2UgY2FuY2VsbGF0aW9ucyBtYXkgb2NjdXIgYXQgYW55IHRpbWUsIGEKKyAgICAgKiB7QGNvZGUgdHJ1ZX0gcmV0dXJuIGRvZXMgbm90IGd1YXJhbnRlZSB0aGF0IHRoaXMgdGhyZWFkCisgICAgICogd2lsbCBldmVyIGFjcXVpcmUgdGhpcyBsb2NrLiAgVGhpcyBtZXRob2QgaXMgZGVzaWduZWQgcHJpbWFyaWx5IGZvciB1c2UKKyAgICAgKiBpbiBtb25pdG9yaW5nIG9mIHRoZSBzeXN0ZW0gc3RhdGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhyZWFkIHRoZSB0aHJlYWQKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZ2l2ZW4gdGhyZWFkIGlzIHF1ZXVlZCB3YWl0aW5nIGZvciB0aGlzIGxvY2sKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSB0aHJlYWQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc1F1ZXVlZFRocmVhZChUaHJlYWQgdGhyZWFkKSB7CisgICAgICAgIHJldHVybiBzeW5jLmlzUXVldWVkKHRocmVhZCk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGVzdGltYXRlIG9mIHRoZSBudW1iZXIgb2YgdGhyZWFkcyB3YWl0aW5nIHRvCisgICAgICogYWNxdWlyZSB0aGlzIGxvY2suICBUaGUgdmFsdWUgaXMgb25seSBhbiBlc3RpbWF0ZSBiZWNhdXNlIHRoZSBudW1iZXIgb2YKKyAgICAgKiB0aHJlYWRzIG1heSBjaGFuZ2UgZHluYW1pY2FsbHkgd2hpbGUgdGhpcyBtZXRob2QgdHJhdmVyc2VzCisgICAgICogaW50ZXJuYWwgZGF0YSBzdHJ1Y3R1cmVzLiAgVGhpcyBtZXRob2QgaXMgZGVzaWduZWQgZm9yIHVzZSBpbgorICAgICAqIG1vbml0b3Jpbmcgb2YgdGhlIHN5c3RlbSBzdGF0ZSwgbm90IGZvciBzeW5jaHJvbml6YXRpb24KKyAgICAgKiBjb250cm9sLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZXN0aW1hdGVkIG51bWJlciBvZiB0aHJlYWRzIHdhaXRpbmcgZm9yIHRoaXMgbG9jaworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UXVldWVMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBzeW5jLmdldFF1ZXVlTGVuZ3RoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvbGxlY3Rpb24gY29udGFpbmluZyB0aHJlYWRzIHRoYXQgbWF5IGJlIHdhaXRpbmcgdG8KKyAgICAgKiBhY3F1aXJlIHRoaXMgbG9jay4gIEJlY2F1c2UgdGhlIGFjdHVhbCBzZXQgb2YgdGhyZWFkcyBtYXkgY2hhbmdlCisgICAgICogZHluYW1pY2FsbHkgd2hpbGUgY29uc3RydWN0aW5nIHRoaXMgcmVzdWx0LCB0aGUgcmV0dXJuZWQKKyAgICAgKiBjb2xsZWN0aW9uIGlzIG9ubHkgYSBiZXN0LWVmZm9ydCBlc3RpbWF0ZS4gIFRoZSBlbGVtZW50cyBvZiB0aGUKKyAgICAgKiByZXR1cm5lZCBjb2xsZWN0aW9uIGFyZSBpbiBubyBwYXJ0aWN1bGFyIG9yZGVyLiAgVGhpcyBtZXRob2QgaXMKKyAgICAgKiBkZXNpZ25lZCB0byBmYWNpbGl0YXRlIGNvbnN0cnVjdGlvbiBvZiBzdWJjbGFzc2VzIHRoYXQgcHJvdmlkZQorICAgICAqIG1vcmUgZXh0ZW5zaXZlIG1vbml0b3JpbmcgZmFjaWxpdGllcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNvbGxlY3Rpb24gb2YgdGhyZWFkcworICAgICAqLworICAgIHByb3RlY3RlZCBDb2xsZWN0aW9uPFRocmVhZD4gZ2V0UXVldWVkVGhyZWFkcygpIHsKKyAgICAgICAgcmV0dXJuIHN5bmMuZ2V0UXVldWVkVGhyZWFkcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFF1ZXJpZXMgd2hldGhlciBhbnkgdGhyZWFkcyBhcmUgd2FpdGluZyBvbiB0aGUgZ2l2ZW4gY29uZGl0aW9uCisgICAgICogYXNzb2NpYXRlZCB3aXRoIHRoaXMgbG9jay4gTm90ZSB0aGF0IGJlY2F1c2UgdGltZW91dHMgYW5kCisgICAgICogaW50ZXJydXB0cyBtYXkgb2NjdXIgYXQgYW55IHRpbWUsIGEge0Bjb2RlIHRydWV9IHJldHVybiBkb2VzCisgICAgICogbm90IGd1YXJhbnRlZSB0aGF0IGEgZnV0dXJlIHtAY29kZSBzaWduYWx9IHdpbGwgYXdha2VuIGFueQorICAgICAqIHRocmVhZHMuICBUaGlzIG1ldGhvZCBpcyBkZXNpZ25lZCBwcmltYXJpbHkgZm9yIHVzZSBpbgorICAgICAqIG1vbml0b3Jpbmcgb2YgdGhlIHN5c3RlbSBzdGF0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb25kaXRpb24gdGhlIGNvbmRpdGlvbgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZXJlIGFyZSBhbnkgd2FpdGluZyB0aHJlYWRzCisgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbG9jayBpcyBub3QgaGVsZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBjb25kaXRpb24gaXMKKyAgICAgKiAgICAgICAgIG5vdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBsb2NrCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgY29uZGl0aW9uIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNXYWl0ZXJzKENvbmRpdGlvbiBjb25kaXRpb24pIHsKKyAgICAgICAgaWYgKGNvbmRpdGlvbiA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGlmICghKGNvbmRpdGlvbiBpbnN0YW5jZW9mIEFic3RyYWN0UXVldWVkU3luY2hyb25pemVyLkNvbmRpdGlvbk9iamVjdCkpCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJub3Qgb3duZXIiKTsKKyAgICAgICAgcmV0dXJuIHN5bmMuaGFzV2FpdGVycygoQWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXIuQ29uZGl0aW9uT2JqZWN0KWNvbmRpdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBlc3RpbWF0ZSBvZiB0aGUgbnVtYmVyIG9mIHRocmVhZHMgd2FpdGluZyBvbiB0aGUKKyAgICAgKiBnaXZlbiBjb25kaXRpb24gYXNzb2NpYXRlZCB3aXRoIHRoaXMgbG9jay4gTm90ZSB0aGF0IGJlY2F1c2UKKyAgICAgKiB0aW1lb3V0cyBhbmQgaW50ZXJydXB0cyBtYXkgb2NjdXIgYXQgYW55IHRpbWUsIHRoZSBlc3RpbWF0ZQorICAgICAqIHNlcnZlcyBvbmx5IGFzIGFuIHVwcGVyIGJvdW5kIG9uIHRoZSBhY3R1YWwgbnVtYmVyIG9mIHdhaXRlcnMuCisgICAgICogVGhpcyBtZXRob2QgaXMgZGVzaWduZWQgZm9yIHVzZSBpbiBtb25pdG9yaW5nIG9mIHRoZSBzeXN0ZW0KKyAgICAgKiBzdGF0ZSwgbm90IGZvciBzeW5jaHJvbml6YXRpb24gY29udHJvbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb25kaXRpb24gdGhlIGNvbmRpdGlvbgorICAgICAqIEByZXR1cm4gdGhlIGVzdGltYXRlZCBudW1iZXIgb2Ygd2FpdGluZyB0aHJlYWRzCisgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbG9jayBpcyBub3QgaGVsZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBjb25kaXRpb24gaXMKKyAgICAgKiAgICAgICAgIG5vdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBsb2NrCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgY29uZGl0aW9uIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFdhaXRRdWV1ZUxlbmd0aChDb25kaXRpb24gY29uZGl0aW9uKSB7CisgICAgICAgIGlmIChjb25kaXRpb24gPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBpZiAoIShjb25kaXRpb24gaW5zdGFuY2VvZiBBYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplci5Db25kaXRpb25PYmplY3QpKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibm90IG93bmVyIik7CisgICAgICAgIHJldHVybiBzeW5jLmdldFdhaXRRdWV1ZUxlbmd0aCgoQWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXIuQ29uZGl0aW9uT2JqZWN0KWNvbmRpdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvbGxlY3Rpb24gY29udGFpbmluZyB0aG9zZSB0aHJlYWRzIHRoYXQgbWF5IGJlCisgICAgICogd2FpdGluZyBvbiB0aGUgZ2l2ZW4gY29uZGl0aW9uIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGxvY2suCisgICAgICogQmVjYXVzZSB0aGUgYWN0dWFsIHNldCBvZiB0aHJlYWRzIG1heSBjaGFuZ2UgZHluYW1pY2FsbHkgd2hpbGUKKyAgICAgKiBjb25zdHJ1Y3RpbmcgdGhpcyByZXN1bHQsIHRoZSByZXR1cm5lZCBjb2xsZWN0aW9uIGlzIG9ubHkgYQorICAgICAqIGJlc3QtZWZmb3J0IGVzdGltYXRlLiBUaGUgZWxlbWVudHMgb2YgdGhlIHJldHVybmVkIGNvbGxlY3Rpb24KKyAgICAgKiBhcmUgaW4gbm8gcGFydGljdWxhciBvcmRlci4gIFRoaXMgbWV0aG9kIGlzIGRlc2lnbmVkIHRvCisgICAgICogZmFjaWxpdGF0ZSBjb25zdHJ1Y3Rpb24gb2Ygc3ViY2xhc3NlcyB0aGF0IHByb3ZpZGUgbW9yZQorICAgICAqIGV4dGVuc2l2ZSBjb25kaXRpb24gbW9uaXRvcmluZyBmYWNpbGl0aWVzLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbmRpdGlvbiB0aGUgY29uZGl0aW9uCisgICAgICogQHJldHVybiB0aGUgY29sbGVjdGlvbiBvZiB0aHJlYWRzCisgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbG9jayBpcyBub3QgaGVsZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBjb25kaXRpb24gaXMKKyAgICAgKiAgICAgICAgIG5vdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBsb2NrCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgY29uZGl0aW9uIGlzIG51bGwKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ29sbGVjdGlvbjxUaHJlYWQ+IGdldFdhaXRpbmdUaHJlYWRzKENvbmRpdGlvbiBjb25kaXRpb24pIHsKKyAgICAgICAgaWYgKGNvbmRpdGlvbiA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGlmICghKGNvbmRpdGlvbiBpbnN0YW5jZW9mIEFic3RyYWN0UXVldWVkU3luY2hyb25pemVyLkNvbmRpdGlvbk9iamVjdCkpCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJub3Qgb3duZXIiKTsKKyAgICAgICAgcmV0dXJuIHN5bmMuZ2V0V2FpdGluZ1RocmVhZHMoKEFic3RyYWN0UXVldWVkU3luY2hyb25pemVyLkNvbmRpdGlvbk9iamVjdCljb25kaXRpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgaWRlbnRpZnlpbmcgdGhpcyBsb2NrLCBhcyB3ZWxsIGFzIGl0cyBsb2NrIHN0YXRlLgorICAgICAqIFRoZSBzdGF0ZSwgaW4gYnJhY2tldHMsIGluY2x1ZGVzIGVpdGhlciB0aGUgU3RyaW5nIHtAY29kZSAiVW5sb2NrZWQifQorICAgICAqIG9yIHRoZSBTdHJpbmcge0Bjb2RlICJMb2NrZWQgYnkifSBmb2xsb3dlZCBieSB0aGUKKyAgICAgKiB7QGxpbmtwbGFpbiBUaHJlYWQjZ2V0TmFtZSBuYW1lfSBvZiB0aGUgb3duaW5nIHRocmVhZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgaWRlbnRpZnlpbmcgdGhpcyBsb2NrLCBhcyB3ZWxsIGFzIGl0cyBsb2NrIHN0YXRlCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgVGhyZWFkIG8gPSBzeW5jLmdldE93bmVyKCk7CisgICAgICAgIHJldHVybiBzdXBlci50b1N0cmluZygpICsgKChvID09IG51bGwpID8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIltVbmxvY2tlZF0iIDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIltMb2NrZWQgYnkgdGhyZWFkICIgKyBvLmdldE5hbWUoKSArICJdIik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL1JlZW50cmFudFJlYWRXcml0ZUxvY2suamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9sb2Nrcy9SZWVudHJhbnRSZWFkV3JpdGVMb2NrLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjFhMWE2MAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9sb2Nrcy9SZWVudHJhbnRSZWFkV3JpdGVMb2NrLmphdmEKQEAgLTAsMCArMSwxNDU3IEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3M7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuKjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKKworLyoqCisgKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgUmVhZFdyaXRlTG9ja30gc3VwcG9ydGluZyBzaW1pbGFyCisgKiBzZW1hbnRpY3MgdG8ge0BsaW5rIFJlZW50cmFudExvY2t9LgorICogPHA+VGhpcyBjbGFzcyBoYXMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOgorICoKKyAqIDx1bD4KKyAqIDxsaT48Yj5BY3F1aXNpdGlvbiBvcmRlcjwvYj4KKyAqCisgKiA8cD4gVGhpcyBjbGFzcyBkb2VzIG5vdCBpbXBvc2UgYSByZWFkZXIgb3Igd3JpdGVyIHByZWZlcmVuY2UKKyAqIG9yZGVyaW5nIGZvciBsb2NrIGFjY2Vzcy4gIEhvd2V2ZXIsIGl0IGRvZXMgc3VwcG9ydCBhbiBvcHRpb25hbAorICogPGVtPmZhaXJuZXNzPC9lbT4gcG9saWN5LgorICoKKyAqIDxkbD4KKyAqIDxkdD48Yj48aT5Ob24tZmFpciBtb2RlIChkZWZhdWx0KTwvaT48L2I+CisgKiA8ZGQ+V2hlbiBjb25zdHJ1Y3RlZCBhcyBub24tZmFpciAodGhlIGRlZmF1bHQpLCB0aGUgb3JkZXIgb2YgZW50cnkKKyAqIHRvIHRoZSByZWFkIGFuZCB3cml0ZSBsb2NrIGlzIHVuc3BlY2lmaWVkLCBzdWJqZWN0IHRvIHJlZW50cmFuY3kKKyAqIGNvbnN0cmFpbnRzLiAgQSBub25mYWlyIGxvY2sgdGhhdCBpcyBjb250aW51b3VzbHkgY29udGVuZGVkIG1heQorICogaW5kZWZpbml0ZWx5IHBvc3Rwb25lIG9uZSBvciBtb3JlIHJlYWRlciBvciB3cml0ZXIgdGhyZWFkcywgYnV0CisgKiB3aWxsIG5vcm1hbGx5IGhhdmUgaGlnaGVyIHRocm91Z2hwdXQgdGhhbiBhIGZhaXIgbG9jay4KKyAqIDxwPgorICoKKyAqIDxkdD48Yj48aT5GYWlyIG1vZGU8L2k+PC9iPgorICogPGRkPiBXaGVuIGNvbnN0cnVjdGVkIGFzIGZhaXIsIHRocmVhZHMgY29udGVuZCBmb3IgZW50cnkgdXNpbmcgYW4KKyAqIGFwcHJveGltYXRlbHkgYXJyaXZhbC1vcmRlciBwb2xpY3kuIFdoZW4gdGhlIGN1cnJlbnRseSBoZWxkIGxvY2sKKyAqIGlzIHJlbGVhc2VkIGVpdGhlciB0aGUgbG9uZ2VzdC13YWl0aW5nIHNpbmdsZSB3cml0ZXIgdGhyZWFkIHdpbGwKKyAqIGJlIGFzc2lnbmVkIHRoZSB3cml0ZSBsb2NrLCBvciBpZiB0aGVyZSBpcyBhIGdyb3VwIG9mIHJlYWRlciB0aHJlYWRzCisgKiB3YWl0aW5nIGxvbmdlciB0aGFuIGFsbCB3YWl0aW5nIHdyaXRlciB0aHJlYWRzLCB0aGF0IGdyb3VwIHdpbGwgYmUKKyAqIGFzc2lnbmVkIHRoZSByZWFkIGxvY2suCisgKgorICogPHA+QSB0aHJlYWQgdGhhdCB0cmllcyB0byBhY3F1aXJlIGEgZmFpciByZWFkIGxvY2sgKG5vbi1yZWVudHJhbnRseSkKKyAqIHdpbGwgYmxvY2sgaWYgZWl0aGVyIHRoZSB3cml0ZSBsb2NrIGlzIGhlbGQsIG9yIHRoZXJlIGlzIGEgd2FpdGluZworICogd3JpdGVyIHRocmVhZC4gVGhlIHRocmVhZCB3aWxsIG5vdCBhY3F1aXJlIHRoZSByZWFkIGxvY2sgdW50aWwKKyAqIGFmdGVyIHRoZSBvbGRlc3QgY3VycmVudGx5IHdhaXRpbmcgd3JpdGVyIHRocmVhZCBoYXMgYWNxdWlyZWQgYW5kCisgKiByZWxlYXNlZCB0aGUgd3JpdGUgbG9jay4gT2YgY291cnNlLCBpZiBhIHdhaXRpbmcgd3JpdGVyIGFiYW5kb25zCisgKiBpdHMgd2FpdCwgbGVhdmluZyBvbmUgb3IgbW9yZSByZWFkZXIgdGhyZWFkcyBhcyB0aGUgbG9uZ2VzdCB3YWl0ZXJzCisgKiBpbiB0aGUgcXVldWUgd2l0aCB0aGUgd3JpdGUgbG9jayBmcmVlLCB0aGVuIHRob3NlIHJlYWRlcnMgd2lsbCBiZQorICogYXNzaWduZWQgdGhlIHJlYWQgbG9jay4KKyAqCisgKiA8cD5BIHRocmVhZCB0aGF0IHRyaWVzIHRvIGFjcXVpcmUgYSBmYWlyIHdyaXRlIGxvY2sgKG5vbi1yZWVudHJhbnRseSkKKyAqIHdpbGwgYmxvY2sgdW5sZXNzIGJvdGggdGhlIHJlYWQgbG9jayBhbmQgd3JpdGUgbG9jayBhcmUgZnJlZSAod2hpY2gKKyAqIGltcGxpZXMgdGhlcmUgYXJlIG5vIHdhaXRpbmcgdGhyZWFkcykuICAoTm90ZSB0aGF0IHRoZSBub24tYmxvY2tpbmcKKyAqIHtAbGluayBSZWFkTG9jayN0cnlMb2NrKCl9IGFuZCB7QGxpbmsgV3JpdGVMb2NrI3RyeUxvY2soKX0gbWV0aG9kcworICogZG8gbm90IGhvbm9yIHRoaXMgZmFpciBzZXR0aW5nIGFuZCB3aWxsIGFjcXVpcmUgdGhlIGxvY2sgaWYgaXQgaXMKKyAqIHBvc3NpYmxlLCByZWdhcmRsZXNzIG9mIHdhaXRpbmcgdGhyZWFkcy4pCisgKiA8cD4KKyAqIDwvZGw+CisgKgorICogPGxpPjxiPlJlZW50cmFuY3k8L2I+CisgKgorICogPHA+VGhpcyBsb2NrIGFsbG93cyBib3RoIHJlYWRlcnMgYW5kIHdyaXRlcnMgdG8gcmVhY3F1aXJlIHJlYWQgb3IKKyAqIHdyaXRlIGxvY2tzIGluIHRoZSBzdHlsZSBvZiBhIHtAbGluayBSZWVudHJhbnRMb2NrfS4gTm9uLXJlZW50cmFudAorICogcmVhZGVycyBhcmUgbm90IGFsbG93ZWQgdW50aWwgYWxsIHdyaXRlIGxvY2tzIGhlbGQgYnkgdGhlIHdyaXRpbmcKKyAqIHRocmVhZCBoYXZlIGJlZW4gcmVsZWFzZWQuCisgKgorICogPHA+QWRkaXRpb25hbGx5LCBhIHdyaXRlciBjYW4gYWNxdWlyZSB0aGUgcmVhZCBsb2NrLCBidXQgbm90CisgKiB2aWNlLXZlcnNhLiAgQW1vbmcgb3RoZXIgYXBwbGljYXRpb25zLCByZWVudHJhbmN5IGNhbiBiZSB1c2VmdWwKKyAqIHdoZW4gd3JpdGUgbG9ja3MgYXJlIGhlbGQgZHVyaW5nIGNhbGxzIG9yIGNhbGxiYWNrcyB0byBtZXRob2RzIHRoYXQKKyAqIHBlcmZvcm0gcmVhZHMgdW5kZXIgcmVhZCBsb2Nrcy4gIElmIGEgcmVhZGVyIHRyaWVzIHRvIGFjcXVpcmUgdGhlCisgKiB3cml0ZSBsb2NrIGl0IHdpbGwgbmV2ZXIgc3VjY2VlZC4KKyAqCisgKiA8bGk+PGI+TG9jayBkb3duZ3JhZGluZzwvYj4KKyAqIDxwPlJlZW50cmFuY3kgYWxzbyBhbGxvd3MgZG93bmdyYWRpbmcgZnJvbSB0aGUgd3JpdGUgbG9jayB0byBhIHJlYWQgbG9jaywKKyAqIGJ5IGFjcXVpcmluZyB0aGUgd3JpdGUgbG9jaywgdGhlbiB0aGUgcmVhZCBsb2NrIGFuZCB0aGVuIHJlbGVhc2luZyB0aGUKKyAqIHdyaXRlIGxvY2suIEhvd2V2ZXIsIHVwZ3JhZGluZyBmcm9tIGEgcmVhZCBsb2NrIHRvIHRoZSB3cml0ZSBsb2NrIGlzCisgKiA8Yj5ub3Q8L2I+IHBvc3NpYmxlLgorICoKKyAqIDxsaT48Yj5JbnRlcnJ1cHRpb24gb2YgbG9jayBhY3F1aXNpdGlvbjwvYj4KKyAqIDxwPlRoZSByZWFkIGxvY2sgYW5kIHdyaXRlIGxvY2sgYm90aCBzdXBwb3J0IGludGVycnVwdGlvbiBkdXJpbmcgbG9jaworICogYWNxdWlzaXRpb24uCisgKgorICogPGxpPjxiPntAbGluayBDb25kaXRpb259IHN1cHBvcnQ8L2I+CisgKiA8cD5UaGUgd3JpdGUgbG9jayBwcm92aWRlcyBhIHtAbGluayBDb25kaXRpb259IGltcGxlbWVudGF0aW9uIHRoYXQKKyAqIGJlaGF2ZXMgaW4gdGhlIHNhbWUgd2F5LCB3aXRoIHJlc3BlY3QgdG8gdGhlIHdyaXRlIGxvY2ssIGFzIHRoZQorICoge0BsaW5rIENvbmRpdGlvbn0gaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgYnkKKyAqIHtAbGluayBSZWVudHJhbnRMb2NrI25ld0NvbmRpdGlvbn0gZG9lcyBmb3Ige0BsaW5rIFJlZW50cmFudExvY2t9LgorICogVGhpcyB7QGxpbmsgQ29uZGl0aW9ufSBjYW4sIG9mIGNvdXJzZSwgb25seSBiZSB1c2VkIHdpdGggdGhlIHdyaXRlIGxvY2suCisgKgorICogPHA+VGhlIHJlYWQgbG9jayBkb2VzIG5vdCBzdXBwb3J0IGEge0BsaW5rIENvbmRpdGlvbn0gYW5kCisgKiB7QGNvZGUgcmVhZExvY2soKS5uZXdDb25kaXRpb24oKX0gdGhyb3dzCisgKiB7QGNvZGUgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259LgorICoKKyAqIDxsaT48Yj5JbnN0cnVtZW50YXRpb248L2I+CisgKiA8cD5UaGlzIGNsYXNzIHN1cHBvcnRzIG1ldGhvZHMgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgbG9ja3MKKyAqIGFyZSBoZWxkIG9yIGNvbnRlbmRlZC4gVGhlc2UgbWV0aG9kcyBhcmUgZGVzaWduZWQgZm9yIG1vbml0b3JpbmcKKyAqIHN5c3RlbSBzdGF0ZSwgbm90IGZvciBzeW5jaHJvbml6YXRpb24gY29udHJvbC4KKyAqIDwvdWw+CisgKgorICogPHA+U2VyaWFsaXphdGlvbiBvZiB0aGlzIGNsYXNzIGJlaGF2ZXMgaW4gdGhlIHNhbWUgd2F5IGFzIGJ1aWx0LWluCisgKiBsb2NrczogYSBkZXNlcmlhbGl6ZWQgbG9jayBpcyBpbiB0aGUgdW5sb2NrZWQgc3RhdGUsIHJlZ2FyZGxlc3Mgb2YKKyAqIGl0cyBzdGF0ZSB3aGVuIHNlcmlhbGl6ZWQuCisgKgorICogPHA+PGI+U2FtcGxlIHVzYWdlczwvYj4uIEhlcmUgaXMgYSBjb2RlIHNrZXRjaCBzaG93aW5nIGhvdyB0byBwZXJmb3JtCisgKiBsb2NrIGRvd25ncmFkaW5nIGFmdGVyIHVwZGF0aW5nIGEgY2FjaGUgKGV4Y2VwdGlvbiBoYW5kbGluZyBpcworICogcGFydGljdWxhcmx5IHRyaWNreSB3aGVuIGhhbmRsaW5nIG11bHRpcGxlIGxvY2tzIGluIGEgbm9uLW5lc3RlZAorICogZmFzaGlvbik6CisgKgorICogPHByZT4ge0Bjb2RlCisgKiBjbGFzcyBDYWNoZWREYXRhIHsKKyAqICAgT2JqZWN0IGRhdGE7CisgKiAgIHZvbGF0aWxlIGJvb2xlYW4gY2FjaGVWYWxpZDsKKyAqICAgZmluYWwgUmVlbnRyYW50UmVhZFdyaXRlTG9jayByd2wgPSBuZXcgUmVlbnRyYW50UmVhZFdyaXRlTG9jaygpOworICoKKyAqICAgdm9pZCBwcm9jZXNzQ2FjaGVkRGF0YSgpIHsKKyAqICAgICByd2wucmVhZExvY2soKS5sb2NrKCk7CisgKiAgICAgaWYgKCFjYWNoZVZhbGlkKSB7CisgKiAgICAgICAgLy8gTXVzdCByZWxlYXNlIHJlYWQgbG9jayBiZWZvcmUgYWNxdWlyaW5nIHdyaXRlIGxvY2sKKyAqICAgICAgICByd2wucmVhZExvY2soKS51bmxvY2soKTsKKyAqICAgICAgICByd2wud3JpdGVMb2NrKCkubG9jaygpOworICogICAgICAgIHRyeSB7CisgKiAgICAgICAgICAvLyBSZWNoZWNrIHN0YXRlIGJlY2F1c2UgYW5vdGhlciB0aHJlYWQgbWlnaHQgaGF2ZQorICogICAgICAgICAgLy8gYWNxdWlyZWQgd3JpdGUgbG9jayBhbmQgY2hhbmdlZCBzdGF0ZSBiZWZvcmUgd2UgZGlkLgorICogICAgICAgICAgaWYgKCFjYWNoZVZhbGlkKSB7CisgKiAgICAgICAgICAgIGRhdGEgPSAuLi4KKyAqICAgICAgICAgICAgY2FjaGVWYWxpZCA9IHRydWU7CisgKiAgICAgICAgICB9CisgKiAgICAgICAgICAvLyBEb3duZ3JhZGUgYnkgYWNxdWlyaW5nIHJlYWQgbG9jayBiZWZvcmUgcmVsZWFzaW5nIHdyaXRlIGxvY2sKKyAqICAgICAgICAgIHJ3bC5yZWFkTG9jaygpLmxvY2soKTsKKyAqICAgICAgICB9IGZpbmFsbHkgeworICogICAgICAgICAgcndsLndyaXRlTG9jaygpLnVubG9jaygpOyAvLyBVbmxvY2sgd3JpdGUsIHN0aWxsIGhvbGQgcmVhZAorICogICAgICAgIH0KKyAqICAgICB9CisgKgorICogICAgIHRyeSB7CisgKiAgICAgICB1c2UoZGF0YSk7CisgKiAgICAgfSBmaW5hbGx5IHsKKyAqICAgICAgIHJ3bC5yZWFkTG9jaygpLnVubG9jaygpOworICogICAgIH0KKyAqICAgfQorICogfX08L3ByZT4KKyAqCisgKiBSZWVudHJhbnRSZWFkV3JpdGVMb2NrcyBjYW4gYmUgdXNlZCB0byBpbXByb3ZlIGNvbmN1cnJlbmN5IGluIHNvbWUKKyAqIHVzZXMgb2Ygc29tZSBraW5kcyBvZiBDb2xsZWN0aW9ucy4gVGhpcyBpcyB0eXBpY2FsbHkgd29ydGh3aGlsZQorICogb25seSB3aGVuIHRoZSBjb2xsZWN0aW9ucyBhcmUgZXhwZWN0ZWQgdG8gYmUgbGFyZ2UsIGFjY2Vzc2VkIGJ5CisgKiBtb3JlIHJlYWRlciB0aHJlYWRzIHRoYW4gd3JpdGVyIHRocmVhZHMsIGFuZCBlbnRhaWwgb3BlcmF0aW9ucyB3aXRoCisgKiBvdmVyaGVhZCB0aGF0IG91dHdlaWdocyBzeW5jaHJvbml6YXRpb24gb3ZlcmhlYWQuIEZvciBleGFtcGxlLCBoZXJlCisgKiBpcyBhIGNsYXNzIHVzaW5nIGEgVHJlZU1hcCB0aGF0IGlzIGV4cGVjdGVkIHRvIGJlIGxhcmdlIGFuZAorICogY29uY3VycmVudGx5IGFjY2Vzc2VkLgorICoKKyAqIDxwcmU+e0Bjb2RlCisgKiBjbGFzcyBSV0RpY3Rpb25hcnkgeworICogICAgcHJpdmF0ZSBmaW5hbCBNYXA8U3RyaW5nLCBEYXRhPiBtID0gbmV3IFRyZWVNYXA8U3RyaW5nLCBEYXRhPigpOworICogICAgcHJpdmF0ZSBmaW5hbCBSZWVudHJhbnRSZWFkV3JpdGVMb2NrIHJ3bCA9IG5ldyBSZWVudHJhbnRSZWFkV3JpdGVMb2NrKCk7CisgKiAgICBwcml2YXRlIGZpbmFsIExvY2sgciA9IHJ3bC5yZWFkTG9jaygpOworICogICAgcHJpdmF0ZSBmaW5hbCBMb2NrIHcgPSByd2wud3JpdGVMb2NrKCk7CisgKgorICogICAgcHVibGljIERhdGEgZ2V0KFN0cmluZyBrZXkpIHsKKyAqICAgICAgICByLmxvY2soKTsKKyAqICAgICAgICB0cnkgeyByZXR1cm4gbS5nZXQoa2V5KTsgfQorICogICAgICAgIGZpbmFsbHkgeyByLnVubG9jaygpOyB9CisgKiAgICB9CisgKiAgICBwdWJsaWMgU3RyaW5nW10gYWxsS2V5cygpIHsKKyAqICAgICAgICByLmxvY2soKTsKKyAqICAgICAgICB0cnkgeyByZXR1cm4gbS5rZXlTZXQoKS50b0FycmF5KCk7IH0KKyAqICAgICAgICBmaW5hbGx5IHsgci51bmxvY2soKTsgfQorICogICAgfQorICogICAgcHVibGljIERhdGEgcHV0KFN0cmluZyBrZXksIERhdGEgdmFsdWUpIHsKKyAqICAgICAgICB3LmxvY2soKTsKKyAqICAgICAgICB0cnkgeyByZXR1cm4gbS5wdXQoa2V5LCB2YWx1ZSk7IH0KKyAqICAgICAgICBmaW5hbGx5IHsgdy51bmxvY2soKTsgfQorICogICAgfQorICogICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgKiAgICAgICAgdy5sb2NrKCk7CisgKiAgICAgICAgdHJ5IHsgbS5jbGVhcigpOyB9CisgKiAgICAgICAgZmluYWxseSB7IHcudW5sb2NrKCk7IH0KKyAqICAgIH0KKyAqIH19PC9wcmU+CisgKgorICogPGgzPkltcGxlbWVudGF0aW9uIE5vdGVzPC9oMz4KKyAqCisgKiA8cD5UaGlzIGxvY2sgc3VwcG9ydHMgYSBtYXhpbXVtIG9mIDY1NTM1IHJlY3Vyc2l2ZSB3cml0ZSBsb2NrcworICogYW5kIDY1NTM1IHJlYWQgbG9ja3MuIEF0dGVtcHRzIHRvIGV4Y2VlZCB0aGVzZSBsaW1pdHMgcmVzdWx0IGluCisgKiB7QGxpbmsgRXJyb3J9IHRocm93cyBmcm9tIGxvY2tpbmcgbWV0aG9kcy4KKyAqCisgKiBAc2luY2UgMS41CisgKiBAYXV0aG9yIERvdWcgTGVhCisgKgorICovCitwdWJsaWMgY2xhc3MgUmVlbnRyYW50UmVhZFdyaXRlTG9jaworICAgICAgICBpbXBsZW1lbnRzIFJlYWRXcml0ZUxvY2ssIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjk5MjQ0ODY0NjQwNzY5MDE2NEw7CisgICAgLyoqIElubmVyIGNsYXNzIHByb3ZpZGluZyByZWFkbG9jayAqLworICAgIHByaXZhdGUgZmluYWwgUmVlbnRyYW50UmVhZFdyaXRlTG9jay5SZWFkTG9jayByZWFkZXJMb2NrOworICAgIC8qKiBJbm5lciBjbGFzcyBwcm92aWRpbmcgd3JpdGVsb2NrICovCisgICAgcHJpdmF0ZSBmaW5hbCBSZWVudHJhbnRSZWFkV3JpdGVMb2NrLldyaXRlTG9jayB3cml0ZXJMb2NrOworICAgIC8qKiBQZXJmb3JtcyBhbGwgc3luY2hyb25pemF0aW9uIG1lY2hhbmljcyAqLworICAgIGZpbmFsIFN5bmMgc3luYzsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFJlZW50cmFudFJlYWRXcml0ZUxvY2t9IHdpdGgKKyAgICAgKiBkZWZhdWx0IChub25mYWlyKSBvcmRlcmluZyBwcm9wZXJ0aWVzLgorICAgICAqLworICAgIHB1YmxpYyBSZWVudHJhbnRSZWFkV3JpdGVMb2NrKCkgeworICAgICAgICB0aGlzKGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBSZWVudHJhbnRSZWFkV3JpdGVMb2NrfSB3aXRoCisgICAgICogdGhlIGdpdmVuIGZhaXJuZXNzIHBvbGljeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmYWlyIHtAY29kZSB0cnVlfSBpZiB0aGlzIGxvY2sgc2hvdWxkIHVzZSBhIGZhaXIgb3JkZXJpbmcgcG9saWN5CisgICAgICovCisgICAgcHVibGljIFJlZW50cmFudFJlYWRXcml0ZUxvY2soYm9vbGVhbiBmYWlyKSB7CisgICAgICAgIHN5bmMgPSBmYWlyID8gbmV3IEZhaXJTeW5jKCkgOiBuZXcgTm9uZmFpclN5bmMoKTsKKyAgICAgICAgcmVhZGVyTG9jayA9IG5ldyBSZWFkTG9jayh0aGlzKTsKKyAgICAgICAgd3JpdGVyTG9jayA9IG5ldyBXcml0ZUxvY2sodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIFJlZW50cmFudFJlYWRXcml0ZUxvY2suV3JpdGVMb2NrIHdyaXRlTG9jaygpIHsgcmV0dXJuIHdyaXRlckxvY2s7IH0KKyAgICBwdWJsaWMgUmVlbnRyYW50UmVhZFdyaXRlTG9jay5SZWFkTG9jayAgcmVhZExvY2soKSAgeyByZXR1cm4gcmVhZGVyTG9jazsgfQorCisgICAgLyoqCisgICAgICogU3luY2hyb25pemF0aW9uIGltcGxlbWVudGF0aW9uIGZvciBSZWVudHJhbnRSZWFkV3JpdGVMb2NrLgorICAgICAqIFN1YmNsYXNzZWQgaW50byBmYWlyIGFuZCBub25mYWlyIHZlcnNpb25zLgorICAgICAqLworICAgIGFic3RyYWN0IHN0YXRpYyBjbGFzcyBTeW5jIGV4dGVuZHMgQWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXIgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA2MzE3NjcxNTE1MDY4Mzc4MDQxTDsKKworICAgICAgICAvKgorICAgICAgICAgKiBSZWFkIHZzIHdyaXRlIGNvdW50IGV4dHJhY3Rpb24gY29uc3RhbnRzIGFuZCBmdW5jdGlvbnMuCisgICAgICAgICAqIExvY2sgc3RhdGUgaXMgbG9naWNhbGx5IGRpdmlkZWQgaW50byB0d28gdW5zaWduZWQgc2hvcnRzOgorICAgICAgICAgKiBUaGUgbG93ZXIgb25lIHJlcHJlc2VudGluZyB0aGUgZXhjbHVzaXZlICh3cml0ZXIpIGxvY2sgaG9sZCBjb3VudCwKKyAgICAgICAgICogYW5kIHRoZSB1cHBlciB0aGUgc2hhcmVkIChyZWFkZXIpIGhvbGQgY291bnQuCisgICAgICAgICAqLworCisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgU0hBUkVEX1NISUZUICAgPSAxNjsKKyAgICAgICAgc3RhdGljIGZpbmFsIGludCBTSEFSRURfVU5JVCAgICA9ICgxIDw8IFNIQVJFRF9TSElGVCk7CisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0NPVU5UICAgICAgPSAoMSA8PCBTSEFSRURfU0hJRlQpIC0gMTsKKyAgICAgICAgc3RhdGljIGZpbmFsIGludCBFWENMVVNJVkVfTUFTSyA9ICgxIDw8IFNIQVJFRF9TSElGVCkgLSAxOworCisgICAgICAgIC8qKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Ygc2hhcmVkIGhvbGRzIHJlcHJlc2VudGVkIGluIGNvdW50ICAqLworICAgICAgICBzdGF0aWMgaW50IHNoYXJlZENvdW50KGludCBjKSAgICB7IHJldHVybiBjID4+PiBTSEFSRURfU0hJRlQ7IH0KKyAgICAgICAgLyoqIFJldHVybnMgdGhlIG51bWJlciBvZiBleGNsdXNpdmUgaG9sZHMgcmVwcmVzZW50ZWQgaW4gY291bnQgICovCisgICAgICAgIHN0YXRpYyBpbnQgZXhjbHVzaXZlQ291bnQoaW50IGMpIHsgcmV0dXJuIGMgJiBFWENMVVNJVkVfTUFTSzsgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBBIGNvdW50ZXIgZm9yIHBlci10aHJlYWQgcmVhZCBob2xkIGNvdW50cy4KKyAgICAgICAgICogTWFpbnRhaW5lZCBhcyBhIFRocmVhZExvY2FsOyBjYWNoZWQgaW4gY2FjaGVkSG9sZENvdW50ZXIKKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBIb2xkQ291bnRlciB7CisgICAgICAgICAgICBpbnQgY291bnQgPSAwOworICAgICAgICAgICAgLy8gVXNlIGlkLCBub3QgcmVmZXJlbmNlLCB0byBhdm9pZCBnYXJiYWdlIHJldGVudGlvbgorICAgICAgICAgICAgZmluYWwgbG9uZyB0aWQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldElkKCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogVGhyZWFkTG9jYWwgc3ViY2xhc3MuIEVhc2llc3QgdG8gZXhwbGljaXRseSBkZWZpbmUgZm9yIHNha2UKKyAgICAgICAgICogb2YgZGVzZXJpYWxpemF0aW9uIG1lY2hhbmljcy4KKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBUaHJlYWRMb2NhbEhvbGRDb3VudGVyCisgICAgICAgICAgICBleHRlbmRzIFRocmVhZExvY2FsPEhvbGRDb3VudGVyPiB7CisgICAgICAgICAgICBwdWJsaWMgSG9sZENvdW50ZXIgaW5pdGlhbFZhbHVlKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSG9sZENvdW50ZXIoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbnVtYmVyIG9mIHJlZW50cmFudCByZWFkIGxvY2tzIGhlbGQgYnkgY3VycmVudCB0aHJlYWQuCisgICAgICAgICAqIEluaXRpYWxpemVkIG9ubHkgaW4gY29uc3RydWN0b3IgYW5kIHJlYWRPYmplY3QuCisgICAgICAgICAqIFJlbW92ZWQgd2hlbmV2ZXIgYSB0aHJlYWQncyByZWFkIGhvbGQgY291bnQgZHJvcHMgdG8gMC4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgdHJhbnNpZW50IFRocmVhZExvY2FsSG9sZENvdW50ZXIgcmVhZEhvbGRzOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgaG9sZCBjb3VudCBvZiB0aGUgbGFzdCB0aHJlYWQgdG8gc3VjY2Vzc2Z1bGx5IGFjcXVpcmUKKyAgICAgICAgICogcmVhZExvY2suIFRoaXMgc2F2ZXMgVGhyZWFkTG9jYWwgbG9va3VwIGluIHRoZSBjb21tb24gY2FzZQorICAgICAgICAgKiB3aGVyZSB0aGUgbmV4dCB0aHJlYWQgdG8gcmVsZWFzZSBpcyB0aGUgbGFzdCBvbmUgdG8KKyAgICAgICAgICogYWNxdWlyZS4gVGhpcyBpcyBub24tdm9sYXRpbGUgc2luY2UgaXQgaXMganVzdCB1c2VkCisgICAgICAgICAqIGFzIGEgaGV1cmlzdGljLCBhbmQgd291bGQgYmUgZ3JlYXQgZm9yIHRocmVhZHMgdG8gY2FjaGUuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPkNhbiBvdXRsaXZlIHRoZSBUaHJlYWQgZm9yIHdoaWNoIGl0IGlzIGNhY2hpbmcgdGhlIHJlYWQKKyAgICAgICAgICogaG9sZCBjb3VudCwgYnV0IGF2b2lkcyBnYXJiYWdlIHJldGVudGlvbiBieSBub3QgcmV0YWluaW5nIGEKKyAgICAgICAgICogcmVmZXJlbmNlIHRvIHRoZSBUaHJlYWQuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPkFjY2Vzc2VkIHZpYSBhIGJlbmlnbiBkYXRhIHJhY2U7IHJlbGllcyBvbiB0aGUgbWVtb3J5CisgICAgICAgICAqIG1vZGVsJ3MgZmluYWwgZmllbGQgYW5kIG91dC1vZi10aGluLWFpciBndWFyYW50ZWVzLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSB0cmFuc2llbnQgSG9sZENvdW50ZXIgY2FjaGVkSG9sZENvdW50ZXI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIGZpcnN0UmVhZGVyIGlzIHRoZSBmaXJzdCB0aHJlYWQgdG8gaGF2ZSBhY3F1aXJlZCB0aGUgcmVhZCBsb2NrLgorICAgICAgICAgKiBmaXJzdFJlYWRlckhvbGRDb3VudCBpcyBmaXJzdFJlYWRlcidzIGhvbGQgY291bnQuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPk1vcmUgcHJlY2lzZWx5LCBmaXJzdFJlYWRlciBpcyB0aGUgdW5pcXVlIHRocmVhZCB0aGF0IGxhc3QKKyAgICAgICAgICogY2hhbmdlZCB0aGUgc2hhcmVkIGNvdW50IGZyb20gMCB0byAxLCBhbmQgaGFzIG5vdCByZWxlYXNlZCB0aGUKKyAgICAgICAgICogcmVhZCBsb2NrIHNpbmNlIHRoZW47IG51bGwgaWYgdGhlcmUgaXMgbm8gc3VjaCB0aHJlYWQuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPkNhbm5vdCBjYXVzZSBnYXJiYWdlIHJldGVudGlvbiB1bmxlc3MgdGhlIHRocmVhZCB0ZXJtaW5hdGVkCisgICAgICAgICAqIHdpdGhvdXQgcmVsaW5xdWlzaGluZyBpdHMgcmVhZCBsb2Nrcywgc2luY2UgdHJ5UmVsZWFzZVNoYXJlZAorICAgICAgICAgKiBzZXRzIGl0IHRvIG51bGwuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPkFjY2Vzc2VkIHZpYSBhIGJlbmlnbiBkYXRhIHJhY2U7IHJlbGllcyBvbiB0aGUgbWVtb3J5CisgICAgICAgICAqIG1vZGVsJ3Mgb3V0LW9mLXRoaW4tYWlyIGd1YXJhbnRlZXMgZm9yIHJlZmVyZW5jZXMuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPlRoaXMgYWxsb3dzIHRyYWNraW5nIG9mIHJlYWQgaG9sZHMgZm9yIHVuY29udGVuZGVkIHJlYWQKKyAgICAgICAgICogbG9ja3MgdG8gYmUgdmVyeSBjaGVhcC4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgdHJhbnNpZW50IFRocmVhZCBmaXJzdFJlYWRlciA9IG51bGw7CisgICAgICAgIHByaXZhdGUgdHJhbnNpZW50IGludCBmaXJzdFJlYWRlckhvbGRDb3VudDsKKworICAgICAgICBTeW5jKCkgeworICAgICAgICAgICAgcmVhZEhvbGRzID0gbmV3IFRocmVhZExvY2FsSG9sZENvdW50ZXIoKTsKKyAgICAgICAgICAgIHNldFN0YXRlKGdldFN0YXRlKCkpOyAvLyBlbnN1cmVzIHZpc2liaWxpdHkgb2YgcmVhZEhvbGRzCisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBBY3F1aXJlcyBhbmQgcmVsZWFzZXMgdXNlIHRoZSBzYW1lIGNvZGUgZm9yIGZhaXIgYW5kCisgICAgICAgICAqIG5vbmZhaXIgbG9ja3MsIGJ1dCBkaWZmZXIgaW4gd2hldGhlci9ob3cgdGhleSBhbGxvdyBiYXJnaW5nCisgICAgICAgICAqIHdoZW4gcXVldWVzIGFyZSBub24tZW1wdHkuCisgICAgICAgICAqLworCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGN1cnJlbnQgdGhyZWFkLCB3aGVuIHRyeWluZyB0byBhY3F1aXJlCisgICAgICAgICAqIHRoZSByZWFkIGxvY2ssIGFuZCBvdGhlcndpc2UgZWxpZ2libGUgdG8gZG8gc28sIHNob3VsZCBibG9jaworICAgICAgICAgKiBiZWNhdXNlIG9mIHBvbGljeSBmb3Igb3ZlcnRha2luZyBvdGhlciB3YWl0aW5nIHRocmVhZHMuCisgICAgICAgICAqLworICAgICAgICBhYnN0cmFjdCBib29sZWFuIHJlYWRlclNob3VsZEJsb2NrKCk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY3VycmVudCB0aHJlYWQsIHdoZW4gdHJ5aW5nIHRvIGFjcXVpcmUKKyAgICAgICAgICogdGhlIHdyaXRlIGxvY2ssIGFuZCBvdGhlcndpc2UgZWxpZ2libGUgdG8gZG8gc28sIHNob3VsZCBibG9jaworICAgICAgICAgKiBiZWNhdXNlIG9mIHBvbGljeSBmb3Igb3ZlcnRha2luZyBvdGhlciB3YWl0aW5nIHRocmVhZHMuCisgICAgICAgICAqLworICAgICAgICBhYnN0cmFjdCBib29sZWFuIHdyaXRlclNob3VsZEJsb2NrKCk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogTm90ZSB0aGF0IHRyeVJlbGVhc2UgYW5kIHRyeUFjcXVpcmUgY2FuIGJlIGNhbGxlZCBieQorICAgICAgICAgKiBDb25kaXRpb25zLiBTbyBpdCBpcyBwb3NzaWJsZSB0aGF0IHRoZWlyIGFyZ3VtZW50cyBjb250YWluCisgICAgICAgICAqIGJvdGggcmVhZCBhbmQgd3JpdGUgaG9sZHMgdGhhdCBhcmUgYWxsIHJlbGVhc2VkIGR1cmluZyBhCisgICAgICAgICAqIGNvbmRpdGlvbiB3YWl0IGFuZCByZS1lc3RhYmxpc2hlZCBpbiB0cnlBY3F1aXJlLgorICAgICAgICAgKi8KKworICAgICAgICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiB0cnlSZWxlYXNlKGludCByZWxlYXNlcykgeworICAgICAgICAgICAgaWYgKCFpc0hlbGRFeGNsdXNpdmVseSgpKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBpbnQgbmV4dGMgPSBnZXRTdGF0ZSgpIC0gcmVsZWFzZXM7CisgICAgICAgICAgICBib29sZWFuIGZyZWUgPSBleGNsdXNpdmVDb3VudChuZXh0YykgPT0gMDsKKyAgICAgICAgICAgIGlmIChmcmVlKQorICAgICAgICAgICAgICAgIHNldEV4Y2x1c2l2ZU93bmVyVGhyZWFkKG51bGwpOworICAgICAgICAgICAgc2V0U3RhdGUobmV4dGMpOworICAgICAgICAgICAgcmV0dXJuIGZyZWU7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiB0cnlBY3F1aXJlKGludCBhY3F1aXJlcykgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFdhbGt0aHJvdWdoOgorICAgICAgICAgICAgICogMS4gSWYgcmVhZCBjb3VudCBub256ZXJvIG9yIHdyaXRlIGNvdW50IG5vbnplcm8KKyAgICAgICAgICAgICAqICAgIGFuZCBvd25lciBpcyBhIGRpZmZlcmVudCB0aHJlYWQsIGZhaWwuCisgICAgICAgICAgICAgKiAyLiBJZiBjb3VudCB3b3VsZCBzYXR1cmF0ZSwgZmFpbC4gKFRoaXMgY2FuIG9ubHkKKyAgICAgICAgICAgICAqICAgIGhhcHBlbiBpZiBjb3VudCBpcyBhbHJlYWR5IG5vbnplcm8uKQorICAgICAgICAgICAgICogMy4gT3RoZXJ3aXNlLCB0aGlzIHRocmVhZCBpcyBlbGlnaWJsZSBmb3IgbG9jayBpZgorICAgICAgICAgICAgICogICAgaXQgaXMgZWl0aGVyIGEgcmVlbnRyYW50IGFjcXVpcmUgb3IKKyAgICAgICAgICAgICAqICAgIHF1ZXVlIHBvbGljeSBhbGxvd3MgaXQuIElmIHNvLCB1cGRhdGUgc3RhdGUKKyAgICAgICAgICAgICAqICAgIGFuZCBzZXQgb3duZXIuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIFRocmVhZCBjdXJyZW50ID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKyAgICAgICAgICAgIGludCBjID0gZ2V0U3RhdGUoKTsKKyAgICAgICAgICAgIGludCB3ID0gZXhjbHVzaXZlQ291bnQoYyk7CisgICAgICAgICAgICBpZiAoYyAhPSAwKSB7CisgICAgICAgICAgICAgICAgLy8gKE5vdGU6IGlmIGMgIT0gMCBhbmQgdyA9PSAwIHRoZW4gc2hhcmVkIGNvdW50ICE9IDApCisgICAgICAgICAgICAgICAgaWYgKHcgPT0gMCB8fCBjdXJyZW50ICE9IGdldEV4Y2x1c2l2ZU93bmVyVGhyZWFkKCkpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICBpZiAodyArIGV4Y2x1c2l2ZUNvdW50KGFjcXVpcmVzKSA+IE1BWF9DT1VOVCkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJNYXhpbXVtIGxvY2sgY291bnQgZXhjZWVkZWQiKTsKKyAgICAgICAgICAgICAgICAvLyBSZWVudHJhbnQgYWNxdWlyZQorICAgICAgICAgICAgICAgIHNldFN0YXRlKGMgKyBhY3F1aXJlcyk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAod3JpdGVyU2hvdWxkQmxvY2soKSB8fAorICAgICAgICAgICAgICAgICFjb21wYXJlQW5kU2V0U3RhdGUoYywgYyArIGFjcXVpcmVzKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICBzZXRFeGNsdXNpdmVPd25lclRocmVhZChjdXJyZW50KTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIGZpbmFsIGJvb2xlYW4gdHJ5UmVsZWFzZVNoYXJlZChpbnQgdW51c2VkKSB7CisgICAgICAgICAgICBUaHJlYWQgY3VycmVudCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisgICAgICAgICAgICBpZiAoZmlyc3RSZWFkZXIgPT0gY3VycmVudCkgeworICAgICAgICAgICAgICAgIC8vIGFzc2VydCBmaXJzdFJlYWRlckhvbGRDb3VudCA+IDA7CisgICAgICAgICAgICAgICAgaWYgKGZpcnN0UmVhZGVySG9sZENvdW50ID09IDEpCisgICAgICAgICAgICAgICAgICAgIGZpcnN0UmVhZGVyID0gbnVsbDsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIGZpcnN0UmVhZGVySG9sZENvdW50LS07CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIEhvbGRDb3VudGVyIHJoID0gY2FjaGVkSG9sZENvdW50ZXI7CisgICAgICAgICAgICAgICAgaWYgKHJoID09IG51bGwgfHwgcmgudGlkICE9IGN1cnJlbnQuZ2V0SWQoKSkKKyAgICAgICAgICAgICAgICAgICAgcmggPSByZWFkSG9sZHMuZ2V0KCk7CisgICAgICAgICAgICAgICAgaW50IGNvdW50ID0gcmguY291bnQ7CisgICAgICAgICAgICAgICAgaWYgKGNvdW50IDw9IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVhZEhvbGRzLnJlbW92ZSgpOworICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPD0gMCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IHVubWF0Y2hlZFVubG9ja0V4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAtLXJoLmNvdW50OworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIGludCBjID0gZ2V0U3RhdGUoKTsKKyAgICAgICAgICAgICAgICBpbnQgbmV4dGMgPSBjIC0gU0hBUkVEX1VOSVQ7CisgICAgICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXRTdGF0ZShjLCBuZXh0YykpCisgICAgICAgICAgICAgICAgICAgIC8vIFJlbGVhc2luZyB0aGUgcmVhZCBsb2NrIGhhcyBubyBlZmZlY3Qgb24gcmVhZGVycywKKyAgICAgICAgICAgICAgICAgICAgLy8gYnV0IGl0IG1heSBhbGxvdyB3YWl0aW5nIHdyaXRlcnMgdG8gcHJvY2VlZCBpZgorICAgICAgICAgICAgICAgICAgICAvLyBib3RoIHJlYWQgYW5kIHdyaXRlIGxvY2tzIGFyZSBub3cgZnJlZS4KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5leHRjID09IDA7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gdW5tYXRjaGVkVW5sb2NrRXhjZXB0aW9uKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJhdHRlbXB0IHRvIHVubG9jayByZWFkIGxvY2ssIG5vdCBsb2NrZWQgYnkgY3VycmVudCB0aHJlYWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCBmaW5hbCBpbnQgdHJ5QWNxdWlyZVNoYXJlZChpbnQgdW51c2VkKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogV2Fsa3Rocm91Z2g6CisgICAgICAgICAgICAgKiAxLiBJZiB3cml0ZSBsb2NrIGhlbGQgYnkgYW5vdGhlciB0aHJlYWQsIGZhaWwuCisgICAgICAgICAgICAgKiAyLiBPdGhlcndpc2UsIHRoaXMgdGhyZWFkIGlzIGVsaWdpYmxlIGZvcgorICAgICAgICAgICAgICogICAgbG9jayB3cnQgc3RhdGUsIHNvIGFzayBpZiBpdCBzaG91bGQgYmxvY2sKKyAgICAgICAgICAgICAqICAgIGJlY2F1c2Ugb2YgcXVldWUgcG9saWN5LiBJZiBub3QsIHRyeQorICAgICAgICAgICAgICogICAgdG8gZ3JhbnQgYnkgQ0FTaW5nIHN0YXRlIGFuZCB1cGRhdGluZyBjb3VudC4KKyAgICAgICAgICAgICAqICAgIE5vdGUgdGhhdCBzdGVwIGRvZXMgbm90IGNoZWNrIGZvciByZWVudHJhbnQKKyAgICAgICAgICAgICAqICAgIGFjcXVpcmVzLCB3aGljaCBpcyBwb3N0cG9uZWQgdG8gZnVsbCB2ZXJzaW9uCisgICAgICAgICAgICAgKiAgICB0byBhdm9pZCBoYXZpbmcgdG8gY2hlY2sgaG9sZCBjb3VudCBpbgorICAgICAgICAgICAgICogICAgdGhlIG1vcmUgdHlwaWNhbCBub24tcmVlbnRyYW50IGNhc2UuCisgICAgICAgICAgICAgKiAzLiBJZiBzdGVwIDIgZmFpbHMgZWl0aGVyIGJlY2F1c2UgdGhyZWFkCisgICAgICAgICAgICAgKiAgICBhcHBhcmVudGx5IG5vdCBlbGlnaWJsZSBvciBDQVMgZmFpbHMgb3IgY291bnQKKyAgICAgICAgICAgICAqICAgIHNhdHVyYXRlZCwgY2hhaW4gdG8gdmVyc2lvbiB3aXRoIGZ1bGwgcmV0cnkgbG9vcC4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgVGhyZWFkIGN1cnJlbnQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICAgICAgaW50IGMgPSBnZXRTdGF0ZSgpOworICAgICAgICAgICAgaWYgKGV4Y2x1c2l2ZUNvdW50KGMpICE9IDAgJiYKKyAgICAgICAgICAgICAgICBnZXRFeGNsdXNpdmVPd25lclRocmVhZCgpICE9IGN1cnJlbnQpCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgaW50IHIgPSBzaGFyZWRDb3VudChjKTsKKyAgICAgICAgICAgIGlmICghcmVhZGVyU2hvdWxkQmxvY2soKSAmJgorICAgICAgICAgICAgICAgIHIgPCBNQVhfQ09VTlQgJiYKKyAgICAgICAgICAgICAgICBjb21wYXJlQW5kU2V0U3RhdGUoYywgYyArIFNIQVJFRF9VTklUKSkgeworICAgICAgICAgICAgICAgIGlmIChyID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgZmlyc3RSZWFkZXIgPSBjdXJyZW50OworICAgICAgICAgICAgICAgICAgICBmaXJzdFJlYWRlckhvbGRDb3VudCA9IDE7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChmaXJzdFJlYWRlciA9PSBjdXJyZW50KSB7CisgICAgICAgICAgICAgICAgICAgIGZpcnN0UmVhZGVySG9sZENvdW50Kys7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgSG9sZENvdW50ZXIgcmggPSBjYWNoZWRIb2xkQ291bnRlcjsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHJoID09IG51bGwgfHwgcmgudGlkICE9IGN1cnJlbnQuZ2V0SWQoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlZEhvbGRDb3VudGVyID0gcmggPSByZWFkSG9sZHMuZ2V0KCk7CisgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJoLmNvdW50ID09IDApCisgICAgICAgICAgICAgICAgICAgICAgICByZWFkSG9sZHMuc2V0KHJoKTsKKyAgICAgICAgICAgICAgICAgICAgcmguY291bnQrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZnVsbFRyeUFjcXVpcmVTaGFyZWQoY3VycmVudCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogRnVsbCB2ZXJzaW9uIG9mIGFjcXVpcmUgZm9yIHJlYWRzLCB0aGF0IGhhbmRsZXMgQ0FTIG1pc3NlcworICAgICAgICAgKiBhbmQgcmVlbnRyYW50IHJlYWRzIG5vdCBkZWFsdCB3aXRoIGluIHRyeUFjcXVpcmVTaGFyZWQuCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBpbnQgZnVsbFRyeUFjcXVpcmVTaGFyZWQoVGhyZWFkIGN1cnJlbnQpIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBUaGlzIGNvZGUgaXMgaW4gcGFydCByZWR1bmRhbnQgd2l0aCB0aGF0IGluCisgICAgICAgICAgICAgKiB0cnlBY3F1aXJlU2hhcmVkIGJ1dCBpcyBzaW1wbGVyIG92ZXJhbGwgYnkgbm90CisgICAgICAgICAgICAgKiBjb21wbGljYXRpbmcgdHJ5QWNxdWlyZVNoYXJlZCB3aXRoIGludGVyYWN0aW9ucyBiZXR3ZWVuCisgICAgICAgICAgICAgKiByZXRyaWVzIGFuZCBsYXppbHkgcmVhZGluZyBob2xkIGNvdW50cy4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgSG9sZENvdW50ZXIgcmggPSBudWxsOworICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIGludCBjID0gZ2V0U3RhdGUoKTsKKyAgICAgICAgICAgICAgICBpZiAoZXhjbHVzaXZlQ291bnQoYykgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoZ2V0RXhjbHVzaXZlT3duZXJUaHJlYWQoKSAhPSBjdXJyZW50KQorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgICAgICAvLyBlbHNlIHdlIGhvbGQgdGhlIGV4Y2x1c2l2ZSBsb2NrOyBibG9ja2luZyBoZXJlCisgICAgICAgICAgICAgICAgICAgIC8vIHdvdWxkIGNhdXNlIGRlYWRsb2NrLgorICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVhZGVyU2hvdWxkQmxvY2soKSkgeworICAgICAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgd2UncmUgbm90IGFjcXVpcmluZyByZWFkIGxvY2sgcmVlbnRyYW50bHkKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZpcnN0UmVhZGVyID09IGN1cnJlbnQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFzc2VydCBmaXJzdFJlYWRlckhvbGRDb3VudCA+IDA7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmggPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJoID0gY2FjaGVkSG9sZENvdW50ZXI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJoID09IG51bGwgfHwgcmgudGlkICE9IGN1cnJlbnQuZ2V0SWQoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByaCA9IHJlYWRIb2xkcy5nZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJoLmNvdW50ID09IDApCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkSG9sZHMucmVtb3ZlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJoLmNvdW50ID09IDApCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChzaGFyZWRDb3VudChjKSA9PSBNQVhfQ09VTlQpCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiTWF4aW11bSBsb2NrIGNvdW50IGV4Y2VlZGVkIik7CisgICAgICAgICAgICAgICAgaWYgKGNvbXBhcmVBbmRTZXRTdGF0ZShjLCBjICsgU0hBUkVEX1VOSVQpKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChzaGFyZWRDb3VudChjKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdFJlYWRlciA9IGN1cnJlbnQ7CisgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdFJlYWRlckhvbGRDb3VudCA9IDE7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZmlyc3RSZWFkZXIgPT0gY3VycmVudCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RSZWFkZXJIb2xkQ291bnQrKzsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyaCA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJoID0gY2FjaGVkSG9sZENvdW50ZXI7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmggPT0gbnVsbCB8fCByaC50aWQgIT0gY3VycmVudC5nZXRJZCgpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJoID0gcmVhZEhvbGRzLmdldCgpOworICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAocmguY291bnQgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkSG9sZHMuc2V0KHJoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJoLmNvdW50Kys7CisgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZWRIb2xkQ291bnRlciA9IHJoOyAvLyBjYWNoZSBmb3IgcmVsZWFzZQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBQZXJmb3JtcyB0cnlMb2NrIGZvciB3cml0ZSwgZW5hYmxpbmcgYmFyZ2luZyBpbiBib3RoIG1vZGVzLgorICAgICAgICAgKiBUaGlzIGlzIGlkZW50aWNhbCBpbiBlZmZlY3QgdG8gdHJ5QWNxdWlyZSBleGNlcHQgZm9yIGxhY2sKKyAgICAgICAgICogb2YgY2FsbHMgdG8gd3JpdGVyU2hvdWxkQmxvY2suCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBib29sZWFuIHRyeVdyaXRlTG9jaygpIHsKKyAgICAgICAgICAgIFRocmVhZCBjdXJyZW50ID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKyAgICAgICAgICAgIGludCBjID0gZ2V0U3RhdGUoKTsKKyAgICAgICAgICAgIGlmIChjICE9IDApIHsKKyAgICAgICAgICAgICAgICBpbnQgdyA9IGV4Y2x1c2l2ZUNvdW50KGMpOworICAgICAgICAgICAgICAgIGlmICh3ID09IDAgfHwgY3VycmVudCAhPSBnZXRFeGNsdXNpdmVPd25lclRocmVhZCgpKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgaWYgKHcgPT0gTUFYX0NPVU5UKQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIk1heGltdW0gbG9jayBjb3VudCBleGNlZWRlZCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFjb21wYXJlQW5kU2V0U3RhdGUoYywgYyArIDEpKQorICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIHNldEV4Y2x1c2l2ZU93bmVyVGhyZWFkKGN1cnJlbnQpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUGVyZm9ybXMgdHJ5TG9jayBmb3IgcmVhZCwgZW5hYmxpbmcgYmFyZ2luZyBpbiBib3RoIG1vZGVzLgorICAgICAgICAgKiBUaGlzIGlzIGlkZW50aWNhbCBpbiBlZmZlY3QgdG8gdHJ5QWNxdWlyZVNoYXJlZCBleGNlcHQgZm9yCisgICAgICAgICAqIGxhY2sgb2YgY2FsbHMgdG8gcmVhZGVyU2hvdWxkQmxvY2suCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBib29sZWFuIHRyeVJlYWRMb2NrKCkgeworICAgICAgICAgICAgVGhyZWFkIGN1cnJlbnQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgICAgIGludCBjID0gZ2V0U3RhdGUoKTsKKyAgICAgICAgICAgICAgICBpZiAoZXhjbHVzaXZlQ291bnQoYykgIT0gMCAmJgorICAgICAgICAgICAgICAgICAgICBnZXRFeGNsdXNpdmVPd25lclRocmVhZCgpICE9IGN1cnJlbnQpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICBpbnQgciA9IHNoYXJlZENvdW50KGMpOworICAgICAgICAgICAgICAgIGlmIChyID09IE1BWF9DT1VOVCkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJNYXhpbXVtIGxvY2sgY291bnQgZXhjZWVkZWQiKTsKKyAgICAgICAgICAgICAgICBpZiAoY29tcGFyZUFuZFNldFN0YXRlKGMsIGMgKyBTSEFSRURfVU5JVCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHIgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RSZWFkZXIgPSBjdXJyZW50OworICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RSZWFkZXJIb2xkQ291bnQgPSAxOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGZpcnN0UmVhZGVyID09IGN1cnJlbnQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0UmVhZGVySG9sZENvdW50Kys7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBIb2xkQ291bnRlciByaCA9IGNhY2hlZEhvbGRDb3VudGVyOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJoID09IG51bGwgfHwgcmgudGlkICE9IGN1cnJlbnQuZ2V0SWQoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZWRIb2xkQ291bnRlciA9IHJoID0gcmVhZEhvbGRzLmdldCgpOworICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAocmguY291bnQgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkSG9sZHMuc2V0KHJoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJoLmNvdW50Kys7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIGZpbmFsIGJvb2xlYW4gaXNIZWxkRXhjbHVzaXZlbHkoKSB7CisgICAgICAgICAgICAvLyBXaGlsZSB3ZSBtdXN0IGluIGdlbmVyYWwgcmVhZCBzdGF0ZSBiZWZvcmUgb3duZXIsCisgICAgICAgICAgICAvLyB3ZSBkb24ndCBuZWVkIHRvIGRvIHNvIHRvIGNoZWNrIGlmIGN1cnJlbnQgdGhyZWFkIGlzIG93bmVyCisgICAgICAgICAgICByZXR1cm4gZ2V0RXhjbHVzaXZlT3duZXJUaHJlYWQoKSA9PSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gTWV0aG9kcyByZWxheWVkIHRvIG91dGVyIGNsYXNzCisKKyAgICAgICAgZmluYWwgQ29uZGl0aW9uT2JqZWN0IG5ld0NvbmRpdGlvbigpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQ29uZGl0aW9uT2JqZWN0KCk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBUaHJlYWQgZ2V0T3duZXIoKSB7CisgICAgICAgICAgICAvLyBNdXN0IHJlYWQgc3RhdGUgYmVmb3JlIG93bmVyIHRvIGVuc3VyZSBtZW1vcnkgY29uc2lzdGVuY3kKKyAgICAgICAgICAgIHJldHVybiAoKGV4Y2x1c2l2ZUNvdW50KGdldFN0YXRlKCkpID09IDApID8KKyAgICAgICAgICAgICAgICAgICAgbnVsbCA6CisgICAgICAgICAgICAgICAgICAgIGdldEV4Y2x1c2l2ZU93bmVyVGhyZWFkKCkpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgaW50IGdldFJlYWRMb2NrQ291bnQoKSB7CisgICAgICAgICAgICByZXR1cm4gc2hhcmVkQ291bnQoZ2V0U3RhdGUoKSk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBib29sZWFuIGlzV3JpdGVMb2NrZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gZXhjbHVzaXZlQ291bnQoZ2V0U3RhdGUoKSkgIT0gMDsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGludCBnZXRXcml0ZUhvbGRDb3VudCgpIHsKKyAgICAgICAgICAgIHJldHVybiBpc0hlbGRFeGNsdXNpdmVseSgpID8gZXhjbHVzaXZlQ291bnQoZ2V0U3RhdGUoKSkgOiAwOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgaW50IGdldFJlYWRIb2xkQ291bnQoKSB7CisgICAgICAgICAgICBpZiAoZ2V0UmVhZExvY2tDb3VudCgpID09IDApCisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisKKyAgICAgICAgICAgIFRocmVhZCBjdXJyZW50ID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKyAgICAgICAgICAgIGlmIChmaXJzdFJlYWRlciA9PSBjdXJyZW50KQorICAgICAgICAgICAgICAgIHJldHVybiBmaXJzdFJlYWRlckhvbGRDb3VudDsKKworICAgICAgICAgICAgSG9sZENvdW50ZXIgcmggPSBjYWNoZWRIb2xkQ291bnRlcjsKKyAgICAgICAgICAgIGlmIChyaCAhPSBudWxsICYmIHJoLnRpZCA9PSBjdXJyZW50LmdldElkKCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIHJoLmNvdW50OworCisgICAgICAgICAgICBpbnQgY291bnQgPSByZWFkSG9sZHMuZ2V0KCkuY291bnQ7CisgICAgICAgICAgICBpZiAoY291bnQgPT0gMCkgcmVhZEhvbGRzLnJlbW92ZSgpOworICAgICAgICAgICAgcmV0dXJuIGNvdW50OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJlY29uc3RpdHV0ZSB0aGlzIGxvY2sgaW5zdGFuY2UgZnJvbSBhIHN0cmVhbQorICAgICAgICAgKiBAcGFyYW0gcyB0aGUgc3RyZWFtCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtIHMpCisgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisgICAgICAgICAgICByZWFkSG9sZHMgPSBuZXcgVGhyZWFkTG9jYWxIb2xkQ291bnRlcigpOworICAgICAgICAgICAgc2V0U3RhdGUoMCk7IC8vIHJlc2V0IHRvIHVubG9ja2VkIHN0YXRlCisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBpbnQgZ2V0Q291bnQoKSB7IHJldHVybiBnZXRTdGF0ZSgpOyB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTm9uZmFpciB2ZXJzaW9uIG9mIFN5bmMKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgY2xhc3MgTm9uZmFpclN5bmMgZXh0ZW5kcyBTeW5jIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTgxNTk2MjU1MzU2NTQzOTUwMzdMOworICAgICAgICBmaW5hbCBib29sZWFuIHdyaXRlclNob3VsZEJsb2NrKCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyB3cml0ZXJzIGNhbiBhbHdheXMgYmFyZ2UKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBib29sZWFuIHJlYWRlclNob3VsZEJsb2NrKCkgeworICAgICAgICAgICAgLyogQXMgYSBoZXVyaXN0aWMgdG8gYXZvaWQgaW5kZWZpbml0ZSB3cml0ZXIgc3RhcnZhdGlvbiwKKyAgICAgICAgICAgICAqIGJsb2NrIGlmIHRoZSB0aHJlYWQgdGhhdCBtb21lbnRhcmlseSBhcHBlYXJzIHRvIGJlIGhlYWQKKyAgICAgICAgICAgICAqIG9mIHF1ZXVlLCBpZiBvbmUgZXhpc3RzLCBpcyBhIHdhaXRpbmcgd3JpdGVyLiAgVGhpcyBpcworICAgICAgICAgICAgICogb25seSBhIHByb2JhYmlsaXN0aWMgZWZmZWN0IHNpbmNlIGEgbmV3IHJlYWRlciB3aWxsIG5vdAorICAgICAgICAgICAgICogYmxvY2sgaWYgdGhlcmUgaXMgYSB3YWl0aW5nIHdyaXRlciBiZWhpbmQgb3RoZXIgZW5hYmxlZAorICAgICAgICAgICAgICogcmVhZGVycyB0aGF0IGhhdmUgbm90IHlldCBkcmFpbmVkIGZyb20gdGhlIHF1ZXVlLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICByZXR1cm4gYXBwYXJlbnRseUZpcnN0UXVldWVkSXNFeGNsdXNpdmUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZhaXIgdmVyc2lvbiBvZiBTeW5jCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIEZhaXJTeW5jIGV4dGVuZHMgU3luYyB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yMjc0OTkwOTI2NTkzMTYxNDUxTDsKKyAgICAgICAgZmluYWwgYm9vbGVhbiB3cml0ZXJTaG91bGRCbG9jaygpIHsKKyAgICAgICAgICAgIHJldHVybiBoYXNRdWV1ZWRQcmVkZWNlc3NvcnMoKTsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBib29sZWFuIHJlYWRlclNob3VsZEJsb2NrKCkgeworICAgICAgICAgICAgcmV0dXJuIGhhc1F1ZXVlZFByZWRlY2Vzc29ycygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGxvY2sgcmV0dXJuZWQgYnkgbWV0aG9kIHtAbGluayBSZWVudHJhbnRSZWFkV3JpdGVMb2NrI3JlYWRMb2NrfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFJlYWRMb2NrIGltcGxlbWVudHMgTG9jaywgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTk5MjQ0ODY0NjQwNzY5MDE2NEw7CisgICAgICAgIHByaXZhdGUgZmluYWwgU3luYyBzeW5jOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb25zdHJ1Y3RvciBmb3IgdXNlIGJ5IHN1YmNsYXNzZXMKKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIGxvY2sgdGhlIG91dGVyIGxvY2sgb2JqZWN0CisgICAgICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGxvY2sgaXMgbnVsbAorICAgICAgICAgKi8KKyAgICAgICAgcHJvdGVjdGVkIFJlYWRMb2NrKFJlZW50cmFudFJlYWRXcml0ZUxvY2sgbG9jaykgeworICAgICAgICAgICAgc3luYyA9IGxvY2suc3luYzsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBBY3F1aXJlcyB0aGUgcmVhZCBsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5BY3F1aXJlcyB0aGUgcmVhZCBsb2NrIGlmIHRoZSB3cml0ZSBsb2NrIGlzIG5vdCBoZWxkIGJ5CisgICAgICAgICAqIGFub3RoZXIgdGhyZWFkIGFuZCByZXR1cm5zIGltbWVkaWF0ZWx5LgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5JZiB0aGUgd3JpdGUgbG9jayBpcyBoZWxkIGJ5IGFub3RoZXIgdGhyZWFkIHRoZW4KKyAgICAgICAgICogdGhlIGN1cnJlbnQgdGhyZWFkIGJlY29tZXMgZGlzYWJsZWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nCisgICAgICAgICAqIHB1cnBvc2VzIGFuZCBsaWVzIGRvcm1hbnQgdW50aWwgdGhlIHJlYWQgbG9jayBoYXMgYmVlbiBhY3F1aXJlZC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyB2b2lkIGxvY2soKSB7CisgICAgICAgICAgICBzeW5jLmFjcXVpcmVTaGFyZWQoMSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQWNxdWlyZXMgdGhlIHJlYWQgbG9jayB1bmxlc3MgdGhlIGN1cnJlbnQgdGhyZWFkIGlzCisgICAgICAgICAqIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0ZWR9LgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5BY3F1aXJlcyB0aGUgcmVhZCBsb2NrIGlmIHRoZSB3cml0ZSBsb2NrIGlzIG5vdCBoZWxkCisgICAgICAgICAqIGJ5IGFub3RoZXIgdGhyZWFkIGFuZCByZXR1cm5zIGltbWVkaWF0ZWx5LgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5JZiB0aGUgd3JpdGUgbG9jayBpcyBoZWxkIGJ5IGFub3RoZXIgdGhyZWFkIHRoZW4gdGhlCisgICAgICAgICAqIGN1cnJlbnQgdGhyZWFkIGJlY29tZXMgZGlzYWJsZWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nCisgICAgICAgICAqIHB1cnBvc2VzIGFuZCBsaWVzIGRvcm1hbnQgdW50aWwgb25lIG9mIHR3byB0aGluZ3MgaGFwcGVuczoKKyAgICAgICAgICoKKyAgICAgICAgICogPHVsPgorICAgICAgICAgKgorICAgICAgICAgKiA8bGk+VGhlIHJlYWQgbG9jayBpcyBhY3F1aXJlZCBieSB0aGUgY3VycmVudCB0aHJlYWQ7IG9yCisgICAgICAgICAqCisgICAgICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdHN9CisgICAgICAgICAqIHRoZSBjdXJyZW50IHRocmVhZC4KKyAgICAgICAgICoKKyAgICAgICAgICogPC91bD4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+SWYgdGhlIGN1cnJlbnQgdGhyZWFkOgorICAgICAgICAgKgorICAgICAgICAgKiA8dWw+CisgICAgICAgICAqCisgICAgICAgICAqIDxsaT5oYXMgaXRzIGludGVycnVwdGVkIHN0YXR1cyBzZXQgb24gZW50cnkgdG8gdGhpcyBtZXRob2Q7IG9yCisgICAgICAgICAqCisgICAgICAgICAqIDxsaT5pcyB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfSB3aGlsZQorICAgICAgICAgKiBhY3F1aXJpbmcgdGhlIHJlYWQgbG9jaywKKyAgICAgICAgICoKKyAgICAgICAgICogPC91bD4KKyAgICAgICAgICoKKyAgICAgICAgICogdGhlbiB7QGxpbmsgSW50ZXJydXB0ZWRFeGNlcHRpb259IGlzIHRocm93biBhbmQgdGhlIGN1cnJlbnQKKyAgICAgICAgICogdGhyZWFkJ3MgaW50ZXJydXB0ZWQgc3RhdHVzIGlzIGNsZWFyZWQuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPkluIHRoaXMgaW1wbGVtZW50YXRpb24sIGFzIHRoaXMgbWV0aG9kIGlzIGFuIGV4cGxpY2l0CisgICAgICAgICAqIGludGVycnVwdGlvbiBwb2ludCwgcHJlZmVyZW5jZSBpcyBnaXZlbiB0byByZXNwb25kaW5nIHRvCisgICAgICAgICAqIHRoZSBpbnRlcnJ1cHQgb3ZlciBub3JtYWwgb3IgcmVlbnRyYW50IGFjcXVpc2l0aW9uIG9mIHRoZQorICAgICAgICAgKiBsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IHRocmVhZCBpcyBpbnRlcnJ1cHRlZAorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHZvaWQgbG9ja0ludGVycnVwdGlibHkoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICAgICAgc3luYy5hY3F1aXJlU2hhcmVkSW50ZXJydXB0aWJseSgxKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBBY3F1aXJlcyB0aGUgcmVhZCBsb2NrIG9ubHkgaWYgdGhlIHdyaXRlIGxvY2sgaXMgbm90IGhlbGQgYnkKKyAgICAgICAgICogYW5vdGhlciB0aHJlYWQgYXQgdGhlIHRpbWUgb2YgaW52b2NhdGlvbi4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+QWNxdWlyZXMgdGhlIHJlYWQgbG9jayBpZiB0aGUgd3JpdGUgbG9jayBpcyBub3QgaGVsZCBieQorICAgICAgICAgKiBhbm90aGVyIHRocmVhZCBhbmQgcmV0dXJucyBpbW1lZGlhdGVseSB3aXRoIHRoZSB2YWx1ZQorICAgICAgICAgKiB7QGNvZGUgdHJ1ZX0uIEV2ZW4gd2hlbiB0aGlzIGxvY2sgaGFzIGJlZW4gc2V0IHRvIHVzZSBhCisgICAgICAgICAqIGZhaXIgb3JkZXJpbmcgcG9saWN5LCBhIGNhbGwgdG8ge0Bjb2RlIHRyeUxvY2soKX0KKyAgICAgICAgICogPGVtPndpbGw8L2VtPiBpbW1lZGlhdGVseSBhY3F1aXJlIHRoZSByZWFkIGxvY2sgaWYgaXQgaXMKKyAgICAgICAgICogYXZhaWxhYmxlLCB3aGV0aGVyIG9yIG5vdCBvdGhlciB0aHJlYWRzIGFyZSBjdXJyZW50bHkKKyAgICAgICAgICogd2FpdGluZyBmb3IgdGhlIHJlYWQgbG9jay4gIFRoaXMgJnF1b3Q7YmFyZ2luZyZxdW90OyBiZWhhdmlvcgorICAgICAgICAgKiBjYW4gYmUgdXNlZnVsIGluIGNlcnRhaW4gY2lyY3Vtc3RhbmNlcywgZXZlbiB0aG91Z2ggaXQKKyAgICAgICAgICogYnJlYWtzIGZhaXJuZXNzLiBJZiB5b3Ugd2FudCB0byBob25vciB0aGUgZmFpcm5lc3Mgc2V0dGluZworICAgICAgICAgKiBmb3IgdGhpcyBsb2NrLCB0aGVuIHVzZSB7QGxpbmsgI3RyeUxvY2sobG9uZywgVGltZVVuaXQpCisgICAgICAgICAqIHRyeUxvY2soMCwgVGltZVVuaXQuU0VDT05EUykgfSB3aGljaCBpcyBhbG1vc3QgZXF1aXZhbGVudAorICAgICAgICAgKiAoaXQgYWxzbyBkZXRlY3RzIGludGVycnVwdGlvbikuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPklmIHRoZSB3cml0ZSBsb2NrIGlzIGhlbGQgYnkgYW5vdGhlciB0aHJlYWQgdGhlbgorICAgICAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiBpbW1lZGlhdGVseSB3aXRoIHRoZSB2YWx1ZQorICAgICAgICAgKiB7QGNvZGUgZmFsc2V9LgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgcmVhZCBsb2NrIHdhcyBhY3F1aXJlZAorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljICBib29sZWFuIHRyeUxvY2soKSB7CisgICAgICAgICAgICByZXR1cm4gc3luYy50cnlSZWFkTG9jaygpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEFjcXVpcmVzIHRoZSByZWFkIGxvY2sgaWYgdGhlIHdyaXRlIGxvY2sgaXMgbm90IGhlbGQgYnkKKyAgICAgICAgICogYW5vdGhlciB0aHJlYWQgd2l0aGluIHRoZSBnaXZlbiB3YWl0aW5nIHRpbWUgYW5kIHRoZQorICAgICAgICAgKiBjdXJyZW50IHRocmVhZCBoYXMgbm90IGJlZW4ge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdAorICAgICAgICAgKiBpbnRlcnJ1cHRlZH0uCisgICAgICAgICAqCisgICAgICAgICAqIDxwPkFjcXVpcmVzIHRoZSByZWFkIGxvY2sgaWYgdGhlIHdyaXRlIGxvY2sgaXMgbm90IGhlbGQgYnkKKyAgICAgICAgICogYW5vdGhlciB0aHJlYWQgYW5kIHJldHVybnMgaW1tZWRpYXRlbHkgd2l0aCB0aGUgdmFsdWUKKyAgICAgICAgICoge0Bjb2RlIHRydWV9LiBJZiB0aGlzIGxvY2sgaGFzIGJlZW4gc2V0IHRvIHVzZSBhIGZhaXIKKyAgICAgICAgICogb3JkZXJpbmcgcG9saWN5IHRoZW4gYW4gYXZhaWxhYmxlIGxvY2sgPGVtPndpbGwgbm90PC9lbT4gYmUKKyAgICAgICAgICogYWNxdWlyZWQgaWYgYW55IG90aGVyIHRocmVhZHMgYXJlIHdhaXRpbmcgZm9yIHRoZQorICAgICAgICAgKiBsb2NrLiBUaGlzIGlzIGluIGNvbnRyYXN0IHRvIHRoZSB7QGxpbmsgI3RyeUxvY2soKX0KKyAgICAgICAgICogbWV0aG9kLiBJZiB5b3Ugd2FudCBhIHRpbWVkIHtAY29kZSB0cnlMb2NrfSB0aGF0IGRvZXMKKyAgICAgICAgICogcGVybWl0IGJhcmdpbmcgb24gYSBmYWlyIGxvY2sgdGhlbiBjb21iaW5lIHRoZSB0aW1lZCBhbmQKKyAgICAgICAgICogdW4tdGltZWQgZm9ybXMgdG9nZXRoZXI6CisgICAgICAgICAqCisgICAgICAgICAqIDxwcmU+aWYgKGxvY2sudHJ5TG9jaygpIHx8IGxvY2sudHJ5TG9jayh0aW1lb3V0LCB1bml0KSApIHsgLi4uIH0KKyAgICAgICAgICogPC9wcmU+CisgICAgICAgICAqCisgICAgICAgICAqIDxwPklmIHRoZSB3cml0ZSBsb2NrIGlzIGhlbGQgYnkgYW5vdGhlciB0aHJlYWQgdGhlbiB0aGUKKyAgICAgICAgICogY3VycmVudCB0aHJlYWQgYmVjb21lcyBkaXNhYmxlZCBmb3IgdGhyZWFkIHNjaGVkdWxpbmcKKyAgICAgICAgICogcHVycG9zZXMgYW5kIGxpZXMgZG9ybWFudCB1bnRpbCBvbmUgb2YgdGhyZWUgdGhpbmdzIGhhcHBlbnM6CisgICAgICAgICAqCisgICAgICAgICAqIDx1bD4KKyAgICAgICAgICoKKyAgICAgICAgICogPGxpPlRoZSByZWFkIGxvY2sgaXMgYWNxdWlyZWQgYnkgdGhlIGN1cnJlbnQgdGhyZWFkOyBvcgorICAgICAgICAgKgorICAgICAgICAgKiA8bGk+U29tZSBvdGhlciB0aHJlYWQge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRzfQorICAgICAgICAgKiB0aGUgY3VycmVudCB0aHJlYWQ7IG9yCisgICAgICAgICAqCisgICAgICAgICAqIDxsaT5UaGUgc3BlY2lmaWVkIHdhaXRpbmcgdGltZSBlbGFwc2VzLgorICAgICAgICAgKgorICAgICAgICAgKiA8L3VsPgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5JZiB0aGUgcmVhZCBsb2NrIGlzIGFjcXVpcmVkIHRoZW4gdGhlIHZhbHVlIHtAY29kZSB0cnVlfSBpcworICAgICAgICAgKiByZXR1cm5lZC4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+SWYgdGhlIGN1cnJlbnQgdGhyZWFkOgorICAgICAgICAgKgorICAgICAgICAgKiA8dWw+CisgICAgICAgICAqCisgICAgICAgICAqIDxsaT5oYXMgaXRzIGludGVycnVwdGVkIHN0YXR1cyBzZXQgb24gZW50cnkgdG8gdGhpcyBtZXRob2Q7IG9yCisgICAgICAgICAqCisgICAgICAgICAqIDxsaT5pcyB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfSB3aGlsZQorICAgICAgICAgKiBhY3F1aXJpbmcgdGhlIHJlYWQgbG9jaywKKyAgICAgICAgICoKKyAgICAgICAgICogPC91bD4gdGhlbiB7QGxpbmsgSW50ZXJydXB0ZWRFeGNlcHRpb259IGlzIHRocm93biBhbmQgdGhlCisgICAgICAgICAqIGN1cnJlbnQgdGhyZWFkJ3MgaW50ZXJydXB0ZWQgc3RhdHVzIGlzIGNsZWFyZWQuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPklmIHRoZSBzcGVjaWZpZWQgd2FpdGluZyB0aW1lIGVsYXBzZXMgdGhlbiB0aGUgdmFsdWUKKyAgICAgICAgICoge0Bjb2RlIGZhbHNlfSBpcyByZXR1cm5lZC4gIElmIHRoZSB0aW1lIGlzIGxlc3MgdGhhbiBvcgorICAgICAgICAgKiBlcXVhbCB0byB6ZXJvLCB0aGUgbWV0aG9kIHdpbGwgbm90IHdhaXQgYXQgYWxsLgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5JbiB0aGlzIGltcGxlbWVudGF0aW9uLCBhcyB0aGlzIG1ldGhvZCBpcyBhbiBleHBsaWNpdAorICAgICAgICAgKiBpbnRlcnJ1cHRpb24gcG9pbnQsIHByZWZlcmVuY2UgaXMgZ2l2ZW4gdG8gcmVzcG9uZGluZyB0bworICAgICAgICAgKiB0aGUgaW50ZXJydXB0IG92ZXIgbm9ybWFsIG9yIHJlZW50cmFudCBhY3F1aXNpdGlvbiBvZiB0aGUKKyAgICAgICAgICogbG9jaywgYW5kIG92ZXIgcmVwb3J0aW5nIHRoZSBlbGFwc2Ugb2YgdGhlIHdhaXRpbmcgdGltZS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIHRpbWVvdXQgdGhlIHRpbWUgdG8gd2FpdCBmb3IgdGhlIHJlYWQgbG9jaworICAgICAgICAgKiBAcGFyYW0gdW5pdCB0aGUgdGltZSB1bml0IG9mIHRoZSB0aW1lb3V0IGFyZ3VtZW50CisgICAgICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSByZWFkIGxvY2sgd2FzIGFjcXVpcmVkCisgICAgICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkCisgICAgICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHRpbWUgdW5pdCBpcyBudWxsCisgICAgICAgICAqCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgYm9vbGVhbiB0cnlMb2NrKGxvbmcgdGltZW91dCwgVGltZVVuaXQgdW5pdCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHN5bmMudHJ5QWNxdWlyZVNoYXJlZE5hbm9zKDEsIHVuaXQudG9OYW5vcyh0aW1lb3V0KSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQXR0ZW1wdHMgdG8gcmVsZWFzZSB0aGlzIGxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIDxwPiBJZiB0aGUgbnVtYmVyIG9mIHJlYWRlcnMgaXMgbm93IHplcm8gdGhlbiB0aGUgbG9jaworICAgICAgICAgKiBpcyBtYWRlIGF2YWlsYWJsZSBmb3Igd3JpdGUgbG9jayBhdHRlbXB0cy4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyAgdm9pZCB1bmxvY2soKSB7CisgICAgICAgICAgICBzeW5jLnJlbGVhc2VTaGFyZWQoMSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogVGhyb3dzIHtAY29kZSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gYmVjYXVzZQorICAgICAgICAgKiB7QGNvZGUgUmVhZExvY2tzfSBkbyBub3Qgc3VwcG9ydCBjb25kaXRpb25zLgorICAgICAgICAgKgorICAgICAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGFsd2F5cworICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIENvbmRpdGlvbiBuZXdDb25kaXRpb24oKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGlkZW50aWZ5aW5nIHRoaXMgbG9jaywgYXMgd2VsbCBhcyBpdHMgbG9jayBzdGF0ZS4KKyAgICAgICAgICogVGhlIHN0YXRlLCBpbiBicmFja2V0cywgaW5jbHVkZXMgdGhlIFN0cmluZyB7QGNvZGUgIlJlYWQgbG9ja3MgPSJ9CisgICAgICAgICAqIGZvbGxvd2VkIGJ5IHRoZSBudW1iZXIgb2YgaGVsZCByZWFkIGxvY2tzLgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIGlkZW50aWZ5aW5nIHRoaXMgbG9jaywgYXMgd2VsbCBhcyBpdHMgbG9jayBzdGF0ZQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIGludCByID0gc3luYy5nZXRSZWFkTG9ja0NvdW50KCk7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKSArCisgICAgICAgICAgICAgICAgIltSZWFkIGxvY2tzID0gIiArIHIgKyAiXSI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgbG9jayByZXR1cm5lZCBieSBtZXRob2Qge0BsaW5rIFJlZW50cmFudFJlYWRXcml0ZUxvY2sjd3JpdGVMb2NrfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFdyaXRlTG9jayBpbXBsZW1lbnRzIExvY2ssIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQ5OTI0NDg2NDY0MDc2OTAxNjRMOworICAgICAgICBwcml2YXRlIGZpbmFsIFN5bmMgc3luYzsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0b3IgZm9yIHVzZSBieSBzdWJjbGFzc2VzCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBsb2NrIHRoZSBvdXRlciBsb2NrIG9iamVjdAorICAgICAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBsb2NrIGlzIG51bGwKKyAgICAgICAgICovCisgICAgICAgIHByb3RlY3RlZCBXcml0ZUxvY2soUmVlbnRyYW50UmVhZFdyaXRlTG9jayBsb2NrKSB7CisgICAgICAgICAgICBzeW5jID0gbG9jay5zeW5jOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEFjcXVpcmVzIHRoZSB3cml0ZSBsb2NrLgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5BY3F1aXJlcyB0aGUgd3JpdGUgbG9jayBpZiBuZWl0aGVyIHRoZSByZWFkIG5vciB3cml0ZSBsb2NrCisgICAgICAgICAqIGFyZSBoZWxkIGJ5IGFub3RoZXIgdGhyZWFkCisgICAgICAgICAqIGFuZCByZXR1cm5zIGltbWVkaWF0ZWx5LCBzZXR0aW5nIHRoZSB3cml0ZSBsb2NrIGhvbGQgY291bnQgdG8KKyAgICAgICAgICogb25lLgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5JZiB0aGUgY3VycmVudCB0aHJlYWQgYWxyZWFkeSBob2xkcyB0aGUgd3JpdGUgbG9jayB0aGVuIHRoZQorICAgICAgICAgKiBob2xkIGNvdW50IGlzIGluY3JlbWVudGVkIGJ5IG9uZSBhbmQgdGhlIG1ldGhvZCByZXR1cm5zCisgICAgICAgICAqIGltbWVkaWF0ZWx5LgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5JZiB0aGUgbG9jayBpcyBoZWxkIGJ5IGFub3RoZXIgdGhyZWFkIHRoZW4gdGhlIGN1cnJlbnQKKyAgICAgICAgICogdGhyZWFkIGJlY29tZXMgZGlzYWJsZWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nIHB1cnBvc2VzIGFuZAorICAgICAgICAgKiBsaWVzIGRvcm1hbnQgdW50aWwgdGhlIHdyaXRlIGxvY2sgaGFzIGJlZW4gYWNxdWlyZWQsIGF0IHdoaWNoCisgICAgICAgICAqIHRpbWUgdGhlIHdyaXRlIGxvY2sgaG9sZCBjb3VudCBpcyBzZXQgdG8gb25lLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHZvaWQgbG9jaygpIHsKKyAgICAgICAgICAgIHN5bmMuYWNxdWlyZSgxKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBBY3F1aXJlcyB0aGUgd3JpdGUgbG9jayB1bmxlc3MgdGhlIGN1cnJlbnQgdGhyZWFkIGlzCisgICAgICAgICAqIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0ZWR9LgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5BY3F1aXJlcyB0aGUgd3JpdGUgbG9jayBpZiBuZWl0aGVyIHRoZSByZWFkIG5vciB3cml0ZSBsb2NrCisgICAgICAgICAqIGFyZSBoZWxkIGJ5IGFub3RoZXIgdGhyZWFkCisgICAgICAgICAqIGFuZCByZXR1cm5zIGltbWVkaWF0ZWx5LCBzZXR0aW5nIHRoZSB3cml0ZSBsb2NrIGhvbGQgY291bnQgdG8KKyAgICAgICAgICogb25lLgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5JZiB0aGUgY3VycmVudCB0aHJlYWQgYWxyZWFkeSBob2xkcyB0aGlzIGxvY2sgdGhlbiB0aGUKKyAgICAgICAgICogaG9sZCBjb3VudCBpcyBpbmNyZW1lbnRlZCBieSBvbmUgYW5kIHRoZSBtZXRob2QgcmV0dXJucworICAgICAgICAgKiBpbW1lZGlhdGVseS4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+SWYgdGhlIGxvY2sgaXMgaGVsZCBieSBhbm90aGVyIHRocmVhZCB0aGVuIHRoZSBjdXJyZW50CisgICAgICAgICAqIHRocmVhZCBiZWNvbWVzIGRpc2FibGVkIGZvciB0aHJlYWQgc2NoZWR1bGluZyBwdXJwb3NlcyBhbmQKKyAgICAgICAgICogbGllcyBkb3JtYW50IHVudGlsIG9uZSBvZiB0d28gdGhpbmdzIGhhcHBlbnM6CisgICAgICAgICAqCisgICAgICAgICAqIDx1bD4KKyAgICAgICAgICoKKyAgICAgICAgICogPGxpPlRoZSB3cml0ZSBsb2NrIGlzIGFjcXVpcmVkIGJ5IHRoZSBjdXJyZW50IHRocmVhZDsgb3IKKyAgICAgICAgICoKKyAgICAgICAgICogPGxpPlNvbWUgb3RoZXIgdGhyZWFkIHtAbGlua3BsYWluIFRocmVhZCNpbnRlcnJ1cHQgaW50ZXJydXB0c30KKyAgICAgICAgICogdGhlIGN1cnJlbnQgdGhyZWFkLgorICAgICAgICAgKgorICAgICAgICAgKiA8L3VsPgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5JZiB0aGUgd3JpdGUgbG9jayBpcyBhY3F1aXJlZCBieSB0aGUgY3VycmVudCB0aHJlYWQgdGhlbiB0aGUKKyAgICAgICAgICogbG9jayBob2xkIGNvdW50IGlzIHNldCB0byBvbmUuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPklmIHRoZSBjdXJyZW50IHRocmVhZDoKKyAgICAgICAgICoKKyAgICAgICAgICogPHVsPgorICAgICAgICAgKgorICAgICAgICAgKiA8bGk+aGFzIGl0cyBpbnRlcnJ1cHRlZCBzdGF0dXMgc2V0IG9uIGVudHJ5IHRvIHRoaXMgbWV0aG9kOworICAgICAgICAgKiBvcgorICAgICAgICAgKgorICAgICAgICAgKiA8bGk+aXMge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRlZH0gd2hpbGUKKyAgICAgICAgICogYWNxdWlyaW5nIHRoZSB3cml0ZSBsb2NrLAorICAgICAgICAgKgorICAgICAgICAgKiA8L3VsPgorICAgICAgICAgKgorICAgICAgICAgKiB0aGVuIHtAbGluayBJbnRlcnJ1cHRlZEV4Y2VwdGlvbn0gaXMgdGhyb3duIGFuZCB0aGUgY3VycmVudAorICAgICAgICAgKiB0aHJlYWQncyBpbnRlcnJ1cHRlZCBzdGF0dXMgaXMgY2xlYXJlZC4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+SW4gdGhpcyBpbXBsZW1lbnRhdGlvbiwgYXMgdGhpcyBtZXRob2QgaXMgYW4gZXhwbGljaXQKKyAgICAgICAgICogaW50ZXJydXB0aW9uIHBvaW50LCBwcmVmZXJlbmNlIGlzIGdpdmVuIHRvIHJlc3BvbmRpbmcgdG8KKyAgICAgICAgICogdGhlIGludGVycnVwdCBvdmVyIG5vcm1hbCBvciByZWVudHJhbnQgYWNxdWlzaXRpb24gb2YgdGhlCisgICAgICAgICAqIGxvY2suCisgICAgICAgICAqCisgICAgICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCBsb2NrSW50ZXJydXB0aWJseSgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzeW5jLmFjcXVpcmVJbnRlcnJ1cHRpYmx5KDEpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEFjcXVpcmVzIHRoZSB3cml0ZSBsb2NrIG9ubHkgaWYgaXQgaXMgbm90IGhlbGQgYnkgYW5vdGhlciB0aHJlYWQKKyAgICAgICAgICogYXQgdGhlIHRpbWUgb2YgaW52b2NhdGlvbi4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+QWNxdWlyZXMgdGhlIHdyaXRlIGxvY2sgaWYgbmVpdGhlciB0aGUgcmVhZCBub3Igd3JpdGUgbG9jaworICAgICAgICAgKiBhcmUgaGVsZCBieSBhbm90aGVyIHRocmVhZAorICAgICAgICAgKiBhbmQgcmV0dXJucyBpbW1lZGlhdGVseSB3aXRoIHRoZSB2YWx1ZSB7QGNvZGUgdHJ1ZX0sCisgICAgICAgICAqIHNldHRpbmcgdGhlIHdyaXRlIGxvY2sgaG9sZCBjb3VudCB0byBvbmUuIEV2ZW4gd2hlbiB0aGlzIGxvY2sgaGFzCisgICAgICAgICAqIGJlZW4gc2V0IHRvIHVzZSBhIGZhaXIgb3JkZXJpbmcgcG9saWN5LCBhIGNhbGwgdG8KKyAgICAgICAgICoge0Bjb2RlIHRyeUxvY2soKX0gPGVtPndpbGw8L2VtPiBpbW1lZGlhdGVseSBhY3F1aXJlIHRoZQorICAgICAgICAgKiBsb2NrIGlmIGl0IGlzIGF2YWlsYWJsZSwgd2hldGhlciBvciBub3Qgb3RoZXIgdGhyZWFkcyBhcmUKKyAgICAgICAgICogY3VycmVudGx5IHdhaXRpbmcgZm9yIHRoZSB3cml0ZSBsb2NrLiAgVGhpcyAmcXVvdDtiYXJnaW5nJnF1b3Q7CisgICAgICAgICAqIGJlaGF2aW9yIGNhbiBiZSB1c2VmdWwgaW4gY2VydGFpbiBjaXJjdW1zdGFuY2VzLCBldmVuCisgICAgICAgICAqIHRob3VnaCBpdCBicmVha3MgZmFpcm5lc3MuIElmIHlvdSB3YW50IHRvIGhvbm9yIHRoZQorICAgICAgICAgKiBmYWlybmVzcyBzZXR0aW5nIGZvciB0aGlzIGxvY2ssIHRoZW4gdXNlIHtAbGluaworICAgICAgICAgKiAjdHJ5TG9jayhsb25nLCBUaW1lVW5pdCkgdHJ5TG9jaygwLCBUaW1lVW5pdC5TRUNPTkRTKSB9CisgICAgICAgICAqIHdoaWNoIGlzIGFsbW9zdCBlcXVpdmFsZW50IChpdCBhbHNvIGRldGVjdHMgaW50ZXJydXB0aW9uKS4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+IElmIHRoZSBjdXJyZW50IHRocmVhZCBhbHJlYWR5IGhvbGRzIHRoaXMgbG9jayB0aGVuIHRoZQorICAgICAgICAgKiBob2xkIGNvdW50IGlzIGluY3JlbWVudGVkIGJ5IG9uZSBhbmQgdGhlIG1ldGhvZCByZXR1cm5zCisgICAgICAgICAqIHtAY29kZSB0cnVlfS4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+SWYgdGhlIGxvY2sgaXMgaGVsZCBieSBhbm90aGVyIHRocmVhZCB0aGVuIHRoaXMgbWV0aG9kCisgICAgICAgICAqIHdpbGwgcmV0dXJuIGltbWVkaWF0ZWx5IHdpdGggdGhlIHZhbHVlIHtAY29kZSBmYWxzZX0uCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBsb2NrIHdhcyBmcmVlIGFuZCB3YXMgYWNxdWlyZWQKKyAgICAgICAgICogYnkgdGhlIGN1cnJlbnQgdGhyZWFkLCBvciB0aGUgd3JpdGUgbG9jayB3YXMgYWxyZWFkeSBoZWxkCisgICAgICAgICAqIGJ5IHRoZSBjdXJyZW50IHRocmVhZDsgYW5kIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGJvb2xlYW4gdHJ5TG9jayggKSB7CisgICAgICAgICAgICByZXR1cm4gc3luYy50cnlXcml0ZUxvY2soKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBBY3F1aXJlcyB0aGUgd3JpdGUgbG9jayBpZiBpdCBpcyBub3QgaGVsZCBieSBhbm90aGVyIHRocmVhZAorICAgICAgICAgKiB3aXRoaW4gdGhlIGdpdmVuIHdhaXRpbmcgdGltZSBhbmQgdGhlIGN1cnJlbnQgdGhyZWFkIGhhcworICAgICAgICAgKiBub3QgYmVlbiB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfS4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+QWNxdWlyZXMgdGhlIHdyaXRlIGxvY2sgaWYgbmVpdGhlciB0aGUgcmVhZCBub3Igd3JpdGUgbG9jaworICAgICAgICAgKiBhcmUgaGVsZCBieSBhbm90aGVyIHRocmVhZAorICAgICAgICAgKiBhbmQgcmV0dXJucyBpbW1lZGlhdGVseSB3aXRoIHRoZSB2YWx1ZSB7QGNvZGUgdHJ1ZX0sCisgICAgICAgICAqIHNldHRpbmcgdGhlIHdyaXRlIGxvY2sgaG9sZCBjb3VudCB0byBvbmUuIElmIHRoaXMgbG9jayBoYXMgYmVlbgorICAgICAgICAgKiBzZXQgdG8gdXNlIGEgZmFpciBvcmRlcmluZyBwb2xpY3kgdGhlbiBhbiBhdmFpbGFibGUgbG9jaworICAgICAgICAgKiA8ZW0+d2lsbCBub3Q8L2VtPiBiZSBhY3F1aXJlZCBpZiBhbnkgb3RoZXIgdGhyZWFkcyBhcmUKKyAgICAgICAgICogd2FpdGluZyBmb3IgdGhlIHdyaXRlIGxvY2suIFRoaXMgaXMgaW4gY29udHJhc3QgdG8gdGhlIHtAbGluaworICAgICAgICAgKiAjdHJ5TG9jaygpfSBtZXRob2QuIElmIHlvdSB3YW50IGEgdGltZWQge0Bjb2RlIHRyeUxvY2t9CisgICAgICAgICAqIHRoYXQgZG9lcyBwZXJtaXQgYmFyZ2luZyBvbiBhIGZhaXIgbG9jayB0aGVuIGNvbWJpbmUgdGhlCisgICAgICAgICAqIHRpbWVkIGFuZCB1bi10aW1lZCBmb3JtcyB0b2dldGhlcjoKKyAgICAgICAgICoKKyAgICAgICAgICogPHByZT5pZiAobG9jay50cnlMb2NrKCkgfHwgbG9jay50cnlMb2NrKHRpbWVvdXQsIHVuaXQpICkgeyAuLi4gfQorICAgICAgICAgKiA8L3ByZT4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+SWYgdGhlIGN1cnJlbnQgdGhyZWFkIGFscmVhZHkgaG9sZHMgdGhpcyBsb2NrIHRoZW4gdGhlCisgICAgICAgICAqIGhvbGQgY291bnQgaXMgaW5jcmVtZW50ZWQgYnkgb25lIGFuZCB0aGUgbWV0aG9kIHJldHVybnMKKyAgICAgICAgICoge0Bjb2RlIHRydWV9LgorICAgICAgICAgKgorICAgICAgICAgKiA8cD5JZiB0aGUgbG9jayBpcyBoZWxkIGJ5IGFub3RoZXIgdGhyZWFkIHRoZW4gdGhlIGN1cnJlbnQKKyAgICAgICAgICogdGhyZWFkIGJlY29tZXMgZGlzYWJsZWQgZm9yIHRocmVhZCBzY2hlZHVsaW5nIHB1cnBvc2VzIGFuZAorICAgICAgICAgKiBsaWVzIGRvcm1hbnQgdW50aWwgb25lIG9mIHRocmVlIHRoaW5ncyBoYXBwZW5zOgorICAgICAgICAgKgorICAgICAgICAgKiA8dWw+CisgICAgICAgICAqCisgICAgICAgICAqIDxsaT5UaGUgd3JpdGUgbG9jayBpcyBhY3F1aXJlZCBieSB0aGUgY3VycmVudCB0aHJlYWQ7IG9yCisgICAgICAgICAqCisgICAgICAgICAqIDxsaT5Tb21lIG90aGVyIHRocmVhZCB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdHN9CisgICAgICAgICAqIHRoZSBjdXJyZW50IHRocmVhZDsgb3IKKyAgICAgICAgICoKKyAgICAgICAgICogPGxpPlRoZSBzcGVjaWZpZWQgd2FpdGluZyB0aW1lIGVsYXBzZXMKKyAgICAgICAgICoKKyAgICAgICAgICogPC91bD4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+SWYgdGhlIHdyaXRlIGxvY2sgaXMgYWNxdWlyZWQgdGhlbiB0aGUgdmFsdWUge0Bjb2RlIHRydWV9IGlzCisgICAgICAgICAqIHJldHVybmVkIGFuZCB0aGUgd3JpdGUgbG9jayBob2xkIGNvdW50IGlzIHNldCB0byBvbmUuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPklmIHRoZSBjdXJyZW50IHRocmVhZDoKKyAgICAgICAgICoKKyAgICAgICAgICogPHVsPgorICAgICAgICAgKgorICAgICAgICAgKiA8bGk+aGFzIGl0cyBpbnRlcnJ1cHRlZCBzdGF0dXMgc2V0IG9uIGVudHJ5IHRvIHRoaXMgbWV0aG9kOworICAgICAgICAgKiBvcgorICAgICAgICAgKgorICAgICAgICAgKiA8bGk+aXMge0BsaW5rcGxhaW4gVGhyZWFkI2ludGVycnVwdCBpbnRlcnJ1cHRlZH0gd2hpbGUKKyAgICAgICAgICogYWNxdWlyaW5nIHRoZSB3cml0ZSBsb2NrLAorICAgICAgICAgKgorICAgICAgICAgKiA8L3VsPgorICAgICAgICAgKgorICAgICAgICAgKiB0aGVuIHtAbGluayBJbnRlcnJ1cHRlZEV4Y2VwdGlvbn0gaXMgdGhyb3duIGFuZCB0aGUgY3VycmVudAorICAgICAgICAgKiB0aHJlYWQncyBpbnRlcnJ1cHRlZCBzdGF0dXMgaXMgY2xlYXJlZC4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+SWYgdGhlIHNwZWNpZmllZCB3YWl0aW5nIHRpbWUgZWxhcHNlcyB0aGVuIHRoZSB2YWx1ZQorICAgICAgICAgKiB7QGNvZGUgZmFsc2V9IGlzIHJldHVybmVkLiAgSWYgdGhlIHRpbWUgaXMgbGVzcyB0aGFuIG9yCisgICAgICAgICAqIGVxdWFsIHRvIHplcm8sIHRoZSBtZXRob2Qgd2lsbCBub3Qgd2FpdCBhdCBhbGwuCisgICAgICAgICAqCisgICAgICAgICAqIDxwPkluIHRoaXMgaW1wbGVtZW50YXRpb24sIGFzIHRoaXMgbWV0aG9kIGlzIGFuIGV4cGxpY2l0CisgICAgICAgICAqIGludGVycnVwdGlvbiBwb2ludCwgcHJlZmVyZW5jZSBpcyBnaXZlbiB0byByZXNwb25kaW5nIHRvCisgICAgICAgICAqIHRoZSBpbnRlcnJ1cHQgb3ZlciBub3JtYWwgb3IgcmVlbnRyYW50IGFjcXVpc2l0aW9uIG9mIHRoZQorICAgICAgICAgKiBsb2NrLCBhbmQgb3ZlciByZXBvcnRpbmcgdGhlIGVsYXBzZSBvZiB0aGUgd2FpdGluZyB0aW1lLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gdGltZW91dCB0aGUgdGltZSB0byB3YWl0IGZvciB0aGUgd3JpdGUgbG9jaworICAgICAgICAgKiBAcGFyYW0gdW5pdCB0aGUgdGltZSB1bml0IG9mIHRoZSB0aW1lb3V0IGFyZ3VtZW50CisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBsb2NrIHdhcyBmcmVlIGFuZCB3YXMgYWNxdWlyZWQKKyAgICAgICAgICogYnkgdGhlIGN1cnJlbnQgdGhyZWFkLCBvciB0aGUgd3JpdGUgbG9jayB3YXMgYWxyZWFkeSBoZWxkIGJ5IHRoZQorICAgICAgICAgKiBjdXJyZW50IHRocmVhZDsgYW5kIHtAY29kZSBmYWxzZX0gaWYgdGhlIHdhaXRpbmcgdGltZQorICAgICAgICAgKiBlbGFwc2VkIGJlZm9yZSB0aGUgbG9jayBjb3VsZCBiZSBhY3F1aXJlZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCB0aHJlYWQgaXMgaW50ZXJydXB0ZWQKKyAgICAgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgdGltZSB1bml0IGlzIG51bGwKKyAgICAgICAgICoKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBib29sZWFuIHRyeUxvY2sobG9uZyB0aW1lb3V0LCBUaW1lVW5pdCB1bml0KQorICAgICAgICAgICAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gc3luYy50cnlBY3F1aXJlTmFub3MoMSwgdW5pdC50b05hbm9zKHRpbWVvdXQpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBBdHRlbXB0cyB0byByZWxlYXNlIHRoaXMgbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+SWYgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIHRoZSBob2xkZXIgb2YgdGhpcyBsb2NrIHRoZW4KKyAgICAgICAgICogdGhlIGhvbGQgY291bnQgaXMgZGVjcmVtZW50ZWQuIElmIHRoZSBob2xkIGNvdW50IGlzIG5vdworICAgICAgICAgKiB6ZXJvIHRoZW4gdGhlIGxvY2sgaXMgcmVsZWFzZWQuICBJZiB0aGUgY3VycmVudCB0aHJlYWQgaXMKKyAgICAgICAgICogbm90IHRoZSBob2xkZXIgb2YgdGhpcyBsb2NrIHRoZW4ge0BsaW5rCisgICAgICAgICAqIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb259IGlzIHRocm93bi4KKyAgICAgICAgICoKKyAgICAgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IHRocmVhZCBkb2VzIG5vdAorICAgICAgICAgKiBob2xkIHRoaXMgbG9jay4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyB2b2lkIHVubG9jaygpIHsKKyAgICAgICAgICAgIHN5bmMucmVsZWFzZSgxKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGEge0BsaW5rIENvbmRpdGlvbn0gaW5zdGFuY2UgZm9yIHVzZSB3aXRoIHRoaXMKKyAgICAgICAgICoge0BsaW5rIExvY2t9IGluc3RhbmNlLgorICAgICAgICAgKiA8cD5UaGUgcmV0dXJuZWQge0BsaW5rIENvbmRpdGlvbn0gaW5zdGFuY2Ugc3VwcG9ydHMgdGhlIHNhbWUKKyAgICAgICAgICogdXNhZ2VzIGFzIGRvIHRoZSB7QGxpbmsgT2JqZWN0fSBtb25pdG9yIG1ldGhvZHMgKHtAbGluaworICAgICAgICAgKiBPYmplY3Qjd2FpdCgpIHdhaXR9LCB7QGxpbmsgT2JqZWN0I25vdGlmeSBub3RpZnl9LCBhbmQge0BsaW5rCisgICAgICAgICAqIE9iamVjdCNub3RpZnlBbGwgbm90aWZ5QWxsfSkgd2hlbiB1c2VkIHdpdGggdGhlIGJ1aWx0LWluCisgICAgICAgICAqIG1vbml0b3IgbG9jay4KKyAgICAgICAgICoKKyAgICAgICAgICogPHVsPgorICAgICAgICAgKgorICAgICAgICAgKiA8bGk+SWYgdGhpcyB3cml0ZSBsb2NrIGlzIG5vdCBoZWxkIHdoZW4gYW55IHtAbGluaworICAgICAgICAgKiBDb25kaXRpb259IG1ldGhvZCBpcyBjYWxsZWQgdGhlbiBhbiB7QGxpbmsKKyAgICAgICAgICogSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbn0gaXMgdGhyb3duLiAgKFJlYWQgbG9ja3MgYXJlCisgICAgICAgICAqIGhlbGQgaW5kZXBlbmRlbnRseSBvZiB3cml0ZSBsb2Nrcywgc28gYXJlIG5vdCBjaGVja2VkIG9yCisgICAgICAgICAqIGFmZmVjdGVkLiBIb3dldmVyIGl0IGlzIGVzc2VudGlhbGx5IGFsd2F5cyBhbiBlcnJvciB0bworICAgICAgICAgKiBpbnZva2UgYSBjb25kaXRpb24gd2FpdGluZyBtZXRob2Qgd2hlbiB0aGUgY3VycmVudCB0aHJlYWQKKyAgICAgICAgICogaGFzIGFsc28gYWNxdWlyZWQgcmVhZCBsb2Nrcywgc2luY2Ugb3RoZXIgdGhyZWFkcyB0aGF0CisgICAgICAgICAqIGNvdWxkIHVuYmxvY2sgaXQgd2lsbCBub3QgYmUgYWJsZSB0byBhY3F1aXJlIHRoZSB3cml0ZQorICAgICAgICAgKiBsb2NrLikKKyAgICAgICAgICoKKyAgICAgICAgICogPGxpPldoZW4gdGhlIGNvbmRpdGlvbiB7QGxpbmtwbGFpbiBDb25kaXRpb24jYXdhaXQoKSB3YWl0aW5nfQorICAgICAgICAgKiBtZXRob2RzIGFyZSBjYWxsZWQgdGhlIHdyaXRlIGxvY2sgaXMgcmVsZWFzZWQgYW5kLCBiZWZvcmUKKyAgICAgICAgICogdGhleSByZXR1cm4sIHRoZSB3cml0ZSBsb2NrIGlzIHJlYWNxdWlyZWQgYW5kIHRoZSBsb2NrIGhvbGQKKyAgICAgICAgICogY291bnQgcmVzdG9yZWQgdG8gd2hhdCBpdCB3YXMgd2hlbiB0aGUgbWV0aG9kIHdhcyBjYWxsZWQuCisgICAgICAgICAqCisgICAgICAgICAqIDxsaT5JZiBhIHRocmVhZCBpcyB7QGxpbmtwbGFpbiBUaHJlYWQjaW50ZXJydXB0IGludGVycnVwdGVkfSB3aGlsZQorICAgICAgICAgKiB3YWl0aW5nIHRoZW4gdGhlIHdhaXQgd2lsbCB0ZXJtaW5hdGUsIGFuIHtAbGluaworICAgICAgICAgKiBJbnRlcnJ1cHRlZEV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24sIGFuZCB0aGUgdGhyZWFkJ3MKKyAgICAgICAgICogaW50ZXJydXB0ZWQgc3RhdHVzIHdpbGwgYmUgY2xlYXJlZC4KKyAgICAgICAgICoKKyAgICAgICAgICogPGxpPiBXYWl0aW5nIHRocmVhZHMgYXJlIHNpZ25hbGxlZCBpbiBGSUZPIG9yZGVyLgorICAgICAgICAgKgorICAgICAgICAgKiA8bGk+VGhlIG9yZGVyaW5nIG9mIGxvY2sgcmVhY3F1aXNpdGlvbiBmb3IgdGhyZWFkcyByZXR1cm5pbmcKKyAgICAgICAgICogZnJvbSB3YWl0aW5nIG1ldGhvZHMgaXMgdGhlIHNhbWUgYXMgZm9yIHRocmVhZHMgaW5pdGlhbGx5CisgICAgICAgICAqIGFjcXVpcmluZyB0aGUgbG9jaywgd2hpY2ggaXMgaW4gdGhlIGRlZmF1bHQgY2FzZSBub3Qgc3BlY2lmaWVkLAorICAgICAgICAgKiBidXQgZm9yIDxlbT5mYWlyPC9lbT4gbG9ja3MgZmF2b3JzIHRob3NlIHRocmVhZHMgdGhhdCBoYXZlIGJlZW4KKyAgICAgICAgICogd2FpdGluZyB0aGUgbG9uZ2VzdC4KKyAgICAgICAgICoKKyAgICAgICAgICogPC91bD4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUgQ29uZGl0aW9uIG9iamVjdAorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIENvbmRpdGlvbiBuZXdDb25kaXRpb24oKSB7CisgICAgICAgICAgICByZXR1cm4gc3luYy5uZXdDb25kaXRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGlkZW50aWZ5aW5nIHRoaXMgbG9jaywgYXMgd2VsbCBhcyBpdHMgbG9jaworICAgICAgICAgKiBzdGF0ZS4gIFRoZSBzdGF0ZSwgaW4gYnJhY2tldHMgaW5jbHVkZXMgZWl0aGVyIHRoZSBTdHJpbmcKKyAgICAgICAgICoge0Bjb2RlICJVbmxvY2tlZCJ9IG9yIHRoZSBTdHJpbmcge0Bjb2RlICJMb2NrZWQgYnkifQorICAgICAgICAgKiBmb2xsb3dlZCBieSB0aGUge0BsaW5rcGxhaW4gVGhyZWFkI2dldE5hbWUgbmFtZX0gb2YgdGhlIG93bmluZyB0aHJlYWQuCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gYSBzdHJpbmcgaWRlbnRpZnlpbmcgdGhpcyBsb2NrLCBhcyB3ZWxsIGFzIGl0cyBsb2NrIHN0YXRlCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgVGhyZWFkIG8gPSBzeW5jLmdldE93bmVyKCk7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKSArICgobyA9PSBudWxsKSA/CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiW1VubG9ja2VkXSIgOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIltMb2NrZWQgYnkgdGhyZWFkICIgKyBvLmdldE5hbWUoKSArICJdIik7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUXVlcmllcyBpZiB0aGlzIHdyaXRlIGxvY2sgaXMgaGVsZCBieSB0aGUgY3VycmVudCB0aHJlYWQuCisgICAgICAgICAqIElkZW50aWNhbCBpbiBlZmZlY3QgdG8ge0BsaW5rCisgICAgICAgICAqIFJlZW50cmFudFJlYWRXcml0ZUxvY2sjaXNXcml0ZUxvY2tlZEJ5Q3VycmVudFRocmVhZH0uCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBjdXJyZW50IHRocmVhZCBob2xkcyB0aGlzIGxvY2sgYW5kCisgICAgICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgICAgICogQHNpbmNlIDEuNgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNIZWxkQnlDdXJyZW50VGhyZWFkKCkgeworICAgICAgICAgICAgcmV0dXJuIHN5bmMuaXNIZWxkRXhjbHVzaXZlbHkoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBRdWVyaWVzIHRoZSBudW1iZXIgb2YgaG9sZHMgb24gdGhpcyB3cml0ZSBsb2NrIGJ5IHRoZSBjdXJyZW50CisgICAgICAgICAqIHRocmVhZC4gIEEgdGhyZWFkIGhhcyBhIGhvbGQgb24gYSBsb2NrIGZvciBlYWNoIGxvY2sgYWN0aW9uCisgICAgICAgICAqIHRoYXQgaXMgbm90IG1hdGNoZWQgYnkgYW4gdW5sb2NrIGFjdGlvbi4gIElkZW50aWNhbCBpbiBlZmZlY3QKKyAgICAgICAgICogdG8ge0BsaW5rIFJlZW50cmFudFJlYWRXcml0ZUxvY2sjZ2V0V3JpdGVIb2xkQ291bnR9LgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgaG9sZHMgb24gdGhpcyBsb2NrIGJ5IHRoZSBjdXJyZW50IHRocmVhZCwKKyAgICAgICAgICogICAgICAgICBvciB6ZXJvIGlmIHRoaXMgbG9jayBpcyBub3QgaGVsZCBieSB0aGUgY3VycmVudCB0aHJlYWQKKyAgICAgICAgICogQHNpbmNlIDEuNgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGludCBnZXRIb2xkQ291bnQoKSB7CisgICAgICAgICAgICByZXR1cm4gc3luYy5nZXRXcml0ZUhvbGRDb3VudCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gSW5zdHJ1bWVudGF0aW9uIGFuZCBzdGF0dXMKKworICAgIC8qKgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoaXMgbG9jayBoYXMgZmFpcm5lc3Mgc2V0IHRydWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGxvY2sgaGFzIGZhaXJuZXNzIHNldCB0cnVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNGYWlyKCkgeworICAgICAgICByZXR1cm4gc3luYyBpbnN0YW5jZW9mIEZhaXJTeW5jOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRocmVhZCB0aGF0IGN1cnJlbnRseSBvd25zIHRoZSB3cml0ZSBsb2NrLCBvcgorICAgICAqIHtAY29kZSBudWxsfSBpZiBub3Qgb3duZWQuIFdoZW4gdGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IGEKKyAgICAgKiB0aHJlYWQgdGhhdCBpcyBub3QgdGhlIG93bmVyLCB0aGUgcmV0dXJuIHZhbHVlIHJlZmxlY3RzIGEKKyAgICAgKiBiZXN0LWVmZm9ydCBhcHByb3hpbWF0aW9uIG9mIGN1cnJlbnQgbG9jayBzdGF0dXMuIEZvciBleGFtcGxlLAorICAgICAqIHRoZSBvd25lciBtYXkgYmUgbW9tZW50YXJpbHkge0Bjb2RlIG51bGx9IGV2ZW4gaWYgdGhlcmUgYXJlCisgICAgICogdGhyZWFkcyB0cnlpbmcgdG8gYWNxdWlyZSB0aGUgbG9jayBidXQgaGF2ZSBub3QgeWV0IGRvbmUgc28uCisgICAgICogVGhpcyBtZXRob2QgaXMgZGVzaWduZWQgdG8gZmFjaWxpdGF0ZSBjb25zdHJ1Y3Rpb24gb2YKKyAgICAgKiBzdWJjbGFzc2VzIHRoYXQgcHJvdmlkZSBtb3JlIGV4dGVuc2l2ZSBsb2NrIG1vbml0b3JpbmcKKyAgICAgKiBmYWNpbGl0aWVzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgb3duZXIsIG9yIHtAY29kZSBudWxsfSBpZiBub3Qgb3duZWQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgVGhyZWFkIGdldE93bmVyKCkgeworICAgICAgICByZXR1cm4gc3luYy5nZXRPd25lcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFF1ZXJpZXMgdGhlIG51bWJlciBvZiByZWFkIGxvY2tzIGhlbGQgZm9yIHRoaXMgbG9jay4gVGhpcworICAgICAqIG1ldGhvZCBpcyBkZXNpZ25lZCBmb3IgdXNlIGluIG1vbml0b3Jpbmcgc3lzdGVtIHN0YXRlLCBub3QgZm9yCisgICAgICogc3luY2hyb25pemF0aW9uIGNvbnRyb2wuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHJlYWQgbG9ja3MgaGVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFJlYWRMb2NrQ291bnQoKSB7CisgICAgICAgIHJldHVybiBzeW5jLmdldFJlYWRMb2NrQ291bnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBRdWVyaWVzIGlmIHRoZSB3cml0ZSBsb2NrIGlzIGhlbGQgYnkgYW55IHRocmVhZC4gVGhpcyBtZXRob2QgaXMKKyAgICAgKiBkZXNpZ25lZCBmb3IgdXNlIGluIG1vbml0b3Jpbmcgc3lzdGVtIHN0YXRlLCBub3QgZm9yCisgICAgICogc3luY2hyb25pemF0aW9uIGNvbnRyb2wuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBhbnkgdGhyZWFkIGhvbGRzIHRoZSB3cml0ZSBsb2NrIGFuZAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1dyaXRlTG9ja2VkKCkgeworICAgICAgICByZXR1cm4gc3luYy5pc1dyaXRlTG9ja2VkKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUXVlcmllcyBpZiB0aGUgd3JpdGUgbG9jayBpcyBoZWxkIGJ5IHRoZSBjdXJyZW50IHRocmVhZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBjdXJyZW50IHRocmVhZCBob2xkcyB0aGUgd3JpdGUgbG9jayBhbmQKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNXcml0ZUxvY2tlZEJ5Q3VycmVudFRocmVhZCgpIHsKKyAgICAgICAgcmV0dXJuIHN5bmMuaXNIZWxkRXhjbHVzaXZlbHkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBRdWVyaWVzIHRoZSBudW1iZXIgb2YgcmVlbnRyYW50IHdyaXRlIGhvbGRzIG9uIHRoaXMgbG9jayBieSB0aGUKKyAgICAgKiBjdXJyZW50IHRocmVhZC4gIEEgd3JpdGVyIHRocmVhZCBoYXMgYSBob2xkIG9uIGEgbG9jayBmb3IKKyAgICAgKiBlYWNoIGxvY2sgYWN0aW9uIHRoYXQgaXMgbm90IG1hdGNoZWQgYnkgYW4gdW5sb2NrIGFjdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBob2xkcyBvbiB0aGUgd3JpdGUgbG9jayBieSB0aGUgY3VycmVudCB0aHJlYWQsCisgICAgICogICAgICAgICBvciB6ZXJvIGlmIHRoZSB3cml0ZSBsb2NrIGlzIG5vdCBoZWxkIGJ5IHRoZSBjdXJyZW50IHRocmVhZAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0V3JpdGVIb2xkQ291bnQoKSB7CisgICAgICAgIHJldHVybiBzeW5jLmdldFdyaXRlSG9sZENvdW50KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUXVlcmllcyB0aGUgbnVtYmVyIG9mIHJlZW50cmFudCByZWFkIGhvbGRzIG9uIHRoaXMgbG9jayBieSB0aGUKKyAgICAgKiBjdXJyZW50IHRocmVhZC4gIEEgcmVhZGVyIHRocmVhZCBoYXMgYSBob2xkIG9uIGEgbG9jayBmb3IKKyAgICAgKiBlYWNoIGxvY2sgYWN0aW9uIHRoYXQgaXMgbm90IG1hdGNoZWQgYnkgYW4gdW5sb2NrIGFjdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBob2xkcyBvbiB0aGUgcmVhZCBsb2NrIGJ5IHRoZSBjdXJyZW50IHRocmVhZCwKKyAgICAgKiAgICAgICAgIG9yIHplcm8gaWYgdGhlIHJlYWQgbG9jayBpcyBub3QgaGVsZCBieSB0aGUgY3VycmVudCB0aHJlYWQKKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIGludCBnZXRSZWFkSG9sZENvdW50KCkgeworICAgICAgICByZXR1cm4gc3luYy5nZXRSZWFkSG9sZENvdW50KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvbGxlY3Rpb24gY29udGFpbmluZyB0aHJlYWRzIHRoYXQgbWF5IGJlIHdhaXRpbmcgdG8KKyAgICAgKiBhY3F1aXJlIHRoZSB3cml0ZSBsb2NrLiAgQmVjYXVzZSB0aGUgYWN0dWFsIHNldCBvZiB0aHJlYWRzIG1heQorICAgICAqIGNoYW5nZSBkeW5hbWljYWxseSB3aGlsZSBjb25zdHJ1Y3RpbmcgdGhpcyByZXN1bHQsIHRoZSByZXR1cm5lZAorICAgICAqIGNvbGxlY3Rpb24gaXMgb25seSBhIGJlc3QtZWZmb3J0IGVzdGltYXRlLiAgVGhlIGVsZW1lbnRzIG9mIHRoZQorICAgICAqIHJldHVybmVkIGNvbGxlY3Rpb24gYXJlIGluIG5vIHBhcnRpY3VsYXIgb3JkZXIuICBUaGlzIG1ldGhvZCBpcworICAgICAqIGRlc2lnbmVkIHRvIGZhY2lsaXRhdGUgY29uc3RydWN0aW9uIG9mIHN1YmNsYXNzZXMgdGhhdCBwcm92aWRlCisgICAgICogbW9yZSBleHRlbnNpdmUgbG9jayBtb25pdG9yaW5nIGZhY2lsaXRpZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb2xsZWN0aW9uIG9mIHRocmVhZHMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ29sbGVjdGlvbjxUaHJlYWQ+IGdldFF1ZXVlZFdyaXRlclRocmVhZHMoKSB7CisgICAgICAgIHJldHVybiBzeW5jLmdldEV4Y2x1c2l2ZVF1ZXVlZFRocmVhZHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29sbGVjdGlvbiBjb250YWluaW5nIHRocmVhZHMgdGhhdCBtYXkgYmUgd2FpdGluZyB0bworICAgICAqIGFjcXVpcmUgdGhlIHJlYWQgbG9jay4gIEJlY2F1c2UgdGhlIGFjdHVhbCBzZXQgb2YgdGhyZWFkcyBtYXkKKyAgICAgKiBjaGFuZ2UgZHluYW1pY2FsbHkgd2hpbGUgY29uc3RydWN0aW5nIHRoaXMgcmVzdWx0LCB0aGUgcmV0dXJuZWQKKyAgICAgKiBjb2xsZWN0aW9uIGlzIG9ubHkgYSBiZXN0LWVmZm9ydCBlc3RpbWF0ZS4gIFRoZSBlbGVtZW50cyBvZiB0aGUKKyAgICAgKiByZXR1cm5lZCBjb2xsZWN0aW9uIGFyZSBpbiBubyBwYXJ0aWN1bGFyIG9yZGVyLiAgVGhpcyBtZXRob2QgaXMKKyAgICAgKiBkZXNpZ25lZCB0byBmYWNpbGl0YXRlIGNvbnN0cnVjdGlvbiBvZiBzdWJjbGFzc2VzIHRoYXQgcHJvdmlkZQorICAgICAqIG1vcmUgZXh0ZW5zaXZlIGxvY2sgbW9uaXRvcmluZyBmYWNpbGl0aWVzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29sbGVjdGlvbiBvZiB0aHJlYWRzCisgICAgICovCisgICAgcHJvdGVjdGVkIENvbGxlY3Rpb248VGhyZWFkPiBnZXRRdWV1ZWRSZWFkZXJUaHJlYWRzKCkgeworICAgICAgICByZXR1cm4gc3luYy5nZXRTaGFyZWRRdWV1ZWRUaHJlYWRzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUXVlcmllcyB3aGV0aGVyIGFueSB0aHJlYWRzIGFyZSB3YWl0aW5nIHRvIGFjcXVpcmUgdGhlIHJlYWQgb3IKKyAgICAgKiB3cml0ZSBsb2NrLiBOb3RlIHRoYXQgYmVjYXVzZSBjYW5jZWxsYXRpb25zIG1heSBvY2N1ciBhdCBhbnkKKyAgICAgKiB0aW1lLCBhIHtAY29kZSB0cnVlfSByZXR1cm4gZG9lcyBub3QgZ3VhcmFudGVlIHRoYXQgYW55IG90aGVyCisgICAgICogdGhyZWFkIHdpbGwgZXZlciBhY3F1aXJlIGEgbG9jay4gIFRoaXMgbWV0aG9kIGlzIGRlc2lnbmVkCisgICAgICogcHJpbWFyaWx5IGZvciB1c2UgaW4gbW9uaXRvcmluZyBvZiB0aGUgc3lzdGVtIHN0YXRlLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlcmUgbWF5IGJlIG90aGVyIHRocmVhZHMgd2FpdGluZyB0bworICAgICAqICAgICAgICAgYWNxdWlyZSB0aGUgbG9jaworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc1F1ZXVlZFRocmVhZHMoKSB7CisgICAgICAgIHJldHVybiBzeW5jLmhhc1F1ZXVlZFRocmVhZHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBRdWVyaWVzIHdoZXRoZXIgdGhlIGdpdmVuIHRocmVhZCBpcyB3YWl0aW5nIHRvIGFjcXVpcmUgZWl0aGVyCisgICAgICogdGhlIHJlYWQgb3Igd3JpdGUgbG9jay4gTm90ZSB0aGF0IGJlY2F1c2UgY2FuY2VsbGF0aW9ucyBtYXkKKyAgICAgKiBvY2N1ciBhdCBhbnkgdGltZSwgYSB7QGNvZGUgdHJ1ZX0gcmV0dXJuIGRvZXMgbm90IGd1YXJhbnRlZQorICAgICAqIHRoYXQgdGhpcyB0aHJlYWQgd2lsbCBldmVyIGFjcXVpcmUgYSBsb2NrLiAgVGhpcyBtZXRob2QgaXMKKyAgICAgKiBkZXNpZ25lZCBwcmltYXJpbHkgZm9yIHVzZSBpbiBtb25pdG9yaW5nIG9mIHRoZSBzeXN0ZW0gc3RhdGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhyZWFkIHRoZSB0aHJlYWQKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZ2l2ZW4gdGhyZWFkIGlzIHF1ZXVlZCB3YWl0aW5nIGZvciB0aGlzIGxvY2sKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSB0aHJlYWQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc1F1ZXVlZFRocmVhZChUaHJlYWQgdGhyZWFkKSB7CisgICAgICAgIHJldHVybiBzeW5jLmlzUXVldWVkKHRocmVhZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBlc3RpbWF0ZSBvZiB0aGUgbnVtYmVyIG9mIHRocmVhZHMgd2FpdGluZyB0byBhY3F1aXJlCisgICAgICogZWl0aGVyIHRoZSByZWFkIG9yIHdyaXRlIGxvY2suICBUaGUgdmFsdWUgaXMgb25seSBhbiBlc3RpbWF0ZQorICAgICAqIGJlY2F1c2UgdGhlIG51bWJlciBvZiB0aHJlYWRzIG1heSBjaGFuZ2UgZHluYW1pY2FsbHkgd2hpbGUgdGhpcworICAgICAqIG1ldGhvZCB0cmF2ZXJzZXMgaW50ZXJuYWwgZGF0YSBzdHJ1Y3R1cmVzLiAgVGhpcyBtZXRob2QgaXMKKyAgICAgKiBkZXNpZ25lZCBmb3IgdXNlIGluIG1vbml0b3Jpbmcgb2YgdGhlIHN5c3RlbSBzdGF0ZSwgbm90IGZvcgorICAgICAqIHN5bmNocm9uaXphdGlvbiBjb250cm9sLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZXN0aW1hdGVkIG51bWJlciBvZiB0aHJlYWRzIHdhaXRpbmcgZm9yIHRoaXMgbG9jaworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UXVldWVMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBzeW5jLmdldFF1ZXVlTGVuZ3RoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvbGxlY3Rpb24gY29udGFpbmluZyB0aHJlYWRzIHRoYXQgbWF5IGJlIHdhaXRpbmcgdG8KKyAgICAgKiBhY3F1aXJlIGVpdGhlciB0aGUgcmVhZCBvciB3cml0ZSBsb2NrLiAgQmVjYXVzZSB0aGUgYWN0dWFsIHNldAorICAgICAqIG9mIHRocmVhZHMgbWF5IGNoYW5nZSBkeW5hbWljYWxseSB3aGlsZSBjb25zdHJ1Y3RpbmcgdGhpcworICAgICAqIHJlc3VsdCwgdGhlIHJldHVybmVkIGNvbGxlY3Rpb24gaXMgb25seSBhIGJlc3QtZWZmb3J0IGVzdGltYXRlLgorICAgICAqIFRoZSBlbGVtZW50cyBvZiB0aGUgcmV0dXJuZWQgY29sbGVjdGlvbiBhcmUgaW4gbm8gcGFydGljdWxhcgorICAgICAqIG9yZGVyLiAgVGhpcyBtZXRob2QgaXMgZGVzaWduZWQgdG8gZmFjaWxpdGF0ZSBjb25zdHJ1Y3Rpb24gb2YKKyAgICAgKiBzdWJjbGFzc2VzIHRoYXQgcHJvdmlkZSBtb3JlIGV4dGVuc2l2ZSBtb25pdG9yaW5nIGZhY2lsaXRpZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb2xsZWN0aW9uIG9mIHRocmVhZHMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ29sbGVjdGlvbjxUaHJlYWQ+IGdldFF1ZXVlZFRocmVhZHMoKSB7CisgICAgICAgIHJldHVybiBzeW5jLmdldFF1ZXVlZFRocmVhZHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBRdWVyaWVzIHdoZXRoZXIgYW55IHRocmVhZHMgYXJlIHdhaXRpbmcgb24gdGhlIGdpdmVuIGNvbmRpdGlvbgorICAgICAqIGFzc29jaWF0ZWQgd2l0aCB0aGUgd3JpdGUgbG9jay4gTm90ZSB0aGF0IGJlY2F1c2UgdGltZW91dHMgYW5kCisgICAgICogaW50ZXJydXB0cyBtYXkgb2NjdXIgYXQgYW55IHRpbWUsIGEge0Bjb2RlIHRydWV9IHJldHVybiBkb2VzCisgICAgICogbm90IGd1YXJhbnRlZSB0aGF0IGEgZnV0dXJlIHtAY29kZSBzaWduYWx9IHdpbGwgYXdha2VuIGFueQorICAgICAqIHRocmVhZHMuICBUaGlzIG1ldGhvZCBpcyBkZXNpZ25lZCBwcmltYXJpbHkgZm9yIHVzZSBpbgorICAgICAqIG1vbml0b3Jpbmcgb2YgdGhlIHN5c3RlbSBzdGF0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb25kaXRpb24gdGhlIGNvbmRpdGlvbgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZXJlIGFyZSBhbnkgd2FpdGluZyB0aHJlYWRzCisgICAgICogQHRocm93cyBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbG9jayBpcyBub3QgaGVsZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBjb25kaXRpb24gaXMKKyAgICAgKiAgICAgICAgIG5vdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBsb2NrCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgY29uZGl0aW9uIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNXYWl0ZXJzKENvbmRpdGlvbiBjb25kaXRpb24pIHsKKyAgICAgICAgaWYgKGNvbmRpdGlvbiA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGlmICghKGNvbmRpdGlvbiBpbnN0YW5jZW9mIEFic3RyYWN0UXVldWVkU3luY2hyb25pemVyLkNvbmRpdGlvbk9iamVjdCkpCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJub3Qgb3duZXIiKTsKKyAgICAgICAgcmV0dXJuIHN5bmMuaGFzV2FpdGVycygoQWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXIuQ29uZGl0aW9uT2JqZWN0KWNvbmRpdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBlc3RpbWF0ZSBvZiB0aGUgbnVtYmVyIG9mIHRocmVhZHMgd2FpdGluZyBvbiB0aGUKKyAgICAgKiBnaXZlbiBjb25kaXRpb24gYXNzb2NpYXRlZCB3aXRoIHRoZSB3cml0ZSBsb2NrLiBOb3RlIHRoYXQgYmVjYXVzZQorICAgICAqIHRpbWVvdXRzIGFuZCBpbnRlcnJ1cHRzIG1heSBvY2N1ciBhdCBhbnkgdGltZSwgdGhlIGVzdGltYXRlCisgICAgICogc2VydmVzIG9ubHkgYXMgYW4gdXBwZXIgYm91bmQgb24gdGhlIGFjdHVhbCBudW1iZXIgb2Ygd2FpdGVycy4KKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBkZXNpZ25lZCBmb3IgdXNlIGluIG1vbml0b3Jpbmcgb2YgdGhlIHN5c3RlbQorICAgICAqIHN0YXRlLCBub3QgZm9yIHN5bmNocm9uaXphdGlvbiBjb250cm9sLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbmRpdGlvbiB0aGUgY29uZGl0aW9uCisgICAgICogQHJldHVybiB0aGUgZXN0aW1hdGVkIG51bWJlciBvZiB3YWl0aW5nIHRocmVhZHMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBsb2NrIGlzIG5vdCBoZWxkCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGNvbmRpdGlvbiBpcworICAgICAqICAgICAgICAgbm90IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGxvY2sKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBjb25kaXRpb24gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0V2FpdFF1ZXVlTGVuZ3RoKENvbmRpdGlvbiBjb25kaXRpb24pIHsKKyAgICAgICAgaWYgKGNvbmRpdGlvbiA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGlmICghKGNvbmRpdGlvbiBpbnN0YW5jZW9mIEFic3RyYWN0UXVldWVkU3luY2hyb25pemVyLkNvbmRpdGlvbk9iamVjdCkpCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJub3Qgb3duZXIiKTsKKyAgICAgICAgcmV0dXJuIHN5bmMuZ2V0V2FpdFF1ZXVlTGVuZ3RoKChBYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplci5Db25kaXRpb25PYmplY3QpY29uZGl0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29sbGVjdGlvbiBjb250YWluaW5nIHRob3NlIHRocmVhZHMgdGhhdCBtYXkgYmUKKyAgICAgKiB3YWl0aW5nIG9uIHRoZSBnaXZlbiBjb25kaXRpb24gYXNzb2NpYXRlZCB3aXRoIHRoZSB3cml0ZSBsb2NrLgorICAgICAqIEJlY2F1c2UgdGhlIGFjdHVhbCBzZXQgb2YgdGhyZWFkcyBtYXkgY2hhbmdlIGR5bmFtaWNhbGx5IHdoaWxlCisgICAgICogY29uc3RydWN0aW5nIHRoaXMgcmVzdWx0LCB0aGUgcmV0dXJuZWQgY29sbGVjdGlvbiBpcyBvbmx5IGEKKyAgICAgKiBiZXN0LWVmZm9ydCBlc3RpbWF0ZS4gVGhlIGVsZW1lbnRzIG9mIHRoZSByZXR1cm5lZCBjb2xsZWN0aW9uCisgICAgICogYXJlIGluIG5vIHBhcnRpY3VsYXIgb3JkZXIuICBUaGlzIG1ldGhvZCBpcyBkZXNpZ25lZCB0bworICAgICAqIGZhY2lsaXRhdGUgY29uc3RydWN0aW9uIG9mIHN1YmNsYXNzZXMgdGhhdCBwcm92aWRlIG1vcmUKKyAgICAgKiBleHRlbnNpdmUgY29uZGl0aW9uIG1vbml0b3JpbmcgZmFjaWxpdGllcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb25kaXRpb24gdGhlIGNvbmRpdGlvbgorICAgICAqIEByZXR1cm4gdGhlIGNvbGxlY3Rpb24gb2YgdGhyZWFkcworICAgICAqIEB0aHJvd3MgSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGxvY2sgaXMgbm90IGhlbGQKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gY29uZGl0aW9uIGlzCisgICAgICogICAgICAgICBub3QgYXNzb2NpYXRlZCB3aXRoIHRoaXMgbG9jaworICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGNvbmRpdGlvbiBpcyBudWxsCisgICAgICovCisgICAgcHJvdGVjdGVkIENvbGxlY3Rpb248VGhyZWFkPiBnZXRXYWl0aW5nVGhyZWFkcyhDb25kaXRpb24gY29uZGl0aW9uKSB7CisgICAgICAgIGlmIChjb25kaXRpb24gPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBpZiAoIShjb25kaXRpb24gaW5zdGFuY2VvZiBBYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplci5Db25kaXRpb25PYmplY3QpKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibm90IG93bmVyIik7CisgICAgICAgIHJldHVybiBzeW5jLmdldFdhaXRpbmdUaHJlYWRzKChBYnN0cmFjdFF1ZXVlZFN5bmNocm9uaXplci5Db25kaXRpb25PYmplY3QpY29uZGl0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGlkZW50aWZ5aW5nIHRoaXMgbG9jaywgYXMgd2VsbCBhcyBpdHMgbG9jayBzdGF0ZS4KKyAgICAgKiBUaGUgc3RhdGUsIGluIGJyYWNrZXRzLCBpbmNsdWRlcyB0aGUgU3RyaW5nIHtAY29kZSAiV3JpdGUgbG9ja3MgPSJ9CisgICAgICogZm9sbG93ZWQgYnkgdGhlIG51bWJlciBvZiByZWVudHJhbnRseSBoZWxkIHdyaXRlIGxvY2tzLCBhbmQgdGhlCisgICAgICogU3RyaW5nIHtAY29kZSAiUmVhZCBsb2NrcyA9In0gZm9sbG93ZWQgYnkgdGhlIG51bWJlciBvZiBoZWxkCisgICAgICogcmVhZCBsb2Nrcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgaWRlbnRpZnlpbmcgdGhpcyBsb2NrLCBhcyB3ZWxsIGFzIGl0cyBsb2NrIHN0YXRlCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgaW50IGMgPSBzeW5jLmdldENvdW50KCk7CisgICAgICAgIGludCB3ID0gU3luYy5leGNsdXNpdmVDb3VudChjKTsKKyAgICAgICAgaW50IHIgPSBTeW5jLnNoYXJlZENvdW50KGMpOworCisgICAgICAgIHJldHVybiBzdXBlci50b1N0cmluZygpICsKKyAgICAgICAgICAgICJbV3JpdGUgbG9ja3MgPSAiICsgdyArICIsIFJlYWQgbG9ja3MgPSAiICsgciArICJdIjsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9sb2Nrcy9VbnNhZmVBY2Nlc3MuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9sb2Nrcy9VbnNhZmVBY2Nlc3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wN2Y2NGU0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL1Vuc2FmZUFjY2Vzcy5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzOworCitpbXBvcnQgc3VuLm1pc2MuVW5zYWZlOworCisvKioKKyAqIEVhc3kgYWNjZXNzIHRvIHtAbGluayBVbnNhZmV9IGZvciB0aGUgcmVzdCBvZiB0aGlzIHBhY2thZ2UuCisgKi8KKy8qcGFja2FnZSovIGZpbmFsIGNsYXNzIFVuc2FmZUFjY2VzcyB7CisgICAgLyoqIG5vbi1udWxsOyB1bmlxdWUgaW5zdGFuY2Ugb2Yge0BsaW5rIFVuc2FmZX0gKi8KKyAgICAvKnBhY2thZ2UqLyBzdGF0aWMgZmluYWwgVW5zYWZlIFRIRV9PTkUgPSBVbnNhZmUuZ2V0VW5zYWZlKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNsYXNzIGlzIHVuaW5zdGFudGlhYmxlLgorICAgICAqLworICAgIHByaXZhdGUgVW5zYWZlQWNjZXNzKCkgeworICAgICAgICAvLyBUaGlzIHNwYWNlIGludGVudGlvbmFsbHkgbGVmdCBibGFuay4KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvbG9ja3MvcGFja2FnZS1pbmZvLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvbG9ja3MvcGFja2FnZS1pbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODYwYWNkZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9sb2Nrcy9wYWNrYWdlLWluZm8uamF2YQpAQCAtMCwwICsxLDUwIEBACisvKgorICogV3JpdHRlbiBieSBEb3VnIExlYSB3aXRoIGFzc2lzdGFuY2UgZnJvbSBtZW1iZXJzIG9mIEpDUCBKU1ItMTY2CisgKiBFeHBlcnQgR3JvdXAgYW5kIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgZG9tYWluLCBhcyBleHBsYWluZWQgYXQKKyAqIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbgorICovCisKKy8qKgorICogSW50ZXJmYWNlcyBhbmQgY2xhc3NlcyBwcm92aWRpbmcgYSBmcmFtZXdvcmsgZm9yIGxvY2tpbmcgYW5kIHdhaXRpbmcKKyAqIGZvciBjb25kaXRpb25zIHRoYXQgaXMgZGlzdGluY3QgZnJvbSBidWlsdC1pbiBzeW5jaHJvbml6YXRpb24gYW5kCisgKiBtb25pdG9ycy4gIFRoZSBmcmFtZXdvcmsgcGVybWl0cyBtdWNoIGdyZWF0ZXIgZmxleGliaWxpdHkgaW4gdGhlIHVzZSBvZgorICogbG9ja3MgYW5kIGNvbmRpdGlvbnMsIGF0IHRoZSBleHBlbnNlIG9mIG1vcmUgYXdrd2FyZCBzeW50YXguCisgKgorICogPHA+VGhlIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5Mb2NrfSBpbnRlcmZhY2Ugc3VwcG9ydHMKKyAqIGxvY2tpbmcgZGlzY2lwbGluZXMgdGhhdCBkaWZmZXIgaW4gc2VtYW50aWNzIChyZWVudHJhbnQsIGZhaXIsIGV0YyksCisgKiBhbmQgdGhhdCBjYW4gYmUgdXNlZCBpbiBub24tYmxvY2stc3RydWN0dXJlZCBjb250ZXh0cyBpbmNsdWRpbmcKKyAqIGhhbmQtb3Zlci1oYW5kIGFuZCBsb2NrIHJlb3JkZXJpbmcgYWxnb3JpdGhtcy4gIFRoZSBtYWluIGltcGxlbWVudGF0aW9uCisgKiBpcyB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3MuUmVlbnRyYW50TG9ja30uCisgKgorICogPHA+VGhlIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5SZWFkV3JpdGVMb2NrfSBpbnRlcmZhY2UKKyAqIHNpbWlsYXJseSBkZWZpbmVzIGxvY2tzIHRoYXQgbWF5IGJlIHNoYXJlZCBhbW9uZyByZWFkZXJzIGJ1dCBhcmUKKyAqIGV4Y2x1c2l2ZSB0byB3cml0ZXJzLiAgT25seSBhIHNpbmdsZSBpbXBsZW1lbnRhdGlvbiwge0BsaW5rCisgKiBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5SZWVudHJhbnRSZWFkV3JpdGVMb2NrfSwgaXMgcHJvdmlkZWQsIHNpbmNlCisgKiBpdCBjb3ZlcnMgbW9zdCBzdGFuZGFyZCB1c2FnZSBjb250ZXh0cy4gIEJ1dCBwcm9ncmFtbWVycyBtYXkgY3JlYXRlCisgKiB0aGVpciBvd24gaW1wbGVtZW50YXRpb25zIHRvIGNvdmVyIG5vbnN0YW5kYXJkIHJlcXVpcmVtZW50cy4KKyAqCisgKiA8cD5UaGUge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLkNvbmRpdGlvbn0gaW50ZXJmYWNlCisgKiBkZXNjcmliZXMgY29uZGl0aW9uIHZhcmlhYmxlcyB0aGF0IG1heSBiZSBhc3NvY2lhdGVkIHdpdGggTG9ja3MuCisgKiBUaGVzZSBhcmUgc2ltaWxhciBpbiB1c2FnZSB0byB0aGUgaW1wbGljaXQgbW9uaXRvcnMgYWNjZXNzZWQgdXNpbmcKKyAqIHtAY29kZSBPYmplY3Qud2FpdH0sIGJ1dCBvZmZlciBleHRlbmRlZCBjYXBhYmlsaXRpZXMuCisgKiBJbiBwYXJ0aWN1bGFyLCBtdWx0aXBsZSB7QGNvZGUgQ29uZGl0aW9ufSBvYmplY3RzIG1heSBiZSBhc3NvY2lhdGVkCisgKiB3aXRoIGEgc2luZ2xlIHtAY29kZSBMb2NrfS4gIFRvIGF2b2lkIGNvbXBhdGliaWxpdHkgaXNzdWVzLCB0aGUKKyAqIG5hbWVzIG9mIHtAY29kZSBDb25kaXRpb259IG1ldGhvZHMgYXJlIGRpZmZlcmVudCBmcm9tIHRoZQorICogY29ycmVzcG9uZGluZyB7QGNvZGUgT2JqZWN0fSB2ZXJzaW9ucy4KKyAqCisgKiA8cD5UaGUge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLkFic3RyYWN0UXVldWVkU3luY2hyb25pemVyfQorICogY2xhc3Mgc2VydmVzIGFzIGEgdXNlZnVsIHN1cGVyY2xhc3MgZm9yIGRlZmluaW5nIGxvY2tzIGFuZCBvdGhlcgorICogc3luY2hyb25pemVycyB0aGF0IHJlbHkgb24gcXVldWluZyBibG9ja2VkIHRocmVhZHMuICBUaGUge0BsaW5rCisgKiBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5BYnN0cmFjdFF1ZXVlZExvbmdTeW5jaHJvbml6ZXJ9IGNsYXNzCisgKiBwcm92aWRlcyB0aGUgc2FtZSBmdW5jdGlvbmFsaXR5IGJ1dCBleHRlbmRzIHN1cHBvcnQgdG8gNjQgYml0cyBvZgorICogc3luY2hyb25pemF0aW9uIHN0YXRlLiAgQm90aCBleHRlbmQgY2xhc3Mge0BsaW5rCisgKiBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5BYnN0cmFjdE93bmFibGVTeW5jaHJvbml6ZXJ9LCBhIHNpbXBsZQorICogY2xhc3MgdGhhdCBoZWxwcyByZWNvcmQgdGhlIHRocmVhZCBjdXJyZW50bHkgaG9sZGluZyBleGNsdXNpdmUKKyAqIHN5bmNocm9uaXphdGlvbi4gIFRoZSB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3MuTG9ja1N1cHBvcnR9CisgKiBjbGFzcyBwcm92aWRlcyBsb3dlci1sZXZlbCBibG9ja2luZyBhbmQgdW5ibG9ja2luZyBzdXBwb3J0IHRoYXQgaXMKKyAqIHVzZWZ1bCBmb3IgdGhvc2UgZGV2ZWxvcGVycyBpbXBsZW1lbnRpbmcgdGhlaXIgb3duIGN1c3RvbWl6ZWQgbG9jaworICogY2xhc3Nlcy4KKyAqCisgKiBAc2luY2UgMS41CisgKi8KK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3M7CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvcGFja2FnZS1pbmZvLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2NvbmN1cnJlbnQvcGFja2FnZS1pbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODUwOWE0MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvY29uY3VycmVudC9wYWNrYWdlLWluZm8uamF2YQpAQCAtMCwwICsxLDI1NiBAQAorLyoKKyAqIFdyaXR0ZW4gYnkgRG91ZyBMZWEgd2l0aCBhc3Npc3RhbmNlIGZyb20gbWVtYmVycyBvZiBKQ1AgSlNSLTE2NgorICogRXhwZXJ0IEdyb3VwIGFuZCByZWxlYXNlZCB0byB0aGUgcHVibGljIGRvbWFpbiwgYXMgZXhwbGFpbmVkIGF0CisgKiBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9wdWJsaWNkb21haW4KKyAqLworCisvLyBCRUdJTiBhbmRyb2lkLW5vdGUKKy8vIERyb3BwZWQgcmVmZXJlbmNlcyB0byB1bnJlbGVhc2VkIEFQSXMgKEZvcmtKb2luUG9vbCwgUGhhc2VyLCBldGMuKQorLy8gRU5EIGFuZHJvaWQtbm90ZQorCisvKioKKyAqIFV0aWxpdHkgY2xhc3NlcyBjb21tb25seSB1c2VmdWwgaW4gY29uY3VycmVudCBwcm9ncmFtbWluZy4gIFRoaXMKKyAqIHBhY2thZ2UgaW5jbHVkZXMgYSBmZXcgc21hbGwgc3RhbmRhcmRpemVkIGV4dGVuc2libGUgZnJhbWV3b3JrcywgYXMKKyAqIHdlbGwgYXMgc29tZSBjbGFzc2VzIHRoYXQgcHJvdmlkZSB1c2VmdWwgZnVuY3Rpb25hbGl0eSBhbmQgYXJlCisgKiBvdGhlcndpc2UgdGVkaW91cyBvciBkaWZmaWN1bHQgdG8gaW1wbGVtZW50LiAgSGVyZSBhcmUgYnJpZWYKKyAqIGRlc2NyaXB0aW9ucyBvZiB0aGUgbWFpbiBjb21wb25lbnRzLiAgU2VlIGFsc28gdGhlCisgKiB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3N9IGFuZAorICoge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pY30gcGFja2FnZXMuCisgKgorICogPGgyPkV4ZWN1dG9yczwvaDI+CisgKgorICogPGI+SW50ZXJmYWNlcy48L2I+CisgKgorICoge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yfSBpcyBhIHNpbXBsZSBzdGFuZGFyZGl6ZWQKKyAqIGludGVyZmFjZSBmb3IgZGVmaW5pbmcgY3VzdG9tIHRocmVhZC1saWtlIHN1YnN5c3RlbXMsIGluY2x1ZGluZworICogdGhyZWFkIHBvb2xzLCBhc3luY2hyb25vdXMgSU8sIGFuZCBsaWdodHdlaWdodCB0YXNrIGZyYW1ld29ya3MuCisgKiBEZXBlbmRpbmcgb24gd2hpY2ggY29uY3JldGUgRXhlY3V0b3IgY2xhc3MgaXMgYmVpbmcgdXNlZCwgdGFza3MgbWF5CisgKiBleGVjdXRlIGluIGEgbmV3bHkgY3JlYXRlZCB0aHJlYWQsIGFuIGV4aXN0aW5nIHRhc2stZXhlY3V0aW9uIHRocmVhZCwKKyAqIG9yIHRoZSB0aHJlYWQgY2FsbGluZyB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3IjZXhlY3V0ZQorICogZXhlY3V0ZX0sIGFuZCBtYXkgZXhlY3V0ZSBzZXF1ZW50aWFsbHkgb3IgY29uY3VycmVudGx5LgorICoKKyAqIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvclNlcnZpY2V9IHByb3ZpZGVzIGEgbW9yZQorICogY29tcGxldGUgYXN5bmNocm9ub3VzIHRhc2sgZXhlY3V0aW9uIGZyYW1ld29yay4gIEFuCisgKiBFeGVjdXRvclNlcnZpY2UgbWFuYWdlcyBxdWV1aW5nIGFuZCBzY2hlZHVsaW5nIG9mIHRhc2tzLAorICogYW5kIGFsbG93cyBjb250cm9sbGVkIHNodXRkb3duLgorICoKKyAqIFRoZSB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlfQorICogc3ViaW50ZXJmYWNlIGFuZCBhc3NvY2lhdGVkIGludGVyZmFjZXMgYWRkIHN1cHBvcnQgZm9yCisgKiBkZWxheWVkIGFuZCBwZXJpb2RpYyB0YXNrIGV4ZWN1dGlvbi4gIEV4ZWN1dG9yU2VydmljZXMKKyAqIHByb3ZpZGUgbWV0aG9kcyBhcnJhbmdpbmcgYXN5bmNocm9ub3VzIGV4ZWN1dGlvbiBvZiBhbnkKKyAqIGZ1bmN0aW9uIGV4cHJlc3NlZCBhcyB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuQ2FsbGFibGV9LAorICogdGhlIHJlc3VsdC1iZWFyaW5nIGFuYWxvZyBvZiB7QGxpbmsgamF2YS5sYW5nLlJ1bm5hYmxlfS4KKyAqCisgKiBBIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5GdXR1cmV9IHJldHVybnMgdGhlIHJlc3VsdHMgb2YKKyAqIGEgZnVuY3Rpb24sIGFsbG93cyBkZXRlcm1pbmF0aW9uIG9mIHdoZXRoZXIgZXhlY3V0aW9uIGhhcworICogY29tcGxldGVkLCBhbmQgcHJvdmlkZXMgYSBtZWFucyB0byBjYW5jZWwgZXhlY3V0aW9uLgorICoKKyAqIEEge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LlJ1bm5hYmxlRnV0dXJlfSBpcyBhIHtAY29kZSBGdXR1cmV9CisgKiB0aGF0IHBvc3Nlc3NlcyBhIHtAY29kZSBydW59IG1ldGhvZCB0aGF0IHVwb24gZXhlY3V0aW9uLAorICogc2V0cyBpdHMgcmVzdWx0cy4KKyAqCisgKiA8cD4KKyAqCisgKiA8Yj5JbXBsZW1lbnRhdGlvbnMuPC9iPgorICoKKyAqIENsYXNzZXMge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvcn0gYW5kCisgKiB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuU2NoZWR1bGVkVGhyZWFkUG9vbEV4ZWN1dG9yfQorICogcHJvdmlkZSB0dW5hYmxlLCBmbGV4aWJsZSB0aHJlYWQgcG9vbHMuCisgKgorICogVGhlIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcnN9IGNsYXNzIHByb3ZpZGVzCisgKiBmYWN0b3J5IG1ldGhvZHMgZm9yIHRoZSBtb3N0IGNvbW1vbiBraW5kcyBhbmQgY29uZmlndXJhdGlvbnMKKyAqIG9mIEV4ZWN1dG9ycywgYXMgd2VsbCBhcyBhIGZldyB1dGlsaXR5IG1ldGhvZHMgZm9yIHVzaW5nCisgKiB0aGVtLiAgT3RoZXIgdXRpbGl0aWVzIGJhc2VkIG9uIHtAY29kZSBFeGVjdXRvcnN9IGluY2x1ZGUgdGhlCisgKiBjb25jcmV0ZSBjbGFzcyB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuRnV0dXJlVGFza30KKyAqIHByb3ZpZGluZyBhIGNvbW1vbiBleHRlbnNpYmxlIGltcGxlbWVudGF0aW9uIG9mIEZ1dHVyZXMsIGFuZAorICoge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yQ29tcGxldGlvblNlcnZpY2V9LCB0aGF0CisgKiBhc3Npc3RzIGluIGNvb3JkaW5hdGluZyB0aGUgcHJvY2Vzc2luZyBvZiBncm91cHMgb2YKKyAqIGFzeW5jaHJvbm91cyB0YXNrcy4KKyAqCisgKiA8aDI+UXVldWVzPC9oMj4KKyAqCisgKiBUaGUge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LkNvbmN1cnJlbnRMaW5rZWRRdWV1ZX0gY2xhc3MKKyAqIHN1cHBsaWVzIGFuIGVmZmljaWVudCBzY2FsYWJsZSB0aHJlYWQtc2FmZSBub24tYmxvY2tpbmcgRklGTworICogcXVldWUuCisgKgorICogPHA+Rml2ZSBpbXBsZW1lbnRhdGlvbnMgaW4ge0Bjb2RlIGphdmEudXRpbC5jb25jdXJyZW50fSBzdXBwb3J0CisgKiB0aGUgZXh0ZW5kZWQge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LkJsb2NraW5nUXVldWV9CisgKiBpbnRlcmZhY2UsIHRoYXQgZGVmaW5lcyBibG9ja2luZyB2ZXJzaW9ucyBvZiBwdXQgYW5kIHRha2U6CisgKiB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuTGlua2VkQmxvY2tpbmdRdWV1ZX0sCisgKiB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuQXJyYXlCbG9ja2luZ1F1ZXVlfSwKKyAqIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5TeW5jaHJvbm91c1F1ZXVlfSwKKyAqIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5Qcmlvcml0eUJsb2NraW5nUXVldWV9LCBhbmQKKyAqIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5EZWxheVF1ZXVlfS4KKyAqIFRoZSBkaWZmZXJlbnQgY2xhc3NlcyBjb3ZlciB0aGUgbW9zdCBjb21tb24gdXNhZ2UgY29udGV4dHMKKyAqIGZvciBwcm9kdWNlci1jb25zdW1lciwgbWVzc2FnaW5nLCBwYXJhbGxlbCB0YXNraW5nLCBhbmQKKyAqIHJlbGF0ZWQgY29uY3VycmVudCBkZXNpZ25zLgorICoKKyAqIDxwPlRoZSB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuQmxvY2tpbmdEZXF1ZX0gaW50ZXJmYWNlCisgKiBleHRlbmRzIHtAY29kZSBCbG9ja2luZ1F1ZXVlfSB0byBzdXBwb3J0IGJvdGggRklGTyBhbmQgTElGTworICogKHN0YWNrLWJhc2VkKSBvcGVyYXRpb25zLgorICogQ2xhc3Mge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LkxpbmtlZEJsb2NraW5nRGVxdWV9CisgKiBwcm92aWRlcyBhbiBpbXBsZW1lbnRhdGlvbi4KKyAqCisgKiA8aDI+VGltaW5nPC9oMj4KKyAqCisgKiBUaGUge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0fSBjbGFzcyBwcm92aWRlcworICogbXVsdGlwbGUgZ3JhbnVsYXJpdGllcyAoaW5jbHVkaW5nIG5hbm9zZWNvbmRzKSBmb3IKKyAqIHNwZWNpZnlpbmcgYW5kIGNvbnRyb2xsaW5nIHRpbWUtb3V0IGJhc2VkIG9wZXJhdGlvbnMuICBNb3N0CisgKiBjbGFzc2VzIGluIHRoZSBwYWNrYWdlIGNvbnRhaW4gb3BlcmF0aW9ucyBiYXNlZCBvbiB0aW1lLW91dHMKKyAqIGluIGFkZGl0aW9uIHRvIGluZGVmaW5pdGUgd2FpdHMuICBJbiBhbGwgY2FzZXMgdGhhdAorICogdGltZS1vdXRzIGFyZSB1c2VkLCB0aGUgdGltZS1vdXQgc3BlY2lmaWVzIHRoZSBtaW5pbXVtIHRpbWUKKyAqIHRoYXQgdGhlIG1ldGhvZCBzaG91bGQgd2FpdCBiZWZvcmUgaW5kaWNhdGluZyB0aGF0IGl0CisgKiB0aW1lZC1vdXQuICBJbXBsZW1lbnRhdGlvbnMgbWFrZSBhICZxdW90O2Jlc3QgZWZmb3J0JnF1b3Q7CisgKiB0byBkZXRlY3QgdGltZS1vdXRzIGFzIHNvb24gYXMgcG9zc2libGUgYWZ0ZXIgdGhleSBvY2N1ci4KKyAqIEhvd2V2ZXIsIGFuIGluZGVmaW5pdGUgYW1vdW50IG9mIHRpbWUgbWF5IGVsYXBzZSBiZXR3ZWVuIGEKKyAqIHRpbWUtb3V0IGJlaW5nIGRldGVjdGVkIGFuZCBhIHRocmVhZCBhY3R1YWxseSBleGVjdXRpbmcKKyAqIGFnYWluIGFmdGVyIHRoYXQgdGltZS1vdXQuICBBbGwgbWV0aG9kcyB0aGF0IGFjY2VwdCB0aW1lb3V0CisgKiBwYXJhbWV0ZXJzIHRyZWF0IHZhbHVlcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gemVybyB0byBtZWFuCisgKiBub3QgdG8gd2FpdCBhdCBhbGwuICBUbyB3YWl0ICJmb3JldmVyIiwgeW91IGNhbiB1c2UgYSB2YWx1ZQorICogb2Yge0Bjb2RlIExvbmcuTUFYX1ZBTFVFfS4KKyAqCisgKiA8aDI+U3luY2hyb25pemVyczwvaDI+CisgKgorICogRml2ZSBjbGFzc2VzIGFpZCBjb21tb24gc3BlY2lhbC1wdXJwb3NlIHN5bmNocm9uaXphdGlvbiBpZGlvbXMuCisgKiA8dWw+CisgKgorICogPGxpPntAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5TZW1hcGhvcmV9IGlzIGEgY2xhc3NpYyBjb25jdXJyZW5jeSB0b29sLgorICoKKyAqIDxsaT57QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuQ291bnREb3duTGF0Y2h9IGlzIGEgdmVyeSBzaW1wbGUgeWV0CisgKiB2ZXJ5IGNvbW1vbiB1dGlsaXR5IGZvciBibG9ja2luZyB1bnRpbCBhIGdpdmVuIG51bWJlciBvZiBzaWduYWxzLAorICogZXZlbnRzLCBvciBjb25kaXRpb25zIGhvbGQuCisgKgorICogPGxpPkEge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LkN5Y2xpY0JhcnJpZXJ9IGlzIGEgcmVzZXR0YWJsZQorICogbXVsdGl3YXkgc3luY2hyb25pemF0aW9uIHBvaW50IHVzZWZ1bCBpbiBzb21lIHN0eWxlcyBvZiBwYXJhbGxlbAorICogcHJvZ3JhbW1pbmcuCisgKgorICogPGxpPkFuIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5FeGNoYW5nZXJ9IGFsbG93cyB0d28gdGhyZWFkcyB0bworICogZXhjaGFuZ2Ugb2JqZWN0cyBhdCBhIHJlbmRlenZvdXMgcG9pbnQsIGFuZCBpcyB1c2VmdWwgaW4gc2V2ZXJhbAorICogcGlwZWxpbmUgZGVzaWducy4KKyAqCisgKiA8L3VsPgorICoKKyAqIDxoMj5Db25jdXJyZW50IENvbGxlY3Rpb25zPC9oMj4KKyAqCisgKiBCZXNpZGVzIFF1ZXVlcywgdGhpcyBwYWNrYWdlIHN1cHBsaWVzIENvbGxlY3Rpb24gaW1wbGVtZW50YXRpb25zCisgKiBkZXNpZ25lZCBmb3IgdXNlIGluIG11bHRpdGhyZWFkZWQgY29udGV4dHM6CisgKiB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudEhhc2hNYXB9LAorICoge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LkNvbmN1cnJlbnRTa2lwTGlzdE1hcH0sCisgKiB7QGxpbmsgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudFNraXBMaXN0U2V0fSwKKyAqIHtAbGluayBqYXZhLnV0aWwuY29uY3VycmVudC5Db3B5T25Xcml0ZUFycmF5TGlzdH0sIGFuZAorICoge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LkNvcHlPbldyaXRlQXJyYXlTZXR9LgorICogV2hlbiBtYW55IHRocmVhZHMgYXJlIGV4cGVjdGVkIHRvIGFjY2VzcyBhIGdpdmVuIGNvbGxlY3Rpb24sIGEKKyAqIHtAY29kZSBDb25jdXJyZW50SGFzaE1hcH0gaXMgbm9ybWFsbHkgcHJlZmVyYWJsZSB0byBhIHN5bmNocm9uaXplZAorICoge0Bjb2RlIEhhc2hNYXB9LCBhbmQgYSB7QGNvZGUgQ29uY3VycmVudFNraXBMaXN0TWFwfSBpcyBub3JtYWxseQorICogcHJlZmVyYWJsZSB0byBhIHN5bmNocm9uaXplZCB7QGNvZGUgVHJlZU1hcH0uCisgKiBBIHtAY29kZSBDb3B5T25Xcml0ZUFycmF5TGlzdH0gaXMgcHJlZmVyYWJsZSB0byBhIHN5bmNocm9uaXplZAorICoge0Bjb2RlIEFycmF5TGlzdH0gd2hlbiB0aGUgZXhwZWN0ZWQgbnVtYmVyIG9mIHJlYWRzIGFuZCB0cmF2ZXJzYWxzCisgKiBncmVhdGx5IG91dG51bWJlciB0aGUgbnVtYmVyIG9mIHVwZGF0ZXMgdG8gYSBsaXN0LgorCisgKiA8cD5UaGUgIkNvbmN1cnJlbnQiIHByZWZpeCB1c2VkIHdpdGggc29tZSBjbGFzc2VzIGluIHRoaXMgcGFja2FnZQorICogaXMgYSBzaG9ydGhhbmQgaW5kaWNhdGluZyBzZXZlcmFsIGRpZmZlcmVuY2VzIGZyb20gc2ltaWxhcgorICogInN5bmNocm9uaXplZCIgY2xhc3Nlcy4gIEZvciBleGFtcGxlIHtAY29kZSBqYXZhLnV0aWwuSGFzaHRhYmxlfSBhbmQKKyAqIHtAY29kZSBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRNYXAobmV3IEhhc2hNYXAoKSl9IGFyZQorICogc3luY2hyb25pemVkLiAgQnV0IHtAbGluaworICogamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudEhhc2hNYXB9IGlzICJjb25jdXJyZW50Ii4gIEEKKyAqIGNvbmN1cnJlbnQgY29sbGVjdGlvbiBpcyB0aHJlYWQtc2FmZSwgYnV0IG5vdCBnb3Zlcm5lZCBieSBhCisgKiBzaW5nbGUgZXhjbHVzaW9uIGxvY2suICBJbiB0aGUgcGFydGljdWxhciBjYXNlIG9mCisgKiBDb25jdXJyZW50SGFzaE1hcCwgaXQgc2FmZWx5IHBlcm1pdHMgYW55IG51bWJlciBvZgorICogY29uY3VycmVudCByZWFkcyBhcyB3ZWxsIGFzIGEgdHVuYWJsZSBudW1iZXIgb2YgY29uY3VycmVudAorICogd3JpdGVzLiAgIlN5bmNocm9uaXplZCIgY2xhc3NlcyBjYW4gYmUgdXNlZnVsIHdoZW4geW91IG5lZWQKKyAqIHRvIHByZXZlbnQgYWxsIGFjY2VzcyB0byBhIGNvbGxlY3Rpb24gdmlhIGEgc2luZ2xlIGxvY2ssIGF0CisgKiB0aGUgZXhwZW5zZSBvZiBwb29yZXIgc2NhbGFiaWxpdHkuICBJbiBvdGhlciBjYXNlcyBpbiB3aGljaAorICogbXVsdGlwbGUgdGhyZWFkcyBhcmUgZXhwZWN0ZWQgdG8gYWNjZXNzIGEgY29tbW9uIGNvbGxlY3Rpb24sCisgKiAiY29uY3VycmVudCIgdmVyc2lvbnMgYXJlIG5vcm1hbGx5IHByZWZlcmFibGUuICBBbmQKKyAqIHVuc3luY2hyb25pemVkIGNvbGxlY3Rpb25zIGFyZSBwcmVmZXJhYmxlIHdoZW4gZWl0aGVyCisgKiBjb2xsZWN0aW9ucyBhcmUgdW5zaGFyZWQsIG9yIGFyZSBhY2Nlc3NpYmxlIG9ubHkgd2hlbgorICogaG9sZGluZyBvdGhlciBsb2Nrcy4KKyAqCisgKiA8cD5Nb3N0IGNvbmN1cnJlbnQgQ29sbGVjdGlvbiBpbXBsZW1lbnRhdGlvbnMgKGluY2x1ZGluZyBtb3N0CisgKiBRdWV1ZXMpIGFsc28gZGlmZmVyIGZyb20gdGhlIHVzdWFsIGphdmEudXRpbCBjb252ZW50aW9ucyBpbiB0aGF0CisgKiB0aGVpciBJdGVyYXRvcnMgcHJvdmlkZSA8ZW0+d2Vha2x5IGNvbnNpc3RlbnQ8L2VtPiByYXRoZXIgdGhhbgorICogZmFzdC1mYWlsIHRyYXZlcnNhbC4gIEEgd2Vha2x5IGNvbnNpc3RlbnQgaXRlcmF0b3IgaXMgdGhyZWFkLXNhZmUsCisgKiBidXQgZG9lcyBub3QgbmVjZXNzYXJpbHkgZnJlZXplIHRoZSBjb2xsZWN0aW9uIHdoaWxlIGl0ZXJhdGluZywgc28KKyAqIGl0IG1heSAob3IgbWF5IG5vdCkgcmVmbGVjdCBhbnkgdXBkYXRlcyBzaW5jZSB0aGUgaXRlcmF0b3Igd2FzCisgKiBjcmVhdGVkLgorICoKKyAqIDxoMj48YSBuYW1lPSJNZW1vcnlWaXNpYmlsaXR5Ij5NZW1vcnkgQ29uc2lzdGVuY3kgUHJvcGVydGllczwvYT48L2gyPgorICoKKyAqIDxhIGhyZWY9Imh0dHA6Ly9qYXZhLnN1bi5jb20vZG9jcy9ib29rcy9qbHMvdGhpcmRfZWRpdGlvbi9odG1sL21lbW9yeS5odG1sIj4KKyAqIENoYXB0ZXIgMTcgb2YgdGhlIEphdmEgTGFuZ3VhZ2UgU3BlY2lmaWNhdGlvbjwvYT4gZGVmaW5lcyB0aGUKKyAqIDxpPmhhcHBlbnMtYmVmb3JlPC9pPiByZWxhdGlvbiBvbiBtZW1vcnkgb3BlcmF0aW9ucyBzdWNoIGFzIHJlYWRzIGFuZAorICogd3JpdGVzIG9mIHNoYXJlZCB2YXJpYWJsZXMuICBUaGUgcmVzdWx0cyBvZiBhIHdyaXRlIGJ5IG9uZSB0aHJlYWQgYXJlCisgKiBndWFyYW50ZWVkIHRvIGJlIHZpc2libGUgdG8gYSByZWFkIGJ5IGFub3RoZXIgdGhyZWFkIG9ubHkgaWYgdGhlIHdyaXRlCisgKiBvcGVyYXRpb24gPGk+aGFwcGVucy1iZWZvcmU8L2k+IHRoZSByZWFkIG9wZXJhdGlvbi4gIFRoZQorICoge0Bjb2RlIHN5bmNocm9uaXplZH0gYW5kIHtAY29kZSB2b2xhdGlsZX0gY29uc3RydWN0cywgYXMgd2VsbCBhcyB0aGUKKyAqIHtAY29kZSBUaHJlYWQuc3RhcnQoKX0gYW5kIHtAY29kZSBUaHJlYWQuam9pbigpfSBtZXRob2RzLCBjYW4gZm9ybQorICogPGk+aGFwcGVucy1iZWZvcmU8L2k+IHJlbGF0aW9uc2hpcHMuICBJbiBwYXJ0aWN1bGFyOgorICoKKyAqIDx1bD4KKyAqICAgPGxpPkVhY2ggYWN0aW9uIGluIGEgdGhyZWFkIDxpPmhhcHBlbnMtYmVmb3JlPC9pPiBldmVyeSBhY3Rpb24gaW4gdGhhdAorICogICB0aHJlYWQgdGhhdCBjb21lcyBsYXRlciBpbiB0aGUgcHJvZ3JhbSdzIG9yZGVyLgorICoKKyAqICAgPGxpPkFuIHVubG9jayAoe0Bjb2RlIHN5bmNocm9uaXplZH0gYmxvY2sgb3IgbWV0aG9kIGV4aXQpIG9mIGEKKyAqICAgbW9uaXRvciA8aT5oYXBwZW5zLWJlZm9yZTwvaT4gZXZlcnkgc3Vic2VxdWVudCBsb2NrICh7QGNvZGUgc3luY2hyb25pemVkfQorICogICBibG9jayBvciBtZXRob2QgZW50cnkpIG9mIHRoYXQgc2FtZSBtb25pdG9yLiAgQW5kIGJlY2F1c2UKKyAqICAgdGhlIDxpPmhhcHBlbnMtYmVmb3JlPC9pPiByZWxhdGlvbiBpcyB0cmFuc2l0aXZlLCBhbGwgYWN0aW9ucworICogICBvZiBhIHRocmVhZCBwcmlvciB0byB1bmxvY2tpbmcgPGk+aGFwcGVuLWJlZm9yZTwvaT4gYWxsIGFjdGlvbnMKKyAqICAgc3Vic2VxdWVudCB0byBhbnkgdGhyZWFkIGxvY2tpbmcgdGhhdCBtb25pdG9yLgorICoKKyAqICAgPGxpPkEgd3JpdGUgdG8gYSB7QGNvZGUgdm9sYXRpbGV9IGZpZWxkIDxpPmhhcHBlbnMtYmVmb3JlPC9pPiBldmVyeQorICogICBzdWJzZXF1ZW50IHJlYWQgb2YgdGhhdCBzYW1lIGZpZWxkLiAgV3JpdGVzIGFuZCByZWFkcyBvZgorICogICB7QGNvZGUgdm9sYXRpbGV9IGZpZWxkcyBoYXZlIHNpbWlsYXIgbWVtb3J5IGNvbnNpc3RlbmN5IGVmZmVjdHMKKyAqICAgYXMgZW50ZXJpbmcgYW5kIGV4aXRpbmcgbW9uaXRvcnMsIGJ1dCBkbyA8ZW0+bm90PC9lbT4gZW50YWlsCisgKiAgIG11dHVhbCBleGNsdXNpb24gbG9ja2luZy4KKyAqCisgKiAgIDxsaT5BIGNhbGwgdG8ge0Bjb2RlIHN0YXJ0fSBvbiBhIHRocmVhZCA8aT5oYXBwZW5zLWJlZm9yZTwvaT4gYW55CisgKiAgIGFjdGlvbiBpbiB0aGUgc3RhcnRlZCB0aHJlYWQuCisgKgorICogICA8bGk+QWxsIGFjdGlvbnMgaW4gYSB0aHJlYWQgPGk+aGFwcGVuLWJlZm9yZTwvaT4gYW55IG90aGVyIHRocmVhZAorICogICBzdWNjZXNzZnVsbHkgcmV0dXJucyBmcm9tIGEge0Bjb2RlIGpvaW59IG9uIHRoYXQgdGhyZWFkLgorICoKKyAqIDwvdWw+CisgKgorICoKKyAqIFRoZSBtZXRob2RzIG9mIGFsbCBjbGFzc2VzIGluIHtAY29kZSBqYXZhLnV0aWwuY29uY3VycmVudH0gYW5kIGl0cworICogc3VicGFja2FnZXMgZXh0ZW5kIHRoZXNlIGd1YXJhbnRlZXMgdG8gaGlnaGVyLWxldmVsCisgKiBzeW5jaHJvbml6YXRpb24uICBJbiBwYXJ0aWN1bGFyOgorICoKKyAqIDx1bD4KKyAqCisgKiAgIDxsaT5BY3Rpb25zIGluIGEgdGhyZWFkIHByaW9yIHRvIHBsYWNpbmcgYW4gb2JqZWN0IGludG8gYW55IGNvbmN1cnJlbnQKKyAqICAgY29sbGVjdGlvbiA8aT5oYXBwZW4tYmVmb3JlPC9pPiBhY3Rpb25zIHN1YnNlcXVlbnQgdG8gdGhlIGFjY2VzcyBvcgorICogICByZW1vdmFsIG9mIHRoYXQgZWxlbWVudCBmcm9tIHRoZSBjb2xsZWN0aW9uIGluIGFub3RoZXIgdGhyZWFkLgorICoKKyAqICAgPGxpPkFjdGlvbnMgaW4gYSB0aHJlYWQgcHJpb3IgdG8gdGhlIHN1Ym1pc3Npb24gb2YgYSB7QGNvZGUgUnVubmFibGV9CisgKiAgIHRvIGFuIHtAY29kZSBFeGVjdXRvcn0gPGk+aGFwcGVuLWJlZm9yZTwvaT4gaXRzIGV4ZWN1dGlvbiBiZWdpbnMuCisgKiAgIFNpbWlsYXJseSBmb3Ige0Bjb2RlIENhbGxhYmxlc30gc3VibWl0dGVkIHRvIGFuIHtAY29kZSBFeGVjdXRvclNlcnZpY2V9LgorICoKKyAqICAgPGxpPkFjdGlvbnMgdGFrZW4gYnkgdGhlIGFzeW5jaHJvbm91cyBjb21wdXRhdGlvbiByZXByZXNlbnRlZCBieSBhCisgKiAgIHtAY29kZSBGdXR1cmV9IDxpPmhhcHBlbi1iZWZvcmU8L2k+IGFjdGlvbnMgc3Vic2VxdWVudCB0byB0aGUKKyAqICAgcmV0cmlldmFsIG9mIHRoZSByZXN1bHQgdmlhIHtAY29kZSBGdXR1cmUuZ2V0KCl9IGluIGFub3RoZXIgdGhyZWFkLgorICoKKyAqICAgPGxpPkFjdGlvbnMgcHJpb3IgdG8gInJlbGVhc2luZyIgc3luY2hyb25pemVyIG1ldGhvZHMgc3VjaCBhcworICogICB7QGNvZGUgTG9jay51bmxvY2t9LCB7QGNvZGUgU2VtYXBob3JlLnJlbGVhc2V9LCBhbmQKKyAqICAge0Bjb2RlIENvdW50RG93bkxhdGNoLmNvdW50RG93bn0gPGk+aGFwcGVuLWJlZm9yZTwvaT4gYWN0aW9ucworICogICBzdWJzZXF1ZW50IHRvIGEgc3VjY2Vzc2Z1bCAiYWNxdWlyaW5nIiBtZXRob2Qgc3VjaCBhcworICogICB7QGNvZGUgTG9jay5sb2NrfSwge0Bjb2RlIFNlbWFwaG9yZS5hY3F1aXJlfSwKKyAqICAge0Bjb2RlIENvbmRpdGlvbi5hd2FpdH0sIGFuZCB7QGNvZGUgQ291bnREb3duTGF0Y2guYXdhaXR9IG9uIHRoZQorICogICBzYW1lIHN5bmNocm9uaXplciBvYmplY3QgaW4gYW5vdGhlciB0aHJlYWQuCisgKgorICogICA8bGk+Rm9yIGVhY2ggcGFpciBvZiB0aHJlYWRzIHRoYXQgc3VjY2Vzc2Z1bGx5IGV4Y2hhbmdlIG9iamVjdHMgdmlhCisgKiAgIGFuIHtAY29kZSBFeGNoYW5nZXJ9LCBhY3Rpb25zIHByaW9yIHRvIHRoZSB7QGNvZGUgZXhjaGFuZ2UoKX0KKyAqICAgaW4gZWFjaCB0aHJlYWQgPGk+aGFwcGVuLWJlZm9yZTwvaT4gdGhvc2Ugc3Vic2VxdWVudCB0byB0aGUKKyAqICAgY29ycmVzcG9uZGluZyB7QGNvZGUgZXhjaGFuZ2UoKX0gaW4gYW5vdGhlciB0aHJlYWQuCisgKgorICogICA8bGk+QWN0aW9ucyBwcmlvciB0byBjYWxsaW5nIHtAY29kZSBDeWNsaWNCYXJyaWVyLmF3YWl0fQorICogICA8aT5oYXBwZW4tYmVmb3JlPC9pPiBhY3Rpb25zIHBlcmZvcm1lZCBieSB0aGUgYmFycmllciBhY3Rpb24sIGFuZAorICogICBhY3Rpb25zIHBlcmZvcm1lZCBieSB0aGUgYmFycmllciBhY3Rpb24gPGk+aGFwcGVuLWJlZm9yZTwvaT4gYWN0aW9ucworICogICBzdWJzZXF1ZW50IHRvIGEgc3VjY2Vzc2Z1bCByZXR1cm4gZnJvbSB0aGUgY29ycmVzcG9uZGluZyB7QGNvZGUgYXdhaXR9CisgKiAgIGluIG90aGVyIHRocmVhZHMuCisgKgorICogPC91bD4KKyAqCisgKiBAc2luY2UgMS41CisgKi8KK3BhY2thZ2UgamF2YS51dGlsLmNvbmN1cnJlbnQ7CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2phci9BdHRyaWJ1dGVzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2phci9BdHRyaWJ1dGVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDgwMDhjZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvamFyL0F0dHJpYnV0ZXMuamF2YQpAQCAtMCwwICsxLDQyOCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmphcjsKKworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCisvKioKKyAqIFRoZSB7QGNvZGUgQXR0cmlidXRlc30gY2xhc3MgaXMgdXNlZCB0byBzdG9yZSB2YWx1ZXMgZm9yIG1hbmlmZXN0IGVudHJpZXMuCisgKiBBdHRyaWJ1dGUga2V5cyBhcmUgZ2VuZXJhbGx5IGluc3RhbmNlcyBvZiB7QGNvZGUgQXR0cmlidXRlcy5OYW1lfS4gVmFsdWVzCisgKiBhc3NvY2lhdGVkIHdpdGggYXR0cmlidXRlIGtleXMgYXJlIG9mIHR5cGUge0Bjb2RlIFN0cmluZ30uCisgKi8KK3B1YmxpYyBjbGFzcyBBdHRyaWJ1dGVzIGltcGxlbWVudHMgQ2xvbmVhYmxlLCBNYXA8T2JqZWN0LCBPYmplY3Q+IHsKKworICAgIC8qKgorICAgICAqIFRoZSB7QGNvZGUgQXR0cmlidXRlc30gYXMgbmFtZS92YWx1ZSBwYWlycy4gTWFwcyB0aGUgYXR0cmlidXRlIG5hbWVzIChhcworICAgICAqIHtAbGluayBBdHRyaWJ1dGVzLk5hbWV9KSBvZiBhIEpBUiBmaWxlIG1hbmlmZXN0IHRvIGFyYml0cmFyeSB2YWx1ZXMuIFRoZQorICAgICAqIGF0dHJpYnV0ZSBuYW1lcyB0aHVzIGFyZSBvYnRhaW5lZCBmcm9tIHRoZSB7QGxpbmsgTWFuaWZlc3R9IGZvcgorICAgICAqIGNvbnZlbmllbmNlLgorICAgICAqLworICAgIHByb3RlY3RlZCBNYXA8T2JqZWN0LCBPYmplY3Q+IG1hcDsKKworICAgIC8qKgorICAgICAqIFRoZSBuYW1lIHBhcnQgb2YgdGhlIG5hbWUvdmFsdWUgcGFpcnMgY29uc3RpdHV0aW5nIGFuIGF0dHJpYnV0ZSBhcworICAgICAqIGRlZmluZWQgYnkgdGhlIHNwZWNpZmljYXRpb24gb2YgdGhlIEpBUiBtYW5pZmVzdC4gTWF5IGJlIGNvbXBvc2VkIG9mIHRoZQorICAgICAqIGZvbGxvd2luZyBBU0NJSSBzaWducyBhcyBkZWZpbmVkIGluIHRoZSBFQk5GIGJlbG93OgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiBuYW1lICAgICAgID0gYWxwaGFudW0gKmhlYWRlcmNoYXIKKyAgICAgKiBoZWFkZXJjaGFyID0gYWxwaGFudW0gfCAtIHwgXworICAgICAqIGFscGhhbnVtICAgPSB7QS1afSB8IHthLXp9IHwgezAtOX0KKyAgICAgKiA8L3ByZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE5hbWUgeworICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBuYW1lOworCisgICAgICAgIC8qKiBUaGUgY2xhc3MgcGF0aCAoYSBtYWluIGF0dHJpYnV0ZSkuICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTmFtZSBDTEFTU19QQVRIID0gbmV3IE5hbWUoIkNsYXNzLVBhdGgiKTsKKworICAgICAgICAvKiogVGhlIHZlcnNpb24gb2YgdGhlIG1hbmlmZXN0IGZpbGUgKGEgbWFpbiBhdHRyaWJ1dGUpLiAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE5hbWUgTUFOSUZFU1RfVkVSU0lPTiA9IG5ldyBOYW1lKCJNYW5pZmVzdC1WZXJzaW9uIik7CisKKyAgICAgICAgLyoqIFRoZSBtYWluIGNsYXNzJ3MgbmFtZSAoZm9yIHN0YW5kLWFsb25lIGFwcGxpY2F0aW9ucykuICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTmFtZSBNQUlOX0NMQVNTID0gbmV3IE5hbWUoIk1haW4tQ2xhc3MiKTsKKworICAgICAgICAvKiogRGVmaW5lcyB0aGUgc2lnbmF0dXJlIHZlcnNpb24gb2YgdGhlIEpBUiBmaWxlLiAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE5hbWUgU0lHTkFUVVJFX1ZFUlNJT04gPSBuZXcgTmFtZSgiU2lnbmF0dXJlLVZlcnNpb24iKTsKKworICAgICAgICAvKiogVGhlIHtAY29kZSBDb250ZW50LVR5cGV9IG1hbmlmZXN0IGF0dHJpYnV0ZS4gKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBOYW1lIENPTlRFTlRfVFlQRSA9IG5ldyBOYW1lKCJDb250ZW50LVR5cGUiKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHtAY29kZSBTZWFsZWR9IG1hbmlmZXN0IGF0dHJpYnV0ZSB3aGljaCBtYXkgaGF2ZSB0aGUgdmFsdWUKKyAgICAgICAgICoge0Bjb2RlIHRydWV9IGZvciBzZWFsZWQgYXJjaGl2ZXMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE5hbWUgU0VBTEVEID0gbmV3IE5hbWUoIlNlYWxlZCIpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUge0Bjb2RlIEltcGxlbWVudGF0aW9uLVRpdGxlfSBhdHRyaWJ1dGUgd2hvc2UgdmFsdWUgaXMgYSBzdHJpbmcKKyAgICAgICAgICogdGhhdCBkZWZpbmVzIHRoZSB0aXRsZSBvZiB0aGUgZXh0ZW5zaW9uIGltcGxlbWVudGF0aW9uLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBOYW1lIElNUExFTUVOVEFUSU9OX1RJVExFID0gbmV3IE5hbWUoIkltcGxlbWVudGF0aW9uLVRpdGxlIik7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB7QGNvZGUgSW1wbGVtZW50YXRpb24tVmVyc2lvbn0gYXR0cmlidXRlIGRlZmluaW5nIHRoZSB2ZXJzaW9uIG9mCisgICAgICAgICAqIHRoZSBleHRlbnNpb24gaW1wbGVtZW50YXRpb24uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE5hbWUgSU1QTEVNRU5UQVRJT05fVkVSU0lPTiA9IG5ldyBOYW1lKCJJbXBsZW1lbnRhdGlvbi1WZXJzaW9uIik7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB7QGNvZGUgSW1wbGVtZW50YXRpb24tVmVuZG9yfSBhdHRyaWJ1dGUgZGVmaW5pbmcgdGhlIG9yZ2FuaXphdGlvbgorICAgICAgICAgKiB0aGF0IG1haW50YWlucyB0aGUgZXh0ZW5zaW9uIGltcGxlbWVudGF0aW9uLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBOYW1lIElNUExFTUVOVEFUSU9OX1ZFTkRPUiA9IG5ldyBOYW1lKCJJbXBsZW1lbnRhdGlvbi1WZW5kb3IiKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHtAY29kZSBTcGVjaWZpY2F0aW9uLVRpdGxlfSBhdHRyaWJ1dGUgZGVmaW5pbmcgdGhlIHRpdGxlIG9mIHRoZQorICAgICAgICAgKiBleHRlbnNpb24gc3BlY2lmaWNhdGlvbi4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTmFtZSBTUEVDSUZJQ0FUSU9OX1RJVExFID0gbmV3IE5hbWUoIlNwZWNpZmljYXRpb24tVGl0bGUiKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHtAY29kZSBTcGVjaWZpY2F0aW9uLVZlcnNpb259IGF0dHJpYnV0ZSBkZWZpbmluZyB0aGUgdmVyc2lvbiBvZgorICAgICAgICAgKiB0aGUgZXh0ZW5zaW9uIHNwZWNpZmljYXRpb24uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE5hbWUgU1BFQ0lGSUNBVElPTl9WRVJTSU9OID0gbmV3IE5hbWUoIlNwZWNpZmljYXRpb24tVmVyc2lvbiIpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUge0Bjb2RlIFNwZWNpZmljYXRpb24tVmVuZG9yfSBhdHRyaWJ1dGUgZGVmaW5pbmcgdGhlIG9yZ2FuaXphdGlvbgorICAgICAgICAgKiB0aGF0IG1haW50YWlucyB0aGUgZXh0ZW5zaW9uIHNwZWNpZmljYXRpb24uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE5hbWUgU1BFQ0lGSUNBVElPTl9WRU5ET1IgPSBuZXcgTmFtZSgiU3BlY2lmaWNhdGlvbi1WZW5kb3IiKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHtAY29kZSBFeHRlbnNpb24tTGlzdH0gYXR0cmlidXRlIGRlZmluaW5nIHRoZSBleHRlbnNpb25zIHRoYXQgYXJlCisgICAgICAgICAqIG5lZWRlZCBieSB0aGUgYXBwbGV0LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBOYW1lIEVYVEVOU0lPTl9MSVNUID0gbmV3IE5hbWUoIkV4dGVuc2lvbi1MaXN0Iik7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB7QGNvZGUgRXh0ZW5zaW9uLU5hbWV9IGF0dHJpYnV0ZSB3aGljaCBkZWZpbmVzIHRoZSB1bmlxdWUgbmFtZSBvZgorICAgICAgICAgKiB0aGUgZXh0ZW5zaW9uLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBOYW1lIEVYVEVOU0lPTl9OQU1FID0gbmV3IE5hbWUoIkV4dGVuc2lvbi1OYW1lIik7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB7QGNvZGUgRXh0ZW5zaW9uLUluc3RhbGxhdGlvbn0gYXR0cmlidXRlLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBOYW1lIEVYVEVOU0lPTl9JTlNUQUxMQVRJT04gPSBuZXcgTmFtZSgiRXh0ZW5zaW9uLUluc3RhbGxhdGlvbiIpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUge0Bjb2RlIEltcGxlbWVudGF0aW9uLVZlbmRvci1JZH0gYXR0cmlidXRlIHNwZWNpZmllcyB0aGUgdmVuZG9yCisgICAgICAgICAqIG9mIGFuIGV4dGVuc2lvbiBpbXBsZW1lbnRhdGlvbiBpZiB0aGUgYXBwbGV0IHJlcXVpcmVzIGFuCisgICAgICAgICAqIGltcGxlbWVudGF0aW9uIGZyb20gYSBzcGVjaWZpYyB2ZW5kb3IuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE5hbWUgSU1QTEVNRU5UQVRJT05fVkVORE9SX0lEID0gbmV3IE5hbWUoIkltcGxlbWVudGF0aW9uLVZlbmRvci1JZCIpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUge0Bjb2RlIEltcGxlbWVudGF0aW9uLVVSTH0gYXR0cmlidXRlIHNwZWNpZnlpbmcgYSBVUkwgdGhhdCBjYW4gYmUKKyAgICAgICAgICogdXNlZCB0byBvYnRhaW4gdGhlIG1vc3QgcmVjZW50IHZlcnNpb24gb2YgdGhlIGV4dGVuc2lvbiBpZiB0aGUKKyAgICAgICAgICogcmVxdWlyZWQgdmVyc2lvbiBpcyBub3QgYWxyZWFkeSBpbnN0YWxsZWQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE5hbWUgSU1QTEVNRU5UQVRJT05fVVJMID0gbmV3IE5hbWUoIkltcGxlbWVudGF0aW9uLVVSTCIpOworCisgICAgICAgIHN0YXRpYyBmaW5hbCBOYW1lIE5BTUUgPSBuZXcgTmFtZSgiTmFtZSIpOworCisgICAgICAgIHB1YmxpYyBOYW1lKFN0cmluZyBuYW1lKSB7CisgICAgICAgICAgICAvLyBlbmNvZGVkIG5hbWUgKyAiXHJcbiIgbXVzdCBiZSA8PSA3MiBieXRlczsgQVNDSUktb25seSBzbyBieXRlIGNvdW50IGVxdWFscyBjaGFyIGNvdW50CisgICAgICAgICAgICBpZiAobmFtZS5pc0VtcHR5KCkgfHwgbmFtZS5sZW5ndGgoKSA+IE1hbmlmZXN0LkxJTkVfTEVOR1RIX0xJTUlUIC0gMikgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24obmFtZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmFtZS5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgY2hhciBjaCA9IG5hbWUuY2hhckF0KGkpOworICAgICAgICAgICAgICAgIGlmICghKChjaCA+PSAnYScgJiYgY2ggPD0gJ3onKSB8fCAoY2ggPj0gJ0EnICYmIGNoIDw9ICdaJykKKyAgICAgICAgICAgICAgICAgICAgICAgIHx8IGNoID09ICdfJyB8fCBjaCA9PSAnLScgfHwgKGNoID49ICcwJyAmJiBjaCA8PSAnOScpKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKG5hbWUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBOYW1lCisgICAgICAgICAgICAgICAgICAgICYmICgoTmFtZSkgb2JqZWN0KS5uYW1lLmVxdWFsc0lnbm9yZUNhc2UobmFtZSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBuYW1lLnRvTG93ZXJDYXNlKExvY2FsZS5VUykuaGFzaENvZGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIHtAY29kZSBBdHRyaWJ1dGVzfSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXR0cmlidXRlcygpIHsKKyAgICAgICAgbWFwID0gbmV3IEhhc2hNYXA8T2JqZWN0LCBPYmplY3Q+KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiB7QGNvZGUgQXR0cmlidXRlc30gaW5zdGFuY2Ugb2J0YWluaW5nIGtleXMgYW5kIHZhbHVlcyBmcm9tCisgICAgICogdGhlIHBhcmFtZXRlciB7QGNvZGUgYXR0cmlifS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhdHRyaWIKKyAgICAgKiAgICAgICAgICAgIFRoZSBhdHRyaWJ1dGVzIHRvIG9idGFpbiBlbnRyaWVzIGZyb20uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIEF0dHJpYnV0ZXMoQXR0cmlidXRlcyBhdHRyaWIpIHsKKyAgICAgICAgbWFwID0gKE1hcDxPYmplY3QsIE9iamVjdD4pICgoSGFzaE1hcCkgYXR0cmliLm1hcCkuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIHtAY29kZSBBdHRyaWJ1dGVzfSBpbnN0YW5jZSB3aXRoIGluaXRpYWwgY2FwYWNpdHkgb2Ygc2l6ZQorICAgICAqIHtAY29kZSBzaXplfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICBJbml0aWFsIHNpemUgb2YgdGhpcyB7QGNvZGUgQXR0cmlidXRlc30gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIEF0dHJpYnV0ZXMoaW50IHNpemUpIHsKKyAgICAgICAgbWFwID0gbmV3IEhhc2hNYXA8T2JqZWN0LCBPYmplY3Q+KHNpemUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYWxsIGtleS92YWx1ZSBwYWlycyBmcm9tIHRoaXMge0Bjb2RlIEF0dHJpYnV0ZXN9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBtYXAuY2xlYXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhpcyB7QGNvZGUgQXR0cmlidXRlc30gY29udGFpbnMgdGhlIHNwZWNpZmllZCBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICBUaGUga2V5IHRvIHNlYXJjaCBmb3IuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGtleSBpcyBmb3VuZCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNLZXkoT2JqZWN0IGtleSkgeworICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoaXMge0Bjb2RlIEF0dHJpYnV0ZXN9IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSB2YWx1ZSBpcyBmb3VuZCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNWYWx1ZShPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc1ZhbHVlKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc2V0IGNvbnRhaW5pbmcgbWFwIGVudHJpZXMgZm9yIGVhY2ggb2YgdGhlIGtleS92YWx1ZSBwYWlyCisgICAgICogY29udGFpbmVkIGluIHRoaXMge0Bjb2RlIEF0dHJpYnV0ZXN9LgorICAgICAqCisgICAgICogQHJldHVybiBhIHNldCBvZiBNYXAuRW50cnkncworICAgICAqLworICAgIHB1YmxpYyBTZXQ8TWFwLkVudHJ5PE9iamVjdCwgT2JqZWN0Pj4gZW50cnlTZXQoKSB7CisgICAgICAgIHJldHVybiBtYXAuZW50cnlTZXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHBhcmFtZXRlciBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IHRvIHNlYXJjaCBmb3IuCisgICAgICogQHJldHVybiBPYmplY3QgYXNzb2NpYXRlZCB3aXRoIGtleSwgb3Ige0Bjb2RlIG51bGx9IGlmIGtleSBkb2VzIG5vdAorICAgICAqICAgICAgICAgZXhpc3QuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXQoT2JqZWN0IGtleSkgeworICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGlzIHtAY29kZSBBdHRyaWJ1dGVzfSBjb250YWlucyBhbnkga2V5cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIG9uZSBvciBtb3JlIGtleXMgZXhpc3QsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgIHJldHVybiBtYXAuaXNFbXB0eSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgU2V0fSBjb250YWluaW5nIGFsbCB0aGUga2V5cyBmb3VuZCBpbiB0aGlzIHtAY29kZQorICAgICAqIEF0dHJpYnV0ZXN9LgorICAgICAqCisgICAgICogQHJldHVybiBhIHtAY29kZSBTZXR9IG9mIGFsbCBrZXlzLgorICAgICAqLworICAgIHB1YmxpYyBTZXQ8T2JqZWN0PiBrZXlTZXQoKSB7CisgICAgICAgIHJldHVybiBtYXAua2V5U2V0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3RvcmVzIGtleS92YWx1ZSBwYWlycyBpbiB0aGlzIHtAY29kZSBBdHRyaWJ1dGVzfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgdG8gYXNzb2NpYXRlIHdpdGggdmFsdWUuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gc3RvcmUgaW4gdGhpcyB7QGNvZGUgQXR0cmlidXRlc30uCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgYmVpbmcgc3RvcmVkLgorICAgICAqIEBleGNlcHRpb24gQ2xhc3NDYXN0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgd2hlbiBrZXkgaXMgbm90IGFuIHtAY29kZSBBdHRyaWJ1dGVzLk5hbWV9IG9yIHZhbHVlIGlzIG5vdAorICAgICAqICAgICAgICAgICAgICAgIGEge0Bjb2RlIFN0cmluZ30uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImNhc3QiKQorICAgIC8vIFJlcXVpcmUgY2FzdCB0byBmb3JjZSBDbGFzc0Nhc3RFeGNlcHRpb24KKyAgICBwdWJsaWMgT2JqZWN0IHB1dChPYmplY3Qga2V5LCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIG1hcC5wdXQoKE5hbWUpIGtleSwgKFN0cmluZykgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0b3JlcyBhbGwgdGhlIGtleS92YWx1ZSBwYWlycyBpbiB0aGUgYXJndW1lbnQgaW4gdGhpcyB7QGNvZGUKKyAgICAgKiBBdHRyaWJ1dGVzfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhdHRyaWIKKyAgICAgKiAgICAgICAgICAgIHRoZSBhc3NvY2lhdGlvbnMgdG8gc3RvcmUgKG11c3QgYmUgb2YgdHlwZSB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIEF0dHJpYnV0ZXN9KS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXRBbGwoTWFwPD8sID8+IGF0dHJpYikgeworICAgICAgICBpZiAoYXR0cmliID09IG51bGwgfHwgIShhdHRyaWIgaW5zdGFuY2VvZiBBdHRyaWJ1dGVzKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzQ2FzdEV4Y2VwdGlvbihhdHRyaWIuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiIG5vdCBhbiBBdHRyaWJ1dGVzIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5tYXAucHV0QWxsKGF0dHJpYik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVsZXRlcyB0aGUga2V5L3ZhbHVlIHBhaXIgd2l0aCBrZXkge0Bjb2RlIGtleX0gZnJvbSB0aGlzIHtAY29kZQorICAgICAqIEF0dHJpYnV0ZXN9LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byByZW1vdmUuCisgICAgICogQHJldHVybiB0aGUgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVtb3ZlZCBrZXksIHtAY29kZSBudWxsfSBpZiBub3QKKyAgICAgKiAgICAgICAgIHByZXNlbnQuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCByZW1vdmUoT2JqZWN0IGtleSkgeworICAgICAgICByZXR1cm4gbWFwLnJlbW92ZShrZXkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBrZXkvdmFsdWUgcGFpcnMgYXNzb2NpYXRlZCB3aXRoIHRoaXMge0Bjb2RlCisgICAgICogQXR0cmlidXRlc30uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzaXplIG9mIHRoaXMge0Bjb2RlIEF0dHJpYnV0ZXN9LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIG1hcC5zaXplKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvbGxlY3Rpb24gb2YgYWxsIHRoZSB2YWx1ZXMgcHJlc2VudCBpbiB0aGlzIHtAY29kZQorICAgICAqIEF0dHJpYnV0ZXN9LgorICAgICAqCisgICAgICogQHJldHVybiBhIGNvbGxlY3Rpb24gb2YgYWxsIHZhbHVlcyBwcmVzZW50LgorICAgICAqLworICAgIHB1YmxpYyBDb2xsZWN0aW9uPE9iamVjdD4gdmFsdWVzKCkgeworICAgICAgICByZXR1cm4gbWFwLnZhbHVlcygpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIEF0dHJpYnV0ZXMgY2xvbmU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjbG9uZSA9IChBdHRyaWJ1dGVzKSBzdXBlci5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICAgICAgY2xvbmUubWFwID0gKE1hcDxPYmplY3QsIE9iamVjdD4pICgoSGFzaE1hcCkgbWFwKS5jbG9uZSgpOworICAgICAgICByZXR1cm4gY2xvbmU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaGFzaCBjb2RlIG9mIHRoaXMge0Bjb2RlIEF0dHJpYnV0ZXN9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIG9mIHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiBtYXAuaGFzaENvZGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIGlmIHRoaXMge0Bjb2RlIEF0dHJpYnV0ZXN9IGFuZCB0aGUgcGFyYW1ldGVyIHtAY29kZQorICAgICAqIEF0dHJpYnV0ZXN9IGFyZSBlcXVhbC4gVHdvIHtAY29kZSBBdHRyaWJ1dGVzfSBpbnN0YW5jZXMgYXJlIGVxdWFsIGlmIHRoZXkKKyAgICAgKiBjb250YWluIHRoZSBzYW1lIGtleXMgYW5kIHZhbHVlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3Qgd2l0aCB3aGljaCB0aGlzIHtAY29kZSBBdHRyaWJ1dGVzfSBpcyBjb21wYXJlZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUge0Bjb2RlIEF0dHJpYnV0ZXN9IGFyZSBlcXVhbCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgIGlmICh0aGlzID09IG9iaikgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIEF0dHJpYnV0ZXMpIHsKKyAgICAgICAgICAgIHJldHVybiBtYXAuZXF1YWxzKCgoQXR0cmlidXRlcykgb2JqKS5tYXApOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHBhcmFtZXRlciB7QGNvZGUgQXR0cmlidXRlcy5OYW1lfQorICAgICAqIGtleS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUga2V5IHRvIG9idGFpbiB0aGUgdmFsdWUgZm9yLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBTdHJpbmd9IGFzc29jaWF0ZWQgd2l0aCBuYW1lLCBvciB7QGNvZGUgbnVsbH0gaWYgbmFtZQorICAgICAqICAgICAgICAgaXMgbm90IGEgdmFsaWQga2V5LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoQXR0cmlidXRlcy5OYW1lIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIChTdHJpbmcpIG1hcC5nZXQobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyaW5nIGFzc29jaWF0ZWQgd2l0aCB0aGUgcGFyYW1ldGVyIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byBvYnRhaW4gdGhlIHZhbHVlIGZvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgYXNzb2NpYXRlZCB3aXRoIG5hbWUsIG9yIHtAY29kZSBudWxsfSBpZiBuYW1lIGlzIG5vdCBhCisgICAgICogICAgICAgICB2YWxpZCBrZXkuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZShTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gKFN0cmluZykgbWFwLmdldChuZXcgQXR0cmlidXRlcy5OYW1lKG5hbWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdG9yZXMgdGhlIHZhbHVlIHtAY29kZSB2YWx9IGFzc29jaWF0ZWQgd2l0aCB0aGUga2V5IHtAY29kZSBuYW1lfSBpbiB0aGlzCisgICAgICoge0Bjb2RlIEF0dHJpYnV0ZXN9LgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgdG8gc3RvcmUuCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIHN0b3JlIGluIHRoaXMge0Bjb2RlIEF0dHJpYnV0ZXN9LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIGJlaW5nIHN0b3JlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHB1dFZhbHVlKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsKSB7CisgICAgICAgIHJldHVybiAoU3RyaW5nKSBtYXAucHV0KG5ldyBBdHRyaWJ1dGVzLk5hbWUobmFtZSksIHZhbCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9qYXIvSW5pdE1hbmlmZXN0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2phci9Jbml0TWFuaWZlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jODJhMWU0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9qYXIvSW5pdE1hbmlmZXN0LmphdmEKQEAgLTAsMCArMSwxNzYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5qYXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldHM7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBSZWFkcyBhIEpBUiBmaWxlIG1hbmlmZXN0LiBUaGUgc3BlY2lmaWNhdGlvbiBpcyBoZXJlOgorICogaHR0cDovL2phdmEuc3VuLmNvbS9qYXZhc2UvNi9kb2NzL3RlY2hub3Rlcy9ndWlkZXMvamFyL2phci5odG1sCisgKi8KK2NsYXNzIEluaXRNYW5pZmVzdCB7CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gYnVmOworCisgICAgcHJpdmF0ZSBpbnQgcG9zOworCisgICAgcHJpdmF0ZSBBdHRyaWJ1dGVzLk5hbWUgbmFtZTsKKworICAgIHByaXZhdGUgU3RyaW5nIHZhbHVlOworCisgICAgcHJpdmF0ZSBmaW5hbCBVbnNhZmVCeXRlU2VxdWVuY2UgdmFsdWVCdWZmZXIgPSBuZXcgVW5zYWZlQnl0ZVNlcXVlbmNlKDgwKTsKKyAgICBwcml2YXRlIGludCBjb25zZWN1dGl2ZUxpbmVCcmVha3MgPSAwOworCisgICAgSW5pdE1hbmlmZXN0KGJ5dGVbXSBidWYsIEF0dHJpYnV0ZXMgbWFpbiwgQXR0cmlidXRlcy5OYW1lIHZlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5idWYgPSBidWY7CisKKyAgICAgICAgLy8gY2hlY2sgYSB2ZXJzaW9uIGF0dHJpYnV0ZQorICAgICAgICBpZiAoIXJlYWRIZWFkZXIoKSB8fCAodmVyICE9IG51bGwgJiYgIW5hbWUuZXF1YWxzKHZlcikpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIk1pc3NpbmcgdmVyc2lvbiBhdHRyaWJ1dGU6ICIgKyB2ZXIpOworICAgICAgICB9CisKKyAgICAgICAgbWFpbi5wdXQobmFtZSwgdmFsdWUpOworICAgICAgICB3aGlsZSAocmVhZEhlYWRlcigpKSB7CisgICAgICAgICAgICBtYWluLnB1dChuYW1lLCB2YWx1ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICB2b2lkIGluaXRFbnRyaWVzKE1hcDxTdHJpbmcsIEF0dHJpYnV0ZXM+IGVudHJpZXMsCisgICAgICAgICAgICBNYXA8U3RyaW5nLCBNYW5pZmVzdC5DaHVuaz4gY2h1bmtzKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIGludCBtYXJrID0gcG9zOworICAgICAgICB3aGlsZSAocmVhZEhlYWRlcigpKSB7CisgICAgICAgICAgICBpZiAoIUF0dHJpYnV0ZXMuTmFtZS5OQU1FLmVxdWFscyhuYW1lKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRW50cnkgaXMgbm90IG5hbWVkIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTdHJpbmcgZW50cnlOYW1lVmFsdWUgPSB2YWx1ZTsKKworICAgICAgICAgICAgQXR0cmlidXRlcyBlbnRyeSA9IGVudHJpZXMuZ2V0KGVudHJ5TmFtZVZhbHVlKTsKKyAgICAgICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgZW50cnkgPSBuZXcgQXR0cmlidXRlcygxMik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHdoaWxlIChyZWFkSGVhZGVyKCkpIHsKKyAgICAgICAgICAgICAgICBlbnRyeS5wdXQobmFtZSwgdmFsdWUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoY2h1bmtzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZiAoY2h1bmtzLmdldChlbnRyeU5hbWVWYWx1ZSkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAvLyBUT0RPIEEgYnVnOiB0aGVyZSBtaWdodCBiZSBzZXZlcmFsIHZlcmlmaWNhdGlvbiBjaHVua3MgZm9yCisgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBzYW1lIG5hbWUuIEkgYmVsaWV2ZSB0aGV5IHNob3VsZCBiZSB1c2VkIHRvIHVwZGF0ZQorICAgICAgICAgICAgICAgICAgICAvLyBzaWduYXR1cmUgaW4gb3JkZXIgb2YgYXBwZWFyYW5jZTsgdGhlcmUgYXJlIHR3byB3YXlzIHRvIGZpeAorICAgICAgICAgICAgICAgICAgICAvLyB0aGlzOiBlaXRoZXIgdXNlIGEgbGlzdCBvZiBjaHVua3MsIG9yIGRlY2lkZSBvbiB1c2VkCisgICAgICAgICAgICAgICAgICAgIC8vIHNpZ25hdHVyZSBhbGdvcml0aG0gaW4gYWR2YW5jZSBhbmQgcmVyZWFkIHRoZSBjaHVua3Mgd2hpbGUKKyAgICAgICAgICAgICAgICAgICAgLy8gdXBkYXRpbmcgdGhlIHNpZ25hdHVyZTsgZm9yIG5vdyBhIGRlZmVuc2l2ZSBlcnJvciBpcyB0aHJvd24KKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJBIGphciB2ZXJpZmllciBkb2VzIG5vdCBzdXBwb3J0IG1vcmUgdGhhbiBvbmUgZW50cnkgd2l0aCB0aGUgc2FtZSBuYW1lIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNodW5rcy5wdXQoZW50cnlOYW1lVmFsdWUsIG5ldyBNYW5pZmVzdC5DaHVuayhtYXJrLCBwb3MpKTsKKyAgICAgICAgICAgICAgICBtYXJrID0gcG9zOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBlbnRyaWVzLnB1dChlbnRyeU5hbWVWYWx1ZSwgZW50cnkpOworICAgICAgICB9CisgICAgfQorCisgICAgaW50IGdldFBvcygpIHsKKyAgICAgICAgcmV0dXJuIHBvczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGEgc2luZ2xlIGxpbmUgZnJvbSB0aGUgbWFuaWZlc3QgYnVmZmVyLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiByZWFkSGVhZGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNvbnNlY3V0aXZlTGluZUJyZWFrcyA+IDEpIHsKKyAgICAgICAgICAgIC8vIGJyZWFrIGEgc2VjdGlvbiBvbiBhbiBlbXB0eSBsaW5lCisgICAgICAgICAgICBjb25zZWN1dGl2ZUxpbmVCcmVha3MgPSAwOworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJlYWROYW1lKCk7CisgICAgICAgIGNvbnNlY3V0aXZlTGluZUJyZWFrcyA9IDA7CisgICAgICAgIHJlYWRWYWx1ZSgpOworICAgICAgICAvLyBpZiB0aGUgbGFzdCBsaW5lIGJyZWFrIGlzIG1pc3NlZCwgdGhlIGxpbmUKKyAgICAgICAgLy8gaXMgaWdub3JlZCBieSB0aGUgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uCisgICAgICAgIHJldHVybiBjb25zZWN1dGl2ZUxpbmVCcmVha3MgPiAwOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkTmFtZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBtYXJrID0gcG9zOworCisgICAgICAgIHdoaWxlIChwb3MgPCBidWYubGVuZ3RoKSB7CisgICAgICAgICAgICBpZiAoYnVmW3BvcysrXSAhPSAnOicpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBuZXcgU3RyaW5nKGJ1ZiwgbWFyaywgcG9zIC0gbWFyayAtIDEsIENoYXJzZXRzLlVTX0FTQ0lJKTsKKworICAgICAgICAgICAgaWYgKGJ1Zltwb3MrK10gIT0gJyAnKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKFN0cmluZy5mb3JtYXQoIkludmFsaWQgdmFsdWUgZm9yIGF0dHJpYnV0ZSAnJXMnIiwgbmFtZSkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRoaXMubmFtZSA9IG5ldyBBdHRyaWJ1dGVzLk5hbWUobmFtZSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIG5ldyBBdHRyaWJ1dGVzLk5hbWUoKSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGJ1dCB3ZSBkZWNsYXJlIElPRXhjZXB0aW9uCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkVmFsdWUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBib29sZWFuIGxhc3RDciA9IGZhbHNlOworICAgICAgICBpbnQgbWFyayA9IHBvczsKKyAgICAgICAgaW50IGxhc3QgPSBwb3M7CisgICAgICAgIHZhbHVlQnVmZmVyLnJld2luZCgpOworICAgICAgICB3aGlsZSAocG9zIDwgYnVmLmxlbmd0aCkgeworICAgICAgICAgICAgYnl0ZSBuZXh0ID0gYnVmW3BvcysrXTsKKyAgICAgICAgICAgIHN3aXRjaCAobmV4dCkgeworICAgICAgICAgICAgY2FzZSAwOgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiTlVMIGNoYXJhY3RlciBpbiBhIG1hbmlmZXN0Iik7CisgICAgICAgICAgICBjYXNlICdcbic6CisgICAgICAgICAgICAgICAgaWYgKGxhc3RDcikgeworICAgICAgICAgICAgICAgICAgICBsYXN0Q3IgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBjb25zZWN1dGl2ZUxpbmVCcmVha3MrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICBjYXNlICdccic6CisgICAgICAgICAgICAgICAgbGFzdENyID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBjb25zZWN1dGl2ZUxpbmVCcmVha3MrKzsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIGNhc2UgJyAnOgorICAgICAgICAgICAgICAgIGlmIChjb25zZWN1dGl2ZUxpbmVCcmVha3MgPT0gMSkgeworICAgICAgICAgICAgICAgICAgICB2YWx1ZUJ1ZmZlci53cml0ZShidWYsIG1hcmssIGxhc3QgLSBtYXJrKTsKKyAgICAgICAgICAgICAgICAgICAgbWFyayA9IHBvczsKKyAgICAgICAgICAgICAgICAgICAgY29uc2VjdXRpdmVMaW5lQnJlYWtzID0gMDsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoY29uc2VjdXRpdmVMaW5lQnJlYWtzID49IDEpIHsKKyAgICAgICAgICAgICAgICBwb3MtLTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGxhc3QgPSBwb3M7CisgICAgICAgIH0KKworICAgICAgICB2YWx1ZUJ1ZmZlci53cml0ZShidWYsIG1hcmssIGxhc3QgLSBtYXJrKTsKKyAgICAgICAgdmFsdWUgPSB2YWx1ZUJ1ZmZlci50b1N0cmluZyhDaGFyc2V0cy5VVEZfOCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9qYXIvSmFyRW50cnkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvamFyL0phckVudHJ5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzgxZGQ1MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvamFyL0phckVudHJ5LmphdmEKQEAgLTAsMCArMSwyMTggQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5qYXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuQ29kZVNpZ25lcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGg7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEVudHJ5OworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsOworCisvKioKKyAqIFJlcHJlc2VudHMgYSBzaW5nbGUgZmlsZSBpbiBhIEpBUiBhcmNoaXZlIHRvZ2V0aGVyIHdpdGggdGhlIG1hbmlmZXN0CisgKiBhdHRyaWJ1dGVzIGFuZCBkaWdpdGFsIHNpZ25hdHVyZXMgYXNzb2NpYXRlZCB3aXRoIGl0LgorICoKKyAqIEBzZWUgSmFyRmlsZQorICogQHNlZSBKYXJJbnB1dFN0cmVhbQorICovCitwdWJsaWMgY2xhc3MgSmFyRW50cnkgZXh0ZW5kcyBaaXBFbnRyeSB7CisgICAgcHJpdmF0ZSBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXM7CisKKyAgICBKYXJGaWxlIHBhcmVudEphcjsKKworICAgIENvZGVTaWduZXIgc2lnbmVyc1tdOworCisgICAgLy8gQ2FjaGVkIGZhY3RvcnkgdXNlZCB0byBidWlsZCBDZXJ0UGF0aC1zIGluIDxjb2RlPmdldENvZGVTaWduZXJzKCk8L2NvZGU+LgorICAgIHByaXZhdGUgQ2VydGlmaWNhdGVGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNGYWN0b3J5Q2hlY2tlZCA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgSmFyRW50cnl9IG5hbWVkIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgVGhlIG5hbWUgb2YgdGhlIG5ldyB7QGNvZGUgSmFyRW50cnl9LgorICAgICAqLworICAgIHB1YmxpYyBKYXJFbnRyeShTdHJpbmcgbmFtZSkgeworICAgICAgICBzdXBlcihuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBKYXJFbnRyeX0gdXNpbmcgdGhlIHZhbHVlcyBvYnRhaW5lZCBmcm9tIGVudHJ5LgorICAgICAqCisgICAgICogQHBhcmFtIGVudHJ5CisgICAgICogICAgICAgICAgICBUaGUgWmlwRW50cnkgdG8gb2J0YWluIHZhbHVlcyBmcm9tLgorICAgICAqLworICAgIHB1YmxpYyBKYXJFbnRyeShaaXBFbnRyeSBlbnRyeSkgeworICAgICAgICBzdXBlcihlbnRyeSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIEF0dHJpYnV0ZXN9IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBlbnRyeSBvcgorICAgICAqIHtAY29kZSBudWxsfSBpZiBub25lIGV4aXN0cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBBdHRyaWJ1dGVzfSBmb3IgdGhpcyBlbnRyeS4KKyAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgSWYgYW4gZXJyb3Igb2NjdXJzIG9idGFpbmluZyB0aGUge0Bjb2RlIEF0dHJpYnV0ZXN9LgorICAgICAqIEBzZWUgQXR0cmlidXRlcworICAgICAqLworICAgIHB1YmxpYyBBdHRyaWJ1dGVzIGdldEF0dHJpYnV0ZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoYXR0cmlidXRlcyAhPSBudWxsIHx8IHBhcmVudEphciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gYXR0cmlidXRlczsKKyAgICAgICAgfQorICAgICAgICBNYW5pZmVzdCBtYW5pZmVzdCA9IHBhcmVudEphci5nZXRNYW5pZmVzdCgpOworICAgICAgICBpZiAobWFuaWZlc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXMgPSBtYW5pZmVzdC5nZXRBdHRyaWJ1dGVzKGdldE5hbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBvZiB7QGNvZGUgQ2VydGlmaWNhdGV9IE9iamVjdHMgYXNzb2NpYXRlZCB3aXRoIHRoaXMKKyAgICAgKiBlbnRyeSBvciB7QGNvZGUgbnVsbH0gaWYgbm9uZSBleGlzdHMuIE1ha2Ugc3VyZSB0aGF0IHRoZSBldmVyeXRoaW5nIGlzCisgICAgICogcmVhZCBmcm9tIHRoZSBpbnB1dCBzdHJlYW0gYmVmb3JlIGNhbGxpbmcgdGhpcyBtZXRob2QsIG9yIGVsc2UgdGhlIG1ldGhvZAorICAgICAqIHJldHVybnMge0Bjb2RlIG51bGx9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2VydGlmaWNhdGUgZm9yIHRoaXMgZW50cnkuCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVbXSBnZXRDZXJ0aWZpY2F0ZXMoKSB7CisgICAgICAgIGlmIChwYXJlbnRKYXIgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgSmFyVmVyaWZpZXIgamFyVmVyaWZpZXIgPSBwYXJlbnRKYXIudmVyaWZpZXI7CisgICAgICAgIGlmIChqYXJWZXJpZmllciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gamFyVmVyaWZpZXIuZ2V0Q2VydGlmaWNhdGVzKGdldE5hbWUoKSk7CisgICAgfQorCisgICAgdm9pZCBzZXRBdHRyaWJ1dGVzKEF0dHJpYnV0ZXMgYXR0cmliKSB7CisgICAgICAgIGF0dHJpYnV0ZXMgPSBhdHRyaWI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBKYXJFbnRyeX0gdXNpbmcgdGhlIHZhbHVlcyBvYnRhaW5lZCBmcm9tIHRoZQorICAgICAqIGFyZ3VtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGplCisgICAgICogICAgICAgICAgICBUaGUge0Bjb2RlIEphckVudHJ5fSB0byBvYnRhaW4gdmFsdWVzIGZyb20uCisgICAgICovCisgICAgcHVibGljIEphckVudHJ5KEphckVudHJ5IGplKSB7CisgICAgICAgIHN1cGVyKGplKTsKKyAgICAgICAgcGFyZW50SmFyID0gamUucGFyZW50SmFyOworICAgICAgICBhdHRyaWJ1dGVzID0gamUuYXR0cmlidXRlczsKKyAgICAgICAgc2lnbmVycyA9IGplLnNpZ25lcnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29kZSBzaWduZXJzIGZvciB0aGUgZGlnaXRhbCBzaWduYXR1cmVzIGFzc29jaWF0ZWQgd2l0aCB0aGUKKyAgICAgKiBKQVIgZmlsZS4gSWYgdGhlcmUgaXMgbm8gc3VjaCBjb2RlIHNpZ25lciwgaXQgcmV0dXJucyB7QGNvZGUgbnVsbH0uIE1ha2UKKyAgICAgKiBzdXJlIHRoYXQgdGhlIGV2ZXJ5dGhpbmcgaXMgcmVhZCBmcm9tIHRoZSBpbnB1dCBzdHJlYW0gYmVmb3JlIGNhbGxpbmcKKyAgICAgKiB0aGlzIG1ldGhvZCwgb3IgZWxzZSB0aGUgbWV0aG9kIHJldHVybnMge0Bjb2RlIG51bGx9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29kZSBzaWduZXJzIGZvciB0aGUgSkFSIGVudHJ5LgorICAgICAqIEBzZWUgQ29kZVNpZ25lcgorICAgICAqLworICAgIHB1YmxpYyBDb2RlU2lnbmVyW10gZ2V0Q29kZVNpZ25lcnMoKSB7CisgICAgICAgIGlmIChzaWduZXJzID09IG51bGwpIHsKKyAgICAgICAgICAgIHNpZ25lcnMgPSBnZXRDb2RlU2lnbmVycyhnZXRDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNpZ25lcnMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBDb2RlU2lnbmVyW10gdG1wID0gbmV3IENvZGVTaWduZXJbc2lnbmVycy5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHNpZ25lcnMsIDAsIHRtcCwgMCwgdG1wLmxlbmd0aCk7CisgICAgICAgIHJldHVybiB0bXA7CisgICAgfQorCisgICAgcHJpdmF0ZSBDb2RlU2lnbmVyW10gZ2V0Q29kZVNpZ25lcnMoQ2VydGlmaWNhdGVbXSBjZXJ0cykgeworICAgICAgICBpZiAoY2VydHMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBYNTAwUHJpbmNpcGFsIHByZXZJc3N1ZXIgPSBudWxsOworICAgICAgICBBcnJheUxpc3Q8Q2VydGlmaWNhdGU+IGxpc3QgPSBuZXcgQXJyYXlMaXN0PENlcnRpZmljYXRlPihjZXJ0cy5sZW5ndGgpOworICAgICAgICBBcnJheUxpc3Q8Q29kZVNpZ25lcj4gYXNpZ25lcnMgPSBuZXcgQXJyYXlMaXN0PENvZGVTaWduZXI+KCk7CisKKyAgICAgICAgZm9yIChDZXJ0aWZpY2F0ZSBlbGVtZW50IDogY2VydHMpIHsKKyAgICAgICAgICAgIGlmICghKGVsZW1lbnQgaW5zdGFuY2VvZiBYNTA5Q2VydGlmaWNhdGUpKSB7CisgICAgICAgICAgICAgICAgLy8gT25seSBYNTA5Q2VydGlmaWNhdGUtcyBhcmUgdGFrZW4gaW50byBhY2NvdW50IC0gc2VlIEFQSSBzcGVjLgorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlIHg1MDkgPSAoWDUwOUNlcnRpZmljYXRlKSBlbGVtZW50OworICAgICAgICAgICAgaWYgKHByZXZJc3N1ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIFg1MDBQcmluY2lwYWwgc3ViaiA9IHg1MDkuZ2V0U3ViamVjdFg1MDBQcmluY2lwYWwoKTsKKyAgICAgICAgICAgICAgICBpZiAoIXByZXZJc3N1ZXIuZXF1YWxzKHN1YmopKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIE9rLCB0aGlzIGVuZHMgdGhlIHByZXZpb3VzIGNoYWluLAorICAgICAgICAgICAgICAgICAgICAvLyBzbyB0cmFuc2Zvcm0gdGhpcyBvbmUgaW50byBDZXJ0UGF0aCAuLi4KKyAgICAgICAgICAgICAgICAgICAgYWRkQ29kZVNpZ25lcihhc2lnbmVycywgbGlzdCk7CisgICAgICAgICAgICAgICAgICAgIC8vIC4uLiBhbmQgc3RhcnQgYSBuZXcgb25lCisgICAgICAgICAgICAgICAgICAgIGxpc3QuY2xlYXIoKTsKKyAgICAgICAgICAgICAgICB9Ly8gZWxzZSB7IGl0J3Mgc3RpbGwgdGhlIHNhbWUgY2hhaW4gfQorCisgICAgICAgICAgICB9CisgICAgICAgICAgICBwcmV2SXNzdWVyID0geDUwOS5nZXRJc3N1ZXJYNTAwUHJpbmNpcGFsKCk7CisgICAgICAgICAgICBsaXN0LmFkZCh4NTA5KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIWxpc3QuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBhZGRDb2RlU2lnbmVyKGFzaWduZXJzLCBsaXN0KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYXNpZ25lcnMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAvLyAnc2lnbmVycycgaXMgJ251bGwnIGFscmVhZHkKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQ29kZVNpZ25lcltdIHRtcCA9IG5ldyBDb2RlU2lnbmVyW2FzaWduZXJzLnNpemUoKV07CisgICAgICAgIGFzaWduZXJzLnRvQXJyYXkodG1wKTsKKyAgICAgICAgcmV0dXJuIHRtcDsKKworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhZGRDb2RlU2lnbmVyKEFycmF5TGlzdDxDb2RlU2lnbmVyPiBhc2lnbmVycywKKyAgICAgICAgICAgIExpc3Q8Q2VydGlmaWNhdGU+IGxpc3QpIHsKKyAgICAgICAgQ2VydFBhdGggY2VydFBhdGggPSBudWxsOworICAgICAgICBpZiAoIWlzRmFjdG9yeUNoZWNrZWQpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZmFjdG9yeSA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgLy8gZG8gbm90aGluZworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBpc0ZhY3RvcnlDaGVja2VkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoZmFjdG9yeSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRQYXRoID0gZmFjdG9yeS5nZW5lcmF0ZUNlcnRQYXRoKGxpc3QpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgLy8gZG8gbm90aGluZworICAgICAgICB9CisgICAgICAgIGlmIChjZXJ0UGF0aCAhPSBudWxsKSB7CisgICAgICAgICAgICBhc2lnbmVycy5hZGQobmV3IENvZGVTaWduZXIoY2VydFBhdGgsIG51bGwpKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvamFyL0phckV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9qYXIvSmFyRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzg0ZmRkOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvamFyL0phckV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5qYXI7CisKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEV4Y2VwdGlvbjsKKworLyoqCisgKiBUaGlzIHJ1bnRpbWUgZXhjZXB0aW9uIGlzIHRocm93biB3aGVuIGEgcHJvYmxlbSBvY2N1cnMgd2hpbGUgcmVhZGluZyBhIEpBUgorICogZmlsZS4KKyAqLworcHVibGljIGNsYXNzIEphckV4Y2VwdGlvbiBleHRlbmRzIFppcEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3MTU5Nzc4NDAwOTYzOTU0NDczTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEphckV4Y2VwdGlvbn0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIEphckV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBKYXJFeGNlcHRpb259IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGV0YWlsTWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGUgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBKYXJFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9qYXIvSmFyRmlsZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9qYXIvSmFyRmlsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUxMjllODIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2phci9KYXJGaWxlLmphdmEKQEAgLTAsMCArMSw0NTYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5qYXI7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWx0ZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFbnRyeTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEZpbGU7CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworCisvKioKKyAqIHtAY29kZSBKYXJGaWxlfSBpcyB1c2VkIHRvIHJlYWQgamFyIGVudHJpZXMgYW5kIHRoZWlyIGFzc29jaWF0ZWQgZGF0YSBmcm9tCisgKiBqYXIgZmlsZXMuCisgKgorICogQHNlZSBKYXJJbnB1dFN0cmVhbQorICogQHNlZSBKYXJFbnRyeQorICovCitwdWJsaWMgY2xhc3MgSmFyRmlsZSBleHRlbmRzIFppcEZpbGUgeworCisgICAgLyoqCisgICAgICogVGhlIE1BTklGRVNUIGZpbGUgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNQU5JRkVTVF9OQU1FID0gIk1FVEEtSU5GL01BTklGRVNULk1GIjsKKworICAgIC8vIFRoZSBkaXJlY3RvcnkgY29udGFpbmluZyB0aGUgbWFuaWZlc3QuCisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBNRVRBX0RJUiA9ICJNRVRBLUlORi8iOworCisgICAgLy8gVGhlIG1hbmlmZXN0IGFmdGVyIGl0IGhhcyBiZWVuIHJlYWQgZnJvbSB0aGUgSkFSLgorICAgIHByaXZhdGUgTWFuaWZlc3QgbWFuaWZlc3Q7CisKKyAgICAvLyBUaGUgZW50cnkgZm9yIHRoZSBNQU5JRkVTVC5NRiBmaWxlIGJlZm9yZSBpdCBpcyByZWFkLgorICAgIHByaXZhdGUgWmlwRW50cnkgbWFuaWZlc3RFbnRyeTsKKworICAgIEphclZlcmlmaWVyIHZlcmlmaWVyOworCisgICAgcHJpdmF0ZSBib29sZWFuIGNsb3NlZCA9IGZhbHNlOworCisgICAgc3RhdGljIGZpbmFsIGNsYXNzIEphckZpbGVJbnB1dFN0cmVhbSBleHRlbmRzIEZpbHRlcklucHV0U3RyZWFtIHsKKyAgICAgICAgcHJpdmF0ZSBsb25nIGNvdW50OworCisgICAgICAgIHByaXZhdGUgWmlwRW50cnkgemlwRW50cnk7CisKKyAgICAgICAgcHJpdmF0ZSBKYXJWZXJpZmllci5WZXJpZmllckVudHJ5IGVudHJ5OworCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBkb25lID0gZmFsc2U7CisKKyAgICAgICAgSmFyRmlsZUlucHV0U3RyZWFtKElucHV0U3RyZWFtIGlzLCBaaXBFbnRyeSB6ZSwKKyAgICAgICAgICAgICAgICBKYXJWZXJpZmllci5WZXJpZmllckVudHJ5IGUpIHsKKyAgICAgICAgICAgIHN1cGVyKGlzKTsKKyAgICAgICAgICAgIHppcEVudHJ5ID0gemU7CisgICAgICAgICAgICBjb3VudCA9IHppcEVudHJ5LmdldFNpemUoKTsKKyAgICAgICAgICAgIGVudHJ5ID0gZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaWYgKGRvbmUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY291bnQgPiAwKSB7CisgICAgICAgICAgICAgICAgaW50IHIgPSBzdXBlci5yZWFkKCk7CisgICAgICAgICAgICAgICAgaWYgKHIgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgZW50cnkud3JpdGUocik7CisgICAgICAgICAgICAgICAgICAgIGNvdW50LS07CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgY291bnQgPSAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoY291bnQgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgZW50cnkudmVyaWZ5KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiByOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBlbnRyeS52ZXJpZnkoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCByZWFkKGJ5dGVbXSBidWYsIGludCBvZmYsIGludCBuYnl0ZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoZG9uZSkgeworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjb3VudCA+IDApIHsKKyAgICAgICAgICAgICAgICBpbnQgciA9IHN1cGVyLnJlYWQoYnVmLCBvZmYsIG5ieXRlcyk7CisgICAgICAgICAgICAgICAgaWYgKHIgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHNpemUgPSByOworICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPCBzaXplKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gKGludCkgY291bnQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZW50cnkud3JpdGUoYnVmLCBvZmYsIHNpemUpOworICAgICAgICAgICAgICAgICAgICBjb3VudCAtPSBzaXplOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gMDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGNvdW50ID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIGVudHJ5LnZlcmlmeSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gcjsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CisgICAgICAgICAgICAgICAgZW50cnkudmVyaWZ5KCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChkb25lKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuYXZhaWxhYmxlKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGxvbmcgc2tpcChsb25nIGJ5dGVDb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBTdHJlYW1zLnNraXBCeVJlYWRpbmcodGhpcywgYnl0ZUNvdW50KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyB7QGNvZGUgSmFyRmlsZX0gdXNpbmcgdGhlIGNvbnRlbnRzIG9mIHRoZSBzcGVjaWZpZWQgZmlsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlCisgICAgICogICAgICAgICAgICB0aGUgSkFSIGZpbGUgYXMge0BsaW5rIEZpbGV9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiB0aGUgZmlsZSBjYW5ub3QgYmUgcmVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSmFyRmlsZShGaWxlIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoZmlsZSwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBKYXJGaWxlfSB1c2luZyB0aGUgY29udGVudHMgb2YgdGhlIHNwZWNpZmllZCBmaWxlLgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBKQVIgZmlsZSBhcyB7QGxpbmsgRmlsZX0uCisgICAgICogQHBhcmFtIHZlcmlmeQorICAgICAqICAgICAgICAgICAgaWYgdGhpcyBKQVIgZmlsZSBpcyBzaWduZWQgd2hldGhlciBpdCBtdXN0IGJlIHZlcmlmaWVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiB0aGUgZmlsZSBjYW5ub3QgYmUgcmVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSmFyRmlsZShGaWxlIGZpbGUsIGJvb2xlYW4gdmVyaWZ5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihmaWxlKTsKKyAgICAgICAgaWYgKHZlcmlmeSkgeworICAgICAgICAgICAgdmVyaWZpZXIgPSBuZXcgSmFyVmVyaWZpZXIoZmlsZS5nZXRQYXRoKCkpOworICAgICAgICB9CisgICAgICAgIHJlYWRNZXRhRW50cmllcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyB7QGNvZGUgSmFyRmlsZX0gdXNpbmcgdGhlIGNvbnRlbnRzIG9mIGZpbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZQorICAgICAqICAgICAgICAgICAgdGhlIEpBUiBmaWxlIGFzIHtAbGluayBGaWxlfS4KKyAgICAgKiBAcGFyYW0gdmVyaWZ5CisgICAgICogICAgICAgICAgICBpZiB0aGlzIEpBUiBmaWxlZCBpcyBzaWduZWQgd2hldGhlciBpdCBtdXN0IGJlIHZlcmlmaWVkLgorICAgICAqIEBwYXJhbSBtb2RlCisgICAgICogICAgICAgICAgICB0aGUgbW9kZSB0byB1c2UsIGVpdGhlciB7QGxpbmsgWmlwRmlsZSNPUEVOX1JFQUQgT1BFTl9SRUFEfSBvcgorICAgICAqICAgICAgICAgICAge0BsaW5rIFppcEZpbGUjT1BFTl9ERUxFVEUgT1BFTl9ERUxFVEV9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiB0aGUgZmlsZSBjYW5ub3QgYmUgcmVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSmFyRmlsZShGaWxlIGZpbGUsIGJvb2xlYW4gdmVyaWZ5LCBpbnQgbW9kZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoZmlsZSwgbW9kZSk7CisgICAgICAgIGlmICh2ZXJpZnkpIHsKKyAgICAgICAgICAgIHZlcmlmaWVyID0gbmV3IEphclZlcmlmaWVyKGZpbGUuZ2V0UGF0aCgpKTsKKyAgICAgICAgfQorICAgICAgICByZWFkTWV0YUVudHJpZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcge0Bjb2RlIEphckZpbGV9IGZyb20gdGhlIGNvbnRlbnRzIG9mIHRoZSBmaWxlIHNwZWNpZmllZCBieQorICAgICAqIGZpbGVuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGVuYW1lCisgICAgICogICAgICAgICAgICB0aGUgZmlsZSBuYW1lIHJlZmVycmluZyB0byB0aGUgSkFSIGZpbGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGZpbGUgbmFtZSBjYW5ub3QgYmUgb3BlbmVkIGZvciByZWFkaW5nLgorICAgICAqLworICAgIHB1YmxpYyBKYXJGaWxlKFN0cmluZyBmaWxlbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhmaWxlbmFtZSwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBKYXJGaWxlfSBmcm9tIHRoZSBjb250ZW50cyBvZiB0aGUgZmlsZSBzcGVjaWZpZWQgYnkKKyAgICAgKiB7QGNvZGUgZmlsZW5hbWV9LgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGVuYW1lCisgICAgICogICAgICAgICAgICB0aGUgZmlsZSBuYW1lIHJlZmVycmluZyB0byB0aGUgSkFSIGZpbGUuCisgICAgICogQHBhcmFtIHZlcmlmeQorICAgICAqICAgICAgICAgICAgaWYgdGhpcyBKQVIgZmlsZWQgaXMgc2lnbmVkIHdoZXRoZXIgaXQgbXVzdCBiZSB2ZXJpZmllZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgZmlsZSBjYW5ub3QgYmUgb3BlbmVkIG9yIHJlYWQuCisgICAgICovCisgICAgcHVibGljIEphckZpbGUoU3RyaW5nIGZpbGVuYW1lLCBib29sZWFuIHZlcmlmeSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoZmlsZW5hbWUpOworICAgICAgICBpZiAodmVyaWZ5KSB7CisgICAgICAgICAgICB2ZXJpZmllciA9IG5ldyBKYXJWZXJpZmllcihmaWxlbmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgcmVhZE1ldGFFbnRyaWVzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGFuIGVudW1lcmF0aW9uIGNvbnRhaW5pbmcgdGhlIHtAY29kZSBKYXJFbnRyeXN9IGNvbnRhaW5lZCBpbiB0aGlzCisgICAgICoge0Bjb2RlIEphckZpbGV9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIEVudW1lcmF0aW9ufSBjb250YWluaW5nIHRoZSBKQVIgZW50cmllcy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMge0Bjb2RlIEphckZpbGV9IGlzIGNsb3NlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248SmFyRW50cnk+IGVudHJpZXMoKSB7CisgICAgICAgIGNsYXNzIEphckZpbGVFbnVtZXJhdG9yIGltcGxlbWVudHMgRW51bWVyYXRpb248SmFyRW50cnk+IHsKKyAgICAgICAgICAgIEVudW1lcmF0aW9uPD8gZXh0ZW5kcyBaaXBFbnRyeT4gemU7CisKKyAgICAgICAgICAgIEphckZpbGUgamY7CisKKyAgICAgICAgICAgIEphckZpbGVFbnVtZXJhdG9yKEVudW1lcmF0aW9uPD8gZXh0ZW5kcyBaaXBFbnRyeT4gemVudW0sIEphckZpbGUgamYpIHsKKyAgICAgICAgICAgICAgICB6ZSA9IHplbnVtOworICAgICAgICAgICAgICAgIHRoaXMuamYgPSBqZjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTW9yZUVsZW1lbnRzKCkgeworICAgICAgICAgICAgICAgIHJldHVybiB6ZS5oYXNNb3JlRWxlbWVudHMoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIEphckVudHJ5IG5leHRFbGVtZW50KCkgeworICAgICAgICAgICAgICAgIEphckVudHJ5IGplID0gbmV3IEphckVudHJ5KHplLm5leHRFbGVtZW50KCkpOworICAgICAgICAgICAgICAgIGplLnBhcmVudEphciA9IGpmOworICAgICAgICAgICAgICAgIHJldHVybiBqZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEphckZpbGVFbnVtZXJhdG9yKHN1cGVyLmVudHJpZXMoKSwgdGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSB7QGNvZGUgSmFyRW50cnl9IHNwZWNpZmllZCBieSBpdHMgbmFtZSBvciB7QGNvZGUgbnVsbH0gaWYgbm8KKyAgICAgKiBzdWNoIGVudHJ5IGV4aXN0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZW50cnkgaW4gdGhlIEpBUiBmaWxlLgorICAgICAqIEByZXR1cm4gdGhlIEpBUiBlbnRyeSBkZWZpbmVkIGJ5IHRoZSBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyBKYXJFbnRyeSBnZXRKYXJFbnRyeShTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gKEphckVudHJ5KSBnZXRFbnRyeShuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgTWFuaWZlc3R9IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyB7QGNvZGUgSmFyRmlsZX0KKyAgICAgKiBvciB7QGNvZGUgbnVsbH0gaWYgbm8gTUFOSUZFU1QgZW50cnkgZXhpc3RzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgTUFOSUZFU1QuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyByZWFkaW5nIHRoZSBNQU5JRkVTVCBmaWxlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGphciBmaWxlIGlzIGNsb3NlZC4KKyAgICAgKiBAc2VlIE1hbmlmZXN0CisgICAgICovCisgICAgcHVibGljIE1hbmlmZXN0IGdldE1hbmlmZXN0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNsb3NlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiSmFyRmlsZSBoYXMgYmVlbiBjbG9zZWQiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobWFuaWZlc3QgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG1hbmlmZXN0OworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IHN1cGVyLmdldElucHV0U3RyZWFtKG1hbmlmZXN0RW50cnkpOworICAgICAgICAgICAgaWYgKHZlcmlmaWVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB2ZXJpZmllci5hZGRNZXRhRW50cnkobWFuaWZlc3RFbnRyeS5nZXROYW1lKCksIFN0cmVhbXMucmVhZEZ1bGx5KGlzKSk7CisgICAgICAgICAgICAgICAgaXMgPSBzdXBlci5nZXRJbnB1dFN0cmVhbShtYW5pZmVzdEVudHJ5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbWFuaWZlc3QgPSBuZXcgTWFuaWZlc3QoaXMsIHZlcmlmaWVyICE9IG51bGwpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbWFuaWZlc3RFbnRyeSA9IG51bGw7ICAvLyBDYW4gZGlzY2FyZCB0aGUgZW50cnkgbm93LgorICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBtYW5pZmVzdEVudHJ5ID0gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbWFuaWZlc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbGVkIGJ5IHRoZSBKYXJGaWxlIGNvbnN0cnVjdG9ycywgdGhpcyBtZXRob2QgcmVhZHMgdGhlIGNvbnRlbnRzIG9mIHRoZQorICAgICAqIGZpbGUncyBNRVRBLUlORi8gZGlyZWN0b3J5IGFuZCBwaWNrcyBvdXQgdGhlIE1BTklGRVNULk1GIGZpbGUgYW5kCisgICAgICogdmVyaWZpZXIgc2lnbmF0dXJlIGZpbGVzIGlmIHRoZXkgZXhpc3QuIEFueSBzaWduYXR1cmUgZmlsZXMgZm91bmQgYXJlCisgICAgICogcmVnaXN0ZXJlZCB3aXRoIHRoZSB2ZXJpZmllci4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gcmVhZGluZyB0aGUgamFyIGZpbGUgZW50cmllcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZE1ldGFFbnRyaWVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gR2V0IGFsbCBtZXRhIGRpcmVjdG9yeSBlbnRyaWVzCisgICAgICAgIFppcEVudHJ5W10gbWV0YUVudHJpZXMgPSBnZXRNZXRhRW50cmllc0ltcGwoKTsKKyAgICAgICAgaWYgKG1ldGFFbnRyaWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHZlcmlmaWVyID0gbnVsbDsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gc2lnbmVkID0gZmFsc2U7CisKKyAgICAgICAgZm9yIChaaXBFbnRyeSBlbnRyeSA6IG1ldGFFbnRyaWVzKSB7CisgICAgICAgICAgICBTdHJpbmcgZW50cnlOYW1lID0gZW50cnkuZ2V0TmFtZSgpOworICAgICAgICAgICAgLy8gSXMgdGhpcyB0aGUgZW50cnkgZm9yIE1FVEEtSU5GL01BTklGRVNULk1GID8KKyAgICAgICAgICAgIGlmIChtYW5pZmVzdEVudHJ5ID09IG51bGwgJiYgZW50cnlOYW1lLmVxdWFsc0lnbm9yZUNhc2UoTUFOSUZFU1RfTkFNRSkpIHsKKyAgICAgICAgICAgICAgICBtYW5pZmVzdEVudHJ5ID0gZW50cnk7CisgICAgICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gdmVyaWZpZXIgdGhlbiB3ZSBkb24ndCBuZWVkIHRvIGxvb2sgYW55IGZ1cnRoZXIuCisgICAgICAgICAgICAgICAgaWYgKHZlcmlmaWVyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBJcyB0aGlzIGFuIGVudHJ5IHRoYXQgdGhlIHZlcmlmaWVyIG5lZWRzPworICAgICAgICAgICAgICAgIGlmICh2ZXJpZmllciAhPSBudWxsCisgICAgICAgICAgICAgICAgICAgICAgICAmJiAoZW5kc1dpdGhJZ25vcmVDYXNlKGVudHJ5TmFtZSwgIi5TRiIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGVuZHNXaXRoSWdub3JlQ2FzZShlbnRyeU5hbWUsICIuRFNBIikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgZW5kc1dpdGhJZ25vcmVDYXNlKGVudHJ5TmFtZSwgIi5SU0EiKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgc2lnbmVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBzdXBlci5nZXRJbnB1dFN0cmVhbShlbnRyeSk7CisgICAgICAgICAgICAgICAgICAgIHZlcmlmaWVyLmFkZE1ldGFFbnRyeShlbnRyeU5hbWUsIFN0cmVhbXMucmVhZEZ1bGx5KGlzKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gSWYgdGhlcmUgd2VyZSBubyBzaWduYXR1cmUgZmlsZXMsIHRoZW4gbm8gdmVyaWZpZXIgd29yayB0byBkby4KKyAgICAgICAgaWYgKCFzaWduZWQpIHsKKyAgICAgICAgICAgIHZlcmlmaWVyID0gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gZW5kc1dpdGhJZ25vcmVDYXNlKFN0cmluZyBzLCBTdHJpbmcgc3VmZml4KSB7CisgICAgICAgIHJldHVybiBzLnJlZ2lvbk1hdGNoZXModHJ1ZSwgcy5sZW5ndGgoKSAtIHN1ZmZpeC5sZW5ndGgoKSwgc3VmZml4LCAwLCBzdWZmaXgubGVuZ3RoKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhbiB7QGNvZGUgSW5wdXRTdHJlYW19IGZvciByZWFkaW5nIHRoZSBkZWNvbXByZXNzZWQgY29udGVudHMgb2YKKyAgICAgKiBaSVAgZW50cnkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBaSVAgZW50cnkgdG8gYmUgcmVhZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBpbnB1dCBzdHJlYW0gdG8gcmVhZCBmcm9tLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnJlZCB3aGlsZSBjcmVhdGluZyB0aGUgaW5wdXQgc3RyZWFtLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbShaaXBFbnRyeSB6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG1hbmlmZXN0RW50cnkgIT0gbnVsbCkgeworICAgICAgICAgICAgZ2V0TWFuaWZlc3QoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodmVyaWZpZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgdmVyaWZpZXIuc2V0TWFuaWZlc3QoZ2V0TWFuaWZlc3QoKSk7CisgICAgICAgICAgICBpZiAobWFuaWZlc3QgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHZlcmlmaWVyLm1haW5BdHRyaWJ1dGVzRW5kID0gbWFuaWZlc3QuZ2V0TWFpbkF0dHJpYnV0ZXNFbmQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh2ZXJpZmllci5yZWFkQ2VydGlmaWNhdGVzKCkpIHsKKyAgICAgICAgICAgICAgICB2ZXJpZmllci5yZW1vdmVNZXRhRW50cmllcygpOworICAgICAgICAgICAgICAgIGlmIChtYW5pZmVzdCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIG1hbmlmZXN0LnJlbW92ZUNodW5rcygpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoIXZlcmlmaWVyLmlzU2lnbmVkSmFyKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdmVyaWZpZXIgPSBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IHN1cGVyLmdldElucHV0U3RyZWFtKHplKTsKKyAgICAgICAgaWYgKGluID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGlmICh2ZXJpZmllciA9PSBudWxsIHx8IHplLmdldFNpemUoKSA9PSAtMSkgeworICAgICAgICAgICAgcmV0dXJuIGluOworICAgICAgICB9CisgICAgICAgIEphclZlcmlmaWVyLlZlcmlmaWVyRW50cnkgZW50cnkgPSB2ZXJpZmllci5pbml0RW50cnkoemUuZ2V0TmFtZSgpKTsKKyAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBpbjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEphckZpbGVJbnB1dFN0cmVhbShpbiwgemUsIGVudHJ5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHtAY29kZSBKYXJFbnRyeX0gc3BlY2lmaWVkIGJ5IG5hbWUgb3Ige0Bjb2RlIG51bGx9IGlmIG5vIHN1Y2gKKyAgICAgKiBlbnRyeSBleGlzdHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGVudHJ5IGluIHRoZSBKQVIgZmlsZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBaSVAgZW50cnkgZXh0cmFjdGVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBFbnRyeSBnZXRFbnRyeShTdHJpbmcgbmFtZSkgeworICAgICAgICBaaXBFbnRyeSB6ZSA9IHN1cGVyLmdldEVudHJ5KG5hbWUpOworICAgICAgICBpZiAoemUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHplOworICAgICAgICB9CisgICAgICAgIEphckVudHJ5IGplID0gbmV3IEphckVudHJ5KHplKTsKKyAgICAgICAgamUucGFyZW50SmFyID0gdGhpczsKKyAgICAgICAgcmV0dXJuIGplOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYWxsIHRoZSBaaXBFbnRyeSdzIHRoYXQgcmVsYXRlIHRvIGZpbGVzIGluIHRoZQorICAgICAqIEpBUidzIE1FVEEtSU5GIGRpcmVjdG9yeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxpc3Qgb2YgWmlwRW50cnkncyBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgYXJlIG5vbmUuCisgICAgICovCisgICAgcHJpdmF0ZSBaaXBFbnRyeVtdIGdldE1ldGFFbnRyaWVzSW1wbCgpIHsKKyAgICAgICAgTGlzdDxaaXBFbnRyeT4gbGlzdCA9IG5ldyBBcnJheUxpc3Q8WmlwRW50cnk+KDgpOworICAgICAgICBFbnVtZXJhdGlvbjw/IGV4dGVuZHMgWmlwRW50cnk+IGFsbEVudHJpZXMgPSBlbnRyaWVzKCk7CisgICAgICAgIHdoaWxlIChhbGxFbnRyaWVzLmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICBaaXBFbnRyeSB6ZSA9IGFsbEVudHJpZXMubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGlmICh6ZS5nZXROYW1lKCkuc3RhcnRzV2l0aChNRVRBX0RJUikKKyAgICAgICAgICAgICAgICAgICAgJiYgemUuZ2V0TmFtZSgpLmxlbmd0aCgpID4gTUVUQV9ESVIubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgICAgICBsaXN0LmFkZCh6ZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxpc3Quc2l6ZSgpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIFppcEVudHJ5W10gcmVzdWx0ID0gbmV3IFppcEVudHJ5W2xpc3Quc2l6ZSgpXTsKKyAgICAgICAgbGlzdC50b0FycmF5KHJlc3VsdCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMge0Bjb2RlIEphckZpbGV9LgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLmNsb3NlKCk7CisgICAgICAgIGNsb3NlZCA9IHRydWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9qYXIvSmFySW5wdXRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvamFyL0phcklucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDNmNzY1ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvamFyL0phcklucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwyMTcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5qYXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEVudHJ5OworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwSW5wdXRTdHJlYW07CisKKy8qKgorICogVGhlIGlucHV0IHN0cmVhbSBmcm9tIHdoaWNoIHRoZSBKQVIgZmlsZSB0byBiZSByZWFkIG1heSBiZSBmZXRjaGVkLiBJdCBpcworICogdXNlZCBsaWtlIHRoZSB7QGNvZGUgWmlwSW5wdXRTdHJlYW19LgorICoKKyAqIEBzZWUgWmlwSW5wdXRTdHJlYW0KKyAqLworcHVibGljIGNsYXNzIEphcklucHV0U3RyZWFtIGV4dGVuZHMgWmlwSW5wdXRTdHJlYW0geworCisgICAgcHJpdmF0ZSBNYW5pZmVzdCBtYW5pZmVzdDsKKworICAgIHByaXZhdGUgYm9vbGVhbiBlb3MgPSBmYWxzZTsKKworICAgIHByaXZhdGUgSmFyRW50cnkgbUVudHJ5OworCisgICAgcHJpdmF0ZSBKYXJFbnRyeSBqYXJFbnRyeTsKKworICAgIHByaXZhdGUgYm9vbGVhbiBpc01ldGE7CisKKyAgICBwcml2YXRlIEphclZlcmlmaWVyIHZlcmlmaWVyOworCisgICAgcHJpdmF0ZSBPdXRwdXRTdHJlYW0gdmVyU3RyZWFtOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSmFySW5wdXRTdHJlYW19IGZyb20gYW4gaW5wdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIHN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IHN0cmVhbSBjb250YWluaW5nIHRoZSBKQVIgZmlsZS4KKyAgICAgKiBAcGFyYW0gdmVyaWZ5CisgICAgICogICAgICAgICAgICBpZiB0aGUgZmlsZSBzaG91bGQgYmUgdmVyaWZpZWQgd2l0aCBhIHtAY29kZSBKYXJWZXJpZmllcn0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFuIGVycm9yIG9jY3VycyByZWFkaW5nIGVudHJpZXMgZnJvbSB0aGUgaW5wdXQgc3RyZWFtLgorICAgICAqIEBzZWUgWmlwSW5wdXRTdHJlYW0jWmlwSW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0pCisgICAgICovCisgICAgcHVibGljIEphcklucHV0U3RyZWFtKElucHV0U3RyZWFtIHN0cmVhbSwgYm9vbGVhbiB2ZXJpZnkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKHN0cmVhbSk7CisgICAgICAgIGlmICh2ZXJpZnkpIHsKKyAgICAgICAgICAgIHZlcmlmaWVyID0gbmV3IEphclZlcmlmaWVyKCJKYXJJbnB1dFN0cmVhbSIpOworICAgICAgICB9CisgICAgICAgIGlmICgobUVudHJ5ID0gZ2V0TmV4dEphckVudHJ5KCkpID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAobUVudHJ5LmdldE5hbWUoKS5lcXVhbHNJZ25vcmVDYXNlKEphckZpbGUuTUVUQV9ESVIpKSB7CisgICAgICAgICAgICBtRW50cnkgPSBudWxsOyAvLyBtb2RpZmllcyBiZWhhdmlvciBvZiBnZXROZXh0SmFyRW50cnkoKQorICAgICAgICAgICAgY2xvc2VFbnRyeSgpOworICAgICAgICAgICAgbUVudHJ5ID0gZ2V0TmV4dEphckVudHJ5KCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG1FbnRyeS5nZXROYW1lKCkuZXF1YWxzSWdub3JlQ2FzZShKYXJGaWxlLk1BTklGRVNUX05BTUUpKSB7CisgICAgICAgICAgICBtRW50cnkgPSBudWxsOworICAgICAgICAgICAgbWFuaWZlc3QgPSBuZXcgTWFuaWZlc3QodGhpcywgdmVyaWZ5KTsKKyAgICAgICAgICAgIGNsb3NlRW50cnkoKTsKKyAgICAgICAgICAgIGlmICh2ZXJpZnkpIHsKKyAgICAgICAgICAgICAgICB2ZXJpZmllci5zZXRNYW5pZmVzdChtYW5pZmVzdCk7CisgICAgICAgICAgICAgICAgaWYgKG1hbmlmZXN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdmVyaWZpZXIubWFpbkF0dHJpYnV0ZXNFbmQgPSBtYW5pZmVzdC5nZXRNYWluQXR0cmlidXRlc0VuZCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgQXR0cmlidXRlcyB0ZW1wID0gbmV3IEF0dHJpYnV0ZXMoMyk7CisgICAgICAgICAgICB0ZW1wLm1hcC5wdXQoImhpZGRlbiIsIG51bGwpOworICAgICAgICAgICAgbUVudHJ5LnNldEF0dHJpYnV0ZXModGVtcCk7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogaWYgbm90IGZyb20gdGhlIGZpcnN0IGVudHJ5LCB3ZSB3aWxsIG5vdCBnZXQgZW5vdWdoCisgICAgICAgICAgICAgKiBpbmZvcm1hdGlvbixzbyBubyB2ZXJpZnkgd2lsbCBiZSB0YWtlbiBvdXQuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHZlcmlmaWVyID0gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEphcklucHV0U3RyZWFtfSBmcm9tIGFuIGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBzdHJlYW0gY29udGFpbmluZyB0aGUgSkFSIGZpbGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFuIGVycm9yIG9jY3VycyByZWFkaW5nIGVudHJpZXMgZnJvbSB0aGUgaW5wdXQgc3RyZWFtLgorICAgICAqIEBzZWUgWmlwSW5wdXRTdHJlYW0jWmlwSW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0pCisgICAgICovCisgICAgcHVibGljIEphcklucHV0U3RyZWFtKElucHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhzdHJlYW0sIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBNYW5pZmVzdH0gb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIHtAY29kZQorICAgICAqIEphcklucHV0U3RyZWFtfSBvciB7QGNvZGUgbnVsbH0gaWYgbm8gbWFuaWZlc3QgZW50cnkgZXhpc3RzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgTUFOSUZFU1Qgc3BlY2lmeWluZyB0aGUgY29udGVudHMgb2YgdGhlIEpBUiBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBNYW5pZmVzdCBnZXRNYW5pZmVzdCgpIHsKKyAgICAgICAgcmV0dXJuIG1hbmlmZXN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5leHQge0Bjb2RlIEphckVudHJ5fSBjb250YWluZWQgaW4gdGhpcyBzdHJlYW0gb3Ige0Bjb2RlCisgICAgICogbnVsbH0gaWYgbm8gbW9yZSBlbnRyaWVzIGFyZSBwcmVzZW50LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV4dCBKQVIgZW50cnkuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIHRoZSBlbnRyeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSmFyRW50cnkgZ2V0TmV4dEphckVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIChKYXJFbnRyeSkgZ2V0TmV4dEVudHJ5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdXAgdG8ge0Bjb2RlIGxlbmd0aH0gb2YgZGVjb21wcmVzc2VkIGRhdGEgYW5kIHN0b3JlcyBpdCBpbgorICAgICAqIHtAY29kZSBidWZmZXJ9IHN0YXJ0aW5nIGF0IHtAY29kZSBvZmZzZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgQnVmZmVyIHRvIHN0b3JlIGludG8KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICBvZmZzZXQgaW4gYnVmZmVyIHRvIHN0b3JlIGF0CisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgbnVtYmVyIG9mIGJ5dGVzIHRvIHN0b3JlCisgICAgICogQHJldHVybiBOdW1iZXIgb2YgdW5jb21wcmVzc2VkIGJ5dGVzIHJlYWQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSU9FeGNlcHRpb24gb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAobUVudHJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBpbnQgciA9IHN1cGVyLnJlYWQoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIGlmICh2ZXJTdHJlYW0gIT0gbnVsbCAmJiAhZW9zKSB7CisgICAgICAgICAgICBpZiAociA9PSAtMSkgeworICAgICAgICAgICAgICAgIGVvcyA9IHRydWU7CisgICAgICAgICAgICAgICAgaWYgKHZlcmlmaWVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGlzTWV0YSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZpZXIuYWRkTWV0YUVudHJ5KGphckVudHJ5LmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChCeXRlQXJyYXlPdXRwdXRTdHJlYW0pIHZlclN0cmVhbSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudG9CeXRlQXJyYXkoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcmlmaWVyLnJlYWRDZXJ0aWZpY2F0ZXMoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJpZmllciA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICgoSmFyVmVyaWZpZXIuVmVyaWZpZXJFbnRyeSkgdmVyU3RyZWFtKS52ZXJpZnkoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdmVyU3RyZWFtLndyaXRlKGJ1ZmZlciwgb2Zmc2V0LCByKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IHtAY29kZSBaaXBFbnRyeX0gY29udGFpbmVkIGluIHRoaXMgc3RyZWFtIG9yIHtAY29kZQorICAgICAqIG51bGx9IGlmIG5vIG1vcmUgZW50cmllcyBhcmUgcHJlc2VudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgZXh0cmFjdGVkIFpJUCBlbnRyeS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHJlYWRpbmcgdGhlIGVudHJ5LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBaaXBFbnRyeSBnZXROZXh0RW50cnkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAobUVudHJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGphckVudHJ5ID0gbUVudHJ5OworICAgICAgICAgICAgbUVudHJ5ID0gbnVsbDsKKyAgICAgICAgICAgIGphckVudHJ5LnNldEF0dHJpYnV0ZXMobnVsbCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBqYXJFbnRyeSA9IChKYXJFbnRyeSkgc3VwZXIuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICBpZiAoamFyRW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHZlcmlmaWVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpc01ldGEgPSBqYXJFbnRyeS5nZXROYW1lKCkudG9VcHBlckNhc2UoTG9jYWxlLlVTKS5zdGFydHNXaXRoKEphckZpbGUuTUVUQV9ESVIpOworICAgICAgICAgICAgICAgIGlmIChpc01ldGEpIHsKKyAgICAgICAgICAgICAgICAgICAgdmVyU3RyZWFtID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHZlclN0cmVhbSA9IHZlcmlmaWVyLmluaXRFbnRyeShqYXJFbnRyeS5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBlb3MgPSBmYWxzZTsKKyAgICAgICAgcmV0dXJuIGphckVudHJ5OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBaaXBFbnRyeSBjcmVhdGVaaXBFbnRyeShTdHJpbmcgbmFtZSkgeworICAgICAgICBKYXJFbnRyeSBlbnRyeSA9IG5ldyBKYXJFbnRyeShuYW1lKTsKKyAgICAgICAgaWYgKG1hbmlmZXN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGVudHJ5LnNldEF0dHJpYnV0ZXMobWFuaWZlc3QuZ2V0QXR0cmlidXRlcyhuYW1lKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVudHJ5OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvamFyL0phck91dHB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9qYXIvSmFyT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzhlM2FhNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvamFyL0phck91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsODQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5qYXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRW50cnk7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBPdXRwdXRTdHJlYW07CisKKy8qKgorICogVGhlIHtAY29kZSBKYXJPdXRwdXRTdHJlYW19IGlzIHVzZWQgdG8gd3JpdGUgZGF0YSBpbiB0aGUge0Bjb2RlIEphckZpbGV9CisgKiBmb3JtYXQgdG8gYW4gYXJiaXRyYXJ5IG91dHB1dCBzdHJlYW0KKyAqLworcHVibGljIGNsYXNzIEphck91dHB1dFN0cmVhbSBleHRlbmRzIFppcE91dHB1dFN0cmVhbSB7CisKKyAgICBwcml2YXRlIE1hbmlmZXN0IG1hbmlmZXN0OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSmFyT3V0cHV0U3RyZWFtfSB1c2luZyBhbiBvdXRwdXQgc3RyZWFtLiBUaGUKKyAgICAgKiBjb250ZW50IG9mIHRoZSB7QGNvZGUgTWFuaWZlc3R9IG11c3QgbWF0Y2ggdGhlIEpBUiBlbnRyeSBpbmZvcm1hdGlvbgorICAgICAqIHdyaXR0ZW4gc3Vic2VxdWVudGx5IHRvIHRoZSBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT3V0cHV0U3RyZWFtfSB0byB3cml0ZSB0bworICAgICAqIEBwYXJhbSBtZgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBNYW5pZmVzdH0gdG8gb3V0cHV0IGZvciB0aGlzIEpBUiBmaWxlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgY3JlYXRpbmcgdGhlIHtAY29kZSBKYXJPdXRwdXRTdHJlYW19LgorICAgICAqLworICAgIHB1YmxpYyBKYXJPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG9zLCBNYW5pZmVzdCBtZikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIob3MpOworICAgICAgICBpZiAobWYgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgbWFuaWZlc3QgPSBtZjsKKyAgICAgICAgWmlwRW50cnkgemUgPSBuZXcgWmlwRW50cnkoSmFyRmlsZS5NQU5JRkVTVF9OQU1FKTsKKyAgICAgICAgcHV0TmV4dEVudHJ5KHplKTsKKyAgICAgICAgbWFuaWZlc3Qud3JpdGUodGhpcyk7CisgICAgICAgIGNsb3NlRW50cnkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBKYXJPdXRwdXRTdHJlYW19IHVzaW5nIGFuIGFyYml0cmFyeSBvdXRwdXQKKyAgICAgKiBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT3V0cHV0U3RyZWFtfSB0byB3cml0ZSB0by4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSB7QGNvZGUgSmFyT3V0cHV0U3RyZWFtfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSmFyT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIob3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3BlY2lmaWVkIFpJUCBlbnRyeSB0byB0aGUgdW5kZXJseWluZyBzdHJlYW0uIFRoZSBwcmV2aW91cworICAgICAqIGVudHJ5IGlzIGNsb3NlZCBpZiBpdCBpcyBzdGlsbCBvcGVuLgorICAgICAqCisgICAgICogQHBhcmFtIHplCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIFppcEVudHJ5fSB0byB3cml0ZSB0by4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdyaXRpbmcgdG8gdGhlIGVudHJ5LgorICAgICAqIEBzZWUgWmlwRW50cnkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBwdXROZXh0RW50cnkoWmlwRW50cnkgemUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnB1dE5leHRFbnRyeSh6ZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9qYXIvSmFyVmVyaWZpZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvamFyL0phclZlcmlmaWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWMwZTA4OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvamFyL0phclZlcmlmaWVyLmphdmEKQEAgLTAsMCArMSw0NjcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5qYXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0czsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKK2ltcG9ydCBsaWJjb3JlLmlvLkJhc2U2NDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudXRpbHMuSmFyVXRpbHM7CisKKy8qKgorICogTm9uLXB1YmxpYyBjbGFzcyB1c2VkIGJ5IHtAbGluayBKYXJGaWxlfSBhbmQge0BsaW5rIEphcklucHV0U3RyZWFtfSB0byBtYW5hZ2UKKyAqIHRoZSB2ZXJpZmljYXRpb24gb2Ygc2lnbmVkIEpBUnMuIHtAY29kZSBKYXJGaWxlfSBhbmQge0Bjb2RlIEphcklucHV0U3RyZWFtfQorICogb2JqZWN0cyBhcmUgZXhwZWN0ZWQgdG8gaGF2ZSBhIHtAY29kZSBKYXJWZXJpZmllcn0gaW5zdGFuY2UgbWVtYmVyIHdoaWNoCisgKiBjYW4gYmUgdXNlZCB0byBjYXJyeSBvdXQgdGhlIHRhc2tzIGFzc29jaWF0ZWQgd2l0aCB2ZXJpZnlpbmcgYSBzaWduZWQgSkFSLgorICogVGhlc2UgdGFza3Mgd291bGQgdHlwaWNhbGx5IGluY2x1ZGU6CisgKiA8dWw+CisgKiA8bGk+dmVyaWZpY2F0aW9uIG9mIGFsbCBzaWduZWQgc2lnbmF0dXJlIGZpbGVzCisgKiA8bGk+Y29uZmlybWF0aW9uIHRoYXQgYWxsIHNpZ25lZCBkYXRhIHdhcyBzaWduZWQgb25seSBieSB0aGUgcGFydHkgb3IgcGFydGllcworICogc3BlY2lmaWVkIGluIHRoZSBzaWduYXR1cmUgYmxvY2sgZGF0YQorICogPGxpPnZlcmlmaWNhdGlvbiB0aGF0IHRoZSBjb250ZW50cyBvZiBhbGwgc2lnbmF0dXJlIGZpbGVzIChpLmUuIHtAY29kZSAuU0Z9CisgKiBmaWxlcykgYWdyZWUgd2l0aCB0aGUgSkFSIGVudHJpZXMgaW5mb3JtYXRpb24gZm91bmQgaW4gdGhlIEpBUiBtYW5pZmVzdC4KKyAqIDwvdWw+CisgKi8KK2NsYXNzIEphclZlcmlmaWVyIHsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGphck5hbWU7CisKKyAgICBwcml2YXRlIE1hbmlmZXN0IG1hbjsKKworICAgIHByaXZhdGUgSGFzaE1hcDxTdHJpbmcsIGJ5dGVbXT4gbWV0YUVudHJpZXMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIGJ5dGVbXT4oNSk7CisKKyAgICBwcml2YXRlIGZpbmFsIEhhc2h0YWJsZTxTdHJpbmcsIEhhc2hNYXA8U3RyaW5nLCBBdHRyaWJ1dGVzPj4gc2lnbmF0dXJlcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBIYXNoTWFwPFN0cmluZywgQXR0cmlidXRlcz4+KAorICAgICAgICAgICAgNSk7CisKKyAgICBwcml2YXRlIGZpbmFsIEhhc2h0YWJsZTxTdHJpbmcsIENlcnRpZmljYXRlW10+IGNlcnRpZmljYXRlcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBDZXJ0aWZpY2F0ZVtdPigKKyAgICAgICAgICAgIDUpOworCisgICAgcHJpdmF0ZSBmaW5hbCBIYXNodGFibGU8U3RyaW5nLCBDZXJ0aWZpY2F0ZVtdPiB2ZXJpZmllZEVudHJpZXMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgQ2VydGlmaWNhdGVbXT4oKTsKKworICAgIGludCBtYWluQXR0cmlidXRlc0VuZDsKKworICAgIC8qKgorICAgICAqIFN0b3JlcyBhbmQgYSBoYXNoIGFuZCBhIG1lc3NhZ2UgZGlnZXN0IGFuZCB2ZXJpZmllcyB0aGF0IG1hc3NhZ2UgZGlnZXN0CisgICAgICogbWF0Y2hlcyB0aGUgaGFzaC4KKyAgICAgKi8KKyAgICBjbGFzcyBWZXJpZmllckVudHJ5IGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKworICAgICAgICBwcml2YXRlIFN0cmluZyBuYW1lOworCisgICAgICAgIHByaXZhdGUgTWVzc2FnZURpZ2VzdCBkaWdlc3Q7CisKKyAgICAgICAgcHJpdmF0ZSBieXRlW10gaGFzaDsKKworICAgICAgICBwcml2YXRlIENlcnRpZmljYXRlW10gY2VydGlmaWNhdGVzOworCisgICAgICAgIFZlcmlmaWVyRW50cnkoU3RyaW5nIG5hbWUsIE1lc3NhZ2VEaWdlc3QgZGlnZXN0LCBieXRlW10gaGFzaCwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZVtdIGNlcnRpZmljYXRlcykgeworICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgICAgICAgIHRoaXMuZGlnZXN0ID0gZGlnZXN0OworICAgICAgICAgICAgdGhpcy5oYXNoID0gaGFzaDsKKyAgICAgICAgICAgIHRoaXMuY2VydGlmaWNhdGVzID0gY2VydGlmaWNhdGVzOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFVwZGF0ZXMgYSBkaWdlc3Qgd2l0aCBvbmUgYnl0ZS4KKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgdmFsdWUpIHsKKyAgICAgICAgICAgIGRpZ2VzdC51cGRhdGUoKGJ5dGUpIHZhbHVlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBVcGRhdGVzIGEgZGlnZXN0IHdpdGggYnl0ZSBhcnJheS4KKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYnVmLCBpbnQgb2ZmLCBpbnQgbmJ5dGVzKSB7CisgICAgICAgICAgICBkaWdlc3QudXBkYXRlKGJ1Ziwgb2ZmLCBuYnl0ZXMpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFZlcmlmaWVzIHRoYXQgdGhlIGRpZ2VzdHMgc3RvcmVkIGluIHRoZSBtYW5pZmVzdCBtYXRjaCB0aGUgZGVjcnlwdGVkCisgICAgICAgICAqIGRpZ2VzdHMgZnJvbSB0aGUgLlNGIGZpbGUuIFRoaXMgaW5kaWNhdGVzIHRoZSB2YWxpZGl0eSBvZiB0aGUKKyAgICAgICAgICogc2lnbmluZywgbm90IHRoZSBpbnRlZ3JpdHkgb2YgdGhlIGZpbGUsIGFzIGl0J3MgZGlnZXN0IG11c3QgYmUKKyAgICAgICAgICogY2FsY3VsYXRlZCBhbmQgdmVyaWZpZWQgd2hlbiBpdHMgY29udGVudHMgYXJlIHJlYWQuCisgICAgICAgICAqCisgICAgICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYgdGhlIGRpZ2VzdCB2YWx1ZSBzdG9yZWQgaW4gdGhlIG1hbmlmZXN0IGRvZXMgPGk+bm90PC9pPgorICAgICAgICAgKiAgICAgICAgICAgICBhZ3JlZSB3aXRoIHRoZSBkZWNyeXB0ZWQgZGlnZXN0IGFzIHJlY292ZXJlZCBmcm9tIHRoZQorICAgICAgICAgKiAgICAgICAgICAgICA8Y29kZT4uU0Y8L2NvZGU+IGZpbGUuCisgICAgICAgICAqLworICAgICAgICB2b2lkIHZlcmlmeSgpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBkID0gZGlnZXN0LmRpZ2VzdCgpOworICAgICAgICAgICAgaWYgKCFNZXNzYWdlRGlnZXN0LmlzRXF1YWwoZCwgQmFzZTY0LmRlY29kZShoYXNoKSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBpbnZhbGlkRGlnZXN0KEphckZpbGUuTUFOSUZFU1RfTkFNRSwgbmFtZSwgamFyTmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB2ZXJpZmllZEVudHJpZXMucHV0KG5hbWUsIGNlcnRpZmljYXRlcyk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgU2VjdXJpdHlFeGNlcHRpb24gaW52YWxpZERpZ2VzdChTdHJpbmcgc2lnbmF0dXJlRmlsZSwgU3RyaW5nIG5hbWUsIFN0cmluZyBqYXJOYW1lKSB7CisgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbihzaWduYXR1cmVGaWxlICsgIiBoYXMgaW52YWxpZCBkaWdlc3QgZm9yICIgKyBuYW1lICsKKyAgICAgICAgICAgICAgICAiIGluICIgKyBqYXJOYW1lKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFNlY3VyaXR5RXhjZXB0aW9uIGZhaWxlZFZlcmlmaWNhdGlvbihTdHJpbmcgamFyTmFtZSwgU3RyaW5nIHNpZ25hdHVyZUZpbGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKGphck5hbWUgKyAiIGZhaWxlZCB2ZXJpZmljYXRpb24gb2YgIiArIHNpZ25hdHVyZUZpbGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW5kIHJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEphclZlcmlmaWVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgSkFSIGZpbGUgYmVpbmcgdmVyaWZpZWQuCisgICAgICovCisgICAgSmFyVmVyaWZpZXIoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgamFyTmFtZSA9IG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW52b2tlZCBmb3IgZWFjaCBuZXcgSkFSIGVudHJ5IHJlYWQgb3BlcmF0aW9uIGZyb20gdGhlIGlucHV0CisgICAgICogc3RyZWFtLiBUaGlzIG1ldGhvZCBjb25zdHJ1Y3RzIGFuZCByZXR1cm5zIGEgbmV3IHtAbGluayBWZXJpZmllckVudHJ5fQorICAgICAqIHdoaWNoIGNvbnRhaW5zIHRoZSBjZXJ0aWZpY2F0ZXMgdXNlZCB0byBzaWduIHRoZSBlbnRyeSBhbmQgaXRzIGhhc2ggdmFsdWUKKyAgICAgKiBhcyBzcGVjaWZpZWQgaW4gdGhlIEpBUiBNQU5JRkVTVCBmb3JtYXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgYW4gZW50cnkgaW4gYSBKQVIgZmlsZSB3aGljaCBpcyA8Yj5ub3Q8L2I+IGluIHRoZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIE1FVEEtSU5GfSBkaXJlY3RvcnkuCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB7QGxpbmsgVmVyaWZpZXJFbnRyeX0gd2hpY2ggY2FuIGJlIHVzZWQgYnkKKyAgICAgKiAgICAgICAgIGNhbGxlcnMgYXMgYW4ge0BsaW5rIE91dHB1dFN0cmVhbX0uCisgICAgICovCisgICAgVmVyaWZpZXJFbnRyeSBpbml0RW50cnkoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgLy8gSWYgbm8gbWFuaWZlc3QgaXMgcHJlc2VudCBieSB0aGUgdGltZSBhbiBlbnRyeSBpcyBmb3VuZCwKKyAgICAgICAgLy8gdmVyaWZpY2F0aW9uIGNhbm5vdCBvY2N1ci4gSWYgbm8gc2lnbmF0dXJlIGZpbGVzIGhhdmUKKyAgICAgICAgLy8gYmVlbiBmb3VuZCwgZG8gbm90IHZlcmlmeS4KKyAgICAgICAgaWYgKG1hbiA9PSBudWxsIHx8IHNpZ25hdHVyZXMuc2l6ZSgpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQXR0cmlidXRlcyBhdHRyaWJ1dGVzID0gbWFuLmdldEF0dHJpYnV0ZXMobmFtZSk7CisgICAgICAgIC8vIGVudHJ5IGhhcyBubyBkaWdlc3QKKyAgICAgICAgaWYgKGF0dHJpYnV0ZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBBcnJheUxpc3Q8Q2VydGlmaWNhdGU+IGNlcnRzID0gbmV3IEFycmF5TGlzdDxDZXJ0aWZpY2F0ZT4oKTsKKyAgICAgICAgSXRlcmF0b3I8TWFwLkVudHJ5PFN0cmluZywgSGFzaE1hcDxTdHJpbmcsIEF0dHJpYnV0ZXM+Pj4gaXQgPSBzaWduYXR1cmVzLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgTWFwLkVudHJ5PFN0cmluZywgSGFzaE1hcDxTdHJpbmcsIEF0dHJpYnV0ZXM+PiBlbnRyeSA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIEhhc2hNYXA8U3RyaW5nLCBBdHRyaWJ1dGVzPiBobSA9IGVudHJ5LmdldFZhbHVlKCk7CisgICAgICAgICAgICBpZiAoaG0uZ2V0KG5hbWUpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyBGb3VuZCBhbiBlbnRyeSBmb3IgZW50cnkgbmFtZSBpbiAuU0YgZmlsZQorICAgICAgICAgICAgICAgIFN0cmluZyBzaWduYXR1cmVGaWxlID0gZW50cnkuZ2V0S2V5KCk7CisgICAgICAgICAgICAgICAgY2VydHMuYWRkQWxsKGdldFNpZ25lckNlcnRpZmljYXRlcyhzaWduYXR1cmVGaWxlLCBjZXJ0aWZpY2F0ZXMpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIGVudHJ5IGlzIG5vdCBzaWduZWQKKyAgICAgICAgaWYgKGNlcnRzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgQ2VydGlmaWNhdGVbXSBjZXJ0aWZpY2F0ZXNBcnJheSA9IGNlcnRzLnRvQXJyYXkobmV3IENlcnRpZmljYXRlW2NlcnRzLnNpemUoKV0pOworCisgICAgICAgIFN0cmluZyBhbGdvcml0aG1zID0gYXR0cmlidXRlcy5nZXRWYWx1ZSgiRGlnZXN0LUFsZ29yaXRobXMiKTsKKyAgICAgICAgaWYgKGFsZ29yaXRobXMgPT0gbnVsbCkgeworICAgICAgICAgICAgYWxnb3JpdGhtcyA9ICJTSEEgU0hBMSI7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nVG9rZW5pemVyIHRva2VucyA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoYWxnb3JpdGhtcyk7CisgICAgICAgIHdoaWxlICh0b2tlbnMuaGFzTW9yZVRva2VucygpKSB7CisgICAgICAgICAgICBTdHJpbmcgYWxnb3JpdGhtID0gdG9rZW5zLm5leHRUb2tlbigpOworICAgICAgICAgICAgU3RyaW5nIGhhc2ggPSBhdHRyaWJ1dGVzLmdldFZhbHVlKGFsZ29yaXRobSArICItRGlnZXN0Iik7CisgICAgICAgICAgICBpZiAoaGFzaCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBieXRlW10gaGFzaEJ5dGVzID0gaGFzaC5nZXRCeXRlcyhDaGFyc2V0cy5JU09fODg1OV8xKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFZlcmlmaWVyRW50cnkobmFtZSwgTWVzc2FnZURpZ2VzdAorICAgICAgICAgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKGFsZ29yaXRobSksIGhhc2hCeXRlcywgY2VydGlmaWNhdGVzQXJyYXkpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBpZ25vcmVkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkIGEgbmV3IG1ldGEgZW50cnkgdG8gdGhlIGludGVybmFsIGNvbGxlY3Rpb24gb2YgZGF0YSBoZWxkIG9uIGVhY2ggSkFSCisgICAgICogZW50cnkgaW4gdGhlIHtAY29kZSBNRVRBLUlORn0gZGlyZWN0b3J5IGluY2x1ZGluZyB0aGUgbWFuaWZlc3QKKyAgICAgKiBmaWxlIGl0c2VsZi4gRmlsZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBzaWduaW5nIG9mIGEgSkFSIHdvdWxkIGFsc28gYmUKKyAgICAgKiBhZGRlZCB0byB0aGlzIGNvbGxlY3Rpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGZpbGUgbG9jYXRlZCBpbiB0aGUge0Bjb2RlIE1FVEEtSU5GfQorICAgICAqICAgICAgICAgICAgZGlyZWN0b3J5LgorICAgICAqIEBwYXJhbSBidWYKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWxlIGJ5dGVzIGZvciB0aGUgZmlsZSBjYWxsZWQge0Bjb2RlIG5hbWV9LgorICAgICAqIEBzZWUgI3JlbW92ZU1ldGFFbnRyaWVzKCkKKyAgICAgKi8KKyAgICB2b2lkIGFkZE1ldGFFbnRyeShTdHJpbmcgbmFtZSwgYnl0ZVtdIGJ1ZikgeworICAgICAgICBtZXRhRW50cmllcy5wdXQobmFtZS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpLCBidWYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHRoZSBhc3NvY2lhdGVkIEpBUiBmaWxlIGlzIHNpZ25lZCwgY2hlY2sgb24gdGhlIHZhbGlkaXR5IG9mIGFsbCBvZiB0aGUKKyAgICAgKiBrbm93biBzaWduYXR1cmVzLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGFzc29jaWF0ZWQgSkFSIGlzIHNpZ25lZCBhbmQgYW4gaW50ZXJuYWwKKyAgICAgKiAgICAgICAgIGNoZWNrIHZlcmlmaWVzIHRoZSB2YWxpZGl0eSBvZiB0aGUgc2lnbmF0dXJlKHMpLiB7QGNvZGUgZmFsc2V9IGlmCisgICAgICogICAgICAgICB0aGUgYXNzb2NpYXRlZCBKQVIgZmlsZSBoYXMgbm8gZW50cmllcyBhdCBhbGwgaW4gaXRzIHtAY29kZQorICAgICAqICAgICAgICAgTUVUQS1JTkZ9IGRpcmVjdG9yeS4gVGhpcyBzaXR1YXRpb24gaXMgaW5kaWNhdGl2ZSBvZiBhbiBpbnZhbGlkCisgICAgICogICAgICAgICBKQVIgZmlsZS4KKyAgICAgKiAgICAgICAgIDxwPgorICAgICAqICAgICAgICAgV2lsbCBhbHNvIHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIEpBUiBmaWxlIGlzIDxpPm5vdDwvaT4KKyAgICAgKiAgICAgICAgIHNpZ25lZC4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIEpBUiBmaWxlIGlzIHNpZ25lZCBhbmQgaXQgaXMgZGV0ZXJtaW5lZCB0aGF0IGEKKyAgICAgKiAgICAgICAgICAgICBzaWduYXR1cmUgYmxvY2sgZmlsZSBjb250YWlucyBhbiBpbnZhbGlkIHNpZ25hdHVyZSBmb3IgdGhlCisgICAgICogICAgICAgICAgICAgY29ycmVzcG9uZGluZyBzaWduYXR1cmUgZmlsZS4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgYm9vbGVhbiByZWFkQ2VydGlmaWNhdGVzKCkgeworICAgICAgICBpZiAobWV0YUVudHJpZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIEl0ZXJhdG9yPFN0cmluZz4gaXQgPSBtZXRhRW50cmllcy5rZXlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBTdHJpbmcga2V5ID0gaXQubmV4dCgpOworICAgICAgICAgICAgaWYgKGtleS5lbmRzV2l0aCgiLkRTQSIpIHx8IGtleS5lbmRzV2l0aCgiLlJTQSIpKSB7CisgICAgICAgICAgICAgICAgdmVyaWZ5Q2VydGlmaWNhdGUoa2V5KTsKKyAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3IgcmVjdXJzaXZlIGNsYXNzIGxvYWQKKyAgICAgICAgICAgICAgICBpZiAobWV0YUVudHJpZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGl0LnJlbW92ZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBjZXJ0RmlsZQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB2ZXJpZnlDZXJ0aWZpY2F0ZShTdHJpbmcgY2VydEZpbGUpIHsKKyAgICAgICAgLy8gRm91bmQgRGlnaXRhbCBTaWcsIC5TRiBzaG91bGQgYWxyZWFkeSBoYXZlIGJlZW4gcmVhZAorICAgICAgICBTdHJpbmcgc2lnbmF0dXJlRmlsZSA9IGNlcnRGaWxlLnN1YnN0cmluZygwLCBjZXJ0RmlsZS5sYXN0SW5kZXhPZignLicpKQorICAgICAgICAgICAgICAgICsgIi5TRiI7CisgICAgICAgIGJ5dGVbXSBzZkJ5dGVzID0gbWV0YUVudHJpZXMuZ2V0KHNpZ25hdHVyZUZpbGUpOworICAgICAgICBpZiAoc2ZCeXRlcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBieXRlW10gbWFuaWZlc3QgPSBtZXRhRW50cmllcy5nZXQoSmFyRmlsZS5NQU5JRkVTVF9OQU1FKTsKKyAgICAgICAgLy8gTWFuaWZlc3QgZW50cnkgaXMgcmVxdWlyZWQgZm9yIGFueSB2ZXJpZmljYXRpb25zLgorICAgICAgICBpZiAobWFuaWZlc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZVtdIHNCbG9ja0J5dGVzID0gbWV0YUVudHJpZXMuZ2V0KGNlcnRGaWxlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRpZmljYXRlW10gc2lnbmVyQ2VydENoYWluID0gSmFyVXRpbHMudmVyaWZ5U2lnbmF0dXJlKAorICAgICAgICAgICAgICAgICAgICBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc2ZCeXRlcyksCisgICAgICAgICAgICAgICAgICAgIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShzQmxvY2tCeXRlcykpOworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFJlY3Vyc2l2ZSBjYWxsIGluIGxvYWRpbmcgc2VjdXJpdHkgcHJvdmlkZXIgcmVsYXRlZCBjbGFzcyB3aGljaAorICAgICAgICAgICAgICogaXMgaW4gYSBzaWduZWQgSkFSLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAobWV0YUVudHJpZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzaWduZXJDZXJ0Q2hhaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGNlcnRpZmljYXRlcy5wdXQoc2lnbmF0dXJlRmlsZSwgc2lnbmVyQ2VydENoYWluKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9IGNhdGNoIChHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgZmFpbGVkVmVyaWZpY2F0aW9uKGphck5hbWUsIHNpZ25hdHVyZUZpbGUpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVmVyaWZ5IG1hbmlmZXN0IGhhc2ggaW4gLnNmIGZpbGUKKyAgICAgICAgQXR0cmlidXRlcyBhdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgSGFzaE1hcDxTdHJpbmcsIEF0dHJpYnV0ZXM+IGVudHJpZXMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIEF0dHJpYnV0ZXM+KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbml0TWFuaWZlc3QgaW0gPSBuZXcgSW5pdE1hbmlmZXN0KHNmQnl0ZXMsIGF0dHJpYnV0ZXMsIEF0dHJpYnV0ZXMuTmFtZS5TSUdOQVRVUkVfVkVSU0lPTik7CisgICAgICAgICAgICBpbS5pbml0RW50cmllcyhlbnRyaWVzLCBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBjcmVhdGVkQnlTaWdudG9vbCA9IGZhbHNlOworICAgICAgICBTdHJpbmcgY3JlYXRlZEJ5ID0gYXR0cmlidXRlcy5nZXRWYWx1ZSgiQ3JlYXRlZC1CeSIpOworICAgICAgICBpZiAoY3JlYXRlZEJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGNyZWF0ZWRCeVNpZ250b29sID0gY3JlYXRlZEJ5LmluZGV4T2YoInNpZ250b29sIikgIT0gLTE7CisgICAgICAgIH0KKworICAgICAgICAvLyBVc2UgLlNGIHRvIHZlcmlmeSB0aGUgbWFpbkF0dHJpYnV0ZXMgb2YgdGhlIG1hbmlmZXN0CisgICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIC1EaWdlc3QtTWFuaWZlc3QtTWFpbi1BdHRyaWJ1dGVzIGVudHJ5IGluIC5TRgorICAgICAgICAvLyBmaWxlLCBzdWNoIGFzIHRob3NlIGNyZWF0ZWQgYmVmb3JlIGphdmEgMS41LCB0aGVuIHdlIGlnbm9yZQorICAgICAgICAvLyBzdWNoIHZlcmlmaWNhdGlvbi4KKyAgICAgICAgaWYgKG1haW5BdHRyaWJ1dGVzRW5kID4gMCAmJiAhY3JlYXRlZEJ5U2lnbnRvb2wpIHsKKyAgICAgICAgICAgIFN0cmluZyBkaWdlc3RBdHRyaWJ1dGUgPSAiLURpZ2VzdC1NYW5pZmVzdC1NYWluLUF0dHJpYnV0ZXMiOworICAgICAgICAgICAgaWYgKCF2ZXJpZnkoYXR0cmlidXRlcywgZGlnZXN0QXR0cmlidXRlLCBtYW5pZmVzdCwgMCwgbWFpbkF0dHJpYnV0ZXNFbmQsIGZhbHNlLCB0cnVlKSkgeworICAgICAgICAgICAgICAgIHRocm93IGZhaWxlZFZlcmlmaWNhdGlvbihqYXJOYW1lLCBzaWduYXR1cmVGaWxlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFVzZSAuU0YgdG8gdmVyaWZ5IHRoZSB3aG9sZSBtYW5pZmVzdC4KKyAgICAgICAgU3RyaW5nIGRpZ2VzdEF0dHJpYnV0ZSA9IGNyZWF0ZWRCeVNpZ250b29sID8gIi1EaWdlc3QiCisgICAgICAgICAgICAgICAgOiAiLURpZ2VzdC1NYW5pZmVzdCI7CisgICAgICAgIGlmICghdmVyaWZ5KGF0dHJpYnV0ZXMsIGRpZ2VzdEF0dHJpYnV0ZSwgbWFuaWZlc3QsIDAsIG1hbmlmZXN0Lmxlbmd0aCwKKyAgICAgICAgICAgICAgICBmYWxzZSwgZmFsc2UpKSB7CisgICAgICAgICAgICBJdGVyYXRvcjxNYXAuRW50cnk8U3RyaW5nLCBBdHRyaWJ1dGVzPj4gaXQgPSBlbnRyaWVzLmVudHJ5U2V0KCkKKyAgICAgICAgICAgICAgICAgICAgLml0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgTWFwLkVudHJ5PFN0cmluZywgQXR0cmlidXRlcz4gZW50cnkgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgTWFuaWZlc3QuQ2h1bmsgY2h1bmsgPSBtYW4uZ2V0Q2h1bmsoZW50cnkuZ2V0S2V5KCkpOworICAgICAgICAgICAgICAgIGlmIChjaHVuayA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKCF2ZXJpZnkoZW50cnkuZ2V0VmFsdWUoKSwgIi1EaWdlc3QiLCBtYW5pZmVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rLnN0YXJ0LCBjaHVuay5lbmQsIGNyZWF0ZWRCeVNpZ250b29sLCBmYWxzZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgaW52YWxpZERpZ2VzdChzaWduYXR1cmVGaWxlLCBlbnRyeS5nZXRLZXkoKSwgamFyTmFtZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIG1ldGFFbnRyaWVzLnB1dChzaWduYXR1cmVGaWxlLCBudWxsKTsKKyAgICAgICAgc2lnbmF0dXJlcy5wdXQoc2lnbmF0dXJlRmlsZSwgZW50cmllcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzb2NpYXRlIHRoaXMgdmVyaWZpZXIgd2l0aCB0aGUgc3BlY2lmaWVkIHtAbGluayBNYW5pZmVzdH0gb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIG1mCisgICAgICogICAgICAgICAgICBhIHtAY29kZSBqYXZhLnV0aWwuamFyLk1hbmlmZXN0fSBvYmplY3QuCisgICAgICovCisgICAgdm9pZCBzZXRNYW5pZmVzdChNYW5pZmVzdCBtZikgeworICAgICAgICBtYW4gPSBtZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgPGNvZGU+Ym9vbGVhbjwvY29kZT4gaW5kaWNhdGlvbiBvZiB3aGV0aGVyIG9yIG5vdCB0aGUKKyAgICAgKiBhc3NvY2lhdGVkIGphciBmaWxlIGlzIHNpZ25lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBKQVIgaXMgc2lnbmVkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgYm9vbGVhbiBpc1NpZ25lZEphcigpIHsKKyAgICAgICAgcmV0dXJuIGNlcnRpZmljYXRlcy5zaXplKCkgPiAwOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiB2ZXJpZnkoQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBTdHJpbmcgZW50cnksIGJ5dGVbXSBkYXRhLAorICAgICAgICAgICAgaW50IHN0YXJ0LCBpbnQgZW5kLCBib29sZWFuIGlnbm9yZVNlY29uZEVuZGxpbmUsIGJvb2xlYW4gaWdub3JhYmxlKSB7CisgICAgICAgIFN0cmluZyBhbGdvcml0aG1zID0gYXR0cmlidXRlcy5nZXRWYWx1ZSgiRGlnZXN0LUFsZ29yaXRobXMiKTsKKyAgICAgICAgaWYgKGFsZ29yaXRobXMgPT0gbnVsbCkgeworICAgICAgICAgICAgYWxnb3JpdGhtcyA9ICJTSEEgU0hBMSI7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nVG9rZW5pemVyIHRva2VucyA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoYWxnb3JpdGhtcyk7CisgICAgICAgIHdoaWxlICh0b2tlbnMuaGFzTW9yZVRva2VucygpKSB7CisgICAgICAgICAgICBTdHJpbmcgYWxnb3JpdGhtID0gdG9rZW5zLm5leHRUb2tlbigpOworICAgICAgICAgICAgU3RyaW5nIGhhc2ggPSBhdHRyaWJ1dGVzLmdldFZhbHVlKGFsZ29yaXRobSArIGVudHJ5KTsKKyAgICAgICAgICAgIGlmIChoYXNoID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBtZDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbWQgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGlnbm9yZVNlY29uZEVuZGxpbmUgJiYgZGF0YVtlbmQgLSAxXSA9PSAnXG4nCisgICAgICAgICAgICAgICAgICAgICYmIGRhdGFbZW5kIC0gMl0gPT0gJ1xuJykgeworICAgICAgICAgICAgICAgIG1kLnVwZGF0ZShkYXRhLCBzdGFydCwgZW5kIC0gMSAtIHN0YXJ0KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgbWQudXBkYXRlKGRhdGEsIHN0YXJ0LCBlbmQgLSBzdGFydCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBieXRlW10gYiA9IG1kLmRpZ2VzdCgpOworICAgICAgICAgICAgYnl0ZVtdIGhhc2hCeXRlcyA9IGhhc2guZ2V0Qnl0ZXMoQ2hhcnNldHMuSVNPXzg4NTlfMSk7CisgICAgICAgICAgICByZXR1cm4gTWVzc2FnZURpZ2VzdC5pc0VxdWFsKGIsIEJhc2U2NC5kZWNvZGUoaGFzaEJ5dGVzKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlnbm9yYWJsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFsbCBvZiB0aGUge0BsaW5rIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZX0gaW5zdGFuY2VzIHRoYXQKKyAgICAgKiB3ZXJlIHVzZWQgdG8gdmVyaWZ5IHRoZSBzaWduYXR1cmUgb24gdGhlIEpBUiBlbnRyeSBjYWxsZWQKKyAgICAgKiB7QGNvZGUgbmFtZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgYSBKQVIgZW50cnkuCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiB7QGxpbmsgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlfS4KKyAgICAgKi8KKyAgICBDZXJ0aWZpY2F0ZVtdIGdldENlcnRpZmljYXRlcyhTdHJpbmcgbmFtZSkgeworICAgICAgICBDZXJ0aWZpY2F0ZVtdIHZlcmlmaWVkQ2VydHMgPSB2ZXJpZmllZEVudHJpZXMuZ2V0KG5hbWUpOworICAgICAgICBpZiAodmVyaWZpZWRDZXJ0cyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdmVyaWZpZWRDZXJ0cy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSBhbGwgZW50cmllcyBmcm9tIHRoZSBpbnRlcm5hbCBjb2xsZWN0aW9uIG9mIGRhdGEgaGVsZCBhYm91dCBlYWNoCisgICAgICogSkFSIGVudHJ5IGluIHRoZSB7QGNvZGUgTUVUQS1JTkZ9IGRpcmVjdG9yeS4KKyAgICAgKgorICAgICAqIEBzZWUgI2FkZE1ldGFFbnRyeShTdHJpbmcsIGJ5dGVbXSkKKyAgICAgKi8KKyAgICB2b2lkIHJlbW92ZU1ldGFFbnRyaWVzKCkgeworICAgICAgICBtZXRhRW50cmllcyA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHtAY29kZSBWZWN0b3J9IG9mIGFsbCBvZiB0aGUKKyAgICAgKiB7QGxpbmsgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlfXMgdGhhdCBhcmUgYXNzb2NpYXRlZCB3aXRoIHRoZQorICAgICAqIHNpZ25pbmcgb2YgdGhlIG5hbWVkIHNpZ25hdHVyZSBmaWxlLgorICAgICAqCisgICAgICogQHBhcmFtIHNpZ25hdHVyZUZpbGVOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiBhIHNpZ25hdHVyZSBmaWxlLgorICAgICAqIEBwYXJhbSBjZXJ0aWZpY2F0ZXMKKyAgICAgKiAgICAgICAgICAgIGEge0Bjb2RlIE1hcH0gb2YgYWxsIG9mIHRoZSBjZXJ0aWZpY2F0ZSBjaGFpbnMgZGlzY292ZXJlZCBzbworICAgICAqICAgICAgICAgICAgZmFyIHdoaWxlIGF0dGVtcHRpbmcgdG8gdmVyaWZ5IHRoZSBKQVIgdGhhdCBjb250YWlucyB0aGUKKyAgICAgKiAgICAgICAgICAgIHNpZ25hdHVyZSBmaWxlIHtAY29kZSBzaWduYXR1cmVGaWxlTmFtZX0uIFRoaXMgb2JqZWN0IGlzCisgICAgICogICAgICAgICAgICBwcmV2aW91c2x5IHNldCBpbiB0aGUgY291cnNlIG9mIG9uZSBvciBtb3JlIGNhbGxzIHRvCisgICAgICogICAgICAgICAgICB7QGxpbmsgI3ZlcmlmeUphclNpZ25hdHVyZUZpbGUoU3RyaW5nLCBTdHJpbmcsIFN0cmluZywgTWFwLCBNYXApfQorICAgICAqICAgICAgICAgICAgd2hlcmUgaXQgd2FzIHBhc3NlZCBhcyB0aGUgbGFzdCBhcmd1bWVudC4KKyAgICAgKiBAcmV0dXJuIGFsbCBvZiB0aGUge0Bjb2RlIENlcnRpZmljYXRlfSBlbnRyaWVzIGZvciB0aGUgc2lnbmVyIG9mIHRoZSBKQVIKKyAgICAgKiAgICAgICAgIHdob3NlIGFjdGlvbnMgbGVkIHRvIHRoZSBjcmVhdGlvbiBvZiB0aGUgbmFtZWQgc2lnbmF0dXJlIGZpbGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBWZWN0b3I8Q2VydGlmaWNhdGU+IGdldFNpZ25lckNlcnRpZmljYXRlcygKKyAgICAgICAgICAgIFN0cmluZyBzaWduYXR1cmVGaWxlTmFtZSwgTWFwPFN0cmluZywgQ2VydGlmaWNhdGVbXT4gY2VydGlmaWNhdGVzKSB7CisgICAgICAgIFZlY3RvcjxDZXJ0aWZpY2F0ZT4gcmVzdWx0ID0gbmV3IFZlY3RvcjxDZXJ0aWZpY2F0ZT4oKTsKKyAgICAgICAgQ2VydGlmaWNhdGVbXSBjZXJ0Q2hhaW4gPSBjZXJ0aWZpY2F0ZXMuZ2V0KHNpZ25hdHVyZUZpbGVOYW1lKTsKKyAgICAgICAgaWYgKGNlcnRDaGFpbiAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKENlcnRpZmljYXRlIGVsZW1lbnQgOiBjZXJ0Q2hhaW4pIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYWRkKGVsZW1lbnQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9qYXIvTWFuaWZlc3QuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvamFyL01hbmlmZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDQ2YWVhMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvamFyL01hbmlmZXN0LmphdmEKQEAgLTAsMCArMSwzNjIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5qYXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLkNoYXJCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0RW5jb2RlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRzOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ29kZXJSZXN1bHQ7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworCisvKioKKyAqIFRoZSB7QGNvZGUgTWFuaWZlc3R9IGNsYXNzIGlzIHVzZWQgdG8gb2J0YWluIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBmb3IgYQorICoge0Bjb2RlIEphckZpbGV9IGFuZCBpdHMgZW50cmllcy4KKyAqLworcHVibGljIGNsYXNzIE1hbmlmZXN0IGltcGxlbWVudHMgQ2xvbmVhYmxlIHsKKyAgICBzdGF0aWMgZmluYWwgaW50IExJTkVfTEVOR1RIX0xJTUlUID0gNzI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gTElORV9TRVBBUkFUT1IgPSBuZXcgYnl0ZVtdIHsgJ1xyJywgJ1xuJyB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIFZBTFVFX1NFUEFSQVRPUiA9IG5ldyBieXRlW10geyAnOicsICcgJyB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQXR0cmlidXRlcy5OYW1lIE5BTUVfQVRUUklCVVRFID0gbmV3IEF0dHJpYnV0ZXMuTmFtZSgiTmFtZSIpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGQgQkFJU19CVUYgPSBnZXRCeXRlQXJyYXlJbnB1dFN0cmVhbUZpZWxkKCJidWYiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZCBCQUlTX1BPUyA9IGdldEJ5dGVBcnJheUlucHV0U3RyZWFtRmllbGQoInBvcyIpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgRmllbGQgZ2V0Qnl0ZUFycmF5SW5wdXRTdHJlYW1GaWVsZChTdHJpbmcgbmFtZSkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgRmllbGQgZiA9IEJ5dGVBcnJheUlucHV0U3RyZWFtLmNsYXNzLmdldERlY2xhcmVkRmllbGQobmFtZSk7CisgICAgICAgICAgICBmLnNldEFjY2Vzc2libGUodHJ1ZSk7CisgICAgICAgICAgICByZXR1cm4gZjsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBBdHRyaWJ1dGVzIG1haW5BdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZXMoKTsKKworICAgIHByaXZhdGUgSGFzaE1hcDxTdHJpbmcsIEF0dHJpYnV0ZXM+IGVudHJpZXMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIEF0dHJpYnV0ZXM+KCk7CisKKyAgICBzdGF0aWMgY2xhc3MgQ2h1bmsgeworICAgICAgICBpbnQgc3RhcnQ7CisgICAgICAgIGludCBlbmQ7CisKKyAgICAgICAgQ2h1bmsoaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgICAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7CisgICAgICAgICAgICB0aGlzLmVuZCA9IGVuZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgSGFzaE1hcDxTdHJpbmcsIENodW5rPiBjaHVua3M7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZW5kIG9mIHRoZSBtYWluIGF0dHJpYnV0ZXMgc2VjdGlvbiBpbiB0aGUgbWFuaWZlc3QgaXMgbmVlZGVkIGluCisgICAgICogdmVyaWZpY2F0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgaW50IG1haW5FbmQ7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBNYW5pZmVzdH0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIE1hbmlmZXN0KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIE1hbmlmZXN0fSBpbnN0YW5jZSB1c2luZyB0aGUgYXR0cmlidXRlcyBvYnRhaW5lZAorICAgICAqIGZyb20gdGhlIGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpcworICAgICAqICAgICAgICAgICAge0Bjb2RlIElucHV0U3RyZWFtfSB0byBwYXJzZSBmb3IgYXR0cmlidXRlcy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSU8gZXJyb3Igb2NjdXJzIHdoaWxlIGNyZWF0aW5nIHRoaXMge0Bjb2RlIE1hbmlmZXN0fQorICAgICAqLworICAgIHB1YmxpYyBNYW5pZmVzdChJbnB1dFN0cmVhbSBpcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmVhZChpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgTWFuaWZlc3R9IGluc3RhbmNlLiBUaGUgbmV3IGluc3RhbmNlIHdpbGwgaGF2ZSB0aGUKKyAgICAgKiBzYW1lIGF0dHJpYnV0ZXMgYXMgdGhvc2UgZm91bmQgaW4gdGhlIHBhcmFtZXRlciB7QGNvZGUgTWFuaWZlc3R9LgorICAgICAqCisgICAgICogQHBhcmFtIG1hbgorICAgICAqICAgICAgICAgICAge0Bjb2RlIE1hbmlmZXN0fSBpbnN0YW5jZSB0byBvYnRhaW4gYXR0cmlidXRlcyBmcm9tLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBNYW5pZmVzdChNYW5pZmVzdCBtYW4pIHsKKyAgICAgICAgbWFpbkF0dHJpYnV0ZXMgPSAoQXR0cmlidXRlcykgbWFuLm1haW5BdHRyaWJ1dGVzLmNsb25lKCk7CisgICAgICAgIGVudHJpZXMgPSAoSGFzaE1hcDxTdHJpbmcsIEF0dHJpYnV0ZXM+KSAoKEhhc2hNYXA8U3RyaW5nLCBBdHRyaWJ1dGVzPikgbWFuCisgICAgICAgICAgICAgICAgLmdldEVudHJpZXMoKSkuY2xvbmUoKTsKKyAgICB9CisKKyAgICBNYW5pZmVzdChJbnB1dFN0cmVhbSBpcywgYm9vbGVhbiByZWFkQ2h1bmtzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAocmVhZENodW5rcykgeworICAgICAgICAgICAgY2h1bmtzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBDaHVuaz4oKTsKKyAgICAgICAgfQorICAgICAgICByZWFkKGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhlIGJvdGggdGhlIG1haW4gYXR0cmlidXRlcyBhcyB3ZWxsIGFzIHRoZSBlbnRyeSBhdHRyaWJ1dGVzCisgICAgICogYXNzb2NpYXRlZCB3aXRoIHRoaXMge0Bjb2RlIE1hbmlmZXN0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgZW50cmllcy5jbGVhcigpOworICAgICAgICBtYWluQXR0cmlidXRlcy5jbGVhcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBBdHRyaWJ1dGVzfSBhc3NvY2lhdGVkIHdpdGggdGhlIHBhcmFtZXRlciBlbnRyeQorICAgICAqIHtAY29kZSBuYW1lfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZW50cnkgdG8gb2J0YWluIHtAY29kZSBBdHRyaWJ1dGVzfSBmcm9tLgorICAgICAqIEByZXR1cm4gdGhlIEF0dHJpYnV0ZXMgZm9yIHRoZSBlbnRyeSBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIGVudHJ5IGRvZXMKKyAgICAgKiAgICAgICAgIG5vdCBleGlzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXR0cmlidXRlcyBnZXRBdHRyaWJ1dGVzKFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiBnZXRFbnRyaWVzKCkuZ2V0KG5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBtYXAgY29udGFpbmluZyB0aGUge0Bjb2RlIEF0dHJpYnV0ZXN9IGZvciBlYWNoIGVudHJ5IGluIHRoZQorICAgICAqIHtAY29kZSBNYW5pZmVzdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtYXAgb2YgZW50cnkgYXR0cmlidXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWFwPFN0cmluZywgQXR0cmlidXRlcz4gZ2V0RW50cmllcygpIHsKKyAgICAgICAgcmV0dXJuIGVudHJpZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbWFpbiB7QGNvZGUgQXR0cmlidXRlc30gb2YgdGhlIHtAY29kZSBKYXJGaWxlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gbWFpbiB7QGNvZGUgQXR0cmlidXRlc30gYXNzb2NpYXRlZCB3aXRoIHRoZSBzb3VyY2Uge0Bjb2RlCisgICAgICogICAgICAgICBKYXJGaWxlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXR0cmlidXRlcyBnZXRNYWluQXR0cmlidXRlcygpIHsKKyAgICAgICAgcmV0dXJuIG1haW5BdHRyaWJ1dGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBjb3B5IG9mIHRoaXMge0Bjb2RlIE1hbmlmZXN0fS4gVGhlIHJldHVybmVkIHtAY29kZSBNYW5pZmVzdH0KKyAgICAgKiB3aWxsIGVxdWFsIHRoZSB7QGNvZGUgTWFuaWZlc3R9IGZyb20gd2hpY2ggaXQgd2FzIGNsb25lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBjb3B5IG9mIHRoaXMgaW5zdGFuY2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBNYW5pZmVzdCh0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgb3V0IHRoZSBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gb2YgdGhlIHJlY2VpdmVyIHRvIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB7QGNvZGUgT3V0cHV0U3RyZWFtfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcworICAgICAqICAgICAgICAgICAgVGhlIHtAY29kZSBPdXRwdXRTdHJlYW19IHRvIHdyaXRlIHRvLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBlcnJvciBvY2N1cnMgd3JpdGluZyB0aGUge0Bjb2RlIE1hbmlmZXN0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZShPdXRwdXRTdHJlYW0gb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlKHRoaXMsIG9zKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNZXJnZXMgbmFtZS9hdHRyaWJ1dGUgcGFpcnMgcmVhZCBmcm9tIHRoZSBpbnB1dCBzdHJlYW0ge0Bjb2RlIGlzfSBpbnRvIHRoaXMgbWFuaWZlc3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXMKKyAgICAgKiAgICAgICAgICAgIFRoZSB7QGNvZGUgSW5wdXRTdHJlYW19IHRvIHJlYWQgZnJvbS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW4gZXJyb3Igb2NjdXJzIHJlYWRpbmcgdGhlIG1hbmlmZXN0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlYWQoSW5wdXRTdHJlYW0gaXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBidWY7CisgICAgICAgIGlmIChpcyBpbnN0YW5jZW9mIEJ5dGVBcnJheUlucHV0U3RyZWFtKSB7CisgICAgICAgICAgICBidWYgPSBleHBvc2VCeXRlQXJyYXlJbnB1dFN0cmVhbUJ5dGVzKChCeXRlQXJyYXlJbnB1dFN0cmVhbSkgaXMpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYnVmID0gU3RyZWFtcy5yZWFkRnVsbHlOb0Nsb3NlKGlzKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChidWYubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGEgd29ya2Fyb3VuZCBmb3IgSEFSTU9OWS01NjYyCisgICAgICAgIC8vIHJlcGxhY2UgRU9GIGFuZCBOVUwgd2l0aCBhbm90aGVyIG5ldyBsaW5lCisgICAgICAgIC8vIHdoaWNoIGRvZXMgbm90IHRyaWdnZXIgYW4gZXJyb3IKKyAgICAgICAgYnl0ZSBiID0gYnVmW2J1Zi5sZW5ndGggLSAxXTsKKyAgICAgICAgaWYgKGIgPT0gMCB8fCBiID09IDI2KSB7CisgICAgICAgICAgICBidWZbYnVmLmxlbmd0aCAtIDFdID0gJ1xuJzsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEF0dHJpYnV0ZXMuTmFtZS5NQU5JRkVTVF9WRVJTSU9OIGlzIG5vdCB1c2VkIGZvcgorICAgICAgICAvLyB0aGUgc2Vjb25kIHBhcmFtZXRlciBmb3IgUkkgY29tcGF0aWJpbGl0eQorICAgICAgICBJbml0TWFuaWZlc3QgaW0gPSBuZXcgSW5pdE1hbmlmZXN0KGJ1ZiwgbWFpbkF0dHJpYnV0ZXMsIG51bGwpOworICAgICAgICBtYWluRW5kID0gaW0uZ2V0UG9zKCk7CisgICAgICAgIGltLmluaXRFbnRyaWVzKGVudHJpZXMsIGNodW5rcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGJ5dGVbXSBjb250YWluaW5nIGFsbCB0aGUgYnl0ZXMgZnJvbSBhIEJ5dGVBcnJheUlucHV0U3RyZWFtLgorICAgICAqIFdoZXJlIHBvc3NpYmxlLCB0aGlzIHJldHVybnMgdGhlIGFjdHVhbCBhcnJheSByYXRoZXIgdGhhbiBhIGNvcHkuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdIGV4cG9zZUJ5dGVBcnJheUlucHV0U3RyZWFtQnl0ZXMoQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcykgeworICAgICAgICBieXRlW10gYnVmZmVyOworICAgICAgICBzeW5jaHJvbml6ZWQgKGJhaXMpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBidWY7CisgICAgICAgICAgICBpbnQgcG9zOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBidWYgPSAoYnl0ZVtdKSBCQUlTX0JVRi5nZXQoYmFpcyk7CisgICAgICAgICAgICAgICAgcG9zID0gQkFJU19QT1MuZ2V0SW50KGJhaXMpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoaWFlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBhdmFpbGFibGUgPSBiYWlzLmF2YWlsYWJsZSgpOworICAgICAgICAgICAgaWYgKHBvcyA9PSAwICYmIGJ1Zi5sZW5ndGggPT0gYXZhaWxhYmxlKSB7CisgICAgICAgICAgICAgICAgYnVmZmVyID0gYnVmOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBidWZmZXIgPSBuZXcgYnl0ZVthdmFpbGFibGVdOworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCBwb3MsIGJ1ZmZlciwgMCwgYXZhaWxhYmxlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJhaXMuc2tpcChhdmFpbGFibGUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBidWZmZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaGFzaCBjb2RlIGZvciB0aGlzIGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIHtAY29kZSBNYW5pZmVzdH0ncyBoYXNoQ29kZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gbWFpbkF0dHJpYnV0ZXMuaGFzaENvZGUoKSBeIGdldEVudHJpZXMoKS5oYXNoQ29kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgaWYgdGhlIHJlY2VpdmVyIGlzIGVxdWFsIHRvIHRoZSBwYXJhbWV0ZXIgb2JqZWN0LiBUd28ge0Bjb2RlCisgICAgICogTWFuaWZlc3R9cyBhcmUgZXF1YWwgaWYgdGhleSBoYXZlIGlkZW50aWNhbCBtYWluIGF0dHJpYnV0ZXMgYXMgd2VsbCBhcworICAgICAqIGlkZW50aWNhbCBlbnRyeSBhdHRyaWJ1dGVzLgorICAgICAqCisgICAgICogQHBhcmFtIG8KKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSBhZ2FpbnN0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBtYW5pZmVzdHMgYXJlIGVxdWFsLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICBpZiAobyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG8uZ2V0Q2xhc3MoKSAhPSB0aGlzLmdldENsYXNzKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIW1haW5BdHRyaWJ1dGVzLmVxdWFscygoKE1hbmlmZXN0KSBvKS5tYWluQXR0cmlidXRlcykpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0RW50cmllcygpLmVxdWFscygoKE1hbmlmZXN0KSBvKS5nZXRFbnRyaWVzKCkpOworICAgIH0KKworICAgIENodW5rIGdldENodW5rKFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiBjaHVua3MuZ2V0KG5hbWUpOworICAgIH0KKworICAgIHZvaWQgcmVtb3ZlQ2h1bmtzKCkgeworICAgICAgICBjaHVua3MgPSBudWxsOworICAgIH0KKworICAgIGludCBnZXRNYWluQXR0cmlidXRlc0VuZCgpIHsKKyAgICAgICAgcmV0dXJuIG1haW5FbmQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIG91dCB0aGUgYXR0cmlidXRlIGluZm9ybWF0aW9uIG9mIHRoZSBzcGVjaWZpZWQgbWFuaWZlc3QgdG8gdGhlCisgICAgICogc3BlY2lmaWVkIHtAY29kZSBPdXRwdXRTdHJlYW19CisgICAgICoKKyAgICAgKiBAcGFyYW0gbWFuaWZlc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYW5pZmVzdCB0byB3cml0ZSBvdXQuCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgVGhlIHtAY29kZSBPdXRwdXRTdHJlYW19IHRvIHdyaXRlIHRvLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBlcnJvciBvY2N1cnMgd3JpdGluZyB0aGUge0Bjb2RlIE1hbmlmZXN0fS4KKyAgICAgKi8KKyAgICBzdGF0aWMgdm9pZCB3cml0ZShNYW5pZmVzdCBtYW5pZmVzdCwgT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQ2hhcnNldEVuY29kZXIgZW5jb2RlciA9IENoYXJzZXRzLlVURl84Lm5ld0VuY29kZXIoKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBidWZmZXIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKExJTkVfTEVOR1RIX0xJTUlUKTsKKworICAgICAgICBTdHJpbmcgdmVyc2lvbiA9IG1hbmlmZXN0Lm1haW5BdHRyaWJ1dGVzLmdldFZhbHVlKEF0dHJpYnV0ZXMuTmFtZS5NQU5JRkVTVF9WRVJTSU9OKTsKKyAgICAgICAgaWYgKHZlcnNpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgd3JpdGVFbnRyeShvdXQsIEF0dHJpYnV0ZXMuTmFtZS5NQU5JRkVTVF9WRVJTSU9OLCB2ZXJzaW9uLCBlbmNvZGVyLCBidWZmZXIpOworICAgICAgICAgICAgSXRlcmF0b3I8Pz4gZW50cmllcyA9IG1hbmlmZXN0Lm1haW5BdHRyaWJ1dGVzLmtleVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoZW50cmllcy5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBBdHRyaWJ1dGVzLk5hbWUgbmFtZSA9IChBdHRyaWJ1dGVzLk5hbWUpIGVudHJpZXMubmV4dCgpOworICAgICAgICAgICAgICAgIGlmICghbmFtZS5lcXVhbHMoQXR0cmlidXRlcy5OYW1lLk1BTklGRVNUX1ZFUlNJT04pKSB7CisgICAgICAgICAgICAgICAgICAgIHdyaXRlRW50cnkob3V0LCBuYW1lLCBtYW5pZmVzdC5tYWluQXR0cmlidXRlcy5nZXRWYWx1ZShuYW1lKSwgZW5jb2RlciwgYnVmZmVyKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgb3V0LndyaXRlKExJTkVfU0VQQVJBVE9SKTsKKyAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBpID0gbWFuaWZlc3QuZ2V0RW50cmllcygpLmtleVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpLmhhc05leHQoKSkgeworICAgICAgICAgICAgU3RyaW5nIGtleSA9IGkubmV4dCgpOworICAgICAgICAgICAgd3JpdGVFbnRyeShvdXQsIE5BTUVfQVRUUklCVVRFLCBrZXksIGVuY29kZXIsIGJ1ZmZlcik7CisgICAgICAgICAgICBBdHRyaWJ1dGVzIGF0dHJpYiA9IG1hbmlmZXN0LmVudHJpZXMuZ2V0KGtleSk7CisgICAgICAgICAgICBJdGVyYXRvcjw/PiBlbnRyaWVzID0gYXR0cmliLmtleVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoZW50cmllcy5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBBdHRyaWJ1dGVzLk5hbWUgbmFtZSA9IChBdHRyaWJ1dGVzLk5hbWUpIGVudHJpZXMubmV4dCgpOworICAgICAgICAgICAgICAgIHdyaXRlRW50cnkob3V0LCBuYW1lLCBhdHRyaWIuZ2V0VmFsdWUobmFtZSksIGVuY29kZXIsIGJ1ZmZlcik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBvdXQud3JpdGUoTElORV9TRVBBUkFUT1IpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB3cml0ZUVudHJ5KE91dHB1dFN0cmVhbSBvcywgQXR0cmlidXRlcy5OYW1lIG5hbWUsCisgICAgICAgICAgICBTdHJpbmcgdmFsdWUsIENoYXJzZXRFbmNvZGVyIGVuY29kZXIsIEJ5dGVCdWZmZXIgYkJ1ZikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIG5hbWVTdHJpbmcgPSBuYW1lLmdldE5hbWUoKTsKKyAgICAgICAgb3Mud3JpdGUobmFtZVN0cmluZy5nZXRCeXRlcyhDaGFyc2V0cy5VU19BU0NJSSkpOworICAgICAgICBvcy53cml0ZShWQUxVRV9TRVBBUkFUT1IpOworCisgICAgICAgIGVuY29kZXIucmVzZXQoKTsKKyAgICAgICAgYkJ1Zi5jbGVhcigpLmxpbWl0KExJTkVfTEVOR1RIX0xJTUlUIC0gbmFtZVN0cmluZy5sZW5ndGgoKSAtIDIpOworCisgICAgICAgIENoYXJCdWZmZXIgY0J1ZiA9IENoYXJCdWZmZXIud3JhcCh2YWx1ZSk7CisKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIENvZGVyUmVzdWx0IHIgPSBlbmNvZGVyLmVuY29kZShjQnVmLCBiQnVmLCB0cnVlKTsKKyAgICAgICAgICAgIGlmIChDb2RlclJlc3VsdC5VTkRFUkZMT1cgPT0gcikgeworICAgICAgICAgICAgICAgIHIgPSBlbmNvZGVyLmZsdXNoKGJCdWYpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgb3Mud3JpdGUoYkJ1Zi5hcnJheSgpLCBiQnVmLmFycmF5T2Zmc2V0KCksIGJCdWYucG9zaXRpb24oKSk7CisgICAgICAgICAgICBvcy53cml0ZShMSU5FX1NFUEFSQVRPUik7CisgICAgICAgICAgICBpZiAoQ29kZXJSZXN1bHQuVU5ERVJGTE9XID09IHIpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG9zLndyaXRlKCcgJyk7CisgICAgICAgICAgICBiQnVmLmNsZWFyKCkubGltaXQoTElORV9MRU5HVEhfTElNSVQgLSAxKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvamFyL1BhY2syMDAuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvamFyL1BhY2syMDAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYWNmMjQxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9qYXIvUGFjazIwMC5qYXZhCkBAIC0wLDAgKzEsMzE1IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgamF2YS51dGlsLmphcjsKKworaW1wb3J0IGphdmEuYmVhbnMuUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5Tb3J0ZWRNYXA7CisKKy8qKgorICogQ2xhc3MgZmFjdG9yeSBmb3Ige0BsaW5rIFBhY2syMDAuUGFja2VyfSBhbmQge0BsaW5rIFBhY2syMDAuVW5wYWNrZXJ9LgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgUGFjazIwMCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1lTVEVNX1BST1BFUlRZX1BBQ0tFUiA9ICJqYXZhLnV0aWwuamFyLlBhY2syMDAuUGFja2VyIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTWVNURU1fUFJPUEVSVFlfVU5QQUNLRVIgPSAiamF2YS51dGlsLmphci5QYWNrMjAwLlVucGFja2VyIjsKKworICAgIC8qKgorICAgICAqIFByZXZlbnQgdGhpcyBjbGFzcyBmcm9tIGJlaW5nIGluc3RhbnRpYXRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFBhY2syMDAoKSB7CisgICAgICAgIC8vIGRvIG5vdGhpbmcKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIGEgcGFja2VyIGVuZ2luZS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gb2YgdGhlIHBhY2tlciBlbmdpbmUgaXMgZGVmaW5lZCBieSB0aGUgc3lzdGVtIHByb3BlcnR5CisgICAgICoge0Bjb2RlICdqYXZhLnV0aWwuamFyLlBhY2syMDAuUGFja2VyJ30uIElmIHRoaXMgc3lzdGVtIHByb3BlcnR5IGlzCisgICAgICogZGVmaW5lZCBhbiBpbnN0YW5jZSBvZiB0aGUgc3BlY2lmaWVkIGNsYXNzIGlzIHJldHVybmVkLCBvdGhlcndpc2UgdGhlCisgICAgICogc3lzdGVtJ3MgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIFBhY2tlcn0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFBhY2syMDAuUGFja2VyIG5ld1BhY2tlcigpIHsKKyAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eShTWVNURU1fUFJPUEVSVFlfUEFDS0VSLCAib3JnLmFwYWNoZS5oYXJtb255LnBhY2syMDAuUGFjazIwMFBhY2tlckFkYXB0ZXIiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFRPRE8gTm90IHN1cmUgaWYgdGhpcyB3aWxsIGNhdXNlIHByb2JsZW1zIHdpdGgKKyAgICAgICAgICAgIC8vIGxvYWRpbmcgdGhlIHBhY2tlcgorICAgICAgICAgICAgcmV0dXJuIChQYWNrZXIpIENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkubG9hZENsYXNzKGNsYXNzTmFtZSkubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiQ2FuJ3QgbG9hZCBjbGFzcyAiICsgY2xhc3NOYW1lLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2YgYSB1bnBhY2tlciBlbmdpbmUuCisgICAgICogPHA+CisgICAgICogVGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZSB1bnBhY2tlciBlbmdpbmUgaXMgZGVmaW5lZCBieSB0aGUgc3lzdGVtCisgICAgICogcHJvcGVydHkge0Bjb2RlICdqYXZhLnV0aWwuamFyLlBhY2syMDAuVW5wYWNrZXInfS4gSWYgdGhpcyBzeXN0ZW0KKyAgICAgKiBwcm9wZXJ0eSBpcyBkZWZpbmVkIGFuIGluc3RhbmNlIG9mIHRoZSBzcGVjaWZpZWQgY2xhc3MgaXMgcmV0dXJuZWQsCisgICAgICogb3RoZXJ3aXNlIHRoZSBzeXN0ZW0ncyBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiBhIGluc3RhbmNlIG9mIHtAY29kZSBVbnBhY2tlcn0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBQYWNrMjAwLlVucGFja2VyIG5ld1VucGFja2VyKCkgeworICAgICAgICBTdHJpbmcgY2xhc3NOYW1lID0gU3lzdGVtLmdldFByb3BlcnR5KFNZU1RFTV9QUk9QRVJUWV9VTlBBQ0tFUiwgIm9yZy5hcGFjaGUuaGFybW9ueS51bnBhY2syMDAuUGFjazIwMFVucGFja2VyQWRhcHRlciIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIChVbnBhY2tlcikgQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoY2xhc3NOYW1lKS5uZXdJbnN0YW5jZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJDYW4ndCBsb2FkIGNsYXNzICIgKyBjbGFzc05hbWUsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGludGVyZmFjZSBkZWZpbmluZyB0aGUgQVBJIGZvciBjb252ZXJ0aW5nIGEgSkFSIGZpbGUgdG8gYW4gb3V0cHV0CisgICAgICogc3RyZWFtIGluIHRoZSBQYWNrMjAwIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludGVyZmFjZSBQYWNrZXIgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiB0aGUgZm9ybWF0IG9mIGEgY2xhc3MgYXR0cmlidXRlIG5hbWUuCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgZmluYWwgU3RyaW5nIENMQVNTX0FUVFJJQlVURV9QRlggPSAicGFjay5jbGFzcy5hdHRyaWJ1dGUuIjsKKworICAgICAgICAvKioKKyAgICAgICAgICogdGhlIGZvcm1hdCBvZiBhIGNvZGUgYXR0cmlidXRlIG5hbWUuCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgZmluYWwgU3RyaW5nIENPREVfQVRUUklCVVRFX1BGWCA9ICJwYWNrLmNvZGUuYXR0cmlidXRlLiI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIHRoZSBkZWZsYXRpb24gaGludCB0byBzZXQgaW4gdGhlIG91dHB1dCBhcmNoaXZlLgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIFN0cmluZyBERUZMQVRFX0hJTlQgPSAicGFjay5kZWZsYXRlLmhpbnQiOworCisgICAgICAgIC8qKgorICAgICAgICAgKiB0aGUgaW5kaWNhdGVkIGFtb3VudCBvZiBlZmZvcnQgdG8gdXNlIGluIGNvbXByZXNzaW5nIHRoZSBhcmNoaXZlLgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIFN0cmluZyBFRkZPUlQgPSAicGFjay5lZmZvcnQiOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBhIFN0cmluZyByZXByZXNlbnRhdGlvbiBmb3Ige0Bjb2RlIGVycm9yfS4KKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1IgPSAiZXJyb3IiOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBhIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUgZmFsc2V9LgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIFN0cmluZyBGQUxTRSA9ICJmYWxzZSI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIHRoZSBmb3JtYXQgb2YgYSBmaWVsZCBhdHRyaWJ1dGUgbmFtZS4KKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklFTERfQVRUUklCVVRFX1BGWCA9ICJwYWNrLmZpZWxkLmF0dHJpYnV0ZS4iOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBhIFN0cmluZyByZXByZXNlbnRhdGlvbiBmb3Ige0Bjb2RlIGtlZXB9LgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIFN0cmluZyBLRUVQID0gImtlZXAiOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBkZWNpZGUgaWYgYWxsIGVsZW1lbnRzIHNoYWxsIHRyYW5zbWl0IGluIHRoZWlyIG9yaWdpbmFsIG9yZGVyLgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIFN0cmluZyBLRUVQX0ZJTEVfT1JERVIgPSAicGFjay5rZWVwLmZpbGUub3JkZXIiOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBhIFN0cmluZyByZXByZXNlbnRhdGlvbiBmb3Ige0Bjb2RlIGxhdGVzdH0uCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgZmluYWwgU3RyaW5nIExBVEVTVCA9ICJsYXRlc3QiOworCisgICAgICAgIC8qKgorICAgICAgICAgKiB0aGUgZm9ybWF0IG9mIGEgbWV0aG9kIGF0dHJpYnV0ZSBuYW1lLgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIFN0cmluZyBNRVRIT0RfQVRUUklCVVRFX1BGWCA9ICJwYWNrLm1ldGhvZC5hdHRyaWJ1dGUuIjsKKworICAgICAgICAvKioKKyAgICAgICAgICogaWYgaXQgc2hhbGwgYXR0ZW1wdCB0byBkZXRlcm1pbmUgdGhlIGxhdGVzdCBtb2RpZmljYXRpb24gdGltZSBpZiB0aGlzCisgICAgICAgICAqIGlzIHNldCB0byB7QGNvZGUgTEFURVNUfS4KKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgTU9ESUZJQ0FUSU9OX1RJTUUgPSAicGFjay5tb2RpZmljYXRpb24udGltZSI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIGEgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHtAY29kZSBwYXNzfS4KKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgUEFTUyA9ICJwYXNzIjsKKworICAgICAgICAvKioKKyAgICAgICAgICogdGhlIGZpbGUgdGhhdCB3aWxsIG5vdCBiZSBjb21wcmVzc2VkLgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIFN0cmluZyBQQVNTX0ZJTEVfUEZYID0gInBhY2sucGFzcy5maWxlLiI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIHBhY2tlciBwcm9ncmVzcyBhcyBhIHBlcmNlbnRhZ2UuCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgZmluYWwgU3RyaW5nIFBST0dSRVNTID0gInBhY2sucHJvZ3Jlc3MiOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgbnVtYmVyIG9mIGJ5dGVzIG9mIGVhY2ggYXJjaGl2ZSBzZWdtZW50LgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIFN0cmluZyBTRUdNRU5UX0xJTUlUID0gInBhY2suc2VnbWVudC5saW1pdCI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIGEgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHtAY29kZSBzdHJpcH0uCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgZmluYWwgU3RyaW5nIFNUUklQID0gInN0cmlwIjsKKworICAgICAgICAvKioKKyAgICAgICAgICogYSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIHRydWV9LgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIFN0cmluZyBUUlVFID0gInRydWUiOworCisgICAgICAgIC8qKgorICAgICAgICAgKiB0aGUgYWN0aW9uIHRvIHRha2UgaWYgYW4gdW5rbm93biBhdHRyaWJ1dGUgaXMgZW5jb3VudGVyZWQuCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgZmluYWwgU3RyaW5nIFVOS05PV05fQVRUUklCVVRFID0gInBhY2sudW5rbm93bi5hdHRyaWJ1dGUiOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGEgc29ydGVkIG1hcCBvZiB0aGUgcHJvcGVydGllcyBvZiB0aGlzIHBhY2tlci4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiB0aGUgcHJvcGVydGllcyBvZiB0aGUgcGFja2VyLgorICAgICAgICAgKi8KKyAgICAgICAgU29ydGVkTWFwPFN0cmluZywgU3RyaW5nPiBwcm9wZXJ0aWVzKCk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFBhY2sgdGhlIHNwZWNpZmllZCBKQVIgZmlsZSB0byB0aGUgc3BlY2lmaWVkIG91dHB1dCBzdHJlYW0uCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBpbgorICAgICAgICAgKiAgICAgICAgICAgIEpBUiBmaWxlIHRvIGJlIGNvbXByZXNzZWQuCisgICAgICAgICAqIEBwYXJhbSBvdXQKKyAgICAgICAgICogICAgICAgICAgICBzdHJlYW0gb2YgY29tcHJlc3NlZCBkYXRhLgorICAgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIEkvTyBleGNlcHRpb24gb2NjdXJzLgorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBwYWNrKEphckZpbGUgaW4sIE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgICAgICAvKioKKyAgICAgICAgICogUGFjayB0aGUgZGF0YSBmcm9tIHRoZSBzcGVjaWZpZWQgamFyIGlucHV0IHN0cmVhbSB0byB0aGUgc3BlY2lmaWVkCisgICAgICAgICAqIG91dHB1dCBzdHJlYW0uCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBpbgorICAgICAgICAgKiAgICAgICAgICAgIHN0cmVhbSBvZiB1bmNvbXByZXNzZWQgSkFSIGRhdGEuCisgICAgICAgICAqIEBwYXJhbSBvdXQKKyAgICAgICAgICogICAgICAgICAgICBzdHJlYW0gb2YgY29tcHJlc3NlZCBkYXRhLgorICAgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICAgICAqICAgICAgICAgICAgIGlmIEkvTyBleGNlcHRpb24gb2NjdXJzLgorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBwYWNrKEphcklucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIGFkZCBhIGxpc3RlbmVyIGZvciBQcm9wZXJ0eUNoYW5nZSBldmVudHMKKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIGxpc3RlbmVyCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGxpc3RlbmVyIHRvIGxpc3RlbiBpZiBQcm9wZXJ0eUNoYW5nZSBldmVudHMgb2NjdXJzCisgICAgICAgICAqLworICAgICAgICB2b2lkIGFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lcik7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIHJlbW92ZSBhIGxpc3RlbmVyCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBsaXN0ZW5lcgorICAgICAgICAgKiAgICAgICAgICAgIGxpc3RlbmVyIHRvIHJlbW92ZQorICAgICAgICAgKi8KKyAgICAgICAgdm9pZCByZW1vdmVQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBpbnRlcmZhY2UgZGVmaW5pbmcgdGhlIEFQSSBmb3IgY29udmVydGluZyBhIHBhY2tlZCBzdHJlYW0gaW4gdGhlCisgICAgICogUGFjazIwMCBmb3JtYXQgdG8gYSBKQVIgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludGVyZmFjZSBVbnBhY2tlciB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBTdHJpbmcgaW5kaWNhdGluZyBpZiB0aGUgdW5wYWNrZXIgc2hvdWxkIGlnbm9yZSBhbGwgdHJhbnNtaXR0ZWQKKyAgICAgICAgICogdmFsdWVzLGNhbiBiZSByZXBsYWNlZCBieSBlaXRoZXIge0Bjb2RlIHRydWV9IG9yIHtAY29kZSBmYWxzZX0uCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkxBVEVfSElOVCA9ICJ1bnBhY2suZGVmbGF0ZS5oaW50IjsKKworICAgICAgICAvKioKKyAgICAgICAgICogYSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIGZhbHNlfS4KKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRkFMU0UgPSAiZmFsc2UiOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBhIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB7QGNvZGUga2VlcH0uCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgZmluYWwgU3RyaW5nIEtFRVAgPSAia2VlcCI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIHRoZSBwcm9ncmVzcyBhcyBhIHtAY29kZSBwZXJjZW50YWdlfS4KKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJPR1JFU1MgPSAidW5wYWNrLnByb2dyZXNzIjsKKworICAgICAgICAvKioKKyAgICAgICAgICogYSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIHRydWV9LgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIFN0cmluZyBUUlVFID0gInRydWUiOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGEgc29ydGVkIG1hcCBvZiB0aGUgcHJvcGVydGllcyBvZiB0aGlzIHVucGFja2VyLgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBwcm9wZXJ0aWVzIG9mIHVucGFja2VyLgorICAgICAgICAgKi8KKyAgICAgICAgU29ydGVkTWFwPFN0cmluZywgU3RyaW5nPiBwcm9wZXJ0aWVzKCk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFVucGFjayB0aGUgc3BlY2lmaWVkIHN0cmVhbSB0byB0aGUgc3BlY2lmaWVkIEpBUiBvdXRwdXQgc3RyZWFtLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gaW4KKyAgICAgICAgICogICAgICAgICAgICBzdHJlYW0gdG8gdW5jb21wcmVzc2VkLgorICAgICAgICAgKiBAcGFyYW0gb3V0CisgICAgICAgICAqICAgICAgICAgICAgSkFSIG91dHB1dCBzdHJlYW0gb2YgdW5jb21wcmVzc2VkIGRhdGEuCisgICAgICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYgSS9PIGV4Y2VwdGlvbiBvY2N1cnMuCisgICAgICAgICAqLworICAgICAgICB2b2lkIHVucGFjayhJbnB1dFN0cmVhbSBpbiwgSmFyT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBVbnBhY2sgdGhlIGNvbnRlbnRzIG9mIHRoZSBzcGVjaWZpZWQge0Bjb2RlIEZpbGV9IHRvIHRoZSBzcGVjaWZpZWQKKyAgICAgICAgICogSkFSIG91dHB1dCBzdHJlYW0uCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBpbgorICAgICAgICAgKiAgICAgICAgICAgIGZpbGUgdG8gYmUgdW5jb21wcmVzc2VkLgorICAgICAgICAgKiBAcGFyYW0gb3V0CisgICAgICAgICAqICAgICAgICAgICAgSkFSIG91dHB1dCBzdHJlYW0gb2YgdW5jb21wcmVzc2VkIGRhdGEuCisgICAgICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYgSS9PIGV4Y2VwdGlvbiBvY2N1cnMuCisgICAgICAgICAqLworICAgICAgICB2b2lkIHVucGFjayhGaWxlIGluLCBKYXJPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIGFkZCBhIGxpc3RlbmVyIGZvciB7QGNvZGUgUHJvcGVydHlDaGFuZ2V9IGV2ZW50cy4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIGxpc3RlbmVyCisgICAgICAgICAqICAgICAgICAgICAgdGhlIGxpc3RlbmVyIHRvIGxpc3RlbiBpZiB7QGNvZGUgUHJvcGVydHlDaGFuZ2V9IGV2ZW50cworICAgICAgICAgKiAgICAgICAgICAgIG9jY3Vycy4KKyAgICAgICAgICovCisgICAgICAgIHZvaWQgYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogcmVtb3ZlIGEgbGlzdGVuZXIuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBsaXN0ZW5lcgorICAgICAgICAgKiAgICAgICAgICAgIGxpc3RlbmVyIHRvIHJlbW92ZS4KKyAgICAgICAgICovCisgICAgICAgIHZvaWQgcmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9Db25zb2xlSGFuZGxlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL0NvbnNvbGVIYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOThiN2IyNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9Db25zb2xlSGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsNzIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5sb2dnaW5nOworCisvKioKKyAqIEEgaGFuZGxlciB0aGF0IHdyaXRlcyBsb2cgbWVzc2FnZXMgdG8gdGhlIHN0YW5kYXJkIG91dHB1dCBzdHJlYW0KKyAqIHtAY29kZSBTeXN0ZW0uZXJyfS4KKyAqIDxwPgorICogVGhpcyBoYW5kbGVyIHJlYWRzIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBmcm9tIHRoZSBsb2cgbWFuYWdlciB0bworICogaW5pdGlhbGl6ZSBpdHNlbGY6CisgKiA8dWw+CisgKiA8bGk+amF2YS51dGlsLmxvZ2dpbmcuQ29uc29sZUhhbmRsZXIubGV2ZWwgc3BlY2lmaWVzIHRoZSBsb2dnaW5nIGxldmVsLAorICogZGVmYXVsdHMgdG8ge0Bjb2RlIExldmVsLklORk99IGlmIHRoaXMgcHJvcGVydHkgaXMgbm90IGZvdW5kIG9yIGhhcyBhbgorICogaW52YWxpZCB2YWx1ZS4KKyAqIDxsaT5qYXZhLnV0aWwubG9nZ2luZy5Db25zb2xlSGFuZGxlci5maWx0ZXIgc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBmaWx0ZXIKKyAqIGNsYXNzIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGhhbmRsZXIsIGRlZmF1bHRzIHRvIHtAY29kZSBudWxsfSBpZiB0aGlzCisgKiBwcm9wZXJ0eSBpcyBub3QgZm91bmQgb3IgaGFzIGFuIGludmFsaWQgdmFsdWUuCisgKiA8bGk+amF2YS51dGlsLmxvZ2dpbmcuQ29uc29sZUhhbmRsZXIuZm9ybWF0dGVyIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUKKyAqIGZvcm1hdHRlciBjbGFzcyB0byBiZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBoYW5kbGVyLCBkZWZhdWx0cyB0bworICoge0Bjb2RlIGphdmEudXRpbC5sb2dnaW5nLlNpbXBsZUZvcm1hdHRlcn0gaWYgdGhpcyBwcm9wZXJ0eSBpcyBub3QgZm91bmQgb3IKKyAqIGhhcyBhbiBpbnZhbGlkIHZhbHVlLgorICogPGxpPmphdmEudXRpbC5sb2dnaW5nLkNvbnNvbGVIYW5kbGVyLmVuY29kaW5nIHNwZWNpZmllcyB0aGUgZW5jb2RpbmcgdGhpcworICogaGFuZGxlciB3aWxsIHVzZSB0byBlbmNvZGUgbG9nIG1lc3NhZ2VzLCBkZWZhdWx0cyB0byB7QGNvZGUgbnVsbH0gaWYgdGhpcworICogcHJvcGVydHkgaXMgbm90IGZvdW5kIG9yIGhhcyBhbiBpbnZhbGlkIHZhbHVlLgorICogPC91bD4KKyAqIDxwPgorICogVGhpcyBjbGFzcyBpcyBub3QgdGhyZWFkLXNhZmUuCisgKi8KK3B1YmxpYyBjbGFzcyBDb25zb2xlSGFuZGxlciBleHRlbmRzIFN0cmVhbUhhbmRsZXIgeworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBDb25zb2xlSGFuZGxlcn0gb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBDb25zb2xlSGFuZGxlcigpIHsKKyAgICAgICAgc3VwZXIoU3lzdGVtLmVycik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgaGFuZGxlci4gVGhlIHtAY29kZSBTeXN0ZW0uZXJyfSBpcyBmbHVzaGVkIGJ1dCBub3QgY2xvc2VkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgeworICAgICAgICBzdXBlci5jbG9zZShmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9ncyBhIHJlY29yZCBpZiBuZWNlc3NhcnkuIEEgZmx1c2ggb3BlcmF0aW9uIHdpbGwgYmUgZG9uZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWNvcmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2cgcmVjb3JkIHRvIGJlIGxvZ2dlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBwdWJsaXNoKExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgc3VwZXIucHVibGlzaChyZWNvcmQpOworICAgICAgICBzdXBlci5mbHVzaCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9FcnJvck1hbmFnZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9FcnJvck1hbmFnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NzdiZTBiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL0Vycm9yTWFuYWdlci5qYXZhCkBAIC0wLDAgKzEsMTA1IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwubG9nZ2luZzsKKworLyoqCisgKiBBbiBlcnJvciByZXBvcnRpbmcgZmFjaWxpdHkgZm9yIHtAbGluayBIYW5kbGVyfSBpbXBsZW1lbnRhdGlvbnMgdG8gcmVjb3JkIGFueQorICogZXJyb3IgdGhhdCBtYXkgaGFwcGVuIGR1cmluZyBsb2dnaW5nLiB7QGNvZGUgSGFuZGxlcnN9IHNob3VsZCByZXBvcnQgZXJyb3JzCisgKiB0byBhbiB7QGNvZGUgRXJyb3JNYW5hZ2VyfSwgaW5zdGVhZCBvZiB0aHJvd2luZyBleGNlcHRpb25zLCB3aGljaCB3b3VsZAorICogaW50ZXJmZXJlIHdpdGggdGhlIGxvZyBpc3N1ZXIncyBleGVjdXRpb24uCisgKi8KK3B1YmxpYyBjbGFzcyBFcnJvck1hbmFnZXIgeworCisgICAgLyoqCisgICAgICogVGhlIGVycm9yIGNvZGUgaW5kaWNhdGluZyBhIGZhaWx1cmUgdGhhdCBkb2VzIG5vdCBmaXQgaW4gYW55IG9mIHRoZQorICAgICAqIHNwZWNpZmljIHR5cGVzIG9mIGZhaWx1cmVzIHRoYXQgZm9sbG93LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEdFTkVSSUNfRkFJTFVSRSA9IDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZXJyb3IgY29kZSBpbmRpY2F0aW5nIGEgZmFpbHVyZSB3aGVuIHdyaXRpbmcgdG8gYW4gb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXUklURV9GQUlMVVJFID0gMTsKKworICAgIC8qKgorICAgICAqIFRoZSBlcnJvciBjb2RlIGluZGljYXRpbmcgYSBmYWlsdXJlIHdoZW4gZmx1c2hpbmcgYW4gb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGTFVTSF9GQUlMVVJFID0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSBlcnJvciBjb2RlIGluZGljYXRpbmcgYSBmYWlsdXJlIHdoZW4gY2xvc2luZyBhbiBvdXRwdXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMT1NFX0ZBSUxVUkUgPSAzOworCisgICAgLyoqCisgICAgICogVGhlIGVycm9yIGNvZGUgaW5kaWNhdGluZyBhIGZhaWx1cmUgd2hlbiBvcGVuaW5nIGFuIG91dHB1dCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BFTl9GQUlMVVJFID0gNDsKKworICAgIC8qKgorICAgICAqIFRoZSBlcnJvciBjb2RlIGluZGljYXRpbmcgYSBmYWlsdXJlIHdoZW4gZm9ybWF0dGluZyB0aGUgZXJyb3IgbWVzc2FnZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9STUFUX0ZBSUxVUkUgPSA1OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gRkFJTFVSRVMgPSBuZXcgU3RyaW5nW10geyAiR0VORVJJQ19GQUlMVVJFIiwKKyAgICAgICAgICAgICJXUklURV9GQUlMVVJFIiwgIkZMVVNIX0ZBSUxVUkUiLCAiQ0xPU0VfRkFJTFVSRSIsICJPUEVOX0ZBSUxVUkUiLAorICAgICAgICAgICAgIkZPUk1BVF9GQUlMVVJFIiB9OworCisgICAgLyoqCisgICAgICogQW4gaW5kaWNhdG9yIGZvciBkZXRlcm1pbmluZyBpZiB0aGUgZXJyb3IgbWFuYWdlciBoYXMgYmVlbiBjYWxsZWQgYXQKKyAgICAgKiBsZWFzdCBvbmNlIGJlZm9yZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gY2FsbGVkOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgRXJyb3JNYW5hZ2VyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRXJyb3JNYW5hZ2VyKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcG9ydHMgYW4gZXJyb3IgdXNpbmcgdGhlIGdpdmVuIG1lc3NhZ2UsIGV4Y2VwdGlvbiBhbmQgZXJyb3IgY29kZS4gVGhpcworICAgICAqIGltcGxlbWVudGF0aW9uIHdpbGwgd3JpdGUgb3V0IHRoZSBtZXNzYWdlIHRvIHtAbGluayBTeXN0ZW0jZXJyfSBvbiB0aGUKKyAgICAgKiBmaXJzdCBjYWxsIGFuZCBhbGwgc3Vic2VxdWVudCBjYWxscyBhcmUgaWdub3JlZC4gQSBzdWJjbGFzcyBvZiB0aGlzIGNsYXNzCisgICAgICogc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBlcnJvciBtZXNzYWdlLCB3aGljaCBtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqIEBwYXJhbSBleGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNlcHRpb24gYXNzb2NpYXRlZCB3aXRoIHRoZSBlcnJvciwgd2hpY2ggbWF5IGJlCisgICAgICogICAgICAgICAgICB7QGNvZGUgbnVsbH0uCisgICAgICogQHBhcmFtIGVycm9yQ29kZQorICAgICAqICAgICAgICAgICAgdGhlIGVycm9yIGNvZGUgdGhhdCBpZGVudGlmaWVzIHRoZSB0eXBlIG9mIGVycm9yOyBzZWUgdGhlCisgICAgICogICAgICAgICAgICBjb25zdGFudCBmaWVsZHMgb2YgdGhpcyBjbGFzcyBmb3IgcG9zc2libGUgdmFsdWVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVycm9yKFN0cmluZyBtZXNzYWdlLCBFeGNlcHRpb24gZXhjZXB0aW9uLCBpbnQgZXJyb3JDb2RlKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgaWYgKGNhbGxlZCkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhbGxlZCA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiOiAiICsgRkFJTFVSRVNbZXJyb3JDb2RlXSk7CisgICAgICAgIGlmIChtZXNzYWdlICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiRXJyb3IgbWVzc2FnZSAtICIgKyBtZXNzYWdlKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXhjZXB0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiRXhjZXB0aW9uIC0gIiArIGV4Y2VwdGlvbik7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvRmlsZUhhbmRsZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9GaWxlSGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk4MDk1NWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvRmlsZUhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDU2NyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmxvZ2dpbmc7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5GaWxlQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5GaWxlTG9jazsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKKworLyoqCisgKiBBIHtAY29kZSBGaWxlSGFuZGxlcn0gd3JpdGVzIGxvZ2dpbmcgcmVjb3JkcyBpbnRvIGEgc3BlY2lmaWVkIGZpbGUgb3IgYQorICogcm90YXRpbmcgc2V0IG9mIGZpbGVzLgorICogPHA+CisgKiBXaGVuIGEgc2V0IG9mIGZpbGVzIGlzIHVzZWQgYW5kIGEgZ2l2ZW4gYW1vdW50IG9mIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiB0bworICogb25lIGZpbGUsIHRoZW4gdGhpcyBmaWxlIGlzIGNsb3NlZCBhbmQgYW5vdGhlciBmaWxlIGlzIG9wZW5lZC4gVGhlIG5hbWUgb2YKKyAqIHRoZXNlIGZpbGVzIGFyZSBnZW5lcmF0ZWQgYnkgZ2l2ZW4gbmFtZSBwYXR0ZXJuLCBzZWUgYmVsb3cgZm9yIGRldGFpbHMuCisgKiBXaGVuIHRoZSBmaWxlcyBoYXZlIGFsbCBiZWVuIGZpbGxlZCB0aGUgSGFuZGxlciByZXR1cm5zIHRvIHRoZSBmaXJzdCBhbmQgZ29lcworICogdGhyb3VnaCB0aGUgc2V0IGFnYWluLgorICogPHA+CisgKiBCeSBkZWZhdWx0LCB0aGUgSS9PIGJ1ZmZlcmluZyBtZWNoYW5pc20gaXMgZW5hYmxlZCwgYnV0IHdoZW4gZWFjaCBsb2cgcmVjb3JkCisgKiBpcyBjb21wbGV0ZSwgaXQgaXMgZmx1c2hlZCBvdXQuCisgKiA8cD4KKyAqIHtAY29kZSBYTUxGb3JtYXR0ZXJ9IGlzIHRoZSBkZWZhdWx0IGZvcm1hdHRlciBmb3Ige0Bjb2RlIEZpbGVIYW5kbGVyfS4KKyAqIDxwPgorICoge0Bjb2RlIEZpbGVIYW5kbGVyfSByZWFkcyB0aGUgZm9sbG93aW5nIHtAY29kZSBMb2dNYW5hZ2VyfSBwcm9wZXJ0aWVzIGZvcgorICogaW5pdGlhbGl6YXRpb247IGlmIGEgcHJvcGVydHkgaXMgbm90IGRlZmluZWQgb3IgaGFzIGFuIGludmFsaWQgdmFsdWUsIGEKKyAqIGRlZmF1bHQgdmFsdWUgaXMgdXNlZC4KKyAqIDx1bD4KKyAqIDxsaT5qYXZhLnV0aWwubG9nZ2luZy5GaWxlSGFuZGxlci5hcHBlbmQgc3BlY2lmaWVzIHdoZXRoZXIgdGhpcworICoge0Bjb2RlIEZpbGVIYW5kbGVyfSBzaG91bGQgYXBwZW5kIG9udG8gZXhpc3RpbmcgZmlsZXMsIGRlZmF1bHRzIHRvCisgKiB7QGNvZGUgZmFsc2V9LjwvbGk+CisgKiA8bGk+amF2YS51dGlsLmxvZ2dpbmcuRmlsZUhhbmRsZXIuY291bnQgc3BlY2lmaWVzIGhvdyBtYW55IG91dHB1dCBmaWxlcyB0bworICogcm90YXRlLCBkZWZhdWx0cyB0byAxLjwvbGk+CisgKiA8bGk+amF2YS51dGlsLmxvZ2dpbmcuRmlsZUhhbmRsZXIuZmlsdGVyIHNwZWNpZmllcyB0aGUge0Bjb2RlIEZpbHRlcn0gY2xhc3MKKyAqIG5hbWUsIGRlZmF1bHRzIHRvIG5vIHtAY29kZSBGaWx0ZXJ9LjwvbGk+CisgKiA8bGk+amF2YS51dGlsLmxvZ2dpbmcuRmlsZUhhbmRsZXIuZm9ybWF0dGVyIHNwZWNpZmllcyB0aGUge0Bjb2RlIEZvcm1hdHRlcn0KKyAqIGNsYXNzLCBkZWZhdWx0cyB0byB7QGNvZGUgamF2YS51dGlsLmxvZ2dpbmcuWE1MRm9ybWF0dGVyfS48L2xpPgorICogPGxpPmphdmEudXRpbC5sb2dnaW5nLkZpbGVIYW5kbGVyLmVuY29kaW5nIHNwZWNpZmllcyB0aGUgY2hhcmFjdGVyIHNldAorICogZW5jb2RpbmcgbmFtZSwgZGVmYXVsdHMgdG8gdGhlIGRlZmF1bHQgcGxhdGZvcm0gZW5jb2RpbmcuPC9saT4KKyAqIDxsaT5qYXZhLnV0aWwubG9nZ2luZy5GaWxlSGFuZGxlci5sZXZlbCBzcGVjaWZpZXMgdGhlIGxldmVsIGZvciB0aGlzCisgKiB7QGNvZGUgSGFuZGxlcn0sIGRlZmF1bHRzIHRvIHtAY29kZSBMZXZlbC5BTEx9LjwvbGk+CisgKiA8bGk+amF2YS51dGlsLmxvZ2dpbmcuRmlsZUhhbmRsZXIubGltaXQgc3BlY2lmaWVzIHRoZSBtYXhpbXVtIG51bWJlciBvZgorICogYnl0ZXMgdG8gd3JpdGUgdG8gYW55IG9uZSBmaWxlLCBkZWZhdWx0cyB0byB6ZXJvLCB3aGljaCBtZWFucyBubyBsaW1pdC48L2xpPgorICogPGxpPmphdmEudXRpbC5sb2dnaW5nLkZpbGVIYW5kbGVyLnBhdHRlcm4gc3BlY2lmaWVzIG5hbWUgcGF0dGVybiBmb3IgdGhlCisgKiBvdXRwdXQgZmlsZXMuIFNlZSBiZWxvdyBmb3IgZGV0YWlscy4gRGVmYXVsdHMgdG8gIiVoL2phdmEldS5sb2ciLjwvbGk+CisgKiA8L3VsPgorICogPHA+CisgKiBOYW1lIHBhdHRlcm4gaXMgYSBzdHJpbmcgdGhhdCBtYXkgaW5jbHVkZSBzb21lIHNwZWNpYWwgc3Vic3RyaW5ncywgd2hpY2ggd2lsbAorICogYmUgcmVwbGFjZWQgdG8gZ2VuZXJhdGUgb3V0cHV0IGZpbGVzOgorICogPHVsPgorICogPGxpPiIvIiByZXByZXNlbnRzIHRoZSBsb2NhbCBwYXRobmFtZSBzZXBhcmF0b3I8L2xpPgorICogPGxpPiIlZyIgcmVwcmVzZW50cyB0aGUgZ2VuZXJhdGlvbiBudW1iZXIgdG8gZGlzdGluZ3Vpc2ggcm90YXRlZCBsb2dzPC9saT4KKyAqIDxsaT4iJWgiIHJlcHJlc2VudHMgdGhlIGhvbWUgZGlyZWN0b3J5IG9mIHRoZSBjdXJyZW50IHVzZXIsIHdoaWNoIGlzCisgKiBzcGVjaWZpZWQgYnkgInVzZXIuaG9tZSIgc3lzdGVtIHByb3BlcnR5PC9saT4KKyAqIDxsaT4iJXQiIHJlcHJlc2VudHMgdGhlIHN5c3RlbSdzIHRlbXBvcmFyeSBkaXJlY3Rvcnk8L2xpPgorICogPGxpPiIldSIgcmVwcmVzZW50cyBhIHVuaXF1ZSBudW1iZXIgdG8gcmVzb2x2ZSBjb25mbGljdHM8L2xpPgorICogPGxpPiIlJSIgcmVwcmVzZW50cyB0aGUgcGVyY2VudCBzaWduIGNoYXJhY3RlciAnJSc8L2xpPgorICogPC91bD4KKyAqIDxwPgorICogTm9ybWFsbHksIHRoZSBnZW5lcmF0aW9uIG51bWJlcnMgYXJlIG5vdCBsYXJnZXIgdGhhbiB0aGUgZ2l2ZW4gZmlsZSBjb3VudCBhbmQKKyAqIGZvbGxvdyB0aGUgc2VxdWVuY2UgMCwgMSwgMi4uLi4gSWYgdGhlIGZpbGUgY291bnQgaXMgbGFyZ2VyIHRoYW4gb25lLCBidXQgdGhlCisgKiBnZW5lcmF0aW9uIGZpZWxkKCIlZyIpIGhhcyBub3QgYmVlbiBzcGVjaWZpZWQgaW4gdGhlIHBhdHRlcm4sIHRoZW4gdGhlCisgKiBnZW5lcmF0aW9uIG51bWJlciBhZnRlciBhIGRvdCB3aWxsIGJlIGFkZGVkIHRvIHRoZSBlbmQgb2YgdGhlIGZpbGUgbmFtZS4KKyAqIDxwPgorICogVGhlICIldSIgdW5pcXVlIGZpZWxkIGlzIHVzZWQgdG8gYXZvaWQgY29uZmxpY3RzIGFuZCBpcyBzZXQgdG8gMCBhdCBmaXJzdC4gSWYKKyAqIG9uZSB7QGNvZGUgRmlsZUhhbmRsZXJ9IHRyaWVzIHRvIG9wZW4gdGhlIGZpbGVuYW1lIHdoaWNoIGlzIGN1cnJlbnRseSBpbiB1c2UKKyAqIGJ5IGFub3RoZXIgcHJvY2VzcywgaXQgd2lsbCByZXBlYXRlZGx5IGluY3JlbWVudCB0aGUgdW5pcXVlIG51bWJlciBmaWVsZCBhbmQKKyAqIHRyeSBhZ2Fpbi4gSWYgdGhlICIldSIgY29tcG9uZW50IGhhcyBub3QgYmVlbiBpbmNsdWRlZCBpbiB0aGUgZmlsZSBuYW1lCisgKiBwYXR0ZXJuIGFuZCBzb21lIGNvbnRlbnRpb24gb24gYSBmaWxlIGRvZXMgb2NjdXIsIHRoZW4gYSB1bmlxdWUgbnVtZXJpY2FsCisgKiB2YWx1ZSB3aWxsIGJlIGFkZGVkIHRvIHRoZSBlbmQgb2YgdGhlIGZpbGVuYW1lIGluIHF1ZXN0aW9uIGltbWVkaWF0ZWx5IHRvIHRoZQorICogcmlnaHQgb2YgYSBkb3QuIFRoZSBnZW5lcmF0aW9uIG9mIHVuaXF1ZSBJRHMgZm9yIGF2b2lkaW5nIGNvbmZsaWN0cyBpcyBvbmx5CisgKiBndWFyYW50ZWVkIHRvIHdvcmsgcmVsaWFibHkgd2hlbiB1c2luZyBhIGxvY2FsIGRpc2sgZmlsZSBzeXN0ZW0uCisgKi8KK3B1YmxpYyBjbGFzcyBGaWxlSGFuZGxlciBleHRlbmRzIFN0cmVhbUhhbmRsZXIgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIExDS19FWFQgPSAiLmxjayI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9DT1VOVCA9IDE7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9MSU1JVCA9IDA7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFRkFVTFRfQVBQRU5EID0gZmFsc2U7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9QQVRURVJOID0gIiVoL2phdmEldS5sb2ciOworCisgICAgLy8gbWFpbnRhaW4gYWxsIGZpbGUgbG9ja3MgaG9sZCBieSB0aGlzIHByb2Nlc3MKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBIYXNodGFibGU8U3RyaW5nLCBGaWxlTG9jaz4gYWxsTG9ja3MgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgRmlsZUxvY2s+KCk7CisKKyAgICAvLyB0aGUgY291bnQgb2YgZmlsZXMgd2hpY2ggdGhlIG91dHB1dCBjeWNsZSB0aHJvdWdoCisgICAgcHJpdmF0ZSBpbnQgY291bnQ7CisKKyAgICAvLyB0aGUgc2l6ZSBsaW1pdGF0aW9uIGluIGJ5dGUgb2YgbG9nIGZpbGUKKyAgICBwcml2YXRlIGludCBsaW1pdDsKKworICAgIC8vIHdoZXRoZXIgdGhlIEZpbGVIYW5kbGVyIHNob3VsZCBvcGVuIGEgZXhpc3RpbmcgZmlsZSBmb3Igb3V0cHV0IGluIGFwcGVuZAorICAgIC8vIG1vZGUKKyAgICBwcml2YXRlIGJvb2xlYW4gYXBwZW5kOworCisgICAgLy8gdGhlIHBhdHRlcm4gZm9yIG91dHB1dCBmaWxlIG5hbWUKKyAgICBwcml2YXRlIFN0cmluZyBwYXR0ZXJuOworCisgICAgLy8gbWFpbnRhaW4gYSBMb2dNYW5hZ2VyIGluc3RhbmNlIGZvciBjb252ZW5pZW5jZQorICAgIHByaXZhdGUgTG9nTWFuYWdlciBtYW5hZ2VyOworCisgICAgLy8gb3V0cHV0IHN0cmVhbSwgd2hpY2ggY2FuIG1lYXN1cmUgdGhlIG91dHB1dCBmaWxlIGxlbmd0aAorICAgIHByaXZhdGUgTWVhc3VyZU91dHB1dFN0cmVhbSBvdXRwdXQ7CisKKyAgICAvLyB1c2VkIG91dHB1dCBmaWxlCisgICAgcHJpdmF0ZSBGaWxlW10gZmlsZXM7CisKKyAgICAvLyBvdXRwdXQgZmlsZSBsb2NrCisgICAgRmlsZUxvY2sgbG9jayA9IG51bGw7CisKKyAgICAvLyBjdXJyZW50IG91dHB1dCBmaWxlIG5hbWUKKyAgICBTdHJpbmcgZmlsZU5hbWUgPSBudWxsOworCisgICAgLy8gY3VycmVudCB1bmlxdWUgSUQKKyAgICBpbnQgdW5pcXVlSUQgPSAtMTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIHtAY29kZSBGaWxlSGFuZGxlcn0gdXNpbmcge0Bjb2RlIExvZ01hbmFnZXJ9IHByb3BlcnRpZXMgb3IKKyAgICAgKiB0aGVpciBkZWZhdWx0IHZhbHVlLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBGaWxlSGFuZGxlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGluaXQobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7CisgICAgfQorCisgICAgLy8gaW5pdCBwcm9wZXJ0aWVzCisgICAgcHJpdmF0ZSB2b2lkIGluaXQoU3RyaW5nIHAsIEJvb2xlYW4gYSwgSW50ZWdlciBsLCBJbnRlZ2VyIGMpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBjaGVjayBhY2Nlc3MKKyAgICAgICAgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgICAgICBtYW5hZ2VyLmNoZWNrQWNjZXNzKCk7CisgICAgICAgIGluaXRQcm9wZXJ0aWVzKHAsIGEsIGwsIGMpOworICAgICAgICBpbml0T3V0cHV0RmlsZXMoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgaW5pdE91dHB1dEZpbGVzKCkgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgLy8gdHJ5IHRvIGZpbmQgYSB1bmlxdWUgZmlsZSB3aGljaCBpcyBub3QgbG9ja2VkIGJ5IG90aGVyIHByb2Nlc3MKKyAgICAgICAgICAgIHVuaXF1ZUlEKys7CisgICAgICAgICAgICAvLyBGSVhNRTogaW1wcm92ZSBwZXJmb3JtYW5jZSBoZXJlCisgICAgICAgICAgICBmb3IgKGludCBnZW5lcmF0aW9uID0gMDsgZ2VuZXJhdGlvbiA8IGNvdW50OyBnZW5lcmF0aW9uKyspIHsKKyAgICAgICAgICAgICAgICAvLyBjYWNoZSBhbGwgZmlsZSBuYW1lcyBmb3Igcm90YXRpb24gdXNlCisgICAgICAgICAgICAgICAgZmlsZXNbZ2VuZXJhdGlvbl0gPSBuZXcgRmlsZShwYXJzZUZpbGVOYW1lKGdlbmVyYXRpb24pKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpbGVOYW1lID0gZmlsZXNbMF0uZ2V0QWJzb2x1dGVQYXRoKCk7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGFsbExvY2tzKSB7CisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgKiBpZiBjdXJyZW50IHByb2Nlc3MgaGFzIGhlbGQgbG9jayBmb3IgdGhpcyBmaWxlTmFtZSBjb250aW51ZQorICAgICAgICAgICAgICAgICAqIHRvIGZpbmQgbmV4dCBmaWxlCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgaWYgKGFsbExvY2tzLmdldChmaWxlTmFtZSkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGZpbGVzWzBdLmV4aXN0cygpCisgICAgICAgICAgICAgICAgICAgICAgICAmJiAoIWFwcGVuZCB8fCBmaWxlc1swXS5sZW5ndGgoKSA+PSBsaW1pdCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGNvdW50IC0gMTsgaSA+IDA7IGktLSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVzW2ldLmV4aXN0cygpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZXNbaV0uZGVsZXRlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc1tpIC0gMV0ucmVuYW1lVG8oZmlsZXNbaV0pOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gZmlsZVN0cmVhbSA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZpbGVOYW1lCisgICAgICAgICAgICAgICAgICAgICAgICArIExDS19FWFQpOworICAgICAgICAgICAgICAgIEZpbGVDaGFubmVsIGNoYW5uZWwgPSBmaWxlU3RyZWFtLmdldENoYW5uZWwoKTsKKyAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAqIGlmIGxvY2sgaXMgdW5zdXBwb3J0ZWQgYW5kIElPRXhjZXB0aW9uIHRocm93biwganVzdCBsZXQgdGhlCisgICAgICAgICAgICAgICAgICogSU9FeGNlcHRpb24gdGhyb3dzIG91dCBhbmQgZXhpdCBvdGhlcndpc2UgaXQgd2lsbCBnbyBpbnRvIGFuCisgICAgICAgICAgICAgICAgICogdW5kZWFkIGN5Y2xlCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgbG9jayA9IGNoYW5uZWwudHJ5TG9jaygpOworICAgICAgICAgICAgICAgIGlmIChsb2NrID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkoZmlsZVN0cmVhbSk7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhbGxMb2Nrcy5wdXQoZmlsZU5hbWUsIGxvY2spOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIG91dHB1dCA9IG5ldyBNZWFzdXJlT3V0cHV0U3RyZWFtKG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICBuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlTmFtZSwgYXBwZW5kKSksIGZpbGVzWzBdLmxlbmd0aCgpKTsKKyAgICAgICAgc2V0T3V0cHV0U3RyZWFtKG91dHB1dCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGluaXRQcm9wZXJ0aWVzKFN0cmluZyBwLCBCb29sZWFuIGEsIEludGVnZXIgbCwgSW50ZWdlciBjKSB7CisgICAgICAgIHN1cGVyLmluaXRQcm9wZXJ0aWVzKCJBTEwiLCBudWxsLCAiamF2YS51dGlsLmxvZ2dpbmcuWE1MRm9ybWF0dGVyIiwKKyAgICAgICAgICAgICAgICBudWxsKTsKKyAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9IHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCk7CisgICAgICAgIHBhdHRlcm4gPSAocCA9PSBudWxsKSA/IGdldFN0cmluZ1Byb3BlcnR5KGNsYXNzTmFtZSArICIucGF0dGVybiIsCisgICAgICAgICAgICAgICAgREVGQVVMVF9QQVRURVJOKSA6IHA7CisgICAgICAgIGlmIChwYXR0ZXJuID09IG51bGwgfHwgcGF0dGVybi5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiUGF0dGVybiBjYW5ub3QgYmUgZW1wdHkgb3IgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGFwcGVuZCA9IChhID09IG51bGwpID8gZ2V0Qm9vbGVhblByb3BlcnR5KGNsYXNzTmFtZSArICIuYXBwZW5kIiwKKyAgICAgICAgICAgICAgICBERUZBVUxUX0FQUEVORCkgOiBhLmJvb2xlYW5WYWx1ZSgpOworICAgICAgICBjb3VudCA9IChjID09IG51bGwpID8gZ2V0SW50UHJvcGVydHkoY2xhc3NOYW1lICsgIi5jb3VudCIsCisgICAgICAgICAgICAgICAgREVGQVVMVF9DT1VOVCkgOiBjLmludFZhbHVlKCk7CisgICAgICAgIGxpbWl0ID0gKGwgPT0gbnVsbCkgPyBnZXRJbnRQcm9wZXJ0eShjbGFzc05hbWUgKyAiLmxpbWl0IiwKKyAgICAgICAgICAgICAgICBERUZBVUxUX0xJTUlUKSA6IGwuaW50VmFsdWUoKTsKKyAgICAgICAgY291bnQgPSBjb3VudCA8IDEgPyBERUZBVUxUX0NPVU5UIDogY291bnQ7CisgICAgICAgIGxpbWl0ID0gbGltaXQgPCAwID8gREVGQVVMVF9MSU1JVCA6IGxpbWl0OworICAgICAgICBmaWxlcyA9IG5ldyBGaWxlW2NvdW50XTsKKyAgICB9CisKKyAgICB2b2lkIGZpbmROZXh0R2VuZXJhdGlvbigpIHsKKyAgICAgICAgc3VwZXIuY2xvc2UoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IGNvdW50IC0gMTsgaSA+IDA7IGktLSkgeworICAgICAgICAgICAgaWYgKGZpbGVzW2ldLmV4aXN0cygpKSB7CisgICAgICAgICAgICAgICAgZmlsZXNbaV0uZGVsZXRlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmaWxlc1tpIC0gMV0ucmVuYW1lVG8oZmlsZXNbaV0pOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXRwdXQgPSBuZXcgTWVhc3VyZU91dHB1dFN0cmVhbShuZXcgQnVmZmVyZWRPdXRwdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgIG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZpbGVzWzBdKSkpOworICAgICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZTEpIHsKKyAgICAgICAgICAgIHRoaXMuZ2V0RXJyb3JNYW5hZ2VyKCkuZXJyb3IoIkVycm9yIG9wZW5pbmcgbG9nIGZpbGUiLCBlMSwgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgIH0KKyAgICAgICAgc2V0T3V0cHV0U3RyZWFtKG91dHB1dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJhbnNmb3JtIHRoZSBwYXR0ZXJuIHRvIHRoZSB2YWxpZCBmaWxlIG5hbWUsIHJlcGxhY2luZyBhbnkgcGF0dGVybnMsIGFuZAorICAgICAqIGFwcGx5aW5nIGdlbmVyYXRpb24gYW5kIHVuaXF1ZUlEIGlmIHByZXNlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZ2VuCisgICAgICogICAgICAgICAgICBnZW5lcmF0aW9uIG9mIHRoaXMgZmlsZQorICAgICAqIEByZXR1cm4gdHJhbnNmb3JtZWQgZmlsZW5hbWUgcmVhZHkgZm9yIHVzZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBwYXJzZUZpbGVOYW1lKGludCBnZW4pIHsKKyAgICAgICAgaW50IGN1ciA9IDA7CisgICAgICAgIGludCBuZXh0ID0gMDsKKyAgICAgICAgYm9vbGVhbiBoYXNVbmlxdWVJRCA9IGZhbHNlOworICAgICAgICBib29sZWFuIGhhc0dlbmVyYXRpb24gPSBmYWxzZTsKKworICAgICAgICAvLyBUT0RPIHByaXZpbGVnZSBjb2RlPworCisgICAgICAgIFN0cmluZyB0ZW1wUGF0aCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKTsKKyAgICAgICAgYm9vbGVhbiB0ZW1wUGF0aEhhc1NlcEVuZCA9ICh0ZW1wUGF0aCA9PSBudWxsID8gZmFsc2UgOiB0ZW1wUGF0aAorICAgICAgICAgICAgICAgIC5lbmRzV2l0aChGaWxlLnNlcGFyYXRvcikpOworCisgICAgICAgIFN0cmluZyBob21lUGF0aCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgidXNlci5ob21lIik7CisgICAgICAgIGJvb2xlYW4gaG9tZVBhdGhIYXNTZXBFbmQgPSAoaG9tZVBhdGggPT0gbnVsbCA/IGZhbHNlIDogaG9tZVBhdGgKKyAgICAgICAgICAgICAgICAuZW5kc1dpdGgoRmlsZS5zZXBhcmF0b3IpKTsKKworICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgcGF0dGVybiA9IHBhdHRlcm4ucmVwbGFjZSgnLycsIEZpbGUuc2VwYXJhdG9yQ2hhcik7CisKKyAgICAgICAgY2hhcltdIHZhbHVlID0gcGF0dGVybi50b0NoYXJBcnJheSgpOworICAgICAgICB3aGlsZSAoKG5leHQgPSBwYXR0ZXJuLmluZGV4T2YoJyUnLCBjdXIpKSA+PSAwKSB7CisgICAgICAgICAgICBpZiAoKytuZXh0IDwgcGF0dGVybi5sZW5ndGgoKSkgeworICAgICAgICAgICAgICAgIHN3aXRjaCAodmFsdWVbbmV4dF0pIHsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAnZyc6CisgICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQodmFsdWUsIGN1ciwgbmV4dCAtIGN1ciAtIDEpLmFwcGVuZChnZW4pOworICAgICAgICAgICAgICAgICAgICAgICAgaGFzR2VuZXJhdGlvbiA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAndSc6CisgICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQodmFsdWUsIGN1ciwgbmV4dCAtIGN1ciAtIDEpLmFwcGVuZCh1bmlxdWVJRCk7CisgICAgICAgICAgICAgICAgICAgICAgICBoYXNVbmlxdWVJRCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAndCc6CisgICAgICAgICAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAgICAgICAgICogd2Ugc2hvdWxkIHByb2JhYmx5IHRyeSB0byBkbyBzb21ldGhpbmcgY3V0ZSBoZXJlIGxpa2UKKyAgICAgICAgICAgICAgICAgICAgICAgICAqIGxvb2thaGVhZCBmb3IgYWRqYWNlbnQgJy8nCisgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZCh2YWx1ZSwgY3VyLCBuZXh0IC0gY3VyIC0gMSkuYXBwZW5kKHRlbXBQYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGVtcFBhdGhIYXNTZXBFbmQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoRmlsZS5zZXBhcmF0b3IpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2gnOgorICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKHZhbHVlLCBjdXIsIG5leHQgLSBjdXIgLSAxKS5hcHBlbmQoaG9tZVBhdGgpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFob21lUGF0aEhhc1NlcEVuZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZChGaWxlLnNlcGFyYXRvcik7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAnJSc6CisgICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQodmFsdWUsIGN1ciwgbmV4dCAtIGN1ciAtIDEpLmFwcGVuZCgnJScpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQodmFsdWUsIGN1ciwgbmV4dCAtIGN1cik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGN1ciA9ICsrbmV4dDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gZmFpbCBzaWxlbnRseQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgc2IuYXBwZW5kKHZhbHVlLCBjdXIsIHZhbHVlLmxlbmd0aCAtIGN1cik7CisKKyAgICAgICAgaWYgKCFoYXNHZW5lcmF0aW9uICYmIGNvdW50ID4gMSkgeworICAgICAgICAgICAgc2IuYXBwZW5kKCIuIikuYXBwZW5kKGdlbik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWhhc1VuaXF1ZUlEICYmIHVuaXF1ZUlEID4gMCkgeworICAgICAgICAgICAgc2IuYXBwZW5kKCIuIikuYXBwZW5kKHVuaXF1ZUlEKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIC8vIGdldCBib29sZWFuIExvZ01hbmFnZXIgcHJvcGVydHksIGlmIGludmFsaWQgdmFsdWUgZ290LCB1c2luZyBkZWZhdWx0CisgICAgLy8gdmFsdWUKKyAgICBwcml2YXRlIGJvb2xlYW4gZ2V0Qm9vbGVhblByb3BlcnR5KFN0cmluZyBrZXksIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CisgICAgICAgIFN0cmluZyBwcm9wZXJ0eSA9IG1hbmFnZXIuZ2V0UHJvcGVydHkoa2V5KTsKKyAgICAgICAgaWYgKHByb3BlcnR5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7CisgICAgICAgIH0KKyAgICAgICAgYm9vbGVhbiByZXN1bHQgPSBkZWZhdWx0VmFsdWU7CisgICAgICAgIGlmICgidHJ1ZSIuZXF1YWxzSWdub3JlQ2FzZShwcm9wZXJ0eSkpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IHRydWU7CisgICAgICAgIH0gZWxzZSBpZiAoImZhbHNlIi5lcXVhbHNJZ25vcmVDYXNlKHByb3BlcnR5KSkgeworICAgICAgICAgICAgcmVzdWx0ID0gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvLyBnZXQgU3RyaW5nIExvZ01hbmFnZXIgcHJvcGVydHksIGlmIGludmFsaWQgdmFsdWUgZ290LCB1c2luZyBkZWZhdWx0IHZhbHVlCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0U3RyaW5nUHJvcGVydHkoU3RyaW5nIGtleSwgU3RyaW5nIGRlZmF1bHRWYWx1ZSkgeworICAgICAgICBTdHJpbmcgcHJvcGVydHkgPSBtYW5hZ2VyLmdldFByb3BlcnR5KGtleSk7CisgICAgICAgIHJldHVybiBwcm9wZXJ0eSA9PSBudWxsID8gZGVmYXVsdFZhbHVlIDogcHJvcGVydHk7CisgICAgfQorCisgICAgLy8gZ2V0IGludCBMb2dNYW5hZ2VyIHByb3BlcnR5LCBpZiBpbnZhbGlkIHZhbHVlIGdvdCwgdXNpbmcgZGVmYXVsdCB2YWx1ZQorICAgIHByaXZhdGUgaW50IGdldEludFByb3BlcnR5KFN0cmluZyBrZXksIGludCBkZWZhdWx0VmFsdWUpIHsKKyAgICAgICAgU3RyaW5nIHByb3BlcnR5ID0gbWFuYWdlci5nZXRQcm9wZXJ0eShrZXkpOworICAgICAgICBpbnQgcmVzdWx0ID0gZGVmYXVsdFZhbHVlOworICAgICAgICBpZiAocHJvcGVydHkgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSBJbnRlZ2VyLnBhcnNlSW50KHByb3BlcnR5KTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gaWdub3JlCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBGaWxlSGFuZGxlcn0uIFRoZSBnaXZlbiBuYW1lIHBhdHRlcm4gaXMgdXNlZCBhcworICAgICAqIG91dHB1dCBmaWxlbmFtZSwgdGhlIGZpbGUgbGltaXQgaXMgc2V0IHRvIHplcm8gKG5vIGxpbWl0KSwgdGhlIGZpbGUgY291bnQKKyAgICAgKiBpcyBzZXQgdG8gb25lOyB0aGUgcmVtYWluaW5nIGNvbmZpZ3VyYXRpb24gaXMgZG9uZSB1c2luZworICAgICAqIHtAY29kZSBMb2dNYW5hZ2VyfSBwcm9wZXJ0aWVzIG9yIHRoZWlyIGRlZmF1bHQgdmFsdWVzLiBUaGlzIGhhbmRsZXIKKyAgICAgKiB3cml0ZXMgdG8gb25seSBvbmUgZmlsZSB3aXRoIG5vIHNpemUgbGltaXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGF0dGVybgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgcGF0dGVybiBmb3IgdGhlIG91dHB1dCBmaWxlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYXR0ZXJuIGlzIGVtcHR5LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGF0dGVybiBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIEZpbGVIYW5kbGVyKFN0cmluZyBwYXR0ZXJuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAocGF0dGVybi5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlBhdHRlcm4gY2Fubm90IGJlIGVtcHR5Iik7CisgICAgICAgIH0KKyAgICAgICAgaW5pdChwYXR0ZXJuLCBudWxsLCBJbnRlZ2VyLnZhbHVlT2YoREVGQVVMVF9MSU1JVCksIEludGVnZXIudmFsdWVPZihERUZBVUxUX0NPVU5UKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgbmV3IHtAY29kZSBGaWxlSGFuZGxlcn0uIFRoZSBnaXZlbiBuYW1lIHBhdHRlcm4gaXMgdXNlZCBhcworICAgICAqIG91dHB1dCBmaWxlbmFtZSwgdGhlIGZpbGUgbGltaXQgaXMgc2V0IHRvIHplcm8gKG5vIGxpbWl0KSwgdGhlIGZpbGUgY291bnQKKyAgICAgKiBpcyBpbml0aWFsaXplZCB0byBvbmUgYW5kIHRoZSB2YWx1ZSBvZiB7QGNvZGUgYXBwZW5kfSBiZWNvbWVzIHRoZSBuZXcKKyAgICAgKiBpbnN0YW5jZSdzIGFwcGVuZCBtb2RlLiBUaGUgcmVtYWluaW5nIGNvbmZpZ3VyYXRpb24gaXMgZG9uZSB1c2luZworICAgICAqIHtAY29kZSBMb2dNYW5hZ2VyfSBwcm9wZXJ0aWVzLiBUaGlzIGhhbmRsZXIgd3JpdGVzIHRvIG9ubHkgb25lIGZpbGUKKyAgICAgKiB3aXRoIG5vIHNpemUgbGltaXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGF0dGVybgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgcGF0dGVybiBmb3IgdGhlIG91dHB1dCBmaWxlLgorICAgICAqIEBwYXJhbSBhcHBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcHBlbmQgbW9kZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcGF0dGVybn0gaXMgZW1wdHkuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBwYXR0ZXJufSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIEZpbGVIYW5kbGVyKFN0cmluZyBwYXR0ZXJuLCBib29sZWFuIGFwcGVuZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBhdHRlcm4uaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQYXR0ZXJuIGNhbm5vdCBiZSBlbXB0eSIpOworICAgICAgICB9CisgICAgICAgIGluaXQocGF0dGVybiwgQm9vbGVhbi52YWx1ZU9mKGFwcGVuZCksIEludGVnZXIudmFsdWVPZihERUZBVUxUX0xJTUlUKSwKKyAgICAgICAgICAgICAgICBJbnRlZ2VyLnZhbHVlT2YoREVGQVVMVF9DT1VOVCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIG5ldyB7QGNvZGUgRmlsZUhhbmRsZXJ9LiBUaGUgZ2l2ZW4gbmFtZSBwYXR0ZXJuIGlzIHVzZWQgYXMKKyAgICAgKiBvdXRwdXQgZmlsZW5hbWUsIHRoZSBtYXhpbXVtIGZpbGUgc2l6ZSBpcyBzZXQgdG8ge0Bjb2RlIGxpbWl0fSBhbmQgdGhlCisgICAgICogZmlsZSBjb3VudCBpcyBpbml0aWFsaXplZCB0byB7QGNvZGUgY291bnR9LiBUaGUgcmVtYWluaW5nIGNvbmZpZ3VyYXRpb24KKyAgICAgKiBpcyBkb25lIHVzaW5nIHtAY29kZSBMb2dNYW5hZ2VyfSBwcm9wZXJ0aWVzLiBUaGlzIGhhbmRsZXIgaXMgY29uZmlndXJlZAorICAgICAqIHRvIHdyaXRlIHRvIGEgcm90YXRpbmcgc2V0IG9mIGNvdW50IGZpbGVzLCB3aGVuIHRoZSBsaW1pdCBvZiBieXRlcyBoYXMKKyAgICAgKiBiZWVuIHdyaXR0ZW4gdG8gb25lIG91dHB1dCBmaWxlLCBhbm90aGVyIGZpbGUgd2lsbCBiZSBvcGVuZWQgaW5zdGVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXR0ZXJuCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBwYXR0ZXJuIGZvciB0aGUgb3V0cHV0IGZpbGUuCisgICAgICogQHBhcmFtIGxpbWl0CisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhbW91bnQgbGltaXQgaW4gYnl0ZXMgb2Ygb25lIG91dHB1dCBmaWxlLCBjYW4gbm90IGJlCisgICAgICogICAgICAgICAgICBuZWdhdGl2ZS4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBmaWxlcyB0byB1c2UsIGNhbiBub3QgYmUgbGVzcyB0aGFuIG9uZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcGF0dGVybn0gaXMgZW1wdHksIHtAY29kZSBsaW1pdCA8IDB9IG9yCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGNvdW50IDwgMX0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBwYXR0ZXJufSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIEZpbGVIYW5kbGVyKFN0cmluZyBwYXR0ZXJuLCBpbnQgbGltaXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBhdHRlcm4uaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQYXR0ZXJuIGNhbm5vdCBiZSBlbXB0eSIpOworICAgICAgICB9CisgICAgICAgIGlmIChsaW1pdCA8IDAgfHwgY291bnQgPCAxKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJsaW1pdCA8IDAgfHwgY291bnQgPCAxIik7CisgICAgICAgIH0KKyAgICAgICAgaW5pdChwYXR0ZXJuLCBudWxsLCBJbnRlZ2VyLnZhbHVlT2YobGltaXQpLCBJbnRlZ2VyLnZhbHVlT2YoY291bnQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBuZXcge0Bjb2RlIEZpbGVIYW5kbGVyfS4gVGhlIGdpdmVuIG5hbWUgcGF0dGVybiBpcyB1c2VkIGFzCisgICAgICogb3V0cHV0IGZpbGVuYW1lLCB0aGUgbWF4aW11bSBmaWxlIHNpemUgaXMgc2V0IHRvIHtAY29kZSBsaW1pdH0sIHRoZSBmaWxlCisgICAgICogY291bnQgaXMgaW5pdGlhbGl6ZWQgdG8ge0Bjb2RlIGNvdW50fSBhbmQgdGhlIGFwcGVuZCBtb2RlIGlzIHNldCB0bworICAgICAqIHtAY29kZSBhcHBlbmR9LiBUaGUgcmVtYWluaW5nIGNvbmZpZ3VyYXRpb24gaXMgZG9uZSB1c2luZworICAgICAqIHtAY29kZSBMb2dNYW5hZ2VyfSBwcm9wZXJ0aWVzLiBUaGlzIGhhbmRsZXIgaXMgY29uZmlndXJlZCB0byB3cml0ZSB0byBhCisgICAgICogcm90YXRpbmcgc2V0IG9mIGNvdW50IGZpbGVzLCB3aGVuIHRoZSBsaW1pdCBvZiBieXRlcyBoYXMgYmVlbiB3cml0dGVuIHRvCisgICAgICogb25lIG91dHB1dCBmaWxlLCBhbm90aGVyIGZpbGUgd2lsbCBiZSBvcGVuZWQgaW5zdGVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXR0ZXJuCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBwYXR0ZXJuIGZvciB0aGUgb3V0cHV0IGZpbGUuCisgICAgICogQHBhcmFtIGxpbWl0CisgICAgICogICAgICAgICAgICB0aGUgZGF0YSBhbW91bnQgbGltaXQgaW4gYnl0ZXMgb2Ygb25lIG91dHB1dCBmaWxlLCBjYW4gbm90IGJlCisgICAgICogICAgICAgICAgICBuZWdhdGl2ZS4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBmaWxlcyB0byB1c2UsIGNhbiBub3QgYmUgbGVzcyB0aGFuIG9uZS4KKyAgICAgKiBAcGFyYW0gYXBwZW5kCisgICAgICogICAgICAgICAgICB0aGUgYXBwZW5kIG1vZGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHBhdHRlcm59IGlzIGVtcHR5LCB7QGNvZGUgbGltaXQgPCAwfSBvcgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBjb3VudCA8IDF9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcGF0dGVybn0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBGaWxlSGFuZGxlcihTdHJpbmcgcGF0dGVybiwgaW50IGxpbWl0LCBpbnQgY291bnQsIGJvb2xlYW4gYXBwZW5kKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAocGF0dGVybi5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlBhdHRlcm4gY2Fubm90IGJlIGVtcHR5Iik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxpbWl0IDwgMCB8fCBjb3VudCA8IDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImxpbWl0IDwgMCB8fCBjb3VudCA8IDEiKTsKKyAgICAgICAgfQorICAgICAgICBpbml0KHBhdHRlcm4sIEJvb2xlYW4udmFsdWVPZihhcHBlbmQpLCBJbnRlZ2VyLnZhbHVlT2YobGltaXQpLCBJbnRlZ2VyLnZhbHVlT2YoY291bnQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIGFuZCBjbG9zZXMgYWxsIG9wZW5lZCBmaWxlcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICAgICAgLy8gcmVsZWFzZSBsb2NrcworICAgICAgICBzdXBlci5jbG9zZSgpOworICAgICAgICBhbGxMb2Nrcy5yZW1vdmUoZmlsZU5hbWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgRmlsZUNoYW5uZWwgY2hhbm5lbCA9IGxvY2suY2hhbm5lbCgpOworICAgICAgICAgICAgbG9jay5yZWxlYXNlKCk7CisgICAgICAgICAgICBjaGFubmVsLmNsb3NlKCk7CisgICAgICAgICAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShmaWxlTmFtZSArIExDS19FWFQpOworICAgICAgICAgICAgZmlsZS5kZWxldGUoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gaWdub3JlCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQdWJsaXNoIGEge0Bjb2RlIExvZ1JlY29yZH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVjb3JkCisgICAgICogICAgICAgICAgICB0aGUgbG9nIHJlY29yZCB0byBwdWJsaXNoLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBwdWJsaXNoKExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgc3VwZXIucHVibGlzaChyZWNvcmQpOworICAgICAgICBmbHVzaCgpOworICAgICAgICBpZiAobGltaXQgPiAwICYmIG91dHB1dC5nZXRMZW5ndGgoKSA+PSBsaW1pdCkgeworICAgICAgICAgICAgZmluZE5leHRHZW5lcmF0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG91dHB1dCBzdHJlYW0gdXNlcyB0aGUgZGVjb3JhdG9yIHBhdHRlcm4gdG8gYWRkIG1lYXN1cmVtZW50IGZlYXR1cmVzCisgICAgICogdG8gT3V0cHV0U3RyZWFtIHdoaWNoIGNhbiBkZXRlY3QgdGhlIHRvdGFsIHNpemUoaW4gYnl0ZXMpIG9mIG91dHB1dCwgdGhlCisgICAgICogaW5pdGlhbCBzaXplIGNhbiBiZSBzZXQuCisgICAgICovCisgICAgc3RhdGljIGNsYXNzIE1lYXN1cmVPdXRwdXRTdHJlYW0gZXh0ZW5kcyBPdXRwdXRTdHJlYW0geworCisgICAgICAgIE91dHB1dFN0cmVhbSB3cmFwcGVkOworCisgICAgICAgIGxvbmcgbGVuZ3RoOworCisgICAgICAgIHB1YmxpYyBNZWFzdXJlT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBzdHJlYW0sIGxvbmcgY3VycmVudExlbmd0aCkgeworICAgICAgICAgICAgd3JhcHBlZCA9IHN0cmVhbTsKKyAgICAgICAgICAgIGxlbmd0aCA9IGN1cnJlbnRMZW5ndGg7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTWVhc3VyZU91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gc3RyZWFtKSB7CisgICAgICAgICAgICB0aGlzKHN0cmVhbSwgMCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IG9uZUJ5dGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICB3cmFwcGVkLndyaXRlKG9uZUJ5dGUpOworICAgICAgICAgICAgbGVuZ3RoKys7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICB3cmFwcGVkLndyaXRlKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgICAgIGxlbmd0aCArPSBsZW47CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgd3JhcHBlZC5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHdyYXBwZWQuZmx1c2goKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBsb25nIGdldExlbmd0aCgpIHsKKyAgICAgICAgICAgIHJldHVybiBsZW5ndGg7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXRMZW5ndGgobG9uZyBuZXdMZW5ndGgpIHsKKyAgICAgICAgICAgIGxlbmd0aCA9IG5ld0xlbmd0aDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9GaWx0ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9GaWx0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMjk2ZGRiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL0ZpbHRlci5qYXZhCkBAIC0wLDAgKzEsMzUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5sb2dnaW5nOworCisvKioKKyAqIEEge0Bjb2RlIEZpbHRlcn0gcHJvdmlkZXMgYSBtZWNoYW5pc20gZm9yIGV4ZXJjaXNpbmcgZmluZS1ncmFpbmVkIGNvbnRyb2wKKyAqIG92ZXIgd2hpY2ggcmVjb3JkcyBnZXQgbG9nZ2VkLgorICovCitwdWJsaWMgaW50ZXJmYWNlIEZpbHRlciB7CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mge0Bjb2RlIHJlY29yZH0gdG8gZGV0ZXJtaW5lIGlmIGl0IHNob3VsZCBiZSBsb2dnZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVjb3JkCisgICAgICogICAgICAgICAgICB0aGUge0BsaW5rIExvZ1JlY29yZH0gdG8gYmUgY2hlY2tlZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3VwcGxpZWQgbG9nIHJlY29yZCBuZWVkcyB0byBiZSBsb2dnZWQsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBib29sZWFuIGlzTG9nZ2FibGUoTG9nUmVjb3JkIHJlY29yZCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvRm9ybWF0dGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvRm9ybWF0dGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjE4YzJlOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9Gb3JtYXR0ZXIuamF2YQpAQCAtMCwwICsxLDExNiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmxvZ2dpbmc7CisKK2ltcG9ydCBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdDsKK2ltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7CisKKy8qKgorICoge0Bjb2RlIEZvcm1hdHRlcn0gb2JqZWN0cyBhcmUgdXNlZCB0byBmb3JtYXQge0BsaW5rIExvZ1JlY29yZH0gb2JqZWN0cyBpbnRvIGEKKyAqIHN0cmluZyByZXByZXNlbnRhdGlvbi4gSGVhZCBhbmQgdGFpbCBzdHJpbmdzIGFyZSBzb21ldGltZXMgdXNlZCB0byB3cmFwIGEgc2V0CisgKiBvZiByZWNvcmRzLiBUaGUge0Bjb2RlIGdldEhlYWR9IGFuZCB7QGNvZGUgZ2V0VGFpbH0gbWV0aG9kcyBhcmUgdXNlZCBmb3IgdGhpcworICogcHVycG9zZS4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEZvcm1hdHRlciB7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIEZvcm1hdHRlcn0gb2JqZWN0LgorICAgICAqLworICAgIHByb3RlY3RlZCBGb3JtYXR0ZXIoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgYSB7QGxpbmsgTG9nUmVjb3JkfSBvYmplY3QgaW50byBhIHN0cmluZyByZXByZXNlbnRhdGlvbi4gVGhlCisgICAgICogcmVzdWx0ZWQgc3RyaW5nIGlzIHVzdWFsbHkgbG9jYWxpemVkIGFuZCBpbmNsdWRlcyB0aGUgbWVzc2FnZSBmaWVsZCBvZgorICAgICAqIHRoZSByZWNvcmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgICAgdGhlIGxvZyByZWNvcmQgdG8gYmUgZm9ybWF0dGVkIGludG8gYSBzdHJpbmcuCisgICAgICogQHJldHVybiB0aGUgZm9ybWF0dGVkIHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGZvcm1hdChMb2dSZWNvcmQgcik7CisKKyAgICAvKioKKyAgICAgKiBGb3JtYXRzIGEge0Bjb2RlIExvZ1JlY29yZH0gb2JqZWN0IGludG8gYSBsb2NhbGl6ZWQgc3RyaW5nCisgICAgICogcmVwcmVzZW50YXRpb24uIFRoaXMgaXMgYSBjb252ZW5pZW5jZSBtZXRob2QgZm9yIHN1YmNsYXNzZXMgb2Yge0Bjb2RlCisgICAgICogRm9ybWF0dGVyfS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbWVzc2FnZSBzdHJpbmcgaXMgZmlyc3RseSBsb2NhbGl6ZWQgdXNpbmcgdGhlIHtAY29kZSBSZXNvdXJjZUJ1bmRsZX0KKyAgICAgKiBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBzdXBwbGllZCB7QGNvZGUgTG9nUmVjb3JkfS4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RpY2UgOiBpZiBtZXNzYWdlIGNvbnRhaW5zICJ7MCIsIHRoZW4gamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQgaXMgdXNlZC4KKyAgICAgKiBPdGhlcndpc2Ugbm8gZm9ybWF0dGluZyBpcyBwZXJmb3JtZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgICAgdGhlIGxvZyByZWNvcmQgdG8gYmUgZm9ybWF0dGVkLgorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyByZXN1bHRlZCBmcm9tIHRoZSBmb3JtYXR0aW5nLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0TWVzc2FnZShMb2dSZWNvcmQgcikgeworICAgICAgICBTdHJpbmcgcGF0dGVybiA9IHIuZ2V0TWVzc2FnZSgpOworICAgICAgICBSZXNvdXJjZUJ1bmRsZSByYiA9IG51bGw7CisgICAgICAgIC8vIHRyeSB0byBsb2NhbGl6ZSB0aGUgbWVzc2FnZSBzdHJpbmcgZmlyc3QKKyAgICAgICAgaWYgKChyYiA9IHIuZ2V0UmVzb3VyY2VCdW5kbGUoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwYXR0ZXJuID0gcmIuZ2V0U3RyaW5nKHBhdHRlcm4pOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBwYXR0ZXJuID0gci5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBhdHRlcm4gIT0gbnVsbCkgeworICAgICAgICAgICAgT2JqZWN0W10gcGFyYW1zID0gci5nZXRQYXJhbWV0ZXJzKCk7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogaWYgdGhlIG1lc3NhZ2UgY29udGFpbnMgInswIiwgdXNlIGphdmEudGV4dC5NZXNzYWdlRm9ybWF0IHRvCisgICAgICAgICAgICAgKiBmb3JtYXQgdGhlIHN0cmluZworICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAocGF0dGVybi5pbmRleE9mKCJ7MCIpID49IDAgJiYgcGFyYW1zICE9IG51bGwgJiYgcGFyYW1zLmxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuID0gTWVzc2FnZUZvcm1hdC5mb3JtYXQocGF0dGVybiwgcGFyYW1zKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuID0gci5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBwYXR0ZXJuOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGhlYWQgc3RyaW5nIHVzZWQgdG8gd3JhcCBhIHNldCBvZiBsb2cgcmVjb3Jkcy4gVGhpcyBiYXNlIGNsYXNzCisgICAgICogYWx3YXlzIHJldHVybnMgYW4gZW1wdHkgc3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YXJnZXQgaGFuZGxlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBoZWFkIHN0cmluZyB1c2VkIHRvIHdyYXAgYSBzZXQgb2YgbG9nIHJlY29yZHMsIGVtcHR5IGluIHRoaXMKKyAgICAgKiAgICAgICAgIGltcGxlbWVudGF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0SGVhZChIYW5kbGVyIGgpIHsKKyAgICAgICAgcmV0dXJuICIiOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHRhaWwgc3RyaW5nIHVzZWQgdG8gd3JhcCBhIHNldCBvZiBsb2cgcmVjb3Jkcy4gVGhpcyBiYXNlIGNsYXNzCisgICAgICogYWx3YXlzIHJldHVybnMgdGhlIGVtcHR5IHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IGhhbmRsZXIuCisgICAgICogQHJldHVybiB0aGUgdGFpbCBzdHJpbmcgdXNlZCB0byB3cmFwIGEgc2V0IG9mIGxvZyByZWNvcmRzLCBlbXB0eSBpbiB0aGlzCisgICAgICogICAgICAgICBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFRhaWwoSGFuZGxlciBoKSB7CisgICAgICAgIHJldHVybiAiIjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvSGFuZGxlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL0hhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YTZjMTRlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL0hhbmRsZXIuamF2YQpAQCAtMCwwICsxLDM2NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmxvZ2dpbmc7CisKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OworCisvKioKKyAqIEEge0Bjb2RlIEhhbmRsZXJ9IG9iamVjdCBhY2NlcHRzIGEgbG9nZ2luZyByZXF1ZXN0IGFuZCBleHBvcnRzIHRoZSBkZXNpcmVkCisgKiBtZXNzYWdlcyB0byBhIHRhcmdldCwgZm9yIGV4YW1wbGUsIGEgZmlsZSwgdGhlIGNvbnNvbGUsIGV0Yy4gSXQgY2FuIGJlCisgKiBkaXNhYmxlZCBieSBzZXR0aW5nIGl0cyBsb2dnaW5nIGxldmVsIHRvIHtAY29kZSBMZXZlbC5PRkZ9LgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgSGFuZGxlciB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMZXZlbCBERUZBVUxUX0xFVkVMID0gTGV2ZWwuQUxMOworCisgICAgLy8gdGhlIGVycm9yIG1hbmFnZXIgdG8gcmVwb3J0IGVycm9ycyBkdXJpbmcgbG9nZ2luZworICAgIHByaXZhdGUgRXJyb3JNYW5hZ2VyIGVycm9yTWFuOworCisgICAgLy8gdGhlIGNoYXJhY3RlciBlbmNvZGluZyB1c2VkIGJ5IHRoaXMgaGFuZGxlcgorICAgIHByaXZhdGUgU3RyaW5nIGVuY29kaW5nOworCisgICAgLy8gdGhlIGxvZ2dpbmcgbGV2ZWwKKyAgICBwcml2YXRlIExldmVsIGxldmVsOworCisgICAgLy8gdGhlIGZvcm1hdHRlciB1c2VkIHRvIGV4cG9ydCBtZXNzYWdlcworICAgIHByaXZhdGUgRm9ybWF0dGVyIGZvcm1hdHRlcjsKKworICAgIC8vIHRoZSBmaWx0ZXIgdXNlZCB0byBmaWx0ZXIgdW5kZXNpcmVkIG1lc3NhZ2VzCisgICAgcHJpdmF0ZSBGaWx0ZXIgZmlsdGVyOworCisgICAgLy8gY2xhc3MgbmFtZSwgdXNlZCBmb3IgcHJvcGVydHkgcmVhZGluZworICAgIHByaXZhdGUgU3RyaW5nIHByZWZpeDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgSGFuZGxlcn0gb2JqZWN0IHdpdGggYSBkZWZhdWx0IGVycm9yIG1hbmFnZXIgaW5zdGFuY2UKKyAgICAgKiB7QGNvZGUgRXJyb3JNYW5hZ2VyfSwgdGhlIGRlZmF1bHQgZW5jb2RpbmcsIGFuZCB0aGUgZGVmYXVsdCBsb2dnaW5nCisgICAgICogbGV2ZWwge0Bjb2RlIExldmVsLkFMTH0uIEl0IGhhcyBubyBmaWx0ZXIgYW5kIG5vIGZvcm1hdHRlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSGFuZGxlcigpIHsKKyAgICAgICAgdGhpcy5lcnJvck1hbiA9IG5ldyBFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgdGhpcy5sZXZlbCA9IERFRkFVTFRfTEVWRUw7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBudWxsOworICAgICAgICB0aGlzLmZpbHRlciA9IG51bGw7CisgICAgICAgIHRoaXMuZm9ybWF0dGVyID0gbnVsbDsKKyAgICAgICAgdGhpcy5wcmVmaXggPSB0aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpOworICAgIH0KKworICAgIC8vIGdldCBhIGluc3RhbmNlIGZyb20gZ2l2ZW4gY2xhc3MgbmFtZSwgdXNpbmcgQ2xhc3MuZm9yTmFtZSgpCisgICAgcHJpdmF0ZSBPYmplY3QgZ2V0RGVmYXVsdEluc3RhbmNlKFN0cmluZyBjbGFzc05hbWUpIHsKKyAgICAgICAgT2JqZWN0IHJlc3VsdCA9IG51bGw7CisgICAgICAgIGlmIChjbGFzc05hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzdWx0ID0gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUpLm5ld0luc3RhbmNlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBpZ25vcmUKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8vIGdldCBhIGluc3RhbmNlIGZyb20gZ2l2ZW4gY2xhc3MgbmFtZSwgdXNpbmcgY29udGV4dCBjbGFzc2xvYWRlcgorICAgIHByaXZhdGUgT2JqZWN0IGdldEN1c3RvbWl6ZUluc3RhbmNlKGZpbmFsIFN0cmluZyBjbGFzc05hbWUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDbGFzc0xvYWRlciBsb2FkZXIgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpOworICAgICAgICBpZiAobG9hZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIGxvYWRlciA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCk7CisgICAgICAgIH0KKyAgICAgICAgQ2xhc3M8Pz4gYyA9IGxvYWRlci5sb2FkQ2xhc3MoY2xhc3NOYW1lKTsKKyAgICAgICAgcmV0dXJuIGMubmV3SW5zdGFuY2UoKTsKKyAgICB9CisKKyAgICAvLyBwcmludCBlcnJvciBtZXNzYWdlIGluIHNvbWUgZm9ybWF0CisgICAgdm9pZCBwcmludEludmFsaWRQcm9wTWVzc2FnZShTdHJpbmcga2V5LCBTdHJpbmcgdmFsdWUsIEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIFN0cmluZyBtc2cgPSAiSW52YWxpZCBwcm9wZXJ0eSB2YWx1ZSBmb3IgIiArIHByZWZpeCArICI6IiArIGtleSArICIvIiArIHZhbHVlOworICAgICAgICBlcnJvck1hbi5lcnJvcihtc2csIGUsIEVycm9yTWFuYWdlci5HRU5FUklDX0ZBSUxVUkUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGluaXQgdGhlIGNvbW1vbiBwcm9wZXJ0aWVzLCBpbmNsdWRpbmcgZmlsdGVyLCBsZXZlbCwgZm9ybWF0dGVyLCBhbmQKKyAgICAgKiBlbmNvZGluZworICAgICAqLworICAgIHZvaWQgaW5pdFByb3BlcnRpZXMoU3RyaW5nIGRlZmF1bHRMZXZlbCwgU3RyaW5nIGRlZmF1bHRGaWx0ZXIsCisgICAgICAgICAgICBTdHJpbmcgZGVmYXVsdEZvcm1hdHRlciwgU3RyaW5nIGRlZmF1bHRFbmNvZGluZykgeworICAgICAgICBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKworICAgICAgICAvLyBzZXQgZmlsdGVyCisgICAgICAgIGZpbmFsIFN0cmluZyBmaWx0ZXJOYW1lID0gbWFuYWdlci5nZXRQcm9wZXJ0eShwcmVmaXggKyAiLmZpbHRlciIpOworICAgICAgICBpZiAoZmlsdGVyTmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZpbHRlciA9IChGaWx0ZXIpIGdldEN1c3RvbWl6ZUluc3RhbmNlKGZpbHRlck5hbWUpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUxKSB7CisgICAgICAgICAgICAgICAgcHJpbnRJbnZhbGlkUHJvcE1lc3NhZ2UoImZpbHRlciIsIGZpbHRlck5hbWUsIGUxKTsKKyAgICAgICAgICAgICAgICBmaWx0ZXIgPSAoRmlsdGVyKSBnZXREZWZhdWx0SW5zdGFuY2UoZGVmYXVsdEZpbHRlcik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmaWx0ZXIgPSAoRmlsdGVyKSBnZXREZWZhdWx0SW5zdGFuY2UoZGVmYXVsdEZpbHRlcik7CisgICAgICAgIH0KKworICAgICAgICAvLyBzZXQgbGV2ZWwKKyAgICAgICAgU3RyaW5nIGxldmVsTmFtZSA9IG1hbmFnZXIuZ2V0UHJvcGVydHkocHJlZml4ICsgIi5sZXZlbCIpOworICAgICAgICBpZiAobGV2ZWxOYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbGV2ZWwgPSBMZXZlbC5wYXJzZShsZXZlbE5hbWUpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBwcmludEludmFsaWRQcm9wTWVzc2FnZSgibGV2ZWwiLCBsZXZlbE5hbWUsIGUpOworICAgICAgICAgICAgICAgIGxldmVsID0gTGV2ZWwucGFyc2UoZGVmYXVsdExldmVsKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGxldmVsID0gTGV2ZWwucGFyc2UoZGVmYXVsdExldmVsKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHNldCBmb3JtYXR0ZXIKKyAgICAgICAgZmluYWwgU3RyaW5nIGZvcm1hdHRlck5hbWUgPSBtYW5hZ2VyLmdldFByb3BlcnR5KHByZWZpeCArICIuZm9ybWF0dGVyIik7CisgICAgICAgIGlmIChmb3JtYXR0ZXJOYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZm9ybWF0dGVyID0gKEZvcm1hdHRlcikgZ2V0Q3VzdG9taXplSW5zdGFuY2UoZm9ybWF0dGVyTmFtZSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHByaW50SW52YWxpZFByb3BNZXNzYWdlKCJmb3JtYXR0ZXIiLCBmb3JtYXR0ZXJOYW1lLCBlKTsKKyAgICAgICAgICAgICAgICBmb3JtYXR0ZXIgPSAoRm9ybWF0dGVyKSBnZXREZWZhdWx0SW5zdGFuY2UoZGVmYXVsdEZvcm1hdHRlcik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmb3JtYXR0ZXIgPSAoRm9ybWF0dGVyKSBnZXREZWZhdWx0SW5zdGFuY2UoZGVmYXVsdEZvcm1hdHRlcik7CisgICAgICAgIH0KKworICAgICAgICAvLyBzZXQgZW5jb2RpbmcKKyAgICAgICAgZmluYWwgU3RyaW5nIGVuY29kaW5nTmFtZSA9IG1hbmFnZXIuZ2V0UHJvcGVydHkocHJlZml4ICsgIi5lbmNvZGluZyIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50ZXJuYWxTZXRFbmNvZGluZyhlbmNvZGluZ05hbWUpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHByaW50SW52YWxpZFByb3BNZXNzYWdlKCJlbmNvZGluZyIsIGVuY29kaW5nTmFtZSwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhpcyBoYW5kbGVyLiBBIGZsdXNoIG9wZXJhdGlvbiB3aWxsIGJlIHBlcmZvcm1lZCBhbmQgYWxsIHRoZQorICAgICAqIGFzc29jaWF0ZWQgcmVzb3VyY2VzIHdpbGwgYmUgZnJlZWQuIENsaWVudCBhcHBsaWNhdGlvbnMgc2hvdWxkIG5vdCB1c2UKKyAgICAgKiB0aGlzIGhhbmRsZXIgYWZ0ZXIgY2xvc2luZyBpdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBjbG9zZSgpOworCisgICAgLyoqCisgICAgICogRmx1c2hlcyBhbnkgYnVmZmVyZWQgb3V0cHV0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGZsdXNoKCk7CisKKyAgICAvKioKKyAgICAgKiBBY2NlcHRzIGEgbG9nZ2luZyByZXF1ZXN0IGFuZCBzZW5kcyBpdCB0byB0aGUgdGhlIHRhcmdldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWNvcmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2cgcmVjb3JkIHRvIGJlIGxvZ2dlZDsge0Bjb2RlIG51bGx9IHJlY29yZHMgYXJlIGlnbm9yZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcHVibGlzaChMb2dSZWNvcmQgcmVjb3JkKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNoYXJhY3RlciBlbmNvZGluZyB1c2VkIGJ5IHRoaXMgaGFuZGxlciwge0Bjb2RlIG51bGx9IGZvcgorICAgICAqIGRlZmF1bHQgZW5jb2RpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgdXNlZCBieSB0aGlzIGhhbmRsZXIuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2Rpbmc7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZXJyb3IgbWFuYWdlciB1c2VkIGJ5IHRoaXMgaGFuZGxlciB0byByZXBvcnQgZXJyb3JzIGR1cmluZworICAgICAqIGxvZ2dpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBlcnJvciBtYW5hZ2VyIHVzZWQgYnkgdGhpcyBoYW5kbGVyLgorICAgICAqLworICAgIHB1YmxpYyBFcnJvck1hbmFnZXIgZ2V0RXJyb3JNYW5hZ2VyKCkgeworICAgICAgICBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKS5jaGVja0FjY2VzcygpOworICAgICAgICByZXR1cm4gdGhpcy5lcnJvck1hbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBmaWx0ZXIgdXNlZCBieSB0aGlzIGhhbmRsZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBmaWx0ZXIgdXNlZCBieSB0aGlzIGhhbmRsZXIgKHBvc3NpYmx5IHtAY29kZSBudWxsfSkuCisgICAgICovCisgICAgcHVibGljIEZpbHRlciBnZXRGaWx0ZXIoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmZpbHRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBmb3JtYXR0ZXIgdXNlZCBieSB0aGlzIGhhbmRsZXIgdG8gZm9ybWF0IHRoZSBsb2dnaW5nIG1lc3NhZ2VzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZm9ybWF0dGVyIHVzZWQgYnkgdGhpcyBoYW5kbGVyIChwb3NzaWJseSB7QGNvZGUgbnVsbH0pLgorICAgICAqLworICAgIHB1YmxpYyBGb3JtYXR0ZXIgZ2V0Rm9ybWF0dGVyKCkgeworICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXR0ZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9nZ2luZyBsZXZlbCBvZiB0aGlzIGhhbmRsZXIsIHJlY29yZHMgd2l0aCBsZXZlbHMgbG93ZXIgdGhhbgorICAgICAqIHRoaXMgdmFsdWUgd2lsbCBiZSBkcm9wcGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbG9nZ2luZyBsZXZlbCBvZiB0aGlzIGhhbmRsZXIuCisgICAgICovCisgICAgcHVibGljIExldmVsIGdldExldmVsKCkgeworICAgICAgICByZXR1cm4gdGhpcy5sZXZlbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHN1cHBsaWVkIGxvZyByZWNvcmQgbmVlZHMgdG8gYmUgbG9nZ2VkLiBUaGUKKyAgICAgKiBsb2dnaW5nIGxldmVscyB3aWxsIGJlIGNoZWNrZWQgYXMgd2VsbCBhcyB0aGUgZmlsdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHJlY29yZAorICAgICAqICAgICAgICAgICAgdGhlIGxvZyByZWNvcmQgdG8gYmUgY2hlY2tlZC4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3VwcGxpZWQgbG9nIHJlY29yZCBuZWVkcyB0byBiZSBsb2dnZWQsCisgICAgICogICAgICAgICBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0xvZ2dhYmxlKExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgaWYgKHJlY29yZCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodGhpcy5sZXZlbC5pbnRWYWx1ZSgpID09IExldmVsLk9GRi5pbnRWYWx1ZSgpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0gZWxzZSBpZiAocmVjb3JkLmdldExldmVsKCkuaW50VmFsdWUoKSA+PSB0aGlzLmxldmVsLmludFZhbHVlKCkpIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzLmZpbHRlciA9PSBudWxsIHx8IHRoaXMuZmlsdGVyLmlzTG9nZ2FibGUocmVjb3JkKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwb3J0cyBhbiBlcnJvciB0byB0aGUgZXJyb3IgbWFuYWdlciBhc3NvY2lhdGVkIHdpdGggdGhpcyBoYW5kbGVyLAorICAgICAqIHtAY29kZSBFcnJvck1hbmFnZXJ9IGlzIHVzZWQgZm9yIHRoYXQgcHVycG9zZS4gTm8gc2VjdXJpdHkgY2hlY2tzIGFyZQorICAgICAqIGRvbmUsIHRoZXJlZm9yZSB0aGlzIGlzIGNvbXBhdGlibGUgd2l0aCBlbnZpcm9ubWVudHMgd2hlcmUgdGhlIGNhbGxlcgorICAgICAqIGlzIG5vbi1wcml2aWxlZ2VkLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIGVycm9yIG1lc3NhZ2UsIG1heSBiZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHBhcmFtIGV4CisgICAgICogICAgICAgICAgICB0aGUgYXNzb2NpYXRlZCBleGNlcHRpb24sIG1heSBiZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHBhcmFtIGNvZGUKKyAgICAgKiAgICAgICAgICAgIGFuIHtAY29kZSBFcnJvck1hbmFnZXJ9IGVycm9yIGNvZGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcmVwb3J0RXJyb3IoU3RyaW5nIG1zZywgRXhjZXB0aW9uIGV4LCBpbnQgY29kZSkgeworICAgICAgICB0aGlzLmVycm9yTWFuLmVycm9yKG1zZywgZXgsIGNvZGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNoYXJhY3RlciBlbmNvZGluZyB1c2VkIGJ5IHRoaXMgaGFuZGxlci4gQSB7QGNvZGUgbnVsbH0gdmFsdWUKKyAgICAgKiBpbmRpY2F0ZXMgdGhlIHVzZSBvZiB0aGUgZGVmYXVsdCBlbmNvZGluZy4gVGhpcyBpbnRlcm5hbCBtZXRob2QgZG9lcworICAgICAqIG5vdCBjaGVjayBzZWN1cml0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdFbmNvZGluZworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciBlbmNvZGluZyB0byBzZXQuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBlbmNvZGluZyBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBydW50aW1lLgorICAgICAqLworICAgIHZvaWQgaW50ZXJuYWxTZXRFbmNvZGluZyhTdHJpbmcgbmV3RW5jb2RpbmcpIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gYWNjZXB0cyAibnVsbCIgYmVjYXVzZSBpdCBpbmRpY2F0ZXMgdXNpbmcgZGVmYXVsdCBlbmNvZGluZworICAgICAgICBpZiAobmV3RW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhpcy5lbmNvZGluZyA9IG51bGw7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoQ2hhcnNldC5pc1N1cHBvcnRlZChuZXdFbmNvZGluZykpIHsKKyAgICAgICAgICAgICAgICB0aGlzLmVuY29kaW5nID0gbmV3RW5jb2Rpbmc7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uKG5ld0VuY29kaW5nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNoYXJhY3RlciBlbmNvZGluZyB1c2VkIGJ5IHRoaXMgaGFuZGxlciwge0Bjb2RlIG51bGx9IGluZGljYXRlcworICAgICAqIGEgZGVmYXVsdCBlbmNvZGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbmNvZGluZworICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciBlbmNvZGluZyB0byBzZXQuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBlbmNvZGluZyBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBydW50aW1lLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nKFN0cmluZyBlbmNvZGluZykgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgICAgICBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKS5jaGVja0FjY2VzcygpOworICAgICAgICBpbnRlcm5hbFNldEVuY29kaW5nKGVuY29kaW5nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBlcnJvciBtYW5hZ2VyIGZvciB0aGlzIGhhbmRsZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBlcnJvciBtYW5hZ2VyIHRvIHNldC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGVtfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RXJyb3JNYW5hZ2VyKEVycm9yTWFuYWdlciBlbSkgeworICAgICAgICBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKS5jaGVja0FjY2VzcygpOworICAgICAgICBpZiAoZW0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5lcnJvck1hbiA9IGVtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZpbHRlciB0byBiZSB1c2VkIGJ5IHRoaXMgaGFuZGxlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdGaWx0ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaWx0ZXIgdG8gc2V0LCBtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZpbHRlcihGaWx0ZXIgbmV3RmlsdGVyKSB7CisgICAgICAgIExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpLmNoZWNrQWNjZXNzKCk7CisgICAgICAgIHRoaXMuZmlsdGVyID0gbmV3RmlsdGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZvcm1hdHRlciB0byBiZSB1c2VkIGJ5IHRoaXMgaGFuZGxlci4gVGhpcyBpbnRlcm5hbCBtZXRob2QgZG9lcworICAgICAqIG5vdCBjaGVjayBzZWN1cml0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdGb3JtYXR0ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBmb3JtYXR0ZXIgdG8gc2V0LgorICAgICAqLworICAgIHZvaWQgaW50ZXJuYWxTZXRGb3JtYXR0ZXIoRm9ybWF0dGVyIG5ld0Zvcm1hdHRlcikgeworICAgICAgICBpZiAobmV3Rm9ybWF0dGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMuZm9ybWF0dGVyID0gbmV3Rm9ybWF0dGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZvcm1hdHRlciB0byBiZSB1c2VkIGJ5IHRoaXMgaGFuZGxlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdGb3JtYXR0ZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBmb3JtYXR0ZXIgdG8gc2V0LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbmV3Rm9ybWF0dGVyfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Rm9ybWF0dGVyKEZvcm1hdHRlciBuZXdGb3JtYXR0ZXIpIHsKKyAgICAgICAgTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCkuY2hlY2tBY2Nlc3MoKTsKKyAgICAgICAgaW50ZXJuYWxTZXRGb3JtYXR0ZXIobmV3Rm9ybWF0dGVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBsb2dnaW5nIGxldmVsIG9mIHRoZSBtZXNzYWdlcyBsb2dnZWQgYnkgdGhpcyBoYW5kbGVyLCBsZXZlbHMKKyAgICAgKiBsb3dlciB0aGFuIHRoaXMgdmFsdWUgd2lsbCBiZSBkcm9wcGVkLgorICAgICAqCisgICAgICogQHBhcmFtIG5ld0xldmVsCisgICAgICogICAgICAgICAgICB0aGUgbG9nZ2luZyBsZXZlbCB0byBzZXQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBuZXdMZXZlbH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExldmVsKExldmVsIG5ld0xldmVsKSB7CisgICAgICAgIGlmIChuZXdMZXZlbCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKS5jaGVja0FjY2VzcygpOworICAgICAgICB0aGlzLmxldmVsID0gbmV3TGV2ZWw7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL0xldmVsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvTGV2ZWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNGNjODJmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL0xldmVsLmphdmEKQEAgLTAsMCArMSwzNTcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5sb2dnaW5nOworCitpbXBvcnQgZGFsdmlrLnN5c3RlbS5WTVN0YWNrOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7CitpbXBvcnQgbGliY29yZS51dGlsLk9iamVjdHM7CisKKy8qKgorICoge0Bjb2RlIExldmVsfSBvYmplY3RzIGFyZSB1c2VkIHRvIGluZGljYXRlIHRoZSBsZXZlbCBvZiBsb2dnaW5nLiBUaGVyZSBhcmUgYQorICogc2V0IG9mIHByZWRlZmluZWQgbG9nZ2luZyBsZXZlbHMsIGVhY2ggYXNzb2NpYXRlZCB3aXRoIGFuIGludGVnZXIgdmFsdWUuCisgKiBFbmFibGluZyBhIGNlcnRhaW4gbG9nZ2luZyBsZXZlbCBhbHNvIGVuYWJsZXMgYWxsIGxvZ2dpbmcgbGV2ZWxzIHdpdGggbGFyZ2VyCisgKiB2YWx1ZXMuCisgKiA8cD4KKyAqIFRoZSBwcmVkZWZpbmVkIGxldmVscyBpbiBhc2NlbmRpbmcgb3JkZXIgYXJlIEZJTkVTVCwgRklORVIsIEZJTkUsIENPTkZJRywKKyAqIElORk8sIFdBUk5JTkcsIFNFVkVSRS4gVGhlcmUgYXJlIHR3byBhZGRpdGlvbmFsIHByZWRlZmluZWQgbGV2ZWxzLCB3aGljaCBhcmUKKyAqIEFMTCBhbmQgT0ZGLiBBTEwgaW5kaWNhdGVzIGxvZ2dpbmcgYWxsIG1lc3NhZ2VzLCBhbmQgT0ZGIGluZGljYXRlcyBsb2dnaW5nIG5vCisgKiBtZXNzYWdlcy4KKyAqLworcHVibGljIGNsYXNzIExldmVsIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04MTc2MTYwNzk1NzA2MzEzMDcwTDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIExpc3Q8TGV2ZWw+IGxldmVscyA9IG5ldyBBcnJheUxpc3Q8TGV2ZWw+KDkpOworCisgICAgLyoqCisgICAgICogVGhlIE9GRiBsZXZlbCBwcm92aWRlcyBubyBsb2dnaW5nIG1lc3NhZ2VzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTGV2ZWwgT0ZGID0gbmV3IExldmVsKCJPRkYiLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgU0VWRVJFIGxldmVsIHByb3ZpZGVzIHNldmVyZSBmYWlsdXJlIG1lc3NhZ2VzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTGV2ZWwgU0VWRVJFID0gbmV3IExldmVsKCJTRVZFUkUiLCAxMDAwKTsKKworICAgIC8qKgorICAgICAqIFRoZSBXQVJOSU5HIGxldmVsIHByb3ZpZGVzIHdhcm5pbmdzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTGV2ZWwgV0FSTklORyA9IG5ldyBMZXZlbCgiV0FSTklORyIsIDkwMCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgSU5GTyBsZXZlbCBwcm92aWRlcyBpbmZvcm1hdGl2ZSBtZXNzYWdlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIExldmVsIElORk8gPSBuZXcgTGV2ZWwoIklORk8iLCA4MDApOworCisgICAgLyoqCisgICAgICogVGhlIENPTkZJRyBsZXZlbCBwcm92aWRlcyBzdGF0aWMgY29uZmlndXJhdGlvbiBtZXNzYWdlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIExldmVsIENPTkZJRyA9IG5ldyBMZXZlbCgiQ09ORklHIiwgNzAwKTsKKworICAgIC8qKgorICAgICAqIFRoZSBGSU5FIGxldmVsIHByb3ZpZGVzIHRyYWNpbmcgbWVzc2FnZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBMZXZlbCBGSU5FID0gbmV3IExldmVsKCJGSU5FIiwgNTAwKTsKKworICAgIC8qKgorICAgICAqIFRoZSBGSU5FUiBsZXZlbCBwcm92aWRlcyBtb3JlIGRldGFpbGVkIHRyYWNpbmcgbWVzc2FnZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBMZXZlbCBGSU5FUiA9IG5ldyBMZXZlbCgiRklORVIiLCA0MDApOworCisgICAgLyoqCisgICAgICogVGhlIEZJTkVTVCBsZXZlbCBwcm92aWRlcyBoaWdobHkgZGV0YWlsZWQgdHJhY2luZyBtZXNzYWdlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIExldmVsIEZJTkVTVCA9IG5ldyBMZXZlbCgiRklORVNUIiwgMzAwKTsKKworICAgIC8qKgorICAgICAqIFRoZSBBTEwgbGV2ZWwgcHJvdmlkZXMgYWxsIGxvZ2dpbmcgbWVzc2FnZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBMZXZlbCBBTEwgPSBuZXcgTGV2ZWwoIkFMTCIsIEludGVnZXIuTUlOX1ZBTFVFKTsKKworICAgIC8qKgorICAgICAqIFBhcnNlcyBhIGxldmVsIG5hbWUgaW50byBhIHtAY29kZSBMZXZlbH0gb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBkZXNpcmVkIHtAY29kZSBsZXZlbH0sIHdoaWNoIGNhbm5vdCBiZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIG51bGx9LgorICAgICAqIEByZXR1cm4gdGhlIGxldmVsIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbmFtZX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG5hbWV9IGlzIG5vdCB2YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIExldmVsIHBhcnNlKFN0cmluZyBuYW1lKSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJuYW1lID09IG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gaXNOYW1lQW5JbnQ7CisgICAgICAgIGludCBuYW1lQXNJbnQ7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuYW1lQXNJbnQgPSBJbnRlZ2VyLnBhcnNlSW50KG5hbWUpOworICAgICAgICAgICAgaXNOYW1lQW5JbnQgPSB0cnVlOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgbmFtZUFzSW50ID0gMDsKKyAgICAgICAgICAgIGlzTmFtZUFuSW50ID0gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBzeW5jaHJvbml6ZWQgKGxldmVscykgeworICAgICAgICAgICAgZm9yIChMZXZlbCBsZXZlbCA6IGxldmVscykgeworICAgICAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyhsZXZlbC5nZXROYW1lKCkpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBsZXZlbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChpc05hbWVBbkludCkgeworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogTG9vcCB0aHJvdWdoIGxldmVscyBhIHNlY29uZCB0aW1lLCBzbyB0aGF0IHRoZSByZXR1cm5lZAorICAgICAgICAgICAgICAgICAqIGluc3RhbmNlIHdpbGwgYmUgcGFzc2VkIG9uIHRoZSBvcmRlciBvZiBjb25zdHJ1Y3Rpb24uCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgZm9yIChMZXZlbCBsZXZlbCA6IGxldmVscykgeworICAgICAgICAgICAgICAgICAgICBpZiAobmFtZUFzSW50ID09IGxldmVsLmludFZhbHVlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBsZXZlbDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmICghaXNOYW1lQW5JbnQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkNhbm5vdCBwYXJzZSBuYW1lICciICsgbmFtZSArICInIik7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IExldmVsKG5hbWUsIG5hbWVBc0ludCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIG5hbWUgb2YgdGhpcyBMZXZlbC4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBuYW1lOworCisgICAgLyoqCisgICAgICogVGhlIGludGVnZXIgdmFsdWUgaW5kaWNhdGluZyB0aGUgbGV2ZWwuCisgICAgICoKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcmVzb3VyY2UgYnVuZGxlIHVzZWQgdG8gbG9jYWxpemUgdGhlIGxldmVsIG5hbWUuCisgICAgICoKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcmVzb3VyY2VCdW5kbGVOYW1lOworCisgICAgLyoqCisgICAgICogVGhlIHJlc291cmNlIGJ1bmRsZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBsZXZlbCwgdXNlZCB0byBsb2NhbGl6ZSB0aGUKKyAgICAgKiBsZXZlbCBuYW1lLgorICAgICAqLworICAgIHByaXZhdGUgdHJhbnNpZW50IFJlc291cmNlQnVuZGxlIHJiOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBpbnN0YW5jZSBvZiB7QGNvZGUgTGV2ZWx9IHRha2luZyB0aGUgc3VwcGxpZWQgbmFtZSBhbmQKKyAgICAgKiBsZXZlbCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgbGV2ZWwuCisgICAgICogQHBhcmFtIGxldmVsCisgICAgICogICAgICAgICAgICBhbiBpbnRlZ2VyIHZhbHVlIGluZGljYXRpbmcgdGhlIGxldmVsLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbmFtZX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHByb3RlY3RlZCBMZXZlbChTdHJpbmcgbmFtZSwgaW50IGxldmVsKSB7CisgICAgICAgIHRoaXMobmFtZSwgbGV2ZWwsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIExldmVsfSB0YWtpbmcgdGhlIHN1cHBsaWVkIG5hbWUsIGxldmVsCisgICAgICogdmFsdWUgYW5kIHJlc291cmNlIGJ1bmRsZSBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBsZXZlbC4KKyAgICAgKiBAcGFyYW0gbGV2ZWwKKyAgICAgKiAgICAgICAgICAgIGFuIGludGVnZXIgdmFsdWUgaW5kaWNhdGluZyB0aGUgbGV2ZWwuCisgICAgICogQHBhcmFtIHJlc291cmNlQnVuZGxlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIGJ1bmRsZSB0byB1c2UuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBuYW1lfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHJvdGVjdGVkIExldmVsKFN0cmluZyBuYW1lLCBpbnQgbGV2ZWwsIFN0cmluZyByZXNvdXJjZUJ1bmRsZU5hbWUpIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJuYW1lID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgICAgICB0aGlzLnZhbHVlID0gbGV2ZWw7CisgICAgICAgIHRoaXMucmVzb3VyY2VCdW5kbGVOYW1lID0gcmVzb3VyY2VCdW5kbGVOYW1lOworICAgICAgICBpZiAocmVzb3VyY2VCdW5kbGVOYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmIgPSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUocmVzb3VyY2VCdW5kbGVOYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgTG9jYWxlLmdldERlZmF1bHQoKSwgVk1TdGFjay5nZXRDYWxsaW5nQ2xhc3NMb2FkZXIoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHJiID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzeW5jaHJvbml6ZWQgKGxldmVscykgeworICAgICAgICAgICAgbGV2ZWxzLmFkZCh0aGlzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWUgb2YgdGhpcyBsZXZlbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBsZXZlbCdzIG5hbWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gdGhpcy5uYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIGJ1bmRsZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBsZXZlbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhpcyBsZXZlbCdzIHJlc291cmNlIGJ1bmRsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFJlc291cmNlQnVuZGxlTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMucmVzb3VyY2VCdW5kbGVOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGludGVnZXIgdmFsdWUgaW5kaWNhdGluZyB0aGlzIGxldmVsLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIGxldmVsJ3MgaW50ZWdlciB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGludFZhbHVlKCkgeworICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXJpYWxpemF0aW9uIGhlbHBlciBtZXRob2QgdG8gbWFpbnRhaW4gc2luZ2xldG9ucyBhbmQgYWRkIGFueSBuZXcKKyAgICAgKiBsZXZlbHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZXNvbHZlZCBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIE9iamVjdCByZWFkUmVzb2x2ZSgpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsZXZlbHMpIHsKKyAgICAgICAgICAgIGZvciAoTGV2ZWwgbGV2ZWwgOiBsZXZlbHMpIHsKKyAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbGV2ZWwudmFsdWUpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICghbmFtZS5lcXVhbHMobGV2ZWwubmFtZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChPYmplY3RzLmVxdWFsKHJlc291cmNlQnVuZGxlTmFtZSwgbGV2ZWwucmVzb3VyY2VCdW5kbGVOYW1lKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGV2ZWw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gVGhpcyBpcyBhIG5ldyB2YWx1ZSwgc28gYWRkIGl0LgorICAgICAgICAgICAgbGV2ZWxzLmFkZCh0aGlzKTsKKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VyaWFsaXphdGlvbiBoZWxwZXIgdG8gc2V0dXAgdHJhbnNpZW50IHJlc291cmNlIGJ1bmRsZSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbgorICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IHN0cmVhbSB0byByZWFkIHRoZSBpbnN0YW5jZSBkYXRhIGZyb20uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIElPIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGNsYXNzIGlzIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIGluLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisgICAgICAgIGlmIChyZXNvdXJjZUJ1bmRsZU5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByYiA9IFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShyZXNvdXJjZUJ1bmRsZU5hbWUpOworICAgICAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICByYiA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsb2NhbGl6ZWQgbmFtZSBvZiB0aGlzIGxldmVsLiBUaGUgZGVmYXVsdCBsb2NhbGUgaXMgdXNlZC4gSWYgbm8KKyAgICAgKiByZXNvdXJjZSBidW5kbGUgaXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgbGV2ZWwgdGhlbiB0aGUgb3JpZ2luYWwgbGV2ZWwKKyAgICAgKiBuYW1lIGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbG9jYWxpemVkIG5hbWUgb2YgdGhpcyBsZXZlbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsaXplZE5hbWUoKSB7CisgICAgICAgIGlmIChyYiA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbmFtZTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gcmIuZ2V0U3RyaW5nKG5hbWUpOworICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0d28ge0Bjb2RlIExldmVsfSBvYmplY3RzIGZvciBlcXVhbGl0eS4gVGhleSBhcmUgY29uc2lkZXJlZCB0bworICAgICAqIGJlIGVxdWFsIGlmIHRoZXkgaGF2ZSB0aGUgc2FtZSBsZXZlbCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvCisgICAgICogICAgICAgICAgICB0aGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyBsZXZlbCB0by4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIG9iamVjdCBlcXVhbHMgdG8gdGhlIHN1cHBsaWVkIG9iamVjdCwKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICBpZiAodGhpcyA9PSBvKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBMZXZlbCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiAoKExldmVsKSBvKS5pbnRWYWx1ZSgpID09IHRoaXMudmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaGFzaCBjb2RlIG9mIHRoaXMge0Bjb2RlIExldmVsfSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgbGV2ZWwncyBoYXNoIGNvZGUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMge0Bjb2RlIExldmVsfSBvYmplY3QuIEluCisgICAgICogdGhpcyBjYXNlLCBpdCBpcyB0aGUgbGV2ZWwncyBuYW1lLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgbGV2ZWwuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMubmFtZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvTG9nTWFuYWdlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL0xvZ01hbmFnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NDljMjYzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL0xvZ01hbmFnZXIuamF2YQpAQCAtMCwwICsxLDUyOSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmxvZ2dpbmc7CisKK2ltcG9ydCBqYXZhLmJlYW5zLlByb3BlcnR5Q2hhbmdlTGlzdGVuZXI7CitpbXBvcnQgamF2YS5iZWFucy5Qcm9wZXJ0eUNoYW5nZVN1cHBvcnQ7CitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CitpbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKK2ltcG9ydCBsaWJjb3JlLmlvLklvVXRpbHM7CisKKy8qKgorICoge0Bjb2RlIExvZ01hbmFnZXJ9IGlzIHVzZWQgdG8gbWFpbnRhaW4gY29uZmlndXJhdGlvbiBwcm9wZXJ0aWVzIG9mIHRoZQorICogbG9nZ2luZyBmcmFtZXdvcmssIGFuZCB0byBtYW5hZ2UgYSBoaWVyYXJjaGljYWwgbmFtZXNwYWNlIG9mIGFsbCBuYW1lZAorICoge0Bjb2RlIExvZ2dlcn0gb2JqZWN0cy4KKyAqIDxwPgorICogVGhlcmUgaXMgb25seSBvbmUgZ2xvYmFsIHtAY29kZSBMb2dNYW5hZ2VyfSBpbnN0YW5jZSBpbiB0aGUKKyAqIGFwcGxpY2F0aW9uLCB3aGljaCBjYW4gYmUgZ2V0IGJ5IGNhbGxpbmcgc3RhdGljIG1ldGhvZAorICoge0BsaW5rICNnZXRMb2dNYW5hZ2VyKCl9LiBUaGlzIGluc3RhbmNlIGlzIGNyZWF0ZWQgYW5kCisgKiBpbml0aWFsaXplZCBkdXJpbmcgY2xhc3MgaW5pdGlhbGl6YXRpb24gYW5kIGNhbm5vdCBiZSBjaGFuZ2VkLgorICogPHA+CisgKiBUaGUge0Bjb2RlIExvZ01hbmFnZXJ9IGNsYXNzIGNhbiBiZSBzcGVjaWZpZWQgYnkKKyAqIGphdmEudXRpbC5sb2dnaW5nLm1hbmFnZXIgc3lzdGVtIHByb3BlcnR5LCBpZiB0aGUgcHJvcGVydHkgaXMgdW5hdmFpbGFibGUgb3IKKyAqIGludmFsaWQsIHRoZSBkZWZhdWx0IGNsYXNzIHtAbGluayBqYXZhLnV0aWwubG9nZ2luZy5Mb2dNYW5hZ2VyfSB3aWxsCisgKiBiZSB1c2VkLgorICogPHA+CisgKiBPbiBpbml0aWFsaXphdGlvbiwge0Bjb2RlIExvZ01hbmFnZXJ9IHJlYWRzIGl0cyBjb25maWd1cmF0aW9uIGZyb20gYQorICogcHJvcGVydGllcyBmaWxlLCB3aGljaCBieSBkZWZhdWx0IGlzIHRoZSAibGliL2xvZ2dpbmcucHJvcGVydGllcyIgaW4gdGhlIEpSRQorICogZGlyZWN0b3J5LgorICogPHA+CisgKiBIb3dldmVyLCB0d28gb3B0aW9uYWwgc3lzdGVtIHByb3BlcnRpZXMgY2FuIGJlIHVzZWQgdG8gY3VzdG9taXplIHRoZSBpbml0aWFsCisgKiBjb25maWd1cmF0aW9uIHByb2Nlc3Mgb2Yge0Bjb2RlIExvZ01hbmFnZXJ9LgorICogPHVsPgorICogPGxpPiJqYXZhLnV0aWwubG9nZ2luZy5jb25maWcuY2xhc3MiPC9saT4KKyAqIDxsaT4iamF2YS51dGlsLmxvZ2dpbmcuY29uZmlnLmZpbGUiPC9saT4KKyAqIDwvdWw+CisgKiA8cD4KKyAqIFRoZXNlIHR3byBwcm9wZXJ0aWVzIGNhbiBiZSBzZXQgaW4gdGhyZWUgd2F5cywgYnkgdGhlIFByZWZlcmVuY2VzIEFQSSwgYnkgdGhlCisgKiAiamF2YSIgY29tbWFuZCBsaW5lIHByb3BlcnR5IGRlZmluaXRpb25zLCBvciBieSBzeXN0ZW0gcHJvcGVydHkgZGVmaW5pdGlvbnMKKyAqIHBhc3NlZCB0byBKTklfQ3JlYXRlSmF2YVZNLgorICogPHA+CisgKiBUaGUgImphdmEudXRpbC5sb2dnaW5nLmNvbmZpZy5jbGFzcyIgc2hvdWxkIHNwZWNpZmllcyBhIGNsYXNzIG5hbWUuIElmIGl0IGlzCisgKiBzZXQsIHRoaXMgZ2l2ZW4gY2xhc3Mgd2lsbCBiZSBsb2FkZWQgYW5kIGluc3RhbnRpYXRlZCBkdXJpbmcKKyAqIHtAY29kZSBMb2dNYW5hZ2VyfSBpbml0aWFsaXphdGlvbiwgc28gdGhhdCB0aGlzIG9iamVjdCdzIGRlZmF1bHQKKyAqIGNvbnN0cnVjdG9yIGNhbiByZWFkIHRoZSBpbml0aWFsIGNvbmZpZ3VyYXRpb24gYW5kIGRlZmluZSBwcm9wZXJ0aWVzIGZvcgorICoge0Bjb2RlIExvZ01hbmFnZXJ9LgorICogPHA+CisgKiBJZiAiamF2YS51dGlsLmxvZ2dpbmcuY29uZmlnLmNsYXNzIiBwcm9wZXJ0eSBpcyBub3Qgc2V0LCBvciBpdCBpcyBpbnZhbGlkLCBvcgorICogc29tZSBleGNlcHRpb24gaXMgdGhyb3duIGR1cmluZyB0aGUgaW5zdGFudGlhdGlvbiwgdGhlbiB0aGUKKyAqICJqYXZhLnV0aWwubG9nZ2luZy5jb25maWcuZmlsZSIgc3lzdGVtIHByb3BlcnR5IGNhbiBiZSB1c2VkIHRvIHNwZWNpZnkgYQorICogcHJvcGVydGllcyBmaWxlLiBUaGUge0Bjb2RlIExvZ01hbmFnZXJ9IHdpbGwgcmVhZCBpbml0aWFsCisgKiBjb25maWd1cmF0aW9uIGZyb20gdGhpcyBmaWxlLgorICogPHA+CisgKiBJZiBuZWl0aGVyIG9mIHRoZXNlIHByb3BlcnRpZXMgaXMgZGVmaW5lZCwgb3Igc29tZSBleGNlcHRpb24gaXMgdGhyb3duCisgKiBkdXJpbmcgdGhlc2UgdHdvIHByb3BlcnRpZXMgdXNpbmcsIHRoZSB7QGNvZGUgTG9nTWFuYWdlcn0gd2lsbCByZWFkCisgKiBpdHMgaW5pdGlhbCBjb25maWd1cmF0aW9uIGZyb20gZGVmYXVsdCBwcm9wZXJ0aWVzIGZpbGUsIGFzIGRlc2NyaWJlZCBhYm92ZS4KKyAqIDxwPgorICogVGhlIGdsb2JhbCBsb2dnaW5nIHByb3BlcnRpZXMgbWF5IGluY2x1ZGU6CisgKiA8dWw+CisgKiA8bGk+ImhhbmRsZXJzIi4gVGhpcyBwcm9wZXJ0eSdzIHZhbHVlcyBzaG91bGQgYmUgYSBsaXN0IG9mIGNsYXNzIG5hbWVzIGZvcgorICogaGFuZGxlciBjbGFzc2VzIHNlcGFyYXRlZCBieSB3aGl0ZXNwYWNlLCB0aGVzZSBjbGFzc2VzIG11c3QgYmUgc3ViY2xhc3NlcyBvZgorICoge0Bjb2RlIEhhbmRsZXJ9IGFuZCBlYWNoIG11c3QgaGF2ZSBhIGRlZmF1bHQgY29uc3RydWN0b3IsIHRoZXNlCisgKiBjbGFzc2VzIHdpbGwgYmUgbG9hZGVkLCBpbnN0YW50aWF0ZWQgYW5kIHJlZ2lzdGVyZWQgYXMgaGFuZGxlcnMgb24gdGhlIHJvb3QKKyAqIHtAY29kZSBMb2dnZXJ9ICh0aGUge0Bjb2RlIExvZ2dlcn0gbmFtZWQgIiIpLiBUaGVzZQorICoge0Bjb2RlIEhhbmRsZXJ9cyBtYXliZSBpbml0aWFsaXplZCBsYXppbHkuPC9saT4KKyAqIDxsaT4iY29uZmlnIi4gVGhlIHByb3BlcnR5IGRlZmluZXMgYSBsaXN0IG9mIGNsYXNzIG5hbWVzIHNlcGFyYXRlZCBieQorICogd2hpdGVzcGFjZS4gRWFjaCBjbGFzcyBtdXN0IGhhdmUgYSBkZWZhdWx0IGNvbnN0cnVjdG9yLCBpbiB3aGljaCBpdCBjYW4KKyAqIHVwZGF0ZSB0aGUgbG9nZ2luZyBjb25maWd1cmF0aW9uLCBzdWNoIGFzIGxldmVscywgaGFuZGxlcnMsIG9yIGZpbHRlcnMgZm9yCisgKiBzb21lIGxvZ2dlciwgZXRjLiBUaGVzZSBjbGFzc2VzIHdpbGwgYmUgbG9hZGVkIGFuZCBpbnN0YW50aWF0ZWQgZHVyaW5nCisgKiB7QGNvZGUgTG9nTWFuYWdlcn0gY29uZmlndXJhdGlvbjwvbGk+CisgKiA8L3VsPgorICogPHA+CisgKiBUaGlzIGNsYXNzLCB0b2dldGhlciB3aXRoIGFueSBoYW5kbGVyIGFuZCBjb25maWd1cmF0aW9uIGNsYXNzZXMgYXNzb2NpYXRlZAorICogd2l0aCBpdCwgPGI+bXVzdDwvYj4gYmUgbG9hZGVkIGZyb20gdGhlIHN5c3RlbSBjbGFzc3BhdGggd2hlbgorICoge0Bjb2RlIExvZ01hbmFnZXJ9IGNvbmZpZ3VyYXRpb24gb2NjdXJzLgorICogPHA+CisgKiBCZXNpZGVzIGdsb2JhbCBwcm9wZXJ0aWVzLCB0aGUgcHJvcGVydGllcyBmb3IgbG9nZ2VycyBhbmQgSGFuZGxlcnMgY2FuIGJlCisgKiBzcGVjaWZpZWQgaW4gdGhlIHByb3BlcnR5IGZpbGVzLiBUaGUgbmFtZXMgb2YgdGhlc2UgcHJvcGVydGllcyB3aWxsIHN0YXJ0CisgKiB3aXRoIHRoZSBjb21wbGV0ZSBkb3Qgc2VwYXJhdGVkIG5hbWVzIGZvciB0aGUgaGFuZGxlcnMgb3IgbG9nZ2Vycy4KKyAqIDxwPgorICogSW4gdGhlIHtAY29kZSBMb2dNYW5hZ2VyfSdzIGhpZXJhcmNoaWNhbCBuYW1lc3BhY2UsCisgKiB7QGNvZGUgTG9nZ2Vyc30gYXJlIG9yZ2FuaXplZCBiYXNlZCBvbiB0aGVpciBkb3Qgc2VwYXJhdGVkIG5hbWVzLiBGb3IKKyAqIGV4YW1wbGUsICJ4LnkueiIgaXMgY2hpbGQgb2YgIngueSIuCisgKiA8cD4KKyAqIExldmVscyBmb3Ige0Bjb2RlIExvZ2dlcnN9IGNhbiBiZSBkZWZpbmVkIGJ5IHByb3BlcnRpZXMgd2hvc2UgbmFtZSBlbmQKKyAqIHdpdGggIi5sZXZlbCIuIFRodXMgImFsb2dnZXIubGV2ZWwiIGRlZmluZXMgYSBsZXZlbCBmb3IgdGhlIGxvZ2dlciBuYW1lZCBhcworICogImFsb2dnZXIiIGFuZCBmb3IgYWxsIGl0cyBjaGlsZHJlbiBpbiB0aGUgbmFtaW5nIGhpZXJhcmNoeS4gTG9nIGxldmVscworICogcHJvcGVydGllcyBhcmUgcmVhZCBhbmQgYXBwbGllZCBpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGV5IGFyZSBzcGVjaWZpZWQgaW4KKyAqIHRoZSBwcm9wZXJ0eSBmaWxlLiBUaGUgcm9vdCBsb2dnZXIncyBsZXZlbCBjYW4gYmUgZGVmaW5lZCBieSB0aGUgcHJvcGVydHkKKyAqIG5hbWVkIGFzICIubGV2ZWwiLgorICogPHA+CisgKiBUaGlzIGNsYXNzIGlzIHRocmVhZCBzYWZlLiBJdCBpcyBhbiBlcnJvciB0byBzeW5jaHJvbml6ZSBvbiBhCisgKiB7QGNvZGUgTG9nTWFuYWdlcn0gd2hpbGUgc3luY2hyb25pemVkIG9uIGEge0Bjb2RlIExvZ2dlcn0uCisgKi8KK3B1YmxpYyBjbGFzcyBMb2dNYW5hZ2VyIHsKKworICAgIC8qKiBUaGUgc2hhcmVkIGxvZ2dpbmcgcGVybWlzc2lvbi4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMb2dnaW5nUGVybWlzc2lvbiBwZXJtID0gbmV3IExvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIiwgbnVsbCk7CisKKyAgICAvKiogVGhlIHNpbmdsZXRvbiBpbnN0YW5jZS4gKi8KKyAgICBzdGF0aWMgTG9nTWFuYWdlciBtYW5hZ2VyOworCisgICAgLyoqCisgICAgICogVGhlIHtAY29kZSBTdHJpbmd9IHZhbHVlIG9mIHRoZSB7QGxpbmsgTG9nZ2luZ01YQmVhbn0ncyBPYmplY3ROYW1lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIExPR0dJTkdfTVhCRUFOX05BTUUgPSAiamF2YS51dGlsLmxvZ2dpbmc6dHlwZT1Mb2dnaW5nIjsKKworICAgIC8qKgorICAgICAqIEdldCB0aGUge0Bjb2RlIExvZ2dpbmdNWEJlYW59IGluc3RhbmNlLiB0aGlzIGltcGxlbWVudGF0aW9uIGFsd2F5cyB0aHJvd3MKKyAgICAgKiBhbiBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBMb2dnaW5nTVhCZWFufSBpbnN0YW5jZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTG9nZ2luZ01YQmVhbiBnZXRMb2dnaW5nTVhCZWFuKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvLyBGSVhNRTogdXNlIHdlYWsgcmVmZXJlbmNlIHRvIGF2b2lkIGhlYXAgbWVtb3J5IGxlYWsKKyAgICBwcml2YXRlIEhhc2h0YWJsZTxTdHJpbmcsIExvZ2dlcj4gbG9nZ2VyczsKKworICAgIC8qKiBUaGUgY29uZmlndXJhdGlvbiBwcm9wZXJ0aWVzICovCisgICAgcHJpdmF0ZSBQcm9wZXJ0aWVzIHByb3BzOworCisgICAgLyoqIHRoZSBwcm9wZXJ0eSBjaGFuZ2UgbGlzdGVuZXIgKi8KKyAgICBwcml2YXRlIFByb3BlcnR5Q2hhbmdlU3VwcG9ydCBsaXN0ZW5lcnM7CisKKyAgICBzdGF0aWMgeworICAgICAgICAvLyBpbml0IExvZ01hbmFnZXIgc2luZ2xldG9uIGluc3RhbmNlCisgICAgICAgIFN0cmluZyBjbGFzc05hbWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEudXRpbC5sb2dnaW5nLm1hbmFnZXIiKTsKKyAgICAgICAgaWYgKGNsYXNzTmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICBtYW5hZ2VyID0gKExvZ01hbmFnZXIpIGdldEluc3RhbmNlQnlDbGFzcyhjbGFzc05hbWUpOworICAgICAgICB9CisgICAgICAgIGlmIChtYW5hZ2VyID09IG51bGwpIHsKKyAgICAgICAgICAgIG1hbmFnZXIgPSBuZXcgTG9nTWFuYWdlcigpOworICAgICAgICB9CisKKyAgICAgICAgLy8gcmVhZCBjb25maWd1cmF0aW9uCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtYW5hZ2VyLnJlYWRDb25maWd1cmF0aW9uKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gaWYgZ2xvYmFsIGxvZ2dlciBoYXMgYmVlbiBpbml0aWFsaXplZCwgc2V0IHJvb3QgYXMgaXRzIHBhcmVudAorICAgICAgICBMb2dnZXIgcm9vdCA9IG5ldyBMb2dnZXIoIiIsIG51bGwpOworICAgICAgICByb290LnNldExldmVsKExldmVsLklORk8pOworICAgICAgICBMb2dnZXIuZ2xvYmFsLnNldFBhcmVudChyb290KTsKKworICAgICAgICBtYW5hZ2VyLmFkZExvZ2dlcihyb290KTsKKyAgICAgICAgbWFuYWdlci5hZGRMb2dnZXIoTG9nZ2VyLmdsb2JhbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gVGhpcyBpcyBub3QgcHVibGljIGJlY2F1c2UgdGhlcmUgc2hvdWxkIGJlIG9ubHkgb25lCisgICAgICoge0Bjb2RlIExvZ01hbmFnZXJ9IGluc3RhbmNlLCB3aGljaCBjYW4gYmUgZ2V0IGJ5CisgICAgICoge0Bjb2RlIExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpfS4gVGhpcyBpcyBwcm90ZWN0ZWQgc28gdGhhdAorICAgICAqIGFwcGxpY2F0aW9uIGNhbiBzdWJjbGFzcyB0aGUgb2JqZWN0LgorICAgICAqLworICAgIHByb3RlY3RlZCBMb2dNYW5hZ2VyKCkgeworICAgICAgICBsb2dnZXJzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIExvZ2dlcj4oKTsKKyAgICAgICAgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICBsaXN0ZW5lcnMgPSBuZXcgUHJvcGVydHlDaGFuZ2VTdXBwb3J0KHRoaXMpOworICAgICAgICAvLyBhZGQgc2h1dGRvd24gaG9vayB0byBlbnN1cmUgdGhhdCB0aGUgYXNzb2NpYXRlZCByZXNvdXJjZSB3aWxsIGJlCisgICAgICAgIC8vIGZyZWVkIHdoZW4gSlZNIGV4aXRzCisgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmFkZFNodXRkb3duSG9vayhuZXcgVGhyZWFkKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICByZXNldCgpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb2VzIG5vdGhpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2hlY2tBY2Nlc3MoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkIGEgZ2l2ZW4gbG9nZ2VyIGludG8gdGhlIGhpZXJhcmNoaWNhbCBuYW1lc3BhY2UuIFRoZQorICAgICAqIHtAY29kZSBMb2dnZXIuYWRkTG9nZ2VyKCl9IGZhY3RvcnkgbWV0aG9kcyBjYWxsIHRoaXMgbWV0aG9kIHRvIGFkZCBuZXdseQorICAgICAqIGNyZWF0ZWQgTG9nZ2VyLiBUaGlzIHJldHVybnMgZmFsc2UgaWYgYSBsb2dnZXIgd2l0aCB0aGUgZ2l2ZW4gbmFtZSBoYXMKKyAgICAgKiBleGlzdGVkIGluIHRoZSBuYW1lc3BhY2UKKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlIHRoYXQgdGhlIHtAY29kZSBMb2dNYW5hZ2VyfSBtYXkgb25seSByZXRhaW4gd2VhayByZWZlcmVuY2VzIHRvCisgICAgICogcmVnaXN0ZXJlZCBsb2dnZXJzLiBJbiBvcmRlciB0byBwcmV2ZW50IHtAY29kZSBMb2dnZXJ9IG9iamVjdHMgZnJvbSBiZWluZworICAgICAqIHVuZXhwZWN0ZWRseSBnYXJiYWdlIGNvbGxlY3RlZCBpdCBpcyBuZWNlc3NhcnkgZm9yIDxpPmFwcGxpY2F0aW9uczwvaT4KKyAgICAgKiB0byBtYWludGFpbiByZWZlcmVuY2VzIHRvIHRoZW0uCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGxvZ2dlcgorICAgICAqICAgICAgICAgICAgdGhlIGxvZ2dlciB0byBiZSBhZGRlZC4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIGxvZ2dlciBpcyBhZGRlZCBpbnRvIHRoZSBuYW1lc3BhY2UKKyAgICAgKiAgICAgICAgIHN1Y2Nlc3NmdWxseSwgZmFsc2UgaWYgdGhlIGdpdmVuIGxvZ2dlciBleGlzdHMgaW4gdGhlIG5hbWVzcGFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gYWRkTG9nZ2VyKExvZ2dlciBsb2dnZXIpIHsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBsb2dnZXIuZ2V0TmFtZSgpOworICAgICAgICBpZiAobG9nZ2Vycy5nZXQobmFtZSkgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGFkZFRvRmFtaWx5VHJlZShsb2dnZXIsIG5hbWUpOworICAgICAgICBsb2dnZXJzLnB1dChuYW1lLCBsb2dnZXIpOworICAgICAgICBsb2dnZXIuc2V0TWFuYWdlcih0aGlzKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFkZFRvRmFtaWx5VHJlZShMb2dnZXIgbG9nZ2VyLCBTdHJpbmcgbmFtZSkgeworICAgICAgICBMb2dnZXIgcGFyZW50ID0gbnVsbDsKKyAgICAgICAgLy8gZmluZCBwYXJlbnQKKyAgICAgICAgaW50IGxhc3RTZXBhcmF0b3I7CisgICAgICAgIFN0cmluZyBwYXJlbnROYW1lID0gbmFtZTsKKyAgICAgICAgd2hpbGUgKChsYXN0U2VwYXJhdG9yID0gcGFyZW50TmFtZS5sYXN0SW5kZXhPZignLicpKSAhPSAtMSkgeworICAgICAgICAgICAgcGFyZW50TmFtZSA9IHBhcmVudE5hbWUuc3Vic3RyaW5nKDAsIGxhc3RTZXBhcmF0b3IpOworICAgICAgICAgICAgcGFyZW50ID0gbG9nZ2Vycy5nZXQocGFyZW50TmFtZSk7CisgICAgICAgICAgICBpZiAocGFyZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXRQYXJlbnQobG9nZ2VyLCBwYXJlbnQpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfSBlbHNlIGlmIChnZXRQcm9wZXJ0eShwYXJlbnROYW1lICsgIi5sZXZlbCIpICE9IG51bGwgfHwKKyAgICAgICAgICAgICAgICAgICAgZ2V0UHJvcGVydHkocGFyZW50TmFtZSArICIuaGFuZGxlcnMiKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcGFyZW50ID0gTG9nZ2VyLmdldExvZ2dlcihwYXJlbnROYW1lKTsKKyAgICAgICAgICAgICAgICBzZXRQYXJlbnQobG9nZ2VyLCBwYXJlbnQpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChwYXJlbnQgPT0gbnVsbCAmJiAocGFyZW50ID0gbG9nZ2Vycy5nZXQoIiIpKSAhPSBudWxsKSB7CisgICAgICAgICAgICBzZXRQYXJlbnQobG9nZ2VyLCBwYXJlbnQpOworICAgICAgICB9CisKKyAgICAgICAgLy8gZmluZCBjaGlsZHJlbgorICAgICAgICAvLyBUT0RPOiBwZXJmb3JtYW5jZSBjYW4gYmUgaW1wcm92ZWQgaGVyZT8KKyAgICAgICAgU3RyaW5nIG5hbWVEb3QgPSBuYW1lICsgJy4nOworICAgICAgICBDb2xsZWN0aW9uPExvZ2dlcj4gYWxsTG9nZ2VycyA9IGxvZ2dlcnMudmFsdWVzKCk7CisgICAgICAgIGZvciAoZmluYWwgTG9nZ2VyIGNoaWxkIDogYWxsTG9nZ2VycykgeworICAgICAgICAgICAgTG9nZ2VyIG9sZFBhcmVudCA9IGNoaWxkLmdldFBhcmVudCgpOworICAgICAgICAgICAgaWYgKHBhcmVudCA9PSBvbGRQYXJlbnQgJiYgKG5hbWUubGVuZ3RoKCkgPT0gMCB8fCBjaGlsZC5nZXROYW1lKCkuc3RhcnRzV2l0aChuYW1lRG90KSkpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBMb2dnZXIgdGhpc0xvZ2dlciA9IGxvZ2dlcjsKKyAgICAgICAgICAgICAgICBjaGlsZC5zZXRQYXJlbnQodGhpc0xvZ2dlcik7CisgICAgICAgICAgICAgICAgaWYgKG9sZFBhcmVudCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIC0tIHJlbW92ZSBmcm9tIG9sZCBwYXJlbnQgYXMgdGhlIHBhcmVudCBoYXMgYmVlbiBjaGFuZ2VkCisgICAgICAgICAgICAgICAgICAgIG9sZFBhcmVudC5jaGlsZHJlbi5yZW1vdmUoY2hpbGQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbG9nZ2VyIHdpdGggdGhlIGdpdmVuIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgbmFtZSBvZiBsb2dnZXIKKyAgICAgKiBAcmV0dXJuIGxvZ2dlciB3aXRoIGdpdmVuIG5hbWUsIG9yIHtAY29kZSBudWxsfSBpZiBub3RoaW5nIGlzIGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgTG9nZ2VyIGdldExvZ2dlcihTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gbG9nZ2Vycy5nZXQobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGEge0Bjb2RlIEVudW1lcmF0aW9ufSBvZiBhbGwgcmVnaXN0ZXJlZCBsb2dnZXIgbmFtZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGVudW1lcmF0aW9uIG9mIHJlZ2lzdGVyZWQgbG9nZ2VyIG5hbWVzCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBFbnVtZXJhdGlvbjxTdHJpbmc+IGdldExvZ2dlck5hbWVzKCkgeworICAgICAgICByZXR1cm4gbG9nZ2Vycy5rZXlzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBnbG9iYWwge0Bjb2RlIExvZ01hbmFnZXJ9IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZ2xvYmFsIHtAY29kZSBMb2dNYW5hZ2VyfSBpbnN0YW5jZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTG9nTWFuYWdlciBnZXRMb2dNYW5hZ2VyKCkgeworICAgICAgICByZXR1cm4gbWFuYWdlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHZhbHVlIG9mIHByb3BlcnR5IHdpdGggZ2l2ZW4gbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiBwcm9wZXJ0eQorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHByb3BlcnR5CisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gcHJvcHMuZ2V0UHJvcGVydHkobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmUtaW5pdGlhbGl6ZSB0aGUgcHJvcGVydGllcyBhbmQgY29uZmlndXJhdGlvbi4gVGhlIGluaXRpYWxpemF0aW9uCisgICAgICogcHJvY2VzcyBpcyBzYW1lIGFzIHRoZSB7QGNvZGUgTG9nTWFuYWdlcn0gaW5zdGFudGlhdGlvbi4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RpY2UgOiBObyB7QGNvZGUgUHJvcGVydHlDaGFuZ2VFdmVudH0gYXJlIGZpcmVkLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbnkgSU8gcmVsYXRlZCBwcm9ibGVtcyBoYXBwZW5lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZWFkQ29uZmlndXJhdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIGNoZWNrIGNvbmZpZyBjbGFzcworICAgICAgICBTdHJpbmcgY29uZmlnQ2xhc3NOYW1lID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLnV0aWwubG9nZ2luZy5jb25maWcuY2xhc3MiKTsKKyAgICAgICAgaWYgKGNvbmZpZ0NsYXNzTmFtZSA9PSBudWxsIHx8IGdldEluc3RhbmNlQnlDbGFzcyhjb25maWdDbGFzc05hbWUpID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGlmIGNvbmZpZyBjbGFzcyBmYWlsZWQsIGNoZWNrIGNvbmZpZyBmaWxlCisgICAgICAgICAgICBTdHJpbmcgY29uZmlnRmlsZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS51dGlsLmxvZ2dpbmcuY29uZmlnLmZpbGUiKTsKKworICAgICAgICAgICAgaWYgKGNvbmZpZ0ZpbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIGlmIGNhbm5vdCBmaW5kIGNvbmZpZ0ZpbGUsIHVzZSBkZWZhdWx0IGxvZ2dpbmcucHJvcGVydGllcworICAgICAgICAgICAgICAgIGNvbmZpZ0ZpbGUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaG9tZSIpICsgRmlsZS5zZXBhcmF0b3IgKyAibGliIiArCisgICAgICAgICAgICAgICAgICAgICAgICBGaWxlLnNlcGFyYXRvciArICJsb2dnaW5nLnByb3BlcnRpZXMiOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBJbnB1dFN0cmVhbSBpbnB1dCA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGlucHV0ID0gbmV3IEZpbGVJbnB1dFN0cmVhbShjb25maWdGaWxlKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gZmFsbCBiYWNrIHRvIHVzaW5nIHRoZSBidWlsdC1pbiBsb2dnaW5nLnByb3BlcnRpZXMgZmlsZQorICAgICAgICAgICAgICAgICAgICBpbnB1dCA9IExvZ01hbmFnZXIuY2xhc3MuZ2V0UmVzb3VyY2VBc1N0cmVhbSgibG9nZ2luZy5wcm9wZXJ0aWVzIik7CisgICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBleGNlcHRpb247CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmVhZENvbmZpZ3VyYXRpb24obmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oaW5wdXQpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkoaW5wdXQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gdXNlIFN5c3RlbUNsYXNzTG9hZGVyIHRvIGxvYWQgY2xhc3MgZnJvbSBzeXN0ZW0gY2xhc3NwYXRoCisgICAgc3RhdGljIE9iamVjdCBnZXRJbnN0YW5jZUJ5Q2xhc3MoZmluYWwgU3RyaW5nIGNsYXNzTmFtZSkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3M8Pz4gY2xhenogPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpLmxvYWRDbGFzcyhjbGFzc05hbWUpOworICAgICAgICAgICAgcmV0dXJuIGNsYXp6Lm5ld0luc3RhbmNlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENsYXNzPD8+IGNsYXp6ID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoY2xhc3NOYW1lKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gY2xhenoubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBpbm5lckUpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkxvYWRpbmcgY2xhc3MgJyIgKyBjbGFzc05hbWUgKyAiJyBmYWlsZWQiKTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oaW5uZXJFKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIGFjdHVhbCBpbml0aWFsaXphdGlvbiBwcm9jZXNzIGZyb20gYSBnaXZlbiBpbnB1dCBzdHJlYW0KKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIHJlYWRDb25maWd1cmF0aW9uSW1wbChJbnB1dFN0cmVhbSBpbnMpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXNldCgpOworICAgICAgICBwcm9wcy5sb2FkKGlucyk7CisKKyAgICAgICAgLy8gVGhlIFJJIHRyZWF0cyB0aGUgcm9vdCBsb2dnZXIgYXMgc3BlY2lhbC4gRm9yIGNvbXBhdGliaWxpdHksIGFsd2F5cworICAgICAgICAvLyB1cGRhdGUgdGhlIHJvb3QgbG9nZ2VyJ3MgaGFuZGxlcnMuCisgICAgICAgIExvZ2dlciByb290ID0gbG9nZ2Vycy5nZXQoIiIpOworICAgICAgICBpZiAocm9vdCAhPSBudWxsKSB7CisgICAgICAgICAgICByb290LnNldE1hbmFnZXIodGhpcyk7CisgICAgICAgIH0KKworICAgICAgICAvLyBwYXJzZSBwcm9wZXJ0eSAiY29uZmlnIiBhbmQgYXBwbHkgc2V0dGluZworICAgICAgICBTdHJpbmcgY29uZmlncyA9IHByb3BzLmdldFByb3BlcnR5KCJjb25maWciKTsKKyAgICAgICAgaWYgKGNvbmZpZ3MgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihjb25maWdzLCAiICIpOworICAgICAgICAgICAgd2hpbGUgKHN0Lmhhc01vcmVUb2tlbnMoKSkgeworICAgICAgICAgICAgICAgIFN0cmluZyBjb25maWdlck5hbWUgPSBzdC5uZXh0VG9rZW4oKTsKKyAgICAgICAgICAgICAgICBnZXRJbnN0YW5jZUJ5Q2xhc3MoY29uZmlnZXJOYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHNldCBsZXZlbHMgZm9yIGxvZ2dlcgorICAgICAgICBDb2xsZWN0aW9uPExvZ2dlcj4gYWxsTG9nZ2VycyA9IGxvZ2dlcnMudmFsdWVzKCk7CisgICAgICAgIGZvciAoTG9nZ2VyIGxvZ2dlciA6IGFsbExvZ2dlcnMpIHsKKyAgICAgICAgICAgIFN0cmluZyBwcm9wZXJ0eSA9IHByb3BzLmdldFByb3BlcnR5KGxvZ2dlci5nZXROYW1lKCkgKyAiLmxldmVsIik7CisgICAgICAgICAgICBpZiAocHJvcGVydHkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGxvZ2dlci5zZXRMZXZlbChMZXZlbC5wYXJzZShwcm9wZXJ0eSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGxpc3RlbmVycy5maXJlUHJvcGVydHlDaGFuZ2UobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmUtaW5pdGlhbGl6ZSB0aGUgcHJvcGVydGllcyBhbmQgY29uZmlndXJhdGlvbiBmcm9tIHRoZSBnaXZlbgorICAgICAqIHtAY29kZSBJbnB1dFN0cmVhbX0KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RpY2UgOiBObyB7QGNvZGUgUHJvcGVydHlDaGFuZ2VFdmVudH0gYXJlIGZpcmVkLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBzdHJlYW0KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW55IElPIHJlbGF0ZWQgcHJvYmxlbXMgaGFwcGVuZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVhZENvbmZpZ3VyYXRpb24oSW5wdXRTdHJlYW0gaW5zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja0FjY2VzcygpOworICAgICAgICByZWFkQ29uZmlndXJhdGlvbkltcGwoaW5zKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldCBjb25maWd1cmF0aW9uLgorICAgICAqCisgICAgICogPHA+QWxsIGhhbmRsZXJzIGFyZSBjbG9zZWQgYW5kIHJlbW92ZWQgZnJvbSBhbnkgbmFtZWQgbG9nZ2Vycy4gQWxsIGxvZ2dlcnMnCisgICAgICogbGV2ZWwgaXMgc2V0IHRvIG51bGwsIGV4Y2VwdCB0aGUgcm9vdCBsb2dnZXIncyBsZXZlbCBpcyBzZXQgdG8KKyAgICAgKiB7QGNvZGUgTGV2ZWwuSU5GT30uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHJlc2V0KCkgeworICAgICAgICBjaGVja0FjY2VzcygpOworICAgICAgICBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgIEVudW1lcmF0aW9uPFN0cmluZz4gbmFtZXMgPSBnZXRMb2dnZXJOYW1lcygpOworICAgICAgICB3aGlsZSAobmFtZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIFN0cmluZyBuYW1lID0gbmFtZXMubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIExvZ2dlciBsb2dnZXIgPSBnZXRMb2dnZXIobmFtZSk7CisgICAgICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBsb2dnZXIucmVzZXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBMb2dnZXIgcm9vdCA9IGxvZ2dlcnMuZ2V0KCIiKTsKKyAgICAgICAgaWYgKHJvb3QgIT0gbnVsbCkgeworICAgICAgICAgICAgcm9vdC5zZXRMZXZlbChMZXZlbC5JTkZPKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCBhIHtAY29kZSBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyfSwgd2hpY2ggd2lsbCBiZSBpbnZva2VkIHdoZW4KKyAgICAgKiB0aGUgcHJvcGVydGllcyBhcmUgcmVyZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIGwKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcn0gdG8gYmUgYWRkZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIGwpIHsKKyAgICAgICAgaWYgKGwgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tBY2Nlc3MoKTsKKyAgICAgICAgbGlzdGVuZXJzLmFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIobCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlIGEge0Bjb2RlIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJ9LCBkbyBub3RoaW5nIGlmIHRoZSBnaXZlbgorICAgICAqIGxpc3RlbmVyIGlzIG5vdCBmb3VuZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJ9IHRvIGJlIHJlbW92ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIGwpIHsKKyAgICAgICAgY2hlY2tBY2Nlc3MoKTsKKyAgICAgICAgbGlzdGVuZXJzLnJlbW92ZVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIobCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5hbWVkIGxvZ2dlciBhc3NvY2lhdGVkIHdpdGggdGhlIHN1cHBsaWVkIHJlc291cmNlIGJ1bmRsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZXNvdXJjZUJ1bmRsZU5hbWUgdGhlIHJlc291cmNlIGJ1bmRsZSB0byBhc3NvY2lhdGUsIG9yIG51bGwgZm9yCisgICAgICogICAgICBubyBhc3NvY2lhdGVkIHJlc291cmNlIGJ1bmRsZS4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgTG9nZ2VyIGdldE9yQ3JlYXRlKFN0cmluZyBuYW1lLCBTdHJpbmcgcmVzb3VyY2VCdW5kbGVOYW1lKSB7CisgICAgICAgIExvZ2dlciByZXN1bHQgPSBnZXRMb2dnZXIobmFtZSk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0ID0gbmV3IExvZ2dlcihuYW1lLCByZXNvdXJjZUJ1bmRsZU5hbWUpOworICAgICAgICAgICAgYWRkTG9nZ2VyKHJlc3VsdCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHBhcmVudCBvZiB0aGlzIGxvZ2dlciBpbiB0aGUgbmFtZXNwYWNlLiBDYWxsZXJzIG11c3QgZmlyc3QKKyAgICAgKiB7QGxpbmsgI2NoZWNrQWNjZXNzKCkgY2hlY2sgc2VjdXJpdHl9LgorICAgICAqCisgICAgICogQHBhcmFtIG5ld1BhcmVudAorICAgICAqICAgICAgICAgICAgdGhlIHBhcmVudCBsb2dnZXIgdG8gc2V0LgorICAgICAqLworICAgIHN5bmNocm9uaXplZCB2b2lkIHNldFBhcmVudChMb2dnZXIgbG9nZ2VyLCBMb2dnZXIgbmV3UGFyZW50KSB7CisgICAgICAgIGxvZ2dlci5wYXJlbnQgPSBuZXdQYXJlbnQ7CisKKyAgICAgICAgaWYgKGxvZ2dlci5sZXZlbE9ialZhbCA9PSBudWxsKSB7CisgICAgICAgICAgICBzZXRMZXZlbFJlY3Vyc2l2ZWx5KGxvZ2dlciwgbnVsbCk7CisgICAgICAgIH0KKyAgICAgICAgbmV3UGFyZW50LmNoaWxkcmVuLmFkZChsb2dnZXIpOworICAgICAgICBsb2dnZXIudXBkYXRlRGFsdmlrTG9nSGFuZGxlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGxldmVsIG9uIHtAY29kZSBsb2dnZXJ9IHRvIHtAY29kZSBuZXdMZXZlbH0uIEFueSBjaGlsZCBsb2dnZXJzCisgICAgICogY3VycmVudGx5IGluaGVyaXRpbmcgdGhlaXIgbGV2ZWwgZnJvbSB7QGNvZGUgbG9nZ2VyfSB3aWxsIGJlIHVwZGF0ZWQKKyAgICAgKiByZWN1cnNpdmVseS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdMZXZlbCB0aGUgbmV3IG1pbmltdW0gbG9nZ2luZyB0aHJlc2hvbGQuIElmIG51bGwsIHRoZSBsb2dnZXIncworICAgICAqICAgICAgcGFyZW50IGxldmVsIHdpbGwgYmUgdXNlZDsgb3Ige0Bjb2RlIExldmVsLklORk99IGZvciBsb2dnZXJzIHdpdGggbm8KKyAgICAgKiAgICAgIHBhcmVudC4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgdm9pZCBzZXRMZXZlbFJlY3Vyc2l2ZWx5KExvZ2dlciBsb2dnZXIsIExldmVsIG5ld0xldmVsKSB7CisgICAgICAgIGludCBwcmV2aW91cyA9IGxvZ2dlci5sZXZlbEludFZhbDsKKyAgICAgICAgbG9nZ2VyLmxldmVsT2JqVmFsID0gbmV3TGV2ZWw7CisKKyAgICAgICAgaWYgKG5ld0xldmVsID09IG51bGwpIHsKKyAgICAgICAgICAgIGxvZ2dlci5sZXZlbEludFZhbCA9IGxvZ2dlci5wYXJlbnQgIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICA/IGxvZ2dlci5wYXJlbnQubGV2ZWxJbnRWYWwKKyAgICAgICAgICAgICAgICAgICAgOiBMZXZlbC5JTkZPLmludFZhbHVlKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBsb2dnZXIubGV2ZWxJbnRWYWwgPSBuZXdMZXZlbC5pbnRWYWx1ZSgpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHByZXZpb3VzICE9IGxvZ2dlci5sZXZlbEludFZhbCkgeworICAgICAgICAgICAgZm9yIChMb2dnZXIgY2hpbGQgOiBsb2dnZXIuY2hpbGRyZW4pIHsKKyAgICAgICAgICAgICAgICBpZiAoY2hpbGQubGV2ZWxPYmpWYWwgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBzZXRMZXZlbFJlY3Vyc2l2ZWx5KGNoaWxkLCBudWxsKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvTG9nUmVjb3JkLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvTG9nUmVjb3JkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTk0NGYyMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9Mb2dSZWNvcmQuamF2YQpAQCAtMCwwICsxLDUwNSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmxvZ2dpbmc7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7CisKKy8qKgorICogQSB7QGNvZGUgTG9nUmVjb3JkfSBvYmplY3QgcmVwcmVzZW50cyBhIGxvZ2dpbmcgcmVxdWVzdC4gSXQgaXMgcGFzc2VkIGJldHdlZW4KKyAqIHRoZSBsb2dnaW5nIGZyYW1ld29yayBhbmQgaW5kaXZpZHVhbCBsb2dnaW5nIGhhbmRsZXJzLiBDbGllbnQgYXBwbGljYXRpb25zCisgKiBzaG91bGQgbm90IG1vZGlmeSBhIHtAY29kZSBMb2dSZWNvcmR9IG9iamVjdCB0aGF0IGhhcyBiZWVuIHBhc3NlZCBpbnRvIHRoZQorICogbG9nZ2luZyBmcmFtZXdvcmsuCisgKiA8cD4KKyAqIFRoZSB7QGNvZGUgTG9nUmVjb3JkfSBjbGFzcyB3aWxsIGluZmVyIHRoZSBzb3VyY2UgbWV0aG9kIG5hbWUgYW5kIHNvdXJjZQorICogY2xhc3MgbmFtZSB0aGUgZmlyc3QgdGltZSB0aGV5IGFyZSBhY2Nlc3NlZCBpZiB0aGUgY2xpZW50IGFwcGxpY2F0aW9uIGRpZG4ndAorICogc3BlY2lmeSB0aGVtIGV4cGxpY2l0bHkuIFRoaXMgYXV0b21hdGljIGluZmVyZW5jZSBpcyBiYXNlZCBvbiB0aGUgYW5hbHlzaXMgb2YKKyAqIHRoZSBjYWxsIHN0YWNrIGFuZCBpcyBub3QgZ3VhcmFudGVlZCB0byBiZSBwcmVjaXNlLiBDbGllbnQgYXBwbGljYXRpb25zCisgKiBzaG91bGQgZm9yY2UgdGhlIGluaXRpYWxpemF0aW9uIG9mIHRoZXNlIHR3byBmaWVsZHMgYnkgY2FsbGluZworICoge0Bjb2RlIGdldFNvdXJjZUNsYXNzTmFtZX0gb3Ige0Bjb2RlIGdldFNvdXJjZU1ldGhvZE5hbWV9IGlmIHRoZXkgZXhwZWN0IHRvCisgKiB1c2UgdGhlbSBhZnRlciBwYXNzaW5nIHRoZSB7QGNvZGUgTG9nUmVjb3JkfSBvYmplY3QgdG8gYW5vdGhlciB0aHJlYWQgb3IKKyAqIHRyYW5zbWl0dGluZyBpdCBvdmVyIFJNSS4KKyAqLworcHVibGljIGNsYXNzIExvZ1JlY29yZCBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1MzcyMDQ4MDUzMTM0NTEyNTM0TDsKKworICAgIC8vIFRoZSBtYWpvciBieXRlIHVzZWQgaW4gc2VyaWFsaXphdGlvbi4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFKT1IgPSAxOworCisgICAgLy8gVGhlIG1pbm9yIGJ5dGUgdXNlZCBpbiBzZXJpYWxpemF0aW9uLgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNSU5PUiA9IDQ7CisKKyAgICAvLyBTdG9yZSB0aGUgY3VycmVudCB2YWx1ZSBmb3IgdGhlIHNlcXVlbmNlIG51bWJlci4KKyAgICBwcml2YXRlIHN0YXRpYyBsb25nIGN1cnJlbnRTZXF1ZW5jZU51bWJlciA9IDA7CisKKyAgICAvLyBTdG9yZSB0aGUgaWQgZm9yIGVhY2ggdGhyZWFkLgorICAgIHByaXZhdGUgc3RhdGljIFRocmVhZExvY2FsPEludGVnZXI+IGN1cnJlbnRUaHJlYWRJZCA9IG5ldyBUaHJlYWRMb2NhbDxJbnRlZ2VyPigpOworCisgICAgLy8gVGhlIGJhc2UgaWQgYXMgdGhlIHN0YXJ0aW5nIHBvaW50IGZvciB0aHJlYWQgSUQgYWxsb2NhdGlvbi4KKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgaW5pdFRocmVhZElkID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBsb2dnaW5nIGxldmVsLgorICAgICAqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByaXZhdGUgTGV2ZWwgbGV2ZWw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc2VxdWVuY2UgbnVtYmVyLgorICAgICAqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByaXZhdGUgbG9uZyBzZXF1ZW5jZU51bWJlcjsKKworICAgIC8qKgorICAgICAqIFRoZSBuYW1lIG9mIHRoZSBjbGFzcyB0aGF0IGlzc3VlZCB0aGUgbG9nZ2luZyBjYWxsLgorICAgICAqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHNvdXJjZUNsYXNzTmFtZTsKKworICAgIC8qKgorICAgICAqIFRoZSBuYW1lIG9mIHRoZSBtZXRob2QgdGhhdCBpc3N1ZWQgdGhlIGxvZ2dpbmcgY2FsbC4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBzb3VyY2VNZXRob2ROYW1lOworCisgICAgLyoqCisgICAgICogVGhlIG9yaWdpbmFsIG1lc3NhZ2UgdGV4dC4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBtZXNzYWdlOworCisgICAgLyoqCisgICAgICogVGhlIElEIG9mIHRoZSB0aHJlYWQgdGhhdCBpc3N1ZWQgdGhlIGxvZ2dpbmcgY2FsbC4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIGludCB0aHJlYWRJRDsKKworICAgIC8qKgorICAgICAqIFRoZSB0aW1lIHRoYXQgdGhlIGV2ZW50IG9jY3VycmVkLCBpbiBtaWxsaXNlY29uZHMgc2luY2UgMTk3MC4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIGxvbmcgbWlsbGlzOworCisgICAgLyoqCisgICAgICogVGhlIGFzc29jaWF0ZWQge0Bjb2RlIFRocm93YWJsZX0gb2JqZWN0IGlmIGFueS4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIFRocm93YWJsZSB0aHJvd247CisKKyAgICAvKioKKyAgICAgKiBUaGUgbmFtZSBvZiB0aGUgc291cmNlIGxvZ2dlci4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBsb2dnZXJOYW1lOworCisgICAgLyoqCisgICAgICogVGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIGJ1bmRsZSB1c2VkIHRvIGxvY2FsaXplIHRoZSBsb2cgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyByZXNvdXJjZUJ1bmRsZU5hbWU7CisKKyAgICAvLyBUaGUgYXNzb2NpYXRlZCByZXNvdXJjZSBidW5kbGUgaWYgYW55LgorICAgIHByaXZhdGUgdHJhbnNpZW50IFJlc291cmNlQnVuZGxlIHJlc291cmNlQnVuZGxlOworCisgICAgLy8gVGhlIHBhcmFtZXRlcnMuCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgT2JqZWN0W10gcGFyYW1ldGVyczsKKworICAgIC8vIElmIHRoZSBzb3VyY2UgbWV0aG9kIGFuZCBzb3VyY2UgY2xhc3MgaGFzIGJlZW4gaW5pdGlhbGl6ZWQKKyAgICBwcml2YXRlIHRyYW5zaWVudCBib29sZWFuIHNvdXJjZUluaXRpYWxpemVkOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBMb2dSZWNvcmR9IG9iamVjdCB1c2luZyB0aGUgc3VwcGxpZWQgdGhlIGxvZ2dpbmcKKyAgICAgKiBsZXZlbCBhbmQgbWVzc2FnZS4gVGhlIG1pbGxpcyBwcm9wZXJ0eSBpcyBzZXQgdG8gdGhlIGN1cnJlbnQgdGltZS4gVGhlCisgICAgICogc2VxdWVuY2UgcHJvcGVydHkgaXMgc2V0IHRvIGEgbmV3IHVuaXF1ZSB2YWx1ZSwgYWxsb2NhdGVkIGluIGluY3JlYXNpbmcKKyAgICAgKiBvcmRlciB3aXRoaW4gdGhlIFZNLiBUaGUgdGhyZWFkIElEIGlzIHNldCB0byBhIHVuaXF1ZSB2YWx1ZQorICAgICAqIGZvciB0aGUgY3VycmVudCB0aHJlYWQuIEFsbCBvdGhlciBwcm9wZXJ0aWVzIGFyZSBzZXQgdG8ge0Bjb2RlIG51bGx9LgorICAgICAqCisgICAgICogQHBhcmFtIGxldmVsCisgICAgICogICAgICAgICAgICB0aGUgbG9nZ2luZyBsZXZlbCwgbWF5IG5vdCBiZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIHJhdyBtZXNzYWdlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbGV2ZWx9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTG9nUmVjb3JkKExldmVsIGxldmVsLCBTdHJpbmcgbXNnKSB7CisgICAgICAgIGlmIChsZXZlbCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImxldmVsID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmxldmVsID0gbGV2ZWw7CisgICAgICAgIHRoaXMubWVzc2FnZSA9IG1zZzsKKyAgICAgICAgdGhpcy5taWxsaXMgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKworICAgICAgICBzeW5jaHJvbml6ZWQgKExvZ1JlY29yZC5jbGFzcykgeworICAgICAgICAgICAgdGhpcy5zZXF1ZW5jZU51bWJlciA9IGN1cnJlbnRTZXF1ZW5jZU51bWJlcisrOworICAgICAgICAgICAgSW50ZWdlciBpZCA9IGN1cnJlbnRUaHJlYWRJZC5nZXQoKTsKKyAgICAgICAgICAgIGlmIChpZCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhpcy50aHJlYWRJRCA9IGluaXRUaHJlYWRJZDsKKyAgICAgICAgICAgICAgICBjdXJyZW50VGhyZWFkSWQuc2V0KEludGVnZXIudmFsdWVPZihpbml0VGhyZWFkSWQrKykpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aGlzLnRocmVhZElEID0gaWQuaW50VmFsdWUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuc291cmNlQ2xhc3NOYW1lID0gbnVsbDsKKyAgICAgICAgdGhpcy5zb3VyY2VNZXRob2ROYW1lID0gbnVsbDsKKyAgICAgICAgdGhpcy5sb2dnZXJOYW1lID0gbnVsbDsKKyAgICAgICAgdGhpcy5wYXJhbWV0ZXJzID0gbnVsbDsKKyAgICAgICAgdGhpcy5yZXNvdXJjZUJ1bmRsZSA9IG51bGw7CisgICAgICAgIHRoaXMucmVzb3VyY2VCdW5kbGVOYW1lID0gbnVsbDsKKyAgICAgICAgdGhpcy50aHJvd24gPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxvZ2dpbmcgbGV2ZWwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsb2dnaW5nIGxldmVsLgorICAgICAqLworICAgIHB1YmxpYyBMZXZlbCBnZXRMZXZlbCgpIHsKKyAgICAgICAgcmV0dXJuIGxldmVsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGxvZ2dpbmcgbGV2ZWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGV2ZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZXZlbCB0byBzZXQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBsZXZlbH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExldmVsKExldmVsIGxldmVsKSB7CisgICAgICAgIGlmIChsZXZlbCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImxldmVsID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmxldmVsID0gbGV2ZWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbmFtZSBvZiB0aGUgbG9nZ2VyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbG9nZ2VyIG5hbWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRMb2dnZXJOYW1lKCkgeworICAgICAgICByZXR1cm4gbG9nZ2VyTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBsb2dnZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9nZ2VyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGxvZ2dlciBuYW1lIHRvIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMb2dnZXJOYW1lKFN0cmluZyBsb2dnZXJOYW1lKSB7CisgICAgICAgIHRoaXMubG9nZ2VyTmFtZSA9IGxvZ2dlck5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcmF3IG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByYXcgbWVzc2FnZSwgbWF5IGJlIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2UoKSB7CisgICAgICAgIHJldHVybiBtZXNzYWdlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHJhdyBtZXNzYWdlLiBXaGVuIHRoaXMgcmVjb3JkIGlzIGZvcm1hdHRlZCBieSBhIGxvZ2dlciB0aGF0IGhhcworICAgICAqIGEgbG9jYWxpemF0aW9uIHJlc291cmNlIGJ1bmRsZSB0aGF0IGNvbnRhaW5zIGFuIGVudHJ5IGZvciB7QGNvZGUgbWVzc2FnZX0sCisgICAgICogdGhlbiB0aGUgcmF3IG1lc3NhZ2UgaXMgcmVwbGFjZWQgd2l0aCBpdHMgbG9jYWxpemVkIHZlcnNpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIHJhdyBtZXNzYWdlIHRvIHNldCwgbWF5IGJlIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRNZXNzYWdlKFN0cmluZyBtZXNzYWdlKSB7CisgICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdGltZSB3aGVuIHRoaXMgZXZlbnQgb2NjdXJyZWQsIGluIG1pbGxpc2Vjb25kcyBzaW5jZSAxOTcwLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdGltZSB3aGVuIHRoaXMgZXZlbnQgb2NjdXJyZWQsIGluIG1pbGxpc2Vjb25kcyBzaW5jZSAxOTcwLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldE1pbGxpcygpIHsKKyAgICAgICAgcmV0dXJuIG1pbGxpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB0aW1lIHdoZW4gdGhpcyBldmVudCBvY2N1cnJlZCwgaW4gbWlsbGlzZWNvbmRzIHNpbmNlIDE5NzAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWlsbGlzCisgICAgICogICAgICAgICAgICB0aGUgdGltZSB3aGVuIHRoaXMgZXZlbnQgb2NjdXJyZWQsIGluIG1pbGxpc2Vjb25kcyBzaW5jZSAxOTcwLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1pbGxpcyhsb25nIG1pbGxpcykgeworICAgICAgICB0aGlzLm1pbGxpcyA9IG1pbGxpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBwYXJhbWV0ZXJzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2YgcGFyYW1ldGVycyBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgYXJlIG5vCisgICAgICogICAgICAgICBwYXJhbWV0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3RbXSBnZXRQYXJhbWV0ZXJzKCkgeworICAgICAgICByZXR1cm4gcGFyYW1ldGVyczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwYXJhbWV0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlcnMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBwYXJhbWV0ZXJzIHRvIHNldCwgbWF5IGJlIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQYXJhbWV0ZXJzKE9iamVjdFtdIHBhcmFtZXRlcnMpIHsKKyAgICAgICAgdGhpcy5wYXJhbWV0ZXJzID0gcGFyYW1ldGVyczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSByZXNvdXJjZSBidW5kbGUgdXNlZCB0byBsb2NhbGl6ZSB0aGUgcmF3IG1lc3NhZ2UgZHVyaW5nCisgICAgICogZm9ybWF0dGluZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGFzc29jaWF0ZWQgcmVzb3VyY2UgYnVuZGxlLCB7QGNvZGUgbnVsbH0gaWYgbm9uZSBpcworICAgICAqICAgICAgICAgYXZhaWxhYmxlIG9yIHRoZSBtZXNzYWdlIGlzIG5vdCBsb2NhbGl6YWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzb3VyY2VCdW5kbGUgZ2V0UmVzb3VyY2VCdW5kbGUoKSB7CisgICAgICAgIHJldHVybiByZXNvdXJjZUJ1bmRsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSByZXNvdXJjZSBidW5kbGUgdXNlZCB0byBsb2NhbGl6ZSB0aGUgcmF3IG1lc3NhZ2UgZHVyaW5nCisgICAgICogZm9ybWF0dGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZXNvdXJjZUJ1bmRsZQorICAgICAqICAgICAgICAgICAgdGhlIHJlc291cmNlIGJ1bmRsZSB0byBzZXQsIG1heSBiZSB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmVzb3VyY2VCdW5kbGUoUmVzb3VyY2VCdW5kbGUgcmVzb3VyY2VCdW5kbGUpIHsKKyAgICAgICAgdGhpcy5yZXNvdXJjZUJ1bmRsZSA9IHJlc291cmNlQnVuZGxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIGJ1bmRsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIGJ1bmRsZSwge0Bjb2RlIG51bGx9IGlmIG5vbmUgaXMKKyAgICAgKiAgICAgICAgIGF2YWlsYWJsZSBvciB0aGUgbWVzc2FnZSBpcyBub3QgbG9jYWxpemFibGUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRSZXNvdXJjZUJ1bmRsZU5hbWUoKSB7CisgICAgICAgIHJldHVybiByZXNvdXJjZUJ1bmRsZU5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmFtZSBvZiB0aGUgcmVzb3VyY2UgYnVuZGxlLgorICAgICAqCisgICAgICogQHBhcmFtIHJlc291cmNlQnVuZGxlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIGJ1bmRsZSB0byBzZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmVzb3VyY2VCdW5kbGVOYW1lKFN0cmluZyByZXNvdXJjZUJ1bmRsZU5hbWUpIHsKKyAgICAgICAgdGhpcy5yZXNvdXJjZUJ1bmRsZU5hbWUgPSByZXNvdXJjZUJ1bmRsZU5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2VxdWVuY2UgbnVtYmVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc2VxdWVuY2UgbnVtYmVyLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFNlcXVlbmNlTnVtYmVyKCkgeworICAgICAgICByZXR1cm4gc2VxdWVuY2VOdW1iZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc2VxdWVuY2UgbnVtYmVyLiBJdCBpcyB1c3VhbGx5IG5vdCBuZWNlc3NhcnkgdG8gY2FsbCB0aGlzIG1ldGhvZAorICAgICAqIHRvIGNoYW5nZSB0aGUgc2VxdWVuY2UgbnVtYmVyIGJlY2F1c2UgdGhlIG51bWJlciBpcyBhbGxvY2F0ZWQgd2hlbiB0aGlzCisgICAgICogaW5zdGFuY2UgaXMgY29uc3RydWN0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2VxdWVuY2VOdW1iZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZXF1ZW5jZSBudW1iZXIgdG8gc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNlcXVlbmNlTnVtYmVyKGxvbmcgc2VxdWVuY2VOdW1iZXIpIHsKKyAgICAgICAgdGhpcy5zZXF1ZW5jZU51bWJlciA9IHNlcXVlbmNlTnVtYmVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWUgb2YgdGhlIGNsYXNzIHRoYXQgaXMgdGhlIHNvdXJjZSBvZiB0aGlzIGxvZyByZWNvcmQuIFRoaXMKKyAgICAgKiBpbmZvcm1hdGlvbiBjYW4gYmUgY2hhbmdlZCwgbWF5IGJlIHtAY29kZSBudWxsfSBhbmQgaXMgdW50cnVzdGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgc291cmNlIGNsYXNzIG9mIHRoaXMgbG9nIHJlY29yZCAocG9zc2libGl0eSB7QGNvZGUgbnVsbH0pCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTb3VyY2VDbGFzc05hbWUoKSB7CisgICAgICAgIGluaXRTb3VyY2UoKTsKKyAgICAgICAgcmV0dXJuIHNvdXJjZUNsYXNzTmFtZTsKKyAgICB9CisKKyAgICAvKgorICAgICAqICBJbml0IHRoZSBzb3VyY2VDbGFzcyBhbmQgc291cmNlTWV0aG9kIGZpZWxkcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdFNvdXJjZSgpIHsKKyAgICAgICAgaWYgKHNvdXJjZUluaXRpYWxpemVkKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIHNhd0xvZ2dlciA9IGZhbHNlOworICAgICAgICBmb3IgKFN0YWNrVHJhY2VFbGVtZW50IGVsZW1lbnQgOiBuZXcgVGhyb3dhYmxlKCkuZ2V0U3RhY2tUcmFjZSgpKSB7CisgICAgICAgICAgICBTdHJpbmcgY3VycmVudCA9IGVsZW1lbnQuZ2V0Q2xhc3NOYW1lKCk7CisgICAgICAgICAgICBpZiAoY3VycmVudC5zdGFydHNXaXRoKExvZ2dlci5jbGFzcy5nZXROYW1lKCkpKSB7CisgICAgICAgICAgICAgICAgc2F3TG9nZ2VyID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoc2F3TG9nZ2VyKSB7CisgICAgICAgICAgICAgICAgdGhpcy5zb3VyY2VDbGFzc05hbWUgPSBlbGVtZW50LmdldENsYXNzTmFtZSgpOworICAgICAgICAgICAgICAgIHRoaXMuc291cmNlTWV0aG9kTmFtZSA9IGVsZW1lbnQuZ2V0TWV0aG9kTmFtZSgpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgc291cmNlSW5pdGlhbGl6ZWQgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5hbWUgb2YgdGhlIGNsYXNzIHRoYXQgaXMgdGhlIHNvdXJjZSBvZiB0aGlzIGxvZyByZWNvcmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc291cmNlQ2xhc3NOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgc291cmNlIGNsYXNzIG9mIHRoaXMgbG9nIHJlY29yZCwgbWF5IGJlCisgICAgICogICAgICAgICAgICB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U291cmNlQ2xhc3NOYW1lKFN0cmluZyBzb3VyY2VDbGFzc05hbWUpIHsKKyAgICAgICAgc291cmNlSW5pdGlhbGl6ZWQgPSB0cnVlOworICAgICAgICB0aGlzLnNvdXJjZUNsYXNzTmFtZSA9IHNvdXJjZUNsYXNzTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBuYW1lIG9mIHRoZSBtZXRob2QgdGhhdCBpcyB0aGUgc291cmNlIG9mIHRoaXMgbG9nIHJlY29yZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIHNvdXJjZSBtZXRob2Qgb2YgdGhpcyBsb2cgcmVjb3JkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U291cmNlTWV0aG9kTmFtZSgpIHsKKyAgICAgICAgaW5pdFNvdXJjZSgpOworICAgICAgICByZXR1cm4gc291cmNlTWV0aG9kTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBtZXRob2QgdGhhdCBpcyB0aGUgc291cmNlIG9mIHRoaXMgbG9nIHJlY29yZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzb3VyY2VNZXRob2ROYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgc291cmNlIG1ldGhvZCBvZiB0aGlzIGxvZyByZWNvcmQsIG1heSBiZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNvdXJjZU1ldGhvZE5hbWUoU3RyaW5nIHNvdXJjZU1ldGhvZE5hbWUpIHsKKyAgICAgICAgc291cmNlSW5pdGlhbGl6ZWQgPSB0cnVlOworICAgICAgICB0aGlzLnNvdXJjZU1ldGhvZE5hbWUgPSBzb3VyY2VNZXRob2ROYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSB1bmlxdWUgSUQgb2YgdGhlIHRocmVhZCBvcmlnaW5hdGluZyB0aGUgbG9nIHJlY29yZC4gRXZlcnkgdGhyZWFkCisgICAgICogYmVjb21lcyBhIGRpZmZlcmVudCBJRC4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RpY2UgOiB0aGUgSUQgZG9lc24ndCBuZWNlc3NhcnkgbWFwIHRoZSBPUyB0aHJlYWQgSUQKKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBJRCBvZiB0aGUgdGhyZWFkIG9yaWdpbmF0aW5nIHRoaXMgbG9nIHJlY29yZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFRocmVhZElEKCkgeworICAgICAgICByZXR1cm4gdGhyZWFkSUQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgSUQgb2YgdGhlIHRocmVhZCBvcmlnaW5hdGluZyB0aGlzIGxvZyByZWNvcmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhyZWFkSUQKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgSUQgb2YgdGhlIHRocmVhZCBvcmlnaW5hdGluZyB0aGlzIGxvZyByZWNvcmQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VGhyZWFkSUQoaW50IHRocmVhZElEKSB7CisgICAgICAgIHRoaXMudGhyZWFkSUQgPSB0aHJlYWRJRDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB7QGNvZGUgVGhyb3dhYmxlfSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoaXMgbG9nIHJlY29yZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBUaHJvd2FibGV9IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBsb2cgcmVjb3JkLgorICAgICAqLworICAgIHB1YmxpYyBUaHJvd2FibGUgZ2V0VGhyb3duKCkgeworICAgICAgICByZXR1cm4gdGhyb3duOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHtAY29kZSBUaHJvd2FibGV9IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBsb2cgcmVjb3JkLgorICAgICAqCisgICAgICogQHBhcmFtIHRocm93bgorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB7QGNvZGUgVGhyb3dhYmxlfSBvYmplY3QgdG8gYXNzb2NpYXRlIHdpdGggdGhpcyBsb2cKKyAgICAgKiAgICAgICAgICAgIHJlY29yZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUaHJvd24oVGhyb3dhYmxlIHRocm93bikgeworICAgICAgICB0aGlzLnRocm93biA9IHRocm93bjsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEN1c3RvbWl6ZWQgc2VyaWFsaXphdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LmRlZmF1bHRXcml0ZU9iamVjdCgpOworICAgICAgICBvdXQud3JpdGVCeXRlKE1BSk9SKTsKKyAgICAgICAgb3V0LndyaXRlQnl0ZShNSU5PUik7CisgICAgICAgIGlmIChwYXJhbWV0ZXJzID09IG51bGwpIHsKKyAgICAgICAgICAgIG91dC53cml0ZUludCgtMSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBvdXQud3JpdGVJbnQocGFyYW1ldGVycy5sZW5ndGgpOworICAgICAgICAgICAgZm9yIChPYmplY3QgZWxlbWVudCA6IHBhcmFtZXRlcnMpIHsKKyAgICAgICAgICAgICAgICBvdXQud3JpdGVPYmplY3QoKGVsZW1lbnQgPT0gbnVsbCkgPyBudWxsIDogZWxlbWVudC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQ3VzdG9taXplZCBkZXNlcmlhbGl6YXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBpbi5kZWZhdWx0UmVhZE9iamVjdCgpOworICAgICAgICBieXRlIG1ham9yID0gaW4ucmVhZEJ5dGUoKTsKKyAgICAgICAgYnl0ZSBtaW5vciA9IGluLnJlYWRCeXRlKCk7CisgICAgICAgIC8vIG9ubHkgY2hlY2sgTUFKT1IgdmVyc2lvbgorICAgICAgICBpZiAobWFqb3IgIT0gTUFKT1IpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRGlmZmVyZW50IHZlcnNpb24gIiArIEJ5dGUudmFsdWVPZihtYWpvcikgKyAiLiIgKyBCeXRlLnZhbHVlT2YobWlub3IpKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBsZW5ndGggPSBpbi5yZWFkSW50KCk7CisgICAgICAgIGlmIChsZW5ndGggPj0gMCkgeworICAgICAgICAgICAgcGFyYW1ldGVycyA9IG5ldyBPYmplY3RbbGVuZ3RoXTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyYW1ldGVycy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIHBhcmFtZXRlcnNbaV0gPSBpbi5yZWFkT2JqZWN0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJlc291cmNlQnVuZGxlTmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJlc291cmNlQnVuZGxlID0gTG9nZ2VyLmxvYWRSZXNvdXJjZUJ1bmRsZShyZXNvdXJjZUJ1bmRsZU5hbWUpOworICAgICAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBDYW5ub3QgZmluZCB0aGUgc3BlY2lmaWVkIHJlc291cmNlIGJ1bmRsZQorICAgICAgICAgICAgICAgIHJlc291cmNlQnVuZGxlID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9Mb2dnZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9Mb2dnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYzg2ZGM4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL0xvZ2dlci5qYXZhCkBAIC0wLDAgKzEsMTMzNyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmxvZ2dpbmc7CisKK2ltcG9ydCBkYWx2aWsuc3lzdGVtLkRhbHZpa0xvZ0hhbmRsZXI7CitpbXBvcnQgZGFsdmlrLnN5c3RlbS5EYWx2aWtMb2dnaW5nOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29weU9uV3JpdGVBcnJheUxpc3Q7CisKKy8qKgorICogTG9nZ2VycyBhcmUgdXNlZCB0byBsb2cgcmVjb3JkcyB0byBhIHZhcmlldHkgb2YgZGVzdGluYXRpb25zIHN1Y2ggYXMgbG9nIGZpbGVzIG9yCisgKiB0aGUgY29uc29sZS4gVGhleSB1c2UgaW5zdGFuY2VzIG9mIHtAbGluayBIYW5kbGVyfSB0byBhY3R1YWxseSBkbyB0aGUgZGVzdGluYXRpb24tc3BlY2lmaWMKKyAqIG9wZXJhdGlvbnMuCisgKgorICogPHA+Q2xpZW50IGFwcGxpY2F0aW9ucyBjYW4gZ2V0IG5hbWVkIGxvZ2dlcnMgYnkgY2FsbGluZyB0aGUge0Bjb2RlIGdldExvZ2dlcn0KKyAqIG1ldGhvZHMuIFRoZXkgY2FuIGFsc28gZ2V0IGFub255bW91cyBsb2dnZXJzIGJ5IGNhbGxpbmcgdGhlCisgKiB7QGNvZGUgZ2V0QW5vbnltb3VzTG9nZ2VyfSBtZXRob2RzLiBOYW1lZCBsb2dnZXJzIGFyZSBvcmdhbml6ZWQgaW4gYQorICogbmFtZXNwYWNlIGhpZXJhcmNoeSBtYW5hZ2VkIGJ5IGEgbG9nIG1hbmFnZXIuIFRoZSBuYW1pbmcgY29udmVudGlvbiBpcworICogdXN1YWxseSB0aGUgSmF2YSBwYWNrYWdlIG5hbWluZyBjb252ZW50aW9uLiBBbm9ueW1vdXMgbG9nZ2VycyBkbyBub3QgYmVsb25nIHRvIGFueSBuYW1lc3BhY2UuCisgKgorICogPHA+RGV2ZWxvcGVycyBzaG91bGQgdXNlIG5hbWVkIGxvZ2dlcnMgdG8gZW5hYmxlIGxvZ2dpbmcgdG8gYmUgY29udHJvbGxlZCBvbiBhCisgKiBwZXIte0Bjb2RlIExvZ2dlcn0gZ3JhbnVsYXJpdHkuIFRoZSByZWNvbW1lbmRlZCBpZGlvbSBpcyB0byBjcmVhdGUgYW5kIGFzc2lnbiB0aGUgbG9nZ2VyIHRvCisgKiBhIHtAY29kZSBzdGF0aWMgZmluYWx9IGZpZWxkLiBUaGlzIGVuc3VyZXMgdGhhdCB0aGVyZSdzIGFsd2F5cyBhIHN0cm9uZyByZWZlcmVuY2UgdG8gdGhlIGxvZ2dlciwKKyAqIHByZXZlbnRpbmcgaXQgZnJvbSBiZWluZyBnYXJiYWdlIGNvbGxlY3RlZC4gSW4gcGFydGljdWxhciwge0BsaW5rIExvZ01hbmFnZXIjYWRkTG9nZ2VyKExvZ2dlcil9CisgKiB3aWxsIDxpPm5vdDwvaT4ga2VlcCB5b3VyIGxvZ2dlciBsaXZlLgorICoKKyAqIDxwPkxvZ2dlcnMgImluaGVyaXQiIGxvZyBsZXZlbCBzZXR0aW5nIGZyb20gdGhlaXIgcGFyZW50IGlmIHRoZWlyIG93biBsZXZlbCBpcworICogc2V0IHRvIHtAY29kZSBudWxsfS4gVGhpcyBpcyBhbHNvIHRydWUgZm9yIHRoZSByZXNvdXJjZSBidW5kbGUuIFRoZSBsb2dnZXIncworICogcmVzb3VyY2UgYnVuZGxlIGlzIHVzZWQgdG8gbG9jYWxpemUgdGhlIGxvZyBtZXNzYWdlcyBpZiBubyByZXNvdXJjZSBidW5kbGUKKyAqIG5hbWUgaXMgZ2l2ZW4gd2hlbiBhIGxvZyBtZXRob2QgaXMgY2FsbGVkLiBJZiB7QGNvZGUgZ2V0VXNlUGFyZW50SGFuZGxlcnMoKX0KKyAqIHJldHVybnMge0Bjb2RlIHRydWV9LCBsb2dnZXJzIGFsc28gaW5oZXJpdCB0aGVpciBwYXJlbnQncyBoYW5kbGVycy4gSW4gdGhpcworICogY29udGV4dCwgImluaGVyaXQiIG9ubHkgbWVhbnMgdGhhdCAiYmVoYXZpb3IiIGlzIGluaGVyaXRlZC4gVGhlIGludGVybmFsCisgKiBmaWVsZCB2YWx1ZXMgd2lsbCBub3QgY2hhbmdlLCBmb3IgZXhhbXBsZSwge0Bjb2RlIGdldExldmVsKCl9IHN0aWxsIHJldHVybnMKKyAqIHtAY29kZSBudWxsfS4KKyAqIDxwPgorICogV2hlbiBsb2FkaW5nIGEgZ2l2ZW4gcmVzb3VyY2UgYnVuZGxlLCB0aGUgbG9nZ2VyIGZpcnN0IHRyaWVzIHRvIHVzZSB0aGUKKyAqIGNvbnRleHQge0Bjb2RlIENsYXNzTG9hZGVyfS4gSWYgdGhhdCBmYWlscywgaXQgdHJpZXMgdGhlIHN5c3RlbSB7QGNvZGUgQ2xhc3NMb2FkZXJ9LiBBbmQgaWYKKyAqIHRoYXQgc3RpbGwgZmFpbHMsIGl0IHNlYXJjaGVzIHVwIHRoZSBjbGFzcyBzdGFjayBhbmQgdXNlcyBlYWNoIGNsYXNzJ3MKKyAqIHtAY29kZSBDbGFzc0xvYWRlcn0gdG8gdHJ5IHRvIGxvY2F0ZSB0aGUgcmVzb3VyY2UgYnVuZGxlLgorICogPHA+CisgKiBTb21lIGxvZyBtZXRob2RzIGFjY2VwdCBsb2cgcmVxdWVzdHMgdGhhdCBkbyBub3Qgc3BlY2lmeSB0aGUgc291cmNlIGNsYXNzIGFuZAorICogc291cmNlIG1ldGhvZC4gSW4gdGhlc2UgY2FzZXMsIHRoZSBsb2dnaW5nIGZyYW1ld29yayB3aWxsIGF1dG9tYXRpY2FsbHkgaW5mZXIKKyAqIHRoZSBjYWxsaW5nIGNsYXNzIGFuZCBtZXRob2QsIGJ1dCB0aGlzIGlzIG5vdCBndWFyYW50ZWVkIHRvIGJlIGFjY3VyYXRlLgorICogPHA+CisgKiBPbmNlIGEge0Bjb2RlIExvZ1JlY29yZH0gb2JqZWN0IGhhcyBiZWVuIHBhc3NlZCBpbnRvIHRoZSBsb2dnaW5nIGZyYW1ld29yaywKKyAqIGl0IGlzIG93bmVkIGJ5IHRoZSBsb2dnaW5nIGZyYW1ld29yayBhbmQgdGhlIGNsaWVudCBhcHBsaWNhdGlvbnMgc2hvdWxkIG5vdAorICogdXNlIGl0IGFueSBsb25nZXIuCisgKiA8cD4KKyAqIEFsbCBtZXRob2RzIG9mIHRoaXMgY2xhc3MgYXJlIHRocmVhZC1zYWZlLgorICoKKyAqIEBzZWUgTG9nTWFuYWdlcgorICovCitwdWJsaWMgY2xhc3MgTG9nZ2VyIHsKKworICAgIC8qKiBBIGhhbmRsZXIgZm9yIHVzZSB3aGVuIG5vIGhhbmRsZXIgb3B0aW1pemF0aW9uIGlzIHBvc3NpYmxlLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIERhbHZpa0xvZ0hhbmRsZXIgR0VORVJBTF9MT0dfSEFORExFUiA9IG5ldyBEYWx2aWtMb2dIYW5kbGVyKCkgeworICAgICAgICBwdWJsaWMgdm9pZCBwdWJsaXNoKExvZ2dlciBzb3VyY2UsIFN0cmluZyB0YWcsIExldmVsIGxldmVsLCBTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQobGV2ZWwsIG1lc3NhZ2UpOworICAgICAgICAgICAgcmVjb3JkLnNldExvZ2dlck5hbWUoc291cmNlLm5hbWUpOworICAgICAgICAgICAgc291cmNlLnNldFJlc291cmNlQnVuZGxlKHJlY29yZCk7CisgICAgICAgICAgICBzb3VyY2UubG9nKHJlY29yZCk7CisgICAgICAgIH0KKyAgICB9OworCisgICAgLyoqCisgICAgICogVGhlIG5hbWUgb2YgdGhlIGdsb2JhbCBsb2dnZXIuIEJlZm9yZSB1c2luZyB0aGlzLCBzZWUgdGhlIGRpc2N1c3Npb24gb2YgaG93IHRvIHVzZQorICAgICAqIHtAY29kZSBMb2dnZXJ9IGluIHRoZSBjbGFzcyBkb2N1bWVudGF0aW9uLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHTE9CQUxfTE9HR0VSX05BTUUgPSAiZ2xvYmFsIjsKKworICAgIC8qKgorICAgICAqIFRoZSBnbG9iYWwgbG9nZ2VyIGlzIHByb3ZpZGVkIGFzIGNvbnZlbmllbmNlIGZvciBjYXN1YWwgdXNlLgorICAgICAqIEBkZXByZWNhdGVkIGRlYWRsb2NrLXByb25lLiBVc2Uge0Bjb2RlIExvZ2dlci5nZXRMb2dnZXIoTG9nZ2VyLkdMT0JBTF9MT0dHRVJfTkFNRSl9IGFzCisgICAgICogYSBkaXJlY3QgcmVwbGFjZW1lbnQsIGJ1dCBzZWUgdGhlIGRpc2N1c3Npb24gb2YgaG93IHRvIHVzZSB7QGNvZGUgTG9nZ2VyfSBpbiB0aGUgY2xhc3MKKyAgICAgKiBkb2N1bWVudGF0aW9uLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBMb2dnZXIgZ2xvYmFsID0gbmV3IExvZ2dlcihHTE9CQUxfTE9HR0VSX05BTUUsIG51bGwpOworCisgICAgLyoqCisgICAgICogV2hlbiBjb252ZXJ0aW5nIHRoZSBjb25jdXJyZW50IGNvbGxlY3Rpb24gb2YgaGFuZGxlcnMgdG8gYW4gYXJyYXksIHdlCisgICAgICogYWx3YXlzIHBhc3MgYSB6ZXJvLWxlbmd0aCBhcnJheSB0byBhdm9pZCBzaXplIG1pc2NhbGN1bGF0aW9ucy4gUGFzc2luZworICAgICAqIHByb3Blcmx5LXNpemVkIGFycmF5cyBpcyBub24tYXRvbWljLCBhbmQgcmlza3MgYSBudWxsIGVsZW1lbnQgaW4gdGhlCisgICAgICogcmVzdWx0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEhhbmRsZXJbXSBFTVBUWV9IQU5ETEVSU19BUlJBWSA9IG5ldyBIYW5kbGVyWzBdOworCisgICAgLyoqIFRoZSBuYW1lIG9mIHRoaXMgbG9nZ2VyLiAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgU3RyaW5nIG5hbWU7CisKKyAgICAvKiogVGhlIHBhcmVudCBsb2dnZXIgb2YgdGhpcyBsb2dnZXIuICovCisgICAgTG9nZ2VyIHBhcmVudDsKKworICAgIC8qKiBUaGUgbG9nZ2luZyBsZXZlbCBvZiB0aGlzIGxvZ2dlciwgb3IgbnVsbCBpZiBub25lIGlzIHNldC4gKi8KKyAgICB2b2xhdGlsZSBMZXZlbCBsZXZlbE9ialZhbDsKKworICAgIC8qKgorICAgICAqIFRoZSBlZmZlY3RpdmUgbG9nZ2luZyBsZXZlbCBvZiB0aGlzIGxvZ2dlci4gSW4gb3JkZXIgb2YgcHJlZmVyZW5jZSB0aGlzCisgICAgICogaXMgdGhlIGZpcnN0IGFwcGxpY2FibGUgb2Y6CisgICAgICogPG9sPgorICAgICAqIDxsaT50aGUgaW50IHZhbHVlIG9mIHRoaXMgbG9nZ2VyJ3Mge0BsaW5rICNsZXZlbE9ialZhbH0KKyAgICAgKiA8bGk+dGhlIGxvZ2dpbmcgbGV2ZWwgb2YgdGhlIHBhcmVudAorICAgICAqIDxsaT50aGUgZGVmYXVsdCBsZXZlbCAoe0BsaW5rIExldmVsI0lORk99KQorICAgICAqIDwvb2w+CisgICAgICovCisgICAgdm9sYXRpbGUgaW50IGxldmVsSW50VmFsID0gTGV2ZWwuSU5GTy5pbnRWYWx1ZSgpOworCisgICAgLyoqIFRoZSBmaWx0ZXIuICovCisgICAgcHJpdmF0ZSBGaWx0ZXIgZmlsdGVyOworCisgICAgLyoqCisgICAgICogVGhlIHJlc291cmNlIGJ1bmRsZSB1c2VkIHRvIGxvY2FsaXplIGxvZ2dpbmcgbWVzc2FnZXMuIElmIG51bGwsIG5vCisgICAgICogbG9jYWxpemF0aW9uIHdpbGwgYmUgcGVyZm9ybWVkLgorICAgICAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgU3RyaW5nIHJlc291cmNlQnVuZGxlTmFtZTsKKworICAgIC8qKiBUaGUgbG9hZGVkIHJlc291cmNlIGJ1bmRsZSBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCBuYW1lLiAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgUmVzb3VyY2VCdW5kbGUgcmVzb3VyY2VCdW5kbGU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaGFuZGxlcnMgYXR0YWNoZWQgdG8gdGhpcyBsb2dnZXIuIEVhZ2VybHkgaW5pdGlhbGl6ZWQgYW5kCisgICAgICogY29uY3VycmVudGx5IG1vZGlmaWVkLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgTGlzdDxIYW5kbGVyPiBoYW5kbGVycyA9IG5ldyBDb3B5T25Xcml0ZUFycmF5TGlzdDxIYW5kbGVyPigpOworCisgICAgLyoqIFRydWUgdG8gbm90aWZ5IHRoZSBwYXJlbnQncyBoYW5kbGVycyBvZiBlYWNoIGxvZyBtZXNzYWdlLiAqLworICAgIHByaXZhdGUgYm9vbGVhbiBub3RpZnlQYXJlbnRIYW5kbGVycyA9IHRydWU7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIGxvZ2dlciBpcyBuYW1lZC4gT25seSB7QGxpbmsgI2dldEFub255bW91c0xvZ2dlcgorICAgICAqIGFub255bW91cyBsb2dnZXJzfSBhcmUgdW5uYW1lZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNOYW1lZCA9IHRydWU7CisKKyAgICAvKioKKyAgICAgKiBDaGlsZCBsb2dnZXJzLiBTaG91bGQgYmUgYWNjZXNzZWQgb25seSB3aGlsZSBzeW5jaHJvbml6ZWQgb24ge0Bjb2RlCisgICAgICogTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCl9LgorICAgICAqLworICAgIGZpbmFsIExpc3Q8TG9nZ2VyPiBjaGlsZHJlbiA9IG5ldyBBcnJheUxpc3Q8TG9nZ2VyPigpOworCisgICAgLyoqIHRoZSB0YWcgdXNlZCBmb3Igb3B0aW1pemVkIGxvZ2dpbmcuIERlcml2ZWQgZnJvbSB0aGUgbG9nZ2VyIG5hbWUuICovCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgYW5kcm9pZFRhZzsKKworICAgIC8qKiBIYW5kbGVyIGRlbGVnYXRlIGZvciBlaXRoZXIgb3B0aW1pemVkIG9yIHN0YW5kYXJkIGxvZ2dpbmcuICovCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBEYWx2aWtMb2dIYW5kbGVyIGRhbHZpa0xvZ0hhbmRsZXIgPSBHRU5FUkFMX0xPR19IQU5ETEVSOworCisgICAgLyoqCisgICAgICogV2UndmUgb3B0aW1pemVkIGZvciB0aGUgY29tbW9uIGNhc2U6IGxvZ2dpbmcgdG8gYSBzaW5nbGUgaGFuZGxlciB0aGF0CisgICAgICogaW1wbGVtZW50cyB7QGxpbmsgRGFsdmlrTG9nSGFuZGxlcn0uIFRoaXMgaXMgaG93IEFuZHJvaWQgZnJhbWV3b3JrCisgICAgICogYXBwbGljYXRpb25zIGFyZSBjb25maWd1cmVkIGJ5IGRlZmF1bHQuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG9wdGltaXphdGlvbiBoYXMgYmVlbiBtZWFzdXJlZCB0byBzaG93IGEgMi43NXggaW1wcm92ZW1lbnQgaW4KKyAgICAgKiB0aHJvdWdocHV0IGluIHRoZSBjb21tb24gY2FzZTogMTU0bnMgdnMuIDU2bnMgcGVyIG1lc3NhZ2Ugb24gYSBDb3J0ZXgtQTguCisgICAgICogRGlyZWN0IHVzZSBvZiB7QGNvZGUgYW5kcm9pZC51dGlsLkxvZ30gdGFrZXMgMjlucyBwZXIgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIDxwPkVhY2ggdGltZSB0aGUgaGFuZGxlciBjb25maWd1cmF0aW9uIGNoYW5nZXMsIGVpdGhlciBkaXJlY3RseSBvcgorICAgICAqIGluZGlyZWN0bHksIGl0J3MgbmVjZXNzYXJ5IHRvIGVpdGhlciB0dXJuIG9uIG9yIG9mZiB0aGlzIG9wdGltaXphdGlvbi4KKyAgICAgKiBXaGVuIHRoZSBvcHRpbWl6YXRpb24gaXMgb2ZmLCB7QGxpbmsgI2RhbHZpa0xvZ0hhbmRsZXJ9IGlzIGFzc2lnbmVkIHRvCisgICAgICoge0BsaW5rICNHRU5FUkFMX0xPR19IQU5ETEVSfSB3aGljaCBjYW4gc2F0aXNmeSBhcmJpdHJhcnkgY29uZmlndXJhdGlvbi4KKyAgICAgKiBXaGVuIHRoZSBvcHRpbWl6YXRpb24gaXMgcG9zc2libGUsIHtAbGluayAjZGFsdmlrTG9nSGFuZGxlcn0gaXMgYXNzaWduZWQKKyAgICAgKiB0byB0aGUgdXNlcidzIGVmZmljaWVudCBpbXBsZW1lbnRhdGlvbi4gSW4gcHJhdGljZSB0aGlzIGlzIHVzdWFsbHkgdGhlCisgICAgICoge0Bjb2RlIGNvbS5hbmRyb2lkLmludGVybmFsLmxvZ2dpbmcuQW5kcm9pZEhhbmRsZXJ9LgorICAgICAqLworICAgIHZvaWQgdXBkYXRlRGFsdmlrTG9nSGFuZGxlcigpIHsKKyAgICAgICAgRGFsdmlrTG9nSGFuZGxlciBuZXdMb2dIYW5kbGVyID0gR0VORVJBTF9MT0dfSEFORExFUjsKKworICAgICAgICBMb2dnZXIgcGFyZW50ID0gdGhpcy5wYXJlbnQ7CisKKyAgICAgICAgaWYgKGdldENsYXNzKCkgIT0gTG9nZ2VyLmNsYXNzKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogRG8gbm90aGluZy4gU3ViY2xhc3NlcyBhcmVuJ3QgZWxpZ2libGUgZm9yIHRoZSBvcHRpbWl6YXRpb24KKyAgICAgICAgICAgICAqIGJlY2F1c2UgdGhleSBtYXkgb3ZlcnJpZGUgbWV0aG9kcyBsaWtlIGdldEhhbmRsZXJzKCkgb3IKKyAgICAgICAgICAgICAqIGxvZyhMb2dSZWNvcmQpLgorICAgICAgICAgICAgICovCisKKyAgICAgICAgfSBlbHNlIGlmIChwYXJlbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gd2UgdXNlIGFuIGl0ZXJhdG9yIHJhdGhlciB0aGFuIHNpemUoKStnZXQoKSBmb3Igc2FmZSBjb25jdXJyZW5jeQorICAgICAgICAgICAgSXRlcmF0b3I8SGFuZGxlcj4gaCA9IGhhbmRsZXJzLml0ZXJhdG9yKCk7CisgICAgICAgICAgICBpZiAoaC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBIYW5kbGVyIGZpcnN0SGFuZGxlciA9IGgubmV4dCgpOworICAgICAgICAgICAgICAgIGlmICghaC5oYXNOZXh0KCkgJiYgZmlyc3RIYW5kbGVyIGluc3RhbmNlb2YgRGFsdmlrTG9nSGFuZGxlcikgeworICAgICAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAgICAgKiBBdCB0aGlzIHBvaW50LCB3ZSdyZSBlbGlnaWJsZSBmb3IgdGhlIG9wdGltaXphdGlvbi4gV2UndmUKKyAgICAgICAgICAgICAgICAgICAgICogc2F0aXNmaWVkIHRoZXNlIGNvbnN0cmFpbnRzOgorICAgICAgICAgICAgICAgICAgICAgKiAgIDEuIFRoaXMgaXMgbm90IGEgc3ViY2xhc3Mgb2YgbG9nZ2VyCisgICAgICAgICAgICAgICAgICAgICAqICAgMi4gVGhpcyBpcyBhIHJvb3QgbG9nZ2VyIChubyBwYXJlbnQpCisgICAgICAgICAgICAgICAgICAgICAqICAgMy4gVGhlcmUgaXMgZXhhY3RseSBvbmUgaGFuZGxlciBpbnN0YWxsZWQKKyAgICAgICAgICAgICAgICAgICAgICogICA0LiBUaGF0IGhhbmRsZXIgaXMgYSBEYWx2aWtMb2dIYW5kbGVyCisgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICBuZXdMb2dIYW5kbGVyID0gKERhbHZpa0xvZ0hhbmRsZXIpIGZpcnN0SGFuZGxlcjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAoaGFuZGxlcnMuaXNFbXB0eSgpICYmIG5vdGlmeVBhcmVudEhhbmRsZXJzKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogQXQgdGhpcyBwb2ludCwgd2UncmUgZWxpZ2libGUgZm9yIHRoZSBvcHRpbWl6YXRpb24gaWYgb3VyIHBhcmVudAorICAgICAgICAgICAgICogbG9nZ2VyIGlzIGVsaWdpYmxlLiBXZSd2ZSBzYXRpc2ZpZWQgdGhlc2UgY29uc3RyYWludHM6CisgICAgICAgICAgICAgKiAgIDEuIFRoaXMgaXMgbm90IGEgc3ViY2xhc3Mgb2YgbG9nZ2VyCisgICAgICAgICAgICAgKiAgIDIuIG91ciBwYXJlbnQgZXhpc3RzCisgICAgICAgICAgICAgKiAgIDMuIHdlIGhhdmUgbm8gaGFuZGxlcnMgb2Ygb3VyIG93bgorICAgICAgICAgICAgICogICA0LiB3ZSBub3RpZnkgb3VyIHBhcmVudCdzIGhhbmRsZXJzCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIG5ld0xvZ0hhbmRsZXIgPSBwYXJlbnQuZGFsdmlrTG9nSGFuZGxlcjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChuZXdMb2dIYW5kbGVyID09IHRoaXMuZGFsdmlrTG9nSGFuZGxlcikgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5kYWx2aWtMb2dIYW5kbGVyID0gbmV3TG9nSGFuZGxlcjsKKworICAgICAgICBmb3IgKExvZ2dlciBsb2dnZXIgOiBjaGlsZHJlbikgeworICAgICAgICAgICAgbG9nZ2VyLnVwZGF0ZURhbHZpa0xvZ0hhbmRsZXIoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgTG9nZ2VyfSBvYmplY3Qgd2l0aCB0aGUgc3VwcGxpZWQgbmFtZSBhbmQgcmVzb3VyY2UKKyAgICAgKiBidW5kbGUgbmFtZTsge0Bjb2RlIG5vdGlmaXlQYXJlbnRIYW5kbGVyc30gaXMgc2V0IHRvIHtAY29kZSB0cnVlfS4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RpY2UgOiBMb2dnZXJzIHVzZSBhIG5hbWluZyBoaWVyYXJjaHkuIFRodXMgInoueC55IiBpcyBhIGNoaWxkIG9mICJ6LngiLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoaXMgbG9nZ2VyLCBtYXkgYmUge0Bjb2RlIG51bGx9IGZvciBhbm9ueW1vdXMKKyAgICAgKiAgICAgICAgICAgIGxvZ2dlcnMuCisgICAgICogQHBhcmFtIHJlc291cmNlQnVuZGxlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIGJ1bmRsZSB1c2VkIHRvIGxvY2FsaXplIGxvZ2dpbmcKKyAgICAgKiAgICAgICAgICAgIG1lc3NhZ2VzLCBtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCByZXNvdXJjZSBidW5kbGUgY2FuIG5vdCBiZSBsb2FkZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIExvZ2dlcihTdHJpbmcgbmFtZSwgU3RyaW5nIHJlc291cmNlQnVuZGxlTmFtZSkgeworICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgICAgICBpbml0UmVzb3VyY2VCdW5kbGUocmVzb3VyY2VCdW5kbGVOYW1lKTsKKyAgICAgICAgdGhpcy5hbmRyb2lkVGFnID0gRGFsdmlrTG9nZ2luZy5sb2dnZXJOYW1lVG9UYWcobmFtZSk7CisgICAgICAgIHVwZGF0ZURhbHZpa0xvZ0hhbmRsZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2FkIHRoZSBzcGVjaWZpZWQgcmVzb3VyY2UgYnVuZGxlLCB1c2UgcHJpdmlsZWdlZCBjb2RlLgorICAgICAqCisgICAgICogQHBhcmFtIHJlc291cmNlQnVuZGxlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIGJ1bmRsZSB0byBsb2FkLCBjYW5ub3QgYmUge0Bjb2RlIG51bGx9LgorICAgICAqIEByZXR1cm4gdGhlIGxvYWRlZCByZXNvdXJjZSBidW5kbGUuCisgICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHJlc291cmNlIGJ1bmRsZSBjYW4gbm90IGJlIGxvYWRlZC4KKyAgICAgKi8KKyAgICBzdGF0aWMgUmVzb3VyY2VCdW5kbGUgbG9hZFJlc291cmNlQnVuZGxlKFN0cmluZyByZXNvdXJjZUJ1bmRsZU5hbWUpIHsKKyAgICAgICAgLy8gdHJ5IGNvbnRleHQgY2xhc3MgbG9hZGVyIHRvIGxvYWQgdGhlIHJlc291cmNlCisgICAgICAgIENsYXNzTG9hZGVyIGNsID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgaWYgKGNsICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShyZXNvdXJjZUJ1bmRsZU5hbWUsIExvY2FsZS5nZXREZWZhdWx0KCksIGNsKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICAgICAgLy8gRmFpbGVkIHRvIGxvYWQgdXNpbmcgY29udGV4dCBjbGFzcyBsb2FkZXIsIGlnbm9yZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIHRyeSBzeXN0ZW0gY2xhc3MgbG9hZGVyIHRvIGxvYWQgdGhlIHJlc291cmNlCisgICAgICAgIGNsID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKTsKKyAgICAgICAgaWYgKGNsICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShyZXNvdXJjZUJ1bmRsZU5hbWUsIExvY2FsZS5nZXREZWZhdWx0KCksIGNsKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICAgICAgLy8gRmFpbGVkIHRvIGxvYWQgdXNpbmcgc3lzdGVtIGNsYXNzIGxvYWRlciwgaWdub3JlCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbigiRmFpbGVkIHRvIGxvYWQgdGhlIHNwZWNpZmllZCByZXNvdXJjZSBidW5kbGUgXCIiICsKKyAgICAgICAgICAgICAgICByZXNvdXJjZUJ1bmRsZU5hbWUgKyAiXCIiLCByZXNvdXJjZUJ1bmRsZU5hbWUsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gYW5vbnltb3VzIGxvZ2dlciB0byB1c2UgaW50ZXJuYWxseSBpbiBhIHRocmVhZC4gQW5vbnltb3VzIGxvZ2dlcnMKKyAgICAgKiBhcmUgbm90IHJlZ2lzdGVyZWQgaW4gdGhlIGxvZyBtYW5hZ2VyJ3MgbmFtZXNwYWNlLiBObyBzZWN1cml0eSBjaGVja3MKKyAgICAgKiB3aWxsIGJlIHBlcmZvcm1lZCB3aGVuIHVwZGF0aW5nIGFuIGFub255bW91cyBsb2dnZXIncyBjb250cm9sIHNldHRpbmdzLgorICAgICAqIDxwPgorICAgICAqIFRoZSBhbm9ueW1vdXMgbG9nZ2VycycgcGFyZW50IGlzIHNldCB0byBiZSB0aGUgcm9vdCBsb2dnZXIuIFRoaXMgd2F5IGl0CisgICAgICogaW5oZXJpdHMgdGhlIGRlZmF1bHQgbG9nZ2luZyBsZXZlbCBhbmQgaGFuZGxlcnMgZnJvbSB0aGUgcm9vdCBsb2dnZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgbmV3IGluc3RhbmNlIG9mIGFub255bW91cyBsb2dnZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBMb2dnZXIgZ2V0QW5vbnltb3VzTG9nZ2VyKCkgeworICAgICAgICByZXR1cm4gZ2V0QW5vbnltb3VzTG9nZ2VyKG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW4gYW5vbnltb3VzIGxvZ2dlciB0byB1c2UgaW50ZXJuYWxseSBpbiBhIHRocmVhZC4gQW5vbnltb3VzIGxvZ2dlcnMKKyAgICAgKiBhcmUgbm90IHJlZ2lzdGVyZWQgaW4gdGhlIGxvZyBtYW5hZ2VyJ3MgbmFtZXNwYWNlLiBObyBzZWN1cml0eSBjaGVja3MKKyAgICAgKiB3aWxsIGJlIHBlcmZvcm1lZCB3aGVuIHVwZGF0aW5nIGFuIGFub255bW91cyBsb2dnZXIncyBjb250cm9sIHNldHRpbmdzLgorICAgICAqIDxwPgorICAgICAqIFRoZSBhbm9ueW1vdXMgbG9nZ2VycycgcGFyZW50IGlzIHNldCB0byBiZSB0aGUgcm9vdCBsb2dnZXIuIFRoaXMgd2F5IGl0CisgICAgICogaW5oZXJpdHMgZGVmYXVsdCBsb2dnaW5nIGxldmVsIGFuZCBoYW5kbGVycyBmcm9tIHRoZSByb290IGxvZ2dlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZXNvdXJjZUJ1bmRsZU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSBidW5kbGUgdXNlZCB0byBsb2NhbGl6ZSBsb2cgbWVzc2FnZXMuCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiBhbm9ueW1vdXMgbG9nZ2VyLgorICAgICAqIEB0aHJvd3MgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCByZXNvdXJjZSBidW5kbGUgY2FuIG5vdCBiZSBsb2FkZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBMb2dnZXIgZ2V0QW5vbnltb3VzTG9nZ2VyKFN0cmluZyByZXNvdXJjZUJ1bmRsZU5hbWUpIHsKKyAgICAgICAgTG9nZ2VyIHJlc3VsdCA9IG5ldyBMb2dnZXIobnVsbCwgcmVzb3VyY2VCdW5kbGVOYW1lKTsKKyAgICAgICAgcmVzdWx0LmlzTmFtZWQgPSBmYWxzZTsKKyAgICAgICAgTG9nTWFuYWdlciBsb2dNYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7CisgICAgICAgIGxvZ01hbmFnZXIuc2V0UGFyZW50KHJlc3VsdCwgbG9nTWFuYWdlci5nZXRMb2dnZXIoIiIpKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIGxvZ2dlcidzIHJlc291cmNlIGJ1bmRsZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoaXMgbG9nZ2VyJ3MgcmVzb3VyY2UgYnVuZGxlIGFscmVhZHkKKyAgICAgKiAgICAgIGV4aXN0cyBhbmQgaXMgZGlmZmVyZW50IGZyb20gdGhlIHJlc291cmNlIGJ1bmRsZSBzcGVjaWZpZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCBpbml0UmVzb3VyY2VCdW5kbGUoU3RyaW5nIHJlc291cmNlQnVuZGxlTmFtZSkgeworICAgICAgICBTdHJpbmcgY3VycmVudCA9IHRoaXMucmVzb3VyY2VCdW5kbGVOYW1lOworCisgICAgICAgIGlmIChjdXJyZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChjdXJyZW50LmVxdWFscyhyZXNvdXJjZUJ1bmRsZU5hbWUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJSZXNvdXJjZSBidW5kbGUgbmFtZSAnIiArIHJlc291cmNlQnVuZGxlTmFtZSArICInIGlzIGluY29uc2lzdGVudCB3aXRoIHRoZSBleGlzdGluZyAnIiArIGN1cnJlbnQgKyAiJyIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKHJlc291cmNlQnVuZGxlTmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICB0aGlzLnJlc291cmNlQnVuZGxlID0gbG9hZFJlc291cmNlQnVuZGxlKHJlc291cmNlQnVuZGxlTmFtZSk7CisgICAgICAgICAgICB0aGlzLnJlc291cmNlQnVuZGxlTmFtZSA9IHJlc291cmNlQnVuZGxlTmFtZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBuYW1lZCBsb2dnZXIuIFRoZSByZXR1cm5lZCBsb2dnZXIgbWF5IGFscmVhZHkgZXhpc3Qgb3IgbWF5IGJlCisgICAgICogbmV3bHkgY3JlYXRlZC4gSW4gdGhlIGxhdHRlciBjYXNlLCBpdHMgbGV2ZWwgd2lsbCBiZSBzZXQgdG8gdGhlCisgICAgICogY29uZmlndXJlZCBsZXZlbCBhY2NvcmRpbmcgdG8gdGhlIHtAY29kZSBMb2dNYW5hZ2VyfSdzIHByb3BlcnRpZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGxvZ2dlciB0byBnZXQsIGNhbm5vdCBiZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHJldHVybiBhIG5hbWVkIGxvZ2dlci4KKyAgICAgKiBAdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIHRoZSBzcGVjaWZpZWQgcmVzb3VyY2UgYnVuZGxlIGNhbiBub3QgYmUgbG9hZGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTG9nZ2VyIGdldExvZ2dlcihTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCkuZ2V0T3JDcmVhdGUobmFtZSwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIG5hbWVkIGxvZ2dlciBhc3NvY2lhdGVkIHdpdGggdGhlIHN1cHBsaWVkIHJlc291cmNlIGJ1bmRsZS4gVGhlCisgICAgICogcmVzb3VyY2UgYnVuZGxlIHdpbGwgYmUgdXNlZCB0byBsb2NhbGl6ZSBsb2dnaW5nIG1lc3NhZ2VzLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBsb2dnZXIgdG8gZ2V0LCBjYW5ub3QgYmUge0Bjb2RlIG51bGx9LgorICAgICAqIEBwYXJhbSByZXNvdXJjZUJ1bmRsZU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSBidW5kbGUsIG1heSBiZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbG9nZ2VyIGlkZW50aWZpZWQgYnkge0Bjb2RlIG5hbWV9IGlzIGFzc29jaWF0ZWQgd2l0aCBhCisgICAgICogICAgICAgICAgICAgcmVzb3VyY2UgYnVuZGxlIGFuZCBpdHMgbmFtZSBpcyBub3QgZXF1YWwgdG8KKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgcmVzb3VyY2VCdW5kbGVOYW1lfS4KKyAgICAgKiBAdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSBidW5kbGUgY2Fubm90IGJlIGZvdW5kLgorICAgICAqIEByZXR1cm4gYSBuYW1lZCBsb2dnZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBMb2dnZXIgZ2V0TG9nZ2VyKFN0cmluZyBuYW1lLCBTdHJpbmcgcmVzb3VyY2VCdW5kbGVOYW1lKSB7CisgICAgICAgIExvZ2dlciByZXN1bHQgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKQorICAgICAgICAgICAgICAgIC5nZXRPckNyZWF0ZShuYW1lLCByZXNvdXJjZUJ1bmRsZU5hbWUpOworICAgICAgICByZXN1bHQuaW5pdFJlc291cmNlQnVuZGxlKHJlc291cmNlQnVuZGxlTmFtZSk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZ2xvYmFsIHtAY29kZSBMb2dnZXJ9LgorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKiBAaGlkZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIExvZ2dlciBnZXRHbG9iYWwoKSB7CisgICAgICAgIHJldHVybiBnbG9iYWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBhIGhhbmRsZXIgdG8gdGhpcyBsb2dnZXIuIFRoZSB7QGNvZGUgbmFtZX0gd2lsbCBiZSBmZWQgd2l0aCBsb2cKKyAgICAgKiByZWNvcmRzIHJlY2VpdmVkIGJ5IHRoaXMgbG9nZ2VyLgorICAgICAqCisgICAgICogQHBhcmFtIGhhbmRsZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBoYW5kbGVyIG9iamVjdCB0byBhZGQsIGNhbm5vdCBiZSB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkSGFuZGxlcihIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICAgICAgaWYgKGhhbmRsZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJoYW5kbGVyID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICAvLyBBbm9ueW1vdXMgbG9nZ2VycyBjYW4gYWx3YXlzIGFkZCBoYW5kbGVycworICAgICAgICBpZiAodGhpcy5pc05hbWVkKSB7CisgICAgICAgICAgICBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKS5jaGVja0FjY2VzcygpOworICAgICAgICB9CisgICAgICAgIHRoaXMuaGFuZGxlcnMuYWRkKGhhbmRsZXIpOworICAgICAgICB1cGRhdGVEYWx2aWtMb2dIYW5kbGVyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBsb2dnZXIncyBtYW5hZ2VyIGFuZCBpbml0aWFsaXplcyBpdHMgY29uZmlndXJhdGlvbiBmcm9tIHRoZQorICAgICAqIG1hbmFnZXIncyBwcm9wZXJ0aWVzLgorICAgICAqLworICAgIHZvaWQgc2V0TWFuYWdlcihMb2dNYW5hZ2VyIG1hbmFnZXIpIHsKKyAgICAgICAgU3RyaW5nIGxldmVsUHJvcGVydHkgPSBtYW5hZ2VyLmdldFByb3BlcnR5KG5hbWUgKyAiLmxldmVsIik7CisgICAgICAgIGlmIChsZXZlbFByb3BlcnR5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbWFuYWdlci5zZXRMZXZlbFJlY3Vyc2l2ZWx5KExvZ2dlci50aGlzLCBMZXZlbC5wYXJzZShsZXZlbFByb3BlcnR5KSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaW52YWxpZExldmVsKSB7CisgICAgICAgICAgICAgICAgaW52YWxpZExldmVsLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGhhbmRsZXJzUHJvcGVydHlOYW1lID0gbmFtZS5pc0VtcHR5KCkgPyAiaGFuZGxlcnMiIDogbmFtZSArICIuaGFuZGxlcnMiOworICAgICAgICBTdHJpbmcgaGFuZGxlcnNQcm9wZXJ0eSA9IG1hbmFnZXIuZ2V0UHJvcGVydHkoaGFuZGxlcnNQcm9wZXJ0eU5hbWUpOworICAgICAgICBpZiAoaGFuZGxlcnNQcm9wZXJ0eSAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKFN0cmluZyBoYW5kbGVyTmFtZSA6IGhhbmRsZXJzUHJvcGVydHkuc3BsaXQoIix8XFxzIikpIHsKKyAgICAgICAgICAgICAgICBpZiAoaGFuZGxlck5hbWUuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGZpbmFsIEhhbmRsZXIgaGFuZGxlcjsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBoYW5kbGVyID0gKEhhbmRsZXIpIExvZ01hbmFnZXIuZ2V0SW5zdGFuY2VCeUNsYXNzKGhhbmRsZXJOYW1lKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gaW52YWxpZEhhbmRsZXJOYW1lKSB7CisgICAgICAgICAgICAgICAgICAgIGludmFsaWRIYW5kbGVyTmFtZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxldmVsID0gbWFuYWdlci5nZXRQcm9wZXJ0eShoYW5kbGVyTmFtZSArICIubGV2ZWwiKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGxldmVsICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuc2V0TGV2ZWwoTGV2ZWwucGFyc2UobGV2ZWwpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBpbnZhbGlkTGV2ZWwpIHsKKyAgICAgICAgICAgICAgICAgICAgaW52YWxpZExldmVsLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGhhbmRsZXJzLmFkZChoYW5kbGVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHVwZGF0ZURhbHZpa0xvZ0hhbmRsZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFsbCB0aGUgaGFuZGxlcnMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgbG9nZ2VyLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBhbGwgdGhlIGhhbmRsZXJzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGxvZ2dlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgSGFuZGxlcltdIGdldEhhbmRsZXJzKCkgeworICAgICAgICByZXR1cm4gaGFuZGxlcnMudG9BcnJheShFTVBUWV9IQU5ETEVSU19BUlJBWSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhIGhhbmRsZXIgZnJvbSB0aGlzIGxvZ2dlci4gSWYgdGhlIHNwZWNpZmllZCBoYW5kbGVyIGRvZXMgbm90CisgICAgICogZXhpc3QgdGhlbiB0aGlzIG1ldGhvZCBoYXMgbm8gZWZmZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIGhhbmRsZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBoYW5kbGVyIHRvIGJlIHJlbW92ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlSGFuZGxlcihIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICAgICAgLy8gQW5vbnltb3VzIGxvZ2dlcnMgY2FuIGFsd2F5cyByZW1vdmUgaGFuZGxlcnMKKyAgICAgICAgaWYgKHRoaXMuaXNOYW1lZCkgeworICAgICAgICAgICAgTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCkuY2hlY2tBY2Nlc3MoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaGFuZGxlciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5oYW5kbGVycy5yZW1vdmUoaGFuZGxlcik7CisgICAgICAgIHVwZGF0ZURhbHZpa0xvZ0hhbmRsZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBmaWx0ZXIgdXNlZCBieSB0aGlzIGxvZ2dlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGZpbHRlciB1c2VkIGJ5IHRoaXMgbG9nZ2VyLCBtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBGaWx0ZXIgZ2V0RmlsdGVyKCkgeworICAgICAgICByZXR1cm4gdGhpcy5maWx0ZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZmlsdGVyIHVzZWQgYnkgdGhpcyBsb2dnZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3RmlsdGVyCisgICAgICogICAgICAgICAgICB0aGUgZmlsdGVyIHRvIHNldCwgbWF5IGJlIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGaWx0ZXIoRmlsdGVyIG5ld0ZpbHRlcikgeworICAgICAgICAvLyBBbm9ueW1vdXMgbG9nZ2VycyBjYW4gYWx3YXlzIHNldCB0aGUgZmlsdGVyCisgICAgICAgIGlmICh0aGlzLmlzTmFtZWQpIHsKKyAgICAgICAgICAgIExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpLmNoZWNrQWNjZXNzKCk7CisgICAgICAgIH0KKyAgICAgICAgZmlsdGVyID0gbmV3RmlsdGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxvZ2dpbmcgbGV2ZWwgb2YgdGhpcyBsb2dnZXIuIEEge0Bjb2RlIG51bGx9IGxldmVsIGluZGljYXRlcworICAgICAqIHRoYXQgdGhpcyBsb2dnZXIgaW5oZXJpdHMgaXRzIHBhcmVudCdzIGxldmVsLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbG9nZ2luZyBsZXZlbCBvZiB0aGlzIGxvZ2dlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGV2ZWwgZ2V0TGV2ZWwoKSB7CisgICAgICAgIHJldHVybiBsZXZlbE9ialZhbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBsb2dnaW5nIGxldmVsIGZvciB0aGlzIGxvZ2dlci4gQSB7QGNvZGUgbnVsbH0gbGV2ZWwgaW5kaWNhdGVzCisgICAgICogdGhhdCB0aGlzIGxvZ2dlciB3aWxsIGluaGVyaXQgaXRzIHBhcmVudCdzIGxldmVsLgorICAgICAqCisgICAgICogQHBhcmFtIG5ld0xldmVsCisgICAgICogICAgICAgICAgICB0aGUgbG9nZ2luZyBsZXZlbCB0byBzZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TGV2ZWwoTGV2ZWwgbmV3TGV2ZWwpIHsKKyAgICAgICAgLy8gQW5vbnltb3VzIGxvZ2dlcnMgY2FuIGFsd2F5cyBzZXQgdGhlIGxldmVsCisgICAgICAgIExvZ01hbmFnZXIgbG9nTWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgICAgICBpZiAodGhpcy5pc05hbWVkKSB7CisgICAgICAgICAgICBsb2dNYW5hZ2VyLmNoZWNrQWNjZXNzKCk7CisgICAgICAgIH0KKyAgICAgICAgbG9nTWFuYWdlci5zZXRMZXZlbFJlY3Vyc2l2ZWx5KHRoaXMsIG5ld0xldmVsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBmbGFnIHdoaWNoIGluZGljYXRlcyB3aGV0aGVyIHRvIHVzZSB0aGUgaGFuZGxlcnMgb2YgdGhpcworICAgICAqIGxvZ2dlcidzIHBhcmVudCB0byBwdWJsaXNoIGluY29taW5nIGxvZyByZWNvcmRzLCBwb3RlbnRpYWxseSByZWN1cnNpdmVseQorICAgICAqIHVwIHRoZSBuYW1lc3BhY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBzZXQgdG8gdXNlIHBhcmVudCdzIGhhbmRsZXJzLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0VXNlUGFyZW50SGFuZGxlcnMoKSB7CisgICAgICAgIHJldHVybiB0aGlzLm5vdGlmeVBhcmVudEhhbmRsZXJzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZsYWcgd2hpY2ggaW5kaWNhdGVzIHdoZXRoZXIgdG8gdXNlIHRoZSBoYW5kbGVycyBvZiB0aGlzCisgICAgICogbG9nZ2VyJ3MgcGFyZW50LCBwb3RlbnRpYWxseSByZWN1cnNpdmVseSB1cCB0aGUgbmFtZXNwYWNlLgorICAgICAqCisgICAgICogQHBhcmFtIG5vdGlmeVBhcmVudEhhbmRsZXJzCisgICAgICogICAgICAgICAgICB0aGUgbmV3IGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRvIHVzZSB0aGUgcGFyZW50J3MgaGFuZGxlcnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VXNlUGFyZW50SGFuZGxlcnMoYm9vbGVhbiBub3RpZnlQYXJlbnRIYW5kbGVycykgeworICAgICAgICAvLyBBbm9ueW1vdXMgbG9nZ2VycyBjYW4gYWx3YXlzIHNldCB0aGUgdXNlUGFyZW50SGFuZGxlcnMgZmxhZworICAgICAgICBpZiAodGhpcy5pc05hbWVkKSB7CisgICAgICAgICAgICBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKS5jaGVja0FjY2VzcygpOworICAgICAgICB9CisgICAgICAgIHRoaXMubm90aWZ5UGFyZW50SGFuZGxlcnMgPSBub3RpZnlQYXJlbnRIYW5kbGVyczsKKyAgICAgICAgdXBkYXRlRGFsdmlrTG9nSGFuZGxlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5lYXJlc3QgcGFyZW50IG9mIHRoaXMgbG9nZ2VyIGluIHRoZSBuYW1lc3BhY2UsIGEge0Bjb2RlIG51bGx9CisgICAgICogdmFsdWUgd2lsbCBiZSByZXR1cm5lZCBpZiBjYWxsZWQgb24gdGhlIHJvb3QgbG9nZ2VyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcGFyZW50IG9mIHRoaXMgbG9nZ2VyIGluIHRoZSBuYW1lc3BhY2UuCisgICAgICovCisgICAgcHVibGljIExvZ2dlciBnZXRQYXJlbnQoKSB7CisgICAgICAgIHJldHVybiBwYXJlbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcGFyZW50IG9mIHRoaXMgbG9nZ2VyIGluIHRoZSBuYW1lc3BhY2UuIFRoaXMgbWV0aG9kIHNob3VsZCBiZQorICAgICAqIHVzZWQgYnkgdGhlIHtAY29kZSBMb2dNYW5hZ2VyfSBvYmplY3Qgb25seS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJlbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJlbnQgbG9nZ2VyIHRvIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQYXJlbnQoTG9nZ2VyIHBhcmVudCkgeworICAgICAgICBpZiAocGFyZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicGFyZW50ID09IG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGV2ZW4gYW5vbnltb3VzIGxvZ2dlcnMgYXJlIGNoZWNrZWQKKyAgICAgICAgTG9nTWFuYWdlciBsb2dNYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7CisgICAgICAgIGxvZ01hbmFnZXIuY2hlY2tBY2Nlc3MoKTsKKyAgICAgICAgbG9nTWFuYWdlci5zZXRQYXJlbnQodGhpcywgcGFyZW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBuYW1lIG9mIHRoaXMgbG9nZ2VyLCB7QGNvZGUgbnVsbH0gZm9yIGFub255bW91cyBsb2dnZXJzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGlzIGxvZ2dlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiB0aGlzLm5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9hZGVkIHJlc291cmNlIGJ1bmRsZSB1c2VkIGJ5IHRoaXMgbG9nZ2VyIHRvIGxvY2FsaXplIGxvZ2dpbmcKKyAgICAgKiBtZXNzYWdlcy4gSWYgdGhlIHZhbHVlIGlzIHtAY29kZSBudWxsfSwgdGhlIHBhcmVudCdzIHJlc291cmNlIGJ1bmRsZSB3aWxsIGJlCisgICAgICogaW5oZXJpdGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbG9hZGVkIHJlc291cmNlIGJ1bmRsZSB1c2VkIGJ5IHRoaXMgbG9nZ2VyLgorICAgICAqLworICAgIHB1YmxpYyBSZXNvdXJjZUJ1bmRsZSBnZXRSZXNvdXJjZUJ1bmRsZSgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMucmVzb3VyY2VCdW5kbGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbmFtZSBvZiB0aGUgbG9hZGVkIHJlc291cmNlIGJ1bmRsZSB1c2VkIGJ5IHRoaXMgbG9nZ2VyIHRvCisgICAgICogbG9jYWxpemUgbG9nZ2luZyBtZXNzYWdlcy4gSWYgdGhlIHZhbHVlIGlzIHtAY29kZSBudWxsfSwgdGhlIHBhcmVudCdzIHJlc291cmNlCisgICAgICogYnVuZGxlIG5hbWUgd2lsbCBiZSBpbmhlcml0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBsb2FkZWQgcmVzb3VyY2UgYnVuZGxlIHVzZWQgYnkgdGhpcyBsb2dnZXIuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRSZXNvdXJjZUJ1bmRsZU5hbWUoKSB7CisgICAgICAgIHJldHVybiB0aGlzLnJlc291cmNlQnVuZGxlTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBmb3IgY29tcGF0aWJpbGl0eS4gVGVzdHMgd3JpdHRlbiB0byB0aGUgcmVmZXJlbmNlCisgICAgICogaW1wbGVtZW50YXRpb24gQVBJIGltcGx5IHRoYXQgdGhlIGlzTG9nZ2FibGUoKSBtZXRob2QgaXMgbm90IGNhbGxlZAorICAgICAqIGRpcmVjdGx5LiBUaGlzIGJlaGF2aW9yIGlzIGltcG9ydGFudCBiZWNhdXNlIHN1YmNsYXNzIG1heSBvdmVycmlkZQorICAgICAqIGlzTG9nZ2FibGUoKSBtZXRob2QsIHNvIHRoYXQgYWZmZWN0IHRoZSByZXN1bHQgb2YgbG9nIG1ldGhvZHMuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGludGVybmFsSXNMb2dnYWJsZShMZXZlbCBsKSB7CisgICAgICAgIGludCBlZmZlY3RpdmVMZXZlbCA9IGxldmVsSW50VmFsOworICAgICAgICBpZiAoZWZmZWN0aXZlTGV2ZWwgPT0gTGV2ZWwuT0ZGLmludFZhbHVlKCkpIHsKKyAgICAgICAgICAgIC8vIGFsd2F5cyByZXR1cm4gZmFsc2UgaWYgdGhlIGVmZmVjdGl2ZSBsZXZlbCBpcyBvZmYKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbC5pbnRWYWx1ZSgpID49IGVmZmVjdGl2ZUxldmVsOworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGlzIGxvZ2dlciB3aWxsIGFjdHVhbGx5IGxvZyBtZXNzYWdlcyBvZiB0aGUKKyAgICAgKiBzcGVjaWZpZWQgbGV2ZWwuIFRoZSBlZmZlY3RpdmUgbGV2ZWwgdXNlZCB0byBkbyB0aGUgZGV0ZXJtaW5hdGlvbiBtYXkgYmUKKyAgICAgKiBpbmhlcml0ZWQgZnJvbSBpdHMgcGFyZW50LiBUaGUgZGVmYXVsdCBsZXZlbCBpcyB7QGNvZGUgTGV2ZWwuSU5GT30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIGxldmVsIHRvIGNoZWNrLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgbG9nZ2VyIHdpbGwgYWN0dWFsbHkgbG9nIHRoaXMgbGV2ZWwsCisgICAgICogICAgICAgICBvdGhlcndpc2Uge0Bjb2RlIGZhbHNlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0xvZ2dhYmxlKExldmVsIGwpIHsKKyAgICAgICAgcmV0dXJuIGludGVybmFsSXNMb2dnYWJsZShsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSByZXNvdXJjZSBidW5kbGUgYW5kIGl0cyBuYW1lIGZvciBhIHN1cHBsaWVkIExvZ1JlY29yZCBvYmplY3QuCisgICAgICogVGhpcyBtZXRob2QgZmlyc3QgdHJpZXMgdG8gdXNlIHRoaXMgbG9nZ2VyJ3MgcmVzb3VyY2UgYnVuZGxlIGlmIGFueSwKKyAgICAgKiBvdGhlcndpc2UgdHJ5IHRvIGluaGVyaXQgZnJvbSB0aGlzIGxvZ2dlcidzIHBhcmVudCwgcmVjdXJzaXZlbHkgdXAgdGhlCisgICAgICogbmFtZXNwYWNlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRSZXNvdXJjZUJ1bmRsZShMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgIGZvciAoTG9nZ2VyIHAgPSB0aGlzOyBwICE9IG51bGw7IHAgPSBwLnBhcmVudCkgeworICAgICAgICAgICAgU3RyaW5nIHJlc291cmNlQnVuZGxlTmFtZSA9IHAucmVzb3VyY2VCdW5kbGVOYW1lOworICAgICAgICAgICAgaWYgKHJlc291cmNlQnVuZGxlTmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmVjb3JkLnNldFJlc291cmNlQnVuZGxlKHAucmVzb3VyY2VCdW5kbGUpOworICAgICAgICAgICAgICAgIHJlY29yZC5zZXRSZXNvdXJjZUJ1bmRsZU5hbWUocmVzb3VyY2VCdW5kbGVOYW1lKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dzIGEgbWVzc2FnZSBpbmRpY2F0aW5nIHRoYXQgYSBtZXRob2QgaGFzIGJlZW4gZW50ZXJlZC4gQSBsb2cgcmVjb3JkCisgICAgICogd2l0aCBsb2cgbGV2ZWwge0Bjb2RlIExldmVsLkZJTkVSfSwgbG9nIG1lc3NhZ2UgIkVOVFJZIiwgdGhlIHNwZWNpZmllZAorICAgICAqIHNvdXJjZSBjbGFzcyBuYW1lIGFuZCBzb3VyY2UgbWV0aG9kIG5hbWUgaXMgc3VibWl0dGVkIGZvciBsb2dnaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZUNsYXNzCisgICAgICogICAgICAgICAgICB0aGUgY2FsbGluZyBjbGFzcyBuYW1lLgorICAgICAqIEBwYXJhbSBzb3VyY2VNZXRob2QKKyAgICAgKiAgICAgICAgICAgIHRoZSBtZXRob2QgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlbnRlcmluZyhTdHJpbmcgc291cmNlQ2xhc3MsIFN0cmluZyBzb3VyY2VNZXRob2QpIHsKKyAgICAgICAgaWYgKCFpbnRlcm5hbElzTG9nZ2FibGUoTGV2ZWwuRklORVIpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5GSU5FUiwgIkVOVFJZIik7CisgICAgICAgIHJlY29yZC5zZXRMb2dnZXJOYW1lKHRoaXMubmFtZSk7CisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VDbGFzc05hbWUoc291cmNlQ2xhc3MpOworICAgICAgICByZWNvcmQuc2V0U291cmNlTWV0aG9kTmFtZShzb3VyY2VNZXRob2QpOworICAgICAgICBzZXRSZXNvdXJjZUJ1bmRsZShyZWNvcmQpOworICAgICAgICBsb2cocmVjb3JkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dzIGEgbWVzc2FnZSBpbmRpY2F0aW5nIHRoYXQgYSBtZXRob2QgaGFzIGJlZW4gZW50ZXJlZC4gQSBsb2cgcmVjb3JkCisgICAgICogd2l0aCBsb2cgbGV2ZWwge0Bjb2RlIExldmVsLkZJTkVSfSwgbG9nIG1lc3NhZ2UgIkVOVFJZIiwgdGhlIHNwZWNpZmllZAorICAgICAqIHNvdXJjZSBjbGFzcyBuYW1lLCBzb3VyY2UgbWV0aG9kIG5hbWUgYW5kIG9uZSBwYXJhbWV0ZXIgaXMgc3VibWl0dGVkIGZvcgorICAgICAqIGxvZ2dpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc291cmNlQ2xhc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgY2xhc3MgbmFtZS4KKyAgICAgKiBAcGFyYW0gc291cmNlTWV0aG9kCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIG1ldGhvZCBuYW1lLgorICAgICAqIEBwYXJhbSBwYXJhbQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBmb3IgdGhlIG1ldGhvZCBjYWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVudGVyaW5nKFN0cmluZyBzb3VyY2VDbGFzcywgU3RyaW5nIHNvdXJjZU1ldGhvZCwgT2JqZWN0IHBhcmFtKSB7CisgICAgICAgIGlmICghaW50ZXJuYWxJc0xvZ2dhYmxlKExldmVsLkZJTkVSKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuRklORVIsICJFTlRSWSIgKyAiIHswfSIpOworICAgICAgICByZWNvcmQuc2V0TG9nZ2VyTmFtZSh0aGlzLm5hbWUpOworICAgICAgICByZWNvcmQuc2V0U291cmNlQ2xhc3NOYW1lKHNvdXJjZUNsYXNzKTsKKyAgICAgICAgcmVjb3JkLnNldFNvdXJjZU1ldGhvZE5hbWUoc291cmNlTWV0aG9kKTsKKyAgICAgICAgcmVjb3JkLnNldFBhcmFtZXRlcnMobmV3IE9iamVjdFtdIHsgcGFyYW0gfSk7CisgICAgICAgIHNldFJlc291cmNlQnVuZGxlKHJlY29yZCk7CisgICAgICAgIGxvZyhyZWNvcmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvZ3MgYSBtZXNzYWdlIGluZGljYXRpbmcgdGhhdCBhIG1ldGhvZCBoYXMgYmVlbiBlbnRlcmVkLiBBIGxvZyByZWNvcmQKKyAgICAgKiB3aXRoIGxvZyBsZXZlbCB7QGNvZGUgTGV2ZWwuRklORVJ9LCBsb2cgbWVzc2FnZSAiRU5UUlkiLCB0aGUgc3BlY2lmaWVkCisgICAgICogc291cmNlIGNsYXNzIG5hbWUsIHNvdXJjZSBtZXRob2QgbmFtZSBhbmQgYXJyYXkgb2YgcGFyYW1ldGVycyBpcworICAgICAqIHN1Ym1pdHRlZCBmb3IgbG9nZ2luZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzb3VyY2VDbGFzcworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBjbGFzcyBuYW1lLgorICAgICAqIEBwYXJhbSBzb3VyY2VNZXRob2QKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgbWV0aG9kIG5hbWUuCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgYW4gYXJyYXkgb2YgcGFyYW1ldGVycyBmb3IgdGhlIG1ldGhvZCBjYWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVudGVyaW5nKFN0cmluZyBzb3VyY2VDbGFzcywgU3RyaW5nIHNvdXJjZU1ldGhvZCwKKyAgICAgICAgICAgIE9iamVjdFtdIHBhcmFtcykgeworICAgICAgICBpZiAoIWludGVybmFsSXNMb2dnYWJsZShMZXZlbC5GSU5FUikpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBtc2cgPSAiRU5UUlkiOworICAgICAgICBpZiAocGFyYW1zICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgbXNnQnVmZmVyID0gbmV3IFN0cmluZ0J1aWxkZXIoIkVOVFJZIik7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcmFtcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIG1zZ0J1ZmZlci5hcHBlbmQoIiB7IikuYXBwZW5kKGkpLmFwcGVuZCgifSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbXNnID0gbXNnQnVmZmVyLnRvU3RyaW5nKCk7CisgICAgICAgIH0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuRklORVIsIG1zZyk7CisgICAgICAgIHJlY29yZC5zZXRMb2dnZXJOYW1lKHRoaXMubmFtZSk7CisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VDbGFzc05hbWUoc291cmNlQ2xhc3MpOworICAgICAgICByZWNvcmQuc2V0U291cmNlTWV0aG9kTmFtZShzb3VyY2VNZXRob2QpOworICAgICAgICByZWNvcmQuc2V0UGFyYW1ldGVycyhwYXJhbXMpOworICAgICAgICBzZXRSZXNvdXJjZUJ1bmRsZShyZWNvcmQpOworICAgICAgICBsb2cocmVjb3JkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dzIGEgbWVzc2FnZSBpbmRpY2F0aW5nIHRoYXQgYSBtZXRob2QgaXMgZXhpdGVkLiBBIGxvZyByZWNvcmQgd2l0aCBsb2cKKyAgICAgKiBsZXZlbCB7QGNvZGUgTGV2ZWwuRklORVJ9LCBsb2cgbWVzc2FnZSAiUkVUVVJOIiwgdGhlIHNwZWNpZmllZCBzb3VyY2UKKyAgICAgKiBjbGFzcyBuYW1lIGFuZCBzb3VyY2UgbWV0aG9kIG5hbWUgaXMgc3VibWl0dGVkIGZvciBsb2dnaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZUNsYXNzCisgICAgICogICAgICAgICAgICB0aGUgY2FsbGluZyBjbGFzcyBuYW1lLgorICAgICAqIEBwYXJhbSBzb3VyY2VNZXRob2QKKyAgICAgKiAgICAgICAgICAgIHRoZSBtZXRob2QgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBleGl0aW5nKFN0cmluZyBzb3VyY2VDbGFzcywgU3RyaW5nIHNvdXJjZU1ldGhvZCkgeworICAgICAgICBpZiAoIWludGVybmFsSXNMb2dnYWJsZShMZXZlbC5GSU5FUikpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLkZJTkVSLCAiUkVUVVJOIik7CisgICAgICAgIHJlY29yZC5zZXRMb2dnZXJOYW1lKHRoaXMubmFtZSk7CisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VDbGFzc05hbWUoc291cmNlQ2xhc3MpOworICAgICAgICByZWNvcmQuc2V0U291cmNlTWV0aG9kTmFtZShzb3VyY2VNZXRob2QpOworICAgICAgICBzZXRSZXNvdXJjZUJ1bmRsZShyZWNvcmQpOworICAgICAgICBsb2cocmVjb3JkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dzIGEgbWVzc2FnZSBpbmRpY2F0aW5nIHRoYXQgYSBtZXRob2QgaXMgZXhpdGVkLiBBIGxvZyByZWNvcmQgd2l0aCBsb2cKKyAgICAgKiBsZXZlbCB7QGNvZGUgTGV2ZWwuRklORVJ9LCBsb2cgbWVzc2FnZSAiUkVUVVJOIiwgdGhlIHNwZWNpZmllZCBzb3VyY2UKKyAgICAgKiBjbGFzcyBuYW1lLCBzb3VyY2UgbWV0aG9kIG5hbWUgYW5kIHJldHVybiB2YWx1ZSBpcyBzdWJtaXR0ZWQgZm9yIGxvZ2dpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc291cmNlQ2xhc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgY2xhc3MgbmFtZS4KKyAgICAgKiBAcGFyYW0gc291cmNlTWV0aG9kCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIG1ldGhvZCBuYW1lLgorICAgICAqIEBwYXJhbSByZXN1bHQKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIG1ldGhvZCBjYWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGV4aXRpbmcoU3RyaW5nIHNvdXJjZUNsYXNzLCBTdHJpbmcgc291cmNlTWV0aG9kLCBPYmplY3QgcmVzdWx0KSB7CisgICAgICAgIGlmICghaW50ZXJuYWxJc0xvZ2dhYmxlKExldmVsLkZJTkVSKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuRklORVIsICJSRVRVUk4iICsgIiB7MH0iKTsKKyAgICAgICAgcmVjb3JkLnNldExvZ2dlck5hbWUodGhpcy5uYW1lKTsKKyAgICAgICAgcmVjb3JkLnNldFNvdXJjZUNsYXNzTmFtZShzb3VyY2VDbGFzcyk7CisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VNZXRob2ROYW1lKHNvdXJjZU1ldGhvZCk7CisgICAgICAgIHJlY29yZC5zZXRQYXJhbWV0ZXJzKG5ldyBPYmplY3RbXSB7IHJlc3VsdCB9KTsKKyAgICAgICAgc2V0UmVzb3VyY2VCdW5kbGUocmVjb3JkKTsKKyAgICAgICAgbG9nKHJlY29yZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9ncyBhIG1lc3NhZ2UgaW5kaWNhdGluZyB0aGF0IGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uIEEgbG9nIHJlY29yZCB3aXRoCisgICAgICogbG9nIGxldmVsIHtAY29kZSBMZXZlbC5GSU5FUn0sIGxvZyBtZXNzYWdlICJUSFJPVyIsIHRoZSBzcGVjaWZpZWQgc291cmNlCisgICAgICogY2xhc3MgbmFtZSwgc291cmNlIG1ldGhvZCBuYW1lIGFuZCB0aGUge0Bjb2RlIFRocm93YWJsZX0gb2JqZWN0IGlzCisgICAgICogc3VibWl0dGVkIGZvciBsb2dnaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZUNsYXNzCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGNsYXNzIG5hbWUuCisgICAgICogQHBhcmFtIHNvdXJjZU1ldGhvZAorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBtZXRob2QgbmFtZS4KKyAgICAgKiBAcGFyYW0gdGhyb3duCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIFRocm93YWJsZX0gb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRocm93aW5nKFN0cmluZyBzb3VyY2VDbGFzcywgU3RyaW5nIHNvdXJjZU1ldGhvZCwKKyAgICAgICAgICAgIFRocm93YWJsZSB0aHJvd24pIHsKKyAgICAgICAgaWYgKCFpbnRlcm5hbElzTG9nZ2FibGUoTGV2ZWwuRklORVIpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5GSU5FUiwgIlRIUk9XIik7CisgICAgICAgIHJlY29yZC5zZXRMb2dnZXJOYW1lKHRoaXMubmFtZSk7CisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VDbGFzc05hbWUoc291cmNlQ2xhc3MpOworICAgICAgICByZWNvcmQuc2V0U291cmNlTWV0aG9kTmFtZShzb3VyY2VNZXRob2QpOworICAgICAgICByZWNvcmQuc2V0VGhyb3duKHRocm93bik7CisgICAgICAgIHNldFJlc291cmNlQnVuZGxlKHJlY29yZCk7CisgICAgICAgIGxvZyhyZWNvcmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvZ3MgYSBtZXNzYWdlIG9mIGxldmVsIHtAY29kZSBMZXZlbC5TRVZFUkV9OyB0aGUgbWVzc2FnZSBpcyB0cmFuc21pdHRlZAorICAgICAqIHRvIGFsbCBzdWJzY3JpYmVkIGhhbmRsZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIG1lc3NhZ2UgdG8gbG9nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldmVyZShTdHJpbmcgbXNnKSB7CisgICAgICAgIGxvZyhMZXZlbC5TRVZFUkUsIG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9ncyBhIG1lc3NhZ2Ugb2YgbGV2ZWwge0Bjb2RlIExldmVsLldBUk5JTkd9OyB0aGUgbWVzc2FnZSBpcworICAgICAqIHRyYW5zbWl0dGVkIHRvIGFsbCBzdWJzY3JpYmVkIGhhbmRsZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIG1lc3NhZ2UgdG8gbG9nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoU3RyaW5nIG1zZykgeworICAgICAgICBsb2coTGV2ZWwuV0FSTklORywgbXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dzIGEgbWVzc2FnZSBvZiBsZXZlbCB7QGNvZGUgTGV2ZWwuSU5GT307IHRoZSBtZXNzYWdlIGlzIHRyYW5zbWl0dGVkCisgICAgICogdG8gYWxsIHN1YnNjcmliZWQgaGFuZGxlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgbWVzc2FnZSB0byBsb2cuCisgICAgICovCisgICAgcHVibGljIHZvaWQgaW5mbyhTdHJpbmcgbXNnKSB7CisgICAgICAgIGxvZyhMZXZlbC5JTkZPLCBtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvZ3MgYSBtZXNzYWdlIG9mIGxldmVsIHtAY29kZSBMZXZlbC5DT05GSUd9OyB0aGUgbWVzc2FnZSBpcyB0cmFuc21pdHRlZAorICAgICAqIHRvIGFsbCBzdWJzY3JpYmVkIGhhbmRsZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIG1lc3NhZ2UgdG8gbG9nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNvbmZpZyhTdHJpbmcgbXNnKSB7CisgICAgICAgIGxvZyhMZXZlbC5DT05GSUcsIG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9ncyBhIG1lc3NhZ2Ugb2YgbGV2ZWwge0Bjb2RlIExldmVsLkZJTkV9OyB0aGUgbWVzc2FnZSBpcyB0cmFuc21pdHRlZAorICAgICAqIHRvIGFsbCBzdWJzY3JpYmVkIGhhbmRsZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIG1lc3NhZ2UgdG8gbG9nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZpbmUoU3RyaW5nIG1zZykgeworICAgICAgICBsb2coTGV2ZWwuRklORSwgbXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dzIGEgbWVzc2FnZSBvZiBsZXZlbCB7QGNvZGUgTGV2ZWwuRklORVJ9OyB0aGUgbWVzc2FnZSBpcyB0cmFuc21pdHRlZAorICAgICAqIHRvIGFsbCBzdWJzY3JpYmVkIGhhbmRsZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIG1lc3NhZ2UgdG8gbG9nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZpbmVyKFN0cmluZyBtc2cpIHsKKyAgICAgICAgbG9nKExldmVsLkZJTkVSLCBtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvZ3MgYSBtZXNzYWdlIG9mIGxldmVsIHtAY29kZSBMZXZlbC5GSU5FU1R9OyB0aGUgbWVzc2FnZSBpcyB0cmFuc21pdHRlZAorICAgICAqIHRvIGFsbCBzdWJzY3JpYmVkIGhhbmRsZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIG1lc3NhZ2UgdG8gbG9nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZpbmVzdChTdHJpbmcgbXNnKSB7CisgICAgICAgIGxvZyhMZXZlbC5GSU5FU1QsIG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9ncyBhIG1lc3NhZ2Ugb2YgdGhlIHNwZWNpZmllZCBsZXZlbC4gVGhlIG1lc3NhZ2UgaXMgdHJhbnNtaXR0ZWQgdG8gYWxsCisgICAgICogc3Vic2NyaWJlZCBoYW5kbGVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2dMZXZlbAorICAgICAqICAgICAgICAgICAgdGhlIGxldmVsIG9mIHRoZSBzcGVjaWZpZWQgbWVzc2FnZS4KKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgbWVzc2FnZSB0byBsb2cuCisgICAgICovCisgICAgcHVibGljIHZvaWQgbG9nKExldmVsIGxvZ0xldmVsLCBTdHJpbmcgbXNnKSB7CisgICAgICAgIGlmICghaW50ZXJuYWxJc0xvZ2dhYmxlKGxvZ0xldmVsKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGRhbHZpa0xvZ0hhbmRsZXIucHVibGlzaCh0aGlzLCBhbmRyb2lkVGFnLCBsb2dMZXZlbCwgbXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dzIGEgbWVzc2FnZSBvZiB0aGUgc3BlY2lmaWVkIGxldmVsIHdpdGggdGhlIHN1cHBsaWVkIHBhcmFtZXRlci4gVGhlCisgICAgICogbWVzc2FnZSBpcyB0aGVuIHRyYW5zbWl0dGVkIHRvIGFsbCBzdWJzY3JpYmVkIGhhbmRsZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGxvZ0xldmVsCisgICAgICogICAgICAgICAgICB0aGUgbGV2ZWwgb2YgdGhlIGdpdmVuIG1lc3NhZ2UuCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIG1lc3NhZ2UgdG8gbG9nLgorICAgICAqIEBwYXJhbSBwYXJhbQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBhc3NvY2lhdGVkIHdpdGggdGhlIGV2ZW50IHRoYXQgaXMgbG9nZ2VkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvZyhMZXZlbCBsb2dMZXZlbCwgU3RyaW5nIG1zZywgT2JqZWN0IHBhcmFtKSB7CisgICAgICAgIGlmICghaW50ZXJuYWxJc0xvZ2dhYmxlKGxvZ0xldmVsKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQobG9nTGV2ZWwsIG1zZyk7CisgICAgICAgIHJlY29yZC5zZXRMb2dnZXJOYW1lKHRoaXMubmFtZSk7CisgICAgICAgIHJlY29yZC5zZXRQYXJhbWV0ZXJzKG5ldyBPYmplY3RbXSB7IHBhcmFtIH0pOworICAgICAgICBzZXRSZXNvdXJjZUJ1bmRsZShyZWNvcmQpOworICAgICAgICBsb2cocmVjb3JkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dzIGEgbWVzc2FnZSBvZiB0aGUgc3BlY2lmaWVkIGxldmVsIHdpdGggdGhlIHN1cHBsaWVkIHBhcmFtZXRlciBhcnJheS4KKyAgICAgKiBUaGUgbWVzc2FnZSBpcyB0aGVuIHRyYW5zbWl0dGVkIHRvIGFsbCBzdWJzY3JpYmVkIGhhbmRsZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGxvZ0xldmVsCisgICAgICogICAgICAgICAgICB0aGUgbGV2ZWwgb2YgdGhlIGdpdmVuIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgbWVzc2FnZSB0byBsb2cuCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBhcnJheSBhc3NvY2lhdGVkIHdpdGggdGhlIGV2ZW50IHRoYXQgaXMgbG9nZ2VkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvZyhMZXZlbCBsb2dMZXZlbCwgU3RyaW5nIG1zZywgT2JqZWN0W10gcGFyYW1zKSB7CisgICAgICAgIGlmICghaW50ZXJuYWxJc0xvZ2dhYmxlKGxvZ0xldmVsKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQobG9nTGV2ZWwsIG1zZyk7CisgICAgICAgIHJlY29yZC5zZXRMb2dnZXJOYW1lKHRoaXMubmFtZSk7CisgICAgICAgIHJlY29yZC5zZXRQYXJhbWV0ZXJzKHBhcmFtcyk7CisgICAgICAgIHNldFJlc291cmNlQnVuZGxlKHJlY29yZCk7CisgICAgICAgIGxvZyhyZWNvcmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvZ3MgYSBtZXNzYWdlIG9mIHRoZSBzcGVjaWZpZWQgbGV2ZWwgd2l0aCB0aGUgc3VwcGxpZWQge0Bjb2RlIFRocm93YWJsZX0KKyAgICAgKiBvYmplY3QuIFRoZSBtZXNzYWdlIGlzIHRoZW4gdHJhbnNtaXR0ZWQgdG8gYWxsIHN1YnNjcmliZWQgaGFuZGxlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9nTGV2ZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZXZlbCBvZiB0aGUgZ2l2ZW4gbWVzc2FnZS4KKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgbWVzc2FnZSB0byBsb2cuCisgICAgICogQHBhcmFtIHRocm93bgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBUaHJvd2FibGV9IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIGV2ZW50IHRoYXQgaXMKKyAgICAgKiAgICAgICAgICAgIGxvZ2dlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBsb2coTGV2ZWwgbG9nTGV2ZWwsIFN0cmluZyBtc2csIFRocm93YWJsZSB0aHJvd24pIHsKKyAgICAgICAgaWYgKCFpbnRlcm5hbElzTG9nZ2FibGUobG9nTGV2ZWwpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChsb2dMZXZlbCwgbXNnKTsKKyAgICAgICAgcmVjb3JkLnNldExvZ2dlck5hbWUodGhpcy5uYW1lKTsKKyAgICAgICAgcmVjb3JkLnNldFRocm93bih0aHJvd24pOworICAgICAgICBzZXRSZXNvdXJjZUJ1bmRsZShyZWNvcmQpOworICAgICAgICBsb2cocmVjb3JkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dzIGEgZ2l2ZW4gbG9nIHJlY29yZC4gT25seSByZWNvcmRzIHdpdGggYSBsb2dnaW5nIGxldmVsIHRoYXQgaXMgZXF1YWwKKyAgICAgKiBvciBncmVhdGVyIHRoYW4gdGhpcyBsb2dnZXIncyBsZXZlbCB3aWxsIGJlIHN1Ym1pdHRlZCB0byB0aGlzIGxvZ2dlcidzCisgICAgICogaGFuZGxlcnMgZm9yIGxvZ2dpbmcuIElmIHtAY29kZSBnZXRVc2VQYXJlbnRIYW5kbGVycygpfSByZXR1cm5zIHtAY29kZQorICAgICAqIHRydWV9LCB0aGUgbG9nIHJlY29yZCB3aWxsIGFsc28gYmUgc3VibWl0dGVkIHRvIHRoZSBoYW5kbGVycyBvZiB0aGlzCisgICAgICogbG9nZ2VyJ3MgcGFyZW50LCBwb3RlbnRpYWxseSByZWN1cnNpdmVseSB1cCB0aGUgbmFtZXNwYWNlLgorICAgICAqIDxwPgorICAgICAqIFNpbmNlIGFsbCBvdGhlciBsb2cgbWV0aG9kcyBjYWxsIHRoaXMgbWV0aG9kIHRvIGFjdHVhbGx5IHBlcmZvcm0gdGhlCisgICAgICogbG9nZ2luZyBhY3Rpb24sIHN1YmNsYXNzZXMgb2YgdGhpcyBjbGFzcyBjYW4gb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8KKyAgICAgKiBjYXRjaCBhbGwgbG9nZ2luZyBhY3Rpdml0aWVzLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWNvcmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2cgcmVjb3JkIHRvIGJlIGxvZ2dlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBsb2coTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICBpZiAoIWludGVybmFsSXNMb2dnYWJsZShyZWNvcmQuZ2V0TGV2ZWwoKSkpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGFwcGx5IHRoZSBmaWx0ZXIgaWYgYW55CisgICAgICAgIEZpbHRlciBmID0gZmlsdGVyOworICAgICAgICBpZiAoZiAhPSBudWxsICYmICFmLmlzTG9nZ2FibGUocmVjb3JkKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogY2FsbCB0aGUgaGFuZGxlcnMgb2YgdGhpcyBsb2dnZXIsIHRocm93IGFueSBleGNlcHRpb24gdGhhdCBvY2N1cnMKKyAgICAgICAgICovCisgICAgICAgIEhhbmRsZXJbXSBhbGxIYW5kbGVycyA9IGdldEhhbmRsZXJzKCk7CisgICAgICAgIGZvciAoSGFuZGxlciBlbGVtZW50IDogYWxsSGFuZGxlcnMpIHsKKyAgICAgICAgICAgIGVsZW1lbnQucHVibGlzaChyZWNvcmQpOworICAgICAgICB9CisgICAgICAgIC8vIGNhbGwgdGhlIHBhcmVudCdzIGhhbmRsZXJzIGlmIHNldCB1c2VQYXJlbnRIYW5kbGVycworICAgICAgICBMb2dnZXIgdGVtcCA9IHRoaXM7CisgICAgICAgIExvZ2dlciB0aGVQYXJlbnQgPSB0ZW1wLnBhcmVudDsKKyAgICAgICAgd2hpbGUgKHRoZVBhcmVudCAhPSBudWxsICYmIHRlbXAuZ2V0VXNlUGFyZW50SGFuZGxlcnMoKSkgeworICAgICAgICAgICAgSGFuZGxlcltdIGhhID0gdGhlUGFyZW50LmdldEhhbmRsZXJzKCk7CisgICAgICAgICAgICBmb3IgKEhhbmRsZXIgZWxlbWVudCA6IGhhKSB7CisgICAgICAgICAgICAgICAgZWxlbWVudC5wdWJsaXNoKHJlY29yZCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0ZW1wID0gdGhlUGFyZW50OworICAgICAgICAgICAgdGhlUGFyZW50ID0gdGVtcC5wYXJlbnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dzIGEgbWVzc2FnZSBvZiB0aGUgZ2l2ZW4gbGV2ZWwgd2l0aCB0aGUgc3BlY2lmaWVkIHNvdXJjZSBjbGFzcyBuYW1lCisgICAgICogYW5kIHNvdXJjZSBtZXRob2QgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2dMZXZlbAorICAgICAqICAgICAgICAgICAgdGhlIGxldmVsIG9mIHRoZSBnaXZlbiBtZXNzYWdlLgorICAgICAqIEBwYXJhbSBzb3VyY2VDbGFzcworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBjbGFzcyBuYW1lLgorICAgICAqIEBwYXJhbSBzb3VyY2VNZXRob2QKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgbWV0aG9kIG5hbWUuCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvZ3AoTGV2ZWwgbG9nTGV2ZWwsIFN0cmluZyBzb3VyY2VDbGFzcywgU3RyaW5nIHNvdXJjZU1ldGhvZCwKKyAgICAgICAgICAgIFN0cmluZyBtc2cpIHsKKyAgICAgICAgaWYgKCFpbnRlcm5hbElzTG9nZ2FibGUobG9nTGV2ZWwpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChsb2dMZXZlbCwgbXNnKTsKKyAgICAgICAgcmVjb3JkLnNldExvZ2dlck5hbWUodGhpcy5uYW1lKTsKKyAgICAgICAgcmVjb3JkLnNldFNvdXJjZUNsYXNzTmFtZShzb3VyY2VDbGFzcyk7CisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VNZXRob2ROYW1lKHNvdXJjZU1ldGhvZCk7CisgICAgICAgIHNldFJlc291cmNlQnVuZGxlKHJlY29yZCk7CisgICAgICAgIGxvZyhyZWNvcmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvZ3MgYSBtZXNzYWdlIG9mIHRoZSBnaXZlbiBsZXZlbCB3aXRoIHRoZSBzcGVjaWZpZWQgc291cmNlIGNsYXNzIG5hbWUsCisgICAgICogc291cmNlIG1ldGhvZCBuYW1lIGFuZCBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9nTGV2ZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZXZlbCBvZiB0aGUgZ2l2ZW4gbWVzc2FnZQorICAgICAqIEBwYXJhbSBzb3VyY2VDbGFzcworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBjbGFzcyBuYW1lCisgICAgICogQHBhcmFtIHNvdXJjZU1ldGhvZAorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBtZXRob2QgbmFtZQorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZAorICAgICAqIEBwYXJhbSBwYXJhbQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBhc3NvY2lhdGVkIHdpdGggdGhlIGV2ZW50IHRoYXQgaXMgbG9nZ2VkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvZ3AoTGV2ZWwgbG9nTGV2ZWwsIFN0cmluZyBzb3VyY2VDbGFzcywgU3RyaW5nIHNvdXJjZU1ldGhvZCwKKyAgICAgICAgICAgIFN0cmluZyBtc2csIE9iamVjdCBwYXJhbSkgeworICAgICAgICBpZiAoIWludGVybmFsSXNMb2dnYWJsZShsb2dMZXZlbCkpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKGxvZ0xldmVsLCBtc2cpOworICAgICAgICByZWNvcmQuc2V0TG9nZ2VyTmFtZSh0aGlzLm5hbWUpOworICAgICAgICByZWNvcmQuc2V0U291cmNlQ2xhc3NOYW1lKHNvdXJjZUNsYXNzKTsKKyAgICAgICAgcmVjb3JkLnNldFNvdXJjZU1ldGhvZE5hbWUoc291cmNlTWV0aG9kKTsKKyAgICAgICAgcmVjb3JkLnNldFBhcmFtZXRlcnMobmV3IE9iamVjdFtdIHsgcGFyYW0gfSk7CisgICAgICAgIHNldFJlc291cmNlQnVuZGxlKHJlY29yZCk7CisgICAgICAgIGxvZyhyZWNvcmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvZ3MgYSBtZXNzYWdlIG9mIHRoZSBnaXZlbiBsZXZlbCB3aXRoIHRoZSBzcGVjaWZpZWQgc291cmNlIGNsYXNzIG5hbWUsCisgICAgICogc291cmNlIG1ldGhvZCBuYW1lIGFuZCBwYXJhbWV0ZXIgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9nTGV2ZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZXZlbCBvZiB0aGUgZ2l2ZW4gbWVzc2FnZS4KKyAgICAgKiBAcGFyYW0gc291cmNlQ2xhc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgY2xhc3MgbmFtZS4KKyAgICAgKiBAcGFyYW0gc291cmNlTWV0aG9kCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIG1ldGhvZCBuYW1lLgorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC4KKyAgICAgKiBAcGFyYW0gcGFyYW1zCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIGFycmF5IGFzc29jaWF0ZWQgd2l0aCB0aGUgZXZlbnQgdGhhdCBpcyBsb2dnZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgbG9ncChMZXZlbCBsb2dMZXZlbCwgU3RyaW5nIHNvdXJjZUNsYXNzLCBTdHJpbmcgc291cmNlTWV0aG9kLAorICAgICAgICAgICAgU3RyaW5nIG1zZywgT2JqZWN0W10gcGFyYW1zKSB7CisgICAgICAgIGlmICghaW50ZXJuYWxJc0xvZ2dhYmxlKGxvZ0xldmVsKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQobG9nTGV2ZWwsIG1zZyk7CisgICAgICAgIHJlY29yZC5zZXRMb2dnZXJOYW1lKHRoaXMubmFtZSk7CisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VDbGFzc05hbWUoc291cmNlQ2xhc3MpOworICAgICAgICByZWNvcmQuc2V0U291cmNlTWV0aG9kTmFtZShzb3VyY2VNZXRob2QpOworICAgICAgICByZWNvcmQuc2V0UGFyYW1ldGVycyhwYXJhbXMpOworICAgICAgICBzZXRSZXNvdXJjZUJ1bmRsZShyZWNvcmQpOworICAgICAgICBsb2cocmVjb3JkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dzIGEgbWVzc2FnZSBvZiB0aGUgZ2l2ZW4gbGV2ZWwgd2l0aCB0aGUgc3BlY2lmaWVkIHNvdXJjZSBjbGFzcyBuYW1lLAorICAgICAqIHNvdXJjZSBtZXRob2QgbmFtZSBhbmQge0Bjb2RlIFRocm93YWJsZX0gb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIGxvZ0xldmVsCisgICAgICogICAgICAgICAgICB0aGUgbGV2ZWwgb2YgdGhlIGdpdmVuIG1lc3NhZ2UuCisgICAgICogQHBhcmFtIHNvdXJjZUNsYXNzCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGNsYXNzIG5hbWUuCisgICAgICogQHBhcmFtIHNvdXJjZU1ldGhvZAorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBtZXRob2QgbmFtZS4KKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuCisgICAgICogQHBhcmFtIHRocm93bgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBUaHJvd2FibGV9IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBsb2dwKExldmVsIGxvZ0xldmVsLCBTdHJpbmcgc291cmNlQ2xhc3MsIFN0cmluZyBzb3VyY2VNZXRob2QsCisgICAgICAgICAgICBTdHJpbmcgbXNnLCBUaHJvd2FibGUgdGhyb3duKSB7CisgICAgICAgIGlmICghaW50ZXJuYWxJc0xvZ2dhYmxlKGxvZ0xldmVsKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQobG9nTGV2ZWwsIG1zZyk7CisgICAgICAgIHJlY29yZC5zZXRMb2dnZXJOYW1lKHRoaXMubmFtZSk7CisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VDbGFzc05hbWUoc291cmNlQ2xhc3MpOworICAgICAgICByZWNvcmQuc2V0U291cmNlTWV0aG9kTmFtZShzb3VyY2VNZXRob2QpOworICAgICAgICByZWNvcmQuc2V0VGhyb3duKHRocm93bik7CisgICAgICAgIHNldFJlc291cmNlQnVuZGxlKHJlY29yZCk7CisgICAgICAgIGxvZyhyZWNvcmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvZ3MgYSBtZXNzYWdlIG9mIHRoZSBnaXZlbiBsZXZlbCB3aXRoIHRoZSBzcGVjaWZpZWQgc291cmNlIGNsYXNzIG5hbWUKKyAgICAgKiBhbmQgc291cmNlIG1ldGhvZCBuYW1lLCB1c2luZyB0aGUgZ2l2ZW4gcmVzb3VyY2UgYnVuZGxlIHRvIGxvY2FsaXplIHRoZQorICAgICAqIG1lc3NhZ2UuIElmIHtAY29kZSBidW5kbGVOYW1lfSBpcyBudWxsLCB0aGUgZW1wdHkgc3RyaW5nIG9yIG5vdCB2YWxpZCB0aGVuCisgICAgICogdGhlIG1lc3NhZ2UgaXMgbm90IGxvY2FsaXplZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2dMZXZlbAorICAgICAqICAgICAgICAgICAgdGhlIGxldmVsIG9mIHRoZSBnaXZlbiBtZXNzYWdlLgorICAgICAqIEBwYXJhbSBzb3VyY2VDbGFzcworICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBjbGFzcyBuYW1lLgorICAgICAqIEBwYXJhbSBzb3VyY2VNZXRob2QKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgbWV0aG9kIG5hbWUuCisgICAgICogQHBhcmFtIGJ1bmRsZU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSBidW5kbGUgdXNlZCB0byBsb2NhbGl6ZSB0aGUgbWVzc2FnZS4KKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgbG9ncmIoTGV2ZWwgbG9nTGV2ZWwsIFN0cmluZyBzb3VyY2VDbGFzcywgU3RyaW5nIHNvdXJjZU1ldGhvZCwKKyAgICAgICAgICAgIFN0cmluZyBidW5kbGVOYW1lLCBTdHJpbmcgbXNnKSB7CisgICAgICAgIGlmICghaW50ZXJuYWxJc0xvZ2dhYmxlKGxvZ0xldmVsKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQobG9nTGV2ZWwsIG1zZyk7CisgICAgICAgIGlmIChidW5kbGVOYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmVjb3JkLnNldFJlc291cmNlQnVuZGxlKGxvYWRSZXNvdXJjZUJ1bmRsZShidW5kbGVOYW1lKSk7CisgICAgICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGlnbm9yZQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVjb3JkLnNldFJlc291cmNlQnVuZGxlTmFtZShidW5kbGVOYW1lKTsKKyAgICAgICAgfQorICAgICAgICByZWNvcmQuc2V0TG9nZ2VyTmFtZSh0aGlzLm5hbWUpOworICAgICAgICByZWNvcmQuc2V0U291cmNlQ2xhc3NOYW1lKHNvdXJjZUNsYXNzKTsKKyAgICAgICAgcmVjb3JkLnNldFNvdXJjZU1ldGhvZE5hbWUoc291cmNlTWV0aG9kKTsKKyAgICAgICAgbG9nKHJlY29yZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9ncyBhIG1lc3NhZ2Ugb2YgdGhlIGdpdmVuIGxldmVsIHdpdGggdGhlIHNwZWNpZmllZCBzb3VyY2UgY2xhc3MgbmFtZSwKKyAgICAgKiBzb3VyY2UgbWV0aG9kIG5hbWUgYW5kIHBhcmFtZXRlciwgdXNpbmcgdGhlIGdpdmVuIHJlc291cmNlIGJ1bmRsZSB0bworICAgICAqIGxvY2FsaXplIHRoZSBtZXNzYWdlLiBJZiB7QGNvZGUgYnVuZGxlTmFtZX0gaXMgbnVsbCwgdGhlIGVtcHR5IHN0cmluZworICAgICAqIG9yIG5vdCB2YWxpZCB0aGVuIHRoZSBtZXNzYWdlIGlzIG5vdCBsb2NhbGl6ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9nTGV2ZWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZXZlbCBvZiB0aGUgZ2l2ZW4gbWVzc2FnZS4KKyAgICAgKiBAcGFyYW0gc291cmNlQ2xhc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgY2xhc3MgbmFtZS4KKyAgICAgKiBAcGFyYW0gc291cmNlTWV0aG9kCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIG1ldGhvZCBuYW1lLgorICAgICAqIEBwYXJhbSBidW5kbGVOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcmVzb3VyY2UgYnVuZGxlIHVzZWQgdG8gbG9jYWxpemUgdGhlIG1lc3NhZ2UuCisgICAgICogQHBhcmFtIG1zZworICAgICAqICAgICAgICAgICAgdGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLgorICAgICAqIEBwYXJhbSBwYXJhbQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlciBhc3NvY2lhdGVkIHdpdGggdGhlIGV2ZW50IHRoYXQgaXMgbG9nZ2VkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvZ3JiKExldmVsIGxvZ0xldmVsLCBTdHJpbmcgc291cmNlQ2xhc3MsIFN0cmluZyBzb3VyY2VNZXRob2QsCisgICAgICAgICAgICBTdHJpbmcgYnVuZGxlTmFtZSwgU3RyaW5nIG1zZywgT2JqZWN0IHBhcmFtKSB7CisgICAgICAgIGlmICghaW50ZXJuYWxJc0xvZ2dhYmxlKGxvZ0xldmVsKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQobG9nTGV2ZWwsIG1zZyk7CisgICAgICAgIGlmIChidW5kbGVOYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmVjb3JkLnNldFJlc291cmNlQnVuZGxlKGxvYWRSZXNvdXJjZUJ1bmRsZShidW5kbGVOYW1lKSk7CisgICAgICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGlnbm9yZQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVjb3JkLnNldFJlc291cmNlQnVuZGxlTmFtZShidW5kbGVOYW1lKTsKKyAgICAgICAgfQorICAgICAgICByZWNvcmQuc2V0TG9nZ2VyTmFtZSh0aGlzLm5hbWUpOworICAgICAgICByZWNvcmQuc2V0U291cmNlQ2xhc3NOYW1lKHNvdXJjZUNsYXNzKTsKKyAgICAgICAgcmVjb3JkLnNldFNvdXJjZU1ldGhvZE5hbWUoc291cmNlTWV0aG9kKTsKKyAgICAgICAgcmVjb3JkLnNldFBhcmFtZXRlcnMobmV3IE9iamVjdFtdIHsgcGFyYW0gfSk7CisgICAgICAgIGxvZyhyZWNvcmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvZ3MgYSBtZXNzYWdlIG9mIHRoZSBnaXZlbiBsZXZlbCB3aXRoIHRoZSBzcGVjaWZpZWQgc291cmNlIGNsYXNzIG5hbWUsCisgICAgICogc291cmNlIG1ldGhvZCBuYW1lIGFuZCBwYXJhbWV0ZXIgYXJyYXksIHVzaW5nIHRoZSBnaXZlbiByZXNvdXJjZSBidW5kbGUKKyAgICAgKiB0byBsb2NhbGl6ZSB0aGUgbWVzc2FnZS4gSWYge0Bjb2RlIGJ1bmRsZU5hbWV9IGlzIG51bGwsIHRoZSBlbXB0eSBzdHJpbmcKKyAgICAgKiBvciBub3QgdmFsaWQgdGhlbiB0aGUgbWVzc2FnZSBpcyBub3QgbG9jYWxpemVkLgorICAgICAqCisgICAgICogQHBhcmFtIGxvZ0xldmVsCisgICAgICogICAgICAgICAgICB0aGUgbGV2ZWwgb2YgdGhlIGdpdmVuIG1lc3NhZ2UuCisgICAgICogQHBhcmFtIHNvdXJjZUNsYXNzCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGNsYXNzIG5hbWUuCisgICAgICogQHBhcmFtIHNvdXJjZU1ldGhvZAorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBtZXRob2QgbmFtZS4KKyAgICAgKiBAcGFyYW0gYnVuZGxlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIGJ1bmRsZSB1c2VkIHRvIGxvY2FsaXplIHRoZSBtZXNzYWdlLgorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC4KKyAgICAgKiBAcGFyYW0gcGFyYW1zCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVyIGFycmF5IGFzc29jaWF0ZWQgd2l0aCB0aGUgZXZlbnQgdGhhdCBpcyBsb2dnZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgbG9ncmIoTGV2ZWwgbG9nTGV2ZWwsIFN0cmluZyBzb3VyY2VDbGFzcywgU3RyaW5nIHNvdXJjZU1ldGhvZCwKKyAgICAgICAgICAgIFN0cmluZyBidW5kbGVOYW1lLCBTdHJpbmcgbXNnLCBPYmplY3RbXSBwYXJhbXMpIHsKKyAgICAgICAgaWYgKCFpbnRlcm5hbElzTG9nZ2FibGUobG9nTGV2ZWwpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChsb2dMZXZlbCwgbXNnKTsKKyAgICAgICAgaWYgKGJ1bmRsZU5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZWNvcmQuc2V0UmVzb3VyY2VCdW5kbGUobG9hZFJlc291cmNlQnVuZGxlKGJ1bmRsZU5hbWUpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gaWdub3JlCisgICAgICAgICAgICB9CisgICAgICAgICAgICByZWNvcmQuc2V0UmVzb3VyY2VCdW5kbGVOYW1lKGJ1bmRsZU5hbWUpOworICAgICAgICB9CisgICAgICAgIHJlY29yZC5zZXRMb2dnZXJOYW1lKHRoaXMubmFtZSk7CisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VDbGFzc05hbWUoc291cmNlQ2xhc3MpOworICAgICAgICByZWNvcmQuc2V0U291cmNlTWV0aG9kTmFtZShzb3VyY2VNZXRob2QpOworICAgICAgICByZWNvcmQuc2V0UGFyYW1ldGVycyhwYXJhbXMpOworICAgICAgICBsb2cocmVjb3JkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dzIGEgbWVzc2FnZSBvZiB0aGUgZ2l2ZW4gbGV2ZWwgd2l0aCB0aGUgc3BlY2lmaWVkIHNvdXJjZSBjbGFzcyBuYW1lLAorICAgICAqIHNvdXJjZSBtZXRob2QgbmFtZSBhbmQge0Bjb2RlIFRocm93YWJsZX0gb2JqZWN0LCB1c2luZyB0aGUgZ2l2ZW4gcmVzb3VyY2UKKyAgICAgKiBidW5kbGUgdG8gbG9jYWxpemUgdGhlIG1lc3NhZ2UuIElmIHtAY29kZSBidW5kbGVOYW1lfSBpcyBudWxsLCB0aGUgZW1wdHkKKyAgICAgKiBzdHJpbmcgb3Igbm90IHZhbGlkIHRoZW4gdGhlIG1lc3NhZ2UgaXMgbm90IGxvY2FsaXplZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2dMZXZlbAorICAgICAqICAgICAgICAgICAgdGhlIGxldmVsIG9mIHRoZSBnaXZlbiBtZXNzYWdlCisgICAgICogQHBhcmFtIHNvdXJjZUNsYXNzCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGNsYXNzIG5hbWUKKyAgICAgKiBAcGFyYW0gc291cmNlTWV0aG9kCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIG1ldGhvZCBuYW1lCisgICAgICogQHBhcmFtIGJ1bmRsZU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSBidW5kbGUgdXNlZCB0byBsb2NhbGl6ZSB0aGUgbWVzc2FnZS4KKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuCisgICAgICogQHBhcmFtIHRocm93bgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBUaHJvd2FibGV9IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBsb2dyYihMZXZlbCBsb2dMZXZlbCwgU3RyaW5nIHNvdXJjZUNsYXNzLCBTdHJpbmcgc291cmNlTWV0aG9kLAorICAgICAgICAgICAgU3RyaW5nIGJ1bmRsZU5hbWUsIFN0cmluZyBtc2csIFRocm93YWJsZSB0aHJvd24pIHsKKyAgICAgICAgaWYgKCFpbnRlcm5hbElzTG9nZ2FibGUobG9nTGV2ZWwpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChsb2dMZXZlbCwgbXNnKTsKKyAgICAgICAgaWYgKGJ1bmRsZU5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZWNvcmQuc2V0UmVzb3VyY2VCdW5kbGUobG9hZFJlc291cmNlQnVuZGxlKGJ1bmRsZU5hbWUpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gaWdub3JlCisgICAgICAgICAgICB9CisgICAgICAgICAgICByZWNvcmQuc2V0UmVzb3VyY2VCdW5kbGVOYW1lKGJ1bmRsZU5hbWUpOworICAgICAgICB9CisgICAgICAgIHJlY29yZC5zZXRMb2dnZXJOYW1lKHRoaXMubmFtZSk7CisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VDbGFzc05hbWUoc291cmNlQ2xhc3MpOworICAgICAgICByZWNvcmQuc2V0U291cmNlTWV0aG9kTmFtZShzb3VyY2VNZXRob2QpOworICAgICAgICByZWNvcmQuc2V0VGhyb3duKHRocm93bik7CisgICAgICAgIGxvZyhyZWNvcmQpOworICAgIH0KKworICAgIHZvaWQgcmVzZXQoKSB7CisgICAgICAgIGxldmVsT2JqVmFsID0gbnVsbDsKKyAgICAgICAgbGV2ZWxJbnRWYWwgPSBMZXZlbC5JTkZPLmludFZhbHVlKCk7CisKKyAgICAgICAgZm9yIChIYW5kbGVyIGhhbmRsZXIgOiBoYW5kbGVycykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAoaGFuZGxlcnMucmVtb3ZlKGhhbmRsZXIpKSB7CisgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdXBkYXRlRGFsdmlrTG9nSGFuZGxlcigpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9Mb2dnaW5nTVhCZWFuLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvTG9nZ2luZ01YQmVhbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEzNmE5ZDQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvTG9nZ2luZ01YQmVhbi5qYXZhCkBAIC0wLDAgKzEsNzkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5sb2dnaW5nOworCitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKgorICoge0Bjb2RlIExvZ2dpbmdNWEJlYW59IGlzIHRoZSBtYW5hZ2VtZW50IGludGVyZmFjZSBmb3IgdGhlIGxvZ2dpbmcgc3ViLXN5c3RlbS4KKyAqIDxwPgorICogVGhlIE9iamVjdE5hbWUgZm9yIGlkZW50aWZ5aW5nIHRoZSB7QGNvZGUgTG9nZ2luZ01YQmVhbn0gaW4gYSBiZWFuIHNlcnZlciBpcworICoge0BsaW5rIExvZ01hbmFnZXIjTE9HR0lOR19NWEJFQU5fTkFNRX0uCisgKiA8L3A+CisgKgorICogQHNpbmNlIDEuNQorICovCitwdWJsaWMgaW50ZXJmYWNlIExvZ2dpbmdNWEJlYW4geworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3RyaW5nIHZhbHVlIG9mIHRoZSBsb2dnaW5nIGxldmVsIG9mIGEgbG9nZ2VyLiBBbiBlbXB0eSBzdHJpbmcKKyAgICAgKiBpcyByZXR1cm5lZCB3aGVuIHRoZSBsb2dnZXIncyBsZXZlbCBpcyBkZWZpbmVkIGJ5IGl0cyBwYXJlbnQuIEEKKyAgICAgKiB7QGNvZGUgbnVsbH0gaXMgcmV0dXJuZWQgaWYgdGhlIHNwZWNpZmllZCBsb2dnZXIgZG9lcyBub3QgZXhpc3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9nZ2VyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGxvZ2dlciBsb29rdXAuCisgICAgICogQHJldHVybiBhIHtAY29kZSBTdHJpbmd9IGlmIHRoZSBsb2dnZXIgaXMgZm91bmQsIG90aGVyd2lzZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHNlZSBMZXZlbCNnZXROYW1lKCkKKyAgICAgKi8KKyAgICBTdHJpbmcgZ2V0TG9nZ2VyTGV2ZWwoU3RyaW5nIGxvZ2dlck5hbWUpOworCisgICAgLyoqCisgICAgICogR2V0cyBhIGxpc3Qgb2YgYWxsIGN1cnJlbnRseSByZWdpc3RlcmVkIGxvZ2dlciBuYW1lcy4gVGhpcyBpcyBwZXJmb3JtZWQKKyAgICAgKiB1c2luZyB0aGUge0BsaW5rIExvZ01hbmFnZXIjZ2V0TG9nZ2VyTmFtZXMoKX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgbGlzdCBvZiBsb2dnZXIgbmFtZXMuCisgICAgICovCisgICAgTGlzdDxTdHJpbmc+IGdldExvZ2dlck5hbWVzKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBuYW1lIG9mIHRoZSBwYXJlbnQgbG9nZ2VyIG9mIGEgbG9nZ2VyLiBJZiB0aGUgbG9nZ2VyIGRvZXNuJ3QKKyAgICAgKiBleGlzdCB0aGVuIHtAY29kZSBudWxsfSBpcyByZXR1cm5lZC4gSWYgdGhlIGxvZ2dlciBpcyB0aGUgcm9vdCBsb2dnZXIsCisgICAgICogdGhlbiBhbiBlbXB0eSB7QGNvZGUgU3RyaW5nfSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2dnZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgbG9nZ2VyIHRvIGxvb2t1cC4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFN0cmluZ30gaWYgdGhlIGxvZ2dlciB3YXMgZm91bmQsIG90aGVyd2lzZSB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgU3RyaW5nIGdldFBhcmVudExvZ2dlck5hbWUoU3RyaW5nIGxvZ2dlck5hbWUpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbG9nIGxldmVsIG9mIGEgbG9nZ2VyLiBMZXZlbE5hbWUgc2V0IHRvIHtAY29kZSBudWxsfSBtZWFucyB0aGUKKyAgICAgKiBsZXZlbCBpcyBpbmhlcml0ZWQgZnJvbSB0aGUgbmVhcmVzdCBub24tbnVsbCBhbmNlc3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2dnZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgbG9nZ2VyIHRvIHNldCB0aGUgbGV2ZWwgb24sIHdoaWNoIG11c3Qgbm90IGJlCisgICAgICogICAgICAgICAgICB7QGNvZGUgbnVsbH0uCisgICAgICogQHBhcmFtIGxldmVsTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGxldmVsIHRvIHNldCBvbiB0aGUgbG9nZ2VyLCB3aGljaCBtYXkgYmUge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGxvZ2dlck5hbWV9IGlzIG5vdCBhIHJlZ2lzdGVyZWQgbG9nZ2VyIG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIGxldmVsTmFtZX0gaXMgbm90IG51bGwgYW5kIG5vdCB2YWxpZC4KKyAgICAgKiBAc2VlIExldmVsI3BhcnNlKFN0cmluZykKKyAgICAgKi8KKyAgICB2b2lkIHNldExvZ2dlckxldmVsKFN0cmluZyBsb2dnZXJOYW1lLCBTdHJpbmcgbGV2ZWxOYW1lKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9Mb2dnaW5nUGVybWlzc2lvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL0xvZ2dpbmdQZXJtaXNzaW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2E1NWUyNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9Mb2dnaW5nUGVybWlzc2lvbi5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5sb2dnaW5nOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5CYXNpY1Blcm1pc3Npb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5HdWFyZDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBMb2dnaW5nUGVybWlzc2lvbiBleHRlbmRzIEJhc2ljUGVybWlzc2lvbiBpbXBsZW1lbnRzIEd1YXJkLCBTZXJpYWxpemFibGUgeworICAgIHB1YmxpYyBMb2dnaW5nUGVybWlzc2lvbihTdHJpbmcgbmFtZSwgU3RyaW5nIGFjdGlvbnMpIHsgc3VwZXIoIiIsICIiKTsgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgZ2V0QWN0aW9ucygpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpbXBsaWVzKFBlcm1pc3Npb24gcGVybWlzc2lvbikgeyByZXR1cm4gdHJ1ZTsgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL01lbW9yeUhhbmRsZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9NZW1vcnlIYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDI5YjBlZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9NZW1vcnlIYW5kbGVyLmphdmEKQEAgLTAsMCArMSwyNjEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5sb2dnaW5nOworCisvKioKKyAqIEEge0Bjb2RlIEhhbmRsZXJ9IHB1dCB0aGUgZGVzY3JpcHRpb24gb2YgbG9nIGV2ZW50cyBpbnRvIGEgY3ljbGVkIG1lbW9yeQorICogYnVmZmVyLgorICogPHA+CisgKiBNb3N0bHkgdGhpcyB7QGNvZGUgTWVtb3J5SGFuZGxlcn0ganVzdCBwdXRzIHRoZSBnaXZlbiB7QGNvZGUgTG9nUmVjb3JkfSBpbnRvCisgKiB0aGUgaW50ZXJuYWwgYnVmZmVyIGFuZCBkb2Vzbid0IHBlcmZvcm0gYW55IGZvcm1hdHRpbmcgb3IgYW55IG90aGVyIHByb2Nlc3MuCisgKiBXaGVuIHRoZSBidWZmZXIgaXMgZnVsbCwgdGhlIGVhcmxpZXN0IGJ1ZmZlcmVkIHJlY29yZHMgd2lsbCBiZSBkaXNjYXJkZWQuCisgKiA8cD4KKyAqIEV2ZXJ5IHtAY29kZSBNZW1vcnlIYW5kbGVyfSBoYXMgYSB0YXJnZXQgaGFuZGxlciwgYW5kIHB1c2ggYWN0aW9uIGNhbiBiZQorICogdHJpZ2dlcmVkIHNvIHRoYXQgYWxsIGJ1ZmZlcmVkIHJlY29yZHMgd2lsbCBiZSBvdXRwdXQgdG8gdGhlIHRhcmdldCBoYW5kbGVyCisgKiBhbmQgbm9ybWFsbHkgdGhlIGxhdHRlciB3aWxsIHB1Ymxpc2ggdGhlIHJlY29yZHMuIEFmdGVyIHRoZSBwdXNoIGFjdGlvbiwgdGhlCisgKiBidWZmZXIgd2lsbCBiZSBjbGVhcmVkLgorICogPHA+CisgKiBUaGUgcHVzaCBtZXRob2QgY2FuIGJlIGNhbGxlZCBkaXJlY3RseSwgYnV0IHdpbGwgYWxzbyBiZSBjYWxsZWQgYXV0b21hdGljYWxseQorICogaWYgYSBuZXcgPGNvZGU+TG9nUmVjb3JkPC9jb2RlPiBpcyBhZGRlZCB0aGF0IGhhcyBhIGxldmVsIGdyZWF0ZXIgdGhhbiBvcgorICogZXF1YWwgdG8gdGhhbiB0aGUgdmFsdWUgZGVmaW5lZCBmb3IgdGhlIHByb3BlcnR5CisgKiBqYXZhLnV0aWwubG9nZ2luZy5NZW1vcnlIYW5kbGVyLnB1c2guCisgKiA8cD4KKyAqIHtAY29kZSBNZW1vcnlIYW5kbGVyfSB3aWxsIHJlYWQgZm9sbG93aW5nIHtAY29kZSBMb2dNYW5hZ2VyfSBwcm9wZXJ0aWVzIGZvcgorICogaW5pdGlhbGl6YXRpb24sIGlmIGdpdmVuIHByb3BlcnRpZXMgYXJlIG5vdCBkZWZpbmVkIG9yIGhhcyBpbnZhbGlkIHZhbHVlcywKKyAqIGRlZmF1bHQgdmFsdWUgd2lsbCBiZSB1c2VkLgorICogPHVsPgorICogPGxpPmphdmEudXRpbC5sb2dnaW5nLk1lbW9yeUhhbmRsZXIuZmlsdGVyIHNwZWNpZmllcyB0aGUge0Bjb2RlIEZpbHRlcn0KKyAqIGNsYXNzIG5hbWUsIGRlZmF1bHRzIHRvIG5vIHtAY29kZSBGaWx0ZXJ9LjwvbGk+CisgKiA8bGk+amF2YS51dGlsLmxvZ2dpbmcuTWVtb3J5SGFuZGxlci5sZXZlbCBzcGVjaWZpZXMgdGhlIGxldmVsIGZvciB0aGlzCisgKiB7QGNvZGUgSGFuZGxlcn0sIGRlZmF1bHRzIHRvIHtAY29kZSBMZXZlbC5BTEx9LjwvbGk+CisgKiA8bGk+amF2YS51dGlsLmxvZ2dpbmcuTWVtb3J5SGFuZGxlci5wdXNoIHNwZWNpZmllcyB0aGUgcHVzaCBsZXZlbCwgZGVmYXVsdHMKKyAqIHRvIGxldmVsLlNFVkVSRS48L2xpPgorICogPGxpPmphdmEudXRpbC5sb2dnaW5nLk1lbW9yeUhhbmRsZXIuc2l6ZSBzcGVjaWZpZXMgdGhlIGJ1ZmZlciBzaXplIGluIG51bWJlcgorICogb2Yge0Bjb2RlIExvZ1JlY29yZH0sIGRlZmF1bHRzIHRvIDEwMDAuPC9saT4KKyAqIDxsaT5qYXZhLnV0aWwubG9nZ2luZy5NZW1vcnlIYW5kbGVyLnRhcmdldCBzcGVjaWZpZXMgdGhlIGNsYXNzIG9mIHRoZSB0YXJnZXQKKyAqIHtAY29kZSBIYW5kbGVyfSwgbm8gZGVmYXVsdCB2YWx1ZSwgd2hpY2ggbWVhbnMgdGhpcyBwcm9wZXJ0eSBtdXN0IGJlCisgKiBzcGVjaWZpZWQgZWl0aGVyIGJ5IHByb3BlcnR5IHNldHRpbmcgb3IgYnkgY29uc3RydWN0b3IuPC9saT4KKyAqIDwvdWw+CisgKi8KK3B1YmxpYyBjbGFzcyBNZW1vcnlIYW5kbGVyIGV4dGVuZHMgSGFuZGxlciB7CisKKyAgICAvLyBkZWZhdWx0IG1heGltdW0gYnVmZmVyZWQgbnVtYmVyIG9mIExvZ1JlY29yZAorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1NJWkUgPSAxMDAwOworCisgICAgLy8gdGFyZ2V0IGhhbmRsZXIKKyAgICBwcml2YXRlIEhhbmRsZXIgdGFyZ2V0OworCisgICAgLy8gYnVmZmVyIHNpemUKKyAgICBwcml2YXRlIGludCBzaXplID0gREVGQVVMVF9TSVpFOworCisgICAgLy8gcHVzaCBsZXZlbAorICAgIHByaXZhdGUgTGV2ZWwgcHVzaCA9IExldmVsLlNFVkVSRTsKKworICAgIC8vIExvZ01hbmFnZXIgaW5zdGFuY2UgZm9yIGNvbnZlbmllbmNlCisgICAgcHJpdmF0ZSBmaW5hbCBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKworICAgIC8vIGJ1ZmZlcgorICAgIHByaXZhdGUgTG9nUmVjb3JkW10gYnVmZmVyOworCisgICAgLy8gY3VycmVudCBwb3NpdGlvbiBpbiBidWZmZXIKKyAgICBwcml2YXRlIGludCBjdXJzb3I7CisKKyAgICAvKioKKyAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLCBjb25zdHJ1Y3QgYW5kIGluaXQgYSB7QGNvZGUgTWVtb3J5SGFuZGxlcn0gdXNpbmcKKyAgICAgKiB7QGNvZGUgTG9nTWFuYWdlcn0gcHJvcGVydGllcyBvciBkZWZhdWx0IHZhbHVlcy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHByb3BlcnR5IHZhbHVlIGFyZSBpbnZhbGlkIGFuZCBubyBkZWZhdWx0IHZhbHVlIGNvdWxkIGJlCisgICAgICogICAgICAgICAgICAgdXNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWVtb3J5SGFuZGxlcigpIHsKKyAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9IHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCk7CisgICAgICAgIC8vIGluaXQgdGFyZ2V0CisgICAgICAgIGZpbmFsIFN0cmluZyB0YXJnZXROYW1lID0gbWFuYWdlci5nZXRQcm9wZXJ0eShjbGFzc05hbWUgKyAiLnRhcmdldCIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3NMb2FkZXIgbG9hZGVyID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgICAgIGlmIChsb2FkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGxvYWRlciA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBDbGFzczw/PiB0YXJnZXRDbGFzcyA9IGxvYWRlci5sb2FkQ2xhc3ModGFyZ2V0TmFtZSk7CisgICAgICAgICAgICB0YXJnZXQgPSAoSGFuZGxlcikgdGFyZ2V0Q2xhc3MubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJDYW5ub3QgbG9hZCB0YXJnZXQgaGFuZGxlciAnIiArIHRhcmdldE5hbWUgKyAiJyIpOworICAgICAgICB9CisgICAgICAgIC8vIGluaXQgc2l6ZQorICAgICAgICBTdHJpbmcgc2l6ZVN0cmluZyA9IG1hbmFnZXIuZ2V0UHJvcGVydHkoY2xhc3NOYW1lICsgIi5zaXplIik7CisgICAgICAgIGlmIChzaXplU3RyaW5nICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2l6ZSA9IEludGVnZXIucGFyc2VJbnQoc2l6ZVN0cmluZyk7CisgICAgICAgICAgICAgICAgaWYgKHNpemUgPD0gMCkgeworICAgICAgICAgICAgICAgICAgICBzaXplID0gREVGQVVMVF9TSVpFOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgcHJpbnRJbnZhbGlkUHJvcE1lc3NhZ2UoY2xhc3NOYW1lICsgIi5zaXplIiwgc2l6ZVN0cmluZywgZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gaW5pdCBwdXNoIGxldmVsCisgICAgICAgIFN0cmluZyBwdXNoTmFtZSA9IG1hbmFnZXIuZ2V0UHJvcGVydHkoY2xhc3NOYW1lICsgIi5wdXNoIik7CisgICAgICAgIGlmIChwdXNoTmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHB1c2ggPSBMZXZlbC5wYXJzZShwdXNoTmFtZSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHByaW50SW52YWxpZFByb3BNZXNzYWdlKGNsYXNzTmFtZSArICIucHVzaCIsIHB1c2hOYW1lLCBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBpbml0IG90aGVyIHByb3BlcnRpZXMgd2hpY2ggYXJlIGNvbW1vbiBmb3IgYWxsIEhhbmRsZXIKKyAgICAgICAgaW5pdFByb3BlcnRpZXMoIkFMTCIsIG51bGwsICJqYXZhLnV0aWwubG9nZ2luZy5TaW1wbGVGb3JtYXR0ZXIiLCBudWxsKTsKKyAgICAgICAgYnVmZmVyID0gbmV3IExvZ1JlY29yZFtzaXplXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYW5kIGluaXQgYSB7QGNvZGUgTWVtb3J5SGFuZGxlcn0gdXNpbmcgZ2l2ZW4gdGFyZ2V0LCBzaXplIGFuZAorICAgICAqIHB1c2ggbGV2ZWwsIG90aGVyIHByb3BlcnRpZXMgdXNpbmcge0Bjb2RlIExvZ01hbmFnZXJ9IHByb3BlcnRpZXMgb3IKKyAgICAgKiBkZWZhdWx0IHZhbHVlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YXJnZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBnaXZlbiB7QGNvZGUgSGFuZGxlcn0gdG8gb3V0cHV0CisgICAgICogQHBhcmFtIHNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBidWZmZXJlZCB7QGNvZGUgTG9nUmVjb3JkfSwgZ3JlYXRlciB0aGFuCisgICAgICogICAgICAgICAgICB6ZXJvCisgICAgICogQHBhcmFtIHB1c2hMZXZlbAorICAgICAqICAgICAgICAgICAgdGhlIHB1c2ggbGV2ZWwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBzaXplIDw9IDB9CisgICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgcHJvcGVydHkgdmFsdWUgYXJlIGludmFsaWQgYW5kIG5vIGRlZmF1bHQgdmFsdWUgY291bGQgYmUKKyAgICAgKiAgICAgICAgICAgICB1c2VkLgorICAgICAqLworICAgIHB1YmxpYyBNZW1vcnlIYW5kbGVyKEhhbmRsZXIgdGFyZ2V0LCBpbnQgc2l6ZSwgTGV2ZWwgcHVzaExldmVsKSB7CisgICAgICAgIGlmIChzaXplIDw9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInNpemUgPD0gMCIpOworICAgICAgICB9CisgICAgICAgIHRhcmdldC5nZXRMZXZlbCgpOworICAgICAgICBwdXNoTGV2ZWwuaW50VmFsdWUoKTsKKyAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7CisgICAgICAgIHRoaXMuc2l6ZSA9IHNpemU7CisgICAgICAgIHRoaXMucHVzaCA9IHB1c2hMZXZlbDsKKyAgICAgICAgaW5pdFByb3BlcnRpZXMoIkFMTCIsIG51bGwsICJqYXZhLnV0aWwubG9nZ2luZy5TaW1wbGVGb3JtYXR0ZXIiLCBudWxsKTsKKyAgICAgICAgYnVmZmVyID0gbmV3IExvZ1JlY29yZFtzaXplXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZSB0aGlzIGhhbmRsZXIgYW5kIHRhcmdldCBoYW5kbGVyLCBmcmVlIGFsbCBhc3NvY2lhdGVkIHJlc291cmNlcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICAgICAgbWFuYWdlci5jaGVja0FjY2VzcygpOworICAgICAgICB0YXJnZXQuY2xvc2UoKTsKKyAgICAgICAgc2V0TGV2ZWwoTGV2ZWwuT0ZGKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxsIHRhcmdldCBoYW5kbGVyIHRvIGZsdXNoIGFueSBidWZmZXJlZCBvdXRwdXQuIE5vdGUgdGhhdCB0aGlzIGRvZXNuJ3QKKyAgICAgKiBjYXVzZSB0aGlzIHtAY29kZSBNZW1vcnlIYW5kbGVyfSB0byBwdXNoLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgeworICAgICAgICB0YXJnZXQuZmx1c2goKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQdXQgYSBnaXZlbiB7QGNvZGUgTG9nUmVjb3JkfSBpbnRvIGludGVybmFsIGJ1ZmZlci4gSWYgZ2l2ZW4gcmVjb3JkIGlzCisgICAgICogbm90IGxvZ2dhYmxlLCBqdXN0IHJldHVybi4gT3RoZXJ3aXNlIGl0IGlzIHN0b3JlZCBpbiB0aGUgYnVmZmVyLgorICAgICAqIEZ1cnRoZXJtb3JlIGlmIHRoZSByZWNvcmQncyBsZXZlbCBpcyBub3QgbGVzcyB0aGFuIHRoZSBwdXNoIGxldmVsLCB0aGUKKyAgICAgKiBwdXNoIGFjdGlvbiBpcyB0cmlnZ2VyZWQgdG8gb3V0cHV0IGFsbCB0aGUgYnVmZmVyZWQgcmVjb3JkcyB0byB0aGUgdGFyZ2V0CisgICAgICogaGFuZGxlciwgYW5kIHRoZSB0YXJnZXQgaGFuZGxlciB3aWxsIHB1Ymxpc2ggdGhlbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWNvcmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2cgcmVjb3JkCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBwdWJsaXNoKExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgaWYgKCFpc0xvZ2dhYmxlKHJlY29yZCkpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAoY3Vyc29yID49IHNpemUpIHsKKyAgICAgICAgICAgIGN1cnNvciA9IDA7CisgICAgICAgIH0KKyAgICAgICAgYnVmZmVyW2N1cnNvcisrXSA9IHJlY29yZDsKKyAgICAgICAgaWYgKHJlY29yZC5nZXRMZXZlbCgpLmludFZhbHVlKCkgPj0gcHVzaC5pbnRWYWx1ZSgpKSB7CisgICAgICAgICAgICBwdXNoKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHB1c2ggbGV2ZWwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwdXNoIGxldmVsCisgICAgICovCisgICAgcHVibGljIExldmVsIGdldFB1c2hMZXZlbCgpIHsKKyAgICAgICAgcmV0dXJuIHB1c2g7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgaWYgZ2l2ZW4ge0Bjb2RlIExvZ1JlY29yZH0gd291bGQgYmUgcHV0IGludG8gdGhpcworICAgICAqIHtAY29kZSBNZW1vcnlIYW5kbGVyfSdzIGludGVybmFsIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZ2l2ZW4ge0Bjb2RlIExvZ1JlY29yZH0gaXMgbG9nZ2FibGUgaWYgYW5kIG9ubHkgaWYgaXQgaGFzIGFwcHJvcHJpYXRlCisgICAgICogbGV2ZWwgYW5kIGl0IHBhc3MgYW55IGFzc29jaWF0ZWQgZmlsdGVyJ3MgY2hlY2suCisgICAgICogPHA+CisgICAgICogTm90ZSB0aGF0IHRoZSBwdXNoIGxldmVsIGlzIG5vdCB1c2VkIGZvciB0aGlzIGNoZWNrLgorICAgICAqCisgICAgICogQHBhcmFtIHJlY29yZAorICAgICAqICAgICAgICAgICAgdGhlIGdpdmVuIHtAY29kZSBMb2dSZWNvcmR9CisgICAgICogQHJldHVybiB0aGUgZ2l2ZW4ge0Bjb2RlIExvZ1JlY29yZH0gaWYgaXQgc2hvdWxkIGJlIGxvZ2dlZCwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgaWYge0Bjb2RlIExvZ1JlY29yZH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzTG9nZ2FibGUoTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICByZXR1cm4gc3VwZXIuaXNMb2dnYWJsZShyZWNvcmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyaWdnZXJzIGEgcHVzaCBhY3Rpb24gdG8gb3V0cHV0IGFsbCBidWZmZXJlZCByZWNvcmRzIHRvIHRoZSB0YXJnZXQgaGFuZGxlciwKKyAgICAgKiBhbmQgdGhlIHRhcmdldCBoYW5kbGVyIHdpbGwgcHVibGlzaCB0aGVtLiBUaGVuIHRoZSBidWZmZXIgaXMgY2xlYXJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXNoKCkgeworICAgICAgICBmb3IgKGludCBpID0gY3Vyc29yOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYnVmZmVyW2ldICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0YXJnZXQucHVibGlzaChidWZmZXJbaV0pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnVmZmVyW2ldID0gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGN1cnNvcjsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYnVmZmVyW2ldICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0YXJnZXQucHVibGlzaChidWZmZXJbaV0pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnVmZmVyW2ldID0gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBjdXJzb3IgPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgcHVzaCBsZXZlbC4gVGhlIHB1c2ggbGV2ZWwgaXMgdXNlZCB0byBjaGVjayB0aGUgcHVzaCBhY3Rpb24KKyAgICAgKiB0cmlnZ2VyaW5nLiBXaGVuIGEgbmV3IHtAY29kZSBMb2dSZWNvcmR9IGlzIHB1dCBpbnRvIHRoZSBpbnRlcm5hbAorICAgICAqIGJ1ZmZlciBhbmQgaXRzIGxldmVsIGlzIG5vdCBsZXNzIHRoYW4gdGhlIHB1c2ggbGV2ZWwsIHRoZSBwdXNoIGFjdGlvbgorICAgICAqIHdpbGwgYmUgdHJpZ2dlcmVkLiBOb3RlIHRoYXQgc2V0IG5ldyBwdXNoIGxldmVsIHdvbid0IHRyaWdnZXIgcHVzaCBhY3Rpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3TGV2ZWwKKyAgICAgKiAgICAgICAgICAgICAgICAgdGhlIG5ldyBsZXZlbCB0byBzZXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UHVzaExldmVsKExldmVsIG5ld0xldmVsKSB7CisgICAgICAgIG1hbmFnZXIuY2hlY2tBY2Nlc3MoKTsKKyAgICAgICAgbmV3TGV2ZWwuaW50VmFsdWUoKTsKKyAgICAgICAgdGhpcy5wdXNoID0gbmV3TGV2ZWw7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL1NpbXBsZUZvcm1hdHRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL1NpbXBsZUZvcm1hdHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIyNTI3ZTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvU2ltcGxlRm9ybWF0dGVyLmphdmEKQEAgLTAsMCArMSw2OSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmxvZ2dpbmc7CisKK2ltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOworaW1wb3J0IGphdmEuaW8uU3RyaW5nV3JpdGVyOworaW1wb3J0IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0OworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKKworLyoqCisgKiB7QGNvZGUgU2ltcGxlRm9ybWF0dGVyfSBjYW4gYmUgdXNlZCB0byBwcmludCBhIHN1bW1hcnkgb2YgdGhlIGluZm9ybWF0aW9uCisgKiBjb250YWluZWQgaW4gYSB7QGNvZGUgTG9nUmVjb3JkfSBvYmplY3QgaW4gYSBodW1hbiByZWFkYWJsZSBmb3JtYXQuCisgKi8KK3B1YmxpYyBjbGFzcyBTaW1wbGVGb3JtYXR0ZXIgZXh0ZW5kcyBGb3JtYXR0ZXIgeworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFNpbXBsZUZvcm1hdHRlcn0uCisgICAgICovCisgICAgcHVibGljIFNpbXBsZUZvcm1hdHRlcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyBhIHtAbGluayBMb2dSZWNvcmR9IG9iamVjdCBpbnRvIGEgaHVtYW4gcmVhZGFibGUgc3RyaW5nCisgICAgICogcmVwcmVzZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgICAgdGhlIGxvZyByZWNvcmQgdG8gYmUgZm9ybWF0dGVkIGludG8gYSBzdHJpbmcuCisgICAgICogQHJldHVybiB0aGUgZm9ybWF0dGVkIHN0cmluZy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdChMb2dSZWNvcmQgcikgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgc2IuYXBwZW5kKE1lc3NhZ2VGb3JtYXQuZm9ybWF0KCJ7MCwgZGF0ZX0gezAsIHRpbWV9ICIsCisgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmV3IERhdGUoci5nZXRNaWxsaXMoKSkgfSkpOworICAgICAgICBzYi5hcHBlbmQoci5nZXRTb3VyY2VDbGFzc05hbWUoKSkuYXBwZW5kKCIgIik7CisgICAgICAgIHNiLmFwcGVuZChyLmdldFNvdXJjZU1ldGhvZE5hbWUoKSkuYXBwZW5kKFN5c3RlbS5saW5lU2VwYXJhdG9yKCkpOworICAgICAgICBzYi5hcHBlbmQoci5nZXRMZXZlbCgpLmdldE5hbWUoKSkuYXBwZW5kKCI6ICIpOworICAgICAgICBzYi5hcHBlbmQoZm9ybWF0TWVzc2FnZShyKSkuYXBwZW5kKFN5c3RlbS5saW5lU2VwYXJhdG9yKCkpOworICAgICAgICBpZiAoci5nZXRUaHJvd24oKSAhPSBudWxsKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIlRocm93YWJsZSBvY2N1cnJlZDogIik7CisgICAgICAgICAgICBUaHJvd2FibGUgdCA9IHIuZ2V0VGhyb3duKCk7CisgICAgICAgICAgICBQcmludFdyaXRlciBwdyA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFN0cmluZ1dyaXRlciBzdyA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKKyAgICAgICAgICAgICAgICBwdyA9IG5ldyBQcmludFdyaXRlcihzdyk7CisgICAgICAgICAgICAgICAgdC5wcmludFN0YWNrVHJhY2UocHcpOworICAgICAgICAgICAgICAgIHNiLmFwcGVuZChzdy50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkocHcpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9Tb2NrZXRIYW5kbGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvU29ja2V0SGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg1YTllNmMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvU29ja2V0SGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsMTU3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwubG9nZ2luZzsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CisKKy8qKgorICogQSBoYW5kbGVyIHRoYXQgd3JpdGVzIGxvZyBtZXNzYWdlcyB0byBhIHNvY2tldCBjb25uZWN0aW9uLgorICogPHA+CisgKiBUaGlzIGhhbmRsZXIgcmVhZHMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzIGZyb20gdGhlIGxvZyBtYW5hZ2VyIHRvCisgKiBpbml0aWFsaXplIGl0c2VsZjoKKyAqIDx1bD4KKyAqIDxsaT5qYXZhLnV0aWwubG9nZ2luZy5Db25zb2xlSGFuZGxlci5sZXZlbCBzcGVjaWZpZXMgdGhlIGxvZ2dpbmcgbGV2ZWwsCisgKiBkZWZhdWx0cyB0byB7QGNvZGUgTGV2ZWwuQUxMfSBpZiB0aGlzIHByb3BlcnR5IGlzIG5vdCBmb3VuZCBvciBoYXMgYW4gaW52YWxpZAorICogdmFsdWUuCisgKiA8bGk+amF2YS51dGlsLmxvZ2dpbmcuU29ja2V0SGFuZGxlci5maWx0ZXIgc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBmaWx0ZXIKKyAqIGNsYXNzIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGhhbmRsZXIsIGRlZmF1bHRzIHRvIHtAY29kZSBudWxsfSBpZiB0aGlzCisgKiBwcm9wZXJ0eSBpcyBub3QgZm91bmQgb3IgaGFzIGFuIGludmFsaWQgdmFsdWUuCisgKiA8bGk+amF2YS51dGlsLmxvZ2dpbmcuU29ja2V0SGFuZGxlci5mb3JtYXR0ZXIgc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZQorICogZm9ybWF0dGVyIGNsYXNzIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGhhbmRsZXIsIGRlZmF1bHRzIHRvCisgKiB7QGNvZGUgamF2YS51dGlsLmxvZ2dpbmcuWE1MRm9ybWF0dGVyfSBpZiB0aGlzIHByb3BlcnR5IGlzIG5vdCBmb3VuZCBvciBoYXMKKyAqIGFuIGludmFsaWQgdmFsdWUuCisgKiA8bGk+amF2YS51dGlsLmxvZ2dpbmcuU29ja2V0SGFuZGxlci5lbmNvZGluZyBzcGVjaWZpZXMgdGhlIGVuY29kaW5nIHRoaXMKKyAqIGhhbmRsZXIgd2lsbCB1c2UgdG8gZW5jb2RlIGxvZyBtZXNzYWdlcywgZGVmYXVsdHMgdG8ge0Bjb2RlIG51bGx9IGlmIHRoaXMKKyAqIHByb3BlcnR5IGlzIG5vdCBmb3VuZCBvciBoYXMgYW4gaW52YWxpZCB2YWx1ZS4KKyAqIDxsaT5qYXZhLnV0aWwubG9nZ2luZy5Tb2NrZXRIYW5kbGVyLmhvc3Qgc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBob3N0IHRoYXQKKyAqIHRoaXMgaGFuZGxlciBzaG91bGQgY29ubmVjdCB0by4gVGhlcmUncyBubyBkZWZhdWx0IHZhbHVlIGZvciB0aGlzIHByb3BlcnR5LgorICogPGxpPmphdmEudXRpbC5sb2dnaW5nLlNvY2tldEhhbmRsZXIuZW5jb2Rpbmcgc3BlY2lmaWVzIHRoZSBwb3J0IG51bWJlciB0aGF0CisgKiB0aGlzIGhhbmRsZXIgc2hvdWxkIGNvbm5lY3QgdG8uIFRoZXJlJ3Mgbm8gZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcyBwcm9wZXJ0eS4KKyAqIDwvdWw+CisgKiA8cD4KKyAqIFRoaXMgaGFuZGxlciBidWZmZXJzIHRoZSBvdXRnb2luZyBtZXNzYWdlcywgYnV0IGZsdXNoZXMgZWFjaCB0aW1lIGEgbG9nCisgKiByZWNvcmQgaGFzIGJlZW4gcHVibGlzaGVkLgorICogPHA+CisgKiBUaGlzIGNsYXNzIGlzIG5vdCB0aHJlYWQtc2FmZS4KKyAqLworcHVibGljIGNsYXNzIFNvY2tldEhhbmRsZXIgZXh0ZW5kcyBTdHJlYW1IYW5kbGVyIHsKKworICAgIC8vIGRlZmF1bHQgbGV2ZWwKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9MRVZFTCA9ICJBTEwiOworCisgICAgLy8gZGVmYXVsdCBmb3JtYXR0ZXIKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9GT1JNQVRURVIgPSAiamF2YS51dGlsLmxvZ2dpbmcuWE1MRm9ybWF0dGVyIjsKKworICAgIC8vIHRoZSBzb2NrZXQgY29ubmVjdGlvbgorICAgIHByaXZhdGUgU29ja2V0IHNvY2tldDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgU29ja2V0SGFuZGxlcn0gb2JqZWN0IHVzaW5nIHRoZSBwcm9wZXJ0aWVzIHJlYWQgYnkKKyAgICAgKiB0aGUgbG9nIG1hbmFnZXIsIGluY2x1ZGluZyB0aGUgaG9zdCBuYW1lIGFuZCBwb3J0IG51bWJlci4gRGVmYXVsdAorICAgICAqIGZvcm1hdHRpbmcgdXNlcyB0aGUgWE1MRm9ybWF0dGVyIGNsYXNzIGFuZCBsZXZlbCBpcyBzZXQgdG8gQUxMLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGZhaWxlZCB0byBjb25uZWN0IHRvIHRoZSBzcGVjaWZpZWQgaG9zdCBhbmQgcG9ydC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBob3N0IG5hbWUgb3IgcG9ydCBudW1iZXIgaXMgaWxsZWdhbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU29ja2V0SGFuZGxlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKERFRkFVTFRfTEVWRUwsIG51bGwsIERFRkFVTFRfRk9STUFUVEVSLCBudWxsKTsKKyAgICAgICAgaW5pdFNvY2tldChMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKS5nZXRQcm9wZXJ0eSgKKyAgICAgICAgICAgICAgICAiamF2YS51dGlsLmxvZ2dpbmcuU29ja2V0SGFuZGxlci5ob3N0IiksIExvZ01hbmFnZXIKKyAgICAgICAgICAgICAgICAuZ2V0TG9nTWFuYWdlcigpLmdldFByb3BlcnR5KAorICAgICAgICAgICAgICAgICAgICAgICAgImphdmEudXRpbC5sb2dnaW5nLlNvY2tldEhhbmRsZXIucG9ydCIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIFNvY2tldEhhbmRsZXJ9IG9iamVjdCB1c2luZyB0aGUgc3BlY2lmaWVkIGhvc3QgbmFtZQorICAgICAqIGFuZCBwb3J0IG51bWJlciB0b2dldGhlciB3aXRoIG90aGVyIHByb3BlcnRpZXMgcmVhZCBieSB0aGUgbG9nIG1hbmFnZXIuCisgICAgICogRGVmYXVsdCBmb3JtYXR0aW5nIHVzZXMgdGhlIFhNTEZvcm1hdHRlciBjbGFzcyBhbmQgbGV2ZWwgaXMgc2V0IHRvIEFMTC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3N0CisgICAgICogICAgICAgICAgICB0aGUgaG9zdCBuYW1lCisgICAgICogQHBhcmFtIHBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IG51bWJlcgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBmYWlsZWQgdG8gY29ubmVjdCB0byB0aGUgc3BlY2lmaWVkIGhvc3QgYW5kIHBvcnQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaG9zdCBuYW1lIG9yIHBvcnQgbnVtYmVyIGlzIGlsbGVnYWwuCisgICAgICovCisgICAgcHVibGljIFNvY2tldEhhbmRsZXIoU3RyaW5nIGhvc3QsIGludCBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihERUZBVUxUX0xFVkVMLCBudWxsLCBERUZBVUxUX0ZPUk1BVFRFUiwgbnVsbCk7CisgICAgICAgIGluaXRTb2NrZXQoaG9zdCwgU3RyaW5nLnZhbHVlT2YocG9ydCkpOworICAgIH0KKworICAgIC8vIEluaXRpYWxpemUgdGhlIHNvY2tldCBjb25uZWN0aW9uIGFuZCBwcmVwYXJlIHRoZSBvdXRwdXQgc3RyZWFtCisgICAgcHJpdmF0ZSB2b2lkIGluaXRTb2NrZXQoU3RyaW5nIGhvc3QsIFN0cmluZyBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBjaGVjayB0aGUgdmFsaWRpdHkgb2YgdGhlIGhvc3QgbmFtZQorICAgICAgICBpZiAoaG9zdCA9PSBudWxsIHx8IGhvc3QuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJob3N0ID09IG51bGwgfHwgaG9zdC5pc0VtcHR5KCkiKTsKKyAgICAgICAgfQorICAgICAgICAvLyBjaGVjayB0aGUgdmFsaWRpdHkgb2YgdGhlIHBvcnQgbnVtYmVyCisgICAgICAgIGludCBwID0gMDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHAgPSBJbnRlZ2VyLnBhcnNlSW50KHBvcnQpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSWxsZWdhbCBwb3J0IGFyZ3VtZW50Iik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHAgPD0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSWxsZWdhbCBwb3J0IGFyZ3VtZW50Iik7CisgICAgICAgIH0KKyAgICAgICAgLy8gZXN0YWJsaXNoIHRoZSBuZXR3b3JrIGNvbm5lY3Rpb24KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoaXMuc29ja2V0ID0gbmV3IFNvY2tldChob3N0LCBwKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZ2V0RXJyb3JNYW5hZ2VyKCkuZXJyb3IoIkZhaWxlZCB0byBlc3RhYmxpc2ggdGhlIG5ldHdvcmsgY29ubmVjdGlvbiIsIGUsCisgICAgICAgICAgICAgICAgICAgIEVycm9yTWFuYWdlci5PUEVOX0ZBSUxVUkUpOworICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgfQorICAgICAgICBzdXBlci5pbnRlcm5hbFNldE91dHB1dFN0cmVhbShuZXcgQnVmZmVyZWRPdXRwdXRTdHJlYW0odGhpcy5zb2NrZXQuZ2V0T3V0cHV0U3RyZWFtKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhpcyBoYW5kbGVyLiBUaGUgbmV0d29yayBjb25uZWN0aW9uIHRvIHRoZSBob3N0IGlzIGFsc28gY2xvc2VkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3VwZXIuY2xvc2UoKTsKKyAgICAgICAgICAgIGlmICh0aGlzLnNvY2tldCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhpcy5zb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB0aGlzLnNvY2tldCA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBnZXRFcnJvck1hbmFnZXIoKS5lcnJvcigiRXhjZXB0aW9uIG9jY3VycmVkIHdoZW4gY2xvc2luZyB0aGUgc29ja2V0IGhhbmRsZXIiLCBlLAorICAgICAgICAgICAgICAgICAgICBFcnJvck1hbmFnZXIuQ0xPU0VfRkFJTFVSRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dzIGEgcmVjb3JkIGlmIG5lY2Vzc2FyeS4gQSBmbHVzaCBvcGVyYXRpb24gd2lsbCBiZSBkb25lIGFmdGVyd2FyZHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVjb3JkCisgICAgICogICAgICAgICAgICB0aGUgbG9nIHJlY29yZCB0byBiZSBsb2dnZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcHVibGlzaChMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgIHN1cGVyLnB1Ymxpc2gocmVjb3JkKTsKKyAgICAgICAgc3VwZXIuZmx1c2goKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvU3RyZWFtSGFuZGxlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL1N0cmVhbUhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NTgxODM1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL1N0cmVhbUhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDMyOSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLmxvZ2dpbmc7CisKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5Xcml0ZXI7CisKKy8qKgorICogQSB7QGNvZGUgU3RyZWFtSGFuZGxlcn0gb2JqZWN0IHdyaXRlcyBsb2cgbWVzc2FnZXMgdG8gYW4gb3V0cHV0IHN0cmVhbSwgdGhhdAorICogaXMsIG9iamVjdHMgb2YgdGhlIGNsYXNzIHtAbGluayBqYXZhLmlvLk91dHB1dFN0cmVhbX0uCisgKiA8cD4KKyAqIEEge0Bjb2RlIFN0cmVhbUhhbmRsZXJ9IG9iamVjdCByZWFkcyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMgZnJvbSB0aGUgbG9nCisgKiBtYW5hZ2VyIHRvIGluaXRpYWxpemUgaXRzZWxmLiBBIGRlZmF1bHQgdmFsdWUgd2lsbCBiZSB1c2VkIGlmIGEgcHJvcGVydHkgaXMKKyAqIG5vdCBmb3VuZCBvciBoYXMgYW4gaW52YWxpZCB2YWx1ZS4KKyAqIDx1bD4KKyAqIDxsaT5qYXZhLnV0aWwubG9nZ2luZy5TdHJlYW1IYW5kbGVyLmVuY29kaW5nIHNwZWNpZmllcyB0aGUgZW5jb2RpbmcgdGhpcworICogaGFuZGxlciB3aWxsIHVzZSB0byBlbmNvZGUgbG9nIG1lc3NhZ2VzLiBEZWZhdWx0IGlzIHRoZSBlbmNvZGluZyB1c2VkIGJ5IHRoZQorICogY3VycmVudCBwbGF0Zm9ybS4KKyAqIDxsaT5qYXZhLnV0aWwubG9nZ2luZy5TdHJlYW1IYW5kbGVyLmZpbHRlciBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGZpbHRlcgorICogY2xhc3MgdG8gYmUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgaGFuZGxlci4gTm8gPGNvZGU+RmlsdGVyPC9jb2RlPiBpcyB1c2VkIGJ5CisgKiBkZWZhdWx0LgorICogPGxpPmphdmEudXRpbC5sb2dnaW5nLlN0cmVhbUhhbmRsZXIuZm9ybWF0dGVyIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUKKyAqIGZvcm1hdHRlciBjbGFzcyB0byBiZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBoYW5kbGVyLiBEZWZhdWx0IGlzCisgKiB7QGNvZGUgamF2YS51dGlsLmxvZ2dpbmcuU2ltcGxlRm9ybWF0dGVyfS4KKyAqIDxsaT5qYXZhLnV0aWwubG9nZ2luZy5TdHJlYW1IYW5kbGVyLmxldmVsIHNwZWNpZmllcyB0aGUgbG9nZ2luZyBsZXZlbC4KKyAqIERlZmF1bHRzIGlzIHtAY29kZSBMZXZlbC5JTkZPfS4KKyAqIDwvdWw+CisgKiA8cD4KKyAqIFRoaXMgY2xhc3MgaXMgbm90IHRocmVhZC1zYWZlLgorICovCitwdWJsaWMgY2xhc3MgU3RyZWFtSGFuZGxlciBleHRlbmRzIEhhbmRsZXIgeworCisgICAgLy8gdGhlIG91dHB1dCBzdHJlYW0gdGhpcyBoYW5kbGVyIHdyaXRlcyB0bworICAgIHByaXZhdGUgT3V0cHV0U3RyZWFtIG9zOworCisgICAgLy8gdGhlIHdyaXRlciB0aGF0IHdyaXRlcyB0byB0aGUgb3V0cHV0IHN0cmVhbQorICAgIHByaXZhdGUgV3JpdGVyIHdyaXRlcjsKKworICAgIC8vIHRoZSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGUgd3JpdGVyIGhhcyBiZWVuIGluaXRpYWxpemVkCisgICAgcHJpdmF0ZSBib29sZWFuIHdyaXRlck5vdEluaXRpYWxpemVkOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBTdHJlYW1IYW5kbGVyfSBvYmplY3QuIFRoZSBuZXcgc3RyZWFtIGhhbmRsZXIKKyAgICAgKiBkb2VzIG5vdCBoYXZlIGFuIGFzc29jaWF0ZWQgb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyZWFtSGFuZGxlcigpIHsKKyAgICAgICAgaW5pdFByb3BlcnRpZXMoIklORk8iLCBudWxsLCAiamF2YS51dGlsLmxvZ2dpbmcuU2ltcGxlRm9ybWF0dGVyIiwgbnVsbCk7CisgICAgICAgIHRoaXMub3MgPSBudWxsOworICAgICAgICB0aGlzLndyaXRlciA9IG51bGw7CisgICAgICAgIHRoaXMud3JpdGVyTm90SW5pdGlhbGl6ZWQgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgU3RyZWFtSGFuZGxlcn0gb2JqZWN0IHdpdGggdGhlIHN1cHBsaWVkIG91dHB1dAorICAgICAqIHN0cmVhbS4gRGVmYXVsdCBwcm9wZXJ0aWVzIGFyZSByZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIG9zCisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IHN0cmVhbSB0aGlzIGhhbmRsZXIgd3JpdGVzIHRvLgorICAgICAqLworICAgIFN0cmVhbUhhbmRsZXIoT3V0cHV0U3RyZWFtIG9zKSB7CisgICAgICAgIHRoaXMoKTsKKyAgICAgICAgdGhpcy5vcyA9IG9zOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGNvZGUgU3RyZWFtSGFuZGxlcn0gb2JqZWN0LiBUaGUgc3BlY2lmaWVkIGRlZmF1bHQgdmFsdWVzCisgICAgICogd2lsbCBiZSB1c2VkIGlmIHRoZSBjb3JyZXNwb25kaW5nIHByb3BlcnRpZXMgYXJlIG5vdCBmb3VuZCBpbiB0aGUgbG9nCisgICAgICogbWFuYWdlcidzIHByb3BlcnRpZXMuCisgICAgICovCisgICAgU3RyZWFtSGFuZGxlcihTdHJpbmcgZGVmYXVsdExldmVsLCBTdHJpbmcgZGVmYXVsdEZpbHRlciwKKyAgICAgICAgICAgIFN0cmluZyBkZWZhdWx0Rm9ybWF0dGVyLCBTdHJpbmcgZGVmYXVsdEVuY29kaW5nKSB7CisgICAgICAgIGluaXRQcm9wZXJ0aWVzKGRlZmF1bHRMZXZlbCwgZGVmYXVsdEZpbHRlciwgZGVmYXVsdEZvcm1hdHRlciwKKyAgICAgICAgICAgICAgICBkZWZhdWx0RW5jb2RpbmcpOworICAgICAgICB0aGlzLm9zID0gbnVsbDsKKyAgICAgICAgdGhpcy53cml0ZXIgPSBudWxsOworICAgICAgICB0aGlzLndyaXRlck5vdEluaXRpYWxpemVkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIFN0cmVhbUhhbmRsZXJ9IG9iamVjdCB3aXRoIHRoZSBzdXBwbGllZCBvdXRwdXQgc3RyZWFtCisgICAgICogYW5kIGZvcm1hdHRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcworICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBzdHJlYW0gdGhpcyBoYW5kbGVyIHdyaXRlcyB0by4KKyAgICAgKiBAcGFyYW0gZm9ybWF0dGVyCisgICAgICogICAgICAgICAgICB0aGUgZm9ybWF0dGVyIHRoaXMgaGFuZGxlciB1c2VzIHRvIGZvcm1hdCB0aGUgb3V0cHV0LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgb3N9IG9yIHtAY29kZSBmb3JtYXR0ZXJ9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyZWFtSGFuZGxlcihPdXRwdXRTdHJlYW0gb3MsIEZvcm1hdHRlciBmb3JtYXR0ZXIpIHsKKyAgICAgICAgdGhpcygpOworICAgICAgICBpZiAob3MgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJvcyA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZvcm1hdHRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImZvcm1hdHRlciA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5vcyA9IG9zOworICAgICAgICBpbnRlcm5hbFNldEZvcm1hdHRlcihmb3JtYXR0ZXIpOworICAgIH0KKworICAgIC8vIGluaXRpYWxpemUgdGhlIHdyaXRlcgorICAgIHByaXZhdGUgdm9pZCBpbml0aWFsaXplV3JpdGVyKCkgeworICAgICAgICB0aGlzLndyaXRlck5vdEluaXRpYWxpemVkID0gZmFsc2U7CisgICAgICAgIGlmIChnZXRFbmNvZGluZygpID09IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMud3JpdGVyID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcih0aGlzLm9zKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdGhpcy53cml0ZXIgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKHRoaXMub3MsIGdldEVuY29kaW5nKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgKiBTaG91bGQgbm90IGhhcHBlbiBiZWNhdXNlIGl0J3MgY2hlY2tlZCBpbgorICAgICAgICAgICAgICAgICAqIHN1cGVyLmluaXRQcm9wZXJ0aWVzKCkuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgd3JpdGUoZ2V0Rm9ybWF0dGVyKCkuZ2V0SGVhZCh0aGlzKSk7CisgICAgfQorCisgICAgLy8gV3JpdGUgYSBzdHJpbmcgdG8gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlKFN0cmluZyBzKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGlzLndyaXRlci53cml0ZShzKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGdldEVycm9yTWFuYWdlcigpLmVycm9yKCJFeGNlcHRpb24gb2NjdXJyZWQgd2hlbiB3cml0aW5nIHRvIHRoZSBvdXRwdXQgc3RyZWFtIiwgZSwKKyAgICAgICAgICAgICAgICAgICAgRXJyb3JNYW5hZ2VyLldSSVRFX0ZBSUxVUkUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgb3V0cHV0IHN0cmVhbSB0aGlzIGhhbmRsZXIgd3JpdGVzIHRvLiBOb3RlIGl0IGRvZXMgbm90aGluZyBlbHNlLgorICAgICAqCisgICAgICogQHBhcmFtIG5ld09zCisgICAgICogICAgICAgICAgICB0aGUgbmV3IG91dHB1dCBzdHJlYW0KKyAgICAgKi8KKyAgICB2b2lkIGludGVybmFsU2V0T3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBuZXdPcykgeworICAgICAgICB0aGlzLm9zID0gbmV3T3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgb3V0cHV0IHN0cmVhbSB0aGlzIGhhbmRsZXIgd3JpdGVzIHRvLiBJZiB0aGVyZSdzIGFuIGV4aXN0aW5nCisgICAgICogb3V0cHV0IHN0cmVhbSwgdGhlIHRhaWwgc3RyaW5nIG9mIHRoZSBhc3NvY2lhdGVkIGZvcm1hdHRlciB3aWxsIGJlCisgICAgICogd3JpdHRlbiB0byBpdC4gVGhlbiBpdCB3aWxsIGJlIGZsdXNoZWQsIGNsb3NlZCBhbmQgcmVwbGFjZWQgd2l0aAorICAgICAqIHtAY29kZSBvc30uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIG9zfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0T3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvcykgeworICAgICAgICBpZiAob3MgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCkuY2hlY2tBY2Nlc3MoKTsKKyAgICAgICAgY2xvc2UodHJ1ZSk7CisgICAgICAgIHRoaXMud3JpdGVyID0gbnVsbDsKKyAgICAgICAgdGhpcy5vcyA9IG9zOworICAgICAgICB0aGlzLndyaXRlck5vdEluaXRpYWxpemVkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgdXNlZCBieSB0aGlzIGhhbmRsZXIuIEEge0Bjb2RlIG51bGx9IHZhbHVlCisgICAgICogaW5kaWNhdGVzIHRoYXQgdGhlIGRlZmF1bHQgZW5jb2Rpbmcgc2hvdWxkIGJlIHVzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgdG8gc2V0LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmcgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgcnVudGltZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gZmx1c2ggZmlyc3QgYmVmb3JlIHNldCBuZXcgZW5jb2RpbmcKKyAgICAgICAgdGhpcy5mbHVzaCgpOworICAgICAgICBzdXBlci5zZXRFbmNvZGluZyhlbmNvZGluZyk7CisgICAgICAgIC8vIHJlbmV3IHdyaXRlciBvbmx5IGlmIHRoZSB3cml0ZXIgZXhpc3RzCisgICAgICAgIGlmICh0aGlzLndyaXRlciAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoZ2V0RW5jb2RpbmcoKSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhpcy53cml0ZXIgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKHRoaXMub3MpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICB0aGlzLndyaXRlciA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIodGhpcy5vcywgZ2V0RW5jb2RpbmcoKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICAgICAqIFNob3VsZCBub3QgaGFwcGVuIGJlY2F1c2UgaXQncyBjaGVja2VkIGluCisgICAgICAgICAgICAgICAgICAgICAqIHN1cGVyLmluaXRQcm9wZXJ0aWVzKCkuCisgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgaGFuZGxlciwgYnV0IHRoZSB1bmRlcmx5aW5nIG91dHB1dCBzdHJlYW0gaXMgb25seSBjbG9zZWQgaWYKKyAgICAgKiB7QGNvZGUgY2xvc2VTdHJlYW19IGlzIHtAY29kZSB0cnVlfS4gU2VjdXJpdHkgaXMgbm90IGNoZWNrZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2xvc2VTdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHdoZXRoZXIgdG8gY2xvc2UgdGhlIHVuZGVybHlpbmcgb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICB2b2lkIGNsb3NlKGJvb2xlYW4gY2xvc2VTdHJlYW0pIHsKKyAgICAgICAgaWYgKHRoaXMub3MgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKHRoaXMud3JpdGVyTm90SW5pdGlhbGl6ZWQpIHsKKyAgICAgICAgICAgICAgICBpbml0aWFsaXplV3JpdGVyKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB3cml0ZShnZXRGb3JtYXR0ZXIoKS5nZXRUYWlsKHRoaXMpKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdGhpcy53cml0ZXIuZmx1c2goKTsKKyAgICAgICAgICAgICAgICBpZiAoY2xvc2VTdHJlYW0pIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy53cml0ZXIuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy53cml0ZXIgPSBudWxsOworICAgICAgICAgICAgICAgICAgICB0aGlzLm9zID0gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGdldEVycm9yTWFuYWdlcigpLmVycm9yKCJFeGNlcHRpb24gb2NjdXJyZWQgd2hlbiBjbG9zaW5nIHRoZSBvdXRwdXQgc3RyZWFtIiwgZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEVycm9yTWFuYWdlci5DTE9TRV9GQUlMVVJFKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGlzIGhhbmRsZXIuIFRoZSB0YWlsIHN0cmluZyBvZiB0aGUgZm9ybWF0dGVyIGFzc29jaWF0ZWQgd2l0aAorICAgICAqIHRoaXMgaGFuZGxlciBpcyB3cml0dGVuIG91dC4gQSBmbHVzaCBvcGVyYXRpb24gYW5kIGEgc3Vic2VxdWVudCBjbG9zZQorICAgICAqIG9wZXJhdGlvbiBpcyB0aGVuIHBlcmZvcm1lZCB1cG9uIHRoZSBvdXRwdXQgc3RyZWFtLiBDbGllbnQgYXBwbGljYXRpb25zCisgICAgICogc2hvdWxkIG5vdCB1c2UgYSBoYW5kbGVyIGFmdGVyIGNsb3NpbmcgaXQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgIExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpLmNoZWNrQWNjZXNzKCk7CisgICAgICAgIGNsb3NlKHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZsdXNoZXMgYW55IGJ1ZmZlcmVkIG91dHB1dC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHsKKyAgICAgICAgaWYgKHRoaXMub3MgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAodGhpcy53cml0ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0aGlzLndyaXRlci5mbHVzaCgpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMub3MuZmx1c2goKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGdldEVycm9yTWFuYWdlcigpLmVycm9yKCJFeGNlcHRpb24gb2NjdXJyZWQgd2hlbiBmbHVzaGluZyB0aGUgb3V0cHV0IHN0cmVhbSIsCisgICAgICAgICAgICAgICAgICAgICAgICBlLCBFcnJvck1hbmFnZXIuRkxVU0hfRkFJTFVSRSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBY2NlcHRzIGEgbG9nZ2luZyByZXF1ZXN0LiBUaGUgbG9nIHJlY29yZCBpcyBmb3JtYXR0ZWQgYW5kIHdyaXR0ZW4gdG8gdGhlCisgICAgICogb3V0cHV0IHN0cmVhbSBpZiB0aGUgZm9sbG93aW5nIHRocmVlIGNvbmRpdGlvbnMgYXJlIG1ldDoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPnRoZSBzdXBwbGllZCBsb2cgcmVjb3JkIGhhcyBhdCBsZWFzdCB0aGUgcmVxdWlyZWQgbG9nZ2luZyBsZXZlbDsKKyAgICAgKiA8bGk+dGhlIHN1cHBsaWVkIGxvZyByZWNvcmQgcGFzc2VzIHRoZSBmaWx0ZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMKKyAgICAgKiBoYW5kbGVyLCBpZiBhbnk7CisgICAgICogPGxpPnRoZSBvdXRwdXQgc3RyZWFtIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGhhbmRsZXIgaXMgbm90IHtAY29kZSBudWxsfS4KKyAgICAgKiA8L3VsPgorICAgICAqIElmIGl0IGlzIHRoZSBmaXJzdCB0aW1lIGEgbG9nIHJlY29yZCBpcyB3cml0dGVuIG91dCwgdGhlIGhlYWQgc3RyaW5nIG9mCisgICAgICogdGhlIGZvcm1hdHRlciBhc3NvY2lhdGVkIHdpdGggdGhpcyBoYW5kbGVyIGlzIHdyaXR0ZW4gb3V0IGZpcnN0LgorICAgICAqCisgICAgICogQHBhcmFtIHJlY29yZAorICAgICAqICAgICAgICAgICAgdGhlIGxvZyByZWNvcmQgdG8gYmUgbG9nZ2VkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBwdWJsaXNoKExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICh0aGlzLmlzTG9nZ2FibGUocmVjb3JkKSkgeworICAgICAgICAgICAgICAgIGlmICh0aGlzLndyaXRlck5vdEluaXRpYWxpemVkKSB7CisgICAgICAgICAgICAgICAgICAgIGluaXRpYWxpemVXcml0ZXIoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IG51bGw7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgbXNnID0gZ2V0Rm9ybWF0dGVyKCkuZm9ybWF0KHJlY29yZCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZ2V0RXJyb3JNYW5hZ2VyKCkuZXJyb3IoIkV4Y2VwdGlvbiBvY2N1cnJlZCB3aGVuIGZvcm1hdHRpbmcgdGhlIGxvZyByZWNvcmQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUsIEVycm9yTWFuYWdlci5GT1JNQVRfRkFJTFVSRSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHdyaXRlKG1zZyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBnZXRFcnJvck1hbmFnZXIoKS5lcnJvcigiRXhjZXB0aW9uIG9jY3VycmVkIHdoZW4gbG9nZ2luZyB0aGUgcmVjb3JkIiwgZSwKKyAgICAgICAgICAgICAgICAgICAgRXJyb3JNYW5hZ2VyLkdFTkVSSUNfRkFJTFVSRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHN1cHBsaWVkIGxvZyByZWNvcmQgbmVlZHMgdG8gYmUgbG9nZ2VkLiBUaGUKKyAgICAgKiBsb2dnaW5nIGxldmVscyBhcmUgY2hlY2tlZCBhcyB3ZWxsIGFzIHRoZSBmaWx0ZXIuIFRoZSBvdXRwdXQgc3RyZWFtIG9mCisgICAgICogdGhpcyBoYW5kbGVyIGlzIGFsc28gY2hlY2tlZC4gSWYgaXQgaXMge0Bjb2RlIG51bGx9LCB0aGlzIG1ldGhvZCByZXR1cm5zCisgICAgICoge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiA8cD4KKyAgICAgKiBOb3RpY2UgOiBDYXNlIG9mIG5vIG91dHB1dCBzdHJlYW0gd2lsbCByZXR1cm4ge0Bjb2RlIGZhbHNlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWNvcmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2cgcmVjb3JkIHRvIGJlIGNoZWNrZWQuCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIHJlY29yZH0gbmVlZHMgdG8gYmUgbG9nZ2VkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNMb2dnYWJsZShMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgIGlmIChyZWNvcmQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLm9zICE9IG51bGwgJiYgc3VwZXIuaXNMb2dnYWJsZShyZWNvcmQpKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL1hNTEZvcm1hdHRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9sb2dnaW5nL1hNTEZvcm1hdHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBkODBiM2UKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvWE1MRm9ybWF0dGVyLmphdmEKQEAgLTAsMCArMSwxODAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5sb2dnaW5nOworCitpbXBvcnQgamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQ7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOworCisvKioKKyAqIEZvcm1hdHRlciB0byBjb252ZXJ0IGEge0BsaW5rIExvZ1JlY29yZH0gaW50byBhbiBYTUwgc3RyaW5nLiBUaGUgRFRECisgKiBzcGVjaWZpZWQgaW4gQXBwZW5kaXggQSB0byB0aGUgSmF2YSBMb2dnaW5nIEFQSXMgc3BlY2lmaWNhdGlvbiBpcyB1c2VkLgorICoge0Bjb2RlIFhNTEZvcm1hdHRlcn0gdXNlcyB0aGUgb3V0cHV0IGhhbmRsZXIncyBlbmNvZGluZyBpZiBpdCBpcyBzcGVjaWZpZWQsCisgKiBvdGhlcndpc2UgdGhlIGRlZmF1bHQgcGxhdGZvcm0gZW5jb2RpbmcgaXMgdXNlZCBpbnN0ZWFkLiBVVEYtOCBpcyB0aGUKKyAqIHJlY29tbWVuZGVkIGVuY29kaW5nLgorICovCitwdWJsaWMgY2xhc3MgWE1MRm9ybWF0dGVyIGV4dGVuZHMgRm9ybWF0dGVyIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBpbmRlbnQgPSAiICAgICI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBYTUxGb3JtYXR0ZXJ9LgorICAgICAqLworICAgIHB1YmxpYyBYTUxGb3JtYXR0ZXIoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgYSB7QGNvZGUgTG9nUmVjb3JkfSBpbnRvIGFuIFhNTCBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgICAgdGhlIGxvZyByZWNvcmQgdG8gYmUgZm9ybWF0dGVkLgorICAgICAqIEByZXR1cm4gdGhlIGxvZyByZWNvcmQgZm9ybWF0dGVkIGFzIGFuIFhNTCBzdHJpbmcuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBmb3JtYXQoTG9nUmVjb3JkIHIpIHsKKyAgICAgICAgLy8gY2FsbCBhIG1ldGhvZCBvZiBMb2dSZWNvcmQgdG8gZW5zdXJlIG5vdCBudWxsCisgICAgICAgIGxvbmcgdGltZSA9IHIuZ2V0TWlsbGlzKCk7CisgICAgICAgIC8vIGZvcm1hdCB0byBkYXRlCisgICAgICAgIFN0cmluZyBkYXRlID0gTWVzc2FnZUZvcm1hdC5mb3JtYXQoInswLCBkYXRlfSB7MCwgdGltZX0iLCBuZXcgT2JqZWN0W10geyBuZXcgRGF0ZSh0aW1lKSB9KTsKKyAgICAgICAgU3RyaW5nIG5sID0gU3lzdGVtLmxpbmVTZXBhcmF0b3IoKTsKKworICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgc2IuYXBwZW5kKCI8cmVjb3JkPiIpLmFwcGVuZChubCk7CisgICAgICAgIGFwcGVuZChzYiwgMSwgImRhdGUiLCBkYXRlKTsKKyAgICAgICAgYXBwZW5kKHNiLCAxLCAibWlsbGlzIiwgdGltZSk7CisgICAgICAgIGFwcGVuZChzYiwgMSwgInNlcXVlbmNlIiwgci5nZXRTZXF1ZW5jZU51bWJlcigpKTsKKyAgICAgICAgaWYgKHIuZ2V0TG9nZ2VyTmFtZSgpICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFwcGVuZChzYiwgMSwgImxvZ2dlciIsIHIuZ2V0TG9nZ2VyTmFtZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhcHBlbmQoc2IsIDEsICJsZXZlbCIsIHIuZ2V0TGV2ZWwoKS5nZXROYW1lKCkpOworICAgICAgICBpZiAoci5nZXRTb3VyY2VDbGFzc05hbWUoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBhcHBlbmQoc2IsIDEsICJjbGFzcyIsIHIuZ2V0U291cmNlQ2xhc3NOYW1lKCkpOworICAgICAgICB9CisgICAgICAgIGlmIChyLmdldFNvdXJjZU1ldGhvZE5hbWUoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBhcHBlbmQoc2IsIDEsICJtZXRob2QiLCByLmdldFNvdXJjZU1ldGhvZE5hbWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXBwZW5kKHNiLCAxLCAidGhyZWFkIiwgci5nZXRUaHJlYWRJRCgpKTsKKyAgICAgICAgZm9ybWF0TWVzc2FnZXMociwgc2IpOworICAgICAgICBPYmplY3RbXSBwYXJhbXMgPSByLmdldFBhcmFtZXRlcnMoKTsKKyAgICAgICAgaWYgKHBhcmFtcyAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKE9iamVjdCBlbGVtZW50IDogcGFyYW1zKSB7CisgICAgICAgICAgICAgICAgYXBwZW5kKHNiLCAxLCAicGFyYW0iLCBlbGVtZW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmb3JtYXRUaHJvd2FibGUociwgc2IpOworICAgICAgICBzYi5hcHBlbmQoIjwvcmVjb3JkPiIpLmFwcGVuZChubCk7CisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBmb3JtYXRNZXNzYWdlcyhMb2dSZWNvcmQgciwgU3RyaW5nQnVpbGRlciBzYikgeworICAgICAgICAvLyBnZXQgbG9jYWxpemVkIG1lc3NhZ2UgaWYgaGFzLCBidXQgZG9uJ3QgY2FsbCBGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZQorICAgICAgICAvLyB0byBwYXJzZSBwYXR0ZXJuIHN0cmluZworICAgICAgICBSZXNvdXJjZUJ1bmRsZSByYiA9IHIuZ2V0UmVzb3VyY2VCdW5kbGUoKTsKKyAgICAgICAgU3RyaW5nIHBhdHRlcm4gPSByLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgaWYgKHJiICE9IG51bGwgJiYgcGF0dGVybiAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgbWVzc2FnZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbWVzc2FnZSA9IHJiLmdldFN0cmluZyhwYXR0ZXJuKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChtZXNzYWdlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBtZXNzYWdlID0gcGF0dGVybjsKKyAgICAgICAgICAgICAgICBhcHBlbmQoc2IsIDEsICJtZXNzYWdlIiwgbWVzc2FnZSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFwcGVuZChzYiwgMSwgIm1lc3NhZ2UiLCBtZXNzYWdlKTsKKyAgICAgICAgICAgICAgICBhcHBlbmQoc2IsIDEsICJrZXkiLCBwYXR0ZXJuKTsKKyAgICAgICAgICAgICAgICBhcHBlbmQoc2IsIDEsICJjYXRhbG9nIiwgci5nZXRSZXNvdXJjZUJ1bmRsZU5hbWUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAocGF0dGVybiAhPSBudWxsKSB7CisgICAgICAgICAgICBhcHBlbmQoc2IsIDEsICJtZXNzYWdlIiwgcGF0dGVybik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoaW5kZW50KS5hcHBlbmQoIjxtZXNzYWdlLz4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBmb3JtYXRUaHJvd2FibGUoTG9nUmVjb3JkIHIsIFN0cmluZ0J1aWxkZXIgc2IpIHsKKyAgICAgICAgVGhyb3dhYmxlIHQ7CisgICAgICAgIGlmICgodCA9IHIuZ2V0VGhyb3duKCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN0cmluZyBubCA9IFN5c3RlbS5saW5lU2VwYXJhdG9yKCk7CisgICAgICAgICAgICBzYi5hcHBlbmQoaW5kZW50KS5hcHBlbmQoIjxleGNlcHRpb24+IikuYXBwZW5kKG5sKTsKKyAgICAgICAgICAgIGFwcGVuZChzYiwgMiwgIm1lc3NhZ2UiLCB0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgLy8gZm9ybWF0IHRocm93YWJsZSdzIHN0YWNrIHRyYWNlCisgICAgICAgICAgICBTdGFja1RyYWNlRWxlbWVudFtdIGVsZW1lbnRzID0gdC5nZXRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmb3IgKFN0YWNrVHJhY2VFbGVtZW50IGUgOiBlbGVtZW50cykgeworICAgICAgICAgICAgICAgIHNiLmFwcGVuZChpbmRlbnQpLmFwcGVuZChpbmRlbnQpLmFwcGVuZCgiPGZyYW1lPiIpLmFwcGVuZChubCk7CisgICAgICAgICAgICAgICAgYXBwZW5kKHNiLCAzLCAiY2xhc3MiLCBlLmdldENsYXNzTmFtZSgpKTsKKyAgICAgICAgICAgICAgICBhcHBlbmQoc2IsIDMsICJtZXRob2QiLCBlLmdldE1ldGhvZE5hbWUoKSk7CisgICAgICAgICAgICAgICAgYXBwZW5kKHNiLCAzLCAibGluZSIsIGUuZ2V0TGluZU51bWJlcigpKTsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoaW5kZW50KS5hcHBlbmQoaW5kZW50KS5hcHBlbmQoIjwvZnJhbWU+IikuYXBwZW5kKG5sKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNiLmFwcGVuZChpbmRlbnQpLmFwcGVuZCgiPC9leGNlcHRpb24+IikuYXBwZW5kKG5sKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYXBwZW5kKFN0cmluZ0J1aWxkZXIgc2IsIGludCBpbmRlbnRDb3VudCwgU3RyaW5nIHRhZywgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5kZW50Q291bnQ7ICsraSkgeworICAgICAgICAgICAgc2IuYXBwZW5kKGluZGVudCk7CisgICAgICAgIH0KKyAgICAgICAgc2IuYXBwZW5kKCI8IikuYXBwZW5kKHRhZykuYXBwZW5kKCI+Iik7CisgICAgICAgIHNiLmFwcGVuZCh2YWx1ZSk7CisgICAgICAgIHNiLmFwcGVuZCgiPC8iKS5hcHBlbmQodGFnKS5hcHBlbmQoIj4iKTsKKyAgICAgICAgc2IuYXBwZW5kKFN5c3RlbS5saW5lU2VwYXJhdG9yKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhlYWRlciBzdHJpbmcgZm9yIGEgc2V0IG9mIGxvZyByZWNvcmRzIGZvcm1hdHRlZCBhcyBYTUwKKyAgICAgKiBzdHJpbmdzLCB1c2luZyB0aGUgb3V0cHV0IGhhbmRsZXIncyBlbmNvZGluZyBpZiBpdCBpcyBkZWZpbmVkLCBvdGhlcndpc2UKKyAgICAgKiB1c2luZyB0aGUgZGVmYXVsdCBwbGF0Zm9ybSBlbmNvZGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBoCisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IGhhbmRsZXIsIG1heSBiZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHJldHVybiB0aGUgaGVhZGVyIHN0cmluZyBmb3IgbG9nIHJlY29yZHMgZm9ybWF0dGVkIGFzIFhNTCBzdHJpbmdzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0SGVhZChIYW5kbGVyIGgpIHsKKyAgICAgICAgU3RyaW5nIGVuY29kaW5nID0gbnVsbDsKKyAgICAgICAgaWYgKGggIT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSBoLmdldEVuY29kaW5nKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIGVuY29kaW5nID0gU3lzdGVtLmdldFByb3BlcnR5KCJmaWxlLmVuY29kaW5nIik7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIHNiLmFwcGVuZCgiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiIikuYXBwZW5kKGVuY29kaW5nKS5hcHBlbmQoIlwiIHN0YW5kYWxvbmU9XCJub1wiPz4iKTsKKyAgICAgICAgc2IuYXBwZW5kKFN5c3RlbS5saW5lU2VwYXJhdG9yKCkpOworICAgICAgICBzYi5hcHBlbmQoIjwhRE9DVFlQRSBsb2cgU1lTVEVNIFwibG9nZ2VyLmR0ZFwiPiIpOworICAgICAgICBzYi5hcHBlbmQoU3lzdGVtLmxpbmVTZXBhcmF0b3IoKSk7CisgICAgICAgIHNiLmFwcGVuZCgiPGxvZz4iKTsKKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGFpbCBzdHJpbmcgZm9yIGEgc2V0IG9mIGxvZyByZWNvcmRzIGZvcm1hdHRlZCBhcyBYTUwKKyAgICAgKiBzdHJpbmdzLgorICAgICAqCisgICAgICogQHBhcmFtIGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdXRwdXQgaGFuZGxlciwgbWF5IGJlIHtAY29kZSBudWxsfS4KKyAgICAgKiBAcmV0dXJuIHRoZSB0YWlsIHN0cmluZyBmb3IgbG9nIHJlY29yZHMgZm9ybWF0dGVkIGFzIFhNTCBzdHJpbmdzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFpbChIYW5kbGVyIGgpIHsKKyAgICAgICAgcmV0dXJuICI8L2xvZz4iOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvbG9nZ2luZy9sb2dnaW5nLnByb3BlcnRpZXMgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvbG9nZ2luZy5wcm9wZXJ0aWVzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY5OWZlM2YKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL2xvZ2dpbmcvbG9nZ2luZy5wcm9wZXJ0aWVzCkBAIC0wLDAgKzEsNjUgQEAKKyMgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisjIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorIyB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisjIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisjICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisjIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjIAorIyAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjIAorIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorIworCisjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjIERlZmF1bHQgbG9nZ2luZyBwcm9wZXJ0eSBmaWxlLgorIyBUaGlzIGZpbGUgaXMgdXNlZCBieSBqYXZhLnV0aWwubG9nZ2luZyBwYWNrYWdlIGFzIGRlZmF1bHQgc2V0dGluZ3MsIHVzZXJzIGNhbgorIyBzcGVjaWZ5IGFub3RoZXIgZmlsZSBpbnN0ZWFkIHdpdGggamF2YS51dGlsLmxvZ2dpbmcuY29uZmlnLmZpbGUgc3lzdGVtIAorIyBwcm9wZXJ0eSwgdGhpcyBwcm9wZXJ0eSBjYW4gYmUgc2V0IHZpYSB0aGUgUHJlZmVyZW5jZSBBUEksIG9yIGFzIFZNIGFyZ3VtZW50cyAKKyMgcGFzc2VkIHRvICJqYXZhIiBjb21tYW5kLCBvciBhcyBwcm9wZXJ0eSBkZWZpbml0aW9uIHBhc3NlZCB0byBKTklfQ3JlYXRlSmF2YVZNLiAKKyMgWW91IGNhbiByZWZlciB0byBKYXZhRG9jIG9mIGphdmEudXRpbC5sb2dnaW5nIHBhY2thZ2UgZm9yIG1vcmUgaW5mb3JtYXRpb24KKyMgYWJvdXQgdGhpcyBmaWxlLgorIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjIEdsb2JhbCBzZXR0aW5ncworIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjIFNwZWNpZnkgZGVmYXVsdCBsZXZlbCBmb3IgZ2xvYmFsIGxvZ2dlciwgdGhlIGV2ZW50IHdob3NlIGxldmVsIGlzIGJlbG93IHdvbid0CisjIGJlIGxvZ2dlZC4gWW91IGNhbiBzcGVjaWZ5IGxldmVsIGZvciBldmVyeSBsb2dnZXIsIG90aGVyd2lzZSB0aGUgbGV2ZWwgb2YgcGFyZW50IAorIyBsb2dnZXIgd2lsbCBiZSB1c2VkLiBZb3UgY2FuIGFsc28gc2V0IHRoZSBsZXZlbCBmb3IgZXZlcnkgaGFuZGxlciwgYXMgYmVsb3cgZm9yIAorIyBqYXZhLnV0aWwubG9nZ2luZy5Db25zb2xlSGFuZGxlci4KKy5sZXZlbD1JTkZPCisKKyMgU3BlY2lmeSBoYW5kbGVyIGNsYXNzZXMgbGlzdCwgdGhlc2UgY2xhc3NlcyB3aWxsIGJlIGluc3RhbnRpYXRlZCBkdXJpbmcgdGhlIAorIyBsb2dnaW5nIGZyYW1ld29yayBpbml0aWFsaXphdGlvbi4gVGhlIGxpc3Qgc2hvdWxkIGJlIHdoaXRlIHNwYWNlIHNlcGFyYXRlZC4KKyMgRm9yIGV4YW1wbGUsIHVzZSB0aGUgbGluZSBiZWxvdyB0byBhZGQgU29ja2V0SGFuZGxlci4gTm90ZSB0aGF0IHRoZSBoYW5kbGVyCisjIGNsYXNzZXMgbXVzdCBiZSBpbiB0aGUgY2xhc3NwYXRoLgorIworIyBoYW5kbGVycz1qYXZhLnV0aWwubG9nZ2luZy5Db25zb2xlSGFuZGxlciBqYXZhLnV0aWwubG9nZ2luZy5Tb2NrZXRIYW5kbGVyCisjCitoYW5kbGVycz1qYXZhLnV0aWwubG9nZ2luZy5Db25zb2xlSGFuZGxlcgorCisjIFNwZWNpZnkgYSBjbGFzcyBuYW1lcyBsaXN0LCB0aGVzZSBjbGFzc2VzJyBkZWZhdWx0IGNvbnN0cnVjdG9yIHdpbGwgYmUgZXhlY3V0ZWQgCisjIGR1cmluZyBsb2dnaW5nIHBhY2thZ2UgaW5pdGlhbGl6YXRpb24sIHdoaWNoIG1heSBjb250YWluIHNvbWUgY29kZSB0byBzZXQgdGhlIAorIyBsb2dnaW5nIGNvbmZpZ3VyYXRpb24uIFRoZSBsaXN0IHNob3VsZCBiZSB3aGl0ZSBzcGFjZSBzZXBhcmF0ZWQsIGFuZCB0aGUgCisjIGNsYXNzZXMgbXVzdCBiZSBpbiB0aGUgY2xhc3NwYXRoLgorIworIyBjb25maWc9CisKKworIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIyBIYW5kbGVyIHNldHRpbmdzCisjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyMgVGhlIHByb3BlcnRpZXMgYmVsb3cgYXJlIHNhbXBsZXMgZm9yIGhhbmRsZXIgc2V0dGluZ3MuCisjamF2YS51dGlsLmxvZ2dpbmcuQ29uc29sZUhhbmRsZXIuZm9ybWF0dGVyPWphdmEudXRpbC5sb2dnaW5nLlNpbXBsZUZvcm1hdHRlcgorI2phdmEudXRpbC5sb2dnaW5nLkNvbnNvbGVIYW5kbGVyLmxldmVsPUlORk8KKyNqYXZhLnV0aWwubG9nZ2luZy5GaWxlSGFuZGxlci5saW1pdD0xMDAwMDAKKyNqYXZhLnV0aWwubG9nZ2luZy5GaWxlSGFuZGxlci5jb3VudD0xCisjamF2YS51dGlsLmxvZ2dpbmcuRmlsZUhhbmRsZXIuZm9ybWF0dGVyPWphdmEudXRpbC5sb2dnaW5nLlhNTEZvcm1hdHRlcgorI2phdmEudXRpbC5sb2dnaW5nLkZpbGVIYW5kbGVyLnBhdHRlcm49JWgvamF2YSV1LmxvZworIApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9wcmVmcy9BYnN0cmFjdFByZWZlcmVuY2VzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL0Fic3RyYWN0UHJlZmVyZW5jZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kODZkNzg5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9wcmVmcy9BYnN0cmFjdFByZWZlcmVuY2VzLmphdmEKQEAgLTAsMCArMSw5MDIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLnByZWZzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyOworaW1wb3J0IGphdmEudXRpbC5FdmVudE9iamVjdDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlU2V0OworaW1wb3J0IGxpYmNvcmUuaW8uQmFzZTY0OworaW1wb3J0IGxpYmNvcmUudXRpbC5FbXB0eUFycmF5OworCisvKioKKyAqIFRoaXMgYWJzdHJhY3QgY2xhc3MgaXMgYSBwYXJ0aWFsIGltcGxlbWVudGF0aW9uIG9mIHRoZSBhYnN0cmFjdCBjbGFzcworICogUHJlZmVyZW5jZXMsIHdoaWNoIGNhbiBiZSB1c2VkIHRvIHNpbXBsaWZ5IHtAY29kZSBQcmVmZXJlbmNlc30gcHJvdmlkZXIncworICogaW1wbGVtZW50YXRpb24uIFRoaXMgY2xhc3MgZGVmaW5lcyBuaW5lIGFic3RyYWN0IFNQSSBtZXRob2RzLCB3aGljaCBtdXN0IGJlCisgKiBpbXBsZW1lbnRlZCBieSBhIHByZWZlcmVuY2UgcHJvdmlkZXIuCisgKgorICogQHNpbmNlIDEuNAorICogQHNlZSBQcmVmZXJlbmNlcworICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RQcmVmZXJlbmNlcyBleHRlbmRzIFByZWZlcmVuY2VzIHsKKyAgICAvKgorICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICogQ2xhc3MgZmllbGRzCisgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAgKi8KKyAgICAvKiogdGhlIHVuaGFuZGxlZCBldmVudHMgY29sbGVjdGlvbiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIExpc3Q8RXZlbnRPYmplY3Q+IGV2ZW50cyA9IG5ldyBMaW5rZWRMaXN0PEV2ZW50T2JqZWN0PigpOworICAgIC8qKiB0aGUgZXZlbnQgZGlzcGF0Y2hlciB0aHJlYWQgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFdmVudERpc3BhdGNoZXIgZGlzcGF0Y2hlciA9IG5ldyBFdmVudERpc3BhdGNoZXIoIlByZWZlcmVuY2UgRXZlbnQgRGlzcGF0Y2hlciIpOworCisgICAgLyoKKyAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAqIENsYXNzIGluaXRpYWxpemVyCisgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAgKi8KKyAgICBzdGF0aWMgeworICAgICAgICBkaXNwYXRjaGVyLnNldERhZW1vbih0cnVlKTsKKyAgICAgICAgZGlzcGF0Y2hlci5zdGFydCgpOworICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5hZGRTaHV0ZG93bkhvb2sobmV3IFRocmVhZCgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIFByZWZlcmVuY2VzIHVyb290ID0gUHJlZmVyZW5jZXMudXNlclJvb3QoKTsKKyAgICAgICAgICAgICAgICBQcmVmZXJlbmNlcyBzcm9vdCA9IFByZWZlcmVuY2VzLnN5c3RlbVJvb3QoKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICB1cm9vdC5mbHVzaCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzcm9vdC5mbHVzaCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAqIEluc3RhbmNlIGZpZWxkcyAocGFja2FnZS1wcml2YXRlKQorICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICovCisgICAgLyoqIHRydWUgaWYgdGhpcyBub2RlIGlzIGluIHVzZXIgcHJlZmVyZW5jZSBoaWVyYXJjaHkgKi8KKyAgICBib29sZWFuIHVzZXJOb2RlOworCisgICAgLyoKKyAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAqIEluc3RhbmNlIGZpZWxkcyAocHJpdmF0ZSkKKyAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAqLworICAgIC8qKgorICAgICAqIFRoZSBvYmplY3QgdXNlZCB0byBsb2NrIHRoaXMgbm9kZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgT2JqZWN0IGxvY2s7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGZpZWxkIGlzIHRydWUgaWYgdGhpcyBub2RlIGlzIGNyZWF0ZWQgd2hpbGUgaXQgZG9lc24ndCBleGlzdCBpbiB0aGUKKyAgICAgKiBiYWNraW5nIHN0b3JlLiBUaGlzIGZpZWxkJ3MgZGVmYXVsdCB2YWx1ZSBpcyBmYWxzZSwgYW5kIGl0IGlzIGNoZWNrZWQKKyAgICAgKiB3aGVuIHRoZSBub2RlIGNyZWF0aW9uIGlzIGNvbXBsZXRlZCwgYW5kIGlmIGl0IGlzIHRydWUsIHRoZSBub2RlIGNoYW5nZQorICAgICAqIGV2ZW50IHdpbGwgYmUgZmlyZWQgZm9yIHRoaXMgbm9kZSdzIHBhcmVudC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBuZXdOb2RlOworCisgICAgLyoqIGNhY2hlZCBjaGlsZCBub2RlcyAqLworICAgIHByaXZhdGUgTWFwPFN0cmluZywgQWJzdHJhY3RQcmVmZXJlbmNlcz4gY2FjaGVkTm9kZTsKKworICAgIC8vdGhlIGNvbGxlY3Rpb25zIG9mIGxpc3RlbmVycworICAgIHByaXZhdGUgTGlzdDxFdmVudExpc3RlbmVyPiBub2RlQ2hhbmdlTGlzdGVuZXJzOworICAgIHByaXZhdGUgTGlzdDxFdmVudExpc3RlbmVyPiBwcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXJzOworCisgICAgLy90aGlzIG5vZGUncyBuYW1lCisgICAgcHJpdmF0ZSBTdHJpbmcgbm9kZU5hbWU7CisKKyAgICAvL2hhbmRsZXIgdG8gdGhpcyBub2RlJ3MgcGFyZW50CisgICAgcHJpdmF0ZSBBYnN0cmFjdFByZWZlcmVuY2VzIHBhcmVudFByZWY7CisKKyAgICAvL3RydWUgaWYgdGhpcyBub2RlIGhhcyBiZWVuIHJlbW92ZWQKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNSZW1vdmVkOworCisgICAgLy9oYW5kbGVyIHRvIHRoaXMgbm9kZSdzIHJvb3Qgbm9kZQorICAgIHByaXZhdGUgQWJzdHJhY3RQcmVmZXJlbmNlcyByb290OworCisgICAgLyoKKyAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAqIENvbnN0cnVjdG9ycworICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICovCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgQWJzdHJhY3RQcmVmZXJlbmNlc30gaW5zdGFuY2UgdXNpbmcgdGhlIGdpdmVuCisgICAgICogcGFyZW50IG5vZGUgYW5kIG5vZGUgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJlbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJlbnQgbm9kZSBvZiB0aGUgbmV3IG5vZGUgb3Ige0Bjb2RlIG51bGx9IHRvIGluZGljYXRlCisgICAgICogICAgICAgICAgICB0aGF0IHRoZSBuZXcgbm9kZSBpcyBhIHJvb3Qgbm9kZS4KKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIG5ldyBub2RlIG9yIGFuIGVtcHR5IHN0cmluZyB0byBpbmRpY2F0ZSB0aGF0CisgICAgICogICAgICAgICAgICB0aGlzIG5vZGUgaXMgY2FsbGVkICJyb290Ii4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBuYW1lIGNvbnRhaW5zIGEgc2xhc2ggY2hhcmFjdGVyIG9yIGlzIGVtcHR5IGlmIHtAY29kZQorICAgICAqICAgICAgICAgICAgIHBhcmVudH0gaXMgbm90IHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQWJzdHJhY3RQcmVmZXJlbmNlcyhBYnN0cmFjdFByZWZlcmVuY2VzIHBhcmVudCwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgaWYgKChwYXJlbnQgPT0gbnVsbCBeIG5hbWUubGVuZ3RoKCkgPT0gMCkgfHwgbmFtZS5pbmRleE9mKCIvIikgPj0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJvb3QgPSAocGFyZW50ID09IG51bGwpID8gdGhpcyA6IHBhcmVudC5yb290OworICAgICAgICBub2RlQ2hhbmdlTGlzdGVuZXJzID0gbmV3IExpbmtlZExpc3Q8RXZlbnRMaXN0ZW5lcj4oKTsKKyAgICAgICAgcHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVycyA9IG5ldyBMaW5rZWRMaXN0PEV2ZW50TGlzdGVuZXI+KCk7CisgICAgICAgIGlzUmVtb3ZlZCA9IGZhbHNlOworICAgICAgICBjYWNoZWROb2RlID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBBYnN0cmFjdFByZWZlcmVuY2VzPigpOworICAgICAgICBub2RlTmFtZSA9IG5hbWU7CisgICAgICAgIHBhcmVudFByZWYgPSBwYXJlbnQ7CisgICAgICAgIGxvY2sgPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIHVzZXJOb2RlID0gcm9vdC51c2VyTm9kZTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICogTWV0aG9kcworICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICovCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBhbGwgY2FjaGVkIGNoaWxkIG5vZGVzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2YgY2FjaGVkIGNoaWxkIG5vZGVzLgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBBYnN0cmFjdFByZWZlcmVuY2VzW10gY2FjaGVkQ2hpbGRyZW4oKSB7CisgICAgICAgIHJldHVybiBjYWNoZWROb2RlLnZhbHVlcygpLnRvQXJyYXkobmV3IEFic3RyYWN0UHJlZmVyZW5jZXNbY2FjaGVkTm9kZS5zaXplKCldKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjaGlsZCBub2RlIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIG9yIHtAY29kZSBudWxsfSBpZiBpdAorICAgICAqIGRvZXNuJ3QgZXhpc3QuIEltcGxlbWVudGVycyBjYW4gYXNzdW1lIHRoYXQgdGhlIG5hbWUgc3VwcGxpZWQgdG8gdGhpcworICAgICAqIG1ldGhvZCB3aWxsIGJlIGEgdmFsaWQgbm9kZSBuYW1lIHN0cmluZyAoY29uZm9ybWluZyB0byB0aGUgbm9kZSBuYW1pbmcKKyAgICAgKiBmb3JtYXQpIGFuZCB3aWxsIG5vdCBjb3JyZXNwb25kIHRvIGEgbm9kZSB0aGF0IGhhcyBiZWVuIGNhY2hlZCBvcgorICAgICAqIHJlbW92ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGRlc2lyZWQgY2hpbGQgbm9kZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBjaGlsZCBub2RlIHdpdGggdGhlIGdpdmVuIG5hbWUgb3Ige0Bjb2RlIG51bGx9IGlmIGl0IGRvZXNuJ3QKKyAgICAgKiAgICAgICAgIGV4aXN0LgorICAgICAqIEB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGJhY2tpbmcgc3RvcmUgaXMgdW5hdmFpbGFibGUgb3IgY2F1c2VzIGFuIG9wZXJhdGlvbgorICAgICAqICAgICAgICAgICAgIGZhaWx1cmUuCisgICAgICovCisgICAgcHJvdGVjdGVkIEFic3RyYWN0UHJlZmVyZW5jZXMgZ2V0Q2hpbGQoU3RyaW5nIG5hbWUpCisgICAgICAgICAgICB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBjaGVja1N0YXRlKCk7CisgICAgICAgICAgICBBYnN0cmFjdFByZWZlcmVuY2VzIHJlc3VsdCA9IG51bGw7CisgICAgICAgICAgICBTdHJpbmdbXSBjaGlsZHJlbk5hbWVzID0gY2hpbGRyZW5OYW1lcygpOworICAgICAgICAgICAgZm9yIChTdHJpbmcgY2hpbGRyZW5OYW1lIDogY2hpbGRyZW5OYW1lcykgeworICAgICAgICAgICAgICAgIGlmIChjaGlsZHJlbk5hbWUuZXF1YWxzKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNoaWxkU3BpKG5hbWUpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBub2RlIGhhcyBiZWVuIHJlbW92ZWQgYnkgaW52b2tpbmcgdGhlIG1ldGhvZCB7QGNvZGUKKyAgICAgKiByZW1vdmVOb2RlKCl9LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0sIGlmIHRoaXMgbm9kZSBoYXMgYmVlbiByZW1vdmVkLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNSZW1vdmVkKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIHJldHVybiBpc1JlbW92ZWQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIGNoYW5nZXMgb2YgdGhpcyBub2RlIHRvIHRoZSBiYWNraW5nIHN0b3JlLiBUaGlzIG1ldGhvZCBzaG91bGQKKyAgICAgKiBvbmx5IGZsdXNoIHRoaXMgbm9kZSBhbmQgc2hvdWxkIG5vdCBpbmNsdWRlIHRoZSBkZXNjZW5kYW50IG5vZGVzLiBBbnkKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiB0aGF0IHdhbnRzIHRvIHByb3ZpZGUgZnVuY3Rpb25hbGl0eSB0byBmbHVzaCBhbGwgbm9kZXMKKyAgICAgKiBhdCBvbmNlIHNob3VsZCBvdmVycmlkZSB0aGUgbWV0aG9kIHtAbGluayAjZmx1c2goKSBmbHVzaCgpfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGJhY2tpbmcgc3RvcmUgaXMgdW5hdmFpbGFibGUgb3IgY2F1c2VzIGFuIG9wZXJhdGlvbgorICAgICAqICAgICAgICAgICAgIGZhaWx1cmUuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgZmx1c2hTcGkoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZXMgb2YgYWxsIG9mIHRoZSBjaGlsZCBub2RlcyBvZiB0aGlzIG5vZGUgb3IgYW4gZW1wdHkKKyAgICAgKiBhcnJheSBpZiB0aGlzIG5vZGUgaGFzIG5vIGNoaWxkcmVuLiBUaGUgbmFtZXMgb2YgY2FjaGVkIGNoaWxkcmVuIGFyZSBub3QKKyAgICAgKiByZXF1aXJlZCB0byBiZSByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWVzIG9mIHRoaXMgbm9kZSdzIGNoaWxkcmVuLgorICAgICAqIEB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGJhY2tpbmcgc3RvcmUgaXMgdW5hdmFpbGFibGUgb3IgY2F1c2VzIGFuIG9wZXJhdGlvbgorICAgICAqICAgICAgICAgICAgIGZhaWx1cmUuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IFN0cmluZ1tdIGNoaWxkcmVuTmFtZXNTcGkoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2hpbGQgcHJlZmVyZW5jZSBub2RlIHdpdGggdGhlIGdpdmVuIG5hbWUsIGNyZWF0aW5nIGl0CisgICAgICogaWYgaXQgZG9lcyBub3QgZXhpc3QuIFRoZSBjYWxsZXIgb2YgdGhpcyBtZXRob2Qgc2hvdWxkIGVuc3VyZSB0aGF0IHRoZQorICAgICAqIGdpdmVuIG5hbWUgaXMgdmFsaWQgYW5kIHRoYXQgdGhpcyBub2RlIGhhcyBub3QgYmVlbiByZW1vdmVkIG9yIGNhY2hlZC4KKyAgICAgKiBJZiB0aGUgbmFtZWQgbm9kZSBoYXMganVzdCBiZWVuIHJlbW92ZWQsIHRoZSBpbXBsZW1lbnRhdGlvbgorICAgICAqIG9mIHRoaXMgbWV0aG9kIG11c3QgY3JlYXRlIGEgbmV3IG9uZSBpbnN0ZWFkIG9mIHJlYWN0aXZhdGluZyB0aGUgcmVtb3ZlZAorICAgICAqIG9uZS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbmV3IGNyZWF0aW9uIGlzIG5vdCByZXF1aXJlZCB0byBiZSBwZXJzaXN0ZWQgaW1tZWRpYXRlbHkgdW50aWwgdGhlCisgICAgICogZmx1c2ggbWV0aG9kIHdpbGwgYmUgaW52b2tlZC4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGNoaWxkIHByZWZlcmVuY2UgdG8gYmUgcmV0dXJuZWQuCisgICAgICogQHJldHVybiB0aGUgY2hpbGQgcHJlZmVyZW5jZSBub2RlLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBBYnN0cmFjdFByZWZlcmVuY2VzIGNoaWxkU3BpKFN0cmluZyBuYW1lKTsKKworCisgICAgLyoqCisgICAgICogUHV0cyB0aGUgZ2l2ZW4ga2V5LXZhbHVlIHBhaXIgaW50byB0aGlzIG5vZGUuIENhbGxlciBvZiB0aGlzIG1ldGhvZAorICAgICAqIHNob3VsZCBlbnN1cmUgdGhhdCBib3RoIG9mIHRoZSBnaXZlbiB2YWx1ZXMgYXJlIHZhbGlkIGFuZCB0aGF0IHRoaXMKKyAgICAgKiBub2RlIGhhcyBub3QgYmVlbiByZW1vdmVkLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBnaXZlbiBwcmVmZXJlbmNlIGtleS4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBnaXZlbiBwcmVmZXJlbmNlIHZhbHVlLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIHB1dFNwaShTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHByZWZlcmVuY2UgdmFsdWUgbWFwcGVkIHRvIHRoZSBnaXZlbiBrZXkuIFRoZSBjYWxsZXIgb2YgdGhpcworICAgICAqIG1ldGhvZCBzaG91bGQgZW5zdXJlIHRoYXQgdGhlIGdpdmVuIGtleSBpcyB2YWxpZCBhbmQgdGhhdCB0aGlzIG5vZGUgaGFzCisgICAgICogbm90IGJlZW4gcmVtb3ZlZC4gVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCB0aHJvdyBhbnkgZXhjZXB0aW9ucyBidXQgaWYgaXQKKyAgICAgKiBkb2VzLCB0aGUgY2FsbGVyIHdpbGwgaWdub3JlIHRoZSBleGNlcHRpb24sIHJlZ2FyZGluZyBpdCBhcyBhIHtAY29kZQorICAgICAqIG51bGx9IHJldHVybiB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBnaXZlbiBrZXkgdG8gYmUgc2VhcmNoZWQgZm9yLgorICAgICAqIEByZXR1cm4gdGhlIHByZWZlcmVuY2UgdmFsdWUgbWFwcGVkIHRvIHRoZSBnaXZlbiBrZXkuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IFN0cmluZyBnZXRTcGkoU3RyaW5nIGtleSk7CisKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgYWxsIHByZWZlcmVuY2Uga2V5cyBvZiB0aGlzIG5vZGUgb3IgYW4gZW1wdHkgYXJyYXkgaWYKKyAgICAgKiBubyBwcmVmZXJlbmNlcyBoYXZlIGJlZW4gZm91bmQuIFRoZSBjYWxsZXIgb2YgdGhpcyBtZXRob2Qgc2hvdWxkIGVuc3VyZQorICAgICAqIHRoYXQgdGhpcyBub2RlIGhhcyBub3QgYmVlbiByZW1vdmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYXJyYXkgb2YgYWxsIHByZWZlcmVuY2Uga2V5cy4KKyAgICAgKiBAdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBiYWNraW5nIHN0b3JlIGlzIHVuYXZhaWxhYmxlIG9yIGNhdXNlcyBhbiBvcGVyYXRpb24KKyAgICAgKiAgICAgICAgICAgICBmYWlsdXJlLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBTdHJpbmdbXSBrZXlzU3BpKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhpcyBub2RlIGZyb20gdGhlIHByZWZlcmVuY2UgaGllcmFyY2h5IHRyZWUuIFRoZSBjYWxsZXIgb2YgdGhpcworICAgICAqIG1ldGhvZCBzaG91bGQgZW5zdXJlIHRoYXQgdGhpcyBub2RlIGhhcyBubyBjaGlsZCBub2Rlcywgd2hpY2ggbWVhbnMgdGhlCisgICAgICogbWV0aG9kIHtAbGluayBQcmVmZXJlbmNlcyNyZW1vdmVOb2RlKCkgUHJlZmVyZW5jZXMucmVtb3ZlTm9kZSgpfSBzaG91bGQKKyAgICAgKiBpbnZva2UgdGhpcyBtZXRob2QgbXVsdGlwbGUtdGltZXMgaW4gYm90dG9tLXVwIHBhdHRlcm4uIFRoZSByZW1vdmFsIGlzCisgICAgICogbm90IHJlcXVpcmVkIHRvIGJlIHBlcnNpc3RlZCB1bnRpbCBhZnRlciBpdCBpcyBmbHVzaGVkLgorICAgICAqCisgICAgICogQHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgYmFja2luZyBzdG9yZSBpcyB1bmF2YWlsYWJsZSBvciBjYXVzZXMgYW4gb3BlcmF0aW9uCisgICAgICogICAgICAgICAgICAgZmFpbHVyZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCByZW1vdmVOb2RlU3BpKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIHByZWZlcmVuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGtleS4gVGhlIGNhbGxlciBvZiB0aGlzIG1ldGhvZAorICAgICAqIHNob3VsZCBlbnN1cmUgdGhhdCB0aGUgZ2l2ZW4ga2V5IGlzIHZhbGlkIGFuZCB0aGF0IHRoaXMgbm9kZSBoYXMgbm90IGJlZW4KKyAgICAgKiByZW1vdmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBvZiB0aGUgcHJlZmVyZW5jZSB0aGF0IGlzIHRvIGJlIHJlbW92ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgcmVtb3ZlU3BpKFN0cmluZyBrZXkpOworCisgICAgLyoqCisgICAgICogU3luY2hyb25pemVzIHRoaXMgbm9kZSB3aXRoIHRoZSBiYWNraW5nIHN0b3JlLiBUaGlzIG1ldGhvZCBzaG91bGQgb25seQorICAgICAqIHN5bmNocm9uaXplIHRoaXMgbm9kZSBhbmQgc2hvdWxkIG5vdCBpbmNsdWRlIHRoZSBkZXNjZW5kYW50IG5vZGVzLiBBbgorICAgICAqIGltcGxlbWVudGF0aW9uIHRoYXQgd2FudHMgdG8gcHJvdmlkZSBmdW5jdGlvbmFsaXR5IHRvIHN5bmNocm9uaXplIGFsbAorICAgICAqIG5vZGVzIGF0IG9uY2Ugc2hvdWxkIG92ZXJyaWRlIHRoZSBtZXRob2Qge0BsaW5rICNzeW5jKCkgc3luYygpfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGJhY2tpbmcgc3RvcmUgaXMgdW5hdmFpbGFibGUgb3IgY2F1c2VzIGFuIG9wZXJhdGlvbgorICAgICAqICAgICAgICAgICAgIGZhaWx1cmUuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgc3luY1NwaSgpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb247CisKKyAgICAvKgorICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICogTWV0aG9kcyBpbmhlcml0ZWQgZnJvbSBQcmVmZXJlbmNlcworICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBhYnNvbHV0ZVBhdGgoKSB7CisgICAgICAgIGlmIChwYXJlbnRQcmVmID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAiLyI7CisgICAgICAgIH0gZWxzZSBpZiAocGFyZW50UHJlZiA9PSByb290KSB7CisgICAgICAgICAgICByZXR1cm4gIi8iICsgbm9kZU5hbWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHBhcmVudFByZWYuYWJzb2x1dGVQYXRoKCkgKyAiLyIgKyBub2RlTmFtZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nW10gY2hpbGRyZW5OYW1lcygpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGNoZWNrU3RhdGUoKTsKKyAgICAgICAgICAgIFRyZWVTZXQ8U3RyaW5nPiByZXN1bHQgPSBuZXcgVHJlZVNldDxTdHJpbmc+KGNhY2hlZE5vZGUua2V5U2V0KCkpOworICAgICAgICAgICAgU3RyaW5nW10gbmFtZXMgPSBjaGlsZHJlbk5hbWVzU3BpKCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5hbWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChuYW1lc1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0LnRvQXJyYXkobmV3IFN0cmluZ1tyZXN1bHQuc2l6ZSgpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIGtleSA6IGtleXMoKSkgeworICAgICAgICAgICAgICAgIHJlbW92ZShrZXkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZXhwb3J0Tm9kZShPdXRwdXRTdHJlYW0gb3N0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uLCBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBpZiAob3N0cmVhbSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIlN0cmVhbSBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tTdGF0ZSgpOworICAgICAgICBYTUxQYXJzZXIuZXhwb3J0UHJlZnModGhpcywgb3N0cmVhbSwgZmFsc2UpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGV4cG9ydFN1YnRyZWUoT3V0cHV0U3RyZWFtIG9zdHJlYW0pIHRocm93cyBJT0V4Y2VwdGlvbiwgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG9zdHJlYW0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJTdHJlYW0gaXMgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGNoZWNrU3RhdGUoKTsKKyAgICAgICAgWE1MUGFyc2VyLmV4cG9ydFByZWZzKHRoaXMsIG9zdHJlYW0sIHRydWUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgZmx1c2hTcGkoKTsKKyAgICAgICAgfQorICAgICAgICBBYnN0cmFjdFByZWZlcmVuY2VzW10gY2MgPSBjYWNoZWRDaGlsZHJlbigpOworICAgICAgICBpbnQgaTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IGNjLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjY1tpXS5mbHVzaCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXQoU3RyaW5nIGtleSwgU3RyaW5nIGRlZmx0KSB7CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IG51bGw7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tTdGF0ZSgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSBnZXRTcGkoa2V5KTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gaWdub3JlZAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiAocmVzdWx0ID09IG51bGwgPyBkZWZsdCA6IHJlc3VsdCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0Qm9vbGVhbihTdHJpbmcga2V5LCBib29sZWFuIGRlZmx0KSB7CisgICAgICAgIFN0cmluZyByZXN1bHQgPSBnZXQoa2V5LCBudWxsKTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZGVmbHQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCJ0cnVlIi5lcXVhbHNJZ25vcmVDYXNlKHJlc3VsdCkpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9IGVsc2UgaWYgKCJmYWxzZSIuZXF1YWxzSWdub3JlQ2FzZShyZXN1bHQpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gZGVmbHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZVtdIGdldEJ5dGVBcnJheShTdHJpbmcga2V5LCBieXRlW10gZGVmbHQpIHsKKyAgICAgICAgU3RyaW5nIHN2YWx1ZSA9IGdldChrZXksIG51bGwpOworICAgICAgICBpZiAoc3ZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBkZWZsdDsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3ZhbHVlLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBFbXB0eUFycmF5LkJZVEU7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ5dGVbXSBiYXZhbHVlID0gc3ZhbHVlLmdldEJ5dGVzKENoYXJzZXRzLlVTX0FTQ0lJKTsKKyAgICAgICAgICAgIGlmIChiYXZhbHVlLmxlbmd0aCAlIDQgIT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBkZWZsdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBCYXNlNjQuZGVjb2RlKGJhdmFsdWUpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIGRlZmx0OworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGRvdWJsZSBnZXREb3VibGUoU3RyaW5nIGtleSwgZG91YmxlIGRlZmx0KSB7CisgICAgICAgIFN0cmluZyByZXN1bHQgPSBnZXQoa2V5LCBudWxsKTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZGVmbHQ7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBEb3VibGUucGFyc2VEb3VibGUocmVzdWx0KTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBkZWZsdDsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmbG9hdCBnZXRGbG9hdChTdHJpbmcga2V5LCBmbG9hdCBkZWZsdCkgeworICAgICAgICBTdHJpbmcgcmVzdWx0ID0gZ2V0KGtleSwgbnVsbCk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGRlZmx0OworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gRmxvYXQucGFyc2VGbG9hdChyZXN1bHQpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIGRlZmx0OworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRJbnQoU3RyaW5nIGtleSwgaW50IGRlZmx0KSB7CisgICAgICAgIFN0cmluZyByZXN1bHQgPSBnZXQoa2V5LCBudWxsKTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZGVmbHQ7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLnBhcnNlSW50KHJlc3VsdCk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gZGVmbHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRMb25nKFN0cmluZyBrZXksIGxvbmcgZGVmbHQpIHsKKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGdldChrZXksIG51bGwpOworICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBkZWZsdDsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIExvbmcucGFyc2VMb25nKHJlc3VsdCk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gZGVmbHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1VzZXJOb2RlKCkgeworICAgICAgICByZXR1cm4gcm9vdCA9PSBQcmVmZXJlbmNlcy51c2VyUm9vdCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdbXSBrZXlzKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tTdGF0ZSgpOworICAgICAgICAgICAgcmV0dXJuIGtleXNTcGkoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgbmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG5vZGVOYW1lOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBQcmVmZXJlbmNlcyBub2RlKFN0cmluZyBuYW1lKSB7CisgICAgICAgIEFic3RyYWN0UHJlZmVyZW5jZXMgc3RhcnROb2RlID0gbnVsbDsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBjaGVja1N0YXRlKCk7CisgICAgICAgICAgICB2YWxpZGF0ZU5hbWUobmFtZSk7CisgICAgICAgICAgICBpZiAobmFtZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIi8iLmVxdWFscyhuYW1lKSkgeworICAgICAgICAgICAgICAgIHJldHVybiByb290OworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG5hbWUuc3RhcnRzV2l0aCgiLyIpKSB7CisgICAgICAgICAgICAgICAgc3RhcnROb2RlID0gcm9vdDsKKyAgICAgICAgICAgICAgICBuYW1lID0gbmFtZS5zdWJzdHJpbmcoMSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHN0YXJ0Tm9kZSA9IHRoaXM7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzdGFydE5vZGUubm9kZUltcGwobmFtZSwgdHJ1ZSk7CisgICAgICAgIH0gY2F0Y2ggKEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBzaG91bGQgbm90IGhhcHBlbgorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdmFsaWRhdGVOYW1lKFN0cmluZyBuYW1lKSB7CisgICAgICAgIGlmIChuYW1lLmVuZHNXaXRoKCIvIikgJiYgbmFtZS5sZW5ndGgoKSA+IDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5hbWUgY2Fubm90IGVuZCB3aXRoICcvJyIpOworICAgICAgICB9CisgICAgICAgIGlmIChuYW1lLmluZGV4T2YoIi8vIikgPj0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTmFtZSBjYW5ub3QgY29udGFpbiBjb25zZWN1dGl2ZSAnLycgY2hhcmFjdGVycyIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBBYnN0cmFjdFByZWZlcmVuY2VzIG5vZGVJbXBsKFN0cmluZyBwYXRoLCBib29sZWFuIGNyZWF0ZU5ldykKKyAgICAgICAgICAgIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBTdHJpbmdbXSBuYW1lcyA9IHBhdGguc3BsaXQoIi8iKTsKKyAgICAgICAgQWJzdHJhY3RQcmVmZXJlbmNlcyBjdXJyZW50Tm9kZSA9IHRoaXM7CisgICAgICAgIEFic3RyYWN0UHJlZmVyZW5jZXMgdGVtcDsKKyAgICAgICAgZm9yIChTdHJpbmcgbmFtZSA6IG5hbWVzKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGN1cnJlbnROb2RlLmxvY2spIHsKKyAgICAgICAgICAgICAgICB0ZW1wID0gY3VycmVudE5vZGUuY2FjaGVkTm9kZS5nZXQobmFtZSk7CisgICAgICAgICAgICAgICAgaWYgKHRlbXAgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0ZW1wID0gZ2V0Tm9kZUZyb21CYWNrZW5kKGNyZWF0ZU5ldywgY3VycmVudE5vZGUsIG5hbWUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGN1cnJlbnROb2RlID0gdGVtcDsKKyAgICAgICAgICAgIGlmIChjdXJyZW50Tm9kZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGN1cnJlbnROb2RlOworICAgIH0KKworICAgIHByaXZhdGUgQWJzdHJhY3RQcmVmZXJlbmNlcyBnZXROb2RlRnJvbUJhY2tlbmQoYm9vbGVhbiBjcmVhdGVOZXcsCisgICAgICAgICAgICBBYnN0cmFjdFByZWZlcmVuY2VzIGN1cnJlbnROb2RlLCBTdHJpbmcgbmFtZSkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChuYW1lLmxlbmd0aCgpID4gTUFYX05BTUVfTEVOR1RIKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJOYW1lICciICsgbmFtZSArICInIHRvbyBsb25nIik7CisgICAgICAgIH0KKyAgICAgICAgQWJzdHJhY3RQcmVmZXJlbmNlcyB0ZW1wOworICAgICAgICBpZiAoY3JlYXRlTmV3KSB7CisgICAgICAgICAgICB0ZW1wID0gY3VycmVudE5vZGUuY2hpbGRTcGkobmFtZSk7CisgICAgICAgICAgICBjdXJyZW50Tm9kZS5jYWNoZWROb2RlLnB1dChuYW1lLCB0ZW1wKTsKKyAgICAgICAgICAgIGlmICh0ZW1wLm5ld05vZGUgJiYgY3VycmVudE5vZGUubm9kZUNoYW5nZUxpc3RlbmVycy5zaXplKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgY3VycmVudE5vZGUubm90aWZ5Q2hpbGRBZGRlZCh0ZW1wKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRlbXAgPSBjdXJyZW50Tm9kZS5nZXRDaGlsZChuYW1lKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGVtcDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBub2RlRXhpc3RzKFN0cmluZyBuYW1lKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgQWJzdHJhY3RQcmVmZXJlbmNlcyBzdGFydE5vZGUgPSBudWxsOworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGlmIChpc1JlbW92ZWQoKSkgeworICAgICAgICAgICAgICAgIGlmIChuYW1lLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIlRoaXMgbm9kZSBoYXMgYmVlbiByZW1vdmVkIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB2YWxpZGF0ZU5hbWUobmFtZSk7CisgICAgICAgICAgICBpZiAobmFtZS5pc0VtcHR5KCkgfHwgIi8iLmVxdWFscyhuYW1lKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG5hbWUuc3RhcnRzV2l0aCgiLyIpKSB7CisgICAgICAgICAgICAgICAgc3RhcnROb2RlID0gcm9vdDsKKyAgICAgICAgICAgICAgICBuYW1lID0gbmFtZS5zdWJzdHJpbmcoMSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHN0YXJ0Tm9kZSA9IHRoaXM7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFByZWZlcmVuY2VzIHJlc3VsdCA9IHN0YXJ0Tm9kZS5ub2RlSW1wbChuYW1lLCBmYWxzZSk7CisgICAgICAgICAgICByZXR1cm4gKHJlc3VsdCAhPSBudWxsKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFByZWZlcmVuY2VzIHBhcmVudCgpIHsKKyAgICAgICAgY2hlY2tTdGF0ZSgpOworICAgICAgICByZXR1cm4gcGFyZW50UHJlZjsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tTdGF0ZSgpIHsKKyAgICAgICAgaWYgKGlzUmVtb3ZlZCgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJUaGlzIG5vZGUgaGFzIGJlZW4gcmVtb3ZlZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcHV0KFN0cmluZyBrZXksIFN0cmluZyB2YWx1ZSkgeworICAgICAgICBpZiAoa2V5ID09IG51bGwgfHwgdmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGtleS5sZW5ndGgoKSA+IE1BWF9LRVlfTEVOR1RIIHx8IHZhbHVlLmxlbmd0aCgpID4gTUFYX1ZBTFVFX0xFTkdUSCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tTdGF0ZSgpOworICAgICAgICAgICAgcHV0U3BpKGtleSwgdmFsdWUpOworICAgICAgICB9CisgICAgICAgIG5vdGlmeVByZWZlcmVuY2VDaGFuZ2Uoa2V5LCB2YWx1ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcHV0Qm9vbGVhbihTdHJpbmcga2V5LCBib29sZWFuIHZhbHVlKSB7CisgICAgICAgIHB1dChrZXksIFN0cmluZy52YWx1ZU9mKHZhbHVlKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcHV0Qnl0ZUFycmF5KFN0cmluZyBrZXksIGJ5dGVbXSB2YWx1ZSkgeworICAgICAgICBwdXQoa2V5LCBCYXNlNjQuZW5jb2RlKHZhbHVlKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcHV0RG91YmxlKFN0cmluZyBrZXksIGRvdWJsZSB2YWx1ZSkgeworICAgICAgICBwdXQoa2V5LCBEb3VibGUudG9TdHJpbmcodmFsdWUpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBwdXRGbG9hdChTdHJpbmcga2V5LCBmbG9hdCB2YWx1ZSkgeworICAgICAgICBwdXQoa2V5LCBGbG9hdC50b1N0cmluZyh2YWx1ZSkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHB1dEludChTdHJpbmcga2V5LCBpbnQgdmFsdWUpIHsKKyAgICAgICAgcHV0KGtleSwgSW50ZWdlci50b1N0cmluZyh2YWx1ZSkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHB1dExvbmcoU3RyaW5nIGtleSwgbG9uZyB2YWx1ZSkgeworICAgICAgICBwdXQoa2V5LCBMb25nLnRvU3RyaW5nKHZhbHVlKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVtb3ZlKFN0cmluZyBrZXkpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBjaGVja1N0YXRlKCk7CisgICAgICAgICAgICByZW1vdmVTcGkoa2V5KTsKKyAgICAgICAgfQorICAgICAgICBub3RpZnlQcmVmZXJlbmNlQ2hhbmdlKGtleSwgbnVsbCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVtb3ZlTm9kZSgpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBpZiAocm9vdCA9PSB0aGlzKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIkNhbm5vdCByZW1vdmUgcm9vdCBub2RlIik7CisgICAgICAgIH0KKyAgICAgICAgc3luY2hyb25pemVkIChwYXJlbnRQcmVmLmxvY2spIHsKKyAgICAgICAgICAgIHJlbW92ZU5vZGVJbXBsKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVtb3ZlTm9kZUltcGwoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBjaGVja1N0YXRlKCk7CisgICAgICAgICAgICBTdHJpbmdbXSBjaGlsZHJlbk5hbWVzID0gY2hpbGRyZW5OYW1lc1NwaSgpOworICAgICAgICAgICAgZm9yIChTdHJpbmcgY2hpbGRyZW5OYW1lIDogY2hpbGRyZW5OYW1lcykgeworICAgICAgICAgICAgICAgIGlmIChjYWNoZWROb2RlLmdldChjaGlsZHJlbk5hbWUpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgQWJzdHJhY3RQcmVmZXJlbmNlcyBjaGlsZCA9IGNoaWxkU3BpKGNoaWxkcmVuTmFtZSk7CisgICAgICAgICAgICAgICAgICAgIGNhY2hlZE5vZGUucHV0KGNoaWxkcmVuTmFtZSwgY2hpbGQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZmluYWwgQ29sbGVjdGlvbjxBYnN0cmFjdFByZWZlcmVuY2VzPiB2YWx1ZXMgPSBjYWNoZWROb2RlLnZhbHVlcygpOworICAgICAgICAgICAgZmluYWwgQWJzdHJhY3RQcmVmZXJlbmNlc1tdIGNoaWxkcmVuID0gdmFsdWVzLnRvQXJyYXkobmV3IEFic3RyYWN0UHJlZmVyZW5jZXNbdmFsdWVzLnNpemUoKV0pOworICAgICAgICAgICAgZm9yIChBYnN0cmFjdFByZWZlcmVuY2VzIGNoaWxkIDogY2hpbGRyZW4pIHsKKyAgICAgICAgICAgICAgICBjaGlsZC5yZW1vdmVOb2RlSW1wbCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVtb3ZlTm9kZVNwaSgpOworICAgICAgICAgICAgaXNSZW1vdmVkID0gdHJ1ZTsKKyAgICAgICAgICAgIHBhcmVudFByZWYuY2FjaGVkTm9kZS5yZW1vdmUobm9kZU5hbWUpOworICAgICAgICB9CisgICAgICAgIGlmIChwYXJlbnRQcmVmLm5vZGVDaGFuZ2VMaXN0ZW5lcnMuc2l6ZSgpID4gMCkgeworICAgICAgICAgICAgcGFyZW50UHJlZi5ub3RpZnlDaGlsZFJlbW92ZWQodGhpcyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhZGROb2RlQ2hhbmdlTGlzdGVuZXIoTm9kZUNoYW5nZUxpc3RlbmVyIG5jbCkgeworICAgICAgICBpZiAobmNsID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGNoZWNrU3RhdGUoKTsKKyAgICAgICAgc3luY2hyb25pemVkIChub2RlQ2hhbmdlTGlzdGVuZXJzKSB7CisgICAgICAgICAgICBub2RlQ2hhbmdlTGlzdGVuZXJzLmFkZChuY2wpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYWRkUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyKFByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lciBwY2wpIHsKKyAgICAgICAgaWYgKHBjbCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBjaGVja1N0YXRlKCk7CisgICAgICAgIHN5bmNocm9uaXplZCAocHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVycykgeworICAgICAgICAgICAgcHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVycy5hZGQocGNsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJlbW92ZU5vZGVDaGFuZ2VMaXN0ZW5lcihOb2RlQ2hhbmdlTGlzdGVuZXIgbmNsKSB7CisgICAgICAgIGNoZWNrU3RhdGUoKTsKKyAgICAgICAgc3luY2hyb25pemVkIChub2RlQ2hhbmdlTGlzdGVuZXJzKSB7CisgICAgICAgICAgICBpbnQgcG9zOworICAgICAgICAgICAgaWYgKChwb3MgPSBub2RlQ2hhbmdlTGlzdGVuZXJzLmluZGV4T2YobmNsKSkgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBub2RlQ2hhbmdlTGlzdGVuZXJzLnJlbW92ZShwb3MpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVtb3ZlUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyKFByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lciBwY2wpIHsKKyAgICAgICAgY2hlY2tTdGF0ZSgpOworICAgICAgICBzeW5jaHJvbml6ZWQgKHByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcnMpIHsKKyAgICAgICAgICAgIGludCBwb3M7CisgICAgICAgICAgICBpZiAoKHBvcyA9IHByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcnMuaW5kZXhPZihwY2wpKSA9PSAtMSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcnMucmVtb3ZlKHBvcyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzeW5jKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgY2hlY2tTdGF0ZSgpOworICAgICAgICAgICAgc3luY1NwaSgpOworICAgICAgICB9CisgICAgICAgIGZvciAoQWJzdHJhY3RQcmVmZXJlbmNlcyBjaGlsZCA6IGNhY2hlZENoaWxkcmVuKCkpIHsKKyAgICAgICAgICAgIGNoaWxkLnN5bmMoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiAoaXNVc2VyTm9kZSgpID8gIlVzZXIiIDogIlN5c3RlbSIpICsgIiBQcmVmZXJlbmNlIE5vZGU6ICIgKyBhYnNvbHV0ZVBhdGgoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgbm90aWZ5Q2hpbGRBZGRlZChQcmVmZXJlbmNlcyBjaGlsZCkgeworICAgICAgICBOb2RlQ2hhbmdlRXZlbnQgbmNlID0gbmV3IE5vZGVBZGRFdmVudCh0aGlzLCBjaGlsZCk7CisgICAgICAgIHN5bmNocm9uaXplZCAoZXZlbnRzKSB7CisgICAgICAgICAgICBldmVudHMuYWRkKG5jZSk7CisgICAgICAgICAgICBldmVudHMubm90aWZ5QWxsKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgbm90aWZ5Q2hpbGRSZW1vdmVkKFByZWZlcmVuY2VzIGNoaWxkKSB7CisgICAgICAgIE5vZGVDaGFuZ2VFdmVudCBuY2UgPSBuZXcgTm9kZVJlbW92ZUV2ZW50KHRoaXMsIGNoaWxkKTsKKyAgICAgICAgc3luY2hyb25pemVkIChldmVudHMpIHsKKyAgICAgICAgICAgIGV2ZW50cy5hZGQobmNlKTsKKyAgICAgICAgICAgIGV2ZW50cy5ub3RpZnlBbGwoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBub3RpZnlQcmVmZXJlbmNlQ2hhbmdlKFN0cmluZyBrZXksIFN0cmluZyBuZXdWYWx1ZSkgeworICAgICAgICBQcmVmZXJlbmNlQ2hhbmdlRXZlbnQgcGNlID0gbmV3IFByZWZlcmVuY2VDaGFuZ2VFdmVudCh0aGlzLCBrZXksIG5ld1ZhbHVlKTsKKyAgICAgICAgc3luY2hyb25pemVkIChldmVudHMpIHsKKyAgICAgICAgICAgIGV2ZW50cy5hZGQocGNlKTsKKyAgICAgICAgICAgIGV2ZW50cy5ub3RpZnlBbGwoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEV2ZW50RGlzcGF0Y2hlciBleHRlbmRzIFRocmVhZCB7CisgICAgICAgIEV2ZW50RGlzcGF0Y2hlcihTdHJpbmcgbmFtZSl7CisgICAgICAgICAgICBzdXBlcihuYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgIEV2ZW50T2JqZWN0IGV2ZW50OworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGV2ZW50ID0gZ2V0RXZlbnRPYmplY3QoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBBYnN0cmFjdFByZWZlcmVuY2VzIHByZWYgPSAoQWJzdHJhY3RQcmVmZXJlbmNlcykgZXZlbnQuZ2V0U291cmNlKCk7CisgICAgICAgICAgICAgICAgaWYgKGV2ZW50IGluc3RhbmNlb2YgTm9kZUFkZEV2ZW50KSB7CisgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoTm9kZUFkZCgoTm9kZUNoYW5nZUV2ZW50KSBldmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmLm5vZGVDaGFuZ2VMaXN0ZW5lcnMpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXZlbnQgaW5zdGFuY2VvZiBOb2RlUmVtb3ZlRXZlbnQpIHsKKyAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hOb2RlUmVtb3ZlKChOb2RlQ2hhbmdlRXZlbnQpIGV2ZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWYubm9kZUNoYW5nZUxpc3RlbmVycyk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChldmVudCBpbnN0YW5jZW9mIFByZWZlcmVuY2VDaGFuZ2VFdmVudCkgeworICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaFByZWZDaGFuZ2UoKFByZWZlcmVuY2VDaGFuZ2VFdmVudCkgZXZlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZi5wcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXJzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIEV2ZW50T2JqZWN0IGdldEV2ZW50T2JqZWN0KCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoZXZlbnRzKSB7CisgICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZXZlbnRzLndhaXQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgRXZlbnRPYmplY3QgZXZlbnQgPSBldmVudHMuZ2V0KDApOworICAgICAgICAgICAgICAgIGV2ZW50cy5yZW1vdmUoMCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSB2b2lkIGRpc3BhdGNoUHJlZkNoYW5nZShQcmVmZXJlbmNlQ2hhbmdlRXZlbnQgZXZlbnQsCisgICAgICAgICAgICAgICAgTGlzdDxFdmVudExpc3RlbmVyPiBwcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXJzKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcnMpIHsKKyAgICAgICAgICAgICAgICBmb3IgKEV2ZW50TGlzdGVuZXIgcHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyIDogcHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVycykgeworICAgICAgICAgICAgICAgICAgICAoKFByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcikgcHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyKS5wcmVmZXJlbmNlQ2hhbmdlKGV2ZW50KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgZGlzcGF0Y2hOb2RlUmVtb3ZlKE5vZGVDaGFuZ2VFdmVudCBldmVudCwKKyAgICAgICAgICAgICAgICBMaXN0PEV2ZW50TGlzdGVuZXI+IG5vZGVDaGFuZ2VMaXN0ZW5lcnMpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobm9kZUNoYW5nZUxpc3RlbmVycykgeworICAgICAgICAgICAgICAgIGZvciAoRXZlbnRMaXN0ZW5lciBub2RlQ2hhbmdlTGlzdGVuZXIgOiBub2RlQ2hhbmdlTGlzdGVuZXJzKSB7CisgICAgICAgICAgICAgICAgICAgICgoTm9kZUNoYW5nZUxpc3RlbmVyKSBub2RlQ2hhbmdlTGlzdGVuZXIpLmNoaWxkUmVtb3ZlZChldmVudCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSB2b2lkIGRpc3BhdGNoTm9kZUFkZChOb2RlQ2hhbmdlRXZlbnQgZXZlbnQsCisgICAgICAgICAgICAgICAgTGlzdDxFdmVudExpc3RlbmVyPiBub2RlQ2hhbmdlTGlzdGVuZXJzKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG5vZGVDaGFuZ2VMaXN0ZW5lcnMpIHsKKyAgICAgICAgICAgICAgICBmb3IgKEV2ZW50TGlzdGVuZXIgbm9kZUNoYW5nZUxpc3RlbmVyIDogbm9kZUNoYW5nZUxpc3RlbmVycykgeworICAgICAgICAgICAgICAgICAgICBOb2RlQ2hhbmdlTGlzdGVuZXIgbmNsID0gKE5vZGVDaGFuZ2VMaXN0ZW5lcikgbm9kZUNoYW5nZUxpc3RlbmVyOworICAgICAgICAgICAgICAgICAgICBuY2wuY2hpbGRBZGRlZChldmVudCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTm9kZUFkZEV2ZW50IGV4dGVuZHMgTm9kZUNoYW5nZUV2ZW50IHsKKyAgICAgICAgLy9UaGUgYmFzZSBjbGFzcyBpcyBOT1Qgc2VyaWFsaXphYmxlLCBzbyB0aGlzIGNsYXNzIGlzbid0IGVpdGhlci4KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAgICAgcHVibGljIE5vZGVBZGRFdmVudChQcmVmZXJlbmNlcyBwLCBQcmVmZXJlbmNlcyBjKSB7CisgICAgICAgICAgICBzdXBlcihwLCBjKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIE5vZGVSZW1vdmVFdmVudCBleHRlbmRzIE5vZGVDaGFuZ2VFdmVudCB7CisgICAgICAgIC8vVGhlIGJhc2UgY2xhc3MgaXMgTk9UIHNlcmlhbGl6YWJsZSwgc28gdGhpcyBjbGFzcyBpc24ndCBlaXRoZXIuCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgICAgIHB1YmxpYyBOb2RlUmVtb3ZlRXZlbnQoUHJlZmVyZW5jZXMgcCwgUHJlZmVyZW5jZXMgYykgeworICAgICAgICAgICAgc3VwZXIocCwgYyk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL0JhY2tpbmdTdG9yZUV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9wcmVmcy9CYWNraW5nU3RvcmVFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNzRlMmQwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9wcmVmcy9CYWNraW5nU3RvcmVFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDUxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5wcmVmczsKKworLyoqCisgKiBBbiBleGNlcHRpb24gdG8gaW5kaWNhdGUgdGhhdCBhbiBlcnJvciB3YXMgZW5jb3VudGVyZWQgd2hpbGUgYWNjZXNzaW5nIHRoZQorICogYmFja2luZyBzdG9yZS4KKyAqCisgKiBAc2luY2UgMS40CisgKi8KK3B1YmxpYyBjbGFzcyBCYWNraW5nU3RvcmVFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODU5Nzk2NTAwNDAxMTA4NDY5TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbn0gaW5zdGFuY2Ugd2l0aCBhIGRldGFpbGVkCisgICAgICogZXhjZXB0aW9uIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbGVkIGV4Y2VwdGlvbiBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBCYWNraW5nU3RvcmVFeGNlcHRpb24gKFN0cmluZyBzKSB7CisgICAgICAgIHN1cGVyKHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbn0gaW5zdGFuY2Ugd2l0aCBhIG5lc3RlZAorICAgICAqIHtAY29kZSBUaHJvd2FibGV9LgorICAgICAqCisgICAgICogQHBhcmFtIHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXN0ZWQge0Bjb2RlIFRocm93YWJsZX0uCisgICAgICovCisgICAgcHVibGljIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgc3VwZXIodCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9wcmVmcy9GaWxlUHJlZmVyZW5jZXNGYWN0b3J5SW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9wcmVmcy9GaWxlUHJlZmVyZW5jZXNGYWN0b3J5SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhmMmQwYWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL0ZpbGVQcmVmZXJlbmNlc0ZhY3RvcnlJbXBsLmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwucHJlZnM7CisKKy8qKgorICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgPGNvZGU+UHJlZmVyZW5jZXNGYWN0b3J5PC9jb2RlPiBmb3IgdGhlIExpbnV4CisgKiBwbGF0Zm9ybSwgdXNpbmcgdGhlIGZpbGUgc3lzdGVtIGFzIGl0cyBiYWNrIGVuZC4KKyAqCisgKiBAc2luY2UgMS40CisgKi8KK2NsYXNzIEZpbGVQcmVmZXJlbmNlc0ZhY3RvcnlJbXBsIGltcGxlbWVudHMgUHJlZmVyZW5jZXNGYWN0b3J5IHsKKyAgICAvLyAgdXNlciByb290IHByZWZlcmVuY2VzCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUHJlZmVyZW5jZXMgVVNFUl9ST09UID0gbmV3IEZpbGVQcmVmZXJlbmNlc0ltcGwodHJ1ZSk7CisKKyAgICAvLyAgc3lzdGVtIHJvb3QgcHJlZmVyZW5jZXMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQcmVmZXJlbmNlcyBTWVNURU1fUk9PVCA9IG5ldyBGaWxlUHJlZmVyZW5jZXNJbXBsKGZhbHNlKTsKKworICAgIHB1YmxpYyBGaWxlUHJlZmVyZW5jZXNGYWN0b3J5SW1wbCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgUHJlZmVyZW5jZXMgdXNlclJvb3QoKSB7CisgICAgICAgIHJldHVybiBVU0VSX1JPT1Q7CisgICAgfQorCisgICAgcHVibGljIFByZWZlcmVuY2VzIHN5c3RlbVJvb3QoKSB7CisgICAgICAgIHJldHVybiBTWVNURU1fUk9PVDsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcHJlZnMvRmlsZVByZWZlcmVuY2VzSW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9wcmVmcy9GaWxlUHJlZmVyZW5jZXNJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmQzNjdhNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcHJlZnMvRmlsZVByZWZlcmVuY2VzSW1wbC5qYXZhCkBAIC0wLDAgKzEsMTkwIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5wcmVmczsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVuYW1lRmlsdGVyOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCisvKioKKyAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIDxjb2RlPkFic3RyYWN0UHJlZmVyZW5jZXM8L2NvZGU+IGZvciB0aGUgTGludXgKKyAqIHBsYXRmb3JtLCB1c2luZyB0aGUgZmlsZSBzeXN0ZW0gYXMgaXRzIGJhY2sgZW5kLgorICoKKyAqIFRPRE8gc29tZSBzeW5jIG1lY2hhbmlzbSB3aXRoIGJhY2tlbmQsIFBlcmZvcm1hbmNlIC0gY2hlY2sgZmlsZSBlZGl0IGRhdGUKKyAqCisgKiBAc2luY2UgMS40CisgKi8KK2NsYXNzIEZpbGVQcmVmZXJlbmNlc0ltcGwgZXh0ZW5kcyBBYnN0cmFjdFByZWZlcmVuY2VzIHsKKworICAgIC8vcHJlZnMgZmlsZSBuYW1lCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBSRUZTX0ZJTEVfTkFNRSA9ICJwcmVmcy54bWwiOworCisgICAgLy9ob21lIGRpcmVjdG9yeSBmb3IgdXNlciBwcmVmcworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBVU0VSX0hPTUUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoInVzZXIuaG9tZSIpICsgIi8uamF2YS8udXNlclByZWZzIjsKKworICAgIC8vaG9tZSBkaXJlY3RvcnkgZm9yIHN5c3RlbSBwcmVmcworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBTWVNURU1fSE9NRSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5ob21lIikgKyAiLy5zeXN0ZW1QcmVmcyI7CisKKyAgICAvL2ZpbGUgcGF0aCBmb3IgdGhpcyBwcmVmZXJlbmNlcyBub2RlCisgICAgcHJpdmF0ZSBTdHJpbmcgcGF0aDsKKworICAgIC8vaW50ZXJuYWwgY2FjaGUgZm9yIHByZWZzIGtleS12YWx1ZSBwYWlyCisgICAgcHJpdmF0ZSBQcm9wZXJ0aWVzIHByZWZzOworCisgICAgLy9maWxlIHJlcHJlc2VudHMgdGhpcyBwcmVmZXJlbmNlcyBub2RlCisgICAgcHJpdmF0ZSBGaWxlIHByZWZzRmlsZTsKKworICAgIC8vcGFyZW50IGRpciBmb3IgdGhpcyBwcmVmZXJlbmNlcyBub2RlCisgICAgcHJpdmF0ZSBGaWxlIGRpcjsKKworICAgIC8vY2FjaGUgZm9yIHJlbW92ZWQgcHJlZnMga2V5LXZhbHVlIHBhaXIKKyAgICBwcml2YXRlIFNldDxTdHJpbmc+IHJlbW92ZWQgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7CisKKyAgICAvL2NhY2hlIGZvciB1cGRhdGVkIHByZWZzIGtleS12YWx1ZSBwYWlyCisgICAgcHJpdmF0ZSBTZXQ8U3RyaW5nPiB1cGRhdGVkID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworCisgICAgLyoKKyAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAqIENvbnN0cnVjdG9ycworICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3Qgcm9vdCA8Y29kZT5GaWxlUHJlZmVyZW5jZXNJbXBsPC9jb2RlPiBpbnN0YW5jZSwgY29uc3RydWN0CisgICAgICogdXNlciByb290IGlmIHVzZXJOb2RlIGlzIHRydWUsIHN5c3RlbSByb290IG90aGVyd2lzZQorICAgICAqLworICAgIEZpbGVQcmVmZXJlbmNlc0ltcGwoYm9vbGVhbiB1c2VyTm9kZSkgeworICAgICAgICBzdXBlcihudWxsLCAiIik7CisgICAgICAgIHRoaXMudXNlck5vZGUgPSB1c2VyTm9kZTsKKyAgICAgICAgcGF0aCA9IHVzZXJOb2RlID8gVVNFUl9IT01FIDogU1lTVEVNX0hPTUU7CisgICAgICAgIGluaXRQcmVmcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIHByZWZzIHVzaW5nIGdpdmVuIHBhcmVudCBhbmQgZ2l2ZW4gbmFtZQorICAgICAqLworICAgIHByaXZhdGUgRmlsZVByZWZlcmVuY2VzSW1wbChBYnN0cmFjdFByZWZlcmVuY2VzIHBhcmVudCwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgc3VwZXIocGFyZW50LCBuYW1lKTsKKyAgICAgICAgcGF0aCA9ICgoRmlsZVByZWZlcmVuY2VzSW1wbCkgcGFyZW50KS5wYXRoICsgRmlsZS5zZXBhcmF0b3IgKyBuYW1lOworICAgICAgICBpbml0UHJlZnMoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgaW5pdFByZWZzKCkgeworICAgICAgICBkaXIgPSBuZXcgRmlsZShwYXRoKTsKKyAgICAgICAgbmV3Tm9kZSA9ICFkaXIuZXhpc3RzKCk7CisgICAgICAgIHByZWZzRmlsZSA9IG5ldyBGaWxlKHBhdGggKyBGaWxlLnNlcGFyYXRvciArIFBSRUZTX0ZJTEVfTkFNRSk7CisgICAgICAgIHByZWZzID0gWE1MUGFyc2VyLnJlYWRYbWxQcmVmZXJlbmNlcyhwcmVmc0ZpbGUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBTdHJpbmdbXSBjaGlsZHJlbk5hbWVzU3BpKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIG5hbWVzID0gZGlyLmxpc3QobmV3IEZpbGVuYW1lRmlsdGVyKCkgeworICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gYWNjZXB0KEZpbGUgcGFyZW50LCBTdHJpbmcgbmFtZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRmlsZShwYXRoICsgRmlsZS5zZXBhcmF0b3IgKyBuYW1lKS5pc0RpcmVjdG9yeSgpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAgICAgaWYgKG5hbWVzID09IG51bGwpIHsvLyBmaWxlIGlzIG5vdCBhIGRpcmVjdG9yeSwgZXhjZXB0aW9uIGNhc2UKKyAgICAgICAgICAgIHRocm93IG5ldyBCYWNraW5nU3RvcmVFeGNlcHRpb24oIkNhbm5vdCBnZXQgY2hpbGQgbmFtZXMgZm9yICIgKyB0b1N0cmluZygpCisgICAgICAgICAgICAgICAgICAgICsgIiAocGF0aCBpcyAiICsgcGF0aCArICIpIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5hbWVzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBBYnN0cmFjdFByZWZlcmVuY2VzIGNoaWxkU3BpKFN0cmluZyBuYW1lKSB7CisgICAgICAgIEZpbGVQcmVmZXJlbmNlc0ltcGwgY2hpbGQgPSBuZXcgRmlsZVByZWZlcmVuY2VzSW1wbCh0aGlzLCBuYW1lKTsKKyAgICAgICAgcmV0dXJuIGNoaWxkOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGZsdXNoU3BpKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvL2lmIHJlbW92ZWQsIHJldHVybgorICAgICAgICAgICAgaWYoaXNSZW1vdmVkKCkpeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIHJlbG9hZAorICAgICAgICAgICAgUHJvcGVydGllcyBjdXJyZW50UHJlZnMgPSBYTUxQYXJzZXIucmVhZFhtbFByZWZlcmVuY2VzKHByZWZzRmlsZSk7CisgICAgICAgICAgICAvLyBtZXJnZQorICAgICAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBpdCA9IHJlbW92ZWQuaXRlcmF0b3IoKTsKKyAgICAgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBjdXJyZW50UHJlZnMucmVtb3ZlKGl0Lm5leHQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZW1vdmVkLmNsZWFyKCk7CisgICAgICAgICAgICBpdCA9IHVwZGF0ZWQuaXRlcmF0b3IoKTsKKyAgICAgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBPYmplY3Qga2V5ID0gaXQubmV4dCgpOworICAgICAgICAgICAgICAgIGN1cnJlbnRQcmVmcy5wdXQoa2V5LCBwcmVmcy5nZXQoa2V5KSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB1cGRhdGVkLmNsZWFyKCk7CisgICAgICAgICAgICAvLyBmbHVzaAorICAgICAgICAgICAgcHJlZnMgPSBjdXJyZW50UHJlZnM7CisgICAgICAgICAgICBYTUxQYXJzZXIud3JpdGVYbWxQcmVmZXJlbmNlcyhwcmVmc0ZpbGUsIHByZWZzKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCYWNraW5nU3RvcmVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldFNwaShTdHJpbmcga2V5KSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAocHJlZnMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHByZWZzID0gWE1MUGFyc2VyLnJlYWRYbWxQcmVmZXJlbmNlcyhwcmVmc0ZpbGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHByZWZzLmdldFByb3BlcnR5KGtleSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBpZiBFeGNlcHRpb24gaGFwcGVuZWQsIHJldHVybiBudWxsCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBTdHJpbmdbXSBrZXlzU3BpKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFNldDxPYmplY3Q+IGtzID0gcHJlZnMua2V5U2V0KCk7CisgICAgICAgIHJldHVybiBrcy50b0FycmF5KG5ldyBTdHJpbmdba3Muc2l6ZSgpXSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgcHV0U3BpKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpIHsKKyAgICAgICAgcHJlZnMuc2V0UHJvcGVydHkobmFtZSwgdmFsdWUpOworICAgICAgICB1cGRhdGVkLmFkZChuYW1lKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCByZW1vdmVOb2RlU3BpKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIHByZWZzRmlsZS5kZWxldGUoKTsKKyAgICAgICAgYm9vbGVhbiByZW1vdmVTdWNjZWVkID0gZGlyLmRlbGV0ZSgpOworICAgICAgICBpZiAoIXJlbW92ZVN1Y2NlZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBCYWNraW5nU3RvcmVFeGNlcHRpb24oIkNhbm5vdCByZW1vdmUgIiArIHRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgcmVtb3ZlU3BpKFN0cmluZyBrZXkpIHsKKyAgICAgICAgcHJlZnMucmVtb3ZlKGtleSk7CisgICAgICAgIHVwZGF0ZWQucmVtb3ZlKGtleSk7CisgICAgICAgIHJlbW92ZWQuYWRkKGtleSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc3luY1NwaSgpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBmbHVzaFNwaSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcHJlZnMvSW52YWxpZFByZWZlcmVuY2VzRm9ybWF0RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL0ludmFsaWRQcmVmZXJlbmNlc0Zvcm1hdEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE1YWYwODIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL0ludmFsaWRQcmVmZXJlbmNlc0Zvcm1hdEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLnByZWZzOworCisvKioKKyAqIEFuIGV4Y2VwdGlvbiB0byBpbmRpY2F0ZSB0aGF0IHRoZSBpbnB1dCBYTUwgZmlsZSBpcyBub3Qgd2VsbC1mb3JtZWQgb3IgY291bGQKKyAqIG5vdCBiZSB2YWxpZGF0ZWQgYWdhaW5zdCB0aGUgYXBwcm9wcmlhdGUgZG9jdW1lbnQgdHlwZSAoc3BlY2lmaWVkIGJ5CisgKiBpbiB0aGUge0Bjb2RlIFByZWZlcmVuY2VzfSkuCisgKi8KK3B1YmxpYyBjbGFzcyBJbnZhbGlkUHJlZmVyZW5jZXNGb3JtYXRFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTc5MTcxNTE4NDIzMjExOTY2OUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJbnZhbGlkUHJlZmVyZW5jZXNGb3JtYXRFeGNlcHRpb259IGluc3RhbmNlIHdpdGgKKyAgICAgKiBhIGRldGFpbGVkIGV4Y2VwdGlvbiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWxlZCBleGNlcHRpb24gbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW52YWxpZFByZWZlcmVuY2VzRm9ybWF0RXhjZXB0aW9uIChTdHJpbmcgcykgeworICAgICAgICBzdXBlcihzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBJbnZhbGlkUHJlZmVyZW5jZXNGb3JtYXRFeGNlcHRpb259IGluc3RhbmNlIHdpdGgKKyAgICAgKiBhIGRldGFpbGVkIGV4Y2VwdGlvbiBtZXNzYWdlIGFuZCBhIG5lc3RlZCB7QGNvZGUgVGhyb3dhYmxlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsZWQgZXhjZXB0aW9uIG1lc3NhZ2UuCisgICAgICogQHBhcmFtIHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXN0ZWQge0Bjb2RlIFRocm93YWJsZX0uCisgICAgICovCisgICAgcHVibGljIEludmFsaWRQcmVmZXJlbmNlc0Zvcm1hdEV4Y2VwdGlvbiAoU3RyaW5nIHMsIFRocm93YWJsZSB0KSB7CisgICAgICAgIHN1cGVyKHMsdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgSW52YWxpZFByZWZlcmVuY2VzRm9ybWF0RXhjZXB0aW9ufSBpbnN0YW5jZSB3aXRoCisgICAgICogYSBuZXN0ZWQge0Bjb2RlIFRocm93YWJsZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdAorICAgICAqICAgICAgICAgICAgdGhlIG5lc3RlZCB7QGNvZGUgVGhyb3dhYmxlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW52YWxpZFByZWZlcmVuY2VzRm9ybWF0RXhjZXB0aW9uIChUaHJvd2FibGUgdCkgeworICAgICAgICBzdXBlcih0KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL05vZGVDaGFuZ2VFdmVudC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9wcmVmcy9Ob2RlQ2hhbmdlRXZlbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOWFkOGEzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9wcmVmcy9Ob2RlQ2hhbmdlRXZlbnQuamF2YQpAQCAtMCwwICsxLDk0IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5wcmVmczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5Ob3RTZXJpYWxpemFibGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuRXZlbnRPYmplY3Q7CisKKy8qKgorICogVGhpcyBpcyB0aGUgZXZlbnQgY2xhc3MgdG8gaW5kaWNhdGUgdGhhdCBvbmUgY2hpbGQgb2YgdGhlIHByZWZlcmVuY2Ugbm9kZSBoYXMKKyAqIGJlZW4gYWRkZWQgb3IgZGVsZXRlZC4KKyAqIDxwPgorICogUGxlYXNlIG5vdGUgdGhhdCBhbHRob3VnaCB0aGUgY2xhc3MgaXMgbWFya2VkIGFzIHtAY29kZSBTZXJpYWxpemFibGV9IGJ5CisgKiBpbmhlcml0YW5jZSBmcm9tIHtAY29kZSBFdmVudE9iamVjdH0sIHRoaXMgdHlwZSBpcyBub3QgaW50ZW5kZWQgdG8gYmUgc2VyaWFsaXplZAorICogc28gdGhlIHNlcmlhbGl6YXRpb24gbWV0aG9kcyBkbyBub3RoaW5nIGJ1dCB0aHJvdyBhIHtAY29kZSBOb3RTZXJpYWxpemFibGVFeGNlcHRpb259LgorICoKKyAqIEBzZWUgamF2YS51dGlsLnByZWZzLlByZWZlcmVuY2VzCisgKiBAc2VlIGphdmEudXRpbC5wcmVmcy5Ob2RlQ2hhbmdlTGlzdGVuZXIKKyAqCisgKiBAc2luY2UgMS40CisgKi8KK3B1YmxpYyBjbGFzcyBOb2RlQ2hhbmdlRXZlbnQgZXh0ZW5kcyBFdmVudE9iamVjdCBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA4MDY4OTQ5MDg2NTk2NTcyOTU3TDsKKworICAgIHByaXZhdGUgZmluYWwgUHJlZmVyZW5jZXMgcGFyZW50OworICAgIHByaXZhdGUgZmluYWwgUHJlZmVyZW5jZXMgY2hpbGQ7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBOb2RlQ2hhbmdlRXZlbnR9IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIHAKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgUHJlZmVyZW5jZXN9IGluc3RhbmNlIHRoYXQgZmlyZWQgdGhpcyBldmVudDsgdGhpcyBvYmplY3QgaXMKKyAgICAgKiAgICAgICAgICAgIGNvbnNpZGVyZWQgYXMgdGhlIGV2ZW50IHNvdXJjZS4KKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGNoaWxkIHtAY29kZSBQcmVmZXJlbmNlc30gaW5zdGFuY2UgdGhhdCB3YXMgYWRkZWQgb3IgZGVsZXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9kZUNoYW5nZUV2ZW50IChQcmVmZXJlbmNlcyBwLCBQcmVmZXJlbmNlcyBjKSB7CisgICAgICAgIHN1cGVyKHApOworICAgICAgICBwYXJlbnQgPSBwOworICAgICAgICBjaGlsZCA9IGM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUge0Bjb2RlIFByZWZlcmVuY2VzfSBpbnN0YW5jZSB0aGF0IGZpcmVkIHRoaXMgZXZlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgUHJlZmVyZW5jZXN9IGluc3RhbmNlIHRoYXQgZmlyZWQgdGhpcyBldmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJlZmVyZW5jZXMgZ2V0UGFyZW50KCkgeworICAgICAgICByZXR1cm4gcGFyZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNoaWxkIHtAY29kZSBQcmVmZXJlbmNlc30gbm9kZSB0aGF0IHdhcyBhZGRlZCBvciByZW1vdmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYWRkZWQgb3IgcmVtb3ZlZCBjaGlsZCB7QGNvZGUgUHJlZmVyZW5jZXN9IG5vZGUuCisgICAgICovCisgICAgcHVibGljIFByZWZlcmVuY2VzIGdldENoaWxkKCkgeworICAgICAgICByZXR1cm4gY2hpbGQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgYWx3YXlzIHRocm93cyBhIDxjb2RlPk5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbjwvY29kZT4sCisgICAgICogYmVjYXVzZSB0aGlzIG9iamVjdCBjYW5ub3QgYmUgc2VyaWFsaXplZCwKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QgKE9iamVjdE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBOb3RTZXJpYWxpemFibGVFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBhbHdheXMgdGhyb3dzIGEgPGNvZGU+Tm90U2VyaWFsaXphYmxlRXhjZXB0aW9uPC9jb2RlPiwKKyAgICAgKiBiZWNhdXNlIHRoaXMgb2JqZWN0IGNhbm5vdCBiZSBzZXJpYWxpemVkLAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0IChPYmplY3RJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IE5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbigpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcHJlZnMvTm9kZUNoYW5nZUxpc3RlbmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL05vZGVDaGFuZ2VMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg5MGUzMWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL05vZGVDaGFuZ2VMaXN0ZW5lci5qYXZhCkBAIC0wLDAgKzEsNDggQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLnByZWZzOworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CisKKy8qKgorICogVGhpcyBpbnRlcmZhY2UgaXMgdXNlZCB0byBoYW5kbGUgcHJlZmVyZW5jZSBub2RlIGNoYW5nZSBldmVudHMuIFRoZQorICogaW1wbGVtZW50YXRpb24gb2YgdGhpcyBpbnRlcmZhY2UgY2FuIGJlIGluc3RhbGxlZCBieSB0aGUge0Bjb2RlIFByZWZlcmVuY2VzfQorICogaW5zdGFuY2UuCisgKgorICogQHNlZSBQcmVmZXJlbmNlcworICogQHNlZSBOb2RlQ2hhbmdlRXZlbnQKKyAqCisgKiBAc2luY2UgMS40CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgTm9kZUNoYW5nZUxpc3RlbmVyIGV4dGVuZHMgRXZlbnRMaXN0ZW5lciB7CisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgZ2V0cyBjYWxsZWQgd2hlbmV2ZXIgYSBjaGlsZCBub2RlIGlzIGFkZGVkIHRvIGFub3RoZXIgbm9kZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlCisgICAgICogICAgICAgICAgICB0aGUgbm9kZSBjaGFuZ2UgZXZlbnQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2hpbGRBZGRlZCAoTm9kZUNoYW5nZUV2ZW50IGUpOworCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgZ2V0cyBjYWxsZWQgd2hlbmV2ZXIgYSBjaGlsZCBub2RlIGlzIHJlbW92ZWQgZnJvbSBhbm90aGVyCisgICAgICogbm9kZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlCisgICAgICogICAgICAgICAgICB0aGUgbm9kZSBjaGFuZ2UgZXZlbnQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2hpbGRSZW1vdmVkIChOb2RlQ2hhbmdlRXZlbnQgZSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL05vZGVTZXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcHJlZnMvTm9kZVNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVhOGM5NzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL05vZGVTZXQuamF2YQpAQCAtMCwwICsxLDMzIEBACitwYWNrYWdlIGphdmEudXRpbC5wcmVmczsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CisKK2NsYXNzIE5vZGVTZXQgaW1wbGVtZW50cyBOb2RlTGlzdCB7CisKKyAgICBBcnJheUxpc3Q8Tm9kZT4gbGlzdCA9IG5ldyBBcnJheUxpc3Q8Tm9kZT4oKTsKKworICAgIHB1YmxpYyBOb2RlU2V0KEl0ZXJhdG9yPE5vZGU+IG5vZGVzKSB7CisgICAgICAgIHdoaWxlKG5vZGVzLmhhc05leHQoKSkgeworICAgICAgICAgICAgbGlzdC5hZGQobm9kZXMubmV4dCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gbGlzdC5zaXplKCk7CisgICAgfQorCisgICAgcHVibGljIE5vZGUgaXRlbShpbnQgaW5kZXgpIHsKKyAgICAgICAgTm9kZSByZXN1bHQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzdWx0ID0gbGlzdC5nZXQoaW5kZXgpOworICAgICAgICB9IGNhdGNoKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9vYmUpIHsKKyAgICAgICAgICAgIC8vIFRPRE8gbG9nIHRoaXMgZXZlbnQ/CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9wcmVmcy9QcmVmZXJlbmNlQ2hhbmdlRXZlbnQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcHJlZnMvUHJlZmVyZW5jZUNoYW5nZUV2ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODllNTgwNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcHJlZnMvUHJlZmVyZW5jZUNoYW5nZUV2ZW50LmphdmEKQEAgLTAsMCArMSwxMTIgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLnByZWZzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEudXRpbC5FdmVudE9iamVjdDsKKworLyoqCisgKiBUaGlzIGlzIHRoZSBldmVudCBjbGFzcyB0byBpbmRpY2F0ZSB0aGF0IGEgcHJlZmVyZW5jZSBoYXMgYmVlbiBhZGRlZCwgZGVsZXRlZAorICogb3IgdXBkYXRlZC4KKyAqIDxwPgorICogUGxlYXNlIG5vdGUgdGhhdCBhbHRob3VnaCB0aGUgY2xhc3MgaXMgbWFya2VkIGFzIHtAY29kZSBTZXJpYWxpemFibGV9IGJ5CisgKiBpbmhlcml0YW5jZSBmcm9tIHtAY29kZSBFdmVudE9iamVjdH0sIHRoaXMgdHlwZSBpcyBub3QgaW50ZW5kZWQgdG8gYmUgc2VyaWFsaXplZAorICogc28gdGhlIHNlcmlhbGl6YXRpb24gbWV0aG9kcyBkbyBub3RoaW5nIGJ1dCB0aHJvdyBhIHtAY29kZSBOb3RTZXJpYWxpemFibGVFeGNlcHRpb259LgorICoKKyAqIEBzZWUgamF2YS51dGlsLnByZWZzLlByZWZlcmVuY2VzCisgKiBAc2VlIGphdmEudXRpbC5wcmVmcy5QcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIKKyAqCisgKiBAc2luY2UgMS40CisgKi8KK3B1YmxpYyBjbGFzcyBQcmVmZXJlbmNlQ2hhbmdlRXZlbnQgZXh0ZW5kcyBFdmVudE9iamVjdCBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3OTM3MjQ1MTMzNjgwMjQ5NzVMOworCisgICAgcHJpdmF0ZSBmaW5hbCBQcmVmZXJlbmNlcyBub2RlOworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcga2V5OworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgdmFsdWU7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBuZXcge0Bjb2RlIFByZWZlcmVuY2VDaGFuZ2VFdmVudH0gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBQcmVmZXJlbmNlc30gaW5zdGFuY2UgdGhhdCBmaXJlZCB0aGlzIGV2ZW50OyB0aGlzIG9iamVjdCBpcworICAgICAqICAgICAgICAgICAgY29uc2lkZXJlZCBhcyB0aGUgZXZlbnQncyBzb3VyY2UuCisgICAgICogQHBhcmFtIGsKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGFuZ2VkIHByZWZlcmVuY2Uga2V5LgorICAgICAqIEBwYXJhbSB2CisgICAgICogICAgICAgICAgICB0aGUgbmV3IHZhbHVlIG9mIHRoZSBjaGFuZ2VkIHByZWZlcmVuY2UsIHRoaXMgdmFsdWUgY2FuIGJlCisgICAgICogICAgICAgICAgICB7QGNvZGUgbnVsbH0sIHdoaWNoIG1lYW5zIHRoZSBwcmVmZXJlbmNlIGhhcyBiZWVuIHJlbW92ZWQuCisgICAgICovCisgICAgcHVibGljIFByZWZlcmVuY2VDaGFuZ2VFdmVudChQcmVmZXJlbmNlcyBwLCBTdHJpbmcgaywgU3RyaW5nIHYpIHsKKyAgICAgICAgc3VwZXIocCk7CisgICAgICAgIG5vZGUgPSBwOworICAgICAgICBrZXkgPSBrOworICAgICAgICB2YWx1ZSA9IHY7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUga2V5IG9mIHRoZSBjaGFuZ2VkIHByZWZlcmVuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFuZ2VkIHByZWZlcmVuY2UncyBrZXkuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRLZXkoKSB7CisgICAgICAgIHJldHVybiBrZXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbmV3IHZhbHVlIG9mIHRoZSBjaGFuZ2VkIHByZWZlcmVuY2Ugb3Ige0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqIHByZWZlcmVuY2UgaGFzIGJlZW4gcmVtb3ZlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5ldyB2YWx1ZSBvZiB0aGUgY2hhbmdlZCBwcmVmZXJlbmNlIG9yIHtAY29kZSBudWxsfSBpZiB0aGUKKyAgICAgKiAgICAgICAgIHByZWZlcmVuY2UgaGFzIGJlZW4gcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5ld1ZhbHVlKCkgeworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUge0Bjb2RlIFByZWZlcmVuY2VzfSBpbnN0YW5jZSB0aGF0IGZpcmVkIHRoaXMgZXZlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgUHJlZmVyZW5jZXN9IGluc3RhbmNlIHRoYXQgZmlyZWQgdGhpcyBldmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJlZmVyZW5jZXMgZ2V0Tm9kZSgpIHsKKyAgICAgICAgcmV0dXJuIG5vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgYWx3YXlzIHRocm93cyBhIDxjb2RlPk5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbjwvY29kZT4sCisgICAgICogYmVjYXVzZSB0aGlzIG9iamVjdCBjYW5ub3QgYmUgc2VyaWFsaXplZCwKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IE5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGFsd2F5cyB0aHJvd3MgYSA8Y29kZT5Ob3RTZXJpYWxpemFibGVFeGNlcHRpb248L2NvZGU+LAorICAgICAqIGJlY2F1c2UgdGhpcyBvYmplY3QgY2Fubm90IGJlIHNlcmlhbGl6ZWQsCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbnsKKyAgICAgICAgdGhyb3cgbmV3IE5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbigpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcHJlZnMvUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL1ByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVlMWFmODMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL1ByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lci5qYXZhCkBAIC0wLDAgKzEsNDMgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLnByZWZzOworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CisKKy8qKgorICogVGhpcyBpbnRlcmZhY2UgaXMgdXNlZCB0byBoYW5kbGUgcHJlZmVyZW5jZXMgY2hhbmdlIGV2ZW50cy4gVGhlCisgKiBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGludGVyZmFjZSBjYW4gYmUgaW5zdGFsbGVkIGJ5IHRoZSB7QGNvZGUgUHJlZmVyZW5jZXN9CisgKiBpbnN0YW5jZS4KKyAqCisgKiBAc2VlIFByZWZlcmVuY2VzCisgKiBAc2VlIFByZWZlcmVuY2VDaGFuZ2VFdmVudAorICoKKyAqCisgKiBAc2luY2UgMS40CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyIGV4dGVuZHMgRXZlbnRMaXN0ZW5lciB7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBnZXRzIGludm9rZWQgd2hlbmV2ZXIgYSBwcmVmZXJlbmNlIGlzIGFkZGVkLCBkZWxldGVkIG9yCisgICAgICogdXBkYXRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwY2UKKyAgICAgKiAgICAgICAgICAgIHRoZSBldmVudCBpbnN0YW5jZSB3aGljaCBkZXNjcmliZXMgdGhlIGNoYW5nZWQge0Bjb2RlIFByZWZlcmVuY2VzfQorICAgICAqICAgICAgICAgICAgaW5zdGFuY2UgYW5kIHRoZSBwcmVmZXJlbmNlIHZhbHVlLgorICAgICAqLworICAgIHZvaWQgcHJlZmVyZW5jZUNoYW5nZSAoUHJlZmVyZW5jZUNoYW5nZUV2ZW50IHBjZSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL1ByZWZlcmVuY2VzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL1ByZWZlcmVuY2VzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjgwODA1MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcHJlZnMvUHJlZmVyZW5jZXMuamF2YQpAQCAtMCwwICsxLDg1OSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwucHJlZnM7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyOworCisvKioKKyAqIEFuIGluc3RhbmNlIG9mIHRoZSBjbGFzcyB7QGNvZGUgUHJlZmVyZW5jZXN9IHJlcHJlc2VudHMgb25lIG5vZGUgaW4gYQorICogcHJlZmVyZW5jZSB0cmVlLCB3aGljaCBwcm92aWRlcyBhIG1lY2hhbmlzbSB0byBzdG9yZSBhbmQgYWNjZXNzIGNvbmZpZ3VyYXRpb24KKyAqIGRhdGEgaW4gYSBoaWVyYXJjaGljYWwgd2F5LiBUd28gaGllcmFyY2h5IHRyZWVzIGFyZSBtYWludGFpbmVkLCBvbmUgZm9yCisgKiBzeXN0ZW0gcHJlZmVyZW5jZXMgc2hhcmVkIGJ5IGFsbCB1c2VycyBhbmQgdGhlIG90aGVyIGZvciB1c2VyIHByZWZlcmVuY2VzCisgKiBzcGVjaWZpYyB0byB0aGUgdXNlci4ge0Bjb2RlIFByZWZlcmVuY2VzfSBoaWVyYXJjaHkgdHJlZXMgYW5kIGRhdGEgYXJlIHN0b3JlZAorICogaW4gYW4gaW1wbGVtZW50YXRpb24tZGVwZW5kZW50IGJhY2stZW5kLgorICogPHA+CisgKiBFdmVyeSBub2RlIGhhcyBvbmUgbmFtZSBhbmQgb25lIHVuaXF1ZSBhYnNvbHV0ZSBwYXRoIGZvbGxvd2luZyB0aGUgc2FtZQorICogbm90YXRpb25hbCBjb252ZW50aW9ucyBhcyBkaXJlY3RvcmllcyBpbiBhIGZpbGUgc3lzdGVtLiBUaGUgcm9vdCBub2RlJ3MKKyAqIG5hbWUgaXMgIiIsIGFuZCBvdGhlciBub2RlIG5hbWUgc3RyaW5ncyBjYW5ub3QgY29udGFpbiB0aGUgc2xhc2ggY2hhcmFjdGVyCisgKiBhbmQgY2Fubm90IGJlIGVtcHR5LiBUaGUgcm9vdCBub2RlJ3MgYWJzb2x1dGUgcGF0aCBpcyAiLyIsIGFuZCBhbGwgb3RoZXIKKyAqIG5vZGVzJyBhYnNvbHV0ZSBwYXRocyBhcmUgY29uc3RydWN0ZWQgaW4gdGhlIHN0YW5kYXJkIHdheTogJmx0O3BhcmVudCdzCisgKiBhYnNvbHV0ZSBwYXRoJmd0OyArICIvIiArICZsdDtub2RlJ3MgbmFtZSZndDsuIFNpbmNlIHRoZSBzZXQgb2Ygbm9kZXMgZm9ybXMgYQorICogdHJlZSB3aXRoIHRoZSByb290IG5vZGUgYXQgaXRzIGJhc2UsIGFsbCBhYnNvbHV0ZSBwYXRocyBzdGFydCB3aXRoIHRoZSBzbGFzaAorICogY2hhcmFjdGVyLiBFdmVyeSBub2RlIGhhcyBvbmUgcmVsYXRpdmUgcGF0aCB0byBlYWNoIG9mIGl0cyBhbmNlc3RvcnMuIFRoZQorICogcmVsYXRpdmUgcGF0aCBkb2Vzbid0IHN0YXJ0IHdpdGggc2xhc2g6IGl0IGVxdWFscyB0aGUgbm9kZSdzIGFic29sdXRlIHBhdGgKKyAqIHdpdGggbGVhZGluZyBzdWJzdHJpbmcgcmVtb3ZlZCBjb3JyZXNwb25kaW5nIHRvIHRoZSBhbmNlc3RvcidzIGFic29sdXRlIHBhdGgKKyAqIGFuZCBhIHNsYXNoLgorICogPHA+CisgKiBNb2RpZmljYXRpb24gdG8gcHJlZmVyZW5jZXMgZGF0YSBtYXkgYmUgYXN5bmNocm9ub3VzLCB3aGljaCBtZWFucyB0aGF0CisgKiBwcmVmZXJlbmNlIHVwZGF0ZSBtZXRob2QgY2FsbHMgbWF5IHJldHVybiBpbW1lZGlhdGVseSBpbnN0ZWFkIG9mIGJsb2NraW5nLgorICogVGhlIHtAY29kZSBmbHVzaCgpfSBhbmQge0Bjb2RlIHN5bmMoKX0gbWV0aG9kcyBmb3JjZSB0aGUgYmFjay1lbmQgdG8KKyAqIHN5bmNocm9ub3VzbHkgcGVyZm9ybSBhbGwgcGVuZGluZyB1cGRhdGVzLCBidXQgdGhlIGltcGxlbWVudGF0aW9uIGlzCisgKiBwZXJtaXR0ZWQgdG8gcGVyZm9ybSB0aGUgbW9kaWZpY2F0aW9ucyBvbiB0aGUgdW5kZXJseWluZyBiYWNrLWVuZCBkYXRhCisgKiBhdCBhbnkgdGltZSBiZXR3ZWVuIHRoZSBtb21lbnQgdGhlIHJlcXVlc3QgaXMgbWFkZSBhbmQgdGhlIG1vbWVudCB0aGUKKyAqIHtAY29kZSBmbHVzaCgpfSBvciB7QGNvZGUgc3luYygpfSBtZXRob2QgcmV0dXJucy4gUGxlYXNlIG5vdGUgdGhhdCBpZiB0aGUgSlZNCisgKiBleGl0cyBub3JtYWxseSwgdGhlIGltcGxlbWVudGF0aW9uIG11c3QgYXNzdXJlIGFsbCBtb2RpZmljYXRpb25zIGFyZQorICogcGVyc2lzdGVkIGltcGxpY2l0bHkuCisgKiA8cD4KKyAqIFdoZW4gaW52b2tpbmcgYSBtZXRob2QgdGhhdCByZXRyaWV2ZXMgcHJlZmVyZW5jZXMsIHRoZSB1c2VyIG11c3QgcHJvdmlkZQorICogYSBkZWZhdWx0IHZhbHVlLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyByZXR1cm5lZCB3aGVuIHRoZSBwcmVmZXJlbmNlcyBjYW5ub3QKKyAqIGJlIGZvdW5kIG9yIHRoZSBiYWNrLWVuZCBpcyB1bmF2YWlsYWJsZS4gU29tZSBvdGhlciBtZXRob2RzIHdpbGwgdGhyb3cKKyAqIHtAY29kZSBCYWNraW5nU3RvcmVFeGNlcHRpb259IHdoZW4gdGhlIGJhY2stZW5kIGlzIHVuYXZhaWxhYmxlLgorICogPC9wPgorICogPHA+CisgKiBQcmVmZXJlbmNlcyBjYW4gYmUgZXhwb3J0ZWQgdG8gYW5kIGltcG9ydGVkIGZyb20gYW4gWE1MIGZpbGVzLiBUaGVzZQorICogZG9jdW1lbnRzIG11c3QgaGF2ZSBhbiBYTUwgRE9DVFlQRSBkZWNsYXJhdGlvbjoKKyAqIDxwcmU+e0Bjb2RlCisgKiA8IURPQ1RZUEUgcHJlZmVyZW5jZXMgU1lTVEVNICJodHRwOi8vamF2YS5zdW4uY29tL2R0ZC9wcmVmZXJlbmNlcy5kdGQiPgorICogfTwvcHJlPgorICogVGhpcyBzeXN0ZW0gVVJJIGlzIG5vdCByZWFsbHkgYWNjZXNzZWQgYnkgbmV0d29yaywgaXQgaXMgb25seSBhCisgKiBpZGVudGlmaWNhdGlvbiBzdHJpbmcuIFZpc2l0IHRoZSBEVEQgbG9jYXRpb24gdG8gc2VlIHRoZSBhY3R1YWwgZm9ybWF0CisgKiBwZXJtaXR0ZWQuCisgKiA8cD4KKyAqIFRoZXJlIG11c3QgYmUgYSBjb25jcmV0ZSB7QGNvZGUgUHJlZmVyZW5jZXNGYWN0b3J5fSB0eXBlIGZvciBldmVyeSBjb25jcmV0ZQorICoge0Bjb2RlIFByZWZlcmVuY2VzfSB0eXBlIGRldmVsb3BlZC4gRXZlcnkgSjJTRSBpbXBsZW1lbnRhdGlvbiBtdXN0IHByb3ZpZGUgYQorICogZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBmb3IgZXZlcnkgc3VwcG9ydGVkIHBsYXRmb3JtLCBhbmQgbXVzdCBhbHNvIHByb3ZpZGUgYQorICogbWVhbnMgb2YgcmVwbGFjaW5nIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uLiBUaGlzIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlCisgKiBzeXN0ZW0gcHJvcGVydHkge0Bjb2RlIGphdmEudXRpbC5wcmVmcy5QcmVmZXJlbmNlc0ZhY3Rvcnl9IHRvIGRldGVybWluZSB3aGljaAorICogcHJlZmVyZW5jZXMgaW1wbGVtZW50YXRpb24gdG8gdXNlLgorICogPHA+CisgKiBUaGUgbWV0aG9kcyBvZiB0aGlzIGNsYXNzIGFyZSB0aHJlYWQtc2FmZS4gSWYgbXVsdGlwbGUgSlZNcyBhcmUgdXNpbmcgdGhlCisgKiBzYW1lIGJhY2stZW5kIGNvbmN1cnJlbnRseSwgdGhlIGJhY2stZW5kIHdvbid0IGJlIGNvcnJ1cHRlZCwgYnV0IG5vIG90aGVyCisgKiBiZWhhdmlvciBndWFyYW50ZWVzIGFyZSBtYWRlLgorICoKKyAqIEBzZWUgUHJlZmVyZW5jZXNGYWN0b3J5CisgKgorICogQHNpbmNlIDEuNAorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgUHJlZmVyZW5jZXMgeworICAgIC8qKgorICAgICAqIE1heGltdW0gc2l6ZSBpbiBjaGFyYWN0ZXJzIGFsbG93ZWQgZm9yIGEgcHJlZmVyZW5jZXMga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9LRVlfTEVOR1RIID0gODA7CisKKyAgICAvKioKKyAgICAgKiBNYXhpbXVtIHNpemUgaW4gY2hhcmFjdGVycyBhbGxvd2VkIGZvciBhIHByZWZlcmVuY2VzIG5hbWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX05BTUVfTEVOR1RIID0gODA7CisKKyAgICAvKioKKyAgICAgKiBNYXhpbXVtIHNpemUgaW4gY2hhcmFjdGVycyBhbGxvd2VkIGZvciBhIHByZWZlcmVuY2VzIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9WQUxVRV9MRU5HVEggPSA4MTkyOworCisgICAgLy9mYWN0b3J5IHVzZWQgdG8gZ2V0IHVzZXIvc3lzdGVtIHByZWZzIHJvb3QKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQcmVmZXJlbmNlc0ZhY3RvcnkgZmFjdG9yeSA9IGZpbmRQcmVmZXJlbmNlc0ZhY3RvcnkoKTsKKworICAgIHByaXZhdGUgc3RhdGljIFByZWZlcmVuY2VzRmFjdG9yeSBmaW5kUHJlZmVyZW5jZXNGYWN0b3J5KCkgeworICAgICAgICAvLyBUcnkgdGhlIHN5c3RlbSBwcm9wZXJ0eSBmaXJzdC4uLgorICAgICAgICBQcmVmZXJlbmNlc0ZhY3RvcnkgcmVzdWx0ID0gU2VydmljZUxvYWRlci5sb2FkRnJvbVN5c3RlbVByb3BlcnR5KFByZWZlcmVuY2VzRmFjdG9yeS5jbGFzcyk7CisgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgICAgICAvLyBUaGVuIHVzZSBTZXJ2aWNlTG9hZGVyIGZvciBNRVRBLUlORi9zZXJ2aWNlcy8uLi4KKyAgICAgICAgZm9yIChQcmVmZXJlbmNlc0ZhY3RvcnkgaW1wbCA6IFNlcnZpY2VMb2FkZXIubG9hZChQcmVmZXJlbmNlc0ZhY3RvcnkuY2xhc3MpKSB7CisgICAgICAgICAgICByZXR1cm4gaW1wbDsKKyAgICAgICAgfQorICAgICAgICAvLyBGaW5hbGx5IHJldHVybiBhIGRlZmF1bHQuLi4KKyAgICAgICAgcmV0dXJuIG5ldyBGaWxlUHJlZmVyZW5jZXNGYWN0b3J5SW1wbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IsIGZvciB1c2UgYnkgc3ViY2xhc3NlcyBvbmx5LgorICAgICAqLworICAgIHByb3RlY3RlZCBQcmVmZXJlbmNlcygpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhYnNvbHV0ZSBwYXRoIHN0cmluZyBvZiB0aGlzIHByZWZlcmVuY2Ugbm9kZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByZWZlcmVuY2Ugbm9kZSdzIGFic29sdXRlIHBhdGggc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgYWJzb2x1dGVQYXRoKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lcyBvZiBhbGwgY2hpbGRyZW4gb2YgdGhpcyBub2RlIG9yIGFuIGVtcHR5IGFycmF5IGlmIHRoaXMKKyAgICAgKiBub2RlIGhhcyBubyBjaGlsZHJlbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWVzIG9mIGFsbCBjaGlsZHJlbiBvZiB0aGlzIG5vZGUuCisgICAgICogQHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBiYWNraW5nIHN0b3JlIGlzIHVuYXZhaWxhYmxlIG9yIGNhdXNlcyBhbiBvcGVyYXRpb24KKyAgICAgKiAgICAgICAgICAgICBmYWlsdXJlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBub2RlIGhhcyBiZWVuIHJlbW92ZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZ1tdIGNoaWxkcmVuTmFtZXMoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhbGwgcHJlZmVyZW5jZXMgb2YgdGhpcyBub2RlLgorICAgICAqCisgICAgICogQHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBiYWNraW5nIHN0b3JlIGlzIHVuYXZhaWxhYmxlIG9yIGNhdXNlcyBhbiBvcGVyYXRpb24KKyAgICAgKiAgICAgICAgICAgICBmYWlsdXJlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBub2RlIGhhcyBiZWVuIHJlbW92ZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgY2xlYXIoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRXhwb3J0cyBhbGwgb2YgdGhlIHByZWZlcmVuY2VzIG9mIHRoaXMgbm9kZSB0byBhIFhNTCBkb2N1bWVudCB1c2luZyB0aGUKKyAgICAgKiBnaXZlbiBvdXRwdXQgc3RyZWFtLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgWE1MIGRvY3VtZW50IHVzZXMgdGhlIFVURi04IGVuY29kaW5nIGFuZCBpcyB3cml0dGVuIGFjY29yZGluZyB0byB0aGUKKyAgICAgKiBEVEQgaW4gaXRzIERPQ1RZUEUgZGVjbGFyYXRpb24sIHdoaWNoIGlzIHRoZSBmb2xsb3dpbmc6CisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqICZsdDshRE9DVFlQRSBwcmVmZXJlbmNlcyBTWVNURU0gJnF1b3Q7aHR0cDovL2phdmEuc3VuLmNvbS9kdGQvcHJlZmVyZW5jZXMuZHRkJnF1b3Q7Jmd0OworICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogPGk+UGxlYXNlIG5vdGUgdGhhdCAodW5saWtlIHRoZSBtZXRob2RzIG9mIHRoaXMgY2xhc3MgdGhhdCBkb24ndCBjb25jZXJuCisgICAgICogc2VyaWFsaXphdGlvbiksIHRoaXMgY2FsbCBpcyBub3QgdGhyZWFkLXNhZmUuPC9pPgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvc3RyZWFtCisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IHN0cmVhbSB0byB3cml0ZSB0aGUgWE1MLWZvcm1hdHRlZCBkYXRhIHRvLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgZXhwb3J0aW5nLgorICAgICAqIEB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGJhY2tpbmcgc3RvcmUgaXMgdW5hdmFpbGFibGUgb3IgY2F1c2VzIGFuIG9wZXJhdGlvbgorICAgICAqICAgICAgICAgICAgIGZhaWx1cmUuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG5vZGUgaGFzIGJlZW4gcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBleHBvcnROb2RlKE91dHB1dFN0cmVhbSBvc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24sIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEV4cG9ydHMgYWxsIG9mIHRoZSBwcmVmZXJlbmNlcyBvZiB0aGlzIG5vZGUgYW5kIGFsbCBpdHMgZGVzY2VuZGFudHMgdG8gYQorICAgICAqIFhNTCBkb2N1bWVudCB1c2luZyB0aGUgZ2l2ZW4gb3V0cHV0IHN0cmVhbS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIFhNTCBkb2N1bWVudCB1c2VzIHRoZSBVVEYtOCBlbmNvZGluZyBhbmQgaXMgd3JpdHRlbiBhY2NvcmRpbmcgdG8gdGhlCisgICAgICogRFREIGluIGl0cyBET0NUWVBFIGRlY2xhcmF0aW9uLCB3aGljaCBpcyB0aGUgZm9sbG93aW5nOgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiAmbHQ7IURPQ1RZUEUgcHJlZmVyZW5jZXMgU1lTVEVNICZxdW90O2h0dHA6Ly9qYXZhLnN1bi5jb20vZHRkL3ByZWZlcmVuY2VzLmR0ZCZxdW90OyZndDsKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIDxpPlBsZWFzZSBub3RlIHRoYXQgKHVubGlrZSB0aGUgbWV0aG9kcyBvZiB0aGlzIGNsYXNzIHRoYXQgZG9uJ3QgY29uY2VybgorICAgICAqIHNlcmlhbGl6YXRpb24pLCB0aGlzIGNhbGwgaXMgbm90IHRocmVhZC1zYWZlLjwvaT4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gb3N0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBzdHJlYW0gdG8gd3JpdGUgdGhlIFhNTC1mb3JtYXR0ZWQgZGF0YSB0by4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGV4cG9ydGluZy4KKyAgICAgKiBAdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBiYWNraW5nIHN0b3JlIGlzIHVuYXZhaWxhYmxlIG9yIGNhdXNlcyBhbiBvcGVyYXRpb24KKyAgICAgKiAgICAgICAgICAgICBmYWlsdXJlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBub2RlIGhhcyBiZWVuIHJlbW92ZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZXhwb3J0U3VidHJlZShPdXRwdXRTdHJlYW0gb3N0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgQmFja2luZ1N0b3JlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRm9yY2VzIGFsbCBwZW5kaW5nIHVwZGF0ZXMgdG8gdGhpcyBub2RlIGFuZCBpdHMgZGVzY2VuZGFudHMgdG8gYmUKKyAgICAgKiBwZXJzaXN0ZWQgaW4gdGhlIGJhY2tpbmcgc3RvcmUuCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBub2RlIGhhcyBiZWVuIHJlbW92ZWQsIHRoZSBpbnZvY2F0aW9uIG9mIHRoaXMgbWV0aG9kIG9ubHkgZmx1c2hlcworICAgICAqIHRoaXMgbm9kZSwgbm90IGl0cyBkZXNjZW5kYW50cy4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBiYWNraW5nIHN0b3JlIGlzIHVuYXZhaWxhYmxlIG9yIGNhdXNlcyBhbiBvcGVyYXRpb24KKyAgICAgKiAgICAgICAgICAgICBmYWlsdXJlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGZsdXNoKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHtAY29kZSBTdHJpbmd9IHZhbHVlIG1hcHBlZCB0byB0aGUgZ2l2ZW4ga2V5IG9yIGl0cyBkZWZhdWx0CisgICAgICogdmFsdWUgaWYgbm8gdmFsdWUgaXMgbWFwcGVkIG9yIG5vIGJhY2tpbmcgc3RvcmUgaXMgYXZhaWxhYmxlLgorICAgICAqIDxwPgorICAgICAqIFNvbWUgaW1wbGVtZW50YXRpb25zIG1heSBzdG9yZSBkZWZhdWx0IHZhbHVlcyBpbiBiYWNraW5nIHN0b3Jlcy4gSW4gdGhpcworICAgICAqIGNhc2UsIGlmIHRoZXJlIGlzIG5vIHZhbHVlIG1hcHBlZCB0byB0aGUgZ2l2ZW4ga2V5LCB0aGUgc3RvcmVkIGRlZmF1bHQKKyAgICAgKiB2YWx1ZSBpcyByZXR1cm5lZC4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUgcHJlZmVyZW5jZSBrZXkuCisgICAgICogQHBhcmFtIGRlZmx0CisgICAgICogICAgICAgICAgICB0aGUgZGVmYXVsdCB2YWx1ZSwgd2hpY2ggd2lsbCBiZSByZXR1cm5lZCBpZiBubyB2YWx1ZSBpcworICAgICAqICAgICAgICAgICAgbWFwcGVkIHRvIHRoZSBnaXZlbiBrZXkgb3Igbm8gYmFja2luZyBzdG9yZSBpcyBhdmFpbGFibGUuCisgICAgICogQHJldHVybiB0aGUgcHJlZmVyZW5jZSB2YWx1ZSBtYXBwZWQgdG8gdGhlIGdpdmVuIGtleS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbm9kZSBoYXMgYmVlbiByZW1vdmVkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFyYW1ldGVyIHtAY29kZSBrZXl9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldChTdHJpbmcga2V5LCBTdHJpbmcgZGVmbHQpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUge0Bjb2RlIGJvb2xlYW59IHZhbHVlIG1hcHBlZCB0byB0aGUgZ2l2ZW4ga2V5IG9yIGl0cyBkZWZhdWx0CisgICAgICogdmFsdWUgaWYgbm8gdmFsdWUgaXMgbWFwcGVkLCBpZiB0aGUgYmFja2luZyBzdG9yZSBpcyB1bmF2YWlsYWJsZSwgb3IgaWYKKyAgICAgKiB0aGUgdmFsdWUgaXMgaW52YWxpZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgb25seSB2YWxpZCB2YWx1ZXMgYXJlIHRoZSB7QGNvZGUgU3RyaW5nfSAidHJ1ZSIsIHdoaWNoIHJlcHJlc2VudHMKKyAgICAgKiB7QGNvZGUgdHJ1ZX0gYW5kICJmYWxzZSIsIHdoaWNoIHJlcHJlc2VudHMge0Bjb2RlIGZhbHNlfSwgaWdub3JpbmcgY2FzZS4KKyAgICAgKiA8L3A+CisgICAgICogPHA+CisgICAgICogU29tZSBpbXBsZW1lbnRhdGlvbnMgbWF5IHN0b3JlIGRlZmF1bHQgdmFsdWVzIGluIGJhY2tpbmcgc3RvcmVzLiBJbiB0aGlzCisgICAgICogY2FzZSwgaWYgdGhlcmUgaXMgbm8gdmFsdWUgbWFwcGVkIHRvIHRoZSBnaXZlbiBrZXksIHRoZSBzdG9yZWQgZGVmYXVsdAorICAgICAqIHZhbHVlIGlzIHJldHVybmVkLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmVmZXJlbmNlIGtleS4KKyAgICAgKiBAcGFyYW0gZGVmbHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZWZhdWx0IHZhbHVlLCB3aGljaCB3aWxsIGJlIHJldHVybmVkIGlmIG5vIHZhbHVlIGlzCisgICAgICogICAgICAgICAgICBtYXBwZWQgdG8gdGhlIGdpdmVuIGtleSwgaWYgdGhlIGJhY2tpbmcgc3RvcmUgaXMgdW5hdmFpbGFibGUsCisgICAgICogICAgICAgICAgICBvciBpZiB0aGUgdmFsdWUgaXMgaW52YWxpZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBib29sZWFuIHZhbHVlIG1hcHBlZCB0byB0aGUgZ2l2ZW4ga2V5LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBub2RlIGhhcyBiZWVuIHJlbW92ZWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYXJhbWV0ZXIge0Bjb2RlIGtleX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGdldEJvb2xlYW4oU3RyaW5nIGtleSwgYm9vbGVhbiBkZWZsdCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB7QGNvZGUgYnl0ZX0gYXJyYXkgdmFsdWUgbWFwcGVkIHRvIHRoZSBnaXZlbiBrZXkgb3IgaXRzIGRlZmF1bHQKKyAgICAgKiB2YWx1ZSBpZiBubyB2YWx1ZSBpcyBtYXBwZWQsIGlmIHRoZSBiYWNraW5nIHN0b3JlIGlzIHVuYXZhaWxhYmxlLCBvciBpZgorICAgICAqIHRoZSB2YWx1ZSBpcyBhbiBpbnZhbGlkIHN0cmluZy4KKyAgICAgKiA8cD4KKyAgICAgKiBUbyBiZSB2YWxpZCwgdGhlIHZhbHVlIHN0cmluZyBtdXN0IGJlIEJhc2U2NC1lbmNvZGVkIGJpbmFyeSBkYXRhLiBUaGUKKyAgICAgKiBCYXNlNjQgZW5jb2RpbmcgaXMgYXMgZGVmaW5lZCBpbiA8YQorICAgICAqIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIwNDUudHh0Ij5SRkMgMjA0NTwvYT4sIHNlY3Rpb24gNi44LgorICAgICAqIDwvcD4KKyAgICAgKiA8cD4KKyAgICAgKiBTb21lIGltcGxlbWVudGF0aW9ucyBtYXkgc3RvcmUgZGVmYXVsdCB2YWx1ZXMgaW4gYmFja2luZyBzdG9yZXMuIEluIHRoaXMKKyAgICAgKiBjYXNlLCBpZiB0aGVyZSBpcyBubyB2YWx1ZSBtYXBwZWQgdG8gdGhlIGdpdmVuIGtleSwgdGhlIHN0b3JlZCBkZWZhdWx0CisgICAgICogdmFsdWUgaXMgcmV0dXJuZWQuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIHByZWZlcmVuY2Uga2V5LgorICAgICAqIEBwYXJhbSBkZWZsdAorICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgdmFsdWUsIHdoaWNoIHdpbGwgYmUgcmV0dXJuZWQgaWYgbm8gdmFsdWUgaXMKKyAgICAgKiAgICAgICAgICAgIG1hcHBlZCB0byB0aGUgZ2l2ZW4ga2V5LCBpZiB0aGUgYmFja2luZyBzdG9yZSBpcyB1bmF2YWlsYWJsZSwKKyAgICAgKiAgICAgICAgICAgIG9yIGlmIHRoZSB2YWx1ZSBpcyBpbnZhbGlkLgorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgYXJyYXkgdmFsdWUgbWFwcGVkIHRvIHRoZSBnaXZlbiBrZXkuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG5vZGUgaGFzIGJlZW4gcmVtb3ZlZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBhcmFtZXRlciB7QGNvZGUga2V5fSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJ5dGVbXSBnZXRCeXRlQXJyYXkoU3RyaW5nIGtleSwgYnl0ZVtdIGRlZmx0KTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHtAY29kZSBkb3VibGV9IHZhbHVlIG1hcHBlZCB0byB0aGUgZ2l2ZW4ga2V5IG9yIGl0cyBkZWZhdWx0CisgICAgICogdmFsdWUgaWYgbm8gdmFsdWUgaXMgbWFwcGVkLCBpZiB0aGUgYmFja2luZyBzdG9yZSBpcyB1bmF2YWlsYWJsZSwgb3IgaWYKKyAgICAgKiB0aGUgdmFsdWUgaXMgYW4gaW52YWxpZCBzdHJpbmcuCisgICAgICogPHA+CisgICAgICogVG8gYmUgdmFsaWQsIHRoZSB2YWx1ZSBzdHJpbmcgbXVzdCBiZSBhIHN0cmluZyB0aGF0IGNhbiBiZSBjb252ZXJ0ZWQgdG8gYQorICAgICAqIHtAY29kZSBkb3VibGV9IGJ5IHtAbGluayBEb3VibGUjcGFyc2VEb3VibGUoU3RyaW5nKQorICAgICAqIERvdWJsZS5wYXJzZURvdWJsZShTdHJpbmcpfS4KKyAgICAgKiA8cD4KKyAgICAgKiBTb21lIGltcGxlbWVudGF0aW9ucyBtYXkgc3RvcmUgZGVmYXVsdCB2YWx1ZXMgaW4gYmFja2luZyBzdG9yZXMuIEluIHRoaXMKKyAgICAgKiBjYXNlLCBpZiB0aGVyZSBpcyBubyB2YWx1ZSBtYXBwZWQgdG8gdGhlIGdpdmVuIGtleSwgdGhlIHN0b3JlZCBkZWZhdWx0CisgICAgICogdmFsdWUgaXMgcmV0dXJuZWQuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIHByZWZlcmVuY2Uga2V5LgorICAgICAqIEBwYXJhbSBkZWZsdAorICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgdmFsdWUsIHdoaWNoIHdpbGwgYmUgcmV0dXJuZWQgaWYgbm8gdmFsdWUgaXMKKyAgICAgKiAgICAgICAgICAgIG1hcHBlZCB0byB0aGUgZ2l2ZW4ga2V5LCBpZiB0aGUgYmFja2luZyBzdG9yZSBpcyB1bmF2YWlsYWJsZSwgb3IgaWYgdGhlCisgICAgICogICAgICAgICAgICB2YWx1ZSBpcyBpbnZhbGlkLgorICAgICAqIEByZXR1cm4gdGhlIGRvdWJsZSB2YWx1ZSBtYXBwZWQgdG8gdGhlIGdpdmVuIGtleS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbm9kZSBoYXMgYmVlbiByZW1vdmVkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFyYW1ldGVyIHtAY29kZSBrZXl9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgZG91YmxlIGdldERvdWJsZShTdHJpbmcga2V5LCBkb3VibGUgZGVmbHQpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUge0Bjb2RlIGZsb2F0fSB2YWx1ZSBtYXBwZWQgdG8gdGhlIGdpdmVuIGtleSBvciBpdHMgZGVmYXVsdCB2YWx1ZQorICAgICAqIGlmIG5vIHZhbHVlIGlzIG1hcHBlZCwgaWYgdGhlIGJhY2tpbmcgc3RvcmUgaXMgdW5hdmFpbGFibGUsIG9yIGlmIHRoZQorICAgICAqIHZhbHVlIGlzIGFuIGludmFsaWQgc3RyaW5nLgorICAgICAqIDxwPgorICAgICAqIFRvIGJlIHZhbGlkLCB0aGUgdmFsdWUgc3RyaW5nIG11c3QgYmUgYSBzdHJpbmcgdGhhdCBjYW4gYmUgY29udmVydGVkIHRvIGEKKyAgICAgKiB7QGNvZGUgZmxvYXR9IGJ5IHtAbGluayBGbG9hdCNwYXJzZUZsb2F0KFN0cmluZykKKyAgICAgKiBGbG9hdC5wYXJzZUZsb2F0KFN0cmluZyl9LgorICAgICAqIDwvcD4KKyAgICAgKiA8cD4KKyAgICAgKiBTb21lIGltcGxlbWVudGF0aW9ucyBtYXkgc3RvcmUgZGVmYXVsdCB2YWx1ZXMgaW4gYmFja2luZyBzdG9yZXMuIEluIHRoaXMKKyAgICAgKiBjYXNlLCBpZiB0aGVyZSBpcyBubyB2YWx1ZSBtYXBwZWQgdG8gdGhlIGdpdmVuIGtleSwgdGhlIHN0b3JlZCBkZWZhdWx0CisgICAgICogdmFsdWUgaXMgcmV0dXJuZWQuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIHByZWZlcmVuY2Uga2V5LgorICAgICAqIEBwYXJhbSBkZWZsdAorICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgdmFsdWUsIHdoaWNoIHdpbGwgYmUgcmV0dXJuZWQgaWYgbm8gdmFsdWUgaXMKKyAgICAgKiAgICAgICAgICAgIG1hcHBlZCB0byB0aGUgZ2l2ZW4ga2V5LCBpZiB0aGUgYmFja2luZyBzdG9yZSBpcyB1bmF2YWlsYWJsZSwgb3IgaWYgdGhlCisgICAgICogICAgICAgICAgICB2YWx1ZSBpcyBpbnZhbGlkLgorICAgICAqIEByZXR1cm4gdGhlIGZsb2F0IHZhbHVlIG1hcHBlZCB0byB0aGUgZ2l2ZW4ga2V5LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBub2RlIGhhcyBiZWVuIHJlbW92ZWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYXJhbWV0ZXIge0Bjb2RlIGtleX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBmbG9hdCBnZXRGbG9hdChTdHJpbmcga2V5LCBmbG9hdCBkZWZsdCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB7QGNvZGUgaW50fSB2YWx1ZSBtYXBwZWQgdG8gdGhlIGdpdmVuIGtleSBvciBpdHMgZGVmYXVsdCB2YWx1ZQorICAgICAqIGlmIG5vIHZhbHVlIGlzIG1hcHBlZCwgaWYgdGhlIGJhY2tpbmcgc3RvcmUgaXMgdW5hdmFpbGFibGUsIG9yIGlmIHRoZQorICAgICAqIHZhbHVlIGlzIGFuIGludmFsaWQgc3RyaW5nLgorICAgICAqIDxwPgorICAgICAqIFRvIGJlIHZhbGlkLCB0aGUgdmFsdWUgc3RyaW5nIG11c3QgYmUgYSBzdHJpbmcgdGhhdCBjYW4gYmUgY29udmVydGVkIHRvCisgICAgICogYW4ge0Bjb2RlIGludH0gYnkge0BsaW5rIEludGVnZXIjcGFyc2VJbnQoU3RyaW5nKQorICAgICAqIEludGVnZXIucGFyc2VJbnQoU3RyaW5nKX0uCisgICAgICogPC9wPgorICAgICAqIDxwPgorICAgICAqIFNvbWUgaW1wbGVtZW50YXRpb25zIG1heSBzdG9yZSBkZWZhdWx0IHZhbHVlcyBpbiBiYWNraW5nIHN0b3Jlcy4gSW4gdGhpcworICAgICAqIGNhc2UsIGlmIHRoZXJlIGlzIG5vIHZhbHVlIG1hcHBlZCB0byB0aGUgZ2l2ZW4ga2V5LCB0aGUgc3RvcmVkIGRlZmF1bHQKKyAgICAgKiB2YWx1ZSBpcyByZXR1cm5lZC4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUgcHJlZmVyZW5jZSBrZXkuCisgICAgICogQHBhcmFtIGRlZmx0CisgICAgICogICAgICAgICAgICB0aGUgZGVmYXVsdCB2YWx1ZSwgd2hpY2ggd2lsbCBiZSByZXR1cm5lZCBpZiBubyB2YWx1ZSBpcworICAgICAqICAgICAgICAgICAgbWFwcGVkIHRvIHRoZSBnaXZlbiBrZXksIGlmIHRoZSBiYWNraW5nIHN0b3JlIGlzIHVuYXZhaWxhYmxlLAorICAgICAqICAgICAgICAgICAgb3IgaWYgdGhlIHZhbHVlIGlzIGludmFsaWQuCisgICAgICogQHJldHVybiB0aGUgaW50ZWdlciB2YWx1ZSBtYXBwZWQgdG8gdGhlIGdpdmVuIGtleS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbm9kZSBoYXMgYmVlbiByZW1vdmVkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFyYW1ldGVyIHtAY29kZSBrZXl9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldEludChTdHJpbmcga2V5LCBpbnQgZGVmbHQpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUge0Bjb2RlIGxvbmd9IHZhbHVlIG1hcHBlZCB0byB0aGUgZ2l2ZW4ga2V5IG9yIGl0cyBkZWZhdWx0IHZhbHVlCisgICAgICogaWYgbm8gdmFsdWUgaXMgbWFwcGVkLCBpZiB0aGUgYmFja2luZyBzdG9yZSBpcyB1bmF2YWlsYWJsZSwgb3IgaWYgdGhlCisgICAgICogdmFsdWUgaXMgYW4gaW52YWxpZCBzdHJpbmcuCisgICAgICogPHA+CisgICAgICogVG8gYmUgdmFsaWQsIHRoZSB2YWx1ZSBzdHJpbmcgbXVzdCBiZSBhIHN0cmluZyB0aGF0IGNhbiBiZSBjb252ZXJ0ZWQgdG8gYQorICAgICAqIHtAY29kZSBsb25nfSBieSB7QGxpbmsgTG9uZyNwYXJzZUxvbmcoU3RyaW5nKSBMb25nLnBhcnNlTG9uZyhTdHJpbmcpfS4KKyAgICAgKiA8L3A+CisgICAgICogPHA+CisgICAgICogU29tZSBpbXBsZW1lbnRhdGlvbnMgbWF5IHN0b3JlIGRlZmF1bHQgdmFsdWVzIGluIGJhY2tpbmcgc3RvcmVzLiBJbiB0aGlzCisgICAgICogY2FzZSwgaWYgdGhlcmUgaXMgbm8gdmFsdWUgbWFwcGVkIHRvIHRoZSBnaXZlbiBrZXksIHRoZSBzdG9yZWQgZGVmYXVsdAorICAgICAqIHZhbHVlIGlzIHJldHVybmVkLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmVmZXJlbmNlIGtleS4KKyAgICAgKiBAcGFyYW0gZGVmbHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZWZhdWx0IHZhbHVlLCB3aGljaCB3aWxsIGJlIHJldHVybmVkIGlmIG5vIHZhbHVlIGlzCisgICAgICogICAgICAgICAgICBtYXBwZWQgdG8gdGhlIGdpdmVuIGtleSwgaWYgdGhlIGJhY2tpbmcgc3RvcmUgaXMgdW5hdmFpbGFibGUsCisgICAgICogICAgICAgICAgICBvciBpZiB0aGUgdmFsdWUgaXMgaW52YWxpZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBsb25nIHZhbHVlIG1hcHBlZCB0byB0aGUgZ2l2ZW4ga2V5LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBub2RlIGhhcyBiZWVuIHJlbW92ZWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYXJhbWV0ZXIge0Bjb2RlIGtleX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBsb25nIGdldExvbmcoU3RyaW5nIGtleSwgbG9uZyBkZWZsdCk7CisKKyAgICAvKioKKyAgICAgKiBJbXBvcnRzIGFsbCB0aGUgcHJlZmVyZW5jZXMgZnJvbSBhbiBYTUwgZG9jdW1lbnQgdXNpbmcgdGhlIGdpdmVuIGlucHV0CisgICAgICogc3RyZWFtLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgWE1MIGRvY3VtZW50IHVzZXMgdGhlIFVURi04IGVuY29kaW5nIGFuZCBtdXN0IGJlIHdyaXR0ZW4gYWNjb3JkaW5nCisgICAgICogdG8gdGhlIERURCBpbiBpdHMgRE9DVFlQRSBkZWNsYXJhdGlvbiwgd2hpY2ggbXVzdCBiZSB0aGUgZm9sbG93aW5nOgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiAmbHQ7IURPQ1RZUEUgcHJlZmVyZW5jZXMgU1lTVEVNICZxdW90O2h0dHA6Ly9qYXZhLnN1bi5jb20vZHRkL3ByZWZlcmVuY2VzLmR0ZCZxdW90OyZndDsKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIDxpPlBsZWFzZSBub3RlIHRoYXQgKHVubGlrZSB0aGUgbWV0aG9kcyBvZiB0aGlzIGNsYXNzIHRoYXQgZG9uJ3QgY29uY2VybgorICAgICAqIHNlcmlhbGl6YXRpb24pLCB0aGlzIGNhbGwgaXMgbm90IHRocmVhZC1zYWZlLjwvaT4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaXN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IHN0cmVhbSB0byByZWFkIHRoZSBkYXRhIGZyb20uCisgICAgICogQHRocm93cyBJbnZhbGlkUHJlZmVyZW5jZXNGb3JtYXRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZGF0YSByZWFkIGZyb20gdGhlIGdpdmVuIGlucHV0IHN0cmVhbSBpcyBub3QgZnJvbSBhCisgICAgICogICAgICAgICAgICAgdmFsaWQgWE1MIGRvY3VtZW50LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgaW1wb3J0aW5nLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBpbXBvcnRQcmVmZXJlbmNlcyAoSW5wdXRTdHJlYW0gaXN0cmVhbSkgdGhyb3dzIEludmFsaWRQcmVmZXJlbmNlc0Zvcm1hdEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaXN0cmVhbSA9PSBudWxsKXsKKyAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUkxFeGNlcHRpb24oIklucHV0c3RyZWFtIGNhbm5vdCBiZSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgWE1MUGFyc2VyLmltcG9ydFByZWZzKGlzdHJlYW0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIGlzIGEgdXNlciBwcmVmZXJlbmNlIG5vZGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSwgaWYgdGhpcyBpcyBhIHVzZXIgcHJlZmVyZW5jZSBub2RlLCB7QGNvZGUgZmFsc2V9IGlmCisgICAgICogICAgICAgICB0aGlzIGlzIGEgc3lzdGVtIHByZWZlcmVuY2Ugbm9kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc1VzZXJOb2RlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFsbCBwcmVmZXJlbmNlIGtleXMgc3RvcmVkIGluIHRoaXMgbm9kZSBvciBhbiBlbXB0eSBhcnJheSBpZiBubworICAgICAqIGtleSB3YXMgZm91bmQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsaXN0IG9mIGFsbCBwcmVmZXJlbmNlIGtleXMgb2YgdGhpcyBub2RlLgorICAgICAqIEB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGJhY2tpbmcgc3RvcmUgaXMgdW5hdmFpbGFibGUgb3IgY2F1c2VzIGFuIG9wZXJhdGlvbgorICAgICAqICAgICAgICAgICAgIGZhaWx1cmUuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG5vZGUgaGFzIGJlZW4gcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nW10ga2V5cygpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoaXMgbm9kZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhpcyBub2RlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgbmFtZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJlZmVyZW5jZSBub2RlIHdpdGggdGhlIGdpdmVuIHBhdGggbmFtZS4gVGhlIHBhdGggbmFtZSBjYW4KKyAgICAgKiBiZSByZWxhdGl2ZSBvciBhYnNvbHV0ZS4gVGhlIHJlcXVlc3RlZCBub2RlIGFuZCBpdHMgYW5jZXN0b3JzIHdpbGwKKyAgICAgKiBiZSBjcmVhdGVkIGlmIHRoZXkgZG8gbm90IGV4aXN0LgorICAgICAqIDxwPgorICAgICAqIFRoZSBwYXRoIGlzIHRyZWF0ZWQgYXMgcmVsYXRpdmUgdG8gdGhpcyBub2RlIGlmIGl0IGRvZXNuJ3Qgc3RhcnQgd2l0aCBhCisgICAgICogc2xhc2gsIG90aGVyd2lzZSBpdCB3aWxsIGJlIHRyZWF0ZWQgYXMgYW4gYWJzb2x1dGUgcGF0aC4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcGF0aAorICAgICAqICAgICAgICAgICAgdGhlIHBhdGggbmFtZSBvZiB0aGUgcmVxdWVzdGVkIHByZWZlcmVuY2Ugbm9kZS4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0ZWQgcHJlZmVyZW5jZSBub2RlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBub2RlIGhhcyBiZWVuIHJlbW92ZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGF0aCBuYW1lIGlzIGludmFsaWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBnaXZlbiBwYXRoIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgUHJlZmVyZW5jZXMgbm9kZShTdHJpbmcgcGF0aCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHByZWZlcmVuY2Ugbm9kZSB3aXRoIHRoZSBnaXZlbiBwYXRoIG5hbWUgZXhpc3RzLiBUaGUKKyAgICAgKiBwYXRoIGlzIHRyZWF0ZWQgYXMgcmVsYXRpdmUgdG8gdGhpcyBub2RlIGlmIGl0IGRvZXNuJ3Qgc3RhcnQgd2l0aCBhIHNsYXNoLAorICAgICAqIG90aGVyd2lzZSBpdCBpcyB0cmVhdGVkIGFzIGFuIGFic29sdXRlIHBhdGguCisgICAgICogPHA+CisgICAgICogUGxlYXNlIG5vdGUgdGhhdCBpZiB0aGlzIG5vZGUgaGFzIGJlZW4gcmVtb3ZlZCwgYW4gaW52b2NhdGlvbiBvZiB0aGlzCisgICAgICogbm9kZSB3aWxsIHRocm93IGFuIHtAY29kZSBJbGxlZ2FsU3RhdGVFeGNlcHRpb259IHVubGVzcyB0aGUgZ2l2ZW4gcGF0aCBpcworICAgICAqIGFuIGVtcHR5IHN0cmluZywgd2hpY2ggd2lsbCByZXR1cm4ge0Bjb2RlIGZhbHNlfS4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcGF0aAorICAgICAqICAgICAgICAgICAgdGhlIHBhdGggbmFtZSBvZiB0aGUgcHJlZmVyZW5jZSBub2RlIHRvIHF1ZXJ5LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9LCBpZiB0aGUgcXVlcmllZCBwcmVmZXJlbmNlIG5vZGUgZXhpc3RzLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG5vZGUgaGFzIGJlZW4gcmVtb3ZlZCBhbmQgdGhlIHBhdGggaXMgbm90IGFuIGVtcHR5CisgICAgICogICAgICAgICAgICAgc3RyaW5nLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBhdGggbmFtZSBpcyBpbnZhbGlkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2l2ZW4gcGF0aCBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgYmFja2luZyBzdG9yZSBpcyB1bmF2YWlsYWJsZSBvciBjYXVzZXMgYW4gb3BlcmF0aW9uCisgICAgICogICAgICAgICAgICAgZmFpbHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBub2RlRXhpc3RzKFN0cmluZyBwYXRoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGFyZW50IHByZWZlcmVuY2Ugbm9kZSBvZiB0aGlzIG5vZGUgb3Ige0Bjb2RlIG51bGx9IGlmIHRoaXMKKyAgICAgKiBub2RlIGlzIHRoZSByb290IG5vZGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwYXJlbnQgcHJlZmVyZW5jZSBub2RlIG9mIHRoaXMgbm9kZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbm9kZSBoYXMgYmVlbiByZW1vdmVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBQcmVmZXJlbmNlcyBwYXJlbnQoKTsKKworICAgIC8qKgorICAgICAqIEFkZHMgYSBuZXcgcHJlZmVyZW5jZSB0byB0aGlzIG5vZGUgdXNpbmcgdGhlIGdpdmVuIGtleSBhbmQgdmFsdWUgb3IKKyAgICAgKiB1cGRhdGVzIHRoZSB2YWx1ZSBpZiBhIHByZWZlcmVuY2Ugd2l0aCB0aGUgZ2l2ZW4ga2V5IGFscmVhZHkgZXhpc3RzLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIHByZWZlcmVuY2Uga2V5IHRvIGJlIGFkZGVkIG9yIHVwZGF0ZWQuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgcHJlZmVyZW5jZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGtleS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIGtleSBvciB2YWx1ZSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2l2ZW4ga2V5J3MgbGVuZ3RoIGlzIGJpZ2dlciB0aGFuIHtAY29kZQorICAgICAqICAgICAgICAgICAgIE1BWF9LRVlfTEVOR1RIfSBvciB0aGUgdmFsdWUncyBsZW5ndGggaXMgYmlnZ2VyIHRoYW4ge0Bjb2RlCisgICAgICogICAgICAgICAgICAgTUFYX1ZBTFVFX0xFTkdUSH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG5vZGUgaGFzIGJlZW4gcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBwdXQoU3RyaW5nIGtleSwgU3RyaW5nIHZhbHVlKTsKKworICAgIC8qKgorICAgICAqIEFkZHMgYSBuZXcgcHJlZmVyZW5jZSB3aXRoIGEge0Bjb2RlIGJvb2xlYW59IHZhbHVlIHRvIHRoaXMgbm9kZSB1c2luZyB0aGUKKyAgICAgKiBnaXZlbiBrZXkgYW5kIHZhbHVlIG9yIHVwZGF0ZXMgdGhlIHZhbHVlIGlmIGEgcHJlZmVyZW5jZSB3aXRoIHRoZSBnaXZlbgorICAgICAqIGtleSBhbHJlYWR5IGV4aXN0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmVmZXJlbmNlIGtleSB0byBiZSBhZGRlZCBvciB1cGRhdGVkLgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHByZWZlcmVuY2Uge0Bjb2RlIGJvb2xlYW59IHZhbHVlIGZvciB0aGUgZ2l2ZW4ga2V5LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2l2ZW4ga2V5IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBnaXZlbiBrZXkncyBsZW5ndGggaXMgYmlnZ2VyIHRoYW4ge0Bjb2RlCisgICAgICogICAgICAgICAgICAgTUFYX0tFWV9MRU5HVEh9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBub2RlIGhhcyBiZWVuIHJlbW92ZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcHV0Qm9vbGVhbihTdHJpbmcga2V5LCBib29sZWFuIHZhbHVlKTsKKworICAgIC8qKgorICAgICAqIEFkZHMgYSBuZXcgcHJlZmVyZW5jZSB0byB0aGlzIG5vZGUgdXNpbmcgdGhlIGdpdmVuIGtleSBhbmQgdGhlIHN0cmluZworICAgICAqIGZvcm0gb2YgdGhlIGdpdmVuIHZhbHVlIG9yIHVwZGF0ZXMgdGhlIHZhbHVlIGlmIGEgcHJlZmVyZW5jZSB3aXRoIHRoZQorICAgICAqIGdpdmVuIGtleSBhbHJlYWR5IGV4aXN0cy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgc3RyaW5nIGZvcm0gb2YgdGhlIHZhbHVlIGlzIHRoZSBCYXNlNjQtZW5jb2RlZCBiaW5hcnkgZGF0YSBvZiB0aGUKKyAgICAgKiBnaXZlbiBieXRlIGFycmF5LiBUaGUgQmFzZTY0IGVuY29kaW5nIGlzIGFzIGRlZmluZWQgaW4gPGEKKyAgICAgKiBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMDQ1LnR4dCI+UkZDIDIwNDU8L2E+LCBzZWN0aW9uIDYuOC4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUgcHJlZmVyZW5jZSBrZXkgdG8gYmUgYWRkZWQgb3IgdXBkYXRlZC4KKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmVmZXJlbmNlIHZhbHVlIGZvciB0aGUgZ2l2ZW4ga2V5LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2l2ZW4ga2V5IG9yIHZhbHVlIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBnaXZlbiBrZXkncyBsZW5ndGggaXMgYmlnZ2VyIHRoYW4ge0Bjb2RlCisgICAgICogICAgICAgICAgICAgTUFYX0tFWV9MRU5HVEh9IG9yIHZhbHVlJ3MgbGVuZ3RoIGlzIGJpZ2dlciB0aGFuIHRocmVlCisgICAgICogICAgICAgICAgICAgcXVhcnRlcnMgb2Yge0Bjb2RlIE1BWF9LRVlfTEVOR1RIfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbm9kZSBoYXMgYmVlbiByZW1vdmVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHB1dEJ5dGVBcnJheShTdHJpbmcga2V5LCBieXRlW10gdmFsdWUpOworCisgICAgLyoqCisgICAgICogQWRkcyBhIG5ldyBwcmVmZXJlbmNlIHRvIHRoaXMgbm9kZSB1c2luZyB0aGUgZ2l2ZW4ga2V5IGFuZCB7QGNvZGUgZG91YmxlfQorICAgICAqIHZhbHVlIG9yIHVwZGF0ZXMgdGhlIHZhbHVlIGlmIGEgcHJlZmVyZW5jZSB3aXRoIHRoZQorICAgICAqIGdpdmVuIGtleSBhbHJlYWR5IGV4aXN0cy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgdmFsdWUgaXMgc3RvcmVkIGluIGl0cyBzdHJpbmcgZm9ybSwgd2hpY2ggaXMgdGhlIHJlc3VsdCBvZiBpbnZva2luZworICAgICAqIHtAbGluayBEb3VibGUjdG9TdHJpbmcoZG91YmxlKSBEb3VibGUudG9TdHJpbmcoZG91YmxlKX0uCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIHByZWZlcmVuY2Uga2V5IHRvIGJlIGFkZGVkIG9yIHVwZGF0ZWQuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgcHJlZmVyZW5jZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGtleS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIGtleSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2l2ZW4ga2V5J3MgbGVuZ3RoIGlzIGJpZ2dlciB0aGFuIHtAY29kZQorICAgICAqICAgICAgICAgICAgIE1BWF9LRVlfTEVOR1RIfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbm9kZSBoYXMgYmVlbiByZW1vdmVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHB1dERvdWJsZShTdHJpbmcga2V5LCBkb3VibGUgdmFsdWUpOworCisgICAgLyoqCisgICAgICogQWRkcyBhIG5ldyBwcmVmZXJlbmNlIHRvIHRoaXMgbm9kZSB1c2luZyB0aGUgZ2l2ZW4ga2V5IGFuZCB7QGNvZGUgZmxvYXR9CisgICAgICogdmFsdWUgb3IgdXBkYXRlcyB0aGUgdmFsdWUgaWYgYSBwcmVmZXJlbmNlIHdpdGggdGhlCisgICAgICogZ2l2ZW4ga2V5IGFscmVhZHkgZXhpc3RzLgorICAgICAqIDxwPgorICAgICAqIFRoZSB2YWx1ZSBpcyBzdG9yZWQgaW4gaXRzIHN0cmluZyBmb3JtLCB3aGljaCBpcyB0aGUgcmVzdWx0IG9mIGludm9raW5nCisgICAgICoge0BsaW5rIEZsb2F0I3RvU3RyaW5nKGZsb2F0KSBGbG9hdC50b1N0cmluZyhmbG9hdCl9LgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmVmZXJlbmNlIGtleSB0byBiZSBhZGRlZCBvciB1cGRhdGVkLgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHByZWZlcmVuY2UgdmFsdWUgZm9yIHRoZSBnaXZlbiBrZXkuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBnaXZlbiBrZXkgaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIGtleSdzIGxlbmd0aCBpcyBiaWdnZXIgdGhhbiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBNQVhfS0VZX0xFTkdUSH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG5vZGUgaGFzIGJlZW4gcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBwdXRGbG9hdChTdHJpbmcga2V5LCBmbG9hdCB2YWx1ZSk7CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGEgbmV3IHByZWZlcmVuY2UgdG8gdGhpcyBub2RlIHVzaW5nIHRoZSBnaXZlbiBrZXkgYW5kIHtAY29kZSBpbnR9CisgICAgICogdmFsdWUgb3IgdXBkYXRlcyB0aGUgdmFsdWUgaWYgYSBwcmVmZXJlbmNlIHdpdGggdGhlCisgICAgICogZ2l2ZW4ga2V5IGFscmVhZHkgZXhpc3RzLgorICAgICAqIDxwPgorICAgICAqIFRoZSB2YWx1ZSBpcyBzdG9yZWQgaW4gaXRzIHN0cmluZyBmb3JtLCB3aGljaCBpcyB0aGUgcmVzdWx0IG9mIGludm9raW5nCisgICAgICoge0BsaW5rIEludGVnZXIjdG9TdHJpbmcoaW50KSBJbnRlZ2VyLnRvU3RyaW5nKGludCl9LgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcmVmZXJlbmNlIGtleSB0byBiZSBhZGRlZCBvciB1cGRhdGVkLgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIHByZWZlcmVuY2UgdmFsdWUgZm9yIHRoZSBnaXZlbiBrZXkuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBnaXZlbiBrZXkgaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIGtleSdzIGxlbmd0aCBpcyBiaWdnZXIgdGhhbiB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBNQVhfS0VZX0xFTkdUSH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG5vZGUgaGFzIGJlZW4gcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBwdXRJbnQoU3RyaW5nIGtleSwgaW50IHZhbHVlKTsKKworICAgIC8qKgorICAgICAqIEFkZHMgYSBuZXcgcHJlZmVyZW5jZSB0byB0aGlzIG5vZGUgdXNpbmcgdGhlIGdpdmVuIGtleSBhbmQge0Bjb2RlIGxvbmd9CisgICAgICogdmFsdWUgb3IgdXBkYXRlcyB0aGUgdmFsdWUgaWYgYSBwcmVmZXJlbmNlIHdpdGggdGhlCisgICAgICogZ2l2ZW4ga2V5IGFscmVhZHkgZXhpc3RzLgorICAgICAqIDxwPgorICAgICAqIFRoZSB2YWx1ZSBpcyBzdG9yZWQgaW4gaXRzIHN0cmluZyBmb3JtLCB3aGljaCBpcyB0aGUgcmVzdWx0IG9mIGludm9raW5nCisgICAgICoge0BsaW5rIExvbmcjdG9TdHJpbmcobG9uZykgTG9uZy50b1N0cmluZyhsb25nKX0uCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIHByZWZlcmVuY2Uga2V5IHRvIGJlIGFkZGVkIG9yIHVwZGF0ZWQuCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgcHJlZmVyZW5jZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGtleS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIGtleSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2l2ZW4ga2V5J3MgbGVuZ3RoIGlzIGJpZ2dlciB0aGFuIHtAY29kZQorICAgICAqICAgICAgICAgICAgIE1BWF9LRVlfTEVOR1RIfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbm9kZSBoYXMgYmVlbiByZW1vdmVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHB1dExvbmcoU3RyaW5nIGtleSwgbG9uZyB2YWx1ZSk7CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBwcmVmZXJlbmNlIG1hcHBlZCB0byB0aGUgZ2l2ZW4ga2V5IGZyb20gdGhpcyBub2RlLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBvZiB0aGUgcHJlZmVyZW5jZSB0byBiZSByZW1vdmVkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2l2ZW4ga2V5IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbm9kZSBoYXMgYmVlbiByZW1vdmVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHJlbW92ZShTdHJpbmcga2V5KTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhpcyBwcmVmZXJlbmNlIG5vZGUgd2l0aCBhbGwgaXRzIGRlc2NlbmRhbnRzLiBUaGUgcmVtb3ZhbCB3b24ndAorICAgICAqIG5lY2Vzc2FyaWx5IGJlIHBlcnNpc3RlZCB1bnRpbCB0aGUgbWV0aG9kIHtAY29kZSBmbHVzaCgpfSBpcyBpbnZva2VkLgorICAgICAqCisgICAgICogQHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgYmFja2luZyBzdG9yZSBpcyB1bmF2YWlsYWJsZSBvciBjYXVzZXMgYW4gb3BlcmF0aW9uCisgICAgICogICAgICAgICAgICAgZmFpbHVyZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbm9kZSBoYXMgYmVlbiByZW1vdmVkLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGlzIGEgcm9vdCBub2RlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHJlbW92ZU5vZGUoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVnaXN0ZXJzIGEge0Bjb2RlIE5vZGVDaGFuZ2VMaXN0ZW5lcn0gaW5zdGFuY2UgZm9yIHRoaXMgbm9kZSwgd2hpY2ggd2lsbAorICAgICAqIGhhbmRsZSB7QGNvZGUgTm9kZUNoYW5nZUV2ZW50fXMuIHtAY29kZSBOb2RlQ2hhbmdlRXZlbnR9cyB3aWxsIGJlIGZpcmVkCisgICAgICogd2hlbiBhIGNoaWxkIG5vZGUgaGFzIGJlZW4gYWRkZWQgdG8gb3IgcmVtb3ZlZCBmcm9tIHRoaXMgbm9kZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuY2wKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0ZW5lciB0byBiZSByZWdpc3RlcmVkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2l2ZW4gbGlzdGVuZXIgaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBub2RlIGhhcyBiZWVuIHJlbW92ZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgYWRkTm9kZUNoYW5nZUxpc3RlbmVyKE5vZGVDaGFuZ2VMaXN0ZW5lciBuY2wpOworCisgICAgLyoqCisgICAgICogUmVnaXN0ZXJzIGEge0Bjb2RlIFByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcn0gaW5zdGFuY2UgZm9yIHRoaXMgbm9kZSwKKyAgICAgKiB3aGljaCB3aWxsIGhhbmRsZSB7QGNvZGUgUHJlZmVyZW5jZUNoYW5nZUV2ZW50fXMuIHtAY29kZQorICAgICAqIFByZWZlcmVuY2VDaGFuZ2VFdmVudH1zIHdpbGwgYmUgZmlyZWQgd2hlbiBhIHByZWZlcmVuY2UgaGFzIGJlZW4gYWRkZWQKKyAgICAgKiB0bywgcmVtb3ZlZCBmcm9tLCBvciB1cGRhdGVkIGZvciB0aGlzIG5vZGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGNsCisgICAgICogICAgICAgICAgICB0aGUgbGlzdGVuZXIgdG8gYmUgcmVnaXN0ZXJlZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIGxpc3RlbmVyIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbm9kZSBoYXMgYmVlbiByZW1vdmVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGFkZFByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lciAoUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyIHBjbCk7CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBnaXZlbiB7QGNvZGUgTm9kZUNoYW5nZUxpc3RlbmVyfSBpbnN0YW5jZSBmcm9tIHRoaXMgbm9kZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuY2wKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0ZW5lciB0byBiZSByZW1vdmVkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIGxpc3RlbmVyIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgbm9kZSBoYXMgYmVlbiByZW1vdmVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHJlbW92ZU5vZGVDaGFuZ2VMaXN0ZW5lciAoTm9kZUNoYW5nZUxpc3RlbmVyIG5jbCk7CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBnaXZlbiB7QGNvZGUgUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyfSBpbnN0YW5jZSBmcm9tIHRoaXMKKyAgICAgKiBub2RlLgorICAgICAqCisgICAgICogQHBhcmFtIHBjbAorICAgICAqICAgICAgICAgICAgdGhlIGxpc3RlbmVyIHRvIGJlIHJlbW92ZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZ2l2ZW4gbGlzdGVuZXIgaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBub2RlIGhhcyBiZWVuIHJlbW92ZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcmVtb3ZlUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyIChQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIgcGNsKTsKKworICAgIC8qKgorICAgICAqIFN5bmNocm9uaXplcyB0aGUgZGF0YSBvZiB0aGlzIHByZWZlcmVuY2Ugbm9kZSBhbmQgaXRzIGRlc2NlbmRhbnRzIHdpdGgKKyAgICAgKiB0aGUgYmFjay1lbmQgcHJlZmVyZW5jZSBzdG9yZS4gQW55IGNoYW5nZXMgZm91bmQgaW4gdGhlIGJhY2stZW5kIGRhdGEKKyAgICAgKiBzaG91bGQgYmUgcmVmbGVjdGVkIGluIHRoaXMgbm9kZSBhbmQgaXRzIGRlc2NlbmRhbnRzLCBhbmQgYXQgdGhlIHNhbWUKKyAgICAgKiB0aW1lIGFueSBsb2NhbCBjaGFuZ2VzIHRvIHRoaXMgbm9kZSBhbmQgZGVzY2VuZGFudHMgc2hvdWxkIGJlIHBlcnNpc3RlZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGJhY2tpbmcgc3RvcmUgaXMgdW5hdmFpbGFibGUgb3IgY2F1c2VzIGFuIG9wZXJhdGlvbgorICAgICAqICAgICAgICAgICAgIGZhaWx1cmUuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIG5vZGUgaGFzIGJlZW4gcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzeW5jKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN5c3RlbSBwcmVmZXJlbmNlIG5vZGUgZm9yIHRoZSBwYWNrYWdlIG9mIHRoZSBnaXZlbiBjbGFzcy4KKyAgICAgKiBUaGUgYWJzb2x1dGUgcGF0aCBvZiB0aGUgcmV0dXJuZWQgbm9kZSBpcyBvbmUgc2xhc2ggZm9sbG93ZWQgYnkgdGhlIGdpdmVuCisgICAgICogY2xhc3MncyBmdWxsIHBhY2thZ2UgbmFtZSwgcmVwbGFjaW5nIGVhY2ggcGVyaW9kIGNoYXJhY3RlciAoJy4nKSB3aXRoCisgICAgICogYSBzbGFzaC4gRm9yIGV4YW1wbGUsIHRoZSBhYnNvbHV0ZSBwYXRoIG9mIHRoZSBwcmVmZXJlbmNlIGFzc29jaWF0ZWQgd2l0aAorICAgICAqIHRoZSBjbGFzcyBPYmplY3Qgd291bGQgYmUgIi9qYXZhL2xhbmciLiBBcyBhIHNwZWNpYWwgY2FzZSwgdGhlIHVubmFtZWQKKyAgICAgKiBwYWNrYWdlIGlzIGFzc29jaWF0ZWQgd2l0aCBhIHByZWZlcmVuY2Ugbm9kZSAiLyZsdDt1bm5hbWVkJmd0OyIuIFRoaXMKKyAgICAgKiBtZXRob2Qgd2lsbCBjcmVhdGUgdGhlIG5vZGUgYW5kIGl0cyBhbmNlc3RvcnMgYXMgbmVlZGVkLiBBbnkgbm9kZXMgY3JlYXRlZAorICAgICAqIGJ5IHRoaXMgbWV0aG9kIHdvbid0IG5lY2Vzc2FyaWx5IGJlIHBlcnNpc3RlZCB1bnRpbCB0aGUgbWV0aG9kIHtAY29kZQorICAgICAqIGZsdXNoKCl9IGlzIGludm9rZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGdpdmVuIGNsYXNzLgorICAgICAqIEByZXR1cm4gdGhlIHN5c3RlbSBwcmVmZXJlbmNlIG5vZGUgZm9yIHRoZSBwYWNrYWdlIG9mIHRoZSBnaXZlbiBjbGFzcy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGdpdmVuIGNsYXNzIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFByZWZlcmVuY2VzIHN5c3RlbU5vZGVGb3JQYWNrYWdlIChDbGFzczw/PiBjKSB7CisgICAgICAgIHJldHVybiBmYWN0b3J5LnN5c3RlbVJvb3QoKS5ub2RlKGdldE5vZGVOYW1lKGMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByb290IG5vZGUgb2YgdGhlIHN5c3RlbSBwcmVmZXJlbmNlIGhpZXJhcmNoeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN5c3RlbSBwcmVmZXJlbmNlIGhpZXJhcmNoeSByb290IG5vZGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBQcmVmZXJlbmNlcyBzeXN0ZW1Sb290KCkgeworICAgICAgICByZXR1cm4gZmFjdG9yeS5zeXN0ZW1Sb290KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdXNlciBwcmVmZXJlbmNlIG5vZGUgZm9yIHRoZSBwYWNrYWdlIG9mIHRoZSBnaXZlbiBjbGFzcy4KKyAgICAgKiBUaGUgYWJzb2x1dGUgcGF0aCBvZiB0aGUgcmV0dXJuZWQgbm9kZSBpcyBvbmUgc2xhc2ggZm9sbG93ZWQgYnkgdGhlIGdpdmVuCisgICAgICogY2xhc3MncyBmdWxsIHBhY2thZ2UgbmFtZSwgcmVwbGFjaW5nIGVhY2ggcGVyaW9kIGNoYXJhY3RlciAoJy4nKSB3aXRoCisgICAgICogYSBzbGFzaC4gRm9yIGV4YW1wbGUsIHRoZSBhYnNvbHV0ZSBwYXRoIG9mIHRoZSBwcmVmZXJlbmNlIGFzc29jaWF0ZWQgd2l0aAorICAgICAqIHRoZSBjbGFzcyBPYmplY3Qgd291bGQgYmUgIi9qYXZhL2xhbmciLiBBcyBhIHNwZWNpYWwgY2FzZSwgdGhlIHVubmFtZWQKKyAgICAgKiBwYWNrYWdlIGlzIGFzc29jaWF0ZWQgd2l0aCBhIHByZWZlcmVuY2Ugbm9kZSAiLyZsdDt1bm5hbWVkJmd0OyIuIFRoaXMKKyAgICAgKiBtZXRob2Qgd2lsbCBjcmVhdGUgdGhlIG5vZGUgYW5kIGl0cyBhbmNlc3RvcnMgYXMgbmVlZGVkLiBBbnkgbm9kZXMgY3JlYXRlZAorICAgICAqIGJ5IHRoaXMgbWV0aG9kIHdvbid0IG5lY2Vzc2FyaWx5IGJlIHBlcnNpc3RlZCB1bnRpbCB0aGUgbWV0aG9kIHtAY29kZQorICAgICAqIGZsdXNoKCl9IGlzIGludm9rZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGdpdmVuIGNsYXNzLgorICAgICAqIEByZXR1cm4gdGhlIHVzZXIgcHJlZmVyZW5jZSBub2RlIGZvciB0aGUgcGFja2FnZSBvZiB0aGUgZ2l2ZW4gY2xhc3MuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBnaXZlbiBjbGFzcyBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBQcmVmZXJlbmNlcyB1c2VyTm9kZUZvclBhY2thZ2UgKENsYXNzPD8+IGMpIHsKKyAgICAgICAgcmV0dXJuIGZhY3RvcnkudXNlclJvb3QoKS5ub2RlKGdldE5vZGVOYW1lKGMpKTsKKyAgICB9CisKKyAgICAvL3BhcnNlIG5vZGUncyBhYnNvbHV0ZSBwYXRoIGZyb20gY2xhc3MgaW5zdGFuY2UKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoQ2xhc3M8Pz4gYyl7CisgICAgICAgIFBhY2thZ2UgcCA9IGMuZ2V0UGFja2FnZSgpOworICAgICAgICBpZiAocCA9PSBudWxsKXsKKyAgICAgICAgICAgIHJldHVybiAiLzx1bm5hbWVkPiI7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuICIvIitwLmdldE5hbWUoKS5yZXBsYWNlKCcuJywgJy8nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByb290IG5vZGUgb2YgdGhlIHVzZXIgcHJlZmVyZW5jZSBoaWVyYXJjaHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB1c2VyIHByZWZlcmVuY2UgaGllcmFyY2h5IHJvb3Qgbm9kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFByZWZlcmVuY2VzIHVzZXJSb290KCkgeworICAgICAgICByZXR1cm4gZmFjdG9yeS51c2VyUm9vdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBub2RlLiBUaGUgZm9ybWF0IGlzICJVc2VyL1N5c3RlbQorICAgICAqIFByZWZlcmVuY2UgTm9kZTogIiBmb2xsb3dlZCBieSB0aGlzIG5vZGUncyBhYnNvbHV0ZSBwYXRoLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgbm9kZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIHRvU3RyaW5nKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL1ByZWZlcmVuY2VzRmFjdG9yeS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9wcmVmcy9QcmVmZXJlbmNlc0ZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZTI2NDE5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9wcmVmcy9QcmVmZXJlbmNlc0ZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDQzIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5wcmVmczsKKworLyoqCisgKiBUaGlzIGludGVyZmFjZSBpcyB1c2VkIGJ5IHRoZSB7QGxpbmsgUHJlZmVyZW5jZXN9IGNsYXNzIGFzIGZhY3RvcnkgY2xhc3MgdG8KKyAqIGNyZWF0ZSB7QGNvZGUgUHJlZmVyZW5jZXN9IGluc3RhbmNlcy4gVGhpcyBpbnRlcmZhY2UgY2FuIGJlIGltcGxlbWVudGVkIGFuZAorICogaW5zdGFsbGVkIHRvIHJlcGxhY2UgdGhlIGRlZmF1bHQgcHJlZmVyZW5jZXMgaW1wbGVtZW50YXRpb24uCisgKgorICogQHNlZSBqYXZhLnV0aWwucHJlZnMuUHJlZmVyZW5jZXMKKyAqCisgKiBAc2luY2UgMS40CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUHJlZmVyZW5jZXNGYWN0b3J5IHsKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByb290IG5vZGUgb2YgdGhlIHByZWZlcmVuY2VzIGhpZXJhcmNoeSBmb3IgdGhlIGNhbGxpbmcgdXNlcgorICAgICAqIGNvbnRleHQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB1c2VyIHByZWZlcmVuY2VzIGhpZXJhcmNoeSByb290IG5vZGUuCisgICAgICovCisgICAgUHJlZmVyZW5jZXMgdXNlclJvb3QoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgc3lzdGVtIHByZWZlcmVuY2VzIGhpZXJhcmNoeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN5c3RlbSBwcmVmZXJlbmNlcyBoaWVyYXJjaHkgcm9vdCBub2RlLgorICAgICAqLworICAgIFByZWZlcmVuY2VzIHN5c3RlbVJvb3QoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcHJlZnMvWE1MUGFyc2VyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL1hNTFBhcnNlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZlMjVjN2QKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ByZWZzL1hNTFBhcnNlci5qYXZhCkBAIC0wLDAgKzEsNTA0IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5wcmVmczsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRXcml0ZXI7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLlJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1JlYWRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CitpbXBvcnQgamF2YS51dGlsLlVVSUQ7CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CitpbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbjsKKworLyoqCisgKiBVdGlsaXR5IGNsYXNzIGZvciB0aGUgUHJlZmVyZW5jZXMgaW1wb3J0L2V4cG9ydCBmcm9tIFhNTCBmaWxlLgorICovCitjbGFzcyBYTUxQYXJzZXIgeworCisgICAgLyoKKyAgICAgKiBDb25zdGFudCAtIHRoZSBzcGVjaWZpZWQgRFREIFVSTAorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJFRlNfRFREX05BTUUgPSAiaHR0cDovL2phdmEuc3VuLmNvbS9kdGQvcHJlZmVyZW5jZXMuZHRkIjsKKworICAgIC8qCisgICAgICogQ29uc3RhbnQgLSB0aGUgRFREIHN0cmluZworICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJFRlNfRFREID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi04XCI/PiIKKyAgICAgICAgKyAiICAgIDwhRUxFTUVOVCBwcmVmZXJlbmNlcyAocm9vdCk+IgorICAgICAgICArICIgICAgPCFBVFRMSVNUIHByZWZlcmVuY2VzIEVYVEVSTkFMX1hNTF9WRVJTSU9OIENEQVRBIFwiMC4wXCIgPiIKKyAgICAgICAgKyAiICAgIDwhRUxFTUVOVCByb290IChtYXAsIG5vZGUqKSA+IgorICAgICAgICArICIgICAgPCFBVFRMSVNUIHJvb3QgdHlwZSAoc3lzdGVtfHVzZXIpICNSRVFVSVJFRCA+IgorICAgICAgICArICIgICAgPCFFTEVNRU5UIG5vZGUgKG1hcCwgbm9kZSopID4iCisgICAgICAgICsgIiAgICA8IUFUVExJU1Qgbm9kZSBuYW1lIENEQVRBICNSRVFVSVJFRCA+IgorICAgICAgICArICIgICAgPCFFTEVNRU5UIG1hcCAoZW50cnkqKSA+IgorICAgICAgICArICIgICAgPCFFTEVNRU5UIGVudHJ5IEVNUFRZID4iCisgICAgICAgICsgIiAgICA8IUFUVExJU1QgZW50cnkga2V5ICAgQ0RBVEEgI1JFUVVJUkVEIHZhbHVlIENEQVRBICNSRVFVSVJFRCA+IjsKKworICAgIC8qCisgICAgICogQ29uc3RhbnQgLSB0aGUgc3BlY2lmaWVkIGhlYWRlcgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgSEVBREVSID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi04XCI/PiI7CisKKyAgICAvKgorICAgICAqIENvbnN0YW50IC0gdGhlIHNwZWNpZmllZCBET0NUWVBFCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBET0NUWVBFID0gIjwhRE9DVFlQRSBwcmVmZXJlbmNlcyBTWVNURU0iOworCisgICAgLyoKKyAgICAgKiBDb25zdGFudCAtIHVzZWQgYnkgRmlsZVByZWZlcmVuY2VzSW1wbCwgd2hpY2ggaXMgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiBMaW51eCBwbGF0Zm9ybQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX1BSRUZTID0gIjwhRE9DVFlQRSBtYXAgU1lTVEVNICdodHRwOi8vamF2YS5zdW4uY29tL2R0ZC9wcmVmZXJlbmNlcy5kdGQnPiI7CisKKyAgICAvKgorICAgICAqIENvbnN0YW50IC0gc3BlY2lmeSB0aGUgRFREIHZlcnNpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBmbG9hdCBYTUxfVkVSU0lPTiA9IDEuMGY7CisKKyAgICAvKgorICAgICAqIERPTSBidWlsZGVyCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICAvKgorICAgICAqIHNwZWNpZnkgdGhlIGluZGVudCBsZXZlbAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCBpbmRlbnQgPSAtMTsKKworICAgIC8qCisgICAgICogaW5pdCBET00gYnVpbGRlcgorICAgICAqLworICAgIHN0YXRpYyB7CisgICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9IERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgZmFjdG9yeS5zZXRWYWxpZGF0aW5nKGZhbHNlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5Lm5ld0RvY3VtZW50QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlKTsKKyAgICAgICAgfQorICAgICAgICBidWlsZGVyLnNldEVudGl0eVJlc29sdmVyKG5ldyBFbnRpdHlSZXNvbHZlcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBJbnB1dFNvdXJjZSByZXNvbHZlRW50aXR5KFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQorICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIGlmIChzeXN0ZW1JZC5lcXVhbHMoUFJFRlNfRFREX05BTUUpKSB7CisgICAgICAgICAgICAgICAgICAgIElucHV0U291cmNlIHJlc3VsdCA9IG5ldyBJbnB1dFNvdXJjZShuZXcgU3RyaW5nUmVhZGVyKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBSRUZTX0RURCkpOworICAgICAgICAgICAgICAgICAgICByZXN1bHQuc2V0U3lzdGVtSWQoUFJFRlNfRFREX05BTUUpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCJJbnZhbGlkIERPQ1RZUEUgZGVjbGFyYXRpb24gIiArIHN5c3RlbUlkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIGJ1aWxkZXIuc2V0RXJyb3JIYW5kbGVyKG5ldyBFcnJvckhhbmRsZXIoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBYTUxQYXJzZXIoKSB7Ly8gZW1wdHkgY29uc3RydWN0b3IKKyAgICB9CisKKyAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgICAgICogdXRpbGl0aWVzIGZvciBQcmVmZXJlbmNlcyBleHBvcnQKKyAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisgICAgc3RhdGljIHZvaWQgZXhwb3J0UHJlZnMoUHJlZmVyZW5jZXMgcHJlZnMsIE91dHB1dFN0cmVhbSBzdHJlYW0sCisgICAgICAgICAgICBib29sZWFuIHdpdGhTdWJUcmVlKSB0aHJvd3MgSU9FeGNlcHRpb24sIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIGluZGVudCA9IC0xOworICAgICAgICBCdWZmZXJlZFdyaXRlciBvdXQgPSBuZXcgQnVmZmVyZWRXcml0ZXIobmV3IE91dHB1dFN0cmVhbVdyaXRlcihzdHJlYW0sICJVVEYtOCIpKTsKKyAgICAgICAgb3V0LndyaXRlKEhFQURFUik7CisgICAgICAgIG91dC5uZXdMaW5lKCk7CisgICAgICAgIG91dC5uZXdMaW5lKCk7CisKKyAgICAgICAgb3V0LndyaXRlKERPQ1RZUEUpOworICAgICAgICBvdXQud3JpdGUoIiAnIik7CisgICAgICAgIG91dC53cml0ZShQUkVGU19EVERfTkFNRSk7CisgICAgICAgIG91dC53cml0ZSgiJz4iKTsKKyAgICAgICAgb3V0Lm5ld0xpbmUoKTsKKyAgICAgICAgb3V0Lm5ld0xpbmUoKTsKKworICAgICAgICBmbHVzaFN0YXJ0VGFnKCJwcmVmZXJlbmNlcyIsIG5ldyBTdHJpbmdbXSB7ICJFWFRFUk5BTF9YTUxfVkVSU0lPTiIgfSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geyBTdHJpbmcudmFsdWVPZihYTUxfVkVSU0lPTikgfSwgb3V0KTsKKyAgICAgICAgZmx1c2hTdGFydFRhZygicm9vdCIsIG5ldyBTdHJpbmdbXSB7ICJ0eXBlIiB9LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7IHByZWZzLmlzVXNlck5vZGUoKSA/ICJ1c2VyIiA6ICJzeXN0ZW0iIH0sIG91dCk7CisgICAgICAgIGZsdXNoRW1wdHlFbGVtZW50KCJtYXAiLCBvdXQpOworCisgICAgICAgIFN0cmluZ1Rva2VuaXplciBhbmNlc3RvcnMgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHByZWZzLmFic29sdXRlUGF0aCgpLCAiLyIpOworICAgICAgICBleHBvcnROb2RlKGFuY2VzdG9ycywgcHJlZnMsIHdpdGhTdWJUcmVlLCBvdXQpOworCisgICAgICAgIGZsdXNoRW5kVGFnKCJyb290Iiwgb3V0KTsKKyAgICAgICAgZmx1c2hFbmRUYWcoInByZWZlcmVuY2VzIiwgb3V0KTsKKyAgICAgICAgb3V0LmZsdXNoKCk7CisgICAgICAgIG91dCA9IG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBleHBvcnROb2RlKFN0cmluZ1Rva2VuaXplciBhbmNlc3RvcnMsCisgICAgICAgICAgICBQcmVmZXJlbmNlcyBwcmVmcywgYm9vbGVhbiB3aXRoU3ViVHJlZSwgQnVmZmVyZWRXcml0ZXIgb3V0KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBpZiAoYW5jZXN0b3JzLmhhc01vcmVUb2tlbnMoKSkgeworICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBhbmNlc3RvcnMubmV4dFRva2VuKCk7CisgICAgICAgICAgICBmbHVzaFN0YXJ0VGFnKCJub2RlIiwgbmV3IFN0cmluZ1tdIHsgIm5hbWUiIH0sIG5ldyBTdHJpbmdbXSB7IG5hbWUgfSwgb3V0KTsKKyAgICAgICAgICAgIGlmIChhbmNlc3RvcnMuaGFzTW9yZVRva2VucygpKSB7CisgICAgICAgICAgICAgICAgZmx1c2hFbXB0eUVsZW1lbnQoIm1hcCIsIG91dCk7CisgICAgICAgICAgICAgICAgZXhwb3J0Tm9kZShhbmNlc3RvcnMsIHByZWZzLCB3aXRoU3ViVHJlZSwgb3V0KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZXhwb3J0RW50cmllcyhwcmVmcywgb3V0KTsKKyAgICAgICAgICAgICAgICBpZiAod2l0aFN1YlRyZWUpIHsKKyAgICAgICAgICAgICAgICAgICAgZXhwb3J0U3ViVHJlZShwcmVmcywgb3V0KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmbHVzaEVuZFRhZygibm9kZSIsIG91dCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGV4cG9ydFN1YlRyZWUoUHJlZmVyZW5jZXMgcHJlZnMsIEJ1ZmZlcmVkV3JpdGVyIG91dCkKKyAgICB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIG5hbWVzID0gcHJlZnMuY2hpbGRyZW5OYW1lcygpOworICAgICAgICBpZiAobmFtZXMubGVuZ3RoID4gMCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuYW1lcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIFByZWZlcmVuY2VzIGNoaWxkID0gcHJlZnMubm9kZShuYW1lc1tpXSk7CisgICAgICAgICAgICAgICAgZmx1c2hTdGFydFRhZygibm9kZSIsIG5ldyBTdHJpbmdbXSB7ICJuYW1lIiB9LCBuZXcgU3RyaW5nW10geyBuYW1lc1tpXSB9LCBvdXQpOworICAgICAgICAgICAgICAgIGV4cG9ydEVudHJpZXMoY2hpbGQsIG91dCk7CisgICAgICAgICAgICAgICAgZXhwb3J0U3ViVHJlZShjaGlsZCwgb3V0KTsKKyAgICAgICAgICAgICAgICBmbHVzaEVuZFRhZygibm9kZSIsIG91dCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGV4cG9ydEVudHJpZXMoUHJlZmVyZW5jZXMgcHJlZnMsIEJ1ZmZlcmVkV3JpdGVyIG91dCkKKyAgICB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIGtleXMgPSBwcmVmcy5rZXlzKCk7CisgICAgICAgIFN0cmluZ1tdIHZhbHVlcyA9IG5ldyBTdHJpbmdba2V5cy5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHZhbHVlc1tpXSA9IHByZWZzLmdldChrZXlzW2ldLCBudWxsKTsKKyAgICAgICAgfQorICAgICAgICBleHBvcnRFbnRyaWVzKGtleXMsIHZhbHVlcywgb3V0KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGV4cG9ydEVudHJpZXMoU3RyaW5nW10ga2V5cywgU3RyaW5nW10gdmFsdWVzLAorICAgICAgICAgICAgQnVmZmVyZWRXcml0ZXIgb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoa2V5cy5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgZmx1c2hFbXB0eUVsZW1lbnQoIm1hcCIsIG91dCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZmx1c2hTdGFydFRhZygibWFwIiwgb3V0KTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAodmFsdWVzW2ldICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmbHVzaEVtcHR5RWxlbWVudCgiZW50cnkiLCBuZXcgU3RyaW5nW10geyAia2V5IiwgInZhbHVlIiB9LAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHsga2V5c1tpXSwgdmFsdWVzW2ldIH0sIG91dCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZmx1c2hFbmRUYWcoIm1hcCIsIG91dCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBmbHVzaEVuZFRhZyhTdHJpbmcgdGFnTmFtZSwgQnVmZmVyZWRXcml0ZXIgb3V0KQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZsdXNoSW5kZW50KGluZGVudC0tLCBvdXQpOworICAgICAgICBvdXQud3JpdGUoIjwvIik7CisgICAgICAgIG91dC53cml0ZSh0YWdOYW1lKTsKKyAgICAgICAgb3V0LndyaXRlKCI+Iik7CisgICAgICAgIG91dC5uZXdMaW5lKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBmbHVzaEVtcHR5RWxlbWVudChTdHJpbmcgdGFnTmFtZSwgQnVmZmVyZWRXcml0ZXIgb3V0KQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZsdXNoSW5kZW50KCsraW5kZW50LCBvdXQpOworICAgICAgICBvdXQud3JpdGUoIjwiKTsKKyAgICAgICAgb3V0LndyaXRlKHRhZ05hbWUpOworICAgICAgICBvdXQud3JpdGUoIiAvPiIpOworICAgICAgICBvdXQubmV3TGluZSgpOworICAgICAgICBpbmRlbnQtLTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGZsdXNoRW1wdHlFbGVtZW50KFN0cmluZyB0YWdOYW1lLCBTdHJpbmdbXSBhdHRyS2V5cywKKyAgICAgICAgICAgIFN0cmluZ1tdIGF0dHJWYWx1ZXMsIEJ1ZmZlcmVkV3JpdGVyIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmx1c2hJbmRlbnQoKytpbmRlbnQsIG91dCk7CisgICAgICAgIG91dC53cml0ZSgiPCIpOworICAgICAgICBvdXQud3JpdGUodGFnTmFtZSk7CisgICAgICAgIGZsdXNoUGFpcnMoYXR0cktleXMsIGF0dHJWYWx1ZXMsIG91dCk7CisgICAgICAgIG91dC53cml0ZSgiIC8+Iik7CisgICAgICAgIG91dC5uZXdMaW5lKCk7CisgICAgICAgIGluZGVudC0tOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZmx1c2hQYWlycyhTdHJpbmdbXSBhdHRyS2V5cywgU3RyaW5nW10gYXR0clZhbHVlcywKKyAgICAgICAgICAgIEJ1ZmZlcmVkV3JpdGVyIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyS2V5cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgb3V0LndyaXRlKCIgIik7CisgICAgICAgICAgICBvdXQud3JpdGUoYXR0cktleXNbaV0pOworICAgICAgICAgICAgb3V0LndyaXRlKCI9XCIiKTsKKyAgICAgICAgICAgIG91dC53cml0ZShodG1sRW5jb2RlKGF0dHJWYWx1ZXNbaV0pKTsKKyAgICAgICAgICAgIG91dC53cml0ZSgiXCIiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZmx1c2hJbmRlbnQoaW50IGluZCwgQnVmZmVyZWRXcml0ZXIgb3V0KQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5kOyBpKyspIHsKKyAgICAgICAgICAgIG91dC53cml0ZSgiICAiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZmx1c2hTdGFydFRhZyhTdHJpbmcgdGFnTmFtZSwgU3RyaW5nW10gYXR0cktleXMsCisgICAgICAgICAgICBTdHJpbmdbXSBhdHRyVmFsdWVzLCBCdWZmZXJlZFdyaXRlciBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZsdXNoSW5kZW50KCsraW5kZW50LCBvdXQpOworICAgICAgICBvdXQud3JpdGUoIjwiKTsKKyAgICAgICAgb3V0LndyaXRlKHRhZ05hbWUpOworICAgICAgICBmbHVzaFBhaXJzKGF0dHJLZXlzLCBhdHRyVmFsdWVzLCBvdXQpOworICAgICAgICBvdXQud3JpdGUoIj4iKTsKKyAgICAgICAgb3V0Lm5ld0xpbmUoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGZsdXNoU3RhcnRUYWcoU3RyaW5nIHRhZ05hbWUsIEJ1ZmZlcmVkV3JpdGVyIG91dCkKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmbHVzaEluZGVudCgrK2luZGVudCwgb3V0KTsKKyAgICAgICAgb3V0LndyaXRlKCI8Iik7CisgICAgICAgIG91dC53cml0ZSh0YWdOYW1lKTsKKyAgICAgICAgb3V0LndyaXRlKCI+Iik7CisgICAgICAgIG91dC5uZXdMaW5lKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGh0bWxFbmNvZGUoU3RyaW5nIHMpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcy5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBjaGFyIGMgPSBzLmNoYXJBdChpKTsKKyAgICAgICAgICAgIHN3aXRjaCAoYykgeworICAgICAgICAgICAgY2FzZSAnPCc6CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCImbHQ7Iik7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICc+JzoKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIiZndDsiKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJyYnOgorICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgiJmFtcDsiKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJyInOgorICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgiJnF1b3Q7Iik7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIHNiLmFwcGVuZChjKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgICAgICogdXRpbGl0aWVzIGZvciBQcmVmZXJlbmNlcyBpbXBvcnQKKyAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisgICAgc3RhdGljIHZvaWQgaW1wb3J0UHJlZnMoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiwgSW52YWxpZFByZWZlcmVuY2VzRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGxvYWQgWE1MIGRvY3VtZW50CisgICAgICAgICAgICBEb2N1bWVudCBkb2MgPSBidWlsZGVyLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShpbikpOworCisgICAgICAgICAgICAvLyBjaGVjayBwcmVmZXJlbmNlcycgZXhwb3J0IHZlcnNpb24KKyAgICAgICAgICAgIEVsZW1lbnQgcHJlZmVyZW5jZXM7CisgICAgICAgICAgICBwcmVmZXJlbmNlcyA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgICAgIFN0cmluZyB2ZXJzaW9uID0gcHJlZmVyZW5jZXMuZ2V0QXR0cmlidXRlKCJFWFRFUk5BTF9YTUxfVkVSU0lPTiIpOworICAgICAgICAgICAgaWYgKHZlcnNpb24gIT0gbnVsbCAmJiBGbG9hdC5wYXJzZUZsb2F0KHZlcnNpb24pID4gWE1MX1ZFUlNJT04pIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFByZWZlcmVuY2VzRm9ybWF0RXhjZXB0aW9uKCJQcmVmZXJlbmNlcyB2ZXJzaW9uICIgKyB2ZXJzaW9uICsKKyAgICAgICAgICAgICAgICAgICAgICAgICIgaXMgbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBjaGVjayBwcmVmZXJlbmNlcyByb290J3MgdHlwZQorICAgICAgICAgICAgRWxlbWVudCByb290ID0gKEVsZW1lbnQpIHByZWZlcmVuY2VzCisgICAgICAgICAgICAuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInJvb3QiKS5pdGVtKDApOworICAgICAgICAgICAgUHJlZmVyZW5jZXMgcHJlZnNSb290ID0gbnVsbDsKKyAgICAgICAgICAgIFN0cmluZyB0eXBlID0gcm9vdC5nZXRBdHRyaWJ1dGUoInR5cGUiKTsKKyAgICAgICAgICAgIGlmICh0eXBlLmVxdWFscygidXNlciIpKSB7CisgICAgICAgICAgICAgICAgcHJlZnNSb290ID0gUHJlZmVyZW5jZXMudXNlclJvb3QoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcHJlZnNSb290ID0gUHJlZmVyZW5jZXMuc3lzdGVtUm9vdCgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBsb2FkIG5vZGUKKyAgICAgICAgICAgIGxvYWROb2RlKHByZWZzUm9vdCwgcm9vdCk7CisgICAgICAgIH0gY2F0Y2ggKEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRQcmVmZXJlbmNlc0Zvcm1hdEV4Y2VwdGlvbihlKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUHJlZmVyZW5jZXNGb3JtYXRFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGxvYWROb2RlKFByZWZlcmVuY2VzIHByZWZzLCBFbGVtZW50IG5vZGUpIHsKKyAgICAgICAgLy8gbG9hZCBwcmVmZXJlbmNlcworICAgICAgICBOb2RlTGlzdCBjaGlsZHJlbiA9IHNlbGVjdE5vZGVMaXN0KG5vZGUsICJub2RlIik7CisgICAgICAgIE5vZGVMaXN0IGVudHJpZXMgPSBzZWxlY3ROb2RlTGlzdChub2RlLCAibWFwL2VudHJ5Iik7CisgICAgICAgIGludCBjaGlsZE51bWJlciA9IGNoaWxkcmVuLmdldExlbmd0aCgpOworICAgICAgICBQcmVmZXJlbmNlc1tdIHByZWZDaGlsZHJlbiA9IG5ldyBQcmVmZXJlbmNlc1tjaGlsZE51bWJlcl07CisgICAgICAgIGludCBlbnRyeU51bWJlciA9IGVudHJpZXMuZ2V0TGVuZ3RoKCk7CisgICAgICAgIHN5bmNocm9uaXplZCAoKChBYnN0cmFjdFByZWZlcmVuY2VzKSBwcmVmcykubG9jaykgeworICAgICAgICAgICAgaWYgKCgoQWJzdHJhY3RQcmVmZXJlbmNlcykgcHJlZnMpLmlzUmVtb3ZlZCgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbnRyeU51bWJlcjsgaSsrKSB7CisgICAgICAgICAgICAgICAgRWxlbWVudCBlbnRyeSA9IChFbGVtZW50KSBlbnRyaWVzLml0ZW0oaSk7CisgICAgICAgICAgICAgICAgU3RyaW5nIGtleSA9IGVudHJ5LmdldEF0dHJpYnV0ZSgia2V5Iik7CisgICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gZW50cnkuZ2V0QXR0cmlidXRlKCJ2YWx1ZSIpOworICAgICAgICAgICAgICAgIHByZWZzLnB1dChrZXksIHZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIGdldCBjaGlsZHJlbiBwcmVmZXJlbmNlcyBub2RlCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoaWxkTnVtYmVyOyBpKyspIHsKKyAgICAgICAgICAgICAgICBFbGVtZW50IGNoaWxkID0gKEVsZW1lbnQpIGNoaWxkcmVuLml0ZW0oaSk7CisgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBjaGlsZC5nZXRBdHRyaWJ1dGUoIm5hbWUiKTsKKyAgICAgICAgICAgICAgICBwcmVmQ2hpbGRyZW5baV0gPSBwcmVmcy5ub2RlKG5hbWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gbG9hZCBjaGlsZHJlbiBub2RlcyBhZnRlciB1bmxvY2sKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaGlsZE51bWJlcjsgaSsrKSB7CisgICAgICAgICAgICBsb2FkTm9kZShwcmVmQ2hpbGRyZW5baV0sIChFbGVtZW50KSBjaGlsZHJlbi5pdGVtKGkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRPRE8gZGlydHkgaW1wbGVtZW50YXRpb24gb2YgYSBtZXRob2QgZnJvbSBqYXZheC54bWwueHBhdGgKKyAgICAvLyBzaG91bGQgYmUgcmVwbGFjZWQgd2l0aCBhIGNhbGwgdG8gYSBnb29kIGltcGwgb2YgdGhpcyBtZXRob2QKKyAgICBwcml2YXRlIHN0YXRpYyBOb2RlTGlzdCBzZWxlY3ROb2RlTGlzdChFbGVtZW50IGRvY3VtZW50RWxlbWVudCwgU3RyaW5nIHN0cmluZykgeworCisgICAgICAgIE5vZGVMaXN0IHJlc3VsdCA9IG51bGw7CisKKyAgICAgICAgQXJyYXlMaXN0PE5vZGU+IGlucHV0ID0gbmV3IEFycmF5TGlzdDxOb2RlPigpOworCisgICAgICAgIFN0cmluZ1tdIHBhdGggPSBzdHJpbmcuc3BsaXQoIi8iKTsKKworICAgICAgICBOb2RlTGlzdCBjaGlsZE5vZGVzID0gZG9jdW1lbnRFbGVtZW50LmdldENoaWxkTm9kZXMoKTsKKworICAgICAgICBpZihwYXRoWzBdLmVxdWFscygiZW50cnkiKSB8fCBwYXRoWzBdLmVxdWFscygibm9kZSIpKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoaWxkTm9kZXMuZ2V0TGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgICAgIE9iamVjdCBuZXh0ID0gY2hpbGROb2Rlcy5pdGVtKGkpOworICAgICAgICAgICAgICAgIGlmKG5leHQgaW5zdGFuY2VvZiBFbGVtZW50KSB7CisgICAgICAgICAgICAgICAgICAgIGlmKCgoRWxlbWVudCkgbmV4dCkuZ2V0Tm9kZU5hbWUoKS5lcXVhbHMocGF0aFswXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LmFkZCgoTm9kZSluZXh0KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmKHBhdGhbMF0uZXF1YWxzKCJtYXAiKSAmJiBwYXRoWzFdLmVxdWFscygiZW50cnkiKSkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaGlsZE5vZGVzLmdldExlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICBPYmplY3QgbmV4dCA9IGNoaWxkTm9kZXMuaXRlbShpKTsKKyAgICAgICAgICAgICAgICBpZihuZXh0IGluc3RhbmNlb2YgRWxlbWVudCkgeworICAgICAgICAgICAgICAgICAgICBpZigoKEVsZW1lbnQpIG5leHQpLmdldE5vZGVOYW1lKCkuZXF1YWxzKHBhdGhbMF0pKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBOb2RlTGlzdCBuZXh0Q2hpbGROb2RlcyA9ICgoTm9kZSluZXh0KS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IG5leHRDaGlsZE5vZGVzLmdldExlbmd0aCgpOyBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3Qgc3VibmV4dCA9IG5leHRDaGlsZE5vZGVzLml0ZW0oaik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoc3VibmV4dCBpbnN0YW5jZW9mIEVsZW1lbnQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoKChFbGVtZW50KXN1Ym5leHQpLmdldE5vZGVOYW1lKCkuZXF1YWxzKHBhdGhbMV0pKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC5hZGQoKE5vZGUpc3VibmV4dCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXN1bHQgPSBuZXcgTm9kZVNldChpbnB1dC5pdGVyYXRvcigpKTsKKworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByZWZlcmVuY2VzIGZyb20ge0Bjb2RlIHhtbEZpbGV9LiBSZXR1cm5zIGVtcHR5IHByb3BlcnRpZXMgaWYKKyAgICAgKiBhbnkgZXJyb3JzIG9jY3VyLgorICAgICAqLworICAgIHN0YXRpYyBQcm9wZXJ0aWVzIHJlYWRYbWxQcmVmZXJlbmNlcyhGaWxlIHhtbEZpbGUpIHsKKyAgICAgICAgUHJvcGVydGllcyByZXN1bHQgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICBpZiAoIXhtbEZpbGUuZXhpc3RzKCkpIHsKKyAgICAgICAgICAgIHhtbEZpbGUuZ2V0UGFyZW50RmlsZSgpLm1rZGlycygpOworICAgICAgICB9IGVsc2UgaWYgKHhtbEZpbGUuY2FuUmVhZCgpKSB7CisgICAgICAgICAgICBSZWFkZXIgcmVhZGVyID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3IElucHV0U3RyZWFtUmVhZGVyKG5ldyBGaWxlSW5wdXRTdHJlYW0oeG1sRmlsZSksICJVVEYtOCIpOworICAgICAgICAgICAgICAgIERvY3VtZW50IGRvY3VtZW50ID0gYnVpbGRlci5wYXJzZShuZXcgSW5wdXRTb3VyY2UocmVhZGVyKSk7CisgICAgICAgICAgICAgICAgTm9kZUxpc3QgZW50cmllcyA9IHNlbGVjdE5vZGVMaXN0KGRvY3VtZW50LmdldERvY3VtZW50RWxlbWVudCgpLCAiZW50cnkiKTsKKyAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gZW50cmllcy5nZXRMZW5ndGgoKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIEVsZW1lbnQgbm9kZSA9IChFbGVtZW50KSBlbnRyaWVzLml0ZW0oaSk7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBrZXkgPSBub2RlLmdldEF0dHJpYnV0ZSgia2V5Iik7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IG5vZGUuZ2V0QXR0cmlidXRlKCJ2YWx1ZSIpOworICAgICAgICAgICAgICAgICAgICByZXN1bHQuc2V0UHJvcGVydHkoa2V5LCB2YWx1ZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkocmVhZGVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIHRoZSBwcmVmcyBBUEkgcmVxdWlyZXMgdGhpcyB0byBiZSBob3N0aWxlIHRvd2FyZHMgcHJlLWV4aXN0aW5nIGZpbGVzCisgICAgICAgICAgICB4bWxGaWxlLmRlbGV0ZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBwcmVmZXJlbmNlcyB0byB7QGNvZGUgeG1sRmlsZX0uCisgICAgICovCisgICAgc3RhdGljIHZvaWQgd3JpdGVYbWxQcmVmZXJlbmNlcyhGaWxlIHhtbEZpbGUsIFByb3BlcnRpZXMgcHJvcGVydGllcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZSBwYXJlbnQgPSB4bWxGaWxlLmdldFBhcmVudEZpbGUoKTsKKyAgICAgICAgRmlsZSB0ZW1wb3JhcnlGb3JXcml0aW5nID0gbmV3IEZpbGUocGFyZW50LCAicHJlZnMtIiArIFVVSUQucmFuZG9tVVVJRCgpICsgIi54bWwudG1wIik7CisKKyAgICAgICAgQnVmZmVyZWRXcml0ZXIgb3V0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG91dCA9IG5ldyBCdWZmZXJlZFdyaXRlcihuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKAorICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZU91dHB1dFN0cmVhbSh0ZW1wb3JhcnlGb3JXcml0aW5nKSwgIlVURi04IikpOworICAgICAgICAgICAgb3V0LndyaXRlKEhFQURFUik7CisgICAgICAgICAgICBvdXQubmV3TGluZSgpOworICAgICAgICAgICAgb3V0LndyaXRlKEZJTEVfUFJFRlMpOworICAgICAgICAgICAgb3V0Lm5ld0xpbmUoKTsKKyAgICAgICAgICAgIFN0cmluZ1tdIGtleXMgPSBwcm9wZXJ0aWVzLmtleVNldCgpLnRvQXJyYXkobmV3IFN0cmluZ1twcm9wZXJ0aWVzLnNpemUoKV0pOworICAgICAgICAgICAgaW50IGxlbmd0aCA9IGtleXMubGVuZ3RoOworICAgICAgICAgICAgU3RyaW5nW10gdmFsdWVzID0gbmV3IFN0cmluZ1tsZW5ndGhdOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIHZhbHVlc1tpXSA9IHByb3BlcnRpZXMuZ2V0UHJvcGVydHkoa2V5c1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBleHBvcnRFbnRyaWVzKGtleXMsIHZhbHVlcywgb3V0KTsKKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgaWYgKCF0ZW1wb3JhcnlGb3JXcml0aW5nLnJlbmFtZVRvKHhtbEZpbGUpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJGYWlsZWQgdG8gd3JpdGUgcHJlZmVyZW5jZXMgdG8gIiArIHhtbEZpbGUpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkob3V0KTsKKyAgICAgICAgICAgIHRlbXBvcmFyeUZvcldyaXRpbmcuZGVsZXRlKCk7IC8vIG5vLW9wIHVubGVzcyBzb21ldGhpbmcgZmFpbGVkCisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3JlZ2V4L01hdGNoUmVzdWx0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3JlZ2V4L01hdGNoUmVzdWx0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzZjMTdhOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcmVnZXgvTWF0Y2hSZXN1bHQuamF2YQpAQCAtMCwwICsxLDk3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5yZWdleDsKKworLyoqCisgKiBIb2xkcyB0aGUgcmVzdWx0cyBvZiBhIHN1Y2Nlc3NmdWwgbWF0Y2ggb2YgYSB7QGxpbmsgUGF0dGVybn0gYWdhaW5zdCBhCisgKiBnaXZlbiBzdHJpbmcuIFRoZSByZXN1bHQgaXMgZGl2aWRlZCBpbnRvIGdyb3Vwcywgd2l0aCBvbmUgZ3JvdXAgZm9yIGVhY2gKKyAqIHBhaXIgb2YgcGFyZW50aGVzZXMgaW4gdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBhbmQgYW4gYWRkaXRpb25hbCBncm91cCBmb3IKKyAqIHRoZSB3aG9sZSByZWd1bGFyIGV4cHJlc3Npb24uIFRoZSBzdGFydCwgZW5kLCBhbmQgY29udGVudHMgb2YgZWFjaCBncm91cAorICogY2FuIGJlIHF1ZXJpZWQuCisgKgorICogQHNlZSBNYXRjaGVyCisgKiBAc2VlIE1hdGNoZXIjdG9NYXRjaFJlc3VsdCgpCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgTWF0Y2hSZXN1bHQgeworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBmb2xsb3dpbmcgdGhlIHRleHQgdGhhdCBtYXRjaGVkCisgICAgICogdGhlIHdob2xlIHJlZ3VsYXIgZXhwcmVzc2lvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNoYXJhY3RlciBpbmRleC4KKyAgICAgKi8KKyAgICBpbnQgZW5kKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGZvbGxvd2luZyB0aGUgdGV4dCB0aGF0IG1hdGNoZWQKKyAgICAgKiBhIGdpdmVuIGdyb3VwLgorICAgICAqCisgICAgICogQHBhcmFtIGdyb3VwCisgICAgICogICAgICAgICAgICB0aGUgZ3JvdXAsIHJhbmdpbmcgZnJvbSAwIHRvIGdyb3VwQ291bnQoKSAtIDEsIHdpdGggMAorICAgICAqICAgICAgICAgICAgcmVwcmVzZW50aW5nIHRoZSB3aG9sZSBwYXR0ZXJuLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2hhcmFjdGVyIGluZGV4LgorICAgICAqLworICAgIGludCBlbmQoaW50IGdyb3VwKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRleHQgdGhhdCBtYXRjaGVkIHRoZSB3aG9sZSByZWd1bGFyIGV4cHJlc3Npb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB0ZXh0LgorICAgICAqLworICAgIFN0cmluZyBncm91cCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGV4dCB0aGF0IG1hdGNoZWQgYSBnaXZlbiBncm91cCBvZiB0aGUgcmVndWxhciBleHByZXNzaW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGdyb3VwCisgICAgICogICAgICAgICAgICB0aGUgZ3JvdXAsIHJhbmdpbmcgZnJvbSAwIHRvIGdyb3VwQ291bnQoKSAtIDEsIHdpdGggMAorICAgICAqICAgICAgICAgICAgcmVwcmVzZW50aW5nIHRoZSB3aG9sZSBwYXR0ZXJuLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdGV4dCB0aGF0IG1hdGNoZWQgdGhlIGdyb3VwLgorICAgICAqLworICAgIFN0cmluZyBncm91cChpbnQgZ3JvdXApOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGdyb3VwcyBpbiB0aGUgcmVzdWx0LCB3aGljaCBpcyBhbHdheXMgZXF1YWwgdG8KKyAgICAgKiB0aGUgbnVtYmVyIG9mIGdyb3VwcyBpbiB0aGUgb3JpZ2luYWwgcmVndWxhciBleHByZXNzaW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGdyb3Vwcy4KKyAgICAgKi8KKyAgICBpbnQgZ3JvdXBDb3VudCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgdGV4dCB0aGF0IG1hdGNoZWQKKyAgICAgKiB0aGUgd2hvbGUgcmVndWxhciBleHByZXNzaW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2hhcmFjdGVyIGluZGV4LgorICAgICAqLworICAgIGludCBzdGFydCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgdGV4dCB0aGF0IG1hdGNoZWQgYSBnaXZlbgorICAgICAqIGdyb3VwLgorICAgICAqCisgICAgICogQHBhcmFtIGdyb3VwCisgICAgICogICAgICAgICAgICB0aGUgZ3JvdXAsIHJhbmdpbmcgZnJvbSAwIHRvIGdyb3VwQ291bnQoKSAtIDEsIHdpdGggMAorICAgICAqICAgICAgICAgICAgcmVwcmVzZW50aW5nIHRoZSB3aG9sZSBwYXR0ZXJuLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2hhcmFjdGVyIGluZGV4LgorICAgICAqLworICAgIGludCBzdGFydChpbnQgZ3JvdXApOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9yZWdleC9NYXRjaFJlc3VsdEltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcmVnZXgvTWF0Y2hSZXN1bHRJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjY4NTc1NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcmVnZXgvTWF0Y2hSZXN1bHRJbXBsLmphdmEKQEAgLTAsMCArMSw3OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLnJlZ2V4OworCisvKioKKyAqIEhvbGRzIHRoZSByZXN1bHRzIG9mIGEgc3VjY2Vzc2Z1bCBtYXRjaCBvZiBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBhZ2FpbnN0IGEKKyAqIGdpdmVuIHN0cmluZy4gT25seSB1c2VkIGludGVybmFsbHksIHRodXMgc3BhcnNlbHkgZG9jdW1lbnRlZCAodGhvdWdoIHRoZQorICogZGVmaW5pbmcgcHVibGljIGludGVyZmFjZSBoYXMgZnVsbCBkb2N1bWVudGF0aW9uKS4KKyAqCisgKiBAc2VlIGphdmEudXRpbC5yZWdleC5NYXRjaFJlc3VsdAorICovCitjbGFzcyBNYXRjaFJlc3VsdEltcGwgaW1wbGVtZW50cyBNYXRjaFJlc3VsdCB7CisKKyAgICAvKioKKyAgICAgKiBIb2xkcyB0aGUgb3JpZ2luYWwgaW5wdXQgdGV4dC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyB0ZXh0OworCisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIG9mZnNldHMgb2YgdGhlIGdyb3VwcyBpbiB0aGUgaW5wdXQgdGV4dC4gVGhlIGZpcnN0IHR3bworICAgICAqIGVsZW1lbnRzIHNwZWNpZml5IHN0YXJ0IGFuZCBlbmQgb2YgdGhlIHplcm8gZ3JvdXAsIHRoZSBuZXh0IHR3byBzcGVjaWZ5CisgICAgICogZ3JvdXAgMSwgYW5kIHNvIG9uLgorICAgICAqLworICAgIHByaXZhdGUgaW50W10gb2Zmc2V0czsKKworICAgIE1hdGNoUmVzdWx0SW1wbChTdHJpbmcgdGV4dCwgaW50W10gb2Zmc2V0cykgeworICAgICAgICB0aGlzLnRleHQgPSB0ZXh0OworICAgICAgICB0aGlzLm9mZnNldHMgPSBvZmZzZXRzLmNsb25lKCk7CisgICAgfQorCisgICAgcHVibGljIGludCBlbmQoKSB7CisgICAgICAgIHJldHVybiBlbmQoMCk7CisgICAgfQorCisgICAgcHVibGljIGludCBlbmQoaW50IGdyb3VwKSB7CisgICAgICAgIHJldHVybiBvZmZzZXRzWzIgKiBncm91cCArIDFdOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ3JvdXAoKSB7CisgICAgICAgIHJldHVybiB0ZXh0LnN1YnN0cmluZyhzdGFydCgpLCBlbmQoKSk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBncm91cChpbnQgZ3JvdXApIHsKKyAgICAgICAgaW50IGZyb20gPSBvZmZzZXRzW2dyb3VwICogMl07CisgICAgICAgIGludCB0byA9IG9mZnNldHNbKGdyb3VwICogMikgKyAxXTsKKyAgICAgICAgaWYgKGZyb20gPT0gLTEgfHwgdG8gPT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIHRleHQuc3Vic3RyaW5nKGZyb20sIHRvKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ3JvdXBDb3VudCgpIHsKKyAgICAgICAgcmV0dXJuIChvZmZzZXRzLmxlbmd0aCAvIDIpIC0gMTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IHN0YXJ0KCkgeworICAgICAgICByZXR1cm4gc3RhcnQoMCk7CisgICAgfQorCisgICAgcHVibGljIGludCBzdGFydChpbnQgZ3JvdXApIHsKKyAgICAgICAgcmV0dXJuIG9mZnNldHNbMiAqIGdyb3VwXTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcmVnZXgvTWF0Y2hlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9yZWdleC9NYXRjaGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNThiY2Y5ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcmVnZXgvTWF0Y2hlci5qYXZhCkBAIC0wLDAgKzEsNjgzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwucmVnZXg7CisKKy8qKgorICogVGhlIHJlc3VsdCBvZiBhcHBseWluZyBhIHtAY29kZSBQYXR0ZXJufSB0byBhIGdpdmVuIGlucHV0LiBTZWUge0BsaW5rIFBhdHRlcm59IGZvcgorICogZXhhbXBsZSB1c2VzLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTWF0Y2hlciBpbXBsZW1lbnRzIE1hdGNoUmVzdWx0IHsKKworICAgIC8qKgorICAgICAqIEhvbGRzIHRoZSBwYXR0ZXJuLCB0aGF0IGlzLCB0aGUgY29tcGlsZWQgcmVndWxhciBleHByZXNzaW9uLgorICAgICAqLworICAgIHByaXZhdGUgUGF0dGVybiBwYXR0ZXJuOworCisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIGhhbmRsZSBmb3IgdGhlIG5hdGl2ZSB2ZXJzaW9uIG9mIHRoZSBwYXR0ZXJuLgorICAgICAqLworICAgIHByaXZhdGUgaW50IGFkZHJlc3M7CisKKyAgICAvKioKKyAgICAgKiBIb2xkcyB0aGUgaW5wdXQgdGV4dC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBpbnB1dDsKKworICAgIC8qKgorICAgICAqIEhvbGRzIHRoZSBzdGFydCBvZiB0aGUgcmVnaW9uLCBvciAwIGlmIHRoZSBtYXRjaGluZyBzaG91bGQgc3RhcnQgYXQgdGhlCisgICAgICogYmVnaW5uaW5nIG9mIHRoZSB0ZXh0LgorICAgICAqLworICAgIHByaXZhdGUgaW50IHJlZ2lvblN0YXJ0OworCisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIGVuZCBvZiB0aGUgcmVnaW9uLCBvciBpbnB1dC5sZW5ndGgoKSBpZiB0aGUgbWF0Y2hpbmcgc2hvdWxkCisgICAgICogZ28gdW50aWwgdGhlIGVuZCBvZiB0aGUgaW5wdXQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgcmVnaW9uRW5kOworCisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBuZXh0IGZpbmQgb3BlcmF0aW9uIHdpbGwgdGFrZSBwbGFjZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBmaW5kUG9zOworCisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBuZXh0IGFwcGVuZCBvcGVyYXRpb24gd2lsbCB0YWtlIHBsYWNlLgorICAgICAqLworICAgIHByaXZhdGUgaW50IGFwcGVuZFBvczsKKworICAgIC8qKgorICAgICAqIFJlZmxlY3RzIHdoZXRoZXIgYSBtYXRjaCBoYXMgYmVlbiBmb3VuZCBkdXJpbmcgdGhlIG1vc3QgcmVjZW50IGZpbmQKKyAgICAgKiBvcGVyYXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIG1hdGNoRm91bmQ7CisKKyAgICAvKioKKyAgICAgKiBIb2xkcyB0aGUgb2Zmc2V0cyBmb3IgdGhlIG1vc3QgcmVjZW50IG1hdGNoLgorICAgICAqLworICAgIHByaXZhdGUgaW50W10gbWF0Y2hPZmZzZXRzOworCisgICAgLyoqCisgICAgICogUmVmbGVjdHMgd2hldGhlciB0aGUgYm91bmRzIG9mIHRoZSByZWdpb24gYXJlIGFuY2hvcmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gYW5jaG9yaW5nQm91bmRzID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIFJlZmxlY3RzIHdoZXRoZXIgdGhlIGJvdW5kcyBvZiB0aGUgcmVnaW9uIGFyZSB0cmFuc3BhcmVudC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gdHJhbnNwYXJlbnRCb3VuZHM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbWF0Y2hlciBmb3IgYSBnaXZlbiBjb21iaW5hdGlvbiBvZiBwYXR0ZXJuIGFuZCBpbnB1dC4gQm90aAorICAgICAqIGVsZW1lbnRzIGNhbiBiZSBjaGFuZ2VkIGxhdGVyIG9uLgorICAgICAqCisgICAgICogQHBhcmFtIHBhdHRlcm4KKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXR0ZXJuIHRvIHVzZS4KKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCB0byB1c2UuCisgICAgICovCisgICAgTWF0Y2hlcihQYXR0ZXJuIHBhdHRlcm4sIENoYXJTZXF1ZW5jZSBpbnB1dCkgeworICAgICAgICB1c2VQYXR0ZXJuKHBhdHRlcm4pOworICAgICAgICByZXNldChpbnB1dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyBhIGxpdGVyYWwgcGFydCBvZiB0aGUgaW5wdXQgcGx1cyBhIHJlcGxhY2VtZW50IGZvciB0aGUgY3VycmVudAorICAgICAqIG1hdGNoIHRvIGEgZ2l2ZW4ge0BsaW5rIFN0cmluZ0J1ZmZlcn0uIFRoZSBsaXRlcmFsIHBhcnQgaXMgZXhhY3RseSB0aGUKKyAgICAgKiBwYXJ0IG9mIHRoZSBpbnB1dCBiZXR3ZWVuIHRoZSBwcmV2aW91cyBtYXRjaCBhbmQgdGhlIGN1cnJlbnQgbWF0Y2guIFRoZQorICAgICAqIG1ldGhvZCBjYW4gYmUgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIHtAbGluayAjZmluZCgpfSBhbmQKKyAgICAgKiB7QGxpbmsgI2FwcGVuZFRhaWwoU3RyaW5nQnVmZmVyKX0gdG8gd2FsayB0aHJvdWdoIHRoZSBpbnB1dCBhbmQgcmVwbGFjZQorICAgICAqIGFsbCBvY2N1cnJlbmNlcyBvZiB0aGUge0Bjb2RlIFBhdHRlcm59IHdpdGggc29tZXRoaW5nIGVsc2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmZmVyCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIFN0cmluZ0J1ZmZlcn0gdG8gYXBwZW5kIHRvLgorICAgICAqIEBwYXJhbSByZXBsYWNlbWVudAorICAgICAqICAgICAgICAgICAgdGhlIHJlcGxhY2VtZW50IHRleHQuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIE1hdGNoZXJ9IGl0c2VsZi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG5vIHN1Y2Nlc3NmdWwgbWF0Y2ggaGFzIGJlZW4gbWFkZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWF0Y2hlciBhcHBlbmRSZXBsYWNlbWVudChTdHJpbmdCdWZmZXIgYnVmZmVyLCBTdHJpbmcgcmVwbGFjZW1lbnQpIHsKKyAgICAgICAgYnVmZmVyLmFwcGVuZChpbnB1dC5zdWJzdHJpbmcoYXBwZW5kUG9zLCBzdGFydCgpKSk7CisgICAgICAgIGFwcGVuZEV2YWx1YXRlZChidWZmZXIsIHJlcGxhY2VtZW50KTsKKyAgICAgICAgYXBwZW5kUG9zID0gZW5kKCk7CisKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW50ZXJuYWwgaGVscGVyIG1ldGhvZCB0byBhcHBlbmQgYSBnaXZlbiBzdHJpbmcgdG8gYSBnaXZlbiBzdHJpbmcgYnVmZmVyLgorICAgICAqIElmIHRoZSBzdHJpbmcgY29udGFpbnMgYW55IHJlZmVyZW5jZXMgdG8gZ3JvdXBzLCB0aGVzZSBhcmUgcmVwbGFjZWQgYnkKKyAgICAgKiB0aGUgY29ycmVzcG9uZGluZyBncm91cCdzIGNvbnRlbnRzLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZmZlcgorICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyBidWZmZXIuCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgdG8gYXBwZW5kLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhcHBlbmRFdmFsdWF0ZWQoU3RyaW5nQnVmZmVyIGJ1ZmZlciwgU3RyaW5nIHMpIHsKKyAgICAgICAgYm9vbGVhbiBlc2NhcGUgPSBmYWxzZTsKKyAgICAgICAgYm9vbGVhbiBkb2xsYXIgPSBmYWxzZTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHMubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgY2hhciBjID0gcy5jaGFyQXQoaSk7CisgICAgICAgICAgICBpZiAoYyA9PSAnXFwnICYmICFlc2NhcGUpIHsKKyAgICAgICAgICAgICAgICBlc2NhcGUgPSB0cnVlOworICAgICAgICAgICAgfSBlbHNlIGlmIChjID09ICckJyAmJiAhZXNjYXBlKSB7CisgICAgICAgICAgICAgICAgZG9sbGFyID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoYyA+PSAnMCcgJiYgYyA8PSAnOScgJiYgZG9sbGFyKSB7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChncm91cChjIC0gJzAnKSk7CisgICAgICAgICAgICAgICAgZG9sbGFyID0gZmFsc2U7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoYyk7CisgICAgICAgICAgICAgICAgZG9sbGFyID0gZmFsc2U7CisgICAgICAgICAgICAgICAgZXNjYXBlID0gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBUaGlzIHNlZW1pbmdseSBzdHVwaWQgcGllY2Ugb2YgY29kZSByZXByb2R1Y2VzIGEgSkRLIGJ1Zy4KKyAgICAgICAgaWYgKGVzY2FwZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihzLmxlbmd0aCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0cyB0aGUge0Bjb2RlIE1hdGNoZXJ9LiBUaGlzIHJlc3VsdHMgaW4gdGhlIHJlZ2lvbiBiZWluZyBzZXQgdG8gdGhlCisgICAgICogd2hvbGUgaW5wdXQuIFJlc3VsdHMgb2YgYSBwcmV2aW91cyBmaW5kIGdldCBsb3N0LiBUaGUgbmV4dCBhdHRlbXB0IHRvCisgICAgICogZmluZCBhbiBvY2N1cnJlbmNlIG9mIHRoZSB7QGxpbmsgUGF0dGVybn0gaW4gdGhlIHN0cmluZyB3aWxsIHN0YXJ0IGF0IHRoZQorICAgICAqIGJlZ2lubmluZyBvZiB0aGUgaW5wdXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgTWF0Y2hlcn0gaXRzZWxmLgorICAgICAqLworICAgIHB1YmxpYyBNYXRjaGVyIHJlc2V0KCkgeworICAgICAgICByZXR1cm4gcmVzZXQoaW5wdXQsIDAsIGlucHV0Lmxlbmd0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm92aWRlcyBhIG5ldyBpbnB1dCBhbmQgcmVzZXRzIHRoZSB7QGNvZGUgTWF0Y2hlcn0uIFRoaXMgcmVzdWx0cyBpbiB0aGUKKyAgICAgKiByZWdpb24gYmVpbmcgc2V0IHRvIHRoZSB3aG9sZSBpbnB1dC4gUmVzdWx0cyBvZiBhIHByZXZpb3VzIGZpbmQgZ2V0IGxvc3QuCisgICAgICogVGhlIG5leHQgYXR0ZW1wdCB0byBmaW5kIGFuIG9jY3VycmVuY2Ugb2YgdGhlIHtAbGluayBQYXR0ZXJufSBpbiB0aGUKKyAgICAgKiBzdHJpbmcgd2lsbCBzdGFydCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBpbnB1dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dAorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBpbnB1dCBzZXF1ZW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBNYXRjaGVyfSBpdHNlbGYuCisgICAgICovCisgICAgcHVibGljIE1hdGNoZXIgcmVzZXQoQ2hhclNlcXVlbmNlIGlucHV0KSB7CisgICAgICAgIHJldHVybiByZXNldChpbnB1dCwgMCwgaW5wdXQubGVuZ3RoKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0cyB0aGUgTWF0Y2hlci4gQSBuZXcgaW5wdXQgc2VxdWVuY2UgYW5kIGEgbmV3IHJlZ2lvbiBjYW4gYmUKKyAgICAgKiBzcGVjaWZpZWQuIFJlc3VsdHMgb2YgYSBwcmV2aW91cyBmaW5kIGdldCBsb3N0LiBUaGUgbmV4dCBhdHRlbXB0IHRvIGZpbmQKKyAgICAgKiBhbiBvY2N1cnJlbmNlIG9mIHRoZSBQYXR0ZXJuIGluIHRoZSBzdHJpbmcgd2lsbCBzdGFydCBhdCB0aGUgYmVnaW5uaW5nIG9mCisgICAgICogdGhlIHJlZ2lvbi4gVGhpcyBpcyB0aGUgaW50ZXJuYWwgdmVyc2lvbiBvZiByZXNldCgpIHRvIHdoaWNoIHRoZSBzZXZlcmFsCisgICAgICogcHVibGljIHZlcnNpb25zIGRlbGVnYXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgc2VxdWVuY2UuCisgICAgICogQHBhcmFtIHN0YXJ0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnQgb2YgdGhlIHJlZ2lvbi4KKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICB0aGUgZW5kIG9mIHRoZSByZWdpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtYXRjaGVyIGl0c2VsZi4KKyAgICAgKi8KKyAgICBwcml2YXRlIE1hdGNoZXIgcmVzZXQoQ2hhclNlcXVlbmNlIGlucHV0LCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgaWYgKGlucHV0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzdGFydCA8IDAgfHwgZW5kIDwgMCB8fCBzdGFydCA+IGlucHV0Lmxlbmd0aCgpIHx8IGVuZCA+IGlucHV0Lmxlbmd0aCgpIHx8IHN0YXJ0ID4gZW5kKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5pbnB1dCA9IGlucHV0LnRvU3RyaW5nKCk7CisgICAgICAgIHRoaXMucmVnaW9uU3RhcnQgPSBzdGFydDsKKyAgICAgICAgdGhpcy5yZWdpb25FbmQgPSBlbmQ7CisgICAgICAgIHJlc2V0Rm9ySW5wdXQoKTsKKworICAgICAgICBtYXRjaEZvdW5kID0gZmFsc2U7CisgICAgICAgIGZpbmRQb3MgPSByZWdpb25TdGFydDsKKyAgICAgICAgYXBwZW5kUG9zID0gMDsKKworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGEgbmV3IHBhdHRlcm4gZm9yIHRoZSB7QGNvZGUgTWF0Y2hlcn0uIFJlc3VsdHMgb2YgYSBwcmV2aW91cyBmaW5kCisgICAgICogZ2V0IGxvc3QuIFRoZSBuZXh0IGF0dGVtcHQgdG8gZmluZCBhbiBvY2N1cnJlbmNlIG9mIHRoZSB7QGxpbmsgUGF0dGVybn0KKyAgICAgKiBpbiB0aGUgc3RyaW5nIHdpbGwgc3RhcnQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgaW5wdXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGF0dGVybgorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB7QGNvZGUgUGF0dGVybn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgTWF0Y2hlcn0gaXRzZWxmLgorICAgICAqLworICAgIHB1YmxpYyBNYXRjaGVyIHVzZVBhdHRlcm4oUGF0dGVybiBwYXR0ZXJuKSB7CisgICAgICAgIGlmIChwYXR0ZXJuID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMucGF0dGVybiA9IHBhdHRlcm47CisKKyAgICAgICAgaWYgKGFkZHJlc3MgIT0gMCkgeworICAgICAgICAgICAgY2xvc2VJbXBsKGFkZHJlc3MpOworICAgICAgICAgICAgYWRkcmVzcyA9IDA7CisgICAgICAgIH0KKyAgICAgICAgYWRkcmVzcyA9IG9wZW5JbXBsKHBhdHRlcm4uYWRkcmVzcyk7CisKKyAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlc2V0Rm9ySW5wdXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIG1hdGNoT2Zmc2V0cyA9IG5ldyBpbnRbKGdyb3VwQ291bnQoKSArIDEpICogMl07CisgICAgICAgIG1hdGNoRm91bmQgPSBmYWxzZTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlc2V0Rm9ySW5wdXQoKSB7CisgICAgICAgIHNldElucHV0SW1wbChhZGRyZXNzLCBpbnB1dCwgcmVnaW9uU3RhcnQsIHJlZ2lvbkVuZCk7CisgICAgICAgIHVzZUFuY2hvcmluZ0JvdW5kc0ltcGwoYWRkcmVzcywgYW5jaG9yaW5nQm91bmRzKTsKKyAgICAgICAgdXNlVHJhbnNwYXJlbnRCb3VuZHNJbXBsKGFkZHJlc3MsIHRyYW5zcGFyZW50Qm91bmRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhpcyBtYXRjaGVyIGFuZCBzZXRzIGEgcmVnaW9uLiBPbmx5IGNoYXJhY3RlcnMgaW5zaWRlIHRoZSByZWdpb24KKyAgICAgKiBhcmUgY29uc2lkZXJlZCBmb3IgYSBtYXRjaC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgcmVnaW9uLgorICAgICAqIEBwYXJhbSBlbmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaXJzdCBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIGVuZCBvZiB0aGUgcmVnaW9uLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBNYXRjaGVyfSBpdHNlbGYuCisgICAgICovCisgICAgcHVibGljIE1hdGNoZXIgcmVnaW9uKGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICByZXR1cm4gcmVzZXQoaW5wdXQsIHN0YXJ0LCBlbmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlICh1bm1hdGNoZWQpIHJlbWFpbmRlciBvZiB0aGUgaW5wdXQgdG8gdGhlIGdpdmVuCisgICAgICoge0BsaW5rIFN0cmluZ0J1ZmZlcn0uIFRoZSBtZXRob2QgY2FuIGJlIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aAorICAgICAqIHtAbGluayAjZmluZCgpfSBhbmQge0BsaW5rICNhcHBlbmRSZXBsYWNlbWVudChTdHJpbmdCdWZmZXIsIFN0cmluZyl9IHRvCisgICAgICogd2FsayB0aHJvdWdoIHRoZSBpbnB1dCBhbmQgcmVwbGFjZSBhbGwgbWF0Y2hlcyBvZiB0aGUge0Bjb2RlIFBhdHRlcm59CisgICAgICogd2l0aCBzb21ldGhpbmcgZWxzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWZmZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgU3RyaW5nQnVmZmVyfSB0byBhcHBlbmQgdG8uCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFN0cmluZ0J1ZmZlcn0uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBzdWNjZXNzZnVsIG1hdGNoIGhhcyBiZWVuIG1hZGUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZ0J1ZmZlciBhcHBlbmRUYWlsKFN0cmluZ0J1ZmZlciBidWZmZXIpIHsKKyAgICAgICAgaWYgKGFwcGVuZFBvcyA8IHJlZ2lvbkVuZCkgeworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChpbnB1dC5zdWJzdHJpbmcoYXBwZW5kUG9zLCByZWdpb25FbmQpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnVmZmVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2VzIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoaXMgbWF0Y2hlcidzIHBhdHRlcm4gaW4gdGhlIGlucHV0IHdpdGgKKyAgICAgKiBhIGdpdmVuIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZXBsYWNlbWVudAorICAgICAqICAgICAgICAgICAgdGhlIHJlcGxhY2VtZW50IHRleHQuCisgICAgICogQHJldHVybiB0aGUgbW9kaWZpZWQgaW5wdXQgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgcmVwbGFjZUZpcnN0KFN0cmluZyByZXBsYWNlbWVudCkgeworICAgICAgICByZXNldCgpOworICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcihpbnB1dC5sZW5ndGgoKSk7CisgICAgICAgIGlmIChmaW5kKCkpIHsKKyAgICAgICAgICAgIGFwcGVuZFJlcGxhY2VtZW50KGJ1ZmZlciwgcmVwbGFjZW1lbnQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBhcHBlbmRUYWlsKGJ1ZmZlcikudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyBhbGwgb2NjdXJyZW5jZXMgb2YgdGhpcyBtYXRjaGVyJ3MgcGF0dGVybiBpbiB0aGUgaW5wdXQgd2l0aCBhCisgICAgICogZ2l2ZW4gc3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHJlcGxhY2VtZW50CisgICAgICogICAgICAgICAgICB0aGUgcmVwbGFjZW1lbnQgdGV4dC4KKyAgICAgKiBAcmV0dXJuIHRoZSBtb2RpZmllZCBpbnB1dCBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyByZXBsYWNlQWxsKFN0cmluZyByZXBsYWNlbWVudCkgeworICAgICAgICByZXNldCgpOworICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcihpbnB1dC5sZW5ndGgoKSk7CisgICAgICAgIHdoaWxlIChmaW5kKCkpIHsKKyAgICAgICAgICAgIGFwcGVuZFJlcGxhY2VtZW50KGJ1ZmZlciwgcmVwbGFjZW1lbnQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBhcHBlbmRUYWlsKGJ1ZmZlcikudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGxpbmsgUGF0dGVybn0gaW5zdGFuY2UgdXNlZCBpbnNpZGUgdGhpcyBtYXRjaGVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFBhdHRlcm59IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBQYXR0ZXJuIHBhdHRlcm4oKSB7CisgICAgICAgIHJldHVybiBwYXR0ZXJuOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRleHQgdGhhdCBtYXRjaGVkIGEgZ2l2ZW4gZ3JvdXAgb2YgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbi4KKyAgICAgKiBFeHBsaWNpdCBjYXB0dXJpbmcgZ3JvdXBzIGluIHRoZSBwYXR0ZXJuIGFyZSBudW1iZXJlZCBsZWZ0IHRvIHJpZ2h0IGluIG9yZGVyCisgICAgICogb2YgdGhlaXIgPGk+b3BlbmluZzwvaT4gcGFyZW50aGVzaXMsIHN0YXJ0aW5nIGF0IDEuCisgICAgICogVGhlIHNwZWNpYWwgZ3JvdXAgMCByZXByZXNlbnRzIHRoZSBlbnRpcmUgbWF0Y2ggKGFzIGlmIHRoZSBlbnRpcmUgcGF0dGVybiBpcyBzdXJyb3VuZGVkCisgICAgICogYnkgYW4gaW1wbGljaXQgY2FwdHVyaW5nIGdyb3VwKS4KKyAgICAgKiBGb3IgZXhhbXBsZSwgImEoKGIpYykiIG1hdGNoaW5nICJhYmMiIHdvdWxkIGdpdmUgdGhlIGZvbGxvd2luZyBncm91cHM6CisgICAgICogPHByZT4KKyAgICAgKiAwICJhYmMiCisgICAgICogMSAiYmMiCisgICAgICogMiAiYiIKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIDxwPkFuIG9wdGlvbmFsIGNhcHR1cmluZyBncm91cCB0aGF0IGZhaWxlZCB0byBtYXRjaCBhcyBwYXJ0IG9mIGFuIG92ZXJhbGwKKyAgICAgKiBzdWNjZXNzZnVsIG1hdGNoIChmb3IgZXhhbXBsZSwgImEoYik/YyIgbWF0Y2hpbmcgImFjIikgcmV0dXJucyBudWxsLgorICAgICAqIEEgY2FwdHVyaW5nIGdyb3VwIHRoYXQgbWF0Y2hlZCB0aGUgZW1wdHkgc3RyaW5nIChmb3IgZXhhbXBsZSwgImEoYj8pYyIgbWF0Y2hpbmcgImFjIikKKyAgICAgKiByZXR1cm5zIHRoZSBlbXB0eSBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG5vIHN1Y2Nlc3NmdWwgbWF0Y2ggaGFzIGJlZW4gbWFkZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdyb3VwKGludCBncm91cCkgeworICAgICAgICBlbnN1cmVNYXRjaCgpOworICAgICAgICBpbnQgZnJvbSA9IG1hdGNoT2Zmc2V0c1tncm91cCAqIDJdOworICAgICAgICBpbnQgdG8gPSBtYXRjaE9mZnNldHNbKGdyb3VwICogMikgKyAxXTsKKyAgICAgICAgaWYgKGZyb20gPT0gLTEgfHwgdG8gPT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIGlucHV0LnN1YnN0cmluZyhmcm9tLCB0byk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0ZXh0IHRoYXQgbWF0Y2hlZCB0aGUgd2hvbGUgcmVndWxhciBleHByZXNzaW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdGV4dC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG5vIHN1Y2Nlc3NmdWwgbWF0Y2ggaGFzIGJlZW4gbWFkZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdyb3VwKCkgeworICAgICAgICByZXR1cm4gZ3JvdXAoMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBvY2N1cnJlbmNlIG9mIHRoZSB7QGxpbmsgUGF0dGVybn0gaW4gdGhlIGlucHV0LiBUaGUKKyAgICAgKiBtZXRob2Qgc3RhcnRzIHRoZSBzZWFyY2ggZnJvbSB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGluIHRoZSBpbnB1dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgVGhlIGluZGV4IGluIHRoZSBpbnB1dCBhdCB3aGljaCB0aGUgZmluZCBvcGVyYXRpb24gaXMgdG8KKyAgICAgKiAgICAgICAgICAgIGJlZ2luLiBJZiB0aGlzIGlzIGxlc3MgdGhhbiB0aGUgc3RhcnQgb2YgdGhlIHJlZ2lvbiwgaXQgaXMKKyAgICAgKiAgICAgICAgICAgIGF1dG9tYXRpY2FsbHkgYWRqdXN0ZWQgdG8gdGhhdCB2YWx1ZS4gSWYgaXQgaXMgYmV5b25kIHRoZSBlbmQKKyAgICAgKiAgICAgICAgICAgIG9mIHRoZSByZWdpb24sIHRoZSBtZXRob2Qgd2lsbCBmYWlsLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiAoYW5kIG9ubHkgaWYpIGEgbWF0Y2ggaGFzIGJlZW4gZm91bmQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZmluZChpbnQgc3RhcnQpIHsKKyAgICAgICAgZmluZFBvcyA9IHN0YXJ0OworCisgICAgICAgIGlmIChmaW5kUG9zIDwgcmVnaW9uU3RhcnQpIHsKKyAgICAgICAgICAgIGZpbmRQb3MgPSByZWdpb25TdGFydDsKKyAgICAgICAgfSBlbHNlIGlmIChmaW5kUG9zID49IHJlZ2lvbkVuZCkgeworICAgICAgICAgICAgbWF0Y2hGb3VuZCA9IGZhbHNlOworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgbWF0Y2hGb3VuZCA9IGZpbmRJbXBsKGFkZHJlc3MsIGlucHV0LCBmaW5kUG9zLCBtYXRjaE9mZnNldHMpOworICAgICAgICBpZiAobWF0Y2hGb3VuZCkgeworICAgICAgICAgICAgZmluZFBvcyA9IG1hdGNoT2Zmc2V0c1sxXTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbWF0Y2hGb3VuZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IG9jY3VycmVuY2Ugb2YgdGhlIHtAbGluayBQYXR0ZXJufSBpbiB0aGUgaW5wdXQuIElmIGEKKyAgICAgKiBwcmV2aW91cyBtYXRjaCB3YXMgc3VjY2Vzc2Z1bCwgdGhlIG1ldGhvZCBjb250aW51ZXMgdGhlIHNlYXJjaCBmcm9tIHRoZQorICAgICAqIGZpcnN0IGNoYXJhY3RlciBmb2xsb3dpbmcgdGhhdCBtYXRjaCBpbiB0aGUgaW5wdXQuIE90aGVyd2lzZSBpdCBzZWFyY2hlcworICAgICAqIGVpdGhlciBmcm9tIHRoZSByZWdpb24gc3RhcnQgKGlmIG9uZSBoYXMgYmVlbiBzZXQpLCBvciBmcm9tIHBvc2l0aW9uIDAuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgKGFuZCBvbmx5IGlmKSBhIG1hdGNoIGhhcyBiZWVuIGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGZpbmQoKSB7CisgICAgICAgIG1hdGNoRm91bmQgPSBmaW5kTmV4dEltcGwoYWRkcmVzcywgaW5wdXQsIG1hdGNoT2Zmc2V0cyk7CisgICAgICAgIGlmIChtYXRjaEZvdW5kKSB7CisgICAgICAgICAgICBmaW5kUG9zID0gbWF0Y2hPZmZzZXRzWzFdOworICAgICAgICB9CisgICAgICAgIHJldHVybiBtYXRjaEZvdW5kOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyaWVzIHRvIG1hdGNoIHRoZSB7QGxpbmsgUGF0dGVybn0sIHN0YXJ0aW5nIGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUKKyAgICAgKiByZWdpb24gKG9yIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGlucHV0LCBpZiBubyByZWdpb24gaGFzIGJlZW4gc2V0KS4KKyAgICAgKiBEb2Vzbid0IHJlcXVpcmUgdGhlIHtAY29kZSBQYXR0ZXJufSB0byBtYXRjaCBhZ2FpbnN0IHRoZSB3aG9sZSByZWdpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgKGFuZCBvbmx5IGlmKSB0aGUge0Bjb2RlIFBhdHRlcm59IG1hdGNoZXMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbG9va2luZ0F0KCkgeworICAgICAgICBtYXRjaEZvdW5kID0gbG9va2luZ0F0SW1wbChhZGRyZXNzLCBpbnB1dCwgbWF0Y2hPZmZzZXRzKTsKKyAgICAgICAgaWYgKG1hdGNoRm91bmQpIHsKKyAgICAgICAgICAgIGZpbmRQb3MgPSBtYXRjaE9mZnNldHNbMV07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG1hdGNoRm91bmQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJpZXMgdG8gbWF0Y2ggdGhlIHtAbGluayBQYXR0ZXJufSBhZ2FpbnN0IHRoZSBlbnRpcmUgcmVnaW9uIChvciB0aGUKKyAgICAgKiBlbnRpcmUgaW5wdXQsIGlmIG5vIHJlZ2lvbiBoYXMgYmVlbiBzZXQpLgorICAgICAqCisgICAgICogQHJldHVybiB0cnVlIGlmIChhbmQgb25seSBpZikgdGhlIHtAY29kZSBQYXR0ZXJufSBtYXRjaGVzIHRoZSBlbnRpcmUKKyAgICAgKiAgICAgICAgIHJlZ2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaGVzKCkgeworICAgICAgICBtYXRjaEZvdW5kID0gbWF0Y2hlc0ltcGwoYWRkcmVzcywgaW5wdXQsIG1hdGNoT2Zmc2V0cyk7CisgICAgICAgIGlmIChtYXRjaEZvdW5kKSB7CisgICAgICAgICAgICBmaW5kUG9zID0gbWF0Y2hPZmZzZXRzWzFdOworICAgICAgICB9CisgICAgICAgIHJldHVybiBtYXRjaEZvdW5kOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIHRleHQgdGhhdCBtYXRjaGVkIGEgZ2l2ZW4KKyAgICAgKiBncm91cC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBncm91cAorICAgICAqICAgICAgICAgICAgdGhlIGdyb3VwLCByYW5naW5nIGZyb20gMCB0byBncm91cENvdW50KCkgLSAxLCB3aXRoIDAKKyAgICAgKiAgICAgICAgICAgIHJlcHJlc2VudGluZyB0aGUgd2hvbGUgcGF0dGVybi4KKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFyYWN0ZXIgaW5kZXguCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBzdWNjZXNzZnVsIG1hdGNoIGhhcyBiZWVuIG1hZGUuCisgICAgICovCisgICAgcHVibGljIGludCBzdGFydChpbnQgZ3JvdXApIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24geworICAgICAgICBlbnN1cmVNYXRjaCgpOworICAgICAgICByZXR1cm4gbWF0Y2hPZmZzZXRzW2dyb3VwICogMl07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBmb2xsb3dpbmcgdGhlIHRleHQgdGhhdCBtYXRjaGVkCisgICAgICogYSBnaXZlbiBncm91cC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBncm91cAorICAgICAqICAgICAgICAgICAgdGhlIGdyb3VwLCByYW5naW5nIGZyb20gMCB0byBncm91cENvdW50KCkgLSAxLCB3aXRoIDAKKyAgICAgKiAgICAgICAgICAgIHJlcHJlc2VudGluZyB0aGUgd2hvbGUgcGF0dGVybi4KKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFyYWN0ZXIgaW5kZXguCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBzdWNjZXNzZnVsIG1hdGNoIGhhcyBiZWVuIG1hZGUuCisgICAgICovCisgICAgcHVibGljIGludCBlbmQoaW50IGdyb3VwKSB7CisgICAgICAgIGVuc3VyZU1hdGNoKCk7CisgICAgICAgIHJldHVybiBtYXRjaE9mZnNldHNbKGdyb3VwICogMikgKyAxXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgcmVwbGFjZW1lbnQgc3RyaW5nIGZvciB0aGUgZ2l2ZW4gb25lIHRoYXQgaGFzIGFsbCBiYWNrc2xhc2hlcworICAgICAqIGFuZCBkb2xsYXIgc2lnbnMgZXNjYXBlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzCisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgc3RyaW5nLgorICAgICAqIEByZXR1cm4gdGhlIGlucHV0IHN0cmluZywgd2l0aCBhbGwgYmFja3NsYXNoZXMgYW5kIGRvbGxhciBzaWducyBoYXZpbmcKKyAgICAgKiAgICAgICAgIGJlZW4gZXNjYXBlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBxdW90ZVJlcGxhY2VtZW50KFN0cmluZyBzKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIocy5sZW5ndGgoKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcy5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBjaGFyIGMgPSBzLmNoYXJBdChpKTsKKyAgICAgICAgICAgIGlmIChjID09ICdcXCcgfHwgYyA9PSAnJCcpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCdcXCcpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChjKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgdGV4dCB0aGF0IG1hdGNoZWQgdGhlCisgICAgICogd2hvbGUgcmVndWxhciBleHByZXNzaW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2hhcmFjdGVyIGluZGV4LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgbm8gc3VjY2Vzc2Z1bCBtYXRjaCBoYXMgYmVlbiBtYWRlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgc3RhcnQoKSB7CisgICAgICAgIHJldHVybiBzdGFydCgwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZ3JvdXBzIGluIHRoZSByZXN1bHRzLCB3aGljaCBpcyBhbHdheXMgZXF1YWwgdG8KKyAgICAgKiB0aGUgbnVtYmVyIG9mIGdyb3VwcyBpbiB0aGUgb3JpZ2luYWwgcmVndWxhciBleHByZXNzaW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGdyb3Vwcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdyb3VwQ291bnQoKSB7CisgICAgICAgIHJldHVybiBncm91cENvdW50SW1wbChhZGRyZXNzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGZvbGxvd2luZyB0aGUgdGV4dCB0aGF0IG1hdGNoZWQKKyAgICAgKiB0aGUgd2hvbGUgcmVndWxhciBleHByZXNzaW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2hhcmFjdGVyIGluZGV4LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgbm8gc3VjY2Vzc2Z1bCBtYXRjaCBoYXMgYmVlbiBtYWRlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZW5kKCkgeworICAgICAgICByZXR1cm4gZW5kKDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIHRoZSBjdXJyZW50IG1hdGNoIGludG8gYSBzZXBhcmF0ZSB7QGxpbmsgTWF0Y2hSZXN1bHR9IGluc3RhbmNlCisgICAgICogdGhhdCBpcyBpbmRlcGVuZGVudCBmcm9tIHRoaXMgbWF0Y2hlci4gVGhlIG5ldyBvYmplY3QgaXMgdW5hZmZlY3RlZCB3aGVuCisgICAgICogdGhlIHN0YXRlIG9mIHRoaXMgbWF0Y2hlciBjaGFuZ2VzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV3IHtAY29kZSBNYXRjaFJlc3VsdH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBzdWNjZXNzZnVsIG1hdGNoIGhhcyBiZWVuIG1hZGUuCisgICAgICovCisgICAgcHVibGljIE1hdGNoUmVzdWx0IHRvTWF0Y2hSZXN1bHQoKSB7CisgICAgICAgIGVuc3VyZU1hdGNoKCk7CisgICAgICAgIHJldHVybiBuZXcgTWF0Y2hSZXN1bHRJbXBsKGlucHV0LCBtYXRjaE9mZnNldHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGlzIG1hdGNoZXIgaGFzIGFuY2hvcmluZyBib3VuZHMgZW5hYmxlZCBvciBub3QuIFdoZW4KKyAgICAgKiBhbmNob3JpbmcgYm91bmRzIGFyZSBlbmFibGVkLCB0aGUgc3RhcnQgYW5kIGVuZCBvZiB0aGUgaW5wdXQgbWF0Y2ggdGhlCisgICAgICogJ14nIGFuZCAnJCcgbWV0YS1jaGFyYWN0ZXJzLCBvdGhlcndpc2Ugbm90LiBBbmNob3JpbmcgYm91bmRzIGFyZSBlbmFibGVkCisgICAgICogYnkgZGVmYXVsdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSBmb3IgYW5jaG9yaW5nIGJvdW5kcy4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgTWF0Y2hlcn0gaXRzZWxmLgorICAgICAqLworICAgIHB1YmxpYyBNYXRjaGVyIHVzZUFuY2hvcmluZ0JvdW5kcyhib29sZWFuIHZhbHVlKSB7CisgICAgICAgIGFuY2hvcmluZ0JvdW5kcyA9IHZhbHVlOworICAgICAgICB1c2VBbmNob3JpbmdCb3VuZHNJbXBsKGFkZHJlc3MsIHZhbHVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBtYXRjaGVyIGhhcyBhbmNob3JpbmcgYm91bmRzIGVuYWJsZWQuIFdoZW4KKyAgICAgKiBhbmNob3JpbmcgYm91bmRzIGFyZSBlbmFibGVkLCB0aGUgc3RhcnQgYW5kIGVuZCBvZiB0aGUgaW5wdXQgbWF0Y2ggdGhlCisgICAgICogJ14nIGFuZCAnJCcgbWV0YS1jaGFyYWN0ZXJzLCBvdGhlcndpc2Ugbm90LiBBbmNob3JpbmcgYm91bmRzIGFyZSBlbmFibGVkCisgICAgICogYnkgZGVmYXVsdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiAoYW5kIG9ubHkgaWYpIHRoZSB7QGNvZGUgTWF0Y2hlcn0gdXNlcyBhbmNob3JpbmcgYm91bmRzLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc0FuY2hvcmluZ0JvdW5kcygpIHsKKyAgICAgICAgcmV0dXJuIGFuY2hvcmluZ0JvdW5kczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhpcyBtYXRjaGVyIGhhcyB0cmFuc3BhcmVudCBib3VuZHMgZW5hYmxlZCBvciBub3QuCisgICAgICogV2hlbiB0cmFuc3BhcmVudCBib3VuZHMgYXJlIGVuYWJsZWQsIHRoZSBwYXJ0cyBvZiB0aGUgaW5wdXQgb3V0c2lkZSB0aGUKKyAgICAgKiByZWdpb24gYXJlIHN1YmplY3QgdG8gbG9va2FoZWFkIGFuZCBsb29rYmVoaW5kLCBvdGhlcndpc2UgdGhleSBhcmUgbm90LgorICAgICAqIFRyYW5zcGFyZW50IGJvdW5kcyBhcmUgZGlzYWJsZWQgYnkgZGVmYXVsdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB2YWx1ZSBmb3IgdHJhbnNwYXJlbnQgYm91bmRzLgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBNYXRjaGVyfSBpdHNlbGYuCisgICAgICovCisgICAgcHVibGljIE1hdGNoZXIgdXNlVHJhbnNwYXJlbnRCb3VuZHMoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICB0cmFuc3BhcmVudEJvdW5kcyA9IHZhbHVlOworICAgICAgICB1c2VUcmFuc3BhcmVudEJvdW5kc0ltcGwoYWRkcmVzcywgdmFsdWUpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYWtlcyBzdXJlIHRoYXQgYSBzdWNjZXNzZnVsIG1hdGNoIGhhcyBiZWVuIG1hZGUuIElzIGludm9rZWQgaW50ZXJuYWxseQorICAgICAqIGZyb20gdmFyaW91cyBwbGFjZXMgaW4gdGhlIGNsYXNzLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBzdWNjZXNzZnVsIG1hdGNoIGhhcyBiZWVuIG1hZGUuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZU1hdGNoKCkgeworICAgICAgICBpZiAoIW1hdGNoRm91bmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIk5vIHN1Y2Nlc3NmdWwgbWF0Y2ggc28gZmFyIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIG1hdGNoZXIgaGFzIHRyYW5zcGFyZW50IGJvdW5kcyBlbmFibGVkLiBXaGVuCisgICAgICogdHJhbnNwYXJlbnQgYm91bmRzIGFyZSBlbmFibGVkLCB0aGUgcGFydHMgb2YgdGhlIGlucHV0IG91dHNpZGUgdGhlIHJlZ2lvbgorICAgICAqIGFyZSBzdWJqZWN0IHRvIGxvb2thaGVhZCBhbmQgbG9va2JlaGluZCwgb3RoZXJ3aXNlIHRoZXkgYXJlIG5vdC4KKyAgICAgKiBUcmFuc3BhcmVudCBib3VuZHMgYXJlIGRpc2FibGVkIGJ5IGRlZmF1bHQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgKGFuZCBvbmx5IGlmKSB0aGUge0Bjb2RlIE1hdGNoZXJ9IHVzZXMgYW5jaG9yaW5nIGJvdW5kcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNUcmFuc3BhcmVudEJvdW5kcygpIHsKKyAgICAgICAgcmV0dXJuIHRyYW5zcGFyZW50Qm91bmRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBtYXRjaGVyJ3MgcmVnaW9uIHN0YXJ0LCB0aGF0IGlzLCB0aGUgZmlyc3QgY2hhcmFjdGVyIHRoYXQgaXMKKyAgICAgKiBjb25zaWRlcmVkIGZvciBhIG1hdGNoLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3RhcnQgb2YgdGhlIHJlZ2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHJlZ2lvblN0YXJ0KCkgeworICAgICAgICByZXR1cm4gcmVnaW9uU3RhcnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIG1hdGNoZXIncyByZWdpb24gZW5kLCB0aGF0IGlzLCB0aGUgZmlyc3QgY2hhcmFjdGVyIHRoYXQgaXMKKyAgICAgKiBub3QgY29uc2lkZXJlZCBmb3IgYSBtYXRjaC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVuZCBvZiB0aGUgcmVnaW9uLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgcmVnaW9uRW5kKCkgeworICAgICAgICByZXR1cm4gcmVnaW9uRW5kOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIG1vcmUgaW5wdXQgbWlnaHQgY2hhbmdlIGEgc3VjY2Vzc2Z1bCBtYXRjaCBpbnRvIGFuCisgICAgICogdW5zdWNjZXNzZnVsIG9uZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiAoYW5kIG9ubHkgaWYpIG1vcmUgaW5wdXQgbWlnaHQgY2hhbmdlIGEgc3VjY2Vzc2Z1bCBtYXRjaAorICAgICAqICAgICAgICAgaW50byBhbiB1bnN1Y2Nlc3NmdWwgb25lLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHJlcXVpcmVFbmQoKSB7CisgICAgICAgIHJldHVybiByZXF1aXJlRW5kSW1wbChhZGRyZXNzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgbGFzdCBtYXRjaCBoaXQgdGhlIGVuZCBvZiB0aGUgaW5wdXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgKGFuZCBvbmx5IGlmKSB0aGUgbGFzdCBtYXRjaCBoaXQgdGhlIGVuZCBvZiB0aGUgaW5wdXQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGl0RW5kKCkgeworICAgICAgICByZXR1cm4gaGl0RW5kSW1wbChhZGRyZXNzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNsb3NlSW1wbChhZGRyZXNzKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHN1cGVyLmZpbmFsaXplKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgdm9pZCBjbG9zZUltcGwoaW50IGFkZHIpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBib29sZWFuIGZpbmRJbXBsKGludCBhZGRyLCBTdHJpbmcgcywgaW50IHN0YXJ0SW5kZXgsIGludFtdIG9mZnNldHMpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBib29sZWFuIGZpbmROZXh0SW1wbChpbnQgYWRkciwgU3RyaW5nIHMsIGludFtdIG9mZnNldHMpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgZ3JvdXBDb3VudEltcGwoaW50IGFkZHIpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBib29sZWFuIGhpdEVuZEltcGwoaW50IGFkZHIpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBib29sZWFuIGxvb2tpbmdBdEltcGwoaW50IGFkZHIsIFN0cmluZyBzLCBpbnRbXSBvZmZzZXRzKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBtYXRjaGVzSW1wbChpbnQgYWRkciwgU3RyaW5nIHMsIGludFtdIG9mZnNldHMpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgb3BlbkltcGwoaW50IHBhdHRlcm5BZGRyKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiByZXF1aXJlRW5kSW1wbChpbnQgYWRkcik7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIHZvaWQgc2V0SW5wdXRJbXBsKGludCBhZGRyLCBTdHJpbmcgcywgaW50IHN0YXJ0LCBpbnQgZW5kKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgdm9pZCB1c2VBbmNob3JpbmdCb3VuZHNJbXBsKGludCBhZGRyLCBib29sZWFuIHZhbHVlKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgdm9pZCB1c2VUcmFuc3BhcmVudEJvdW5kc0ltcGwoaW50IGFkZHIsIGJvb2xlYW4gdmFsdWUpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9yZWdleC9QYXR0ZXJuLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3JlZ2V4L1BhdHRlcm4uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40Njk4NGI5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9yZWdleC9QYXR0ZXJuLmphdmEKQEAgLTAsMCArMSw0NTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC5yZWdleDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworLyoqCisgKiBQYXR0ZXJucyBhcmUgY29tcGlsZWQgcmVndWxhciBleHByZXNzaW9ucy4gSW4gbWFueSBjYXNlcywgY29udmVuaWVuY2UgbWV0aG9kcyBzdWNoIGFzCisgKiB7QGxpbmsgU3RyaW5nI21hdGNoZXMgU3RyaW5nLm1hdGNoZXN9LCB7QGxpbmsgU3RyaW5nI3JlcGxhY2VBbGwgU3RyaW5nLnJlcGxhY2VBbGx9IGFuZAorICoge0BsaW5rIFN0cmluZyNzcGxpdCBTdHJpbmcuc3BsaXR9IHdpbGwgYmUgcHJlZmVyYWJsZSwgYnV0IGlmIHlvdSBuZWVkIHRvIGRvIGEgbG90IG9mIHdvcmsKKyAqIHdpdGggdGhlIHNhbWUgcmVndWxhciBleHByZXNzaW9uLCBpdCBtYXkgYmUgbW9yZSBlZmZpY2llbnQgdG8gY29tcGlsZSBpdCBvbmNlIGFuZCByZXVzZSBpdC4KKyAqIFRoZSB7QGNvZGUgUGF0dGVybn0gY2xhc3MgYW5kIGl0cyBjb21wYW5pb24sIHtAbGluayBNYXRjaGVyfSwgYWxzbyBvZmZlciBtb3JlIGZ1bmN0aW9uYWxpdHkKKyAqIHRoYW4gdGhlIHNtYWxsIGFtb3VudCBleHBvc2VkIGJ5IHtAY29kZSBTdHJpbmd9LgorICoKKyAqIDxwcmU+CisgKiAvLyBTdHJpbmcgY29udmVuaWVuY2UgbWV0aG9kczoKKyAqIGJvb2xlYW4gc2F3RmFpbHVyZXMgPSBzLm1hdGNoZXMoIkZhaWx1cmVzOiBcXGQrIik7CisgKiBTdHJpbmcgZmFyZXdlbGwgPSBzLnJlcGxhY2VBbGwoIkhlbGxvLCAoXFxTKykiLCAiR29vZGJ5ZSwgJDEiKTsKKyAqIFN0cmluZ1tdIGZpZWxkcyA9IHMuc3BsaXQoIjoiKTsKKyAqCisgKiAvLyBEaXJlY3QgdXNlIG9mIFBhdHRlcm46CisgKiBQYXR0ZXJuIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIkhlbGxvLCAoXFxTKykiKTsKKyAqIE1hdGNoZXIgbSA9IHAubWF0Y2hlcihpbnB1dFN0cmluZyk7CisgKiB3aGlsZSAobS5maW5kKCkpIHsgLy8gRmluZCBlYWNoIG1hdGNoIGluIHR1cm47IFN0cmluZyBjYW4ndCBkbyB0aGlzLgorICogICAgIFN0cmluZyBuYW1lID0gbS5ncm91cCgxKTsgLy8gQWNjZXNzIGEgc3VibWF0Y2ggZ3JvdXA7IFN0cmluZyBjYW4ndCBkbyB0aGlzLgorICogfQorICogPC9wcmU+CisgKgorICogPGgzPlJlZ3VsYXIgZXhwcmVzc2lvbiBzeW50YXg8L2gzPgorICogPHNwYW4gY2xhc3M9ImRhdGF0YWJsZSI+CisgKiA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgorICogLmRhdGF0YWJsZSB0ZCB7IHBhZGRpbmctcmlnaHQ6IDIwcHg7IH0KKyAqIDwvc3R5bGU+CisgKgorICogPHA+SmF2YSBzdXBwb3J0cyBhIHN1YnNldCBvZiBQZXJsIDUgcmVndWxhciBleHByZXNzaW9uIHN5bnRheC4gQW4gaW1wb3J0YW50IGdvdGNoYSBpcyB0aGF0IEphdmEKKyAqIGhhcyBubyByZWd1bGFyIGV4cHJlc3Npb24gbGl0ZXJhbHMsIGFuZCB1c2VzIHBsYWluIG9sZCBzdHJpbmcgbGl0ZXJhbHMgaW5zdGVhZC4gVGhpcyBtZWFucyB0aGF0CisgKiB5b3UgbmVlZCBhbiBleHRyYSBsZXZlbCBvZiBlc2NhcGluZy4gRm9yIGV4YW1wbGUsIHRoZSByZWd1bGFyIGV4cHJlc3Npb24ge0Bjb2RlIFxzK30gaGFzIHRvCisgKiBiZSByZXByZXNlbnRlZCBhcyB0aGUgc3RyaW5nIHtAY29kZSAiXFxzKyJ9LgorICoKKyAqIDxoMz5Fc2NhcGUgc2VxdWVuY2VzPC9oMz4KKyAqIDxwPjx0YWJsZT4KKyAqIDx0cj4gPHRkPiBcIDwvdGQ+IDx0ZD5RdW90ZSB0aGUgZm9sbG93aW5nIG1ldGFjaGFyYWN0ZXIgKHNvIHtAY29kZSBcLn0gbWF0Y2hlcyBhIGxpdGVyYWwge0Bjb2RlIC59KS48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFxRIDwvdGQ+IDx0ZD5RdW90ZSBhbGwgZm9sbG93aW5nIG1ldGFjaGFyYWN0ZXJzIHVudGlsIHtAY29kZSBcRX0uPC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBcRSA8L3RkPiA8dGQ+U3RvcCBxdW90aW5nIG1ldGFjaGFyYWN0ZXJzIChzdGFydGVkIGJ5IHtAY29kZSBcUX0pLjwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gXFwgPC90ZD4gPHRkPkEgbGl0ZXJhbCBiYWNrc2xhc2guPC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiAmI3gwMDVjO3U8aT5oaGhoPC9pPiA8L3RkPiA8dGQ+VGhlIFVuaWNvZGUgY2hhcmFjdGVyIFUraGhoaCAoaW4gaGV4KS48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+ICYjeDAwNWM7eDxpPmhoPC9pPiA8L3RkPiA8dGQ+VGhlIFVuaWNvZGUgY2hhcmFjdGVyIFUrMDBoaCAoaW4gaGV4KS48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFxjPGk+eDwvaT4gPC90ZD4gPHRkPlRoZSBBU0NJSSBjb250cm9sIGNoYXJhY3RlciBeeCAoc28ge0Bjb2RlIFxjSH0gd291bGQgYmUgXkgsIFUrMDAwOCkuPC90ZD4gPC90cj4KKyAqCisgKiA8dHI+IDx0ZD4gXGEgPC90ZD4gPHRkPlRoZSBBU0NJSSBiZWxsIGNoYXJhY3RlciAoVSswMDA3KS48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFxlIDwvdGQ+IDx0ZD5UaGUgQVNDSUkgRVNDIGNoYXJhY3RlciAoVSswMDFiKS48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFxmIDwvdGQ+IDx0ZD5UaGUgQVNDSUkgZm9ybSBmZWVkIGNoYXJhY3RlciAoVSswMDBjKS48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFxuIDwvdGQ+IDx0ZD5UaGUgQVNDSUkgbmV3bGluZSBjaGFyYWN0ZXIgKFUrMDAwYSkuPC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBcciA8L3RkPiA8dGQ+VGhlIEFTQ0lJIGNhcnJpYWdlIHJldHVybiBjaGFyYWN0ZXIgKFUrMDAwZCkuPC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBcdCA8L3RkPiA8dGQ+VGhlIEFTQ0lJIHRhYiBjaGFyYWN0ZXIgKFUrMDAwOSkuPC90ZD4gPC90cj4KKyAqIDwvdGFibGU+CisgKgorICogPGgzPkNoYXJhY3RlciBjbGFzc2VzPC9oMz4KKyAqIDxwPkl0J3MgcG9zc2libGUgdG8gY29uc3RydWN0IGFyYml0cmFyeSBjaGFyYWN0ZXIgY2xhc3NlcyB1c2luZyBzZXQgb3BlcmF0aW9uczoKKyAqIDx0YWJsZT4KKyAqIDx0cj4gPHRkPiBbYWJjXSA8L3RkPiA8dGQ+QW55IG9uZSBvZiB7QGNvZGUgYX0sIHtAY29kZSBifSwgb3Ige0Bjb2RlIGN9LiAoRW51bWVyYXRpb24uKTwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gW2EtY10gPC90ZD4gPHRkPkFueSBvbmUgb2Yge0Bjb2RlIGF9LCB7QGNvZGUgYn0sIG9yIHtAY29kZSBjfS4gKFJhbmdlLik8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFteYWJjXSA8L3RkPiA8dGQ+QW55IGNoYXJhY3RlciA8aT5leGNlcHQ8L2k+IHtAY29kZSBhfSwge0Bjb2RlIGJ9LCBvciB7QGNvZGUgY30uIChOZWdhdGlvbi4pPC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBbW2EtZl1bMC05XV0gPC90ZD4gPHRkPkFueSBjaGFyYWN0ZXIgaW4gZWl0aGVyIHJhbmdlLiAoVW5pb24uKTwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gW1thLXpdJiZbamtsXV0gPC90ZD4gPHRkPkFueSBjaGFyYWN0ZXIgaW4gYm90aCByYW5nZXMuIChJbnRlcnNlY3Rpb24uKTwvdGQ+IDwvdHI+CisgKiA8L3RhYmxlPgorICogPHA+TW9zdCBvZiB0aGUgdGltZSwgdGhlIGJ1aWx0LWluIGNoYXJhY3RlciBjbGFzc2VzIGFyZSBtb3JlIHVzZWZ1bDoKKyAqIDx0YWJsZT4KKyAqIDx0cj4gPHRkPiBcZCA8L3RkPiA8dGQ+QW55IGRpZ2l0IGNoYXJhY3Rlci48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFxEIDwvdGQ+IDx0ZD5Bbnkgbm9uLWRpZ2l0IGNoYXJhY3Rlci48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFxzIDwvdGQ+IDx0ZD5Bbnkgd2hpdGVzcGFjZSBjaGFyYWN0ZXIuPC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBcUyA8L3RkPiA8dGQ+QW55IG5vbi13aGl0ZXNwYWNlIGNoYXJhY3Rlci48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFx3IDwvdGQ+IDx0ZD5Bbnkgd29yZCBjaGFyYWN0ZXIuPC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBcVyA8L3RkPiA8dGQ+QW55IG5vbi13b3JkIGNoYXJhY3Rlci48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFxwezxpPk5BTUU8L2k+fSA8L3RkPiA8dGQ+IEFueSBjaGFyYWN0ZXIgaW4gdGhlIGNsYXNzIHdpdGggdGhlIGdpdmVuIDxpPk5BTUU8L2k+LiA8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFxQezxpPk5BTUU8L2k+fSA8L3RkPiA8dGQ+IEFueSBjaGFyYWN0ZXIgPGk+bm90PC9pPiBpbiB0aGUgbmFtZWQgY2xhc3MuIDwvdGQ+IDwvdHI+CisgKiA8L3RhYmxlPgorICogPHA+VGhlcmUgYXJlIGEgdmFyaWV0eSBvZiBuYW1lZCBjbGFzc2VzOgorICogPHVsPgorICogPGxpPjxhIGhyZWY9Ii4uLy4uL2xhbmcvQ2hhcmFjdGVyLmh0bWwjdW5pY29kZV9jYXRlZ29yaWVzIj5Vbmljb2RlIGNhdGVnb3J5IG5hbWVzPC9hPiwKKyAqIHByZWZpeGVkIGJ5IHtAY29kZSBJc30uIEZvciBleGFtcGxlIHtAY29kZSBccHtJc0x1fX0gZm9yIGFsbCB1cHBlcmNhc2UgbGV0dGVycy4KKyAqIDxsaT5QT1NJWCBjbGFzcyBuYW1lcy4gVGhlc2UgYXJlICdBbG51bScsICdBbHBoYScsICdBU0NJSScsICdCbGFuaycsICdDbnRybCcsICdEaWdpdCcsCisgKiAnR3JhcGgnLCAnTG93ZXInLCAnUHJpbnQnLCAnUHVuY3QnLCAnVXBwZXInLCAnWERpZ2l0Jy4KKyAqIDxsaT5Vbmljb2RlIGJsb2NrIG5hbWVzLCBhcyB1c2VkIGJ5IHtAbGluayBqYXZhLmxhbmcuQ2hhcmFjdGVyLlVuaWNvZGVCbG9jayNmb3JOYW1lfSBwcmVmaXhlZAorICogYnkge0Bjb2RlIElufS4gRm9yIGV4YW1wbGUge0Bjb2RlIFxwe0luSGVicmV3fX0gZm9yIGFsbCBjaGFyYWN0ZXJzIGluIHRoZSBIZWJyZXcgYmxvY2suCisgKiA8bGk+Q2hhcmFjdGVyIG1ldGhvZCBuYW1lcy4gVGhlc2UgYXJlIGFsbCBub24tZGVwcmVjYXRlZCBtZXRob2RzIGZyb20ge0BsaW5rIGphdmEubGFuZy5DaGFyYWN0ZXJ9CisgKiB3aG9zZSBuYW1lIHN0YXJ0cyB3aXRoIHtAY29kZSBpc30sIGJ1dCB3aXRoIHRoZSB7QGNvZGUgaXN9IHJlcGxhY2VkIGJ5IHtAY29kZSBqYXZhfS4KKyAqIEZvciBleGFtcGxlLCB7QGNvZGUgXHB7amF2YUxvd2VyQ2FzZX19LgorICogPC91bD4KKyAqCisgKiA8aDM+UXVhbnRpZmllcnM8L2gzPgorICogPHA+UXVhbnRpZmllcnMgbWF0Y2ggc29tZSBudW1iZXIgb2YgaW5zdGFuY2VzIG9mIHRoZSBwcmVjZWRpbmcgcmVndWxhciBleHByZXNzaW9uLgorICogPHRhYmxlPgorICogPHRyPiA8dGQ+ICogPC90ZD4gPHRkPlplcm8gb3IgbW9yZS48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+ID8gPC90ZD4gPHRkPlplcm8gb3Igb25lLjwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gKyA8L3RkPiA8dGQ+T25lIG9yIG1vcmUuPC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiB7PGk+bjwvaT59IDwvdGQ+IDx0ZD5FeGFjdGx5IDxpPm48L2k+LjwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gezxpPm4sPC9pPn0gPC90ZD4gPHRkPkF0IGxlYXN0IDxpPm48L2k+LjwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gezxpPm48L2k+LDxpPm08L2k+fSA8L3RkPiA8dGQ+QXQgbGVhc3QgPGk+bjwvaT4gYnV0IG5vdCBtb3JlIHRoYW4gPGk+bTwvaT4uPC90ZD4gPC90cj4KKyAqIDwvdGFibGU+CisgKiA8cD5RdWFudGlmaWVycyBhcmUgImdyZWVkeSIgYnkgZGVmYXVsdCwgbWVhbmluZyB0aGF0IHRoZXkgd2lsbCBtYXRjaCB0aGUgbG9uZ2VzdCBwb3NzaWJsZSBpbnB1dAorICogc2VxdWVuY2UuIFRoZXJlIGFyZSBhbHNvIG5vbi1ncmVlZHkgcXVhbnRpZmllcnMgdGhhdCBtYXRjaCB0aGUgc2hvcnRlc3QgcG9zc2libGUgaW5wdXQgc2VxdWVuY2UuCisgKiBUaGV5J3JlIHNhbWUgYXMgdGhlIGdyZWVkeSBvbmVzIGJ1dCB3aXRoIGEgdHJhaWxpbmcge0Bjb2RlID99OgorICogPHRhYmxlPgorICogPHRyPiA8dGQ+ICo/IDwvdGQ+IDx0ZD5aZXJvIG9yIG1vcmUgKG5vbi1ncmVlZHkpLjwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gPz8gPC90ZD4gPHRkPlplcm8gb3Igb25lIChub24tZ3JlZWR5KS48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+ICs/IDwvdGQ+IDx0ZD5PbmUgb3IgbW9yZSAobm9uLWdyZWVkeSkuPC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiB7PGk+bjwvaT59PyA8L3RkPiA8dGQ+RXhhY3RseSA8aT5uPC9pPiAobm9uLWdyZWVkeSkuPC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiB7PGk+biw8L2k+fT8gPC90ZD4gPHRkPkF0IGxlYXN0IDxpPm48L2k+IChub24tZ3JlZWR5KS48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IHs8aT5uPC9pPiw8aT5tPC9pPn0/IDwvdGQ+IDx0ZD5BdCBsZWFzdCA8aT5uPC9pPiBidXQgbm90IG1vcmUgdGhhbiA8aT5tPC9pPiAobm9uLWdyZWVkeSkuPC90ZD4gPC90cj4KKyAqIDwvdGFibGU+CisgKiA8cD5RdWFudGlmaWVycyBhbGxvdyBiYWNrdHJhY2tpbmcgYnkgZGVmYXVsdC4gVGhlcmUgYXJlIGFsc28gcG9zc2Vzc2l2ZSBxdWFudGlmaWVycyB0byBwcmV2ZW50CisgKiBiYWNrdHJhY2tpbmcuIFRoZXkncmUgc2FtZSBhcyB0aGUgZ3JlZWR5IG9uZXMgYnV0IHdpdGggYSB0cmFpbGluZyB7QGNvZGUgK306CisgKiA8dGFibGU+CisgKiA8dHI+IDx0ZD4gKisgPC90ZD4gPHRkPlplcm8gb3IgbW9yZSAocG9zc2Vzc2l2ZSkuPC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiA/KyA8L3RkPiA8dGQ+WmVybyBvciBvbmUgKHBvc3Nlc3NpdmUpLjwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gKysgPC90ZD4gPHRkPk9uZSBvciBtb3JlIChwb3NzZXNzaXZlKS48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IHs8aT5uPC9pPn0rIDwvdGQ+IDx0ZD5FeGFjdGx5IDxpPm48L2k+IChwb3NzZXNzaXZlKS48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IHs8aT5uLDwvaT59KyA8L3RkPiA8dGQ+QXQgbGVhc3QgPGk+bjwvaT4gKHBvc3Nlc3NpdmUpLjwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gezxpPm48L2k+LDxpPm08L2k+fSsgPC90ZD4gPHRkPkF0IGxlYXN0IDxpPm48L2k+IGJ1dCBub3QgbW9yZSB0aGFuIDxpPm08L2k+IChwb3NzZXNzaXZlKS48L3RkPiA8L3RyPgorICogPC90YWJsZT4KKyAqCisgKiA8aDM+WmVyby13aWR0aCBhc3NlcnRpb25zPC9oMz4KKyAqIDxwPjx0YWJsZT4KKyAqIDx0cj4gPHRkPiBeIDwvdGQ+IDx0ZD5BdCBiZWdpbm5pbmcgb2YgbGluZS48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+ICQgPC90ZD4gPHRkPkF0IGVuZCBvZiBsaW5lLjwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gXEEgPC90ZD4gPHRkPkF0IGJlZ2lubmluZyBvZiBpbnB1dC48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFxiIDwvdGQ+IDx0ZD5BdCB3b3JkIGJvdW5kYXJ5LjwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gXEIgPC90ZD4gPHRkPkF0IG5vbi13b3JkIGJvdW5kYXJ5LjwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gXEcgPC90ZD4gPHRkPkF0IGVuZCBvZiBwcmV2aW91cyBtYXRjaC48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFx6IDwvdGQ+IDx0ZD5BdCBlbmQgb2YgaW5wdXQuPC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiBcWiA8L3RkPiA8dGQ+QXQgZW5kIG9mIGlucHV0LCBvciBiZWZvcmUgbmV3bGluZSBhdCBlbmQuPC90ZD4gPC90cj4KKyAqIDwvdGFibGU+CisgKgorICogPGgzPkxvb2stYXJvdW5kIGFzc2VydGlvbnM8L2gzPgorICogPHA+TG9vay1hcm91bmQgYXNzZXJ0aW9ucyBhc3NlcnQgdGhhdCB0aGUgc3VicGF0dGVybiBkb2VzIChwb3NpdGl2ZSkgb3IgZG9lc24ndCAobmVnYXRpdmUpIG1hdGNoCisgKiBhZnRlciAobG9vay1haGVhZCkgb3IgYmVmb3JlIChsb29rLWJlaGluZCkgdGhlIGN1cnJlbnQgcG9zaXRpb24sIHdpdGhvdXQgaW5jbHVkaW5nIHRoZSBtYXRjaGVkCisgKiB0ZXh0IGluIHRoZSBjb250YWluaW5nIG1hdGNoLiBUaGUgbWF4aW11bSBsZW5ndGggb2YgcG9zc2libGUgbWF0Y2hlcyBmb3IgbG9vay1iZWhpbmQgcGF0dGVybnMKKyAqIG11c3Qgbm90IGJlIHVuYm91bmRlZC4KKyAqIDxwPjx0YWJsZT4KKyAqIDx0cj4gPHRkPiAoPz08aT5hPC9pPikgPC90ZD4gPHRkPlplcm8td2lkdGggcG9zaXRpdmUgbG9vay1haGVhZC48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+ICg/ITxpPmE8L2k+KSA8L3RkPiA8dGQ+WmVyby13aWR0aCBuZWdhdGl2ZSBsb29rLWFoZWFkLjwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gKD8mbHQ7PTxpPmE8L2k+KSA8L3RkPiA8dGQ+WmVyby13aWR0aCBwb3NpdGl2ZSBsb29rLWJlaGluZC48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+ICg/Jmx0OyE8aT5hPC9pPikgPC90ZD4gPHRkPlplcm8td2lkdGggbmVnYXRpdmUgbG9vay1iZWhpbmQuPC90ZD4gPC90cj4KKyAqIDwvdGFibGU+CisgKgorICogPGgzPkdyb3VwczwvaDM+CisgKgorICogPHA+PHRhYmxlPgorICogPHRyPiA8dGQ+ICg8aT5hPC9pPikgPC90ZD4gPHRkPkEgY2FwdHVyaW5nIGdyb3VwLjwvdGQ+IDwvdHI+CisgKiA8dHI+IDx0ZD4gKD86PGk+YTwvaT4pIDwvdGQ+IDx0ZD5BIG5vbi1jYXB0dXJpbmcgZ3JvdXAuPC90ZD4gPC90cj4KKyAqIDx0cj4gPHRkPiAoPyZndDs8aT5hPC9pPikgPC90ZD4gPHRkPkFuIGluZGVwZW5kZW50IG5vbi1jYXB0dXJpbmcgZ3JvdXAuIChUaGUgZmlyc3QgbWF0Y2ggb2YgdGhlIHN1Ymdyb3VwIGlzIHRoZSBvbmx5IG1hdGNoIHRyaWVkLik8L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IFw8aT5uPC9pPiA8L3RkPiA8dGQ+VGhlIHRleHQgYWxyZWFkeSBtYXRjaGVkIGJ5IGNhcHR1cmluZyBncm91cCA8aT5uPC9pPi48L3RkPiA8L3RyPgorICogPC90YWJsZT4KKyAqIDxwPlNlZSB7QGxpbmsgTWF0Y2hlciNncm91cH0gZm9yIGRldGFpbHMgb2YgaG93IGNhcHR1cmluZyBncm91cHMgYXJlIG51bWJlcmVkIGFuZCBhY2Nlc3NlZC4KKyAqCisgKiA8aDM+T3BlcmF0b3JzPC9oMz4KKyAqIDxwPjx0YWJsZT4KKyAqIDx0cj4gPHRkPiA8aT5hYjwvaT4gPC90ZD4gPHRkPkV4cHJlc3Npb24gPGk+YTwvaT4gZm9sbG93ZWQgYnkgZXhwcmVzc2lvbiA8aT5iPC9pPi48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+IDxpPmE8L2k+fDxpPmI8L2k+IDwvdGQ+IDx0ZD5FaXRoZXIgZXhwcmVzc2lvbiA8aT5hPC9pPiBvciBleHByZXNzaW9uIDxpPmI8L2k+LjwvdGQ+IDwvdHI+CisgKiA8L3RhYmxlPgorICoKKyAqIDxhIG5hbWU9ImZsYWdzIj48aDM+RmxhZ3M8L2gzPjwvYT4KKyAqIDxwPjx0YWJsZT4KKyAqIDx0cj4gPHRkPiAoP2RpbXN1eC1kaW1zdXg6PGk+YTwvaT4pIDwvdGQ+IDx0ZD5FdmFsdWF0ZXMgdGhlIGV4cHJlc3Npb24gPGk+YTwvaT4gd2l0aCB0aGUgZ2l2ZW4gZmxhZ3MgZW5hYmxlZC9kaXNhYmxlZC48L3RkPiA8L3RyPgorICogPHRyPiA8dGQ+ICg/ZGltc3V4LWRpbXN1eCkgPC90ZD4gPHRkPkV2YWx1YXRlcyB0aGUgcmVzdCBvZiB0aGUgcGF0dGVybiB3aXRoIHRoZSBnaXZlbiBmbGFncyBlbmFibGVkL2Rpc2FibGVkLjwvdGQ+IDwvdHI+CisgKiA8L3RhYmxlPgorICoKKyAqIDxwPlRoZSBmbGFncyBhcmU6CisgKiA8dGFibGU+CisgKiA8dHI+PHRkPntAY29kZSBpfTwvdGQ+IDx0ZD57QGxpbmsgI0NBU0VfSU5TRU5TSVRJVkV9PC90ZD4gPHRkPmNhc2UgaW5zZW5zaXRpdmUgbWF0Y2hpbmc8L3RkPjwvdHI+CisgKiA8dHI+PHRkPntAY29kZSBkfTwvdGQ+IDx0ZD57QGxpbmsgI1VOSVhfTElORVN9PC90ZD4gICAgICAgPHRkPm9ubHkgYWNjZXB0IHtAY29kZSAnXG4nfSBhcyBhIGxpbmUgdGVybWluYXRvcjwvdGQ+PC90cj4KKyAqIDx0cj48dGQ+e0Bjb2RlIG19PC90ZD4gPHRkPntAbGluayAjTVVMVElMSU5FfTwvdGQ+ICAgICAgICA8dGQ+YWxsb3cge0Bjb2RlIF59IGFuZCB7QGNvZGUgJH0gdG8gbWF0Y2ggYmVnaW5uaW5nL2VuZCBvZiBhbnkgbGluZTwvdGQ+PC90cj4KKyAqIDx0cj48dGQ+e0Bjb2RlIHN9PC90ZD4gPHRkPntAbGluayAjRE9UQUxMfTwvdGQ+ICAgICAgICAgICA8dGQ+YWxsb3cge0Bjb2RlIC59IHRvIG1hdGNoIHtAY29kZSAnXG4nfSAoInMiIGZvciAic2luZ2xlIGxpbmUiKTwvdGQ+PC90cj4KKyAqIDx0cj48dGQ+e0Bjb2RlIHV9PC90ZD4gPHRkPntAbGluayAjVU5JQ09ERV9DQVNFfTwvdGQ+ICAgICA8dGQ+ZW5hYmxlIFVuaWNvZGUgY2FzZSBmb2xkaW5nPC90ZD48L3RyPgorICogPHRyPjx0ZD57QGNvZGUgeH08L3RkPiA8dGQ+e0BsaW5rICNDT01NRU5UU308L3RkPiAgICAgICAgIDx0ZD5hbGxvdyB3aGl0ZXNwYWNlIGFuZCBjb21tZW50czwvdGQ+PC90cj4KKyAqIDwvdGFibGU+CisgKiA8cD5FaXRoZXIgc2V0IG9mIGZsYWdzIG1heSBiZSBlbXB0eS4gRm9yIGV4YW1wbGUsIHtAY29kZSAoP2ktbSl9IHdvdWxkIHR1cm4gb24gY2FzZS1pbnNlbnNpdGl2aXR5CisgKiBhbmQgdHVybiBvZmYgbXVsdGlsaW5lIG1vZGUsIHtAY29kZSAoP2kpfSB3b3VsZCBqdXN0IHR1cm4gb24gY2FzZS1pbnNlbnNpdGl2aXR5LAorICogYW5kIHtAY29kZSAoPy1tKX0gd291bGQganVzdCB0dXJuIG9mZiBtdWx0aWxpbmUgbW9kZS4KKyAqIDxwPk5vdGUgdGhhdCBvbiBBbmRyb2lkLCB7QGNvZGUgVU5JQ09ERV9DQVNFfSBpcyBhbHdheXMgb246IGNhc2UtaW5zZW5zaXRpdmUgbWF0Y2hpbmcgd2lsbAorICogYWx3YXlzIGJlIFVuaWNvZGUtYXdhcmUuCisgKiA8cD5UaGVyZSBhcmUgdHdvIG90aGVyIGZsYWdzIG5vdCBzZXR0YWJsZSB2aWEgdGhpcyBtZWNoYW5pc206IHtAbGluayAjQ0FOT05fRVF9IGFuZAorICoge0BsaW5rICNMSVRFUkFMfS4gQXR0ZW1wdHMgdG8gdXNlIHtAbGluayAjQ0FOT05fRVF9IG9uIEFuZHJvaWQgd2lsbCB0aHJvdyBhbiBleGNlcHRpb24uCisgKiA8L3NwYW4+CisgKgorICogPGgzPkltcGxlbWVudGF0aW9uIG5vdGVzPC9oMz4KKyAqCisgKiA8cD5UaGUgcmVndWxhciBleHByZXNzaW9uIGltcGxlbWVudGF0aW9uIHVzZWQgaW4gQW5kcm9pZCBpcyBwcm92aWRlZCBieQorICogPGEgaHJlZj0iaHR0cDovL3d3dy5pY3UtcHJvamVjdC5vcmciPklDVTwvYT4uIFRoZSBub3RhdGlvbiBmb3IgdGhlIHJlZ3VsYXIKKyAqIGV4cHJlc3Npb25zIGlzIG1vc3RseSBhIHN1cGVyc2V0IG9mIHRob3NlIHVzZWQgaW4gb3RoZXIgSmF2YSBsYW5ndWFnZQorICogaW1wbGVtZW50YXRpb25zLiBUaGlzIG1lYW5zIHRoYXQgZXhpc3RpbmcgYXBwbGljYXRpb25zIHdpbGwgbm9ybWFsbHkgd29yayBhcworICogZXhwZWN0ZWQsIGJ1dCBpbiByYXJlIGNhc2VzIEFuZHJvaWQgbWF5IGFjY2VwdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0aGF0IGlzCisgKiBub3QgYWNjZXB0ZWQgYnkgb3RoZXIgaW1wbGVtZW50YXRpb25zLgorICoKKyAqIDxwPkluIHNvbWUgY2FzZXMsIEFuZHJvaWQgd2lsbCByZWNvZ25pemUgdGhhdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBpcyBhIHNpbXBsZQorICogc3BlY2lhbCBjYXNlIHRoYXQgY2FuIGJlIGhhbmRsZWQgbW9yZSBlZmZpY2llbnRseS4gVGhpcyBpcyB0cnVlIG9mIGJvdGggdGhlIGNvbnZlbmllbmNlIG1ldGhvZHMKKyAqIGluIHtAY29kZSBTdHJpbmd9IGFuZCB0aGUgbWV0aG9kcyBpbiB7QGNvZGUgUGF0dGVybn0uCisgKgorICogQHNlZSBNYXRjaGVyCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBQYXR0ZXJuIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDUwNzMyNTgxNjI2NDQ2NDg0NjFMOworCisgICAgLyoqCisgICAgICogVGhpcyBjb25zdGFudCBzcGVjaWZpZXMgdGhhdCBhIHBhdHRlcm4gbWF0Y2hlcyBVbml4IGxpbmUgZW5kaW5ncyAoJ1xuJykKKyAgICAgKiBvbmx5IGFnYWluc3QgdGhlICcuJywgJ14nLCBhbmQgJyQnIG1ldGEgY2hhcmFjdGVycy4gQ29ycmVzcG9uZHMgdG8ge0Bjb2RlICg/ZCl9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOSVhfTElORVMgPSAweDAxOworCisgICAgLyoqCisgICAgICogVGhpcyBjb25zdGFudCBzcGVjaWZpZXMgdGhhdCBhIHtAY29kZSBQYXR0ZXJufSBpcyBtYXRjaGVkCisgICAgICogY2FzZS1pbnNlbnNpdGl2ZWx5LiBUaGF0IGlzLCB0aGUgcGF0dGVybnMgImErIiBhbmQgIkErIiB3b3VsZCBib3RoIG1hdGNoCisgICAgICogdGhlIHN0cmluZyAiYUFhQWFBIi4gU2VlIHtAbGluayAjVU5JQ09ERV9DQVNFfS4gQ29ycmVzcG9uZHMgdG8ge0Bjb2RlICg/aSl9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENBU0VfSU5TRU5TSVRJVkUgPSAweDAyOworCisgICAgLyoqCisgICAgICogVGhpcyBjb25zdGFudCBzcGVjaWZpZXMgdGhhdCBhIHtAY29kZSBQYXR0ZXJufSBtYXkgY29udGFpbiB3aGl0ZXNwYWNlIG9yCisgICAgICogY29tbWVudHMuIE90aGVyd2lzZSBjb21tZW50cyBhbmQgd2hpdGVzcGFjZSBhcmUgdGFrZW4gYXMgbGl0ZXJhbAorICAgICAqIGNoYXJhY3RlcnMuIENvcnJlc3BvbmRzIHRvIHtAY29kZSAoP3gpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT01NRU5UUyA9IDB4MDQ7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNvbnN0YW50IHNwZWNpZmllcyB0aGF0IHRoZSBtZXRhIGNoYXJhY3RlcnMgJ14nIGFuZCAnJCcgbWF0Y2ggb25seQorICAgICAqIHRoZSBiZWdpbm5pbmcgYW5kIGVuZCBvZiBhbiBpbnB1dCBsaW5lLCByZXNwZWN0aXZlbHkuIE5vcm1hbGx5LCB0aGV5CisgICAgICogbWF0Y2ggdGhlIGJlZ2lubmluZyBhbmQgdGhlIGVuZCBvZiB0aGUgY29tcGxldGUgaW5wdXQuIENvcnJlc3BvbmRzIHRvIHtAY29kZSAoP20pfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNVUxUSUxJTkUgPSAweDA4OworCisgICAgLyoqCisgICAgICogVGhpcyBjb25zdGFudCBzcGVjaWZpZXMgdGhhdCB0aGUgd2hvbGUge0Bjb2RlIFBhdHRlcm59IGlzIHRvIGJlIHRha2VuCisgICAgICogbGl0ZXJhbGx5LCB0aGF0IGlzLCBhbGwgbWV0YSBjaGFyYWN0ZXJzIGxvc2UgdGhlaXIgbWVhbmluZ3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTElURVJBTCA9IDB4MTA7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNvbnN0YW50IHNwZWNpZmllcyB0aGF0IHRoZSAnLicgbWV0YSBjaGFyYWN0ZXIgbWF0Y2hlcyBhcmJpdHJhcnkKKyAgICAgKiBjaGFyYWN0ZXJzLCBpbmNsdWRpbmcgbGluZSBlbmRpbmdzLCB3aGljaCBpcyBub3JtYWxseSBub3QgdGhlIGNhc2UuCisgICAgICogQ29ycmVzcG9uZHMgdG8ge0Bjb2RlICg/cyl9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERPVEFMTCA9IDB4MjA7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNvbnN0YW50IHNwZWNpZmllcyB0aGF0IGEge0Bjb2RlIFBhdHRlcm59IHRoYXQgdXNlcyBjYXNlLWluc2Vuc2l0aXZlIG1hdGNoaW5nCisgICAgICogd2lsbCB1c2UgVW5pY29kZSBjYXNlIGZvbGRpbmcuIE9uIEFuZHJvaWQsIHtAY29kZSBVTklDT0RFX0NBU0V9IGlzIGFsd2F5cyBvbjoKKyAgICAgKiBjYXNlLWluc2Vuc2l0aXZlIG1hdGNoaW5nIHdpbGwgYWx3YXlzIGJlIFVuaWNvZGUtYXdhcmUuIElmIHlvdXIgY29kZSBpcyBpbnRlbmRlZCB0bworICAgICAqIGJlIHBvcnRhYmxlIGFuZCB1c2VzIGNhc2UtaW5zZW5zaXRpdmUgbWF0Y2hpbmcgb24gbm9uLUFTQ0lJIGNoYXJhY3RlcnMsIHlvdSBzaG91bGQKKyAgICAgKiB1c2UgdGhpcyBmbGFnLiBDb3JyZXNwb25kcyB0byB7QGNvZGUgKD91KX0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5JQ09ERV9DQVNFID0gMHg0MDsKKworICAgIC8qKgorICAgICAqIFRoaXMgY29uc3RhbnQgc3BlY2lmaWVzIHRoYXQgYSBjaGFyYWN0ZXIgaW4gYSB7QGNvZGUgUGF0dGVybn0gYW5kIGEKKyAgICAgKiBjaGFyYWN0ZXIgaW4gdGhlIGlucHV0IHN0cmluZyBvbmx5IG1hdGNoIGlmIHRoZXkgYXJlIGNhbm9uaWNhbGx5CisgICAgICogZXF1aXZhbGVudC4gSXQgaXMgKGN1cnJlbnRseSkgbm90IHN1cHBvcnRlZCBpbiBBbmRyb2lkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENBTk9OX0VRID0gMHg4MDsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHBhdHRlcm47CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgZmxhZ3M7CisKKyAgICB0cmFuc2llbnQgaW50IGFkZHJlc3M7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEge0BsaW5rIE1hdGNoZXJ9IGZvciB0aGlzIHBhdHRlcm4gYXBwbGllZCB0byB0aGUgZ2l2ZW4ge0Bjb2RlIGlucHV0fS4KKyAgICAgKiBUaGUge0Bjb2RlIE1hdGNoZXJ9IGNhbiBiZSB1c2VkIHRvIG1hdGNoIHRoZSB7QGNvZGUgUGF0dGVybn0gYWdhaW5zdCB0aGUKKyAgICAgKiB3aG9sZSBpbnB1dCwgZmluZCBvY2N1cnJlbmNlcyBvZiB0aGUge0Bjb2RlIFBhdHRlcm59IGluIHRoZSBpbnB1dCwgb3IKKyAgICAgKiByZXBsYWNlIHBhcnRzIG9mIHRoZSBpbnB1dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWF0Y2hlciBtYXRjaGVyKENoYXJTZXF1ZW5jZSBpbnB1dCkgeworICAgICAgICByZXR1cm4gbmV3IE1hdGNoZXIodGhpcywgaW5wdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNwbGl0cyB0aGUgZ2l2ZW4ge0Bjb2RlIGlucHV0fSBhdCBvY2N1cnJlbmNlcyBvZiB0aGlzIHBhdHRlcm4uCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGlzIHBhdHRlcm4gZG9lcyBub3Qgb2NjdXIgaW4gdGhlIGlucHV0LCB0aGUgcmVzdWx0IGlzIGFuCisgICAgICogYXJyYXkgY29udGFpbmluZyB0aGUgaW5wdXQgKGNvbnZlcnRlZCBmcm9tIGEge0Bjb2RlIENoYXJTZXF1ZW5jZX0gdG8KKyAgICAgKiBhIHtAY29kZSBTdHJpbmd9KS4KKyAgICAgKgorICAgICAqIDxwPk90aGVyd2lzZSwgdGhlIHtAY29kZSBsaW1pdH0gcGFyYW1ldGVyIGNvbnRyb2xzIHRoZSBjb250ZW50cyBvZiB0aGUKKyAgICAgKiByZXR1cm5lZCBhcnJheSBhcyBkZXNjcmliZWQgYmVsb3cuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGltaXQKKyAgICAgKiAgICAgICAgICAgIERldGVybWluZXMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGVudHJpZXMgaW4gdGhlIHJlc3VsdGluZworICAgICAqICAgICAgICAgICAgYXJyYXksIGFuZCB0aGUgdHJlYXRtZW50IG9mIHRyYWlsaW5nIGVtcHR5IHN0cmluZ3MuCisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+Rm9yIG4gJmd0OyAwLCB0aGUgcmVzdWx0aW5nIGFycmF5IGNvbnRhaW5zIGF0IG1vc3QgbgorICAgICAqICAgICAgICAgICAgZW50cmllcy4gSWYgdGhpcyBpcyBmZXdlciB0aGFuIHRoZSBudW1iZXIgb2YgbWF0Y2hlcywgdGhlCisgICAgICogICAgICAgICAgICBmaW5hbCBlbnRyeSB3aWxsIGNvbnRhaW4gYWxsIHJlbWFpbmluZyBpbnB1dC4KKyAgICAgKiAgICAgICAgICAgIDxsaT5Gb3IgbiAmbHQ7IDAsIHRoZSBsZW5ndGggb2YgdGhlIHJlc3VsdGluZyBhcnJheSBpcworICAgICAqICAgICAgICAgICAgZXhhY3RseSB0aGUgbnVtYmVyIG9mIG9jY3VycmVuY2VzIG9mIHRoZSB7QGNvZGUgUGF0dGVybn0KKyAgICAgKiAgICAgICAgICAgIHBsdXMgb25lIGZvciB0aGUgdGV4dCBhZnRlciB0aGUgZmluYWwgc2VwYXJhdG9yLgorICAgICAqICAgICAgICAgICAgQWxsIGVudHJpZXMgYXJlIGluY2x1ZGVkLgorICAgICAqICAgICAgICAgICAgPGxpPkZvciBuID09IDAsIHRoZSByZXN1bHQgaXMgYXMgZm9yIG4gJmx0OyAwLCBleGNlcHQKKyAgICAgKiAgICAgICAgICAgIHRyYWlsaW5nIGVtcHR5IHN0cmluZ3Mgd2lsbCBub3QgYmUgcmV0dXJuZWQuIChOb3RlIHRoYXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjYXNlIHdoZXJlIHRoZSBpbnB1dCBpcyBpdHNlbGYgYW4gZW1wdHkgc3RyaW5nIGlzCisgICAgICogICAgICAgICAgICBzcGVjaWFsLCBhcyBkZXNjcmliZWQgYWJvdmUsIGFuZCB0aGUgbGltaXQgcGFyYW1ldGVyIGRvZXMKKyAgICAgKiAgICAgICAgICAgIG5vdCBhcHBseSB0aGVyZS4pCisgICAgICogICAgICAgICAgICA8L3VsPgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBzcGxpdChDaGFyU2VxdWVuY2UgaW5wdXQsIGludCBsaW1pdCkgeworICAgICAgICByZXR1cm4gU3BsaXR0ZXIuc3BsaXQodGhpcywgcGF0dGVybiwgaW5wdXQudG9TdHJpbmcoKSwgbGltaXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8ge0Bjb2RlIHNwbGl0KGlucHV0LCAwKX0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIHNwbGl0KENoYXJTZXF1ZW5jZSBpbnB1dCkgeworICAgICAgICByZXR1cm4gc3BsaXQoaW5wdXQsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBzdXBwbGllZCB0byB7QGNvZGUgY29tcGlsZX0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBwYXR0ZXJuKCkgeworICAgICAgICByZXR1cm4gcGF0dGVybjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gcGF0dGVybjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBmbGFncyBzdXBwbGllZCB0byB7QGNvZGUgY29tcGlsZX0uCisgICAgICovCisgICAgcHVibGljIGludCBmbGFncygpIHsKKyAgICAgICAgcmV0dXJuIGZsYWdzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb21waWxlZCBmb3JtIG9mIHRoZSBnaXZlbiB7QGNvZGUgcmVndWxhckV4cHJlc3Npb259LCBhcyBtb2RpZmllZCBieSB0aGUKKyAgICAgKiBnaXZlbiB7QGNvZGUgZmxhZ3N9LiBTZWUgdGhlIDxhIGhyZWY9IiNmbGFncyI+ZmxhZ3Mgb3ZlcnZpZXc8L2E+IGZvciBtb3JlIG9uIGZsYWdzLgorICAgICAqCisgICAgICogQHRocm93cyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGlmIHRoZSByZWd1bGFyIGV4cHJlc3Npb24gaXMgc3ludGFjdGljYWxseSBpbmNvcnJlY3QuCisgICAgICoKKyAgICAgKiBAc2VlICNDQU5PTl9FUQorICAgICAqIEBzZWUgI0NBU0VfSU5TRU5TSVRJVkUKKyAgICAgKiBAc2VlICNDT01NRU5UUworICAgICAqIEBzZWUgI0RPVEFMTAorICAgICAqIEBzZWUgI0xJVEVSQUwKKyAgICAgKiBAc2VlICNNVUxUSUxJTkUKKyAgICAgKiBAc2VlICNVTklDT0RFX0NBU0UKKyAgICAgKiBAc2VlICNVTklYX0xJTkVTCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBQYXR0ZXJuIGNvbXBpbGUoU3RyaW5nIHJlZ3VsYXJFeHByZXNzaW9uLCBpbnQgZmxhZ3MpIHRocm93cyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBQYXR0ZXJuKHJlZ3VsYXJFeHByZXNzaW9uLCBmbGFncyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgUGF0dGVybi5jb21waWxlKHBhdHRlcm4sIDApfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFBhdHRlcm4gY29tcGlsZShTdHJpbmcgcGF0dGVybikgeworICAgICAgICByZXR1cm4gbmV3IFBhdHRlcm4ocGF0dGVybiwgMCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBQYXR0ZXJuKFN0cmluZyBwYXR0ZXJuLCBpbnQgZmxhZ3MpIHRocm93cyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKChmbGFncyAmIENBTk9OX0VRKSAhPSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIkNBTk9OX0VRIGZsYWcgbm90IHN1cHBvcnRlZCIpOworICAgICAgICB9CisgICAgICAgIHRoaXMucGF0dGVybiA9IHBhdHRlcm47CisgICAgICAgIHRoaXMuZmxhZ3MgPSBmbGFnczsKKyAgICAgICAgY29tcGlsZSgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjb21waWxlKCkgdGhyb3dzIFBhdHRlcm5TeW50YXhFeGNlcHRpb24geworICAgICAgICBpZiAocGF0dGVybiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInBhdHRlcm4gPT0gbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGljdVBhdHRlcm4gPSBwYXR0ZXJuOworICAgICAgICBpZiAoKGZsYWdzICYgTElURVJBTCkgIT0gMCkgeworICAgICAgICAgICAgaWN1UGF0dGVybiA9IHF1b3RlKHBhdHRlcm4pOworICAgICAgICB9CisKKyAgICAgICAgLy8gVGhlc2UgYXJlIHRoZSBmbGFncyBuYXRpdmVseSBzdXBwb3J0ZWQgYnkgSUNVLgorICAgICAgICAvLyBUaGV5IGV2ZW4gaGF2ZSB0aGUgc2FtZSB2YWx1ZSBpbiBuYXRpdmUgY29kZS4KKyAgICAgICAgaW50IGljdUZsYWdzID0gZmxhZ3MgJiAoQ0FTRV9JTlNFTlNJVElWRSB8IENPTU1FTlRTIHwgTVVMVElMSU5FIHwgRE9UQUxMIHwgVU5JWF9MSU5FUyk7CisKKyAgICAgICAgYWRkcmVzcyA9IGNvbXBpbGVJbXBsKGljdVBhdHRlcm4sIGljdUZsYWdzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB3aGV0aGVyIHRoZSBnaXZlbiB7QGNvZGUgcmVndWxhckV4cHJlc3Npb259IG1hdGNoZXMgdGhlIGdpdmVuIHtAY29kZSBpbnB1dH0uCisgICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgUGF0dGVybi5jb21waWxlKHJlZ3VsYXJFeHByZXNzaW9uKS5tYXRjaGVyKGlucHV0KS5tYXRjaGVzKCl9LgorICAgICAqIElmIHRoZSBzYW1lIHJlZ3VsYXIgZXhwcmVzc2lvbiBpcyB0byBiZSB1c2VkIGZvciBtdWx0aXBsZSBvcGVyYXRpb25zLCBpdCBtYXkgYmUgbW9yZQorICAgICAqIGVmZmljaWVudCB0byByZXVzZSBhIGNvbXBpbGVkIHtAY29kZSBQYXR0ZXJufS4KKyAgICAgKgorICAgICAqIEBzZWUgUGF0dGVybiNjb21waWxlKGphdmEubGFuZy5TdHJpbmcsIGludCkKKyAgICAgKiBAc2VlIE1hdGNoZXIjbWF0Y2hlcygpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIG1hdGNoZXMoU3RyaW5nIHJlZ3VsYXJFeHByZXNzaW9uLCBDaGFyU2VxdWVuY2UgaW5wdXQpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBNYXRjaGVyKG5ldyBQYXR0ZXJuKHJlZ3VsYXJFeHByZXNzaW9uLCAwKSwgaW5wdXQpLm1hdGNoZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBRdW90ZXMgdGhlIGdpdmVuIHtAY29kZSBzdHJpbmd9IHVzaW5nICJcUSIgYW5kICJcRSIsIHNvIHRoYXQgYWxsCisgICAgICogbWV0YS1jaGFyYWN0ZXJzIGxvc2UgdGhlaXIgc3BlY2lhbCBtZWFuaW5nLiBUaGlzIG1ldGhvZCBjb3JyZWN0bHkKKyAgICAgKiBlc2NhcGVzIGVtYmVkZGVkIGluc3RhbmNlcyBvZiAiXFEiIG9yICJcRSIuIElmIHRoZSBlbnRpcmUgcmVzdWx0CisgICAgICogaXMgdG8gYmUgcGFzc2VkIHZlcmJhdGltIHRvIHtAbGluayAjY29tcGlsZX0sIGl0J3MgdXN1YWxseSBjbGVhcmVyCisgICAgICogdG8gdXNlIHRoZSB7QGxpbmsgI0xJVEVSQUx9IGZsYWcgaW5zdGVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBxdW90ZShTdHJpbmcgc3RyaW5nKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBzYi5hcHBlbmQoIlxcUSIpOworICAgICAgICBpbnQgYXBvcyA9IDA7CisgICAgICAgIGludCBrOworICAgICAgICB3aGlsZSAoKGsgPSBzdHJpbmcuaW5kZXhPZigiXFxFIiwgYXBvcykpID49IDApIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZChzdHJpbmcuc3Vic3RyaW5nKGFwb3MsIGsgKyAyKSkuYXBwZW5kKCJcXFxcRVxcUSIpOworICAgICAgICAgICAgYXBvcyA9IGsgKyAyOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzYi5hcHBlbmQoc3RyaW5nLnN1YnN0cmluZyhhcG9zKSkuYXBwZW5kKCJcXEUiKS50b1N0cmluZygpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2xvc2VJbXBsKGFkZHJlc3MpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc3VwZXIuZmluYWxpemUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIHMpIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIHMuZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgY29tcGlsZSgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIGNsb3NlSW1wbChpbnQgYWRkcik7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGludCBjb21waWxlSW1wbChTdHJpbmcgcmVnZXgsIGludCBmbGFncyk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3JlZ2V4L1BhdHRlcm5TeW50YXhFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcmVnZXgvUGF0dGVyblN5bnRheEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjMWRlNGIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3JlZ2V4L1BhdHRlcm5TeW50YXhFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDE0MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwucmVnZXg7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIEVuY2Fwc3VsYXRlcyBhIHN5bnRheCBlcnJvciB0aGF0IG9jY3VycmVkIGR1cmluZyB0aGUgY29tcGlsYXRpb24gb2YgYQorICoge0BsaW5rIFBhdHRlcm59LiBNaWdodCBpbmNsdWRlIGEgZGV0YWlsZWQgZGVzY3JpcHRpb24sIHRoZSBvcmlnaW5hbCByZWd1bGFyCisgKiBleHByZXNzaW9uLCBhbmQgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBlcnJvciBvY2N1cnJlZC4KKyAqCisgKiBAc2VlIFBhdHRlcm4jY29tcGlsZShTdHJpbmcpCisgKiBAc2VlIFBhdHRlcm4jY29tcGlsZShqYXZhLmxhbmcuU3RyaW5nLGludCkKKyAqLworcHVibGljIGNsYXNzIFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZXh0ZW5kcyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTM4NjQ2MzkxMjYyMjYwNTkyMThMOworCisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBzeW50YXggZXJyb3IsIG9yIG51bGwgaWYgdGhlIGRlc2NyaXB0aW9uIGlzCisgICAgICogbm90IGtub3duLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGRlc2M7CisKKyAgICAvKioKKyAgICAgKiBIb2xkcyB0aGUgc3ludGFjdGljYWxseSBpbmNvcnJlY3QgcmVndWxhciBleHByZXNzaW9uLCBvciBudWxsIGlmIHRoZQorICAgICAqIHJlZ3VsYXIgZXhwcmVzc2lvbiBpcyBub3Qga25vd24uCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgcGF0dGVybjsKKworICAgIC8qKgorICAgICAqIEhvbGRzIHRoZSBpbmRleCBhcm91bmQgd2hpY2ggdGhlIGVycm9yIG9jY3VyZWQsIG9yIC0xLCBpbiBjYXNlIGl0IGlzCisgICAgICogdW5rbm93bi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBpbmRleCA9IC0xOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGZvciBhIGdpdmVuIG1lc3NhZ2UsIHBhdHRlcm4sIGFuZAorICAgICAqIGVycm9yIGluZGV4LgorICAgICAqCisgICAgICogQHBhcmFtIGRlc2NyaXB0aW9uCisgICAgICogICAgICAgICAgICB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIHN5bnRheCBlcnJvciwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqICAgICAgICAgICAgZGVzY3JpcHRpb24gaXMgbm90IGtub3duLgorICAgICAqIEBwYXJhbSBwYXR0ZXJuCisgICAgICogICAgICAgICAgICB0aGUgc3ludGFjdGljYWxseSBpbmNvcnJlY3QgcmVndWxhciBleHByZXNzaW9uLCBvcgorICAgICAqICAgICAgICAgICAge0Bjb2RlIG51bGx9IGlmIHRoZSByZWd1bGFyIGV4cHJlc3Npb24gaXMgbm90IGtub3duLgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGNoYXJhY3RlciBpbmRleCBhcm91bmQgd2hpY2ggdGhlIGVycm9yIG9jY3VycmVkLCBvciAtMSBpZgorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IGlzIG5vdCBrbm93bi4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGF0dGVyblN5bnRheEV4Y2VwdGlvbihTdHJpbmcgZGVzY3JpcHRpb24sIFN0cmluZyBwYXR0ZXJuLCBpbnQgaW5kZXgpIHsKKyAgICAgICAgdGhpcy5kZXNjID0gZGVzY3JpcHRpb247CisgICAgICAgIHRoaXMucGF0dGVybiA9IHBhdHRlcm47CisgICAgICAgIHRoaXMuaW5kZXggPSBpbmRleDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzeW50YWN0aWNhbGx5IGluY29ycmVjdCByZWd1bGFyIGV4cHJlc3Npb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZWd1bGFyIGV4cHJlc3Npb24uCisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFBhdHRlcm4oKSB7CisgICAgICAgIHJldHVybiBwYXR0ZXJuOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBkZXRhaWxlZCBlcnJvciBtZXNzYWdlIGZvciB0aGUgZXhjZXB0aW9uLiBUaGUgbWVzc2FnZSBpcworICAgICAqIHBvdGVudGlhbGx5IG11bHRpLWxpbmUsIGFuZCBpdCBtaWdodCBpbmNsdWRlIGEgZGV0YWlsZWQgZGVzY3JpcHRpb24sIHRoZQorICAgICAqIG9yaWdpbmFsIHJlZ3VsYXIgZXhwcmVzc2lvbiwgYW5kIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgZXJyb3Igb2NjdXJyZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBlcnJvciBtZXNzYWdlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGlmIChkZXNjICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZChkZXNjKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChpbmRleCA+PSAwKSB7CisgICAgICAgICAgICBpZiAoZGVzYyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCcgJyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzYi5hcHBlbmQoIm5lYXIgaW5kZXggIik7CisgICAgICAgICAgICBzYi5hcHBlbmQoaW5kZXgpOworICAgICAgICAgICAgc2IuYXBwZW5kKCc6Jyk7CisgICAgICAgIH0KKworICAgICAgICBpZiAocGF0dGVybiAhPSBudWxsKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoJ1xuJyk7CisgICAgICAgICAgICBzYi5hcHBlbmQocGF0dGVybik7CisKKyAgICAgICAgICAgIGlmIChpbmRleCA+PSAwKSB7CisgICAgICAgICAgICAgICAgY2hhcltdIHNwYWNlcyA9IG5ldyBjaGFyW2luZGV4XTsKKyAgICAgICAgICAgICAgICBBcnJheXMuZmlsbChzcGFjZXMsICcgJyk7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCdcbicpOworICAgICAgICAgICAgICAgIHNiLmFwcGVuZChzcGFjZXMpOworICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgnXicpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIHN5bnRheCBlcnJvciwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqIGRlc2NyaXB0aW9uIGlzIG5vdCBrbm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGRlc2NyaXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGVzY3JpcHRpb24oKSB7CisgICAgICAgIHJldHVybiBkZXNjOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNoYXJhY3RlciBpbmRleCBhcm91bmQgd2hpY2ggdGhlIGVycm9yIG9jY3VycmVkLCBvciAtMSBpZiB0aGUKKyAgICAgKiBpbmRleCBpcyBub3Qga25vd24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbmRleC4KKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXgoKSB7CisgICAgICAgIHJldHVybiBpbmRleDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3JlZ2V4L1NwbGl0dGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3JlZ2V4L1NwbGl0dGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDMwYmFkYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvcmVnZXgvU3BsaXR0ZXIuamF2YQpAQCAtMCwwICsxLDEyMCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLnJlZ2V4OworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBVc2VkIHRvIG1ha2Uge0Bjb2RlIFN0cmluZy5zcGxpdH0gZmFzdCAoYW5kIHRvIGhlbHAge0Bjb2RlIFBhdHRlcm4uc3BsaXR9IHRvbykuCisgKiBAaGlkZQorICovCitwdWJsaWMgY2xhc3MgU3BsaXR0ZXIgeworICAgIC8vIFRoZSBSSSBhbGxvd3MgcmVndWxhciBleHByZXNzaW9ucyBiZWdpbm5pbmcgd2l0aCBdIG9yIH0sIGJ1dCB0aGF0J3MgcHJvYmFibHkgYSBidWcuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE1FVEFDSEFSQUNURVJTID0gIlxcPyorW10oKXt9XiQufCI7CisKKyAgICBwcml2YXRlIFNwbGl0dGVyKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSByZXN1bHQgZXF1aXZhbGVudCB0byB7QGNvZGUgcy5zcGxpdChzZXBhcmF0b3IsIGxpbWl0KX0gaWYgaXQncyBhYmxlCisgICAgICogdG8gY29tcHV0ZSBpdCBtb3JlIGNoZWFwbHkgdGhhbiBJQ1UsIG9yIG51bGwgaWYgdGhlIGNhbGxlciBzaG91bGQgZmFsbCBiYWNrIHRvCisgICAgICogdXNpbmcgSUNVLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gZmFzdFNwbGl0KFN0cmluZyByZSwgU3RyaW5nIGlucHV0LCBpbnQgbGltaXQpIHsKKyAgICAgICAgLy8gQ2FuIHdlIGRvIGl0IGNoZWFwbHk/CisgICAgICAgIGludCBsZW4gPSByZS5sZW5ndGgoKTsKKyAgICAgICAgaWYgKGxlbiA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBjaGFyIGNoID0gcmUuY2hhckF0KDApOworICAgICAgICBpZiAobGVuID09IDEgJiYgTUVUQUNIQVJBQ1RFUlMuaW5kZXhPZihjaCkgPT0gLTEpIHsKKyAgICAgICAgICAgIC8vIFdlJ3JlIGxvb2tpbmcgZm9yIGEgc2luZ2xlIG5vbi1tZXRhY2hhcmFjdGVyLiBFYXN5LgorICAgICAgICB9IGVsc2UgaWYgKGxlbiA9PSAyICYmIGNoID09ICdcXCcpIHsKKyAgICAgICAgICAgIC8vIFdlJ3JlIGxvb2tpbmcgZm9yIGEgcXVvdGVkIGNoYXJhY3Rlci4KKyAgICAgICAgICAgIC8vIFF1b3RlZCBtZXRhY2hhcmFjdGVycyBhcmUgZWZmZWN0aXZlbHkgc2luZ2xlIG5vbi1tZXRhY2hhcmFjdGVycy4KKyAgICAgICAgICAgIGNoID0gcmUuY2hhckF0KDEpOworICAgICAgICAgICAgaWYgKE1FVEFDSEFSQUNURVJTLmluZGV4T2YoY2gpID09IC0xKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFdlIGNhbiBkbyB0aGlzIGNoZWFwbHkuLi4KKworICAgICAgICAvLyBVbmxpa2UgUGVybCwgd2hpY2ggY29uc2lkZXJzIHRoZSByZXN1bHQgb2Ygc3BsaXR0aW5nIHRoZSBlbXB0eSBzdHJpbmcgdG8gYmUgdGhlIGVtcHR5CisgICAgICAgIC8vIGFycmF5LCBKYXZhIHJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyB0aGUgZW1wdHkgc3RyaW5nLgorICAgICAgICBpZiAoaW5wdXQuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZ1tdIHsgIiIgfTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIENvbGxlY3QgdGV4dCBwcmVjZWRpbmcgZWFjaCBvY2N1cnJlbmNlIG9mIHRoZSBzZXBhcmF0b3IsIHdoaWxlIHRoZXJlJ3MgZW5vdWdoIHNwYWNlLgorICAgICAgICBBcnJheUxpc3Q8U3RyaW5nPiBsaXN0ID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGludCBtYXhTaXplID0gbGltaXQgPD0gMCA/IEludGVnZXIuTUFYX1ZBTFVFIDogbGltaXQ7CisgICAgICAgIGludCBiZWdpbiA9IDA7CisgICAgICAgIGludCBlbmQ7CisgICAgICAgIHdoaWxlICgoZW5kID0gaW5wdXQuaW5kZXhPZihjaCwgYmVnaW4pKSAhPSAtMSAmJiBsaXN0LnNpemUoKSArIDEgPCBtYXhTaXplKSB7CisgICAgICAgICAgICBsaXN0LmFkZChpbnB1dC5zdWJzdHJpbmcoYmVnaW4sIGVuZCkpOworICAgICAgICAgICAgYmVnaW4gPSBlbmQgKyAxOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmaW5pc2hTcGxpdChsaXN0LCBpbnB1dCwgYmVnaW4sIG1heFNpemUsIGxpbWl0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZ1tdIHNwbGl0KFBhdHRlcm4gcGF0dGVybiwgU3RyaW5nIHJlLCBTdHJpbmcgaW5wdXQsIGludCBsaW1pdCkgeworICAgICAgICBTdHJpbmdbXSBmYXN0UmVzdWx0ID0gZmFzdFNwbGl0KHJlLCBpbnB1dCwgbGltaXQpOworICAgICAgICBpZiAoZmFzdFJlc3VsdCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZmFzdFJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFVubGlrZSBQZXJsLCB3aGljaCBjb25zaWRlcnMgdGhlIHJlc3VsdCBvZiBzcGxpdHRpbmcgdGhlIGVtcHR5IHN0cmluZyB0byBiZSB0aGUgZW1wdHkKKyAgICAgICAgLy8gYXJyYXksIEphdmEgcmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIHRoZSBlbXB0eSBzdHJpbmcuCisgICAgICAgIGlmIChpbnB1dC5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nW10geyAiIiB9OworICAgICAgICB9CisKKyAgICAgICAgLy8gQ29sbGVjdCB0ZXh0IHByZWNlZGluZyBlYWNoIG9jY3VycmVuY2Ugb2YgdGhlIHNlcGFyYXRvciwgd2hpbGUgdGhlcmUncyBlbm91Z2ggc3BhY2UuCisgICAgICAgIEFycmF5TGlzdDxTdHJpbmc+IGxpc3QgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgaW50IG1heFNpemUgPSBsaW1pdCA8PSAwID8gSW50ZWdlci5NQVhfVkFMVUUgOiBsaW1pdDsKKyAgICAgICAgTWF0Y2hlciBtYXRjaGVyID0gbmV3IE1hdGNoZXIocGF0dGVybiwgaW5wdXQpOworICAgICAgICBpbnQgYmVnaW4gPSAwOworICAgICAgICB3aGlsZSAobWF0Y2hlci5maW5kKCkgJiYgbGlzdC5zaXplKCkgKyAxIDwgbWF4U2l6ZSkgeworICAgICAgICAgICAgbGlzdC5hZGQoaW5wdXQuc3Vic3RyaW5nKGJlZ2luLCBtYXRjaGVyLnN0YXJ0KCkpKTsKKyAgICAgICAgICAgIGJlZ2luID0gbWF0Y2hlci5lbmQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmluaXNoU3BsaXQobGlzdCwgaW5wdXQsIGJlZ2luLCBtYXhTaXplLCBsaW1pdCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gZmluaXNoU3BsaXQoTGlzdDxTdHJpbmc+IGxpc3QsIFN0cmluZyBpbnB1dCwgaW50IGJlZ2luLCBpbnQgbWF4U2l6ZSwgaW50IGxpbWl0KSB7CisgICAgICAgIC8vIEFkZCB0cmFpbGluZyB0ZXh0LgorICAgICAgICBpZiAoYmVnaW4gPCBpbnB1dC5sZW5ndGgoKSkgeworICAgICAgICAgICAgbGlzdC5hZGQoaW5wdXQuc3Vic3RyaW5nKGJlZ2luKSk7CisgICAgICAgIH0gZWxzZSBpZiAobGltaXQgIT0gMCkgeyAvLyBObyBwb2ludCBhZGRpbmcgdGhlIGVtcHR5IHN0cmluZyBpZiBsaW1pdCA9PSAwLCBqdXN0IHRvIHJlbW92ZSBpdCBiZWxvdy4KKyAgICAgICAgICAgIGxpc3QuYWRkKCIiKTsKKyAgICAgICAgfQorICAgICAgICAvLyBSZW1vdmUgYWxsIHRyYWlsaW5nIGVtcHR5IG1hdGNoZXMgaW4gdGhlIGxpbWl0ID09IDAgY2FzZS4KKyAgICAgICAgaWYgKGxpbWl0ID09IDApIHsKKyAgICAgICAgICAgIGludCBpID0gbGlzdC5zaXplKCkgLSAxOworICAgICAgICAgICAgd2hpbGUgKGkgPj0gMCAmJiBsaXN0LmdldChpKS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICBsaXN0LnJlbW92ZShpKTsKKyAgICAgICAgICAgICAgICBpLS07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gQ29udmVydCB0byBhbiBhcnJheS4KKyAgICAgICAgcmV0dXJuIGxpc3QudG9BcnJheShuZXcgU3RyaW5nW2xpc3Quc2l6ZSgpXSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9zcGkvQ3VycmVuY3lOYW1lUHJvdmlkZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvc3BpL0N1cnJlbmN5TmFtZVByb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDcxN2FhMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvc3BpL0N1cnJlbmN5TmFtZVByb3ZpZGVyLmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoNCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlDQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aA0KKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuDQorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wDQorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoDQorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQorICoNCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wDQorICoNCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLA0KKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4NCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4NCisgKi8NCisNCitwYWNrYWdlIGphdmEudXRpbC5zcGk7DQorDQoraW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7DQorDQorLyoqDQorICogVGhpcyBhYnN0cmFjdCBjbGFzcyBzaG91bGQgYmUgZXh0ZW5kZWQgYnkgc2VydmljZSBwcm92aWRlcnMgdGhhdCBwcm92aWRlDQorICogbG9jYWxpemVkIGN1cnJlbmN5IHN5bWJvbHMgKGN1cnJlbmN5IG5hbWVzKSBmcm9tIGN1cnJlbmN5IGNvZGVzLg0KKyAqIDxwPk5vdGUgdGhhdCBBbmRyb2lkIGRvZXMgbm90IHN1cHBvcnQgdXNlci1zdXBwbGllZCBsb2NhbGUgc2VydmljZSBwcm92aWRlcnMuDQorICogQHNpbmNlIDEuNg0KKyAqIEBoaWRlDQorICovDQorcHVibGljIGFic3RyYWN0IGNsYXNzIEN1cnJlbmN5TmFtZVByb3ZpZGVyIGV4dGVuZHMgTG9jYWxlU2VydmljZVByb3ZpZGVyIHsNCisgICAgLyoqDQorICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IsIGZvciB1c2UgYnkgc3ViY2xhc3Nlcy4NCisgICAgICovDQorICAgIHByb3RlY3RlZCBDdXJyZW5jeU5hbWVQcm92aWRlcigpIHsNCisgICAgICAgIC8vIGRvIG5vdGhpbmcNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogUmV0dXJucyB0aGUgbG9jYWxpemVkIGN1cnJlbmN5IHN5bWJvbCBmb3IgdGhlIGdpdmVuIGN1cnJlbmN5IGNvZGUuDQorICAgICAqDQorICAgICAqIEBwYXJhbSBjb2RlIGFuIElTTyA0MjE3IGN1cnJlbmN5IGNvZGUNCisgICAgICogQHBhcmFtIGxvY2FsZSBhIGxvY2FsZQ0KKyAgICAgKiBAcmV0dXJuIHRoZSBzeW1ib2wgb3IgbnVsbCBpZiB0aGVyZSBpcyBubyBhdmFpbGFibGUgc3ltYm9sIGluIHRoZSBsb2NhbGUNCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbg0KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY29kZSA9PSBudWxsIHx8IGxvY2FsZSA9PSBudWxsfQ0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbg0KKyAgICAgKiAgICAgICAgICAgICBpZiBjb2RlIG9yIGxvY2FsZSBpcyBub3QgaW4gYSBsZWdhbCBmb3JtYXQgb3Igbm90IGF2YWlsYWJsZQ0KKyAgICAgKi8NCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRTeW1ib2woU3RyaW5nIGNvZGUsIExvY2FsZSBsb2NhbGUpOw0KK30NCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3NwaS9Mb2NhbGVOYW1lUHJvdmlkZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvc3BpL0xvY2FsZU5hbWVQcm92aWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBkMjUwNzQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3NwaS9Mb2NhbGVOYW1lUHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDc1IEBACisvKg0KKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUNCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoDQorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4NCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjANCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgNCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQNCisgKg0KKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCisgKg0KKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlDQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsDQorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kDQorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLg0KKyAqLw0KKw0KK3BhY2thZ2UgamF2YS51dGlsLnNwaTsNCisNCitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsNCisNCisvKioNCisgKiBUaGlzIGFic3RyYWN0IGNsYXNzIHNob3VsZCBiZSBleHRlbmRlZCBieSBzZXJ2aWNlIHByb3ZpZGVycyB0aGF0IHByb3ZpZGUNCisgKiBsb2NhbGl6ZWQgbG9jYWxlIG5hbWVzLg0KKyAqIDxwPk5vdGUgdGhhdCBBbmRyb2lkIGRvZXMgbm90IHN1cHBvcnQgdXNlci1zdXBwbGllZCBsb2NhbGUgc2VydmljZSBwcm92aWRlcnMuDQorICogQHNpbmNlIDEuNg0KKyAqIEBoaWRlDQorICovDQorcHVibGljIGFic3RyYWN0IGNsYXNzIExvY2FsZU5hbWVQcm92aWRlciBleHRlbmRzIExvY2FsZVNlcnZpY2VQcm92aWRlciB7DQorICAgIC8qKg0KKyAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLCBmb3IgdXNlIGJ5IHN1YmNsYXNzZXMuDQorICAgICAqLw0KKyAgICBwcm90ZWN0ZWQgTG9jYWxlTmFtZVByb3ZpZGVyKCkgew0KKyAgICAgICAgLy8gZG8gbm90aGluZw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbGl6ZWQgbmFtZSBmb3IgdGhlIGdpdmVuIElTTyA2MzkgbGFuZ3VhZ2UgY29kZS4NCisgICAgICoNCisgICAgICogQHBhcmFtIGxhbmd1YWdlQ29kZSBhbiBJU08gNjM5IGxhbmd1YWdlIGNvZGUNCisgICAgICogQHBhcmFtIGxvY2FsZSBhIGxvY2FsZQ0KKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9yIG51bGwgaWYgdW5hdmFpbGFibGUNCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbg0KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY29kZSA9PSBudWxsIHx8IGxvY2FsZSA9PSBudWxsfQ0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbg0KKyAgICAgKiAgICAgICAgICAgICBpZiBjb2RlIG9yIGxvY2FsZSBpcyBub3QgaW4gYSBsZWdhbCBmb3JtYXQgb3Igbm90IGF2YWlsYWJsZQ0KKyAgICAgKi8NCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXREaXNwbGF5TGFuZ3VhZ2UoU3RyaW5nIGxhbmd1YWdlQ29kZSwgTG9jYWxlIGxvY2FsZSk7DQorDQorICAgIC8qKg0KKyAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbGl6ZWQgbmFtZSBmb3IgdGhlIGdpdmVuIElTTyAzMTY2IGNvdW50cnkgY29kZS4NCisgICAgICoNCisgICAgICogQHBhcmFtIGNvdW50cnlDb2RlIGFuIElTTyAzMTY2IGxhbmd1YWdlIGNvZGUNCisgICAgICogQHBhcmFtIGxvY2FsZSBhIGxvY2FsZQ0KKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9yIG51bGwgaWYgdW5hdmFpbGFibGUNCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbg0KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY29kZSA9PSBudWxsIHx8IGxvY2FsZSA9PSBudWxsfQ0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbg0KKyAgICAgKiAgICAgICAgICAgICBpZiBjb2RlIG9yIGxvY2FsZSBpcyBub3QgaW4gYSBsZWdhbCBmb3JtYXQgb3Igbm90IGF2YWlsYWJsZQ0KKyAgICAgKi8NCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXREaXNwbGF5Q291bnRyeShTdHJpbmcgY291bnRyeUNvZGUsIExvY2FsZSBsb2NhbGUpOw0KKw0KKyAgICAvKioNCisgICAgICogUmV0dXJucyB0aGUgbG9jYWxpemVkIG5hbWUgZm9yIHRoZSBnaXZlbiB2YXJpYW50IGNvZGUuDQorICAgICAqDQorICAgICAqIEBwYXJhbSB2YXJpYW50Q29kZSBhIHZhcmlhbnQgY29kZQ0KKyAgICAgKiBAcGFyYW0gbG9jYWxlIGEgbG9jYWxlDQorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb3IgbnVsbCBpZiB1bmF2YWlsYWJsZQ0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uDQorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBjb2RlID09IG51bGwgfHwgbG9jYWxlID09IG51bGx9DQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uDQorICAgICAqICAgICAgICAgICAgIGlmIGNvZGUgb3IgbG9jYWxlIGlzIG5vdCBpbiBhIGxlZ2FsIGZvcm1hdCBvciBub3QgYXZhaWxhYmxlDQorICAgICAqLw0KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldERpc3BsYXlWYXJpYW50KFN0cmluZyB2YXJpYW50Q29kZSwgTG9jYWxlIGxvY2FsZSk7DQorfQ0KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvc3BpL0xvY2FsZVNlcnZpY2VQcm92aWRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9zcGkvTG9jYWxlU2VydmljZVByb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjFiNjJkZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvc3BpL0xvY2FsZVNlcnZpY2VQcm92aWRlci5qYXZhCkBAIC0wLDAgKzEsNDAgQEAKKy8qDQorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQ0KKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgNCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLg0KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMA0KKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aA0KKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdA0KKyAqDQorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMA0KKyAqDQorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUNCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuDQorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQNCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQorICovDQorDQorcGFja2FnZSBqYXZhLnV0aWwuc3BpOw0KKw0KK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOw0KKw0KKy8qKg0KKyAqIFRoZSBiYXNlIGNsYXNzIGZvciBhbGwgdGhlIGxvY2FsZSByZWxhdGVkIHNlcnZpY2UgcHJvdmlkZXIgaW50ZXJmYWNlcyAoU1BJcykuDQorICogPHA+Tm90ZSB0aGF0IEFuZHJvaWQgZG9lcyBub3Qgc3VwcG9ydCB1c2VyLXN1cHBsaWVkIGxvY2FsZSBzZXJ2aWNlIHByb3ZpZGVycy4NCisgKiBAc2luY2UgMS42DQorICogQGhpZGUNCisgKi8NCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTG9jYWxlU2VydmljZVByb3ZpZGVyIHsNCisgICAgLyoqDQorICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IsIGZvciB1c2UgYnkgc3ViY2xhc3Nlcy4NCisgICAgICovDQorICAgIHByb3RlY3RlZCBMb2NhbGVTZXJ2aWNlUHJvdmlkZXIoKSB7DQorICAgICAgICAvLyBkbyBub3RoaW5nDQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIFJldHVybnMgYWxsIGxvY2FsZXMgZm9yIHdoaWNoIHRoaXMgbG9jYWxlIHNlcnZpY2UgcHJvdmlkZXIgaGFzIGxvY2FsaXplZCBvYmplY3RzIG9yIG5hbWVzLg0KKyAgICAgKi8NCisgICAgcHVibGljIGFic3RyYWN0IExvY2FsZVtdIGdldEF2YWlsYWJsZUxvY2FsZXMoKTsNCit9DQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC9zcGkvVGltZVpvbmVOYW1lUHJvdmlkZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvc3BpL1RpbWVab25lTmFtZVByb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTMzZDE0ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvc3BpL1RpbWVab25lTmFtZVByb3ZpZGVyLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyoNCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlDQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aA0KKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuDQorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wDQorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoDQorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQorICoNCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wDQorICoNCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLA0KKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4NCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4NCisgKi8NCisNCitwYWNrYWdlIGphdmEudXRpbC5zcGk7DQorDQoraW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7DQorDQorLyoqDQorICogVGhpcyBhYnN0cmFjdCBjbGFzcyBzaG91bGQgYmUgZXh0ZW5kZWQgYnkgc2VydmljZSBwcm92aWRlcnMgdGhhdCBwcm92aWRlDQorICogbG9jYWxpemVkIHRpbWUgem9uZSBuYW1lcy4NCisgKiA8cD5Ob3RlIHRoYXQgQW5kcm9pZCBkb2VzIG5vdCBzdXBwb3J0IHVzZXItc3VwcGxpZWQgbG9jYWxlIHNlcnZpY2UgcHJvdmlkZXJzLg0KKyAqIEBzaW5jZSAxLjYNCisgKiBAaGlkZQ0KKyAqLw0KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBUaW1lWm9uZU5hbWVQcm92aWRlciBleHRlbmRzIExvY2FsZVNlcnZpY2VQcm92aWRlciB7DQorICAgIC8qKg0KKyAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLCBmb3IgdXNlIGJ5IHN1YmNsYXNzZXMuDQorICAgICAqLw0KKyAgICBwcm90ZWN0ZWQgVGltZVpvbmVOYW1lUHJvdmlkZXIoKSB7DQorICAgICAgICAvLyBkbyBub3RoaW5nDQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIFJldHVybnMgdGhlIGxvY2FsaXplZCBuYW1lIGZvciB0aGUgZ2l2ZW4gdGltZSB6b25lIGluIHRoZSBnaXZlbiBsb2NhbGUuDQorICAgICAqDQorICAgICAqIEBwYXJhbSBpZCB0aGUgdGltZSB6b25lIGlkDQorICAgICAqIEBwYXJhbSBkYXlsaWdodCB0cnVlIHRvIHJldHVybiB0aGUgbmFtZSBmb3IgZGF5bGlnaHQgc2F2aW5nIHRpbWUuDQorICAgICAqIEBwYXJhbSBzdHlsZSBUaW1lWm9uZS5MT05HIG9yIFRpbWVab25lLlNIT1JUDQorICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZQ0KKyAgICAgKiBAcmV0dXJuIHRoZSByZWFkYWJsZSB0aW1lIHpvbmUgbmFtZSwgb3IgbnVsbCBpZiBpdCBpcyB1bmF2YWlsYWJsZQ0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uDQorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBpZCA9PSBudWxsIHx8IGxvY2FsZSA9PSBudWxsfQ0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbg0KKyAgICAgKiAgICAgICAgICAgICBpZiBsb2NhbGUgaXMgbm90IGF2YWlsYWJsZSBvciBzdHlsZSBpcyBpbnZhbGlkDQorICAgICAqLw0KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldERpc3BsYXlOYW1lKFN0cmluZyBpZCwgYm9vbGVhbiBkYXlsaWdodCwgaW50IHN0eWxlLCBMb2NhbGUgbG9jYWxlKTsNCit9DQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvQWRsZXIzMi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvQWRsZXIzMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFkZDE0ZGEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9BZGxlcjMyLmphdmEKQEAgLTAsMCArMSw4MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLnppcDsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogVGhlIEFkbGVyLTMyIGNsYXNzIGlzIHVzZWQgdG8gY29tcHV0ZSB0aGUge0Bjb2RlIEFkbGVyMzJ9IGNoZWNrc3VtIGZyb20gYSBzZXQKKyAqIG9mIGRhdGEuIENvbXBhcmVkIHRvIHtAbGluayBDUkMzMn0gaXQgdHJhZGVzIHJlbGlhYmlsaXR5IGZvciBzcGVlZC4KKyAqIFJlZmVyIHRvIFJGQyAxOTUwIGZvciB0aGUgc3BlY2lmaWNhdGlvbi4KKyAqLworcHVibGljIGNsYXNzIEFkbGVyMzIgaW1wbGVtZW50cyBDaGVja3N1bSB7CisKKyAgICBwcml2YXRlIGxvbmcgYWRsZXIgPSAxOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIEFkbGVyMzJ9IGNoZWNrc3VtIGZvciBhbGwgaW5wdXQgcmVjZWl2ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBjaGVja3N1bSBmb3IgdGhpcyBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIGFkbGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0IHRoaXMgaW5zdGFuY2UgdG8gaXRzIGluaXRpYWwgY2hlY2tzdW0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB7CisgICAgICAgIGFkbGVyID0gMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGUgdGhpcyB7QGNvZGUgQWRsZXIzMn0gY2hlY2tzdW0gd2l0aCB0aGUgc2luZ2xlIGJ5dGUgcHJvdmlkZWQgYXMKKyAgICAgKiBhcmd1bWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSB0byB1cGRhdGUgY2hlY2tzdW0gd2l0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGUoaW50IGkpIHsKKyAgICAgICAgYWRsZXIgPSB1cGRhdGVCeXRlSW1wbChpLCBhZGxlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlIHRoaXMge0Bjb2RlIEFkbGVyMzJ9IGNoZWNrc3VtIHVzaW5nIHRoZSBjb250ZW50cyBvZiB7QGNvZGUgYnVmfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWYKKyAgICAgKiAgICAgICAgICAgIGJ5dGVzIHRvIHVwZGF0ZSBjaGVja3N1bSB3aXRoLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZShieXRlW10gYnVmKSB7CisgICAgICAgIHVwZGF0ZShidWYsIDAsIGJ1Zi5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZSB0aGlzIHtAY29kZSBBZGxlcjMyfSBjaGVja3N1bSB3aXRoIHRoZSBjb250ZW50cyBvZiB7QGNvZGUgYnVmfSwKKyAgICAgKiBzdGFydGluZyBmcm9tIHtAY29kZSBvZmZzZXR9IGFuZCByZWFkaW5nIHtAY29kZSBieXRlQ291bnR9IGJ5dGVzIG9mIGRhdGEuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlKGJ5dGVbXSBidWYsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmLmxlbmd0aCwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICBhZGxlciA9IHVwZGF0ZUltcGwoYnVmLCBvZmZzZXQsIGJ5dGVDb3VudCwgYWRsZXIpOworICAgIH0KKworICAgIHByaXZhdGUgbmF0aXZlIGxvbmcgdXBkYXRlSW1wbChieXRlW10gYnVmLCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50LCBsb25nIGFkbGVyMSk7CisKKyAgICBwcml2YXRlIG5hdGl2ZSBsb25nIHVwZGF0ZUJ5dGVJbXBsKGludCB2YWwsIGxvbmcgYWRsZXIxKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL0NSQzMyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9DUkMzMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVkMGRiZDQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9DUkMzMi5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC56aXA7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIFRoZSBDUkMzMiBjbGFzcyBpcyB1c2VkIHRvIGNvbXB1dGUgYSBDUkMzMiBjaGVja3N1bSBmcm9tIGRhdGEgcHJvdmlkZWQgYXMKKyAqIGlucHV0IHZhbHVlLiBTZWUgYWxzbyB7QGxpbmsgQWRsZXIzMn0gd2hpY2ggaXMgYWxtb3N0IGFzIGdvb2QsIGJ1dCBjaGVhcGVyLgorICovCitwdWJsaWMgY2xhc3MgQ1JDMzIgaW1wbGVtZW50cyBDaGVja3N1bSB7CisKKyAgICBwcml2YXRlIGxvbmcgY3JjID0gMEw7CisKKyAgICBsb25nIHRieXRlcyA9IDBMOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgQ1JDMzIgY2hlY2tzdW0gZm9yIGFsbCBpbnB1dCByZWNlaXZlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIGNoZWNrc3VtIGZvciB0aGlzIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFZhbHVlKCkgeworICAgICAgICByZXR1cm4gY3JjOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0cyB0aGUgQ1JDMzIgY2hlY2tzdW0gdG8gaXQgaW5pdGlhbCBzdGF0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKKyAgICAgICAgdGJ5dGVzID0gY3JjID0gMDsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhpcyBjaGVja3N1bSB3aXRoIHRoZSBieXRlIHZhbHVlIHByb3ZpZGVkIGFzIGludGVnZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsCisgICAgICogICAgICAgICAgICByZXByZXNlbnRzIHRoZSBieXRlIHRvIHVwZGF0ZSB0aGUgY2hlY2tzdW0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlKGludCB2YWwpIHsKKyAgICAgICAgY3JjID0gdXBkYXRlQnl0ZUltcGwoKGJ5dGUpIHZhbCwgY3JjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoaXMgY2hlY2tzdW0gd2l0aCB0aGUgYnl0ZXMgY29udGFpbmVkIGluIGJ1ZmZlciB7QGNvZGUgYnVmfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWYKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXIgaG9sZGluZyB0aGUgZGF0YSB0byB1cGRhdGUgdGhlIGNoZWNrc3VtIHdpdGguCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlKGJ5dGVbXSBidWYpIHsKKyAgICAgICAgdXBkYXRlKGJ1ZiwgMCwgYnVmLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlIHRoaXMge0Bjb2RlIENSQzMyfSBjaGVja3N1bSB3aXRoIHRoZSBjb250ZW50cyBvZiB7QGNvZGUgYnVmfSwKKyAgICAgKiBzdGFydGluZyBmcm9tIHtAY29kZSBvZmZzZXR9IGFuZCByZWFkaW5nIHtAY29kZSBieXRlQ291bnR9IGJ5dGVzIG9mIGRhdGEuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlKGJ5dGVbXSBidWYsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQpIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmLmxlbmd0aCwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICB0Ynl0ZXMgKz0gYnl0ZUNvdW50OworICAgICAgICBjcmMgPSB1cGRhdGVJbXBsKGJ1Ziwgb2Zmc2V0LCBieXRlQ291bnQsIGNyYyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBuYXRpdmUgbG9uZyB1cGRhdGVJbXBsKGJ5dGVbXSBidWYsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQsIGxvbmcgY3JjMSk7CisKKyAgICBwcml2YXRlIG5hdGl2ZSBsb25nIHVwZGF0ZUJ5dGVJbXBsKGJ5dGUgdmFsLCBsb25nIGNyYzEpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvQ2hlY2tlZElucHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9DaGVja2VkSW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NTQwOThiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvQ2hlY2tlZElucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxMTcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC56aXA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworCisvKioKKyAqIFRoZSB7QGNvZGUgQ2hlY2tlZElucHV0U3RyZWFtfSBjbGFzcyBpcyB1c2VkIHRvIG1haW50YWluIGEgY2hlY2tzdW0gYXQgdGhlCisgKiBzYW1lIHRpbWUgYXMgdGhlIGRhdGEsIG9uIHdoaWNoIHRoZSBjaGVja3N1bSBpcyBjb21wdXRlZCwgaXMgcmVhZCBmcm9tIGEKKyAqIHN0cmVhbS4gVGhlIHB1cnBvc2Ugb2YgdGhpcyBjaGVja3N1bSBpcyB0byBlc3RhYmxpc2ggZGF0YSBpbnRlZ3JpdHksCisgKiBjb21wYXJpbmcgdGhlIGNvbXB1dGVkIGNoZWNrc3VtIGFnYWluc3QgYSBwdWJsaXNoZWQgY2hlY2tzdW0gdmFsdWUuCisgKi8KK3B1YmxpYyBjbGFzcyBDaGVja2VkSW5wdXRTdHJlYW0gZXh0ZW5kcyBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtIHsKKworICAgIHByaXZhdGUgZmluYWwgQ2hlY2tzdW0gY2hlY2s7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBDaGVja2VkSW5wdXRTdHJlYW19IG9uIHtAY29kZSBJbnB1dFN0cmVhbX0KKyAgICAgKiB7QGNvZGUgaXN9LiBUaGUgY2hlY2tzdW0gd2lsbCBiZSBjYWxjdWxhdGVkIHVzaW5nIHRoZSBhbGdvcml0aG0KKyAgICAgKiBpbXBsZW1lbnRlZCBieSB7QGNvZGUgY3N1bX0uCisgICAgICoKKyAgICAgKiA8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IHBhc3NpbmcgYSBudWxsIHNvdXJjZSBjcmVhdGVzIGFuIGludmFsaWQKKyAgICAgKiB7QGNvZGUgQ2hlY2tlZElucHV0U3RyZWFtfS4gQWxsIG9wZXJhdGlvbnMgb24gc3VjaCBhIHN0cmVhbSB3aWxsIGZhaWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBzdHJlYW0gdG8gY2FsY3VsYXRlIGNoZWNrc3VtIGZyb20uCisgICAgICogQHBhcmFtIGNzdW0KKyAgICAgKiAgICAgICAgICAgIGFuIGVudGl0eSBpbXBsZW1lbnRpbmcgdGhlIGNoZWNrc3VtIGFsZ29yaXRobS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2hlY2tlZElucHV0U3RyZWFtKElucHV0U3RyZWFtIGlzLCBDaGVja3N1bSBjc3VtKSB7CisgICAgICAgIHN1cGVyKGlzKTsKKyAgICAgICAgY2hlY2sgPSBjc3VtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIG9uZSBieXRlIG9mIGRhdGEgZnJvbSB0aGUgdW5kZXJseWluZyBpbnB1dCBzdHJlYW0gYW5kIHVwZGF0ZXMgdGhlCisgICAgICogY2hlY2tzdW0gd2l0aCB0aGUgYnl0ZSBkYXRhLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgLTF9IGF0IHRoZSBlbmQgb2YgdGhlIHN0cmVhbSwgYSBzaW5nbGUgYnl0ZSB2YWx1ZQorICAgICAqICAgICAgICAgb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiB7QGNvZGUgSU9FeGNlcHRpb259IG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgeCA9IGluLnJlYWQoKTsKKyAgICAgICAgaWYgKHggIT0gLTEpIHsKKyAgICAgICAgICAgIGNoZWNrLnVwZGF0ZSh4KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4geDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB1cCB0byBuIGJ5dGVzIG9mIGRhdGEgZnJvbSB0aGUgdW5kZXJseWluZyBpbnB1dCBzdHJlYW0sIHN0b3JpbmcgaXQKKyAgICAgKiBpbnRvIHtAY29kZSBidWZ9LCBzdGFydGluZyBhdCBvZmZzZXQge0Bjb2RlIG9mZn0uIFRoZSBjaGVja3N1bSBpcworICAgICAqIHVwZGF0ZWQgd2l0aCB0aGUgYnl0ZXMgcmVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWYKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIGFycmF5IGluIHdoaWNoIHRvIHN0b3JlIHRoZSBieXRlcyByZWFkLgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIHBvc2l0aW9uIGluIHtAY29kZSBidWZ9IHRvIHN0b3JlIHRoZSBieXRlcyByZWFkCisgICAgICogICAgICAgICAgICBmcm9tIHRoaXMgc3RyZWFtLgorICAgICAqIEBwYXJhbSBuYnl0ZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0byBzdG9yZSBpbiB7QGNvZGUgYnVmfS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgcmVhZCBvciB7QGNvZGUgLTF9IGlmIGFycml2ZWQgYXQgdGhlCisgICAgICogICAgICAgICBlbmQgb2YgdGhlIGZpbHRlcmVkIHN0cmVhbSB3aGlsZSByZWFkaW5nIHRoZSBkYXRhLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHN0cmVhbSBpcyBjbG9zZWQgb3Igc29tZSBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmLCBpbnQgb2ZmLCBpbnQgbmJ5dGVzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgeCA9IGluLnJlYWQoYnVmLCBvZmYsIG5ieXRlcyk7CisgICAgICAgIGlmICh4ICE9IC0xKSB7CisgICAgICAgICAgICBjaGVjay51cGRhdGUoYnVmLCBvZmYsIHgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB4OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNoZWNrc3VtIGNhbGN1bGF0ZWQgb24gdGhlIHN0cmVhbSByZWFkIHNvIGZhci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHVwZGF0ZWQgY2hlY2tzdW0uCisgICAgICovCisgICAgcHVibGljIENoZWNrc3VtIGdldENoZWNrc3VtKCkgeworICAgICAgICByZXR1cm4gY2hlY2s7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcCB1cCB0byB7QGNvZGUgYnl0ZUNvdW50fSBieXRlcyBvZiBkYXRhIG9uIHRoZSB1bmRlcmx5aW5nIGlucHV0CisgICAgICogc3RyZWFtLiBBbnkgc2tpcHBlZCBieXRlcyBhcmUgYWRkZWQgdG8gdGhlIHJ1bm5pbmcgY2hlY2tzdW0gdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnl0ZUNvdW50IHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gc2tpcC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoaXMgc3RyZWFtIGlzIGNsb3NlZCBvciBhbm90aGVyIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHNraXBwZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgc2tpcChsb25nIGJ5dGVDb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIFN0cmVhbXMuc2tpcEJ5UmVhZGluZyh0aGlzLCBieXRlQ291bnQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL0NoZWNrZWRPdXRwdXRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL0NoZWNrZWRPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYzE5NzI2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvQ2hlY2tlZE91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC56aXA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCisvKioKKyAqIFRoZSB7QGNvZGUgQ2hlY2tlZE91dHB1dFN0cmVhbX0gY2xhc3MgaXMgdXNlZCB0byBtYWludGFpbiBhIHJ1bm5pbmcgY2hlY2tzdW0KKyAqIG9mIGFsbCBkYXRhIHdyaXR0ZW4gdG8gYSBzdHJlYW0uIFRoZSBwdXJwb3NlIG9mIHRoaXMgY2hlY2tzdW0gaXMgdG8gZXN0YWJsaXNoCisgKiBkYXRhIGludGVncml0eSwgYnkgcHVibGlzaGluZyB0aGUgY2hlY2tzdW0gdG8gb3RoZXIgcGFydGllcyB3YW50aW5nIHRvIHJlYWQKKyAqIHRoZSBub24gY29ycnVwdGVkIGRhdGEuCisgKi8KK3B1YmxpYyBjbGFzcyBDaGVja2VkT3V0cHV0U3RyZWFtIGV4dGVuZHMgamF2YS5pby5GaWx0ZXJPdXRwdXRTdHJlYW0geworCisgICAgcHJpdmF0ZSBmaW5hbCBDaGVja3N1bSBjaGVjazsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIENoZWNrZWRPdXRwdXRTdHJlYW19IG9uIHtAY29kZSBPdXRwdXRTdHJlYW19CisgICAgICoge0Bjb2RlIG9zfS4gVGhlIGNoZWNrc3VtIGlzIGNhbGN1bGF0ZWQgdXNpbmcgdGhlIGFsZ29yaXRobSBpbXBsZW1lbnRlZAorICAgICAqIGJ5IHtAY29kZSBjc3VtfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcworICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBzdHJlYW0gdG8gY2FsY3VsYXRlIGNoZWNrc3VtIGZvci4KKyAgICAgKiBAcGFyYW0gY3MKKyAgICAgKiAgICAgICAgICAgIGFuIGVudGl0eSBpbXBsZW1lbnRpbmcgdGhlIGNoZWNrc3VtIGFsZ29yaXRobS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2hlY2tlZE91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3MsIENoZWNrc3VtIGNzKSB7CisgICAgICAgIHN1cGVyKG9zKTsKKyAgICAgICAgY2hlY2sgPSBjczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjaGVja3N1bSBjYWxjdWxhdGVkIG9uIHRoZSBzdHJlYW0gcmVhZCBzbyBmYXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB1cGRhdGVkIGNoZWNrc3VtLgorICAgICAqLworICAgIHB1YmxpYyBDaGVja3N1bSBnZXRDaGVja3N1bSgpIHsKKyAgICAgICAgcmV0dXJuIGNoZWNrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3BlY2lmaWVkIGJ5dGUgdG8gdGhlIHVuZGVybHlpbmcgc3RyZWFtLiBUaGUgY2hlY2tzdW0gaXMKKyAgICAgKiB1cGRhdGVkIHdpdGgge0Bjb2RlIHZhbH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsCisgICAgICogICAgICAgICAgICB0aGUgZGF0YSB2YWx1ZSB0byB3cml0dGVuIHRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJTyBlcnJvciBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IHZhbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LndyaXRlKHZhbCk7CisgICAgICAgIGNoZWNrLnVwZGF0ZSh2YWwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBuIGJ5dGVzIG9mIGRhdGEgZnJvbSB7QGNvZGUgYnVmfSBzdGFydGluZyBhdCBvZmZzZXQge0Bjb2RlIG9mZn0gdG8KKyAgICAgKiB0aGUgdW5kZXJseWluZyBzdHJlYW0uIFRoZSBjaGVja3N1bSBpcyB1cGRhdGVkIHdpdGggdGhlIGJ5dGVzIHdyaXR0ZW4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmCisgICAgICogICAgICAgICAgICBkYXRhIHdyaXR0ZW4gdG8gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICogQHBhcmFtIG9mZgorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCB0byBzdGFydCByZWFkaW5nIHRoZSBkYXRhIGZyb20ge0Bjb2RlIGJ1Zn0gd3JpdHRlbgorICAgICAqICAgICAgICAgICAgdG8gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICogQHBhcmFtIG5ieXRlcworICAgICAqICAgICAgICAgICAgbnVtYmVyIG9mIGJ5dGVzIHRvIHdyaXRlIHRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJTyBlcnJvciBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGJ1ZiwgaW50IG9mZiwgaW50IG5ieXRlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LndyaXRlKGJ1Ziwgb2ZmLCBuYnl0ZXMpOworICAgICAgICBjaGVjay51cGRhdGUoYnVmLCBvZmYsIG5ieXRlcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvQ2hlY2tzdW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL0NoZWNrc3VtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODI0Yjg1YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL0NoZWNrc3VtLmphdmEKQEAgLTAsMCArMSw1NyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLnppcDsKKworLyoqCisgKiBUaGUgaW50ZXJmYWNlIGNvbW1vbiB0byBjaGVja3N1bSBjbGFzc2VzIHN1Y2ggYXMge0BsaW5rIEFkbGVyMzJ9IGFuZCB7QGxpbmsgQ1JDMzJ9LgorICovCitwdWJsaWMgaW50ZXJmYWNlIENoZWNrc3VtIHsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgY2FsY3VsYXRlZCBjaGVja3N1bSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNoZWNrc3VtLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFZhbHVlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhlIGNoZWNrc3VtIHZhbHVlIGFwcGxpZWQgYmVmb3JlIGJlZ2lubmluZyBjYWxjdWxhdGlvbnMgb24gYSBuZXcKKyAgICAgKiBzdHJlYW0gb2YgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZXNldCgpOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgY2hlY2tzdW0gd2l0aCB0aGUgZ2l2ZW4gYnl0ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYnVmCisgICAgICogICAgICAgICAgICB0aGUgYnl0ZSBhcnJheSBmcm9tIHdoaWNoIHRvIHJlYWQgdGhlIGJ5dGVzLgorICAgICAqIEBwYXJhbSBvZmYKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIHBvc2l0aW9uIGluIHtAY29kZSBidWZ9IHRvIHJlYWQgdGhlIGJ5dGVzIGZyb20uCisgICAgICogQHBhcmFtIG5ieXRlcworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyB0byByZWFkIGZyb20ge0Bjb2RlIGJ1Zn0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlKGJ5dGVbXSBidWYsIGludCBvZmYsIGludCBuYnl0ZXMpOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgY2hlY2tzdW0gdmFsdWUgd2l0aCB0aGUgZ2l2ZW4gYnl0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBieXRlIHRvIHVwZGF0ZSB0aGUgY2hlY2tzdW0gd2l0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGUoaW50IHZhbCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9EYXRhRm9ybWF0RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9EYXRhRm9ybWF0RXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODExYzRjNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL0RhdGFGb3JtYXRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQ0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuemlwOworCisvKioKKyAqIHtAY29kZSBEYXRhRm9ybWF0RXhjZXB0aW9ufSBpcyB1c2VkIHRvIGluZGljYXRlIGFuIGVycm9yIGluIHRoZSBmb3JtYXQgb2YgYQorICogcGFydGljdWxhciBkYXRhIHN0cmVhbSB3aGljaCBpcyB0byBiZSB1bmNvbXByZXNzZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBEYXRhRm9ybWF0RXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDIyMTk2MzI4NzA4OTM2NDE0NTJMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRGF0YUZvcm1hdEV4Y2VwdGlvbn0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIERhdGFGb3JtYXRFeGNlcHRpb24oKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRGF0YUZvcm1hdEV4Y2VwdGlvbn0gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIERhdGFGb3JtYXRFeGNlcHRpb24oU3RyaW5nIGRldGFpbE1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIoZGV0YWlsTWVzc2FnZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvRGVmbGF0ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL0RlZmxhdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDQ0Yjk3NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL0RlZmxhdGVyLmphdmEKQEAgLTAsMCArMSw0NzkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC56aXA7CisKK2ltcG9ydCBkYWx2aWsuc3lzdGVtLkNsb3NlR3VhcmQ7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuRW1wdHlBcnJheTsKKworLyoqCisgKiBUaGlzIGNsYXNzIGNvbXByZXNzZXMgZGF0YSB1c2luZyB0aGUgPGk+REVGTEFURTwvaT4gYWxnb3JpdGhtIChzZWUgPGEKKyAqIGhyZWY9Imh0dHA6Ly93d3cuZ3ppcC5vcmcvYWxnb3JpdGhtLnR4dCI+c3BlY2lmaWNhdGlvbjwvYT4pLgorICoKKyAqIDxwPkl0IGlzIHVzdWFsbHkgbW9yZSBjb252ZW5pZW50IHRvIHVzZSB7QGxpbmsgRGVmbGF0ZXJPdXRwdXRTdHJlYW19LgorICoKKyAqIDxwPlRvIGNvbXByZXNzIGFuIGluLW1lbW9yeSB7QGNvZGUgYnl0ZVtdfSB0byBhbm90aGVyIGluLW1lbW9yeSB7QGNvZGUgYnl0ZVtdfSBtYW51YWxseToKKyAqIDxwcmU+CisgKiAgICAgYnl0ZVtdIG9yaWdpbmFsQnl0ZXMgPSAuLi4KKyAqCisgKiAgICAgRGVmbGF0ZXIgZGVmbGF0ZXIgPSBuZXcgRGVmbGF0ZXIoKTsKKyAqICAgICBkZWZsYXRlci5zZXRJbnB1dChvcmlnaW5hbEJ5dGVzKTsKKyAqICAgICBkZWZsYXRlci5maW5pc2goKTsKKyAqCisgKiAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgKiAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzgxOTJdOworICogICAgIHdoaWxlICghZGVmbGF0ZXIuZmluaXNoZWQoKSkgeworICogICAgICAgICBpbnQgYnl0ZUNvdW50ID0gZGVmbGF0ZXIuZGVmbGF0ZShidWYpOworICogICAgICAgICBiYW9zLndyaXRlKGJ1ZiwgMCwgYnl0ZUNvdW50KTsKKyAqICAgICB9CisgKiAgICAgZGVmbGF0ZXIuZW5kKCk7CisgKgorICogICAgIGJ5dGVbXSBjb21wcmVzc2VkQnl0ZXMgPSBiYW9zLnRvQnl0ZUFycmF5KCk7CisgKiA8L3ByZT4KKyAqIDxwPkluIHNpdHVhdGlvbnMgd2hlcmUgeW91IGRvbid0IGhhdmUgYWxsIHRoZSBpbnB1dCBpbiBvbmUgYXJyYXkgKG9yIGhhdmUgc28gbXVjaAorICogaW5wdXQgdGhhdCB5b3Ugd2FudCB0byBmZWVkIGl0IHRvIHRoZSBkZWZsYXRlciBpbiBjaHVua3MpLCBpdCdzIHBvc3NpYmxlIHRvIGNhbGwKKyAqIHtAbGluayAjc2V0SW5wdXQgc2V0SW5wdXR9IHJlcGVhdGVkbHksIGJ1dCB5b3UncmUgbXVjaCBiZXR0ZXIgb2ZmIHVzaW5nCisgKiB7QGxpbmsgRGVmbGF0ZXJPdXRwdXRTdHJlYW19IHRvIGhhbmRsZSBhbGwgdGhpcyBmb3IgeW91LiB7QGxpbmsgRGVmbGF0ZXJPdXRwdXRTdHJlYW19IGFsc28gaGVscHMKKyAqIG1pbmltaXplIG1lbW9yeSByZXF1aXJlbWVudHMmbmJzcDsmbWRhc2g7IHRoZSBzYW1wbGUgY29kZSBhYm92ZSBpcyB2ZXJ5IGV4cGVuc2l2ZS4KKyAqLworcHVibGljIGNsYXNzIERlZmxhdGVyIHsKKworICAgIC8qKgorICAgICAqIFVwcGVyIGJvdW5kIGZvciB0aGUgY29tcHJlc3Npb24gbGV2ZWwgcmFuZ2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkVTVF9DT01QUkVTU0lPTiA9IDk7CisKKyAgICAvKioKKyAgICAgKiBMb3dlciBib3VuZCBmb3IgY29tcHJlc3Npb24gbGV2ZWwgcmFuZ2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkVTVF9TUEVFRCA9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGVmYXVsdCBjb21wcmVzc2lvbiBsZXZlbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0NPTVBSRVNTSU9OID0gLTE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGVmYXVsdCBjb21wcmVzc2lvbiBzdHJhdGVneS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1NUUkFURUdZID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBkZWZhdWx0IGNvbXByZXNzaW9uIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZMQVRFRCA9IDg7CisKKyAgICAvKioKKyAgICAgKiBBIGNvbXByZXNzaW9uIHN0cmF0ZWd5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJTFRFUkVEID0gMTsKKworICAgIC8qKgorICAgICAqIEEgY29tcHJlc3Npb24gc3RyYXRlZ3kuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFVGRk1BTl9PTkxZID0gMjsKKworICAgIC8qKgorICAgICAqIEEgY29tcHJlc3Npb24gbGV2ZWwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9fQ09NUFJFU1NJT04gPSAwOworCisgICAgLyoqCisgICAgICogVXNlIGJ1ZmZlcmluZyBmb3IgYmVzdCBjb21wcmVzc2lvbi4KKyAgICAgKgorICAgICAqIEBoaWRlCisgICAgICogQHNpbmNlIDEuNworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5PX0ZMVVNIID0gMDsKKworICAgIC8qKgorICAgICAqIEZsdXNoIGJ1ZmZlcnMgc28gcmVjaXBpZW50cyBjYW4gaW1tZWRpYXRlbHkgZGVjb2RlIHRoZSBkYXRhIHNlbnQgdGh1cworICAgICAqIGZhci4gVGhpcyBtb2RlIG1heSBkZWdyYWRlIGNvbXByZXNzaW9uLgorICAgICAqCisgICAgICogQGhpZGUKKyAgICAgKiBAc2luY2UgMS43CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1lOQ19GTFVTSCA9IDI7CisKKyAgICAvKioKKyAgICAgKiBGbHVzaCBidWZmZXJzIHNvIHJlY2lwaWVudHMgY2FuIGltbWVkaWF0ZWx5IGRlY29kZSB0aGUgZGF0YSBzZW50IHRodXMKKyAgICAgKiBmYXIuIFRoZSBjb21wcmVzc2lvbiBzdGF0ZSBpcyBhbHNvIHJlc2V0IHRvIHBlcm1pdCByYW5kb20gYWNjZXNzIGFuZAorICAgICAqIHJlY292ZXJ5IGZvciBjbGllbnRzIHdobyBoYXZlIGRpc2NhcmRlZCBvciBkYW1hZ2VkIHRoZWlyIG93biBjb3B5LiBUaGlzCisgICAgICogbW9kZSBtYXkgZGVncmFkZSBjb21wcmVzc2lvbi4KKyAgICAgKgorICAgICAqIEBoaWRlCisgICAgICogQHNpbmNlIDEuNworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTExfRkxVU0ggPSAzOworCisgICAgLyoqCisgICAgICogRmx1c2ggYnVmZmVycyBhbmQgbWFyayB0aGUgZW5kIG9mIHRoZSBkYXRhIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRklOSVNIID0gNDsKKworICAgIC8qKgorICAgICAqIFRoZSB1Z2x5IG5hbWUgZmx1c2hQYXJtIGlzIGZvciBSSSBjb21wYXRpYmlsaXR5LCBzaG91bGQgY29kZSBuZWVkIHRvIGFjY2VzcyB0aGlzCisgICAgICogZmllbGQgdmlhIHJlZmxlY3Rpb24gaWYgaXQncyBub3QgYWJsZSB0byB1c2UgcHVibGljIEFQSSB0byBjaG9vc2Ugd2hhdAorICAgICAqIGtpbmQgb2YgZmx1c2hpbmcgaXQgZ2V0cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBmbHVzaFBhcm0gPSBOT19GTFVTSDsKKworICAgIHByaXZhdGUgYm9vbGVhbiBmaW5pc2hlZDsKKworICAgIHByaXZhdGUgaW50IGNvbXByZXNzTGV2ZWwgPSBERUZBVUxUX0NPTVBSRVNTSU9OOworCisgICAgcHJpdmF0ZSBpbnQgc3RyYXRlZ3kgPSBERUZBVUxUX1NUUkFURUdZOworCisgICAgcHJpdmF0ZSBsb25nIHN0cmVhbUhhbmRsZSA9IC0xOworCisgICAgcHJpdmF0ZSBieXRlW10gaW5wdXRCdWZmZXI7CisKKyAgICBwcml2YXRlIGludCBpblJlYWQ7CisKKyAgICBwcml2YXRlIGludCBpbkxlbmd0aDsKKworICAgIHByaXZhdGUgZmluYWwgQ2xvc2VHdWFyZCBndWFyZCA9IENsb3NlR3VhcmQuZ2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBEZWZsYXRlcn0gaW5zdGFuY2UgdXNpbmcgdGhlIGRlZmF1bHQgY29tcHJlc3Npb24KKyAgICAgKiBsZXZlbC4gVGhlIHN0cmF0ZWd5IGNhbiBiZSBzcGVjaWZpZWQgd2l0aCB7QGxpbmsgI3NldFN0cmF0ZWd5fS4gQQorICAgICAqIGhlYWRlciBpcyBhZGRlZCB0byB0aGUgb3V0cHV0IGJ5IGRlZmF1bHQ7IHVzZSB7QGxpbmsKKyAgICAgKiAjRGVmbGF0ZXIoaW50LCBib29sZWFuKX0gaWYgeW91IG5lZWQgdG8gb21pdCB0aGUgaGVhZGVyLgorICAgICAqLworICAgIHB1YmxpYyBEZWZsYXRlcigpIHsKKyAgICAgICAgdGhpcyhERUZBVUxUX0NPTVBSRVNTSU9OLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgRGVmbGF0ZXJ9IGluc3RhbmNlIHVzaW5nIGNvbXByZXNzaW9uCisgICAgICogbGV2ZWwge0Bjb2RlIGxldmVsfS4gVGhlIHN0cmF0ZWd5IGNhbiBiZSBzcGVjaWZpZWQgd2l0aCB7QGxpbmsgI3NldFN0cmF0ZWd5fS4KKyAgICAgKiBBIGhlYWRlciBpcyBhZGRlZCB0byB0aGUgb3V0cHV0IGJ5IGRlZmF1bHQ7IHVzZQorICAgICAqIHtAbGluayAjRGVmbGF0ZXIoaW50LCBib29sZWFuKX0gaWYgeW91IG5lZWQgdG8gb21pdCB0aGUgaGVhZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGxldmVsCisgICAgICogICAgICAgICAgICB0aGUgY29tcHJlc3Npb24gbGV2ZWwgaW4gdGhlIHJhbmdlIGJldHdlZW4gMCBhbmQgOS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGVmbGF0ZXIoaW50IGxldmVsKSB7CisgICAgICAgIHRoaXMobGV2ZWwsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBEZWZsYXRlcn0gaW5zdGFuY2Ugd2l0aCBhIHNwZWNpZmljIGNvbXByZXNzaW9uCisgICAgICogbGV2ZWwuIElmIHtAY29kZSBub0hlYWRlcn0gaXMgdHJ1ZSwgbm8gWkxJQiBoZWFkZXIgaXMgYWRkZWQgdG8gdGhlCisgICAgICogb3V0cHV0LiBJbiBhIFpJUCBhcmNoaXZlIGV2ZXJ5IGVudHJ5IChjb21wcmVzc2VkIGZpbGUpIGNvbWVzIHdpdGggc3VjaCBhCisgICAgICogaGVhZGVyLiBUaGUgc3RyYXRlZ3kgY2FuIGJlIHNwZWNpZmllZCB1c2luZyB7QGxpbmsgI3NldFN0cmF0ZWd5fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsZXZlbAorICAgICAqICAgICAgICAgICAgdGhlIGNvbXByZXNzaW9uIGxldmVsIGluIHRoZSByYW5nZSBiZXR3ZWVuIDAgYW5kIDkuCisgICAgICogQHBhcmFtIG5vSGVhZGVyCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gaW5kaWNhdGVzIHRoYXQgbm8gWkxJQiBoZWFkZXIgc2hvdWxkIGJlIHdyaXR0ZW4uCisgICAgICovCisgICAgcHVibGljIERlZmxhdGVyKGludCBsZXZlbCwgYm9vbGVhbiBub0hlYWRlcikgeworICAgICAgICBpZiAobGV2ZWwgPCBERUZBVUxUX0NPTVBSRVNTSU9OIHx8IGxldmVsID4gQkVTVF9DT01QUkVTU0lPTikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGNvbXByZXNzTGV2ZWwgPSBsZXZlbDsKKyAgICAgICAgc3RyZWFtSGFuZGxlID0gY3JlYXRlU3RyZWFtKGNvbXByZXNzTGV2ZWwsIHN0cmF0ZWd5LCBub0hlYWRlcik7CisgICAgICAgIGd1YXJkLm9wZW4oImVuZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlZmxhdGVzIHRoZSBkYXRhIChwcmV2aW91c2x5IHBhc3NlZCB0byB7QGxpbmsgI3NldElucHV0IHNldElucHV0fSkgaW50byB0aGUKKyAgICAgKiBzdXBwbGllZCBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIG51bWJlciBvZiBieXRlcyBvZiBjb21wcmVzc2VkIGRhdGEgd3JpdHRlbiB0byB7QGNvZGUgYnVmfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGRlZmxhdGUoYnl0ZVtdIGJ1ZikgeworICAgICAgICByZXR1cm4gZGVmbGF0ZShidWYsIDAsIGJ1Zi5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlZmxhdGVzIGRhdGEgKHByZXZpb3VzbHkgcGFzc2VkIHRvIHtAbGluayAjc2V0SW5wdXQgc2V0SW5wdXR9KSBpbnRvIGEgc3BlY2lmaWMKKyAgICAgKiByZWdpb24gd2l0aGluIHRoZSBzdXBwbGllZCBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgb2YgY29tcHJlc3NlZCBkYXRhIHdyaXR0ZW4gdG8ge0Bjb2RlIGJ1Zn0uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZGVmbGF0ZShieXRlW10gYnVmLCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB7CisgICAgICAgIHJldHVybiBkZWZsYXRlSW1wbChidWYsIG9mZnNldCwgYnl0ZUNvdW50LCBmbHVzaFBhcm0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlZmxhdGVzIGRhdGEgKHByZXZpb3VzbHkgcGFzc2VkIHRvIHtAbGluayAjc2V0SW5wdXQgc2V0SW5wdXR9KSBpbnRvIGEgc3BlY2lmaWMKKyAgICAgKiByZWdpb24gd2l0aGluIHRoZSBzdXBwbGllZCBidWZmZXIsIG9wdGlvbmFsbHkgZmx1c2hpbmcgdGhlIGlucHV0IGJ1ZmZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmbHVzaCBvbmUgb2Yge0BsaW5rICNOT19GTFVTSH0sIHtAbGluayAjU1lOQ19GTFVTSH0gb3Ige0BsaW5rICNGVUxMX0ZMVVNIfS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY29tcHJlc3NlZCBieXRlcyB3cml0dGVuIHRvIHtAY29kZSBidWZ9LiBJZiB0aGlzCisgICAgICogICAgICBlcXVhbHMge0Bjb2RlIGJ5dGVDb3VudH0sIHRoZSBudW1iZXIgb2YgYnl0ZXMgb2YgaW5wdXQgdG8gYmUgZmx1c2hlZAorICAgICAqICAgICAgbWF5IGhhdmUgZXhjZWVkZWQgdGhlIG91dHB1dCBidWZmZXIncyBjYXBhY2l0eS4gSW4gdGhpcyBjYXNlLAorICAgICAqICAgICAgZmluaXNoaW5nIGEgZmx1c2ggd2lsbCByZXF1aXJlIHRoZSBvdXRwdXQgYnVmZmVyIHRvIGJlIGRyYWluZWQKKyAgICAgKiAgICAgIGFuZCBhZGRpdGlvbmFsIGNhbGxzIHRvIHtAbGluayAjZGVmbGF0ZX0gdG8gYmUgbWFkZS4KKyAgICAgKiBAaGlkZQorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBkZWZsYXRlKGJ5dGVbXSBidWYsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQsIGludCBmbHVzaCkgeworICAgICAgICBpZiAoZmx1c2ggIT0gTk9fRkxVU0ggJiYgZmx1c2ggIT0gU1lOQ19GTFVTSCAmJiBmbHVzaCAhPSBGVUxMX0ZMVVNIKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJCYWQgZmx1c2ggdmFsdWU6ICIgKyBmbHVzaCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRlZmxhdGVJbXBsKGJ1Ziwgb2Zmc2V0LCBieXRlQ291bnQsIGZsdXNoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCBpbnQgZGVmbGF0ZUltcGwoYnl0ZVtdIGJ1ZiwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCwgaW50IGZsdXNoKSB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWYubGVuZ3RoLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIGlmIChpbnB1dEJ1ZmZlciA9PSBudWxsKSB7CisgICAgICAgICAgICBzZXRJbnB1dChFbXB0eUFycmF5LkJZVEUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkZWZsYXRlSW1wbChidWYsIG9mZnNldCwgYnl0ZUNvdW50LCBzdHJlYW1IYW5kbGUsIGZsdXNoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIG5hdGl2ZSBpbnQgZGVmbGF0ZUltcGwoYnl0ZVtdIGJ1ZiwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCwgbG9uZyBoYW5kbGUsIGludCBmbHVzaFBhcm0pOworCisgICAgLyoqCisgICAgICogRnJlZXMgYWxsIHJlc291cmNlcyBoZWxkIG9udG8gYnkgdGhpcyBkZWZsYXRpbmcgYWxnb3JpdGhtLiBBbnkgdW51c2VkCisgICAgICogaW5wdXQgb3Igb3V0cHV0IGlzIGRpc2NhcmRlZC4gVGhpcyBtZXRob2Qgc2hvdWxkIGJlIGNhbGxlZCBleHBsaWNpdGx5IGluCisgICAgICogb3JkZXIgdG8gZnJlZSBuYXRpdmUgcmVzb3VyY2VzIGFzIHNvb24gYXMgcG9zc2libGUuIEFmdGVyIHtAY29kZSBlbmQoKX0gaXMKKyAgICAgKiBjYWxsZWQsIG90aGVyIG1ldGhvZHMgd2lsbCB0eXBpY2FsbHkgdGhyb3cge0Bjb2RlIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGVuZCgpIHsKKyAgICAgICAgZ3VhcmQuY2xvc2UoKTsKKyAgICAgICAgZW5kSW1wbCgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBlbmRJbXBsKCkgeworICAgICAgICBpZiAoc3RyZWFtSGFuZGxlICE9IC0xKSB7CisgICAgICAgICAgICBlbmRJbXBsKHN0cmVhbUhhbmRsZSk7CisgICAgICAgICAgICBpbnB1dEJ1ZmZlciA9IG51bGw7CisgICAgICAgICAgICBzdHJlYW1IYW5kbGUgPSAtMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgbmF0aXZlIHZvaWQgZW5kSW1wbChsb25nIGhhbmRsZSk7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoZ3VhcmQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGd1YXJkLndhcm5JZk9wZW4oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgICAgIGVuZCgpOyAvLyB0byBhbGxvdyBvdmVycmlkaW5nIGNsYXNzZXMgdG8gY2xlYW4gdXAKKyAgICAgICAgICAgICAgICBlbmRJbXBsKCk7IC8vIGluIGNhc2UgdGhvc2UgY2xhc3NlcyBkb24ndCBjYWxsIHN1cGVyLmVuZCgpCisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN1cGVyLmZpbmFsaXplKCk7CisgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcih0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB0byB0aGUge0Bjb2RlIERlZmxhdGVyfSB0aGF0IGFsbCB1bmNvbXByZXNzZWQgaW5wdXQgaGFzIGJlZW4gcHJvdmlkZWQKKyAgICAgKiB0byBpdC4KKyAgICAgKgorICAgICAqIEBzZWUgI2ZpbmlzaGVkCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGZpbmlzaCgpIHsKKyAgICAgICAgZmx1c2hQYXJtID0gRklOSVNIOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB7QGxpbmsgI2ZpbmlzaCBmaW5pc2h9IGhhcyBiZWVuIGNhbGxlZCBhbmQgYWxsCisgICAgICogZGF0YSBwcm92aWRlZCBieSB7QGxpbmsgI3NldElucHV0IHNldElucHV0fSBoYXMgYmVlbgorICAgICAqIHN1Y2Nlc3NmdWxseSBjb21wcmVzc2VkIGFuZCBjb25zdW1lZCBieSB7QGxpbmsgI2RlZmxhdGUgZGVmbGF0ZX0uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGZpbmlzaGVkKCkgeworICAgICAgICByZXR1cm4gZmluaXNoZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0BsaW5rIEFkbGVyMzJ9IGNoZWNrc3VtIG9mIHRoZSB1bmNvbXByZXNzZWQgZGF0YSByZWFkIHNvIGZhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRBZGxlcigpIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIHJldHVybiBnZXRBZGxlckltcGwoc3RyZWFtSGFuZGxlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIG5hdGl2ZSBpbnQgZ2V0QWRsZXJJbXBsKGxvbmcgaGFuZGxlKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyBvZiBpbnB1dCByZWFkIGJ5IHRoaXMge0Bjb2RlIERlZmxhdGVyfS4gVGhpcworICAgICAqIG1ldGhvZCBpcyBsaW1pdGVkIHRvIDMyIGJpdHM7IHVzZSB7QGxpbmsgI2dldEJ5dGVzUmVhZH0gaW5zdGVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRUb3RhbEluKCkgeworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgcmV0dXJuIChpbnQpIGdldFRvdGFsSW5JbXBsKHN0cmVhbUhhbmRsZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBuYXRpdmUgbG9uZyBnZXRUb3RhbEluSW1wbChsb25nIGhhbmRsZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiB0byB0aGUgb3V0cHV0IGJ1ZmZlciBieSB0aGlzIHtAY29kZQorICAgICAqIERlZmxhdGVyfS4gVGhlIG1ldGhvZCBpcyBsaW1pdGVkIHRvIDMyIGJpdHM7IHVzZSB7QGxpbmsgI2dldEJ5dGVzV3JpdHRlbn0gaW5zdGVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRUb3RhbE91dCgpIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIHJldHVybiAoaW50KSBnZXRUb3RhbE91dEltcGwoc3RyZWFtSGFuZGxlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIG5hdGl2ZSBsb25nIGdldFRvdGFsT3V0SW1wbChsb25nIGhhbmRsZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYge0BsaW5rICNzZXRJbnB1dCBzZXRJbnB1dH0gbXVzdCBiZSBjYWxsZWQgYmVmb3JlIGRlZmxhdGlvbiBjYW4gY29udGludWUuCisgICAgICogSWYgYWxsIHVuY29tcHJlc3NlZCBkYXRhIGhhcyBiZWVuIHByb3ZpZGVkIHRvIHRoZSB7QGNvZGUgRGVmbGF0ZXJ9LAorICAgICAqIHtAbGluayAjZmluaXNofSBtdXN0IGJlIGNhbGxlZCB0byBlbnN1cmUgdGhlIGNvbXByZXNzZWQgZGF0YSBpcyBvdXRwdXQuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIG5lZWRzSW5wdXQoKSB7CisgICAgICAgIGlmIChpbnB1dEJ1ZmZlciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW5SZWFkID09IGluTGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0cyB0aGUge0Bjb2RlIERlZmxhdGVyfSB0byBhY2NlcHQgbmV3IGlucHV0IHdpdGhvdXQgYWZmZWN0aW5nIGFueQorICAgICAqIHByZXZpb3VzbHkgbWFkZSBzZXR0aW5ncyBmb3IgdGhlIGNvbXByZXNzaW9uIHN0cmF0ZWd5IG9yIGxldmVsLiBUaGlzCisgICAgICogb3BlcmF0aW9uIDxpPm11c3Q8L2k+IGJlIGNhbGxlZCBhZnRlciB7QGxpbmsgI2ZpbmlzaGVkfSByZXR1cm5zCisgICAgICogdHJ1ZSBpZiB0aGUge0Bjb2RlIERlZmxhdGVyfSBpcyB0byBiZSByZXVzZWQuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHJlc2V0KCkgeworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgZmx1c2hQYXJtID0gTk9fRkxVU0g7CisgICAgICAgIGZpbmlzaGVkID0gZmFsc2U7CisgICAgICAgIHJlc2V0SW1wbChzdHJlYW1IYW5kbGUpOworICAgICAgICBpbnB1dEJ1ZmZlciA9IG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBuYXRpdmUgdm9pZCByZXNldEltcGwobG9uZyBoYW5kbGUpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGljdGlvbmFyeSB0byBiZSB1c2VkIGZvciBjb21wcmVzc2lvbiBieSB0aGlzIHtAY29kZSBEZWZsYXRlcn0uCisgICAgICogVGhpcyBtZXRob2QgY2FuIG9ubHkgYmUgY2FsbGVkIGlmIHRoaXMge0Bjb2RlIERlZmxhdGVyfSBzdXBwb3J0cyB0aGUgd3JpdGluZworICAgICAqIG9mIFpMSUIgaGVhZGVycy4gVGhpcyBpcyB0aGUgZGVmYXVsdCwgYnV0IGNhbiBiZSBvdmVycmlkZGVuCisgICAgICogdXNpbmcge0BsaW5rICNEZWZsYXRlcihpbnQsIGJvb2xlYW4pfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREaWN0aW9uYXJ5KGJ5dGVbXSBkaWN0aW9uYXJ5KSB7CisgICAgICAgIHNldERpY3Rpb25hcnkoZGljdGlvbmFyeSwgMCwgZGljdGlvbmFyeS5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGRpY3Rpb25hcnkgdG8gYmUgdXNlZCBmb3IgY29tcHJlc3Npb24gYnkgdGhpcyB7QGNvZGUgRGVmbGF0ZXJ9LgorICAgICAqIFRoaXMgbWV0aG9kIGNhbiBvbmx5IGJlIGNhbGxlZCBpZiB0aGlzIHtAY29kZSBEZWZsYXRlcn0gc3VwcG9ydHMgdGhlIHdyaXRpbmcKKyAgICAgKiBvZiBaTElCIGhlYWRlcnMuIFRoaXMgaXMgdGhlIGRlZmF1bHQsIGJ1dCBjYW4gYmUgb3ZlcnJpZGRlbgorICAgICAqIHVzaW5nIHtAbGluayAjRGVmbGF0ZXIoaW50LCBib29sZWFuKX0uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldERpY3Rpb25hcnkoYnl0ZVtdIGJ1ZiwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCkgeworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmLmxlbmd0aCwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICBzZXREaWN0aW9uYXJ5SW1wbChidWYsIG9mZnNldCwgYnl0ZUNvdW50LCBzdHJlYW1IYW5kbGUpOworICAgIH0KKworICAgIHByaXZhdGUgbmF0aXZlIHZvaWQgc2V0RGljdGlvbmFyeUltcGwoYnl0ZVtdIGJ1ZiwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCwgbG9uZyBoYW5kbGUpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgaW5wdXQgYnVmZmVyIHRoZSB7QGNvZGUgRGVmbGF0ZXJ9IHdpbGwgdXNlIHRvIGV4dHJhY3QgdW5jb21wcmVzc2VkIGJ5dGVzCisgICAgICogZm9yIGxhdGVyIGNvbXByZXNzaW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldElucHV0KGJ5dGVbXSBidWYpIHsKKyAgICAgICAgc2V0SW5wdXQoYnVmLCAwLCBidWYubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBpbnB1dCBidWZmZXIgdGhlIHtAY29kZSBEZWZsYXRlcn0gd2lsbCB1c2UgdG8gZXh0cmFjdCB1bmNvbXByZXNzZWQgYnl0ZXMKKyAgICAgKiBmb3IgbGF0ZXIgY29tcHJlc3Npb24uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldElucHV0KGJ5dGVbXSBidWYsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQpIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGJ1Zi5sZW5ndGgsIG9mZnNldCwgYnl0ZUNvdW50KTsKKyAgICAgICAgaW5MZW5ndGggPSBieXRlQ291bnQ7CisgICAgICAgIGluUmVhZCA9IDA7CisgICAgICAgIGlmIChpbnB1dEJ1ZmZlciA9PSBudWxsKSB7CisgICAgICAgICAgICBzZXRMZXZlbHNJbXBsKGNvbXByZXNzTGV2ZWwsIHN0cmF0ZWd5LCBzdHJlYW1IYW5kbGUpOworICAgICAgICB9CisgICAgICAgIGlucHV0QnVmZmVyID0gYnVmOworICAgICAgICBzZXRJbnB1dEltcGwoYnVmLCBvZmZzZXQsIGJ5dGVDb3VudCwgc3RyZWFtSGFuZGxlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIG5hdGl2ZSB2b2lkIHNldExldmVsc0ltcGwoaW50IGxldmVsLCBpbnQgc3RyYXRlZ3ksIGxvbmcgaGFuZGxlKTsKKworICAgIHByaXZhdGUgbmF0aXZlIHZvaWQgc2V0SW5wdXRJbXBsKGJ5dGVbXSBidWYsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQsIGxvbmcgaGFuZGxlKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNvbXByZXNzaW9uIGxldmVsIHRvIGJlIHVzZWQgd2hlbiBjb21wcmVzc2luZyBkYXRhLiBUaGUKKyAgICAgKiBjb21wcmVzc2lvbiBsZXZlbCBtdXN0IGJlIGEgdmFsdWUgYmV0d2VlbiAwIGFuZCA5LiBUaGlzIHZhbHVlIG11c3QgYmUgc2V0CisgICAgICogcHJpb3IgdG8gY2FsbGluZyB7QGxpbmsgI3NldElucHV0IHNldElucHV0fS4KKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIElmIHRoZSBjb21wcmVzc2lvbiBsZXZlbCBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRMZXZlbChpbnQgbGV2ZWwpIHsKKyAgICAgICAgaWYgKGxldmVsIDwgREVGQVVMVF9DT01QUkVTU0lPTiB8fCBsZXZlbCA+IEJFU1RfQ09NUFJFU1NJT04pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkJhZCBsZXZlbDogIiArIGxldmVsKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXRCdWZmZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigic2V0TGV2ZWwgY2Fubm90IGJlIGNhbGxlZCBhZnRlciBzZXRJbnB1dCIpOworICAgICAgICB9CisgICAgICAgIGNvbXByZXNzTGV2ZWwgPSBsZXZlbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjb21wcmVzc2lvbiBzdHJhdGVneSB0byBiZSB1c2VkLiBUaGUgc3RyYXRlZ3kgbXVzdCBiZSBvbmUgb2YKKyAgICAgKiBGSUxURVJFRCwgSFVGRk1BTl9PTkxZIG9yIERFRkFVTFRfU1RSQVRFR1kuIFRoaXMgdmFsdWUgbXVzdCBiZSBzZXQgcHJpb3IKKyAgICAgKiB0byBjYWxsaW5nIHtAbGluayAjc2V0SW5wdXQgc2V0SW5wdXR9LgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBJZiB0aGUgc3RyYXRlZ3kgc3BlY2lmaWVkIGlzIG5vdCBvbmUgb2YgRklMVEVSRUQsCisgICAgICogICAgICAgICAgICAgICAgSFVGRk1BTl9PTkxZIG9yIERFRkFVTFRfU1RSQVRFR1kuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFN0cmF0ZWd5KGludCBzdHJhdGVneSkgeworICAgICAgICBpZiAoc3RyYXRlZ3kgPCBERUZBVUxUX1NUUkFURUdZIHx8IHN0cmF0ZWd5ID4gSFVGRk1BTl9PTkxZKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJCYWQgc3RyYXRlZ3k6ICIgKyBzdHJhdGVneSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0QnVmZmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oInNldFN0cmF0ZWd5IGNhbm5vdCBiZSBjYWxsZWQgYWZ0ZXIgc2V0SW5wdXQiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnN0cmF0ZWd5ID0gc3RyYXRlZ3k7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgYnkgdGhlIHtAY29kZSBEZWZsYXRlcn0uIFRoaXMKKyAgICAgKiBtZXRob2QgaXMgdGhlIHNhbWUgYXMge0BsaW5rICNnZXRUb3RhbElufSBleGNlcHQgdGhhdCBpdCByZXR1cm5zIGEKKyAgICAgKiB7QGNvZGUgbG9uZ30gdmFsdWUgaW5zdGVhZCBvZiBhbiBpbnRlZ2VyLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgbG9uZyBnZXRCeXRlc1JlYWQoKSB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICByZXR1cm4gZ2V0VG90YWxJbkltcGwoc3RyZWFtSGFuZGxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgdGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuIGJ5IHRoaXMge0Bjb2RlIERlZmxhdGVyfS4gVGhpcworICAgICAqIG1ldGhvZCBpcyB0aGUgc2FtZSBhcyB7QGNvZGUgZ2V0VG90YWxPdXR9IGV4Y2VwdCBpdCByZXR1cm5zIGEKKyAgICAgKiB7QGNvZGUgbG9uZ30gdmFsdWUgaW5zdGVhZCBvZiBhbiBpbnRlZ2VyLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgbG9uZyBnZXRCeXRlc1dyaXR0ZW4oKSB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICByZXR1cm4gZ2V0VG90YWxPdXRJbXBsKHN0cmVhbUhhbmRsZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBuYXRpdmUgbG9uZyBjcmVhdGVTdHJlYW0oaW50IGxldmVsLCBpbnQgc3RyYXRlZ3kxLCBib29sZWFuIG5vSGVhZGVyMSk7CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tPcGVuKCkgeworICAgICAgICBpZiAoc3RyZWFtSGFuZGxlID09IC0xKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJhdHRlbXB0IHRvIHVzZSBEZWZsYXRlciBhZnRlciBjYWxsaW5nIGVuZCIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvRGVmbGF0ZXJJbnB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvRGVmbGF0ZXJJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM2ZTk1ZjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9EZWZsYXRlcklucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwyMDkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC56aXA7CisKK2ltcG9ydCBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGxpYmNvcmUuaW8uU3RyZWFtczsKKworLyoqCisgKiBBbiB7QGNvZGUgSW5wdXRTdHJlYW19IGZpbHRlciB0byBjb21wcmVzcyBkYXRhLiBDYWxsZXJzIHJlYWQKKyAqIGNvbXByZXNzZWQgZGF0YSBpbiB0aGUgImRlZmxhdGUiIGZvcm1hdCBmcm9tIHRoZSB1bmNvbXByZXNzZWQKKyAqIHVuZGVybHlpbmcgc3RyZWFtLgorICogQHNpbmNlIDEuNgorICovCitwdWJsaWMgY2xhc3MgRGVmbGF0ZXJJbnB1dFN0cmVhbSBleHRlbmRzIEZpbHRlcklucHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9CVUZGRVJfU0laRSA9IDEwMjQ7CisKKyAgICBwcm90ZWN0ZWQgZmluYWwgRGVmbGF0ZXIgZGVmOworICAgIHByb3RlY3RlZCBmaW5hbCBieXRlW10gYnVmOworCisgICAgcHJpdmF0ZSBib29sZWFuIGNsb3NlZCA9IGZhbHNlOworICAgIHByaXZhdGUgYm9vbGVhbiBhdmFpbGFibGUgPSB0cnVlOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBEZWZsYXRlcklucHV0U3RyZWFtfSB3aXRoIGEgbmV3IHtAY29kZSBEZWZsYXRlcn0gYW5kIGFuCisgICAgICogaW1wbGVtZW50YXRpb24tZGVmaW5lZCBkZWZhdWx0IGludGVybmFsIGJ1ZmZlciBzaXplLiB7QGNvZGUgaW59IGlzIGEgc291cmNlIG9mCisgICAgICogdW5jb21wcmVzc2VkIGRhdGEsIGFuZCB0aGlzIHN0cmVhbSB3aWxsIGJlIGEgc291cmNlIG9mIGNvbXByZXNzZWQgZGF0YS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbiB0aGUgc291cmNlIHtAY29kZSBJbnB1dFN0cmVhbX0KKyAgICAgKi8KKyAgICBwdWJsaWMgRGVmbGF0ZXJJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbikgeworICAgICAgICB0aGlzKGluLCBuZXcgRGVmbGF0ZXIoKSwgREVGQVVMVF9CVUZGRVJfU0laRSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHtAY29kZSBEZWZsYXRlcklucHV0U3RyZWFtfSB3aXRoIHRoZSBnaXZlbiB7QGNvZGUgRGVmbGF0ZXJ9IGFuZCBhbgorICAgICAqIGltcGxlbWVudGF0aW9uLWRlZmluZWQgZGVmYXVsdCBpbnRlcm5hbCBidWZmZXIgc2l6ZS4ge0Bjb2RlIGlufSBpcyBhIHNvdXJjZSBvZgorICAgICAqIHVuY29tcHJlc3NlZCBkYXRhLCBhbmQgdGhpcyBzdHJlYW0gd2lsbCBiZSBhIHNvdXJjZSBvZiBjb21wcmVzc2VkIGRhdGEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4gdGhlIHNvdXJjZSB7QGNvZGUgSW5wdXRTdHJlYW19CisgICAgICogQHBhcmFtIGRlZmxhdGVyIHRoZSB7QGNvZGUgRGVmbGF0ZXJ9IHRvIGJlIHVzZWQgZm9yIGNvbXByZXNzaW9uCisgICAgICovCisgICAgcHVibGljIERlZmxhdGVySW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaW4sIERlZmxhdGVyIGRlZmxhdGVyKSB7CisgICAgICAgIHRoaXMoaW4sIGRlZmxhdGVyLCBERUZBVUxUX0JVRkZFUl9TSVpFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0Bjb2RlIERlZmxhdGVySW5wdXRTdHJlYW19IHdpdGggdGhlIGdpdmVuIHtAY29kZSBEZWZsYXRlcn0gYW5kCisgICAgICogZ2l2ZW4gaW50ZXJuYWwgYnVmZmVyIHNpemUuIHtAY29kZSBpbn0gaXMgYSBzb3VyY2Ugb2YKKyAgICAgKiB1bmNvbXByZXNzZWQgZGF0YSwgYW5kIHRoaXMgc3RyZWFtIHdpbGwgYmUgYSBzb3VyY2Ugb2YgY29tcHJlc3NlZCBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIGluIHRoZSBzb3VyY2Uge0Bjb2RlIElucHV0U3RyZWFtfQorICAgICAqIEBwYXJhbSBkZWZsYXRlciB0aGUge0Bjb2RlIERlZmxhdGVyfSB0byBiZSB1c2VkIGZvciBjb21wcmVzc2lvbgorICAgICAqIEBwYXJhbSBidWZmZXJTaXplIHRoZSBsZW5ndGggaW4gYnl0ZXMgb2YgdGhlIGludGVybmFsIGJ1ZmZlcgorICAgICAqLworICAgIHB1YmxpYyBEZWZsYXRlcklucHV0U3RyZWFtKElucHV0U3RyZWFtIGluLCBEZWZsYXRlciBkZWZsYXRlciwgaW50IGJ1ZmZlclNpemUpIHsKKyAgICAgICAgc3VwZXIoaW4pOworICAgICAgICBpZiAoaW4gPT0gbnVsbCB8fCBkZWZsYXRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYnVmZmVyU2l6ZSA8PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5kZWYgPSBkZWZsYXRlcjsKKyAgICAgICAgdGhpcy5idWYgPSBuZXcgYnl0ZVtidWZmZXJTaXplXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhlIHVuZGVybHlpbmcgaW5wdXQgc3RyZWFtIGFuZCBkaXNjYXJkcyBhbnkgcmVtYWluaW5nIHVuY29tcHJlc3NlZAorICAgICAqIGRhdGEuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjbG9zZWQgPSB0cnVlOworICAgICAgICBkZWYuZW5kKCk7CisgICAgICAgIGluLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYSBieXRlIGZyb20gdGhlIGNvbXByZXNzZWQgaW5wdXQgc3RyZWFtLiBUaGUgcmVzdWx0IHdpbGwgYmUgYSBieXRlIG9mIGNvbXByZXNzZWQKKyAgICAgKiBkYXRhIGNvcnJlc3BvbmRpbmcgdG8gYW4gdW5jb21wcmVzc2VkIGJ5dGUgb3IgYnl0ZXMgcmVhZCBmcm9tIHRoZSB1bmRlcmx5aW5nIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBTdHJlYW1zLnJlYWRTaW5nbGVCeXRlKHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGNvbXByZXNzZWQgZGF0YSBpbnRvIGEgYnl0ZSBidWZmZXIuIFRoZSByZXN1bHQgd2lsbCBiZSBieXRlcyBvZiBjb21wcmVzc2VkCisgICAgICogZGF0YSBjb3JyZXNwb25kaW5nIHRvIGFuIHVuY29tcHJlc3NlZCBieXRlIG9yIGJ5dGVzIHJlYWQgZnJvbSB0aGUgdW5kZXJseWluZyBzdHJlYW0uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgY29tcHJlc3NlZCBpbnB1dAorICAgICAqICAgICAgICAgc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXIubGVuZ3RoLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIGlmIChieXRlQ291bnQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWF2YWlsYWJsZSkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisKKyAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgd2hpbGUgKGNvdW50IDwgYnl0ZUNvdW50ICYmICFkZWYuZmluaXNoZWQoKSkgeworICAgICAgICAgICAgaWYgKGRlZi5uZWVkc0lucHV0KCkpIHsKKyAgICAgICAgICAgICAgICAvLyByZWFkIGRhdGEgZnJvbSBpbnB1dCBzdHJlYW0KKyAgICAgICAgICAgICAgICBpbnQgYnl0ZXNSZWFkID0gaW4ucmVhZChidWYpOworICAgICAgICAgICAgICAgIGlmIChieXRlc1JlYWQgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgZGVmLmZpbmlzaCgpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGRlZi5zZXRJbnB1dChidWYsIDAsIGJ5dGVzUmVhZCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IGJ5dGVzRGVmbGF0ZWQgPSBkZWYuZGVmbGF0ZShidWYsIDAsIE1hdGgubWluKGJ1Zi5sZW5ndGgsIGJ5dGVDb3VudCAtIGNvdW50KSk7CisgICAgICAgICAgICBpZiAoYnl0ZXNEZWZsYXRlZCA9PSAtMSkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWYsIDAsIGJ1ZmZlciwgb2Zmc2V0ICsgY291bnQsIGJ5dGVzRGVmbGF0ZWQpOworICAgICAgICAgICAgY291bnQgKz0gYnl0ZXNEZWZsYXRlZDsKKyAgICAgICAgfQorICAgICAgICBpZiAoY291bnQgPT0gMCkgeworICAgICAgICAgICAgY291bnQgPSAtMTsKKyAgICAgICAgICAgIGF2YWlsYWJsZSA9IGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICogPHA+Tm90ZTogaWYge0Bjb2RlIG4gPiBJbnRlZ2VyLk1BWF9WQUxVRX0sIHRoaXMgc3RyZWFtIHdpbGwgb25seSBhdHRlbXB0IHRvCisgICAgICogc2tpcCB7QGNvZGUgSW50ZWdlci5NQVhfVkFMVUV9IGJ5dGVzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIHNraXAobG9uZyBieXRlQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVDb3VudCA9IE1hdGgubWluKEludGVnZXIuTUFYX1ZBTFVFLCBieXRlQ291bnQpOworICAgICAgICByZXR1cm4gU3RyZWFtcy5za2lwQnlSZWFkaW5nKHRoaXMsIGJ5dGVDb3VudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyAwIHdoZW4gd2hlbiB0aGlzIHN0cmVhbSBoYXMgZXhoYXVzdGVkIGl0cyBpbnB1dDsgYW5kIDEgb3RoZXJ3aXNlLgorICAgICAqIEEgcmVzdWx0IG9mIDEgZG9lcyBub3QgZ3VhcmFudGVlIHRoYXQgZnVydGhlciBieXRlcyBjYW4gYmUgcmV0dXJuZWQsCisgICAgICogd2l0aCBvciB3aXRob3V0IGJsb2NraW5nLgorICAgICAqCisgICAgICogPHA+QWx0aG91Z2ggY29uc2lzdGVudCB3aXRoIHRoZSBSSSwgdGhpcyBiZWhhdmlvciBpcyBpbmNvbnNpc3RlbnQgd2l0aAorICAgICAqIHtAbGluayBJbnB1dFN0cmVhbSNhdmFpbGFibGUoKX0sIGFuZCB2aW9sYXRlcyB0aGUgPGEKKyAgICAgKiBocmVmPSJodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0xpc2tvdl9zdWJzdGl0dXRpb25fcHJpbmNpcGxlIj5MaXNrb3YKKyAgICAgKiBTdWJzdGl0dXRpb24gUHJpbmNpcGxlPC9hPi4gVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkLgorICAgICAqCisgICAgICogQHJldHVybiAwIGlmIG5vIGZ1cnRoZXIgYnl0ZXMgYXJlIGF2YWlsYWJsZS4gT3RoZXJ3aXNlIHJldHVybnMgMSwKKyAgICAgKiAgICAgICAgIHdoaWNoIHN1Z2dlc3RzIChidXQgZG9lcyBub3QgZ3VhcmFudGVlKSB0aGF0IGFkZGl0aW9uYWwgYnl0ZXMgYXJlCisgICAgICogICAgICAgICBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGlzIHN0cmVhbSBpcyBjbG9zZWQgb3IgYW4gZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICByZXR1cm4gYXZhaWxhYmxlID8gMSA6IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBmYWxzZSBiZWNhdXNlIHtAY29kZSBEZWZsYXRlcklucHV0U3RyZWFtfSBkb2VzIG5vdCBzdXBwb3J0CisgICAgICoge0Bjb2RlIG1hcmt9L3tAY29kZSByZXNldH0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gbWFya1N1cHBvcnRlZCgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgb3BlcmF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgYW5kIGRvZXMgbm90aGluZy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBtYXJrKGludCBsaW1pdCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgb3BlcmF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgYW5kIHRocm93cyB7QGNvZGUgSU9FeGNlcHRpb259LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrQ2xvc2VkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNsb3NlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJTdHJlYW0gaXMgY2xvc2VkIik7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9EZWZsYXRlck91dHB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvRGVmbGF0ZXJPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMGJjYjk5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvRGVmbGF0ZXJPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDIyMSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLnppcDsKKworaW1wb3J0IGphdmEuaW8uRmlsdGVyT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBsaWJjb3JlLmlvLlN0cmVhbXM7CisKKy8qKgorICogVGhpcyBjbGFzcyBwcm92aWRlcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB7QGNvZGUgRmlsdGVyT3V0cHV0U3RyZWFtfSB0aGF0CisgKiBjb21wcmVzc2VzIGRhdGEgdXNpbmcgdGhlIDxpPkRFRkxBVEU8L2k+IGFsZ29yaXRobS4gQmFzaWNhbGx5IGl0IHdyYXBzIHRoZQorICoge0Bjb2RlIERlZmxhdGVyfSBjbGFzcyBhbmQgdGFrZXMgY2FyZSBvZiB0aGUgYnVmZmVyaW5nLgorICoKKyAqIEBzZWUgRGVmbGF0ZXIKKyAqLworcHVibGljIGNsYXNzIERlZmxhdGVyT3V0cHV0U3RyZWFtIGV4dGVuZHMgRmlsdGVyT3V0cHV0U3RyZWFtIHsKKyAgICBzdGF0aWMgZmluYWwgaW50IEJVRl9TSVpFID0gNTEyOworCisgICAgLyoqCisgICAgICogVGhlIGJ1ZmZlciBmb3IgdGhlIGRhdGEgdG8gYmUgd3JpdHRlbiB0by4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIGJ1ZjsKKworICAgIC8qKgorICAgICAqIFRoZSBkZWZsYXRlciB1c2VkLgorICAgICAqLworICAgIHByb3RlY3RlZCBEZWZsYXRlciBkZWY7CisKKyAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKKworICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBzeW5jRmx1c2g7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNvbnN0cnVjdG9yIGxldHMgeW91IHBhc3MgdGhlIHtAY29kZSBEZWZsYXRlcn0gc3BlY2lmeWluZyB0aGUKKyAgICAgKiBjb21wcmVzc2lvbiBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3MKKyAgICAgKiAgICAgICAgICAgIGlzIHRoZSB7QGNvZGUgT3V0cHV0U3RyZWFtfSB3aGVyZSB0byB3cml0ZSB0aGUgY29tcHJlc3NlZCBkYXRhCisgICAgICogICAgICAgICAgICB0by4KKyAgICAgKiBAcGFyYW0gZGVmCisgICAgICogICAgICAgICAgICBpcyB0aGUgc3BlY2lmaWMge0Bjb2RlIERlZmxhdGVyfSB0aGF0IGlzIHVzZWQgdG8gY29tcHJlc3MKKyAgICAgKiAgICAgICAgICAgIGRhdGEuCisgICAgICovCisgICAgcHVibGljIERlZmxhdGVyT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvcywgRGVmbGF0ZXIgZGVmKSB7CisgICAgICAgIHRoaXMob3MsIGRlZiwgQlVGX1NJWkUsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGlzIHRoZSBtb3N0IGJhc2ljIGNvbnN0cnVjdG9yLiBZb3Ugb25seSBuZWVkIHRvIHBhc3MgdGhlIHtAY29kZQorICAgICAqIE91dHB1dFN0cmVhbX0gdG8gd2hpY2ggdGhlIGNvbXByZXNzZWQgZGF0YSBzaGFsbCBiZSB3cml0dGVuIHRvLiBUaGUKKyAgICAgKiBkZWZhdWx0IHNldHRpbmdzIGZvciB0aGUge0Bjb2RlIERlZmxhdGVyfSBhbmQgaW50ZXJuYWwgYnVmZmVyIGFyZSB1c2VkLgorICAgICAqIEluIHBhcnRpY3VsYXIgdGhlIHtAY29kZSBEZWZsYXRlcn0gcHJvZHVjZXMgYSBaTElCIGhlYWRlciBpbiB0aGUgb3V0cHV0CisgICAgICogc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIG9zCisgICAgICogICAgICAgICAgICBpcyB0aGUgT3V0cHV0U3RyZWFtIHdoZXJlIHRvIHdyaXRlIHRoZSBjb21wcmVzc2VkIGRhdGEgdG8uCisgICAgICovCisgICAgcHVibGljIERlZmxhdGVyT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvcykgeworICAgICAgICB0aGlzKG9zLCBuZXcgRGVmbGF0ZXIoKSwgQlVGX1NJWkUsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNvbnN0cnVjdG9yIGxldHMgeW91IHNwZWNpZnkgYm90aCB0aGUgY29tcHJlc3Npb24gYWxnb3JpdGhtIGFzIHdlbGwKKyAgICAgKiBhcyB0aGUgaW50ZXJuYWwgYnVmZmVyIHNpemUgdG8gYmUgdXNlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcworICAgICAqICAgICAgICAgICAgaXMgdGhlIHtAY29kZSBPdXRwdXRTdHJlYW19IHdoZXJlIHRvIHdyaXRlIHRoZSBjb21wcmVzc2VkIGRhdGEKKyAgICAgKiAgICAgICAgICAgIHRvLgorICAgICAqIEBwYXJhbSBkZWYKKyAgICAgKiAgICAgICAgICAgIGlzIHRoZSBzcGVjaWZpYyB7QGNvZGUgRGVmbGF0ZXJ9IHRoYXQgd2lsbCBiZSB1c2VkIHRvIGNvbXByZXNzCisgICAgICogICAgICAgICAgICBkYXRhLgorICAgICAqIEBwYXJhbSBic2l6ZQorICAgICAqICAgICAgICAgICAgaXMgdGhlIHNpemUgdG8gYmUgdXNlZCBmb3IgdGhlIGludGVybmFsIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGVmbGF0ZXJPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG9zLCBEZWZsYXRlciBkZWYsIGludCBic2l6ZSkgeworICAgICAgICB0aGlzKG9zLCBkZWYsIGJzaXplLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQGhpZGUKKyAgICAgKiBAc2luY2UgMS43CisgICAgICovCisgICAgcHVibGljIERlZmxhdGVyT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvcywgYm9vbGVhbiBzeW5jRmx1c2gpIHsKKyAgICAgICAgdGhpcyhvcywgbmV3IERlZmxhdGVyKCksIEJVRl9TSVpFLCBzeW5jRmx1c2gpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBoaWRlCisgICAgICogQHNpbmNlIDEuNworICAgICAqLworICAgIHB1YmxpYyBEZWZsYXRlck91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3MsIERlZmxhdGVyIGRlZiwgYm9vbGVhbiBzeW5jRmx1c2gpIHsKKyAgICAgICAgdGhpcyhvcywgZGVmLCBCVUZfU0laRSwgc3luY0ZsdXNoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAaGlkZQorICAgICAqIEBzaW5jZSAxLjcKKyAgICAgKi8KKyAgICBwdWJsaWMgRGVmbGF0ZXJPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG9zLCBEZWZsYXRlciBkZWYsIGludCBic2l6ZSwgYm9vbGVhbiBzeW5jRmx1c2gpIHsKKyAgICAgICAgc3VwZXIob3MpOworICAgICAgICBpZiAob3MgPT0gbnVsbCB8fCBkZWYgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJzaXplIDw9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmRlZiA9IGRlZjsKKyAgICAgICAgdGhpcy5zeW5jRmx1c2ggPSBzeW5jRmx1c2g7CisgICAgICAgIGJ1ZiA9IG5ldyBieXRlW2JzaXplXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wcmVzcyB0aGUgZGF0YSBpbiB0aGUgaW5wdXQgYnVmZmVyIGFuZCB3cml0ZSBpdCB0byB0aGUgdW5kZXJseWluZworICAgICAqIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIGRlZmxhdGlvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBkZWZsYXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGJ5dGVDb3VudDsKKyAgICAgICAgd2hpbGUgKChieXRlQ291bnQgPSBkZWYuZGVmbGF0ZShidWYpKSAhPSAwKSB7CisgICAgICAgICAgICBvdXQud3JpdGUoYnVmLCAwLCBieXRlQ291bnQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGFueSB1bndyaXR0ZW4gY29tcHJlc3NlZCBkYXRhIHRvIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSwgdGhlIGNsb3NlcworICAgICAqIGFsbCB1bmRlcmx5aW5nIHN0cmVhbXMuIFRoaXMgc3RyZWFtIGNhbiBubyBsb25nZXIgYmUgdXNlZCBhZnRlciBjbG9zZSgpCisgICAgICogaGFzIGJlZW4gY2FsbGVkLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjbG9zaW5nIHRoZSBkYXRhIGNvbXByZXNzaW9uCisgICAgICogICAgICAgICAgICAgcHJvY2Vzcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIGV2ZXJ5dGhpbmcgY2xvc2VkIGhlcmUgc2hvdWxkIGFsc28gYmUgY2xvc2VkIGluIFppcE91dHB1dFN0cmVhbS5jbG9zZSgpCisgICAgICAgIGlmICghZGVmLmZpbmlzaGVkKCkpIHsKKyAgICAgICAgICAgIGZpbmlzaCgpOworICAgICAgICB9CisgICAgICAgIGRlZi5lbmQoKTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGFueSB1bndyaXR0ZW4gZGF0YSB0byB0aGUgdW5kZXJseWluZyBzdHJlYW0uIERvZXMgbm90IGNsb3NlIHRoZQorICAgICAqIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZmluaXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGRvbmUpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBkZWYuZmluaXNoKCk7CisgICAgICAgIHdoaWxlICghZGVmLmZpbmlzaGVkKCkpIHsKKyAgICAgICAgICAgIGludCBieXRlQ291bnQgPSBkZWYuZGVmbGF0ZShidWYpOworICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZiwgMCwgYnl0ZUNvdW50KTsKKyAgICAgICAgfQorICAgICAgICBkb25lID0gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgd3JpdGUoaW50IGkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmVhbXMud3JpdGVTaW5nbGVCeXRlKHRoaXMsIGkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXByZXNzZXMge0Bjb2RlIGJ5dGVDb3VudH0gYnl0ZXMgb2YgZGF0YSBmcm9tIHtAY29kZSBidWZ9IHN0YXJ0aW5nIGF0CisgICAgICoge0Bjb2RlIG9mZnNldH0gYW5kIHdyaXRlcyBpdCB0byB0aGUgdW5kZXJseWluZyBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFuIGVycm9yIG9jY3VycyBkdXJpbmcgd3JpdGluZy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGRvbmUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiYXR0ZW1wdCB0byB3cml0ZSBhZnRlciBmaW5pc2giKTsKKyAgICAgICAgfQorICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXIubGVuZ3RoLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIGlmICghZGVmLm5lZWRzSW5wdXQoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgZGVmLnNldElucHV0KGJ1ZmZlciwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICBkZWZsYXRlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmx1c2hlcyB0aGUgdW5kZXJseWluZyBzdHJlYW0uIFRoaXMgZmx1c2hlcyBvbmx5IHRoZSBieXRlcyB0aGF0IGNhbiBiZQorICAgICAqIGNvbXByZXNzZWQgYXQgdGhlIGhpZ2hlc3QgbGV2ZWwuCisgICAgICoKKyAgICAgKiA8cD5Gb3IgZGVmbGF0ZXIgb3V0cHV0IHN0cmVhbXMgY29uc3RydWN0ZWQgd2l0aCBKYXZhIDcncworICAgICAqIHtAY29kZSBzeW5jRmx1c2h9IHBhcmFtZXRlciBzZXQgdG8gdHJ1ZSAobm90IHlldCBhdmFpbGFibGUgb24gQW5kcm9pZCksCisgICAgICogdGhpcyBmaXJzdCBmbHVzaGVzIGFsbCBvdXRzdGFuZGluZyBkYXRhIHNvIHRoYXQgaXQgbWF5IGJlIGltbWVkaWF0ZWx5CisgICAgICogcmVhZCBieSBpdHMgcmVjaXBpZW50LiBEb2luZyBzbyBtYXkgZGVncmFkZSBjb21wcmVzc2lvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoc3luY0ZsdXNoKSB7CisgICAgICAgICAgICBpbnQgYnl0ZUNvdW50OworICAgICAgICAgICAgd2hpbGUgKChieXRlQ291bnQgPSBkZWYuZGVmbGF0ZShidWYsIDAsIGJ1Zi5sZW5ndGgsIERlZmxhdGVyLlNZTkNfRkxVU0gpKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZiwgMCwgYnl0ZUNvdW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBvdXQuZmx1c2goKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9HWklQSW5wdXRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL0daSVBJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZkNzNhY2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9HWklQSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDIyOCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLnppcDsKKworaW1wb3J0IGphdmEuaW8uRU9GRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5CeXRlT3JkZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBsaWJjb3JlLmlvLk1lbW9yeTsKKworLyoqCisgKiBUaGUge0Bjb2RlIEdaSVBJbnB1dFN0cmVhbX0gY2xhc3MgaXMgdXNlZCB0byByZWFkIGRhdGEgc3RvcmVkIGluIHRoZSBHWklQCisgKiBmb3JtYXQsIHJlYWRpbmcgYW5kIGRlY29tcHJlc3NpbmcgR1pJUCBkYXRhIGZyb20gdGhlIHVuZGVybHlpbmcgc3RyZWFtIGludG8KKyAqIGl0cyBidWZmZXIuCisgKgorICogPGgzPkV4YW1wbGU8L2gzPgorICogPHA+VXNpbmcge0Bjb2RlIEdaSVBJbnB1dFN0cmVhbX0gaXMgZWFzaWVyIHRoYW4ge0BsaW5rIFppcElucHV0U3RyZWFtfQorICogYmVjYXVzZSBHWklQIGlzIG9ubHkgZm9yIGNvbXByZXNzaW9uLCBhbmQgaXMgbm90IGEgY29udGFpbmVyIGZvciBtdWx0aXBsZSBmaWxlcy4KKyAqIFRoaXMgY29kZSBkZWNvbXByZXNzZXMgdGhlIGRhdGEgZnJvbSBhIEdaSVAgc3RyZWFtLCBzaW1pbGFyIHRvIHRoZSB7QGNvZGUgZ3VuemlwKDEpfSB1dGlsaXR5LgorICogPHByZT4KKyAqIElucHV0U3RyZWFtIGlzID0gLi4uCisgKiBHWklQSW5wdXRTdHJlYW0gemlzID0gbmV3IEdaSVBJbnB1dFN0cmVhbShuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShpcykpOworICogdHJ5IHsKKyAqICAgICAvLyBSZWFkaW5nIGZyb20gJ3ppcycgZ2V0cyB5b3UgdGhlIHVuY29tcHJlc3NlZCBieXRlcy4uLgorICogICAgIHByb2Nlc3NTdHJlYW0oemlzKTsKKyAqIH0gZmluYWxseSB7CisgKiAgICAgemlzLmNsb3NlKCk7CisgKiB9CisgKiA8L3ByZT4KKyAqLworcHVibGljIGNsYXNzIEdaSVBJbnB1dFN0cmVhbSBleHRlbmRzIEluZmxhdGVySW5wdXRTdHJlYW0geworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGQ09NTUVOVCA9IDE2OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEZFWFRSQSA9IDQ7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRkhDUkMgPSAyOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEZOQU1FID0gODsKKworICAgIC8qKgorICAgICAqIFRoZSBtYWdpYyBoZWFkZXIgZm9yIHRoZSBHWklQIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBHWklQX01BR0lDID0gMHg4YjFmOworCisgICAgLyoqCisgICAgICogVGhlIGNoZWNrc3VtIGFsZ29yaXRobSB1c2VkIHdoZW4gaGFuZGxpbmcgdW5jb21wcmVzc2VkIGRhdGEuCisgICAgICovCisgICAgcHJvdGVjdGVkIENSQzMyIGNyYyA9IG5ldyBDUkMzMigpOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoZSBlbmQgb2YgdGhlIGlucHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBlb3MgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIHtAY29kZSBHWklQSW5wdXRTdHJlYW19IHRvIHJlYWQgZnJvbSBHWklQIGRhdGEgZnJvbSB0aGUKKyAgICAgKiB1bmRlcmx5aW5nIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpcworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBJbnB1dFN0cmVhbX0gdG8gcmVhZCBkYXRhIGZyb20uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIHtAY29kZSBJT0V4Y2VwdGlvbn0gb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBHWklQSW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMoaXMsIEJVRl9TSVpFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSB7QGNvZGUgR1pJUElucHV0U3RyZWFtfSB0byByZWFkIGZyb20gR1pJUCBkYXRhIGZyb20gdGhlCisgICAgICogdW5kZXJseWluZyBzdHJlYW0uIFNldCB0aGUgaW50ZXJuYWwgYnVmZmVyIHNpemUgdG8ge0Bjb2RlIHNpemV9LgorICAgICAqCisgICAgICogQHBhcmFtIGlzCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIElucHV0U3RyZWFtfSB0byByZWFkIGRhdGEgZnJvbS4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVybmFsIHJlYWQgYnVmZmVyIHNpemUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIHtAY29kZSBJT0V4Y2VwdGlvbn0gb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBHWklQSW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaXMsIGludCBzaXplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihpcywgbmV3IEluZmxhdGVyKHRydWUpLCBzaXplKTsKKyAgICAgICAgYnl0ZVtdIGhlYWRlciA9IG5ldyBieXRlWzEwXTsKKyAgICAgICAgcmVhZEZ1bGx5KGhlYWRlciwgMCwgaGVhZGVyLmxlbmd0aCk7CisgICAgICAgIHNob3J0IG1hZ2ljID0gTWVtb3J5LnBlZWtTaG9ydChoZWFkZXIsIDAsIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKTsKKyAgICAgICAgaWYgKG1hZ2ljICE9IChzaG9ydCkgR1pJUF9NQUdJQykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKFN0cmluZy5mb3JtYXQoInVua25vd24gZm9ybWF0IChtYWdpYyBudW1iZXIgJXgpIiwgbWFnaWMpKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgZmxhZ3MgPSBoZWFkZXJbM107CisgICAgICAgIGJvb2xlYW4gaGNyYyA9IChmbGFncyAmIEZIQ1JDKSAhPSAwOworICAgICAgICBpZiAoaGNyYykgeworICAgICAgICAgICAgY3JjLnVwZGF0ZShoZWFkZXIsIDAsIGhlYWRlci5sZW5ndGgpOworICAgICAgICB9CisgICAgICAgIGlmICgoZmxhZ3MgJiBGRVhUUkEpICE9IDApIHsKKyAgICAgICAgICAgIHJlYWRGdWxseShoZWFkZXIsIDAsIDIpOworICAgICAgICAgICAgaWYgKGhjcmMpIHsKKyAgICAgICAgICAgICAgICBjcmMudXBkYXRlKGhlYWRlciwgMCwgMik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgbGVuZ3RoID0gTWVtb3J5LnBlZWtTaG9ydChoZWFkZXIsIDAsIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSAmIDB4ZmZmZjsKKyAgICAgICAgICAgIHdoaWxlIChsZW5ndGggPiAwKSB7CisgICAgICAgICAgICAgICAgaW50IG1heCA9IGxlbmd0aCA+IGJ1Zi5sZW5ndGggPyBidWYubGVuZ3RoIDogbGVuZ3RoOworICAgICAgICAgICAgICAgIGludCByZXN1bHQgPSBpbi5yZWFkKGJ1ZiwgMCwgbWF4KTsKKyAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGhjcmMpIHsKKyAgICAgICAgICAgICAgICAgICAgY3JjLnVwZGF0ZShidWYsIDAsIHJlc3VsdCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGxlbmd0aCAtPSByZXN1bHQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKChmbGFncyAmIEZOQU1FKSAhPSAwKSB7CisgICAgICAgICAgICByZWFkWmVyb1Rlcm1pbmF0ZWQoaGNyYyk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChmbGFncyAmIEZDT01NRU5UKSAhPSAwKSB7CisgICAgICAgICAgICByZWFkWmVyb1Rlcm1pbmF0ZWQoaGNyYyk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGhjcmMpIHsKKyAgICAgICAgICAgIHJlYWRGdWxseShoZWFkZXIsIDAsIDIpOworICAgICAgICAgICAgc2hvcnQgY3JjMTYgPSBNZW1vcnkucGVla1Nob3J0KGhlYWRlciwgMCwgQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pOworICAgICAgICAgICAgaWYgKChzaG9ydCkgY3JjLmdldFZhbHVlKCkgIT0gY3JjMTYpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNSQyBtaXNtYXRjaCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY3JjLnJlc2V0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhpcyBzdHJlYW0gYW5kIGFueSB1bmRlcmx5aW5nIHN0cmVhbXMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBlb3MgPSB0cnVlOworICAgICAgICBzdXBlci5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGFuZCBkZWNvbXByZXNzZXMgR1pJUCBkYXRhIGZyb20gdGhlIHVuZGVybHlpbmcgc3RyZWFtIGludG8gdGhlCisgICAgICogZ2l2ZW4gYnVmZmVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY2xvc2VkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlN0cmVhbSBpcyBjbG9zZWQiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZW9zKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBieXRlQ291bnQpOworCisgICAgICAgIGludCBieXRlc1JlYWQ7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBieXRlc1JlYWQgPSBzdXBlci5yZWFkKGJ1ZmZlciwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZW9zID0gZW9mOyAvLyB1cGRhdGUgZW9zIGFmdGVyIGV2ZXJ5IHJlYWQoKSwgZXZlbiB3aGVuIGl0IHRocm93cworICAgICAgICB9CisKKyAgICAgICAgaWYgKGJ5dGVzUmVhZCAhPSAtMSkgeworICAgICAgICAgICAgY3JjLnVwZGF0ZShidWZmZXIsIG9mZnNldCwgYnl0ZXNSZWFkKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChlb3MpIHsKKyAgICAgICAgICAgIHZlcmlmeUNyYygpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGJ5dGVzUmVhZDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdmVyaWZ5Q3JjKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gR2V0IG5vbi1jb21wcmVzc2VkIGJ5dGVzIHJlYWQgYnkgZmlsbAorICAgICAgICBpbnQgc2l6ZSA9IGluZi5nZXRSZW1haW5pbmcoKTsKKyAgICAgICAgZmluYWwgaW50IHRyYWlsZXJTaXplID0gODsgLy8gY3JjICg0IGJ5dGVzKSArIHRvdGFsIG91dCAoNCBieXRlcykKKyAgICAgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVt0cmFpbGVyU2l6ZV07CisgICAgICAgIGludCBjb3B5U2l6ZSA9IChzaXplID4gdHJhaWxlclNpemUpID8gdHJhaWxlclNpemUgOiBzaXplOworCisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCBsZW4gLSBzaXplLCBiLCAwLCBjb3B5U2l6ZSk7CisgICAgICAgIHJlYWRGdWxseShiLCBjb3B5U2l6ZSwgdHJhaWxlclNpemUgLSBjb3B5U2l6ZSk7CisKKyAgICAgICAgaWYgKE1lbW9yeS5wZWVrSW50KGIsIDAsIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSAhPSAoaW50KSBjcmMuZ2V0VmFsdWUoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDUkMgbWlzbWF0Y2giKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoTWVtb3J5LnBlZWtJbnQoYiwgNCwgQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pICE9IGluZi5nZXRUb3RhbE91dCgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlNpemUgbWlzbWF0Y2giKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkRnVsbHkoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHJlc3VsdDsKKyAgICAgICAgd2hpbGUgKGxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IGluLnJlYWQoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgICAgICBpZiAocmVzdWx0ID09IC0xKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgb2Zmc2V0ICs9IHJlc3VsdDsKKyAgICAgICAgICAgIGxlbmd0aCAtPSByZXN1bHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZFplcm9UZXJtaW5hdGVkKGJvb2xlYW4gaGNyYykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHJlc3VsdDsKKyAgICAgICAgd2hpbGUgKChyZXN1bHQgPSBpbi5yZWFkKCkpID4gMCkgeworICAgICAgICAgICAgaWYgKGhjcmMpIHsKKyAgICAgICAgICAgICAgICBjcmMudXBkYXRlKHJlc3VsdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJlc3VsdCA9PSAtMSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIC8vIEFkZCB0aGUgemVybworICAgICAgICBpZiAoaGNyYykgeworICAgICAgICAgICAgY3JjLnVwZGF0ZShyZXN1bHQpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvR1pJUE91dHB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvR1pJUE91dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdkMzBhZTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9HWklQT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxMjMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC56aXA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCisvKioKKyAqIFRoZSB7QGNvZGUgR1pJUE91dHB1dFN0cmVhbX0gY2xhc3MgaXMgdXNlZCB0byB3cml0ZSBkYXRhIHRvIGEgc3RyZWFtIGluIHRoZQorICogR1pJUCBzdG9yYWdlIGZvcm1hdC4KKyAqCisgKiA8aDM+RXhhbXBsZTwvaDM+CisgKiA8cD5Vc2luZyB7QGNvZGUgR1pJUE91dHB1dFN0cmVhbX0gaXMgYSBsaXR0bGUgZWFzaWVyIHRoYW4ge0BsaW5rIFppcE91dHB1dFN0cmVhbX0KKyAqIGJlY2F1c2UgR1pJUCBpcyBvbmx5IGZvciBjb21wcmVzc2lvbiwgYW5kIGlzIG5vdCBhIGNvbnRhaW5lciBmb3IgbXVsdGlwbGUgZmlsZXMuCisgKiBUaGlzIGNvZGUgY3JlYXRlcyBhIEdaSVAgc3RyZWFtLCBzaW1pbGFyIHRvIHRoZSB7QGNvZGUgZ3ppcCgxKX0gdXRpbGl0eS4KKyAqIDxwcmU+CisgKiBPdXRwdXRTdHJlYW0gb3MgPSAuLi4KKyAqIGJ5dGVbXSBieXRlcyA9IC4uLgorICogR1pJUE91dHB1dFN0cmVhbSB6b3MgPSBuZXcgR1pJUE91dHB1dFN0cmVhbShuZXcgQnVmZmVyZWRPdXRwdXRTdHJlYW0ob3MpKTsKKyAqIHRyeSB7CisgKiAgICAgem9zLndyaXRlKGJ5dGVzKTsKKyAqIH0gZmluYWxseSB7CisgKiAgICAgem9zLmNsb3NlKCk7CisgKiB9CisgKiA8L3ByZT4KKyAqLworcHVibGljIGNsYXNzIEdaSVBPdXRwdXRTdHJlYW0gZXh0ZW5kcyBEZWZsYXRlck91dHB1dFN0cmVhbSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY2hlY2tzdW0gYWxnb3JpdGhtIHVzZWQgd2hlbiB0cmVhdGluZyB1bmNvbXByZXNzZWQgZGF0YS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ1JDMzIgY3JjID0gbmV3IENSQzMyKCk7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBuZXcge0Bjb2RlIEdaSVBPdXRwdXRTdHJlYW19IHRvIHdyaXRlIGRhdGEgaW4gR1pJUCBmb3JtYXQgdG8KKyAgICAgKiB0aGUgdW5kZXJseWluZyBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT3V0cHV0U3RyZWFtfSB0byB3cml0ZSBkYXRhIHRvLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiB7QGNvZGUgSU9FeGNlcHRpb259IG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgR1pJUE91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMob3MsIEJVRl9TSVpFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBuZXcge0Bjb2RlIEdaSVBPdXRwdXRTdHJlYW19IHRvIHdyaXRlIGRhdGEgaW4gR1pJUCBmb3JtYXQgdG8KKyAgICAgKiB0aGUgdW5kZXJseWluZyBzdHJlYW0uIFNldCB0aGUgaW50ZXJuYWwgY29tcHJlc3Npb24gYnVmZmVyIHRvIHNpemUKKyAgICAgKiB7QGNvZGUgc2l6ZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3MKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT3V0cHV0U3RyZWFtfSB0byB3cml0ZSB0by4KKyAgICAgKiBAcGFyYW0gc2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIGludGVybmFsIGJ1ZmZlciBzaXplLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiB7QGNvZGUgSU9FeGNlcHRpb259IG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgR1pJUE91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3MsIGludCBzaXplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihvcywgbmV3IERlZmxhdGVyKERlZmxhdGVyLkRFRkFVTFRfQ09NUFJFU1NJT04sIHRydWUpLCBzaXplKTsKKyAgICAgICAgd3JpdGVTaG9ydChHWklQSW5wdXRTdHJlYW0uR1pJUF9NQUdJQyk7CisgICAgICAgIG91dC53cml0ZShEZWZsYXRlci5ERUZMQVRFRCk7CisgICAgICAgIG91dC53cml0ZSgwKTsgLy8gZmxhZ3MKKyAgICAgICAgd3JpdGVMb25nKDApOyAvLyBtb2QgdGltZQorICAgICAgICBvdXQud3JpdGUoMCk7IC8vIGV4dHJhIGZsYWdzCisgICAgICAgIG91dC53cml0ZSgwKTsgLy8gb3BlcmF0aW5nIHN5c3RlbQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB0byB0aGUgc3RyZWFtIHRoYXQgYWxsIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBvdXQsIGFuZCBhbnkgR1pJUAorICAgICAqIHRlcm1pbmFsIGRhdGEgY2FuIG5vdyBiZSB3cml0dGVuLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIHtAY29kZSBJT0V4Y2VwdGlvbn0gb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZpbmlzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLmZpbmlzaCgpOworICAgICAgICB3cml0ZUxvbmcoY3JjLmdldFZhbHVlKCkpOworICAgICAgICB3cml0ZUxvbmcoY3JjLnRieXRlcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGUgdXAgdG8gbmJ5dGVzIG9mIGRhdGEgZnJvbSB0aGUgZ2l2ZW4gYnVmZmVyLCBzdGFydGluZyBhdCBvZmZzZXQgb2ZmLAorICAgICAqIHRvIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBpbiBHWklQIGZvcm1hdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYnVmZmVyLCBpbnQgb2ZmLCBpbnQgbmJ5dGVzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlci53cml0ZShidWZmZXIsIG9mZiwgbmJ5dGVzKTsKKyAgICAgICAgY3JjLnVwZGF0ZShidWZmZXIsIG9mZiwgbmJ5dGVzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGxvbmcgd3JpdGVMb25nKGxvbmcgaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gV3JpdGUgb3V0IHRoZSBsb25nIHZhbHVlIGFzIGFuIHVuc2lnbmVkIGludAorICAgICAgICBpbnQgdW5zaWduZWQgPSAoaW50KSBpOworICAgICAgICBvdXQud3JpdGUodW5zaWduZWQgJiAweEZGKTsKKyAgICAgICAgb3V0LndyaXRlKCh1bnNpZ25lZCA+PiA4KSAmIDB4RkYpOworICAgICAgICBvdXQud3JpdGUoKHVuc2lnbmVkID4+IDE2KSAmIDB4RkYpOworICAgICAgICBvdXQud3JpdGUoKHVuc2lnbmVkID4+IDI0KSAmIDB4RkYpOworICAgICAgICByZXR1cm4gaTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCB3cml0ZVNob3J0KGludCBpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXQud3JpdGUoaSAmIDB4RkYpOworICAgICAgICBvdXQud3JpdGUoKGkgPj4gOCkgJiAweEZGKTsKKyAgICAgICAgcmV0dXJuIGk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvSW5mbGF0ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL0luZmxhdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWUxMGFhNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL0luZmxhdGVyLmphdmEKQEAgLTAsMCArMSwzMjYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC56aXA7CisKK2ltcG9ydCBkYWx2aWsuc3lzdGVtLkNsb3NlR3VhcmQ7CitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIFRoaXMgY2xhc3MgZGVjb21wcmVzc2VzIGRhdGEgdGhhdCB3YXMgY29tcHJlc3NlZCB1c2luZyB0aGUgPGk+REVGTEFURTwvaT4KKyAqIGFsZ29yaXRobSAoc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuZ3ppcC5vcmcvYWxnb3JpdGhtLnR4dCI+c3BlY2lmaWNhdGlvbjwvYT4pLgorICoKKyAqIDxwPkl0IGlzIHVzdWFsbHkgbW9yZSBjb252ZW5pZW50IHRvIHVzZSB7QGxpbmsgSW5mbGF0ZXJJbnB1dFN0cmVhbX0uCisgKgorICogPHA+VG8gZGVjb21wcmVzcyBhbiBpbi1tZW1vcnkge0Bjb2RlIGJ5dGVbXX0gdG8gYW5vdGhlciBpbi1tZW1vcnkge0Bjb2RlIGJ5dGVbXX0gbWFudWFsbHk6CisgKiA8cHJlPgorICogICAgIGJ5dGVbXSBjb21wcmVzc2VkQnl0ZXMgPSAuLi4KKyAqICAgICBpbnQgZGVjb21wcmVzc2VkQnl0ZUNvdW50ID0gLi4uIC8vIEZyb20geW91ciBmb3JtYXQncyBtZXRhZGF0YS4KKyAqICAgICBJbmZsYXRlciBpbmZsYXRlciA9IG5ldyBJbmZsYXRlcigpOworICogICAgIGluZmxhdGVyLnNldElucHV0KGNvbXByZXNzZWRCeXRlcywgMCwgY29tcHJlc3NlZEJ5dGVzLmxlbmd0aCk7CisgKiAgICAgYnl0ZVtdIGRlY29tcHJlc3NlZEJ5dGVzID0gbmV3IGJ5dGVbZGVjb21wcmVzc2VkQnl0ZUNvdW50XTsKKyAqICAgICBpZiAoaW5mbGF0ZXIuaW5mbGF0ZShkZWNvbXByZXNzZWRCeXRlcykgIT0gZGVjb21wcmVzc2VkQnl0ZUNvdW50KSB7CisgKiAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICogICAgIH0KKyAqICAgICBpbmZsYXRlci5lbmQoKTsKKyAqIDwvcHJlPgorICogPHA+SW4gc2l0dWF0aW9ucyB3aGVyZSB5b3UgZG9uJ3QgaGF2ZSBhbGwgdGhlIGlucHV0IGluIG9uZSBhcnJheSAob3IgaGF2ZSBzbyBtdWNoCisgKiBpbnB1dCB0aGF0IHlvdSB3YW50IHRvIGZlZWQgaXQgdG8gdGhlIGluZmxhdGVyIGluIGNodW5rcyksIGl0J3MgcG9zc2libGUgdG8gY2FsbAorICoge0BsaW5rICNzZXRJbnB1dH0gcmVwZWF0ZWRseSwgYnV0IHlvdSdyZSBtdWNoIGJldHRlciBvZmYgdXNpbmcge0BsaW5rIEluZmxhdGVySW5wdXRTdHJlYW19CisgKiB0byBoYW5kbGUgYWxsIHRoaXMgZm9yIHlvdS4KKyAqCisgKiA8cD5JZiB5b3UgZG9uJ3Qga25vdyBob3cgYmlnIHRoZSBkZWNvbXByZXNzZWQgZGF0YSB3aWxsIGJlLCB5b3UgY2FuIGNhbGwge0BsaW5rICNpbmZsYXRlfQorICogcmVwZWF0ZWRseSBvbiBhIHRlbXBvcmFyeSBidWZmZXIsIGNvcHlpbmcgdGhlIGJ5dGVzIHRvIGEge0BsaW5rIGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtfSwKKyAqIGJ1dCB0aGlzIGlzIHByb2JhYmx5IGFub3RoZXIgc2lnbiB5b3UnZCBiZSBiZXR0ZXIgb2ZmIHVzaW5nIHtAbGluayBJbmZsYXRlcklucHV0U3RyZWFtfS4KKyAqLworcHVibGljIGNsYXNzIEluZmxhdGVyIHsKKworICAgIHByaXZhdGUgaW50IGluTGVuZ3RoOworCisgICAgcHJpdmF0ZSBpbnQgaW5SZWFkOyAvLyBTZXQgYnkgaW5mbGF0ZUltcGwuCisgICAgcHJpdmF0ZSBib29sZWFuIGZpbmlzaGVkOyAvLyBTZXQgYnkgaW5mbGF0ZUltcGwuCisgICAgcHJpdmF0ZSBib29sZWFuIG5lZWRzRGljdGlvbmFyeTsgLy8gU2V0IGJ5IGluZmxhdGVJbXBsLgorCisgICAgcHJpdmF0ZSBsb25nIHN0cmVhbUhhbmRsZSA9IC0xOworCisgICAgcHJpdmF0ZSBmaW5hbCBDbG9zZUd1YXJkIGd1YXJkID0gQ2xvc2VHdWFyZC5nZXQoKTsKKworICAgIC8qKgorICAgICAqIFRoaXMgY29uc3RydWN0b3IgY3JlYXRlcyBhbiBpbmZsYXRlciB0aGF0IGV4cGVjdHMgYSBoZWFkZXIgZnJvbSB0aGUgaW5wdXQKKyAgICAgKiBzdHJlYW0uIFVzZSB7QGxpbmsgI0luZmxhdGVyKGJvb2xlYW4pfSBpZiB0aGUgaW5wdXQgY29tZXMgd2l0aG91dCBhIFpMSUIKKyAgICAgKiBoZWFkZXIuCisgICAgICovCisgICAgcHVibGljIEluZmxhdGVyKCkgeworICAgICAgICB0aGlzKGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNvbnN0cnVjdG9yIGFsbG93cyB0byBjcmVhdGUgYW4gaW5mbGF0ZXIgdGhhdCBleHBlY3RzIG5vIGhlYWRlciBmcm9tCisgICAgICogdGhlIGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBub0hlYWRlcgorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGluZGljYXRlcyB0aGF0IG5vIFpMSUIgaGVhZGVyIGNvbWVzIHdpdGggdGhlCisgICAgICogICAgICAgICAgICBpbnB1dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5mbGF0ZXIoYm9vbGVhbiBub0hlYWRlcikgeworICAgICAgICBzdHJlYW1IYW5kbGUgPSBjcmVhdGVTdHJlYW0obm9IZWFkZXIpOworICAgICAgICBndWFyZC5vcGVuKCJlbmQiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIG5hdGl2ZSBsb25nIGNyZWF0ZVN0cmVhbShib29sZWFuIG5vSGVhZGVyMSk7CisKKyAgICAvKioKKyAgICAgKiBSZWxlYXNlcyByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMge0Bjb2RlIEluZmxhdGVyfS4gQW55IHVudXNlZAorICAgICAqIGlucHV0IG9yIG91dHB1dCBpcyBkaXNjYXJkZWQuIFRoaXMgbWV0aG9kIHNob3VsZCBiZSBjYWxsZWQgZXhwbGljaXRseSBpbgorICAgICAqIG9yZGVyIHRvIGZyZWUgbmF0aXZlIHJlc291cmNlcyBhcyBzb29uIGFzIHBvc3NpYmxlLiBBZnRlciB7QGNvZGUgZW5kKCl9IGlzCisgICAgICogY2FsbGVkLCBvdGhlciBtZXRob2RzIHdpbGwgdHlwaWNhbGx5IHRocm93IHtAY29kZSBJbGxlZ2FsU3RhdGVFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBlbmQoKSB7CisgICAgICAgIGd1YXJkLmNsb3NlKCk7CisgICAgICAgIGlmIChzdHJlYW1IYW5kbGUgIT0gLTEpIHsKKyAgICAgICAgICAgIGVuZEltcGwoc3RyZWFtSGFuZGxlKTsKKyAgICAgICAgICAgIGluUmVhZCA9IDA7CisgICAgICAgICAgICBpbkxlbmd0aCA9IDA7CisgICAgICAgICAgICBzdHJlYW1IYW5kbGUgPSAtMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgbmF0aXZlIHZvaWQgZW5kSW1wbChsb25nIGhhbmRsZSk7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoZ3VhcmQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGd1YXJkLndhcm5JZk9wZW4oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVuZCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdXBlci5maW5hbGl6ZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIHtAY29kZSBJbmZsYXRlcn0gaGFzIGluZmxhdGVkIHRoZSBlbnRpcmUgZGVmbGF0ZWQKKyAgICAgKiBzdHJlYW0uIElmIGRlZmxhdGVkIGJ5dGVzIHJlbWFpbiBhbmQge0BsaW5rICNuZWVkc0lucHV0fSByZXR1cm5zIHtAY29kZQorICAgICAqIHRydWV9IHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIHtAY29kZSBmYWxzZX0uIFRoaXMgbWV0aG9kIHNob3VsZCBiZQorICAgICAqIGNhbGxlZCBhZnRlciBhbGwgZGVmbGF0ZWQgaW5wdXQgaXMgc3VwcGxpZWQgdG8gdGhlIHtAY29kZSBJbmZsYXRlcn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBhbGwgaW5wdXQgaGFzIGJlZW4gaW5mbGF0ZWQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gZmluaXNoZWQoKSB7CisgICAgICAgIHJldHVybiBmaW5pc2hlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGxpbmsgQWRsZXIzMn0gY2hlY2tzdW0gb2YgdGhlIGJ5dGVzIGluZmxhdGVkIHNvIGZhciwgb3IgdGhlCisgICAgICogY2hlY2tzdW0gb2YgdGhlIHByZXNldCBkaWN0aW9uYXJ5IGlmIHtAbGluayAjbmVlZHNEaWN0aW9uYXJ5fSByZXR1cm5zIHRydWUuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0QWRsZXIoKSB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICByZXR1cm4gZ2V0QWRsZXJJbXBsKHN0cmVhbUhhbmRsZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBuYXRpdmUgaW50IGdldEFkbGVySW1wbChsb25nIGhhbmRsZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZCBieSB0aGUge0Bjb2RlIEluZmxhdGVyfS4gVGhpcworICAgICAqIG1ldGhvZCBpcyB0aGUgc2FtZSBhcyB7QGxpbmsgI2dldFRvdGFsSW59IGV4Y2VwdCB0aGF0IGl0IHJldHVybnMgYQorICAgICAqIHtAY29kZSBsb25nfSB2YWx1ZSBpbnN0ZWFkIG9mIGFuIGludGVnZXIuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBsb25nIGdldEJ5dGVzUmVhZCgpIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIHJldHVybiBnZXRUb3RhbEluSW1wbChzdHJlYW1IYW5kbGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB0aGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gYnkgdGhpcyB7QGNvZGUgSW5mbGF0ZXJ9LiBUaGlzCisgICAgICogbWV0aG9kIGlzIHRoZSBzYW1lIGFzIHtAY29kZSBnZXRUb3RhbE91dH0gZXhjZXB0IGl0IHJldHVybnMgYQorICAgICAqIHtAY29kZSBsb25nfSB2YWx1ZSBpbnN0ZWFkIG9mIGFuIGludGVnZXIuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBsb25nIGdldEJ5dGVzV3JpdHRlbigpIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIHJldHVybiBnZXRUb3RhbE91dEltcGwoc3RyZWFtSGFuZGxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgb2YgY3VycmVudCBpbnB1dCByZW1haW5pbmcgdG8gYmUgcmVhZCBieSB0aGlzCisgICAgICogaW5mbGF0ZXIuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0UmVtYWluaW5nKCkgeworICAgICAgICByZXR1cm4gaW5MZW5ndGggLSBpblJlYWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIG9mIGlucHV0IHJlYWQgYnkgdGhpcyB7QGNvZGUgSW5mbGF0ZXJ9LiBUaGlzCisgICAgICogbWV0aG9kIGlzIGxpbWl0ZWQgdG8gMzIgYml0czsgdXNlIHtAbGluayAjZ2V0Qnl0ZXNSZWFkfSBpbnN0ZWFkLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldFRvdGFsSW4oKSB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICByZXR1cm4gKGludCkgTWF0aC5taW4oZ2V0VG90YWxJbkltcGwoc3RyZWFtSGFuZGxlKSwgKGxvbmcpIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICB9CisKKyAgICBwcml2YXRlIG5hdGl2ZSBsb25nIGdldFRvdGFsSW5JbXBsKGxvbmcgaGFuZGxlKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuIHRvIHRoZSBvdXRwdXQgYnVmZmVyIGJ5IHRoaXMge0Bjb2RlCisgICAgICogSW5mbGF0ZXJ9LiBUaGUgbWV0aG9kIGlzIGxpbWl0ZWQgdG8gMzIgYml0czsgdXNlIHtAbGluayAjZ2V0Qnl0ZXNXcml0dGVufSBpbnN0ZWFkLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldFRvdGFsT3V0KCkgeworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgcmV0dXJuIChpbnQpIE1hdGgubWluKGdldFRvdGFsT3V0SW1wbChzdHJlYW1IYW5kbGUpLCAobG9uZykgSW50ZWdlci5NQVhfVkFMVUUpOworICAgIH0KKworICAgIHByaXZhdGUgbmF0aXZlIGxvbmcgZ2V0VG90YWxPdXRJbXBsKGxvbmcgaGFuZGxlKTsKKworICAgIC8qKgorICAgICAqIEluZmxhdGVzIGJ5dGVzIGZyb20gdGhlIGN1cnJlbnQgaW5wdXQgYW5kIHN0b3JlcyB0aGVtIGluIHtAY29kZSBidWZ9LgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZgorICAgICAqICAgICAgICAgICAgdGhlIGJ1ZmZlciB3aGVyZSBkZWNvbXByZXNzZWQgZGF0YSBieXRlcyBhcmUgd3JpdHRlbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW5mbGF0ZWQuCisgICAgICogQHRocm93cyBEYXRhRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHVuZGVybHlpbmcgc3RyZWFtIGlzIGNvcnJ1cHRlZCBvciB3YXMgbm90IGNvbXByZXNzZWQKKyAgICAgKiAgICAgICAgICAgICB1c2luZyBhIHtAY29kZSBEZWZsYXRlcn0uCisgICAgICovCisgICAgcHVibGljIGludCBpbmZsYXRlKGJ5dGVbXSBidWYpIHRocm93cyBEYXRhRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGluZmxhdGUoYnVmLCAwLCBidWYubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmZsYXRlcyB1cCB0byB7QGNvZGUgYnl0ZUNvdW50fSBieXRlcyBmcm9tIHRoZSBjdXJyZW50IGlucHV0IGFuZCBzdG9yZXMgdGhlbSBpbgorICAgICAqIHtAY29kZSBidWZ9IHN0YXJ0aW5nIGF0IHtAY29kZSBvZmZzZXR9LgorICAgICAqCisgICAgICogQHRocm93cyBEYXRhRm9ybWF0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHVuZGVybHlpbmcgc3RyZWFtIGlzIGNvcnJ1cHRlZCBvciB3YXMgbm90IGNvbXByZXNzZWQKKyAgICAgKiAgICAgICAgICAgICB1c2luZyBhIHtAY29kZSBEZWZsYXRlcn0uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGluZmxhdGVkLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGluZmxhdGUoYnl0ZVtdIGJ1ZiwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCkgdGhyb3dzIERhdGFGb3JtYXRFeGNlcHRpb24geworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWYubGVuZ3RoLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisKKyAgICAgICAgY2hlY2tPcGVuKCk7CisKKyAgICAgICAgaWYgKG5lZWRzSW5wdXQoKSkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIG5lZWRlZERpY3QgPSBuZWVkc0RpY3Rpb25hcnk7CisgICAgICAgIG5lZWRzRGljdGlvbmFyeSA9IGZhbHNlOworICAgICAgICBpbnQgcmVzdWx0ID0gaW5mbGF0ZUltcGwoYnVmLCBvZmZzZXQsIGJ5dGVDb3VudCwgc3RyZWFtSGFuZGxlKTsKKyAgICAgICAgaWYgKG5lZWRzRGljdGlvbmFyeSAmJiBuZWVkZWREaWN0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRGF0YUZvcm1hdEV4Y2VwdGlvbigiTmVlZHMgZGljdGlvbmFyeSIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBuYXRpdmUgaW50IGluZmxhdGVJbXBsKGJ5dGVbXSBidWYsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQsIGxvbmcgaGFuZGxlKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgaW5wdXQgYnl0ZXMgd2VyZSBjb21wcmVzc2VkIHdpdGggYSBwcmVzZXQKKyAgICAgKiBkaWN0aW9uYXJ5LiBUaGlzIG1ldGhvZCBzaG91bGQgYmUgY2FsbGVkIGlmIHRoZSBmaXJzdCBjYWxsIHRvIHtAbGluayAjaW5mbGF0ZX0gcmV0dXJucyAwLAorICAgICAqIHRvIGRldGVybWluZSB3aGV0aGVyIGEgZGljdGlvbmFyeSBpcyByZXF1aXJlZC4gSWYgc28sIHtAbGluayAjc2V0RGljdGlvbmFyeX0KKyAgICAgKiBzaG91bGQgYmUgY2FsbGVkIHdpdGggdGhlIGFwcHJvcHJpYXRlIGRpY3Rpb25hcnkgYmVmb3JlIGNhbGxpbmcge0Bjb2RlCisgICAgICogaW5mbGF0ZX0gYWdhaW4uIFVzZSB7QGxpbmsgI2dldEFkbGVyfSB0byBkZXRlcm1pbmUgd2hpY2ggZGljdGlvbmFyeSBpcyByZXF1aXJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gbmVlZHNEaWN0aW9uYXJ5KCkgeworICAgICAgICByZXR1cm4gbmVlZHNEaWN0aW9uYXJ5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB7QGxpbmsgI3NldElucHV0fSBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgaW5mbGF0aW9uIGNhbiBjb250aW51ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gbmVlZHNJbnB1dCgpIHsKKyAgICAgICAgcmV0dXJuIGluUmVhZCA9PSBpbkxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhpcyB7QGNvZGUgSW5mbGF0ZXJ9LiBTaG91bGQgYmUgY2FsbGVkIHByaW9yIHRvIGluZmxhdGluZyBhIG5ldworICAgICAqIHNldCBvZiBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZXNldCgpIHsKKyAgICAgICAgY2hlY2tPcGVuKCk7CisgICAgICAgIGZpbmlzaGVkID0gZmFsc2U7CisgICAgICAgIG5lZWRzRGljdGlvbmFyeSA9IGZhbHNlOworICAgICAgICBpbkxlbmd0aCA9IGluUmVhZCA9IDA7CisgICAgICAgIHJlc2V0SW1wbChzdHJlYW1IYW5kbGUpOworICAgIH0KKworICAgIHByaXZhdGUgbmF0aXZlIHZvaWQgcmVzZXRJbXBsKGxvbmcgaGFuZGxlKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHByZXNldCBkaWN0aW9uYXJ5IHRvIGJlIHVzZWQgZm9yIGluZmxhdGlvbiB0byB7QGNvZGUgZGljdGlvbmFyeX0uCisgICAgICogU2VlIHtAbGluayAjbmVlZHNEaWN0aW9uYXJ5fSBmb3IgZGV0YWlscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0RGljdGlvbmFyeShieXRlW10gZGljdGlvbmFyeSkgeworICAgICAgICBzZXREaWN0aW9uYXJ5KGRpY3Rpb25hcnksIDAsIGRpY3Rpb25hcnkubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwcmVzZXQgZGljdGlvbmFyeSB0byBiZSB1c2VkIGZvciBpbmZsYXRpb24gdG8gYSBzdWJzZXF1ZW5jZSBvZiB7QGNvZGUgZGljdGlvbmFyeX0KKyAgICAgKiBzdGFydGluZyBhdCB7QGNvZGUgb2Zmc2V0fSBhbmQgY29udGludWluZyBmb3Ige0Bjb2RlIGJ5dGVDb3VudH0gYnl0ZXMuIFNlZSB7QGxpbmsKKyAgICAgKiAjbmVlZHNEaWN0aW9uYXJ5fSBmb3IgZGV0YWlscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0RGljdGlvbmFyeShieXRlW10gZGljdGlvbmFyeSwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCkgeworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoZGljdGlvbmFyeS5sZW5ndGgsIG9mZnNldCwgYnl0ZUNvdW50KTsKKyAgICAgICAgc2V0RGljdGlvbmFyeUltcGwoZGljdGlvbmFyeSwgb2Zmc2V0LCBieXRlQ291bnQsIHN0cmVhbUhhbmRsZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBuYXRpdmUgdm9pZCBzZXREaWN0aW9uYXJ5SW1wbChieXRlW10gZGljdGlvbmFyeSwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCwgbG9uZyBoYW5kbGUpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY3VycmVudCBpbnB1dCB0byB0byBiZSBkZWNvbXByZXNzZWQuIFRoaXMgbWV0aG9kIHNob3VsZCBvbmx5IGJlCisgICAgICogY2FsbGVkIGlmIHtAbGluayAjbmVlZHNJbnB1dH0gcmV0dXJucyB7QGNvZGUgdHJ1ZX0uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldElucHV0KGJ5dGVbXSBidWYpIHsKKyAgICAgICAgc2V0SW5wdXQoYnVmLCAwLCBidWYubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjdXJyZW50IGlucHV0IHRvIHRvIGJlIGRlY29tcHJlc3NlZC4gVGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUKKyAgICAgKiBjYWxsZWQgaWYge0BsaW5rICNuZWVkc0lucHV0fSByZXR1cm5zIHtAY29kZSB0cnVlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0SW5wdXQoYnl0ZVtdIGJ1ZiwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCkgeworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmLmxlbmd0aCwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICBpblJlYWQgPSAwOworICAgICAgICBpbkxlbmd0aCA9IGJ5dGVDb3VudDsKKyAgICAgICAgc2V0SW5wdXRJbXBsKGJ1Ziwgb2Zmc2V0LCBieXRlQ291bnQsIHN0cmVhbUhhbmRsZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBuYXRpdmUgdm9pZCBzZXRJbnB1dEltcGwoYnl0ZVtdIGJ1ZiwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCwgbG9uZyBoYW5kbGUpOworCisgICAgc3luY2hyb25pemVkIGludCBzZXRGaWxlSW5wdXQoRmlsZURlc2NyaXB0b3IgZmQsIGxvbmcgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBpblJlYWQgPSAwOworICAgICAgICBpbkxlbmd0aCA9IHNldEZpbGVJbnB1dEltcGwoZmQsIG9mZnNldCwgYnl0ZUNvdW50LCBzdHJlYW1IYW5kbGUpOworICAgICAgICByZXR1cm4gaW5MZW5ndGg7CisgICAgfQorCisgICAgcHJpdmF0ZSBuYXRpdmUgaW50IHNldEZpbGVJbnB1dEltcGwoRmlsZURlc2NyaXB0b3IgZmQsIGxvbmcgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50LCBsb25nIGhhbmRsZSk7CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tPcGVuKCkgeworICAgICAgICBpZiAoc3RyZWFtSGFuZGxlID09IC0xKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJhdHRlbXB0IHRvIHVzZSBJbmZsYXRlciBhZnRlciBjYWxsaW5nIGVuZCIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvSW5mbGF0ZXJJbnB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvSW5mbGF0ZXJJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU4MGQ2MDUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9JbmZsYXRlcklucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwzMDEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC56aXA7CisKK2ltcG9ydCBqYXZhLmlvLkVPRkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGxpYmNvcmUuaW8uU3RyZWFtczsKKworLyoqCisgKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGFuIGltcGxlbWVudGF0aW9uIG9mIHtAY29kZSBGaWx0ZXJJbnB1dFN0cmVhbX0gdGhhdAorICogZGVjb21wcmVzc2VzIGRhdGEgdGhhdCB3YXMgY29tcHJlc3NlZCB1c2luZyB0aGUgPGk+REVGTEFURTwvaT4gYWxnb3JpdGhtCisgKiAoc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuZ3ppcC5vcmcvYWxnb3JpdGhtLnR4dCI+c3BlY2lmaWNhdGlvbjwvYT4pLgorICogQmFzaWNhbGx5IGl0IHdyYXBzIHRoZSB7QGNvZGUgSW5mbGF0ZXJ9IGNsYXNzIGFuZCB0YWtlcyBjYXJlIG9mIHRoZQorICogYnVmZmVyaW5nLgorICoKKyAqIEBzZWUgSW5mbGF0ZXIKKyAqIEBzZWUgRGVmbGF0ZXJPdXRwdXRTdHJlYW0KKyAqLworcHVibGljIGNsYXNzIEluZmxhdGVySW5wdXRTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJJbnB1dFN0cmVhbSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW5mbGF0ZXIgdXNlZCBmb3IgdGhpcyBzdHJlYW0uCisgICAgICovCisgICAgcHJvdGVjdGVkIEluZmxhdGVyIGluZjsKKworICAgIC8qKgorICAgICAqIFRoZSBpbnB1dCBidWZmZXIgdXNlZCBmb3IgZGVjb21wcmVzc2lvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIGJ1ZjsKKworICAgIC8qKgorICAgICAqIFRoZSBsZW5ndGggb2YgdGhlIGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGxlbjsKKworICAgIGJvb2xlYW4gY2xvc2VkOworCisgICAgLyoqCisgICAgICogVHJ1ZSBpZiB0aGlzIHN0cmVhbSdzIGxhc3QgYnl0ZSBoYXMgYmVlbiByZXR1cm5lZCB0byB0aGUgdXNlci4gVGhpcworICAgICAqIGNvdWxkIGJlIGJlY2F1c2UgdGhlIHVuZGVybHlpbmcgc3RyZWFtIGhhcyBiZWVuIGV4aGF1c3RlZCwgb3IgaWYgZXJyb3JzCisgICAgICogd2VyZSBlbmNvdW50ZXJlZCB3aGlsZSBpbmZsYXRpbmcgdGhhdCBzdHJlYW0uCisgICAgICovCisgICAgYm9vbGVhbiBlb2Y7CisKKyAgICBzdGF0aWMgZmluYWwgaW50IEJVRl9TSVpFID0gNTEyOworCisgICAgaW50IG5hdGl2ZUVuZEJ1ZlNpemUgPSAwOworCisgICAgLyoqCisgICAgICogVGhpcyBpcyB0aGUgbW9zdCBiYXNpYyBjb25zdHJ1Y3Rvci4gWW91IG9ubHkgbmVlZCB0byBwYXNzIHRoZSB7QGNvZGUKKyAgICAgKiBJbnB1dFN0cmVhbX0gZnJvbSB3aGljaCB0aGUgY29tcHJlc3NlZCBkYXRhIGlzIHRvIGJlIHJlYWQgZnJvbS4gRGVmYXVsdAorICAgICAqIHNldHRpbmdzIGZvciB0aGUge0Bjb2RlIEluZmxhdGVyfSBhbmQgaW50ZXJuYWwgYnVmZmVyIGFyZSBiZSB1c2VkLiBJbgorICAgICAqIHBhcnRpY3VsYXIgdGhlIEluZmxhdGVyIGV4cGVjdHMgYSBaTElCIGhlYWRlciBmcm9tIHRoZSBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXMKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgSW5wdXRTdHJlYW19IHRvIHJlYWQgZGF0YSBmcm9tLgorICAgICAqLworICAgIHB1YmxpYyBJbmZsYXRlcklucHV0U3RyZWFtKElucHV0U3RyZWFtIGlzKSB7CisgICAgICAgIHRoaXMoaXMsIG5ldyBJbmZsYXRlcigpLCBCVUZfU0laRSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBjb25zdHJ1Y3RvciBsZXRzIHlvdSBwYXNzIGEgc3BlY2lmaWNhbGx5IGluaXRpYWxpemVkIEluZmxhdGVyLAorICAgICAqIGZvciBleGFtcGxlIG9uZSB0aGF0IGV4cGVjdHMgbm8gWkxJQiBoZWFkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXMKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgSW5wdXRTdHJlYW19IHRvIHJlYWQgZGF0YSBmcm9tLgorICAgICAqIEBwYXJhbSBpbmZsYXRlcgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmljIHtAY29kZSBJbmZsYXRlcn0gZm9yIGRlY29tcHJlc3NpbmcgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5mbGF0ZXJJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpcywgSW5mbGF0ZXIgaW5mbGF0ZXIpIHsKKyAgICAgICAgdGhpcyhpcywgaW5mbGF0ZXIsIEJVRl9TSVpFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNvbnN0cnVjdG9yIGxldHMgeW91IHNwZWNpZnkgYm90aCB0aGUge0Bjb2RlIEluZmxhdGVyfSBhcyB3ZWxsIGFzCisgICAgICogdGhlIGludGVybmFsIGJ1ZmZlciBzaXplIHRvIGJlIHVzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXMKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgSW5wdXRTdHJlYW19IHRvIHJlYWQgZGF0YSBmcm9tLgorICAgICAqIEBwYXJhbSBpbmZsYXRlcgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmljIHtAY29kZSBJbmZsYXRlcn0gZm9yIGRlY29tcHJlc3NpbmcgZGF0YS4KKyAgICAgKiBAcGFyYW0gYnNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaXplIHRvIGJlIHVzZWQgZm9yIHRoZSBpbnRlcm5hbCBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIEluZmxhdGVySW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaXMsIEluZmxhdGVyIGluZmxhdGVyLCBpbnQgYnNpemUpIHsKKyAgICAgICAgc3VwZXIoaXMpOworICAgICAgICBpZiAoaXMgPT0gbnVsbCB8fCBpbmZsYXRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYnNpemUgPD0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMuaW5mID0gaW5mbGF0ZXI7CisgICAgICAgIGlmIChpcyBpbnN0YW5jZW9mIFppcEZpbGUuUkFGU3RyZWFtKSB7CisgICAgICAgICAgICBuYXRpdmVFbmRCdWZTaXplID0gYnNpemU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBidWYgPSBuZXcgYnl0ZVtic2l6ZV07CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHNpbmdsZSBieXRlIG9mIGRlY29tcHJlc3NlZCBkYXRhLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYnl0ZSByZWFkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgcmVhZGluZyB0aGUgYnl0ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIFN0cmVhbXMucmVhZFNpbmdsZUJ5dGUodGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdXAgdG8ge0Bjb2RlIGJ5dGVDb3VudH0gYnl0ZXMgb2YgZGVjb21wcmVzc2VkIGRhdGEgYW5kIHN0b3JlcyBpdCBpbgorICAgICAqIHtAY29kZSBidWZmZXJ9IHN0YXJ0aW5nIGF0IHtAY29kZSBvZmZzZXR9LgorICAgICAqCisgICAgICogQHJldHVybiBOdW1iZXIgb2YgdW5jb21wcmVzc2VkIGJ5dGVzIHJlYWQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tDbG9zZWQoKTsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBieXRlQ291bnQpOworCisgICAgICAgIGlmIChieXRlQ291bnQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZW9mKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKworICAgICAgICBkbyB7CisgICAgICAgICAgICBpZiAoaW5mLm5lZWRzSW5wdXQoKSkgeworICAgICAgICAgICAgICAgIGZpbGwoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIEludmFyaWFudDogaWYgcmVhZGluZyByZXR1cm5zIC0xIG9yIHRocm93cywgZW9mIG11c3QgYmUgdHJ1ZS4KKyAgICAgICAgICAgIC8vIEl0IG1heSBhbHNvIGJlIHRydWUgaWYgdGhlIG5leHQgcmVhZCgpIHNob3VsZCByZXR1cm4gLTEuCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGludCByZXN1bHQgPSBpbmYuaW5mbGF0ZShidWZmZXIsIG9mZnNldCwgYnl0ZUNvdW50KTsKKyAgICAgICAgICAgICAgICBlb2YgPSBpbmYuZmluaXNoZWQoKTsKKyAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID4gMCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZW9mKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluZi5uZWVkc0RpY3Rpb25hcnkoKSkgeworICAgICAgICAgICAgICAgICAgICBlb2YgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChsZW4gPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgZW9mID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgICAgICAvLyBJZiByZXN1bHQgPT0gMCwgZmlsbCgpIGFuZCB0cnkgYWdhaW4KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChEYXRhRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBlb2YgPSB0cnVlOworICAgICAgICAgICAgICAgIGlmIChsZW4gPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aHJvdyAoSU9FeGNlcHRpb24pIChuZXcgSU9FeGNlcHRpb24oKS5pbml0Q2F1c2UoZSkpOworICAgICAgICAgICAgfQorICAgICAgICB9IHdoaWxlICh0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaWxscyB0aGUgaW5wdXQgYnVmZmVyIHdpdGggZGF0YSB0byBiZSBkZWNvbXByZXNzZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4ge0Bjb2RlIElPRXhjZXB0aW9ufSBvY2N1cnMuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgZmlsbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrQ2xvc2VkKCk7CisgICAgICAgIGlmIChuYXRpdmVFbmRCdWZTaXplID4gMCkgeworICAgICAgICAgICAgWmlwRmlsZS5SQUZTdHJlYW0gaXMgPSAoWmlwRmlsZS5SQUZTdHJlYW0paW47CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGlzLm1TaGFyZWRSYWYpIHsKKyAgICAgICAgICAgICAgICBsb25nIGxlbiA9IGlzLm1MZW5ndGggLSBpcy5tT2Zmc2V0OworICAgICAgICAgICAgICAgIGlmIChsZW4gPiBuYXRpdmVFbmRCdWZTaXplKSBsZW4gPSBuYXRpdmVFbmRCdWZTaXplOworICAgICAgICAgICAgICAgIGludCBjbnQgPSBpbmYuc2V0RmlsZUlucHV0KGlzLm1TaGFyZWRSYWYuZ2V0RkQoKSwgaXMubU9mZnNldCwgbmF0aXZlRW5kQnVmU2l6ZSk7CisgICAgICAgICAgICAgICAgaXMuc2tpcChjbnQpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKChsZW4gPSBpbi5yZWFkKGJ1ZikpID4gMCkgeworICAgICAgICAgICAgICAgIGluZi5zZXRJbnB1dChidWYsIDAsIGxlbik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTa2lwcyB1cCB0byB7QGNvZGUgYnl0ZUNvdW50fSBieXRlcyBvZiB1bmNvbXByZXNzZWQgZGF0YS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBieXRlQ291bnQgdGhlIG51bWJlciBvZiBieXRlcyB0byBza2lwLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiB1bmNvbXByZXNzZWQgYnl0ZXMgc2tpcHBlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgYnl0ZUNvdW50IDwgMH0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMgc2tpcHBpbmcuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgc2tpcChsb25nIGJ5dGVDb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGJ5dGVDb3VudCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImJ5dGVDb3VudCA8IDAiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gU3RyZWFtcy5za2lwQnlSZWFkaW5nKHRoaXMsIGJ5dGVDb3VudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyAwIHdoZW4gd2hlbiB0aGlzIHN0cmVhbSBoYXMgZXhoYXVzdGVkIGl0cyBpbnB1dDsgYW5kIDEgb3RoZXJ3aXNlLgorICAgICAqIEEgcmVzdWx0IG9mIDEgZG9lcyBub3QgZ3VhcmFudGVlIHRoYXQgZnVydGhlciBieXRlcyBjYW4gYmUgcmV0dXJuZWQsCisgICAgICogd2l0aCBvciB3aXRob3V0IGJsb2NraW5nLgorICAgICAqCisgICAgICogPHA+QWx0aG91Z2ggY29uc2lzdGVudCB3aXRoIHRoZSBSSSwgdGhpcyBiZWhhdmlvciBpcyBpbmNvbnNpc3RlbnQgd2l0aAorICAgICAqIHtAbGluayBJbnB1dFN0cmVhbSNhdmFpbGFibGUoKX0sIGFuZCB2aW9sYXRlcyB0aGUgPGEKKyAgICAgKiBocmVmPSJodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0xpc2tvdl9zdWJzdGl0dXRpb25fcHJpbmNpcGxlIj5MaXNrb3YKKyAgICAgKiBTdWJzdGl0dXRpb24gUHJpbmNpcGxlPC9hPi4gVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkLgorICAgICAqCisgICAgICogQHJldHVybiAwIGlmIG5vIGZ1cnRoZXIgYnl0ZXMgYXJlIGF2YWlsYWJsZS4gT3RoZXJ3aXNlIHJldHVybnMgMSwKKyAgICAgKiAgICAgICAgIHdoaWNoIHN1Z2dlc3RzIChidXQgZG9lcyBub3QgZ3VhcmFudGVlKSB0aGF0IGFkZGl0aW9uYWwgYnl0ZXMgYXJlCisgICAgICogICAgICAgICBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGlzIHN0cmVhbSBpcyBjbG9zZWQgb3IgYW4gZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICBpZiAoZW9mKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhlIGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBlcnJvciBvY2N1cnMgY2xvc2luZyB0aGUgaW5wdXQgc3RyZWFtLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFjbG9zZWQpIHsKKyAgICAgICAgICAgIGluZi5lbmQoKTsKKyAgICAgICAgICAgIGNsb3NlZCA9IHRydWU7CisgICAgICAgICAgICBlb2YgPSB0cnVlOworICAgICAgICAgICAgc3VwZXIuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIE1hcmtzIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBzdHJlYW0uIFRoaXMgaW1wbGVtZW50YXRpb24gb3ZlcnJpZGVzCisgICAgICogdGhlIHN1cGVyIHR5cGUgaW1wbGVtZW50YXRpb24gdG8gZG8gbm90aGluZyBhdCBhbGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhZGxpbWl0CisgICAgICogICAgICAgICAgICBvZiBubyB1c2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgbWFyayhpbnQgcmVhZGxpbWl0KSB7CisgICAgICAgIC8vIGRvIG5vdGhpbmcKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldCB0aGUgcG9zaXRpb24gb2YgdGhlIHN0cmVhbSB0byB0aGUgbGFzdCBtYXJrZWQgcG9zaXRpb24uIFRoaXMKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBvdmVycmlkZXMgdGhlIHN1cGVydHlwZSBpbXBsZW1lbnRhdGlvbiBhbmQgYWx3YXlzIHRocm93cworICAgICAqIGFuIHtAbGluayBJT0V4Y2VwdGlvbiBJT0V4Y2VwdGlvbn0gd2hlbiBjYWxsZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIG1ldGhvZCBpcyBjYWxsZWQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCByZXNldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgcmVjZWl2ZXIgaW1wbGVtZW50cyB7QGNvZGUgbWFya30gc2VtYW50aWNzLiBUaGlzIHR5cGUKKyAgICAgKiBkb2VzIG5vdCBzdXBwb3J0IHtAY29kZSBtYXJrKCl9LCBzbyBhbHdheXMgcmVzcG9uZHMge0Bjb2RlIGZhbHNlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gZmFsc2UsIGFsd2F5cworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hcmtTdXBwb3J0ZWQoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tDbG9zZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY2xvc2VkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlN0cmVhbSBpcyBjbG9zZWQiKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL0luZmxhdGVyT3V0cHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9JbmZsYXRlck91dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM5Njg3YjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9JbmZsYXRlck91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMTYyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuemlwOworCitpbXBvcnQgamF2YS5pby5GaWx0ZXJPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIEFuIHtAY29kZSBPdXRwdXRTdHJlYW19IGZpbHRlciB0byBkZWNvbXByZXNzIGRhdGEuIENhbGxlcnMgd3JpdGUKKyAqIGNvbXByZXNzZWQgZGF0YSBpbiB0aGUgImRlZmxhdGUiIGZvcm1hdCwgYW5kIHVuY29tcHJlc3NlZCBkYXRhIGlzCisgKiB3cml0dGVuIHRvIHRoZSB1bmRlcmx5aW5nIHN0cmVhbS4KKyAqIEBzaW5jZSAxLjYKKyAqLworcHVibGljIGNsYXNzIEluZmxhdGVyT3V0cHV0U3RyZWFtIGV4dGVuZHMgRmlsdGVyT3V0cHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9CVUZGRVJfU0laRSA9IDEwMjQ7CisKKyAgICBwcm90ZWN0ZWQgZmluYWwgSW5mbGF0ZXIgaW5mOworICAgIHByb3RlY3RlZCBmaW5hbCBieXRlW10gYnVmOworCisgICAgcHJpdmF0ZSBib29sZWFuIGNsb3NlZCA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiB7QGNvZGUgSW5mbGF0ZXJPdXRwdXRTdHJlYW19IHdpdGggYSBuZXcge0Bjb2RlIEluZmxhdGVyfSBhbmQgYW4KKyAgICAgKiBpbXBsZW1lbnRhdGlvbi1kZWZpbmVkIGRlZmF1bHQgaW50ZXJuYWwgYnVmZmVyIHNpemUuIHtAY29kZSBvdXR9IGlzIGEgZGVzdGluYXRpb24KKyAgICAgKiBmb3IgdW5jb21wcmVzc2VkIGRhdGEsIGFuZCBjb21wcmVzc2VkIGRhdGEgd2lsbCBiZSB3cml0dGVuIHRvIHRoaXMgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIG91dCB0aGUgZGVzdGluYXRpb24ge0Bjb2RlIE91dHB1dFN0cmVhbX0KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5mbGF0ZXJPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgICB0aGlzKG91dCwgbmV3IEluZmxhdGVyKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4ge0Bjb2RlIEluZmxhdGVyT3V0cHV0U3RyZWFtfSB3aXRoIHRoZSBnaXZlbiB7QGNvZGUgSW5mbGF0ZXJ9IGFuZCBhbgorICAgICAqIGltcGxlbWVudGF0aW9uLWRlZmluZWQgZGVmYXVsdCBpbnRlcm5hbCBidWZmZXIgc2l6ZS4ge0Bjb2RlIG91dH0gaXMgYSBkZXN0aW5hdGlvbgorICAgICAqIGZvciB1bmNvbXByZXNzZWQgZGF0YSwgYW5kIGNvbXByZXNzZWQgZGF0YSB3aWxsIGJlIHdyaXR0ZW4gdG8gdGhpcyBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0IHRoZSBkZXN0aW5hdGlvbiB7QGNvZGUgT3V0cHV0U3RyZWFtfQorICAgICAqIEBwYXJhbSBpbmYgdGhlIHtAY29kZSBJbmZsYXRlcn0gdG8gYmUgdXNlZCBmb3IgZGVjb21wcmVzc2lvbgorICAgICAqLworICAgIHB1YmxpYyBJbmZsYXRlck91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3V0LCBJbmZsYXRlciBpbmYpIHsKKyAgICAgICAgdGhpcyhvdXQsIGluZiwgREVGQVVMVF9CVUZGRVJfU0laRSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiB7QGNvZGUgSW5mbGF0ZXJPdXRwdXRTdHJlYW19IHdpdGggdGhlIGdpdmVuIHtAY29kZSBJbmZsYXRlcn0gYW5kCisgICAgICogZ2l2ZW4gaW50ZXJuYWwgYnVmZmVyIHNpemUuIHtAY29kZSBvdXR9IGlzIGEgZGVzdGluYXRpb24KKyAgICAgKiBmb3IgdW5jb21wcmVzc2VkIGRhdGEsIGFuZCBjb21wcmVzc2VkIGRhdGEgd2lsbCBiZSB3cml0dGVuIHRvIHRoaXMgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIG91dCB0aGUgZGVzdGluYXRpb24ge0Bjb2RlIE91dHB1dFN0cmVhbX0KKyAgICAgKiBAcGFyYW0gaW5mIHRoZSB7QGNvZGUgSW5mbGF0ZXJ9IHRvIGJlIHVzZWQgZm9yIGRlY29tcHJlc3Npb24KKyAgICAgKiBAcGFyYW0gYnVmZmVyU2l6ZSB0aGUgbGVuZ3RoIGluIGJ5dGVzIG9mIHRoZSBpbnRlcm5hbCBidWZmZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgSW5mbGF0ZXJPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG91dCwgSW5mbGF0ZXIgaW5mLCBpbnQgYnVmZmVyU2l6ZSkgeworICAgICAgICBzdXBlcihvdXQpOworICAgICAgICBpZiAob3V0ID09IG51bGwgfHwgaW5mID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChidWZmZXJTaXplIDw9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmluZiA9IGluZjsKKyAgICAgICAgdGhpcy5idWYgPSBuZXcgYnl0ZVtidWZmZXJTaXplXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgcmVtYWluaW5nIGRhdGEgaW50byB0aGUgb3V0cHV0IHN0cmVhbSBhbmQgY2xvc2VzIHRoZSB1bmRlcmx5aW5nCisgICAgICogb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghY2xvc2VkKSB7CisgICAgICAgICAgICBmaW5pc2goKTsKKyAgICAgICAgICAgIGluZi5lbmQoKTsKKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluaXNoKCk7CisgICAgICAgIG91dC5mbHVzaCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmlzaGVzIHdyaXRpbmcgY3VycmVudCB1bmNvbXByZXNzZWQgZGF0YSBpbnRvIHRoZSBJbmZsYXRlck91dHB1dFN0cmVhbQorICAgICAqIHdpdGhvdXQgY2xvc2luZyBpdC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3Vycywgb3IgdGhlIHN0cmVhbSBoYXMgYmVlbiBjbG9zZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBmaW5pc2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICB3cml0ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBhIGJ5dGUgdG8gdGhlIGRlY29tcHJlc3Npbmcgb3V0cHV0IHN0cmVhbS4ge0Bjb2RlIGJ9IHNob3VsZCBiZSBhIGJ5dGUgb2YKKyAgICAgKiBjb21wcmVzc2VkIGlucHV0LiBUaGUgY29ycmVzcG9uZGluZyB1bmNvbXByZXNzZWQgZGF0YSB3aWxsIGJlIHdyaXR0ZW4gdG8gdGhlIHVuZGVybHlpbmcKKyAgICAgKiBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYiB0aGUgYnl0ZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3Vycywgb3IgdGhlIHN0cmVhbSBoYXMgYmVlbiBjbG9zZWQKKyAgICAgKiBAdGhyb3dzIFppcEV4Y2VwdGlvbiBpZiBhIHppcCBleGNlcHRpb24gb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24sIFppcEV4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlKG5ldyBieXRlW10geyAoYnl0ZSkgYiB9LCAwLCAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdG8gdGhlIGRlY29tcHJlc3Npbmcgb3V0cHV0IHN0cmVhbS4gVGhlIHtAY29kZSBieXRlc30gYXJyYXkgc2hvdWxkIGNvbnRhaW4KKyAgICAgKiBjb21wcmVzc2VkIGlucHV0LiBUaGUgY29ycmVzcG9uZGluZyB1bmNvbXByZXNzZWQgZGF0YSB3aWxsIGJlIHdyaXR0ZW4gdG8gdGhlIHVuZGVybHlpbmcKKyAgICAgKiBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMsIG9yIHRoZSBzdHJlYW0gaGFzIGJlZW4gY2xvc2VkCisgICAgICogQHRocm93cyBaaXBFeGNlcHRpb24gaWYgYSB6aXAgZXhjZXB0aW9uIG9jY3Vycy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHtAY29kZSBiID09IG51bGx9LgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB7QGNvZGUgb2ZmIDwgMCB8fCBsZW4gPCAwIHx8IG9mZiArIGxlbiA+IGIubGVuZ3RofQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBieXRlcywgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uLCBaaXBFeGNlcHRpb24geworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChieXRlcy5sZW5ndGgsIG9mZnNldCwgYnl0ZUNvdW50KTsKKyAgICAgICAgaW5mLnNldElucHV0KGJ5dGVzLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIHdyaXRlKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBaaXBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IGluZmxhdGVkOworICAgICAgICAgICAgd2hpbGUgKChpbmZsYXRlZCA9IGluZi5pbmZsYXRlKGJ1ZikpID4gMCkgeworICAgICAgICAgICAgICAgIG91dC53cml0ZShidWYsIDAsIGluZmxhdGVkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRGF0YUZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tDbG9zZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY2xvc2VkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL1ppcENvbnN0YW50cy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvWmlwQ29uc3RhbnRzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGNlNjViYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL1ppcENvbnN0YW50cy5qYXZhCkBAIC0wLDAgKzEsMzggQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC56aXA7CisKKy8qKgorICogRG8gbm90IGFkZCBjb25zdGFudHMgdG8gdGhpcyBpbnRlcmZhY2UhIEl0J3MgaW1wbGVtZW50ZWQgYnkgdGhlIGNsYXNzZXMKKyAqIGluIHRoaXMgcGFja2FnZSB3aG9zZSBuYW1lcyBzdGFydCAiWmlwIiwgYW5kIHRoZSBjb25zdGFudHMgYXJlIHRoZXJlYnkKKyAqIHB1YmxpYyBBUEkuCisgKi8KK2ludGVyZmFjZSBaaXBDb25zdGFudHMgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIExPQ1NJRyA9IDB4NDAzNGI1MCwgRVhUU0lHID0gMHg4MDc0YjUwLAorICAgICAgICAgICAgQ0VOU0lHID0gMHgyMDE0YjUwLCBFTkRTSUcgPSAweDYwNTRiNTA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT0NIRFIgPSAzMCwgRVhUSERSID0gMTYsIENFTkhEUiA9IDQ2LCBFTkRIRFIgPSAyMiwKKyAgICAgICAgICAgIExPQ1ZFUiA9IDQsIExPQ0ZMRyA9IDYsIExPQ0hPVyA9IDgsIExPQ1RJTSA9IDEwLCBMT0NDUkMgPSAxNCwKKyAgICAgICAgICAgIExPQ1NJWiA9IDE4LCBMT0NMRU4gPSAyMiwgTE9DTkFNID0gMjYsIExPQ0VYVCA9IDI4LCBFWFRDUkMgPSA0LAorICAgICAgICAgICAgRVhUU0laID0gOCwgRVhUTEVOID0gMTIsIENFTlZFTSA9IDQsIENFTlZFUiA9IDYsIENFTkZMRyA9IDgsCisgICAgICAgICAgICBDRU5IT1cgPSAxMCwgQ0VOVElNID0gMTIsIENFTkNSQyA9IDE2LCBDRU5TSVogPSAyMCwgQ0VOTEVOID0gMjQsCisgICAgICAgICAgICBDRU5OQU0gPSAyOCwgQ0VORVhUID0gMzAsIENFTkNPTSA9IDMyLCBDRU5EU0sgPSAzNCwgQ0VOQVRUID0gMzYsCisgICAgICAgICAgICBDRU5BVFggPSAzOCwgQ0VOT0ZGID0gNDIsIEVORFNVQiA9IDgsIEVORFRPVCA9IDEwLCBFTkRTSVogPSAxMiwKKyAgICAgICAgICAgIEVORE9GRiA9IDE2LCBFTkRDT00gPSAyMDsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL1ppcEVudHJ5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9aaXBFbnRyeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk4OGJkMmMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9aaXBFbnRyeS5qYXZhCkBAIC0wLDAgKzEsMzk3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuemlwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLkJ5dGVPcmRlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRzOworaW1wb3J0IGphdmEudXRpbC5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI7CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworaW1wb3J0IGxpYmNvcmUuaW8uQnVmZmVySXRlcmF0b3I7CitpbXBvcnQgbGliY29yZS5pby5IZWFwQnVmZmVySXRlcmF0b3I7CisKKy8qKgorICogQW4gaW5zdGFuY2Ugb2Yge0Bjb2RlIFppcEVudHJ5fSByZXByZXNlbnRzIGFuIGVudHJ5IHdpdGhpbiBhIDxpPlpJUC1hcmNoaXZlPC9pPi4KKyAqIEFuIGVudHJ5IGhhcyBhdHRyaWJ1dGVzIHN1Y2ggYXMgbmFtZSAoPSBwYXRoKSBvciB0aGUgc2l6ZSBvZiBpdHMgZGF0YS4gV2hpbGUKKyAqIGFuIGVudHJ5IGlkZW50aWZpZXMgZGF0YSBzdG9yZWQgaW4gYW4gYXJjaGl2ZSwgaXQgZG9lcyBub3QgaG9sZCB0aGUgZGF0YQorICogaXRzZWxmLiBGb3IgZXhhbXBsZSB3aGVuIHJlYWRpbmcgYSA8aT5aSVAtZmlsZTwvaT4geW91IHdpbGwgZmlyc3QgcmV0cmlldmUKKyAqIGFsbCBpdHMgZW50cmllcyBpbiBhIGNvbGxlY3Rpb24gYW5kIHRoZW4gcmVhZCB0aGUgZGF0YSBmb3IgYSBzcGVjaWZpYyBlbnRyeQorICogdGhyb3VnaCBhbiBpbnB1dCBzdHJlYW0uCisgKgorICogQHNlZSBaaXBGaWxlCisgKiBAc2VlIFppcE91dHB1dFN0cmVhbQorICovCitwdWJsaWMgY2xhc3MgWmlwRW50cnkgaW1wbGVtZW50cyBaaXBDb25zdGFudHMsIENsb25lYWJsZSB7CisgICAgU3RyaW5nIG5hbWUsIGNvbW1lbnQ7CisKKyAgICBsb25nIGNvbXByZXNzZWRTaXplID0gLTEsIGNyYyA9IC0xLCBzaXplID0gLTE7CisKKyAgICBpbnQgY29tcHJlc3Npb25NZXRob2QgPSAtMSwgdGltZSA9IC0xLCBtb2REYXRlID0gLTE7CisKKyAgICBieXRlW10gZXh0cmE7CisKKyAgICBpbnQgbmFtZUxlbmd0aCA9IC0xOworICAgIGxvbmcgbUxvY2FsSGVhZGVyUmVsT2Zmc2V0ID0gLTE7CisKKyAgICAvKioKKyAgICAgKiBaaXAgZW50cnkgc3RhdGU6IERlZmxhdGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkxBVEVEID0gODsKKworICAgIC8qKgorICAgICAqIFppcCBlbnRyeSBzdGF0ZTogU3RvcmVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUT1JFRCA9IDA7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBaaXBFbnRyeX0gd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIFpJUCBlbnRyeS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBuYW1lIGxlbmd0aCBpcyBvdXRzaWRlIHRoZSByYW5nZSAoPiAweEZGRkYpLgorICAgICAqLworICAgIHB1YmxpYyBaaXBFbnRyeShTdHJpbmcgbmFtZSkgeworICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobmFtZS5sZW5ndGgoKSA+IDB4RkZGRikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTmFtZSB0b28gbG9uZzogIiArIG5hbWUubGVuZ3RoKCkpOworICAgICAgICB9CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY29tbWVudCBmb3IgdGhpcyB7QGNvZGUgWmlwRW50cnl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29tbWVudCBmb3IgdGhpcyB7QGNvZGUgWmlwRW50cnl9LCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUKKyAgICAgKiAgICAgICAgIGlzIG5vIGNvbW1lbnQuIElmIHdlJ3JlIHJlYWRpbmcgYW4gYXJjaGl2ZSB3aXRoCisgICAgICogICAgICAgICB7QGNvZGUgWmlwSW5wdXRTdHJlYW19IHRoZSBjb21tZW50IGlzIG5vdCBhdmFpbGFibGUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb21tZW50KCkgeworICAgICAgICByZXR1cm4gY29tbWVudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjb21wcmVzc2VkIHNpemUgb2YgdGhpcyB7QGNvZGUgWmlwRW50cnl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29tcHJlc3NlZCBzaXplLCBvciAtMSBpZiB0aGUgY29tcHJlc3NlZCBzaXplIGhhcyBub3QgYmVlbgorICAgICAqICAgICAgICAgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldENvbXByZXNzZWRTaXplKCkgeworICAgICAgICByZXR1cm4gY29tcHJlc3NlZFNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY2hlY2tzdW0gZm9yIHRoaXMge0Bjb2RlIFppcEVudHJ5fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNoZWNrc3VtLCBvciAtMSBpZiB0aGUgY2hlY2tzdW0gaGFzIG5vdCBiZWVuIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRDcmMoKSB7CisgICAgICAgIHJldHVybiBjcmM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZXh0cmEgaW5mb3JtYXRpb24gZm9yIHRoaXMge0Bjb2RlIFppcEVudHJ5fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBieXRlIGFycmF5IGNvbnRhaW5pbmcgdGhlIGV4dHJhIGluZm9ybWF0aW9uLCBvciB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiAgICAgICAgIHRoZXJlIGlzIG5vbmUuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFeHRyYSgpIHsKKyAgICAgICAgcmV0dXJuIGV4dHJhOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNvbXByZXNzaW9uIG1ldGhvZCBmb3IgdGhpcyB7QGNvZGUgWmlwRW50cnl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY29tcHJlc3Npb24gbWV0aG9kLCBlaXRoZXIge0Bjb2RlIERFRkxBVEVEfSwge0Bjb2RlIFNUT1JFRH0KKyAgICAgKiAgICAgICAgIG9yIC0xIGlmIHRoZSBjb21wcmVzc2lvbiBtZXRob2QgaGFzIG5vdCBiZWVuIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1ldGhvZCgpIHsKKyAgICAgICAgcmV0dXJuIGNvbXByZXNzaW9uTWV0aG9kOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWUgb2YgdGhpcyB7QGNvZGUgWmlwRW50cnl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZW50cnkgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHVuY29tcHJlc3NlZCBzaXplIG9mIHRoaXMge0Bjb2RlIFppcEVudHJ5fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHVuY29tcHJlc3NlZCBzaXplLCBvciB7QGNvZGUgLTF9IGlmIHRoZSBzaXplIGhhcyBub3QgYmVlbgorICAgICAqICAgICAgICAgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFNpemUoKSB7CisgICAgICAgIHJldHVybiBzaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxhc3QgbW9kaWZpY2F0aW9uIHRpbWUgb2YgdGhpcyB7QGNvZGUgWmlwRW50cnl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGFzdCBtb2RpZmljYXRpb24gdGltZSBhcyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBzaW5jZQorICAgICAqICAgICAgICAgSmFuLiAxLCAxOTcwLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFRpbWUoKSB7CisgICAgICAgIGlmICh0aW1lICE9IC0xKSB7CisgICAgICAgICAgICBHcmVnb3JpYW5DYWxlbmRhciBjYWwgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoKTsKKyAgICAgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuTUlMTElTRUNPTkQsIDApOworICAgICAgICAgICAgY2FsLnNldCgxOTgwICsgKChtb2REYXRlID4+IDkpICYgMHg3ZiksICgobW9kRGF0ZSA+PiA1KSAmIDB4ZikgLSAxLAorICAgICAgICAgICAgICAgICAgICBtb2REYXRlICYgMHgxZiwgKHRpbWUgPj4gMTEpICYgMHgxZiwgKHRpbWUgPj4gNSkgJiAweDNmLAorICAgICAgICAgICAgICAgICAgICAodGltZSAmIDB4MWYpIDw8IDEpOworICAgICAgICAgICAgcmV0dXJuIGNhbC5nZXRUaW1lKCkuZ2V0VGltZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmUgd2hldGhlciBvciBub3QgdGhpcyB7QGNvZGUgWmlwRW50cnl9IGlzIGEgZGlyZWN0b3J5LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gd2hlbiB0aGlzIHtAY29kZSBaaXBFbnRyeX0gaXMgYSBkaXJlY3RvcnksIHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdG9yeSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWUuY2hhckF0KG5hbWUubGVuZ3RoKCkgLSAxKSA9PSAnLyc7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY29tbWVudCBmb3IgdGhpcyB7QGNvZGUgWmlwRW50cnl9LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbW1lbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb21tZW50IGZvciB0aGlzIGVudHJ5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvbW1lbnQoU3RyaW5nIGNvbW1lbnQpIHsKKyAgICAgICAgaWYgKGNvbW1lbnQgPT0gbnVsbCB8fCBjb21tZW50Lmxlbmd0aCgpIDw9IDB4RkZGRikgeworICAgICAgICAgICAgdGhpcy5jb21tZW50ID0gY29tbWVudDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNvbXByZXNzZWQgc2l6ZSBmb3IgdGhpcyB7QGNvZGUgWmlwRW50cnl9LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgY29tcHJlc3NlZCBzaXplIChpbiBieXRlcykuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q29tcHJlc3NlZFNpemUobG9uZyB2YWx1ZSkgeworICAgICAgICBjb21wcmVzc2VkU2l6ZSA9IHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNoZWNrc3VtIGZvciB0aGlzIHtAY29kZSBaaXBFbnRyeX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaGVja3N1bSBmb3IgdGhpcyBlbnRyeS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSB2YWx1ZX0gaXMgPCAwIG9yID4gMHhGRkZGRkZGRkwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q3JjKGxvbmcgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlID49IDAgJiYgdmFsdWUgPD0gMHhGRkZGRkZGRkwpIHsKKyAgICAgICAgICAgIGNyYyA9IHZhbHVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQmFkIENSQzMyOiAiICsgdmFsdWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZXh0cmEgaW5mb3JtYXRpb24gZm9yIHRoaXMge0Bjb2RlIFppcEVudHJ5fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogICAgICAgICAgICBhIGJ5dGUgYXJyYXkgY29udGFpbmluZyB0aGUgZXh0cmEgaW5mb3JtYXRpb24uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB3aGVuIHRoZSBsZW5ndGggb2YgZGF0YSBpcyBncmVhdGVyIHRoYW4gMHhGRkZGIGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEV4dHJhKGJ5dGVbXSBkYXRhKSB7CisgICAgICAgIGlmIChkYXRhID09IG51bGwgfHwgZGF0YS5sZW5ndGggPD0gMHhGRkZGKSB7CisgICAgICAgICAgICBleHRyYSA9IGRhdGE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjb21wcmVzc2lvbiBtZXRob2QgZm9yIHRoaXMge0Bjb2RlIFppcEVudHJ5fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqICAgICAgICAgICAgdGhlIGNvbXByZXNzaW9uIG1ldGhvZCwgZWl0aGVyIHtAY29kZSBERUZMQVRFRH0gb3Ige0Bjb2RlCisgICAgICogICAgICAgICAgICBTVE9SRUR9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiB2YWx1ZSBpcyBub3Qge0Bjb2RlIERFRkxBVEVEfSBvciB7QGNvZGUgU1RPUkVEfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRNZXRob2QoaW50IHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSAhPSBTVE9SRUQgJiYgdmFsdWUgIT0gREVGTEFURUQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkJhZCBtZXRob2Q6ICIgKyB2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgY29tcHJlc3Npb25NZXRob2QgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB1bmNvbXByZXNzZWQgc2l6ZSBvZiB0aGlzIHtAY29kZSBaaXBFbnRyeX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB1bmNvbXByZXNzZWQgc2l6ZSBmb3IgdGhpcyBlbnRyeS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSB2YWx1ZX0gPCAwIG9yIHtAY29kZSB2YWx1ZX0gPiAweEZGRkZGRkZGTC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTaXplKGxvbmcgdmFsdWUpIHsKKyAgICAgICAgaWYgKHZhbHVlID49IDAgJiYgdmFsdWUgPD0gMHhGRkZGRkZGRkwpIHsKKyAgICAgICAgICAgIHNpemUgPSB2YWx1ZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkJhZCBzaXplOiAiICsgdmFsdWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbW9kaWZpY2F0aW9uIHRpbWUgb2YgdGhpcyB7QGNvZGUgWmlwRW50cnl9LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgbW9kaWZpY2F0aW9uIHRpbWUgYXMgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgc2luY2UgSmFuLgorICAgICAqICAgICAgICAgICAgMSwgMTk3MC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lKGxvbmcgdmFsdWUpIHsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKCk7CisgICAgICAgIGNhbC5zZXRUaW1lKG5ldyBEYXRlKHZhbHVlKSk7CisgICAgICAgIGludCB5ZWFyID0gY2FsLmdldChDYWxlbmRhci5ZRUFSKTsKKyAgICAgICAgaWYgKHllYXIgPCAxOTgwKSB7CisgICAgICAgICAgICBtb2REYXRlID0gMHgyMTsKKyAgICAgICAgICAgIHRpbWUgPSAwOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbW9kRGF0ZSA9IGNhbC5nZXQoQ2FsZW5kYXIuREFURSk7CisgICAgICAgICAgICBtb2REYXRlID0gKGNhbC5nZXQoQ2FsZW5kYXIuTU9OVEgpICsgMSA8PCA1KSB8IG1vZERhdGU7CisgICAgICAgICAgICBtb2REYXRlID0gKChjYWwuZ2V0KENhbGVuZGFyLllFQVIpIC0gMTk4MCkgPDwgOSkgfCBtb2REYXRlOworICAgICAgICAgICAgdGltZSA9IGNhbC5nZXQoQ2FsZW5kYXIuU0VDT05EKSA+PiAxOworICAgICAgICAgICAgdGltZSA9IChjYWwuZ2V0KENhbGVuZGFyLk1JTlVURSkgPDwgNSkgfCB0aW1lOworICAgICAgICAgICAgdGltZSA9IChjYWwuZ2V0KENhbGVuZGFyLkhPVVJfT0ZfREFZKSA8PCAxMSkgfCB0aW1lOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMge0Bjb2RlIFppcEVudHJ5fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZSBaaXBFbnRyeX0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgWmlwRW50cnl9IHVzaW5nIHRoZSB2YWx1ZXMgb2J0YWluZWQgZnJvbSB7QGNvZGUKKyAgICAgKiB6ZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gemUKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgWmlwRW50cnl9IGZyb20gd2hpY2ggdG8gb2J0YWluIHZhbHVlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwRW50cnkoWmlwRW50cnkgemUpIHsKKyAgICAgICAgbmFtZSA9IHplLm5hbWU7CisgICAgICAgIGNvbW1lbnQgPSB6ZS5jb21tZW50OworICAgICAgICB0aW1lID0gemUudGltZTsKKyAgICAgICAgc2l6ZSA9IHplLnNpemU7CisgICAgICAgIGNvbXByZXNzZWRTaXplID0gemUuY29tcHJlc3NlZFNpemU7CisgICAgICAgIGNyYyA9IHplLmNyYzsKKyAgICAgICAgY29tcHJlc3Npb25NZXRob2QgPSB6ZS5jb21wcmVzc2lvbk1ldGhvZDsKKyAgICAgICAgbW9kRGF0ZSA9IHplLm1vZERhdGU7CisgICAgICAgIGV4dHJhID0gemUuZXh0cmE7CisgICAgICAgIG5hbWVMZW5ndGggPSB6ZS5uYW1lTGVuZ3RoOworICAgICAgICBtTG9jYWxIZWFkZXJSZWxPZmZzZXQgPSB6ZS5tTG9jYWxIZWFkZXJSZWxPZmZzZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGRlZXAgY29weSBvZiB0aGlzIHppcCBlbnRyeS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFppcEVudHJ5IHJlc3VsdCA9IChaaXBFbnRyeSkgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgICAgIHJlc3VsdC5leHRyYSA9IGV4dHJhICE9IG51bGwgPyBleHRyYS5jbG9uZSgpIDogbnVsbDsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhhc2ggY29kZSBmb3IgdGhpcyB7QGNvZGUgWmlwRW50cnl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlIG9mIHRoZSBlbnRyeS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gbmFtZS5oYXNoQ29kZSgpOworICAgIH0KKworICAgIC8qCisgICAgICogSW50ZXJuYWwgY29uc3RydWN0b3IuICBDcmVhdGVzIGEgbmV3IFppcEVudHJ5IGJ5IHJlYWRpbmcgdGhlCisgICAgICogQ2VudHJhbCBEaXJlY3RvcnkgRW50cnkgZnJvbSAiaW4iLCB3aGljaCBtdXN0IGJlIHBvc2l0aW9uZWQgYXQKKyAgICAgKiB0aGUgQ0RFIHNpZ25hdHVyZS4KKyAgICAgKgorICAgICAqIE9uIGV4aXQsICJpbiIgd2lsbCBiZSBwb3NpdGlvbmVkIGF0IHRoZSBzdGFydCBvZiB0aGUgbmV4dCBlbnRyeS4KKyAgICAgKi8KKyAgICBaaXBFbnRyeShieXRlW10gaGRyQnVmLCBJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyZWFtcy5yZWFkRnVsbHkoaW4sIGhkckJ1ZiwgMCwgaGRyQnVmLmxlbmd0aCk7CisKKyAgICAgICAgQnVmZmVySXRlcmF0b3IgaXQgPSBIZWFwQnVmZmVySXRlcmF0b3IuaXRlcmF0b3IoaGRyQnVmLCAwLCBoZHJCdWYubGVuZ3RoLCBCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisKKyAgICAgICAgaW50IHNpZyA9IGl0LnJlYWRJbnQoKTsKKyAgICAgICAgaWYgKHNpZyAhPSBDRU5TSUcpIHsKKyAgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJDZW50cmFsIERpcmVjdG9yeSBFbnRyeSBub3QgZm91bmQiKTsKKyAgICAgICAgfQorCisgICAgICAgIGl0LnNlZWsoMTApOworICAgICAgICBjb21wcmVzc2lvbk1ldGhvZCA9IGl0LnJlYWRTaG9ydCgpOworICAgICAgICB0aW1lID0gaXQucmVhZFNob3J0KCk7CisgICAgICAgIG1vZERhdGUgPSBpdC5yZWFkU2hvcnQoKTsKKworICAgICAgICAvLyBUaGVzZSBhcmUgMzItYml0IHZhbHVlcyBpbiB0aGUgZmlsZSwgYnV0IDY0LWJpdCBmaWVsZHMgaW4gdGhpcyBvYmplY3QuCisgICAgICAgIGNyYyA9ICgobG9uZykgaXQucmVhZEludCgpKSAmIDB4ZmZmZmZmZmZMOworICAgICAgICBjb21wcmVzc2VkU2l6ZSA9ICgobG9uZykgaXQucmVhZEludCgpKSAmIDB4ZmZmZmZmZmZMOworICAgICAgICBzaXplID0gKChsb25nKSBpdC5yZWFkSW50KCkpICYgMHhmZmZmZmZmZkw7CisKKyAgICAgICAgbmFtZUxlbmd0aCA9IGl0LnJlYWRTaG9ydCgpOworICAgICAgICBpbnQgZXh0cmFMZW5ndGggPSBpdC5yZWFkU2hvcnQoKTsKKyAgICAgICAgaW50IGNvbW1lbnRMZW5ndGggPSBpdC5yZWFkU2hvcnQoKTsKKworICAgICAgICAvLyBUaGlzIGlzIGEgMzItYml0IHZhbHVlIGluIHRoZSBmaWxlLCBidXQgYSA2NC1iaXQgZmllbGQgaW4gdGhpcyBvYmplY3QuCisgICAgICAgIGl0LnNlZWsoNDIpOworICAgICAgICBtTG9jYWxIZWFkZXJSZWxPZmZzZXQgPSAoKGxvbmcpIGl0LnJlYWRJbnQoKSkgJiAweGZmZmZmZmZmTDsKKworICAgICAgICBieXRlW10gbmFtZUJ5dGVzID0gbmV3IGJ5dGVbbmFtZUxlbmd0aF07CisgICAgICAgIFN0cmVhbXMucmVhZEZ1bGx5KGluLCBuYW1lQnl0ZXMsIDAsIG5hbWVCeXRlcy5sZW5ndGgpOworICAgICAgICBuYW1lID0gbmV3IFN0cmluZyhuYW1lQnl0ZXMsIDAsIG5hbWVCeXRlcy5sZW5ndGgsIENoYXJzZXRzLlVURl84KTsKKworICAgICAgICAvLyBUaGUgUkkgaGFzIGFsd2F5cyBhc3N1bWVkIFVURi04LiAoSWYgR1BCRl9VVEY4X0ZMQUcgaXNuJ3Qgc2V0LCB0aGUgZW5jb2RpbmcgaXMKKyAgICAgICAgLy8gYWN0dWFsbHkgSUJNLTQzNy4pCisgICAgICAgIGlmIChjb21tZW50TGVuZ3RoID4gMCkgeworICAgICAgICAgICAgYnl0ZVtdIGNvbW1lbnRCeXRlcyA9IG5ldyBieXRlW2NvbW1lbnRMZW5ndGhdOworICAgICAgICAgICAgU3RyZWFtcy5yZWFkRnVsbHkoaW4sIGNvbW1lbnRCeXRlcywgMCwgY29tbWVudExlbmd0aCk7CisgICAgICAgICAgICBjb21tZW50ID0gbmV3IFN0cmluZyhjb21tZW50Qnl0ZXMsIDAsIGNvbW1lbnRCeXRlcy5sZW5ndGgsIENoYXJzZXRzLlVURl84KTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChleHRyYUxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgIGV4dHJhID0gbmV3IGJ5dGVbZXh0cmFMZW5ndGhdOworICAgICAgICAgICAgU3RyZWFtcy5yZWFkRnVsbHkoaW4sIGV4dHJhLCAwLCBleHRyYUxlbmd0aCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9aaXBFcnJvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvWmlwRXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NzE4NTc1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvWmlwRXJyb3IuamF2YQpAQCAtMCwwICsxLDMzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuemlwOworCisvKioKKyAqIFRocm93biB3aGVuIGFuIHVucmVjb3ZlcmFibGUgWklQIGVycm9yIGhhcyBvY2N1cnJlZC4KKyAqIEBzaW5jZSAxLjYKKyAqLworcHVibGljIGNsYXNzIFppcEVycm9yIGV4dGVuZHMgSW50ZXJuYWxFcnJvciB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODUzOTczNDIyMjY2ODYxOTc5TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBaaXBFcnJvciB3aXRoIHRoZSBnaXZlbiBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwRXJyb3IoU3RyaW5nIHMpIHsKKyAgICAgICAgc3VwZXIocyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvWmlwRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9aaXBFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNzc5NDNlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvWmlwRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YS51dGlsLnppcDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogVGhpcyBydW50aW1lIGV4Y2VwdGlvbiBpcyB0aHJvd24gYnkge0Bjb2RlIFppcEZpbGV9IGFuZCB7QGNvZGUKKyAqIFppcElucHV0U3RyZWFtfSB3aGVuIHRoZSBmaWxlIG9yIHN0cmVhbSBpcyBub3QgYSB2YWxpZCBaSVAgZmlsZS4KKyAqCisgKiBAc2VlIFppcEZpbGUKKyAqIEBzZWUgWmlwSW5wdXRTdHJlYW0KKyAqLworcHVibGljIGNsYXNzIFppcEV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDgwMDAxOTY4MzQwNjY3NDg2MjNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgWmlwRXhjZXB0aW9ufSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwRXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcge0Bjb2RlIFppcEV4Y2VwdGlvbn0gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXRhaWxNZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFppcEV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgeworICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL1ppcEZpbGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL1ppcEZpbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNTc2ZDg1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvWmlwRmlsZS5qYXZhCkBAIC0wLDAgKzEsNDU0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZhLnV0aWwuemlwOworCitpbXBvcnQgZGFsdmlrLnN5c3RlbS5DbG9zZUd1YXJkOworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkVPRkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZTsKK2ltcG9ydCBqYXZhLm5pby5CeXRlT3JkZXI7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcDsKK2ltcG9ydCBsaWJjb3JlLmlvLkJ1ZmZlckl0ZXJhdG9yOworaW1wb3J0IGxpYmNvcmUuaW8uSGVhcEJ1ZmZlckl0ZXJhdG9yOworaW1wb3J0IGxpYmNvcmUuaW8uU3RyZWFtczsKKworLyoqCisgKiBUaGlzIGNsYXNzIHByb3ZpZGVzIHJhbmRvbSByZWFkIGFjY2VzcyB0byBhIDxpPlpJUC1hcmNoaXZlPC9pPiBmaWxlLgorICogPHA+CisgKiBXaGlsZSB7QGNvZGUgWmlwSW5wdXRTdHJlYW19IHByb3ZpZGVzIHN0cmVhbSBiYXNlZCByZWFkIGFjY2VzcyB0byBhCisgKiA8aT5aSVAtYXJjaGl2ZTwvaT4sIHRoaXMgY2xhc3MgaW1wbGVtZW50cyBtb3JlIGVmZmljaWVudCAoZmlsZSBiYXNlZCkgYWNjZXNzCisgKiBhbmQgbWFrZXMgdXNlIG9mIHRoZSA8aT5jZW50cmFsIGRpcmVjdG9yeTwvaT4gd2l0aGluIGEgPGk+WklQLWFyY2hpdmU8L2k+LgorICogPHA+CisgKiBVc2Uge0Bjb2RlIFppcE91dHB1dFN0cmVhbX0gaWYgeW91IHdhbnQgdG8gY3JlYXRlIGFuIGFyY2hpdmUuCisgKiA8cD4KKyAqIEEgdGVtcG9yYXJ5IFpJUCBmaWxlIGNhbiBiZSBtYXJrZWQgZm9yIGF1dG9tYXRpYyBkZWxldGlvbiB1cG9uIGNsb3NpbmcgaXQuCisgKgorICogQHNlZSBaaXBFbnRyeQorICogQHNlZSBaaXBPdXRwdXRTdHJlYW0KKyAqLworcHVibGljIGNsYXNzIFppcEZpbGUgaW1wbGVtZW50cyBaaXBDb25zdGFudHMgeworICAgIC8qKgorICAgICAqIEdlbmVyYWwgUHVycG9zZSBCaXQgRmxhZ3MsIEJpdCAzLgorICAgICAqIElmIHRoaXMgYml0IGlzIHNldCwgdGhlIGZpZWxkcyBjcmMtMzIsIGNvbXByZXNzZWQKKyAgICAgKiBzaXplIGFuZCB1bmNvbXByZXNzZWQgc2l6ZSBhcmUgc2V0IHRvIHplcm8gaW4gdGhlCisgICAgICogbG9jYWwgaGVhZGVyLiAgVGhlIGNvcnJlY3QgdmFsdWVzIGFyZSBwdXQgaW4gdGhlCisgICAgICogZGF0YSBkZXNjcmlwdG9yIGltbWVkaWF0ZWx5IGZvbGxvd2luZyB0aGUgY29tcHJlc3NlZAorICAgICAqIGRhdGEuICAoTm90ZTogUEtaSVAgdmVyc2lvbiAyLjA0ZyBmb3IgRE9TIG9ubHkKKyAgICAgKiByZWNvZ25pemVzIHRoaXMgYml0IGZvciBtZXRob2QgOCBjb21wcmVzc2lvbiwgbmV3ZXIKKyAgICAgKiB2ZXJzaW9ucyBvZiBQS1pJUCByZWNvZ25pemUgdGhpcyBiaXQgZm9yIGFueQorICAgICAqIGNvbXByZXNzaW9uIG1ldGhvZC4pCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGludCBHUEJGX0RBVEFfREVTQ1JJUFRPUl9GTEFHID0gMSA8PCAzOworCisgICAgLyoqCisgICAgICogR2VuZXJhbCBQdXJwb3NlIEJpdCBGbGFncywgQml0IDExLgorICAgICAqIExhbmd1YWdlIGVuY29kaW5nIGZsYWcgKEVGUykuICBJZiB0aGlzIGJpdCBpcyBzZXQsCisgICAgICogdGhlIGZpbGVuYW1lIGFuZCBjb21tZW50IGZpZWxkcyBmb3IgdGhpcyBmaWxlCisgICAgICogbXVzdCBiZSBlbmNvZGVkIHVzaW5nIFVURi04LgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBpbnQgR1BCRl9VVEY4X0ZMQUcgPSAxIDw8IDExOworCisgICAgLyoqCisgICAgICogT3BlbiBaSVAgZmlsZSBmb3IgcmVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUEVOX1JFQUQgPSAxOworCisgICAgLyoqCisgICAgICogRGVsZXRlIFpJUCBmaWxlIHdoZW4gY2xvc2VkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QRU5fREVMRVRFID0gNDsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGZpbGVOYW1lOworCisgICAgcHJpdmF0ZSBGaWxlIGZpbGVUb0RlbGV0ZU9uQ2xvc2U7CisKKyAgICBwcml2YXRlIFJhbmRvbUFjY2Vzc0ZpbGUgbVJhZjsKKworICAgIHByaXZhdGUgZmluYWwgTGlua2VkSGFzaE1hcDxTdHJpbmcsIFppcEVudHJ5PiBtRW50cmllcyA9IG5ldyBMaW5rZWRIYXNoTWFwPFN0cmluZywgWmlwRW50cnk+KCk7CisKKyAgICBwcml2YXRlIGZpbmFsIENsb3NlR3VhcmQgZ3VhcmQgPSBDbG9zZUd1YXJkLmdldCgpOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgWmlwRmlsZX0gd2l0aCB0aGUgc3BlY2lmaWVkIGZpbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZQorICAgICAqICAgICAgICAgICAgdGhlIGZpbGUgdG8gcmVhZCBmcm9tLgorICAgICAqIEB0aHJvd3MgWmlwRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBaSVAgZXJyb3Igb2NjdXJzLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiB7QGNvZGUgSU9FeGNlcHRpb259IG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwRmlsZShGaWxlIGZpbGUpIHRocm93cyBaaXBFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhmaWxlLCBPUEVOX1JFQUQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE9wZW5zIGEgZmlsZSBhcyA8aT5aSVAtYXJjaGl2ZTwvaT4uICJtb2RlIiBtdXN0IGJlIHtAY29kZSBPUEVOX1JFQUR9IG9yCisgICAgICoge0Bjb2RlIE9QRU5fREVMRVRFfSAuIFRoZSBsYXR0ZXIgc2V0cyB0aGUgImRlbGV0ZSBvbiBleGl0IiBmbGFnIHRocm91Z2ggYQorICAgICAqIGZpbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZQorICAgICAqICAgICAgICAgICAgdGhlIFpJUCBmaWxlIHRvIHJlYWQuCisgICAgICogQHBhcmFtIG1vZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBtb2RlIG9mIHRoZSBmaWxlIG9wZW4gb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiB7QGNvZGUgSU9FeGNlcHRpb259IG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwRmlsZShGaWxlIGZpbGUsIGludCBtb2RlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaWxlTmFtZSA9IGZpbGUuZ2V0UGF0aCgpOworICAgICAgICBpZiAobW9kZSAhPSBPUEVOX1JFQUQgJiYgbW9kZSAhPSAoT1BFTl9SRUFEIHwgT1BFTl9ERUxFVEUpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoKG1vZGUgJiBPUEVOX0RFTEVURSkgIT0gMCkgeworICAgICAgICAgICAgZmlsZVRvRGVsZXRlT25DbG9zZSA9IGZpbGU7IC8vIGZpbGUuZGVsZXRlT25FeGl0KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmaWxlVG9EZWxldGVPbkNsb3NlID0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIG1SYWYgPSBuZXcgUmFuZG9tQWNjZXNzRmlsZShmaWxlTmFtZSwgInIiKTsKKworICAgICAgICByZWFkQ2VudHJhbERpcigpOworICAgICAgICBndWFyZC5vcGVuKCJjbG9zZSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE9wZW5zIGEgWklQIGFyY2hpdmVkIGZpbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIFpJUCBmaWxlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJT0V4Y2VwdGlvbiBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIFppcEZpbGUoU3RyaW5nIG5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMobmV3IEZpbGUobmFtZSksIE9QRU5fUkVBRCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChndWFyZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZ3VhcmQud2FybklmT3BlbigpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdXBlci5maW5hbGl6ZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhpcyBaSVAgZmlsZS4gVGhpcyBtZXRob2QgaXMgaWRlbXBvdGVudC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJT0V4Y2VwdGlvbiBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBndWFyZC5jbG9zZSgpOworICAgICAgICBSYW5kb21BY2Nlc3NGaWxlIHJhZiA9IG1SYWY7CisKKyAgICAgICAgaWYgKHJhZiAhPSBudWxsKSB7IC8vIE9ubHkgY2xvc2UgaW5pdGlhbGl6ZWQgaW5zdGFuY2VzCisgICAgICAgICAgICBzeW5jaHJvbml6ZWQocmFmKSB7CisgICAgICAgICAgICAgICAgbVJhZiA9IG51bGw7CisgICAgICAgICAgICAgICAgcmFmLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZmlsZVRvRGVsZXRlT25DbG9zZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZmlsZVRvRGVsZXRlT25DbG9zZS5kZWxldGUoKTsKKyAgICAgICAgICAgICAgICBmaWxlVG9EZWxldGVPbkNsb3NlID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja05vdENsb3NlZCgpIHsKKyAgICAgICAgaWYgKG1SYWYgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiWmlwIGZpbGUgY2xvc2VkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGVudW1lcmF0aW9uIG9mIHRoZSBlbnRyaWVzLiBUaGUgZW50cmllcyBhcmUgbGlzdGVkIGluIHRoZQorICAgICAqIG9yZGVyIGluIHdoaWNoIHRoZXkgYXBwZWFyIGluIHRoZSBaSVAgYXJjaGl2ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVudW1lcmF0aW9uIG9mIHRoZSBlbnRyaWVzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgWklQIGZpbGUgaGFzIGJlZW4gY2xvc2VkLgorICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbjw/IGV4dGVuZHMgWmlwRW50cnk+IGVudHJpZXMoKSB7CisgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgIGZpbmFsIEl0ZXJhdG9yPFppcEVudHJ5PiBpdGVyYXRvciA9IG1FbnRyaWVzLnZhbHVlcygpLml0ZXJhdG9yKCk7CisKKyAgICAgICAgcmV0dXJuIG5ldyBFbnVtZXJhdGlvbjxaaXBFbnRyeT4oKSB7CisgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNNb3JlRWxlbWVudHMoKSB7CisgICAgICAgICAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3IuaGFzTmV4dCgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgWmlwRW50cnkgbmV4dEVsZW1lbnQoKSB7CisgICAgICAgICAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3IubmV4dCgpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFpJUCBlbnRyeSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBmcm9tIHRoaXMge0Bjb2RlIFppcEZpbGV9LgorICAgICAqCisgICAgICogQHBhcmFtIGVudHJ5TmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGVudHJ5IGluIHRoZSBaSVAgZmlsZS4KKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFppcEVudHJ5fSBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIGVudHJ5IG5hbWUgZG9lcyBub3QKKyAgICAgKiAgICAgICAgIGV4aXN0IGluIHRoZSBaSVAgZmlsZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIFpJUCBmaWxlIGhhcyBiZWVuIGNsb3NlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwRW50cnkgZ2V0RW50cnkoU3RyaW5nIGVudHJ5TmFtZSkgeworICAgICAgICBjaGVja05vdENsb3NlZCgpOworICAgICAgICBpZiAoZW50cnlOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgWmlwRW50cnkgemUgPSBtRW50cmllcy5nZXQoZW50cnlOYW1lKTsKKyAgICAgICAgaWYgKHplID09IG51bGwpIHsKKyAgICAgICAgICAgIHplID0gbUVudHJpZXMuZ2V0KGVudHJ5TmFtZSArICIvIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHplOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5wdXQgc3RyZWFtIG9uIHRoZSBkYXRhIG9mIHRoZSBzcGVjaWZpZWQge0Bjb2RlIFppcEVudHJ5fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbnRyeQorICAgICAqICAgICAgICAgICAgdGhlIFppcEVudHJ5LgorICAgICAqIEByZXR1cm4gYW4gaW5wdXQgc3RyZWFtIG9mIHRoZSBkYXRhIGNvbnRhaW5lZCBpbiB0aGUge0Bjb2RlIFppcEVudHJ5fS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4ge0Bjb2RlIElPRXhjZXB0aW9ufSBvY2N1cnMuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBaSVAgZmlsZSBoYXMgYmVlbiBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKFppcEVudHJ5IGVudHJ5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBNYWtlIHN1cmUgdGhpcyBaaXBFbnRyeSBpcyBpbiB0aGlzIFppcCBmaWxlLiAgV2UgcnVuIGl0IHRocm91Z2ggdGhlIG5hbWUgbG9va3VwLgorICAgICAgICBlbnRyeSA9IGdldEVudHJ5KGVudHJ5LmdldE5hbWUoKSk7CisgICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIENyZWF0ZSBhbiBJbnB1dFN0cmVhbSBhdCB0aGUgcmlnaHQgcGFydCBvZiB0aGUgZmlsZS4KKyAgICAgICAgUmFuZG9tQWNjZXNzRmlsZSByYWYgPSBtUmFmOworICAgICAgICBzeW5jaHJvbml6ZWQgKHJhZikgeworICAgICAgICAgICAgLy8gV2UgZG9uJ3Qga25vdyB0aGUgZW50cnkgZGF0YSdzIHN0YXJ0IHBvc2l0aW9uLiBBbGwgd2UgaGF2ZSBpcyB0aGUKKyAgICAgICAgICAgIC8vIHBvc2l0aW9uIG9mIHRoZSBlbnRyeSdzIGxvY2FsIGhlYWRlci4gQXQgcG9zaXRpb24gMjggd2UgZmluZCB0aGUKKyAgICAgICAgICAgIC8vIGxlbmd0aCBvZiB0aGUgZXh0cmEgZGF0YS4gSW4gc29tZSBjYXNlcyB0aGlzIGxlbmd0aCBkaWZmZXJzIGZyb20KKyAgICAgICAgICAgIC8vIHRoZSBvbmUgY29taW5nIGluIHRoZSBjZW50cmFsIGhlYWRlci4KKyAgICAgICAgICAgIFJBRlN0cmVhbSByYWZzdHJtID0gbmV3IFJBRlN0cmVhbShyYWYsIGVudHJ5Lm1Mb2NhbEhlYWRlclJlbE9mZnNldCArIDI4KTsKKyAgICAgICAgICAgIERhdGFJbnB1dFN0cmVhbSBpcyA9IG5ldyBEYXRhSW5wdXRTdHJlYW0ocmFmc3RybSk7CisgICAgICAgICAgICBpbnQgbG9jYWxFeHRyYUxlbk9yV2hhdGV2ZXIgPSBTaG9ydC5yZXZlcnNlQnl0ZXMoaXMucmVhZFNob3J0KCkpOworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKworICAgICAgICAgICAgLy8gU2tpcCB0aGUgbmFtZSBhbmQgdGhpcyAiZXh0cmEiIGRhdGEgb3Igd2hhdGV2ZXIgaXQgaXM6CisgICAgICAgICAgICByYWZzdHJtLnNraXAoZW50cnkubmFtZUxlbmd0aCArIGxvY2FsRXh0cmFMZW5PcldoYXRldmVyKTsKKyAgICAgICAgICAgIHJhZnN0cm0ubUxlbmd0aCA9IHJhZnN0cm0ubU9mZnNldCArIGVudHJ5LmNvbXByZXNzZWRTaXplOworICAgICAgICAgICAgaWYgKGVudHJ5LmNvbXByZXNzaW9uTWV0aG9kID09IFppcEVudHJ5LkRFRkxBVEVEKSB7CisgICAgICAgICAgICAgICAgaW50IGJ1ZlNpemUgPSBNYXRoLm1heCgxMDI0LCAoaW50KU1hdGgubWluKGVudHJ5LmdldFNpemUoKSwgNjU1MzVMKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBaaXBJbmZsYXRlcklucHV0U3RyZWFtKHJhZnN0cm0sIG5ldyBJbmZsYXRlcih0cnVlKSwgYnVmU2l6ZSwgZW50cnkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmFmc3RybTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGZpbGUgbmFtZSBvZiB0aGlzIHtAY29kZSBaaXBGaWxlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGZpbGUgbmFtZSBvZiB0aGlzIHtAY29kZSBaaXBGaWxlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBmaWxlTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Yge0Bjb2RlIFppcEVudHJpZXN9IGluIHRoaXMge0Bjb2RlIFppcEZpbGV9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGVudHJpZXMgaW4gdGhpcyBmaWxlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgWklQIGZpbGUgaGFzIGJlZW4gY2xvc2VkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgcmV0dXJuIG1FbnRyaWVzLnNpemUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kIHRoZSBjZW50cmFsIGRpcmVjdG9yeSBhbmQgcmVhZCB0aGUgY29udGVudHMuCisgICAgICoKKyAgICAgKiA8cD5UaGUgY2VudHJhbCBkaXJlY3RvcnkgY2FuIGJlIGZvbGxvd2VkIGJ5IGEgdmFyaWFibGUtbGVuZ3RoIGNvbW1lbnQKKyAgICAgKiBmaWVsZCwgc28gd2UgaGF2ZSB0byBzY2FuIHRocm91Z2ggaXQgYmFja3dhcmRzLiAgVGhlIGNvbW1lbnQgaXMgYXQKKyAgICAgKiBtb3N0IDY0SywgcGx1cyB3ZSBoYXZlIDE4IGJ5dGVzIGZvciB0aGUgZW5kLW9mLWNlbnRyYWwtZGlyIHN0dWZmCisgICAgICogaXRzZWxmLCBwbHVzIGFwcGFyZW50bHkgc29tZXRpbWVzIHBlb3BsZSB0aHJvdyByYW5kb20ganVuayBvbiB0aGUgZW5kCisgICAgICoganVzdCBmb3IgdGhlIGZ1biBvZiBpdC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaXMgYWxsIGEgbGl0dGxlIHdvYmJseS4gIElmIHRoZSB3cm9uZyB2YWx1ZSBlbmRzIHVwIGluIHRoZSBFT0NECisgICAgICogYXJlYSwgd2UncmUgaG9zZWQuIFRoaXMgYXBwZWFycyB0byBiZSB0aGUgd2F5IHRoYXQgZXZlcnlib2R5IGhhbmRsZXMKKyAgICAgKiBpdCB0aG91Z2gsIHNvIHdlJ3JlIGluIGdvb2QgY29tcGFueSBpZiB0aGlzIGZhaWxzLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkQ2VudHJhbERpcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8qCisgICAgICAgICAqIFNjYW4gYmFjaywgbG9va2luZyBmb3IgdGhlIEVuZCBPZiBDZW50cmFsIERpcmVjdG9yeSBmaWVsZC4gIElmCisgICAgICAgICAqIHRoZSBhcmNoaXZlIGRvZXNuJ3QgaGF2ZSBhIGNvbW1lbnQsIHdlJ2xsIGhpdCBpdCBvbiB0aGUgZmlyc3QKKyAgICAgICAgICogdHJ5LgorICAgICAgICAgKgorICAgICAgICAgKiBObyBuZWVkIHRvIHN5bmNocm9uaXplIG1SYWYgaGVyZSAtLSB3ZSBvbmx5IGRvIHRoaXMgd2hlbiB3ZQorICAgICAgICAgKiBmaXJzdCBvcGVuIHRoZSBaaXAgZmlsZS4KKyAgICAgICAgICovCisgICAgICAgIGxvbmcgc2Nhbk9mZnNldCA9IG1SYWYubGVuZ3RoKCkgLSBFTkRIRFI7CisgICAgICAgIGlmIChzY2FuT2Zmc2V0IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFppcEV4Y2VwdGlvbigidG9vIHNob3J0IHRvIGJlIFppcCIpOworICAgICAgICB9CisKKyAgICAgICAgbG9uZyBzdG9wT2Zmc2V0ID0gc2Nhbk9mZnNldCAtIDY1NTM2OworICAgICAgICBpZiAoc3RvcE9mZnNldCA8IDApIHsKKyAgICAgICAgICAgIHN0b3BPZmZzZXQgPSAwOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgaW50IEVOREhFQURFUk1BR0lDID0gMHgwNjA1NGI1MDsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIG1SYWYuc2VlayhzY2FuT2Zmc2V0KTsKKyAgICAgICAgICAgIGlmIChJbnRlZ2VyLnJldmVyc2VCeXRlcyhtUmFmLnJlYWRJbnQoKSkgPT0gRU5ESEVBREVSTUFHSUMpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc2Nhbk9mZnNldC0tOworICAgICAgICAgICAgaWYgKHNjYW5PZmZzZXQgPCBzdG9wT2Zmc2V0KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFppcEV4Y2VwdGlvbigiRU9DRCBub3QgZm91bmQ7IG5vdCBhIFppcCBhcmNoaXZlPyIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gUmVhZCB0aGUgRW5kIE9mIENlbnRyYWwgRGlyZWN0b3J5LiBXZSBjb3VsZCB1c2UgRU5ESERSIGluc3RlYWQgb2YgdGhlIG1hZ2ljIG51bWJlciAxOCwKKyAgICAgICAgLy8gYnV0IHdlIGRvbid0IGFjdHVhbGx5IG5lZWQgYWxsIHRoZSBoZWFkZXIuCisgICAgICAgIGJ5dGVbXSBlb2NkID0gbmV3IGJ5dGVbMThdOworICAgICAgICBtUmFmLnJlYWRGdWxseShlb2NkKTsKKworICAgICAgICAvLyBQdWxsIG91dCB0aGUgaW5mb3JtYXRpb24gd2UgbmVlZC4KKyAgICAgICAgQnVmZmVySXRlcmF0b3IgaXQgPSBIZWFwQnVmZmVySXRlcmF0b3IuaXRlcmF0b3IoZW9jZCwgMCwgZW9jZC5sZW5ndGgsIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKTsKKyAgICAgICAgc2hvcnQgZGlza051bWJlciA9IGl0LnJlYWRTaG9ydCgpOworICAgICAgICBzaG9ydCBkaXNrV2l0aENlbnRyYWxEaXIgPSBpdC5yZWFkU2hvcnQoKTsKKyAgICAgICAgc2hvcnQgbnVtRW50cmllcyA9IGl0LnJlYWRTaG9ydCgpOworICAgICAgICBzaG9ydCB0b3RhbE51bUVudHJpZXMgPSBpdC5yZWFkU2hvcnQoKTsKKyAgICAgICAgaXQuc2tpcCg0KTsgLy8gSWdub3JlIGNlbnRyYWxEaXJTaXplLgorICAgICAgICBpbnQgY2VudHJhbERpck9mZnNldCA9IGl0LnJlYWRJbnQoKTsKKworICAgICAgICBpZiAobnVtRW50cmllcyAhPSB0b3RhbE51bUVudHJpZXMgfHwgZGlza051bWJlciAhPSAwIHx8IGRpc2tXaXRoQ2VudHJhbERpciAhPSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJzcGFubmVkIGFyY2hpdmVzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFNlZWsgdG8gdGhlIGZpcnN0IENERSBhbmQgcmVhZCBhbGwgZW50cmllcy4KKyAgICAgICAgUkFGU3RyZWFtIHJhZnMgPSBuZXcgUkFGU3RyZWFtKG1SYWYsIGNlbnRyYWxEaXJPZmZzZXQpOworICAgICAgICBCdWZmZXJlZElucHV0U3RyZWFtIGJpbiA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKHJhZnMsIDQwOTYpOworICAgICAgICBieXRlW10gaGRyQnVmID0gbmV3IGJ5dGVbQ0VOSERSXTsgLy8gUmV1c2UgdGhlIHNhbWUgYnVmZmVyIGZvciBlYWNoIGVudHJ5LgorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUVudHJpZXM7ICsraSkgeworICAgICAgICAgICAgWmlwRW50cnkgbmV3RW50cnkgPSBuZXcgWmlwRW50cnkoaGRyQnVmLCBiaW4pOworICAgICAgICAgICAgbUVudHJpZXMucHV0KG5ld0VudHJ5LmdldE5hbWUoKSwgbmV3RW50cnkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JhcCBhIHN0cmVhbSBhcm91bmQgYSBSYW5kb21BY2Nlc3NGaWxlLiAgVGhlIFJhbmRvbUFjY2Vzc0ZpbGUgaXMgc2hhcmVkCisgICAgICogYW1vbmcgYWxsIHN0cmVhbXMgcmV0dXJuZWQgYnkgZ2V0SW5wdXRTdHJlYW0oKSwgc28gd2UgaGF2ZSB0byBzeW5jaHJvbml6ZQorICAgICAqIGFjY2VzcyB0byBpdC4gIChXZSBjYW4gb3B0aW1pemUgdGhpcyBieSBhZGRpbmcgYnVmZmVyaW5nIGhlcmUgdG8gcmVkdWNlCisgICAgICogY29sbGlzaW9ucy4pCisgICAgICoKKyAgICAgKiA8cD5XZSBjb3VsZCBzdXBwb3J0IG1hcmsvcmVzZXQsIGJ1dCB3ZSBkb24ndCBjdXJyZW50bHkgbmVlZCB0aGVtLgorICAgICAqLworICAgIHN0YXRpYyBjbGFzcyBSQUZTdHJlYW0gZXh0ZW5kcyBJbnB1dFN0cmVhbSB7CisKKyAgICAgICAgUmFuZG9tQWNjZXNzRmlsZSBtU2hhcmVkUmFmOworICAgICAgICBsb25nIG1PZmZzZXQ7CisgICAgICAgIGxvbmcgbUxlbmd0aDsKKworICAgICAgICBwdWJsaWMgUkFGU3RyZWFtKFJhbmRvbUFjY2Vzc0ZpbGUgcmFmLCBsb25nIHBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIG1TaGFyZWRSYWYgPSByYWY7CisgICAgICAgICAgICBtT2Zmc2V0ID0gcG9zOworICAgICAgICAgICAgbUxlbmd0aCA9IHJhZi5sZW5ndGgoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gKG1PZmZzZXQgPCBtTGVuZ3RoID8gMSA6IDApOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gU3RyZWFtcy5yZWFkU2luZ2xlQnl0ZSh0aGlzKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG1TaGFyZWRSYWYpIHsKKyAgICAgICAgICAgICAgICBtU2hhcmVkUmFmLnNlZWsobU9mZnNldCk7CisgICAgICAgICAgICAgICAgaWYgKGxlbiA+IG1MZW5ndGggLSBtT2Zmc2V0KSB7CisgICAgICAgICAgICAgICAgICAgIGxlbiA9IChpbnQpIChtTGVuZ3RoIC0gbU9mZnNldCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGludCBjb3VudCA9IG1TaGFyZWRSYWYucmVhZChiLCBvZmYsIGxlbik7CisgICAgICAgICAgICAgICAgaWYgKGNvdW50ID4gMCkgeworICAgICAgICAgICAgICAgICAgICBtT2Zmc2V0ICs9IGNvdW50OworICAgICAgICAgICAgICAgICAgICByZXR1cm4gY291bnQ7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgbG9uZyBza2lwKGxvbmcgYnl0ZUNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaWYgKGJ5dGVDb3VudCA+IG1MZW5ndGggLSBtT2Zmc2V0KSB7CisgICAgICAgICAgICAgICAgYnl0ZUNvdW50ID0gbUxlbmd0aCAtIG1PZmZzZXQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtT2Zmc2V0ICs9IGJ5dGVDb3VudDsKKyAgICAgICAgICAgIHJldHVybiBieXRlQ291bnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgWmlwSW5mbGF0ZXJJbnB1dFN0cmVhbSBleHRlbmRzIEluZmxhdGVySW5wdXRTdHJlYW0geworCisgICAgICAgIFppcEVudHJ5IGVudHJ5OworICAgICAgICBsb25nIGJ5dGVzUmVhZCA9IDA7CisKKyAgICAgICAgcHVibGljIFppcEluZmxhdGVySW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaXMsIEluZmxhdGVyIGluZiwgaW50IGJzaXplLCBaaXBFbnRyeSBlbnRyeSkgeworICAgICAgICAgICAgc3VwZXIoaXMsIGluZiwgYnNpemUpOworICAgICAgICAgICAgdGhpcy5lbnRyeSA9IGVudHJ5OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmZmVyLCBpbnQgb2ZmLCBpbnQgbmJ5dGVzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaW50IGkgPSBzdXBlci5yZWFkKGJ1ZmZlciwgb2ZmLCBuYnl0ZXMpOworICAgICAgICAgICAgaWYgKGkgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICBieXRlc1JlYWQgKz0gaTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChjbG9zZWQpIHsKKyAgICAgICAgICAgICAgICAvLyBPdXIgc3VwZXJjbGFzcyB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiwgYnV0IHRoZXJlJ3MgYSBqdHJlZyB0ZXN0IHRoYXQKKyAgICAgICAgICAgICAgICAvLyBleHBsaWNpdGx5IGNoZWNrcyB0aGF0IHRoZSBJbnB1dFN0cmVhbSByZXR1cm5lZCBmcm9tIFppcEZpbGUuZ2V0SW5wdXRTdHJlYW0KKyAgICAgICAgICAgICAgICAvLyByZXR1cm5zIDAgZXZlbiB3aGVuIGNsb3NlZC4KKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBzdXBlci5hdmFpbGFibGUoKSA9PSAwID8gMCA6IChpbnQpIChlbnRyeS5nZXRTaXplKCkgLSBieXRlc1JlYWQpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvWmlwSW5wdXRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL1ppcElucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzlmMjVjMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZhL3V0aWwvemlwL1ppcElucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwzNjcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC56aXA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QdXNoYmFja0lucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLkJ5dGVPcmRlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0Lk1vZGlmaWVkVXRmODsKK2ltcG9ydCBqYXZhLnV0aWwuamFyLkF0dHJpYnV0ZXM7CitpbXBvcnQgamF2YS51dGlsLmphci5KYXJFbnRyeTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGxpYmNvcmUuaW8uTWVtb3J5OworaW1wb3J0IGxpYmNvcmUuaW8uU3RyZWFtczsKKworLyoqCisgKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGFuIGltcGxlbWVudGF0aW9uIG9mIHtAY29kZSBGaWx0ZXJJbnB1dFN0cmVhbX0gdGhhdAorICogZGVjb21wcmVzc2VzIGRhdGEgZnJvbSBhbiB7QGNvZGUgSW5wdXRTdHJlYW19IGNvbnRhaW5pbmcgYSBaSVAgYXJjaGl2ZS4KKyAqCisgKiA8cD5BIFpJUCBhcmNoaXZlIGlzIGEgY29sbGVjdGlvbiBvZiAocG9zc2libHkpIGNvbXByZXNzZWQgZmlsZXMuCisgKiBXaGVuIHJlYWRpbmcgZnJvbSBhIHtAY29kZSBaaXBJbnB1dFN0cmVhbX0sIHlvdSByZXRyaWV2ZSB0aGUKKyAqIGVudHJ5J3MgbWV0YWRhdGEgd2l0aCB7QGNvZGUgZ2V0TmV4dEVudHJ5fSBiZWZvcmUgeW91IGNhbiByZWFkIHRoZSB1c2VyZGF0YS4KKyAqCisgKiA8cD5BbHRob3VnaCB7QGNvZGUgSW5mbGF0ZXJJbnB1dFN0cmVhbX0gY2FuIG9ubHkgcmVhZCBjb21wcmVzc2VkIFpJUCBhcmNoaXZlCisgKiBlbnRyaWVzLCB0aGlzIGNsYXNzIGNhbiByZWFkIG5vbi1jb21wcmVzc2VkIGVudHJpZXMgYXMgd2VsbC4KKyAqCisgKiA8cD5Vc2Uge0Bjb2RlIFppcEZpbGV9IGlmIHlvdSBjYW4gYWNjZXNzIHRoZSBhcmNoaXZlIGFzIGEgZmlsZSBkaXJlY3RseSwKKyAqIGVzcGVjaWFsbHkgaWYgeW91IHdhbnQgcmFuZG9tIGFjY2VzcyB0byBlbnRyaWVzLCByYXRoZXIgdGhhbiBuZWVkaW5nIHRvCisgKiBpdGVyYXRlIG92ZXIgYWxsIGVudHJpZXMuCisgKgorICogPGgzPkV4YW1wbGU8L2gzPgorICogPHA+VXNpbmcge0Bjb2RlIFppcElucHV0U3RyZWFtfSBpcyBhIGxpdHRsZSBtb3JlIGNvbXBsaWNhdGVkIHRoYW4ge0BsaW5rIEdaSVBJbnB1dFN0cmVhbX0KKyAqIGJlY2F1c2UgWklQIGFyY2hpdmVzIGFyZSBjb250YWluZXJzIHRoYXQgY2FuIGNvbnRhaW4gbXVsdGlwbGUgZmlsZXMuIFRoaXMgY29kZSBwdWxscyBhbGwgdGhlCisgKiBmaWxlcyBvdXQgb2YgYSBaSVAgYXJjaGl2ZSwgc2ltaWxhciB0byB0aGUge0Bjb2RlIHVuemlwKDEpfSB1dGlsaXR5LgorICogPHByZT4KKyAqIElucHV0U3RyZWFtIGlzID0gLi4uCisgKiBaaXBJbnB1dFN0cmVhbSB6aXMgPSBuZXcgWmlwSW5wdXRTdHJlYW0obmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oaXMpKTsKKyAqIHRyeSB7CisgKiAgICAgWmlwRW50cnkgemU7CisgKiAgICAgd2hpbGUgKCh6ZSA9IHppcy5nZXROZXh0RW50cnkoKSkgIT0gbnVsbCkgeworICogICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAqICAgICAgICAgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlWzEwMjRdOworICogICAgICAgICBpbnQgY291bnQ7CisgKiAgICAgICAgIHdoaWxlICgoY291bnQgPSB6aXMucmVhZChidWZmZXIpKSAhPSAtMSkgeworICogICAgICAgICAgICAgYmFvcy53cml0ZShidWZmZXIsIDAsIGNvdW50KTsKKyAqICAgICAgICAgfQorICogICAgICAgICBTdHJpbmcgZmlsZW5hbWUgPSB6ZS5nZXROYW1lKCk7CisgKiAgICAgICAgIGJ5dGVbXSBieXRlcyA9IGJhb3MudG9CeXRlQXJyYXkoKTsKKyAqICAgICAgICAgLy8gZG8gc29tZXRoaW5nIHdpdGggJ2ZpbGVuYW1lJyBhbmQgJ2J5dGVzJy4uLgorICogICAgIH0KKyAqIH0gZmluYWxseSB7CisgKiAgICAgemlzLmNsb3NlKCk7CisgKiB9CisgKiA8L3ByZT4KKyAqCisgKiBAc2VlIFppcEVudHJ5CisgKiBAc2VlIFppcEZpbGUKKyAqLworcHVibGljIGNsYXNzIFppcElucHV0U3RyZWFtIGV4dGVuZHMgSW5mbGF0ZXJJbnB1dFN0cmVhbSBpbXBsZW1lbnRzIFppcENvbnN0YW50cyB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFpJUExvY2FsSGVhZGVyVmVyc2lvbk5lZWRlZCA9IDIwOworCisgICAgcHJpdmF0ZSBib29sZWFuIGVudHJpZXNFbmQgPSBmYWxzZTsKKworICAgIHByaXZhdGUgYm9vbGVhbiBoYXNERCA9IGZhbHNlOworCisgICAgcHJpdmF0ZSBpbnQgZW50cnlJbiA9IDA7CisKKyAgICBwcml2YXRlIGludCBpblJlYWQsIGxhc3RSZWFkID0gMDsKKworICAgIHByaXZhdGUgWmlwRW50cnkgY3VycmVudEVudHJ5OworCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gaGRyQnVmID0gbmV3IGJ5dGVbTE9DSERSIC0gTE9DVkVSXTsKKworICAgIHByaXZhdGUgZmluYWwgQ1JDMzIgY3JjID0gbmV3IENSQzMyKCk7CisKKyAgICBwcml2YXRlIGJ5dGVbXSBuYW1lQnVmID0gbmV3IGJ5dGVbMjU2XTsKKworICAgIHByaXZhdGUgY2hhcltdIGNoYXJCdWYgPSBuZXcgY2hhclsyNTZdOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyB7QGNvZGUgWmlwSW5wdXRTdHJlYW19IGZyb20gdGhlIHNwZWNpZmllZCBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyZWFtCisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgc3RyZWFtIHRvIHJlcHJlc2VudGluZyBhIFpJUCBhcmNoaXZlLgorICAgICAqLworICAgIHB1YmxpYyBaaXBJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBzdHJlYW0pIHsKKyAgICAgICAgc3VwZXIobmV3IFB1c2hiYWNrSW5wdXRTdHJlYW0oc3RyZWFtLCBCVUZfU0laRSksIG5ldyBJbmZsYXRlcih0cnVlKSk7CisgICAgICAgIGlmIChzdHJlYW0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhpcyB7QGNvZGUgWmlwSW5wdXRTdHJlYW19LgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIHtAY29kZSBJT0V4Y2VwdGlvbn0gb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFjbG9zZWQpIHsKKyAgICAgICAgICAgIGNsb3NlRW50cnkoKTsgLy8gQ2xvc2UgdGhlIGN1cnJlbnQgZW50cnkKKyAgICAgICAgICAgIHN1cGVyLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhlIGN1cnJlbnQgWklQIGVudHJ5IGFuZCBwb3NpdGlvbnMgdG8gcmVhZCB0aGUgbmV4dCBlbnRyeS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiB7QGNvZGUgSU9FeGNlcHRpb259IG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbG9zZUVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tDbG9zZWQoKTsKKyAgICAgICAgaWYgKGN1cnJlbnRFbnRyeSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKGN1cnJlbnRFbnRyeSBpbnN0YW5jZW9mIGphdmEudXRpbC5qYXIuSmFyRW50cnkpIHsKKyAgICAgICAgICAgIEF0dHJpYnV0ZXMgdGVtcCA9ICgoSmFyRW50cnkpIGN1cnJlbnRFbnRyeSkuZ2V0QXR0cmlidXRlcygpOworICAgICAgICAgICAgaWYgKHRlbXAgIT0gbnVsbCAmJiB0ZW1wLmNvbnRhaW5zS2V5KCJoaWRkZW4iKSkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIFRoZSBmb2xsb3dpbmcgY29kZSBpcyBjYXJlZnVsIHRvIGxlYXZlIHRoZSBaaXBJbnB1dFN0cmVhbSBpbiBhCisgICAgICAgICAqIGNvbnNpc3RlbnQgc3RhdGUsIGV2ZW4gd2hlbiBjbG9zZSgpIHJlc3VsdHMgaW4gYW4gZXhjZXB0aW9uLiBJdCBkb2VzCisgICAgICAgICAqIHNvIGJ5OgorICAgICAgICAgKiAgLSBwdXNoaW5nIGJ5dGVzIGJhY2sgaW50byB0aGUgc291cmNlIHN0cmVhbQorICAgICAgICAgKiAgLSByZWFkaW5nIGEgZGF0YSBkZXNjcmlwdG9yIGZvb3RlciBmcm9tIHRoZSBzb3VyY2Ugc3RyZWFtCisgICAgICAgICAqICAtIHJlc2V0dGluZyBmaWVsZHMgdGhhdCBtYW5hZ2UgdGhlIGVudHJ5IGJlaW5nIGNsb3NlZAorICAgICAgICAgKi8KKworICAgICAgICAvLyBFbnN1cmUgYWxsIGVudHJ5IGJ5dGVzIGFyZSByZWFkCisgICAgICAgIEV4Y2VwdGlvbiBmYWlsdXJlID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmVhbXMuc2tpcEFsbCh0aGlzKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWx1cmUgPSBlOworICAgICAgICB9CisKKyAgICAgICAgaW50IGluQiwgb3V0OworICAgICAgICBpZiAoY3VycmVudEVudHJ5LmNvbXByZXNzaW9uTWV0aG9kID09IFppcEVudHJ5LkRFRkxBVEVEKSB7CisgICAgICAgICAgICBpbkIgPSBpbmYuZ2V0VG90YWxJbigpOworICAgICAgICAgICAgb3V0ID0gaW5mLmdldFRvdGFsT3V0KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpbkIgPSBpblJlYWQ7CisgICAgICAgICAgICBvdXQgPSBpblJlYWQ7CisgICAgICAgIH0KKyAgICAgICAgaW50IGRpZmYgPSBlbnRyeUluIC0gaW5COworICAgICAgICAvLyBQdXNoYmFjayBhbnkgcmVxdWlyZWQgYnl0ZXMKKyAgICAgICAgaWYgKGRpZmYgIT0gMCkgeworICAgICAgICAgICAgKChQdXNoYmFja0lucHV0U3RyZWFtKSBpbikudW5yZWFkKGJ1ZiwgbGVuIC0gZGlmZiwgZGlmZik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZEFuZFZlcmlmeURhdGFEZXNjcmlwdG9yKGluQiwgb3V0KTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGlmIChmYWlsdXJlID09IG51bGwpIHsgLy8gb3RoZXJ3aXNlIHdlJ3JlIGFscmVhZHkgZ29pbmcgdG8gdGhyb3cKKyAgICAgICAgICAgICAgICBmYWlsdXJlID0gZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGluZi5yZXNldCgpOworICAgICAgICBsYXN0UmVhZCA9IGluUmVhZCA9IGVudHJ5SW4gPSBsZW4gPSAwOworICAgICAgICBjcmMucmVzZXQoKTsKKyAgICAgICAgY3VycmVudEVudHJ5ID0gbnVsbDsKKworICAgICAgICBpZiAoZmFpbHVyZSAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoZmFpbHVyZSBpbnN0YW5jZW9mIElPRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgKElPRXhjZXB0aW9uKSBmYWlsdXJlOworICAgICAgICAgICAgfSBlbHNlIGlmIChmYWlsdXJlIGluc3RhbmNlb2YgUnVudGltZUV4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgIHRocm93IChSdW50aW1lRXhjZXB0aW9uKSBmYWlsdXJlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQXNzZXJ0aW9uRXJyb3IgZXJyb3IgPSBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKKyAgICAgICAgICAgIGVycm9yLmluaXRDYXVzZShmYWlsdXJlKTsKKyAgICAgICAgICAgIHRocm93IGVycm9yOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRBbmRWZXJpZnlEYXRhRGVzY3JpcHRvcihpbnQgaW5CLCBpbnQgb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaGFzREQpIHsKKyAgICAgICAgICAgIFN0cmVhbXMucmVhZEZ1bGx5KGluLCBoZHJCdWYsIDAsIEVYVEhEUik7CisgICAgICAgICAgICBpbnQgc2lnID0gTWVtb3J5LnBlZWtJbnQoaGRyQnVmLCAwLCBCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisgICAgICAgICAgICBpZiAoc2lnICE9IChpbnQpIEVYVFNJRykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBaaXBFeGNlcHRpb24oU3RyaW5nLmZvcm1hdCgidW5rbm93biBmb3JtYXQgKEVYVFNJRz0leCkiLCBzaWcpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGN1cnJlbnRFbnRyeS5jcmMgPSAoKGxvbmcpIE1lbW9yeS5wZWVrSW50KGhkckJ1ZiwgRVhUQ1JDLCBCeXRlT3JkZXIuTElUVExFX0VORElBTikpICYgMHhmZmZmZmZmZkw7CisgICAgICAgICAgICBjdXJyZW50RW50cnkuY29tcHJlc3NlZFNpemUgPSAoKGxvbmcpIE1lbW9yeS5wZWVrSW50KGhkckJ1ZiwgRVhUU0laLCBCeXRlT3JkZXIuTElUVExFX0VORElBTikpICYgMHhmZmZmZmZmZkw7CisgICAgICAgICAgICBjdXJyZW50RW50cnkuc2l6ZSA9ICgobG9uZykgTWVtb3J5LnBlZWtJbnQoaGRyQnVmLCBFWFRMRU4sIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSkgJiAweGZmZmZmZmZmTDsKKyAgICAgICAgfQorICAgICAgICBpZiAoY3VycmVudEVudHJ5LmNyYyAhPSBjcmMuZ2V0VmFsdWUoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFppcEV4Y2VwdGlvbigiQ1JDIG1pc21hdGNoIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGN1cnJlbnRFbnRyeS5jb21wcmVzc2VkU2l6ZSAhPSBpbkIgfHwgY3VycmVudEVudHJ5LnNpemUgIT0gb3V0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJTaXplIG1pc21hdGNoIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB0aGUgbmV4dCBlbnRyeSBmcm9tIHRoaXMge0Bjb2RlIFppcElucHV0U3RyZWFtfSBvciB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiBubyBtb3JlIGVudHJpZXMgYXJlIHByZXNlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IHtAY29kZSBaaXBFbnRyeX0gY29udGFpbmVkIGluIHRoZSBpbnB1dCBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIHtAY29kZSBJT0V4Y2VwdGlvbn0gb2NjdXJzLgorICAgICAqIEBzZWUgWmlwRW50cnkKKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwRW50cnkgZ2V0TmV4dEVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2xvc2VFbnRyeSgpOworICAgICAgICBpZiAoZW50cmllc0VuZCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBTdHJlYW1zLnJlYWRGdWxseShpbiwgaGRyQnVmLCAwLCA0KTsKKyAgICAgICAgaW50IGhkciA9IE1lbW9yeS5wZWVrSW50KGhkckJ1ZiwgMCwgQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pOworICAgICAgICBpZiAoaGRyID09IENFTlNJRykgeworICAgICAgICAgICAgZW50cmllc0VuZCA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaGRyICE9IExPQ1NJRykgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvLyBSZWFkIHRoZSBsb2NhbCBoZWFkZXIKKyAgICAgICAgU3RyZWFtcy5yZWFkRnVsbHkoaW4sIGhkckJ1ZiwgMCwgKExPQ0hEUiAtIExPQ1ZFUikpOworICAgICAgICBpbnQgdmVyc2lvbiA9IE1lbW9yeS5wZWVrU2hvcnQoaGRyQnVmLCAwLCBCeXRlT3JkZXIuTElUVExFX0VORElBTikgJiAweGZmOworICAgICAgICBpZiAodmVyc2lvbiA+IFpJUExvY2FsSGVhZGVyVmVyc2lvbk5lZWRlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFppcEV4Y2VwdGlvbigiQ2Fubm90IHJlYWQgbG9jYWwgaGVhZGVyIHZlcnNpb24gIiArIHZlcnNpb24pOworICAgICAgICB9CisgICAgICAgIHNob3J0IGZsYWdzID0gTWVtb3J5LnBlZWtTaG9ydChoZHJCdWYsIExPQ0ZMRyAtIExPQ1ZFUiwgQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pOworICAgICAgICBoYXNERCA9ICgoZmxhZ3MgJiBaaXBGaWxlLkdQQkZfREFUQV9ERVNDUklQVE9SX0ZMQUcpICE9IDApOworICAgICAgICBpbnQgY2VUaW1lID0gTWVtb3J5LnBlZWtTaG9ydChoZHJCdWYsIExPQ1RJTSAtIExPQ1ZFUiwgQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pICYgMHhmZmZmOworICAgICAgICBpbnQgY2VNb2REYXRlID0gTWVtb3J5LnBlZWtTaG9ydChoZHJCdWYsIExPQ1RJTSAtIExPQ1ZFUiArIDIsIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSAmIDB4ZmZmZjsKKyAgICAgICAgaW50IGNlQ29tcHJlc3Npb25NZXRob2QgPSBNZW1vcnkucGVla1Nob3J0KGhkckJ1ZiwgTE9DSE9XIC0gTE9DVkVSLCBCeXRlT3JkZXIuTElUVExFX0VORElBTikgJiAweGZmZmY7CisgICAgICAgIGxvbmcgY2VDcmMgPSAwLCBjZUNvbXByZXNzZWRTaXplID0gMCwgY2VTaXplID0gLTE7CisgICAgICAgIGlmICghaGFzREQpIHsKKyAgICAgICAgICAgIGNlQ3JjID0gKChsb25nKSBNZW1vcnkucGVla0ludChoZHJCdWYsIExPQ0NSQyAtIExPQ1ZFUiwgQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pKSAmIDB4ZmZmZmZmZmZMOworICAgICAgICAgICAgY2VDb21wcmVzc2VkU2l6ZSA9ICgobG9uZykgTWVtb3J5LnBlZWtJbnQoaGRyQnVmLCBMT0NTSVogLSBMT0NWRVIsIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSkgJiAweGZmZmZmZmZmTDsKKyAgICAgICAgICAgIGNlU2l6ZSA9ICgobG9uZykgTWVtb3J5LnBlZWtJbnQoaGRyQnVmLCBMT0NMRU4gLSBMT0NWRVIsIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSkgJiAweGZmZmZmZmZmTDsKKyAgICAgICAgfQorICAgICAgICBpbnQgbmFtZUxlbmd0aCA9IE1lbW9yeS5wZWVrU2hvcnQoaGRyQnVmLCBMT0NOQU0gLSBMT0NWRVIsIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSAmIDB4ZmZmZjsKKyAgICAgICAgaWYgKG5hbWVMZW5ndGggPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFppcEV4Y2VwdGlvbigiRW50cnkgaXMgbm90IG5hbWVkIik7CisgICAgICAgIH0KKyAgICAgICAgaW50IGV4dHJhTGVuZ3RoID0gTWVtb3J5LnBlZWtTaG9ydChoZHJCdWYsIExPQ0VYVCAtIExPQ1ZFUiwgQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pICYgMHhmZmZmOworCisgICAgICAgIGlmIChuYW1lTGVuZ3RoID4gbmFtZUJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgIG5hbWVCdWYgPSBuZXcgYnl0ZVtuYW1lTGVuZ3RoXTsKKyAgICAgICAgICAgIC8vIFRoZSBieXRlcyBhcmUgbW9kaWZpZWQgVVRGLTgsIHNvIHRoZSBudW1iZXIgb2YgY2hhcnMgd2lsbCBhbHdheXMgYmUgbGVzcyB0aGFuIG9yCisgICAgICAgICAgICAvLyBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGJ5dGVzLiBJdCdzIGZpbmUgaWYgdGhpcyBidWZmZXIgaXMgdG9vIGxvbmcuCisgICAgICAgICAgICBjaGFyQnVmID0gbmV3IGNoYXJbbmFtZUxlbmd0aF07CisgICAgICAgIH0KKyAgICAgICAgU3RyZWFtcy5yZWFkRnVsbHkoaW4sIG5hbWVCdWYsIDAsIG5hbWVMZW5ndGgpOworICAgICAgICBjdXJyZW50RW50cnkgPSBjcmVhdGVaaXBFbnRyeShNb2RpZmllZFV0ZjguZGVjb2RlKG5hbWVCdWYsIGNoYXJCdWYsIDAsIG5hbWVMZW5ndGgpKTsKKyAgICAgICAgY3VycmVudEVudHJ5LnRpbWUgPSBjZVRpbWU7CisgICAgICAgIGN1cnJlbnRFbnRyeS5tb2REYXRlID0gY2VNb2REYXRlOworICAgICAgICBjdXJyZW50RW50cnkuc2V0TWV0aG9kKGNlQ29tcHJlc3Npb25NZXRob2QpOworICAgICAgICBpZiAoY2VTaXplICE9IC0xKSB7CisgICAgICAgICAgICBjdXJyZW50RW50cnkuc2V0Q3JjKGNlQ3JjKTsKKyAgICAgICAgICAgIGN1cnJlbnRFbnRyeS5zZXRTaXplKGNlU2l6ZSk7CisgICAgICAgICAgICBjdXJyZW50RW50cnkuc2V0Q29tcHJlc3NlZFNpemUoY2VDb21wcmVzc2VkU2l6ZSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGV4dHJhTGVuZ3RoID4gMCkgeworICAgICAgICAgICAgYnl0ZVtdIGV4dHJhRGF0YSA9IG5ldyBieXRlW2V4dHJhTGVuZ3RoXTsKKyAgICAgICAgICAgIFN0cmVhbXMucmVhZEZ1bGx5KGluLCBleHRyYURhdGEsIDAsIGV4dHJhTGVuZ3RoKTsKKyAgICAgICAgICAgIGN1cnJlbnRFbnRyeS5zZXRFeHRyYShleHRyYURhdGEpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjdXJyZW50RW50cnk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdXAgdG8gdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgdW5jb21wcmVzc2VkIGJ5dGVzIGludG8gdGhlIGJ1ZmZlcgorICAgICAqIHN0YXJ0aW5nIGF0IHRoZSBvZmZzZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja0Nsb3NlZCgpOworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXIubGVuZ3RoLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisKKyAgICAgICAgaWYgKGluZi5maW5pc2hlZCgpIHx8IGN1cnJlbnRFbnRyeSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKworICAgICAgICBpZiAoY3VycmVudEVudHJ5LmNvbXByZXNzaW9uTWV0aG9kID09IFppcEVudHJ5LlNUT1JFRCkgeworICAgICAgICAgICAgaW50IGNzaXplID0gKGludCkgY3VycmVudEVudHJ5LnNpemU7CisgICAgICAgICAgICBpZiAoaW5SZWFkID49IGNzaXplKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGxhc3RSZWFkID49IGxlbikgeworICAgICAgICAgICAgICAgIGxhc3RSZWFkID0gMDsKKyAgICAgICAgICAgICAgICBpZiAoKGxlbiA9IGluLnJlYWQoYnVmKSkgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgZW9mID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbnRyeUluICs9IGxlbjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCB0b1JlYWQgPSBieXRlQ291bnQgPiAobGVuIC0gbGFzdFJlYWQpID8gbGVuIC0gbGFzdFJlYWQgOiBieXRlQ291bnQ7CisgICAgICAgICAgICBpZiAoKGNzaXplIC0gaW5SZWFkKSA8IHRvUmVhZCkgeworICAgICAgICAgICAgICAgIHRvUmVhZCA9IGNzaXplIC0gaW5SZWFkOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWYsIGxhc3RSZWFkLCBidWZmZXIsIG9mZnNldCwgdG9SZWFkKTsKKyAgICAgICAgICAgIGxhc3RSZWFkICs9IHRvUmVhZDsKKyAgICAgICAgICAgIGluUmVhZCArPSB0b1JlYWQ7CisgICAgICAgICAgICBjcmMudXBkYXRlKGJ1ZmZlciwgb2Zmc2V0LCB0b1JlYWQpOworICAgICAgICAgICAgcmV0dXJuIHRvUmVhZDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5mLm5lZWRzSW5wdXQoKSkgeworICAgICAgICAgICAgZmlsbCgpOworICAgICAgICAgICAgaWYgKGxlbiA+IDApIHsKKyAgICAgICAgICAgICAgICBlbnRyeUluICs9IGxlbjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpbnQgcmVhZDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWQgPSBpbmYuaW5mbGF0ZShidWZmZXIsIG9mZnNldCwgYnl0ZUNvdW50KTsKKyAgICAgICAgfSBjYXRjaCAoRGF0YUZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocmVhZCA9PSAwICYmIGluZi5maW5pc2hlZCgpKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgY3JjLnVwZGF0ZShidWZmZXIsIG9mZnNldCwgcmVhZCk7CisgICAgICAgIHJldHVybiByZWFkOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tDbG9zZWQoKTsKKyAgICAgICAgLy8gVGhlIEluZmxhdGVySW5wdXRTdHJlYW0gY29udHJhY3Qgc2F5cyB3ZSBtdXN0IG9ubHkgcmV0dXJuIDAgb3IgMS4KKyAgICAgICAgcmV0dXJuIChjdXJyZW50RW50cnkgPT0gbnVsbCB8fCBpblJlYWQgPCBjdXJyZW50RW50cnkuc2l6ZSkgPyAxIDogMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBjcmVhdGVzIGEge0BsaW5rIFppcEVudHJ5IH0gd2l0aCB0aGUgZ2l2ZW4gbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZW50cnkuCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCB7QGNvZGUgWmlwRW50cnl9LgorICAgICAqLworICAgIHByb3RlY3RlZCBaaXBFbnRyeSBjcmVhdGVaaXBFbnRyeShTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gbmV3IFppcEVudHJ5KG5hbWUpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja0Nsb3NlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjbG9zZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU3RyZWFtIGlzIGNsb3NlZCIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvWmlwT3V0cHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YS91dGlsL3ppcC9aaXBPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MjQ4NDdhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmEvdXRpbC96aXAvWmlwT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw0MjcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmEudXRpbC56aXA7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldHM7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgYW4gaW1wbGVtZW50YXRpb24gb2Yge0Bjb2RlIEZpbHRlck91dHB1dFN0cmVhbX0gdGhhdAorICogY29tcHJlc3NlcyBkYXRhIGVudHJpZXMgaW50byBhIDxpPlpJUC1hcmNoaXZlPC9pPiBvdXRwdXQgc3RyZWFtLgorICogPHA+CisgKiB7QGNvZGUgWmlwT3V0cHV0U3RyZWFtfSBpcyB1c2VkIHRvIHdyaXRlIHtAY29kZSBaaXBFbnRyaWVzfSB0byB0aGUgdW5kZXJseWluZworICogc3RyZWFtLiBPdXRwdXQgZnJvbSB7QGNvZGUgWmlwT3V0cHV0U3RyZWFtfSBjb25mb3JtcyB0byB0aGUge0Bjb2RlIFppcEZpbGV9CisgKiBmaWxlIGZvcm1hdC4KKyAqIDxwPgorICogV2hpbGUge0Bjb2RlIERlZmxhdGVyT3V0cHV0U3RyZWFtfSBjYW4gd3JpdGUgYSBjb21wcmVzc2VkIDxpPlpJUC1hcmNoaXZlPC9pPgorICogZW50cnksIHRoaXMgZXh0ZW5zaW9uIGNhbiB3cml0ZSB1bmNvbXByZXNzZWQgZW50cmllcyBhcyB3ZWxsLiBJbiB0aGlzIGNhc2UKKyAqIHNwZWNpYWwgcnVsZXMgYXBwbHksIGZvciB0aGlzIHB1cnBvc2UgcmVmZXIgdG8gdGhlIDxhCisgKiBocmVmPSJodHRwOi8vd3d3LnBrd2FyZS5jb20vZG9jdW1lbnRzL2Nhc2VzdHVkaWVzL0FQUE5PVEUuVFhUIj5maWxlIGZvcm1hdAorICogc3BlY2lmaWNhdGlvbjwvYT4uCisgKgorICogPGgzPkV4YW1wbGU8L2gzPgorICogPHA+VXNpbmcge0Bjb2RlIFppcE91dHB1dFN0cmVhbX0gaXMgYSBsaXR0bGUgbW9yZSBjb21wbGljYXRlZCB0aGFuIHtAbGluayBHWklQT3V0cHV0U3RyZWFtfQorICogYmVjYXVzZSBaSVAgYXJjaGl2ZXMgYXJlIGNvbnRhaW5lcnMgdGhhdCBjYW4gY29udGFpbiBtdWx0aXBsZSBmaWxlcy4gVGhpcyBjb2RlIGNyZWF0ZXMgYSBaSVAKKyAqIGFyY2hpdmUgY29udGFpbmluZyBzZXZlcmFsIGZpbGVzLCBzaW1pbGFyIHRvIHRoZSB7QGNvZGUgemlwKDEpfSB1dGlsaXR5LgorICogPHByZT4KKyAqIE91dHB1dFN0cmVhbSBvcyA9IC4uLgorICogWmlwT3V0cHV0U3RyZWFtIHpvcyA9IG5ldyBaaXBPdXRwdXRTdHJlYW0obmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKG9zKSk7CisgKiB0cnkgeworICogICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZUNvdW50OyArK2kpIHsKKyAqICAgICAgICAgU3RyaW5nIGZpbGVuYW1lID0gLi4uCisgKiAgICAgICAgIGJ5dGVbXSBieXRlcyA9IC4uLgorICogICAgICAgICBaaXBFbnRyeSBlbnRyeSA9IG5ldyBaaXBFbnRyeShmaWxlbmFtZSk7CisgKiAgICAgICAgIHpvcy5wdXROZXh0RW50cnkoZW50cnkpOworICogICAgICAgICB6b3Mud3JpdGUoYnl0ZXMpOworICogICAgICAgICB6b3MuY2xvc2VFbnRyeSgpOworICogICAgIH0KKyAqIH0gZmluYWxseSB7CisgKiAgICAgem9zLmNsb3NlKCk7CisgKiB9CisgKiA8L3ByZT4KKyAqCisgKiBAc2VlIFppcEVudHJ5CisgKiBAc2VlIFppcEZpbGUKKyAqLworcHVibGljIGNsYXNzIFppcE91dHB1dFN0cmVhbSBleHRlbmRzIERlZmxhdGVyT3V0cHV0U3RyZWFtIGltcGxlbWVudHMgWmlwQ29uc3RhbnRzIHsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyBkZWZsYXRlZCBlbnRyaWVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkxBVEVEID0gODsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB1bmNvbXByZXNzZWQgZW50cmllcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVE9SRUQgPSAwOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFpJUExvY2FsSGVhZGVyVmVyc2lvbk5lZWRlZCA9IDIwOworCisgICAgcHJpdmF0ZSBTdHJpbmcgY29tbWVudDsKKworICAgIHByaXZhdGUgZmluYWwgQXJyYXlMaXN0PFN0cmluZz4gZW50cmllcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworCisgICAgcHJpdmF0ZSBpbnQgY29tcHJlc3NNZXRob2QgPSBERUZMQVRFRDsKKworICAgIHByaXZhdGUgaW50IGNvbXByZXNzTGV2ZWwgPSBEZWZsYXRlci5ERUZBVUxUX0NPTVBSRVNTSU9OOworCisgICAgcHJpdmF0ZSBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gY0RpciA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKworICAgIHByaXZhdGUgWmlwRW50cnkgY3VycmVudEVudHJ5OworCisgICAgcHJpdmF0ZSBmaW5hbCBDUkMzMiBjcmMgPSBuZXcgQ1JDMzIoKTsKKworICAgIHByaXZhdGUgaW50IG9mZnNldCA9IDAsIGN1ck9mZnNldCA9IDAsIG5hbWVMZW5ndGg7CisKKyAgICBwcml2YXRlIGJ5dGVbXSBuYW1lQnl0ZXM7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHtAY29kZSBaaXBPdXRwdXRTdHJlYW19IHdpdGggdGhlIHNwZWNpZmllZCBvdXRwdXQKKyAgICAgKiBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcDEKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT3V0cHV0U3RyZWFtfSB0byB3cml0ZSB0aGUgZGF0YSB0by4KKyAgICAgKi8KKyAgICBwdWJsaWMgWmlwT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBwMSkgeworICAgICAgICBzdXBlcihwMSwgbmV3IERlZmxhdGVyKERlZmxhdGVyLkRFRkFVTFRfQ09NUFJFU1NJT04sIHRydWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhlIGN1cnJlbnQge0Bjb2RlIFppcEVudHJ5fSwgaWYgYW55LCBhbmQgdGhlIHVuZGVybHlpbmcgb3V0cHV0CisgICAgICogc3RyZWFtLiBJZiB0aGUgc3RyZWFtIGlzIGFscmVhZHkgY2xvc2VkIHRoaXMgbWV0aG9kIGRvZXMgbm90aGluZy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBlcnJvciBvY2N1cnMgY2xvc2luZyB0aGUgc3RyZWFtLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gZG9uJ3QgY2FsbCBzdXBlci5jbG9zZSgpIGJlY2F1c2UgdGhhdCBjYWxscyBmaW5pc2goKSBjb25kaXRpb25hbGx5CisgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgZmluaXNoKCk7CisgICAgICAgICAgICBkZWYuZW5kKCk7CisgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIG91dCA9IG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhlIGN1cnJlbnQge0Bjb2RlIFppcEVudHJ5fS4gQW55IGVudHJ5IHRlcm1pbmFsIGRhdGEgaXMgd3JpdHRlbgorICAgICAqIHRvIHRoZSB1bmRlcmx5aW5nIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbiBlcnJvciBvY2N1cnMgY2xvc2luZyB0aGUgZW50cnkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xvc2VFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrQ2xvc2VkKCk7CisgICAgICAgIGlmIChjdXJyZW50RW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGlmIChjdXJyZW50RW50cnkuZ2V0TWV0aG9kKCkgPT0gREVGTEFURUQpIHsKKyAgICAgICAgICAgIHN1cGVyLmZpbmlzaCgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVmVyaWZ5IHZhbHVlcyBmb3IgU1RPUkVEIHR5cGVzCisgICAgICAgIGlmIChjdXJyZW50RW50cnkuZ2V0TWV0aG9kKCkgPT0gU1RPUkVEKSB7CisgICAgICAgICAgICBpZiAoY3JjLmdldFZhbHVlKCkgIT0gY3VycmVudEVudHJ5LmNyYykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBaaXBFeGNlcHRpb24oIkNSQyBtaXNtYXRjaCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGN1cnJlbnRFbnRyeS5zaXplICE9IGNyYy50Ynl0ZXMpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJTaXplIG1pc21hdGNoIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY3VyT2Zmc2V0ID0gTE9DSERSOworCisgICAgICAgIC8vIFdyaXRlIHRoZSBEYXRhRGVzY3JpcHRvcgorICAgICAgICBpZiAoY3VycmVudEVudHJ5LmdldE1ldGhvZCgpICE9IFNUT1JFRCkgeworICAgICAgICAgICAgY3VyT2Zmc2V0ICs9IEVYVEhEUjsKKyAgICAgICAgICAgIHdyaXRlTG9uZyhvdXQsIEVYVFNJRyk7CisgICAgICAgICAgICB3cml0ZUxvbmcob3V0LCBjdXJyZW50RW50cnkuY3JjID0gY3JjLmdldFZhbHVlKCkpOworICAgICAgICAgICAgd3JpdGVMb25nKG91dCwgY3VycmVudEVudHJ5LmNvbXByZXNzZWRTaXplID0gZGVmLmdldFRvdGFsT3V0KCkpOworICAgICAgICAgICAgd3JpdGVMb25nKG91dCwgY3VycmVudEVudHJ5LnNpemUgPSBkZWYuZ2V0VG90YWxJbigpKTsKKyAgICAgICAgfQorICAgICAgICAvLyBVcGRhdGUgdGhlIENlbnRyYWxEaXJlY3RvcnkKKyAgICAgICAgLy8gaHR0cDovL3d3dy5wa3dhcmUuY29tL2RvY3VtZW50cy9jYXNlc3R1ZGllcy9BUFBOT1RFLlRYVAorICAgICAgICBpbnQgZmxhZ3MgPSBjdXJyZW50RW50cnkuZ2V0TWV0aG9kKCkgPT0gU1RPUkVEID8gMCA6IFppcEZpbGUuR1BCRl9EQVRBX0RFU0NSSVBUT1JfRkxBRzsKKyAgICAgICAgLy8gU2luY2UgZ2luZ2VyYnJlYWQsIHdlIGFsd2F5cyBzZXQgdGhlIFVURi04IGZsYWcgb24gaW5kaXZpZHVhbCBmaWxlcy4KKyAgICAgICAgLy8gU29tZSB0b29scyBpbnNpc3QgdGhhdCB0aGUgY2VudHJhbCBkaXJlY3RvcnkgYWxzbyBoYXZlIHRoZSBVVEYtOCBmbGFnLgorICAgICAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTIwMjE0CisgICAgICAgIGZsYWdzIHw9IFppcEZpbGUuR1BCRl9VVEY4X0ZMQUc7CisgICAgICAgIHdyaXRlTG9uZyhjRGlyLCBDRU5TSUcpOworICAgICAgICB3cml0ZVNob3J0KGNEaXIsIFpJUExvY2FsSGVhZGVyVmVyc2lvbk5lZWRlZCk7IC8vIFZlcnNpb24gY3JlYXRlZAorICAgICAgICB3cml0ZVNob3J0KGNEaXIsIFpJUExvY2FsSGVhZGVyVmVyc2lvbk5lZWRlZCk7IC8vIFZlcnNpb24gdG8gZXh0cmFjdAorICAgICAgICB3cml0ZVNob3J0KGNEaXIsIGZsYWdzKTsKKyAgICAgICAgd3JpdGVTaG9ydChjRGlyLCBjdXJyZW50RW50cnkuZ2V0TWV0aG9kKCkpOworICAgICAgICB3cml0ZVNob3J0KGNEaXIsIGN1cnJlbnRFbnRyeS50aW1lKTsKKyAgICAgICAgd3JpdGVTaG9ydChjRGlyLCBjdXJyZW50RW50cnkubW9kRGF0ZSk7CisgICAgICAgIHdyaXRlTG9uZyhjRGlyLCBjcmMuZ2V0VmFsdWUoKSk7CisgICAgICAgIGlmIChjdXJyZW50RW50cnkuZ2V0TWV0aG9kKCkgPT0gREVGTEFURUQpIHsKKyAgICAgICAgICAgIGN1ck9mZnNldCArPSB3cml0ZUxvbmcoY0RpciwgZGVmLmdldFRvdGFsT3V0KCkpOworICAgICAgICAgICAgd3JpdGVMb25nKGNEaXIsIGRlZi5nZXRUb3RhbEluKCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY3VyT2Zmc2V0ICs9IHdyaXRlTG9uZyhjRGlyLCBjcmMudGJ5dGVzKTsKKyAgICAgICAgICAgIHdyaXRlTG9uZyhjRGlyLCBjcmMudGJ5dGVzKTsKKyAgICAgICAgfQorICAgICAgICBjdXJPZmZzZXQgKz0gd3JpdGVTaG9ydChjRGlyLCBuYW1lTGVuZ3RoKTsKKyAgICAgICAgaWYgKGN1cnJlbnRFbnRyeS5leHRyYSAhPSBudWxsKSB7CisgICAgICAgICAgICBjdXJPZmZzZXQgKz0gd3JpdGVTaG9ydChjRGlyLCBjdXJyZW50RW50cnkuZXh0cmEubGVuZ3RoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHdyaXRlU2hvcnQoY0RpciwgMCk7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIGM7CisgICAgICAgIGlmICgoYyA9IGN1cnJlbnRFbnRyeS5nZXRDb21tZW50KCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgIHdyaXRlU2hvcnQoY0RpciwgYy5sZW5ndGgoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB3cml0ZVNob3J0KGNEaXIsIDApOworICAgICAgICB9CisgICAgICAgIHdyaXRlU2hvcnQoY0RpciwgMCk7IC8vIERpc2sgU3RhcnQKKyAgICAgICAgd3JpdGVTaG9ydChjRGlyLCAwKTsgLy8gSW50ZXJuYWwgRmlsZSBBdHRyaWJ1dGVzCisgICAgICAgIHdyaXRlTG9uZyhjRGlyLCAwKTsgLy8gRXh0ZXJuYWwgRmlsZSBBdHRyaWJ1dGVzCisgICAgICAgIHdyaXRlTG9uZyhjRGlyLCBvZmZzZXQpOworICAgICAgICBjRGlyLndyaXRlKG5hbWVCeXRlcyk7CisgICAgICAgIG5hbWVCeXRlcyA9IG51bGw7CisgICAgICAgIGlmIChjdXJyZW50RW50cnkuZXh0cmEgIT0gbnVsbCkgeworICAgICAgICAgICAgY0Rpci53cml0ZShjdXJyZW50RW50cnkuZXh0cmEpOworICAgICAgICB9CisgICAgICAgIG9mZnNldCArPSBjdXJPZmZzZXQ7CisgICAgICAgIGlmIChjICE9IG51bGwpIHsKKyAgICAgICAgICAgIGNEaXIud3JpdGUoYy5nZXRCeXRlcygpKTsKKyAgICAgICAgfQorICAgICAgICBjdXJyZW50RW50cnkgPSBudWxsOworICAgICAgICBjcmMucmVzZXQoKTsKKyAgICAgICAgZGVmLnJlc2V0KCk7CisgICAgICAgIGRvbmUgPSBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhhdCBhbGwgZW50cmllcyBoYXZlIGJlZW4gd3JpdHRlbiB0byB0aGUgc3RyZWFtLiBBbnkgdGVybWluYWwKKyAgICAgKiBpbmZvcm1hdGlvbiBpcyB3cml0dGVuIHRvIHRoZSB1bmRlcmx5aW5nIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgdGVybWluYXRpbmcgdGhlIHN0cmVhbS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmaW5pc2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBUT0RPOiBpcyB0aGVyZSBhIGJ1ZyBoZXJlPyB3aHkgbm90IGNoZWNrQ2xvc2VkPworICAgICAgICBpZiAob3V0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU3RyZWFtIGlzIGNsb3NlZCIpOworICAgICAgICB9CisgICAgICAgIGlmIChjRGlyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZW50cmllcy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBaaXBFeGNlcHRpb24oIk5vIGVudHJpZXMiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY3VycmVudEVudHJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGNsb3NlRW50cnkoKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgY2RpclNpemUgPSBjRGlyLnNpemUoKTsKKyAgICAgICAgLy8gV3JpdGUgQ2VudHJhbCBEaXIgRW5kCisgICAgICAgIHdyaXRlTG9uZyhjRGlyLCBFTkRTSUcpOworICAgICAgICB3cml0ZVNob3J0KGNEaXIsIDApOyAvLyBEaXNrIE51bWJlcgorICAgICAgICB3cml0ZVNob3J0KGNEaXIsIDApOyAvLyBTdGFydCBEaXNrCisgICAgICAgIHdyaXRlU2hvcnQoY0RpciwgZW50cmllcy5zaXplKCkpOyAvLyBOdW1iZXIgb2YgZW50cmllcworICAgICAgICB3cml0ZVNob3J0KGNEaXIsIGVudHJpZXMuc2l6ZSgpKTsgLy8gTnVtYmVyIG9mIGVudHJpZXMKKyAgICAgICAgd3JpdGVMb25nKGNEaXIsIGNkaXJTaXplKTsgLy8gU2l6ZSBvZiBjZW50cmFsIGRpcgorICAgICAgICB3cml0ZUxvbmcoY0Rpciwgb2Zmc2V0KTsgLy8gT2Zmc2V0IG9mIGNlbnRyYWwgZGlyCisgICAgICAgIGlmIChjb21tZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHdyaXRlU2hvcnQoY0RpciwgY29tbWVudC5sZW5ndGgoKSk7CisgICAgICAgICAgICBjRGlyLndyaXRlKGNvbW1lbnQuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB3cml0ZVNob3J0KGNEaXIsIDApOworICAgICAgICB9CisgICAgICAgIC8vIFdyaXRlIHRoZSBjZW50cmFsIGRpcgorICAgICAgICBvdXQud3JpdGUoY0Rpci50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgY0RpciA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGVudHJ5IGluZm9ybWF0aW9uIHRvIHRoZSB1bmRlcmx5aW5nIHN0cmVhbS4gRGF0YSBhc3NvY2lhdGVkIHdpdGgKKyAgICAgKiB0aGUgZW50cnkgY2FuIHRoZW4gYmUgd3JpdHRlbiB1c2luZyB7QGNvZGUgd3JpdGUoKX0uIEFmdGVyIGRhdGEgaXMKKyAgICAgKiB3cml0dGVuIHtAY29kZSBjbG9zZUVudHJ5KCl9IG11c3QgYmUgY2FsbGVkIHRvIGNvbXBsZXRlIHRoZSB3cml0aW5nIG9mCisgICAgICogdGhlIGVudHJ5IHRvIHRoZSB1bmRlcmx5aW5nIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB6ZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBaaXBFbnRyeX0gdG8gc3RvcmUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFuIGVycm9yIG9jY3VycyBzdG9yaW5nIHRoZSBlbnRyeS4KKyAgICAgKiBAc2VlICN3cml0ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1dE5leHRFbnRyeShaaXBFbnRyeSB6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGN1cnJlbnRFbnRyeSAhPSBudWxsKSB7CisgICAgICAgICAgICBjbG9zZUVudHJ5KCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHplLmdldE1ldGhvZCgpID09IFNUT1JFRCB8fCAoY29tcHJlc3NNZXRob2QgPT0gU1RPUkVEICYmIHplLmdldE1ldGhvZCgpID09IC0xKSkgeworICAgICAgICAgICAgaWYgKHplLmNyYyA9PSAtMSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBaaXBFeGNlcHRpb24oIkNSQyBtaXNtYXRjaCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHplLnNpemUgPT0gLTEgJiYgemUuY29tcHJlc3NlZFNpemUgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJTaXplIG1pc21hdGNoIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoemUuc2l6ZSAhPSB6ZS5jb21wcmVzc2VkU2l6ZSAmJiB6ZS5jb21wcmVzc2VkU2l6ZSAhPSAtMSAmJiB6ZS5zaXplICE9IC0xKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFppcEV4Y2VwdGlvbigiU2l6ZSBtaXNtYXRjaCIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGNoZWNrQ2xvc2VkKCk7CisgICAgICAgIGlmIChlbnRyaWVzLmNvbnRhaW5zKHplLm5hbWUpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJFbnRyeSBhbHJlYWR5IGV4aXN0czogIiArIHplLm5hbWUpOworICAgICAgICB9CisgICAgICAgIG5hbWVCeXRlcyA9IHplLm5hbWUuZ2V0Qnl0ZXMoQ2hhcnNldHMuVVRGXzgpOworICAgICAgICBuYW1lTGVuZ3RoID0gbmFtZUJ5dGVzLmxlbmd0aDsKKyAgICAgICAgaWYgKG5hbWVMZW5ndGggPiAweGZmZmYpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5hbWUgdG9vIGxvbmc6ICIgKyBuYW1lTGVuZ3RoICsgIiBVVEYtOCBieXRlcyIpOworICAgICAgICB9CisKKyAgICAgICAgZGVmLnNldExldmVsKGNvbXByZXNzTGV2ZWwpOworICAgICAgICBjdXJyZW50RW50cnkgPSB6ZTsKKyAgICAgICAgZW50cmllcy5hZGQoY3VycmVudEVudHJ5Lm5hbWUpOworICAgICAgICBpZiAoY3VycmVudEVudHJ5LmdldE1ldGhvZCgpID09IC0xKSB7CisgICAgICAgICAgICBjdXJyZW50RW50cnkuc2V0TWV0aG9kKGNvbXByZXNzTWV0aG9kKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIExvY2FsIGZpbGUgaGVhZGVyLgorICAgICAgICAvLyBodHRwOi8vd3d3LnBrd2FyZS5jb20vZG9jdW1lbnRzL2Nhc2VzdHVkaWVzL0FQUE5PVEUuVFhUCisgICAgICAgIGludCBmbGFncyA9IGN1cnJlbnRFbnRyeS5nZXRNZXRob2QoKSA9PSBTVE9SRUQgPyAwIDogWmlwRmlsZS5HUEJGX0RBVEFfREVTQ1JJUFRPUl9GTEFHOworICAgICAgICAvLyBKYXZhIGFsd2F5cyBvdXRwdXRzIFVURi04IGZpbGVuYW1lcy4gKEJlZm9yZSBKYXZhIDcsIHRoZSBSSSBkaWRuJ3Qgc2V0IHRoaXMgZmxhZyBhbmQgdXNlZAorICAgICAgICAvLyBtb2RpZmllZCBVVEYtOC4gRnJvbSBKYXZhIDcsIGl0IHNldHMgdGhpcyBmbGFnIGFuZCB1c2VzIG5vcm1hbCBVVEYtOC4pCisgICAgICAgIGZsYWdzIHw9IFppcEZpbGUuR1BCRl9VVEY4X0ZMQUc7CisgICAgICAgIHdyaXRlTG9uZyhvdXQsIExPQ1NJRyk7IC8vIEVudHJ5IGhlYWRlcgorICAgICAgICB3cml0ZVNob3J0KG91dCwgWklQTG9jYWxIZWFkZXJWZXJzaW9uTmVlZGVkKTsgLy8gRXh0cmFjdGlvbiB2ZXJzaW9uCisgICAgICAgIHdyaXRlU2hvcnQob3V0LCBmbGFncyk7CisgICAgICAgIHdyaXRlU2hvcnQob3V0LCBjdXJyZW50RW50cnkuZ2V0TWV0aG9kKCkpOworICAgICAgICBpZiAoY3VycmVudEVudHJ5LmdldFRpbWUoKSA9PSAtMSkgeworICAgICAgICAgICAgY3VycmVudEVudHJ5LnNldFRpbWUoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworICAgICAgICB9CisgICAgICAgIHdyaXRlU2hvcnQob3V0LCBjdXJyZW50RW50cnkudGltZSk7CisgICAgICAgIHdyaXRlU2hvcnQob3V0LCBjdXJyZW50RW50cnkubW9kRGF0ZSk7CisKKyAgICAgICAgaWYgKGN1cnJlbnRFbnRyeS5nZXRNZXRob2QoKSA9PSBTVE9SRUQpIHsKKyAgICAgICAgICAgIGlmIChjdXJyZW50RW50cnkuc2l6ZSA9PSAtMSkgeworICAgICAgICAgICAgICAgIGN1cnJlbnRFbnRyeS5zaXplID0gY3VycmVudEVudHJ5LmNvbXByZXNzZWRTaXplOworICAgICAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50RW50cnkuY29tcHJlc3NlZFNpemUgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICBjdXJyZW50RW50cnkuY29tcHJlc3NlZFNpemUgPSBjdXJyZW50RW50cnkuc2l6ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHdyaXRlTG9uZyhvdXQsIGN1cnJlbnRFbnRyeS5jcmMpOworICAgICAgICAgICAgd3JpdGVMb25nKG91dCwgY3VycmVudEVudHJ5LnNpemUpOworICAgICAgICAgICAgd3JpdGVMb25nKG91dCwgY3VycmVudEVudHJ5LnNpemUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgd3JpdGVMb25nKG91dCwgMCk7CisgICAgICAgICAgICB3cml0ZUxvbmcob3V0LCAwKTsKKyAgICAgICAgICAgIHdyaXRlTG9uZyhvdXQsIDApOworICAgICAgICB9CisgICAgICAgIHdyaXRlU2hvcnQob3V0LCBuYW1lTGVuZ3RoKTsKKyAgICAgICAgaWYgKGN1cnJlbnRFbnRyeS5leHRyYSAhPSBudWxsKSB7CisgICAgICAgICAgICB3cml0ZVNob3J0KG91dCwgY3VycmVudEVudHJ5LmV4dHJhLmxlbmd0aCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB3cml0ZVNob3J0KG91dCwgMCk7CisgICAgICAgIH0KKyAgICAgICAgb3V0LndyaXRlKG5hbWVCeXRlcyk7CisgICAgICAgIGlmIChjdXJyZW50RW50cnkuZXh0cmEgIT0gbnVsbCkgeworICAgICAgICAgICAgb3V0LndyaXRlKGN1cnJlbnRFbnRyeS5leHRyYSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB7QGNvZGUgWmlwRmlsZX0gY29tbWVudCBhc3NvY2lhdGVkIHdpdGggdGhlIGZpbGUgYmVpbmcgd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb21tZW50CisgICAgICogICAgICAgICAgICB0aGUgY29tbWVudCBhc3NvY2lhdGVkIHdpdGggdGhlIGZpbGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q29tbWVudChTdHJpbmcgY29tbWVudCkgeworICAgICAgICBpZiAoY29tbWVudC5sZW5ndGgoKSA+IDB4RkZGRikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQ29tbWVudCB0b28gbG9uZzogIiArIGNvbW1lbnQubGVuZ3RoKCkgKyAiIGNoYXJhY3RlcnMiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmNvbW1lbnQgPSBjb21tZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGNvbXByZXNzaW9uIGxldmVsIHRvIGJlIHVzZWQgZm9yIHdyaXRpbmcgZW50cnkgZGF0YS4gVGhpcyBsZXZlbAorICAgICAqIG1heSBiZSBzZXQgb24gYSBwZXIgZW50cnkgYmFzaXMuIFRoZSBsZXZlbCBtdXN0IGhhdmUgYSB2YWx1ZSBiZXR3ZWVuIC0xCisgICAgICogYW5kIDggYWNjb3JkaW5nIHRvIHRoZSB7QGNvZGUgRGVmbGF0ZXJ9IGNvbXByZXNzaW9uIGxldmVsIGJvdW5kcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsZXZlbAorICAgICAqICAgICAgICAgICAgdGhlIGNvbXByZXNzaW9uIGxldmVsIChyYW5naW5nIGZyb20gLTEgdG8gOCkuCisgICAgICogQHNlZSBEZWZsYXRlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExldmVsKGludCBsZXZlbCkgeworICAgICAgICBpZiAobGV2ZWwgPCBEZWZsYXRlci5ERUZBVUxUX0NPTVBSRVNTSU9OIHx8IGxldmVsID4gRGVmbGF0ZXIuQkVTVF9DT01QUkVTU0lPTikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGNvbXByZXNzTGV2ZWwgPSBsZXZlbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjb21wcmVzc2lvbiBtZXRob2QgdG8gYmUgdXNlZCB3aGVuIGNvbXByZXNzaW5nIGVudHJ5IGRhdGEuCisgICAgICogbWV0aG9kIG11c3QgYmUgb25lIG9mIHtAY29kZSBTVE9SRUR9IChmb3Igbm8gY29tcHJlc3Npb24pIG9yIHtAY29kZQorICAgICAqIERFRkxBVEVEfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXRob2QKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb21wcmVzc2lvbiBtZXRob2QgdG8gdXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1ldGhvZChpbnQgbWV0aG9kKSB7CisgICAgICAgIGlmIChtZXRob2QgIT0gU1RPUkVEICYmIG1ldGhvZCAhPSBERUZMQVRFRCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGNvbXByZXNzTWV0aG9kID0gbWV0aG9kOworICAgIH0KKworICAgIHByaXZhdGUgbG9uZyB3cml0ZUxvbmcoT3V0cHV0U3RyZWFtIG9zLCBsb25nIGkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFdyaXRlIG91dCB0aGUgbG9uZyB2YWx1ZSBhcyBhbiB1bnNpZ25lZCBpbnQKKyAgICAgICAgb3Mud3JpdGUoKGludCkgKGkgJiAweEZGKSk7CisgICAgICAgIG9zLndyaXRlKChpbnQpIChpID4+IDgpICYgMHhGRik7CisgICAgICAgIG9zLndyaXRlKChpbnQpIChpID4+IDE2KSAmIDB4RkYpOworICAgICAgICBvcy53cml0ZSgoaW50KSAoaSA+PiAyNCkgJiAweEZGKTsKKyAgICAgICAgcmV0dXJuIGk7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgd3JpdGVTaG9ydChPdXRwdXRTdHJlYW0gb3MsIGludCBpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvcy53cml0ZShpICYgMHhGRik7CisgICAgICAgIG9zLndyaXRlKChpID4+IDgpICYgMHhGRik7CisgICAgICAgIHJldHVybiBpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBkYXRhIGZvciB0aGUgY3VycmVudCBlbnRyeSB0byB0aGUgdW5kZXJseWluZyBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgSWYgYW4gZXJyb3Igb2NjdXJzIHdyaXRpbmcgdG8gdGhlIHN0cmVhbQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGJ1ZmZlci5sZW5ndGgsIG9mZnNldCwgYnl0ZUNvdW50KTsKKyAgICAgICAgaWYgKGN1cnJlbnRFbnRyeSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWmlwRXhjZXB0aW9uKCJObyBhY3RpdmUgZW50cnkiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjdXJyZW50RW50cnkuZ2V0TWV0aG9kKCkgPT0gU1RPUkVEKSB7CisgICAgICAgICAgICBvdXQud3JpdGUoYnVmZmVyLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzdXBlci53cml0ZShidWZmZXIsIG9mZnNldCwgYnl0ZUNvdW50KTsKKyAgICAgICAgfQorICAgICAgICBjcmMudXBkYXRlKGJ1ZmZlciwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja0Nsb3NlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjRGlyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU3RyZWFtIGlzIGNsb3NlZCIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9CYWRQYWRkaW5nRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL0JhZFBhZGRpbmdFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45Mjg4ZjQ3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9CYWRQYWRkaW5nRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbjsKKworLyoqCisgKiBUaGUgZXhjZXB0aW9uIHRoYXQgaXMgdGhyb3duIHdoZW4gYSBwYWRkaW5nIG1lY2hhbmlzbSBpcyBleHBlY3RlZCBmb3IgdGhlCisgKiBpbnB1dCBkYXRhLCBidXQgdGhlIGlucHV0IGRhdGEgZG9lcyBub3QgaGF2ZSB0aGUgcHJvcGVyIHBhZGRpbmcgYnl0ZXMuCisgKi8KK3B1YmxpYyBjbGFzcyBCYWRQYWRkaW5nRXhjZXB0aW9uIGV4dGVuZHMgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHsKKworICAgIC8qKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTMxNTAzMzg5Mzk4NDcyODQ0M0w7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHtAY29kZSBCYWRQYWRkaW5nRXhjZXB0aW9ufSB3aXRoIGEgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIEJhZFBhZGRpbmdFeGNlcHRpb24oU3RyaW5nIG1zZykgeworICAgICAgICBzdXBlcihtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIEJhZFBhZGRpbmdFeGNlcHRpb259IHdpdGggbm8gbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmFkUGFkZGluZ0V4Y2VwdGlvbigpIHsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9DaXBoZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vQ2lwaGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzhjYjYwMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vQ2lwaGVyLmphdmEKQEAgLTAsMCArMSwxMzY0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LmNyeXB0bzsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by5pbnRlcm5hbC5OdWxsQ2lwaGVyU3BpOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5mb3J0cmVzcy5FbmdpbmU7CisKKy8qKgorICogVGhpcyBjbGFzcyBwcm92aWRlcyBhY2Nlc3MgdG8gaW1wbGVtZW50YXRpb25zIG9mIGNyeXB0b2dyYXBoaWMgY2lwaGVycyBmb3IKKyAqIGVuY3J5cHRpb24gYW5kIGRlY3J5cHRpb24uIENpcGhlciBjbGFzc2VzIGNhbiBub3QgYmUgaW5zdGFudGlhdGVkIGRpcmVjdGx5LAorICogb25lIGhhcyB0byBjYWxsIHRoZSBDaXBoZXIncyB7QGNvZGUgZ2V0SW5zdGFuY2V9IG1ldGhvZCB3aXRoIHRoZSBuYW1lIG9mIGEKKyAqIHJlcXVlc3RlZCB0cmFuc2Zvcm1hdGlvbiwgb3B0aW9uYWxseSB3aXRoIGEgcHJvdmlkZXIuIEEgdHJhbnNmb3JtYXRpb24KKyAqIHNwZWNpZmllcyBhbiBvcGVyYXRpb24gKG9yIGEgc2V0IG9mIG9wZXJhdGlvbnMpIGFzIGEgc3RyaW5nIGluIHRoZSBmb3JtOgorICogPHVsPgorICogPGxpPjxpPiJhbGdvcml0aG0vbW9kZS9wYWRkaW5nIjwvaT48L2xpPiBvcgorICogPGxpPjxpPiJhbGdvcml0aG0iPC9pPjwvbGk+CisgKiA8L3VsPgorICogPGk+YWxnb3JpdGhtPC9pPiBpcyB0aGUgbmFtZSBvZiBhIGNyeXB0b2dyYXBoaWMgYWxnb3JpdGhtLCA8aT5tb2RlPC9pPiBpcyB0aGUKKyAqIG5hbWUgb2YgYSBmZWVkYmFjayBtb2RlIGFuZCA8aT5wYWRkaW5nPC9pPiBpcyB0aGUgbmFtZSBvZiBhIHBhZGRpbmcgc2NoZW1lLgorICogSWYgPGk+bW9kZTwvaT4gYW5kL29yIDxpPnBhZGRpbmc8L2k+IHZhbHVlcyBhcmUgb21pdHRlZCwgcHJvdmlkZXIgc3BlY2lmaWMKKyAqIGRlZmF1bHQgdmFsdWVzIHdpbGwgYmUgdXNlZC4KKyAqIDxwPgorICogQSB2YWxpZCB0cmFuc2Zvcm1hdGlvbiB3b3VsZCBiZToKKyAqIDx1bD4KKyAqIHtAY29kZSBDaXBoZXIgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiQUVTL0NCQy9QS0NTNVBhZGRpbmciKTt9CisgKiA8L3VsPgorICogV2hlbiBhIGJsb2NrIGNpcGhlciBpcyByZXF1ZXN0ZWQgaW4gaW4gc3RyZWFtIGNpcGhlciBtb2RlLCB0aGUgbnVtYmVyIG9mIGJpdHMKKyAqIHRvIGJlIHByb2Nlc3NlZCBhdCBhIHRpbWUgY2FuIGJlIG9wdGlvbmFsbHkgc3BlY2lmaWVkIGJ5IGFwcGVuZGluZyBpdCB0byB0aGUKKyAqIG1vZGUgbmFtZS4gZS5nLiA8aT4iQUVTL0NGQjgvTm9QYWRkaW5nIjwvaT4uIElmIG5vIG51bWJlciBpcyBzcGVjaWZpZWQsIGEKKyAqIHByb3ZpZGVyIHNwZWNpZmljIGRlZmF1bHQgdmFsdWUgaXMgdXNlZC4KKyAqLworcHVibGljIGNsYXNzIENpcGhlciB7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCBmb3IgZGVjcnlwdGlvbiBvcGVyYXRpb24gbW9kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUNSWVBUX01PREUgPSAyOworCisgICAgLyoqCisgICAgICogQ29uc3RhbnQgZm9yIGVuY3J5cHRpb24gb3BlcmF0aW9uIG1vZGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5DUllQVF9NT0RFID0gMTsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IGluZGljYXRpbmcgdGhhdCB0aGUga2V5IHRvIGJlIHVud3JhcHBlZCBpcyBhIHByaXZhdGUga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBSSVZBVEVfS0VZID0gMjsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IGluZGljYXRpbmcgdGhhdCB0aGUga2V5IHRvIGJlIHVud3JhcHBlZCBpcyBhIHB1YmxpYyBrZXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFVCTElDX0tFWSA9IDE7CisKKyAgICAvKioKKyAgICAgKiBDb25zdGFudCBpbmRpY2F0aW5nIHRoYXQgdGhlIGtleSB0byBiZSB1bndyYXBwZWQgaXMgYSBzZWNyZXQga2V5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFQ1JFVF9LRVkgPSAzOworCisgICAgLyoqCisgICAgICogQ29uc3RhbnQgZm9yIGtleSB1bndyYXBwaW5nIG9wZXJhdGlvbiBtb2RlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOV1JBUF9NT0RFID0gNDsKKworICAgIC8qKgorICAgICAqIENvbnN0YW50IGZvciBrZXkgd3JhcHBpbmcgb3BlcmF0aW9uIG1vZGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV1JBUF9NT0RFID0gMzsKKworICAgIHByaXZhdGUgaW50IG1vZGU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc2VydmljZSBuYW1lLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRVJWSUNFID0gIkNpcGhlciI7CisKKyAgICAvKioKKyAgICAgKiBVc2VkIHRvIGFjY2VzcyBjb21tb24gZW5naW5lIGZ1bmN0aW9uYWxpdHkuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRW5naW5lIEVOR0lORSA9IG5ldyBFbmdpbmUoU0VSVklDRSk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcHJvdmlkZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBQcm92aWRlciBwcm92aWRlcjsKKworICAgIC8qKgorICAgICAqIFRoZSBTUEkgaW1wbGVtZW50YXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBDaXBoZXJTcGkgc3BpSW1wbDsKKworICAgIC8qKgorICAgICAqIFRoZSB0cmFuc2Zvcm1hdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyB0cmFuc2Zvcm1hdGlvbjsKKworICAgIHByaXZhdGUgc3RhdGljIFNlY3VyZVJhbmRvbSBzZWN1cmVSYW5kb207CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IENpcGhlciBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaXBoZXJTcGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbXBsZW1lbnRhdGlvbiBkZWxlZ2F0ZSBvZiB0aGUgY2lwaGVyLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHByb3ZpZGVyIG9mIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGNpcGhlci4KKyAgICAgKiBAcGFyYW0gdHJhbnNmb3JtYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiB0aGF0IHRoaXMgY2lwaGVyIHBlcmZvcm1zLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBlaXRoZXIgY2lwaGVyU3BpIGlzIHtAY29kZSBudWxsfSBvciBwcm92aWRlciBpcyB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBudWxsfSBhbmQge0Bjb2RlIGNpcGhlclNwaX0gaXMgYSB7QGNvZGUgTnVsbENpcGhlclNwaX0uCisgICAgICovCisgICAgcHJvdGVjdGVkIENpcGhlcihDaXBoZXJTcGkgY2lwaGVyU3BpLCBQcm92aWRlciBwcm92aWRlciwKKyAgICAgICAgICAgIFN0cmluZyB0cmFuc2Zvcm1hdGlvbikgeworICAgICAgICBpZiAoY2lwaGVyU3BpID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmICghKGNpcGhlclNwaSBpbnN0YW5jZW9mIE51bGxDaXBoZXJTcGkpICYmIHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMucHJvdmlkZXIgPSBwcm92aWRlcjsKKyAgICAgICAgdGhpcy50cmFuc2Zvcm1hdGlvbiA9IHRyYW5zZm9ybWF0aW9uOworICAgICAgICB0aGlzLnNwaUltcGwgPSBjaXBoZXJTcGk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBDaXBoZXIgZm9yIHRoZSBzcGVjaWZpZWQgdHJhbnNmb3JtYXRpb24uIFRoZSBpbnN0YWxsZWQKKyAgICAgKiBwcm92aWRlcnMgYXJlIHNlYXJjaGVkIGluIG9yZGVyIGZvciBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogdHJhbnNmb3JtYXRpb24uIFRoZSBmaXJzdCBmb3VuZCBwcm92aWRlciBwcm92aWRpbmcgdGhlIHRyYW5zZm9ybWF0aW9uIGlzCisgICAgICogdXNlZCB0byBjcmVhdGUgdGhlIGNpcGhlci4gSWYgbm8gcHJvdmlkZXIgaXMgZm91bmQgYW4gZXhjZXB0aW9uIGlzCisgICAgICogdGhyb3duLgorICAgICAqCisgICAgICogQHBhcmFtIHRyYW5zZm9ybWF0aW9uCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gdG8gY3JlYXRlIGEgY2lwaGVyIGZvci4KKyAgICAgKiBAcmV0dXJuIGEgY2lwaGVyIGZvciB0aGUgcmVxdWVzdGVkIHRyYW5zZm9ybWF0aW9uLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgbm8gaW5zdGFsbGVkIHByb3ZpZGVyIGNhbiBwcm92aWRlIHRoZQorICAgICAqICAgICAgICAgICAgIDxpPnRyYW5zZm9ybWF0aW9uPC9pPiwgb3IgaXQgaXMge0Bjb2RlIG51bGx9LCBlbXB0eSBvciBpbiBhbgorICAgICAqICAgICAgICAgICAgIGludmFsaWQgZm9ybWF0LgorICAgICAqIEB0aHJvd3MgTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG5vIGluc3RhbGxlZCBwcm92aWRlciBjYW4gcHJvdmlkZSB0aGUgcGFkZGluZyBzY2hlbWUgaW4KKyAgICAgKiAgICAgICAgICAgICB0aGUgPGk+dHJhbnNmb3JtYXRpb248L2k+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2lwaGVyIGdldEluc3RhbmNlKFN0cmluZyB0cmFuc2Zvcm1hdGlvbikKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFBhZGRpbmdFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZ2V0Q2lwaGVyKHRyYW5zZm9ybWF0aW9uLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGNpcGhlciBmb3IgdGhlIHNwZWNpZmllZCB0cmFuc2Zvcm1hdGlvbiBwcm92aWRlZCBieSB0aGUKKyAgICAgKiBzcGVjaWZpZWQgcHJvdmlkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHJhbnNmb3JtYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiB0byBjcmVhdGUgYSBjaXBoZXIgZm9yLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIHRvIGFzayBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLgorICAgICAqIEByZXR1cm4gYSBjaXBoZXIgZm9yIHRoZSByZXF1ZXN0ZWQgdHJhbnNmb3JtYXRpb24uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGNhbiBub3QgcHJvdmlkZSB0aGUKKyAgICAgKiAgICAgICAgICAgICA8aT50cmFuc2Zvcm1hdGlvbjwvaT4sIG9yIGl0IGlzIHtAY29kZSBudWxsfSwgZW1wdHkgb3IgaW4gYW4KKyAgICAgKiAgICAgICAgICAgICBpbnZhbGlkIGZvcm1hdC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgbm8gcHJvdmlkZXIgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgY2FuIGJlIGZvdW5kLgorICAgICAqIEB0aHJvd3MgTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSByZXF1ZXN0ZWQgcGFkZGluZyBzY2hlbWUgaW4gdGhlIDxpPnRyYW5zZm9ybWF0aW9uPC9pPgorICAgICAqICAgICAgICAgICAgIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENpcGhlciBnZXRJbnN0YW5jZShTdHJpbmcgdHJhbnNmb3JtYXRpb24sCisgICAgICAgICAgICBTdHJpbmcgcHJvdmlkZXIpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwgTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbiB7CisKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInByb3ZpZGVyID09IG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIFByb3ZpZGVyIHAgPSBTZWN1cml0eS5nZXRQcm92aWRlcihwcm92aWRlcik7CisgICAgICAgIGlmIChwID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbigiUHJvdmlkZXIgbm90IGF2YWlsYWJsZTogIiArIHByb3ZpZGVyKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0SW5zdGFuY2UodHJhbnNmb3JtYXRpb24sIHApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgY2lwaGVyIGZvciB0aGUgc3BlY2lmaWVkIHRyYW5zZm9ybWF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHRyYW5zZm9ybWF0aW9uCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gdG8gY3JlYXRlIGEgY2lwaGVyIGZvci4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm92aWRlciB0byBhc2sgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbi4KKyAgICAgKiBAcmV0dXJuIGEgY2lwaGVyIGZvciB0aGUgcmVxdWVzdGVkIHRyYW5zZm9ybWF0aW9uLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBjYW4gbm90IHByb3ZpZGUgdGhlCisgICAgICogICAgICAgICAgICAgPGk+dHJhbnNmb3JtYXRpb248L2k+LCBvciBpdCBpcyB7QGNvZGUgbnVsbH0sIGVtcHR5IG9yIGluIGFuCisgICAgICogICAgICAgICAgICAgaW52YWxpZCBmb3JtYXQuCisgICAgICogQHRocm93cyBOb1N1Y2hQYWRkaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHJlcXVlc3RlZCBwYWRkaW5nIHNjaGVtZSBpbiB0aGUgPGk+dHJhbnNmb3JtYXRpb248L2k+CisgICAgICogICAgICAgICAgICAgaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwcm92aWRlciBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDaXBoZXIgZ2V0SW5zdGFuY2UoU3RyaW5nIHRyYW5zZm9ybWF0aW9uLAorICAgICAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hQYWRkaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInByb3ZpZGVyID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBDaXBoZXIgYyA9IGdldENpcGhlcih0cmFuc2Zvcm1hdGlvbiwgcHJvdmlkZXIpOworICAgICAgICByZXR1cm4gYzsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gaW52YWxpZFRyYW5zZm9ybWF0aW9uKFN0cmluZyB0cmFuc2Zvcm1hdGlvbikKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKCJJbnZhbGlkIHRyYW5zZm9ybWF0aW9uOiAiICsgdHJhbnNmb3JtYXRpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmQgYXBwcm9wcmlhdGUgQ2lwaGVyIGFjY29yZGluZyB0aGUgc3BlY2lmaWNhdGlvbiBydWxlcworICAgICAqCisgICAgICogQHBhcmFtIHRyYW5zZm9ybWF0aW9uCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogQHJldHVybgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogQHRocm93cyBOb1N1Y2hQYWRkaW5nRXhjZXB0aW9uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgc3luY2hyb25pemVkIENpcGhlciBnZXRDaXBoZXIoU3RyaW5nIHRyYW5zZm9ybWF0aW9uLCBQcm92aWRlciBwcm92aWRlcikKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFBhZGRpbmdFeGNlcHRpb24geworCisgICAgICAgIGlmICh0cmFuc2Zvcm1hdGlvbiA9PSBudWxsIHx8IHRyYW5zZm9ybWF0aW9uLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgdGhyb3cgaW52YWxpZFRyYW5zZm9ybWF0aW9uKHRyYW5zZm9ybWF0aW9uKTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ1tdIHRyYW5zZiA9IGNoZWNrVHJhbnNmb3JtYXRpb24odHJhbnNmb3JtYXRpb24pOworCisgICAgICAgIGJvb2xlYW4gbmVlZFNldFBhZGRpbmcgPSBmYWxzZTsKKyAgICAgICAgYm9vbGVhbiBuZWVkU2V0TW9kZSA9IGZhbHNlOworICAgICAgICBPYmplY3QgZW5naW5lU3BpID0gbnVsbDsKKyAgICAgICAgUHJvdmlkZXIgZW5naW5lUHJvdmlkZXIgPSBwcm92aWRlcjsKKyAgICAgICAgaWYgKHRyYW5zZlsxXSA9PSBudWxsICYmIHRyYW5zZlsyXSA9PSBudWxsKSB7IC8vICJhbGdvcml0aG0iCisgICAgICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIEVuZ2luZS5TcGlBbmRQcm92aWRlciBzYXAgPSBFTkdJTkUuZ2V0SW5zdGFuY2UodHJhbnNmWzBdLCBudWxsKTsKKyAgICAgICAgICAgICAgICBlbmdpbmVTcGkgPSBzYXAuc3BpOworICAgICAgICAgICAgICAgIGVuZ2luZVByb3ZpZGVyID0gc2FwLnByb3ZpZGVyOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBlbmdpbmVTcGkgPSBFTkdJTkUuZ2V0SW5zdGFuY2UodHJhbnNmWzBdLCBwcm92aWRlciwgbnVsbCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBTdHJpbmdbXSBzZWFyY2hPcmRlciA9IHsKKyAgICAgICAgICAgICAgICB0cmFuc2ZbMF0gKyAiLyIgKyB0cmFuc2ZbMV0gKyAiLyIgKyB0cmFuc2ZbMl0sIC8vICJhbGdvcml0aG0vbW9kZS9wYWRkaW5nIgorICAgICAgICAgICAgICAgIHRyYW5zZlswXSArICIvIiArIHRyYW5zZlsxXSwgLy8gImFsZ29yaXRobS9tb2RlIgorICAgICAgICAgICAgICAgIHRyYW5zZlswXSArICIvLyIgKyB0cmFuc2ZbMl0sIC8vICJhbGdvcml0aG0vL3BhZGRpbmciCisgICAgICAgICAgICAgICAgdHJhbnNmWzBdIC8vICJhbGdvcml0aG0iCisgICAgICAgICAgICB9OworICAgICAgICAgICAgaW50IGk7CisgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc2VhcmNoT3JkZXIubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgRW5naW5lLlNwaUFuZFByb3ZpZGVyIHNhcCA9IEVOR0lORS5nZXRJbnN0YW5jZShzZWFyY2hPcmRlcltpXSwgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgICAgICBlbmdpbmVTcGkgPSBzYXAuc3BpOworICAgICAgICAgICAgICAgICAgICAgICAgZW5naW5lUHJvdmlkZXIgPSBzYXAucHJvdmlkZXI7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBlbmdpbmVTcGkgPSBFTkdJTkUuZ2V0SW5zdGFuY2Uoc2VhcmNoT3JkZXJbaV0sIHByb3ZpZGVyLCBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSBzZWFyY2hPcmRlci5sZW5ndGgtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbih0cmFuc2Zvcm1hdGlvbiwgZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzd2l0Y2ggKGkpIHsKKyAgICAgICAgICAgICAgICBjYXNlIDE6IC8vICJhbGdvcml0aG0vbW9kZSIKKyAgICAgICAgICAgICAgICAgICAgbmVlZFNldFBhZGRpbmcgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIDI6IC8vICJhbGdvcml0aG0vL3BhZGRpbmciCisgICAgICAgICAgICAgICAgICAgIG5lZWRTZXRNb2RlID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAzOiAvLyAiYWxnb3JpdGhtIgorICAgICAgICAgICAgICAgICAgICBuZWVkU2V0UGFkZGluZyA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIG5lZWRTZXRNb2RlID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoZW5naW5lU3BpID09IG51bGwgfHwgZW5naW5lUHJvdmlkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbih0cmFuc2Zvcm1hdGlvbik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCEoZW5naW5lU3BpIGluc3RhbmNlb2YgQ2lwaGVyU3BpKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbihlbmdpbmVTcGkuZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworICAgICAgICB9CisgICAgICAgIENpcGhlclNwaSBjc3BpID0gKENpcGhlclNwaSkgZW5naW5lU3BpOworICAgICAgICBDaXBoZXIgYyA9IG5ldyBDaXBoZXIoY3NwaSwgZW5naW5lUHJvdmlkZXIsIHRyYW5zZm9ybWF0aW9uKTsKKyAgICAgICAgaWYgKG5lZWRTZXRNb2RlKSB7CisgICAgICAgICAgICBjLnNwaUltcGwuZW5naW5lU2V0TW9kZSh0cmFuc2ZbMV0pOworICAgICAgICB9CisgICAgICAgIGlmIChuZWVkU2V0UGFkZGluZykgeworICAgICAgICAgICAgYy5zcGlJbXBsLmVuZ2luZVNldFBhZGRpbmcodHJhbnNmWzJdKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYzsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBjaGVja1RyYW5zZm9ybWF0aW9uKFN0cmluZyB0cmFuc2Zvcm1hdGlvbikgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIC8vIGlnbm9yZSBhbiBleHRyYSBwcmVmaXggLyBjaGFyYWN0ZXJzIHN1Y2ggYXMgaW4KKyAgICAgICAgLy8gIi9ERVMvQ0JDL1BLQ1M1UGFkZGluIiBodHRwOi8vYi8zMzg3Njg4CisgICAgICAgIGlmICh0cmFuc2Zvcm1hdGlvbi5zdGFydHNXaXRoKCIvIikpIHsKKyAgICAgICAgICAgIHRyYW5zZm9ybWF0aW9uID0gdHJhbnNmb3JtYXRpb24uc3Vic3RyaW5nKDEpOworICAgICAgICB9CisgICAgICAgIC8vICd0cmFuc2Zvcm1hdGlvbicgc2hvdWxkIGJlIG9mIHRoZSBmb3JtICJhbGdvcml0aG0vbW9kZS9wYWRkaW5nIi4KKyAgICAgICAgU3RyaW5nW10gcGllY2VzID0gdHJhbnNmb3JtYXRpb24uc3BsaXQoIi8iKTsKKyAgICAgICAgaWYgKHBpZWNlcy5sZW5ndGggPiAzKSB7CisgICAgICAgICAgICB0aHJvdyBpbnZhbGlkVHJhbnNmb3JtYXRpb24odHJhbnNmb3JtYXRpb24pOworICAgICAgICB9CisgICAgICAgIC8vIEVtcHR5IG9yIG1pc3NpbmcgcGllY2VzIGFyZSByZXByZXNlbnRlZCBieSBudWxsLgorICAgICAgICBTdHJpbmdbXSByZXN1bHQgPSBuZXcgU3RyaW5nWzNdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBpZWNlcy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgU3RyaW5nIHBpZWNlID0gcGllY2VzW2ldLnRyaW0oKTsKKyAgICAgICAgICAgIGlmICghcGllY2UuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0W2ldID0gcGllY2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gWW91IE1VU1Qgc3BlY2lmeSBhbiBhbGdvcml0aG0uCisgICAgICAgIGlmIChyZXN1bHRbMF0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgaW52YWxpZFRyYW5zZm9ybWF0aW9uKHRyYW5zZm9ybWF0aW9uKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShyZXN1bHRbMV0gPT0gbnVsbCAmJiByZXN1bHRbMl0gPT0gbnVsbCkgJiYgKHJlc3VsdFsxXSA9PSBudWxsIHx8IHJlc3VsdFsyXSA9PSBudWxsKSkgeworICAgICAgICAgICAgdGhyb3cgaW52YWxpZFRyYW5zZm9ybWF0aW9uKHRyYW5zZm9ybWF0aW9uKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByb3ZpZGVyIG9mIHRoaXMgY2lwaGVyIGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJvdmlkZXIgb2YgdGhpcyBjaXBoZXIgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFByb3ZpZGVyIGdldFByb3ZpZGVyKCkgeworICAgICAgICByZXR1cm4gcHJvdmlkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtIG9mIHRoaXMgY2lwaGVyIGluc3RhbmNlLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIDxpPnRyYW5zZm9ybWF0aW9uPC9pPiBhcmd1bWVudCB1c2VkIGluIHRoZQorICAgICAqIHtAY29kZSBnZXRJbnN0YW5jZX0gY2FsbCBjcmVhdGluZyB0aGlzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobSBvZiB0aGlzIGNpcGhlciBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgcmV0dXJuIHRyYW5zZm9ybWF0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBjaXBoZXJzIGJsb2NrIHNpemUgKGluIGJ5dGVzKS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBjaXBoZXJzIGJsb2NrIHNpemUuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRCbG9ja1NpemUoKSB7CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZUdldEJsb2NrU2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxlbmd0aCBpbiBieXRlcyBhbiBvdXRwdXQgYnVmZmVyIG5lZWRzIHRvIGJlIHdoZW4gdGhpcyBjaXBoZXIKKyAgICAgKiBpcyB1cGRhdGVkIHdpdGgge0Bjb2RlIGlucHV0TGVufSBieXRlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dExlbgorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBieXRlcyBvZiB0aGUgaW5wdXQuCisgICAgICogQHJldHVybiB0aGUgb3V0cHV0IGJ1ZmZlciBsZW5ndGggZm9yIHRoZSBpbnB1dCBsZW5ndGguCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNpcGhlciBpbnN0YW5jZSBpcyBpbiBhbiBpbnZhbGlkIHN0YXRlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0T3V0cHV0U2l6ZShpbnQgaW5wdXRMZW4pIHsKKyAgICAgICAgaWYgKG1vZGUgPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiQ2lwaGVyIGhhcyBub3QgeWV0IGJlZW4gaW5pdGlhbGl6ZWQiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVHZXRPdXRwdXRTaXplKGlucHV0TGVuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSA8aT5pbml0aWFsaXphdGlvbiB2ZWN0b3I8L2k+IGZvciB0aGlzIGNpcGhlciBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIDxpPmluaXRpYWxpemF0aW9uIHZlY3RvcjwvaT4gZm9yIHRoaXMgY2lwaGVyIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBieXRlW10gZ2V0SVYoKSB7CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZUdldElWKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGFyYW1ldGVycyB0aGF0IHdoZXJlIHVzZWQgdG8gY3JlYXRlIHRoaXMgY2lwaGVyIGluc3RhbmNlLgorICAgICAqIDxwPgorICAgICAqIFRoZXNlIG1heSBiZSBhIHRoZSBzYW1lIHBhcmFtZXRlcnMgdGhhdCB3ZXJlIHVzZWQgdG8gY3JlYXRlIHRoaXMgY2lwaGVyCisgICAgICogaW5zdGFuY2UsIG9yIG1heSBiZSBhIGNvbWJpbmF0aW9uIG9mIGRlZmF1bHQgYW5kIHJhbmRvbSBwYXJhbWV0ZXJzLAorICAgICAqIGRlcGVuZGluZyBvbiB0aGUgdW5kZXJseWluZyBjaXBoZXIgaW1wbGVtZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwYXJhbWV0ZXJzIHRoYXQgd2hlcmUgdXNlZCB0byBjcmVhdGUgdGhpcyBjaXBoZXIgaW5zdGFuY2UsIG9yCisgICAgICogICAgICAgICB7QGNvZGUgbnVsbH0gaWYgdGhpcyBjaXBoZXIgaW5zdGFuY2UgZG9lcyBub3QgaGF2ZSBhbnkKKyAgICAgKiAgICAgICAgIHBhcmFtZXRlcnMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEFsZ29yaXRobVBhcmFtZXRlcnMgZ2V0UGFyYW1ldGVycygpIHsKKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lR2V0UGFyYW1ldGVycygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGV4ZW1wdGlvbiBtZWNoYW5pc20gYXNzb2NpYXRlZCB3aXRoIHRoaXMgY2lwaGVyLgorICAgICAqCisgICAgICogQHJldHVybiBjdXJyZW50bHkge0Bjb2RlIG51bGx9CisgICAgICovCisgICAgcHVibGljIGZpbmFsIEV4ZW1wdGlvbk1lY2hhbmlzbSBnZXRFeGVtcHRpb25NZWNoYW5pc20oKSB7CisgICAgICAgIC8vRklYTUUgaW1wbGVtZW50IGdldEV4ZW1wdGlvbk1lY2hhbmlzbQorCisgICAgICAgIC8vICAgICAgICB0cnkgeworICAgICAgICAvLyAgICAgICAgICAgIHJldHVybiBFeGVtcHRpb25NZWNoYW5pc20uZ2V0SW5zdGFuY2UodHJhbnNmb3JtYXRpb24sIHByb3ZpZGVyKTsKKyAgICAgICAgLy8gICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAvLyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyBjaXBoZXIgaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGtleS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgY2lwaGVyIGlzIGluaXRpYWxpemVkIGZvciB0aGUgc3BlY2lmaWVkIG9wZXJhdGlvbmFsIG1vZGUgKG9uZSBvZjoKKyAgICAgKiBlbmNyeXB0aW9uLCBkZWNyeXB0aW9uLCBrZXkgd3JhcHBpbmcgb3Iga2V5IHVud3JhcHBpbmcpIGRlcGVuZGluZyBvbgorICAgICAqIHtAY29kZSBvcG1vZGV9LgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgY2lwaGVyIGluc3RhbmNlIG5lZWRzIGFueSBhbGdvcml0aG0gcGFyYW1ldGVycyBvciByYW5kb20gdmFsdWVzCisgICAgICogdGhhdCB0aGUgc3BlY2lmaWVkIGtleSBjYW4gbm90IHByb3ZpZGUsIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uIG9mCisgICAgICogdGhpcyBjaXBoZXIgaXMgc3VwcG9zZWQgdG8gZ2VuZXJhdGUgdGhlIHJlcXVpcmVkIHBhcmFtZXRlcnMgKHVzaW5nIGl0cworICAgICAqIHByb3ZpZGVyIG9yIHJhbmRvbSB2YWx1ZXMpLgorICAgICAqIDxwPgorICAgICAqIFdoZW4gYSBjaXBoZXIgaW5zdGFuY2UgaXMgaW5pdGlhbGl6ZWQgYnkgYSBjYWxsIHRvIGFueSBvZiB0aGUge0Bjb2RlCisgICAgICogaW5pdH0gbWV0aG9kcywgdGhlIHN0YXRlIG9mIHRoZSBpbnN0YW5jZSBpcyBvdmVycmlkZGVuLCBtZWFuaW5nIHRoYXQgaXQKKyAgICAgKiBpcyBlcXVpdmFsZW50IHRvIGNyZWF0aW5nIGEgbmV3IGluc3RhbmNlIGFuZCBjYWxsaW5nIGl0cyB7QGNvZGUgaW5pdH0KKyAgICAgKiBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3Btb2RlCisgICAgICogICAgICAgICAgICB0aGUgb3BlcmF0aW9uIHRoaXMgY2lwaGVyIGluc3RhbmNlIHNob3VsZCBiZSBpbml0aWFsaXplZCBmb3IKKyAgICAgKiAgICAgICAgICAgIChvbmUgb2Y6IHtAY29kZSBFTkNSWVBUX01PREV9LCB7QGNvZGUgREVDUllQVF9NT0RFfSwge0Bjb2RlCisgICAgICogICAgICAgICAgICBXUkFQX01PREV9IG9yIHtAY29kZSBVTldSQVBfTU9ERX0pLgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBrZXkgZm9yIHRoZSBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBrZXkgY2FuIG5vdCBiZSB1c2VkIHRvIGluaXRpYWxpemUgdGhpcworICAgICAqICAgICAgICAgICAgIGNpcGhlciBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBpbml0KGludCBvcG1vZGUsIEtleSBrZXkpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNlY3VyZVJhbmRvbSA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBJbiB0aGVvcnkgaXQgbWlnaHQgYmUgdGhyZWFkLXVuc2FmZSBidXQgaW4gdGhlIGdpdmVuIGNhc2UgaXQncyBPSworICAgICAgICAgICAgLy8gc2luY2UgaXQgZG9lcyBub3QgbWF0dGVyIHdoaWNoIFNlY3VyZVJhbmRvbSBpbnN0YW5jZSBpcyBwYXNzZWQKKyAgICAgICAgICAgIC8vIHRvIHRoZSBpbml0KCkKKyAgICAgICAgICAgIHNlY3VyZVJhbmRvbSA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgfQorICAgICAgICBpbml0KG9wbW9kZSwga2V5LCBzZWN1cmVSYW5kb20pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMgY2lwaGVyIGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBrZXkgYW5kIGEgc291cmNlIG9mCisgICAgICogcmFuZG9tbmVzcy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgY2lwaGVyIGlzIGluaXRpYWxpemVkIGZvciB0aGUgc3BlY2lmaWVkIG9wZXJhdGlvbmFsIG1vZGUgKG9uZSBvZjoKKyAgICAgKiBlbmNyeXB0aW9uLCBkZWNyeXB0aW9uLCBrZXkgd3JhcHBpbmcgb3Iga2V5IHVud3JhcHBpbmcpIGRlcGVuZGluZyBvbgorICAgICAqIHtAY29kZSBvcG1vZGV9LgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgY2lwaGVyIGluc3RhbmNlIG5lZWRzIGFueSBhbGdvcml0aG0gcGFyYW1ldGVycyBvciByYW5kb20gdmFsdWVzCisgICAgICogdGhhdCB0aGUgc3BlY2lmaWVkIGtleSBjYW4gbm90IHByb3ZpZGUsIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uIG9mCisgICAgICogdGhpcyBjaXBoZXIgaXMgc3VwcG9zZWQgdG8gZ2VuZXJhdGUgdGhlIHJlcXVpcmVkIHBhcmFtZXRlcnMgKHVzaW5nIGl0cworICAgICAqIHByb3ZpZGVyIG9yIHJhbmRvbSB2YWx1ZXMpLiBSYW5kb20gdmFsdWVzIGFyZSBnZW5lcmF0ZWQgdXNpbmcge0Bjb2RlCisgICAgICogcmFuZG9tfTsKKyAgICAgKiA8cD4KKyAgICAgKiBXaGVuIGEgY2lwaGVyIGluc3RhbmNlIGlzIGluaXRpYWxpemVkIGJ5IGEgY2FsbCB0byBhbnkgb2YgdGhlIHtAY29kZQorICAgICAqIGluaXR9IG1ldGhvZHMsIHRoZSBzdGF0ZSBvZiB0aGUgaW5zdGFuY2UgaXMgb3ZlcnJpZGRlbiwgbWVhbnMgaXQgaXMKKyAgICAgKiBlcXVpdmFsZW50IHRvIGNyZWF0aW5nIGEgbmV3IGluc3RhbmNlIGFuZCBjYWxsaW5nIGl0IHtAY29kZSBpbml0fSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3Btb2RlCisgICAgICogICAgICAgICAgICB0aGUgb3BlcmF0aW9uIHRoaXMgY2lwaGVyIGluc3RhbmNlIHNob3VsZCBiZSBpbml0aWFsaXplZCBmb3IKKyAgICAgKiAgICAgICAgICAgIChvbmUgb2Y6IHtAY29kZSBFTkNSWVBUX01PREV9LCB7QGNvZGUgREVDUllQVF9NT0RFfSwge0Bjb2RlCisgICAgICogICAgICAgICAgICBXUkFQX01PREV9IG9yIHtAY29kZSBVTldSQVBfTU9ERX0pLgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBrZXkgZm9yIHRoZSBvcGVyYXRpb24uCisgICAgICogQHBhcmFtIHJhbmRvbQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBvZiByYW5kb21uZXNzIHRvIHVzZS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGtleSBjYW4gbm90IGJlIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGlzCisgICAgICogICAgICAgICAgICAgY2lwaGVyIGluc3RhbmNlLgorICAgICAqIEB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgb3Btb2RlIGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdChpbnQgb3Btb2RlLCBLZXkga2V5LCBTZWN1cmVSYW5kb20gcmFuZG9tKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrTW9kZShvcG1vZGUpOworICAgICAgICAvLyAgICAgICAgRklYTUUgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAgICAvLyAgICAgICAgaWYga2V5c2l6ZSBleGNlZWRzIHRoZSBtYXhpbXVtIGFsbG93YWJsZSBrZXlzaXplCisgICAgICAgIC8vICAgICAgICAoanVyaXNkaWN0aW9uIHBvbGljeSBmaWxlcykKKyAgICAgICAgc3BpSW1wbC5lbmdpbmVJbml0KG9wbW9kZSwga2V5LCByYW5kb20pOworICAgICAgICBtb2RlID0gb3Btb2RlOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja01vZGUoaW50IG1vZGUpIHsKKyAgICAgICAgaWYgKG1vZGUgIT0gRU5DUllQVF9NT0RFICYmIG1vZGUgIT0gREVDUllQVF9NT0RFCisgICAgICAgICAgICAmJiBtb2RlICE9IFVOV1JBUF9NT0RFICYmIG1vZGUgIT0gV1JBUF9NT0RFKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbigiSW52YWxpZCBtb2RlOiAiICsgbW9kZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIGNpcGhlciBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IGFuZCBhbGdvcml0aG0KKyAgICAgKiBwYXJhbWV0ZXJzLgorICAgICAqIDxwPgorICAgICAqIFRoZSBjaXBoZXIgaXMgaW5pdGlhbGl6ZWQgZm9yIHRoZSBzcGVjaWZpZWQgb3BlcmF0aW9uYWwgbW9kZSAob25lIG9mOgorICAgICAqIGVuY3J5cHRpb24sIGRlY3J5cHRpb24sIGtleSB3cmFwcGluZyBvciBrZXkgdW53cmFwcGluZykuCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBjaXBoZXIgaW5zdGFuY2UgbmVlZHMgYW55IGFsZ29yaXRobSBwYXJhbWV0ZXJzIGFuZCB7QGNvZGUgcGFyYW1zfQorICAgICAqIGlzIHtAY29kZSBudWxsfSwgdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBjaXBoZXIgaXMgc3VwcG9zZWQKKyAgICAgKiB0byBnZW5lcmF0ZSB0aGUgcmVxdWlyZWQgcGFyYW1ldGVycyAodXNpbmcgaXRzIHByb3ZpZGVyIG9yIHJhbmRvbQorICAgICAqIHZhbHVlcykuCisgICAgICogPHA+CisgICAgICogV2hlbiBhIGNpcGhlciBpbnN0YW5jZSBpcyBpbml0aWFsaXplZCBieSBhIGNhbGwgdG8gYW55IG9mIHRoZSB7QGNvZGUKKyAgICAgKiBpbml0fSBtZXRob2RzLCB0aGUgc3RhdGUgb2YgdGhlIGluc3RhbmNlIGlzIG92ZXJyaWRkZW4sIG1lYW5zIGl0IGlzCisgICAgICogZXF1aXZhbGVudCB0byBjcmVhdGluZyBhIG5ldyBpbnN0YW5jZSBhbmQgY2FsbGluZyBpdCB7QGNvZGUgaW5pdH0gbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIG9wbW9kZQorICAgICAqICAgICAgICAgICAgdGhlIG9wZXJhdGlvbiB0aGlzIGNpcGhlciBpbnN0YW5jZSBzaG91bGQgYmUgaW5pdGlhbGl6ZWQgZm9yCisgICAgICogICAgICAgICAgICAob25lIG9mOiB7QGNvZGUgRU5DUllQVF9NT0RFfSwge0Bjb2RlIERFQ1JZUFRfTU9ERX0sIHtAY29kZQorICAgICAqICAgICAgICAgICAgV1JBUF9NT0RFfSBvciB7QGNvZGUgVU5XUkFQX01PREV9KS4KKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQga2V5IGZvciB0aGUgb3BlcmF0aW9uLgorICAgICAqIEBwYXJhbSBwYXJhbXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGdvcml0aG0gcGFyYW1ldGVycy4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGtleSBjYW4gbm90IGJlIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGlzCisgICAgICogICAgICAgICAgICAgY2lwaGVyIGluc3RhbmNlLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGl0IHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycyBhcmUgaW5hcHByb3ByaWF0ZSBmb3IgdGhpcworICAgICAqICAgICAgICAgICAgIGNpcGhlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBpbml0KGludCBvcG1vZGUsIEtleSBrZXksIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1zKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24sIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBpZiAoc2VjdXJlUmFuZG9tID09IG51bGwpIHsKKyAgICAgICAgICAgIHNlY3VyZVJhbmRvbSA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgfQorICAgICAgICBpbml0KG9wbW9kZSwga2V5LCBwYXJhbXMsIHNlY3VyZVJhbmRvbSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyBjaXBoZXIgaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGtleSwgYWxnb3JpdGhtCisgICAgICogcGFyYW1ldGVycyBhbmQgYSBzb3VyY2Ugb2YgcmFuZG9tbmVzcy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgY2lwaGVyIGlzIGluaXRpYWxpemVkIGZvciB0aGUgc3BlY2lmaWVkIG9wZXJhdGlvbmFsIG1vZGUgKG9uZSBvZjoKKyAgICAgKiBlbmNyeXB0aW9uLCBkZWNyeXB0aW9uLCBrZXkgd3JhcHBpbmcgb3Iga2V5IHVud3JhcHBpbmcpIGRlcGVuZGluZyBvbgorICAgICAqIHtAY29kZSBvcG1vZGV9LgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgY2lwaGVyIGluc3RhbmNlIG5lZWRzIGFueSBhbGdvcml0aG0gcGFyYW1ldGVycyBhbmQge0Bjb2RlIHBhcmFtc30KKyAgICAgKiBpcyB7QGNvZGUgbnVsbH0sIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgY2lwaGVyIGlzIHN1cHBvc2VkCisgICAgICogdG8gZ2VuZXJhdGUgdGhlIHJlcXVpcmVkIHBhcmFtZXRlcnMgKHVzaW5nIGl0cyBwcm92aWRlciBvciByYW5kb20KKyAgICAgKiB2YWx1ZXMpLiBSYW5kb20gdmFsdWVzIGFyZSBnZW5lcmF0ZWQgdXNpbmcge0Bjb2RlIHJhbmRvbX07CisgICAgICogPHA+CisgICAgICogV2hlbiBhIGNpcGhlciBpbnN0YW5jZSBpcyBpbml0aWFsaXplZCBieSBhIGNhbGwgdG8gYW55IG9mIHRoZSB7QGNvZGUKKyAgICAgKiBpbml0fSBtZXRob2RzLCB0aGUgc3RhdGUgb2YgdGhlIGluc3RhbmNlIGlzIG92ZXJyaWRkZW4sIG1lYW5pbmcgdGhhdCBpdAorICAgICAqIGlzIGVxdWl2YWxlbnQgdG8gY3JlYXRpbmcgYSBuZXcgaW5zdGFuY2UgYW5kIGNhbGxpbmcgaXQge0Bjb2RlIGluaXR9CisgICAgICogbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIG9wbW9kZQorICAgICAqICAgICAgICAgICAgdGhlIG9wZXJhdGlvbiB0aGlzIGNpcGhlciBpbnN0YW5jZSBzaG91bGQgYmUgaW5pdGlhbGl6ZWQgZm9yCisgICAgICogICAgICAgICAgICAob25lIG9mOiB7QGNvZGUgRU5DUllQVF9NT0RFfSwge0Bjb2RlIERFQ1JZUFRfTU9ERX0sIHtAY29kZQorICAgICAqICAgICAgICAgICAgV1JBUF9NT0RFfSBvciB7QGNvZGUgVU5XUkFQX01PREV9KS4KKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQga2V5IGZvciB0aGUgb3BlcmF0aW9uLgorICAgICAqIEBwYXJhbSBwYXJhbXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGdvcml0aG0gcGFyYW1ldGVycy4KKyAgICAgKiBAcGFyYW0gcmFuZG9tCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIG9mIHJhbmRvbW5lc3MgdG8gdXNlLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbiBub3QgYmUgdXNlZCB0byBpbml0aWFsaXplIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBjaXBoZXIgaW5zdGFuY2UuCisgICAgICogQHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaXQgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzIGFyZSBpbmFwcHJvcHJpYXRlIGZvciB0aGlzCisgICAgICogICAgICAgICAgICAgY2lwaGVyLgorICAgICAqIEB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQge0Bjb2RlIG9wbW9kZX0gaXMgaW52YWxpZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBpbml0KGludCBvcG1vZGUsIEtleSBrZXksIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1zLAorICAgICAgICAgICAgU2VjdXJlUmFuZG9tIHJhbmRvbSkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tNb2RlKG9wbW9kZSk7CisgICAgICAgIC8vICAgICAgICBGSVhNRSBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICAgIC8vICAgICAgICBpZiBrZXlzaXplIGV4Y2VlZHMgdGhlIG1heGltdW0gYWxsb3dhYmxlIGtleXNpemUKKyAgICAgICAgLy8gICAgICAgIChqdXJpc2RpY3Rpb24gcG9saWN5IGZpbGVzKQorICAgICAgICAvLyAgICAgICAgRklYTUUgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAgICAvLyAgICAgICAgY3J5cHRvZ3JhcGhpYyBzdHJlbmd0aCBleGNlZWQgdGhlIGxlZ2FsIGxpbWl0cworICAgICAgICAvLyAgICAgICAgKGp1cmlzZGljdGlvbiBwb2xpY3kgZmlsZXMpCisgICAgICAgIHNwaUltcGwuZW5naW5lSW5pdChvcG1vZGUsIGtleSwgcGFyYW1zLCByYW5kb20pOworICAgICAgICBtb2RlID0gb3Btb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMgY2lwaGVyIGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBrZXkgYW5kIGFsZ29yaXRobQorICAgICAqIHBhcmFtZXRlcnMuCisgICAgICogPHA+CisgICAgICogVGhlIGNpcGhlciBpcyBpbml0aWFsaXplZCBmb3IgdGhlIHNwZWNpZmllZCBvcGVyYXRpb24gKG9uZSBvZjoKKyAgICAgKiBlbmNyeXB0aW9uLCBkZWNyeXB0aW9uLCBrZXkgd3JhcHBpbmcgb3Iga2V5IHVud3JhcHBpbmcpIGRlcGVuZGluZyBvbgorICAgICAqIHtAY29kZSBvcG1vZGV9LgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgY2lwaGVyIGluc3RhbmNlIG5lZWRzIGFueSBhbGdvcml0aG0gcGFyYW1ldGVycyBhbmQge0Bjb2RlIHBhcmFtc30KKyAgICAgKiBpcyB7QGNvZGUgbnVsbH0sIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgY2lwaGVyIGlzIHN1cHBvc2VkCisgICAgICogdG8gZ2VuZXJhdGUgdGhlIHJlcXVpcmVkIHBhcmFtZXRlcnMgKHVzaW5nIGl0cyBwcm92aWRlciBvciByYW5kb20KKyAgICAgKiB2YWx1ZXMpLgorICAgICAqIDxwPgorICAgICAqIFdoZW4gYSBjaXBoZXIgaW5zdGFuY2UgaXMgaW5pdGlhbGl6ZWQgYnkgYSBjYWxsIHRvIGFueSBvZiB0aGUge0Bjb2RlCisgICAgICogaW5pdH0gbWV0aG9kcywgdGhlIHN0YXRlIG9mIHRoZSBpbnN0YW5jZSBpcyBvdmVycmlkZGVuLCBtZWFuaW5nIHRoYXQgaXQKKyAgICAgKiBpcyBlcXVpdmFsZW50IHRvIGNyZWF0aW5nIGEgbmV3IGluc3RhbmNlIGFuZCBjYWxsaW5nIGl0IHtAY29kZSBpbml0fQorICAgICAqIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcG1vZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBvcGVyYXRpb24gdGhpcyBjaXBoZXIgaW5zdGFuY2Ugc2hvdWxkIGJlIGluaXRpYWxpemVkIGZvcgorICAgICAqICAgICAgICAgICAgKG9uZSBvZjoge0Bjb2RlIEVOQ1JZUFRfTU9ERX0sIHtAY29kZSBERUNSWVBUX01PREV9LCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFdSQVBfTU9ERX0gb3Ige0Bjb2RlIFVOV1JBUF9NT0RFfSkuCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IGtleSBmb3IgdGhlIG9wZXJhdGlvbi4KKyAgICAgKiBAcGFyYW0gcGFyYW1zCisgICAgICogICAgICAgICAgICB0aGUgYWxnb3JpdGhtIHBhcmFtZXRlcnMuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBrZXkgY2FuIG5vdCBiZSB1c2VkIHRvIGluaXRpYWxpemUgdGhpcworICAgICAqICAgICAgICAgICAgIGNpcGhlciBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpdCB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMgYXJlIGluYXBwcm9wcmlhdGUgZm9yIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBjaXBoZXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdChpbnQgb3Btb2RlLCBLZXkga2V5LCBBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtcykKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLCBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNlY3VyZVJhbmRvbSA9PSBudWxsKSB7CisgICAgICAgICAgICBzZWN1cmVSYW5kb20gPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIH0KKyAgICAgICAgaW5pdChvcG1vZGUsIGtleSwgcGFyYW1zLCBzZWN1cmVSYW5kb20pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMgY2lwaGVyIGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBrZXksIGFsZ29yaXRobQorICAgICAqIHBhcmFtZXRlcnMgYW5kIGEgc291cmNlIG9mIHJhbmRvbW5lc3MuCisgICAgICogPHA+CisgICAgICogVGhlIGNpcGhlciB3aWxsIGJlIGluaXRpYWxpemVkIGZvciB0aGUgc3BlY2lmaWVkIG9wZXJhdGlvbiAob25lIG9mOgorICAgICAqIGVuY3J5cHRpb24sIGRlY3J5cHRpb24sIGtleSB3cmFwcGluZyBvciBrZXkgdW53cmFwcGluZykgZGVwZW5kaW5nIG9uCisgICAgICoge0Bjb2RlIG9wbW9kZX0uCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBjaXBoZXIgaW5zdGFuY2UgbmVlZHMgYW55IGFsZ29yaXRobSBwYXJhbWV0ZXJzIGFuZCB7QGNvZGUgcGFyYW1zfQorICAgICAqIGlzIHtAY29kZSBudWxsfSwgdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBjaXBoZXIgaXMgc3VwcG9zZWQKKyAgICAgKiB0byBnZW5lcmF0ZSB0aGUgcmVxdWlyZWQgcGFyYW1ldGVycyAodXNpbmcgaXRzIHByb3ZpZGVyIG9yIHJhbmRvbQorICAgICAqIHZhbHVlcykuIFJhbmRvbSB2YWx1ZXMgYXJlIGdlbmVyYXRlZCB1c2luZyB7QGNvZGUgcmFuZG9tfS4KKyAgICAgKiA8cD4KKyAgICAgKiBXaGVuIGEgY2lwaGVyIGluc3RhbmNlIGlzIGluaXRpYWxpemVkIGJ5IGEgY2FsbCB0byBhbnkgb2YgdGhlIHtAY29kZQorICAgICAqIGluaXR9IG1ldGhvZHMsIHRoZSBzdGF0ZSBvZiB0aGUgaW5zdGFuY2UgaXMgb3ZlcnJpZGRlbiwgbWVhbnMgaXQgaXMKKyAgICAgKiBlcXVpdmFsZW50IHRvIGNyZWF0aW5nIGEgbmV3IGluc3RhbmNlIGFuZCBjYWxsaW5nIGl0IHtAY29kZSBpbml0fSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3Btb2RlCisgICAgICogICAgICAgICAgICB0aGUgb3BlcmF0aW9uIHRoaXMgY2lwaGVyIGluc3RhbmNlIHNob3VsZCBiZSBpbml0aWFsaXplZCBmb3IKKyAgICAgKiAgICAgICAgICAgIChvbmUgb2Y6IHtAY29kZSBFTkNSWVBUX01PREV9LCB7QGNvZGUgREVDUllQVF9NT0RFfSwge0Bjb2RlCisgICAgICogICAgICAgICAgICBXUkFQX01PREV9IG9yIHtAY29kZSBVTldSQVBfTU9ERX0pLgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBrZXkgZm9yIHRoZSBvcGVyYXRpb24uCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIGFsZ29yaXRobSBwYXJhbWV0ZXJzLgorICAgICAqIEBwYXJhbSByYW5kb20KKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2Ugb2YgcmFuZG9tbmVzcyB0byB1c2UuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBrZXkgY2FuIG5vdCBiZSB1c2VkIHRvIGluaXRpYWxpemUgdGhpcworICAgICAqICAgICAgICAgICAgIGNpcGhlciBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMgYXJlIGluYXBwcm9wcmlhdGUgZm9yIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBjaXBoZXIuCisgICAgICogQHRocm93cyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCB7QGNvZGUgb3Btb2RlfSBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGluaXQoaW50IG9wbW9kZSwgS2V5IGtleSwgQWxnb3JpdGhtUGFyYW1ldGVycyBwYXJhbXMsCisgICAgICAgICAgICBTZWN1cmVSYW5kb20gcmFuZG9tKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBjaGVja01vZGUob3Btb2RlKTsKKyAgICAgICAgLy8gICAgICAgIEZJWE1FIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgICAgLy8gICAgICAgIGlmIGtleXNpemUgZXhjZWVkcyB0aGUgbWF4aW11bSBhbGxvd2FibGUga2V5c2l6ZQorICAgICAgICAvLyAgICAgICAgKGp1cmlzZGljdGlvbiBwb2xpY3kgZmlsZXMpCisgICAgICAgIC8vICAgICAgICBGSVhNRSBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uCisgICAgICAgIC8vICAgICAgICBjcnlwdG9ncmFwaGljIHN0cmVuZ3RoIGV4Y2VlZCB0aGUgbGVnYWwgbGltaXRzCisgICAgICAgIC8vICAgICAgICAoanVyaXNkaWN0aW9uIHBvbGljeSBmaWxlcykKKyAgICAgICAgc3BpSW1wbC5lbmdpbmVJbml0KG9wbW9kZSwga2V5LCBwYXJhbXMsIHJhbmRvbSk7CisgICAgICAgIG1vZGUgPSBvcG1vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyBjaXBoZXIgaW5zdGFuY2Ugd2l0aCB0aGUgcHVibGljIGtleSBmcm9tIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjZXJ0aWZpY2F0ZS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgY2lwaGVyIHdpbGwgYmUgaW5pdGlhbGl6ZWQgZm9yIHRoZSBzcGVjaWZpZWQgb3BlcmF0aW9uIChvbmUgb2Y6CisgICAgICogZW5jcnlwdGlvbiwgZGVjcnlwdGlvbiwga2V5IHdyYXBwaW5nIG9yIGtleSB1bndyYXBwaW5nKSBkZXBlbmRpbmcgb24KKyAgICAgKiB7QGNvZGUgb3Btb2RlfS4KKyAgICAgKiA8cD4KKyAgICAgKiBJdCB0aGUgdHlwZSBvZiB0aGUgY2VydGlmaWNhdGUgaXMgWC41MDkgYW5kIHRoZSBjZXJ0aWZpY2F0ZSBoYXMgYSA8aT5rZXkKKyAgICAgKiB1c2FnZTwvaT4gZXh0ZW5zaW9uIGZpZWxkIG1hcmtlZCBhcyBjcml0aWNhbCwgdGhlIHNwZWNpZmllZCB7QGNvZGUKKyAgICAgKiBvcG1vZGV9IGhhcyB0aGUgYmUgZW5hYmxlZCBmb3IgdGhpcyBrZXksIG90aGVyd2lzZSBhbiB7QGNvZGUKKyAgICAgKiBJbnZhbGlkS2V5RXhjZXB0aW9ufSBpcyB0aHJvd24uCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBjaXBoZXIgaW5zdGFuY2UgbmVlZHMgYW55IGFsZ29yaXRobSBwYXJhbWV0ZXJzIHRoYXQgdGhlIGtleSBpbgorICAgICAqIHRoZSBjZXJ0aWZpY2F0ZSBjYW4gbm90IHByb3ZpZGUsIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uIG9mIHRoaXMKKyAgICAgKiBjaXBoZXIgaXMgc3VwcG9zZWQgdG8gZ2VuZXJhdGUgdGhlIHJlcXVpcmVkIHBhcmFtZXRlcnMgKHVzaW5nIGl0cworICAgICAqIHByb3ZpZGVyIG9yIHJhbmRvbSB2YWx1ZXMpLgorICAgICAqIDxwPgorICAgICAqIFdoZW4gYSBjaXBoZXIgaW5zdGFuY2UgaXMgaW5pdGlhbGl6ZWQgYnkgYSBjYWxsIHRvIGFueSBvZiB0aGUge0Bjb2RlCisgICAgICogaW5pdH0gbWV0aG9kcywgdGhlIHN0YXRlIG9mIHRoZSBpbnN0YW5jZSBpcyBvdmVycmlkZGVuLCBtZWFucyBpdCBpcworICAgICAqIGVxdWl2YWxlbnQgdG8gY3JlYXRpbmcgYSBuZXcgaW5zdGFuY2UgYW5kIGNhbGxpbmcgaXQge0Bjb2RlIGluaXR9IG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcG1vZGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBvcGVyYXRpb24gdGhpcyBjaXBoZXIgaW5zdGFuY2Ugc2hvdWxkIGJlIGluaXRpYWxpemVkIGZvcgorICAgICAqICAgICAgICAgICAgKG9uZSBvZjoge0Bjb2RlIEVOQ1JZUFRfTU9ERX0sIHtAY29kZSBERUNSWVBUX01PREV9LCB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFdSQVBfTU9ERX0gb3Ige0Bjb2RlIFVOV1JBUF9NT0RFfSkuCisgICAgICogQHBhcmFtIGNlcnRpZmljYXRlCisgICAgICogICAgICAgICAgICB0aGUgY2VydGlmaWNhdGUuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHB1YmxpYyBrZXkgaW4gdGhlIGNlcnRpZmljYXRlIGNhbiBub3QgYmUgdXNlZCB0bworICAgICAqICAgICAgICAgICAgIGluaXRpYWxpemUgdGhpcyBjaXBoZXIgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdChpbnQgb3Btb2RlLCBDZXJ0aWZpY2F0ZSBjZXJ0aWZpY2F0ZSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNlY3VyZVJhbmRvbSA9PSBudWxsKSB7CisgICAgICAgICAgICBzZWN1cmVSYW5kb20gPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIH0KKyAgICAgICAgaW5pdChvcG1vZGUsIGNlcnRpZmljYXRlLCBzZWN1cmVSYW5kb20pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMgY2lwaGVyIGluc3RhbmNlIHdpdGggdGhlIHB1YmxpYyBrZXkgZnJvbSB0aGUgc3BlY2lmaWVkCisgICAgICogY2VydGlmaWNhdGUgYW5kIGEgc291cmNlIG9mIHJhbmRvbW5lc3MuCisgICAgICogPHA+CisgICAgICogVGhlIGNpcGhlciB3aWxsIGJlIGluaXRpYWxpemVkIGZvciB0aGUgc3BlY2lmaWVkIG9wZXJhdGlvbiAob25lIG9mOgorICAgICAqIGVuY3J5cHRpb24sIGRlY3J5cHRpb24sIGtleSB3cmFwcGluZyBvciBrZXkgdW53cmFwcGluZykgZGVwZW5kaW5nIG9uCisgICAgICoge0Bjb2RlIG9wbW9kZX0uCisgICAgICogPHA+CisgICAgICogSXQgdGhlIHR5cGUgb2YgdGhlIGNlcnRpZmljYXRlIGlzIFguNTA5IGFuZCB0aGUgY2VydGlmaWNhdGUgaGFzIGEgPGk+a2V5CisgICAgICogdXNhZ2U8L2k+IGV4dGVuc2lvbiBmaWVsZCBtYXJrZWQgYXMgY3JpdGljYWwsIHRoZSBzcGVjaWZpZWQge0Bjb2RlCisgICAgICogb3Btb2RlfSBoYXMgdGhlIGJlIGVuYWJsZWQgZm9yIHRoaXMga2V5LCBvdGhlcndpc2UgYW4ge0Bjb2RlCisgICAgICogSW52YWxpZEtleUV4Y2VwdGlvbn0gaXMgdGhyb3duLgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgY2lwaGVyIGluc3RhbmNlIG5lZWRzIGFueSBhbGdvcml0aG0gcGFyYW1ldGVycyB0aGF0IHRoZSBrZXkgaW4KKyAgICAgKiB0aGUgY2VydGlmaWNhdGUgY2FuIG5vdCBwcm92aWRlLCB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzCisgICAgICogY2lwaGVyIGlzIHN1cHBvc2VkIHRvIGdlbmVyYXRlIHRoZSByZXF1aXJlZCBwYXJhbWV0ZXJzICh1c2luZyBpdHMKKyAgICAgKiBwcm92aWRlciBvciByYW5kb20gdmFsdWVzKS4gUmFuZG9tIHZhbHVlcyBhcmUgZ2VuZXJhdGVkIHVzaW5nIHtAY29kZQorICAgICAqIHJhbmRvbX0uCisgICAgICogPHA+CisgICAgICogV2hlbiBhIGNpcGhlciBpbnN0YW5jZSBpcyBpbml0aWFsaXplZCBieSBhIGNhbGwgdG8gYW55IG9mIHRoZSB7QGNvZGUKKyAgICAgKiBpbml0fSBtZXRob2RzLCB0aGUgc3RhdGUgb2YgdGhlIGluc3RhbmNlIGlzIG92ZXJyaWRkZW4sIG1lYW5zIGl0IGlzCisgICAgICogZXF1aXZhbGVudCB0byBjcmVhdGluZyBhIG5ldyBpbnN0YW5jZSBhbmQgY2FsbGluZyBpdCB7QGNvZGUgaW5pdH0gbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIG9wbW9kZQorICAgICAqICAgICAgICAgICAgdGhlIG9wZXJhdGlvbiB0aGlzIGNpcGhlciBpbnN0YW5jZSBzaG91bGQgYmUgaW5pdGlhbGl6ZWQgZm9yCisgICAgICogICAgICAgICAgICAob25lIG9mOiB7QGNvZGUgRU5DUllQVF9NT0RFfSwge0Bjb2RlIERFQ1JZUFRfTU9ERX0sIHtAY29kZQorICAgICAqICAgICAgICAgICAgV1JBUF9NT0RFfSBvciB7QGNvZGUgVU5XUkFQX01PREV9KS4KKyAgICAgKiBAcGFyYW0gY2VydGlmaWNhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZS4KKyAgICAgKiBAcGFyYW0gcmFuZG9tCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIG9mIHJhbmRvbW5lc3MgdG8gYmUgdXNlZC4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcHVibGljIGtleSBpbiB0aGUgY2VydGlmaWNhdGUgY2FuIG5vdCBiZSB1c2VkIHRvCisgICAgICogICAgICAgICAgICAgaW5pdGlhbGl6ZSB0aGlzIGNpcGhlciBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBpbml0KGludCBvcG1vZGUsIENlcnRpZmljYXRlIGNlcnRpZmljYXRlLAorICAgICAgICAgICAgU2VjdXJlUmFuZG9tIHJhbmRvbSkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICBjaGVja01vZGUob3Btb2RlKTsKKyAgICAgICAgaWYgKGNlcnRpZmljYXRlIGluc3RhbmNlb2YgWDUwOUNlcnRpZmljYXRlKSB7CisgICAgICAgICAgICBTZXQ8U3RyaW5nPiBjZSA9ICgoWDUwOUNlcnRpZmljYXRlKSBjZXJ0aWZpY2F0ZSkuZ2V0Q3JpdGljYWxFeHRlbnNpb25PSURzKCk7CisgICAgICAgICAgICBib29sZWFuIGNyaXRpY2FsID0gZmFsc2U7CisgICAgICAgICAgICBpZiAoY2UgIT0gbnVsbCAmJiAhY2UuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgZm9yIChTdHJpbmcgb2lkIDogY2UpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG9pZC5lcXVhbHMoIjIuNS4yOS4xNSIpKSB7IC8vIEtleVVzYWdlIE9JRCA9IDIuNS4yOS4xNQorICAgICAgICAgICAgICAgICAgICAgICAgY3JpdGljYWwgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGNyaXRpY2FsKSB7CisgICAgICAgICAgICAgICAgICAgIGJvb2xlYW5bXSBrZXlVc2FnZSA9ICgoWDUwOUNlcnRpZmljYXRlKSBjZXJ0aWZpY2F0ZSkuZ2V0S2V5VXNhZ2UoKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gQXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwOgorICAgICAgICAgICAgICAgICAgICAvLyAgIEludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUKKyAgICAgICAgICAgICAgICAgICAgLy8gICBDZXJ0aWZpY2F0ZSBhbmQgQ2VydGlmaWNhdGUgUmV2b2NhdGlvbiBMaXN0IChDUkwpIFByb2ZpbGUuCisgICAgICAgICAgICAgICAgICAgIC8vIFNlY3Rpb24gNC4yLjEuMyAgS2V5IFVzYWdlCisgICAgICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0CisgICAgICAgICAgICAgICAgICAgIC8vCisgICAgICAgICAgICAgICAgICAgIC8vIEtleVVzYWdlIDo6PSBCSVQgU1RSSU5HIHtkaWdpdGFsU2lnbmF0dXJlICgwKSwKKyAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgIG5vblJlcHVkaWF0aW9uICAgKDEpLAorICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAga2V5RW5jaXBoZXJtZW50ICAoMiksCisgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhRW5jaXBoZXJtZW50ICgzKSwKKyAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgIGtleUFncmVlbWVudCAgICAgKDQpLAorICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAga2V5Q2VydFNpZ24gICAgICAoNSksCisgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICBjUkxTaWduICAgICAgICAgICg2KSwKKyAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgIGVuY2lwaGVyT25seSAgICAgKDcpLAorICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjaXBoZXJPbmx5ICAgICAoOCkgfQorICAgICAgICAgICAgICAgICAgICBpZiAoa2V5VXNhZ2UgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wbW9kZSA9PSBFTkNSWVBUX01PREUgJiYgIWtleVVzYWdlWzNdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oIlRoZSBwdWJsaWMga2V5IGluIHRoZSBjZXJ0aWZpY2F0ZSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiY2Fubm90IGJlIHVzZWQgZm9yIEVOQ1JZUFRfTU9ERSIpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvcG1vZGUgPT0gV1JBUF9NT0RFICYmICFrZXlVc2FnZVsyXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5RXhjZXB0aW9uKCJUaGUgcHVibGljIGtleSBpbiB0aGUgY2VydGlmaWNhdGUgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgImNhbm5vdCBiZSB1c2VkIGZvciBXUkFQX01PREUiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyAgICAgICAgRklYTUUgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAgICAvLyAgICAgICAgaWYga2V5c2l6ZSBleGNlZWRzIHRoZSBtYXhpbXVtIGFsbG93YWJsZSBrZXlzaXplCisgICAgICAgIC8vICAgICAgICAoanVyaXNkaWN0aW9uIHBvbGljeSBmaWxlcykKKyAgICAgICAgc3BpSW1wbC5lbmdpbmVJbml0KG9wbW9kZSwgY2VydGlmaWNhdGUuZ2V0UHVibGljS2V5KCksIHJhbmRvbSk7CisgICAgICAgIG1vZGUgPSBvcG1vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udGludWVzIGEgbXVsdGktcGFydCB0cmFuc2Zvcm1hdGlvbiAoZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uKS4gVGhlCisgICAgICogdHJhbnNmb3JtZWQgYnl0ZXMgYXJlIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgYnl0ZXMgdG8gdHJhbnNmb3JtLgorICAgICAqIEByZXR1cm4gdGhlIHRyYW5zZm9ybWVkIGJ5dGVzIGluIGEgbmV3IGJ1ZmZlciwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqICAgICAgICAgaW5wdXQgaGFzIHplcm8gbGVuZ3RoLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaXBoZXIgaW5zdGFuY2UgaXMgbm90IGluaXRpYWxpemVkIGZvciBlbmNyeXB0aW9uIG9yCisgICAgICogICAgICAgICAgICAgZGVjcnlwdGlvbi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBpbnB1dCBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJ5dGVbXSB1cGRhdGUoYnl0ZVtdIGlucHV0KSB7CisgICAgICAgIGlmIChtb2RlICE9IEVOQ1JZUFRfTU9ERSAmJiBtb2RlICE9IERFQ1JZUFRfTU9ERSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJpbnB1dCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0Lmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVVcGRhdGUoaW5wdXQsIDAsIGlucHV0Lmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udGludWVzIGEgbXVsdGktcGFydCB0cmFuc2Zvcm1hdGlvbiAoZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uKS4gVGhlCisgICAgICogdHJhbnNmb3JtZWQgYnl0ZXMgYXJlIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgYnl0ZXMgdG8gdHJhbnNmb3JtLgorICAgICAqIEBwYXJhbSBpbnB1dE9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgaW5wdXQgdG8gc3RhcnQuCisgICAgICogQHBhcmFtIGlucHV0TGVuCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBpbnB1dCB0byB0cmFuc2Zvcm0uCisgICAgICogQHJldHVybiB0aGUgdHJhbnNmb3JtZWQgYnl0ZXMgaW4gYSBuZXcgYnVmZmVyLCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlCisgICAgICogICAgICAgICBpbnB1dCBoYXMgemVybyBsZW5ndGguCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNpcGhlciBpbnN0YW5jZSBpcyBub3QgaW5pdGlhbGl6ZWQgZm9yIGVuY3J5cHRpb24gb3IKKyAgICAgKiAgICAgICAgICAgICBkZWNyeXB0aW9uLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGlucHV0IGlzIHtAY29kZSBudWxsfSwgb3IgaWYge0Bjb2RlIGlucHV0T2Zmc2V0fSBhbmQKKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgaW5wdXRMZW59IGRvIG5vdCBzcGVjaWZ5IGEgdmFsaWQgY2h1bmsgaW4gdGhlIGlucHV0CisgICAgICogICAgICAgICAgICAgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBieXRlW10gdXBkYXRlKGJ5dGVbXSBpbnB1dCwgaW50IGlucHV0T2Zmc2V0LCBpbnQgaW5wdXRMZW4pIHsKKyAgICAgICAgaWYgKG1vZGUgIT0gRU5DUllQVF9NT0RFICYmIG1vZGUgIT0gREVDUllQVF9NT0RFKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImlucHV0ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXRPZmZzZXQgPCAwIHx8IGlucHV0TGVuIDwgMAorICAgICAgICAgICAgICAgIHx8IGlucHV0TGVuID4gaW5wdXQubGVuZ3RoCisgICAgICAgICAgICAgICAgfHwgaW5wdXRPZmZzZXQgPiBpbnB1dC5sZW5ndGggLSBpbnB1dExlbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW5jb3JyZWN0IGlucHV0T2Zmc2V0L2lucHV0TGVuIHBhcmFtZXRlcnMiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZVVwZGF0ZShpbnB1dCwgaW5wdXRPZmZzZXQsIGlucHV0TGVuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb250aW51ZXMgYSBtdWx0aS1wYXJ0IHRyYW5zZm9ybWF0aW9uIChlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24pLiBUaGUKKyAgICAgKiB0cmFuc2Zvcm1lZCBieXRlcyBhcmUgc3RvcmVkIGluIHRoZSB7QGNvZGUgb3V0cHV0fSBidWZmZXIuCisgICAgICogPHA+CisgICAgICogSWYgdGhlIHNpemUgb2YgdGhlIHtAY29kZSBvdXRwdXR9IGJ1ZmZlciBpcyB0b28gc21hbGwgdG8gaG9sZCB0aGUgcmVzdWx0LAorICAgICAqIGEge0Bjb2RlIFNob3J0QnVmZmVyRXhjZXB0aW9ufSBpcyB0aHJvd24uIFVzZQorICAgICAqIHtAbGluayBDaXBoZXIjZ2V0T3V0cHV0U2l6ZSBnZXRPdXRwdXRTaXplfSB0byBjaGVjayBmb3IgdGhlIHNpemUgb2YgdGhlCisgICAgICogb3V0cHV0IGJ1ZmZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dAorICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IGJ5dGVzIHRvIHRyYW5zZm9ybS4KKyAgICAgKiBAcGFyYW0gaW5wdXRPZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIGlucHV0IHRvIHN0YXJ0LgorICAgICAqIEBwYXJhbSBpbnB1dExlbgorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgaW5wdXQgdG8gdHJhbnNmb3JtLgorICAgICAqIEBwYXJhbSBvdXRwdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdXRwdXQgYnVmZmVyLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBwbGFjZWQgaW4gb3V0cHV0LgorICAgICAqIEB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2l6ZSBvZiB0aGUge0Bjb2RlIG91dHB1dH0gYnVmZmVyIGlzIHRvbyBzbWFsbC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2lwaGVyIGluc3RhbmNlIGlzIG5vdCBpbml0aWFsaXplZCBmb3IgZW5jcnlwdGlvbiBvcgorICAgICAqICAgICAgICAgICAgIGRlY3J5cHRpb24uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaW5wdXQgaXMge0Bjb2RlIG51bGx9LCB0aGUgb3V0cHV0IGlzIHtAY29kZSBudWxsfSwgb3IKKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW5wdXRPZmZzZXR9IGFuZCB7QGNvZGUgaW5wdXRMZW59IGRvIG5vdCBzcGVjaWZ5IGEKKyAgICAgKiAgICAgICAgICAgICB2YWxpZCBjaHVuayBpbiB0aGUgaW5wdXQgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgdXBkYXRlKGJ5dGVbXSBpbnB1dCwgaW50IGlucHV0T2Zmc2V0LCBpbnQgaW5wdXRMZW4sCisgICAgICAgICAgICBieXRlW10gb3V0cHV0KSB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24geworICAgICAgICByZXR1cm4gdXBkYXRlKGlucHV0LCBpbnB1dE9mZnNldCwgaW5wdXRMZW4sIG91dHB1dCwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udGludWVzIGEgbXVsdGktcGFydCB0cmFuc2Zvcm1hdGlvbiAoZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uKS4gVGhlCisgICAgICogdHJhbnNmb3JtZWQgYnl0ZXMgYXJlIHN0b3JlZCBpbiB0aGUge0Bjb2RlIG91dHB1dH0gYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBzaXplIG9mIHRoZSB7QGNvZGUgb3V0cHV0fSBidWZmZXIgaXMgdG9vIHNtYWxsIHRvIGhvbGQgdGhlIHJlc3VsdCwKKyAgICAgKiBhIHtAY29kZSBTaG9ydEJ1ZmZlckV4Y2VwdGlvbn0gaXMgdGhyb3duLiBVc2UKKyAgICAgKiB7QGxpbmsgQ2lwaGVyI2dldE91dHB1dFNpemUgZ2V0T3V0cHV0U2l6ZX0gdG8gY2hlY2sgZm9yIHRoZSBzaXplIG9mIHRoZQorICAgICAqIG91dHB1dCBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBieXRlcyB0byB0cmFuc2Zvcm0uCisgICAgICogQHBhcmFtIGlucHV0T2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBpbnB1dCB0byBzdGFydC4KKyAgICAgKiBAcGFyYW0gaW5wdXRMZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhlIGlucHV0IHRvIHRyYW5zZm9ybS4KKyAgICAgKiBAcGFyYW0gb3V0cHV0CisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IGJ1ZmZlci4KKyAgICAgKiBAcGFyYW0gb3V0cHV0T2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBvdXRwdXQgYnVmZmVyLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBwbGFjZWQgaW4gb3V0cHV0LgorICAgICAqIEB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2l6ZSBvZiB0aGUge0Bjb2RlIG91dHB1dH0gYnVmZmVyIGlzIHRvbyBzbWFsbC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2lwaGVyIGluc3RhbmNlIGlzIG5vdCBpbml0aWFsaXplZCBmb3IgZW5jcnlwdGlvbiBvcgorICAgICAqICAgICAgICAgICAgIGRlY3J5cHRpb24uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaW5wdXQgaXMge0Bjb2RlIG51bGx9LCB0aGUgb3V0cHV0IGlzIHtAY29kZSBudWxsfSwgb3IKKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgaW5wdXRPZmZzZXR9IGFuZCB7QGNvZGUgaW5wdXRMZW59IGRvIG5vdCBzcGVjaWZ5IGEKKyAgICAgKiAgICAgICAgICAgICB2YWxpZCBjaHVuayBpbiB0aGUgaW5wdXQgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgdXBkYXRlKGJ5dGVbXSBpbnB1dCwgaW50IGlucHV0T2Zmc2V0LCBpbnQgaW5wdXRMZW4sCisgICAgICAgICAgICBieXRlW10gb3V0cHV0LCBpbnQgb3V0cHV0T2Zmc2V0KSB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24geworICAgICAgICBpZiAobW9kZSAhPSBFTkNSWVBUX01PREUgJiYgbW9kZSAhPSBERUNSWVBUX01PREUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaW5wdXQgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChvdXRwdXQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigib3V0cHV0ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAob3V0cHV0T2Zmc2V0IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigib3V0cHV0T2Zmc2V0IDwgMCIpOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dE9mZnNldCA8IDAgfHwgaW5wdXRMZW4gPCAwIHx8IGlucHV0TGVuID4gaW5wdXQubGVuZ3RoCisgICAgICAgICAgICAgICAgfHwgaW5wdXRPZmZzZXQgPiBpbnB1dC5sZW5ndGggLSBpbnB1dExlbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW5jb3JyZWN0IGlucHV0T2Zmc2V0L2lucHV0TGVuIHBhcmFtZXRlcnMiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZVVwZGF0ZShpbnB1dCwgaW5wdXRPZmZzZXQsIGlucHV0TGVuLCBvdXRwdXQsCisgICAgICAgICAgICAgICAgb3V0cHV0T2Zmc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb250aW51ZXMgYSBtdWx0aS1wYXJ0IHRyYW5zZm9ybWF0aW9uIChlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24pLiBUaGUKKyAgICAgKiB7QGNvZGUgaW5wdXQucmVtYWluaW5nKCl9IGJ5dGVzIHN0YXJ0aW5nIGF0IHtAY29kZSBpbnB1dC5wb3NpdGlvbigpfSBhcmUKKyAgICAgKiB0cmFuc2Zvcm1lZCBhbmQgc3RvcmVkIGluIHRoZSB7QGNvZGUgb3V0cHV0fSBidWZmZXIuCisgICAgICogPHA+CisgICAgICogSWYgdGhlIHtAY29kZSBvdXRwdXQucmVtYWluaW5nKCl9IGlzIHRvbyBzbWFsbCB0byBob2xkIHRoZSB0cmFuc2Zvcm1lZAorICAgICAqIGJ5dGVzIGEge0Bjb2RlIFNob3J0QnVmZmVyRXhjZXB0aW9ufSBpcyB0aHJvd24uIFVzZQorICAgICAqIHtAbGluayBDaXBoZXIjZ2V0T3V0cHV0U2l6ZSBnZXRPdXRwdXRTaXplfSB0byBjaGVjayBmb3IgdGhlIHNpemUgb2YgdGhlCisgICAgICogb3V0cHV0IGJ1ZmZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dAorICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IGJ1ZmZlciB0byB0cmFuc2Zvcm0uCisgICAgICogQHBhcmFtIG91dHB1dAorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBidWZmZXIgdG8gc3RvcmUgdGhlIHJlc3VsdCB3aXRoaW4uCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHN0b3JlZCBpbiB0aGUgb3V0cHV0IGJ1ZmZlci4KKyAgICAgKiBAdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNpemUgb2YgdGhlIHtAY29kZSBvdXRwdXR9IGJ1ZmZlciBpcyB0b28gc21hbGwuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNpcGhlciBpbnN0YW5jZSBpcyBub3QgaW5pdGlhbGl6ZWQgZm9yIGVuY3J5cHRpb24gb3IKKyAgICAgKiAgICAgICAgICAgICBkZWNyeXB0aW9uLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGlucHV0IGJ1ZmZlciBhbmQgdGhlIG91dHB1dCBidWZmZXIgYXJlIHRoZSBpZGVudGljYWwKKyAgICAgKiAgICAgICAgICAgICBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCB1cGRhdGUoQnl0ZUJ1ZmZlciBpbnB1dCwgQnl0ZUJ1ZmZlciBvdXRwdXQpCisgICAgICAgICAgICB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24geworICAgICAgICBpZiAobW9kZSAhPSBFTkNSWVBUX01PREUgJiYgbW9kZSAhPSBERUNSWVBUX01PREUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQgPT0gb3V0cHV0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJpbnB1dCA9PSBvdXRwdXQiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVVcGRhdGUoaW5wdXQsIG91dHB1dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluaXNoZXMgYSBtdWx0aS1wYXJ0IHRyYW5zZm9ybWF0aW9uIChlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24pLgorICAgICAqIDxwPgorICAgICAqIFByb2Nlc3NlcyBhbnkgYnl0ZXMgdGhhdCBtYXkgaGF2ZSBiZWVuIGJ1ZmZlcmVkIGluIHByZXZpb3VzIHtAY29kZQorICAgICAqIHVwZGF0ZX0gY2FsbHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBmaW5hbCBieXRlcyBmcm9tIHRoZSB0cmFuc2Zvcm1hdGlvbi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2l6ZSBvZiB0aGUgcmVzdWx0aW5nIGJ5dGVzIGlzIG5vdCBhIG11bHRpcGxlIG9mIHRoZQorICAgICAqICAgICAgICAgICAgIGNpcGhlciBibG9jayBzaXplLgorICAgICAqIEB0aHJvd3MgQmFkUGFkZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYWRkaW5nIG9mIHRoZSBkYXRhIGRvZXMgbm90IG1hdGNoIHRoZSBwYWRkaW5nIHNjaGVtZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2lwaGVyIGluc3RhbmNlIGlzIG5vdCBpbml0aWFsaXplZCBmb3IgZW5jcnlwdGlvbiBvcgorICAgICAqICAgICAgICAgICAgIGRlY3J5cHRpb24uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJ5dGVbXSBkb0ZpbmFsKCkgdGhyb3dzIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24sCisgICAgICAgICAgICBCYWRQYWRkaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG1vZGUgIT0gRU5DUllQVF9NT0RFICYmIG1vZGUgIT0gREVDUllQVF9NT0RFKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lRG9GaW5hbChudWxsLCAwLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5pc2hlcyBhIG11bHRpLXBhcnQgdHJhbnNmb3JtYXRpb24gKGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbikuCisgICAgICogPHA+CisgICAgICogUHJvY2Vzc2VzIGFueSBieXRlcyB0aGF0IG1heSBoYXZlIGJlZW4gYnVmZmVyZWQgaW4gcHJldmlvdXMge0Bjb2RlCisgICAgICogdXBkYXRlfSBjYWxscy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZmluYWwgdHJhbnNmb3JtZWQgYnl0ZXMgYXJlIHN0b3JlZCBpbiB0aGUge0Bjb2RlIG91dHB1dH0gYnVmZmVyLgorICAgICAqCisgICAgICogQHBhcmFtIG91dHB1dAorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBidWZmZXIuCisgICAgICogQHBhcmFtIG91dHB1dE9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgb3V0cHV0IGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgcGxhY2VkIGluIHRoZSBvdXRwdXQgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIHRoZSByZXN1bHRpbmcgYnl0ZXMgaXMgbm90IGEgbXVsdGlwbGUgb2YgdGhlCisgICAgICogICAgICAgICAgICAgY2lwaGVyIGJsb2NrIHNpemUuCisgICAgICogQHRocm93cyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIHRoZSB7QGNvZGUgb3V0cHV0fSBidWZmZXIgaXMgdG9vIHNtYWxsLgorICAgICAqIEB0aHJvd3MgQmFkUGFkZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYWRkaW5nIG9mIHRoZSBkYXRhIGRvZXMgbm90IG1hdGNoIHRoZSBwYWRkaW5nIHNjaGVtZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2lwaGVyIGluc3RhbmNlIGlzIG5vdCBpbml0aWFsaXplZCBmb3IgZW5jcnlwdGlvbiBvcgorICAgICAqICAgICAgICAgICAgIGRlY3J5cHRpb24uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBkb0ZpbmFsKGJ5dGVbXSBvdXRwdXQsIGludCBvdXRwdXRPZmZzZXQpCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiwgU2hvcnRCdWZmZXJFeGNlcHRpb24sCisgICAgICAgICAgICBCYWRQYWRkaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG1vZGUgIT0gRU5DUllQVF9NT0RFICYmIG1vZGUgIT0gREVDUllQVF9NT0RFKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG91dHB1dE9mZnNldCA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm91dHB1dE9mZnNldCA8IDAiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVEb0ZpbmFsKG51bGwsIDAsIDAsIG91dHB1dCwgb3V0cHV0T2Zmc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5pc2hlcyBhIG11bHRpLXBhcnQgdHJhbnNmb3JtYXRpb24gKGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbikuCisgICAgICogPHA+CisgICAgICogUHJvY2Vzc2VzIHRoZSBieXRlcyBpbiB7QGNvZGUgaW5wdXR9IGJ1ZmZlciwgYW5kIGFueSBieXRlcyB0aGF0IGhhdmUgYmVlbgorICAgICAqIGJ1ZmZlcmVkIGluIHByZXZpb3VzIHtAY29kZSB1cGRhdGV9IGNhbGxzLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgYnVmZmVyLgorICAgICAqIEByZXR1cm4gdGhlIGZpbmFsIGJ5dGVzIGZyb20gdGhlIHRyYW5zZm9ybWF0aW9uLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIHRoZSByZXN1bHRpbmcgYnl0ZXMgaXMgbm90IGEgbXVsdGlwbGUgb2YgdGhlCisgICAgICogICAgICAgICAgICAgY2lwaGVyIGJsb2NrIHNpemUuCisgICAgICogQHRocm93cyBCYWRQYWRkaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBhZGRpbmcgb2YgdGhlIGRhdGEgZG9lcyBub3QgbWF0Y2ggdGhlIHBhZGRpbmcgc2NoZW1lLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaXBoZXIgaW5zdGFuY2UgaXMgbm90IGluaXRpYWxpemVkIGZvciBlbmNyeXB0aW9uIG9yCisgICAgICogICAgICAgICAgICAgZGVjcnlwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYnl0ZVtdIGRvRmluYWwoYnl0ZVtdIGlucHV0KSB0aHJvd3MgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEJhZFBhZGRpbmdFeGNlcHRpb24geworICAgICAgICBpZiAobW9kZSAhPSBFTkNSWVBUX01PREUgJiYgbW9kZSAhPSBERUNSWVBUX01PREUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVEb0ZpbmFsKGlucHV0LCAwLCBpbnB1dC5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmlzaGVzIGEgbXVsdGktcGFydCB0cmFuc2Zvcm1hdGlvbiAoZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uKS4KKyAgICAgKiA8cD4KKyAgICAgKiBQcm9jZXNzZXMgdGhlIHtAY29kZSBpbnB1dExlbn0gYnl0ZXMgaW4ge0Bjb2RlIGlucHV0fSBidWZmZXIgYXQge0Bjb2RlCisgICAgICogaW5wdXRPZmZzZXR9LCBhbmQgYW55IGJ5dGVzIHRoYXQgaGF2ZSBiZWVuIGJ1ZmZlcmVkIGluIHByZXZpb3VzIHtAY29kZQorICAgICAqIHVwZGF0ZX0gY2FsbHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBidWZmZXIuCisgICAgICogQHBhcmFtIGlucHV0T2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBpbnB1dCBidWZmZXIuCisgICAgICogQHBhcmFtIGlucHV0TGVuCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBpbnB1dAorICAgICAqIEByZXR1cm4gdGhlIGZpbmFsIGJ5dGVzIGZyb20gdGhlIHRyYW5zZm9ybWF0aW9uLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIHRoZSByZXN1bHRpbmcgYnl0ZXMgaXMgbm90IGEgbXVsdGlwbGUgb2YgdGhlCisgICAgICogICAgICAgICAgICAgY2lwaGVyIGJsb2NrIHNpemUuCisgICAgICogQHRocm93cyBCYWRQYWRkaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBhZGRpbmcgb2YgdGhlIGRhdGEgZG9lcyBub3QgbWF0Y2ggdGhlIHBhZGRpbmcgc2NoZW1lLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaXBoZXIgaW5zdGFuY2UgaXMgbm90IGluaXRpYWxpemVkIGZvciBlbmNyeXB0aW9uIG9yCisgICAgICogICAgICAgICAgICAgZGVjcnlwdGlvbi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBpbnB1dE9mZnNldH0gYW5kIHtAY29kZSBpbnB1dExlbn0gZG8gbm90IHNwZWNpZnkgYW4KKyAgICAgKiAgICAgICAgICAgICB2YWxpZCBjaHVuayBpbiB0aGUgaW5wdXQgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBieXRlW10gZG9GaW5hbChieXRlW10gaW5wdXQsIGludCBpbnB1dE9mZnNldCwgaW50IGlucHV0TGVuKQorICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24sIEJhZFBhZGRpbmdFeGNlcHRpb24geworICAgICAgICBpZiAobW9kZSAhPSBFTkNSWVBUX01PREUgJiYgbW9kZSAhPSBERUNSWVBUX01PREUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXRPZmZzZXQgPCAwIHx8IGlucHV0TGVuIDwgMCB8fCBpbnB1dE9mZnNldCArIGlucHV0TGVuID4gaW5wdXQubGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbmNvcnJlY3QgaW5wdXRPZmZzZXQvaW5wdXRMZW4gcGFyYW1ldGVycyIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZURvRmluYWwoaW5wdXQsIGlucHV0T2Zmc2V0LCBpbnB1dExlbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluaXNoZXMgYSBtdWx0aS1wYXJ0IHRyYW5zZm9ybWF0aW9uIChlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24pLgorICAgICAqIDxwPgorICAgICAqIFByb2Nlc3NlcyB0aGUge0Bjb2RlIGlucHV0TGVufSBieXRlcyBpbiB7QGNvZGUgaW5wdXR9IGJ1ZmZlciBhdCB7QGNvZGUKKyAgICAgKiBpbnB1dE9mZnNldH0sIGFuZCBhbnkgYnl0ZXMgdGhhdCBoYXZlIGJlZW4gYnVmZmVyZWQgaW4gcHJldmlvdXMge0Bjb2RlCisgICAgICogdXBkYXRlfSBjYWxscy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dAorICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IGJ1ZmZlci4KKyAgICAgKiBAcGFyYW0gaW5wdXRPZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIGlucHV0IGJ1ZmZlci4KKyAgICAgKiBAcGFyYW0gaW5wdXRMZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhlIGlucHV0LgorICAgICAqIEBwYXJhbSBvdXRwdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvdXRwdXQgYnVmZmVyIGZvciB0aGUgdHJhbnNmb3JtZWQgYnl0ZXMuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHBsYWNlZCBpbiB0aGUgb3V0cHV0IGJ1ZmZlci4KKyAgICAgKiBAdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNpemUgb2YgdGhlIHtAY29kZSBvdXRwdXR9IGJ1ZmZlciBpcyB0b28gc21hbGwuCisgICAgICogQHRocm93cyBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNpemUgb2YgdGhlIHJlc3VsdGluZyBieXRlcyBpcyBub3QgYSBtdWx0aXBsZSBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgICBjaXBoZXIgYmxvY2sgc2l6ZS4KKyAgICAgKiBAdGhyb3dzIEJhZFBhZGRpbmdFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFkZGluZyBvZiB0aGUgZGF0YSBkb2VzIG5vdCBtYXRjaCB0aGUgcGFkZGluZyBzY2hlbWUuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNpcGhlciBpbnN0YW5jZSBpcyBub3QgaW5pdGlhbGl6ZWQgZm9yIGVuY3J5cHRpb24gb3IKKyAgICAgKiAgICAgICAgICAgICBkZWNyeXB0aW9uLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGlucHV0T2Zmc2V0fSBhbmQge0Bjb2RlIGlucHV0TGVufSBkbyBub3Qgc3BlY2lmeSBhbgorICAgICAqICAgICAgICAgICAgIHZhbGlkIGNodW5rIGluIHRoZSBpbnB1dCBidWZmZXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBkb0ZpbmFsKGJ5dGVbXSBpbnB1dCwgaW50IGlucHV0T2Zmc2V0LCBpbnQgaW5wdXRMZW4sCisgICAgICAgICAgICBieXRlW10gb3V0cHV0KSB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uLCBCYWRQYWRkaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGRvRmluYWwoaW5wdXQsIGlucHV0T2Zmc2V0LCBpbnB1dExlbiwgb3V0cHV0LCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5pc2hlcyBhIG11bHRpLXBhcnQgdHJhbnNmb3JtYXRpb24gKGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbikuCisgICAgICogPHA+CisgICAgICogUHJvY2Vzc2VzIHRoZSB7QGNvZGUgaW5wdXRMZW59IGJ5dGVzIGluIHtAY29kZSBpbnB1dH0gYnVmZmVyIGF0IHtAY29kZQorICAgICAqIGlucHV0T2Zmc2V0fSwgYW5kIGFueSBieXRlcyB0aGF0IGhhdmUgYmVlbiBidWZmZXJlZCBpbiBwcmV2aW91cyB7QGNvZGUKKyAgICAgKiB1cGRhdGV9IGNhbGxzLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgYnVmZmVyLgorICAgICAqIEBwYXJhbSBpbnB1dE9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgaW5wdXQgYnVmZmVyLgorICAgICAqIEBwYXJhbSBpbnB1dExlbgorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgaW5wdXQuCisgICAgICogQHBhcmFtIG91dHB1dAorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBidWZmZXIgZm9yIHRoZSB0cmFuc2Zvcm1lZCBieXRlcy4KKyAgICAgKiBAcGFyYW0gb3V0cHV0T2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBvdXRwdXQgYnVmZmVyLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBwbGFjZWQgaW4gdGhlIG91dHB1dCBidWZmZXIuCisgICAgICogQHRocm93cyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIHRoZSB7QGNvZGUgb3V0cHV0fSBidWZmZXIgaXMgdG9vIHNtYWxsLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIHRoZSByZXN1bHRpbmcgYnl0ZXMgaXMgbm90IGEgbXVsdGlwbGUgb2YgdGhlCisgICAgICogICAgICAgICAgICAgY2lwaGVyIGJsb2NrIHNpemUuCisgICAgICogQHRocm93cyBCYWRQYWRkaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBhZGRpbmcgb2YgdGhlIGRhdGEgZG9lcyBub3QgbWF0Y2ggdGhlIHBhZGRpbmcgc2NoZW1lLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBjaXBoZXIgaW5zdGFuY2UgaXMgbm90IGluaXRpYWxpemVkIGZvciBlbmNyeXB0aW9uIG9yCisgICAgICogICAgICAgICAgICAgZGVjcnlwdGlvbi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBpbnB1dE9mZnNldH0gYW5kIHtAY29kZSBpbnB1dExlbn0gZG8gbm90IHNwZWNpZnkgYW4KKyAgICAgKiAgICAgICAgICAgICB2YWxpZCBjaHVuayBpbiB0aGUgaW5wdXQgYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZG9GaW5hbChieXRlW10gaW5wdXQsIGludCBpbnB1dE9mZnNldCwgaW50IGlucHV0TGVuLAorICAgICAgICAgICAgYnl0ZVtdIG91dHB1dCwgaW50IG91dHB1dE9mZnNldCkgdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiwgQmFkUGFkZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChtb2RlICE9IEVOQ1JZUFRfTU9ERSAmJiBtb2RlICE9IERFQ1JZUFRfTU9ERSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dE9mZnNldCA8IDAgfHwgaW5wdXRMZW4gPCAwIHx8IGlucHV0T2Zmc2V0ICsgaW5wdXRMZW4gPiBpbnB1dC5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkluY29ycmVjdCBpbnB1dE9mZnNldC9pbnB1dExlbiBwYXJhbWV0ZXJzIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lRG9GaW5hbChpbnB1dCwgaW5wdXRPZmZzZXQsIGlucHV0TGVuLCBvdXRwdXQsCisgICAgICAgICAgICAgICAgb3V0cHV0T2Zmc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5pc2hlcyBhIG11bHRpLXBhcnQgdHJhbnNmb3JtYXRpb24gKGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbikuCisgICAgICogPHA+CisgICAgICogUHJvY2Vzc2VzIHRoZSB7QGNvZGUgaW5wdXQucmVtYWluaW5nKCl9IGJ5dGVzIGluIHtAY29kZSBpbnB1dH0gYnVmZmVyIGF0CisgICAgICoge0Bjb2RlIGlucHV0LnBvc2l0aW9uKCl9LCBhbmQgYW55IGJ5dGVzIHRoYXQgaGF2ZSBiZWVuIGJ1ZmZlcmVkIGluCisgICAgICogcHJldmlvdXMge0Bjb2RlIHVwZGF0ZX0gY2FsbHMuIFRoZSB0cmFuc2Zvcm1lZCBieXRlcyBhcmUgcGxhY2VkIGludG8KKyAgICAgKiB7QGNvZGUgb3V0cHV0fSBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBidWZmZXIuCisgICAgICogQHBhcmFtIG91dHB1dAorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBidWZmZXIuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHBsYWNlZCBpbnRvIHRoZSBvdXRwdXQgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2l6ZSBvZiB0aGUge0Bjb2RlIG91dHB1dH0gYnVmZmVyIGlzIHRvbyBzbWFsbC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2l6ZSBvZiB0aGUgcmVzdWx0aW5nIGJ5dGVzIGlzIG5vdCBhIG11bHRpcGxlIG9mIHRoZQorICAgICAqICAgICAgICAgICAgIGNpcGhlciBibG9jayBzaXplLgorICAgICAqIEB0aHJvd3MgQmFkUGFkZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYWRkaW5nIG9mIHRoZSBkYXRhIGRvZXMgbm90IG1hdGNoIHRoZSBwYWRkaW5nIHNjaGVtZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBpbnB1dCBidWZmZXIgYW5kIHRoZSBvdXRwdXQgYnVmZmVyIGFyZSB0aGUgc2FtZQorICAgICAqICAgICAgICAgICAgIG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2lwaGVyIGluc3RhbmNlIGlzIG5vdCBpbml0aWFsaXplZCBmb3IgZW5jcnlwdGlvbiBvcgorICAgICAqICAgICAgICAgICAgIGRlY3J5cHRpb24uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBkb0ZpbmFsKEJ5dGVCdWZmZXIgaW5wdXQsIEJ5dGVCdWZmZXIgb3V0cHV0KQorICAgICAgICAgICAgdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uLCBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uLAorICAgICAgICAgICAgQmFkUGFkZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChtb2RlICE9IEVOQ1JZUFRfTU9ERSAmJiBtb2RlICE9IERFQ1JZUFRfTU9ERSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dCA9PSBvdXRwdXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImlucHV0ID09IG91dHB1dCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZURvRmluYWwoaW5wdXQsIG91dHB1dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JhcHMgYSBrZXkgdXNpbmcgdGhpcyBjaXBoZXIgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IHRvIHdyYXAuCisgICAgICogQHJldHVybiB0aGUgd3JhcHBlZCBrZXkuCisgICAgICogQHRocm93cyBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNpemUgb2YgdGhlIHJlc3VsdGluZyBieXRlcyBpcyBub3QgYSBtdWx0aXBsZSBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgICBjaXBoZXIgYmxvY2sgc2l6ZS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNpcGhlciBpbnN0YW5jZSBjYW4gbm90IHdyYXAgdGhpcyBrZXkuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNpcGhlciBpbnN0YW5jZSBpcyBub3QgaW5pdGlhbGl6ZWQgZm9yIHdyYXBwaW5nLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBieXRlW10gd3JhcChLZXkga2V5KSB0aHJvd3MgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICBpZiAobW9kZSAhPSBXUkFQX01PREUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVXcmFwKGtleSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVW53cmFwcyBhIGtleSB1c2luZyB0aGlzIGNpcGhlciBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB3cmFwcGVkS2V5CisgICAgICogICAgICAgICAgICB0aGUgd3JhcHBlZCBrZXkgdG8gdW53cmFwLgorICAgICAqIEBwYXJhbSB3cmFwcGVkS2V5QWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgYWxnb3JpdGhtIGZvciB0aGUgd3JhcHBlZCBrZXkuCisgICAgICogQHBhcmFtIHdyYXBwZWRLZXlUeXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgd3JhcHBlZCBrZXkgKG9uZSBvZjoge0Bjb2RlIFNFQ1JFVF9LRVkKKyAgICAgKiAgICAgICAgICAgIDxjb2RlPiwgPGNvZGU+UFJJVkFURV9LRVl9IG9yIHtAY29kZSBQVUJMSUNfS0VZfSkKKyAgICAgKiBAcmV0dXJuIHRoZSB1bndyYXBwZWQga2V5CisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSB3cmFwcGVkS2V5fSBjYW4gbm90IGJlIHVud3JhcHBlZCB0byBhIGtleSBvZgorICAgICAqICAgICAgICAgICAgIHR5cGUge0Bjb2RlIHdyYXBwZWRLZXlUeXBlfSBmb3IgdGhlIHtAY29kZQorICAgICAqICAgICAgICAgICAgIHdyYXBwZWRLZXlBbGdvcml0aG19LgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgbm8gcHJvdmlkZXIgY2FuIGJlIGZvdW5kIHRoYXQgY2FuIGNyZWF0ZSBhIGtleSBvZiB0eXBlCisgICAgICogICAgICAgICAgICAge0Bjb2RlIHdyYXBwZWRLZXlUeXBlfSBmb3IgdGhlIHtAY29kZSB3cmFwcGVkS2V5QWxnb3JpdGhtfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2lwaGVyIGluc3RhbmNlIGlzIG5vdCBpbml0aWFsaXplZCBmb3IgdW53cmFwcGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgS2V5IHVud3JhcChieXRlW10gd3JhcHBlZEtleSwgU3RyaW5nIHdyYXBwZWRLZXlBbGdvcml0aG0sCisgICAgICAgICAgICBpbnQgd3JhcHBlZEtleVR5cGUpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG1vZGUgIT0gVU5XUkFQX01PREUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVVbndyYXAod3JhcHBlZEtleSwgd3JhcHBlZEtleUFsZ29yaXRobSwKKyAgICAgICAgICAgICAgICB3cmFwcGVkS2V5VHlwZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbWF4aW11bSBrZXkgbGVuZ3RoIGZvciB0aGUgc3BlY2lmaWVkIHRyYW5zZm9ybWF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHRyYW5zZm9ybWF0aW9uCisgICAgICogICAgICAgICAgICB0aGUgdHJhbnNmb3JtYXRpb24gbmFtZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIGtleSBsZW5ndGgsIGN1cnJlbnRseSB7QGNvZGUgSW50ZWdlci5NQVhfVkFMVUV9LgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgbm8gcHJvdmlkZXIgZm9yIHRoZSBzcGVjaWZpZWQge0Bjb2RlIHRyYW5zZm9ybWF0aW9ufSBjYW4KKyAgICAgKiAgICAgICAgICAgICBiZSBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHRyYW5zZm9ybWF0aW9ufSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgZ2V0TWF4QWxsb3dlZEtleUxlbmd0aChTdHJpbmcgdHJhbnNmb3JtYXRpb24pCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRyYW5zZm9ybWF0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGNoZWNrVHJhbnNmb3JtYXRpb24odHJhbnNmb3JtYXRpb24pOworICAgICAgICAvL0ZJWE1FIGp1cmlzZGljdGlvbiBwb2xpY3kgZmlsZXMKKyAgICAgICAgcmV0dXJuIEludGVnZXIuTUFYX1ZBTFVFOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1heGltdW0gY2lwaGVyIHBhcmFtZXRlciB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZAorICAgICAqIHRyYW5zZm9ybWF0aW9uLiBJZiB0aGVyZSBpcyBubyBtYXhpbXVtIGxpbWl0LCB7QGNvZGUgbnVsbH0gaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHJhbnNmb3JtYXRpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSB0cmFuc2Zvcm1hdGlvbiBuYW1lLgorICAgICAqIEByZXR1cm4gYSBwYXJhbWV0ZXIgc3BlYyBob2xkaW5nIHRoZSBtYXhpbXVtIHZhbHVlIG9yIHtAY29kZSBudWxsfS4KKyAgICAgKiAgICAgICAgIEN1cnJlbnRseSB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBwcm92aWRlciBmb3IgdGhlIHNwZWNpZmllZCB7QGNvZGUgdHJhbnNmb3JtYXRpb259IGNhbgorICAgICAqICAgICAgICAgICAgIGJlIGZvdW5kLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgdHJhbnNmb3JtYXRpb259IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgZ2V0TWF4QWxsb3dlZFBhcmFtZXRlclNwZWMoCisgICAgICAgICAgICBTdHJpbmcgdHJhbnNmb3JtYXRpb24pIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAodHJhbnNmb3JtYXRpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tUcmFuc2Zvcm1hdGlvbih0cmFuc2Zvcm1hdGlvbik7CisgICAgICAgIC8vRklYTUUganVyaXNkaWN0aW9uIHBvbGljeSBmaWxlcworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL0NpcGhlcklucHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL0NpcGhlcklucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGRlMzdkYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vQ2lwaGVySW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDE4NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbjsKK2ltcG9ydCBsaWJjb3JlLmlvLlN0cmVhbXM7CisKKy8qKgorICogVGhpcyBjbGFzcyB3cmFwcyBhbiB7QGNvZGUgSW5wdXRTdHJlYW19IGFuZCBhIGNpcGhlciBzbyB0aGF0IHtAY29kZSByZWFkKCl9CisgKiBtZXRob2RzIHJldHVybiBkYXRhIHRoYXQgYXJlIHJlYWQgZnJvbSB0aGUgdW5kZXJseWluZyB7QGNvZGUgSW5wdXRTdHJlYW19IGFuZAorICogcHJvY2Vzc2VkIGJ5IHRoZSBjaXBoZXIuCisgKiA8cD4KKyAqIFRoZSBjaXBoZXIgbXVzdCBiZSBpbml0aWFsaXplZCBmb3IgdGhlIHJlcXVlc3RlZCBvcGVyYXRpb24gYmVmb3JlIGJlaW5nIHVzZWQKKyAqIGJ5IGEge0Bjb2RlIENpcGhlcklucHV0U3RyZWFtfS4gRm9yIGV4YW1wbGUsIGlmIGEgY2lwaGVyIGluaXRpYWxpemVkIGZvcgorICogZGVjcnlwdGlvbiBpcyB1c2VkIHdpdGggYSB7QGNvZGUgQ2lwaGVySW5wdXRTdHJlYW19LCB0aGUge0Bjb2RlCisgKiBDaXBoZXJJbnB1dFN0cmVhbX0gdHJpZXMgdG8gcmVhZCB0aGUgZGF0YSBhbiBkZWNyeXB0IHRoZW0gYmVmb3JlIHJldHVybmluZy4KKyAqLworcHVibGljIGNsYXNzIENpcGhlcklucHV0U3RyZWFtIGV4dGVuZHMgRmlsdGVySW5wdXRTdHJlYW0geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElfQlVGRkVSX1NJWkUgPSAyMDsKKworICAgIHByaXZhdGUgZmluYWwgQ2lwaGVyIGNpcGhlcjsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBpbnB1dEJ1ZmZlciA9IG5ldyBieXRlW0lfQlVGRkVSX1NJWkVdOworICAgIHByaXZhdGUgaW50IGluZGV4OyAvLyBpbmRleCBvZiB0aGUgYnl0ZXMgdG8gcmV0dXJuIGZyb20gb3V0cHV0QnVmZmVyCisgICAgcHJpdmF0ZSBieXRlW10gb3V0cHV0QnVmZmVyOworICAgIHByaXZhdGUgYm9vbGVhbiBmaW5pc2hlZDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENpcGhlcklucHV0U3RyZWFtfSBpbnN0YW5jZSBmb3IgYW4ge0Bjb2RlCisgICAgICogSW5wdXRTdHJlYW19IGFuZCBhIGNpcGhlci4KKyAgICAgKgorICAgICAqIDxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gcGFzc2luZyBhIG51bGwgc291cmNlIGNyZWF0ZXMgYW4gaW52YWxpZAorICAgICAqIHtAY29kZSBDaXBoZXJJbnB1dFN0cmVhbX0uIEFsbCByZWFkIG9wZXJhdGlvbnMgb24gc3VjaCBhIHN0cmVhbSB3aWxsCisgICAgICogZmFpbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpcworICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IHN0cmVhbSB0byByZWFkIGRhdGEgZnJvbS4KKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGNpcGhlciB0byBwcm9jZXNzIHRoZSBkYXRhIHdpdGguCisgICAgICovCisgICAgcHVibGljIENpcGhlcklucHV0U3RyZWFtKElucHV0U3RyZWFtIGlzLCBDaXBoZXIgYykgeworICAgICAgICBzdXBlcihpcyk7CisgICAgICAgIHRoaXMuY2lwaGVyID0gYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDaXBoZXJJbnB1dFN0cmVhbX0gaW5zdGFuY2UgZm9yIGFuIHtAY29kZQorICAgICAqIElucHV0U3RyZWFtfSB3aXRob3V0IGEgY2lwaGVyLgorICAgICAqIDxwPgorICAgICAqIEEge0Bjb2RlIE51bGxDaXBoZXJ9IGlzIGNyZWF0ZWQgYW5kIHVzZWQgdG8gcHJvY2VzcyB0aGUgZGF0YS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpcworICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IHN0cmVhbSB0byByZWFkIGRhdGEgZnJvbS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ2lwaGVySW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaXMpIHsKKyAgICAgICAgdGhpcyhpcywgbmV3IE51bGxDaXBoZXIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIG5leHQgYnl0ZSBmcm9tIHRoaXMgY2lwaGVyIGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgYnl0ZSwgb3Ige0Bjb2RlIC0xfSBpZiB0aGUgZW5kIG9mIHRoZSBzdHJlYW0gaXMgcmVhY2hlZC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChmaW5pc2hlZCkgeworICAgICAgICAgICAgcmV0dXJuICgob3V0cHV0QnVmZmVyID09IG51bGwpIHx8IChpbmRleCA9PSBvdXRwdXRCdWZmZXIubGVuZ3RoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IC0xCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBvdXRwdXRCdWZmZXJbaW5kZXgrK10gJiAweEZGOworICAgICAgICB9CisgICAgICAgIGlmICgob3V0cHV0QnVmZmVyICE9IG51bGwpICYmIChpbmRleCA8IG91dHB1dEJ1ZmZlci5sZW5ndGgpKSB7CisgICAgICAgICAgICByZXR1cm4gb3V0cHV0QnVmZmVyW2luZGV4KytdICYgMHhGRjsKKyAgICAgICAgfQorICAgICAgICBpbmRleCA9IDA7CisgICAgICAgIG91dHB1dEJ1ZmZlciA9IG51bGw7CisgICAgICAgIGludCBieXRlQ291bnQ7CisgICAgICAgIHdoaWxlIChvdXRwdXRCdWZmZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKChieXRlQ291bnQgPSBpbi5yZWFkKGlucHV0QnVmZmVyKSkgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBvdXRwdXRCdWZmZXIgPSBjaXBoZXIuZG9GaW5hbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZpbmlzaGVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG91dHB1dEJ1ZmZlciA9IGNpcGhlci51cGRhdGUoaW5wdXRCdWZmZXIsIDAsIGJ5dGVDb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlYWQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB0aGUgbmV4dCB7QGNvZGUgbGVufSBieXRlcyBmcm9tIHRoaXMgaW5wdXQgc3RyZWFtIGludG8gYnVmZmVyCisgICAgICoge0Bjb2RlIGJ1Zn0gc3RhcnRpbmcgYXQgb2Zmc2V0IHtAY29kZSBvZmZ9LgorICAgICAqIDxwPgorICAgICAqIGlmIHtAY29kZSBifSBpcyB7QGNvZGUgbnVsbH0sIHRoZSBuZXh0IHtAY29kZSBsZW59IGJ5dGVzIGFyZSByZWFkIGFuZAorICAgICAqIGRpc2NhcmRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBmaWxsZWQgaW50byBidWZmZXIge0Bjb2RlIGJ9LCBvciB7QGNvZGUgLTF9CisgICAgICogICAgICAgICBvZiB0aGUgb2YgdGhlIHN0cmVhbSBpcyByZWFjaGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB1bmRlcmx5aW5nIGlucHV0IHN0cmVhbSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGJ5dGVbXSBidWYsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpbiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIlVuZGVybHlpbmcgaW5wdXQgc3RyZWFtIGlzIG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyArK2kpIHsKKyAgICAgICAgICAgIGludCBiID0gcmVhZCgpOworICAgICAgICAgICAgaWYgKGIgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gKGkgPT0gMCkgPyAtMSA6IGk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYnVmICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBidWZbb2ZmK2ldID0gKGJ5dGUpIGI7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgc2tpcChsb25nIGJ5dGVDb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIFN0cmVhbXMuc2tpcEJ5UmVhZGluZyh0aGlzLCBieXRlQ291bnQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMge0Bjb2RlIENpcGhlcklucHV0U3RyZWFtfSwgYWxzbyBjbG9zZXMgdGhlIHVuZGVybHlpbmcgaW5wdXQKKyAgICAgKiBzdHJlYW0gYW5kIGNhbGwge0Bjb2RlIGRvRmluYWx9IG9uIHRoZSBjaXBoZXIgb2JqZWN0LgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaXBoZXIuZG9GaW5hbCgpOworICAgICAgICB9IGNhdGNoIChHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgICAgICAvL2RvIGxpa2UgUkkgZG9lcworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBpbnB1dCBzdHJlYW0gc3VwcG9ydHMge0Bjb2RlIG1hcmt9IGFuZAorICAgICAqIHtAY29kZSByZXNldH0sIHdoaWNoIGl0IGRvZXMgbm90LgorICAgICAqCisgICAgICogQHJldHVybiBmYWxzZSwgc2luY2UgdGhpcyBpbnB1dCBzdHJlYW0gZG9lcyBub3Qgc3VwcG9ydCB7QGNvZGUgbWFya30gYW5kCisgICAgICogICAgICAgICB7QGNvZGUgcmVzZXR9LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hcmtTdXBwb3J0ZWQoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL0NpcGhlck91dHB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9DaXBoZXJPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMWY2NDI5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9DaXBoZXJPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDE0NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLmlvLkZpbHRlck91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGxpYmNvcmUuaW8uU3RyZWFtczsKKworLyoqCisgKiBUaGlzIGNsYXNzIHdyYXBzIGFuIG91dHB1dCBzdHJlYW0gYW5kIGEgY2lwaGVyIHNvIHRoYXQge0Bjb2RlIHdyaXRlfSBtZXRob2RzCisgKiBzZW5kIHRoZSBkYXRhIHRocm91Z2ggdGhlIGNpcGhlciBiZWZvcmUgd3JpdGluZyB0aGVtIHRvIHRoZSB1bmRlcmx5aW5nIG91dHB1dAorICogc3RyZWFtLgorICogPHA+CisgKiBUaGUgY2lwaGVyIG11c3QgYmUgaW5pdGlhbGl6ZWQgZm9yIHRoZSByZXF1ZXN0ZWQgb3BlcmF0aW9uIGJlZm9yZSBiZWluZyB1c2VkCisgKiBieSBhIHtAY29kZSBDaXBoZXJPdXRwdXRTdHJlYW19LiBGb3IgZXhhbXBsZSwgaWYgYSBjaXBoZXIgaW5pdGlhbGl6ZWQgZm9yCisgKiBlbmNyeXB0aW9uIGlzIHVzZWQgd2l0aCBhIHtAY29kZSBDaXBoZXJPdXRwdXRTdHJlYW19LCB0aGUge0Bjb2RlCisgKiBDaXBoZXJPdXRwdXRTdHJlYW19IHRyaWVzIHRvIGVuY3J5cHQgdGhlIGRhdGEgd3JpdGluZyBpdCBvdXQuCisgKi8KK3B1YmxpYyBjbGFzcyBDaXBoZXJPdXRwdXRTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJPdXRwdXRTdHJlYW0geworCisgICAgcHJpdmF0ZSBmaW5hbCBDaXBoZXIgY2lwaGVyOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2lwaGVyT3V0cHV0U3RyZWFtfSBpbnN0YW5jZSBmb3IgYW4ge0Bjb2RlCisgICAgICogT3V0cHV0U3RyZWFtfSBhbmQgYSB7QGNvZGUgQ2lwaGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcworICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBzdHJlYW0gdG8gd3JpdGUgZGF0YSB0by4KKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIGNpcGhlciB0byBwcm9jZXNzIHRoZSBkYXRhIHdpdGguCisgICAgICovCisgICAgcHVibGljIENpcGhlck91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3MsIENpcGhlciBjKSB7CisgICAgICAgIHN1cGVyKG9zKTsKKyAgICAgICAgY2lwaGVyID0gYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDaXBoZXJPdXRwdXRTdHJlYW19IGluc3RhbmNlIGZvciBhbiB7QGNvZGUKKyAgICAgKiBPdXRwdXRTdHJlYW19IHdpdGhvdXQgYSBjaXBoZXIuCisgICAgICogPHA+CisgICAgICogQSB7QGNvZGUgTnVsbENpcGhlcn0gaXMgY3JlYXRlZCB0byBwcm9jZXNzIHRoZSBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIG9zCisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IHN0cmVhbSB0byB3cml0ZSB0aGUgZGF0YSB0by4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ2lwaGVyT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvcykgeworICAgICAgICB0aGlzKG9zLCBuZXcgTnVsbENpcGhlcigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIHNpbmdsZSBieXRlIHRvIHRoaXMgY2lwaGVyIG91dHB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgdG8gd3JpdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmVhbXMud3JpdGVTaW5nbGVCeXRlKHRoaXMsIGIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUge0Bjb2RlIGxlbn0gYnl0ZXMgZnJvbSBidWZmZXIge0Bjb2RlIGJ9IHN0YXJ0aW5nIGF0IG9mZnNldAorICAgICAqIHtAY29kZSBvZmZ9IHRvIHRoaXMgY2lwaGVyIG91dHB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYgorICAgICAqICAgICAgICAgICAgdGhlIGJ1ZmZlci4KKyAgICAgKiBAcGFyYW0gb2ZmCisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IHRvIHN0YXJ0IGF0LgorICAgICAqIEBwYXJhbSBsZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChsZW4gPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBjaXBoZXIudXBkYXRlKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7CisgICAgICAgICAgICBvdXQud3JpdGUocmVzdWx0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZsdXNoZXMgdGhpcyBjaXBoZXIgb3V0cHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC5mbHVzaCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlIHRoaXMgY2lwaGVyIG91dHB1dCBzdHJlYW0uCisgICAgICogPHA+CisgICAgICogT24gdGhlIHVuZGVybHlpbmcgY2lwaGVyIHtAY29kZSBkb0ZpbmFsfSB3aWxsIGJlIGludm9rZWQsIGFuZCBhbnkKKyAgICAgKiBidWZmZXJlZCBieXRlcyBmcm9tIHRoZSBjaXBoZXIgYXJlIGFsc28gd3JpdHRlbiBvdXQsIGFuZCB0aGUgY2lwaGVyIGlzCisgICAgICogcmVzZXQgdG8gaXRzIGluaXRpYWwgc3RhdGUuIFRoZSB1bmRlcmx5aW5nIG91dHB1dCBzdHJlYW0gaXMgYWxzbyBjbG9zZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIHJlc3VsdDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChjaXBoZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNpcGhlci5kb0ZpbmFsKCk7CisgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIG91dC53cml0ZShyZXN1bHQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChCYWRQYWRkaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9DaXBoZXJTcGkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vQ2lwaGVyU3BpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWY5MWJhOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vQ2lwaGVyU3BpLmphdmEKQEAgLTAsMCArMSw1NTMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguY3J5cHRvOworCitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKKworLyoqCisgKiBUaGlzIGNsYXNzIGRlZmluZXMgdGhlIDxpPlNlcnZpY2UgUHJvdmlkZXIgSW50ZXJmYWNlPC9pPiAoPGI+U1BJPC9iPikgZm9yCisgKiBjcnlwdG9ncmFwaGljIGNpcGhlcnMuCisgKiA8cD4KKyAqIEltcGxlbWVudGVycyBvZiBjcnlwdG9ncmFwaGljIGNpcGhlcnMgbXVzdCBpbXBsZW1lbnQgYWxsIHRoZSBhYnN0cmFjdCBtZXRob2RzCisgKiBmb3IgZXZlcnkgY2lwaGVyIHRoZXkgaW1wbGVtZW50LiB7QGNvZGUgQ2lwaGVyU3BpfSBpbnN0YW5jZXMgYXJlIGNyZWF0ZWQKKyAqIGFsb25nIHdpdGggY2lwaGVycyB3aGVuIHRoZSB7QGxpbmsgQ2lwaGVyI2dldEluc3RhbmNlfSBtZXRob2QgaXMgY2FsbGVkLiBBCisgKiB7QGNvZGUgQ2lwaGVyfSBpcyByZWZlcmVuY2VkIGJ5IGEgPGk+dHJhbnNmb3JtYXRpb248L2k+LCB3aGljaCBpcyBhIHN0cmluZworICogdGhhdCBkZXNjcmliZXMgdGhlIG9wZXJhdGlvbiAob3Igc2V0IG9mIG9wZXJhdGlvbnMpLCBhbHdheXMgY29uc2lzdGluZyBvZiB0aGUKKyAqIGNpcGhlcidzIG5hbWUgYW5kIG9wdGlvbmFsbHkgZm9sbG93ZWQgYnkgYSBtb2RlIGFuZCBhIHBhZGRpbmcsIGluIHRoZSBmb3JtOgorICogPHVsPgorICogPGxpPiJhbGdvcml0aG0iPC9saT5vcgorICogPGxpPiJhbGdvcml0aG0vbW9kZS9wYWRkaW5nIjwvbGk+CisgKiA8L3VsPgorICogVGhlIGZvbGxvd2luZyBiZWhhdmlvciBzaG91bGQgYmUgaW1wbGVtZW50ZWQgZm9yIG9idGFpbmluZyB7QGNvZGUgQ2lwaGVyfQorICogaW5zdGFuY2VzLgorICogPHA+CisgKiBXaGVuIG9uZSBvZiB0aGUge0BsaW5rIENpcGhlciNnZXRJbnN0YW5jZX0gZmFjdG9yeSBtZXRob2RzIGlzIGNhbGxlZCB3aXRoIGEKKyAqIDxpPnRyYW5zZm9ybWF0aW9uPC9pPiB0aGF0IGlzIG9ubHkgYW4gPGk+YWxnb3JpdGhtPC9pPiwgY2hlY2sgaWYgdGhlIHByb3ZpZGVyCisgKiBkZWZpbmVzIGEge0Bjb2RlIENpcGhlclNwaX0gZm9yICJhbGdvcml0aG0iLCBpZiBzbzogcmV0dXJuIGl0LCBvdGhlcndpc2UKKyAqIHRocm93IGEge0BsaW5rIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbn0uCisgKiA8cD4KKyAqIFRoZSBmb2xsb3dpbmcgcnVsZXMgYXBwbHkgd2hlbiBhIDxpPnRyYW5zZm9ybWF0aW9uPC9pPiBpcyBvZiB0aGUgZm9ybQorICogImFsZ29yaXRobS9tb2RlL3BhZGRpbmciOgorICogPHVsPgorICogMS4gVGhlIFByb3ZpZGVyIGhhcyBhIHtAY29kZSBDaXBoZXJTcGl9IHN1YmNsYXNzIHJlZ2lzdGVyZWQgZm9yCisgKiAiYWxnb3JpdGhtL21vZGUvcGFkZGluZyI6IHJldHVybiBpdCwgb3RoZXJ3aXNlIGdvIHRvIHN0ZXAgMi4KKyAqIDwvdWw+CisgKiA8dWw+CisgKiAyLiBUaGUgUHJvdmlkZXIgaGFzIGEge0Bjb2RlIENpcGhlclNwaX0gc3ViY2xhc3MgcmVnaXN0ZXJlZCBmb3IKKyAqICJhbGdvcml0aG0vbW9kZSI6IGluc3RhbnRpYXRlIGl0LCBjYWxsCisgKiB7QGxpbmsgQ2lwaGVyU3BpI2VuZ2luZVNldFBhZGRpbmcoU3RyaW5nKSBlbmdpbmVTZXRQYWRkaW5nKFN0cmluZyl9IGZvciB0aGUKKyAqIHBhZGRpbmcgbmFtZSBhbmQgcmV0dXJuIGl0LCBvdGhlcndpc2UgZ28gdG8gc3RlcCAzLgorICogPC91bD4KKyAqIDx1bD4KKyAqIDMuIFRoZSBQcm92aWRlciBoYXMgYSB7QGNvZGUgQ2lwaGVyU3BpfSBzdWJjbGFzcyByZWdpc3RlcmVkIGZvcgorICogImFsZ29yaXRobS8vcGFkZGluZyI6IGluc3RhbnRpYXRlIGl0LCBjYWxsCisgKiB7QGxpbmsgQ2lwaGVyU3BpI2VuZ2luZVNldE1vZGUoU3RyaW5nKSBlbmdpbmVTZXRNb2RlKFN0cmluZyl9IGZvciB0aGUgbW9kZQorICogbmFtZSBhbmQgcmV0dXJuIGl0LCBvdGhlcndpc2UgZ28gdG8gc3RlcCA0LgorICogPC91bD4KKyAqIDx1bD4KKyAqIDQuIFRoZSBQcm92aWRlciBoYXMgYSB7QGNvZGUgQ2lwaGVyU3BpfSBzdWJjbGFzcyByZWdpc3RlcmVkIGZvciAiYWxnb3JpdGhtIjoKKyAqIGluc3RhbnRpYXRlIGl0LCBjYWxsIHtAbGluayBDaXBoZXJTcGkjZW5naW5lU2V0TW9kZShTdHJpbmcpCisgKiBlbmdpbmVTZXRNb2RlKFN0cmluZyl9IGZvciB0aGUgbW9kZSBuYW1lICwgY2FsbAorICoge0BsaW5rIENpcGhlclNwaSNlbmdpbmVTZXRQYWRkaW5nKFN0cmluZykgZW5naW5lU2V0UGFkZGluZyhTdHJpbmcpfSBmb3IgdGhlCisgKiBwYWRkaW5nIG5hbWUgYW5kIHJldHVybiBpdCwgb3RoZXJ3aXNlIHRocm93IGEKKyAqIHtAbGluayBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb259LgorICogPC91bD4KKyAqCisgKiBAc2VlIENpcGhlcgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ2lwaGVyU3BpIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENpcGhlclNwaX0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIENpcGhlclNwaSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBtb2RlIGZvciB0aGlzIGNpcGhlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb2RlCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgY2lwaGVyIG1vZGUuCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGNpcGhlciBtb2RlIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcworICAgICAqICAgICAgICAgICAgIHByb3ZpZGVyLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGVuZ2luZVNldE1vZGUoU3RyaW5nIG1vZGUpCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcGFkZGluZyBtZXRob2QgZm9yIHRoaXMgY2lwaGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHBhZGRpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBwYWRkaW5nIG1ldGhvZC4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaFBhZGRpbmdFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHBhZGRpbmcgbWV0aG9kIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcworICAgICAqICAgICAgICAgICAgIGNpcGhlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBlbmdpbmVTZXRQYWRkaW5nKFN0cmluZyBwYWRkaW5nKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaFBhZGRpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBibG9jayBzaXplIG9mIHRoaXMgY2lwaGVyIChpbiBieXRlcykKKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJsb2NrIHNpemUgb2YgdGhpcyBjaXBoZXIsIG9yIHplcm8gaWYgdGhpcyBjaXBoZXIgaXMgbm90IGEKKyAgICAgKiAgICAgICAgIGJsb2NrIGNpcGhlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW50IGVuZ2luZUdldEJsb2NrU2l6ZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2l6ZSBmb3IgYSBidWZmZXIgKGluIGJ5dGVzKSwgdGhhdCB0aGUgbmV4dCBjYWxsIHRvIHtAY29kZQorICAgICAqIHVwZGF0ZX0gb2Yge0Bjb2RlIGRvRmluYWx9IHdvdWxkIHJldHVybiwgdGFraW5nIGludG8gYWNjb3VudCBhbnkgYnVmZmVyZWQKKyAgICAgKiBkYXRhIGZyb20gcHJldmlvdXMge0Bjb2RlIHVwZGF0ZX0gY2FsbHMgYW5kIHBhZGRpbmcuCisgICAgICogPHA+CisgICAgICogVGhlIGFjdHVhbCBvdXRwdXQgbGVuZ3RoIG9mIHRoZSBuZXh0IGNhbGwgdG8ge0Bjb2RlIHVwZGF0ZX0gb3Ige0Bjb2RlCisgICAgICogZG9GaW5hbH0gbWF5IGJlIHNtYWxsZXIgdGhhbiB0aGUgbGVuZ3RoIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0TGVuCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBpbnB1dCAoaW4gYnl0ZXMpLgorICAgICAqIEByZXR1cm4gdGhlIHNpemUgZm9yIGEgYnVmZmVyIChpbiBieXRlcykuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IGludCBlbmdpbmVHZXRPdXRwdXRTaXplKGludCBpbnB1dExlbik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBJbml0aWFsaXphdGlvbiBWZWN0b3IgKElWKSB0aGF0IHdhcyB1c2VkIHRvIGluaXRpYWxpemUgdGhpcworICAgICAqIGNpcGhlciBvciB7QGNvZGUgbnVsbH0gaWYgbm9uZSB3YXMgdXNlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIEluaXRpYWxpemF0aW9uIFZlY3RvciAoSVYpLCBvciB7QGNvZGUgbnVsbH0gaWYgbm9uZSB3YXMgdXNlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgYnl0ZVtdIGVuZ2luZUdldElWKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwYXJhbWV0ZXJzIHRoYXQgd2hlcmUgdXNlZCB0byBjcmVhdGUgdGhpcyBjaXBoZXIgaW5zdGFuY2UuCisgICAgICogPHA+CisgICAgICogVGhlc2UgbWF5IGJlIGEgdGhlIHNhbWUgcGFyYW1ldGVycyB0aGF0IHdlcmUgdXNlZCB0byBjcmVhdGUgdGhpcyBjaXBoZXIKKyAgICAgKiBpbnN0YW5jZSwgb3IgbWF5IGJlIGEgY29tYmluYXRpb24gb2YgZGVmYXVsdCBhbmQgcmFuZG9tIHBhcmFtZXRlcnMsCisgICAgICogZGVwZW5kaW5nIG9uIHRoZSB1bmRlcmx5aW5nIGNpcGhlciBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlcnMgdGhhdCB3aGVyZSB1c2VkIHRvIGNyZWF0ZSB0aGlzIGNpcGhlciBpbnN0YW5jZSwgb3IKKyAgICAgKiAgICAgICAgIHtAY29kZSBudWxsfSBpZiB0aGlzIGNpcGhlciBpbnN0YW5jZSBkb2VzIG5vdCBoYXZlIGFueSBwYXJhbWV0ZXJzCisgICAgICogICAgICAgICBhdCBhbGwuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IEFsZ29yaXRobVBhcmFtZXRlcnMgZW5naW5lR2V0UGFyYW1ldGVycygpOworCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyBjaXBoZXIgaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGtleSBhbmQgYSBzb3VyY2Ugb2YKKyAgICAgKiByYW5kb21uZXNzLgorICAgICAqIDxwPgorICAgICAqIFRoZSBjaXBoZXIgd2lsbCBiZSBpbml0aWFsaXplZCBmb3IgdGhlIHNwZWNpZmllZCBvcGVyYXRpb24gKG9uZSBvZjoKKyAgICAgKiBlbmNyeXB0aW9uLCBkZWNyeXB0aW9uLCBrZXkgd3JhcHBpbmcgb3Iga2V5IHVud3JhcHBpbmcpIGRlcGVuZGluZyBvbgorICAgICAqIHtAY29kZSBvcG1vZGV9LgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgY2lwaGVyIGluc3RhbmNlIG5lZWRzIGFueSBhbGdvcml0aG0gcGFyYW1ldGVycyBvciByYW5kb20gdmFsdWVzCisgICAgICogdGhhdCB0aGUgc3BlY2lmaWVkIGtleSBjYW5ub3QgcHJvdmlkZSwgdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24gb2YKKyAgICAgKiB0aGlzIGNpcGhlciBpcyBzdXBwb3NlZCB0byBnZW5lcmF0ZSB0aGUgcmVxdWlyZWQgcGFyYW1ldGVycyAodXNpbmcgaXRzCisgICAgICogcHJvdmlkZXIgb3IgcmFuZG9tIHZhbHVlcykuIFJhbmRvbSB2YWx1ZXMgd2lsbCBiZSBnZW5lcmF0ZWQgdXNpbmcge0Bjb2RlCisgICAgICogcmFuZG9tfTsKKyAgICAgKiA8cD4KKyAgICAgKiBXaGVuIGEgY2lwaGVyIGluc3RhbmNlIGlzIGluaXRpYWxpemVkIGJ5IGEgY2FsbCB0byBhbnkgb2YgdGhlIHtAY29kZQorICAgICAqIGluaXR9IG1ldGhvZHMsIHRoZSBzdGF0ZSBvZiB0aGUgaW5zdGFuY2UgaXMgb3ZlcnJpZGRlbiwgbWVhbnMgaXQgaXMKKyAgICAgKiBlcXVpdmFsZW50IHRvIGNyZWF0aW5nIGEgbmV3IGluc3RhbmNlIGFuZCBjYWxsaW5nIGl0IHtAY29kZSBpbml0fSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3Btb2RlCisgICAgICogICAgICAgICAgICB0aGUgb3BlcmF0aW9uIHRoaXMgY2lwaGVyIGluc3RhbmNlIHNob3VsZCBiZSBpbml0aWFsaXplZCBmb3IKKyAgICAgKiAgICAgICAgICAgIChvbmUgb2Y6IHtAY29kZSBFTkNSWVBUX01PREV9LCB7QGNvZGUgREVDUllQVF9NT0RFfSwge0Bjb2RlCisgICAgICogICAgICAgICAgICBXUkFQX01PREV9IG9yIHtAY29kZSBVTldSQVBfTU9ERX0pLgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBrZXkgZm9yIHRoZSBvcGVyYXRpb24uCisgICAgICogQHBhcmFtIHJhbmRvbQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBvZiByYW5kb21uZXNzIHRvIHVzZS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgdXNlZCB0byBpbml0aWFsaXplIHRoaXMgY2lwaGVyCisgICAgICogICAgICAgICAgICAgaW5zdGFuY2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgZW5naW5lSW5pdChpbnQgb3Btb2RlLCBLZXkga2V5LCBTZWN1cmVSYW5kb20gcmFuZG9tKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIGNpcGhlciBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LCBhbGdvcml0aG0KKyAgICAgKiBwYXJhbWV0ZXJzIGFuZCBhIHNvdXJjZSBvZiByYW5kb21uZXNzLgorICAgICAqIDxwPgorICAgICAqIFRoZSBjaXBoZXIgd2lsbCBiZSBpbml0aWFsaXplZCBmb3IgdGhlIHNwZWNpZmllZCBvcGVyYXRpb24gKG9uZSBvZjoKKyAgICAgKiBlbmNyeXB0aW9uLCBkZWNyeXB0aW9uLCBrZXkgd3JhcHBpbmcgb3Iga2V5IHVud3JhcHBpbmcpIGRlcGVuZGluZyBvbgorICAgICAqIHtAY29kZSBvcG1vZGV9LgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgY2lwaGVyIGluc3RhbmNlIG5lZWRzIGFueSBhbGdvcml0aG0gcGFyYW1ldGVycyBhbmQge0Bjb2RlIHBhcmFtc30KKyAgICAgKiBpcyB7QGNvZGUgbnVsbH0sIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgY2lwaGVyIGlzIHN1cHBvc2VkCisgICAgICogdG8gZ2VuZXJhdGUgdGhlIHJlcXVpcmVkIHBhcmFtZXRlcnMgKHVzaW5nIGl0cyBwcm92aWRlciBvciByYW5kb20KKyAgICAgKiB2YWx1ZXMpLiBSYW5kb20gdmFsdWVzIGFyZSBnZW5lcmF0ZWQgdXNpbmcge0Bjb2RlIHJhbmRvbX0uCisgICAgICogPHA+CisgICAgICogV2hlbiBhIGNpcGhlciBpbnN0YW5jZSBpcyBpbml0aWFsaXplZCBieSBhIGNhbGwgdG8gYW55IG9mIHRoZSB7QGNvZGUKKyAgICAgKiBpbml0fSBtZXRob2RzLCB0aGUgc3RhdGUgb2YgdGhlIGluc3RhbmNlIGlzIG92ZXJyaWRkZW4sIG1lYW5zIGl0IGlzCisgICAgICogZXF1aXZhbGVudCB0byBjcmVhdGluZyBhIG5ldyBpbnN0YW5jZSBhbmQgY2FsbGluZyBpdCB7QGNvZGUgaW5pdH0gbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIG9wbW9kZQorICAgICAqICAgICAgICAgICAgdGhlIG9wZXJhdGlvbiB0aGlzIGNpcGhlciBpbnN0YW5jZSBzaG91bGQgYmUgaW5pdGlhbGl6ZWQgZm9yCisgICAgICogICAgICAgICAgICAob25lIG9mOiB7QGNvZGUgRU5DUllQVF9NT0RFfSwge0Bjb2RlIERFQ1JZUFRfTU9ERX0sIHtAY29kZQorICAgICAqICAgICAgICAgICAgV1JBUF9NT0RFfSBvciB7QGNvZGUgVU5XUkFQX01PREV9KS4KKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQga2V5IGZvciB0aGUgb3BlcmF0aW9uLgorICAgICAqIEBwYXJhbSBwYXJhbXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhbGdvcml0aG0gcGFyYW1ldGVycy4KKyAgICAgKiBAcGFyYW0gcmFuZG9tCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIG9mIHJhbmRvbW5lc3MgdG8gdXNlLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbm5vdCBiZSB1c2VkIHRvIGluaXRpYWxpemUgdGhpcyBjaXBoZXIKKyAgICAgKiAgICAgICAgICAgICBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpdCB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMgYXJlIGluYXBwcm9wcmlhdGUgZm9yIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBjaXBoZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgZW5naW5lSW5pdChpbnQgb3Btb2RlLCBLZXkga2V5LAorICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMsIFNlY3VyZVJhbmRvbSByYW5kb20pCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMgY2lwaGVyIGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBrZXksIGFsZ29yaXRobQorICAgICAqIHBhcmFtZXRlcnMgYW5kIGEgc291cmNlIG9mIHJhbmRvbW5lc3MuCisgICAgICogPHA+CisgICAgICogVGhlIGNpcGhlciB3aWxsIGJlIGluaXRpYWxpemVkIGZvciB0aGUgc3BlY2lmaWVkIG9wZXJhdGlvbiAob25lIG9mOgorICAgICAqIGVuY3J5cHRpb24sIGRlY3J5cHRpb24sIGtleSB3cmFwcGluZyBvciBrZXkgdW53cmFwcGluZykgZGVwZW5kaW5nIG9uCisgICAgICoge0Bjb2RlIG9wbW9kZX0uCisgICAgICogPHA+CisgICAgICogSWYgdGhpcyBjaXBoZXIgaW5zdGFuY2UgbmVlZHMgYW55IGFsZ29yaXRobSBwYXJhbWV0ZXJzIGFuZCB7QGNvZGUgcGFyYW1zfQorICAgICAqIGlzIHtAY29kZSBudWxsfSwgdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBjaXBoZXIgaXMgc3VwcG9zZWQKKyAgICAgKiB0byBnZW5lcmF0ZSB0aGUgcmVxdWlyZWQgcGFyYW1ldGVycyAodXNpbmcgaXRzIHByb3ZpZGVyIG9yIHJhbmRvbQorICAgICAqIHZhbHVlcykuIFJhbmRvbSB2YWx1ZXMgYXJlIGdlbmVyYXRlZCB1c2luZyB7QGNvZGUgcmFuZG9tfS4KKyAgICAgKiA8cD4KKyAgICAgKiBXaGVuIGEgY2lwaGVyIGluc3RhbmNlIGlzIGluaXRpYWxpemVkIGJ5IGEgY2FsbCB0byBhbnkgb2YgdGhlIHtAY29kZQorICAgICAqIGluaXR9IG1ldGhvZHMsIHRoZSBzdGF0ZSBvZiB0aGUgaW5zdGFuY2UgaXMgb3ZlcnJpZGRlbiwgbWVhbnMgaXQgaXMKKyAgICAgKiBlcXVpdmFsZW50IHRvIGNyZWF0aW5nIGEgbmV3IGluc3RhbmNlIGFuZCBjYWxsaW5nIGl0IHtAY29kZSBpbml0fSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3Btb2RlCisgICAgICogICAgICAgICAgICB0aGUgb3BlcmF0aW9uIHRoaXMgY2lwaGVyIGluc3RhbmNlIHNob3VsZCBiZSBpbml0aWFsaXplZCBmb3IKKyAgICAgKiAgICAgICAgICAgIChvbmUgb2Y6IHtAY29kZSBFTkNSWVBUX01PREV9LCB7QGNvZGUgREVDUllQVF9NT0RFfSwge0Bjb2RlCisgICAgICogICAgICAgICAgICBXUkFQX01PREV9IG9yIHtAY29kZSBVTldSQVBfTU9ERX0pLgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBrZXkgZm9yIHRoZSBvcGVyYXRpb24uCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIGFsZ29yaXRobSBwYXJhbWV0ZXJzLgorICAgICAqIEBwYXJhbSByYW5kb20KKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2Ugb2YgcmFuZG9tbmVzcyB0byB1c2UuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGNpcGhlcgorICAgICAqICAgICAgICAgICAgIGluc3RhbmNlLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycyBhcmUgaW5hcHByb3ByaWF0ZSBmb3IgdGhpcworICAgICAqICAgICAgICAgICAgIGNpcGhlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBlbmdpbmVJbml0KGludCBvcG1vZGUsIEtleSBrZXksCisgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtcywgU2VjdXJlUmFuZG9tIHJhbmRvbSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLCBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ29udGludWVzIGEgbXVsdGktcGFydCB0cmFuc2Zvcm1hdGlvbiAoZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uKS4gVGhlCisgICAgICogdHJhbnNmb3JtZWQgYnl0ZXMgYXJlIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgYnl0ZXMgdG8gdHJhbnNmb3JtLgorICAgICAqIEBwYXJhbSBpbnB1dE9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgaW5wdXQgdG8gc3RhcnQuCisgICAgICogQHBhcmFtIGlucHV0TGVuCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBpbnB1dCB0byB0cmFuc2Zvcm0uCisgICAgICogQHJldHVybiB0aGUgdHJhbnNmb3JtZWQgYnl0ZXMgaW4gYSBuZXcgYnVmZmVyLCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlCisgICAgICogICAgICAgICBpbnB1dCBoYXMgemVybyBsZW5ndGguCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNpcGhlciBpbnN0YW5jZSBpcyBub3QgaW5pdGlhbGl6ZWQgZm9yIGVuY3J5cHRpb24gb3IKKyAgICAgKiAgICAgICAgICAgICBkZWNyeXB0aW9uLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGlucHV0IGlzIG51bGwsIG9yIGlmIHtAY29kZSBpbnB1dE9mZnNldH0gYW5kIHtAY29kZQorICAgICAqICAgICAgICAgICAgIGlucHV0TGVufSBkbyBub3Qgc3BlY2lmeSBhIHZhbGlkIGNodW5rIGluIHRoZSBpbnB1dCBidWZmZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IGJ5dGVbXSBlbmdpbmVVcGRhdGUoYnl0ZVtdIGlucHV0LCBpbnQgaW5wdXRPZmZzZXQsCisgICAgICAgICAgICBpbnQgaW5wdXRMZW4pOworCisgICAgLyoqCisgICAgICogQ29udGludWVzIGEgbXVsdGktcGFydCB0cmFuc2Zvcm1hdGlvbiAoZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uKS4gVGhlCisgICAgICogdHJhbnNmb3JtZWQgYnl0ZXMgYXJlIHN0b3JlZCBpbiB0aGUge0Bjb2RlIG91dHB1dH0gYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBzaXplIG9mIHRoZSB7QGNvZGUgb3V0cHV0fSBidWZmZXIgaXMgdG9vIHNtYWxsIHRvIGhvbGQgdGhlIHJlc3VsdCwKKyAgICAgKiBhIHtAY29kZSBTaG9ydEJ1ZmZlckV4Y2VwdGlvbn0gaXMgdGhyb3duLiBVc2UKKyAgICAgKiB7QGxpbmsgQ2lwaGVyI2dldE91dHB1dFNpemUgZ2V0T3V0cHV0U2l6ZX0gdG8gY2hlY2sgZm9yIHRoZSBzaXplIG9mIHRoZQorICAgICAqIG91dHB1dCBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBieXRlcyB0byB0cmFuc2Zvcm0uCisgICAgICogQHBhcmFtIGlucHV0T2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBpbnB1dCB0byBzdGFydC4KKyAgICAgKiBAcGFyYW0gaW5wdXRMZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhlIGlucHV0IHRvIHRyYW5zZm9ybS4KKyAgICAgKiBAcGFyYW0gb3V0cHV0CisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IGJ1ZmZlci4KKyAgICAgKiBAcGFyYW0gb3V0cHV0T2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBvdXRwdXQgYnVmZmVyLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBwbGFjZWQgaW4gb3V0cHV0LgorICAgICAqIEB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2l6ZSBvZiB0aGUge0Bjb2RlIG91dHB1dH0gYnVmZmVyIGlzIHRvbyBzbWFsbC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW50IGVuZ2luZVVwZGF0ZShieXRlW10gaW5wdXQsIGludCBpbnB1dE9mZnNldCwKKyAgICAgICAgICAgIGludCBpbnB1dExlbiwgYnl0ZVtdIG91dHB1dCwgaW50IG91dHB1dE9mZnNldCkKKyAgICAgICAgICAgIHRocm93cyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENvbnRpbnVlcyBhIG11bHRpLXBhcnQgdHJhbnNmb3JtYXRpb24gKGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbikuIFRoZQorICAgICAqIHtAY29kZSBpbnB1dC5yZW1haW5pbmcoKX0gYnl0ZXMgc3RhcnRpbmcgYXQge0Bjb2RlIGlucHV0LnBvc2l0aW9uKCl9IGFyZQorICAgICAqIHRyYW5zZm9ybWVkIGFuZCBzdG9yZWQgaW4gdGhlIHtAY29kZSBvdXRwdXR9IGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUge0Bjb2RlIG91dHB1dC5yZW1haW5pbmcoKX0gaXMgdG9vIHNtYWxsIHRvIGhvbGQgdGhlIHRyYW5zZm9ybWVkCisgICAgICogYnl0ZXMgYSB7QGNvZGUgU2hvcnRCdWZmZXJFeGNlcHRpb259IGlzIHRocm93bi4gVXNlCisgICAgICoge0BsaW5rIENpcGhlciNnZXRPdXRwdXRTaXplIGdldE91dHB1dFNpemV9IHRvIGNoZWNrIGZvciB0aGUgc2l6ZSBvZiB0aGUKKyAgICAgKiBvdXRwdXQgYnVmZmVyLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgYnVmZmVyIHRvIHRyYW5zZm9ybS4KKyAgICAgKiBAcGFyYW0gb3V0cHV0CisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IGJ1ZmZlciB0byBzdG9yZSB0aGUgcmVzdWx0IHdpdGhpbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgc3RvcmVkIGluIHRoZSBvdXRwdXQgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2l6ZSBvZiB0aGUge0Bjb2RlIG91dHB1dH0gYnVmZmVyIGlzIHRvbyBzbWFsbC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGVuZ2luZVVwZGF0ZShCeXRlQnVmZmVyIGlucHV0LCBCeXRlQnVmZmVyIG91dHB1dCkKKyAgICAgICAgICAgIHRocm93cyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpbnB1dCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImlucHV0ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAob3V0cHV0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigib3V0cHV0ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgcG9zaXRpb24gPSBpbnB1dC5wb3NpdGlvbigpOworICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5saW1pdCgpOworICAgICAgICBpZiAoKGxpbWl0IC0gcG9zaXRpb24pIDw9IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSBiSW5wdXQ7CisgICAgICAgIGJ5dGVbXSBiT3V0cHV0OworICAgICAgICBpZiAoaW5wdXQuaGFzQXJyYXkoKSkgeworICAgICAgICAgICAgYklucHV0ID0gaW5wdXQuYXJyYXkoKTsKKyAgICAgICAgICAgIGludCBvZmZzZXQgPSBpbnB1dC5hcnJheU9mZnNldCgpOworICAgICAgICAgICAgYk91dHB1dCA9IGVuZ2luZVVwZGF0ZShiSW5wdXQsIG9mZnNldCArIHBvc2l0aW9uLCBsaW1pdCAtIHBvc2l0aW9uKTsKKyAgICAgICAgICAgIGlucHV0LnBvc2l0aW9uKGxpbWl0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJJbnB1dCA9IG5ldyBieXRlW2xpbWl0IC0gcG9zaXRpb25dOworICAgICAgICAgICAgaW5wdXQuZ2V0KGJJbnB1dCk7CisgICAgICAgICAgICBiT3V0cHV0ID0gZW5naW5lVXBkYXRlKGJJbnB1dCwgMCwgbGltaXQgLSBwb3NpdGlvbik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJPdXRwdXQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG91dHB1dC5yZW1haW5pbmcoKSA8IGJPdXRwdXQubGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU2hvcnRCdWZmZXJFeGNlcHRpb24oIm91dHB1dCBidWZmZXIgdG9vIHNtYWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG91dHB1dC5wdXQoYk91dHB1dCk7CisgICAgICAgIH0gY2F0Y2ggKGphdmEubmlvLkJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbigib3V0cHV0IGJ1ZmZlciB0b28gc21hbGwiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYk91dHB1dC5sZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluaXNoZXMgYSBtdWx0aS1wYXJ0IHRyYW5zZm9ybWF0aW9uIChlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24pLgorICAgICAqIDxwPgorICAgICAqIFByb2Nlc3NlcyB0aGUge0Bjb2RlIGlucHV0TGVufSBieXRlcyBpbiB7QGNvZGUgaW5wdXR9IGJ1ZmZlciBhdCB7QGNvZGUKKyAgICAgKiBpbnB1dE9mZnNldH0sIGFuZCBhbnkgYnl0ZXMgdGhhdCBoYXZlIGJlZW4gYnVmZmVyZWQgaW4gcHJldmlvdXMge0Bjb2RlCisgICAgICogdXBkYXRlfSBjYWxscy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dAorICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IGJ1ZmZlci4KKyAgICAgKiBAcGFyYW0gaW5wdXRPZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIGlucHV0IGJ1ZmZlci4KKyAgICAgKiBAcGFyYW0gaW5wdXRMZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhlIGlucHV0LgorICAgICAqIEByZXR1cm4gdGhlIGZpbmFsIGJ5dGVzIGZyb20gdGhlIHRyYW5zZm9ybWF0aW9uLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIHRoZSByZXN1bHRpbmcgYnl0ZXMgaXMgbm90IGEgbXVsdGlwbGUgb2YgdGhlCisgICAgICogICAgICAgICAgICAgY2lwaGVyIGJsb2NrIHNpemUuCisgICAgICogQHRocm93cyBCYWRQYWRkaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBhZGRpbmcgb2YgdGhlIGRhdGEgZG9lcyBub3QgbWF0Y2ggdGhlIHBhZGRpbmcgc2NoZW1lLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBieXRlW10gZW5naW5lRG9GaW5hbChieXRlW10gaW5wdXQsIGludCBpbnB1dE9mZnNldCwKKyAgICAgICAgICAgIGludCBpbnB1dExlbikgdGhyb3dzIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24sIEJhZFBhZGRpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBGaW5pc2hlcyBhIG11bHRpLXBhcnQgdHJhbnNmb3JtYXRpb24gKGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbikuCisgICAgICogPHA+CisgICAgICogUHJvY2Vzc2VzIHRoZSB7QGNvZGUgaW5wdXRMZW59IGJ5dGVzIGluIHtAY29kZSBpbnB1dH0gYnVmZmVyIGF0CisgICAgICoge0Bjb2RlIGlucHV0T2Zmc2V0fSwgYW5kIGFueSBieXRlcyB0aGF0IGhhdmUgYmVlbiBidWZmZXJlZCBpbiBwcmV2aW91cworICAgICAqIHtAY29kZSB1cGRhdGV9IGNhbGxzLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgaW5wdXQgYnVmZmVyLgorICAgICAqIEBwYXJhbSBpbnB1dE9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgaW5wdXQgYnVmZmVyLgorICAgICAqIEBwYXJhbSBpbnB1dExlbgorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgaW5wdXQuCisgICAgICogQHBhcmFtIG91dHB1dAorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBidWZmZXIgZm9yIHRoZSB0cmFuc2Zvcm1lZCBieXRlcy4KKyAgICAgKiBAcGFyYW0gb3V0cHV0T2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBvdXRwdXQgYnVmZmVyLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBwbGFjZWQgaW4gdGhlIG91dHB1dCBidWZmZXIuCisgICAgICogQHRocm93cyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIHRoZSB7QGNvZGUgb3V0cHV0fSBidWZmZXIgaXMgdG9vIHNtYWxsLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIHRoZSByZXN1bHRpbmcgYnl0ZXMgaXMgbm90IGEgbXVsdGlwbGUgb2YgdGhlCisgICAgICogICAgICAgICAgICAgY2lwaGVyIGJsb2NrIHNpemUuCisgICAgICogQHRocm93cyBCYWRQYWRkaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBhZGRpbmcgb2YgdGhlIGRhdGEgZG9lcyBub3QgbWF0Y2ggdGhlIHBhZGRpbmcgc2NoZW1lLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBpbnQgZW5naW5lRG9GaW5hbChieXRlW10gaW5wdXQsIGludCBpbnB1dE9mZnNldCwKKyAgICAgICAgICAgIGludCBpbnB1dExlbiwgYnl0ZVtdIG91dHB1dCwgaW50IG91dHB1dE9mZnNldCkKKyAgICAgICAgICAgIHRocm93cyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbiwgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEJhZFBhZGRpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBGaW5pc2hlcyBhIG11bHRpLXBhcnQgdHJhbnNmb3JtYXRpb24gKGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbikuCisgICAgICogPHA+CisgICAgICogUHJvY2Vzc2VzIHRoZSB7QGNvZGUgaW5wdXQucmVtYWluaW5nKCl9IGJ5dGVzIGluIHtAY29kZSBpbnB1dH0gYnVmZmVyIGF0CisgICAgICoge0Bjb2RlIGlucHV0LnBvc2l0aW9uKCl9LCBhbmQgYW55IGJ5dGVzIHRoYXQgaGF2ZSBiZWVuIGJ1ZmZlcmVkIGluCisgICAgICogcHJldmlvdXMge0Bjb2RlIHVwZGF0ZX0gY2FsbHMuIFRoZSB0cmFuc2Zvcm1lZCBieXRlcyBhcmUgcGxhY2VkIGludG8KKyAgICAgKiB7QGNvZGUgb3V0cHV0fSBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbnB1dCBidWZmZXIuCisgICAgICogQHBhcmFtIG91dHB1dAorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBidWZmZXIuCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHBsYWNlZCBpbnRvIHRoZSBvdXRwdXQgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2l6ZSBvZiB0aGUge0Bjb2RlIG91dHB1dH0gYnVmZmVyIGlzIHRvbyBzbWFsbC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2l6ZSBvZiB0aGUgcmVzdWx0aW5nIGJ5dGVzIGlzIG5vdCBhIG11bHRpcGxlIG9mIHRoZQorICAgICAqICAgICAgICAgICAgIGNpcGhlciBibG9jayBzaXplLgorICAgICAqIEB0aHJvd3MgQmFkUGFkZGluZ0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYWRkaW5nIG9mIHRoZSBkYXRhIGRvZXMgbm90IG1hdGNoIHRoZSBwYWRkaW5nIHNjaGVtZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBpbnB1dCBidWZmZXIgYW5kIHRoZSBvdXRwdXQgYnVmZmVyIGFyZSB0aGUgc2FtZQorICAgICAqICAgICAgICAgICAgIG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgY2lwaGVyIGluc3RhbmNlIGlzIG5vdCBpbml0aWFsaXplZCBmb3IgZW5jcnlwdGlvbiBvcgorICAgICAqICAgICAgICAgICAgIGRlY3J5cHRpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBlbmdpbmVEb0ZpbmFsKEJ5dGVCdWZmZXIgaW5wdXQsIEJ5dGVCdWZmZXIgb3V0cHV0KQorICAgICAgICAgICAgdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uLCBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uLAorICAgICAgICAgICAgQmFkUGFkZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpbnB1dCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImlucHV0ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAob3V0cHV0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigib3V0cHV0ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgcG9zaXRpb24gPSBpbnB1dC5wb3NpdGlvbigpOworICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5saW1pdCgpOworCisgICAgICAgIGlmICgobGltaXQgLSBwb3NpdGlvbikgPD0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIGJJbnB1dDsKKyAgICAgICAgYnl0ZVtdIGJPdXRwdXQ7CisKKyAgICAgICAgaWYgKGlucHV0Lmhhc0FycmF5KCkpIHsKKyAgICAgICAgICAgIGJJbnB1dCA9IGlucHV0LmFycmF5KCk7CisgICAgICAgICAgICBpbnQgb2Zmc2V0ID0gaW5wdXQuYXJyYXlPZmZzZXQoKTsKKyAgICAgICAgICAgIGJPdXRwdXQgPSBlbmdpbmVEb0ZpbmFsKGJJbnB1dCwgb2Zmc2V0ICsgcG9zaXRpb24sIGxpbWl0IC0gcG9zaXRpb24pOworICAgICAgICAgICAgaW5wdXQucG9zaXRpb24obGltaXQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYklucHV0ID0gbmV3IGJ5dGVbbGltaXQgLSBwb3NpdGlvbl07CisgICAgICAgICAgICBpbnB1dC5nZXQoYklucHV0KTsKKyAgICAgICAgICAgIGJPdXRwdXQgPSBlbmdpbmVEb0ZpbmFsKGJJbnB1dCwgMCwgbGltaXQgLSBwb3NpdGlvbik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG91dHB1dC5yZW1haW5pbmcoKSA8IGJPdXRwdXQubGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU2hvcnRCdWZmZXJFeGNlcHRpb24oIm91dHB1dCBidWZmZXIgdG9vIHNtYWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG91dHB1dC5wdXQoYk91dHB1dCk7CisgICAgICAgIH0gY2F0Y2ggKGphdmEubmlvLkJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbigib3V0cHV0IGJ1ZmZlciB0b28gc21hbGwiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYk91dHB1dC5sZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JhcHMgYSBrZXkgdXNpbmcgdGhpcyBjaXBoZXIgaW5zdGFuY2UuIFRoaXMgbWV0aG9kIGhhcyBiZWVuIGFkZGVkIHRvCisgICAgICogdGhpcyBjbGFzcyAoZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LCBpdCBjYW5ub3QgYmUgYWJzdHJhY3QpLiBJZiB0aGlzCisgICAgICogbWV0aG9kIGlzIG5vdCBvdmVycmlkZGVuLCBpdCB0aHJvd3MgYW4ge0Bjb2RlCisgICAgICogVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byB3cmFwLgorICAgICAqIEByZXR1cm4gdGhlIHdyYXBwZWQga2V5CisgICAgICogQHRocm93cyBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNpemUgb2YgdGhlIHJlc3VsdGluZyBieXRlcyBpcyBub3QgYSBtdWx0aXBsZSBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgICBjaXBoZXIgYmxvY2sgc2l6ZS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGNpcGhlciBpbnN0YW5jZSBjYW5ub3Qgd3JhcCB0aGlzIGtleS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuZ2luZVdyYXAoS2V5IGtleSkgdGhyb3dzIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24sIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVbndyYXBzIGEga2V5IHVzaW5nIHRoaXMgY2lwaGVyIGluc3RhbmNlLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIGhhcyBiZWVuIGFkZGVkIHRvIHRoaXMgY2xhc3MgKGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSwgaXQKKyAgICAgKiBjYW5ub3QgYmUgYWJzdHJhY3QpLiBJZiB0aGlzIG1ldGhvZCBpcyBub3Qgb3ZlcnJpZGRlbiwgaXQgdGhyb3dzIGFuCisgICAgICoge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB3cmFwcGVkS2V5CisgICAgICogICAgICAgICAgICB0aGUgd3JhcHBlZCBrZXkgdG8gdW53cmFwLgorICAgICAqIEBwYXJhbSB3cmFwcGVkS2V5QWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgYWxnb3JpdGhtIGZvciB0aGUgd3JhcHBlZCBrZXkuCisgICAgICogQHBhcmFtIHdyYXBwZWRLZXlUeXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgd3JhcHBlZCBrZXkgKG9uZSBvZjoge0Bjb2RlIFNFQ1JFVF9LRVl9LAorICAgICAqICAgICAgICAgICAge0Bjb2RlIFBSSVZBVEVfS0VZfSBvciB7QGNvZGUgUFVCTElDX0tFWX0pCisgICAgICogQHJldHVybiB0aGUgdW53cmFwcGVkIGtleS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIHdyYXBwZWRLZXl9IGNhbm5vdCBiZSB1bndyYXBwZWQgdG8gYSBrZXkgb2YKKyAgICAgKiAgICAgICAgICAgICB0eXBlIHtAY29kZSB3cmFwcGVkS2V5VHlwZX0gZm9yIHRoZSB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICB3cmFwcGVkS2V5QWxnb3JpdGhtfS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG5vIHByb3ZpZGVyIGNhbiBiZSBmb3VuZCB0aGF0IGNhbiBjcmVhdGUgYSBrZXkgb2YgdHlwZQorICAgICAqICAgICAgICAgICAgIHtAY29kZSB3cmFwcGVkS2V5VHlwZX0gZm9yIHRoZSB7QGNvZGUgd3JhcHBlZEtleUFsZ29yaXRobX0uCisgICAgICovCisgICAgcHJvdGVjdGVkIEtleSBlbmdpbmVVbndyYXAoYnl0ZVtdIHdyYXBwZWRLZXksIFN0cmluZyB3cmFwcGVkS2V5QWxnb3JpdGhtLAorICAgICAgICAgICAgaW50IHdyYXBwZWRLZXlUeXBlKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2l6ZSBvZiBhIHNwZWNpZmllZCBrZXkgb2JqZWN0IGluIGJpdHMuIFRoaXMgbWV0aG9kIGhhcyBiZWVuCisgICAgICogYWRkZWQgdG8gdGhpcyBjbGFzcyAoZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LCBpdCBjYW5ub3QgYmUgYWJzdHJhY3QpLgorICAgICAqIElmIHRoaXMgbWV0aG9kIGlzIG5vdCBvdmVycmlkZGVuLCBpdCB0aHJvd3MgYW4ge0Bjb2RlCisgICAgICogVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byBnZXQgdGhlIHNpemUgZm9yLgorICAgICAqIEByZXR1cm4gdGhlIHNpemUgb2YgYSBzcGVjaWZpZWQga2V5IG9iamVjdCBpbiBiaXRzLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzaXplIG9mIHRoZSBrZXkgY2Fubm90IGJlIGRldGVybWluZWQgYnkgdGhpcworICAgICAqICAgICAgICAgICAgIGltcGxlbWVudGF0aW9uLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgZW5naW5lR2V0S2V5U2l6ZShLZXkga2V5KSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMzRmMDdhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9FbmNyeXB0ZWRQcml2YXRlS2V5SW5mby5qYXZhCkBAIC0wLDAgKzEsNTQzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LmNyeXB0bzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5JbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuUEtDUzhFbmNvZGVkS2V5U3BlYzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xQW55OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFJbXBsaWNpdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xSW50ZWdlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xT2N0ZXRTdHJpbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXRPZjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudXRpbHMuQWxnTmFtZU1hcHBlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5BbGdvcml0aG1JZGVudGlmaWVyOworCisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSB7QGNvZGUgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm99IEFTTi4xIHR5cGUgYXMKKyAqIHNwZWNpZmllZCBpbiA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM1MjA4LnR4dCI+UEtDUworICogIzggLSBQcml2YXRlLUtleSBJbmZvcm1hdGlvbiBTeW50YXggU3RhbmRhcmQ8L2E+LgorICogPHA+CisgKiBUaGUgZGVmaW5pdGlvbiBvZiBBU04uMSBpcyBhcyBmb2xsb3dzOgorICogPGRsPgorICogRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gOjo9IFNFUVVFTkNFIHsKKyAqIDxkZD5lbmNyeXB0aW9uQWxnb3JpdGhtIEFsZ29yaXRobUlkZW50aWZpZXIsPC9kZD4KKyAqIDxkZD5lbmNyeXB0ZWREYXRhIE9DVEVUIFNUUklORyB9PC9kZD4KKyAqIDwvZGw+CisgKiA8ZGw+CisgKiBBbGdvcml0aG1JZGVudGlmaWVyIDo6PSBTRVFVRU5DRSB7CisgKiA8ZGQ+YWxnb3JpdGhtIE9CSkVDVCBJREVOVElGSUVSLDwvZGQ+CisgKiA8ZGQ+cGFyYW1ldGVycyBBTlkgREVGSU5FRCBCWSBhbGdvcml0aG0gT1BUSU9OQUwgfTwvZGQ+CisgKiA8L2RsPgorICovCitwdWJsaWMgY2xhc3MgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8geworICAgIC8vIEVuY3J5cHRpb24gYWxnb3JpdGhtIG5hbWUKKyAgICBwcml2YXRlIFN0cmluZyBhbGdOYW1lOworICAgIC8vIEVuY3J5cHRpb24gYWxnb3JpdGhtIHBhcmFtZXRlcnMKKyAgICBwcml2YXRlIGZpbmFsIEFsZ29yaXRobVBhcmFtZXRlcnMgYWxnUGFyYW1ldGVyczsKKyAgICAvLyBFbmNyeXB0ZWQgcHJpdmF0ZSBrZXkgZGF0YQorICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGVuY3J5cHRlZERhdGE7CisgICAgLy8gRW5jcnlwdGlvbiBhbGdvcml0aG0gT0lECisgICAgcHJpdmF0ZSBTdHJpbmcgb2lkOworICAgIC8vIFRoaXMgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gQVNOLjEgREVSIGVuY29kaW5nCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBieXRlW10gZW5jb2RlZDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4ge0Bjb2RlIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvfSBpbnN0YW5jZSBmcm9tIGl0cyBlbmNvZGVkCisgICAgICogcmVwcmVzZW50YXRpb24gYnkgcGFyc2luZyBpdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbmNvZGVkCisgICAgICogICAgICAgICAgICB0aGUgZW5jb2RlZCByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG9iamVjdAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBwYXJzaW5nIHRoZSBlbmNvZGVkIHJlcHJlc2VudGF0aW9uIGZhaWxzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZW5jb2RlZH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhieXRlW10gZW5jb2RlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGVuY29kZWQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJlbmNvZGVkID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmVuY29kZWQgPSBuZXcgYnl0ZVtlbmNvZGVkLmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZW5jb2RlZCwgMCwgdGhpcy5lbmNvZGVkLCAwLCBlbmNvZGVkLmxlbmd0aCk7CisgICAgICAgIE9iamVjdFtdIHZhbHVlczsKKworICAgICAgICB2YWx1ZXMgPSAoT2JqZWN0W10pYXNuMS5kZWNvZGUoZW5jb2RlZCk7CisKKyAgICAgICAgQWxnb3JpdGhtSWRlbnRpZmllciBhSWQgPSAoQWxnb3JpdGhtSWRlbnRpZmllcikgdmFsdWVzWzBdOworCisgICAgICAgIGFsZ05hbWUgPSBhSWQuZ2V0QWxnb3JpdGhtKCk7CisgICAgICAgIC8vIGFsZ05hbWUgPT0gb2lkIG5vdworICAgICAgICBib29sZWFuIG1hcHBpbmdFeGlzdHMgPSBtYXBBbGdOYW1lKCk7CisgICAgICAgIC8vIGFsZ05hbWUgPT0gbmFtZSBmcm9tIG1hcCBvaWQtPm5hbWUgaWYgbWFwcGluZyBleGlzdHMsIG9yCisgICAgICAgIC8vIGFsZ05hbWUgPT0gb2lkIGlmIG1hcHBpbmcgZG9lcyBub3QgZXhpc3QKKworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIGFQYXJhbXMgPSBudWxsOworICAgICAgICBieXRlW10gcGFyYW1zID0gYUlkLmdldFBhcmFtZXRlcnMoKTsKKyAgICAgICAgaWYgKHBhcmFtcyAhPSBudWxsICYmICFpc051bGxWYWx1ZShwYXJhbXMpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGFQYXJhbXMgPSBBbGdvcml0aG1QYXJhbWV0ZXJzLmdldEluc3RhbmNlKGFsZ05hbWUpOworICAgICAgICAgICAgICAgIGFQYXJhbXMuaW5pdChhSWQuZ2V0UGFyYW1ldGVycygpKTsKKyAgICAgICAgICAgICAgICBpZiAoIW1hcHBpbmdFeGlzdHMpIHsKKyAgICAgICAgICAgICAgICAgICAgYWxnTmFtZSA9IGFQYXJhbXMuZ2V0QWxnb3JpdGhtKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhbGdQYXJhbWV0ZXJzID0gYVBhcmFtczsKKworICAgICAgICBlbmNyeXB0ZWREYXRhID0gKGJ5dGVbXSkgdmFsdWVzWzFdOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNOdWxsVmFsdWUoYnl0ZVtdIHRvQ2hlY2spIHsKKyAgICAgICAgcmV0dXJuIHRvQ2hlY2tbMF0gPT0gNSAmJiB0b0NoZWNrWzFdID09IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiB7QGNvZGUgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm99IGluc3RhbmNlIGZyb20gYW4gYWxnb3JpdGhtCisgICAgICogbmFtZSBhbmQgaXRzIGVuY3J5cHRlZCBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIGVuY3JBbGdOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiBhbiBhbGdvcml0aG0uCisgICAgICogQHBhcmFtIGVuY3J5cHRlZERhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmNyeXB0ZWQgZGF0YS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB7QGNvZGUgZW5jckFsZ05hbWV9IGlzIG5vdCBhIHN1cHBvcnRlZCBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBlbmNyQWxnTmFtZX0gb3Ige0Bjb2RlIGVuY3J5cHRlZERhdGF9IGlzIHtAY29kZQorICAgICAqICAgICAgICAgICAgIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGVuY3J5cHRlZERhdGF9IGlzIGVtcHR5LgorICAgICAqLworICAgIHB1YmxpYyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhTdHJpbmcgZW5jckFsZ05hbWUsIGJ5dGVbXSBlbmNyeXB0ZWREYXRhKQorICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGVuY3JBbGdOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidGhlIGFsZ05hbWUgcGFyYW1ldGVyIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmFsZ05hbWUgPSBlbmNyQWxnTmFtZTsKKyAgICAgICAgaWYgKCFtYXBBbGdOYW1lKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oIlVuc3VwcG9ydGVkIGFsZ29yaXRobTogIiArIHRoaXMuYWxnTmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVuY3J5cHRlZERhdGEgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJlbmNyeXB0ZWREYXRhID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZW5jcnlwdGVkRGF0YS5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiZW5jcnlwdGVkRGF0YS5sZW5ndGggPT0gMCIpOworICAgICAgICB9CisgICAgICAgIHRoaXMuZW5jcnlwdGVkRGF0YSA9IG5ldyBieXRlW2VuY3J5cHRlZERhdGEubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShlbmNyeXB0ZWREYXRhLCAwLAorICAgICAgICAgICAgICAgIHRoaXMuZW5jcnlwdGVkRGF0YSwgMCwgZW5jcnlwdGVkRGF0YS5sZW5ndGgpOworICAgICAgICB0aGlzLmFsZ1BhcmFtZXRlcnMgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4ge0Bjb2RlIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvfSBpbnN0YW5jZSBmcm9tIHRoZQorICAgICAqIGVuY3J5cHRpb24gYWxnb3JpdGhtIHBhcmFtZXRlcnMgYW4gaXRzIGVuY3J5cHRlZCBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ1BhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIGVuY3J5cHRpb24gYWxnb3JpdGhtIHBhcmFtZXRlcnMuCisgICAgICogQHBhcmFtIGVuY3J5cHRlZERhdGEKKyAgICAgKiAgICAgICAgICAgIHRoZSBlbmNyeXB0ZWQgZGF0YS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhbGdvcml0aG0gbmFtZSBvZiB0aGUgc3BlY2lmaWVkIHtAY29kZSBhbGdQYXJhbXN9CisgICAgICogICAgICAgICAgICAgcGFyYW1ldGVyIGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhbGdQYXJhbXN9IG9yIHtAY29kZSBlbmNyeXB0ZWREYXRhfSBpcworICAgICAqICAgICAgICAgICAgIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oQWxnb3JpdGhtUGFyYW1ldGVycyBhbGdQYXJhbXMsIGJ5dGVbXSBlbmNyeXB0ZWREYXRhKQorICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFsZ1BhcmFtcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImFsZ1BhcmFtcyA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5hbGdQYXJhbWV0ZXJzID0gYWxnUGFyYW1zOworICAgICAgICBpZiAoZW5jcnlwdGVkRGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImVuY3J5cHRlZERhdGEgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChlbmNyeXB0ZWREYXRhLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJlbmNyeXB0ZWREYXRhLmxlbmd0aCA9PSAwIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5lbmNyeXB0ZWREYXRhID0gbmV3IGJ5dGVbZW5jcnlwdGVkRGF0YS5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVuY3J5cHRlZERhdGEsIDAsCisgICAgICAgICAgICAgICAgdGhpcy5lbmNyeXB0ZWREYXRhLCAwLCBlbmNyeXB0ZWREYXRhLmxlbmd0aCk7CisgICAgICAgIHRoaXMuYWxnTmFtZSA9IHRoaXMuYWxnUGFyYW1ldGVycy5nZXRBbGdvcml0aG0oKTsKKyAgICAgICAgaWYgKCFtYXBBbGdOYW1lKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oIlVuc3VwcG9ydGVkIGFsZ29yaXRobTogIiArIHRoaXMuYWxnTmFtZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBlbmNyeXB0aW9uIGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGVuY3J5cHRpb24gYWxnb3JpdGhtLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIGFsZ05hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGFyYW1ldGVycyB1c2VkIGJ5IHRoZSBlbmNyeXB0aW9uIGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHBhcmFtZXRlcnMgdXNlZCBieSB0aGUgZW5jcnlwdGlvbiBhbGdvcml0aG0uCisgICAgICovCisgICAgcHVibGljIEFsZ29yaXRobVBhcmFtZXRlcnMgZ2V0QWxnUGFyYW1ldGVycygpIHsKKyAgICAgICAgcmV0dXJuIGFsZ1BhcmFtZXRlcnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5jcnlwdGVkIGRhdGEgb2YgdGhpcyBrZXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBlbmNyeXB0ZWQgZGF0YSBvZiB0aGlzIGtleSwgZWFjaCB0aW1lIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBhCisgICAgICogICAgICAgICBuZXcgYXJyYXkgaXMgcmV0dXJuZWQuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNyeXB0ZWREYXRhKCkgeworICAgICAgICBieXRlW10gcmV0ID0gbmV3IGJ5dGVbZW5jcnlwdGVkRGF0YS5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVuY3J5cHRlZERhdGEsIDAsIHJldCwgMCwgZW5jcnlwdGVkRGF0YS5sZW5ndGgpOworICAgICAgICByZXR1cm4gcmV0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBQS0NTOEVuY29kZWRLZXlTcGVjfSBvYmplY3QgZXh0cmFjdGVkIGZyb20gdGhlCisgICAgICogZW5jcnlwdGVkIGRhdGEuCisgICAgICogPHA+CisgICAgICogVGhlIGNpcGhlciBtdXN0IGJlIGluaXRpYWxpemUgaW4gZWl0aGVyIHtAY29kZSBDaXBoZXIuREVDUllQVF9NT0RFfSBvcgorICAgICAqIHtAY29kZSBDaXBoZXIuVU5XUkFQX01PREV9IHdpdGggdGhlIHNhbWUgcGFyYW1ldGVycyBhbmQga2V5IHVzZWQgZm9yCisgICAgICogZW5jcnlwdGluZyB0aGlzLgorICAgICAqCisgICAgICogQHBhcmFtIGNpcGhlcgorICAgICAqICAgICAgICAgICAgdGhlIGNpcGhlciBpbml0aWFsaXplZCBmb3IgZGVjcnlwdGluZyB0aGUgZW5jcnlwdGVkIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgZXh0cmFjdGVkIHtAY29kZSBQS0NTOEVuY29kZWRLZXlTcGVjfS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBjaXBoZXIgaXMgbm90IHN1aXRlZCB0byBkZWNyeXB0IHRoZQorICAgICAqICAgICAgICAgICAgIGVuY3J5cHRlZCBkYXRhLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgY2lwaGVyfSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFBLQ1M4RW5jb2RlZEtleVNwZWMgZ2V0S2V5U3BlYyhDaXBoZXIgY2lwaGVyKQorICAgICAgICB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24geworICAgICAgICBpZiAoY2lwaGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiY2lwaGVyID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYnl0ZVtdIGRlY3J5cHRlZERhdGEgPSBjaXBoZXIuZG9GaW5hbChlbmNyeXB0ZWREYXRhKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQVNOMVByaXZhdGVLZXlJbmZvLnZlcmlmeShkZWNyeXB0ZWREYXRhKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUxKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKCJEZWNyeXB0ZWQgZGF0YSBkb2VzIG5vdCByZXByZXNlbnQgdmFsaWQgUEtDUyM4IFByaXZhdGVLZXlJbmZvIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IFBLQ1M4RW5jb2RlZEtleVNwZWMoZGVjcnlwdGVkRGF0YSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleVNwZWNFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKEJhZFBhZGRpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBQS0NTOEVuY29kZWRLZXlTcGVjfSBvYmplY3QgZXh0cmFjdGVkIGZyb20gdGhlCisgICAgICogZW5jcnlwdGVkIGRhdGEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGVjcnlwdEtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byBkZWNyeXB0IHRoZSBlbmNyeXB0ZWQgZGF0YSB3aXRoLgorICAgICAqIEByZXR1cm4gdGhlIGV4dHJhY3RlZCB7QGNvZGUgUEtDUzhFbmNvZGVkS2V5U3BlY30uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyB1c2FibGUgY2lwaGVyIGNhbiBiZSBmb3VuZCB0byBkZWNyeXB0IHRoZSBlbmNyeXB0ZWQKKyAgICAgKiAgICAgICAgICAgICBkYXRhLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkZWNyeXB0S2V5fSBpcyBub3QgdXNhYmxlIHRvIGRlY3J5cHQgdGhlIGVuY3J5cHRlZAorICAgICAqICAgICAgICAgICAgIGRhdGEuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBkZWNyeXB0S2V5fSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIFBLQ1M4RW5jb2RlZEtleVNwZWMgZ2V0S2V5U3BlYyhLZXkgZGVjcnlwdEtleSkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICBpZiAoZGVjcnlwdEtleSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImRlY3J5cHRLZXkgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDaXBoZXIgY2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKGFsZ05hbWUpOworICAgICAgICAgICAgaWYgKGFsZ1BhcmFtZXRlcnMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGNpcGhlci5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGRlY3J5cHRLZXkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBjaXBoZXIuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLCBkZWNyeXB0S2V5LCBhbGdQYXJhbWV0ZXJzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ5dGVbXSBkZWNyeXB0ZWREYXRhID0gY2lwaGVyLmRvRmluYWwoZW5jcnlwdGVkRGF0YSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEFTTjFQcml2YXRlS2V5SW5mby52ZXJpZnkoZGVjcnlwdGVkRGF0YSk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlMSkgeworICAgICAgICAgICAgICAgIHRocm93IGludmFsaWRLZXkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuZXcgUEtDUzhFbmNvZGVkS2V5U3BlYyhkZWNyeXB0ZWREYXRhKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5RXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKEJhZFBhZGRpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIFBLQ1M4RW5jb2RlZEtleVNwZWN9IG9iamVjdCBleHRyYWN0ZWQgZnJvbSB0aGUKKyAgICAgKiBlbmNyeXB0ZWQgZGF0YS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZWNyeXB0S2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IHRvIGRlY3J5cHQgdGhlIGVuY3J5cHRlZCBkYXRhIHdpdGguCisgICAgICogQHBhcmFtIHByb3ZpZGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgYSBwcm92aWRlciB3aG9zZSBjaXBoZXIgaW1wbGVtZW50YXRpb24gc2hvdWxkIGJlCisgICAgICogICAgICAgICAgICB1c2VkLgorICAgICAqIEByZXR1cm4gdGhlIGV4dHJhY3RlZCB7QGNvZGUgUEtDUzhFbmNvZGVkS2V5U3BlY30uCisgICAgICogQHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG5vIHByb3ZpZGVyIHdpdGgge0Bjb2RlIHByb3ZpZGVyTmFtZX0gY2FuIGJlIGZvdW5kLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgbm8gdXNhYmxlIGNpcGhlciBjYW4gYmUgZm91bmQgdG8gZGVjcnlwdCB0aGUgZW5jcnlwdGVkCisgICAgICogICAgICAgICAgICAgZGF0YS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGVjcnlwdEtleX0gaXMgbm90IHVzYWJsZSB0byBkZWNyeXB0IHRoZSBlbmNyeXB0ZWQKKyAgICAgKiAgICAgICAgICAgICBkYXRhLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgZGVjcnlwdEtleX0gb3Ige0Bjb2RlIHByb3ZpZGVyTmFtZX0gaXMge0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICAgICAgLgorICAgICAqLworICAgIHB1YmxpYyBQS0NTOEVuY29kZWRLZXlTcGVjIGdldEtleVNwZWMoS2V5IGRlY3J5cHRLZXksIFN0cmluZyBwcm92aWRlck5hbWUpCisgICAgICAgIHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICBpZiAoZGVjcnlwdEtleSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImRlY3J5cHRLZXkgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChwcm92aWRlck5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJwcm92aWRlck5hbWUgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDaXBoZXIgY2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKGFsZ05hbWUsIHByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICBpZiAoYWxnUGFyYW1ldGVycyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY2lwaGVyLmluaXQoQ2lwaGVyLkRFQ1JZUFRfTU9ERSwgZGVjcnlwdEtleSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGNpcGhlci5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGRlY3J5cHRLZXksIGFsZ1BhcmFtZXRlcnMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnl0ZVtdIGRlY3J5cHRlZERhdGEgPSBjaXBoZXIuZG9GaW5hbChlbmNyeXB0ZWREYXRhKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQVNOMVByaXZhdGVLZXlJbmZvLnZlcmlmeShkZWNyeXB0ZWREYXRhKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUxKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgaW52YWxpZEtleSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBQS0NTOEVuY29kZWRLZXlTcGVjKGRlY3J5cHRlZERhdGEpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hQYWRkaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5RXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoQmFkUGFkZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgUEtDUzhFbmNvZGVkS2V5U3BlY30gb2JqZWN0IGV4dHJhY3RlZCBmcm9tIHRoZQorICAgICAqIGVuY3J5cHRlZCBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIGRlY3J5cHRLZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgdG8gZGVjcnlwdCB0aGUgZW5jcnlwdGVkIGRhdGEgd2l0aC4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm92aWRlciB3aG9zZSBjaXBoZXIgaW1wbGVtZW50YXRpb24gc2hvdWxkIGJlIHVzZWQuCisgICAgICogQHJldHVybiB0aGUgZXh0cmFjdGVkIHtAY29kZSBQS0NTOEVuY29kZWRLZXlTcGVjfS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG5vIHVzYWJsZSBjaXBoZXIgY2FuIGJlIGZvdW5kIHRvIGRlY3J5cHQgdGhlIGVuY3J5cHRlZAorICAgICAqICAgICAgICAgICAgIGRhdGEuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGRlY3J5cHRLZXl9IGlzIG5vdCB1c2FibGUgdG8gZGVjcnlwdCB0aGUgZW5jcnlwdGVkCisgICAgICogICAgICAgICAgICAgZGF0YS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGRlY3J5cHRLZXl9IG9yIHtAY29kZSBwcm92aWRlcn0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBQS0NTOEVuY29kZWRLZXlTcGVjIGdldEtleVNwZWMoS2V5IGRlY3J5cHRLZXksIFByb3ZpZGVyIHByb3ZpZGVyKQorICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChkZWNyeXB0S2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiZGVjcnlwdEtleSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicHJvdmlkZXIgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDaXBoZXIgY2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKGFsZ05hbWUsIHByb3ZpZGVyKTsKKyAgICAgICAgICAgIGlmIChhbGdQYXJhbWV0ZXJzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjaXBoZXIuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLCBkZWNyeXB0S2V5KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgY2lwaGVyLmluaXQoQ2lwaGVyLkRFQ1JZUFRfTU9ERSwgZGVjcnlwdEtleSwgYWxnUGFyYW1ldGVycyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBieXRlW10gZGVjcnlwdGVkRGF0YSA9IGNpcGhlci5kb0ZpbmFsKGVuY3J5cHRlZERhdGEpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBBU04xUHJpdmF0ZUtleUluZm8udmVyaWZ5KGRlY3J5cHRlZERhdGEpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZTEpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBpbnZhbGlkS2V5KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IFBLQ1M4RW5jb2RlZEtleVNwZWMoZGVjcnlwdGVkRGF0YSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFBhZGRpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChCYWRQYWRkaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5RXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgSW52YWxpZEtleUV4Y2VwdGlvbiBpbnZhbGlkS2V5KCkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbigiRGVjcnlwdGVkIGRhdGEgZG9lcyBub3QgcmVwcmVzZW50IHZhbGlkIFBLQ1MjOCBQcml2YXRlS2V5SW5mbyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIEFTTi4xIGVuY29kZWQgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBBU04uMSBlbmNvZGVkIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgb2JqZWN0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBlbmNvZGluZyB0aGlzIG9iamVjdCBmYWlscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoZW5jb2RlZCA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBHZW5lcmF0ZSBBU04uMSBlbmNvZGluZzoKKyAgICAgICAgICAgIGVuY29kZWQgPSBhc24xLmVuY29kZSh0aGlzKTsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gcmV0ID0gbmV3IGJ5dGVbZW5jb2RlZC5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVuY29kZWQsIDAsIHJldCwgMCwgZW5jb2RlZC5sZW5ndGgpOworICAgICAgICByZXR1cm4gcmV0OworICAgIH0KKworICAgIC8vIFBlcmZvcm1zIGFsbCBuZWVkZWQgYWxnIG5hbWUgbWFwcGluZ3MuCisgICAgLy8gUmV0dXJucyAndHJ1ZScgaWYgbWFwcGluZyBhdmFpbGFibGUgJ2ZhbHNlJyBvdGhlcndpc2UKKyAgICBwcml2YXRlIGJvb2xlYW4gbWFwQWxnTmFtZSgpIHsKKyAgICAgICAgaWYgKEFsZ05hbWVNYXBwZXIuaXNPSUQodGhpcy5hbGdOYW1lKSkgeworICAgICAgICAgICAgLy8gT0lEIHByb3ZpZGVkIHRvIHRoZSBjdG9yCisgICAgICAgICAgICAvLyBnZXQgcmlkIG9mIHBvc3NpYmxlIGxlYWRpbmcgIk9JRC4iCisgICAgICAgICAgICB0aGlzLm9pZCA9IEFsZ05hbWVNYXBwZXIubm9ybWFsaXplKHRoaXMuYWxnTmFtZSk7CisgICAgICAgICAgICAvLyB0cnkgdG8gZmluZCBtYXBwaW5nIE9JRC0+YWxnTmFtZQorICAgICAgICAgICAgdGhpcy5hbGdOYW1lID0gQWxnTmFtZU1hcHBlci5tYXAyQWxnTmFtZSh0aGlzLm9pZCk7CisgICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBubyBtYXBwaW5nIE9JRC0+YWxnTmFtZQorICAgICAgICAgICAgLy8gc2V0IE9JRCBhcyBhbGdOYW1lCisgICAgICAgICAgICBpZiAodGhpcy5hbGdOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aGlzLmFsZ05hbWUgPSB0aGlzLm9pZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFN0cmluZyBzdGROYW1lID0gQWxnTmFtZU1hcHBlci5nZXRTdGFuZGFyZE5hbWUodGhpcy5hbGdOYW1lKTsKKyAgICAgICAgICAgIC8vIEFsZyBuYW1lIHByb3ZpZGVkIHRvIHRoZSBjdG9yCisgICAgICAgICAgICAvLyB0cnkgdG8gZmluZCBtYXBwaW5nIGFsZ05hbWUtPk9JRCBvcgorICAgICAgICAgICAgLy8gKGFsZ05hbWUtPnN0ZEFsZ05hbWUpLT5PSUQKKyAgICAgICAgICAgIHRoaXMub2lkID0gQWxnTmFtZU1hcHBlci5tYXAyT0lEKHRoaXMuYWxnTmFtZSk7CisgICAgICAgICAgICBpZiAodGhpcy5vaWQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmIChzdGROYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gbm8gYWJvdmUgbWFwcGluZ3MgYXZhaWxhYmxlCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGhpcy5vaWQgPSBBbGdOYW1lTWFwcGVyLm1hcDJPSUQoc3RkTmFtZSk7CisgICAgICAgICAgICAgICAgaWYgKHRoaXMub2lkID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aGlzLmFsZ05hbWUgPSBzdGROYW1lOworICAgICAgICAgICAgfSBlbHNlIGlmIChzdGROYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aGlzLmFsZ05hbWUgPSBzdGROYW1lOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8vCisgICAgLy8gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gREVSIGVuY29kZXIvZGVjb2Rlci4KKyAgICAvLyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyBBU04uMSBkZWZpbml0aW9uCisgICAgLy8gKGFzIGRlZmluZWQgaW4gUEtDUyAjODogUHJpdmF0ZS1LZXkgSW5mb3JtYXRpb24gU3ludGF4IFN0YW5kYXJkCisgICAgLy8gIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzMTMudHh0KQorICAgIC8vCisgICAgLy8gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gOjo9ICBTRVFVRU5DRSB7CisgICAgLy8gICAgICBlbmNyeXB0aW9uQWxnb3JpdGhtICAgQWxnb3JpdGhtSWRlbnRpZmllciwKKyAgICAvLyAgICAgIGVuY3J5cHRlZERhdGEgICBPQ1RFVCBTVFJJTkcgfQorICAgIC8vCisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gbnVsbFBhcmFtID0gbmV3IGJ5dGVbXSB7IDUsIDAgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBhc24xID0gbmV3IEFTTjFTZXF1ZW5jZShuZXcgQVNOMVR5cGVbXSB7CisgICAgICAgICAgICBBbGdvcml0aG1JZGVudGlmaWVyLkFTTjEsIEFTTjFPY3RldFN0cmluZy5nZXRJbnN0YW5jZSgpIH0pIHsKKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKworICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyBlcGtpID0gKEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKSBvYmplY3Q7CisKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBhbGdQYXJtc0VuY29kZWQgPSAoZXBraS5hbGdQYXJhbWV0ZXJzID09IG51bGwpID8gbnVsbFBhcmFtCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZXBraS5hbGdQYXJhbWV0ZXJzLmdldEVuY29kZWQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlc1swXSA9IG5ldyBBbGdvcml0aG1JZGVudGlmaWVyKGVwa2kub2lkLCBhbGdQYXJtc0VuY29kZWQpOworICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzWzFdID0gZXBraS5lbmNyeXB0ZWREYXRhOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgfTsKKworICAgIC8vIFByaXZhdGVLZXlJbmZvIERFUiBkZWNvZGVyLgorICAgIC8vIFByaXZhdGVLZXlJbmZvIEFTTi4xIGRlZmluaXRpb24KKyAgICAvLyAoYXMgZGVmaW5lZCBpbiBQS0NTICM4OiBQcml2YXRlLUtleSBJbmZvcm1hdGlvbiBTeW50YXggU3RhbmRhcmQKKyAgICAvLyAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjMxMy50eHQpCisgICAgLy8KKyAgICAvLworICAgIC8vICAgIFByaXZhdGVLZXlJbmZvIDo6PSBTRVFVRU5DRSB7CisgICAgLy8gICAgICAgIHZlcnNpb24gVmVyc2lvbiwKKyAgICAvLyAgICAgICAgcHJpdmF0ZUtleUFsZ29yaXRobSBQcml2YXRlS2V5QWxnb3JpdGhtSWRlbnRpZmllciwKKyAgICAvLyAgICAgICAgcHJpdmF0ZUtleSBQcml2YXRlS2V5LAorICAgIC8vICAgICAgICBhdHRyaWJ1dGVzIFswXSBJTVBMSUNJVCBBdHRyaWJ1dGVzIE9QVElPTkFMIH0KKyAgICAvLworICAgIC8vICAgICAgVmVyc2lvbiA6Oj0gSU5URUdFUgorICAgIC8vCisgICAgLy8gICAgICBQcml2YXRlS2V5QWxnb3JpdGhtSWRlbnRpZmllciA6Oj0gQWxnb3JpdGhtSWRlbnRpZmllcgorICAgIC8vCisgICAgLy8gICAgICBQcml2YXRlS2V5IDo6PSBPQ1RFVCBTVFJJTkcKKyAgICAvLworICAgIC8vICAgICAgQXR0cmlidXRlcyA6Oj0gU0VUIE9GIEF0dHJpYnV0ZQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQVNOMVNldE9mIEFTTjFBdHRyaWJ1dGVzID0gbmV3IEFTTjFTZXRPZihBU04xQW55LmdldEluc3RhbmNlKCkpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQVNOMVNlcXVlbmNlIEFTTjFQcml2YXRlS2V5SW5mbyA9IG5ldyBBU04xU2VxdWVuY2UoCisgICAgICAgICAgICBuZXcgQVNOMVR5cGVbXSB7IEFTTjFJbnRlZ2VyLmdldEluc3RhbmNlKCksIEFsZ29yaXRobUlkZW50aWZpZXIuQVNOMSwKKyAgICAgICAgICAgICAgICAgICAgQVNOMU9jdGV0U3RyaW5nLmdldEluc3RhbmNlKCksCisgICAgICAgICAgICAgICAgICAgIG5ldyBBU04xSW1wbGljaXQoMCwgQVNOMUF0dHJpYnV0ZXMpIH0pIHsKKyAgICAgICAgeworICAgICAgICAgICAgc2V0T3B0aW9uYWwoMyk7IC8vYXR0cmlidXRlcyBhcmUgb3B0aW9uYWwKKyAgICAgICAgfQorICAgIH07Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL0V4ZW1wdGlvbk1lY2hhbmlzbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9FeGVtcHRpb25NZWNoYW5pc20uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYWM0OTk0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9FeGVtcHRpb25NZWNoYW5pc20uamF2YQpAQCAtMCwwICsxLDM3NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5mb3J0cmVzcy5FbmdpbmU7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBmdW5jdGlvbmFsaXR5IG9mIGFuIGV4ZW1wdGlvbiBtZWNoYW5pc20gc3VjaCBhcworICogPGk+a2V5IHJlY292ZXJ5PC9pPiwgPGk+a2V5IHdlYWtlbmluZzwvaT4sIG9yIDxpPmtleSBlc2Nyb3c8L2k+LgorICovCitwdWJsaWMgY2xhc3MgRXhlbXB0aW9uTWVjaGFuaXNtIHsKKworICAgIC8vIFVzZWQgdG8gYWNjZXNzIGNvbW1vbiBlbmdpbmUgZnVuY3Rpb25hbGl0eQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEVuZ2luZSBFTkdJTkUgPSBuZXcgRW5naW5lKCJFeGVtcHRpb25NZWNoYW5pc20iKTsKKworICAgIC8vIFN0b3JlIHVzZWQgcHJvdmlkZXIKKyAgICBwcml2YXRlIGZpbmFsIFByb3ZpZGVyIHByb3ZpZGVyOworCisgICAgLy8gU3RvcmUgdXNlZCBzcGkgaW1wbGVtZW50YXRpb24KKyAgICBwcml2YXRlIGZpbmFsIEV4ZW1wdGlvbk1lY2hhbmlzbVNwaSBzcGlJbXBsOworCisgICAgLy8gU3RvcmUgbWVjaGFuaXNtIG5hbWUKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBtZWNoYW5pc207CisKKyAgICAvLyBTdG9yZSBzdGF0ZSAoaW5pdGlhbGl6ZWQgb3Igbm90KQorICAgIHByaXZhdGUgYm9vbGVhbiBpc0luaXQ7CisKKyAgICAvLyBTdG9yZSBpbml0S2V5IHZhbHVlCisgICAgcHJpdmF0ZSBLZXkgaW5pdEtleTsKKworICAgIC8vIEluZGljYXRlcyBpZiBibG9iIGdlbmVyYXRlZCBzdWNjZXNzZnVsbHkKKyAgICBwcml2YXRlIGJvb2xlYW4gZ2VuZXJhdGVkOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHtAY29kZSBFeGVtcHRpb25NZWNoYW5pc219IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIGV4bWVjaFNwaQorICAgICAqICAgICAgICAgICAgdGhlIGltcGxlbWVudGF0aW9uIGRlbGVnYXRlLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIGFzc29jaWF0ZWQgcHJvdmlkZXIuCisgICAgICogQHBhcmFtIG1lY2hhbmlzbQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIG1lY2hhbmlzbS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRXhlbXB0aW9uTWVjaGFuaXNtKEV4ZW1wdGlvbk1lY2hhbmlzbVNwaSBleG1lY2hTcGksCisgICAgICAgICAgICBQcm92aWRlciBwcm92aWRlciwgU3RyaW5nIG1lY2hhbmlzbSkgeworICAgICAgICB0aGlzLm1lY2hhbmlzbSA9IG1lY2hhbmlzbTsKKyAgICAgICAgdGhpcy5zcGlJbXBsID0gZXhtZWNoU3BpOworICAgICAgICB0aGlzLnByb3ZpZGVyID0gcHJvdmlkZXI7CisgICAgICAgIGlzSW5pdCA9IGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhpcyB7QGNvZGUgRXhlbXB0aW9uTWVjaGFuaXNtfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhpcyB7QGNvZGUgRXhlbXB0aW9uTWVjaGFuaXNtfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBtZWNoYW5pc207CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyB7QGNvZGUgRXhlbXB0aW9uTWVjaGFuaXNtfSBpbnN0YW5jZSB0aGF0IHByb3ZpZGVzIHRoZQorICAgICAqIHNwZWNpZmllZCBleGVtcHRpb24gbWVjaGFuaXNtIGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXF1ZXN0ZWQgZXhlbXB0aW9uIG1lY2hhbmlzbS4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcge0Bjb2RlIEV4ZW1wdGlvbk1lY2hhbmlzbX0gaW5zdGFuY2UuCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobSBpcyBub3QgYXZhaWxhYmxlIGJ5IGFueSBwcm92aWRlci4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGFsZ29yaXRobSBwYXJhbWV0ZXIgaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRXhlbXB0aW9uTWVjaGFuaXNtIGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFsZ29yaXRobSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBFbmdpbmUuU3BpQW5kUHJvdmlkZXIgc2FwID0gRU5HSU5FLmdldEluc3RhbmNlKGFsZ29yaXRobSwgbnVsbCk7CisgICAgICAgIHJldHVybiBuZXcgRXhlbXB0aW9uTWVjaGFuaXNtKChFeGVtcHRpb25NZWNoYW5pc21TcGkpIHNhcC5zcGksIHNhcC5wcm92aWRlciwgYWxnb3JpdGhtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBFeGVtcHRpb25NZWNoYW5zbX0gaW5zdGFuY2UgdGhhdCBwcm92aWRlcyB0aGUKKyAgICAgKiBzcGVjaWZpZWQgZXhlbXB0aW9uIG1lY2hhbmlzbSBhbGdvcml0aG0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlcXVlc3RlZCBleGVtcHRpb24gbWVjaGFuaXNtLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIHRoYXQgaXMgcHJvdmlkaW5nIHRoZSBhbGdvcml0aG0uCisgICAgICogQHJldHVybiB0aGUgbmV3IHtAY29kZSBFeGVtcHRpb25NZWNoYW5pc219IGluc3RhbmNlLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0gaXMgbm90IHByb3ZpZGVkIGJ5IHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgICAgICBwcm92aWRlci4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgYWxnb3JpdGhtIHBhcmFtZXRlciBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcHJvdmlkZXIgcGFyYW1ldGVyIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEV4ZW1wdGlvbk1lY2hhbmlzbSBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLAorICAgICAgICAgICAgU3RyaW5nIHByb3ZpZGVyKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicHJvdmlkZXIgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIFByb3ZpZGVyIGltcFByb3ZpZGVyID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXIocHJvdmlkZXIpOworICAgICAgICBpZiAoaW1wUHJvdmlkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uKHByb3ZpZGVyKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRJbnN0YW5jZShhbGdvcml0aG0sIGltcFByb3ZpZGVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IHtAY29kZSBFeGVtcHRpb25NZWNoYW5pc219IGluc3RhbmNlIHRoYXQgcHJvdmlkZXMgdGhlCisgICAgICogc3BlY2lmaWVkIGV4ZW1wdGlvbiBtZWNoYW5pc20gYWxnb3JpdGhtIGZyb20gdGhlIHNwZWNpZmllZCBwcm92aWRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXF1ZXN0ZWQgZXhlbXB0aW9uIG1lY2hhbmlzbS4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm92aWRlciB0aGF0IGlzIHByb3ZpZGluZyB0aGUgYWxnb3JpdGhtLgorICAgICAqIEByZXR1cm4gdGhlIG5ldyB7QGNvZGUgRXhlbXB0aW9uTWVjaGFuaXNtfSBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIGlzIG5vdCBwcm92aWRlZCBieSB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICAgICAgcHJvdmlkZXIuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhbGdvcml0aG0gcGFyYW1ldGVyIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwcm92aWRlciBwYXJhbWV0ZXIgaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRXhlbXB0aW9uTWVjaGFuaXNtIGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sCisgICAgICAgICAgICBQcm92aWRlciBwcm92aWRlcikgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhbGdvcml0aG0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInByb3ZpZGVyID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBPYmplY3Qgc3BpID0gRU5HSU5FLmdldEluc3RhbmNlKGFsZ29yaXRobSwgcHJvdmlkZXIsIG51bGwpOworICAgICAgICByZXR1cm4gbmV3IEV4ZW1wdGlvbk1lY2hhbmlzbSgoRXhlbXB0aW9uTWVjaGFuaXNtU3BpKSBzcGksIHByb3ZpZGVyLCBhbGdvcml0aG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByb3ZpZGVyIG9mIHRoaXMge0Bjb2RlIEV4ZW1wdGlvbk1lY2hhbmlzbX0gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcm92aWRlciBvZiB0aGlzIHtAY29kZSBFeGVtcHRpb25NZWNoYW5pc219IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBQcm92aWRlciBnZXRQcm92aWRlcigpIHsKKyAgICAgICAgcmV0dXJuIHByb3ZpZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgcmVzdWx0IGJsb2IgZm9yIHRoaXMge0Bjb2RlIEV4ZW1wdGlvbk1lY2hhbmlzbX0KKyAgICAgKiBpbnN0YW5jZSBoYXMgYmVlbiBnZW5lcmF0ZWQgc3VjY2Vzc2Z1bGx5IGFuZCB0aGF0IHRoZSBzcGVjaWZpZWQga2V5IGlzCisgICAgICogdGhlIHNhbWUgYXMgdGhlIG9uZSB0aGF0IHdhcyB1c2VkIHRvIGluaXRpYWxpemUgYW5kIGdlbmVyYXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byB2ZXJpZnkuCisgICAgICogQHJldHVybiB3aGV0aGVyIHRoZSByZXN1bHQgYmxvYiBmb3IgdGhpcyB7QGNvZGUgRXhlbXB0aW9uTWVjaGFuaXNtfQorICAgICAqICAgICAgICAgaW5zdGFuY2UgaGFzIGJlZW4gZ2VuZXJhdGVkIHN1Y2Nlc3NmdWxseS4KKyAgICAgKiBAdGhyb3dzIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBkZXRlcm1pbmluZyB3aGV0aGVyIHRoZSByZXN1bHQgYmxvYgorICAgICAqICAgICAgICAgICAgIGhhcyBiZWVuIGdlbmVyYXRlZCBzdWNjZXNzZnVsbHkuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNDcnlwdG9BbGxvd2VkKEtleSBrZXkpCisgICAgICAgICAgICB0aHJvd3MgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIHsKKworICAgICAgICBpZiAoZ2VuZXJhdGVkCisgICAgICAgICAgICAgICAgJiYgKGluaXRLZXkuZXF1YWxzKGtleSkgfHwgQXJyYXlzLmVxdWFscyhpbml0S2V5LmdldEVuY29kZWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGtleS5nZXRFbmNvZGVkKCkpKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNpemUgaW4gYnl0ZXMgZm9yIHRoZSBvdXRwdXQgYnVmZmVyIG5lZWRlZCB0byBob2xkIHRoZSBvdXRwdXQKKyAgICAgKiBvZiB0aGUgbmV4dCB7QGxpbmsgI2dlbkV4ZW1wdGlvbkJsb2J9IGNhbGwsIGdpdmVuIHRoZSBzcGVjaWZpZWQge0Bjb2RlCisgICAgICogaW5wdXRMZW59IChpbiBieXRlcykuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXRMZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpZWQgaW5wdXQgbGVuZ3RoIChpbiBieXRlcykuCisgICAgICogQHJldHVybiB0aGUgc2l6ZSBpbiBieXRlcyBmb3IgdGhlIG91dHB1dCBidWZmZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBFeGVtcHRpb25NZWNoYW5pc219IGluc3RhbmNlIGlzIG5vdAorICAgICAqICAgICAgICAgICAgIGluaXRpYWxpemVkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0T3V0cHV0U2l6ZShpbnQgaW5wdXRMZW4pIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24geworICAgICAgICBpZiAoIWlzSW5pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiRXhlbXB0aW9uTWVjaGFuaXNtIGlzIG5vdCBpbml0aWFsaXplZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZUdldE91dHB1dFNpemUoaW5wdXRMZW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEV4ZW1wdGlvbk1lY2hhbmlzbX0gaW5zdGFuY2Ugd2l0aCB0aGUKKyAgICAgKiBzcGVjaWZpZWQga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2Ugd2l0aC4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUga2V5IGNhbm5vdCBiZSB1c2VkIHRvIGluaXRpYWxpemUgdGhpcyBtZWNoYW5pc20uCisgICAgICogQHRocm93cyBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBlcnJvcihzKSBvY2N1ciBkdXJpbmcgaW5pdGlhbGl6YXRpb24uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdChLZXkga2V5KSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiB7CisgICAgICAgIGdlbmVyYXRlZCA9IGZhbHNlOworICAgICAgICBzcGlJbXBsLmVuZ2luZUluaXQoa2V5KTsKKyAgICAgICAgaW5pdEtleSA9IGtleTsKKyAgICAgICAgaXNJbml0ID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBFeGVtcHRpb25NZWNoYW5pc219IGluc3RhbmNlIHdpdGggdGhlCisgICAgICogc3BlY2lmaWVkIGtleSBhbmQgYWxnb3JpdGhtIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSB3aXRoLgorICAgICAqIEBwYXJhbSBwYXJhbQorICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgZXhlbXB0aW9uIG1lY2hhbmlzbSBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGtleSBjYW5ub3QgYmUgdXNlZCB0byBpbml0aWFsaXplIHRoaXMgbWVjaGFuaXNtLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYXJhbWV0ZXJzIGNhbm5vdCBiZSB1c2VkIHRvIGluaXRpYWxpemUgdGhpcworICAgICAqICAgICAgICAgICAgIG1lY2hhbmlzbS4KKyAgICAgKiBAdGhyb3dzIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVycm9yKHMpIG9jY3VyIGR1cmluZyBpbml0aWFsaXphdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBpbml0KEtleSBrZXksIEFsZ29yaXRobVBhcmFtZXRlcnMgcGFyYW0pCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiB7CisgICAgICAgIGdlbmVyYXRlZCA9IGZhbHNlOworICAgICAgICBzcGlJbXBsLmVuZ2luZUluaXQoa2V5LCBwYXJhbSk7CisgICAgICAgIGluaXRLZXkgPSBrZXk7CisgICAgICAgIGlzSW5pdCA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyB7QGNvZGUgRXhlbXB0aW9uTWVjaGFuaXNtfSBpbnN0YW5jZSB3aXRoIHRoZQorICAgICAqIHNwZWNpZmllZCBrZXkgYW5kIGFsZ29yaXRobSBwYXJhbWV0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2Ugd2l0aC4KKyAgICAgKiBAcGFyYW0gcGFyYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIGV4ZW1wdGlvbiBtZWNoYW5pc20gYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBrZXkgY2Fubm90IGJlIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIG1lY2hhbmlzbS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aGUgdGhlIHBhcmFtZXRlcnMgY2Fubm90IGJlIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGlzCisgICAgICogICAgICAgICAgICAgbWVjaGFuaXNtLgorICAgICAqIEB0aHJvd3MgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZXJyb3Iocykgb2NjdXIgZHVyaW5nIGluaXRpYWxpemF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGluaXQoS2V5IGtleSwgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLCBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIHsKKyAgICAgICAgZ2VuZXJhdGVkID0gZmFsc2U7CisgICAgICAgIHNwaUltcGwuZW5naW5lSW5pdChrZXksIHBhcmFtKTsKKyAgICAgICAgaW5pdEtleSA9IGtleTsKKyAgICAgICAgaXNJbml0ID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgdGhlIHJlc3VsdCBrZXkgYmxvYiBmb3IgdGhpcyBleGVtcHRpb24gbWVjaGFuaXNtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVzdWx0IGtleSBibG9iIGZvciB0aGlzIGV4ZW1wdGlvbiBtZWNoYW5pc20uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIHtAY29kZSBFeGVtcHRpb25NZWNoYW5pc219IGluc3RhbmNlIGlzIG5vdAorICAgICAqICAgICAgICAgICAgIGluaXRpYWxpemVkLgorICAgICAqIEB0aHJvd3MgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZXJyb3Iocykgb2NjdXIgZHVyaW5nIGdlbmVyYXRpb24uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJ5dGVbXSBnZW5FeGVtcHRpb25CbG9iKCkgdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaXNJbml0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJFeGVtcHRpb25NZWNoYW5pc20gaXMgbm90IGluaXRpYWxpemVkIik7CisgICAgICAgIH0KKyAgICAgICAgZ2VuZXJhdGVkID0gZmFsc2U7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBzcGlJbXBsLmVuZ2luZUdlbkV4ZW1wdGlvbkJsb2IoKTsKKyAgICAgICAgZ2VuZXJhdGVkID0gdHJ1ZTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgdGhlIHJlc3VsdCBrZXkgYmxvYiBmb3IgdGhpcyBleGVtcHRpb24gbWVjaGFuaXNtIGFuZCBzdG9yZXMgaXQKKyAgICAgKiBpbnRvIHRoZSB7QGNvZGUgb3V0cHV0fSBidWZmZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0cHV0CisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IGJ1ZmZlciBmb3IgdGhlIHJlc3VsdCBrZXkgYmxvYi4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiB0byB0aGUge0Bjb2RlIG91dHB1dH0gYnVmZmVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgRXhlbXB0aW9uTWVjaGFuaXNtfSBpbnN0YW5jZSBpcyBub3QKKyAgICAgKiAgICAgICAgICAgICBpbml0aWFsaXplZC4KKyAgICAgKiBAdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHByb3ZpZGVkIGJ1ZmZlciBpcyB0b28gc21hbGwgZm9yIHRoZSByZXN1bHQga2V5IGJsb2IuCisgICAgICogQHRocm93cyBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBlcnJvcihzKSBvY2N1ciBkdXJpbmcgZ2VuZXJhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdlbkV4ZW1wdGlvbkJsb2IoYnl0ZVtdIG91dHB1dCkKKyAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24sIFNob3J0QnVmZmVyRXhjZXB0aW9uLAorICAgICAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGdlbkV4ZW1wdGlvbkJsb2Iob3V0cHV0LCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgdGhlIHJlc3VsdCBrZXkgYmxvYiBmb3IgdGhpcyBleGVtcHRpb24gbWVjaGFuaXNtIGFuZCBzdG9yZXMgaXQKKyAgICAgKiBpbnRvIHRoZSB7QGNvZGUgb3V0cHV0fSBidWZmZXIgYXQgb2Zmc2V0IHtAY29kZSBvdXRwdXRPZmZzZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIG91dHB1dAorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBidWZmZXIgZm9yIHRoZSByZXN1bHQga2V5IGJsb2IuCisgICAgICogQHBhcmFtIG91dHB1dE9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgb3V0cHV0IGJ1ZmZlciB0byBzdGFydC4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiB0byB0aGUge0Bjb2RlIG91dHB1dH0gYnVmZmVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyB7QGNvZGUgRXhlbXB0aW9uTWVjaGFuaXNtfSBpbnN0YW5jZSBpcyBub3QKKyAgICAgKiAgICAgICAgICAgICBpbml0aWFsaXplZC4KKyAgICAgKiBAdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHByb3ZpZGVkIGJ1ZmZlciBpcyB0b28gc21hbGwgZm9yIHRoZSByZXN1bHQga2V5IGJsb2IuCisgICAgICogQHRocm93cyBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBlcnJvcihzKSBvY2N1ciBkdXJpbmcgZ2VuZXJhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdlbkV4ZW1wdGlvbkJsb2IoYnl0ZVtdIG91dHB1dCwgaW50IG91dHB1dE9mZnNldCkKKyAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24sIFNob3J0QnVmZmVyRXhjZXB0aW9uLAorICAgICAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc0luaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkV4ZW1wdGlvbk1lY2hhbmlzbSBpcyBub3QgaW5pdGlhbGl6ZWQiKTsKKyAgICAgICAgfQorICAgICAgICBnZW5lcmF0ZWQgPSBmYWxzZTsKKyAgICAgICAgaW50IGxlbiA9IHNwaUltcGwuZW5naW5lR2VuRXhlbXB0aW9uQmxvYihvdXRwdXQsIG91dHB1dE9mZnNldCk7CisgICAgICAgIGdlbmVyYXRlZCA9IHRydWU7CisgICAgICAgIHJldHVybiBsZW47CisgICAgfQorCisgICAgLyoqCisgICAgICogT3ZlcnJpZGUgdG8gY2xlYXIgYW55IGtleSBzdGF0ZSBpbiB0aGUgaW5zdGFuY2UuCisgICAgICovCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3VwZXIuZmluYWxpemUoKTsKKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgIC8vIGZvciBjb25zaXN0ZW5jeSB3aXRoIHRoZSBSSSwgd2UgbXVzdCBvdmVycmlkZSBPYmplY3QuZmluYWxpemUoKSB0bworICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSB0aHJvd3MgY2xhdXNlLgorICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHQpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9FeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmJlOTBkNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbjsKKworLyoqCisgKiBUaGlzIGlzIHRoZSBiYXNlIGNsYXNzIGZvciB7QGNvZGUgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9ufS4KKyAqLworcHVibGljIGNsYXNzIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiBleHRlbmRzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB7CisKKyAgICAvKioKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTU3MjY5OTQyOTI3Nzk1NzEwOUw7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgZXhjZXB0aW9uIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9ufSB3aXRoIG5vIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbigpIHsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9FeGVtcHRpb25NZWNoYW5pc21TcGkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vRXhlbXB0aW9uTWVjaGFuaXNtU3BpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzlhMjdmNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vRXhlbXB0aW9uTWVjaGFuaXNtU3BpLmphdmEKQEAgLTAsMCArMSwxMzAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguY3J5cHRvOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CisKKy8qKgorICogVGhlIDxpPlNlcnZpY2UgUHJvdmlkZXIgSW50ZXJmYWNlPC9pPiAoPGI+U1BJPC9iPikgZGVmaW5pdGlvbiBmb3IgdGhlIHtAY29kZQorICogRXhlbXB0aW9uTWVjaGFuaXNtfSBjbGFzcy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEV4ZW1wdGlvbk1lY2hhbmlzbVNwaSB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBFeGVtcHRpb25NZWNoYW5pc21TcGl9IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBFeGVtcHRpb25NZWNoYW5pc21TcGkoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIHRoZSByZXN1bHQga2V5IGJsb2IgZm9yIHRoaXMgZXhlbXB0aW9uIG1lY2hhbmlzbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBrZXkgYmxvYiBmb3IgdGhpcyBleGVtcHRpb24gbWVjaGFuaXNtLgorICAgICAqIEB0aHJvd3MgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZXJyb3Iocykgb2NjdXIgZHVyaW5nIGdlbmVyYXRpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IGJ5dGVbXSBlbmdpbmVHZW5FeGVtcHRpb25CbG9iKCkKKyAgICAgICAgICAgIHRocm93cyBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgdGhlIHJlc3VsdCBrZXkgYmxvYiBmb3IgdGhpcyBleGVtcHRpb24gbWVjaGFuaXNtIGFuZCBzdG9yZXMgaXQKKyAgICAgKiBpbnRvIHRoZSB7QGNvZGUgb3V0cHV0fSBidWZmZXIgYXQgb2Zmc2V0IHtAY29kZSBvdXRwdXRPZmZzZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIG91dHB1dAorICAgICAqICAgICAgICAgICAgdGhlIG91dHB1dCBidWZmZXIgZm9yIHRoZSByZXN1bHQga2V5IGJsb2IuCisgICAgICogQHBhcmFtIG91dHB1dE9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgb3V0cHV0IGJ1ZmZlciB0byBzdGFydC4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiB0byB0aGUge0Bjb2RlIG91dHB1dH0gYnVmZmVyLgorICAgICAqIEB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcHJvdmlkZWQgYnVmZmVyIGlzIHRvbyBzbWFsbCBmb3IgdGhlIHJlc3VsdCBrZXkgYmxvYi4KKyAgICAgKiBAdGhyb3dzIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVycm9yKHMpIG9jY3VyIGR1cmluZyBnZW5lcmF0aW9uLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBpbnQgZW5naW5lR2VuRXhlbXB0aW9uQmxvYihieXRlW10gb3V0cHV0LAorICAgICAgICAgICAgaW50IG91dHB1dE9mZnNldCkgdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uLAorICAgICAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2l6ZSBpbiBieXRlcyBmb3IgdGhlIG91dHB1dCBidWZmZXIgbmVlZGVkIHRvIGhvbGQgdGhlIG91dHB1dAorICAgICAqIG9mIHRoZSBuZXh0IHtAbGluayAjZW5naW5lR2VuRXhlbXB0aW9uQmxvYn0gY2FsbCwgZ2l2ZW4gdGhlIHNwZWNpZmllZAorICAgICAqIHtAY29kZSBpbnB1dExlbn0gKGluIGJ5dGVzKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dExlbgorICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBpbnB1dCBsZW5ndGggKGluIGJ5dGVzKS4KKyAgICAgKiBAcmV0dXJuIHRoZSBzaXplIGluIGJ5dGVzIGZvciB0aGUgb3V0cHV0IGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW50IGVuZ2luZUdldE91dHB1dFNpemUoaW50IGlucHV0TGVuKTsKKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEV4ZW1wdGlvbk1lY2hhbmlzbX0gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICoga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2Ugd2l0aC4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUga2V5IGNhbm5vdCBiZSB1c2VkIHRvIGluaXRpYWxpemUgdGhpcyBtZWNoYW5pc20uCisgICAgICogQHRocm93cyBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBlcnJvcihzKSBvY2N1ciBkdXJpbmcgaW5pdGlhbGl6YXRpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgZW5naW5lSW5pdChLZXkga2V5KSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEV4ZW1wdGlvbk1lY2hhbmlzbX0gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICoga2V5IGFuZCBhbGdvcml0aG0gcGFyYW1ldGVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIHdpdGguCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgZXhlbXB0aW9uIG1lY2hhbmlzbSBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGtleSBjYW5ub3QgYmUgdXNlZCB0byBpbml0aWFsaXplIHRoaXMgbWVjaGFuaXNtLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYXJhbWV0ZXJzIGNhbm5vdCBiZSB1c2VkIHRvIGluaXRpYWxpemUgdGhpcworICAgICAqICAgICAgICAgICAgIG1lY2hhbmlzbS4KKyAgICAgKiBAdGhyb3dzIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGVycm9yKHMpIG9jY3VyIGR1cmluZyBpbml0aWFsaXphdGlvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBlbmdpbmVJbml0KEtleSBrZXksIEFsZ29yaXRobVBhcmFtZXRlcnMgcGFyYW1zKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24sIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24sCisgICAgICAgICAgICBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBFeGVtcHRpb25NZWNoYW5pc219IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIGtleSBhbmQgYWxnb3JpdGhtIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSB3aXRoLgorICAgICAqIEBwYXJhbSBwYXJhbXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIGV4ZW1wdGlvbiBtZWNoYW5pc20gYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBrZXkgY2Fubm90IGJlIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIG1lY2hhbmlzbS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aGUgdGhlIHBhcmFtZXRlcnMgY2Fubm90IGJlIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGlzCisgICAgICogICAgICAgICAgICAgbWVjaGFuaXNtLgorICAgICAqIEB0aHJvd3MgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZXJyb3Iocykgb2NjdXIgZHVyaW5nIGluaXRpYWxpemF0aW9uLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGVuZ2luZUluaXQoS2V5IGtleSwgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbjsKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL0lsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBmZDVhODMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL0lsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQ5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LmNyeXB0bzsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uOworCisvKioKKyAqIFRoZSBleGNlcHRpb24sIHRoYXQgaXMgdGhyb3duIHdoZW4gdGhlIGRhdGEgbGVuZ3RoIHByb3ZpZGVkIHRvIGEgYmxvY2sgY2lwaGVyCisgKiBkb2VzIG5vdCBtYXRjaCB0aGUgYmxvY2sgc2l6ZSBvZiB0aGUgY2lwaGVyLgorICovCitwdWJsaWMgY2xhc3MgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiBleHRlbmRzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB7CisKKyAgICAvKioKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTE5NjUxNDQ4MTE5NTM1NDAzOTJMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbn0gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24oU3RyaW5nIG1zZykgeworICAgICAgICBzdXBlcihtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uKCkgeworICAgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL0tleUFncmVlbWVudC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9LZXlBZ3JlZW1lbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YzVkODZjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9LZXlBZ3JlZW1lbnQuamF2YQpAQCAtMCwwICsxLDMxNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5mb3J0cmVzcy5FbmdpbmU7CisKKy8qKgorICogVGhpcyBjbGFzcyBwcm92aWRlcyB0aGUgZnVuY3Rpb25hbGl0eSBmb3IgYSBrZXkgZXhjaGFuZ2UgcHJvdG9jb2wuIFRoaXMKKyAqIGVuYWJsZXMgdHdvIG9yIG1vcmUgcGFydGllcyB0byBhZ3JlZSBvbiBhIHNlY3JldCBrZXkgZm9yIHN5bW1ldHJpYworICogY3J5cHRvZ3JhcGh5LgorICovCitwdWJsaWMgY2xhc3MgS2V5QWdyZWVtZW50IHsKKworICAgIC8vIFVzZWQgdG8gYWNjZXNzIGNvbW1vbiBlbmdpbmUgZnVuY3Rpb25hbGl0eQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEVuZ2luZSBFTkdJTkUgPSBuZXcgRW5naW5lKCJLZXlBZ3JlZW1lbnQiKTsKKworICAgIC8vIFN0b3JlIFNlY3VyZVJhbmRvbQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFNlY3VyZVJhbmRvbSBSQU5ET00gPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisKKyAgICAvLyBTdG9yZSB1c2VkIHByb3ZpZGVyCisgICAgcHJpdmF0ZSBmaW5hbCBQcm92aWRlciBwcm92aWRlcjsKKworICAgIC8vIFN0b3JlIHVzZWQgc3BpIGltcGxlbWVudGF0aW9uCisgICAgcHJpdmF0ZSBmaW5hbCBLZXlBZ3JlZW1lbnRTcGkgc3BpSW1wbDsKKworICAgIC8vIFN0b3JlIHVzZWQgYWxnb3JpdGhtIG5hbWUKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBhbGdvcml0aG07CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBLZXlBZ3JlZW1lbnR9IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIGtleUFncmVlU3BpCisgICAgICogICAgICAgICAgICB0aGUgPGI+U1BJPC9iPiBkZWxlZ2F0ZS4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm92aWRlciBwcm92aWRpbmcgdGhpcyBLZXlBZ3JlZW1lbnQuCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGtleSBhZ3JlZW1lbnQgYWxnb3JpdGhtLgorICAgICAqLworICAgIHByb3RlY3RlZCBLZXlBZ3JlZW1lbnQoS2V5QWdyZWVtZW50U3BpIGtleUFncmVlU3BpLCBQcm92aWRlciBwcm92aWRlciwKKyAgICAgICAgICAgIFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgdGhpcy5wcm92aWRlciA9IHByb3ZpZGVyOworICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICAgICAgdGhpcy5zcGlJbXBsID0ga2V5QWdyZWVTcGk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUga2V5IGFncmVlbWVudCBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBrZXkgYWdyZWVtZW50IGFsZ29yaXRobS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgcmV0dXJuIGFsZ29yaXRobTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcm92aWRlciBmb3IgdGhpcyB7QGNvZGUgS2V5QWdyZWVtZW50fSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByb3ZpZGVyIGZvciB0aGlzIHtAY29kZSBLZXlBZ3JlZW1lbnR9IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBQcm92aWRlciBnZXRQcm92aWRlcigpIHsKKyAgICAgICAgcmV0dXJuIHByb3ZpZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEtleUFncmVlbWVudH0gZm9yIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGtleSBhZ3JlZW1lbnQgYWxnb3JpdGhtIHRvIGNyZWF0ZS4KKyAgICAgKiBAcmV0dXJuIGEga2V5IGFncmVlbWVudCBmb3IgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBpbnN0YWxsZWQgcHJvdmlkZXIgY2FuIHByb3ZpZGUgdGhlIHJlcXVlc3RlZCBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEtleUFncmVlbWVudCBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhbGdvcml0aG0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgRW5naW5lLlNwaUFuZFByb3ZpZGVyIHNhcCA9IEVOR0lORS5nZXRJbnN0YW5jZShhbGdvcml0aG0sIG51bGwpOworICAgICAgICByZXR1cm4gbmV3IEtleUFncmVlbWVudCgoS2V5QWdyZWVtZW50U3BpKSBzYXAuc3BpLCBzYXAucHJvdmlkZXIsIGFsZ29yaXRobSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgS2V5QWdyZWVtZW50fSBmb3IgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0gZnJvbSB0aGUKKyAgICAgKiBzcGVjaWZpZWQgcHJvdmlkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUga2V5IGFncmVlbWVudCBhbGdvcml0aG0gdG8gY3JlYXRlLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIHRoYXQgcHJvdmlkZXMgdGhlIHJlcXVlc3RlZAorICAgICAqICAgICAgICAgICAgYWxnb3JpdGhtLgorICAgICAqIEByZXR1cm4gYSBrZXkgYWdyZWVtZW50IGZvciB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobSBmcm9tIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIHByb3ZpZGVyLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBjYW5ub3QgcHJvdmlkZSB0aGUgcmVxdWVzdGVkCisgICAgICogICAgICAgICAgICAgYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGRvZXMgbm90IGV4aXN0LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBuYW1lIGlzIHtAY29kZSBudWxsfSBvciBlbXB0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEtleUFncmVlbWVudCBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLAorICAgICAgICAgICAgU3RyaW5nIHByb3ZpZGVyKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCB8fCBwcm92aWRlci5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlByb3ZpZGVyIGlzIG51bGwgb3IgZW1wdHkiKTsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBpbXBQcm92aWRlciA9IFNlY3VyaXR5LmdldFByb3ZpZGVyKHByb3ZpZGVyKTsKKyAgICAgICAgaWYgKGltcFByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbihwcm92aWRlcik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEluc3RhbmNlKGFsZ29yaXRobSwgaW1wUHJvdmlkZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyB7QGNvZGUgS2V5QWdyZWVtZW50fSBmb3IgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0gZnJvbSB0aGUKKyAgICAgKiBzcGVjaWZpZWQgcHJvdmlkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUga2V5IGFncmVlbWVudCBhbGdvcml0aG0gdG8gY3JlYXRlLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHByb3ZpZGVyIHRoYXQgcHJvdmlkZXMgdGhlIHJlcXVlc3RlZCBhbGdvcml0aG0uCisgICAgICogQHJldHVybiBhIGtleSBhZ3JlZW1lbnQgZm9yIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIGZyb20gdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgcHJvdmlkZXIuCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGNhbm5vdCBwcm92aWRlIHRoZSByZXF1ZXN0ZWQKKyAgICAgKiAgICAgICAgICAgICBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0gbmFtZSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBLZXlBZ3JlZW1lbnQgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwKKyAgICAgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInByb3ZpZGVyID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIE9iamVjdCBzcGkgPSBFTkdJTkUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBwcm92aWRlciwgbnVsbCk7CisgICAgICAgIHJldHVybiBuZXcgS2V5QWdyZWVtZW50KChLZXlBZ3JlZW1lbnRTcGkpIHNwaSwgcHJvdmlkZXIsIGFsZ29yaXRobSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyB7QGNvZGUgS2V5QWdyZWVtZW50fSB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byBpbml0aWFsaXplIHRoaXMga2V5IGFncmVlbWVudC4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgdXNlZCB0byBpbml0aWFsaXplIHRoaXMga2V5CisgICAgICogICAgICAgICAgICAgYWdyZWVtZW50LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGluaXQoS2V5IGtleSkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICBzcGlJbXBsLmVuZ2luZUluaXQoa2V5LCBSQU5ET00pOy8vbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBLZXlBZ3JlZW1lbnR9IHdpdGggdGhlIHNwZWNpZmllZCBrZXkgYW5kIHRoZQorICAgICAqIHNwZWNpZmllZCByYW5kb21uZXNzIHNvdXJjZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgdG8gaW5pdGlhbGl6ZSB0aGlzIGtleSBhZ3JlZW1lbnQuCisgICAgICogQHBhcmFtIHJhbmRvbQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBmb3IgYW55IHJhbmRvbW5lc3MgbmVlZGVkLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbm5vdCBiZSB1c2VkIHRvIGluaXRpYWxpemUgdGhpcyBrZXkKKyAgICAgKiAgICAgICAgICAgICBhZ3JlZW1lbnQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdChLZXkga2V5LCBTZWN1cmVSYW5kb20gcmFuZG9tKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICBzcGlJbXBsLmVuZ2luZUluaXQoa2V5LCByYW5kb20pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEtleUFncmVlbWVudH0gd2l0aCB0aGUgc3BlY2lmaWVkIGtleSBhbmQgdGhlCisgICAgICogYWxnb3JpdGhtIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IHRvIGluaXRpYWxpemUgdGhpcyBrZXkgYWdyZWVtZW50LgorICAgICAqIEBwYXJhbSBwYXJhbXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIGtleSBhZ3JlZW1lbnQgYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbm5vdCBiZSB1c2VkIHRvIGluaXRpYWxpemUgdGhpcyBrZXkKKyAgICAgKiAgICAgICAgICAgICBhZ3JlZW1lbnQuCisgICAgICogQHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzIGFyZSBpbnZhbGlkIGZvciB0aGlzIGtleQorICAgICAqICAgICAgICAgICAgIGFncmVlbWVudCBhbGdvcml0aG0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdChLZXkga2V5LCBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtcykKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLCBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgc3BpSW1wbC5lbmdpbmVJbml0KGtleSwgcGFyYW1zLCBSQU5ET00pOy8vbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBLZXlBZ3JlZW1lbnR9IHdpdGggdGhlIHNwZWNpZmllZCBrZXksIGFsZ29yaXRobQorICAgICAqIHBhcmFtZXRlcnMgYW5kIHJhbmRvbW5lc3Mgc291cmNlLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byBpbml0aWFsaXplIHRoaXMga2V5IGFncmVlbWVudC4KKyAgICAgKiBAcGFyYW0gcGFyYW1zCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVycyBmb3IgdGhpcyBrZXkgYWdyZWVtZW50IGFsZ29yaXRobS4KKyAgICAgKiBAcGFyYW0gcmFuZG9tCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGZvciBhbnkgcmFuZG9tbmVzcyBuZWVkZWQuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGtleQorICAgICAqICAgICAgICAgICAgIGFncmVlbWVudC4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMgYXJlIGludmFsaWQgZm9yIHRoaXMga2V5CisgICAgICogICAgICAgICAgICAgYWdyZWVtZW50IGFsZ29yaXRobS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBpbml0KEtleSBrZXksIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1zLAorICAgICAgICAgICAgU2VjdXJlUmFuZG9tIHJhbmRvbSkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgc3BpSW1wbC5lbmdpbmVJbml0KGtleSwgcGFyYW1zLCByYW5kb20pOworICAgIH0KKworICAgIC8qKgorICAgICAqIERvZXMgdGhlIG5leHQgKG9yIHRoZSBsYXN0KSBwaGFzZSBvZiB0aGUga2V5IGFncmVlbWVudCwgdXNpbmcgdGhlCisgICAgICogc3BlY2lmaWVkIGtleS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgcmVjZWl2ZWQgZnJvbSB0aGUgb3RoZXIgcGFydHkgZm9yIHRoaXMgcGhhc2UuCisgICAgICogQHBhcmFtIGxhc3RQaGFzZQorICAgICAqICAgICAgICAgICAgc2V0IHRvIHtAY29kZSB0cnVlfSBpZiB0aGlzIGlzIHRoZSBsYXN0IHBoYXNlIG9mIHRoaXMga2V5CisgICAgICogICAgICAgICAgICBhZ3JlZW1lbnQuCisgICAgICogQHJldHVybiB0aGUgaW50ZXJtZWRpYXRlIGtleSBmcm9tIHRoaXMgcGhhc2Ugb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzCisgICAgICogICAgICAgICBubyBpbnRlcm1lZGlhdGUga2V5IGZvciB0aGlzIHBoYXNlLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbm5vdCBiZSB1c2VkIGluIHRoaXMga2V5IGFncmVlbWVudCBvcgorICAgICAqICAgICAgICAgICAgIHRoaXMgcGhhc2UsCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGluc3RhbmNlIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgS2V5IGRvUGhhc2UoS2V5IGtleSwgYm9vbGVhbiBsYXN0UGhhc2UpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lRG9QaGFzZShrZXksIGxhc3RQaGFzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIHRoZSBzaGFyZWQgc2VjcmV0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZ2VuZXJhdGVkIHNoYXJlZCBzZWNyZXQuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGtleSBhZ3JlZW1lbnQgaXMgbm90IGNvbXBsZXRlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBieXRlW10gZ2VuZXJhdGVTZWNyZXQoKSB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lR2VuZXJhdGVTZWNyZXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgdGhlIHNoYXJlZCBzZWNyZXQgYW5kIHN0b3JlcyBpdCBpbnRvIHRoZSBidWZmZXIge0Bjb2RlCisgICAgICogc2hhcmVkU2VjcmVkfSBhdCB7QGNvZGUgb2Zmc2V0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaGFyZWRTZWNyZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXIgdG8gc3RvcmUgdGhlIHNoYXJlZCBzZWNyZXQuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgYnVmZmVyLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBzdG9yZWQgaW4gdGhlIGJ1ZmZlci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMga2V5IGFncmVlbWVudCBpcyBub3QgY29tcGxldGUuCisgICAgICogQHRocm93cyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYnVmZmVyIGlzIHRvbyBzbWFsbCBmb3IgdGhlIHNoYXJlZCBzZWNyZXQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZW5lcmF0ZVNlY3JldChieXRlW10gc2hhcmVkU2VjcmV0LCBpbnQgb2Zmc2V0KQorICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiwgU2hvcnRCdWZmZXJFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVHZW5lcmF0ZVNlY3JldChzaGFyZWRTZWNyZXQsIG9mZnNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIHRoZSBzaGFyZWQgc2VjcmV0LgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIGFsZ29yaXRobSB0byBmb3IgdGhlIHtAY29kZSBTZWNyZXRLZXl9CisgICAgICogQHJldHVybiB0aGUgc2hhcmVkIHNlY3JldCBhcyBhIHtAY29kZSBTZWNyZXRLZXl9IG9mIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIGFsZ29yaXRobS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMga2V5IGFncmVlbWVudCBpcyBub3QgY29tcGxldGUuCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobSBmb3IgdGhlIHNlY3JldCBrZXkgZG9lcyBub3QKKyAgICAgKiAgICAgICAgICAgICBleGlzdHMuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSB7QGNvZGUgU2VjcmV0S2V5fSB3aXRoIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIGNhbm5vdCBiZQorICAgICAqICAgICAgICAgICAgIGNyZWF0ZWQgdXNpbmcgdGhlIGdlbmVyYXRlZCBzaGFyZWQgc2VjcmV0LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTZWNyZXRLZXkgZ2VuZXJhdGVTZWNyZXQoU3RyaW5nIGFsZ29yaXRobSkKKyAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVHZW5lcmF0ZVNlY3JldChhbGdvcml0aG0pOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9LZXlBZ3JlZW1lbnRTcGkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vS2V5QWdyZWVtZW50U3BpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTAxMTE4MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vS2V5QWdyZWVtZW50U3BpLmphdmEKQEAgLTAsMCArMSwxNDEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguY3J5cHRvOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKKworLyoqCisgKiBUaGUgPGk+U2VydmljZSBQcm92aWRlciBJbnRlcmZhY2U8L2k+ICg8Yj5TUEk8L2I+KSBkZWZpbml0aW9uIGZvciB0aGUKKyAqIHtAY29kZSBLZXlBZ3JlZW1lbnR9IGNsYXNzLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgS2V5QWdyZWVtZW50U3BpIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEtleUFncmVlbWVudFNwaX0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIEtleUFncmVlbWVudFNwaSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb2VzIHRoZSBuZXh0IChvciB0aGUgbGFzdCkgcGhhc2Ugb2YgdGhlIGtleSBhZ3JlZW1lbnQsIHVzaW5nIHRoZQorICAgICAqIHNwZWNpZmllZCBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IHJlY2VpdmVkIGZyb20gdGhlIG90aGVyIHBhcnR5IGZvciB0aGlzIHBoYXNlLgorICAgICAqIEBwYXJhbSBsYXN0UGhhc2UKKyAgICAgKiAgICAgICAgICAgIHNldCB0byB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBpcyB0aGUgbGFzdCBwaGFzZSBvZiB0aGlzIGtleQorICAgICAqICAgICAgICAgICAgYWdyZWVtZW50LgorICAgICAqIEByZXR1cm4gdGhlIGludGVybWVkaWF0ZSBrZXkgZnJvbSB0aGlzIHBoYXNlIG9yIG51bGwgaWYgdGhlcmUgaXMgbm8KKyAgICAgKiAgICAgICAgIGludGVybWVkaWF0ZSBrZXkgZm9yIHRoaXMgcGhhc2UuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIHVzZWQgaW4gdGhpcyBrZXkgYWdyZWVtZW50IG9yCisgICAgICogICAgICAgICAgICAgdGhpcyBwaGFzZSwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgaW5zdGFuY2UgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBLZXkgZW5naW5lRG9QaGFzZShLZXkga2V5LCBib29sZWFuIGxhc3RQaGFzZSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLCBJbGxlZ2FsU3RhdGVFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgdGhlIHNoYXJlZCBzZWNyZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBnZW5lcmF0ZWQgc2hhcmVkIHNlY3JldC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMga2V5IGFncmVlbWVudCBpcyBub3QgY29tcGxldGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IGJ5dGVbXSBlbmdpbmVHZW5lcmF0ZVNlY3JldCgpCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIHRoZSBzaGFyZWQgc2VjcmV0IGFuZCBzdG9yZXMgaXQgaW50byB0aGUgYnVmZmVyIHtAY29kZQorICAgICAqIHNoYXJlZFNlY3JlZH0gYXQge0Bjb2RlIG9mZnNldH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2hhcmVkU2VjcmV0CisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHRvIHN0b3JlIHRoZSBzaGFyZWQgc2VjcmV0LgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIGJ1ZmZlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgc3RvcmVkIGluIHRoZSBidWZmZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGtleSBhZ3JlZW1lbnQgaXMgbm90IGNvbXBsZXRlLgorICAgICAqIEB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGJ1ZmZlciBpcyB0b28gc21hbGwgZm9yIHRoZSBzaGFyZWQgc2VjcmV0LgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBpbnQgZW5naW5lR2VuZXJhdGVTZWNyZXQoYnl0ZVtdIHNoYXJlZFNlY3JldCwgaW50IG9mZnNldCkKKyAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24sIFNob3J0QnVmZmVyRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIHRoZSBzaGFyZWQgc2VjcmV0LgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIGFsZ29yaXRobSB0byBmb3IgdGhlIHtAY29kZSBTZWNyZXRLZXl9CisgICAgICogQHJldHVybiB0aGUgc2hhcmVkIHNlY3JldCBhcyBhIHtAY29kZSBTZWNyZXRLZXl9IG9mIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgIGFsZ29yaXRobS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMga2V5IGFncmVlbWVudCBpcyBub3QgY29tcGxldGUuCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobSBmb3IgdGhlIHNlY3JldCBrZXkgZG9lcyBub3QKKyAgICAgKiAgICAgICAgICAgICBleGlzdHMuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSB7QGNvZGUgU2VjcmV0S2V5fSB3aXRoIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIGNhbm5vdCBiZQorICAgICAqICAgICAgICAgICAgIGNyZWF0ZWQgdXNpbmcgdGhlIGdlbmVyYXRlZCBzaGFyZWQgc2VjcmV0LgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBTZWNyZXRLZXkgZW5naW5lR2VuZXJhdGVTZWNyZXQoU3RyaW5nIGFsZ29yaXRobSkKKyAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBLZXlBZ3JlZW1lbnRTcGl9IHdpdGggdGhlIHNwZWNpZmllZCBrZXkgYW5kIHRoZQorICAgICAqIHNwZWNpZmllZCByYW5kb21uZXNzIHNvdXJjZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgdG8gaW5pdGlhbGl6ZSB0aGlzIGtleSBhZ3JlZW1lbnQuCisgICAgICogQHBhcmFtIHJhbmRvbQorICAgICAqICAgICAgICAgICAgdGhlIHNvdXJjZSBmb3IgYW55IHJhbmRvbW5lc3MgbmVlZGVkLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbm5vdCBiZSB1c2VkIHRvIGluaXRpYWxpemUgdGhpcyBrZXkKKyAgICAgKiAgICAgICAgICAgICBhZ3JlZW1lbnQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgZW5naW5lSW5pdChLZXkga2V5LCBTZWN1cmVSYW5kb20gcmFuZG9tKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBLZXlBZ3JlZW1lbnRTcGl9IHdpdGggdGhlIHNwZWNpZmllZCBrZXksCisgICAgICogYWxnb3JpdGhtIHBhcmFtZXRlcnMgYW5kIHJhbmRvbW5lc3Mgc291cmNlLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byBpbml0aWFsaXplIHRoaXMga2V5IGFncmVlbWVudC4KKyAgICAgKiBAcGFyYW0gcGFyYW1zCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVycyBmb3IgdGhpcyBrZXkgYWdyZWVtZW50IGFsZ29yaXRobS4KKyAgICAgKiBAcGFyYW0gcmFuZG9tCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGZvciBhbnkgcmFuZG9tbmVzcyBuZWVkZWQuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGtleQorICAgICAqICAgICAgICAgICAgIGFncmVlbWVudC4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMgYXJlIGludmFsaWQgZm9yIHRoaXMga2V5CisgICAgICogICAgICAgICAgICAgYWdyZWVtZW50IGFsZ29yaXRobS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBlbmdpbmVJbml0KEtleSBrZXksIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1zLAorICAgICAgICAgICAgU2VjdXJlUmFuZG9tIHJhbmRvbSkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vS2V5R2VuZXJhdG9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL0tleUdlbmVyYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc3YjFhODIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL0tleUdlbmVyYXRvci5qYXZhCkBAIC0wLDAgKzEsMjQyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LmNyeXB0bzsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuZm9ydHJlc3MuRW5naW5lOworCisKKy8qKgorICogVGhpcyBjbGFzcyBwcm92aWRlcyB0aGUgcHVibGljIEFQSSBmb3IgZ2VuZXJhdGluZyBzeW1tZXRyaWMgY3J5cHRvZ3JhcGhpYworICoga2V5cy4KKyAqLworcHVibGljIGNsYXNzIEtleUdlbmVyYXRvciB7CisKKyAgICAvLyBVc2VkIHRvIGFjY2VzcyBjb21tb24gZW5naW5lIGZ1bmN0aW9uYWxpdHkKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFbmdpbmUgRU5HSU5FID0gbmV3IEVuZ2luZSgiS2V5R2VuZXJhdG9yIik7CisKKyAgICAvLyBTdG9yZSBTZWN1cmVSYW5kb20KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTZWN1cmVSYW5kb20gUkFORE9NID0gbmV3IFNlY3VyZVJhbmRvbSgpOworCisgICAgLy8gU3RvcmUgdXNlZCBwcm92aWRlcgorICAgIHByaXZhdGUgZmluYWwgUHJvdmlkZXIgcHJvdmlkZXI7CisKKyAgICAvLyBTdG9yZSB1c2VkIHNwaSBpbXBsZW1lbnRhdGlvbgorICAgIHByaXZhdGUgZmluYWwgS2V5R2VuZXJhdG9yU3BpIHNwaUltcGw7CisKKyAgICAvLyBTdG9yZSB1c2VkIGFsZ29yaXRobSBuYW1lCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgYWxnb3JpdGhtOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgS2V5R2VuZXJhdG9yfSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXlHZW5TcGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbXBsZW1lbnRhdGlvbiBkZWxlZ2F0ZS4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbXBsZW1lbnRhdGlvbiBwcm92aWRlci4KKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtLgorICAgICAqLworICAgIHByb3RlY3RlZCBLZXlHZW5lcmF0b3IoS2V5R2VuZXJhdG9yU3BpIGtleUdlblNwaSwgUHJvdmlkZXIgcHJvdmlkZXIsCisgICAgICAgICAgICBTdHJpbmcgYWxnb3JpdGhtKSB7CisgICAgICAgIHRoaXMucHJvdmlkZXIgPSBwcm92aWRlcjsKKyAgICAgICAgdGhpcy5hbGdvcml0aG0gPSBhbGdvcml0aG07CisgICAgICAgIHRoaXMuc3BpSW1wbCA9IGtleUdlblNwaTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBrZXkgZ2VuZXJhdGlvbiBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBrZXkgZ2VuZXJhdGlvbiBhbGdvcml0aG0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiBhbGdvcml0aG07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJvdmlkZXIgb2YgdGhpcyB7QGNvZGUgS2V5R2VuZXJhdG9yfSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByb3ZpZGVyIG9mIHRoaXMge0Bjb2RlIEtleUdlbmVyYXRvcn0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFByb3ZpZGVyIGdldFByb3ZpZGVyKCkgeworICAgICAgICByZXR1cm4gcHJvdmlkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgS2V5R2VuZXJhdG9yfSBpbnN0YW5jZSB0aGF0IHByb3ZpZGVzIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBrZXkgYWxnb3JpdGhtLAorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlcXVlc3RlZCBrZXkgYWxnb3JpdGhtCisgICAgICogQHJldHVybiB0aGUgbmV3IHtAY29kZSBLZXlHZW5lcmF0b3J9IGluc3RhbmNlLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZSBieSBhbnkgcHJvdmlkZXIuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhbGdvcml0aG19IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEtleUdlbmVyYXRvciBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhbGdvcml0aG0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgRW5naW5lLlNwaUFuZFByb3ZpZGVyIHNhcCA9IEVOR0lORS5nZXRJbnN0YW5jZShhbGdvcml0aG0sIG51bGwpOworICAgICAgICByZXR1cm4gbmV3IEtleUdlbmVyYXRvcigoS2V5R2VuZXJhdG9yU3BpKSBzYXAuc3BpLCBzYXAucHJvdmlkZXIsIGFsZ29yaXRobSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgS2V5R2VuZXJhdG9yfSBpbnN0YW5jZSB0aGF0IHByb3ZpZGVzIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBrZXkgYWxnb3JpdGhtIGZyb20gdGhlIHNwZWNpZmllZCBwcm92aWRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXF1ZXN0ZWQga2V5IGFsZ29yaXRobS4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSBwcm92aWRlciB0aGF0IGlzIHByb3ZpZGluZyB0aGUgYWxnb3JpdGhtLgorICAgICAqIEByZXR1cm4gdGhlIG5ldyB7QGNvZGUgS2V5R2VuZXJhdG9yfSBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIGlzIG5vdCBwcm92aWRlZCBieSB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICAgICAgcHJvdmlkZXIuCisgICAgICogQHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgaXMgbmFtZSBpcyB7QGNvZGUgbnVsbH0gb3IgZW1wdHkuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIG5hbWUgaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgS2V5R2VuZXJhdG9yIGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sCisgICAgICAgICAgICBTdHJpbmcgcHJvdmlkZXIpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwgfHwgcHJvdmlkZXIuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQcm92aWRlciBpcyBudWxsIG9yIGVtcHR5Iik7CisgICAgICAgIH0KKyAgICAgICAgUHJvdmlkZXIgaW1wUHJvdmlkZXIgPSBTZWN1cml0eS5nZXRQcm92aWRlcihwcm92aWRlcik7CisgICAgICAgIGlmIChpbXBQcm92aWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24ocHJvdmlkZXIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRJbnN0YW5jZShhbGdvcml0aG0sIGltcFByb3ZpZGVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBLZXlHZW5lcmF0b3J9IGluc3RhbmNlIHRoYXQgcHJvdmlkZXMgdGhlIHNwZWNpZmllZAorICAgICAqIGtleSBhbGdvcml0aG0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlcXVlc3RlZCBrZXkgYWxnb3JpdGhtLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHByb3ZpZGVyIHRoYXQgaXMgcHJvdmlkaW5nIHRoZSBhbGdvcml0aG0KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXcge0Bjb2RlIEtleUdlbmVyYXRvcn0gaW5zdGFuY2UuCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobSBpcyBub3QgcHJvdmlkZWQgYnkgdGhlIHNwZWNpZmllZAorICAgICAqICAgICAgICAgICAgIHByb3ZpZGVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIG5hbWUgaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgS2V5R2VuZXJhdG9yIGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sCisgICAgICAgICAgICBQcm92aWRlciBwcm92aWRlcikgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwcm92aWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJwcm92aWRlciA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFsZ29yaXRobSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBPYmplY3Qgc3BpID0gRU5HSU5FLmdldEluc3RhbmNlKGFsZ29yaXRobSwgcHJvdmlkZXIsIG51bGwpOworICAgICAgICByZXR1cm4gbmV3IEtleUdlbmVyYXRvcigoS2V5R2VuZXJhdG9yU3BpKSBzcGksIHByb3ZpZGVyLCBhbGdvcml0aG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdlbmVyYXRlcyBhIHNlY3JldCBrZXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBnZW5lcmF0ZWQgc2VjcmV0IGtleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU2VjcmV0S2V5IGdlbmVyYXRlS2V5KCkgeworICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVHZW5lcmF0ZUtleSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEtleUdlbmVyYXRvcn0gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogYWxnb3JpdGhtIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1zCisgICAgICogICAgICAgICAgICB0aGUgcGFyYW1ldGVycyBmb3IgdGhlIGtleSBnZW5lcmF0aW9uIGFsZ29yaXRobS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFyYW1ldGVycyBjYW5ub3QgYmUgdXNlZCB0byBpbml0aWFsaXplIHRoaXMga2V5CisgICAgICogICAgICAgICAgICAgZ2VuZXJhdG9yIGFsZ29yaXRobS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBpbml0KEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1zKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBzcGlJbXBsLmVuZ2luZUluaXQocGFyYW1zLCBSQU5ET00pOy8vbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBLZXlHZW5lcmF0b3J9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIGFsZ29yaXRobSBwYXJhbWV0ZXJzIGFuZCByYW5kb21uZXNzIHNvdXJjZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXJzIGZvciB0aGUga2V5IGdlbmVyYXRpb24gYWxnb3JpdGhtLgorICAgICAqIEBwYXJhbSByYW5kb20KKyAgICAgKiAgICAgICAgICAgIHRoZSByYW5kb21uZXNzIHNvdXJjZSBmb3IgYW55IHJhbmRvbSBieXRlcy4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcGFyYW1ldGVycyBjYW5ub3QgYmUgdXNlcyB0byBpbml0aWFsaXplIHRoaXMga2V5CisgICAgICogICAgICAgICAgICAgZ2VuZXJhdG9yIGFsZ29yaXRobS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBpbml0KEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1zLCBTZWN1cmVSYW5kb20gcmFuZG9tKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBzcGlJbXBsLmVuZ2luZUluaXQocGFyYW1zLCByYW5kb20pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEtleUdlbmVyYXRvcn0gaW5zdGFuY2UgZm9yIHRoZSBzcGVjaWZpZWQga2V5IHNpemUKKyAgICAgKiAoaW4gYml0cykuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5c2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIHNpemUgb2YgdGhlIGtleSAoaW4gYml0cykuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdChpbnQga2V5c2l6ZSkgeworICAgICAgICBzcGlJbXBsLmVuZ2luZUluaXQoa2V5c2l6ZSwgUkFORE9NKTsvL25ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyB7QGNvZGUgS2V5R2VuZXJhdG9yfSBpbnN0YW5jZSBmb3IgdGhlIHNwZWNpZmllZCBrZXkgc2l6ZQorICAgICAqIChpbiBiaXRzKSB1c2luZyB0aGUgc3BlY2lmaWVkIHJhbmRvbW5lc3Mgc291cmNlLgorICAgICAqCisgICAgICogQHBhcmFtIGtleXNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaXplIG9mIHRoZSBrZXkgKGluIGJpdHMpLgorICAgICAqIEBwYXJhbSByYW5kb20KKyAgICAgKiAgICAgICAgICAgIHRoZSByYW5kb21uZXNzIHNvdXJjZSBmb3IgYW55IHJhbmRvbSBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBpbml0KGludCBrZXlzaXplLCBTZWN1cmVSYW5kb20gcmFuZG9tKSB7CisgICAgICAgIHNwaUltcGwuZW5naW5lSW5pdChrZXlzaXplLCByYW5kb20pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEtleUdlbmVyYXRvcn0gd2l0aCB0aGUgc3BlY2lmaWVkIHJhbmRvbW5lc3MKKyAgICAgKiBzb3VyY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmFuZG9tCisgICAgICogICAgICAgICAgICB0aGUgcmFuZG9tbmVzcyBzb3VyY2UgZm9yIGFueSByYW5kb20gYnl0ZXMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdChTZWN1cmVSYW5kb20gcmFuZG9tKSB7CisgICAgICAgIHNwaUltcGwuZW5naW5lSW5pdChyYW5kb20pOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vS2V5R2VuZXJhdG9yU3BpLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL0tleUdlbmVyYXRvclNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI3Y2ZlMzIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL0tleUdlbmVyYXRvclNwaS5qYXZhCkBAIC0wLDAgKzEsNzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguY3J5cHRvOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworCisvKioKKyAqIFRoZSA8aT5TZXJ2aWNlIFByb3ZpZGVyIEludGVyZmFjZTwvaT4gKDxiPlNQSTwvYj4pIGRlZmluaXRpb24gZm9yIHRoZQorICoge0Bjb2RlIEtleUdlbmVyYXRvcn0gY2xhc3MuCisgKgorICogQHNlZSBLZXlHZW5lcmF0b3IKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEtleUdlbmVyYXRvclNwaSB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBLZXlHZW5lcmF0b3JTcGl9IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBLZXlHZW5lcmF0b3JTcGkoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGEgc2VjcmV0IGtleS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGdlbmVyYXRlZCBzZWNyZXQga2V5LgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBTZWNyZXRLZXkgZW5naW5lR2VuZXJhdGVLZXkoKTsKKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEtleUdlbmVyYXRvclNwaX0gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogYWxnb3JpdGhtIHBhcmFtZXRlcnMgYW5kIHJhbmRvbW5lc3Mgc291cmNlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlcnMgZm9yIHRoZSBrZXkgZ2VuZXJhdGlvbiBhbGdvcml0aG0uCisgICAgICogQHBhcmFtIHJhbmRvbQorICAgICAqICAgICAgICAgICAgdGhlIHJhbmRvbW5lc3Mgc291cmNlIGZvciBhbnkgcmFuZG9tIGJ5dGVzLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYXJhbWV0ZXJzIGNhbm5vdCBiZSB1c2VzIHRvIGluaXRpYWxpemUgdGhpcyBrZXkKKyAgICAgKiAgICAgICAgICAgICBnZW5lcmF0b3IgYWxnb3JpdGhtLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGVuZ2luZUluaXQoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMsCisgICAgICAgICAgICBTZWN1cmVSYW5kb20gcmFuZG9tKSB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIEtleUdlbmVyYXRvcn0gaW5zdGFuY2UgZm9yIHRoZSBzcGVjaWZpZWQga2V5CisgICAgICogc2l6ZSAoaW4gYml0cykgdXNpbmcgdGhlIHNwZWNpZmllZCByYW5kb21uZXNzIHNvdXJjZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXlzaXplCisgICAgICogICAgICAgICAgICB0aGUgc2l6ZSBvZiB0aGUga2V5IChpbiBiaXRzKS4KKyAgICAgKiBAcGFyYW0gcmFuZG9tCisgICAgICogICAgICAgICAgICB0aGUgcmFuZG9tbmVzcyBzb3VyY2UgZm9yIGFueSByYW5kb20gYnl0ZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgZW5naW5lSW5pdChpbnQga2V5c2l6ZSwgU2VjdXJlUmFuZG9tIHJhbmRvbSk7CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBLZXlHZW5lcmF0b3J9IHdpdGggdGhlIHNwZWNpZmllZCByYW5kb21uZXNzCisgICAgICogc291cmNlLgorICAgICAqCisgICAgICogQHBhcmFtIHJhbmRvbQorICAgICAqICAgICAgICAgICAgdGhlIHJhbmRvbW5lc3Mgc291cmNlIGZvciBhbnkgcmFuZG9tIGJ5dGVzLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGVuZ2luZUluaXQoU2VjdXJlUmFuZG9tIHJhbmRvbSk7Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9NYWMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vTWFjLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWEwNWI1OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vTWFjLmphdmEKQEAgLTAsMCArMSw0MjEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguY3J5cHRvOworCitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5mb3J0cmVzcy5FbmdpbmU7CisKKworLyoqCisgKiBUaGlzIGNsYXNzIHByb3ZpZGVzIHRoZSBwdWJsaWMgQVBJIGZvciA8aT5NZXNzYWdlIEF1dGhlbnRpY2F0aW9uIENvZGU8L2k+CisgKiAoTUFDKSBhbGdvcml0aG1zLgorICovCitwdWJsaWMgY2xhc3MgTWFjIGltcGxlbWVudHMgQ2xvbmVhYmxlIHsKKworICAgIC8vVXNlZCB0byBhY2Nlc3MgY29tbW9uIGVuZ2luZSBmdW5jdGlvbmFsaXR5CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRW5naW5lIEVOR0lORSA9IG5ldyBFbmdpbmUoIk1hYyIpOworCisgICAgLy8gU3RvcmUgdXNlZCBwcm92aWRlcgorICAgIHByaXZhdGUgZmluYWwgUHJvdmlkZXIgcHJvdmlkZXI7CisKKyAgICAvLyBTdG9yZSB1c2VkIHNwaSBpbXBsZW1lbnRhdGlvbgorICAgIHByaXZhdGUgZmluYWwgTWFjU3BpIHNwaUltcGw7CisKKyAgICAvLyBTdG9yZSB1c2VkIGFsZ29yaXRobSBuYW1lCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgYWxnb3JpdGhtOworCisgICAgLy8gU3RvcmUgTWFjIHN0YXRlIChpbml0aWFsaXplZCBvciBub3QgaW5pdGlhbGl6ZWQpCisgICAgcHJpdmF0ZSBib29sZWFuIGlzSW5pdE1hYzsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIE1hY30gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWFjU3BpCisgICAgICogICAgICAgICAgICB0aGUgaW1wbGVtZW50YXRpb24gZGVsZWdhdGUuCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgaW1wbGVtZW50YXRpb24gcHJvdmlkZXIuCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIE1BQyBhbGdvcml0aG0uCisgICAgICovCisgICAgcHJvdGVjdGVkIE1hYyhNYWNTcGkgbWFjU3BpLCBQcm92aWRlciBwcm92aWRlciwgU3RyaW5nIGFsZ29yaXRobSkgeworICAgICAgICB0aGlzLnByb3ZpZGVyID0gcHJvdmlkZXI7CisgICAgICAgIHRoaXMuYWxnb3JpdGhtID0gYWxnb3JpdGhtOworICAgICAgICB0aGlzLnNwaUltcGwgPSBtYWNTcGk7CisgICAgICAgIHRoaXMuaXNJbml0TWFjID0gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgTUFDIGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIE1BQyBhbGdvcml0aG0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiBhbGdvcml0aG07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJvdmlkZXIgb2YgdGhpcyB7QGNvZGUgTWFjfSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByb3ZpZGVyIG9mIHRoaXMge0Bjb2RlIE1hY30gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFByb3ZpZGVyIGdldFByb3ZpZGVyKCkgeworICAgICAgICByZXR1cm4gcHJvdmlkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgTWFjfSBpbnN0YW5jZSB0aGF0IHByb3ZpZGVzIHRoZSBzcGVjaWZpZWQgTUFDCisgICAgICogYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlcXVlc3RlZCBNQUMgYWxnb3JpdGhtLgorICAgICAqIEByZXR1cm4gdGhlIG5ldyB7QGNvZGUgTWFjfSBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUgYnkgYW55IHByb3ZpZGVyLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYWxnb3JpdGhtfSBpcyB7QGNvZGUgbnVsbH0gKGluc3RlYWQgb2YKKyAgICAgKiAgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYXMgaW4gMS40IHJlbGVhc2UpLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFjIGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFsZ29yaXRobSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBFbmdpbmUuU3BpQW5kUHJvdmlkZXIgc2FwID0gRU5HSU5FLmdldEluc3RhbmNlKGFsZ29yaXRobSwgbnVsbCk7CisgICAgICAgIHJldHVybiBuZXcgTWFjKChNYWNTcGkpIHNhcC5zcGksIHNhcC5wcm92aWRlciwgYWxnb3JpdGhtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBNYWN9IGluc3RhbmNlIHRoYXQgcHJvdmlkZXMgdGhlIHNwZWNpZmllZCBNQUMKKyAgICAgKiBhbGdvcml0aG0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlcXVlc3RlZCBNQUMgYWxnb3JpdGhtLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIHRoYXQgaXMgcHJvdmlkaW5nIHRoZSBhbGdvcml0aG0uCisgICAgICogQHJldHVybiB0aGUgbmV3IHtAY29kZSBNYWN9IGluc3RhbmNlLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0gaXMgbm90IHByb3ZpZGVkIGJ5IHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgICAgICAgICAgICBwcm92aWRlci4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBuYW1lIGlzIHtAY29kZSBudWxsfSBvciBlbXB0eS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFsZ29yaXRobX0gaXMge0Bjb2RlIG51bGx9IChpbnN0ZWFkIG9mCisgICAgICogICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGFzIGluIDEuNCByZWxlYXNlKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hYyBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwcm92aWRlciA9PSBudWxsIHx8IHByb3ZpZGVyLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiUHJvdmlkZXIgaXMgbnVsbCBvciBlbXB0eSIpOworICAgICAgICB9CisgICAgICAgIFByb3ZpZGVyIGltcFByb3ZpZGVyID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXIocHJvdmlkZXIpOworICAgICAgICBpZiAoaW1wUHJvdmlkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uKHByb3ZpZGVyKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBpbXBQcm92aWRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgTWFjfSBpbnN0YW5jZSB0aGF0IHByb3ZpZGVzIHRoZSBzcGVjaWZpZWQgTUFDCisgICAgICogYWxnb3JpdGhtIGZyb20gdGhlIHNwZWNpZmllZCBwcm92aWRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXF1ZXN0ZWQgTUFDIGFsZ29yaXRobS4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm92aWRlciB0aGF0IGlzIHByb3ZpZGluZyB0aGUgYWxnb3JpdGhtLgorICAgICAqIEByZXR1cm4gdGhlIG5ldyB7QGNvZGUgTWFjfSBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIGlzIG5vdCBwcm92aWRlZCBieSB0aGUgc3BlY2lmaWVkCisgICAgICogICAgICAgICAgICAgcHJvdmlkZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcHJvdmlkZXJ9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFsZ29yaXRobX0gaXMge0Bjb2RlIG51bGx9IChpbnN0ZWFkIG9mCisgICAgICogICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGFzIGluIDEuNCByZWxlYXNlKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hYyBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBQcm92aWRlciBwcm92aWRlcikKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicHJvdmlkZXIgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChhbGdvcml0aG0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgT2JqZWN0IHNwaSA9IEVOR0lORS5nZXRJbnN0YW5jZShhbGdvcml0aG0sIHByb3ZpZGVyLCBudWxsKTsKKyAgICAgICAgcmV0dXJuIG5ldyBNYWMoKE1hY1NwaSkgc3BpLCBwcm92aWRlciwgYWxnb3JpdGhtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhpcyBNQUMgKGluIGJ5dGVzKS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGlzIE1BQyAoaW4gYnl0ZXMpLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TWFjTGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVHZXRNYWNMZW5ndGgoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBNYWN9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBrZXkgYW5kCisgICAgICogYWxnb3JpdGhtIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IHRvIGluaXRpYWxpemUgdGhpcyBhbGdvcml0aG0uCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbm5vdCBiZSB1c2VkIHRvIGluaXRpYWxpemUgdGhpcworICAgICAqICAgICAgICAgICAgIGFsZ29yaXRobSwgb3IgaXQgaXMgbnVsbC4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMgY2Fubm90IGJlIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGlzCisgICAgICogICAgICAgICAgICAgYWxnb3JpdGhtLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGluaXQoS2V5IGtleSwgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oImtleSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgc3BpSW1wbC5lbmdpbmVJbml0KGtleSwgcGFyYW1zKTsKKyAgICAgICAgaXNJbml0TWFjID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBNYWN9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IHRvIGluaXRpYWxpemUgdGhpcyBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgaW5pdGlhbGl6YXRpb24gZmFpbHMgYmVjYXVzZSB0aGUgcHJvdmlkZWQga2V5IGlzIHtAY29kZQorICAgICAqICAgICAgICAgICAgIG51bGx9LgorICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbm5vdCBiZSB1c2VkIHRvIGluaXRpYWxpemUgdGhpcworICAgICAqICAgICAgICAgICAgIGFsZ29yaXRobS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBpbml0KEtleSBrZXkpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbigia2V5ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc3BpSW1wbC5lbmdpbmVJbml0KGtleSwgbnVsbCk7CisgICAgICAgICAgICBpc0luaXRNYWMgPSB0cnVlOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGlzIHtAY29kZSBNYWN9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBieXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgYnl0ZQorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBNQUMgaXMgbm90IGluaXRpYWxpemVkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHVwZGF0ZShieXRlIGlucHV0KSB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc0luaXRNYWMpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBzcGlJbXBsLmVuZ2luZVVwZGF0ZShpbnB1dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGlzIHtAY29kZSBNYWN9IGluc3RhbmNlIHdpdGggdGhlIGRhdGEgZnJvbSB0aGUgc3BlY2lmaWVkIGJ1ZmZlcgorICAgICAqIHtAY29kZSBpbnB1dH0gZnJvbSB0aGUgc3BlY2lmaWVkIHtAY29kZSBvZmZzZXR9IGFuZCBsZW5ndGgge0Bjb2RlIGxlbn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXIuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgYnVmZmVyLgorICAgICAqIEBwYXJhbSBsZW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgaW4gdGhlIGJ1ZmZlci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgTUFDIGlzIG5vdCBpbml0aWFsaXplZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBvZmZzZXR9IGFuZCB7QGNvZGUgbGVufSBkbyBub3Qgc3BlY2lmaWVkIGEgdmFsaWQKKyAgICAgKiAgICAgICAgICAgICBjaHVuayBpbiB7QGNvZGUgaW5wdXR9IGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB1cGRhdGUoYnl0ZVtdIGlucHV0LCBpbnQgb2Zmc2V0LCBpbnQgbGVuKSB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpc0luaXRNYWMpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGlmICgob2Zmc2V0IDwgMCkgfHwgKGxlbiA8IDApIHx8ICgob2Zmc2V0ICsgbGVuKSA+IGlucHV0Lmxlbmd0aCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkluY29ycmVjdCBhcmd1bWVudHMiKTsKKyAgICAgICAgfQorICAgICAgICBzcGlJbXBsLmVuZ2luZVVwZGF0ZShpbnB1dCwgb2Zmc2V0LCBsZW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyB0aGUgYnVmZmVyIHByb3ZpZGVkIGFzIGlucHV0IGZvciBmdXJ0aGVyIHByb2Nlc3NpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIE1BQyBpcyBub3QgaW5pdGlhbGl6ZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdXBkYXRlKGJ5dGVbXSBpbnB1dCkgdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaXNJbml0TWFjKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNwaUltcGwuZW5naW5lVXBkYXRlKGlucHV0LCAwLCBpbnB1dC5sZW5ndGgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGlzIHtAY29kZSBNYWN9IGluc3RhbmNlIHdpdGggdGhlIGRhdGEgZnJvbSB0aGUgc3BlY2lmaWVkCisgICAgICogYnVmZmVyLCBzdGFydGluZyBhdCB7QGxpbmsgQnl0ZUJ1ZmZlciNwb3NpdGlvbigpfSwgaW5jbHVkaW5nIHRoZSBuZXh0CisgICAgICoge0BsaW5rIEJ5dGVCdWZmZXIjcmVtYWluaW5nKCl9IGJ5dGVzLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBNQUMgaXMgbm90IGluaXRpYWxpemVkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHVwZGF0ZShCeXRlQnVmZmVyIGlucHV0KSB7CisgICAgICAgIGlmICghaXNJbml0TWFjKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNwaUltcGwuZW5naW5lVXBkYXRlKGlucHV0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImlucHV0ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGVzIHRoZSBkaWdlc3Qgb2YgdGhpcyBNQUMgYmFzZWQgb24gdGhlIGRhdGEgcHJldmlvdXNseSBzcGVjaWZpZWQgaW4KKyAgICAgKiB7QGxpbmsgI3VwZGF0ZX0gY2FsbHMuCisgICAgICogPHA+CisgICAgICogVGhpcyB7QGNvZGUgTWFjfSBpbnN0YW5jZSBpcyByZXZlcnRlZCB0byBpdHMgaW5pdGlhbCBzdGF0ZSBhbmQgY2FuIGJlCisgICAgICogdXNlZCB0byBzdGFydCB0aGUgbmV4dCBNQUMgY29tcHV0YXRpb24gd2l0aCB0aGUgc2FtZSBwYXJhbWV0ZXJzIG9yCisgICAgICogaW5pdGlhbGl6ZWQgd2l0aCBkaWZmZXJlbnQgcGFyYW1ldGVycy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGdlbmVyYXRlZCBkaWdlc3QuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIE1BQyBpcyBub3QgaW5pdGlhbGl6ZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJ5dGVbXSBkb0ZpbmFsKCkgdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaXNJbml0TWFjKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lRG9GaW5hbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGVzIHRoZSBkaWdlc3Qgb2YgdGhpcyBNQUMgYmFzZWQgb24gdGhlIGRhdGEgcHJldmlvdXNseSBzcGVjaWZpZWQgaW4KKyAgICAgKiB7QGxpbmsgI3VwZGF0ZX0gY2FsbHMgYW5kIHN0b3JlcyB0aGUgZGlnZXN0IGluIHRoZSBzcGVjaWZpZWQge0Bjb2RlCisgICAgICogb3V0cHV0fSBidWZmZXIgYXQgb2Zmc2V0IHtAY29kZSBvdXRPZmZzZXR9LgorICAgICAqIDxwPgorICAgICAqIFRoaXMge0Bjb2RlIE1hY30gaW5zdGFuY2UgaXMgcmV2ZXJ0ZWQgdG8gaXRzIGluaXRpYWwgc3RhdGUgYW5kIGNhbiBiZQorICAgICAqIHVzZWQgdG8gc3RhcnQgdGhlIG5leHQgTUFDIGNvbXB1dGF0aW9uIHdpdGggdGhlIHNhbWUgcGFyYW1ldGVycyBvcgorICAgICAqIGluaXRpYWxpemVkIHdpdGggZGlmZmVyZW50IHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0cHV0CisgICAgICogICAgICAgICAgICB0aGUgb3V0cHV0IGJ1ZmZlcgorICAgICAqIEBwYXJhbSBvdXRPZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIG91dHB1dCBidWZmZXIKKyAgICAgKiBAdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBvdXRwdXQgYnVmZmVyIGlzIGVpdGhlciB0b28gc21hbGwgZm9yIHRoZQorICAgICAqICAgICAgICAgICAgIGRpZ2VzdCB0byBiZSBzdG9yZWQsIHRoZSBzcGVjaWZpZWQgb3V0cHV0IGJ1ZmZlciBpcyB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgICBudWxsfSwgb3IgdGhlIHNwZWNpZmllZCBvZmZzZXQgaXMgbmVnYXRpdmUgb3IgcGFzdCB0aGUgbGVuZ3RoCisgICAgICogICAgICAgICAgICAgb2YgdGhlIG91dHB1dCBidWZmZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIE1BQyBpcyBub3QgaW5pdGlhbGl6ZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgZG9GaW5hbChieXRlW10gb3V0cHV0LCBpbnQgb3V0T2Zmc2V0KQorICAgICAgICAgICAgdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uLCBJbGxlZ2FsU3RhdGVFeGNlcHRpb24geworICAgICAgICBpZiAoIWlzSW5pdE1hYykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChvdXRwdXQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNob3J0QnVmZmVyRXhjZXB0aW9uKCJvdXRwdXQgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmICgob3V0T2Zmc2V0IDwgMCkgfHwgKG91dE9mZnNldCA+PSBvdXRwdXQubGVuZ3RoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNob3J0QnVmZmVyRXhjZXB0aW9uKCJJbmNvcnJlY3Qgb3V0T2Zmc2V0OiAiICsgb3V0T2Zmc2V0KTsKKyAgICAgICAgfQorICAgICAgICBpbnQgdCA9IHNwaUltcGwuZW5naW5lR2V0TWFjTGVuZ3RoKCk7CisgICAgICAgIGlmICh0ID4gKG91dHB1dC5sZW5ndGggLSBvdXRPZmZzZXQpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU2hvcnRCdWZmZXJFeGNlcHRpb24oIk91dHB1dCBidWZmZXIgaXMgc2hvcnQuIE5lZWRlZCAiICsgdCArICIgYnl0ZXMuIik7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IHNwaUltcGwuZW5naW5lRG9GaW5hbCgpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHJlc3VsdCwgMCwgb3V0cHV0LCBvdXRPZmZzZXQsIHJlc3VsdC5sZW5ndGgpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZXMgdGhlIGRpZ2VzdCBvZiB0aGlzIE1BQyBiYXNlZCBvbiB0aGUgZGF0YSBwcmV2aW91c2x5IHNwZWNpZmllZCBvbgorICAgICAqIHtAbGluayAjdXBkYXRlfSBjYWxscyBhbmQgb24gdGhlIGZpbmFsIGJ5dGVzIHNwZWNpZmllZCBieSB7QGNvZGUgaW5wdXR9CisgICAgICogKG9yIGJhc2VkIG9uIHRob3NlIGJ5dGVzIG9ubHkpLgorICAgICAqIDxwPgorICAgICAqIFRoaXMge0Bjb2RlIE1hY30gaW5zdGFuY2UgaXMgcmV2ZXJ0ZWQgdG8gaXRzIGluaXRpYWwgc3RhdGUgYW5kIGNhbiBiZQorICAgICAqIHVzZWQgdG8gc3RhcnQgdGhlIG5leHQgTUFDIGNvbXB1dGF0aW9uIHdpdGggdGhlIHNhbWUgcGFyYW1ldGVycyBvcgorICAgICAqIGluaXRpYWxpemVkIHdpdGggZGlmZmVyZW50IHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBmaW5hbCBieXRlcy4KKyAgICAgKiBAcmV0dXJuIHRoZSBnZW5lcmF0ZWQgZGlnZXN0LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBNQUMgaXMgbm90IGluaXRpYWxpemVkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBieXRlW10gZG9GaW5hbChieXRlW10gaW5wdXQpIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24geworICAgICAgICBpZiAoIWlzSW5pdE1hYykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dCAhPSBudWxsKSB7CisgICAgICAgICAgICBzcGlJbXBsLmVuZ2luZVVwZGF0ZShpbnB1dCwgMCwgaW5wdXQubGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVEb0ZpbmFsKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzZXRzIHRoaXMge0Bjb2RlIE1hY30gaW5zdGFuY2UgdG8gaXRzIGluaXRpYWwgc3RhdGUuCisgICAgICogPHA+CisgICAgICogVGhpcyB7QGNvZGUgTWFjfSBpbnN0YW5jZSBpcyByZXZlcnRlZCB0byBpdHMgaW5pdGlhbCBzdGF0ZSBhbmQgY2FuIGJlCisgICAgICogdXNlZCB0byBzdGFydCB0aGUgbmV4dCBNQUMgY29tcHV0YXRpb24gd2l0aCB0aGUgc2FtZSBwYXJhbWV0ZXJzIG9yCisgICAgICogaW5pdGlhbGl6ZWQgd2l0aCBkaWZmZXJlbnQgcGFyYW1ldGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCByZXNldCgpIHsKKyAgICAgICAgc3BpSW1wbC5lbmdpbmVSZXNldCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb25lcyB0aGlzIHtAY29kZSBNYWN9IGluc3RhbmNlIGFuZCB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNsb25lZCBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBjbG9uaW5nLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICBNYWNTcGkgbmV3U3BpSW1wbCA9IChNYWNTcGkpc3BpSW1wbC5jbG9uZSgpOworICAgICAgICBNYWMgbWFjID0gbmV3IE1hYyhuZXdTcGlJbXBsLCB0aGlzLnByb3ZpZGVyLCB0aGlzLmFsZ29yaXRobSk7CisgICAgICAgIG1hYy5pc0luaXRNYWMgPSB0aGlzLmlzSW5pdE1hYzsKKyAgICAgICAgcmV0dXJuIG1hYzsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL01hY1NwaS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9NYWNTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMWNjNDAwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9NYWNTcGkuamF2YQpAQCAtMCwwICsxLDE0NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CisKKy8qKgorICogVGhlIDxpPlNlcnZpY2UtUHJvdmlkZXIgSW50ZXJmYWNlPC9pPiAoPGI+U1BJPC9iPikgZGVmaW5pdGlvbiBmb3IgdGhlIHtAY29kZQorICogTWFjfSBjbGFzcy4KKyAqCisgKiBAc2VlIE1hYworICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTWFjU3BpIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIE1hY1NwaX0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIE1hY1NwaSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhpcyBNQUMgKGluIGJ5dGVzKS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGlzIE1BQyAoaW4gYnl0ZXMpLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBpbnQgZW5naW5lR2V0TWFjTGVuZ3RoKCk7CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBNYWNTcGl9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBrZXkgYW5kCisgICAgICogYWxnb3JpdGhtIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IHRvIGluaXRpYWxpemUgdGhpcyBhbGdvcml0aG0uCisgICAgICogQHBhcmFtIHBhcmFtcworICAgICAqICAgICAgICAgICAgdGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbm5vdCBiZSB1c2VkIHRvIGluaXRpYWxpemUgdGhpcworICAgICAqICAgICAgICAgICAgIGFsZ29yaXRobSwgb3IgaXQgaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycyBjYW5ub3QgYmUgdXNlZCB0byBpbml0aWFsaXplIHRoaXMKKyAgICAgKiAgICAgICAgICAgICBhbGdvcml0aG0uCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgZW5naW5lSW5pdChLZXkga2V5LCBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtcykKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLCBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGlzIHtAY29kZSBNYWNTcGl9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBieXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgYnl0ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZSBpbnB1dCk7CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoaXMge0Bjb2RlIE1hY1NwaX0gaW5zdGFuY2Ugd2l0aCB0aGUgZGF0YSBmcm9tIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBidWZmZXIge0Bjb2RlIGlucHV0fSBmcm9tIHRoZSBzcGVjaWZpZWQge0Bjb2RlIG9mZnNldH0gYW5kIGxlbmd0aCB7QGNvZGUKKyAgICAgKiBsZW59LgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0CisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyLgorICAgICAqIEBwYXJhbSBvZmZzZXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBvZmZzZXQgaW4gdGhlIGJ1ZmZlci4KKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhIGluIHRoZSBidWZmZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgZW5naW5lVXBkYXRlKGJ5dGVbXSBpbnB1dCwgaW50IG9mZnNldCwgaW50IGxlbik7CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoaXMge0Bjb2RlIE1hY1NwaX0gaW5zdGFuY2Ugd2l0aCB0aGUgZGF0YSBmcm9tIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBidWZmZXIsIHN0YXJ0aW5nIGF0IHtAbGluayBCeXRlQnVmZmVyI3Bvc2l0aW9uKCl9LCBpbmNsdWRpbmcgdGhlIG5leHQKKyAgICAgKiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZW1haW5pbmcoKX0gYnl0ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKEJ5dGVCdWZmZXIgaW5wdXQpIHsKKyAgICAgICAgaWYgKCFpbnB1dC5oYXNSZW1haW5pbmcoKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSBiSW5wdXQ7CisgICAgICAgIGlmIChpbnB1dC5oYXNBcnJheSgpKSB7CisgICAgICAgICAgICBiSW5wdXQgPSBpbnB1dC5hcnJheSgpOworICAgICAgICAgICAgaW50IG9mZnNldCA9IGlucHV0LmFycmF5T2Zmc2V0KCk7CisgICAgICAgICAgICBpbnQgcG9zaXRpb24gPSBpbnB1dC5wb3NpdGlvbigpOworICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQubGltaXQoKTsKKyAgICAgICAgICAgIGVuZ2luZVVwZGF0ZShiSW5wdXQsIG9mZnNldCArIHBvc2l0aW9uLCBsaW1pdCAtIHBvc2l0aW9uKTsKKyAgICAgICAgICAgIGlucHV0LnBvc2l0aW9uKGxpbWl0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJJbnB1dCA9IG5ldyBieXRlW2lucHV0LmxpbWl0KCkgLSBpbnB1dC5wb3NpdGlvbigpXTsKKyAgICAgICAgICAgIGlucHV0LmdldChiSW5wdXQpOworICAgICAgICAgICAgZW5naW5lVXBkYXRlKGJJbnB1dCwgMCwgYklucHV0Lmxlbmd0aCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlcyB0aGUgZGlnZXN0IG9mIHRoaXMgTUFDIGJhc2VkIG9uIHRoZSBkYXRhIHByZXZpb3VzbHkgc3BlY2lmaWVkIGluCisgICAgICoge0BsaW5rICNlbmdpbmVVcGRhdGV9IGNhbGxzLgorICAgICAqIDxwPgorICAgICAqIFRoaXMge0Bjb2RlIE1hY1NwaX0gaW5zdGFuY2UgaXMgcmV2ZXJ0ZWQgdG8gaXRzIGluaXRpYWwgc3RhdGUgYW5kCisgICAgICogY2FuIGJlIHVzZWQgdG8gc3RhcnQgdGhlIG5leHQgTUFDIGNvbXB1dGF0aW9uIHdpdGggdGhlIHNhbWUgcGFyYW1ldGVycyBvcgorICAgICAqIGluaXRpYWxpemVkIHdpdGggZGlmZmVyZW50IHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBnZW5lcmF0ZWQgZGlnZXN0LgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBieXRlW10gZW5naW5lRG9GaW5hbCgpOworCisgICAgLyoqCisgICAgICogUmVzZXRzIHRoaXMge0Bjb2RlIE1hY1NwaX0gaW5zdGFuY2UgdG8gaXRzIGluaXRpYWwgc3RhdGUuCisgICAgICogPHA+CisgICAgICogVGhpcyB7QGNvZGUgTWFjU3BpfSBpbnN0YW5jZSBpcyByZXZlcnRlZCB0byBpdHMgaW5pdGlhbCBzdGF0ZSBhbmQgY2FuIGJlCisgICAgICogdXNlZCB0byBzdGFydCB0aGUgbmV4dCBNQUMgY29tcHV0YXRpb24gd2l0aCB0aGUgc2FtZSBwYXJhbWV0ZXJzIG9yCisgICAgICogaW5pdGlhbGl6ZWQgd2l0aCBkaWZmZXJlbnQgcGFyYW1ldGVycy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBlbmdpbmVSZXNldCgpOworCisgICAgLyoqCisgICAgICogQ2xvbmVzIHRoaXMge0Bjb2RlIE1hY1NwaX0gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjbG9uZWQgaW5zdGFuY2UuCisgICAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGNsb25pbmcgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9Ob1N1Y2hQYWRkaW5nRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL05vU3VjaFBhZGRpbmdFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYWJiMTgxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9Ob1N1Y2hQYWRkaW5nRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbjsKKworLyoqCisgKiBUaGUgZXhjZXB0aW9uIHRoYXQgaXMgdGhyb3duIHdoZW4gdGhlIHJlcXVlc3RlZCBwYWRkaW5nIG1lY2hhbmlzbSBpcyBub3QKKyAqIHN1cHBvcnRlZC4KKyAqLworcHVibGljIGNsYXNzIE5vU3VjaFBhZGRpbmdFeGNlcHRpb24gZXh0ZW5kcyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24geworCisgICAgLyoqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00NTcyODg1MjAxMjAwMTc1NDY2TDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIE5vU3VjaFBhZGRpbmdFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIE5vU3VjaFBhZGRpbmdFeGNlcHRpb24oKSB7CisgICAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vTnVsbENpcGhlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9OdWxsQ2lwaGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTdhMDRkNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vTnVsbENpcGhlci5qYXZhCkBAIC0wLDAgKzEsNDggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEJvcmlzIFYuIEt1em5ldHNvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIGphdmF4LmNyeXB0bzsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLmludGVybmFsLk51bGxDaXBoZXJTcGk7CisKKworLyoqCisgKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGFuIGlkZW50aXR5IGNpcGhlciB0aGF0IGRvZXMgbm90IHRyYW5zZm9ybSB0aGUgaW5wdXQgZGF0YQorICogaW4gYW55IHdheS4gVGhlIDxpPmVuY3J5cHRlZDwvaT4gZGF0YSBpcyBpZGVudGljYWwgdG8gdGhlIDxpPnBsYWluIHRleHQ8L2k+LgorICovCitwdWJsaWMgY2xhc3MgTnVsbENpcGhlciBleHRlbmRzIENpcGhlciB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBOdWxsQ2lwaGVyfSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTnVsbENpcGhlcigpIHsKKyAgICAgICAgc3VwZXIobmV3IE51bGxDaXBoZXJTcGkoKSwgbnVsbCwgbnVsbCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGlzLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgKEtleSludWxsLCAoU2VjdXJlUmFuZG9tKW51bGwpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9TZWFsZWRPYmplY3QuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vU2VhbGVkT2JqZWN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzljMTUzNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vU2VhbGVkT2JqZWN0LmphdmEKQEAgLTAsMCArMSwyODMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguY3J5cHRvOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKKworLyoqCisgKiBBIHtAY29kZSBTZWFsZWRPYmplY3R9IGlzIGEgd3JhcHBlciBhcm91bmQgYSB7QGNvZGUgc2VyaWFsaXphYmxlfSBvYmplY3QKKyAqIGluc3RhbmNlIGFuZCBlbmNyeXB0cyBpdCB1c2luZyBhIGNyeXB0b2dyYXBoaWMgY2lwaGVyLgorICogPHA+CisgKiBTaW5jZSBhIHtAY29kZSBTZWFsZWRPYmplY3R9IGluc3RhbmNlIGlzIGEgc2VyaWFsaXphYmxlIG9iamVjdCBpdHNlbGYgaXQgY2FuCisgKiBlaXRoZXIgYmUgc3RvcmVkIG9yIHRyYW5zbWl0dGVkIG92ZXIgYW4gaW5zZWN1cmUgY2hhbm5lbC4KKyAqIDxwPgorICogVGhlIHdyYXBwZWQgb2JqZWN0IGNhbiBsYXRlciBiZSBkZWNyeXB0ZWQgKHVuc2VhbGVkKSB1c2luZyB0aGUgY29ycmVzcG9uZGluZworICoga2V5IGFuZCB0aGVuIGJlIGRlc2VyaWFsaXplZCB0byByZXRyaWV2ZSB0aGUgb3JpZ2luYWwgb2JqZWN0LlRoZSBzZWFsZWQKKyAqIG9iamVjdCBpdHNlbGYga2VlcHMgdHJhY2sgb2YgdGhlIGNpcGhlciBhbmQgY29ycmVzcG9uZGluZyBwYXJhbWV0ZXJzLgorICovCitwdWJsaWMgY2xhc3MgU2VhbGVkT2JqZWN0IGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDQ0ODI4MzgyNjU1NTEzNDQ3NTJMOworCisgICAgLyoqCisgICAgICogVGhlIHtAbGluayBBbGdvcml0aG1QYXJhbWV0ZXJzfSBpbiBlbmNvZGVkIGZvcm1hdC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuY29kZWRQYXJhbXM7CisgICAgcHJpdmF0ZSBieXRlW10gZW5jcnlwdGVkQ29udGVudDsKKyAgICBwcml2YXRlIFN0cmluZyBzZWFsQWxnOworICAgIHByaXZhdGUgU3RyaW5nIHBhcmFtc0FsZzsKKworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIHMpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgZW5jb2RlZFBhcmFtcyA9IChieXRlIFtdKSBzLnJlYWRVbnNoYXJlZCgpOworICAgICAgICBlbmNyeXB0ZWRDb250ZW50ID0gKGJ5dGUgW10pIHMucmVhZFVuc2hhcmVkKCk7CisgICAgICAgIHNlYWxBbGcgPSAoU3RyaW5nKSBzLnJlYWRVbnNoYXJlZCgpOworICAgICAgICBwYXJhbXNBbGcgPSAoU3RyaW5nKSBzLnJlYWRVbnNoYXJlZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFNlYWxlZE9iamVjdH0gaW5zdGFuY2Ugd3JhcHBpbmcgdGhlIHNwZWNpZmllZCBvYmplY3QKKyAgICAgKiBhbmQgc2VhbGluZyBpdCB1c2luZyB0aGUgc3BlY2lmaWVkIGNpcGhlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgY2lwaGVyIG11c3QgYmUgZnVsbHkgaW5pdGlhbGl6ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIHNlYWwsIGNhbiBiZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaXBoZXIgdG8gZW5jcnlwdCB0aGUgb2JqZWN0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2VyaWFsaXphdGlvbiBmYWlscy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGNpcGhlciBpcyBhIGJsb2NrIGNpcGhlciBhbmQgdGhlIGxlbmd0aCBvZgorICAgICAqICAgICAgICAgICAgIHRoZSBzZXJpYWxpemVkIGRhdGEgaXMgbm90IGEgbXVsdGlwbGUgb2YgdGhlIGNpcGhlcnMgYmxvY2sKKyAgICAgKiAgICAgICAgICAgICBzaXplLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2lwaGVyIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2VhbGVkT2JqZWN0KFNlcmlhbGl6YWJsZSBvYmplY3QsIENpcGhlciBjKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiYyA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0gb29zID0gbmV3IE9iamVjdE91dHB1dFN0cmVhbShib3MpOworICAgICAgICAgICAgb29zLndyaXRlT2JqZWN0KG9iamVjdCk7CisgICAgICAgICAgICBvb3MuZmx1c2goKTsKKyAgICAgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlcnMgYXAgPSBjLmdldFBhcmFtZXRlcnMoKTsKKyAgICAgICAgICAgIHRoaXMuZW5jb2RlZFBhcmFtcyA9IChhcCA9PSBudWxsKSA/IG51bGwgOiBhcC5nZXRFbmNvZGVkKCk7CisgICAgICAgICAgICB0aGlzLnBhcmFtc0FsZyA9IChhcCA9PSBudWxsKSA/IG51bGwgOiBhcC5nZXRBbGdvcml0aG0oKTsKKyAgICAgICAgICAgIHRoaXMuc2VhbEFsZyA9IGMuZ2V0QWxnb3JpdGhtKCk7CisgICAgICAgICAgICB0aGlzLmVuY3J5cHRlZENvbnRlbnQgPSBjLmRvRmluYWwoYm9zLnRvQnl0ZUFycmF5KCkpOworICAgICAgICB9IGNhdGNoIChCYWRQYWRkaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIHNob3VsZCBiZSBuZXZlciB0aHJvd24gYmVjYXVzZSB0aGUgY2lwaGVyCisgICAgICAgICAgICAvLyBzaG91bGQgYmUgaW5pdGlhbGl6ZWQgZm9yIGVuY3J5cHRpb24KKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgU2VhbGVkT2JqZWN0fSBpbnN0YW5jZSBieSBjb3B5aW5nIHRoZSBkYXRhIGZyb20KKyAgICAgKiB0aGUgc3BlY2lmaWVkIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzbworICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb3B5LgorICAgICAqLworICAgIHByb3RlY3RlZCBTZWFsZWRPYmplY3QoU2VhbGVkT2JqZWN0IHNvKSB7CisgICAgICAgIGlmIChzbyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInNvID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmVuY3J5cHRlZENvbnRlbnQgPSBzby5lbmNyeXB0ZWRDb250ZW50OworICAgICAgICB0aGlzLmVuY29kZWRQYXJhbXMgPSBzby5lbmNvZGVkUGFyYW1zOworICAgICAgICB0aGlzLnNlYWxBbGcgPSBzby5zZWFsQWxnOworICAgICAgICB0aGlzLnBhcmFtc0FsZyA9IHNvLnBhcmFtc0FsZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhbGdvcml0aG0gdGhpcyBvYmplY3Qgd2FzIHNlYWxlZCB3aXRoLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYWxnb3JpdGhtIHRoaXMgb2JqZWN0IHdhcyBzZWFsZWQgd2l0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgcmV0dXJuIHNlYWxBbGc7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgd3JhcHBlZCBvYmplY3QsIGRlY3J5cHRpbmcgaXQgdXNpbmcgdGhlIHNwZWNpZmllZCBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IHRvIGRlY3J5cHQgdGhlIGRhdGEgd2l0aC4KKyAgICAgKiBAcmV0dXJuIHRoZSBlbmNhcHN1bGF0ZWQgb2JqZWN0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBkZXNlcmlhbGl6YXRpb24gZmFpbHMuCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZGVzZXJpYWxpemF0aW9uIGZhaWxzLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGFsZ29yaXRobSB0byBkZWNyeXB0IHRoZSBkYXRhIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIHVzZWQgdG8gZGVjcnlwdCB0aGUgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgT2JqZWN0IGdldE9iamVjdChLZXkga2V5KQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbigia2V5ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2lwaGVyIGNpcGhlciA9IENpcGhlci5nZXRJbnN0YW5jZShzZWFsQWxnKTsKKyAgICAgICAgICAgIGlmICgocGFyYW1zQWxnICE9IG51bGwpICYmIChwYXJhbXNBbGcubGVuZ3RoKCkgIT0gMCkpIHsKKyAgICAgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtcyA9CisgICAgICAgICAgICAgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlcnMuZ2V0SW5zdGFuY2UocGFyYW1zQWxnKTsKKyAgICAgICAgICAgICAgICBwYXJhbXMuaW5pdChlbmNvZGVkUGFyYW1zKTsKKyAgICAgICAgICAgICAgICBjaXBoZXIuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLCBrZXksIHBhcmFtcyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGNpcGhlci5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGtleSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBieXRlW10gc2VyaWFsaXplZCA9IGNpcGhlci5kb0ZpbmFsKGVuY3J5cHRlZENvbnRlbnQpOworICAgICAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0gb2lzID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdElucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShzZXJpYWxpemVkKSk7CisgICAgICAgICAgICByZXR1cm4gb2lzLnJlYWRPYmplY3QoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbiBlKSAgeworICAgICAgICAgICAgLy8gc2hvdWxkIG5vdCBiZSB0aHJvd24gYmVjYXVzZSBjaXBoZXIgdGV4dCB3YXMgbWFkZQorICAgICAgICAgICAgLy8gd2l0aCBleGlzdGluZyBwYWRkaW5nCisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gc2hvdWxkIG5vdCBiZSB0aHJvd24gYmVjYXVzZSBjaXBoZXIgdGV4dCB3YXMgbWFkZQorICAgICAgICAgICAgLy8gd2l0aCBjb3JyZWN0IGFsZ29yaXRobSBwYXJhbWV0ZXJzCisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gc2hvdWxkIG5vdCBiZSB0aHJvd24gYmVjYXVzZSB0aGUgY2lwaGVyIHRleHQKKyAgICAgICAgICAgIC8vIHdhcyBjb3JyZWN0bHkgbWFkZQorICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbihlLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoIChCYWRQYWRkaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIHNob3VsZCBub3QgYmUgdGhyb3duIGJlY2F1c2UgdGhlIGNpcGhlciB0ZXh0CisgICAgICAgICAgICAvLyB3YXMgY29ycmVjdGx5IG1hZGUKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oZS50b1N0cmluZygpKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uICBlKSB7CisgICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgYmUgdGhyb3duIGJlY2F1c2UgY2lwaGVyIGlzIGluaXRpYWxpemVkCisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB3cmFwcGVkIG9iamVjdCwgZGVjcnlwdGluZyBpdCB1c2luZyB0aGUgc3BlY2lmaWVkCisgICAgICogY2lwaGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSBjaXBoZXIgdG8gZGVjcnlwdCB0aGUgZGF0YS4KKyAgICAgKiBAcmV0dXJuIHRoZSBlbmNhcHN1bGF0ZWQgb2JqZWN0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBkZXNlcmlhbGl6YXRpb24gZmFpbHMuCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZGVzZXJpYWxpemF0aW9uIGZhaWxzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgY2lwaGVyIGlzIGEgYmxvY2sgY2lwaGVyIGFuZCB0aGUgbGVuZ3RoIG9mCisgICAgICogICAgICAgICAgICAgdGhlIHNlcmlhbGl6ZWQgZGF0YSBpcyBub3QgYSBtdWx0aXBsZSBvZiB0aGUgY2lwaGVycyBibG9jaworICAgICAqICAgICAgICAgICAgIHNpemUuCisgICAgICogQHRocm93cyBCYWRQYWRkaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHBhZGRpbmcgb2YgdGhlIGRhdGEgZG9lcyBub3QgbWF0Y2ggdGhlIHBhZGRpbmcgc2NoZW1lLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBPYmplY3QgZ2V0T2JqZWN0KENpcGhlciBjKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiwgQmFkUGFkZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiYyA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIHNlcmlhbGl6ZWQgPSBjLmRvRmluYWwoZW5jcnlwdGVkQ29udGVudCk7CisgICAgICAgIE9iamVjdElucHV0U3RyZWFtIG9pcyA9CisgICAgICAgICAgICAgICAgbmV3IE9iamVjdElucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHNlcmlhbGl6ZWQpKTsKKyAgICAgICAgcmV0dXJuIG9pcy5yZWFkT2JqZWN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgd3JhcHBlZCBvYmplY3QsIGRlY3J5cHRpbmcgaXQgdXNpbmcgdGhlIHNwZWNpZmllZCBrZXkuIFRoZQorICAgICAqIHNwZWNpZmllZCBwcm92aWRlciBpcyB1c2VkIHRvIHJldHJpZXZlIHRoZSBjaXBoZXIgYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSB0byBkZWNyeXB0IHRoZSBkYXRhLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIHRoYXQgcHJvdmlkZXMgdGhlIGNpcGhlciBhbGdvcml0aG0uCisgICAgICogQHJldHVybiB0aGUgZW5jYXBzdWxhdGVkIG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZGVzZXJpYWxpemF0aW9uIGZhaWxzLgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGRlc2VyaWFsaXphdGlvbiBmYWlscy4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBhbGdvcml0aG0gdXNlZCB0byBkZWNyeXB0IHRoZSBkYXRhIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICogQHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgdXNlZCB0byBkZWNyeXB0IHRoZSBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBPYmplY3QgZ2V0T2JqZWN0KEtleSBrZXksIFN0cmluZyBwcm92aWRlcikKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCB8fCBwcm92aWRlci5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInByb3ZpZGVyIG5hbWUgZW1wdHkgb3IgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDaXBoZXIgY2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKHNlYWxBbGcsIHByb3ZpZGVyKTsKKyAgICAgICAgICAgIGlmICgocGFyYW1zQWxnICE9IG51bGwpICYmIChwYXJhbXNBbGcubGVuZ3RoKCkgIT0gMCkpIHsKKyAgICAgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtcyA9CisgICAgICAgICAgICAgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlcnMuZ2V0SW5zdGFuY2UocGFyYW1zQWxnKTsKKyAgICAgICAgICAgICAgICBwYXJhbXMuaW5pdChlbmNvZGVkUGFyYW1zKTsKKyAgICAgICAgICAgICAgICBjaXBoZXIuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLCBrZXksIHBhcmFtcyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGNpcGhlci5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGtleSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBieXRlW10gc2VyaWFsaXplZCA9IGNpcGhlci5kb0ZpbmFsKGVuY3J5cHRlZENvbnRlbnQpOworICAgICAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0gb2lzID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdElucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShzZXJpYWxpemVkKSk7CisgICAgICAgICAgICByZXR1cm4gb2lzLnJlYWRPYmplY3QoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbiBlKSAgeworICAgICAgICAgICAgLy8gc2hvdWxkIG5vdCBiZSB0aHJvd24gYmVjYXVzZSBjaXBoZXIgdGV4dCB3YXMgbWFkZQorICAgICAgICAgICAgLy8gd2l0aCBleGlzdGluZyBwYWRkaW5nCisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gc2hvdWxkIG5vdCBiZSB0aHJvd24gYmVjYXVzZSBjaXBoZXIgdGV4dCB3YXMgbWFkZQorICAgICAgICAgICAgLy8gd2l0aCBjb3JyZWN0IGFsZ29yaXRobSBwYXJhbWV0ZXJzCisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gc2hvdWxkIG5vdCBiZSB0aHJvd24gYmVjYXVzZSB0aGUgY2lwaGVyIHRleHQKKyAgICAgICAgICAgIC8vIHdhcyBjb3JyZWN0bHkgbWFkZQorICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbihlLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoIChCYWRQYWRkaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIHNob3VsZCBub3QgYmUgdGhyb3duIGJlY2F1c2UgdGhlIGNpcGhlciB0ZXh0CisgICAgICAgICAgICAvLyB3YXMgY29ycmVjdGx5IG1hZGUKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oZS50b1N0cmluZygpKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uICBlKSB7CisgICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgYmUgdGhyb3duIGJlY2F1c2UgY2lwaGVyIGlzIGluaXRpYWxpemVkCisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL1NlY3JldEtleS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9TZWNyZXRLZXkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYzYxMDc0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9TZWNyZXRLZXkuamF2YQpAQCAtMCwwICsxLDQxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LmNyeXB0bzsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5OworCisvKioKKyAqIEEgY3J5cHRvZ3JhcGhpYyBzZWNyZXQgKHN5bW1ldHJpYykga2V5LgorICogPHA+CisgKiBUaGlzIGludGVyZmFjZSBpcyBhIDxpPm1hcmtlciBpbnRlcmZhY2U8L2k+IHRvIGdyb3VwIHNlY3JldCBrZXlzIGFuZCB0bworICogcHJvdmlkZSB0eXBlIHNhZmV0eSBmb3IuCisgKiA8cD4KKyAqIEltcGxlbWVudGF0aW9ucyBvZiB0aGlzIGludGVyZmFjZSBoYXZlIHRvIG92ZXJ3cml0ZSB0aGUKKyAqIHtAbGluayBPYmplY3QjZXF1YWxzKE9iamVjdCkgZXF1YWxzfSBhbmQge0BsaW5rIE9iamVjdCNoYXNoQ29kZSgpIGhhc2hDb2RlfQorICogZnJvbSB7QGxpbmsgamF2YS5sYW5nLk9iamVjdH0gc28gY29tcGFyaXNvbiBpcyBkb25lIHVzaW5nIHRoZSBhY3R1YWwga2V5IGRhdGEKKyAqIGFuZCBub3QgdGhlIG9iamVjdCByZWZlcmVuY2UuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgU2VjcmV0S2V5IGV4dGVuZHMgS2V5IHsKKworICAgIC8qKgorICAgICAqIFRoZSBzZXJpYWxpemF0aW9uIHZlcnNpb24gaWRlbnRpZmllci4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00Nzk1ODc4NzA5NTk1MTQ2OTUyTDsKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL1NlY3JldEtleUZhY3RvcnkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vU2VjcmV0S2V5RmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVlNDdhYmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL1NlY3JldEtleUZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDIyMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkludmFsaWRLZXlTcGVjRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5LZXlTcGVjOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5mb3J0cmVzcy5FbmdpbmU7CisKKworLyoqCisgKiBUaGUgcHVibGljIEFQSSBmb3Ige0Bjb2RlIFNlY3JldEtleUZhY3Rvcnl9IGltcGxlbWVudGF0aW9ucy4KKyAqIDxwPgorICogU2VjcmV0IGtleSBmYWN0b3JpZXMgcHJvdmlkZSB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uYWxpdHk6CisgKiA8dWw+CisgKiA8bGk+Y29udmVydCB7QGxpbmsgU2VjcmV0S2V5fSBvYmplY3RzIHRvIGFuZCBmcm9tIHtAbGluayBLZXlTcGVjfSBvYmplY3RzPC9saT4KKyAqIDxsaT50cmFuc2xhdGUge0BsaW5rIFNlY3JldEtleX0gb2JqZWN0cyBmcm9tIG9uZSBwcm92aWRlciBpbXBsZW1lbnRhdGlvbiB0bworICogYW5vdGhlcjwvbGk+CisgKiA8L3VsPgorICogV2hpY2gga2V5IHNwZWNpZmljYXRpb25zIGFyZSBzdXBwb3J0ZWQgYnkgdGhlIHtAbGluayAjZ2VuZXJhdGVTZWNyZXR9IGFuZAorICoge0BsaW5rICNnZXRLZXlTcGVjfSBpcyBwcm92aWRlciBkZXBlbmRlbnQuCisgKi8KK3B1YmxpYyBjbGFzcyBTZWNyZXRLZXlGYWN0b3J5IHsKKworICAgIC8vIFVzZWQgdG8gYWNjZXNzIGNvbW1vbiBlbmdpbmUgZnVuY3Rpb25hbGl0eQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEVuZ2luZSBFTkdJTkUgPSBuZXcgRW5naW5lKCJTZWNyZXRLZXlGYWN0b3J5Iik7CisKKyAgICAvLyBTdG9yZSB1c2VkIHByb3ZpZGVyCisgICAgcHJpdmF0ZSBmaW5hbCBQcm92aWRlciBwcm92aWRlcjsKKworICAgIC8vIFN0b3JlIHVzZWQgc3BpIGltcGxlbWVudGF0aW9uCisgICAgcHJpdmF0ZSBmaW5hbCBTZWNyZXRLZXlGYWN0b3J5U3BpIHNwaUltcGw7CisKKyAgICAvLyBTdG9yZSB1c2VkIGFsZ29yaXRobSBuYW1lCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgYWxnb3JpdGhtOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgU2VjcmV0S2V5RmFjdG9yeX0KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXlGYWNTcGkKKyAgICAgKiAgICAgICAgICAgIHRoZSBTUEkgZGVsZWdhdGUuCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgcHJvdmlkZXIgcHJvdmlkaW5nIHRoaXMga2V5IGZhY3RvcnkuCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIGFsZ29yaXRobSBuYW1lIGZvciB0aGUgc2VjcmV0IGtleS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU2VjcmV0S2V5RmFjdG9yeShTZWNyZXRLZXlGYWN0b3J5U3BpIGtleUZhY1NwaSwKKyAgICAgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyLCBTdHJpbmcgYWxnb3JpdGhtKSB7CisgICAgICAgIHRoaXMucHJvdmlkZXIgPSBwcm92aWRlcjsKKyAgICAgICAgdGhpcy5hbGdvcml0aG0gPSBhbGdvcml0aG07CisgICAgICAgIHRoaXMuc3BpSW1wbCA9IGtleUZhY1NwaTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBzZWNyZXQga2V5IGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIHNlY3JldCBrZXkgYWxnb3JpdGhtLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICByZXR1cm4gYWxnb3JpdGhtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByb3ZpZGVyIGZvciB0aGlzIHtAY29kZSBTZWNyZXRLZXlGYWN0b3J5fSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByb3ZpZGVyIGZvciB0aGlzIHtAY29kZSBTZWNyZXRLZXlGYWN0b3J5fSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgUHJvdmlkZXIgZ2V0UHJvdmlkZXIoKSB7CisgICAgICAgIHJldHVybiBwcm92aWRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBTZWNyZXRLZXlGYWN0b3J5fSBpbnN0YW5jZSBmb3IgdGhlIHNwZWNpZmllZCBrZXkKKyAgICAgKiBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUga2V5IGFsZ29yaXRobS4KKyAgICAgKiBAcmV0dXJuIGEgc2VjcmV0IGtleSBmYWN0b3J5IGZvciB0aGUgc3BlY2lmaWVkIGtleSBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBpbnN0YWxsZWQgcHJvdmlkZXIgY2FuIHByb3ZpZGUgdGhlIHJlcXVlc3RlZCBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFNlY3JldEtleUZhY3RvcnkgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIEVuZ2luZS5TcGlBbmRQcm92aWRlciBzYXAgPSBFTkdJTkUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBudWxsKTsKKyAgICAgICAgcmV0dXJuIG5ldyBTZWNyZXRLZXlGYWN0b3J5KChTZWNyZXRLZXlGYWN0b3J5U3BpKSBzYXAuc3BpLCBzYXAucHJvdmlkZXIsIGFsZ29yaXRobSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgU2VjcmV0S2V5RmFjdG9yeX0gaW5zdGFuY2UgZm9yIHRoZSBzcGVjaWZpZWQga2V5CisgICAgICogYWxnb3JpdGhtIGZyb20gdGhlIHNwZWNpZmllZCB7QGNvZGUgcHJvdmlkZXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGtleSBhbGdvcml0aG0uCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcHJvdmlkZXIgdGhhdCBwcm92aWRlcyB0aGUgcmVxdWVzdGVkCisgICAgICogICAgICAgICAgICBhbGdvcml0aG0uCisgICAgICogQHJldHVybiBhIHNlY3JldCBrZXkgZmFjdG9yeSBmb3IgdGhlIHNwZWNpZmllZCBrZXkgYWxnb3JpdGhtIGZyb20gdGhlCisgICAgICogICAgICAgICBzcGVjaWZpZWQgcHJvdmlkZXIuCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGNhbm5vdCBwcm92aWRlIHRoZSByZXF1ZXN0ZWQKKyAgICAgKiAgICAgICAgICAgICBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgZG9lcyBub3QgZXhpc3QuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIG5hbWUgaXMge0Bjb2RlIG51bGx9IG9yIGVtcHR5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU2VjcmV0S2V5RmFjdG9yeSBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLAorICAgICAgICAgICAgU3RyaW5nIHByb3ZpZGVyKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCB8fCBwcm92aWRlci5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlByb3ZpZGVyIGlzIG51bGwgb3IgZW1wdHkiKTsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBpbXBQcm92aWRlciA9IFNlY3VyaXR5LmdldFByb3ZpZGVyKHByb3ZpZGVyKTsKKyAgICAgICAgaWYgKGltcFByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbihwcm92aWRlcik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEluc3RhbmNlKGFsZ29yaXRobSwgaW1wUHJvdmlkZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFNlY3JldEtleUZhY3Rvcnl9IGluc3RhbmNlIGZvciB0aGUgc3BlY2lmaWVkIGtleQorICAgICAqIGFsZ29yaXRobSBmcm9tIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUga2V5IGFsZ29yaXRobS4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm92aWRlciB0aGF0IHByb3ZpZGVzIHRoZSByZXF1ZXN0ZWQgYWxnb3JpdGhtLgorICAgICAqIEByZXR1cm4gYSBzZWNyZXQga2V5IGZhY3RvcnkgZm9yIHRoZSBzcGVjaWZpZWQga2V5IGFsZ29yaXRobSBmcm9tIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBjYW5ub3QgcHJvdmlkZXIgdGhlIHJlcXVlc3RlZAorICAgICAqICAgICAgICAgICAgIGFsZ29yaXRobS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpcyB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobSBuYW1lIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFNlY3JldEtleUZhY3RvcnkgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwKKyAgICAgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInByb3ZpZGVyID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIE9iamVjdCBzcGkgPSBFTkdJTkUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBwcm92aWRlciwgbnVsbCk7CisgICAgICAgIHJldHVybiBuZXcgU2VjcmV0S2V5RmFjdG9yeSgoU2VjcmV0S2V5RmFjdG9yeVNwaSkgc3BpLCBwcm92aWRlciwgYWxnb3JpdGhtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZSBhIHNlY3JldCBrZXkgZnJvbSB0aGUgc3BlY2lmaWVkIGtleSBzcGVjaWZpY2F0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGtleVNwZWMKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgc3BlY2lmaWNhdGlvbi4KKyAgICAgKiBAcmV0dXJuIGEgc2VjcmV0IGtleS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBrZXkgc3BlY2lmaWNhdGlvbiBjYW5ub3QgYmUgdXNlZCB0byBnZW5lcmF0ZQorICAgICAqICAgICAgICAgICAgIGEgc2VjcmV0IGtleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU2VjcmV0S2V5IGdlbmVyYXRlU2VjcmV0KEtleVNwZWMga2V5U3BlYykKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZUdlbmVyYXRlU2VjcmV0KGtleVNwZWMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGtleSBzcGVjaWZpY2F0aW9uIG9mIHRoZSBzcGVjaWZpZWQgc2VjcmV0IGtleS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNyZXQga2V5IHRvIGdldCB0aGUgc3BlY2lmaWNhdGlvbiBmcm9tLgorICAgICAqIEBwYXJhbSBrZXlTcGVjCisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IGtleSBzcGVjaWZpY2F0aW9uIGNsYXNzLgorICAgICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2YgdGhlIHNwZWNpZmllZCBrZXkgc3BlY2lmaWNhdGlvbiBjbGFzcy4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBzZWNyZXQga2V5IGNhbm5vdCBiZSB0cmFuc2Zvcm1lZCBpbnRvIHRoZQorICAgICAqICAgICAgICAgICAgIHJlcXVlc3RlZCBrZXkgc3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgZmluYWwgS2V5U3BlYyBnZXRLZXlTcGVjKFNlY3JldEtleSBrZXksIENsYXNzIGtleVNwZWMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVHZXRLZXlTcGVjKGtleSwga2V5U3BlYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJhbnNsYXRlcyB0aGUgc3BlY2lmaWVkIHNlY3JldCBrZXkgaW50byBhbiBpbnN0YW5jZSBvZiB0aGUgY29ycmVzcG9uZGluZworICAgICAqIGtleSBmcm9tIHRoZSBwcm92aWRlciBvZiB0aGlzIGtleSBmYWN0b3J5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIHNlY3JldCBrZXkgdG8gdHJhbnNsYXRlLgorICAgICAqIEByZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgdHJhbnNsYXRlZCBrZXkuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIHRyYW5zbGF0ZWQgdXNpbmcgdGhpcyBrZXkKKyAgICAgKiAgICAgICAgICAgICBmYWN0b3J5LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTZWNyZXRLZXkgdHJhbnNsYXRlS2V5KFNlY3JldEtleSBrZXkpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZVRyYW5zbGF0ZUtleShrZXkpOworCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9TZWNyZXRLZXlGYWN0b3J5U3BpLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL1NlY3JldEtleUZhY3RvcnlTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZDc3NjRlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9TZWNyZXRLZXlGYWN0b3J5U3BpLmphdmEKQEAgLTAsMCArMSw3OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkludmFsaWRLZXlTcGVjRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5LZXlTcGVjOworCisvKioKKyAqIFRoZSA8aT5TZXJ2aWNlIFByb3ZpZGVyIEludGVyZmFjZTwvaT4gKDxiPlNQSTwvYj4pIGRlZmluaXRpb24gZm9yIHRoZSB7QGNvZGUKKyAqIFNlY3JldEtleUZhY3Rvcnl9IGNsYXNzLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU2VjcmV0S2V5RmFjdG9yeVNwaSB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBTZWNyZXRLZXlGYWN0b3J5U3BpfSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2VjcmV0S2V5RmFjdG9yeVNwaSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZSBhIHNlY3JldCBrZXkgZnJvbSB0aGUgc3BlY2lmaWVkIGtleSBzcGVjaWZpY2F0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGtleVNwZWMKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgc3BlY2lmaWNhdGlvbi4KKyAgICAgKiBAcmV0dXJuIGEgc2VjcmV0IGtleS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBrZXkgc3BlY2lmaWNhdGlvbiBjYW5ub3QgYmUgdXNlZCB0byBnZW5lcmF0ZQorICAgICAqICAgICAgICAgICAgIGEgc2VjcmV0IGtleS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgU2VjcmV0S2V5IGVuZ2luZUdlbmVyYXRlU2VjcmV0KEtleVNwZWMga2V5U3BlYykKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGtleSBzcGVjaWZpY2F0aW9uIG9mIHRoZSBzcGVjaWZpZWQgc2VjcmV0IGtleS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBzZWNyZXQga2V5IHRvIGdldCB0aGUgc3BlY2lmaWNhdGlvbiBmcm9tLgorICAgICAqIEBwYXJhbSBrZXlTcGVjCisgICAgICogICAgICAgICAgICB0aGUgdGFyZ2V0IGtleSBzcGVjaWZpY2F0aW9uIGNsYXNzLgorICAgICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2YgdGhlIHNwZWNpZmllZCBrZXkgc3BlY2lmaWNhdGlvbiBjbGFzcy4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBzZWNyZXQga2V5IGNhbm5vdCBiZSB0cmFuc2Zvcm1lZCBpbnRvIHRoZQorICAgICAqICAgICAgICAgICAgIHJlcXVlc3RlZCBrZXkgc3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgS2V5U3BlYyBlbmdpbmVHZXRLZXlTcGVjKFNlY3JldEtleSBrZXksIENsYXNzIGtleVNwZWMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBUcmFuc2xhdGVzIHRoZSBzcGVjaWZpZWQgc2VjcmV0IGtleSBpbnRvIGFuIGluc3RhbmNlIG9mIHRoZSBjb3JyZXNwb25kaW5nCisgICAgICoga2V5IGZyb20gdGhlIHByb3ZpZGVyIG9mIHRoaXMga2V5IGZhY3RvcnkuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUgc2VjcmV0IGtleSB0byB0cmFuc2xhdGUuCisgICAgICogQHJldHVybiB0aGUgY29ycmVzcG9uZGluZyB0cmFuc2xhdGVkIGtleS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgdHJhbnNsYXRlZCB1c2luZyB0aGlzIGtleQorICAgICAqICAgICAgICAgICAgIGZhY3RvcnkuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IFNlY3JldEtleSBlbmdpbmVUcmFuc2xhdGVLZXkoU2VjcmV0S2V5IGtleSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uOworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vU2hvcnRCdWZmZXJFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vU2hvcnRCdWZmZXJFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZmRmYzA3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9TaG9ydEJ1ZmZlckV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbjsKKworLyoqCisgKiBUaGUgZXhjZXB0aW9uIHRoYXQgaXMgdGhyb3duIHdoZW4gdGhlIHJlc3VsdCBvZiBhbiBvcGVyYXRpb24gaXMgYXR0ZW1wdGVkIHRvCisgKiBzdG9yZSBpbiBhIHVzZXIgcHJvdmlkZWQgYnVmZmVyIHRoYXQgaXMgdG9vIHNtYWxsLgorICovCitwdWJsaWMgY2xhc3MgU2hvcnRCdWZmZXJFeGNlcHRpb24gZXh0ZW5kcyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24geworCisgICAgLyoqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDg0Mjc3MTg2NDA4MzI5NDM3NDdMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB7QGNvZGUgU2hvcnRCdWZmZXJFeGNlcHRpb259IHdpdGggdGhlCisgICAgICogc3BlY2lmaWVkIG1lc3NhZ2UKKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBleGNlcHRpb24gbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2hvcnRCdWZmZXJFeGNlcHRpb24oU3RyaW5nIG1zZykgeworICAgICAgICBzdXBlcihtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2Yge0Bjb2RlIFNob3J0QnVmZmVyRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2hvcnRCdWZmZXJFeGNlcHRpb24oKSB7CisgICAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vaW50ZXJmYWNlcy9ESEtleS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9pbnRlcmZhY2VzL0RIS2V5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmVmMTdkNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vaW50ZXJmYWNlcy9ESEtleS5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguY3J5cHRvLmludGVyZmFjZXM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5ESFBhcmFtZXRlclNwZWM7CisKKy8qKgorICogVGhlIGludGVyZmFjZSBmb3IgYSBEaWZmaWUtSGVsbG1hbiBrZXkuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgREhLZXkgeworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGFyYW1ldGVycyBmb3IgdGhpcyBrZXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIGtleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgREhQYXJhbWV0ZXJTcGVjIGdldFBhcmFtcygpOworfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL2ludGVyZmFjZXMvREhQcml2YXRlS2V5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL2ludGVyZmFjZXMvREhQcml2YXRlS2V5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjYzZTBjYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vaW50ZXJmYWNlcy9ESFByaXZhdGVLZXkuamF2YQpAQCAtMCwwICsxLDM5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LmNyeXB0by5pbnRlcmZhY2VzOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworCisvKioKKyAqIFRoZSBpbnRlcmZhY2UgZm9yIGEgcHJpdmF0ZSBrZXkgaW4gdGhlIERpZmZpZS1IZWxsbWFuIGtleSBleGNoYW5nZSBwcm90b2NvbC4KKyAqLworcHVibGljIGludGVyZmFjZSBESFByaXZhdGVLZXkgZXh0ZW5kcyBESEtleSwgUHJpdmF0ZUtleSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc2VyaWFsaXphdGlvbiB2ZXJzaW9uIGlkZW50aWZpZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAyMjExNzkxMTEzMzgwMzk2NTUzTDsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBrZXkncyBwcml2YXRlIHZhbHVlIHguCisgICAgICogQHJldHVybiB0aGlzIGtleSdzIHByaXZhdGUgdmFsdWUgeC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRYKCk7CisKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL2ludGVyZmFjZXMvREhQdWJsaWNLZXkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vaW50ZXJmYWNlcy9ESFB1YmxpY0tleS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkyZThmMTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL2ludGVyZmFjZXMvREhQdWJsaWNLZXkuamF2YQpAQCAtMCwwICsxLDM4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LmNyeXB0by5pbnRlcmZhY2VzOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CisKKy8qKgorICogVGhlIGludGVyZmFjZSBmb3IgYSBwdWJsaWMga2V5IGluIHRoZSBEaWZmaWUtSGVsbG1hbiBrZXkgZXhjaGFuZ2UgcHJvdG9jb2wuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgREhQdWJsaWNLZXkgZXh0ZW5kcyBESEtleSwgUHVibGljS2V5IHsKKworICAgIC8qKgorICAgICAqIFRoZSBzZXJpYWwgdmVyc2lvbiBpZGVudGlmaWVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTY2MjgxMDM1NjMzNTI1MTkxOTNMOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIGtleSdzIHB1YmxpYyB2YWx1ZSBZLgorICAgICAqIEByZXR1cm4gdGhpcyBrZXkncyBwdWJsaWMgdmFsdWUgWS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRZKCk7Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9pbnRlcmZhY2VzL1BCRUtleS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9pbnRlcmZhY2VzL1BCRUtleS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM3MTg3MTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL2ludGVyZmFjZXMvUEJFS2V5LmphdmEKQEAgLTAsMCArMSw1MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG8uaW50ZXJmYWNlczsKKworaW1wb3J0IGphdmF4LmNyeXB0by5TZWNyZXRLZXk7CisKKy8qKgorICogVGhlIGludGVyZmFjZSB0byBhIDxpPnBhc3N3b3JkLWJhc2VkLWVuY3J5cHRpb248L2k+ICBrZXkuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUEJFS2V5IGV4dGVuZHMgU2VjcmV0S2V5IHsKKworICAgIC8qKgorICAgICAqIFRoZSBzZXJpYWwgdmVyc2lvbiBpZGVudGlmaWVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTE0MzAwMTU5OTMzMDQzMzM5MjFMOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaXRlcmF0aW9uIGNvdW50LCAwIGlmIG5vdCBzcGVjaWZpZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpdGVyYXRpb24gY291bnQsIDAgaWYgbm90IHNwZWNpZmllZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEl0ZXJhdGlvbkNvdW50KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29weSBvZiB0aGUgc2FsdCBkYXRhIG9yIG51bGwgaWYgbm90IHNwZWNpZmllZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBjb3B5IG9mIHRoZSBzYWx0IGRhdGEgb3IgbnVsbCBpZiBub3Qgc3BlY2lmaWVkLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0U2FsdCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvcHkgdG8gdGhlIHBhc3N3b3JkLgorICAgICAqCisgICAgICogQHJldHVybiBhIGNvcHkgdG8gdGhlIHBhc3N3b3JkLgorICAgICAqLworICAgIHB1YmxpYyBjaGFyW10gZ2V0UGFzc3dvcmQoKTsKKworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vaW50ZXJmYWNlcy9wYWNrYWdlLmh0bWwgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL2ludGVyZmFjZXMvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyNzgzMTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL2ludGVyZmFjZXMvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMTEgQEAKKzxodG1sPgorICA8Ym9keT4KKyAgICA8cD4KKyAgICAgIFRoaXMgcGFja2FnZSBwcm92aWRlcyB0aGUgaW50ZXJmYWNlcyBuZWVkZWQgdG8gaW1wbGVtZW50IHRoZSAKKyAgICAgIERpZmZpZS1IZWxsbWFuIChESCkga2V5IGFncmVlbWVudCdzIGFsZ29yaXRobSBhcyBzcGVjaWZpZWQgYnkgUEtDUyMzLgorCisgICAgICBUaGUgcGFyYW1ldGVycyBmb3IgdGhlIERIIGFsZ29yaXRobSBtdXN0IGJlIGFjY2Vzc2VkIHdpdGhvdXQgdW5kdWx5IAorICAgICAgcmVzdHJpY3Rpb24gYXMgZm9yIGV4YW1wbGUgaGFyZHdhcmUgcmVwb3NpdG9yeSBmb3IgdGhlIHBhcmFtZXRlcnMgbWF0ZXJpYWwuCisgICAgPC9wPgorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL3BhY2thZ2UuaHRtbCBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyMzliNzIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDE4IEBACis8aHRtbD4KKzxoZWFkPgorPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXMtYXNjaWkiPgorPC9oZWFkPgorPGh0bWw+Cis8Ym9keT4KKzxwPgorVGhpcyBwYWNrYWdlIHByb3ZpZGVzIHRoZSBjbGFzc2VzIGFuZCBpbnRlcmZhY2VzIGZvciBjcnlwdG9ncmFwaGljIGFwcGxpY2F0aW9ucyBpbXBsZW1lbnRpbmcgYWxnb3JpdGhtcyBmb3IgZW5jcnlwdGlvbiwgZGVjcnlwdGlvbiwgb3IKK2tleSBhZ3JlZW1lbnQuIAorPC9wPjxwPgorU3RyZWFtIGNpcGhlcnMgYXJlIHN1cHBvcnRlZCBhcyB3ZWxsIGFzIGFzeW1tZXRyaWMsIHN5bW1ldHJpYyBhbmQgYmxvY2sgY2lwaGVycy4gQ2lwaGVyIGltcGxlbWVudGF0aW9ucyBmcm9tIGRpZmZlcmVudCBwcm92aWRlcnMgY2FuIGJlIGludGVncmF0ZWQgdXNpbmcKK3RoZSBTUEkgKFNlcnZpY2UgUHJvdmlkZXIgSW50ZXJmYWNlKSBhYnN0cmFjdCBjbGFzc2VzLiBXaXRoIGNsYXNzIHtAbGluayBqYXZheC5jcnlwdG8uU2VhbGVkT2JqZWN0fSBhIHByb2dyYW1tZXIgY2FuIHNlY3VyZSBhbiBvYmplY3QgYnkKK2VuY3J5cHRpbmcgaXQgd2l0aCBhIGNpcGhlci4KKzwvcD48cD4KK0F1dGhlbnRpY2F0aW9uIG1heSBiZSBiYXNlZCBvbiBNQUMgKE1lc3NhZ2UgQXV0aGVudGljYXRpb24gQ29kZSkgc3VjaCBhcyBITUFDIChIYXNoIE1BQywgaS5lLiB3aXRoIGEgU0hBLTEgaGFzaCBmdW5jdGlvbikuCis8L3A+Cis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL3NwZWMvREVTS2V5U3BlYy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL0RFU0tleVNwZWMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45OTZmOGZlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL0RFU0tleVNwZWMuamF2YQpAQCAtMCwwICsxLDIwOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuS2V5U3BlYzsKKworLyoqCisgKiBUaGUga2V5IHNwZWNpZmljYXRpb24gZm9yIGEgREVTIGtleS4KKyAqLworcHVibGljIGNsYXNzIERFU0tleVNwZWMgaW1wbGVtZW50cyBLZXlTcGVjIHsKKworICAgIC8qKgorICAgICAqIFRoZSBsZW5ndGggb2YgYSBERVMga2V5IGluIGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFU19LRVlfTEVOID0gODsKKworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGtleTsKKworICAgIC8vIERFUyB3ZWFrIGFuZCBzZW1pLXdlYWsga2V5cworICAgIC8vIEdvdCBmcm9tOgorICAgIC8vIEZJUCBQVUIgNzQKKyAgICAvLyBGRURFUkFMIElORk9STUFUSU9OIFBST0NFU1NJTkcgU1RBTkRBUkRTIFBVQkxJQ0FUSU9OIDE5ODEKKyAgICAvLyBHVUlERUxJTkVTIEZPUiBJTVBMRU1FTlRJTkcgQU5EIFVTSU5HIFRIRSBOQlMgREFUQSBFTkNSWVBUSU9OIFNUQU5EQVJECisgICAgLy8gaHR0cDovL3d3dy5kaWNlLnVjbC5hYy5iZS9jcnlwdG8vc3RhbmRhcmRzL2ZpcHMvZmlwNzQvZmlwNzQtMS5wZGYKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW11bXSBTRU1JV0VBS1MgPSB7CisgICAgICAgICAgICAgICAgeyhieXRlKSAweEUwLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4RTAsIChieXRlKSAweDAxLAorICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweEYxLCAoYnl0ZSkgMHgwMX0sCisKKyAgICAgICAgICAgICAgICB7KGJ5dGUpIDB4MDEsIChieXRlKSAweEUwLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4RTAsCisgICAgICAgICAgICAgICAgIChieXRlKSAweDAxLCAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweEYxfSwKKworICAgICAgICAgICAgICAgIHsoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4MUYsIChieXRlKSAweEZFLCAoYnl0ZSkgMHgxRiwKKyAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4RkUsIChieXRlKSAweDBFLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4MEV9LAorCisgICAgICAgICAgICAgICAgeyhieXRlKSAweDFGLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4MUYsIChieXRlKSAweEZFLAorICAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwRSwgKGJ5dGUpIDB4RkUsIChieXRlKSAweDBFLCAoYnl0ZSkgMHhGRX0sCisKKyAgICAgICAgICAgICAgICB7KGJ5dGUpIDB4RTAsIChieXRlKSAweDFGLCAoYnl0ZSkgMHhFMCwgKGJ5dGUpIDB4MUYsCisgICAgICAgICAgICAgICAgIChieXRlKSAweEYxLCAoYnl0ZSkgMHgwRSwgKGJ5dGUpIDB4RjEsIChieXRlKSAweDBFfSwKKworICAgICAgICAgICAgICAgIHsoYnl0ZSkgMHgxRiwgKGJ5dGUpIDB4RTAsIChieXRlKSAweDFGLCAoYnl0ZSkgMHhFMCwKKyAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MEUsIChieXRlKSAweEYxLCAoYnl0ZSkgMHgwRSwgKGJ5dGUpIDB4RjF9LAorCisgICAgICAgICAgICAgICAgeyhieXRlKSAweDAxLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweEZFLAorICAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4RkUsIChieXRlKSAweDAxLCAoYnl0ZSkgMHhGRX0sCisKKyAgICAgICAgICAgICAgICB7KGJ5dGUpIDB4RkUsIChieXRlKSAweDAxLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4MDEsCisgICAgICAgICAgICAgICAgIChieXRlKSAweEZFLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4RkUsIChieXRlKSAweDAxfSwKKworICAgICAgICAgICAgICAgIHsoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MUYsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgxRiwKKyAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweDBFLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MEV9LAorCisgICAgICAgICAgICAgICAgeyhieXRlKSAweDFGLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MUYsIChieXRlKSAweDAxLAorICAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwRSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDBFLCAoYnl0ZSkgMHgwMX0sCisKKyAgICAgICAgICAgICAgICB7KGJ5dGUpIDB4RTAsIChieXRlKSAweEZFLCAoYnl0ZSkgMHhFMCwgKGJ5dGUpIDB4RkUsCisgICAgICAgICAgICAgICAgIChieXRlKSAweEYxLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4RjEsIChieXRlKSAweEZFfSwKKworICAgICAgICAgICAgICAgIHsoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4RTAsIChieXRlKSAweEZFLCAoYnl0ZSkgMHhFMCwKKyAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4RkUsIChieXRlKSAweEYxLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4RjF9LAorCisgICAgICAgICAgICAgICAgeyhieXRlKSAweDAxLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAxLAorICAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMX0sCisKKyAgICAgICAgICAgICAgICB7KGJ5dGUpIDB4RkUsIChieXRlKSAweEZFLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4RkUsCisgICAgICAgICAgICAgICAgIChieXRlKSAweEZFLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4RkUsIChieXRlKSAweEZFfSwKKworICAgICAgICAgICAgICAgIHsoYnl0ZSkgMHhFMCwgKGJ5dGUpIDB4RTAsIChieXRlKSAweEUwLCAoYnl0ZSkgMHhFMCwKKyAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4RjEsIChieXRlKSAweEYxLCAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4RjF9LAorCisgICAgICAgICAgICAgICAgeyhieXRlKSAweDFGLCAoYnl0ZSkgMHgxRiwgKGJ5dGUpIDB4MUYsIChieXRlKSAweDFGLAorICAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwRSwgKGJ5dGUpIDB4MEUsIChieXRlKSAweDBFLCAoYnl0ZSkgMHgwRX0sCisKKyAgICAgICAgICAgICAgICB9OworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5ERVNLZXlTcGVjPC9jb2RlPiBmcm9tIHRoZSBmaXJzdCA4IGJ5dGVzIG9mIHRoZQorICAgICAqIHNwZWNpZmllZCBrZXkgZGF0YS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgZGF0YS4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbGVuZ3RoIG9mIHRoZSBzcGVjaWZpZWQga2V5IGRhdGEgaXMgbGVzcyB0aGFuIDguCisgICAgICovCisgICAgcHVibGljIERFU0tleVNwZWMoYnl0ZVtdIGtleSkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICB0aGlzKGtleSwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5ERVNLZXlTcGVjPC9jb2RlPiBmcm9tIHRoZSBmaXJzdCA4IGJ5dGVzIG9mIHRoZQorICAgICAqIHNwZWNpZmllZCBrZXkgZGF0YSBzdGFydGluZyBhdCA8Y29kZT5vZmZzZXQ8L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBkYXRhCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCB0byBzdGFydCBhdC4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbGVuZ3RoIG9mIHRoZSBzcGVjaWZpZWQga2V5IGRhdGEgc3RhcnRpbmcgYXQgb2Zmc2V0IGlzCisgICAgICogICAgICAgICAgICAgbGVzcyB0aGFuIDguCisgICAgICovCisgICAgcHVibGljIERFU0tleVNwZWMoYnl0ZVtdIGtleSwgaW50IG9mZnNldCkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigia2V5ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoa2V5Lmxlbmd0aCAtIG9mZnNldCA8IERFU19LRVlfTEVOKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbigia2V5IHRvbyBzaG9ydCIpOworICAgICAgICB9CisgICAgICAgIHRoaXMua2V5ID0gbmV3IGJ5dGVbREVTX0tFWV9MRU5dOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGtleSwgb2Zmc2V0LCB0aGlzLmtleSwgMCwgREVTX0tFWV9MRU4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb3B5IG9mIHRoZSBrZXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGUga2V5LgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0S2V5KCkgeworICAgICAgICBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbREVTX0tFWV9MRU5dOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRoaXMua2V5LCAwLCByZXN1bHQsIDAsIERFU19LRVlfTEVOKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBrZXkgZGF0YSBzdGFydGluZyBhdCA8Y29kZT5vZmZzZXQ8L2NvZGU+IGlzCisgICAgICogPGk+cGFyaXR5LWFkanVzdGVkPC9pPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgZGF0YS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IHRvIHN0YXJ0IGNoZWNraW5nIGF0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQga2V5IGRhdGEgaXMgcGFyaXR5LWFkanVzdGVkLAorICAgICAqICAgICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGxlbmd0aCBvZiB0aGUga2V5IGRhdGEgc3RhcnRpbmcgYXQgb2Zmc2V0IGlzIGxlc3MgdGhhbgorICAgICAqICAgICAgICAgICAgIDgsIG9yIHRoZSBrZXkgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNQYXJpdHlBZGp1c3RlZChieXRlW10ga2V5LCBpbnQgb2Zmc2V0KSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oImtleSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGtleS5sZW5ndGggLSBvZmZzZXQgPCBERVNfS0VZX0xFTikgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oImtleSB0b28gc2hvcnQiKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBieXRlS2V5ID0gMDsKKworICAgICAgICBmb3IgKGludCBpID0gb2Zmc2V0OyBpIDwgREVTX0tFWV9MRU47IGkrKykgeworICAgICAgICAgICAgYnl0ZUtleSA9IGtleVtpXTsKKworICAgICAgICAgICAgYnl0ZUtleSBePSBieXRlS2V5ID4+IDE7CisgICAgICAgICAgICBieXRlS2V5IF49IGJ5dGVLZXkgPj4gMjsKKyAgICAgICAgICAgIGJ5dGVLZXkgXj0gYnl0ZUtleSA+PiA0OworCisgICAgICAgICAgICBpZiAoKGJ5dGVLZXkgJiAxKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgc3BlY2lmaWVkIGtleSBkYXRhIHN0YXJ0aW5nIGF0IDxjb2RlPm9mZnNldDwvY29kZT4gaXMKKyAgICAgKiB3ZWFrIG9yIHNlbWktd2Vhay4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgZGF0YS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IHRvIHN0YXJ0IGNoZWNraW5nIGF0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQga2V5IGRhdGEgaXMgd2VhayBvciBzZW1pLXdlYWsuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGxlbmd0aCBvZiB0aGUga2V5IGRhdGEgc3RhcnRpbmcgYXQgb2Zmc2V0IGlzIGxlc3MgdGhhbgorICAgICAqICAgICAgICAgICAgIDgsIG9yIGl0IGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzV2VhayhieXRlW10ga2V5LCBpbnQgb2Zmc2V0KSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oImtleSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGtleS5sZW5ndGggLSBvZmZzZXQgPCBERVNfS0VZX0xFTikgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oImtleSB0b28gc2hvcnQiKTsKKyAgICAgICAgfQorICAgICAgICBJOgorICAgICAgICBmb3IgKGludCBpPTA7IGk8U0VNSVdFQUtTLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGludCBqPTA7IGo8REVTX0tFWV9MRU47IGorKykgeworICAgICAgICAgICAgICAgIGlmIChTRU1JV0VBS1NbaV1bal0gIT0ga2V5W29mZnNldCtqXSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBJOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL3NwZWMvREVTZWRlS2V5U3BlYy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL0RFU2VkZUtleVNwZWMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZTg2YWViCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL0RFU2VkZUtleVNwZWMuamF2YQpAQCAtMCwwICsxLDEyMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuS2V5U3BlYzsKKworLyoqCisgKiBUaGUga2V5IHNwZWNpZmljYXRpb24gZm9yIGEgdHJpcGxlLURFUyAoREVTLUVERSkga2V5LgorICovCitwdWJsaWMgY2xhc3MgREVTZWRlS2V5U3BlYyBpbXBsZW1lbnRzIEtleVNwZWMgeworCisgICAgLyoqCisgICAgICogVGhlIGxlbmd0aCBvZiBhIERFUy1FREUga2V5IGluIGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFU19FREVfS0VZX0xFTiA9IDI0OworCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10ga2V5OworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5ERVNlZGVLZXlTcGVjPC9jb2RlPiBpbnN0YW5jZSBmcm9tIHRoZSBmaXJzdCAyNCAoCisgICAgICoge0BsaW5rICNERVNfRURFX0tFWV9MRU59KSBieXRlcyBvZiB0aGUgc3BlY2lmaWVkIGtleSBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBkYXRhLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBsZW5ndGggb2YgdGhlIGtleSBkYXRhIGlzIGxlc3MgdGhhbiAyNC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGtleSBkYXRhIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIERFU2VkZUtleVNwZWMoYnl0ZVtdIGtleSkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChrZXkubGVuZ3RoIDwgREVTX0VERV9LRVlfTEVOKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMua2V5ID0gbmV3IGJ5dGVbREVTX0VERV9LRVlfTEVOXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShrZXksIDAsIHRoaXMua2V5LCAwLCBERVNfRURFX0tFWV9MRU4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+REVTZWRlS2V5U3BlYzwvY29kZT4gaW5zdGFuY2UgZnJvbSB0aGUgZmlyc3QgMjQgKAorICAgICAqIHtAbGluayAjREVTX0VERV9LRVlfTEVOfSApIGJ5dGVzIG9mIHRoZSBzcGVjaWZpZWQga2V5IGRhdGEgc3RhcnRpbmcgYXQKKyAgICAgKiA8Y29kZT5vZmZzZXQ8L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBkYXRhCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCB0byBzdGFydCBhdC4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgbGVuZ3RoIG9mIHRoZSBrZXkgZGF0YSBzdGFydGluZyBhdCBvZmZzZXQgaXMgbGVzcyB0aGFuCisgICAgICogICAgICAgICAgICAgMjQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBrZXkgZGF0YSBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBERVNlZGVLZXlTcGVjKGJ5dGVbXSBrZXksIGludCBvZmZzZXQpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoa2V5Lmxlbmd0aCAtIG9mZnNldCA8IERFU19FREVfS0VZX0xFTikgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmtleSA9IG5ldyBieXRlW0RFU19FREVfS0VZX0xFTl07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoa2V5LCBvZmZzZXQsIHRoaXMua2V5LCAwLCBERVNfRURFX0tFWV9MRU4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb3B5IG9mIHRoZSBrZXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGUga2V5LgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0S2V5KCkgeworICAgICAgICBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGUgW0RFU19FREVfS0VZX0xFTl07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodGhpcy5rZXksIDAsIHJlc3VsdCwgMCwgREVTX0VERV9LRVlfTEVOKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBrZXkgZGF0YSBzdGFydGluZyBhdCA8Y29kZT5vZmZzZXQ8L2NvZGU+IGlzCisgICAgICogPGk+cGFyaXR5LWFkanVzdGVkPC9pPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgZGF0YS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IHRvIHN0YXJ0IGNoZWNraW5nIGF0LgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQga2V5IGRhdGEgaXMgcGFyaXR5LWFkanVzdGVkLAorICAgICAqICAgICAgICAgICAge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGxlbmd0aCBvZiB0aGUga2V5IGRhdGEgc3RhcnRpbmcgYXQgb2Zmc2V0IGlzIGxlc3MgdGhhbgorICAgICAqICAgICAgICAgICAgIDI0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1Bhcml0eUFkanVzdGVkKGJ5dGVbXSBrZXksIGludCBvZmZzZXQpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGtleS5sZW5ndGggLSBvZmZzZXQgPCBERVNfRURFX0tFWV9MRU4pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaT1vZmZzZXQ7IGk8REVTX0VERV9LRVlfTEVOK29mZnNldDsgaSsrKSB7CisgICAgICAgICAgICBpbnQgYiA9IGtleVtpXTsKKyAgICAgICAgICAgIGlmICgoKChiICYgMSkgKyAoKGIgJiAyKSA+PiAxKSArICgoYiAmIDQpID4+IDIpCisgICAgICAgICAgICAgICAgKyAoKGIgJiA4KSA+PiAzKSArICgoYiAmIDE2KSA+PiA0KSArICgoYiAmIDMyKSA+PiA1KQorICAgICAgICAgICAgICAgICsgKChiICYgNjQpID4+IDYpKSAmIDEpID09ICgoYiAmIDEyOCkgPj4gNykpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL0RIR2VuUGFyYW1ldGVyU3BlYy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL0RIR2VuUGFyYW1ldGVyU3BlYy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY2ZGRjMDMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL3NwZWMvREhHZW5QYXJhbWV0ZXJTcGVjLmphdmEKQEAgLTAsMCArMSw2MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworCisvKioKKyAqIFRoZSBhbGdvcml0aG0gcGFyYW1ldGVyIHNwZWNpZmljYXRpb24gZm9yIGdlbmVyYXRpbmcgRGlmZmllLUhlbGxtYW4KKyAqIHBhcmFtZXRlcnMgdXNlZCBpbiBEaWZmaWUtSGVsbG1hbiBrZXkgYWdyZWVtZW50LgorICovCitwdWJsaWMgY2xhc3MgREhHZW5QYXJhbWV0ZXJTcGVjIGltcGxlbWVudHMgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyB7CisKKyAgICBwcml2YXRlIGZpbmFsIGludCBwcmltZVNpemU7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgZXhwb25lbnRTaXplOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5ESEdlblBhcmFtZXRlclNwZWM8L2NvZGU+IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJpbWVTaXplCisgICAgICogICAgICAgICAgICB0aGUgc2l6ZSBvZiB0aGUgPGk+cHJpbWUgbW9kdWx1czwvaT4gaW4gYml0cy4KKyAgICAgKiBAcGFyYW0gZXhwb25lbnRTaXplCisgICAgICogICAgICAgICAgICB0aGUgc2l6ZSBvZiB0aGUgPGk+cmFuZG9tIGV4cG9uZW50PC9pPiBpbiBiaXRzLgorICAgICAqLworICAgIHB1YmxpYyBESEdlblBhcmFtZXRlclNwZWMoaW50IHByaW1lU2l6ZSwgaW50IGV4cG9uZW50U2l6ZSkgeworICAgICAgICB0aGlzLnByaW1lU2l6ZSA9IHByaW1lU2l6ZTsKKyAgICAgICAgdGhpcy5leHBvbmVudFNpemUgPSBleHBvbmVudFNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2l6ZSBvZiB0aGUgPGk+cHJpbWUgbW9kdWx1czwvaT4gaW4gYml0cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNpemUgb2YgdGhlIHByaW1lIG1vZHVsdXMgaW4gYml0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFByaW1lU2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIHByaW1lU2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzaXplIG9mIHRoZSA8aT5yYW5kb20gZXhwb25lbnQ8L2k+IGluIGJpdHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzaXplIG9mIHRoZSByYW5kb20gZXhwb25lbnQgaW4gYml0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEV4cG9uZW50U2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIGV4cG9uZW50U2l6ZTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vc3BlYy9ESFBhcmFtZXRlclNwZWMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vc3BlYy9ESFBhcmFtZXRlclNwZWMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MDMwYjQwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL0RIUGFyYW1ldGVyU3BlYy5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguY3J5cHRvLnNwZWM7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKKworLyoqCisgKiBUaGUgYWxnb3JpdGhtIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uIGZvciB0aGUgRGlmZmllLUhlbGxtYW4gYWxnb3JpdGhtLgorICovCitwdWJsaWMgY2xhc3MgREhQYXJhbWV0ZXJTcGVjIGltcGxlbWVudHMgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyB7CisKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgcDsKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgZzsKKyAgICBwcml2YXRlIGZpbmFsIGludCBsOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5ESFBhcmFtZXRlclNwZWM8L2NvZGU+IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIDxpPnByaW1lIG1vZHVsdXM8L2k+IGFuZCA8aT5iYXNlIGdlbmVyYXRvcjwvaT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcAorICAgICAqICAgICAgICAgICAgdGhlIHByaW1lIG1vZHVsdXMuCisgICAgICogQHBhcmFtIGcKKyAgICAgKiAgICAgICAgICAgIHRoZSBiYXNlIGdlbmVyYXRvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgREhQYXJhbWV0ZXJTcGVjKEJpZ0ludGVnZXIgcCwgQmlnSW50ZWdlciBnKSB7CisgICAgICAgIHRoaXMucCA9IHA7CisgICAgICAgIHRoaXMuZyA9IGc7CisgICAgICAgIHRoaXMubCA9IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5ESFBhcmFtZXRlclNwZWM8L2NvZGU+IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIDxpPnByaW1lIG1vZHVsdXM8L2k+LCA8aT5iYXNlIGdlbmVyYXRvcjwvaT4gYW5kIHNpemUgKGluIGJpdHMpIG9mIHRoZQorICAgICAqIDxpPnJhbmRvbSBleHBvbmVudDwvaT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcAorICAgICAqICAgICAgICAgICAgdGhlIHByaW1lIG1vZHVsdXMuCisgICAgICogQHBhcmFtIGcKKyAgICAgKiAgICAgICAgICAgIHRoZSBiYXNlIGdlbmVyYXRvci4KKyAgICAgKiBAcGFyYW0gbAorICAgICAqICAgICAgICAgICAgdGhlIHNpemUgb2YgdGhlIHJhbmRvbSBleHBvbmVudCAoaW4gYml0cykuCisgICAgICovCisgICAgcHVibGljIERIUGFyYW1ldGVyU3BlYyhCaWdJbnRlZ2VyIHAsIEJpZ0ludGVnZXIgZywgaW50IGwpIHsKKyAgICAgICAgdGhpcy5wID0gcDsKKyAgICAgICAgdGhpcy5nID0gZzsKKyAgICAgICAgdGhpcy5sID0gbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSA8aT5wcmltZSBtb2R1bHVzPC9pPiBvZiB0aGlzIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJpbWUgbW9kdWx1cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQKCkgeworICAgICAgICByZXR1cm4gcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSA8aT5iYXNlIGdlbmVyYXRvcjwvaT4gb2YgdGhpcyBwYXJhbWV0ZXIgc3BlY2lmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJhc2UgZ2VuZXJhdG9yLgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldEcoKSB7CisgICAgICAgIHJldHVybiBnOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNpemUgKGluIGJpdHMpIG9mIHRoZSA8aT5yYW5kb20gZXhwb25lbnQ8L2k+LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc2l6ZSAoaW4gYml0cykgb2YgdGhlIHJhbmRvbSBleHBvbmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEwoKSB7CisgICAgICAgIHJldHVybiBsOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL0RIUHJpdmF0ZUtleVNwZWMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vc3BlYy9ESFByaXZhdGVLZXlTcGVjLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTI1YTAwMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vc3BlYy9ESFByaXZhdGVLZXlTcGVjLmphdmEKQEAgLTAsMCArMSw3NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5LZXlTcGVjOworCisvKioKKyAqIFRoZSBrZXkgc3BlY2lmaWNhdGlvbiBmb3IgYSBEaWZmaWUtSGVsbG1hbiBwcml2YXRlIGtleS4KKyAqLworcHVibGljIGNsYXNzIERIUHJpdmF0ZUtleVNwZWMgaW1wbGVtZW50cyBLZXlTcGVjIHsKKworICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciB4OworICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBwOworICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBnOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5ESFByaXZhdGVLZXlTcGVjPC9jb2RlPiB3aXRoIHRoZSBzcGVjaWZpZWQgPGk+cHJpdmF0ZQorICAgICAqIHZhbHVlPC9pPiA8Y29kZT54PC9jb2RlPi4gPGk+cHJpbWUgbW9kdWx1czwvaT4gPGNvZGU+cDwvY29kZT4gYW5kIDxpPmJhc2UKKyAgICAgKiBnZW5lcmF0b3I8L2k+IDxjb2RlPmc8L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtIHgKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcml2YXRlIHZhbHVlLgorICAgICAqIEBwYXJhbSBwCisgICAgICogICAgICAgICAgICB0aGUgcHJpbWUgbW9kdWx1cy4KKyAgICAgKiBAcGFyYW0gZworICAgICAqICAgICAgICAgICAgdGhlIGJhc2UgZ2VuZXJhdG9yLgorICAgICAqLworICAgIHB1YmxpYyBESFByaXZhdGVLZXlTcGVjKEJpZ0ludGVnZXIgeCwgQmlnSW50ZWdlciBwLCBCaWdJbnRlZ2VyIGcpIHsKKyAgICAgICAgdGhpcy54ID0geDsKKyAgICAgICAgdGhpcy5wID0gcDsKKyAgICAgICAgdGhpcy5nID0gZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSA8aT5wcml2YXRlIHZhbHVlPC9pPiA8Y29kZT54PC9jb2RlPi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByaXZhdGUgdmFsdWUgPGNvZGU+eDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0WCgpIHsKKyAgICAgICAgcmV0dXJuIHg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgPGk+cHJpbWUgbW9kdWx1czwvaT4gPGNvZGU+cDwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmltZSBtb2R1bHVzIDxjb2RlPnA8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFAoKSB7CisgICAgICAgIHJldHVybiBwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIDxpPmJhc2UgZ2VuZXJhdG9yPC9pPiA8Y29kZT5nPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJhc2UgZ2VuZXJhdG9yIDxjb2RlPmc8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldEcoKSB7CisgICAgICAgIHJldHVybiBnOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL0RIUHVibGljS2V5U3BlYy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL0RIUHVibGljS2V5U3BlYy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1ZDQ0NjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL3NwZWMvREhQdWJsaWNLZXlTcGVjLmphdmEKQEAgLTAsMCArMSw3NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5LZXlTcGVjOworCisvKioKKyAqIFRoZSBrZXkgc3BlY2lmaWNhdGlvbiBmb3IgYSBEaWZmaWUtSGVsbG1hbiBwdWJsaWMga2V5LgorICovCitwdWJsaWMgY2xhc3MgREhQdWJsaWNLZXlTcGVjIGltcGxlbWVudHMgS2V5U3BlYyB7CisKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgeTsKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgcDsKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgZzsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+REhQdWJsaWNLZXlTcGVjPC9jb2RlPiBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiA8aT5wdWJsaWMgdmFsdWU8L2k+IDxjb2RlPnk8L2NvZGU+LCB0aGUgPGk+cHJpbWUgbW9kdWx1czwvaT4KKyAgICAgKiA8Y29kZT5wPC9jb2RlPiBhbmQgdGhlIDxpPmJhc2UgZ2VuZXJhdG9yPC9pPiA8Y29kZT5nPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB5CisgICAgICogICAgICAgICAgICB0aGUgcHVibGljIHZhbHVlLgorICAgICAqIEBwYXJhbSBwCisgICAgICogICAgICAgICAgICB0aGUgcHJpbWUgbW9kdWx1cy4KKyAgICAgKiBAcGFyYW0gZworICAgICAqICAgICAgICAgICAgdGhlIGJhc2UgZ2VuZXJhdG9yLgorICAgICAqLworICAgIHB1YmxpYyBESFB1YmxpY0tleVNwZWMoQmlnSW50ZWdlciB5LCBCaWdJbnRlZ2VyIHAsIEJpZ0ludGVnZXIgZykgeworICAgICAgICB0aGlzLnkgPSB5OworICAgICAgICB0aGlzLnAgPSBwOworICAgICAgICB0aGlzLmcgPSBnOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIDxpPnB1YmxpYyB2YWx1ZTwvaT4gPGNvZGU+eTwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwdWJsaWMgdmFsdWUgPGNvZGU+eTwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0WSgpIHsKKyAgICAgICAgcmV0dXJuIHk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgPGk+cHJpbWUgbW9kdWx1czwvaT4gPGNvZGU+cDwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmltZSBtb2R1bHVzIDxjb2RlPnA8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFAoKSB7CisgICAgICAgIHJldHVybiBwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIDxpPmJhc2UgZ2VuZXJhdG9yPC9pPiA8Y29kZT5nPC9jb2RlPjsKKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGJhc2UgZ2VuZXJhdG9yIDxjb2RlPmc8L2NvZGU+OworICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldEcoKSB7CisgICAgICAgIHJldHVybiBnOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL0l2UGFyYW1ldGVyU3BlYy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL0l2UGFyYW1ldGVyU3BlYy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU4MWZmMGQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL3NwZWMvSXZQYXJhbWV0ZXJTcGVjLmphdmEKQEAgLTAsMCArMSw4MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogVGhlIGFsZ29yaXRobSBwYXJhbWV0ZXIgc3BlY2lmaWNhdGlvbiBmb3IgYW4gPGk+aW5pdGlhbGl6YXRpb24gdmVjdG9yPC9pPi4KKyAqLworcHVibGljIGNsYXNzIEl2UGFyYW1ldGVyU3BlYyBpbXBsZW1lbnRzIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgeworCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gaXY7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPkl2UGFyYW1ldGVyU3BlYzwvY29kZT4gaW5zdGFuY2Ugd2l0aCB0aGUgYnl0ZXMgZnJvbQorICAgICAqIHRoZSBzcGVjaWZpZWQgYnVmZmVyIDxpPml2PC9pPiB1c2VkIGFzIDxpPmluaXRpYWxpemF0aW9uIHZlY3RvcjwvaT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXYKKyAgICAgKiAgICAgICAgICAgIHRoZSBidWZmZXIgdXNlZCBhcyBpbml0aWFsaXphdGlvbiB2ZWN0b3IuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYnVmZmVyIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIEl2UGFyYW1ldGVyU3BlYyhieXRlW10gaXYpIHsKKyAgICAgICAgaWYgKGl2ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiaXYgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRoaXMuaXYgPSBuZXcgYnl0ZVtpdi5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGl2LCAwLCB0aGlzLml2LCAwLCBpdi5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+SXZQYXJhbWV0ZXJTcGVjPC9jb2RlPiBpbnN0YW5jZSB3aXRoIDxjb2RlPmJ5dGVDb3VudDwvY29kZT4KKyAgICAgKiBieXRlcyBmcm9tIHRoZSBzcGVjaWZpZWQgYnVmZmVyIDxjb2RlPml2PC9jb2RlPiBzdGFydGluZyBhdAorICAgICAqIDxjb2RlPm9mZnNldDwvY29kZT4uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgYnVmZmVyIGlzIG51bGwgb3IgPGNvZGU+b2Zmc2V0PC9jb2RlPiBhbmQKKyAgICAgKiAgICAgICAgICAgICA8Y29kZT5ieXRlQ291bnQ8L2NvZGU+IGRvIG5vdCBzcGVjaWZ5IGEgdmFsaWQgY2h1bmsgaW4gdGhlCisgICAgICogICAgICAgICAgICAgc3BlY2lmaWVkIGJ1ZmZlci4KKyAgICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIDxjb2RlPm9mZnNldDwvY29kZT4gb3IgPGNvZGU+Ynl0ZUNvdW50PC9jb2RlPiBhcmUgbmVnYXRpdmUuCisgICAgICovCisgICAgcHVibGljIEl2UGFyYW1ldGVyU3BlYyhieXRlW10gaXYsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQpIHsKKyAgICAgICAgaWYgKChpdiA9PSBudWxsKSB8fCAoaXYubGVuZ3RoIC0gb2Zmc2V0IDwgYnl0ZUNvdW50KSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGl2Lmxlbmd0aCwgb2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICB0aGlzLml2ID0gbmV3IGJ5dGVbYnl0ZUNvdW50XTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShpdiwgb2Zmc2V0LCB0aGlzLml2LCAwLCBieXRlQ291bnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb3B5IG9mIHRoZSA8aT5pbml0aWFsaXphdGlvbiB2ZWN0b3I8L2k+IGRhdGEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGUgaW5pdGlhbGl6YXRpb24gdmVjdG9yIGRhdGEuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRJVigpIHsKKyAgICAgICAgYnl0ZVtdIHJlcyA9IG5ldyBieXRlW2l2Lmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoaXYsIDAsIHJlcywgMCwgaXYubGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL3NwZWMvT0FFUFBhcmFtZXRlclNwZWMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vc3BlYy9PQUVQUGFyYW1ldGVyU3BlYy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNiYzlhYjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL3NwZWMvT0FFUFBhcmFtZXRlclNwZWMuamF2YQpAQCAtMCwwICsxLDEyMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5NR0YxUGFyYW1ldGVyU3BlYzsKKworLyoqCisgKiBUaGUgYWxnb3JpdGhtIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uIGZvciB0aGUgPGk+T0FFUCBQYWRkaW5nPC9pPiBhbGdvcml0aG0uCisgKiA8cD4KKyAqIFRoaXMgcGFkZGluZyBhbGdvcml0aG0gaXMgZGVmaW5lZCBpbiB0aGUgPGEKKyAqIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzM0NDcudHh0Ij5QS0NTICMxPC9hPiBzdGFuZGFyZC4KKyAqLworcHVibGljIGNsYXNzIE9BRVBQYXJhbWV0ZXJTcGVjIGltcGxlbWVudHMgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyB7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBtZE5hbWU7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbWdmTmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgbWdmU3BlYzsKKyAgICBwcml2YXRlIGZpbmFsIFBTb3VyY2UgcFNyYzsKKworICAgIC8qKgorICAgICAqIFRoZSBhbGdvcml0aG0gcGFyYW1ldGVyIGluc3RhbmNlIHdpdGggZGVmYXVsdCB2YWx1ZXMuCisgICAgICogPHA+CisgICAgICogSXQgdXNlcyB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6CisgICAgICogPHVsPjxsaT5tZXNzYWdlIGRpZ2VzdCA6IDxjb2RlPiJTSEEtMSI8L2NvZGU+PC9saT4KKyAgICAgKiA8bGk+bWFzayBnZW5lcmF0aW9uIGZ1bmN0aW9uICg8aT5tZ2Y8L2k+KSA6IDxjb2RlPiJNR0YxIjwvY29kZT48L2xpPgorICAgICAqIDxsaT5wYXJhbWV0ZXJzIGZvciB0aGUgPGk+bWdmPC9pPiA6ICJTSEEtMSIge0BsaW5rIE1HRjFQYXJhbWV0ZXJTcGVjI1NIQTF9PC9saT4KKyAgICAgKiA8bGk+dGhlIHNvdXJjZSBvZiB0aGUgbGFiZWwgPGNvZGU+TDwvY29kZT46IHtAbGluayBQU291cmNlLlBTcGVjaWZpZWQjREVGQVVMVH08L2xpPgorICAgICAqIDwvdWw+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBPQUVQUGFyYW1ldGVyU3BlYyBERUZBVUxUID0gbmV3IE9BRVBQYXJhbWV0ZXJTcGVjKCk7CisKKyAgICBwcml2YXRlIE9BRVBQYXJhbWV0ZXJTcGVjKCkgeworICAgICAgICB0aGlzLm1kTmFtZSA9ICJTSEEtMSI7CisgICAgICAgIHRoaXMubWdmTmFtZSA9ICJNR0YxIjsKKyAgICAgICAgdGhpcy5tZ2ZTcGVjID0gTUdGMVBhcmFtZXRlclNwZWMuU0hBMTsKKyAgICAgICAgdGhpcy5wU3JjID0gUFNvdXJjZS5QU3BlY2lmaWVkLkRFRkFVTFQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5PQUVQUGFyYW1ldGVyU3BlYzwvY29kZT4gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogPGk+bWVzc2FnZSBkaWdlc3Q8L2k+IGFsZ29yaXRobSBuYW1lLCA8aT5tYXNrIGdlbmVyYXRpb24gZnVuY3Rpb248L2k+CisgICAgICogKDxpPm1nZjwvaT4pIGFsZ29yaXRobSBuYW1lLCA8aT5wYXJhbWV0ZXJzPC9pPiBmb3IgdGhlIDxpPm1nZjwvaT4KKyAgICAgKiBhbGdvcml0aG0gYW5kIHRoZSA8aT5zb3VyY2Ugb2YgdGhlIGxhYmVsIDxjb2RlPkw8L2NvZGU+PC9pPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZE5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBtZXNzYWdlIGRpZ2VzdCBhbGdvcml0aG0gbmFtZS4KKyAgICAgKiBAcGFyYW0gbWdmTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG1hc2sgZ2VuZXJhdGlvbiBmdW5jdGlvbiBhbGdvcml0aG0gbmFtZS4KKyAgICAgKiBAcGFyYW0gbWdmU3BlYworICAgICAqICAgICAgICAgICAgdGhlIGFsZ29yaXRobSBwYXJhbWV0ZXIgc3BlY2lmaWNhdGlvbiBmb3IgdGhlIG1hc2sgZ2VuZXJhdGlvbgorICAgICAqICAgICAgICAgICAgZnVuY3Rpb24gYWxnb3JpdGhtLgorICAgICAqIEBwYXJhbSBwU3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIG9mIHRoZSBsYWJlbCA8Y29kZT5MPC9jb2RlPi4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgb25lIG9mIDxjb2RlPm1kTmFtZTwvY29kZT4sIDxjb2RlPm1nZk5hbWU8L2NvZGU+IG9yCisgICAgICogICAgICAgICAgICAgPGNvZGU+cFNyYzwvY29kZT4gaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgT0FFUFBhcmFtZXRlclNwZWMoU3RyaW5nIG1kTmFtZSwgU3RyaW5nIG1nZk5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgbWdmU3BlYywgUFNvdXJjZSBwU3JjKSB7CisgICAgICAgIGlmICgobWROYW1lID09IG51bGwpIHx8IChtZ2ZOYW1lID09IG51bGwpIHx8IChwU3JjID09IG51bGwpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLm1kTmFtZSA9IG1kTmFtZTsKKyAgICAgICAgdGhpcy5tZ2ZOYW1lID0gbWdmTmFtZTsKKyAgICAgICAgdGhpcy5tZ2ZTcGVjID0gbWdmU3BlYzsKKyAgICAgICAgdGhpcy5wU3JjID0gcFNyYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhbGdvcml0aG0gbmFtZSBvZiB0aGUgPGk+bWVzc2FnZSBkaWdlc3Q8L2k+LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYWxnb3JpdGhtIG5hbWUgb2YgdGhlIG1lc3NhZ2UgZGlnZXN0LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGlnZXN0QWxnb3JpdGhtKCkgeworICAgICAgICByZXR1cm4gbWROYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFsZ29yaXRobSBuYW1lIG9mIHRoZSA8aT5tYXNrIGdlbmVyYXRpb24gZnVuY3Rpb248L2k+LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYWxnb3JpdGhtIG5hbWUgb2YgdGhlIG1hc2sgZ2VuZXJhdGlvbiBmdW5jdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE1HRkFsZ29yaXRobSgpIHsKKyAgICAgICAgcmV0dXJuIG1nZk5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYWxnb3JpdGhtIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uIGZvciB0aGUgbWFzayBnZW5lcmF0aW9uCisgICAgICogZnVuY3Rpb24gYWxnb3JpdGhtLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgYWxnb3JpdGhtIHBhcmFtZXRlciBzcGVjaWZpY2F0aW9uIGZvciB0aGUgbWFzayBnZW5lcmF0aW9uCisgICAgICogICAgICAgICBmdW5jdGlvbiBhbGdvcml0aG0uCisgICAgICovCisgICAgcHVibGljIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgZ2V0TUdGUGFyYW1ldGVycygpIHsKKyAgICAgICAgcmV0dXJuIG1nZlNwZWM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc291cmNlIG9mIHRoZSBsYWJlbCA8Y29kZT5MPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNvdXJjZSBvZiB0aGUgbGFiZWwgPGNvZGU+TDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIFBTb3VyY2UgZ2V0UFNvdXJjZSgpIHsKKyAgICAgICAgcmV0dXJuIHBTcmM7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL3NwZWMvUEJFS2V5U3BlYy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL1BCRUtleVNwZWMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMWYwZDk2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL1BCRUtleVNwZWMuamF2YQpAQCAtMCwwICsxLDE5NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5LZXlTcGVjOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgbGliY29yZS51dGlsLkVtcHR5QXJyYXk7CisKKy8qKgorICogVGhlIGtleSBzcGVjaWZpY2F0aW9uIGZvciBhIDxpPnBhc3N3b3JkIGJhc2VkIGVuY3J5cHRpb248L2k+IGtleS4KKyAqIDxwPgorICogUGFzc3dvcmQgYmFzZWQgZW5jcnlwdGlvbiBpcyBkZXNjcmliZWQgaW4gPGEKKyAqIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzI4OTgudHh0Ij5QS0NTICM1PC9hPi4KKyAqLworcHVibGljIGNsYXNzIFBCRUtleVNwZWMgaW1wbGVtZW50cyBLZXlTcGVjIHsKKworICAgIHByaXZhdGUgY2hhcltdIHBhc3N3b3JkOworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIHNhbHQ7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgaXRlcmF0aW9uQ291bnQ7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQga2V5TGVuZ3RoOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5QQkVLZXlTcGVjPC9jb2RlPiB3aXRoIHRoZSBzcGVjaWZpZWQgcGFzc3dvcmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFzc3dvcmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXNzd29yZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUEJFS2V5U3BlYyhjaGFyW10gcGFzc3dvcmQpIHsKKyAgICAgICAgaWYgKHBhc3N3b3JkID09IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMucGFzc3dvcmQgPSBFbXB0eUFycmF5LkNIQVI7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aGlzLnBhc3N3b3JkID0gbmV3IGNoYXJbcGFzc3dvcmQubGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocGFzc3dvcmQsIDAsIHRoaXMucGFzc3dvcmQsIDAsIHBhc3N3b3JkLmxlbmd0aCk7CisgICAgICAgIH0KKyAgICAgICAgc2FsdCA9IG51bGw7CisgICAgICAgIGl0ZXJhdGlvbkNvdW50ID0gMDsKKyAgICAgICAga2V5TGVuZ3RoID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPlBCRUtleVNwZWM8L2NvZGU+IHdpdGggdGhlIHNwZWNpZmllZCBwYXNzd29yZCwgc2FsdCwKKyAgICAgKiBpdGVyYXRpb24gY291bnQgYW5kIHRoZSBkZXNpcmVkIGxlbmd0aCBvZiB0aGUgZGVyaXZlZCBrZXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFzc3dvcmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXNzd29yZC4KKyAgICAgKiBAcGFyYW0gc2FsdAorICAgICAqICAgICAgICAgICAgdGhlIHNhbHQuCisgICAgICogQHBhcmFtIGl0ZXJhdGlvbkNvdW50CisgICAgICogICAgICAgICAgICB0aGUgaXRlcmF0aW9uIGNvdW50LgorICAgICAqIEBwYXJhbSBrZXlMZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXNpcmVkIGtleSBsZW5ndGggb2YgdGhlIGRlcml2ZWQga2V5LAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc2FsdCBpcyBudWxsLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNhbHQgaXMgZW1wdHksIGl0ZXJhdGlvbiBjb3VudCBpcyB6ZXJvIG9yIG5lZ2F0aXZlIG9yCisgICAgICogICAgICAgICAgICAgdGhlIGtleSBsZW5ndGggaXMgemVybyBvciBuZWdhdGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUEJFS2V5U3BlYyhjaGFyW10gcGFzc3dvcmQsIGJ5dGVbXSBzYWx0LCBpbnQgaXRlcmF0aW9uQ291bnQsCisgICAgICAgICAgICAgICAgICAgICAgaW50IGtleUxlbmd0aCkgeworICAgICAgICBpZiAoc2FsdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInNhbHQgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChzYWx0Lmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzYWx0Lmxlbmd0aCA9PSAwIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGl0ZXJhdGlvbkNvdW50IDw9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIml0ZXJhdGlvbkNvdW50IDw9IDAiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoa2V5TGVuZ3RoIDw9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImtleUxlbmd0aCA8PSAwIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAocGFzc3dvcmQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhpcy5wYXNzd29yZCA9IEVtcHR5QXJyYXkuQ0hBUjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRoaXMucGFzc3dvcmQgPSBuZXcgY2hhcltwYXNzd29yZC5sZW5ndGhdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShwYXNzd29yZCwgMCwgdGhpcy5wYXNzd29yZCwgMCwgcGFzc3dvcmQubGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnNhbHQgPSBuZXcgYnl0ZVtzYWx0Lmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2FsdCwgMCwgdGhpcy5zYWx0LCAwLCBzYWx0Lmxlbmd0aCk7CisgICAgICAgIHRoaXMuaXRlcmF0aW9uQ291bnQgPSBpdGVyYXRpb25Db3VudDsKKyAgICAgICAgdGhpcy5rZXlMZW5ndGggPSBrZXlMZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5QQkVLZXlTcGVjPC9jb2RlPiB3aXRoIHRoZSBzcGVjaWZpZWQgcGFzc3dvcmQsIHNhbHQKKyAgICAgKiBhbmQgaXRlcmF0aW9uIGNvdW50LgorICAgICAqCisgICAgICogQHBhcmFtIHBhc3N3b3JkCisgICAgICogICAgICAgICAgICB0aGUgcGFzc3dvcmQuCisgICAgICogQHBhcmFtIHNhbHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzYWx0LgorICAgICAqIEBwYXJhbSBpdGVyYXRpb25Db3VudAorICAgICAqICAgICAgICAgICAgdGhlIGl0ZXJhdGlvbiBjb3VudC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgc2FsdCBpcyBudWxsLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNhbHQgaXMgZW1wdHkgb3IgaXRlcmF0aW9uIGNvdW50IGlzIHplcm8gb3IgbmVnYXRpdmUuCisgICAgICovCisgICAgcHVibGljIFBCRUtleVNwZWMoY2hhcltdIHBhc3N3b3JkLCBieXRlW10gc2FsdCwgaW50IGl0ZXJhdGlvbkNvdW50KSB7CisgICAgICAgIGlmIChzYWx0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigic2FsdCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNhbHQubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInNhbHQubGVuZ3RoID09IDAiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaXRlcmF0aW9uQ291bnQgPD0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaXRlcmF0aW9uQ291bnQgPD0gMCIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHBhc3N3b3JkID09IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMucGFzc3dvcmQgPSBFbXB0eUFycmF5LkNIQVI7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aGlzLnBhc3N3b3JkID0gbmV3IGNoYXJbcGFzc3dvcmQubGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocGFzc3dvcmQsIDAsIHRoaXMucGFzc3dvcmQsIDAsIHBhc3N3b3JkLmxlbmd0aCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zYWx0ID0gbmV3IGJ5dGVbc2FsdC5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHNhbHQsIDAsIHRoaXMuc2FsdCwgMCwgc2FsdC5sZW5ndGgpOworICAgICAgICB0aGlzLml0ZXJhdGlvbkNvdW50ID0gaXRlcmF0aW9uQ291bnQ7CisgICAgICAgIHRoaXMua2V5TGVuZ3RoID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbGVhcnMgdGhlIHBhc3N3b3JkIGJ5IG92ZXJ3cml0aW5nIGl0LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGNsZWFyUGFzc3dvcmQoKSB7CisgICAgICAgIEFycmF5cy5maWxsKHBhc3N3b3JkLCAnPycpOworICAgICAgICBwYXNzd29yZCA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhlIHBhc3N3b3JkIG9mIHRoaXMga2V5IHNwZWNpZmljYXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGUgcGFzc3dvcmQgb2YgdGhpcyBrZXkgc3BlY2lmaWNhdGlvbi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwYXNzd29yZCBoYXMgYmVlbiBjbGVhcmVkIGJlZm9yZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgY2hhcltdIGdldFBhc3N3b3JkKCkgeworICAgICAgICBpZiAocGFzc3dvcmQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVGhlIHBhc3N3b3JkIGhhcyBiZWVuIGNsZWFyZWQiKTsKKyAgICAgICAgfQorICAgICAgICBjaGFyW10gcmVzdWx0ID0gbmV3IGNoYXJbcGFzc3dvcmQubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShwYXNzd29yZCwgMCwgcmVzdWx0LCAwLCBwYXNzd29yZC5sZW5ndGgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBjb3B5IG9mIHRoZSBzYWx0IG9mIHRoaXMga2V5IHNwZWNpZmljYXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGUgc2FsdCBvZiB0aGlzIGtleSBzcGVjaWZpY2F0aW9uIG9yIG51bGwgaWYgbm9uZSBpcworICAgICAqICAgICAgICAgc3BlY2lmaWVkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBieXRlW10gZ2V0U2FsdCgpIHsKKyAgICAgICAgaWYgKHNhbHQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW3NhbHQubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzYWx0LCAwLCByZXN1bHQsIDAsIHNhbHQubGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpdGVyYXRpb24gY291bnQgb2YgdGhpcyBrZXkgc3BlY2lmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGl0ZXJhdGlvbiBjb3VudCBvZiB0aGlzIGtleSBzcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0SXRlcmF0aW9uQ291bnQoKSB7CisgICAgICAgIHJldHVybiBpdGVyYXRpb25Db3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZXNpcmVkIGtleSBsZW5ndGggb2YgdGhlIGRlcml2ZWQga2V5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZGVzaXJlZCBrZXkgbGVuZ3RoIG9mIHRoZSBkZXJpdmVkIGtleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdldEtleUxlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIGtleUxlbmd0aDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL3NwZWMvUEJFUGFyYW1ldGVyU3BlYy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL1BCRVBhcmFtZXRlclNwZWMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZjY3NzY1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL1BCRVBhcmFtZXRlclNwZWMuamF2YQpAQCAtMCwwICsxLDc0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LmNyeXB0by5zcGVjOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CisKKy8qKgorICogVGhlIGFsZ29yaXRobSBwYXJhbWV0ZXIgc3BlY2lmaWNhdGlvbiBmb3IgYSA8aT5wYXNzd29yZCBiYXNlZCBlbmNyeXB0aW9uPC9pPgorICogYWxnb3JpdGhtLgorICogPHA+CisgKiBQYXNzd29yZCBiYXNlZCBlbmNyeXB0aW9uIGlzIGRlc2NyaWJlZCBpbiA8YQorICogaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjg5OC50eHQiPlBLQ1MgIzU8L2E+LgorICoKKyAqLworcHVibGljIGNsYXNzIFBCRVBhcmFtZXRlclNwZWMgaW1wbGVtZW50cyBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHsKKworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIHNhbHQ7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgaXRlcmF0aW9uQ291bnQ7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPlBCRVBhcmFtZXRlclNwZWM8L2NvZGU+IHdpdGggdGhlIHNwZWNpZmllZCBzYWx0IGFuZAorICAgICAqIGl0ZXJhdGlvbiBjb3VudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzYWx0CisgICAgICogICAgICAgICAgICB0aGUgc2FsdC4KKyAgICAgKiBAcGFyYW0gaXRlcmF0aW9uQ291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBpdGVyYXRpb24gY291bnQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHNhbHQgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUEJFUGFyYW1ldGVyU3BlYyhieXRlW10gc2FsdCwgaW50IGl0ZXJhdGlvbkNvdW50KSB7CisgICAgICAgIGlmIChzYWx0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigic2FsdCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zYWx0ID0gbmV3IGJ5dGVbc2FsdC5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHNhbHQsIDAsIHRoaXMuc2FsdCwgMCwgc2FsdC5sZW5ndGgpOworICAgICAgICB0aGlzLml0ZXJhdGlvbkNvdW50ID0gaXRlcmF0aW9uQ291bnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvcHkgdG8gdGhlIHNhbHQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgY29weSB0byB0aGUgc2FsdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldFNhbHQoKSB7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtzYWx0Lmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2FsdCwgMCwgcmVzdWx0LCAwLCBzYWx0Lmxlbmd0aCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaXRlcmF0aW9uIGNvdW50LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaXRlcmF0aW9uIGNvdW50LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SXRlcmF0aW9uQ291bnQoKSB7CisgICAgICAgIHJldHVybiBpdGVyYXRpb25Db3VudDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL3NwZWMvUFNvdXJjZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL1BTb3VyY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZWZhMWU5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL1BTb3VyY2UuamF2YQpAQCAtMCwwICsxLDEwNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGxpYmNvcmUudXRpbC5FbXB0eUFycmF5OworCisvKioKKyAqIFRoZSBzb3VyY2Ugb2YgdGhlIGxhYmVsIDxjb2RlPkw8L2NvZGU+IGFzIHNwZWNpZmllZCBpbiA8YQorICogaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzQ0Ny50eHQiPiBQS0NTICMxPC9hPi4KKyAqLworcHVibGljIGNsYXNzIFBTb3VyY2UgeworCisgICAgcHJpdmF0ZSBTdHJpbmcgcFNyY05hbWU7CisKKyAgICBwcml2YXRlIFBTb3VyY2UoKSB7fQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5QU291cmNlPC9jb2RlPiBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgc291cmNlCisgICAgICogYWxnb3JpdGhtIGlkZW50aWZpZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcFNyY05hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgYWxnb3JpdGhtIGlkZW50aWZpZXIuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHBTcmNOYW1lIGlzIG51bGwuCisgICAgICovCisgICAgcHJvdGVjdGVkIFBTb3VyY2UoU3RyaW5nIHBTcmNOYW1lKSB7CisgICAgICAgIGlmIChwU3JjTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnBTcmNOYW1lID0gcFNyY05hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc291cmNlIGFsZ29yaXRobSBpZGVudGlmaWVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc291cmNlIGFsZ29yaXRobSBpZGVudGlmaWVyLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICByZXR1cm4gcFNyY05hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGV4cGxpY2l0IHNwZWNpZmljYXRpb24gb2YgdGhlIHBhcmFtZXRlciA8Y29kZT5QPC9jb2RlPiB1c2VkIGluIHRoZQorICAgICAqIHNvdXJjZSBhbGdvcml0aG0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBQU3BlY2lmaWVkIGV4dGVuZHMgUFNvdXJjZSB7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gcDsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGluc3RhbmNlIG9mIDxjb2RlPlBTcGVjaWZpZWQ8L2NvZGU+IHdpdGggdGhlIGRlZmF1bHQgdmFsdWUKKyAgICAgICAgICogPGNvZGU+Ynl0ZVswXTwvY29kZT4gZm9yIDxjb2RlPlA8L2NvZGU+CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFBTcGVjaWZpZWQgREVGQVVMVCA9IG5ldyBQU3BlY2lmaWVkKCk7CisKKyAgICAgICAgcHJpdmF0ZSBQU3BlY2lmaWVkKCkgeworICAgICAgICAgICAgc3VwZXIoIlBTcGVjaWZpZWQiKTsKKyAgICAgICAgICAgIHAgPSBFbXB0eUFycmF5LkJZVEU7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiA8Y29kZT5QU3BlY2lmaWVkPC9jb2RlPiB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgICAgICogcGFyYW1ldGVyIDxjb2RlPlA8L2NvZGU+LgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gcAorICAgICAgICAgKiAgICAgICAgICAgIHRoZSBwYXJhbWV0ZXIgPGNvZGU+UDwvY29kZT4uCisgICAgICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgICAgICogICAgICAgICAgICAgaWYgPGNvZGU+cDwvY29kZT4gaXMgbnVsbC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBQU3BlY2lmaWVkKGJ5dGVbXSBwKSB7CisgICAgICAgICAgICBzdXBlcigiUFNwZWNpZmllZCIpOworICAgICAgICAgICAgaWYgKHAgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy9UT0RPOiBJdCBpcyB1bmtub3duIHdoaWNoIG5hbWUgc2hvdWxkIGJlIHVzZWQhCisgICAgICAgICAgICAvL3N1cGVyKCIiKTsKKyAgICAgICAgICAgIHRoaXMucCA9IG5ldyBieXRlW3AubGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocCwgMCwgdGhpcy5wLCAwLCBwLmxlbmd0aCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhlIHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIgPGNvZGU+UDwvY29kZT4uCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4gYSBjb3B5IG9mIHRoZSB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyIDxjb2RlPlA8L2NvZGU+CisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldFZhbHVlKCkgeworICAgICAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW3AubGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocCwgMCwgcmVzdWx0LCAwLCBwLmxlbmd0aCk7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL1JDMlBhcmFtZXRlclNwZWMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vc3BlYy9SQzJQYXJhbWV0ZXJTcGVjLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzkxMDQyOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vc3BlYy9SQzJQYXJhbWV0ZXJTcGVjLmphdmEKQEAgLTAsMCArMSwxNjEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguY3J5cHRvLnNwZWM7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIFRoZSBhbGdvcml0aG0gcGFyYW1ldGVyIHNwZWNpZmljYXRpb24gZm9yIHRoZSA8YQorICogaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI2OC50eHQiPlJDMjwvYT4gYWxnb3JpdGhtLgorICovCitwdWJsaWMgY2xhc3MgUkMyUGFyYW1ldGVyU3BlYyBpbXBsZW1lbnRzIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgeworCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgZWZmZWN0aXZlS2V5Qml0czsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBpdjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+UkMyUGFyYW1ldGVyU3BlYzwvY29kZT4gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogZWZmZWN0aXZlIGtleSBsZW5ndGggKGluIGJpdHMpLAorICAgICAqCisgICAgICogQHBhcmFtIGVmZmVjdGl2ZUtleUJpdHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBlZmZlY3RpdmUga2V5IGxlbmd0aCAoaW4gYml0cykuCisgICAgICovCisgICAgcHVibGljIFJDMlBhcmFtZXRlclNwZWMoaW50IGVmZmVjdGl2ZUtleUJpdHMpIHsKKyAgICAgICAgdGhpcy5lZmZlY3RpdmVLZXlCaXRzID0gZWZmZWN0aXZlS2V5Qml0czsKKyAgICAgICAgaXYgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+UkMyUGFyYW1ldGVyU3BlYzwvY29kZT4gaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogZWZmZWN0aXZlIGtleSBsZW5ndGggKGluIGJpdHMpIGFuZCA8aT5pbml0aWFsaXphdGlvbiB2ZWN0b3I8L2k+LgorICAgICAqIDxwPgorICAgICAqIFRoZSBzaXplIG9mIHRoZSA8aT5pbml0aWFsaXphdGlvbiB2ZWN0b3I8L2k+IG11c3QgYmUgYXQgbGVhc3QgOCBieXRlcworICAgICAqIHdoaWNoIGFyZSBjb3BpZWQgdG8gcHJvdGVjdCB0aGVtIGFnYWluc3QgbW9kaWZpY2F0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGVmZmVjdGl2ZUtleUJpdHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBlZmZlY3RpdmUga2V5IGxlbmd0aCAoaW4gYml0cykuCisgICAgICogQHBhcmFtIGl2CisgICAgICogICAgICAgICAgICB0aGUgaW5pdGlhbGl6YXRpb24gdmVjdG9yLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciBpcyBudWxsIG9yIHNob3J0ZXIgdGhhbiA4IGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBSQzJQYXJhbWV0ZXJTcGVjKGludCBlZmZlY3RpdmVLZXlCaXRzLCBieXRlW10gaXYpIHsKKyAgICAgICAgaWYgKGl2ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIml2ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaXYubGVuZ3RoIDwgOCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaXYubGVuZ3RoIDwgOCIpOworICAgICAgICB9CisgICAgICAgIHRoaXMuZWZmZWN0aXZlS2V5Qml0cyA9IGVmZmVjdGl2ZUtleUJpdHM7CisgICAgICAgIHRoaXMuaXYgPSBuZXcgYnl0ZVs4XTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShpdiwgMCwgdGhpcy5pdiwgMCwgOCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5SQzJQYXJhbWV0ZXJTcGVjPC9jb2RlPiBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBlZmZlY3RpdmUga2V5IGxlbmd0aCAoaW4gYml0cykgYW5kIDxpPmluaXRpYWxpemF0aW9uIHZlY3RvcjxpPi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgc2l6ZSBvZiB0aGUgPGk+aW5pdGlhbGl6YXRpb24gdmVjdG9yPC9pPiBzdGFydGluZyBhdAorICAgICAqIDxjb2RlPm9mZnNldDwvY29kZT4gbXVzdCBiZSBhdCBsZWFzdCA4IGJ5dGVzIHdoaWNoIGFyZSBjb3BpZWQgdG8gcHJvdGVjdAorICAgICAqIHRoZW0gYWdhaW5zdCBtb2RpZmljYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZWZmZWN0aXZlS2V5Qml0cworICAgICAqICAgICAgICAgICAgdGhlIGVmZmVjdGl2ZSBrZXkgbGVuZ3RoIChpbiBiaXRzKS4KKyAgICAgKiBAcGFyYW0gaXYKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3IuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldCBpbiB0aGUgaW5pdGlhbGl6YXRpb24gdmVjdG9yIHRvIHN0YXJ0IGF0LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciBpcyBudWxsIG9yIHN0YXJ0aW5nIGF0CisgICAgICogICAgICAgICAgICAgPGNvZGU+b2Zmc2V0PC9jb2RlPiBpcyBzaG9ydGVyIHRoYW4gOCBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUkMyUGFyYW1ldGVyU3BlYyhpbnQgZWZmZWN0aXZlS2V5Qml0cywgYnl0ZVtdIGl2LCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIGlmIChpdiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJpdiA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGl2Lmxlbmd0aCAtIG9mZnNldCA8IDgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIml2Lmxlbmd0aCAtIG9mZnNldCA8IDgiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmVmZmVjdGl2ZUtleUJpdHMgPSBlZmZlY3RpdmVLZXlCaXRzOworICAgICAgICB0aGlzLml2ID0gbmV3IGJ5dGVbOF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoaXYsIG9mZnNldCwgdGhpcy5pdiwgMCwgOCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZWZmZWN0aXZlIGtleSBsZW5ndGggKGluIGJpdHMpLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZWZmZWN0aXZlIGtleSBsZW5ndGggKGluIGJpdHMpLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RWZmZWN0aXZlS2V5Qml0cygpIHsKKyAgICAgICAgcmV0dXJuIGVmZmVjdGl2ZUtleUJpdHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhlIGluaXRpYWxpemF0aW9uIHZlY3Rvci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBjb3B5IG9mIHRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3IsIG9yIG51bGwgaWYgbm9uZSBzcGVjaWZpZWQuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRJVigpIHsKKyAgICAgICAgaWYgKGl2ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtpdi5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGl2LCAwLCByZXN1bHQsIDAsIGl2Lmxlbmd0aCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBvYmplY3QgdG8gdGhpcyA8Y29kZT5SQzJQYXJhbWV0ZXJTcGVjPC9jb2RlPgorICAgICAqIGluc3RhbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBjb21wYXJlLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZWZmZWN0aXZlIGtleSBsZW5ndGggYW5kIHRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3Igb2YKKyAgICAgKiAgICAgICAgIGJvdGggb2JqZWN0cyBhcmUgZXF1YWwsIG90aGVyd2lzZSBmYWxzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIFJDMlBhcmFtZXRlclNwZWMpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgUkMyUGFyYW1ldGVyU3BlYyBwcyA9IChSQzJQYXJhbWV0ZXJTcGVjKSBvYmo7CisgICAgICAgIHJldHVybiAoZWZmZWN0aXZlS2V5Qml0cyA9PSBwcy5lZmZlY3RpdmVLZXlCaXRzKQorICAgICAgICAgICAgJiYgKEFycmF5cy5lcXVhbHMoaXYsIHBzLml2KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaGFzaCBjb2RlIG9mIHRoaXMgPGNvZGU+UkMyUGFyYW1ldGVyU3BlYzwvY29kZT4gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IHJlc3VsdCA9IGVmZmVjdGl2ZUtleUJpdHM7CisgICAgICAgIGlmIChpdiA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgICAgIGZvciAoYnl0ZSBlbGVtZW50IDogaXYpIHsKKyAgICAgICAgICAgIHJlc3VsdCArPSBlbGVtZW50OworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL1JDNVBhcmFtZXRlclNwZWMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vc3BlYy9SQzVQYXJhbWV0ZXJTcGVjLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDhhODkwZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vc3BlYy9SQzVQYXJhbWV0ZXJTcGVjLmphdmEKQEAgLTAsMCArMSwyMTAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguY3J5cHRvLnNwZWM7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIFRoZSBhbGdvcml0aG0gcGFyYW1ldGVyIHNwZWNpZmljYXRpb24gZm9yIHRoZSA8YQorICogaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjA0MC50eHQiPlJDNTwvYT4gYWxnb3JpdGhtLgorICovCitwdWJsaWMgY2xhc3MgUkM1UGFyYW1ldGVyU3BlYyBpbXBsZW1lbnRzIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgeworCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmVyc2lvbjsKKyAgICBwcml2YXRlIGZpbmFsIGludCByb3VuZHM7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgd29yZFNpemU7CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gaXY7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPlJDNVBhcmFtZXRlclNwZWM8L2NvZGU+IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIHZlcnNpb24sIHJvdW5kIGNvdW50IGFuIHdvcmQgc2l6ZSAoaW4gYml0cykuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmVyc2lvbgorICAgICAqICAgICAgICAgICAgdGhlIHZlcnNpb24uCisgICAgICogQHBhcmFtIHJvdW5kcworICAgICAqICAgICAgICAgICAgdGhlIHJvdW5kIGNvdW50LgorICAgICAqIEBwYXJhbSB3b3JkU2l6ZQorICAgICAqICAgICAgICAgICAgdGhlIHdvcmQgc2l6ZSAoaW4gYml0cykuCisgICAgICovCisgICAgcHVibGljIFJDNVBhcmFtZXRlclNwZWMoaW50IHZlcnNpb24sIGludCByb3VuZHMsIGludCB3b3JkU2l6ZSkgeworICAgICAgICB0aGlzLnZlcnNpb24gPSB2ZXJzaW9uOworICAgICAgICB0aGlzLnJvdW5kcyA9IHJvdW5kczsKKyAgICAgICAgdGhpcy53b3JkU2l6ZSA9IHdvcmRTaXplOworICAgICAgICB0aGlzLml2ID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPlJDNVBhcmFtZXRlclNwZWM8L2NvZGU+IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIHZlcnNpb24sIHJvdW5kIGNvdW50LCB3b3JkIHNpemUgKGluIGJpdHMpIGFuZCBhbiA8aT5pbml0aWFsaXphdGlvbgorICAgICAqIHZlY3RvcjwvaT4uCisgICAgICogPHA+CisgICAgICogVGhlIHNpemUgb2YgdGhlIDxpPmluaXRpYWxpemF0aW9uIHZlY3RvcjwvaT4gbXVzdCBiZSBhdCBsZWFzdAorICAgICAqIDxjb2RlPjIgKiAod29yZFNpemUgLyA4KTwvY29kZT4gYnl0ZXMgd2hpY2ggYXJlIGNvcGllZCB0byBwcm90ZWN0IHRoZW0KKyAgICAgKiBhZ2FpbnN0IG1vZGlmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2ZXJzaW9uCisgICAgICogICAgICAgICAgICB0aGUgdmVyc2lvbi4KKyAgICAgKiBAcGFyYW0gcm91bmRzCisgICAgICogICAgICAgICAgICB0aGUgcm91bmQgY291bnQuCisgICAgICogQHBhcmFtIHdvcmRTaXplCisgICAgICogICAgICAgICAgICB0aGUgd29yZCBzaXplIChpbiBiaXRzKS4KKyAgICAgKiBAcGFyYW0gaXYKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3IuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaW5pdGlhbGl6YXRpb24gdmVjdG9yIGlzIG51bGwgb3Igc2hvcnRlciB0aGFuIDxjb2RlPjIKKyAgICAgKiAgICAgICAgICAgICAqICh3b3JkU2l6ZSAvIDgpPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgUkM1UGFyYW1ldGVyU3BlYyhpbnQgdmVyc2lvbiwgaW50IHJvdW5kcywgaW50IHdvcmRTaXplLCBieXRlW10gaXYpIHsKKyAgICAgICAgaWYgKGl2ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIml2ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaXYubGVuZ3RoIDwgMiAqICh3b3JkU2l6ZSAvIDgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJpdi5sZW5ndGggPCAyICogKHdvcmRTaXplIC8gOCkiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnZlcnNpb24gPSB2ZXJzaW9uOworICAgICAgICB0aGlzLnJvdW5kcyA9IHJvdW5kczsKKyAgICAgICAgdGhpcy53b3JkU2l6ZSA9IHdvcmRTaXplOworICAgICAgICB0aGlzLml2ID0gbmV3IGJ5dGVbMiood29yZFNpemUvOCldOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGl2LCAwLCB0aGlzLml2LCAwLCAyKih3b3JkU2l6ZS84KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5SQzVQYXJhbWV0ZXJTcGVjPC9jb2RlPiBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB2ZXJzaW9uLCByb3VuZCBjb3VudCwgd29yZFNpemUgKGluIGJpdHMpLCBhbiA8aT5pbml0aWFsaXphdGlvbiB2ZWN0b3I8L2k+CisgICAgICogYW5kIGFuIG9mZnNldC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgc2l6ZSBvZiB0aGUgPGk+aW5pdGlhbGl6YXRpb24gdmVjdG9yPC9pPiBtdXN0IGJlIGF0IGxlYXN0CisgICAgICogPGNvZGU+b2Zmc2V0ICsgKDIgKiAod29yZFNpemUgLyA4KSk8L2NvZGU+IGJ5dGVzLiBUaGUgYnl0ZXMgc3RhcnRpbmcgYXQKKyAgICAgKiA8Y29kZT5vZmZzZXQ8L2NvZGU+IGFyZSBjb3BpZWQgdG8gcHJvdGVjdCB0aGVtIGFnYWluc3QgbW9kaWZpY2F0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHZlcnNpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSB2ZXJzaW9uLgorICAgICAqIEBwYXJhbSByb3VuZHMKKyAgICAgKiAgICAgICAgICAgIHRoZSByb3VuZCBjb3VudC4KKyAgICAgKiBAcGFyYW0gd29yZFNpemUKKyAgICAgKiAgICAgICAgICAgIHRoZSB3b3JkIHNpemUgKGluIGJpdHMpLgorICAgICAqIEBwYXJhbSBpdgorICAgICAqICAgICAgICAgICAgdGhlIGluaXRpYWxpemF0aW9uIHZlY3Rvci4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3IuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaW5pdGlhbGl6YXRpb24gdmVjdG9yIGlzIG51bGwgb2Ygc2hvcnRlciB0aGFuCisgICAgICogICAgICAgICAgICAgPGNvZGU+b2Zmc2V0ICsgKDIgKiAod29yZFNpemUgLyA4KSk8L2NvZGU+LgorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgPGNvZGU+b2Zmc2V0PC9jb2RlPiBpcyBuZWdhdGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUkM1UGFyYW1ldGVyU3BlYyhpbnQgdmVyc2lvbiwgaW50IHJvdW5kcywgaW50IHdvcmRTaXplLCBieXRlW10gaXYsIGludCBvZmZzZXQpIHsKKyAgICAgICAgaWYgKGl2ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIml2ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2Zmc2V0IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigib2Zmc2V0IDwgMDogIiArIG9mZnNldCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGl2Lmxlbmd0aCAtIG9mZnNldCA8IDIgKiAod29yZFNpemUgLyA4KSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaXYubGVuZ3RoIC0gb2Zmc2V0IDwgMiAqICh3b3JkU2l6ZSAvIDgpIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjsKKyAgICAgICAgdGhpcy5yb3VuZHMgPSByb3VuZHM7CisgICAgICAgIHRoaXMud29yZFNpemUgPSB3b3JkU2l6ZTsKKyAgICAgICAgdGhpcy5pdiA9IG5ldyBieXRlW29mZnNldCsyKih3b3JkU2l6ZS84KV07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoaXYsIG9mZnNldCwgdGhpcy5pdiwgMCwgMiood29yZFNpemUvOCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZlcnNpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB2ZXJzaW9uLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VmVyc2lvbigpIHsKKyAgICAgICAgcmV0dXJuIHZlcnNpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcm91bmQgY291bnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByb3VuZCBjb3VudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFJvdW5kcygpIHsKKyAgICAgICAgcmV0dXJuIHJvdW5kczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB3b3JkIHNpemUgKGluIGJpdHMpLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgd29yZCBzaXplIChpbiBiaXRzKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFdvcmRTaXplKCkgeworICAgICAgICByZXR1cm4gd29yZFNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhlIGluaXRpYWxpemF0aW9uIHZlY3Rvci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBjb3B5IG9mIHRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3IsIG9yIG51bGwgaWYgbm9uZSBzcGVjaWZpZWQuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRJVigpIHsKKyAgICAgICAgaWYgKGl2ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtpdi5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGl2LCAwLCByZXN1bHQsIDAsIGl2Lmxlbmd0aCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBvYmplY3Qgd2l0aCB0aGlzIDxjb2RlPlJDNVBhcmFtZXRlclNwZWM8L2NvZGU+CisgICAgICogaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUuCisgICAgICogQHJldHVybiB0cnVlIGlmIHZlcnNpb24sIHJvdW5kIGNvdW50LCB3b3JkIHNpemUgYW5kIGluaXRpYWxpemFpb24gdmVjdG9yCisgICAgICogICAgICAgICBvZiBib3RoIG9iamVjdHMgYXJlIGVxdWFsLCBvdGhlcndpc2UgZmFsc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBSQzVQYXJhbWV0ZXJTcGVjKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIFJDNVBhcmFtZXRlclNwZWMgcHMgPSAoUkM1UGFyYW1ldGVyU3BlYykgb2JqOworICAgICAgICByZXR1cm4gKHZlcnNpb24gPT0gcHMudmVyc2lvbikKKyAgICAgICAgICAgICYmIChyb3VuZHMgPT0gcHMucm91bmRzKQorICAgICAgICAgICAgJiYgKHdvcmRTaXplID09IHBzLndvcmRTaXplKQorICAgICAgICAgICAgJiYgKEFycmF5cy5lcXVhbHMoaXYsIHBzLml2KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaGFzaCBjb2RlIG9mIHRoaXMgPGNvZGU+UkM1UGFyYW1ldGVyU3BlYzwvY29kZT4gaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IHJlc3VsdCA9IHZlcnNpb24gKyByb3VuZHMgKyB3b3JkU2l6ZTsKKyAgICAgICAgaWYgKGl2ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChieXRlIGVsZW1lbnQgOiBpdikgeworICAgICAgICAgICAgcmVzdWx0ICs9IGVsZW1lbnQgJiAweEZGOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vc3BlYy9TZWNyZXRLZXlTcGVjLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTg2ODkxNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9jcnlwdG8vc3BlYy9TZWNyZXRLZXlTcGVjLmphdmEKQEAgLTAsMCArMSwxNzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBqYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5LZXlTcGVjOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YXguY3J5cHRvLlNlY3JldEtleTsKKworLyoqCisgKiBBIGtleSBzcGVjaWZpY2F0aW9uIGZvciBhIDxjb2RlPlNlY3JldEtleTwvY29kZT4gYW5kIGFsc28gYSBzZWNyZXQga2V5CisgKiBpbXBsZW1lbnRhdGlvbiB0aGF0IGlzIHByb3ZpZGVyLWluZGVwZW5kZW50LiBJdCBjYW4gYmUgdXNlZCBmb3IgcmF3IHNlY3JldAorICoga2V5cyB0aGF0IGNhbiBiZSBzcGVjaWZpZWQgYXMgPGNvZGU+Ynl0ZVtdPC9jb2RlPi4KKyAqLworcHVibGljIGNsYXNzIFNlY3JldEtleVNwZWMgaW1wbGVtZW50cyBTZWNyZXRLZXksIEtleVNwZWMsIFNlcmlhbGl6YWJsZSB7CisKKyAgICAvLyBUaGUgNS4wIHNwZWMuIGRvZXNuJ3QgZGVjbGFyZSB0aGlzIHNlcmlhbFZlcnNpb25VSUQgZmllbGQKKyAgICAvLyBJbiBvcmRlciB0byBiZSBjb21wYXRpYmxlIGl0IGlzIGV4cGxpY2l0bHkgZGVjbGFyZWQgaGVyZQorICAgIC8vIGZvciBkZXRhaWxzIHNlZSBIQVJNT05ZLTIzMworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDY1NzcyMzgzMTczMDcyODk5MzNMOworCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10ga2V5OworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGFsZ29yaXRobTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+U2VjcmV0S2V5U3BlYzwvY29kZT4gZm9yIHRoZSBzcGVjaWZpZWQga2V5IGRhdGEgYW5kCisgICAgICogYWxnb3JpdGhtIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IGRhdGEuCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIGFsZ29yaXRobSBuYW1lLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGtleSBkYXRhIG9yIHRoZSBhbGdvcml0aG0gbmFtZSBpcyBudWxsIG9yIGlmIHRoZSBrZXkKKyAgICAgKiAgICAgICAgICAgICBkYXRhIGlzIGVtcHR5LgorICAgICAqLworICAgIHB1YmxpYyBTZWNyZXRLZXlTcGVjKGJ5dGVbXSBrZXksIFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJrZXkgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChrZXkubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImtleS5sZW5ndGggPT0gMCIpOworICAgICAgICB9CisgICAgICAgIGlmIChhbGdvcml0aG0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiYWxnb3JpdGhtID09IG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuYWxnb3JpdGhtID0gYWxnb3JpdGhtOworICAgICAgICB0aGlzLmtleSA9IG5ldyBieXRlW2tleS5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGtleSwgMCwgdGhpcy5rZXksIDAsIGtleS5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+U2VjcmV0S2V5U3BlYzwvY29kZT4gZm9yIHRoZSBrZXkgZGF0YSBmcm9tIHRoZQorICAgICAqIHNwZWNpZmllZCBidWZmZXIgPGNvZGU+a2V5PC9jb2RlPiBzdGFydGluZyBhdCA8Y29kZT5vZmZzZXQ8L2NvZGU+IHdpdGgKKyAgICAgKiBsZW5ndGggPGNvZGU+bGVuPC9jb2RlPiBhbmQgdGhlIHNwZWNpZmllZCA8Y29kZT5hbGdvcml0aG08L2NvZGU+IG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICogICAgICAgICAgICB0aGUga2V5IGRhdGEuCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgdGhlIG9mZnNldC4KKyAgICAgKiBAcGFyYW0gbGVuCisgICAgICogICAgICAgICAgICB0aGUgc2l6ZSBvZiB0aGUga2V5IGRhdGEuCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIGFsZ29yaXRobSBuYW1lLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGtleSBkYXRhIG9yIHRoZSBhbGdvcml0aG0gbmFtZSBpcyBudWxsLCB0aGUga2V5IGRhdGEKKyAgICAgKiAgICAgICAgICAgICBpcyBlbXB0eSBvciA8Y29kZT5vZmZzZXQ8L2NvZGU+IGFuZCA8Y29kZT5sZW48L2NvZGU+IGRvIG5vdAorICAgICAqICAgICAgICAgICAgIHNwZWNpZnkgYSB2YWxpZCBjaHVuayBpbiB0aGUgYnVmZmVyIDxjb2RlPmtleTwvY29kZT4uCisgICAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiA8Y29kZT5vZmZzZXQ8L2NvZGU+IG9yIDxjb2RlPmxlbjwvY29kZT4gaXMgbmVnYXRpdmUuCisgICAgICovCisgICAgcHVibGljIFNlY3JldEtleVNwZWMoYnl0ZVtdIGtleSwgaW50IG9mZnNldCwgaW50IGxlbiwgU3RyaW5nIGFsZ29yaXRobSkgeworICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImtleSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGtleS5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigia2V5Lmxlbmd0aCA9PSAwIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxlbiA8IDAgfHwgb2Zmc2V0IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigibGVuIDwgMCB8fCBvZmZzZXQgPCAwIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGtleS5sZW5ndGggLSBvZmZzZXQgPCBsZW4pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImtleSB0b28gc2hvcnQiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImFsZ29yaXRobSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5hbGdvcml0aG0gPSBhbGdvcml0aG07CisgICAgICAgIHRoaXMua2V5ID0gbmV3IGJ5dGVbbGVuXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShrZXksIG9mZnNldCwgdGhpcy5rZXksIDAsIGxlbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYWxnb3JpdGhtIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBhbGdvcml0aG0gbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgcmV0dXJuIGFsZ29yaXRobTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBmb3JtYXQgdXNlZCB0byBlbmNvZGUgdGhlIGtleS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGZvcm1hdCBuYW1lICJSQVciLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICByZXR1cm4gIlJBVyI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5jb2RlZCBmb3JtIG9mIHRoaXMgc2VjcmV0IGtleS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVuY29kZWQgZm9ybSBvZiB0aGlzIHNlY3JldCBrZXkuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVba2V5Lmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoa2V5LCAwLCByZXN1bHQsIDAsIGtleS5sZW5ndGgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhhc2ggY29kZSBvZiB0aGlzIDxjb2RlPlNlY3JldEtleVNwZWM8L2NvZGU+IG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBpbnQgcmVzdWx0ID0gYWxnb3JpdGhtLmxlbmd0aCgpOworICAgICAgICBmb3IgKGJ5dGUgZWxlbWVudCA6IGtleSkgeworICAgICAgICAgICAgcmVzdWx0ICs9IGVsZW1lbnQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIG9iamVjdCB3aXRoIHRoaXMgPGNvZGU+U2VjcmV0S2V5U3BlYzwvY29kZT4KKyAgICAgKiBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZS4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGFsZ29yaXRobSBuYW1lIGFuZCBrZXkgb2YgYm90aCBvYmplY3QgYXJlIGVxdWFsLAorICAgICAqICAgICAgICAgb3RoZXJ3aXNlIGZhbHNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgIGlmIChvYmogPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgU2VjcmV0S2V5U3BlYykpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBTZWNyZXRLZXlTcGVjIGtzID0gKFNlY3JldEtleVNwZWMpIG9iajsKKyAgICAgICAgcmV0dXJuIChhbGdvcml0aG0uZXF1YWxzSWdub3JlQ2FzZShrcy5hbGdvcml0aG0pKQorICAgICAgICAgICAgJiYgKEFycmF5cy5lcXVhbHMoa2V5LCBrcy5rZXkpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvY3J5cHRvL3NwZWMvcGFja2FnZS5odG1sIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNzdhYzNkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L2NyeXB0by9zcGVjL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDI1IEBACis8aHRtbD4KKyAgPGJvZHk+CisgICAgPHA+CisgICAgICBUaGlzIHBhY2thZ2UgcHJvdmlkZXMgdGhlIGNsYXNzZXMgYW5kIGludGVyZmFjZXMgbmVlZGVkIHRvIHNwZWNpZnkga2V5cworICAgICAgYW5kIHBhcmFtZXRlciBmb3IgZW5jcnlwdGlvbi4gVGhlIGZvbGxvd2luZyBzdGFuZGFyZHMgYXJlIHN1cHBvcnRlZDoKKyAgICAgIDx1bD4KKyAgICAgIDxsaT5QS0NTIzMgRGlmZmllLUhlbGxtYW4gS2V5IEFncmVlbWVudCBzdGFuZGFyZDsKKyAgICAgIDxsaT5GSVBTLTQ2LTIgRGF0YSBFbmNyeXB0aW9uIFN0YW5kYXJkIChERVMpOworICAgICAgPGxpPlBLQ1MjNSBQYXNzd29yZC1CYXNlZCBDcnlwdG9ncmFwaHkgc3RhbmRhcmQuCisgICAgICA8L3VsPgorICAgICAgPHA+S2V5cyBtYXkgYmUgc3BlY2lmaWVkIHZpYSBhbGdvcml0aG0gb3IgaW4gYSBtb3JlIGFic3RyYWN0IGFuZCBnZW5lcmFsIHdheQorICAgICAgd2l0aCBBU04uMS4KKworICAgICAgPHA+S2V5cyBhbmQgYWxnb3JpdGhtIHBhcmFtZXRlcnMgYXJlIHNwZWNpZmllZCBmb3IgdGhlIGZvbGxvd2luZyBwcm9jZWR1cmVzOgorICAgICAgPHVsPgorICAgICAgPGxpPkRICisgICAgICA8bGk+REVTCisgICAgICA8bGk+VHJpcGxlREVTCisgICAgICA8bGk+UEJFCisgICAgICA8bGk+UkMyCisgICAgICA8bGk+UkM1CisgICAgICA8L2xpPgorICAgIDwvcD4KKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9EZWZhdWx0U2VydmVyU29ja2V0RmFjdG9yeS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9EZWZhdWx0U2VydmVyU29ja2V0RmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4YTUyNmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L0RlZmF1bHRTZXJ2ZXJTb2NrZXRGYWN0b3J5LmphdmEKQEAgLTAsMCArMSw0NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKKworZmluYWwgY2xhc3MgRGVmYXVsdFNlcnZlclNvY2tldEZhY3RvcnkgZXh0ZW5kcyBTZXJ2ZXJTb2NrZXRGYWN0b3J5IHsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTZXJ2ZXJTb2NrZXQgY3JlYXRlU2VydmVyU29ja2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTZXJ2ZXJTb2NrZXQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2VydmVyU29ja2V0IGNyZWF0ZVNlcnZlclNvY2tldChpbnQgcG9ydCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTZXJ2ZXJTb2NrZXQocG9ydCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNlcnZlclNvY2tldCBjcmVhdGVTZXJ2ZXJTb2NrZXQoaW50IHBvcnQsIGludCBiYWNrbG9nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3IFNlcnZlclNvY2tldChwb3J0LCBiYWNrbG9nKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2VydmVyU29ja2V0IGNyZWF0ZVNlcnZlclNvY2tldChpbnQgcG9ydCwgaW50IGJhY2tsb2csIEluZXRBZGRyZXNzIGlBZGRyZXNzKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTZXJ2ZXJTb2NrZXQocG9ydCwgYmFja2xvZywgaUFkZHJlc3MpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvRGVmYXVsdFNvY2tldEZhY3RvcnkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvRGVmYXVsdFNvY2tldEZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZDI4ZDM3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9EZWZhdWx0U29ja2V0RmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsNTkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXgubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuVW5rbm93bkhvc3RFeGNlcHRpb247CisKKy8qKgorICogRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgamF2YXgubmV0LlNvY2tldEZhY3Rvcnl9CisgKi8KK2ZpbmFsIGNsYXNzIERlZmF1bHRTb2NrZXRGYWN0b3J5IGV4dGVuZHMgU29ja2V0RmFjdG9yeSB7CisKKyAgICBEZWZhdWx0U29ja2V0RmFjdG9yeSgpIHsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgU29ja2V0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoU3RyaW5nIGhvc3QsIGludCBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24sIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTb2NrZXQoaG9zdCwgcG9ydCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoU3RyaW5nIGhvc3QsIGludCBwb3J0LCBJbmV0QWRkcmVzcyBsb2NhbEhvc3QsIGludCBsb2NhbFBvcnQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTb2NrZXQoaG9zdCwgcG9ydCwgbG9jYWxIb3N0LCBsb2NhbFBvcnQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzIGhvc3QsIGludCBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3IFNvY2tldChob3N0LCBwb3J0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcyBhZGRyZXNzLCBpbnQgcG9ydCwgSW5ldEFkZHJlc3MgbG9jYWxBZGRyZXNzLAorICAgICAgICAgICAgaW50IGxvY2FsUG9ydCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTb2NrZXQoYWRkcmVzcywgcG9ydCwgbG9jYWxBZGRyZXNzLCBsb2NhbFBvcnQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvU2VydmVyU29ja2V0RmFjdG9yeS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9TZXJ2ZXJTb2NrZXRGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2Y5ZGFjYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvU2VydmVyU29ja2V0RmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU2VydmVyU29ja2V0OworaW1wb3J0IGphdmEubmV0LlNvY2tldEV4Y2VwdGlvbjsKKworLyoqCisgKiBUaGlzIGFic3RyYWN0IGNsYXNzIGRlZmluZXMgbWV0aG9kcyB0byBjcmVhdGUgc2VydmVyIHNvY2tldHMuIEl0IGNhbiBiZQorICogc3ViY2xhc3NlZCB0byBjcmVhdGUgc3BlY2lmaWMgc2VydmVyIHNvY2tldCB0eXBlcy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFNlcnZlclNvY2tldEZhY3RvcnkgeworICAgIHByaXZhdGUgc3RhdGljIFNlcnZlclNvY2tldEZhY3RvcnkgZGVmYXVsdEZhY3Rvcnk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHNlcnZlciBzb2NrZXQgZmFjdG9yeSBvZiB0aGUgc3lzdGVtIHdoaWNoIGNhbiBiZSB1c2VkIHRvCisgICAgICogY3JlYXRlIG5ldyBzZXJ2ZXIgc29ja2V0cyB3aXRob3V0IGNyZWF0aW5nIGEgc3ViY2xhc3Mgb2YgdGhpcyBmYWN0b3J5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3lzdGVtIGRlZmF1bHQgc2VydmVyIHNvY2tldCBmYWN0b3J5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIFNlcnZlclNvY2tldEZhY3RvcnkgZ2V0RGVmYXVsdCgpIHsKKyAgICAgICAgaWYgKGRlZmF1bHRGYWN0b3J5ID09IG51bGwpIHsKKyAgICAgICAgICAgIGRlZmF1bHRGYWN0b3J5ID0gbmV3IERlZmF1bHRTZXJ2ZXJTb2NrZXRGYWN0b3J5KCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRlZmF1bHRGYWN0b3J5OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFNlcnZlclNvY2tldEZhY3Rvcnl9IGluc3RhbmNlLgorICAgICAqLworICAgIHByb3RlY3RlZCBTZXJ2ZXJTb2NrZXRGYWN0b3J5KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgc2VydmVyIHNvY2tldCB3aGljaCBpcyBub3QgYm91bmQgdG8gYW55IGxvY2FsIGFkZHJlc3MuIFRoaXMKKyAgICAgKiBtZXRob2QgaGFzIHRvIGJlIG92ZXJyaWRkZW4gYnkgYSBzdWJjbGFzcyBvdGhlcndpc2UgYSB7QGNvZGUKKyAgICAgKiBTb2NrZXRFeGNlcHRpb259IGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgdW5ib3VuZCBzZXJ2ZXIgc29ja2V0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY3JlYXRpbmcgYSBuZXcgc2VydmVyIHNvY2tldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2VydmVyU29ja2V0IGNyZWF0ZVNlcnZlclNvY2tldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIGZvbGxvdyBSSSdzIGJlaGF2aW9yCisgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oIlVuYm91bmQgc2VydmVyIHNvY2tldHMgbm90IGltcGxlbWVudGVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBzZXJ2ZXIgc29ja2V0IHdoaWNoIGlzIGJvdW5kIHRvIHRoZSBnaXZlbiBwb3J0IHdpdGggYQorICAgICAqIG1heGltdW0gYmFja2xvZyBvZiA1MCB1bmFjY2VwdGVkIGNvbm5lY3Rpb25zLgorICAgICAqCisgICAgICogQHBhcmFtIHBvcnQgdGhlIHBvcnQgb24gd2hpY2ggdGhlIGNyZWF0ZWQgc29ja2V0IGhhcyB0byBsaXN0ZW4uCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCBib3VuZCBzZXJ2ZXIgc29ja2V0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY3JlYXRpbmcgYSBuZXcgc2VydmVyIHNvY2tldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2VydmVyU29ja2V0IGNyZWF0ZVNlcnZlclNvY2tldChpbnQgcG9ydCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBzZXJ2ZXIgc29ja2V0IHdoaWNoIGlzIGJvdW5kIHRvIHRoZSBnaXZlbiBwb3J0IGFuZAorICAgICAqIGNvbmZpZ3VyZXMgaXRzIG1heGltdW0gb2YgcXVldWVkIGNvbm5lY3Rpb25zLgorICAgICAqCisgICAgICogQHBhcmFtIHBvcnQgdGhlIHBvcnQgb24gd2hpY2ggdGhlIGNyZWF0ZWQgc29ja2V0IGhhcyB0byBsaXN0ZW4uCisgICAgICogQHBhcmFtIGJhY2tsb2cgdGhlIG1heGltdW0gbnVtYmVyIG9mIHVuYWNjZXB0ZWQgY29ubmVjdGlvbnMuIFBhc3NpbmcgMCBvcgorICAgICAqICAgICBhIG5lZ2F0aXZlIHZhbHVlIHlpZWxkcyB0aGUgZGVmYXVsdCBiYWNrbG9nIG9mIDUwLgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgYm91bmQgc2VydmVyIHNvY2tldC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjcmVhdGluZyBhIG5ldyBzZXJ2ZXIgc29ja2V0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTZXJ2ZXJTb2NrZXQgY3JlYXRlU2VydmVyU29ja2V0KGludCBwb3J0LCBpbnQgYmFja2xvZykgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBzZXJ2ZXIgc29ja2V0IHdoaWNoIGlzIGJvdW5kIHRvIHRoZSBnaXZlbiBhZGRyZXNzIG9uIHRoZQorICAgICAqIHNwZWNpZmllZCBwb3J0IGFuZCBjb25maWd1cmVzIGl0cyBtYXhpbXVtIG9mIHF1ZXVlZCBjb25uZWN0aW9ucy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwb3J0IHRoZSBwb3J0IG9uIHdoaWNoIHRoZSBjcmVhdGVkIHNvY2tldCBoYXMgdG8gbGlzdGVuLgorICAgICAqIEBwYXJhbSBiYWNrbG9nIHRoZSBtYXhpbXVtIG51bWJlciBvZiB1bmFjY2VwdGVkIGNvbm5lY3Rpb25zLiBQYXNzaW5nIDAgb3IKKyAgICAgKiAgICAgYSBuZWdhdGl2ZSB2YWx1ZSB5aWVsZHMgdGhlIGRlZmF1bHQgYmFja2xvZyBvZiA1MC4KKyAgICAgKiBAcGFyYW0gaUFkZHJlc3MgdGhlIGFkZHJlc3Mgb2YgdGhlIG5ldHdvcmsgaW50ZXJmYWNlIHdoaWNoIGlzIHVzZWQgYnkgdGhlCisgICAgICogICAgIGNyZWF0ZWQgc29ja2V0LgorICAgICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgYm91bmQgc2VydmVyIHNvY2tldC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjcmVhdGluZyBhIG5ldyBzZXJ2ZXIgc29ja2V0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTZXJ2ZXJTb2NrZXQgY3JlYXRlU2VydmVyU29ja2V0KGludCBwb3J0LCBpbnQgYmFja2xvZywgSW5ldEFkZHJlc3MgaUFkZHJlc3MpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvU29ja2V0RmFjdG9yeS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9Tb2NrZXRGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2ZkZGU0MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvU29ja2V0RmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMTUyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0OworaW1wb3J0IGphdmEubmV0LlNvY2tldEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKKworLyoqCisgKiBUaGlzIGFic3RyYWN0IGNsYXNzIGRlZmluZXMgbWV0aG9kcyB0byBjcmVhdGUgc29ja2V0cy4gSXQgY2FuIGJlIHN1YmNsYXNzZWQKKyAqIHRvIGNyZWF0ZSBzcGVjaWZpYyBzb2NrZXQgdHlwZXMgd2l0aCBhZGRpdGlvbmFsIHNvY2tldC1sZXZlbCBmdW5jdGlvbmFsaXR5LgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU29ja2V0RmFjdG9yeSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTb2NrZXRGYWN0b3J5IGRlZmF1bHRGYWN0b3J5OworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZGVmYXVsdCBzb2NrZXQgZmFjdG9yeSBvZiB0aGUgc3lzdGVtIHdoaWNoIGNhbiBiZSB1c2VkIHRvIGNyZWF0ZQorICAgICAqIG5ldyBzb2NrZXRzIHdpdGhvdXQgY3JlYXRpbmcgYSBzdWJjbGFzcyBvZiB0aGlzIGZhY3RvcnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzeXN0ZW0gZGVmYXVsdCBzb2NrZXQgZmFjdG9yeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBTb2NrZXRGYWN0b3J5IGdldERlZmF1bHQoKSB7CisgICAgICAgIGlmIChkZWZhdWx0RmFjdG9yeSA9PSBudWxsKSB7CisgICAgICAgICAgICBkZWZhdWx0RmFjdG9yeSA9IG5ldyBEZWZhdWx0U29ja2V0RmFjdG9yeSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkZWZhdWx0RmFjdG9yeTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBTb2NrZXRGYWN0b3J5fSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU29ja2V0RmFjdG9yeSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHNvY2tldCB3aGljaCBpcyBub3QgY29ubmVjdGVkIHRvIGFueSByZW1vdGUgaG9zdC4gVGhpcworICAgICAqIG1ldGhvZCBoYXMgdG8gYmUgb3ZlcnJpZGRlbiBieSBhIHN1YmNsYXNzIG90aGVyd2lzZSBhIHtAY29kZQorICAgICAqIFNvY2tldEV4Y2VwdGlvbn0gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCB1bmNvbm5lY3RlZCBzb2NrZXQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjcmVhdGluZyBhIG5ldyBzb2NrZXQuCisgICAgICovCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBmb2xsb3cgUkkncyBiZWhhdmlvcgorICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKCJVbmNvbm5lY3RlZCBzb2NrZXRzIG5vdCBpbXBsZW1lbnRlZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgc29ja2V0IHdoaWNoIGlzIGNvbm5lY3RlZCB0byB0aGUgcmVtb3RlIGhvc3Qgc3BlY2lmaWVkIGJ5CisgICAgICogdGhlIHBhcmFtZXRlcnMge0Bjb2RlIGhvc3R9IGFuZCB7QGNvZGUgcG9ydH0uIFRoZSBzb2NrZXQgaXMgYm91bmQgdG8gYW55CisgICAgICogYXZhaWxhYmxlIGxvY2FsIGFkZHJlc3MgYW5kIHBvcnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaG9zdAorICAgICAqICAgICAgICAgICAgdGhlIHJlbW90ZSBob3N0IGFkZHJlc3MgdGhlIHNvY2tldCBoYXMgdG8gYmUgY29ubmVjdGVkIHRvLgorICAgICAqIEBwYXJhbSBwb3J0CisgICAgICogICAgICAgICAgICB0aGUgcG9ydCBudW1iZXIgb2YgdGhlIHJlbW90ZSBob3N0IGF0IHdoaWNoIHRoZSBzb2NrZXQgaXMKKyAgICAgKiAgICAgICAgICAgIGNvbm5lY3RlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBjcmVhdGVkIGNvbm5lY3RlZCBzb2NrZXQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjcmVhdGluZyBhIG5ldyBzb2NrZXQuCisgICAgICogQHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgaG9zdCBpcyB1bmtub3duIG9yIHRoZSBJUCBhZGRyZXNzIGNvdWxkIG5vdAorICAgICAqICAgICAgICAgICAgIGJlIHJlc29sdmVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTb2NrZXQgY3JlYXRlU29ja2V0KFN0cmluZyBob3N0LCBpbnQgcG9ydCkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgVW5rbm93bkhvc3RFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHNvY2tldCB3aGljaCBpcyBjb25uZWN0ZWQgdG8gdGhlIHJlbW90ZSBob3N0IHNwZWNpZmllZCBieQorICAgICAqIHRoZSBwYXJhbWV0ZXJzIHtAY29kZSBob3N0fSBhbmQge0Bjb2RlIHBvcnR9LiBUaGUgc29ja2V0IGlzIGJvdW5kIHRvIHRoZQorICAgICAqIGxvY2FsIG5ldHdvcmsgaW50ZXJmYWNlIHNwZWNpZmllZCBieSB0aGUgSW5ldEFkZHJlc3Mge0Bjb2RlIGxvY2FsSG9zdH0gb24KKyAgICAgKiBwb3J0IHtAY29kZSBsb2NhbFBvcnR9LgorICAgICAqCisgICAgICogQHBhcmFtIGhvc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSByZW1vdGUgaG9zdCBhZGRyZXNzIHRoZSBzb2NrZXQgaGFzIHRvIGJlIGNvbm5lY3RlZCB0by4KKyAgICAgKiBAcGFyYW0gcG9ydAorICAgICAqICAgICAgICAgICAgdGhlIHBvcnQgbnVtYmVyIG9mIHRoZSByZW1vdGUgaG9zdCBhdCB3aGljaCB0aGUgc29ja2V0IGlzCisgICAgICogICAgICAgICAgICBjb25uZWN0ZWQuCisgICAgICogQHBhcmFtIGxvY2FsSG9zdAorICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsIGhvc3QgYWRkcmVzcyB0aGUgc29ja2V0IGlzIGJvdW5kIHRvLgorICAgICAqIEBwYXJhbSBsb2NhbFBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IG51bWJlciBvZiB0aGUgbG9jYWwgaG9zdCBhdCB3aGljaCB0aGUgc29ja2V0IGlzCisgICAgICogICAgICAgICAgICBib3VuZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBjcmVhdGVkIGNvbm5lY3RlZCBzb2NrZXQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSBjcmVhdGluZyBhIG5ldyBzb2NrZXQuCisgICAgICogQHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgaG9zdCBpcyB1bmtub3duIG9yIHRoZSBJUCBhZGRyZXNzIGNvdWxkIG5vdAorICAgICAqICAgICAgICAgICAgIGJlIHJlc29sdmVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTb2NrZXQgY3JlYXRlU29ja2V0KFN0cmluZyBob3N0LCBpbnQgcG9ydCwgSW5ldEFkZHJlc3MgbG9jYWxIb3N0LCBpbnQgbG9jYWxQb3J0KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBVbmtub3duSG9zdEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgc29ja2V0IHdoaWNoIGlzIGNvbm5lY3RlZCB0byB0aGUgcmVtb3RlIGhvc3Qgc3BlY2lmaWVkIGJ5CisgICAgICogdGhlIEluZXRBZGRyZXNzIHtAY29kZSBob3N0fS4gVGhlIHNvY2tldCBpcyBib3VuZCB0byBhbnkgYXZhaWxhYmxlIGxvY2FsCisgICAgICogYWRkcmVzcyBhbmQgcG9ydC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3N0CisgICAgICogICAgICAgICAgICB0aGUgaG9zdCBhZGRyZXNzIHRoZSBzb2NrZXQgaGFzIHRvIGJlIGNvbm5lY3RlZCB0by4KKyAgICAgKiBAcGFyYW0gcG9ydAorICAgICAqICAgICAgICAgICAgdGhlIHBvcnQgbnVtYmVyIG9mIHRoZSByZW1vdGUgaG9zdCBhdCB3aGljaCB0aGUgc29ja2V0IGlzCisgICAgICogICAgICAgICAgICBjb25uZWN0ZWQuCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCBjb25uZWN0ZWQgc29ja2V0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY3JlYXRpbmcgYSBuZXcgc29ja2V0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTb2NrZXQgY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzIGhvc3QsIGludCBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgc29ja2V0IHdoaWNoIGlzIGNvbm5lY3RlZCB0byB0aGUgcmVtb3RlIGhvc3Qgc3BlY2lmaWVkIGJ5CisgICAgICogdGhlIEluZXRBZGRyZXNzIHtAY29kZSBhZGRyZXNzfS4gVGhlIHNvY2tldCBpcyBib3VuZCB0byB0aGUgbG9jYWwgbmV0d29yaworICAgICAqIGludGVyZmFjZSBzcGVjaWZpZWQgYnkgdGhlIEluZXRBZGRyZXNzIHtAY29kZSBsb2NhbEhvc3R9IG9uIHBvcnQge0Bjb2RlCisgICAgICogbG9jYWxQb3J0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhZGRyZXNzCisgICAgICogICAgICAgICAgICB0aGUgcmVtb3RlIGhvc3QgYWRkcmVzcyB0aGUgc29ja2V0IGhhcyB0byBiZSBjb25uZWN0ZWQgdG8uCisgICAgICogQHBhcmFtIHBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IG51bWJlciBvZiB0aGUgcmVtb3RlIGhvc3QgYXQgd2hpY2ggdGhlIHNvY2tldCBpcworICAgICAqICAgICAgICAgICAgY29ubmVjdGVkLgorICAgICAqIEBwYXJhbSBsb2NhbEFkZHJlc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhbCBob3N0IGFkZHJlc3MgdGhlIHNvY2tldCBpcyBib3VuZCB0by4KKyAgICAgKiBAcGFyYW0gbG9jYWxQb3J0CisgICAgICogICAgICAgICAgICB0aGUgcG9ydCBudW1iZXIgb2YgdGhlIGxvY2FsIGhvc3QgYXQgd2hpY2ggdGhlIHNvY2tldCBpcworICAgICAqICAgICAgICAgICAgYm91bmQuCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlZCBjb25uZWN0ZWQgc29ja2V0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgY3JlYXRpbmcgYSBuZXcgc29ja2V0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTb2NrZXQgY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzIGFkZHJlc3MsIGludCBwb3J0LCBJbmV0QWRkcmVzcyBsb2NhbEFkZHJlc3MsCisgICAgICAgICAgICBpbnQgbG9jYWxQb3J0KSB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3BhY2thZ2UuaHRtbCBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2NzRkMDYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDcgQEAKKzxodG1sPgorICA8Ym9keT4KKyAgICA8cD4KKyAgICAgIFRoaXMgcGFja2FnZSBwcm92aWRlcyBmYWN0b3J5IGNsYXNzZXMgdG8gY3JlYXRlIHNvY2tldHMgYW5kIHNlcnZlci1zb2NrZXRzLiBUaGlzIGNsYXNzZXMgY2FuIGJlIHN1YmNsYXNzZWQgdG8gY3JlYXRlIGZhY3RvcmllcyBmb3Igb3RoZXIga2luZHMgb2Ygc29ja2V0IGZvciBleGFtcGxlIHRoZSBTU0wtY2FwYWJsZSBzb2NrZXRzIGZyb20gdGhlIHBhY2thZ2UgamF2YXgubmV0LnNzbC4KKyAgICA8L3A+CisgIDwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0NlcnRQYXRoVHJ1c3RNYW5hZ2VyUGFyYW1ldGVycy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvQ2VydFBhdGhUcnVzdE1hbmFnZXJQYXJhbWV0ZXJzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjIwNzA4OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0NlcnRQYXRoVHJ1c3RNYW5hZ2VyUGFyYW1ldGVycy5qYXZhCkBAIC0wLDAgKzEsNTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aFBhcmFtZXRlcnM7CisKKy8qKgorICogQ2VydGlmaWNhdGlvbiBwYXRoIHBhcmFtZXRlcnMgdG8gcHJvdmlkZSB0byBjZXJ0aWZpY2F0aW9uIHBhdGgKKyAqIGJhc2VkIHtAbGluayBUcnVzdE1hbmFnZXJ9LgorICoKKyAqIEBzaW5jZSAxLjUKKyAqLworcHVibGljIGNsYXNzIENlcnRQYXRoVHJ1c3RNYW5hZ2VyUGFyYW1ldGVycyBpbXBsZW1lbnRzIE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyB7CisKKyAgICBwcml2YXRlIGZpbmFsIENlcnRQYXRoUGFyYW1ldGVycyBwYXJhbTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENlcnRQYXRoVHJ1c3RNYW5hZ2VyUGFyYW1ldGVyc30gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogY2VydGlmaWNhdGlvbiBwYXRoIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVycworICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRpb24gcGF0aCBwYXJhbWV0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0UGF0aFRydXN0TWFuYWdlclBhcmFtZXRlcnMoQ2VydFBhdGhQYXJhbWV0ZXJzIHBhcmFtZXRlcnMpIHsKKyAgICAgICAgcGFyYW0gPSAoQ2VydFBhdGhQYXJhbWV0ZXJzKSBwYXJhbWV0ZXJzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhlIGNlcnRpZmljYXRpb24gcGF0aCBwYXJhbWV0ZXJzLgorICAgICAqCisgICAgICogQHJldHVybiBhIGNvcHkgb2YgdGhlIGNlcnRpZmljYXRpb24gcGF0aCBwYXJhbWV0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0UGF0aFBhcmFtZXRlcnMgZ2V0UGFyYW1ldGVycygpIHsKKyAgICAgICAgcmV0dXJuIChDZXJ0UGF0aFBhcmFtZXRlcnMpIHBhcmFtLmNsb25lKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9EZWZhdWx0SG9zdG5hbWVWZXJpZmllci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvRGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZmVkMjgwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvRGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIuamF2YQpAQCAtMCwwICsxLDIwMSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CisKKy8qKgorICogQSBIb3N0bmFtZVZlcmlmaWVyIHRoYXQgd29ya3MgdGhlIHNhbWUgd2F5IGFzIEN1cmwgYW5kIEZpcmVmb3guCisgKgorICogPHA+VGhlIGhvc3RuYW1lIG11c3QgbWF0Y2ggZWl0aGVyIHRoZSBmaXJzdCBDTiwgb3IgYW55IG9mIHRoZSBzdWJqZWN0LWFsdHMuCisgKiBBIHdpbGRjYXJkIGNhbiBvY2N1ciBpbiB0aGUgQ04sIGFuZCBpbiBhbnkgb2YgdGhlIHN1YmplY3QtYWx0cy4KKyAqCisgKiBAYXV0aG9yIEp1bGl1cyBEYXZpZXMKKyAqLworY2xhc3MgRGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIgaW1wbGVtZW50cyBIb3N0bmFtZVZlcmlmaWVyIHsKKworICAgIC8qKgorICAgICAqIFRoaXMgY29udGFpbnMgYSBsaXN0IG9mIDJuZC1sZXZlbCBkb21haW5zIHRoYXQgYXJlbid0IGFsbG93ZWQgdG8KKyAgICAgKiBoYXZlIHdpbGRjYXJkcyB3aGVuIGNvbWJpbmVkIHdpdGggY291bnRyeS1jb2Rlcy4KKyAgICAgKiBGb3IgZXhhbXBsZTogWyouY28udWtdLgorICAgICAqCisgICAgICogPHA+VGhlIFsqLmNvLnVrXSBwcm9ibGVtIGlzIGFuIGludGVyZXN0aW5nIG9uZS4gIFNob3VsZCB3ZSBqdXN0IGhvcGUKKyAgICAgKiB0aGF0IENBJ3Mgd291bGQgbmV2ZXIgZm9vbGlzaGx5IGFsbG93IHN1Y2ggYSBjZXJ0aWZpY2F0ZSB0byBoYXBwZW4/CisgICAgICogTG9va3MgbGlrZSB3ZSdyZSB0aGUgb25seSBpbXBsZW1lbnRhdGlvbiBndWFyZGluZyBhZ2FpbnN0IHRoaXMuCisgICAgICogRmlyZWZveCwgQ3VybCwgU3VuIEphdmEgMS40LCA1LCA2IGRvbid0IGJvdGhlciB3aXRoIHRoaXMgY2hlY2suCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gQkFEX0NPVU5UUllfMkxEUyA9CisgICAgICAgICAgeyAiYWMiLCAiY28iLCAiY29tIiwgImVkIiwgImVkdSIsICJnbyIsICJnb3V2IiwgImdvdiIsICJpbmZvIiwKKyAgICAgICAgICAgICJsZyIsICJuZSIsICJuZXQiLCAib3IiLCAib3JnIiB9OworCisgICAgc3RhdGljIHsKKyAgICAgICAgLy8gSnVzdCBpbiBjYXNlIGRldmVsb3BlciBmb3Jnb3QgdG8gbWFudWFsbHkgc29ydCB0aGUgYXJyYXkuICA6LSkKKyAgICAgICAgQXJyYXlzLnNvcnQoQkFEX0NPVU5UUllfMkxEUyk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gdmVyaWZ5KFN0cmluZyBob3N0LCBTU0xTZXNzaW9uIHNlc3Npb24pIHsKKyAgICAgICAgQ2VydGlmaWNhdGVbXSBjZXJ0czsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRzID0gc2Vzc2lvbi5nZXRQZWVyQ2VydGlmaWNhdGVzKCk7CisgICAgICAgIH0gY2F0Y2ggKFNTTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgeDUwOSA9IChYNTA5Q2VydGlmaWNhdGUpIGNlcnRzWzBdOworCisgICAgICAgIC8vIFdlIGNhbiBiZSBjYXNlLWluc2Vuc2l0aXZlIHdoZW4gY29tcGFyaW5nIHRoZSBob3N0IHdlIHVzZWQgdG8KKyAgICAgICAgLy8gZXN0YWJsaXNoIHRoZSBzb2NrZXQgdG8gdGhlIGhvc3RuYW1lIGluIHRoZSBjZXJ0aWZpY2F0ZS4KKyAgICAgICAgU3RyaW5nIGhvc3ROYW1lID0gaG9zdC50cmltKCkudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpOworCisgICAgICAgIC8vIFZlcmlmeSB0aGUgZmlyc3QgQ04gcHJvdmlkZWQuIE90aGVyIENOcyBhcmUgaWdub3JlZC4gRmlyZWZveCwgd2dldCwKKyAgICAgICAgLy8gY3VybCwgYW5kIFN1biBKYXZhIHdvcmsgdGhpcyB3YXkuCisgICAgICAgIFN0cmluZyBmaXJzdENuID0gZ2V0Rmlyc3RDbih4NTA5KTsKKyAgICAgICAgaWYgKG1hdGNoZXMoaG9zdE5hbWUsIGZpcnN0Q24pKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoU3RyaW5nIGNuIDogZ2V0RE5TU3ViamVjdEFsdHMoeDUwOSkpIHsKKyAgICAgICAgICAgIGlmIChtYXRjaGVzKGhvc3ROYW1lLCBjbikpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYge0Bjb2RlIGhvc3RuYW1lfSBtYXRjaGVzIHtAY29kZSBjbn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaG9zdE5hbWUgYSB0cmltbWVkLCBsb3dlcmNhc2UgaG9zdG5hbWUgdG8gdmVyaWZ5CisgICAgICogQHBhcmFtIGNuIGEgY2VydGlmaWNhdGUgQ04gb3IgRE5TIHN1YmplY3QgYWx0LiBFaXRoZXIgYSBsaXRlcmFsIG5hbWUgb3IKKyAgICAgKiAgICAgYSB3aWxkY2FyZCBvZiB0aGUgZm9ybSAiKi5nb29nbGUuY29tIi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gbWF0Y2hlcyhTdHJpbmcgaG9zdE5hbWUsIFN0cmluZyBjbikgeworICAgICAgICBpZiAoY24gPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLy8gRG9uJ3QgdHJpbSB0aGUgQ04sIHRob3VnaCEKKyAgICAgICAgY24gPSBjbi50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisKKyAgICAgICAgaWYgKGNuLnN0YXJ0c1dpdGgoIiouIikpIHsKKyAgICAgICAgICAgIC8vIFdoZW4gYSB3aWxkY2FyZCBtYXRjaGVzLCBhbHNvIGNoZWNrIHRoYXQgdGhlIHdpbGRjYXJkIGlzIGxlZ2l0CisgICAgICAgICAgICAvLyAgIC0gV2lsZGNhcmRzIG11c3QgY29udGFpbiBhdCBsZWFzdCB0d28gZG90czogIiouZ29vZ2xlLmNvbSIKKyAgICAgICAgICAgIC8vICAgLSBXaWxkY2FyZHMgbXVzdCBiZSBmb3IgcHJpdmF0ZSBkb21haW5zLiBObyAiKi5jby51ayIgZXRjLgorICAgICAgICAgICAgLy8gICAtIFdpbGRjYXJkcyBtdXN0IG5vdCBtYXRjaCBJUCBhZGRyZXNzZXM6ICIqLjguOCIKKyAgICAgICAgICAgIGludCBtYXRjaExlbmd0aCA9IGNuLmxlbmd0aCgpIC0gMTsKKyAgICAgICAgICAgIHJldHVybiBob3N0TmFtZS5yZWdpb25NYXRjaGVzKGhvc3ROYW1lLmxlbmd0aCgpIC0gbWF0Y2hMZW5ndGgsIGNuLCAxLCBtYXRjaExlbmd0aCkKKyAgICAgICAgICAgICAgICAgICAgJiYgY24uaW5kZXhPZignLicsIDIpICE9IC0xCisgICAgICAgICAgICAgICAgICAgICYmIGFjY2VwdGFibGVDb3VudHJ5V2lsZGNhcmQoY24pCisgICAgICAgICAgICAgICAgICAgICYmICFJbmV0QWRkcmVzcy5pc051bWVyaWMoaG9zdE5hbWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIGhvc3ROYW1lLmVxdWFscyhjbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gYWNjZXB0YWJsZUNvdW50cnlXaWxkY2FyZChTdHJpbmcgY24pIHsKKyAgICAgICAgaW50IGNuTGVuID0gY24ubGVuZ3RoKCk7CisgICAgICAgIGlmIChjbkxlbiA+PSA3ICYmIGNuTGVuIDw9IDkpIHsKKyAgICAgICAgICAgIC8vIExvb2sgZm9yIHRoZSAnLicgaW4gdGhlIDNyZC1sYXN0IHBvc2l0aW9uOgorICAgICAgICAgICAgaWYgKGNuLmNoYXJBdChjbkxlbiAtIDMpID09ICcuJykgeworICAgICAgICAgICAgICAgIC8vIFRyaW0gb2ZmIHRoZSBbKi5dIGFuZCB0aGUgWy5YWF0uCisgICAgICAgICAgICAgICAgU3RyaW5nIHMgPSBjbi5zdWJzdHJpbmcoMiwgY25MZW4gLSAzKTsKKyAgICAgICAgICAgICAgICAvLyBBbmQgdGVzdCBhZ2FpbnN0IHRoZSBzb3J0ZWQgYXJyYXkgb2YgYmFkIDJsZHM6CisgICAgICAgICAgICAgICAgaW50IHggPSBBcnJheXMuYmluYXJ5U2VhcmNoKEJBRF9DT1VOVFJZXzJMRFMsIHMpOworICAgICAgICAgICAgICAgIHJldHVybiB4IDwgMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyBnZXRGaXJzdENuKFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0KSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFNlYmFzdGlhbiBIYXVlcidzIG9yaWdpbmFsIFN0cmljdFNTTFByb3RvY29sU29ja2V0RmFjdG9yeSB1c2VkCisgICAgICAgICAqIGdldE5hbWUoKSBhbmQgaGFkIHRoZSBmb2xsb3dpbmcgY29tbWVudDoKKyAgICAgICAgICoKKyAgICAgICAgICogICAgICBQYXJzZXMgYSBYLjUwMCBkaXN0aW5ndWlzaGVkIG5hbWUgZm9yIHRoZSB2YWx1ZSBvZiB0aGUKKyAgICAgICAgICogICAgICJDb21tb24gTmFtZSIgZmllbGQuICBUaGlzIGlzIGRvbmUgYSBiaXQgc2xvcHB5IHJpZ2h0CisgICAgICAgICAqICAgICBub3cgYW5kIHNob3VsZCBwcm9iYWJseSBiZSBkb25lIGEgYml0IG1vcmUgYWNjb3JkaW5nIHRvCisgICAgICAgICAqICAgICA8Y29kZT5SRkMgMjI1MzwvY29kZT4uCisgICAgICAgICAqCisgICAgICAgICAqIEkndmUgbm90aWNlZCB0aGF0IHRvU3RyaW5nKCkgc2VlbXMgdG8gZG8gYSBiZXR0ZXIgam9iIHRoYW4KKyAgICAgICAgICogZ2V0TmFtZSgpIG9uIHRoZXNlIFg1MDBQcmluY2lwYWwgb2JqZWN0cywgc28gSSdtIGhvcGluZyB0aGF0CisgICAgICAgICAqIGFkZHJlc3NlcyBTZWJhc3RpYW4ncyBjb25jZXJuLgorICAgICAgICAgKgorICAgICAgICAgKiBGb3IgZXhhbXBsZSwgZ2V0TmFtZSgpIGdpdmVzIG1lIHRoaXM6CisgICAgICAgICAqIDEuMi44NDAuMTEzNTQ5LjEuOS4xPSMxNjE2NmE3NTZjNjk3NTczNjQ2MTc2Njk2NTczNDA2Mzc1NjM2MjYzMmU2MzZmNmQKKyAgICAgICAgICoKKyAgICAgICAgICogd2hlcmVhcyB0b1N0cmluZygpIGdpdmVzIG1lIHRoaXM6CisgICAgICAgICAqIEVNQUlMQUREUkVTUz1qdWxpdXNkYXZpZXNAY3VjYmMuY29tCisgICAgICAgICAqCisgICAgICAgICAqIExvb2tzIGxpa2UgdG9TdHJpbmcoKSBldmVuIHdvcmtzIHdpdGggbm9uLWFzY2lpIGRvbWFpbiBuYW1lcyEKKyAgICAgICAgICogSSB0ZXN0ZWQgaXQgd2l0aCAiJiN4ODJiMTsmI3g1YjUwOy5jby5qcCIgYW5kIGl0IHdvcmtlZCBmaW5lLgorICAgICAgICAgKi8KKyAgICAgICAgU3RyaW5nIHN1YmplY3RQcmluY2lwYWwgPSBjZXJ0LmdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCkudG9TdHJpbmcoKTsKKyAgICAgICAgZm9yIChTdHJpbmcgdG9rZW4gOiBzdWJqZWN0UHJpbmNpcGFsLnNwbGl0KCIsIikpIHsKKyAgICAgICAgICAgIGludCB4ID0gdG9rZW4uaW5kZXhPZigiQ049Iik7CisgICAgICAgICAgICBpZiAoeCA+PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRva2VuLnN1YnN0cmluZyh4ICsgMyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbGwgU3ViamVjdEFsdCBETlMgbmFtZXMgZnJvbSBhbiBYNTA5Q2VydGlmaWNhdGUuCisgICAgICoKKyAgICAgKiA8cD5Ob3RlOiBKYXZhIGRvZXNuJ3QgYXBwZWFyIGFibGUgdG8gZXh0cmFjdCBpbnRlcm5hdGlvbmFsIGNoYXJhY3RlcnMKKyAgICAgKiBmcm9tIHRoZSBTdWJqZWN0QWx0cy4gIEl0IGNhbiBvbmx5IGV4dHJhY3QgaW50ZXJuYXRpb25hbCBjaGFyYWN0ZXJzCisgICAgICogZnJvbSB0aGUgQ04gZmllbGQuCisgICAgICoKKyAgICAgKiA8cD4oT3IgbWF5YmUgdGhlIHZlcnNpb24gb2YgT3BlblNTTCBJJ20gdXNpbmcgdG8gdGVzdCBpc24ndCBzdG9yaW5nIHRoZQorICAgICAqIGludGVybmF0aW9uYWwgY2hhcmFjdGVycyBjb3JyZWN0bHkgaW4gdGhlIFN1YmplY3RBbHRzPykuCisgICAgICovCisgICAgcHJpdmF0ZSBMaXN0PFN0cmluZz4gZ2V0RE5TU3ViamVjdEFsdHMoWDUwOUNlcnRpZmljYXRlIGNlcnQpIHsKKyAgICAgICAgQ29sbGVjdGlvbjxMaXN0PD8+PiBzdWJqZWN0QWx0ZXJuYXRpdmVOYW1lczsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN1YmplY3RBbHRlcm5hdGl2ZU5hbWVzID0gY2VydC5nZXRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcygpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24gY3BlKSB7CisgICAgICAgICAgICBTeXN0ZW0ubG9nSSgiRXJyb3IgcGFyc2luZyBjZXJ0aWZpY2F0ZSIsIGNwZSk7CisgICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc3ViamVjdEFsdGVybmF0aXZlTmFtZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOworICAgICAgICB9CisKKyAgICAgICAgTGlzdDxTdHJpbmc+IHN1YmplY3RBbHRMaXN0ID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGZvciAoTGlzdDw/PiBwYWlyIDogc3ViamVjdEFsdGVybmF0aXZlTmFtZXMpIHsKKyAgICAgICAgICAgIGludCB0eXBlID0gKEludGVnZXIpIHBhaXIuZ2V0KDApOworICAgICAgICAgICAgLy8gSWYgdHlwZSBpcyAyLCB0aGVuIHdlJ3ZlIGdvdCBhIGROU05hbWUKKyAgICAgICAgICAgIGlmICh0eXBlID09IDIpIHsKKyAgICAgICAgICAgICAgICBzdWJqZWN0QWx0TGlzdC5hZGQoKFN0cmluZykgcGFpci5nZXQoMSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBzdWJqZWN0QWx0TGlzdDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9EZWZhdWx0U1NMU2VydmVyU29ja2V0RmFjdG9yeS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvRGVmYXVsdFNTTFNlcnZlclNvY2tldEZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMDcwZTZiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvRGVmYXVsdFNTTFNlcnZlclNvY2tldEZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDYzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRFeGNlcHRpb247CitpbXBvcnQgbGliY29yZS51dGlsLkVtcHR5QXJyYXk7CisKKy8qKgorICogRGVmYXVsdCBpbm9wZXJhdGl2ZSBpbXBsZW1lbnRhdGlvbiBvZiBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldEZhY3RvcnkKKyAqLworY2xhc3MgRGVmYXVsdFNTTFNlcnZlclNvY2tldEZhY3RvcnkgZXh0ZW5kcyBTU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5IHsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGVyck1lc3NhZ2U7CisKKyAgICBEZWZhdWx0U1NMU2VydmVyU29ja2V0RmFjdG9yeShTdHJpbmcgbWVzKSB7CisgICAgICAgIGVyck1lc3NhZ2UgPSBtZXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ1tdIGdldERlZmF1bHRDaXBoZXJTdWl0ZXMoKSB7CisgICAgICAgIHJldHVybiBFbXB0eUFycmF5LlNUUklORzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkgeworICAgICAgICByZXR1cm4gRW1wdHlBcnJheS5TVFJJTkc7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNlcnZlclNvY2tldCBjcmVhdGVTZXJ2ZXJTb2NrZXQoaW50IHBvcnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oZXJyTWVzc2FnZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNlcnZlclNvY2tldCBjcmVhdGVTZXJ2ZXJTb2NrZXQoaW50IHBvcnQsIGludCBiYWNrbG9nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKGVyck1lc3NhZ2UpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTZXJ2ZXJTb2NrZXQgY3JlYXRlU2VydmVyU29ja2V0KGludCBwb3J0LCBpbnQgYmFja2xvZywgSW5ldEFkZHJlc3MgaUFkZHJlc3MpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKGVyck1lc3NhZ2UpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvRGVmYXVsdFNTTFNvY2tldEZhY3RvcnkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0RlZmF1bHRTU0xTb2NrZXRGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWJmZDc0YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0RlZmF1bHRTU0xTb2NrZXRGYWN0b3J5LmphdmEKQEAgLTAsMCArMSw3NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUudXRpbC5FbXB0eUFycmF5OworCisvKioKKyAqIERlZmF1bHQgaW5vcGVyYXRpdmUgaW1wbGVtZW50YXRpb24gb2YgamF2YXgubmV0LnNzbC5TU0xTb2NrZXRGYWN0b3J5CisgKgorICovCitjbGFzcyBEZWZhdWx0U1NMU29ja2V0RmFjdG9yeSBleHRlbmRzIFNTTFNvY2tldEZhY3RvcnkgeworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZXJyTWVzc2FnZTsKKworICAgIERlZmF1bHRTU0xTb2NrZXRGYWN0b3J5KFN0cmluZyBtZXMpIHsKKyAgICAgICAgZXJyTWVzc2FnZSA9IG1lczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgcmV0dXJuIEVtcHR5QXJyYXkuU1RSSU5HOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSB7CisgICAgICAgIHJldHVybiBFbXB0eUFycmF5LlNUUklORzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldChTb2NrZXQgcywgU3RyaW5nIGhvc3QsIGludCBwb3J0LCBib29sZWFuIGF1dG9DbG9zZSkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oZXJyTWVzc2FnZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoU3RyaW5nIGhvc3QsIGludCBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24sIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbihlcnJNZXNzYWdlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldChTdHJpbmcgaG9zdCwgaW50IHBvcnQsIEluZXRBZGRyZXNzIGxvY2FsSG9zdCwgaW50IGxvY2FsUG9ydCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgVW5rbm93bkhvc3RFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKGVyck1lc3NhZ2UpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzIGhvc3QsIGludCBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKGVyck1lc3NhZ2UpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzIGFkZHJlc3MsIGludCBwb3J0LCBJbmV0QWRkcmVzcyBsb2NhbEFkZHJlc3MsCisgICAgICAgICAgICBpbnQgbG9jYWxQb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKGVyck1lc3NhZ2UpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0hhbmRzaGFrZUNvbXBsZXRlZEV2ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjlhY2IwYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0hhbmRzaGFrZUNvbXBsZXRlZEV2ZW50LmphdmEKQEAgLTAsMCArMSwxMzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuRXZlbnRPYmplY3Q7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CisKKy8qKgorICogVGhlIGV2ZW50IG9iamVjdCBlbmNhcHN1bGF0aW5nIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBhIGNvbXBsZXRlZCBTU0wKKyAqIGhhbmRzaGFrZSBvbiBhIFNTTCBjb25uZWN0aW9uLgorICovCitwdWJsaWMgY2xhc3MgSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQgZXh0ZW5kcyBFdmVudE9iamVjdCB7CisKKyAgICBwcml2YXRlIHRyYW5zaWVudCBTU0xTZXNzaW9uIHNlc3Npb247CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBIYW5kc2hha2VDb21wbGV0ZWRFdmVudH0gd2l0aCB0aGUgc3BlY2lmaWVkIFNTTAorICAgICAqIHNvY2tldCBhbmQgU1NMIHNlc3Npb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc29jaworICAgICAqICAgICAgICAgICAgdGhlIFNTTCBzb2NrZXQuCisgICAgICogQHBhcmFtIHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBTU0wgc2Vzc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQoU1NMU29ja2V0IHNvY2ssIFNTTFNlc3Npb24gcykgeworICAgICAgICBzdXBlcihzb2NrKTsKKyAgICAgICAgc2Vzc2lvbiA9IHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgU1NMIHNlc3Npb24gYXNzb2NpYXRlZCB3aXRoIHRoaXMgZXZlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBTU0wgc2Vzc2lvbiBhc3NvY2lhdGVkIHdpdGggdGhpcyBldmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1NMU2Vzc2lvbiBnZXRTZXNzaW9uKCkgeworICAgICAgICByZXR1cm4gc2Vzc2lvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBjaXBoZXIgc3VpdGUgbmVnb3RpYXRlZCBkdXJpbmcgdGhpcyBoYW5kc2hha2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBjaXBoZXIgc3VpdGUgbmVnb3RpYXRlZCBkdXJpbmcgdGhpcyBoYW5kc2hha2UuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDaXBoZXJTdWl0ZSgpIHsKKyAgICAgICAgcmV0dXJuIHNlc3Npb24uZ2V0Q2lwaGVyU3VpdGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIGxvY2FsIGNlcnRpZmljYXRlcyB1c2VkIGR1cmluZyB0aGUgaGFuZHNoYWtlLiBUaGVzZQorICAgICAqIGNlcnRpZmljYXRlcyB3ZXJlIHNlbnQgdG8gdGhlIHBlZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGVzIHVzZWQgZHVyaW5nIHRoZSBoYW5kc2hha2Ugd2l0aAorICAgICAqICAgICAgICAgdGhlIGxvY2FsIGlkZW50aXR5IGNlcnRpZmljYXRlIGZvbGxvd2VkIGJ5IENBcywgb3Ige0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpZiBubyBjZXJ0aWZpY2F0ZXMgd2VyZSB1c2VkIGR1cmluZyB0aGUgaGFuZHNoYWtlLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZVtdIGdldExvY2FsQ2VydGlmaWNhdGVzKCkgeworICAgICAgICByZXR1cm4gc2Vzc2lvbi5nZXRMb2NhbENlcnRpZmljYXRlcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbGlzdCBvZiBjZXJ0aWZpY2F0ZXMgaWRlbnRpZnlpbmcgdGhlIHBlZXIgZHVyaW5nIHRoZQorICAgICAqIGhhbmRzaGFrZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGVzIGlkZW50aWZ5aW5nIHRoZSBwZWVyIHdpdGggdGhlIHBlZXIncworICAgICAqICAgICAgICAgaWRlbnRpdHkgY2VydGlmaWNhdGUgZm9sbG93ZWQgYnkgQ0FzLgorICAgICAqIEB0aHJvd3MgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaWRlbnRpdHkgb2YgdGhlIHBlZXIgaGFzIG5vdCBiZWVuIHZlcmlmaWVkLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZVtdIGdldFBlZXJDZXJ0aWZpY2F0ZXMoKSB0aHJvd3MgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc2Vzc2lvbi5nZXRQZWVyQ2VydGlmaWNhdGVzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGlzdCBvZiBjZXJ0aWZpY2F0ZXMgaWRlbnRpZnlpbmcgdGhlIHBlZXIuIFRoZSBwZWVyJ3MKKyAgICAgKiBpZGVudGl0eSBjZXJ0aWZpY2F0ZSBpcyBmb2xsb3dlZCBieSB0aGUgdmFsaWRhdGVkIGNlcnRpZmljYXRlIGF1dGhvcml0eQorICAgICAqIGNlcnRpZmljYXRlcy4KKyAgICAgKiA8cD4KKyAgICAgKiA8Yj5SZXBsYWNlZCBieTo8L2I+IHtAbGluayAjZ2V0UGVlckNlcnRpZmljYXRlcygpfQorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGlzdCBvZiBjZXJ0aWZpY2F0ZXMgaWRlbnRpZnlpbmcgdGhlIHBlZXIKKyAgICAgKiBAdGhyb3dzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGlkZW50aXR5IG9mIHRoZSBwZWVyIGhhcyBub3QgYmVlbiB2ZXJpZmllZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgWDUwOUNlcnRpZmljYXRlW10gZ2V0UGVlckNlcnRpZmljYXRlQ2hhaW4oKSB0aHJvd3MgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc2Vzc2lvbi5nZXRQZWVyQ2VydGlmaWNhdGVDaGFpbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBQcmluY2lwYWx9IGlkZW50aWZ5aW5nIHRoZSBwZWVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFByaW5jaXBhbH0gaWRlbnRpZnlpbmcgdGhlIHBlZXIuCisgICAgICogQHRocm93cyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBpZGVudGl0eSBvZiB0aGUgcGVlciBoYXMgbm90IGJlZW4gdmVyaWZpZWQuCisgICAgICovCisgICAgcHVibGljIFByaW5jaXBhbCBnZXRQZWVyUHJpbmNpcGFsKCkgdGhyb3dzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNlc3Npb24uZ2V0UGVlclByaW5jaXBhbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBQcmluY2lwYWx9IHVzZWQgdG8gaWRlbnRpZnkgZHVyaW5nIHRoZSBoYW5kc2hha2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgUHJpbmNpcGFsfSB1c2VkIHRvIGlkZW50aWZ5IGR1cmluZyB0aGUgaGFuZHNoYWtlLgorICAgICAqLworICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0TG9jYWxQcmluY2lwYWwoKSB7CisgICAgICAgIHJldHVybiBzZXNzaW9uLmdldExvY2FsUHJpbmNpcGFsKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgU1NMIHNvY2tldCB0aGF0IHByb2R1Y2VkIHRoaXMgZXZlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBTU0wgc29ja2V0IHRoYXQgcHJvZHVjZWQgdGhpcyBldmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1NMU29ja2V0IGdldFNvY2tldCgpIHsKKyAgICAgICAgcmV0dXJuIChTU0xTb2NrZXQpIHRoaXMuc291cmNlOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0hhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTAzMmM2MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0hhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyLmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CisKKy8qKgorICogVGhlIGxpc3RlbmVyIHRvIGJlIGltcGxlbWVudGVkIHRvIHJlY2VpdmUgZXZlbnQgbm90aWZpY2F0aW9ucyBvbiBjb21wbGV0aW9uCisgKiBvZiBTU0wgaGFuZHNoYWtlIG9uIGFuIFNTTCBjb25uZWN0aW9uLgorICovCitwdWJsaWMgaW50ZXJmYWNlIEhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyIGV4dGVuZHMgRXZlbnRMaXN0ZW5lciB7CisgICAgLyoqCisgICAgICogVGhlIGNhbGxiYWNrIG1ldGhvZCB0aGF0IGlzIGludm9rZWQgd2hlbiBhIFNTTCBoYW5kc2hha2UgaXMgY29tcGxldGVkLgorICAgICAqCisgICAgICogQHBhcmFtIGV2ZW50CisgICAgICogICAgICAgICAgICB0aGUgaW5mb3JtYXRpb24gb24gdGhlIGNvbXBsZXRlZCBTU0wgaGFuZHNoYWtlIGV2ZW50LgorICAgICAqLworICAgIHZvaWQgaGFuZHNoYWtlQ29tcGxldGVkKEhhbmRzaGFrZUNvbXBsZXRlZEV2ZW50IGV2ZW50KTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0hvc3RuYW1lVmVyaWZpZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0hvc3RuYW1lVmVyaWZpZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MDU3NjJlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvSG9zdG5hbWVWZXJpZmllci5qYXZhCkBAIC0wLDAgKzEsNDAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXgubmV0LnNzbDsKKworLyoqCisgKiBUaGUgaW50ZXJmYWNlIHRvIGJlIHVzZWQgdG8gcHJvdmlkZSBob3N0bmFtZSB2ZXJpZmljYXRpb24gZnVuY3Rpb25hbGl0eS4KKyAqIDxwPgorICogVGhpcyBpcyBhbiBleHRlbmRlZCB2ZXJpZmljYXRpb24gb3B0aW9uIHRoYXQgaW1wbGVtZW50ZXJzIGNhbiBwcm92aWRlLiBJdCBpcyB0byBiZSB1c2VkCisgKiBkdXJpbmcgYSBoYW5kc2hha2UgaWYgdGhlIFVSTCdzIGhvc3RuYW1lIGRvZXMgbm90IG1hdGNoIHRoZSBwZWVyJ3MKKyAqIGlkZW50aWZpY2F0aW9uIGhvc3RuYW1lLgorICovCitwdWJsaWMgaW50ZXJmYWNlIEhvc3RuYW1lVmVyaWZpZXIgeworICAgIC8qKgorICAgICAqIFZlcmlmaWVzIHRoYXQgdGhlIHNwZWNpZmllZCBob3N0bmFtZSBpcyBhbGxvd2VkIHdpdGhpbiB0aGUgc3BlY2lmaWVkIFNTTAorICAgICAqIHNlc3Npb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaG9zdG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBob3N0bmFtZS4KKyAgICAgKiBAcGFyYW0gc2Vzc2lvbgorICAgICAqICAgICAgICAgICAgdGhlIFNTTCBzZXNzaW9uIG9mIHRoZSBjb25uZWN0aW9uLgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgaG9zdG5hbWUgaXMgYWxsb3dlZCwgb3RoZXJ3aXNlCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9LgorICAgICAqLworICAgIGJvb2xlYW4gdmVyaWZ5KFN0cmluZyBob3N0bmFtZSwgU1NMU2Vzc2lvbiBzZXNzaW9uKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0h0dHBzVVJMQ29ubmVjdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvSHR0cHNVUkxDb25uZWN0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGYyMmYzOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0h0dHBzVVJMQ29ubmVjdGlvbi5qYXZhCkBAIC0wLDAgKzEsMjk2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLm5ldC5IdHRwVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QcmluY2lwYWw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CisKKy8qKgorICogQW4ge0BsaW5rIEh0dHBVUkxDb25uZWN0aW9ufSBmb3IgSFRUUFMgKDxhCisgKiBocmVmPSJodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMyODE4Ij5SRkMgMjgxODwvYT4pLiBBCisgKiBjb25uZWN0ZWQge0Bjb2RlIEh0dHBzVVJMQ29ubmVjdGlvbn0gYWxsb3dzIGFjY2VzcyB0byB0aGUKKyAqIG5lZ290aWF0ZWQgY2lwaGVyIHN1aXRlLCB0aGUgc2VydmVyIGNlcnRpZmljYXRlIGNoYWluLCBhbmQgdGhlCisgKiBjbGllbnQgY2VydGlmaWNhdGUgY2hhaW4gaWYgYW55LgorICoKKyAqIDxoMz5Qcm92aWRpbmcgYW4gYXBwbGljYXRpb24gc3BlY2lmaWMgWDUwOVRydXN0TWFuYWdlcjwvaDM+CisgKgorICogSWYgYW4gYXBwbGljYXRpb24gd2FudHMgdG8gdHJ1c3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IChDQSkKKyAqIGNlcnRpZmljYXRlcyB0aGF0IGFyZSBub3QgcGFydCBvZiB0aGUgc3lzdGVtLCBpdCBzaG91bGQgc3BlY2lmeSBpdHMKKyAqIG93biB7QGNvZGUgWDUwOVRydXN0TWFuYWdlcn0gdmlhIGEge0Bjb2RlIFNTTFNvY2tldEZhY3Rvcnl9IHNldCBvbgorICogdGhlIHtAY29kZSBIdHRwc1VSTENvbm5lY3Rpb259LiBUaGUge0Bjb2RlIFg1MDlUcnVzdE1hbmFnZXJ9IGNhbiBiZQorICogY3JlYXRlZCBiYXNlZCBvbiBhIHtAY29kZSBLZXlTdG9yZX0gdXNpbmcgYSB7QGNvZGUKKyAqIFRydXN0TWFuYWdlckZhY3Rvcnl9IHRvIHN1cHBseSB0cnVzdGVkIENBIGNlcnRpZmljYXRlcy4gTm90ZSB0aGF0CisgKiBzZWxmLXNpZ25lZCBjZXJ0aWZpY2F0ZXMgYXJlIGVmZmVjdGl2ZWx5IHRoZWlyIG93biBDQSBhbmQgY2FuIGJlCisgKiB0cnVzdGVkIGJ5IGluY2x1ZGluZyB0aGVtIGluIGEge0Bjb2RlIEtleVN0b3JlfS4KKyAqCisgKiA8cD5Gb3IgZXhhbXBsZSwgdG8gdHJ1c3QgYSBzZXQgb2YgY2VydGlmaWNhdGVzIHNwZWNpZmllZCBieSBhIHtAY29kZSBLZXlTdG9yZX06CisgKiA8cHJlPiAgIHtAY29kZQorICogICBLZXlTdG9yZSBrZXlTdG9yZSA9IC4uLjsKKyAqICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeSB0bWYgPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKCJYNTA5Iik7CisgKiAgIHRtZi5pbml0KGtleVN0b3JlKTsKKyAqCisgKiAgIFNTTENvbnRleHQgY29udGV4dCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UoIlRMUyIpOworICogICBjb250ZXh0LmluaXQobnVsbCwgdG1mLmdldFRydXN0TWFuYWdlcnMoKSwgbnVsbCk7CisgKgorICogICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cHM6Ly93d3cuZXhhbXBsZS5jb20vIik7CisgKiAgIEh0dHBzVVJMQ29ubmVjdGlvbiB1cmxDb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgKiAgIHVybENvbm5lY3Rpb24uc2V0U1NMU29ja2V0RmFjdG9yeShjb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKSk7CisgKiAgIElucHV0U3RyZWFtIGluID0gdXJsQ29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpOworICogfTwvcHJlPgorICoKKyAqIDxwPkl0IGlzIHBvc3NpYmxlIHRvIGltcGxlbWVudCB7QGNvZGUgWDUwOVRydXN0TWFuYWdlcn0gZGlyZWN0bHkKKyAqIGluc3RlYWQgb2YgdXNpbmcgb25lIGNyZWF0ZWQgYnkgYSB7QGNvZGUKKyAqIFRydXN0TWFuYWdlckZhY3Rvcnl9LiBXaGlsZSB0aGlzIGlzIHN0cmFpZ2h0Zm9yd2FyZCBpbiB0aGUgaW5zZWN1cmUKKyAqIGNhc2Ugb2YgYWxsb3dpbmcgYWxsIGNlcnRpZmljYXRlIGNoYWlucyB0byBwYXNzIHZlcmlmaWNhdGlvbiwKKyAqIHdyaXRpbmcgYSBwcm9wZXIgaW1wbGVtZW50YXRpb24gd2lsbCB1c3VhbGx5IHdhbnQgdG8gdGFrZSBhZHZhbnRhZ2UKKyAqIG9mIHtAbGluayBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhWYWxpZGF0b3IKKyAqIENlcnRQYXRoVmFsaWRhdG9yfS4gSW4gZ2VuZXJhbCwgaXQgbWlnaHQgYmUgYmV0dGVyIHRvIHdyaXRlIGEKKyAqIGN1c3RvbSB7QGNvZGUgS2V5U3RvcmV9IGltcGxlbWVudGF0aW9uIHRvIHBhc3MgdG8gdGhlIHtAY29kZQorICogVHJ1c3RNYW5hZ2VyRmFjdG9yeX0gdGhhbiB0byB0cnkgYW5kIHdyaXRlIGEgY3VzdG9tIHtAY29kZQorICogWDUwOVRydXN0TWFuYWdlcn0uCisgKgorICogPGgzPlByb3ZpZGluZyBhbiBhcHBsaWNhdGlvbiBzcGVjaWZpYyBYNTA5S2V5TWFuYWdlcjwvaDM+CisgKgorICogQSBjdXN0b20ge0Bjb2RlIFg1MDlLZXlNYW5hZ2VyfSBjYW4gYmUgdXNlZCB0byBzdXBwbHkgYSBjbGllbnQKKyAqIGNlcnRpZmljYXRlIGFuZCBpdHMgYXNzb2NpYXRlZCBwcml2YXRlIGtleSB0byBhdXRoZW50aWNhdGUgYQorICogY29ubmVjdGlvbiB0byB0aGUgc2VydmVyLiBUaGUge0Bjb2RlIFg1MDlLZXlNYW5hZ2VyfSBjYW4gYmUgY3JlYXRlZAorICogYmFzZWQgb24gYSB7QGNvZGUgS2V5U3RvcmV9IHVzaW5nIGEge0Bjb2RlIEtleU1hbmFnZXJGYWN0b3J5fS4KKyAqCisgKiA8cD5Gb3IgZXhhbXBsZSwgdG8gc3VwcGx5IGNsaWVudCBjZXJ0aWZpY2F0ZXMgZnJvbSBhIHtAY29kZSBLZXlTdG9yZX06CisgKiA8cHJlPiAgIHtAY29kZQorICogICBLZXlTdG9yZSBrZXlTdG9yZSA9IC4uLjsKKyAqICAgS2V5TWFuYWdlckZhY3Rvcnkga21mID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoIlg1MDkiKTsKKyAqICAga21mLmluaXQoa2V5U3RvcmUpOworICoKKyAqICAgU1NMQ29udGV4dCBjb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZSgiVExTIik7CisgKiAgIGNvbnRleHQuaW5pdChrbWYuZ2V0S2V5TWFuYWdlcnMoKSwgbnVsbCwgbnVsbCk7CisgKgorICogICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cHM6Ly93d3cuZXhhbXBsZS5jb20vIik7CisgKiAgIEh0dHBzVVJMQ29ubmVjdGlvbiB1cmxDb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgKiAgIHVybENvbm5lY3Rpb24uc2V0U1NMU29ja2V0RmFjdG9yeShjb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKSk7CisgKiAgIElucHV0U3RyZWFtIGluID0gdXJsQ29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpOworICogfTwvcHJlPgorICoKKyAqIDxwPkEge0Bjb2RlIFg1MDlLZXlNYW5hZ2VyfSBjYW4gYWxzbyBiZSBpbXBsZW1lbnRlZCBkaXJlY3RseS4gVGhpcworICogY2FuIGFsbG93IGFuIGFwcGxpY2F0aW9uIHRvIHJldHVybiBhIGNlcnRpZmljYXRlIGFuZCBwcml2YXRlIGtleQorICogZnJvbSBhIG5vbi17QGNvZGUgS2V5U3RvcmV9IHNvdXJjZSBvciB0byBzcGVjaWZ5IGl0cyBvd24gbG9naWMgZm9yCisgKiBzZWxlY3RpbmcgYSBzcGVjaWZpYyBjcmVkZW50aWFsIHRvIHVzZSB3aGVuIG1hbnkgbWF5IGJlIHByZXNlbnQgaW4KKyAqIGEgc2luZ2xlIHtAY29kZSBLZXlTdG9yZX0uCisgKgorICogPGgzPlRMUyBJbnRvbGVyYW5jZSBTdXBwb3J0PC9oMz4KKyAqCisgKiBUaGlzIGNsYXNzIGF0dGVtcHRzIHRvIGNyZWF0ZSBzZWN1cmUgY29ubmVjdGlvbnMgdXNpbmcgY29tbW9uIFRMUworICogZXh0ZW5zaW9ucyBhbmQgU1NMIGRlZmxhdGUgY29tcHJlc3Npb24uIFNob3VsZCB0aGF0IGZhaWwsIHRoZQorICogY29ubmVjdGlvbiB3aWxsIGJlIHJldHJpZWQgd2l0aCBTU0x2MyBvbmx5LgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgSHR0cHNVUkxDb25uZWN0aW9uIGV4dGVuZHMgSHR0cFVSTENvbm5lY3Rpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgSG9zdG5hbWVWZXJpZmllciBkZWZhdWx0SG9zdG5hbWVWZXJpZmllciA9IG5ldyBEZWZhdWx0SG9zdG5hbWVWZXJpZmllcigpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU1NMU29ja2V0RmFjdG9yeSBkZWZhdWx0U1NMU29ja2V0RmFjdG9yeSA9IChTU0xTb2NrZXRGYWN0b3J5KSBTU0xTb2NrZXRGYWN0b3J5CisgICAgICAgICAgICAuZ2V0RGVmYXVsdCgpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGVmYXVsdCBob3N0bmFtZSB2ZXJpZmllciB0byBiZSB1c2VkIGJ5IG5ldyBpbnN0YW5jZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdgorICAgICAqICAgICAgICAgICAgdGhlIG5ldyBkZWZhdWx0IGhvc3RuYW1lIHZlcmlmaWVyCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHZlcmlmaWVyIGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoSG9zdG5hbWVWZXJpZmllciB2KSB7CisgICAgICAgIGlmICh2ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkhvc3RuYW1lVmVyaWZpZXIgaXMgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGRlZmF1bHRIb3N0bmFtZVZlcmlmaWVyID0gdjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGhvc3RuYW1lIHZlcmlmaWVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZGVmYXVsdCBob3N0bmFtZSB2ZXJpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEhvc3RuYW1lVmVyaWZpZXIgZ2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoKSB7CisgICAgICAgIHJldHVybiBkZWZhdWx0SG9zdG5hbWVWZXJpZmllcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBkZWZhdWx0IFNTTCBzb2NrZXQgZmFjdG9yeSB0byBiZSB1c2VkIGJ5IG5ldyBpbnN0YW5jZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2YKKyAgICAgKiAgICAgICAgICAgIHRoZSBuZXcgZGVmYXVsdCBTU0wgc29ja2V0IGZhY3RvcnkuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHNvY2tldCBmYWN0b3J5IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0RGVmYXVsdFNTTFNvY2tldEZhY3RvcnkoU1NMU29ja2V0RmFjdG9yeSBzZikgeworICAgICAgICBpZiAoc2YgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiU1NMU29ja2V0RmFjdG9yeSBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgZGVmYXVsdFNTTFNvY2tldEZhY3RvcnkgPSBzZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IFNTTCBzb2NrZXQgZmFjdG9yeSBmb3IgbmV3IGluc3RhbmNlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGRlZmF1bHQgU1NMIHNvY2tldCBmYWN0b3J5IGZvciBuZXcgaW5zdGFuY2VzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU1NMU29ja2V0RmFjdG9yeSBnZXREZWZhdWx0U1NMU29ja2V0RmFjdG9yeSgpIHsKKyAgICAgICAgcmV0dXJuIGRlZmF1bHRTU0xTb2NrZXRGYWN0b3J5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBob3N0IG5hbWUgdmVyaWZpZXIgdXNlZCBieSB0aGlzIGNvbm5lY3Rpb24uIEl0IGlzIGluaXRpYWxpemVkIGZyb20KKyAgICAgKiB0aGUgZGVmYXVsdCBob3N0bmFtZSB2ZXJpZmllcgorICAgICAqIHtAbGluayAjc2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoSG9zdG5hbWVWZXJpZmllcil9IG9yCisgICAgICoge0BsaW5rICNnZXREZWZhdWx0SG9zdG5hbWVWZXJpZmllcigpfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSG9zdG5hbWVWZXJpZmllciBob3N0bmFtZVZlcmlmaWVyOworCisgICAgcHJpdmF0ZSBTU0xTb2NrZXRGYWN0b3J5IHNzbFNvY2tldEZhY3Rvcnk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBIdHRwc1VSTENvbm5lY3Rpb259IHdpdGggdGhlIHNwZWNpZmllZCB7QGNvZGUgVVJMfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmwKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgVVJMfSB0byBjb25uZWN0IHRvLgorICAgICAqLworICAgIHByb3RlY3RlZCBIdHRwc1VSTENvbm5lY3Rpb24oVVJMIHVybCkgeworICAgICAgICBzdXBlcih1cmwpOworICAgICAgICBob3N0bmFtZVZlcmlmaWVyID0gZGVmYXVsdEhvc3RuYW1lVmVyaWZpZXI7CisgICAgICAgIHNzbFNvY2tldEZhY3RvcnkgPSBkZWZhdWx0U1NMU29ja2V0RmFjdG9yeTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBjaXBoZXIgc3VpdGUgbmVnb3RpYXRlZCBkdXJpbmcgdGhlIFNTTCBoYW5kc2hha2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBjaXBoZXIgc3VpdGUgbmVnb3RpYXRlZCBkdXJpbmcgdGhlIFNTTCBoYW5kc2hha2UuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBjb25uZWN0aW9uIGhhcyBiZWVuIGVzdGFibGlzaGVkIHlldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldENpcGhlclN1aXRlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIGxvY2FsIGNlcnRpZmljYXRlcyB1c2VkIGR1cmluZyB0aGUgaGFuZHNoYWtlLiBUaGVzZQorICAgICAqIGNlcnRpZmljYXRlcyB3ZXJlIHNlbnQgdG8gdGhlIHBlZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGVzIHVzZWQgZHVyaW5nIHRoZSBoYW5kc2hha2Ugd2l0aAorICAgICAqICAgICAgICAgdGhlIGxvY2FsIGlkZW50aXR5IGNlcnRpZmljYXRlIGZvbGxvd2VkIGJ5IENBcywgb3Ige0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpZiBubyBjZXJ0aWZpY2F0ZXMgd2VyZSB1c2VkIGR1cmluZyB0aGUgaGFuZHNoYWtlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgbm8gY29ubmVjdGlvbiBoYXMgYmVlbiBlc3RhYmxpc2hlZCB5ZXQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IENlcnRpZmljYXRlW10gZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbGlzdCBvZiBjZXJ0aWZpY2F0ZXMgaWRlbnRpZnlpbmcgdGhlIHBlZXIgZHVyaW5nIHRoZQorICAgICAqIGhhbmRzaGFrZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGVzIGlkZW50aWZ5aW5nIHRoZSBwZWVyIHdpdGggdGhlIHBlZXIncworICAgICAqICAgICAgICAgaWRlbnRpdHkgY2VydGlmaWNhdGUgZm9sbG93ZWQgYnkgQ0FzLgorICAgICAqIEB0aHJvd3MgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaWRlbnRpdHkgb2YgdGhlIHBlZXIgaGFzIG5vdCBiZWVuIHZlcmlmaWVkLi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG5vIGNvbm5lY3Rpb24gaGFzIGJlZW4gZXN0YWJsaXNoZWQgeWV0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBDZXJ0aWZpY2F0ZVtdIGdldFNlcnZlckNlcnRpZmljYXRlcygpIHRocm93cyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBQcmluY2lwYWx9IGlkZW50aWZ5aW5nIHRoZSBwZWVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFByaW5jaXBhbH0gaWRlbnRpZnlpbmcgdGhlIHBlZXIuCisgICAgICogQHRocm93cyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBpZGVudGl0eSBvZiB0aGUgcGVlciBoYXMgbm90IGJlZW4gdmVyaWZpZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBjb25uZWN0aW9uIGhhcyBiZWVuIGVzdGFibGlzaGVkIHlldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpbmNpcGFsIGdldFBlZXJQcmluY2lwYWwoKSB0aHJvd3MgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24geworICAgICAgICBDZXJ0aWZpY2F0ZVtdIGNlcnRzID0gZ2V0U2VydmVyQ2VydGlmaWNhdGVzKCk7CisgICAgICAgIGlmIChjZXJ0cyA9PSBudWxsIHx8IGNlcnRzLmxlbmd0aCA9PSAwIHx8ICghKGNlcnRzWzBdIGluc3RhbmNlb2YgWDUwOUNlcnRpZmljYXRlKSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbigiTm8gc2VydmVyJ3MgZW5kLWVudGl0eSBjZXJ0aWZpY2F0ZSIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoKFg1MDlDZXJ0aWZpY2F0ZSkgY2VydHNbMF0pLmdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUge0Bjb2RlIFByaW5jaXBhbH0gdXNlZCB0byBpZGVudGlmeSB0aGUgbG9jYWwgaG9zdCBkdXJpbmcgdGhlIGhhbmRzaGFrZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBQcmluY2lwYWx9IHVzZWQgdG8gaWRlbnRpZnkgdGhlIGxvY2FsIGhvc3QgZHVyaW5nIHRoZSBoYW5kc2hha2UsIG9yCisgICAgICogICAgICAgICB7QGNvZGUgbnVsbH0gaWYgbm9uZSB3YXMgdXNlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG5vIGNvbm5lY3Rpb24gaGFzIGJlZW4gZXN0YWJsaXNoZWQgeWV0LgorICAgICAqLworICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0TG9jYWxQcmluY2lwYWwoKSB7CisgICAgICAgIENlcnRpZmljYXRlW10gY2VydHMgPSBnZXRMb2NhbENlcnRpZmljYXRlcygpOworICAgICAgICBpZiAoY2VydHMgPT0gbnVsbCB8fCBjZXJ0cy5sZW5ndGggPT0gMCB8fCAoIShjZXJ0c1swXSBpbnN0YW5jZW9mIFg1MDlDZXJ0aWZpY2F0ZSkpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKChYNTA5Q2VydGlmaWNhdGUpIGNlcnRzWzBdKS5nZXRTdWJqZWN0WDUwMFByaW5jaXBhbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGhvc3RuYW1lIHZlcmlmaWVyIGZvciB0aGlzIGluc3RhbmNlLgorICAgICAqCisgICAgICogQHBhcmFtIHYKKyAgICAgKiAgICAgICAgICAgIHRoZSBob3N0bmFtZSB2ZXJpZmllciBmb3IgdGhpcyBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgdmVyaWZpZXIgaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEhvc3RuYW1lVmVyaWZpZXIoSG9zdG5hbWVWZXJpZmllciB2KSB7CisgICAgICAgIGlmICh2ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkhvc3RuYW1lVmVyaWZpZXIgaXMgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGhvc3RuYW1lVmVyaWZpZXIgPSB2OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhvc3RuYW1lIHZlcmlmaWVyIHVzZWQgYnkgdGhpcyBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGhvc3RuYW1lIHZlcmlmaWVyIHVzZWQgYnkgdGhpcyBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSG9zdG5hbWVWZXJpZmllciBnZXRIb3N0bmFtZVZlcmlmaWVyKCkgeworICAgICAgICByZXR1cm4gaG9zdG5hbWVWZXJpZmllcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBTU0wgc29ja2V0IGZhY3RvcnkgZm9yIHRoaXMgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2YKKyAgICAgKiAgICAgICAgICAgIHRoZSBTU0wgc29ja2V0IGZhY3RvcnkgdG8gYmUgdXNlZCBieSB0aGlzIGluc3RhbmNlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBzb2NrZXQgZmFjdG9yeSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U1NMU29ja2V0RmFjdG9yeShTU0xTb2NrZXRGYWN0b3J5IHNmKSB7CisgICAgICAgIGlmIChzZiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJTU0xTb2NrZXRGYWN0b3J5IGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBzc2xTb2NrZXRGYWN0b3J5ID0gc2Y7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgU1NMIHNvY2tldCBmYWN0b3J5IHVzZWQgYnkgdGhpcyBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIFNTTCBzb2NrZXQgZmFjdG9yeSB1c2VkIGJ5IHRoaXMgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIFNTTFNvY2tldEZhY3RvcnkgZ2V0U1NMU29ja2V0RmFjdG9yeSgpIHsKKyAgICAgICAgcmV0dXJuIHNzbFNvY2tldEZhY3Rvcnk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9LZXlNYW5hZ2VyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9LZXlNYW5hZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzBjODAzMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0tleU1hbmFnZXIuamF2YQpAQCAtMCwwICsxLDI3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldC5zc2w7CisKKy8qKgorICogVGhpcyBpcyB0aGUgaW50ZXJmYWNlIHRvIGltcGxlbWVudCBpbiBvcmRlciB0byBtYXJrIGEgY2xhc3MgYXMgYSBKU1NFIGtleQorICogbWFuYWdlcnMgc28gdGhhdCBrZXkgbWFuYWdlcnMgY2FuIGJlIGVhc2lseSBncm91cGVkLiBUaGUga2V5IG1hbmFnZXJzIGFyZQorICogcmVzcG9uc2libGUgZm9yIGhhbmRsaW5nIHRoZSBrZXlzIHVzZWQgdG8gYXV0aGVudGljYXRlIHRoZSBsb2NhbCBzaWRlIHRvIGl0cworICogcGVlciwKKyAqLworcHVibGljIGludGVyZmFjZSBLZXlNYW5hZ2VyIHsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0tleU1hbmFnZXJGYWN0b3J5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9LZXlNYW5hZ2VyRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyY2U4YTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9LZXlNYW5hZ2VyRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMjIyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuZm9ydHJlc3MuRW5naW5lOworCisvKioKKyAqIFRoZSBwdWJsaWMgQVBJIGZvciB7QGNvZGUgS2V5TWFuYWdlckZhY3Rvcnl9IGltcGxlbWVudGF0aW9ucy4KKyAqLworcHVibGljIGNsYXNzIEtleU1hbmFnZXJGYWN0b3J5IHsKKyAgICAvLyBTdG9yZSBLZXlNYW5hZ2VyRmFjdG9yeSBzZXJ2aWNlIG5hbWUKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VSVklDRSA9ICJLZXlNYW5hZ2VyRmFjdG9yeSI7CisKKyAgICAvLyBVc2VkIHRvIGFjY2VzcyBjb21tb24gZW5naW5lIGZ1bmN0aW9uYWxpdHkKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFbmdpbmUgRU5HSU5FID0gbmV3IEVuZ2luZShTRVJWSUNFKTsKKworICAgIC8vIFN0b3JlIGRlZmF1bHQgcHJvcGVydHkgbmFtZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QRVJUWV9OQU1FID0gInNzbC5LZXlNYW5hZ2VyRmFjdG9yeS5hbGdvcml0aG0iOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBrZXkgbWFuYWdlciBmYWN0b3J5IGFsZ29yaXRobSBuYW1lLgorICAgICAqIDxwPgorICAgICAqIFRoZSBkZWZhdWx0IGFsZ29yaXRobSBuYW1lIGlzIHNwZWNpZmllZCBieSB0aGUgc2VjdXJpdHkgcHJvcGVydHk6CisgICAgICoge0Bjb2RlICdzc2wuS2V5TWFuYWdlckZhY3RvcnkuYWxnb3JpdGhtJ30uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkZWZhdWx0IGFsZ29yaXRobSBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGdldERlZmF1bHRBbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiBTZWN1cml0eS5nZXRQcm9wZXJ0eShQUk9QRVJUWV9OQU1FKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBLZXlNYW5hZ2VyRmFjdG9yeX0gaW5zdGFuY2UgZm9yIHRoZSBzcGVjaWZpZWQga2V5CisgICAgICogbWFuYWdlbWVudCBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcmVxdWVzdGVkIGtleSBtYW5hZ2VtZW50IGFsZ29yaXRobS4KKyAgICAgKiBAcmV0dXJuIGEga2V5IG1hbmFnZXIgZmFjdG9yeSBmb3IgdGhlIHJlcXVlc3RlZCBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBpbnN0YWxsZWQgcHJvdmlkZXIgY2FuIHByb3ZpZGUgdGhlIHJlcXVlc3RlZCBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhbGdvcml0aG19IGlzIHtAY29kZSBudWxsfSAoaW5zdGVhZCBvZgorICAgICAqICAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBhcyBpbiAxLjQgcmVsZWFzZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEtleU1hbmFnZXJGYWN0b3J5IGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFsZ29yaXRobSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgRW5naW5lLlNwaUFuZFByb3ZpZGVyIHNhcCA9IEVOR0lORS5nZXRJbnN0YW5jZShhbGdvcml0aG0sIG51bGwpOworICAgICAgICByZXR1cm4gbmV3IEtleU1hbmFnZXJGYWN0b3J5KChLZXlNYW5hZ2VyRmFjdG9yeVNwaSkgc2FwLnNwaSwgc2FwLnByb3ZpZGVyLCBhbGdvcml0aG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEtleU1hbmFnZXJGYWN0b3J5fSBpbnN0YW5jZSBmb3IgdGhlIHNwZWNpZmllZCBrZXkKKyAgICAgKiBtYW5hZ2VtZW50IGFsZ29yaXRobSBmcm9tIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcmVxdWVzdGVkIGtleSBtYW5hZ2VtZW50IGFsZ29yaXRobSBuYW1lLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIHRoYXQgcHJvdmlkZXMgdGhlIHJlcXVlc3RlZAorICAgICAqICAgICAgICAgICAgYWxnb3JpdGhtLgorICAgICAqIEByZXR1cm4gYSBrZXkgbWFuYWdlciBmYWN0b3J5IGZvciB0aGUgcmVxdWVzdGVkIGFsZ29yaXRobS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgY2Fubm90IHByb3ZpZGUgdGhlIHJlcXVlc3RlZAorICAgICAqICAgICAgICAgICAgIGFsZ29yaXRobS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBkb2VzIG5vdCBleGlzdC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFsZ29yaXRobX0gaXMge0Bjb2RlIG51bGx9IChpbnN0ZWFkIG9mCisgICAgICogICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGFzIGluIDEuNCByZWxlYXNlKQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgS2V5TWFuYWdlckZhY3RvcnkgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAoKHByb3ZpZGVyID09IG51bGwpIHx8IChwcm92aWRlci5sZW5ndGgoKSA9PSAwKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiUHJvdmlkZXIgaXMgbnVsbCBvciBlbXB0eSIpOworICAgICAgICB9CisgICAgICAgIFByb3ZpZGVyIGltcFByb3ZpZGVyID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXIocHJvdmlkZXIpOworICAgICAgICBpZiAoaW1wUHJvdmlkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uKHByb3ZpZGVyKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBpbXBQcm92aWRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgS2V5TWFuYWdlckZhY3Rvcnl9IGluc3RhbmNlIGZvciB0aGUgc3BlY2lmaWVkIGtleQorICAgICAqIG1hbmFnZW1lbnQgYWxnb3JpdGhtIGZyb20gdGhlIHNwZWNpZmllZCBwcm92aWRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXF1ZXN0ZWQga2V5IG1hbmFnZW1lbnQgYWxnb3JpdGhtIG5hbWUuCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgcHJvdmlkZXIgdGhhdCBwcm92aWRlcyB0aGUgcmVxdWVzdGVkIGFsZ29yaXRobS4KKyAgICAgKiBAcmV0dXJuIGEga2V5IG1hbmFnZXIgZmFjdG9yeSBmb3IgdGhlIHJlcXVlc3RlZCBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGNhbm5vdCBwcm92aWRlIHRoZSByZXF1ZXN0ZWQKKyAgICAgKiAgICAgICAgICAgICBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhbGdvcml0aG19IGlzIHtAY29kZSBudWxsfSAoaW5zdGVhZCBvZgorICAgICAqICAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBhcyBpbiAxLjQgcmVsZWFzZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEtleU1hbmFnZXJGYWN0b3J5IGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwcm92aWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQcm92aWRlciBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFsZ29yaXRobSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgT2JqZWN0IHNwaSA9IEVOR0lORS5nZXRJbnN0YW5jZShhbGdvcml0aG0sIHByb3ZpZGVyLCBudWxsKTsKKyAgICAgICAgcmV0dXJuIG5ldyBLZXlNYW5hZ2VyRmFjdG9yeSgoS2V5TWFuYWdlckZhY3RvcnlTcGkpIHNwaSwgcHJvdmlkZXIsIGFsZ29yaXRobSk7CisgICAgfQorCisgICAgLy8gU3RvcmUgdXNlZCBwcm92aWRlcgorICAgIHByaXZhdGUgZmluYWwgUHJvdmlkZXIgcHJvdmlkZXI7CisKKyAgICAvLyBTdG9yZSB1c2VkIEtleU1hbmFnZXJGYWN0b3J5U3BpIGltcGxlbWVudGF0aW9uCisgICAgcHJpdmF0ZSBmaW5hbCBLZXlNYW5hZ2VyRmFjdG9yeVNwaSBzcGlJbXBsOworCisgICAgLy8gU3RvcmUgdXNlZCBhbGdvcml0aG0KKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBhbGdvcml0aG07CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBLZXlNYW5hZ2VyRmFjdG9yeX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmFjdG9yeVNwaQorICAgICAqICAgICAgICAgICAgdGhlIGltcGxlbWVudGF0aW9uIGRlbGVnYXRlLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHByb3ZpZGVyLgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgbWFuYWdlbWVudCBhbGdvcml0aG0gbmFtZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgS2V5TWFuYWdlckZhY3RvcnkoS2V5TWFuYWdlckZhY3RvcnlTcGkgZmFjdG9yeVNwaSwgUHJvdmlkZXIgcHJvdmlkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgdGhpcy5wcm92aWRlciA9IHByb3ZpZGVyOworICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICAgICAgdGhpcy5zcGlJbXBsID0gZmFjdG9yeVNwaTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBrZXkgbWFuYWdlbWVudCBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBrZXkgbWFuYWdlbWVudCBhbGdvcml0aG0uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiBhbGdvcml0aG07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJvdmlkZXIgZm9yIHRoaXMge0Bjb2RlIEtleU1hbmFnZXJGYWN0b3J5fSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByb3ZpZGVyIGZvciB0aGlzIHtAY29kZSBLZXlNYW5hZ2VyRmFjdG9yeX0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFByb3ZpZGVyIGdldFByb3ZpZGVyKCkgeworICAgICAgICByZXR1cm4gcHJvdmlkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IHN0b3JlIGFuZCBwYXNzd29yZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrcworICAgICAqICAgICAgICAgICAgdGhlIGtleSBzdG9yZSBvciB7QGNvZGUgbnVsbH0gdG8gdXNlIHRoZSBkZWZhdWx0IGtleSBzdG9yZS4KKyAgICAgKiBAcGFyYW0gcGFzc3dvcmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXNzd29yZCBmb3IgdGhlIHNwZWNpZmllZCBrZXkgc3RvcmUgb3Ige0Bjb2RlIG51bGx9IGlmIG5vCisgICAgICogICAgICAgICAgICBrZXkgc3RvcmUgaXMgcHJvdmlkZWQuCisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGluaXRpYWxpemluZyB0aGlzIGtleSBtYW5hZ2VyIGZhY3RvcnkgZmFpbHMuCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHJlcXVpcmVkIGFsZ29yaXRobSBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEga2V5IGNhbm5vdCBiZSByZWNvdmVyZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdChLZXlTdG9yZSBrcywgY2hhcltdIHBhc3N3b3JkKSB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24geworICAgICAgICBzcGlJbXBsLmVuZ2luZUluaXQoa3MsIHBhc3N3b3JkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBmYWN0b3J5IHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3BlYworICAgICAqICAgICAgICAgICAgdGhlIGZhY3RvcnkgcGFyYW1ldGVycy4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdChNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMgc3BlYykKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgc3BpSW1wbC5lbmdpbmVJbml0KHNwZWMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGtleSBtYW5hZ2Vycywgb25lIGluc3RhbmNlIGZvciBlYWNoIHR5cGUgb2Yga2V5IGluIHRoZQorICAgICAqIGtleSBzdG9yZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBsaXN0IG9mIGtleSBtYW5hZ2Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgS2V5TWFuYWdlcltdIGdldEtleU1hbmFnZXJzKCkgeworICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVHZXRLZXlNYW5hZ2VycygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0tleU1hbmFnZXJGYWN0b3J5U3BpLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9LZXlNYW5hZ2VyRmFjdG9yeVNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1NmM5OWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9LZXlNYW5hZ2VyRmFjdG9yeVNwaS5qYXZhCkBAIC0wLDAgKzEsNzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5VbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uOworCisvKioKKyAqIFRoZSA8aT5TZXJ2aWNlIFByb3ZpZGVyIEludGVyZmFjZTwvaT4gKFNQSSkgZm9yIHRoZQorICoge0Bjb2RlIEtleU1hbmFnZXJGYWN0b3J5fSBjbGFzcy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEtleU1hbmFnZXJGYWN0b3J5U3BpIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEtleU1hbmFnZXJGYWN0b3J5U3BpfSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgS2V5TWFuYWdlckZhY3RvcnlTcGkoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IHN0b3JlIGFuZCBwYXNzd29yZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrcworICAgICAqICAgICAgICAgICAgdGhlIGtleSBzdG9yZSBvciB7QGNvZGUgbnVsbH0gdG8gdXNlIHRoZSBkZWZhdWx0IGtleSBzdG9yZS4KKyAgICAgKiBAcGFyYW0gcGFzc3dvcmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgc3RvcmUgcGFzc3dvcmQuCisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGluaXRpYWxpemluZyB0aGlzIGluc3RhbmNlIGZhaWxzLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSByZXF1aXJlZCBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgKiBAdGhyb3dzIFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIGtleSBjYW5ub3QgYmUgcmVjb3ZlcmVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGVuZ2luZUluaXQoS2V5U3RvcmUga3MsIGNoYXJbXSBwYXNzd29yZCkgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgZmFjdG9yeSBwYXJhbWV0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIHNwZWMKKyAgICAgKiAgICAgICAgICAgIHRoZSBmYWN0b3J5IHBhcmFtZXRlcnMuCisgICAgICogQHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGVuZ2luZUluaXQoTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzIHNwZWMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGtleSBtYW5hZ2Vycywgb25lIGluc3RhbmNlIGZvciBlYWNoIHR5cGUgb2Yga2V5IGluIHRoZQorICAgICAqIGtleSBzdG9yZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBsaXN0IG9mIGtleSBtYW5hZ2Vycy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgS2V5TWFuYWdlcltdIGVuZ2luZUdldEtleU1hbmFnZXJzKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9LZXlTdG9yZUJ1aWxkZXJQYXJhbWV0ZXJzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9LZXlTdG9yZUJ1aWxkZXJQYXJhbWV0ZXJzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2QzYzFmYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL0tleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMuamF2YQpAQCAtMCwwICsxLDc4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIFRoZSBwYXJhbWV0ZXJzIGZvciB7QGNvZGUgS2V5TWFuYWdlcn1zLiBUaGUgcGFyYW1ldGVycyBhcmUgYSBsaXN0IG9mCisgKiB7QGNvZGUgS2V5U3RvcmUuQnVpbGRlcn1zLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqIEBzZWUgS2V5U3RvcmUuQnVpbGRlcgorICovCitwdWJsaWMgY2xhc3MgS2V5U3RvcmVCdWlsZGVyUGFyYW1ldGVycyBpbXBsZW1lbnRzIE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyB7CisKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8S2V5U3RvcmUuQnVpbGRlcj4ga3NidWlsZGVyczsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIEtleVN0b3JlQnVpbGRlclBhcmFtZXRlcnN9IHdpdGggdGhlIHNwZWNpZmllZCBrZXkKKyAgICAgKiBzdG9yZSBidWlsZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1aWxkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgc3RvcmUgYnVpbGRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgS2V5U3RvcmVCdWlsZGVyUGFyYW1ldGVycyhLZXlTdG9yZS5CdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICAgICAgaWYgKGJ1aWxkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJidWlsZGVyID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBrc2J1aWxkZXJzID0gQ29sbGVjdGlvbnMuc2luZ2xldG9uTGlzdChidWlsZGVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBLZXlTdG9yZUJ1aWxkZXJQYXJhbWV0ZXJzfSB3aXRoIHRoZSBzcGVjaWZpZWQgbGlzdAorICAgICAqIG9mIHtAY29kZSBLZXlTdG9yZS5CdWlsZGVyfXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVycworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2Yga2V5IHN0b3JlIGJ1aWxkZXJzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGxpc3QgaXMgZW1wdHkuCisgICAgICovCisgICAgcHVibGljIEtleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMoTGlzdDxLZXlTdG9yZS5CdWlsZGVyPiBwYXJhbWV0ZXJzKSB7CisgICAgICAgIGlmIChwYXJhbWV0ZXJzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicGFyYW1ldGVycyA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBhcmFtZXRlcnMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJwYXJhbWV0ZXJzLmlzRW1wdHkoKSIpOworICAgICAgICB9CisgICAgICAgIGtzYnVpbGRlcnMgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KG5ldyBBcnJheUxpc3Q8S2V5U3RvcmUuQnVpbGRlcj4ocGFyYW1ldGVycykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHVubW9kaWZpYWJsZSBsaXN0IG9mIHtAY29kZSBLZXlTdG9yZS5CdWlsZGVyfXMgYXNzb2NpYXRlZAorICAgICAqIHdpdGggdGhpcyBwYXJhbWV0ZXJzIGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdW5tb2RpZmlhYmxlIGxpc3Qgb2Yge0Bjb2RlIEtleVN0b3JlLkJ1aWxkZXJ9cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxLZXlTdG9yZS5CdWlsZGVyPiBnZXRQYXJhbWV0ZXJzKCkgeworICAgICAgICByZXR1cm4ga3NidWlsZGVyczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9NYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL01hbmFnZXJGYWN0b3J5UGFyYW1ldGVycy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI5MGRlZWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9NYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMuamF2YQpAQCAtMCwwICsxLDI3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldC5zc2w7CisKKy8qKgorICogVGhlIG1hcmtlciBpbnRlcmZhY2UgZm9yIGtleSBtYW5hZ2VyIGZhY3RvcnkgcGFyYW1ldGVycy4gSXRzIHB1cnBvc2UgaXMgdG8KKyAqIGdyb3VwIGtleSBtYW5hZ2VyIGZhY3RvcnkgcGFyYW1ldGVycyBvYmplY3RzLgorICoKKyAqIEBzaW5jZSAxLjQKKyAqLworcHVibGljIGludGVyZmFjZSBNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMgeworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvU1NMQ29udGV4dC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvU1NMQ29udGV4dC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkwOTdiYjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xDb250ZXh0LmphdmEKQEAgLTAsMCArMSwzMTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5TWFuYWdlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuZm9ydHJlc3MuRW5naW5lOworCisKKy8qKgorICogVGhlIHB1YmxpYyBBUEkgZm9yIHNlY3VyZSBzb2NrZXQgcHJvdG9jb2wgaW1wbGVtZW50YXRpb25zLiBJdCBhY3RzIGFzIGZhY3RvcnkKKyAqIGZvciB7QGNvZGUgU1NMU29ja2V0RmFjdG9yeX0ncyBhbmQge0Bjb2RlIFNTTEVuZ2luZX1zLgorICovCitwdWJsaWMgY2xhc3MgU1NMQ29udGV4dCB7CisgICAgLy8gU3RvcmVTU0xDb250ZXh0IHNlcnZpY2UgbmFtZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRVJWSUNFID0gIlNTTENvbnRleHQiOworCisgICAgLy8gVXNlZCB0byBhY2Nlc3MgY29tbW9uIGVuZ2luZSBmdW5jdGlvbmFsaXR5CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRW5naW5lIEVOR0lORSA9IG5ldyBFbmdpbmUoU0VSVklDRSk7CisKKyAgICAvKioKKyAgICAgKiBEZWZhdWx0IFNTTENvbnRleHQgdGhhdCBjYW4gYmUgcmVwbGFjZWQgd2l0aCBTU0xDb250ZXh0LnNldERlZmF1bHQoKQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFNTTENvbnRleHQgREVGQVVMVDsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgU1NMQ29udGV4dC4KKyAgICAgKgorICAgICAqIFRoZSBkZWZhdWx0IFNTTCBjb250ZXh0IGNhbiBiZSBzZXQgd2l0aCB7QGxpbmsgI3NldERlZmF1bHR9LiBJZgorICAgICAqIG5vdCwgb25lIHdpbGwgYmUgY3JlYXRlZCB3aXRoIHtAY29kZQorICAgICAqIFNTTENvbnRleHQuZ2V0SW5zdGFuY2UoIkRlZmF1bHQiKX0sIHdoaWNoIHdpbGwgYWxyZWFkeSBiZQorICAgICAqIGluaXRpYWxpemVkLgorICAgICAqCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBwcm9ibGVtIGNyZWF0aW5nCisgICAgICogdGhlIGRlZmF1bHQgaW5zdGFuY2UuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU1NMQ29udGV4dCBnZXREZWZhdWx0KCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAoRU5HSU5FKSB7CisgICAgICAgICAgICBpZiAoREVGQVVMVCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgREVGQVVMVCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UoIkRlZmF1bHQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBERUZBVUxUOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGVmYXVsdCBTU0xDb250ZXh0IGluc3RhbmNlIGFzIHJldHVybmVkIGJ5IHtAbGluaworICAgICAqICNnZXREZWZhdWx0KCl9IHRvIGEgbm9uLW51bGwgaW5pdGlhbGl6ZWQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIG9uIGEgbnVsbCBhcmd1bWVudAorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0RGVmYXVsdChTU0xDb250ZXh0IHNzbENvbnRleHQpIHsKKyAgICAgICAgaWYgKHNzbENvbnRleHQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJzc2xDb250ZXh0ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBzeW5jaHJvbml6ZWQgKEVOR0lORSkgeworICAgICAgICAgICAgREVGQVVMVCA9IHNzbENvbnRleHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBTU0xDb250ZXh0fSBpbnN0YW5jZSBmb3IgdGhlIHNwZWNpZmllZCBwcm90b2NvbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcm90b2NvbAorICAgICAqICAgICAgICAgICAgdGhlIHJlcXVlc3RlZCBwcm90b2NvbCB0byBjcmVhdGUgYSBjb250ZXh0IGZvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBjcmVhdGVkIHtAY29kZSBTU0xDb250ZXh0fSBpbnN0YW5jZS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG5vIGluc3RhbGxlZCBwcm92aWRlciBjYW4gcHJvdmlkZSB0aGUgcmVxdWVzdGVkIHByb3RvY29sCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBwcm90b2NvbH0gaXMge0Bjb2RlIG51bGx9IChpbnN0ZWFkIG9mCisgICAgICogICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGFzIGluIDEuNCByZWxlYXNlKQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU1NMQ29udGV4dCBnZXRJbnN0YW5jZShTdHJpbmcgcHJvdG9jb2wpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAocHJvdG9jb2wgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJwcm90b2NvbCBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgRW5naW5lLlNwaUFuZFByb3ZpZGVyIHNhcCA9IEVOR0lORS5nZXRJbnN0YW5jZShwcm90b2NvbCwgbnVsbCk7CisgICAgICAgIHJldHVybiBuZXcgU1NMQ29udGV4dCgoU1NMQ29udGV4dFNwaSkgc2FwLnNwaSwgc2FwLnByb3ZpZGVyLCBwcm90b2NvbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgU1NMQ29udGV4dH0gaW5zdGFuY2UgZm9yIHRoZSBzcGVjaWZpZWQgcHJvdG9jb2wgZnJvbQorICAgICAqIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJvdG9jb2wKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXF1ZXN0ZWQgcHJvdG9jb2wgdG8gY3JlYXRlIGEgY29udGV4dCBmb3IuCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgcHJvdmlkZXIgdGhhdCBwcm92aWRlcyB0aGUgcmVxdWVzdGVkIHByb3RvY29sLgorICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIFNTTENvbnRleHR9IGZvciB0aGUgcmVxdWVzdGVkIHByb3RvY29sLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBjYW5ub3QgcHJvdmlkZXIgdGhlIHJlcXVlc3RlZAorICAgICAqICAgICAgICAgICAgIHByb3RvY29sLgorICAgICAqIEB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGRvZXMgbm90IGV4aXRzLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgcHJvdG9jb2x9IGlzIHtAY29kZSBudWxsfSAoaW5zdGVhZCBvZgorICAgICAqICAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBhcyBpbiAxLjQgcmVsZWFzZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNTTENvbnRleHQgZ2V0SW5zdGFuY2UoU3RyaW5nIHByb3RvY29sLCBTdHJpbmcgcHJvdmlkZXIpCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwcm92aWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQcm92aWRlciBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHByb3ZpZGVyLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlByb3ZpZGVyIGlzIGVtcHR5Iik7CisgICAgICAgIH0KKyAgICAgICAgUHJvdmlkZXIgaW1wUHJvdmlkZXIgPSBTZWN1cml0eS5nZXRQcm92aWRlcihwcm92aWRlcik7CisgICAgICAgIGlmIChpbXBQcm92aWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24ocHJvdmlkZXIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRJbnN0YW5jZShwcm90b2NvbCwgaW1wUHJvdmlkZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFNTTENvbnRleHR9IGluc3RhbmNlIGZvciB0aGUgc3BlY2lmaWVkIHByb3RvY29sIGZyb20KKyAgICAgKiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHByb3RvY29sCisgICAgICogICAgICAgICAgICB0aGUgcmVxdWVzdGVkIHByb3RvY29sIHRvIGNyZWF0ZSBhIGNvbnRleHQgZm9yCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgcHJvdmlkZXIgdGhhdCBwcm92aWRlcyB0aGUgcmVxdWVzdGVkIHByb3RvY29sLgorICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIFNTTENvbnRleHR9IGZvciB0aGUgcmVxdWVzdGVkIHByb3RvY29sLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBjYW5ub3QgcHJvdmlkZSB0aGUgcmVxdWVzdGVkCisgICAgICogICAgICAgICAgICAgcHJvdG9jb2wuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBwcm90b2NvbH0gaXMge0Bjb2RlIG51bGx9IChpbnN0ZWFkIG9mCisgICAgICogICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGFzIGluIDEuNCByZWxlYXNlKQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU1NMQ29udGV4dCBnZXRJbnN0YW5jZShTdHJpbmcgcHJvdG9jb2wsIFByb3ZpZGVyIHByb3ZpZGVyKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwcm92aWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJwcm92aWRlciBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHByb3RvY29sID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicHJvdG9jb2wgaXMgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIE9iamVjdCBzcGkgPSBFTkdJTkUuZ2V0SW5zdGFuY2UocHJvdG9jb2wsIHByb3ZpZGVyLCBudWxsKTsKKyAgICAgICAgcmV0dXJuIG5ldyBTU0xDb250ZXh0KChTU0xDb250ZXh0U3BpKSBzcGksIHByb3ZpZGVyLCBwcm90b2NvbCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBQcm92aWRlciBwcm92aWRlcjsKKworICAgIHByaXZhdGUgZmluYWwgU1NMQ29udGV4dFNwaSBzcGlJbXBsOworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcHJvdG9jb2w7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBTU0xDb250ZXh0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb250ZXh0U3BpCisgICAgICogICAgICAgICAgICB0aGUgaW1wbGVtZW50YXRpb24gZGVsZWdhdGUuCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgcHJvdmlkZXIuCisgICAgICogQHBhcmFtIHByb3RvY29sCisgICAgICogICAgICAgICAgICB0aGUgcHJvdG9jb2wgbmFtZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU1NMQ29udGV4dChTU0xDb250ZXh0U3BpIGNvbnRleHRTcGksIFByb3ZpZGVyIHByb3ZpZGVyLCBTdHJpbmcgcHJvdG9jb2wpIHsKKyAgICAgICAgdGhpcy5wcm92aWRlciA9IHByb3ZpZGVyOworICAgICAgICB0aGlzLnByb3RvY29sID0gcHJvdG9jb2w7CisgICAgICAgIHRoaXMuc3BpSW1wbCA9IGNvbnRleHRTcGk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgc2VjdXJlIHNvY2tldCBwcm90b2NvbCBvZiB0aGlzIGluc3RhbmNlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgc2VjdXJlIHNvY2tldCBwcm90b2NvbCBvZiB0aGlzIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0UHJvdG9jb2woKSB7CisgICAgICAgIHJldHVybiBwcm90b2NvbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcm92aWRlciBvZiB0aGlzIHtAY29kZSBTU0xDb250ZXh0fSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByb3ZpZGVyIG9mIHRoaXMge0Bjb2RlIFNTTENvbnRleHR9IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBQcm92aWRlciBnZXRQcm92aWRlcigpIHsKKyAgICAgICAgcmV0dXJuIHByb3ZpZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIFNTTENvbnRleHR9IGluc3RhbmNlLiBBbGwgb2YgdGhlIGFyZ3VtZW50cyBhcmUKKyAgICAgKiBvcHRpb25hbCwgYW5kIHRoZSBzZWN1cml0eSBwcm92aWRlcnMgd2lsbCBiZSBzZWFyY2hlZCBmb3IgdGhlIHJlcXVpcmVkCisgICAgICogaW1wbGVtZW50YXRpb25zIG9mIHRoZSBuZWVkZWQgYWxnb3JpdGhtcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrbQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBzb3VyY2VzIG9yIHtAY29kZSBudWxsfS4KKyAgICAgKiBAcGFyYW0gdG0KKyAgICAgKiAgICAgICAgICAgIHRoZSB0cnVzdCBkZWNpc2lvbiBzb3VyY2VzIG9yIHtAY29kZSBudWxsfS4KKyAgICAgKiBAcGFyYW0gc3IKKyAgICAgKiAgICAgICAgICAgIHRoZSByYW5kb21uZXNzIHNvdXJjZSBvciB7QGNvZGUgbnVsbC59CisgICAgICogQHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgaW5pdGlhbGl6aW5nIHRoaXMgaW5zdGFuY2UgZmFpbHMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdChLZXlNYW5hZ2VyW10ga20sIFRydXN0TWFuYWdlcltdIHRtLCBTZWN1cmVSYW5kb20gc3IpCisgICAgICAgICAgICB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiB7CisgICAgICAgIHNwaUltcGwuZW5naW5lSW5pdChrbSwgdG0sIHNyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc29ja2V0IGZhY3RvcnkgZm9yIHRoaXMgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc29ja2V0IGZhY3RvcnkgZm9yIHRoaXMgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFNTTFNvY2tldEZhY3RvcnkgZ2V0U29ja2V0RmFjdG9yeSgpIHsKKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lR2V0U29ja2V0RmFjdG9yeSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzZXJ2ZXIgc29ja2V0IGZhY3RvcnkgZm9yIHRoaXMgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc2VydmVyIHNvY2tldCBmYWN0b3J5IGZvciB0aGlzIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5IGdldFNlcnZlclNvY2tldEZhY3RvcnkoKSB7CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZUdldFNlcnZlclNvY2tldEZhY3RvcnkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIHtAY29kZSBTU0xFbmdpbmV9IGluc3RhbmNlIGZyb20gdGhpcyBjb250ZXh0LgorICAgICAqCisgICAgICogQHJldHVybiBhbiB7QGNvZGUgU1NMRW5naW5lfSBpbnN0YW5jZSBmcm9tIHRoaXMgY29udGV4dC4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHByb3ZpZGVyIGRvZXMgbm90IHN1cHBvcnQgdGhlIG9wZXJhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU1NMRW5naW5lIGNyZWF0ZVNTTEVuZ2luZSgpIHsKKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lQ3JlYXRlU1NMRW5naW5lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiB7QGNvZGUgU1NMRW5naW5lfSBpbnN0YW5jZSBmcm9tIHRoaXMgY29udGV4dCB3aXRoIHRoZQorICAgICAqIHNwZWNpZmllZCBob3N0bmFtZSBhbmQgcG9ydC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwZWVySG9zdAorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGhvc3QKKyAgICAgKiBAcGFyYW0gcGVlclBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0CisgICAgICogQHJldHVybiBhbiB7QGNvZGUgU1NMRW5naW5lfSBpbnN0YW5jZSBmcm9tIHRoaXMgY29udGV4dC4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHByb3ZpZGVyIGRvZXMgbm90IHN1cHBvcnQgdGhlIG9wZXJhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU1NMRW5naW5lIGNyZWF0ZVNTTEVuZ2luZShTdHJpbmcgcGVlckhvc3QsIGludCBwZWVyUG9ydCkgeworICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVDcmVhdGVTU0xFbmdpbmUocGVlckhvc3QsIHBlZXJQb3J0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBTU0wgc2Vzc2lvbiBjb250ZXh0IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSBzZXQgb2YgU1NMIHNlc3Npb25zCisgICAgICogdGhhdCBjYW4gYmUgdXNlZCBmb3IgaGFuZHNoYWtlIG9mIHNlcnZlci1zaWRlIFNTTCBzb2NrZXRzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgU1NMIHNlcnZlciBzZXNzaW9uIGNvbnRleHQgZm9yIHRoaXMgY29udGV4dCBvciB7QGNvZGUgbnVsbH0KKyAgICAgKiAgICAgICAgIGlmIHRoZSB1bmRlcmx5aW5nIHByb3ZpZGVyIGRvZXMgbm90IHByb3ZpZGUgYW4gaW1wbGVtZW50YXRpb24gb2YKKyAgICAgKiAgICAgICAgIHRoZSB7QGNvZGUgU1NMU2Vzc2lvbkNvbnRleHR9IGludGVyZmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU1NMU2Vzc2lvbkNvbnRleHQgZ2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKSB7CisgICAgICAgIHJldHVybiBzcGlJbXBsLmVuZ2luZUdldFNlcnZlclNlc3Npb25Db250ZXh0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgU1NMIHNlc3Npb24gY29udGV4dCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgc2V0IG9mIFNTTCBzZXNzaW9ucworICAgICAqIHRoYXQgY2FuIGJlIHVzZWQgZm9yIGhhbmRzaGFrZSBvZiBjbGllbnQtc2lkZSBTU0wgc29ja2V0cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIFNTTCBjbGllbnQgc2Vzc2lvbiBjb250ZXh0IGZvciB0aGlzIGNvbnRleHQgb3Ige0Bjb2RlIG51bGx9CisgICAgICogICAgICAgICBpZiB0aGUgdW5kZXJseWluZyBwcm92aWRlciBkb2VzIG5vdCBwcm92aWRlIGFuIGltcGxlbWVudGF0aW9uIG9mCisgICAgICogICAgICAgICB0aGUge0Bjb2RlIFNTTFNlc3Npb25Db250ZXh0fSBpbnRlcmZhY2UuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFNTTFNlc3Npb25Db250ZXh0IGdldENsaWVudFNlc3Npb25Db250ZXh0KCkgeworICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVHZXRDbGllbnRTZXNzaW9uQ29udGV4dCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgU1NMIGhhbmRzaGFrZSBwYXJhbWV0ZXJzIGZvciBTU0xTb2NrZXRzCisgICAgICogY3JlYXRlZCBieSB0aGlzIFNTTENvbnRleHQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTU0xQYXJhbWV0ZXJzIGdldERlZmF1bHRTU0xQYXJhbWV0ZXJzKCkgeworICAgICAgICByZXR1cm4gc3BpSW1wbC5lbmdpbmVHZXREZWZhdWx0U1NMUGFyYW1ldGVycygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgU1NMIGhhbmRzaGFrZSBwYXJhbWV0ZXJzIGZvciBTU0xTb2NrZXRzIHRoYXQgaW5jbHVkZXMKKyAgICAgKiBhbGwgc3VwcG9ydGVkIGNpcGhlciBzdWl0ZXMgYW5kIHByb3RvY29scy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIGZpbmFsIFNTTFBhcmFtZXRlcnMgZ2V0U3VwcG9ydGVkU1NMUGFyYW1ldGVycygpIHsKKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lR2V0U3VwcG9ydGVkU1NMUGFyYW1ldGVycygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTENvbnRleHRTcGkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTENvbnRleHRTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZTJlNzNlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvU1NMQ29udGV4dFNwaS5qYXZhCkBAIC0wLDAgKzEsMTY0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5TWFuYWdlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKKworLyoqCisgKiBUaGUgPGk+U2VydmljZSBQcm92aWRlciBJbnRlcmZhY2U8L2k+IChTUEkpIGZvciB0aGUge0Bjb2RlIFNTTENvbnRleHR9IGNsYXNzLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU1NMQ29udGV4dFNwaSB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBTU0xDb250ZXh0U3BpfSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1NMQ29udGV4dFNwaSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHtAY29kZSBTU0xDb250ZXh0fSBpbnN0YW5jZS4gQWxsIG9mIHRoZSBhcmd1bWVudHMgYXJlCisgICAgICogb3B0aW9uYWwsIGFuZCB0aGUgc2VjdXJpdHkgcHJvdmlkZXJzIHdpbGwgYmUgc2VhcmNoZWQgZm9yIHRoZSByZXF1aXJlZAorICAgICAqIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgbmVlZGVkIGFsZ29yaXRobXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga20KKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXkgc291cmNlcyBvciB7QGNvZGUgbnVsbH0uCisgICAgICogQHBhcmFtIHRtCisgICAgICogICAgICAgICAgICB0aGUgdHJ1c3QgZGVjaXNpb24gc291cmNlcyBvciB7QGNvZGUgbnVsbH0uCisgICAgICogQHBhcmFtIHNyCisgICAgICogICAgICAgICAgICB0aGUgcmFuZG9tbmVzcyBzb3VyY2Ugb3Ige0Bjb2RlIG51bGwufQorICAgICAqIEB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGluaXRpYWxpemluZyB0aGlzIGluc3RhbmNlIGZhaWxzLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGVuZ2luZUluaXQoS2V5TWFuYWdlcltdIGttLCBUcnVzdE1hbmFnZXJbXSB0bSwgU2VjdXJlUmFuZG9tIHNyKQorICAgICAgICAgICAgdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc29ja2V0IGZhY3RvcnkgZm9yIHRoaXMgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgc29ja2V0IGZhY3RvcnkgZm9yIHRoaXMgaW5zdGFuY2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IFNTTFNvY2tldEZhY3RvcnkgZW5naW5lR2V0U29ja2V0RmFjdG9yeSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNlcnZlciBzb2NrZXQgZmFjdG9yeSBmb3IgdGhpcyBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzZXJ2ZXIgc29ja2V0IGZhY3RvcnkgZm9yIHRoaXMgaW5zdGFuY2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IFNTTFNlcnZlclNvY2tldEZhY3RvcnkgZW5naW5lR2V0U2VydmVyU29ja2V0RmFjdG9yeSgpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiB7QGNvZGUgU1NMRW5naW5lfSBpbnN0YW5jZSBmcm9tIHRoaXMgY29udGV4dCB3aXRoIHRoZQorICAgICAqIHNwZWNpZmllZCBob3N0bmFtZSBhbmQgcG9ydC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3N0CisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgaG9zdAorICAgICAqIEBwYXJhbSBwb3J0CisgICAgICogICAgICAgICAgICB0aGUgcG9ydAorICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIFNTTEVuZ2luZX0gaW5zdGFuY2UgZnJvbSB0aGlzIGNvbnRleHQuCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBwcm92aWRlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSBvcGVyYXRpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IFNTTEVuZ2luZSBlbmdpbmVDcmVhdGVTU0xFbmdpbmUoU3RyaW5nIGhvc3QsIGludCBwb3J0KTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4ge0Bjb2RlIFNTTEVuZ2luZX0gaW5zdGFuY2UgZnJvbSB0aGlzIGNvbnRleHQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBTU0xFbmdpbmV9IGluc3RhbmNlIGZyb20gdGhpcyBjb250ZXh0LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcHJvdmlkZXIgZG9lcyBub3Qgc3VwcG9ydCB0aGUgb3BlcmF0aW9uLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBTU0xFbmdpbmUgZW5naW5lQ3JlYXRlU1NMRW5naW5lKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBTU0wgc2Vzc2lvbiBjb250ZXh0IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSBzZXQgb2YgU1NMIHNlc3Npb25zCisgICAgICogdGhhdCBjYW4gYmUgdXNlZCBmb3IgdGhlIHNlcnZlciBzaWRlIG9mIHRoZSBTU0wgaGFuZHNoYWtlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgU1NMIHNlcnZlciBzZXNzaW9uIGNvbnRleHQgZm9yIHRoaXMgY29udGV4dCBvciB7QGNvZGUgbnVsbH0KKyAgICAgKiAgICAgICAgIGlmIHRoZSB1bmRlcmx5aW5nIHByb3ZpZGVyIGRvZXMgbm90IHByb3ZpZGUgYW4gaW1wbGVtZW50YXRpb24gb2YKKyAgICAgKiAgICAgICAgIHRoZSB7QGNvZGUgU1NMU2Vzc2lvbkNvbnRleHR9IGludGVyZmFjZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgU1NMU2Vzc2lvbkNvbnRleHQgZW5naW5lR2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIFNTTCBzZXNzaW9uIGNvbnRleHQgdGhhdCBlbmNhcHN1bGF0ZXMgdGhlIHNldCBvZiBTU0wgc2Vzc2lvbnMKKyAgICAgKiB0aGF0IGNhbiBiZSB1c2VkIGZvciB0aGUgY2xpZW50IHNpZGUgb2YgdGhlIFNTTCBoYW5kc2hha2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBTU0wgY2xpZW50IHNlc3Npb24gY29udGV4dCBmb3IgdGhpcyBjb250ZXh0IG9yIHtAY29kZSBudWxsfQorICAgICAqICAgICAgICAgaWYgdGhlIHVuZGVybHlpbmcgcHJvdmlkZXIgZG9lcyBub3QgcHJvdmlkZSBhbiBpbXBsZW1lbnRhdGlvbiBvZgorICAgICAqICAgICAgICAgdGhlIHtAY29kZSBTU0xTZXNzaW9uQ29udGV4dH0gaW50ZXJmYWNlLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBTU0xTZXNzaW9uQ29udGV4dCBlbmdpbmVHZXRDbGllbnRTZXNzaW9uQ29udGV4dCgpOworCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IFNTTFBhcmFtZXRlcnMgaW5zdGFuY2UgdGhhdCBpbmNsdWRlcyB0aGUgZGVmYXVsdAorICAgICAqIFNTTCBoYW5kc2hha2UgcGFyYW1ldGVycyB2YWx1ZXMgaW5jbHVkaW5nIGNpcGhlciBzdWl0ZXMsCisgICAgICogcHJvdG9jb2xzLCBhbmQgY2xpZW50IGF1dGhlbnRpY2F0aW9uLgorICAgICAqCisgICAgICogPHA+VGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcmV0dXJucyBhbiBTU0xQYXJhbWV0ZXJzIHdpdGggdmFsdWVzCisgICAgICogYmFzZWQgYW4gU1NMU29ja2V0IGNyZWF0ZWQgZnJvbSB0aGlzIGluc3RhbmNlcyBTb2NrZXRGYWN0b3J5LgorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHByb3RlY3RlZCBqYXZheC5uZXQuc3NsLlNTTFBhcmFtZXRlcnMgZW5naW5lR2V0RGVmYXVsdFNTTFBhcmFtZXRlcnMoKSB7CisgICAgICAgIHJldHVybiBjcmVhdGVTU0xQYXJhbWV0ZXJzKGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IFNTTFBhcmFtZXRlcnMgaW5zdGFuY2UgdGhhdCBpbmNsdWRlcyBhbGwKKyAgICAgKiBzdXBwb3J0ZWQgY2lwaGVyIHN1aXRlcyBhbmQgcHJvdG9jb2xzLgorICAgICAqCisgICAgICogPHA+VGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcmV0dXJucyBhbiBTU0xQYXJhbWV0ZXJzIHdpdGggdmFsdWVzCisgICAgICogYmFzZWQgYW4gU1NMU29ja2V0IGNyZWF0ZWQgZnJvbSB0aGlzIGluc3RhbmNlcyBTb2NrZXRGYWN0b3J5LgorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHByb3RlY3RlZCBqYXZheC5uZXQuc3NsLlNTTFBhcmFtZXRlcnMgZW5naW5lR2V0U3VwcG9ydGVkU1NMUGFyYW1ldGVycygpIHsKKyAgICAgICAgcmV0dXJuIGNyZWF0ZVNTTFBhcmFtZXRlcnModHJ1ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBqYXZheC5uZXQuc3NsLlNTTFBhcmFtZXRlcnMgY3JlYXRlU1NMUGFyYW1ldGVycyhib29sZWFuIHN1cHBvcnRlZCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMU29ja2V0IHMgPSAoU1NMU29ja2V0KSBlbmdpbmVHZXRTb2NrZXRGYWN0b3J5KCkuY3JlYXRlU29ja2V0KCk7CisgICAgICAgICAgICBqYXZheC5uZXQuc3NsLlNTTFBhcmFtZXRlcnMgcCA9IG5ldyBqYXZheC5uZXQuc3NsLlNTTFBhcmFtZXRlcnMoKTsKKyAgICAgICAgICAgIFN0cmluZ1tdIGNpcGhlclN1aXRlczsKKyAgICAgICAgICAgIFN0cmluZ1tdIHByb3RvY29sczsKKyAgICAgICAgICAgIGlmIChzdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgICAgICBjaXBoZXJTdWl0ZXMgPSBzLmdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpOworICAgICAgICAgICAgICAgIHByb3RvY29scyA9IHMuZ2V0U3VwcG9ydGVkUHJvdG9jb2xzKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGNpcGhlclN1aXRlcyA9IHMuZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpOworICAgICAgICAgICAgICAgIHByb3RvY29scyA9IHMuZ2V0RW5hYmxlZFByb3RvY29scygpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcC5zZXRDaXBoZXJTdWl0ZXMoY2lwaGVyU3VpdGVzKTsKKyAgICAgICAgICAgIHAuc2V0UHJvdG9jb2xzKHByb3RvY29scyk7CisgICAgICAgICAgICBwLnNldE5lZWRDbGllbnRBdXRoKHMuZ2V0TmVlZENsaWVudEF1dGgoKSk7CisgICAgICAgICAgICBwLnNldFdhbnRDbGllbnRBdXRoKHMuZ2V0V2FudENsaWVudEF1dGgoKSk7CisgICAgICAgICAgICByZXR1cm4gcDsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFNTTENvbnRleHQuZ2V0RGVmYXVsdFNTTFBhcmFtZXRlcnMgc3BlY2lmaWVzIHRvIHRocm93CisgICAgICAgICAgICAgKiBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHByb2JsZW0gZ2V0dGluZyB0aGUKKyAgICAgICAgICAgICAqIHBhcmFtZXRlcnMKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJDb3VsZCBub3QgYWNjZXNzIHN1cHBvcnRlZCBTU0wgcGFyYW1ldGVycyIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvU1NMRW5naW5lLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xFbmdpbmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNmM5OTQ2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvU1NMRW5naW5lLmphdmEKQEAgLTAsMCArMSw1MDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CisKKy8qKgorICogVGhlIGFic3RyYWN0IGltcGxlbWVudGF0aW9uIG9mIHNlY3VyZSBjb21tdW5pY2F0aW9ucyB1c2luZyBTU0wsIFRMUywgb3Igb3RoZXIKKyAqIHByb3RvY29scy4gSXQgaW5jbHVkZXMgdGhlIHNldHVwLCBoYW5kc2hha2UsIGFuZCBlbmNyeXB0L2RlY3J5cHQKKyAqIGZ1bmN0aW9uYWxpdHkgbmVlZGVkIHRvIGNyZWF0ZSBhIHNlY3VyZSBjb25uZWN0aW9uLgorICoKKyAqIEBzaW5jZSAxLjUKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFNTTEVuZ2luZSB7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcGVlckhvc3Q7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgcGVlclBvcnQ7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBTU0xFbmdpbmV9IGluc3RhbmNlLgorICAgICAqLworICAgIHByb3RlY3RlZCBTU0xFbmdpbmUoKSB7CisgICAgICAgIHBlZXJIb3N0ID0gbnVsbDsKKyAgICAgICAgcGVlclBvcnQgPSAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBTU0xFbmdpbmV9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBob3N0IGFuZAorICAgICAqIHBvcnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaG9zdAorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGhvc3QuCisgICAgICogQHBhcmFtIHBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IG9mIHRoZSBob3N0LgorICAgICAqLworICAgIHByb3RlY3RlZCBTU0xFbmdpbmUoU3RyaW5nIGhvc3QsIGludCBwb3J0KSB7CisgICAgICAgIHRoaXMucGVlckhvc3QgPSBob3N0OworICAgICAgICB0aGlzLnBlZXJQb3J0ID0gcG9ydDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBwZWVyIGhvc3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBwZWVyIGhvc3QsIG9yIHtAY29kZSBudWxsfSBpZiBub25lIGlzIGF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFBlZXJIb3N0KCkgeworICAgICAgICByZXR1cm4gcGVlckhvc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcG9ydCBudW1iZXIgb2YgdGhlIHBlZXIgaG9zdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHBvcnQgbnVtYmVyIG9mIHRoZSBwZWVyIGhvc3QsIG9yIHtAY29kZSAtMX0gaXMgbm9uZSBpcworICAgICAqICAgICAgICAgYXZhaWxhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UGVlclBvcnQoKSB7CisgICAgICAgIHJldHVybiBwZWVyUG9ydDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWF0ZXMgYSBoYW5kc2hha2Ugb24gdGhpcyBlbmdpbmUuCisgICAgICogPHA+CisgICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCBpcyBub3QgbmVlZGVkIGZvciB0aGUgaW5pdGlhbCBoYW5kc2hha2U6IGl0IHdpbGwgYmUKKyAgICAgKiBjYWxsZWQgYnkge0Bjb2RlIHdyYXB9IG9yIHtAY29kZSB1bndyYXB9IGlmIHRoZSBpbml0aWFsIGhhbmRzaGFrZSBoYXMgbm90CisgICAgICogYmVlbiBzdGFydGVkIHlldC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU1NMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgc3RhcnRpbmcgdGhlIGhhbmRzaGFrZSBmYWlscy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmdpbmUgZG9lcyBub3QgaGF2ZSBhbGwgdGhlIG5lZWRlZCBzZXR0aW5ncyAoZS5nLgorICAgICAqICAgICAgICAgICAgIGNsaWVudC9zZXJ2ZXIgbW9kZSBub3Qgc2V0KS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBiZWdpbkhhbmRzaGFrZSgpIHRocm93cyBTU0xFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGlzIGVuZ2luZSBpbnN0YW5jZSB0aGF0IG5vIG1vcmUgaW5ib3VuZCBuZXR3b3JrIGRhdGEgd2lsbCBiZQorICAgICAqIHNlbnQgdG8gdGhpcyBlbmdpbmUuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNTTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoaXMgZW5naW5lIGRpZCBub3QgcmVjZWl2ZSBhIG5lZWRlZCBwcm90b2NvbCBzcGVjaWZpYworICAgICAqICAgICAgICAgICAgIGNsb3NlIG5vdGlmaWNhdGlvbiBtZXNzYWdlIGZyb20gdGhlIHBlZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgY2xvc2VJbmJvdW5kKCkgdGhyb3dzIFNTTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIE5vdGlmaWVzIHRoaXMgZW5naW5lIGluc3RhbmNlIHRoYXQgbm8gbW9yZSBvdXRib3VuZCBhcHBsaWNhdGlvbiBkYXRhIHdpbGwKKyAgICAgKiBiZSBzZW50IHRvIHRoaXMgZW5naW5lLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGNsb3NlT3V0Ym91bmQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBkZWxlZ2F0ZSB0YXNrIGZvciB0aGlzIGVuZ2luZSBpbnN0YW5jZS4gU29tZSBlbmdpbmUgb3BlcmF0aW9ucworICAgICAqIG1heSByZXF1aXJlIHRoZSByZXN1bHRzIG9mIGJsb2NraW5nIG9yIGxvbmcgcnVubmluZyBvcGVyYXRpb25zLCBhbmQgdGhlCisgICAgICoge0Bjb2RlIFNTTEVuZ2luZVJlc3VsdH0gaW5zdGFuY2VzIHJldHVybmVkIGJ5IHRoaXMgZW5naW5lIG1heSBpbmRpY2F0ZQorICAgICAqIHRoYXQgYSBkZWxlZ2F0ZWQgdGFzayByZXN1bHQgaXMgbmVlZGVkLiBJbiB0aGlzIGNhc2UgdGhlCisgICAgICoge0BsaW5rIFJ1bm5hYmxlI3J1bigpIHJ1bn0gbWV0aG9kIG9mIHRoZSByZXR1cm5lZCB7QGNvZGUgUnVubmFibGV9CisgICAgICogZGVsZWdhdGVkIHRhc2sgbXVzdCBiZSBjYWxsZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgZGVsZWdhdGUgdGFzaywgb3Ige0Bjb2RlIG51bGx9IGlmIG5vbmUgYXJlIGF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgUnVubmFibGUgZ2V0RGVsZWdhdGVkVGFzaygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgU1NMIGNpcGhlciBzdWl0ZSBuYW1lcyB0aGF0IGFyZSBlbmFibGVkIGluIHRoaXMgZW5naW5lCisgICAgICogaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBTU0wgY2lwaGVyIHN1aXRlIG5hbWVzIHRoYXQgYXJlIGVuYWJsZWQgaW4gdGhpcyBlbmdpbmUKKyAgICAgKiAgICAgICAgIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmdbXSBnZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcm90b2NvbCB2ZXJzaW9uIG5hbWVzIHRoYXQgYXJlIGVuYWJsZWQgaW4gdGhpcyBlbmdpbmUKKyAgICAgKiBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByb3RvY29sIHZlcnNpb24gbmFtZXMgdGhhdCBhcmUgZW5hYmxlZCBpbiB0aGlzIGVuZ2luZQorICAgICAqICAgICAgICAgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZ1tdIGdldEVuYWJsZWRQcm90b2NvbHMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciBuZXcgU1NMIHNlc3Npb25zIG1heSBiZSBlc3RhYmxpc2hlZCBieSB0aGlzIGVuZ2luZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIG5ldyBzZXNzaW9uIG1heSBiZSBlc3RhYmxpc2hlZCwge0Bjb2RlIGZhbHNlfSBpZgorICAgICAqICAgICAgICAgZXhpc3Rpbmcgc2Vzc2lvbnMgbXVzdCBiZSByZXVzZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdGF0dXMgb2YgdGhlIGhhbmRzaGFrZSBvZiB0aGlzIGVuZ2luZSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN0YXR1cyBvZiB0aGUgaGFuZHNoYWtlIG9mIHRoaXMgZW5naW5lIGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzIGdldEhhbmRzaGFrZVN0YXR1cygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgZW5naW5lIGluc3RhbmNlIHdpbGwgcmVxdWlyZSBjbGllbnQgYXV0aGVudGljYXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGVuZ2luZSB3aWxsIHJlcXVpcmUgY2xpZW50IGF1dGhlbnRpY2F0aW9uLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBpZiBubyBjbGllbnQgYXV0aGVudGljYXRpb24gaXMgbmVlZGVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGdldE5lZWRDbGllbnRBdXRoKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBTU0wgc2Vzc2lvbiBmb3IgdGhpcyBlbmdpbmUgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBTU0wgc2Vzc2lvbiBmb3IgdGhpcyBlbmdpbmUgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFNTTFNlc3Npb24gZ2V0U2Vzc2lvbigpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgU1NMIGNpcGhlciBzdWl0ZSBuYW1lcyB0aGF0IGFyZSBzdXBwb3J0ZWQgYnkgdGhpcyBlbmdpbmUuCisgICAgICogVGhlc2UgY2lwaGVyIHN1aXRlcyBjYW4gYmUgZW5hYmxlZCB1c2luZworICAgICAqIHtAbGluayAjc2V0RW5hYmxlZENpcGhlclN1aXRlcyhTdHJpbmdbXSl9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgU1NMIGNpcGhlciBzdWl0ZSBuYW1lcyB0aGF0IGFyZSBzdXBwb3J0ZWQgYnkgdGhpcyBlbmdpbmUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZ1tdIGdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJvdG9jb2wgbmFtZXMgdGhhdCBhcmUgc3VwcG9ydGVkIGJ5IHRoaXMgZW5naW5lLiBUaGVzZQorICAgICAqIHByb3RvY29scyBjYW4gYmUgZW5hYmxlcyB1c2luZyB7QGxpbmsgI3NldEVuYWJsZWRQcm90b2NvbHMoU3RyaW5nW10pfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByb3RvY29sIG5hbWVzIHRoYXQgYXJlIHN1cHBvcnRlZCBieSB0aGlzIGVuZ2luZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nW10gZ2V0U3VwcG9ydGVkUHJvdG9jb2xzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBlbmdpbmUgaXMgc2V0IHRvIGFjdCBpbiBjbGllbnQgbW9kZSB3aGVuCisgICAgICogaGFuZHNoYWtpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZW5naW5lIGlzIHNldCB0byBkbyBoYW5kc2hha2luZyBpbiBjbGllbnQKKyAgICAgKiAgICAgICAgIG1vZGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZ2V0VXNlQ2xpZW50TW9kZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgZW5naW5lIHdpbGwgcmVxdWVzdCBjbGllbnQgYXV0aGVudGljYXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBjbGllbnQgYXV0aGVudGljYXRpb24gd2lsbCBiZSByZXF1ZXN0ZWQsCisgICAgICogICAgICAgICB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBnZXRXYW50Q2xpZW50QXV0aCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIG5vIG1vcmUgaW5ib3VuZCBkYXRhIHdpbGwgYmUgYWNjZXB0ZWQgYnkgdGhpcyBlbmdpbmUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBubyBtb3JlIGluYm91bmQgZGF0YSB3aWxsIGJlIGFjY2VwdGVkIGJ5IHRoaXMKKyAgICAgKiAgICAgICAgIGVuZ2luZSwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNJbmJvdW5kRG9uZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIG5vIG1vcmUgb3V0Ym91bmQgZGF0YSB3aWxsIGJlIHByb2R1Y2VkIGJ5IHRoaXMgZW5naW5lLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgbm8gbW9yZSBvdXRib3VuZCBkYXRhIHdpbGwgYmUgcHJvZHVjdGVkIGJ5IHRoaXMKKyAgICAgKiAgICAgICAgIGVuZ2luZSwge0Bjb2RlIG90aGVyd2lzZX0gZmFsc2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNPdXRib3VuZERvbmUoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIFNTTCBjaXBoZXIgc3VpdGUgbmFtZXMgdGhhdCBzaG91bGQgYmUgZW5hYmxlZCBpbiB0aGlzIGVuZ2luZQorICAgICAqIGluc3RhbmNlLiBPbmx5IGNpcGhlciBzdWl0ZXMgbGlzdGVkIGJ5IHtAY29kZSBnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKX0KKyAgICAgKiBhcmUgYWxsb3dlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdWl0ZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBTU0wgY2lwaGVyIHN1aXRlIG5hbWVzIHRvIGJlIGVuYWJsZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBvbmUgb2YgdGhlIHNwZWNpZmllZCBjaXBoZXIgc3VpdGVzIGlzIG5vdCBzdXBwb3J0ZWQsIG9yIGlmCisgICAgICogICAgICAgICAgICAge0Bjb2RlIHN1aXRlc30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoU3RyaW5nW10gc3VpdGVzKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHByb3RvY29sIHZlcnNpb24gbmFtZXMgdGhhdCBzaG91bGQgYmUgZW5hYmxlZCBpbiB0aGlzIGVuZ2luZQorICAgICAqIGluc3RhbmNlLiBPbmx5IHByb3RvY29scyBsaXN0ZWQgYnkge0Bjb2RlIGdldFN1cHBvcnRlZFByb3RvY29scygpfSBhcmUKKyAgICAgKiBhbGxvd2VkLgorICAgICAqCisgICAgICogQHBhcmFtIHByb3RvY29scworICAgICAqICAgICAgICAgICAgdGhlIHByb3RvY29sIHZlcnNpb24gbmFtZXMgdG8gYmUgZW5hYmxlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG9uZSBvZiB0aGUgcHJvdG9jb2wgdmVyc2lvbiBuYW1lcyBpcyBub3Qgc3VwcG9ydGVkLCBvciBpZgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBwcm90b2NvbHN9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRFbmFibGVkUHJvdG9jb2xzKFN0cmluZ1tdIHByb3RvY29scyk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHdoZXRoZXIgbmV3IFNTTCBzZXNzaW9ucyBtYXkgYmUgZXN0YWJsaXNoZWQgYnkgdGhpcyBlbmdpbmUgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmxhZworICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGlmIG5ldyBTU0wgc2Vzc2lvbnMgbWF5IGJlIGVzdGFibGlzaGVkLAorICAgICAqICAgICAgICAgICAge0Bjb2RlIGZhbHNlfSBpZiBleGlzdGluZyBTU0wgc2Vzc2lvbnMgbXVzdCBiZSByZXVzZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKGJvb2xlYW4gZmxhZyk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHdoZXRoZXIgdGhpcyBlbmdpbmUgbXVzdCByZXF1aXJlIGNsaWVudCBhdXRoZW50aWNhdGlvbi4gVGhlIGNsaWVudAorICAgICAqIGF1dGhlbnRpY2F0aW9uIGlzIG9uZSBvZjoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPmF1dGhlbnRpY2F0aW9uIHJlcXVpcmVkPC9saT4KKyAgICAgKiA8bGk+YXV0aGVudGljYXRpb24gcmVxdWVzdGVkPC9saT4KKyAgICAgKiA8bGk+bm8gYXV0aGVudGljYXRpb24gbmVlZGVkPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqIFRoaXMgbWV0aG9kIG92ZXJyaWRlcyB0aGUgc2V0dGluZyBvZiB7QGxpbmsgI3NldFdhbnRDbGllbnRBdXRoKGJvb2xlYW4pfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZWVkCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gaWYgY2xpZW50IGF1dGhlbnRpY2F0aW9uIGlzIHJlcXVpcmVkLAorICAgICAqICAgICAgICAgICAge0Bjb2RlIGZhbHNlfSBpZiBubyBhdXRoZW50aWNhdGlvbiBpcyBuZWVkZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0TmVlZENsaWVudEF1dGgoYm9vbGVhbiBuZWVkKTsKKworICAgIC8qKgorICAgICAqIFNldHMgd2hldGhlciB0aGlzIGVuZ2luZSBzaG91bGQgYWN0IGluIGNsaWVudCAob3Igc2VydmVyKSBtb2RlIHdoZW4KKyAgICAgKiBoYW5kc2hha2luZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb2RlCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBlbmdpbmUgc2hvdWxkIGFjdCBpbiBjbGllbnQgbW9kZSwKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBmYWxzZX0gaWYgbm90LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIHN0YXJ0aW5nIHRoZSBpbml0aWFsCisgICAgICogICAgICAgICAgICAgaGFuZHNoYWtlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFVzZUNsaWVudE1vZGUoYm9vbGVhbiBtb2RlKTsKKworICAgIC8qKgorICAgICAqIFNldHMgd2hldGhlciB0aGlzIGVuZ2luZSBzaG91bGQgcmVxdWVzdCBjbGllbnQgYXV0aGVudGljYXRpb24uIFRoZSBjbGllbnQKKyAgICAgKiBhdXRoZW50aWNhdGlvbiBpcyBvbmUgb2YgdGhlIGZvbGxvd2luZzoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPmF1dGhlbnRpY2F0aW9uIHJlcXVpcmVkPC9saT4KKyAgICAgKiA8bGk+YXV0aGVudGljYXRpb24gcmVxdWVzdGVkPC9saT4KKyAgICAgKiA8bGk+bm8gYXV0aGVudGljYXRpb24gbmVlZGVkPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqIFRoaXMgbWV0aG9kIG92ZXJyaWRlcyB0aGUgc2V0dGluZyBvZiB7QGxpbmsgI3NldE5lZWRDbGllbnRBdXRoKGJvb2xlYW4pfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB3YW50CisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gaWYgY2xpZW50IGF1dGhlbnRpY2F0aW9uIHNob3VsZCBiZSByZXF1ZXN0ZWQsCisgICAgICogICAgICAgICAgICB7QGNvZGUgZmFsc2V9IGlmIG5vIGF1dGhlbnRpY2F0aW9uIGlzIG5lZWRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRXYW50Q2xpZW50QXV0aChib29sZWFuIHdhbnQpOworCisgICAgLyoqCisgICAgICogRGVjb2RlcyB0aGUgaW5jb21pbmcgbmV0d29yayBkYXRhIGJ1ZmZlciBpbnRvIGFwcGxpY2F0aW9uIGRhdGEgYnVmZmVycy4KKyAgICAgKiBJZiBhIGhhbmRzaGFrZSBoYXMgbm90IGJlZW4gc3RhcnRlZCB5ZXQsIGl0IHdpbGwgYXV0b21hdGljYWxseSBiZQorICAgICAqIHN0YXJ0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHdpdGggaW5jb21pbmcgbmV0d29yayBkYXRhCisgICAgICogQHBhcmFtIGRzdHMKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBkZXN0aW5hdGlvbiBidWZmZXJzIGZvciBpbmNvbWluZyBhcHBsaWNhdGlvbgorICAgICAqICAgICAgICAgICAgZGF0YS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBhcnJheSBvZiBkZXN0aW5hdGlvbiBidWZmZXJzIHRvIHdoaWNoIGRhdGEKKyAgICAgKiAgICAgICAgICAgIGlzIHRvIGJlIHRyYW5zZmVycmVkLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBkZXN0aW5hdGlvbiBidWZmZXJzIHRvIGJlIHVzZWQuCisgICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9iamVjdCBvZiB0aGlzIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNTTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnJlZCB3aGlsZSBwcm9jZXNzaW5nIHRoZSBkYXRhLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBsZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBkc3RzLmxlbmd0aCAtIG9mZnNldH0uCisgICAgICogQHRocm93cyBqYXZhLm5pby5SZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG9uZSBvZiB0aGUgZGVzdGluYXRpb24gYnVmZmVycyBpcyByZWFkLW9ubHkuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3JjfSwge0Bjb2RlIGRzdHN9LCBvciBvbmUgb2YgdGhlIGVudHJpZXMgaW4KKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgZHN0c30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGVuZ2luZSBkb2VzIG5vdCBoYXZlIGFsbCB0aGUgbmVlZGVkIHNldHRpbmdzIChlLmcuCisgICAgICogICAgICAgICAgICAgY2xpZW50L3NlcnZlciBtb2RlIG5vdCBzZXQpLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTU0xFbmdpbmVSZXN1bHQgdW53cmFwKEJ5dGVCdWZmZXIgc3JjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5dGVCdWZmZXJbXSBkc3RzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxlbmd0aCkgdGhyb3dzIFNTTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEVuY29kZXMgdGhlIG91dGdvaW5nIGFwcGxpY2F0aW9uIGRhdGEgYnVmZmVycyBpbnRvIHRoZSBuZXR3b3JrIGRhdGEKKyAgICAgKiBidWZmZXIuIElmIGEgaGFuZHNoYWtlIGhhcyBub3QgYmVlbiBzdGFydGVkIHlldCwgaXQgd2lsbCBhdXRvbWF0aWNhbGx5IGJlCisgICAgICogc3RhcnRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcmNzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2Ygc291cmNlIGJ1ZmZlcnMgb2Ygb3V0Z29pbmcgYXBwbGljYXRpb24gZGF0YS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgb2Zmc2V0IGluIHRoZSBhcnJheSBvZiBzb3VyY2UgYnVmZmVycyBmcm9tIHdoaWNoIGRhdGEgaXMKKyAgICAgKiAgICAgICAgICAgIHRvIGJlIHJldHJpZXZlZC4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBudW1iZXIgb2Ygc291cmNlIGJ1ZmZlcnMgdG8gYmUgdXNlZC4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gYnVmZmVyIGZvciBuZXR3b3JrIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9iamVjdCBvZiB0aGlzIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNTTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnJlZCB3aGlsZSBwcm9jZXNzaW5nIHRoZSBkYXRhLgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBsZW5ndGh9IGlzIGdyZWF0ZXIgdGhhbgorICAgICAqICAgICAgICAgICAgIHtAY29kZSBzcmNzLmxlbmd0aCAtIG9mZnNldH0uCisgICAgICogQHRocm93cyBqYXZhLm5pby5SZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBkZXN0aW5hdGlvbiBidWZmZXIgaXMgcmVhZG9ubHkuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3Jjc30sIHtAY29kZSBkc3R9LCBvciBvbmUgdGhlIGVudHJpZXMgaW4KKyAgICAgKiAgICAgICAgICAgICB7QGNvZGUgc3Jjc30gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGVuZ2luZSBkb2VzIG5vdCBoYXZlIGFsbCB0aGUgbmVlZGVkIHNldHRpbmdzIChlLmcuCisgICAgICogICAgICAgICAgICAgY2xpZW50L3NlcnZlciBtb2RlIG5vdCBzZXQpLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTU0xFbmdpbmVSZXN1bHQgd3JhcChCeXRlQnVmZmVyW10gc3JjcywgaW50IG9mZnNldCwgaW50IGxlbmd0aCwgQnl0ZUJ1ZmZlciBkc3QpCisgICAgICAgICAgICB0aHJvd3MgU1NMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGVjb2RlcyB0aGUgaW5jb21pbmcgbmV0d29yayBkYXRhIGJ1ZmZlciBpbnRvIHRoZSBhcHBsaWNhdGlvbiBkYXRhCisgICAgICogYnVmZmVyLiBJZiBhIGhhbmRzaGFrZSBoYXMgbm90IGJlZW4gc3RhcnRlZCB5ZXQsIGl0IHdpbGwgYXV0b21hdGljYWxseSBiZQorICAgICAqIHN0YXJ0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgYnVmZmVyIHdpdGggaW5jb21pbmcgbmV0d29yayBkYXRhCisgICAgICogQHBhcmFtIGRzdAorICAgICAqICAgICAgICAgICAgdGhlIGRlc3RpbmF0aW9uIGJ1ZmZlciBmb3IgaW5jb21pbmcgYXBwbGljYXRpb24gZGF0YS4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2JqZWN0IG9mIHRoaXMgb3BlcmF0aW9uLgorICAgICAqIEB0aHJvd3MgU1NMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycmVkIHdoaWxlIHByb2Nlc3NpbmcgdGhlIGRhdGEuCisgICAgICogQHRocm93cyBqYXZhLm5pby5SZWFkT25seUJ1ZmZlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG9uZSBvZiB0aGUgZGVzdGluYXRpb24gYnVmZmVycyBpcyByZWFkLW9ubHkuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3JjfSBvciB7QGNvZGUgZHN0fSBpcyB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZW5naW5lIGRvZXMgbm90IGhhdmUgYWxsIHRoZSBuZWVkZWQgc2V0dGluZ3MgKGUuZy4KKyAgICAgKiAgICAgICAgICAgICBjbGllbnQvc2VydmVyIG1vZGUgbm90IHNldCkuCisgICAgICovCisgICAgcHVibGljIFNTTEVuZ2luZVJlc3VsdCB1bndyYXAoQnl0ZUJ1ZmZlciBzcmMsIEJ5dGVCdWZmZXIgZHN0KSB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHVud3JhcChzcmMsIG5ldyBCeXRlQnVmZmVyW10geyBkc3QgfSwgMCwgMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVjb2RlcyB0aGUgaW5jb21pbmcgbmV0d29yayBkYXRhIGJ1ZmZlciBpbnRvIHRoZSBhcHBsaWNhdGlvbiBkYXRhCisgICAgICogYnVmZmVycy4gSWYgYSBoYW5kc2hha2UgaGFzIG5vdCBiZWVuIHN0YXJ0ZWQgeWV0LCBpdCB3aWxsIGF1dG9tYXRpY2FsbHkKKyAgICAgKiBiZSBzdGFydGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHNyYworICAgICAqICAgICAgICAgICAgdGhlIGJ1ZmZlciB3aXRoIGluY29taW5nIG5ldHdvcmsgZGF0YQorICAgICAqIEBwYXJhbSBkc3RzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2YgZGVzdGluYXRpb24gYnVmZmVycyBmb3IgaW5jb21pbmcgYXBwbGljYXRpb24KKyAgICAgKiAgICAgICAgICAgIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9iamVjdCBvZiB0aGlzIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNTTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnJlZCB3aGlsZSBwcm9jZXNzaW5nIHRoZSBkYXRhLgorICAgICAqIEB0aHJvd3MgamF2YS5uaW8uUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBvbmUgb2YgdGhlIGRlc3RpbmF0aW9uIGJ1ZmZlcnMgaXMgcmVhZC1vbmx5LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHNyY30gb3Ige0Bjb2RlIGRzdHN9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmdpbmUgZG9lcyBub3QgaGF2ZSBhbGwgdGhlIG5lZWRlZCBzZXR0aW5ncyAoZS5nLgorICAgICAqICAgICAgICAgICAgIGNsaWVudC9zZXJ2ZXIgbW9kZSBub3Qgc2V0KS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1NMRW5naW5lUmVzdWx0IHVud3JhcChCeXRlQnVmZmVyIHNyYywgQnl0ZUJ1ZmZlcltdIGRzdHMpIHRocm93cyBTU0xFeGNlcHRpb24geworICAgICAgICBpZiAoZHN0cyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJCeXRlIGJ1ZmZlciBhcnJheSBkc3RzIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdW53cmFwKHNyYywgZHN0cywgMCwgZHN0cy5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuY29kZXMgdGhlIG91dGdvaW5nIGFwcGxpY2F0aW9uIGRhdGEgYnVmZmVycyBpbnRvIHRoZSBuZXR3b3JrIGRhdGEKKyAgICAgKiBidWZmZXIuIElmIGEgaGFuZHNoYWtlIGhhcyBub3QgYmVlbiBzdGFydGVkIHlldCwgaXQgd2lsbCBhdXRvbWF0aWNhbGx5IGJlCisgICAgICogc3RhcnRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzcmNzCisgICAgICogICAgICAgICAgICB0aGUgYXJyYXkgb2Ygc291cmNlIGJ1ZmZlcnMgb2Ygb3V0Z29pbmcgYXBwbGljYXRpb24gZGF0YS4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gYnVmZmVyIGZvciBuZXR3b3JrIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9iamVjdCBvZiB0aGlzIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNTTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnJlZCB3aGlsZSBwcm9jZXNzaW5nIHRoZSBkYXRhLgorICAgICAqIEB0aHJvd3MgamF2YS5uaW8uUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZGVzdGluYXRpb24gYnVmZmVyIGlzIHJlYWRvbmx5LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHNyY3N9IG9yIHtAY29kZSBkc3R9IGlzIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBlbmdpbmUgZG9lcyBub3QgaGF2ZSBhbGwgdGhlIG5lZWRlZCBzZXR0aW5ncyAoZS5nLgorICAgICAqICAgICAgICAgICAgIGNsaWVudC9zZXJ2ZXIgbW9kZSBub3Qgc2V0KS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1NMRW5naW5lUmVzdWx0IHdyYXAoQnl0ZUJ1ZmZlcltdIHNyY3MsIEJ5dGVCdWZmZXIgZHN0KSB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNyY3MgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQnl0ZSBidWZmZXIgYXJyYXkgc3JjcyBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHdyYXAoc3JjcywgMCwgc3Jjcy5sZW5ndGgsIGRzdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlcyB0aGUgb3V0Z29pbmcgYXBwbGljYXRpb24gZGF0YSBidWZmZXIgaW50byB0aGUgbmV0d29yayBkYXRhCisgICAgICogYnVmZmVyLiBJZiBhIGhhbmRzaGFrZSBoYXMgbm90IGJlZW4gc3RhcnRlZCB5ZXQsIGl0IHdpbGwgYXV0b21hdGljYWxseSBiZQorICAgICAqIHN0YXJ0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3JjCisgICAgICogICAgICAgICAgICB0aGUgc291cmNlIGJ1ZmZlcnMgb2Ygb3V0Z29pbmcgYXBwbGljYXRpb24gZGF0YS4KKyAgICAgKiBAcGFyYW0gZHN0CisgICAgICogICAgICAgICAgICB0aGUgZGVzdGluYXRpb24gYnVmZmVyIGZvciBuZXR3b3JrIGRhdGEuCisgICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9iamVjdCBvZiB0aGlzIG9wZXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFNTTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnJlZCB3aGlsZSBwcm9jZXNzaW5nIHRoZSBkYXRhLgorICAgICAqIEB0aHJvd3MgamF2YS5uaW8uUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgZGVzdGluYXRpb24gYnVmZmVyIGlzIHJlYWRvbmx5LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIHNyY30gb3Ige0Bjb2RlIGRzdH0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGVuZ2luZSBkb2VzIG5vdCBoYXZlIGFsbCB0aGUgbmVlZGVkIHNldHRpbmdzIChlLmcuCisgICAgICogICAgICAgICAgICAgY2xpZW50L3NlcnZlciBtb2RlIG5vdCBzZXQpLgorICAgICAqLworICAgIHB1YmxpYyBTU0xFbmdpbmVSZXN1bHQgd3JhcChCeXRlQnVmZmVyIHNyYywgQnl0ZUJ1ZmZlciBkc3QpIHRocm93cyBTU0xFeGNlcHRpb24geworICAgICAgICByZXR1cm4gd3JhcChuZXcgQnl0ZUJ1ZmZlcltdIHsgc3JjIH0sIDAsIDEsIGRzdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBTU0xQYXJhbWV0ZXJzIGJhc2VkIG9uIHRoaXMgU1NMU29ja2V0J3MgY3VycmVudAorICAgICAqIGNpcGhlciBzdWl0ZXMsIHByb3RvY29scywgYW5kIGNsaWVudCBhdXRoZW50aWNhdGlvbiBzZXR0aW5ncy4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgU1NMUGFyYW1ldGVycyBnZXRTU0xQYXJhbWV0ZXJzKCkgeworICAgICAgICBTU0xQYXJhbWV0ZXJzIHAgPSBuZXcgU1NMUGFyYW1ldGVycygpOworICAgICAgICBwLnNldENpcGhlclN1aXRlcyhnZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCkpOworICAgICAgICBwLnNldFByb3RvY29scyhnZXRFbmFibGVkUHJvdG9jb2xzKCkpOworICAgICAgICBwLnNldE5lZWRDbGllbnRBdXRoKGdldE5lZWRDbGllbnRBdXRoKCkpOworICAgICAgICBwLnNldFdhbnRDbGllbnRBdXRoKGdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICByZXR1cm4gcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHZhcmlvdXMgU1NMIGhhbmRzaGFrZSBwYXJhbWV0ZXJzIGJhc2VkIG9uIHRoZSBTU0xQYXJhbWV0ZXIKKyAgICAgKiBhcmd1bWVudC4gU3BlY2lmaWNhbGx5LCBzZXRzIHRoZSBTU0xFbmdpbmUncyBlbmFibGVkIGNpcGhlcgorICAgICAqIHN1aXRlcyBpZiB0aGUgcGFyYW1ldGVyJ3MgY2lwaGVyIHN1aXRlcyBhcmUgbm9uLW51bGwuIFNpbWlsYXJseQorICAgICAqIHNldHMgdGhlIGVuYWJsZWQgcHJvdG9jb2xzLiBJZiB0aGUgcGFyYW1ldGVycyBzcGVjaWZ5IHRoZSB3YW50CisgICAgICogb3IgbmVlZCBmb3IgY2xpZW50IGF1dGhlbnRpY2F0aW9uLCB0aG9zZSByZXF1aXJlbWVudHMgYXJlIHNldAorICAgICAqIG9uIHRoZSBTU0xFbmdpbmUsIG90aGVyd2lzZSBib3RoIGFyZSBzZXQgdG8gZmFsc2UuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNTTFBhcmFtZXRlcnMoU1NMUGFyYW1ldGVycyBwKSB7CisgICAgICAgIFN0cmluZ1tdIGNpcGhlclN1aXRlcyA9IHAuZ2V0Q2lwaGVyU3VpdGVzKCk7CisgICAgICAgIGlmIChjaXBoZXJTdWl0ZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgc2V0RW5hYmxlZENpcGhlclN1aXRlcyhjaXBoZXJTdWl0ZXMpOworICAgICAgICB9CisgICAgICAgIFN0cmluZ1tdIHByb3RvY29scyA9IHAuZ2V0UHJvdG9jb2xzKCk7CisgICAgICAgIGlmIChwcm90b2NvbHMgIT0gbnVsbCkgeworICAgICAgICAgICAgc2V0RW5hYmxlZFByb3RvY29scyhwcm90b2NvbHMpOworICAgICAgICB9CisgICAgICAgIGlmIChwLmdldE5lZWRDbGllbnRBdXRoKCkpIHsKKyAgICAgICAgICAgIHNldE5lZWRDbGllbnRBdXRoKHRydWUpOworICAgICAgICB9IGVsc2UgaWYgKHAuZ2V0V2FudENsaWVudEF1dGgoKSkgeworICAgICAgICAgICAgc2V0V2FudENsaWVudEF1dGgodHJ1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzZXRXYW50Q2xpZW50QXV0aChmYWxzZSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xFbmdpbmVSZXN1bHQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTEVuZ2luZVJlc3VsdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhOTg4MzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xFbmdpbmVSZXN1bHQuamF2YQpAQCAtMCwwICsxLDE3MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5uZXQuc3NsOworCisvKioKKyAqIFRoZSByZXN1bHQgb2JqZWN0IGRlc2NyaWJpbmcgdGhlIHN0YXRlIG9mIHRoZSB7QGNvZGUgU1NMRW5naW5lfSBwcm9kdWNlZAorICogYnkgdGhlIHtAY29kZSB3cmFwKCl9IGFuZCB7QGNvZGUgdW53cmFwKCl9IG9wZXJhdGlvbnMuCisgKi8KK3B1YmxpYyBjbGFzcyBTU0xFbmdpbmVSZXN1bHQgeworCisgICAgLyoqCisgICAgICogVGhlIHtAY29kZSBlbnVtfSBkZXNjcmliaW5nIHRoZSBzdGF0ZSBvZiB0aGUgY3VycmVudCBoYW5kc2hha2UuCisgICAgICovCisgICAgcHVibGljIGVudW0gSGFuZHNoYWtlU3RhdHVzIHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIE5vIGhhbmRzaGFrZSBpbiBwcm9ncmVzcy4KKyAgICAgICAgICovCisgICAgICAgIE5PVF9IQU5EU0hBS0lORywKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBoYW5kc2hha2UgaXMgZmluaXNoZWQuCisgICAgICAgICAqLworICAgICAgICBGSU5JU0hFRCwKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSByZXN1bHRzIG9mIG9uZSAob3IgbW9yZSkgZGVsZWdhdGVkIHRhc2tzIGFyZSBuZWVkZWQgdG8gY29udGludWUKKyAgICAgICAgICogdGhlIGhhbmRzaGFrZS4KKyAgICAgICAgICovCisgICAgICAgIE5FRURfVEFTSywKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBlbmdpbmUgbXVzdCBzZW5kIGRhdGEgdG8gdGhlIHJlbW90ZSBzaWRlIHRvIGNvbnRpbnVlIHRoZQorICAgICAgICAgKiBoYW5kc2hha2UuCisgICAgICAgICAqLworICAgICAgICBORUVEX1dSQVAsCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgZW5naW5lIG5lZWRzIHRvIHJlY2VpdmUgZGF0YSBmcm9tIHRoZSByZW1vdGUgc2lkZSB0byBjb250aW51ZSB0aGUKKyAgICAgICAgICogaGFuZHNoYWtlLgorICAgICAgICAgKi8KKyAgICAgICAgTkVFRF9VTldSQVAKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUge0Bjb2RlIGVudW19IGRlc2NyaWJpbmcgdGhlIHJlc3VsdCBvZiB0aGUge0Bjb2RlIFNTTEVuZ2luZX0KKyAgICAgKiBvcGVyYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBlbnVtIFN0YXR1cyB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgc2l6ZSBvZiB0aGUgZGVzdGluYXRpb24gYnVmZmVyIGlzIHRvbyBzbWFsbCB0byBob2xkIHRoZSByZXN1bHQgb2YKKyAgICAgICAgICogdGhlIGN1cnJlbnQgb3BlcmF0aW9uLgorICAgICAgICAgKi8KKyAgICAgICAgQlVGRkVSX09WRVJGTE9XLAorICAgICAgICAvKioKKyAgICAgICAgICogVGhlcmUgd2VyZSBub3QgZW5vdWdoIGJ5dGVzIGF2YWlsYWJsZSBpbiB0aGUgc291cmNlIGJ1ZmZlciB0bworICAgICAgICAgKiBjb21wbGV0ZSB0aGUgY3VycmVudCBvcGVyYXRpb24uCisgICAgICAgICAqLworICAgICAgICBCVUZGRVJfVU5ERVJGTE9XLAorICAgICAgICAvKioKKyAgICAgICAgICogVGhlIG9wZXJhdGlvbiBjbG9zZWQgdGhpcyBzaWRlIG9mIHRoZSBjb21tdW5pY2F0aW9uIG9yIHdhcyBhbHJlYWR5CisgICAgICAgICAqIGNsb3NlZC4KKyAgICAgICAgICovCisgICAgICAgIENMT1NFRCwKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBvcGVyYXRpb24gY29tcGxldGVkIHN1Y2Nlc3NmdWxseS4KKyAgICAgICAgICovCisgICAgICAgIE9LCisgICAgfQorCisgICAgLy8gU3RvcmUgU3RhdHVzIG9iamVjdAorICAgIHByaXZhdGUgZmluYWwgU1NMRW5naW5lUmVzdWx0LlN0YXR1cyBzdGF0dXM7CisKKyAgICAvLyBTdG9yZSBIYW5kc2hha2VTdGF0dXMgb2JqZWN0CisgICAgcHJpdmF0ZSBmaW5hbCBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzIGhhbmRzaGFrZVN0YXR1czsKKworICAgIC8vIFN0b3JlIGJ5dGVzQ29uc3VtZWQKKyAgICBwcml2YXRlIGZpbmFsIGludCBieXRlc0NvbnN1bWVkOworCisgICAgLy8gU3RvcmUgYnl0ZXNQcm9kdWNlZAorICAgIHByaXZhdGUgZmluYWwgaW50IGJ5dGVzUHJvZHVjZWQ7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBTU0xFbmdpbmVSZXN1bHR9IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBzdGF0ZQorICAgICAqIHZhbHVlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdGF0dXMKKyAgICAgKiAgICAgICAgICAgIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIHtAY29kZSBTU0xFbmdpbmV9IG9wZXJhdGlvbi4KKyAgICAgKiBAcGFyYW0gaGFuZHNoYWtlU3RhdHVzCisgICAgICogICAgICAgICAgICB0aGUgc3RhdHVzIG9mIHRoZSBjdXJyZW50IGhhbmRzaGFrZQorICAgICAqIEBwYXJhbSBieXRlc0NvbnN1bWVkCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJldHJpZXZlZCBmcm9tIHRoZSBzb3VyY2UgYnVmZmVyKHMpLgorICAgICAqIEBwYXJhbSBieXRlc1Byb2R1Y2VkCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRyYW5zZmVycmVkIHRvIHRoZSBkZXN0aW5hdGlvbiBidWZmZXIocykuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc3RhdHVzfSBvciB7QGNvZGUgaGFuZHNoYWtlU3RhdHVzfSBpcyB7QGNvZGUgbnVsbH0sCisgICAgICogICAgICAgICAgICAgb3IgaWYge0Bjb2RlIGJ5dGVzQ29uc3VtZWR9IG9yIHtAY29kZSBieXRlc1Byb2R1Y2VzfSBhcmUKKyAgICAgKiAgICAgICAgICAgICBuZWdhdGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1NMRW5naW5lUmVzdWx0KFNTTEVuZ2luZVJlc3VsdC5TdGF0dXMgc3RhdHVzLAorICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cyBoYW5kc2hha2VTdGF0dXMsIGludCBieXRlc0NvbnN1bWVkLCBpbnQgYnl0ZXNQcm9kdWNlZCkgeworICAgICAgICBpZiAoc3RhdHVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInN0YXR1cyBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGhhbmRzaGFrZVN0YXR1cyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJoYW5kc2hha2VTdGF0dXMgaXMgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChieXRlc0NvbnN1bWVkIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiYnl0ZXNDb25zdW1lZCBpcyBuZWdhdGl2ZSIpOworICAgICAgICB9CisgICAgICAgIGlmIChieXRlc1Byb2R1Y2VkIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiYnl0ZXNQcm9kdWNlZCBpcyBuZWdhdGl2ZSIpOworICAgICAgICB9CisgICAgICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzOworICAgICAgICB0aGlzLmhhbmRzaGFrZVN0YXR1cyA9IGhhbmRzaGFrZVN0YXR1czsKKyAgICAgICAgdGhpcy5ieXRlc0NvbnN1bWVkID0gYnl0ZXNDb25zdW1lZDsKKyAgICAgICAgdGhpcy5ieXRlc1Byb2R1Y2VkID0gYnl0ZXNQcm9kdWNlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIHtAY29kZSBTU0xFbmdpbmV9IG9wZXJhdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUge0Bjb2RlIFNTTEVuZ2luZX0gb3BlcmF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdGF0dXMgZ2V0U3RhdHVzKCkgeworICAgICAgICByZXR1cm4gc3RhdHVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0YXR1cyBvZiB0aGUgY3VycmVudCBoYW5kc2hha2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdGF0dXMgb2YgdGhlIGN1cnJlbnQgaGFuZHNoYWtlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBIYW5kc2hha2VTdGF0dXMgZ2V0SGFuZHNoYWtlU3RhdHVzKCkgeworICAgICAgICByZXR1cm4gaGFuZHNoYWtlU3RhdHVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyByZXRyaWV2ZWQgZnJvbSB0aGUgc291cmNlIGJ1ZmZlcihzKS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyByZXRyaWV2ZWQgZnJvbSB0aGUgc291cmNlIGJ1ZmZlcihzKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGJ5dGVzQ29uc3VtZWQoKSB7CisgICAgICAgIHJldHVybiBieXRlc0NvbnN1bWVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyB0cmFuc2ZlcnJlZCB0byB0aGUgZGVzdGluYXRpb24gYnVmZmVyKHMpLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRyYW5zZmVycmVkIHRvIHRoZSBkZXN0aW5hdGlvbiBidWZmZXIocykuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBieXRlc1Byb2R1Y2VkKCkgeworICAgICAgICByZXR1cm4gYnl0ZXNQcm9kdWNlZDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gIlNTTEVuZ2luZVJlcG9ydDogU3RhdHVzID0gIiArIHN0YXR1cyArICIgIEhhbmRzaGFrZVN0YXR1cyA9ICIgKyBoYW5kc2hha2VTdGF0dXMKKyAgICAgICAgICAgICAgICArICJcbiAgICAgICAgICAgICAgICAgYnl0ZXNDb25zdW1lZCA9ICIgKyBieXRlc0NvbnN1bWVkICsgIiBieXRlc1Byb2R1Y2VkID0gIgorICAgICAgICAgICAgICAgICsgYnl0ZXNQcm9kdWNlZDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVkNzE2ZjcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDYxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFRoZSBiYXNlIGNsYXNzIGZvciBhbGwgU1NMIHJlbGF0ZWQgZXhjZXB0aW9ucy4KKyAqLworcHVibGljIGNsYXNzIFNTTEV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0NTExMDA2NDYwNjUwNzA4OTY3TDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFNTTEV4Y2VwdGlvbn0gd2l0aCB0aGUgc3BlY2lmaWVkIHJlYXNvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSByZWFzb24gZm9yIHRoZSBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFNTTEV4Y2VwdGlvbihTdHJpbmcgcmVhc29uKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgU1NMRXhjZXB0aW9ufSB3aXRoIHRoZSBzcGVjaWZpZWQgbWVzc2FnZSBhbmQgY2F1c2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGUgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGNhdXNlLgorICAgICAqLworICAgIHB1YmxpYyBTU0xFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICAgICAgc3VwZXIuaW5pdENhdXNlKGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBTU0xFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqICAgICAgICAgICAgdGhlIGNhdXNlCisgICAgICovCisgICAgcHVibGljIFNTTEV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UgPT0gbnVsbCA/IG51bGwgOiBjYXVzZS50b1N0cmluZygpKTsKKyAgICAgICAgc3VwZXIuaW5pdENhdXNlKGNhdXNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xIYW5kc2hha2VFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTEhhbmRzaGFrZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE5Mzk0MzMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xIYW5kc2hha2VFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDUwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldC5zc2w7CisKKy8qKgorICogVGhlIGV4Y2VwdGlvbiB0aGF0IGlzIHRocm93biB3aGVuIGEgaGFuZHNoYWtlIGNvdWxkIG5vdCBiZSBjb21wbGV0ZWQKKyAqIHN1Y2Nlc3NmdWxseS4KKyAqLworcHVibGljIGNsYXNzIFNTTEhhbmRzaGFrZUV4Y2VwdGlvbiBleHRlbmRzIFNTTEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTA0NTg4MTMxNTAxODMyNjg5MEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIHdpdGggdGhlIGdpdmVuIGRldGFpbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBTU0xIYW5kc2hha2VFeGNlcHRpb24oU3RyaW5nIHJlYXNvbikgeworICAgICAgICBzdXBlcihyZWFzb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugd2l0aCBnaXZlbiBjYXVzZS4KKyAgICAgKiBAaGlkZSBpbnRlcm5hbCB1c2Ugb25seQorICAgICAqLworICAgIHB1YmxpYyBTU0xIYW5kc2hha2VFeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIHdpdGggZ2l2ZW4gZGV0YWlsIG1lc3NhZ2UgYW5kIGNhdXNlLgorICAgICAqIEBoaWRlIGludGVybmFsIHVzZSBvbmx5CisgICAgICovCisgICAgcHVibGljIFNTTEhhbmRzaGFrZUV4Y2VwdGlvbihTdHJpbmcgcmVhc29uLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIocmVhc29uLCBjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvU1NMS2V5RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xLZXlFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZDgxNjc2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvU1NMS2V5RXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5uZXQuc3NsOworCisvKioKKyAqIFRoZSBleGNlcHRpb24gdGhhdCBpcyB0aHJvd24gd2hlbiBhbiBpbnZhbGlkIFNTTCBrZXkgaXMgZW5jb3VudGVyZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBTU0xLZXlFeGNlcHRpb24gZXh0ZW5kcyBTU0xFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTgwNzE2NjQwODE5NDE5Mzc4NzRMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgU1NMS2V5RXhjZXB0aW9ufSB3aXRoIHRoZSBzcGVjaWZpZWQgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1NMS2V5RXhjZXB0aW9uKFN0cmluZyByZWFzb24pIHsKKyAgICAgICAgc3VwZXIocmVhc29uKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xQYXJhbWV0ZXJzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xQYXJhbWV0ZXJzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjY5NGVmMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTFBhcmFtZXRlcnMuamF2YQpAQCAtMCwwICsxLDE0MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXgubmV0LnNzbDsKKworLyoqCisgKiBTU0wgaGFuZHNoYWtlIHBhcmFtZXRlcnMgdGhhdCBpbmNsdWRlIHByb3RvY29scywgY2lwaGVyIHN1aXRlcywgYW5kCisgKiBjbGllbnQgYXV0aGVudGljYXRpb24gcmVxdWlyZW1lbnRzLgorICogQHNpbmNlIDEuNgorICovCitwdWJsaWMgY2xhc3MgU1NMUGFyYW1ldGVycyB7CisKKyAgICBwcml2YXRlIFN0cmluZ1tdIGNpcGhlclN1aXRlczsKKyAgICBwcml2YXRlIFN0cmluZ1tdIHByb3RvY29sczsKKyAgICBwcml2YXRlIGJvb2xlYW4gbmVlZENsaWVudEF1dGg7CisgICAgcHJpdmF0ZSBib29sZWFuIHdhbnRDbGllbnRBdXRoOworCisgICAgLyoqCisgICAgICogVGhlIGRlZmF1bHQgU1NMUGFyYW1ldGVycyBjb25zdHJ1Y3Rvci4gQ2lwaGVyIHN1aXRlcyBhbmQKKyAgICAgKiBwcm90b2NvbHMgYXJlIGluaXRpYWxpemVkIHRvIG51bGwgYW5kIGNsaWVudCBhdXRoZW50aWNhdGlvbgorICAgICAqIG9wdGlvbnMgYXJlIGluaXRpYWxpemVkIHRvIGZhbHNlLgorICAgICAqLworICAgIHB1YmxpYyBTU0xQYXJhbWV0ZXJzKCkge30KKworICAgIC8qKgorICAgICAqIEEgU1NMUGFyYW1ldGVycyBjb25zdHJ1Y3RvciB0aGF0IGFsbG93cyB0aGUgdmFsdWVzIGZvciB0aGUKKyAgICAgKiBpbml0aWFsIGNpcGhlciBzdWl0ZXMgYXJyYXkgdG8gYmUgcHJvdmlkZWQuIE90aGVyIHZhbHVlcworICAgICAqIGRlZmF1bHQgYXMgc3BlY2lmaWVkIGluIHtAbGluayAjU1NMUGFyYW1ldGVycygpfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaXBoZXJTdWl0ZXMgQW4gYXJyYXkgb2YgY2lwaGVyU3VpdGVzIHRoYXQgaXMgY2xvbmVkIGZvcgorICAgICAqIHVzZSB3aXRoaW4gdGhlIFNTTFBhcmFtZXRlcnMsIG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIFNTTFBhcmFtZXRlcnMoU3RyaW5nW10gY2lwaGVyU3VpdGVzKSB7CisgICAgICAgIHNldENpcGhlclN1aXRlcyhjaXBoZXJTdWl0ZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgU1NMUGFyYW1ldGVycyBjb25zdHJ1Y3RvciB0aGF0IGFsbG93cyB0aGUgdmFsdWVzIGZvciBpbml0aWFsCisgICAgICogY2lwaGVyIHN1aXRlcyBhbmQgcHJvdG9jb2xzIGFycmF5cyB0byBiZSBwcm92aWRlZC4gT3RoZXIgdmFsdWVzCisgICAgICogZGVmYXVsdCBhcyBzcGVjaWZpZWQgaW4ge0BsaW5rICNTU0xQYXJhbWV0ZXJzKCl9LgorICAgICAqCisgICAgICogQHBhcmFtIGNpcGhlclN1aXRlcyBBbiBhcnJheSBvZiBjaXBoZXIgbmFtZXMgdGhhdCBpcyBjbG9uZWQgZm9yCisgICAgICogdXNlIHdpdGhpbiB0aGUgU1NMUGFyYW1ldGVycywgb3IgbnVsbC4KKyAgICAgKiBAcGFyYW0gcHJvdG9jb2xzIEFuIGFycmF5IG9mIHByb3RvY29sIG5hbWVzIHRoYXQgaXMgY2xvbmVkIGZvcgorICAgICAqIHVzZSB3aXRoaW4gdGhlIFNTTFBhcmFtZXRlcnMsIG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIFNTTFBhcmFtZXRlcnMoU3RyaW5nW10gY2lwaGVyU3VpdGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1tdIHByb3RvY29scykgeworICAgICAgICBzZXRDaXBoZXJTdWl0ZXMoY2lwaGVyU3VpdGVzKTsKKyAgICAgICAgc2V0UHJvdG9jb2xzKHByb3RvY29scyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhlIGNpcGhlciBzdWl0ZXMsIG9yIG51bGwgaWYgbm9uZSBoYXZlIGJlZW4KKyAgICAgKiBzcGVjaWZpZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIGdldENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgaWYgKGNpcGhlclN1aXRlcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2lwaGVyU3VpdGVzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY2lwaGVyIHN1aXRlcyB0byBhIGNvcHkgb2YgdGhlIGlucHV0LCBvciBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q2lwaGVyU3VpdGVzKFN0cmluZ1tdIGNpcGhlclN1aXRlcykgeworICAgICAgICB0aGlzLmNpcGhlclN1aXRlcyA9ICgoY2lwaGVyU3VpdGVzID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNpcGhlclN1aXRlcy5jbG9uZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29weSBvZiB0aGUgcHJvdG9jb2xzLCBvciBudWxsIGlmIG5vbmUgaGF2ZSBiZWVuCisgICAgICogc3BlY2lmaWVkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRQcm90b2NvbHMoKSB7CisgICAgICAgIGlmIChwcm90b2NvbHMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHByb3RvY29scy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHByb3RvY29scyB0byBhIGNvcHkgb2YgdGhlIGlucHV0LCBvciBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UHJvdG9jb2xzKFN0cmluZ1tdIHByb3RvY29scykgeworICAgICAgICB0aGlzLnByb3RvY29scyA9ICgocHJvdG9jb2xzID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHByb3RvY29scy5jbG9uZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgYSBzZXJ2ZXIgcmVxdWlyZXMgYXV0aGVudGljYXRpb24gZnJvbSBhIGNsaWVudAorICAgICAqIGR1cmluZyBoYW5kc2hha2luZy4gSWYgdGhpcyByZXR1cm5zIHRydWUsIHtAbGluaworICAgICAqICNnZXRXYW50Q2xpZW50QXV0aH0gd2lsbCByZXR1cm4gZmFsc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0TmVlZENsaWVudEF1dGggKCkgeworICAgICAgICByZXR1cm4gbmVlZENsaWVudEF1dGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB3aGV0aGVyIG9yIG5vdCB0byBhIHNlcnZlciBuZWVkcyBjbGllbnQgYXV0aGVudGljYXRpb24uCisgICAgICogQWZ0ZXIgY2FsbGluZyB0aGlzLCAjZ2V0V2FudENsaWVudEF1dGgoKSB3aWxsIHJldHVybiBmYWxzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROZWVkQ2xpZW50QXV0aCAoYm9vbGVhbiBuZWVkQ2xpZW50QXV0aCkgeworICAgICAgICB0aGlzLm5lZWRDbGllbnRBdXRoID0gbmVlZENsaWVudEF1dGg7CisgICAgICAgIHRoaXMud2FudENsaWVudEF1dGggPSBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgYSBzZXJ2ZXIgb3B0aW9uYWxseSB3YW50cyB0byBhdXRoZW50aWNhdGUgYQorICAgICAqIGNsaWVudCBkdXJpbmcgaGFuZHNoYWtpbmcuIElmIHRoaXMgcmV0dXJucyB0cnVlLCB7QGxpbmsKKyAgICAgKiAjZ2V0TmVlZENsaWVudEF1dGh9IHdpbGwgcmV0dXJuIGZhbHNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldFdhbnRDbGllbnRBdXRoICgpIHsKKyAgICAgICAgcmV0dXJuIHdhbnRDbGllbnRBdXRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgd2hldGhlciBvciBub3QgdG8gYSBzZXJ2ZXIgd2FudHMgY2xpZW50IGF1dGhlbnRpY2F0aW9uLgorICAgICAqIEFmdGVyIGNhbGxpbmcgdGhpcywgI2dldE5lZWRDbGllbnRBdXRoKCkgd2lsbCByZXR1cm4gZmFsc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0V2FudENsaWVudEF1dGggKGJvb2xlYW4gd2FudENsaWVudEF1dGgpIHsKKyAgICAgICAgdGhpcy53YW50Q2xpZW50QXV0aCA9IHdhbnRDbGllbnRBdXRoOworICAgICAgICB0aGlzLm5lZWRDbGllbnRBdXRoID0gZmFsc2U7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmI1YmQ2NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5uZXQuc3NsOworCisvKioKKyAqIFRoZSBleGNlcHRpb24gdGhhdCBpcyB0aHJvd24gd2hlbiB0aGUgaWRlbnRpdHkgb2YgYSBwZWVyIGhhcyBub3QgYmVlZAorICogdmVyaWZpZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbiBleHRlbmRzIFNTTEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODkxOTUxMjY3NTAwMDYwMDU0N0w7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbn0gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24oU3RyaW5nIHJlYXNvbikgeworICAgICAgICBzdXBlcihyZWFzb24pOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTFBlcm1pc3Npb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTFBlcm1pc3Npb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTM3YmUwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvU1NMUGVybWlzc2lvbi5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuQmFzaWNQZXJtaXNzaW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbjsKKworLyoqCisgKiBMZWdhY3kgc2VjdXJpdHkgY29kZTsgZG8gbm90IHVzZS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFNTTFBlcm1pc3Npb24gZXh0ZW5kcyBCYXNpY1Blcm1pc3Npb24geworICAgIHB1YmxpYyBTU0xQZXJtaXNzaW9uKFN0cmluZyBuYW1lKSB7IHN1cGVyKCIiKTsgfQorCisgICAgcHVibGljIFNTTFBlcm1pc3Npb24oU3RyaW5nIG5hbWUsIFN0cmluZyBhY3Rpb25zKSB7IHN1cGVyKCIiLCAiIik7IH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIGdldEFjdGlvbnMoKSB7IHJldHVybiBudWxsOyB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaW1wbGllcyhQZXJtaXNzaW9uIHBlcm1pc3Npb24pIHsgcmV0dXJuIHRydWU7IH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTFByb3RvY29sRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xQcm90b2NvbEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUwZWQ3NGQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xQcm90b2NvbEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXgubmV0LnNzbDsKKworLyoqCisgKiBUaGUgZXhjZXB0aW9uIHRoYXQgaXMgdGhyb3duIHdoZW4gYW4gZXJyb3IgaW4gdGhlIG9wZXJhdGlvbiBvZiB0aGUgU1NMCisgKiBwcm90b2NvbCBpcyBlbmNvdW50ZXJlZC4KKyAqLworcHVibGljIGNsYXNzIFNTTFByb3RvY29sRXhjZXB0aW9uIGV4dGVuZHMgU1NMRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDU0NDUwNjcwNjM3OTkxMzQ5MjhMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgU1NMUHJvdG9jb2xFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqICAgICAgICAgICAgdGhlIGRldGFpbCBtZXNzYWdlIGZvciB0aGUgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBTU0xQcm90b2NvbEV4Y2VwdGlvbihTdHJpbmcgcmVhc29uKSB7CisgICAgICAgIHN1cGVyKHJlYXNvbik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvU1NMU2VydmVyU29ja2V0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xTZXJ2ZXJTb2NrZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMTA5MTcwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvU1NMU2VydmVyU29ja2V0LmphdmEKQEAgLTAsMCArMSwyMzEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU2VydmVyU29ja2V0OworCisvKioKKyAqIFRoZSBleHRlbnNpb24gb2Yge0Bjb2RlIFNlcnZlclNvY2tldH0gd2hpY2ggcHJvdmlkZXMgc2VjdXJlIHNlcnZlciBzb2NrZXRzCisgKiBiYXNlZCBvbiBwcm90b2NvbHMgbGlrZSBTU0wsIFRMUywgb3Igb3RoZXJzLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU1NMU2VydmVyU29ja2V0IGV4dGVuZHMgU2VydmVyU29ja2V0IHsKKworICAgIC8qKgorICAgICAqIE9ubHkgdG8gYmUgdXNlZCBieSBzdWJjbGFzc2VzLgorICAgICAqIDxwPgorICAgICAqIENyZWF0ZXMgYSBUQ1Agc2VydmVyIHNvY2tldCB3aXRoIHRoZSBkZWZhdWx0IGF1dGhlbnRpY2F0aW9uIGNvbnRleHQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgY3JlYXRpbmcgdGhlIHNvY2tldCBmYWlscy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU1NMU2VydmVyU29ja2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPbmx5IHRvIGJlIHVzZWQgYnkgc3ViY2xhc3Nlcy4KKyAgICAgKiA8cD4KKyAgICAgKiBDcmVhdGVzIGEgVENQIHNlcnZlciBzb2NrZXQgb24gdGhlIHNwZWNpZmllZCBwb3J0IHdpdGggdGhlIGRlZmF1bHQKKyAgICAgKiBhdXRoZW50aWNhdGlvbiBjb250ZXh0LiBUaGUgY29ubmVjdGlvbidzIGRlZmF1bHQgYmFja2xvZyBzaXplIGlzIDUwCisgICAgICogY29ubmVjdGlvbnMuCisgICAgICogQHBhcmFtIHBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IHRvIGxpc3RlbiBvbi4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgY3JlYXRpbmcgdGhlIHNvY2tldCBmYWlscy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU1NMU2VydmVyU29ja2V0KGludCBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihwb3J0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPbmx5IHRvIGJlIHVzZWQgYnkgc3ViY2xhc3Nlcy4KKyAgICAgKiA8cD4KKyAgICAgKiBDcmVhdGVzIGEgVENQIHNlcnZlciBzb2NrZXQgb24gdGhlIHNwZWNpZmllZCBwb3J0IHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBiYWNrbG9nIGFuZCB0aGUgZGVmYXVsdCBhdXRoZW50aWNhdGlvbiBjb250ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIHBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IHRvIGxpc3RlbiBvbi4KKyAgICAgKiBAcGFyYW0gYmFja2xvZworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBwZW5kaW5nIGNvbm5lY3Rpb25zIHRvIHF1ZXVlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBjcmVhdGluZyB0aGUgc29ja2V0IGZhaWxzLgorICAgICAqLworICAgIHByb3RlY3RlZCBTU0xTZXJ2ZXJTb2NrZXQoaW50IHBvcnQsIGludCBiYWNrbG9nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihwb3J0LCBiYWNrbG9nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPbmx5IHRvIGJlIHVzZWQgYnkgc3ViY2xhc3Nlcy4KKyAgICAgKiA8cD4KKyAgICAgKiBDcmVhdGVzIGEgVENQIHNlcnZlciBzb2NrZXQgb24gdGhlIHNwZWNpZmllZCBwb3J0LCB1c2luZyB0aGUgc3BlY2lmaWVkCisgICAgICogYmFja2xvZywgbGlzdGVuaW5nIG9uIHRoZSBzcGVjaWZpZWQgaW50ZXJmYWNlLCBhbmQgdXNpbmcgdGhlIGRlZmF1bHQKKyAgICAgKiBhdXRoZW50aWNhdGlvbiBjb250ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIHBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IHRoZSBsaXN0ZW4gb24uCisgICAgICogQHBhcmFtIGJhY2tsb2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgcGVuZGluZyBjb25uZWN0aW9ucyB0byBxdWV1ZS4KKyAgICAgKiBAcGFyYW0gYWRkcmVzcworICAgICAqICAgICAgICAgICAgdGhlIGFkZHJlc3Mgb2YgdGhlIGludGVyZmFjZSB0byBhY2NlcHQgY29ubmVjdGlvbnMgb24uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGNyZWF0aW5nIHRoZSBzb2NrZXQgZmFpbHMuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNTTFNlcnZlclNvY2tldChpbnQgcG9ydCwgaW50IGJhY2tsb2csIEluZXRBZGRyZXNzIGFkZHJlc3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKHBvcnQsIGJhY2tsb2csIGFkZHJlc3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWVzIG9mIHRoZSBlbmFibGVkIGNpcGhlciBzdWl0ZXMgdG8gYmUgdXNlZCBmb3IgbmV3CisgICAgICogY29ubmVjdGlvbnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lcyBvZiB0aGUgZW5hYmxlZCBjaXBoZXIgc3VpdGVzIHRvIGJlIHVzZWQgZm9yIG5ldworICAgICAqICAgICAgICAgY29ubmVjdGlvbnMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZ1tdIGdldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5hbWVzIG9mIHRoZSBjaXBoZXIgc3VpdGVzIHRvIGJlIGVuYWJsZWQgZm9yIG5ldyBjb25uZWN0aW9ucy4KKyAgICAgKiBPbmx5IGNpcGhlciBzdWl0ZXMgcmV0dXJuZWQgYnkge0BsaW5rICNnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKX0gYXJlCisgICAgICogYWxsb3dlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdWl0ZXMKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lcyBvZiB0aGUgdG8gYmUgZW5hYmxlZCBjaXBoZXIgc3VpdGVzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgb25lIG9mIHRoZSBjaXBoZXIgc3VpdGUgbmFtZXMgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRFbmFibGVkQ2lwaGVyU3VpdGVzKFN0cmluZ1tdIHN1aXRlcyk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lcyBvZiB0aGUgc3VwcG9ydGVkIGNpcGhlciBzdWl0ZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lcyBvZiB0aGUgc3VwcG9ydGVkIGNpcGhlciBzdWl0ZXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZ1tdIGdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZXMgb2YgdGhlIHN1cHBvcnRlZCBwcm90b2NvbHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lcyBvZiB0aGUgc3VwcG9ydGVkIHByb3RvY29scy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nW10gZ2V0U3VwcG9ydGVkUHJvdG9jb2xzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lcyBvZiB0aGUgZW5hYmxlZCBwcm90b2NvbHMgdG8gYmUgdXNlZCBmb3IgbmV3CisgICAgICogY29ubmVjdGlvbnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lcyBvZiB0aGUgZW5hYmxlZCBwcm90b2NvbHMgdG8gYmUgdXNlZCBmb3IgbmV3CisgICAgICogICAgICAgICBjb25uZWN0aW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nW10gZ2V0RW5hYmxlZFByb3RvY29scygpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmFtZXMgb2YgdGhlIHByb3RvY29scyB0byBiZSBlbmFibGVkIGZvciBuZXcgY29ubmVjdGlvbnMuIE9ubHkKKyAgICAgKiBwcm90b2NvbHMgcmV0dXJuZWQgYnkge0BsaW5rICNnZXRTdXBwb3J0ZWRQcm90b2NvbHMoKX0gYXJlIGFsbG93ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJvdG9jb2xzCisgICAgICogICAgICAgICAgICB0aGUgbmFtZXMgb2YgdGhlIHRvIGJlIGVuYWJsZWQgcHJvdG9jb2xzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgb25lIG9mIHRoZSBwcm90b2NvbHMgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRFbmFibGVkUHJvdG9jb2xzKFN0cmluZ1tdIHByb3RvY29scyk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHdoZXRoZXIgc2VydmVyLW1vZGUgY29ubmVjdGlvbnMgd2lsbCBiZSBjb25maWd1cmVkIHRvIHJlcXVpcmUgY2xpZW50CisgICAgICogYXV0aGVudGljYXRpb24uIFRoZSBjbGllbnQgYXV0aGVudGljYXRpb24gaXMgb25lIG9mIHRoZSBmb2xsb3dpbmc6CisgICAgICogPHVsPgorICAgICAqIDxsaT5hdXRoZW50aWNhdGlvbiByZXF1aXJlZDwvbGk+CisgICAgICogPGxpPmF1dGhlbnRpY2F0aW9uIHJlcXVlc3RlZDwvbGk+CisgICAgICogPGxpPm5vIGF1dGhlbnRpY2F0aW9uIG5lZWRlZDwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiBUaGlzIG1ldGhvZCBvdmVycmlkZXMgdGhlIHNldHRpbmcgb2Yge0BsaW5rICNzZXRXYW50Q2xpZW50QXV0aChib29sZWFuKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmVlZAorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGlmIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpcyByZXF1aXJlZCwKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSBmYWxzZX0gaWYgbm8gYXV0aGVudGljYXRpb24gaXMgbmVlZGVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldE5lZWRDbGllbnRBdXRoKGJvb2xlYW4gbmVlZCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgc2VydmVyLW1vZGUgY29ubmVjdGlvbnMgd2lsbCBiZSBjb25maWd1cmVkIHRvIHJlcXVpcmUKKyAgICAgKiBjbGllbnQgYXV0aGVudGljYXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBjbGllbnQgYXV0aGVudGljYXRpb24gaXMgcmVxdWlyZWQsIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIGlmIG5vIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpcyBuZWVkZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZ2V0TmVlZENsaWVudEF1dGgoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgd2hldGhlciBzZXJ2ZXItbW9kZSBjb25uZWN0aW9ucyB3aWxsIGJlIGNvbmZpZ3VyZWQgdG8gcmVxdWVzdCBjbGllbnQKKyAgICAgKiBhdXRoZW50aWNhdGlvbi4gVGhlIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpcyBvbmUgb2YgdGhlIGZvbGxvd2luZzoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPmF1dGhlbnRpY2F0aW9uIHJlcXVpcmVkPC9saT4KKyAgICAgKiA8bGk+YXV0aGVudGljYXRpb24gcmVxdWVzdGVkPC9saT4KKyAgICAgKiA8bGk+bm8gYXV0aGVudGljYXRpb24gbmVlZGVkPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqIFRoaXMgbWV0aG9kIG92ZXJyaWRlcyB0aGUgc2V0dGluZyBvZiB7QGxpbmsgI3NldE5lZWRDbGllbnRBdXRoKGJvb2xlYW4pfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB3YW50CisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gaWYgY2xpZW50IGF1dGhlbnRpY2F0aW9uIHNob3VsZCBiZSByZXF1ZXN0ZWQsCisgICAgICogICAgICAgICAgICB7QGNvZGUgZmFsc2V9IGlmIG5vIGF1dGhlbnRpY2F0aW9uIGlzIG5lZWRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRXYW50Q2xpZW50QXV0aChib29sZWFuIHdhbnQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHNlcnZlci1tb2RlIGNvbm5lY3Rpb25zIHdpbGwgYmUgY29uZmlndXJlZCB0byByZXF1ZXN0CisgICAgICogY2xpZW50IGF1dGhlbnRpY2F0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaXMgY2xpZW50IGF1dGhlbnRpY2F0aW9uIHdpbGwgYmUgcmVxdWVzdGVkLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBpZiBubyBjbGllbnQgYXV0aGVudGljYXRpb24gaXMgbmVlZGVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGdldFdhbnRDbGllbnRBdXRoKCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHdoZXRoZXIgbmV3IGNvbm5lY3Rpb25zIHNob3VsZCBhY3QgaW4gY2xpZW50IG1vZGUgd2hlbiBoYW5kc2hha2luZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb2RlCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gaWYgbmV3IGNvbm5lY3Rpb25zIHNob3VsZCBhY3QgaW4gY2xpZW50IG1vZGUsCisgICAgICogICAgICAgICAgICB7QGNvZGUgZmFsc2V9IGlmIG5vdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRVc2VDbGllbnRNb2RlKGJvb2xlYW4gbW9kZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgbmV3IGNvbm5lY3Rpb24gd2lsbCBhY3QgaW4gY2xpZW50IG1vZGUgd2hlbiBoYW5kc2hha2luZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIG5ldyBjb25uZWN0aW9ucyB3aWxsIGFjdCBpbiBjbGllbnQgbW9kZSB3aGVuCisgICAgICogICAgICAgICBoYW5kc2hha2luZywge0Bjb2RlIGZhbHNlfSBpZiBub3QuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZ2V0VXNlQ2xpZW50TW9kZSgpOworCisgICAgLyoqCisgICAgICogU2V0cyB3aGV0aGVyIG5ldyBTU0wgc2Vzc2lvbnMgbWF5IGJlIGVzdGFibGlzaGVkIGZvciBuZXcgY29ubmVjdGlvbnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmxhZworICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGlmIG5ldyBTU0wgc2Vzc2lvbnMgbWF5IGJlIGVzdGFibGlzaGVkLAorICAgICAqICAgICAgICAgICAge0Bjb2RlIGZhbHNlfSBpZiBleGlzdGluZyBTU0wgc2Vzc2lvbnMgbXVzdCBiZSByZXVzZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKGJvb2xlYW4gZmxhZyk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgbmV3IFNTTCBzZXNzaW9ucyBtYXkgYmUgZXN0YWJsaXNoZWQgZm9yIG5ldyBjb25uZWN0aW9ucy4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIG5ldyBTU0wgc2Vzc2lvbnMgbWF5IGJlIGVzdGFibGlzaGVkLAorICAgICAqICAgICAgICAge0Bjb2RlIGZhbHNlfSBpZiBleGlzdGluZyBTU0wgc2Vzc2lvbnMgbXVzdCBiZSByZXVzZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2NlNzJjZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTFNlcnZlclNvY2tldEZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDk5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmF4Lm5ldC5TZXJ2ZXJTb2NrZXRGYWN0b3J5OworCisvKioKKyAqIFRoZSBmYWN0b3J5IGZvciBTU0wgc2VydmVyIHNvY2tldHMuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5IGV4dGVuZHMgU2VydmVyU29ja2V0RmFjdG9yeSB7CisgICAgLy8gVE9ETyBFWFBPUlQgQ09OVFJPTAorCisgICAgLy8gVGhlIGRlZmF1bHQgU1NMIHNvY2tldCBmYWN0b3J5CisgICAgcHJpdmF0ZSBzdGF0aWMgU2VydmVyU29ja2V0RmFjdG9yeSBkZWZhdWx0U2VydmVyU29ja2V0RmFjdG9yeTsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZWZhdWx0TmFtZTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQge0Bjb2RlIFNTTFNlcnZlclNvY2tldEZhY3Rvcnl9IGluc3RhbmNlLiBUaGUgZGVmYXVsdAorICAgICAqIGltcGxlbWVudGF0aW9uIGlzIGRlZmluZWQgYnkgdGhlIHNlY3VyaXR5IHByb3BlcnR5CisgICAgICogInNzbC5TZXJ2ZXJTb2NrZXRGYWN0b3J5LnByb3ZpZGVyIi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGRlZmF1bHQge0Bjb2RlIFNTTFNlcnZlclNvY2tldEZhY3Rvcnl9IGluc3RhbmNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIFNlcnZlclNvY2tldEZhY3RvcnkgZ2V0RGVmYXVsdCgpIHsKKyAgICAgICAgaWYgKGRlZmF1bHRTZXJ2ZXJTb2NrZXRGYWN0b3J5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBkZWZhdWx0U2VydmVyU29ja2V0RmFjdG9yeTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZGVmYXVsdE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgZGVmYXVsdE5hbWUgPSBTZWN1cml0eS5nZXRQcm9wZXJ0eSgic3NsLlNlcnZlclNvY2tldEZhY3RvcnkucHJvdmlkZXIiKTsKKyAgICAgICAgICAgIGlmIChkZWZhdWx0TmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgQ2xhc3NMb2FkZXIgY2wgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpOworICAgICAgICAgICAgICAgIGlmIChjbCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGNsID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgQ2xhc3M8Pz4gc3NmYyA9IENsYXNzLmZvck5hbWUoZGVmYXVsdE5hbWUsIHRydWUsIGNsKTsKKyAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFNlcnZlclNvY2tldEZhY3RvcnkgPSAoU2VydmVyU29ja2V0RmFjdG9yeSkgc3NmYy5uZXdJbnN0YW5jZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChkZWZhdWx0U2VydmVyU29ja2V0RmFjdG9yeSA9PSBudWxsKSB7CisgICAgICAgICAgICBTU0xDb250ZXh0IGNvbnRleHQ7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNvbnRleHQgPSBTU0xDb250ZXh0LmdldERlZmF1bHQoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgY29udGV4dCA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY29udGV4dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZGVmYXVsdFNlcnZlclNvY2tldEZhY3RvcnkgPSBjb250ZXh0LmdldFNlcnZlclNvY2tldEZhY3RvcnkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoZGVmYXVsdFNlcnZlclNvY2tldEZhY3RvcnkgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gVXNlIGludGVybmFsIGR1bW15IGltcGxlbWVudGF0aW9uCisgICAgICAgICAgICBkZWZhdWx0U2VydmVyU29ja2V0RmFjdG9yeSA9IG5ldyBEZWZhdWx0U1NMU2VydmVyU29ja2V0RmFjdG9yeSgKKyAgICAgICAgICAgICAgICAgICAgIk5vIFNlcnZlclNvY2tldEZhY3RvcnkgaW5zdGFsbGVkIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRlZmF1bHRTZXJ2ZXJTb2NrZXRGYWN0b3J5OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFNTTFNlcnZlclNvY2tldEZhY3Rvcnl9IGluc3RhbmNlLgorICAgICAqLworICAgIHByb3RlY3RlZCBTU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWVzIG9mIHRoZSBjaXBoZXIgc3VpdGVzIHRoYXQgYXJlIGVuYWJsZWQgYnkgZGVmYXVsdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWVzIG9mIHRoZSBjaXBoZXIgc3VpdGVzIHRoYXQgYXJlIGVuYWJsZWQgYnkgZGVmYXVsdAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmdbXSBnZXREZWZhdWx0Q2lwaGVyU3VpdGVzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIHN1cHBvcnRlZCBjaXBoZXIgc3VpdGVzIHRoYXQgY291bGQgYmUgZW5hYmxlZCBmb3IgYW4KKyAgICAgKiBTU0wgY29ubmVjdGlvbiBjcmVhdGVkIGJ5IHRoaXMgZmFjdG9yeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxpc3Qgb2Ygc3VwcG9ydGVkIGNpcGhlciBzdWl0ZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nW10gZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xTZXNzaW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xTZXNzaW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzRjYTBhNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTFNlc3Npb24uamF2YQpAQCAtMCwwICsxLDIyNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5QcmluY2lwYWw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworCisvKioKKyAqIFRoZSBpbnRlcmZhY2UgcmVwcmVzZW50aW5nIGFuIFNTTCBzZXNzaW9uLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFNTTFNlc3Npb24geworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbWF4aW11bSBzaXplIHRoYXQgYW4gYXBwbGljYXRpb24gYnVmZmVyIGNhbiBiZSBmb3IgdGhpcworICAgICAqIHNlc3Npb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIGFwcGxpY2F0aW9uIGJ1ZmZlciBzaXplLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0QXBwbGljYXRpb25CdWZmZXJTaXplKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBjaXBoZXIgc3VpdGUgdXNlZCBpbiB0aGlzIHNlc3Npb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBjaXBoZXIgc3VpdGUgdXNlZCBpbiB0aGlzIHNlc3Npb24uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDaXBoZXJTdWl0ZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGltZSB0aGlzIHNlc3Npb24gd2FzIGNyZWF0ZWQsIGluIG1pbGxpc2Vjb25kcyBzaW5jZSBtaWRuaWdodAorICAgICAqIEphbnVhcnkgMXN0IDE5NzAgVVRDLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdGltZSB0aGUgc2Vzc2lvbiB3YXMgY3JlYXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRDcmVhdGlvblRpbWUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyBzZXNzaW9ucyBpZGVudGlmaWVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIHNlc3Npb25zIGlkZW50aWZpZXIuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRJZCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGltZSB0aGlzIHNlc3Npb24gd2FzIGxhc3QgYWNjZXNzZWQsIGluIG1pbGxpc2Vjb25kcyBzaW5jZQorICAgICAqIG1pZG5pZ2h0IEphbnVhcnkgMXN0IDE5NzAgVVRDLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdGltZSB0aGlzIHNlc3Npb24gd2FzIGxhc3QgYWNjZXNzZWQuCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0TGFzdEFjY2Vzc2VkVGltZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGlzdCBvZiBjZXJ0aWZpY2F0ZXMgdGhhdCB3ZXJlIHVzZWQgdG8gaWRlbnRpZnkgdGhlIGxvY2FsCisgICAgICogc2lkZSB0byB0aGUgcGVlciBkdXJpbmcgdGhlIGhhbmRzaGFrZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGVzLCBvcmRlcmVkIGZyb20gbG9jYWwgY2VydGlmaWNhdGUgdG8KKyAgICAgKiAgICAgICAgIENBJ3MgY2VydGlmaWNhdGVzLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZVtdIGdldExvY2FsQ2VydGlmaWNhdGVzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcmluY2lwYWwgdXNlZCB0byBpZGVudGlmeSB0aGUgbG9jYWwgc2lkZSB0byB0aGUgcGVlciBkdXJpbmcKKyAgICAgKiB0aGUgaGFuZHNoYWtlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJpbmNpcGFsIHVzZWQgdG8gaWRlbnRpZnkgdGhlIGxvY2FsIHNpZGUuCisgICAgICovCisgICAgcHVibGljIFByaW5jaXBhbCBnZXRMb2NhbFByaW5jaXBhbCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbWF4aW11bSBzaXplIHRoYXQgYSBuZXR3b3JrIGJ1ZmZlciBjYW4gYmUgZm9yIHRoaXMgc2Vzc2lvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG1heGltdW0gbmV0d29yayBidWZmZXIgc2l6ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFBhY2tldEJ1ZmZlclNpemUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGVzIHRoZSBwZWVyIHVzZWQgdG8gaWRlbnRpZnkgaXRzZWxmIGR1cmluZworICAgICAqIHRoZSBoYW5kc2hha2UuCisgICAgICogPHA+CisgICAgICogTm90ZTogdGhpcyBtZXRob2QgZXhpc3RzIGZvciBjb21wYXRpbGl0eSByZWFzb25zLCB1c2UKKyAgICAgKiB7QGxpbmsgI2dldFBlZXJDZXJ0aWZpY2F0ZXMoKX0gaW5zdGVhZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGVzLCBvcmRlcmVkIGZyb20gdGhlIGlkZW50aXR5IGNlcnRpZmljYXRlIHRvCisgICAgICogICAgICAgICB0aGUgQ0EncyBjZXJ0aWZpY2F0ZXMKKyAgICAgKiBAdGhyb3dzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGlkZW50aXR5IG9mIHRoZSBwZWVyIGlzIG5vdCB2ZXJpZmllZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgWDUwOUNlcnRpZmljYXRlW10gZ2V0UGVlckNlcnRpZmljYXRlQ2hhaW4oKSB0aHJvd3MgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIGNlcnRpZmljYXRlcyB0aGUgcGVlciB1c2VkIHRvIGlkZW50aWZ5IGl0c2VsZiBkdXJpbmcKKyAgICAgKiB0aGUgaGFuZHNoYWtlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGlzdCBvZiBjZXJ0aWZpY2F0ZXMsIG9yZGVyZWQgZnJvbSB0aGUgaWRlbnRpdHkgY2VydGlmaWNhdGUgdG8KKyAgICAgKiAgICAgICAgIHRoZSBDQSdzIGNlcnRpZmljYXRlcy4KKyAgICAgKiBAdGhyb3dzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGlkZW50aXR5IG9mIHRoZSBwZWVyIGlzIG5vdCB2ZXJpZmllZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVbXSBnZXRQZWVyQ2VydGlmaWNhdGVzKCkgdGhyb3dzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaG9zdCBuYW1lIG9mIHRoZSBwZWVyIG9mIHRoaXMgc2Vzc2lvbi4gVGhlIGhvc3QgbmFtZSBpcyBub3QKKyAgICAgKiBhdXRoZW50aWNhdGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaG9zdCBuYW1lIG9mIHRoZSBwZWVyIG9mIHRoaXMgc2Vzc2lvbiwgb3Ige0Bjb2RlIG51bGx9IGlmIG5vCisgICAgICogICAgICAgICBob3N0IG5hbWUgaXMgYXZhaWxhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGVlckhvc3QoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHBvcnQgbnVtYmVyIG9mIHRoZSBwZWVyIG9mIHRoaXMgc2Vzc2lvbi4gVGhlIHBvcnQgbnVtYmVyIGlzCisgICAgICogbm90IGF1dGhlbnRpY2F0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwb3J0IG51bWJlciBvZiB0aGUgcGVlciwgb2Yge0Bjb2RlIC0xfSBpcyBubyBwb3J0IG51bWJlciBpcworICAgICAqICAgICAgICAgYXZhaWxhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UGVlclBvcnQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByaW5jaXBhbCBpZGVudGlmeWluZyB0aGUgcGVlciBkdXJpbmcgdGhlIGhhbmRzaGFrZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByaW5jaXBhbCBpZGVudGlmeWluZyB0aGUgcGVlci4KKyAgICAgKiBAdGhyb3dzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGlkZW50aXR5IG9mIHRoZSBwZWVyIGhhcyBub3QgYmVlbiB2ZXJpZmllZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpbmNpcGFsIGdldFBlZXJQcmluY2lwYWwoKSB0aHJvd3MgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcm90b2NvbCBuYW1lIHRoYXQgaXMgdXNlZCBmb3IgYWxsIGNvbm5lY3Rpb25zIGluIHRoaXMKKyAgICAgKiBzZXNzaW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJvdG9jb2wgbmFtZSB0aGF0IGlzIHVzZWQgZm9yIGFsbCBjb25uZWN0aW9ucyBpbiB0aGlzCisgICAgICogICAgICAgICBzZXNzaW9uLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJvdG9jb2woKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNvbnRleHQgb2YgdGhpcyBzZXNzaW9uLCBvciBudWxsIGlmIG5vIGNvbnRleHQgaXMgYXZhaWxhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBTU0xTZXNzaW9uQ29udGV4dCBnZXRTZXNzaW9uQ29udGV4dCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgb2JqZWN0IGJvdW5kIHRvIHRoZSBzcGVjaWZpZWQgbmFtZSBpbiB0aGlzIHNlc3Npb24ncworICAgICAqIGFwcGxpY2F0aW9uIGxheWVyIGRhdGEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIGJvdW5kIHZhbHVlLgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIGJvdW5kIHRvIHRoZSBzcGVjaWZpZWQgbmFtZSwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZQorICAgICAqICAgICAgICAgc3BlY2lmaWVkIG5hbWUgZG9lcyBub3QgZXhpc3Qgb3IgaXMgbm90IGFjY2Vzc2libGUgaW4gdGhlIGN1cnJlbnQKKyAgICAgKiAgICAgICAgIGFjY2VzcyBjb250cm9sIGNvbnRleHQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbmFtZX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0VmFsdWUoU3RyaW5nIG5hbWUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGlzdCBvZiB0aGUgb2JqZWN0IG5hbWVzIGJvdW5kIHRvIHRoaXMgc2Vzc2lvbidzIGFwcGxpY2F0aW9uCisgICAgICogbGF5ZXIgZGF0YS4uCisgICAgICogPHA+CisgICAgICogRGVwZW5kaW5nIG9uIHRoZSBjdXJyZW50IGFjY2VzcyBjb250cm9sIGNvbnRleHQsIHRoZSBsaXN0IG9mIG9iamVjdCBuYW1lcworICAgICAqIG1heSBiZSBkaWZmZXJlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsaXN0IG9mIHRoZSBvYmplY3QgbmFtZXMgYm91bmQgdG8gdGhpcyBzZXNzaW9uJ3MgYXBwbGljYXRpb24KKyAgICAgKiAgICAgICAgIGxheWVyIGRhdGEuCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIGdldFZhbHVlTmFtZXMoKTsKKworICAgIC8qKgorICAgICAqIEludmFsaWRhdGVzIHRoaXMgc2Vzc2lvbi4KKyAgICAgKiA8cD4KKyAgICAgKiBObyBuZXcgY29ubmVjdGlvbnMgY2FuIGJlIGNyZWF0ZWQsIGJ1dCBhbnkgZXhpc3RpbmcgY29ubmVjdGlvbiByZW1haW5zCisgICAgICogdmFsaWQgdW50aWwgaXQgaXMgY2xvc2VkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGludmFsaWRhdGUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIHNlc3Npb24gaXMgdmFsaWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHNlc3Npb24gaXMgdmFsaWQsIG90aGVyd2lzZSB7QGNvZGUgZmFsc2V9LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzVmFsaWQoKTsKKworICAgIC8qKgorICAgICAqIEJpbmRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHVuZGVyIHRoZSBzcGVjaWZpZWQgbmFtZSBpbiB0aGlzIHNlc3Npb24ncworICAgICAqIGFwcGxpY2F0aW9uIGxheWVyIGRhdGEuCisgICAgICogPHA+CisgICAgICogRm9yIGJpbmRpbmdzIChuZXcgb3IgZXhpc3RpbmcpIGltcGxlbWVudGluZyB0aGUKKyAgICAgKiB7QGNvZGUgU1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lcn0gaW50ZXJmYWNlIHRoZSBvYmplY3Qgd2lsbCBiZSBub3RpZmllZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSB0byBiaW5kIHRoZSBvYmplY3QgdG8uCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICB0aGUgb2JqZWN0IHRvIGJpbmQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBlaXRoZXIge0Bjb2RlIG5hbWV9IG9yIHtAY29kZSB2YWx1ZX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1dFZhbHVlKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpOworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgYmluZGluZyBmb3IgdGhlIHNwZWNpZmllZCBuYW1lIGluIHRoaXMgc2Vzc2lvbidzIGFwcGxpY2F0aW9uCisgICAgICogbGF5ZXIgZGF0YS4gSWYgdGhlIGV4aXN0aW5nIGJpbmRpbmcgaW1wbGVtZW50cyB0aGUKKyAgICAgKiB7QGNvZGUgU1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lcn0gaW50ZXJmYWNlIHRoZSBvYmplY3Qgd2lsbCBiZSBub3RpZmllZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgYmluZGluZyB0byByZW1vdmUuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgbmFtZX0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZVZhbHVlKFN0cmluZyBuYW1lKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTFNlc3Npb25CaW5kaW5nRXZlbnQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTFNlc3Npb25CaW5kaW5nRXZlbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MDUxOTJkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvU1NMU2Vzc2lvbkJpbmRpbmdFdmVudC5qYXZhCkBAIC0wLDAgKzEsNjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEudXRpbC5FdmVudE9iamVjdDsKKworLyoqCisgKiBUaGUgZXZlbnQgc2VudCB0byBhbiB7QGNvZGUgU1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lcn0gd2hlbiB0aGUgbGlzdGVuZXIKKyAqIG9iamVjdCBpcyBib3VuZCAoe0BsaW5rIFNTTFNlc3Npb24jcHV0VmFsdWUoU3RyaW5nLCBPYmplY3QpfSkgb3IgdW5ib3VuZAorICogKHtAbGluayBTU0xTZXNzaW9uI3JlbW92ZVZhbHVlKFN0cmluZyl9KSB0byBhbiB7QGNvZGUgU1NMU2Vzc2lvbn0uCisgKi8KK3B1YmxpYyBjbGFzcyBTU0xTZXNzaW9uQmluZGluZ0V2ZW50IGV4dGVuZHMgRXZlbnRPYmplY3QgeworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbmFtZTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFNTTFNlc3Npb25CaW5kaW5nRXZlbnR9IGZvciB0aGUgc3BlY2lmaWVkIHNlc3Npb24KKyAgICAgKiBpbmRpY2F0aW5nIGEgYmluZGluZyBldmVudCBmb3IgdGhlIHNwZWNpZmllZCBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIHNlc3Npb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzZXNzaW9uIGZvciB3aGljaCB0aGUgZXZlbnQgb2NjdXJzLgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgb2JqZWN0IGJlaW5nICh1bilib3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1NMU2Vzc2lvbkJpbmRpbmdFdmVudChTU0xTZXNzaW9uIHNlc3Npb24sIFN0cmluZyBuYW1lKSB7CisgICAgICAgIHN1cGVyKHNlc3Npb24pOworICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGJpbmRpbmcgYmVpbmcgYWRkZWQgb3IgcmVtb3ZlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGJpbmRpbmcuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzZXNzaW9uIHRvIHdoaWNoIHRoZSBiaW5kaW5nIGlzIGFkZGVkIG9yIGZyb20gd2hpY2ggaXQgaXMKKyAgICAgKiByZW1vdmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc2Vzc2lvbiB0byB3aGljaCB0aGUgYmluZGluZyBpcyBhZGRlZCBvciBmcm9tIHdoaWNoIGl0IGlzCisgICAgICogICAgICAgICByZW1vdmVkLgorICAgICAqLworICAgIHB1YmxpYyBTU0xTZXNzaW9uIGdldFNlc3Npb24oKSB7CisgICAgICAgIHJldHVybiAoU1NMU2Vzc2lvbikgdGhpcy5zb3VyY2U7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDNhZDc0NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDQ0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lcjsKKworLyoqCisgKiBUaGUgaW50ZXJmYWNlIHRvIGJlIGltcGxlbWVudGVkIGJ5IGFueSBvYmplY3QgdGhhdCByZXF1aXJlcyBub3RpZmljYXRpb24gd2hlbgorICogZGF0YSBvYmplY3RzIGFyZSBib3VuZCB0byAob3IgdW5ib3VuZCBmcm9tKSBhbiB7QGNvZGUgU1NMU2Vzc2lvbn0uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgU1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lciBleHRlbmRzIEV2ZW50TGlzdGVuZXIgeworCisgICAgLyoqCisgICAgICogTm90aWZpZXMgdGhpcyBsaXN0ZW5lciB3aGVuIGEgdmFsdWUgaXMgYm91bmQgdG8gYW4ge0Bjb2RlIFNTTFNlc3Npb259LgorICAgICAqCisgICAgICogQHBhcmFtIGV2ZW50CisgICAgICogICAgICAgICAgICB0aGUgZXZlbnQgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB2YWx1ZUJvdW5kKFNTTFNlc3Npb25CaW5kaW5nRXZlbnQgZXZlbnQpOworCisgICAgLyoqCisgICAgICogTm90aWZpZXMgdGhpcyBsaXN0ZW5lciB3aGVuIGEgdmFsdWUgaXMgdW5ib3VuZCBmcm9tIGFuIHtAY29kZSBTU0xTZXNzaW9ufS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBldmVudAorICAgICAqICAgICAgICAgICAgdGhlIGV2ZW50IGRhdGEuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdmFsdWVVbmJvdW5kKFNTTFNlc3Npb25CaW5kaW5nRXZlbnQgZXZlbnQpOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xTZXNzaW9uQ29udGV4dC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvU1NMU2Vzc2lvbkNvbnRleHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMzkzMDcyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvU1NMU2Vzc2lvbkNvbnRleHQuamF2YQpAQCAtMCwwICsxLDgxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CisKKy8qKgorICogQSBjb2xsZWN0aW9uIG9mIHtAY29kZSBTU0xTZXNzaW9ufXMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgU1NMU2Vzc2lvbkNvbnRleHQgeworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaXRlcmFibGUgb2YgYWxsIHNlc3Npb24gaWRlbnRpZmllcnMgaW4gdGhpcyBzZXNzaW9uIGNvbnRleHQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGl0ZXJhYmxlIG9mIGFsbCBzZXNzaW9uIGlkZW50aWZpZXJzIGluIHRoaXMgc2Vzc2lvbiBjb250ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxieXRlW10+IGdldElkcygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2Vzc2lvbiBmb3IgdGhlIHNwZWNpZmllZCBzZXNzaW9uIGlkZW50aWZpZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2Vzc2lvbklkCisgICAgICogICAgICAgICAgICB0aGUgc2Vzc2lvbiBpZGVudGlmaWVyIG9mIHRoZSBzZXNzaW9uIHRvIGxvb2sgdXAuCisgICAgICogQHJldHVybiB0aGUgc2Vzc2lvbiBmb3IgdGhlIHNwZWNpZmllZCBzZXNzaW9uIGlkZW50aWZpZXIsIG9yIHtAY29kZSBudWxsfQorICAgICAqICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBzZXNzaW9uIGlkZW50aWZpZXIgZG9lcyBub3QgcmVmZXIgdG8gYSBzZXNzaW9uCisgICAgICogICAgICAgICBpbiB0aGlzIGNvbnRleHQuCisgICAgICovCisgICAgcHVibGljIFNTTFNlc3Npb24gZ2V0U2Vzc2lvbihieXRlW10gc2Vzc2lvbklkKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNpemUgb2YgdGhlIHNlc3Npb24gY2FjaGUgZm9yIHRoaXMgc2Vzc2lvbiBjb250ZXh0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc2l6ZSBvZiB0aGUgc2Vzc2lvbiBjYWNoZSBmb3IgdGhpcyBzZXNzaW9uIGNvbnRleHQsIG9yCisgICAgICogICAgICAgICB7QGNvZGUgemVyb30gaWYgdW5saW1pdGVkLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U2Vzc2lvbkNhY2hlU2l6ZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGltZW91dCBmb3Igc2Vzc2lvbnMgaW4gdGhpcyBzZXNzaW9uIGNvbnRleHQuIFNlc3Npb25zCisgICAgICogZXhjZWVkaW5nIHRoZSB0aW1lb3V0IGFyZSBpbnZhbGlkYXRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHRpbWVvdXQgaW4gc2Vjb25kcywgb3Ige0Bjb2RlIHplcm99IGlmIHVubGltaXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFNlc3Npb25UaW1lb3V0KCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzaXplIG9mIHRoZSBzZXNzaW9uIGNhY2hlIGZvciB0aGlzIHNlc3Npb24gY29udGV4dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzaXplCisgICAgICogICAgICAgICAgICB0aGUgc2l6ZSBvZiB0aGUgc2Vzc2lvbiBjYWNoZSwgb3Ige0Bjb2RlIHplcm99IGZvciB1bmxpbWl0ZWQKKyAgICAgKiAgICAgICAgICAgIGNhY2hlIHNpemUuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc2l6ZX0gaXMgbmVnYXRpdmUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2Vzc2lvbkNhY2hlU2l6ZShpbnQgc2l6ZSkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHRpbWVvdXQgZm9yIHNlc3Npb25zIGluIHRoaXMgY29udGV4dC4gU2Vzc2lvbnMgZXhjZWVkaW5nIHRoZQorICAgICAqIHRpbWVvdXQgYXJlIGludmFsaWRhdGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHNlY29uZHMKKyAgICAgKiAgICAgICAgICAgIHRoZSB0aW1lb3V0IGluIHNlY29uZHMsIG9yIHtAY29kZSB6ZXJvfSBpZiB1bmxpbWl0ZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgc2Vjb25kc30gaXMgbmVnYXRpdmUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2Vzc2lvblRpbWVvdXQoaW50IHNlY29uZHMpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xTb2NrZXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTFNvY2tldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJjODBiMjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9TU0xTb2NrZXQuamF2YQpAQCAtMCwwICsxLDMzMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuVW5rbm93bkhvc3RFeGNlcHRpb247CisKKy8qKgorICogVGhlIGV4dGVuc2lvbiBvZiB7QGNvZGUgU29ja2V0fSBwcm92aWRpbmcgc2VjdXJlIHByb3RvY29scyBsaWtlIFNTTCAoU2VjdXJlCisgKiBTb2NrZXQgTGF5ZXIiKSBvciBUTFMgKFRyYW5zcG9ydCBMYXllciBTZWN1cml0eSkuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTU0xTb2NrZXQgZXh0ZW5kcyBTb2NrZXQgeworCisgICAgLyoqCisgICAgICogT25seSB0byBiZSB1c2VkIGJ5IHN1YmNsYXNzZXMuCisgICAgICogPHA+CisgICAgICogQ3JlYXRlcyBhIFRDUCBzb2NrZXQuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNTTFNvY2tldCgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPbmx5IHRvIGJlIHVzZWQgYnkgc3ViY2xhc3Nlcy4KKyAgICAgKiA8cD4KKyAgICAgKiBDcmVhdGVzIGEgVENQIHNvY2tldCBjb25uZWN0aW9uIHRvIHRoZSBzcGVjaWZpZWQgaG9zdCBhdCB0aGUgc3BlY2lmaWVkCisgICAgICogcG9ydC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3N0CisgICAgICogICAgICAgICAgICB0aGUgaG9zdCBuYW1lIHRvIGNvbm5lY3QgdG8uCisgICAgICogQHBhcmFtIHBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IG51bWJlciB0byBjb25uZWN0IHRvLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBjcmVhdGluZyB0aGUgc29ja2V0IGZhaWxzLgorICAgICAqIEB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIGhvc3QgaXMgbm90IGtub3duLgorICAgICAqLworICAgIHByb3RlY3RlZCBTU0xTb2NrZXQoU3RyaW5nIGhvc3QsIGludCBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24sIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoaG9zdCwgcG9ydCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT25seSB0byBiZSB1c2VkIGJ5IHN1YmNsYXNzZXMuCisgICAgICogPHA+CisgICAgICogQ3JlYXRlcyBhIFRDUCBzb2NrZXQgY29ubmVjdGlvbiB0byB0aGUgc3BlY2lmaWVkIGFkZHJlc3MgYXQgdGhlIHNwZWNpZmllZAorICAgICAqIHBvcnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWRkcmVzcworICAgICAqICAgICAgICAgICAgdGhlIGFkZHJlc3MgdG8gY29ubmVjdCB0by4KKyAgICAgKiBAcGFyYW0gcG9ydAorICAgICAqICAgICAgICAgICAgdGhlIHBvcnQgbnVtYmVyIHRvIGNvbm5lY3QgdG8uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGNyZWF0aW5nIHRoZSBzb2NrZXQgZmFpbHMuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNTTFNvY2tldChJbmV0QWRkcmVzcyBhZGRyZXNzLCBpbnQgcG9ydCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoYWRkcmVzcywgcG9ydCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT25seSB0byBiZSB1c2VkIGJ5IHN1YmNsYXNzZXMuCisgICAgICogPHA+CisgICAgICogQ3JlYXRlcyBhIFRDUCBzb2NrZXQgY29ubmVjdGlvbiB0byB0aGUgc3BlY2lmaWVkIGhvc3QgYXQgdGhlIHNwZWNpZmllZAorICAgICAqIHBvcnQgd2l0aCB0aGUgY2xpZW50IHNpZGUgYm91bmQgdG8gdGhlIHNwZWNpZmllZCBhZGRyZXNzIGFuZCBwb3J0LgorICAgICAqCisgICAgICogQHBhcmFtIGhvc3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBob3N0IG5hbWUgdG8gY29ubmVjdCB0by4KKyAgICAgKiBAcGFyYW0gcG9ydAorICAgICAqICAgICAgICAgICAgdGhlIHBvcnQgbnVtYmVyIHRvIGNvbm5lY3QgdG8uCisgICAgICogQHBhcmFtIGNsaWVudEFkZHJlc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBjbGllbnQgYWRkcmVzcyB0byBiaW5kIHRvCisgICAgICogQHBhcmFtIGNsaWVudFBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBjbGllbnQgcG9ydCBudW1iZXIgdG8gYmluZCB0by4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgY3JlYXRpbmcgdGhlIHNvY2tldCBmYWlscy4KKyAgICAgKiBAdGhyb3dzIFVua25vd25Ib3N0RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBob3N0IGlzIG5vdCBrbm93bi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU1NMU29ja2V0KFN0cmluZyBob3N0LCBpbnQgcG9ydCwgSW5ldEFkZHJlc3MgY2xpZW50QWRkcmVzcywgaW50IGNsaWVudFBvcnQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoaG9zdCwgcG9ydCwgY2xpZW50QWRkcmVzcywgY2xpZW50UG9ydCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT25seSB0byBiZSB1c2VkIGJ5IHN1YmNsYXNzZXMuCisgICAgICogPHA+CisgICAgICogQ3JlYXRlcyBhIFRDUCBzb2NrZXQgY29ubmVjdGlvbiB0byB0aGUgc3BlY2lmaWVkIGFkZHJlc3MgYXQgdGhlIHNwZWNpZmllZAorICAgICAqIHBvcnQgd2l0aCB0aGUgY2xpZW50IHNpZGUgYm91bmQgdG8gdGhlIHNwZWNpZmllZCBhZGRyZXNzIGFuZCBwb3J0LgorICAgICAqCisgICAgICogQHBhcmFtIGFkZHJlc3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBhZGRyZXNzIHRvIGNvbm5lY3QgdG8uCisgICAgICogQHBhcmFtIHBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IG51bWJlciB0byBjb25uZWN0IHRvLgorICAgICAqIEBwYXJhbSBjbGllbnRBZGRyZXNzCisgICAgICogICAgICAgICAgICB0aGUgY2xpZW50IGFkZHJlc3MgdG8gYmluZCB0by4KKyAgICAgKiBAcGFyYW0gY2xpZW50UG9ydAorICAgICAqICAgICAgICAgICAgdGhlIGNsaWVudCBwb3J0IG51bWJlciB0byBiaW5kIHRvLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBjcmVhdGluZyB0aGUgc29ja2V0IGZhaWxzLgorICAgICAqLworICAgIHByb3RlY3RlZCBTU0xTb2NrZXQoSW5ldEFkZHJlc3MgYWRkcmVzcywgaW50IHBvcnQsIEluZXRBZGRyZXNzIGNsaWVudEFkZHJlc3MsIGludCBjbGllbnRQb3J0KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoYWRkcmVzcywgcG9ydCwgY2xpZW50QWRkcmVzcywgY2xpZW50UG9ydCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVW5zdXBwb3J0ZWQgZm9yIFNTTCBiZWNhdXNlIHJlYWRpbmcgZnJvbSBhbiBTU0wgc29ja2V0IG1heSByZXF1aXJlCisgICAgICogd3JpdGluZyB0byB0aGUgbmV0d29yay4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2h1dGRvd25JbnB1dCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVuc3VwcG9ydGVkIGZvciBTU0wgYmVjYXVzZSB3cml0aW5nIHRvIGFuIFNTTCBzb2NrZXQgbWF5IHJlcXVpcmUgcmVhZGluZworICAgICAqIGZyb20gdGhlIG5ldHdvcmsuCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHNodXRkb3duT3V0cHV0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZXMgb2YgdGhlIHN1cHBvcnRlZCBjaXBoZXIgc3VpdGVzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmdbXSBnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWVzIG9mIHRoZSBlbmFibGVkIGNpcGhlciBzdWl0ZXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZ1tdIGdldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG5hbWVzIG9mIHRoZSBjaXBoZXIgc3VpdGVzIHRvIGJlIGVuYWJsZWQuCisgICAgICogT25seSBjaXBoZXIgc3VpdGVzIHJldHVybmVkIGJ5IHtAbGluayAjZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCl9IGFyZQorICAgICAqIGFsbG93ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3VpdGVzCisgICAgICogICAgICAgICAgICB0aGUgbmFtZXMgb2YgdGhlIHRvIGJlIGVuYWJsZWQgY2lwaGVyIHN1aXRlcy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIG9uZSBvZiB0aGUgY2lwaGVyIHN1aXRlIG5hbWVzIGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RW5hYmxlZENpcGhlclN1aXRlcyhTdHJpbmdbXSBzdWl0ZXMpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZXMgb2YgdGhlIHN1cHBvcnRlZCBwcm90b2NvbHMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZ1tdIGdldFN1cHBvcnRlZFByb3RvY29scygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZXMgb2YgdGhlIGVuYWJsZWQgcHJvdG9jb2xzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmdbXSBnZXRFbmFibGVkUHJvdG9jb2xzKCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lcyBvZiB0aGUgcHJvdG9jb2xzIHRvIGJlIGVuYWJsZWQuIE9ubHkKKyAgICAgKiBwcm90b2NvbHMgcmV0dXJuZWQgYnkge0BsaW5rICNnZXRTdXBwb3J0ZWRQcm90b2NvbHMoKX0gYXJlIGFsbG93ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJvdG9jb2xzCisgICAgICogICAgICAgICAgICB0aGUgbmFtZXMgb2YgdGhlIHRvIGJlIGVuYWJsZWQgcHJvdG9jb2xzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgb25lIG9mIHRoZSBwcm90b2NvbHMgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRFbmFibGVkUHJvdG9jb2xzKFN0cmluZ1tdIHByb3RvY29scyk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgU1NMU2Vzc2lvbn0gZm9yIHRoaXMgY29ubmVjdGlvbi4gSWYgbmVjZXNzYXJ5LCBhCisgICAgICogaGFuZHNoYWtlIHdpbGwgYmUgaW5pdGlhdGVkLCBpbiB3aGljaCBjYXNlIHRoaXMgbWV0aG9kIHdpbGwgYmxvY2sgdW50aWwgdGhlIGhhbmRzaGFrZQorICAgICAqIGhhcyBiZWVuIGVzdGFibGlzaGVkLiBJZiB0aGUgaGFuZHNoYWtlIGZhaWxzLCBhbiBpbnZhbGlkIHNlc3Npb24gb2JqZWN0CisgICAgICogd2lsbCBiZSByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNlc3Npb24gb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTU0xTZXNzaW9uIGdldFNlc3Npb24oKTsKKworICAgIC8qKgorICAgICAqIFJlZ2lzdGVycyB0aGUgc3BlY2lmaWVkIGxpc3RlbmVyIHRvIHJlY2VpdmUgbm90aWZpY2F0aW9uIG9uIGNvbXBsZXRpb24gb2YgYQorICAgICAqIGhhbmRzaGFrZSBvbiB0aGlzIGNvbm5lY3Rpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGlzdGVuZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBsaXN0ZW5lciB0byByZWdpc3Rlci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBsaXN0ZW5lcn0gaXMge0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGFkZEhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyKEhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyIGxpc3RlbmVyKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCBoYW5kc2hha2UgY29tcGxldGlvbiBsaXN0ZW5lci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsaXN0ZW5lcgorICAgICAqICAgICAgICAgICAgdGhlIGxpc3RlbmVyIHRvIHJlbW92ZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgbGlzdGVuZXIgaXMgbm90IHJlZ2lzdGVyZWQgb3Ige0Bjb2RlIG51bGx9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHJlbW92ZUhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyKEhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyIGxpc3RlbmVyKTsKKworICAgIC8qKgorICAgICAqIFN0YXJ0cyBhIG5ldyBTU0wgaGFuZHNoYWtlIG9uIHRoaXMgY29ubmVjdGlvbi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc3RhcnRIYW5kc2hha2UoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHdoZXRoZXIgdGhpcyBjb25uZWN0aW9uIHNob3VsZCBhY3QgaW4gY2xpZW50IG1vZGUgd2hlbiBoYW5kc2hha2luZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb2RlCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBjb25uZWN0aW9uIHNob3VsZCBhY3QgaW4gY2xpZW50IG1vZGUsCisgICAgICogICAgICAgICAgICB7QGNvZGUgZmFsc2V9IGlmIG5vdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRVc2VDbGllbnRNb2RlKGJvb2xlYW4gbW9kZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBjb25uZWN0aW9uIHdpbGwgYWN0IGluIGNsaWVudCBtb2RlIHdoZW4gaGFuZHNoYWtpbmcuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZ2V0VXNlQ2xpZW50TW9kZSgpOworCisgICAgLyoqCisgICAgICogU2V0cyB3aGV0aGVyIHRoZSBzZXJ2ZXIgc2hvdWxkIHJlcXVpcmUgY2xpZW50IGF1dGhlbnRpY2F0aW9uLiBUaGlzCisgICAgICogZG9lcyBub3QgYXBwbHkgdG8gc29ja2V0cyBpbiB7QGxpbmsgI2dldFVzZUNsaWVudE1vZGUoKSBjbGllbnQgbW9kZX0uCisgICAgICogQ2xpZW50IGF1dGhlbnRpY2F0aW9uIGlzIG9uZSBvZiB0aGUgZm9sbG93aW5nOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+YXV0aGVudGljYXRpb24gcmVxdWlyZWQ8L2xpPgorICAgICAqIDxsaT5hdXRoZW50aWNhdGlvbiByZXF1ZXN0ZWQ8L2xpPgorICAgICAqIDxsaT5ubyBhdXRoZW50aWNhdGlvbiBuZWVkZWQ8L2xpPgorICAgICAqIDwvdWw+CisgICAgICogVGhpcyBtZXRob2Qgb3ZlcnJpZGVzIHRoZSBzZXR0aW5nIG9mIHtAbGluayAjc2V0V2FudENsaWVudEF1dGgoYm9vbGVhbil9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldE5lZWRDbGllbnRBdXRoKGJvb2xlYW4gbmVlZCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHdoZXRoZXIgdGhlIHNlcnZlciBzaG91bGQgcmVxdWVzdCBjbGllbnQgYXV0aGVudGljYXRpb24uIFVubGlrZQorICAgICAqIHtAbGluayAjc2V0TmVlZENsaWVudEF1dGh9IHRoaXMgd29uJ3Qgc3RvcCB0aGUgbmVnb3RpYXRpb24gaWYgdGhlIGNsaWVudAorICAgICAqIGRvZXNuJ3QgYXV0aGVudGljYXRlLiBUaGlzIGRvZXMgbm90IGFwcGx5IHRvIHNvY2tldHMgaW4ge0BsaW5rCisgICAgICogI2dldFVzZUNsaWVudE1vZGUoKSBjbGllbnQgbW9kZX0uVGhlIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpcyBvbmUgb2Y6CisgICAgICogPHVsPgorICAgICAqIDxsaT5hdXRoZW50aWNhdGlvbiByZXF1aXJlZDwvbGk+CisgICAgICogPGxpPmF1dGhlbnRpY2F0aW9uIHJlcXVlc3RlZDwvbGk+CisgICAgICogPGxpPm5vIGF1dGhlbnRpY2F0aW9uIG5lZWRlZDwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiBUaGlzIG1ldGhvZCBvdmVycmlkZXMgdGhlIHNldHRpbmcgb2Yge0BsaW5rICNzZXROZWVkQ2xpZW50QXV0aChib29sZWFuKX0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0V2FudENsaWVudEF1dGgoYm9vbGVhbiB3YW50KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc2VydmVyIHNvY2tldCBzaG91bGQgcmVxdWlyZSBjbGllbnQgYXV0aGVudGljYXRpb24uCisgICAgICogVGhpcyBkb2VzIG5vdCBhcHBseSB0byBzb2NrZXRzIGluIHtAbGluayAjZ2V0VXNlQ2xpZW50TW9kZSgpIGNsaWVudAorICAgICAqIG1vZGV9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGdldE5lZWRDbGllbnRBdXRoKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNlcnZlciBzaG91bGQgcmVxdWVzdCBjbGllbnQgYXV0aGVudGljYXRpb24uIFRoaXMKKyAgICAgKiBkb2VzIG5vdCBhcHBseSB0byBzb2NrZXRzIGluIHtAbGluayAjZ2V0VXNlQ2xpZW50TW9kZSgpIGNsaWVudCBtb2RlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBnZXRXYW50Q2xpZW50QXV0aCgpOworCisgICAgLyoqCisgICAgICogU2V0cyB3aGV0aGVyIG5ldyBTU0wgc2Vzc2lvbnMgbWF5IGJlIGNyZWF0ZWQgYnkgdGhpcyBzb2NrZXQgb3IgaWYKKyAgICAgKiBleGlzdGluZyBzZXNzaW9ucyBtdXN0IGJlIHJldXNlZC4gSWYge0Bjb2RlIGZsYWd9IGlzIGZhbHNlIGFuZCB0aGVyZSBhcmUKKyAgICAgKiBubyBzZXNzaW9ucyB0byByZXN1bWUsIGhhbmRzaGFraW5nIHdpbGwgZmFpbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmbGFnIHtAY29kZSB0cnVlfSBpZiBuZXcgc2Vzc2lvbnMgbWF5IGJlIGNyZWF0ZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKGJvb2xlYW4gZmxhZyk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgbmV3IFNTTCBzZXNzaW9ucyBtYXkgYmUgY3JlYXRlZCBieSB0aGlzIHNvY2tldCBvciBpZgorICAgICAqIGV4aXN0aW5nIHNlc3Npb25zIG11c3QgYmUgcmV1c2VkLgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgbmV3IHNlc3Npb25zIG1heSBiZSBjcmVhdGVkLCBvdGhlcndpc2UKKyAgICAgKiAgICAgICAgIHtAY29kZSBmYWxzZX0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IFNTTFBhcmFtZXRlcnMgYmFzZWQgb24gdGhpcyBTU0xTb2NrZXQncyBjdXJyZW50CisgICAgICogY2lwaGVyIHN1aXRlcywgcHJvdG9jb2xzLCBhbmQgY2xpZW50IGF1dGhlbnRpY2F0aW9uIHNldHRpbmdzLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBTU0xQYXJhbWV0ZXJzIGdldFNTTFBhcmFtZXRlcnMoKSB7CisgICAgICAgIFNTTFBhcmFtZXRlcnMgcCA9IG5ldyBTU0xQYXJhbWV0ZXJzKCk7CisgICAgICAgIHAuc2V0Q2lwaGVyU3VpdGVzKGdldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKSk7CisgICAgICAgIHAuc2V0UHJvdG9jb2xzKGdldEVuYWJsZWRQcm90b2NvbHMoKSk7CisgICAgICAgIHAuc2V0TmVlZENsaWVudEF1dGgoZ2V0TmVlZENsaWVudEF1dGgoKSk7CisgICAgICAgIHAuc2V0V2FudENsaWVudEF1dGgoZ2V0V2FudENsaWVudEF1dGgoKSk7CisgICAgICAgIHJldHVybiBwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdmFyaW91cyBTU0wgaGFuZHNoYWtlIHBhcmFtZXRlcnMgYmFzZWQgb24gdGhlIFNTTFBhcmFtZXRlcgorICAgICAqIGFyZ3VtZW50LiBTcGVjaWZpY2FsbHksIHNldHMgdGhlIFNTTFNvY2tldCdzIGVuYWJsZWQgY2lwaGVyCisgICAgICogc3VpdGVzIGlmIHRoZSBwYXJhbWV0ZXIncyBjaXBoZXIgc3VpdGVzIGFyZSBub24tbnVsbC4gU2ltaWxhcmx5CisgICAgICogc2V0cyB0aGUgZW5hYmxlZCBwcm90b2NvbHMuIElmIHRoZSBwYXJhbWV0ZXJzIHNwZWNpZnkgdGhlIHdhbnQKKyAgICAgKiBvciBuZWVkIGZvciBjbGllbnQgYXV0aGVudGljYXRpb24sIHRob3NlIHJlcXVpcmVtZW50cyBhcmUgc2V0CisgICAgICogb24gdGhlIFNTTFNvY2tldCwgb3RoZXJ3aXNlIGJvdGggYXJlIHNldCB0byBmYWxzZS4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U1NMUGFyYW1ldGVycyhTU0xQYXJhbWV0ZXJzIHApIHsKKyAgICAgICAgU3RyaW5nW10gY2lwaGVyU3VpdGVzID0gcC5nZXRDaXBoZXJTdWl0ZXMoKTsKKyAgICAgICAgaWYgKGNpcGhlclN1aXRlcyAhPSBudWxsKSB7CisgICAgICAgICAgICBzZXRFbmFibGVkQ2lwaGVyU3VpdGVzKGNpcGhlclN1aXRlcyk7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nW10gcHJvdG9jb2xzID0gcC5nZXRQcm90b2NvbHMoKTsKKyAgICAgICAgaWYgKHByb3RvY29scyAhPSBudWxsKSB7CisgICAgICAgICAgICBzZXRFbmFibGVkUHJvdG9jb2xzKHByb3RvY29scyk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHAuZ2V0TmVlZENsaWVudEF1dGgoKSkgeworICAgICAgICAgICAgc2V0TmVlZENsaWVudEF1dGgodHJ1ZSk7CisgICAgICAgIH0gZWxzZSBpZiAocC5nZXRXYW50Q2xpZW50QXV0aCgpKSB7CisgICAgICAgICAgICBzZXRXYW50Q2xpZW50QXV0aCh0cnVlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHNldFdhbnRDbGllbnRBdXRoKGZhbHNlKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTFNvY2tldEZhY3RvcnkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1NTTFNvY2tldEZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMDdkMGZkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvU1NMU29ja2V0RmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMTI0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5OworCisvKioKKyAqIFRoZSBhYnN0cmFjdCBmYWN0b3J5IGltcGxlbWVudGF0aW9uIHRvIGNyZWF0ZSB7QGNvZGUgU1NMU29ja2V0fXMuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTU0xTb2NrZXRGYWN0b3J5IGV4dGVuZHMgU29ja2V0RmFjdG9yeSB7CisgICAgLy8gRklYTUUgRVhQT1JUIENPTlRST0wKKworICAgIC8vIFRoZSBkZWZhdWx0IFNTTCBzb2NrZXQgZmFjdG9yeQorICAgIHByaXZhdGUgc3RhdGljIFNvY2tldEZhY3RvcnkgZGVmYXVsdFNvY2tldEZhY3Rvcnk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZGVmYXVsdE5hbWU7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHtAY29kZSBTU0xTb2NrZXRGYWN0b3J5fSBpbnN0YW5jZS4gVGhlIGRlZmF1bHQgaXMKKyAgICAgKiBkZWZpbmVkIGJ5IHRoZSBzZWN1cml0eSBwcm9wZXJ0eSB7QGNvZGUgJ3NzbC5Tb2NrZXRGYWN0b3J5LnByb3ZpZGVyJ30uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBkZWZhdWx0IHNzbCBzb2NrZXQgZmFjdG9yeSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBTb2NrZXRGYWN0b3J5IGdldERlZmF1bHQoKSB7CisgICAgICAgIGlmIChkZWZhdWx0U29ja2V0RmFjdG9yeSAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZGVmYXVsdFNvY2tldEZhY3Rvcnk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRlZmF1bHROYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIGRlZmF1bHROYW1lID0gU2VjdXJpdHkuZ2V0UHJvcGVydHkoInNzbC5Tb2NrZXRGYWN0b3J5LnByb3ZpZGVyIik7CisgICAgICAgICAgICBpZiAoZGVmYXVsdE5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIENsYXNzTG9hZGVyIGNsID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgICAgICAgICBpZiAoY2wgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBjbCA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIENsYXNzPD8+IHNmYyA9IENsYXNzLmZvck5hbWUoZGVmYXVsdE5hbWUsIHRydWUsIGNsKTsKKyAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFNvY2tldEZhY3RvcnkgPSAoU29ja2V0RmFjdG9yeSkgc2ZjLm5ld0luc3RhbmNlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmxvZ0UoIlByb2JsZW0gY3JlYXRpbmcgIiArIGRlZmF1bHROYW1lLCBlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoZGVmYXVsdFNvY2tldEZhY3RvcnkgPT0gbnVsbCkgeworICAgICAgICAgICAgU1NMQ29udGV4dCBjb250ZXh0OworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjb250ZXh0ID0gU1NMQ29udGV4dC5nZXREZWZhdWx0KCk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGNvbnRleHQgPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGNvbnRleHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGRlZmF1bHRTb2NrZXRGYWN0b3J5ID0gY29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRlZmF1bHRTb2NrZXRGYWN0b3J5ID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIFVzZSBpbnRlcm5hbCBpbXBsZW1lbnRhdGlvbgorICAgICAgICAgICAgZGVmYXVsdFNvY2tldEZhY3RvcnkgPSBuZXcgRGVmYXVsdFNTTFNvY2tldEZhY3RvcnkoIk5vIFNTTFNvY2tldEZhY3RvcnkgaW5zdGFsbGVkIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRlZmF1bHRTb2NrZXRGYWN0b3J5OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFNTTFNvY2tldEZhY3Rvcnl9LgorICAgICAqLworICAgIHB1YmxpYyBTU0xTb2NrZXRGYWN0b3J5KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWVzIG9mIHRoZSBjaXBoZXIgc3VpdGVzIHRoYXQgYXJlIGVuYWJsZWQgYnkgZGVmYXVsdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWVzIG9mIHRoZSBjaXBoZXIgc3VpdGVzIHRoYXQgYXJlIGVuYWJsZWQgYnkgZGVmYXVsdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nW10gZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZXMgb2YgdGhlIGNpcGhlciBzdWl0ZXMgdGhhdCBhcmUgc3VwcG9ydGVkIGFuZCBjb3VsZCBiZQorICAgICAqIGVuYWJsZWQgZm9yIGFuIFNTTCBjb25uZWN0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZXMgb2YgdGhlIGNpcGhlciBzdWl0ZXMgdGhhdCBhcmUgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmdbXSBnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4ge0Bjb2RlIFNTTFNvY2tldH0gb3ZlciB0aGUgc3BlY2lmaWVkIHNvY2tldCB0aGF0IGlzIGNvbm5lY3RlZAorICAgICAqIHRvIHRoZSBzcGVjaWZpZWQgaG9zdCBhdCB0aGUgc3BlY2lmaWVkIHBvcnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcworICAgICAqICAgICAgICAgICAgdGhlIHNvY2tldC4KKyAgICAgKiBAcGFyYW0gaG9zdAorICAgICAqICAgICAgICAgICAgdGhlIGhvc3QuCisgICAgICogQHBhcmFtIHBvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwb3J0IG51bWJlci4KKyAgICAgKiBAcGFyYW0gYXV0b0Nsb3NlCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gaWYgc29ja2V0IHtAY29kZSBzfSBzaG91bGQgYmUgY2xvc2VkIHdoZW4gdGhlCisgICAgICogICAgICAgICAgICBjcmVhdGVkIHNvY2tldCBpcyBjbG9zZWQsIHtAY29kZSBmYWxzZX0gaWYgdGhlIHNvY2tldAorICAgICAqICAgICAgICAgICAge0Bjb2RlIHN9IHNob3VsZCBiZSBsZWZ0IG9wZW4uCisgICAgICogQHJldHVybiB0aGUgY3JlYXRlcyBzc2wgc29ja2V0LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBjcmVhdGluZyB0aGUgc29ja2V0IGZhaWxzLgorICAgICAqIEB0aHJvd3MgamF2YS5uZXQuVW5rbm93bkhvc3RFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaG9zdCBpcyB1bmtub3duLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTb2NrZXQgY3JlYXRlU29ja2V0KFNvY2tldCBzLCBTdHJpbmcgaG9zdCwgaW50IHBvcnQsIGJvb2xlYW4gYXV0b0Nsb3NlKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvVHJ1c3RNYW5hZ2VyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9UcnVzdE1hbmFnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YmRiMTZiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvVHJ1c3RNYW5hZ2VyLmphdmEKQEAgLTAsMCArMSwyOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5uZXQuc3NsOworCisvKioKKyAqIFRoZSBtYXJrZXIgaW50ZXJmYWNlIGZvciBKU1NFIHRydXN0IG1hbmFnZXJzLiBUaGUgcHVycG9zZSBpcyB0byBncm91cCB0cnVzdAorICogbWFuYWdlcnMuIFRoZSByZXNwb25zaWJpbGl0eSBhIHRydXN0IG1hbmFnZXIgaXMgdG8gaGFuZGxlIHRoZSB0cnVzdCBkYXRhIHVzZWQgdG8KKyAqIG1ha2UgdHJ1c3QgZGVjaXNpb25zIGZvciBkZWNpZGluZyB3aGV0aGVyIGNyZWRlbnRpYWxzIG9mIGEgcGVlciBzaG91bGQgYmUKKyAqIGFjY2VwdGVkLAorICogQHNlZSBUcnVzdE1hbmFnZXJGYWN0b3J5CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgVHJ1c3RNYW5hZ2VyIHsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1RydXN0TWFuYWdlckZhY3RvcnkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1RydXN0TWFuYWdlckZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZjNiZjhjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvVHJ1c3RNYW5hZ2VyRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMjE4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5mb3J0cmVzcy5FbmdpbmU7CisKKy8qKgorICogVGhlIGZhY3RvcnkgZm9yIHtAY29kZSBUcnVzdE1hbmFnZXJ9cyBiYXNlZCBvbiB7QGNvZGUgS2V5U3RvcmV9IG9yIHByb3ZpZGVyCisgKiBzcGVjaWZpYyBpbXBsZW1lbnRhdGlvbi4KKyAqLworcHVibGljIGNsYXNzIFRydXN0TWFuYWdlckZhY3RvcnkgeworICAgIC8vIFN0b3JlIFRydXN0TWFuYWdlciBzZXJ2aWNlIG5hbWUKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VSVklDRSA9ICJUcnVzdE1hbmFnZXJGYWN0b3J5IjsKKworICAgIC8vIFVzZWQgdG8gYWNjZXNzIGNvbW1vbiBlbmdpbmUgZnVuY3Rpb25hbGl0eQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEVuZ2luZSBFTkdJTkUgPSBuZXcgRW5naW5lKFNFUlZJQ0UpOworCisgICAgLy8gU3RvcmUgZGVmYXVsdCBwcm9wZXJ0eSBuYW1lCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZTkFNRSA9ICJzc2wuVHJ1c3RNYW5hZ2VyRmFjdG9yeS5hbGdvcml0aG0iOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBhbGdvcml0aG0gbmFtZSBmb3IgdGhlIHtAY29kZSBUcnVzdE1hbmFnZXJGYWN0b3J5fS4gVGhlCisgICAgICogZGVmYXVsdCBhbGdvcml0aG0gbmFtZSBpcyBzcGVjaWZpZWQgYnkgdGhlIHNlY3VyaXR5IHByb3BlcnR5CisgICAgICoge0Bjb2RlICdzc2wuVHJ1c3RNYW5hZ2VyRmFjdG9yeS5hbGdvcml0aG0nfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGRlZmF1bHQgYWxnb3JpdGhtIG5hbWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgZ2V0RGVmYXVsdEFsZ29yaXRobSgpIHsKKyAgICAgICAgcmV0dXJuIFNlY3VyaXR5LmdldFByb3BlcnR5KFBST1BFUlRZTkFNRSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgVHJ1c3RNYW5hZ2VyRmFjdG9yeX0gaW5zdGFuY2UgZm9yIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB0cnVzdCBtYW5hZ2VtZW50IGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIHRoZSByZXF1ZXN0ZWQgdHJ1c3QgbWFuYWdlbWVudCBhbGdvcml0aG0uCisgICAgICogQHJldHVybiBhIHRydXN0IG1hbmFnZXIgZmFjdG9yeSBmb3IgdGhlIHJlcXVlc3RlZCBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBubyBpbnN0YWxsZWQgcHJvdmlkZXIgY2FuIHByb3ZpZGUgdGhlIHJlcXVlc3RlZCBhbGdvcml0aG0uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHtAY29kZSBhbGdvcml0aG19IGlzIHtAY29kZSBudWxsfSAoaW5zdGVhZCBvZgorICAgICAqICAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBhcyBpbiAxLjQgcmVsZWFzZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRydXN0TWFuYWdlckZhY3RvcnkgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoYWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiYWxnb3JpdGhtIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBFbmdpbmUuU3BpQW5kUHJvdmlkZXIgc2FwID0gRU5HSU5FLmdldEluc3RhbmNlKGFsZ29yaXRobSwgbnVsbCk7CisgICAgICAgIHJldHVybiBuZXcgVHJ1c3RNYW5hZ2VyRmFjdG9yeSgoVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaSkgc2FwLnNwaSwgc2FwLnByb3ZpZGVyLCBhbGdvcml0aG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFRydXN0TWFuYWdlckZhY3Rvcnl9IGluc3RhbmNlIGZvciB0aGUgc3BlY2lmaWVkCisgICAgICogdHJ1c3QgbWFuYWdlbWVudCBhbGdvcml0aG0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlcXVlc3RlZCB0cnVzdCBtYW5hZ2VtZW50IGFsZ29yaXRobSBuYW1lLgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIHRoYXQgcHJvdmlkZXMgdGhlIHJlcXVlc3RlZAorICAgICAqICAgICAgICAgICAgYWxnb3JpdGhtLgorICAgICAqIEByZXR1cm4gYSB0cnVzdCBtYW5hZ2VyIGZhY3RvcnkgZm9yIHRoZSByZXF1ZXN0ZWQgYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBjYW5ub3QgcHJvdmlkZSB0aGUgcmVxdWVzdGVkCisgICAgICogICAgICAgICAgICAgYWxnb3JpdGhtLgorICAgICAqIEB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyIGRvZXMgbm90IGV4aXN0LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB7QGNvZGUgYWxnb3JpdGhtfSBpcyB7QGNvZGUgbnVsbH0gKGluc3RlYWQgb2YKKyAgICAgKiAgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYXMgaW4gMS40IHJlbGVhc2UpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBUcnVzdE1hbmFnZXJGYWN0b3J5IGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcikKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKChwcm92aWRlciA9PSBudWxsKSB8fCAocHJvdmlkZXIubGVuZ3RoKCkgPT0gMCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlByb3ZpZGVyIGlzIG51bGwgb3IgZW1wdHkiKTsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBpbXBQcm92aWRlciA9IFNlY3VyaXR5LmdldFByb3ZpZGVyKHByb3ZpZGVyKTsKKyAgICAgICAgaWYgKGltcFByb3ZpZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbihwcm92aWRlcik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEluc3RhbmNlKGFsZ29yaXRobSwgaW1wUHJvdmlkZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFRydXN0TWFuYWdlckZhY3Rvcnl9IGluc3RhbmNlIGZvciB0aGUgc3BlY2lmaWVkCisgICAgICogdHJ1c3QgbWFuYWdlbWVudCBhbGdvcml0aG0gZnJvbSB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGFsZ29yaXRobQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHJlcXVlc3RlZCBrZXkgbWFuYWdlbWVudCBhbGdvcml0aG0gbmFtZS4KKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm92aWRlciB0aGF0IHByb3ZpZGVzIHRoZSByZXF1ZXN0ZWQgYWxnb3JpdGhtLgorICAgICAqIEByZXR1cm4gYSBrZXkgbWFuYWdlciBmYWN0b3J5IGZvciB0aGUgcmVxdWVzdGVkIGFsZ29yaXRobS4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgY2Fubm90IHByb3ZpZGUgdGhlIHJlcXVlc3RlZAorICAgICAqICAgICAgICAgICAgIGFsZ29yaXRobS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYge0Bjb2RlIGFsZ29yaXRobX0gaXMge0Bjb2RlIG51bGx9IChpbnN0ZWFkIG9mCisgICAgICogICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGFzIGluIDEuNCByZWxlYXNlKQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHJ1c3RNYW5hZ2VyRmFjdG9yeSBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBQcm92aWRlciBwcm92aWRlcikKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiUHJvdmlkZXIgaXMgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChhbGdvcml0aG0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJhbGdvcml0aG0gaXMgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIE9iamVjdCBzcGkgPSBFTkdJTkUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBwcm92aWRlciwgbnVsbCk7CisgICAgICAgIHJldHVybiBuZXcgVHJ1c3RNYW5hZ2VyRmFjdG9yeSgoVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaSkgc3BpLCBwcm92aWRlciwgYWxnb3JpdGhtKTsKKyAgICB9CisKKyAgICAvLyBTdG9yZSB1c2VkIHByb3ZpZGVyCisgICAgcHJpdmF0ZSBmaW5hbCBQcm92aWRlciBwcm92aWRlcjsKKworICAgIC8vIFN0b3JlIHVzZWQgVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaSBpbXBsZW1lbnRhdGlvbgorICAgIHByaXZhdGUgZmluYWwgVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaSBzcGlJbXBsOworCisgICAgLy8gU3RvcmUgdXNlZCBhbGdvcml0aG0KKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBhbGdvcml0aG07CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBUcnVzdE1hbmFnZXJGYWN0b3J5fSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmYWN0b3J5U3BpCisgICAgICogICAgICAgICAgICB0aGUgaW1wbGVtZW50YXRpb24gZGVsZWdhdGUuCisgICAgICogQHBhcmFtIHByb3ZpZGVyCisgICAgICogICAgICAgICAgICB0aGUgcHJvdmlkZXIKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICogICAgICAgICAgICB0aGUgYWxnb3JpdGhtIG5hbWUuCisgICAgICovCisgICAgcHJvdGVjdGVkIFRydXN0TWFuYWdlckZhY3RvcnkoVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaSBmYWN0b3J5U3BpLCBQcm92aWRlciBwcm92aWRlciwKKyAgICAgICAgICAgIFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgdGhpcy5wcm92aWRlciA9IHByb3ZpZGVyOworICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICAgICAgdGhpcy5zcGlJbXBsID0gZmFjdG9yeVNwaTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoaXMge0Bjb2RlIFRydXN0TWFuYWdlckZhY3Rvcnl9IGFsZ29yaXRobQorICAgICAqIGltcGxlbWVudGF0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGlzIHtAY29kZSBUcnVzdE1hbmFnZXJGYWN0b3J5fSBhbGdvcml0aG0KKyAgICAgKiAgICAgICAgIGltcGxlbWVudGF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICByZXR1cm4gYWxnb3JpdGhtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByb3ZpZGVyIGZvciB0aGlzIHtAY29kZSBUcnVzdE1hbmFnZXJGYWN0b3J5fSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByb3ZpZGVyIGZvciB0aGlzIHtAY29kZSBUcnVzdE1hbmFnZXJGYWN0b3J5fSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgUHJvdmlkZXIgZ2V0UHJvdmlkZXIoKSB7CisgICAgICAgIHJldHVybiBwcm92aWRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIGZhY3RvcnkgaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGtleXN0b3JlIGFzIHNvdXJjZQorICAgICAqIG9mIGNlcnRpZmljYXRlIGF1dGhvcml0aWVzIGFuZCB0cnVzdCBtYXRlcmlhbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrcworICAgICAqICAgICAgICAgICAgdGhlIGtleXN0b3JlIG9yIHtAY29kZSBudWxsfS4KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGluaXRpYWxpemF0aW9uIGZhaWxzLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGluaXQoS2V5U3RvcmUga3MpIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIHNwaUltcGwuZW5naW5lSW5pdChrcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyBmYWN0b3J5IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBwcm92aWRlci1zcGVjaWZpYworICAgICAqIHBhcmFtZXRlcnMgZm9yIGEgc291cmNlIG9mIHRydXN0IG1hdGVyaWFsLgorICAgICAqCisgICAgICogQHBhcmFtIHNwZWMKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm92aWRlci1zcGVjaWZpYyBwYXJhbWV0ZXJzLgorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBpbml0aWFsaXphdGlvbiBmYWlscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBpbml0KE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyBzcGVjKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBzcGlJbXBsLmVuZ2luZUluaXQoc3BlYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGlzdCBvZiB7QGNvZGUgVHJ1c3RNYW5hZ2VyfXMgd2l0aCBvbmUgZW50cnkgZm9yIGVhY2ggdHlwZQorICAgICAqIG9mIHRydXN0IG1hdGVyaWFsLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGlzdCBvZiB7QGNvZGUgVHJ1c3RNYW5hZ2VyfXMKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgVHJ1c3RNYW5hZ2VyW10gZ2V0VHJ1c3RNYW5hZ2VycygpIHsKKyAgICAgICAgcmV0dXJuIHNwaUltcGwuZW5naW5lR2V0VHJ1c3RNYW5hZ2VycygpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcwMDMzZTkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9UcnVzdE1hbmFnZXJGYWN0b3J5U3BpLmphdmEKQEAgLTAsMCArMSw2NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZUV4Y2VwdGlvbjsKKworLyoqCisgKiBUaGUgPGk+U2VydmljZSBQcm92aWRlciBJbnRlcmZhY2U8L2k+IChTUEkpIGZvciB0aGUKKyAqIHtAY29kZSBUcnVzdE1hbmFnZXJGYWN0b3J5fSBjbGFzcy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFRydXN0TWFuYWdlckZhY3RvcnlTcGkgeworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaX0gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIFRydXN0TWFuYWdlckZhY3RvcnlTcGkoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyBmYWN0b3J5IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBrZXlzdG9yZSBhcyBzb3VyY2UKKyAgICAgKiBvZiBjZXJ0aWZpY2F0ZSBhdXRob3JpdGllcyBhbmQgdHJ1c3QgbWF0ZXJpYWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga3MKKyAgICAgKiAgICAgICAgICAgIHRoZSBrZXlzdG9yZSBvciB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBpbml0aWFsaXphdGlvbiBmYWlscy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBlbmdpbmVJbml0KEtleVN0b3JlIGtzKSB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIGZhY3RvcnkgaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHByb3ZpZGVyLXNwZWNpZmljCisgICAgICogcGFyYW1ldGVycyBmb3IgYSBzb3VyY2Ugb2YgdHJ1c3QgbWF0ZXJpYWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3BlYworICAgICAqICAgICAgICAgICAgdGhlIHByb3ZpZGVyLXNwZWNpZmljIHBhcmFtZXRlcnMuCisgICAgICogQHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGluaXRpYWxpemF0aW9uIGZhaWxzLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGVuZ2luZUluaXQoTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzIHNwZWMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxpc3Qgb2Yge0Bjb2RlIFRydXN0TWFuYWdlcn1zIHdpdGggb25lIGVudHJ5IGZvciBlYWNoIHR5cGUKKyAgICAgKiBvZiB0cnVzdCBtYXRlcmlhbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxpc3Qgb2Yge0Bjb2RlIFRydXN0TWFuYWdlcn1zCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IFRydXN0TWFuYWdlcltdIGVuZ2luZUdldFRydXN0TWFuYWdlcnMoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1g1MDlFeHRlbmRlZEtleU1hbmFnZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1g1MDlFeHRlbmRlZEtleU1hbmFnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ODc3Zjg3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvWDUwOUV4dGVuZGVkS2V5TWFuYWdlci5qYXZhCkBAIC0wLDAgKzEsNzUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworCisvKioKKyAqIFRoZSBhYnN0cmFjdCBleHRlbnNpb24gZm9yIHRoZSB7QGNvZGUgWDUwOUtleU1hbmFnZXJ9IGludGVyZmFjZS4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFg1MDlFeHRlbmRlZEtleU1hbmFnZXIgaW1wbGVtZW50cyBYNTA5S2V5TWFuYWdlciB7CisKKyAgICAvKioKKyAgICAgKiBUbyBiZSB1c2VkIGJ5IHN1YmNsYXNzZXMgb25seS4KKyAgICAgKiA8cD4KKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyfSBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgWDUwOUV4dGVuZGVkS2V5TWFuYWdlcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaG9vc2VzIGFuIGFsaWFzIGZvciB0aGUgY2xpZW50IHNpZGUgb2YgYW4gU1NMIGNvbm5lY3Rpb24gdG8gYXV0aGVudGljYXRlCisgICAgICogaXQgd2l0aCB0aGUgc3BlY2lmaWVkIHB1YmxpYyBrZXkgdHlwZSBhbmQgY2VydGlmaWNhdGUgaXNzdWVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXlUeXBlCisgICAgICogICAgICAgICAgICB0aGUgbGlzdCBvZiBwdWJsaWMga2V5IGFsZ29yaXRobSBuYW1lcy4KKyAgICAgKiBAcGFyYW0gaXNzdWVycworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGUgaXNzdWVycywgb3Ige0Bjb2RlIG51bGx9IGlmIGFueSBpc3N1ZXIKKyAgICAgKiAgICAgICAgICAgIHdpbGwgZG8uCisgICAgICogQHBhcmFtIGVuZ2luZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBTU0xFbmdpbmV9IGZvciB0aGUgY29ubmVjdGlvbiwgb3Ige0Bjb2RlIG51bGx9IGlmCisgICAgICogICAgICAgICAgICBubyBlbmdpbmUgaXMgcHJlZGVmaW5lZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhbGlhcyBuYW1lIG9mIGEgbWF0Y2hpbmcga2V5IG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSBhcmUgbm8KKyAgICAgKiAgICAgICAgIG1hdGNoZXMuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBjaG9vc2VFbmdpbmVDbGllbnRBbGlhcyhTdHJpbmdbXSBrZXlUeXBlLAorICAgICAgICAgICAgUHJpbmNpcGFsW10gaXNzdWVycywgU1NMRW5naW5lIGVuZ2luZSkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaG9vc2VzIGFuIGFsaWFzIGZvciB0aGUgc2VydmVyIHNpZGUgb2YgYW4gU1NMIGNvbm5lY3Rpb24gdG8gYXV0aGVudGljYXRlCisgICAgICogaXQgd2l0aCB0aGUgc3BlY2lmaWVkIHB1YmxpYyBrZXkgdHlwZSBhbmQgY2VydGlmaWNhdGUgaXNzdWVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXlUeXBlCisgICAgICogICAgICAgICAgICB0aGUgbGlzdCBvZiBwdWJsaWMga2V5IGFsZ29yaXRobSBuYW1lcy4KKyAgICAgKiBAcGFyYW0gaXNzdWVycworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGUgaXNzdWVycywgb3Ige0Bjb2RlIG51bGx9IGlmIGFueSBpc3N1ZXIKKyAgICAgKiAgICAgICAgICAgIHdpbGwgZG8uCisgICAgICogQHBhcmFtIGVuZ2luZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBTU0xFbmdpbmV9IGZvciB0aGUgY29ubmVjdGlvbiwgb3Ige0Bjb2RlIG51bGx9IGlmCisgICAgICogICAgICAgICAgICBubyBlbmdpbmUgaXMgcHJlZGVmaW5lZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhbGlhcyBuYW1lIG9mIGEgbWF0Y2hpbmcga2V5IG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSBhcmUgbm8KKyAgICAgKiAgICAgICAgIG1hdGNoZXMuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBjaG9vc2VFbmdpbmVTZXJ2ZXJBbGlhcyhTdHJpbmcga2V5VHlwZSwgUHJpbmNpcGFsW10gaXNzdWVycywKKyAgICAgICAgICAgIFNTTEVuZ2luZSBlbmdpbmUpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9YNTA5S2V5TWFuYWdlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvWDUwOUtleU1hbmFnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZWJjNDI3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L25ldC9zc2wvWDUwOUtleU1hbmFnZXIuamF2YQpAQCAtMCwwICsxLDExMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5uZXQuU29ja2V0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworCisvKioKKyAqIEEgS2V5IE1hbmFnZXIgZm9yIFg1MDkgY2VydGlmaWNhdGUtYmFzZWQga2V5IHBhaXJzLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFg1MDlLZXlNYW5hZ2VyIGV4dGVuZHMgS2V5TWFuYWdlciB7CisKKyAgICAvKioKKyAgICAgKiBDaG9vc2VzIGFuIGFsaWFzIGZvciB0aGUgY2xpZW50IHNpZGUgb2YgYW4gU1NMIGNvbm5lY3Rpb24gdG8gYXV0aGVudGljYXRlCisgICAgICogaXQgd2l0aCB0aGUgc3BlY2lmaWVkIHB1YmxpYyBrZXkgdHlwZSBhbmQgY2VydGlmaWNhdGUgaXNzdWVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXlUeXBlCisgICAgICogICAgICAgICAgICB0aGUgbGlzdCBvZiBwdWJsaWMga2V5IGFsZ29yaXRobSBuYW1lcy4KKyAgICAgKiBAcGFyYW0gaXNzdWVycworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGUgaXNzdWVycywgb3Ige0Bjb2RlIG51bGx9IGlmIGFueSBpc3N1ZXIKKyAgICAgKiAgICAgICAgICAgIHdpbGwgZG8uCisgICAgICogQHBhcmFtIHNvY2tldAorICAgICAqICAgICAgICAgICAgdGhlIHNvY2tldCBmb3IgdGhlIGNvbm5lY3Rpb24sIG9yIHtAY29kZSBudWxsfSBpZgorICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIHNlbGVjdGVkIGRvZXMgbm90IGRlcGVuZCBvbiBhIHNwZWNpZmljIHNvY2tldC4KKyAgICAgKiBAcmV0dXJuIHRoZSBhbGlhcyBuYW1lIG9mIGEgbWF0Y2hpbmcga2V5IG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZSBhcmUgbm8KKyAgICAgKiAgICAgICAgIG1hdGNoZXMuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBjaG9vc2VDbGllbnRBbGlhcyhTdHJpbmdbXSBrZXlUeXBlLCBQcmluY2lwYWxbXSBpc3N1ZXJzLAorICAgICAgICAgICAgU29ja2V0IHNvY2tldCk7CisKKyAgICAvKioKKyAgICAgKiBDaG9vc2VzIGFuIGFsaWFzIGZvciB0aGUgc2VydmVyIHNpZGUgb2YgYW4gU1NMIGNvbm5lY3Rpb24gdG8gYXV0aGVudGljYXRlCisgICAgICogaXQgd2l0aCB0aGUgc3BlY2lmaWVkIHB1YmxpYyBrZXkgdHlwZSBhbmQgY2VydGlmaWNhdGUgaXNzdWVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXlUeXBlCisgICAgICogICAgICAgICAgICB0aGUgbGlzdCBvZiBwdWJsaWMga2V5IGFsZ29yaXRobSB0eXBlIG5hbWVzLgorICAgICAqIEBwYXJhbSBpc3N1ZXJzCisgICAgICogICAgICAgICAgICB0aGUgbGlzdCBvZiBjZXJ0aWZpY2F0ZSBpc3N1ZXJzLCBvciB7QGNvZGUgbnVsbH0gaWYgYW55IGlzc3VlcgorICAgICAqICAgICAgICAgICAgd2lsbCBkby4KKyAgICAgKiBAcGFyYW0gc29ja2V0CisgICAgICogICAgICAgICAgICB0aGUgc29ja2V0IGZvciB0aGUgY29ubmVjdGlvbiwgb3Ige0Bjb2RlIG51bGx9IGlmCisgICAgICogICAgICAgICAgICB0aGUgYWxpYXMgc2VsZWN0ZWQgZG9lcyBub3QgZGVwZW5kIG9uIGEgc3BlY2lmaWMgc29ja2V0LgorICAgICAqIEByZXR1cm4gdGhlIGFsaWFzIG5hbWUgb2YgYSBtYXRjaGluZyBrZXkgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGFyZSBubworICAgICAqICAgICAgICAgbWF0Y2hlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGNob29zZVNlcnZlckFsaWFzKFN0cmluZyBrZXlUeXBlLCBQcmluY2lwYWxbXSBpc3N1ZXJzLAorICAgICAgICAgICAgU29ja2V0IHNvY2tldCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjZXJ0aWZpY2F0ZSBjaGFpbiBmb3IgdGhlIHNwZWNpZmllZCBhbGlhcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGlhcworICAgICAqICAgICAgICAgICAgdGhlIGFsaWFzIHRvIGdldCB0aGUgY2VydGlmaWNhdGUgY2hhaW4gZm9yLgorICAgICAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRlIGNoYWluIGZvciB0aGUgc3BlY2lmaWVkIGFsaWFzLCBvciB7QGNvZGUgbnVsbH0gaWYKKyAgICAgKiAgICAgICAgIHRoZSBhbGlhcyBjYW5ub3QgYmUgZm91bmQuCisgICAgICovCisgICAgcHVibGljIFg1MDlDZXJ0aWZpY2F0ZVtdIGdldENlcnRpZmljYXRlQ2hhaW4oU3RyaW5nIGFsaWFzKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNsaWVudCBhbGlhc2VzIGZvciB0aGUgc3BlY2lmaWVkIHB1YmxpYyBrZXkgdHlwZSBhbmQgbGlzdCBvZgorICAgICAqIGNlcnRpZmljYXRlIGlzc3VlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5VHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHB1YmxpYyBrZXkgYWxnb3JpdGhtIHR5cGUgbmFtZS4KKyAgICAgKiBAcGFyYW0gaXNzdWVycworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGUgaXNzdWVycywgb3Ige0Bjb2RlIG51bGx9IGlmIGFueSBpc3N1ZXIKKyAgICAgKiAgICAgICAgICAgIHdpbGwgZG8uCisgICAgICogQHJldHVybiB0aGUgY2xpZW50IGFsaWFzZXMgZm9yIHRoZSBzcGVjaWZpZWQgcHVibGljIGtleSB0eXBlLCBvcgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlmIHRoZXJlIGFyZSBubyBtYXRjaGluZyBhbGlhc2VzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRDbGllbnRBbGlhc2VzKFN0cmluZyBrZXlUeXBlLCBQcmluY2lwYWxbXSBpc3N1ZXJzKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNlcnZlciBhbGlhc2VzIGZvciB0aGUgc3BlY2lmaWVkIHB1YmxpYyBrZXkgdHlwZSBhbmQgbGlzdCBvZgorICAgICAqIGNlcnRpZmljYXRlIGlzc3VlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5VHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHB1YmxpYyBrZXkgYWxnb3JpdGhtIHR5cGUgbmFtZS4KKyAgICAgKiBAcGFyYW0gaXNzdWVycworICAgICAqICAgICAgICAgICAgdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGUgaXNzdWVycywgb3Ige0Bjb2RlIG51bGx9IGlmIGFueSBpc3N1ZXIKKyAgICAgKiAgICAgICAgICAgIHdpbGwgZG8uCisgICAgICogQHJldHVybiB0aGUgY2xpZW50IGFsaWFzZXMgZm9yIHRoZSBzcGVjaWZpZWQgcHVibGljIGtleSB0eXBlLCBvcgorICAgICAqICAgICAgICAge0Bjb2RlIG51bGx9IGlmIHRoZXJlIGFyZSBubyBtYXRjaGluZyBhbGlhc2VzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRTZXJ2ZXJBbGlhc2VzKFN0cmluZyBrZXlUeXBlLCBQcmluY2lwYWxbXSBpc3N1ZXJzKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByaXZhdGUga2V5IGZvciB0aGUgc3BlY2lmaWVkIGFsaWFzLgorICAgICAqCisgICAgICogQHBhcmFtIGFsaWFzCisgICAgICogICAgICAgICAgICB0aGUgYWxpYXMgdG8gZ2V0IHRoZSBwcml2YXRlIGtleSBmb3IuCisgICAgICogQHJldHVybiB0aGUgcHJpdmF0ZSBrZXkgZm9yIHRoZSBzcGVjaWZpZWQgYWxpYXMsIG9yIHtAY29kZSBudWxsfSBpZiB0aGUKKyAgICAgKiAgICAgICAgIGFsaWFzIGNhbm5vdCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpdmF0ZUtleSBnZXRQcml2YXRlS2V5KFN0cmluZyBhbGlhcyk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9YNTA5VHJ1c3RNYW5hZ2VyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9YNTA5VHJ1c3RNYW5hZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2Q3ODI3ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL1g1MDlUcnVzdE1hbmFnZXIuamF2YQpAQCAtMCwwICsxLDc2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKKworLyoqCisgKiBUaGUgdHJ1c3QgbWFuYWdlciBmb3IgWDUwOSBjZXJ0aWZpY2F0ZXMgdG8gYmUgdXNlZCB0byBwZXJmb3JtIGF1dGhlbnRpY2F0aW9uCisgKiBmb3Igc2VjdXJlIHNvY2tldHMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgWDUwOVRydXN0TWFuYWdlciBleHRlbmRzIFRydXN0TWFuYWdlciB7CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgc3BlY2lmaWVkIGNlcnRpZmljYXRlIGNoYWluIChwYXJ0aWFsIG9yIGNvbXBsZXRlKSBjYW4KKyAgICAgKiBiZSB2YWxpZGF0ZWQgYW5kIGlzIHRydXN0ZWQgZm9yIGNsaWVudCBhdXRoZW50aWNhdGlvbiBmb3IgdGhlIHNwZWNpZmllZAorICAgICAqIGF1dGhlbnRpY2F0aW9uIHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhaW4KKyAgICAgKiAgICAgICAgICAgIHRoZSBjZXJ0aWZpY2F0ZSBjaGFpbiB0byB2YWxpZGF0ZS4KKyAgICAgKiBAcGFyYW0gYXV0aFR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBhdXRoZW50aWNhdGlvbiB0eXBlIHVzZWQuCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjZXJ0aWZpY2F0ZSBjaGFpbiBjYW4ndCBiZSB2YWxpZGF0ZWQgb3IgaXNuJ3QgdHJ1c3RlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgY2VydGlmaWNhdGUgY2hhaW4gaXMgZW1wdHkgb3Ige0Bjb2RlIG51bGx9LAorICAgICAqICAgICAgICAgICAgIG9yIGlmIHRoZSBzcGVjaWZpZWQgYXV0aGVudGljYXRpb24gdHlwZSBpcyB7QGNvZGUgbnVsbH0gb3IgYW4KKyAgICAgKiAgICAgICAgICAgICBlbXB0eSBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2hlY2tDbGllbnRUcnVzdGVkKFg1MDlDZXJ0aWZpY2F0ZVtdIGNoYWluLCBTdHJpbmcgYXV0aFR5cGUpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY2VydGlmaWNhdGUgY2hhaW4gKHBhcnRpYWwgb3IgY29tcGxldGUpIGNhbgorICAgICAqIGJlIHZhbGlkYXRlZCBhbmQgaXMgdHJ1c3RlZCBmb3Igc2VydmVyIGF1dGhlbnRpY2F0aW9uIGZvciB0aGUgc3BlY2lmaWVkCisgICAgICoga2V5IGV4Y2hhbmdlIGFsZ29yaXRobS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaGFpbgorICAgICAqICAgICAgICAgICAgdGhlIGNlcnRpZmljYXRlIGNoYWluIHRvIHZhbGlkYXRlLgorICAgICAqIEBwYXJhbSBhdXRoVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIGtleSBleGNoYW5nZSBhbGdvcml0aG0gbmFtZS4KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNlcnRpZmljYXRlIGNoYWluIGNhbid0IGJlIHZhbGlkYXRlZCBvciBpc24ndCB0cnVzdGVkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBjZXJ0aWZpY2F0ZSBjaGFpbiBpcyBlbXB0eSBvciB7QGNvZGUgbnVsbH0sCisgICAgICogICAgICAgICAgICAgb3IgaWYgdGhlIHNwZWNpZmllZCBhdXRoZW50aWNhdGlvbiB0eXBlIGlzIHtAY29kZSBudWxsfSBvciBhbgorICAgICAqICAgICAgICAgICAgIGVtcHR5IHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjaGVja1NlcnZlclRydXN0ZWQoWDUwOUNlcnRpZmljYXRlW10gY2hhaW4sIFN0cmluZyBhdXRoVHlwZSkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGUgaXNzdWVyIGF1dGhvcml0aWVzIHdoaWNoIGFyZSB0cnVzdGVkIGZvcgorICAgICAqIGF1dGhlbnRpY2F0aW9uIG9mIHBlZXJzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGlzdCBvZiBjZXJ0aWZpY2F0ZSBpc3N1ZXIgYXV0aG9yaXRpZXMgd2hpY2ggYXJlIHRydXN0ZWQgZm9yCisgICAgICogICAgICAgICBhdXRoZW50aWNhdGlvbiBvZiBwZWVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgWDUwOUNlcnRpZmljYXRlW10gZ2V0QWNjZXB0ZWRJc3N1ZXJzKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9wYWNrYWdlLmh0bWwgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvbmV0L3NzbC9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTQ3NTNjOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9uZXQvc3NsL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDIwIEBACis8aHRtbD4KKzxoZWFkPgorPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXMtYXNjaWkiPgorPC9oZWFkPgorPGh0bWw+Cis8Ym9keT4KKzxwPgorVGhpcyBwYWNrYWdlIHByb3ZpZGVzIGFsbCB0aGUgY2xhc3NlcyBhbmQgaW50ZXJmYWNlcyBuZWVkZWQgdG8gaW1wbGVtZW50IGFuZCBwcm9ncmFtIHRoZSBTZWN1cmUgU29ja2V0CithYnN0cmFjdGlvbiBiYXNlZCBvbiB0aGUgU1NMIHByb3RvY29sIFNTU0x2My4wIG9yIFRMU3YxLjIuCitBbGwgdGhlIGRldGFpbHMgb2YgdGhlIFNTTCBoYW5kc2hha2UgcHJvdG9jb2wgYXJlIGFjY291bnRlZCBmb3IsIGFuZCBhIGNsaWVudCBvciBhIHNlcnZlciBjYW4gc3BlY2lmeSB0aGUgY2lwaGVyIAorc2V0IHRvIHVzZS4KKworWC41MDkgY2VydGlmaWNhdGVzIGFyZSB2ZXJpZmllZCwgYW5kLCBpZiBkZXNpcmVkLCB0aGUgY2xpZW50IGFuZCB0aGUgc2VydmVyIGVhY2ggaGF2ZSB0aGUgb3B0aW9uIG9mIHZlcmlmeWluZwordGhlIGVudGlyZSBjZXJ0aWZpY2F0ZSBjaGFpbiB1bnRpbCB0aGUgcm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgaXMgcmVhY2hlZC4KKworQW5kcm9pZCB1c2VzIGNvZGUgZnJvbSBUaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlIChodHRwOi8vd3d3LmJvdW5jeWNhc3RsZS5vcmcpIGFuZCBPcGVuU1NMIChodHRwOi8vb3BlbnNzbC5vcmcpLgorCis8L3A+Cis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvYXV0aC9BdXRoUGVybWlzc2lvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvQXV0aFBlcm1pc3Npb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYmY2MjFhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvQXV0aFBlcm1pc3Npb24uamF2YQpAQCAtMCwwICsxLDM0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LnNlY3VyaXR5LmF1dGg7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkJhc2ljUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBBdXRoUGVybWlzc2lvbiBleHRlbmRzIEJhc2ljUGVybWlzc2lvbiB7CisgICAgcHVibGljIEF1dGhQZXJtaXNzaW9uKFN0cmluZyBuYW1lKSB7IHN1cGVyKCIiKTsgfQorCisgICAgcHVibGljIEF1dGhQZXJtaXNzaW9uKFN0cmluZyBuYW1lLCBTdHJpbmcgYWN0aW9ucykgeyBzdXBlcigiIiwgIiIpOyB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyBnZXRBY3Rpb25zKCkgeyByZXR1cm4gbnVsbDsgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGltcGxpZXMoUGVybWlzc2lvbiBwZXJtaXNzaW9uKSB7IHJldHVybiB0cnVlOyB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvYXV0aC9EZXN0cm95RmFpbGVkRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvYXV0aC9EZXN0cm95RmFpbGVkRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmI0YzQwMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9hdXRoL0Rlc3Ryb3lGYWlsZWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LnNlY3VyaXR5LmF1dGg7CisKKy8qKgorICogU2lnbmFscyB0aGF0IHRoZSB7QGxpbmsgRGVzdHJveWFibGUjZGVzdHJveSgpfSBtZXRob2QgZmFpbGVkLgorICovCitwdWJsaWMgY2xhc3MgRGVzdHJveUZhaWxlZEV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNzc5MDE1Mjg1NzI4Mjc0OTE2Mkw7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGV4Y2VwdGlvbiBvZiB0eXBlIHtAY29kZSBEZXN0cm95RmFpbGVkRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGVzdHJveUZhaWxlZEV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGV4Y2VwdGlvbiBvZiB0eXBlIHtAY29kZSBEZXN0cm95RmFpbGVkRXhjZXB0aW9ufS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICBBIGRldGFpbCBtZXNzYWdlIHRoYXQgZGVzY3JpYmVzIHRoZSByZWFzb24gZm9yIHRoaXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBEZXN0cm95RmFpbGVkRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvRGVzdHJveWFibGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9hdXRoL0Rlc3Ryb3lhYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjRkMGZhMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9hdXRoL0Rlc3Ryb3lhYmxlLmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5zZWN1cml0eS5hdXRoOworCisvKioKKyAqIEFsbG93cyBmb3Igc3BlY2lhbCB0cmVhdG1lbnQgb2Ygc2Vuc2l0aXZlIGluZm9ybWF0aW9uLCB3aGVuIGl0IGNvbWVzIHRvCisgKiBkZXN0cm95aW5nIG9yIGNsZWFyaW5nIG9mIHRoZSBkYXRhLgorICovCitwdWJsaWMgaW50ZXJmYWNlIERlc3Ryb3lhYmxlIHsKKworICAgIC8qKgorICAgICAqIEVyYXNlcyB0aGUgc2Vuc2l0aXZlIGluZm9ybWF0aW9uLiBPbmNlIGFuIG9iamVjdCBpcyBkZXN0cm95ZWQgYW55IGNhbGxzCisgICAgICogdG8gaXRzIG1ldGhvZHMgd2lsbCB0aHJvdyBhbiB7QGNvZGUgSWxsZWdhbFN0YXRlRXhjZXB0aW9ufS4gSWYgaXQgZG9lcworICAgICAqIG5vdCBzdWNjZWVkIGEgRGVzdHJveUZhaWxlZEV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIERlc3Ryb3lGYWlsZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgaW5mb3JtYXRpb24gY2Fubm90IGJlIGVyYXNlZC4KKyAgICAgKi8KKyAgICB2b2lkIGRlc3Ryb3koKSB0aHJvd3MgRGVzdHJveUZhaWxlZEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IG9uY2UgYW4gb2JqZWN0IGhhcyBiZWVuIHNhZmVseSBkZXN0cm95ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhlIG9iamVjdCBoYXMgYmVlbiBzYWZlbHkgZGVzdHJveWVkLgorICAgICAqLworICAgIGJvb2xlYW4gaXNEZXN0cm95ZWQoKTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvUHJpdmF0ZUNyZWRlbnRpYWxQZXJtaXNzaW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvYXV0aC9Qcml2YXRlQ3JlZGVudGlhbFBlcm1pc3Npb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYjZiZWJjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvUHJpdmF0ZUNyZWRlbnRpYWxQZXJtaXNzaW9uLmphdmEKQEAgLTAsMCArMSw0MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5zZWN1cml0eS5hdXRoOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb25Db2xsZWN0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKKy8qKgorICogTGVnYWN5IHNlY3VyaXR5IGNvZGU7IGRvIG5vdCB1c2UuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBQcml2YXRlQ3JlZGVudGlhbFBlcm1pc3Npb24gZXh0ZW5kcyBQZXJtaXNzaW9uIHsKKyAgICBwdWJsaWMgUHJpdmF0ZUNyZWRlbnRpYWxQZXJtaXNzaW9uKFN0cmluZyBuYW1lLCBTdHJpbmcgYWN0aW9uKSB7IHN1cGVyKCIiKTsgfQorCisgICAgcHVibGljIFN0cmluZ1tdW10gZ2V0UHJpbmNpcGFscygpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q3JlZGVudGlhbENsYXNzKCkgeyByZXR1cm4gbnVsbDsgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgZ2V0QWN0aW9ucygpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpbXBsaWVzKFBlcm1pc3Npb24gcGVybWlzc2lvbikgeyByZXR1cm4gdHJ1ZTsgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvU3ViamVjdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvU3ViamVjdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE5NTg0ODQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvYXV0aC9TdWJqZWN0LmphdmEKQEAgLTAsMCArMSw3NDAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguc2VjdXJpdHkuYXV0aDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xDb250ZXh0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkRvbWFpbkNvbWJpbmVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3RlY3Rpb25Eb21haW47CitpbXBvcnQgamF2YS51dGlsLkFic3RyYWN0U2V0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCisvKioKKyAqIFRoZSBjZW50cmFsIGNsYXNzIG9mIHRoZSB7QGNvZGUgamF2YXguc2VjdXJpdHkuYXV0aH0gcGFja2FnZSByZXByZXNlbnRpbmcgYW4KKyAqIGF1dGhlbnRpY2F0ZWQgdXNlciBvciBlbnRpdHkgKGJvdGggcmVmZXJyZWQgdG8gYXMgInN1YmplY3QiKS4gSVQgZGVmaW5lcyBhbHNvCisgKiB0aGUgc3RhdGljIG1ldGhvZHMgdGhhdCBhbGxvdyBjb2RlIHRvIGJlIHJ1biwgYW5kIGRvIG1vZGlmaWNhdGlvbnMgYWNjb3JkaW5nCisgKiB0byB0aGUgc3ViamVjdCdzIHBlcm1pc3Npb25zLgorICogPHA+CisgKiBBIHN1YmplY3QgaGFzIHRoZSBmb2xsb3dpbmcgZmVhdHVyZXM6CisgKiA8dWw+CisgKiA8bGk+QSBzZXQgb2Yge0Bjb2RlIFByaW5jaXBhbH0gb2JqZWN0cyBzcGVjaWZ5aW5nIHRoZSBpZGVudGl0aWVzIGJvdW5kIHRvIGEKKyAqIHtAY29kZSBTdWJqZWN0fSB0aGF0IGRpc3Rpbmd1aXNoIGl0LjwvbGk+CisgKiA8bGk+Q3JlZGVudGlhbHMgKHB1YmxpYyBhbmQgcHJpdmF0ZSkgc3VjaCBhcyBjZXJ0aWZpY2F0ZXMsIGtleXMsIG9yCisgKiBhdXRoZW50aWNhdGlvbiBwcm9vZnMgc3VjaCBhcyB0aWNrZXRzPC9saT4KKyAqIDwvdWw+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTdWJqZWN0IGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04MzA4NTIyNzU1NjAwMTU2MDU2TDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEF1dGhQZXJtaXNzaW9uIF9BUyA9IG5ldyBBdXRoUGVybWlzc2lvbigiZG9BcyIpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQXV0aFBlcm1pc3Npb24gX0FTX1BSSVZJTEVHRUQgPSBuZXcgQXV0aFBlcm1pc3Npb24oCisgICAgICAgICAgICAiZG9Bc1ByaXZpbGVnZWQiKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEF1dGhQZXJtaXNzaW9uIF9TVUJKRUNUID0gbmV3IEF1dGhQZXJtaXNzaW9uKAorICAgICAgICAgICAgImdldFN1YmplY3QiKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEF1dGhQZXJtaXNzaW9uIF9QUklOQ0lQQUxTID0gbmV3IEF1dGhQZXJtaXNzaW9uKAorICAgICAgICAgICAgIm1vZGlmeVByaW5jaXBhbHMiKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEF1dGhQZXJtaXNzaW9uIF9QUklWQVRFX0NSRURFTlRJQUxTID0gbmV3IEF1dGhQZXJtaXNzaW9uKAorICAgICAgICAgICAgIm1vZGlmeVByaXZhdGVDcmVkZW50aWFscyIpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQXV0aFBlcm1pc3Npb24gX1BVQkxJQ19DUkVERU5USUFMUyA9IG5ldyBBdXRoUGVybWlzc2lvbigKKyAgICAgICAgICAgICJtb2RpZnlQdWJsaWNDcmVkZW50aWFscyIpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQXV0aFBlcm1pc3Npb24gX1JFQURfT05MWSA9IG5ldyBBdXRoUGVybWlzc2lvbigKKyAgICAgICAgICAgICJzZXRSZWFkT25seSIpOworCisgICAgcHJpdmF0ZSBmaW5hbCBTZXQ8UHJpbmNpcGFsPiBwcmluY2lwYWxzOworCisgICAgcHJpdmF0ZSBib29sZWFuIHJlYWRPbmx5OworCisgICAgLy8gc2V0IG9mIHByaXZhdGUgY3JlZGVudGlhbHMKKyAgICBwcml2YXRlIHRyYW5zaWVudCBTZWN1cmVTZXQ8T2JqZWN0PiBwcml2YXRlQ3JlZGVudGlhbHM7CisKKyAgICAvLyBzZXQgb2YgcHVibGljIGNyZWRlbnRpYWxzCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgU2VjdXJlU2V0PE9iamVjdD4gcHVibGljQ3JlZGVudGlhbHM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGVmYXVsdCBjb25zdHJ1Y3RvciBpbml0aWFsaXppbmcgdGhlIHNldHMgb2YgcHVibGljIGFuZCBwcml2YXRlCisgICAgICogY3JlZGVudGlhbHMgYW5kIHByaW5jaXBhbHMgd2l0aCB0aGUgZW1wdHkgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBTdWJqZWN0KCkgeworICAgICAgICBwcmluY2lwYWxzID0gbmV3IFNlY3VyZVNldDxQcmluY2lwYWw+KF9QUklOQ0lQQUxTKTsKKyAgICAgICAgcHVibGljQ3JlZGVudGlhbHMgPSBuZXcgU2VjdXJlU2V0PE9iamVjdD4oX1BVQkxJQ19DUkVERU5USUFMUyk7CisgICAgICAgIHByaXZhdGVDcmVkZW50aWFscyA9IG5ldyBTZWN1cmVTZXQ8T2JqZWN0PihfUFJJVkFURV9DUkVERU5USUFMUyk7CisKKyAgICAgICAgcmVhZE9ubHkgPSBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29uc3RydWN0b3IgZm9yIHRoZSBzdWJqZWN0LCBzZXR0aW5nIGl0cyBwdWJsaWMgYW5kIHByaXZhdGUKKyAgICAgKiBjcmVkZW50aWFscyBhbmQgcHJpbmNpcGFscyBhY2NvcmRpbmcgdG8gdGhlIGFyZ3VtZW50cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFkT25seQorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IGlmIHRoaXMge0Bjb2RlIFN1YmplY3R9IGlzIHJlYWQtb25seSwgdGh1cworICAgICAqICAgICAgICAgICAgcHJldmVudGluZyBhbnkgbW9kaWZpY2F0aW9ucyB0byBiZSBkb25lLgorICAgICAqIEBwYXJhbSBzdWJqUHJpbmNpcGFscworICAgICAqICAgICAgICAgICAgdGhlIHNldCBvZiBQcmluY2lwYWxzIHRoYXQgYXJlIGF0dHJpYnV0ZWQgdG8gdGhpcyB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFN1YmplY3R9LgorICAgICAqIEBwYXJhbSBwdWJDcmVkZW50aWFscworICAgICAqICAgICAgICAgICAgdGhlIHNldCBvZiBwdWJsaWMgY3JlZGVudGlhbHMgdGhhdCBkaXN0aW5ndWlzaCB0aGlzIHtAY29kZQorICAgICAqICAgICAgICAgICAgU3ViamVjdH0uCisgICAgICogQHBhcmFtIHByaXZDcmVkZW50aWFscworICAgICAqICAgICAgICAgICAgdGhlIHNldCBvZiBwcml2YXRlIGNyZWRlbnRpYWxzIHRoYXQgZGlzdGluZ3Vpc2ggdGhpcyB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFN1YmplY3R9LgorICAgICAqLworICAgIHB1YmxpYyBTdWJqZWN0KGJvb2xlYW4gcmVhZE9ubHksIFNldDw/IGV4dGVuZHMgUHJpbmNpcGFsPiBzdWJqUHJpbmNpcGFscywKKyAgICAgICAgICAgIFNldDw/PiBwdWJDcmVkZW50aWFscywgU2V0PD8+IHByaXZDcmVkZW50aWFscykgeworCisgICAgICAgIGlmIChzdWJqUHJpbmNpcGFscyA9PSBudWxsIHx8IHB1YkNyZWRlbnRpYWxzID09IG51bGwgfHwgcHJpdkNyZWRlbnRpYWxzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgcHJpbmNpcGFscyA9IG5ldyBTZWN1cmVTZXQ8UHJpbmNpcGFsPihfUFJJTkNJUEFMUywgc3VialByaW5jaXBhbHMpOworICAgICAgICBwdWJsaWNDcmVkZW50aWFscyA9IG5ldyBTZWN1cmVTZXQ8T2JqZWN0PihfUFVCTElDX0NSRURFTlRJQUxTLCBwdWJDcmVkZW50aWFscyk7CisgICAgICAgIHByaXZhdGVDcmVkZW50aWFscyA9IG5ldyBTZWN1cmVTZXQ8T2JqZWN0PihfUFJJVkFURV9DUkVERU5USUFMUywgcHJpdkNyZWRlbnRpYWxzKTsKKworICAgICAgICB0aGlzLnJlYWRPbmx5ID0gcmVhZE9ubHk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgY29kZSBkZWZpbmVkIGJ5IHtAY29kZSBhY3Rpb259IHVzaW5nIHRoZSBwZXJtaXNzaW9ucyBncmFudGVkIHRvCisgICAgICogdGhlIHtAY29kZSBTdWJqZWN0fSBpdHNlbGYgYW5kIHRvIHRoZSBjb2RlIGFzIHdlbGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3ViamVjdAorICAgICAqICAgICAgICAgICAgdGhlIGRpc3Rpbmd1aXNoZWQge0Bjb2RlIFN1YmplY3R9LgorICAgICAqIEBwYXJhbSBhY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2RlIHRvIGJlIHJ1bi4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgT2JqZWN0fSByZXR1cm5lZCB3aGVuIHJ1bm5pbmcgdGhlIHtAY29kZSBhY3Rpb259LgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzdGF0aWMgPFQ+IFQgZG9BcyhTdWJqZWN0IHN1YmplY3QsIFByaXZpbGVnZWRBY3Rpb248VD4gYWN0aW9uKSB7CisgICAgICAgIHJldHVybiBkb0FzX1ByaXZpbGVnZWRBY3Rpb24oc3ViamVjdCwgYWN0aW9uLCBBY2Nlc3NDb250cm9sbGVyLmdldENvbnRleHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVuIHRoZSBjb2RlIGRlZmluZWQgYnkge0Bjb2RlIGFjdGlvbn0gdXNpbmcgdGhlIHBlcm1pc3Npb25zIGdyYW50ZWQgdG8KKyAgICAgKiB0aGUge0Bjb2RlIFN1YmplY3R9IGFuZCB0byB0aGUgY29kZSBpdHNlbGYsIGFkZGl0aW9uYWxseSBwcm92aWRpbmcgYSBtb3JlCisgICAgICogc3BlY2lmaWMgY29udGV4dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdWJqZWN0CisgICAgICogICAgICAgICAgICB0aGUgZGlzdGluZ3Vpc2hlZCB7QGNvZGUgU3ViamVjdH0uCisgICAgICogQHBhcmFtIGFjdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGNvZGUgdG8gYmUgcnVuLgorICAgICAqIEBwYXJhbSBjb250ZXh0CisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWMgY29udGV4dCBpbiB3aGljaCB0aGUge0Bjb2RlIGFjdGlvbn0gaXMgaW52b2tlZC4KKyAgICAgKiAgICAgICAgICAgIGlmIHtAY29kZSBudWxsfSBhIG5ldyB7QGxpbmsgQWNjZXNzQ29udHJvbENvbnRleHR9IGlzCisgICAgICogICAgICAgICAgICBpbnN0YW50aWF0ZWQuCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIE9iamVjdH0gcmV0dXJuZWQgd2hlbiBydW5uaW5nIHRoZSB7QGNvZGUgYWN0aW9ufS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgc3RhdGljIDxUPiBUIGRvQXNQcml2aWxlZ2VkKFN1YmplY3Qgc3ViamVjdCwgUHJpdmlsZWdlZEFjdGlvbjxUPiBhY3Rpb24sCisgICAgICAgICAgICBBY2Nlc3NDb250cm9sQ29udGV4dCBjb250ZXh0KSB7CisgICAgICAgIGlmIChjb250ZXh0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBkb0FzX1ByaXZpbGVnZWRBY3Rpb24oc3ViamVjdCwgYWN0aW9uLCBuZXcgQWNjZXNzQ29udHJvbENvbnRleHQoCisgICAgICAgICAgICAgICAgICAgIG5ldyBQcm90ZWN0aW9uRG9tYWluWzBdKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRvQXNfUHJpdmlsZWdlZEFjdGlvbihzdWJqZWN0LCBhY3Rpb24sIGNvbnRleHQpOworICAgIH0KKworICAgIC8vIGluc3RhbnRpYXRlcyBhIG5ldyBjb250ZXh0IGFuZCBwYXNzZXMgaXQgdG8gQWNjZXNzQ29udHJvbGxlcgorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHByaXZhdGUgc3RhdGljIDxUPiBUIGRvQXNfUHJpdmlsZWdlZEFjdGlvbihTdWJqZWN0IHN1YmplY3QsIFByaXZpbGVnZWRBY3Rpb248VD4gYWN0aW9uLAorICAgICAgICAgICAgZmluYWwgQWNjZXNzQ29udHJvbENvbnRleHQgY29udGV4dCkgeworCisgICAgICAgIEFjY2Vzc0NvbnRyb2xDb250ZXh0IG5ld0NvbnRleHQ7CisKKyAgICAgICAgZmluYWwgU3ViamVjdERvbWFpbkNvbWJpbmVyIGNvbWJpbmVyOworICAgICAgICBpZiAoc3ViamVjdCA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24KKyAgICAgICAgICAgIC8vIGlmIHN1YmplY3QgaXMgbnVsbCB0aGVyZSBpcyBub3RoaW5nIHRvIGNvbWJpbmUKKyAgICAgICAgICAgIGNvbWJpbmVyID0gbnVsbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNvbWJpbmVyID0gbmV3IFN1YmplY3REb21haW5Db21iaW5lcihzdWJqZWN0KTsKKyAgICAgICAgfQorCisgICAgICAgIFByaXZpbGVnZWRBY3Rpb24gZGNjQWN0aW9uID0gbmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7CisgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFjY2Vzc0NvbnRyb2xDb250ZXh0KGNvbnRleHQsIGNvbWJpbmVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBuZXdDb250ZXh0ID0gKEFjY2Vzc0NvbnRyb2xDb250ZXh0KSBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChkY2NBY3Rpb24pOworCisgICAgICAgIHJldHVybiBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChhY3Rpb24sIG5ld0NvbnRleHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIGNvZGUgZGVmaW5lZCBieSB7QGNvZGUgYWN0aW9ufSB1c2luZyB0aGUgcGVybWlzc2lvbnMgZ3JhbnRlZCB0bworICAgICAqIHRoZSBzdWJqZWN0IGFuZCB0byB0aGUgY29kZSBpdHNlbGYuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3ViamVjdAorICAgICAqICAgICAgICAgICAgdGhlIGRpc3Rpbmd1aXNoZWQge0Bjb2RlIFN1YmplY3R9LgorICAgICAqIEBwYXJhbSBhY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb2RlIHRvIGJlIHJ1bi4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgT2JqZWN0fSByZXR1cm5lZCB3aGVuIHJ1bm5pbmcgdGhlIHtAY29kZSBhY3Rpb259LgorICAgICAqIEB0aHJvd3MgUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHJ1bm5pbmcgdGhlIHtAY29kZSBhY3Rpb259IHRocm93cyBhbiBleGNlcHRpb24uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN0YXRpYyA8VD4gVCBkb0FzKFN1YmplY3Qgc3ViamVjdCwgUHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbjxUPiBhY3Rpb24pCisgICAgICAgICAgICB0aHJvd3MgUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBkb0FzX1ByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb24oc3ViamVjdCwgYWN0aW9uLCBBY2Nlc3NDb250cm9sbGVyLmdldENvbnRleHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgY29kZSBkZWZpbmVkIGJ5IHtAY29kZSBhY3Rpb259IHVzaW5nIHRoZSBwZXJtaXNzaW9ucyBncmFudGVkIHRvCisgICAgICogdGhlIHN1YmplY3QgYW5kIHRvIHRoZSBjb2RlIGl0c2VsZiwgYWRkaXRpb25hbGx5IHByb3ZpZGluZyBhIG1vcmUKKyAgICAgKiBzcGVjaWZpYyBjb250ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIHN1YmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBkaXN0aW5ndWlzaGVkIHtAY29kZSBTdWJqZWN0fS4KKyAgICAgKiBAcGFyYW0gYWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgY29kZSB0byBiZSBydW4uCisgICAgICogQHBhcmFtIGNvbnRleHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzcGVjaWZpYyBjb250ZXh0IGluIHdoaWNoIHRoZSB7QGNvZGUgYWN0aW9ufSBpcyBpbnZva2VkLgorICAgICAqICAgICAgICAgICAgaWYge0Bjb2RlIG51bGx9IGEgbmV3IHtAbGluayBBY2Nlc3NDb250cm9sQ29udGV4dH0gaXMKKyAgICAgKiAgICAgICAgICAgIGluc3RhbnRpYXRlZC4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgT2JqZWN0fSByZXR1cm5lZCB3aGVuIHJ1bm5pbmcgdGhlIHtAY29kZSBhY3Rpb259LgorICAgICAqIEB0aHJvd3MgUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHJ1bm5pbmcgdGhlIHtAY29kZSBhY3Rpb259IHRocm93cyBhbiBleGNlcHRpb24uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN0YXRpYyA8VD4gVCBkb0FzUHJpdmlsZWdlZChTdWJqZWN0IHN1YmplY3QsCisgICAgICAgICAgICBQcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uPFQ+IGFjdGlvbiwgQWNjZXNzQ29udHJvbENvbnRleHQgY29udGV4dCkKKyAgICAgICAgICAgIHRocm93cyBQcml2aWxlZ2VkQWN0aW9uRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNvbnRleHQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGRvQXNfUHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbihzdWJqZWN0LCBhY3Rpb24sCisgICAgICAgICAgICAgICAgICAgIG5ldyBBY2Nlc3NDb250cm9sQ29udGV4dChuZXcgUHJvdGVjdGlvbkRvbWFpblswXSkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkb0FzX1ByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb24oc3ViamVjdCwgYWN0aW9uLCBjb250ZXh0KTsKKyAgICB9CisKKyAgICAvLyBpbnN0YW50aWF0ZXMgYSBuZXcgY29udGV4dCBhbmQgcGFzc2VzIGl0IHRvIEFjY2Vzc0NvbnRyb2xsZXIKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIHN0YXRpYyA8VD4gVCBkb0FzX1ByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb24oU3ViamVjdCBzdWJqZWN0LAorICAgICAgICAgICAgUHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbjxUPiBhY3Rpb24sIGZpbmFsIEFjY2Vzc0NvbnRyb2xDb250ZXh0IGNvbnRleHQpCisgICAgICAgICAgICB0aHJvd3MgUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbiB7CisKKyAgICAgICAgQWNjZXNzQ29udHJvbENvbnRleHQgbmV3Q29udGV4dDsKKworICAgICAgICBmaW5hbCBTdWJqZWN0RG9tYWluQ29tYmluZXIgY29tYmluZXI7CisgICAgICAgIGlmIChzdWJqZWN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIHBlcmZvcm1hbmNlIG9wdGltaXphdGlvbgorICAgICAgICAgICAgLy8gaWYgc3ViamVjdCBpcyBudWxsIHRoZXJlIGlzIG5vdGhpbmcgdG8gY29tYmluZQorICAgICAgICAgICAgY29tYmluZXIgPSBudWxsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY29tYmluZXIgPSBuZXcgU3ViamVjdERvbWFpbkNvbWJpbmVyKHN1YmplY3QpOworICAgICAgICB9CisKKyAgICAgICAgUHJpdmlsZWdlZEFjdGlvbjxBY2Nlc3NDb250cm9sQ29udGV4dD4gZGNjQWN0aW9uID0gbmV3IFByaXZpbGVnZWRBY3Rpb248QWNjZXNzQ29udHJvbENvbnRleHQ+KCkgeworICAgICAgICAgICAgcHVibGljIEFjY2Vzc0NvbnRyb2xDb250ZXh0IHJ1bigpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFjY2Vzc0NvbnRyb2xDb250ZXh0KGNvbnRleHQsIGNvbWJpbmVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBuZXdDb250ZXh0ID0gQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQoZGNjQWN0aW9uKTsKKworICAgICAgICByZXR1cm4gQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQoYWN0aW9uLCBuZXdDb250ZXh0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgdHdvIFN1YmplY3RzIGZvciBlcXVhbGl0eS4gTW9yZSBzcGVjaWZpY2FsbHkgaWYgdGhlIHByaW5jaXBhbHMsCisgICAgICogcHVibGljIGFuZCBwcml2YXRlIGNyZWRlbnRpYWxzIGFyZSBlcXVhbCwgZXF1YWxpdHkgZm9yIHR3byB7QGNvZGUKKyAgICAgKiBTdWJqZWN0c30gaXMgaW1wbGllZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgT2JqZWN0fSBjaGVja2VkIGZvciBlcXVhbGl0eSB3aXRoIHRoaXMge0Bjb2RlCisgICAgICogICAgICAgICAgICBTdWJqZWN0fS4KKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIHtAY29kZSBTdWJqZWN0fSBpcyBlcXVhbCB0byB0aGlzCisgICAgICogICAgICAgICBvbmUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKworICAgICAgICBpZiAodGhpcyA9PSBvYmopIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG9iaiA9PSBudWxsIHx8IHRoaXMuZ2V0Q2xhc3MoKSAhPSBvYmouZ2V0Q2xhc3MoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgU3ViamVjdCB0aGF0ID0gKFN1YmplY3QpIG9iajsKKworICAgICAgICBpZiAocHJpbmNpcGFscy5lcXVhbHModGhhdC5wcmluY2lwYWxzKQorICAgICAgICAgICAgICAgICYmIHB1YmxpY0NyZWRlbnRpYWxzLmVxdWFscyh0aGF0LnB1YmxpY0NyZWRlbnRpYWxzKQorICAgICAgICAgICAgICAgICYmIHByaXZhdGVDcmVkZW50aWFscy5lcXVhbHModGhhdC5wcml2YXRlQ3JlZGVudGlhbHMpKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHtAY29kZSBTdWJqZWN0fSdzIHtAbGluayBQcmluY2lwYWx9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGlzIHtAY29kZSBTdWJqZWN0fSdzIHtAbGluayBQcmluY2lwYWx9LgorICAgICAqLworICAgIHB1YmxpYyBTZXQ8UHJpbmNpcGFsPiBnZXRQcmluY2lwYWxzKCkgeworICAgICAgICByZXR1cm4gcHJpbmNpcGFsczsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhpcyB7QGNvZGUgU3ViamVjdH0ncyB7QGxpbmsgUHJpbmNpcGFsfSB3aGljaCBpcyBhIHN1YmNsYXNzIG9mCisgICAgICogdGhlIHtAY29kZSBDbGFzc30gcHJvdmlkZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDbGFzc30gYXMgYSBjcml0ZXJpYSB3aGljaCB0aGUge0Bjb2RlIFByaW5jaXBhbH0KKyAgICAgKiAgICAgICAgICAgIHJldHVybmVkIG11c3Qgc2F0aXNmeS4KKyAgICAgKiBAcmV0dXJuIHRoaXMge0Bjb2RlIFN1YmplY3R9J3Mge0BsaW5rIFByaW5jaXBhbH0uIE1vZGlmaWNhdGlvbnMgdG8gdGhlCisgICAgICogICAgICAgICByZXR1cm5lZCBzZXQgb2Yge0Bjb2RlIFByaW5jaXBhbH1zIGRvIG5vdCBhZmZlY3QgdGhpcyB7QGNvZGUKKyAgICAgKiAgICAgICAgIFN1YmplY3R9J3Mgc2V0LgorICAgICAqLworICAgIHB1YmxpYyA8VCBleHRlbmRzIFByaW5jaXBhbD4gU2V0PFQ+IGdldFByaW5jaXBhbHMoQ2xhc3M8VD4gYykgeworICAgICAgICByZXR1cm4gKChTZWN1cmVTZXQ8UHJpbmNpcGFsPikgcHJpbmNpcGFscykuZ2V0KGMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByaXZhdGUgY3JlZGVudGlhbHMgYXNzb2NpYXRlZCB3aXRoIHRoaXMge0Bjb2RlIFN1YmplY3R9LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJpdmF0ZSBjcmVkZW50aWFscyBhc3NvY2lhdGVkIHdpdGggdGhpcyB7QGNvZGUgU3ViamVjdH0uCisgICAgICovCisgICAgcHVibGljIFNldDxPYmplY3Q+IGdldFByaXZhdGVDcmVkZW50aWFscygpIHsKKyAgICAgICAgcmV0dXJuIHByaXZhdGVDcmVkZW50aWFsczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoaXMge0Bjb2RlIFN1YmplY3R9J3MgcHJpdmF0ZSBjcmVkZW50aWFscyB3aGljaCBhcmUgYSBzdWJjbGFzcworICAgICAqIG9mIHRoZSB7QGNvZGUgQ2xhc3N9IHByb3ZpZGVkLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2xhc3N9IGFzIGEgY3JpdGVyaWEgd2hpY2ggdGhlIHByaXZhdGUgY3JlZGVudGlhbHMKKyAgICAgKiAgICAgICAgICAgIHJldHVybmVkIG11c3Qgc2F0aXNmeS4KKyAgICAgKiBAcmV0dXJuIHRoaXMge0Bjb2RlIFN1YmplY3R9J3MgcHJpdmF0ZSBjcmVkZW50aWFscy4gTW9kaWZpY2F0aW9ucyB0byB0aGUKKyAgICAgKiAgICAgICAgIHJldHVybmVkIHNldCBvZiBjcmVkZW50aWFscyBkbyBub3QgYWZmZWN0IHRoaXMge0Bjb2RlIFN1YmplY3R9J3MKKyAgICAgKiAgICAgICAgIGNyZWRlbnRpYWxzLgorICAgICAqLworICAgIHB1YmxpYyA8VD4gU2V0PFQ+IGdldFByaXZhdGVDcmVkZW50aWFscyhDbGFzczxUPiBjKSB7CisgICAgICAgIHJldHVybiBwcml2YXRlQ3JlZGVudGlhbHMuZ2V0KGMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHB1YmxpYyBjcmVkZW50aWFscyBhc3NvY2lhdGVkIHdpdGggdGhpcyB7QGNvZGUgU3ViamVjdH0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwdWJsaWMgY3JlZGVudGlhbHMgYXNzb2NpYXRlZCB3aXRoIHRoaXMge0Bjb2RlIFN1YmplY3R9LgorICAgICAqLworICAgIHB1YmxpYyBTZXQ8T2JqZWN0PiBnZXRQdWJsaWNDcmVkZW50aWFscygpIHsKKyAgICAgICAgcmV0dXJuIHB1YmxpY0NyZWRlbnRpYWxzOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGlzIHtAY29kZSBTdWJqZWN0fSdzIHB1YmxpYyBjcmVkZW50aWFscyB3aGljaCBhcmUgYSBzdWJjbGFzcyBvZgorICAgICAqIHRoZSB7QGNvZGUgQ2xhc3N9IHByb3ZpZGVkLgorICAgICAqCisgICAgICogQHBhcmFtIGMKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2xhc3N9IGFzIGEgY3JpdGVyaWEgd2hpY2ggdGhlIHB1YmxpYyBjcmVkZW50aWFscworICAgICAqICAgICAgICAgICAgcmV0dXJuZWQgbXVzdCBzYXRpc2Z5LgorICAgICAqIEByZXR1cm4gdGhpcyB7QGNvZGUgU3ViamVjdH0ncyBwdWJsaWMgY3JlZGVudGlhbHMuIE1vZGlmaWNhdGlvbnMgdG8gdGhlCisgICAgICogICAgICAgICByZXR1cm5lZCBzZXQgb2YgY3JlZGVudGlhbHMgZG8gbm90IGFmZmVjdCB0aGlzIHtAY29kZSBTdWJqZWN0fSdzCisgICAgICogICAgICAgICBjcmVkZW50aWFscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgPFQ+IFNldDxUPiBnZXRQdWJsaWNDcmVkZW50aWFscyhDbGFzczxUPiBjKSB7CisgICAgICAgIHJldHVybiBwdWJsaWNDcmVkZW50aWFscy5nZXQoYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGhhc2ggY29kZSBvZiB0aGlzIHtAY29kZSBTdWJqZWN0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBoYXNoIGNvZGUgb2YgdGhpcyB7QGNvZGUgU3ViamVjdH0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIHByaW5jaXBhbHMuaGFzaENvZGUoKSArIHByaXZhdGVDcmVkZW50aWFscy5oYXNoQ29kZSgpCisgICAgICAgICAgICAgICAgKyBwdWJsaWNDcmVkZW50aWFscy5oYXNoQ29kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByZXZlbnRzIGZyb20gbW9kaWZpY2F0aW9ucyBiZWluZyBkb25lIHRvIHRoZSBjcmVkZW50aWFscyBhbmQge0BsaW5rCisgICAgICogUHJpbmNpcGFsfSBzZXRzLiBBZnRlciBzZXR0aW5nIGl0IHRvIHJlYWQtb25seSB0aGlzIHtAY29kZSBTdWJqZWN0fSBjYW4KKyAgICAgKiBub3QgYmUgbWFkZSB3cml0YWJsZSBhZ2Fpbi4gVGhlIGRlc3Ryb3kgbWV0aG9kIG9uIHRoZSBjcmVkZW50aWFscyBzdGlsbAorICAgICAqIHdvcmtzIHRob3VnaC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSZWFkT25seSgpIHsKKyAgICAgICAgcmVhZE9ubHkgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIHtAY29kZSBTdWJqZWN0fSBpcyByZWFkLW9ubHkgb3Igbm90LgorICAgICAqCisgICAgICogQHJldHVybiB3aGV0aGVyIHRoaXMge0Bjb2RlIFN1YmplY3R9IGlzIHJlYWQtb25seSBvciBub3QuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNSZWFkT25seSgpIHsKKyAgICAgICAgcmV0dXJuIHJlYWRPbmx5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSB7QGNvZGUgU3RyaW5nfSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZSBTdWJqZWN0fS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgU3RyaW5nfSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHtAY29kZSBTdWJqZWN0fS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJTdWJqZWN0OlxuIik7CisKKyAgICAgICAgSXRlcmF0b3I8Pz4gaXQgPSBwcmluY2lwYWxzLml0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIlx0UHJpbmNpcGFsOiAiKTsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoaXQubmV4dCgpKTsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJ1xuJyk7CisgICAgICAgIH0KKworICAgICAgICBpdCA9IHB1YmxpY0NyZWRlbnRpYWxzLml0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIlx0UHVibGljIENyZWRlbnRpYWw6ICIpOworICAgICAgICAgICAgYnVmLmFwcGVuZChpdC5uZXh0KCkpOworICAgICAgICAgICAgYnVmLmFwcGVuZCgnXG4nKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBvZmZzZXQgPSBidWYubGVuZ3RoKCkgLSAxOworICAgICAgICBpdCA9IHByaXZhdGVDcmVkZW50aWFscy5pdGVyYXRvcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIlx0UHJpdmF0ZSBDcmVkZW50aWFsOiAiKTsKKyAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGl0Lm5leHQoKSk7CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnXG4nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYnVmLmRlbGV0ZShvZmZzZXQsIGJ1Zi5sZW5ndGgoKSk7CisgICAgICAgICAgICBidWYuYXBwZW5kKCJcdFByaXZhdGUgQ3JlZGVudGlhbHM6IG5vIGFjY2Vzc2libGUgaW5mb3JtYXRpb25cbiIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisKKyAgICAgICAgaW4uZGVmYXVsdFJlYWRPYmplY3QoKTsKKworICAgICAgICBwdWJsaWNDcmVkZW50aWFscyA9IG5ldyBTZWN1cmVTZXQ8T2JqZWN0PihfUFVCTElDX0NSRURFTlRJQUxTKTsKKyAgICAgICAgcHJpdmF0ZUNyZWRlbnRpYWxzID0gbmV3IFNlY3VyZVNldDxPYmplY3Q+KF9QUklWQVRFX0NSRURFTlRJQUxTKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LmRlZmF1bHRXcml0ZU9iamVjdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBTdWJqZWN0fSB0aGF0IHdhcyBsYXN0IGFzc29jaWF0ZWQgd2l0aCB0aGUge0Bjb2RlCisgICAgICogY29udGV4dH0gcHJvdmlkZWQgYXMgYXJndW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29udGV4dAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBjb250ZXh0fSB0aGF0IHdhcyBhc3NvY2lhdGVkIHdpdGggdGhlCisgICAgICogICAgICAgICAgICB7QGNvZGUgU3ViamVjdH0uCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFN1YmplY3R9IHRoYXQgd2FzIGxhc3QgYXNzb2NpYXRlZCB3aXRoIHRoZSB7QGNvZGUKKyAgICAgKiAgICAgICAgIGNvbnRleHR9IHByb3ZpZGVkIGFzIGFyZ3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3ViamVjdCBnZXRTdWJqZWN0KGZpbmFsIEFjY2Vzc0NvbnRyb2xDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgaWYgKGNvbnRleHQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJBY2Nlc3NDb250cm9sQ29udGV4dCBjYW5ub3QgYmUgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIFByaXZpbGVnZWRBY3Rpb248RG9tYWluQ29tYmluZXI+IGFjdGlvbiA9IG5ldyBQcml2aWxlZ2VkQWN0aW9uPERvbWFpbkNvbWJpbmVyPigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBEb21haW5Db21iaW5lciBydW4oKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuZ2V0RG9tYWluQ29tYmluZXIoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgRG9tYWluQ29tYmluZXIgY29tYmluZXIgPSBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChhY3Rpb24pOworCisgICAgICAgIGlmICgoY29tYmluZXIgPT0gbnVsbCkgfHwgIShjb21iaW5lciBpbnN0YW5jZW9mIFN1YmplY3REb21haW5Db21iaW5lcikpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoKFN1YmplY3REb21haW5Db21iaW5lcikgY29tYmluZXIpLmdldFN1YmplY3QoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tTdGF0ZSgpIHsKKyAgICAgICAgaWYgKHJlYWRPbmx5KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJTZXQgaXMgcmVhZC1vbmx5Iik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIGNsYXNzIFNlY3VyZVNldDxTU1Q+IGV4dGVuZHMgQWJzdHJhY3RTZXQ8U1NUPiBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbXBhdGliaWxpdHkgaXNzdWU6IHNlZSBjb21tZW50cyBmb3Igc2V0VHlwZSB2YXJpYWJsZQorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzkxMTc1NDE3MTExMTgwMDM1OUw7CisKKyAgICAgICAgcHJpdmF0ZSBMaW5rZWRMaXN0PFNTVD4gZWxlbWVudHM7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogSXMgdXNlZCB0byBkZWZpbmUgYSBzZXQgdHlwZSBmb3Igc2VyaWFsaXphdGlvbi4KKyAgICAgICAgICoKKyAgICAgICAgICogQSB0eXBlIGNhbiBiZSBwcmluY2lwYWwsIHByaXYuIG9yIHB1Yi4gY3JlZGVudGlhbCBzZXQuIFRoZSBzcGVjLgorICAgICAgICAgKiBkb2Vzbid0IGNsZWFybHkgc2F5cyB0aGF0IHByaXYuIGFuZCBwdWIuIGNyZWRlbnRpYWwgc2V0cyBjYW4gYmUKKyAgICAgICAgICogc2VyaWFsaXplZCBhbmQgd2hhdCBjbGFzc2VzIHRoZXkgYXJlLiBJdCBpcyBvbmx5IHBvc3NpYmxlIHRvIGZpZ3VyZQorICAgICAgICAgKiBvdXQgZnJvbSB3cml0ZU9iamVjdCBtZXRob2QgY29tbWVudHMgdGhhdCBwcml2LiBjcmVkZW50aWFsIHNldCBpcworICAgICAgICAgKiBzZXJpYWxpemFibGUgYW5kIGl0IGlzIGFuIGluc3RhbmNlIG9mIFNlY3VyZVNldCBjbGFzcy4gU28gcHViLgorICAgICAgICAgKiBjcmVkZW50aWFsIHdhcyBpbXBsZW1lbnRlZCBieSBhbmFsb2d5CisgICAgICAgICAqCisgICAgICAgICAqIENvbXBhdGliaWxpdHkgaXNzdWU6IHRoZSBjbGFzcyBmb2xsb3dzIGl0cyBzcGVjaWZpZWQgc2VyaWFsIGZvcm0uCisgICAgICAgICAqIEFsc28gYWNjb3JkaW5nIHRvIHRoZSBzZXJpYWxpemF0aW9uIHNwZWMuIGFkZGluZyBuZXcgZmllbGQgaXMgYQorICAgICAgICAgKiBjb21wYXRpYmxlIGNoYW5nZS4gU28gaXMgb2sgZm9yIHByaW5jaXBhbCBzZXQgKGJlY2F1c2UgdGhlIGRlZmF1bHQKKyAgICAgICAgICogdmFsdWUgZm9yIGludGVnZXIgaXMgemVybykuIEJ1dCBwcml2LiBvciBwdWIuIGNyZWRlbnRpYWwgc2V0IGl0IGlzCisgICAgICAgICAqIG5vdCBjb21wYXRpYmxlIGJlY2F1c2UgbW9zdCBwcm9iYWJseSBvdGhlciBpbXBsZW1lbnRhdGlvbnMgcmVzb2x2ZQorICAgICAgICAgKiB0aGlzIGlzc3VlIGluIG90aGVyIHdheQorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBpbnQgc2V0VHlwZTsKKworICAgICAgICAvLyBEZWZpbmVzIHByaW5jaXBhbCBzZXQgZm9yIHNlcmlhbGl6YXRpb24uCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTRVRfUHJpbmNpcGFsID0gMDsKKworICAgICAgICAvLyBEZWZpbmVzIHByaXZhdGUgY3JlZGVudGlhbCBzZXQgZm9yIHNlcmlhbGl6YXRpb24uCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTRVRfUHJpdkNyZWQgPSAxOworCisgICAgICAgIC8vIERlZmluZXMgcHVibGljIGNyZWRlbnRpYWwgc2V0IGZvciBzZXJpYWxpemF0aW9uLgorICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0VUX1B1YkNyZWQgPSAyOworCisgICAgICAgIC8vIHBlcm1pc3Npb24gcmVxdWlyZWQgdG8gbW9kaWZ5IHNldAorICAgICAgICBwcml2YXRlIHRyYW5zaWVudCBBdXRoUGVybWlzc2lvbiBwZXJtaXNzaW9uOworCisgICAgICAgIHByb3RlY3RlZCBTZWN1cmVTZXQoQXV0aFBlcm1pc3Npb24gcGVybSkgeworICAgICAgICAgICAgcGVybWlzc2lvbiA9IHBlcm07CisgICAgICAgICAgICBlbGVtZW50cyA9IG5ldyBMaW5rZWRMaXN0PFNTVD4oKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNyZWF0ZXMgc2V0IGZyb20gc3BlY2lmaWVkIGNvbGxlY3Rpb24gd2l0aCBzcGVjaWZpZWQgcGVybWlzc2lvbgorICAgICAgICAvLyBhbGwgY29sbGVjdGlvbiBlbGVtZW50cyBhcmUgdmVyaWZpZWQgYmVmb3JlIGFkZGluZworICAgICAgICBwcm90ZWN0ZWQgU2VjdXJlU2V0KEF1dGhQZXJtaXNzaW9uIHBlcm0sIENvbGxlY3Rpb248PyBleHRlbmRzIFNTVD4gcykgeworICAgICAgICAgICAgdGhpcyhwZXJtKTsKKworICAgICAgICAgICAgLy8gU3ViamVjdCdzIGNvbnN0cnVjdG9yIHJlY2VpdmVzIGEgU2V0LCB3ZSBjYW4gdHJ1c3RzIGlmIGEgc2V0IGlzIGZyb20gYm9vdGNsYXNzcGF0aCwKKyAgICAgICAgICAgIC8vIGFuZCBub3QgdG8gY2hlY2sgd2hldGhlciBpdCBjb250YWlucyBkdXBsaWNhdGVzIG9yIG5vdAorICAgICAgICAgICAgYm9vbGVhbiB0cnVzdCA9IHMuZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpID09IG51bGw7CisKKyAgICAgICAgICAgIGZvciAoU1NUIG8gOiBzKSB7CisgICAgICAgICAgICAgICAgdmVyaWZ5RWxlbWVudChvKTsKKyAgICAgICAgICAgICAgICBpZiAodHJ1c3QgfHwgIWVsZW1lbnRzLmNvbnRhaW5zKG8pKSB7CisgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLmFkZChvKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyB2ZXJpZmllcyBuZXcgc2V0IGVsZW1lbnQKKyAgICAgICAgcHJpdmF0ZSB2b2lkIHZlcmlmeUVsZW1lbnQoT2JqZWN0IG8pIHsKKworICAgICAgICAgICAgaWYgKG8gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHBlcm1pc3Npb24gPT0gX1BSSU5DSVBBTFMgJiYgIShQcmluY2lwYWwuY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShvLmdldENsYXNzKCkpKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkVsZW1lbnQgaXMgbm90IGluc3RhbmNlIG9mIGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiB2ZXJpZmllcyBzcGVjaWZpZWQgZWxlbWVudCwgY2hlY2tzIHNldCBzdGF0ZSwgYW5kIHNlY3VyaXR5IHBlcm1pc3Npb24KKyAgICAgICAgICogdG8gbW9kaWZ5IHNldCBiZWZvcmUgYWRkaW5nIG5ldyBlbGVtZW50CisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gYWRkKFNTVCBvKSB7CisKKyAgICAgICAgICAgIHZlcmlmeUVsZW1lbnQobyk7CisKKyAgICAgICAgICAgIGNoZWNrU3RhdGUoKTsKKworICAgICAgICAgICAgaWYgKCFlbGVtZW50cy5jb250YWlucyhvKSkgeworICAgICAgICAgICAgICAgIGVsZW1lbnRzLmFkZChvKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHJldHVybnMgYW4gaW5zdGFuY2Ugb2YgU2VjdXJlSXRlcmF0b3IKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBJdGVyYXRvcjxTU1Q+IGl0ZXJhdG9yKCkgeworCisgICAgICAgICAgICBpZiAocGVybWlzc2lvbiA9PSBfUFJJVkFURV9DUkVERU5USUFMUykgeworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogcHJpdmF0ZSBjcmVkZW50aWFsIHNldCByZXF1aXJlcyBpdGVyYXRvciB3aXRoIGFkZGl0aW9uYWwKKyAgICAgICAgICAgICAgICAgKiBzZWN1cml0eSBjaGVjayAoUHJpdmF0ZUNyZWRlbnRpYWxQZXJtaXNzaW9uKQorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2VjdXJlSXRlcmF0b3IoZWxlbWVudHMuaXRlcmF0b3IoKSkgeworICAgICAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAgICAgKiBjaGVja3MgcGVybWlzc2lvbiB0byBhY2Nlc3MgbmV4dCBwcml2YXRlIGNyZWRlbnRpYWwgbW92ZXMKKyAgICAgICAgICAgICAgICAgICAgICogdG8gdGhlIG5leHQgZWxlbWVudCBldmVuIFNlY3VyaXR5RXhjZXB0aW9uIHdhcyB0aHJvd24KKyAgICAgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICBwdWJsaWMgU1NUIG5leHQoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBTU1Qgb2JqID0gaXRlcmF0b3IubmV4dCgpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9iajsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IFNlY3VyZUl0ZXJhdG9yKGVsZW1lbnRzLml0ZXJhdG9yKCkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIHJldGFpbkFsbChDb2xsZWN0aW9uPD8+IGMpIHsKKworICAgICAgICAgICAgaWYgKGMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnJldGFpbkFsbChjKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gZWxlbWVudHMuc2l6ZSgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIHJldHVybiBzZXQgd2l0aCBlbGVtZW50cyB0aGF0IGFyZSBpbnN0YW5jZXMgb3Igc3ViY2xhc3NlcyBvZiB0aGUKKyAgICAgICAgICogc3BlY2lmaWVkIGNsYXNzCisgICAgICAgICAqLworICAgICAgICBwcm90ZWN0ZWQgZmluYWwgPEU+IFNldDxFPiBnZXQoZmluYWwgQ2xhc3M8RT4gYykgeworCisgICAgICAgICAgICBpZiAoYyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEFic3RyYWN0U2V0PEU+IHMgPSBuZXcgQWJzdHJhY3RTZXQ8RT4oKSB7CisgICAgICAgICAgICAgICAgcHJpdmF0ZSBMaW5rZWRMaXN0PEU+IGVsZW1lbnRzID0gbmV3IExpbmtlZExpc3Q8RT4oKTsKKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGFkZChFIG8pIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFjLmlzQXNzaWduYWJsZUZyb20oby5nZXRDbGFzcygpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCB0eXBlOiAiICsgby5nZXRDbGFzcygpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50cy5jb250YWlucyhvKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLmFkZChvKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIEl0ZXJhdG9yPEU+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudHMuaXRlcmF0b3IoKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiByZXRhaW5BbGwoQ29sbGVjdGlvbjw/PiBjKSB7CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnJldGFpbkFsbChjKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50cy5zaXplKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfTsKKworICAgICAgICAgICAgLy8gRklYTUUgbXVzdCBoYXZlIHBlcm1pc3Npb25zIGZvciByZXF1ZXN0ZWQgcHJpdi4gY3JlZGVudGlhbHMKKyAgICAgICAgICAgIGZvciAoU1NUIG8gOiB0aGlzKSB7CisgICAgICAgICAgICAgICAgaWYgKGMuaXNBc3NpZ25hYmxlRnJvbShvLmdldENsYXNzKCkpKSB7CisgICAgICAgICAgICAgICAgICAgIHMuYWRkKGMuY2FzdChvKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHM7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICAgICAgaW4uZGVmYXVsdFJlYWRPYmplY3QoKTsKKworICAgICAgICAgICAgc3dpdGNoIChzZXRUeXBlKSB7CisgICAgICAgICAgICBjYXNlIFNFVF9QcmluY2lwYWw6CisgICAgICAgICAgICAgICAgcGVybWlzc2lvbiA9IF9QUklOQ0lQQUxTOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBTRVRfUHJpdkNyZWQ6CisgICAgICAgICAgICAgICAgcGVybWlzc2lvbiA9IF9QUklWQVRFX0NSRURFTlRJQUxTOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBTRVRfUHViQ3JlZDoKKyAgICAgICAgICAgICAgICBwZXJtaXNzaW9uID0gX1BVQkxJQ19DUkVERU5USUFMUzsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmb3IgKFNTVCBlbGVtZW50IDogZWxlbWVudHMpIHsKKyAgICAgICAgICAgICAgICB2ZXJpZnlFbGVtZW50KGVsZW1lbnQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIlVudXNlZERlY2xhcmF0aW9uIikKKyAgICAgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgICAgIGlmIChwZXJtaXNzaW9uID09IF9QUklWQVRFX0NSRURFTlRJQUxTKSB7CisgICAgICAgICAgICAgICAgc2V0VHlwZSA9IFNFVF9Qcml2Q3JlZDsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAocGVybWlzc2lvbiA9PSBfUFJJTkNJUEFMUykgeworICAgICAgICAgICAgICAgIHNldFR5cGUgPSBTRVRfUHJpbmNpcGFsOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzZXRUeXBlID0gU0VUX1B1YkNyZWQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIG91dC5kZWZhdWx0V3JpdGVPYmplY3QoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXByZXNlbnRzIGl0ZXJhdG9yIGZvciBzdWJqZWN0J3Mgc2VjdXJlIHNldAorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBjbGFzcyBTZWN1cmVJdGVyYXRvciBpbXBsZW1lbnRzIEl0ZXJhdG9yPFNTVD4geworICAgICAgICAgICAgcHJvdGVjdGVkIEl0ZXJhdG9yPFNTVD4gaXRlcmF0b3I7CisKKyAgICAgICAgICAgIHByb3RlY3RlZCBTZWN1cmVJdGVyYXRvcihJdGVyYXRvcjxTU1Q+IGl0ZXJhdG9yKSB7CisgICAgICAgICAgICAgICAgdGhpcy5pdGVyYXRvciA9IGl0ZXJhdG9yOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgICAgIHJldHVybiBpdGVyYXRvci5oYXNOZXh0KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBTU1QgbmV4dCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3IubmV4dCgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgICAqIGNoZWNrcyBzZXQgc3RhdGUsIGFuZCBzZWN1cml0eSBwZXJtaXNzaW9uIHRvIG1vZGlmeSBzZXQgYmVmb3JlCisgICAgICAgICAgICAgKiByZW1vdmluZyBjdXJyZW50IGVsZW1lbnQKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICAgICAgICAgIGNoZWNrU3RhdGUoKTsKKyAgICAgICAgICAgICAgICBpdGVyYXRvci5yZW1vdmUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9hdXRoL1N1YmplY3REb21haW5Db21iaW5lci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvU3ViamVjdERvbWFpbkNvbWJpbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDljMmYyNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9hdXRoL1N1YmplY3REb21haW5Db21iaW5lci5qYXZhCkBAIC0wLDAgKzEsMzIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguc2VjdXJpdHkuYXV0aDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuRG9tYWluQ29tYmluZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm90ZWN0aW9uRG9tYWluOworCisvKioKKyAqIExlZ2FjeSBzZWN1cml0eSBjb2RlOyBkbyBub3QgdXNlLgorICovCitwdWJsaWMgY2xhc3MgU3ViamVjdERvbWFpbkNvbWJpbmVyIGltcGxlbWVudHMgRG9tYWluQ29tYmluZXIgeworICAgIHB1YmxpYyBTdWJqZWN0RG9tYWluQ29tYmluZXIoU3ViamVjdCBzdWJqZWN0KSB7IH0KKworICAgIHB1YmxpYyBTdWJqZWN0IGdldFN1YmplY3QoKSB7IHJldHVybiBudWxsOyB9CisKKyAgICBwdWJsaWMgUHJvdGVjdGlvbkRvbWFpbltdIGNvbWJpbmUoUHJvdGVjdGlvbkRvbWFpbltdIGN1cnJlbnREb21haW5zLCBQcm90ZWN0aW9uRG9tYWluW10gYXNzaWduZWREb21haW5zKSB7IHJldHVybiBudWxsOyB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvYXV0aC9jYWxsYmFjay9DYWxsYmFjay5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvY2FsbGJhY2svQ2FsbGJhY2suamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ODU0ZDNmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvY2FsbGJhY2svQ2FsbGJhY2suamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2s7CisKKy8qKgorICogRGVmaW5lcyBhbiBlbXB0eSBiYXNlIGludGVyZmFjZSBmb3IgYWxsIHtAY29kZSBDYWxsYmFja31zIHVzZWQgZHVyaW5nCisgKiBhdXRoZW50aWNhdGlvbi4KKyAqLworcHVibGljIGludGVyZmFjZSBDYWxsYmFjayB7Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvY2FsbGJhY2svQ2FsbGJhY2tIYW5kbGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvYXV0aC9jYWxsYmFjay9DYWxsYmFja0hhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMWJmMzBiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvY2FsbGJhY2svQ2FsbGJhY2tIYW5kbGVyLmphdmEKQEAgLTAsMCArMSw1NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5zZWN1cml0eS5hdXRoLmNhbGxiYWNrOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBOZWVkcyB0byBiZSBpbXBsZW1lbnRlZCBieSBjbGFzc2VzIHRoYXQgd2FudCB0byBoYW5kbGUgYXV0aGVudGljYXRpb24KKyAqIHtAbGluayBDYWxsYmFja31zLiBBIHNpbmdsZSBtZXRob2Qge0BsaW5rICNoYW5kbGUoQ2FsbGJhY2tbXSl9IG11c3QgYmUKKyAqIHByb3ZpZGVkIHRoYXQgY2hlY2tzIHRoZSB0eXBlIG9mIHRoZSBpbmNvbWluZyB7QGNvZGUgQ2FsbGJhY2t9cyBhbmQgcmVhY3RzCisgKiBhY2NvcmRpbmdseS4ge0Bjb2RlIENhbGxiYWNrSGFuZGxlcn1zIGNhbiBiZSBpbnN0YWxsZWQgcGVyIGFwcGxpY2F0aW9uLiBJdCBpcworICogYWxzbyBwb3NzaWJsZSB0byBjb25maWd1cmUgYSBzeXN0ZW0tZGVmYXVsdCB7QGNvZGUgQ2FsbGJhY2tIYW5kbGVyfSBieQorICogc2V0dGluZyB0aGUge0Bjb2RlIGF1dGgubG9naW4uZGVmYXVsdENhbGxiYWNrSGFuZGxlcn0gcHJvcGVydHkgaW4gdGhlCisgKiBzdGFuZGFyZCB7QGNvZGUgc2VjdXJpdHkucHJvcGVydGllc30gZmlsZS4KKyAqLworcHVibGljIGludGVyZmFjZSBDYWxsYmFja0hhbmRsZXIgeworCisgICAgLyoqCisgICAgICogSGFuZGxlcyB0aGUgYWN0dWFsIHtAbGluayBDYWxsYmFja30uIEEge0Bjb2RlIENhbGxiYWNrSGFuZGxlcn0gbmVlZHMgdG8KKyAgICAgKiBpbXBsZW1lbnQgdGhpcyBtZXRob2QuIEluIHRoZSBtZXRob2QsIGl0IGlzIGZyZWUgdG8gc2VsZWN0IHdoaWNoIHtAY29kZQorICAgICAqIENhbGxiYWNrfXMgaXQgYWN0dWFsbHkgd2FudHMgdG8gaGFuZGxlIGFuZCBpbiB3aGljaCB3YXkuIEZvciBleGFtcGxlLCBhCisgICAgICogY29uc29sZS1iYXNlZCB7QGNvZGUgQ2FsbGJhY2tIYW5kbGVyfSBtaWdodCBjaG9vc2UgdG8gc2VxdWVudGlhbGx5IGFzaworICAgICAqIHRoZSB1c2VyIGZvciBsb2dpbiBhbmQgcGFzc3dvcmQsIGlmIGl0IGltcGxlbWVudHMgdGhlc2Uge0Bjb2RlIENhbGxiYWNrfQorICAgICAqIHMsIHdoZXJlYXMgYSBHVUktYmFzZWQgb25lIG1pZ2h0IG9wZW4gYSBzaW5nbGUgZGlhbG9nIHdpbmRvdyBmb3IgYm90aAorICAgICAqIHZhbHVlcy4gSWYgYSB7QGNvZGUgQ2FsbGJhY2tIYW5kbGVyfSBpcyBub3QgYWJsZSB0byBoYW5kbGUgYSBzcGVjaWZpYworICAgICAqIHtAY29kZSBDYWxsYmFja30sIGl0IG5lZWRzIHRvIHRocm93IGFuCisgICAgICoge0BsaW5rIFVuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb259LgorICAgICAqCisgICAgICogQHBhcmFtIGNhbGxiYWNrcworICAgICAqICAgICAgICAgICAgdGhlIGFycmF5IG9mIHtAY29kZSBDYWxsYmFja31zIHRoYXQgbmVlZCBoYW5kbGluZworICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJL08gcmVsYXRlZCBlcnJvciBvY2N1cnMKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUge0Bjb2RlIENhbGxiYWNrSGFuZGxlcn0gaXMgbm90IGFibGUgdG8gaGFuZGxlIGEKKyAgICAgKiAgICAgICAgICAgICBzcGVjaWZpYyB7QGNvZGUgQ2FsbGJhY2t9CisgICAgICovCisgICAgdm9pZCBoYW5kbGUoQ2FsbGJhY2tbXSBjYWxsYmFja3MpIHRocm93cyBJT0V4Y2VwdGlvbiwgVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbjsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvY2FsbGJhY2svUGFzc3dvcmRDYWxsYmFjay5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvY2FsbGJhY2svUGFzc3dvcmRDYWxsYmFjay5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEzZjgzM2UKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvYXV0aC9jYWxsYmFjay9QYXNzd29yZENhbGxiYWNrLmphdmEKQEAgLTAsMCArMSwxMjEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguc2VjdXJpdHkuYXV0aC5jYWxsYmFjazsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogVXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIGEge0BsaW5rIENhbGxiYWNrSGFuZGxlcn0gdG8gcmV0cmlldmUgYSBwYXNzd29yZAorICogd2hlbiBuZWVkZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBQYXNzd29yZENhbGxiYWNrIGltcGxlbWVudHMgQ2FsbGJhY2ssIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAyMjY3NDIyNjQ3NDU0OTA5OTI2TDsKKworICAgIHByaXZhdGUgU3RyaW5nIHByb21wdDsKKworICAgIGJvb2xlYW4gZWNob09uOworCisgICAgcHJpdmF0ZSBjaGFyW10gaW5wdXRQYXNzd29yZDsKKworICAgIHByaXZhdGUgdm9pZCBzZXRQcm9tcHQoU3RyaW5nIHByb21wdCkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwcm9tcHQgPT0gbnVsbCB8fCBwcm9tcHQubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBwcm9tcHQiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnByb21wdCA9IHByb21wdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBQYXNzd29yZENhbGxiYWNrfSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcm9tcHQKKyAgICAgKiAgICAgICAgICAgIHRoZSBtZXNzYWdlIHRoYXQgc2hvdWxkIGJlIGRpc3BsYXllZCB0byB0aGUgdXNlcgorICAgICAqIEBwYXJhbSBlY2hvT24KKyAgICAgKiAgICAgICAgICAgIGRldGVybWluZXMgd2hldGhlciB0aGUgdXNlciBpbnB1dCBzaG91bGQgYmUgZWNob2VkCisgICAgICovCisgICAgcHVibGljIFBhc3N3b3JkQ2FsbGJhY2soU3RyaW5nIHByb21wdCwgYm9vbGVhbiBlY2hvT24pIHsKKyAgICAgICAgc2V0UHJvbXB0KHByb21wdCk7CisgICAgICAgIHRoaXMuZWNob09uID0gZWNob09uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByb21wdCB0aGF0IHdhcyBzcGVjaWZpZWQgd2hlbiBjcmVhdGluZyB0aGlzIHtAY29kZQorICAgICAqIFBhc3N3b3JkQ2FsbGJhY2t9CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcm9tcHQKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFByb21wdCgpIHsKKyAgICAgICAgcmV0dXJuIHByb21wdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBRdWVyaWVzIHdoZXRoZXIgdGhpcyB7QGNvZGUgUGFzc3dvcmRDYWxsYmFja30gZXhwZWN0cyB1c2VyIGlucHV0IHRvIGJlCisgICAgICogZWNob2VkLCB3aGljaCBpcyBzcGVjaWZpZWQgZHVyaW5nIHRoZSBjcmVhdGlvbiBvZiB0aGUgb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgKGFuZCBvbmx5IGlmKSB1c2VyIGlucHV0IHNob3VsZCBiZSBlY2hvZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VjaG9PbigpIHsKKyAgICAgICAgcmV0dXJuIGVjaG9PbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwYXNzd29yZC4gVGhlIHtAbGluayBDYWxsYmFja0hhbmRsZXJ9IHRoYXQgcGVyZm9ybXMgdGhlIGFjdHVhbAorICAgICAqIHByb3Zpc2lvbmluZyBvciBpbnB1dCBvZiB0aGUgcGFzc3dvcmQgbmVlZHMgdG8gY2FsbCB0aGlzIG1ldGhvZCB0byBoYW5kCisgICAgICogYmFjayB0aGUgcGFzc3dvcmQgdG8gdGhlIHNlY3VyaXR5IHNlcnZpY2UgdGhhdCByZXF1ZXN0ZWQgaXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFzc3dvcmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXNzd29yZC4gQSBjb3B5IG9mIHRoaXMgaXMgc3RvcmVkLCBzbyBzdWJzZXF1ZW50IGNoYW5nZXMKKyAgICAgKiAgICAgICAgICAgIHRvIHRoZSBpbnB1dCBhcnJheSBkbyBub3QgYWZmZWN0IHRoZSB7QGNvZGUgUGFzc3dvcmRDYWxsYmFja30uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UGFzc3dvcmQoY2hhcltdIHBhc3N3b3JkKSB7CisgICAgICAgIGlmIChwYXNzd29yZCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aGlzLmlucHV0UGFzc3dvcmQgPSBwYXNzd29yZDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlucHV0UGFzc3dvcmQgPSBuZXcgY2hhcltwYXNzd29yZC5sZW5ndGhdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShwYXNzd29yZCwgMCwgaW5wdXRQYXNzd29yZCwgMCwgaW5wdXRQYXNzd29yZC5sZW5ndGgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGFzc3dvcmQuIFRoZSBzZWN1cml0eSBzZXJ2aWNlIHRoYXQgbmVlZHMgdGhlIHBhc3N3b3JkCisgICAgICogdXN1YWxseSBjYWxscyB0aGlzIG1ldGhvZCBvbmNlIHRoZSB7QGxpbmsgQ2FsbGJhY2tIYW5kbGVyfSBoYXMgZmluaXNoZWQKKyAgICAgKiBpdHMgd29yay4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHBhc3N3b3JkLiBBIGNvcHkgb2YgdGhlIGludGVybmFsIHBhc3N3b3JkIGlzIGNyZWF0ZWQgYW5kCisgICAgICogICAgICAgICByZXR1cm5lZCwgc28gc3Vic2VxdWVudCBjaGFuZ2VzIHRvIHRoZSBpbnRlcm5hbCBwYXNzd29yZCBkbyBub3QKKyAgICAgKiAgICAgICAgIGFmZmVjdCB0aGUgcmVzdWx0LgorICAgICAqLworICAgIHB1YmxpYyBjaGFyW10gZ2V0UGFzc3dvcmQoKSB7CisgICAgICAgIGlmIChpbnB1dFBhc3N3b3JkICE9IG51bGwpIHsKKyAgICAgICAgICAgIGNoYXJbXSB0bXAgPSBuZXcgY2hhcltpbnB1dFBhc3N3b3JkLmxlbmd0aF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGlucHV0UGFzc3dvcmQsIDAsIHRtcCwgMCwgdG1wLmxlbmd0aCk7CisgICAgICAgICAgICByZXR1cm4gdG1wOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsZWFycyB0aGUgcGFzc3dvcmQgc3RvcmVkIGluIHRoaXMge0Bjb2RlIFBhc3N3b3JkQ2FsbGJhY2t9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsZWFyUGFzc3dvcmQoKSB7CisgICAgICAgIGlmIChpbnB1dFBhc3N3b3JkICE9IG51bGwpIHsKKyAgICAgICAgICAgIEFycmF5cy5maWxsKGlucHV0UGFzc3dvcmQsICdcdTAwMDAnKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9hdXRoL2NhbGxiYWNrL1Vuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9hdXRoL2NhbGxiYWNrL1Vuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YzViNWU0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvY2FsbGJhY2svVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguc2VjdXJpdHkuYXV0aC5jYWxsYmFjazsKKworLyoqCisgKiBUaHJvd24gd2hlbiBhIHtAbGluayBDYWxsYmFja0hhbmRsZXJ9IGRvZXMgbm90IHN1cHBvcnQgYSBwYXJ0aWN1bGFyIHtAbGluaworICogQ2FsbGJhY2t9LgorICovCitwdWJsaWMgY2xhc3MgVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjg3MzU1NjMyNzY1NTY2NjgzOUw7CisKKyAgICBwcml2YXRlIENhbGxiYWNrIGNhbGxiYWNrOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBleGNlcHRpb24gaW5zdGFuY2UgYW5kIGluaXRpYWxpemVzIGl0IHdpdGgganVzdCB0aGUKKyAgICAgKiB1bnN1cHBvcnRlZCB7QGNvZGUgQ2FsbGJhY2t9LCBidXQgbm8gZXJyb3IgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYWxsYmFjaworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDYWxsYmFja30KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbihDYWxsYmFjayBjYWxsYmFjaykgeworICAgICAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBleGNlcHRpb24gaW5zdGFuY2UgYW5kIGluaXRpYWxpemVzIGl0IHdpdGggYm90aCB0aGUKKyAgICAgKiB1bnN1cHBvcnRlZCB7QGNvZGUgQ2FsbGJhY2t9IGFuZCBhbiBlcnJvciBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGNhbGxiYWNrCisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIENhbGxiYWNrfQorICAgICAqIEBwYXJhbSBtZXNzYWdlCisgICAgICogICAgICAgICAgICB0aGUgZXJyb3IgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBVbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uKENhbGxiYWNrIGNhbGxiYWNrLCBTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICAgICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHVuc3VwcG9ydGVkIHtAY29kZSBDYWxsYmFja30gdGhhdCB0cmlnZ2VyZWQgdGhpcyBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgQ2FsbGJhY2t9CisgICAgICovCisgICAgcHVibGljIENhbGxiYWNrIGdldENhbGxiYWNrKCkgeworICAgICAgICByZXR1cm4gY2FsbGJhY2s7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvY2FsbGJhY2svcGFja2FnZS5odG1sIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvY2FsbGJhY2svcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxMDI5NTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvYXV0aC9jYWxsYmFjay9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwyMSBAQAorPGh0bWw+Cis8aGVhZD4KKzxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXVzLWFzY2lpIj4KKzwvaGVhZD4KKzxodG1sPgorPGJvZHk+Cis8cD4KK1RoaXMgcGFja2FnZSBwcm92aWRlcyBjbGFzc2VzIGFuZCBpbnRlcmZhY2VzIG5lZWRlZCB0byBpbnRlcmFjdCB3aXRoIHRoZQorYXBwbGljYXRpb24gaW4gb3JkZXIgdG8gZXhlY3V0ZSB0aGUgYXV0aGVudGljYXRpb24gYW5kIGF1dGhvcml6YXRpb24KK3Byb2Nlc3Nlcy4gSXQgaXMgYSBjbGFzc2ljYWwgY2FsbGJhY2sgbWVjaGFuaXNtOiBvbmUgcmV0cmlldmVzIGluZm9ybWF0aW9uIChpLmUuCitmb3IgYXV0aGVudGljYXRpb24gcHVycG9zZXMpIGFuZCBvbmUgZGlzcGxheSBzb21lIG1lc3NhZ2VzIChmb3IgZXhhbXBsZSBlcnJvcgorbWVzc2FnZXMpLgorPC9wPgorPHA+CitOb3RlIHRoYXQgdGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBwYWNrYWdlIGlzIG5vdCBjb21wbGV0ZSwgdGhhdCBpcywKK25vdCBjb21wYXRpYmxlIHdpdGggZGVza3RvcCBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlIEphdmEgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuCitJdCBjb250YWlucyBvbmx5IHdoYXQgd2FzIG5lZWRlZCB0byBtYWtlIHRoZSBjb21waWxlciBoYXBweSwgdGhhdCBpcywgY2xhc3NlcworcmVxdWlyZWQgYnkgb3RoZXIgcGFja2FnZXMuIAorPC9wPgorPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvbG9naW4vTG9naW5FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9hdXRoL2xvZ2luL0xvZ2luRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTdjYTJmNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9hdXRoL2xvZ2luL0xvZ2luRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5zZWN1cml0eS5hdXRoLmxvZ2luOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb247CisKKy8qKgorICogQmFzZSBjbGFzcyBmb3IgZXhjZXB0aW9ucyB0aGF0IGFyZSB0aHJvd24gd2hlbiBhIGxvZ2luIGVycm9yIG9jY3Vycy4KKyAqLworcHVibGljIGNsYXNzIExvZ2luRXhjZXB0aW9uIGV4dGVuZHMgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00Njc5MDkxNjI0MDM1MjMyNDg4TDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgZXhjZXB0aW9uIGluc3RhbmNlIGFuZCBpbml0aWFsaXplcyBpdCB3aXRoIGRlZmF1bHQgdmFsdWVzLgorICAgICAqLworICAgIHB1YmxpYyBMb2dpbkV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGV4Y2VwdGlvbiBpbnN0YW5jZSBhbmQgaW5pdGlhbGl6ZXMgaXQgd2l0aCBhIGdpdmVuIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZSB0aGUgZXJyb3IgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBMb2dpbkV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9hdXRoL2xvZ2luL3BhY2thZ2UuaHRtbCBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9hdXRoL2xvZ2luL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMjcwOTgwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgvbG9naW4vcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMTkgQEAKKzxodG1sPgorPGhlYWQ+Cis8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD11cy1hc2NpaSI+Cis8L2hlYWQ+Cis8aHRtbD4KKzxib2R5PgorPHA+CitUaGlzIHBhY2thZ2UgcHJvdmlkZXMgYSBwbHVnZ2FibGUgYW5kIHN0YWNrYWJsZSBhdXRoZW50aWNhdGlvbiBzeXN0ZW0gYmFzZWQgb24KK2lkZWFzIGFuZCBjb25jZXB0cyBmcm9tIHRoZSBVbml4LVBBTSBtb2R1bGUuIE5ldyBhdXRoZW50aWNhdGlvbiBtZXRob2RzIGNhbiBiZQorc3BlY2lmaWVkIHNpbXBseSB2aWEgYSBuZXcgTG9naW5Nb2R1bGUgYW5kIGNoYWluZWQgdG9nZXRoZXIgd2l0aCB0aGUgZXhpc3RpbmcKK29uZXMuCis8L3A+CitOb3RlIHRoYXQgdGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBwYWNrYWdlIGlzIG5vdCBjb21wbGV0ZSwgdGhhdCBpcywKK25vdCBjb21wYXRpYmxlIHdpdGggZGVza3RvcCBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlIEphdmEgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuCitJdCBjb250YWlucyBvbmx5IHdoYXQgd2FzIG5lZWRlZCB0byBtYWtlIHRoZSBjb21waWxlciBoYXBweSwgdGhhdCBpcywgY2xhc3NlcworcmVxdWlyZWQgYnkgb3RoZXIgcGFja2FnZXMuIAorPC9wPgorPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgveDUwMC9YNTAwUHJpbmNpcGFsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvYXV0aC94NTAwL1g1MDBQcmluY2lwYWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjQ1M2U5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2F1dGgveDUwMC9YNTAwUHJpbmNpcGFsLmphdmEKQEAgLTAsMCArMSwzMTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QcmluY2lwYWw7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwMS5OYW1lOworCisvKioKKyAqIFJlcHJlc2VudHMgYW4gWC41MDAgcHJpbmNpcGFsLCB3aGljaCBob2xkcyB0aGUgZGlzdGluZ3Vpc2hlZCBuYW1lIG9mIHNvbWUKKyAqIG5ldHdvcmsgZW50aXR5LiBBbiBleGFtcGxlIG9mIGEgZGlzdGluZ3Vpc2hlZCBuYW1lIGlzIHtAY29kZSAiTz1Tb21lT3JnLAorICogT1U9U29tZU9yZ1VuaXQsIEM9VVMifS4gVGhlIGNsYXNzIGNhbiBiZSBpbnN0YW50aWF0ZWQgZnJvbSBhIGJ5dGUgcmVwcmVzZW50YXRpb24KKyAqIG9mIGFuIG9iamVjdCBpZGVudGlmaWVyIChPSUQpLCBhbiBBU04uMSBERVItZW5jb2RlZCB2ZXJzaW9uLCBvciBhIHNpbXBsZQorICogc3RyaW5nIGhvbGRpbmcgdGhlIGRpc3Rpbmd1aXNoZWQgbmFtZS4gVGhlIHJlcHJlc2VudGF0aW9ucyBtdXN0IGZvbGxvdyBlaXRoZXIKKyAqIFJGQyAyMjUzLCBSRkMgMTc3OSwgb3IgUkZDMjQ1OS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFg1MDBQcmluY2lwYWwgaW1wbGVtZW50cyBTZXJpYWxpemFibGUsIFByaW5jaXBhbCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTAwNDYzMzQ4MTExMzQ1NzIxTDsKKworICAgIC8qKgorICAgICAqIERlZmluZXMgYSBjb25zdGFudCBmb3IgdGhlIGNhbm9uaWNhbCBzdHJpbmcgZm9ybWF0IG9mIGRpc3Rpbmd1aXNoZWQKKyAgICAgKiBuYW1lcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDQU5PTklDQUwgPSAiQ0FOT05JQ0FMIjsKKworICAgIC8qKgorICAgICAqIERlZmluZXMgYSBjb25zdGFudCBmb3IgdGhlIFJGQyAxNzc5IHN0cmluZyBmb3JtYXQgb2YgZGlzdGluZ3Vpc2hlZAorICAgICAqIG5hbWVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFJGQzE3NzkgPSAiUkZDMTc3OSI7CisKKyAgICAvKioKKyAgICAgKiBEZWZpbmVzIGEgY29uc3RhbnQgZm9yIHRoZSBSRkMgMjI1MyBzdHJpbmcgZm9ybWF0IG9mIGRpc3Rpbmd1aXNoZWQKKyAgICAgKiBuYW1lcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBSRkMyMjUzID0gIlJGQzIyNTMiOworCisgICAgLy9EaXN0aW5ndWlzaGVkIE5hbWUKKyAgICBwcml2YXRlIHRyYW5zaWVudCBOYW1lIGRuOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBYNTAwUHJpbmNpcGFsIGZyb20gYSBnaXZlbiBBU04uMSBERVIgZW5jb2Rpbmcgb2YgYQorICAgICAqIGRpc3Rpbmd1aXNoZWQgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogICAgICAgICAgICB0aGUgQVNOLjEgREVSLWVuY29kZWQgZGlzdGluZ3Vpc2hlZCBuYW1lCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBBU04uMSBERVItZW5jb2RlZCBkaXN0aW5ndWlzaGVkIG5hbWUgaXMgaW5jb3JyZWN0CisgICAgICovCisgICAgcHVibGljIFg1MDBQcmluY2lwYWwoYnl0ZVtdIG5hbWUpIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTmFtZSBjYW5ub3QgYmUgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBGSVhNRSBkbiA9IG5ldyBOYW1lKG5hbWUpOworICAgICAgICAgICAgZG4gPSAoTmFtZSkgTmFtZS5BU04xLmRlY29kZShuYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgaW5jb3JyZWN0SW5wdXRFbmNvZGluZyhlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgWDUwMFByaW5jaXBhbCBmcm9tIGEgZ2l2ZW4gQVNOLjEgREVSIGVuY29kaW5nIG9mIGEKKyAgICAgKiBkaXN0aW5ndWlzaGVkIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiAgICAgICAgICAgIGFuIHtAY29kZSBJbnB1dFN0cmVhbX0gaG9sZGluZyB0aGUgQVNOLjEgREVSLWVuY29kZWQKKyAgICAgKiAgICAgICAgICAgIGRpc3Rpbmd1aXNoZWQgbmFtZQorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgQVNOLjEgREVSLWVuY29kZWQgZGlzdGluZ3Vpc2hlZCBuYW1lIGlzIGluY29ycmVjdAorICAgICAqLworICAgIHB1YmxpYyBYNTAwUHJpbmNpcGFsKElucHV0U3RyZWFtIGluKSB7CisgICAgICAgIGlmIChpbiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImluID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gRklYTUUgZG4gPSBuZXcgTmFtZShpcyk7CisgICAgICAgICAgICBkbiA9IChOYW1lKSBOYW1lLkFTTjEuZGVjb2RlKGluKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgaW5jb3JyZWN0SW5wdXRFbmNvZGluZyhlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGluY29ycmVjdElucHV0RW5jb2RpbmcoSU9FeGNlcHRpb24gZSkgeworICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlID0gbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW5jb3JyZWN0IGlucHV0IGVuY29kaW5nIik7CisgICAgICAgIGlhZS5pbml0Q2F1c2UoZSk7CisgICAgICAgIHRocm93IGlhZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IFg1MDBQcmluY2lwYWwgZnJvbSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhCisgICAgICogZGlzdGluZ3Vpc2hlZCBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGRpc3Rpbmd1aXNoZWQgbmFtZQorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkaXN0aW5ndWlzaGVkIG5hbWUgaXMKKyAgICAgKiAgICAgICAgICAgICBpbmNvcnJlY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgWDUwMFByaW5jaXBhbChTdHJpbmcgbmFtZSkgeworICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIk5hbWUgY2Fubm90IGJlIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZG4gPSBuZXcgTmFtZShuYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgaW5jb3JyZWN0SW5wdXROYW1lKGUsIG5hbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFg1MDBQcmluY2lwYWwoU3RyaW5nIG5hbWUsIE1hcDxTdHJpbmcsU3RyaW5nPiBrZXl3b3JkTWFwKXsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJOYW1lIGNhbm5vdCBiZSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRuID0gbmV3IE5hbWUoc3Vic3RpdHV0ZU5hbWVGcm9tTWFwKG5hbWUsIGtleXdvcmRNYXApKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgaW5jb3JyZWN0SW5wdXROYW1lKGUsIG5hbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaW5jb3JyZWN0SW5wdXROYW1lKElPRXhjZXB0aW9uIGUsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUgPSBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbmNvcnJlY3QgaW5wdXQgbmFtZToiICsgbmFtZSk7CisgICAgICAgIGlhZS5pbml0Q2F1c2UoZSk7CisgICAgICAgIHRocm93IGlhZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHRyYW5zaWVudCBTdHJpbmcgY2Fub25pY2FsTmFtZTsKKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCBTdHJpbmcgZ2V0Q2Fub25pY2FsTmFtZSgpIHsKKyAgICAgICAgaWYgKGNhbm9uaWNhbE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgY2Fub25pY2FsTmFtZSA9IGRuLmdldE5hbWUoQ0FOT05JQ0FMKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2Fub25pY2FsTmFtZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgaWYgKHRoaXMgPT0gbykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG8gPT0gbnVsbCB8fCB0aGlzLmdldENsYXNzKCkgIT0gby5nZXRDbGFzcygpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgWDUwMFByaW5jaXBhbCBwcmluY2lwYWwgPSAoWDUwMFByaW5jaXBhbCkgbzsKKyAgICAgICAgcmV0dXJuIGdldENhbm9uaWNhbE5hbWUoKS5lcXVhbHMocHJpbmNpcGFsLmdldENhbm9uaWNhbE5hbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBBU04uMSBERVItZW5jb2RlZCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZGlzdGluZ3Vpc2hlZCBuYW1lCisgICAgICogY29udGFpbmVkIGluIHRoaXMgWC41MDAgcHJpbmNpcGFsLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgQVNOLjEgREVSLWVuY29kZWQgcmVwcmVzZW50YXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGJ5dGVbXSBzcmMgPSBkbi5nZXRFbmNvZGVkKCk7CisgICAgICAgIGJ5dGVbXSBkc3QgPSBuZXcgYnl0ZVtzcmMubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzcmMsIDAsIGRzdCwgMCwgZHN0Lmxlbmd0aCk7CisgICAgICAgIHJldHVybiBkc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGh1bWFuLXJlYWRhYmxlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZGlzdGluZ3Vpc2hlZCBuYW1lCisgICAgICogY29udGFpbmVkIGluIHRoaXMgWC41MDAgcHJpbmNpcGFsLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gZG4uZ2V0TmFtZShSRkMyMjUzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkaXN0aW5ndWlzaGVkIG5hbWUgY29udGFpbmVkIGluCisgICAgICogdGhpcyBYLjUwMCBwcmluY2lwYWwuIFRoZSBmb3JtYXQgb2YgdGhlIHJlcHJlc2VudGF0aW9uIGNhbiBiZSBjaG9zZW4uCisgICAgICogVmFsaWQgYXJndW1lbnRzIGFyZSB7QGxpbmsgI1JGQzE3Nzl9LCB7QGxpbmsgI1JGQzIyNTN9LCBhbmQKKyAgICAgKiB7QGxpbmsgI0NBTk9OSUNBTH0uIFRoZSByZXByZXNlbnRhdGlvbnMgYXJlIHNwZWNpZmllZCBpbiBSRkMgMTc3OSBhbmQgUkZDCisgICAgICogMjI1MywgcmVzcGVjdGl2ZWx5LiBUaGUgY2Fub25pY2FsIGZvcm0gaXMgYmFzZWQgb24gUkZDIDIyNTMsIGJ1dCBhZGRzCisgICAgICogc29tZSBjYW5vbmljYWxpemluZyBvcGVyYXRpb25zIGxpa2UgcmVtb3ZpbmcgbGVhZGluZyBhbmQgdHJhaWxpbmcKKyAgICAgKiB3aGl0ZXNwYWNlLCBsb3dlci1jYXNpbmcgdGhlIHdob2xlIG5hbWUsIGFuZCBicmluZ2luZyBpdCBpbnRvIGEKKyAgICAgKiBub3JtYWxpemVkIFVuaWNvZGUgcmVwcmVzZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9ybWF0CisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgZm9ybWF0IHRvIHVzZSBmb3IgdGhlIHJlcHJlc2VudGF0aW9uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHtAY29kZSBmb3JtYXR9IGFyZ3VtZW50IGlzIG5vdCBvbmUgb2YgdGhlIHRocmVlCisgICAgICogICAgICAgICAgICAgbWVudGlvbmVkIGFib3ZlCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKFN0cmluZyBmb3JtYXQpIHsKKyAgICAgICAgaWYgKENBTk9OSUNBTC5lcXVhbHMoZm9ybWF0KSkgeworICAgICAgICAgICAgcmV0dXJuIGdldENhbm9uaWNhbE5hbWUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBkbi5nZXROYW1lKGZvcm1hdCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKFN0cmluZyBmb3JtYXQsIE1hcDxTdHJpbmcsIFN0cmluZz4gb2lkTWFwKSB7CisgICAgICAgIFN0cmluZyByZmMxNzc5TmFtZSA9IGRuLmdldE5hbWUoUkZDMTc3OSk7CisgICAgICAgIFN0cmluZyByZmMyMjUzTmFtZSA9IGRuLmdldE5hbWUoUkZDMjI1Myk7CisKKyAgICAgICAgaWYgKGZvcm1hdC5lcXVhbHNJZ25vcmVDYXNlKCJSRkMxNzc5IikpIHsKKyAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0TmFtZSA9IG5ldyBTdHJpbmdCdWlsZGVyKHJmYzE3NzlOYW1lKTsKKyAgICAgICAgICAgIGludCBmcm9tSW5kZXggPSByZXN1bHROYW1lLmxlbmd0aCgpOworICAgICAgICAgICAgaW50IGVxdWFsSW5kZXggPSAtMTsKKyAgICAgICAgICAgIHdoaWxlICgtMSAhPSAoZXF1YWxJbmRleCA9IHJlc3VsdE5hbWUubGFzdEluZGV4T2YoIj0iLCBmcm9tSW5kZXgpKSkgeworICAgICAgICAgICAgICAgIGludCBjb21tYUluZGV4ID0gcmVzdWx0TmFtZS5sYXN0SW5kZXhPZigiLCIsIGVxdWFsSW5kZXgpOworICAgICAgICAgICAgICAgIFN0cmluZyBzdWJOYW1lID0gcmVzdWx0TmFtZS5zdWJzdHJpbmcoY29tbWFJbmRleCArIDEsCisgICAgICAgICAgICAgICAgICAgICAgICBlcXVhbEluZGV4KS50cmltKCk7CisgICAgICAgICAgICAgICAgaWYgKHN1Yk5hbWUubGVuZ3RoKCkgPiA0CisgICAgICAgICAgICAgICAgICAgICAgICAmJiBzdWJOYW1lLnN1YnN0cmluZygwLCA0KS5lcXVhbHMoIk9JRC4iKSkgeworICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc3ViU3ViTmFtZSA9IHN1Yk5hbWUuc3Vic3RyaW5nKDQpOworICAgICAgICAgICAgICAgICAgICBpZiAob2lkTWFwLmNvbnRhaW5zS2V5KHN1YlN1Yk5hbWUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcmVwbGFjZU5hbWUgPSBvaWRNYXAuZ2V0KHN1YlN1Yk5hbWUpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYoY29tbWFJbmRleCA+IDApIHJlcGxhY2VOYW1lID0gIiAiICsgcmVwbGFjZU5hbWU7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHROYW1lLnJlcGxhY2UoY29tbWFJbmRleCArIDEsIGVxdWFsSW5kZXgsIHJlcGxhY2VOYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmcm9tSW5kZXggPSBjb21tYUluZGV4OworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJlc3VsdE5hbWUudG9TdHJpbmcoKTsKKyAgICAgICAgfSBlbHNlIGlmIChmb3JtYXQuZXF1YWxzSWdub3JlQ2FzZSgiUkZDMjI1MyIpKSB7CisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdE5hbWUgPSBuZXcgU3RyaW5nQnVpbGRlcihyZmMyMjUzTmFtZSk7CisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHN1YnNpZHlOYW1lID0gbmV3IFN0cmluZ0J1aWxkZXIocmZjMTc3OU5hbWUpOworCisgICAgICAgICAgICBpbnQgZnJvbUluZGV4ID0gcmVzdWx0TmFtZS5sZW5ndGgoKTsKKyAgICAgICAgICAgIGludCBzdWJzaWR5RnJvbUluZGV4ID0gc3Vic2lkeU5hbWUubGVuZ3RoKCk7CisgICAgICAgICAgICBpbnQgZXF1YWxJbmRleCA9IC0xOworICAgICAgICAgICAgaW50IHN1YnNpZHlFcXVhbEluZGV4ID0gLTE7CisgICAgICAgICAgICB3aGlsZSAoLTEgIT0gKGVxdWFsSW5kZXggPSByZXN1bHROYW1lLmxhc3RJbmRleE9mKCI9IiwgZnJvbUluZGV4KSkpIHsKKyAgICAgICAgICAgICAgICBzdWJzaWR5RXF1YWxJbmRleCA9IHN1YnNpZHlOYW1lLmxhc3RJbmRleE9mKCI9IiwKKyAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNpZHlGcm9tSW5kZXgpOworICAgICAgICAgICAgICAgIGludCBjb21tYUluZGV4ID0gcmVzdWx0TmFtZS5sYXN0SW5kZXhPZigiLCIsIGVxdWFsSW5kZXgpOworICAgICAgICAgICAgICAgIFN0cmluZyBzdWJOYW1lID0gcmVzdWx0TmFtZS5zdWJzdHJpbmcoY29tbWFJbmRleCArIDEsCisgICAgICAgICAgICAgICAgICAgICAgICBlcXVhbEluZGV4KS50cmltKCk7CisgICAgICAgICAgICAgICAgaWYgKG9pZE1hcC5jb250YWluc0tleShzdWJOYW1lKSkgeworICAgICAgICAgICAgICAgICAgICBpbnQgc3ViT3JpZ25hbEVuZEluZGV4ID0gcmVzdWx0TmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKCIsIiwgZXF1YWxJbmRleCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChzdWJPcmlnbmFsRW5kSW5kZXggPT0gLTEpCisgICAgICAgICAgICAgICAgICAgICAgICBzdWJPcmlnbmFsRW5kSW5kZXggPSByZXN1bHROYW1lLmxlbmd0aCgpOworICAgICAgICAgICAgICAgICAgICBpbnQgc3ViR29hbEVuZEluZGV4ID0gc3Vic2lkeU5hbWUuaW5kZXhPZigiLCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2lkeUVxdWFsSW5kZXgpOworICAgICAgICAgICAgICAgICAgICBpZiAoc3ViR29hbEVuZEluZGV4ID09IC0xKQorICAgICAgICAgICAgICAgICAgICAgICAgc3ViR29hbEVuZEluZGV4ID0gc3Vic2lkeU5hbWUubGVuZ3RoKCk7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdE5hbWUucmVwbGFjZShlcXVhbEluZGV4ICsgMSwgc3ViT3JpZ25hbEVuZEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNpZHlOYW1lLnN1YnN0cmluZyhzdWJzaWR5RXF1YWxJbmRleCArIDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJHb2FsRW5kSW5kZXgpKTsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0TmFtZS5yZXBsYWNlKGNvbW1hSW5kZXggKyAxLCBlcXVhbEluZGV4LCBvaWRNYXAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0KHN1Yk5hbWUpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZnJvbUluZGV4ID0gY29tbWFJbmRleDsKKyAgICAgICAgICAgICAgICBzdWJzaWR5RnJvbUluZGV4ID0gc3Vic2lkeUVxdWFsSW5kZXggLSAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJlc3VsdE5hbWUudG9TdHJpbmcoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImludmFsaWQgZm9ybWF0IHNwZWNpZmllZDogIiArIGZvcm1hdCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gZ2V0Q2Fub25pY2FsTmFtZSgpLmhhc2hDb2RlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIGRuLmdldE5hbWUoUkZDMTc3OSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC53cml0ZU9iamVjdChkbi5nZXRFbmNvZGVkKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBkbiA9IChOYW1lKSBOYW1lLkFTTjEuZGVjb2RlKChieXRlW10pIGluLnJlYWRPYmplY3QoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgc3Vic3RpdHV0ZU5hbWVGcm9tTWFwKFN0cmluZyBuYW1lLCBNYXA8U3RyaW5nLCBTdHJpbmc+IGtleXdvcmRNYXApIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYk5hbWUgPSBuZXcgU3RyaW5nQnVpbGRlcihuYW1lKTsKKyAgICAgICAgaW50IGZyb21JbmRleCA9IHNiTmFtZS5sZW5ndGgoKTsKKyAgICAgICAgaW50IGVxdWFsSW5kZXg7CisgICAgICAgIHdoaWxlICgtMSAhPSAoZXF1YWxJbmRleCA9IHNiTmFtZS5sYXN0SW5kZXhPZigiPSIsIGZyb21JbmRleCkpKSB7CisgICAgICAgICAgICBpbnQgY29tbWFJbmRleCA9IHNiTmFtZS5sYXN0SW5kZXhPZigiLCIsIGVxdWFsSW5kZXgpOworICAgICAgICAgICAgU3RyaW5nIHN1Yk5hbWUgPSBzYk5hbWUuc3Vic3RyaW5nKGNvbW1hSW5kZXggKyAxLCBlcXVhbEluZGV4KS50cmltKCk7CisgICAgICAgICAgICBpZiAoa2V5d29yZE1hcC5jb250YWluc0tleShzdWJOYW1lKSkgeworICAgICAgICAgICAgICAgIHNiTmFtZS5yZXBsYWNlKGNvbW1hSW5kZXggKyAxLCBlcXVhbEluZGV4LCBrZXl3b3JkTWFwLmdldChzdWJOYW1lKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmcm9tSW5kZXggPSBjb21tYUluZGV4OworICAgICAgICB9CisgICAgICAgIHJldHVybiBzYk5hbWUudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvYXV0aC94NTAwL3BhY2thZ2UuaHRtbCBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9hdXRoL3g1MDAvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY3YzQ4NGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvYXV0aC94NTAwL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDE3IEBACis8aHRtbD4KKzxoZWFkPgorPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXMtYXNjaWkiPgorPC9oZWFkPgorPGh0bWw+Cis8Ym9keT4KKzxwPgorVGhpcyBwYWNrYWdlIHByb3ZpZGVzIGNsYXNzZXMgbmVlZGVkIHRvIHN0b3JlIFguNTAwIHByaW5jaXBhbHMgYW5kIHRoZWlyCitjcmVkZW50aWFscy4KKzwvcD4KK05vdGUgdGhhdCB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIHBhY2thZ2UgaXMgbm90IGNvbXBsZXRlLCB0aGF0IGlzLAorbm90IGNvbXBhdGlibGUgd2l0aCBkZXNrdG9wIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgSmF2YSBwcm9ncmFtbWluZyBsYW5ndWFnZS4KK0l0IGNvbnRhaW5zIG9ubHkgd2hhdCB3YXMgbmVlZGVkIHRvIG1ha2UgdGhlIGNvbXBpbGVyIGhhcHB5LCB0aGF0IGlzLCBjbGFzc2VzCityZXF1aXJlZCBieSBvdGhlciBwYWNrYWdlcy4gCis8L3A+Cis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iM2UzMWY2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGUuamF2YQpAQCAtMCwwICsxLDE2MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmVFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBBYnN0cmFjdCBjbGFzcyB0byByZXByZXNlbnQgaWRlbnRpdHkgY2VydGlmaWNhdGVzLiBJdCByZXByZXNlbnRzIGEgd2F5IHRvCisgKiB2ZXJpZnkgdGhlIGJpbmRpbmcgb2YgYSBQcmluY2lwYWwgYW5kIGl0cyBwdWJsaWMga2V5LiBFeGFtcGxlcyBhcmUgWC41MDksCisgKiBQR1AsIGFuZCBTRFNJLgorICogPHA+CisgKiBOb3RlOiBUaGlzIHBhY2thZ2UgaXMgcHJvdmlkZWQgb25seSBmb3IgY29tcGF0aWJpbGl0eSByZWFzb25zLgorICogSXQgY29udGFpbnMgYSBzaW1wbGlmaWVkIHZlcnNpb24gb2YgdGhlIGphdmEuc2VjdXJpdHkuY2VydCBwYWNrYWdlIHRoYXQgd2FzCisgKiBwcmV2aW91c2x5IHVzZWQgYnkgSlNTRSAoSmF2YSBTU0wgcGFja2FnZSkuIEFsbCBhcHBsaWNhdGlvbnMgdGhhdCBkbyBub3QgaGF2ZQorICogdG8gYmUgY29tcGF0aWJsZSB3aXRoIG9sZGVyIHZlcnNpb25zIG9mIEpTU0UgKHRoYXQgaXMgYmVmb3JlIEphdmEgU0RLIDEuNSkKKyAqIHNob3VsZCBvbmx5IHVzZSBqYXZhLnNlY3VyaXR5LmNlcnQuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBDZXJ0aWZpY2F0ZSB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZX0uCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlKCkge30KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBhcmd1bWVudCB0byB0aGlzIENlcnRpZmljYXRlLiBJZiBib3RoIGhhdmUgdGhlIHNhbWUgYnl0ZXMKKyAgICAgKiB0aGV5IGFyZSBhc3N1bWVkIHRvIGJlIGVxdWFsLgorICAgICAqCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDZXJ0aWZpY2F0ZX0gdG8gY29tcGFyZSB3aXRoIHRoaXMgb2JqZWN0CisgICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB7QGNvZGUgb2JqfSBpcyB0aGUgc2FtZSBhcyB0aGlzCisgICAgICogICAgICAgICB7QGNvZGUgQ2VydGlmaWNhdGV9LCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlCisgICAgICogQHNlZSAjaGFzaENvZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIENlcnRpZmljYXRlKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIENlcnRpZmljYXRlIG9iamVjdCA9IChDZXJ0aWZpY2F0ZSkgb2JqOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMoZ2V0RW5jb2RlZCgpLCBvYmplY3QuZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGludGVnZXIgaGFzaCBjb2RlIGZvciB0aGUgcmVjZWl2ZXIuIEFueSB0d28gb2JqZWN0cyB3aGljaAorICAgICAqIHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiB3aGVuIHBhc3NlZCB0byA8Y29kZT5lcXVhbHM8L2NvZGU+IG11c3QgYW5zd2VyCisgICAgICogdGhlIHNhbWUgdmFsdWUgZm9yIHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBoYXNoCisgICAgICogQHNlZSAjZXF1YWxzCisgICAgICovCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IHJlcyA9IDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBieXRlW10gYXJyYXkgPSBnZXRFbmNvZGVkKCk7CisgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8YXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICByZXMgKz0gYXJyYXlbaV07CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZW5jb2RlZCByZXByZXNlbnRhdGlvbiBmb3IgdGhpcyBjZXJ0aWZpY2F0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVuY29kZWQgcmVwcmVzZW50YXRpb24gZm9yIHRoaXMgY2VydGlmaWNhdGUuCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgZW5jb2RpbmcgZmFpbHMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJ5dGVbXSBnZXRFbmNvZGVkKCkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVmVyaWZpZXMgdGhhdCB0aGlzIGNlcnRpZmljYXRlIHdhcyBzaWduZWQgd2l0aCB0aGUgZ2l2ZW4gcHVibGljIGtleS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHB1YmxpYyBrZXkgZm9yIHdoaWNoIHZlcmlmaWNhdGlvbiBzaG91bGQgYmUgcGVyZm9ybWVkLgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBlbmNvZGluZyBlcnJvcnMgYXJlIGRldGVjdGVkCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiB1bnN1cHBvcnRlZCBhbGdvcml0aG0gaXMgZGV0ZWN0ZWQKKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBpbnZhbGlkIGtleSBpcyBkZXRlY3RlZAorICAgICAqIEB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBubyBkZWZhdWx0IHByb3ZpZGVyCisgICAgICogQHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBzaWduYXR1cmUgZXJyb3JzIGFyZSBkZXRlY3RlZAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5KQorICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgSW52YWxpZEtleUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgU2lnbmF0dXJlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVmVyaWZpZXMgdGhhdCB0aGlzIGNlcnRpZmljYXRlIHdhcyBzaWduZWQgd2l0aCB0aGUgZ2l2ZW4gcHVibGljIGtleS4gVXNlcworICAgICAqIHRoZSBzaWduYXR1cmUgYWxnb3JpdGhtIGdpdmVuIGJ5IHRoZSBwcm92aWRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkKKyAgICAgKiAgICAgICAgICAgIHB1YmxpYyBrZXkgZm9yIHdoaWNoIHZlcmlmaWNhdGlvbiBzaG91bGQgYmUgcGVyZm9ybWVkLgorICAgICAqIEBwYXJhbSBzaWdQcm92aWRlcgorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHNpZ25hdHVyZSBwcm92aWRlci4KKyAgICAgKiBAZXhjZXB0aW9uIENlcnRpZmljYXRlRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgZW5jb2RpbmcgZXJyb3JzIGFyZSBkZXRlY3RlZAorICAgICAqIEBleGNlcHRpb24gTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW4gdW5zdXBwb3J0ZWQgYWxnb3JpdGhtIGlzIGRldGVjdGVkCisgICAgICogQGV4Y2VwdGlvbiBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgYW4gaW52YWxpZCBrZXkgaXMgZGV0ZWN0ZWQKKyAgICAgKiBAZXhjZXB0aW9uIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgdGhlIHNwZWNpZmllZCBwcm92aWRlciBkb2VzIG5vdCBleGlzdHMuCisgICAgICogQGV4Y2VwdGlvbiBTaWduYXR1cmVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBpZiBzaWduYXR1cmUgZXJyb3JzIGFyZSBkZXRlY3RlZAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5LCBTdHJpbmcgc2lnUHJvdmlkZXIpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICAgICBJbnZhbGlkS2V5RXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICAgICBTaWduYXR1cmVFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUKKyAgICAgKiByZWNlaXZlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBwcmludGFibGUgcmVwcmVzZW50YXRpb24gZm9yIHRoZSByZWNlaXZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIHRvU3RyaW5nKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwdWJsaWMga2V5IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBjZXJ0aWZpY2F0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHB1YmxpYyBrZXkgY29ycmVzcG9uZGluZyB0byB0aGlzIGNlcnRpZmljYXRlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBQdWJsaWNLZXkgZ2V0UHVibGljS2V5KCk7Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ODBlNDNmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKworcGFja2FnZSBqYXZheC5zZWN1cml0eS5jZXJ0OworCisvKioKKyAqIFRoZSBleGNlcHRpb24gdGhhdCBpcyB0aHJvd24gd2hlbiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgYSB7QGNvZGUgQ2VydGlmaWNhdGV9CisgKiBpcyBiZWluZyBlbmNvZGVkLgorICogPHA+CisgKiBOb3RlOiBUaGlzIHBhY2thZ2UgaXMgcHJvdmlkZWQgb25seSBmb3IgY29tcGF0aWJpbGl0eSByZWFzb25zLiBJdCBjb250YWlucyBhCisgKiBzaW1wbGlmaWVkIHZlcnNpb24gb2YgdGhlIGphdmEuc2VjdXJpdHkuY2VydCBwYWNrYWdlIHRoYXQgd2FzIHByZXZpb3VzbHkgdXNlZAorICogYnkgSlNTRSAoSmF2YSBTU0wgcGFja2FnZSkuIEFsbCBhcHBsaWNhdGlvbnMgdGhhdCBkbyBub3QgaGF2ZSB0byBiZQorICogY29tcGF0aWJsZSB3aXRoIG9sZGVyIHZlcnNpb25zIG9mIEpTU0UgKHRoYXQgaXMgYmVmb3JlIEphdmEgU0RLIDEuNSkgc2hvdWxkCisgKiBvbmx5IHVzZSBqYXZhLnNlY3VyaXR5LmNlcnQuCisgKi8KK3B1YmxpYyBjbGFzcyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIGV4dGVuZHMgQ2VydGlmaWNhdGVFeGNlcHRpb24geworCisgICAgLyoqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04MTg3NjQyNzIzMDQ4NDAzNDcwTDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24oU3RyaW5nIG1zZykgeworICAgICAgICBzdXBlcihtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb259LgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZkMmE2MTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKworcGFja2FnZSBqYXZheC5zZWN1cml0eS5jZXJ0OworCisvKioKKyAqIFRoZSBiYXNlIGNsYXNzIGZvciBhbGwge0Bjb2RlIENlcnRpZmljYXRlfSByZWxhdGVkIGV4Y2VwdGlvbnMuCisgKiA8cD4KKyAqIE5vdGU6IFRoaXMgcGFja2FnZSBpcyBwcm92aWRlZCBvbmx5IGZvciBjb21wYXRpYmlsaXR5IHJlYXNvbnMuIEl0IGNvbnRhaW5zIGEKKyAqIHNpbXBsaWZpZWQgdmVyc2lvbiBvZiB0aGUgamF2YS5zZWN1cml0eS5jZXJ0IHBhY2thZ2UgdGhhdCB3YXMgcHJldmlvdXNseSB1c2VkCisgKiBieSBKU1NFIChKYXZhIFNTTCBwYWNrYWdlKS4gQWxsIGFwcGxpY2F0aW9ucyB0aGF0IGRvIG5vdCBoYXZlIHRvIGJlCisgKiBjb21wYXRpYmxlIHdpdGggb2xkZXIgdmVyc2lvbnMgb2YgSlNTRSAodGhhdCBpcyBiZWZvcmUgSmF2YSBTREsgMS41KSBzaG91bGQKKyAqIG9ubHkgdXNlIGphdmEuc2VjdXJpdHkuY2VydC4KKyAqLworcHVibGljIGNsYXNzIENlcnRpZmljYXRlRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKworICAgIC8qKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTc1NzIxMzM3NDAzMDc4NTI5MEw7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbn0gd2l0aCB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlRXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKKyAgICAgICAgc3VwZXIobXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlRXhjZXB0aW9uKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTRlNjU1OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguc2VjdXJpdHkuY2VydDsKKworLyoqCisgKiBUaGUgZXhjZXB0aW9uIHRoYXQgaXMgdGhyb3duIHdoZW4gYSB7QGNvZGUgQ2VydGlmaWNhdGV9IGhhcyBleHBpcmVkLgorICogPHA+CisgKiBOb3RlOiBUaGlzIHBhY2thZ2UgaXMgcHJvdmlkZWQgb25seSBmb3IgY29tcGF0aWJpbGl0eSByZWFzb25zLiBJdCBjb250YWlucyBhCisgKiBzaW1wbGlmaWVkIHZlcnNpb24gb2YgdGhlIGphdmEuc2VjdXJpdHkuY2VydCBwYWNrYWdlIHRoYXQgd2FzIHByZXZpb3VzbHkgdXNlZAorICogYnkgSlNTRSAoSmF2YSBTU0wgcGFja2FnZSkuIEFsbCBhcHBsaWNhdGlvbnMgdGhhdCBkbyBub3QgaGF2ZSB0byBiZQorICogY29tcGF0aWJsZSB3aXRoIG9sZGVyIHZlcnNpb25zIG9mIEpTU0UgKHRoYXQgaXMgYmVmb3JlIEphdmEgU0RLIDEuNSkgc2hvdWxkCisgKiBvbmx5IHVzZSBqYXZhLnNlY3VyaXR5LmNlcnQuCisgKi8KK3B1YmxpYyBjbGFzcyBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24gZXh0ZW5kcyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisKKyAgICAvKioKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTA5MTYwMTIxMjE3NzI2MTg4M0w7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZmUwYTMzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguc2VjdXJpdHkuY2VydDsKKworLyoqCisgKiBUaGUgZXhjZXB0aW9uIHRoYXQgaXMgdGhyb3duIHdoZW4gYSB7QGNvZGUgQ2VydGlmaWNhdGV9IGlzIG5vdCB5ZXQgdmFsaWQuCisgKiA8cD4KKyAqIE5vdGU6IFRoaXMgcGFja2FnZSBpcyBwcm92aWRlZCBvbmx5IGZvciBjb21wYXRpYmlsaXR5IHJlYXNvbnMuIEl0IGNvbnRhaW5zIGEKKyAqIHNpbXBsaWZpZWQgdmVyc2lvbiBvZiB0aGUgamF2YS5zZWN1cml0eS5jZXJ0IHBhY2thZ2UgdGhhdCB3YXMgcHJldmlvdXNseSB1c2VkCisgKiBieSBKU1NFIChKYXZhIFNTTCBwYWNrYWdlKS4gQWxsIGFwcGxpY2F0aW9ucyB0aGF0IGRvIG5vdCBoYXZlIHRvIGJlCisgKiBjb21wYXRpYmxlIHdpdGggb2xkZXIgdmVyc2lvbnMgb2YgSlNTRSAodGhhdCBpcyBiZWZvcmUgSmF2YSBTREsgMS41KSBzaG91bGQKKyAqIG9ubHkgdXNlIGphdmEuc2VjdXJpdHkuY2VydC4KKyAqLworcHVibGljIGNsYXNzIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24gZXh0ZW5kcyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisKKyAgICAvKioKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTg5NzYxNzI0NzQyNjY4MjI4MThMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbn0gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbn0uCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ODk4NmMwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5zZWN1cml0eS5jZXJ0OworCisvKioKKyAqIFRoZSBleGNlcHRpb24gdGhhdCBpcyB0aHJvd24gd2hlbiBhIHtAY29kZSBDZXJ0aWZpY2F0ZX0gY2FuIG5vdCBiZSBwYXJzZWQuCisgKiA8cD4KKyAqIE5vdGU6IFRoaXMgcGFja2FnZSBpcyBwcm92aWRlZCBvbmx5IGZvciBjb21wYXRpYmlsaXR5IHJlYXNvbnMuIEl0IGNvbnRhaW5zIGEKKyAqIHNpbXBsaWZpZWQgdmVyc2lvbiBvZiB0aGUgamF2YS5zZWN1cml0eS5jZXJ0IHBhY2thZ2UgdGhhdCB3YXMgcHJldmlvdXNseSB1c2VkCisgKiBieSBKU1NFIChKYXZhIFNTTCBwYWNrYWdlKS4gQWxsIGFwcGxpY2F0aW9ucyB0aGF0IGRvIG5vdCBoYXZlIHRvIGJlCisgKiBjb21wYXRpYmxlIHdpdGggb2xkZXIgdmVyc2lvbnMgb2YgSlNTRSAodGhhdCBpcyBiZWZvcmUgSmF2YSBTREsgMS41KSBzaG91bGQKKyAqIG9ubHkgdXNlIGphdmEuc2VjdXJpdHkuY2VydC4KKyAqLworcHVibGljIGNsYXNzIENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbiBleHRlbmRzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKworICAgIC8qKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODQ0OTM1MjQyMjk1MTEzNjIyOUw7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCisgICAgICogICAgICAgICAgICB0aGUgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9ufS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9jZXJ0L1g1MDlDZXJ0aWZpY2F0ZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2NlcnQvWDUwOUNlcnRpZmljYXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTg1YTU1NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zZWN1cml0eS9jZXJ0L1g1MDlDZXJ0aWZpY2F0ZS5qYXZhCkBAIC0wLDAgKzEsMzc4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5QcmluY2lwYWw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5OworaW1wb3J0IGphdmEudXRpbC5EYXRlOworCisvKioKKyAqIEFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIFguNTA5IGNlcnRpZmljYXRlcy4KKyAqIDxwPgorICogVGhpcyByZXByZXNlbnRzIGEgc3RhbmRhcmQgd2F5IGZvciBhY2Nlc3NpbmcgdGhlIGF0dHJpYnV0ZXMgb2YgWC41MDkgdjEKKyAqIGNlcnRpZmljYXRlcy4KKyAqIDxwPgorICogTm90ZTogVGhpcyBwYWNrYWdlIGlzIHByb3ZpZGVkIG9ubHkgZm9yIGNvbXBhdGliaWxpdHkgcmVhc29ucy4KKyAqIEl0IGNvbnRhaW5zIGEgc2ltcGxpZmllZCB2ZXJzaW9uIG9mIHRoZSBqYXZhLnNlY3VyaXR5LmNlcnQgcGFja2FnZSB0aGF0IHdhcworICogcHJldmlvdXNseSB1c2VkIGJ5IEpTU0UgKEphdmEgU1NMIHBhY2thZ2UpLiBBbGwgYXBwbGljYXRpb25zIHRoYXQgZG8gbm90IGhhdmUKKyAqIHRvIGJlIGNvbXBhdGlibGUgd2l0aCBvbGRlciB2ZXJzaW9ucyBvZiBKU1NFICh0aGF0IGlzIGJlZm9yZSBKYXZhIFNESyAxLjUpCisgKiBzaG91bGQgb25seSB1c2UgamF2YS5zZWN1cml0eS5jZXJ0LgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgWDUwOUNlcnRpZmljYXRlIGV4dGVuZHMgQ2VydGlmaWNhdGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgQ29uc3RydWN0b3IgY29uc3RydWN0b3I7CisgICAgc3RhdGljIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBjbGFzc25hbWUgPSBTZWN1cml0eS5nZXRQcm9wZXJ0eSgiY2VydC5wcm92aWRlci54NTA5djEiKTsKKyAgICAgICAgICAgIENsYXNzIGNsID0gQ2xhc3MuZm9yTmFtZShjbGFzc25hbWUpOworICAgICAgICAgICAgY29uc3RydWN0b3IgPSBjbC5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbXSB7SW5wdXRTdHJlYW0uY2xhc3N9KTsKKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFg1MDlDZXJ0aWZpY2F0ZX0uCisgICAgICovCisgICAgcHVibGljIFg1MDlDZXJ0aWZpY2F0ZSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBYNTA5Q2VydGlmaWNhdGV9IGFuZCBpbml0aWFsaXplcyBpdCBmcm9tIHRoZQorICAgICAqIHNwZWNpZmllZCBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5TdHJlYW0KKyAgICAgKiAgICAgICAgICAgIGlucHV0IHN0cmVhbSBjb250YWluaW5nIGRhdGEgdG8gaW5pdGlhbGl6ZSB0aGUgY2VydGlmaWNhdGUuCisgICAgICogQHJldHVybiB0aGUgY2VydGlmaWNhdGUgaW5pdGlhbGl6ZWQgZnJvbSB0aGUgc3BlY2lmaWVkIGlucHV0IHN0cmVhbQorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2VydGlmaWNhdGUgY2Fubm90IGJlIGNyZWF0ZWQgb3IgaW5pdGlhbGl6ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBYNTA5Q2VydGlmaWNhdGUgZ2V0SW5zdGFuY2UoSW5wdXRTdHJlYW0gaW5TdHJlYW0pCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBpZiAoaW5TdHJlYW0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKCJpblN0cmVhbSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvbnN0cnVjdG9yICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChYNTA5Q2VydGlmaWNhdGUpCisgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yLm5ld0luc3RhbmNlKG5ldyBPYmplY3RbXSB7aW5TdHJlYW19KTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGUgY2VydDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgICAgIGNlcnQgPSAoamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShpblN0cmVhbSk7CisgICAgICAgIH0gY2F0Y2ggKGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ldyBYNTA5Q2VydGlmaWNhdGUoKSB7CisKKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2VydC5nZXRFbmNvZGVkKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgdm9pZCB2ZXJpZnkoUHVibGljS2V5IGtleSkgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIEludmFsaWRLZXlFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLCBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGNlcnQudmVyaWZ5KGtleSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5LCBTdHJpbmcgc2lnUHJvdmlkZXIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIEludmFsaWRLZXlFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLCBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGNlcnQudmVyaWZ5KGtleSwgc2lnUHJvdmlkZXIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjZXJ0LnRvU3RyaW5nKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBQdWJsaWNLZXkgZ2V0UHVibGljS2V5KCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjZXJ0LmdldFB1YmxpY0tleSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBjaGVja1ZhbGlkaXR5KCkgdGhyb3dzIENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgY2VydC5jaGVja1ZhbGlkaXR5KCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHZvaWQgY2hlY2tWYWxpZGl0eShEYXRlIGRhdGUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgY2VydC5jaGVja1ZhbGlkaXR5KGRhdGUpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0VmVyc2lvbigpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0U2VyaWFsTnVtYmVyKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjZXJ0LmdldFNlcmlhbE51bWJlcigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgUHJpbmNpcGFsIGdldElzc3VlckROKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjZXJ0LmdldElzc3VlckROKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0U3ViamVjdEROKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjZXJ0LmdldFN1YmplY3RETigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgRGF0ZSBnZXROb3RCZWZvcmUoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNlcnQuZ2V0Tm90QmVmb3JlKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBEYXRlIGdldE5vdEFmdGVyKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjZXJ0LmdldE5vdEFmdGVyKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2lnQWxnTmFtZSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY2VydC5nZXRTaWdBbGdOYW1lKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2lnQWxnT0lEKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjZXJ0LmdldFNpZ0FsZ09JRCgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldFNpZ0FsZ1BhcmFtcygpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY2VydC5nZXRTaWdBbGdQYXJhbXMoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAY29kZSBYNTA5Q2VydGlmaWNhdGV9IGFuZCBpbml0aWFsaXplcyBpdCBmcm9tIHRoZQorICAgICAqIHNwZWNpZmllZCBieXRlIGFycmF5LgorICAgICAqCisgICAgICogQHBhcmFtIGNlcnREYXRhCisgICAgICogICAgICAgICAgICBieXRlIGFycmF5IGNvbnRhaW5pbmcgZGF0YSB0byBpbml0aWFsaXplIHRoZSBjZXJ0aWZpY2F0ZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBjZXJ0aWZpY2F0ZSBpbml0aWFsaXplZCBmcm9tIHRoZSBzcGVjaWZpZWQgYnl0ZSBhcnJheQorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2VydGlmaWNhdGUgY2Fubm90IGJlIGNyZWF0ZWQgb3IgaW5pdGlhbGl6ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBYNTA5Q2VydGlmaWNhdGUgZ2V0SW5zdGFuY2UoYnl0ZVtdIGNlcnREYXRhKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNlcnREYXRhID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigiY2VydERhdGEgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJhaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oY2VydERhdGEpOworICAgICAgICByZXR1cm4gZ2V0SW5zdGFuY2UoYmFpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGNlcnRpZmljYXRlIGlzIGN1cnJlbnRseSB2YWxpZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgdmFsaWRpdHkgZGVmaW5lZCBpbiBBU04uMToKKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogdmFsaWRpdHkgICAgICAgICAgICAgVmFsaWRpdHkKKyAgICAgKgorICAgICAqIFZhbGlkaXR5IDo6PSBTRVFVRU5DRSB7CisgICAgICogICAgICBub3RCZWZvcmUgICAgICAgQ2VydGlmaWNhdGVWYWxpZGl0eURhdGUsCisgICAgICogICAgICBub3RBZnRlciAgICAgICAgQ2VydGlmaWNhdGVWYWxpZGl0eURhdGUgfQorICAgICAqCisgICAgICogQ2VydGlmaWNhdGVWYWxpZGl0eURhdGUgOjo9IENIT0lDRSB7CisgICAgICogICAgICB1dGNUaW1lICAgICAgICAgVVRDVGltZSwKKyAgICAgKiAgICAgIGdlbmVyYWxUaW1lICAgICBHZW5lcmFsaXplZFRpbWUgfQorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgY2VydGlmaWNhdGUgaGFzIGV4cGlyZWQuCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNlcnRpZmljYXRlIGlzIG5vdCB5ZXQgdmFsaWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgY2hlY2tWYWxpZGl0eSgpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgY2VydGlmaWNhdGUgaXMgdmFsaWQgYXQgdGhlIHNwZWNpZmllZCBkYXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRlIHRvIGNoZWNrIHRoZSB2YWxpZGl0eSBhZ2FpbnN0LgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIGNlcnRpZmljYXRlIGhhcyBleHBpcmVkLgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBjZXJ0aWZpY2F0ZSBpcyBub3QgeWV0IHZhbGlkLgorICAgICAqIEBzZWUgI2NoZWNrVmFsaWRpdHkoKQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGNoZWNrVmFsaWRpdHkoRGF0ZSBkYXRlKQorICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbiwgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNlcnRpZmljYXRlcyB7QGNvZGUgdmVyc2lvbn0gKHZlcnNpb24gbnVtYmVyKS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgdmVyc2lvbiBkZWZpbmVkIGlzIEFTTi4xOgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiBWZXJzaW9uIDo6PSAgSU5URUdFUiAgeyAgdjEoMCksIHYyKDEpLCB2MygyKSAgfQorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdmVyc2lvbiBudW1iZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRWZXJzaW9uKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgc2VyaWFsTnVtYmVyfSBvZiB0aGUgY2VydGlmaWNhdGUuCisgICAgICogPHA+CisgICAgICogVGhlIEFTTi4xIGRlZmluaXRpb24gb2Yge0Bjb2RlIHNlcmlhbE51bWJlcn06CisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqIENlcnRpZmljYXRlU2VyaWFsTnVtYmVyICA6Oj0gIElOVEVHRVIKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNlcmlhbCBudW1iZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJpZ0ludGVnZXIgZ2V0U2VyaWFsTnVtYmVyKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgaXNzdWVyfSAoaXNzdWVyIGRpc3Rpbmd1aXNoZWQgbmFtZSkgYXMgYW4KKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYyB7QGNvZGUgUHJpbmNpcGFsfSBvYmplY3QuCisgICAgICogPHA+CisgICAgICogVGhlIEFTTi4xIGRlZmluaXRpb24gb2Yge0Bjb2RlIGlzc3Vlcn06CisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqICBpc3N1ZXIgICAgICBOYW1lCisgICAgICoKKyAgICAgKiAgTmFtZSA6Oj0gQ0hPSUNFIHsKKyAgICAgKiAgICAgIFJETlNlcXVlbmNlIH0KKyAgICAgKgorICAgICAqICAgIFJETlNlcXVlbmNlIDo6PSBTRVFVRU5DRSBPRiBSZWxhdGl2ZURpc3Rpbmd1aXNoZWROYW1lCisgICAgICoKKyAgICAgKiAgICBSZWxhdGl2ZURpc3Rpbmd1aXNoZWROYW1lIDo6PSBTRVQgT0YgQXR0cmlidXRlVHlwZUFuZFZhbHVlCisgICAgICoKKyAgICAgKiAgICBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgOjo9IFNFUVVFTkNFIHsKKyAgICAgKiAgICAgIHR5cGUgICAgIEF0dHJpYnV0ZVR5cGUsCisgICAgICogICAgICB2YWx1ZSAgICBBdHRyaWJ1dGVWYWx1ZSB9CisgICAgICoKKyAgICAgKiAgICBBdHRyaWJ1dGVUeXBlIDo6PSBPQkpFQ1QgSURFTlRJRklFUgorICAgICAqCisgICAgICogICAgQXR0cmlidXRlVmFsdWUgOjo9IEFOWSBERUZJTkVEIEJZIEF0dHJpYnV0ZVR5cGUKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBpc3N1ZXJ9IGFzIGFuIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIHtAY29kZQorICAgICAqICAgICAgICAgUHJpbmNpcGFsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgUHJpbmNpcGFsIGdldElzc3VlckROKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgc3ViamVjdH0gKHN1YmplY3QgZGlzdGluZ3Vpc2hlZCBuYW1lKSBhcyBhbgorICAgICAqIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIHtAY29kZSBQcmluY2lwYWx9IG9iamVjdC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgQVNOLjEgZGVmaW5pdGlvbiBvZiB7QGNvZGUgc3ViamVjdH06CisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqIHN1YmplY3QgICAgICBOYW1lCisgICAgICoKKyAgICAgKiAgTmFtZSA6Oj0gQ0hPSUNFIHsKKyAgICAgKiAgICAgIFJETlNlcXVlbmNlIH0KKyAgICAgKgorICAgICAqICAgIFJETlNlcXVlbmNlIDo6PSBTRVFVRU5DRSBPRiBSZWxhdGl2ZURpc3Rpbmd1aXNoZWROYW1lCisgICAgICoKKyAgICAgKiAgICBSZWxhdGl2ZURpc3Rpbmd1aXNoZWROYW1lIDo6PSBTRVQgT0YgQXR0cmlidXRlVHlwZUFuZFZhbHVlCisgICAgICoKKyAgICAgKiAgICBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgOjo9IFNFUVVFTkNFIHsKKyAgICAgKiAgICAgIHR5cGUgICAgIEF0dHJpYnV0ZVR5cGUsCisgICAgICogICAgICB2YWx1ZSAgICBBdHRyaWJ1dGVWYWx1ZSB9CisgICAgICoKKyAgICAgKiAgICBBdHRyaWJ1dGVUeXBlIDo6PSBPQkpFQ1QgSURFTlRJRklFUgorICAgICAqCisgICAgICogICAgQXR0cmlidXRlVmFsdWUgOjo9IEFOWSBERUZJTkVEIEJZIEF0dHJpYnV0ZVR5cGUKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHtAY29kZSBzdWJqZWN0fSAoc3ViamVjdCBkaXN0aW5ndWlzaGVkIG5hbWUpLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBQcmluY2lwYWwgZ2V0U3ViamVjdEROKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgbm90QmVmb3JlfSBkYXRlIGZyb20gdGhlIHZhbGlkaXR5IHBlcmlvZCBvZiB0aGUKKyAgICAgKiBjZXJ0aWZpY2F0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHN0YXJ0IG9mIHRoZSB2YWxpZGl0eSBwZXJpb2QuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IERhdGUgZ2V0Tm90QmVmb3JlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgbm90QWZ0ZXJ9IGRhdGUgb2YgdGhlIHZhbGlkaXR5IHBlcmlvZCBvZiB0aGUKKyAgICAgKiBjZXJ0aWZpY2F0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGVuZCBvZiB0aGUgdmFsaWRpdHkgcGVyaW9kLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBEYXRlIGdldE5vdEFmdGVyKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0gZm9yIHRoZSBjZXJ0aWZpY2F0ZSBzaWduYXR1cmUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzaWduYXR1cmUgYWxnb3JpdGhtIG5hbWUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRTaWdBbGdOYW1lKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBPSUQgb2YgdGhlIHNpZ25hdHVyZSBhbGdvcml0aG0gZnJvbSB0aGUgY2VydGlmaWNhdGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBPSUQgb2YgdGhlIHNpZ25hdHVyZSBhbGdvcml0aG0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRTaWdBbGdPSUQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHBhcmFtZXRlcnMgb2YgdGhlIHNpZ25hdHVyZSBhbGdvcml0aG0gaW4gREVSLWVuY29kZWQgZm9ybWF0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcGFyYW1ldGVycyBvZiB0aGUgc2lnbmF0dXJlIGFsZ29yaXRobSwgb3IgbnVsbCBpZiBub25lIGFyZQorICAgICAqICAgICAgICAgdXNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYnl0ZVtdIGdldFNpZ0FsZ1BhcmFtcygpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2NlcnQvcGFja2FnZS5odG1sIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NlY3VyaXR5L2NlcnQvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc5MmI0NDYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc2VjdXJpdHkvY2VydC9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwxNCBAQAorPGh0bWw+Cis8aGVhZD4KKzxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXVzLWFzY2lpIj4KKzwvaGVhZD4KKzxodG1sPgorPGJvZHk+Cis8cD4KK1RoaXMgcGFja2FnZSBpcyBwcm92aWRlZCBvbmx5IGZvciBjb21wYXRpYmlsaXR5IHJlYXNvbnMuIEl0IGNvbnRhaW5zICBhIHNpbXBsaWZpZWQKK3ZlcnNpb24gb2YgdGhlIGphdmEuc2VjdXJpdHkuY2VydCBwYWNrYWdlIHRoYXQgd2FzIHByZXZpb3VzbHkgdXNlZCBieSBKU1NFIChKYXZhIFNTTCAgcGFja2FnZSkuCitBbGwgYXBwbGljYXRpb25zIHRoYXQgZG8gbm90IGhhdmUgdG8gYmUgY29tcGF0aWJsZSB3aXRoIG9sZGVyIHZlcnNpb25zIG9mIEpTU0UgKHRoYXQgaXMKK2JlZm9yZSBKYXZhIFNESyAxLjUpIHNob3VsZCBvbmx5IHVzZSBqYXZhLnNlY3VyaXR5LmNlcnQuCis8L3A+Cis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc3FsL0NvbW1vbkRhdGFTb3VyY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zcWwvQ29tbW9uRGF0YVNvdXJjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZlNWEyNTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc3FsL0NvbW1vbkRhdGFTb3VyY2UuamF2YQpAQCAtMCwwICsxLDcxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5zcWw7CisKK2ltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOworaW1wb3J0IGphdmEuc3FsLlNRTEV4Y2VwdGlvbjsKKworLyoqCisgKiBJbnRlcmZhY2UgdGhhdCBkZWZpbmVzIHRoZSBtZXRob2RzIHdoaWNoIGFyZSBjb21tb24gYmV0d2VlbiBEYXRhU291cmNlLAorICogWEFEYXRhU291cmNlIGFuZCBDb25uZWN0aW9uUG9vbERhdGFTb3VyY2UuCisgKgorICogQHNpbmNlIDEuNgorICovCitwdWJsaWMgaW50ZXJmYWNlIENvbW1vbkRhdGFTb3VyY2UgeworCisgICAgLyoqCisgICAgICogV2hpbGUgYXR0ZW1wdGluZyB0byBjb25uZWN0IHRvIGEgZGF0YWJhc2UsIHRoaXMgbWV0aG9kIGdldCB0aGUgbWF4aW11bQorICAgICAqIHRpbWUgaW4gc2Vjb25kcyB0aGF0IHRoaXMgZGF0YSBzb3VyY2UgY2FuIHdhaXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFuIGludGVnZXIgdmFsdWUgdG8gaW5kaWNhdGUgdGhlIG1heGltdW0gdGltZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIEFuIGV4Y2VwdGlvbiB0aHJldyB3aGVuIGEgZGF0YSBiYXNlIGFjY2VzcyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRMb2dpblRpbWVvdXQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGEgbG9nIHdyaXRlciB3aGljaCBpcyBhIGNoYXJhY3RlciBvdXRwdXQgc3RyZWFtIHRvIHdoaWNoIGFsbAorICAgICAqIGxvZ2dpbmcgYW5kIHRyYWNpbmcgbWVzc2FnZXMgZm9yIHRoaXMgZGF0YSBzb3VyY2Ugd2lsbCBiZSBwcmludGVkLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgUHJpbnRXcml0ZXIgb2JqZWN0IGZvciB0aGlzIERhdGFTb3VyY2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBBbiBleGNlcHRpb24gdGhyZXcgd2hlbiBhIGRhdGEgYmFzZSBhY2Nlc3MgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIFByaW50V3JpdGVyIGdldExvZ1dyaXRlcigpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXaGlsZSBhdHRlbXB0aW5nIHRvIGNvbm5lY3QgdG8gYSBkYXRhYmFzZSwgdGhpcyBtZXRob2Qgc2V0IHRoZSBtYXhpbXVtCisgICAgICogdGltZSBpbiBzZWNvbmRzIHRoYXQgdGhpcyBkYXRhIHNvdXJjZSBjYW4gd2FpdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzZWNvbmRzCisgICAgICogICAgICAgICAgICBBbiBpbnRlZ2VyIHZhbHVlIHRvIGluZGljYXRlIHRoZSBtYXhpbXVtIHRpbWUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBBbiBleGNlcHRpb24gdGhyZXcgd2hlbiBhIGRhdGEgYmFzZSBhY2Nlc3MgZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHZvaWQgc2V0TG9naW5UaW1lb3V0KGludCBzZWNvbmRzKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0IGEgbG9nIHdyaXRlciB3aGljaCBpcyBhIGNoYXJhY3RlciBvdXRwdXQgc3RyZWFtIHRvIHdoaWNoIGFsbCBsb2dnaW5nCisgICAgICogYW5kIHRyYWNpbmcgbWVzc2FnZXMgZm9yIHRoaXMgZGF0YSBzb3VyY2Ugd2lsbCBiZSBwcmludGVkLgorICAgICAqCisgICAgICogQHBhcmFtIG91dAorICAgICAqICAgICAgICAgICAgVGhlIFByaW50V3JpdGVyIG9iamVjdCBmb3IgdGhpcyBEYXRhU291cmNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgdm9pZCBzZXRMb2dXcml0ZXIoUHJpbnRXcml0ZXIgb3V0KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zcWwvQ29ubmVjdGlvbkV2ZW50LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc3FsL0Nvbm5lY3Rpb25FdmVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRkNzM4YmQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc3FsL0Nvbm5lY3Rpb25FdmVudC5qYXZhCkBAIC0wLDAgKzEsNzQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LnNxbDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEuc3FsLlNRTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuRXZlbnRPYmplY3Q7CisKKy8qKgorICogU2VudCB3aGVuIHNwZWNpZmljIGV2ZW50cyBoYXBwZW4gb24gYSB7QGxpbmsgUG9vbGVkQ29ubmVjdGlvbn0gb2JqZWN0LiBUaGVzZQorICogZXZlbnRzIGFyZSBhIGZhY2lsaXR5IHRvIHJlcG9ydCB3aGVuIGFuIGFwcGxpY2F0aW9uIGNsb3NlcyB0aGUgcG9vbGVkCisgKiBjb25uZWN0aW9uIG9yIHdoZW4gYW4gZXJyb3Igb2NjdXJzIGluIHRoZSBwb29sZWQgY29ubmVjdGlvbi4KKyAqLworcHVibGljIGNsYXNzIENvbm5lY3Rpb25FdmVudCBleHRlbmRzIEV2ZW50T2JqZWN0IGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00ODQzMjE3NjQ1MjkwMDMwMDAyTDsKKworICAgIHByaXZhdGUgU1FMRXhjZXB0aW9uIGV4OworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGNvbm5lY3Rpb24gZXZlbnQgaW5pdGlhbGl6ZWQgd2l0aCB0aGUgc3VwcGxpZWQge0Bjb2RlCisgICAgICogUG9vbGVkQ29ubmVjdGlvbn0gcmVwb3J0aW5nIHRoYXQgdGhlIGFwcGxpY2F0aW9uIGhhcyBjbG9zZWQgdGhlCisgICAgICogY29ubmVjdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVDb25uZWN0aW9uCisgICAgICogICAgICAgICAgICB0aGUgY29ubmVjdGlvbiBmb3Igd2hpY2ggdGhpcyBldmVudCBpcyBjcmVhdGVkLgorICAgICAqLworICAgIHB1YmxpYyBDb25uZWN0aW9uRXZlbnQoUG9vbGVkQ29ubmVjdGlvbiB0aGVDb25uZWN0aW9uKSB7CisgICAgICAgIHN1cGVyKHRoZUNvbm5lY3Rpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgQ29ubmVjdGlvbkV2ZW50fSBpbml0aWFsaXplZCB3aXRoIHRoZSBzdXBwbGllZCB7QGNvZGUKKyAgICAgKiBQb29sZWRDb25uZWN0aW9ufSBhbmQgd2l0aCB0aGUgc3VwcGxpZWQge0Bjb2RlIFNRTEV4Y2VwdGlvbn0gaW5kaWNhdGluZworICAgICAqIHRoYXQgYW4gZXJyb3IgaGFzIG9jY3VycmVkIHdpdGhpbiB0aGUge0Bjb2RlIFBvb2xlZENvbm5lY3Rpb259LgorICAgICAqCisgICAgICogQHBhcmFtIHRoZUNvbm5lY3Rpb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBjb25uZWN0aW9uIGZvciB3aGljaCB0aGlzIGV2ZW50IGlzIGNyZWF0ZWQuCisgICAgICogQHBhcmFtIHRoZUV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHN0YXRlIG9mIGVycm9yIHRoYXQgaGFzIG9jY3VycmVkIG9uIHRoZQorICAgICAqICAgICAgICAgICAgYXBwbGljYXRpb24gc2lkZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29ubmVjdGlvbkV2ZW50KFBvb2xlZENvbm5lY3Rpb24gdGhlQ29ubmVjdGlvbiwKKyAgICAgICAgICAgIFNRTEV4Y2VwdGlvbiB0aGVFeGNlcHRpb24pIHsKKyAgICAgICAgc3VwZXIodGhlQ29ubmVjdGlvbik7CisgICAgICAgIGV4ID0gdGhlRXhjZXB0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHtAY29kZSBTUUxFeGNlcHRpb259IHdoaWNoIGhvbGRzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBlcnJvcgorICAgICAqIHdoaWNoIG9jY3VycmVkIGluIHRoZSB7QGNvZGUgUG9vbGVkQ29ubmVjdGlvbn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFNRTEV4Y2VwdGlvbn0gY29udGFpbmluZyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZXJyb3IuCisgICAgICogICAgICAgICBNYXkgYmUge0Bjb2RlIG51bGx9IGlmIG5vIGVycm9yIGhhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU1FMRXhjZXB0aW9uIGdldFNRTEV4Y2VwdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIGV4OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zcWwvQ29ubmVjdGlvbkV2ZW50TGlzdGVuZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zcWwvQ29ubmVjdGlvbkV2ZW50TGlzdGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNmVlODAwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NxbC9Db25uZWN0aW9uRXZlbnRMaXN0ZW5lci5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LnNxbDsKKworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyOworCisvKioKKyAqIEFuIGludGVyZmFjZSB1c2VkIHRvIHJlY2VpdmUgZXZlbnRzIGdlbmVyYXRlZCBieSBhIHtAbGluayBQb29sZWRDb25uZWN0aW9ufS4KKyAqIDxwPgorICogVGhpcyBpbnRlcmZhY2Ugd291bGQgdHlwaWNhbGx5IGJlIGltcGxlbWVudGVkIGJ5IGEgY29tcG9uZW50IHdoaWNoIG1hbmFnZXMgYQorICogY29ubmVjdGlvbiBwb29sIChhIGNvbm5lY3Rpb24gcG9vbCBtYW5hZ2VyKS4gQSBjb25uZWN0aW9uIHRyaWdnZXJzIGFuIGV2ZW50CisgKiB0byBhIHtAY29kZSBDb25uZWN0aW9uRXZlbnRMaXN0ZW5lcn0gZWl0aGVyIHdoZW4gdGhlIGFwcGxpY2F0aW9uIGNsb3NlcyBhCisgKiBjb25uZWN0aW9uIGl0IGhhcyBiZWVuIHVzaW5nIG9yIHdoZW4gYSBzaWduaWZpY2FudCBlcnJvciBvY2N1cnMgd2hpbGUgdGhlCisgKiBjb25uZWN0aW9uIGlzIGJlaW5nIHVzZWQuCisgKiA8cD4KKyAqIFRoZSBjb25uZWN0aW9uIHBvb2wgbWFuYWdlciBjYW4gcmV0dXJuIGNsb3NlZCBjb25uZWN0aW9ucyB0byB0aGUgcG9vbCBmb3IKKyAqIGxhdGVyIHJldXNlLiBDb25uZWN0aW9ucyBleHBlcmllbmNpbmcgYW4gZXJyb3Igc2hvdWxkIGJlIGRpc2NhcmRlZC4KKyAqLworcHVibGljIGludGVyZmFjZSBDb25uZWN0aW9uRXZlbnRMaXN0ZW5lciBleHRlbmRzIEV2ZW50TGlzdGVuZXIgeworCisgICAgLyoqCisgICAgICogTm90aWZpZXMgdGhlIHtAY29kZSBDb25uZWN0aW9uRXZlbnRMaXN0ZW5lcn0gdGhhdCBhbiBhcHBsaWNhdGlvbiBoYXMKKyAgICAgKiBjYWxsZWQgdGhlIHtAY29kZSBjbG9zZX0gbWV0aG9kIG9uIGEgcG9vbGVkIGNvbm5lY3Rpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlRXZlbnQKKyAgICAgKiAgICAgICAgICAgIGEge0Bjb2RlIENvbm5lY3Rpb25FdmVudH0gY29udGFpbmluZyBkZXRhaWxzIGFib3V0IHRoZSBzb3VyY2UKKyAgICAgKiAgICAgICAgICAgIG9mIHRoZSBldmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjb25uZWN0aW9uQ2xvc2VkKENvbm5lY3Rpb25FdmVudCB0aGVFdmVudCk7CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGUge0Bjb2RlIENvbm5lY3Rpb25FdmVudExpc3RlbmVyfSB0aGF0IGFuIGVycm9yIGhhcyBvY2N1cnJlZAorICAgICAqIG9uIGEge0Bjb2RlIFBvb2xlZENvbm5lY3Rpb259LiBUaGlzIG5vdGlmaWNhdGlvbiBpcyB0cmlnZ2VyZWQgPGk+YmVmb3JlPC9pPiB0aGUKKyAgICAgKiB7QGNvZGUgU1FMRXhjZXB0aW9ufSwgd2hpY2ggaXMgYXZhaWxhYmxlIHRocm91Z2ggdGhlIGV2ZW50IGFyZ3VtZW50LCBpcworICAgICAqIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVFdmVudAorICAgICAqICAgICAgICAgICAgYSB7QGNvZGUgQ29ubmVjdGlvbkV2ZW50fSBjb250YWluaW5nIGRldGFpbHMgYWJvdXQgdGhlIHNvdXJjZQorICAgICAqICAgICAgICAgICAgb2YgdGhlIGV2ZW50IGFuZCB0aGUge0Bjb2RlIFNRTEV4Y2VwdGlvbn0gdGhhdCBoYXMgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY29ubmVjdGlvbkVycm9yT2NjdXJyZWQoQ29ubmVjdGlvbkV2ZW50IHRoZUV2ZW50KTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zcWwvQ29ubmVjdGlvblBvb2xEYXRhU291cmNlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc3FsL0Nvbm5lY3Rpb25Qb29sRGF0YVNvdXJjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyNjNlNzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc3FsL0Nvbm5lY3Rpb25Qb29sRGF0YVNvdXJjZS5qYXZhCkBAIC0wLDAgKzEsNTkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LnNxbDsKKworaW1wb3J0IGphdmEuc3FsLlNRTEV4Y2VwdGlvbjsKKworLyoqCisgKiBBbiBpbnRlcmZhY2UgZm9yIHRoZSBjcmVhdGlvbiBvZiB7QGNvZGUgQ29ubmVjdGlvblBvb2xEYXRhU291cmNlfSBvYmplY3RzLgorICogVXNlZCBpbnRlcm5hbGx5IHdpdGhpbiB0aGUgcGFja2FnZS4KKyAqIDxwPgorICogQSBjbGFzcyB3aGljaCBpbXBsZW1lbnRzIHRoZSB7QGNvZGUgQ29ubmVjdGlvblBvb2xEYXRhU291cmNlfSBpbnRlcmZhY2UgaXMKKyAqIHR5cGljYWxseSByZWdpc3RlcmVkIHdpdGggYSBKTkRJIG5hbWluZyBzZXJ2aWNlIGRpcmVjdG9yeSBhbmQgaXMgcmV0cmlldmVkCisgKiBmcm9tIHRoZXJlIGJ5IG5hbWUuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQ29ubmVjdGlvblBvb2xEYXRhU291cmNlIGV4dGVuZHMgQ29tbW9uRGF0YVNvdXJjZSB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgY29ubmVjdGlvbiB0byBhIGRhdGFiYXNlIHdoaWNoIGNhbiB0aGVuIGJlIHVzZWQgYXMgYSBwb29sZWQKKyAgICAgKiBjb25uZWN0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBhIHtAY29kZSBQb29sZWRDb25uZWN0aW9ufSB3aGljaCByZXByZXNlbnRzIHRoZSBjb25uZWN0aW9uIHRvIHRoZQorICAgICAqICAgICAgICAgZGF0YWJhc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUG9vbGVkQ29ubmVjdGlvbiBnZXRQb29sZWRDb25uZWN0aW9uKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBjb25uZWN0aW9uIHRvIGEgZGF0YWJhc2UsIHVzaW5nIHRoZSBzdXBwbGllZCB1c2VyIG5hbWUgYW5kCisgICAgICogcGFzc3dvcmQsIHdoaWNoIGNhbiB0aGVuIGJlIHVzZWQgYXMgYSBwb29sZWQgY29ubmVjdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVVc2VyCisgICAgICogICAgICAgICAgICB0aGUgYSB1c2VyIG5hbWUgZm9yIHRoZSBkYXRhYmFzZSBsb2dpbi4KKyAgICAgKiBAcGFyYW0gdGhlUGFzc3dvcmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXNzd29yZCBhc3NvY2lhdGVkIHdpdGggdGhlIHVzZXIgaWRlbnRpZmllZCBieSB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIHRoZVVzZXJ9LgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgUG9vbGVkQ29ubmVjdGlvbn0gb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIGNvbm5lY3Rpb24KKyAgICAgKiAgICAgICAgIHRvIHRoZSBkYXRhYmFzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBQb29sZWRDb25uZWN0aW9uIGdldFBvb2xlZENvbm5lY3Rpb24oU3RyaW5nIHRoZVVzZXIsCisgICAgICAgICAgICBTdHJpbmcgdGhlUGFzc3dvcmQpIHRocm93cyBTUUxFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc3FsL0RhdGFTb3VyY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zcWwvRGF0YVNvdXJjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgwYzI4NjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc3FsL0RhdGFTb3VyY2UuamF2YQpAQCAtMCwwICsxLDgyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5zcWw7CisKK2ltcG9ydCBqYXZhLnNxbC5Db25uZWN0aW9uOworaW1wb3J0IGphdmEuc3FsLlNRTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5XcmFwcGVyOworCisvKioKKyAqIEFuIGludGVyZmFjZSBmb3IgdGhlIGNyZWF0aW9uIG9mIHtAY29kZSBDb25uZWN0aW9ufSBvYmplY3RzIHdoaWNoIHJlcHJlc2VudCBhCisgKiBjb25uZWN0aW9uIHRvIGEgZGF0YWJhc2UuIFRoaXMgaW50ZXJmYWNlIGlzIGFuIGFsdGVybmF0aXZlIHRvIHRoZSB7QGNvZGUKKyAqIGphdmEuc3FsLkRyaXZlck1hbmFnZXJ9LgorICogPHA+CisgKiBBIGNsYXNzIHdoaWNoIGltcGxlbWVudHMgdGhlIHtAY29kZSBEYXRhU291cmNlfSBpbnRlcmZhY2UgaXMgdHlwaWNhbGx5CisgKiByZWdpc3RlcmVkIHdpdGggYSBKTkRJIG5hbWluZyBzZXJ2aWNlIGRpcmVjdG9yeSBhbmQgaXMgcmV0cmlldmVkIGZyb20gdGhlcmUKKyAqIGJ5IG5hbWUuCisgKiA8cD4KKyAqIFRoZSB7QGNvZGUgRGF0YVNvdXJjZX0gaW50ZXJmYWNlIGlzIHR5cGljYWxseSBpbXBsZW1lbnRlZCBieSB0aGUgd3JpdGVyIG9mIGEKKyAqIEpEQkMgZHJpdmVyLiBUaGVyZSBhcmUgdGhyZWUgdmFyaWFudHMgb2YgdGhlIHtAY29kZSBEYXRhU291cmNlfSBpbnRlcmZhY2UsCisgKiB3aGljaCBwcm9kdWNlIGNvbm5lY3Rpb25zIHdpdGggZGlmZmVyZW50IGNoYXJhY3RlcmlzdGljczoKKyAqIDxvbD4KKyAqIDxsaT48aT5TdGFuZGFyZCB7QGNvZGUgRGF0YVNvdXJjZX08L2k+OiBwcm9kdWNlcyBzdGFuZGFyZCB7QGNvZGUgQ29ubmVjdGlvbn0KKyAqIG9iamVjdHMgd2l0aCBubyBzcGVjaWFsIGZlYXR1cmVzLjwvbGk+CisgKiA8bGk+PGk+Q29ubmVjdGlvbiBQb29sIHtAY29kZSBEYXRhU291cmNlfTwvaT46IHByb2R1Y2VzIHtAY29kZQorICogUG9vbGVkQ29ubmVjdGlvbn0gb2JqZWN0cyB3aGljaCByZXF1aXJlIGEgY29ubmVjdGlvbiBwb29sIG1hbmFnZXIgYXMgYW4KKyAqIGludGVybWVkaWFyeSBjb21wb25lbnQuPC9saT4KKyAqIDxsaT48aT5EaXN0cmlidXRlZCB0cmFuc2FjdGlvbiB7QGNvZGUgRGF0YVNvdXJjZX0gKCJYQURhdGFTb3VyY2UiKTwvaT46CisgKiBwcm9kdWNlcyB7QGNvZGUgWEFDb25uZWN0aW9ufSBvYmplY3RzIHdoaWNoIGNhbiBiZSB1c2VkIHRvIGhhbmRsZSBkaXN0cmlidXRlZAorICogdHJhbnNhY3Rpb25zIHdoaWNoIHR5cGljYWxseSByZXF1aXJlIGFuIGludGVybWVkaWFyeSB0cmFuc2FjdGlvbiBtYW5hZ2VyCisgKiBjb21wb25lbnQuIHtAY29kZSBYQUNvbm5lY3Rpb259IG9iamVjdHMgYWxzbyBwcm92aWRlIGNvbm5lY3Rpb24gcG9vbGluZworICogY2FwYWJpbGl0aWVzIGFzIHdlbGwgYXMgZGlzdHJpYnV0ZWQgdHJhbnNhY3Rpb24gY2FwYWJpbGl0aWVzLjwvbGk+CisgKiA8L29sPgorICogPHA+CisgKiBOb3RlIHRoYXQgYSBKREJDIGRyaXZlciB3aGljaCBpcyBhY2Nlc3NlZCB2aWEgdGhlIHtAY29kZSBEYXRhU291cmNlfQorICogaW50ZXJmYWNlIGlzIGxvYWRlZCB2aWEgYSBKTkRJIGxvb2t1cCBwcm9jZXNzLiBBIGRyaXZlciBsb2FkZWQgaW4gdGhpcyB3YXkKKyAqIGRvZXMgbm90IHJlZ2lzdGVyIGl0c2VsZiB3aXRoIHRoZSB7QGNvZGUgRHJpdmVyTWFuYWdlcn0uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRGF0YVNvdXJjZSBleHRlbmRzIENvbW1vbkRhdGFTb3VyY2UsIFdyYXBwZXIgeworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGNvbm5lY3Rpb24gdG8gdGhlIGRhdGFiYXNlIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlCisgICAgICogRGF0YVNvdXJjZX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIENvbm5lY3Rpb259IG9iamVjdCB3aGljaCBpcyBhIGNvbm5lY3Rpb24gdG8gdGhlCisgICAgICogICAgICAgICBkYXRhYmFzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBDb25uZWN0aW9uIGdldENvbm5lY3Rpb24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGNvbm5lY3Rpb24gdG8gdGhlIGRhdGFiYXNlIHJlcHJlc2VudGVkIGJ5IHRoaXMge0Bjb2RlCisgICAgICogRGF0YVNvdXJjZX0sIHVzaW5nIHRoZSBzdXBwbGllZCB1c2VyIG5hbWUgYW5kIHBhc3N3b3JkLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZVVzZXJuYW1lCisgICAgICogICAgICAgICAgICB0aGUgYSB1c2VyIG5hbWUgZm9yIHRoZSBkYXRhYmFzZSBsb2dpbi4KKyAgICAgKiBAcGFyYW0gdGhlUGFzc3dvcmQKKyAgICAgKiAgICAgICAgICAgIHRoZSBwYXNzd29yZCBhc3NvY2lhdGVkIHdpdGggdGhlIHVzZXIgaWRlbnRpZmllZCBieSB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIHRoZVVzZXJuYW1lfS4KKyAgICAgKiBAcmV0dXJuIHRoZSB7QGNvZGUgQ29ubmVjdGlvbn0gb2JqZWN0IHdoaWNoIGlzIHRoZSBjb25uZWN0aW9uIHRvIHRoZQorICAgICAqICAgICAgICAgZGF0YWJhc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29ubmVjdGlvbiBnZXRDb25uZWN0aW9uKFN0cmluZyB0aGVVc2VybmFtZSwgU3RyaW5nIHRoZVBhc3N3b3JkKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zcWwvUG9vbGVkQ29ubmVjdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NxbC9Qb29sZWRDb25uZWN0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDQ0YzVlYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zcWwvUG9vbGVkQ29ubmVjdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTMyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5zcWw7CisKK2ltcG9ydCBqYXZhLnNxbC5Db25uZWN0aW9uOworaW1wb3J0IGphdmEuc3FsLlNRTEV4Y2VwdGlvbjsKKworLyoqCisgKiBBbiBpbnRlcmZhY2Ugd2hpY2ggcHJvdmlkZXMgZmFjaWxpdGllcyBmb3IgaGFuZGxpbmcgY29ubmVjdGlvbnMgdG8gYSBkYXRhYmFzZQorICogd2hpY2ggYXJlIHBvb2xlZC4KKyAqIDxwPgorICogVHlwaWNhbGx5LCBhIHtAY29kZSBQb29sZWRDb25uZWN0aW9ufSBpcyByZWN5Y2xlZCB3aGVuIGl0IGlzIG5vIGxvbmdlcgorICogcmVxdWlyZWQgYnkgYW4gYXBwbGljYXRpb24sIHJhdGhlciB0aGFuIGJlaW5nIGNsb3NlZCBhbmQgZGlzY2FyZGVkLiBUaGUKKyAqIHJlYXNvbiBmb3IgdHJlYXRpbmcgY29ubmVjdGlvbnMgaW4gdGhpcyB3YXkgaXMgdGhhdCBpdCBjYW4gYmUgYW4gZXhwZW5zaXZlCisgKiBwcm9jZXNzIGJvdGggdG8gZXN0YWJsaXNoIGEgY29ubmVjdGlvbiB0byBhIGRhdGFiYXNlIGFuZCB0byBkZXN0cm95IHRoZQorICogY29ubmVjdGlvbi4gUmV1c2luZyBjb25uZWN0aW9ucyB0aHJvdWdoIGEgcG9vbCBpcyBhIHdheSBvZiBpbXByb3Zpbmcgc3lzdGVtCisgKiBwZXJmb3JtYW5jZSBhbmQgcmVkdWNpbmcgb3ZlcmhlYWQuCisgKiA8cD4KKyAqIEl0IGlzIG5vdCBpbnRlbmRlZCB0aGF0IGFuIGFwcGxpY2F0aW9uIHVzZXMgdGhlIHtAY29kZSBQb29sZWRDb25uZWN0aW9ufQorICogaW50ZXJmYWNlIGRpcmVjdGx5LiBUaGUge0Bjb2RlIFBvb2xlZENvbm5lY3Rpb259IGludGVyZmFjZSBpcyBpbnRlbmRlZCBmb3IKKyAqIHVzZSBieSBhIGNvbXBvbmVudCBjYWxsZWQgYSBjb25uZWN0aW9uIHBvb2wgbWFuYWdlciwgdHlwaWNhbGx5IHBhcnQgb2YgdGhlCisgKiBpbmZyYXN0cnVjdHVyZSB0aGF0IHN1cHBvcnRzIHVzZSBvZiB0aGUgZGF0YWJhc2UgYnkgYXBwbGljYXRpb25zLgorICogPHA+CisgKiBBcHBsaWNhdGlvbnMgb2J0YWluIGNvbm5lY3Rpb25zIHRvIHRoZSBkYXRhYmFzZSBieSBjYWxsaW5nIHRoZQorICoge0BsaW5rIERhdGFTb3VyY2UjZ2V0Q29ubmVjdGlvbn0gbWV0aG9kLiBCZWhpbmQgdGhlIHNjZW5lcywgdGhlIGNvbm5lY3Rpb24KKyAqIHBvb2wgbWFuYWdlciB3aWxsIGdldCBhIHtAY29kZSBQb29sZWRDb25uZWN0aW9ufSBvYmplY3QgZnJvbSBpdHMgY29ubmVjdGlvbgorICogcG9vbCBhbmQgcGFzc2VzIGJhY2sgYSBjb25uZWN0aW9uIG9iamVjdCB0aGF0IHdyYXBzIG9yIHJlZmVyZW5jZXMgdGhlIHtAY29kZQorICogUG9vbGVkQ29ubmVjdGlvbn0gb2JqZWN0LiBBIG5ldyB7QGNvZGUgUG9vbGVkQ29ubmVjdGlvbn0gb2JqZWN0IHdpbGwgb25seSBiZQorICogY3JlYXRlZCBpZiB0aGUgcG9vbCBpcyBlbXB0eS4KKyAqIDxwPgorICogV2hlbiB0aGUgYXBwbGljYXRpb24gaXMgZmluaXNoZWQgdXNpbmcgYSB7QGNvZGUgUG9vbGVkQ29ubmVjdGlvbn0sIHRoZQorICogYXBwbGljYXRpb24gY2FsbHMgdGhlIHtAbGluayBDb25uZWN0aW9uI2Nsb3NlfSBtZXRob2QuIFRoZSBjb25uZWN0aW9uIHBvb2wKKyAqIG1hbmFnZXIgaXMgbm90aWZpZWQgdmlhIGEge0BsaW5rIENvbm5lY3Rpb25FdmVudH0gZnJvbSB0aGUgY29ubmVjdGlvbiB0aGF0CisgKiB0aGlzIGhhcyBoYXBwZW5lZCAodGhlIHBvb2wgbWFuYWdlciByZWdpc3RlcnMgaXRzZWxmIHdpdGggdGhlIGNvbm5lY3Rpb24KKyAqIGJlZm9yZSB0aGUgY29ubmVjdGlvbiBpcyBnaXZlbiB0byB0aGUgYXBwbGljYXRpb24pLiBUaGUgcG9vbCBtYW5hZ2VyIHJlbW92ZXMKKyAqIHRoZSB1bmRlcmx5aW5nIHtAY29kZSBQb29sZWRDb25uZWN0aW9ufSBvYmplY3QgZnJvbSB0aGUgY29ubmVjdGlvbiBhbmQKKyAqIHJldHVybnMgaXQgdG8gdGhlIHBvb2wgZm9yIHJldXNlIC0gdGhlIHtAY29kZSBQb29sZWRDb25uZWN0aW9ufSBpcyB0aHVzCisgKiByZWN5Y2xlZCByYXRoZXIgdGhhbiBiZWluZyBkZXN0cm95ZWQuCisgKiA8cD4KKyAqIFRoZSBjb25uZWN0aW9uIHRvIHRoZSBkYXRhYmFzZSByZXByZXNlbnRlZCBieSB0aGUge0Bjb2RlIFBvb2xlZENvbm5lY3Rpb259IGlzCisgKiBrZXB0IG9wZW4gdW50aWwgdGhlIHtAY29kZSBQb29sZWRDb25uZWN0aW9ufSBvYmplY3QgaXRzZWxmIGlzIGRlYWN0aXZhdGVkIGJ5CisgKiB0aGUgY29ubmVjdGlvbiBwb29sIG1hbmFnZXIsIHdoaWNoIGNhbGxzIHtAY29kZSBQb29sZWRDb25uZWN0aW9uLmNsb3NlKCl9LgorICogVGhpcyBpcyB0eXBpY2FsbHkgZG9uZSBpZiB0aGVyZSBhcmUgdG9vIG1hbnkgaW5hY3RpdmUgY29ubmVjdGlvbnMgaW4gdGhlCisgKiBwb29sLCBpZiB0aGUge0Bjb2RlIFBvb2xlZENvbm5lY3Rpb259IGVuY291bnRlcnMgYSBwcm9ibGVtIHRoYXQgbWFrZXMgaXQKKyAqIHVudXNhYmxlIG9yIGlmIHRoZSB3aG9sZSBzeXN0ZW0gaXMgYmVpbmcgc2h1dCBkb3duLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFBvb2xlZENvbm5lY3Rpb24geworCisgICAgLyoqCisgICAgICogUmVnaXN0ZXJzIHRoZSBzdXBwbGllZCB7QGNvZGUgQ29ubmVjdGlvbkV2ZW50TGlzdGVuZXJ9IHdpdGggdGhpcyB7QGNvZGUKKyAgICAgKiBQb29sZWRDb25uZWN0aW9ufS4gT25jZSByZWdpc3RlcmVkLCB0aGUge0Bjb2RlIENvbm5lY3Rpb25FdmVudExpc3RlbmVyfQorICAgICAqIHdpbGwgcmVjZWl2ZSB7QGxpbmsgQ29ubmVjdGlvbkV2ZW50fSBldmVudHMgd2hlbiB0aGV5IG9jY3VyIGluIHRoZQorICAgICAqIHtAY29kZSBQb29sZWRDb25uZWN0aW9ufS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVMaXN0ZW5lcgorICAgICAqICAgICAgICAgICAgYW4gb2JqZWN0IHdoaWNoIGltcGxlbWVudHMgdGhlIHtAY29kZSBDb25uZWN0aW9uRXZlbnRMaXN0ZW5lcn0KKyAgICAgKiAgICAgICAgICAgIGludGVyZmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRDb25uZWN0aW9uRXZlbnRMaXN0ZW5lcihDb25uZWN0aW9uRXZlbnRMaXN0ZW5lciB0aGVMaXN0ZW5lcik7CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIGRhdGFiYXNlIGhlbGQgYnkgdGhpcyB7QGNvZGUKKyAgICAgKiBQb29sZWRDb25uZWN0aW9ufS4gVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZSBjYWxsZWQgZGlyZWN0bHkgYnkKKyAgICAgKiBhcHBsaWNhdGlvbiBjb2RlIC0gaXQgaXMgaW50ZW5kZWQgb25seSBmb3IgdGhlIGNvbm5lY3Rpb24gcG9vbCBtYW5hZ2VyCisgICAgICogY29tcG9uZW50LgorICAgICAqCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgY29ubmVjdGlvbiB0byB0aGUgZGF0YWJhc2UuIFRoaXMgbWV0aG9kIGlzIHR5cGljYWxseSBjYWxsZWQgYnkKKyAgICAgKiB0aGUgY29ubmVjdGlvbiBwb29sIG1hbmFnZXIgd2hlbiBhbiBhcHBsaWNhdGlvbiBpbnZva2VzIHRoZSBtZXRob2QKKyAgICAgKiB7QGNvZGUgRGF0YVNvdXJjZS5nZXRDb25uZWN0aW9uKCl9IGFuZCB0aGVyZSBhcmUgbm8ge0Bjb2RlCisgICAgICogUG9vbGVkQ29ubmVjdGlvbn0gb2JqZWN0cyBhdmFpbGFibGUgaW4gdGhlIGNvbm5lY3Rpb24gcG9vbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgQ29ubmVjdGlvbn0gb2JqZWN0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBwcm9ibGVtIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIENvbm5lY3Rpb24gZ2V0Q29ubmVjdGlvbigpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBVbnJlZ2lzdGVycyB0aGUgc3VwcGxpZWQge0Bjb2RlIENvbm5lY3Rpb25FdmVudExpc3RlbmVyfSBmcm9tIHRoaXMge0Bjb2RlCisgICAgICogUG9vbGVkQ29ubmVjdGlvbn0uIE9uY2UgdW5yZWdpc3RlcmVkLCB0aGUge0Bjb2RlIENvbm5lY3Rpb25FdmVudExpc3RlbmVyfQorICAgICAqIHdpbGwgbm8gbG9uZ2VyIHJlY2VpdmUgZXZlbnRzIG9jY3VycmluZyBpbiB0aGUge0Bjb2RlIFBvb2xlZENvbm5lY3Rpb259LgorICAgICAqCisgICAgICogQHBhcmFtIHRoZUxpc3RlbmVyCisgICAgICogICAgICAgICAgICBhbiBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyB0aGUge0Bjb2RlIENvbm5lY3Rpb25FdmVudExpc3RlbmVyfQorICAgICAqICAgICAgICAgICAgaW50ZXJmYWNlLiBUaGlzIG9iamVjdCBzaG91bGQgaGF2ZSBwcmV2aW91c2x5IGJlZW4gcmVnaXN0ZXJlZAorICAgICAqICAgICAgICAgICAgd2l0aCB0aGUge0Bjb2RlIFBvb2xlZENvbm5lY3Rpb259IHVzaW5nIHRoZSB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIGFkZENvbm5lY3Rpb25FdmVudExpc3RlbmVyfSBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlQ29ubmVjdGlvbkV2ZW50TGlzdGVuZXIoCisgICAgICAgICAgICBDb25uZWN0aW9uRXZlbnRMaXN0ZW5lciB0aGVMaXN0ZW5lcik7CisKKyAgICAvKioKKyAgICAgKiBBZGQgYSBTdGF0ZW1lbnRFdmVudExpc3RlbmVyIHRvIHRoaXMgUG9vbGVkQ29ubmVjdGlvbiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGlzdGVuZXIKKyAgICAgKiAgICAgICAgICAgIEEgU3RhdGVtZW50RXZlbnRMaXN0ZW5lciBvYmplY3Qgd2hpY2ggaXMgdG8gYmUgYWRkZWQgd2l0aCB0aGlzCisgICAgICogICAgICAgICAgICBQb29sZWRDb25uZWN0aW9uIG9iamVjdAorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRTdGF0ZW1lbnRFdmVudExpc3RlbmVyKFN0YXRlbWVudEV2ZW50TGlzdGVuZXIgbGlzdGVuZXIpOworCisgICAgLyoqCisgICAgICogUmVtb3ZlIGEgU3RhdGVtZW50RXZlbnRMaXN0ZW5lciBmcm9tIHRoaXMgUG9vbGVkQ29ubmVjdGlvbiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGlzdGVuZXIKKyAgICAgKiAgICAgICAgICAgIEEgU3RhdGVtZW50RXZlbnRMaXN0ZW5lciBvYmplY3Qgd2hpY2ggaXMgdG8gYmUgcmVtb3ZlZCBmb3JtCisgICAgICogICAgICAgICAgICB0aGlzIFBvb2xlZENvbm5lY3Rpb24gb2JqZWN0CisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZVN0YXRlbWVudEV2ZW50TGlzdGVuZXIoU3RhdGVtZW50RXZlbnRMaXN0ZW5lciBsaXN0ZW5lcik7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc3FsL1Jvd1NldC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NxbC9Sb3dTZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44Yzc0ZmU5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NxbC9Sb3dTZXQuamF2YQpAQCAtMCwwICsxLDE4MTcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LnNxbDsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CitpbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEuc3FsLkFycmF5OworaW1wb3J0IGphdmEuc3FsLkJsb2I7CitpbXBvcnQgamF2YS5zcWwuQ2xvYjsKK2ltcG9ydCBqYXZhLnNxbC5EYXRlOworaW1wb3J0IGphdmEuc3FsLk5DbG9iOworaW1wb3J0IGphdmEuc3FsLlJlZjsKK2ltcG9ydCBqYXZhLnNxbC5SZXN1bHRTZXQ7CitpbXBvcnQgamF2YS5zcWwuUm93SWQ7CitpbXBvcnQgamF2YS5zcWwuU1FMRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc3FsLlNRTFhNTDsKK2ltcG9ydCBqYXZhLnNxbC5UaW1lOworaW1wb3J0IGphdmEuc3FsLlRpbWVzdGFtcDsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBBbiBpbnRlcmZhY2Ugd2hpY2ggcHJvdmlkZXMgbWVhbnMgdG8gYWNjZXNzIGRhdGEgd2hpY2gKKyAqIHBlcnNpc3RzIG9uIGEgZGF0YWJhc2UuIEl0IGV4dGVuZHMgdGhlIGZ1bmN0aW9uYWxpdHkgb2YKKyAqIHtAbGluayBqYXZhLnNxbC5SZXN1bHRTZXQgUmVzdWx0U2V0fSBpbnRvIGEgZm9ybSB0aGF0IGl0IGNhbiBiZSB1c2VkIGFzIGEKKyAqIEphdmFCZWFuIGNvbXBvbmVudCwgc3VpdGVkIGZvciBhIHZpc3VhbCBwcm9ncmFtbWluZyBlbnZpcm9ubWVudC4KKyAqIDxwPgorICoge0Bjb2RlIFJvd1NldH0gcHJvdmlkZXMgZ2V0dGVycyBhbmQgc2V0dGVycyBmb3IgcHJvcGVydGllcyByZWxhdGluZyB0byB0aGUKKyAqIGdlbmVyYWwgZGF0YWJhc2UgZW52aXJvbm1lbnQgdG9nZXRoZXIgd2l0aCB0aGUgZ2V0dGVycyBhbmQgc2V0dGVycyBmb3IKKyAqIGRpc3RpbmN0IGRhdGEgdmFsdWVzIHdoaWNoIGNvbnN0aXR1dGUgdGhlIHJvdyBzZXQuIFRoZSB7QGNvZGUgUm93U2V0fSBjbGFzcworICogc3VwcG9ydHMgSmF2YUJlYW4gZXZlbnRzIHNvIHRoYXQgb3RoZXIgY29tcG9uZW50cyBpbiBhbiBhcHBsaWNhdGlvbiBjYW4gYmUKKyAqIGluZm9ybWVkIHdoZW4gY2hhbmdlcyBoYXBwZW4gc3VjaCBhcyBjaGFuZ2VzIGluIGRhdGEgdmFsdWVzLgorICogPHA+CisgKiB7QGNvZGUgUm93U2V0fSBpcyBhIGZhY2lsaXR5IGltcGxlbWVudGVkIG9uIHRvcCBvZiB0aGUgcmVtYWluZGVyIG9mIHRoZSBKREJDCisgKiBBUEkuIEl0IG1heSBiZSA8aT5jb25uZWN0ZWQ8L2k+LCBtYWludGFpbmluZyBhIGNvbm5lY3Rpb24gdG8gdGhlIGRhdGFiYXNlCisgKiB0aHJvdWdob3V0IGl0cyBsaWZlY3ljbGUuIFRoZSBjaGFuZ2VzIG1hZGUgb24gYSA8aT5kaXNjb25uZWN0ZWQ8L2k+IHtAY29kZQorICogUm93U2V0fSBvbiB0aGUgb3RoZXIgaGFuZCBjYW4gYmUgcGVyc2lzdGVkIG9ubHkgZXN0YWJsaXNoaW5nIGEgbmV3IGNvbm5lY3Rpb24KKyAqIHdpdGggdGhlIGRhdGFiYXNlIGVhY2ggdGltZS4KKyAqIDxwPgorICogRGlzY29ubmVjdGVkIHtAY29kZSBSb3dTZXRzfSBtYWtlIHVzZSBvZiB7QGNvZGUgUm93U2V0UmVhZGVyc30gdG8gcG9wdWxhdGUKKyAqIHRoZSB7QGNvZGUgUm93U2V0fSB3aXRoIGRhdGEsIHBvc3NpYmx5IGZyb20gYSBub24tcmVsYXRpb25hbCBkYXRhYmFzZSBzb3VyY2UuCisgKiBUaGV5IG1heSBhbHNvIHVzZSB7QGNvZGUgUm93U2V0V3JpdGVyc30gdG8gc2VuZCBkYXRhIGJhY2sgdG8gdGhlIHVuZGVybHlpbmcKKyAqIGRhdGEgc3RvcmUuIFRoZXJlIGlzIGNvbnNpZGVyYWJsZSBmcmVlZG9tIGluIHRoZSB3YXkgdGhhdCB7QGNvZGUKKyAqIFJvd1NldFJlYWRlcnN9IGFuZCB7QGNvZGUgUm93U2V0V3JpdGVyc30gbWF5IGJlIGltcGxlbWVudGVkIHRvIHJldHJpZXZlIGFuZAorICogc3RvcmUgZGF0YS4KKyAqCisgKiBAc2VlIFJvd1NldFJlYWRlcgorICogQHNlZSBSb3dTZXRXcml0ZXIKKyAqLworcHVibGljIGludGVyZmFjZSBSb3dTZXQgZXh0ZW5kcyBSZXN1bHRTZXQgeworCisgICAgLyoqCisgICAgICogUmVnaXN0ZXJzIHRoZSBzdXBwbGllZCB7QGxpbmsgUm93U2V0TGlzdGVuZXJ9IHdpdGggdGhpcyB7QGNvZGUgUm93U2V0fS4KKyAgICAgKiBPbmNlIHJlZ2lzdGVyZWQsIHRoZSB7QGxpbmsgUm93U2V0TGlzdGVuZXJ9IGlzIG5vdGlmaWVkIG9mIGV2ZW50cworICAgICAqIGdlbmVyYXRlZCBieSB0aGUge0Bjb2RlIFJvd1NldH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlTGlzdGVuZXIKKyAgICAgKiAgICAgICAgICAgIGFuIG9iamVjdCB3aGljaCBpbXBsZW1lbnRzIHRoZSB7QGNvZGUgcm93U2V0TGlzdGVuZXJ9CisgICAgICogICAgICAgICAgICBpbnRlcmZhY2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkUm93U2V0TGlzdGVuZXIoUm93U2V0TGlzdGVuZXIgdGhlTGlzdGVuZXIpOworCisgICAgLyoqCisgICAgICogQ2xlYXJzIHRoZSBwYXJhbWV0ZXJzIHByZXZpb3VzbHkgc2V0IGZvciB0aGlzIHtAY29kZSBSb3dTZXR9LgorICAgICAqIDxwPgorICAgICAqIFRoZSB7QGNvZGUgUm93U2V0fSBvYmplY3QgcmV0YWlucyBpdHMgdmFsdWUgdW50aWwgZWl0aGVyIGEgbmV3IHZhbHVlIGZvcgorICAgICAqIGEgcGFyYW1ldGVyIGlzIHNldCBvciBpdHMgdmFsdWUgaXMgYWN0aXZlbHkgcmVzZXQuIHtAY29kZQorICAgICAqIGNsZWFyUGFyYW1ldGVyc30gcHJvdmlkZXMgYSBmYWNpbGl0eSB0byBjbGVhciB0aGUgdmFsdWVzIGZvciBhbGwKKyAgICAgKiBwYXJhbWV0ZXJzIHdpdGggb25lIG1ldGhvZCBjYWxsLgorICAgICAqCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHByb2JsZW0gb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXJQYXJhbWV0ZXJzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEZldGNoZXMgZGF0YSBmb3IgdGhpcyB7QGNvZGUgUm93U2V0fSBmcm9tIHRoZSBkYXRhYmFzZS4gSWYgc3VjY2Vzc2Z1bCwKKyAgICAgKiBhbnkgZXhpc3RpbmcgZGF0YSBmb3IgdGhlIHtAY29kZSBSb3dTZXR9IGlzIGRpc2NhcmRlZCBhbmQgaXRzIG1ldGFkYXRhIGlzCisgICAgICogb3ZlcndyaXR0ZW4uCisgICAgICogPHA+CisgICAgICogRGF0YSBpcyByZXRyaWV2ZWQgY29ubmVjdGluZyB0byB0aGUgZGF0YWJhc2UgYW5kIGV4ZWN1dGluZyBhbgorICAgICAqIGFjY29yZGluZyBTUUwgc3RhdGVtZW50LiBUaGlzIHJlcXVpcmVzIHNvbWUgb3IgYWxsIG9mIHRoZSBmb2xsb3dpbmcKKyAgICAgKiBwcm9wZXJ0aWVzIHRvIGJlIHNldDogVVJMLCBkYXRhYmFzZSBuYW1lLCB1c2VyIG5hbWUsIHBhc3N3b3JkLAorICAgICAqIHRyYW5zYWN0aW9uIGlzb2xhdGlvbiwgdHlwZSBtYXA7IHBsdXMgc29tZSBvciBhbGwgb2YgdGhlIHByb3BlcnRpZXM6CisgICAgICogY29tbWFuZCwgcmVhZCBvbmx5LCBtYXhpbXVtIGZpZWxkIHNpemUsIG1heGltdW0gcm93cywgZXNjYXBlIHByb2Nlc3NpbmcsCisgICAgICogYW5kIHF1ZXJ5IHRpbWVvdXQuCisgICAgICogPHA+CisgICAgICogVGhlIHtAY29kZSBSb3dTZXR9IG1heSB1c2UgYSB7QGNvZGUgUm93U2V0UmVhZGVyfSB0byBhY2Nlc3MgdGhlIGRhdGFiYXNlCisgICAgICogaXQgd2lsbCB0aGVuIGludm9rZSB0aGUge0BsaW5rIFJvd1NldFJlYWRlciNyZWFkRGF0YX0gbWV0aG9kIG9uIHRoZQorICAgICAqIHJlYWRlciB0byBmZXRjaCB0aGUgZGF0YS4gV2hlbiB0aGUgbmV3IGRhdGEgaXMgZmV0Y2hlZCBhbGwgdGhlIGxpc3RlbmVycworICAgICAqIGFyZSBub3RpZmllZCB0byB0YWtlIGFwcHJvcHJpYXRlIG1lYXN1cmVzLgorICAgICAqCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHByb2JsZW0gb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2Ugb3IgaWYgdGhlCisgICAgICogICAgICAgICAgICAgcHJvcGVydGllcyBuZWVkZWQgdG8gYWNjZXNzIHRoZSBkYXRhYmFzZSBoYXZlIG5vdCBiZWVuIHNldC4KKyAgICAgKiBAc2VlIFJvd1NldE1ldGFEYXRhCisgICAgICogQHNlZSBSb3dTZXRSZWFkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBleGVjdXRlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHtAY29kZSBSb3dTZXR9J3MgY29tbWFuZCBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBzdHJpbmcgY29udGFpbmluZyB0aGUge0Bjb2RlIFJvd1NldH0ncyBjb21tYW5kIHByb3BlcnR5LiBBCisgICAgICogICAgICAgICBjb21tYW5kIGlzIGEgU1FMIHN0YXRlbWVudCB3aGljaCBpcyBleGVjdXRlZCB0byBmZXRjaCByZXF1aXJlZAorICAgICAqICAgICAgICAgZGF0YSBpbnRvIHRoZSB7QGNvZGUgUm93U2V0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbW1hbmQoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIE9EQkMgRGF0YSBTb3VyY2UgTmFtZSBwcm9wZXJ0eSBhc3NvY2lhdGVkIHdpdGggdGhpcyB7QGNvZGUKKyAgICAgKiBSb3dTZXR9LiBUaGUgZGF0YWJhc2UgbmFtZSBjYW4gYmUgdXNlZCB0byBmaW5kIGEge0BsaW5rIERhdGFTb3VyY2V9CisgICAgICogd2hpY2ggaGFzIGJlZW4gcmVnaXN0ZXJlZCB3aXRoIGEgbmFtaW5nIHNlcnZpY2UgLSB0aGUge0BsaW5rIERhdGFTb3VyY2V9CisgICAgICogY2FuIHRoZW4gYmUgdXNlZCB0byBjcmVhdGUgYSBjb25uZWN0aW9uIHRvIHRoZSBkYXRhYmFzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGF0YVNvdXJjZU5hbWUoKTsKKworICAgIC8qKgorICAgICAqIFJlcG9ydHMgaWYgZXNjYXBlIHByb2Nlc3NpbmcgaXMgZW5hYmxlZCBmb3IgdGhpcyB7QGNvZGUgUm93U2V0fS4gSWYKKyAgICAgKiBlc2NhcGUgcHJvY2Vzc2luZyBpcyBvbiwgdGhlIGRyaXZlciBwZXJmb3JtcyBhIHN1YnN0aXR1dGlvbiBvZiB0aGUgZXNjYXBlCisgICAgICogc3ludGF4IHdpdGggdGhlIGFwcGxpY2FibGUgY29kZSBiZWZvcmUgc2VuZGluZyBhbiBTUUwgY29tbWFuZCB0byB0aGUKKyAgICAgKiBkYXRhYmFzZS4gVGhlIGRlZmF1bHQgdmFsdWUgZm9yIGVzY2FwZSBwcm9jZXNzaW5nIGlzIHtAY29kZSB0cnVlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGVzY2FwZSBwcm9jZXNzaW5nIGlzIGVuYWJsZWQsIHtAY29kZQorICAgICAqICAgICAgICAgZmFsc2V9IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRFc2NhcGVQcm9jZXNzaW5nKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHRoYXQgY2FuIGJlIHJldHVybmVkIGZvciBjb2x1bW4gdmFsdWVzCisgICAgICogd2hpY2ggYXJlIG9mIHR5cGUge0Bjb2RlIEJJTkFSWX0sIHtAY29kZSBWQVJCSU5BUll9LCB7QGNvZGUKKyAgICAgKiBMT05HVkFSQklOQVJZQklOQVJZfSwge0Bjb2RlIENIQVJ9LCB7QGNvZGUgVkFSQ0hBUn0sIG9yIHtAY29kZQorICAgICAqIExPTkdWQVJDSEFSfS4gRXhjZXNzIGRhdGEgaXMgc2lsZW50bHkgZGlzY2FyZGVkIGlmIHRoZSBudW1iZXIgaXMKKyAgICAgKiBleGNlZWRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgbWF4aW11bSBzaXplIGluIGJ5dGVzLiAwIGltcGxpZXMgbm8gc2l6ZSBsaW1pdC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1heEZpZWxkU2l6ZSgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBtYXhpbXVtIG51bWJlciBvZiByb3dzIGZvciB0aGlzIHtAY29kZSBSb3dTZXR9LiBFeGNlc3Mgcm93cyBhcmUKKyAgICAgKiBkaXNjYXJkZWQgc2lsZW50bHkgaWYgdGhlIGxpbWl0IGlzIGV4Y2VlZGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgbWF4aW11bSBudW1iZXIgb2Ygcm93cy4gMCBpbXBsaWVzIG5vIHJvdyBsaW1pdC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1heFJvd3MoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgdGhlIHBhc3N3b3JkIHByb3BlcnR5IGZvciB0aGlzIHtAY29kZSBSb3dTZXR9LiBUaGlzCisgICAgICogcHJvcGVydHkgaXMgdXNlZCB3aGVuIGEgY29ubmVjdGlvbiB0byB0aGUgZGF0YWJhc2UgaXMgZXN0YWJsaXNoZWQuCisgICAgICogVGhlcmVmb3JlIGl0IHNob3VsZCBiZSBzZXQgcHJpb3IgdG8gaW52b2tpbmcgdGhlIHtAbGluayAjZXhlY3V0ZX0gbWV0aG9kLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHBhc3N3b3JkIHByb3BlcnR5LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGFzc3dvcmQoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHRpbWVvdXQgZm9yIHRoZSBkcml2ZXIgd2hlbiBhIHF1ZXJ5IG9wZXJhdGlvbiBpcyBleGVjdXRlZC4gSWYgYQorICAgICAqIHF1ZXJ5IHRha2VzIGxvbmdlciB0aGFuIHRoZSB0aW1lb3V0IHRoZW4gYSB7QGNvZGUgU1FMRXhjZXB0aW9ufSBpcworICAgICAqIHRocm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHRpbWVvdXQgdmFsdWUgaW4gc2Vjb25kcy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UXVlcnlUaW1lb3V0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHRyYW5zYWN0aW9uIGlzb2xhdGlvbiBsZXZlbCBwcm9wZXJ0eSBzZXQgZm9yIHRoaXMKKyAgICAgKiB7QGNvZGUgUm93U2V0fS4gVGhlIHRyYW5zYWN0aW9uIGlzb2xhdGlvbiBsZXZlbCBkZWZpbmVzIHRoZQorICAgICAqIHBvbGljeSBpbXBsZW1lbnRlZCBvbiB0aGUgZGF0YWJhc2UgZm9yIG1haW50YWluaW5nIHRoZSBkYXRhCisgICAgICogdmFsdWVzIGNvbnNpc3RlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uIGlzb2xhdGlvbiBsZXZlbC4gTXVzdCBiZSBvbmUgb2Y6CisgICAgICogICAgICAgICA8dWw+CisgICAgICogICAgICAgICA8bGk+e0Bjb2RlIENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fUkVBRF9VTkNPTU1JVFRFRH08L2xpPgorICAgICAqICAgICAgICAgPGxpPntAY29kZSBDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1JFQURfQ09NTUlUVEVEfTwvbGk+CisgICAgICogICAgICAgICA8bGk+e0Bjb2RlIENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fUkVQRUFUQUJMRV9SRUFEfTwvbGk+CisgICAgICogICAgICAgICA8bGk+e0Bjb2RlIENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fU0VSSUFMSVpBQkxFfTwvbGk+CisgICAgICogICAgICAgICA8L3VsPgorICAgICAqIEBzZWUgamF2YS5zcWwuQ29ubmVjdGlvbgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VHJhbnNhY3Rpb25Jc29sYXRpb24oKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGN1c3RvbSBtYXBwaW5nIG9mIFNRTCBVc2VyLURlZmluZWQgVHlwZXMgKFVEVHMpIGFuZCBKYXZhIGNsYXNzZXMKKyAgICAgKiBmb3IgdGhpcyB7QGNvZGUgUm93U2V0fSwgaWYgYXBwbGljYWJsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1c3RvbSBtYXBwaW5ncyBvZiBTUUwgdHlwZXMgdG8gSmF2YSBjbGFzc2VzLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIE1hcDxTdHJpbmcsIENsYXNzPD8+PiBnZXRUeXBlTWFwKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFVSTCBwcm9wZXJ0eSB2YWx1ZSBmb3IgdGhpcyB7QGNvZGUgUm93U2V0fS4gSWYgdGhlcmUgaXMgbm8KKyAgICAgKiB7QGNvZGUgRGF0YVNvdXJjZX0gb2JqZWN0IHNwZWNpZmllZCwgdGhlIHtAY29kZSBSb3dTZXR9IHVzZXMgdGhlIFVSTCB0bworICAgICAqIGVzdGFibGlzaCBhIGNvbm5lY3Rpb24gdG8gdGhlIGRhdGFiYXNlLiBUaGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhlIFVSTCBpcworICAgICAqIHtAY29kZSBudWxsfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBTdHJpbmcgaG9sZGluZyB0aGUgdmFsdWUgb2YgdGhlIFVSTCBwcm9wZXJ0eS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VXJsKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSB7QGNvZGUgdXNlcm5hbWV9IHByb3BlcnR5IGZvciB0aGlzIHtAY29kZSBSb3dTZXR9LgorICAgICAqIFRoZSB7QGNvZGUgdXNlcm5hbWV9IGlzIHVzZWQgd2hlbiBlc3RhYmxpc2hpbmcgYSBjb25uZWN0aW9uIHRvIHRoZQorICAgICAqIGRhdGFiYXNlIGFuZCBzaG91bGQgYmUgc2V0IGJlZm9yZSB0aGUge0Bjb2RlIGV4ZWN1dGV9IG1ldGhvZCBpcyBpbnZva2VkLgorICAgICAqCisgICAgICogQHJldHVybiBhIHtAY29kZSBTdHJpbmd9IGhvbGRpbmcgdGhlIHZhbHVlIG9mIHRoZSB7QGNvZGUgdXNlcm5hbWV9CisgICAgICogICAgICAgICBwcm9wZXJ0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFVzZXJuYW1lKCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgaWYgdGhpcyB7QGNvZGUgUm93U2V0fSBpcyByZWFkLW9ubHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHtAY29kZSBSb3dTZXR9IGlzIHJlYWQtb25seSwge0Bjb2RlIGZhbHNlfQorICAgICAqICAgICAgICAgaWYgaXQgaXMgdXBkYXRhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUmVhZE9ubHkoKTsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYSBzcGVjaWZpZWQge0BsaW5rIFJvd1NldExpc3RlbmVyfSBvYmplY3QgZnJvbSB0aGUgc2V0IG9mCisgICAgICogbGlzdGVuZXJzIHdoaWNoIHdpbGwgYmUgbm90aWZpZWQgb2YgZXZlbnRzIGJ5IHRoaXMge0Bjb2RlIFJvd1NldH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlTGlzdGVuZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGxpbmsgUm93U2V0TGlzdGVuZXJ9IHRvIHJlbW92ZSBmcm9tIHRoZSBzZXQgb2YgbGlzdGVuZXJzCisgICAgICogICAgICAgICAgICBmb3IgdGhpcyB7QGNvZGUgUm93U2V0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVSb3dTZXRMaXN0ZW5lcihSb3dTZXRMaXN0ZW5lciB0aGVMaXN0ZW5lcik7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzcGVjaWZpZWQge0Bjb2RlIEFSUkFZfSBwYXJhbWV0ZXIgaW4gdGhlIHtAY29kZSBSb3dTZXR9IGNvbW1hbmQKKyAgICAgKiB3aXRoIHRoZSBzdXBwbGllZCB7QGNvZGUgamF2YS5zcWwuQXJyYXl9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIHBhcmFtZXRlciB0byBzZXQ7IHRoZSBmaXJzdCBwYXJhbWV0ZXIncyBpbmRleAorICAgICAqICAgICAgICAgICAgaXMgMS4KKyAgICAgKiBAcGFyYW0gdGhlQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQXJyYXl9IGRhdGEgdmFsdWUgdG8gd2hpY2ggdGhlIHBhcmFtZXRlciBpcyBzZXQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRBcnJheShpbnQgcGFyYW1ldGVySW5kZXgsIEFycmF5IHRoZUFycmF5KQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSB7QGNvZGUgUm93U2V0fSBjb21tYW5kCisgICAgICogd2l0aCB0aGUgQVNDSUkgZGF0YSBpbiB0aGUgc3VwcGxpZWQge0Bjb2RlIGphdmEuaW8uSW5wdXRTdHJlYW19IHZhbHVlLgorICAgICAqIERhdGEgaXMgcmVhZCBmcm9tIHRoZSB7QGNvZGUgSW5wdXRTdHJlYW19IHVudGlsIGVuZC1vZi1maWxlIGlzIHJlYWNoZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgcGFyYW1ldGVyIHRvIHNldDsgdGhlIGZpcnN0IHBhcmFtZXRlcidzIGluZGV4CisgICAgICogICAgICAgICAgICBpcyAxLgorICAgICAqIEBwYXJhbSB0aGVJbnB1dFN0cmVhbQorICAgICAqICAgICAgICAgICAgdGhlIEFTQ0lJIGRhdGEgdmFsdWUgdG8gd2hpY2ggdGhlIHBhcmFtZXRlciBpcyBzZXQuCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YSBpbiBieXRlcy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEFzY2lpU3RyZWFtKGludCBwYXJhbWV0ZXJJbmRleCwgSW5wdXRTdHJlYW0gdGhlSW5wdXRTdHJlYW0sCisgICAgICAgICAgICBpbnQgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIFJvd1NldCBjb21tYW5kIHdpdGggdGhlCisgICAgICogQVNDSUkgZGF0YSBpbiB0aGUgc3VwcGxpZWQgamF2YS5pby5JbnB1dFN0cmVhbSB2YWx1ZS4gRGF0YSBpcyByZWFkIGZyb20KKyAgICAgKiB0aGUgSW5wdXRTdHJlYW0gdW50aWwgZW5kLW9mLWZpbGUgaXMgcmVhY2hlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgaW5kZXggb2YgdGhlIHBhcmFtZXRlciB0byBzZXQsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCA9IDEuCisgICAgICogQHBhcmFtIHRoZUlucHV0U3RyZWFtCisgICAgICogICAgICAgICAgICBhbiBJbnB1dFN0cmVhbSBjb250YWluaW5nIHRoZSBBU0NJSSBkYXRhIHRvIHNldCBpbnRvIHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyIHZhbHVlCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKworICAgIHB1YmxpYyB2b2lkIHNldEFzY2lpU3RyZWFtKGludCBwYXJhbWV0ZXJJbmRleCwgSW5wdXRTdHJlYW0gdGhlSW5wdXRTdHJlYW0pCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIFJvd1NldCBjb21tYW5kIHdpdGggdGhlCisgICAgICogQVNDSUkgZGF0YSBpbiB0aGUgc3VwcGxpZWQgamF2YS5pby5JbnB1dFN0cmVhbSB2YWx1ZS4gRGF0YSBpcyByZWFkIGZyb20KKyAgICAgKiB0aGUgSW5wdXRTdHJlYW0gdW50aWwgZW5kLW9mLWZpbGUgaXMgcmVhY2hlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZUlucHV0U3RyZWFtCisgICAgICogICAgICAgICAgICBhbiBJbnB1dFN0cmVhbSBjb250YWluaW5nIHRoZSBBU0NJSSBkYXRhIHRvIHNldCBpbnRvIHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyIHZhbHVlCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKworICAgIHB1YmxpYyB2b2lkIHNldEFzY2lpU3RyZWFtKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBJbnB1dFN0cmVhbSB0aGVJbnB1dFN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgd2l0aCB0aGUKKyAgICAgKiBBU0NJSSBkYXRhIGluIHRoZSBzdXBwbGllZCBqYXZhLmlvLklucHV0U3RyZWFtIHZhbHVlLiBEYXRhIGlzIHJlYWQgZnJvbQorICAgICAqIHRoZSBJbnB1dFN0cmVhbSB1bnRpbCBlbmQtb2YtZmlsZSBpcyByZWFjaGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIGZvciBwYXJhbWV0ZXIKKyAgICAgKiBAcGFyYW0gdGhlSW5wdXRTdHJlYW0KKyAgICAgKiAgICAgICAgICAgIGFuIElucHV0U3RyZWFtIGNvbnRhaW5pbmcgdGhlIEFTQ0lJIGRhdGEgdG8gc2V0IGludG8gdGhlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIgdmFsdWUKKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhIGluIGJ5dGVzCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRBc2NpaVN0cmVhbShTdHJpbmcgcGFyYW1ldGVyTmFtZSwKKyAgICAgICAgICAgIElucHV0U3RyZWFtIHRoZUlucHV0U3RyZWFtLCBpbnQgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBTUUwge0Bjb2RlIE5VTUVSSUN9IHBhcmFtZXRlciBpbiB0aGUKKyAgICAgKiB7QGNvZGUgUm93U2V0fSBjb21tYW5kIHdpdGggdGhlIGRhdGEgaW4gdGhlIHN1cHBsaWVkIHtAY29kZQorICAgICAqIGphdmEubWF0aC5CaWdEZWNpbWFsfSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0OyB0aGUgZmlyc3QgcGFyYW1ldGVyJ3MgaW5kZXgKKyAgICAgKiAgICAgICAgICAgIGlzIDEuCisgICAgICogQHBhcmFtIHRoZUJpZ0RlY2ltYWwKKyAgICAgKiAgICAgICAgICAgIHRoZSBiaWcgZGVjaW1hbCB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJpZ0RlY2ltYWwoaW50IHBhcmFtZXRlckluZGV4LCBCaWdEZWNpbWFsIHRoZUJpZ0RlY2ltYWwpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBTUUwgTlVNRVJJQyBwYXJhbWV0ZXIgaW4gdGhlIFJvd1NldAorICAgICAqIGNvbW1hbmQgd2l0aCB0aGUgZGF0YSBpbiB0aGUgc3VwcGxpZWQgamF2YS5tYXRoLkJpZ0RlY2ltYWwgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgZm9yIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSB0aGVCaWdEZWNpbWFsCisgICAgICogICAgICAgICAgICB0aGUgQmlnRGVjaW1hbCBjb250YWluaW5nIHRoZSB2YWx1ZQorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QmlnRGVjaW1hbChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgQmlnRGVjaW1hbCB0aGVCaWdEZWNpbWFsKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSB7QGNvZGUgUm93U2V0fSBjb21tYW5kCisgICAgICogdG8gdGhlIGJpbmFyeSBkYXRhIGluIHRoZSBzdXBwbGllZCBpbnB1dCBzdHJlYW0uIERhdGEgaXMgcmVhZCBmcm9tIHRoZQorICAgICAqIGlucHV0IHN0cmVhbSB1bnRpbCBlbmQtb2YtZmlsZSBpcyByZWFjaGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIHBhcmFtZXRlciB0byBzZXQ7IHRoZSBmaXJzdCBwYXJhbWV0ZXIncyBpbmRleAorICAgICAqICAgICAgICAgICAgaXMgMS4KKyAgICAgKiBAcGFyYW0gdGhlSW5wdXRTdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHRoZSBiaW5hcnkgZGF0YSBzdHJlYW0gdG8gd2hpY2ggdGhlIHBhcmFtZXRlciBpcyBzZXQuCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YSBpbiBieXRlcy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJpbmFyeVN0cmVhbShpbnQgcGFyYW1ldGVySW5kZXgsIElucHV0U3RyZWFtIHRoZUlucHV0U3RyZWFtLAorICAgICAgICAgICAgaW50IGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB3aXRoIHRoZQorICAgICAqIGJpbmFyeSBkYXRhIGluIHRoZSBzdXBwbGllZCBqYXZhLmlvLklucHV0U3RyZWFtIHZhbHVlLiBEYXRhIGlzIHJlYWQgZnJvbQorICAgICAqIHRoZSBJbnB1dFN0cmVhbSB1bnRpbCBlbmQtb2YtZmlsZSBpcyByZWFjaGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICBpbmRleCBvZiB0aGUgcGFyYW1ldGVyIHRvIHNldCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4ID0gMS4KKyAgICAgKiBAcGFyYW0gdGhlSW5wdXRTdHJlYW0KKyAgICAgKiAgICAgICAgICAgIGFuIElucHV0U3RyZWFtIGNvbnRhaW5pbmcgdGhlIGJpbmFyeSBkYXRhIHRvIHNldCBpbnRvIHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyIHZhbHVlCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCaW5hcnlTdHJlYW0oaW50IHBhcmFtZXRlckluZGV4LCBJbnB1dFN0cmVhbSB0aGVJbnB1dFN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgd2l0aCB0aGUKKyAgICAgKiBiaW5hcnkgZGF0YSBpbiB0aGUgc3VwcGxpZWQgamF2YS5pby5JbnB1dFN0cmVhbSB2YWx1ZS4gRGF0YSBpcyByZWFkIGZyb20KKyAgICAgKiB0aGUgSW5wdXRTdHJlYW0gdW50aWwgZW5kLW9mLWZpbGUgaXMgcmVhY2hlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZUlucHV0U3RyZWFtCisgICAgICogICAgICAgICAgICBhbiBJbnB1dFN0cmVhbSBjb250YWluaW5nIHRoZSBiaW5hcnkgZGF0YSB0byBzZXQgaW50byB0aGUKKyAgICAgKiAgICAgICAgICAgIHBhcmFtZXRlciB2YWx1ZQorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QmluYXJ5U3RyZWFtKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBJbnB1dFN0cmVhbSB0aGVJbnB1dFN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgd2l0aCB0aGUKKyAgICAgKiBiaW5hcnkgZGF0YSBpbiB0aGUgc3VwcGxpZWQgamF2YS5pby5JbnB1dFN0cmVhbSB2YWx1ZS4gRGF0YSBpcyByZWFkIGZyb20KKyAgICAgKiB0aGUgSW5wdXRTdHJlYW0gdW50aWwgZW5kLW9mLWZpbGUgaXMgcmVhY2hlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZUlucHV0U3RyZWFtCisgICAgICogICAgICAgICAgICBhbiBJbnB1dFN0cmVhbSBjb250YWluaW5nIHRoZSBiaW5hcnkgZGF0YSB0byBzZXQgaW50byB0aGUKKyAgICAgKiAgICAgICAgICAgIHBhcmFtZXRlciB2YWx1ZQorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgaW4gYnl0ZXMKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJpbmFyeVN0cmVhbShTdHJpbmcgcGFyYW1ldGVyTmFtZSwKKyAgICAgICAgICAgIElucHV0U3RyZWFtIHRoZUlucHV0U3RyZWFtLCBpbnQgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIHtAY29kZSBSb3dTZXR9IGNvbW1hbmQKKyAgICAgKiB0byB0aGUgc3VwcGxpZWQge0Bjb2RlIEJsb2J9IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIHBhcmFtZXRlciB0byBzZXQ7IHRoZSBmaXJzdCBwYXJhbWV0ZXIncyBpbmRleAorICAgICAqICAgICAgICAgICAgaXMgMS4KKyAgICAgKiBAcGFyYW0gdGhlQmxvYgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBCbG9ifSB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJsb2IoaW50IHBhcmFtZXRlckluZGV4LCBCbG9iIHRoZUJsb2IpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgd2l0aCB0aGUKKyAgICAgKiB2YWx1ZSBvZiBhIHN1cHBsaWVkIGphdmEuaW8uSW5wdXRTdHJlYW0uIERhdGEgaXMgcmVhZCBmcm9tIHRoZQorICAgICAqIElucHV0U3RyZWFtIHVudGlsIGVuZC1vZi1maWxlIGlzIHJlYWNoZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggPSAxLgorICAgICAqIEBwYXJhbSB0aGVJbnB1dFN0cmVhbQorICAgICAqICAgICAgICAgICAgYW4gSW5wdXRTdHJlYW0gY29udGFpbmluZyB0aGUgYmluYXJ5IGRhdGEgdG8gc2V0IGludG8gdGhlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIgdmFsdWUKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJsb2IoaW50IHBhcmFtZXRlckluZGV4LCBJbnB1dFN0cmVhbSB0aGVJbnB1dFN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgd2l0aCB0aGUKKyAgICAgKiB2YWx1ZSBvZiBhIHN1cHBsaWVkIGphdmEuaW8uSW5wdXRTdHJlYW0uIERhdGEgaXMgcmVhZCBmcm9tIHRoZQorICAgICAqIElucHV0U3RyZWFtIHVudGlsIGVuZC1vZi1maWxlIGlzIHJlYWNoZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggPSAxLgorICAgICAqIEBwYXJhbSB0aGVJbnB1dFN0cmVhbQorICAgICAqICAgICAgICAgICAgYW4gSW5wdXRTdHJlYW0gY29udGFpbmluZyB0aGUgYmluYXJ5IGRhdGEgdG8gc2V0IGludG8gdGhlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIgdmFsdWUKKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhIGluIGJ5dGVzCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCbG9iKGludCBwYXJhbWV0ZXJJbmRleCwgSW5wdXRTdHJlYW0gdGhlSW5wdXRTdHJlYW0sCisgICAgICAgICAgICBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB3aXRoIHRoZQorICAgICAqIHZhbHVlIG9mIGEgc3VwcGxpZWQgamF2YS5pby5JbnB1dFN0cmVhbS4gRGF0YSBpcyByZWFkIGZyb20gdGhlCisgICAgICogSW5wdXRTdHJlYW0gdW50aWwgZW5kLW9mLWZpbGUgaXMgcmVhY2hlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZUlucHV0U3RyZWFtCisgICAgICogICAgICAgICAgICBhbiBJbnB1dFN0cmVhbSBjb250YWluaW5nIHRoZSBiaW5hcnkgZGF0YSB0byBzZXQgaW50byB0aGUKKyAgICAgKiAgICAgICAgICAgIHBhcmFtZXRlciB2YWx1ZQorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QmxvYihTdHJpbmcgcGFyYW1ldGVyTmFtZSwgSW5wdXRTdHJlYW0gdGhlSW5wdXRTdHJlYW0pCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIFJvd1NldCBjb21tYW5kIHdpdGggdGhlCisgICAgICogdmFsdWUgb2YgYSBzdXBwbGllZCBqYXZhLmlvLklucHV0U3RyZWFtLiBEYXRhIGlzIHJlYWQgZnJvbSB0aGUKKyAgICAgKiBJbnB1dFN0cmVhbSB1bnRpbCBlbmQtb2YtZmlsZSBpcyByZWFjaGVkLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBuYW1lIGZvciBwYXJhbWV0ZXIKKyAgICAgKiBAcGFyYW0gdGhlSW5wdXRTdHJlYW0KKyAgICAgKiAgICAgICAgICAgIGFuIElucHV0U3RyZWFtIGNvbnRhaW5pbmcgdGhlIGJpbmFyeSBkYXRhIHRvIHNldCBpbnRvIHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyIHZhbHVlCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YSBpbiBieXRlcworICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QmxvYihTdHJpbmcgcGFyYW1ldGVyTmFtZSwgSW5wdXRTdHJlYW0gdGhlSW5wdXRTdHJlYW0sCisgICAgICAgICAgICBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB3aXRoIHRoZQorICAgICAqIHZhbHVlIG9mIGEgc3VwcGxpZWQgamF2YS5zcWwuQmxvYi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZUJsb2IKKyAgICAgKiAgICAgICAgICAgIHRoZSBCbG9iIHZhbHVlIHRvIHNldAorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QmxvYihTdHJpbmcgcGFyYW1ldGVyTmFtZSwgQmxvYiB0aGVCbG9iKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIHtAY29kZSBSb3dTZXR9IGNvbW1hbmQKKyAgICAgKiB0byB0aGUgc3VwcGxpZWQgYm9vbGVhbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0OyB0aGUgZmlyc3QgcGFyYW1ldGVyJ3MgaW5kZXgKKyAgICAgKiAgICAgICAgICAgIGlzIDEuCisgICAgICogQHBhcmFtIHRoZUJvb2xlYW4KKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgYm9vbGVhbn0gdmFsdWUgdG8gd2hpY2ggdGhlIHBhcmFtZXRlciBpcyBzZXQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCb29sZWFuKGludCBwYXJhbWV0ZXJJbmRleCwgYm9vbGVhbiB0aGVCb29sZWFuKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB0byB0aGUKKyAgICAgKiBzdXBwbGllZCBib29sZWFuLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIG5hbWUgZm9yIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSB0aGVCb29sZWFuCisgICAgICogICAgICAgICAgICB0aGUgYm9vbGVhbiB2YWx1ZSB0byBzZXQKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJvb2xlYW4oU3RyaW5nIHBhcmFtZXRlck5hbWUsIGJvb2xlYW4gdGhlQm9vbGVhbikKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUge0Bjb2RlIFJvd1NldH0gY29tbWFuZAorICAgICAqIHRvIHRoZSBzdXBwbGllZCBieXRlIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIHBhcmFtZXRlciB0byBzZXQ7IHRoZSBmaXJzdCBwYXJhbWV0ZXIncyBpbmRleAorICAgICAqICAgICAgICAgICAgaXMgMS4KKyAgICAgKiBAcGFyYW0gdGhlQnl0ZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBieXRlfSB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJ5dGUoaW50IHBhcmFtZXRlckluZGV4LCBieXRlIHRoZUJ5dGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgdG8gdGhlCisgICAgICogc3VwcGxpZWQgYnl0ZSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICBuYW1lIGZvciBwYXJhbWV0ZXIKKyAgICAgKiBAcGFyYW0gdGhlQnl0ZQorICAgICAqICAgICAgICAgICAgdGhlIGJ5dGUgdmFsdWUgdG8gc2V0CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCeXRlKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBieXRlIHRoZUJ5dGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUge0Bjb2RlIFJvd1NldH0gY29tbWFuZAorICAgICAqIHRvIHRoZSBzdXBwbGllZCBieXRlIGFycmF5IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIHBhcmFtZXRlciB0byBzZXQ7IHRoZSBmaXJzdCBwYXJhbWV0ZXIncyBpbmRleAorICAgICAqICAgICAgICAgICAgaXMgMS4KKyAgICAgKiBAcGFyYW0gdGhlQnl0ZUFycmF5CisgICAgICogICAgICAgICAgICB0aGUge0Bjb2RlIEFycmF5fSBvZiB7QGNvZGUgYnl0ZXN9IHRvIHdoaWNoIHRoZSBwYXJhbWV0ZXIgaXMgc2V0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Qnl0ZXMoaW50IHBhcmFtZXRlckluZGV4LCBieXRlW10gdGhlQnl0ZUFycmF5KQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB0byB0aGUKKyAgICAgKiBzdXBwbGllZCBieXRlIGFycmF5IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIG5hbWUgZm9yIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSB0aGVCeXRlQXJyYXkKKyAgICAgKiAgICAgICAgICAgIHRoZSBhcnJheSBvZiBieXRlcyB0byBzZXQgaW50byB0aGUgcGFyYW1ldGVyLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Qnl0ZXMoU3RyaW5nIHBhcmFtZXRlck5hbWUsIGJ5dGVbXSB0aGVCeXRlQXJyYXkpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIHtAY29kZSBSb3dTZXR9IGNvbW1hbmQKKyAgICAgKiB0byB0aGUgc2VxdWVuY2Ugb2YgVW5pY29kZSBjaGFyYWN0ZXJzIGNhcnJpZWQgYnkgdGhlIHN1cHBsaWVkIHtAY29kZQorICAgICAqIGphdmEuaW8uUmVhZGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0OyB0aGUgZmlyc3QgcGFyYW1ldGVyJ3MgaW5kZXgKKyAgICAgKiAgICAgICAgICAgIGlzIDEuCisgICAgICogQHBhcmFtIHRoZVJlYWRlcgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBSZWFkZXJ9IHdoaWNoIGNvbnRhaW5zIHRoZSBVbmljb2RlIGRhdGEgdG8gc2V0IHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgaW4gdGhlIHtAY29kZSBSZWFkZXJ9IGluIGNoYXJhY3RlcnMuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDaGFyYWN0ZXJTdHJlYW0oaW50IHBhcmFtZXRlckluZGV4LCBSZWFkZXIgdGhlUmVhZGVyLAorICAgICAgICAgICAgaW50IGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB0byB0aGUKKyAgICAgKiBzZXF1ZW5jZSBvZiBVbmljb2RlIGNoYXJhY3RlcnMgY2FycmllZCBieSB0aGUgc3VwcGxpZWQgamF2YS5pby5SZWFkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggPSAxLgorICAgICAqIEBwYXJhbSB0aGVSZWFkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZWFkZXIgd2hpY2ggY29udGFpbnMgdGhlIFVuaWNvZGUgZGF0YSB0byBzZXQgaW50byB0aGUKKyAgICAgKiAgICAgICAgICAgIHBhcmFtZXRlcgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q2hhcmFjdGVyU3RyZWFtKGludCBwYXJhbWV0ZXJJbmRleCwgUmVhZGVyIHRoZVJlYWRlcikKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgdG8gdGhlCisgICAgICogc2VxdWVuY2Ugb2YgVW5pY29kZSBjaGFyYWN0ZXJzIGNhcnJpZWQgYnkgdGhlIHN1cHBsaWVkIGphdmEuaW8uUmVhZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIG5hbWUgZm9yIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSB0aGVSZWFkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZWFkZXIgd2hpY2ggY29udGFpbnMgdGhlIFVuaWNvZGUgZGF0YSB0byBzZXQgaW50byB0aGUKKyAgICAgKiAgICAgICAgICAgIHBhcmFtZXRlcgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q2hhcmFjdGVyU3RyZWFtKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBSZWFkZXIgdGhlUmVhZGVyKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB0byB0aGUKKyAgICAgKiBzZXF1ZW5jZSBvZiBVbmljb2RlIGNoYXJhY3RlcnMgY2FycmllZCBieSB0aGUgc3VwcGxpZWQgamF2YS5pby5SZWFkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZVJlYWRlcgorICAgICAqICAgICAgICAgICAgdGhlIFJlYWRlciB3aGljaCBjb250YWlucyB0aGUgVW5pY29kZSBkYXRhIHRvIHNldCBpbnRvIHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YSBpbiB0aGUgUmVhZGVyIGluIGNoYXJhY3RlcnMKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENoYXJhY3RlclN0cmVhbShTdHJpbmcgcGFyYW1ldGVyTmFtZSwgUmVhZGVyIHRoZVJlYWRlciwKKyAgICAgICAgICAgIGludCBsZW5ndGgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUge0Bjb2RlIFJvd1NldH0gY29tbWFuZAorICAgICAqIHdpdGggdGhlIHZhbHVlIG9mIGEgc3VwcGxpZWQge0Bjb2RlIGphdmEuc3FsLkNsb2J9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIHBhcmFtZXRlciB0byBzZXQ7IHRoZSBmaXJzdCBwYXJhbWV0ZXIncyBpbmRleAorICAgICAqICAgICAgICAgICAgaXMgMS4KKyAgICAgKiBAcGFyYW0gdGhlQ2xvYgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBDbG9ifSB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENsb2IoaW50IHBhcmFtZXRlckluZGV4LCBDbG9iIHRoZUNsb2IpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgd2l0aCB0aGUKKyAgICAgKiB2YWx1ZSBvZiBhIHN1cHBsaWVkIGphdmEuaW8uUmVhZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICBpbmRleCBvZiB0aGUgcGFyYW1ldGVyIHRvIHNldCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4ID0gMS4KKyAgICAgKiBAcGFyYW0gdGhlUmVhZGVyCisgICAgICogICAgICAgICAgICB0aGUgUmVhZGVyIHdoaWNoIGNvbnRhaW5zIHRoZSBVbmljb2RlIGRhdGEgdG8gc2V0IGludG8gdGhlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENsb2IoaW50IHBhcmFtZXRlckluZGV4LCBSZWFkZXIgdGhlUmVhZGVyKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB3aXRoIHRoZQorICAgICAqIHZhbHVlIG9mIGEgc3VwcGxpZWQgamF2YS5pby5SZWFkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggPSAxLgorICAgICAqIEBwYXJhbSB0aGVSZWFkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZWFkZXIgd2hpY2ggY29udGFpbnMgdGhlIFVuaWNvZGUgZGF0YSB0byBzZXQgaW50byB0aGUKKyAgICAgKiAgICAgICAgICAgIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgaW4gdGhlIFJlYWRlciBpbiBjaGFyYWN0ZXJzCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDbG9iKGludCBwYXJhbWV0ZXJJbmRleCwgUmVhZGVyIHRoZVJlYWRlciwgbG9uZyBsZW5ndGgpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIFJvd1NldCBjb21tYW5kIHdpdGggdGhlCisgICAgICogdmFsdWUgb2YgYSBzdXBwbGllZCBqYXZhLnNxbC5DbG9iLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIG5hbWUgZm9yIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSB0aGVDbG9iCisgICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWMgQ2xvYiBvYmplY3QKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENsb2IoU3RyaW5nIHBhcmFtZXRlck5hbWUsIENsb2IgdGhlQ2xvYikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB3aXRoIHRoZQorICAgICAqIHZhbHVlIG9mIGEgc3VwcGxpZWQgamF2YS5pby5SZWFkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZVJlYWRlcgorICAgICAqICAgICAgICAgICAgdGhlIFJlYWRlciB3aGljaCBjb250YWlucyB0aGUgVW5pY29kZSBkYXRhIHRvIHNldCBpbnRvIHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDbG9iKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBSZWFkZXIgdGhlUmVhZGVyKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB3aXRoIHRoZQorICAgICAqIHZhbHVlIG9mIGEgc3VwcGxpZWQgamF2YS5pby5SZWFkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZVJlYWRlcgorICAgICAqICAgICAgICAgICAgdGhlIFJlYWRlciB3aGljaCBjb250YWlucyB0aGUgVW5pY29kZSBkYXRhIHRvIHNldCBpbnRvIHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YSBpbiB0aGUgUmVhZGVyIGluIGNoYXJhY3RlcnMKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENsb2IoU3RyaW5nIHBhcmFtZXRlck5hbWUsIFJlYWRlciB0aGVSZWFkZXIsIGxvbmcgbGVuZ3RoKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIENvbW1hbmQgcHJvcGVydHkgZm9yIHRoaXMge0Bjb2RlIFJvd1NldH0gLSB0aGUgY29tbWFuZCBpcyBhbiBTUUwKKyAgICAgKiBxdWVyeSB3aGljaCBydW5zIHdoZW4gdGhlIHtAY29kZSBleGVjdXRlfSBtZXRob2QgaXMgaW52b2tlZC4gVGhpcworICAgICAqIHByb3BlcnR5IGlzIG9wdGlvbmFsIGZvciBkYXRhYmFzZXMgdGhhdCBkbyBub3Qgc3VwcG9ydCBjb21tYW5kcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBTUUwgcXVlcnkuIENhbiBiZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb21tYW5kKFN0cmluZyBjbWQpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjb25jdXJyZW5jeSBwcm9wZXJ0eSBvZiB0aGlzIHtAY29kZSBSb3dTZXR9LiBUaGUgZGVmYXVsdCB2YWx1ZQorICAgICAqIGlzIHtAY29kZSBSZXN1bHRTZXQuQ09OQ1VSX1JFQURfT05MWX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29uY3VycmVuY3kKKyAgICAgKiAgICAgICAgICAgIHRoZSBjb25jdXJyZW5jeSB2YWx1ZS4gT25lIG9mOgorICAgICAqICAgICAgICAgICAgPHVsPgorICAgICAqICAgICAgICAgICAgPGxpPntAY29kZSBSZXN1bHRTZXQuQ09OQ1VSX1JFQURfT05MWX08L2xpPgorICAgICAqICAgICAgICAgICAgPGxpPntAY29kZSBSZXN1bHRTZXQuQ09OQ1VSX1VQREFUQUJMRX08L2xpPgorICAgICAqICAgICAgICAgICAgPC91bD4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqIEBzZWUgamF2YS5zcWwuUmVzdWx0U2V0CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q29uY3VycmVuY3koaW50IGNvbmN1cnJlbmN5KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGF0YWJhc2UgbmFtZSBwcm9wZXJ0eSBmb3IgdGhlIHtAY29kZSBSb3dTZXR9LgorICAgICAqIDxwPgorICAgICAqIFRoZSBkYXRhYmFzZSBuYW1lIGNhbiBiZSB1c2VkIHRvIGZpbmQgYSB7QGxpbmsgRGF0YVNvdXJjZX0gd2hpY2ggaGFzIGJlZW4KKyAgICAgKiByZWdpc3RlcmVkIHdpdGggYSBuYW1pbmcgc2VydmljZSAtIHRoZSB7QGxpbmsgRGF0YVNvdXJjZX0gY2FuIHRoZW4gYmUKKyAgICAgKiB1c2VkIHRvIGNyZWF0ZSBhIGNvbm5lY3Rpb24gdG8gdGhlIGRhdGFiYXNlLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBkYXRhYmFzZSBuYW1lLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGF0YVNvdXJjZU5hbWUoU3RyaW5nIG5hbWUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUge0Bjb2RlIFJvd1NldH0gY29tbWFuZAorICAgICAqIHdpdGggdGhlIHZhbHVlIG9mIGEgc3VwcGxpZWQge0Bjb2RlIGphdmEuc3FsLkRhdGV9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIHBhcmFtZXRlciB0byBzZXQ7IHRoZSBmaXJzdCBwYXJhbWV0ZXIncyBpbmRleAorICAgICAqICAgICAgICAgICAgaXMgMS4KKyAgICAgKiBAcGFyYW0gdGhlRGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIGRhdGUgdmFsdWUgdG8gd2hpY2ggdGhlIHBhcmFtZXRlciBpcyBzZXQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREYXRlKGludCBwYXJhbWV0ZXJJbmRleCwgRGF0ZSB0aGVEYXRlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIHtAY29kZSBSb3dTZXR9IGNvbW1hbmQKKyAgICAgKiB3aXRoIHRoZSB2YWx1ZSBvZiBhIHN1cHBsaWVkIHtAY29kZSBqYXZhLnNxbC5EYXRlfSwgd2hlcmUgdGhlIGNvbnZlcnNpb24KKyAgICAgKiBvZiB0aGUgZGF0ZSB0byBhbiBTUUwge0Bjb2RlIERBVEV9IHZhbHVlIGlzIGNhbGN1bGF0ZWQgdXNpbmcgYSBzdXBwbGllZAorICAgICAqIHtAY29kZSBDYWxlbmRhcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgcGFyYW1ldGVyIHRvIHNldDsgdGhlIGZpcnN0IHBhcmFtZXRlcidzIGluZGV4CisgICAgICogICAgICAgICAgICBpcyAxLgorICAgICAqIEBwYXJhbSB0aGVEYXRlCisgICAgICogICAgICAgICAgICB0aGUgZGF0ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGlzIHNldC4KKyAgICAgKiBAcGFyYW0gdGhlQ2FsZW5kYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9IHRvIHVzZSBpbiBjb252ZXJ0aW5nIHRoZSBEYXRlIHRvIGFuIFNRTAorICAgICAqICAgICAgICAgICAge0Bjb2RlIERBVEV9IHZhbHVlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGF0ZShpbnQgcGFyYW1ldGVySW5kZXgsIERhdGUgdGhlRGF0ZSwgQ2FsZW5kYXIgdGhlQ2FsZW5kYXIpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIFJvd1NldCBjb21tYW5kIHdpdGggdGhlCisgICAgICogdmFsdWUgb2YgYSBzdXBwbGllZCBqYXZhLnNxbC5EYXRlLCB3aGVyZSB0aGUgY29udmVyc2lvbiBvZiB0aGUgRGF0ZSB0byBhbgorICAgICAqIFNRTCBEQVRFIHZhbHVlIGlzIGNhbGN1bGF0ZWQgdXNpbmcgYSBzdXBwbGllZCBDYWxlbmRhci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICBuYW1lIGZvciBwYXJhbWV0ZXIKKyAgICAgKiBAcGFyYW0gdGhlRGF0ZQorICAgICAqICAgICAgICAgICAgdGhlIERhdGUgdG8gdXNlCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREYXRlKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBEYXRlIHRoZURhdGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgd2l0aCB0aGUKKyAgICAgKiB2YWx1ZSBvZiBhIHN1cHBsaWVkIGphdmEuc3FsLkRhdGUsIHdoZXJlIHRoZSBjb252ZXJzaW9uIG9mIHRoZSBEYXRlIHRvIGFuCisgICAgICogU1FMIERBVEUgdmFsdWUgaXMgY2FsY3VsYXRlZCB1c2luZyBhIHN1cHBsaWVkIENhbGVuZGFyLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIG5hbWUgZm9yIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSB0aGVEYXRlCisgICAgICogICAgICAgICAgICB0aGUgRGF0ZSB0byB1c2UKKyAgICAgKiBAcGFyYW0gdGhlQ2FsZW5kYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBDYWxlbmRhciB0byB1c2UgaW4gY29udmVydGluZyB0aGUgRGF0ZSB0byBhbiBTUUwgREFURQorICAgICAqICAgICAgICAgICAgdmFsdWUKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERhdGUoU3RyaW5nIHBhcmFtZXRlck5hbWUsIERhdGUgdGhlRGF0ZSwgQ2FsZW5kYXIgdGhlQ2FsZW5kYXIpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIHtAY29kZSBSb3dTZXR9IGNvbW1hbmQKKyAgICAgKiB3aXRoIHRoZSBzdXBwbGllZCB7QGNvZGUgZG91YmxlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0OyB0aGUgZmlyc3QgcGFyYW1ldGVyJ3MgaW5kZXgKKyAgICAgKiAgICAgICAgICAgIGlzIDEuCisgICAgICogQHBhcmFtIHRoZURvdWJsZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBkb3VibGV9IHZhbHVlIHRvIHdoaWNoIHRoZSBwYXJhbWV0ZXIgaXMgc2V0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RG91YmxlKGludCBwYXJhbWV0ZXJJbmRleCwgZG91YmxlIHRoZURvdWJsZSkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgd2l0aCB0aGUKKyAgICAgKiBzdXBwbGllZCBkb3VibGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZURvdWJsZQorICAgICAqICAgICAgICAgICAgdGhlIGRvdWJsZSB2YWx1ZSB0byBzZXQKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERvdWJsZShTdHJpbmcgcGFyYW1ldGVyTmFtZSwgZG91YmxlIHRoZURvdWJsZSkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBlc2NhcGUgcHJvY2Vzc2luZyBzdGF0dXMgZm9yIHRoaXMge0Bjb2RlIFJvd1NldH0uIElmIGVzY2FwZQorICAgICAqIHByb2Nlc3NpbmcgaXMgb24sIHRoZSBkcml2ZXIgcGVyZm9ybXMgYSBzdWJzdGl0dXRpb24gb2YgdGhlIGVzY2FwZSBzeW50YXgKKyAgICAgKiB3aXRoIHRoZSBhcHBsaWNhYmxlIGNvZGUgYmVmb3JlIHNlbmRpbmcgYW4gU1FMIGNvbW1hbmQgdG8gdGhlIGRhdGFiYXNlLgorICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlIGZvciBlc2NhcGUgcHJvY2Vzc2luZyBpcyB7QGNvZGUgdHJ1ZX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW5hYmxlCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gdG8gZW5hYmxlIGVzY2FwZSBwcm9jZXNzaW5nLCB7QGNvZGUgZmFsc2V9IHRvCisgICAgICogICAgICAgICAgICB0dXJuIGl0IG9mZi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEVzY2FwZVByb2Nlc3NpbmcoYm9vbGVhbiBlbmFibGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUge0Bjb2RlIFJvd1NldH0gY29tbWFuZAorICAgICAqIHdpdGggdGhlIHN1cHBsaWVkIHtAY29kZSBmbG9hdH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgcGFyYW1ldGVyIHRvIHNldDsgdGhlIGZpcnN0IHBhcmFtZXRlcidzIGluZGV4CisgICAgICogICAgICAgICAgICBpcyAxLgorICAgICAqIEBwYXJhbSB0aGVGbG9hdAorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBmbG9hdH0gdmFsdWUgdG8gd2hpY2ggdGhlIHBhcmFtZXRlciBpcyBzZXQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGbG9hdChpbnQgcGFyYW1ldGVySW5kZXgsIGZsb2F0IHRoZUZsb2F0KQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB3aXRoIHRoZQorICAgICAqIHN1cHBsaWVkIGZsb2F0LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIG5hbWUgZm9yIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSB0aGVGbG9hdAorICAgICAqICAgICAgICAgICAgdGhlIGZsb2F0IHZhbHVlIHRvIHNldAorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RmxvYXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIGZsb2F0IHRoZUZsb2F0KQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSB7QGNvZGUgUm93U2V0fSBjb21tYW5kCisgICAgICogd2l0aCB0aGUgc3VwcGxpZWQge0Bjb2RlIGludGVnZXJ9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIHBhcmFtZXRlciB0byBzZXQ7IHRoZSBmaXJzdCBwYXJhbWV0ZXIncyBpbmRleAorICAgICAqICAgICAgICAgICAgaXMgMS4KKyAgICAgKiBAcGFyYW0gdGhlSW50ZWdlcgorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBpbnRlZ2VyfSB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEludChpbnQgcGFyYW1ldGVySW5kZXgsIGludCB0aGVJbnRlZ2VyKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIFJvd1NldCBjb21tYW5kIHdpdGggdGhlCisgICAgICogc3VwcGxpZWQgaW50ZWdlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICBuYW1lIGZvciBwYXJhbWV0ZXIKKyAgICAgKiBAcGFyYW0gdGhlSW50ZWdlcgorICAgICAqICAgICAgICAgICAgdGhlIGludGVnZXIgdmFsdWUgdG8gc2V0CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRJbnQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIGludCB0aGVJbnRlZ2VyKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSB7QGNvZGUgUm93U2V0fSBjb21tYW5kCisgICAgICogd2l0aCB0aGUgc3VwcGxpZWQge0Bjb2RlIGxvbmd9LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIHBhcmFtZXRlciB0byBzZXQ7IHRoZSBmaXJzdCBwYXJhbWV0ZXIncyBpbmRleAorICAgICAqICAgICAgICAgICAgaXMgMS4KKyAgICAgKiBAcGFyYW0gdGhlTG9uZworICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBsb25nfSB2YWx1ZSB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExvbmcoaW50IHBhcmFtZXRlckluZGV4LCBsb25nIHRoZUxvbmcpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgd2l0aCB0aGUKKyAgICAgKiBzdXBwbGllZCBsb25nLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIG5hbWUgZm9yIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSB0aGVMb25nCisgICAgICogICAgICAgICAgICB0aGUgbG9uZyB2YWx1ZSB0byBzZXQKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExvbmcoU3RyaW5nIHBhcmFtZXRlck5hbWUsIGxvbmcgdGhlTG9uZykgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHdoaWNoIGNhbiBiZSByZXR1cm5lZCBmb3IgYSBjb2x1bW4gdmFsdWUKKyAgICAgKiB3aGVyZSB0aGUgY29sdW1uIHR5cGUgaXMgb25lIG9mIHtAY29kZSBCSU5BUll9LCB7QGNvZGUgVkFSQklOQVJZfSwKKyAgICAgKiB7QGNvZGUgTE9OR1ZBUkJJTkFSWUJJTkFSWX0sIHtAY29kZSBDSEFSfSwge0Bjb2RlIFZBUkNIQVJ9LCBvciB7QGNvZGUKKyAgICAgKiBMT05HVkFSQ0hBUn0uIERhdGEgd2hpY2ggZXhjZWVkcyB0aGlzIGxpbWl0IGlzIHNpbGVudGx5IGRpc2NhcmRlZC4gRm9yCisgICAgICogcG9ydGFiaWxpdHksIGEgdmFsdWUgZ3JlYXRlciB0aGFuIDI1NiBpcyByZWNvbW1lbmRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtYXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBtYXhpbXVtIHNpemUgb2YgdGhlIHJldHVybmVkIGNvbHVtbiB2YWx1ZSBpbiBieXRlcy4gMAorICAgICAqICAgICAgICAgICAgaW1wbGllcyBubyBzaXplIGxpbWl0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TWF4RmllbGRTaXplKGludCBtYXgpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBtYXhpbXVtIG51bWJlciBvZiByb3dzIHdoaWNoIGNhbiBiZSBoZWxkIGJ5IHRoZSB7QGNvZGUgUm93U2V0fS4KKyAgICAgKiBBbnkgYWRkaXRpb25hbCByb3dzIGFyZSBzaWxlbnRseSBkaXNjYXJkZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWF4CisgICAgICogICAgICAgICAgICB0aGUgbWF4aW11bSBudW1iZXIgb2Ygcm93cyB3aGljaCBjYW4gYmUgaGVsZCBpbiB0aGUge0Bjb2RlCisgICAgICogICAgICAgICAgICBSb3dTZXR9LiAwIG1lYW5zIG5vIGxpbWl0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TWF4Um93cyhpbnQgbWF4KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIFJvd1NldCBjb21tYW5kIHdpdGggdGhlCisgICAgICogdmFsdWUgb2YgYSBzdXBwbGllZCBqYXZhLmlvLlJlYWRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgaW5kZXggb2YgdGhlIHBhcmFtZXRlciB0byBzZXQsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCA9IDEuCisgICAgICogQHBhcmFtIHRoZVJlYWRlcgorICAgICAqICAgICAgICAgICAgdGhlIFJlYWRlciB3aGljaCBjb250YWlucyB0aGUgVW5pY29kZSBkYXRhIHRvIHNldCBpbnRvIHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROQ2hhcmFjdGVyU3RyZWFtKGludCBwYXJhbWV0ZXJJbmRleCwgUmVhZGVyIHRoZVJlYWRlcikKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgd2l0aCB0aGUKKyAgICAgKiB2YWx1ZSBvZiBhIHN1cHBsaWVkIGphdmEuaW8uUmVhZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICBpbmRleCBvZiB0aGUgcGFyYW1ldGVyIHRvIHNldCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4ID0gMS4KKyAgICAgKiBAcGFyYW0gdGhlUmVhZGVyCisgICAgICogICAgICAgICAgICB0aGUgUmVhZGVyIHdoaWNoIGNvbnRhaW5zIHRoZSBVbmljb2RlIGRhdGEgdG8gc2V0IGludG8gdGhlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIKKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhIGluIHRoZSBSZWFkZXIgaW4gY2hhcmFjdGVycworICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TkNoYXJhY3RlclN0cmVhbShpbnQgcGFyYW1ldGVySW5kZXgsIFJlYWRlciB0aGVSZWFkZXIsCisgICAgICAgICAgICBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB3aXRoIHRoZQorICAgICAqIHZhbHVlIG9mIGEgc3VwcGxpZWQgamF2YS5pby5SZWFkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZVJlYWRlcgorICAgICAqICAgICAgICAgICAgdGhlIFJlYWRlciB3aGljaCBjb250YWlucyB0aGUgVW5pY29kZSBkYXRhIHRvIHNldCBpbnRvIHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROQ2hhcmFjdGVyU3RyZWFtKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBSZWFkZXIgdGhlUmVhZGVyKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB3aXRoIHRoZQorICAgICAqIHZhbHVlIG9mIGEgc3VwcGxpZWQgamF2YS5pby5SZWFkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZVJlYWRlcgorICAgICAqICAgICAgICAgICAgdGhlIFJlYWRlciB3aGljaCBjb250YWlucyB0aGUgVW5pY29kZSBkYXRhIHRvIHNldCBpbnRvIHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqICAgICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YSBpbiB0aGUgUmVhZGVyIGluIGNoYXJhY3RlcnMKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5DaGFyYWN0ZXJTdHJlYW0oU3RyaW5nIHBhcmFtZXRlck5hbWUsIFJlYWRlciB0aGVSZWFkZXIsCisgICAgICAgICAgICBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB3aXRoIHRoZQorICAgICAqIHZhbHVlIG9mIGEgc3VwcGxpZWQgamF2YS5zcWwuTkNsb2IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggPSAxLgorICAgICAqIEBwYXJhbSB0aGVOQ2xvYgorICAgICAqICAgICAgICAgICAgdGhlIE5DbG9iIHZhbHVlIHRvIHNldAorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TkNsb2IoaW50IHBhcmFtZXRlckluZGV4LCBOQ2xvYiB0aGVOQ2xvYikKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgd2l0aCB0aGUKKyAgICAgKiB2YWx1ZSBvZiBhIHN1cHBsaWVkIGphdmEuaW8uUmVhZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICBpbmRleCBvZiB0aGUgcGFyYW1ldGVyIHRvIHNldCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4ID0gMS4KKyAgICAgKiBAcGFyYW0gdGhlUmVhZGVyCisgICAgICogICAgICAgICAgICB0aGUgUmVhZGVyIHdoaWNoIGNvbnRhaW5zIHRoZSBVbmljb2RlIGRhdGEgdG8gc2V0IGludG8gdGhlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5DbG9iKGludCBwYXJhbWV0ZXJJbmRleCwgUmVhZGVyIHRoZVJlYWRlcikKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgd2l0aCB0aGUKKyAgICAgKiB2YWx1ZSBvZiBhIHN1cHBsaWVkIGphdmEuaW8uUmVhZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICBpbmRleCBvZiB0aGUgcGFyYW1ldGVyIHRvIHNldCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4ID0gMS4KKyAgICAgKiBAcGFyYW0gdGhlUmVhZGVyCisgICAgICogICAgICAgICAgICB0aGUgUmVhZGVyIHdoaWNoIGNvbnRhaW5zIHRoZSBVbmljb2RlIGRhdGEgdG8gc2V0IGludG8gdGhlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIKKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogICAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhIGluIHRoZSBSZWFkZXIgaW4gY2hhcmFjdGVycworICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TkNsb2IoaW50IHBhcmFtZXRlckluZGV4LCBSZWFkZXIgdGhlUmVhZGVyLCBsb25nIGxlbmd0aCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgd2l0aCB0aGUKKyAgICAgKiB2YWx1ZSBvZiBhIHN1cHBsaWVkIGphdmEuc3FsLk5DbG9iLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIG5hbWUgZm9yIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSB0aGVOQ2xvYgorICAgICAqICAgICAgICAgICAgdGhlIE5DbG9iIHZhbHVlIHRvIHNldAorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TkNsb2IoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE5DbG9iIHRoZU5DbG9iKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB3aXRoIHRoZQorICAgICAqIHZhbHVlIG9mIGEgc3VwcGxpZWQgamF2YS5pby5SZWFkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZVJlYWRlcgorICAgICAqICAgICAgICAgICAgdGhlIFJlYWRlciB3aGljaCBjb250YWlucyB0aGUgVW5pY29kZSBkYXRhIHRvIHNldCBpbnRvIHRoZQorICAgICAqICAgICAgICAgICAgcGFyYW1ldGVyCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROQ2xvYihTdHJpbmcgcGFyYW1ldGVyTmFtZSwgUmVhZGVyIHRoZVJlYWRlcikKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgd2l0aCB0aGUKKyAgICAgKiB2YWx1ZSBvZiBhIHN1cHBsaWVkIGphdmEuaW8uUmVhZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIG5hbWUgZm9yIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSB0aGVSZWFkZXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBSZWFkZXIgd2hpY2ggY29udGFpbnMgdGhlIFVuaWNvZGUgZGF0YSB0byBzZXQgaW50byB0aGUKKyAgICAgKiAgICAgICAgICAgIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiAgICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgaW4gdGhlIFJlYWRlciBpbiBjaGFyYWN0ZXJzCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROQ2xvYihTdHJpbmcgcGFyYW1ldGVyTmFtZSwgUmVhZGVyIHRoZVJlYWRlciwgbG9uZyBsZW5ndGgpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIFJvd1NldCBjb21tYW5kIHRvIHRoZQorICAgICAqIHN1cHBsaWVkIE5TdHJpbmcKKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgaW5kZXggb2YgdGhlIHBhcmFtZXRlciB0byBzZXQsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCA9IDEuCisgICAgICogQHBhcmFtIHRoZU5TdHJpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSBOU3RyaW5nIHZhbHVlIHRvIHNldAorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TlN0cmluZyhpbnQgcGFyYW1ldGVySW5kZXgsIFN0cmluZyB0aGVOU3RyaW5nKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB0byB0aGUKKyAgICAgKiBzdXBwbGllZCBOU3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIG5hbWUgZm9yIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSB0aGVOU3RyaW5nCisgICAgICogICAgICAgICAgICB0aGUgTlN0cmluZyB2YWx1ZSB0byBzZXQKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5TdHJpbmcoU3RyaW5nIHBhcmFtZXRlck5hbWUsIFN0cmluZyB0aGVOU3RyaW5nKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSB7QGNvZGUgUm93U2V0fSBjb21tYW5kCisgICAgICogdG8gU1FMIHtAY29kZSBOVUxMfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0OyB0aGUgZmlyc3QgcGFyYW1ldGVyJ3MgaW5kZXgKKyAgICAgKiAgICAgICAgICAgIGlzIDEuCisgICAgICogQHBhcmFtIHNxbFR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIG9mIHRoZSBwYXJhbWV0ZXIsIGFzIGRlZmluZWQgYnkge0Bjb2RlCisgICAgICogICAgICAgICAgICBqYXZhLnNxbC5UeXBlc30uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROdWxsKGludCBwYXJhbWV0ZXJJbmRleCwgaW50IHNxbFR5cGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUge0Bjb2RlIFJvd1NldH0gY29tbWFuZAorICAgICAqIHRvIFNRTCB7QGNvZGUgTlVMTH0uIFRoaXMgZm9ybSBvZiB0aGUge0Bjb2RlIHNldE51bGx9IG1ldGhvZCBzaG91bGQgYmUKKyAgICAgKiB1c2VkIGZvciBVc2VyIERlZmluZWQgVHlwZXMgYW5kIHtAY29kZSBSRUZ9IHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgcGFyYW1ldGVyIHRvIHNldDsgdGhlIGZpcnN0IHBhcmFtZXRlcidzIGluZGV4CisgICAgICogICAgICAgICAgICBpcyAxLgorICAgICAqIEBwYXJhbSBzcWxUeXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgcGFyYW1ldGVyLCBhcyBkZWZpbmVkIGJ5IHtAY29kZQorICAgICAqICAgICAgICAgICAgamF2YS5zcWwuVHlwZXN9LgorICAgICAqIEBwYXJhbSB0eXBlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIGFuIFNRTCB1c2VyIGRlZmluZWQgdHlwZSBvciB0aGUKKyAgICAgKiAgICAgICAgICAgIG5hbWUgb2YgdGhlIFNRTCBzdHJ1Y3R1cmVkIHR5cGUgcmVmZXJlbmNlZCBieSBhIHtAY29kZSBSRUZ9CisgICAgICogICAgICAgICAgICB0eXBlLiBJZ25vcmVkIGlmIHRoZSBzcWxUeXBlIGlzIG5vdCBhIFVEVCBvciBSRUYgdHlwZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE51bGwoaW50IHBhcmFtZXRlckluZGV4LCBpbnQgc3FsVHlwZSwgU3RyaW5nIHR5cGVOYW1lKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB0byBTUUwKKyAgICAgKiBOVUxMLiBUaGlzIGZvcm0gb2YgdGhlIDxjb2RlPnNldE51bGw8L2NvZGU+IG1ldGhvZCBzaG91bGQgYmUgdXNlZCBmb3IKKyAgICAgKiBVc2VyIERlZmluZWQgVHlwZXMgYW5kIFJFRiBwYXJhbWV0ZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIG5hbWUgZm9yIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSBzcWxUeXBlCisgICAgICogICAgICAgICAgICB0aGUgdHlwZSBvZiB0aGUgcGFyYW1ldGVyLCBhcyBkZWZpbmVkIGJ5IGphdmEuc3FsLlR5cGVzLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TnVsbChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgaW50IHNxbFR5cGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgdG8gU1FMCisgICAgICogTlVMTC4gVGhpcyBmb3JtIG9mIHRoZSA8Y29kZT5zZXROdWxsPC9jb2RlPiBtZXRob2Qgc2hvdWxkIGJlIHVzZWQgZm9yCisgICAgICogVXNlciBEZWZpbmVkIFR5cGVzIGFuZCBSRUYgcGFyYW1ldGVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICBuYW1lIGZvciBwYXJhbWV0ZXIKKyAgICAgKiBAcGFyYW0gc3FsVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIHR5cGUgb2YgdGhlIHBhcmFtZXRlciwgYXMgZGVmaW5lZCBieSBqYXZhLnNxbC5UeXBlcy4KKyAgICAgKiBAcGFyYW0gdHlwZU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiBhbiBTUUwgVXNlciBEZWZpbmVkIFR5cGUgb3IgdGhlCisgICAgICogICAgICAgICAgICBuYW1lIG9mIHRoZSBTUUwgc3RydWN0dXJlZCB0eXBlIHJlZmVyZW5jZWQgYnkgYSBSRUYgdHlwZS4KKyAgICAgKiAgICAgICAgICAgIElnbm9yZWQgaWYgdGhlIHNxbFR5cGUgaXMgbm90IGEgVURUIG9yIFJFRiB0eXBlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TnVsbChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgaW50IHNxbFR5cGUsIFN0cmluZyB0eXBlTmFtZSkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUge0Bjb2RlIFJvd1NldH0gY29tbWFuZAorICAgICAqIHRvIGEgc3VwcGxpZWQgSmF2YSBvYmplY3QuCisgICAgICogPHA+CisgICAgICogVGhlIEpEQkMgc3BlY2lmaWNhdGlvbiBwcm92aWRlcyBhIHN0YW5kYXJkIG1hcHBpbmcgZm9yIEphdmEgb2JqZWN0cyB0bworICAgICAqIFNRTCBkYXRhIHR5cGVzLiBEYXRhYmFzZSBzcGVjaWZpYyB0eXBlcyBjYW4gYmUgbWFwcGVkIGJ5IEpEQkMgZHJpdmVyCisgICAgICogc3BlY2lmaWMgSmF2YSB0eXBlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0OyB0aGUgZmlyc3QgcGFyYW1ldGVyJ3MgaW5kZXgKKyAgICAgKiAgICAgICAgICAgIGlzIDEuCisgICAgICogQHBhcmFtIHRoZU9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIEphdmEgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGRhdGEgdmFsdWUgdG8gd2hpY2ggdGhlCisgICAgICogICAgICAgICAgICBwYXJhbWV0ZXIgaXMgc2V0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0T2JqZWN0KGludCBwYXJhbWV0ZXJJbmRleCwgT2JqZWN0IHRoZU9iamVjdCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUge0Bjb2RlIFJvd1NldH0gY29tbWFuZAorICAgICAqIHRvIGEgc3VwcGxpZWQgSmF2YSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgcGFyYW1ldGVyIHRvIHNldDsgdGhlIGZpcnN0IHBhcmFtZXRlcidzIGluZGV4CisgICAgICogICAgICAgICAgICBpcyAxLgorICAgICAqIEBwYXJhbSB0aGVPYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBKYXZhIG9iamVjdCBjb250YWluaW5nIHRoZSBkYXRhIHZhbHVlLgorICAgICAqIEBwYXJhbSB0YXJnZXRTcWxUeXBlCisgICAgICogICAgICAgICAgICB0aGUgU1FMIHR5cGUgdG8gc2VuZCB0byB0aGUgZGF0YWJhc2UsIGFzIGRlZmluZWQgaW4ge0Bjb2RlCisgICAgICogICAgICAgICAgICBqYXZhLnNxbC5UeXBlc30uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRPYmplY3QoaW50IHBhcmFtZXRlckluZGV4LCBPYmplY3QgdGhlT2JqZWN0LAorICAgICAgICAgICAgaW50IHRhcmdldFNxbFR5cGUpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUge0Bjb2RlIFJvd1NldH0gY29tbWFuZAorICAgICAqIHRvIGEgc3VwcGxpZWQgSmF2YSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgcGFyYW1ldGVyIHRvIHNldDsgdGhlIGZpcnN0IHBhcmFtZXRlcidzIGluZGV4CisgICAgICogICAgICAgICAgICBpcyAxLgorICAgICAqIEBwYXJhbSB0aGVPYmplY3QKKyAgICAgKiAgICAgICAgICAgIHRoZSBKYXZhIG9iamVjdCBjb250YWluaW5nIHRoZSBkYXRhIHZhbHVlLgorICAgICAqIEBwYXJhbSB0YXJnZXRTcWxUeXBlCisgICAgICogICAgICAgICAgICB0aGUgU1FMIHR5cGUgdG8gc2VuZCB0byB0aGUgZGF0YWJhc2UsIGFzIGRlZmluZWQgaW4ge0Bjb2RlCisgICAgICogICAgICAgICAgICBqYXZhLnNxbC5UeXBlc30uCisgICAgICogQHBhcmFtIHNjYWxlCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGRpZ2l0cyBhZnRlciB0aGUgZGVjaW1hbCBwb2ludCwgZm9yIHtAY29kZQorICAgICAqICAgICAgICAgICAgamF2YS5zcWwuVHlwZXMuREVDSU1BTH0gYW5kIHtAY29kZSBqYXZhLnNxbC5UeXBlcy5OVU1FUklDfQorICAgICAqICAgICAgICAgICAgdHlwZXMuIElnbm9yZWQgZm9yIGFsbCBvdGhlciB0eXBlcy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE9iamVjdChpbnQgcGFyYW1ldGVySW5kZXgsIE9iamVjdCB0aGVPYmplY3QsCisgICAgICAgICAgICBpbnQgdGFyZ2V0U3FsVHlwZSwgaW50IHNjYWxlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB0byBhCisgICAgICogc3VwcGxpZWQgSmF2YSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZU9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIEphdmEgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGRhdGEgdmFsdWUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRPYmplY3QoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB0aGVPYmplY3QpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIFJvd1NldCBjb21tYW5kIHRvIGEKKyAgICAgKiBzdXBwbGllZCBKYXZhIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICBuYW1lIGZvciBwYXJhbWV0ZXIKKyAgICAgKiBAcGFyYW0gdGhlT2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgSmF2YSBvYmplY3QgY29udGFpbmluZyB0aGUgZGF0YSB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gdGFyZ2V0U3FsVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIFNRTCB0eXBlIHRvIHNlbmQgdG8gdGhlIGRhdGFiYXNlLCBhcyBkZWZpbmVkIGluCisgICAgICogICAgICAgICAgICBqYXZhLnNxbC5UeXBlcy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE9iamVjdChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHRoZU9iamVjdCwKKyAgICAgICAgICAgIGludCB0YXJnZXRTcWxUeXBlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIFJvd1NldCBjb21tYW5kIHRvIGEKKyAgICAgKiBzdXBwbGllZCBKYXZhIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICBuYW1lIGZvciBwYXJhbWV0ZXIKKyAgICAgKiBAcGFyYW0gdGhlT2JqZWN0CisgICAgICogICAgICAgICAgICB0aGUgSmF2YSBvYmplY3QgY29udGFpbmluZyB0aGUgZGF0YSB2YWx1ZS4KKyAgICAgKiBAcGFyYW0gdGFyZ2V0U3FsVHlwZQorICAgICAqICAgICAgICAgICAgdGhlIFNRTCB0eXBlIHRvIHNlbmQgdG8gdGhlIGRhdGFiYXNlLCBhcyBkZWZpbmVkIGluCisgICAgICogICAgICAgICAgICBqYXZhLnNxbC5UeXBlcy4KKyAgICAgKiBAcGFyYW0gc2NhbGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgZGlnaXRzIGFmdGVyIHRoZSBkZWNpbWFsIHBvaW50LCBmb3IKKyAgICAgKiAgICAgICAgICAgIGphdmEuc3FsLlR5cGVzLkRFQ0lNQUwgYW5kIGphdmEuc3FsLlR5cGVzLk5VTUVSSUMgdHlwZXMuCisgICAgICogICAgICAgICAgICBJZ25vcmVkIGZvciBhbGwgb3RoZXIgdHlwZXMuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRPYmplY3QoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB0aGVPYmplY3QsCisgICAgICAgICAgICBpbnQgdGFyZ2V0U3FsVHlwZSwgaW50IHNjYWxlKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGF0YWJhc2UgUGFzc3dvcmQgZm9yIHRoaXMge0Bjb2RlIFJvd1NldH0uIFRoaXMgcHJvcGVydHkgaXMgdXNlZAorICAgICAqIHdoZW4gYSBjb25uZWN0aW9uIHRvIHRoZSBkYXRhYmFzZSBpcyBlc3RhYmxpc2hlZC4gVGhlcmVmb3JlIGl0IHNob3VsZCBiZQorICAgICAqIHNldCBwcmlvciB0byBpbnZva2luZyB0aGUge0BsaW5rICNleGVjdXRlfSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFzc3dvcmQKKyAgICAgKiAgICAgICAgICAgIGEge0Bjb2RlIFN0cmluZ30gaG9sZGluZyB0aGUgcGFzc3dvcmQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQYXNzd29yZChTdHJpbmcgcGFzc3dvcmQpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0aW1lb3V0IGZvciB0aGUgZHJpdmVyIHdoZW4gYSBxdWVyeSBvcGVyYXRpb24gaXMgZXhlY3V0ZWQuIElmIGEKKyAgICAgKiBxdWVyeSB0YWtlcyBsb25nZXIgdGhhbiB0aGUgdGltZW91dCwgYSB7QGNvZGUgU1FMRXhjZXB0aW9ufSBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2Vjb25kcworICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBzZWNvbmRzIGZvciB0aGUgdGltZW91dC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFF1ZXJ5VGltZW91dChpbnQgc2Vjb25kcykgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgd2hldGhlciB0aGUge0Bjb2RlIFJvd1NldH0gaXMgcmVhZC1vbmx5IG9yIHVwZGF0YWJsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFkT25seQorICAgICAqICAgICAgICAgICAge0Bjb2RlIHRydWV9IHRvIHNldCB0aGUge0Bjb2RlIFJvd1NldH0gdG8gcmVhZC1vbmx5IHN0YXRlLAorICAgICAqICAgICAgICAgICAge0Bjb2RlIGZhbHNlfSB0byBhbGxvdyB1cGRhdGVzLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmVhZE9ubHkoYm9vbGVhbiByZWFkT25seSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSB7QGNvZGUgUm93U2V0fSBjb21tYW5kCisgICAgICogdG8gYSBzdXBwbGllZCB7QGNvZGUgamF2YS5zcWwuUmVmfS4gVGhpcyBpcyBzZW50IHRvIHRoZSBkYXRhYmFzZSBhcyBhbgorICAgICAqIFNRTCB7QGNvZGUgUkVGfSB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0OyB0aGUgZmlyc3QgcGFyYW1ldGVyJ3MgaW5kZXgKKyAgICAgKiAgICAgICAgICAgIGlzIDEuCisgICAgICogQHBhcmFtIHRoZVJlZgorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIHdoaWNoIHRoZSBwYXJhbWV0ZXIgaXMgc2V0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICogQHNlZSBqYXZhLnNxbC5SZWYKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSZWYoaW50IHBhcmFtZXRlckluZGV4LCBSZWYgdGhlUmVmKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIHtAY29kZSBSb3dTZXR9IGNvbW1hbmQKKyAgICAgKiB0byBhIHN1cHBsaWVkIHtAY29kZSBzaG9ydCBpbnRlZ2VyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0OyB0aGUgZmlyc3QgcGFyYW1ldGVyJ3MgaW5kZXgKKyAgICAgKiAgICAgICAgICAgIGlzIDEuCisgICAgICogQHBhcmFtIHRoZVNob3J0CisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gd2hpY2ggdGhlIHBhcmFtZXRlciBpcyBzZXQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTaG9ydChpbnQgcGFyYW1ldGVySW5kZXgsIHNob3J0IHRoZVNob3J0KQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB0byBhCisgICAgICogc3VwcGxpZWQgc2hvcnQgaW50ZWdlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICBuYW1lIGZvciBwYXJhbWV0ZXIKKyAgICAgKiBAcGFyYW0gdGhlU2hvcnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzaG9ydCB2YWx1ZSB0byBzZXQKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNob3J0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBzaG9ydCB0aGVTaG9ydCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUge0Bjb2RlIFJvd1NldH0gY29tbWFuZAorICAgICAqIHRvIGEgc3VwcGxpZWQge0Bjb2RlIFN0cmluZ30uIFRoZSBzdHJpbmcgaXMgcGxhY2VkIGludG8gdGhlIGRhdGFiYXNlIGFzIGEKKyAgICAgKiB7QGNvZGUgVkFSQ0hBUn0gb3Ige0Bjb2RlIExPTkdWQVJDSEFSfSBTUUwgdmFsdWUsIGRlcGVuZGluZyBvbiB0aGUKKyAgICAgKiBkYXRhYmFzZSBsaW1pdHMgZm9yIHRoZSBsZW5ndGggb2Yge0Bjb2RlIFZBUkNIQVJ9IHZhbHVlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0OyB0aGUgZmlyc3QgcGFyYW1ldGVyJ3MgaW5kZXgKKyAgICAgKiAgICAgICAgICAgIGlzIDEuCisgICAgICogQHBhcmFtIHRoZVN0cmluZworICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIHdoaWNoIHRoZSBwYXJhbWV0ZXIgaXMgc2V0LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3RyaW5nKGludCBwYXJhbWV0ZXJJbmRleCwgU3RyaW5nIHRoZVN0cmluZykKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgdG8gYQorICAgICAqIHN1cHBsaWVkIFN0cmluZy4gVGhlIFN0cmluZyBpcyBwbGFjZWQgaW50byB0aGUgZGF0YWJhc2UgYXMgYSBWQVJDSEFSIG9yCisgICAgICogTE9OR1ZBUkNIQVIgU1FMIHZhbHVlLCBkZXBlbmRpbmcgb24gdGhlIGRhdGFiYXNlIGxpbWl0cyBmb3IgdGhlIGxlbmd0aCBvZgorICAgICAqIFZBUkNIQVIgdmFsdWVzLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUKKyAgICAgKiAgICAgICAgICAgIG5hbWUgZm9yIHBhcmFtZXRlcgorICAgICAqIEBwYXJhbSB0aGVTdHJpbmcKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN0cmluZyhTdHJpbmcgcGFyYW1ldGVyTmFtZSwgU3RyaW5nIHRoZVN0cmluZykKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgdG8gdGhlCisgICAgICogc3VwcGxpZWQgUm93SWQKKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgaW5kZXggb2YgdGhlIHBhcmFtZXRlciB0byBzZXQsIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaGFzCisgICAgICogICAgICAgICAgICBpbmRleCA9IDEuCisgICAgICogQHBhcmFtIHRoZVJvd0lkCisgICAgICogICAgICAgICAgICB0aGUgUm93SWQgdmFsdWUgdG8gc2V0CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSb3dJZChpbnQgcGFyYW1ldGVySW5kZXgsIFJvd0lkIHRoZVJvd0lkKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB0byB0aGUKKyAgICAgKiBzdXBwbGllZCBSb3dJZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICBuYW1lIGZvciBwYXJhbWV0ZXIKKyAgICAgKiBAcGFyYW0gdGhlUm93SWQKKyAgICAgKiAgICAgICAgICAgIHRoZSBSb3dJZCB2YWx1ZSB0byBzZXQKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFJvd0lkKFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBSb3dJZCB0aGVSb3dJZCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUgUm93U2V0IGNvbW1hbmQgdG8gdGhlCisgICAgICogc3VwcGxpZWQgU1FMWE1MCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0LCB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGhhcworICAgICAqICAgICAgICAgICAgaW5kZXggPSAxLgorICAgICAqIEBwYXJhbSB0aGVTUUxYTUwKKyAgICAgKiAgICAgICAgICAgIHRoZSBTUUxYTUwgdmFsdWUgdG8gc2V0CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTUUxYTUwoaW50IHBhcmFtZXRlckluZGV4LCBTUUxYTUwgdGhlU1FMWE1MKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB0byB0aGUKKyAgICAgKiBzdXBwbGllZCBTUUxYTUwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZVNRTFhNTAorICAgICAqICAgICAgICAgICAgdGhlIFNRTFhNTCB2YWx1ZSB0byBzZXQKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNRTFhNTChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgU1FMWE1MIHRoZVNRTFhNTCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUge0Bjb2RlIFJvd1NldH0gY29tbWFuZAorICAgICAqIHRvIGEgc3VwcGxpZWQge0Bjb2RlIGphdmEuc3FsLlRpbWV9LCBjb252ZXJ0aW5nIGl0IHRvIGFuIFNRTCB7QGNvZGUgVElNRX0KKyAgICAgKiB2YWx1ZSB1c2luZyB0aGUgc3lzdGVtIGRlZmF1bHQge0Bjb2RlIENhbGVuZGFyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0OyB0aGUgZmlyc3QgcGFyYW1ldGVyJ3MgaW5kZXgKKyAgICAgKiAgICAgICAgICAgIGlzIDEuCisgICAgICogQHBhcmFtIHRoZVRpbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqIEBzZWUgamF2YS51dGlsLkNhbGVuZGFyCisgICAgICogQHNlZSBqYXZhLnNxbC5UaW1lCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VGltZShpbnQgcGFyYW1ldGVySW5kZXgsIFRpbWUgdGhlVGltZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSB7QGNvZGUgUm93U2V0fSBjb21tYW5kCisgICAgICogdG8gYSBzdXBwbGllZCB7QGNvZGUgamF2YS5zcWwuVGltZX0sIGNvbnZlcnRpbmcgaXQgdG8gYW4gU1FMIHtAY29kZSBUSU1FfQorICAgICAqIHZhbHVlIHVzaW5nIGEgc3VwcGxpZWQge0Bjb2RlIENhbGVuZGFyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJJbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgdG8gc2V0OyB0aGUgZmlyc3QgcGFyYW1ldGVyJ3MgaW5kZXgKKyAgICAgKiAgICAgICAgICAgIGlzIDEuCisgICAgICogQHBhcmFtIHRoZVRpbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGlzIHNldC4KKyAgICAgKiBAcGFyYW0gdGhlQ2FsZW5kYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9IHRvIHVzZSBpbiB0aGUgY29udmVyc2lvbiBvcGVyYXRpb24uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKiBAc2VlIGphdmEudXRpbC5DYWxlbmRhcgorICAgICAqIEBzZWUgamF2YS5zcWwuVGltZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRpbWUoaW50IHBhcmFtZXRlckluZGV4LCBUaW1lIHRoZVRpbWUsIENhbGVuZGFyIHRoZUNhbGVuZGFyKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSBSb3dTZXQgY29tbWFuZCB0byBhCisgICAgICogc3VwcGxpZWQgamF2YS5zcWwuVGltZSwgY29udmVydGluZyB0byBhbiBTUUwgVElNRSB2YWx1ZSB1c2luZyBhIHN1cHBsaWVkCisgICAgICogQ2FsZW5kYXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZVRpbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBUaW1lIHZhbHVlIHRvIHNldAorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VGltZShTdHJpbmcgcGFyYW1ldGVyTmFtZSwgVGltZSB0aGVUaW1lKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIFJvd1NldCBjb21tYW5kIHRvIGEKKyAgICAgKiBzdXBwbGllZCBqYXZhLnNxbC5UaW1lLCBjb252ZXJ0aW5nIHRvIGFuIFNRTCBUSU1FIHZhbHVlIHVzaW5nIGEgc3VwcGxpZWQKKyAgICAgKiBDYWxlbmRhci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICBuYW1lIGZvciBwYXJhbWV0ZXIKKyAgICAgKiBAcGFyYW0gdGhlVGltZQorICAgICAqICAgICAgICAgICAgdGhlIFRpbWUgdmFsdWUgdG8gc2V0CisgICAgICogQHBhcmFtIHRoZUNhbGVuZGFyCisgICAgICogICAgICAgICAgICB0aGUgQ2FsZW5kYXIgdG8gdXNlIGluIHRoZSBjb252ZXJzaW9uIG9wZXJhdGlvbgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VGltZShTdHJpbmcgcGFyYW1ldGVyTmFtZSwgVGltZSB0aGVUaW1lLCBDYWxlbmRhciB0aGVDYWxlbmRhcikKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciBpbiB0aGUge0Bjb2RlIFJvd1NldH0gY29tbWFuZAorICAgICAqIHRvIGEgc3VwcGxpZWQge0Bjb2RlIGphdmEuc3FsLlRpbWVzdGFtcH0sIGNvbnZlcnRpbmcgaXQgdG8gYW4gU1FMIHtAY29kZQorICAgICAqIFRJTUVTVEFNUH0gdmFsdWUgdXNpbmcgdGhlIHN5c3RlbSBkZWZhdWx0IHtAY29kZSBDYWxlbmRhcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgcGFyYW1ldGVyIHRvIHNldDsgdGhlIGZpcnN0IHBhcmFtZXRlcidzIGluZGV4CisgICAgICogICAgICAgICAgICBpcyAxLgorICAgICAqIEBwYXJhbSB0aGVUaW1lc3RhbXAKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGlzIHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqIEBzZWUgamF2YS51dGlsLkNhbGVuZGFyCisgICAgICogQHNlZSBqYXZhLnNxbC5UaW1lc3RhbXAKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lc3RhbXAoaW50IHBhcmFtZXRlckluZGV4LCBUaW1lc3RhbXAgdGhlVGltZXN0YW1wKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIGluIHRoZSB7QGNvZGUgUm93U2V0fSBjb21tYW5kCisgICAgICogdG8gYSBzdXBwbGllZCB7QGNvZGUgamF2YS5zcWwuVGltZXN0YW1wfSwgY29udmVydGluZyBpdCB0byBhbiBTUUwge0Bjb2RlCisgICAgICogVElNRVNUQU1QfSB2YWx1ZSB1c2luZyBhIHN1cHBsaWVkIHtAY29kZSBDYWxlbmRhcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVySW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgcGFyYW1ldGVyIHRvIHNldDsgdGhlIGZpcnN0IHBhcmFtZXRlcidzIGluZGV4CisgICAgICogICAgICAgICAgICBpcyAxLgorICAgICAqIEBwYXJhbSB0aGVUaW1lc3RhbXAKKyAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSB0byB3aGljaCB0aGUgcGFyYW1ldGVyIGlzIHNldC4KKyAgICAgKiBAcGFyYW0gdGhlQ2FsZW5kYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSB7QGNvZGUgQ2FsZW5kYXJ9IHRvIHVzZSBpbiB0aGUgY29udmVyc2lvbiBvcGVyYXRpb24KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqIEBzZWUgamF2YS51dGlsLkNhbGVuZGFyCisgICAgICogQHNlZSBqYXZhLnNxbC5UaW1lc3RhbXAKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lc3RhbXAoaW50IHBhcmFtZXRlckluZGV4LCBUaW1lc3RhbXAgdGhlVGltZXN0YW1wLAorICAgICAgICAgICAgQ2FsZW5kYXIgdGhlQ2FsZW5kYXIpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIFJvd1NldCBjb21tYW5kIHRvIGEKKyAgICAgKiBzdXBwbGllZCBqYXZhLnNxbC5UaW1lc3RhbXAgY29udmVydGluZyB0byBhbiBTUUwgVElNRVNUQU1QIHZhbHVlCisgICAgICogdXNpbmcgdGhlIHN5c3RlbSBkZWZhdWx0IHtAY29kZSBDYWxlbmRhcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZQorICAgICAqICAgICAgICAgICAgbmFtZSBmb3IgcGFyYW1ldGVyCisgICAgICogQHBhcmFtIHRoZVRpbWVzdGFtcAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIHdoaWNoIHRoZSBwYXJhbWV0ZXIgaXMgc2V0CisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lc3RhbXAoU3RyaW5nIHBhcmFtZXRlck5hbWUsIFRpbWVzdGFtcCB0aGVUaW1lc3RhbXApCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgaW4gdGhlIFJvd1NldCBjb21tYW5kIHRvIGEKKyAgICAgKiBzdXBwbGllZCBqYXZhLnNxbC5UaW1lc3RhbXAgY29udmVydGluZyB0byBhbiBTUUwgVElNRVNUQU1QIHZhbHVlIHVzaW5nIGEKKyAgICAgKiBzdXBwbGllZCBDYWxlbmRhci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lCisgICAgICogICAgICAgICAgICBuYW1lIGZvciBwYXJhbWV0ZXIKKyAgICAgKiBAcGFyYW0gdGhlVGltZXN0YW1wCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gd2hpY2ggdGhlIHBhcmFtZXRlciBpcyBzZXQKKyAgICAgKiBAcGFyYW0gdGhlQ2FsZW5kYXIKKyAgICAgKiAgICAgICAgICAgIHRoZSBDYWxlbmRhciB0byB1c2UgaW4gdGhlIGNvbnZlcnNpb24gb3BlcmF0aW9uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lc3RhbXAoU3RyaW5nIHBhcmFtZXRlck5hbWUsIFRpbWVzdGFtcCB0aGVUaW1lc3RhbXAsCisgICAgICAgICAgICBDYWxlbmRhciB0aGVDYWxlbmRhcikgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHRhcmdldCBpbnN0YW5jZSdzIHRyYW5zYWN0aW9uIGlzb2xhdGlvbiBsZXZlbCB0byBvbmUgb2YgYQorICAgICAqIGRpc2NyZXRlIHNldCBvZiBwb3NzaWJsZSB2YWx1ZXMuIFRoZSB0cmFuc2FjdGlvbiBpc29sYXRpb24gbGV2ZWwgZGVmaW5lcworICAgICAqIHRoZSBwb2xpY3kgaW1wbGVtZW50ZWQgb24gdGhlIGRhdGFiYXNlIGZvciBtYWludGFpbmluZyB0aGUgZGF0YSB2YWx1ZXMKKyAgICAgKiBjb25zaXN0ZW50LgorICAgICAqIDxwPgorICAgICAqIEtlZXAgaW4gbWluZCB0aGF0IHNldHRpbmcgYSB0cmFuc2FjdGlvbiBpc29sYXRpb24gbGV2ZWwgaGFzIG5vIGVmZmVjdAorICAgICAqIHVubGVzcyB5b3VyIGRyaXZlciBhbmQgREJNUyBzdXBwb3J0IGl0LgorICAgICAqCisgICAgICogQHBhcmFtIGxldmVsCisgICAgICogICAgICAgICAgICB0aGUgdHJhbnNhY3Rpb24gaXNvbGF0aW9uIGxldmVsLiBPbmUgb2Y6CisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+e0Bjb2RlIENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fUkVBRF9VTkNPTU1JVFRFRH08L2xpPgorICAgICAqICAgICAgICAgICAgPGxpPntAY29kZSBDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1JFQURfQ09NTUlUVEVEfTwvbGk+CisgICAgICogICAgICAgICAgICA8bGk+e0Bjb2RlIENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fUkVQRUFUQUJMRV9SRUFEfTwvbGk+CisgICAgICogICAgICAgICAgICA8bGk+e0Bjb2RlIENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fU0VSSUFMSVpBQkxFfTwvbGk+CisgICAgICogICAgICAgICAgICA8L3VsPgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICogQHNlZSBqYXZhLnNxbC5Db25uZWN0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VHJhbnNhY3Rpb25Jc29sYXRpb24oaW50IGxldmVsKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdHlwZSBvZiB0aGlzIHtAY29kZSBSb3dTZXR9LiBCeSBkZWZhdWx0LCB0aGUgdHlwZSBpcworICAgICAqIG5vbi1zY3JvbGxhYmxlLgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0eXBlIGZvciB0aGUge0Bjb2RlIFJvd1NldH0uIE9uZSBvZjoKKyAgICAgKiAgICAgICAgICAgIDx1bD4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGNvZGUgUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZfTwvbGk+CisgICAgICogICAgICAgICAgICA8bGk+e0Bjb2RlIFJlc3VsdFNldC5UWVBFX1NDUk9MTF9JTlNFTlNJVElWRX08L2xpPgorICAgICAqICAgICAgICAgICAgPGxpPntAY29kZSBSZXN1bHRTZXQuVFlQRV9TQ1JPTExfU0VOU0lUSVZFfTwvbGk+CisgICAgICogICAgICAgICAgICA8L3VsPgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VHlwZShpbnQgdHlwZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG1hcHBpbmcgb2YgU1FMIFVzZXIgRGVmaW5lZCBUeXBlcyAoVURUcykgdG8gSmF2YSBjbGFzc2VzLiBUaGUKKyAgICAgKiBKYXZhIGNsYXNzZXMgbXVzdCBhbGwgaW1wbGVtZW50IHRoZSB7QGxpbmsgamF2YS5zcWwuU1FMRGF0YSBTUUxEYXRhfQorICAgICAqIGludGVyZmFjZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVUeXBlTWFwCisgICAgICogICAgICAgICAgICB0aGUgbmFtZXMgb2YgU1FMIFVEVHMgYW5kIHRoZSBKYXZhIGNsYXNzZXMgdG8gd2hpY2ggdGhleSBhcmUKKyAgICAgKiAgICAgICAgICAgIG1hcHBlZC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFR5cGVNYXAoTWFwPFN0cmluZywgQ2xhc3M8Pz4+IHRoZVR5cGVNYXApCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgVVJMIHVzZWQgYnkgdGhpcyB7QGNvZGUgUm93U2V0fSB0byBhY2Nlc3MgdGhlIGRhdGFiYXNlIHZpYSBhCisgICAgICoge0Bjb2RlIERyaXZlck1hbmFnZXJ9LiBUaGUgVVJMIGlzIG9wdGlvbmFsIC0gYW4gYWx0ZXJuYXRpdmUgaXMgdG8gdXNlIGEKKyAgICAgKiBkYXRhYmFzZSBuYW1lIHRvIGNyZWF0ZSBhIGNvbm5lY3Rpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlVVJMCisgICAgICogICAgICAgICAgICB0aGUgVVJMIGZvciB0aGUgZGF0YWJhc2UuIENhbiBiZSB7QGNvZGUgbnVsbH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRVcmwoU3RyaW5nIHRoZVVSTCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIFVSTCB1c2VkIGJ5IHRoaXMgUm93U2V0IHRvIGFjY2VzcyB0aGUgZGF0YWJhc2UgdmlhIGEKKyAgICAgKiA8Y29kZT5Ecml2ZXJNYW5hZ2VyPC9jb2RlPi4gVGhlIFVSTCBpcyBvcHRpb25hbCAtIGFuIGFsdGVybmF0aXZlIGlzIHRvCisgICAgICogdXNlIGEgRGF0YSBTb3VyY2UgTmFtZSB0byBjcmVhdGUgYSBjb25uZWN0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckluZGV4CisgICAgICogICAgICAgICAgICBpbmRleCBvZiB0aGUgcGFyYW1ldGVyIHRvIHNldCwgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBoYXMKKyAgICAgKiAgICAgICAgICAgIGluZGV4ID0gMS4KKyAgICAgKiBAcGFyYW0gdGhlVVJMCisgICAgICogICAgICAgICAgICBhIGphdmEubmV0LlVSTCBjb250YWluaW5nIHRoZSBVUkwgZm9yIHRoZSBkYXRhYmFzZS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFVSTChpbnQgcGFyYW1ldGVySW5kZXgsIFVSTCB0aGVVUkwpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB7QGNvZGUgVXNlcm5hbWV9IHByb3BlcnR5IGZvciB0aGUge0Bjb2RlIFJvd1NldH0sIHVzZWQgdG8KKyAgICAgKiBhdXRoZW50aWNhdGUgYSBjb25uZWN0aW9uIHRvIHRoZSBkYXRhYmFzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVVc2VybmFtZQorICAgICAqICAgICAgICAgICAgdGhlIG5ldyB1c2VyIG5hbWUgZm9yIHRoaXMgcm93IHNldC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIGVycm9yIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFVzZXJuYW1lKFN0cmluZyB0aGVVc2VybmFtZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zcWwvUm93U2V0RXZlbnQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zcWwvUm93U2V0RXZlbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYjFkNzc0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NxbC9Sb3dTZXRFdmVudC5qYXZhCkBAIC0wLDAgKzEsNTQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGphdmF4LnNxbDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEudXRpbC5FdmVudE9iamVjdDsKKworLyoqCisgKiBBbiBldmVudCB3aGljaCBpcyBzZW50IHdoZW4gc3BlY2lmaWMgZXZlbnRzIGhhcHBlbiB0byBhIHtAbGluayBSb3dTZXR9CisgKiBvYmplY3QuIFRoZSBldmVudHMgYXJlIHNlbnQgdG8gaW5mb3JtIHJlZ2lzdGVyZWQgbGlzdGVuZXJzIHRoYXQgY2hhbmdlcyBoYXZlCisgKiBvY2N1cnJlZCB0byB0aGUge0Bjb2RlIFJvd1NldH0uIFRoZSBldmVudHMgY292ZXJlZCBhcmU6CisgKiA8b2w+CisgKiA8bGk+QSBzaW5nbGUgcm93IGluIHRoZSB7QGNvZGUgUm93U2V0fSBjaGFuZ2VzLjwvbGk+CisgKiA8bGk+VGhlIHdob2xlIHNldCBvZiBkYXRhIGluIHRoZSB7QGNvZGUgUm93U2V0fSBjaGFuZ2VzLjwvbGk+CisgKiA8bGk+VGhlIHtAY29kZSBSb3dTZXR9IGN1cnNvciBwb3NpdGlvbiBjaGFuZ2VzLjwvbGk+CisgKiA8L29sPgorICogPHA+CisgKiBUaGUgZXZlbnQgY29udGFpbnMgYSByZWZlcmVuY2UgdG8gdGhlIHtAY29kZSBSb3dTZXR9IG9iamVjdCB3aGljaCBnZW5lcmF0ZWQKKyAqIHRoZSBtZXNzYWdlIHNvIHRoYXQgdGhlIGxpc3RlbmVycyBjYW4gZXh0cmFjdCB3aGF0ZXZlciBpbmZvcm1hdGlvbiB0aGV5IG5lZWQKKyAqIGZyb20gdGhhdCByZWZlcmVuY2UuCisgKi8KK3B1YmxpYyBjbGFzcyBSb3dTZXRFdmVudCBleHRlbmRzIEV2ZW50T2JqZWN0IGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xODc1NDUwODc2NTQ2MzMyMDA1TDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSB7QGNvZGUgUm93U2V0RXZlbnR9IG9iamVjdCBjb250YWluaW5nIGEgcmVmZXJlbmNlIHRvIHRoZQorICAgICAqIHtAbGluayBSb3dTZXR9IG9iamVjdCB0aGF0IGdlbmVyYXRlZCB0aGUgZXZlbnQuIEluZm9ybWF0aW9uIGFib3V0IHRoZQorICAgICAqIGNoYW5nZXMgdGhhdCBoYXZlIG9jY3VycmVkIHRvIHRoZSB7QGNvZGUgUm93U2V0fSBjYW4gYmUgZXh0cmFjdGVkIGZyb20KKyAgICAgKiB0aGUge0Bjb2RlIFJvd1NldH0gdXNpbmcgb25lIG9yIG1vcmUgb2YgdGhlIHF1ZXJ5IG1ldGhvZHMgYXZhaWxhYmxlIG9uCisgICAgICogdGhlIHtAY29kZSBSb3dTZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIHRoZVNvdXJjZQorICAgICAqICAgICAgICAgICAgdGhlIHtAY29kZSBSb3dTZXR9IHdoaWNoIGdlbmVyYXRlZCB0aGUgZXZlbnQuCisgICAgICovCisgICAgcHVibGljIFJvd1NldEV2ZW50KFJvd1NldCB0aGVTb3VyY2UpIHsKKyAgICAgICAgc3VwZXIodGhlU291cmNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc3FsL1Jvd1NldEludGVybmFsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc3FsL1Jvd1NldEludGVybmFsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzc0OWJiOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zcWwvUm93U2V0SW50ZXJuYWwuamF2YQpAQCAtMCwwICsxLDg3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5zcWw7CisKK2ltcG9ydCBqYXZhLnNxbC5Db25uZWN0aW9uOworaW1wb3J0IGphdmEuc3FsLlJlc3VsdFNldDsKK2ltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247CisKKy8qKgorICogQW4gaW50ZXJmYWNlIHByb3ZpZGVkIGJ5IGEge0Bjb2RlIFJvd1NldH0gb2JqZWN0IHRvIGxldCBlaXRoZXIgYSB7QGNvZGUKKyAqIFJvd1NldFJlYWRlcn0gb3IgYSB7QGNvZGUgUm93U2V0V3JpdGVyfSBhY2Nlc3MgaXRzIGludGVybmFsIHN0YXRlLCB0aGVyZWJ5CisgKiBwcm92aWRpbmcgZmFjaWxpdGllcyB0byByZWFkIGFuZCB1cGRhdGUgdGhlIHN0YXRlIG9mIHRoZSB7QGNvZGUgUm93U2V0fS4KKyAqLworcHVibGljIGludGVyZmFjZSBSb3dTZXRJbnRlcm5hbCB7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjb25uZWN0aW9uIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHtAY29kZSBSb3dTZXR9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNvbm5lY3Rpb24gb3Ige0Bjb2RlIG51bGx9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgYSBwcm9ibGVtIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIENvbm5lY3Rpb24gZ2V0Q29ubmVjdGlvbigpIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB7QGNvZGUgUmVzdWx0U2V0fSB0aGF0IHdhcyB0aGUgb3JpZ2luYWwgKHVubW9kaWZpZWQpIGNvbnRlbnQgb2YKKyAgICAgKiB0aGUge0Bjb2RlIFJvd1NldH0uCisgICAgICogPHA+CisgICAgICogVGhlIHtAY29kZSBSZXN1bHRTZXR9J3MgY3Vyc29yIGlzIHBvc2l0aW9uZWQgYmVmb3JlIHRoZSBmaXJzdCByb3cgb2YKKyAgICAgKiBkYXRhLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUge0Bjb2RlIFJlc3VsdFNldH0gdGhhdCBjb250YWluZWQgdGhlIG9yaWdpbmFsIGRhdGEgdmFsdWUgb2YKKyAgICAgKiAgICAgICAgIHRoZSB7QGNvZGUgUm93U2V0fS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyBSZXN1bHRTZXQgZ2V0T3JpZ2luYWwoKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgb3JpZ2luYWwgdmFsdWUgb2YgdGhlIGN1cnJlbnQgcm93IG9ubHkuIElmIHRoZSBjdXJyZW50IHJvdyBkaWQKKyAgICAgKiBub3QgaGF2ZSBhbiBvcmlnaW5hbCB2YWx1ZSwgdGhlbiBhbiBlbXB0eSB2YWx1ZSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSB7QGNvZGUgUmVzdWx0U2V0fSBjb250YWluaW5nIHRoZSB2YWx1ZSBvZiB0aGUgY3VycmVudCByb3cgb25seS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLCBvciBpZiB0aGUKKyAgICAgKiAgICAgICAgICAgICBjdXJzb3IgaXMgbm90IG9uIGEgdmFsaWQgcm93IChiZWZvcmUgdGhlIGZpcnN0IHJvdywgYWZ0ZXIgdGhlCisgICAgICogICAgICAgICAgICAgbGFzdCBvbmUgb3IgcG9pbnRpbmcgdG8gdGhlIGluc2VydCByb3cpLgorICAgICAqLworICAgIHB1YmxpYyBSZXN1bHRTZXQgZ2V0T3JpZ2luYWxSb3coKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcGFyYW1ldGVyIHZhbHVlcyB0aGF0IGhhdmUgYmVlbiBzZXQgZm9yIHRoaXMge0Bjb2RlIFJvd1NldH0ncworICAgICAqIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZXMgb2YgcGFyYW1ldGVycyB0aGF0IGhhdmUgYmVlbiBzZXQuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0W10gZ2V0UGFyYW1zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMge0Bjb2RlIFJvd1NldE1ldGFEYXRhfSBmb3IgdGhpcyB7QGNvZGUgUm93U2V0fS4gVGhlIHtAY29kZQorICAgICAqIFJvd1NldE1ldGFEYXRhfSBpcyB1c2VkIGJ5IGEge0Bjb2RlIFJvd1NldFJlYWRlcn0gdG8gc2V0IHZhbHVlcyBnaXZpbmcKKyAgICAgKiBpbmZvcm1hdGlvbiBhYm91dCB0aGUge0Bjb2RlIFJvd1NldH0ncyBjb2x1bW5zLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZU1ldGFEYXRhCisgICAgICogICAgICAgICAgICBob2xkcyB0aGUgbWV0YWRhdGEgYWJvdXQgdGhlIHtAY29kZSBSb3dTZXR9J3MgY29sdW1ucy4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1ldGFEYXRhKFJvd1NldE1ldGFEYXRhIHRoZU1ldGFEYXRhKSB0aHJvd3MgU1FMRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NxbC9Sb3dTZXRMaXN0ZW5lci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NxbC9Sb3dTZXRMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJlYjJjOWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc3FsL1Jvd1NldExpc3RlbmVyLmphdmEKQEAgLTAsMCArMSw2NyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguc3FsOworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CisKKy8qKgorICogQW4gaW50ZXJmYWNlIHVzZWQgdG8gc2VuZCBub3RpZmljYXRpb24gb2YgZXZlbnRzIG9jY3VycmluZyBpbiB0aGUgY29udGV4dCBvZgorICogYSB7QGxpbmsgUm93U2V0fS4gVG8gcmVjZWl2ZSB0aGUgbm90aWZpY2F0aW9uIGV2ZW50cywgYW4gb2JqZWN0IG11c3QKKyAqIGltcGxlbWVudCB0aGUge0Bjb2RlIFJvd1NldExpc3RlbmVyfSBpbnRlcmZhY2UgYW5kIHRoZW4gcmVnaXN0ZXIgaXRzZWxmIHdpdGgKKyAqIHRoZSB7QGNvZGUgUm93U2V0fSBvZiBpbnRlcmVzdCB1c2luZyB0aGUKKyAqIHtAbGluayBSb3dTZXQjYWRkUm93U2V0TGlzdGVuZXIoUm93U2V0TGlzdGVuZXIpfSBtZXRob2QuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUm93U2V0TGlzdGVuZXIgZXh0ZW5kcyBFdmVudExpc3RlbmVyIHsKKworICAgIC8qKgorICAgICAqIE5vdGlmaWVzIHRoZSBsaXN0ZW5lciB0aGF0IHRoZSB7QGNvZGUgUm93U2V0fSdzIGN1cnNvciBpbiB7QGNvZGUKKyAgICAgKiB0aGVFdmVudC5nZXRTb3VyY2V9IGhhcyBtb3ZlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVFdmVudAorICAgICAqICAgICAgICAgICAgYSB7QGNvZGUgUm93U2V0RXZlbnR9IHRoYXQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlCisgICAgICogICAgICAgICAgICB7QGNvZGUgUm93U2V0fSBpbnZvbHZlZC4gVGhpcyBpbmZvcm1hdGlvbiBjYW4gYmUgdXNlZCB0bworICAgICAqICAgICAgICAgICAgcmV0cmlldmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNoYW5nZSwgc3VjaCBhcyB0aGUgdXBkYXRlZAorICAgICAqICAgICAgICAgICAgZGF0YSB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY3Vyc29yTW92ZWQoUm93U2V0RXZlbnQgdGhlRXZlbnQpOworCisgICAgLyoqCisgICAgICogTm90aWZpZXMgdGhlIGxpc3RlbmVyIHRoYXQgb25lIG9mIHRoZSB7QGNvZGUgUm93U2V0fSdzIHJvd3MgaW4ge0Bjb2RlCisgICAgICogdGhlRXZlbnQuZ2V0U291cmNlfSBoYXMgY2hhbmdlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aGVFdmVudAorICAgICAqICAgICAgICAgICAgYSB7QGNvZGUgUm93U2V0RXZlbnR9IHRoYXQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlCisgICAgICogICAgICAgICAgICB7QGNvZGUgUm93U2V0fSBpbnZvbHZlZC4gVGhpcyBpbmZvcm1hdGlvbiBjYW4gYmUgdXNlZCB0bworICAgICAqICAgICAgICAgICAgcmV0cmlldmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNoYW5nZSwgc3VjaCBhcyB0aGUgbmV3IGN1cnNvcgorICAgICAqICAgICAgICAgICAgcG9zaXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcm93Q2hhbmdlZChSb3dTZXRFdmVudCB0aGVFdmVudCk7CisKKyAgICAvKioKKyAgICAgKiBOb3RpZmllcyB0aGUgbGlzdGVuZXIgdGhhdCB0aGUge0Bjb2RlIFJvd1NldH0ncyBlbnRpcmUgY29udGVudHMgaW4KKyAgICAgKiB7QGNvZGUgdGhlRXZlbnQuZ2V0U291cmNlfSBoYXZlIGJlZW4gdXBkYXRlZCAoYW4gZXhhbXBsZSBpcyB0aGUgZXhlY3V0aW9uCisgICAgICogb2YgYSBjb21tYW5kIHdoaWNoIHJldHJpZXZlcyBuZXcgZGF0YSBmcm9tIHRoZSBkYXRhYmFzZSkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlRXZlbnQKKyAgICAgKiAgICAgICAgICAgIGEge0Bjb2RlIFJvd1NldEV2ZW50fSB0aGF0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZQorICAgICAqICAgICAgICAgICAge0Bjb2RlIFJvd1NldH0gaW52b2x2ZWQuIFRoaXMgaW5mb3JtYXRpb24gY2FuIGJlIHVzZWQgdG8KKyAgICAgKiAgICAgICAgICAgIHJldHJpZXZlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjaGFuZ2UsIHN1Y2ggYXMgdGhlIHVwZGF0ZWQKKyAgICAgKiAgICAgICAgICAgIHJvd3Mgb2YgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByb3dTZXRDaGFuZ2VkKFJvd1NldEV2ZW50IHRoZUV2ZW50KTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zcWwvUm93U2V0TWV0YURhdGEuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zcWwvUm93U2V0TWV0YURhdGEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOTZjOGI5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NxbC9Sb3dTZXRNZXRhRGF0YS5qYXZhCkBAIC0wLDAgKzEsMjkzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5zcWw7CisKK2ltcG9ydCBqYXZhLnNxbC5SZXN1bHRTZXRNZXRhRGF0YTsKK2ltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247CisKKy8qKgorICogQW4gaW50ZXJmYWNlIHdoaWNoIHByb3ZpZGVzIGZhY2lsaXRpZXMgZm9yIGdldHRpbmcgaW5mb3JtYXRpb24gYWJvdXQgdGhlCisgKiBjb2x1bW5zIGluIGEge0Bjb2RlIFJvd1NldH0uCisgKiA8cD4KKyAqIHtAY29kZSBSb3dTZXRNZXRhRGF0YX0gZXh0ZW5kcyB7QGxpbmsgamF2YS5zcWwuUmVzdWx0U2V0TWV0YURhdGF9LCBhZGRpbmcgbmV3CisgKiBvcGVyYXRpb25zIGZvciBjYXJyeWluZyBvdXQgdmFsdWUgc2V0cy4KKyAqIDxwPgorICogQXBwbGljYXRpb24gY29kZSB3b3VsZCBub3Qgbm9ybWFsbHkgY2FsbCB0aGlzIGludGVyZmFjZSBkaXJlY3RseS4gSXQgd291bGQgYmUKKyAqIGNhbGxlZCBpbnRlcm5hbGx5IHdoZW4ge0Bjb2RlIFJvd1NldC5leGVjdXRlfSBpcyBjYWxsZWQuCisgKgorICogQHNlZSBSb3dTZXRJbnRlcm5hbCNzZXRNZXRhRGF0YShSb3dTZXRNZXRhRGF0YSkKKyAqLworcHVibGljIGludGVyZmFjZSBSb3dTZXRNZXRhRGF0YSBleHRlbmRzIFJlc3VsdFNldE1ldGFEYXRhIHsKKworICAgIC8qKgorICAgICAqIFNldHMgYXV0b21hdGljIG51bWJlcmluZyBmb3IgYSBzcGVjaWZpZWQgY29sdW1uIGluIHRoZSB7QGNvZGUgUm93U2V0fS4gSWYKKyAgICAgKiBhdXRvbWF0aWMgbnVtYmVyaW5nIGlzIG9uLCB0aGUgY29sdW1uIGlzIHJlYWQtb25seS4gVGhlIGRlZmF1bHQgdmFsdWUgZm9yCisgICAgICogdGhlIGF1dG8gaW5jcmVtZW50IHBhcmFtZXRlciBpcyB7QGNvZGUgZmFsc2V9LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggbnVtYmVyIGZvciB0aGUgY29sdW1uOyB0aGUgZmlyc3QgY29sdW1uJ3MgaW5kZXggaXMKKyAgICAgKiAgICAgICAgICAgIDEuCisgICAgICogQHBhcmFtIGF1dG9JbmNyZW1lbnQKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSB0cnVlfSB0byBzZXQgYXV0b21hdGljIG51bWJlcmluZyBvbiwge0Bjb2RlIGZhbHNlfSB0bworICAgICAqICAgICAgICAgICAgdHVybiBpdCBvZmYgKGRlZmF1bHQpLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEF1dG9JbmNyZW1lbnQoaW50IGNvbHVtbkluZGV4LCBib29sZWFuIGF1dG9JbmNyZW1lbnQpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY2FzZSBzZW5zaXRpdmUgcHJvcGVydHkgZm9yIGEgc3BlY2lmaWVkIGNvbHVtbiBpbiB0aGUge0Bjb2RlCisgICAgICogUm93U2V0fS4gVGhlIGRlZmF1bHQgaXMgdGhhdCB0aGUgY29sdW1uIGlzIG5vdCBjYXNlIHNlbnNpdGl2ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG51bWJlciBmb3IgdGhlIGNvbHVtbjsgdGhlIGZpcnN0IGNvbHVtbidzIGluZGV4IGlzCisgICAgICogICAgICAgICAgICAxLgorICAgICAqIEBwYXJhbSBjYXNlU2Vuc2l0aXZlCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gdG8gbWFrZSB0aGUgY29sdW1uIGNhc2Ugc2Vuc2l0aXZlLCB7QGNvZGUgZmFsc2V9CisgICAgICogICAgICAgICAgICB0byBtYWtlIGl0IGNhc2UgaW5zZW5zaXRpdmUgKGRlZmF1bHQpLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENhc2VTZW5zaXRpdmUoaW50IGNvbHVtbkluZGV4LCBib29sZWFuIGNhc2VTZW5zaXRpdmUpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY2F0YWxvZyBuYW1lIGZvciBhIHNwZWNpZmllZCBjb2x1bW4gaW4gdGhlIHtAY29kZSBSb3dTZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggbnVtYmVyIGZvciB0aGUgY29sdW1uOyB0aGUgZmlyc3QgY29sdW1uJ3MgaW5kZXggaXMKKyAgICAgKiAgICAgICAgICAgIDEuCisgICAgICogQHBhcmFtIGNhdGFsb2dOYW1lCisgICAgICogICAgICAgICAgICB0aGUgbmV3IGNhdGFsb2cncyBuYW1lLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENhdGFsb2dOYW1lKGludCBjb2x1bW5JbmRleCwgU3RyaW5nIGNhdGFsb2dOYW1lKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG51bWJlciBvZiBjb2x1bW5zIGNvbnRhaW5lZCBpbiB0aGUgcm93IHNldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5Db3VudAorICAgICAqICAgICAgICAgICAgdGhlIG51bWJlciBvZiBjb2x1bW5zIGNvbnRhaW5lZCBpbiB0aGUge0Bjb2RlIFJvd1NldH0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHByb2JsZW0gb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q29sdW1uQ291bnQoaW50IGNvbHVtbkNvdW50KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbm9ybWFsIG1heGltdW0gd2lkdGggaW4gY2hhcmFjdGVycyBmb3IgYSBzcGVjaWZpZWQgY29sdW1uIGluIHRoZQorICAgICAqIHtAY29kZSBSb3dTZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggbnVtYmVyIGZvciB0aGUgY29sdW1uOyB0aGUgZmlyc3QgY29sdW1uJ3MgaW5kZXggaXMKKyAgICAgKiAgICAgICAgICAgIDEuCisgICAgICogQHBhcmFtIGRpc3BsYXlTaXplCisgICAgICogICAgICAgICAgICB0aGUgbm9ybWFsIG1heGltdW0gY29sdW1uIHdpZHRoIGluIGNoYXJhY3RlcnMuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHByb2JsZW0gb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q29sdW1uRGlzcGxheVNpemUoaW50IGNvbHVtbkluZGV4LCBpbnQgZGlzcGxheVNpemUpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc3VnZ2VzdGVkIG5hbWUgYXMgbGFiZWwgZm9yIHRoZSBjb2x1bW4gY29udGFpbmVkIGluIHRoZSB7QGNvZGUKKyAgICAgKiBSb3dTZXR9LiBUaGUgbGFiZWwgaXMgYW4gYWxpYXMgZm9yIHByaW50aW5nIGFuZCBkaXNwbGF5aW5nIHB1cnBvc2VzLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggbnVtYmVyIGZvciB0aGUgY29sdW1uOyB0aGUgZmlyc3QgY29sdW1uJ3MgaW5kZXggaXMKKyAgICAgKiAgICAgICAgICAgIDEuCisgICAgICogQHBhcmFtIHRoZUxhYmVsCisgICAgICogICAgICAgICAgICB0aGUgYWxpYXMgbmFtZSBmb3IgdGhlIGNvbHVtbi4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb2x1bW5MYWJlbChpbnQgY29sdW1uSW5kZXgsIFN0cmluZyB0aGVMYWJlbCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjb2x1bW4gbmFtZSBmb3IgYSBzcGVjaWZpZWQgY29sdW1uIGluIHRoZSB7QGNvZGUgUm93U2V0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG51bWJlciBmb3IgdGhlIGNvbHVtbjsgdGhlIGZpcnN0IGNvbHVtbidzIGluZGV4IGlzCisgICAgICogICAgICAgICAgICAxLgorICAgICAqIEBwYXJhbSB0aGVDb2x1bW5OYW1lCisgICAgICogICAgICAgICAgICB0aGUgY29sdW1uJ3MgbGFiZWwuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHByb2JsZW0gb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q29sdW1uTmFtZShpbnQgY29sdW1uSW5kZXgsIFN0cmluZyB0aGVDb2x1bW5OYW1lKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIFNRTCB0eXBlIGZvciBhIHNwZWNpZmllZCBjb2x1bW4gaW4gdGhlIHtAY29kZSBSb3dTZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggbnVtYmVyIGZvciB0aGUgY29sdW1uOyB0aGUgZmlyc3QgY29sdW1uJ3MgaW5kZXggaXMKKyAgICAgKiAgICAgICAgICAgIDEuCisgICAgICogQHBhcmFtIHRoZVNRTFR5cGUKKyAgICAgKiAgICAgICAgICAgIHRoZSBTUUwgVHlwZSwgYXMgZGVmaW5lZCBieSB7QGNvZGUgamF2YS5zcWwuVHlwZXN9LgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvbHVtblR5cGUoaW50IGNvbHVtbkluZGV4LCBpbnQgdGhlU1FMVHlwZSkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB0eXBlIG5hbWUgZm9yIGEgc3BlY2lmaWVkIGNvbHVtbiBpbiB0aGUge0Bjb2RlIFJvd1NldH0sIHdoZXJlCisgICAgICogdGhlIGRhdGEgdHlwZSBpcyBzcGVjaWZpYyB0byB0aGUgZGF0YSBzb3VyY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBudW1iZXIgZm9yIHRoZSBjb2x1bW47IHRoZSBmaXJzdCBjb2x1bW4ncyBpbmRleCBpcworICAgICAqICAgICAgICAgICAgMS4KKyAgICAgKiBAcGFyYW0gdGhlVHlwZU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSBTUUwgdHlwZSBuYW1lIGZvciB0aGUgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvbHVtblR5cGVOYW1lKGludCBjb2x1bW5JbmRleCwgU3RyaW5nIHRoZVR5cGVOYW1lKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgd2hldGhlciBhIHNwZWNpZmllZCBjb2x1bW4gaXMgYSBjdXJyZW5jeSB2YWx1ZS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMKKyAgICAgKiB7QGNvZGUgZmFsc2V9LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggbnVtYmVyIGZvciB0aGUgY29sdW1uOyB0aGUgZmlyc3QgY29sdW1uJ3MgaW5kZXggaXMKKyAgICAgKiAgICAgICAgICAgIDEuCisgICAgICogQHBhcmFtIGlzQ3VycmVuY3kKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSB0cnVlfSBpZiB0aGUgY29sdW1uIHNob3VsZCBiZSB0cmVhdGVkIGFzIGEgY3VycmVuY3kKKyAgICAgKiAgICAgICAgICAgIHZhbHVlLCB7QGNvZGUgZmFsc2V9IGlmIGl0IHNob3VsZCBub3QgYmUgdHJlYXRlZCBhcyBhIGN1cnJlbmN5CisgICAgICogICAgICAgICAgICB2YWx1ZSAoZGVmYXVsdCkuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHByb2JsZW0gb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q3VycmVuY3koaW50IGNvbHVtbkluZGV4LCBib29sZWFuIGlzQ3VycmVuY3kpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB3aGV0aGVyIGEgc3BlY2lmaWVkIGNvbHVtbiBjYW4gY29udGFpbiBTUUwge0Bjb2RlIE5VTEx9IHZhbHVlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG51bWJlciBmb3IgdGhlIGNvbHVtbjsgdGhlIGZpcnN0IGNvbHVtbidzIGluZGV4IGlzCisgICAgICogICAgICAgICAgICAxLgorICAgICAqIEBwYXJhbSBudWxsYWJpbGl0eQorICAgICAqICAgICAgICAgICAgYW4gaW50ZWdlciB3aGljaCBpcyBvbmUgb2YgdGhlIGZvbGxvd2luZyB2YWx1ZXM6CisgICAgICogICAgICAgICAgICA8dWw+CisgICAgICogICAgICAgICAgICA8bGk+e0Bjb2RlIFJlc3VsdFNldE1ldGFEYXRhLmNvbHVtbk5vTnVsbHN9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGNvZGUgUmVzdWx0U2V0TWV0YURhdGEuY29sdW1uTnVsbGFibGV9PC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT57QGNvZGUgUmVzdWx0U2V0TWV0YURhdGEuY29sdW1uTnVsbGFibGVVbmtub3dufTwvbGk+CisgICAgICogICAgICAgICAgICA8L3VsPgorICAgICAqICAgICAgICAgICAgPHA+CisgICAgICogICAgICAgICAgICBUaGUgZGVmYXVsdCB2YWx1ZSBpcyB7QGNvZGUKKyAgICAgKiAgICAgICAgICAgIFJlc3VsdFNldE1ldGFEYXRhLmNvbHVtbk51bGxhYmxlVW5rbm93bn0uCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHByb2JsZW0gb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TnVsbGFibGUoaW50IGNvbHVtbkluZGV4LCBpbnQgbnVsbGFiaWxpdHkpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbnVtYmVyIG9mIGRlY2ltYWwgZGlnaXRzIGZvciBhIHNwZWNpZmllZCBjb2x1bW4gaW4gdGhlIHtAY29kZQorICAgICAqIFJvd1NldH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uSW5kZXgKKyAgICAgKiAgICAgICAgICAgIHRoZSBpbmRleCBudW1iZXIgZm9yIHRoZSBjb2x1bW47IHRoZSBmaXJzdCBjb2x1bW4ncyBpbmRleCBpcworICAgICAqICAgICAgICAgICAgMS4KKyAgICAgKiBAcGFyYW0gdGhlUHJlY2lzaW9uCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGRlY2ltYWwgZGlnaXRzLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFByZWNpc2lvbihpbnQgY29sdW1uSW5kZXgsIGludCB0aGVQcmVjaXNpb24pCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGVjbGFyZXMgaG93IG1hbnkgZGVjaW1hbCBkaWdpdHMgdGhlcmUgc2hvdWxkIGJlIGFmdGVyIGEgZGVjaW1hbCBwb2ludAorICAgICAqIGZvciB0aGUgY29sdW1uIHNwZWNpZmllZCBieSB7QGNvZGUgY29sdW1uSW5kZXh9LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggbnVtYmVyIGZvciB0aGUgY29sdW1uOyB0aGUgZmlyc3QgY29sdW1uJ3MgaW5kZXggaXMKKyAgICAgKiAgICAgICAgICAgIDEuCisgICAgICogQHBhcmFtIHRoZVNjYWxlCisgICAgICogICAgICAgICAgICB0aGUgbnVtYmVyIG9mIGRpZ2l0cyBhZnRlciB0aGUgZGVjaW1hbCBwb2ludC4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTY2FsZShpbnQgY29sdW1uSW5kZXgsIGludCB0aGVTY2FsZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHNjaGVtYSBuYW1lIGZvciBhIHNwZWNpZmllZCBjb2x1bW4gaW4gdGhlIHtAY29kZSBSb3dTZXR9LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggbnVtYmVyIGZvciB0aGUgY29sdW1uOyB0aGUgZmlyc3QgY29sdW1uJ3MgaW5kZXggaXMKKyAgICAgKiAgICAgICAgICAgIDEuCisgICAgICogQHBhcmFtIHRoZVNjaGVtYU5hbWUKKyAgICAgKiAgICAgICAgICAgIGEge0Bjb2RlIFN0cmluZ30gY29udGFpbmluZyB0aGUgc2NoZW1hIG5hbWUuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHByb2JsZW0gb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2NoZW1hTmFtZShpbnQgY29sdW1uSW5kZXgsIFN0cmluZyB0aGVTY2hlbWFOYW1lKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgd2hldGhlciBhIHNwZWNpZmllZCBjb2x1bW4gY2FuIGJlIHVzZWQgaW4gYSBzZWFyY2ggaW52b2x2aW5nIGEKKyAgICAgKiB7QGNvZGUgV0hFUkV9IGNsYXVzZS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMge0Bjb2RlIGZhbHNlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG51bWJlciBmb3IgdGhlIGNvbHVtbjsgdGhlIGZpcnN0IGNvbHVtbidzIGluZGV4IGlzCisgICAgICogICAgICAgICAgICAxLgorICAgICAqIEBwYXJhbSBpc1NlYXJjaGFibGUKKyAgICAgKiAgICAgICAgICAgIHtAY29kZSB0cnVlfSBvZiB0aGUgY29sdW1uIGNhbiBiZSB1c2VkIGluIGEge0Bjb2RlIFdIRVJFfQorICAgICAqICAgICAgICAgICAgY2xhdXNlIHNlYXJjaCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHByb2JsZW0gb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2VhcmNoYWJsZShpbnQgY29sdW1uSW5kZXgsIGJvb2xlYW4gaXNTZWFyY2hhYmxlKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldHMgaWYgYSBzcGVjaWZpZWQgY29sdW1uIGNhbiBjb250YWluIHNpZ25lZCBudW1iZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbHVtbkluZGV4CisgICAgICogICAgICAgICAgICB0aGUgaW5kZXggbnVtYmVyIGZvciB0aGUgY29sdW1uOyB0aGUgZmlyc3QgY29sdW1uJ3MgaW5kZXggaXMKKyAgICAgKiAgICAgICAgICAgIDEuCisgICAgICogQHBhcmFtIGlzU2lnbmVkCisgICAgICogICAgICAgICAgICB7QGNvZGUgdHJ1ZX0gaWYgdGhlIGNvbHVtbiBjYW4gY29udGFpbiBzaWduZWQgbnVtYmVycywge0Bjb2RlCisgICAgICogICAgICAgICAgICBmYWxzZX0gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNpZ25lZChpbnQgY29sdW1uSW5kZXgsIGJvb2xlYW4gaXNTaWduZWQpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdGFibGUgbmFtZSBmb3IgYSBzcGVjaWZpZWQgY29sdW1uIGluIHRoZSB7QGNvZGUgUm93U2V0fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb2x1bW5JbmRleAorICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IG51bWJlciBmb3IgdGhlIGNvbHVtbjsgdGhlIGZpcnN0IGNvbHVtbidzIGluZGV4IGlzCisgICAgICogICAgICAgICAgICAxLgorICAgICAqIEBwYXJhbSB0aGVUYWJsZU5hbWUKKyAgICAgKiAgICAgICAgICAgIHRoZSB0YWJsZSBuYW1lIGZvciB0aGUgY29sdW1uLgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYSBwcm9ibGVtIG9jY3VycyBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZShpbnQgY29sdW1uSW5kZXgsIFN0cmluZyB0aGVUYWJsZU5hbWUpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NxbC9Sb3dTZXRSZWFkZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zcWwvUm93U2V0UmVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTZkMzA0ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC9zcWwvUm93U2V0UmVhZGVyLmphdmEKQEAgLTAsMCArMSw1NiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguc3FsOworCitpbXBvcnQgamF2YS5zcWwuU1FMRXhjZXB0aW9uOworCisvKioKKyAqIEFuIGludGVyZmFjZSB3aGljaCBwcm92aWRlcyBmdW5jdGlvbmFsaXR5IGZvciBhIGRpc2Nvbm5lY3RlZCB7QGNvZGUgUm93U2V0fQorICogdG8gZ2V0IGRhdGEgZnJvbSBhIGRhdGFiYXNlIGludG8gaXRzIHJvd3MuIFRoZSB7QGNvZGUgUm93U2V0fSBjYWxscyB0aGUKKyAqIHtAY29kZSBSb3dTZXRSZWFkZXJ9IGludGVyZmFjZSB3aGVuIHRoZSB7QGNvZGUgUm93U2V0fSdzIGV4ZWN1dGUgbWV0aG9kIGlzCisgKiBpbnZva2VkIC0gYSB7QGNvZGUgUm93U2V0UmVhZGVyfSBtdXN0IGZpcnN0IGJlIHJlZ2lzdGVyZWQgd2l0aCB0aGUge0Bjb2RlCisgKiBSb3dTZXR9IGZvciB0aGlzIHRvIHdvcmsuCisgKgorICogQHNlZSBSb3dTZXQKKyAqLworcHVibGljIGludGVyZmFjZSBSb3dTZXRSZWFkZXIgeworCisgICAgLyoqCisgICAgICogUmVhZHMgbmV3IGRhdGEgaW50byB0aGUge0Bjb2RlIFJvd1NldH0uIFRoZSBjYWxsaW5nIHtAY29kZSBSb3dTZXR9IG9iamVjdAorICAgICAqIG11c3QgaXRzZWxmIGltcGxlbWVudCB0aGUge0Bjb2RlIFJvd1NldEludGVybmFsfSBpbnRlcmZhY2UgYW5kIHRoZQorICAgICAqIHtAY29kZSBSb3dTZXRSZWFkZXJ9IG11c3QgYmUgcmVnaXN0ZXJlZCBhcyBhIHJlYWRlciBvbiB0aGUKKyAgICAgKiB7QGNvZGUgUm93U2V0fS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBhZGRzIHJvd3MgaW50byB0aGUgY2FsbGluZyB7QGNvZGUgUm93U2V0fS4gVGhlIHJlYWRlciBtYXkKKyAgICAgKiBpbnZva2UgYW55IG9mIHRoZSB7QGNvZGUgUm93U2V0fSdzIG1ldGhvZHMgZXhjZXB0IGZvciB0aGUge0Bjb2RlIGV4ZWN1dGV9CisgICAgICogbWV0aG9kIChjYWxsaW5nIHtAY29kZSBleGVjdXRlfSB3aWxsIGNhdXNlIGFuIHtAY29kZSBTUUxFeGNlcHRpb259IHRvIGJlCisgICAgICogdGhyb3duKS4gSG93ZXZlciwgd2hlbiB0aGUgcmVhZGVyIGNhbGxzIHRoZSB7QGNvZGUgUm93U2V0fSdzIG1ldGhvZHMsIG5vCisgICAgICogZXZlbnRzIGFyZSBzZW50IHRvIGxpc3RlbmVycyAtIGFueSBsaXN0ZW5lcnMgYXJlIGluZm9ybWVkIGJ5IHRoZSBjYWxsaW5nCisgICAgICoge0Bjb2RlIFJvd1NldH0ncyB7QGNvZGUgZXhlY3V0ZX0gbWV0aG9kIG9uY2UgdGhlIHJlYWRlciByZXR1cm5zIGZyb20gdGhlCisgICAgICoge0Bjb2RlIHJlYWREYXRhfSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhlQ2FsbGVyCisgICAgICogICAgICAgICAgICBtdXN0IGJlIHRoZSBjYWxsaW5nIHtAY29kZSBSb3dTZXR9IG9iamVjdCwgd2hpY2ggbXVzdCBoYXZlCisgICAgICogICAgICAgICAgICBpbXBsZW1lbnRlZCB0aGUge0Bjb2RlIFJvd1NldEludGVybmFsfSBpbnRlcmZhY2UuCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhIHByb2JsZW0gb2NjdXJzIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2Ugb3IgaWYgdGhlIHJlYWRlcgorICAgICAqICAgICAgICAgICAgIGNhbGxzIHRoZSB7QGxpbmsgUm93U2V0I2V4ZWN1dGUoKX0gbWV0aG9kLgorICAgICAqIEBzZWUgUm93U2V0SW50ZXJuYWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZWFkRGF0YShSb3dTZXRJbnRlcm5hbCB0aGVDYWxsZXIpIHRocm93cyBTUUxFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc3FsL1Jvd1NldFdyaXRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NxbC9Sb3dTZXRXcml0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YTNmMmNmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NxbC9Sb3dTZXRXcml0ZXIuamF2YQpAQCAtMCwwICsxLDU4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC5zcWw7CisKK2ltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247CisKKy8qKgorICogQW4gaW50ZXJmYWNlIHdoaWNoIHByb3ZpZGVzIGZ1bmN0aW9uYWxpdHkgZm9yIGEgZGlzY29ubmVjdGVkIHtAY29kZSBSb3dTZXR9CisgKiB0byBwdXQgZGF0YSB1cGRhdGVzIGJhY2sgdG8gdGhlIGRhdGEgc291cmNlIGZyb20gd2hpY2ggdGhlIHtAY29kZSBSb3dTZXR9IHdhcworICogb3JpZ2luYWxseSBwb3B1bGF0ZWQuIEFuIG9iamVjdCBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2UgaXMgY2FsbGVkIGEKKyAqIHdyaXRlci4KKyAqIDxwPgorICogVGhlIHdyaXRlciBtdXN0IGVzdGFibGlzaCBhIGNvbm5lY3Rpb24gdG8gdGhlIHtAY29kZSBSb3dTZXR9J3MgZGF0YWJhc2UKKyAqIGJlZm9yZSB3cml0aW5nIHRoZSBkYXRhLiBUaGUge0Bjb2RlIFJvd1NldH0gY2FsbGluZyB0aGlzIGludGVyZmFjZSBtdXN0CisgKiBpbXBsZW1lbnQgdGhlIHtAY29kZSBSb3dTZXRJbnRlcm5hbH0gaW50ZXJmYWNlLgorICogPHA+CisgKiBUaGUgd3JpdGVyIG1heSBlbmNvdW50ZXIgYSBzaXR1YXRpb24gd2hlcmUgdGhlIHVwZGF0ZWQgZGF0YSBuZWVkcyB0byBiZQorICogd3JpdHRlbiBiYWNrIHRvIHRoZSBkYXRhYmFzZSwgYnV0IGhhcyBhbHJlYWR5IGJlZW4gdXBkYXRlZCB0aGVyZSBpbiB0aGUgbWVhbgorICogdGltZS4gSG93IGEgY29uZmxpY3Qgb2YgdGhpcyBraW5kIGlzIGhhbmRsZWQgaXMgZGV0ZXJtaW5lZCBieSB0aGUKKyAqIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgd3JpdGVyLgorICoKKyAqIEBzZWUgUm93U2V0SW50ZXJuYWwKKyAqLworcHVibGljIGludGVyZmFjZSBSb3dTZXRXcml0ZXIgeworCisgICAgLyoqCisgICAgICogV3JpdGVzIGNoYW5nZXMgbWFkZSBpbiB0aGUge0Bjb2RlIFJvd1NldH0sIHdoaWNoIGlzIGFzc29jaWF0ZWQgd2l0aCB0aGlzCisgICAgICoge0Bjb2RlIFJvd1NldFdyaXRlcn0sIGJhY2sgdG8gdGhlIGRhdGFiYXNlLgorICAgICAqCisgICAgICogQHBhcmFtIHRoZVJvd1NldAorICAgICAqICAgICAgICAgICAgYSByb3cgc2V0IHRoYXQgZnVsZmlsbHMgdGhlIGZvbGxvd2luZyBjcml0ZXJpYToKKyAgICAgKiAgICAgICAgICAgIDx1bD4KKyAgICAgKiAgICAgICAgICAgIDxsaT5pdCBtdXN0IGltcGxlbWVudCB0aGUge0Bjb2RlIFJvd1NldEludGVybmFsfSBpbnRlcmZhY2UsPC9saT4KKyAgICAgKiAgICAgICAgICAgIDxsaT5oYXZlIHRoaXMge0Bjb2RlIFJvd1NldFdyaXRlcn0gcmVnaXN0ZXJlZCB3aXRoIGl0LDwvbGk+CisgICAgICogICAgICAgICAgICA8bGk+bXVzdCBjYWxsIHRoaXMgbWV0aG9kIGludGVybmFsbHkuPC9saT4KKyAgICAgKiAgICAgICAgICAgIDwvdWw+CisgICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIG1vZGlmaWVkIGRhdGEgd2FzIHdyaXR0ZW4sIHtAY29kZSBmYWxzZX0KKyAgICAgKiAgICAgICAgIG90aGVyd2lzZSAod2hpY2ggdHlwaWNhbGx5IGltcGxpZXMgc29tZSBmb3JtIG9mIGNvbmZsaWN0KS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGEgcHJvYmxlbSBvY2N1cnMgYWNjZXNzaW5nIHRoZSBkYXRhYmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB3cml0ZURhdGEoUm93U2V0SW50ZXJuYWwgdGhlUm93U2V0KSB0aHJvd3MgU1FMRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NxbC9TdGF0ZW1lbnRFdmVudC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NxbC9TdGF0ZW1lbnRFdmVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyNTM3NmMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc3FsL1N0YXRlbWVudEV2ZW50LmphdmEKQEAgLTAsMCArMSw4MSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguc3FsOworCitpbXBvcnQgamF2YS5zcWwuUHJlcGFyZWRTdGF0ZW1lbnQ7CitpbXBvcnQgamF2YS5zcWwuU1FMRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5FdmVudE9iamVjdDsKKworLyoqCisgKiBBIHN0YXRlbWVudCBldmVudCB0aGF0IGEgUHJlcGFyZWRTdGF0ZW1lbnQgaXMgY2xvc2VkCisgKgorICogQHNpbmNlIDEuNgorICovCitwdWJsaWMgY2xhc3MgU3RhdGVtZW50RXZlbnQgZXh0ZW5kcyBFdmVudE9iamVjdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODA4OTU3MzczMTgyNjYwODMxNUw7CisKKyAgICBwcml2YXRlIFNRTEV4Y2VwdGlvbiBleGNlcHRpb247CisKKyAgICBwcml2YXRlIFByZXBhcmVkU3RhdGVtZW50IHN0YXRlbWVudDsKKworICAgIC8qKgorICAgICAqIHRoZSBjb25zdHJ1Y3RvcgorICAgICAqCisgICAgICogQHBhcmFtIGNvbgorICAgICAqICAgICAgICAgICAgdGhlIHN0YXRtZW50IHJlbGF0ZWQgY29ubmVjdGlvbgorICAgICAqIEBwYXJhbSBzdGF0ZW1lbnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGF0ZW1lbnQgdG8gYmUgY2xvc2VkCisgICAgICogQHBhcmFtIGV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgdGhlIGV4Y2VwdGlvbiB0byB0aHJvdworICAgICAqLworICAgIHB1YmxpYyBTdGF0ZW1lbnRFdmVudChQb29sZWRDb25uZWN0aW9uIGNvbiwgUHJlcGFyZWRTdGF0ZW1lbnQgc3RhdGVtZW50LAorICAgICAgICAgICAgU1FMRXhjZXB0aW9uIGV4Y2VwdGlvbikgeworICAgICAgICBzdXBlcihjb24pOworICAgICAgICB0aGlzLnN0YXRlbWVudCA9IHN0YXRlbWVudDsKKyAgICAgICAgdGhpcy5leGNlcHRpb24gPSBleGNlcHRpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogdGhlIGNvbnN0cnVjdG9yIHdpdGggbnVsbCBleGNlcHRpb24KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb24KKyAgICAgKiAgICAgICAgICAgIHRoZSBzdGF0bWVudCByZWxhdGVkIGNvbm5lY3Rpb24KKyAgICAgKiBAcGFyYW0gc3RhdGVtZW50CisgICAgICogICAgICAgICAgICB0aGUgc3RhdGVtZW50IHRvIGJlIGNsb3NlZAorICAgICAqLworICAgIHB1YmxpYyBTdGF0ZW1lbnRFdmVudChQb29sZWRDb25uZWN0aW9uIGNvbiwgUHJlcGFyZWRTdGF0ZW1lbnQgc3RhdGVtZW50KSB7CisgICAgICAgIHRoaXMoY29uLCBzdGF0ZW1lbnQsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHN0YXRlbWVudCBvZiB0aGlzIGV2ZW50CisgICAgICovCisgICAgcHVibGljIFByZXBhcmVkU3RhdGVtZW50IGdldFN0YXRlbWVudCgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGVtZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGV4Y2VwdGlvbiB0byBiZSB0aHJvd24KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGV4Y2VwdGlvbiBvZiB0aGlzIGV2ZW50CisgICAgICovCisgICAgcHVibGljIFNRTEV4Y2VwdGlvbiBnZXRTUUxFeGNlcHRpb24oKSB7CisgICAgICAgIHJldHVybiB0aGlzLmV4Y2VwdGlvbjsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NxbC9TdGF0ZW1lbnRFdmVudExpc3RlbmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgvc3FsL1N0YXRlbWVudEV2ZW50TGlzdGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jODU3YTIxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3NxbC9TdGF0ZW1lbnRFdmVudExpc3RlbmVyLmphdmEKQEAgLTAsMCArMSw0NyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXguc3FsOworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CisKKy8qKgorICogQW4gb2JqZWN0IHRoYXQgcmVnaXN0ZXJzIHRvIGJlIG5vdGlmaWVkIG9mIGV2ZW50cyB0aGF0IG9jY3VyIG9uCisgKiBQcmVwYXJlZFN0YXRlbWVudHMgdGhhdCBhcmUgaW4gdGhlIFN0YXRlbWVudCBwb29sLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFN0YXRlbWVudEV2ZW50TGlzdGVuZXIgZXh0ZW5kcyBFdmVudExpc3RlbmVyIHsKKyAgICAvKioKKyAgICAgKiBUaGUgZHJpdmVyIGNhbGxzIHRoaXMgbWV0aG9kIG9uIGFsbCBTdGF0ZW1lbnRFdmVudExpc3RlbmVycyByZWdpc3RlcmVkIG9uCisgICAgICogdGhlIGNvbm5lY3Rpb24gd2hlbiBpdCBkZXRlY3RzIHRoYXQgYSBQcmVwYXJlZFN0YXRlbWVudCBpcyBjbG9zZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXZlbnQKKyAgICAgKiAgICAgICAgICAgIGFuIFN0YXRlbWVudEV2ZW50IG9iamVjdCBkZXNjcmliaW5nIHRoZSBldmVudCBvZiBzdGF0ZW1lbnQKKyAgICAgKiAgICAgICAgICAgIGNsb3NlZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHN0YXRlbWVudENsb3NlZChTdGF0ZW1lbnRFdmVudCBldmVudCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZHJpdmVyIGNhbGxzIHRoaXMgbWV0aG9kIG9uIGFsbCBTdGF0ZW1lbnRFdmVudExpc3RlbmVycyByZWdpc3RlcmVkIG9uCisgICAgICogdGhlIGNvbm5lY3Rpb24gd2hlbiBpdCBkZXRlY3RzIHRoYXQgYSBQcmVwYXJlZFN0YXRlbWVudCBpcyBpbnZhbGlkLAorICAgICAqIGJlZm9yZSBhIFNRTEV4Y2VwdGlvbiBpcyB0aHJvd24KKyAgICAgKgorICAgICAqIEBwYXJhbSBldmVudAorICAgICAqICAgICAgICAgICAgYW4gU3RhdGVtZW50RXZlbnQgb2JqZWN0IGRlc2NyaWJpbmcgdGhlIGV2ZW50IG9mIHN0YXRlbWVudAorICAgICAqICAgICAgICAgICAgZXJyb3Igb2NjdXJyZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdGF0ZW1lbnRFcnJvck9jY3VycmVkKFN0YXRlbWVudEV2ZW50IGV2ZW50KTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvWE1MQ29uc3RhbnRzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL1hNTENvbnN0YW50cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRkM2M1MTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL1hNTENvbnN0YW50cy5qYXZhCkBAIC0wLDAgKzEsMTc5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8gJElkOiBYTUxDb25zdGFudHMuamF2YSA1ODQ0NzcgMjAwNy0xMC0xNCAwMjo0NDowM1ogbXJnbGF2YXMgJAorCitwYWNrYWdlIGphdmF4LnhtbDsKKworLyoqCisgKiA8cD5VdGlsaXR5IGNsYXNzIHRvIGNvbnRhaW4gYmFzaWMgWE1MIHZhbHVlcyBhcyBjb25zdGFudHMuPC9wPgorICoKKyAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgorICogQHZlcnNpb24gJFJldmlzaW9uOiA1ODQ0NzcgJCwgJERhdGU6IDIwMDctMTAtMTMgMTk6NDQ6MDMgLTA3MDAgKFNhdCwgMTMgT2N0IDIwMDcpICQKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sMTEvIj5FeHRlbnNpYmxlIE1hcmt1cCBMYW5ndWFnZSAoWE1MKSAxLjE8L2E+CisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwiPkV4dGVuc2libGUgTWFya3VwIExhbmd1YWdlIChYTUwpIDEuMCAoU2Vjb25kIEVkaXRpb24pPC9hPgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9YTUwveG1sLVYxMC0yZS1lcnJhdGEiPlhNTCAxLjAgU2Vjb25kIEVkaXRpb24gU3BlY2lmaWNhdGlvbiBFcnJhdGE8L2E+CisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbC1uYW1lczExLyI+TmFtZXNwYWNlcyBpbiBYTUwgMS4xPC9hPgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzIj5OYW1lc3BhY2VzIGluIFhNTDwvYT4KKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvWE1ML3htbC1uYW1lcy0xOTk5MDExNC1lcnJhdGEiPk5hbWVzcGFjZXMgaW4gWE1MIEVycmF0YTwvYT4KKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTEvIj5YTUwgU2NoZW1hIFBhcnQgMTogU3RydWN0dXJlczwvYT4KKyAqIEBzaW5jZSAxLjUKKyAqKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBYTUxDb25zdGFudHMgeworCisgICAgLyoqCisgICAgICogPHA+UHJpdmF0ZSBjb25zdHJ1Y3RvciB0byBwcmV2ZW50IGluc3RhbnRpYXRpb24uPC9wPgorICAgICAqLworICAgIHByaXZhdGUgWE1MQ29uc3RhbnRzKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPk5hbWVzcGFjZSBVUkkgdG8gdXNlIHRvIHJlcHJlc2VudCB0aGF0IHRoZXJlIGlzIG5vIE5hbWVzcGFjZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5EZWZpbmVkIGJ5IHRoZSBOYW1lc3BhY2Ugc3BlY2lmaWNhdGlvbiB0byBiZSAiIi48L3A+CisgICAgICoKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI2RlZmF1bHRpbmciPgorICAgICAqIE5hbWVzcGFjZXMgaW4gWE1MLCA1LjIgTmFtZXNwYWNlIERlZmF1bHRpbmc8L2E+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTlVMTF9OU19VUkkgPSAiIjsKKworICAgIC8qKgorICAgICAqIDxwPlByZWZpeCB0byB1c2UgdG8gcmVwcmVzZW50IHRoZSBkZWZhdWx0IFhNTCBOYW1lc3BhY2UuPC9wPgorICAgICAqCisgICAgICogPHA+RGVmaW5lZCBieSB0aGUgWE1MIHNwZWNpZmljYXRpb24gdG8gYmUgIiIuPC9wPgorICAgICAqCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyNucy1xdWFsbmFtZXMiPgorICAgICAqIE5hbWVzcGFjZXMgaW4gWE1MLCAzLiBRdWFsaWZpZWQgTmFtZXM8L2E+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9OU19QUkVGSVggPSAiIjsKKworICAgIC8qKgorICAgICAqIDxwPlRoZSBvZmZpY2lhbCBYTUwgTmFtZXNwYWNlIG5hbWUgVVJJLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkRlZmluZWQgYnkgdGhlIFhNTCBzcGVjaWZpY2F0aW9uIHRvIGJlCisgICAgICogIjxjb2RlPmh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZTwvY29kZT4iLjwvcD4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8jbnMtcXVhbG5hbWVzIj4KKyAgICAgKiBOYW1lc3BhY2VzIGluIFhNTCwgMy4gUXVhbGlmaWVkIE5hbWVzPC9hPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9OU19VUkkgPQorICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIjsKKworICAgIC8qKgorICAgICAqIDxwPlRoZSBvZmZpY2lhbCBYTUwgTmFtZXNwYWNlIHByZWZpeC48L3A+CisgICAgICoKKyAgICAgKiA8cD5EZWZpbmVkIGJ5IHRoZSBYTUwgc3BlY2lmaWNhdGlvbiB0byBiZSAiPGNvZGU+eG1sPC9jb2RlPiIuPC9wPgorICAgICAqCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyNucy1xdWFsbmFtZXMiPgorICAgICAqIE5hbWVzcGFjZXMgaW4gWE1MLCAzLiBRdWFsaWZpZWQgTmFtZXM8L2E+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX05TX1BSRUZJWCA9ICJ4bWwiOworCisgICAgLyoqCisgICAgICogPHA+VGhlIG9mZmljaWFsIFhNTCBhdHRyaWJ1dGUgdXNlZCBmb3Igc3BlY2lmeWluZyBYTUwgTmFtZXNwYWNlCisgICAgICogZGVjbGFyYXRpb25zLCB7QGxpbmsgI1hNTE5TX0FUVFJJQlVURQorICAgICAqIFhNTENvbnN0YW50cy5YTUxOU19BVFRSSUJVVEV9LCBOYW1lc3BhY2UgbmFtZSBVUkkuPC9wPgorICAgICAqCisgICAgICogPHA+RGVmaW5lZCBieSB0aGUgWE1MIHNwZWNpZmljYXRpb24gdG8gYmUKKyAgICAgKiAiPGNvZGU+aHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy88L2NvZGU+Ii48L3A+CisgICAgICoKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI25zLXF1YWxuYW1lcyI+CisgICAgICogTmFtZXNwYWNlcyBpbiBYTUwsIDMuIFF1YWxpZmllZCBOYW1lczwvYT4KKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1hNTC94bWwtbmFtZXMtMTk5OTAxMTQtZXJyYXRhLyI+CisgICAgICogTmFtZXNwYWNlcyBpbiBYTUwgRXJyYXRhPC9hPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTE5TX0FUVFJJQlVURV9OU19VUkkgPQorICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iOworCisgICAgLyoqCisgICAgICogPHA+VGhlIG9mZmljaWFsIFhNTCBhdHRyaWJ1dGUgdXNlZCBmb3Igc3BlY2lmeWluZyBYTUwgTmFtZXNwYWNlCisgICAgICogZGVjbGFyYXRpb25zLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkl0IGlzIDxzdHJvbmc+PGVtPk5PVDwvZW0+PC9zdHJvbmc+IHZhbGlkIHRvIHVzZSBhcyBhCisgICAgICogcHJlZml4LiAgRGVmaW5lZCBieSB0aGUgWE1MIHNwZWNpZmljYXRpb24gdG8gYmUKKyAgICAgKiAiPGNvZGU+eG1sbnM8L2NvZGU+Ii48L3A+CisgICAgICoKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI25zLXF1YWxuYW1lcyI+CisgICAgICogTmFtZXNwYWNlcyBpbiBYTUwsIDMuIFF1YWxpZmllZCBOYW1lczwvYT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxOU19BVFRSSUJVVEUgPSAieG1sbnMiOworCisgICAgLyoqCisgICAgICogPHA+VzNDIFhNTCBTY2hlbWEgTmFtZXNwYWNlIFVSSS48L3A+CisgICAgICoKKyAgICAgKiA8cD5EZWZpbmVkIHRvIGJlICI8Y29kZT5odHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYTwvY29kZT4iLgorICAgICAqCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMS8jSW5zdGFuY2VfRG9jdW1lbnRfQ29uc3RydWN0aW9ucyI+CisgICAgICogIFhNTCBTY2hlbWEgUGFydCAxOgorICAgICAqICBTdHJ1Y3R1cmVzLCAyLjYgU2NoZW1hLVJlbGF0ZWQgTWFya3VwIGluIERvY3VtZW50cyBCZWluZyBWYWxpZGF0ZWQ8L2E+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVzNDX1hNTF9TQ0hFTUFfTlNfVVJJID0KKyAgICAgICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIjsKKworICAgIC8qKgorICAgICAqIDxwPlczQyBYTUwgU2NoZW1hIEluc3RhbmNlIE5hbWVzcGFjZSBVUkkuPC9wPgorICAgICAqCisgICAgICogPHA+RGVmaW5lZCB0byBiZSAiPGNvZGU+aHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2U8L2NvZGU+Ii48L3A+CisgICAgICoKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0xLyNJbnN0YW5jZV9Eb2N1bWVudF9Db25zdHJ1Y3Rpb25zIj4KKyAgICAgKiAgWE1MIFNjaGVtYSBQYXJ0IDE6CisgICAgICogIFN0cnVjdHVyZXMsIDIuNiBTY2hlbWEtUmVsYXRlZCBNYXJrdXAgaW4gRG9jdW1lbnRzIEJlaW5nIFZhbGlkYXRlZDwvYT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXM0NfWE1MX1NDSEVNQV9JTlNUQU5DRV9OU19VUkkgPQorICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiOworCisgICAgLyoqCisgICAgICogPHA+VzNDIFhQYXRoIERhdGF0eXBlIE5hbWVzcGFjZSBVUkkuPC9wPgorICAgICAqCisgICAgICogPHA+RGVmaW5lZCB0byBiZSAiPGNvZGU+aHR0cDovL3d3dy53My5vcmcvMjAwMy8xMS94cGF0aC1kYXRhdHlwZXM8L2NvZGU+Ii48L3A+CisgICAgICoKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoLWRhdGFtb2RlbCI+WFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWw8L2E+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVzNDX1hQQVRIX0RBVEFUWVBFX05TX1VSSSA9ICJodHRwOi8vd3d3LnczLm9yZy8yMDAzLzExL3hwYXRoLWRhdGF0eXBlcyI7CisKKyAgICAvKioKKyAgICAgKiA8cD5YTUwgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbiBOYW1lc3BhY2UgVVJJIGFzIGFuIGFyYml0cmFyeSB2YWx1ZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5TaW5jZSBub3QgZm9ybWFsbHkgZGVmaW5lZCBieSBhbnkgZXhpc3Rpbmcgc3RhbmRhcmQsIGFyYml0cmFyaWx5IGRlZmluZSB0byBiZSAiPGNvZGU+aHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbDwvY29kZT4iLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9EVERfTlNfVVJJID0gImh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwiOworCisgICAgLyoqCisgICAgICogPHA+UkVMQVggTkcgTmFtZXNwYWNlIFVSSS48L3A+CisgICAgICoKKyAgICAgKiA8cD5EZWZpbmVkIHRvIGJlICI8Y29kZT5odHRwOi8vcmVsYXhuZy5vcmcvbnMvc3RydWN0dXJlLzEuMDwvY29kZT4iLjwvcD4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3JlbGF4bmcub3JnL3NwZWMtMjAwMTEyMDMuaHRtbCI+UkVMQVggTkcgU3BlY2lmaWNhdGlvbjwvYT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBSRUxBWE5HX05TX1VSSSA9ICJodHRwOi8vcmVsYXhuZy5vcmcvbnMvc3RydWN0dXJlLzEuMCI7CisKKyAgICAvKioKKyAgICAgKiA8cD5GZWF0dXJlIGZvciBzZWN1cmUgcHJvY2Vzc2luZy48L3A+CisgICAgICoKKyAgICAgKiA8dWw+CisgICAgICogICA8bGk+CisgICAgICogICAgIDxjb2RlPnRydWU8L2NvZGU+IGluc3RydWN0cyB0aGUgaW1wbGVtZW50YXRpb24gdG8gcHJvY2VzcyBYTUwgc2VjdXJlbHkuCisgICAgICogICAgIFRoaXMgbWF5IHNldCBsaW1pdHMgb24gWE1MIGNvbnN0cnVjdHMgdG8gYXZvaWQgY29uZGl0aW9ucyBzdWNoIGFzIGRlbmlhbCBvZiBzZXJ2aWNlIGF0dGFja3MuCisgICAgICogICA8L2xpPgorICAgICAqICAgPGxpPgorICAgICAqICAgICA8Y29kZT5mYWxzZTwvY29kZT4gaW5zdHJ1Y3RzIHRoZSBpbXBsZW1lbnRhdGlvbiB0byBwcm9jZXNzIFhNTCBhY2NvcmRpbmcgdG8gdGhlIGxldHRlciBvZiB0aGUgWE1MIHNwZWNpZmljYXRpb25zCisgICAgICogICAgIGlnbm9yaW5nIHNlY3VyaXR5IGlzc3VlcyBzdWNoIGFzIGxpbWl0cyBvbiBYTUwgY29uc3RydWN0cyB0byBhdm9pZCBjb25kaXRpb25zIHN1Y2ggYXMgZGVuaWFsIG9mIHNlcnZpY2UgYXR0YWNrcy4KKyAgICAgKiAgIDwvbGk+CisgICAgICogPC91bD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HID0gImh0dHA6Ly9qYXZheC54bWwuWE1MQ29uc3RhbnRzL2ZlYXR1cmUvc2VjdXJlLXByb2Nlc3NpbmciOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9kYXRhdHlwZS9EYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvZGF0YXR5cGUvRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjBkM2ZlNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvZGF0YXR5cGUvRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwxNzAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLyAkSWQ6IERhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbi5qYXZhIDU2OTk4NyAyMDA3LTA4LTI3IDA0OjA4OjQ2WiBtcmdsYXZhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLmRhdGF0eXBlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CisKKy8qKgorICogPHA+SW5kaWNhdGVzIGEgc2VyaW91cyBjb25maWd1cmF0aW9uIGVycm9yLjwvcD4KKyAqCisgKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogNTY5OTg3ICQsICREYXRlOiAyMDA3LTA4LTI2IDIxOjA4OjQ2IC0wNzAwIChTdW4sIDI2IEF1ZyAyMDA3KSAkCisgKiBAc2luY2UgMS41CisgKi8KKworcHVibGljIGNsYXNzIERhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICAvKiogU3RyZWFtIFVuaXF1ZSBJZGVudGlmaWVyLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xNjk5MzczMTU5MDI3MDQ3MjM4TDsKKworICAgIC8qKiBUaGlzIGZpZWxkIGlzIHJlcXVpcmVkIHRvIHN0b3JlIHRoZSBjYXVzZSBvbiBKREsgMS4zIGFuZCBiZWxvdy4gKi8KKyAgICBwcml2YXRlIFRocm93YWJsZSBjYXVzZU9uSkRLMTNPckJlbG93OworCisgICAgLyoqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgY2xhc3MgaXMgYmVpbmcgdXNlZCBpbiBhIEpESyAxLjQgY29udGV4dC4gKi8KKyAgICBwcml2YXRlIHRyYW5zaWVudCBib29sZWFuIGlzSkRLMTRPckFib3ZlID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiA8cD5DcmVhdGUgYSBuZXcgPGNvZGU+RGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uPC9jb2RlPiB3aXRoCisgICAgICogbm8gc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlIGFuZCBjYXVzZS48L3A+CisgICAgICovCisKKyAgICBwdWJsaWMgRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkNyZWF0ZSBhIG5ldyA8Y29kZT5EYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb248L2NvZGU+IHdpdGgKKyAgICAgKiB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKworICAgIHB1YmxpYyBEYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+Q3JlYXRlIGEgbmV3IDxjb2RlPkRhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjwvY29kZT4gd2l0aAorICAgICAqIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UgYW5kIGNhdXNlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKiBAcGFyYW0gY2F1c2UgVGhlIGNhdXNlLiAgQSA8Y29kZT5udWxsPC9jb2RlPiB2YWx1ZSBpcyBwZXJtaXR0ZWQsIGFuZCBpbmRpY2F0ZXMgdGhhdCB0aGUgY2F1c2UgaXMgbm9uZXhpc3RlbnQgb3IgdW5rbm93bi4KKyAgICAgKi8KKworICAgIHB1YmxpYyBEYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICAgICAgaW5pdENhdXNlQnlSZWZsZWN0aW9uKGNhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5DcmVhdGUgYSBuZXcgPGNvZGU+RGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uPC9jb2RlPiB3aXRoCisgICAgICogdGhlIHNwZWNpZmllZCBjYXVzZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2F1c2UgVGhlIGNhdXNlLiAgQSA8Y29kZT5udWxsPC9jb2RlPiB2YWx1ZSBpcyBwZXJtaXR0ZWQsIGFuZCBpbmRpY2F0ZXMgdGhhdCB0aGUgY2F1c2UgaXMgbm9uZXhpc3RlbnQgb3IgdW5rbm93bi4KKyAgICAgKi8KKworICAgIHB1YmxpYyBEYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICAgIHN1cGVyKGNhdXNlID09IG51bGwgPyBudWxsIDogY2F1c2UudG9TdHJpbmcoKSk7CisgICAgICAgIGluaXRDYXVzZUJ5UmVmbGVjdGlvbihjYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnQgdGhlIHRoZSB0cmFjZSBvZiBtZXRob2RzIGZyb20gd2hlcmUgdGhlIGVycm9yCisgICAgICogb3JpZ2luYXRlZC4gIFRoaXMgd2lsbCB0cmFjZSBhbGwgbmVzdGVkIGV4Y2VwdGlvbgorICAgICAqIG9iamVjdHMsIGFzIHdlbGwgYXMgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJpbnRTdGFja1RyYWNlKCkgeworICAgICAgICBpZiAoIWlzSkRLMTRPckFib3ZlICYmIGNhdXNlT25KREsxM09yQmVsb3cgIT0gbnVsbCkgeworICAgICAgICAgICAgcHJpbnRTdGFja1RyYWNlMChuZXcgUHJpbnRXcml0ZXIoU3lzdGVtLmVyciwgdHJ1ZSkpOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgc3VwZXIucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludCB0aGUgdGhlIHRyYWNlIG9mIG1ldGhvZHMgZnJvbSB3aGVyZSB0aGUgZXJyb3IKKyAgICAgKiBvcmlnaW5hdGVkLiAgVGhpcyB3aWxsIHRyYWNlIGFsbCBuZXN0ZWQgZXhjZXB0aW9uCisgICAgICogb2JqZWN0cywgYXMgd2VsbCBhcyB0aGlzIG9iamVjdC4KKyAgICAgKiBAcGFyYW0gcyBUaGUgc3RyZWFtIHdoZXJlIHRoZSBkdW1wIHdpbGwgYmUgc2VudCB0by4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludFN0YWNrVHJhY2UoUHJpbnRTdHJlYW0gcykgeworICAgICAgICBpZiAoIWlzSkRLMTRPckFib3ZlICYmIGNhdXNlT25KREsxM09yQmVsb3cgIT0gbnVsbCkgeworICAgICAgICAgICAgcHJpbnRTdGFja1RyYWNlMChuZXcgUHJpbnRXcml0ZXIocykpOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgc3VwZXIucHJpbnRTdGFja1RyYWNlKHMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnQgdGhlIHRoZSB0cmFjZSBvZiBtZXRob2RzIGZyb20gd2hlcmUgdGhlIGVycm9yCisgICAgICogb3JpZ2luYXRlZC4gIFRoaXMgd2lsbCB0cmFjZSBhbGwgbmVzdGVkIGV4Y2VwdGlvbgorICAgICAqIG9iamVjdHMsIGFzIHdlbGwgYXMgdGhpcyBvYmplY3QuCisgICAgICogQHBhcmFtIHMgVGhlIHdyaXRlciB3aGVyZSB0aGUgZHVtcCB3aWxsIGJlIHNlbnQgdG8uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJpbnRTdGFja1RyYWNlKFByaW50V3JpdGVyIHMpIHsKKyAgICAgICAgaWYgKCFpc0pESzE0T3JBYm92ZSAmJiBjYXVzZU9uSkRLMTNPckJlbG93ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHByaW50U3RhY2tUcmFjZTAocyk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBzdXBlci5wcmludFN0YWNrVHJhY2Uocyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcHJpbnRTdGFja1RyYWNlMChQcmludFdyaXRlciBzKSB7CisgICAgICAgIGNhdXNlT25KREsxM09yQmVsb3cucHJpbnRTdGFja1RyYWNlKHMpOworICAgICAgICBzLnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOworICAgICAgICBzdXBlci5wcmludFN0YWNrVHJhY2Uocyk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGluaXRDYXVzZUJ5UmVmbGVjdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgY2F1c2VPbkpESzEzT3JCZWxvdyA9IGNhdXNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgTWV0aG9kIG0gPSB0aGlzLmdldENsYXNzKCkuZ2V0TWV0aG9kKCJpbml0Q2F1c2UiLCBuZXcgQ2xhc3NbXSB7VGhyb3dhYmxlLmNsYXNzfSk7CisgICAgICAgICAgICBtLmludm9rZSh0aGlzLCBuZXcgT2JqZWN0W10ge2NhdXNlfSk7CisgICAgICAgICAgICBpc0pESzE0T3JBYm92ZSA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgLy8gSWdub3JlIGV4Y2VwdGlvbgorICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHt9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gaW4pCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIGluLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNZXRob2QgbTEgPSB0aGlzLmdldENsYXNzKCkuZ2V0TWV0aG9kKCJnZXRDYXVzZSIsIG5ldyBDbGFzc1tdIHt9KTsKKyAgICAgICAgICAgIFRocm93YWJsZSBjYXVzZSA9IChUaHJvd2FibGUpIG0xLmludm9rZSh0aGlzLCBuZXcgT2JqZWN0W10ge30pOworICAgICAgICAgICAgaWYgKGNhdXNlT25KREsxM09yQmVsb3cgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGNhdXNlT25KREsxM09yQmVsb3cgPSBjYXVzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgaWYgKGNhdXNlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBNZXRob2QgbTIgPSB0aGlzLmdldENsYXNzKCkuZ2V0TWV0aG9kKCJpbml0Q2F1c2UiLCBuZXcgQ2xhc3NbXSB7VGhyb3dhYmxlLmNsYXNzfSk7CisgICAgICAgICAgICAgICAgbTIuaW52b2tlKHRoaXMsIG5ldyBPYmplY3RbXSB7Y2F1c2VPbkpESzEzT3JCZWxvd30pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaXNKREsxNE9yQWJvdmUgPSB0cnVlOworICAgICAgICB9CisgICAgICAgIC8vIElnbm9yZSBleGNlcHRpb24KKyAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7fQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvZGF0YXR5cGUvRGF0YXR5cGVDb25zdGFudHMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvZGF0YXR5cGUvRGF0YXR5cGVDb25zdGFudHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40OTQ2MzkwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9kYXRhdHlwZS9EYXRhdHlwZUNvbnN0YW50cy5qYXZhCkBAIC0wLDAgKzEsMjY4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8gJElkOiBEYXRhdHlwZUNvbnN0YW50cy5qYXZhIDQ0NjU5OCAyMDA2LTA5LTE1IDEyOjU1OjQwWiBqZXJlbWlhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLmRhdGF0eXBlOworCitpbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKK2ltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLlFOYW1lOworCisvKioKKyAqIDxwPlV0aWxpdHkgY2xhc3MgdG8gY29udGFpbiBiYXNpYyBEYXRhdHlwZSB2YWx1ZXMgYXMgY29uc3RhbnRzLjwvcD4KKyAqCisgKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogNDQ2NTk4ICQsICREYXRlOiAyMDA2LTA5LTE1IDA1OjU1OjQwIC0wNzAwIChGcmksIDE1IFNlcCAyMDA2KSAkCisgKiBAc2luY2UgMS41CisgKi8KKworcHVibGljIGZpbmFsIGNsYXNzIERhdGF0eXBlQ29uc3RhbnRzIHsKKworICAgIC8qKgorICAgICAqIDxwPlByaXZhdGUgY29uc3RydWN0b3IgdG8gcHJldmVudCBpbnN0YW50aWF0aW9uLjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIERhdGF0eXBlQ29uc3RhbnRzKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFZhbHVlIGZvciBmaXJzdCBtb250aCBvZiB5ZWFyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpBTlVBUlkgID0gMTsKKworICAgIC8qKgorICAgICAqIFZhbHVlIGZvciBzZWNvbmQgbW9udGggb2YgeWVhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGRUJSVUFSWSA9IDI7CisKKyAgICAvKioKKyAgICAgKiBWYWx1ZSBmb3IgdGhpcmQgbW9udGggb2YgeWVhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVJDSCAgICA9IDM7CisKKyAgICAvKioKKyAgICAgKiBWYWx1ZSBmb3IgZm91cnRoIG1vbnRoIG9mIHllYXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVBSSUwgICAgPSA0OworCisgICAgLyoqCisgICAgICogVmFsdWUgZm9yIGZpZnRoIG1vbnRoIG9mIHllYXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFZICAgICAgPSA1OworCisgICAgLyoqCisgICAgICogVmFsdWUgZm9yIHNpeHRoIG1vbnRoIG9mIHllYXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSlVORSAgICAgPSA2OworCisgICAgLyoqCisgICAgICogVmFsdWUgZm9yIHNldmVudGggbW9udGggb2YgeWVhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBKVUxZICAgICA9IDc7CisKKyAgICAvKioKKyAgICAgKiBWYWx1ZSBmb3IgZWlnaHRoIG1vbnRoIG9mIHllYXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVVHVVNUICAgPSA4OworCisgICAgLyoqCisgICAgICogVmFsdWUgZm9yIG5pbnRoIG1vbnRoIG9mIHllYXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VQVEVNQkVSID0gOTsKKworICAgIC8qKgorICAgICAqIFZhbHVlIGZvciB0ZW50aCBtb250aCBvZiB5ZWFyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9DVE9CRVIgPSAxMDsKKworICAgIC8qKgorICAgICAqIFZhbHVlIGZvciBlbGV2ZW4gbW9udGggb2YgeWVhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT1ZFTUJFUiA9IDExOworCisgICAgLyoqCisgICAgICogVmFsdWUgZm9yIHR3ZWx2ZSBtb250aCBvZiB5ZWFyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFQ0VNQkVSID0gMTI7CisKKyAgICAvKioKKyAgICAgKiA8cD5Db21wYXJpc29uIHJlc3VsdC48L3A+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTEVTU0VSID0gLTE7CisKKyAgICAvKioKKyAgICAgKiA8cD5Db21wYXJpc29uIHJlc3VsdC48L3A+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVFVQUwgPSAgMDsKKworICAgIC8qKgorICAgICAqIDxwPkNvbXBhcmlzb24gcmVzdWx0LjwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBHUkVBVEVSID0gIDE7CisKKyAgICAvKioKKyAgICAgKiA8cD5Db21wYXJpc29uIHJlc3VsdC48L3A+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5ERVRFUk1JTkFURSA9ICAyOworCisgICAgLyoqCisgICAgICogRGVzaWduYXRpb24gdGhhdCBhbiAiaW50IiBmaWVsZCBpcyBub3Qgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VOREVGSU5FRCA9IEludGVnZXIuTUlOX1ZBTFVFOworCisgICAgLyoqCisgICAgICogPHA+QSBjb25zdGFudCB0aGF0IHJlcHJlc2VudHMgdGhlIHllYXJzIGZpZWxkLjwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZpZWxkIFlFQVJTID0gbmV3IEZpZWxkKCJZRUFSUyIsIDApOworCisgICAgLyoqCisgICAgICogPHA+QSBjb25zdGFudCB0aGF0IHJlcHJlc2VudHMgdGhlIG1vbnRocyBmaWVsZC48L3A+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWVsZCBNT05USFMgPSBuZXcgRmllbGQoIk1PTlRIUyIsIDEpOworCisgICAgLyoqCisgICAgICogPHA+QSBjb25zdGFudCB0aGF0IHJlcHJlc2VudHMgdGhlIGRheXMgZmllbGQuPC9wPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgREFZUyA9IG5ldyBGaWVsZCgiREFZUyIsIDIpOworCisgICAgLyoqCisgICAgICogPHA+QSBjb25zdGFudCB0aGF0IHJlcHJlc2VudHMgdGhlIGhvdXJzIGZpZWxkLjwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZpZWxkIEhPVVJTID0gbmV3IEZpZWxkKCJIT1VSUyIsIDMpOworCisgICAgLyoqCisgICAgICogPHA+QSBjb25zdGFudCB0aGF0IHJlcHJlc2VudHMgdGhlIG1pbnV0ZXMgZmllbGQuPC9wPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgTUlOVVRFUyA9IG5ldyBGaWVsZCgiTUlOVVRFUyIsIDQpOworCisgICAgLyoqCisgICAgICogPHA+QSBjb25zdGFudCB0aGF0IHJlcHJlc2VudHMgdGhlIHNlY29uZHMgZmllbGQuPC9wPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgU0VDT05EUyA9IG5ldyBGaWVsZCgiU0VDT05EUyIsIDUpOworCisgICAgLyoqCisgICAgICogVHlwZS1zYWZlIGVudW0gY2xhc3MgdGhhdCByZXByZXNlbnRzIHNpeCBmaWVsZHMKKyAgICAgKiBvZiB0aGUge0BsaW5rIER1cmF0aW9ufSBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogPHA+PGNvZGU+U3RyaW5nPC9jb2RlPiByZXByZXNlbnRhdGlvbiBvZiA8b2RlPkZpZWxkPC9jb2RlPi48L3A+CisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBzdHI7CisgICAgICAgIC8qKgorICAgICAgICAgKiA8cD5VbmlxdWUgaWQgb2YgdGhlIGZpZWxkLjwvcD4KKyAgICAgICAgICoKKyAgICAgICAgICogPHA+VGhpcyB2YWx1ZSBhbGxvd3MgdGhlIHtAbGluayBEdXJhdGlvbn0gY2xhc3MgdG8gdXNlIHN3aXRjaAorICAgICAgICAgKiBzdGF0ZW1lbnRzIHRvIHByb2Nlc3MgZmllbGRzLjwvcD4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgZmluYWwgaW50IGlkOworCisgICAgICAgIC8qKgorICAgICAgICAgKiA8cD5Db25zdHJ1Y3QgYSA8Y29kZT5GaWVsZDwvY29kZT4gd2l0aCBzcGVjaWZpZWQgdmFsdWVzLjwvcD4KKyAgICAgICAgICogQHBhcmFtIHN0ciA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uIG9mIDxjb2RlPkZpZWxkPC9jb2RlPgorICAgICAgICAgKiBAcGFyYW0gaWQgIDxjb2RlPmludDwvY29kZT4gcmVwcmVzZW50YXRpb24gb2YgPGNvZGU+RmllbGQ8L2NvZGU+CisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIEZpZWxkKGZpbmFsIFN0cmluZyBzdHIsIGZpbmFsIGludCBpZCkgeworICAgICAgICAgICAgdGhpcy5zdHIgPSBzdHI7CisgICAgICAgICAgICB0aGlzLmlkID0gaWQ7CisgICAgICAgIH0KKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgYSBmaWVsZCBuYW1lIGluIEVuZ2xpc2guIFRoaXMgbWV0aG9kCisgICAgICAgICAqIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgZm9yIGRlYnVnZ2luZy9kaWFnbm9zaXMKKyAgICAgICAgICogYW5kIG5vdCBmb3IgZGlzcGxheSB0byBlbmQtdXNlcnMuCisgICAgICAgICAqCisgICAgICAgICAqIEByZXR1cm4KKyAgICAgICAgICogICAgICBhIG5vbi1udWxsIHZhbGlkIFN0cmluZyBjb25zdGFudC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7IHJldHVybiBzdHI7IH0KKworICAgICAgICAvKioKKyAgICAgICAgICogPHA+R2V0IGlkIG9mIHRoaXMgRmllbGQuPC9wPgorICAgICAgICAgKgorICAgICAgICAgKiBAcmV0dXJuIElkIG9mIGZpZWxkLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGludCBnZXRJZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBpZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkZ1bGx5IHF1YWxpZmllZCBuYW1lIGZvciBXM0MgWE1MIFNjaGVtYSAxLjAgZGF0YXR5cGUgPGNvZGU+ZGF0ZVRpbWU8L2NvZGU+LjwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFFOYW1lIERBVEVUSU1FID0gbmV3IFFOYW1lKFhNTENvbnN0YW50cy5XM0NfWE1MX1NDSEVNQV9OU19VUkksICJkYXRlVGltZSIpOworCisgICAgLyoqCisgICAgICogPHA+RnVsbHkgcXVhbGlmaWVkIG5hbWUgZm9yIFczQyBYTUwgU2NoZW1hIDEuMCBkYXRhdHlwZSA8Y29kZT50aW1lPC9jb2RlPi48L3A+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBRTmFtZSBUSU1FID0gbmV3IFFOYW1lKFhNTENvbnN0YW50cy5XM0NfWE1MX1NDSEVNQV9OU19VUkksICJ0aW1lIik7CisKKyAgICAvKioKKyAgICAgKiA8cD5GdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgVzNDIFhNTCBTY2hlbWEgMS4wIGRhdGF0eXBlIDxjb2RlPmRhdGU8L2NvZGU+LjwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFFOYW1lIERBVEUgPSBuZXcgUU5hbWUoWE1MQ29uc3RhbnRzLlczQ19YTUxfU0NIRU1BX05TX1VSSSwgImRhdGUiKTsKKworICAgIC8qKgorICAgICAqIDxwPkZ1bGx5IHF1YWxpZmllZCBuYW1lIGZvciBXM0MgWE1MIFNjaGVtYSAxLjAgZGF0YXR5cGUgPGNvZGU+Z1llYXJNb250aDwvY29kZT4uPC9wPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUU5hbWUgR1lFQVJNT05USCA9IG5ldyBRTmFtZShYTUxDb25zdGFudHMuVzNDX1hNTF9TQ0hFTUFfTlNfVVJJLCAiZ1llYXJNb250aCIpOworCisgICAgLyoqCisgICAgICogPHA+RnVsbHkgcXVhbGlmaWVkIG5hbWUgZm9yIFczQyBYTUwgU2NoZW1hIDEuMCBkYXRhdHlwZSA8Y29kZT5nTW9udGhEYXk8L2NvZGU+LjwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFFOYW1lIEdNT05USERBWSA9IG5ldyBRTmFtZShYTUxDb25zdGFudHMuVzNDX1hNTF9TQ0hFTUFfTlNfVVJJLCAiZ01vbnRoRGF5Iik7CisKKyAgICAvKioKKyAgICAgKiA8cD5GdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgVzNDIFhNTCBTY2hlbWEgMS4wIGRhdGF0eXBlIDxjb2RlPmdZZWFyPC9jb2RlPi48L3A+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBRTmFtZSBHWUVBUiA9IG5ldyBRTmFtZShYTUxDb25zdGFudHMuVzNDX1hNTF9TQ0hFTUFfTlNfVVJJLCAiZ1llYXIiKTsKKworICAgIC8qKgorICAgICAqIDxwPkZ1bGx5IHF1YWxpZmllZCBuYW1lIGZvciBXM0MgWE1MIFNjaGVtYSAxLjAgZGF0YXR5cGUgPGNvZGU+Z01vbnRoPC9jb2RlPi48L3A+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBRTmFtZSBHTU9OVEggPSBuZXcgUU5hbWUoWE1MQ29uc3RhbnRzLlczQ19YTUxfU0NIRU1BX05TX1VSSSwgImdNb250aCIpOworCisgICAgLyoqCisgICAgICogPHA+RnVsbHkgcXVhbGlmaWVkIG5hbWUgZm9yIFczQyBYTUwgU2NoZW1hIDEuMCBkYXRhdHlwZSA8Y29kZT5nRGF5PC9jb2RlPi48L3A+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBRTmFtZSBHREFZID0gbmV3IFFOYW1lKFhNTENvbnN0YW50cy5XM0NfWE1MX1NDSEVNQV9OU19VUkksICJnRGF5Iik7CisKKyAgICAvKioKKyAgICAgKiA8cD5GdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgVzNDIFhNTCBTY2hlbWEgZGF0YXR5cGUgPGNvZGU+ZHVyYXRpb248L2NvZGU+LjwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFFOYW1lIERVUkFUSU9OID0gbmV3IFFOYW1lKFhNTENvbnN0YW50cy5XM0NfWE1MX1NDSEVNQV9OU19VUkksICJkdXJhdGlvbiIpOworCisgICAgLyoqCisgICAgICogPHA+RnVsbHkgcXVhbGlmaWVkIG5hbWUgZm9yIFhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBkYXRhdHlwZSA8Y29kZT5kYXlUaW1lRHVyYXRpb248L2NvZGU+LjwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFFOYW1lIERVUkFUSU9OX0RBWVRJTUUgPSBuZXcgUU5hbWUoWE1MQ29uc3RhbnRzLlczQ19YUEFUSF9EQVRBVFlQRV9OU19VUkksICJkYXlUaW1lRHVyYXRpb24iKTsKKworICAgIC8qKgorICAgICAqIDxwPkZ1bGx5IHF1YWxpZmllZCBuYW1lIGZvciBYUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgZGF0YXR5cGUgPGNvZGU+eWVhck1vbnRoRHVyYXRpb248L2NvZGU+LjwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFFOYW1lIERVUkFUSU9OX1lFQVJNT05USCA9IG5ldyBRTmFtZShYTUxDb25zdGFudHMuVzNDX1hQQVRIX0RBVEFUWVBFX05TX1VSSSwgInllYXJNb250aER1cmF0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBXM0MgWE1MIFNjaGVtYSBtYXggdGltZXpvbmUgb2Zmc2V0IGlzIC0xNDowMC4gWm9uZSBvZmZzZXQgaXMgaW4gbWludXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfVElNRVpPTkVfT0ZGU0VUID0gLTE0ICogNjA7CisKKyAgICAvKioKKyAgICAgKiBXM0MgWE1MIFNjaGVtYSBtaW4gdGltZXpvbmUgb2Zmc2V0IGlzICsxNDowMC4gWm9uZSBvZmZzZXQgaXMgaW4gbWludXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNSU5fVElNRVpPTkVfT0ZGU0VUID0gMTQgKiA2MDsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9kYXRhdHlwZS9EYXRhdHlwZUZhY3RvcnkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvZGF0YXR5cGUvRGF0YXR5cGVGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmE4OWRhZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvZGF0YXR5cGUvRGF0YXR5cGVGYWN0b3J5LmphdmEKQEAgLTAsMCArMSwxMDI0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8kSWQ6IERhdGF0eXBlRmFjdG9yeS5qYXZhIDg4NDk1MCAyMDA5LTExLTI3IDE4OjQ2OjE4WiBtcmdsYXZhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLmRhdGF0eXBlOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7CitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyOworCisvKioKKyAqIDxwPkZhY3RvcnkgdGhhdCBjcmVhdGVzIG5ldyA8Y29kZT5qYXZheC54bWwuZGF0YXR5cGU8L2NvZGU+IDxjb2RlPk9iamVjdDwvY29kZT5zIHRoYXQgbWFwIFhNTCB0by9mcm9tIEphdmEgPGNvZGU+T2JqZWN0PC9jb2RlPnMuPC9wPgorICoKKyAqIDxwIGlkPSJEYXRhdHlwZUZhY3RvcnkubmV3SW5zdGFuY2UiPntAbGluayAjbmV3SW5zdGFuY2UoKX0gaXMgdXNlZCB0byBjcmVhdGUgYSBuZXcgPGNvZGU+RGF0YXR5cGVGYWN0b3J5PC9jb2RlPi4KKyAqIFRoZSBmb2xsb3dpbmcgaW1wbGVtZW50YXRpb24gcmVzb2x1dGlvbiBtZWNoYW5pc21zIGFyZSB1c2VkIGluIHRoZSBmb2xsb3dpbmcgb3JkZXI6PC9wPgorICogPG9sPgorICogICAgPGxpPgorICogICAgICBJZiB0aGUgc3lzdGVtIHByb3BlcnR5IHNwZWNpZmllZCBieSB7QGxpbmsgI0RBVEFUWVBFRkFDVE9SWV9QUk9QRVJUWX0sICI8Y29kZT5qYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVGYWN0b3J5PC9jb2RlPiIsCisgKiAgICAgIGV4aXN0cywgYSBjbGFzcyB3aXRoIHRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSdzIHZhbHVlIGlzIGluc3RhbnRpYXRlZC4KKyAqICAgICAgQW55IEV4Y2VwdGlvbiB0aHJvd24gZHVyaW5nIHRoZSBpbnN0YW50aWF0aW9uIHByb2Nlc3MgaXMgd3JhcHBlZCBhcyBhIHtAbGluayBEYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb259LgorICogICAgPC9saT4KKyAqICAgIDxsaT4KKyAqICAgICAgSWYgdGhlIGZpbGUgJHtKQVZBX0hPTUV9L2xpYi9qYXhwLnByb3BlcnRpZXMgZXhpc3RzLCBpdCBpcyBsb2FkZWQgaW4gYSB7QGxpbmsgamF2YS51dGlsLlByb3BlcnRpZXN9IDxjb2RlPk9iamVjdDwvY29kZT4uCisgKiAgICAgIFRoZSA8Y29kZT5Qcm9wZXJ0aWVzPC9jb2RlPiA8Y29kZT5PYmplY3QgPC9jb2RlPiBpcyB0aGVuIHF1ZXJpZWQgZm9yIHRoZSBwcm9wZXJ0eSBhcyBkb2N1bWVudGVkIGluIHRoZSBwcmlvciBzdGVwCisgKiAgICAgIGFuZCBwcm9jZXNzZWQgYXMgZG9jdW1lbnRlZCBpbiB0aGUgcHJpb3Igc3RlcC4KKyAqICAgIDwvbGk+CisgKiAgICA8bGk+CisgKiAgICAgIFRoZSBzZXJ2aWNlcyByZXNvbHV0aW9uIG1lY2hhbmlzbSBpcyB1c2VkLCBlLmcuIDxjb2RlPk1FVEEtSU5GL3NlcnZpY2VzL2phdmEueG1sLmRhdGF0eXBlLkRhdGF0eXBlRmFjdG9yeTwvY29kZT4uCisgKiAgICAgIEFueSBFeGNlcHRpb24gdGhyb3duIGR1cmluZyB0aGUgaW5zdGFudGlhdGlvbiBwcm9jZXNzIGlzIHdyYXBwZWQgYXMgYSB7QGxpbmsgRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9ufS4KKyAqICAgIDwvbGk+CisgKiAgICA8bGk+CisgKiAgICAgIFRoZSBmaW5hbCBtZWNoYW5pc20gaXMgdG8gYXR0ZW1wdCB0byBpbnN0YW50aWF0ZSB0aGUgPGNvZGU+Q2xhc3M8L2NvZGU+IHNwZWNpZmllZCBieQorICogICAgICB7QGxpbmsgI0RBVEFUWVBFRkFDVE9SWV9JTVBMRU1FTlRBVElPTl9DTEFTU30sICI8Y29kZT5qYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVGYWN0b3J5SW1wbDwvY29kZT4iLgorICogICAgICBBbnkgRXhjZXB0aW9uIHRocm93biBkdXJpbmcgdGhlIGluc3RhbnRpYXRpb24gcHJvY2VzcyBpcyB3cmFwcGVkIGFzIGEge0BsaW5rIERhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbn0uCisgKiAgICA8L2xpPgorICogPC9vbD4KKyAqCisgKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKb3NlcGguRmlhbGxpQFN1bi5DT00iPkpvc2VwaCBGaWFsbGk8L2E+CisgKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogODg0OTUwICQsICREYXRlOiAyMDA5LTExLTI3IDEwOjQ2OjE4IC0wODAwIChGcmksIDI3IE5vdiAyMDA5KSAkCisgKiBAc2luY2UgMS41CisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBEYXRhdHlwZUZhY3RvcnkgeworCisgICAgLyoqCisgICAgICogPHA+RGVmYXVsdCBwcm9wZXJ0eSBuYW1lIGFzIGRlZmluZWQgaW4gSlNSIDIwNjogSmF2YShUTSkgQVBJIGZvciBYTUwgUHJvY2Vzc2luZyAoSkFYUCkgMS4zLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkRlZmF1bHQgdmFsdWUgaXMgPGNvZGU+amF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlRmFjdG9yeTwvY29kZT4uPC9wPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERBVEFUWVBFRkFDVE9SWV9QUk9QRVJUWSA9ICJqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVGYWN0b3J5IjsKKworICAgIC8qKgorICAgICAqIDxwPkRlZmF1bHQgaW1wbGVtZW50YXRpb24gY2xhc3MgbmFtZSBhcyBkZWZpbmVkIGluIEpTUiAyMDY6IEphdmEoVE0pIEFQSSBmb3IgWE1MIFByb2Nlc3NpbmcgKEpBWFApIDEuMy48L3A+CisgICAgICoKKyAgICAgKiA8cD5EZWZhdWx0IHZhbHVlIGlzIDxjb2RlPm9yZy5hcGFjaGUueGVyY2VzLmpheHAuZGF0YXR5cGUuRGF0YXR5cGVGYWN0b3J5SW1wbDwvY29kZT4uPC9wPgorICAgICAqLworICAgIC8vIFRoaXMgdXNlcyAibmV3IFN0cmluZyIgdG8gYXZvaWQgYmVpbmcgaW5saW5lZCBhcyBhIGNvbnN0YW50LgorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERBVEFUWVBFRkFDVE9SWV9JTVBMRU1FTlRBVElPTl9DTEFTUyA9IG5ldyBTdHJpbmcoIm9yZy5hcGFjaGUueGVyY2VzLmpheHAuZGF0YXR5cGUuRGF0YXR5cGVGYWN0b3J5SW1wbCIpOworCisgICAgLyoqCisgICAgICogPHA+UHJvdGVjdGVkIGNvbnN0cnVjdG9yIHRvIHByZXZlbnQgaW5zdGFudGlhdGlvbiBvdXRzaWRlIG9mIHBhY2thZ2UuPC9wPgorICAgICAqCisgICAgICogPHA+VXNlIHtAbGluayAjbmV3SW5zdGFuY2UoKX0gdG8gY3JlYXRlIGEgPGNvZGU+RGF0YXR5cGVGYWN0b3J5PC9jb2RlPi48L3A+CisgICAgICovCisgICAgcHJvdGVjdGVkIERhdGF0eXBlRmFjdG9yeSgpIHt9CisKKyAgICAvKioKKyAgICAgKiA8cD5PYnRhaW4gYSBuZXcgaW5zdGFuY2Ugb2YgYSA8Y29kZT5EYXRhdHlwZUZhY3Rvcnk8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBpbXBsZW1lbnRhdGlvbiByZXNvbHV0aW9uIG1lY2hhbmlzbXMgYXJlIDxhIGhyZWY9IiNEYXRhdHlwZUZhY3RvcnkubmV3SW5zdGFuY2UiPmRlZmluZWQ8L2E+IGluIHRoaXMKKyAgICAgKiA8Y29kZT5DbGFzczwvY29kZT4ncyBkb2N1bWVudGF0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gTmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTwvY29kZT4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uIElmIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBub3QKKyAgICAgKiAgIGF2YWlsYWJsZSBvciBjYW5ub3QgYmUgaW5zdGFudGlhdGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgRGF0YXR5cGVGYWN0b3J5IG5ld0luc3RhbmNlKCkKKyAgICAgICAgdGhyb3dzIERhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gKERhdGF0eXBlRmFjdG9yeSkgRmFjdG9yeUZpbmRlci5maW5kKAorICAgICAgICAgICAgICAgICAgICAvKiBUaGUgZGVmYXVsdCBwcm9wZXJ0eSBuYW1lIGFjY29yZGluZyB0byB0aGUgSkFYUCBzcGVjICovCisgICAgICAgICAgICAgICAgICAgIERBVEFUWVBFRkFDVE9SWV9QUk9QRVJUWSwKKyAgICAgICAgICAgICAgICAgICAgLyogVGhlIGZhbGxiYWNrIGltcGxlbWVudGF0aW9uIGNsYXNzIG5hbWUgKi8KKyAgICAgICAgICAgICAgICAgICAgREFUQVRZUEVGQUNUT1JZX0lNUExFTUVOVEFUSU9OX0NMQVNTKTsKKyAgICAgICAgfQorICAgICAgICBjYXRjaCAoRmFjdG9yeUZpbmRlci5Db25maWd1cmF0aW9uRXJyb3IgZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IERhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSwgZS5nZXRFeGNlcHRpb24oKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIHRoZSBuYW1lZCBpbXBsZW1lbnRhdGlvbiBvZiB7QGNvZGUgRGF0YXR5cGVGYWN0b3J5fS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uIGlmIHtAY29kZSBmYWN0b3J5Q2xhc3NOYW1lfSBpcyBub3QgYXZhaWxhYmxlIG9yIGNhbm5vdAorICAgICAqICAgICBiZSBpbnN0YW50aWF0ZWQuCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgRGF0YXR5cGVGYWN0b3J5IG5ld0luc3RhbmNlKFN0cmluZyBmYWN0b3J5Q2xhc3NOYW1lLCBDbGFzc0xvYWRlciBjbGFzc0xvYWRlcikKKyAgICAgICAgICAgIHRocm93cyBEYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb24geworICAgICAgICBpZiAoZmFjdG9yeUNsYXNzTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uKCJmYWN0b3J5Q2xhc3NOYW1lID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2xhc3NMb2FkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgY2xhc3NMb2FkZXIgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDbGFzczw/PiB0eXBlID0gY2xhc3NMb2FkZXIgIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICA/IGNsYXNzTG9hZGVyLmxvYWRDbGFzcyhmYWN0b3J5Q2xhc3NOYW1lKQorICAgICAgICAgICAgICAgICAgICA6IENsYXNzLmZvck5hbWUoZmFjdG9yeUNsYXNzTmFtZSk7CisgICAgICAgICAgICByZXR1cm4gKERhdGF0eXBlRmFjdG9yeSkgdHlwZS5uZXdJbnN0YW5jZSgpOworICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBEYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb24oZSk7CisgICAgICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IERhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihlKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+T2J0YWluIGEgbmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+RHVyYXRpb248L2NvZGU+CisgICAgICogc3BlY2lmeWluZyB0aGUgPGNvZGU+RHVyYXRpb248L2NvZGU+IGFzIGl0cyBzdHJpbmcgcmVwcmVzZW50YXRpb24sICJQblluTW5EVG5Ibk1uUyIsCisgICAgICogYXMgZGVmaW5lZCBpbiBYTUwgU2NoZW1hIDEuMCBzZWN0aW9uIDMuMi42LjEuPC9wPgorICAgICAqCisgICAgICogPHA+WE1MIFNjaGVtYSBQYXJ0IDI6IERhdGF0eXBlcywgMy4yLjYgZHVyYXRpb24sIGRlZmluZXMgPGNvZGU+ZHVyYXRpb248L2NvZGU+IGFzOjwvcD4KKyAgICAgKiA8YmxvY2txdW90ZT4KKyAgICAgKiBkdXJhdGlvbiByZXByZXNlbnRzIGEgZHVyYXRpb24gb2YgdGltZS4KKyAgICAgKiBUaGUgdmFsdWUgc3BhY2Ugb2YgZHVyYXRpb24gaXMgYSBzaXgtZGltZW5zaW9uYWwgc3BhY2Ugd2hlcmUgdGhlIGNvb3JkaW5hdGVzIGRlc2lnbmF0ZSB0aGUKKyAgICAgKiBHcmVnb3JpYW4geWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBhbmQgc2Vjb25kIGNvbXBvbmVudHMgZGVmaW5lZCBpbiBTZWN0aW9uIDUuNS4zLjIgb2YgW0lTTyA4NjAxXSwgcmVzcGVjdGl2ZWx5LgorICAgICAqIFRoZXNlIGNvbXBvbmVudHMgYXJlIG9yZGVyZWQgaW4gdGhlaXIgc2lnbmlmaWNhbmNlIGJ5IHRoZWlyIG9yZGVyIG9mIGFwcGVhcmFuY2UgaS5lLiBhcworICAgICAqIHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgYW5kIHNlY29uZC4KKyAgICAgKiA8L2Jsb2NrcXVvdGU+CisgICAgICogPHA+QWxsIHNpeCB2YWx1ZXMgYXJlIHNldCBhbmQgYXZhaWxhYmxlIGZyb20gdGhlIGNyZWF0ZWQge0BsaW5rIER1cmF0aW9ufTwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBYTUwgU2NoZW1hIHNwZWNpZmljYXRpb24gc3RhdGVzIHRoYXQgdmFsdWVzIGNhbiBiZSBvZiBhbiBhcmJpdHJhcnkgc2l6ZS4KKyAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbWF5IGNob3NlIG5vdCB0byBvciBiZSBpbmNhcGFibGUgb2Ygc3VwcG9ydGluZyBhcmJpdHJhcmlseSBsYXJnZSBhbmQvb3Igc21hbGwgdmFsdWVzLgorICAgICAqIEFuIHtAbGluayBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gd2l0aCBhIG1lc3NhZ2UgaW5kaWNhdGluZyBpbXBsZW1lbnRhdGlvbiBsaW1pdHMKKyAgICAgKiBpZiBpbXBsZW1lbnRhdGlvbiBjYXBhY2l0aWVzIGFyZSBleGNlZWRlZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbGV4aWNhbFJlcHJlc2VudGF0aW9uIDxjb2RlPlN0cmluZzwvY29kZT4gcmVwcmVzZW50YXRpb24gb2YgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCBmcm9tIHBhcnNpbmcgdGhlIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiA8Y29kZT5sZXhpY2FsUmVwcmVzZW50YXRpb248L2NvZGU+IGlzIG5vdCBhIHZhbGlkIHJlcHJlc2VudGF0aW9uIG9mIGEgPGNvZGU+RHVyYXRpb248L2NvZGU+LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gSWYgaW1wbGVtZW50YXRpb24gY2Fubm90IHN1cHBvcnQgcmVxdWVzdGVkIHZhbHVlcy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IER1cmF0aW9uIG5ld0R1cmF0aW9uKGZpbmFsIFN0cmluZyBsZXhpY2FsUmVwcmVzZW50YXRpb24pOworCisgICAgLyoqCisgICAgICogPHA+T2J0YWluIGEgbmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+RHVyYXRpb248L2NvZGU+CisgICAgICogc3BlY2lmeWluZyB0aGUgPGNvZGU+RHVyYXRpb248L2NvZGU+IGFzIG1pbGxpc2Vjb25kcy48L3A+CisgICAgICoKKyAgICAgKiA8cD5YTUwgU2NoZW1hIFBhcnQgMjogRGF0YXR5cGVzLCAzLjIuNiBkdXJhdGlvbiwgZGVmaW5lcyA8Y29kZT5kdXJhdGlvbjwvY29kZT4gYXM6PC9wPgorICAgICAqIDxibG9ja3F1b3RlPgorICAgICAqIGR1cmF0aW9uIHJlcHJlc2VudHMgYSBkdXJhdGlvbiBvZiB0aW1lLgorICAgICAqIFRoZSB2YWx1ZSBzcGFjZSBvZiBkdXJhdGlvbiBpcyBhIHNpeC1kaW1lbnNpb25hbCBzcGFjZSB3aGVyZSB0aGUgY29vcmRpbmF0ZXMgZGVzaWduYXRlIHRoZQorICAgICAqIEdyZWdvcmlhbiB5ZWFyLCBtb250aCwgZGF5LCBob3VyLCBtaW51dGUsIGFuZCBzZWNvbmQgY29tcG9uZW50cyBkZWZpbmVkIGluIFNlY3Rpb24gNS41LjMuMiBvZiBbSVNPIDg2MDFdLCByZXNwZWN0aXZlbHkuCisgICAgICogVGhlc2UgY29tcG9uZW50cyBhcmUgb3JkZXJlZCBpbiB0aGVpciBzaWduaWZpY2FuY2UgYnkgdGhlaXIgb3JkZXIgb2YgYXBwZWFyYW5jZSBpLmUuIGFzCisgICAgICogeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBhbmQgc2Vjb25kLgorICAgICAqIDwvYmxvY2txdW90ZT4KKyAgICAgKiA8cD5BbGwgc2l4IHZhbHVlcyBhcmUgc2V0IGJ5IGNvbXB1dGluZyB0aGVpciB2YWx1ZXMgZnJvbSB0aGUgc3BlY2lmaWVkIG1pbGxpc2Vjb25kcworICAgICAqIGFuZCBhcmUgYXZhaWxhYmxlIHVzaW5nIHRoZSA8Y29kZT5nZXQ8L2NvZGU+IG1ldGhvZHMgb2YgIHRoZSBjcmVhdGVkIHtAbGluayBEdXJhdGlvbn0uCisgICAgICogVGhlIHZhbHVlcyBjb25mb3JtIHRvIGFuZCBhcmUgZGVmaW5lZCBieTo8L3A+CisgICAgICogPHVsPgorICAgICAqICAgPGxpPklTTyA4NjAxOjIwMDAoRSkgU2VjdGlvbiA1LjUuMy4yIEFsdGVybmF0aXZlIGZvcm1hdDwvbGk+CisgICAgICogICA8bGk+PGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2lzb2Zvcm1hdHMiPgorICAgICAqICAgICBXM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBBcHBlbmRpeCBELCBJU08gODYwMSBEYXRlIGFuZCBUaW1lIEZvcm1hdHM8L2E+CisgICAgICogICA8L2xpPgorICAgICAqICAgPGxpPntAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhcn0gIERhdGUvVGltZSBEYXRhdHlwZSBGaWVsZCBNYXBwaW5nIEJldHdlZW4gWE1MIFNjaGVtYSAxLjAgYW5kIEphdmEgUmVwcmVzZW50YXRpb248L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiA8cD5UaGUgZGVmYXVsdCBzdGFydCBpbnN0YW5jZSBpcyBkZWZpbmVkIGJ5IHtAbGluayBHcmVnb3JpYW5DYWxlbmRhcn0ncyB1c2Ugb2YgdGhlIHN0YXJ0IG9mIHRoZSBlcG9jaDogaS5lLiwKKyAgICAgKiB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI1lFQVJ9ID0gMTk3MCwKKyAgICAgKiB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI01PTlRIfSA9IHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjSkFOVUFSWX0sCisgICAgICoge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNEQVRFfSA9IDEsIGV0Yy4KKyAgICAgKiBUaGlzIGlzIGltcG9ydGFudCBhcyB0aGVyZSBhcmUgdmFyaWF0aW9ucyBpbiB0aGUgR3JlZ29yaWFuIENhbGVuZGFyLAorICAgICAqIGUuZy4gbGVhcCB5ZWFycyBoYXZlIGRpZmZlcmVudCBkYXlzIGluIHRoZSBtb250aCA9IHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjRkVCUlVBUll9CisgICAgICogc28gdGhlIHJlc3VsdCBvZiB7QGxpbmsgRHVyYXRpb24jZ2V0TW9udGhzKCl9IGFuZCB7QGxpbmsgRHVyYXRpb24jZ2V0RGF5cygpfSBjYW4gYmUgaW5mbHVlbmNlZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZHVyYXRpb25Jbk1pbGxpU2Vjb25kcyBEdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMgdG8gY3JlYXRlLgorICAgICAqCisgICAgICogQHJldHVybiBOZXcgPGNvZGU+RHVyYXRpb248L2NvZGU+IHJlcHJlc2VudGluZyA8Y29kZT5kdXJhdGlvbkluTWlsbGlTZWNvbmRzPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRHVyYXRpb24gbmV3RHVyYXRpb24oZmluYWwgbG9uZyBkdXJhdGlvbkluTWlsbGlTZWNvbmRzKTsKKworICAgIC8qKgorICAgICAqIDxwPk9idGFpbiBhIG5ldyBpbnN0YW5jZSBvZiBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPgorICAgICAqIHNwZWNpZnlpbmcgdGhlIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBhcyBpc1Bvc2l0aXZlLCB5ZWFycywgbW9udGhzLCBkYXlzLCBob3VycywgbWludXRlcywgc2Vjb25kcy48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgWE1MIFNjaGVtYSBzcGVjaWZpY2F0aW9uIHN0YXRlcyB0aGF0IHZhbHVlcyBjYW4gYmUgb2YgYW4gYXJiaXRyYXJ5IHNpemUuCisgICAgICogSW1wbGVtZW50YXRpb25zIG1heSBjaG9zZSBub3QgdG8gb3IgYmUgaW5jYXBhYmxlIG9mIHN1cHBvcnRpbmcgYXJiaXRyYXJpbHkgbGFyZ2UgYW5kL29yIHNtYWxsIHZhbHVlcy4KKyAgICAgKiBBbiB7QGxpbmsgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259IHdpbGwgYmUgdGhyb3duIHdpdGggYSBtZXNzYWdlIGluZGljYXRpbmcgaW1wbGVtZW50YXRpb24gbGltaXRzCisgICAgICogaWYgaW1wbGVtZW50YXRpb24gY2FwYWNpdGllcyBhcmUgZXhjZWVkZWQuPC9wPgorICAgICAqCisgICAgICogPHA+QSA8Y29kZT5udWxsPC9jb2RlPiB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCBmaWVsZCBpcyBub3Qgc2V0LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpc1Bvc2l0aXZlIFNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4gdG8gY3JlYXRlIGEgbmVnYXRpdmUgZHVyYXRpb24uIFdoZW4gdGhlIGxlbmd0aAorICAgICAqICAgb2YgdGhlIGR1cmF0aW9uIGlzIHplcm8sIHRoaXMgcGFyYW1ldGVyIHdpbGwgYmUgaWdub3JlZC4KKyAgICAgKiBAcGFyYW0geWVhcnMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KKyAgICAgKiBAcGFyYW0gbW9udGhzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+CisgICAgICogQHBhcmFtIGRheXMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KKyAgICAgKiBAcGFyYW0gaG91cnMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KKyAgICAgKiBAcGFyYW0gbWludXRlcyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPgorICAgICAqIEBwYXJhbSBzZWNvbmRzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCBmcm9tIHRoZSBzcGVjaWZpZWQgdmFsdWVzLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdmFsdWVzIGFyZSBub3QgYSB2YWxpZCByZXByZXNlbnRhdGlvbiBvZiBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIElmIGltcGxlbWVudGF0aW9uIGNhbm5vdCBzdXBwb3J0IHJlcXVlc3RlZCB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IER1cmF0aW9uIG5ld0R1cmF0aW9uKAorICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBpc1Bvc2l0aXZlLAorICAgICAgICAgICAgZmluYWwgQmlnSW50ZWdlciB5ZWFycywKKyAgICAgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgbW9udGhzLAorICAgICAgICAgICAgZmluYWwgQmlnSW50ZWdlciBkYXlzLAorICAgICAgICAgICAgZmluYWwgQmlnSW50ZWdlciBob3VycywKKyAgICAgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgbWludXRlcywKKyAgICAgICAgICAgIGZpbmFsIEJpZ0RlY2ltYWwgc2Vjb25kcyk7CisKKyAgICAvKioKKyAgICAgKiA8cD5PYnRhaW4gYSBuZXcgaW5zdGFuY2Ugb2YgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4KKyAgICAgKiBzcGVjaWZ5aW5nIHRoZSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gYXMgaXNQb3NpdGl2ZSwgeWVhcnMsIG1vbnRocywgZGF5cywgaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMuPC9wPgorICAgICAqCisgICAgICogPHA+QSB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCBmaWVsZCBpcyBub3Qgc2V0LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpc1Bvc2l0aXZlIFNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4gdG8gY3JlYXRlIGEgbmVnYXRpdmUgZHVyYXRpb24uIFdoZW4gdGhlIGxlbmd0aAorICAgICAqICAgb2YgdGhlIGR1cmF0aW9uIGlzIHplcm8sIHRoaXMgcGFyYW1ldGVyIHdpbGwgYmUgaWdub3JlZC4KKyAgICAgKiBAcGFyYW0geWVhcnMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KKyAgICAgKiBAcGFyYW0gbW9udGhzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+CisgICAgICogQHBhcmFtIGRheXMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KKyAgICAgKiBAcGFyYW0gaG91cnMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KKyAgICAgKiBAcGFyYW0gbWludXRlcyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPgorICAgICAqIEBwYXJhbSBzZWNvbmRzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCBmcm9tIHRoZSBzcGVjaWZpZWQgdmFsdWVzLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdmFsdWVzIGFyZSBub3QgYSB2YWxpZCByZXByZXNlbnRhdGlvbiBvZiBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBzZWUgI25ld0R1cmF0aW9uKAorICAgICAqICAgYm9vbGVhbiBpc1Bvc2l0aXZlLAorICAgICAqICAgQmlnSW50ZWdlciB5ZWFycywKKyAgICAgKiAgIEJpZ0ludGVnZXIgbW9udGhzLAorICAgICAqICAgQmlnSW50ZWdlciBkYXlzLAorICAgICAqICAgQmlnSW50ZWdlciBob3VycywKKyAgICAgKiAgIEJpZ0ludGVnZXIgbWludXRlcywKKyAgICAgKiAgIEJpZ0RlY2ltYWwgc2Vjb25kcykKKyAgICAgKi8KKyAgICBwdWJsaWMgRHVyYXRpb24gbmV3RHVyYXRpb24oCisgICAgICAgICAgICBmaW5hbCBib29sZWFuIGlzUG9zaXRpdmUsCisgICAgICAgICAgICBmaW5hbCBpbnQgeWVhcnMsCisgICAgICAgICAgICBmaW5hbCBpbnQgbW9udGhzLAorICAgICAgICAgICAgZmluYWwgaW50IGRheXMsCisgICAgICAgICAgICBmaW5hbCBpbnQgaG91cnMsCisgICAgICAgICAgICBmaW5hbCBpbnQgbWludXRlcywKKyAgICAgICAgICAgIGZpbmFsIGludCBzZWNvbmRzKSB7CisKKyAgICAgICAgLy8geWVhcnMgbWF5IG5vdCBiZSBzZXQKKyAgICAgICAgQmlnSW50ZWdlciByZWFsWWVhcnMgPSAoeWVhcnMgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSA/IEJpZ0ludGVnZXIudmFsdWVPZigobG9uZykgeWVhcnMpIDogbnVsbDsKKworICAgICAgICAvLyBtb250aHMgbWF5IG5vdCBiZSBzZXQKKyAgICAgICAgQmlnSW50ZWdlciByZWFsTW9udGhzID0gKG1vbnRocyAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpID8gQmlnSW50ZWdlci52YWx1ZU9mKChsb25nKSBtb250aHMpIDogbnVsbDsKKworICAgICAgICAvLyBkYXlzIG1heSBub3QgYmUgc2V0CisgICAgICAgIEJpZ0ludGVnZXIgcmVhbERheXMgPSAoZGF5cyAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpID8gQmlnSW50ZWdlci52YWx1ZU9mKChsb25nKSBkYXlzKSA6IG51bGw7CisKKyAgICAgICAgLy8gaG91cnMgbWF5IG5vdCBiZSBzZXQKKyAgICAgICAgQmlnSW50ZWdlciByZWFsSG91cnMgPSAoaG91cnMgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSA/IEJpZ0ludGVnZXIudmFsdWVPZigobG9uZykgaG91cnMpIDogbnVsbDsKKworICAgICAgICAvLyBtaW51dGVzIG1heSBub3QgYmUgc2V0CisgICAgICAgIEJpZ0ludGVnZXIgcmVhbE1pbnV0ZXMgPSAobWludXRlcyAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpID8gQmlnSW50ZWdlci52YWx1ZU9mKChsb25nKSBtaW51dGVzKSA6IG51bGw7CisKKyAgICAgICAgLy8gc2Vjb25kcyBtYXkgbm90IGJlIHNldAorICAgICAgICBCaWdEZWNpbWFsIHJlYWxTZWNvbmRzID0gKHNlY29uZHMgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSA/IEJpZ0RlY2ltYWwudmFsdWVPZigobG9uZykgc2Vjb25kcykgOiBudWxsOworCisgICAgICAgIHJldHVybiBuZXdEdXJhdGlvbigKKyAgICAgICAgICAgICAgICBpc1Bvc2l0aXZlLAorICAgICAgICAgICAgICAgIHJlYWxZZWFycywKKyAgICAgICAgICAgICAgICByZWFsTW9udGhzLAorICAgICAgICAgICAgICAgIHJlYWxEYXlzLAorICAgICAgICAgICAgICAgIHJlYWxIb3VycywKKyAgICAgICAgICAgICAgICByZWFsTWludXRlcywKKyAgICAgICAgICAgICAgICByZWFsU2Vjb25kcworICAgICAgICApOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkNyZWF0ZSBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvZiB0eXBlIDxjb2RlPnhkdDpkYXlUaW1lRHVyYXRpb248L2NvZGU+IGJ5IHBhcnNpbmcgaXRzIDxjb2RlPlN0cmluZzwvY29kZT4gcmVwcmVzZW50YXRpb24sCisgICAgICogIjxlbT5QbkRUbkhuTW5TPC9lbT4iLCA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjZHQtZGF5VGltZUR1cmF0aW9uIj4KKyAgICAgKiAgIFhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6ZGF5VGltZUR1cmF0aW9uPC9hPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgZGF0YXR5cGUgPGNvZGU+eGR0OmRheVRpbWVEdXJhdGlvbjwvY29kZT4gaXMgYSBzdWJ0eXBlIG9mIDxjb2RlPnhzOmR1cmF0aW9uPC9jb2RlPgorICAgICAqIHdob3NlIGxleGljYWwgcmVwcmVzZW50YXRpb24gY29udGFpbnMgb25seSBkYXksIGhvdXIsIG1pbnV0ZSwgYW5kIHNlY29uZCBjb21wb25lbnRzLgorICAgICAqIFRoaXMgZGF0YXR5cGUgcmVzaWRlcyBpbiB0aGUgbmFtZXNwYWNlIDxjb2RlPmh0dHA6Ly93d3cudzMub3JnLzIwMDMvMTEveHBhdGgtZGF0YXR5cGVzPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5BbGwgZm91ciB2YWx1ZXMgYXJlIHNldCBhbmQgYXZhaWxhYmxlIGZyb20gdGhlIGNyZWF0ZWQge0BsaW5rIER1cmF0aW9ufTwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBYTUwgU2NoZW1hIHNwZWNpZmljYXRpb24gc3RhdGVzIHRoYXQgdmFsdWVzIGNhbiBiZSBvZiBhbiBhcmJpdHJhcnkgc2l6ZS4KKyAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbWF5IGNob3NlIG5vdCB0byBvciBiZSBpbmNhcGFibGUgb2Ygc3VwcG9ydGluZyBhcmJpdHJhcmlseSBsYXJnZSBhbmQvb3Igc21hbGwgdmFsdWVzLgorICAgICAqIEFuIHtAbGluayBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gd2l0aCBhIG1lc3NhZ2UgaW5kaWNhdGluZyBpbXBsZW1lbnRhdGlvbiBsaW1pdHMKKyAgICAgKiBpZiBpbXBsZW1lbnRhdGlvbiBjYXBhY2l0aWVzIGFyZSBleGNlZWRlZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbGV4aWNhbFJlcHJlc2VudGF0aW9uIExleGljYWwgcmVwcmVzZW50YXRpb24gb2YgYSBkdXJhdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gTmV3IDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBjcmVhdGVkIHVzaW5nIHRoZSBzcGVjaWZpZWQgPGNvZGU+bGV4aWNhbFJlcHJlc2VudGF0aW9uPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSBnaXZlbiBzdHJpbmcgZG9lcyBub3QgY29uZm9ybSB0byB0aGUgYWZvcmVtZW50aW9uZWQgc3BlY2lmaWNhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIElmIGltcGxlbWVudGF0aW9uIGNhbm5vdCBzdXBwb3J0IHJlcXVlc3RlZCB2YWx1ZXMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5sZXhpY2FsUmVwcmVzZW50YXRpb248L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBEdXJhdGlvbiBuZXdEdXJhdGlvbkRheVRpbWUoZmluYWwgU3RyaW5nIGxleGljYWxSZXByZXNlbnRhdGlvbikgeworICAgICAgICBpZiAobGV4aWNhbFJlcHJlc2VudGF0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiVGhlIGxleGljYWwgcmVwcmVzZW50YXRpb24gY2Fubm90IGJlIG51bGwuIik7CisgICAgICAgIH0KKyAgICAgICAgLy8gVGhlIGxleGljYWwgcmVwcmVzZW50YXRpb24gbXVzdCBtYXRjaCB0aGUgcGF0dGVybiBbXllNXSooVC4qKT8KKyAgICAgICAgaW50IHBvcyA9IGxleGljYWxSZXByZXNlbnRhdGlvbi5pbmRleE9mKCdUJyk7CisgICAgICAgIGludCBsZW5ndGggPSAocG9zID49IDApID8gcG9zIDogbGV4aWNhbFJlcHJlc2VudGF0aW9uLmxlbmd0aCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICBjaGFyIGMgPSBsZXhpY2FsUmVwcmVzZW50YXRpb24uY2hhckF0KGkpOworICAgICAgICAgICAgaWYgKGMgPT0gJ1knIHx8IGMgPT0gJ00nKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBkYXlUaW1lRHVyYXRpb24gdmFsdWU6ICIgKyBsZXhpY2FsUmVwcmVzZW50YXRpb24pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXdEdXJhdGlvbihsZXhpY2FsUmVwcmVzZW50YXRpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkNyZWF0ZSBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvZiB0eXBlIDxjb2RlPnhkdDpkYXlUaW1lRHVyYXRpb248L2NvZGU+IHVzaW5nIHRoZSBzcGVjaWZpZWQgbWlsbGlzZWNvbmRzIGFzIGRlZmluZWQgaW4KKyAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjZHQtZGF5VGltZUR1cmF0aW9uIj4KKyAgICAgKiAgIFhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6ZGF5VGltZUR1cmF0aW9uPC9hPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgZGF0YXR5cGUgPGNvZGU+eGR0OmRheVRpbWVEdXJhdGlvbjwvY29kZT4gaXMgYSBzdWJ0eXBlIG9mIDxjb2RlPnhzOmR1cmF0aW9uPC9jb2RlPgorICAgICAqIHdob3NlIGxleGljYWwgcmVwcmVzZW50YXRpb24gY29udGFpbnMgb25seSBkYXksIGhvdXIsIG1pbnV0ZSwgYW5kIHNlY29uZCBjb21wb25lbnRzLgorICAgICAqIFRoaXMgZGF0YXR5cGUgcmVzaWRlcyBpbiB0aGUgbmFtZXNwYWNlIDxjb2RlPmh0dHA6Ly93d3cudzMub3JnLzIwMDMvMTEveHBhdGgtZGF0YXR5cGVzPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5BbGwgZm91ciB2YWx1ZXMgYXJlIHNldCBieSBjb21wdXRpbmcgdGhlaXIgdmFsdWVzIGZyb20gdGhlIHNwZWNpZmllZCBtaWxsaXNlY29uZHMKKyAgICAgKiBhbmQgYXJlIGF2YWlsYWJsZSB1c2luZyB0aGUgPGNvZGU+Z2V0PC9jb2RlPiBtZXRob2RzIG9mICB0aGUgY3JlYXRlZCB7QGxpbmsgRHVyYXRpb259LgorICAgICAqIFRoZSB2YWx1ZXMgY29uZm9ybSB0byBhbmQgYXJlIGRlZmluZWQgYnk6PC9wPgorICAgICAqIDx1bD4KKyAgICAgKiAgIDxsaT5JU08gODYwMToyMDAwKEUpIFNlY3Rpb24gNS41LjMuMiBBbHRlcm5hdGl2ZSBmb3JtYXQ8L2xpPgorICAgICAqICAgPGxpPjxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNpc29mb3JtYXRzIj4KKyAgICAgKiAgICAgVzNDIFhNTCBTY2hlbWEgMS4wIFBhcnQgMiwgQXBwZW5kaXggRCwgSVNPIDg2MDEgRGF0ZSBhbmQgVGltZSBGb3JtYXRzPC9hPgorICAgICAqICAgPC9saT4KKyAgICAgKiAgIDxsaT57QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXJ9ICBEYXRlL1RpbWUgRGF0YXR5cGUgRmllbGQgTWFwcGluZyBCZXR3ZWVuIFhNTCBTY2hlbWEgMS4wIGFuZCBKYXZhIFJlcHJlc2VudGF0aW9uPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogPHA+VGhlIGRlZmF1bHQgc3RhcnQgaW5zdGFuY2UgaXMgZGVmaW5lZCBieSB7QGxpbmsgR3JlZ29yaWFuQ2FsZW5kYXJ9J3MgdXNlIG9mIHRoZSBzdGFydCBvZiB0aGUgZXBvY2g6IGkuZS4sCisgICAgICoge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNZRUFSfSA9IDE5NzAsCisgICAgICoge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNNT05USH0gPSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0pBTlVBUll9LAorICAgICAqIHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjREFURX0gPSAxLCBldGMuCisgICAgICogVGhpcyBpcyBpbXBvcnRhbnQgYXMgdGhlcmUgYXJlIHZhcmlhdGlvbnMgaW4gdGhlIEdyZWdvcmlhbiBDYWxlbmRhciwKKyAgICAgKiBlLmcuIGxlYXAgeWVhcnMgaGF2ZSBkaWZmZXJlbnQgZGF5cyBpbiB0aGUgbW9udGggPSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0ZFQlJVQVJZfQorICAgICAqIHNvIHRoZSByZXN1bHQgb2Yge0BsaW5rIER1cmF0aW9uI2dldERheXMoKX0gY2FuIGJlIGluZmx1ZW5jZWQuPC9wPgorICAgICAqCisgICAgICogPHA+QW55IHJlbWFpbmluZyBtaWxsaXNlY29uZHMgYWZ0ZXIgZGV0ZXJtaW5pbmcgdGhlIGRheSwgaG91ciwgbWludXRlIGFuZCBzZWNvbmQgYXJlIGRpc2NhcmRlZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZHVyYXRpb25Jbk1pbGxpc2Vjb25kcyBNaWxsaXNlY29uZHMgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+IHRvIGNyZWF0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gTmV3IDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBjcmVhdGVkIHdpdGggdGhlIHNwZWNpZmllZCA8Y29kZT5kdXJhdGlvbkluTWlsbGlzZWNvbmRzPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsI2R0LWRheVRpbWVEdXJhdGlvbiI+CisgICAgICogICBYUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OmRheVRpbWVEdXJhdGlvbjwvYT4KKyAgICAgKi8KKyAgICBwdWJsaWMgRHVyYXRpb24gbmV3RHVyYXRpb25EYXlUaW1lKGZpbmFsIGxvbmcgZHVyYXRpb25Jbk1pbGxpc2Vjb25kcykgeworICAgICAgICBsb25nIF9kdXJhdGlvbkluTWlsbGlzZWNvbmRzID0gZHVyYXRpb25Jbk1pbGxpc2Vjb25kczsKKyAgICAgICAgaWYgKF9kdXJhdGlvbkluTWlsbGlzZWNvbmRzID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBuZXdEdXJhdGlvbih0cnVlLCBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsCisgICAgICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgMCwgMCwgMCwgMCk7CisgICAgICAgIH0KKyAgICAgICAgYm9vbGVhbiB0b29Mb25nID0gZmFsc2U7CisgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNQb3NpdGl2ZTsKKyAgICAgICAgaWYgKF9kdXJhdGlvbkluTWlsbGlzZWNvbmRzIDwgMCkgeworICAgICAgICAgICAgaXNQb3NpdGl2ZSA9IGZhbHNlOworICAgICAgICAgICAgaWYgKF9kdXJhdGlvbkluTWlsbGlzZWNvbmRzID09IExvbmcuTUlOX1ZBTFVFKSB7CisgICAgICAgICAgICAgICAgX2R1cmF0aW9uSW5NaWxsaXNlY29uZHMrKzsKKyAgICAgICAgICAgICAgICB0b29Mb25nID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIF9kdXJhdGlvbkluTWlsbGlzZWNvbmRzICo9IC0xOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgaXNQb3NpdGl2ZSA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICBsb25nIHZhbCA9IF9kdXJhdGlvbkluTWlsbGlzZWNvbmRzOworICAgICAgICBpbnQgbWlsbGlzZWNvbmRzID0gKGludCkgKHZhbCAlIDYwMDAwTCk7IC8vIDYwMDAwIG1pbGxpc2Vjb25kcyBwZXIgbWludXRlCisgICAgICAgIGlmICh0b29Mb25nKSB7CisgICAgICAgICAgICArK21pbGxpc2Vjb25kczsKKyAgICAgICAgfQorICAgICAgICBpZiAobWlsbGlzZWNvbmRzICUgMTAwMCA9PSAwKSB7CisgICAgICAgICAgICBpbnQgc2Vjb25kcyA9IG1pbGxpc2Vjb25kcyAvIDEwMDA7CisgICAgICAgICAgICB2YWwgPSB2YWwgLyA2MDAwMEw7CisgICAgICAgICAgICBpbnQgbWludXRlcyA9IChpbnQpICh2YWwgJSA2MEwpOyAvLyA2MCBtaW51dGVzIHBlciBob3VyCisgICAgICAgICAgICB2YWwgPSB2YWwgLyA2MEw7CisgICAgICAgICAgICBpbnQgaG91cnMgPSAoaW50KSAodmFsICUgMjRMKTsgLy8gMjQgaG91cnMgcGVyIGRheQorICAgICAgICAgICAgbG9uZyBkYXlzID0gdmFsIC8gMjRMOworICAgICAgICAgICAgaWYgKGRheXMgPD0gKChsb25nKSBJbnRlZ2VyLk1BWF9WQUxVRSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3RHVyYXRpb24oaXNQb3NpdGl2ZSwgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELAorICAgICAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELCAoaW50KSBkYXlzLCBob3VycywgbWludXRlcywgc2Vjb25kcyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3RHVyYXRpb24oaXNQb3NpdGl2ZSwgbnVsbCwgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZihkYXlzKSwgQmlnSW50ZWdlci52YWx1ZU9mKGhvdXJzKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZihtaW51dGVzKSwgQmlnRGVjaW1hbC52YWx1ZU9mKG1pbGxpc2Vjb25kcywgMykpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQmlnRGVjaW1hbCBzZWNvbmRzID0gQmlnRGVjaW1hbC52YWx1ZU9mKG1pbGxpc2Vjb25kcywgMyk7CisgICAgICAgIHZhbCA9IHZhbCAvIDYwMDAwTDsKKyAgICAgICAgQmlnSW50ZWdlciBtaW51dGVzID0gQmlnSW50ZWdlci52YWx1ZU9mKHZhbCAlIDYwTCk7IC8vIDYwIG1pbnV0ZXMgcGVyIGhvdXIKKyAgICAgICAgdmFsID0gdmFsIC8gNjBMOworICAgICAgICBCaWdJbnRlZ2VyIGhvdXJzID0gQmlnSW50ZWdlci52YWx1ZU9mKHZhbCAlIDI0TCk7IC8vIDI0IGhvdXJzIHBlciBkYXkKKyAgICAgICAgdmFsID0gdmFsIC8gMjRMOworICAgICAgICBCaWdJbnRlZ2VyIGRheXMgPSBCaWdJbnRlZ2VyLnZhbHVlT2YodmFsKTsKKyAgICAgICAgcmV0dXJuIG5ld0R1cmF0aW9uKGlzUG9zaXRpdmUsIG51bGwsIG51bGwsIGRheXMsIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5DcmVhdGUgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2YgdHlwZSA8Y29kZT54ZHQ6ZGF5VGltZUR1cmF0aW9uPC9jb2RlPiB1c2luZyB0aGUgc3BlY2lmaWVkCisgICAgICogPGNvZGU+ZGF5PC9jb2RlPiwgPGNvZGU+aG91cjwvY29kZT4sIDxjb2RlPm1pbnV0ZTwvY29kZT4gYW5kIDxjb2RlPnNlY29uZDwvY29kZT4gYXMgZGVmaW5lZCBpbgorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoLWRhdGFtb2RlbCNkdC1kYXlUaW1lRHVyYXRpb24iPgorICAgICAqICAgWFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWwsIHhkdDpkYXlUaW1lRHVyYXRpb248L2E+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBkYXRhdHlwZSA8Y29kZT54ZHQ6ZGF5VGltZUR1cmF0aW9uPC9jb2RlPiBpcyBhIHN1YnR5cGUgb2YgPGNvZGU+eHM6ZHVyYXRpb248L2NvZGU+CisgICAgICogd2hvc2UgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBjb250YWlucyBvbmx5IGRheSwgaG91ciwgbWludXRlLCBhbmQgc2Vjb25kIGNvbXBvbmVudHMuCisgICAgICogVGhpcyBkYXRhdHlwZSByZXNpZGVzIGluIHRoZSBuYW1lc3BhY2UgPGNvZGU+aHR0cDovL3d3dy53My5vcmcvMjAwMy8xMS94cGF0aC1kYXRhdHlwZXM8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBYTUwgU2NoZW1hIHNwZWNpZmljYXRpb24gc3RhdGVzIHRoYXQgdmFsdWVzIGNhbiBiZSBvZiBhbiBhcmJpdHJhcnkgc2l6ZS4KKyAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbWF5IGNob3NlIG5vdCB0byBvciBiZSBpbmNhcGFibGUgb2Ygc3VwcG9ydGluZyBhcmJpdHJhcmlseSBsYXJnZSBhbmQvb3Igc21hbGwgdmFsdWVzLgorICAgICAqIEFuIHtAbGluayBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gd2l0aCBhIG1lc3NhZ2UgaW5kaWNhdGluZyBpbXBsZW1lbnRhdGlvbiBsaW1pdHMKKyAgICAgKiBpZiBpbXBsZW1lbnRhdGlvbiBjYXBhY2l0aWVzIGFyZSBleGNlZWRlZC48L3A+CisgICAgICoKKyAgICAgKiA8cD5BIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIGluZGljYXRlcyB0aGF0IGZpZWxkIGlzIG5vdCBzZXQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGlzUG9zaXRpdmUgU2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiB0byBjcmVhdGUgYSBuZWdhdGl2ZSBkdXJhdGlvbi4gV2hlbiB0aGUgbGVuZ3RoCisgICAgICogICBvZiB0aGUgZHVyYXRpb24gaXMgemVybywgdGhpcyBwYXJhbWV0ZXIgd2lsbCBiZSBpZ25vcmVkLgorICAgICAqIEBwYXJhbSBkYXkgRGF5IG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KKyAgICAgKiBAcGFyYW0gaG91ciBIb3VyIG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KKyAgICAgKiBAcGFyYW0gbWludXRlIE1pbnV0ZSBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCisgICAgICogQHBhcmFtIHNlY29uZCBTZWNvbmQgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+LgorICAgICAqCisgICAgICogQHJldHVybiBOZXcgPGNvZGU+RHVyYXRpb248L2NvZGU+IGNyZWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIDxjb2RlPmRheTwvY29kZT4sIDxjb2RlPmhvdXI8L2NvZGU+LCA8Y29kZT5taW51dGU8L2NvZGU+CisgICAgICogYW5kIDxjb2RlPnNlY29uZDwvY29kZT4uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiBhbnkgdmFsdWVzIHdvdWxkIGNyZWF0ZSBhbiBpbnZhbGlkIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIElmIGltcGxlbWVudGF0aW9uIGNhbm5vdCBzdXBwb3J0IHJlcXVlc3RlZCB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIER1cmF0aW9uIG5ld0R1cmF0aW9uRGF5VGltZSgKKyAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNQb3NpdGl2ZSwKKyAgICAgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgZGF5LAorICAgICAgICAgICAgZmluYWwgQmlnSW50ZWdlciBob3VyLAorICAgICAgICAgICAgZmluYWwgQmlnSW50ZWdlciBtaW51dGUsCisgICAgICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIHNlY29uZCkgeworCisgICAgICAgIHJldHVybiBuZXdEdXJhdGlvbigKKyAgICAgICAgICAgICAgICBpc1Bvc2l0aXZlLAorICAgICAgICAgICAgICAgIG51bGwsICAvLyB5ZWFycworICAgICAgICAgICAgICAgIG51bGwsIC8vIG1vbnRocworICAgICAgICAgICAgICAgIGRheSwKKyAgICAgICAgICAgICAgICBob3VyLAorICAgICAgICAgICAgICAgIG1pbnV0ZSwKKyAgICAgICAgICAgICAgICAoc2Vjb25kICE9IG51bGwpPyBuZXcgQmlnRGVjaW1hbChzZWNvbmQpOm51bGwKKyAgICAgICAgKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5DcmVhdGUgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2YgdHlwZSA8Y29kZT54ZHQ6ZGF5VGltZUR1cmF0aW9uPC9jb2RlPiB1c2luZyB0aGUgc3BlY2lmaWVkCisgICAgICogPGNvZGU+ZGF5PC9jb2RlPiwgPGNvZGU+aG91cjwvY29kZT4sIDxjb2RlPm1pbnV0ZTwvY29kZT4gYW5kIDxjb2RlPnNlY29uZDwvY29kZT4gYXMgZGVmaW5lZCBpbgorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoLWRhdGFtb2RlbCNkdC1kYXlUaW1lRHVyYXRpb24iPgorICAgICAqICAgWFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWwsIHhkdDpkYXlUaW1lRHVyYXRpb248L2E+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBkYXRhdHlwZSA8Y29kZT54ZHQ6ZGF5VGltZUR1cmF0aW9uPC9jb2RlPiBpcyBhIHN1YnR5cGUgb2YgPGNvZGU+eHM6ZHVyYXRpb248L2NvZGU+CisgICAgICogd2hvc2UgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBjb250YWlucyBvbmx5IGRheSwgaG91ciwgbWludXRlLCBhbmQgc2Vjb25kIGNvbXBvbmVudHMuCisgICAgICogVGhpcyBkYXRhdHlwZSByZXNpZGVzIGluIHRoZSBuYW1lc3BhY2UgPGNvZGU+aHR0cDovL3d3dy53My5vcmcvMjAwMy8xMS94cGF0aC1kYXRhdHlwZXM8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPkEge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gdmFsdWUgaW5kaWNhdGVzIHRoYXQgZmllbGQgaXMgbm90IHNldC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaXNQb3NpdGl2ZSBTZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+IHRvIGNyZWF0ZSBhIG5lZ2F0aXZlIGR1cmF0aW9uLiBXaGVuIHRoZSBsZW5ndGgKKyAgICAgKiAgIG9mIHRoZSBkdXJhdGlvbiBpcyB6ZXJvLCB0aGlzIHBhcmFtZXRlciB3aWxsIGJlIGlnbm9yZWQuCisgICAgICogQHBhcmFtIGRheSBEYXkgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+LgorICAgICAqIEBwYXJhbSBob3VyIEhvdXIgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+LgorICAgICAqIEBwYXJhbSBtaW51dGUgTWludXRlIG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KKyAgICAgKiBAcGFyYW0gc2Vjb25kIFNlY29uZCBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgPGNvZGU+ZGF5PC9jb2RlPiwgPGNvZGU+aG91cjwvY29kZT4sIDxjb2RlPm1pbnV0ZTwvY29kZT4KKyAgICAgKiBhbmQgPGNvZGU+c2Vjb25kPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIGFueSB2YWx1ZXMgd291bGQgY3JlYXRlIGFuIGludmFsaWQgPGNvZGU+RHVyYXRpb248L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBEdXJhdGlvbiBuZXdEdXJhdGlvbkRheVRpbWUoCisgICAgICAgICAgICBmaW5hbCBib29sZWFuIGlzUG9zaXRpdmUsCisgICAgICAgICAgICBmaW5hbCBpbnQgZGF5LAorICAgICAgICAgICAgZmluYWwgaW50IGhvdXIsCisgICAgICAgICAgICBmaW5hbCBpbnQgbWludXRlLAorICAgICAgICAgICAgZmluYWwgaW50IHNlY29uZCkgeworICAgICAgICByZXR1cm4gbmV3RHVyYXRpb24oaXNQb3NpdGl2ZSwKKyAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwKKyAgICAgICAgICAgICAgICBkYXksIGhvdXIsIG1pbnV0ZSwgc2Vjb25kKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5DcmVhdGUgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2YgdHlwZSA8Y29kZT54ZHQ6eWVhck1vbnRoRHVyYXRpb248L2NvZGU+IGJ5IHBhcnNpbmcgaXRzIDxjb2RlPlN0cmluZzwvY29kZT4gcmVwcmVzZW50YXRpb24sCisgICAgICogIjxlbT5QblluTTwvZW0+IiwgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsI2R0LXllYXJNb250aER1cmF0aW9uIj4KKyAgICAgKiAgIFhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6eWVhck1vbnRoRHVyYXRpb248L2E+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBkYXRhdHlwZSA8Y29kZT54ZHQ6eWVhck1vbnRoRHVyYXRpb248L2NvZGU+IGlzIGEgc3VidHlwZSBvZiA8Y29kZT54czpkdXJhdGlvbjwvY29kZT4KKyAgICAgKiB3aG9zZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIGNvbnRhaW5zIG9ubHkgeWVhciBhbmQgbW9udGggY29tcG9uZW50cy4KKyAgICAgKiBUaGlzIGRhdGF0eXBlIHJlc2lkZXMgaW4gdGhlIG5hbWVzcGFjZSB7QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNXM0NfWFBBVEhfREFUQVRZUEVfTlNfVVJJfS48L3A+CisgICAgICoKKyAgICAgKiA8cD5Cb3RoIHZhbHVlcyBhcmUgc2V0IGFuZCBhdmFpbGFibGUgZnJvbSB0aGUgY3JlYXRlZCB7QGxpbmsgRHVyYXRpb259PC9wPgorICAgICAqCisgICAgICogPHA+VGhlIFhNTCBTY2hlbWEgc3BlY2lmaWNhdGlvbiBzdGF0ZXMgdGhhdCB2YWx1ZXMgY2FuIGJlIG9mIGFuIGFyYml0cmFyeSBzaXplLgorICAgICAqIEltcGxlbWVudGF0aW9ucyBtYXkgY2hvc2Ugbm90IHRvIG9yIGJlIGluY2FwYWJsZSBvZiBzdXBwb3J0aW5nIGFyYml0cmFyaWx5IGxhcmdlIGFuZC9vciBzbWFsbCB2YWx1ZXMuCisgICAgICogQW4ge0BsaW5rIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufSB3aWxsIGJlIHRocm93biB3aXRoIGEgbWVzc2FnZSBpbmRpY2F0aW5nIGltcGxlbWVudGF0aW9uIGxpbWl0cworICAgICAqIGlmIGltcGxlbWVudGF0aW9uIGNhcGFjaXRpZXMgYXJlIGV4Y2VlZGVkLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsZXhpY2FsUmVwcmVzZW50YXRpb24gTGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiBhIGR1cmF0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBOZXcgPGNvZGU+RHVyYXRpb248L2NvZGU+IGNyZWF0ZWQgdXNpbmcgdGhlIHNwZWNpZmllZCA8Y29kZT5sZXhpY2FsUmVwcmVzZW50YXRpb248L2NvZGU+LgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4gZG9lcyBub3QgY29uZm9ybSB0byB0aGUgc3BlY2lmaWNhdGlvbi4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIElmIGltcGxlbWVudGF0aW9uIGNhbm5vdCBzdXBwb3J0IHJlcXVlc3RlZCB2YWx1ZXMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5sZXhpY2FsUmVwcmVzZW50YXRpb248L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBEdXJhdGlvbiBuZXdEdXJhdGlvblllYXJNb250aChmaW5hbCBTdHJpbmcgbGV4aWNhbFJlcHJlc2VudGF0aW9uKSB7CisgICAgICAgIGlmIChsZXhpY2FsUmVwcmVzZW50YXRpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJUaGUgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBjYW5ub3QgYmUgbnVsbC4iKTsKKyAgICAgICAgfQorICAgICAgICAvLyBUaGUgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBtdXN0IG1hdGNoIHRoZSBwYXR0ZXJuIFteRFRdKi4KKyAgICAgICAgaW50IGxlbmd0aCA9IGxleGljYWxSZXByZXNlbnRhdGlvbi5sZW5ndGgoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgeworICAgICAgICAgICAgY2hhciBjID0gbGV4aWNhbFJlcHJlc2VudGF0aW9uLmNoYXJBdChpKTsKKyAgICAgICAgICAgIGlmIChjID09ICdEJyB8fCBjID09ICdUJykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgeWVhck1vbnRoRHVyYXRpb24gdmFsdWU6ICIgKyBsZXhpY2FsUmVwcmVzZW50YXRpb24pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXdEdXJhdGlvbihsZXhpY2FsUmVwcmVzZW50YXRpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkNyZWF0ZSBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvZiB0eXBlIDxjb2RlPnhkdDp5ZWFyTW9udGhEdXJhdGlvbjwvY29kZT4gdXNpbmcgdGhlIHNwZWNpZmllZCBtaWxsaXNlY29uZHMgYXMgZGVmaW5lZCBpbgorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoLWRhdGFtb2RlbCNkdC15ZWFyTW9udGhEdXJhdGlvbiI+CisgICAgICogICBYUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OnllYXJNb250aER1cmF0aW9uPC9hPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgZGF0YXR5cGUgPGNvZGU+eGR0OnllYXJNb250aER1cmF0aW9uPC9jb2RlPiBpcyBhIHN1YnR5cGUgb2YgPGNvZGU+eHM6ZHVyYXRpb248L2NvZGU+CisgICAgICogd2hvc2UgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBjb250YWlucyBvbmx5IHllYXIgYW5kIG1vbnRoIGNvbXBvbmVudHMuCisgICAgICogVGhpcyBkYXRhdHlwZSByZXNpZGVzIGluIHRoZSBuYW1lc3BhY2Uge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjVzNDX1hQQVRIX0RBVEFUWVBFX05TX1VSSX0uPC9wPgorICAgICAqCisgICAgICogPHA+Qm90aCB2YWx1ZXMgYXJlIHNldCBieSBjb21wdXRpbmcgdGhlaXIgdmFsdWVzIGZyb20gdGhlIHNwZWNpZmllZCBtaWxsaXNlY29uZHMKKyAgICAgKiBhbmQgYXJlIGF2YWlsYWJsZSB1c2luZyB0aGUgPGNvZGU+Z2V0PC9jb2RlPiBtZXRob2RzIG9mICB0aGUgY3JlYXRlZCB7QGxpbmsgRHVyYXRpb259LgorICAgICAqIFRoZSB2YWx1ZXMgY29uZm9ybSB0byBhbmQgYXJlIGRlZmluZWQgYnk6PC9wPgorICAgICAqIDx1bD4KKyAgICAgKiAgIDxsaT5JU08gODYwMToyMDAwKEUpIFNlY3Rpb24gNS41LjMuMiBBbHRlcm5hdGl2ZSBmb3JtYXQ8L2xpPgorICAgICAqICAgPGxpPjxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNpc29mb3JtYXRzIj4KKyAgICAgKiAgICAgVzNDIFhNTCBTY2hlbWEgMS4wIFBhcnQgMiwgQXBwZW5kaXggRCwgSVNPIDg2MDEgRGF0ZSBhbmQgVGltZSBGb3JtYXRzPC9hPgorICAgICAqICAgPC9saT4KKyAgICAgKiAgIDxsaT57QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXJ9ICBEYXRlL1RpbWUgRGF0YXR5cGUgRmllbGQgTWFwcGluZyBCZXR3ZWVuIFhNTCBTY2hlbWEgMS4wIGFuZCBKYXZhIFJlcHJlc2VudGF0aW9uPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogPHA+VGhlIGRlZmF1bHQgc3RhcnQgaW5zdGFuY2UgaXMgZGVmaW5lZCBieSB7QGxpbmsgR3JlZ29yaWFuQ2FsZW5kYXJ9J3MgdXNlIG9mIHRoZSBzdGFydCBvZiB0aGUgZXBvY2g6IGkuZS4sCisgICAgICoge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNZRUFSfSA9IDE5NzAsCisgICAgICoge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNNT05USH0gPSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0pBTlVBUll9LAorICAgICAqIHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjREFURX0gPSAxLCBldGMuCisgICAgICogVGhpcyBpcyBpbXBvcnRhbnQgYXMgdGhlcmUgYXJlIHZhcmlhdGlvbnMgaW4gdGhlIEdyZWdvcmlhbiBDYWxlbmRhciwKKyAgICAgKiBlLmcuIGxlYXAgeWVhcnMgaGF2ZSBkaWZmZXJlbnQgZGF5cyBpbiB0aGUgbW9udGggPSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0ZFQlJVQVJZfQorICAgICAqIHNvIHRoZSByZXN1bHQgb2Yge0BsaW5rIER1cmF0aW9uI2dldE1vbnRocygpfSBjYW4gYmUgaW5mbHVlbmNlZC48L3A+CisgICAgICoKKyAgICAgKiA8cD5BbnkgcmVtYWluaW5nIG1pbGxpc2Vjb25kcyBhZnRlciBkZXRlcm1pbmluZyB0aGUgeWVhciBhbmQgbW9udGggYXJlIGRpc2NhcmRlZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZHVyYXRpb25Jbk1pbGxpc2Vjb25kcyBNaWxsaXNlY29uZHMgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+IHRvIGNyZWF0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gTmV3IDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBjcmVhdGVkIHVzaW5nIHRoZSBzcGVjaWZpZWQgPGNvZGU+ZHVyYXRpb25Jbk1pbGxpc2Vjb25kczwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIER1cmF0aW9uIG5ld0R1cmF0aW9uWWVhck1vbnRoKGZpbmFsIGxvbmcgZHVyYXRpb25Jbk1pbGxpc2Vjb25kcykgeworCisgICAgICAgIHJldHVybiBuZXdEdXJhdGlvbihkdXJhdGlvbkluTWlsbGlzZWNvbmRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5DcmVhdGUgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2YgdHlwZSA8Y29kZT54ZHQ6eWVhck1vbnRoRHVyYXRpb248L2NvZGU+IHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiA8Y29kZT55ZWFyPC9jb2RlPiBhbmQgPGNvZGU+bW9udGg8L2NvZGU+IGFzIGRlZmluZWQgaW4KKyAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjZHQteWVhck1vbnRoeUR1cmF0aW9uIj4KKyAgICAgKiAgIFhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6eWVhck1vbnRoRHVyYXRpb248L2E+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBYTUwgU2NoZW1hIHNwZWNpZmljYXRpb24gc3RhdGVzIHRoYXQgdmFsdWVzIGNhbiBiZSBvZiBhbiBhcmJpdHJhcnkgc2l6ZS4KKyAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbWF5IGNob3NlIG5vdCB0byBvciBiZSBpbmNhcGFibGUgb2Ygc3VwcG9ydGluZyBhcmJpdHJhcmlseSBsYXJnZSBhbmQvb3Igc21hbGwgdmFsdWVzLgorICAgICAqIEFuIHtAbGluayBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gd2l0aCBhIG1lc3NhZ2UgaW5kaWNhdGluZyBpbXBsZW1lbnRhdGlvbiBsaW1pdHMKKyAgICAgKiBpZiBpbXBsZW1lbnRhdGlvbiBjYXBhY2l0aWVzIGFyZSBleGNlZWRlZC48L3A+CisgICAgICoKKyAgICAgKiA8cD5BIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIGluZGljYXRlcyB0aGF0IGZpZWxkIGlzIG5vdCBzZXQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGlzUG9zaXRpdmUgU2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiB0byBjcmVhdGUgYSBuZWdhdGl2ZSBkdXJhdGlvbi4gV2hlbiB0aGUgbGVuZ3RoCisgICAgICogICBvZiB0aGUgZHVyYXRpb24gaXMgemVybywgdGhpcyBwYXJhbWV0ZXIgd2lsbCBiZSBpZ25vcmVkLgorICAgICAqIEBwYXJhbSB5ZWFyIFllYXIgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+LgorICAgICAqIEBwYXJhbSBtb250aCBNb250aCBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCB1c2luZyB0aGUgc3BlY2lmaWVkIDxjb2RlPnllYXI8L2NvZGU+IGFuZCA8Y29kZT5tb250aDwvY29kZT4uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiBhbnkgdmFsdWVzIHdvdWxkIGNyZWF0ZSBhbiBpbnZhbGlkIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIElmIGltcGxlbWVudGF0aW9uIGNhbm5vdCBzdXBwb3J0IHJlcXVlc3RlZCB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIER1cmF0aW9uIG5ld0R1cmF0aW9uWWVhck1vbnRoKAorICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBpc1Bvc2l0aXZlLAorICAgICAgICAgICAgZmluYWwgQmlnSW50ZWdlciB5ZWFyLAorICAgICAgICAgICAgZmluYWwgQmlnSW50ZWdlciBtb250aCkgeworCisgICAgICAgIHJldHVybiBuZXdEdXJhdGlvbigKKyAgICAgICAgICAgICAgICBpc1Bvc2l0aXZlLAorICAgICAgICAgICAgICAgIHllYXIsCisgICAgICAgICAgICAgICAgbW9udGgsCisgICAgICAgICAgICAgICAgbnVsbCwgLy8gZGF5cworICAgICAgICAgICAgICAgIG51bGwsIC8vIGhvdXJzCisgICAgICAgICAgICAgICAgbnVsbCwgLy8gbWludXRlcworICAgICAgICAgICAgICAgIG51bGwgIC8vIHNlY29uZHMKKyAgICAgICAgKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5DcmVhdGUgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2YgdHlwZSA8Y29kZT54ZHQ6eWVhck1vbnRoRHVyYXRpb248L2NvZGU+IHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiA8Y29kZT55ZWFyPC9jb2RlPiBhbmQgPGNvZGU+bW9udGg8L2NvZGU+IGFzIGRlZmluZWQgaW4KKyAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjZHQteWVhck1vbnRoeUR1cmF0aW9uIj4KKyAgICAgKiAgIFhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6eWVhck1vbnRoRHVyYXRpb248L2E+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPkEge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gdmFsdWUgaW5kaWNhdGVzIHRoYXQgZmllbGQgaXMgbm90IHNldC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaXNQb3NpdGl2ZSBTZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+IHRvIGNyZWF0ZSBhIG5lZ2F0aXZlIGR1cmF0aW9uLiBXaGVuIHRoZSBsZW5ndGgKKyAgICAgKiAgIG9mIHRoZSBkdXJhdGlvbiBpcyB6ZXJvLCB0aGlzIHBhcmFtZXRlciB3aWxsIGJlIGlnbm9yZWQuCisgICAgICogQHBhcmFtIHllYXIgWWVhciBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCisgICAgICogQHBhcmFtIG1vbnRoIE1vbnRoIG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gTmV3IDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBjcmVhdGVkIHVzaW5nIHRoZSBzcGVjaWZpZWQgPGNvZGU+eWVhcjwvY29kZT4gYW5kIDxjb2RlPm1vbnRoPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIGFueSB2YWx1ZXMgd291bGQgY3JlYXRlIGFuIGludmFsaWQgPGNvZGU+RHVyYXRpb248L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBEdXJhdGlvbiBuZXdEdXJhdGlvblllYXJNb250aCgKKyAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNQb3NpdGl2ZSwKKyAgICAgICAgICAgIGZpbmFsIGludCB5ZWFyLAorICAgICAgICAgICAgZmluYWwgaW50IG1vbnRoKSB7CisgICAgICAgIHJldHVybiBuZXdEdXJhdGlvbihpc1Bvc2l0aXZlLCB5ZWFyLCBtb250aCwKKyAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwKKyAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+Q3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIGFuIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5BbGwgZGF0ZS90aW1lIGRhdGF0eXBlIGZpZWxkcyBzZXQgdG8ge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gb3IgbnVsbC48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gd2l0aCBhbGwgZGF0ZS90aW1lIGRhdGF0eXBlIGZpZWxkcyBzZXQgdG8KKyAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFhNTEdyZWdvcmlhbkNhbGVuZGFyIG5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKCk7CisKKyAgICAvKioKKyAgICAgKiA8cD5DcmVhdGUgYSBuZXcgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgYnkgcGFyc2luZyB0aGUgU3RyaW5nIGFzIGEgbGV4aWNhbCByZXByZXNlbnRhdGlvbi48L3A+CisgICAgICoKKyAgICAgKiA8cD5QYXJzaW5nIHRoZSBsZXhpY2FsIHN0cmluZyByZXByZXNlbnRhdGlvbiBpcyBkZWZpbmVkIGluCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2RhdGVUaW1lLW9yZGVyIj5YTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIFNlY3Rpb24gMy4yLls3LTE0XS4xLAorICAgICAqIDxlbT5MZXhpY2FsIFJlcHJlc2VudGF0aW9uPC9lbT4uPC9hPjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gbWF5IG5vdCBoYXZlIGFueSBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlcy48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgcGFyc2luZyBpcyBkb25lIGZpZWxkIGJ5IGZpZWxkIHNvIHRoYXQKKyAgICAgKiB0aGUgZm9sbG93aW5nIGhvbGRzIGZvciBhbnkgbGV4aWNhbGx5IGNvcnJlY3QgU3RyaW5nIHg6PC9wPgorICAgICAqIDxwcmU+CisgICAgICogbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoeCkudG9YTUxGb3JtYXQoKS5lcXVhbHMoeCkKKyAgICAgKiA8L3ByZT4KKyAgICAgKiA8cD5FeGNlcHQgZm9yIHRoZSBub3RlZCBsZXhpY2FsL2Nhbm9uaWNhbCByZXByZXNlbnRhdGlvbiBtaXNtYXRjaGVzCisgICAgICogbGlzdGVkIGluIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDUveG1sc2NoZW1hLWVycmF0YSNlMi00NSI+CisgICAgICogWE1MIFNjaGVtYSAxLjAgZXJyYXRhLCBTZWN0aW9uIDMuMi43LjI8L2E+LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsZXhpY2FsUmVwcmVzZW50YXRpb24gTGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiBvbmUgdGhlIGVpZ2h0IFhNTCBTY2hlbWEgZGF0ZS90aW1lIGRhdGF0eXBlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGNyZWF0ZWQgZnJvbSB0aGUgPGNvZGU+bGV4aWNhbFJlcHJlc2VudGF0aW9uPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSA8Y29kZT5sZXhpY2FsUmVwcmVzZW50YXRpb248L2NvZGU+IGlzIG5vdCBhIHZhbGlkIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPi4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFhNTEdyZWdvcmlhbkNhbGVuZGFyIG5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKGZpbmFsIFN0cmluZyBsZXhpY2FsUmVwcmVzZW50YXRpb24pOworCisgICAgLyoqCisgICAgICogPHA+Q3JlYXRlIGFuIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBmcm9tIGEge0BsaW5rIEdyZWdvcmlhbkNhbGVuZGFyfS48L3A+CisgICAgICoKKyAgICAgKiA8dGFibGUgYm9yZGVyPSIyIiBydWxlcz0iYWxsIiBjZWxscGFkZGluZz0iMiI+CisgICAgICogICA8dGhlYWQ+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGggYWxpZ249ImNlbnRlciIgY29sc3Bhbj0iMiI+CisgICAgICogICAgICAgICAgRmllbGQgYnkgRmllbGQgQ29udmVyc2lvbiBmcm9tCisgICAgICogICAgICAgICAge0BsaW5rIEdyZWdvcmlhbkNhbGVuZGFyfSB0byBhbiB7QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXJ9CisgICAgICogICAgICAgPC90aD4KKyAgICAgKiAgICAgPC90cj4KKyAgICAgKiAgICAgPHRyPgorICAgICAqICAgICAgICA8dGg+PGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBmaWVsZDwvdGg+CisgICAgICogICAgICAgIDx0aD48Y29kZT5qYXZheC54bWwuZGF0YXR5cGUuWE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGZpZWxkPC90aD4KKyAgICAgKiAgICAgPC90cj4KKyAgICAgKiAgIDwvdGhlYWQ+CisgICAgICogICA8dGJvZHk+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+RVJBID09IEdyZWdvcmlhbkNhbGVuZGFyLkJDID8gLVlFQVIgOiBZRUFSPC9jb2RlPjwvdGQ+CisgICAgICogICAgICAgPHRkPntAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhciNzZXRZZWFyKGludCB5ZWFyKX08L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPjxjb2RlPk1PTlRIICsgMTwvY29kZT48L3RkPgorICAgICAqICAgICAgIDx0ZD57QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXIjc2V0TW9udGgoaW50IG1vbnRoKX08L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPjxjb2RlPkRBWV9PRl9NT05USDwvY29kZT48L3RkPgorICAgICAqICAgICAgIDx0ZD57QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXIjc2V0RGF5KGludCBkYXkpfTwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+SE9VUl9PRl9EQVksIE1JTlVURSwgU0VDT05ELCBNSUxMSVNFQ09ORDwvY29kZT48L3RkPgorICAgICAqICAgICAgIDx0ZD57QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXIjc2V0VGltZShpbnQgaG91ciwgaW50IG1pbnV0ZSwgaW50IHNlY29uZCwgQmlnRGVjaW1hbCBmcmFjdGlvbmFsKX08L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPgorICAgICAqICAgICAgICAgPGNvZGU+KFpPTkVfT0ZGU0VUICsgRFNUX09GRlNFVCkgLyAoNjAqMTAwMCk8L2NvZGU+PGJyLz4KKyAgICAgKiAgICAgICAgIDxlbT4oaW4gbWludXRlcyk8L2VtPgorICAgICAqICAgICAgIDwvdGQ+CisgICAgICogICAgICAgPHRkPntAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhciNzZXRUaW1lem9uZShpbnQgb2Zmc2V0KX08c3VwPjxlbT4qPC9lbT48L3N1cD4KKyAgICAgKiAgICAgICA8L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgPC90Ym9keT4KKyAgICAgKiA8L3RhYmxlPgorICAgICAqIDxwPjxlbT4qPC9lbT5jb252ZXJzaW9uIGxvc3Mgb2YgaW5mb3JtYXRpb24uIEl0IGlzIG5vdCBwb3NzaWJsZSB0byByZXByZXNlbnQKKyAgICAgKiBhIDxjb2RlPmphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gZGF5bGlnaHQgc2F2aW5ncyB0aW1lem9uZSBpZCBpbiB0aGUKKyAgICAgKiBYTUwgU2NoZW1hIDEuMCBkYXRlL3RpbWUgZGF0YXR5cGUgcmVwcmVzZW50YXRpb24uPC9wPgorICAgICAqCisgICAgICogPHA+VG8gY29tcHV0ZSB0aGUgcmV0dXJuIHZhbHVlJ3MgPGNvZGU+VGltZVpvbmU8L2NvZGU+IGZpZWxkLAorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+d2hlbiA8Y29kZT50aGlzLmdldFRpbWV6b25lKCkgIT0gRklFTERfVU5ERUZJTkVEPC9jb2RlPiwKKyAgICAgKiBjcmVhdGUgYSA8Y29kZT5qYXZhLnV0aWwuVGltZVpvbmU8L2NvZGU+IHdpdGggYSBjdXN0b20gdGltZXpvbmUgaWQKKyAgICAgKiB1c2luZyB0aGUgPGNvZGU+dGhpcy5nZXRUaW1lem9uZSgpPC9jb2RlPi48L2xpPgorICAgICAqIDxsaT5lbHNlIHVzZSB0aGUgPGNvZGU+R3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGRlZmF1bHQgdGltZXpvbmUgdmFsdWUKKyAgICAgKiBmb3IgdGhlIGhvc3QgaXMgZGVmaW5lZCBhcyBzcGVjaWZpZWQgYnkKKyAgICAgKiA8Y29kZT5qYXZhLnV0aWwuVGltZVpvbmUuZ2V0RGVmYXVsdCgpPC9jb2RlPi48L2xpPjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYWwgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB1c2VkIHRvIGNyZWF0ZSA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4KKyAgICAgKgorICAgICAqIEByZXR1cm4gPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGNyZWF0ZWQgZnJvbSA8Y29kZT5qYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+CisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPmNhbDwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFhNTEdyZWdvcmlhbkNhbGVuZGFyIG5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKGZpbmFsIEdyZWdvcmlhbkNhbGVuZGFyIGNhbCk7CisKKyAgICAvKioKKyAgICAgKiA8cD5Db25zdHJ1Y3RvciBhbGxvd2luZyBmb3IgY29tcGxldGUgdmFsdWUgc3BhY2VzIGFsbG93ZWQgYnkKKyAgICAgKiBXM0MgWE1MIFNjaGVtYSAxLjAgcmVjb21tZW5kYXRpb24gZm9yIHhzZDpkYXRlVGltZSBhbmQgcmVsYXRlZAorICAgICAqIGJ1aWx0aW4gZGF0YXR5cGVzLiBOb3RlIHRoYXQgPGNvZGU+eWVhcjwvY29kZT4gcGFyYW1ldGVyIHN1cHBvcnRzCisgICAgICogYXJiaXRyYXJpbHkgbGFyZ2UgbnVtYmVycyBhbmQgZnJhY3Rpb25hbFNlY29uZCBoYXMgaW5maW5pdGUKKyAgICAgKiBwcmVjaXNpb24uPC9wPgorICAgICAqCisgICAgICogPHA+QSA8Y29kZT5udWxsPC9jb2RlPiB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCBmaWVsZCBpcyBub3Qgc2V0LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSB5ZWFyIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgorICAgICAqIEBwYXJhbSBtb250aCBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KKyAgICAgKiBAcGFyYW0gZGF5IG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgorICAgICAqIEBwYXJhbSBob3VyIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgorICAgICAqIEBwYXJhbSBtaW51dGUgb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCisgICAgICogQHBhcmFtIHNlY29uZCBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KKyAgICAgKiBAcGFyYW0gZnJhY3Rpb25hbFNlY29uZCBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KKyAgICAgKiBAcGFyYW0gdGltZXpvbmUgb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBjcmVhdGVkIGZyb20gc3BlY2lmaWVkIHZhbHVlcy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIGFueSBpbmRpdmlkdWFsIHBhcmFtZXRlcidzIHZhbHVlIGlzIG91dHNpZGUgdGhlIG1heGltdW0gdmFsdWUgY29uc3RyYWludCBmb3IgdGhlIGZpZWxkCisgICAgICogICBhcyBkZXRlcm1pbmVkIGJ5IHRoZSBEYXRlL1RpbWUgRGF0YSBNYXBwaW5nIHRhYmxlIGluIHtAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhcn0KKyAgICAgKiAgIG9yIGlmIHRoZSBjb21wb3NpdGUgdmFsdWVzIGNvbnN0aXR1dGUgYW4gaW52YWxpZCA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gaW5zdGFuY2UKKyAgICAgKiAgIGFzIGRldGVybWluZWQgYnkge0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyI2lzVmFsaWQoKX0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFhNTEdyZWdvcmlhbkNhbGVuZGFyIG5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKAorICAgICAgICAgICAgZmluYWwgQmlnSW50ZWdlciB5ZWFyLAorICAgICAgICAgICAgZmluYWwgaW50IG1vbnRoLAorICAgICAgICAgICAgZmluYWwgaW50IGRheSwKKyAgICAgICAgICAgIGZpbmFsIGludCBob3VyLAorICAgICAgICAgICAgZmluYWwgaW50IG1pbnV0ZSwKKyAgICAgICAgICAgIGZpbmFsIGludCBzZWNvbmQsCisgICAgICAgICAgICBmaW5hbCBCaWdEZWNpbWFsIGZyYWN0aW9uYWxTZWNvbmQsCisgICAgICAgICAgICBmaW5hbCBpbnQgdGltZXpvbmUpOworCisgICAgLyoqCisgICAgICogPHA+Q29uc3RydWN0b3Igb2YgdmFsdWUgc3BhY2VzIHRoYXQgYQorICAgICAqIDxjb2RlPmphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gaW5zdGFuY2Ugd291bGQgbmVlZCB0byBjb252ZXJ0IHRvIGFuCisgICAgICogPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGluc3RhbmNlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPjxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyIGVvbjwvY29kZT4gYW5kCisgICAgICogPGNvZGU+ZnJhY3Rpb25hbFNlY29uZDwvY29kZT4gYXJlIHNldCB0byA8Y29kZT5udWxsPC9jb2RlPjwvcD4KKyAgICAgKgorICAgICAqIDxwPkEge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gdmFsdWUgaW5kaWNhdGVzIHRoYXQgZmllbGQgaXMgbm90IHNldC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0geWVhciBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KKyAgICAgKiBAcGFyYW0gbW9udGggb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCisgICAgICogQHBhcmFtIGRheSBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KKyAgICAgKiBAcGFyYW0gaG91ciBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KKyAgICAgKiBAcGFyYW0gbWludXRlIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgorICAgICAqIEBwYXJhbSBzZWNvbmQgb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCisgICAgICogQHBhcmFtIG1pbGxpc2Vjb25kIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgorICAgICAqIEBwYXJhbSB0aW1lem9uZSBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGNyZWF0ZWQgZnJvbSBzcGVjaWZpZWQgdmFsdWVzLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgYW55IGluZGl2aWR1YWwgcGFyYW1ldGVyJ3MgdmFsdWUgaXMgb3V0c2lkZSB0aGUgbWF4aW11bSB2YWx1ZSBjb25zdHJhaW50IGZvciB0aGUgZmllbGQKKyAgICAgKiAgIGFzIGRldGVybWluZWQgYnkgdGhlIERhdGUvVGltZSBEYXRhIE1hcHBpbmcgdGFibGUgaW4ge0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyfQorICAgICAqICAgb3IgaWYgdGhlIGNvbXBvc2l0ZSB2YWx1ZXMgY29uc3RpdHV0ZSBhbiBpbnZhbGlkIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBpbnN0YW5jZQorICAgICAqICAgYXMgZGV0ZXJtaW5lZCBieSB7QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXIjaXNWYWxpZCgpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoCisgICAgICAgICAgICBmaW5hbCBpbnQgeWVhciwKKyAgICAgICAgICAgIGZpbmFsIGludCBtb250aCwKKyAgICAgICAgICAgIGZpbmFsIGludCBkYXksCisgICAgICAgICAgICBmaW5hbCBpbnQgaG91ciwKKyAgICAgICAgICAgIGZpbmFsIGludCBtaW51dGUsCisgICAgICAgICAgICBmaW5hbCBpbnQgc2Vjb25kLAorICAgICAgICAgICAgZmluYWwgaW50IG1pbGxpc2Vjb25kLAorICAgICAgICAgICAgZmluYWwgaW50IHRpbWV6b25lKSB7CisKKyAgICAgICAgLy8geWVhciBtYXkgYmUgdW5kZWZpbmVkCisgICAgICAgIEJpZ0ludGVnZXIgcmVhbFllYXIgPSAoeWVhciAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpID8gQmlnSW50ZWdlci52YWx1ZU9mKChsb25nKSB5ZWFyKSA6IG51bGw7CisKKyAgICAgICAgLy8gbWlsbGlzZWNvbmQgbWF5IGJlIHVuZGVmaW5lZAorICAgICAgICAvLyBtaWxsaXNlY29uZCBtdXN0IGJlID49IDAgbWlsbGlzZWNvbmQgPD0gMTAwMAorICAgICAgICBCaWdEZWNpbWFsIHJlYWxNaWxsaXNlY29uZCA9IG51bGw7IC8vIHVuZGVmaW5lZCB2YWx1ZQorICAgICAgICBpZiAobWlsbGlzZWNvbmQgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSB7CisgICAgICAgICAgICBpZiAobWlsbGlzZWNvbmQgPCAwIHx8IG1pbGxpc2Vjb25kID4gMTAwMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlRmFjdG9yeSNuZXdYTUxHcmVnb3JpYW5DYWxlbmRhcigiCisgICAgICAgICAgICAgICAgICAgICAgICArICJpbnQgeWVhciwgaW50IG1vbnRoLCBpbnQgZGF5LCBpbnQgaG91ciwgaW50IG1pbnV0ZSwgaW50IHNlY29uZCwgaW50IG1pbGxpc2Vjb25kLCBpbnQgdGltZXpvbmUpIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAid2l0aCBpbnZhbGlkIG1pbGxpc2Vjb25kOiAiICsgbWlsbGlzZWNvbmQKKyAgICAgICAgICAgICAgICApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVhbE1pbGxpc2Vjb25kID0gQmlnRGVjaW1hbC52YWx1ZU9mKChsb25nKSBtaWxsaXNlY29uZCwgMyk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoCisgICAgICAgICAgICAgICAgcmVhbFllYXIsCisgICAgICAgICAgICAgICAgbW9udGgsCisgICAgICAgICAgICAgICAgZGF5LAorICAgICAgICAgICAgICAgIGhvdXIsCisgICAgICAgICAgICAgICAgbWludXRlLAorICAgICAgICAgICAgICAgIHNlY29uZCwKKyAgICAgICAgICAgICAgICByZWFsTWlsbGlzZWNvbmQsCisgICAgICAgICAgICAgICAgdGltZXpvbmUKKyAgICAgICAgKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5DcmVhdGUgYSBKYXZhIHJlcHJlc2VudGF0aW9uIG9mIFhNTCBTY2hlbWEgYnVpbHRpbiBkYXRhdHlwZSA8Y29kZT5kYXRlPC9jb2RlPiBvciA8Y29kZT5nKjwvY29kZT4uPC9wPgorICAgICAqCisgICAgICogPHA+Rm9yIGV4YW1wbGUsIGFuIGluc3RhbmNlIG9mIDxjb2RlPmdZZWFyPC9jb2RlPiBjYW4gYmUgY3JlYXRlZCBpbnZva2luZyB0aGlzIGZhY3RvcnkKKyAgICAgKiB3aXRoIDxjb2RlPm1vbnRoPC9jb2RlPiBhbmQgPGNvZGU+ZGF5PC9jb2RlPiBwYXJhbWV0ZXJzIHNldCB0bworICAgICAqIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LjwvcD4KKyAgICAgKgorICAgICAqIDxwPkEge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gdmFsdWUgaW5kaWNhdGVzIHRoYXQgZmllbGQgaXMgbm90IHNldC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0geWVhciBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KKyAgICAgKiBAcGFyYW0gbW9udGggb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCisgICAgICogQHBhcmFtIGRheSBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KKyAgICAgKiBAcGFyYW0gdGltZXpvbmUgb2Zmc2V0IGluIG1pbnV0ZXMuIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IGluZGljYXRlcyBvcHRpb25hbCBmaWVsZCBpcyBub3Qgc2V0LgorICAgICAqCisgICAgICogQHJldHVybiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gY3JlYXRlZCBmcm9tIHBhcmFtZXRlciB2YWx1ZXMuCisgICAgICoKKyAgICAgKiBAc2VlIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRAorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgYW55IGluZGl2aWR1YWwgcGFyYW1ldGVyJ3MgdmFsdWUgaXMgb3V0c2lkZSB0aGUgbWF4aW11bSB2YWx1ZSBjb25zdHJhaW50IGZvciB0aGUgZmllbGQKKyAgICAgKiAgIGFzIGRldGVybWluZWQgYnkgdGhlIERhdGUvVGltZSBEYXRhIE1hcHBpbmcgdGFibGUgaW4ge0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyfQorICAgICAqICAgb3IgaWYgdGhlIGNvbXBvc2l0ZSB2YWx1ZXMgY29uc3RpdHV0ZSBhbiBpbnZhbGlkIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBpbnN0YW5jZQorICAgICAqICAgYXMgZGV0ZXJtaW5lZCBieSB7QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXIjaXNWYWxpZCgpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXJEYXRlKAorICAgICAgICAgICAgZmluYWwgaW50IHllYXIsCisgICAgICAgICAgICBmaW5hbCBpbnQgbW9udGgsCisgICAgICAgICAgICBmaW5hbCBpbnQgZGF5LAorICAgICAgICAgICAgZmluYWwgaW50IHRpbWV6b25lKSB7CisKKyAgICAgICAgcmV0dXJuIG5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKAorICAgICAgICAgICAgICAgIHllYXIsCisgICAgICAgICAgICAgICAgbW9udGgsCisgICAgICAgICAgICAgICAgZGF5LAorICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgLy8gaG91cgorICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgLy8gbWludXRlCisgICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELCAvLyBzZWNvbmQKKyAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIC8vIG1pbGxpc2Vjb25kCisgICAgICAgICAgICAgICAgdGltZXpvbmUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkNyZWF0ZSBhIEphdmEgaW5zdGFuY2Ugb2YgWE1MIFNjaGVtYSBidWlsdGluIGRhdGF0eXBlIDxjb2RlPnRpbWU8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPkEge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gdmFsdWUgaW5kaWNhdGVzIHRoYXQgZmllbGQgaXMgbm90IHNldC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaG91cnMgbnVtYmVyIG9mIGhvdXJzCisgICAgICogQHBhcmFtIG1pbnV0ZXMgbnVtYmVyIG9mIG1pbnV0ZXMKKyAgICAgKiBAcGFyYW0gc2Vjb25kcyBudW1iZXIgb2Ygc2Vjb25kcworICAgICAqIEBwYXJhbSB0aW1lem9uZSBvZmZzZXQgaW4gbWludXRlcy4ge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gaW5kaWNhdGVzIG9wdGlvbmFsIGZpZWxkIGlzIG5vdCBzZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBjcmVhdGVkIGZyb20gcGFyYW1ldGVyIHZhbHVlcy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIGFueSBpbmRpdmlkdWFsIHBhcmFtZXRlcidzIHZhbHVlIGlzIG91dHNpZGUgdGhlIG1heGltdW0gdmFsdWUgY29uc3RyYWludCBmb3IgdGhlIGZpZWxkCisgICAgICogICBhcyBkZXRlcm1pbmVkIGJ5IHRoZSBEYXRlL1RpbWUgRGF0YSBNYXBwaW5nIHRhYmxlIGluIHtAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhcn0KKyAgICAgKiAgIG9yIGlmIHRoZSBjb21wb3NpdGUgdmFsdWVzIGNvbnN0aXR1dGUgYW4gaW52YWxpZCA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gaW5zdGFuY2UKKyAgICAgKiAgIGFzIGRldGVybWluZWQgYnkge0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyI2lzVmFsaWQoKX0uCisgICAgICoKKyAgICAgKiBAc2VlIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRAorICAgICAqLworICAgIHB1YmxpYyBYTUxHcmVnb3JpYW5DYWxlbmRhciBuZXdYTUxHcmVnb3JpYW5DYWxlbmRhclRpbWUoCisgICAgICAgICAgICBmaW5hbCBpbnQgaG91cnMsCisgICAgICAgICAgICBmaW5hbCBpbnQgbWludXRlcywKKyAgICAgICAgICAgIGZpbmFsIGludCBzZWNvbmRzLAorICAgICAgICAgICAgZmluYWwgaW50IHRpbWV6b25lKSB7CisKKyAgICAgICAgcmV0dXJuIG5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKAorICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgLy8gWWVhcgorICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgLy8gTW9udGgKKyAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIC8vIERheQorICAgICAgICAgICAgICAgIGhvdXJzLAorICAgICAgICAgICAgICAgIG1pbnV0ZXMsCisgICAgICAgICAgICAgICAgc2Vjb25kcywKKyAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIC8vTWlsbGlzZWNvbmQKKyAgICAgICAgICAgICAgICB0aW1lem9uZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+Q3JlYXRlIGEgSmF2YSBpbnN0YW5jZSBvZiBYTUwgU2NoZW1hIGJ1aWx0aW4gZGF0YXR5cGUgdGltZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5BIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIGluZGljYXRlcyB0aGF0IGZpZWxkIGlzIG5vdCBzZXQuPC9wPgorICAgICAqIDxwPkEge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gdmFsdWUgaW5kaWNhdGVzIHRoYXQgZmllbGQgaXMgbm90IHNldC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaG91cnMgbnVtYmVyIG9mIGhvdXJzCisgICAgICogQHBhcmFtIG1pbnV0ZXMgbnVtYmVyIG9mIG1pbnV0ZXMKKyAgICAgKiBAcGFyYW0gc2Vjb25kcyBudW1iZXIgb2Ygc2Vjb25kcworICAgICAqIEBwYXJhbSBmcmFjdGlvbmFsU2Vjb25kIHZhbHVlIG9mIDxjb2RlPm51bGw8L2NvZGU+IGluZGljYXRlcyB0aGF0IHRoaXMgb3B0aW9uYWwgZmllbGQgaXMgbm90IHNldC4KKyAgICAgKiBAcGFyYW0gdGltZXpvbmUgb2Zmc2V0IGluIG1pbnV0ZXMuIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IGluZGljYXRlcyBvcHRpb25hbCBmaWVsZCBpcyBub3Qgc2V0LgorICAgICAqCisgICAgICogQHJldHVybiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gY3JlYXRlZCBmcm9tIHBhcmFtZXRlciB2YWx1ZXMuCisgICAgICoKKyAgICAgKiBAc2VlIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRAorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgYW55IGluZGl2aWR1YWwgcGFyYW1ldGVyJ3MgdmFsdWUgaXMgb3V0c2lkZSB0aGUgbWF4aW11bSB2YWx1ZSBjb25zdHJhaW50IGZvciB0aGUgZmllbGQKKyAgICAgKiAgIGFzIGRldGVybWluZWQgYnkgdGhlIERhdGUvVGltZSBEYXRhIE1hcHBpbmcgdGFibGUgaW4ge0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyfQorICAgICAqICAgb3IgaWYgdGhlIGNvbXBvc2l0ZSB2YWx1ZXMgY29uc3RpdHV0ZSBhbiBpbnZhbGlkIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBpbnN0YW5jZQorICAgICAqICAgYXMgZGV0ZXJtaW5lZCBieSB7QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXIjaXNWYWxpZCgpfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXJUaW1lKAorICAgICAgICAgICAgZmluYWwgaW50IGhvdXJzLAorICAgICAgICAgICAgZmluYWwgaW50IG1pbnV0ZXMsCisgICAgICAgICAgICBmaW5hbCBpbnQgc2Vjb25kcywKKyAgICAgICAgICAgIGZpbmFsIEJpZ0RlY2ltYWwgZnJhY3Rpb25hbFNlY29uZCwKKyAgICAgICAgICAgIGZpbmFsIGludCB0aW1lem9uZSkgeworCisgICAgICAgIHJldHVybiBuZXdYTUxHcmVnb3JpYW5DYWxlbmRhcigKKyAgICAgICAgICAgICAgICBudWxsLCAvLyB5ZWFyCisgICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELCAvLyBtb250aAorICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgLy8gZGF5CisgICAgICAgICAgICAgICAgaG91cnMsCisgICAgICAgICAgICAgICAgbWludXRlcywKKyAgICAgICAgICAgICAgICBzZWNvbmRzLAorICAgICAgICAgICAgICAgIGZyYWN0aW9uYWxTZWNvbmQsCisgICAgICAgICAgICAgICAgdGltZXpvbmUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkNyZWF0ZSBhIEphdmEgaW5zdGFuY2Ugb2YgWE1MIFNjaGVtYSBidWlsdGluIGRhdGF0eXBlIHRpbWUuPC9wPgorICAgICAqCisgICAgICogPHA+QSB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCBmaWVsZCBpcyBub3Qgc2V0LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3VycyBudW1iZXIgb2YgaG91cnMKKyAgICAgKiBAcGFyYW0gbWludXRlcyBudW1iZXIgb2YgbWludXRlcworICAgICAqIEBwYXJhbSBzZWNvbmRzIG51bWJlciBvZiBzZWNvbmRzCisgICAgICogQHBhcmFtIG1pbGxpc2Vjb25kcyBudW1iZXIgb2YgbWlsbGlzZWNvbmRzCisgICAgICogQHBhcmFtIHRpbWV6b25lIG9mZnNldCBpbiBtaW51dGVzLiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSBpbmRpY2F0ZXMgb3B0aW9uYWwgZmllbGQgaXMgbm90IHNldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGNyZWF0ZWQgZnJvbSBwYXJhbWV0ZXIgdmFsdWVzLgorICAgICAqCisgICAgICogQHNlZSBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIGFueSBpbmRpdmlkdWFsIHBhcmFtZXRlcidzIHZhbHVlIGlzIG91dHNpZGUgdGhlIG1heGltdW0gdmFsdWUgY29uc3RyYWludCBmb3IgdGhlIGZpZWxkCisgICAgICogICBhcyBkZXRlcm1pbmVkIGJ5IHRoZSBEYXRlL1RpbWUgRGF0YSBNYXBwaW5nIHRhYmxlIGluIHtAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhcn0KKyAgICAgKiAgIG9yIGlmIHRoZSBjb21wb3NpdGUgdmFsdWVzIGNvbnN0aXR1dGUgYW4gaW52YWxpZCA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gaW5zdGFuY2UKKyAgICAgKiAgIGFzIGRldGVybWluZWQgYnkge0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyI2lzVmFsaWQoKX0uCisgICAgICovCisgICAgcHVibGljIFhNTEdyZWdvcmlhbkNhbGVuZGFyIG5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyVGltZSgKKyAgICAgICAgICAgIGZpbmFsIGludCBob3VycywKKyAgICAgICAgICAgIGZpbmFsIGludCBtaW51dGVzLAorICAgICAgICAgICAgZmluYWwgaW50IHNlY29uZHMsCisgICAgICAgICAgICBmaW5hbCBpbnQgbWlsbGlzZWNvbmRzLAorICAgICAgICAgICAgZmluYWwgaW50IHRpbWV6b25lKSB7CisKKyAgICAgICAgLy8gbWlsbGlzZWNvbmQgbWF5IGJlIHVuZGVmaW5lZAorICAgICAgICAvLyBtaWxsaXNlY29uZCBtdXN0IGJlID49IDAgbWlsbGlzZWNvbmQgPD0gMTAwMAorICAgICAgICBCaWdEZWNpbWFsIHJlYWxNaWxsaXNlY29uZHMgPSBudWxsOyAvLyB1bmRlZmluZWQgdmFsdWUKKyAgICAgICAgaWYgKG1pbGxpc2Vjb25kcyAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpIHsKKyAgICAgICAgICAgIGlmIChtaWxsaXNlY29uZHMgPCAwIHx8IG1pbGxpc2Vjb25kcyA+IDEwMDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgImphdmF4LnhtbC5kYXRhdHlwZS5EYXRhdHlwZUZhY3RvcnkjbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXJUaW1lKCIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgImludCBob3VycywgaW50IG1pbnV0ZXMsIGludCBzZWNvbmRzLCBpbnQgbWlsbGlzZWNvbmRzLCBpbnQgdGltZXpvbmUpIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAid2l0aCBpbnZhbGlkIG1pbGxpc2Vjb25kczogIiArIG1pbGxpc2Vjb25kcworICAgICAgICAgICAgICAgICk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZWFsTWlsbGlzZWNvbmRzID0gQmlnRGVjaW1hbC52YWx1ZU9mKChsb25nKSBtaWxsaXNlY29uZHMsIDMpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyVGltZSgKKyAgICAgICAgICAgICAgICBob3VycywKKyAgICAgICAgICAgICAgICBtaW51dGVzLAorICAgICAgICAgICAgICAgIHNlY29uZHMsCisgICAgICAgICAgICAgICAgcmVhbE1pbGxpc2Vjb25kcywKKyAgICAgICAgICAgICAgICB0aW1lem9uZQorICAgICAgICApOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvZGF0YXR5cGUvRHVyYXRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvZGF0YXR5cGUvRHVyYXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MTIxZDM2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9kYXRhdHlwZS9EdXJhdGlvbi5qYXZhCkBAIC0wLDAgKzEsOTg0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8kSWQ6IER1cmF0aW9uLmphdmEgNzU5ODI4IDIwMDktMDMtMzAgMDE6MjY6MjlaIG1yZ2xhdmFzICQKKworcGFja2FnZSBqYXZheC54bWwuZGF0YXR5cGU7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnRGVjaW1hbDsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyOworaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWU7CisKKy8qKgorICogPHA+SW1tdXRhYmxlIHJlcHJlc2VudGF0aW9uIG9mIGEgdGltZSBzcGFuIGFzIGRlZmluZWQgaW4KKyAqIHRoZSBXM0MgWE1MIFNjaGVtYSAxLjAgc3BlY2lmaWNhdGlvbi48L3A+CisgKgorICogPHA+QSBEdXJhdGlvbiBvYmplY3QgcmVwcmVzZW50cyBhIHBlcmlvZCBvZiBHcmVnb3JpYW4gdGltZSwKKyAqIHdoaWNoIGNvbnNpc3RzIG9mIHNpeCBmaWVsZHMgKHllYXJzLCBtb250aHMsIGRheXMsIGhvdXJzLAorICogbWludXRlcywgYW5kIHNlY29uZHMpIHBsdXMgYSBzaWduICgrLy0pIGZpZWxkLjwvcD4KKyAqCisgKiA8cD5UaGUgZmlyc3QgZml2ZSBmaWVsZHMgaGF2ZSBub24tbmVnYXRpdmUgKD49MCkgaW50ZWdlcnMgb3IgbnVsbAorICogKHdoaWNoIHJlcHJlc2VudHMgdGhhdCB0aGUgZmllbGQgaXMgbm90IHNldCksCisgKiBhbmQgdGhlIHNlY29uZHMgZmllbGQgaGFzIGEgbm9uLW5lZ2F0aXZlIGRlY2ltYWwgb3IgbnVsbC4KKyAqIEEgbmVnYXRpdmUgc2lnbiBpbmRpY2F0ZXMgYSBuZWdhdGl2ZSBkdXJhdGlvbi48L3A+CisgKgorICogPHA+VGhpcyBjbGFzcyBwcm92aWRlcyBhIG51bWJlciBvZiBtZXRob2RzIHRoYXQgbWFrZSBpdCBlYXN5CisgKiB0byB1c2UgZm9yIHRoZSBkdXJhdGlvbiBkYXRhdHlwZSBvZiBYTUwgU2NoZW1hIDEuMCB3aXRoCisgKiB0aGUgZXJyYXRhLjwvcD4KKyAqCisgKiA8aDI+T3JkZXIgcmVsYXRpb25zaGlwPC9oMj4KKyAqIDxwPkR1cmF0aW9uIG9iamVjdHMgb25seSBoYXZlIHBhcnRpYWwgb3JkZXIsIHdoZXJlIHR3byB2YWx1ZXMgQSBhbmQgQgorICogbWF5YmUgZWl0aGVyOjwvcD4KKyAqIDxvbD4KKyAqICA8bGk+QSZsdDtCIChBIGlzIHNob3J0ZXIgdGhhbiBCKQorICogIDxsaT5BJmd0O0IgKEEgaXMgbG9uZ2VyIHRoYW4gQikKKyAqICA8bGk+QT09QiAgIChBIGFuZCBCIGFyZSBvZiB0aGUgc2FtZSBkdXJhdGlvbikKKyAqICA8bGk+QSZsdDs+QiAoQ29tcGFyaXNvbiBiZXR3ZWVuIEEgYW5kIEIgaXMgaW5kZXRlcm1pbmF0ZSkKKyAqIDwvb2w+CisgKgorICogPHA+Rm9yIGV4YW1wbGUsIDMwIGRheXMgY2Fubm90IGJlIG1lYW5pbmdmdWxseSBjb21wYXJlZCB0byBvbmUgbW9udGguCisgKiBUaGUge0BsaW5rICNjb21wYXJlKER1cmF0aW9uIGR1cmF0aW9uKX0gbWV0aG9kIGltcGxlbWVudHMgdGhpcworICogcmVsYXRpb25zaGlwLjwvcD4KKyAqCisgKiA8cD5TZWUgdGhlIHtAbGluayAjaXNMb25nZXJUaGFuKER1cmF0aW9uKX0gbWV0aG9kIGZvciBkZXRhaWxzIGFib3V0CisgKiB0aGUgb3JkZXIgcmVsYXRpb25zaGlwIGFtb25nIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvYmplY3RzLjwvcD4KKyAqCisgKiA8aDI+T3BlcmF0aW9ucyBvdmVyIER1cmF0aW9uPC9oMj4KKyAqIDxwPlRoaXMgY2xhc3MgcHJvdmlkZXMgYSBzZXQgb2YgYmFzaWMgYXJpdGhtZXRpYyBvcGVyYXRpb25zLCBzdWNoCisgKiBhcyBhZGRpdGlvbiwgc3VidHJhY3Rpb24gYW5kIG11bHRpcGxpY2F0aW9uLgorICogQmVjYXVzZSBkdXJhdGlvbnMgZG9uJ3QgaGF2ZSB0b3RhbCBvcmRlciwgYW4gb3BlcmF0aW9uIGNvdWxkCisgKiBmYWlsIGZvciBzb21lIGNvbWJpbmF0aW9ucyBvZiBvcGVyYXRpb25zLiBGb3IgZXhhbXBsZSwgeW91IGNhbm5vdAorICogc3VidHJhY3QgMTUgZGF5cyBmcm9tIDEgbW9udGguIFNlZSB0aGUgamF2YWRvYyBvZiB0aG9zZSBtZXRob2RzCisgKiBmb3IgZGV0YWlsZWQgY29uZGl0aW9ucyB3aGVyZSB0aGlzIGNvdWxkIGhhcHBlbi48L3A+CisgKgorICogPHA+QWxzbywgZGl2aXNpb24gb2YgYSBkdXJhdGlvbiBieSBhIG51bWJlciBpcyBub3QgcHJvdmlkZWQgYmVjYXVzZQorICogdGhlIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBjbGFzcyBjYW4gb25seSBkZWFsIHdpdGggZmluaXRlIHByZWNpc2lvbgorICogZGVjaW1hbCBudW1iZXJzLiBGb3IgZXhhbXBsZSwgb25lIGNhbm5vdCByZXByZXNlbnQgMSBzZWMgZGl2aWRlZCBieSAzLjwvcD4KKyAqCisgKiA8cD5Ib3dldmVyLCB5b3UgY291bGQgc3Vic3RpdHV0ZSBhIGRpdmlzaW9uIGJ5IDMgd2l0aCBtdWx0aXBseWluZworICogYnkgbnVtYmVycyBzdWNoIGFzIDAuMyBvciAwLjMzMy48L3A+CisgKgorICogPGgyPlJhbmdlIG9mIGFsbG93ZWQgdmFsdWVzPC9oMj4KKyAqIDxwPgorICogQmVjYXVzZSBzb21lIG9wZXJhdGlvbnMgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+IHJlbHkgb24ge0BsaW5rIENhbGVuZGFyfQorICogZXZlbiB0aG91Z2gge0BsaW5rIER1cmF0aW9ufSBjYW4gaG9sZCB2ZXJ5IGxhcmdlIG9yIHZlcnkgc21hbGwgdmFsdWVzLAorICogc29tZSBvZiB0aGUgbWV0aG9kcyBtYXkgbm90IHdvcmsgY29ycmVjdGx5IG9uIHN1Y2ggPGNvZGU+RHVyYXRpb248L2NvZGU+cy4KKyAqIFRoZSBpbXBhY3RlZCBtZXRob2RzIGRvY3VtZW50IHRoZWlyIGRlcGVuZGVuY3kgb24ge0BsaW5rIENhbGVuZGFyfS4KKyAqCisgKgorICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86Sm9zZXBoLkZpYWxsaUBTdW4uQ09NIj5Kb3NlcGggRmlhbGxpPC9hPgorICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86S29oc3VrZS5LYXdhZ3VjaGlAU3VuLmNvbSI+S29oc3VrZSBLYXdhZ3VjaGk8L2E+CisgKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogNzU5ODI4ICQsICREYXRlOiAyMDA5LTAzLTI5IDE4OjI2OjI5IC0wNzAwIChTdW4sIDI5IE1hciAyMDA5KSAkCisgKiBAc2VlIFhNTEdyZWdvcmlhbkNhbGVuZGFyI2FkZChEdXJhdGlvbikKKyAqIEBzaW5jZSAxLjUKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzICAgRHVyYXRpb24geworCisgICAgLyoqCisgICAgICogPHA+UmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBYTUwgU2NoZW1hIGRhdGUvdGltZSB0eXBlIHRoYXQgdGhpcyBpbnN0YW5jZQorICAgICAqIG1hcHMgdG8uIFR5cGUgaXMgY29tcHV0ZWQgYmFzZWQgb24gZmllbGRzIHRoYXQgYXJlIHNldCwKKyAgICAgKiBpLmUuIHtAbGluayAjaXNTZXQoRGF0YXR5cGVDb25zdGFudHMuRmllbGQgZmllbGQpfSA9PSA8Y29kZT50cnVlPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiA8dGFibGUgYm9yZGVyPSIyIiBydWxlcz0iYWxsIiBjZWxscGFkZGluZz0iMiI+CisgICAgICogICA8dGhlYWQ+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGggYWxpZ249ImNlbnRlciIgY29sc3Bhbj0iNyI+CisgICAgICogICAgICAgICBSZXF1aXJlZCBmaWVsZHMgZm9yIFhNTCBTY2hlbWEgMS4wIERhdGUvVGltZSBEYXRhdHlwZXMuPGJyLz4KKyAgICAgKiAgICAgICAgIDxpPih0aW1lem9uZSBpcyBvcHRpb25hbCBmb3IgYWxsIGRhdGUvdGltZSBkYXRhdHlwZXMpPC9pPgorICAgICAqICAgICAgIDwvdGg+CisgICAgICogICAgIDwvdHI+CisgICAgICogICA8L3RoZWFkPgorICAgICAqICAgPHRib2R5PgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPkRhdGF0eXBlPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+eWVhcjwvdGQ+CisgICAgICogICAgICAgPHRkPm1vbnRoPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+ZGF5PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+aG91cjwvdGQ+CisgICAgICogICAgICAgPHRkPm1pbnV0ZTwvdGQ+CisgICAgICogICAgICAgPHRkPnNlY29uZDwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+e0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0RVUkFUSU9OfTwvdGQ+CisgICAgICogICAgICAgPHRkPlg8L3RkPgorICAgICAqICAgICAgIDx0ZD5YPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+WDwvdGQ+CisgICAgICogICAgICAgPHRkPlg8L3RkPgorICAgICAqICAgICAgIDx0ZD5YPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+WDwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+e0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0RVUkFUSU9OX0RBWVRJTUV9PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+WDwvdGQ+CisgICAgICogICAgICAgPHRkPlg8L3RkPgorICAgICAqICAgICAgIDx0ZD5YPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+WDwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+e0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0RVUkFUSU9OX1lFQVJNT05USH08L3RkPgorICAgICAqICAgICAgIDx0ZD5YPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+WDwvdGQ+CisgICAgICogICAgICAgPHRkPjwvdGQ+CisgICAgICogICAgICAgPHRkPjwvdGQ+CisgICAgICogICAgICAgPHRkPjwvdGQ+CisgICAgICogICAgICAgPHRkPjwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICA8L3Rib2R5PgorICAgICAqIDwvdGFibGU+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIG9uZSBvZiB0aGUgZm9sbG93aW5nIGNvbnN0YW50czoKKyAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNEVVJBVElPTn0sCisgICAgICogICB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRFVSQVRJT05fREFZVElNRX0gb3IKKyAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNEVVJBVElPTl9ZRUFSTU9OVEh9LgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gSWYgdGhlIGNvbWJpbmF0aW9uIG9mIHNldCBmaWVsZHMgZG9lcyBub3QgbWF0Y2ggb25lIG9mIHRoZSBYTUwgU2NoZW1hIGRhdGUvdGltZSBkYXRhdHlwZXMuCisgICAgICovCisgICAgcHVibGljIFFOYW1lIGdldFhNTFNjaGVtYVR5cGUoKSB7CisKKyAgICAgICAgYm9vbGVhbiB5ZWFyU2V0ID0gaXNTZXQoRGF0YXR5cGVDb25zdGFudHMuWUVBUlMpOworICAgICAgICBib29sZWFuIG1vbnRoU2V0ID0gaXNTZXQoRGF0YXR5cGVDb25zdGFudHMuTU9OVEhTKTsKKyAgICAgICAgYm9vbGVhbiBkYXlTZXQgPSBpc1NldChEYXRhdHlwZUNvbnN0YW50cy5EQVlTKTsKKyAgICAgICAgYm9vbGVhbiBob3VyU2V0ID0gaXNTZXQoRGF0YXR5cGVDb25zdGFudHMuSE9VUlMpOworICAgICAgICBib29sZWFuIG1pbnV0ZVNldCA9IGlzU2V0KERhdGF0eXBlQ29uc3RhbnRzLk1JTlVURVMpOworICAgICAgICBib29sZWFuIHNlY29uZFNldCA9IGlzU2V0KERhdGF0eXBlQ29uc3RhbnRzLlNFQ09ORFMpOworCisgICAgICAgIC8vIERVUkFUSU9OCisgICAgICAgIGlmICh5ZWFyU2V0CisgICAgICAgICAgICAgICAgJiYgbW9udGhTZXQKKyAgICAgICAgICAgICAgICAmJiBkYXlTZXQKKyAgICAgICAgICAgICAgICAmJiBob3VyU2V0CisgICAgICAgICAgICAgICAgJiYgbWludXRlU2V0CisgICAgICAgICAgICAgICAgJiYgc2Vjb25kU2V0KSB7CisgICAgICAgICAgICByZXR1cm4gRGF0YXR5cGVDb25zdGFudHMuRFVSQVRJT047CisgICAgICAgIH0KKworICAgICAgICAvLyBEVVJBVElPTl9EQVlUSU1FCisgICAgICAgIGlmICgheWVhclNldAorICAgICAgICAgICAgICAgICYmICFtb250aFNldAorICAgICAgICAgICAgICAgICYmIGRheVNldAorICAgICAgICAgICAgICAgICYmIGhvdXJTZXQKKyAgICAgICAgICAgICAgICAmJiBtaW51dGVTZXQKKyAgICAgICAgICAgICAgICAmJiBzZWNvbmRTZXQpIHsKKyAgICAgICAgICAgIHJldHVybiBEYXRhdHlwZUNvbnN0YW50cy5EVVJBVElPTl9EQVlUSU1FOworICAgICAgICB9CisKKyAgICAgICAgLy8gRFVSQVRJT05fWUVBUk1PTlRICisgICAgICAgIGlmICh5ZWFyU2V0CisgICAgICAgICAgICAgICAgJiYgbW9udGhTZXQKKyAgICAgICAgICAgICAgICAmJiAhZGF5U2V0CisgICAgICAgICAgICAgICAgJiYgIWhvdXJTZXQKKyAgICAgICAgICAgICAgICAmJiAhbWludXRlU2V0CisgICAgICAgICAgICAgICAgJiYgIXNlY29uZFNldCkgeworICAgICAgICAgICAgcmV0dXJuIERhdGF0eXBlQ29uc3RhbnRzLkRVUkFUSU9OX1lFQVJNT05USDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIG5vdGhpbmcgbWF0Y2hlcworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJqYXZheC54bWwuZGF0YXR5cGUuRHVyYXRpb24jZ2V0WE1MU2NoZW1hVHlwZSgpOiIKKyAgICAgICAgICAgICAgICArICIgdGhpcyBEdXJhdGlvbiBkb2VzIG5vdCBtYXRjaCBvbmUgb2YgdGhlIFhNTCBTY2hlbWEgZGF0ZS90aW1lIGRhdGF0eXBlczoiCisgICAgICAgICAgICAgICAgKyAiIHllYXIgc2V0ID0gIiArIHllYXJTZXQKKyAgICAgICAgICAgICAgICArICIgbW9udGggc2V0ID0gIiArIG1vbnRoU2V0CisgICAgICAgICAgICAgICAgKyAiIGRheSBzZXQgPSAiICsgZGF5U2V0CisgICAgICAgICAgICAgICAgKyAiIGhvdXIgc2V0ID0gIiArIGhvdXJTZXQKKyAgICAgICAgICAgICAgICArICIgbWludXRlIHNldCA9ICIgKyBtaW51dGVTZXQKKyAgICAgICAgICAgICAgICArICIgc2Vjb25kIHNldCA9ICIgKyBzZWNvbmRTZXQKKyAgICAgICAgKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzaWduIG9mIHRoaXMgZHVyYXRpb24gaW4gLTEsMCwgb3IgMS4KKyAgICAgKgorICAgICAqIEByZXR1cm4KKyAgICAgKiAgICAgIC0xIGlmIHRoaXMgZHVyYXRpb24gaXMgbmVnYXRpdmUsIDAgaWYgdGhlIGR1cmF0aW9uIGlzIHplcm8sCisgICAgICogICAgICBhbmQgMSBpZiB0aGUgZHVyYXRpb24gaXMgcG9zaXRpdmUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRTaWduKCk7CisKKyAgICAvKioKKyAgICAgKiA8cD5HZXQgdGhlIHllYXJzIHZhbHVlIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+IGFzIGFuIDxjb2RlPmludDwvY29kZT4gb3IgPGNvZGU+MDwvY29kZT4gaWYgbm90IHByZXNlbnQuPC9wPgorICAgICAqCisgICAgICogPHA+PGNvZGU+Z2V0WWVhcnMoKTwvY29kZT4gaXMgYSBjb252ZW5pZW5jZSBtZXRob2QgZm9yCisgICAgICoge0BsaW5rICNnZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5GaWVsZCBmaWVsZCkgZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuWUVBUlMpfS48L3A+CisgICAgICoKKyAgICAgKiA8cD5BcyB0aGUgcmV0dXJuIHZhbHVlIGlzIGFuIDxjb2RlPmludDwvY29kZT4sIGFuIGluY29ycmVjdCB2YWx1ZSB3aWxsIGJlIHJldHVybmVkIGZvciA8Y29kZT5EdXJhdGlvbjwvY29kZT5zCisgICAgICogd2l0aCB5ZWFycyB0aGF0IGdvIGJleW9uZCB0aGUgcmFuZ2Ugb2YgYW4gPGNvZGU+aW50PC9jb2RlPi4KKyAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5GaWVsZCBmaWVsZCkgZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuWUVBUlMpfSB0byBhdm9pZCBwb3NzaWJsZSBsb3NzIG9mIHByZWNpc2lvbi48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIElmIHRoZSB5ZWFycyBmaWVsZCBpcyBwcmVzZW50LCByZXR1cm4gaXRzIHZhbHVlIGFzIGFuIDxjb2RlPmludDwvY29kZT4sIGVsc2UgcmV0dXJuIDxjb2RlPjA8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0WWVhcnMoKSB7CisgICAgICAgIHJldHVybiBnZXRGaWVsZFZhbHVlQXNJbnQoRGF0YXR5cGVDb25zdGFudHMuWUVBUlMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE9idGFpbnMgdGhlIHZhbHVlIG9mIHRoZSBNT05USFMgZmllbGQgYXMgYW4gaW50ZWdlciB2YWx1ZSwKKyAgICAgKiBvciAwIGlmIG5vdCBwcmVzZW50LgorICAgICAqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MganVzdCBsaWtlIHtAbGluayAjZ2V0WWVhcnMoKX0gZXhjZXB0CisgICAgICogdGhhdCB0aGlzIG1ldGhvZCB3b3JrcyBvbiB0aGUgTU9OVEhTIGZpZWxkLgorICAgICAqCisgICAgICogQHJldHVybiBNb250aHMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNb250aHMoKSB7CisgICAgICAgIHJldHVybiBnZXRGaWVsZFZhbHVlQXNJbnQoRGF0YXR5cGVDb25zdGFudHMuTU9OVEhTKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPYnRhaW5zIHRoZSB2YWx1ZSBvZiB0aGUgREFZUyBmaWVsZCBhcyBhbiBpbnRlZ2VyIHZhbHVlLAorICAgICAqIG9yIDAgaWYgbm90IHByZXNlbnQuCisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBqdXN0IGxpa2Uge0BsaW5rICNnZXRZZWFycygpfSBleGNlcHQKKyAgICAgKiB0aGF0IHRoaXMgbWV0aG9kIHdvcmtzIG9uIHRoZSBEQVlTIGZpZWxkLgorICAgICAqCisgICAgICogQHJldHVybiBEYXlzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0RGF5cygpIHsKKyAgICAgICAgcmV0dXJuIGdldEZpZWxkVmFsdWVBc0ludChEYXRhdHlwZUNvbnN0YW50cy5EQVlTKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPYnRhaW5zIHRoZSB2YWx1ZSBvZiB0aGUgSE9VUlMgZmllbGQgYXMgYW4gaW50ZWdlciB2YWx1ZSwKKyAgICAgKiBvciAwIGlmIG5vdCBwcmVzZW50LgorICAgICAqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MganVzdCBsaWtlIHtAbGluayAjZ2V0WWVhcnMoKX0gZXhjZXB0CisgICAgICogdGhhdCB0aGlzIG1ldGhvZCB3b3JrcyBvbiB0aGUgSE9VUlMgZmllbGQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEhvdXJzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+LgorICAgICAqCisgICAgICovCisgICAgcHVibGljIGludCBnZXRIb3VycygpIHsKKyAgICAgICAgcmV0dXJuIGdldEZpZWxkVmFsdWVBc0ludChEYXRhdHlwZUNvbnN0YW50cy5IT1VSUyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT2J0YWlucyB0aGUgdmFsdWUgb2YgdGhlIE1JTlVURVMgZmllbGQgYXMgYW4gaW50ZWdlciB2YWx1ZSwKKyAgICAgKiBvciAwIGlmIG5vdCBwcmVzZW50LgorICAgICAqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MganVzdCBsaWtlIHtAbGluayAjZ2V0WWVhcnMoKX0gZXhjZXB0CisgICAgICogdGhhdCB0aGlzIG1ldGhvZCB3b3JrcyBvbiB0aGUgTUlOVVRFUyBmaWVsZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gTWludXRlcyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TWludXRlcygpIHsKKyAgICAgICAgcmV0dXJuIGdldEZpZWxkVmFsdWVBc0ludChEYXRhdHlwZUNvbnN0YW50cy5NSU5VVEVTKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPYnRhaW5zIHRoZSB2YWx1ZSBvZiB0aGUgU0VDT05EUyBmaWVsZCBhcyBhbiBpbnRlZ2VyIHZhbHVlLAorICAgICAqIG9yIDAgaWYgbm90IHByZXNlbnQuCisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBqdXN0IGxpa2Uge0BsaW5rICNnZXRZZWFycygpfSBleGNlcHQKKyAgICAgKiB0aGF0IHRoaXMgbWV0aG9kIHdvcmtzIG9uIHRoZSBTRUNPTkRTIGZpZWxkLgorICAgICAqCisgICAgICogQHJldHVybiBzZWNvbmRzIGluIHRoZSBpbnRlZ2VyIHZhbHVlLiBUaGUgZnJhY3Rpb24gb2Ygc2Vjb25kcworICAgICAqICAgd2lsbCBiZSBkaXNjYXJkZWQgKGZvciBleGFtcGxlLCBpZiB0aGUgYWN0dWFsIHZhbHVlIGlzIDIuNSwKKyAgICAgKiAgIHRoaXMgbWV0aG9kIHJldHVybnMgMikKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFNlY29uZHMoKSB7CisgICAgICAgIHJldHVybiBnZXRGaWVsZFZhbHVlQXNJbnQoRGF0YXR5cGVDb25zdGFudHMuU0VDT05EUyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+UmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMuPC9wPgorICAgICAqCisgICAgICogPHA+SWYgdGhlIHNlY29uZHMgZmllbGQgY2FycmllcyBtb3JlIGRpZ2l0cyB0aGFuIG1pbGxpc2Vjb25kIG9yZGVyLAorICAgICAqIHRob3NlIHdpbGwgYmUgc2ltcGx5IGRpc2NhcmRlZCAob3IgaW4gb3RoZXIgd29yZHMsIHJvdW5kZWQgdG8gemVyby4pCisgICAgICogRm9yIGV4YW1wbGUsIGZvciBhbnkgQ2FsZW5kYXIgdmFsdWUgPGNvZGU+eDwvY29kZT4sPC9wPgorICAgICAqIDxwcmU+CisgICAgICogPGNvZGU+bmV3IER1cmF0aW9uKCJQVDEwLjAwMDk5UyIpLmdldFRpbWVJbk1pbGxzKHgpID09IDEwMDAwPC9jb2RlPi4KKyAgICAgKiA8Y29kZT5uZXcgRHVyYXRpb24oIi1QVDEwLjAwMDk5UyIpLmdldFRpbWVJbk1pbGxzKHgpID09IC0xMDAwMDwvY29kZT4uCisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgdXNlcyB0aGUge0BsaW5rICNhZGRUbyhDYWxlbmRhcil9IG1ldGhvZCwKKyAgICAgKiB3aGljaCBtYXkgd29yayBpbmNvcnJlY3RseSB3aXRoIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvYmplY3RzIHdpdGgKKyAgICAgKiB2ZXJ5IGxhcmdlIHZhbHVlcyBpbiBpdHMgZmllbGRzLiBTZWUgdGhlIHtAbGluayAjYWRkVG8oQ2FsZW5kYXIpfQorICAgICAqIG1ldGhvZCBmb3IgZGV0YWlscy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdGFydEluc3RhbnQKKyAgICAgKiAgICAgIFRoZSBsZW5ndGggb2YgYSBtb250aC95ZWFyIHZhcmllcy4gVGhlIDxjb2RlPnN0YXJ0SW5zdGFudDwvY29kZT4gaXMKKyAgICAgKiAgICAgIHVzZWQgdG8gZGlzYW1iaWd1YXRlIHRoaXMgdmFyaWFuY2UuIFNwZWNpZmljYWxseSwgdGhpcyBtZXRob2QKKyAgICAgKiAgICAgIHJldHVybnMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiA8Y29kZT5zdGFydEluc3RhbnQ8L2NvZGU+IGFuZAorICAgICAqICAgICAgPGNvZGU+c3RhcnRJbnN0YW50K2R1cmF0aW9uPC9jb2RlPgorICAgICAqCisgICAgICogQHJldHVybiBtaWxsaXNlY29uZHMgYmV0d2VlbiA8Y29kZT5zdGFydEluc3RhbnQ8L2NvZGU+IGFuZAorICAgICAqICAgPGNvZGU+c3RhcnRJbnN0YW50PC9jb2RlPiBwbHVzIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+CisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnN0YXJ0SW5zdGFudDwvY29kZT4gcGFyYW1ldGVyCisgICAgICogaXMgbnVsbC4KKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFRpbWVJbk1pbGxpcyhmaW5hbCBDYWxlbmRhciBzdGFydEluc3RhbnQpIHsKKyAgICAgICAgQ2FsZW5kYXIgY2FsID0gKENhbGVuZGFyKSBzdGFydEluc3RhbnQuY2xvbmUoKTsKKyAgICAgICAgYWRkVG8oY2FsKTsKKyAgICAgICAgcmV0dXJuIGdldENhbGVuZGFyVGltZUluTWlsbGlzKGNhbCkKKyAgICAgICAgLSBnZXRDYWxlbmRhclRpbWVJbk1pbGxpcyhzdGFydEluc3RhbnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGUgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBzZWNvbmRzIGZpZWxkIGNhcnJpZXMgbW9yZSBkaWdpdHMgdGhhbiBtaWxsaXNlY29uZCBvcmRlciwKKyAgICAgKiB0aG9zZSB3aWxsIGJlIHNpbXBseSBkaXNjYXJkZWQgKG9yIGluIG90aGVyIHdvcmRzLCByb3VuZGVkIHRvIHplcm8uKQorICAgICAqIEZvciBleGFtcGxlLCBmb3IgYW55IDxjb2RlPkRhdGU8L2NvZGU+IHZhbHVlIDxjb2RlPng8L2NvZGU+LDwvcD4KKyAgICAgKiA8cHJlPgorICAgICAqIDxjb2RlPm5ldyBEdXJhdGlvbigiUFQxMC4wMDA5OVMiKS5nZXRUaW1lSW5NaWxscyh4KSA9PSAxMDAwMDwvY29kZT4uCisgICAgICogPGNvZGU+bmV3IER1cmF0aW9uKCItUFQxMC4wMDA5OVMiKS5nZXRUaW1lSW5NaWxscyh4KSA9PSAtMTAwMDA8L2NvZGU+LgorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogPHA+CisgICAgICogTm90ZSB0aGF0IHRoaXMgbWV0aG9kIHVzZXMgdGhlIHtAbGluayAjYWRkVG8oRGF0ZSl9IG1ldGhvZCwKKyAgICAgKiB3aGljaCBtYXkgd29yayBpbmNvcnJlY3RseSB3aXRoIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvYmplY3RzIHdpdGgKKyAgICAgKiB2ZXJ5IGxhcmdlIHZhbHVlcyBpbiBpdHMgZmllbGRzLiBTZWUgdGhlIHtAbGluayAjYWRkVG8oRGF0ZSl9CisgICAgICogbWV0aG9kIGZvciBkZXRhaWxzLgorICAgICAqCisgICAgICogQHBhcmFtIHN0YXJ0SW5zdGFudAorICAgICAqICAgICAgVGhlIGxlbmd0aCBvZiBhIG1vbnRoL3llYXIgdmFyaWVzLiBUaGUgPGNvZGU+c3RhcnRJbnN0YW50PC9jb2RlPiBpcworICAgICAqICAgICAgdXNlZCB0byBkaXNhbWJpZ3VhdGUgdGhpcyB2YXJpYW5jZS4gU3BlY2lmaWNhbGx5LCB0aGlzIG1ldGhvZAorICAgICAqICAgICAgcmV0dXJucyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIDxjb2RlPnN0YXJ0SW5zdGFudDwvY29kZT4gYW5kCisgICAgICogICAgICA8Y29kZT5zdGFydEluc3RhbnQrZHVyYXRpb248L2NvZGU+LgorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgSWYgdGhlIHN0YXJ0SW5zdGFudCBwYXJhbWV0ZXIgaXMgbnVsbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gbWlsbGlzZWNvbmRzIGJldHdlZW4gPGNvZGU+c3RhcnRJbnN0YW50PC9jb2RlPiBhbmQKKyAgICAgKiAgIDxjb2RlPnN0YXJ0SW5zdGFudDwvY29kZT4gcGx1cyB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPgorICAgICAqCisgICAgICogQHNlZSAjZ2V0VGltZUluTWlsbGlzKENhbGVuZGFyKQorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFRpbWVJbk1pbGxpcyhmaW5hbCBEYXRlIHN0YXJ0SW5zdGFudCkgeworICAgICAgICBDYWxlbmRhciBjYWwgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoKTsKKyAgICAgICAgY2FsLnNldFRpbWUoc3RhcnRJbnN0YW50KTsKKyAgICAgICAgdGhpcy5hZGRUbyhjYWwpOworICAgICAgICByZXR1cm4gZ2V0Q2FsZW5kYXJUaW1lSW5NaWxsaXMoY2FsKSAtIHN0YXJ0SW5zdGFudC5nZXRUaW1lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBmaWVsZC4KKyAgICAgKgorICAgICAqIEZpZWxkcyBvZiBhIGR1cmF0aW9uIG9iamVjdCBtYXkgY29udGFpbiBhcmJpdHJhcnkgbGFyZ2UgdmFsdWUuCisgICAgICogVGhlcmVmb3JlIHRoaXMgbWV0aG9kIGlzIGRlc2lnbmVkIHRvIHJldHVybiBhIHtAbGluayBOdW1iZXJ9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEluIGNhc2Ugb2YgWUVBUlMsIE1PTlRIUywgREFZUywgSE9VUlMsIGFuZCBNSU5VVEVTLCB0aGUgcmV0dXJuZWQKKyAgICAgKiBudW1iZXIgd2lsbCBiZSBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyLiBJbiBjYXNlIG9mIHNlY29uZHMsCisgICAgICogdGhlIHJldHVybmVkIG51bWJlciBtYXkgYmUgYSBub24tbmVnYXRpdmUgZGVjaW1hbCB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZAorICAgICAqICAgICAgb25lIG9mIHRoZSBzaXggRmllbGQgY29uc3RhbnRzIChZRUFSUyxNT05USFMsREFZUyxIT1VSUywKKyAgICAgKiAgICAgIE1JTlVURVMsIG9yIFNFQ09ORFMuKQorICAgICAqIEByZXR1cm4KKyAgICAgKiAgICAgIElmIHRoZSBzcGVjaWZpZWQgZmllbGQgaXMgcHJlc2VudCwgdGhpcyBtZXRob2QgcmV0dXJucworICAgICAqICAgICAgYSBub24tbnVsbCBub24tbmVnYXRpdmUge0BsaW5rIE51bWJlcn0gb2JqZWN0IHRoYXQKKyAgICAgKiAgICAgIHJlcHJlc2VudHMgaXRzIHZhbHVlLiBJZiBpdCBpcyBub3QgcHJlc2VudCwgcmV0dXJuIG51bGwuCisgICAgICogICAgICBGb3IgWUVBUlMsIE1PTlRIUywgREFZUywgSE9VUlMsIGFuZCBNSU5VVEVTLCB0aGlzIG1ldGhvZAorICAgICAqICAgICAgcmV0dXJucyBhIHtAbGluayBqYXZhLm1hdGguQmlnSW50ZWdlcn0gb2JqZWN0LiBGb3IgU0VDT05EUywgdGhpcworICAgICAqICAgICAgbWV0aG9kIHJldHVybnMgYSB7QGxpbmsgamF2YS5tYXRoLkJpZ0RlY2ltYWx9LgorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiB0aGUgPGNvZGU+ZmllbGQ8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBOdW1iZXIgZ2V0RmllbGQoZmluYWwgRGF0YXR5cGVDb25zdGFudHMuRmllbGQgZmllbGQpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBmaWVsZCBhcyBhbiA8Y29kZT5pbnQ8L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkCisgICAgICogICAgICBvbmUgb2YgdGhlIHNpeCBGaWVsZCBjb25zdGFudHMgKFlFQVJTLE1PTlRIUyxEQVlTLEhPVVJTLAorICAgICAqICAgICAgTUlOVVRFUywgb3IgU0VDT05EUy4pCisgICAgICogQHJldHVybgorICAgICAqICAgICAgSWYgdGhlIGZpZWxkIGlzIHByZXNlbnQsIHJldHVybiBpdHMgdmFsdWUgYXMgYW4gPGNvZGU+aW50PC9jb2RlPiwKKyAgICAgKiAgICAgIGVsc2UgcmV0dXJuIDxjb2RlPjA8L2NvZGU+LgorICAgICAqLworICAgIHByaXZhdGUgaW50IGdldEZpZWxkVmFsdWVBc0ludChmaW5hbCBEYXRhdHlwZUNvbnN0YW50cy5GaWVsZCBmaWVsZCkgeworICAgICAgICBOdW1iZXIgbiA9IGdldEZpZWxkKGZpZWxkKTsKKyAgICAgICAgaWYgKG4gIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG4uaW50VmFsdWUoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgYSBmaWVsZCBpcyBzZXQuCisgICAgICoKKyAgICAgKiBBIGZpZWxkIG9mIGEgZHVyYXRpb24gb2JqZWN0IG1heSBvciBtYXkgbm90IGJlIHByZXNlbnQuCisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gdGVzdCBpZiBhIGZpZWxkIGlzIHByZXNlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmllbGQKKyAgICAgKiAgICAgIG9uZSBvZiB0aGUgc2l4IEZpZWxkIGNvbnN0YW50cyAoWUVBUlMsTU9OVEhTLERBWVMsSE9VUlMsCisgICAgICogICAgICBNSU5VVEVTLCBvciBTRUNPTkRTLikKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICB0cnVlIGlmIHRoZSBmaWVsZCBpcyBwcmVzZW50LiBmYWxzZSBpZiBub3QuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICBJZiB0aGUgZmllbGQgcGFyYW1ldGVyIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNTZXQoZmluYWwgRGF0YXR5cGVDb25zdGFudHMuRmllbGQgZmllbGQpOworCisgICAgLyoqCisgICAgICogPHA+Q29tcHV0ZXMgYSBuZXcgZHVyYXRpb24gd2hvc2UgdmFsdWUgaXMgPGNvZGU+dGhpcytyaHM8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPkZvciBleGFtcGxlLDwvcD4KKyAgICAgKiA8cHJlPgorICAgICAqICIxIGRheSIgKyAiLTMgZGF5cyIgPSAiLTIgZGF5cyIKKyAgICAgKiAiMSB5ZWFyIiArICIxIGRheSIgPSAiMSB5ZWFyIGFuZCAxIGRheSIKKyAgICAgKiAiLSgxIGhvdXIsNTAgbWludXRlcykiICsgIi0yMCBtaW51dGVzIiA9ICItKDEgaG91cnMsNzAgbWludXRlcykiCisgICAgICogIjE1IGhvdXJzIiArICItMyBkYXlzIiA9ICItKDIgZGF5cyw5IGhvdXJzKSIKKyAgICAgKiAiMSB5ZWFyIiArICItMSBkYXkiID0gSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiA8cD5TaW5jZSB0aGVyZSdzIG5vIHdheSB0byBtZWFuaW5nZnVsbHkgc3VidHJhY3QgMSBkYXkgZnJvbSAxIG1vbnRoLAorICAgICAqIHRoZXJlIGFyZSBjYXNlcyB3aGVyZSB0aGUgb3BlcmF0aW9uIGZhaWxzIGluCisgICAgICoge0BsaW5rIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbn0uPC9wPgorICAgICAqCisgICAgICogPHA+CisgICAgICogRm9ybWFsbHksIHRoZSBjb21wdXRhdGlvbiBpcyBkZWZpbmVkIGFzIGZvbGxvd3MuPC9wPgorICAgICAqIDxwPgorICAgICAqIEZpcnN0bHksIHdlIGNhbiBhc3N1bWUgdGhhdCB0d28gPGNvZGU+RHVyYXRpb248L2NvZGU+cyB0byBiZSBhZGRlZAorICAgICAqIGFyZSBib3RoIHBvc2l0aXZlIHdpdGhvdXQgbG9zaW5nIGdlbmVyYWxpdHkgKGkuZS4sCisgICAgICogPGNvZGU+KC1YKStZPVktWDwvY29kZT4sIDxjb2RlPlgrKC1ZKT1YLVk8L2NvZGU+LAorICAgICAqIDxjb2RlPigtWCkrKC1ZKT0tKFgrWSk8L2NvZGU+KQorICAgICAqCisgICAgICogPHA+CisgICAgICogQWRkaXRpb24gb2YgdHdvIHBvc2l0aXZlIDxjb2RlPkR1cmF0aW9uPC9jb2RlPnMgYXJlIHNpbXBseSBkZWZpbmVkIGFzCisgICAgICogZmllbGQgYnkgZmllbGQgYWRkaXRpb24gd2hlcmUgbWlzc2luZyBmaWVsZHMgYXJlIHRyZWF0ZWQgYXMgMC4KKyAgICAgKiA8cD4KKyAgICAgKiBBIGZpZWxkIG9mIHRoZSByZXN1bHRpbmcgPGNvZGU+RHVyYXRpb248L2NvZGU+IHdpbGwgYmUgdW5zZXQgaWYgYW5kCisgICAgICogb25seSBpZiByZXNwZWN0aXZlIGZpZWxkcyBvZiB0d28gaW5wdXQgPGNvZGU+RHVyYXRpb248L2NvZGU+cyBhcmUgdW5zZXQuCisgICAgICogPHA+CisgICAgICogTm90ZSB0aGF0IDxjb2RlPmxocy5hZGQocmhzKTwvY29kZT4gd2lsbCBiZSBhbHdheXMgc3VjY2Vzc2Z1bCBpZgorICAgICAqIDxjb2RlPmxocy5zaWdudW0oKSpyaHMuc2lnbnVtKCkhPS0xPC9jb2RlPiBvciBib3RoIG9mIHRoZW0gYXJlCisgICAgICogbm9ybWFsaXplZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcmhzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiB0byBhZGQgdG8gdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KKyAgICAgKgorICAgICAqIEByZXR1cm4KKyAgICAgKiAgICAgIG5vbi1udWxsIHZhbGlkIER1cmF0aW9uIG9iamVjdC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgIElmIHRoZSByaHMgcGFyYW1ldGVyIGlzIG51bGwuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgIElmIHR3byBkdXJhdGlvbnMgY2Fubm90IGJlIG1lYW5pbmdmdWxseSBhZGRlZC4gRm9yCisgICAgICogICAgICBleGFtcGxlLCBhZGRpbmcgbmVnYXRpdmUgb25lIGRheSB0byBvbmUgbW9udGggY2F1c2VzCisgICAgICogICAgICB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqCisgICAgICogQHNlZSAjc3VidHJhY3QoRHVyYXRpb24pCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IER1cmF0aW9uIGFkZChmaW5hbCBEdXJhdGlvbiByaHMpOworCisgICAgLyoqCisgICAgICogQWRkcyB0aGlzIGR1cmF0aW9uIHRvIGEge0BsaW5rIENhbGVuZGFyfSBvYmplY3QuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBDYWxscyB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI2FkZChpbnQsaW50KX0gaW4gdGhlCisgICAgICogb3JkZXIgb2YgWUVBUlMsIE1PTlRIUywgREFZUywgSE9VUlMsIE1JTlVURVMsIFNFQ09ORFMsIGFuZCBNSUxMSVNFQ09ORFMKKyAgICAgKiBpZiB0aG9zZSBmaWVsZHMgYXJlIHByZXNlbnQuIEJlY2F1c2UgdGhlIHtAbGluayBDYWxlbmRhcn0gY2xhc3MKKyAgICAgKiB1c2VzIGludCB0byBob2xkIHZhbHVlcywgdGhlcmUgYXJlIGNhc2VzIHdoZXJlIHRoaXMgbWV0aG9kCisgICAgICogd29uJ3Qgd29yayBjb3JyZWN0bHkgKGZvciBleGFtcGxlIGlmIHZhbHVlcyBvZiBmaWVsZHMKKyAgICAgKiBleGNlZWQgdGhlIHJhbmdlIG9mIGludC4pCisgICAgICogPC9wPgorICAgICAqCisgICAgICogPHA+CisgICAgICogQWxzbywgc2luY2UgdGhpcyBkdXJhdGlvbiBjbGFzcyBpcyBhIEdyZWdvcmlhbiBkdXJhdGlvbiwgdGhpcworICAgICAqIG1ldGhvZCB3aWxsIG5vdCB3b3JrIGNvcnJlY3RseSBpZiB0aGUgZ2l2ZW4ge0BsaW5rIENhbGVuZGFyfQorICAgICAqIG9iamVjdCBpcyBiYXNlZCBvbiBzb21lIG90aGVyIGNhbGVuZGFyIHN5c3RlbXMuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogPHA+CisgICAgICogQW55IGZyYWN0aW9uYWwgcGFydHMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2JqZWN0CisgICAgICogYmV5b25kIG1pbGxpc2Vjb25kcyB3aWxsIGJlIHNpbXBseSBpZ25vcmVkLiBGb3IgZXhhbXBsZSwgaWYKKyAgICAgKiB0aGlzIGR1cmF0aW9uIGlzICJQMS4yMzQ1NlMiLCB0aGVuIDEgaXMgYWRkZWQgdG8gU0VDT05EUywKKyAgICAgKiAyMzQgaXMgYWRkZWQgdG8gTUlMTElTRUNPTkRTLCBhbmQgdGhlIHJlc3Qgd2lsbCBiZSB1bnVzZWQuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogPHA+CisgICAgICogTm90ZSB0aGF0IGJlY2F1c2Uge0BsaW5rIENhbGVuZGFyI2FkZChpbnQsIGludCl9IGlzIHVzaW5nCisgICAgICogPHR0PmludDwvdHQ+LCA8Y29kZT5EdXJhdGlvbjwvY29kZT4gd2l0aCB2YWx1ZXMgYmV5b25kIHRoZQorICAgICAqIHJhbmdlIG9mIDx0dD5pbnQ8L3R0PiBpbiBpdHMgZmllbGRzCisgICAgICogd2lsbCBjYXVzZSBvdmVyZmxvdy91bmRlcmZsb3cgdG8gdGhlIGdpdmVuIHtAbGluayBDYWxlbmRhcn0uCisgICAgICoge0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyI2FkZChEdXJhdGlvbil9IHByb3ZpZGVzIHRoZSBzYW1lCisgICAgICogYmFzaWMgb3BlcmF0aW9uIGFzIHRoaXMgbWV0aG9kIHdoaWxlIGF2b2lkaW5nCisgICAgICogdGhlIG92ZXJmbG93L3VuZGVyZmxvdyBpc3N1ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2FsZW5kYXIKKyAgICAgKiAgICAgIEEgY2FsZW5kYXIgb2JqZWN0IHdob3NlIHZhbHVlIHdpbGwgYmUgbW9kaWZpZWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgaWYgdGhlIGNhbGVuZGFyIHBhcmFtZXRlciBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGFkZFRvKENhbGVuZGFyIGNhbGVuZGFyKTsKKworICAgIC8qKgorICAgICAqIEFkZHMgdGhpcyBkdXJhdGlvbiB0byBhIHtAbGluayBEYXRlfSBvYmplY3QuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZ2l2ZW4gZGF0ZSBpcyBmaXJzdCBjb252ZXJ0ZWQgaW50bworICAgICAqIGEge0BsaW5rIGphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcn0sIHRoZW4gdGhlIGR1cmF0aW9uCisgICAgICogaXMgYWRkZWQgZXhhY3RseSBsaWtlIHRoZSB7QGxpbmsgI2FkZFRvKENhbGVuZGFyKX0gbWV0aG9kLgorICAgICAqCisgICAgICogPHA+CisgICAgICogVGhlIHVwZGF0ZWQgdGltZSBpbnN0YW50IGlzIHRoZW4gY29udmVydGVkIGJhY2sgaW50byBhCisgICAgICoge0BsaW5rIERhdGV9IG9iamVjdCBhbmQgdXNlZCB0byB1cGRhdGUgdGhlIGdpdmVuIHtAbGluayBEYXRlfSBvYmplY3QuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIHNvbWV3aGF0IHJlZHVuZGFudCBjb21wdXRhdGlvbiBpcyBuZWNlc3NhcnkgdG8gdW5hbWJpZ3VvdXNseQorICAgICAqIGRldGVybWluZSB0aGUgZHVyYXRpb24gb2YgbW9udGhzIGFuZCB5ZWFycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRlCisgICAgICogICAgICBBIGRhdGUgb2JqZWN0IHdob3NlIHZhbHVlIHdpbGwgYmUgbW9kaWZpZWQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgaWYgdGhlIGRhdGUgcGFyYW1ldGVyIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkVG8oRGF0ZSBkYXRlKSB7CisKKyAgICAgICAgLy8gY2hlY2sgZGF0YSBwYXJhbWV0ZXIKKyAgICAgICAgaWYgKGRhdGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IGNhbGwgIgorICAgICAgICAgICAgICAgICAgICArIHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgKyAiI2FkZFRvKERhdGUgZGF0ZSkgd2l0aCBkYXRlID09IG51bGwuIgorICAgICAgICAgICAgKTsKKyAgICAgICAgfQorCisgICAgICAgIENhbGVuZGFyIGNhbCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigpOworICAgICAgICBjYWwuc2V0VGltZShkYXRlKTsKKyAgICAgICAgdGhpcy5hZGRUbyhjYWwpOworICAgICAgICBkYXRlLnNldFRpbWUoZ2V0Q2FsZW5kYXJUaW1lSW5NaWxsaXMoY2FsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+Q29tcHV0ZXMgYSBuZXcgZHVyYXRpb24gd2hvc2UgdmFsdWUgaXMgPGNvZGU+dGhpcy1yaHM8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPkZvciBleGFtcGxlOjwvcD4KKyAgICAgKiA8cHJlPgorICAgICAqICIxIGRheSIgLSAiLTMgZGF5cyIgPSAiNCBkYXlzIgorICAgICAqICIxIHllYXIiIC0gIjEgZGF5IiA9IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICItKDEgaG91ciw1MCBtaW51dGVzKSIgLSAiLTIwIG1pbnV0ZXMiID0gIi0oMWhvdXJzLDMwIG1pbnV0ZXMpIgorICAgICAqICIxNSBob3VycyIgLSAiLTMgZGF5cyIgPSAiMyBkYXlzIGFuZCAxNSBob3VycyIKKyAgICAgKiAiMSB5ZWFyIiAtICItMSBkYXkiID0gIjEgeWVhciBhbmQgMSBkYXkiCisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiA8cD5TaW5jZSB0aGVyZSdzIG5vIHdheSB0byBtZWFuaW5nZnVsbHkgc3VidHJhY3QgMSBkYXkgZnJvbSAxIG1vbnRoLAorICAgICAqIHRoZXJlIGFyZSBjYXNlcyB3aGVyZSB0aGUgb3BlcmF0aW9uIGZhaWxzIGluIHtAbGluayBJbGxlZ2FsU3RhdGVFeGNlcHRpb259LjwvcD4KKyAgICAgKgorICAgICAqIDxwPkZvcm1hbGx5IHRoZSBjb21wdXRhdGlvbiBpcyBkZWZpbmVkIGFzIGZvbGxvd3MuCisgICAgICogRmlyc3QsIHdlIGNhbiBhc3N1bWUgdGhhdCB0d28gPGNvZGU+RHVyYXRpb248L2NvZGU+cyBhcmUgYm90aCBwb3NpdGl2ZQorICAgICAqIHdpdGhvdXQgbG9zaW5nIGdlbmVyYWxpdHkuICAoaS5lLiwKKyAgICAgKiA8Y29kZT4oLVgpLVk9LShYK1kpPC9jb2RlPiwgPGNvZGU+WC0oLVkpPVgrWTwvY29kZT4sCisgICAgICogPGNvZGU+KC1YKS0oLVkpPS0oWC1ZKTwvY29kZT4pPC9wPgorICAgICAqCisgICAgICogPHA+VGhlbiB0d28gZHVyYXRpb25zIGFyZSBzdWJ0cmFjdGVkIGZpZWxkIGJ5IGZpZWxkLgorICAgICAqIElmIHRoZSBzaWduIG9mIGFueSBub24temVybyBmaWVsZCA8dHQ+RjwvdHQ+IGlzIGRpZmZlcmVudCBmcm9tCisgICAgICogdGhlIHNpZ24gb2YgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgZmllbGQsCisgICAgICogMSAoaWYgPHR0PkY8L3R0PiBpcyBuZWdhdGl2ZSkgb3IgLTEgKG90aGVyd2lzZSkKKyAgICAgKiB3aWxsIGJlIGJvcnJvd2VkIGZyb20gdGhlIG5leHQgYmlnZ2VyIHVuaXQgb2YgPHR0PkY8L3R0Pi48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIHByb2Nlc3MgaXMgcmVwZWF0ZWQgdW50aWwgYWxsIHRoZSBub24temVybyBmaWVsZHMgaGF2ZQorICAgICAqIHRoZSBzYW1lIHNpZ24uPC9wPgorICAgICAqCisgICAgICogPHA+SWYgYSBib3Jyb3cgb2NjdXJzIGluIHRoZSBkYXlzIGZpZWxkIChpbiBvdGhlciB3b3JkcywgaWYKKyAgICAgKiB0aGUgY29tcHV0YXRpb24gbmVlZHMgdG8gYm9ycm93IDEgb3IgLTEgbW9udGggdG8gY29tcGVuc2F0ZQorICAgICAqIGRheXMpLCB0aGVuIHRoZSBjb21wdXRhdGlvbiBmYWlscyBieSB0aHJvd2luZyBhbgorICAgICAqIHtAbGluayBJbGxlZ2FsU3RhdGVFeGNlcHRpb259LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSByaHMgPGNvZGU+RHVyYXRpb248L2NvZGU+IHRvIHN1YnRyYWN0IGZyb20gdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCBmcm9tIHN1YnRyYWN0aW5nIDxjb2RlPnJoczwvY29kZT4gZnJvbSB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgICogICAgICBJZiB0d28gZHVyYXRpb25zIGNhbm5vdCBiZSBtZWFuaW5nZnVsbHkgc3VidHJhY3RlZC4gRm9yCisgICAgICogICAgICBleGFtcGxlLCBzdWJ0cmFjdGluZyBvbmUgZGF5IGZyb20gb25lIG1vbnRoIGNhdXNlcworICAgICAqICAgICAgdGhpcyBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICBJZiB0aGUgcmhzIHBhcmFtZXRlciBpcyBudWxsLgorICAgICAqCisgICAgICogQHNlZSAjYWRkKER1cmF0aW9uKQorICAgICAqLworICAgIHB1YmxpYyBEdXJhdGlvbiBzdWJ0cmFjdChmaW5hbCBEdXJhdGlvbiByaHMpIHsKKyAgICAgICAgcmV0dXJuIGFkZChyaHMubmVnYXRlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkNvbXB1dGVzIGEgbmV3IGR1cmF0aW9uIHdob3NlIHZhbHVlIGlzIDxjb2RlPmZhY3RvcjwvY29kZT4gdGltZXMKKyAgICAgKiBsb25nZXIgdGhhbiB0aGUgdmFsdWUgb2YgdGhpcyBkdXJhdGlvbi48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBwcm92aWRlZCBmb3IgdGhlIGNvbnZlbmllbmNlLgorICAgICAqIEl0IGlzIGZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IHRvIHRoZSBmb2xsb3dpbmcgY29kZTo8L3A+CisgICAgICogPHByZT4KKyAgICAgKiBtdWx0aXBseShuZXcgQmlnRGVjaW1hbChTdHJpbmcudmFsdWVPZihmYWN0b3IpKSkKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmYWN0b3IgRmFjdG9yIHRpbWVzIGxvbmdlciBvZiBuZXcgPGNvZGU+RHVyYXRpb248L2NvZGU+IHRvIGNyZWF0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gTmV3IDxjb2RlPkR1cmF0aW9uPC9jb2RlPiB0aGF0IGlzIDxjb2RlPmZhY3RvcjwvY29kZT50aW1lcyBsb25nZXIgdGhhbiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBzZWUgI211bHRpcGx5KEJpZ0RlY2ltYWwpCisgICAgICovCisgICAgcHVibGljIER1cmF0aW9uIG11bHRpcGx5KGludCBmYWN0b3IpIHsKKyAgICAgICAgcmV0dXJuIG11bHRpcGx5KEJpZ0RlY2ltYWwudmFsdWVPZihmYWN0b3IpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlcyBhIG5ldyBkdXJhdGlvbiB3aG9zZSB2YWx1ZSBpcyA8Y29kZT5mYWN0b3I8L2NvZGU+IHRpbWVzCisgICAgICogbG9uZ2VyIHRoYW4gdGhlIHZhbHVlIG9mIHRoaXMgZHVyYXRpb24uCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBGb3IgZXhhbXBsZSwKKyAgICAgKiA8cHJlPgorICAgICAqICJQMU0iICgxIG1vbnRoKSAqICIxMiIgPSAiUDEyTSIgKDEyIG1vbnRocykKKyAgICAgKiAiUFQxTSIgKDEgbWluKSAqICIwLjMiID0gIlBUMThTIiAoMTggc2Vjb25kcykKKyAgICAgKiAiUDFNIiAoMSBtb250aCkgKiAiMS41IiA9IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogPHA+CisgICAgICogU2luY2UgdGhlIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBjbGFzcyBpcyBpbW11dGFibGUsIHRoaXMgbWV0aG9kCisgICAgICogZG9lc24ndCBjaGFuZ2UgdGhlIHZhbHVlIG9mIHRoaXMgb2JqZWN0LiBJdCBzaW1wbHkgY29tcHV0ZXMKKyAgICAgKiBhIG5ldyBEdXJhdGlvbiBvYmplY3QgYW5kIHJldHVybnMgaXQuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgb3BlcmF0aW9uIHdpbGwgYmUgcGVyZm9ybWVkIGZpZWxkIGJ5IGZpZWxkIHdpdGggdGhlIHByZWNpc2lvbgorICAgICAqIG9mIHtAbGluayBCaWdEZWNpbWFsfS4gU2luY2UgYWxsIHRoZSBmaWVsZHMgZXhjZXB0IHNlY29uZHMgYXJlCisgICAgICogcmVzdHJpY3RlZCB0byBob2xkIGludGVnZXJzLAorICAgICAqIGFueSBmcmFjdGlvbiBwcm9kdWNlZCBieSB0aGUgY29tcHV0YXRpb24gd2lsbCBiZQorICAgICAqIGNhcnJpZWQgZG93biB0b3dhcmQgdGhlIG5leHQgbG93ZXIgdW5pdC4gRm9yIGV4YW1wbGUsCisgICAgICogaWYgeW91IG11bHRpcGx5ICJQMUQiICgxIGRheSkgd2l0aCAiMC41IiwgdGhlbiBpdCB3aWxsIGJlIDAuNSBkYXksCisgICAgICogd2hpY2ggd2lsbCBiZSBjYXJyaWVkIGRvd24gdG8gIlBUMTJIIiAoMTIgaG91cnMpLgorICAgICAqIFdoZW4gZnJhY3Rpb25zIG9mIG1vbnRoIGNhbm5vdCBiZSBtZWFuaW5nZnVsbHkgY2FycmllZCBkb3duCisgICAgICogdG8gZGF5cywgb3IgeWVhciB0byBtb250aHMsIHRoaXMgd2lsbCBjYXVzZSBhbgorICAgICAqIHtAbGluayBJbGxlZ2FsU3RhdGVFeGNlcHRpb259IHRvIGJlIHRocm93bi4KKyAgICAgKiBGb3IgZXhhbXBsZSBpZiB5b3UgbXVsdGlwbGUgb25lIG1vbnRoIGJ5IDAuNS48L3A+CisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUbyBhdm9pZCB7QGxpbmsgSWxsZWdhbFN0YXRlRXhjZXB0aW9ufSwgdXNlCisgICAgICogdGhlIHtAbGluayAjbm9ybWFsaXplV2l0aChDYWxlbmRhcil9IG1ldGhvZCB0byByZW1vdmUgdGhlIHllYXJzCisgICAgICogYW5kIG1vbnRocyBmaWVsZHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmFjdG9yIHRvIG11bHRpcGx5IGJ5CisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICByZXR1cm5zIGEgbm9uLW51bGwgdmFsaWQgPGNvZGU+RHVyYXRpb248L2NvZGU+IG9iamVjdAorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgb3BlcmF0aW9uIHByb2R1Y2VzIGZyYWN0aW9uIGluCisgICAgICogdGhlIG1vbnRocyBmaWVsZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIDxjb2RlPmZhY3RvcjwvY29kZT4gcGFyYW1ldGVyIGlzCisgICAgICogPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRHVyYXRpb24gbXVsdGlwbHkoZmluYWwgQmlnRGVjaW1hbCBmYWN0b3IpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2JqZWN0IHdob3NlCisgICAgICogdmFsdWUgaXMgPGNvZGU+LXRoaXM8L2NvZGU+LgorICAgICAqCisgICAgICogPHA+CisgICAgICogU2luY2UgdGhlIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBjbGFzcyBpcyBpbW11dGFibGUsIHRoaXMgbWV0aG9kCisgICAgICogZG9lc24ndCBjaGFuZ2UgdGhlIHZhbHVlIG9mIHRoaXMgb2JqZWN0LiBJdCBzaW1wbHkgY29tcHV0ZXMKKyAgICAgKiBhIG5ldyBEdXJhdGlvbiBvYmplY3QgYW5kIHJldHVybnMgaXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICBhbHdheXMgcmV0dXJuIGEgbm9uLW51bGwgdmFsaWQgPGNvZGU+RHVyYXRpb248L2NvZGU+IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRHVyYXRpb24gbmVnYXRlKCk7CisKKyAgICAvKioKKyAgICAgKiA8cD5Db252ZXJ0cyB0aGUgeWVhcnMgYW5kIG1vbnRocyBmaWVsZHMgaW50byB0aGUgZGF5cyBmaWVsZAorICAgICAqIGJ5IHVzaW5nIGEgc3BlY2lmaWMgdGltZSBpbnN0YW50IGFzIHRoZSByZWZlcmVuY2UgcG9pbnQuPC9wPgorICAgICAqCisgICAgICogPHA+Rm9yIGV4YW1wbGUsIGR1cmF0aW9uIG9mIG9uZSBtb250aCBub3JtYWxpemVzIHRvIDMxIGRheXMKKyAgICAgKiBnaXZlbiB0aGUgc3RhcnQgdGltZSBpbnN0YW5jZSAiSnVseSA4dGggMjAwMywgMTc6NDA6MzIiLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkZvcm1hbGx5LCB0aGUgY29tcHV0YXRpb24gaXMgZG9uZSBhcyBmb2xsb3dzOjwvcD4KKyAgICAgKiA8b2w+CisgICAgICogIDxsaT50aGUgZ2l2ZW4gQ2FsZW5kYXIgb2JqZWN0IGlzIGNsb25lZDwvbGk+CisgICAgICogIDxsaT50aGUgeWVhcnMsIG1vbnRocyBhbmQgZGF5cyBmaWVsZHMgd2lsbCBiZSBhZGRlZCB0byB0aGUge0BsaW5rIENhbGVuZGFyfSBvYmplY3QKKyAgICAgKiAgICAgIGJ5IHVzaW5nIHRoZSB7QGxpbmsgQ2FsZW5kYXIjYWRkKGludCxpbnQpfSBtZXRob2Q8L2xpPgorICAgICAqICA8bGk+dGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIENhbGVuZGFycyBpbiBjb21wdXRlZCBpbiBtaWxsaXNlY29uZHMgYW5kIGNvbnZlcnRlZCB0byBkYXlzLAorICAgICAqICAgICBpZiBhIHJlbWFpbmRlciBvY2N1cnMgZHVlIHRvIERheWxpZ2h0IFNhdmluZ3MgVGltZSwgaXQgaXMgZGlzY2FyZGVkPC9saT4KKyAgICAgKiAgPGxpPnRoZSBjb21wdXRlZCBkYXlzLCBhbG9uZyB3aXRoIHRoZSBob3VycywgbWludXRlcyBhbmQgc2Vjb25kcworICAgICAqICAgICAgZmllbGRzIG9mIHRoaXMgZHVyYXRpb24gb2JqZWN0IGlzIHVzZWQgdG8gY29uc3RydWN0IGEgbmV3CisgICAgICogICAgICBEdXJhdGlvbiBvYmplY3QuPC9saT4KKyAgICAgKiA8L29sPgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IHNpbmNlIHRoZSBDYWxlbmRhciBjbGFzcyB1c2VzIDxjb2RlPmludDwvY29kZT4gdG8KKyAgICAgKiBob2xkIHRoZSB2YWx1ZSBvZiB5ZWFyIGFuZCBtb250aCwgdGhpcyBtZXRob2QgbWF5IHByb2R1Y2UKKyAgICAgKiBhbiB1bmV4cGVjdGVkIHJlc3VsdCBpZiB0aGlzIGR1cmF0aW9uIG9iamVjdCBob2xkcworICAgICAqIGEgdmVyeSBsYXJnZSB2YWx1ZSBpbiB0aGUgeWVhcnMgb3IgbW9udGhzIGZpZWxkcy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhcnRUaW1lSW5zdGFudCA8Y29kZT5DYWxlbmRhcjwvY29kZT4gcmVmZXJlbmNlIHBvaW50LgorICAgICAqCisgICAgICogQHJldHVybiA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2YgeWVhcnMgYW5kIG1vbnRocyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBhcyBkYXlzLgorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiB0aGUgc3RhcnRUaW1lSW5zdGFudCBwYXJhbWV0ZXIgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRHVyYXRpb24gbm9ybWFsaXplV2l0aChmaW5hbCBDYWxlbmRhciBzdGFydFRpbWVJbnN0YW50KTsKKworICAgIC8qKgorICAgICAqIDxwPlBhcnRpYWwgb3JkZXIgcmVsYXRpb24gY29tcGFyaXNvbiB3aXRoIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+IGluc3RhbmNlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkNvbXBhcmlzb24gcmVzdWx0IG11c3QgYmUgaW4gYWNjb3JkYW5jZSB3aXRoCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2R1cmF0aW9uLW9yZGVyIj5XM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBTZWN0aW9uIDMuMi43LjYuMiwKKyAgICAgKiA8aT5PcmRlciByZWxhdGlvbiBvbiBkdXJhdGlvbjwvaT48L2E+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlJldHVybjo8L3A+CisgICAgICogPHVsPgorICAgICAqICAgPGxpPntAbGluayBEYXRhdHlwZUNvbnN0YW50cyNMRVNTRVJ9IGlmIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+IGlzIHNob3J0ZXIgdGhhbiA8Y29kZT5kdXJhdGlvbjwvY29kZT4gcGFyYW1ldGVyPC9saT4KKyAgICAgKiAgIDxsaT57QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRVFVQUx9IGlmIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+IGlzIGVxdWFsIHRvIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiBwYXJhbWV0ZXI8L2xpPgorICAgICAqICAgPGxpPntAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHUkVBVEVSfSBpZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBpcyBsb25nZXIgdGhhbiA8Y29kZT5kdXJhdGlvbjwvY29kZT4gcGFyYW1ldGVyPC9saT4KKyAgICAgKiAgIDxsaT57QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjSU5ERVRFUk1JTkFURX0gaWYgYSBjb25jbHVzaXZlIHBhcnRpYWwgb3JkZXIgcmVsYXRpb24gY2Fubm90IGJlIGRldGVybWluZWQ8L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZHVyYXRpb24gdG8gY29tcGFyZQorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gPGNvZGU+dGhpczwvY29kZT4gPGNvZGU+RHVyYXRpb248L2NvZGU+YW5kIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiBwYXJhbWV0ZXIgYXMKKyAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNMRVNTRVJ9LCB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRVFVQUx9LCB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjR1JFQVRFUn0KKyAgICAgKiAgIG9yIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNJTkRFVEVSTUlOQVRFfS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gSWYgdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24KKyAgICAgKiAgIGNhbm5vdCByZWFzb25hYmx5IHByb2Nlc3MgdGhlIHJlcXVlc3QsIGUuZy4gVzNDIFhNTCBTY2hlbWEgYWxsb3dzIGZvcgorICAgICAqICAgYXJiaXRyYXJpbHkgbGFyZ2Uvc21hbGwvcHJlY2lzZSB2YWx1ZXMsIHRoZSByZXF1ZXN0IG1heSBiZSBiZXlvbmQgdGhlCisgICAgICogICBpbXBsZW1lbnRhdGlvbnMgY2FwYWJpbGl0eS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBzZWUgI2lzU2hvcnRlclRoYW4oRHVyYXRpb24pCisgICAgICogQHNlZSAjaXNMb25nZXJUaGFuKER1cmF0aW9uKQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgY29tcGFyZShmaW5hbCBEdXJhdGlvbiBkdXJhdGlvbik7CisKKyAgICAvKioKKyAgICAgKiA8cD5DaGVja3MgaWYgdGhpcyBkdXJhdGlvbiBvYmplY3QgaXMgc3RyaWN0bHkgbG9uZ2VyIHRoYW4KKyAgICAgKiBhbm90aGVyIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvYmplY3QuPC9wPgorICAgICAqCisgICAgICogPHA+RHVyYXRpb24gWCBpcyAibG9uZ2VyIiB0aGFuIFkgaWYgYW5kIG9ubHkgaWYgWD5ZCisgICAgICogYXMgZGVmaW5lZCBpbiB0aGUgc2VjdGlvbiAzLjIuNi4yIG9mIHRoZSBYTUwgU2NoZW1hIDEuMAorICAgICAqIHNwZWNpZmljYXRpb24uPC9wPgorICAgICAqCisgICAgICogPHA+Rm9yIGV4YW1wbGUsICJQMUQiIChvbmUgZGF5KSA+ICJQVDEySCIgKDEyIGhvdXJzKSBhbmQKKyAgICAgKiAiUDJZIiAodHdvIHllYXJzKSA+ICJQMjNNIiAoMjMgbW9udGhzKS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZHVyYXRpb24gPGNvZGU+RHVyYXRpb248L2NvZGU+IHRvIHRlc3QgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gYWdhaW5zdC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gSWYgdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24KKyAgICAgKiAgIGNhbm5vdCByZWFzb25hYmx5IHByb2Nlc3MgdGhlIHJlcXVlc3QsIGUuZy4gVzNDIFhNTCBTY2hlbWEgYWxsb3dzIGZvcgorICAgICAqICAgYXJiaXRyYXJpbHkgbGFyZ2Uvc21hbGwvcHJlY2lzZSB2YWx1ZXMsIHRoZSByZXF1ZXN0IG1heSBiZSBiZXlvbmQgdGhlCisgICAgICogICBpbXBsZW1lbnRhdGlvbnMgY2FwYWJpbGl0eS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiBpcyBudWxsLgorICAgICAqCisgICAgICogQHJldHVybgorICAgICAqICAgICAgdHJ1ZSBpZiB0aGUgZHVyYXRpb24gcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3QKKyAgICAgKiAgICAgIGlzIGxvbmdlciB0aGFuIHRoZSBnaXZlbiBkdXJhdGlvbi4gZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqCisgICAgICogQHNlZSAjaXNTaG9ydGVyVGhhbihEdXJhdGlvbikKKyAgICAgKiBAc2VlICNjb21wYXJlKER1cmF0aW9uIGR1cmF0aW9uKQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzTG9uZ2VyVGhhbihmaW5hbCBEdXJhdGlvbiBkdXJhdGlvbikgeworICAgICAgICByZXR1cm4gY29tcGFyZShkdXJhdGlvbikgPT0gRGF0YXR5cGVDb25zdGFudHMuR1JFQVRFUjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5DaGVja3MgaWYgdGhpcyBkdXJhdGlvbiBvYmplY3QgaXMgc3RyaWN0bHkgc2hvcnRlciB0aGFuCisgICAgICogYW5vdGhlciA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2JqZWN0LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkdXJhdGlvbiA8Y29kZT5EdXJhdGlvbjwvY29kZT4gdG8gdGVzdCB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBhZ2FpbnN0LgorICAgICAqCisgICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiA8Y29kZT5kdXJhdGlvbjwvY29kZT4gcGFyYW1ldGVyIGlzIHNob3J0ZXIgdGhhbiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiwKKyAgICAgKiAgIGVsc2UgPGNvZGU+ZmFsc2U8L2NvZGU+LgorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBJZiB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbgorICAgICAqICAgY2Fubm90IHJlYXNvbmFibHkgcHJvY2VzcyB0aGUgcmVxdWVzdCwgZS5nLiBXM0MgWE1MIFNjaGVtYSBhbGxvd3MgZm9yCisgICAgICogICBhcmJpdHJhcmlseSBsYXJnZS9zbWFsbC9wcmVjaXNlIHZhbHVlcywgdGhlIHJlcXVlc3QgbWF5IGJlIGJleW9uZCB0aGUKKyAgICAgKiAgIGltcGxlbWVudGF0aW9ucyBjYXBhYmlsaXR5LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+ZHVyYXRpb248L2NvZGU+IGlzIG51bGwuCisgICAgICoKKyAgICAgKiBAc2VlICNpc0xvbmdlclRoYW4oRHVyYXRpb24gZHVyYXRpb24pCisgICAgICogQHNlZSAjY29tcGFyZShEdXJhdGlvbiBkdXJhdGlvbikKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1Nob3J0ZXJUaGFuKGZpbmFsIER1cmF0aW9uIGR1cmF0aW9uKSB7CisgICAgICAgIHJldHVybiBjb21wYXJlKGR1cmF0aW9uKSA9PSBEYXRhdHlwZUNvbnN0YW50cy5MRVNTRVI7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+Q2hlY2tzIGlmIHRoaXMgZHVyYXRpb24gb2JqZWN0IGhhcyB0aGUgc2FtZSBkdXJhdGlvbgorICAgICAqIGFzIGFub3RoZXIgPGNvZGU+RHVyYXRpb248L2NvZGU+IG9iamVjdC48L3A+CisgICAgICoKKyAgICAgKiA8cD5Gb3IgZXhhbXBsZSwgIlAxRCIgKDEgZGF5KSBpcyBlcXVhbCB0byAiUFQyNEgiICgyNCBob3VycykuPC9wPgorICAgICAqCisgICAgICogPHA+RHVyYXRpb24gWCBpcyBlcXVhbCB0byBZIGlmIGFuZCBvbmx5IGlmIHRpbWUgaW5zdGFudAorICAgICAqIHQrWCBhbmQgdCtZIGFyZSB0aGUgc2FtZSBmb3IgYWxsIHRoZSB0ZXN0IHRpbWUgaW5zdGFudHMKKyAgICAgKiBzcGVjaWZpZWQgaW4gdGhlIHNlY3Rpb24gMy4yLjYuMiBvZiB0aGUgWE1MIFNjaGVtYSAxLjAKKyAgICAgKiBzcGVjaWZpY2F0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB0aGVyZSBhcmUgY2FzZXMgd2hlcmUgdHdvIDxjb2RlPkR1cmF0aW9uPC9jb2RlPnMgYXJlCisgICAgICogImluY29tcGFyYWJsZSIgdG8gZWFjaCBvdGhlciwgbGlrZSBvbmUgbW9udGggYW5kIDMwIGRheXMuCisgICAgICogRm9yIGV4YW1wbGUsPC9wPgorICAgICAqIDxwcmU+CisgICAgICogIW5ldyBEdXJhdGlvbigiUDFNIikuaXNTaG9ydGVyVGhhbihuZXcgRHVyYXRpb24oIlAzMEQiKSkKKyAgICAgKiAhbmV3IER1cmF0aW9uKCJQMU0iKS5pc0xvbmdlclRoYW4obmV3IER1cmF0aW9uKCJQMzBEIikpCisgICAgICogIW5ldyBEdXJhdGlvbigiUDFNIikuZXF1YWxzKG5ldyBEdXJhdGlvbigiUDMwRCIpKQorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogQHBhcmFtIGR1cmF0aW9uCisgICAgICogICAgICBBIG5vbi1udWxsIHZhbGlkIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGlzIGR1cmF0aW9uIGlzIHRoZSBzYW1lIGxlbmd0aCBhcworICAgICAqICAgICAgICAgPGNvZGU+ZHVyYXRpb248L2NvZGU+LgorICAgICAqICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiBpcyBub3QgYQorICAgICAqICAgICAgICAgPGNvZGU+RHVyYXRpb248L2NvZGU+IG9iamVjdCwgaXMgPGNvZGU+bnVsbDwvY29kZT4sCisgICAgICogICAgICAgICBvciBpdHMgbGVuZ3RoIGlzIGRpZmZlcmVudCBmcm9tIHRoaXMgZHVyYXRpb24uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIElmIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uCisgICAgICogICBjYW5ub3QgcmVhc29uYWJseSBwcm9jZXNzIHRoZSByZXF1ZXN0LCBlLmcuIFczQyBYTUwgU2NoZW1hIGFsbG93cyBmb3IKKyAgICAgKiAgIGFyYml0cmFyaWx5IGxhcmdlL3NtYWxsL3ByZWNpc2UgdmFsdWVzLCB0aGUgcmVxdWVzdCBtYXkgYmUgYmV5b25kIHRoZQorICAgICAqICAgaW1wbGVtZW50YXRpb25zIGNhcGFiaWxpdHkuCisgICAgICoKKyAgICAgKiBAc2VlICNjb21wYXJlKER1cmF0aW9uIGR1cmF0aW9uKQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBPYmplY3QgZHVyYXRpb24pIHsKKyAgICAgICAgaWYgKGR1cmF0aW9uID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChkdXJhdGlvbiBpbnN0YW5jZW9mIER1cmF0aW9uKSB7CisgICAgICAgICAgICByZXR1cm4gY29tcGFyZSgoRHVyYXRpb24pIGR1cmF0aW9uKSA9PSBEYXRhdHlwZUNvbnN0YW50cy5FUVVBTDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGhhc2ggY29kZSBjb25zaXN0ZW50IHdpdGggdGhlIGRlZmluaXRpb24gb2YgdGhlIGVxdWFscyBtZXRob2QuCisgICAgICoKKyAgICAgKiBAc2VlIE9iamVjdCNoYXNoQ29kZSgpCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBoYXNoQ29kZSgpOworCisgICAgLyoqCisgICAgICogPHA+UmV0dXJucyBhIDxjb2RlPlN0cmluZzwvY29kZT4gcmVwcmVzZW50YXRpb24gb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gPGNvZGU+T2JqZWN0PC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgcmVzdWx0IGlzIGZvcm1hdHRlZCBhY2NvcmRpbmcgdG8gdGhlIFhNTCBTY2hlbWEgMS4wIHNwZWNpZmljYXRpb24gYW5kIGNhbiBiZSBhbHdheXMgcGFyc2VkIGJhY2sgbGF0ZXIgaW50byB0aGUKKyAgICAgKiBlcXVpdmFsZW50IDxjb2RlPkR1cmF0aW9uPC9jb2RlPiA8Y29kZT5PYmplY3Q8L2NvZGU+IGJ5IHtAbGluayBEYXRhdHlwZUZhY3RvcnkjbmV3RHVyYXRpb24oU3RyaW5nICBsZXhpY2FsUmVwcmVzZW50YXRpb24pfS48L3A+CisgICAgICoKKyAgICAgKiA8cD5Gb3JtYWxseSwgdGhlIGZvbGxvd2luZyBob2xkcyBmb3IgYW55IDxjb2RlPkR1cmF0aW9uPC9jb2RlPgorICAgICAqIDxjb2RlPk9iamVjdDwvY29kZT4geDo8L3A+CisgICAgICogPHByZT4KKyAgICAgKiBuZXcgRHVyYXRpb24oeC50b1N0cmluZygpKS5lcXVhbHMoeCkKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQSBub24tPGNvZGU+bnVsbDwvY29kZT4gdmFsaWQgPGNvZGU+U3RyaW5nPC9jb2RlPiByZXByZXNlbnRhdGlvbiBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisKKyAgICAgICAgaWYgKGdldFNpZ24oKSA8IDApIHsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJy0nKTsKKyAgICAgICAgfQorICAgICAgICBidWYuYXBwZW5kKCdQJyk7CisKKyAgICAgICAgQmlnSW50ZWdlciB5ZWFycyA9IChCaWdJbnRlZ2VyKSBnZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5ZRUFSUyk7CisgICAgICAgIGlmICh5ZWFycyAhPSBudWxsKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKHllYXJzKS5hcHBlbmQoJ1knKTsKKyAgICAgICAgfQorCisgICAgICAgIEJpZ0ludGVnZXIgbW9udGhzID0gKEJpZ0ludGVnZXIpIGdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLk1PTlRIUyk7CisgICAgICAgIGlmIChtb250aHMgIT0gbnVsbCkgeworICAgICAgICAgICAgYnVmLmFwcGVuZChtb250aHMpLmFwcGVuZCgnTScpOworICAgICAgICB9CisKKyAgICAgICAgQmlnSW50ZWdlciBkYXlzID0gKEJpZ0ludGVnZXIpIGdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLkRBWVMpOworICAgICAgICBpZiAoZGF5cyAhPSBudWxsKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKGRheXMpLmFwcGVuZCgnRCcpOworICAgICAgICB9CisKKyAgICAgICAgQmlnSW50ZWdlciBob3VycyA9IChCaWdJbnRlZ2VyKSBnZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5IT1VSUyk7CisgICAgICAgIEJpZ0ludGVnZXIgbWludXRlcyA9IChCaWdJbnRlZ2VyKSBnZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5NSU5VVEVTKTsKKyAgICAgICAgQmlnRGVjaW1hbCBzZWNvbmRzID0gKEJpZ0RlY2ltYWwpIGdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLlNFQ09ORFMpOworICAgICAgICBpZiAoaG91cnMgIT0gbnVsbCB8fCBtaW51dGVzICE9IG51bGwgfHwgc2Vjb25kcyAhPSBudWxsKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKCdUJyk7CisgICAgICAgICAgICBpZiAoaG91cnMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoaG91cnMpLmFwcGVuZCgnSCcpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG1pbnV0ZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQobWludXRlcykuYXBwZW5kKCdNJyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc2Vjb25kcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCh0b1N0cmluZyhzZWNvbmRzKSkuYXBwZW5kKCdTJyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+VHVybnMge0BsaW5rIEJpZ0RlY2ltYWx9IHRvIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkR1ZSB0byBhIGJlaGF2aW9yIGNoYW5nZSBpbiB0aGUge0BsaW5rIEJpZ0RlY2ltYWwjdG9TdHJpbmcoKX0KKyAgICAgKiBtZXRob2QgaW4gSkRLMS41LCB0aGlzIGhhZCB0byBiZSBpbXBsZW1lbnRlZCBoZXJlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBiZCA8Y29kZT5CaWdEZWNpbWFsPC9jb2RlPiB0byBmb3JtYXQgYXMgYSA8Y29kZT5TdHJpbmc8L2NvZGU+CisgICAgICoKKyAgICAgKiBAcmV0dXJuICA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uIG9mIDxjb2RlPkJpZ0RlY2ltYWw8L2NvZGU+CisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgdG9TdHJpbmcoQmlnRGVjaW1hbCBiZCkgeworICAgICAgICBTdHJpbmcgaW50U3RyaW5nID0gYmQudW5zY2FsZWRWYWx1ZSgpLnRvU3RyaW5nKCk7CisgICAgICAgIGludCBzY2FsZSA9IGJkLnNjYWxlKCk7CisKKyAgICAgICAgaWYgKHNjYWxlID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBpbnRTdHJpbmc7CisgICAgICAgIH0KKworICAgICAgICAvKiBJbnNlcnQgZGVjaW1hbCBwb2ludCAqLworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZjsKKyAgICAgICAgaW50IGluc2VydGlvblBvaW50ID0gaW50U3RyaW5nLmxlbmd0aCgpIC0gc2NhbGU7CisgICAgICAgIGlmIChpbnNlcnRpb25Qb2ludCA9PSAwKSB7IC8qIFBvaW50IGdvZXMgcmlnaHQgYmVmb3JlIGludFZhbCAqLworICAgICAgICAgICAgcmV0dXJuICIwLiIgKyBpbnRTdHJpbmc7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoaW5zZXJ0aW9uUG9pbnQgPiAwKSB7IC8qIFBvaW50IGdvZXMgaW5zaWRlIGludFZhbCAqLworICAgICAgICAgICAgYnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoaW50U3RyaW5nKTsKKyAgICAgICAgICAgIGJ1Zi5pbnNlcnQoaW5zZXJ0aW9uUG9pbnQsICcuJyk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7IC8qIFdlIG11c3QgaW5zZXJ0IHplcm9zIGJldHdlZW4gcG9pbnQgYW5kIGludFZhbCAqLworICAgICAgICAgICAgYnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoMyAtIGluc2VydGlvblBvaW50ICsgaW50U3RyaW5nLmxlbmd0aCgpKTsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIjAuIik7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IC1pbnNlcnRpb25Qb2ludDsgaSsrKSB7CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnMCcpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnVmLmFwcGVuZChpbnRTdHJpbmcpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIDxwPkNhbGxzIHRoZSB7QGxpbmsgQ2FsZW5kYXIjZ2V0VGltZUluTWlsbGlzfSBtZXRob2QuCisgICAgICogUHJpb3IgdG8gSkRLMS40LCB0aGlzIG1ldGhvZCB3YXMgcHJvdGVjdGVkIGFuZCB0aGVyZWZvcmUKKyAgICAgKiBjYW5ub3QgYmUgaW52b2tlZCBkaXJlY3RseS48L3A+CisgICAgICoKKyAgICAgKiA8cD5UT0RPOiBJbiBmdXR1cmUsIHRoaXMgc2hvdWxkIGJlIHJlcGxhY2VkIGJ5IDxjb2RlPmNhbC5nZXRUaW1lSW5NaWxsaXMoKTwvY29kZT4uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGNhbCA8Y29kZT5DYWxlbmRhcjwvY29kZT4gdG8gZ2V0IHRpbWUgaW4gbWlsbGlzZWNvbmRzLgorICAgICAqCisgICAgICogQHJldHVybiBNaWxsaXNlY29uZHMgb2YgPGNvZGU+Y2FsPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBsb25nIGdldENhbGVuZGFyVGltZUluTWlsbGlzKGZpbmFsIENhbGVuZGFyIGNhbCkgeworICAgICAgICByZXR1cm4gY2FsLmdldFRpbWUoKS5nZXRUaW1lKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9kYXRhdHlwZS9GYWN0b3J5RmluZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL2RhdGF0eXBlL0ZhY3RvcnlGaW5kZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNjVmNDEyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9kYXRhdHlwZS9GYWN0b3J5RmluZGVyLmphdmEKQEAgLTAsMCArMSwzNTEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLyAkSWQ6IEZhY3RvcnlGaW5kZXIuamF2YSA2NzA0MzIgMjAwOC0wNi0yMyAwMjowMjowOFogbXJnbGF2YXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC5kYXRhdHlwZTsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBsaWJjb3JlLmlvLklvVXRpbHM7CisKKy8qKgorICogPHA+SW1wbGVtZW50IHBsdWdnYWJsZSBkYXRhIHR5cGVzLjwvcD4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGlzIGR1cGxpY2F0ZWQgZm9yIGVhY2ggSkFYUCBzdWJwYWNrYWdlIHNvIGtlZXAgaXQgaW4KKyAqIHN5bmMuICBJdCBpcyBwYWNrYWdlIHByaXZhdGUgZm9yIHNlY3VyZSBjbGFzcyBsb2FkaW5nLjwvcD4KKyAqCisgKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogNjcwNDMyICQsICREYXRlOiAyMDA4LTA2LTIyIDE5OjAyOjA4IC0wNzAwIChTdW4sIDIyIEp1biAyMDA4KSAkCisgKiBAc2luY2UgMS41CisgKi8KK2ZpbmFsIGNsYXNzIEZhY3RvcnlGaW5kZXIgeworCisgICAgLyoqIDxwPk5hbWUgb2YgY2xhc3MgdG8gZGlzcGxheSBpbiBvdXRwdXQgbWVzc2FnZXMuPC9wPiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDTEFTU19OQU1FID0gImphdmF4LnhtbC5kYXRhdHlwZS5GYWN0b3J5RmluZGVyIjsKKworICAgIC8qKiA8cD5EZWJ1ZyBmbGFnIHRvIHRyYWNlIGxvYWRpbmcgcHJvY2Vzcy48L3A+ICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBkZWJ1ZyA9IGZhbHNlOworCisgICAgLyoqIDxwPkNhY2hlIHByb3BlcnRpZXMgZm9yIHBlcmZvcm1hbmNlLjwvcD4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBQcm9wZXJ0aWVzIGNhY2hlUHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCisgICAgLyoqIDxwPkZpcnN0IHRpbWUgcmVxdWlyZXMgaW5pdGlhbGl6YXRpb24gb3ZlcmhlYWQuPC9wPiAqLworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gZmlyc3RUaW1lID0gdHJ1ZTsKKworICAgIC8qKiBEZWZhdWx0IGNvbHVtbnMgcGVyIGxpbmUuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfTElORV9MRU5HVEggPSA4MDsKKworICAgIC8qKgorICAgICAqIDxwPkNoZWNrIHRvIHNlZSBpZiBkZWJ1Z2dpbmcgZW5hYmxlZCBieSBwcm9wZXJ0eS48L3A+CisgICAgICoKKyAgICAgKiA8cD5Vc2UgdHJ5L2NhdGNoIGJsb2NrIHRvIHN1cHBvcnQgYXBwbGV0cywgd2hpY2ggdGhyb3dzCisgICAgICogU2VjdXJpdHlFeGNlcHRpb24gb3V0IG9mIHRoaXMgY29kZS48L3A+CisgICAgICovCisgICAgc3RhdGljIHsKKyAgICAgICAgU3RyaW5nIHZhbCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF4cC5kZWJ1ZyIpOworICAgICAgICAvLyBBbGxvdyBzaW1wbHkgc2V0dGluZyB0aGUgcHJvcCB0byB0dXJuIG9uIGRlYnVnCisgICAgICAgIGRlYnVnID0gdmFsICE9IG51bGwgJiYgKCEgImZhbHNlIi5lcXVhbHModmFsKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBGYWN0b3J5RmluZGVyKCkge30KKworICAgIC8qKgorICAgICAqIDxwPk91dHB1dCBkZWJ1Z2dpbmcgbWVzc2FnZXMuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG1zZyA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIHByaW50IHRvIDxjb2RlPnN0ZGVycjwvY29kZT4uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBkZWJ1Z1ByaW50bG4oU3RyaW5nIG1zZykgeworICAgICAgICBpZiAoZGVidWcpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigKKyAgICAgICAgICAgICAgICBDTEFTU19OQU1FCisgICAgICAgICAgICAgICAgKyAiOiIKKyAgICAgICAgICAgICAgICArIG1zZyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5GaW5kIHRoZSBhcHByb3ByaWF0ZSA8Y29kZT5DbGFzc0xvYWRlcjwvY29kZT4gdG8gdXNlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBjb250ZXh0IENsYXNzTG9hZGVyIGlzIHByZWZlcnJlZC48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIDxjb2RlPkNsYXNzTG9hZGVyPC9jb2RlPiB0byB1c2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIENvbmZpZ3VyYXRpb25FcnJvciBJZiBhIHZhbGlkIDxjb2RlPkNsYXNzTG9hZGVyPC9jb2RlPiBjYW5ub3QgYmUgaWRlbnRpZmllZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBDbGFzc0xvYWRlciBmaW5kQ2xhc3NMb2FkZXIoKSB0aHJvd3MgQ29uZmlndXJhdGlvbkVycm9yIHsKKyAgICAgICAgLy8gRmlndXJlIG91dCB3aGljaCBDbGFzc0xvYWRlciB0byB1c2UgZm9yIGxvYWRpbmcgdGhlIHByb3ZpZGVyCisgICAgICAgIC8vIGNsYXNzLiAgSWYgdGhlcmUgaXMgYSBDb250ZXh0IENsYXNzTG9hZGVyIHRoZW4gdXNlIGl0LgorCisgICAgICAgIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKworICAgICAgICBpZiAoZGVidWcpIGRlYnVnUHJpbnRsbigKKyAgICAgICAgICAgICJVc2luZyBjb250ZXh0IGNsYXNzIGxvYWRlcjogIgorICAgICAgICAgICAgKyBjbGFzc0xvYWRlcik7CisKKyAgICAgICAgaWYgKGNsYXNzTG9hZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGlmIHdlIGhhdmUgbm8gQ29udGV4dCBDbGFzc0xvYWRlcgorICAgICAgICAgICAgLy8gc28gdXNlIHRoZSBjdXJyZW50IENsYXNzTG9hZGVyCisgICAgICAgICAgICBjbGFzc0xvYWRlciA9IEZhY3RvcnlGaW5kZXIuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgICAgIGlmIChkZWJ1ZykgZGVidWdQcmludGxuKAorICAgICAgICAgICAgICAgICJVc2luZyB0aGUgY2xhc3MgbG9hZGVyIG9mIEZhY3RvcnlGaW5kZXI6ICIKKyAgICAgICAgICAgICAgICArIGNsYXNzTG9hZGVyKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjbGFzc0xvYWRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5DcmVhdGUgYW4gaW5zdGFuY2Ugb2YgYSBjbGFzcyB1c2luZyB0aGUgc3BlY2lmaWVkIENsYXNzTG9hZGVyLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbGFzc05hbWUgTmFtZSBvZiBjbGFzcyB0byBjcmVhdGUuCisgICAgICogQHBhcmFtIGNsYXNzTG9hZGVyIENsYXNzTG9hZGVyIHRvIHVzZSB0byBjcmVhdGUgbmFtZWQgY2xhc3MuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIE5ldyBpbnN0YW5jZSBvZiBzcGVjaWZpZWQgY2xhc3MgY3JlYXRlZCB1c2luZyB0aGUgc3BlY2lmaWVkIENsYXNzTG9hZGVyLgorICAgICAqCisgICAgICogQHRocm93cyBDb25maWd1cmF0aW9uRXJyb3IgSWYgY2xhc3MgY291bGQgbm90IGJlIGNyZWF0ZWQuCisgICAgICovCisgICAgc3RhdGljIE9iamVjdCBuZXdJbnN0YW5jZSgKKyAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSwKKyAgICAgICAgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIpCisgICAgICAgIHRocm93cyBDb25maWd1cmF0aW9uRXJyb3IgeworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDbGFzcyBzcGlDbGFzczsKKyAgICAgICAgICAgIGlmIChjbGFzc0xvYWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgc3BpQ2xhc3MgPSBDbGFzcy5mb3JOYW1lKGNsYXNzTmFtZSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHNwaUNsYXNzID0gY2xhc3NMb2FkZXIubG9hZENsYXNzKGNsYXNzTmFtZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChkZWJ1ZykgeworICAgICAgICAgICAgICAgIGRlYnVnUHJpbnRsbigiTG9hZGVkICIgKyBjbGFzc05hbWUgKyAiIGZyb20gIiArIHdoaWNoKHNwaUNsYXNzKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBzcGlDbGFzcy5uZXdJbnN0YW5jZSgpOworICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDb25maWd1cmF0aW9uRXJyb3IoCisgICAgICAgICAgICAgICAgIlByb3ZpZGVyICIgKyBjbGFzc05hbWUgKyAiIG5vdCBmb3VuZCIsIHgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24geCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENvbmZpZ3VyYXRpb25FcnJvcigKKyAgICAgICAgICAgICAgICAiUHJvdmlkZXIgIiArIGNsYXNzTmFtZSArICIgY291bGQgbm90IGJlIGluc3RhbnRpYXRlZDogIiArIHgsIHgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgdGhlIGltcGxlbWVudGF0aW9uIENsYXNzIG9iamVjdCBpbiB0aGUgc3BlY2lmaWVkIG9yZGVyLiAgTWFpbgorICAgICAqIGVudHJ5IHBvaW50LgorICAgICAqIFBhY2thZ2UgcHJpdmF0ZSBzbyB0aGlzIGNvZGUgY2FuIGJlIHNoYXJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmYWN0b3J5SWQgTmFtZSBvZiB0aGUgZmFjdG9yeSB0byBmaW5kLCBzYW1lIGFzIGEgcHJvcGVydHkgbmFtZQorICAgICAqIEBwYXJhbSBmYWxsYmFja0NsYXNzTmFtZSBJbXBsZW1lbnRhdGlvbiBjbGFzcyBuYW1lLCBpZiBub3RoaW5nIGVsc2UgaXMgZm91bmQuICBVc2UgbnVsbCB0byBtZWFuIG5vIGZhbGxiYWNrLgorICAgICAqCisgICAgICogQHJldHVybiBDbGFzcyBPYmplY3Qgb2YgZmFjdG9yeSwgbmV2ZXIgbnVsbAorICAgICAqCisgICAgICogQHRocm93cyBDb25maWd1cmF0aW9uRXJyb3IgSWYgQ2xhc3MgY2Fubm90IGJlIGZvdW5kLgorICAgICAqLworICAgIHN0YXRpYyBPYmplY3QgZmluZChTdHJpbmcgZmFjdG9yeUlkLCBTdHJpbmcgZmFsbGJhY2tDbGFzc05hbWUpIHRocm93cyBDb25maWd1cmF0aW9uRXJyb3IgeworCisgICAgICAgIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyID0gZmluZENsYXNzTG9hZGVyKCk7CisKKyAgICAgICAgLy8gVXNlIHRoZSBzeXN0ZW0gcHJvcGVydHkgZmlyc3QKKyAgICAgICAgU3RyaW5nIHN5c3RlbVByb3AgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoZmFjdG9yeUlkKTsKKyAgICAgICAgaWYgKHN5c3RlbVByb3AgIT0gbnVsbCAmJiBzeXN0ZW1Qcm9wLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgaWYgKGRlYnVnKSBkZWJ1Z1ByaW50bG4oImZvdW5kICIgKyBzeXN0ZW1Qcm9wICsgIiBpbiB0aGUgc3lzdGVtIHByb3BlcnR5ICIgKyBmYWN0b3J5SWQpOworICAgICAgICAgICAgcmV0dXJuIG5ld0luc3RhbmNlKHN5c3RlbVByb3AsIGNsYXNzTG9hZGVyKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRyeSB0byByZWFkIGZyb20gJGphdmEuaG9tZS9saWIvamF4cC5wcm9wZXJ0aWVzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgamF2YWggPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaG9tZSIpOworICAgICAgICAgICAgU3RyaW5nIGNvbmZpZ0ZpbGUgPSBqYXZhaCArIEZpbGUuc2VwYXJhdG9yICsgImxpYiIgKyBGaWxlLnNlcGFyYXRvciArICJqYXhwLnByb3BlcnRpZXMiOworICAgICAgICAgICAgU3RyaW5nIGZhY3RvcnlDbGFzc05hbWUgPSBudWxsOworICAgICAgICAgICAgaWYgKGZpcnN0VGltZSkgeworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoY2FjaGVQcm9wcykgeworICAgICAgICAgICAgICAgICAgICBpZiAoZmlyc3RUaW1lKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBGaWxlIGYgPSBuZXcgRmlsZShjb25maWdGaWxlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0VGltZSA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGYuZXhpc3RzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVidWcpIGRlYnVnUHJpbnRsbigiUmVhZCBwcm9wZXJ0aWVzIGZpbGUgIiArIGYpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlUHJvcHMubG9hZChuZXcgRmlsZUlucHV0U3RyZWFtKGYpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZhY3RvcnlDbGFzc05hbWUgPSBjYWNoZVByb3BzLmdldFByb3BlcnR5KGZhY3RvcnlJZCk7CisgICAgICAgICAgICBpZiAoZGVidWcpIGRlYnVnUHJpbnRsbigiZm91bmQgIiArIGZhY3RvcnlDbGFzc05hbWUgKyAiIGluICRqYXZhLmhvbWUvamF4cC5wcm9wZXJ0aWVzIik7CisKKyAgICAgICAgICAgIGlmIChmYWN0b3J5Q2xhc3NOYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3SW5zdGFuY2UoZmFjdG9yeUNsYXNzTmFtZSwgY2xhc3NMb2FkZXIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGlmIChkZWJ1ZykgeworICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gVHJ5IEphciBTZXJ2aWNlIFByb3ZpZGVyIE1lY2hhbmlzbQorICAgICAgICBPYmplY3QgcHJvdmlkZXIgPSBmaW5kSmFyU2VydmljZVByb3ZpZGVyKGZhY3RvcnlJZCk7CisgICAgICAgIGlmIChwcm92aWRlciAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gcHJvdmlkZXI7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZmFsbGJhY2tDbGFzc05hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENvbmZpZ3VyYXRpb25FcnJvcigKKyAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yICIgKyBmYWN0b3J5SWQgKyAiIGNhbm5vdCBiZSBmb3VuZCIsIG51bGwpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGRlYnVnKSBkZWJ1Z1ByaW50bG4oImxvYWRlZCBmcm9tIGZhbGxiYWNrIHZhbHVlOiAiICsgZmFsbGJhY2tDbGFzc05hbWUpOworICAgICAgICByZXR1cm4gbmV3SW5zdGFuY2UoZmFsbGJhY2tDbGFzc05hbWUsIGNsYXNzTG9hZGVyKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFRyeSB0byBmaW5kIHByb3ZpZGVyIHVzaW5nIEphciBTZXJ2aWNlIFByb3ZpZGVyIE1lY2hhbmlzbQorICAgICAqCisgICAgICogQHJldHVybiBpbnN0YW5jZSBvZiBwcm92aWRlciBjbGFzcyBpZiBmb3VuZCBvciBudWxsCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgT2JqZWN0IGZpbmRKYXJTZXJ2aWNlUHJvdmlkZXIoU3RyaW5nIGZhY3RvcnlJZCkgdGhyb3dzIENvbmZpZ3VyYXRpb25FcnJvciB7CisgICAgICAgIFN0cmluZyBzZXJ2aWNlSWQgPSAiTUVUQS1JTkYvc2VydmljZXMvIiArIGZhY3RvcnlJZDsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBudWxsOworCisgICAgICAgIC8vIEZpcnN0IHRyeSB0aGUgQ29udGV4dCBDbGFzc0xvYWRlcgorICAgICAgICBDbGFzc0xvYWRlciBjbCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisgICAgICAgIGlmIChjbCAhPSBudWxsKSB7CisgICAgICAgICAgICBpcyA9IGNsLmdldFJlc291cmNlQXNTdHJlYW0oc2VydmljZUlkKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChpcyA9PSBudWxsKSB7CisgICAgICAgICAgICBjbCA9IEZhY3RvcnlGaW5kZXIuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgICAgIGlzID0gY2wuZ2V0UmVzb3VyY2VBc1N0cmVhbShzZXJ2aWNlSWQpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGlzID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIE5vIHByb3ZpZGVyIGZvdW5kCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkZWJ1ZykgZGVidWdQcmludGxuKCJmb3VuZCBqYXIgcmVzb3VyY2U9IiArIHNlcnZpY2VJZCArICIgdXNpbmcgQ2xhc3NMb2FkZXI6ICIgKyBjbCk7CisKKyAgICAgICAgQnVmZmVyZWRSZWFkZXIgcmQ7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZCA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaXMsICJVVEYtOCIpLCBERUZBVUxUX0xJTkVfTEVOR1RIKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJkID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihpcyksIERFRkFVTFRfTElORV9MRU5HVEgpOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGZhY3RvcnlDbGFzc05hbWUgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gWFhYIERvZXMgbm90IGhhbmRsZSBhbGwgcG9zc2libGUgaW5wdXQgYXMgc3BlY2lmaWVkIGJ5IHRoZQorICAgICAgICAgICAgLy8gSmFyIFNlcnZpY2UgUHJvdmlkZXIgc3BlY2lmaWNhdGlvbgorICAgICAgICAgICAgZmFjdG9yeUNsYXNzTmFtZSA9IHJkLnJlYWRMaW5lKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIHgpIHsKKyAgICAgICAgICAgIC8vIE5vIHByb3ZpZGVyIGZvdW5kCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIElvVXRpbHMuY2xvc2VRdWlldGx5KHJkKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChmYWN0b3J5Q2xhc3NOYW1lICE9IG51bGwgJiYKKyAgICAgICAgICAgICEgIiIuZXF1YWxzKGZhY3RvcnlDbGFzc05hbWUpKSB7CisgICAgICAgICAgICBpZiAoZGVidWcpIGRlYnVnUHJpbnRsbigiZm91bmQgaW4gcmVzb3VyY2UsIHZhbHVlPSIKKyAgICAgICAgICAgICAgICAgICArIGZhY3RvcnlDbGFzc05hbWUpOworCisgICAgICAgICAgICByZXR1cm4gbmV3SW5zdGFuY2UoZmFjdG9yeUNsYXNzTmFtZSwgY2wpOworICAgICAgICB9CisKKyAgICAgICAgLy8gTm8gcHJvdmlkZXIgZm91bmQKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+Q29uZmlndXJhdGlvbiBFcnJvci48L3A+CisgICAgICovCisgICAgc3RhdGljIGNsYXNzIENvbmZpZ3VyYXRpb25FcnJvciBleHRlbmRzIEVycm9yIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzY0NDQxMzAyNjI0NDIxMTM0N0w7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIDxwPkV4Y2VwdGlvbiB0aGF0IGNhdXNlZCB0aGUgZXJyb3IuPC9wPgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBFeGNlcHRpb24gZXhjZXB0aW9uOworCisgICAgICAgIC8qKgorICAgICAgICAgKiA8cD5Db25zdHJ1Y3QgYSBuZXcgaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBzdHJpbmcgYW5kCisgICAgICAgICAqIGV4Y2VwdGlvbi48L3A+CisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBtc2cgRGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXJyb3IuCisgICAgICAgICAqIEBwYXJhbSB4IEV4Y2VwdGlvbiB0aGF0IGNhdXNlZCB0aGUgZXJyb3IuCisgICAgICAgICAqLworICAgICAgICBDb25maWd1cmF0aW9uRXJyb3IoU3RyaW5nIG1zZywgRXhjZXB0aW9uIHgpIHsKKyAgICAgICAgICAgIHN1cGVyKG1zZyk7CisgICAgICAgICAgICB0aGlzLmV4Y2VwdGlvbiA9IHg7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogPHA+R2V0IHRoZSBFeGNlcHRpb24gdGhhdCBjYXVzZWQgdGhlIGVycm9yLjwvcD4KKyAgICAgICAgICoKKyAgICAgICAgICogQHJldHVybiBFeGNlcHRpb24gdGhhdCBjYXVzZWQgdGhlIGVycm9yLgorICAgICAgICAgKi8KKyAgICAgICAgRXhjZXB0aW9uIGdldEV4Y2VwdGlvbigpIHsKKyAgICAgICAgICAgIHJldHVybiBleGNlcHRpb247CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsb2NhdGlvbiB3aGVyZSB0aGUgZ2l2ZW4gQ2xhc3MgaXMgbG9hZGVkIGZyb20uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHdoaWNoKENsYXNzIGNsYXp6KSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgY2xhc3NuYW1lQXNSZXNvdXJjZSA9IGNsYXp6LmdldE5hbWUoKS5yZXBsYWNlKCcuJywgJy8nKSArICIuY2xhc3MiOworCisgICAgICAgICAgICBDbGFzc0xvYWRlciBsb2FkZXIgPSBjbGF6ei5nZXRDbGFzc0xvYWRlcigpOworCisgICAgICAgICAgICBVUkwgaXQ7CisKKyAgICAgICAgICAgIGlmIChsb2FkZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGl0ID0gbG9hZGVyLmdldFJlc291cmNlKGNsYXNzbmFtZUFzUmVzb3VyY2UpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpdCA9IENsYXNzTG9hZGVyLmdldFN5c3RlbVJlc291cmNlKGNsYXNzbmFtZUFzUmVzb3VyY2UpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoaXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBpdC50b1N0cmluZygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIFRoZSBWTSByYW4gb3V0IG9mIG1lbW9yeSBvciB0aGVyZSB3YXMgc29tZSBvdGhlciBzZXJpb3VzIHByb2JsZW0uIFJlLXRocm93LgorICAgICAgICBjYXRjaCAoVmlydHVhbE1hY2hpbmVFcnJvciB2bWUpIHsKKyAgICAgICAgICAgIHRocm93IHZtZTsKKyAgICAgICAgfQorICAgICAgICAvLyBUaHJlYWREZWF0aCBzaG91bGQgYWx3YXlzIGJlIHJlLXRocm93bgorICAgICAgICBjYXRjaCAoVGhyZWFkRGVhdGggdGQpIHsKKyAgICAgICAgICAgIHRocm93IHRkOworICAgICAgICB9CisgICAgICAgIGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgLy8gd29yayBkZWZlbnNpdmVseS4KKyAgICAgICAgICAgIGlmIChkZWJ1ZykgeworICAgICAgICAgICAgICAgIHQucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuICJ1bmtub3duIGxvY2F0aW9uIjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL2RhdGF0eXBlL1hNTEdyZWdvcmlhbkNhbGVuZGFyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL2RhdGF0eXBlL1hNTEdyZWdvcmlhbkNhbGVuZGFyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjc5NjEwNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvZGF0YXR5cGUvWE1MR3JlZ29yaWFuQ2FsZW5kYXIuamF2YQpAQCAtMCwwICsxLDEwMzcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLyAkSWQ6IFhNTEdyZWdvcmlhbkNhbGVuZGFyLmphdmEgNzU5ODIyIDIwMDktMDMtMzAgMDE6MTU6MTFaIG1yZ2xhdmFzICQKKworcGFja2FnZSBqYXZheC54bWwuZGF0YXR5cGU7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnRGVjaW1hbDsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLlRpbWVab25lOworaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWU7CisKKy8qKgorICogPHA+UmVwcmVzZW50YXRpb24gZm9yIFczQyBYTUwgU2NoZW1hIDEuMCBkYXRlL3RpbWUgZGF0YXR5cGVzLgorICogU3BlY2lmaWNhbGx5LCB0aGVzZSBkYXRlL3RpbWUgZGF0YXR5cGVzIGFyZQorICogPGEgaHJlZj0iI0RBVEVUSU1FIj48Y29kZT5kYXRlVGltZTwvY29kZT48L2E+LAorICogPGEgaHJlZj0iI1RJTUUiPjxjb2RlPnRpbWU8L2NvZGU+PC9hPiwKKyAqIDxhIGhyZWY9IiNEQVRFIj48Y29kZT5kYXRlPC9jb2RlPjwvYT4sCisgKiA8YSBocmVmPSIjR1lFQVJNT05USCI+PGNvZGU+Z1llYXJNb250aDwvY29kZT48L2E+LAorICogPGEgaHJlZj0iI0dNT05USERBWSI+PGNvZGU+Z01vbnRoRGF5PC9jb2RlPjwvYT4sCisgKiA8YSBocmVmPSIjR1lFQVIiPjxjb2RlPmdZZWFyPC9jb2RlPjwvYT4KKyAqIDxhIGhyZWY9IiNHTU9OVEgiPjxjb2RlPmdNb250aDwvY29kZT48L2E+IGFuZAorICogPGEgaHJlZj0iI0dEQVkiPjxjb2RlPmdEYXk8L2NvZGU+PC9hPiBkZWZpbmVkIGluIHRoZSBYTUwgTmFtZXNwYWNlCisgKiA8Y29kZT4iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiPC9jb2RlPi4KKyAqIFRoZXNlIGRhdGF0eXBlcyBhcmUgbm9ybWF0aXZlbHkgZGVmaW5lZCBpbgorICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2RhdGVUaW1lIj5XM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBTZWN0aW9uIDMuMi43LTE0PC9hPi48L3A+CisgKgorICogPHA+VGhlIHRhYmxlIGJlbG93IGRlZmluZXMgdGhlIG1hcHBpbmcgYmV0d2VlbiBYTUwgU2NoZW1hIDEuMAorICogZGF0ZS90aW1lIGRhdGF0eXBlIGZpZWxkcyBhbmQgdGhpcyBjbGFzcycgZmllbGRzLiBJdCBhbHNvIHN1bW1hcml6ZXMKKyAqIHRoZSB2YWx1ZSBjb25zdHJhaW50cyBmb3IgdGhlIGRhdGUgYW5kIHRpbWUgZmllbGRzIGRlZmluZWQgaW4KKyAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNpc29mb3JtYXRzIj5XM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBBcHBlbmRpeCBELAorICogPGk+SVNPIDg2MDEgRGF0ZSBhbmQgVGltZSBGb3JtYXRzPC9pPjwvYT4uPC9wPgorICoKKyAqIDxhIG5hbWU9ImRhdGV0aW1lZmllbGRzbWFwcGluZyIvPgorICogPHRhYmxlIGJvcmRlcj0iMiIgcnVsZXM9ImFsbCIgY2VsbHBhZGRpbmc9IjIiPgorICogICA8dGhlYWQ+CisgKiAgICAgPHRyPgorICogICAgICAgPHRoIGFsaWduPSJjZW50ZXIiIGNvbHNwYW49IjMiPgorICogICAgICAgICBEYXRlL1RpbWUgRGF0YXR5cGUgRmllbGQgTWFwcGluZyBCZXR3ZWVuIFhNTCBTY2hlbWEgMS4wIGFuZCBKYXZhIFJlcHJlc2VudGF0aW9uCisgKiAgICAgICA8L3RoPgorICogICAgIDwvdHI+CisgKiAgIDwvdGhlYWQ+CisgKiAgIDx0Ym9keT4KKyAqICAgICA8dHI+CisgKiAgICAgICA8dGg+WE1MIFNjaGVtYSAxLjA8YnIvPgorICogICAgICAgICAgIGRhdGF0eXBlPGJyLz4KKyAqICAgICAgICAgICAgZmllbGQ8L3RoPgorICogICAgICAgPHRoPlJlbGF0ZWQ8YnIvPlhNTEdyZWdvcmlhbkNhbGVuZGFyPGJyLz5BY2Nlc3NvcihzKTwvdGg+CisgKiAgICAgICA8dGg+VmFsdWUgUmFuZ2U8L3RoPgorICogICAgIDwvdHI+CisgKiAgICAgPGEgbmFtZT0iZGF0ZXRpbWVmaWVsZC15ZWFyIi8+CisgKiAgICAgPHRyPgorICogICAgICAgPHRkPiB5ZWFyIDwvdGQ+CisgKiAgICAgICA8dGQ+IHtAbGluayAjZ2V0WWVhcigpfSArIHtAbGluayAjZ2V0RW9uKCl9IG9yPGJyLz4KKyAqICAgICAgICAgICAge0BsaW5rICNnZXRFb25BbmRZZWFyfQorICogICAgICAgPC90ZD4KKyAqICAgICAgIDx0ZD4gPGNvZGU+Z2V0WWVhcigpPC9jb2RlPiBpcyBhIHZhbHVlIGJldHdlZW4gLSgxMF45LTEpIHRvICgxMF45KS0xCisgKiAgICAgICAgICAgIG9yIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9Ljxici8+CisgKiAgICAgICAgICAgIHtAbGluayAjZ2V0RW9uKCl9IGlzIGhpZ2ggb3JkZXIgeWVhciB2YWx1ZSBpbiBiaWxsaW9uIG9mIHllYXJzLjxici8+CisgKiAgICAgICAgICAgIDxjb2RlPmdldEVvbigpPC9jb2RlPiBoYXMgdmFsdWVzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAoMTBeOSkgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIC0oMTBeOSkuCisgKiAgICAgICAgICAgIEEgdmFsdWUgb2YgbnVsbCBpbmRpY2F0ZXMgZmllbGQgaXMgdW5kZWZpbmVkLjwvYnI+CisgKiAgICAgICAgICAgIEdpdmVuIHRoYXQgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNS94bWxzY2hlbWEtZXJyYXRhI2UyLTYzIj5YTUwgU2NoZW1hIDEuMCBlcnJhdGE8L2E+IHN0YXRlcyB0aGF0IHRoZSB5ZWFyIHplcm8KKyAqICAgICAgICAgICAgd2lsbCBiZSBhIHZhbGlkIGxleGljYWwgdmFsdWUgaW4gYSBmdXR1cmUgdmVyc2lvbiBvZiBYTUwgU2NoZW1hLAorICogICAgICAgICAgICB0aGlzIGNsYXNzIGFsbG93cyB0aGUgeWVhciBmaWVsZCB0byBiZSBzZXQgdG8gemVyby4gT3RoZXJ3aXNlLAorICogICAgICAgICAgICB0aGUgeWVhciBmaWVsZCB2YWx1ZSBpcyBoYW5kbGVkIGV4YWN0bHkgYXMgZGVzY3JpYmVkCisgKiAgICAgICAgICAgIGluIHRoZSBlcnJhdGEgYW5kIFtJU08tODYwMS0xOTg4XS4gTm90ZSB0aGF0IFczQyBYTUwgU2NoZW1hIDEuMAorICogICAgICAgICAgICB2YWxpZGF0aW9uIGRvZXMgbm90IGFsbG93IGZvciB0aGUgeWVhciBmaWVsZCB0byBoYXZlIGEgdmFsdWUgb2YgemVyby4KKyAqICAgICAgICAgICAgPC90ZD4KKyAqICAgICA8L3RyPgorICogICAgIDxhIG5hbWU9ImRhdGV0aW1lZmllbGQtbW9udGgiLz4KKyAqICAgICA8dHI+CisgKiAgICAgICA8dGQ+IG1vbnRoIDwvdGQ+CisgKiAgICAgICA8dGQ+IHtAbGluayAjZ2V0TW9udGgoKX0gPC90ZD4KKyAqICAgICAgIDx0ZD4gMSB0byAxMiBvciB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSA8L3RkPgorICogICAgIDwvdHI+CisgKiAgICAgPGEgbmFtZT0iZGF0ZXRpbWVmaWVsZC1kYXkiLz4KKyAqICAgICA8dHI+CisgKiAgICAgICA8dGQ+IGRheSA8L3RkPgorICogICAgICAgPHRkPiB7QGxpbmsgI2dldERheSgpfSA8L3RkPgorICogICAgICAgPHRkPiBJbmRlcGVuZGVudCBvZiBtb250aCwgbWF4IHJhbmdlIGlzIDEgdG8gMzEgb3Ige0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPGJyLz4KKyAqICAgICAgICAgICAgVGhlIG5vcm1hdGl2ZSB2YWx1ZSBjb25zdHJhaW50IHN0YXRlZCByZWxhdGl2ZSB0byBtb250aAorICogICAgICAgICAgICBmaWVsZCdzIHZhbHVlIGlzIGluIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNpc29mb3JtYXRzIj5XM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBBcHBlbmRpeCBEPC9hPi4KKyAqICAgICAgIDwvdGQ+CisgKiAgICAgPC90cj4KKyAqICAgICA8dHIgaWQ9ImRhdGV0aW1lZmllbGQtaG91ciI+CisgKiAgICAgICA8dGQ+aG91cjwvdGQ+CisgKiAgICAgICA8dGQ+e0BsaW5rICNnZXRIb3VyKCl9PC90ZD4KKyAqICAgICAgIDx0ZD4KKyAqICAgICAgICAgMCB0byAyNCBvciB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS4KKyAqICAgICAgICAgRm9yIGEgdmFsdWUgb2YgMjQsIHRoZSBtaW51dGUgYW5kIHNlY29uZCBmaWVsZCBtdXN0IGJlIHplcm8gcGVyCisgKiAgICAgICAgIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDUveG1sc2NoZW1hLWVycmF0YSNlMi00NSI+WE1MIFNjaGVtYSBFcnJhdGE8L2E+LgorICogICAgICAgPC90ZD4KKyAqICAgICA8L3RyPgorICogICAgIDxhIG5hbWU9ImRhdGV0aW1lZmllbGQtbWludXRlIi8+CisgKiAgICAgPHRyPgorICogICAgICAgPHRkPiBtaW51dGUgPC90ZD4KKyAqICAgICAgIDx0ZD4ge0BsaW5rICNnZXRNaW51dGUoKX0gPC90ZD4KKyAqICAgICAgIDx0ZD4gMCB0byA1OSBvciB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSA8L3RkPgorICogICAgIDwvdHI+CisgKiAgICAgPGEgbmFtZT0iZGF0ZXRpbWVmaWVsZC1zZWNvbmQiLz4KKyAqICAgICA8dHI+CisgKiAgICAgICA8dGQ+c2Vjb25kPC90ZD4KKyAqICAgICAgIDx0ZD4KKyAqICAgICAgICAge0BsaW5rICNnZXRTZWNvbmQoKX0gKyB7QGxpbmsgI2dldE1pbGxpc2Vjb25kKCl9LzEwMDAgb3I8YnIvPgorICogICAgICAgICB7QGxpbmsgI2dldFNlY29uZCgpfSArIHtAbGluayAjZ2V0RnJhY3Rpb25hbFNlY29uZCgpfQorICogICAgICAgPC90ZD4KKyAqICAgICAgIDx0ZD4KKyAqICAgICAgICAge0BsaW5rICNnZXRTZWNvbmQoKX0gZnJvbSAwIHRvIDYwIG9yIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9Ljxici8+CisgKiAgICAgICAgIDxpPihOb3RlOiA2MCBvbmx5IGFsbG93YWJsZSBmb3IgbGVhcCBzZWNvbmQuKTwvaT48YnIvPgorICogICAgICAgICB7QGxpbmsgI2dldEZyYWN0aW9uYWxTZWNvbmQoKX0gYWxsb3dzIGZvciBpbmZpbml0ZSBwcmVjaXNpb24gb3ZlciB0aGUgcmFuZ2UgZnJvbSAwLjAgdG8gMS4wIHdoZW4KKyAqICAgICAgICAgdGhlIHtAbGluayAjZ2V0U2Vjb25kKCl9IGlzIGRlZmluZWQuPGJyLz4KKyAqICAgICAgICAgPGNvZGU+RnJhY3Rpb25hbFNlY29uZDwvY29kZT4gaXMgb3B0aW9uYWwgYW5kIGhhcyBhIHZhbHVlIG9mIDxjb2RlPm51bGw8L2NvZGU+IHdoZW4gaXQgaXMgdW5kZWZpbmVkLjxiciAvPgorICogICAgICAgICAgICB7QGxpbmsgI2dldE1pbGxpc2Vjb25kKCl9IGlzIHRoZSBjb252ZW5pZW5jZQorICogICAgICAgICAgICBtaWxsaXNlY29uZCBwcmVjaXNpb24gb2YgdmFsdWUgb2Yge0BsaW5rICNnZXRGcmFjdGlvbmFsU2Vjb25kKCl9LgorICogICAgICAgPC90ZD4KKyAqICAgICA8L3RyPgorICogICAgIDx0ciBpZD0iZGF0ZXRpbWVmaWVsZC10aW1lem9uZSI+CisgKiAgICAgICA8dGQ+IHRpbWV6b25lIDwvdGQ+CisgKiAgICAgICA8dGQ+IHtAbGluayAjZ2V0VGltZXpvbmUoKX0gPC90ZD4KKyAqICAgICAgIDx0ZD4gTnVtYmVyIG9mIG1pbnV0ZXMgb3Ige0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uCisgKiAgICAgICAgIFZhbHVlIHJhbmdlIGZyb20gLTE0IGhvdXJzICgtMTQgKiA2MCBtaW51dGVzKSB0byAxNCBob3VycyAoMTQgKiA2MCBtaW51dGVzKS4KKyAqICAgICAgIDwvdGQ+CisgKiAgICAgPC90cj4KKyAqICAgPC90Ym9keT4KKyAqICA8L3RhYmxlPgorICoKKyAqIDxwPkFsbCBtYXhpbXVtIHZhbHVlIHNwYWNlIGNvbnN0cmFpbnRzIGxpc3RlZCBmb3IgdGhlIGZpZWxkcyBpbiB0aGUgdGFibGUKKyAqIGFib3ZlIGFyZSBjaGVja2VkIGJ5IGZhY3RvcnkgbWV0aG9kcywgQHtsaW5rIERhdGF0eXBlRmFjdG9yeX0sCisgKiBzZXR0ZXIgbWV0aG9kcyBhbmQgcGFyc2UgbWV0aG9kcyBvZgorICogdGhpcyBjbGFzcy4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gd2hlbiBhCisgKiBwYXJhbWV0ZXIncyB2YWx1ZSBpcyBvdXRzaWRlIHRoZSB2YWx1ZSBjb25zdHJhaW50IGZvciB0aGUgZmllbGQgb3IKKyAqIGlmIHRoZSBjb21wb3NpdGUKKyAqIHZhbHVlcyBjb25zdGl0dXRlIGFuIGludmFsaWQgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgaW5zdGFuY2UgKGZvciBleGFtcGxlLCBpZgorICogdGhlIDMxc3Qgb2YgSnVuZSBpcyBzcGVjaWZpZWQpLgorICogPC9wPgorICoKKyAqIDxwPlRoZSBmb2xsb3dpbmcgb3BlcmF0aW9ucyBhcmUgZGVmaW5lZCBmb3IgdGhpcyBjbGFzczoKKyAqIDx1bD4KKyAqICAgPGxpPmFjY2Vzc29ycy9tdXRhdG9ycyBmb3IgaW5kZXBlbmRlbnQgZGF0ZS90aW1lIGZpZWxkczwvbGk+CisgKiAgIDxsaT5jb252ZXJzaW9uIGJldHdlZW4gdGhpcyBjbGFzcyBhbmQgVzNDIFhNTCBTY2hlbWEgMS4wIGxleGljYWwgcmVwcmVzZW50YXRpb24sCisgKiAgICAge0BsaW5rICN0b1N0cmluZygpfSwge0BsaW5rIERhdGF0eXBlRmFjdG9yeSNuZXdYTUxHcmVnb3JpYW5DYWxlbmRhcihTdHJpbmcgbGV4aWNhbFJlcHJlc2VudGF0aW9uKX08L2xpPgorICogICA8bGk+Y29udmVyc2lvbiBiZXR3ZWVuIHRoaXMgY2xhc3MgYW5kIHtAbGluayBHcmVnb3JpYW5DYWxlbmRhcn0sCisgKiAgICAge0BsaW5rICN0b0dyZWdvcmlhbkNhbGVuZGFyKGphdmEudXRpbC5UaW1lWm9uZSB0aW1lem9uZSwgamF2YS51dGlsLkxvY2FsZSBhTG9jYWxlLCBYTUxHcmVnb3JpYW5DYWxlbmRhciBkZWZhdWx0cyl9LAorICogICAgIHtAbGluayBEYXRhdHlwZUZhY3Rvcnl9PC9saT4KKyAqICAgPGxpPnBhcnRpYWwgb3JkZXIgcmVsYXRpb24gY29tcGFyYXRvciBtZXRob2QsIHtAbGluayAjY29tcGFyZShYTUxHcmVnb3JpYW5DYWxlbmRhciB4bWxHcmVnb3JpYW5DYWxlbmRhcil9PC9saT4KKyAqICAgPGxpPntAbGluayAjZXF1YWxzKE9iamVjdCl9IGRlZmluZWQgcmVsYXRpdmUgdG8ge0BsaW5rICNjb21wYXJlKFhNTEdyZWdvcmlhbkNhbGVuZGFyIHhtbEdyZWdvcmlhbkNhbGVuZGFyKX0uPC9saT4KKyAqICAgPGxpPmFkZGl0aW9uIG9wZXJhdGlvbiB3aXRoIHtAbGluayBEdXJhdGlvbn0KKyAqICAgICAgaW5zdGFuY2UgYXMgZGVmaW5lZCBpbiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jYWRkaW5nLWR1cmF0aW9ucy10by1kYXRlVGltZXMiPgorICogICAgICBXM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBBcHBlbmRpeCBFLCA8aT5BZGRpbmcgZHVyYXRpb25zIHRvIGRhdGVUaW1lczwvaT48L2E+LgorICogICA8L2xpPgorICogPC91bD4KKyAqIDwvcD4KKyAqCisgKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKb3NlcGguRmlhbGxpQFN1bi5jb20iPkpvc2VwaCBGaWFsbGk8L2E+CisgKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpLb2hzdWtlLkthd2FndWNoaUBTdW4uY29tIj5Lb2hzdWtlIEthd2FndWNoaTwvYT4KKyAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgorICogQHZlcnNpb24gJFJldmlzaW9uOiA3NTk4MjIgJCwgJERhdGU6IDIwMDktMDMtMjkgMTg6MTU6MTEgLTA3MDAgKFN1biwgMjkgTWFyIDIwMDkpICQKKyAqIEBzZWUgRHVyYXRpb24KKyAqIEBzZWUgRGF0YXR5cGVGYWN0b3J5CisgKiBAc2luY2UgMS41CisgKi8KKworcHVibGljIGFic3RyYWN0IGNsYXNzIFhNTEdyZWdvcmlhbkNhbGVuZGFyCisgICAgaW1wbGVtZW50cyBDbG9uZWFibGUgeworCisgICAgLyoqCisgICAgICogPHA+VW5zZXQgYWxsIGZpZWxkcyB0byB1bmRlZmluZWQuPC9wPgorICAgICAqCisgICAgICogPHA+U2V0IGFsbCBpbnQgZmllbGRzIHRvIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IGFuZCByZWZlcmVuY2UgZmllbGRzCisgICAgICogdG8gbnVsbC48L3A+CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgY2xlYXIoKTsKKworICAgIC8qKgorICAgICAqIDxwPlJlc2V0IHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGl0cyBvcmlnaW5hbCB2YWx1ZXMuPC9wPgorICAgICAqCisgICAgICogPHA+PGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGlzIHJlc2V0IHRvIHRoZSBzYW1lIHZhbHVlcyBhcyB3aGVuIGl0IHdhcyBjcmVhdGVkIHdpdGgKKyAgICAgKiB7QGxpbmsgRGF0YXR5cGVGYWN0b3J5I25ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKCl9LAorICAgICAqIHtAbGluayBEYXRhdHlwZUZhY3RvcnkjbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoU3RyaW5nIGxleGljYWxSZXByZXNlbnRhdGlvbil9LAorICAgICAqIHtAbGluayBEYXRhdHlwZUZhY3RvcnkjbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoCisgICAgICogICBCaWdJbnRlZ2VyIHllYXIsCisgICAgICogICBpbnQgbW9udGgsCisgICAgICogICBpbnQgZGF5LAorICAgICAqICAgaW50IGhvdXIsCisgICAgICogICBpbnQgbWludXRlLAorICAgICAqICAgaW50IHNlY29uZCwKKyAgICAgKiAgIEJpZ0RlY2ltYWwgZnJhY3Rpb25hbFNlY29uZCwKKyAgICAgKiAgIGludCB0aW1lem9uZSl9LAorICAgICAqIHtAbGluayBEYXRhdHlwZUZhY3RvcnkjbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoCisgICAgICogICBpbnQgeWVhciwKKyAgICAgKiAgIGludCBtb250aCwKKyAgICAgKiAgIGludCBkYXksCisgICAgICogICBpbnQgaG91ciwKKyAgICAgKiAgIGludCBtaW51dGUsCisgICAgICogICBpbnQgc2Vjb25kLAorICAgICAqICAgaW50IG1pbGxpc2Vjb25kLAorICAgICAqICAgaW50IHRpbWV6b25lKX0sCisgICAgICoge0BsaW5rIERhdGF0eXBlRmFjdG9yeSNuZXdYTUxHcmVnb3JpYW5DYWxlbmRhcihHcmVnb3JpYW5DYWxlbmRhciBjYWwpfSwKKyAgICAgKiB7QGxpbmsgRGF0YXR5cGVGYWN0b3J5I25ld1hNTEdyZWdvcmlhbkNhbGVuZGFyRGF0ZSgKKyAgICAgKiAgIGludCB5ZWFyLAorICAgICAqICAgaW50IG1vbnRoLAorICAgICAqICAgaW50IGRheSwKKyAgICAgKiAgIGludCB0aW1lem9uZSl9LAorICAgICAqIHtAbGluayBEYXRhdHlwZUZhY3RvcnkjbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXJUaW1lKAorICAgICAqICAgaW50IGhvdXJzLAorICAgICAqICAgaW50IG1pbnV0ZXMsCisgICAgICogICBpbnQgc2Vjb25kcywKKyAgICAgKiAgIGludCB0aW1lem9uZSl9LAorICAgICAqIHtAbGluayBEYXRhdHlwZUZhY3RvcnkjbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXJUaW1lKAorICAgICAqICAgaW50IGhvdXJzLAorICAgICAqICAgaW50IG1pbnV0ZXMsCisgICAgICogICBpbnQgc2Vjb25kcywKKyAgICAgKiAgIEJpZ0RlY2ltYWwgZnJhY3Rpb25hbFNlY29uZCwKKyAgICAgKiAgIGludCB0aW1lem9uZSl9IG9yCisgICAgICoge0BsaW5rIERhdGF0eXBlRmFjdG9yeSNuZXdYTUxHcmVnb3JpYW5DYWxlbmRhclRpbWUoCisgICAgICogICBpbnQgaG91cnMsCisgICAgICogICBpbnQgbWludXRlcywKKyAgICAgKiAgIGludCBzZWNvbmRzLAorICAgICAqICAgaW50IG1pbGxpc2Vjb25kcywKKyAgICAgKiAgIGludCB0aW1lem9uZSl9LgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIDxwPjxjb2RlPnJlc2V0KCk8L2NvZGU+IGlzIGRlc2lnbmVkIHRvIGFsbG93IHRoZSByZXVzZSBvZiBleGlzdGluZyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT5zCisgICAgICogdGh1cyBzYXZpbmcgcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGUgY3JlYXRpb24gb2YgbmV3IDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPnMuPC9wPgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHJlc2V0KCk7CisKKyAgICAvKioKKyAgICAgKiA8cD5TZXQgbG93IGFuZCBoaWdoIG9yZGVyIGNvbXBvbmVudCBvZiBYU0QgPGNvZGU+ZGF0ZVRpbWU8L2NvZGU+IHllYXIgZmllbGQuPC9wPgorICAgICAqCisgICAgICogPHA+VW5zZXQgdGhpcyBmaWVsZCBieSBpbnZva2luZyB0aGUgc2V0dGVyIHdpdGggYSBwYXJhbWV0ZXIgdmFsdWUgb2YgPGNvZGU+bnVsbDwvY29kZT4uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHllYXIgdmFsdWUgY29uc3RyYWludHMgc3VtbWFyaXplZCBpbiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC15ZWFyIj55ZWFyIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIDxjb2RlPnllYXI8L2NvZGU+IHBhcmFtZXRlciBpcworICAgICAqIG91dHNpZGUgdmFsdWUgY29uc3RyYWludHMgZm9yIHRoZSBmaWVsZCBhcyBzcGVjaWZpZWQgaW4KKyAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZG1hcHBpbmciPmRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRZZWFyKEJpZ0ludGVnZXIgeWVhcik7CisKKyAgICAvKioKKyAgICAgKiA8cD5TZXQgeWVhciBvZiBYU0QgPGNvZGU+ZGF0ZVRpbWU8L2NvZGU+IHllYXIgZmllbGQuPC9wPgorICAgICAqCisgICAgICogPHA+VW5zZXQgdGhpcyBmaWVsZCBieSBpbnZva2luZyB0aGUgc2V0dGVyIHdpdGggYSBwYXJhbWV0ZXIgdmFsdWUgb2YKKyAgICAgKiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48L3A+CisgICAgICoKKyAgICAgKiA8cD5Ob3RlOiBpZiB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIDxjb2RlPnllYXI8L2NvZGU+IHBhcmFtZXRlcgorICAgICAqIGlzIGxlc3MgdGhhbiAxMF45LCB0aGUgZW9uIGNvbXBvbmVudCBvZiB0aGUgWFNEIHllYXIgZmllbGQgaXMgc2V0IHRvCisgICAgICogPGNvZGU+bnVsbDwvY29kZT4gYnkgdGhpcyBtZXRob2QuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHllYXIgdmFsdWUgY29uc3RyYWludHMgYXJlIHN1bW1hcml6ZWQgaW4gPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQteWVhciI+eWVhciBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCisgICAgICogICBJZiB5ZWFyIGlzIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LCB0aGVuIGVvbiBpcyBzZXQgdG8gPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0WWVhcihpbnQgeWVhcik7CisKKyAgICAvKioKKyAgICAgKiA8cD5TZXQgbW9udGguPC9wPgorICAgICAqCisgICAgICogPHA+VW5zZXQgdGhpcyBmaWVsZCBieSBpbnZva2luZyB0aGUgc2V0dGVyIHdpdGggYSBwYXJhbWV0ZXIgdmFsdWUgb2Yge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG1vbnRoIHZhbHVlIGNvbnN0cmFpbnRzIHN1bW1hcml6ZWQgaW4gPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtbW9udGgiPm1vbnRoIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIDxjb2RlPm1vbnRoPC9jb2RlPiBwYXJhbWV0ZXIgaXMKKyAgICAgKiBvdXRzaWRlIHZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGUgZmllbGQgYXMgc3BlY2lmaWVkIGluCisgICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0TW9udGgoaW50IG1vbnRoKTsKKworICAgIC8qKgorICAgICAqIDxwPlNldCBkYXlzIGluIG1vbnRoLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlVuc2V0IHRoaXMgZmllbGQgYnkgaW52b2tpbmcgdGhlIHNldHRlciB3aXRoIGEgcGFyYW1ldGVyIHZhbHVlIG9mIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXkgdmFsdWUgY29uc3RyYWludHMgc3VtbWFyaXplZCBpbiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1kYXkiPmRheSBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiA8Y29kZT5kYXk8L2NvZGU+IHBhcmFtZXRlciBpcworICAgICAqIG91dHNpZGUgdmFsdWUgY29uc3RyYWludHMgZm9yIHRoZSBmaWVsZCBhcyBzcGVjaWZpZWQgaW4KKyAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZG1hcHBpbmciPmRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXREYXkoaW50IGRheSk7CisKKyAgICAvKioKKyAgICAgKiA8cD5TZXQgdGhlIG51bWJlciBvZiBtaW51dGVzIGluIHRoZSB0aW1lem9uZSBvZmZzZXQuPC9wPgorICAgICAqCisgICAgICogPHA+VW5zZXQgdGhpcyBmaWVsZCBieSBpbnZva2luZyB0aGUgc2V0dGVyIHdpdGggYSBwYXJhbWV0ZXIgdmFsdWUgb2Yge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG9mZnNldCB2YWx1ZSBjb25zdHJhaW50cyBzdW1tYXJpemVkIGluIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLXRpbWV6b25lIj4KKyAgICAgKiAgIHRpbWV6b25lIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIDxjb2RlPm9mZnNldDwvY29kZT4gcGFyYW1ldGVyIGlzCisgICAgICogb3V0c2lkZSB2YWx1ZSBjb25zdHJhaW50cyBmb3IgdGhlIGZpZWxkIGFzIHNwZWNpZmllZCBpbgorICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkbWFwcGluZyI+ZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFRpbWV6b25lKGludCBvZmZzZXQpOworCisgICAgLyoqCisgICAgICogPHA+U2V0IHRpbWUgYXMgb25lIHVuaXQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGhvdXIgdmFsdWUgY29uc3RyYWludHMgYXJlIHN1bW1hcml6ZWQgaW4KKyAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1ob3VyIj5ob3VyIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KKyAgICAgKiBAcGFyYW0gbWludXRlIHZhbHVlIGNvbnN0cmFpbnRzIGFyZSBzdW1tYXJpemVkIGluCisgICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtbWludXRlIj5taW51dGUgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgorICAgICAqIEBwYXJhbSBzZWNvbmQgdmFsdWUgY29uc3RyYWludHMgYXJlIHN1bW1hcml6ZWQgaW4KKyAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1zZWNvbmQiPnNlY29uZCBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCisgICAgICoKKyAgICAgKiBAc2VlICNzZXRUaW1lKGludCwgaW50LCBpbnQsIEJpZ0RlY2ltYWwpCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBhbnkgcGFyYW1ldGVyIGlzCisgICAgICogb3V0c2lkZSB2YWx1ZSBjb25zdHJhaW50cyBmb3IgdGhlIGZpZWxkIGFzIHNwZWNpZmllZCBpbgorICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkbWFwcGluZyI+ZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRpbWUoaW50IGhvdXIsIGludCBtaW51dGUsIGludCBzZWNvbmQpIHsKKworICAgICAgICBzZXRUaW1lKAorICAgICAgICAgICAgaG91ciwKKyAgICAgICAgICAgIG1pbnV0ZSwKKyAgICAgICAgICAgIHNlY29uZCwKKyAgICAgICAgICAgIG51bGwgLy8gZnJhY3Rpb25hbAorICAgICAgICApOworICAgIH0KKworICAgIC8qKgorICAgICAgKiA8cD5TZXQgaG91cnMuPC9wPgorICAgICAgKgorICAgICAgKiA8cD5VbnNldCB0aGlzIGZpZWxkIGJ5IGludm9raW5nIHRoZSBzZXR0ZXIgd2l0aCBhIHBhcmFtZXRlciB2YWx1ZSBvZiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48L3A+CisgICAgICAqCisgICAgICAqIEBwYXJhbSBob3VyIHZhbHVlIGNvbnN0cmFpbnRzIHN1bW1hcml6ZWQgaW4gPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtaG91ciI+aG91ciBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCisgICAgICAqCisgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIDxjb2RlPmhvdXI8L2NvZGU+IHBhcmFtZXRlciBpcyBvdXRzaWRlIHZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGUgZmllbGQgYXMgc3BlY2lmaWVkIGluCisgICAgICAqICAgPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0SG91cihpbnQgaG91cik7CisKKyAgICAvKioKKyAgICAgKiA8cD5TZXQgbWludXRlcy48L3A+CisgICAgICoKKyAgICAgKiA8cD5VbnNldCB0aGlzIGZpZWxkIGJ5IGludm9raW5nIHRoZSBzZXR0ZXIgd2l0aCBhIHBhcmFtZXRlciB2YWx1ZSBvZiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbWludXRlIHZhbHVlIGNvbnN0cmFpbnRzIHN1bW1hcml6ZWQgaW4gPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtbWludXRlIj5taW51dGUgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgPGNvZGU+bWludXRlPC9jb2RlPiBwYXJhbWV0ZXIgaXMgb3V0c2lkZSB2YWx1ZSBjb25zdHJhaW50cyBmb3IgdGhlIGZpZWxkIGFzIHNwZWNpZmllZCBpbgorICAgICAqICAgPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCisgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRNaW51dGUoaW50IG1pbnV0ZSk7CisKKyAgICAvKioKKyAgICAgKiA8cD5TZXQgc2Vjb25kcy48L3A+CisgICAgICoKKyAgICAgKiA8cD5VbnNldCB0aGlzIGZpZWxkIGJ5IGludm9raW5nIHRoZSBzZXR0ZXIgd2l0aCBhIHBhcmFtZXRlciB2YWx1ZSBvZiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gc2Vjb25kIHZhbHVlIGNvbnN0cmFpbnRzIHN1bW1hcml6ZWQgaW4gPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtc2Vjb25kIj5zZWNvbmQgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgPGNvZGU+c2Vjb25kPC9jb2RlPiBwYXJhbWV0ZXIgaXMgb3V0c2lkZSB2YWx1ZSBjb25zdHJhaW50cyBmb3IgdGhlIGZpZWxkIGFzIHNwZWNpZmllZCBpbgorICAgICAqICAgPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCisgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRTZWNvbmQoaW50IHNlY29uZCk7CisKKyAgICAvKioKKyAgICAgKiA8cD5TZXQgbWlsbGlzZWNvbmRzLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlVuc2V0IHRoaXMgZmllbGQgYnkgaW52b2tpbmcgdGhlIHNldHRlciB3aXRoIGEgcGFyYW1ldGVyIHZhbHVlIG9mIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtaWxsaXNlY29uZCB2YWx1ZSBjb25zdHJhaW50cyBzdW1tYXJpemVkIGluCisgICAgICogICA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1taWxsaXNlY29uZCI+bWlsbGlzZWNvbmQgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgPGNvZGU+bWlsbGlzZWNvbmQ8L2NvZGU+IHBhcmFtZXRlciBpcyBvdXRzaWRlIHZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGUgZmllbGQgYXMgc3BlY2lmaWVkCisgICAgICogICBpbiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZG1hcHBpbmciPmRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KKyAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldE1pbGxpc2Vjb25kKGludCBtaWxsaXNlY29uZCk7CisKKyAgICAvKioKKyAgICAgKiA8cD5TZXQgZnJhY3Rpb25hbCBzZWNvbmRzLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlVuc2V0IHRoaXMgZmllbGQgYnkgaW52b2tpbmcgdGhlIHNldHRlciB3aXRoIGEgcGFyYW1ldGVyIHZhbHVlIG9mIDxjb2RlPm51bGw8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmcmFjdGlvbmFsIHZhbHVlIGNvbnN0cmFpbnRzIHN1bW1hcml6ZWQgaW4KKyAgICAgKiAgIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLWZyYWN0aW9uYWwiPmZyYWN0aW9uYWwgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgPGNvZGU+ZnJhY3Rpb25hbDwvY29kZT4gcGFyYW1ldGVyIGlzIG91dHNpZGUgdmFsdWUgY29uc3RyYWludHMgZm9yIHRoZSBmaWVsZCBhcyBzcGVjaWZpZWQKKyAgICAgKiAgIGluIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkbWFwcGluZyI+ZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgorICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RnJhY3Rpb25hbFNlY29uZChCaWdEZWNpbWFsIGZyYWN0aW9uYWwpOworCisgICAgLyoqCisgICAgICogPHA+U2V0IHRpbWUgYXMgb25lIHVuaXQsIGluY2x1ZGluZyB0aGUgb3B0aW9uYWwgaW5maW5pdGUgcHJlY2lzaW9uCisgICAgICogZnJhY3Rpb25hbCBzZWNvbmRzLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3VyIHZhbHVlIGNvbnN0cmFpbnRzIGFyZSBzdW1tYXJpemVkIGluCisgICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtaG91ciI+aG91ciBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCisgICAgICogQHBhcmFtIG1pbnV0ZSB2YWx1ZSBjb25zdHJhaW50cyBhcmUgc3VtbWFyaXplZCBpbgorICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLW1pbnV0ZSI+bWludXRlIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KKyAgICAgKiBAcGFyYW0gc2Vjb25kIHZhbHVlIGNvbnN0cmFpbnRzIGFyZSBzdW1tYXJpemVkIGluCisgICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtc2Vjb25kIj5zZWNvbmQgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgorICAgICAqIEBwYXJhbSBmcmFjdGlvbmFsIHZhbHVlIG9mIDxjb2RlPm51bGw8L2NvZGU+IGluZGljYXRlcyB0aGlzIG9wdGlvbmFsCisgICAgICogICBmaWVsZCBpcyBub3Qgc2V0LgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYW55IHBhcmFtZXRlciBpcworICAgICAqIG91dHNpZGUgdmFsdWUgY29uc3RyYWludHMgZm9yIHRoZSBmaWVsZCBhcyBzcGVjaWZpZWQgaW4KKyAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZG1hcHBpbmciPmRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lKAorICAgICAgICBpbnQgaG91ciwKKyAgICAgICAgaW50IG1pbnV0ZSwKKyAgICAgICAgaW50IHNlY29uZCwKKyAgICAgICAgQmlnRGVjaW1hbCBmcmFjdGlvbmFsKSB7CisKKyAgICAgICAgc2V0SG91cihob3VyKTsKKyAgICAgICAgc2V0TWludXRlKG1pbnV0ZSk7CisgICAgICAgIHNldFNlY29uZChzZWNvbmQpOworICAgICAgICBzZXRGcmFjdGlvbmFsU2Vjb25kKGZyYWN0aW9uYWwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlNldCB0aW1lIGFzIG9uZSB1bml0LCBpbmNsdWRpbmcgb3B0aW9uYWwgbWlsbGlzZWNvbmRzLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3VyIHZhbHVlIGNvbnN0cmFpbnRzIGFyZSBzdW1tYXJpemVkIGluCisgICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtaG91ciI+aG91ciBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCisgICAgICogQHBhcmFtIG1pbnV0ZSB2YWx1ZSBjb25zdHJhaW50cyBhcmUgc3VtbWFyaXplZCBpbgorICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLW1pbnV0ZSI+bWludXRlIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KKyAgICAgKiBAcGFyYW0gc2Vjb25kIHZhbHVlIGNvbnN0cmFpbnRzIGFyZSBzdW1tYXJpemVkIGluCisgICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtc2Vjb25kIj5zZWNvbmQgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgorICAgICAqIEBwYXJhbSBtaWxsaXNlY29uZCB2YWx1ZSBvZiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSBpbmRpY2F0ZXMgdGhpcworICAgICAqICAgICAgICAgICAgICAgICAgICBvcHRpb25hbCBmaWVsZCBpcyBub3Qgc2V0LgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYW55IHBhcmFtZXRlciBpcworICAgICAqIG91dHNpZGUgdmFsdWUgY29uc3RyYWludHMgZm9yIHRoZSBmaWVsZCBhcyBzcGVjaWZpZWQgaW4KKyAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZG1hcHBpbmciPmRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lKGludCBob3VyLCBpbnQgbWludXRlLCBpbnQgc2Vjb25kLCBpbnQgbWlsbGlzZWNvbmQpIHsKKworICAgICAgICBzZXRIb3VyKGhvdXIpOworICAgICAgICBzZXRNaW51dGUobWludXRlKTsKKyAgICAgICAgc2V0U2Vjb25kKHNlY29uZCk7CisgICAgICAgIHNldE1pbGxpc2Vjb25kKG1pbGxpc2Vjb25kKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5SZXR1cm4gaGlnaCBvcmRlciBjb21wb25lbnQgZm9yIFhNTCBTY2hlbWEgMS4wIGRhdGVUaW1lIGRhdGF0eXBlIGZpZWxkIGZvcgorICAgICAqIDxjb2RlPnllYXI8L2NvZGU+LgorICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgb3B0aW9uYWwgcGFydCBvZiB0aGUgeWVhciBmaWVsZCBpcyBub3QgZGVmaW5lZC48L3A+CisgICAgICoKKyAgICAgKiA8cD5WYWx1ZSBjb25zdHJhaW50cyBmb3IgdGhpcyB2YWx1ZSBhcmUgc3VtbWFyaXplZCBpbgorICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLXllYXIiPnllYXIgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LjwvcD4KKyAgICAgKiBAcmV0dXJuIGVvbiBvZiB0aGlzIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPi4gVGhlIHZhbHVlCisgICAgICogcmV0dXJuZWQgaXMgYW4gaW50ZWdlciBtdWx0aXBsZSBvZiAxMF45LgorICAgICAqCisgICAgICogQHNlZSAjZ2V0WWVhcigpCisgICAgICogQHNlZSAjZ2V0RW9uQW5kWWVhcigpCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJpZ0ludGVnZXIgZ2V0RW9uKCk7CisKKyAgICAvKioKKyAgICAgKiA8cD5SZXR1cm4gbG93IG9yZGVyIGNvbXBvbmVudCBmb3IgWE1MIFNjaGVtYSAxLjAgZGF0ZVRpbWUgZGF0YXR5cGUgZmllbGQgZm9yCisgICAgICogPGNvZGU+eWVhcjwvY29kZT4gb3Ige0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPC9wPgorICAgICAqCisgICAgICogPHA+VmFsdWUgY29uc3RyYWludHMgZm9yIHRoaXMgdmFsdWUgYXJlIHN1bW1hcml6ZWQgaW4KKyAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC15ZWFyIj55ZWFyIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHllYXIgIG9mIHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+LgorICAgICAqCisgICAgICogQHNlZSAjZ2V0RW9uKCkKKyAgICAgKiBAc2VlICNnZXRFb25BbmRZZWFyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldFllYXIoKTsKKworICAgIC8qKgorICAgICAqIDxwPlJldHVybiBYTUwgU2NoZW1hIDEuMCBkYXRlVGltZSBkYXRhdHlwZSBmaWVsZCBmb3IKKyAgICAgKiA8Y29kZT55ZWFyPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5WYWx1ZSBjb25zdHJhaW50cyBmb3IgdGhpcyB2YWx1ZSBhcmUgc3VtbWFyaXplZCBpbgorICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLXllYXIiPnllYXIgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gc3VtIG9mIDxjb2RlPmVvbjwvY29kZT4gYW5kIDxjb2RlPkJpZ0ludGVnZXIudmFsdWVPZih5ZWFyKTwvY29kZT4KKyAgICAgKiB3aGVuIGJvdGggZmllbGRzIGFyZSBkZWZpbmVkLiBXaGVuIG9ubHkgPGNvZGU+eWVhcjwvY29kZT4gaXMgZGVmaW5lZCwKKyAgICAgKiByZXR1cm4gaXQuIFdoZW4gYm90aCA8Y29kZT5lb248L2NvZGU+IGFuZCA8Y29kZT55ZWFyPC9jb2RlPiBhcmUgbm90CisgICAgICogZGVmaW5lZCwgcmV0dXJuIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqCisgICAgICogQHNlZSAjZ2V0RW9uKCkKKyAgICAgKiBAc2VlICNnZXRZZWFyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQmlnSW50ZWdlciBnZXRFb25BbmRZZWFyKCk7CisKKyAgICAvKioKKyAgICAgKiA8cD5SZXR1cm4gbnVtYmVyIG9mIG1vbnRoIG9yIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGlzIHZhbHVlIGFyZSBzdW1tYXJpemVkIGluCisgICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtbW9udGgiPm1vbnRoIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHllYXIgIG9mIHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+LgorICAgICAqCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRNb250aCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJuIGRheSBpbiBtb250aCBvciB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48L3A+CisgICAgICoKKyAgICAgKiA8cD5WYWx1ZSBjb25zdHJhaW50cyBmb3IgdGhpcyB2YWx1ZSBhcmUgc3VtbWFyaXplZCBpbgorICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLWRheSI+ZGF5IGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi48L3A+CisgICAgICoKKyAgICAgKiBAc2VlICNzZXREYXkoaW50KQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0RGF5KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGltZXpvbmUgb2Zmc2V0IGluIG1pbnV0ZXMgb3IKKyAgICAgKiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSBpZiB0aGlzIG9wdGlvbmFsIGZpZWxkIGlzIG5vdCBkZWZpbmVkLgorICAgICAqCisgICAgICogPHA+VmFsdWUgY29uc3RyYWludHMgZm9yIHRoaXMgdmFsdWUgYXJlIHN1bW1hcml6ZWQgaW4KKyAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC10aW1lem9uZSI+dGltZXpvbmUgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LjwvcD4KKyAgICAgKgorICAgICAqIEBzZWUgI3NldFRpbWV6b25lKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldFRpbWV6b25lKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gaG91cnMgb3Ige0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uCisgICAgICogUmV0dXJucyB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSBpZiB0aGlzIGZpZWxkIGlzIG5vdCBkZWZpbmVkLgorICAgICAqCisgICAgICogPHA+VmFsdWUgY29uc3RyYWludHMgZm9yIHRoaXMgdmFsdWUgYXJlIHN1bW1hcml6ZWQgaW4KKyAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1ob3VyIj5ob3VyIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi48L3A+CisgICAgICogQHNlZSAjc2V0VGltZShpbnQsIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0SG91cigpOworCisgICAgLyoqCisgICAgICogUmV0dXJuIG1pbnV0ZXMgb3Ige0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPC9wPgorICAgICAqIFJldHVybnMge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gaWYgdGhpcyBmaWVsZCBpcyBub3QgZGVmaW5lZC4KKyAgICAgKgorICAgICAqIDxwPlZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGlzIHZhbHVlIGFyZSBzdW1tYXJpemVkIGluCisgICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtbWludXRlIj5taW51dGUgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LjwvcD4KKyAgICAgKiBAc2VlICNzZXRUaW1lKGludCwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRNaW51dGUoKTsKKworICAgIC8qKgorICAgICAqIDxwPlJldHVybiBzZWNvbmRzIG9yIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlJldHVybnMge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gaWYgdGhpcyBmaWVsZCBpcyBub3QgZGVmaW5lZC4KKyAgICAgKiBXaGVuIHRoaXMgZmllbGQgaXMgbm90IGRlZmluZWQsIHRoZSBvcHRpb25hbCB4czpkYXRlVGltZQorICAgICAqIGZyYWN0aW9uYWwgc2Vjb25kcyBmaWVsZCwgcmVwcmVzZW50ZWQgYnkKKyAgICAgKiB7QGxpbmsgI2dldEZyYWN0aW9uYWxTZWNvbmQoKX0gYW5kIHtAbGluayAjZ2V0TWlsbGlzZWNvbmQoKX0sCisgICAgICogbXVzdCBub3QgYmUgZGVmaW5lZC48L3A+CisgICAgICoKKyAgICAgKiA8cD5WYWx1ZSBjb25zdHJhaW50cyBmb3IgdGhpcyB2YWx1ZSBhcmUgc3VtbWFyaXplZCBpbgorICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLXNlY29uZCI+c2Vjb25kIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIFNlY29uZCAgb2YgdGhpcyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uCisgICAgICoKKyAgICAgKiBAc2VlICNnZXRGcmFjdGlvbmFsU2Vjb25kKCkKKyAgICAgKiBAc2VlICNnZXRNaWxsaXNlY29uZCgpCisgICAgICogQHNlZSAjc2V0VGltZShpbnQsIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0U2Vjb25kKCk7CisKKyAgICAvKioKKyAgICAgKiA8cD5SZXR1cm4gbWlsbGlzZWNvbmQgcHJlY2lzaW9uIG9mIHtAbGluayAjZ2V0RnJhY3Rpb25hbFNlY29uZCgpfS48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCByZXByZXNlbnRzIGEgY29udmVuaWVuY2UgYWNjZXNzb3IgdG8gaW5maW5pdGUKKyAgICAgKiBwcmVjaXNpb24gZnJhY3Rpb25hbCBzZWNvbmQgdmFsdWUgcmV0dXJuZWQgYnkKKyAgICAgKiB7QGxpbmsgI2dldEZyYWN0aW9uYWxTZWNvbmQoKX0uIFRoZSByZXR1cm5lZCB2YWx1ZSBpcyB0aGUgcm91bmRlZAorICAgICAqIGRvd24gdG8gbWlsbGlzZWNvbmRzIHZhbHVlIG9mCisgICAgICoge0BsaW5rICNnZXRGcmFjdGlvbmFsU2Vjb25kKCl9LiBXaGVuIHtAbGluayAjZ2V0RnJhY3Rpb25hbFNlY29uZCgpfQorICAgICAqIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4sIHRoaXMgbWV0aG9kIG11c3QgcmV0dXJuCisgICAgICoge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPC9wPgorICAgICAqCisgICAgICogPHA+VmFsdWUgY29uc3RyYWludHMgZm9yIHRoaXMgdmFsdWUgYXJlIHN1bW1hcml6ZWQgaW4KKyAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1zZWNvbmQiPnNlY29uZCBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBNaWxsaXNlY29uZCAgb2YgdGhpcyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uCisgICAgICoKKyAgICAgKiBAc2VlICNnZXRGcmFjdGlvbmFsU2Vjb25kKCkKKyAgICAgKiBAc2VlICNzZXRUaW1lKGludCwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNaWxsaXNlY29uZCgpIHsKKworICAgICAgICBCaWdEZWNpbWFsIGZyYWN0aW9uYWxTZWNvbmRzID0gZ2V0RnJhY3Rpb25hbFNlY29uZCgpOworCisgICAgICAgIC8vIGlzIGZpZWxkIHVuZGVmaW5lZD8KKyAgICAgICAgaWYgKGZyYWN0aW9uYWxTZWNvbmRzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQ7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZ2V0RnJhY3Rpb25hbFNlY29uZCgpLm1vdmVQb2ludFJpZ2h0KDMpLmludFZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+UmV0dXJuIGZyYWN0aW9uYWwgc2Vjb25kcy48L3A+CisgICAgICoKKyAgICAgKiA8cD48Y29kZT5udWxsPC9jb2RlPiBpcyByZXR1cm5lZCB3aGVuIHRoaXMgb3B0aW9uYWwgZmllbGQgaXMgbm90IGRlZmluZWQuPC9wPgorICAgICAqCisgICAgICogPHA+VmFsdWUgY29uc3RyYWludHMgYXJlIGRldGFpbGVkIGluCisgICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtc2Vjb25kIj5zZWNvbmQgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgb3B0aW9uYWwgZmllbGQgY2FuIG9ubHkgaGF2ZSBhIGRlZmluZWQgdmFsdWUgd2hlbiB0aGUKKyAgICAgKiB4czpkYXRlVGltZSBzZWNvbmQgZmllbGQsIHJlcHJlc2VudGVkIGJ5IHtAbGluayAjZ2V0U2Vjb25kKCl9LAorICAgICAqIGRvZXMgbm90IHJldHVybiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIGZyYWN0aW9uYWwgc2Vjb25kcyAgb2YgdGhpcyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uCisgICAgICoKKyAgICAgKiBAc2VlICNnZXRTZWNvbmQoKQorICAgICAqIEBzZWUgI3NldFRpbWUoaW50LCBpbnQsIGludCwgQmlnRGVjaW1hbCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQmlnRGVjaW1hbCBnZXRGcmFjdGlvbmFsU2Vjb25kKCk7CisKKyAgICAvLyBjb21wYXJpc29ucworICAgIC8qKgorICAgICAqIDxwPkNvbXBhcmUgdHdvIGluc3RhbmNlcyBvZiBXM0MgWE1MIFNjaGVtYSAxLjAgZGF0ZS90aW1lIGRhdGF0eXBlcworICAgICAqIGFjY29yZGluZyB0byBwYXJ0aWFsIG9yZGVyIHJlbGF0aW9uIGRlZmluZWQgaW4KKyAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jZGF0ZVRpbWUtb3JkZXIiPlczQyBYTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIFNlY3Rpb24gMy4yLjcuMywKKyAgICAgKiA8aT5PcmRlciByZWxhdGlvbiBvbiBkYXRlVGltZTwvaT48L2E+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPjxjb2RlPnhzZDpkYXRlVGltZTwvY29kZT4gZGF0YXR5cGUgZmllbGQgbWFwcGluZyB0byBhY2Nlc3NvcnMgb2YKKyAgICAgKiB0aGlzIGNsYXNzIGFyZSBkZWZpbmVkIGluCisgICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHhtbEdyZWdvcmlhbkNhbGVuZGFyIEluc3RhbmNlIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBjb21wYXJlCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiA8Y29kZT50aGlzPC9jb2RlPiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gYW5kCisgICAgICogICB0aGUgc3BlY2lmaWVkIDxjb2RlPnhtbEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBhcworICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0xFU1NFUn0sCisgICAgICogICB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRVFVQUx9LAorICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dSRUFURVJ9IG9yCisgICAgICogICB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjSU5ERVRFUk1JTkFURX0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnhtbEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgY29tcGFyZShYTUxHcmVnb3JpYW5DYWxlbmRhciB4bWxHcmVnb3JpYW5DYWxlbmRhcik7CisKKyAgICAvKioKKyAgICAgKiA8cD5Ob3JtYWxpemUgdGhpcyBpbnN0YW5jZSB0byBVVEMuPC9wPgorICAgICAqCisgICAgICogPHA+MjAwMC0wMy0wNFQyMzowMDowMCswMzowMCBub3JtYWxpemVzIHRvIDIwMDAtMDMtMDRUMjA6MDA6MDBaPC9wPgorICAgICAqIDxwPkltcGxlbWVudHMgVzNDIFhNTCBTY2hlbWEgUGFydCAyLCBTZWN0aW9uIDMuMi43LjMgKEEpLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gPGNvZGU+dGhpczwvY29kZT4gPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IG5vcm1hbGl6ZWQgdG8gVVRDLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBYTUxHcmVnb3JpYW5DYWxlbmRhciBub3JtYWxpemUoKTsKKworICAgIC8qKgorICAgICAqIDxwPkluZGljYXRlcyB3aGV0aGVyIHBhcmFtZXRlciA8Y29kZT5vYmo8L2NvZGU+IGlzICJlcXVhbCB0byIgdGhpcyBvbmUuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiB0byBjb21wYXJlLgorICAgICAqCisgICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiB3aGVuIDxjb2RlPm9iajwvY29kZT4gaXMgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+CisgICAgICogICBhbmQgIHtAbGluayAjY29tcGFyZShYTUxHcmVnb3JpYW5DYWxlbmRhciBvYmopfSByZXR1cm5zIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNFUVVBTH0sIG90aGVyd2lzZSA8Y29kZT5mYWxzZTwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgWE1MR3JlZ29yaWFuQ2FsZW5kYXIpIHsKKyAgICAgICAgICAgIHJldHVybiBjb21wYXJlKChYTUxHcmVnb3JpYW5DYWxlbmRhcikgb2JqKSA9PSBEYXRhdHlwZUNvbnN0YW50cy5FUVVBTDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+UmV0dXJucyBhIGhhc2ggY29kZSBjb25zaXN0ZW50IHdpdGggdGhlIGRlZmluaXRpb24gb2YgdGhlIGVxdWFscyBtZXRob2QuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBoYXNoIGNvZGUgb2YgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKworICAgICAgICAvLyBGb2xsb3dpbmcgdHdvIGRhdGVzIGNvbXBhcmUgdG8gRVFVQUxTIHNpbmNlIGluIGRpZmZlcmVudCB0aW1lem9uZXMuCisgICAgICAgIC8vIDIwMDAtMDEtMTVUMTI6MDA6MDAtMDU6MDAgPT0gMjAwMC0wMS0xNVQxMzowMDowMC0wNDowMAorICAgICAgICAvLworICAgICAgICAvLyBNdXN0IGVuc3VyZSBib3RoIGluc3RhbmNlcyBnZW5lcmF0ZSBzYW1lIGhhc2hjb2RlIGJ5IG5vcm1hbGl6aW5nCisgICAgICAgIC8vIHRoaXMgdG8gVVRDIHRpbWV6b25lLgorICAgICAgICBpbnQgdGltZXpvbmUgPSBnZXRUaW1lem9uZSgpOworICAgICAgICBpZiAodGltZXpvbmUgPT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSB7CisgICAgICAgICAgICB0aW1lem9uZSA9IDA7CisgICAgICAgIH0KKyAgICAgICAgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgZ2MgPSB0aGlzOworICAgICAgICBpZiAodGltZXpvbmUgIT0gMCkgeworICAgICAgICAgICAgZ2MgPSB0aGlzLm5vcm1hbGl6ZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnYy5nZXRZZWFyKCkKKyAgICAgICAgKyBnYy5nZXRNb250aCgpCisgICAgICAgICsgZ2MuZ2V0RGF5KCkKKyAgICAgICAgKyBnYy5nZXRIb3VyKCkKKyAgICAgICAgKyBnYy5nZXRNaW51dGUoKQorICAgICAgICArIGdjLmdldFNlY29uZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlJldHVybiB0aGUgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiA8Y29kZT50aGlzPC9jb2RlPiBpbnN0YW5jZS4KKyAgICAgKiBUaGUgZm9ybWF0IGlzIHNwZWNpZmllZCBpbgorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNkYXRlVGltZS1vcmRlciI+WE1MIFNjaGVtYSAxLjAgUGFydCAyLCBTZWN0aW9uIDMuMi5bNy0xNF0uMSwKKyAgICAgKiA8aT5MZXhpY2FsIFJlcHJlc2VudGF0aW9uPC9pPiIuPC9hPjwvcD4KKyAgICAgKgorICAgICAqIDxwPlNwZWNpZmljIHRhcmdldCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIGZvcm1hdCBpcyBkZXRlcm1pbmVkIGJ5CisgICAgICoge0BsaW5rICNnZXRYTUxTY2hlbWFUeXBlKCl9LjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gWE1MLCBhcyA8Y29kZT5TdHJpbmc8L2NvZGU+LCByZXByZXNlbnRhdGlvbiBvZiB0aGlzIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlIGNvbWJpbmF0aW9uIG9mIHNldCBmaWVsZHMKKyAgICAgKiAgICBkb2VzIG5vdCBtYXRjaCBvbmUgb2YgdGhlIGVpZ2h0IGRlZmluZWQgWE1MIFNjaGVtYSBidWlsdGluIGRhdGUvdGltZSBkYXRhdHlwZXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyB0b1hNTEZvcm1hdCgpOworCisgICAgLyoqCisgICAgICogPHA+UmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBYTUwgU2NoZW1hIGRhdGUvdGltZSB0eXBlIHRoYXQgdGhpcyBpbnN0YW5jZQorICAgICAqIG1hcHMgdG8uIFR5cGUgaXMgY29tcHV0ZWQgYmFzZWQgb24gZmllbGRzIHRoYXQgYXJlIHNldC48L3A+CisgICAgICoKKyAgICAgKiA8dGFibGUgYm9yZGVyPSIyIiBydWxlcz0iYWxsIiBjZWxscGFkZGluZz0iMiI+CisgICAgICogICA8dGhlYWQ+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGggYWxpZ249ImNlbnRlciIgY29sc3Bhbj0iNyI+CisgICAgICogICAgICAgICBSZXF1aXJlZCBmaWVsZHMgZm9yIFhNTCBTY2hlbWEgMS4wIERhdGUvVGltZSBEYXRhdHlwZXMuPGJyLz4KKyAgICAgKiAgICAgICAgIDxpPih0aW1lem9uZSBpcyBvcHRpb25hbCBmb3IgYWxsIGRhdGUvdGltZSBkYXRhdHlwZXMpPC9pPgorICAgICAqICAgICAgIDwvdGg+CisgICAgICogICAgIDwvdHI+CisgICAgICogICA8L3RoZWFkPgorICAgICAqICAgPHRib2R5PgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPkRhdGF0eXBlPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+eWVhcjwvdGQ+CisgICAgICogICAgICAgPHRkPm1vbnRoPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+ZGF5PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+aG91cjwvdGQ+CisgICAgICogICAgICAgPHRkPm1pbnV0ZTwvdGQ+CisgICAgICogICAgICAgPHRkPnNlY29uZDwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+e0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0RBVEVUSU1FfTwvdGQ+CisgICAgICogICAgICAgPHRkPlg8L3RkPgorICAgICAqICAgICAgIDx0ZD5YPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+WDwvdGQ+CisgICAgICogICAgICAgPHRkPlg8L3RkPgorICAgICAqICAgICAgIDx0ZD5YPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+WDwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+e0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0RBVEV9PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+WDwvdGQ+CisgICAgICogICAgICAgPHRkPlg8L3RkPgorICAgICAqICAgICAgIDx0ZD5YPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgPC90cj4KKyAgICAgKiAgICAgPHRyPgorICAgICAqICAgICAgIDx0ZD57QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjVElNRX08L3RkPgorICAgICAqICAgICAgIDx0ZD48L3RkPgorICAgICAqICAgICAgIDx0ZD48L3RkPgorICAgICAqICAgICAgIDx0ZD48L3RkPgorICAgICAqICAgICAgIDx0ZD5YPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+WDwvdGQ+CisgICAgICogICAgICAgPHRkPlg8L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPntAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHWUVBUk1PTlRIfTwvdGQ+CisgICAgICogICAgICAgPHRkPlg8L3RkPgorICAgICAqICAgICAgIDx0ZD5YPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgPC90cj4KKyAgICAgKiAgICAgPHRyPgorICAgICAqICAgICAgIDx0ZD57QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjR01PTlRIREFZfTwvdGQ+CisgICAgICogICAgICAgPHRkPjwvdGQ+CisgICAgICogICAgICAgPHRkPlg8L3RkPgorICAgICAqICAgICAgIDx0ZD5YPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgPC90cj4KKyAgICAgKiAgICAgPHRyPgorICAgICAqICAgICAgIDx0ZD57QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjR1lFQVJ9PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+WDwvdGQ+CisgICAgICogICAgICAgPHRkPjwvdGQ+CisgICAgICogICAgICAgPHRkPjwvdGQ+CisgICAgICogICAgICAgPHRkPjwvdGQ+CisgICAgICogICAgICAgPHRkPjwvdGQ+CisgICAgICogICAgICAgPHRkPjwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+e0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dNT05USH08L3RkPgorICAgICAqICAgICAgIDx0ZD48L3RkPgorICAgICAqICAgICAgIDx0ZD5YPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgPC90cj4KKyAgICAgKiAgICAgPHRyPgorICAgICAqICAgICAgIDx0ZD57QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjR0RBWX08L3RkPgorICAgICAqICAgICAgIDx0ZD48L3RkPgorICAgICAqICAgICAgIDx0ZD48L3RkPgorICAgICAqICAgICAgIDx0ZD5YPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PC90ZD4KKyAgICAgKiAgICAgPC90cj4KKyAgICAgKiAgIDwvdGJvZHk+CisgICAgICogPC90YWJsZT4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgY29tYmluYXRpb24gb2Ygc2V0IGZpZWxkcworICAgICAqICAgIGRvZXMgbm90IG1hdGNoIG9uZSBvZiB0aGUgZWlnaHQgZGVmaW5lZCBYTUwgU2NoZW1hIGJ1aWx0aW4KKyAgICAgKiAgICBkYXRlL3RpbWUgZGF0YXR5cGVzLgorICAgICAqIEByZXR1cm4gT25lIG9mIHRoZSBmb2xsb3dpbmcgY2xhc3MgY29uc3RhbnRzOgorICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0RBVEVUSU1FfSwKKyAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNUSU1FfSwKKyAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNEQVRFfSwKKyAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHWUVBUk1PTlRIfSwKKyAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHTU9OVEhEQVl9LAorICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dZRUFSfSwKKyAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHTU9OVEh9IG9yCisgICAgICogICB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjR0RBWX0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFFOYW1lIGdldFhNTFNjaGVtYVR5cGUoKTsKKworICAgIC8qKgorICAgICAqIDxwPlJldHVybnMgYSA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IDxjb2RlPk9iamVjdDwvY29kZT4uPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIHJlc3VsdCBpcyBhIGxleGljYWwgcmVwcmVzZW50YXRpb24gZ2VuZXJhdGVkIGJ5IHtAbGluayAjdG9YTUxGb3JtYXQoKX0uPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBBIG5vbi08Y29kZT5udWxsPC9jb2RlPiB2YWxpZCA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+LgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlIGNvbWJpbmF0aW9uIG9mIHNldCBmaWVsZHMKKyAgICAgKiAgICBkb2VzIG5vdCBtYXRjaCBvbmUgb2YgdGhlIGVpZ2h0IGRlZmluZWQgWE1MIFNjaGVtYSBidWlsdGluIGRhdGUvdGltZSBkYXRhdHlwZXMuCisgICAgICoKKyAgICAgKiBAc2VlICN0b1hNTEZvcm1hdCgpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKworICAgICAgICByZXR1cm4gdG9YTUxGb3JtYXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWYWxpZGF0ZSBpbnN0YW5jZSBieSA8Y29kZT5nZXRYTUxTY2hlbWFUeXBlKCk8L2NvZGU+IGNvbnN0cmFpbnRzLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBkYXRhIHZhbHVlcyBhcmUgdmFsaWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNWYWxpZCgpOworCisgICAgLyoqCisgICAgICogPHA+QWRkIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiB0byB0aGlzIGluc3RhbmNlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBjb21wdXRhdGlvbiBpcyBzcGVjaWZpZWQgaW4KKyAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jYWRkaW5nLWR1cmF0aW9ucy10by1kYXRlVGltZXMiPlhNTCBTY2hlbWEgMS4wIFBhcnQgMiwgQXBwZW5kaXggRSwKKyAgICAgKiA8aT5BZGRpbmcgZHVyYXRpb25zIHRvIGRhdGVUaW1lczwvaT4+PC9hPi4KKyAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZHNtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4KKyAgICAgKiBkZWZpbmVzIHRoZSBtYXBwaW5nIGZyb20gWE1MIFNjaGVtYSAxLjAgPGNvZGU+ZGF0ZVRpbWU8L2NvZGU+IGZpZWxkcworICAgICAqIHRvIHRoaXMgY2xhc3MnIHJlcHJlc2VudGF0aW9uIG9mIHRob3NlIGZpZWxkcy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZHVyYXRpb24gRHVyYXRpb24gdG8gYWRkIHRvIHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+LgorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgd2hlbiA8Y29kZT5kdXJhdGlvbjwvY29kZT4gcGFyYW1ldGVyIGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGFkZChEdXJhdGlvbiBkdXJhdGlvbik7CisKKyAgICAvKioKKyAgICAgKiA8cD5Db252ZXJ0IHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGEge0BsaW5rIEdyZWdvcmlhbkNhbGVuZGFyfS48L3A+CisgICAgICoKKyAgICAgKiA8cD5XaGVuIDxjb2RlPnRoaXM8L2NvZGU+IGluc3RhbmNlIGhhcyBhbiB1bmRlZmluZWQgZmllbGQsIHRoaXMKKyAgICAgKiBjb252ZXJzaW9uIHJlbGllcyBvbiB0aGUgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBkZWZhdWx0CisgICAgICogZm9yIGl0cyBjb3JyZXNwb25kaW5nIGZpZWxkLiBBIG5vdGFibGUgZGlmZmVyZW5jZSBiZXR3ZWVuCisgICAgICogWE1MIFNjaGVtYSAxLjAgZGF0ZS90aW1lIGRhdGF0eXBlcyBhbmQgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPgorICAgICAqIGlzIHRoYXQgVGltZXpvbmUgdmFsdWUgaXMgb3B0aW9uYWwgZm9yIGRhdGUvdGltZSBkYXRhdHlwZXMgYW5kIGl0IGlzCisgICAgICogYSByZXF1aXJlZCBmaWVsZCBmb3IgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPi4gU2VlIGphdmFkb2MKKyAgICAgKiBmb3IgPGNvZGU+amF2YS51dGlsLlRpbWVab25lLmdldERlZmF1bHQoKTwvY29kZT4gb24gaG93IHRoZSBkZWZhdWx0CisgICAgICogaXMgZGV0ZXJtaW5lZC4gVG8gZXhwbGljaXRseSBzcGVjaWZ5IHRoZSA8Y29kZT5UaW1lWm9uZTwvY29kZT4KKyAgICAgKiBpbnN0YW5jZSwgc2VlCisgICAgICoge0BsaW5rICN0b0dyZWdvcmlhbkNhbGVuZGFyKFRpbWVab25lLCBMb2NhbGUsIFhNTEdyZWdvcmlhbkNhbGVuZGFyKX0uPC9wPgorICAgICAqCisgICAgICogPHRhYmxlIGJvcmRlcj0iMiIgcnVsZXM9ImFsbCIgY2VsbHBhZGRpbmc9IjIiPgorICAgICAqICAgPHRoZWFkPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRoIGFsaWduPSJjZW50ZXIiIGNvbHNwYW49IjIiPgorICAgICAqICAgICAgICAgIEZpZWxkIGJ5IEZpZWxkIENvbnZlcnNpb24gZnJvbSB0aGlzIGNsYXNzIHRvCisgICAgICogICAgICAgICAgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPgorICAgICAqICAgICAgIDwvdGg+CisgICAgICogICAgIDwvdHI+CisgICAgICogICA8L3RoZWFkPgorICAgICAqICAgPHRib2R5PgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgIDx0ZD48Y29kZT5qYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGZpZWxkPC90ZD4KKyAgICAgKiAgICAgICAgPHRkPjxjb2RlPmphdmF4LnhtbC5kYXRhdHlwZS5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gZmllbGQ8L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPjxjb2RlPkVSQTwvY29kZT48L3RkPgorICAgICAqICAgICAgIDx0ZD57QGxpbmsgI2dldEVvbkFuZFllYXIoKX08Y29kZT4uc2lnbnVtKCkgPCAwID8gR3JlZ29yaWFuQ2FsZW5kYXIuQkMgOiBHcmVnb3JpYW5DYWxlbmRhci5BRDwvY29kZT48L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPjxjb2RlPllFQVI8L2NvZGU+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+e0BsaW5rICNnZXRFb25BbmRZZWFyKCl9PGNvZGU+LmFicygpLmludFZhbHVlKCk8L2NvZGU+PGk+KjwvaT48L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPjxjb2RlPk1PTlRIPC9jb2RlPjwvdGQ+CisgICAgICogICAgICAgPHRkPntAbGluayAjZ2V0TW9udGgoKX0gLSB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjSkFOVUFSWX0gKyB7QGxpbmsgR3JlZ29yaWFuQ2FsZW5kYXIjSkFOVUFSWX08L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPjxjb2RlPkRBWV9PRl9NT05USDwvY29kZT48L3RkPgorICAgICAqICAgICAgIDx0ZD57QGxpbmsgI2dldERheSgpfTwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+SE9VUl9PRl9EQVk8L2NvZGU+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+e0BsaW5rICNnZXRIb3VyKCl9PC90ZD4KKyAgICAgKiAgICAgPC90cj4KKyAgICAgKiAgICAgPHRyPgorICAgICAqICAgICAgIDx0ZD48Y29kZT5NSU5VVEU8L2NvZGU+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+e0BsaW5rICNnZXRNaW51dGUoKX08L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPjxjb2RlPlNFQ09ORDwvY29kZT48L3RkPgorICAgICAqICAgICAgIDx0ZD57QGxpbmsgI2dldFNlY29uZCgpfTwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+TUlMTElTRUNPTkQ8L2NvZGU+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+Z2V0IG1pbGxpc2Vjb25kIG9yZGVyIGZyb20ge0BsaW5rICNnZXRGcmFjdGlvbmFsU2Vjb25kKCl9PGk+KjwvaT4gPC90ZD4KKyAgICAgKiAgICAgPC90cj4KKyAgICAgKiAgICAgPHRyPgorICAgICAqICAgICAgIDx0ZD48Y29kZT5HcmVnb3JpYW5DYWxlbmRhci5zZXRUaW1lWm9uZShUaW1lWm9uZSk8L2NvZGU+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+e0BsaW5rICNnZXRUaW1lem9uZSgpfSBmb3JtYXR0ZWQgaW50byBDdXN0b20gdGltZXpvbmUgaWQ8L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgPC90Ym9keT4KKyAgICAgKiA8L3RhYmxlPgorICAgICAqIDxpPio8L2k+IGRlc2lnbmF0ZXMgcG9zc2libGUgbG9zcyBvZiBwcmVjaXNpb24gZHVyaW5nIHRoZSBjb252ZXJzaW9uIGR1ZQorICAgICAqIHRvIHNvdXJjZSBkYXRhdHlwZSBoYXZpbmcgaGlnaGVyIHByZWNpc2lvbiB0aGFuIHRhcmdldCBkYXRhdHlwZS4KKyAgICAgKgorICAgICAqIDxwPlRvIGVuc3VyZSBjb25zaXN0ZW5jeSBpbiBjb252ZXJzaW9uIGltcGxlbWVudGF0aW9ucywgdGhlIG5ldworICAgICAqIDxjb2RlPkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBzaG91bGQgYmUgaW5zdGFudGlhdGVkIGluIGZvbGxvd2luZworICAgICAqIG1hbm5lci4KKyAgICAgKiA8dWw+CisgICAgICogICA8bGk+VXNpbmcgPGNvZGU+dGltZVpvbmU8L2NvZGU+IHZhbHVlIGFzIGRlZmluZWQgYWJvdmUsIGNyZWF0ZSBhIG5ldworICAgICAqIDxjb2RlPmphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcih0aW1lWm9uZSxMb2NhbGUuZ2V0RGVmYXVsdCgpKTwvY29kZT4uCisgICAgICogICA8L2xpPgorICAgICAqICAgPGxpPkluaXRpYWxpemUgYWxsIEdyZWdvcmlhbkNhbGVuZGFyIGZpZWxkcyBieSBjYWxsaW5nIHsoQGxpbmsgR2Vnb3JpYW5DYWxlbmRhciNjbGVhcigpfS48L2xpPgorICAgICAqICAgPGxpPk9idGFpbiBhIHB1cmUgR3JlZ29yaWFuIENhbGVuZGFyIGJ5IGludm9raW5nCisgICAgICogICA8Y29kZT5HcmVnb3JpYW5DYWxlbmRhci5zZXRHcmVnb3JpYW5DaGFuZ2UoCisgICAgICogICBuZXcgRGF0ZShMb25nLk1JTl9WQUxVRSkpPC9jb2RlPi48L2xpPgorICAgICAqICAgPGxpPkl0cyBmaWVsZHMgRVJBLCBZRUFSLCBNT05USCwgREFZX09GX01PTlRILCBIT1VSX09GX0RBWSwKKyAgICAgKiAgICAgICBNSU5VVEUsIFNFQ09ORCBhbmQgTUlMTElTRUNPTkQgYXJlIHNldCB1c2luZyB0aGUgbWV0aG9kCisgICAgICogICAgICAgPGNvZGU+Q2FsZW5kYXIuc2V0KGludCxpbnQpPC9jb2RlPjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAc2VlICN0b0dyZWdvcmlhbkNhbGVuZGFyKGphdmEudXRpbC5UaW1lWm9uZSwgamF2YS51dGlsLkxvY2FsZSwgWE1MR3JlZ29yaWFuQ2FsZW5kYXIpCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEdyZWdvcmlhbkNhbGVuZGFyIHRvR3JlZ29yaWFuQ2FsZW5kYXIoKTsKKworICAgIC8qKgorICAgICAqIDxwPkNvbnZlcnQgdGhpcyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gYWxvbmcgd2l0aCBwcm92aWRlZCBwYXJhbWV0ZXJzCisgICAgICogdG8gYSB7QGxpbmsgR3JlZ29yaWFuQ2FsZW5kYXJ9IGluc3RhbmNlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPiBTaW5jZSBYTUwgU2NoZW1hIDEuMCBkYXRlL3RpbWUgZGF0ZXR5cGVzIGhhcyBubyBjb25jZXB0IG9mCisgICAgICogdGltZXpvbmUgaWRzIG9yIGRheWxpZ2h0IHNhdmluZ3MgdGltZXpvbmUgaWRzLCB0aGlzIGNvbnZlcnNpb24gb3BlcmF0aW9uCisgICAgICogYWxsb3dzIHRoZSB1c2VyIHRvIGV4cGxpY2l0bHkgc3BlY2lmeSBvbmUgd2l0aAorICAgICAqIDxjb2RlPnRpbWV6b25lPC9jb2RlPiBwYXJhbWV0ZXIuPC9wPgorICAgICAqCisgICAgICogPHA+VG8gY29tcHV0ZSB0aGUgcmV0dXJuIHZhbHVlJ3MgPGNvZGU+VGltZVpvbmU8L2NvZGU+IGZpZWxkLAorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+d2hlbiBwYXJhbWV0ZXIgPGNvZGU+dGltZVpvbmU8L2NvZGU+IGlzIG5vbi1udWxsLAorICAgICAqIGl0IGlzIHRoZSB0aW1lem9uZSBmaWVsZC48L2xpPgorICAgICAqIDxsaT5lbHNlIHdoZW4gPGNvZGU+dGhpcy5nZXRUaW1lem9uZSgpICE9IEZJRUxEX1VOREVGSU5FRDwvY29kZT4sCisgICAgICogY3JlYXRlIGEgPGNvZGU+amF2YS51dGlsLlRpbWVab25lPC9jb2RlPiB3aXRoIGEgY3VzdG9tIHRpbWV6b25lIGlkCisgICAgICogdXNpbmcgdGhlIDxjb2RlPnRoaXMuZ2V0VGltZXpvbmUoKTwvY29kZT4uPC9saT4KKyAgICAgKiA8bGk+ZWxzZSB3aGVuIDxjb2RlPmRlZmF1bHRzLmdldFRpbWV6b25lKCkgIT0gRklFTERfVU5ERUZJTkVEPC9jb2RlPiwKKyAgICAgKiBjcmVhdGUgYSA8Y29kZT5qYXZhLnV0aWwuVGltZVpvbmU8L2NvZGU+IHdpdGggYSBjdXN0b20gdGltZXpvbmUgaWQKKyAgICAgKiB1c2luZyA8Y29kZT5kZWZhdWx0cy5nZXRUaW1lem9uZSgpPC9jb2RlPi48L2xpPgorICAgICAqIDxsaT5lbHNlIHVzZSB0aGUgPGNvZGU+R3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGRlZmF1bHQgdGltZXpvbmUgdmFsdWUKKyAgICAgKiBmb3IgdGhlIGhvc3QgaXMgZGVmaW5lZCBhcyBzcGVjaWZpZWQgYnkKKyAgICAgKiA8Y29kZT5qYXZhLnV0aWwuVGltZVpvbmUuZ2V0RGVmYXVsdCgpPC9jb2RlPi48L2xpPjwvdWw+PC9wPgorICAgICAqCisgICAgICogPHA+VG8gZW5zdXJlIGNvbnNpc3RlbmN5IGluIGNvbnZlcnNpb24gaW1wbGVtZW50YXRpb25zLCB0aGUgbmV3CisgICAgICogPGNvZGU+R3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHNob3VsZCBiZSBpbnN0YW50aWF0ZWQgaW4gZm9sbG93aW5nCisgICAgICogbWFubmVyLgorICAgICAqIDx1bD4KKyAgICAgKiAgIDxsaT5DcmVhdGUgYSBuZXcgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyKFRpbWVab25lLAorICAgICAqICAgICAgIExvY2FsZSk8L2NvZGU+IHdpdGggVGltZVpvbmUgc2V0IGFzIHNwZWNpZmllZCBhYm92ZSBhbmQgdGhlCisgICAgICogICAgICAgPGNvZGU+TG9jYWxlPC9jb2RlPiBwYXJhbWV0ZXIuCisgICAgICogICA8L2xpPgorICAgICAqICAgPGxpPkluaXRpYWxpemUgYWxsIEdyZWdvcmlhbkNhbGVuZGFyIGZpZWxkcyBieSBjYWxsaW5nIHtAbGluayBHcmVnb3JpYW5DYWxlbmRhciNjbGVhcigpfTwvbGk+CisgICAgICogICA8bGk+T2J0YWluIGEgcHVyZSBHcmVnb3JpYW4gQ2FsZW5kYXIgYnkgaW52b2tpbmcKKyAgICAgKiAgIDxjb2RlPkdyZWdvcmlhbkNhbGVuZGFyLnNldEdyZWdvcmlhbkNoYW5nZSgKKyAgICAgKiAgIG5ldyBEYXRlKExvbmcuTUlOX1ZBTFVFKSk8L2NvZGU+LjwvbGk+CisgICAgICogICA8bGk+SXRzIGZpZWxkcyBFUkEsIFlFQVIsIE1PTlRILCBEQVlfT0ZfTU9OVEgsIEhPVVJfT0ZfREFZLAorICAgICAqICAgICAgIE1JTlVURSwgU0VDT05EIGFuZCBNSUxMSVNFQ09ORCBhcmUgc2V0IHVzaW5nIHRoZSBtZXRob2QKKyAgICAgKiAgICAgICA8Y29kZT5DYWxlbmRhci5zZXQoaW50LGludCk8L2NvZGU+PC9saT4KKyAgICAgKiA8L3VsPjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0aW1lem9uZSBwcm92aWRlIFRpbWV6b25lLiA8Y29kZT5udWxsPC9jb2RlPiBpcyBhIGxlZ2FsIHZhbHVlLgorICAgICAqIEBwYXJhbSBhTG9jYWxlICBwcm92aWRlIGV4cGxpY2l0IExvY2FsZS4gVXNlIGRlZmF1bHQgR3JlZ29yaWFuQ2FsZW5kYXIgbG9jYWxlIGlmCisgICAgICogICAgICAgICAgICAgICAgIHZhbHVlIGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqIEBwYXJhbSBkZWZhdWx0cyBwcm92aWRlIGRlZmF1bHQgZmllbGQgdmFsdWVzIHRvIHVzZSB3aGVuIGNvcnJlc3BvbmRpbmcKKyAgICAgKiAgICAgICAgICAgICAgICAgZmllbGQgZm9yIHRoaXMgaW5zdGFuY2UgaXMgRklFTERfVU5ERUZJTkVEIG9yIG51bGwuCisgICAgICogICAgICAgICAgICAgICAgIElmIDxjb2RlPmRlZmF1bHRzPC9jb2RlPmlzIDxjb2RlPm51bGw8L2NvZGU+IG9yIGEgZmllbGQKKyAgICAgKiAgICAgICAgICAgICAgICAgd2l0aGluIHRoZSBzcGVjaWZpZWQgPGNvZGU+ZGVmYXVsdHM8L2NvZGU+IGlzIHVuZGVmaW5lZCwKKyAgICAgKiAgICAgICAgICAgICAgICAganVzdCB1c2UgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBkZWZhdWx0cy4KKyAgICAgKiBAcmV0dXJuIGEgamF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyIGNvbnZlcnNpb24gb2YgdGhpcyBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgR3JlZ29yaWFuQ2FsZW5kYXIgdG9HcmVnb3JpYW5DYWxlbmRhcigKKyAgICAgICAgamF2YS51dGlsLlRpbWVab25lIHRpbWV6b25lLAorICAgICAgICBqYXZhLnV0aWwuTG9jYWxlIGFMb2NhbGUsCisgICAgICAgIFhNTEdyZWdvcmlhbkNhbGVuZGFyIGRlZmF1bHRzKTsKKworICAgIC8qKgorICAgICAqIDxwPlJldHVybnMgYSA8Y29kZT5qYXZhLnV0aWwuVGltZVpvbmU8L2NvZGU+IGZvciB0aGlzIGNsYXNzLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHRpbWV6b25lIGZpZWxkIGlzIGRlZmluZWQgZm9yIHRoaXMgaW5zdGFuY2UsCisgICAgICogcmV0dXJucyBUaW1lWm9uZSBpbml0aWFsaXplZCB3aXRoIGN1c3RvbSB0aW1lem9uZSBpZAorICAgICAqIG9mIHpvbmVvZmZzZXQuIElmIHRpbWV6b25lIGZpZWxkIGlzIHVuZGVmaW5lZCwKKyAgICAgKiB0cnkgdGhlIGRlZmF1bHRab25lb2Zmc2V0IHRoYXQgd2FzIHBhc3NlZCBpbi4KKyAgICAgKiBJZiBkZWZhdWx0Wm9uZW9mZnNldCBpcyBGSUVMRF9VTkRFRklORUQsIHJldHVybgorICAgICAqIGRlZmF1bHQgdGltZXpvbmUgZm9yIHRoaXMgaG9zdC4KKyAgICAgKiAoU2FtZSBkZWZhdWx0IGFzIGphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcikuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGRlZmF1bHRab25lb2Zmc2V0IGRlZmF1bHQgem9uZW9mZnNldCBpZiB0aGlzIHpvbmVvZmZzZXQgaXMKKyAgICAgKiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGltZVpvbmUgZm9yIHRoaXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFRpbWVab25lIGdldFRpbWVab25lKGludCBkZWZhdWx0Wm9uZW9mZnNldCk7CisKKyAgICAvKioKKyAgICAgKiA8cD5DcmVhdGVzIGFuZCByZXR1cm5zIGEgY29weSBvZiB0aGlzIG9iamVjdC48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIGNvcHkgb2YgdGhpcyA8Y29kZT5PYmplY3Q8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IE9iamVjdCBjbG9uZSgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9kYXRhdHlwZS9wYWNrYWdlLmh0bWwgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL2RhdGF0eXBlL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MjE4NTMzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9kYXRhdHlwZS9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwxNDcgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cis8IS0tICRJZDogcGFja2FnZS5odG1sIDU0MTkzOSAyMDA3LTA1LTI2IDIxOjEwOjUyWiBtcmdsYXZhcyAkIC0tPgorCis8IURPQ1RZUEUgaHRtbCBQVUJMSUMgIi0vL1czQy8vRFREIFhIVE1MIDEuMCBTdHJpY3QvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvVFIveGh0bWwxL0RURC94aHRtbDEtc3RyaWN0LmR0ZCI+Cis8aHRtbCB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI+CisKKwk8aGVhZD4KKwkJPHRpdGxlPmphdmF4LnhtbC5kYXRhdHlwZTwvdGl0bGU+CisKKwkJPG1ldGEgbmFtZT0iQGF1dGhvciIgY29udGVudD0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iIC8+CisJCTxtZXRhIG5hbWU9IkB2ZXJzaW9uIiBjb250ZW50PSIkUmV2aXNpb246IDU0MTkzOSAkLCAkRGF0ZTogMjAwNy0wNS0yNiAxNDoxMDo1MiAtMDcwMCAoU2F0LCAyNiBNYXkgMjAwNykgJCIgLz4KKwkJPG1ldGEgbmFtZT0iQHNlZSIgY29udGVudD0nPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2RhdGVUaW1lIj5XM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBTZWN0aW9uIDMuMi43LTE0PC9hPicgLz4KKwkJPG1ldGEgbmFtZT0iQHNlZSIgY29udGVudD0nPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsLyNkYXlUaW1lRHVyYXRpb24iPlhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6ZGF5VGltZUR1cmF0aW9uPC9hPicgLz4KKwkJPG1ldGEgbmFtZT0iQHNlZSIgY29udGVudD0nPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsLyN5ZWFyTW9udGhEdXJhdGlvbiI+WFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWwsIHhkdDp5ZWFyTW9udGhEdXJhdGlvbjwvYT4nIC8+CisJCTxtZXRhIG5hbWU9IkBzaW5jZSIgY29udGVudD0iMS41IiAvPgorCTwvaGVhZD4KKworCTxib2R5PgorCisJCTxwPlhNTC9KYXZhIFR5cGUgTWFwcGluZ3MuPC9wPgorCQkKKwkJPHA+VGhlIDxjb2RlPmphdmF4LnhtbC5kYXRhdHlwZTwvY29kZT4gQVBJIHByb3ZpZGVzIFhNTC9KYXZhIHR5cGUgbWFwcGluZ3MuPC9wPgorCQkKKwkJPHA+VGhlIGZvbGxvd2luZyBYTUwgc3RhbmRhcmRzIGFwcGx5OjwvcD4KKwkJPHVsPgorCQkJPGxpPjxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNkYXRlVGltZSI+VzNDIFhNTCBTY2hlbWEgMS4wIFBhcnQgMiwgU2VjdGlvbiAzLjIuNy0xNDwvYT48L2xpPgorCQkJPGxpPjxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoLWRhdGFtb2RlbC8jZGF5VGltZUR1cmF0aW9uIj5YUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OmRheVRpbWVEdXJhdGlvbjwvYT48L2xpPgorCQkJPGxpPjxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoLWRhdGFtb2RlbC8jeWVhck1vbnRoRHVyYXRpb24iPlhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6eWVhck1vbnRoRHVyYXRpb248L2E+PC9saT4KKwkJPC91bD4KKworCQk8aHIgLz4KKwkJCisJCTx0YWJsZSBib3JkZXI9IjEiIGNlbGxwYWRkaW5nPSIyIj4KKwkJCTx0aGVhZD4KKwkJCQk8dHI+CisJCQkJCTx0aD5XM0MgWE1MIFNjaGVtYSBEYXRhIFR5cGU8L3RoPgorCQkJCQk8dGg+SmF2YSBEYXRhIFR5cGU8L3RoPgorCQkJCTwvdHI+CisJCQk8L3RoZWFkPgorCQkJCisJCQk8dGJvZHk+CisJCQkJPHRyPgorCQkJCQk8dGQ+eHM6ZGF0ZTwvdGQ+CisJCQkJCTx0ZD57QGxpbmsgamF2YXgueG1sLmRhdGF0eXBlLlhNTEdyZWdvcmlhbkNhbGVuZGFyfTwvdGQ+CisJCQkJPC90cj4KKwkJCQk8dHI+CisJCQkJCTx0ZD54czpkYXRlVGltZTwvdGQ+CisJCQkJCTx0ZD57QGxpbmsgamF2YXgueG1sLmRhdGF0eXBlLlhNTEdyZWdvcmlhbkNhbGVuZGFyfTwvdGQ+CisJCQkJPC90cj4KKwkJCQk8dHI+CisJCQkJCTx0ZD54czpkdXJhdGlvbjwvdGQ+CisJCQkJCTx0ZD57QGxpbmsgamF2YXgueG1sLmRhdGF0eXBlLkR1cmF0aW9ufTwvdGQ+CisJCQkJPC90cj4KKwkJCQk8dHI+CisJCQkJCTx0ZD54czpnRGF5PC90ZD4KKwkJCQkJPHRkPntAbGluayBqYXZheC54bWwuZGF0YXR5cGUuWE1MR3JlZ29yaWFuQ2FsZW5kYXJ9PC90ZD4KKwkJCQk8L3RyPgorCQkJCTx0cj4KKwkJCQkJPHRkPnhzOmdNb250aCA8L3RkPgorCQkJCQk8dGQ+e0BsaW5rIGphdmF4LnhtbC5kYXRhdHlwZS5YTUxHcmVnb3JpYW5DYWxlbmRhcn08L3RkPgorCQkJCTwvdHI+CisJCQkJPHRyPgorCQkJCQk8dGQ+eHM6Z01vbnRoRGF5PC90ZD4KKwkJCQkJPHRkPntAbGluayBqYXZheC54bWwuZGF0YXR5cGUuWE1MR3JlZ29yaWFuQ2FsZW5kYXJ9PC90ZD4KKwkJCQk8L3RyPgorCQkJCTx0cj4KKwkJCQkJPHRkPnhzOmdZZWFyPC90ZD4KKwkJCQkJPHRkPntAbGluayBqYXZheC54bWwuZGF0YXR5cGUuWE1MR3JlZ29yaWFuQ2FsZW5kYXJ9PC90ZD4KKwkJCQk8L3RyPgorCQkJCTx0cj4KKwkJCQkJPHRkPnhzOmdZZWFyTW9udGg8L3RkPgorCQkJCQk8dGQ+e0BsaW5rIGphdmF4LnhtbC5kYXRhdHlwZS5YTUxHcmVnb3JpYW5DYWxlbmRhcn08L3RkPgorCQkJCTwvdHI+CisJCQkJPHRyPgorCQkJCQk8dGQ+eHM6dGltZTwvdGQ+CisJCQkJCTx0ZD57QGxpbmsgamF2YXgueG1sLmRhdGF0eXBlLlhNTEdyZWdvcmlhbkNhbGVuZGFyfTwvdGQ+CisJCQkJPC90cj4KKwkJCQkKKwkJCTwvdGJvZHk+CisJCTwvdGFibGU+CisJCQorCQk8aHIgLz4KKwkJCisJCQorCQk8dGFibGUgYm9yZGVyPSIxIiBjZWxscGFkZGluZz0iMiI+CisJCQk8dGhlYWQ+CisJCQkJPHRyPgorCQkJCQk8dGg+WFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWw8L3RoPgorCQkJCQk8dGg+SmF2YSBEYXRhIFR5cGU8L3RoPgorCQkJCTwvdHI+CisJCQk8L3RoZWFkPgorCQkJCisJCQk8dGJvZHk+CisJCQkJPHRyPgorCQkJCQk8dGQ+eGR0OmRheVRpbWVEdXJhdGlvbjwvdGQ+CisJCQkJCTx0ZD57QGxpbmsgamF2YXgueG1sLmRhdGF0eXBlLkR1cmF0aW9ufTwvdGQ+CisJCQkJPC90cj4KKwkJCQk8dHI+CisJCQkJCTx0ZD54ZHQ6eWVhck1vbnRoRHVyYXRpb248L3RkPgorCQkJCQk8dGQ+e0BsaW5rIGphdmF4LnhtbC5kYXRhdHlwZS5EdXJhdGlvbn08L3RkPgorCQkJCTwvdHI+CisJCQk8L3Rib2R5PgorCQk8L3RhYmxlPgorCQkKKwkJPGhyIC8+CisJCQorCQk8cD4KKwkJCVczQyBYTUwgU2NoZW1hIGRhdGEgdHlwZXMgdGhhdCBoYXZlIGEgIjxlbT5uYXR1cmFsPC9lbT4iIG1hcHBpbmcgdG8gSmF2YSB0eXBlcyBhcmUgZGVmaW5lZCBieQorCQkJSlNSIDMxOiBKYXZhJnRyYWRlOyBBcmNoaXRlY3R1cmUgZm9yIFhNTCBCaW5kaW5nIChKQVhCKSBTcGVjaWZpY2F0aW9uLCBCaW5kaW5nIFhNTCBTY2hlbWEgdG8gSmF2YSBSZXByZXNlbnRhdGlvbnMuCisJCQlKQVhCIGRlZmluZWQgbWFwcGluZ3MgZm9yIFhNTCBTY2hlbWEgYnVpbHQtaW4gZGF0YSB0eXBlcyBpbmNsdWRlOgorCQk8L3A+CisJCTx1bD4KKwkJCTxsaT54czphbnlTaW1wbGVUeXBlPC9saT4KKwkJCTxsaT54czpiYXNlNjRCaW5hcnk8L2xpPgorCQkJPGxpPnhzOmJvb2xlYW48L2xpPgorCQkJPGxpPnhzOmJ5dGU8L2xpPgorCQkJPGxpPnhzOmRlY2ltYWw8L2xpPgorCQkJPGxpPnhzOmRvdWJsZTwvbGk+CisJCQk8bGk+eHM6ZmxvYXQ8L2xpPgorCQkJPGxpPnhzOmhleEJpbmFyeTwvbGk+CisJCQk8bGk+eHM6aW50PC9saT4KKwkJCTxsaT54czppbnRlZ2VyPC9saT4KKwkJCTxsaT54czpsb25nPC9saT4KKwkJCTxsaT54czpRTmFtZTwvbGk+CisJCQk8bGk+eHM6c2hvcnQ8L2xpPgorCQkJPGxpPnhzOnN0cmluZzwvbGk+CisJCQk8bGk+eHM6dW5zaWduZWRCeXRlPC9saT4KKwkJCTxsaT54czp1bnNpZ25lZEludDwvbGk+CisJCQk8bGk+eHM6dW5zaWduZWRTaG9ydDwvbGk+CisJCTwvdWw+CisJCQorCQk8aHIgLz4KKwkJCisKKwkJPHVsPgorCQkJPGxpPkF1dGhvciA8YSBocmVmPSJtYWlsdG86SmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+PC9saT4KKwkJCTxsaT5TZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2RhdGVUaW1lIj5XM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBTZWN0aW9uIDMuMi43LTE0PC9hPjwvbGk+CisJCQk8bGk+U2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoLWRhdGFtb2RlbC8jZGF5VGltZUR1cmF0aW9uIj5YUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OmRheVRpbWVEdXJhdGlvbjwvYT48L2xpPgorCQkJPGxpPlNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwvI3llYXJNb250aER1cmF0aW9uIj5YUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OnllYXJNb250aER1cmF0aW9uPC9hPjwvbGk+CisJCQk8bGk+U2luY2UgMS41PC9saT4KKwkJPC91bD4KKwkJCisJCTxociAvPgorCQkKKworCTwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvbmFtZXNwYWNlL05hbWVzcGFjZUNvbnRleHQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvbmFtZXNwYWNlL05hbWVzcGFjZUNvbnRleHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZDMwMjRhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9uYW1lc3BhY2UvTmFtZXNwYWNlQ29udGV4dC5qYXZhCkBAIC0wLDAgKzEsMjU2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8gJElkOiBOYW1lc3BhY2VDb250ZXh0LmphdmEgNDQ2NTk4IDIwMDYtMDktMTUgMTI6NTU6NDBaIGplcmVtaWFzICQKKworcGFja2FnZSBqYXZheC54bWwubmFtZXNwYWNlOworCitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworCisvKioKKyAqIDxwPkludGVyZmFjZSBmb3IgcmVhZCBvbmx5IFhNTCBOYW1lc3BhY2UgY29udGV4dCBwcm9jZXNzaW5nLjwvcD4KKyAqCisgKiA8cD5BbiBYTUwgTmFtZXNwYWNlIGhhcyB0aGUgcHJvcGVydGllczo8L3A+CisgKiA8dWw+CisgKiAgIDxsaT5OYW1lc3BhY2UgVVJJOgorICogICAgICAgTmFtZXNwYWNlIG5hbWUgZXhwcmVzc2VkIGFzIGEgVVJJIHRvIHdoaWNoIHRoZSBwcmVmaXggaXMgYm91bmQ8L2xpPgorICogICA8bGk+cHJlZml4OiBzeW50YWN0aWNhbGx5LCB0aGlzIGlzIHRoZSBwYXJ0IG9mIHRoZSBhdHRyaWJ1dGUgbmFtZQorICogICAgICAgZm9sbG93aW5nIHRoZSA8Y29kZT5YTUxDb25zdGFudHMuWE1MTlNfQVRUUklCVVRFPC9jb2RlPgorICogICAgICAgKCJ4bWxucyIpIGluIHRoZSBOYW1lc3BhY2UgZGVjbGFyYXRpb248L2xpPgorICogPC91bD4KKyAqIDxwPiBleGFtcGxlOiA8Y29kZT4mbHQ7ZWxlbWVudCB4bWxuczpwcmVmaXg9Imh0dHA6Ly9OYW1lc3BhY2UtbmFtZS1VUkkiJmd0OzwvY29kZT48L3A+CisgKgorICogPHA+QWxsIDxjb2RlPmdldCooKik8L2NvZGU+IG1ldGhvZHMgb3BlcmF0ZSBpbiB0aGUgY3VycmVudCBzY29wZQorICogZm9yIE5hbWVzcGFjZSBVUkkgYW5kIHByZWZpeCByZXNvbHV0aW9uLjwvcD4KKyAqCisgKiA8cD5Ob3RlIHRoYXQgYSBOYW1lc3BhY2UgVVJJIGNhbiBiZSBib3VuZCB0bworICogPHN0cm9uZz5tdWx0aXBsZTwvc3Ryb25nPiBwcmVmaXhlcyBpbiB0aGUgY3VycmVudCBzY29wZS4gIFRoaXMgY2FuCisgKiBvY2N1ciB3aGVuIG11bHRpcGxlIDxjb2RlPlhNTENvbnN0YW50cy5YTUxOU19BVFRSSUJVVEU8L2NvZGU+CisgKiAoInhtbG5zIikgTmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBvY2N1ciBpbiB0aGUgc2FtZSBTdGFydC1UYWcgYW5kCisgKiByZWZlciB0byB0aGUgc2FtZSBOYW1lc3BhY2UgVVJJLiBlLmcuPGJyIC8+CisgKiA8cHJlPgorICogJmx0O2VsZW1lbnQgeG1sbnM6cHJlZml4MT0iaHR0cDovL05hbWVzcGFjZS1uYW1lLVVSSSIKKyAqICAgICAgICAgIHhtbG5zOnByZWZpeDI9Imh0dHA6Ly9OYW1lc3BhY2UtbmFtZS1VUkkiJmd0OworICogPC9wcmU+CisgKiBUaGlzIGNhbiBhbHNvIG9jY3VyIHdoZW4gdGhlIHNhbWUgTmFtZXNwYWNlIFVSSSBpcyB1c2VkIGluIG11bHRpcGxlCisgKiA8Y29kZT5YTUxDb25zdGFudHMuWE1MTlNfQVRUUklCVVRFPC9jb2RlPiAoInhtbG5zIikgTmFtZXNwYWNlCisgKiBkZWNsYXJhdGlvbnMgaW4gdGhlIGxvZ2ljYWwgcGFyZW50IGVsZW1lbnQgaGllcmFyY2h5LiAgZS5nLjxiciAvPgorICogPHByZT4KKyAqICZsdDtwYXJlbnQgeG1sbnM6cHJlZml4MT0iaHR0cDovL05hbWVzcGFjZS1uYW1lLVVSSSI+CisgKiAgICZsdDtjaGlsZCB4bWxuczpwcmVmaXgyPSJodHRwOi8vTmFtZXNwYWNlLW5hbWUtVVJJIiZndDsKKyAqICAgICAuLi4KKyAqICAgJmx0Oy9jaGlsZCZndDsKKyAqICZsdDsvcGFyZW50Jmd0OworICogPC9wcmU+PC9wPgorICoKKyAqIDxwPkEgcHJlZml4IGNhbiBvbmx5IGJlIGJvdW5kIHRvIGEgPHN0cm9uZz5zaW5nbGU8L3N0cm9uZz4KKyAqIE5hbWVzcGFjZSBVUkkgaW4gdGhlIGN1cnJlbnQgc2NvcGUuPC9wPgorICoKKyAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgorICogQHZlcnNpb24gJFJldmlzaW9uOiA0NDY1OTggJCwgJERhdGU6IDIwMDYtMDktMTUgMDU6NTU6NDAgLTA3MDAgKEZyaSwgMTUgU2VwIDIwMDYpICQKKyAqIEBzZWUgamF2YXgueG1sLlhNTENvbnN0YW50cyBqYXZheC5YTUxDb25zdGFudHMgZm9yIGRlY2xhcmF0aW9ucyBvZiBjb21tb24gWE1MIHZhbHVlcworICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jUU5hbWUiPlhNTCBTY2hlbWEgUGFydDI6IERhdGF0eXBlczwvYT4KKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8jbnMtcXVhbG5hbWVzIj5OYW1lc3BhY2VzIGluIFhNTDwvYT4KKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvWE1ML3htbC1uYW1lcy0xOTk5MDExNC1lcnJhdGEiPk5hbWVzcGFjZXMgaW4gWE1MIEVycmF0YTwvYT4KKyAqIEBzaW5jZSAxLjUKKyAqLworCitwdWJsaWMgaW50ZXJmYWNlIE5hbWVzcGFjZUNvbnRleHQgeworCisgICAgLyoqCisgICAgICogPHA+R2V0IE5hbWVzcGFjZSBVUkkgYm91bmQgdG8gYSBwcmVmaXggaW4gdGhlIGN1cnJlbnQgc2NvcGUuPC9wPgorICAgICAqCisgICAgICogPHA+V2hlbiByZXF1ZXN0aW5nIGEgTmFtZXNwYWNlIFVSSSBieSBwcmVmaXgsIHRoZSBmb2xsb3dpbmcKKyAgICAgKiB0YWJsZSBkZXNjcmliZXMgdGhlIHJldHVybmVkIE5hbWVzcGFjZSBVUkkgdmFsdWUgZm9yIGFsbAorICAgICAqIHBvc3NpYmxlIHByZWZpeCB2YWx1ZXM6PC9wPgorICAgICAqCisgICAgICogPHRhYmxlIGJvcmRlcj0iMiIgcnVsZXM9ImFsbCIgY2VsbHBhZGRpbmc9IjQiPgorICAgICAqICAgPHRoZWFkPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkIGFsaWduPSJjZW50ZXIiIGNvbHNwYW49IjIiPgorICAgICAqICAgICAgICAgPGNvZGU+Z2V0TmFtZXNwYWNlVVJJKHByZWZpeCk8L2NvZGU+CisgICAgICogICAgICAgICByZXR1cm4gdmFsdWUgZm9yIHNwZWNpZmllZCBwcmVmaXhlcworICAgICAqICAgICAgIDwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+cHJlZml4IHBhcmFtZXRlcjwvdGQ+CisgICAgICogICAgICAgPHRkPk5hbWVzcGFjZSBVUkkgcmV0dXJuIHZhbHVlPC90ZD4KKyAgICAgKiAgICAgPC90cj4KKyAgICAgKiAgIDwvdGhlYWQ+CisgICAgICogICA8dGJvZHk+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+REVGQVVMVF9OU19QUkVGSVg8L2NvZGU+ICgiIik8L3RkPgorICAgICAqICAgICAgIDx0ZD5kZWZhdWx0IE5hbWVzcGFjZSBVUkkgaW4gdGhlIGN1cnJlbnQgc2NvcGUgb3IKKyAgICAgKiAgICAgICAgIDxjb2RlPntAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI05VTExfTlNfVVJJIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSSgiIil9PC9jb2RlPgorICAgICAqICAgICAgICAgd2hlbiB0aGVyZSBpcyBubyBkZWZhdWx0IE5hbWVzcGFjZSBVUkkgaW4gdGhlIGN1cnJlbnQgc2NvcGU8L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPmJvdW5kIHByZWZpeDwvdGQ+CisgICAgICogICAgICAgPHRkPk5hbWVzcGFjZSBVUkkgYm91bmQgdG8gcHJlZml4IGluIGN1cnJlbnQgc2NvcGU8L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPnVuYm91bmQgcHJlZml4PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+e0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjTlVMTF9OU19VUkkgWE1MQ29uc3RhbnRzLk5VTExfTlNfVVJJKCIiKX08L2NvZGU+IDwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+WE1MQ29uc3RhbnRzLlhNTF9OU19QUkVGSVg8L2NvZGU+ICgieG1sIik8L3RkPgorICAgICAqICAgICAgIDx0ZD48Y29kZT5YTUxDb25zdGFudHMuWE1MX05TX1VSSTwvY29kZT4KKyAgICAgKiAgICAgICAgICAgKCJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiKTwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+WE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURTwvY29kZT4gKCJ4bWxucyIpPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+WE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURV9OU19VUkk8L2NvZGU+CisgICAgICogICAgICAgICAoImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIik8L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPjxjb2RlPm51bGw8L2NvZGU+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd248L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgIDwvdGJvZHk+CisgICAgICogPC90YWJsZT4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcmVmaXggcHJlZml4IHRvIGxvb2sgdXAKKyAgICAgKiBAcmV0dXJuIE5hbWVzcGFjZSBVUkkgYm91bmQgdG8gcHJlZml4IGluIHRoZSBjdXJyZW50IHNjb3BlCisgICAgICovCisgICAgU3RyaW5nIGdldE5hbWVzcGFjZVVSSShTdHJpbmcgcHJlZml4KTsKKworICAgIC8qKgorICAgICAqIDxwPkdldCBwcmVmaXggYm91bmQgdG8gTmFtZXNwYWNlIFVSSSBpbiB0aGUgY3VycmVudCBzY29wZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5UbyBnZXQgYWxsIHByZWZpeGVzIGJvdW5kIHRvIGEgTmFtZXNwYWNlIFVSSSBpbiB0aGUgY3VycmVudAorICAgICAqIHNjb3BlLCB1c2Uge0BsaW5rICNnZXRQcmVmaXhlcyhTdHJpbmcgbmFtZXNwYWNlVVJJKX0uPC9wPgorICAgICAqCisgICAgICogPHA+V2hlbiByZXF1ZXN0aW5nIGEgcHJlZml4IGJ5IE5hbWVzcGFjZSBVUkksIHRoZSBmb2xsb3dpbmcKKyAgICAgKiB0YWJsZSBkZXNjcmliZXMgdGhlIHJldHVybmVkIHByZWZpeCB2YWx1ZSBmb3IgYWxsIE5hbWVzcGFjZSBVUkkKKyAgICAgKiB2YWx1ZXM6PC9wPgorICAgICAqCisgICAgICogPHRhYmxlIGJvcmRlcj0iMiIgcnVsZXM9ImFsbCIgY2VsbHBhZGRpbmc9IjQiPgorICAgICAqICAgPHRoZWFkPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkIGFsaWduPSJjZW50ZXIiIGNvbHNwYW49IjIiPgorICAgICAqICAgICAgICAgPGNvZGU+Z2V0UHJlZml4KG5hbWVzcGFjZVVSSSk8L2NvZGU+IHJldHVybiB2YWx1ZSBmb3IKKyAgICAgKiAgICAgICAgIHNwZWNpZmllZCBOYW1lc3BhY2UgVVJJcworICAgICAqICAgICAgIDwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+TmFtZXNwYWNlIFVSSSBwYXJhbWV0ZXI8L3RkPgorICAgICAqICAgICAgIDx0ZD5wcmVmaXggdmFsdWUgcmV0dXJuZWQ8L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgPC90aGVhZD4KKyAgICAgKiAgIDx0Ym9keT4KKyAgICAgKiAgICAgPHRyPgorICAgICAqICAgICAgIDx0ZD4mbHQ7ZGVmYXVsdCBOYW1lc3BhY2UgVVJJJmd0OzwvdGQ+CisgICAgICogICAgICAgPHRkPjxjb2RlPlhNTENvbnN0YW50cy5ERUZBVUxUX05TX1BSRUZJWDwvY29kZT4gKCIiKQorICAgICAqICAgICAgIDwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+Ym91bmQgTmFtZXNwYWNlIFVSSTwvdGQ+CisgICAgICogICAgICAgPHRkPnByZWZpeCBib3VuZCB0byBOYW1lc3BhY2UgVVJJIGluIHRoZSBjdXJyZW50IHNjb3BlLAorICAgICAqICAgICAgICAgICBpZiBtdWx0aXBsZSBwcmVmaXhlcyBhcmUgYm91bmQgdG8gdGhlIE5hbWVzcGFjZSBVUkkgaW4KKyAgICAgKiAgICAgICAgICAgdGhlIGN1cnJlbnQgc2NvcGUsIGEgc2luZ2xlIGFyYml0cmFyeSBwcmVmaXgsIHdob3NlCisgICAgICogICAgICAgICAgIGNob2ljZSBpcyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQsIGlzIHJldHVybmVkPC90ZD4KKyAgICAgKiAgICAgPC90cj4KKyAgICAgKiAgICAgPHRyPgorICAgICAqICAgICAgIDx0ZD51bmJvdW5kIE5hbWVzcGFjZSBVUkk8L3RkPgorICAgICAqICAgICAgIDx0ZD48Y29kZT5udWxsPC9jb2RlPjwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+WE1MQ29uc3RhbnRzLlhNTF9OU19VUkk8L2NvZGU+CisgICAgICogICAgICAgICAgICgiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIik8L3RkPgorICAgICAqICAgICAgIDx0ZD48Y29kZT5YTUxDb25zdGFudHMuWE1MX05TX1BSRUZJWDwvY29kZT4gKCJ4bWwiKTwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+WE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURV9OU19VUkk8L2NvZGU+CisgICAgICogICAgICAgICAgICgiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iKTwvdGQ+CisgICAgICogICAgICAgPHRkPjxjb2RlPlhNTENvbnN0YW50cy5YTUxOU19BVFRSSUJVVEU8L2NvZGU+ICgieG1sbnMiKTwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+bnVsbDwvY29kZT48L3RkPgorICAgICAqICAgICAgIDx0ZD48Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bjwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICA8L3Rib2R5PgorICAgICAqIDwvdGFibGU+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFVSSSBvZiBOYW1lc3BhY2UgdG8gbG9va3VwCisgICAgICogQHJldHVybiBwcmVmaXggYm91bmQgdG8gTmFtZXNwYWNlIFVSSSBpbiBjdXJyZW50IGNvbnRleHQKKyAgICAgKi8KKyAgICBTdHJpbmcgZ2V0UHJlZml4KFN0cmluZyBuYW1lc3BhY2VVUkkpOworCisgICAgLyoqCisgICAgICogPHA+R2V0IGFsbCBwcmVmaXhlcyBib3VuZCB0byBhIE5hbWVzcGFjZSBVUkkgaW4gdGhlIGN1cnJlbnQKKyAgICAgKiBzY29wZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5BbiBJdGVyYXRvciBvdmVyIFN0cmluZyBlbGVtZW50cyBpcyByZXR1cm5lZCBpbiBhbiBhcmJpdHJhcnksIDxzdHJvbmc+aW1wbGVtZW50YXRpb24gZGVwZW5kZW50PC9zdHJvbmc+LCBvcmRlci48L3A+CisgICAgICoKKyAgICAgKiA8cD48c3Ryb25nPlRoZSA8Y29kZT5JdGVyYXRvcjwvY29kZT4gaXMKKyAgICAgKiA8ZW0+bm90PC9lbT4gbW9kaWZpYWJsZS4gIGUuZy4gdGhlCisgICAgICogPGNvZGU+cmVtb3ZlKCk8L2NvZGU+IG1ldGhvZCB3aWxsIHRocm93CisgICAgICogPGNvZGU+VW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb248L2NvZGU+Ljwvc3Ryb25nPjwvcD4KKyAgICAgKgorICAgICAqIDxwPldoZW4gcmVxdWVzdGluZyBwcmVmaXhlcyBieSBOYW1lc3BhY2UgVVJJLCB0aGUgZm9sbG93aW5nCisgICAgICogdGFibGUgZGVzY3JpYmVzIHRoZSByZXR1cm5lZCBwcmVmaXhlcyB2YWx1ZSBmb3IgYWxsIE5hbWVzcGFjZQorICAgICAqIFVSSSB2YWx1ZXM6PC9wPgorICAgICAqCisgICAgICogPHRhYmxlIGJvcmRlcj0iMiIgcnVsZXM9ImFsbCIgY2VsbHBhZGRpbmc9IjQiPgorICAgICAqICAgPHRoZWFkPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkIGFsaWduPSJjZW50ZXIiIGNvbHNwYW49IjIiPjxjb2RlPgorICAgICAqICAgICAgICAgZ2V0UHJlZml4ZXMobmFtZXNwYWNlVVJJKTwvY29kZT4gcmV0dXJuIHZhbHVlIGZvcgorICAgICAqICAgICAgICAgc3BlY2lmaWVkIE5hbWVzcGFjZSBVUklzPC90ZD4KKyAgICAgKiAgICAgPC90cj4KKyAgICAgKiAgICAgPHRyPgorICAgICAqICAgICAgIDx0ZD5OYW1lc3BhY2UgVVJJIHBhcmFtZXRlcjwvdGQ+CisgICAgICogICAgICAgPHRkPnByZWZpeGVzIHZhbHVlIHJldHVybmVkPC90ZD4KKyAgICAgKiAgICAgPC90cj4KKyAgICAgKiAgIDwvdGhlYWQ+CisgICAgICogICA8dGJvZHk+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+Ym91bmQgTmFtZXNwYWNlIFVSSSwKKyAgICAgKiAgICAgICAgIGluY2x1ZGluZyB0aGUgJmx0O2RlZmF1bHQgTmFtZXNwYWNlIFVSSSZndDs8L3RkPgorICAgICAqICAgICAgIDx0ZD48Y29kZT5JdGVyYXRvcjwvY29kZT4gb3ZlciBwcmVmaXhlcyBib3VuZCB0byBOYW1lc3BhY2UgVVJJIGluCisgICAgICogICAgICAgICB0aGUgY3VycmVudCBzY29wZSBpbiBhbiBhcmJpdHJhcnksIDxzdHJvbmc+aW1wbGVtZW50YXRpb24gZGVwZW5kZW50PC9zdHJvbmc+LAorICAgICAqICAgICAgICAgb3JkZXI8L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPnVuYm91bmQgTmFtZXNwYWNlIFVSSTwvdGQ+CisgICAgICogICAgICAgPHRkPmVtcHR5IDxjb2RlPkl0ZXJhdG9yPC9jb2RlPjwvdGQ+CisgICAgICogICAgIDwvdHI+CisgICAgICogICAgIDx0cj4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+WE1MQ29uc3RhbnRzLlhNTF9OU19VUkk8L2NvZGU+CisgICAgICogICAgICAgICAgICgiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIik8L3RkPgorICAgICAqICAgICAgIDx0ZD48Y29kZT5JdGVyYXRvcjwvY29kZT4gd2l0aCBvbmUgZWxlbWVudCBzZXQgdG8KKyAgICAgKiAgICAgICAgIDxjb2RlPlhNTENvbnN0YW50cy5YTUxfTlNfUFJFRklYPC9jb2RlPiAoInhtbCIpPC90ZD4KKyAgICAgKiAgICAgPC90cj4KKyAgICAgKiAgICAgPHRyPgorICAgICAqICAgICAgIDx0ZD48Y29kZT5YTUxDb25zdGFudHMuWE1MTlNfQVRUUklCVVRFX05TX1VSSTwvY29kZT4KKyAgICAgKiAgICAgICAgICAgKCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIpPC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+SXRlcmF0b3I8L2NvZGU+IHdpdGggb25lIGVsZW1lbnQgc2V0IHRvCisgICAgICogICAgICAgICA8Y29kZT5YTUxDb25zdGFudHMuWE1MTlNfQVRUUklCVVRFPC9jb2RlPiAoInhtbG5zIik8L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgICA8dHI+CisgICAgICogICAgICAgPHRkPjxjb2RlPm51bGw8L2NvZGU+PC90ZD4KKyAgICAgKiAgICAgICA8dGQ+PGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd248L3RkPgorICAgICAqICAgICA8L3RyPgorICAgICAqICAgPC90Ym9keT4KKyAgICAgKiA8L3RhYmxlPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBVUkkgb2YgTmFtZXNwYWNlIHRvIGxvb2t1cAorICAgICAqIEByZXR1cm4gPGNvZGU+SXRlcmF0b3I8L2NvZGU+IGZvciBhbGwgcHJlZml4ZXMgYm91bmQgdG8gdGhlCisgICAgICogTmFtZXNwYWNlIFVSSSBpbiB0aGUgY3VycmVudCBzY29wZQorICAgICAqLworICAgIEl0ZXJhdG9yIGdldFByZWZpeGVzKFN0cmluZyBuYW1lc3BhY2VVUkkpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9uYW1lc3BhY2UvUU5hbWUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvbmFtZXNwYWNlL1FOYW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjc0OGI2NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvbmFtZXNwYWNlL1FOYW1lLmphdmEKQEAgLTAsMCArMSw0ODYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLyAkSWQ6IFFOYW1lLmphdmEgNzU0NTgxIDIwMDktMDMtMTUgMDE6MzI6MzlaIG1yZ2xhdmFzICQKKworcGFja2FnZSBqYXZheC54bWwubmFtZXNwYWNlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb247CitpbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKKworLyoqCisgKiA8cD48Y29kZT5RTmFtZTwvY29kZT4gcmVwcmVzZW50cyBhIDxzdHJvbmc+cXVhbGlmaWVkIG5hbWU8L3N0cm9uZz4KKyAqIGFzIGRlZmluZWQgaW4gdGhlIFhNTCBzcGVjaWZpY2F0aW9uczogPGEKKyAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNRTmFtZSI+WE1MIFNjaGVtYSBQYXJ0MjoKKyAqIERhdGF0eXBlcyBzcGVjaWZpY2F0aW9uPC9hPiwgPGEKKyAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI25zLXF1YWxuYW1lcyI+TmFtZXNwYWNlcworICogaW4gWE1MPC9hPiwgPGEKKyAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1hNTC94bWwtbmFtZXMtMTk5OTAxMTQtZXJyYXRhIj5OYW1lc3BhY2VzCisgKiBpbiBYTUwgRXJyYXRhPC9hPi48L3A+CisgKgorICogPHA+VGhlIHZhbHVlIG9mIGEgPGNvZGU+UU5hbWU8L2NvZGU+IGNvbnRhaW5zIGEgPHN0cm9uZz5OYW1lc3BhY2UKKyAqIFVSSTwvc3Ryb25nPiwgPHN0cm9uZz5sb2NhbCBwYXJ0PC9zdHJvbmc+IGFuZAorICogPHN0cm9uZz5wcmVmaXg8L3N0cm9uZz4uPC9wPgorICoKKyAqIDxwPlRoZSBwcmVmaXggaXMgaW5jbHVkZWQgaW4gPGNvZGU+UU5hbWU8L2NvZGU+IHRvIHJldGFpbiBsZXhpY2FsCisgKiBpbmZvcm1hdGlvbiA8c3Ryb25nPjxlbT53aGVuIHByZXNlbnQ8L2VtPjwvc3Ryb25nPiBpbiBhbiB7QGxpbmsKKyAqIGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlIFhNTCBpbnB1dCBzb3VyY2V9LiBUaGUgcHJlZml4IGlzCisgKiA8c3Ryb25nPjxlbT5OT1Q8L2VtPjwvc3Ryb25nPiB1c2VkIGluIHtAbGluayAjZXF1YWxzKE9iamVjdCkKKyAqIFFOYW1lLmVxdWFscyhPYmplY3QpfSBvciB0byBjb21wdXRlIHRoZSB7QGxpbmsgI2hhc2hDb2RlKCkKKyAqIFFOYW1lLmhhc2hDb2RlKCl9LiAgRXF1YWxpdHkgYW5kIHRoZSBoYXNoIGNvZGUgYXJlIGRlZmluZWQgdXNpbmcKKyAqIDxzdHJvbmc+PGVtPm9ubHk8L2VtPjwvc3Ryb25nPiB0aGUgTmFtZXNwYWNlIFVSSSBhbmQgbG9jYWwgcGFydC48L3A+CisgKgorICogPHA+SWYgbm90IHNwZWNpZmllZCwgdGhlIE5hbWVzcGFjZSBVUkkgaXMgc2V0IHRvIHtAbGluaworICogamF2YXgueG1sLlhNTENvbnN0YW50cyNOVUxMX05TX1VSSSBYTUxDb25zdGFudHMuTlVMTF9OU19VUkl9LgorICogSWYgbm90IHNwZWNpZmllZCwgdGhlIHByZWZpeCBpcyBzZXQgdG8ge0BsaW5rCisgKiBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0RFRkFVTFRfTlNfUFJFRklYCisgKiBYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVh9LjwvcD4KKyAqCisgKiA8cD48Y29kZT5RTmFtZTwvY29kZT4gaXMgaW1tdXRhYmxlLjwvcD4KKyAqCisgKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogNzU0NTgxICQsICREYXRlOiAyMDA5LTAzLTE0IDE4OjMyOjM5IC0wNzAwIChTYXQsIDE0IE1hciAyMDA5KSAkCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNRTmFtZSI+WE1MIFNjaGVtYSBQYXJ0MjogRGF0YXR5cGVzIHNwZWNpZmljYXRpb248L2E+CisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI25zLXF1YWxuYW1lcyI+TmFtZXNwYWNlcyBpbiBYTUw8L2E+CisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1hNTC94bWwtbmFtZXMtMTk5OTAxMTQtZXJyYXRhIj5OYW1lc3BhY2VzIGluIFhNTCBFcnJhdGE8L2E+CisgKiBAc2luY2UgMS41CisgKi8KKworcHVibGljIGNsYXNzIFFOYW1lIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIC8qKgorICAgICAqIDxwPlN0cmVhbSBVbmlxdWUgSWRlbnRpZmllci48L3A+CisgICAgICoKKyAgICAgKiA8cD5UbyBlbmFibGUgdGhlIGNvbXBhdGliaWxpdHkgPGNvZGU+c2VyaWFsVmVyc2lvblVJRDwvY29kZT4KKyAgICAgKiBzZXQgdGhlIFN5c3RlbSBQcm9wZXJ0eQorICAgICAqIDxjb2RlPm9yZy5hcGFjaGUueG1sLm5hbWVzcGFjZS5RTmFtZS51c2VDb21wYXRpYmxlU2VyaWFsVmVyc2lvblVJRDwvY29kZT4KKyAgICAgKiB0byBhIHZhbHVlIG9mICIxLjAiLjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQ7CisKKyAgICAvKioKKyAgICAgKiA8cD5UaGUgb3JpZ2luYWwgZGVmYXVsdCBTdHJlYW0gVW5pcXVlIElkZW50aWZpZXIuPC9wPgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgZGVmYXVsdFNlcmlhbFZlcnNpb25VSUQgPSAtOTEyMDQ0ODc1NDg5NjYwOTk0MEw7CisKKyAgICAvKioKKyAgICAgKiA8cD5UaGUgY29tcGF0aWJpbGl0eSBTdHJlYW0gVW5pcXVlIElkZW50aWZpZXIgdGhhdCB3YXMgaW50cm9kdWNlZAorICAgICAqIHdpdGggSmF2YSA1IFNFIFNESy48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBjb21wYXRpYmlsaXR5U2VyaWFsVmVyc2lvblVJRCA9IDQ0MTg2MjI5ODEwMjY1NDUxNTFMOworCisgICAgc3RhdGljIHsKKyAgICAgICAgU3RyaW5nIGNvbXBhdFByb3BWYWx1ZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgib3JnLmFwYWNoZS54bWwubmFtZXNwYWNlLlFOYW1lLnVzZUNvbXBhdGlibGVTZXJpYWxWZXJzaW9uVUlEIik7CisgICAgICAgIC8vIElmIDEuMCB1c2UgY29tcGF0aWJpbGl0eSBzZXJpYWxWZXJzaW9uVUlECisgICAgICAgIHNlcmlhbFZlcnNpb25VSUQgPSAhIjEuMCIuZXF1YWxzKGNvbXBhdFByb3BWYWx1ZSkgPyBkZWZhdWx0U2VyaWFsVmVyc2lvblVJRCA6IGNvbXBhdGliaWxpdHlTZXJpYWxWZXJzaW9uVUlEOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPk5hbWVzcGFjZSBVUkkgb2YgdGhpcyA8Y29kZT5RTmFtZTwvY29kZT4uPC9wPgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG5hbWVzcGFjZVVSSTsKKworICAgIC8qKgorICAgICAqIDxwPmxvY2FsIHBhcnQgb2YgdGhpcyA8Y29kZT5RTmFtZTwvY29kZT4uPC9wPgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGxvY2FsUGFydDsKKworICAgIC8qKgorICAgICAqIDxwPnByZWZpeCBvZiB0aGlzIDxjb2RlPlFOYW1lPC9jb2RlPi48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgcHJlZml4OworCisgICAgLyoqCisgICAgICogPHA+PGNvZGU+U3RyaW5nPC9jb2RlPiByZXByZXNlbnRhdGlvbiBvZiB0aGlzIDxjb2RlPlFOYW1lPC9jb2RlPi48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgU3RyaW5nIHFOYW1lQXNTdHJpbmc7CisKKyAgICAvKioKKyAgICAgKiA8cD48Y29kZT5RTmFtZTwvY29kZT4gY29uc3RydWN0b3Igc3BlY2lmeWluZyB0aGUgTmFtZXNwYWNlIFVSSQorICAgICAqIGFuZCBsb2NhbCBwYXJ0LjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBOYW1lc3BhY2UgVVJJIGlzIDxjb2RlPm51bGw8L2NvZGU+LCBpdCBpcyBzZXQgdG8KKyAgICAgKiB7QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNOVUxMX05TX1VSSQorICAgICAqIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSX0uICBUaGlzIHZhbHVlIHJlcHJlc2VudHMgbm8KKyAgICAgKiBleHBsaWNpdGx5IGRlZmluZWQgTmFtZXNwYWNlIGFzIGRlZmluZWQgYnkgdGhlIDxhCisgICAgICogaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8jbnMtcXVhbG5hbWVzIj5OYW1lc3BhY2VzCisgICAgICogaW4gWE1MPC9hPiBzcGVjaWZpY2F0aW9uLiAgVGhpcyBhY3Rpb24gcHJlc2VydmVzIGNvbXBhdGlibGUKKyAgICAgKiBiZWhhdmlvciB3aXRoIFFOYW1lIDEuMC4gIEV4cGxpY2l0bHkgcHJvdmlkaW5nIHRoZSB7QGxpbmsKKyAgICAgKiBqYXZheC54bWwuWE1MQ29uc3RhbnRzI05VTExfTlNfVVJJCisgICAgICogWE1MQ29uc3RhbnRzLk5VTExfTlNfVVJJfSB2YWx1ZSBpcyB0aGUgcHJlZmVycmVkIGNvZGluZworICAgICAqIHN0eWxlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBsb2NhbCBwYXJ0IGlzIDxjb2RlPm51bGw8L2NvZGU+IGFuCisgICAgICogPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uCisgICAgICogQSBsb2NhbCBwYXJ0IG9mICIiIGlzIGFsbG93ZWQgdG8gcHJlc2VydmUKKyAgICAgKiBjb21wYXRpYmxlIGJlaGF2aW9yIHdpdGggUU5hbWUgMS4wLiA8L3A+CisgICAgICoKKyAgICAgKiA8cD5XaGVuIHVzaW5nIHRoaXMgY29uc3RydWN0b3IsIHRoZSBwcmVmaXggaXMgc2V0IHRvIHtAbGluaworICAgICAqIGphdmF4LnhtbC5YTUxDb25zdGFudHMjREVGQVVMVF9OU19QUkVGSVgKKyAgICAgKiBYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVh9LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBOYW1lc3BhY2UgVVJJIGlzIG5vdCB2YWxpZGF0ZWQgYXMgYQorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Ij5VUkkgcmVmZXJlbmNlPC9hPi4KKyAgICAgKiBUaGUgbG9jYWwgcGFydCBpcyBub3QgdmFsaWRhdGVkIGFzIGEKKyAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyNOVC1OQ05hbWUiPk5DTmFtZTwvYT4KKyAgICAgKiBhcyBzcGVjaWZpZWQgaW4gPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8iPk5hbWVzcGFjZXMKKyAgICAgKiBpbiBYTUw8L2E+LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgTmFtZXNwYWNlIFVSSSBvZiB0aGUgPGNvZGU+UU5hbWU8L2NvZGU+CisgICAgICogQHBhcmFtIGxvY2FsUGFydCAgICBsb2NhbCBwYXJ0IG9mIHRoZSA8Y29kZT5RTmFtZTwvY29kZT4KKyAgICAgKgorICAgICAqIEBzZWUgI1FOYW1lKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbFBhcnQsIFN0cmluZworICAgICAqIHByZWZpeCkgUU5hbWUoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsUGFydCwgU3RyaW5nCisgICAgICogcHJlZml4KQorICAgICAqLworICAgIHB1YmxpYyBRTmFtZShmaW5hbCBTdHJpbmcgbmFtZXNwYWNlVVJJLCBmaW5hbCBTdHJpbmcgbG9jYWxQYXJ0KSB7CisgICAgICAgIHRoaXMobmFtZXNwYWNlVVJJLCBsb2NhbFBhcnQsIFhNTENvbnN0YW50cy5ERUZBVUxUX05TX1BSRUZJWCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+PGNvZGU+UU5hbWU8L2NvZGU+IGNvbnN0cnVjdG9yIHNwZWNpZnlpbmcgdGhlIE5hbWVzcGFjZSBVUkksCisgICAgICogbG9jYWwgcGFydCBhbmQgcHJlZml4LjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBOYW1lc3BhY2UgVVJJIGlzIDxjb2RlPm51bGw8L2NvZGU+LCBpdCBpcyBzZXQgdG8KKyAgICAgKiB7QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNOVUxMX05TX1VSSQorICAgICAqIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSX0uICBUaGlzIHZhbHVlIHJlcHJlc2VudHMgbm8KKyAgICAgKiBleHBsaWNpdGx5IGRlZmluZWQgTmFtZXNwYWNlIGFzIGRlZmluZWQgYnkgdGhlIDxhCisgICAgICogaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8jbnMtcXVhbG5hbWVzIj5OYW1lc3BhY2VzCisgICAgICogaW4gWE1MPC9hPiBzcGVjaWZpY2F0aW9uLiAgVGhpcyBhY3Rpb24gcHJlc2VydmVzIGNvbXBhdGlibGUKKyAgICAgKiBiZWhhdmlvciB3aXRoIFFOYW1lIDEuMC4gIEV4cGxpY2l0bHkgcHJvdmlkaW5nIHRoZSB7QGxpbmsKKyAgICAgKiBqYXZheC54bWwuWE1MQ29uc3RhbnRzI05VTExfTlNfVVJJCisgICAgICogWE1MQ29uc3RhbnRzLk5VTExfTlNfVVJJfSB2YWx1ZSBpcyB0aGUgcHJlZmVycmVkIGNvZGluZworICAgICAqIHN0eWxlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBsb2NhbCBwYXJ0IGlzIDxjb2RlPm51bGw8L2NvZGU+IGFuCisgICAgICogPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uCisgICAgICogQSBsb2NhbCBwYXJ0IG9mICIiIGlzIGFsbG93ZWQgdG8gcHJlc2VydmUKKyAgICAgKiBjb21wYXRpYmxlIGJlaGF2aW9yIHdpdGggUU5hbWUgMS4wLiA8L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgcHJlZml4IGlzIDxjb2RlPm51bGw8L2NvZGU+LCBhbgorICAgICAqIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLiAgVXNlIHtAbGluaworICAgICAqIGphdmF4LnhtbC5YTUxDb25zdGFudHMjREVGQVVMVF9OU19QUkVGSVgKKyAgICAgKiBYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVh9IHRvIGV4cGxpY2l0bHkgaW5kaWNhdGUgdGhhdCBubworICAgICAqIHByZWZpeCBpcyBwcmVzZW50IG9yIHRoZSBwcmVmaXggaXMgbm90IHJlbGV2YW50LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBOYW1lc3BhY2UgVVJJIGlzIG5vdCB2YWxpZGF0ZWQgYXMgYQorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Ij5VUkkgcmVmZXJlbmNlPC9hPi4KKyAgICAgKiBUaGUgbG9jYWwgcGFydCBhbmQgcHJlZml4IGFyZSBub3QgdmFsaWRhdGVkIGFzIGEKKyAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyNOVC1OQ05hbWUiPk5DTmFtZTwvYT4KKyAgICAgKiBhcyBzcGVjaWZpZWQgaW4gPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8iPk5hbWVzcGFjZXMKKyAgICAgKiBpbiBYTUw8L2E+LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgTmFtZXNwYWNlIFVSSSBvZiB0aGUgPGNvZGU+UU5hbWU8L2NvZGU+CisgICAgICogQHBhcmFtIGxvY2FsUGFydCAgICBsb2NhbCBwYXJ0IG9mIHRoZSA8Y29kZT5RTmFtZTwvY29kZT4KKyAgICAgKiBAcGFyYW0gcHJlZml4ICAgICAgIHByZWZpeCBvZiB0aGUgPGNvZGU+UU5hbWU8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIFFOYW1lKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbFBhcnQsIFN0cmluZyBwcmVmaXgpIHsKKworICAgICAgICAvLyBtYXAgbnVsbCBOYW1lc3BhY2UgVVJJIHRvIGRlZmF1bHQgdG8gcHJlc2VydmUgY29tcGF0aWJpbGl0eSB3aXRoIFFOYW1lIDEuMAorICAgICAgICBpZiAobmFtZXNwYWNlVVJJID09IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMubmFtZXNwYWNlVVJJID0gWE1MQ29uc3RhbnRzLk5VTExfTlNfVVJJOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhpcy5uYW1lc3BhY2VVUkkgPSBuYW1lc3BhY2VVUkk7CisgICAgICAgIH0KKworICAgICAgICAvLyBsb2NhbCBwYXJ0IGlzIHJlcXVpcmVkLiAgIiIgaXMgYWxsb3dlZCB0byBwcmVzZXJ2ZSBjb21wYXRpYmlsaXR5IHdpdGggUU5hbWUgMS4wCisgICAgICAgIGlmIChsb2NhbFBhcnQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibG9jYWwgcGFydCBjYW5ub3QgYmUgXCJudWxsXCIgd2hlbiBjcmVhdGluZyBhIFFOYW1lIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5sb2NhbFBhcnQgPSBsb2NhbFBhcnQ7CisKKyAgICAgICAgLy8gcHJlZml4IGlzIHJlcXVpcmVkCisgICAgICAgIGlmIChwcmVmaXggPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicHJlZml4IGNhbm5vdCBiZSBcIm51bGxcIiB3aGVuIGNyZWF0aW5nIGEgUU5hbWUiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnByZWZpeCA9IHByZWZpeDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD48Y29kZT5RTmFtZTwvY29kZT4gY29uc3RydWN0b3Igc3BlY2lmeWluZyB0aGUgbG9jYWwgcGFydC48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgbG9jYWwgcGFydCBpcyA8Y29kZT5udWxsPC9jb2RlPiBhbgorICAgICAqIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLgorICAgICAqIEEgbG9jYWwgcGFydCBvZiAiIiBpcyBhbGxvd2VkIHRvIHByZXNlcnZlCisgICAgICogY29tcGF0aWJsZSBiZWhhdmlvciB3aXRoIFFOYW1lIDEuMC4gPC9wPgorICAgICAqCisgICAgICogPHA+V2hlbiB1c2luZyB0aGlzIGNvbnN0cnVjdG9yLCB0aGUgTmFtZXNwYWNlIFVSSSBpcyBzZXQgdG8KKyAgICAgKiB7QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNOVUxMX05TX1VSSQorICAgICAqIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSX0gYW5kIHRoZSBwcmVmaXggaXMgc2V0IHRvIHtAbGluaworICAgICAqIGphdmF4LnhtbC5YTUxDb25zdGFudHMjREVGQVVMVF9OU19QUkVGSVgKKyAgICAgKiBYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVh9LjwvcD4KKyAgICAgKgorICAgICAqIDxwPjxlbT5JbiBhbiBYTUwgY29udGV4dCwgYWxsIEVsZW1lbnQgYW5kIEF0dHJpYnV0ZSBuYW1lcyBleGlzdAorICAgICAqIGluIHRoZSBjb250ZXh0IG9mIGEgTmFtZXNwYWNlLiAgTWFraW5nIHRoaXMgZXhwbGljaXQgZHVyaW5nIHRoZQorICAgICAqIGNvbnN0cnVjdGlvbiBvZiBhIDxjb2RlPlFOYW1lPC9jb2RlPiBoZWxwcyBwcmV2ZW50IGhhcmQgdG8KKyAgICAgKiBkaWFnbm9zaXMgWE1MIHZhbGlkaXR5IGVycm9ycy4gIFRoZSBjb25zdHJ1Y3RvcnMge0BsaW5rCisgICAgICogI1FOYW1lKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbFBhcnQpIFFOYW1lKFN0cmluZworICAgICAqIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsUGFydCl9IGFuZAorICAgICAqIHtAbGluayAjUU5hbWUoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsUGFydCwgU3RyaW5nIHByZWZpeCl9CisgICAgICogYXJlIHByZWZlcnJlZC48L2VtPjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBsb2NhbCBwYXJ0IGlzIG5vdCB2YWxpZGF0ZWQgYXMgYQorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI05ULU5DTmFtZSI+TkNOYW1lPC9hPgorICAgICAqIGFzIHNwZWNpZmllZCBpbiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyI+TmFtZXNwYWNlcworICAgICAqIGluIFhNTDwvYT4uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2FsUGFydCBsb2NhbCBwYXJ0IG9mIHRoZSA8Y29kZT5RTmFtZTwvY29kZT4KKyAgICAgKiBAc2VlICNRTmFtZShTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxQYXJ0KSBRTmFtZShTdHJpbmcKKyAgICAgKiBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbFBhcnQpCisgICAgICogQHNlZSAjUU5hbWUoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsUGFydCwgU3RyaW5nCisgICAgICogcHJlZml4KSBRTmFtZShTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxQYXJ0LCBTdHJpbmcKKyAgICAgKiBwcmVmaXgpCisgICAgICovCisgICAgcHVibGljIFFOYW1lKFN0cmluZyBsb2NhbFBhcnQpIHsKKyAgICAgICAgdGhpcygKKyAgICAgICAgICAgIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSSwKKyAgICAgICAgICAgIGxvY2FsUGFydCwKKyAgICAgICAgICAgIFhNTENvbnN0YW50cy5ERUZBVUxUX05TX1BSRUZJWCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+R2V0IHRoZSBOYW1lc3BhY2UgVVJJIG9mIHRoaXMgPGNvZGU+UU5hbWU8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gTmFtZXNwYWNlIFVSSSBvZiB0aGlzIDxjb2RlPlFOYW1lPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKCkgeworICAgICAgICByZXR1cm4gbmFtZXNwYWNlVVJJOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkdldCB0aGUgbG9jYWwgcGFydCBvZiB0aGlzIDxjb2RlPlFOYW1lPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiAgQHJldHVybiBsb2NhbCBwYXJ0IG9mIHRoaXMgPGNvZGU+UU5hbWU8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRMb2NhbFBhcnQoKSB7CisgICAgICAgIHJldHVybiBsb2NhbFBhcnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+R2V0IHRoZSBwcmVmaXggb2YgdGhpcyA8Y29kZT5RTmFtZTwvY29kZT4uPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIHByZWZpeCBhc3NpZ25lZCB0byBhIDxjb2RlPlFOYW1lPC9jb2RlPiBtaWdodAorICAgICAqIDxzdHJvbmc+PGVtPk5PVDwvZW0+PC9zdHJvbmc+IGJlIHZhbGlkIGluIGEgZGlmZmVyZW50CisgICAgICogY29udGV4dC4gRm9yIGV4YW1wbGUsIGEgPGNvZGU+UU5hbWU8L2NvZGU+IG1heSBiZSBhc3NpZ25lZCBhCisgICAgICogcHJlZml4IGluIHRoZSBjb250ZXh0IG9mIHBhcnNpbmcgYSBkb2N1bWVudCBidXQgdGhhdCBwcmVmaXggbWF5CisgICAgICogYmUgaW52YWxpZCBpbiB0aGUgY29udGV4dCBvZiBhIGRpZmZlcmVudCBkb2N1bWVudC48L3A+CisgICAgICoKKyAgICAgKiAgQHJldHVybiBwcmVmaXggb2YgdGhpcyA8Y29kZT5RTmFtZTwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeCgpIHsKKyAgICAgICAgcmV0dXJuIHByZWZpeDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5UZXN0IHRoaXMgPGNvZGU+UU5hbWU8L2NvZGU+IGZvciBlcXVhbGl0eSB3aXRoIGFub3RoZXIKKyAgICAgKiA8Y29kZT5PYmplY3Q8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSA8Y29kZT5PYmplY3Q8L2NvZGU+IHRvIGJlIHRlc3RlZCBpcyBub3QgYQorICAgICAqIDxjb2RlPlFOYW1lPC9jb2RlPiBvciBpcyA8Y29kZT5udWxsPC9jb2RlPiwgdGhlbiB0aGlzIG1ldGhvZAorICAgICAqIHJldHVybnMgPGNvZGU+ZmFsc2U8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlR3byA8Y29kZT5RTmFtZTwvY29kZT5zIGFyZSBjb25zaWRlcmVkIGVxdWFsIGlmIGFuZCBvbmx5IGlmCisgICAgICogYm90aCB0aGUgTmFtZXNwYWNlIFVSSSBhbmQgbG9jYWwgcGFydCBhcmUgZXF1YWwuIFRoaXMgbWV0aG9kCisgICAgICogdXNlcyA8Y29kZT5TdHJpbmcuZXF1YWxzKCk8L2NvZGU+IHRvIGNoZWNrIGVxdWFsaXR5IG9mIHRoZQorICAgICAqIE5hbWVzcGFjZSBVUkkgYW5kIGxvY2FsIHBhcnQuIFRoZSBwcmVmaXggaXMKKyAgICAgKiA8c3Ryb25nPjxlbT5OT1Q8L2VtPjwvc3Ryb25nPiB1c2VkIHRvIGRldGVybWluZSBlcXVhbGl0eS48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBzYXRpc2ZpZXMgdGhlIGdlbmVyYWwgY29udHJhY3Qgb2Yge0BsaW5rCisgICAgICogamF2YS5sYW5nLk9iamVjdCNlcXVhbHMoT2JqZWN0KSBPYmplY3QuZXF1YWxzKE9iamVjdCl9PC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdFRvVGVzdCB0aGUgPGNvZGU+T2JqZWN0PC9jb2RlPiB0byB0ZXN0IGZvcgorICAgICAqIGVxdWFsaXR5IHdpdGggdGhpcyA8Y29kZT5RTmFtZTwvY29kZT4KKyAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBnaXZlbiA8Y29kZT5PYmplY3Q8L2NvZGU+IGlzCisgICAgICogZXF1YWwgdG8gdGhpcyA8Y29kZT5RTmFtZTwvY29kZT4gZWxzZSA8Y29kZT5mYWxzZTwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdFRvVGVzdCkgeworICAgICAgICAvLyBJcyB0aGlzIHRoZSBzYW1lIG9iamVjdD8KKyAgICAgICAgaWYgKG9iamVjdFRvVGVzdCA9PSB0aGlzKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICAvLyBJcyB0aGlzIGEgUU5hbWU/CisgICAgICAgIGlmIChvYmplY3RUb1Rlc3QgaW5zdGFuY2VvZiBRTmFtZSkgeworICAgICAgICAgICAgUU5hbWUgcU5hbWUgPSAoUU5hbWUpIG9iamVjdFRvVGVzdDsKKyAgICAgICAgICAgIHJldHVybiBsb2NhbFBhcnQuZXF1YWxzKHFOYW1lLmxvY2FsUGFydCkgJiYgbmFtZXNwYWNlVVJJLmVxdWFscyhxTmFtZS5uYW1lc3BhY2VVUkkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5HZW5lcmF0ZSB0aGUgaGFzaCBjb2RlIGZvciB0aGlzIDxjb2RlPlFOYW1lPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgaGFzaCBjb2RlIGlzIGNhbGN1bGF0ZWQgdXNpbmcgYm90aCB0aGUgTmFtZXNwYWNlIFVSSSBhbmQKKyAgICAgKiB0aGUgbG9jYWwgcGFydCBvZiB0aGUgPGNvZGU+UU5hbWU8L2NvZGU+LiAgVGhlIHByZWZpeCBpcworICAgICAqIDxzdHJvbmc+PGVtPk5PVDwvZW0+PC9zdHJvbmc+IHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBoYXNoCisgICAgICogY29kZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBzYXRpc2ZpZXMgdGhlIGdlbmVyYWwgY29udHJhY3Qgb2Yge0BsaW5rCisgICAgICogamF2YS5sYW5nLk9iamVjdCNoYXNoQ29kZSgpIE9iamVjdC5oYXNoQ29kZSgpfS48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIGhhc2ggY29kZSBmb3IgdGhpcyA8Y29kZT5RTmFtZTwvY29kZT4gPGNvZGU+T2JqZWN0PC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiBuYW1lc3BhY2VVUkkuaGFzaENvZGUoKSBeIGxvY2FsUGFydC5oYXNoQ29kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPjxjb2RlPlN0cmluZzwvY29kZT4gcmVwcmVzZW50YXRpb24gb2YgdGhpcworICAgICAqIDxjb2RlPlFOYW1lPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgY29tbW9ubHkgYWNjZXB0ZWQgd2F5IG9mIHJlcHJlc2VudGluZyBhIDxjb2RlPlFOYW1lPC9jb2RlPgorICAgICAqIGFzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiB3YXMgPGEgaHJlZj0iaHR0cDovL2pjbGFyay5jb20veG1sL3htbG5zLmh0bSI+ZGVmaW5lZDwvYT4KKyAgICAgKiBieSBKYW1lcyBDbGFyay4gIEFsdGhvdWdoIHRoaXMgaXMgbm90IGEgPGVtPnN0YW5kYXJkPC9lbT4KKyAgICAgKiBzcGVjaWZpY2F0aW9uLCBpdCBpcyBpbiBjb21tb24gdXNlLCAgZS5nLiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lciNzZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSl9LgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gcmVwcmVzZW50cyBhIDxjb2RlPlFOYW1lPC9jb2RlPiBhczoKKyAgICAgKiAieyIgKyBOYW1lc3BhY2UgVVJJICsgIn0iICsgbG9jYWwgcGFydC4gIElmIHRoZSBOYW1lc3BhY2UgVVJJCisgICAgICogPGNvZGU+LmVxdWFscyhYTUxDb25zdGFudHMuTlVMTF9OU19VUkkpPC9jb2RlPiwgb25seSB0aGUKKyAgICAgKiBsb2NhbCBwYXJ0IGlzIHJldHVybmVkLiAgQW4gYXBwcm9wcmlhdGUgdXNlIG9mIHRoaXMgbWV0aG9kIGlzCisgICAgICogZm9yIGRlYnVnZ2luZyBvciBsb2dnaW5nIGZvciBodW1hbiBjb25zdW1wdGlvbi48L3A+CisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoZSBwcmVmaXggdmFsdWUgaXMgPHN0cm9uZz48ZW0+Tk9UPC9lbT48L3N0cm9uZz4KKyAgICAgKiByZXR1cm5lZCBhcyBwYXJ0IG9mIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIHNhdGlzZmllcyB0aGUgZ2VuZXJhbCBjb250cmFjdCBvZiB7QGxpbmsKKyAgICAgKiBqYXZhLmxhbmcuT2JqZWN0I3RvU3RyaW5nKCkgT2JqZWN0LnRvU3RyaW5nKCl9LjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gPGNvZGU+U3RyaW5nPC9jb2RlPiByZXByZXNlbnRhdGlvbiBvZiB0aGlzIDxjb2RlPlFOYW1lPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZyBfcU5hbWVBc1N0cmluZyA9IHFOYW1lQXNTdHJpbmc7CisgICAgICAgIGlmIChfcU5hbWVBc1N0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgbnNMZW5ndGggPSBuYW1lc3BhY2VVUkkubGVuZ3RoKCk7CisgICAgICAgICAgICBpZiAobnNMZW5ndGggPT0gMCkgeworICAgICAgICAgICAgICAgIF9xTmFtZUFzU3RyaW5nID0gbG9jYWxQYXJ0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVpbGRlcihuc0xlbmd0aCArIGxvY2FsUGFydC5sZW5ndGgoKSArIDIpOworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJ3snKTsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKG5hbWVzcGFjZVVSSSk7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnfScpOworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQobG9jYWxQYXJ0KTsKKyAgICAgICAgICAgICAgICBfcU5hbWVBc1N0cmluZyA9IGJ1ZmZlci50b1N0cmluZygpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcU5hbWVBc1N0cmluZyA9IF9xTmFtZUFzU3RyaW5nOworICAgICAgICB9CisgICAgICAgIHJldHVybiBfcU5hbWVBc1N0cmluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD48Y29kZT5RTmFtZTwvY29kZT4gZGVyaXZlZCBmcm9tIHBhcnNpbmcgdGhlIGZvcm1hdHRlZAorICAgICAqIDxjb2RlPlN0cmluZzwvY29kZT4uPC9wPgorICAgICAqCisgICAgICogPHA+SWYgdGhlIDxjb2RlPlN0cmluZzwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4gb3IgZG9lcyBub3QgY29uZm9ybSB0bworICAgICAqIHtAbGluayAjdG9TdHJpbmcoKSBRTmFtZS50b1N0cmluZygpfSBmb3JtYXR0aW5nLCBhbgorICAgICAqIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KKyAgICAgKgorICAgICAqIDxwPjxlbT5UaGUgPGNvZGU+U3RyaW5nPC9jb2RlPiA8c3Ryb25nPk1VU1Q8L3N0cm9uZz4gYmUgaW4gdGhlCisgICAgICogZm9ybSByZXR1cm5lZCBieSB7QGxpbmsgI3RvU3RyaW5nKCkgUU5hbWUudG9TdHJpbmcoKX0uPC9lbT48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgY29tbW9ubHkgYWNjZXB0ZWQgd2F5IG9mIHJlcHJlc2VudGluZyBhIDxjb2RlPlFOYW1lPC9jb2RlPgorICAgICAqIGFzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiB3YXMgPGEgaHJlZj0iaHR0cDovL2pjbGFyay5jb20veG1sL3htbG5zLmh0bSI+ZGVmaW5lZDwvYT4KKyAgICAgKiBieSBKYW1lcyBDbGFyay4gIEFsdGhvdWdoIHRoaXMgaXMgbm90IGEgPGVtPnN0YW5kYXJkPC9lbT4KKyAgICAgKiBzcGVjaWZpY2F0aW9uLCBpdCBpcyBpbiBjb21tb24gdXNlLCAgZS5nLiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lciNzZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSl9LgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gcGFyc2VzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiBmb3JtYXR0ZWQKKyAgICAgKiBhczogInsiICsgTmFtZXNwYWNlIFVSSSArICJ9IiArIGxvY2FsIHBhcnQuICBJZiB0aGUgTmFtZXNwYWNlCisgICAgICogVVJJIDxjb2RlPi5lcXVhbHMoWE1MQ29uc3RhbnRzLk5VTExfTlNfVVJJKTwvY29kZT4sIG9ubHkgdGhlCisgICAgICogbG9jYWwgcGFydCBzaG91bGQgYmUgcHJvdmlkZWQuPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIHByZWZpeCB2YWx1ZSA8c3Ryb25nPjxlbT5DQU5OT1Q8L2VtPjwvc3Ryb25nPiBiZQorICAgICAqIHJlcHJlc2VudGVkIGluIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IGFuZCB3aWxsIGJlIHNldCB0bworICAgICAqIHtAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0RFRkFVTFRfTlNfUFJFRklYCisgICAgICogWE1MQ29uc3RhbnRzLkRFRkFVTFRfTlNfUFJFRklYfS48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBkb2VzIG5vdCBkbyBmdWxsIHZhbGlkYXRpb24gb2YgdGhlIHJlc3VsdGluZworICAgICAqIDxjb2RlPlFOYW1lPC9jb2RlPi4KKyAgICAgKiA8cD5UaGUgTmFtZXNwYWNlIFVSSSBpcyBub3QgdmFsaWRhdGVkIGFzIGEKKyAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dCI+VVJJIHJlZmVyZW5jZTwvYT4uCisgICAgICogVGhlIGxvY2FsIHBhcnQgaXMgbm90IHZhbGlkYXRlZCBhcyBhCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8jTlQtTkNOYW1lIj5OQ05hbWU8L2E+CisgICAgICogYXMgc3BlY2lmaWVkIGluCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8iPk5hbWVzcGFjZXMgaW4gWE1MPC9hPi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcU5hbWVBc1N0cmluZyA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uCisgICAgICogb2YgdGhlIDxjb2RlPlFOYW1lPC9jb2RlPgorICAgICAqIEByZXR1cm4gPGNvZGU+UU5hbWU8L2NvZGU+IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIDxjb2RlPlN0cmluZzwvY29kZT4KKyAgICAgKiBAc2VlICN0b1N0cmluZygpIFFOYW1lLnRvU3RyaW5nKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFFOYW1lIHZhbHVlT2YoU3RyaW5nIHFOYW1lQXNTdHJpbmcpIHsKKworICAgICAgICAvLyBudWxsIGlzIG5vdCB2YWxpZAorICAgICAgICBpZiAocU5hbWVBc1N0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJjYW5ub3QgY3JlYXRlIFFOYW1lIGZyb20gXCJudWxsXCIgb3IgXCJcIiBTdHJpbmciKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vICIiIGxvY2FsIHBhcnQgaXMgdmFsaWQgdG8gcHJlc2VydmUgY29tcGF0aWJsZSBiZWhhdmlvciB3aXRoIFFOYW1lIDEuMAorICAgICAgICBpZiAocU5hbWVBc1N0cmluZy5sZW5ndGgoKSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFFOYW1lKAorICAgICAgICAgICAgICAgIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSSwKKyAgICAgICAgICAgICAgICBxTmFtZUFzU3RyaW5nLAorICAgICAgICAgICAgICAgIFhNTENvbnN0YW50cy5ERUZBVUxUX05TX1BSRUZJWCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBsb2NhbCBwYXJ0IG9ubHk/CisgICAgICAgIGlmIChxTmFtZUFzU3RyaW5nLmNoYXJBdCgwKSAhPSAneycpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUU5hbWUoCisgICAgICAgICAgICAgICAgWE1MQ29uc3RhbnRzLk5VTExfTlNfVVJJLAorICAgICAgICAgICAgICAgIHFOYW1lQXNTdHJpbmcsCisgICAgICAgICAgICAgICAgWE1MQ29uc3RhbnRzLkRFRkFVTFRfTlNfUFJFRklYKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIE5hbWVzcGFjZSBVUkkgaW1wcm9wZXJseSBzcGVjaWZpZWQ/CisgICAgICAgIGlmIChxTmFtZUFzU3RyaW5nLnN0YXJ0c1dpdGgoInsiICsgWE1MQ29uc3RhbnRzLk5VTExfTlNfVVJJICsgIn0iKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiTmFtZXNwYWNlIFVSSSAuZXF1YWxzKFhNTENvbnN0YW50cy5OVUxMX05TX1VSSSksICIKKyAgICAgICAgICAgICAgICArICIuZXF1YWxzKFwiIiArIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSSArICJcIiksICIKKyAgICAgICAgICAgICAgICArICJvbmx5IHRoZSBsb2NhbCBwYXJ0LCAiCisgICAgICAgICAgICAgICAgKyAiXCIiICsgcU5hbWVBc1N0cmluZy5zdWJzdHJpbmcoMiArIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSS5sZW5ndGgoKSkgKyAiXCIsICIKKyAgICAgICAgICAgICAgICArICJzaG91bGQgYmUgcHJvdmlkZWQuIik7CisgICAgICAgIH0KKworICAgICAgICAvLyBOYW1lc3BhY2UgVVJJIGFuZCBsb2NhbCBwYXJ0IHNwZWNpZmllZAorICAgICAgICBpbnQgZW5kT2ZOYW1lc3BhY2VVUkkgPSBxTmFtZUFzU3RyaW5nLmluZGV4T2YoJ30nKTsKKyAgICAgICAgaWYgKGVuZE9mTmFtZXNwYWNlVVJJID09IC0xKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJjYW5ub3QgY3JlYXRlIFFOYW1lIGZyb20gXCIiCisgICAgICAgICAgICAgICAgICAgICsgcU5hbWVBc1N0cmluZworICAgICAgICAgICAgICAgICAgICArICJcIiwgbWlzc2luZyBjbG9zaW5nIFwifVwiIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBRTmFtZSgKKyAgICAgICAgICAgIHFOYW1lQXNTdHJpbmcuc3Vic3RyaW5nKDEsIGVuZE9mTmFtZXNwYWNlVVJJKSwKKyAgICAgICAgICAgIHFOYW1lQXNTdHJpbmcuc3Vic3RyaW5nKGVuZE9mTmFtZXNwYWNlVVJJICsgMSksCisgICAgICAgICAgICBYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVgpOworICAgIH0KKworICAgIC8qCisgICAgICogRm9yIG9sZCB2ZXJzaW9ucyBvZiBRTmFtZSB3aGljaCBkaWRuJ3QgaGF2ZSBhIHByZWZpeCBmaWVsZCwKKyAgICAgKiA8Y29kZT5PYmplY3RJbnB1dFN0cmVhbS5kZWZhdWx0UmVhZE9iamVjdCgpPC9jb2RlPiB3aWxsIGluaXRpYWxpemUKKyAgICAgKiB0aGUgcHJlZml4IHRvIDxjb2RlPm51bGw8L2NvZGU+IGluc3RlYWQgb2YgdGhlIGVtcHR5IHN0cmluZy4gVGhpcworICAgICAqIG1ldGhvZCBmaXhlcyB1cCB0aGUgcHJlZml4IGZpZWxkIGlmIGl0IGRpZG4ndCBleGlzdCBpbiB0aGUgc2VyaWFsaXplZAorICAgICAqIG9iamVjdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpbikKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgaW4uZGVmYXVsdFJlYWRPYmplY3QoKTsKKyAgICAgICAgaWYgKHByZWZpeCA9PSBudWxsKSB7CisgICAgICAgICAgICBwcmVmaXggPSBYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVg7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL25hbWVzcGFjZS9wYWNrYWdlLmh0bWwgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL25hbWVzcGFjZS9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTUyOTZmNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvbmFtZXNwYWNlL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDMzIEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PgorPCEtLQorICAkSWQ6IHBhY2thZ2UuaHRtbCAyMjYxODcgMjAwNS0wNC0xMSAwNzowMjowMlogbmVlcmFqICQKKy0tPgorCis8IURPQ1RZUEUgaHRtbAorICAgICBQVUJMSUMgIi0vL1czQy8vRFREIFhIVE1MIDEuMCBTdHJpY3QvL0VOIgorICAgICAiaHR0cDovL3d3dy53My5vcmcvVFIveGh0bWwxL0RURC94aHRtbDEtc3RyaWN0LmR0ZCI+CisKKzxodG1sIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIj4KKworPGhlYWQ+CisgIDx0aXRsZT5qYXZheC54bWwubmFtZXNwYWNlPC90aXRsZT4KKworICA8bWV0YSBuYW1lPSJDVlMiCisgICAgICAgIGNvbnRlbnQ9IiRJZDogcGFja2FnZS5odG1sIDIyNjE4NyAyMDA1LTA0LTExIDA3OjAyOjAyWiBuZWVyYWogJCIgLz4KKyAgPG1ldGEgbmFtZT0iQVVUSE9SIgorICAgICAgICBjb250ZW50PSJKZWZmLlN1dHRvckBTdW4uY29tIiAvPgorPC9oZWFkPgorCis8Ym9keT4KKworPHA+WE1MIE5hbWVzcGFjZSBwcm9jZXNzaW5nLjwvcD4KKworPHA+VGhlIGZvbGxvd2luZyBYTUwgc3RhbmRhcmRzIGFwcGx5OjwvcD4KKzx1bD4KKyAgPGxpPjxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNRTmFtZSI+WE1MIFNjaGVtYSBQYXJ0MjogRGF0YXR5cGVzIHNwZWNpZmljYXRpb248L2E+PC9saT4KKyAgPGxpPjxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI25zLXF1YWxuYW1lcyI+TmFtZXNwYWNlcyBpbiBYTUw8L2E+PC9saT4KKyAgPGxpPjxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1hNTC94bWwtbmFtZXMtMTk5OTAxMTQtZXJyYXRhIj5OYW1lc3BhY2VzIGluIFhNTCBFcnJhdGE8L2E+PC9saT4KKzwvdWw+CisKKzwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvcGFja2FnZS5odG1sIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjNkODMxOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsNyBAQAorPGh0bWw+CisgIDxib2R5PgorICAgIDxwPgorICAgICAgUHJvdmlkZXMgYSB1dGlsaXR5IGNsYXNzIHdpdGggdXNlZnVsIFhNTCBjb25zdGFudHMuCisgICAgPC9wPgorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3BhcnNlcnMvRG9jdW1lbnRCdWlsZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3BhcnNlcnMvRG9jdW1lbnRCdWlsZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTZjMTkxZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvcGFyc2Vycy9Eb2N1bWVudEJ1aWxkZXIuamF2YQpAQCAtMCwwICsxLDMxNiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vICRJZDogRG9jdW1lbnRCdWlsZGVyLmphdmEgNTg0NDgzIDIwMDctMTAtMTQgMDI6NTQ6NDhaIG1yZ2xhdmFzICQKKworcGFja2FnZSBqYXZheC54bWwucGFyc2VyczsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YXgueG1sLnZhbGlkYXRpb24uU2NoZW1hOworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247CisKKy8qKgorICogRGVmaW5lcyB0aGUgQVBJIHRvIG9idGFpbiBET00gRG9jdW1lbnQgaW5zdGFuY2VzIGZyb20gYW4gWE1MCisgKiBkb2N1bWVudC4gVXNpbmcgdGhpcyBjbGFzcywgYW4gYXBwbGljYXRpb24gcHJvZ3JhbW1lciBjYW4gb2J0YWluIGEKKyAqIHtAbGluayBEb2N1bWVudH0gZnJvbSBYTUwuPHA+CisgKgorICogQW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBjYW4gYmUgb2J0YWluZWQgZnJvbSB0aGUKKyAqIHtAbGluayBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5I25ld0RvY3VtZW50QnVpbGRlcigpfSBtZXRob2QuIE9uY2UKKyAqIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgaXMgb2J0YWluZWQsIFhNTCBjYW4gYmUgcGFyc2VkIGZyb20gYQorICogdmFyaWV0eSBvZiBpbnB1dCBzb3VyY2VzLiBUaGVzZSBpbnB1dCBzb3VyY2VzIGFyZSBJbnB1dFN0cmVhbXMsCisgKiBGaWxlcywgVVJMcywgYW5kIFNBWCBJbnB1dFNvdXJjZXMuPHA+CisgKgorICogTm90ZSB0aGF0IHRoaXMgY2xhc3MgcmV1c2VzIHNldmVyYWwgY2xhc3NlcyBmcm9tIHRoZSBTQVggQVBJLiBUaGlzCisgKiBkb2VzIG5vdCByZXF1aXJlIHRoYXQgdGhlIGltcGxlbWVudG9yIG9mIHRoZSB1bmRlcmx5aW5nIERPTQorICogaW1wbGVtZW50YXRpb24gdXNlIGEgU0FYIHBhcnNlciB0byBwYXJzZSBYTUwgZG9jdW1lbnQgaW50byBhCisgKiA8Y29kZT5Eb2N1bWVudDwvY29kZT4uIEl0IG1lcmVseSByZXF1aXJlcyB0aGF0IHRoZSBpbXBsZW1lbnRhdGlvbgorICogY29tbXVuaWNhdGUgd2l0aCB0aGUgYXBwbGljYXRpb24gdXNpbmcgdGhlc2UgZXhpc3RpbmcgQVBJcy4KKyAqCisgKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogNTg0NDgzICQsICREYXRlOiAyMDA3LTEwLTEzIDE5OjU0OjQ4IC0wNzAwIChTYXQsIDEzIE9jdCAyMDA3KSAkCisgKi8KKworcHVibGljIGFic3RyYWN0IGNsYXNzIERvY3VtZW50QnVpbGRlciB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHID0gZmFsc2U7CisKKyAgICAvKiogUHJvdGVjdGVkIGNvbnN0cnVjdG9yICovCisgICAgcHJvdGVjdGVkIERvY3VtZW50QnVpbGRlciAoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICAqIDxwPlJlc2V0IHRoaXMgPGNvZGU+RG9jdW1lbnRCdWlsZGVyPC9jb2RlPiB0byBpdHMgb3JpZ2luYWwgY29uZmlndXJhdGlvbi48L3A+CisgICAgICAqCisgICAgICAqIDxwPjxjb2RlPkRvY3VtZW50QnVpbGRlcjwvY29kZT4gaXMgcmVzZXQgdG8gdGhlIHNhbWUgc3RhdGUgYXMgd2hlbiBpdCB3YXMgY3JlYXRlZCB3aXRoCisgICAgICAqIHtAbGluayBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5I25ld0RvY3VtZW50QnVpbGRlcigpfS4KKyAgICAgICogPGNvZGU+cmVzZXQoKTwvY29kZT4gaXMgZGVzaWduZWQgdG8gYWxsb3cgdGhlIHJldXNlIG9mIGV4aXN0aW5nIDxjb2RlPkRvY3VtZW50QnVpbGRlcjwvY29kZT5zCisgICAgICAqIHRodXMgc2F2aW5nIHJlc291cmNlcyBhc3NvY2lhdGVkIHdpdGggdGhlIGNyZWF0aW9uIG9mIG5ldyA8Y29kZT5Eb2N1bWVudEJ1aWxkZXI8L2NvZGU+cy48L3A+CisgICAgICAqCisgICAgICAqIDxwPlRoZSByZXNldCA8Y29kZT5Eb2N1bWVudEJ1aWxkZXI8L2NvZGU+IGlzIG5vdCBndWFyYW50ZWVkIHRvIGhhdmUgdGhlIHNhbWUge0BsaW5rIEVudGl0eVJlc29sdmVyfSBvciB7QGxpbmsgRXJyb3JIYW5kbGVyfQorICAgICAgKiA8Y29kZT5PYmplY3Q8L2NvZGU+cywgZS5nLiB7QGxpbmsgT2JqZWN0I2VxdWFscyhPYmplY3Qgb2JqKX0uICBJdCBpcyBndWFyYW50ZWVkIHRvIGhhdmUgYSBmdW5jdGlvbmFsbHkgZXF1YWwKKyAgICAgICogPGNvZGU+RW50aXR5UmVzb2x2ZXI8L2NvZGU+IGFuZCA8Y29kZT5FcnJvckhhbmRsZXI8L2NvZGU+LjwvcD4KKyAgICAgICoKKyAgICAgICogQHNpbmNlIDEuNQorICAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKKworICAgICAgICAvLyBpbXBsZW1lbnRvcnMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kCisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICJUaGlzIERvY3VtZW50QnVpbGRlciwgXCIiICsgdGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSArICJcIiwgZG9lcyBub3Qgc3VwcG9ydCB0aGUgcmVzZXQgZnVuY3Rpb25hbGl0eS4iCisgICAgICAgICAgICArICIgIFNwZWNpZmljYXRpb24gXCIiICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVGl0bGUoKSArICJcIiIKKyAgICAgICAgICAgICsgIiB2ZXJzaW9uIFwiIiArIHRoaXMuZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkuZ2V0U3BlY2lmaWNhdGlvblZlcnNpb24oKSArICJcIiIKKyAgICAgICAgICAgICk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2UgdGhlIGNvbnRlbnQgb2YgdGhlIGdpdmVuIDxjb2RlPklucHV0U3RyZWFtPC9jb2RlPiBhcyBhbiBYTUwKKyAgICAgKiBkb2N1bWVudCBhbmQgcmV0dXJuIGEgbmV3IERPTSB7QGxpbmsgRG9jdW1lbnR9IG9iamVjdC4KKyAgICAgKiBBbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93biBpZiB0aGUKKyAgICAgKiA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4gaXMgbnVsbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpcyBJbnB1dFN0cmVhbSBjb250YWluaW5nIHRoZSBjb250ZW50IHRvIGJlIHBhcnNlZC4KKyAgICAgKiBAcmV0dXJuIDxjb2RlPkRvY3VtZW50PC9jb2RlPiByZXN1bHQgb2YgcGFyc2luZyB0aGUKKyAgICAgKiAgPGNvZGU+SW5wdXRTdHJlYW08L2NvZGU+CisgICAgICogQGV4Y2VwdGlvbiBJT0V4Y2VwdGlvbiBJZiBhbnkgSU8gZXJyb3JzIG9jY3VyLgorICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIElmIGFueSBwYXJzZSBlcnJvcnMgb2NjdXIuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIKKyAgICAgKi8KKworICAgIHB1YmxpYyBEb2N1bWVudCBwYXJzZShJbnB1dFN0cmVhbSBpcykKKyAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaXMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW5wdXRTdHJlYW0gY2Fubm90IGJlIG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIElucHV0U291cmNlIGluID0gbmV3IElucHV0U291cmNlKGlzKTsKKyAgICAgICAgcmV0dXJuIHBhcnNlKGluKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSB0aGUgY29udGVudCBvZiB0aGUgZ2l2ZW4gPGNvZGU+SW5wdXRTdHJlYW08L2NvZGU+IGFzIGFuCisgICAgICogWE1MIGRvY3VtZW50IGFuZCByZXR1cm4gYSBuZXcgRE9NIHtAbGluayBEb2N1bWVudH0gb2JqZWN0LgorICAgICAqIEFuIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duIGlmIHRoZQorICAgICAqIDxjb2RlPklucHV0U3RyZWFtPC9jb2RlPiBpcyBudWxsLgorICAgICAqCisgICAgICogQHBhcmFtIGlzIElucHV0U3RyZWFtIGNvbnRhaW5pbmcgdGhlIGNvbnRlbnQgdG8gYmUgcGFyc2VkLgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBQcm92aWRlIGEgYmFzZSBmb3IgcmVzb2x2aW5nIHJlbGF0aXZlIFVSSXMuCisgICAgICogQHJldHVybiBBIG5ldyBET00gRG9jdW1lbnQgb2JqZWN0LgorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gSWYgYW55IElPIGVycm9ycyBvY2N1ci4KKyAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBJZiBhbnkgcGFyc2UgZXJyb3JzIG9jY3VyLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyCisgICAgICovCisKKyAgICBwdWJsaWMgRG9jdW1lbnQgcGFyc2UoSW5wdXRTdHJlYW0gaXMsIFN0cmluZyBzeXN0ZW1JZCkKKyAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaXMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW5wdXRTdHJlYW0gY2Fubm90IGJlIG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIElucHV0U291cmNlIGluID0gbmV3IElucHV0U291cmNlKGlzKTsKKyAgICAgICAgaW4uc2V0U3lzdGVtSWQoc3lzdGVtSWQpOworICAgICAgICByZXR1cm4gcGFyc2UoaW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBjb250ZW50IG9mIHRoZSBnaXZlbiBVUkkgYXMgYW4gWE1MIGRvY3VtZW50CisgICAgICogYW5kIHJldHVybiBhIG5ldyBET00ge0BsaW5rIERvY3VtZW50fSBvYmplY3QuCisgICAgICogQW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYgdGhlCisgICAgICogVVJJIGlzIDxjb2RlPm51bGw8L2NvZGU+IG51bGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJpIFRoZSBsb2NhdGlvbiBvZiB0aGUgY29udGVudCB0byBiZSBwYXJzZWQuCisgICAgICogQHJldHVybiBBIG5ldyBET00gRG9jdW1lbnQgb2JqZWN0LgorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gSWYgYW55IElPIGVycm9ycyBvY2N1ci4KKyAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBJZiBhbnkgcGFyc2UgZXJyb3JzIG9jY3VyLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyCisgICAgICovCisKKyAgICBwdWJsaWMgRG9jdW1lbnQgcGFyc2UoU3RyaW5nIHVyaSkKKyAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodXJpID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlVSSSBjYW5ub3QgYmUgbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgSW5wdXRTb3VyY2UgaW4gPSBuZXcgSW5wdXRTb3VyY2UodXJpKTsKKyAgICAgICAgcmV0dXJuIHBhcnNlKGluKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSB0aGUgY29udGVudCBvZiB0aGUgZ2l2ZW4gZmlsZSBhcyBhbiBYTUwgZG9jdW1lbnQKKyAgICAgKiBhbmQgcmV0dXJuIGEgbmV3IERPTSB7QGxpbmsgRG9jdW1lbnR9IG9iamVjdC4KKyAgICAgKiBBbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93biBpZiB0aGUKKyAgICAgKiA8Y29kZT5GaWxlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiBudWxsLgorICAgICAqCisgICAgICogQHBhcmFtIGYgVGhlIGZpbGUgY29udGFpbmluZyB0aGUgWE1MIHRvIHBhcnNlLgorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gSWYgYW55IElPIGVycm9ycyBvY2N1ci4KKyAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBJZiBhbnkgcGFyc2UgZXJyb3JzIG9jY3VyLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyCisgICAgICogQHJldHVybiBBIG5ldyBET00gRG9jdW1lbnQgb2JqZWN0LgorICAgICAqLworCisgICAgcHVibGljIERvY3VtZW50IHBhcnNlKEZpbGUgZikgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoZiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWxlIGNhbm5vdCBiZSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgZXNjYXBlZFVSSSA9IEZpbGVQYXRoVG9VUkkuZmlsZXBhdGgyVVJJKGYuZ2V0QWJzb2x1dGVQYXRoKCkpOworCisgICAgICAgIGlmIChERUJVRykgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFc2NhcGVkIFVSSSA9ICIgKyBlc2NhcGVkVVJJKTsKKyAgICAgICAgfQorCisgICAgICAgIElucHV0U291cmNlIGluID0gbmV3IElucHV0U291cmNlKGVzY2FwZWRVUkkpOworICAgICAgICByZXR1cm4gcGFyc2UoaW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBjb250ZW50IG9mIHRoZSBnaXZlbiBpbnB1dCBzb3VyY2UgYXMgYW4gWE1MIGRvY3VtZW50CisgICAgICogYW5kIHJldHVybiBhIG5ldyBET00ge0BsaW5rIERvY3VtZW50fSBvYmplY3QuCisgICAgICogQW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYgdGhlCisgICAgICogPGNvZGU+SW5wdXRTb3VyY2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+IG51bGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXMgSW5wdXRTb3VyY2UgY29udGFpbmluZyB0aGUgY29udGVudCB0byBiZSBwYXJzZWQuCisgICAgICogQGV4Y2VwdGlvbiBJT0V4Y2VwdGlvbiBJZiBhbnkgSU8gZXJyb3JzIG9jY3VyLgorICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIElmIGFueSBwYXJzZSBlcnJvcnMgb2NjdXIuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIKKyAgICAgKiBAcmV0dXJuIEEgbmV3IERPTSBEb2N1bWVudCBvYmplY3QuCisgICAgICovCisKKyAgICBwdWJsaWMgYWJzdHJhY3QgRG9jdW1lbnQgcGFyc2UoSW5wdXRTb3VyY2UgaXMpCisgICAgICAgIHRocm93cyAgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbjsKKworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoaXMgcGFyc2VyIGlzIGNvbmZpZ3VyZWQgdG8KKyAgICAgKiB1bmRlcnN0YW5kIG5hbWVzcGFjZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBwYXJzZXIgaXMgY29uZmlndXJlZCB0byB1bmRlcnN0YW5kCisgICAgICogICAgICAgICBuYW1lc3BhY2VzOyBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisKKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc05hbWVzcGFjZUF3YXJlKCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhpcyBwYXJzZXIgaXMgY29uZmlndXJlZCB0bworICAgICAqIHZhbGlkYXRlIFhNTCBkb2N1bWVudHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBwYXJzZXIgaXMgY29uZmlndXJlZCB0byB2YWxpZGF0ZQorICAgICAqICAgICAgICAgWE1MIGRvY3VtZW50czsgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNWYWxpZGF0aW5nKCk7CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWZ5IHRoZSB7QGxpbmsgRW50aXR5UmVzb2x2ZXJ9IHRvIGJlIHVzZWQgdG8gcmVzb2x2ZQorICAgICAqIGVudGl0aWVzIHByZXNlbnQgaW4gdGhlIFhNTCBkb2N1bWVudCB0byBiZSBwYXJzZWQuIFNldHRpbmcKKyAgICAgKiB0aGlzIHRvIDxjb2RlPm51bGw8L2NvZGU+IHdpbGwgcmVzdWx0IGluIHRoZSB1bmRlcmx5aW5nCisgICAgICogaW1wbGVtZW50YXRpb24gdXNpbmcgaXQncyBvd24gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBhbmQKKyAgICAgKiBiZWhhdmlvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlciBUaGUgPGNvZGU+RW50aXR5UmVzb2x2ZXI8L2NvZGU+IHRvIGJlIHVzZWQgdG8gcmVzb2x2ZSBlbnRpdGllcworICAgICAqICAgICAgICAgICBwcmVzZW50IGluIHRoZSBYTUwgZG9jdW1lbnQgdG8gYmUgcGFyc2VkLgorICAgICAqLworCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoRW50aXR5UmVzb2x2ZXIgZXIpOworCisgICAgLyoqCisgICAgICogU3BlY2lmeSB0aGUge0BsaW5rIEVycm9ySGFuZGxlcn0gdG8gYmUgdXNlZCBieSB0aGUgcGFyc2VyLgorICAgICAqIFNldHRpbmcgdGhpcyB0byA8Y29kZT5udWxsPC9jb2RlPiB3aWxsIHJlc3VsdCBpbiB0aGUgdW5kZXJseWluZworICAgICAqIGltcGxlbWVudGF0aW9uIHVzaW5nIGl0J3Mgb3duIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gYW5kCisgICAgICogYmVoYXZpb3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZWggVGhlIDxjb2RlPkVycm9ySGFuZGxlcjwvY29kZT4gdG8gYmUgdXNlZCBieSB0aGUgcGFyc2VyLgorICAgICAqLworCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlciBlaCk7CisKKyAgICAvKioKKyAgICAgKiBPYnRhaW4gYSBuZXcgaW5zdGFuY2Ugb2YgYSBET00ge0BsaW5rIERvY3VtZW50fSBvYmplY3QKKyAgICAgKiB0byBidWlsZCBhIERPTSB0cmVlIHdpdGguCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEgbmV3IGluc3RhbmNlIG9mIGEgRE9NIERvY3VtZW50IG9iamVjdC4KKyAgICAgKi8KKworICAgIHB1YmxpYyBhYnN0cmFjdCBEb2N1bWVudCBuZXdEb2N1bWVudCgpOworCisgICAgLyoqCisgICAgICogT2J0YWluIGFuIGluc3RhbmNlIG9mIGEge0BsaW5rIERPTUltcGxlbWVudGF0aW9ufSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEgbmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+LgorICAgICAqLworCisgICAgcHVibGljIGFic3RyYWN0IERPTUltcGxlbWVudGF0aW9uIGdldERPTUltcGxlbWVudGF0aW9uKCk7CisKKyAgICAvKiogPHA+R2V0IGEgcmVmZXJlbmNlIHRvIHRoZSB0aGUge0BsaW5rIFNjaGVtYX0gYmVpbmcgdXNlZCBieQorICAgICAqIHRoZSBYTUwgcHJvY2Vzc29yLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIG5vIHNjaGVtYSBpcyBiZWluZyB1c2VkLCA8Y29kZT5udWxsPC9jb2RlPiBpcyByZXR1cm5lZC48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHtAbGluayBTY2hlbWF9IGJlaW5nIHVzZWQgb3IgPGNvZGU+bnVsbDwvY29kZT4KKyAgICAgKiAgaWYgbm9uZSBpbiB1c2UKKyAgICAgKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB3aGVuIGltcGxlbWVudGF0aW9ucyBmb3IKKyAgICAgKiAgICAgIGVhcmxpZXIgdmVyc2lvbnMgb2YgSkFYUCBpcyB1c2VkLCB0aGlzIGV4Y2VwdGlvbiB3aWxsIGJlCisgICAgICogICAgICB0aHJvd24uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIFNjaGVtYSBnZXRTY2hlbWEoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICJUaGlzIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHNwZWNpZmljYXRpb24gXCIiCisgICAgICAgICAgICArIHRoaXMuZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkuZ2V0U3BlY2lmaWNhdGlvblRpdGxlKCkKKyAgICAgICAgICAgICsgIlwiIHZlcnNpb24gXCIiCisgICAgICAgICAgICArIHRoaXMuZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkuZ2V0U3BlY2lmaWNhdGlvblZlcnNpb24oKQorICAgICAgICAgICAgKyAiXCIiCisgICAgICAgICAgICApOworICAgIH0KKworCisgICAgLyoqCisgICAgICogPHA+R2V0IHRoZSBYSW5jbHVkZSBwcm9jZXNzaW5nIG1vZGUgZm9yIHRoaXMgcGFyc2VyLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4KKyAgICAgKiAgICAgIHRoZSByZXR1cm4gdmFsdWUgb2YKKyAgICAgKiAgICAgIHRoZSB7QGxpbmsgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSNpc1hJbmNsdWRlQXdhcmUoKX0KKyAgICAgKiAgICAgIHdoZW4gdGhpcyBwYXJzZXIgd2FzIGNyZWF0ZWQgZnJvbSBmYWN0b3J5LgorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgRm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHdoZW4gaW1wbGVtZW50YXRpb25zIGZvcgorICAgICAqICAgICAgZWFybGllciB2ZXJzaW9ucyBvZiBKQVhQIGlzIHVzZWQsIHRoaXMgZXhjZXB0aW9uIHdpbGwgYmUKKyAgICAgKiAgICAgIHRocm93bi4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKgorICAgICAqIEBzZWUgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSNzZXRYSW5jbHVkZUF3YXJlKGJvb2xlYW4pCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNYSW5jbHVkZUF3YXJlKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgICAiVGhpcyBwYXJzZXIgZG9lcyBub3Qgc3VwcG9ydCBzcGVjaWZpY2F0aW9uIFwiIgorICAgICAgICAgICAgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25UaXRsZSgpCisgICAgICAgICAgICArICJcIiB2ZXJzaW9uIFwiIgorICAgICAgICAgICAgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25WZXJzaW9uKCkKKyAgICAgICAgICAgICsgIlwiIgorICAgICAgICAgICAgKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3BhcnNlcnMvRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9wYXJzZXJzL0RvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMTk4MmExCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9wYXJzZXJzL0RvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDUwMSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vICRJZDogRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5qYXZhIDg4NDk1MCAyMDA5LTExLTI3IDE4OjQ2OjE4WiBtcmdsYXZhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLnBhcnNlcnM7CisKK2ltcG9ydCBqYXZheC54bWwudmFsaWRhdGlvbi5TY2hlbWE7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3RvcnlJbXBsOworCisvKioKKyAqIERlZmluZXMgYSBmYWN0b3J5IEFQSSB0aGF0IGVuYWJsZXMgYXBwbGljYXRpb25zIHRvIG9idGFpbiBhCisgKiBwYXJzZXIgdGhhdCBwcm9kdWNlcyBET00gb2JqZWN0IHRyZWVzIGZyb20gWE1MIGRvY3VtZW50cy4KKyAqCisgKiBAYXV0aG9yIDxhIGhyZWY9IkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgorICogQHZlcnNpb24gJFJldmlzaW9uOiA4ODQ5NTAgJCwgJERhdGU6IDIwMDktMTEtMjcgMTA6NDY6MTggLTA4MDAgKEZyaSwgMjcgTm92IDIwMDkpICQKKyAqLworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gdmFsaWRhdGluZyA9IGZhbHNlOworICAgIHByaXZhdGUgYm9vbGVhbiBuYW1lc3BhY2VBd2FyZSA9IGZhbHNlOworICAgIHByaXZhdGUgYm9vbGVhbiB3aGl0ZXNwYWNlID0gZmFsc2U7CisgICAgcHJpdmF0ZSBib29sZWFuIGV4cGFuZEVudGl0eVJlZiA9IHRydWU7CisgICAgcHJpdmF0ZSBib29sZWFuIGlnbm9yZUNvbW1lbnRzID0gZmFsc2U7CisgICAgcHJpdmF0ZSBib29sZWFuIGNvYWxlc2NpbmcgPSBmYWxzZTsKKworICAgIHByb3RlY3RlZCBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5ICgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFuZHJvaWQncyBpbXBsZW1lbnRhdGlvbiBvZiB7QGNvZGUgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeX0uCisgICAgICogVW5saWtlIG90aGVyIEphdmEgaW1wbGVtZW50YXRpb25zLCB0aGlzIG1ldGhvZCBkb2VzIG5vdCBjb25zdWx0IHN5c3RlbQorICAgICAqIHByb3BlcnRpZXMsIHByb3BlcnR5IGZpbGVzLCBvciB0aGUgc2VydmljZXMgQVBJLgorICAgICAqCisgICAgICogQHJldHVybiBhIG5ldyBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBuZXdJbnN0YW5jZSgpIHsKKyAgICAgICAgLy8gaW5zdGFudGlhdGUgdGhlIGNsYXNzIGRpcmVjdGx5IHJhdGhlciB0aGFuIHVzaW5nIHJlZmxlY3Rpb24KKyAgICAgICAgcmV0dXJuIG5ldyBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgdGhlIG5hbWVkIGltcGxlbWVudGF0aW9uIG9mIHtAY29kZSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5fS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBpZiB7QGNvZGUgZmFjdG9yeUNsYXNzTmFtZX0gaXMgbm90IGF2YWlsYWJsZSBvciBjYW5ub3QgYmUKKyAgICAgKiAgICAgaW5zdGFudGlhdGVkLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIERvY3VtZW50QnVpbGRlckZhY3RvcnkgbmV3SW5zdGFuY2UoU3RyaW5nIGZhY3RvcnlDbGFzc05hbWUsCisgICAgICAgICAgICBDbGFzc0xvYWRlciBjbGFzc0xvYWRlcikgeworICAgICAgICBpZiAoZmFjdG9yeUNsYXNzTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcigiZmFjdG9yeUNsYXNzTmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNsYXNzTG9hZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIGNsYXNzTG9hZGVyID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3M8Pz4gdHlwZSA9IGNsYXNzTG9hZGVyICE9IG51bGwKKyAgICAgICAgICAgICAgICAgICAgPyBjbGFzc0xvYWRlci5sb2FkQ2xhc3MoZmFjdG9yeUNsYXNzTmFtZSkKKyAgICAgICAgICAgICAgICAgICAgOiBDbGFzcy5mb3JOYW1lKGZhY3RvcnlDbGFzc05hbWUpOworICAgICAgICAgICAgcmV0dXJuIChEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KSB0eXBlLm5ld0luc3RhbmNlKCk7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoZSk7CisgICAgICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoZSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIGEge0BsaW5rIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcn0KKyAgICAgKiB1c2luZyB0aGUgY3VycmVudGx5IGNvbmZpZ3VyZWQgcGFyYW1ldGVycy4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBpZiBhIERvY3VtZW50QnVpbGRlcgorICAgICAqIGNhbm5vdCBiZSBjcmVhdGVkIHdoaWNoIHNhdGlzZmllcyB0aGUgY29uZmlndXJhdGlvbiByZXF1ZXN0ZWQuCisgICAgICogQHJldHVybiBBIG5ldyBpbnN0YW5jZSBvZiBhIERvY3VtZW50QnVpbGRlci4KKyAgICAgKi8KKworICAgIHB1YmxpYyBhYnN0cmFjdCBEb2N1bWVudEJ1aWxkZXIgbmV3RG9jdW1lbnRCdWlsZGVyKCkKKyAgICAgICAgdGhyb3dzIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFNwZWNpZmllcyB0aGF0IHRoZSBwYXJzZXIgcHJvZHVjZWQgYnkgdGhpcyBjb2RlIHdpbGwKKyAgICAgKiBwcm92aWRlIHN1cHBvcnQgZm9yIFhNTCBuYW1lc3BhY2VzLiBCeSBkZWZhdWx0IHRoZSB2YWx1ZSBvZiB0aGlzIGlzIHNldAorICAgICAqIHRvIDxjb2RlPmZhbHNlPC9jb2RlPgorICAgICAqCisgICAgICogQHBhcmFtIGF3YXJlbmVzcyB0cnVlIGlmIHRoZSBwYXJzZXIgcHJvZHVjZWQgd2lsbCBwcm92aWRlIHN1cHBvcnQKKyAgICAgKiAgICAgICAgICAgICAgICAgIGZvciBYTUwgbmFtZXNwYWNlczsgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworCisgICAgcHVibGljIHZvaWQgc2V0TmFtZXNwYWNlQXdhcmUoYm9vbGVhbiBhd2FyZW5lc3MpIHsKKyAgICAgICAgdGhpcy5uYW1lc3BhY2VBd2FyZSA9IGF3YXJlbmVzczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWZpZXMgdGhhdCB0aGUgcGFyc2VyIHByb2R1Y2VkIGJ5IHRoaXMgY29kZSB3aWxsCisgICAgICogdmFsaWRhdGUgZG9jdW1lbnRzIGFzIHRoZXkgYXJlIHBhcnNlZC4gQnkgZGVmYXVsdCB0aGUgdmFsdWUgb2YgdGhpcworICAgICAqIGlzIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4uCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlIHRoYXQgInRoZSB2YWxpZGF0aW9uIiBoZXJlIG1lYW5zCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCNwcm9jLXR5cGVzIj5hIHZhbGlkYXRpbmcKKyAgICAgKiBwYXJzZXI8L2E+IGFzIGRlZmluZWQgaW4gdGhlIFhNTCByZWNvbW1lbmRhdGlvbi4KKyAgICAgKiBJbiBvdGhlciB3b3JkcywgaXQgZXNzZW50aWFsbHkganVzdCBjb250cm9scyB0aGUgRFREIHZhbGlkYXRpb24uCisgICAgICogKGV4Y2VwdCB0aGUgbGVnYWN5IHR3byBwcm9wZXJ0aWVzIGRlZmluZWQgaW4gSkFYUCAxLjIuCisgICAgICogU2VlIDxhIGhyZWY9IiN2YWxpZGF0aW9uQ29tcGF0aWJpbGl0eSI+aGVyZTwvYT4gZm9yIG1vcmUgZGV0YWlscy4pCisgICAgICogPC9wPgorICAgICAqCisgICAgICogPHA+CisgICAgICogVG8gdXNlIG1vZGVybiBzY2hlbWEgbGFuZ3VhZ2VzIHN1Y2ggYXMgVzNDIFhNTCBTY2hlbWEgb3IKKyAgICAgKiBSRUxBWCBORyBpbnN0ZWFkIG9mIERURCwgeW91IGNhbiBjb25maWd1cmUgeW91ciBwYXJzZXIgdG8gYmUKKyAgICAgKiBhIG5vbi12YWxpZGF0aW5nIHBhcnNlciBieSBsZWF2aW5nIHRoZSB7QGxpbmsgI3NldFZhbGlkYXRpbmcoYm9vbGVhbil9CisgICAgICogbWV0aG9kIDx0dD5mYWxzZTwvdHQ+LCB0aGVuIHVzZSB0aGUge0BsaW5rICNzZXRTY2hlbWEoU2NoZW1hKX0KKyAgICAgKiBtZXRob2QgdG8gYXNzb2NpYXRlIGEgc2NoZW1hIHRvIGEgcGFyc2VyLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWxpZGF0aW5nIHRydWUgaWYgdGhlIHBhcnNlciBwcm9kdWNlZCB3aWxsIHZhbGlkYXRlIGRvY3VtZW50cworICAgICAqICAgICAgICAgICAgICAgICAgIGFzIHRoZXkgYXJlIHBhcnNlZDsgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworCisgICAgcHVibGljIHZvaWQgc2V0VmFsaWRhdGluZyhib29sZWFuIHZhbGlkYXRpbmcpIHsKKyAgICAgICAgdGhpcy52YWxpZGF0aW5nID0gdmFsaWRhdGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWZpZXMgdGhhdCB0aGUgcGFyc2VycyBjcmVhdGVkIGJ5IHRoaXMgIGZhY3RvcnkgbXVzdCBlbGltaW5hdGUKKyAgICAgKiB3aGl0ZXNwYWNlIGluIGVsZW1lbnQgY29udGVudCAoc29tZXRpbWVzIGtub3duIGxvb3NlbHkgYXMKKyAgICAgKiAnaWdub3JhYmxlIHdoaXRlc3BhY2UnKSB3aGVuIHBhcnNpbmcgWE1MIGRvY3VtZW50cyAoc2VlIFhNTCBSZWMKKyAgICAgKiAyLjEwKS4gTm90ZSB0aGF0IG9ubHkgd2hpdGVzcGFjZSB3aGljaCBpcyBkaXJlY3RseSBjb250YWluZWQgd2l0aGluCisgICAgICogZWxlbWVudCBjb250ZW50IHRoYXQgaGFzIGFuIGVsZW1lbnQgb25seSBjb250ZW50IG1vZGVsIChzZWUgWE1MCisgICAgICogUmVjIDMuMi4xKSB3aWxsIGJlIGVsaW1pbmF0ZWQuIER1ZSB0byByZWxpYW5jZSBvbiB0aGUgY29udGVudCBtb2RlbAorICAgICAqIHRoaXMgc2V0dGluZyByZXF1aXJlcyB0aGUgcGFyc2VyIHRvIGJlIGluIHZhbGlkYXRpbmcgbW9kZS4gQnkgZGVmYXVsdAorICAgICAqIHRoZSB2YWx1ZSBvZiB0aGlzIGlzIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gd2hpdGVzcGFjZSB0cnVlIGlmIHRoZSBwYXJzZXIgY3JlYXRlZCBtdXN0IGVsaW1pbmF0ZSB3aGl0ZXNwYWNlCisgICAgICogICAgICAgICAgICAgICAgICAgaW4gdGhlIGVsZW1lbnQgY29udGVudCB3aGVuIHBhcnNpbmcgWE1MIGRvY3VtZW50czsKKyAgICAgKiAgICAgICAgICAgICAgICAgICBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisKKyAgICBwdWJsaWMgdm9pZCBzZXRJZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZShib29sZWFuIHdoaXRlc3BhY2UpIHsKKyAgICAgICAgdGhpcy53aGl0ZXNwYWNlID0gd2hpdGVzcGFjZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGVjaWZpZXMgdGhhdCB0aGUgcGFyc2VyIHByb2R1Y2VkIGJ5IHRoaXMgY29kZSB3aWxsCisgICAgICogZXhwYW5kIGVudGl0eSByZWZlcmVuY2Ugbm9kZXMuIEJ5IGRlZmF1bHQgdGhlIHZhbHVlIG9mIHRoaXMgaXMgc2V0IHRvCisgICAgICogPGNvZGU+dHJ1ZTwvY29kZT4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleHBhbmRFbnRpdHlSZWYgdHJ1ZSBpZiB0aGUgcGFyc2VyIHByb2R1Y2VkIHdpbGwgZXhwYW5kIGVudGl0eQorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgcmVmZXJlbmNlIG5vZGVzOyBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisKKyAgICBwdWJsaWMgdm9pZCBzZXRFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKGJvb2xlYW4gZXhwYW5kRW50aXR5UmVmKSB7CisgICAgICAgIHRoaXMuZXhwYW5kRW50aXR5UmVmID0gZXhwYW5kRW50aXR5UmVmOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlNwZWNpZmllcyB0aGF0IHRoZSBwYXJzZXIgcHJvZHVjZWQgYnkgdGhpcyBjb2RlIHdpbGwKKyAgICAgKiBpZ25vcmUgY29tbWVudHMuIEJ5IGRlZmF1bHQgdGhlIHZhbHVlIG9mIHRoaXMgaXMgc2V0IHRvIDxjb2RlPmZhbHNlCisgICAgICogPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaWdub3JlQ29tbWVudHMgPGNvZGU+Ym9vbGVhbjwvY29kZT4gdmFsdWUgdG8gaWdub3JlIGNvbW1lbnRzIGR1cmluZyBwcm9jZXNzaW5nCisgICAgICovCisKKyAgICBwdWJsaWMgdm9pZCBzZXRJZ25vcmluZ0NvbW1lbnRzKGJvb2xlYW4gaWdub3JlQ29tbWVudHMpIHsKKyAgICAgICAgdGhpcy5pZ25vcmVDb21tZW50cyA9IGlnbm9yZUNvbW1lbnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNwZWNpZmllcyB0aGF0IHRoZSBwYXJzZXIgcHJvZHVjZWQgYnkgdGhpcyBjb2RlIHdpbGwKKyAgICAgKiBjb252ZXJ0IENEQVRBIG5vZGVzIHRvIFRleHQgbm9kZXMgYW5kIGFwcGVuZCBpdCB0byB0aGUKKyAgICAgKiBhZGphY2VudCAoaWYgYW55KSB0ZXh0IG5vZGUuIEJ5IGRlZmF1bHQgdGhlIHZhbHVlIG9mIHRoaXMgaXMgc2V0IHRvCisgICAgICogPGNvZGU+ZmFsc2U8L2NvZGU+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY29hbGVzY2luZyAgdHJ1ZSBpZiB0aGUgcGFyc2VyIHByb2R1Y2VkIHdpbGwgY29udmVydCBDREFUQSBub2RlcworICAgICAqICAgICAgICAgICAgICAgICAgICB0byBUZXh0IG5vZGVzIGFuZCBhcHBlbmQgaXQgdG8gdGhlIGFkamFjZW50IChpZiBhbnkpCisgICAgICogICAgICAgICAgICAgICAgICAgIHRleHQgbm9kZTsgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworCisgICAgcHVibGljIHZvaWQgc2V0Q29hbGVzY2luZyhib29sZWFuIGNvYWxlc2NpbmcpIHsKKyAgICAgICAgdGhpcy5jb2FsZXNjaW5nID0gY29hbGVzY2luZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhlIGZhY3RvcnkgaXMgY29uZmlndXJlZCB0byBwcm9kdWNlCisgICAgICogcGFyc2VycyB3aGljaCBhcmUgbmFtZXNwYWNlIGF3YXJlLgorICAgICAqCisgICAgICogQHJldHVybiAgdHJ1ZSBpZiB0aGUgZmFjdG9yeSBpcyBjb25maWd1cmVkIHRvIHByb2R1Y2UgcGFyc2VycyB3aGljaAorICAgICAqICAgICAgICAgIGFyZSBuYW1lc3BhY2UgYXdhcmU7IGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKworICAgIHB1YmxpYyBib29sZWFuIGlzTmFtZXNwYWNlQXdhcmUoKSB7CisgICAgICAgIHJldHVybiBuYW1lc3BhY2VBd2FyZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhlIGZhY3RvcnkgaXMgY29uZmlndXJlZCB0byBwcm9kdWNlCisgICAgICogcGFyc2VycyB3aGljaCB2YWxpZGF0ZSB0aGUgWE1MIGNvbnRlbnQgZHVyaW5nIHBhcnNlLgorICAgICAqCisgICAgICogQHJldHVybiAgdHJ1ZSBpZiB0aGUgZmFjdG9yeSBpcyBjb25maWd1cmVkIHRvIHByb2R1Y2UgcGFyc2VycworICAgICAqICAgICAgICAgIHdoaWNoIHZhbGlkYXRlIHRoZSBYTUwgY29udGVudCBkdXJpbmcgcGFyc2U7IGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKworICAgIHB1YmxpYyBib29sZWFuIGlzVmFsaWRhdGluZygpIHsKKyAgICAgICAgcmV0dXJuIHZhbGlkYXRpbmc7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBmYWN0b3J5IGlzIGNvbmZpZ3VyZWQgdG8gcHJvZHVjZQorICAgICAqIHBhcnNlcnMgd2hpY2ggaWdub3JlIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIGluIGVsZW1lbnQgY29udGVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gIHRydWUgaWYgdGhlIGZhY3RvcnkgaXMgY29uZmlndXJlZCB0byBwcm9kdWNlIHBhcnNlcnMKKyAgICAgKiAgICAgICAgICB3aGljaCBpZ25vcmUgaWdub3JhYmxlIHdoaXRlc3BhY2UgaW4gZWxlbWVudCBjb250ZW50OworICAgICAqICAgICAgICAgIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKworICAgIHB1YmxpYyBib29sZWFuIGlzSWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoKSB7CisgICAgICAgIHJldHVybiB3aGl0ZXNwYWNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgZmFjdG9yeSBpcyBjb25maWd1cmVkIHRvIHByb2R1Y2UKKyAgICAgKiBwYXJzZXJzIHdoaWNoIGV4cGFuZCBlbnRpdHkgcmVmZXJlbmNlIG5vZGVzLgorICAgICAqCisgICAgICogQHJldHVybiAgdHJ1ZSBpZiB0aGUgZmFjdG9yeSBpcyBjb25maWd1cmVkIHRvIHByb2R1Y2UgcGFyc2VycworICAgICAqICAgICAgICAgIHdoaWNoIGV4cGFuZCBlbnRpdHkgcmVmZXJlbmNlIG5vZGVzOyBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0V4cGFuZEVudGl0eVJlZmVyZW5jZXMoKSB7CisgICAgICAgIHJldHVybiBleHBhbmRFbnRpdHlSZWY7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBmYWN0b3J5IGlzIGNvbmZpZ3VyZWQgdG8gcHJvZHVjZQorICAgICAqIHBhcnNlcnMgd2hpY2ggaWdub3JlcyBjb21tZW50cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gIHRydWUgaWYgdGhlIGZhY3RvcnkgaXMgY29uZmlndXJlZCB0byBwcm9kdWNlIHBhcnNlcnMKKyAgICAgKiAgICAgICAgICB3aGljaCBpZ25vcmVzIGNvbW1lbnRzOyBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0lnbm9yaW5nQ29tbWVudHMoKSB7CisgICAgICAgIHJldHVybiBpZ25vcmVDb21tZW50czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhlIGZhY3RvcnkgaXMgY29uZmlndXJlZCB0byBwcm9kdWNlCisgICAgICogcGFyc2VycyB3aGljaCBjb252ZXJ0cyBDREFUQSBub2RlcyB0byBUZXh0IG5vZGVzIGFuZCBhcHBlbmRzIGl0IHRvCisgICAgICogdGhlIGFkamFjZW50IChpZiBhbnkpIFRleHQgbm9kZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gIHRydWUgaWYgdGhlIGZhY3RvcnkgaXMgY29uZmlndXJlZCB0byBwcm9kdWNlIHBhcnNlcnMKKyAgICAgKiAgICAgICAgICB3aGljaCBjb252ZXJ0cyBDREFUQSBub2RlcyB0byBUZXh0IG5vZGVzIGFuZCBhcHBlbmRzIGl0IHRvCisgICAgICogICAgICAgICAgdGhlIGFkamFjZW50IChpZiBhbnkpIFRleHQgbm9kZTsgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworCisgICAgcHVibGljIGJvb2xlYW4gaXNDb2FsZXNjaW5nKCkgeworICAgICAgICByZXR1cm4gY29hbGVzY2luZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbGxvd3MgdGhlIHVzZXIgdG8gc2V0IHNwZWNpZmljIGF0dHJpYnV0ZXMgb24gdGhlIHVuZGVybHlpbmcKKyAgICAgKiBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgorICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHJlY29nbml6ZSB0aGUgYXR0cmlidXRlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKQorICAgICAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBBbGxvd3MgdGhlIHVzZXIgdG8gcmV0cmlldmUgc3BlY2lmaWMgYXR0cmlidXRlcyBvbiB0aGUgdW5kZXJseWluZworICAgICAqIGltcGxlbWVudGF0aW9uLgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCisgICAgICogQHJldHVybiB2YWx1ZSBUaGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHJlY29nbml6ZSB0aGUgYXR0cmlidXRlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBPYmplY3QgZ2V0QXR0cmlidXRlKFN0cmluZyBuYW1lKQorICAgICAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiA8cD5TZXQgYSBmZWF0dXJlIGZvciB0aGlzIDxjb2RlPkRvY3VtZW50QnVpbGRlckZhY3Rvcnk8L2NvZGU+IGFuZCA8Y29kZT5Eb2N1bWVudEJ1aWxkZXI8L2NvZGU+cyBjcmVhdGVkIGJ5IHRoaXMgZmFjdG9yeS48L3A+CisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBGZWF0dXJlIG5hbWVzIGFyZSBmdWxseSBxdWFsaWZpZWQge0BsaW5rIGphdmEubmV0LlVSSX1zLgorICAgICAqIEltcGxlbWVudGF0aW9ucyBtYXkgZGVmaW5lIHRoZWlyIG93biBmZWF0dXJlcy4KKyAgICAgKiBBbiB7QGxpbmsgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbn0gaXMgdGhyb3duIGlmIHRoaXMgPGNvZGU+RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTwvY29kZT4gb3IgdGhlCisgICAgICogPGNvZGU+RG9jdW1lbnRCdWlsZGVyPC9jb2RlPnMgaXQgY3JlYXRlcyBjYW5ub3Qgc3VwcG9ydCB0aGUgZmVhdHVyZS4KKyAgICAgKiBJdCBpcyBwb3NzaWJsZSBmb3IgYW4gPGNvZGU+RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTwvY29kZT4gdG8gZXhwb3NlIGEgZmVhdHVyZSB2YWx1ZSBidXQgYmUgdW5hYmxlIHRvIGNoYW5nZSBpdHMgc3RhdGUuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogPHA+CisgICAgICogQWxsIGltcGxlbWVudGF0aW9ucyBhcmUgcmVxdWlyZWQgdG8gc3VwcG9ydCB0aGUge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lOR30gZmVhdHVyZS4KKyAgICAgKiBXaGVuIHRoZSBmZWF0dXJlIGlzOjwvcD4KKyAgICAgKiA8dWw+CisgICAgICogICA8bGk+CisgICAgICogICAgIDxjb2RlPnRydWU8L2NvZGU+OiB0aGUgaW1wbGVtZW50YXRpb24gd2lsbCBsaW1pdCBYTUwgcHJvY2Vzc2luZyB0byBjb25mb3JtIHRvIGltcGxlbWVudGF0aW9uIGxpbWl0cy4KKyAgICAgKiAgICAgRXhhbXBsZXMgaW5jbHVkZSBlbnRpdHkgZXhwYW5zaW9uIGxpbWl0cyBhbmQgWE1MIFNjaGVtYSBjb25zdHJ1Y3RzIHRoYXQgd291bGQgY29uc3VtZSBsYXJnZSBhbW91bnRzIG9mIHJlc291cmNlcy4KKyAgICAgKiAgICAgSWYgWE1MIHByb2Nlc3NpbmcgaXMgbGltaXRlZCBmb3Igc2VjdXJpdHkgcmVhc29ucywgaXQgd2lsbCBiZSByZXBvcnRlZCB2aWEgYSBjYWxsIHRvIHRoZSByZWdpc3RlcmVkCisgICAgICogICAge0BsaW5rIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciNmYXRhbEVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbil9LgorICAgICAqICAgICBTZWUge0BsaW5rICBEb2N1bWVudEJ1aWxkZXIjc2V0RXJyb3JIYW5kbGVyKG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciBlcnJvckhhbmRsZXIpfS4KKyAgICAgKiAgIDwvbGk+CisgICAgICogICA8bGk+CisgICAgICogICAgIDxjb2RlPmZhbHNlPC9jb2RlPjogdGhlIGltcGxlbWVudGF0aW9uIHdpbGwgcHJvY2Vzc2luZyBYTUwgYWNjb3JkaW5nIHRvIHRoZSBYTUwgc3BlY2lmaWNhdGlvbnMgd2l0aG91dAorICAgICAqICAgICByZWdhcmQgdG8gcG9zc2libGUgaW1wbGVtZW50YXRpb24gbGltaXRzLgorICAgICAqICAgPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgRmVhdHVyZSBuYW1lLgorICAgICAqIEBwYXJhbSB2YWx1ZSBJcyBmZWF0dXJlIHN0YXRlIDxjb2RlPnRydWU8L2NvZGU+IG9yIDxjb2RlPmZhbHNlPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGlzIDxjb2RlPkRvY3VtZW50QnVpbGRlckZhY3Rvcnk8L2NvZGU+IG9yIHRoZSA8Y29kZT5Eb2N1bWVudEJ1aWxkZXI8L2NvZGU+cworICAgICAqICAgaXQgY3JlYXRlcyBjYW5ub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiB0aGUgPGNvZGU+bmFtZTwvY29kZT4gcGFyYW1ldGVyIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkKKyAgICAgICAgdGhyb3dzIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiA8cD5HZXQgdGhlIHN0YXRlIG9mIHRoZSBuYW1lZCBmZWF0dXJlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIEZlYXR1cmUgbmFtZXMgYXJlIGZ1bGx5IHF1YWxpZmllZCB7QGxpbmsgamF2YS5uZXQuVVJJfXMuCisgICAgICogSW1wbGVtZW50YXRpb25zIG1heSBkZWZpbmUgdGhlaXIgb3duIGZlYXR1cmVzLgorICAgICAqIEFuIHtAbGluayBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9ufSBpcyB0aHJvd24gaWYgdGhpcyA8Y29kZT5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5PC9jb2RlPiBvciB0aGUKKyAgICAgKiA8Y29kZT5Eb2N1bWVudEJ1aWxkZXI8L2NvZGU+cyBpdCBjcmVhdGVzIGNhbm5vdCBzdXBwb3J0IHRoZSBmZWF0dXJlLgorICAgICAqIEl0IGlzIHBvc3NpYmxlIGZvciBhbiA8Y29kZT5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5PC9jb2RlPiB0byBleHBvc2UgYSBmZWF0dXJlIHZhbHVlIGJ1dCBiZSB1bmFibGUgdG8gY2hhbmdlIGl0cyBzdGF0ZS4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBGZWF0dXJlIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFN0YXRlIG9mIHRoZSBuYW1lZCBmZWF0dXJlLgorICAgICAqCisgICAgICogQHRocm93cyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGlmIHRoaXMgPGNvZGU+RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTwvY29kZT4KKyAgICAgKiAgIG9yIHRoZSA8Y29kZT5Eb2N1bWVudEJ1aWxkZXI8L2NvZGU+cyBpdCBjcmVhdGVzIGNhbm5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKQorICAgICAgICB0aHJvd3MgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHtAbGluayBTY2hlbWF9IG9iamVjdCBzcGVjaWZpZWQgdGhyb3VnaAorICAgICAqIHRoZSB7QGxpbmsgI3NldFNjaGVtYShTY2hlbWEgc2NoZW1hKX0gbWV0aG9kLgorICAgICAqCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICBGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgd2hlbiBpbXBsZW1lbnRhdGlvbnMgZm9yCisgICAgICogICAgICBlYXJsaWVyIHZlcnNpb25zIG9mIEpBWFAgaXMgdXNlZCwgdGhpcyBleGNlcHRpb24gd2lsbCBiZQorICAgICAqICAgICAgdGhyb3duLgorICAgICAqCisgICAgICogQHJldHVybgorICAgICAqICAgICAgdGhlIHtAbGluayBTY2hlbWF9IG9iamVjdCB0aGF0IHdhcyBsYXN0IHNldCB0aHJvdWdoCisgICAgICogICAgICB0aGUge0BsaW5rICNzZXRTY2hlbWEoU2NoZW1hKX0gbWV0aG9kLCBvciBudWxsCisgICAgICogICAgICBpZiB0aGUgbWV0aG9kIHdhcyBub3QgaW52b2tlZCBzaW5jZSBhIHtAbGluayBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5fQorICAgICAqICAgICAgaXMgY3JlYXRlZC4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgU2NoZW1hIGdldFNjaGVtYSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICAgIlRoaXMgcGFyc2VyIGRvZXMgbm90IHN1cHBvcnQgc3BlY2lmaWNhdGlvbiBcIiIKKyAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVGl0bGUoKQorICAgICAgICAgICAgKyAiXCIgdmVyc2lvbiBcIiIKKyAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVmVyc2lvbigpCisgICAgICAgICAgICArICJcIiIKKyAgICAgICAgICAgICk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5TZXQgdGhlIHtAbGluayBTY2hlbWF9IHRvIGJlIHVzZWQgYnkgcGFyc2VycyBjcmVhdGVkCisgICAgICogZnJvbSB0aGlzIGZhY3RvcnkuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBXaGVuIGEge0BsaW5rIFNjaGVtYX0gaXMgbm9uLW51bGwsIGEgcGFyc2VyIHdpbGwgdXNlIGEgdmFsaWRhdG9yCisgICAgICogY3JlYXRlZCBmcm9tIGl0IHRvIHZhbGlkYXRlIGRvY3VtZW50cyBiZWZvcmUgaXQgcGFzc2VzIGluZm9ybWF0aW9uCisgICAgICogZG93biB0byB0aGUgYXBwbGljYXRpb24uCisgICAgICoKKyAgICAgKiA8cD5XaGVuIGVycm9ycyBhcmUgZm91bmQgYnkgdGhlIHZhbGlkYXRvciwgdGhlIHBhcnNlciBpcyByZXNwb25zaWJsZQorICAgICAqIHRvIHJlcG9ydCB0aGVtIHRvIHRoZSB1c2VyLXNwZWNpZmllZCB7QGxpbmsgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyfQorICAgICAqIChvciBpZiB0aGUgZXJyb3IgaGFuZGxlciBpcyBub3Qgc2V0LCBpZ25vcmUgdGhlbSBvciB0aHJvdyB0aGVtKSwganVzdAorICAgICAqIGxpa2UgYW55IG90aGVyIGVycm9ycyBmb3VuZCBieSB0aGUgcGFyc2VyIGl0c2VsZi4KKyAgICAgKiBJbiBvdGhlciB3b3JkcywgaWYgdGhlIHVzZXItc3BlY2lmaWVkIHtAbGluayBvcmcueG1sLnNheC5FcnJvckhhbmRsZXJ9CisgICAgICogaXMgc2V0LCBpdCBtdXN0IHJlY2VpdmUgdGhvc2UgZXJyb3JzLCBhbmQgaWYgbm90LCB0aGV5IG11c3QgYmUKKyAgICAgKiB0cmVhdGVkIGFjY29yZGluZyB0byB0aGUgaW1wbGVtZW50YXRpb24gc3BlY2lmaWMKKyAgICAgKiBkZWZhdWx0IGVycm9yIGhhbmRsaW5nIHJ1bGVzLgorICAgICAqCisgICAgICogPHA+CisgICAgICogQSB2YWxpZGF0b3IgbWF5IG1vZGlmeSB0aGUgb3V0Y29tZSBvZiBhIHBhcnNlIChmb3IgZXhhbXBsZSBieQorICAgICAqIGFkZGluZyBkZWZhdWx0IHZhbHVlcyB0aGF0IHdlcmUgbWlzc2luZyBpbiBkb2N1bWVudHMpLCBhbmQgYSBwYXJzZXIKKyAgICAgKiBpcyByZXNwb25zaWJsZSB0byBtYWtlIHN1cmUgdGhhdCB0aGUgYXBwbGljYXRpb24gd2lsbCByZWNlaXZlCisgICAgICogbW9kaWZpZWQgRE9NIHRyZWVzLgorICAgICAqCisgICAgICogPHA+CisgICAgICogSW5pdGlhbGx5LCBudWxsIGlzIHNldCBhcyB0aGUge0BsaW5rIFNjaGVtYX0uCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIHByb2Nlc3Npbmcgd2lsbCB0YWtlIGVmZmVjdCBldmVuIGlmCisgICAgICogdGhlIHtAbGluayAjaXNWYWxpZGF0aW5nKCl9IG1ldGhvZCByZXR1cm5zIDx0dD5mYWxzZTwvdHQ+LgorICAgICAqCisgICAgICogPHA+SXQgaXMgYW4gZXJyb3IgdG8gdXNlCisgICAgICogdGhlIDxjb2RlPmh0dHA6Ly9qYXZhLnN1bi5jb20veG1sL2pheHAvcHJvcGVydGllcy9zY2hlbWFTb3VyY2U8L2NvZGU+CisgICAgICogcHJvcGVydHkgYW5kL29yIHRoZSA8Y29kZT5odHRwOi8vamF2YS5zdW4uY29tL3htbC9qYXhwL3Byb3BlcnRpZXMvc2NoZW1hTGFuZ3VhZ2U8L2NvZGU+CisgICAgICogcHJvcGVydHkgaW4gY29uanVuY3Rpb24gd2l0aCBhIHtAbGluayBTY2hlbWF9IG9iamVjdC4KKyAgICAgKiBTdWNoIGNvbmZpZ3VyYXRpb24gd2lsbCBjYXVzZSBhIHtAbGluayBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9ufQorICAgICAqIGV4Y2VwdGlvbiB3aGVuIHRoZSB7QGxpbmsgI25ld0RvY3VtZW50QnVpbGRlcigpfSBpcyBpbnZva2VkLjwvcD4KKyAgICAgKgorICAgICAqCisgICAgICogPGg0Pk5vdGUgZm9yIGltcGxlbWVudG9yczwvaDQ+CisgICAgICogPHA+CisgICAgICogQSBwYXJzZXIgbXVzdCBiZSBhYmxlIHRvIHdvcmsgd2l0aCBhbnkge0BsaW5rIFNjaGVtYX0KKyAgICAgKiBpbXBsZW1lbnRhdGlvbi4gSG93ZXZlciwgcGFyc2VycyBhbmQgc2NoZW1hcyBhcmUgYWxsb3dlZAorICAgICAqIHRvIHVzZSBpbXBsZW1lbnRhdGlvbi1zcGVjaWZpYyBjdXN0b20gbWVjaGFuaXNtcworICAgICAqIGFzIGxvbmcgYXMgdGhleSB5aWVsZCB0aGUgcmVzdWx0IGRlc2NyaWJlZCBpbiB0aGUgc3BlY2lmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzY2hlbWEgPGNvZGU+U2NoZW1hPC9jb2RlPiB0byB1c2Ugb3IgPGNvZGU+bnVsbDwvY29kZT4gdG8gcmVtb3ZlIGEgc2NoZW1hLgorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgRm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHdoZW4gaW1wbGVtZW50YXRpb25zIGZvcgorICAgICAqICAgICAgZWFybGllciB2ZXJzaW9ucyBvZiBKQVhQIGlzIHVzZWQsIHRoaXMgZXhjZXB0aW9uIHdpbGwgYmUKKyAgICAgKiAgICAgIHRocm93bi4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTY2hlbWEoU2NoZW1hIHNjaGVtYSkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgICAiVGhpcyBwYXJzZXIgZG9lcyBub3Qgc3VwcG9ydCBzcGVjaWZpY2F0aW9uIFwiIgorICAgICAgICAgICAgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25UaXRsZSgpCisgICAgICAgICAgICArICJcIiB2ZXJzaW9uIFwiIgorICAgICAgICAgICAgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25WZXJzaW9uKCkKKyAgICAgICAgICAgICsgIlwiIgorICAgICAgICAgICAgKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5TZXQgc3RhdGUgb2YgWEluY2x1ZGUgcHJvY2Vzc2luZy48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiBYSW5jbHVkZSBtYXJrdXAgaXMgZm91bmQgaW4gdGhlIGRvY3VtZW50IGluc3RhbmNlLCBzaG91bGQgaXQgYmUKKyAgICAgKiBwcm9jZXNzZWQgYXMgc3BlY2lmaWVkIGluIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hpbmNsdWRlLyI+CisgICAgICogWE1MIEluY2x1c2lvbnMgKFhJbmNsdWRlKSBWZXJzaW9uIDEuMDwvYT4uPC9wPgorICAgICAqCisgICAgICogPHA+WEluY2x1ZGUgcHJvY2Vzc2luZyBkZWZhdWx0cyB0byA8Y29kZT5mYWxzZTwvY29kZT4uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHN0YXRlIFNldCBYSW5jbHVkZSBwcm9jZXNzaW5nIHRvIDxjb2RlPnRydWU8L2NvZGU+IG9yCisgICAgICogICA8Y29kZT5mYWxzZTwvY29kZT4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB3aGVuIGltcGxlbWVudGF0aW9ucyBmb3IKKyAgICAgKiAgICAgIGVhcmxpZXIgdmVyc2lvbnMgb2YgSkFYUCBpcyB1c2VkLCB0aGlzIGV4Y2VwdGlvbiB3aWxsIGJlCisgICAgICogICAgICB0aHJvd24uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0WEluY2x1ZGVBd2FyZShmaW5hbCBib29sZWFuIHN0YXRlKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICJUaGlzIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHNwZWNpZmljYXRpb24gXCIiCisgICAgICAgICAgICArIHRoaXMuZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkuZ2V0U3BlY2lmaWNhdGlvblRpdGxlKCkKKyAgICAgICAgICAgICsgIlwiIHZlcnNpb24gXCIiCisgICAgICAgICAgICArIHRoaXMuZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkuZ2V0U3BlY2lmaWNhdGlvblZlcnNpb24oKQorICAgICAgICAgICAgKyAiXCIiCisgICAgICAgICAgICApOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkdldCBzdGF0ZSBvZiBYSW5jbHVkZSBwcm9jZXNzaW5nLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gY3VycmVudCBzdGF0ZSBvZiBYSW5jbHVkZSBwcm9jZXNzaW5nCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICBGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgd2hlbiBpbXBsZW1lbnRhdGlvbnMgZm9yCisgICAgICogICAgICBlYXJsaWVyIHZlcnNpb25zIG9mIEpBWFAgaXMgdXNlZCwgdGhpcyBleGNlcHRpb24gd2lsbCBiZQorICAgICAqICAgICAgdGhyb3duLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzWEluY2x1ZGVBd2FyZSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICAgIlRoaXMgcGFyc2VyIGRvZXMgbm90IHN1cHBvcnQgc3BlY2lmaWNhdGlvbiBcIiIKKyAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVGl0bGUoKQorICAgICAgICAgICAgKyAiXCIgdmVyc2lvbiBcIiIKKyAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVmVyc2lvbigpCisgICAgICAgICAgICArICJcIiIKKyAgICAgICAgICAgICk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9wYXJzZXJzL0ZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvcGFyc2Vycy9GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzQ1NTU5YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvcGFyc2Vycy9GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yLmphdmEKQEAgLTAsMCArMSwxMTkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLyAkSWQ6IEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IuamF2YSA1Njk5ODAgMjAwNy0wOC0yNyAwMzo1ODoxNVogbXJnbGF2YXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC5wYXJzZXJzOworCisvKioKKyAqIFRocm93biB3aGVuIGEgcHJvYmxlbSB3aXRoIGNvbmZpZ3VyYXRpb24gd2l0aCB0aGUgUGFyc2VyIEZhY3RvcmllcworICogZXhpc3RzLiBUaGlzIGVycm9yIHdpbGwgdHlwaWNhbGx5IGJlIHRocm93biB3aGVuIHRoZSBjbGFzcyBvZiBhCisgKiBwYXJzZXIgZmFjdG9yeSBzcGVjaWZpZWQgaW4gdGhlIHN5c3RlbSBwcm9wZXJ0aWVzIGNhbm5vdCBiZSBmb3VuZAorICogb3IgaW5zdGFudGlhdGVkLgorICoKKyAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgorICogQHZlcnNpb24gJFJldmlzaW9uOiA1Njk5ODAgJCwgJERhdGU6IDIwMDctMDgtMjYgMjA6NTg6MTUgLTA3MDAgKFN1biwgMjYgQXVnIDIwMDcpICQKKyAqLworCitwdWJsaWMgY2xhc3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBleHRlbmRzIEVycm9yIHsKKworICAgIC8qKgorICAgICAqPGNvZGU+RXhjZXB0aW9uPC9jb2RlPiB0aGF0IHJlcHJlc2VudHMgdGhlIGVycm9yLgorICAgICAqLworICAgIHByaXZhdGUgRXhjZXB0aW9uIGV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yPC9jb2RlPiB3aXRoIG5vCisgICAgICogZGV0YWlsIG1lc3NhZ2UuCisgICAgICovCisKKyAgICBwdWJsaWMgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcigpIHsKKyAgICAgICAgdGhpcy5leGNlcHRpb24gPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yPC9jb2RlPiB3aXRoCisgICAgICogdGhlIDxjb2RlPlN0cmluZyA8L2NvZGU+IHNwZWNpZmllZCBhcyBhbiBlcnJvciBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZyBUaGUgZXJyb3IgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKi8KKworICAgIHB1YmxpYyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKFN0cmluZyBtc2cpIHsKKyAgICAgICAgc3VwZXIobXNnKTsKKyAgICAgICAgdGhpcy5leGNlcHRpb24gPSBudWxsOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPkZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3I8L2NvZGU+IHdpdGggYQorICAgICAqIGdpdmVuIDxjb2RlPkV4Y2VwdGlvbjwvY29kZT4gYmFzZSBjYXVzZSBvZiB0aGUgZXJyb3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZSBUaGUgZXhjZXB0aW9uIHRvIGJlIGVuY2Fwc3VsYXRlZCBpbiBhCisgICAgICogRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvci4KKyAgICAgKi8KKworICAgIHB1YmxpYyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHN1cGVyKGUudG9TdHJpbmcoKSk7CisgICAgICAgIHRoaXMuZXhjZXB0aW9uID0gZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+RmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjwvY29kZT4gd2l0aCB0aGUKKyAgICAgKiBnaXZlbiA8Y29kZT5FeGNlcHRpb248L2NvZGU+IGJhc2UgY2F1c2UgYW5kIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGUgVGhlIGV4Y2VwdGlvbiB0byBiZSBlbmNhcHN1bGF0ZWQgaW4gYQorICAgICAqIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IKKyAgICAgKiBAcGFyYW0gbXNnIFRoZSBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKworICAgIHB1YmxpYyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKEV4Y2VwdGlvbiBlLCBTdHJpbmcgbXNnKSB7CisgICAgICAgIHN1cGVyKG1zZyk7CisgICAgICAgIHRoaXMuZXhjZXB0aW9uID0gZTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbWVzc2FnZSAoaWYgYW55KSBmb3IgdGhpcyBlcnJvciAuIElmIHRoZXJlIGlzIG5vCisgICAgICogbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbiBhbmQgdGhlcmUgaXMgYW4gZW5jYXBzdWxhdGVkCisgICAgICogZXhjZXB0aW9uIHRoZW4gdGhlIG1lc3NhZ2Ugb2YgdGhhdCBleGNlcHRpb24sIGlmIGl0IGV4aXN0cyB3aWxsIGJlCisgICAgICogcmV0dXJuZWQuIEVsc2UgdGhlIG5hbWUgb2YgdGhlIGVuY2Fwc3VsYXRlZCBleGNlcHRpb24gd2lsbCBiZQorICAgICAqIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgZXJyb3IgbWVzc2FnZS4KKyAgICAgKi8KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSAoKSB7CisgICAgICAgIFN0cmluZyBtZXNzYWdlID0gc3VwZXIuZ2V0TWVzc2FnZSAoKTsKKworICAgICAgICBpZiAobWVzc2FnZSA9PSBudWxsICYmIGV4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZXhjZXB0aW9uLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBtZXNzYWdlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgYWN0dWFsIGV4Y2VwdGlvbiAoaWYgYW55KSB0aGF0IGNhdXNlZCB0aGlzIGV4Y2VwdGlvbiB0bworICAgICAqIGJlIHJhaXNlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIGVuY2Fwc3VsYXRlZCBleGNlcHRpb24sIG9yIG51bGwgaWYgdGhlcmUgaXMgbm9uZS4KKyAgICAgKi8KKworICAgIHB1YmxpYyBFeGNlcHRpb24gZ2V0RXhjZXB0aW9uICgpIHsKKyAgICAgICAgcmV0dXJuIGV4Y2VwdGlvbjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3BhcnNlcnMvRmlsZVBhdGhUb1VSSS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9wYXJzZXJzL0ZpbGVQYXRoVG9VUkkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZmYzOGMxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9wYXJzZXJzL0ZpbGVQYXRoVG9VUkkuamF2YQpAQCAtMCwwICsxLDEyOSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgamF2YXgueG1sLnBhcnNlcnM7CisKK2NsYXNzIEZpbGVQYXRoVG9VUkkgeworCisgICAgLy8gd2hpY2ggQVNDSUkgY2hhcmFjdGVycyBuZWVkIHRvIGJlIGVzY2FwZWQKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGdOZWVkRXNjYXBpbmdbXSA9IG5ldyBib29sZWFuWzEyOF07CisgICAgLy8gdGhlIGZpcnN0IGhleCBjaGFyYWN0ZXIgaWYgYSBjaGFyYWN0ZXIgbmVlZHMgdG8gYmUgZXNjYXBlZAorICAgIHByaXZhdGUgc3RhdGljIGNoYXJbXSBnQWZ0ZXJFc2NhcGluZzEgPSBuZXcgY2hhclsxMjhdOworICAgIC8vIHRoZSBzZWNvbmQgaGV4IGNoYXJhY3RlciBpZiBhIGNoYXJhY3RlciBuZWVkcyB0byBiZSBlc2NhcGVkCisgICAgcHJpdmF0ZSBzdGF0aWMgY2hhcltdIGdBZnRlckVzY2FwaW5nMiA9IG5ldyBjaGFyWzEyOF07CisgICAgcHJpdmF0ZSBzdGF0aWMgY2hhcltdIGdIZXhDaHMgPSB7JzAnLCAnMScsICcyJywgJzMnLCAnNCcsICc1JywgJzYnLCAnNycsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzgnLCAnOScsICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRid9OworICAgIC8vIGluaXRpYWxpemUgdGhlIGFib3ZlIDMgYXJyYXlzCisgICAgc3RhdGljIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gMHgxZjsgaSsrKSB7CisgICAgICAgICAgICBnTmVlZEVzY2FwaW5nW2ldID0gdHJ1ZTsKKyAgICAgICAgICAgIGdBZnRlckVzY2FwaW5nMVtpXSA9IGdIZXhDaHNbaSA+PiA0XTsKKyAgICAgICAgICAgIGdBZnRlckVzY2FwaW5nMltpXSA9IGdIZXhDaHNbaSAmIDB4Zl07CisgICAgICAgIH0KKyAgICAgICAgZ05lZWRFc2NhcGluZ1sweDdmXSA9IHRydWU7CisgICAgICAgIGdBZnRlckVzY2FwaW5nMVsweDdmXSA9ICc3JzsKKyAgICAgICAgZ0FmdGVyRXNjYXBpbmcyWzB4N2ZdID0gJ0YnOworICAgICAgICBjaGFyW10gZXNjQ2hzID0geycgJywgJzwnLCAnPicsICcjJywgJyUnLCAnIicsICd7JywgJ30nLAorICAgICAgICAgICAgICAgICAgICAgICAgICd8JywgJ1xcJywgJ14nLCAnficsICdbJywgJ10nLCAnYCd9OworICAgICAgICBpbnQgbGVuID0gZXNjQ2hzLmxlbmd0aDsKKyAgICAgICAgY2hhciBjaDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgICAgICAgY2ggPSBlc2NDaHNbaV07CisgICAgICAgICAgICBnTmVlZEVzY2FwaW5nW2NoXSA9IHRydWU7CisgICAgICAgICAgICBnQWZ0ZXJFc2NhcGluZzFbY2hdID0gZ0hleENoc1tjaCA+PiA0XTsKKyAgICAgICAgICAgIGdBZnRlckVzY2FwaW5nMltjaF0gPSBnSGV4Q2hzW2NoICYgMHhmXTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRvIGVzY2FwZSBhIGZpbGUgcGF0aCB0byBhIFVSSSwgYnkgdXNpbmcgJUhIIHRvIHJlcHJlc2VudAorICAgIC8vIHNwZWNpYWwgQVNDSUkgY2hhcmFjdGVyczogMHgwMH4weDFGLCAweDdGLCAnICcsICc8JywgJz4nLCAnIycsICclJworICAgIC8vIGFuZCAnIicgYW5kIG5vbi1BU0NJSSBjaGFyYWN0ZXJzICh3aG9zZSB2YWx1ZSA+PSAxMjgpLgorICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGZpbGVwYXRoMlVSSShTdHJpbmcgcGF0aCl7CisgICAgICAgIC8vIHJldHVybiBudWxsIGlmIHBhdGggaXMgbnVsbC4KKyAgICAgICAgaWYgKHBhdGggPT0gbnVsbCkKKyAgICAgICAgICAgIHJldHVybiBudWxsOworCisgICAgICAgIGNoYXIgc2VwYXJhdG9yID0gamF2YS5pby5GaWxlLnNlcGFyYXRvckNoYXI7CisgICAgICAgIHBhdGggPSBwYXRoLnJlcGxhY2Uoc2VwYXJhdG9yLCAnLycpOworCisgICAgICAgIGludCBsZW4gPSBwYXRoLmxlbmd0aCgpLCBjaDsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVpbGRlcihsZW4qMyk7CisgICAgICAgIGJ1ZmZlci5hcHBlbmQoImZpbGU6Ly8iKTsKKyAgICAgICAgLy8gY2hhbmdlIEM6L2JsYWggdG8gL0M6L2JsYWgKKyAgICAgICAgaWYgKGxlbiA+PSAyICYmIHBhdGguY2hhckF0KDEpID09ICc6JykgeworICAgICAgICAgICAgY2ggPSBDaGFyYWN0ZXIudG9VcHBlckNhc2UocGF0aC5jaGFyQXQoMCkpOworICAgICAgICAgICAgaWYgKGNoID49ICdBJyAmJiBjaCA8PSAnWicpIHsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcvJyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBmb3IgZWFjaCBjaGFyYWN0ZXIgaW4gdGhlIHBhdGgKKyAgICAgICAgaW50IGkgPSAwOworICAgICAgICBmb3IgKDsgaSA8IGxlbjsgaSsrKSB7CisgICAgICAgICAgICBjaCA9IHBhdGguY2hhckF0KGkpOworICAgICAgICAgICAgLy8gaWYgaXQncyBub3QgYW4gQVNDSUkgY2hhcmFjdGVyLCBicmVhayBoZXJlLCBhbmQgdXNlIFVURi04IGVuY29kaW5nCisgICAgICAgICAgICBpZiAoY2ggPj0gMTI4KQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgaWYgKGdOZWVkRXNjYXBpbmdbY2hdKSB7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnJScpOworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZ0FmdGVyRXNjYXBpbmcxW2NoXSk7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnQWZ0ZXJFc2NhcGluZzJbY2hdKTsKKyAgICAgICAgICAgICAgICAvLyByZWNvcmQgdGhlIGZhY3QgdGhhdCBpdCdzIGVzY2FwZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoKGNoYXIpY2gpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gd2Ugc2F3IHNvbWUgbm9uLWFzY2lpIGNoYXJhY3RlcgorICAgICAgICBpZiAoaSA8IGxlbikgeworICAgICAgICAgICAgLy8gZ2V0IFVURi04IGJ5dGVzIGZvciB0aGUgcmVtYWluaW5nIHN1Yi1zdHJpbmcKKyAgICAgICAgICAgIGJ5dGVbXSBieXRlcyA9IG51bGw7CisgICAgICAgICAgICBieXRlIGI7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGJ5dGVzID0gcGF0aC5zdWJzdHJpbmcoaSkuZ2V0Qnl0ZXMoIlVURi04Iik7CisgICAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIHNob3VsZCBuZXZlciBoYXBwZW4KKyAgICAgICAgICAgICAgICByZXR1cm4gcGF0aDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGxlbiA9IGJ5dGVzLmxlbmd0aDsKKworICAgICAgICAgICAgLy8gZm9yIGVhY2ggYnl0ZQorICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisgICAgICAgICAgICAgICAgYiA9IGJ5dGVzW2ldOworICAgICAgICAgICAgICAgIC8vIGZvciBub24tYXNjaWkgY2hhcmFjdGVyOiBtYWtlIGl0IHBvc2l0aXZlLCB0aGVuIGVzY2FwZQorICAgICAgICAgICAgICAgIGlmIChiIDwgMCkgeworICAgICAgICAgICAgICAgICAgICBjaCA9IGIgKyAyNTY7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJyUnKTsKKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnSGV4Q2hzW2NoID4+IDRdKTsKKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnSGV4Q2hzW2NoICYgMHhmXSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UgaWYgKGdOZWVkRXNjYXBpbmdbYl0pIHsKKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnJScpOworICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGdBZnRlckVzY2FwaW5nMVtiXSk7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZ0FmdGVyRXNjYXBpbmcyW2JdKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoKGNoYXIpYik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZygpOworICAgIH0KKworfS8vRmlsZVBhdGhUb1VSSQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9wYXJzZXJzL1BhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvcGFyc2Vycy9QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjkyOWFiNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvcGFyc2Vycy9QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1MSBAQAorCisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8gJElkOiBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLmphdmEgNTY5OTgxIDIwMDctMDgtMjcgMDM6NTk6MDdaIG1yZ2xhdmFzICQKKworcGFja2FnZSBqYXZheC54bWwucGFyc2VyczsKKworLyoqCisgKiBJbmRpY2F0ZXMgYSBzZXJpb3VzIGNvbmZpZ3VyYXRpb24gZXJyb3IuCisgKgorICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86SmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDU2OTk4MSAkLCAkRGF0ZTogMjAwNy0wOC0yNiAyMDo1OTowNyAtMDcwMCAoU3VuLCAyNiBBdWcgMjAwNykgJAorICovCisKK3B1YmxpYyBjbGFzcyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uPC9jb2RlPiB3aXRoIG5vCisgICAgICogZGV0YWlsIG1lc3NhZ2UuCisgICAgICovCisKKyAgICBwdWJsaWMgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+UGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjwvY29kZT4gd2l0aAorICAgICAqIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHNwZWNpZmllZCBhcyBhbiBlcnJvciBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZyBUaGUgZXJyb3IgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKi8KKworICAgIHB1YmxpYyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKKyAgICAgICAgc3VwZXIobXNnKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvcGFyc2Vycy9TQVhQYXJzZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvcGFyc2Vycy9TQVhQYXJzZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOTQzMDFmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9wYXJzZXJzL1NBWFBhcnNlci5qYXZhCkBAIC0wLDAgKzEsNTI0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8gJElkOiBTQVhQYXJzZXIuamF2YSA1ODQ0ODMgMjAwNy0xMC0xNCAwMjo1NDo0OFogbXJnbGF2YXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC5wYXJzZXJzOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZheC54bWwudmFsaWRhdGlvbi5TY2hlbWE7CitpbXBvcnQgb3JnLnhtbC5zYXguSGFuZGxlckJhc2U7CitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CitpbXBvcnQgb3JnLnhtbC5zYXguUGFyc2VyOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcjsKKworCisvKioKKyAqIERlZmluZXMgdGhlIEFQSSB0aGF0IHdyYXBzIGFuIHtAbGluayBvcmcueG1sLnNheC5YTUxSZWFkZXJ9CisgKiBpbXBsZW1lbnRhdGlvbiBjbGFzcy4gSW4gSkFYUCAxLjAsIHRoaXMgY2xhc3Mgd3JhcHBlZCB0aGUKKyAqIHtAbGluayBvcmcueG1sLnNheC5QYXJzZXJ9IGludGVyZmFjZSwgaG93ZXZlciB0aGlzIGludGVyZmFjZSB3YXMKKyAqIHJlcGxhY2VkIGJ5IHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyfS4gRm9yIGVhc2UKKyAqIG9mIHRyYW5zaXRpb24sIHRoaXMgY2xhc3MgY29udGludWVzIHRvIHN1cHBvcnQgdGhlIHNhbWUgbmFtZQorICogYW5kIGludGVyZmFjZSBhcyB3ZWxsIGFzIHN1cHBvcnRpbmcgbmV3IG1ldGhvZHMuCisgKgorICogQW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBjYW4gYmUgb2J0YWluZWQgZnJvbSB0aGUKKyAqIHtAbGluayBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5I25ld1NBWFBhcnNlcigpfSBtZXRob2QuCisgKiBPbmNlIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgaXMgb2J0YWluZWQsIFhNTCBjYW4gYmUgcGFyc2VkIGZyb20KKyAqIGEgdmFyaWV0eSBvZiBpbnB1dCBzb3VyY2VzLiBUaGVzZSBpbnB1dCBzb3VyY2VzIGFyZSBJbnB1dFN0cmVhbXMsCisgKiBGaWxlcywgVVJMcywgYW5kIFNBWCBJbnB1dFNvdXJjZXMuPHA+CisgKgorICogVGhpcyBzdGF0aWMgbWV0aG9kIGNyZWF0ZXMgYSBuZXcgZmFjdG9yeSBpbnN0YW5jZSBiYXNlZAorICogb24gYSBzeXN0ZW0gcHJvcGVydHkgc2V0dGluZyBvciB1c2VzIHRoZSBwbGF0Zm9ybSBkZWZhdWx0CisgKiBpZiBubyBwcm9wZXJ0eSBoYXMgYmVlbiBkZWZpbmVkLjxwPgorICoKKyAqIFRoZSBzeXN0ZW0gcHJvcGVydHkgdGhhdCBjb250cm9scyB3aGljaCBGYWN0b3J5IGltcGxlbWVudGF0aW9uCisgKiB0byBjcmVhdGUgaXMgbmFtZWQgPGNvZGU+JnF1b3Q7amF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeSZxdW90OzwvY29kZT4uCisgKiBUaGlzIHByb3BlcnR5IG5hbWVzIGEgY2xhc3MgdGhhdCBpcyBhIGNvbmNyZXRlIHN1YmNsYXNzIG9mIHRoaXMKKyAqIGFic3RyYWN0IGNsYXNzLiBJZiBubyBwcm9wZXJ0eSBpcyBkZWZpbmVkLCBhIHBsYXRmb3JtIGRlZmF1bHQKKyAqIHdpbGwgYmUgdXNlZC48L3A+CisgKgorICogQXMgdGhlIGNvbnRlbnQgaXMgcGFyc2VkIGJ5IHRoZSB1bmRlcmx5aW5nIHBhcnNlciwgbWV0aG9kcyBvZiB0aGUKKyAqIGdpdmVuIHtAbGluayBvcmcueG1sLnNheC5IYW5kbGVyQmFzZX0gb3IgdGhlCisgKiB7QGxpbmsgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcn0gYXJlIGNhbGxlZC48cD4KKyAqCisgKiBJbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBjbGFzcyB3aGljaCB3cmFwIGFuIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24KKyAqIGNhbiBjb25zaWRlciB1c2luZyB0aGUge0BsaW5rIG9yZy54bWwuc2F4LmhlbHBlcnMuUGFyc2VyQWRhcHRlcn0KKyAqIGNsYXNzIHRvIGluaXRpYWxseSBhZGFwdCB0aGVpciBTQVgxIGltcGxlbWVudGF0aW9uIHRvIHdvcmsgdW5kZXIKKyAqIHRoaXMgcmV2aXNlZCBjbGFzcy4KKyAqCisgKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogNTg0NDgzICQsICREYXRlOiAyMDA3LTEwLTEzIDE5OjU0OjQ4IC0wNzAwIChTYXQsIDEzIE9jdCAyMDA3KSAkCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTQVhQYXJzZXIgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVRyA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogPHA+UHJvdGVjdGVkIGNvbnN0cnVjdG9yIHRvIHByZXZlbnQgaW5zdGFudGlhdGlvbi4KKyAgICAgKiBVc2Uge0BsaW5rIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnkjbmV3U0FYUGFyc2VyKCl9LjwvcD4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU0FYUGFyc2VyICgpIHsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlJlc2V0IHRoaXMgPGNvZGU+U0FYUGFyc2VyPC9jb2RlPiB0byBpdHMgb3JpZ2luYWwgY29uZmlndXJhdGlvbi48L3A+CisgICAgICoKKyAgICAgKiA8cD48Y29kZT5TQVhQYXJzZXI8L2NvZGU+IGlzIHJlc2V0IHRvIHRoZSBzYW1lIHN0YXRlIGFzIHdoZW4gaXQgd2FzIGNyZWF0ZWQgd2l0aAorICAgICAqIHtAbGluayBTQVhQYXJzZXJGYWN0b3J5I25ld1NBWFBhcnNlcigpfS4KKyAgICAgKiA8Y29kZT5yZXNldCgpPC9jb2RlPiBpcyBkZXNpZ25lZCB0byBhbGxvdyB0aGUgcmV1c2Ugb2YgZXhpc3RpbmcgPGNvZGU+U0FYUGFyc2VyPC9jb2RlPnMKKyAgICAgKiB0aHVzIHNhdmluZyByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBjcmVhdGlvbiBvZiBuZXcgPGNvZGU+U0FYUGFyc2VyPC9jb2RlPnMuPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIHJlc2V0IDxjb2RlPlNBWFBhcnNlcjwvY29kZT4gaXMgbm90IGd1YXJhbnRlZWQgdG8gaGF2ZSB0aGUgc2FtZSB7QGxpbmsgU2NoZW1hfQorICAgICAqIDxjb2RlPk9iamVjdDwvY29kZT4sIGUuZy4ge0BsaW5rIE9iamVjdCNlcXVhbHMoT2JqZWN0IG9iail9LiAgSXQgaXMgZ3VhcmFudGVlZCB0byBoYXZlIGEgZnVuY3Rpb25hbGx5IGVxdWFsCisgICAgICogPGNvZGU+U2NoZW1hPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB7CisKKyAgICAgICAgLy8gaW1wbGVtZW50b3JzIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgICAiVGhpcyBTQVhQYXJzZXIsIFwiIiArIHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiXCIsIGRvZXMgbm90IHN1cHBvcnQgdGhlIHJlc2V0IGZ1bmN0aW9uYWxpdHkuIgorICAgICAgICAgICAgKyAiICBTcGVjaWZpY2F0aW9uIFwiIiArIHRoaXMuZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkuZ2V0U3BlY2lmaWNhdGlvblRpdGxlKCkgKyAiXCIiCisgICAgICAgICAgICArICIgdmVyc2lvbiBcIiIgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25WZXJzaW9uKCkgKyAiXCIiCisgICAgICAgICAgICApOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlBhcnNlIHRoZSBjb250ZW50IG9mIHRoZSBnaXZlbiB7QGxpbmsgamF2YS5pby5JbnB1dFN0cmVhbX0KKyAgICAgKiBpbnN0YW5jZSBhcyBYTUwgdXNpbmcgdGhlIHNwZWNpZmllZCB7QGxpbmsgb3JnLnhtbC5zYXguSGFuZGxlckJhc2V9LgorICAgICAqIDxpPiBVc2Ugb2YgdGhlIERlZmF1bHRIYW5kbGVyIHZlcnNpb24gb2YgdGhpcyBtZXRob2QgaXMgcmVjb21tZW5kZWQgYXMKKyAgICAgKiB0aGUgSGFuZGxlckJhc2UgY2xhc3MgaGFzIGJlZW4gZGVwcmVjYXRlZCBpbiBTQVggMi4wPC9pPi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaXMgSW5wdXRTdHJlYW0gY29udGFpbmluZyB0aGUgY29udGVudCB0byBiZSBwYXJzZWQuCisgICAgICogQHBhcmFtIGhiIFRoZSBTQVggSGFuZGxlckJhc2UgdG8gdXNlLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIGdpdmVuIElucHV0U3RyZWFtIGlzIG51bGwuCisgICAgICogQHRocm93cyBTQVhFeGNlcHRpb24gSWYgcGFyc2UgcHJvZHVjZXMgYSBTQVggZXJyb3IuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbiBJTyBlcnJvciBvY2N1cnMgaW50ZXJhY3Rpbmcgd2l0aCB0aGUKKyAgICAgKiAgIDxjb2RlPklucHV0U3RyZWFtPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTdHJlYW0gaXMsIEhhbmRsZXJCYXNlIGhiKQorICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnB1dFN0cmVhbSBjYW5ub3QgYmUgbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgSW5wdXRTb3VyY2UgaW5wdXQgPSBuZXcgSW5wdXRTb3VyY2UoaXMpOworICAgICAgICB0aGlzLnBhcnNlKGlucHV0LCBoYik7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+UGFyc2UgdGhlIGNvbnRlbnQgb2YgdGhlIGdpdmVuIHtAbGluayBqYXZhLmlvLklucHV0U3RyZWFtfQorICAgICAqIGluc3RhbmNlIGFzIFhNTCB1c2luZyB0aGUgc3BlY2lmaWVkIHtAbGluayBvcmcueG1sLnNheC5IYW5kbGVyQmFzZX0uCisgICAgICogPGk+IFVzZSBvZiB0aGUgRGVmYXVsdEhhbmRsZXIgdmVyc2lvbiBvZiB0aGlzIG1ldGhvZCBpcyByZWNvbW1lbmRlZCBhcworICAgICAqIHRoZSBIYW5kbGVyQmFzZSBjbGFzcyBoYXMgYmVlbiBkZXByZWNhdGVkIGluIFNBWCAyLjA8L2k+LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpcyBJbnB1dFN0cmVhbSBjb250YWluaW5nIHRoZSBjb250ZW50IHRvIGJlIHBhcnNlZC4KKyAgICAgKiBAcGFyYW0gaGIgVGhlIFNBWCBIYW5kbGVyQmFzZSB0byB1c2UuCisgICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW1JZCB3aGljaCBpcyBuZWVkZWQgZm9yIHJlc29sdmluZyByZWxhdGl2ZSBVUklzLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIGdpdmVuIDxjb2RlPklucHV0U3RyZWFtPC9jb2RlPiBpcworICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbnkgSU8gZXJyb3Igb2NjdXJzIGludGVyYWN0aW5nIHdpdGggdGhlCisgICAgICogICA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4uCisgICAgICogQHRocm93cyBTQVhFeGNlcHRpb24gSWYgYW55IFNBWCBlcnJvcnMgb2NjdXIgZHVyaW5nIHByb2Nlc3NpbmcuCisgICAgICoKKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciB2ZXJzaW9uIG9mIHRoaXMgbWV0aG9kIGluc3RlYWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcGFyc2UoCisgICAgICAgIElucHV0U3RyZWFtIGlzLAorICAgICAgICBIYW5kbGVyQmFzZSBoYiwKKyAgICAgICAgU3RyaW5nIHN5c3RlbUlkKQorICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnB1dFN0cmVhbSBjYW5ub3QgYmUgbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgSW5wdXRTb3VyY2UgaW5wdXQgPSBuZXcgSW5wdXRTb3VyY2UoaXMpOworICAgICAgICBpbnB1dC5zZXRTeXN0ZW1JZChzeXN0ZW1JZCk7CisgICAgICAgIHRoaXMucGFyc2UoaW5wdXQsIGhiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSB0aGUgY29udGVudCBvZiB0aGUgZ2l2ZW4ge0BsaW5rIGphdmEuaW8uSW5wdXRTdHJlYW19CisgICAgICogaW5zdGFuY2UgYXMgWE1MIHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXMgSW5wdXRTdHJlYW0gY29udGFpbmluZyB0aGUgY29udGVudCB0byBiZSBwYXJzZWQuCisgICAgICogQHBhcmFtIGRoIFRoZSBTQVggRGVmYXVsdEhhbmRsZXIgdG8gdXNlLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIGdpdmVuIElucHV0U3RyZWFtIGlzIG51bGwuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbnkgSU8gZXJyb3JzIG9jY3VyLgorICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIElmIGFueSBTQVggZXJyb3JzIG9jY3VyIGR1cmluZyBwcm9jZXNzaW5nLgorICAgICAqCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwYXJzZShJbnB1dFN0cmVhbSBpcywgRGVmYXVsdEhhbmRsZXIgZGgpCisgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklucHV0U3RyZWFtIGNhbm5vdCBiZSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dCA9IG5ldyBJbnB1dFNvdXJjZShpcyk7CisgICAgICAgIHRoaXMucGFyc2UoaW5wdXQsIGRoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSB0aGUgY29udGVudCBvZiB0aGUgZ2l2ZW4ge0BsaW5rIGphdmEuaW8uSW5wdXRTdHJlYW19CisgICAgICogaW5zdGFuY2UgYXMgWE1MIHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXMgSW5wdXRTdHJlYW0gY29udGFpbmluZyB0aGUgY29udGVudCB0byBiZSBwYXJzZWQuCisgICAgICogQHBhcmFtIGRoIFRoZSBTQVggRGVmYXVsdEhhbmRsZXIgdG8gdXNlLgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtSWQgd2hpY2ggaXMgbmVlZGVkIGZvciByZXNvbHZpbmcgcmVsYXRpdmUgVVJJcy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSBnaXZlbiBJbnB1dFN0cmVhbSBpcyBudWxsLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgYW55IElPIGVycm9ycyBvY2N1ci4KKyAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhbnkgU0FYIGVycm9ycyBvY2N1ciBkdXJpbmcgcHJvY2Vzc2luZy4KKyAgICAgKgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyIHZlcnNpb24gb2YgdGhpcyBtZXRob2QgaW5zdGVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwYXJzZSgKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMsCisgICAgICAgIERlZmF1bHRIYW5kbGVyIGRoLAorICAgICAgICBTdHJpbmcgc3lzdGVtSWQpCisgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklucHV0U3RyZWFtIGNhbm5vdCBiZSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dCA9IG5ldyBJbnB1dFNvdXJjZShpcyk7CisgICAgICAgIGlucHV0LnNldFN5c3RlbUlkKHN5c3RlbUlkKTsKKyAgICAgICAgdGhpcy5wYXJzZShpbnB1dCwgZGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBjb250ZW50IGRlc2NyaWJlZCBieSB0aGUgZ2l2aW5nIFVuaWZvcm0gUmVzb3VyY2UKKyAgICAgKiBJZGVudGlmaWVyIChVUkkpIGFzIFhNTCB1c2luZyB0aGUgc3BlY2lmaWVkCisgICAgICoge0BsaW5rIG9yZy54bWwuc2F4LkhhbmRsZXJCYXNlfS4KKyAgICAgKiA8aT4gVXNlIG9mIHRoZSBEZWZhdWx0SGFuZGxlciB2ZXJzaW9uIG9mIHRoaXMgbWV0aG9kIGlzIHJlY29tbWVuZGVkIGFzCisgICAgICogdGhlIDxjb2RlPkhhbmRsZXJCYXNlPC9jb2RlPiBjbGFzcyBoYXMgYmVlbiBkZXByZWNhdGVkIGluIFNBWCAyLjA8L2k+CisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJpIFRoZSBsb2NhdGlvbiBvZiB0aGUgY29udGVudCB0byBiZSBwYXJzZWQuCisgICAgICogQHBhcmFtIGhiIFRoZSBTQVggSGFuZGxlckJhc2UgdG8gdXNlLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIHVyaSBpcyBudWxsLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgYW55IElPIGVycm9ycyBvY2N1ci4KKyAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhbnkgU0FYIGVycm9ycyBvY2N1ciBkdXJpbmcgcHJvY2Vzc2luZy4KKyAgICAgKgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgcGFyc2UoU3RyaW5nIHVyaSwgSGFuZGxlckJhc2UgaGIpCisgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHVyaSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ1cmkgY2Fubm90IGJlIG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIElucHV0U291cmNlIGlucHV0ID0gbmV3IElucHV0U291cmNlKHVyaSk7CisgICAgICAgIHRoaXMucGFyc2UoaW5wdXQsIGhiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSB0aGUgY29udGVudCBkZXNjcmliZWQgYnkgdGhlIGdpdmluZyBVbmlmb3JtIFJlc291cmNlCisgICAgICogSWRlbnRpZmllciAoVVJJKSBhcyBYTUwgdXNpbmcgdGhlIHNwZWNpZmllZAorICAgICAqIHtAbGluayBvcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmkgVGhlIGxvY2F0aW9uIG9mIHRoZSBjb250ZW50IHRvIGJlIHBhcnNlZC4KKyAgICAgKiBAcGFyYW0gZGggVGhlIFNBWCBEZWZhdWx0SGFuZGxlciB0byB1c2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgdXJpIGlzIG51bGwuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbnkgSU8gZXJyb3JzIG9jY3VyLgorICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIElmIGFueSBTQVggZXJyb3JzIG9jY3VyIGR1cmluZyBwcm9jZXNzaW5nLgorICAgICAqCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwYXJzZShTdHJpbmcgdXJpLCBEZWZhdWx0SGFuZGxlciBkaCkKKyAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodXJpID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInVyaSBjYW5ub3QgYmUgbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgSW5wdXRTb3VyY2UgaW5wdXQgPSBuZXcgSW5wdXRTb3VyY2UodXJpKTsKKyAgICAgICAgdGhpcy5wYXJzZShpbnB1dCwgZGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBjb250ZW50IG9mIHRoZSBmaWxlIHNwZWNpZmllZCBhcyBYTUwgdXNpbmcgdGhlCisgICAgICogc3BlY2lmaWVkIHtAbGluayBvcmcueG1sLnNheC5IYW5kbGVyQmFzZX0uCisgICAgICogPGk+IFVzZSBvZiB0aGUgRGVmYXVsdEhhbmRsZXIgdmVyc2lvbiBvZiB0aGlzIG1ldGhvZCBpcyByZWNvbW1lbmRlZCBhcworICAgICAqIHRoZSBIYW5kbGVyQmFzZSBjbGFzcyBoYXMgYmVlbiBkZXByZWNhdGVkIGluIFNBWCAyLjA8L2k+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZiBUaGUgZmlsZSBjb250YWluaW5nIHRoZSBYTUwgdG8gcGFyc2UKKyAgICAgKiBAcGFyYW0gaGIgVGhlIFNBWCBIYW5kbGVyQmFzZSB0byB1c2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgRmlsZSBvYmplY3QgaXMgbnVsbC4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIElmIGFueSBJTyBlcnJvcnMgb2NjdXIuCisgICAgICogQHRocm93cyBTQVhFeGNlcHRpb24gSWYgYW55IFNBWCBlcnJvcnMgb2NjdXIgZHVyaW5nIHByb2Nlc3NpbmcuCisgICAgICoKKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHBhcnNlKEZpbGUgZiwgSGFuZGxlckJhc2UgaGIpCisgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGYgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmlsZSBjYW5ub3QgYmUgbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGVzY2FwZWRVUkkgPSBGaWxlUGF0aFRvVVJJLmZpbGVwYXRoMlVSSShmLmdldEFic29sdXRlUGF0aCgpKTsKKworICAgICAgICBpZiAoREVCVUcpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXNjYXBlZCBVUkkgPSAiICsgZXNjYXBlZFVSSSk7CisgICAgICAgIH0KKworICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dCA9IG5ldyBJbnB1dFNvdXJjZShlc2NhcGVkVVJJKTsKKyAgICAgICAgdGhpcy5wYXJzZShpbnB1dCwgaGIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBjb250ZW50IG9mIHRoZSBmaWxlIHNwZWNpZmllZCBhcyBYTUwgdXNpbmcgdGhlCisgICAgICogc3BlY2lmaWVkIHtAbGluayBvcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmIFRoZSBmaWxlIGNvbnRhaW5pbmcgdGhlIFhNTCB0byBwYXJzZQorICAgICAqIEBwYXJhbSBkaCBUaGUgU0FYIERlZmF1bHRIYW5kbGVyIHRvIHVzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSBGaWxlIG9iamVjdCBpcyBudWxsLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgYW55IElPIGVycm9ycyBvY2N1ci4KKyAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhbnkgU0FYIGVycm9ycyBvY2N1ciBkdXJpbmcgcHJvY2Vzc2luZy4KKyAgICAgKgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgcGFyc2UoRmlsZSBmLCBEZWZhdWx0SGFuZGxlciBkaCkKKyAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoZiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWxlIGNhbm5vdCBiZSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgZXNjYXBlZFVSSSA9IEZpbGVQYXRoVG9VUkkuZmlsZXBhdGgyVVJJKGYuZ2V0QWJzb2x1dGVQYXRoKCkpOworCisgICAgICAgIGlmIChERUJVRykgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFc2NhcGVkIFVSSSA9ICIgKyBlc2NhcGVkVVJJKTsKKyAgICAgICAgfQorCisgICAgICAgIElucHV0U291cmNlIGlucHV0ID0gbmV3IElucHV0U291cmNlKGVzY2FwZWRVUkkpOworICAgICAgICB0aGlzLnBhcnNlKGlucHV0LCBkaCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2UgdGhlIGNvbnRlbnQgZ2l2ZW4ge0BsaW5rIG9yZy54bWwuc2F4LklucHV0U291cmNlfQorICAgICAqIGFzIFhNTCB1c2luZyB0aGUgc3BlY2lmaWVkCisgICAgICoge0BsaW5rIG9yZy54bWwuc2F4LkhhbmRsZXJCYXNlfS4KKyAgICAgKiA8aT4gVXNlIG9mIHRoZSBEZWZhdWx0SGFuZGxlciB2ZXJzaW9uIG9mIHRoaXMgbWV0aG9kIGlzIHJlY29tbWVuZGVkIGFzCisgICAgICogdGhlIEhhbmRsZXJCYXNlIGNsYXNzIGhhcyBiZWVuIGRlcHJlY2F0ZWQgaW4gU0FYIDIuMDwvaT4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpcyBUaGUgSW5wdXRTb3VyY2UgY29udGFpbmluZyB0aGUgY29udGVudCB0byBiZSBwYXJzZWQuCisgICAgICogQHBhcmFtIGhiIFRoZSBTQVggSGFuZGxlckJhc2UgdG8gdXNlLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIDxjb2RlPklucHV0U291cmNlPC9jb2RlPiBvYmplY3QKKyAgICAgKiAgIGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgYW55IElPIGVycm9ycyBvY2N1ci4KKyAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhbnkgU0FYIGVycm9ycyBvY2N1ciBkdXJpbmcgcHJvY2Vzc2luZy4KKyAgICAgKgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTb3VyY2UgaXMsIEhhbmRsZXJCYXNlIGhiKQorICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnB1dFNvdXJjZSBjYW5ub3QgYmUgbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgUGFyc2VyIHBhcnNlciA9IHRoaXMuZ2V0UGFyc2VyKCk7CisgICAgICAgIGlmIChoYiAhPSBudWxsKSB7CisgICAgICAgICAgICBwYXJzZXIuc2V0RG9jdW1lbnRIYW5kbGVyKGhiKTsKKyAgICAgICAgICAgIHBhcnNlci5zZXRFbnRpdHlSZXNvbHZlcihoYik7CisgICAgICAgICAgICBwYXJzZXIuc2V0RXJyb3JIYW5kbGVyKGhiKTsKKyAgICAgICAgICAgIHBhcnNlci5zZXREVERIYW5kbGVyKGhiKTsKKyAgICAgICAgfQorICAgICAgICBwYXJzZXIucGFyc2UoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBjb250ZW50IGdpdmVuIHtAbGluayBvcmcueG1sLnNheC5JbnB1dFNvdXJjZX0KKyAgICAgKiBhcyBYTUwgdXNpbmcgdGhlIHNwZWNpZmllZAorICAgICAqIHtAbGluayBvcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpcyBUaGUgSW5wdXRTb3VyY2UgY29udGFpbmluZyB0aGUgY29udGVudCB0byBiZSBwYXJzZWQuCisgICAgICogQHBhcmFtIGRoIFRoZSBTQVggRGVmYXVsdEhhbmRsZXIgdG8gdXNlLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIDxjb2RlPklucHV0U291cmNlPC9jb2RlPiBvYmplY3QKKyAgICAgKiAgIGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgYW55IElPIGVycm9ycyBvY2N1ci4KKyAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhbnkgU0FYIGVycm9ycyBvY2N1ciBkdXJpbmcgcHJvY2Vzc2luZy4KKyAgICAgKgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTb3VyY2UgaXMsIERlZmF1bHRIYW5kbGVyIGRoKQorICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnB1dFNvdXJjZSBjYW5ub3QgYmUgbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgWE1MUmVhZGVyIHJlYWRlciA9IHRoaXMuZ2V0WE1MUmVhZGVyKCk7CisgICAgICAgIGlmIChkaCAhPSBudWxsKSB7CisgICAgICAgICAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIoZGgpOworICAgICAgICAgICAgcmVhZGVyLnNldEVudGl0eVJlc29sdmVyKGRoKTsKKyAgICAgICAgICAgIHJlYWRlci5zZXRFcnJvckhhbmRsZXIoZGgpOworICAgICAgICAgICAgcmVhZGVyLnNldERUREhhbmRsZXIoZGgpOworICAgICAgICB9CisgICAgICAgIHJlYWRlci5wYXJzZShpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgU0FYIHBhcnNlciB0aGF0IGlzIGVuY2Fwc3VsYXRlZCBieSB0aGUKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGNsYXNzLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgU0FYIHBhcnNlciB0aGF0IGlzIGVuY2Fwc3VsYXRlZCBieSB0aGUKKyAgICAgKiAgICAgICAgIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgY2xhc3MuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhbnkgU0FYIGVycm9ycyBvY2N1ciBkdXJpbmcgcHJvY2Vzc2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgb3JnLnhtbC5zYXguUGFyc2VyIGdldFBhcnNlcigpIHRocm93cyBTQVhFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyfSB0aGF0IGlzIGVuY2Fwc3VsYXRlZCBieSB0aGUKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGNsYXNzLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgWE1MUmVhZGVyIHRoYXQgaXMgZW5jYXBzdWxhdGVkIGJ5IHRoZQorICAgICAqICAgICAgICAgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBjbGFzcy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIElmIGFueSBTQVggZXJyb3JzIG9jY3VyIGR1cmluZyBwcm9jZXNzaW5nLgorICAgICAqLworCisgICAgcHVibGljIGFic3RyYWN0IG9yZy54bWwuc2F4LlhNTFJlYWRlciBnZXRYTUxSZWFkZXIoKSB0aHJvd3MgU0FYRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoaXMgcGFyc2VyIGlzIGNvbmZpZ3VyZWQgdG8KKyAgICAgKiB1bmRlcnN0YW5kIG5hbWVzcGFjZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBwYXJzZXIgaXMgY29uZmlndXJlZCB0bworICAgICAqICAgICAgICAgdW5kZXJzdGFuZCBuYW1lc3BhY2VzOyBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisKKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc05hbWVzcGFjZUF3YXJlKCk7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhpcyBwYXJzZXIgaXMgY29uZmlndXJlZCB0bworICAgICAqIHZhbGlkYXRlIFhNTCBkb2N1bWVudHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBwYXJzZXIgaXMgY29uZmlndXJlZCB0bworICAgICAqICAgICAgICAgdmFsaWRhdGUgWE1MIGRvY3VtZW50czsgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqLworCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNWYWxpZGF0aW5nKCk7CisKKyAgICAvKioKKyAgICAgKiA8cD5TZXRzIHRoZSBwYXJ0aWN1bGFyIHByb3BlcnR5IGluIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uIG9mCisgICAgICoge0BsaW5rIG9yZy54bWwuc2F4LlhNTFJlYWRlcn0uCisgICAgICogQSBsaXN0IG9mIHRoZSBjb3JlIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIGNhbiBiZSBmb3VuZCBhdAorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly9zYXguc291cmNlZm9yZ2UubmV0Lz9zZWxlY3RlZD1nZXQtc2V0Ij4KKyAgICAgKiBodHRwOi8vc2F4LnNvdXJjZWZvcmdlLm5ldC8/c2VsZWN0ZWQ9Z2V0LXNldDwvYT4uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIGJlIHNldC4KKyAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSB0byBiZSBzZXQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gV2hlbiB0aGUgdW5kZXJseWluZyBYTUxSZWFkZXIgZG9lcworICAgICAqICAgbm90IHJlY29nbml6ZSB0aGUgcHJvcGVydHkgbmFtZS4KKyAgICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBXaGVuIHRoZSB1bmRlcmx5aW5nIFhNTFJlYWRlcgorICAgICAqICByZWNvZ25pemVzIHRoZSBwcm9wZXJ0eSBuYW1lIGJ1dCBkb2Vzbid0IHN1cHBvcnQgdGhlIHByb3BlcnR5LgorICAgICAqCisgICAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0UHJvcGVydHkKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKQorICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogPHA+UmV0dXJucyB0aGUgcGFydGljdWxhciBwcm9wZXJ0eSByZXF1ZXN0ZWQgZm9yIGluIHRoZSB1bmRlcmx5aW5nCisgICAgICogaW1wbGVtZW50YXRpb24gb2Yge0BsaW5rIG9yZy54bWwuc2F4LlhNTFJlYWRlcn0uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIGJlIHJldHJpZXZlZC4KKyAgICAgKiBAcmV0dXJuIFZhbHVlIG9mIHRoZSByZXF1ZXN0ZWQgcHJvcGVydHkuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gV2hlbiB0aGUgdW5kZXJseWluZyBYTUxSZWFkZXIgZG9lcworICAgICAqICAgIG5vdCByZWNvZ25pemUgdGhlIHByb3BlcnR5IG5hbWUuCisgICAgICogQHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUgdW5kZXJseWluZyBYTUxSZWFkZXIKKyAgICAgKiAgcmVjb2duaXplcyB0aGUgcHJvcGVydHkgbmFtZSBidXQgZG9lc24ndCBzdXBwb3J0IHRoZSBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI2dldFByb3BlcnR5CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSkKKyAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKKworICAgIC8qKiA8cD5HZXQgYSByZWZlcmVuY2UgdG8gdGhlIHRoZSB7QGxpbmsgU2NoZW1hfSBiZWluZyB1c2VkIGJ5CisgICAgICogdGhlIFhNTCBwcm9jZXNzb3IuPC9wPgorICAgICAqCisgICAgICogPHA+SWYgbm8gc2NoZW1hIGlzIGJlaW5nIHVzZWQsIDxjb2RlPm51bGw8L2NvZGU+IGlzIHJldHVybmVkLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4ge0BsaW5rIFNjaGVtYX0gYmVpbmcgdXNlZCBvciA8Y29kZT5udWxsPC9jb2RlPgorICAgICAqICBpZiBub25lIGluIHVzZQorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgRm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHdoZW4gaW1wbGVtZW50YXRpb25zIGZvcgorICAgICAqICAgICAgZWFybGllciB2ZXJzaW9ucyBvZiBKQVhQIGlzIHVzZWQsIHRoaXMgZXhjZXB0aW9uIHdpbGwgYmUKKyAgICAgKiAgICAgIHRocm93bi4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgU2NoZW1hIGdldFNjaGVtYSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICAgIlRoaXMgcGFyc2VyIGRvZXMgbm90IHN1cHBvcnQgc3BlY2lmaWNhdGlvbiBcIiIKKyAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVGl0bGUoKQorICAgICAgICAgICAgKyAiXCIgdmVyc2lvbiBcIiIKKyAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVmVyc2lvbigpCisgICAgICAgICAgICArICJcIiIKKyAgICAgICAgICAgICk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+R2V0IHRoZSBYSW5jbHVkZSBwcm9jZXNzaW5nIG1vZGUgZm9yIHRoaXMgcGFyc2VyLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4KKyAgICAgKiAgICAgIHRoZSByZXR1cm4gdmFsdWUgb2YKKyAgICAgKiAgICAgIHRoZSB7QGxpbmsgU0FYUGFyc2VyRmFjdG9yeSNpc1hJbmNsdWRlQXdhcmUoKX0KKyAgICAgKiAgICAgIHdoZW4gdGhpcyBwYXJzZXIgd2FzIGNyZWF0ZWQgZnJvbSBmYWN0b3J5LgorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgRm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHdoZW4gaW1wbGVtZW50YXRpb25zIGZvcgorICAgICAqICAgICAgZWFybGllciB2ZXJzaW9ucyBvZiBKQVhQIGlzIHVzZWQsIHRoaXMgZXhjZXB0aW9uIHdpbGwgYmUKKyAgICAgKiAgICAgIHRocm93bi4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKgorICAgICAqIEBzZWUgU0FYUGFyc2VyRmFjdG9yeSNzZXRYSW5jbHVkZUF3YXJlKGJvb2xlYW4pCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNYSW5jbHVkZUF3YXJlKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgICAiVGhpcyBwYXJzZXIgZG9lcyBub3Qgc3VwcG9ydCBzcGVjaWZpY2F0aW9uIFwiIgorICAgICAgICAgICAgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25UaXRsZSgpCisgICAgICAgICAgICArICJcIiB2ZXJzaW9uIFwiIgorICAgICAgICAgICAgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25WZXJzaW9uKCkKKyAgICAgICAgICAgICsgIlwiIgorICAgICAgICAgICAgKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3BhcnNlcnMvU0FYUGFyc2VyRmFjdG9yeS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9wYXJzZXJzL1NBWFBhcnNlckZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYjQ0MDMzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC9wYXJzZXJzL1NBWFBhcnNlckZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDM3OCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vICRJZDogU0FYUGFyc2VyRmFjdG9yeS5qYXZhIDg4NDk1MCAyMDA5LTExLTI3IDE4OjQ2OjE4WiBtcmdsYXZhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLnBhcnNlcnM7CisKK2ltcG9ydCBqYXZheC54bWwudmFsaWRhdGlvbi5TY2hlbWE7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnlJbXBsOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKKworLyoqCisgKiBEZWZpbmVzIGEgZmFjdG9yeSBBUEkgdGhhdCBlbmFibGVzIGFwcGxpY2F0aW9ucyB0byBjb25maWd1cmUgYW5kCisgKiBvYnRhaW4gYSBTQVggYmFzZWQgcGFyc2VyIHRvIHBhcnNlIFhNTCBkb2N1bWVudHMuCisgKgorICogQGF1dGhvciA8YSBocmVmPSJKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogODg0OTUwICQsICREYXRlOiAyMDA5LTExLTI3IDEwOjQ2OjE4IC0wODAwIChGcmksIDI3IE5vdiAyMDA5KSAkCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTQVhQYXJzZXJGYWN0b3J5IHsKKworICAgIC8qKgorICAgICAqIDxwPlNob3VsZCBQYXJzZXJzIGJlIHZhbGlkYXRpbmc/PC9wPgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiB2YWxpZGF0aW5nID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiA8cD5TaG91bGQgUGFyc2VycyBiZSBuYW1lc3BhY2UgYXdhcmU/PC9wPgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBuYW1lc3BhY2VBd2FyZSA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogPHA+UHJvdGVjdGVkIGNvbnN0cnVjdG9yIHRvIGZvcmNlIHVzZSBvZiB7QGxpbmsgI25ld0luc3RhbmNlKCl9LjwvcD4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU0FYUGFyc2VyRmFjdG9yeSAoKSB7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFuZHJvaWQncyBpbXBsZW1lbnRhdGlvbiBvZiB7QGNvZGUgU0FYUGFyc2VyRmFjdG9yeX0uIFVubGlrZQorICAgICAqIG90aGVyIEphdmEgaW1wbGVtZW50YXRpb25zLCB0aGlzIG1ldGhvZCBkb2VzIG5vdCBjb25zdWx0IHN5c3RlbQorICAgICAqIHByb3BlcnRpZXMsIHByb3BlcnR5IGZpbGVzLCBvciB0aGUgc2VydmljZXMgQVBJLgorICAgICAqCisgICAgICogQHJldHVybiBhIG5ldyBTQVhQYXJzZXJGYWN0b3J5LgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIG5ldmVyLiBJbmNsdWRlZCBmb3IgQVBJCisgICAgICogICAgIGNvbXBhdGliaWxpdHkgd2l0aCBvdGhlciBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNBWFBhcnNlckZhY3RvcnkgbmV3SW5zdGFuY2UoKSB7CisgICAgICAgIC8vIGluc3RhbnRpYXRlIHRoZSBjbGFzcyBkaXJlY3RseSByYXRoZXIgdGhhbiB1c2luZyByZWZsZWN0aW9uCisgICAgICAgIHJldHVybiBuZXcgU0FYUGFyc2VyRmFjdG9yeUltcGwoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIHRoZSBuYW1lZCBpbXBsZW1lbnRhdGlvbiBvZiB7QGNvZGUgU0FYUGFyc2VyRmFjdG9yeX0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgaWYge0Bjb2RlIGZhY3RvcnlDbGFzc05hbWV9IGlzIG5vdCBhdmFpbGFibGUgb3IgY2Fubm90IGJlCisgICAgICogICAgIGluc3RhbnRpYXRlZC4KKyAgICAgKiBAc2luY2UgMS42CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTQVhQYXJzZXJGYWN0b3J5IG5ld0luc3RhbmNlKFN0cmluZyBmYWN0b3J5Q2xhc3NOYW1lLAorICAgICAgICAgICAgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIpIHsKKyAgICAgICAgaWYgKGZhY3RvcnlDbGFzc05hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoImZhY3RvcnlDbGFzc05hbWUgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChjbGFzc0xvYWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICBjbGFzc0xvYWRlciA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENsYXNzPD8+IHR5cGUgPSBjbGFzc0xvYWRlciAhPSBudWxsCisgICAgICAgICAgICAgICAgICAgID8gY2xhc3NMb2FkZXIubG9hZENsYXNzKGZhY3RvcnlDbGFzc05hbWUpCisgICAgICAgICAgICAgICAgICAgIDogQ2xhc3MuZm9yTmFtZShmYWN0b3J5Q2xhc3NOYW1lKTsKKyAgICAgICAgICAgIHJldHVybiAoU0FYUGFyc2VyRmFjdG9yeSkgdHlwZS5uZXdJbnN0YW5jZSgpOworICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKGUpOworICAgICAgICB9IGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKGUpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+Q3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBhIFNBWFBhcnNlciB1c2luZyB0aGUgY3VycmVudGx5CisgICAgICogY29uZmlndXJlZCBmYWN0b3J5IHBhcmFtZXRlcnMuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBBIG5ldyBpbnN0YW5jZSBvZiBhIFNBWFBhcnNlci4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBpZiBhIHBhcnNlciBjYW5ub3QKKyAgICAgKiAgIGJlIGNyZWF0ZWQgd2hpY2ggc2F0aXNmaWVzIHRoZSByZXF1ZXN0ZWQgY29uZmlndXJhdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBmb3IgU0FYIGVycm9ycy4KKyAgICAgKi8KKworICAgIHB1YmxpYyBhYnN0cmFjdCBTQVhQYXJzZXIgbmV3U0FYUGFyc2VyKCkKKyAgICAgICAgdGhyb3dzIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbjsKKworCisgICAgLyoqCisgICAgICogU3BlY2lmaWVzIHRoYXQgdGhlIHBhcnNlciBwcm9kdWNlZCBieSB0aGlzIGNvZGUgd2lsbAorICAgICAqIHByb3ZpZGUgc3VwcG9ydCBmb3IgWE1MIG5hbWVzcGFjZXMuIEJ5IGRlZmF1bHQgdGhlIHZhbHVlIG9mIHRoaXMgaXMgc2V0CisgICAgICogdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtIGF3YXJlbmVzcyB0cnVlIGlmIHRoZSBwYXJzZXIgcHJvZHVjZWQgYnkgdGhpcyBjb2RlIHdpbGwKKyAgICAgKiAgICAgICAgICAgICAgICAgIHByb3ZpZGUgc3VwcG9ydCBmb3IgWE1MIG5hbWVzcGFjZXM7IGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKworICAgIHB1YmxpYyB2b2lkIHNldE5hbWVzcGFjZUF3YXJlKGJvb2xlYW4gYXdhcmVuZXNzKSB7CisgICAgICAgIHRoaXMubmFtZXNwYWNlQXdhcmUgPSBhd2FyZW5lc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3BlY2lmaWVzIHRoYXQgdGhlIHBhcnNlciBwcm9kdWNlZCBieSB0aGlzIGNvZGUgd2lsbAorICAgICAqIHZhbGlkYXRlIGRvY3VtZW50cyBhcyB0aGV5IGFyZSBwYXJzZWQuIEJ5IGRlZmF1bHQgdGhlIHZhbHVlIG9mIHRoaXMgaXMKKyAgICAgKiBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LgorICAgICAqCisgICAgICogPHA+CisgICAgICogTm90ZSB0aGF0ICJ0aGUgdmFsaWRhdGlvbiIgaGVyZSBtZWFucworICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwjcHJvYy10eXBlcyI+YSB2YWxpZGF0aW5nCisgICAgICogcGFyc2VyPC9hPiBhcyBkZWZpbmVkIGluIHRoZSBYTUwgcmVjb21tZW5kYXRpb24uCisgICAgICogSW4gb3RoZXIgd29yZHMsIGl0IGVzc2VudGlhbGx5IGp1c3QgY29udHJvbHMgdGhlIERURCB2YWxpZGF0aW9uLgorICAgICAqIChleGNlcHQgdGhlIGxlZ2FjeSB0d28gcHJvcGVydGllcyBkZWZpbmVkIGluIEpBWFAgMS4yLgorICAgICAqIFNlZSA8YSBocmVmPSIjdmFsaWRhdGlvbkNvbXBhdGliaWxpdHkiPmhlcmU8L2E+IGZvciBtb3JlIGRldGFpbHMuKQorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFRvIHVzZSBtb2Rlcm4gc2NoZW1hIGxhbmd1YWdlcyBzdWNoIGFzIFczQyBYTUwgU2NoZW1hIG9yCisgICAgICogUkVMQVggTkcgaW5zdGVhZCBvZiBEVEQsIHlvdSBjYW4gY29uZmlndXJlIHlvdXIgcGFyc2VyIHRvIGJlCisgICAgICogYSBub24tdmFsaWRhdGluZyBwYXJzZXIgYnkgbGVhdmluZyB0aGUge0BsaW5rICNzZXRWYWxpZGF0aW5nKGJvb2xlYW4pfQorICAgICAqIG1ldGhvZCA8dHQ+ZmFsc2U8L3R0PiwgdGhlbiB1c2UgdGhlIHtAbGluayAjc2V0U2NoZW1hKFNjaGVtYSl9CisgICAgICogbWV0aG9kIHRvIGFzc29jaWF0ZSBhIHNjaGVtYSB0byBhIHBhcnNlci4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsaWRhdGluZyB0cnVlIGlmIHRoZSBwYXJzZXIgcHJvZHVjZWQgYnkgdGhpcyBjb2RlIHdpbGwKKyAgICAgKiAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZSBkb2N1bWVudHMgYXMgdGhleSBhcmUgcGFyc2VkOyBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisKKyAgICBwdWJsaWMgdm9pZCBzZXRWYWxpZGF0aW5nKGJvb2xlYW4gdmFsaWRhdGluZykgeworICAgICAgICB0aGlzLnZhbGlkYXRpbmcgPSB2YWxpZGF0aW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgZmFjdG9yeSBpcyBjb25maWd1cmVkIHRvIHByb2R1Y2UKKyAgICAgKiBwYXJzZXJzIHdoaWNoIGFyZSBuYW1lc3BhY2UgYXdhcmUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGZhY3RvcnkgaXMgY29uZmlndXJlZCB0byBwcm9kdWNlCisgICAgICogICAgICAgICBwYXJzZXJzIHdoaWNoIGFyZSBuYW1lc3BhY2UgYXdhcmU7IGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKworICAgIHB1YmxpYyBib29sZWFuIGlzTmFtZXNwYWNlQXdhcmUoKSB7CisgICAgICAgIHJldHVybiBuYW1lc3BhY2VBd2FyZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhlIGZhY3RvcnkgaXMgY29uZmlndXJlZCB0byBwcm9kdWNlCisgICAgICogcGFyc2VycyB3aGljaCB2YWxpZGF0ZSB0aGUgWE1MIGNvbnRlbnQgZHVyaW5nIHBhcnNlLgorICAgICAqCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmYWN0b3J5IGlzIGNvbmZpZ3VyZWQgdG8gcHJvZHVjZSBwYXJzZXJzIHdoaWNoIHZhbGlkYXRlCisgICAgICogICAgICAgICB0aGUgWE1MIGNvbnRlbnQgZHVyaW5nIHBhcnNlOyBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1ZhbGlkYXRpbmcoKSB7CisgICAgICAgIHJldHVybiB2YWxpZGF0aW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqCisgICAgICogPHA+U2V0cyB0aGUgcGFydGljdWxhciBmZWF0dXJlIGluIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uIG9mCisgICAgICogb3JnLnhtbC5zYXguWE1MUmVhZGVyLgorICAgICAqIEEgbGlzdCBvZiB0aGUgY29yZSBmZWF0dXJlcyBhbmQgcHJvcGVydGllcyBjYW4gYmUgZm91bmQgYXQKKyAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnNheHByb2plY3Qub3JnLyI+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZy88L2E+PC9wPgorICAgICAqCisgICAgICogPHA+QWxsIGltcGxlbWVudGF0aW9ucyBhcmUgcmVxdWlyZWQgdG8gc3VwcG9ydCB0aGUge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lOR30gZmVhdHVyZS4KKyAgICAgKiBXaGVuIHRoZSBmZWF0dXJlIGlzPC9wPgorICAgICAqIDx1bD4KKyAgICAgKiAgIDxsaT4KKyAgICAgKiAgICAgPGNvZGU+dHJ1ZTwvY29kZT46IHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsIGxpbWl0IFhNTCBwcm9jZXNzaW5nIHRvIGNvbmZvcm0gdG8gaW1wbGVtZW50YXRpb24gbGltaXRzLgorICAgICAqICAgICBFeGFtcGxlcyBpbmNsdWRlIGVudGl0eSBleHBhbnNpb24gbGltaXRzIGFuZCBYTUwgU2NoZW1hIGNvbnN0cnVjdHMgdGhhdCB3b3VsZCBjb25zdW1lIGxhcmdlIGFtb3VudHMgb2YgcmVzb3VyY2VzLgorICAgICAqICAgICBJZiBYTUwgcHJvY2Vzc2luZyBpcyBsaW1pdGVkIGZvciBzZWN1cml0eSByZWFzb25zLCBpdCB3aWxsIGJlIHJlcG9ydGVkIHZpYSBhIGNhbGwgdG8gdGhlIHJlZ2lzdGVyZWQKKyAgICAgKiAgICAge0BsaW5rIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciNmYXRhbEVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbil9LgorICAgICAqICAgICBTZWUge0BsaW5rIFNBWFBhcnNlcn0gPGNvZGU+cGFyc2U8L2NvZGU+IG1ldGhvZHMgZm9yIGhhbmRsZXIgc3BlY2lmaWNhdGlvbi4KKyAgICAgKiAgIDwvbGk+CisgICAgICogICA8bGk+CisgICAgICogICAgIFdoZW4gdGhlIGZlYXR1cmUgaXMgPGNvZGU+ZmFsc2U8L2NvZGU+LCB0aGUgaW1wbGVtZW50YXRpb24gd2lsbCBwcm9jZXNzaW5nIFhNTCBhY2NvcmRpbmcgdG8gdGhlIFhNTCBzcGVjaWZpY2F0aW9ucyB3aXRob3V0CisgICAgICogICAgIHJlZ2FyZCB0byBwb3NzaWJsZSBpbXBsZW1lbnRhdGlvbiBsaW1pdHMuCisgICAgICogICA8L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZmVhdHVyZSB0byBiZSBzZXQuCisgICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSBvZiB0aGUgZmVhdHVyZSB0byBiZSBzZXQuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gaWYgYSBwYXJzZXIgY2Fubm90CisgICAgICogICAgIGJlIGNyZWF0ZWQgd2hpY2ggc2F0aXNmaWVzIHRoZSByZXF1ZXN0ZWQgY29uZmlndXJhdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gV2hlbiB0aGUgdW5kZXJseWluZyBYTUxSZWFkZXIgZG9lcworICAgICAqICAgICAgICAgICAgbm90IHJlY29nbml6ZSB0aGUgcHJvcGVydHkgbmFtZS4KKyAgICAgKiBAZXhjZXB0aW9uIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBXaGVuIHRoZSB1bmRlcmx5aW5nIFhNTFJlYWRlcgorICAgICAqICAgICAgICAgICAgcmVjb2duaXplcyB0aGUgcHJvcGVydHkgbmFtZSBidXQgZG9lc24ndCBzdXBwb3J0IHRoZQorICAgICAqICAgICAgICAgICAgcHJvcGVydHkuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiB0aGUgPGNvZGU+bmFtZTwvY29kZT4gcGFyYW1ldGVyIGlzIG51bGwuCisgICAgICoKKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNzZXRGZWF0dXJlCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkKKyAgICAgICAgdGhyb3dzIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24sIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICoKKyAgICAgKiA8cD5SZXR1cm5zIHRoZSBwYXJ0aWN1bGFyIHByb3BlcnR5IHJlcXVlc3RlZCBmb3IgaW4gdGhlIHVuZGVybHlpbmcKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5YTUxSZWFkZXIuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIGJlIHJldHJpZXZlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVmFsdWUgb2YgdGhlIHJlcXVlc3RlZCBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBpZiBhIHBhcnNlciBjYW5ub3QgYmUgY3JlYXRlZCB3aGljaCBzYXRpc2ZpZXMgdGhlIHJlcXVlc3RlZCBjb25maWd1cmF0aW9uLgorICAgICAqIEBleGNlcHRpb24gU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBXaGVuIHRoZSB1bmRlcmx5aW5nIFhNTFJlYWRlciBkb2VzIG5vdCByZWNvZ25pemUgdGhlIHByb3BlcnR5IG5hbWUuCisgICAgICogQGV4Y2VwdGlvbiBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUgdW5kZXJseWluZyBYTUxSZWFkZXIgcmVjb2duaXplcyB0aGUgcHJvcGVydHkgbmFtZSBidXQgZG9lc24ndCBzdXBwb3J0IHRoZSBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI2dldFByb3BlcnR5CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSkKKyAgICAgICAgdGhyb3dzIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24sIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUge0BsaW5rIFNjaGVtYX0gb2JqZWN0IHNwZWNpZmllZCB0aHJvdWdoCisgICAgICogdGhlIHtAbGluayAjc2V0U2NoZW1hKFNjaGVtYSBzY2hlbWEpfSBtZXRob2QuCisgICAgICoKKyAgICAgKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB3aGVuIGltcGxlbWVudGF0aW9ucyBmb3IKKyAgICAgKiAgICAgIGVhcmxpZXIgdmVyc2lvbnMgb2YgSkFYUCBpcyB1c2VkLCB0aGlzIGV4Y2VwdGlvbiB3aWxsIGJlCisgICAgICogICAgICB0aHJvd24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICB0aGUge0BsaW5rIFNjaGVtYX0gb2JqZWN0IHRoYXQgd2FzIGxhc3Qgc2V0IHRocm91Z2gKKyAgICAgKiAgICAgIHRoZSB7QGxpbmsgI3NldFNjaGVtYShTY2hlbWEpfSBtZXRob2QsIG9yIG51bGwKKyAgICAgKiAgICAgIGlmIHRoZSBtZXRob2Qgd2FzIG5vdCBpbnZva2VkIHNpbmNlIGEge0BsaW5rIFNBWFBhcnNlckZhY3Rvcnl9CisgICAgICogICAgICBpcyBjcmVhdGVkLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyBTY2hlbWEgZ2V0U2NoZW1hKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgICAiVGhpcyBwYXJzZXIgZG9lcyBub3Qgc3VwcG9ydCBzcGVjaWZpY2F0aW9uIFwiIgorICAgICAgICAgICAgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25UaXRsZSgpCisgICAgICAgICAgICArICJcIiB2ZXJzaW9uIFwiIgorICAgICAgICAgICAgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25WZXJzaW9uKCkKKyAgICAgICAgICAgICsgIlwiIgorICAgICAgICAgICAgKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5TZXQgdGhlIHtAbGluayBTY2hlbWF9IHRvIGJlIHVzZWQgYnkgcGFyc2VycyBjcmVhdGVkCisgICAgICogZnJvbSB0aGlzIGZhY3RvcnkuPC9wPgorICAgICAqCisgICAgICogPHA+V2hlbiBhIHtAbGluayBTY2hlbWF9IGlzIG5vbi1udWxsLCBhIHBhcnNlciB3aWxsIHVzZSBhIHZhbGlkYXRvcgorICAgICAqIGNyZWF0ZWQgZnJvbSBpdCB0byB2YWxpZGF0ZSBkb2N1bWVudHMgYmVmb3JlIGl0IHBhc3NlcyBpbmZvcm1hdGlvbgorICAgICAqIGRvd24gdG8gdGhlIGFwcGxpY2F0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIDxwPldoZW4gd2FybmluZ3MvZXJyb3JzL2ZhdGFsIGVycm9ycyBhcmUgZm91bmQgYnkgdGhlIHZhbGlkYXRvciwgdGhlIHBhcnNlciBtdXN0CisgICAgICogaGFuZGxlIHRoZW0gYXMgaWYgdGhvc2UgZXJyb3JzIHdlcmUgZm91bmQgYnkgdGhlIHBhcnNlciBpdHNlbGYuCisgICAgICogSW4gb3RoZXIgd29yZHMsIGlmIHRoZSB1c2VyLXNwZWNpZmllZCB7QGxpbmsgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyfQorICAgICAqIGlzIHNldCwgaXQgbXVzdCByZWNlaXZlIHRob3NlIGVycm9ycywgYW5kIGlmIG5vdCwgdGhleSBtdXN0IGJlCisgICAgICogdHJlYXRlZCBhY2NvcmRpbmcgdG8gdGhlIGltcGxlbWVudGF0aW9uIHNwZWNpZmljCisgICAgICogZGVmYXVsdCBlcnJvciBoYW5kbGluZyBydWxlcy4KKyAgICAgKgorICAgICAqIDxwPkEgdmFsaWRhdG9yIG1heSBtb2RpZnkgdGhlIFNBWCBldmVudCBzdHJlYW0gKGZvciBleGFtcGxlIGJ5CisgICAgICogYWRkaW5nIGRlZmF1bHQgdmFsdWVzIHRoYXQgd2VyZSBtaXNzaW5nIGluIGRvY3VtZW50cyksIGFuZCBhIHBhcnNlcgorICAgICAqIGlzIHJlc3BvbnNpYmxlIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBhcHBsaWNhdGlvbiB3aWxsIHJlY2VpdmUKKyAgICAgKiB0aG9zZSBtb2RpZmllZCBldmVudCBzdHJlYW0uPC9wPgorICAgICAqCisgICAgICogPHA+SW5pdGlhbGx5LCA8Y29kZT5udWxsPC9jb2RlPiBpcyBzZXQgYXMgdGhlIHtAbGluayBTY2hlbWF9LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgcHJvY2Vzc2luZyB3aWxsIHRha2UgZWZmZWN0IGV2ZW4gaWYKKyAgICAgKiB0aGUge0BsaW5rICNpc1ZhbGlkYXRpbmcoKX0gbWV0aG9kIHJldHVybnMgPGNvZGU+ZmFsc2U8L2NvZGU+LgorICAgICAqCisgICAgICogPHA+SXQgaXMgYW4gZXJyb3IgdG8gdXNlCisgICAgICogdGhlIDxjb2RlPmh0dHA6Ly9qYXZhLnN1bi5jb20veG1sL2pheHAvcHJvcGVydGllcy9zY2hlbWFTb3VyY2U8L2NvZGU+CisgICAgICogcHJvcGVydHkgYW5kL29yIHRoZSA8Y29kZT5odHRwOi8vamF2YS5zdW4uY29tL3htbC9qYXhwL3Byb3BlcnRpZXMvc2NoZW1hTGFuZ3VhZ2U8L2NvZGU+CisgICAgICogcHJvcGVydHkgaW4gY29uanVuY3Rpb24gd2l0aCBhIG5vbi1udWxsIHtAbGluayBTY2hlbWF9IG9iamVjdC4KKyAgICAgKiBTdWNoIGNvbmZpZ3VyYXRpb24gd2lsbCBjYXVzZSBhIHtAbGluayBTQVhFeGNlcHRpb259CisgICAgICogZXhjZXB0aW9uIHdoZW4gdGhvc2UgcHJvcGVydGllcyBhcmUgc2V0IG9uIGEge0BsaW5rIFNBWFBhcnNlcn0uPC9wPgorICAgICAqCisgICAgICogPGg0Pk5vdGUgZm9yIGltcGxlbWVudG9yczwvaDQ+CisgICAgICogPHA+CisgICAgICogQSBwYXJzZXIgbXVzdCBiZSBhYmxlIHRvIHdvcmsgd2l0aCBhbnkge0BsaW5rIFNjaGVtYX0KKyAgICAgKiBpbXBsZW1lbnRhdGlvbi4gSG93ZXZlciwgcGFyc2VycyBhbmQgc2NoZW1hcyBhcmUgYWxsb3dlZAorICAgICAqIHRvIHVzZSBpbXBsZW1lbnRhdGlvbi1zcGVjaWZpYyBjdXN0b20gbWVjaGFuaXNtcworICAgICAqIGFzIGxvbmcgYXMgdGhleSB5aWVsZCB0aGUgcmVzdWx0IGRlc2NyaWJlZCBpbiB0aGUgc3BlY2lmaWNhdGlvbi4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gc2NoZW1hIDxjb2RlPlNjaGVtYTwvY29kZT4gdG8gdXNlLCA8Y29kZT5udWxsPC9jb2RlPiB0byByZW1vdmUgYSBzY2hlbWEuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICBGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgd2hlbiBpbXBsZW1lbnRhdGlvbnMgZm9yCisgICAgICogICAgICBlYXJsaWVyIHZlcnNpb25zIG9mIEpBWFAgaXMgdXNlZCwgdGhpcyBleGNlcHRpb24gd2lsbCBiZQorICAgICAqICAgICAgdGhyb3duLgorICAgICAqCisgICAgICogQHNpbmNlIDEuNQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNjaGVtYShTY2hlbWEgc2NoZW1hKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICJUaGlzIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHNwZWNpZmljYXRpb24gXCIiCisgICAgICAgICAgICArIHRoaXMuZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkuZ2V0U3BlY2lmaWNhdGlvblRpdGxlKCkKKyAgICAgICAgICAgICsgIlwiIHZlcnNpb24gXCIiCisgICAgICAgICAgICArIHRoaXMuZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkuZ2V0U3BlY2lmaWNhdGlvblZlcnNpb24oKQorICAgICAgICAgICAgKyAiXCIiCisgICAgICAgICAgICApOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlNldCBzdGF0ZSBvZiBYSW5jbHVkZSBwcm9jZXNzaW5nLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIFhJbmNsdWRlIG1hcmt1cCBpcyBmb3VuZCBpbiB0aGUgZG9jdW1lbnQgaW5zdGFuY2UsIHNob3VsZCBpdCBiZQorICAgICAqIHByb2Nlc3NlZCBhcyBzcGVjaWZpZWQgaW4gPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveGluY2x1ZGUvIj4KKyAgICAgKiBYTUwgSW5jbHVzaW9ucyAoWEluY2x1ZGUpIFZlcnNpb24gMS4wPC9hPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5YSW5jbHVkZSBwcm9jZXNzaW5nIGRlZmF1bHRzIHRvIDxjb2RlPmZhbHNlPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhdGUgU2V0IFhJbmNsdWRlIHByb2Nlc3NpbmcgdG8gPGNvZGU+dHJ1ZTwvY29kZT4gb3IKKyAgICAgKiAgIDxjb2RlPmZhbHNlPC9jb2RlPgorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorICAgICAqICAgICAgRm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHdoZW4gaW1wbGVtZW50YXRpb25zIGZvcgorICAgICAqICAgICAgZWFybGllciB2ZXJzaW9ucyBvZiBKQVhQIGlzIHVzZWQsIHRoaXMgZXhjZXB0aW9uIHdpbGwgYmUKKyAgICAgKiAgICAgIHRocm93bi4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRYSW5jbHVkZUF3YXJlKGZpbmFsIGJvb2xlYW4gc3RhdGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICAgIlRoaXMgcGFyc2VyIGRvZXMgbm90IHN1cHBvcnQgc3BlY2lmaWNhdGlvbiBcIiIKKyAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVGl0bGUoKQorICAgICAgICAgICAgKyAiXCIgdmVyc2lvbiBcIiIKKyAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVmVyc2lvbigpCisgICAgICAgICAgICArICJcIiIKKyAgICAgICAgICAgICk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+R2V0IHN0YXRlIG9mIFhJbmNsdWRlIHByb2Nlc3NpbmcuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBjdXJyZW50IHN0YXRlIG9mIFhJbmNsdWRlIHByb2Nlc3NpbmcKKyAgICAgKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB3aGVuIGltcGxlbWVudGF0aW9ucyBmb3IKKyAgICAgKiAgICAgIGVhcmxpZXIgdmVyc2lvbnMgb2YgSkFYUCBpcyB1c2VkLCB0aGlzIGV4Y2VwdGlvbiB3aWxsIGJlCisgICAgICogICAgICB0aHJvd24uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNYSW5jbHVkZUF3YXJlKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgICAiVGhpcyBwYXJzZXIgZG9lcyBub3Qgc3VwcG9ydCBzcGVjaWZpY2F0aW9uIFwiIgorICAgICAgICAgICAgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25UaXRsZSgpCisgICAgICAgICAgICArICJcIiB2ZXJzaW9uIFwiIgorICAgICAgICAgICAgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25WZXJzaW9uKCkKKyAgICAgICAgICAgICsgIlwiIgorICAgICAgICAgICAgKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvcGFyc2Vycy9wYWNrYWdlLmh0bWwgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3BhcnNlcnMvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkyZTA5ZDUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3BhcnNlcnMvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMTcgQEAKKzxIVE1MPjxIRUFEPgorPCEtLQorICAgICRJZDogcGFja2FnZS5odG1sIDIyNjE4MyAyMDA1LTA0LTA4IDEwOjM5OjE0WiBuZWVyYWogJAorLS0+CisKKzwvSEVBRD48Qk9EWT4KKworUHJvdmlkZXMgY2xhc3NlcyBhbGxvd2luZyB0aGUgcHJvY2Vzc2luZyBvZiBYTUwgZG9jdW1lbnRzLiBUd28gdHlwZXMKK29mIHBsdWdhYmxlIHBhcnNlcnMgYXJlIHN1cHBvcnRlZDoKKzx1bD4KKzxsaT5TQVggKFNpbXBsZSBBUEkgZm9yIFhNTCkKKzxsaT5ET00gKERvY3VtZW50IE9iamVjdCBNb2RlbCkKKzwvdWw+CisKKworCis8L0JPRFk+PC9IVE1MPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vRXJyb3JMaXN0ZW5lci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vRXJyb3JMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyMWM1ZmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9FcnJvckxpc3RlbmVyLmphdmEKQEAgLTAsMCArMSwxMDkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLyAkSWQ6IEVycm9yTGlzdGVuZXIuamF2YSA1Njk5OTQgMjAwNy0wOC0yNyAwNDoyODo1N1ogbXJnbGF2YXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm07CisKKy8qKgorICogPHA+VG8gcHJvdmlkZSBjdXN0b21pemVkIGVycm9yIGhhbmRsaW5nLCBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UgYW5kCisgKiB1c2UgdGhlIDxjb2RlPnNldEVycm9yTGlzdGVuZXI8L2NvZGU+IG1ldGhvZCB0byByZWdpc3RlciBhbiBpbnN0YW5jZSBvZiB0aGUKKyAqIGltcGxlbWVudGF0aW9uIHdpdGggdGhlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyfS4gIFRoZQorICogPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+IHRoZW4gcmVwb3J0cyBhbGwgZXJyb3JzIGFuZCB3YXJuaW5ncyB0aHJvdWdoIHRoaXMKKyAqIGludGVyZmFjZS48L3A+CisgKgorICogPHA+SWYgYW4gYXBwbGljYXRpb24gZG9lcyA8ZW0+bm90PC9lbT4gcmVnaXN0ZXIgaXRzIG93biBjdXN0b20KKyAqIDxjb2RlPkVycm9yTGlzdGVuZXI8L2NvZGU+LCB0aGUgZGVmYXVsdCA8Y29kZT5FcnJvckxpc3RlbmVyPC9jb2RlPgorICogaXMgdXNlZCB3aGljaCByZXBvcnRzIGFsbCB3YXJuaW5ncyBhbmQgZXJyb3JzIHRvIDxjb2RlPlN5c3RlbS5lcnI8L2NvZGU+CisgKiBhbmQgZG9lcyBub3QgdGhyb3cgYW55IDxjb2RlPkV4Y2VwdGlvbjwvY29kZT5zLgorICogQXBwbGljYXRpb25zIGFyZSA8ZW0+c3Ryb25nbHk8L2VtPiBlbmNvdXJhZ2VkIHRvIHJlZ2lzdGVyIGFuZCB1c2UKKyAqIDxjb2RlPkVycm9yTGlzdGVuZXI8L2NvZGU+cyB0aGF0IGluc3VyZSBwcm9wZXIgYmVoYXZpb3IgZm9yIHdhcm5pbmdzIGFuZAorICogZXJyb3JzLjwvcD4KKyAqCisgKiA8cD5Gb3IgdHJhbnNmb3JtYXRpb24gZXJyb3JzLCBhIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPiBtdXN0IHVzZSB0aGlzCisgKiBpbnRlcmZhY2UgaW5zdGVhZCBvZiB0aHJvd2luZyBhbiA8Y29kZT5FeGNlcHRpb248L2NvZGU+OiBpdCBpcyB1cCB0byB0aGUKKyAqIGFwcGxpY2F0aW9uIHRvIGRlY2lkZSB3aGV0aGVyIHRvIHRocm93IGFuIDxjb2RlPkV4Y2VwdGlvbjwvY29kZT4gZm9yCisgKiBkaWZmZXJlbnQgdHlwZXMgb2YgZXJyb3JzIGFuZCB3YXJuaW5ncy4gIE5vdGUgaG93ZXZlciB0aGF0IHRoZQorICogPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+IGlzIG5vdCByZXF1aXJlZCB0byBjb250aW51ZSB3aXRoIHRoZSB0cmFuc2Zvcm1hdGlvbgorICogYWZ0ZXIgYSBjYWxsIHRvIHtAbGluayAjZmF0YWxFcnJvcihUcmFuc2Zvcm1lckV4Y2VwdGlvbiBleGNlcHRpb24pfS48L3A+CisgKgorICogPHA+PGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+cyBtYXkgdXNlIHRoaXMgbWVjaGFuaXNtIHRvIHJlcG9ydCBYTUwgcGFyc2luZworICogZXJyb3JzIGFzIHdlbGwgYXMgdHJhbnNmb3JtYXRpb24gZXJyb3JzLjwvcD4KKyAqLworcHVibGljIGludGVyZmFjZSBFcnJvckxpc3RlbmVyIHsKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgd2FybmluZy4KKyAgICAgKgorICAgICAqIDxwPntAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyfSBjYW4gdXNlIHRoaXMgbWV0aG9kIHRvIHJlcG9ydAorICAgICAqIGNvbmRpdGlvbnMgdGhhdCBhcmUgbm90IGVycm9ycyBvciBmYXRhbCBlcnJvcnMuICBUaGUgZGVmYXVsdCBiZWhhdmlvcgorICAgICAqIGlzIHRvIHRha2Ugbm8gYWN0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkFmdGVyIGludm9raW5nIHRoaXMgbWV0aG9kLCB0aGUgVHJhbnNmb3JtZXIgbXVzdCBjb250aW51ZSB3aXRoCisgICAgICogdGhlIHRyYW5zZm9ybWF0aW9uLiBJdCBzaG91bGQgc3RpbGwgYmUgcG9zc2libGUgZm9yIHRoZQorICAgICAqIGFwcGxpY2F0aW9uIHRvIHByb2Nlc3MgdGhlIGRvY3VtZW50IHRocm91Z2ggdG8gdGhlIGVuZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSB3YXJuaW5nIGluZm9ybWF0aW9uIGVuY2Fwc3VsYXRlZCBpbiBhCisgICAgICogICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lciBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlIGFwcGxpY2F0aW9uCisgICAgICogY2hvb3NlcyB0byBkaXNjb250aW51ZSB0aGUgdHJhbnNmb3JtYXRpb24uCisgICAgICoKKyAgICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB3YXJuaW5nKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGV4Y2VwdGlvbikKKyAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSByZWNvdmVyYWJsZSBlcnJvci4KKyAgICAgKgorICAgICAqIDxwPlRoZSB0cmFuc2Zvcm1lciBtdXN0IGNvbnRpbnVlIHRvIHRyeSBhbmQgcHJvdmlkZSBub3JtYWwgdHJhbnNmb3JtYXRpb24KKyAgICAgKiBhZnRlciBpbnZva2luZyB0aGlzIG1ldGhvZC4gIEl0IHNob3VsZCBzdGlsbCBiZSBwb3NzaWJsZSBmb3IgdGhlCisgICAgICogYXBwbGljYXRpb24gdG8gcHJvY2VzcyB0aGUgZG9jdW1lbnQgdGhyb3VnaCB0byB0aGUgZW5kIGlmIG5vIG90aGVyIGVycm9ycworICAgICAqIGFyZSBlbmNvdW50ZXJlZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSBlcnJvciBpbmZvcm1hdGlvbiBlbmNhcHN1bGF0ZWQgaW4gYQorICAgICAqICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZXIgZXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHRoZSBhcHBsaWNhdGlvbgorICAgICAqIGNob29zZXMgdG8gZGlzY29udGludWUgdGhlIHRyYW5zZm9ybWF0aW9uLgorICAgICAqCisgICAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZXJyb3IoVHJhbnNmb3JtZXJFeGNlcHRpb24gZXhjZXB0aW9uKQorICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiA8cD5SZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIG5vbi1yZWNvdmVyYWJsZSBlcnJvci48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+IG11c3QgY29udGludWUgdG8gdHJ5IGFuZCBwcm92aWRlIG5vcm1hbAorICAgICAqIHRyYW5zZm9ybWF0aW9uIGFmdGVyIGludm9raW5nIHRoaXMgbWV0aG9kLiAgSXQgc2hvdWxkIHN0aWxsIGJlIHBvc3NpYmxlIGZvciB0aGUKKyAgICAgKiBhcHBsaWNhdGlvbiB0byBwcm9jZXNzIHRoZSBkb2N1bWVudCB0aHJvdWdoIHRvIHRoZSBlbmQgaWYgbm8gb3RoZXIgZXJyb3JzCisgICAgICogYXJlIGVuY291bnRlcmVkLCBidXQgdGhlcmUgaXMgbm8gZ3VhcmFudGVlIHRoYXQgdGhlIG91dHB1dCB3aWxsIGJlCisgICAgICogdXNlYWJsZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSBlcnJvciBpbmZvcm1hdGlvbiBlbmNhcHN1bGF0ZWQgaW4gYQorICAgICAqICAgIDxjb2RlPlRyYW5zZm9ybWVyRXhjZXB0aW9uPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiB0aGUgYXBwbGljYXRpb24KKyAgICAgKiBjaG9vc2VzIHRvIGRpc2NvbnRpbnVlIHRoZSB0cmFuc2Zvcm1hdGlvbi4KKyAgICAgKgorICAgICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGZhdGFsRXJyb3IoVHJhbnNmb3JtZXJFeGNlcHRpb24gZXhjZXB0aW9uKQorICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9PdXRwdXRLZXlzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9PdXRwdXRLZXlzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODM4M2NkYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL091dHB1dEtleXMuamF2YQpAQCAtMCwwICsxLDE5MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vICRJZDogT3V0cHV0S2V5cy5qYXZhIDU2OTk5NCAyMDA3LTA4LTI3IDA0OjI4OjU3WiBtcmdsYXZhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybTsKKworLyoqCisgKiBQcm92aWRlcyBzdHJpbmcgY29uc3RhbnRzIHRoYXQgY2FuIGJlIHVzZWQgdG8gc2V0CisgKiBvdXRwdXQgcHJvcGVydGllcyBmb3IgYSBUcmFuc2Zvcm1lciwgb3IgdG8gcmV0cmlldmUKKyAqIG91dHB1dCBwcm9wZXJ0aWVzIGZyb20gYSBUcmFuc2Zvcm1lciBvciBUZW1wbGF0ZXMgb2JqZWN0LgorICogPHA+QWxsIHRoZSBmaWVsZHMgaW4gdGhpcyBjbGFzcyBhcmUgcmVhZC1vbmx5LjwvcD4KKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjb3V0cHV0Ij4KKyAqICBzZWN0aW9uIDE2IG9mIHRoZSBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBXM0MgUmVjb21tZW5kYXRpb248L2E+CisgKi8KK3B1YmxpYyBjbGFzcyBPdXRwdXRLZXlzIHsKKworICAgIC8qKgorICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IgaXMgcHJpdmF0ZSBvbiBwdXJwb3NlLiAgVGhpcyBjbGFzcyBpcworICAgICAqIG9ubHkgZm9yIHN0YXRpYyB2YXJpYWJsZSBhY2Nlc3MsIGFuZCBzaG91bGQgbmV2ZXIgYmUgY29uc3RydWN0ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBPdXRwdXRLZXlzKCkgeyB9CisKKyAgICAvKioKKyAgICAgKiBtZXRob2QgPSAieG1sIiB8ICJodG1sIiB8ICJ0ZXh0IiB8IDx2YXI+ZXhwYW5kZWQgbmFtZTwvdmFyPi4KKyAgICAgKgorICAgICAqIDxwPlRoZSB2YWx1ZSBvZiB0aGUgbWV0aG9kIHByb3BlcnR5IGlkZW50aWZpZXMgdGhlIG92ZXJhbGwgbWV0aG9kIHRoYXQKKyAgICAgKiBzaG91bGQgYmUgdXNlZCBmb3Igb3V0cHV0dGluZyB0aGUgcmVzdWx0IHRyZWUuICBPdGhlciBub24tbmFtZXNwYWNlZAorICAgICAqIHZhbHVlcyBtYXkgYmUgdXNlZCwgc3VjaCBhcyAieGh0bWwiLCBidXQsIGlmIGFjY2VwdGVkLCB0aGUgaGFuZGxpbmcKKyAgICAgKiBvZiBzdWNoIHZhbHVlcyBpcyBpbXBsZW1lbnRhdGlvbiBkZWZpbmVkLiAgSWYgYW55IG9mIHRoZSBtZXRob2QgdmFsdWVzCisgICAgICogYXJlIG5vdCBhY2NlcHRlZCBhbmQgYXJlIG5vdCBuYW1lc3BhY2UgcXVhbGlmaWVkLAorICAgICAqIHRoZW4ge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXIjc2V0T3V0cHV0UHJvcGVydHl9CisgICAgICogb3Ige0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXIjc2V0T3V0cHV0UHJvcGVydGllc30gd2lsbAorICAgICAqIHRocm93IGEge0BsaW5rIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259LjwvcD4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNvdXRwdXQiPgorICAgICAqICBzZWN0aW9uIDE2IG9mIHRoZSBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBXM0MgUmVjb21tZW5kYXRpb248L2E+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUVUSE9EID0gIm1ldGhvZCI7CisKKyAgICAvKioKKyAgICAgKiB2ZXJzaW9uID0gPHZhcj5ubXRva2VuPC92YXI+LgorICAgICAqCisgICAgICogPHA+PGNvZGU+dmVyc2lvbjwvY29kZT4gc3BlY2lmaWVzIHRoZSB2ZXJzaW9uIG9mIHRoZSBvdXRwdXQKKyAgICAgKiBtZXRob2QuPC9wPgorICAgICAqIDxwPldoZW4gdGhlIG91dHB1dCBtZXRob2QgaXMgInhtbCIsIHRoZSB2ZXJzaW9uIHZhbHVlIHNwZWNpZmllcyB0aGUKKyAgICAgKiB2ZXJzaW9uIG9mIFhNTCB0byBiZSB1c2VkIGZvciBvdXRwdXR0aW5nIHRoZSByZXN1bHQgdHJlZS4gVGhlIGRlZmF1bHQKKyAgICAgKiB2YWx1ZSBmb3IgdGhlIHhtbCBvdXRwdXQgbWV0aG9kIGlzIDEuMC4gV2hlbiB0aGUgb3V0cHV0IG1ldGhvZCBpcworICAgICAqICJodG1sIiwgdGhlIHZlcnNpb24gdmFsdWUgaW5kaWNhdGVzIHRoZSB2ZXJzaW9uIG9mIHRoZSBIVE1MLgorICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlIGZvciB0aGUgeG1sIG91dHB1dCBtZXRob2QgaXMgNC4wLCB3aGljaCBzcGVjaWZpZXMKKyAgICAgKiB0aGF0IHRoZSByZXN1bHQgc2hvdWxkIGJlIG91dHB1dCBhcyBIVE1MIGNvbmZvcm1pbmcgdG8gdGhlIEhUTUwgNC4wCisgICAgICogUmVjb21tZW5kYXRpb24gW0hUTUxdLiAgSWYgdGhlIG91dHB1dCBtZXRob2QgaXMgInRleHQiLCB0aGUgdmVyc2lvbgorICAgICAqIHByb3BlcnR5IGlzIGlnbm9yZWQuPC9wPgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNvdXRwdXQiPgorICAgICAqICBzZWN0aW9uIDE2IG9mIHRoZSBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBXM0MgUmVjb21tZW5kYXRpb248L2E+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkVSU0lPTiA9ICJ2ZXJzaW9uIjsKKworICAgIC8qKgorICAgICAqIGVuY29kaW5nID0gPHZhcj5zdHJpbmc8L3Zhcj4uCisgICAgICoKKyAgICAgKiA8cD48Y29kZT5lbmNvZGluZzwvY29kZT4gc3BlY2lmaWVzIHRoZSBwcmVmZXJyZWQgY2hhcmFjdGVyCisgICAgICogZW5jb2RpbmcgdGhhdCB0aGUgVHJhbnNmb3JtZXIgc2hvdWxkIHVzZSB0byBlbmNvZGUgc2VxdWVuY2VzIG9mCisgICAgICogY2hhcmFjdGVycyBhcyBzZXF1ZW5jZXMgb2YgYnl0ZXMuIFRoZSB2YWx1ZSBvZiB0aGUgZW5jb2RpbmcgcHJvcGVydHkgc2hvdWxkIGJlCisgICAgICogdHJlYXRlZCBjYXNlLWluc2Vuc2l0aXZlbHkuIFRoZSB2YWx1ZSBtdXN0IG9ubHkgY29udGFpbiBjaGFyYWN0ZXJzIGluCisgICAgICogdGhlIHJhbmdlICN4MjEgdG8gI3g3RSAoaS5lLiwgcHJpbnRhYmxlIEFTQ0lJIGNoYXJhY3RlcnMpLiBUaGUgdmFsdWUKKyAgICAgKiBzaG91bGQgZWl0aGVyIGJlIGEgPGNvZGU+Y2hhcnNldDwvY29kZT4gcmVnaXN0ZXJlZCB3aXRoIHRoZSBJbnRlcm5ldAorICAgICAqIEFzc2lnbmVkIE51bWJlcnMgQXV0aG9yaXR5IDxhIGhyZWY9IiNJQU5BIj5bSUFOQV08L2E+LAorICAgICAqIDxhIGhyZWY9IiNSRkMyMjc4Ij5bUkZDMjI3OF08L2E+IG9yIHN0YXJ0IHdpdGggPGNvZGU+WC08L2NvZGU+LjwvcD4KKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjb3V0cHV0Ij4KKyAgICAgKiBzZWN0aW9uIDE2IG9mIHRoZSBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBXM0MgUmVjb21tZW5kYXRpb248L2E+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5DT0RJTkcgPSAiZW5jb2RpbmciOworCisgICAgLyoqCisgICAgICogb21pdC14bWwtZGVjbGFyYXRpb24gPSAieWVzIiB8ICJubyIuCisgICAgICoKKyAgICAgKiA8cD48Y29kZT5vbWl0LXhtbC1kZWNsYXJhdGlvbjwvY29kZT4gc3BlY2lmaWVzIHdoZXRoZXIgdGhlIFhTTFQKKyAgICAgKiBwcm9jZXNzb3Igc2hvdWxkIG91dHB1dCBhbiBYTUwgZGVjbGFyYXRpb247IHRoZSB2YWx1ZSBtdXN0IGJlCisgICAgICogPGNvZGU+eWVzPC9jb2RlPiBvciA8Y29kZT5ubzwvY29kZT4uPC9wPgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNvdXRwdXQiPgorICAgICAqICBzZWN0aW9uIDE2IG9mIHRoZSBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBXM0MgUmVjb21tZW5kYXRpb248L2E+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgT01JVF9YTUxfREVDTEFSQVRJT04gPSAib21pdC14bWwtZGVjbGFyYXRpb24iOworCisgICAgLyoqCisgICAgICogc3RhbmRhbG9uZSA9ICJ5ZXMiIHwgIm5vIi4KKyAgICAgKgorICAgICAqIDxwPjxjb2RlPnN0YW5kYWxvbmU8L2NvZGU+IHNwZWNpZmllcyB3aGV0aGVyIHRoZSBUcmFuc2Zvcm1lcgorICAgICAqIHNob3VsZCBvdXRwdXQgYSBzdGFuZGFsb25lIGRvY3VtZW50IGRlY2xhcmF0aW9uOyB0aGUgdmFsdWUgbXVzdCBiZQorICAgICAqIDxjb2RlPnllczwvY29kZT4gb3IgPGNvZGU+bm88L2NvZGU+LjwvcD4KKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjb3V0cHV0Ij4KKyAgICAgKiAgc2VjdGlvbiAxNiBvZiB0aGUgWFNMIFRyYW5zZm9ybWF0aW9ucyAoWFNMVCkgVzNDIFJlY29tbWVuZGF0aW9uPC9hPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUQU5EQUxPTkUgPSAic3RhbmRhbG9uZSI7CisKKyAgICAvKioKKyAgICAgKiBkb2N0eXBlLXB1YmxpYyA9IDx2YXI+c3RyaW5nPC92YXI+LgorICAgICAqIDxwPlNlZSB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgdGhlIHtAbGluayAjRE9DVFlQRV9TWVNURU19IHByb3BlcnR5CisgICAgICogZm9yIGEgZGVzY3JpcHRpb24gb2Ygd2hhdCB0aGUgdmFsdWUgb2YgdGhlIGtleSBzaG91bGQgYmUuPC9wPgorICAgICAqCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I291dHB1dCI+CisgICAgICogIHNlY3Rpb24gMTYgb2YgdGhlIFhTTCBUcmFuc2Zvcm1hdGlvbnMgKFhTTFQpIFczQyBSZWNvbW1lbmRhdGlvbjwvYT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET0NUWVBFX1BVQkxJQyA9ICJkb2N0eXBlLXB1YmxpYyI7CisKKyAgICAvKioKKyAgICAgKiBkb2N0eXBlLXN5c3RlbSA9IDx2YXI+c3RyaW5nPC92YXI+LgorICAgICAqIDxwPjxjb2RlPmRvY3R5cGUtc3lzdGVtPC9jb2RlPiBzcGVjaWZpZXMgdGhlIHN5c3RlbSBpZGVudGlmaWVyCisgICAgICogdG8gYmUgdXNlZCBpbiB0aGUgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbi48L3A+CisgICAgICogPHA+SWYgdGhlIGRvY3R5cGUtc3lzdGVtIHByb3BlcnR5IGlzIHNwZWNpZmllZCwgdGhlIHhtbCBvdXRwdXQgbWV0aG9kCisgICAgICogc2hvdWxkIG91dHB1dCBhIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24gaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSBmaXJzdAorICAgICAqIGVsZW1lbnQuIFRoZSBuYW1lIGZvbGxvd2luZyAmbHQ7IURPQ1RZUEUgc2hvdWxkIGJlIHRoZSBuYW1lIG9mIHRoZSBmaXJzdAorICAgICAqIGVsZW1lbnQuIElmIGRvY3R5cGUtcHVibGljIHByb3BlcnR5IGlzIGFsc28gc3BlY2lmaWVkLCB0aGVuIHRoZSB4bWwKKyAgICAgKiBvdXRwdXQgbWV0aG9kIHNob3VsZCBvdXRwdXQgUFVCTElDIGZvbGxvd2VkIGJ5IHRoZSBwdWJsaWMgaWRlbnRpZmllcgorICAgICAqIGFuZCB0aGVuIHRoZSBzeXN0ZW0gaWRlbnRpZmllcjsgb3RoZXJ3aXNlLCBpdCBzaG91bGQgb3V0cHV0IFNZU1RFTQorICAgICAqIGZvbGxvd2VkIGJ5IHRoZSBzeXN0ZW0gaWRlbnRpZmllci4gVGhlIGludGVybmFsIHN1YnNldCBzaG91bGQgYmUgZW1wdHkuCisgICAgICogVGhlIHZhbHVlIG9mIHRoZSBkb2N0eXBlLXB1YmxpYyBwcm9wZXJ0eSBzaG91bGQgYmUgaWdub3JlZCB1bmxlc3MgdGhlIGRvY3R5cGUtc3lzdGVtCisgICAgICogcHJvcGVydHkgaXMgc3BlY2lmaWVkLjwvcD4KKyAgICAgKiA8cD5JZiB0aGUgZG9jdHlwZS1wdWJsaWMgb3IgZG9jdHlwZS1zeXN0ZW0gcHJvcGVydGllcyBhcmUgc3BlY2lmaWVkLAorICAgICAqIHRoZW4gdGhlIGh0bWwgb3V0cHV0IG1ldGhvZCBzaG91bGQgb3V0cHV0IGEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbgorICAgICAqIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgZmlyc3QgZWxlbWVudC4gVGhlIG5hbWUgZm9sbG93aW5nICZsdDshRE9DVFlQRQorICAgICAqIHNob3VsZCBiZSBIVE1MIG9yIGh0bWwuIElmIHRoZSBkb2N0eXBlLXB1YmxpYyBwcm9wZXJ0eSBpcyBzcGVjaWZpZWQsCisgICAgICogdGhlbiB0aGUgb3V0cHV0IG1ldGhvZCBzaG91bGQgb3V0cHV0IFBVQkxJQyBmb2xsb3dlZCBieSB0aGUgc3BlY2lmaWVkCisgICAgICogcHVibGljIGlkZW50aWZpZXI7IGlmIHRoZSBkb2N0eXBlLXN5c3RlbSBwcm9wZXJ0eSBpcyBhbHNvIHNwZWNpZmllZCwKKyAgICAgKiBpdCBzaG91bGQgYWxzbyBvdXRwdXQgdGhlIHNwZWNpZmllZCBzeXN0ZW0gaWRlbnRpZmllciBmb2xsb3dpbmcgdGhlCisgICAgICogcHVibGljIGlkZW50aWZpZXIuIElmIHRoZSBkb2N0eXBlLXN5c3RlbSBwcm9wZXJ0eSBpcyBzcGVjaWZpZWQgYnV0CisgICAgICogdGhlIGRvY3R5cGUtcHVibGljIHByb3BlcnR5IGlzIG5vdCBzcGVjaWZpZWQsIHRoZW4gdGhlIG91dHB1dCBtZXRob2QKKyAgICAgKiBzaG91bGQgb3V0cHV0IFNZU1RFTSBmb2xsb3dlZCBieSB0aGUgc3BlY2lmaWVkIHN5c3RlbSBpZGVudGlmaWVyLjwvcD4KKyAgICAgKgorICAgICAqIDxwPjxjb2RlPmRvY3R5cGUtc3lzdGVtPC9jb2RlPiBzcGVjaWZpZXMgdGhlIHN5c3RlbSBpZGVudGlmaWVyCisgICAgICogdG8gYmUgdXNlZCBpbiB0aGUgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbi48L3A+CisgICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I291dHB1dCI+CisgICAgICogIHNlY3Rpb24gMTYgb2YgdGhlIFhTTCBUcmFuc2Zvcm1hdGlvbnMgKFhTTFQpIFczQyBSZWNvbW1lbmRhdGlvbjwvYT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET0NUWVBFX1NZU1RFTSA9ICJkb2N0eXBlLXN5c3RlbSI7CisKKyAgICAvKioKKyAgICAgKiBjZGF0YS1zZWN0aW9uLWVsZW1lbnRzID0gPHZhcj5leHBhbmRlZCBuYW1lczwvdmFyPi4KKyAgICAgKgorICAgICAqIDxwPjxjb2RlPmNkYXRhLXNlY3Rpb24tZWxlbWVudHM8L2NvZGU+IHNwZWNpZmllcyBhIHdoaXRlc3BhY2UgZGVsaW1pdGVkCisgICAgICogbGlzdCBvZiB0aGUgbmFtZXMgb2YgZWxlbWVudHMgd2hvc2UgdGV4dCBub2RlIGNoaWxkcmVuIHNob3VsZCBiZSBvdXRwdXQKKyAgICAgKiB1c2luZyBDREFUQSBzZWN0aW9ucy4gTm90ZSB0aGF0IHRoZXNlIG5hbWVzIG11c3QgdXNlIHRoZSBmb3JtYXQKKyAgICAgKiBkZXNjcmliZWQgaW4gdGhlIHNlY3Rpb24gUXVhbGZpZWQgTmFtZSBSZXByZXNlbnRhdGlvbiBpbgorICAgICAqIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtfS48L3A+CisgICAgICoKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjb3V0cHV0Ij4KKyAgICAgKiAgc2VjdGlvbiAxNiBvZiB0aGUgWFNMIFRyYW5zZm9ybWF0aW9ucyAoWFNMVCkgVzNDIFJlY29tbWVuZGF0aW9uLjwvYT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDREFUQV9TRUNUSU9OX0VMRU1FTlRTID0KKyAgICAgICAgImNkYXRhLXNlY3Rpb24tZWxlbWVudHMiOworCisgICAgLyoqCisgICAgICogaW5kZW50ID0gInllcyIgfCAibm8iLgorICAgICAqCisgICAgICogPHA+PGNvZGU+aW5kZW50PC9jb2RlPiBzcGVjaWZpZXMgd2hldGhlciB0aGUgVHJhbnNmb3JtZXIgbWF5CisgICAgICogYWRkIGFkZGl0aW9uYWwgd2hpdGVzcGFjZSB3aGVuIG91dHB1dHRpbmcgdGhlIHJlc3VsdCB0cmVlOyB0aGUgdmFsdWUKKyAgICAgKiBtdXN0IGJlIDxjb2RlPnllczwvY29kZT4gb3IgPGNvZGU+bm88L2NvZGU+LiAgPC9wPgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNvdXRwdXQiPgorICAgICAqICBzZWN0aW9uIDE2IG9mIHRoZSBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBXM0MgUmVjb21tZW5kYXRpb248L2E+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5ERU5UID0gImluZGVudCI7CisKKyAgICAvKioKKyAgICAgKiBtZWRpYS10eXBlID0gPHZhcj5zdHJpbmc8L3Zhcj4uCisgICAgICoKKyAgICAgKiA8cD48Y29kZT5tZWRpYS10eXBlPC9jb2RlPiBzcGVjaWZpZXMgdGhlIG1lZGlhIHR5cGUgKE1JTUUKKyAgICAgKiBjb250ZW50IHR5cGUpIG9mIHRoZSBkYXRhIHRoYXQgcmVzdWx0cyBmcm9tIG91dHB1dHRpbmcgdGhlIHJlc3VsdAorICAgICAqIHRyZWUuIFRoZSA8Y29kZT5jaGFyc2V0PC9jb2RlPiBwYXJhbWV0ZXIgc2hvdWxkIG5vdCBiZSBzcGVjaWZpZWQKKyAgICAgKiBleHBsaWNpdGx5OyBpbnN0ZWFkLCB3aGVuIHRoZSB0b3AtbGV2ZWwgbWVkaWEgdHlwZSBpcworICAgICAqIDxjb2RlPnRleHQ8L2NvZGU+LCBhIDxjb2RlPmNoYXJzZXQ8L2NvZGU+IHBhcmFtZXRlciBzaG91bGQgYmUgYWRkZWQKKyAgICAgKiBhY2NvcmRpbmcgdG8gdGhlIGNoYXJhY3RlciBlbmNvZGluZyBhY3R1YWxseSB1c2VkIGJ5IHRoZSBvdXRwdXQKKyAgICAgKiBtZXRob2QuICA8L3A+CisgICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I291dHB1dCI+CisgICAgICogIHNlY3Rpb24gMTYgb2YgdGhlIFhTTCBUcmFuc2Zvcm1hdGlvbnMgKFhTTFQpIFczQyBSZWNvbW1lbmRhdGlvbjwvYT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNRURJQV9UWVBFID0gIm1lZGlhLXR5cGUiOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vUmVzdWx0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9SZXN1bHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZTRjMjg1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vUmVzdWx0LmphdmEKQEAgLTAsMCArMSw4MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vICAkSWQ6IFJlc3VsdC5qYXZhIDQ0NjU5OCAyMDA2LTA5LTE1IDEyOjU1OjQwWiBqZXJlbWlhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybTsKKworLyoqCisgKiA8cD5BbiBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoaXMgaW50ZXJmYWNlIGNvbnRhaW5zIHRoZSBpbmZvcm1hdGlvbgorICogbmVlZGVkIHRvIGJ1aWxkIGEgdHJhbnNmb3JtYXRpb24gcmVzdWx0IHRyZWUuPC9wPgorICoKKyAqIEBhdXRob3IgPGEgaHJlZj0iSmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUmVzdWx0IHsKKworICAgIC8qKgorICAgICAqIFRoZSBuYW1lIG9mIHRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRoYXQgaXMgc2VudCBpZiB0aGUKKyAgICAgKiByZXN1bHQgdHJlZSBkaXNhYmxlcyBvdXRwdXQgZXNjYXBpbmcuCisgICAgICoKKyAgICAgKiA8cD5Ob3JtYWxseSwgcmVzdWx0IHRyZWUgc2VyaWFsaXphdGlvbiBlc2NhcGVzICYgYW5kIDwgKGFuZAorICAgICAqIHBvc3NpYmx5IG90aGVyIGNoYXJhY3RlcnMpIHdoZW4gb3V0cHV0dGluZyB0ZXh0IG5vZGVzLgorICAgICAqIFRoaXMgZW5zdXJlcyB0aGF0IHRoZSBvdXRwdXQgaXMgd2VsbC1mb3JtZWQgWE1MLiBIb3dldmVyLAorICAgICAqIGl0IGlzIHNvbWV0aW1lcyBjb252ZW5pZW50IHRvIGJlIGFibGUgdG8gcHJvZHVjZSBvdXRwdXQgdGhhdCBpcworICAgICAqIGFsbW9zdCwgYnV0IG5vdCBxdWl0ZSB3ZWxsLWZvcm1lZCBYTUw7IGZvciBleGFtcGxlLAorICAgICAqIHRoZSBvdXRwdXQgbWF5IGluY2x1ZGUgaWxsLWZvcm1lZCBzZWN0aW9ucyB0aGF0IHdpbGwKKyAgICAgKiBiZSB0cmFuc2Zvcm1lZCBpbnRvIHdlbGwtZm9ybWVkIFhNTCBieSBhIHN1YnNlcXVlbnQgbm9uLVhNTCBhd2FyZQorICAgICAqIHByb2Nlc3MuIElmIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBpcyBzZW50IHdpdGggdGhpcyBuYW1lLAorICAgICAqIHNlcmlhbGl6YXRpb24gc2hvdWxkIGJlIG91dHB1dCB3aXRob3V0IGFueSBlc2NhcGluZy4gPC9wPgorICAgICAqCisgICAgICogPHA+UmVzdWx0IERPTSB0cmVlcyBtYXkgYWxzbyBoYXZlIFBJX0RJU0FCTEVfT1VUUFVUX0VTQ0FQSU5HIGFuZAorICAgICAqIFBJX0VOQUJMRV9PVVRQVVRfRVNDQVBJTkcgaW5zZXJ0ZWQgaW50byB0aGUgdHJlZS48L3A+CisgICAgICoKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZGlzYWJsZS1vdXRwdXQtZXNjYXBpbmciPmRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQSV9ESVNBQkxFX09VVFBVVF9FU0NBUElORyA9CisgICAgICAgICJqYXZheC54bWwudHJhbnNmb3JtLmRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIjsKKworICAgIC8qKgorICAgICAqIFRoZSBuYW1lIG9mIHRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRoYXQgaXMgc2VudAorICAgICAqIGlmIHRoZSByZXN1bHQgdHJlZSBlbmFibGVzIG91dHB1dCBlc2NhcGluZyBhdCBzb21lIHBvaW50IGFmdGVyIGhhdmluZworICAgICAqIHJlY2VpdmVkIGEgUElfRElTQUJMRV9PVVRQVVRfRVNDQVBJTkcgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkaXNhYmxlLW91dHB1dC1lc2NhcGluZyI+ZGlzYWJsZS1vdXRwdXQtZXNjYXBpbmcgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBJX0VOQUJMRV9PVVRQVVRfRVNDQVBJTkcgPQorICAgICAgICAiamF2YXgueG1sLnRyYW5zZm9ybS5lbmFibGUtb3V0cHV0LWVzY2FwaW5nIjsKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoaXMgUmVzdWx0LgorICAgICAqCisgICAgICogPHA+SWYgdGhlIFJlc3VsdCBpcyBub3QgdG8gYmUgd3JpdHRlbiB0byBhIGZpbGUsIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBvcHRpb25hbC4KKyAgICAgKiBUaGUgYXBwbGljYXRpb24gbWF5IHN0aWxsIHdhbnQgdG8gcHJvdmlkZSBvbmUsIGhvd2V2ZXIsIGZvciB1c2UgaW4gZXJyb3IgbWVzc2FnZXMKKyAgICAgKiBhbmQgd2FybmluZ3MsIG9yIHRvIHJlc29sdmUgcmVsYXRpdmUgb3V0cHV0IGlkZW50aWZpZXJzLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgYXMgYSBVUkkgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCk7CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHN5c3RlbSBpZGVudGlmaWVyIHRoYXQgd2FzIHNldCB3aXRoIHNldFN5c3RlbUlkLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgc3lzdGVtIGlkZW50aWZpZXIgdGhhdCB3YXMgc2V0IHdpdGggc2V0U3lzdGVtSWQsCisgICAgICogb3IgbnVsbCBpZiBzZXRTeXN0ZW1JZCB3YXMgbm90IGNhbGxlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9Tb3VyY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL1NvdXJjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ0Y2JmMjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9Tb3VyY2UuamF2YQpAQCAtMCwwICsxLDQ3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8gJElkOiBTb3VyY2UuamF2YSA0NDY1OTggMjAwNi0wOS0xNSAxMjo1NTo0MFogamVyZW1pYXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm07CisKKy8qKgorICogQW4gb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSBjb250YWlucyB0aGUgaW5mb3JtYXRpb24KKyAqIG5lZWRlZCB0byBhY3QgYXMgc291cmNlIGlucHV0IChYTUwgc291cmNlIG9yIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucykuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgU291cmNlIHsKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoaXMgU291cmNlLgorICAgICAqCisgICAgICogPHA+VGhlIHN5c3RlbSBpZGVudGlmaWVyIGlzIG9wdGlvbmFsIGlmIHRoZSBzb3VyY2UgZG9lcyBub3QKKyAgICAgKiBnZXQgaXRzIGRhdGEgZnJvbSBhIFVSTCwgYnV0IGl0IG1heSBzdGlsbCBiZSB1c2VmdWwgdG8gcHJvdmlkZSBvbmUuCisgICAgICogVGhlIGFwcGxpY2F0aW9uIGNhbiB1c2UgYSBzeXN0ZW0gaWRlbnRpZmllciwgZm9yIGV4YW1wbGUsIHRvIHJlc29sdmUKKyAgICAgKiByZWxhdGl2ZSBVUklzIGFuZCB0byBpbmNsdWRlIGluIGVycm9yIG1lc3NhZ2VzIGFuZCB3YXJuaW5ncy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIGFzIGEgVVJMIHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQpOworCisgICAgLyoqCisgICAgICogR2V0IHRoZSBzeXN0ZW0gaWRlbnRpZmllciB0aGF0IHdhcyBzZXQgd2l0aCBzZXRTeXN0ZW1JZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIHN5c3RlbSBpZGVudGlmaWVyIHRoYXQgd2FzIHNldCB3aXRoIHNldFN5c3RlbUlkLCBvciBudWxsCisgICAgICogaWYgc2V0U3lzdGVtSWQgd2FzIG5vdCBjYWxsZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vU291cmNlTG9jYXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vU291cmNlTG9jYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYzMmVlZTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9Tb3VyY2VMb2NhdG9yLmphdmEKQEAgLTAsMCArMSw5MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vICRJZDogU291cmNlTG9jYXRvci5qYXZhIDQ0NjU5OCAyMDA2LTA5LTE1IDEyOjU1OjQwWiBqZXJlbWlhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybTsKKworLyoqCisgKiBUaGlzIGludGVyZmFjZSBpcyBwcmltYXJpbHkgZm9yIHRoZSBwdXJwb3NlcyBvZiByZXBvcnRpbmcgd2hlcmUKKyAqIGFuIGVycm9yIG9jY3VycmVkIGluIHRoZSBYTUwgc291cmNlIG9yIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucy4KKyAqLworcHVibGljIGludGVyZmFjZSBTb3VyY2VMb2NhdG9yIHsKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50LgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGRvY3VtZW50CisgICAgICogZW50aXR5IG9yIG9mIHRoZSBleHRlcm5hbCBwYXJzZWQgZW50aXR5IGluIHdoaWNoIHRoZSBtYXJrdXAgdGhhdAorICAgICAqIHRyaWdnZXJlZCB0aGUgZXZlbnQgYXBwZWFycy48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHB1YmxpYyBpZGVudGlmaWVyLCBvcgorICAgICAqICAgICAgICAgbnVsbCBpZiBub25lIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBAc2VlICNnZXRTeXN0ZW1JZAorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50LgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGRvY3VtZW50CisgICAgICogZW50aXR5IG9yIG9mIHRoZSBleHRlcm5hbCBwYXJzZWQgZW50aXR5IGluIHdoaWNoIHRoZSBtYXJrdXAgdGhhdAorICAgICAqIHRyaWdnZXJlZCB0aGUgZXZlbnQgYXBwZWFycy48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwsIHRoZSBwYXJzZXIgbXVzdCByZXNvbHZlIGl0CisgICAgICogZnVsbHkgYmVmb3JlIHBhc3NpbmcgaXQgdG8gdGhlIGFwcGxpY2F0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQSBzdHJpbmcgY29udGFpbmluZyB0aGUgc3lzdGVtIGlkZW50aWZpZXIsIG9yIG51bGwKKyAgICAgKiAgICAgICAgIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgorICAgICAqIEBzZWUgI2dldFB1YmxpY0lkCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBsaW5lIG51bWJlciB3aGVyZSB0aGUgY3VycmVudCBkb2N1bWVudCBldmVudCBlbmRzLgorICAgICAqCisgICAgICogPHA+PHN0cm9uZz5XYXJuaW5nOjwvc3Ryb25nPiBUaGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIG1ldGhvZAorICAgICAqIGlzIGludGVuZGVkIG9ubHkgYXMgYW4gYXBwcm94aW1hdGlvbiBmb3IgdGhlIHNha2Ugb2YgZXJyb3IKKyAgICAgKiByZXBvcnRpbmc7IGl0IGlzIG5vdCBpbnRlbmRlZCB0byBwcm92aWRlIHN1ZmZpY2llbnQgaW5mb3JtYXRpb24KKyAgICAgKiB0byBlZGl0IHRoZSBjaGFyYWN0ZXIgY29udGVudCBvZiB0aGUgb3JpZ2luYWwgWE1MIGRvY3VtZW50LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSByZXR1cm4gdmFsdWUgaXMgYW4gYXBwcm94aW1hdGlvbiBvZiB0aGUgbGluZSBudW1iZXIKKyAgICAgKiBpbiB0aGUgZG9jdW1lbnQgZW50aXR5IG9yIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkgd2hlcmUgdGhlCisgICAgICogbWFya3VwIHRoYXQgdHJpZ2dlcmVkIHRoZSBldmVudCBhcHBlYXJzLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIGxpbmUgbnVtYmVyLCBvciAtMSBpZiBub25lIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBAc2VlICNnZXRDb2x1bW5OdW1iZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgY2hhcmFjdGVyIHBvc2l0aW9uIHdoZXJlIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50IGVuZHMuCisgICAgICoKKyAgICAgKiA8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IFRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgbWV0aG9kCisgICAgICogaXMgaW50ZW5kZWQgb25seSBhcyBhbiBhcHByb3hpbWF0aW9uIGZvciB0aGUgc2FrZSBvZiBlcnJvcgorICAgICAqIHJlcG9ydGluZzsgaXQgaXMgbm90IGludGVuZGVkIHRvIHByb3ZpZGUgc3VmZmljaWVudCBpbmZvcm1hdGlvbgorICAgICAqIHRvIGVkaXQgdGhlIGNoYXJhY3RlciBjb250ZW50IG9mIHRoZSBvcmlnaW5hbCBYTUwgZG9jdW1lbnQuPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybiB2YWx1ZSBpcyBhbiBhcHByb3hpbWF0aW9uIG9mIHRoZSBjb2x1bW4gbnVtYmVyCisgICAgICogaW4gdGhlIGRvY3VtZW50IGVudGl0eSBvciBleHRlcm5hbCBwYXJzZWQgZW50aXR5IHdoZXJlIHRoZQorICAgICAqIG1hcmt1cCB0aGF0IHRyaWdnZXJlZCB0aGUgZXZlbnQgYXBwZWFycy48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBjb2x1bW4gbnVtYmVyLCBvciAtMSBpZiBub25lIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBAc2VlICNnZXRMaW5lTnVtYmVyCisgICAgICovCisgICAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL1RlbXBsYXRlcy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vVGVtcGxhdGVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWQ2ZjQ2YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL1RlbXBsYXRlcy5qYXZhCkBAIC0wLDAgKzEsNzMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLyAkSWQ6IFRlbXBsYXRlcy5qYXZhIDU3MDEwMyAyMDA3LTA4LTI3IDEzOjI0OjU1WiBtcmdsYXZhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybTsKKworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworCisvKioKKyAqIEFuIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UgaXMgdGhlIHJ1bnRpbWUgcmVwcmVzZW50YXRpb24gb2YgcHJvY2Vzc2VkCisgKiB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuCisgKgorICogPHA+VGVtcGxhdGVzIG11c3QgYmUgdGhyZWFkLXNhZmUgZm9yIGEgZ2l2ZW4gaW5zdGFuY2UKKyAqIG92ZXIgbXVsdGlwbGUgdGhyZWFkcyBydW5uaW5nIGNvbmN1cnJlbnRseSwgYW5kIG1heQorICogYmUgdXNlZCBtdWx0aXBsZSB0aW1lcyBpbiBhIGdpdmVuIHNlc3Npb24uPC9wPgorICovCitwdWJsaWMgaW50ZXJmYWNlIFRlbXBsYXRlcyB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgdHJhbnNmb3JtYXRpb24gY29udGV4dCBmb3IgdGhpcyBUZW1wbGF0ZXMgb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybiBBIHZhbGlkIG5vbi1udWxsIGluc3RhbmNlIG9mIGEgVHJhbnNmb3JtZXIuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBpZiBhIFRyYW5zZm9ybWVyIGNhbiBub3QgYmUgY3JlYXRlZC4KKyAgICAgKi8KKyAgICBUcmFuc2Zvcm1lciBuZXdUcmFuc2Zvcm1lcigpIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHByb3BlcnRpZXMgY29ycmVzcG9uZGluZyB0byB0aGUgZWZmZWN0aXZlIHhzbDpvdXRwdXQgZWxlbWVudC4KKyAgICAgKiBUaGUgb2JqZWN0IHJldHVybmVkIHdpbGwKKyAgICAgKiBiZSBhIGNsb25lIG9mIHRoZSBpbnRlcm5hbCB2YWx1ZXMuIEFjY29yZGluZ2x5LCBpdCBjYW4gYmUgbXV0YXRlZAorICAgICAqIHdpdGhvdXQgbXV0YXRpbmcgdGhlIFRlbXBsYXRlcyBvYmplY3QsIGFuZCB0aGVuIGhhbmRlZCBpbiB0bworICAgICAqIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyI3NldE91dHB1dFByb3BlcnRpZXN9LgorICAgICAqCisgICAgICogPHA+VGhlIHByb3BlcnRpZXMgcmV0dXJuZWQgc2hvdWxkIGNvbnRhaW4gcHJvcGVydGllcyBzZXQgYnkgdGhlIHN0eWxlc2hlZXQsCisgICAgICogYW5kIHRoZXNlIHByb3BlcnRpZXMgYXJlICJkZWZhdWx0ZWQiIGJ5IGRlZmF1bHQgcHJvcGVydGllcyBzcGVjaWZpZWQgYnkKKyAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I291dHB1dCI+c2VjdGlvbiAxNiBvZiB0aGUKKyAgICAgKiBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBXM0MgUmVjb21tZW5kYXRpb248L2E+LiAgVGhlIHByb3BlcnRpZXMgdGhhdAorICAgICAqIHdlcmUgc3BlY2lmaWNhbGx5IHNldCBieSB0aGUgc3R5bGVzaGVldCBzaG91bGQgYmUgaW4gdGhlIGJhc2UKKyAgICAgKiBQcm9wZXJ0aWVzIGxpc3QsIHdoaWxlIHRoZSBYU0xUIGRlZmF1bHQgcHJvcGVydGllcyB0aGF0IHdlcmUgbm90CisgICAgICogc3BlY2lmaWNhbGx5IHNldCBzaG91bGQgYmUgaW4gdGhlICJkZWZhdWx0IiBQcm9wZXJ0aWVzIGxpc3QuICBUaHVzLAorICAgICAqIGdldE91dHB1dFByb3BlcnRpZXMoKS5nZXRQcm9wZXJ0eShTdHJpbmcga2V5KSB3aWxsIG9idGFpbiBhbnkKKyAgICAgKiBwcm9wZXJ0eSBpbiB0aGF0IHdhcyBzZXQgYnkgdGhlIHN0eWxlc2hlZXQsIDxlbT5vcjwvZW0+IHRoZSBkZWZhdWx0CisgICAgICogcHJvcGVydGllcywgd2hpbGUKKyAgICAgKiBnZXRPdXRwdXRQcm9wZXJ0aWVzKCkuZ2V0KFN0cmluZyBrZXkpIHdpbGwgb25seSByZXRyaWV2ZSBwcm9wZXJ0aWVzCisgICAgICogdGhhdCB3ZXJlIGV4cGxpY2l0bHkgc2V0IGluIHRoZSBzdHlsZXNoZWV0LjwvcD4KKyAgICAgKgorICAgICAqIDxwPkZvciBYU0xULAorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjYXR0cmlidXRlLXZhbHVlLXRlbXBsYXRlcyI+QXR0cmlidXRlCisgICAgICogVmFsdWUgVGVtcGxhdGVzPC9hPiBhdHRyaWJ1dGUgdmFsdWVzIHdpbGwKKyAgICAgKiBiZSByZXR1cm5lZCB1bmV4cGFuZGVkIChzaW5jZSB0aGVyZSBpcyBubyBjb250ZXh0IGF0IHRoaXMgcG9pbnQpLiAgVGhlCisgICAgICogbmFtZXNwYWNlIHByZWZpeGVzIGluc2lkZSBBdHRyaWJ1dGUgVmFsdWUgVGVtcGxhdGVzIHdpbGwgYmUgdW5leHBhbmRlZCwKKyAgICAgKiBzbyB0aGF0IHRoZXkgcmVtYWluIHZhbGlkIFhQYXRoIHZhbHVlcy48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEgUHJvcGVydGllcyBvYmplY3QsIG5ldmVyIG51bGwuCisgICAgICovCisgICAgUHJvcGVydGllcyBnZXRPdXRwdXRQcm9wZXJ0aWVzKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vVHJhbnNmb3JtZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOTRhOWVmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vVHJhbnNmb3JtZXIuamF2YQpAQCAtMCwwICsxLDMyMSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vICRJZDogVHJhbnNmb3JtZXIuamF2YSA1NzAxMDMgMjAwNy0wOC0yNyAxMzoyNDo1NVogbXJnbGF2YXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm07CisKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworLyoqCisgKiBBbiBpbnN0YW5jZSBvZiB0aGlzIGFic3RyYWN0IGNsYXNzIGNhbiB0cmFuc2Zvcm0gYQorICogc291cmNlIHRyZWUgaW50byBhIHJlc3VsdCB0cmVlLgorICoKKyAqIDxwPkFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgY2FuIGJlIG9idGFpbmVkIHdpdGggdGhlCisgKiB7QGxpbmsgVHJhbnNmb3JtZXJGYWN0b3J5I25ld1RyYW5zZm9ybWVyIFRyYW5zZm9ybWVyRmFjdG9yeS5uZXdUcmFuc2Zvcm1lcn0KKyAqIG1ldGhvZC4gVGhpcyBpbnN0YW5jZSBtYXkgdGhlbiBiZSB1c2VkIHRvIHByb2Nlc3MgWE1MIGZyb20gYQorICogdmFyaWV0eSBvZiBzb3VyY2VzIGFuZCB3cml0ZSB0aGUgdHJhbnNmb3JtYXRpb24gb3V0cHV0IHRvIGEKKyAqIHZhcmlldHkgb2Ygc2lua3MuPC9wPgorICoKKyAqIDxwPkFuIG9iamVjdCBvZiB0aGlzIGNsYXNzIG1heSBub3QgYmUgdXNlZCBpbiBtdWx0aXBsZSB0aHJlYWRzCisgKiBydW5uaW5nIGNvbmN1cnJlbnRseS4gIERpZmZlcmVudCBUcmFuc2Zvcm1lcnMgbWF5IGJlIHVzZWQKKyAqIGNvbmN1cnJlbnRseSBieSBkaWZmZXJlbnQgdGhyZWFkcy48L3A+CisgKgorICogPHA+QSA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gbWF5IGJlIHVzZWQgbXVsdGlwbGUgdGltZXMuICBQYXJhbWV0ZXJzIGFuZAorICogb3V0cHV0IHByb3BlcnRpZXMgYXJlIHByZXNlcnZlZCBhY3Jvc3MgdHJhbnNmb3JtYXRpb25zLjwvcD4KKyAqCisgKiBAYXV0aG9yIDxhIGhyZWY9IkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgorICogQHZlcnNpb24gJFJldmlzaW9uOiA1NzAxMDMgJCwgJERhdGU6IDIwMDctMDgtMjcgMDY6MjQ6NTUgLTA3MDAgKE1vbiwgMjcgQXVnIDIwMDcpICQKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFRyYW5zZm9ybWVyIHsKKworICAgIC8qKgorICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IgaXMgcHJvdGVjdGVkIG9uIHB1cnBvc2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIFRyYW5zZm9ybWVyKCkgeyB9CisKKyAgICAvKioKKyAgICAgKiA8cD5SZXNldCB0aGlzIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPiB0byBpdHMgb3JpZ2luYWwgY29uZmlndXJhdGlvbi48L3A+CisgICAgICoKKyAgICAgKiA8cD48Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gaXMgcmVzZXQgdG8gdGhlIHNhbWUgc3RhdGUgYXMgd2hlbiBpdCB3YXMgY3JlYXRlZCB3aXRoCisgICAgICoge0BsaW5rIFRyYW5zZm9ybWVyRmFjdG9yeSNuZXdUcmFuc2Zvcm1lcigpfSwKKyAgICAgKiB7QGxpbmsgVHJhbnNmb3JtZXJGYWN0b3J5I25ld1RyYW5zZm9ybWVyKFNvdXJjZSBzb3VyY2UpfSBvcgorICAgICAqIHtAbGluayBUZW1wbGF0ZXMjbmV3VHJhbnNmb3JtZXIoKX0uCisgICAgICogPGNvZGU+cmVzZXQoKTwvY29kZT4gaXMgZGVzaWduZWQgdG8gYWxsb3cgdGhlIHJldXNlIG9mIGV4aXN0aW5nIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPnMKKyAgICAgKiB0aHVzIHNhdmluZyByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBjcmVhdGlvbiBvZiBuZXcgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+cy48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgcmVzZXQgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+IGlzIG5vdCBndWFyYW50ZWVkIHRvIGhhdmUgdGhlIHNhbWUge0BsaW5rIFVSSVJlc29sdmVyfQorICAgICAqIG9yIHtAbGluayBFcnJvckxpc3RlbmVyfSA8Y29kZT5PYmplY3Q8L2NvZGU+cywgZS5nLiB7QGxpbmsgT2JqZWN0I2VxdWFscyhPYmplY3Qgb2JqKX0uCisgICAgICogSXQgaXMgZ3VhcmFudGVlZCB0byBoYXZlIGEgZnVuY3Rpb25hbGx5IGVxdWFsIDxjb2RlPlVSSVJlc29sdmVyPC9jb2RlPgorICAgICAqIGFuZCA8Y29kZT5FcnJvckxpc3RlbmVyPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB7CisKKyAgICAgICAgLy8gaW1wbGVtZW50b3JzIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZAorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgICAiVGhpcyBUcmFuc2Zvcm1lciwgXCIiICsgdGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSArICJcIiwgZG9lcyBub3Qgc3VwcG9ydCB0aGUgcmVzZXQgZnVuY3Rpb25hbGl0eS4iCisgICAgICAgICAgICArICIgIFNwZWNpZmljYXRpb24gXCIiICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVGl0bGUoKSArICJcIiIKKyAgICAgICAgICAgICsgIiB2ZXJzaW9uIFwiIiArIHRoaXMuZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkuZ2V0U3BlY2lmaWNhdGlvblZlcnNpb24oKSArICJcIiIKKyAgICAgICAgICAgICk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+VHJhbnNmb3JtIHRoZSBYTUwgPGNvZGU+U291cmNlPC9jb2RlPiB0byBhIDxjb2RlPlJlc3VsdDwvY29kZT4uCisgICAgICogU3BlY2lmaWMgdHJhbnNmb3JtYXRpb24gYmVoYXZpb3IgaXMgZGV0ZXJtaW5lZCBieSB0aGUgc2V0dGluZ3Mgb2YgdGhlCisgICAgICogPGNvZGU+VHJhbnNmb3JtZXJGYWN0b3J5PC9jb2RlPiBpbiBlZmZlY3Qgd2hlbiB0aGUKKyAgICAgKiA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gd2FzIGluc3RhbnRpYXRlZCBhbmQgYW55IG1vZGlmaWNhdGlvbnMgbWFkZSB0bworICAgICAqIHRoZSA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gaW5zdGFuY2UuPC9wPgorICAgICAqCisgICAgICogPHA+QW4gZW1wdHkgPGNvZGU+U291cmNlPC9jb2RlPiBpcyByZXByZXNlbnRlZCBhcyBhbiBlbXB0eSBkb2N1bWVudAorICAgICAqIGFzIGNvbnN0cnVjdGVkIGJ5IHtAbGluayBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXIjbmV3RG9jdW1lbnQoKX0uCisgICAgICogVGhlIHJlc3VsdCBvZiB0cmFuc2Zvcm1pbmcgYW4gZW1wdHkgPGNvZGU+U291cmNlPC9jb2RlPiBkZXBlbmRzIG9uCisgICAgICogdGhlIHRyYW5zZm9ybWF0aW9uIGJlaGF2aW9yOyBpdCBpcyBub3QgYWx3YXlzIGFuIGVtcHR5CisgICAgICogPGNvZGU+UmVzdWx0PC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0geG1sU291cmNlIFRoZSBYTUwgaW5wdXQgdG8gdHJhbnNmb3JtLgorICAgICAqIEBwYXJhbSBvdXRwdXRUYXJnZXQgVGhlIDxjb2RlPlJlc3VsdDwvY29kZT4gb2YgdHJhbnNmb3JtaW5nIHRoZQorICAgICAqICAgPGNvZGU+eG1sU291cmNlPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gSWYgYW4gdW5yZWNvdmVyYWJsZSBlcnJvciBvY2N1cnMKKyAgICAgKiAgIGR1cmluZyB0aGUgY291cnNlIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB0cmFuc2Zvcm0oU291cmNlIHhtbFNvdXJjZSwgUmVzdWx0IG91dHB1dFRhcmdldCkKKyAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQWRkIGEgcGFyYW1ldGVyIGZvciB0aGUgdHJhbnNmb3JtYXRpb24uCisgICAgICoKKyAgICAgKiA8cD5QYXNzIGEgcXVhbGlmaWVkIG5hbWUgYXMgYSB0d28tcGFydCBzdHJpbmcsIHRoZSBuYW1lc3BhY2UgVVJJCisgICAgICogZW5jbG9zZWQgaW4gY3VybHkgYnJhY2VzICh7fSksIGZvbGxvd2VkIGJ5IHRoZSBsb2NhbCBuYW1lLiBJZiB0aGUKKyAgICAgKiBuYW1lIGhhcyBhIG51bGwgVVJMLCB0aGUgU3RyaW5nIG9ubHkgY29udGFpbiB0aGUgbG9jYWwgbmFtZS4gQW4KKyAgICAgKiBhcHBsaWNhdGlvbiBjYW4gc2FmZWx5IGNoZWNrIGZvciBhIG5vbi1udWxsIFVSSSBieSB0ZXN0aW5nIHRvIHNlZSBpZiB0aGUKKyAgICAgKiBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIG5hbWUgaXMgYSAneycgY2hhcmFjdGVyLjwvcD4KKyAgICAgKiA8cD5Gb3IgZXhhbXBsZSwgaWYgYSBVUkkgYW5kIGxvY2FsIG5hbWUgd2VyZSBvYnRhaW5lZCBmcm9tIGFuIGVsZW1lbnQKKyAgICAgKiBkZWZpbmVkIHdpdGggJmx0O3h5ejpmb28KKyAgICAgKiB4bWxuczp4eXo9Imh0dHA6Ly94eXouZm9vLmNvbS95YWRhL2Jhei5odG1sIi8mZ3Q7LAorICAgICAqIHRoZW4gdGhlIHF1YWxpZmllZCBuYW1lIHdvdWxkIGJlICJ7aHR0cDovL3h5ei5mb28uY29tL3lhZGEvYmF6Lmh0bWx9Zm9vIi4KKyAgICAgKiBOb3RlIHRoYXQgbm8gcHJlZml4IGlzIHVzZWQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlciwgd2hpY2ggbWF5IGJlZ2luIHdpdGggYQorICAgICAqIG5hbWVzcGFjZSBVUkkgaW4gY3VybHkgYnJhY2VzICh7fSkuCisgICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSBvYmplY3QuICBUaGlzIGNhbiBiZSBhbnkgdmFsaWQgSmF2YSBvYmplY3QuIEl0IGlzCisgICAgICogdXAgdG8gdGhlIHByb2Nlc3NvciB0byBwcm92aWRlIHRoZSBwcm9wZXIgb2JqZWN0IGNvZXJjaW9uIG9yIHRvIHNpbXBseQorICAgICAqIHBhc3MgdGhlIG9iamVjdCBvbiBmb3IgdXNlIGluIGFuIGV4dGVuc2lvbi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgdmFsdWUgaXMgbnVsbC4KKyAgICAgKi8KKyAgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpOworCisgICAgLyoqCisgICAgICogR2V0IGEgcGFyYW1ldGVyIHRoYXQgd2FzIGV4cGxpY2l0bHkgc2V0IHdpdGggc2V0UGFyYW1ldGVyLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgZG9lcyBub3QgcmV0dXJuIGEgZGVmYXVsdCBwYXJhbWV0ZXIgdmFsdWUsIHdoaWNoCisgICAgICogY2Fubm90IGJlIGRldGVybWluZWQgdW50aWwgdGhlIG5vZGUgY29udGV4dCBpcyBldmFsdWF0ZWQgZHVyaW5nCisgICAgICogdGhlIHRyYW5zZm9ybWF0aW9uIHByb2Nlc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBvZiA8Y29kZT5PYmplY3Q8L2NvZGU+IHRvIGdldAorICAgICAqIEByZXR1cm4gQSBwYXJhbWV0ZXIgdGhhdCBoYXMgYmVlbiBzZXQgd2l0aCBzZXRQYXJhbWV0ZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IE9iamVjdCBnZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUpOworCisgICAgLyoqCisgICAgICogPHA+U2V0IGEgbGlzdCBvZiBwYXJhbWV0ZXJzLjwvcD4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB0aGUgbGlzdCBvZiBwYXJhbWV0ZXJzIGlzIHNwZWNpZmllZCBhcyBhCisgICAgICogPGNvZGU+UHJvcGVydGllczwvY29kZT4gPGNvZGU+T2JqZWN0PC9jb2RlPiB3aGljaCBsaW1pdHMgdGhlIHBhcmFtZXRlcgorICAgICAqIHZhbHVlcyB0byA8Y29kZT5TdHJpbmc8L2NvZGU+cy4gIE11bHRpcGxlIGNhbGxzIHRvCisgICAgICoge0BsaW5rICNzZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSl9IHNob3VsZCBiZSB1c2VkIHdoZW4gdGhlCisgICAgICogZGVzaXJlZCB2YWx1ZXMgYXJlIG5vbi08Y29kZT5TdHJpbmc8L2NvZGU+IDxjb2RlPk9iamVjdDwvY29kZT5zLgorICAgICAqIFRoZSBwYXJhbWV0ZXIgbmFtZXMgc2hvdWxkIGNvbmZvcm0gYXMgc3BlY2lmaWVkIGluCisgICAgICoge0BsaW5rICNzZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSl9LgorICAgICAqIEFuIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duIGlmIGFueSBuYW1lcyBkbyBub3QKKyAgICAgKiBjb25mb3JtLjwvcD4KKyAgICAgKgorICAgICAqIDxwPk5ldyBwYXJhbWV0ZXJzIGluIHRoZSBsaXN0IGFyZSBhZGRlZCB0byBhbnkgZXhpc3RpbmcgcGFyYW1ldGVycy4KKyAgICAgKiBJZiB0aGUgbmFtZSBvZiBhIG5ldyBwYXJhbWV0ZXIgaXMgZXF1YWwgdG8gdGhlIG5hbWUgb2YgYW4gZXhpc3RpbmcKKyAgICAgKiBwYXJhbWV0ZXIgYXMgZGV0ZXJtaW5lZCBieSB7QGxpbmsgamF2YS5sYW5nLk9iamVjdCNlcXVhbHMoT2JqZWN0IG9iail9LAorICAgICAqICB0aGUgZXhpc3RpbmcgcGFyYW1ldGVyIGlzIHNldCB0byB0aGUgbmV3IHZhbHVlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbXMgUGFyYW1ldGVycyB0byBzZXQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiBhbnkgcGFyYW1ldGVyIG5hbWVzIGRvIG5vdCBjb25mb3JtCisgICAgICogICB0byB0aGUgbmFtaW5nIHJ1bGVzLgorICAgICAqLworCisgICAgLyoqCisgICAgICogQ2xlYXIgYWxsIHBhcmFtZXRlcnMgc2V0IHdpdGggc2V0UGFyYW1ldGVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGNsZWFyUGFyYW1ldGVycygpOworCisgICAgLyoqCisgICAgICogU2V0IGFuIG9iamVjdCB0aGF0IHdpbGwgYmUgdXNlZCB0byByZXNvbHZlIFVSSXMgdXNlZCBpbgorICAgICAqIGRvY3VtZW50KCkuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgcmVzb2x2ZXIgYXJndW1lbnQgaXMgbnVsbCwgdGhlIFVSSVJlc29sdmVyIHZhbHVlIHdpbGwKKyAgICAgKiBiZSBjbGVhcmVkIGFuZCB0aGUgdHJhbnNmb3JtZXIgd2lsbCBubyBsb25nZXIgaGF2ZSBhIHJlc29sdmVyLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZXNvbHZlciBBbiBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoZSBVUklSZXNvbHZlciBpbnRlcmZhY2UsCisgICAgICogb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRVUklSZXNvbHZlcihVUklSZXNvbHZlciByZXNvbHZlcik7CisKKyAgICAvKioKKyAgICAgKiBHZXQgYW4gb2JqZWN0IHRoYXQgd2lsbCBiZSB1c2VkIHRvIHJlc29sdmUgVVJJcyB1c2VkIGluCisgICAgICogZG9jdW1lbnQoKS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQW4gb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGUgVVJJUmVzb2x2ZXIgaW50ZXJmYWNlLAorICAgICAqIG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFVSSVJlc29sdmVyIGdldFVSSVJlc29sdmVyKCk7CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIG91dHB1dCBwcm9wZXJ0aWVzIGZvciB0aGUgdHJhbnNmb3JtYXRpb24uICBUaGVzZQorICAgICAqIHByb3BlcnRpZXMgd2lsbCBvdmVycmlkZSBwcm9wZXJ0aWVzIHNldCBpbiB0aGUgVGVtcGxhdGVzCisgICAgICogd2l0aCB4c2w6b3V0cHV0LgorICAgICAqCisgICAgICogPHA+SWYgYXJndW1lbnQgdG8gdGhpcyBmdW5jdGlvbiBpcyBudWxsLCBhbnkgcHJvcGVydGllcworICAgICAqIHByZXZpb3VzbHkgc2V0IGFyZSByZW1vdmVkLCBhbmQgdGhlIHZhbHVlIHdpbGwgcmV2ZXJ0IHRvIHRoZSB2YWx1ZQorICAgICAqIGRlZmluZWQgaW4gdGhlIHRlbXBsYXRlcyBvYmplY3QuPC9wPgorICAgICAqCisgICAgICogPHA+UGFzcyBhIHF1YWxpZmllZCBwcm9wZXJ0eSBrZXkgbmFtZSBhcyBhIHR3by1wYXJ0IHN0cmluZywgdGhlIG5hbWVzcGFjZQorICAgICAqIFVSSSBlbmNsb3NlZCBpbiBjdXJseSBicmFjZXMgKHt9KSwgZm9sbG93ZWQgYnkgdGhlIGxvY2FsIG5hbWUuIElmIHRoZQorICAgICAqIG5hbWUgaGFzIGEgbnVsbCBVUkwsIHRoZSBTdHJpbmcgb25seSBjb250YWluIHRoZSBsb2NhbCBuYW1lLiBBbgorICAgICAqIGFwcGxpY2F0aW9uIGNhbiBzYWZlbHkgY2hlY2sgZm9yIGEgbm9uLW51bGwgVVJJIGJ5IHRlc3RpbmcgdG8gc2VlIGlmIHRoZQorICAgICAqIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgbmFtZSBpcyBhICd7JyBjaGFyYWN0ZXIuPC9wPgorICAgICAqIDxwPkZvciBleGFtcGxlLCBpZiBhIFVSSSBhbmQgbG9jYWwgbmFtZSB3ZXJlIG9idGFpbmVkIGZyb20gYW4gZWxlbWVudAorICAgICAqIGRlZmluZWQgd2l0aCAmbHQ7eHl6OmZvbworICAgICAqIHhtbG5zOnh5ej0iaHR0cDovL3h5ei5mb28uY29tL3lhZGEvYmF6Lmh0bWwiLyZndDssCisgICAgICogdGhlbiB0aGUgcXVhbGlmaWVkIG5hbWUgd291bGQgYmUgIntodHRwOi8veHl6LmZvby5jb20veWFkYS9iYXouaHRtbH1mb28iLgorICAgICAqIE5vdGUgdGhhdCBubyBwcmVmaXggaXMgdXNlZC48L3A+CisgICAgICogQW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gIGlmIGFueSBvZiB0aGUKKyAgICAgKiBhcmd1bWVudCBrZXlzIGFyZSBub3QgcmVjb2duaXplZCBhbmQgYXJlIG5vdCBuYW1lc3BhY2UgcXVhbGlmaWVkLgorICAgICAqCisgICAgICogQHBhcmFtIG9mb3JtYXQgQSBzZXQgb2Ygb3V0cHV0IHByb3BlcnRpZXMgdGhhdCB3aWxsIGJlCisgICAgICogdXNlZCB0byBvdmVycmlkZSBhbnkgb2YgdGhlIHNhbWUgcHJvcGVydGllcyBpbiBhZmZlY3QKKyAgICAgKiBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLgorICAgICAqCisgICAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXMKKyAgICAgKiBAc2VlIGphdmEudXRpbC5Qcm9wZXJ0aWVzCisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRPdXRwdXRQcm9wZXJ0aWVzKFByb3BlcnRpZXMgb2Zvcm1hdCk7CisKKyAgICAvKioKKyAgICAgKiA8cD5HZXQgYSBjb3B5IG9mIHRoZSBvdXRwdXQgcHJvcGVydGllcyBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBwcm9wZXJ0aWVzIHJldHVybmVkIHNob3VsZCBjb250YWluIHByb3BlcnRpZXMgc2V0IGJ5IHRoZSB1c2VyLAorICAgICAqIGFuZCBwcm9wZXJ0aWVzIHNldCBieSB0aGUgc3R5bGVzaGVldCwgYW5kIHRoZXNlIHByb3BlcnRpZXMKKyAgICAgKiBhcmUgImRlZmF1bHRlZCIgYnkgZGVmYXVsdCBwcm9wZXJ0aWVzIHNwZWNpZmllZCBieQorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjb3V0cHV0Ij5zZWN0aW9uIDE2IG9mIHRoZQorICAgICAqIFhTTCBUcmFuc2Zvcm1hdGlvbnMgKFhTTFQpIFczQyBSZWNvbW1lbmRhdGlvbjwvYT4uICBUaGUgcHJvcGVydGllcyB0aGF0CisgICAgICogd2VyZSBzcGVjaWZpY2FsbHkgc2V0IGJ5IHRoZSB1c2VyIG9yIHRoZSBzdHlsZXNoZWV0IHNob3VsZCBiZSBpbiB0aGUgYmFzZQorICAgICAqIFByb3BlcnRpZXMgbGlzdCwgd2hpbGUgdGhlIFhTTFQgZGVmYXVsdCBwcm9wZXJ0aWVzIHRoYXQgd2VyZSBub3QKKyAgICAgKiBzcGVjaWZpY2FsbHkgc2V0IHNob3VsZCBiZSB0aGUgZGVmYXVsdCBQcm9wZXJ0aWVzIGxpc3QuICBUaHVzLAorICAgICAqIGdldE91dHB1dFByb3BlcnRpZXMoKS5nZXRQcm9wZXJ0eShTdHJpbmcga2V5KSB3aWxsIG9idGFpbiBhbnkKKyAgICAgKiBwcm9wZXJ0eSBpbiB0aGF0IHdhcyBzZXQgYnkge0BsaW5rICNzZXRPdXRwdXRQcm9wZXJ0eX0sCisgICAgICoge0BsaW5rICNzZXRPdXRwdXRQcm9wZXJ0aWVzfSwgaW4gdGhlIHN0eWxlc2hlZXQsIDxlbT5vcjwvZW0+IHRoZSBkZWZhdWx0CisgICAgICogcHJvcGVydGllcywgd2hpbGUKKyAgICAgKiBnZXRPdXRwdXRQcm9wZXJ0aWVzKCkuZ2V0KFN0cmluZyBrZXkpIHdpbGwgb25seSByZXRyaWV2ZSBwcm9wZXJ0aWVzCisgICAgICogdGhhdCB3ZXJlIGV4cGxpY2l0bHkgc2V0IGJ5IHtAbGluayAjc2V0T3V0cHV0UHJvcGVydHl9LAorICAgICAqIHtAbGluayAjc2V0T3V0cHV0UHJvcGVydGllc30sIG9yIGluIHRoZSBzdHlsZXNoZWV0LjwvcD4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCBtdXRhdGlvbiBvZiB0aGUgUHJvcGVydGllcyBvYmplY3QgcmV0dXJuZWQgd2lsbCBub3QKKyAgICAgKiBlZmZlY3QgdGhlIHByb3BlcnRpZXMgdGhhdCB0aGUgdHJhbnNmb3JtZXIgY29udGFpbnMuPC9wPgorICAgICAqCisgICAgICogPHA+SWYgYW55IG9mIHRoZSBhcmd1bWVudCBrZXlzIGFyZSBub3QgcmVjb2duaXplZCBhbmQgYXJlIG5vdAorICAgICAqIG5hbWVzcGFjZSBxdWFsaWZpZWQsIHRoZSBwcm9wZXJ0eSB3aWxsIGJlIGlnbm9yZWQgYW5kIG5vdCByZXR1cm5lZC4KKyAgICAgKiBJbiBvdGhlciB3b3JkcyB0aGUgYmVoYXZpb3IgaXMgbm90IG9ydGhvZ29uYWwgd2l0aAorICAgICAqIHtAbGluayAjc2V0T3V0cHV0UHJvcGVydGllcyBzZXRPdXRwdXRQcm9wZXJ0aWVzfS48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEgY29weSBvZiB0aGUgc2V0IG9mIG91dHB1dCBwcm9wZXJ0aWVzIGluIGVmZmVjdCBmb3IKKyAgICAgKiAgIHRoZSBuZXh0IHRyYW5zZm9ybWF0aW9uLgorICAgICAqCisgICAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXMKKyAgICAgKiBAc2VlIGphdmEudXRpbC5Qcm9wZXJ0aWVzCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I291dHB1dCI+CisgICAgICogICBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBWZXJzaW9uIDEuMDwvYT4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgUHJvcGVydGllcyBnZXRPdXRwdXRQcm9wZXJ0aWVzKCk7CisKKyAgICAvKioKKyAgICAgKiBTZXQgYW4gb3V0cHV0IHByb3BlcnR5IHRoYXQgd2lsbCBiZSBpbiBlZmZlY3QgZm9yIHRoZQorICAgICAqIHRyYW5zZm9ybWF0aW9uLgorICAgICAqCisgICAgICogPHA+UGFzcyBhIHF1YWxpZmllZCBwcm9wZXJ0eSBuYW1lIGFzIGEgdHdvLXBhcnQgc3RyaW5nLCB0aGUgbmFtZXNwYWNlIFVSSQorICAgICAqIGVuY2xvc2VkIGluIGN1cmx5IGJyYWNlcyAoe30pLCBmb2xsb3dlZCBieSB0aGUgbG9jYWwgbmFtZS4gSWYgdGhlCisgICAgICogbmFtZSBoYXMgYSBudWxsIFVSTCwgdGhlIFN0cmluZyBvbmx5IGNvbnRhaW4gdGhlIGxvY2FsIG5hbWUuIEFuCisgICAgICogYXBwbGljYXRpb24gY2FuIHNhZmVseSBjaGVjayBmb3IgYSBub24tbnVsbCBVUkkgYnkgdGVzdGluZyB0byBzZWUgaWYgdGhlCisgICAgICogZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBuYW1lIGlzIGEgJ3snIGNoYXJhY3Rlci48L3A+CisgICAgICogPHA+Rm9yIGV4YW1wbGUsIGlmIGEgVVJJIGFuZCBsb2NhbCBuYW1lIHdlcmUgb2J0YWluZWQgZnJvbSBhbiBlbGVtZW50CisgICAgICogZGVmaW5lZCB3aXRoICZsdDt4eXo6Zm9vCisgICAgICogeG1sbnM6eHl6PSJodHRwOi8veHl6LmZvby5jb20veWFkYS9iYXouaHRtbCIvJmd0OywKKyAgICAgKiB0aGVuIHRoZSBxdWFsaWZpZWQgbmFtZSB3b3VsZCBiZSAie2h0dHA6Ly94eXouZm9vLmNvbS95YWRhL2Jhei5odG1sfWZvbyIuCisgICAgICogTm90ZSB0aGF0IG5vIHByZWZpeCBpcyB1c2VkLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBQcm9wZXJ0aWVzIG9iamVjdCB0aGF0IHdhcyBwYXNzZWQgdG8ge0BsaW5rICNzZXRPdXRwdXRQcm9wZXJ0aWVzfQorICAgICAqIHdvbid0IGJlIGVmZmVjdGVkIGJ5IGNhbGxpbmcgdGhpcyBtZXRob2QuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgQSBub24tbnVsbCBTdHJpbmcgdGhhdCBzcGVjaWZpZXMgYW4gb3V0cHV0CisgICAgICogcHJvcGVydHkgbmFtZSwgd2hpY2ggbWF5IGJlIG5hbWVzcGFjZSBxdWFsaWZpZWQuCisgICAgICogQHBhcmFtIHZhbHVlIFRoZSBub24tbnVsbCBzdHJpbmcgdmFsdWUgb2YgdGhlIG91dHB1dCBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eSBpcyBub3Qgc3VwcG9ydGVkLCBhbmQgaXMKKyAgICAgKiBub3QgcXVhbGlmaWVkIHdpdGggYSBuYW1lc3BhY2UuCisgICAgICoKKyAgICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5cworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldE91dHB1dFByb3BlcnR5KFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCisgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgYW4gb3V0cHV0IHByb3BlcnR5IHRoYXQgaXMgaW4gZWZmZWN0IGZvciB0aGUKKyAgICAgKiB0cmFuc2Zvcm1lci4gIFRoZSBwcm9wZXJ0eSBzcGVjaWZpZWQgbWF5IGJlIGEgcHJvcGVydHkKKyAgICAgKiB0aGF0IHdhcyBzZXQgd2l0aCBzZXRPdXRwdXRQcm9wZXJ0eSwgb3IgaXQgbWF5IGJlIGEKKyAgICAgKiBwcm9wZXJ0eSBzcGVjaWZpZWQgaW4gdGhlIHN0eWxlc2hlZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBBIG5vbi1udWxsIFN0cmluZyB0aGF0IHNwZWNpZmllcyBhbiBvdXRwdXQKKyAgICAgKiBwcm9wZXJ0eSBuYW1lLCB3aGljaCBtYXkgYmUgbmFtZXNwYWNlIHF1YWxpZmllZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIHN0cmluZyB2YWx1ZSBvZiB0aGUgb3V0cHV0IHByb3BlcnR5LCBvciBudWxsCisgICAgICogaWYgbm8gcHJvcGVydHkgd2FzIGZvdW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIHByb3BlcnR5IGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICoKKyAgICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5cworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0T3V0cHV0UHJvcGVydHkoU3RyaW5nIG5hbWUpCisgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGVycm9yIGV2ZW50IGxpc3RlbmVyIGluIGVmZmVjdCBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGxpc3RlbmVyIFRoZSBuZXcgZXJyb3IgbGlzdGVuZXIuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgbGlzdGVuZXIgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRFcnJvckxpc3RlbmVyKEVycm9yTGlzdGVuZXIgbGlzdGVuZXIpCisgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGVycm9yIGV2ZW50IGhhbmRsZXIgaW4gZWZmZWN0IGZvciB0aGUgdHJhbnNmb3JtYXRpb24uCisgICAgICogSW1wbGVtZW50YXRpb25zIG11c3QgcHJvdmlkZSBhIGRlZmF1bHQgZXJyb3IgbGlzdGVuZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGVycm9yIGhhbmRsZXIsIHdoaWNoIHNob3VsZCBuZXZlciBiZSBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBFcnJvckxpc3RlbmVyIGdldEVycm9yTGlzdGVuZXIoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL1RyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTBmZTUwZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL1RyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLyAkSWQ6IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbi5qYXZhIDU2OTk5NCAyMDA3LTA4LTI3IDA0OjI4OjU3WiBtcmdsYXZhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybTsKKworLyoqCisgKiBJbmRpY2F0ZXMgYSBzZXJpb3VzIGNvbmZpZ3VyYXRpb24gZXJyb3IuCisgKi8KK3B1YmxpYyBjbGFzcyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZXh0ZW5kcyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+VHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uPC9jb2RlPiB3aXRoIG5vCisgICAgICogZGV0YWlsIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbigpIHsKKyAgICAgICAgc3VwZXIoIkNvbmZpZ3VyYXRpb24gRXJyb3IiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+VHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uPC9jb2RlPiB3aXRoCisgICAgICogdGhlIDxjb2RlPlN0cmluZyA8L2NvZGU+IHNwZWNpZmllZCBhcyBhbiBlcnJvciBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZyBUaGUgZXJyb3IgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKKyAgICAgICAgc3VwZXIobXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+VHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uPC9jb2RlPiB3aXRoIGEKKyAgICAgKiBnaXZlbiA8Y29kZT5FeGNlcHRpb248L2NvZGU+IGJhc2UgY2F1c2Ugb2YgdGhlIGVycm9yLgorICAgICAqCisgICAgICogQHBhcmFtIGUgVGhlIGV4Y2VwdGlvbiB0byBiZSBlbmNhcHN1bGF0ZWQgaW4gYQorICAgICAqIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKFRocm93YWJsZSBlKSB7CisgICAgICAgIHN1cGVyKGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb248L2NvZGU+IHdpdGggdGhlCisgICAgICogZ2l2ZW4gPGNvZGU+RXhjZXB0aW9uPC9jb2RlPiBiYXNlIGNhdXNlIGFuZCBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIFRoZSBleGNlcHRpb24gdG8gYmUgZW5jYXBzdWxhdGVkIGluIGEKKyAgICAgKiAgICAgIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgorICAgICAqIEBwYXJhbSBtc2cgVGhlIGRldGFpbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oU3RyaW5nIG1zZywgVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgc3VwZXIobXNnLCBlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGZyb20gYSBtZXNzYWdlIGFuZCBhIExvY2F0b3IuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGNvbnN0cnVjdG9yIGlzIGVzcGVjaWFsbHkgdXNlZnVsIHdoZW4gYW4gYXBwbGljYXRpb24gaXMKKyAgICAgKiBjcmVhdGluZyBpdHMgb3duIGV4Y2VwdGlvbiBmcm9tIHdpdGhpbiBhIERvY3VtZW50SGFuZGxlcgorICAgICAqIGNhbGxiYWNrLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBvciB3YXJuaW5nIG1lc3NhZ2UuCisgICAgICogQHBhcmFtIGxvY2F0b3IgVGhlIGxvY2F0b3Igb2JqZWN0IGZvciB0aGUgZXJyb3Igb3Igd2FybmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU291cmNlTG9jYXRvciBsb2NhdG9yKSB7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UsIGxvY2F0b3IpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyYXAgYW4gZXhpc3RpbmcgZXhjZXB0aW9uIGluIGEgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG9yIHdhcm5pbmcgbWVzc2FnZSwgb3IgbnVsbCB0bworICAgICAqICAgICAgICAgICAgICAgIHVzZSB0aGUgbWVzc2FnZSBmcm9tIHRoZSBlbWJlZGRlZCBleGNlcHRpb24uCisgICAgICogQHBhcmFtIGxvY2F0b3IgVGhlIGxvY2F0b3Igb2JqZWN0IGZvciB0aGUgZXJyb3Igb3Igd2FybmluZy4KKyAgICAgKiBAcGFyYW0gZSBBbnkgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb3VyY2VMb2NhdG9yIGxvY2F0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaHJvd2FibGUgZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlLCBsb2NhdG9yLCBlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vVHJhbnNmb3JtZXJFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NDMxMmI4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vVHJhbnNmb3JtZXJFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDMxNiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vICRJZDogVHJhbnNmb3JtZXJFeGNlcHRpb24uamF2YSA1Njk5OTQgMjAwNy0wOC0yNyAwNDoyODo1N1ogbXJnbGF2YXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm07CisKKy8qKgorICogVGhpcyBjbGFzcyBzcGVjaWZpZXMgYW4gZXhjZXB0aW9uYWwgY29uZGl0aW9uIHRoYXQgb2NjdXJyZWQKKyAqIGR1cmluZyB0aGUgdHJhbnNmb3JtYXRpb24gcHJvY2Vzcy4KKyAqLworcHVibGljIGNsYXNzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKworICAgIC8vIEFkZGVkIHNlcmlhbFZlcnNpb25VSUQgdG8gcHJlc2VydmUgYmluYXJ5IGNvbXBhdGliaWxpdHkKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA5NzU3OTg3NzM3NzI5NTY0MjhMOworCisgICAgLyoqIEZpZWxkIGxvY2F0b3Igc3BlY2lmaWVzIHdoZXJlIHRoZSBlcnJvciBvY2N1cnJlZCAqLworICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvcjsKKworICAgIC8qKgorICAgICAqIE1ldGhvZCBnZXRMb2NhdG9yIHJldHJpZXZlcyBhbiBpbnN0YW5jZSBvZiBhIFNvdXJjZUxvY2F0b3IKKyAgICAgKiBvYmplY3QgdGhhdCBzcGVjaWZpZXMgd2hlcmUgYW4gZXJyb3Igb2NjdXJyZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEgU291cmNlTG9jYXRvciBvYmplY3QsIG9yIG51bGwgaWYgbm9uZSB3YXMgc3BlY2lmaWVkLgorICAgICAqLworICAgIHB1YmxpYyBTb3VyY2VMb2NhdG9yIGdldExvY2F0b3IoKSB7CisgICAgICAgIHJldHVybiBsb2NhdG9yOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1ldGhvZCBzZXRMb2NhdG9yIHNldHMgYW4gaW5zdGFuY2Ugb2YgYSBTb3VyY2VMb2NhdG9yCisgICAgICogb2JqZWN0IHRoYXQgc3BlY2lmaWVzIHdoZXJlIGFuIGVycm9yIG9jY3VycmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2F0aW9uIEEgU291cmNlTG9jYXRvciBvYmplY3QsIG9yIG51bGwgdG8gY2xlYXIgdGhlIGxvY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldExvY2F0b3IoU291cmNlTG9jYXRvciBsb2NhdGlvbikgeworICAgICAgICBsb2NhdG9yID0gbG9jYXRpb247CisgICAgfQorCisgICAgLyoqIEZpZWxkIGNvbnRhaW5lZEV4Y2VwdGlvbiBzcGVjaWZpZXMgYSB3cmFwcGVkIGV4Y2VwdGlvbi4gIE1heSBiZSBudWxsLiAqLworICAgIFRocm93YWJsZSBjb250YWluZWRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCByZXRyaWV2ZXMgYW4gZXhjZXB0aW9uIHRoYXQgdGhpcyBleGNlcHRpb24gd3JhcHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFuIFRocm93YWJsZSBvYmplY3QsIG9yIG51bGwuCisgICAgICogQHNlZSAjZ2V0Q2F1c2UKKyAgICAgKi8KKyAgICBwdWJsaWMgVGhyb3dhYmxlIGdldEV4Y2VwdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIGNvbnRhaW5lZEV4Y2VwdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjYXVzZSBvZiB0aGlzIHRocm93YWJsZSBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUKKyAgICAgKiBjYXVzZSBpcyBub25leGlzdGVudCBvciB1bmtub3duLiAgKFRoZSBjYXVzZSBpcyB0aGUgdGhyb3dhYmxlIHRoYXQKKyAgICAgKiBjYXVzZWQgdGhpcyB0aHJvd2FibGUgdG8gZ2V0IHRocm93bi4pCisgICAgICovCisgICAgcHVibGljIFRocm93YWJsZSBnZXRDYXVzZSgpIHsKKworICAgICAgICByZXR1cm4gKChjb250YWluZWRFeGNlcHRpb24gPT0gdGhpcykKKyAgICAgICAgICAgICAgICA/IG51bGwKKyAgICAgICAgICAgICAgICA6IGNvbnRhaW5lZEV4Y2VwdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhlIDxpPmNhdXNlPC9pPiBvZiB0aGlzIHRocm93YWJsZSB0byB0aGUgc3BlY2lmaWVkIHZhbHVlLgorICAgICAqIChUaGUgY2F1c2UgaXMgdGhlIHRocm93YWJsZSB0aGF0IGNhdXNlZCB0aGlzIHRocm93YWJsZSB0byBnZXQgdGhyb3duLikKKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGNhbiBiZSBjYWxsZWQgYXQgbW9zdCBvbmNlLiAgSXQgaXMgZ2VuZXJhbGx5IGNhbGxlZCBmcm9tCisgICAgICogd2l0aGluIHRoZSBjb25zdHJ1Y3Rvciwgb3IgaW1tZWRpYXRlbHkgYWZ0ZXIgY3JlYXRpbmcgdGhlCisgICAgICogdGhyb3dhYmxlLiAgSWYgdGhpcyB0aHJvd2FibGUgd2FzIGNyZWF0ZWQKKyAgICAgKiB3aXRoIHtAbGluayAjVHJhbnNmb3JtZXJFeGNlcHRpb24oVGhyb3dhYmxlKX0gb3IKKyAgICAgKiB7QGxpbmsgI1RyYW5zZm9ybWVyRXhjZXB0aW9uKFN0cmluZyxUaHJvd2FibGUpfSwgdGhpcyBtZXRob2QgY2Fubm90IGJlIGNhbGxlZAorICAgICAqIGV2ZW4gb25jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgY2F1c2UgdGhlIGNhdXNlICh3aGljaCBpcyBzYXZlZCBmb3IgbGF0ZXIgcmV0cmlldmFsIGJ5IHRoZQorICAgICAqICAgICAgICAge0BsaW5rICNnZXRDYXVzZSgpfSBtZXRob2QpLiAgKEEgPHR0Pm51bGw8L3R0PiB2YWx1ZSBpcworICAgICAqICAgICAgICAgcGVybWl0dGVkLCBhbmQgaW5kaWNhdGVzIHRoYXQgdGhlIGNhdXNlIGlzIG5vbmV4aXN0ZW50IG9yCisgICAgICogICAgICAgICB1bmtub3duLikKKyAgICAgKiBAcmV0dXJuICBhIHJlZmVyZW5jZSB0byB0aGlzIDxjb2RlPlRocm93YWJsZTwvY29kZT4gaW5zdGFuY2UuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIHRoaXMKKyAgICAgKiAgICAgICAgIHRocm93YWJsZS4gIChBIHRocm93YWJsZSBjYW5ub3QKKyAgICAgKiAgICAgICAgIGJlIGl0cyBvd24gY2F1c2UuKQorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgdGhyb3dhYmxlIHdhcworICAgICAqICAgICAgICAgY3JlYXRlZCB3aXRoIHtAbGluayAjVHJhbnNmb3JtZXJFeGNlcHRpb24oVGhyb3dhYmxlKX0gb3IKKyAgICAgKiAgICAgICAgIHtAbGluayAjVHJhbnNmb3JtZXJFeGNlcHRpb24oU3RyaW5nLFRocm93YWJsZSl9LCBvciB0aGlzIG1ldGhvZCBoYXMgYWxyZWFkeQorICAgICAqICAgICAgICAgYmVlbiBjYWxsZWQgb24gdGhpcyB0aHJvd2FibGUuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBUaHJvd2FibGUgaW5pdENhdXNlKFRocm93YWJsZSBjYXVzZSkgeworCisgICAgICAgIGlmICh0aGlzLmNvbnRhaW5lZEV4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDYW4ndCBvdmVyd3JpdGUgY2F1c2UiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjYXVzZSA9PSB0aGlzKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJTZWxmLWNhdXNhdGlvbiBub3QgcGVybWl0dGVkIik7CisgICAgICAgIH0KKworICAgICAgICB0aGlzLmNvbnRhaW5lZEV4Y2VwdGlvbiA9IGNhdXNlOworCisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBvciB3YXJuaW5nIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIFRyYW5zZm9ybWVyRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7CisKKyAgICAgICAgc3VwZXIobWVzc2FnZSk7CisKKyAgICAgICAgdGhpcy5jb250YWluZWRFeGNlcHRpb24gPSBudWxsOworICAgICAgICB0aGlzLmxvY2F0b3IgICAgICAgICAgICA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uIHdyYXBwaW5nIGFuIGV4aXN0aW5nIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIFRoZSBleGNlcHRpb24gdG8gYmUgd3JhcHBlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVHJhbnNmb3JtZXJFeGNlcHRpb24oVGhyb3dhYmxlIGUpIHsKKworICAgICAgICBzdXBlcihlLnRvU3RyaW5nKCkpOworCisgICAgICAgIHRoaXMuY29udGFpbmVkRXhjZXB0aW9uID0gZTsKKyAgICAgICAgdGhpcy5sb2NhdG9yICAgICAgICAgICAgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyYXAgYW4gZXhpc3RpbmcgZXhjZXB0aW9uIGluIGEgVHJhbnNmb3JtZXJFeGNlcHRpb24uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGlzIHVzZWQgZm9yIHRocm93aW5nIHByb2Nlc3NvciBleGNlcHRpb25zIGJlZm9yZQorICAgICAqIHRoZSBwcm9jZXNzaW5nIGhhcyBzdGFydGVkLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBvciB3YXJuaW5nIG1lc3NhZ2UsIG9yIG51bGwgdG8KKyAgICAgKiAgICAgICAgICAgICAgICB1c2UgdGhlIG1lc3NhZ2UgZnJvbSB0aGUgZW1iZWRkZWQgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBlIEFueSBleGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgVHJhbnNmb3JtZXJFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBlKSB7CisKKyAgICAgICAgc3VwZXIoKChtZXNzYWdlID09IG51bGwpIHx8IChtZXNzYWdlLmxlbmd0aCgpID09IDApKQorICAgICAgICAgICAgICA/IGUudG9TdHJpbmcoKQorICAgICAgICAgICAgICA6IG1lc3NhZ2UpOworCisgICAgICAgIHRoaXMuY29udGFpbmVkRXhjZXB0aW9uID0gZTsKKyAgICAgICAgdGhpcy5sb2NhdG9yICAgICAgICAgICAgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBmcm9tIGEgbWVzc2FnZSBhbmQgYSBMb2NhdG9yLgorICAgICAqCisgICAgICogPHA+VGhpcyBjb25zdHJ1Y3RvciBpcyBlc3BlY2lhbGx5IHVzZWZ1bCB3aGVuIGFuIGFwcGxpY2F0aW9uIGlzCisgICAgICogY3JlYXRpbmcgaXRzIG93biBleGNlcHRpb24gZnJvbSB3aXRoaW4gYSBEb2N1bWVudEhhbmRsZXIKKyAgICAgKiBjYWxsYmFjay48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3Igb3Igd2FybmluZyBtZXNzYWdlLgorICAgICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBsb2NhdG9yIG9iamVjdCBmb3IgdGhlIGVycm9yIG9yIHdhcm5pbmcuCisgICAgICovCisgICAgcHVibGljIFRyYW5zZm9ybWVyRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBTb3VyY2VMb2NhdG9yIGxvY2F0b3IpIHsKKworICAgICAgICBzdXBlcihtZXNzYWdlKTsKKworICAgICAgICB0aGlzLmNvbnRhaW5lZEV4Y2VwdGlvbiA9IG51bGw7CisgICAgICAgIHRoaXMubG9jYXRvciAgICAgICAgICAgID0gbG9jYXRvcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcmFwIGFuIGV4aXN0aW5nIGV4Y2VwdGlvbiBpbiBhIFRyYW5zZm9ybWVyRXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG9yIHdhcm5pbmcgbWVzc2FnZSwgb3IgbnVsbCB0bworICAgICAqICAgICAgICAgICAgICAgIHVzZSB0aGUgbWVzc2FnZSBmcm9tIHRoZSBlbWJlZGRlZCBleGNlcHRpb24uCisgICAgICogQHBhcmFtIGxvY2F0b3IgVGhlIGxvY2F0b3Igb2JqZWN0IGZvciB0aGUgZXJyb3Igb3Igd2FybmluZy4KKyAgICAgKiBAcGFyYW0gZSBBbnkgZXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFRyYW5zZm9ybWVyRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBTb3VyY2VMb2NhdG9yIGxvY2F0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRocm93YWJsZSBlKSB7CisKKyAgICAgICAgc3VwZXIobWVzc2FnZSk7CisKKyAgICAgICAgdGhpcy5jb250YWluZWRFeGNlcHRpb24gPSBlOworICAgICAgICB0aGlzLmxvY2F0b3IgICAgICAgICAgICA9IGxvY2F0b3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBlcnJvciBtZXNzYWdlIHdpdGggbG9jYXRpb24gaW5mb3JtYXRpb24KKyAgICAgKiBhcHBlbmRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQSA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGluZyB0aGUgZXJyb3IgbWVzc2FnZSB3aXRoCisgICAgICogICAgICAgICBsb2NhdGlvbiBpbmZvcm1hdGlvbiBhcHBlbmRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2VBbmRMb2NhdGlvbigpIHsKKworICAgICAgICBTdHJpbmdCdWlsZGVyIHNidWZmZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBTdHJpbmcgICAgICAgbWVzc2FnZSA9IHN1cGVyLmdldE1lc3NhZ2UoKTsKKworICAgICAgICBpZiAobnVsbCAhPSBtZXNzYWdlKSB7CisgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZChtZXNzYWdlKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChudWxsICE9IGxvY2F0b3IpIHsKKyAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JRCA9IGxvY2F0b3IuZ2V0U3lzdGVtSWQoKTsKKyAgICAgICAgICAgIGludCAgICBsaW5lICAgICA9IGxvY2F0b3IuZ2V0TGluZU51bWJlcigpOworICAgICAgICAgICAgaW50ICAgIGNvbHVtbiAgID0gbG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKTsKKworICAgICAgICAgICAgaWYgKG51bGwgIT0gc3lzdGVtSUQpIHsKKyAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZCgiOyBTeXN0ZW1JRDogIik7CisgICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoc3lzdGVtSUQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoMCAhPSBsaW5lKSB7CisgICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoIjsgTGluZSM6ICIpOworICAgICAgICAgICAgICAgIHNidWZmZXIuYXBwZW5kKGxpbmUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoMCAhPSBjb2x1bW4pIHsKKyAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZCgiOyBDb2x1bW4jOiAiKTsKKyAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZChjb2x1bW4pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHNidWZmZXIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGxvY2F0aW9uIGluZm9ybWF0aW9uIGFzIGEgc3RyaW5nLgorICAgICAqCisgICAgICogQHJldHVybiBBIHN0cmluZyB3aXRoIGxvY2F0aW9uIGluZm8sIG9yIG51bGwKKyAgICAgKiBpZiB0aGVyZSBpcyBubyBsb2NhdGlvbiBpbmZvcm1hdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldExvY2F0aW9uQXNTdHJpbmcoKSB7CisKKyAgICAgICAgaWYgKG51bGwgIT0gbG9jYXRvcikgeworICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYnVmZmVyICA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgICAgICBTdHJpbmcgICAgICAgc3lzdGVtSUQgPSBsb2NhdG9yLmdldFN5c3RlbUlkKCk7CisgICAgICAgICAgICBpbnQgICAgICAgICAgbGluZSAgICAgPSBsb2NhdG9yLmdldExpbmVOdW1iZXIoKTsKKyAgICAgICAgICAgIGludCAgICAgICAgICBjb2x1bW4gICA9IGxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCk7CisKKyAgICAgICAgICAgIGlmIChudWxsICE9IHN5c3RlbUlEKSB7CisgICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoIjsgU3lzdGVtSUQ6ICIpOworICAgICAgICAgICAgICAgIHNidWZmZXIuYXBwZW5kKHN5c3RlbUlEKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKDAgIT0gbGluZSkgeworICAgICAgICAgICAgICAgIHNidWZmZXIuYXBwZW5kKCI7IExpbmUjOiAiKTsKKyAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZChsaW5lKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKDAgIT0gY29sdW1uKSB7CisgICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoIjsgQ29sdW1uIzogIik7CisgICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoY29sdW1uKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIHNidWZmZXIudG9TdHJpbmcoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJpbnQgdGhlIHRoZSB0cmFjZSBvZiBtZXRob2RzIGZyb20gd2hlcmUgdGhlIGVycm9yCisgICAgICogb3JpZ2luYXRlZC4gIFRoaXMgd2lsbCB0cmFjZSBhbGwgbmVzdGVkIGV4Y2VwdGlvbgorICAgICAqIG9iamVjdHMsIGFzIHdlbGwgYXMgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJpbnRTdGFja1RyYWNlKCkgeworICAgICAgICBwcmludFN0YWNrVHJhY2UobmV3IGphdmEuaW8uUHJpbnRXcml0ZXIoU3lzdGVtLmVyciwgdHJ1ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50IHRoZSB0aGUgdHJhY2Ugb2YgbWV0aG9kcyBmcm9tIHdoZXJlIHRoZSBlcnJvcgorICAgICAqIG9yaWdpbmF0ZWQuICBUaGlzIHdpbGwgdHJhY2UgYWxsIG5lc3RlZCBleGNlcHRpb24KKyAgICAgKiBvYmplY3RzLCBhcyB3ZWxsIGFzIHRoaXMgb2JqZWN0LgorICAgICAqIEBwYXJhbSBzIFRoZSBzdHJlYW0gd2hlcmUgdGhlIGR1bXAgd2lsbCBiZSBzZW50IHRvLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50U3RhY2tUcmFjZShqYXZhLmlvLlByaW50U3RyZWFtIHMpIHsKKyAgICAgICAgcHJpbnRTdGFja1RyYWNlKG5ldyBqYXZhLmlvLlByaW50V3JpdGVyKHMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludCB0aGUgdGhlIHRyYWNlIG9mIG1ldGhvZHMgZnJvbSB3aGVyZSB0aGUgZXJyb3IKKyAgICAgKiBvcmlnaW5hdGVkLiAgVGhpcyB3aWxsIHRyYWNlIGFsbCBuZXN0ZWQgZXhjZXB0aW9uCisgICAgICogb2JqZWN0cywgYXMgd2VsbCBhcyB0aGlzIG9iamVjdC4KKyAgICAgKiBAcGFyYW0gcyBUaGUgd3JpdGVyIHdoZXJlIHRoZSBkdW1wIHdpbGwgYmUgc2VudCB0by4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludFN0YWNrVHJhY2UoamF2YS5pby5QcmludFdyaXRlciBzKSB7CisKKyAgICAgICAgaWYgKHMgPT0gbnVsbCkgeworICAgICAgICAgICAgcyA9IG5ldyBqYXZhLmlvLlByaW50V3JpdGVyKFN5c3RlbS5lcnIsIHRydWUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBsb2NJbmZvID0gZ2V0TG9jYXRpb25Bc1N0cmluZygpOworCisgICAgICAgICAgICBpZiAobnVsbCAhPSBsb2NJbmZvKSB7CisgICAgICAgICAgICAgICAgcy5wcmludGxuKGxvY0luZm8pOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzdXBlci5wcmludFN0YWNrVHJhY2Uocyk7CisgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7fQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL1RyYW5zZm9ybWVyRmFjdG9yeS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vVHJhbnNmb3JtZXJGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzZjOTJjZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL1RyYW5zZm9ybWVyRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMzI4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8gJElkOiBUcmFuc2Zvcm1lckZhY3RvcnkuamF2YSA4ODQ5NjMgMjAwOS0xMS0yNyAxOToxMTo1OVogbXJnbGF2YXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm07CisKKy8qKgorICogPHA+QSBUcmFuc2Zvcm1lckZhY3RvcnkgaW5zdGFuY2UgY2FuIGJlIHVzZWQgdG8gY3JlYXRlCisgKiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcn0gYW5kCisgKiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXN9IG9iamVjdHMuPC9wPgorICoKKyAqIDxwPlRoZSBzeXN0ZW0gcHJvcGVydHkgdGhhdCBkZXRlcm1pbmVzIHdoaWNoIEZhY3RvcnkgaW1wbGVtZW50YXRpb24KKyAqIHRvIGNyZWF0ZSBpcyBuYW1lZCA8Y29kZT4iamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkiPC9jb2RlPi4KKyAqIFRoaXMgcHJvcGVydHkgbmFtZXMgYSBjb25jcmV0ZSBzdWJjbGFzcyBvZiB0aGUKKyAqIDxjb2RlPlRyYW5zZm9ybWVyRmFjdG9yeTwvY29kZT4gYWJzdHJhY3QgY2xhc3MuIElmIHRoZSBwcm9wZXJ0eSBpcyBub3QKKyAqIGRlZmluZWQsIGEgcGxhdGZvcm0gZGVmYXVsdCBpcyBiZSB1c2VkLjwvcD4KKyAqCisgKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFRyYW5zZm9ybWVyRmFjdG9yeSB7CisKKyAgICAvKioKKyAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yIGlzIHByb3RlY3RlZCBvbiBwdXJwb3NlLgorICAgICAqLworICAgIHByb3RlY3RlZCBUcmFuc2Zvcm1lckZhY3RvcnkoKSB7IH0KKworCisgICAgLyoqCisgICAgICogPHA+R2V0IGN1cnJlbnQgc3RhdGUgb2YgY2Fub25pY2FsaXphdGlvbi48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIGN1cnJlbnQgc3RhdGUgY2Fub25pY2FsaXphdGlvbiBjb250cm9sCisgICAgICovCisgICAgLyoKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRDYW5vbmljYWxpemF0aW9uKCkgeworICAgICAgICByZXR1cm4gY2Fub25pY2FsU3RhdGU7CisgICAgfQorICAgICovCisKKyAgICAvKioKKyAgICAgKiA8cD5TZXQgY2Fub25pY2FsaXphdGlvbiBjb250cm9sIHRvIDxjb2RlPnRydWU8L2NvZGU+IG9yCisgICAgICogPC9jb2RlPmZhbHNlPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhdGUgb2YgY2Fub25pY2FsaXphdGlvbgorICAgICAqLworICAgIC8qCisgICAgcHVibGljIHZvaWQgc2V0Q2Fub25pY2FsaXphdGlvbihib29sZWFuIHN0YXRlKSB7CisgICAgICAgIGNhbm9uaWNhbFN0YXRlID0gc3RhdGU7CisgICAgfQorICAgICovCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFuZHJvaWQncyBpbXBsZW1lbnRhdGlvbiBvZiB7QGNvZGUgVHJhbnNmb3JtZXJGYWN0b3J5fS4gVW5saWtlCisgICAgICogb3RoZXIgSmF2YSBpbXBsZW1lbnRhdGlvbnMsIHRoaXMgbWV0aG9kIGRvZXMgbm90IGNvbnN1bHQgc3lzdGVtCisgICAgICogcHJvcGVydGllcywgcHJvcGVydGllcyBmaWxlcywgb3IgdGhlIHNlcnZpY2VzIEFQSS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIG5ldmVyLiBJbmNsdWRlZCBmb3IgQVBJCisgICAgICogICAgIGNvbXBhdGliaWxpdHkgd2l0aCBvdGhlciBKYXZhIGltcGxlbWVudGF0aW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFRyYW5zZm9ybWVyRmFjdG9yeSBuZXdJbnN0YW5jZSgpCisgICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIHsKKyAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9ICJvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5UcmFuc2Zvcm1lckZhY3RvcnlJbXBsIjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiAoVHJhbnNmb3JtZXJGYWN0b3J5KSBDbGFzcy5mb3JOYW1lKGNsYXNzTmFtZSkubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb0NsYXNzRGVmRm91bmRFcnJvcihjbGFzc05hbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiB0aGUgbmFtZWQgaW1wbGVtZW50YXRpb24gb2Yge0Bjb2RlIFRyYW5zZm9ybWVyRmFjdG9yeX0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBpZiB7QGNvZGUgZmFjdG9yeUNsYXNzTmFtZX0gaXMgbm90IGF2YWlsYWJsZSBvcgorICAgICAqICAgICBjYW5ub3QgYmUgaW5zdGFudGlhdGVkLgorICAgICAqIEBzaW5jZSAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFRyYW5zZm9ybWVyRmFjdG9yeSBuZXdJbnN0YW5jZShTdHJpbmcgZmFjdG9yeUNsYXNzTmFtZSwgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIpCisgICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIHsKKyAgICAgICAgaWYgKGZhY3RvcnlDbGFzc05hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcigiZmFjdG9yeUNsYXNzTmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNsYXNzTG9hZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIGNsYXNzTG9hZGVyID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3M8Pz4gdHlwZSA9IGNsYXNzTG9hZGVyICE9IG51bGwKKyAgICAgICAgICAgICAgICAgICAgPyBjbGFzc0xvYWRlci5sb2FkQ2xhc3MoZmFjdG9yeUNsYXNzTmFtZSkKKyAgICAgICAgICAgICAgICAgICAgOiBDbGFzcy5mb3JOYW1lKGZhY3RvcnlDbGFzc05hbWUpOworICAgICAgICAgICAgcmV0dXJuIChUcmFuc2Zvcm1lckZhY3RvcnkpIHR5cGUubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKGUpOworICAgICAgICB9IGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoZSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlByb2Nlc3MgdGhlIDxjb2RlPlNvdXJjZTwvY29kZT4gaW50byBhIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPgorICAgICAqIDxjb2RlPk9iamVjdDwvY29kZT4uICBUaGUgPGNvZGU+U291cmNlPC9jb2RlPiBpcyBhbiBYU0xUIGRvY3VtZW50IHRoYXQKKyAgICAgKiBjb25mb3JtcyB0byA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0Ij4KKyAgICAgKiBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBWZXJzaW9uIDEuMDwvYT4uICBDYXJlIG11c3QKKyAgICAgKiBiZSB0YWtlbiBub3QgdG8gdXNlIHRoaXMgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+IGluIG11bHRpcGxlCisgICAgICogPGNvZGU+VGhyZWFkPC9jb2RlPnMgcnVubmluZyBjb25jdXJyZW50bHkuCisgICAgICogRGlmZmVyZW50IDxjb2RlPlRyYW5zZm9ybWVyRmFjdG9yaWVzPC9jb2RlPiBjYW4gYmUgdXNlZCBjb25jdXJyZW50bHkgYnkKKyAgICAgKiBkaWZmZXJlbnQgPGNvZGU+VGhyZWFkPC9jb2RlPnMuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZSA8Y29kZT5Tb3VyY2UgPC9jb2RlPiBvZiBYU0xUIGRvY3VtZW50IHVzZWQgdG8gY3JlYXRlCisgICAgICogICA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4uCisgICAgICogICBFeGFtcGxlcyBvZiBYTUwgPGNvZGU+U291cmNlPC9jb2RlPnMgaW5jbHVkZQorICAgICAqICAge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZSBTdHJlYW1Tb3VyY2V9LAorICAgICAqICAge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZSBTQVhTb3VyY2V9IGFuZAorICAgICAqICAge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZSBET01Tb3VyY2V9LgorICAgICAqCisgICAgICogQHJldHVybiBBIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPiBvYmplY3QgdGhhdCBtYXkgYmUgdXNlZCB0byBwZXJmb3JtCisgICAgICogICBhIHRyYW5zZm9ybWF0aW9uIGluIGEgc2luZ2xlIDxjb2RlPlRocmVhZDwvY29kZT4sIG5ldmVyCisgICAgICogICA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBpZiB0aGVyZSBhcmUgZXJyb3JzIHdoZW4KKyAgICAgKiAgICBwYXJzaW5nIHRoZSA8Y29kZT5Tb3VyY2U8L2NvZGU+IG9yIGl0IGlzIG5vdCBwb3NzaWJsZSB0byBjcmVhdGUgYQorICAgICAqICAgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+IGluc3RhbmNlLgorICAgICAqCisgICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0Ij4KKyAgICAgKiAgIFhTTCBUcmFuc2Zvcm1hdGlvbnMgKFhTTFQpIFZlcnNpb24gMS4wPC9hPgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBUcmFuc2Zvcm1lciBuZXdUcmFuc2Zvcm1lcihTb3VyY2Ugc291cmNlKQorICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogPHA+Q3JlYXRlIGEgbmV3IDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPiB0aGF0IHBlcmZvcm1zIGEgY29weQorICAgICAqIG9mIHRoZSA8Y29kZT5Tb3VyY2U8L2NvZGU+IHRvIHRoZSA8Y29kZT5SZXN1bHQ8L2NvZGU+LgorICAgICAqIGkuZS4gdGhlICI8ZW0+aWRlbnRpdHkgdHJhbnNmb3JtPC9lbT4iLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQSBUcmFuc2Zvcm1lciBvYmplY3QgdGhhdCBtYXkgYmUgdXNlZCB0byBwZXJmb3JtIGEgdHJhbnNmb3JtYXRpb24KKyAgICAgKiBpbiBhIHNpbmdsZSB0aHJlYWQsIG5ldmVyIG51bGwuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gaWYgaXQgaXMgbm90CisgICAgICogICBwb3NzaWJsZSB0byBjcmVhdGUgYSA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFRyYW5zZm9ybWVyIG5ld1RyYW5zZm9ybWVyKCkKKyAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFByb2Nlc3MgdGhlIFNvdXJjZSBpbnRvIGEgVGVtcGxhdGVzIG9iamVjdCwgd2hpY2ggaXMgYQorICAgICAqIGEgY29tcGlsZWQgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNvdXJjZS4gVGhpcyBUZW1wbGF0ZXMgb2JqZWN0CisgICAgICogbWF5IHRoZW4gYmUgdXNlZCBjb25jdXJyZW50bHkgYWNyb3NzIG11bHRpcGxlIHRocmVhZHMuICBDcmVhdGluZworICAgICAqIGEgVGVtcGxhdGVzIG9iamVjdCBhbGxvd3MgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSB0byBkbyBkZXRhaWxlZAorICAgICAqIHBlcmZvcm1hbmNlIG9wdGltaXphdGlvbiBvZiB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMsIHdpdGhvdXQKKyAgICAgKiBwZW5hbGl6aW5nIHJ1bnRpbWUgdHJhbnNmb3JtYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc291cmNlIEFuIG9iamVjdCB0aGF0IGhvbGRzIGEgVVJMLCBpbnB1dCBzdHJlYW0sIGV0Yy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQSBUZW1wbGF0ZXMgb2JqZWN0IGNhcGFibGUgb2YgYmVpbmcgdXNlZCBmb3IgdHJhbnNmb3JtYXRpb24KKyAgICAgKiBwdXJwb3NlcywgbmV2ZXIgbnVsbC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIE1heSB0aHJvdyB0aGlzIGR1cmluZyB0aGUKKyAgICAgKiBwYXJzZSB3aGVuIGl0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzIG9iamVjdCBhbmQgZmFpbHMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFRlbXBsYXRlcyBuZXdUZW1wbGF0ZXMoU291cmNlIHNvdXJjZSkKKyAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIDxwPkdldCB0aGUgc3R5bGVzaGVldCBzcGVjaWZpY2F0aW9uKHMpIGFzc29jaWF0ZWQgd2l0aCB0aGUKKyAgICAgKiBYTUwgPGNvZGU+U291cmNlPC9jb2RlPiBkb2N1bWVudCB2aWEgdGhlCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sLXN0eWxlc2hlZXQvIj4KKyAgICAgKiB4bWwtc3R5bGVzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9uPC9hPiB0aGF0IG1hdGNoIHRoZSBnaXZlbiBjcml0ZXJpYS4KKyAgICAgKiBOb3RlIHRoYXQgaXQgaXMgcG9zc2libGUgdG8gcmV0dXJuIHNldmVyYWwgc3R5bGVzaGVldHMsIGluIHdoaWNoIGNhc2UKKyAgICAgKiB0aGV5IGFyZSBhcHBsaWVkIGFzIGlmIHRoZXkgd2VyZSBhIGxpc3Qgb2YgaW1wb3J0cyBvciBjYXNjYWRlcyBpbiBhCisgICAgICogc2luZ2xlIHN0eWxlc2hlZXQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZSBUaGUgWE1MIHNvdXJjZSBkb2N1bWVudC4KKyAgICAgKiBAcGFyYW0gbWVkaWEgVGhlIG1lZGlhIGF0dHJpYnV0ZSB0byBiZSBtYXRjaGVkLiAgTWF5IGJlIG51bGwsIGluIHdoaWNoCisgICAgICogICAgICBjYXNlIHRoZSBwcmVmZXJyZWQgdGVtcGxhdGVzIHdpbGwgYmUgdXNlZCAoaS5lLiBhbHRlcm5hdGUgPSBubykuCisgICAgICogQHBhcmFtIHRpdGxlIFRoZSB2YWx1ZSBvZiB0aGUgdGl0bGUgYXR0cmlidXRlIHRvIG1hdGNoLiAgTWF5IGJlIG51bGwuCisgICAgICogQHBhcmFtIGNoYXJzZXQgVGhlIHZhbHVlIG9mIHRoZSBjaGFyc2V0IGF0dHJpYnV0ZSB0byBtYXRjaC4gIE1heSBiZSBudWxsLgorICAgICAqCisgICAgICogQHJldHVybiBBIDxjb2RlPlNvdXJjZTwvY29kZT4gPGNvZGU+T2JqZWN0PC9jb2RlPiBzdWl0YWJsZSBmb3IgcGFzc2luZworICAgICAqICAgdG8gdGhlIDxjb2RlPlRyYW5zZm9ybWVyRmFjdG9yeTwvY29kZT4uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBBbiA8Y29kZT5FeGNlcHRpb248L2NvZGU+CisgICAgICogICBpcyB0aHJvd24gaWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyBwYXJzaW5nIG9mIHRoZQorICAgICAqICAgPGNvZGU+c291cmNlPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sLXN0eWxlc2hlZXQvIj4KKyAgICAgKiAgIEFzc29jaWF0aW5nIFN0eWxlIFNoZWV0cyB3aXRoIFhNTCBkb2N1bWVudHMgVmVyc2lvbiAxLjA8L2E+CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFNvdXJjZSBnZXRBc3NvY2lhdGVkU3R5bGVzaGVldCgKKyAgICAgICAgU291cmNlIHNvdXJjZSwKKyAgICAgICAgU3RyaW5nIG1lZGlhLAorICAgICAgICBTdHJpbmcgdGl0bGUsCisgICAgICAgIFN0cmluZyBjaGFyc2V0KQorICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0IGFuIG9iamVjdCB0aGF0IGlzIHVzZWQgYnkgZGVmYXVsdCBkdXJpbmcgdGhlIHRyYW5zZm9ybWF0aW9uCisgICAgICogdG8gcmVzb2x2ZSBVUklzIHVzZWQgaW4gZG9jdW1lbnQoKSwgeHNsOmltcG9ydCwgb3IgeHNsOmluY2x1ZGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVzb2x2ZXIgQW4gb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGUgVVJJUmVzb2x2ZXIgaW50ZXJmYWNlLAorICAgICAqIG9yIG51bGwuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0VVJJUmVzb2x2ZXIoVVJJUmVzb2x2ZXIgcmVzb2x2ZXIpOworCisgICAgLyoqCisgICAgICogR2V0IHRoZSBvYmplY3QgdGhhdCBpcyB1c2VkIGJ5IGRlZmF1bHQgZHVyaW5nIHRoZSB0cmFuc2Zvcm1hdGlvbgorICAgICAqIHRvIHJlc29sdmUgVVJJcyB1c2VkIGluIGRvY3VtZW50KCksIHhzbDppbXBvcnQsIG9yIHhzbDppbmNsdWRlLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgVVJJUmVzb2x2ZXIgdGhhdCB3YXMgc2V0IHdpdGggc2V0VVJJUmVzb2x2ZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFVSSVJlc29sdmVyIGdldFVSSVJlc29sdmVyKCk7CisKKyAgICAvLz09PT09PT0gQ09ORklHVVJBVElPTiBNRVRIT0RTID09PT09PT0KKworICAgIC8qKgorICAgICAqIDxwPlNldCBhIGZlYXR1cmUgZm9yIHRoaXMgPGNvZGU+VHJhbnNmb3JtZXJGYWN0b3J5PC9jb2RlPiBhbmQgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+cworICAgICAqIG9yIDxjb2RlPlRlbXBsYXRlPC9jb2RlPnMgY3JlYXRlZCBieSB0aGlzIGZhY3RvcnkuPC9wPgorICAgICAqCisgICAgICogPHA+CisgICAgICogRmVhdHVyZSBuYW1lcyBhcmUgZnVsbHkgcXVhbGlmaWVkIHtAbGluayBqYXZhLm5ldC5VUkl9cy4KKyAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbWF5IGRlZmluZSB0aGVpciBvd24gZmVhdHVyZXMuCisgICAgICogQW4ge0BsaW5rIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbn0gaXMgdGhyb3duIGlmIHRoaXMgPGNvZGU+VHJhbnNmb3JtZXJGYWN0b3J5PC9jb2RlPiBvciB0aGUKKyAgICAgKiA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT5zIG9yIDxjb2RlPlRlbXBsYXRlPC9jb2RlPnMgaXQgY3JlYXRlcyBjYW5ub3Qgc3VwcG9ydCB0aGUgZmVhdHVyZS4KKyAgICAgKiBJdCBpcyBwb3NzaWJsZSBmb3IgYW4gPGNvZGU+VHJhbnNmb3JtZXJGYWN0b3J5PC9jb2RlPiB0byBleHBvc2UgYSBmZWF0dXJlIHZhbHVlIGJ1dCBiZSB1bmFibGUgdG8gY2hhbmdlIGl0cyBzdGF0ZS4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiA8cD5BbGwgaW1wbGVtZW50YXRpb25zIGFyZSByZXF1aXJlZCB0byBzdXBwb3J0IHRoZSB7QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HfSBmZWF0dXJlLgorICAgICAqIFdoZW4gdGhlIGZlYXR1cmUgaXM6PC9wPgorICAgICAqIDx1bD4KKyAgICAgKiAgIDxsaT4KKyAgICAgKiAgICAgPGNvZGU+dHJ1ZTwvY29kZT46IHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsIGxpbWl0IFhNTCBwcm9jZXNzaW5nIHRvIGNvbmZvcm0gdG8gaW1wbGVtZW50YXRpb24gbGltaXRzCisgICAgICogICAgIGFuZCBiZWhhdmUgaW4gYSBzZWN1cmUgZmFzaGlvbiBhcyBkZWZpbmVkIGJ5IHRoZSBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKiAgICAgRXhhbXBsZXMgaW5jbHVkZSByZXNvbHZpbmcgdXNlciBkZWZpbmVkIHN0eWxlIHNoZWV0cyBhbmQgZnVuY3Rpb25zLgorICAgICAqICAgICBJZiBYTUwgcHJvY2Vzc2luZyBpcyBsaW1pdGVkIGZvciBzZWN1cml0eSByZWFzb25zLCBpdCB3aWxsIGJlIHJlcG9ydGVkIHZpYSBhIGNhbGwgdG8gdGhlIHJlZ2lzdGVyZWQKKyAgICAgKiAgICAge0BsaW5rIEVycm9yTGlzdGVuZXIjZmF0YWxFcnJvcihUcmFuc2Zvcm1lckV4Y2VwdGlvbiBleGNlcHRpb24pfS4KKyAgICAgKiAgICAgU2VlIHtAbGluayAgI3NldEVycm9yTGlzdGVuZXIoRXJyb3JMaXN0ZW5lciBsaXN0ZW5lcil9LgorICAgICAqICAgPC9saT4KKyAgICAgKiAgIDxsaT4KKyAgICAgKiAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+OiB0aGUgaW1wbGVtZW50YXRpb24gd2lsbCBwcm9jZXNzaW5nIFhNTCBhY2NvcmRpbmcgdG8gdGhlIFhNTCBzcGVjaWZpY2F0aW9ucyB3aXRob3V0CisgICAgICogICAgIHJlZ2FyZCB0byBwb3NzaWJsZSBpbXBsZW1lbnRhdGlvbiBsaW1pdHMuCisgICAgICogICA8L2xpPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBGZWF0dXJlIG5hbWUuCisgICAgICogQHBhcmFtIHZhbHVlIElzIGZlYXR1cmUgc3RhdGUgPGNvZGU+dHJ1ZTwvY29kZT4gb3IgPGNvZGU+ZmFsc2U8L2NvZGU+LgorICAgICAqCisgICAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gaWYgdGhpcyA8Y29kZT5UcmFuc2Zvcm1lckZhY3Rvcnk8L2NvZGU+CisgICAgICogICBvciB0aGUgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+cyBvciA8Y29kZT5UZW1wbGF0ZTwvY29kZT5zIGl0IGNyZWF0ZXMgY2Fubm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgdGhlIDxjb2RlPm5hbWU8L2NvZGU+IHBhcmFtZXRlciBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpCisgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBMb29rIHVwIHRoZSB2YWx1ZSBvZiBhIGZlYXR1cmUuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBGZWF0dXJlIG5hbWVzIGFyZSBmdWxseSBxdWFsaWZpZWQge0BsaW5rIGphdmEubmV0LlVSSX1zLgorICAgICAqIEltcGxlbWVudGF0aW9ucyBtYXkgZGVmaW5lIHRoZWlyIG93biBmZWF0dXJlcy4KKyAgICAgKiA8Y29kZT5mYWxzZTwvY29kZT4gaXMgcmV0dXJuZWQgaWYgdGhpcyA8Y29kZT5UcmFuc2Zvcm1lckZhY3Rvcnk8L2NvZGU+IG9yIHRoZQorICAgICAqIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPnMgb3IgPGNvZGU+VGVtcGxhdGU8L2NvZGU+cyBpdCBjcmVhdGVzIGNhbm5vdCBzdXBwb3J0IHRoZSBmZWF0dXJlLgorICAgICAqIEl0IGlzIHBvc3NpYmxlIGZvciBhbiA8Y29kZT5UcmFuc2Zvcm1lckZhY3Rvcnk8L2NvZGU+IHRvIGV4cG9zZSBhIGZlYXR1cmUgdmFsdWUgYnV0IGJlIHVuYWJsZSB0byBjaGFuZ2UgaXRzIHN0YXRlLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIEZlYXR1cmUgbmFtZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGZlYXR1cmUsIDxjb2RlPnRydWU8L2NvZGU+IG9yIDxjb2RlPmZhbHNlPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgdGhlIDxjb2RlPm5hbWU8L2NvZGU+IHBhcmFtZXRlciBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpOworCisgICAgLyoqCisgICAgICogQWxsb3dzIHRoZSB1c2VyIHRvIHNldCBzcGVjaWZpYyBhdHRyaWJ1dGVzIG9uIHRoZSB1bmRlcmx5aW5nCisgICAgICogaW1wbGVtZW50YXRpb24uICBBbiBhdHRyaWJ1dGUgaW4gdGhpcyBjb250ZXh0IGlzIGRlZmluZWQgdG8KKyAgICAgKiBiZSBhbiBvcHRpb24gdGhhdCB0aGUgaW1wbGVtZW50YXRpb24gcHJvdmlkZXMuCisgICAgICogQW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHJlY29nbml6ZSB0aGUgYXR0cmlidXRlLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KKyAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0QXR0cmlidXRlKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpOworCisgICAgLyoqCisgICAgICogQWxsb3dzIHRoZSB1c2VyIHRvIHJldHJpZXZlIHNwZWNpZmljIGF0dHJpYnV0ZXMgb24gdGhlIHVuZGVybHlpbmcKKyAgICAgKiBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKiBBbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93biBpZiB0aGUgdW5kZXJseWluZworICAgICAqIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgcmVjb2duaXplIHRoZSBhdHRyaWJ1dGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgorICAgICAqIEByZXR1cm4gdmFsdWUgVGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IE9iamVjdCBnZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpOworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBlcnJvciBldmVudCBsaXN0ZW5lciBmb3IgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSwgd2hpY2gKKyAgICAgKiBpcyB1c2VkIGZvciB0aGUgcHJvY2Vzc2luZyBvZiB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMsCisgICAgICogYW5kIG5vdCBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uIGl0c2VsZi4KKyAgICAgKiBBbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93biBpZiB0aGUKKyAgICAgKiA8Y29kZT5FcnJvckxpc3RlbmVyPC9jb2RlPiBsaXN0ZW5lciBpcyA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsaXN0ZW5lciBUaGUgbmV3IGVycm9yIGxpc3RlbmVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEVycm9yTGlzdGVuZXIoRXJyb3JMaXN0ZW5lciBsaXN0ZW5lcik7CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGVycm9yIGV2ZW50IGhhbmRsZXIgZm9yIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGVycm9yIGhhbmRsZXIsIHdoaWNoIHNob3VsZCBuZXZlciBiZSBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBFcnJvckxpc3RlbmVyIGdldEVycm9yTGlzdGVuZXIoKTsKKworfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL1RyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhNGZlZTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IuamF2YQpAQCAtMCwwICsxLDExMyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vICRJZDogVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yLmphdmEgNTY5OTk0IDIwMDctMDgtMjcgMDQ6Mjg6NTdaIG1yZ2xhdmFzICQKKworcGFja2FnZSBqYXZheC54bWwudHJhbnNmb3JtOworCisvKioKKyAqIFRocm93biB3aGVuIGEgcHJvYmxlbSB3aXRoIGNvbmZpZ3VyYXRpb24gd2l0aCB0aGUgVHJhbnNmb3JtZXIgRmFjdG9yaWVzCisgKiBleGlzdHMuIFRoaXMgZXJyb3Igd2lsbCB0eXBpY2FsbHkgYmUgdGhyb3duIHdoZW4gdGhlIGNsYXNzIG9mIGEKKyAqIHRyYW5zZm9ybWF0aW9uIGZhY3Rvcnkgc3BlY2lmaWVkIGluIHRoZSBzeXN0ZW0gcHJvcGVydGllcyBjYW5ub3QgYmUgZm91bmQKKyAqIG9yIGluc3RhbnRpYXRlZC4KKyAqLworcHVibGljIGNsYXNzIFRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBleHRlbmRzIEVycm9yIHsKKworICAgIC8qKgorICAgICAqIDxjb2RlPkV4Y2VwdGlvbjwvY29kZT4gZm9yIHRoZQorICAgICAqICA8Y29kZT5UcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3I8L2NvZGU+LgorICAgICAqLworICAgIHByaXZhdGUgRXhjZXB0aW9uIGV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5UcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3I8L2NvZGU+IHdpdGggbm8KKyAgICAgKiBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKCkgeworICAgICAgICB0aGlzLmV4Y2VwdGlvbiA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPlRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjwvY29kZT4gd2l0aAorICAgICAqIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHNwZWNpZmllZCBhcyBhbiBlcnJvciBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZyBUaGUgZXJyb3IgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKFN0cmluZyBtc2cpIHsKKworICAgICAgICBzdXBlcihtc2cpOworCisgICAgICAgIHRoaXMuZXhjZXB0aW9uID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+VHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yPC9jb2RlPiB3aXRoIGEKKyAgICAgKiBnaXZlbiA8Y29kZT5FeGNlcHRpb248L2NvZGU+IGJhc2UgY2F1c2Ugb2YgdGhlIGVycm9yLgorICAgICAqCisgICAgICogQHBhcmFtIGUgVGhlIGV4Y2VwdGlvbiB0byBiZSBlbmNhcHN1bGF0ZWQgaW4gYQorICAgICAqIFRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKEV4Y2VwdGlvbiBlKSB7CisKKyAgICAgICAgc3VwZXIoZS50b1N0cmluZygpKTsKKworICAgICAgICB0aGlzLmV4Y2VwdGlvbiA9IGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPlRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjwvY29kZT4gd2l0aCB0aGUKKyAgICAgKiBnaXZlbiA8Y29kZT5FeGNlcHRpb248L2NvZGU+IGJhc2UgY2F1c2UgYW5kIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIGUgVGhlIGV4Y2VwdGlvbiB0byBiZSBlbmNhcHN1bGF0ZWQgaW4gYQorICAgICAqIFRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcgorICAgICAqIEBwYXJhbSBtc2cgVGhlIGRldGFpbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBUcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoRXhjZXB0aW9uIGUsIFN0cmluZyBtc2cpIHsKKworICAgICAgICBzdXBlcihtc2cpOworCisgICAgICAgIHRoaXMuZXhjZXB0aW9uID0gZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG1lc3NhZ2UgKGlmIGFueSkgZm9yIHRoaXMgZXJyb3IgLiBJZiB0aGVyZSBpcyBubworICAgICAqIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24gYW5kIHRoZXJlIGlzIGFuIGVuY2Fwc3VsYXRlZAorICAgICAqIGV4Y2VwdGlvbiB0aGVuIHRoZSBtZXNzYWdlIG9mIHRoYXQgZXhjZXB0aW9uIHdpbGwgYmUgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBlcnJvciBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKworICAgICAgICBTdHJpbmcgbWVzc2FnZSA9IHN1cGVyLmdldE1lc3NhZ2UoKTsKKworICAgICAgICBpZiAoKG1lc3NhZ2UgPT0gbnVsbCkgJiYgKGV4Y2VwdGlvbiAhPSBudWxsKSkgeworICAgICAgICAgICAgcmV0dXJuIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbWVzc2FnZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGFjdHVhbCBleGNlcHRpb24gKGlmIGFueSkgdGhhdCBjYXVzZWQgdGhpcyBleGNlcHRpb24gdG8KKyAgICAgKiBiZSByYWlzZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBlbmNhcHN1bGF0ZWQgZXhjZXB0aW9uLCBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuCisgICAgICovCisgICAgcHVibGljIEV4Y2VwdGlvbiBnZXRFeGNlcHRpb24oKSB7CisgICAgICAgIHJldHVybiBleGNlcHRpb247CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vVVJJUmVzb2x2ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL1VSSVJlc29sdmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjhhYjYwMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL1VSSVJlc29sdmVyLmphdmEKQEAgLTAsMCArMSw0NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vICRJZDogVVJJUmVzb2x2ZXIuamF2YSA0NDY1OTggMjAwNi0wOS0xNSAxMjo1NTo0MFogamVyZW1pYXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm07CisKKy8qKgorICogPHA+QW4gb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSB0aGF0IGNhbiBiZSBjYWxsZWQgYnkgdGhlIHByb2Nlc3NvcgorICogdG8gdHVybiBhIFVSSSB1c2VkIGluIGRvY3VtZW50KCksIHhzbDppbXBvcnQsIG9yIHhzbDppbmNsdWRlIGludG8gYSBTb3VyY2Ugb2JqZWN0LgorICovCitwdWJsaWMgaW50ZXJmYWNlIFVSSVJlc29sdmVyIHsKKworICAgIC8qKgorICAgICAqIENhbGxlZCBieSB0aGUgcHJvY2Vzc29yIHdoZW4gaXQgZW5jb3VudGVycworICAgICAqIGFuIHhzbDppbmNsdWRlLCB4c2w6aW1wb3J0LCBvciBkb2N1bWVudCgpIGZ1bmN0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGhyZWYgQW4gaHJlZiBhdHRyaWJ1dGUsIHdoaWNoIG1heSBiZSByZWxhdGl2ZSBvciBhYnNvbHV0ZS4KKyAgICAgKiBAcGFyYW0gYmFzZSBUaGUgYmFzZSBVUkkgYWdhaW5zdCB3aGljaCB0aGUgZmlyc3QgYXJndW1lbnQgd2lsbCBiZSBtYWRlCisgICAgICogYWJzb2x1dGUgaWYgdGhlIGFic29sdXRlIFVSSSBpcyByZXF1aXJlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQSBTb3VyY2Ugb2JqZWN0LCBvciBudWxsIGlmIHRoZSBocmVmIGNhbm5vdCBiZSByZXNvbHZlZCwKKyAgICAgKiBhbmQgdGhlIHByb2Nlc3NvciBzaG91bGQgdHJ5IHRvIHJlc29sdmUgdGhlIFVSSSBpdHNlbGYuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycyB3aGVuIHRyeWluZyB0bworICAgICAqIHJlc29sdmUgdGhlIFVSSS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU291cmNlIHJlc29sdmUoU3RyaW5nIGhyZWYsIFN0cmluZyBiYXNlKQorICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9kb20vRE9NTG9jYXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vZG9tL0RPTUxvY2F0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYWFjYjU3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vZG9tL0RPTUxvY2F0b3IuamF2YQpAQCAtMCwwICsxLDQzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8gJElkOiBET01Mb2NhdG9yLmphdmEgNDQ2NTk4IDIwMDYtMDktMTUgMTI6NTU6NDBaIGplcmVtaWFzICQKKworcGFja2FnZSBqYXZheC54bWwudHJhbnNmb3JtLmRvbTsKKworaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvcjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworCisKKy8qKgorICogSW5kaWNhdGVzIHRoZSBwb3NpdGlvbiBvZiBhIG5vZGUgaW4gYSBzb3VyY2UgRE9NLCBpbnRlbmRlZAorICogcHJpbWFyaWx5IGZvciBlcnJvciByZXBvcnRpbmcuICBUbyB1c2UgYSBET01Mb2NhdG9yLCB0aGUgcmVjZWl2ZXIgb2YgYW4KKyAqIGVycm9yIG11c3QgZG93bmNhc3QgdGhlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3J9CisgKiBvYmplY3QgcmV0dXJuZWQgYnkgYW4gZXhjZXB0aW9uLiBBIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyfQorICogbWF5IHVzZSB0aGlzIG9iamVjdCBmb3IgcHVycG9zZXMgb3RoZXIgdGhhbiBlcnJvciByZXBvcnRpbmcsIGZvciBpbnN0YW5jZSwKKyAqIHRvIGluZGljYXRlIHRoZSBzb3VyY2Ugbm9kZSB0aGF0IG9yaWdpbmF0ZWQgYSByZXN1bHQgbm9kZS4KKyAqLworcHVibGljIGludGVyZmFjZSBET01Mb2NhdG9yIGV4dGVuZHMgU291cmNlTG9jYXRvciB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG5vZGUgd2hlcmUgdGhlIGV2ZW50IG9jY3VycmVkLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgbm9kZSB0aGF0IGlzIHRoZSBsb2NhdGlvbiBmb3IgdGhlIGV2ZW50LgorICAgICAqLworICAgIHB1YmxpYyBOb2RlIGdldE9yaWdpbmF0aW5nTm9kZSgpOworfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9kb20vRE9NUmVzdWx0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9kb20vRE9NUmVzdWx0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGNlM2VjNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL2RvbS9ET01SZXN1bHQuamF2YQpAQCAtMCwwICsxLDM1MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vICRJZDogRE9NUmVzdWx0LmphdmEgNTY5OTk1IDIwMDctMDgtMjcgMDQ6MzE6MDZaIG1yZ2xhdmFzICQKKworcGFja2FnZSBqYXZheC54bWwudHJhbnNmb3JtLmRvbTsKKworaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CisKKy8qKgorICogPHA+QWN0cyBhcyBhIGhvbGRlciBmb3IgYSB0cmFuc2Zvcm1hdGlvbiByZXN1bHQgdHJlZSBpbiB0aGUgZm9ybSBvZiBhIERvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSB0cmVlLjwvcD4KKyAqCisgKiA8cD5JZiBubyBvdXRwdXQgRE9NIHNvdXJjZSBpcyBzZXQsIHRoZSB0cmFuc2Zvcm1hdGlvbiB3aWxsIGNyZWF0ZSBhIERvY3VtZW50IG5vZGUgYXMgdGhlIGhvbGRlciBmb3IgdGhlIHJlc3VsdCBvZiB0aGUgdHJhbnNmb3JtYXRpb24sCisgKiB3aGljaCBtYXkgYmUgcmV0cmlldmVkIHdpdGgge0BsaW5rICNnZXROb2RlKCl9LjwvcD4KKyAqCisgKiBAYXV0aG9yIDxhIGhyZWY9IkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgorICogQHZlcnNpb24gJFJldmlzaW9uOiA1Njk5OTUgJCwgJERhdGU6IDIwMDctMDgtMjYgMjE6MzE6MDYgLTA3MDAgKFN1biwgMjYgQXVnIDIwMDcpICQKKyAqLworcHVibGljIGNsYXNzIERPTVJlc3VsdCBpbXBsZW1lbnRzIFJlc3VsdCB7CisKKyAgICAvKiogPHA+SWYge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I2dldEZlYXR1cmV9CisgICAgICogcmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiB3aGVuIHBhc3NlZCB0aGlzIHZhbHVlIGFzIGFuIGFyZ3VtZW50LAorICAgICAqIHRoZSA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gc3VwcG9ydHMgPGNvZGU+UmVzdWx0PC9jb2RlPiBvdXRwdXQgb2YgdGhpcyB0eXBlLjwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGRUFUVVJFID0gImh0dHA6Ly9qYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01SZXN1bHQvZmVhdHVyZSI7CisKKyAgICAvKioKKyAgICAgKiA8cD5aZXJvLWFyZ3VtZW50IGRlZmF1bHQgY29uc3RydWN0b3IuPC9wPgorICAgICAqCisgICAgICogPHA+PGNvZGU+bm9kZTwvY29kZT4sCisgICAgICogPGNvZGU+c2libGluZ05vZGU8L2NvZGU+IGFuZAorICAgICAqIDxjb2RlPnN5c3RlbUlkPC9jb2RlPgorICAgICAqIHdpbGwgYmUgc2V0IHRvIDxjb2RlPm51bGw8L2NvZGU+LjwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgRE9NUmVzdWx0KCkgeworICAgICAgICBzZXROb2RlKG51bGwpOworICAgICAgICBzZXROZXh0U2libGluZyhudWxsKTsKKyAgICAgICAgc2V0U3lzdGVtSWQobnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+VXNlIGEgRE9NIG5vZGUgdG8gY3JlYXRlIGEgbmV3IG91dHB1dCB0YXJnZXQuPC9wPgorICAgICAqCisgICAgICogPHA+SW4gcHJhY3RpY2UsIHRoZSBub2RlIHNob3VsZCBiZQorICAgICAqIGEge0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50fSBub2RlLAorICAgICAqIGEge0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnR9IG5vZGUsIG9yCisgICAgICogYSB7QGxpbmsgb3JnLnczYy5kb20uRWxlbWVudH0gbm9kZS4KKyAgICAgKiBJbiBvdGhlciB3b3JkcywgYSBub2RlIHRoYXQgYWNjZXB0cyBjaGlsZHJlbi48L3A+CisgICAgICoKKyAgICAgKiA8cD48Y29kZT5zaWJsaW5nTm9kZTwvY29kZT4gYW5kCisgICAgICogPGNvZGU+c3lzdGVtSWQ8L2NvZGU+CisgICAgICogd2lsbCBiZSBzZXQgdG8gPGNvZGU+bnVsbDwvY29kZT4uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5vZGUgVGhlIERPTSBub2RlIHRoYXQgd2lsbCBjb250YWluIHRoZSByZXN1bHQgdHJlZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRE9NUmVzdWx0KE5vZGUgbm9kZSkgeworICAgICAgICBzZXROb2RlKG5vZGUpOworICAgICAgICBzZXROZXh0U2libGluZyhudWxsKTsKKyAgICAgICAgc2V0U3lzdGVtSWQobnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+VXNlIGEgRE9NIG5vZGUgdG8gY3JlYXRlIGEgbmV3IG91dHB1dCB0YXJnZXQgd2l0aCB0aGUgc3BlY2lmaWVkIFN5c3RlbSBJRC48cD4KKyAgICAgKgorICAgICAqIDxwPkluIHByYWN0aWNlLCB0aGUgbm9kZSBzaG91bGQgYmUKKyAgICAgKiBhIHtAbGluayBvcmcudzNjLmRvbS5Eb2N1bWVudH0gbm9kZSwKKyAgICAgKiBhIHtAbGluayBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50fSBub2RlLCBvcgorICAgICAqIGEge0BsaW5rIG9yZy53M2MuZG9tLkVsZW1lbnR9IG5vZGUuCisgICAgICogSW4gb3RoZXIgd29yZHMsIGEgbm9kZSB0aGF0IGFjY2VwdHMgY2hpbGRyZW4uPC9wPgorICAgICAqCisgICAgICogPHA+PGNvZGU+c2libGluZ05vZGU8L2NvZGU+IHdpbGwgYmUgc2V0IHRvIDxjb2RlPm51bGw8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBub2RlIFRoZSBET00gbm9kZSB0aGF0IHdpbGwgY29udGFpbiB0aGUgcmVzdWx0IHRyZWUuCisgICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciB3aGljaCBtYXkgYmUgdXNlZCBpbiBhc3NvY2lhdGlvbiB3aXRoIHRoaXMgbm9kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRE9NUmVzdWx0KE5vZGUgbm9kZSwgU3RyaW5nIHN5c3RlbUlkKSB7CisgICAgICAgIHNldE5vZGUobm9kZSk7CisgICAgICAgIHNldE5leHRTaWJsaW5nKG51bGwpOworICAgICAgICBzZXRTeXN0ZW1JZChzeXN0ZW1JZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+VXNlIGEgRE9NIG5vZGUgdG8gY3JlYXRlIGEgbmV3IG91dHB1dCB0YXJnZXQgc3BlY2lmeWluZyB0aGUgY2hpbGQgbm9kZSB3aGVyZSB0aGUgcmVzdWx0IG5vZGVzIHNob3VsZCBiZSBpbnNlcnRlZCBiZWZvcmUuPC9wPgorICAgICAqCisgICAgICogPHA+SW4gcHJhY3RpY2UsIDxjb2RlPm5vZGU8L2NvZGU+IGFuZCA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gc2hvdWxkIGJlCisgICAgICogYSB7QGxpbmsgb3JnLnczYy5kb20uRG9jdW1lbnR9IG5vZGUsCisgICAgICogYSB7QGxpbmsgb3JnLnczYy5kb20uRG9jdW1lbnRGcmFnbWVudH0gbm9kZSwgb3IKKyAgICAgKiBhIHtAbGluayBvcmcudzNjLmRvbS5FbGVtZW50fSBub2RlLgorICAgICAqIEluIG90aGVyIHdvcmRzLCBhIG5vZGUgdGhhdCBhY2NlcHRzIGNoaWxkcmVuLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlVzZSA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gdG8gc3BlY2lmeSB0aGUgY2hpbGQgbm9kZQorICAgICAqIHdoZXJlIHRoZSByZXN1bHQgbm9kZXMgc2hvdWxkIGJlIGluc2VydGVkIGJlZm9yZS4KKyAgICAgKiBJZiA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gaXMgbm90IGEgc2libGluZyBvZiA8Y29kZT5ub2RlPC9jb2RlPiwKKyAgICAgKiB0aGVuIGFuIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLgorICAgICAqIElmIDxjb2RlPm5vZGU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+IGFuZCA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gaXMgbm90IDxjb2RlPm51bGw8L2NvZGU+LAorICAgICAqIHRoZW4gYW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uCisgICAgICogSWYgPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LAorICAgICAqIHRoZW4gdGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIGNhbGxpbmcge0BsaW5rICNET01SZXN1bHQoTm9kZSBub2RlKX0sCisgICAgICogaS5lLiBhcHBlbmQgdGhlIHJlc3VsdCBub2RlcyBhcyB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgc3BlY2lmaWVkIDxjb2RlPm5vZGU8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPjxjb2RlPnN5c3RlbUlkPC9jb2RlPiB3aWxsIGJlIHNldCB0byA8Y29kZT5udWxsPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbm9kZSBUaGUgRE9NIG5vZGUgdGhhdCB3aWxsIGNvbnRhaW4gdGhlIHJlc3VsdCB0cmVlLgorICAgICAqIEBwYXJhbSBuZXh0U2libGluZyBUaGUgY2hpbGQgbm9kZSB3aGVyZSB0aGUgcmVzdWx0IG5vZGVzIHNob3VsZCBiZSBpbnNlcnRlZCBiZWZvcmUuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gaXMgbm90IGEgc2libGluZyBvZiA8Y29kZT5ub2RlPC9jb2RlPi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiA8Y29kZT5ub2RlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiBhbmQgPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IGlzIG5vdCA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgRE9NUmVzdWx0KE5vZGUgbm9kZSwgTm9kZSBuZXh0U2libGluZykgeworCisgICAgICAgIC8vIGRvZXMgdGhlIGNvcnJlbnQgcGFyZW50L2NoaWxkIHJlbGF0aW9uc2hpcCBleGlzdD8KKyAgICAgICAgaWYgKG5leHRTaWJsaW5nICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGNhbm5vdCBiZSBhIHNpYmxpbmcgb2YgYSBudWxsIG5vZGUKKyAgICAgICAgICAgIGlmIChub2RlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJDYW5ub3QgY3JlYXRlIGEgRE9NUmVzdWx0IHdoZW4gdGhlIG5leHRTaWJsaW5nIGlzIGNvbnRhaW5lZCBieSB0aGUgXCJudWxsXCIgbm9kZS4iKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gbmV4dFNpYmxpbmcgY29udGFpbmVkIGJ5IG5vZGU/CisgICAgICAgICAgICBpZiAoKG5vZGUuY29tcGFyZURvY3VtZW50UG9zaXRpb24obmV4dFNpYmxpbmcpJk5vZGUuRE9DVU1FTlRfUE9TSVRJT05fQ09OVEFJTkVEX0JZKT09MCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkNhbm5vdCBjcmVhdGUgYSBET01SZXN1bHQgd2hlbiB0aGUgbmV4dFNpYmxpbmcgaXMgbm90IGNvbnRhaW5lZCBieSB0aGUgbm9kZS4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHNldE5vZGUobm9kZSk7CisgICAgICAgIHNldE5leHRTaWJsaW5nKG5leHRTaWJsaW5nKTsKKyAgICAgICAgc2V0U3lzdGVtSWQobnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+VXNlIGEgRE9NIG5vZGUgdG8gY3JlYXRlIGEgbmV3IG91dHB1dCB0YXJnZXQgc3BlY2lmeWluZyB0aGUgY2hpbGQgbm9kZSB3aGVyZSB0aGUgcmVzdWx0IG5vZGVzIHNob3VsZCBiZSBpbnNlcnRlZCBiZWZvcmUgYW5kCisgICAgICogdGhlIHNwZWNpZmllZCBTeXN0ZW0gSUQuPC9wPgorICAgICAqCisgICAgICogPHA+SW4gcHJhY3RpY2UsIDxjb2RlPm5vZGU8L2NvZGU+IGFuZCA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gc2hvdWxkIGJlCisgICAgICogYSB7QGxpbmsgb3JnLnczYy5kb20uRG9jdW1lbnR9IG5vZGUsCisgICAgICogYSB7QGxpbmsgb3JnLnczYy5kb20uRG9jdW1lbnRGcmFnbWVudH0gbm9kZSwgb3IgYQorICAgICAqIHtAbGluayBvcmcudzNjLmRvbS5FbGVtZW50fSBub2RlLgorICAgICAqIEluIG90aGVyIHdvcmRzLCBhIG5vZGUgdGhhdCBhY2NlcHRzIGNoaWxkcmVuLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlVzZSA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gdG8gc3BlY2lmeSB0aGUgY2hpbGQgbm9kZQorICAgICAqIHdoZXJlIHRoZSByZXN1bHQgbm9kZXMgc2hvdWxkIGJlIGluc2VydGVkIGJlZm9yZS4KKyAgICAgKiBJZiA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gaXMgbm90IGEgc2libGluZyBvZiA8Y29kZT5ub2RlPC9jb2RlPiwKKyAgICAgKiB0aGVuIGFuIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLgorICAgICAqIElmIDxjb2RlPm5vZGU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+IGFuZCA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gaXMgbm90IDxjb2RlPm51bGw8L2NvZGU+LAorICAgICAqIHRoZW4gYW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uCisgICAgICogSWYgPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LAorICAgICAqIHRoZW4gdGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIGNhbGxpbmcge0BsaW5rICNET01SZXN1bHQoTm9kZSBub2RlLCBTdHJpbmcgc3lzdGVtSWQpfSwKKyAgICAgKiBpLmUuIGFwcGVuZCB0aGUgcmVzdWx0IG5vZGVzIGFzIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSBzcGVjaWZpZWQgbm9kZSBhbmQgdXNlIHRoZSBzcGVjaWZpZWQgU3lzdGVtIElELjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBub2RlIFRoZSBET00gbm9kZSB0aGF0IHdpbGwgY29udGFpbiB0aGUgcmVzdWx0IHRyZWUuCisgICAgICogQHBhcmFtIG5leHRTaWJsaW5nIFRoZSBjaGlsZCBub2RlIHdoZXJlIHRoZSByZXN1bHQgbm9kZXMgc2hvdWxkIGJlIGluc2VydGVkIGJlZm9yZS4KKyAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIHdoaWNoIG1heSBiZSB1c2VkIGluIGFzc29jaWF0aW9uIHdpdGggdGhpcyBub2RlLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IGlzIG5vdCBhIHNpYmxpbmcgb2YgPGNvZGU+bm9kZTwvY29kZT4uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgPGNvZGU+bm9kZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4gYW5kIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiBpcyBub3QgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICoKKyAgICAgKiBAc2luY2UgMS41CisgICAgICovCisgICAgcHVibGljIERPTVJlc3VsdChOb2RlIG5vZGUsIE5vZGUgbmV4dFNpYmxpbmcsIFN0cmluZyBzeXN0ZW1JZCkgeworCisgICAgICAgIC8vIGRvZXMgdGhlIGN1cnJlbnQgcGFyZW50L2NoaWxkIHJlbGF0aW9uc2hpcCBleGlzdD8KKyAgICAgICAgaWYgKG5leHRTaWJsaW5nICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGNhbm5vdCBiZSBhIHNpYmxpbmcgb2YgYSBudWxsIG5vZGUKKyAgICAgICAgICAgIGlmIChub2RlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJDYW5ub3QgY3JlYXRlIGEgRE9NUmVzdWx0IHdoZW4gdGhlIG5leHRTaWJsaW5nIGlzIGNvbnRhaW5lZCBieSB0aGUgXCJudWxsXCIgbm9kZS4iKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gbmV4dFNpYmxpbmcgY29udGFpbmVkIGJ5IG5vZGU/CisgICAgICAgICAgICBpZiAoKG5vZGUuY29tcGFyZURvY3VtZW50UG9zaXRpb24obmV4dFNpYmxpbmcpJk5vZGUuRE9DVU1FTlRfUE9TSVRJT05fQ09OVEFJTkVEX0JZKT09MCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkNhbm5vdCBjcmVhdGUgYSBET01SZXN1bHQgd2hlbiB0aGUgbmV4dFNpYmxpbmcgaXMgbm90IGNvbnRhaW5lZCBieSB0aGUgbm9kZS4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHNldE5vZGUobm9kZSk7CisgICAgICAgIHNldE5leHRTaWJsaW5nKG5leHRTaWJsaW5nKTsKKyAgICAgICAgc2V0U3lzdGVtSWQoc3lzdGVtSWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlNldCB0aGUgbm9kZSB0aGF0IHdpbGwgY29udGFpbiB0aGUgcmVzdWx0IERPTSB0cmVlLjxwPgorICAgICAqCisgICAgICogPHA+SW4gcHJhY3RpY2UsIHRoZSBub2RlIHNob3VsZCBiZQorICAgICAqIGEge0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50fSBub2RlLAorICAgICAqIGEge0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnR9IG5vZGUsIG9yCisgICAgICogYSB7QGxpbmsgb3JnLnczYy5kb20uRWxlbWVudH0gbm9kZS4KKyAgICAgKiBJbiBvdGhlciB3b3JkcywgYSBub2RlIHRoYXQgYWNjZXB0cyBjaGlsZHJlbi48L3A+CisgICAgICoKKyAgICAgKiA8cD5BbiA8Y29kZT5JbGxlZ2FsU3RhdGVFeGNlcHRpb248L2NvZGU+IGlzIHRocm93biBpZiA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gaXMgbm90IDxjb2RlPm51bGw8L2NvZGU+IGFuZAorICAgICAqIDxjb2RlPm5vZGU8L2NvZGU+IGlzIG5vdCBhIHBhcmVudCBvZiA8Y29kZT5uZXh0U2libGluZzwvY29kZT4uCisgICAgICogQW4gPGNvZGU+SWxsZWdhbFN0YXRlRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYgPGNvZGU+bm9kZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4gYW5kCisgICAgICogPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IGlzIG5vdCA8Y29kZT5udWxsPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSB0byB3aGljaCB0aGUgdHJhbnNmb3JtYXRpb24gd2lsbCBiZSBhcHBlbmRlZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIElmIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiBpcyBub3QgPGNvZGU+bnVsbDwvY29kZT4gYW5kCisgICAgICogICA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gaXMgbm90IGEgY2hpbGQgb2YgPGNvZGU+bm9kZTwvY29kZT4uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gSWYgPGNvZGU+bm9kZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4gYW5kCisgICAgICogICA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gaXMgbm90IDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5vZGUoTm9kZSBub2RlKSB7CisgICAgICAgIC8vIGRvZXMgdGhlIGNvcnJlbnQgcGFyZW50L2NoaWxkIHJlbGF0aW9uc2hpcCBleGlzdD8KKyAgICAgICAgaWYgKG5leHRTaWJsaW5nICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGNhbm5vdCBiZSBhIHNpYmxpbmcgb2YgYSBudWxsIG5vZGUKKyAgICAgICAgICAgIGlmIChub2RlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDYW5ub3QgY3JlYXRlIGEgRE9NUmVzdWx0IHdoZW4gdGhlIG5leHRTaWJsaW5nIGlzIGNvbnRhaW5lZCBieSB0aGUgXCJudWxsXCIgbm9kZS4iKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gbmV4dFNpYmxpbmcgY29udGFpbmVkIGJ5IG5vZGU/CisgICAgICAgICAgICBpZiAoKG5vZGUuY29tcGFyZURvY3VtZW50UG9zaXRpb24obmV4dFNpYmxpbmcpJk5vZGUuRE9DVU1FTlRfUE9TSVRJT05fQ09OVEFJTkVEX0JZKT09MCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkNhbm5vdCBjcmVhdGUgYSBET01SZXN1bHQgd2hlbiB0aGUgbmV4dFNpYmxpbmcgaXMgbm90IGNvbnRhaW5lZCBieSB0aGUgbm9kZS4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRoaXMubm9kZSA9IG5vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+R2V0IHRoZSBub2RlIHRoYXQgd2lsbCBjb250YWluIHRoZSByZXN1bHQgRE9NIHRyZWUuPC9wPgorICAgICAqCisgICAgICogPHA+SWYgbm8gbm9kZSB3YXMgc2V0IHZpYQorICAgICAqIHtAbGluayAjRE9NUmVzdWx0KE5vZGUgbm9kZSl9LAorICAgICAqIHtAbGluayAjRE9NUmVzdWx0KE5vZGUgbm9kZSwgU3RyaW5nIHN5c3RlSWQpfSwKKyAgICAgKiB7QGxpbmsgI0RPTVJlc3VsdChOb2RlIG5vZGUsIE5vZGUgbmV4dFNpYmxpbmcpfSwKKyAgICAgKiB7QGxpbmsgI0RPTVJlc3VsdChOb2RlIG5vZGUsIE5vZGUgbmV4dFNpYmxpbmcsIFN0cmluZyBzeXN0ZW1JZCl9IG9yCisgICAgICoge0BsaW5rICNzZXROb2RlKE5vZGUgbm9kZSl9LAorICAgICAqIHRoZW4gdGhlIG5vZGUgd2lsbCBiZSBzZXQgYnkgdGhlIHRyYW5zZm9ybWF0aW9uLCBhbmQgbWF5IGJlIG9idGFpbmVkIGZyb20gdGhpcyBtZXRob2Qgb25jZSB0aGUgdHJhbnNmb3JtYXRpb24gaXMgY29tcGxldGUuCisgICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCBiZWZvcmUgdGhlIHRyYW5zZm9ybWF0aW9uIHdpbGwgcmV0dXJuIDxjb2RlPm51bGw8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIG5vZGUgdG8gd2hpY2ggdGhlIHRyYW5zZm9ybWF0aW9uIHdpbGwgYmUgYXBwZW5kZWQuCisgICAgICovCisgICAgcHVibGljIE5vZGUgZ2V0Tm9kZSgpIHsKKyAgICAgICAgcmV0dXJuIG5vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+U2V0IHRoZSBjaGlsZCBub2RlIGJlZm9yZSB3aGljaCB0aGUgcmVzdWx0IG5vZGVzIHdpbGwgYmUgaW5zZXJ0ZWQuPC9wPgorICAgICAqCisgICAgICogPHA+VXNlIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiB0byBzcGVjaWZ5IHRoZSBjaGlsZCBub2RlCisgICAgICogYmVmb3JlIHdoaWNoIHRoZSByZXN1bHQgbm9kZXMgc2hvdWxkIGJlIGluc2VydGVkLgorICAgICAqIElmIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiBpcyBub3QgYSBkZXNjZW5kYW50IG9mIDxjb2RlPm5vZGU8L2NvZGU+LAorICAgICAqIHRoZW4gYW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uCisgICAgICogSWYgPGNvZGU+bm9kZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4gYW5kIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiBpcyBub3QgPGNvZGU+bnVsbDwvY29kZT4sCisgICAgICogdGhlbiBhbiA8Y29kZT5JbGxlZ2FsU3RhdGVFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi4KKyAgICAgKiBJZiA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sCisgICAgICogdGhlbiB0aGUgYmVoYXZpb3IgaXMgdGhlIHNhbWUgYXMgY2FsbGluZyB7QGxpbmsgI0RPTVJlc3VsdChOb2RlIG5vZGUpfSwKKyAgICAgKiBpLmUuIGFwcGVuZCB0aGUgcmVzdWx0IG5vZGVzIGFzIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSBzcGVjaWZpZWQgPGNvZGU+bm9kZTwvY29kZT4uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5leHRTaWJsaW5nIFRoZSBjaGlsZCBub2RlIGJlZm9yZSB3aGljaCB0aGUgcmVzdWx0IG5vZGVzIHdpbGwgYmUgaW5zZXJ0ZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gaXMgbm90IGEgZGVzY2VuZGFudCBvZiA8Y29kZT5ub2RlPC9jb2RlPi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBJZiA8Y29kZT5ub2RlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiBhbmQgPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IGlzIG5vdCA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROZXh0U2libGluZyhOb2RlIG5leHRTaWJsaW5nKSB7CisKKyAgICAgICAgLy8gZG9lcyB0aGUgY29ycmVudCBwYXJlbnQvY2hpbGQgcmVsYXRpb25zaGlwIGV4aXN0PworICAgICAgICBpZiAobmV4dFNpYmxpbmcgIT0gbnVsbCkgeworICAgICAgICAgICAgLy8gY2Fubm90IGJlIGEgc2libGluZyBvZiBhIG51bGwgbm9kZQorICAgICAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkNhbm5vdCBjcmVhdGUgYSBET01SZXN1bHQgd2hlbiB0aGUgbmV4dFNpYmxpbmcgaXMgY29udGFpbmVkIGJ5IHRoZSBcIm51bGxcIiBub2RlLiIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBuZXh0U2libGluZyBjb250YWluZWQgYnkgbm9kZT8KKyAgICAgICAgICAgIGlmICgobm9kZS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihuZXh0U2libGluZykmTm9kZS5ET0NVTUVOVF9QT1NJVElPTl9DT05UQUlORURfQlkpPT0wKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQ2Fubm90IGNyZWF0ZSBhIERPTVJlc3VsdCB3aGVuIHRoZSBuZXh0U2libGluZyBpcyBub3QgY29udGFpbmVkIGJ5IHRoZSBub2RlLiIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5uZXh0U2libGluZyA9IG5leHRTaWJsaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkdldCB0aGUgY2hpbGQgbm9kZSBiZWZvcmUgd2hpY2ggdGhlIHJlc3VsdCBub2RlcyB3aWxsIGJlIGluc2VydGVkLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIG5vIG5vZGUgd2FzIHNldCB2aWEKKyAgICAgKiB7QGxpbmsgI0RPTVJlc3VsdChOb2RlIG5vZGUsIE5vZGUgbmV4dFNpYmxpbmcpfSwKKyAgICAgKiB7QGxpbmsgI0RPTVJlc3VsdChOb2RlIG5vZGUsIE5vZGUgbmV4dFNpYmxpbmcsIFN0cmluZyBzeXN0ZW1JZCl9IG9yCisgICAgICoge0BsaW5rICNzZXROZXh0U2libGluZyhOb2RlIG5leHRTaWJsaW5nKX0sCisgICAgICogdGhlbiA8Y29kZT5udWxsPC9jb2RlPiB3aWxsIGJlIHJldHVybmVkLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIGNoaWxkIG5vZGUgYmVmb3JlIHdoaWNoIHRoZSByZXN1bHQgbm9kZXMgd2lsbCBiZSBpbnNlcnRlZC4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgTm9kZSBnZXROZXh0U2libGluZygpIHsKKyAgICAgICAgcmV0dXJuIG5leHRTaWJsaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlNldCB0aGUgc3lzdGVtSWQgdGhhdCBtYXkgYmUgdXNlZCBpbiBhc3NvY2lhdGlvbiB3aXRoIHRoZSBub2RlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgYXMgYSBVUkkgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCkgeworICAgICAgICB0aGlzLnN5c3RlbUlkID0gc3lzdGVtSWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+R2V0IHRoZSBTeXN0ZW0gSWRlbnRpZmllci48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiBubyBTeXN0ZW0gSUQgd2FzIHNldCB2aWEKKyAgICAgKiB7QGxpbmsgI0RPTVJlc3VsdChOb2RlIG5vZGUsIFN0cmluZyBzeXN0ZW1JZCl9LAorICAgICAqIHtAbGluayAjRE9NUmVzdWx0KE5vZGUgbm9kZSwgTm9kZSBuZXh0U2libGluZywgU3RyaW5nIHN5c3RlbUlkKX0gb3IKKyAgICAgKiB7QGxpbmsgI3NldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCl9LAorICAgICAqIHRoZW4gPGNvZGU+bnVsbDwvY29kZT4gd2lsbCBiZSByZXR1cm5lZC48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkgeworICAgICAgICByZXR1cm4gc3lzdGVtSWQ7CisgICAgfQorCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIEludGVybmFsIHN0YXRlLgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworICAgIC8qKgorICAgICAqIDxwPlRoZSBub2RlIHRvIHdoaWNoIHRoZSB0cmFuc2Zvcm1hdGlvbiB3aWxsIGJlIGFwcGVuZGVkLjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIE5vZGUgbm9kZSA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiA8cD5UaGUgY2hpbGQgbm9kZSBiZWZvcmUgd2hpY2ggdGhlIHJlc3VsdCBub2RlcyB3aWxsIGJlIGluc2VydGVkLjwvcD4KKyAgICAgKgorICAgICAqIEBzaW5jZSAxLjUKKyAgICAgKi8KKyAgICBwcml2YXRlIE5vZGUgbmV4dFNpYmxpbmcgPSBudWxsOworCisgICAgLyoqCisgICAgICogPHA+VGhlIFN5c3RlbSBJRCB0aGF0IG1heSBiZSB1c2VkIGluIGFzc29jaWF0aW9uIHdpdGggdGhlIG5vZGUuPC9wPgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHN5c3RlbUlkID0gbnVsbDsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL2RvbS9ET01Tb3VyY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL2RvbS9ET01Tb3VyY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MmY2OWFlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vZG9tL0RPTVNvdXJjZS5qYXZhCkBAIC0wLDAgKzEsMTMxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8gJElkOiBET01Tb3VyY2UuamF2YSA0NDY1OTggMjAwNi0wOS0xNSAxMjo1NTo0MFogamVyZW1pYXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tOworCitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKKworLyoqCisgKiA8cD5BY3RzIGFzIGEgaG9sZGVyIGZvciBhIHRyYW5zZm9ybWF0aW9uIFNvdXJjZSB0cmVlIGluIHRoZQorICogZm9ybSBvZiBhIERvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSB0cmVlLjwvcD4KKyAqCisgKiA8cD5Ob3RlIHRoYXQgWFNMVCByZXF1aXJlcyBuYW1lc3BhY2Ugc3VwcG9ydC4gQXR0ZW1wdGluZyB0byB0cmFuc2Zvcm0gYSBET00KKyAqIHRoYXQgd2FzIG5vdCBjb250cnVjdGVkIHdpdGggYSBuYW1lc3BhY2UtYXdhcmUgcGFyc2VyIG1heSByZXN1bHQgaW4gZXJyb3JzLgorICogUGFyc2VycyBjYW4gYmUgbWFkZSBuYW1lc3BhY2UgYXdhcmUgYnkgY2FsbGluZworICoge0BsaW5rIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnkjc2V0TmFtZXNwYWNlQXdhcmUoYm9vbGVhbiBhd2FyZW5lc3MpfS48L3A+CisgKgorICogQGF1dGhvciA8YSBocmVmPSJKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogNDQ2NTk4ICQsICREYXRlOiAyMDA2LTA5LTE1IDA1OjU1OjQwIC0wNzAwIChGcmksIDE1IFNlcCAyMDA2KSAkCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yIj5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPgorICovCitwdWJsaWMgY2xhc3MgRE9NU291cmNlIGltcGxlbWVudHMgU291cmNlIHsKKworICAgIC8qKgorICAgICAqIDxwPjxjb2RlPk5vZGU8L2NvZGU+IHRvIHNlcnZlIGFzIERPTSBzb3VyY2UuPC9wPgorICAgICAqLworICAgIHByaXZhdGUgTm9kZSBub2RlOworCisgICAgLyoqCisgICAgICogPHA+VGhlIGJhc2UgSUQgKFVSTCBvciBzeXN0ZW0gSUQpIGZyb20gd2hlcmUgVVJMcworICAgICAqIHdpbGwgYmUgcmVzb2x2ZWQuPC9wPgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHN5c3RlbUlEOworCisgICAgLyoqIElmIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSNnZXRGZWF0dXJlfQorICAgICAqIHJldHVybnMgdHJ1ZSB3aGVuIHBhc3NlZCB0aGlzIHZhbHVlIGFzIGFuIGFyZ3VtZW50LAorICAgICAqIHRoZSBUcmFuc2Zvcm1lciBzdXBwb3J0cyBTb3VyY2UgaW5wdXQgb2YgdGhpcyB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZFQVRVUkUgPQorICAgICAgICAiaHR0cDovL2phdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZS9mZWF0dXJlIjsKKworICAgIC8qKgorICAgICAqIDxwPlplcm8tYXJndW1lbnQgZGVmYXVsdCBjb25zdHJ1Y3Rvci4gIElmIHRoaXMgY29uc3RydWN0b3IgaXMgdXNlZCwgYW5kCisgICAgICogbm8gRE9NIHNvdXJjZSBpcyBzZXQgdXNpbmcge0BsaW5rICNzZXROb2RlKE5vZGUgbm9kZSl9ICwgdGhlbiB0aGUKKyAgICAgKiA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gd2lsbAorICAgICAqIGNyZWF0ZSBhbiBlbXB0eSBzb3VyY2Uge0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50fSB1c2luZworICAgICAqIHtAbGluayBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXIjbmV3RG9jdW1lbnQoKX0uPC9wPgorICAgICAqCisgICAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyI3RyYW5zZm9ybShTb3VyY2UgeG1sU291cmNlLCBSZXN1bHQgb3V0cHV0VGFyZ2V0KQorICAgICAqLworICAgIHB1YmxpYyBET01Tb3VyY2UoKSB7IH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBpbnB1dCBzb3VyY2Ugd2l0aCBhIERPTSBub2RlLiAgVGhlIG9wZXJhdGlvbgorICAgICAqIHdpbGwgYmUgYXBwbGllZCB0byB0aGUgc3VidHJlZSByb290ZWQgYXQgdGhpcyBub2RlLiAgSW4gWFNMVCwKKyAgICAgKiBhICIvIiBwYXR0ZXJuIHN0aWxsIG1lYW5zIHRoZSByb290IG9mIHRoZSB0cmVlIChub3QgdGhlIHN1YnRyZWUpLAorICAgICAqIGFuZCB0aGUgZXZhbHVhdGlvbiBvZiBnbG9iYWwgdmFyaWFibGVzIGFuZCBwYXJhbWV0ZXJzIGlzIGRvbmUKKyAgICAgKiBmcm9tIHRoZSByb290IG5vZGUgYWxzby4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuIFRoZSBET00gbm9kZSB0aGF0IHdpbGwgY29udGFpbiB0aGUgU291cmNlIHRyZWUuCisgICAgICovCisgICAgcHVibGljIERPTVNvdXJjZShOb2RlIG4pIHsKKyAgICAgICAgc2V0Tm9kZShuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgaW5wdXQgc291cmNlIHdpdGggYSBET00gbm9kZSwgYW5kIHdpdGggdGhlCisgICAgICogc3lzdGVtIElEIGFsc28gcGFzc2VkIGluIGFzIHRoZSBiYXNlIFVSSS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBub2RlIFRoZSBET00gbm9kZSB0aGF0IHdpbGwgY29udGFpbiB0aGUgU291cmNlIHRyZWUuCisgICAgICogQHBhcmFtIHN5c3RlbUlEIFNwZWNpZmllcyB0aGUgYmFzZSBVUkkgYXNzb2NpYXRlZCB3aXRoIG5vZGUuCisgICAgICovCisgICAgcHVibGljIERPTVNvdXJjZShOb2RlIG5vZGUsIFN0cmluZyBzeXN0ZW1JRCkgeworICAgICAgICBzZXROb2RlKG5vZGUpOworICAgICAgICBzZXRTeXN0ZW1JZChzeXN0ZW1JRCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBub2RlIHRoYXQgd2lsbCByZXByZXNlbnRzIGEgU291cmNlIERPTSB0cmVlLgorICAgICAqCisgICAgICogQHBhcmFtIG5vZGUgVGhlIG5vZGUgdGhhdCBpcyB0byBiZSB0cmFuc2Zvcm1lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROb2RlKE5vZGUgbm9kZSkgeworICAgICAgICB0aGlzLm5vZGUgPSBub2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBTb3VyY2UgRE9NIHRyZWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBub2RlIHRoYXQgaXMgdG8gYmUgdHJhbnNmb3JtZWQuCisgICAgICovCisgICAgcHVibGljIE5vZGUgZ2V0Tm9kZSgpIHsKKyAgICAgICAgcmV0dXJuIG5vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBiYXNlIElEIChVUkwgb3Igc3lzdGVtIElEKSBmcm9tIHdoZXJlIFVSTHMKKyAgICAgKiB3aWxsIGJlIHJlc29sdmVkLgorICAgICAqCisgICAgICogQHBhcmFtIHN5c3RlbUlEIEJhc2UgVVJMIGZvciB0aGlzIERPTSB0cmVlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JRCkgeworICAgICAgICB0aGlzLnN5c3RlbUlEID0gc3lzdGVtSUQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBiYXNlIElEIChVUkwgb3Igc3lzdGVtIElEKSBmcm9tIHdoZXJlIFVSTHMKKyAgICAgKiB3aWxsIGJlIHJlc29sdmVkLgorICAgICAqCisgICAgICogQHJldHVybiBCYXNlIFVSTCBmb3IgdGhpcyBET00gdHJlZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkgeworICAgICAgICByZXR1cm4gdGhpcy5zeXN0ZW1JRDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9kb20vcGFja2FnZS5odG1sIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vZG9tL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNjdlNzcxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vZG9tL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDM2IEBACis8IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wIFRyYW5zaXRpb25hbC8vRU4iPgorPGh0bWw+Cis8aGVhZD4KKzxNRVRBIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04Ij4KKzx0aXRsZT5qYXZheC54bWwudHJhbnNmb3JtLmRvbTwvdGl0bGU+Cis8L2hlYWQ+Cis8Ym9keT4KKzxwPlRoaXMgcGFja2FnZSBpbXBsZW1lbnRzIERPTS1zcGVjaWZpYyB0cmFuc2Zvcm1hdGlvbiBBUElzLjwvcD4KKzxwPlRoZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NU291cmNlfSBjbGFzcyBhbGxvd3MgdGhlCitjbGllbnQgb2YgdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgQVBJIHRvIHNwZWNpZnkgYSBET00KK3tAbGluayBvcmcudzNjLmRvbS5Ob2RlfSBhcyB0aGUgc291cmNlIG9mIHRoZSBpbnB1dCB0cmVlLiBUaGUgbW9kZWwgb2YKK2hvdyB0aGUgVHJhbnNmb3JtZXIgZGVhbHMgd2l0aCB0aGUgRE9NIHRyZWUgaW4gdGVybXMgb2YgbWlzbWF0Y2hlcyB3aXRoIHRoZQorPEEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkYXRhLW1vZGVsIj5YU0xUIGRhdGEgbW9kZWw8L0E+IG9yCitvdGhlciBkYXRhIG1vZGVscyBpcyBiZXlvbmQgdGhlIHNjb3BlIG9mIHRoaXMgZG9jdW1lbnQuIEFueSBvZiB0aGUgbm9kZXMKK2Rlcml2ZWQgZnJvbSB7QGxpbmsgb3JnLnczYy5kb20uTm9kZX0gYXJlIGxlZ2FsIGlucHV0LjwvcD4KKzxwPlRoZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NUmVzdWx0fSBjbGFzcyBhbGxvd3MKK2Ege0BsaW5rIG9yZy53M2MuZG9tLk5vZGV9IHRvIGJlIHNwZWNpZmllZCB0byB3aGljaCByZXN1bHQgRE9NIG5vZGVzIHdpbGwKK2JlIGFwcGVuZGVkLiBJZiBhbiBvdXRwdXQgbm9kZSBpcyBub3Qgc3BlY2lmaWVkLCB0aGUgdHJhbnNmb3JtZXIgd2lsbCB1c2UKK3tAbGluayBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXIjbmV3RG9jdW1lbnR9IHRvIGNyZWF0ZSBhbgorb3V0cHV0IHtAbGluayBvcmcudzNjLmRvbS5Eb2N1bWVudH0gbm9kZS4gSWYgYSBub2RlIGlzIHNwZWNpZmllZCwgaXQKK3Nob3VsZCBiZSBvbmUgb2YgdGhlIGZvbGxvd2luZzoge0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50fSwKK3tAbGluayBvcmcudzNjLmRvbS5FbGVtZW50fSwgb3IKK3tAbGluayBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50fS4gU3BlY2lmaWNhdGlvbiBvZiBhbnkgb3RoZXIgbm9kZQordHlwZSBpcyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQgYW5kIHVuZGVmaW5lZCBieSB0aGlzIEFQSS4gSWYgdGhlIHJlc3VsdCBpcyBhCit7QGxpbmsgb3JnLnczYy5kb20uRG9jdW1lbnR9LCB0aGUgb3V0cHV0IG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiBtdXN0IGhhdmUKK2Egc2luZ2xlIGVsZW1lbnQgcm9vdCB0byBzZXQgYXMgdGhlIGRvY3VtZW50IGVsZW1lbnQuPC9wPgorPHA+VGhlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01Mb2NhdG9yfSBub2RlIG1heSBiZSBwYXNzZWQKK3RvIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9ufSBvYmplY3RzLCBhbmQKK3JldHJpZXZlZCBieSB0cnlpbmcgdG8gY2FzdCB0aGUgcmVzdWx0IG9mIHRoZQore0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24jZ2V0TG9jYXRvcigpfSBtZXRob2QuCitUaGUgaW1wbGVtZW50YXRpb24gaGFzIG5vIHJlc3BvbnNpYmlsaXR5IHRvIHVzZSBhIERPTUxvY2F0b3IgaW5zdGVhZCBvZiBhCit7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yfSAodGhvdWdoIGxpbmUgbnVtYmVycyBhbmQgdGhlCitsaWtlIGRvIG5vdCBtYWtlIG11Y2ggc2Vuc2UgZm9yIGEgRE9NKSwgc28gdGhlIHJlc3VsdCBvZiBnZXRMb2NhdG9yIG11c3QgYWx3YXlzCitiZSB0ZXN0ZWQgd2l0aCBhbiBpbnN0YW5jZW9mLiA8L3A+Cis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9vdmVydmlldy5odG1sIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vb3ZlcnZpZXcuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MThkYjliCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vb3ZlcnZpZXcuaHRtbApAQCAtMCwwICsxLDI1NyBAQAorPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KKzxodG1sPgorPGhlYWQ+Cis8TUVUQSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD1VVEYtOCI+Cis8dGl0bGU+PC90aXRsZT4KKzwvaGVhZD4KKzxib2R5PiAKKyAgCis8aDI+VHJhbnNmb3JtYXRpb24gQVBJIEZvciBYTUwgPC9oMj4gCisgIAorICAKKzxoMz5JbnRyb2R1Y3Rpb248L2gzPiAKKyAgCis8cD5UaGlzIG92ZXJ2aWV3IGRlc2NyaWJlcyB0aGUgc2V0IG9mIEFQSXMgY29udGFpbmVkIGluCisJIGphdmF4LnhtbC50cmFuc2Zvcm0uIEZvciB0aGUgc2FrZSBvZiBicmV2aXR5LCB0aGVzZSBpbnRlcmZhY2VzIGFyZSByZWZlcnJlZCB0bworCSBhcyBUckFYIChUcmFuc2Zvcm1hdGlvbnMgZm9yIFhNTCkuIDwvcD4gCisgIAorPHA+VGhlcmUgaXMgYSBicm9hZCBuZWVkIGZvciBKYXZhIGFwcGxpY2F0aW9ucyB0byBiZSBhYmxlIHRvIHRyYW5zZm9ybSBYTUwKKwkgYW5kIHJlbGF0ZWQgdHJlZS1zaGFwZWQgZGF0YSBzdHJ1Y3R1cmVzLiBJbiBmYWN0LCBYTUwgaXMgbm90IG5vcm1hbGx5IHZlcnkKKwkgdXNlZnVsIHRvIGFuIGFwcGxpY2F0aW9uIHdpdGhvdXQgZ29pbmcgdGhyb3VnaCBzb21lIHNvcnQgb2YgdHJhbnNmb3JtYXRpb24sCisJIHVubGVzcyB0aGUgc2VtYW50aWMgc3RydWN0dXJlIGlzIHVzZWQgZGlyZWN0bHkgYXMgZGF0YS4gQWxtb3N0IGFsbCBYTUwtcmVsYXRlZAorCSBhcHBsaWNhdGlvbnMgbmVlZCB0byBwZXJmb3JtIHRyYW5zZm9ybWF0aW9ucy4gVHJhbnNmb3JtYXRpb25zIG1heSBiZSBkZXNjcmliZWQKKwkgYnkgSmF2YSBjb2RlLCBQZXJsIGNvZGUsIDxBIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQiPlhTTFQ8L0E+CisJIFN0eWxlc2hlZXRzLCBvdGhlciB0eXBlcyBvZiBzY3JpcHQsIG9yIGJ5IHByb3ByaWV0YXJ5IGZvcm1hdHMuIFRoZSBpbnB1dHMsIG9uZQorCSBvciBtdWx0aXBsZSwgdG8gYSB0cmFuc2Zvcm1hdGlvbiwgbWF5IGJlIGEgVVJMLCBYTUwgc3RyZWFtLCBhIERPTSB0cmVlLCBTQVgKKwkgRXZlbnRzLCBvciBhIHByb3ByaWV0YXJ5IGZvcm1hdCBvciBkYXRhIHN0cnVjdHVyZS4gVGhlIG91dHB1dCB0eXBlcyBhcmUgdGhlCisJIHByZXR0eSBtdWNoIHRoZSBzYW1lIHR5cGVzIGFzIHRoZSBpbnB1dHMsIGJ1dCBkaWZmZXJlbnQgaW5wdXRzIG1heSBuZWVkIHRvIGJlCisJIGNvbWJpbmVkIHdpdGggZGlmZmVyZW50IG91dHB1dHMuPC9wPiAKKyAgCis8cD5UaGUgZ3JlYXQgY2hhbGxlbmdlIG9mIGEgdHJhbnNmb3JtYXRpb24gQVBJIGlzIGhvdyB0byBkZWFsIHdpdGggYWxsIHRoZQorCSBwb3NzaWJsZSBjb21iaW5hdGlvbnMgb2YgaW5wdXRzIGFuZCBvdXRwdXRzLCB3aXRob3V0IGJlY29taW5nIHNwZWNpYWxpemVkIGZvcgorCSBhbnkgb2YgdGhlIGdpdmVuIHR5cGVzLjwvcD4gCisgIAorPHA+VGhlIEphdmEgY29tbXVuaXR5IHdpbGwgZ3JlYXRseSBiZW5lZml0IGZyb20gYSBjb21tb24gQVBJIHRoYXQgd2lsbAorCSBhbGxvdyB0aGVtIHRvIHVuZGVyc3RhbmQgYW5kIGFwcGx5IGEgc2luZ2xlIG1vZGVsLCB3cml0ZSB0byBjb25zaXN0ZW50CisJIGludGVyZmFjZXMsIGFuZCBhcHBseSB0aGUgdHJhbnNmb3JtYXRpb25zIHBvbHltb3JwaGljYWxseS4gVHJBWCBhdHRlbXB0cyB0bworCSBkZWZpbmUgYSBtb2RlbCB0aGF0IGlzIGNsZWFuIGFuZCBnZW5lcmljLCB5ZXQgZmlsbHMgZ2VuZXJhbCBhcHBsaWNhdGlvbgorCSByZXF1aXJlbWVudHMgYWNyb3NzIGEgd2lkZSB2YXJpZXR5IG9mIHVzZXMuIDwvcD4gCisgICAKKwkgCis8aDM+R2VuZXJhbCBUZXJtaW5vbG9neTwvaDM+IAorCSAKKzxwPlRoaXMgc2VjdGlvbiB3aWxsIGV4cGxhaW4gc29tZSBnZW5lcmFsIHRlcm1pbm9sb2d5IHVzZWQgaW4gdGhpcworCQlkb2N1bWVudC4gVGVjaG5pY2FsIHRlcm1pbm9sb2d5IHdpbGwgYmUgZXhwbGFpbmVkIGluIHRoZSBNb2RlbCBzZWN0aW9uLiBJbiBtYW55CisJCWNhc2VzLCB0aGUgZ2VuZXJhbCB0ZXJtaW5vbG9neSBvdmVybGFwcyB3aXRoIHRoZSB0ZWNobmljYWwgdGVybWlub2xvZ3kuPC9wPiAKKwkgCis8dWw+Cis8bGk+Cis8cD4KKzxiPlRyZWU8L2I+Cis8YnI+VGhpcyB0ZXJtLCBhcyB1c2VkIHdpdGhpbiB0aGlzIGRvY3VtZW50LCBkZXNjcmliZXMgYW4KKwkJCSBhYnN0cmFjdCBzdHJ1Y3R1cmUgdGhhdCBjb25zaXN0cyBvZiBub2RlcyBvciBldmVudHMgdGhhdCBtYXkgYmUgcHJvZHVjZWQgYnkKKwkJCSBYTUwuIEEgVHJlZSBwaHlzaWNhbGx5IG1heSBiZSBhIERPTSB0cmVlLCBhIHNlcmllcyBvZiB3ZWxsIGJhbGFuY2VkIHBhcnNlCisJCQkgZXZlbnRzIChzdWNoIGFzIHRob3NlIGNvbWluZyBmcm9tIGEgU0FYMiBDb250ZW50SGFuZGVyKSwgYSBzZXJpZXMgb2YgcmVxdWVzdHMKKwkJCSAodGhlIHJlc3VsdCBvZiB3aGljaCBjYW4gZGVzY3JpYmUgYSB0cmVlKSwgb3IgYSBzdHJlYW0gb2YgbWFya2VkLXVwCisJCQkgY2hhcmFjdGVycy48L3A+Cis8L2xpPgorPGxpPgorPHA+Cis8Yj5Tb3VyY2UgVHJlZShzKTwvYj4KKzxicj5PbmUgb3IgbW9yZSB0cmVlcyB0aGF0IGFyZSB0aGUgaW5wdXRzIHRvIHRoZQorCQkJIHRyYW5zZm9ybWF0aW9uLjwvcD4KKzwvbGk+Cis8bGk+Cis8cD4KKzxiPlJlc3VsdCBUcmVlKHMpPC9iPgorPGJyPk9uZSBvciBtb3JlIHRyZWVzIHRoYXQgYXJlIHRoZSBvdXRwdXQgb2YgdGhlCisJCQkgdHJhbnNmb3JtYXRpb24uPC9wPgorPC9saT4KKzxsaT4KKzxwPgorPGI+VHJhbnNmb3JtYXRpb248L2I+Cis8YnI+VGhlIHByb2Nlc3NvciBvZiBjb25zdW1pbmcgYSBzdHJlYW0gb3IgdHJlZSB0byBwcm9kdWNlCisJCQkgYW5vdGhlciBzdHJlYW0gb3IgdHJlZS48L3A+Cis8L2xpPgorPGxpPgorPHA+Cis8Yj5JZGVudGl0eSAob3IgQ29weSkgVHJhbnNmb3JtYXRpb248L2I+Cis8YnI+VGhlIHByb2Nlc3Mgb2YgdHJhbnNmb3JtYXRpb24gZnJvbSBhIHNvdXJjZSB0byBhIHJlc3VsdCwKKwkJCSBtYWtpbmcgYXMgZmV3IHN0cnVjdHVyYWwgY2hhbmdlcyBhcyBwb3NzaWJsZSBhbmQgbm8gaW5mb3JtYXRpb25hbCBjaGFuZ2VzLiBUaGUKKwkJCSB0ZXJtIGlzIHNvbWV3aGF0IGxvb3NlbHkgdXNlZCwgYXMgdGhlIHByb2Nlc3MgaXMgcmVhbGx5IGEgY29weS4gZnJvbSBvbmUKKwkJCSAiZm9ybWF0IiAoc3VjaCBhcyBhIERPTSB0cmVlLCBzdHJlYW0sIG9yIHNldCBvZiBTQVggZXZlbnRzKSB0bworCQkJIGFub3RoZXIuPC9wPgorPC9saT4KKzxsaT4KKzxwPgorPGI+U2VyaWFsaXphdGlvbjwvYj4KKzxicj5UaGUgcHJvY2VzcyBvZiB0YWtpbmcgYSB0cmVlIGFuZCB0dXJuaW5nIGl0IGludG8gYSBzdHJlYW0uIEluCisJCQkgc29tZSBzZW5zZSwgYSBzZXJpYWxpemF0aW9uIGlzIGEgc3BlY2lhbGl6ZWQgdHJhbnNmb3JtYXRpb24uPC9wPgorPC9saT4KKzxsaT4KKzxwPgorPGI+UGFyc2luZzwvYj4KKzxicj5UaGUgcHJvY2VzcyBvZiB0YWtpbmcgYSBzdHJlYW0gYW5kIHR1cm5pbmcgaXQgaW50byBhIHRyZWUuIEluCisJCQkgc29tZSBzZW5zZSwgcGFyc2luZyBpcyBhIHNwZWNpYWxpemVkIHRyYW5zZm9ybWF0aW9uLjwvcD4KKzwvbGk+Cis8bGk+Cis8cD4KKzxiPlRyYW5zZm9ybWVyPC9iPgorPGJyPkEgVHJhbnNmb3JtZXIgaXMgdGhlIG9iamVjdCB0aGF0IGV4ZWN1dGVzIHRoZSB0cmFuc2Zvcm1hdGlvbi4KKwkJCSA8L3A+Cis8L2xpPgorPGxpPgorPHA+Cis8Yj5UcmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnM8L2I+Cis8YnI+RGVzY3JpYmVzIHRoZSB0cmFuc2Zvcm1hdGlvbi4gQSBmb3JtIG9mIGNvZGUsIHNjcmlwdCwgb3IKKwkJCSBzaW1wbHkgYSBkZWNsYXJhdGlvbiBvciBzZXJpZXMgb2YgZGVjbGFyYXRpb25zLjwvcD4KKzwvbGk+Cis8bGk+Cis8cD4KKzxiPlN0eWxlc2hlZXQ8L2I+Cis8YnI+VGhlIHNhbWUgYXMgInRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucywiIGV4Y2VwdCBpdCBpcworCQkJIGxpa2VseSB0byBiZSB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggPEEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCI+WFNMVDwvQT4uPC9wPgorPC9saT4KKzxsaT4KKzxwPgorPGI+VGVtcGxhdGVzPC9iPgorPGJyPkFub3RoZXIgZm9ybSBvZiAidHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLiIgSW4gdGhlIFRyQVgKKwkJCSBpbnRlcmZhY2UsIHRoaXMgdGVybSBpcyB1c2VkIHRvIGRlc2NyaWJlIHByb2Nlc3NlZCBvciBjb21waWxlZCB0cmFuc2Zvcm1hdGlvbgorCQkJIGluc3RydWN0aW9ucy4gVGhlIFNvdXJjZSBmbG93cyB0aHJvdWdoIGEgVGVtcGxhdGVzIG9iamVjdCB0byBiZSBmb3JtZWQgaW50byB0aGUKKwkJCSBSZXN1bHQuPC9wPgorPC9saT4KKzxsaT4KKzxwPgorPGI+UHJvY2Vzc29yPC9iPgorPGJyPkEgZ2VuZXJhbCB0ZXJtIGZvciB0aGUgdGhpbmcgdGhhdCBtYXkgYm90aCBwcm9jZXNzIHRoZQorCQkJIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucywgYW5kIHBlcmZvcm0gdGhlIHRyYW5zZm9ybWF0aW9uLjwvcD4KKzwvbGk+Cis8bGk+Cis8cD4KKzxiPkRPTTwvYj4KKzxicj5Eb2N1bWVudCBPYmplY3QgTW9kZWwsIHNwZWNpZmljYWxseSByZWZlcnJpbmcgdG8gdGhlCisJCQkgPEEgaHJlZj0iI2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yJTIwIj5Eb2N1bWVudCBPYmplY3QgTW9kZWwKKwkJCSAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L0E+LjwvcD4KKzwvbGk+Cis8bGk+CisJPHA+CisJCTxiPlNBWDwvYj48YnI+CisJCVNpbXBsZSBBUEkgZm9yIFhNTCwgc3BlY2lmaWNhbGx5IHJlZmVycmluZyB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3NheC5zb3VyY2Vmb3JnZS5uZXQvIj5TQVggMi4wLjIgcmVsZWFzZTwvYT4uCisJPC9wPgorPC9saT4KKzwvdWw+IAorICAgCisgIAorICAKKzxoMz5Nb2RlbDwvaDM+IAorICAKKzxwPlRoZSBzZWN0aW9uIGRlZmluZXMgdGhlIGFic3RyYWN0IG1vZGVsIGZvciBUckFYLCBhcGFydCBmcm9tIHRoZSBkZXRhaWxzCisJIG9mIHRoZSBpbnRlcmZhY2VzLjwvcD4gCisgIAorPHA+QSBUUmFYIDxBIGhyZWY9IiNwYXR0ZXJuLVRyYW5zZm9ybWVyRmFjdG9yeSI+VHJhbnNmb3JtZXJGYWN0b3J5PC9BPiBpcyBhbiBvYmplY3QKKwkgdGhhdCBwcm9jZXNzZXMgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLCBhbmQgcHJvZHVjZXMKKwkgPEEgaHJlZj0iI3BhdHRlcm4tVGVtcGxhdGVzIj5UZW1wbGF0ZXM8L0E+IChpbiB0aGUgdGVjaG5pY2FsCisJIHRlcm1pbm9sb2d5KS4gQSA8QSBocmVmPSIjcGF0dGVybi1UZW1wbGF0ZXMiPlRlbXBsYXRlczwvQT4KKwkgb2JqZWN0IHByb3ZpZGVzIGEgPEEgaHJlZj0iI3BhdHRlcm4tVHJhbnNmb3JtZXIiPlRyYW5zZm9ybWVyPC9BPiwgd2hpY2ggdHJhbnNmb3JtcyBvbmUgb3IKKwkgbW9yZSA8QSBocmVmPSIjcGF0dGVybi1Tb3VyY2UiPlNvdXJjZTwvQT5zIGludG8gb25lIG9yIG1vcmUKKwkgPEEgaHJlZj0iI3BhdHRlcm4tUmVzdWx0Ij5SZXN1bHQ8L0E+cy48L3A+IAorICAKKzxwPlRvIHVzZSB0aGUgVFJhWCBpbnRlcmZhY2UsIHlvdSBjcmVhdGUgYQorCSA8QSBocmVmPSIjcGF0dGVybi1UcmFuc2Zvcm1lckZhY3RvcnkiPlRyYW5zZm9ybWVyRmFjdG9yeTwvQT4sCisJIHdoaWNoIG1heSBkaXJlY3RseSBwcm92aWRlIGEgPEEgaHJlZj0iI3BhdHRlcm4tVHJhbnNmb3JtZXJzIj5UcmFuc2Zvcm1lcnM8L0E+LCBvciB3aGljaCBjYW4gcHJvdmlkZQorCSA8QSBocmVmPSIjcGF0dGVybi1UZW1wbGF0ZXMiPlRlbXBsYXRlczwvQT4gZnJvbSBhIHZhcmlldHkgb2YKKwkgPEEgaHJlZj0iI3BhdHRlcm4tU291cmNlIj5Tb3VyY2U8L0E+cy4gVGhlCisJIDxBIGhyZWY9IiNwYXR0ZXJuLVRlbXBsYXRlcyI+VGVtcGxhdGVzPC9BPiBvYmplY3QgaXMgYSBwcm9jZXNzZWQKKwkgb3IgY29tcGlsZWQgcmVwcmVzZW50YXRpb24gb2YgdGhlIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucywgYW5kIHByb3ZpZGVzIGEKKwkgPEEgaHJlZj0iI3BhdHRlcm4tVHJhbnNmb3JtZXIiPlRyYW5zZm9ybWVyPC9BPi4gVGhlCisJIDxBIGhyZWY9IiNwYXR0ZXJuLVRyYW5zZm9ybWVyIj5UcmFuc2Zvcm1lcjwvQT4gcHJvY2Vzc2VzIGEKKwkgPEEgaHJlZj0iI3BhdHRlcm4tVHJhbnNmb3JtZXIiPlNvdXJjZTwvQT4gYWNjb3JkaW5nIHRvIHRoZQorCSBpbnN0cnVjdGlvbnMgZm91bmQgaW4gdGhlIDxBIGhyZWY9IiNwYXR0ZXJuLVRlbXBsYXRlcyI+VGVtcGxhdGVzPC9BPiwgYW5kIHByb2R1Y2VzIGEKKwkgPEEgaHJlZj0iI3BhdHRlcm4tUmVzdWx0Ij5SZXN1bHQ8L0E+LjwvcD4gCisgIAorPHA+VGhlIHByb2Nlc3Mgb2YgdHJhbnNmb3JtYXRpb24gZnJvbSBhIHRyZWUsIGVpdGhlciBpbiB0aGUgZm9ybSBvZiBhbgorCSBvYmplY3QgbW9kZWwsIG9yIGluIHRoZSBmb3JtIG9mIHBhcnNlIGV2ZW50cywgaW50byBhIHN0cmVhbSwgaXMga25vd24gYXMKKwkgPGNvZGU+c2VyaWFsaXphdGlvbjwvY29kZT4uIFdlIGJlbGlldmUgdGhpcyBpcyB0aGUgbW9zdCBzdWl0YWJsZSB0ZXJtIGZvcgorCSB0aGlzIHByb2Nlc3MsIGRlc3BpdGUgdGhlIG92ZXJsYXAgd2l0aCBKYXZhIG9iamVjdCBzZXJpYWxpemF0aW9uLjwvcD4KKyAgCis8SDM+VFJhWCBQYXR0ZXJuczwvSDM+Cis8dWw+Cis8cD4KKzxiPjxhIG5hbWU9InBhdHRlcm4tUHJvY2Vzc29yIj5Qcm9jZXNzb3I8L2E+PC9iPgorPGJyPgorPGJyPgorPGk+SW50ZW50OiA8L2k+R2VuZXJpYyBjb25jZXB0IGZvciB0aGUKKyAgc2V0IG9mIG9iamVjdHMgdGhhdCBpbXBsZW1lbnQgdGhlIFRyQVggaW50ZXJmYWNlcy48YnI+Cis8aT5SZXNwb25zaWJpbGl0aWVzOiA8L2k+Q3JlYXRlIGNvbXBpbGVkIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucywgdHJhbnNmb3JtCisgIHNvdXJjZXMsIGFuZCBtYW5hZ2UgdHJhbnNmb3JtYXRpb24gcGFyYW1ldGVycyBhbmQKKyAgcHJvcGVydGllcy48YnI+Cis8aT5UaHJlYWQgc2FmZXR5OiA8L2k+T25seSB0aGUgVGVtcGxhdGVzIG9iamVjdCBjYW4gYmUKKyAgdXNlZCBjb25jdXJyZW50bHkgaW4gbXVsdGlwbGUgdGhyZWFkcy4gVGhlIHJlc3Qgb2YgdGhlIHByb2Nlc3NvciBkb2VzIG5vdCBkbworICBzeW5jaHJvbml6ZWQgYmxvY2tpbmcsIGFuZCBzbyBtYXkgbm90IGJlIHVzZWQgdG8gcGVyZm9ybSBtdWx0aXBsZSBjb25jdXJyZW50CisgIG9wZXJhdGlvbnMuIERpZmZlcmVudCBQcm9jZXNzb3JzIGNhbiBiZSB1c2VkIGNvbmN1cnJlbnRseSBieSBkaWZmZXJlbnQKKyAgdGhyZWFkcy48L3A+Cis8cD4KKzxiPjxhIG5hbWU9InBhdHRlcm4tVHJhbnNmb3JtZXJGYWN0b3J5Ij5UcmFuc2Zvcm1lckZhY3Rvcnk8L2E+PC9iPgorPGJyPgorPGJyPgorPGk+SW50ZW50OiA8L2k+U2VydmUgYXMgYSB2ZW5kb3ItbmV1dHJhbCBQcm9jZXNzb3IgaW50ZXJmYWNlIGZvcgorICA8QSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0Ij5YU0xUPC9BPiBhbmQgc2ltaWxhcgorICBwcm9jZXNzb3JzLjxicj4KKzxpPlJlc3BvbnNpYmlsaXRpZXM6IDwvaT5TZXJ2ZSBhcyBhIGZhY3RvcnkgZm9yIGEgY29uY3JldGUKKyAgaW1wbGVtZW50YXRpb24gb2YgYW4gVHJhbnNmb3JtZXJGYWN0b3J5LCBzZXJ2ZSBhcyBhIGRpcmVjdCBmYWN0b3J5IGZvcgorICBUcmFuc2Zvcm1lciBvYmplY3RzLCBzZXJ2ZSBhcyBhIGZhY3RvcnkgZm9yIFRlbXBsYXRlcyBvYmplY3RzLCBhbmQgbWFuYWdlCisgIHByb2Nlc3NvciBzcGVjaWZpYyBmZWF0dXJlcy48YnI+Cis8aT5UaHJlYWQgc2FmZXR5OiA8L2k+QQorICBUcmFuc2Zvcm1lckZhY3RvcnkgbWF5IG5vdCBwZXJmb3JtIG11bHRpcGxlIGNvbmN1cnJlbnQKKyAgb3BlcmF0aW9ucy48L3A+Cis8cD4KKzxiPjxhIG5hbWU9InBhdHRlcm4tVGVtcGxhdGVzIj5UZW1wbGF0ZXM8L2E+PC9iPgorPGJyPgorPGJyPgorPGk+SW50ZW50OiA8L2k+VGhlCisgIHJ1bnRpbWUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucy48YnI+Cis8aT5SZXNwb25zaWJpbGl0aWVzOiA8L2k+QSBkYXRhIGJhZyBmb3IgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zOyBhY3QgYXMgYSBmYWN0b3J5CisgIGZvciBUcmFuc2Zvcm1lcnMuPGJyPgorPGk+VGhyZWFkIHNhZmV0eTogPC9pPlRocmVhZC1zYWZlIGZvciBjb25jdXJyZW50CisgIHVzYWdlIG92ZXIgbXVsdGlwbGUgdGhyZWFkcyBvbmNlIGNvbnN0cnVjdGlvbiBpcyBjb21wbGV0ZS48L3A+Cis8cD4KKzxiPjxhIG5hbWU9InBhdHRlcm4tVHJhbnNmb3JtZXIiPlRyYW5zZm9ybWVyPC9hPjwvYj4KKzxicj4KKzxicj4KKzxpPkludGVudDogPC9pPkFjdCBhcyBhIHBlci10aHJlYWQKKyAgZXhlY3V0aW9uIGNvbnRleHQgZm9yIHRyYW5zZm9ybWF0aW9ucywgYWN0IGFzIGFuIGludGVyZmFjZSBmb3IgcGVyZm9ybWluZyB0aGUKKyAgdHJhbnNmb3JtYXRpb24uPGJyPgorPGk+UmVzcG9uc2liaWxpdGllczogPC9pPlBlcmZvcm0gdGhlCisgIHRyYW5zZm9ybWF0aW9uLjxicj4KKzxpPlRocmVhZCBzYWZldHk6IDwvaT5Pbmx5IG9uZSBpbnN0YW5jZSBwZXIgdGhyZWFkCisgIGlzIHNhZmUuPGJyPgorPGk+Tm90ZXM6IDwvaT5UaGUgVHJhbnNmb3JtZXIgaXMgYm91bmQgdG8gdGhlIFRlbXBsYXRlcworICBvYmplY3QgdGhhdCBjcmVhdGVkIGl0LjwvcD4KKzxwPgorPGI+PGEgbmFtZT0icGF0dGVybi1Tb3VyY2UiPlNvdXJjZTwvYT48L2I+Cis8YnI+Cis8YnI+Cis8aT5JbnRlbnQ6IDwvaT5TZXJ2ZSBhcyBhCisgIHNpbmdsZSB2ZW5kb3ItbmV1dHJhbCBvYmplY3QgZm9yIG11bHRpcGxlIHR5cGVzIG9mIGlucHV0Ljxicj4KKzxpPlJlc3BvbnNpYmlsaXRpZXM6IDwvaT5BY3QgYXMgc2ltcGxlIGRhdGEgaG9sZGVyIGZvciBTeXN0ZW0gSURzLCBET00gbm9kZXMsIHN0cmVhbXMsCisgIGV0Yy48YnI+Cis8aT5UaHJlYWQgc2FmZXR5OiA8L2k+VGhyZWFkLXNhZmUgY29uY3VycmVudGx5IG92ZXIgbXVsdGlwbGUKKyAgdGhyZWFkcyBmb3IgcmVhZC1vbmx5IG9wZXJhdGlvbnM7IG11c3QgYmUgc3luY2hyb25pemVkIGZvciBlZGl0CisgIG9wZXJhdGlvbnMuPC9wPgorPHA+Cis8Yj48YSBuYW1lPSJwYXR0ZXJuLVJlc3VsdCI+UmVzdWx0PC9hPjwvYj4KKzxicj4KKzxicj4KKzxpPlBvdGVudGlhbCBhbHRlcm5hdGUgbmFtZTogPC9pPlJlc3VsdFRhcmdldDxicj4KKzxpPkludGVudDogPC9pPlNlcnZlCisgIGFzIGEgc2luZ2xlIG9iamVjdCBmb3IgbXVsdGlwbGUgdHlwZXMgb2Ygb3V0cHV0LCBzbyB0aGVyZSBjYW4gYmUgc2ltcGxlIHByb2Nlc3MKKyAgbWV0aG9kIHNpZ25hdHVyZXMuPGJyPgorPGk+UmVzcG9uc2liaWxpdGllczogPC9pPkFjdCBhcyBzaW1wbGUgZGF0YSBob2xkZXIgZm9yCisgIG91dHB1dCBzdHJlYW0sIERPTSBub2RlLCBDb250ZW50SGFuZGxlciwgZXRjLjxicj4KKzxpPlRocmVhZCBzYWZldHk6IDwvaT5UaHJlYWQtc2FmZSBjb25jdXJyZW50bHkgb3ZlciBtdWx0aXBsZSB0aHJlYWRzIGZvciByZWFkLW9ubHksCisgIG11c3QgYmUgc3luY2hyb25pemVkIGZvciBlZGl0LjwvcD4KKzwvdWw+IAorICAKKworPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vcGFja2FnZS5odG1sIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNhMDhjN2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwyMDEgQEAKKzw/eG1sIHZlcnNpb249IjEuMCI/PgorPCEtLSAkSWQ6IHBhY2thZ2UuaHRtbCAyMjYxODMgMjAwNS0wNC0wOCAxMDozOToxNFogbmVlcmFqICQgLS0+CisKKzwhRE9DVFlQRSBodG1sIFBVQkxJQyAiLS8vVzNDLy9EVEQgWEhUTUwgMS4wIFN0cmljdC8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9UUi94aHRtbDEvRFREL3hodG1sMS1zdHJpY3QuZHRkIj4KKzxodG1sIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIj4KKzxoZWFkPgorPHRpdGxlPmphdmF4LnhtbC50cmFuc2Zvcm08L3RpdGxlPgorPC9oZWFkPgorCis8Ym9keT4KKzxwPlRoaXMgcGFja2FnZSBkZWZpbmVzIHRoZSBnZW5lcmljIEFQSXMgZm9yIHByb2Nlc3NpbmcgdHJhbnNmb3JtYXRpb24KK2luc3RydWN0aW9ucywgYW5kIHBlcmZvcm1pbmcgYSB0cmFuc2Zvcm1hdGlvbiBmcm9tIHNvdXJjZSB0byByZXN1bHQuIFRoZXNlCitpbnRlcmZhY2VzIGhhdmUgbm8gZGVwZW5kZW5jaWVzIG9uIFNBWCBvciB0aGUgRE9NIHN0YW5kYXJkLCBhbmQgdHJ5IHRvIG1ha2UgYXMKK2ZldyBhc3N1bXB0aW9ucyBhcyBwb3NzaWJsZSBhYm91dCB0aGUgZGV0YWlscyBvZiB0aGUgc291cmNlIGFuZCByZXN1bHQgb2YgYQordHJhbnNmb3JtYXRpb24uIEl0IGFjaGlldmVzIHRoaXMgYnkgZGVmaW5pbmcKK3tAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZX0gYW5kCit7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHR9IGludGVyZmFjZXMuCis8L3A+CisKKzxwPlRvIGRlZmluZSBjb25jcmV0ZSBjbGFzc2VzIGZvciB0aGUgdXNlciwgdGhlIEFQSSBkZWZpbmVzIHNwZWNpYWxpemF0aW9ucworb2YgdGhlIGludGVyZmFjZXMgZm91bmQgYXQgdGhlIHJvb3QgbGV2ZWwuIFRoZXNlIGludGVyZmFjZXMgYXJlIGZvdW5kIGluCit7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zYXh9LCB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5kb219LAorYW5kIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbX0uCis8L3A+CisKKworPGgzPkNyZWF0aW5nIE9iamVjdHM8L2gzPgorCis8cD5UaGUgQVBJIGFsbG93cyBhIGNvbmNyZXRlCit7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnl9IG9iamVjdCB0byBiZSBjcmVhdGVkIGZyb20KK3RoZSBzdGF0aWMgZnVuY3Rpb24KK3tAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSNuZXdJbnN0YW5jZX0uCis8L3A+CisKKworPGgzPlNwZWNpZmljYXRpb24gb2YgSW5wdXRzIGFuZCBPdXRwdXRzPC9oMz4KKworPHA+VGhpcyBBUEkgZGVmaW5lcyB0d28gaW50ZXJmYWNlIG9iamVjdHMgY2FsbGVkCit7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2V9IGFuZAore0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0fS4gSW4gb3JkZXIgdG8gcGFzcyBTb3VyY2UgYW5kIFJlc3VsdAorb2JqZWN0cyB0byB0aGUgaW50ZXJmYWNlcywgY29uY3JldGUgY2xhc3NlcyBtdXN0IGJlIHVzZWQuCitUaHJlZSBjb25jcmV0ZSByZXByZXNlbnRhdGlvbnMgYXJlIGRlZmluZWQgZm9yIGVhY2ggb2YgdGhlc2UKK29iamVjdHM6Cit7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlfSBhbmQKK3tAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHR9LAore0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZX0gYW5kCit7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYUmVzdWx0fSwgYW5kCit7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NU291cmNlfSBhbmQKK3tAbGluayBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01SZXN1bHR9LiBFYWNoIG9mIHRoZXNlIG9iamVjdHMgZGVmaW5lcworYSBGRUFUVVJFIHN0cmluZyAod2hpY2ggaXMgaSB0aGUgZm9ybSBvZiBhIFVSTCksIHdoaWNoIGNhbiBiZSBwYXNzZWQgaW50bwore0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I2dldEZlYXR1cmV9IHRvIHNlZSBpZiB0aGUKK2dpdmVuIHR5cGUgb2YgU291cmNlIG9yIFJlc3VsdCBvYmplY3QgaXMgc3VwcG9ydGVkLiBGb3IgaW5zdGFuY2UsIHRvIHRlc3QgaWYgYQorRE9NU291cmNlIGFuZCBhIFN0cmVhbVJlc3VsdCBpcyBzdXBwb3J0ZWQsIHlvdSBjYW4gYXBwbHkgdGhlIGZvbGxvd2luZwordGVzdC4KKzwvcD4KKworPHByZT4KKzxjb2RlPgorVHJhbnNmb3JtZXJGYWN0b3J5IHRmYWN0b3J5ID0gVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CitpZiAodGZhY3RvcnkuZ2V0RmVhdHVyZShET01Tb3VyY2UuRkVBVFVSRSkgJmFtcDsmYW1wOyB0ZmFjdG9yeS5nZXRGZWF0dXJlKFN0cmVhbVJlc3VsdC5GRUFUVVJFKSkgeworLi4uCit9Cis8L2NvZGU+Cis8L3ByZT4KKworCis8aDM+Cis8YSBuYW1lPSJxbmFtZS1kZWxpbWl0ZXIiPlF1YWxpZmllZCBOYW1lIFJlcHJlc2VudGF0aW9uPC9hPgorPC9oMz4KKworPHA+PGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcyI+TmFtZXNwYWNlczwvYT4KK3ByZXNlbnQgc29tZXRoaW5nIG9mIGEgcHJvYmxlbSBhcmVhIHdoZW4gZGVhbGluZyB3aXRoIFhNTCBvYmplY3RzLiBRdWFsaWZpZWQKK05hbWVzIGFwcGVhciBpbiBYTUwgbWFya3VwIGFzIHByZWZpeGVkIG5hbWVzLiBCdXQgdGhlIHByZWZpeGVzIHRoZW1zZWx2ZXMgZG8KK25vdCBob2xkIGlkZW50aXR5LiBSYXRoZXIsIGl0IGlzIHRoZSBVUklzIHRoYXQgdGhleSBjb250ZXh0dWFsbHkgbWFwIHRvIHRoYXQKK2hvbGQgdGhlIGlkZW50aXR5LiBUaGVyZWZvcmUsIHdoZW4gcGFzc2luZyBhIFF1YWxpZmllZCBOYW1lIGxpa2UgInh5ejpmb28iCithbW9uZyBKYXZhIHByb2dyYW1zLCBvbmUgbXVzdCBwcm92aWRlIGEgbWVhbnMgdG8gbWFwICJ4eXoiIHRvIGEgbmFtZXNwYWNlLgorPC9wPgorCis8cD5PbmUgc29sdXRpb24gaGFzIGJlZW4gdG8gY3JlYXRlIGEgIlFOYW1lIiBvYmplY3QgdGhhdCBob2xkcyB0aGUKK25hbWVzcGFjZSBVUkksIGFzIHdlbGwgYXMgdGhlIHByZWZpeCBhbmQgbG9jYWwgbmFtZSwgYnV0IHRoaXMgaXMgbm90IGFsd2F5cyBhbgorb3B0aW1hbCBzb2x1dGlvbiwgYXMgd2hlbiwgZm9yIGV4YW1wbGUsIHlvdSB3YW50IHRvIHVzZSB1bmlxdWUgc3RyaW5ncyBhcyBrZXlzCitpbiBhIGRpY3Rpb25hcnkgb2JqZWN0LiBOb3QgaGF2aW5nIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGFsc28gbWFrZXMgaXQKK2RpZmZpY3VsdCB0byBzcGVjaWZ5IGEgbmFtZXNwYWNlZCBpZGVudGl0eSBvdXRzaWRlIHRoZSBjb250ZXh0IG9mIGFuIFhNTAorZG9jdW1lbnQuCis8L3A+CisKKzxwPkluIG9yZGVyIHRvIHBhc3MgbmFtZXNwYWNlZCB2YWx1ZXMgdG8gdHJhbnNmb3JtYXRpb25zLAorZm9yIAoraW5zdGFuY2Ugd2hlbiBzZXR0aW5nIGEgcHJvcGVydHkgb3IgYSBwYXJhbWV0ZXIgb24gYSAKK3tAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyfSBvYmplY3QsCit0aGlzIHNwZWNpZmljYXRpb24gZGVmaW5lcyB0aGF0IGEKK1N0cmluZyAicW5hbWUiIG9iamVjdCBwYXJhbWV0ZXIgYmUgcGFzc2VkIGFzIHR3by1wYXJ0IHN0cmluZywgdGhlIG5hbWVzcGFjZSBVUkkKK2VuY2xvc2VkIGluIGN1cmx5IGJyYWNlcyAoe30pLCBmb2xsb3dlZCBieSB0aGUgbG9jYWwgbmFtZS4gSWYgdGhlIHFuYW1lIGhhcyBhCitudWxsIFVSSSwgdGhlbiB0aGUgU3RyaW5nIG9iamVjdCBvbmx5IGNvbnRhaW5zIHRoZSBsb2NhbCBuYW1lLiBBbiBhcHBsaWNhdGlvbgorY2FuIHNhZmVseSBjaGVjayBmb3IgYSBub24tbnVsbCBVUkkgYnkgdGVzdGluZyB0byBzZWUgaWYgdGhlIGZpcnN0IGNoYXJhY3RlciBvZgordGhlIG5hbWUgaXMgYSAneycgY2hhcmFjdGVyLgorPC9wPgorCis8cD5Gb3IgZXhhbXBsZSwgaWYgYSBVUkkgYW5kIGxvY2FsIG5hbWUgd2VyZSBvYnRhaW5lZCBmcm9tIGFuIGVsZW1lbnQKK2RlZmluZWQgd2l0aCAmbHQ7eHl6OmZvbyB4bWxuczp4eXo9Imh0dHA6Ly94eXouZm9vLmNvbS95YWRhL2Jhei5odG1sIi8mZ3Q7LAordGhlbiB0aGUgUXVhbGlmaWVkIE5hbWUgd291bGQgYmUgIntodHRwOi8veHl6LmZvby5jb20veWFkYS9iYXouaHRtbH1mb28iLgorTm90ZSB0aGF0IHRoZSBwcmVmaXggaXMgbG9zdC4KKzwvcD4KKworCis8aDM+UmVzdWx0IFRyZWUgU2VyaWFsaXphdGlvbjwvaDM+CisKKzxwPlNlcmlhbGl6YXRpb24gb2YgdGhlIHJlc3VsdCB0cmVlIHRvIGEgc3RyZWFtIGNhbiBiZSBjb250cm9sbGVkIHdpdGgKK3RoZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lciNzZXRPdXRwdXRQcm9wZXJ0aWVzfSBhbmQgdGhlCit7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lciNzZXRPdXRwdXRQcm9wZXJ0eX0gbWV0aG9kcy4KK1RoZXNlIHByb3BlcnRpZXMgb25seSBhcHBseSB0byBzdHJlYW0gcmVzdWx0cywgdGhleSBoYXZlIG5vIGVmZmVjdCB3aGVuCit0aGUgcmVzdWx0IGlzIGEgRE9NIHRyZWUgb3IgU0FYIGV2ZW50IHN0cmVhbS48L3A+CisKKzxwPlN0cmluZ3MgdGhhdCBtYXRjaCB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNvdXRwdXQiPlhTTFQKK3NwZWNpZmljYXRpb24gZm9yIHhzbDpvdXRwdXQgYXR0cmlidXRlczwvYT4gY2FuIGJlIHJlZmVyZW5jZWQgZnJvbSB0aGUKK3tAbGluayBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXN9IGNsYXNzLiBPdGhlciBzdHJpbmdzIGNhbiBiZQorc3BlY2lmaWVkIGFzIHdlbGwuCitJZiB0aGUgdHJhbnNmb3JtZXIgZG9lcyBub3QgcmVjb2duaXplIGFuIG91dHB1dCBrZXksIGEKK3tAbGluayBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufSBpcyB0aHJvd24sIHVubGVzcyB0aGUKK2tleSBuYW1lIGlzIDxhIGhyZWY9IiNxbmFtZS1kZWxpbWl0ZXIiPm5hbWVzcGFjZSBxdWFsaWZpZWQ8L2E+LiBPdXRwdXQga2V5IG5hbWVzCit0aGF0IGFyZSBuYW1lc3BhY2UgcXVhbGlmaWVkIGFyZSBhbHdheXMgYWxsb3dlZCwgYWx0aG91Z2ggdGhleSBtYXkgYmUKK2lnbm9yZWQgYnkgc29tZSBpbXBsZW1lbnRhdGlvbnMuPC9wPgorCis8cD5JZiBhbGwgdGhhdCBpcyBkZXNpcmVkIGlzIHRoZSBzaW1wbGUgaWRlbnRpdHkgdHJhbnNmb3JtYXRpb24gb2YgYQorc291cmNlIHRvIGEgcmVzdWx0LCB0aGVuIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeX0KK3Byb3ZpZGVzIGEKK3tAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSNuZXdUcmFuc2Zvcm1lcigpfSBtZXRob2QKK3dpdGggbm8gYXJndW1lbnRzLiBUaGlzIG1ldGhvZCBjcmVhdGVzIGEgVHJhbnNmb3JtZXIgdGhhdCBlZmZlY3RpdmVseSBjb3BpZXMKK3RoZSBzb3VyY2UgdG8gdGhlIHJlc3VsdC4gVGhpcyBtZXRob2QgbWF5IGJlIHVzZWQgdG8gY3JlYXRlIGEgRE9NIGZyb20gU0FYCitldmVudHMgb3IgdG8gY3JlYXRlIGFuIFhNTCBvciBIVE1MIHN0cmVhbSBmcm9tIGEgRE9NIG9yIFNBWCBldmVudHMuICA8L3A+CisKKzxoMz5FeGNlcHRpb25zIGFuZCBFcnJvciBSZXBvcnRpbmc8L2gzPgorCis8cD5UaGUgdHJhbnNmb3JtYXRpb24gQVBJIHRocm93IHRocmVlIHR5cGVzIG9mIHNwZWNpYWxpemVkIGV4Y2VwdGlvbnMuIEEKK3tAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcn0gaXMgcGFyYWxsZWwgdG8KK3RoZSB7QGxpbmsgamF2YXgueG1sLnBhcnNlcnMuRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcn0sIGFuZCBpcyB0aHJvd24KK3doZW4gYSBjb25maWd1cmF0aW9uIHByb2JsZW0gd2l0aCB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5IGV4aXN0cy4gVGhpcyBlcnJvcgord2lsbCB0eXBpY2FsbHkgYmUgdGhyb3duIHdoZW4gdGhlIHRyYW5zZm9ybWF0aW9uIGZhY3RvcnkgY2xhc3Mgc3BlY2lmaWVkIHdpdGgKK3RoZSAiamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkiIHN5c3RlbSBwcm9wZXJ0eSBjYW5ub3QgYmUgZm91bmQgb3IKK2luc3RhbnRpYXRlZC48L3A+CisKKzxwPkEge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9ufQorbWF5IGJlIHRocm93biBpZiBmb3IgYW55IHJlYXNvbiBhIFRyYW5zZm9ybWVyIGNhbiBub3QgYmUgY3JlYXRlZC4gQQorVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIG1heSBiZSB0aHJvd24gaWYgdGhlcmUgaXMgYSBzeW50YXggZXJyb3IgaW4KK3RoZSB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMsIGZvciBleGFtcGxlIHdoZW4KK3tAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSNuZXdUcmFuc2Zvcm1lcn0gaXMKK2NhbGxlZC48L3A+CisKKzxwPntAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9ufSBpcyBhIGdlbmVyYWwKK2V4Y2VwdGlvbiB0aGF0IG9jY3VycyBkdXJpbmcgdGhlIGNvdXJzZSBvZiBhIHRyYW5zZm9ybWF0aW9uLiBBIHRyYW5zZm9ybWVyCitleGNlcHRpb24gbWF5IHdyYXAgYW5vdGhlciBleGNlcHRpb24sIGFuZCBpZiBhbnkgb2YgdGhlCit7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiNwcmludFN0YWNrVHJhY2UoKX0KK21ldGhvZHMgYXJlIGNhbGxlZCBvbiBpdCwgaXQgd2lsbCBwcm9kdWNlIGEgbGlzdCBvZiBzdGFjayBkdW1wcywgc3RhcnRpbmcgZnJvbQordGhlIG1vc3QgcmVjZW50LiBUaGUgdHJhbnNmb3JtZXIgZXhjZXB0aW9uIGFsc28gcHJvdmlkZXMgYQore0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvcn0gb2JqZWN0IHdoaWNoIGluZGljYXRlcyB3aGVyZQoraW4gdGhlIHNvdXJjZSB0cmVlIG9yIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucyB0aGUgZXJyb3Igb2NjdXJyZWQuCit7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiNnZXRNZXNzYWdlQW5kTG9jYXRpb24oKX0KK21heSBiZSBjYWxsZWQgdG8gZ2V0IGFuIGVycm9yIG1lc3NhZ2Ugd2l0aCBsb2NhdGlvbiBpbmZvLCBhbmQKK3tAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uI2dldExvY2F0aW9uQXNTdHJpbmcoKX0KK21heSBiZSBjYWxsZWQgdG8gZ2V0IGp1c3QgdGhlIGxvY2F0aW9uIHN0cmluZy48L3A+CisKKzxwPlRyYW5zZm9ybWF0aW9uIHdhcm5pbmdzIGFuZCBlcnJvcnMgYXJlIHNlbnQgdG8gYW4KK3tAbGluayBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXJ9LCBhdCB3aGljaCBwb2ludCB0aGUKK2FwcGxpY2F0aW9uIG1heSBkZWNpZGUgdG8gcmVwb3J0IHRoZSBlcnJvciBvciB3YXJuaW5nLCBhbmQgbWF5IGRlY2lkZSB0byB0aHJvdworYW4gPGNvZGU+RXhjZXB0aW9uPC9jb2RlPiBmb3IgYSBub24tZmF0YWwgZXJyb3IuIFRoZSA8Y29kZT5FcnJvckxpc3RlbmVyPC9jb2RlPiBtYXkgYmUgc2V0IHZpYQore0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I3NldEVycm9yTGlzdGVuZXJ9IGZvcgorcmVwb3J0aW5nIGVycm9ycyB0aGF0IGhhdmUgdG8gZG8gd2l0aCBzeW50YXggZXJyb3JzIGluIHRoZSB0cmFuc2Zvcm1hdGlvbgoraW5zdHJ1Y3Rpb25zLCBvciB2aWEKK3tAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyI3NldEVycm9yTGlzdGVuZXJ9IHRvIHJlcG9ydAorZXJyb3JzIHRoYXQgb2NjdXIgZHVyaW5nIHRoZSB0cmFuc2Zvcm1hdGlvbi4gVGhlIDxjb2RlPkVycm9yTGlzdGVuZXI8L2NvZGU+IG9uIGJvdGggb2JqZWN0cword2lsbCBhbHdheXMgYmUgdmFsaWQgYW5kIG5vbi08Y29kZT5udWxsPC9jb2RlPiwgd2hldGhlciBzZXQgYnkgdGhlIGFwcGxpY2F0aW9uIG9yIGEgZGVmYXVsdAoraW1wbGVtZW50YXRpb24gcHJvdmlkZWQgYnkgdGhlIHByb2Nlc3Nvci4KK1RoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHByb3ZpZGVkIGJ5IHRoZSBwcm9jZXNzb3Igd2lsbCByZXBvcnQgYWxsIHdhcm5pbmdzIGFuZCBlcnJvcnMgdG8gPGNvZGU+U3lzdGVtLmVycjwvY29kZT4KK2FuZCBkb2VzIG5vdCB0aHJvdyBhbnkgPGNvZGU+RXhjZXB0aW9uPC9jb2RlPnMuCitBcHBsaWNhdGlvbnMgYXJlIDxlbT5zdHJvbmdseTwvZW0+IGVuY291cmFnZWQgdG8gcmVnaXN0ZXIgYW5kIHVzZQorPGNvZGU+RXJyb3JMaXN0ZW5lcjwvY29kZT5zIHRoYXQgaW5zdXJlIHByb3BlciBiZWhhdmlvciBmb3Igd2FybmluZ3MgYW5kCitlcnJvcnMuCis8L3A+CisKKworPGgzPlJlc29sdXRpb24gb2YgVVJJcyB3aXRoaW4gYSB0cmFuc2Zvcm1hdGlvbjwvaDM+CisKKzxwPlRoZSBBUEkgcHJvdmlkZXMgYSB3YXkgZm9yIFVSSXMgcmVmZXJlbmNlZCBmcm9tIHdpdGhpbiB0aGUgc3R5bGVzaGVldAoraW5zdHJ1Y3Rpb25zIG9yIHdpdGhpbiB0aGUgdHJhbnNmb3JtYXRpb24gdG8gYmUgcmVzb2x2ZWQgYnkgdGhlIGNhbGxpbmcKK2FwcGxpY2F0aW9uLiBUaGlzIGNhbiBiZSBkb25lIGJ5IGNyZWF0aW5nIGEgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoZQore0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVVJJUmVzb2x2ZXJ9IGludGVyZmFjZSwgd2l0aCBpdHMgb25lIG1ldGhvZCwKK3tAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlVSSVJlc29sdmVyI3Jlc29sdmV9LCBhbmQgdXNlIHRoaXMgY2xhc3MgdG8KK3NldCB0aGUgVVJJIHJlc29sdXRpb24gZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMgb3IgdHJhbnNmb3JtYXRpb24KK3dpdGgge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I3NldFVSSVJlc29sdmVyfSBvcgore0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXIjc2V0VVJJUmVzb2x2ZXJ9LiBUaGUKKzxjb2RlPlVSSVJlc29sdmVyLnJlc29sdmU8L2NvZGU+IG1ldGhvZCB0YWtlcyB0d28gU3RyaW5nIGFyZ3VtZW50cywgdGhlIFVSSSBmb3VuZCBpbiB0aGUKK3N0eWxlc2hlZXQgaW5zdHJ1Y3Rpb25zIG9yIGJ1aWx0IGFzIHBhcnQgb2YgdGhlIHRyYW5zZm9ybWF0aW9uIHByb2Nlc3MsIGFuZCB0aGUKK2Jhc2UgVVJJIAorYWdhaW5zdCB3aGljaCB0aGUgZmlyc3QgYXJndW1lbnQgd2lsbCBiZSBtYWRlIGFic29sdXRlIGlmIHRoZQorYWJzb2x1dGUgVVJJIGlzIHJlcXVpcmVkLgorVGhlIHJldHVybmVkIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZX0gb2JqZWN0IG11c3QgYmUgdXNhYmxlIGJ5Cit0aGUgdHJhbnNmb3JtZXIsIGFzIHNwZWNpZmllZCBpbiBpdHMgaW1wbGVtZW50ZWQgZmVhdHVyZXMuPC9wPgorCisKKzwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9TQVhSZXN1bHQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9TQVhSZXN1bHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYmIzMGJkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vc2F4L1NBWFJlc3VsdC5qYXZhCkBAIC0wLDAgKzEsMTM3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8gJElkOiBTQVhSZXN1bHQuamF2YSA0NDY1OTggMjAwNi0wOS0xNSAxMjo1NTo0MFogamVyZW1pYXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4OworCitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQ7CitpbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOworCisvKioKKyAqIDxwPkFjdHMgYXMgYW4gaG9sZGVyIGZvciBhIHRyYW5zZm9ybWF0aW9uIFJlc3VsdC48L3A+CisgKgorICogQGF1dGhvciA8YSBocmVmPSJKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqLworcHVibGljIGNsYXNzIFNBWFJlc3VsdCBpbXBsZW1lbnRzIFJlc3VsdCB7CisKKyAgICAvKioKKyAgICAgKiBJZiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkjZ2V0RmVhdHVyZX0KKyAgICAgKiByZXR1cm5zIHRydWUgd2hlbiBwYXNzZWQgdGhpcyB2YWx1ZSBhcyBhbiBhcmd1bWVudCwKKyAgICAgKiB0aGUgVHJhbnNmb3JtZXIgc3VwcG9ydHMgUmVzdWx0IG91dHB1dCBvZiB0aGlzIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRkVBVFVSRSA9CisgICAgICAgICJodHRwOi8vamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYUmVzdWx0L2ZlYXR1cmUiOworCisgICAgLyoqCisgICAgICogWmVyby1hcmd1bWVudCBkZWZhdWx0IGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBTQVhSZXN1bHQoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgU0FYUmVzdWx0IHRoYXQgdGFyZ2V0cyBhIFNBWDIge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBoYW5kbGVyIE11c3QgYmUgYSBub24tbnVsbCBDb250ZW50SGFuZGxlciByZWZlcmVuY2UuCisgICAgICovCisgICAgcHVibGljIFNBWFJlc3VsdChDb250ZW50SGFuZGxlciBoYW5kbGVyKSB7CisgICAgICAgIHNldEhhbmRsZXIoaGFuZGxlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSB0YXJnZXQgdG8gYmUgYSBTQVgyIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaGFuZGxlciBNdXN0IGJlIGEgbm9uLW51bGwgQ29udGVudEhhbmRsZXIgcmVmZXJlbmNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEhhbmRsZXIoQ29udGVudEhhbmRsZXIgaGFuZGxlcikgeworICAgICAgICB0aGlzLmhhbmRsZXIgPSBoYW5kbGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyfSB0aGF0IGlzIHRoZSBSZXN1bHQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBDb250ZW50SGFuZGxlciB0aGF0IGlzIHRvIGJlIHRyYW5zZm9ybWF0aW9uIG91dHB1dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29udGVudEhhbmRsZXIgZ2V0SGFuZGxlcigpIHsKKyAgICAgICAgcmV0dXJuIGhhbmRsZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBTQVgyIHtAbGluayBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXJ9IGZvciB0aGUgb3V0cHV0LgorICAgICAqCisgICAgICogPHA+VGhpcyBpcyBuZWVkZWQgdG8gaGFuZGxlIFhNTCBjb21tZW50cyBhbmQgdGhlIGxpa2UuICBJZiB0aGUKKyAgICAgKiBsZXhpY2FsIGhhbmRsZXIgaXMgbm90IHNldCwgYW4gYXR0ZW1wdCBzaG91bGQgYmUgbWFkZSBieSB0aGUKKyAgICAgKiB0cmFuc2Zvcm1lciB0byBjYXN0IHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJ9IHRvIGEKKyAgICAgKiA8Y29kZT5MZXhpY2FsSGFuZGxlcjwvY29kZT4uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGhhbmRsZXIgQSBub24tbnVsbCA8Y29kZT5MZXhpY2FsSGFuZGxlcjwvY29kZT4gZm9yCisgICAgICogaGFuZGxpbmcgbGV4aWNhbCBwYXJzZSBldmVudHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TGV4aWNhbEhhbmRsZXIoTGV4aWNhbEhhbmRsZXIgaGFuZGxlcikgeworICAgICAgICB0aGlzLmxleGhhbmRsZXIgPSBoYW5kbGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhIFNBWDIge0BsaW5rIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcn0gZm9yIHRoZSBvdXRwdXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEgPGNvZGU+TGV4aWNhbEhhbmRsZXI8L2NvZGU+LCBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBMZXhpY2FsSGFuZGxlciBnZXRMZXhpY2FsSGFuZGxlcigpIHsKKyAgICAgICAgcmV0dXJuIGxleGhhbmRsZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWV0aG9kIHNldFN5c3RlbUlkIFNldCB0aGUgc3lzdGVtSUQgdGhhdCBtYXkgYmUgdXNlZCBpbiBhc3NvY2lhdGlvbgorICAgICAqIHdpdGggdGhlIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIGFzIGEgVVJJIHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQpIHsKKyAgICAgICAgdGhpcy5zeXN0ZW1JZCA9IHN5c3RlbUlkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgdGhhdCB3YXMgc2V0IHdpdGggc2V0U3lzdGVtSWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllciB0aGF0IHdhcyBzZXQgd2l0aCBzZXRTeXN0ZW1JZCwgb3IgbnVsbAorICAgICAqIGlmIHNldFN5c3RlbUlkIHdhcyBub3QgY2FsbGVkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7CisgICAgICAgIHJldHVybiBzeXN0ZW1JZDsKKyAgICB9CisKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gSW50ZXJuYWwgc3RhdGUuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisgICAgLyoqCisgICAgICogVGhlIGhhbmRsZXIgZm9yIHBhcnNlIGV2ZW50cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIENvbnRlbnRIYW5kbGVyIGhhbmRsZXI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaGFuZGxlciBmb3IgbGV4aWNhbCBldmVudHMuCisgICAgICovCisgICAgcHJpdmF0ZSBMZXhpY2FsSGFuZGxlciBsZXhoYW5kbGVyOworCisgICAgLyoqCisgICAgICogVGhlIHN5c3RlbUlEIHRoYXQgbWF5IGJlIHVzZWQgaW4gYXNzb2NpYXRpb24KKyAgICAgKiB3aXRoIHRoZSBub2RlLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHN5c3RlbUlkOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vc2F4L1NBWFNvdXJjZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vc2F4L1NBWFNvdXJjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxYzE5OTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9zYXgvU0FYU291cmNlLmphdmEKQEAgLTAsMCArMSwyMDQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLyAkSWQ6IFNBWFNvdXJjZS5qYXZhIDQ0NjU5OCAyMDA2LTA5LTE1IDEyOjU1OjQwWiBqZXJlbWlhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybS5zYXg7CisKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7CitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CitpbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOworCisvKioKKyAqIDxwPkFjdHMgYXMgYW4gaG9sZGVyIGZvciBTQVgtc3R5bGUgU291cmNlLjwvcD4KKyAqCisgKiA8cD5Ob3RlIHRoYXQgWFNMVCByZXF1aXJlcyBuYW1lc3BhY2Ugc3VwcG9ydC4gQXR0ZW1wdGluZyB0byB0cmFuc2Zvcm0gYW4KKyAqIGlucHV0IHNvdXJjZSB0aGF0IGlzIG5vdAorICogZ2VuZXJhdGVkIHdpdGggYSBuYW1lc3BhY2UtYXdhcmUgcGFyc2VyIG1heSByZXN1bHQgaW4gZXJyb3JzLgorICogUGFyc2VycyBjYW4gYmUgbWFkZSBuYW1lc3BhY2UgYXdhcmUgYnkgY2FsbGluZyB0aGUKKyAqIHtAbGluayBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5I3NldE5hbWVzcGFjZUF3YXJlKGJvb2xlYW4gYXdhcmVuZXNzKX0gbWV0aG9kLjwvcD4KKyAqCisgKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogNDQ2NTk4ICQsICREYXRlOiAyMDA2LTA5LTE1IDA1OjU1OjQwIC0wNzAwIChGcmksIDE1IFNlcCAyMDA2KSAkCisgKi8KK3B1YmxpYyBjbGFzcyBTQVhTb3VyY2UgaW1wbGVtZW50cyBTb3VyY2UgeworCisgICAgLyoqCisgICAgICogSWYge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I2dldEZlYXR1cmV9CisgICAgICogcmV0dXJucyB0cnVlIHdoZW4gcGFzc2VkIHRoaXMgdmFsdWUgYXMgYW4gYXJndW1lbnQsCisgICAgICogdGhlIFRyYW5zZm9ybWVyIHN1cHBvcnRzIFNvdXJjZSBpbnB1dCBvZiB0aGlzIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRkVBVFVSRSA9CisgICAgICAgICJodHRwOi8vamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYU291cmNlL2ZlYXR1cmUiOworCisgICAgLyoqCisgICAgICogPHA+WmVyby1hcmd1bWVudCBkZWZhdWx0IGNvbnN0cnVjdG9yLiAgSWYgdGhpcyBjb25zdHJ1Y3RvciBpcyB1c2VkLCBhbmQKKyAgICAgKiBubyBTQVggc291cmNlIGlzIHNldCB1c2luZworICAgICAqIHtAbGluayAjc2V0SW5wdXRTb3VyY2UoSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UpfSAsIHRoZW4gdGhlCisgICAgICogPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+IHdpbGwKKyAgICAgKiBjcmVhdGUgYW4gZW1wdHkgc291cmNlIHtAbGluayBvcmcueG1sLnNheC5JbnB1dFNvdXJjZX0gdXNpbmcKKyAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2UjSW5wdXRTb3VyY2UoKSBuZXcgSW5wdXRTb3VyY2UoKX0uPC9wPgorICAgICAqCisgICAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyI3RyYW5zZm9ybShTb3VyY2UgeG1sU291cmNlLCBSZXN1bHQgb3V0cHV0VGFyZ2V0KQorICAgICAqLworICAgIHB1YmxpYyBTQVhTb3VyY2UoKSB7IH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIDxjb2RlPlNBWFNvdXJjZTwvY29kZT4sIHVzaW5nIGFuIHtAbGluayBvcmcueG1sLnNheC5YTUxSZWFkZXJ9CisgICAgICogYW5kIGEgU0FYIElucHV0U291cmNlLiBUaGUge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJ9CisgICAgICogb3Ige0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFRyYW5zZm9ybWVyRmFjdG9yeX0gd2lsbCBzZXQgaXRzZWxmCisgICAgICogdG8gYmUgdGhlIHJlYWRlcidzIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0sIGFuZCB0aGVuIHdpbGwgY2FsbAorICAgICAqIHJlYWRlci5wYXJzZShpbnB1dFNvdXJjZSkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhZGVyIEFuIFhNTFJlYWRlciB0byBiZSB1c2VkIGZvciB0aGUgcGFyc2UuCisgICAgICogQHBhcmFtIGlucHV0U291cmNlIEEgU0FYIGlucHV0IHNvdXJjZSByZWZlcmVuY2UgdGhhdCBtdXN0IGJlIG5vbi1udWxsCisgICAgICogYW5kIHRoYXQgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIHJlYWRlciBwYXJzZSBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIFNBWFNvdXJjZShYTUxSZWFkZXIgcmVhZGVyLCBJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSkgeworICAgICAgICB0aGlzLnJlYWRlciAgICAgID0gcmVhZGVyOworICAgICAgICB0aGlzLmlucHV0U291cmNlID0gaW5wdXRTb3VyY2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgPGNvZGU+U0FYU291cmNlPC9jb2RlPiwgdXNpbmcgYSBTQVggPGNvZGU+SW5wdXRTb3VyY2U8L2NvZGU+LgorICAgICAqIFRoZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcn0gb3IKKyAgICAgKiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYVHJhbnNmb3JtZXJGYWN0b3J5fSBjcmVhdGVzIGEKKyAgICAgKiByZWFkZXIgdmlhIHtAbGluayBvcmcueG1sLnNheC5oZWxwZXJzLlhNTFJlYWRlckZhY3Rvcnl9CisgICAgICogKGlmIHNldFhNTFJlYWRlciBpcyBub3QgdXNlZCksIHNldHMgaXRzZWxmIGFzCisgICAgICogdGhlIHJlYWRlcidzIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0sIGFuZCBjYWxscworICAgICAqIHJlYWRlci5wYXJzZShpbnB1dFNvdXJjZSkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXRTb3VyY2UgQW4gaW5wdXQgc291cmNlIHJlZmVyZW5jZSB0aGF0IG11c3QgYmUgbm9uLW51bGwKKyAgICAgKiBhbmQgdGhhdCB3aWxsIGJlIHBhc3NlZCB0byB0aGUgcGFyc2UgbWV0aG9kIG9mIHRoZSByZWFkZXIuCisgICAgICovCisgICAgcHVibGljIFNBWFNvdXJjZShJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSkgeworICAgICAgICB0aGlzLmlucHV0U291cmNlID0gaW5wdXRTb3VyY2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBYTUxSZWFkZXIgdG8gYmUgdXNlZCBmb3IgdGhlIFNvdXJjZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFkZXIgQSB2YWxpZCBYTUxSZWFkZXIgb3IgWE1MRmlsdGVyIHJlZmVyZW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRYTUxSZWFkZXIoWE1MUmVhZGVyIHJlYWRlcikgeworICAgICAgICB0aGlzLnJlYWRlciA9IHJlYWRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIFhNTFJlYWRlciB0byBiZSB1c2VkIGZvciB0aGUgU291cmNlLgorICAgICAqCisgICAgICogQHJldHVybiBBIHZhbGlkIFhNTFJlYWRlciBvciBYTUxGaWx0ZXIgcmVmZXJlbmNlLCBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBYTUxSZWFkZXIgZ2V0WE1MUmVhZGVyKCkgeworICAgICAgICByZXR1cm4gcmVhZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgU0FYIElucHV0U291cmNlIHRvIGJlIHVzZWQgZm9yIHRoZSBTb3VyY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXRTb3VyY2UgQSB2YWxpZCBJbnB1dFNvdXJjZSByZWZlcmVuY2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SW5wdXRTb3VyY2UoSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UpIHsKKyAgICAgICAgdGhpcy5pbnB1dFNvdXJjZSA9IGlucHV0U291cmNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgU0FYIElucHV0U291cmNlIHRvIGJlIHVzZWQgZm9yIHRoZSBTb3VyY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEgdmFsaWQgSW5wdXRTb3VyY2UgcmVmZXJlbmNlLCBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFNvdXJjZSBnZXRJbnB1dFNvdXJjZSgpIHsKKyAgICAgICAgcmV0dXJuIGlucHV0U291cmNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoaXMgU291cmNlLiAgSWYgYW4gaW5wdXQgc291cmNlCisgICAgICogaGFzIGFscmVhZHkgYmVlbiBzZXQsIGl0IHdpbGwgc2V0IHRoZSBzeXN0ZW0gSUQgb3IgdGhhdAorICAgICAqIGlucHV0IHNvdXJjZSwgb3RoZXJ3aXNlIGl0IHdpbGwgY3JlYXRlIGEgbmV3IGlucHV0IHNvdXJjZS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBvcHRpb25hbCBpZiB0aGVyZSBpcyBhIGJ5dGUgc3RyZWFtCisgICAgICogb3IgYSBjaGFyYWN0ZXIgc3RyZWFtLCBidXQgaXQgaXMgc3RpbGwgdXNlZnVsIHRvIHByb3ZpZGUgb25lLAorICAgICAqIHNpbmNlIHRoZSBhcHBsaWNhdGlvbiBjYW4gdXNlIGl0IHRvIHJlc29sdmUgcmVsYXRpdmUgVVJJcworICAgICAqIGFuZCBjYW4gaW5jbHVkZSBpdCBpbiBlcnJvciBtZXNzYWdlcyBhbmQgd2FybmluZ3MgKHRoZSBwYXJzZXIKKyAgICAgKiB3aWxsIGF0dGVtcHQgdG8gb3BlbiBhIGNvbm5lY3Rpb24gdG8gdGhlIFVSSSBvbmx5IGlmCisgICAgICogbm8gYnl0ZSBzdHJlYW0gb3IgY2hhcmFjdGVyIHN0cmVhbSBpcyBzcGVjaWZpZWQpLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgYXMgYSBVUkkgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCkgeworCisgICAgICAgIGlmIChudWxsID09IGlucHV0U291cmNlKSB7CisgICAgICAgICAgICBpbnB1dFNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZShzeXN0ZW1JZCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpbnB1dFNvdXJjZS5zZXRTeXN0ZW1JZChzeXN0ZW1JZCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5HZXQgdGhlIGJhc2UgSUQgKFVSSSBvciBzeXN0ZW0gSUQpIGZyb20gd2hlcmUgVVJJcworICAgICAqIHdpbGwgYmUgcmVzb2x2ZWQuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBCYXNlIFVSTCBmb3IgdGhlIDxjb2RlPlNvdXJjZTwvY29kZT4sIG9yIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7CisKKyAgICAgICAgaWYgKGlucHV0U291cmNlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIGlucHV0U291cmNlLmdldFN5c3RlbUlkKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgWE1MUmVhZGVyIHRvIGJlIHVzZWQgZm9yIHRoZSBzb3VyY2UgdHJlZSBpbnB1dC4gTWF5IGJlIG51bGwuCisgICAgICovCisgICAgcHJpdmF0ZSBYTUxSZWFkZXIgcmVhZGVyOworCisgICAgLyoqCisgICAgICogPHA+VGhlIFNBWCBJbnB1dFNvdXJjZSB0byBiZSB1c2VkIGZvciB0aGUgc291cmNlIHRyZWUgaW5wdXQuCisgICAgICogU2hvdWxkIG5vdCBiZSA8Y29kZT5udWxsPGNvZGU+LjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIElucHV0U291cmNlIGlucHV0U291cmNlOworCisgICAgLyoqCisgICAgICogQXR0ZW1wdCB0byBvYnRhaW4gYSBTQVggSW5wdXRTb3VyY2Ugb2JqZWN0IGZyb20gYSBTb3VyY2UKKyAgICAgKiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc291cmNlIE11c3QgYmUgYSBub24tbnVsbCBTb3VyY2UgcmVmZXJlbmNlLgorICAgICAqCisgICAgICogQHJldHVybiBBbiBJbnB1dFNvdXJjZSwgb3IgbnVsbCBpZiBTb3VyY2UgY2FuIG5vdCBiZSBjb252ZXJ0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJbnB1dFNvdXJjZSBzb3VyY2VUb0lucHV0U291cmNlKFNvdXJjZSBzb3VyY2UpIHsKKworICAgICAgICBpZiAoc291cmNlIGluc3RhbmNlb2YgU0FYU291cmNlKSB7CisgICAgICAgICAgICByZXR1cm4gKChTQVhTb3VyY2UpIHNvdXJjZSkuZ2V0SW5wdXRTb3VyY2UoKTsKKyAgICAgICAgfSBlbHNlIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBTdHJlYW1Tb3VyY2UpIHsKKyAgICAgICAgICAgIFN0cmVhbVNvdXJjZSBzcyAgICAgID0gKFN0cmVhbVNvdXJjZSkgc291cmNlOworICAgICAgICAgICAgSW5wdXRTb3VyY2UgIGlzb3VyY2UgPSBuZXcgSW5wdXRTb3VyY2Uoc3MuZ2V0U3lzdGVtSWQoKSk7CisKKyAgICAgICAgICAgIGlzb3VyY2Uuc2V0Qnl0ZVN0cmVhbShzcy5nZXRJbnB1dFN0cmVhbSgpKTsKKyAgICAgICAgICAgIGlzb3VyY2Uuc2V0Q2hhcmFjdGVyU3RyZWFtKHNzLmdldFJlYWRlcigpKTsKKyAgICAgICAgICAgIGlzb3VyY2Uuc2V0UHVibGljSWQoc3MuZ2V0UHVibGljSWQoKSk7CisKKyAgICAgICAgICAgIHJldHVybiBpc291cmNlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9TQVhUcmFuc2Zvcm1lckZhY3RvcnkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9TQVhUcmFuc2Zvcm1lckZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZjYyZDNhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vc2F4L1NBWFRyYW5zZm9ybWVyRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMTQ2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8gJElkOiBTQVhUcmFuc2Zvcm1lckZhY3RvcnkuamF2YSA0NDY1OTggMjAwNi0wOS0xNSAxMjo1NTo0MFogamVyZW1pYXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4OworCitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM7CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnk7CitpbXBvcnQgb3JnLnhtbC5zYXguWE1MRmlsdGVyOworCisvKioKKyAqIFRoaXMgY2xhc3MgZXh0ZW5kcyBUcmFuc2Zvcm1lckZhY3RvcnkgdG8gcHJvdmlkZSBTQVgtc3BlY2lmaWMKKyAqIGZhY3RvcnkgbWV0aG9kcy4gIEl0IHByb3ZpZGVzIHR3byB0eXBlcyBvZiBDb250ZW50SGFuZGxlcnMsCisgKiBvbmUgZm9yIGNyZWF0aW5nIFRyYW5zZm9ybWVycywgdGhlIG90aGVyIGZvciBjcmVhdGluZyBUZW1wbGF0ZXMKKyAqIG9iamVjdHMuCisgKgorICogPHA+SWYgYW4gYXBwbGljYXRpb24gd2FudHMgdG8gc2V0IHRoZSBFcnJvckhhbmRsZXIgb3IgRW50aXR5UmVzb2x2ZXIKKyAqIGZvciBhbiBYTUxSZWFkZXIgdXNlZCBkdXJpbmcgYSB0cmFuc2Zvcm1hdGlvbiwgaXQgc2hvdWxkIHVzZSBhIFVSSVJlc29sdmVyCisgKiB0byByZXR1cm4gdGhlIFNBWFNvdXJjZSB3aGljaCBwcm92aWRlcyAod2l0aCBnZXRYTUxSZWFkZXIpIGEgcmVmZXJlbmNlIHRvCisgKiB0aGUgWE1MUmVhZGVyLjwvcD4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFNBWFRyYW5zZm9ybWVyRmFjdG9yeSBleHRlbmRzIFRyYW5zZm9ybWVyRmFjdG9yeSB7CisKKyAgICAvKiogSWYge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I2dldEZlYXR1cmV9CisgICAgICogcmV0dXJucyB0cnVlIHdoZW4gcGFzc2VkIHRoaXMgdmFsdWUgYXMgYW4gYXJndW1lbnQsCisgICAgICogdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSByZXR1cm5lZCBmcm9tCisgICAgICoge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I25ld0luc3RhbmNlfSBtYXkKKyAgICAgKiBiZSBzYWZlbHkgY2FzdCB0byBhIFNBWFRyYW5zZm9ybWVyRmFjdG9yeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGRUFUVVJFID0KKyAgICAgICAgImh0dHA6Ly9qYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3RvcnkvZmVhdHVyZSI7CisKKyAgICAvKiogSWYge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I2dldEZlYXR1cmV9CisgICAgICogcmV0dXJucyB0cnVlIHdoZW4gcGFzc2VkIHRoaXMgdmFsdWUgYXMgYW4gYXJndW1lbnQsCisgICAgICogdGhlIHtAbGluayAjbmV3WE1MRmlsdGVyKFNvdXJjZSBzcmMpfQorICAgICAqIGFuZCB7QGxpbmsgI25ld1hNTEZpbHRlcihUZW1wbGF0ZXMgdGVtcGxhdGVzKX0gbWV0aG9kcyBhcmUgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZFQVRVUkVfWE1MRklMVEVSID0KKyAgICAgICAgImh0dHA6Ly9qYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3RvcnkvZmVhdHVyZS94bWxmaWx0ZXIiOworCisgICAgLyoqCisgICAgICogVGhlIGRlZmF1bHQgY29uc3RydWN0b3IgaXMgcHJvdGVjdGVkIG9uIHB1cnBvc2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNBWFRyYW5zZm9ybWVyRmFjdG9yeSgpIHt9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYSBUcmFuc2Zvcm1lckhhbmRsZXIgb2JqZWN0IHRoYXQgY2FuIHByb2Nlc3MgU0FYCisgICAgICogQ29udGVudEhhbmRsZXIgZXZlbnRzIGludG8gYSBSZXN1bHQsIGJhc2VkIG9uIHRoZSB0cmFuc2Zvcm1hdGlvbgorICAgICAqIGluc3RydWN0aW9ucyBzcGVjaWZpZWQgYnkgdGhlIGFyZ3VtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHNyYyBUaGUgU291cmNlIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRyYW5zZm9ybWVySGFuZGxlciByZWFkeSB0byB0cmFuc2Zvcm0gU0FYIGV2ZW50cy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIElmIGZvciBzb21lIHJlYXNvbiB0aGUKKyAgICAgKiBUcmFuc2Zvcm1lckhhbmRsZXIgY2FuIG5vdCBiZSBjcmVhdGVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBUcmFuc2Zvcm1lckhhbmRsZXIgbmV3VHJhbnNmb3JtZXJIYW5kbGVyKFNvdXJjZSBzcmMpCisgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgYSBUcmFuc2Zvcm1lckhhbmRsZXIgb2JqZWN0IHRoYXQgY2FuIHByb2Nlc3MgU0FYCisgICAgICogQ29udGVudEhhbmRsZXIgZXZlbnRzIGludG8gYSBSZXN1bHQsIGJhc2VkIG9uIHRoZSBUZW1wbGF0ZXMgYXJndW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGVtcGxhdGVzIFRoZSBjb21waWxlZCB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRyYW5zZm9ybWVySGFuZGxlciByZWFkeSB0byB0cmFuc2Zvcm0gU0FYIGV2ZW50cy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIElmIGZvciBzb21lIHJlYXNvbiB0aGUKKyAgICAgKiBUcmFuc2Zvcm1lckhhbmRsZXIgY2FuIG5vdCBiZSBjcmVhdGVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBUcmFuc2Zvcm1lckhhbmRsZXIgbmV3VHJhbnNmb3JtZXJIYW5kbGVyKAorICAgICAgICBUZW1wbGF0ZXMgdGVtcGxhdGVzKSB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0IGEgVHJhbnNmb3JtZXJIYW5kbGVyIG9iamVjdCB0aGF0IGNhbiBwcm9jZXNzIFNBWAorICAgICAqIENvbnRlbnRIYW5kbGVyIGV2ZW50cyBpbnRvIGEgUmVzdWx0LiBUaGUgdHJhbnNmb3JtYXRpb24KKyAgICAgKiBpcyBkZWZpbmVkIGFzIGFuIGlkZW50aXR5IChvciBjb3B5KSB0cmFuc2Zvcm1hdGlvbiwgZm9yIGV4YW1wbGUKKyAgICAgKiB0byBjb3B5IGEgc2VyaWVzIG9mIFNBWCBwYXJzZSBldmVudHMgaW50byBhIERPTSB0cmVlLgorICAgICAqCisgICAgICogQHJldHVybiBBIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIFRyYW5zZm9ybWVySGFuZGxlciwgdGhhdCBtYXkKKyAgICAgKiBiZSB1c2VkIGFzIGEgQ29udGVudEhhbmRsZXIgZm9yIFNBWCBwYXJzZSBldmVudHMuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBJZiBmb3Igc29tZSByZWFzb24gdGhlCisgICAgICogVHJhbnNmb3JtZXJIYW5kbGVyIGNhbm5vdCBiZSBjcmVhdGVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBUcmFuc2Zvcm1lckhhbmRsZXIgbmV3VHJhbnNmb3JtZXJIYW5kbGVyKCkKKyAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldCBhIFRlbXBsYXRlc0hhbmRsZXIgb2JqZWN0IHRoYXQgY2FuIHByb2Nlc3MgU0FYCisgICAgICogQ29udGVudEhhbmRsZXIgZXZlbnRzIGludG8gYSBUZW1wbGF0ZXMgb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybiBBIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIFRyYW5zZm9ybWVySGFuZGxlciwgdGhhdCBtYXkKKyAgICAgKiBiZSB1c2VkIGFzIGEgQ29udGVudEhhbmRsZXIgZm9yIFNBWCBwYXJzZSBldmVudHMuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBJZiBmb3Igc29tZSByZWFzb24gdGhlCisgICAgICogVGVtcGxhdGVzSGFuZGxlciBjYW5ub3QgYmUgY3JlYXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgVGVtcGxhdGVzSGFuZGxlciBuZXdUZW1wbGF0ZXNIYW5kbGVyKCkKKyAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhbiBYTUxGaWx0ZXIgdGhhdCB1c2VzIHRoZSBnaXZlbiBTb3VyY2UgYXMgdGhlCisgICAgICogdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLgorICAgICAqCisgICAgICogQHBhcmFtIHNyYyBUaGUgU291cmNlIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFuIFhNTEZpbHRlciBvYmplY3QsIG9yIG51bGwgaWYgdGhpcyBmZWF0dXJlIGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBJZiBmb3Igc29tZSByZWFzb24gdGhlCisgICAgICogVGVtcGxhdGVzSGFuZGxlciBjYW5ub3QgYmUgY3JlYXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgWE1MRmlsdGVyIG5ld1hNTEZpbHRlcihTb3VyY2Ugc3JjKQorICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuIFhNTEZpbHRlciwgYmFzZWQgb24gdGhlIFRlbXBsYXRlcyBhcmd1bWVudC4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGVtcGxhdGVzIFRoZSBjb21waWxlZCB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFuIFhNTEZpbHRlciBvYmplY3QsIG9yIG51bGwgaWYgdGhpcyBmZWF0dXJlIGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBJZiBmb3Igc29tZSByZWFzb24gdGhlCisgICAgICogVGVtcGxhdGVzSGFuZGxlciBjYW5ub3QgYmUgY3JlYXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgWE1MRmlsdGVyIG5ld1hNTEZpbHRlcihUZW1wbGF0ZXMgdGVtcGxhdGVzKQorICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vc2F4L1RlbXBsYXRlc0hhbmRsZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9UZW1wbGF0ZXNIYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjA5ZWY2ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9UZW1wbGF0ZXNIYW5kbGVyLmphdmEKQEAgLTAsMCArMSw2MSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vICRJZDogVGVtcGxhdGVzSGFuZGxlci5qYXZhIDQ0NjU5OCAyMDA2LTA5LTE1IDEyOjU1OjQwWiBqZXJlbWlhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybS5zYXg7CisKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlczsKK2ltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKKworLyoqCisgKiBBIFNBWCBDb250ZW50SGFuZGxlciB0aGF0IG1heSBiZSB1c2VkIHRvIHByb2Nlc3MgU0FYCisgKiBwYXJzZSBldmVudHMgKHBhcnNpbmcgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zKSBpbnRvIGEgVGVtcGxhdGVzIG9iamVjdC4KKyAqCisgKiA8cD5Ob3RlIHRoYXQgVGVtcGxhdGVzSGFuZGxlciBkb2VzIG5vdCBuZWVkIHRvIGltcGxlbWVudCBMZXhpY2FsSGFuZGxlci48L3A+CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgVGVtcGxhdGVzSGFuZGxlciBleHRlbmRzIENvbnRlbnRIYW5kbGVyIHsKKworICAgIC8qKgorICAgICAqIFdoZW4gYSBUZW1wbGF0ZXNIYW5kbGVyIG9iamVjdCBpcyB1c2VkIGFzIGEgQ29udGVudEhhbmRsZXIKKyAgICAgKiBmb3IgdGhlIHBhcnNpbmcgb2YgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLCBpdCBjcmVhdGVzIGEgVGVtcGxhdGVzIG9iamVjdCwKKyAgICAgKiB3aGljaCB0aGUgY2FsbGVyIGNhbiBnZXQgb25jZSB0aGUgU0FYIGV2ZW50cyBoYXZlIGJlZW4gY29tcGxldGVkLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgVGVtcGxhdGVzIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIGR1cmluZworICAgICAqIHRoZSBTQVggZXZlbnQgcHJvY2Vzcywgb3IgbnVsbCBpZiBubyBUZW1wbGF0ZXMgb2JqZWN0IGhhcworICAgICAqIGJlZW4gY3JlYXRlZC4KKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBUZW1wbGF0ZXMgZ2V0VGVtcGxhdGVzKCk7CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGJhc2UgSUQgKFVSSSBvciBzeXN0ZW0gSUQpIGZvciB0aGUgVGVtcGxhdGVzIG9iamVjdAorICAgICAqIGNyZWF0ZWQgYnkgdGhpcyBidWlsZGVyLiAgVGhpcyBtdXN0IGJlIHNldCBpbiBvcmRlciB0bworICAgICAqIHJlc29sdmUgcmVsYXRpdmUgVVJJcyBpbiB0aGUgc3R5bGVzaGVldC4gIFRoaXMgbXVzdCBiZQorICAgICAqIGNhbGxlZCBiZWZvcmUgdGhlIHN0YXJ0RG9jdW1lbnQgZXZlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3lzdGVtSUQgQmFzZSBVUkkgZm9yIHRoaXMgc3R5bGVzaGVldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSUQpOworCisgICAgLyoqCisgICAgICogR2V0IHRoZSBiYXNlIElEIChVUkkgb3Igc3lzdGVtIElEKSBmcm9tIHdoZXJlIHJlbGF0aXZlCisgICAgICogVVJMcyB3aWxsIGJlIHJlc29sdmVkLgorICAgICAqIEByZXR1cm4gVGhlIHN5c3RlbUlEIHRoYXQgd2FzIHNldCB3aXRoIHtAbGluayAjc2V0U3lzdGVtSWR9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9UcmFuc2Zvcm1lckhhbmRsZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9UcmFuc2Zvcm1lckhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ODQzNzQ1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vc2F4L1RyYW5zZm9ybWVySGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsNjkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLyAkSWQ6IFRyYW5zZm9ybWVySGFuZGxlci5qYXZhIDQ0NjU5OCAyMDA2LTA5LTE1IDEyOjU1OjQwWiBqZXJlbWlhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybS5zYXg7CisKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdDsKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyOworaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkRUREhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOworCisvKioKKyAqIEEgVHJhbnNmb3JtZXJIYW5kbGVyCisgKiBsaXN0ZW5zIGZvciBTQVggQ29udGVudEhhbmRsZXIgcGFyc2UgZXZlbnRzIGFuZCB0cmFuc2Zvcm1zCisgKiB0aGVtIHRvIGEgUmVzdWx0LgorICovCitwdWJsaWMgaW50ZXJmYWNlIFRyYW5zZm9ybWVySGFuZGxlcgorICAgIGV4dGVuZHMgQ29udGVudEhhbmRsZXIsIExleGljYWxIYW5kbGVyLCBEVERIYW5kbGVyIHsKKworICAgIC8qKgorICAgICAqIDxwPlNldCAgdGhlIDxjb2RlPlJlc3VsdDwvY29kZT4gYXNzb2NpYXRlZCB3aXRoIHRoaXMKKyAgICAgKiA8Y29kZT5UcmFuc2Zvcm1lckhhbmRsZXI8L2NvZGU+IHRvIGJlIHVzZWQgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVzdWx0IEEgPGNvZGU+UmVzdWx0PC9jb2RlPiBpbnN0YW5jZSwgc2hvdWxkIG5vdCBiZQorICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiByZXN1bHQgaXMgaW52YWxpZCBmb3Igc29tZSByZWFzb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmVzdWx0KFJlc3VsdCByZXN1bHQpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGJhc2UgSUQgKFVSSSBvciBzeXN0ZW0gSUQpIGZyb20gd2hlcmUgcmVsYXRpdmUKKyAgICAgKiBVUkxzIHdpbGwgYmUgcmVzb2x2ZWQuCisgICAgICogQHBhcmFtIHN5c3RlbUlEIEJhc2UgVVJJIGZvciB0aGUgc291cmNlIHRyZWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3lzdGVtSWQoU3RyaW5nIHN5c3RlbUlEKTsKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgYmFzZSBJRCAoVVJJIG9yIHN5c3RlbSBJRCkgZnJvbSB3aGVyZSByZWxhdGl2ZQorICAgICAqIFVSTHMgd2lsbCBiZSByZXNvbHZlZC4KKyAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW1JRCB0aGF0IHdhcyBzZXQgd2l0aCB7QGxpbmsgI3NldFN5c3RlbUlkfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCk7CisKKyAgICAvKioKKyAgICAgKiA8cD5HZXQgdGhlIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPiBhc3NvY2lhdGVkIHdpdGggdGhpcyBoYW5kbGVyLCB3aGljaAorICAgICAqIGlzIG5lZWRlZCBpbiBvcmRlciB0byBzZXQgcGFyYW1ldGVycyBhbmQgb3V0cHV0IHByb3BlcnRpZXMuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gYXNzb2NpYXRlZCB3aXRoIHRoaXMKKyAgICAgKiAgIDxjb2RlPlRyYW5zZm9ybWVySGFuZGxlcjwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIFRyYW5zZm9ybWVyIGdldFRyYW5zZm9ybWVyKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9zYXgvcGFja2FnZS5odG1sIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vc2F4L3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YTBkNzA3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vc2F4L3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDY5IEBACis8IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wIFRyYW5zaXRpb25hbC8vRU4iPgorPGh0bWw+Cis8aGVhZD4KKzxNRVRBIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04Ij4KKzx0aXRsZT5qYXZheC54bWwudHJhbnNmb3JtLnNheDwvdGl0bGU+Cis8L2hlYWQ+Cis8Ym9keT4KKzxwPlRoaXMgcGFja2FnZSBpbXBsZW1lbnRzIFNBWDItc3BlY2lmaWMgdHJhbnNmb3JtYXRpb24gQVBJcy4gSXQgcHJvdmlkZXMKKyAgY2xhc3NlcyB3aGljaCBhbGxvdyBpbnB1dCBmcm9tIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0KKyAgZXZlbnRzLCBhbmQgYWxzbyBjbGFzc2VzIHRoYXQgcHJvZHVjZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBldmVudHMuIEl0CisgIGFsc28gcHJvdmlkZXMgbWV0aG9kcyB0byBzZXQgdGhlIGlucHV0IHNvdXJjZSBhcyBhbgorICB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyfSwgb3IgdG8gdXNlIGEKKyAge0BsaW5rIG9yZy54bWwuc2F4LklucHV0U291cmNlfSBhcyB0aGUgc291cmNlLiBJdCBhbHNvIGFsbG93cyB0aGUKKyAgY3JlYXRpb24gb2YgYSB7QGxpbmsgb3JnLnhtbC5zYXguWE1MRmlsdGVyfSwgd2hpY2ggZW5hYmxlcworICB0cmFuc2Zvcm1hdGlvbnMgdG8gInB1bGwiIGZyb20gb3RoZXIgdHJhbnNmb3JtYXRpb25zLCBhbmQgbGV0cyB0aGUgdHJhbnNmb3JtZXIKKyAgdG8gYmUgdXNlZCBwb2x5bW9ycGhpY2FsbHkgYXMgYW4ge0BsaW5rIG9yZy54bWwuc2F4LlhNTFJlYWRlcn0uPC9wPgorPHA+VGhlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhTb3VyY2V9IGNsYXNzIGFsbG93cyB0aGUKKyAgc2V0dGluZyBvZiBhbiB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyfSB0byBiZSB1c2VkIGZvciAicHVsbGluZyIKKyAgcGFyc2UgZXZlbnRzLCBhbmQgYW4ge0BsaW5rIG9yZy54bWwuc2F4LklucHV0U291cmNlfSB0aGF0IG1heSBiZSB1c2VkIHRvCisgIHNwZWNpZnkgdGhlIFNBWCBzb3VyY2UuPC9wPgorPHA+VGhlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhSZXN1bHR9IGNsYXNzIGFsbG93cyB0aGUKKyAgc2V0dGluZyBvZiBhIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0gdG8gYmUgdGhlIHJlY2VpdmVyIG9mCisgIFNBWDIgZXZlbnRzIGZyb20gdGhlIHRyYW5zZm9ybWF0aW9uLiAKKzxwPlRoZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYVHJhbnNmb3JtZXJGYWN0b3J5fSBleHRlbmRzCisgIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeX0gdG8gcHJvdmlkZSBmYWN0b3J5CisgIG1ldGhvZHMgZm9yIGNyZWF0aW5nIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UZW1wbGF0ZXNIYW5kbGVyfSwKKyAge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVySGFuZGxlcn0sIGFuZAorICB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyfSBpbnN0YW5jZXMuPC9wPgorPHA+VG8gb2J0YWluIGEge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFRyYW5zZm9ybWVyRmFjdG9yeX0sCisgIHRoZSBjYWxsZXIgbXVzdCBjYXN0IHRoZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnl9CisgIGluc3RhbmNlIHJldHVybmVkIGZyb20KKyAge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I25ld0luc3RhbmNlfS4gCisKKzxwPlRoZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJIYW5kbGVyfSBpbnRlcmZhY2UKKyAgYWxsb3dzIGEgdHJhbnNmb3JtYXRpb24gdG8gYmUgY3JlYXRlZCBmcm9tIFNBWDIgcGFyc2UgZXZlbnRzLCB3aGljaCBpcyBhICJwdXNoIgorICBtb2RlbCByYXRoZXIgdGhhbiB0aGUgInB1bGwiIG1vZGVsIHRoYXQgbm9ybWFsbHkgb2NjdXJzIGZvciBhIHRyYW5zZm9ybWF0aW9uLgorICBOb3JtYWwgcGFyc2UgZXZlbnRzIGFyZSByZWNlaXZlZCB0aHJvdWdoIHRoZQorICB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJ9IGludGVyZmFjZSwgbGV4aWNhbCBldmVudHMgc3VjaCBhcworICBzdGFydENEQVRBIGFuZCBlbmRDREFUQSBhcmUgcmVjZWl2ZWQgdGhyb3VnaCB0aGUKKyAge0BsaW5rIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcn0gaW50ZXJmYWNlLCBhbmQgZXZlbnRzIHRoYXQgc2lnbmFsCisgIHRoZSBzdGFydCBvciBlbmQgb2YgZGlzYWJsaW5nIG91dHB1dCBlc2NhcGluZyBhcmUgcmVjZWl2ZWQgdmlhCisgIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb259LCB3aXRoIHRoZQorICB0YXJnZXQgcGFyYW1ldGVyIGJlaW5nCisgIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdCNQSV9ESVNBQkxFX09VVFBVVF9FU0NBUElOR30gYW5kCisgIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdCNQSV9FTkFCTEVfT1VUUFVUX0VTQ0FQSU5HfS4gSWYKKyAgcGFyYW1ldGVycywgb3V0cHV0IHByb3BlcnRpZXMsIG9yIG90aGVyIGZlYXR1cmVzIG5lZWQgdG8gYmUgc2V0IG9uIHRoZQorICBUcmFuc2Zvcm1lciBoYW5kbGVyLCBhIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyfSByZWZlcmVuY2UKKyAgd2lsbCBuZWVkIHRvIGJlIG9idGFpbmVkIGZyb20KKyAge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVySGFuZGxlciNnZXRUcmFuc2Zvcm1lcn0sIGFuZAorICB0aGUgbWV0aG9kcyBpbnZva2VkIGZyb20gdGhhdCByZWZlcmVuY2UuIAorCis8cD5UaGUge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRlbXBsYXRlc0hhbmRsZXJ9IGludGVyZmFjZQorICBhbGxvd3MgdGhlIGNyZWF0aW9uIG9mIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlc30gb2JqZWN0cworICBmcm9tIFNBWDIgcGFyc2UgZXZlbnRzLiBPbmNlIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJ9CisgIGV2ZW50cyBhcmUgY29tcGxldGUsIHRoZSBUZW1wbGF0ZXMgb2JqZWN0IG1heSBiZSBvYnRhaW5lZCBmcm9tCisgIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UZW1wbGF0ZXNIYW5kbGVyI2dldFRlbXBsYXRlc30uIE5vdGUgdGhhdAorICB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVGVtcGxhdGVzSGFuZGxlciNzZXRTeXN0ZW1JZH0gc2hvdWxkCisgIG5vcm1hbGx5IGJlIGNhbGxlZCBpbiBvcmRlciB0byBlc3RhYmxpc2ggYSBiYXNlIHN5c3RlbSBJRCBmcm9tIHdoaWNoIHJlbGF0aXZlCisgIFVSTHMgbWF5IGJlIHJlc29sdmVkLiAKKzxwPlRoZQorICB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYVHJhbnNmb3JtZXJGYWN0b3J5I25ld1hNTEZpbHRlcn0KKyAgbWV0aG9kIGFsbG93cyB0aGUgY3JlYXRpb24gb2YgYSB7QGxpbmsgb3JnLnhtbC5zYXguWE1MRmlsdGVyfSwgd2hpY2gKKyAgZW5jYXBzdWxhdGVzIHRoZSBTQVgyIG5vdGlvbiBvZiBhICJwdWxsIiB0cmFuc2Zvcm1hdGlvbi4gVGhlIGZvbGxvd2luZworICBpbGx1c3RyYXRlcyBzZXZlcmFsIHRyYW5zZm9ybWF0aW9ucyBjaGFpbmVkIHRvZ2V0aGVyLiBFYWNoIGZpbHRlciBwb2ludHMgdG8gYQorICBwYXJlbnQge0BsaW5rIG9yZy54bWwuc2F4LlhNTFJlYWRlcn0sIGFuZCB0aGUgZmluYWwgdHJhbnNmb3JtYXRpb24gaXMKKyAgY2F1c2VkIGJ5IGludm9raW5nIHtAbGluayBvcmcueG1sLnNheC5YTUxSZWFkZXIjcGFyc2V9IG9uIHRoZSBmaW5hbAorICByZWFkZXIgaW4gdGhlIGNoYWluLjwvcD4KKzwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL3N0cmVhbS9GaWxlUGF0aFRvVVJJLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9zdHJlYW0vRmlsZVBhdGhUb1VSSS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY5MmI4ZjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9zdHJlYW0vRmlsZVBhdGhUb1VSSS5qYXZhCkBAIC0wLDAgKzEsMTI5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbTsKKworY2xhc3MgRmlsZVBhdGhUb1VSSSB7CisKKyAgICAvLyB3aGljaCBBU0NJSSBjaGFyYWN0ZXJzIG5lZWQgdG8gYmUgZXNjYXBlZAorICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gZ05lZWRFc2NhcGluZ1tdID0gbmV3IGJvb2xlYW5bMTI4XTsKKyAgICAvLyB0aGUgZmlyc3QgaGV4IGNoYXJhY3RlciBpZiBhIGNoYXJhY3RlciBuZWVkcyB0byBiZSBlc2NhcGVkCisgICAgcHJpdmF0ZSBzdGF0aWMgY2hhcltdIGdBZnRlckVzY2FwaW5nMSA9IG5ldyBjaGFyWzEyOF07CisgICAgLy8gdGhlIHNlY29uZCBoZXggY2hhcmFjdGVyIGlmIGEgY2hhcmFjdGVyIG5lZWRzIHRvIGJlIGVzY2FwZWQKKyAgICBwcml2YXRlIHN0YXRpYyBjaGFyW10gZ0FmdGVyRXNjYXBpbmcyID0gbmV3IGNoYXJbMTI4XTsKKyAgICBwcml2YXRlIHN0YXRpYyBjaGFyW10gZ0hleENocyA9IHsnMCcsICcxJywgJzInLCAnMycsICc0JywgJzUnLCAnNicsICc3JywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnOCcsICc5JywgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJ307CisgICAgLy8gaW5pdGlhbGl6ZSB0aGUgYWJvdmUgMyBhcnJheXMKKyAgICBzdGF0aWMgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8PSAweDFmOyBpKyspIHsKKyAgICAgICAgICAgIGdOZWVkRXNjYXBpbmdbaV0gPSB0cnVlOworICAgICAgICAgICAgZ0FmdGVyRXNjYXBpbmcxW2ldID0gZ0hleENoc1tpID4+IDRdOworICAgICAgICAgICAgZ0FmdGVyRXNjYXBpbmcyW2ldID0gZ0hleENoc1tpICYgMHhmXTsKKyAgICAgICAgfQorICAgICAgICBnTmVlZEVzY2FwaW5nWzB4N2ZdID0gdHJ1ZTsKKyAgICAgICAgZ0FmdGVyRXNjYXBpbmcxWzB4N2ZdID0gJzcnOworICAgICAgICBnQWZ0ZXJFc2NhcGluZzJbMHg3Zl0gPSAnRic7CisgICAgICAgIGNoYXJbXSBlc2NDaHMgPSB7JyAnLCAnPCcsICc+JywgJyMnLCAnJScsICciJywgJ3snLCAnfScsCisgICAgICAgICAgICAgICAgICAgICAgICAgJ3wnLCAnXFwnLCAnXicsICd+JywgJ1snLCAnXScsICdgJ307CisgICAgICAgIGludCBsZW4gPSBlc2NDaHMubGVuZ3RoOworICAgICAgICBjaGFyIGNoOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisgICAgICAgICAgICBjaCA9IGVzY0Noc1tpXTsKKyAgICAgICAgICAgIGdOZWVkRXNjYXBpbmdbY2hdID0gdHJ1ZTsKKyAgICAgICAgICAgIGdBZnRlckVzY2FwaW5nMVtjaF0gPSBnSGV4Q2hzW2NoID4+IDRdOworICAgICAgICAgICAgZ0FmdGVyRXNjYXBpbmcyW2NoXSA9IGdIZXhDaHNbY2ggJiAweGZdOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gVG8gZXNjYXBlIGEgZmlsZSBwYXRoIHRvIGEgVVJJLCBieSB1c2luZyAlSEggdG8gcmVwcmVzZW50CisgICAgLy8gc3BlY2lhbCBBU0NJSSBjaGFyYWN0ZXJzOiAweDAwfjB4MUYsIDB4N0YsICcgJywgJzwnLCAnPicsICcjJywgJyUnCisgICAgLy8gYW5kICciJyBhbmQgbm9uLUFTQ0lJIGNoYXJhY3RlcnMgKHdob3NlIHZhbHVlID49IDEyOCkuCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZmlsZXBhdGgyVVJJKFN0cmluZyBwYXRoKXsKKyAgICAgICAgLy8gcmV0dXJuIG51bGwgaWYgcGF0aCBpcyBudWxsLgorICAgICAgICBpZiAocGF0aCA9PSBudWxsKQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisKKyAgICAgICAgY2hhciBzZXBhcmF0b3IgPSBqYXZhLmlvLkZpbGUuc2VwYXJhdG9yQ2hhcjsKKyAgICAgICAgcGF0aCA9IHBhdGgucmVwbGFjZShzZXBhcmF0b3IsICcvJyk7CisKKyAgICAgICAgaW50IGxlbiA9IHBhdGgubGVuZ3RoKCksIGNoOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWlsZGVyKGxlbiozKTsKKyAgICAgICAgYnVmZmVyLmFwcGVuZCgiZmlsZTovLyIpOworICAgICAgICAvLyBjaGFuZ2UgQzovYmxhaCB0byAvQzovYmxhaAorICAgICAgICBpZiAobGVuID49IDIgJiYgcGF0aC5jaGFyQXQoMSkgPT0gJzonKSB7CisgICAgICAgICAgICBjaCA9IENoYXJhY3Rlci50b1VwcGVyQ2FzZShwYXRoLmNoYXJBdCgwKSk7CisgICAgICAgICAgICBpZiAoY2ggPj0gJ0EnICYmIGNoIDw9ICdaJykgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJy8nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIGZvciBlYWNoIGNoYXJhY3RlciBpbiB0aGUgcGF0aAorICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgIGZvciAoOyBpIDwgbGVuOyBpKyspIHsKKyAgICAgICAgICAgIGNoID0gcGF0aC5jaGFyQXQoaSk7CisgICAgICAgICAgICAvLyBpZiBpdCdzIG5vdCBhbiBBU0NJSSBjaGFyYWN0ZXIsIGJyZWFrIGhlcmUsIGFuZCB1c2UgVVRGLTggZW5jb2RpbmcKKyAgICAgICAgICAgIGlmIChjaCA+PSAxMjgpCisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBpZiAoZ05lZWRFc2NhcGluZ1tjaF0pIHsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCclJyk7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnQWZ0ZXJFc2NhcGluZzFbY2hdKTsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGdBZnRlckVzY2FwaW5nMltjaF0pOworICAgICAgICAgICAgICAgIC8vIHJlY29yZCB0aGUgZmFjdCB0aGF0IGl0J3MgZXNjYXBlZAorICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgoY2hhciljaCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyB3ZSBzYXcgc29tZSBub24tYXNjaWkgY2hhcmFjdGVyCisgICAgICAgIGlmIChpIDwgbGVuKSB7CisgICAgICAgICAgICAvLyBnZXQgVVRGLTggYnl0ZXMgZm9yIHRoZSByZW1haW5pbmcgc3ViLXN0cmluZworICAgICAgICAgICAgYnl0ZVtdIGJ5dGVzID0gbnVsbDsKKyAgICAgICAgICAgIGJ5dGUgYjsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYnl0ZXMgPSBwYXRoLnN1YnN0cmluZyhpKS5nZXRCeXRlcygiVVRGLTgiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gc2hvdWxkIG5ldmVyIGhhcHBlbgorICAgICAgICAgICAgICAgIHJldHVybiBwYXRoOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbGVuID0gYnl0ZXMubGVuZ3RoOworCisgICAgICAgICAgICAvLyBmb3IgZWFjaCBieXRlCisgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKyAgICAgICAgICAgICAgICBiID0gYnl0ZXNbaV07CisgICAgICAgICAgICAgICAgLy8gZm9yIG5vbi1hc2NpaSBjaGFyYWN0ZXI6IG1ha2UgaXQgcG9zaXRpdmUsIHRoZW4gZXNjYXBlCisgICAgICAgICAgICAgICAgaWYgKGIgPCAwKSB7CisgICAgICAgICAgICAgICAgICAgIGNoID0gYiArIDI1NjsKKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnJScpOworICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGdIZXhDaHNbY2ggPj4gNF0pOworICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGdIZXhDaHNbY2ggJiAweGZdKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZSBpZiAoZ05lZWRFc2NhcGluZ1tiXSkgeworICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCclJyk7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZ0FmdGVyRXNjYXBpbmcxW2JdKTsKKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnQWZ0ZXJFc2NhcGluZzJbYl0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgoY2hhciliKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7CisgICAgfQorCit9Ly9GaWxlUGF0aFRvVVJJCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9zdHJlYW0vU3RyZWFtUmVzdWx0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9zdHJlYW0vU3RyZWFtUmVzdWx0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTg1NjhhYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL3N0cmVhbS9TdHJlYW1SZXN1bHQuamF2YQpAQCAtMCwwICsxLDE5NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vICRJZDogU3RyZWFtUmVzdWx0LmphdmEgODI5OTcwIDIwMDktMTAtMjYgMjE6MTU6MjlaIG1yZ2xhdmFzICQKKworcGFja2FnZSBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbTsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLldyaXRlcjsKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdDsKKworLyoqCisgKiA8cD5BY3RzIGFzIGFuIGhvbGRlciBmb3IgYSB0cmFuc2Zvcm1hdGlvbiByZXN1bHQsCisgKiB3aGljaCBtYXkgYmUgWE1MLCBwbGFpbiBUZXh0LCBIVE1MLCBvciBzb21lIG90aGVyIGZvcm0gb2YgbWFya3VwLjwvcD4KKyAqCisgKiBAYXV0aG9yIDxhIGhyZWY9IkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgorICovCitwdWJsaWMgY2xhc3MgU3RyZWFtUmVzdWx0IGltcGxlbWVudHMgUmVzdWx0IHsKKworICAgIC8qKiBJZiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkjZ2V0RmVhdHVyZX0KKyAgICAgKiByZXR1cm5zIHRydWUgd2hlbiBwYXNzZWQgdGhpcyB2YWx1ZSBhcyBhbiBhcmd1bWVudCwKKyAgICAgKiB0aGUgVHJhbnNmb3JtZXIgc3VwcG9ydHMgUmVzdWx0IG91dHB1dCBvZiB0aGlzIHR5cGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRkVBVFVSRSA9CisgICAgICAgICJodHRwOi8vamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0L2ZlYXR1cmUiOworCisgICAgLyoqCisgICAgICogWmVyby1hcmd1bWVudCBkZWZhdWx0IGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBTdHJlYW1SZXN1bHQoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgU3RyZWFtUmVzdWx0IGZyb20gYSBieXRlIHN0cmVhbS4gIE5vcm1hbGx5LAorICAgICAqIGEgc3RyZWFtIHNob3VsZCBiZSB1c2VkIHJhdGhlciB0aGFuIGEgcmVhZGVyLCBzbyB0aGF0CisgICAgICogdGhlIHRyYW5zZm9ybWVyIG1heSB1c2UgaW5zdHJ1Y3Rpb25zIGNvbnRhaW5lZCBpbiB0aGUKKyAgICAgKiB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMgdG8gY29udHJvbCB0aGUgZW5jb2RpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0cHV0U3RyZWFtIEEgdmFsaWQgT3V0cHV0U3RyZWFtIHJlZmVyZW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyZWFtUmVzdWx0KE91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0pIHsKKyAgICAgICAgc2V0T3V0cHV0U3RyZWFtKG91dHB1dFN0cmVhbSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgU3RyZWFtUmVzdWx0IGZyb20gYSBjaGFyYWN0ZXIgc3RyZWFtLiAgTm9ybWFsbHksCisgICAgICogYSBzdHJlYW0gc2hvdWxkIGJlIHVzZWQgcmF0aGVyIHRoYW4gYSByZWFkZXIsIHNvIHRoYXQKKyAgICAgKiB0aGUgdHJhbnNmb3JtZXIgbWF5IHVzZSBpbnN0cnVjdGlvbnMgY29udGFpbmVkIGluIHRoZQorICAgICAqIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucyB0byBjb250cm9sIHRoZSBlbmNvZGluZy4gIEhvd2V2ZXIsCisgICAgICogdGhlcmUgYXJlIHRpbWVzIHdoZW4gaXQgaXMgdXNlZnVsIHRvIHdyaXRlIHRvIGEgY2hhcmFjdGVyCisgICAgICogc3RyZWFtLCBzdWNoIGFzIHdoZW4gdXNpbmcgYSBTdHJpbmdXcml0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gd3JpdGVyICBBIHZhbGlkIFdyaXRlciByZWZlcmVuY2UuCisgICAgICovCisgICAgcHVibGljIFN0cmVhbVJlc3VsdChXcml0ZXIgd3JpdGVyKSB7CisgICAgICAgIHNldFdyaXRlcih3cml0ZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIFN0cmVhbVJlc3VsdCBmcm9tIGEgVVJMLgorICAgICAqCisgICAgICogQHBhcmFtIHN5c3RlbUlkIE11c3QgYmUgYSBTdHJpbmcgdGhhdCBjb25mb3JtcyB0byB0aGUgVVJJIHN5bnRheC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyZWFtUmVzdWx0KFN0cmluZyBzeXN0ZW1JZCkgeworICAgICAgICB0aGlzLnN5c3RlbUlkID0gc3lzdGVtSWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgU3RyZWFtUmVzdWx0IGZyb20gYSBGaWxlLgorICAgICAqCisgICAgICogQHBhcmFtIGYgTXVzdCBhIG5vbi1udWxsIEZpbGUgcmVmZXJlbmNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJlYW1SZXN1bHQoRmlsZSBmKSB7CisgICAgICAgIHNldFN5c3RlbUlkKGYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgQnl0ZVN0cmVhbSB0aGF0IGlzIHRvIGJlIHdyaXR0ZW4gdG8uICBOb3JtYWxseSwKKyAgICAgKiBhIHN0cmVhbSBzaG91bGQgYmUgdXNlZCByYXRoZXIgdGhhbiBhIHJlYWRlciwgc28gdGhhdAorICAgICAqIHRoZSB0cmFuc2Zvcm1lciBtYXkgdXNlIGluc3RydWN0aW9ucyBjb250YWluZWQgaW4gdGhlCisgICAgICogdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zIHRvIGNvbnRyb2wgdGhlIGVuY29kaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIG91dHB1dFN0cmVhbSBBIHZhbGlkIE91dHB1dFN0cmVhbSByZWZlcmVuY2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0T3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0pIHsKKyAgICAgICAgdGhpcy5vdXRwdXRTdHJlYW0gPSBvdXRwdXRTdHJlYW07CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBieXRlIHN0cmVhbSB0aGF0IHdhcyBzZXQgd2l0aCBzZXRPdXRwdXRTdHJlYW0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBieXRlIHN0cmVhbSB0aGF0IHdhcyBzZXQgd2l0aCBzZXRPdXRwdXRTdHJlYW0sIG9yIG51bGwKKyAgICAgKiBpZiBzZXRPdXRwdXRTdHJlYW0gb3IgdGhlIEJ5dGVTdHJlYW0gY29uc3RydWN0b3Igd2FzIG5vdCBjYWxsZWQuCisgICAgICovCisgICAgcHVibGljIE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKSB7CisgICAgICAgIHJldHVybiBvdXRwdXRTdHJlYW07CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSB3cml0ZXIgdGhhdCBpcyB0byByZWNlaXZlIHRoZSByZXN1bHQuICBOb3JtYWxseSwKKyAgICAgKiBhIHN0cmVhbSBzaG91bGQgYmUgdXNlZCByYXRoZXIgdGhhbiBhIHdyaXRlciwgc28gdGhhdAorICAgICAqIHRoZSB0cmFuc2Zvcm1lciBtYXkgdXNlIGluc3RydWN0aW9ucyBjb250YWluZWQgaW4gdGhlCisgICAgICogdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zIHRvIGNvbnRyb2wgdGhlIGVuY29kaW5nLiAgSG93ZXZlciwKKyAgICAgKiB0aGVyZSBhcmUgdGltZXMgd2hlbiBpdCBpcyB1c2VmdWwgdG8gd3JpdGUgdG8gYSB3cml0ZXIsCisgICAgICogc3VjaCBhcyB3aGVuIHVzaW5nIGEgU3RyaW5nV3JpdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHdyaXRlciAgQSB2YWxpZCBXcml0ZXIgcmVmZXJlbmNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFdyaXRlcihXcml0ZXIgd3JpdGVyKSB7CisgICAgICAgIHRoaXMud3JpdGVyID0gd3JpdGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgY2hhcmFjdGVyIHN0cmVhbSB0aGF0IHdhcyBzZXQgd2l0aCBzZXRXcml0ZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBjaGFyYWN0ZXIgc3RyZWFtIHRoYXQgd2FzIHNldCB3aXRoIHNldFdyaXRlciwgb3IgbnVsbAorICAgICAqIGlmIHNldFdyaXRlciBvciB0aGUgV3JpdGVyIGNvbnN0cnVjdG9yIHdhcyBub3QgY2FsbGVkLgorICAgICAqLworICAgIHB1YmxpYyBXcml0ZXIgZ2V0V3JpdGVyKCkgeworICAgICAgICByZXR1cm4gd3JpdGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgc3lzdGVtSUQgdGhhdCBtYXkgYmUgdXNlZCBpbiBhc3NvY2lhdGlvbgorICAgICAqIHdpdGggdGhlIGJ5dGUgb3IgY2hhcmFjdGVyIHN0cmVhbSwgb3IsIGlmIG5laXRoZXIgaXMgc2V0LCB1c2UKKyAgICAgKiB0aGlzIHZhbHVlIGFzIGEgd3JpdGVhYmxlIFVSSSAocHJvYmFibHkgYSBmaWxlIG5hbWUpLgorICAgICAqCisgICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBhcyBhIFVSSSBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3lzdGVtSWQoU3RyaW5nIHN5c3RlbUlkKSB7CisgICAgICAgIHRoaXMuc3lzdGVtSWQgPSBzeXN0ZW1JZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5TZXQgdGhlIHN5c3RlbSBJRCBmcm9tIGEgPGNvZGU+RmlsZTwvY29kZT4gcmVmZXJlbmNlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhlIHVzZSBvZiB7QGxpbmsgRmlsZSN0b1VSSSgpfSBhbmQge0BsaW5rIEZpbGUjdG9VUkwoKX0uCisgICAgICogPGNvZGU+dG9VUkkoKTwvY29kZT4gaXMgcHJlZmVycmVkIGFuZCB1c2VkIGlmIHBvc3NpYmxlLgorICAgICAqIFRvIGFsbG93IEpBWFAgMS4zIHRvIHJ1biBvbiBKMlNFIDEuMywgPGNvZGU+dG9VUkwoKTwvY29kZT4KKyAgICAgKiBpcyB1c2VkIGlmIGEge0BsaW5rIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbn0gaXMgdGhyb3duIGJ5IHRoZSBhdHRlbXB0CisgICAgICogdG8gdXNlIDxjb2RlPnRvVVJJKCk8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmIE11c3QgYSBub24tbnVsbCBGaWxlIHJlZmVyZW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChGaWxlIGYpIHsKKyAgICAgICAgdGhpcy5zeXN0ZW1JZCA9IEZpbGVQYXRoVG9VUkkuZmlsZXBhdGgyVVJJKGYuZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgdGhhdCB3YXMgc2V0IHdpdGggc2V0U3lzdGVtSWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllciB0aGF0IHdhcyBzZXQgd2l0aCBzZXRTeXN0ZW1JZCwgb3IgbnVsbAorICAgICAqIGlmIHNldFN5c3RlbUlkIHdhcyBub3QgY2FsbGVkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7CisgICAgICAgIHJldHVybiBzeXN0ZW1JZDsKKyAgICB9CisKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gSW50ZXJuYWwgc3RhdGUuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisgICAgLyoqCisgICAgICogVGhlIHN5c3RlbUlEIHRoYXQgbWF5IGJlIHVzZWQgaW4gYXNzb2NpYXRpb24KKyAgICAgKiB3aXRoIHRoZSBieXRlIG9yIGNoYXJhY3RlciBzdHJlYW0sIG9yLCBpZiBuZWl0aGVyIGlzIHNldCwgdXNlCisgICAgICogdGhpcyB2YWx1ZSBhcyBhIHdyaXRlYWJsZSBVUkkgKHByb2JhYmx5IGEgZmlsZSBuYW1lKS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBzeXN0ZW1JZDsKKworICAgIC8qKgorICAgICAqIFRoZSBieXRlIHN0cmVhbSB0aGF0IGlzIHRvIGJlIHdyaXR0ZW4gdG8uCisgICAgICovCisgICAgcHJpdmF0ZSBPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtOworCisgICAgLyoqCisgICAgICogVGhlIGNoYXJhY3RlciBzdHJlYW0gdGhhdCBpcyB0byBiZSB3cml0dGVuIHRvLgorICAgICAqLworICAgIHByaXZhdGUgV3JpdGVyIHdyaXRlcjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL3N0cmVhbS9TdHJlYW1Tb3VyY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdHJhbnNmb3JtL3N0cmVhbS9TdHJlYW1Tb3VyY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZDk2Y2MwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vc3RyZWFtL1N0cmVhbVNvdXJjZS5qYXZhCkBAIC0wLDAgKzEsMjcyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8gJElkOiBTdHJlYW1Tb3VyY2UuamF2YSA4Mjk5NzEgMjAwOS0xMC0yNiAyMToxNTozOVogbXJnbGF2YXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7CisKKy8qKgorICogPHA+QWN0cyBhcyBhbiBob2xkZXIgZm9yIGEgdHJhbnNmb3JtYXRpb24gU291cmNlIGluIHRoZSBmb3JtCisgKiBvZiBhIHN0cmVhbSBvZiBYTUwgbWFya3VwLjwvcD4KKyAqCisgKiA8cD48ZW0+Tm90ZTo8L2VtPiBEdWUgdG8gdGhlaXIgaW50ZXJuYWwgdXNlIG9mIGVpdGhlciBhIHtAbGluayBSZWFkZXJ9IG9yIHtAbGluayBJbnB1dFN0cmVhbX0gaW5zdGFuY2UsCisgKiA8Y29kZT5TdHJlYW1Tb3VyY2U8L2NvZGU+IGluc3RhbmNlcyBtYXkgb25seSBiZSB1c2VkIG9uY2UuPC9wPgorICoKKyAqIEBhdXRob3IgPGEgaHJlZj0iSmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDgyOTk3MSAkLCAkRGF0ZTogMjAwOS0xMC0yNiAxNDoxNTozOSAtMDcwMCAoTW9uLCAyNiBPY3QgMjAwOSkgJAorICovCitwdWJsaWMgY2xhc3MgU3RyZWFtU291cmNlIGltcGxlbWVudHMgU291cmNlIHsKKworICAgIC8qKiBJZiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkjZ2V0RmVhdHVyZX0KKyAgICAgKiByZXR1cm5zIHRydWUgd2hlbiBwYXNzZWQgdGhpcyB2YWx1ZSBhcyBhbiBhcmd1bWVudCwKKyAgICAgKiB0aGUgVHJhbnNmb3JtZXIgc3VwcG9ydHMgU291cmNlIGlucHV0IG9mIHRoaXMgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGRUFUVVJFID0KKyAgICAgICAgImh0dHA6Ly9qYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2UvZmVhdHVyZSI7CisKKyAgICAvKioKKyAgICAgKiA8cD5aZXJvLWFyZ3VtZW50IGRlZmF1bHQgY29uc3RydWN0b3IuICBJZiB0aGlzIGNvbnN0cnVjdG9yIGlzIHVzZWQsIGFuZAorICAgICAqIG5vIFN0cmVhbSBzb3VyY2UgaXMgc2V0IHVzaW5nCisgICAgICoge0BsaW5rICNzZXRJbnB1dFN0cmVhbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0U3RyZWFtKX0gb3IKKyAgICAgKiB7QGxpbmsgI3NldFJlYWRlcihqYXZhLmlvLlJlYWRlciByZWFkZXIpfSwgdGhlbiB0aGUKKyAgICAgKiA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gd2lsbAorICAgICAqIGNyZWF0ZSBhbiBlbXB0eSBzb3VyY2Uge0BsaW5rIGphdmEuaW8uSW5wdXRTdHJlYW19IHVzaW5nCisgICAgICoge0BsaW5rIGphdmEuaW8uSW5wdXRTdHJlYW0jSW5wdXRTdHJlYW0oKSBuZXcgSW5wdXRTdHJlYW0oKX0uPC9wPgorICAgICAqCisgICAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyI3RyYW5zZm9ybShTb3VyY2UgeG1sU291cmNlLCBSZXN1bHQgb3V0cHV0VGFyZ2V0KQorICAgICAqLworICAgIHB1YmxpYyBTdHJlYW1Tb3VyY2UoKSB7IH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIFN0cmVhbVNvdXJjZSBmcm9tIGEgYnl0ZSBzdHJlYW0uICBOb3JtYWxseSwKKyAgICAgKiBhIHN0cmVhbSBzaG91bGQgYmUgdXNlZCByYXRoZXIgdGhhbiBhIHJlYWRlciwgc28KKyAgICAgKiB0aGUgWE1MIHBhcnNlciBjYW4gcmVzb2x2ZSBjaGFyYWN0ZXIgZW5jb2Rpbmcgc3BlY2lmaWVkCisgICAgICogYnkgdGhlIFhNTCBkZWNsYXJhdGlvbi4KKyAgICAgKgorICAgICAqIDxwPklmIHRoaXMgY29uc3RydWN0b3IgaXMgdXNlZCB0byBwcm9jZXNzIGEgc3R5bGVzaGVldCwgbm9ybWFsbHkKKyAgICAgKiBzZXRTeXN0ZW1JZCBzaG91bGQgYWxzbyBiZSBjYWxsZWQsIHNvIHRoYXQgcmVsYXRpdmUgVVJJIHJlZmVyZW5jZXMKKyAgICAgKiBjYW4gYmUgcmVzb2x2ZWQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0U3RyZWFtIEEgdmFsaWQgSW5wdXRTdHJlYW0gcmVmZXJlbmNlIHRvIGFuIFhNTCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIFN0cmVhbVNvdXJjZShJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSkgeworICAgICAgICBzZXRJbnB1dFN0cmVhbShpbnB1dFN0cmVhbSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgU3RyZWFtU291cmNlIGZyb20gYSBieXRlIHN0cmVhbS4gIE5vcm1hbGx5LAorICAgICAqIGEgc3RyZWFtIHNob3VsZCBiZSB1c2VkIHJhdGhlciB0aGFuIGEgcmVhZGVyLCBzbyB0aGF0CisgICAgICogdGhlIFhNTCBwYXJzZXIgY2FuIHJlc29sdmUgY2hhcmFjdGVyIGVuY29kaW5nIHNwZWNpZmllZAorICAgICAqIGJ5IHRoZSBYTUwgZGVjbGFyYXRpb24uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGNvbnN0cnVjdG9yIGFsbG93cyB0aGUgc3lzdGVtSUQgdG8gYmUgc2V0IGluIGFkZGl0aW9uCisgICAgICogdG8gdGhlIGlucHV0IHN0cmVhbSwgd2hpY2ggYWxsb3dzIHJlbGF0aXZlIFVSSXMKKyAgICAgKiB0byBiZSBwcm9jZXNzZWQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0U3RyZWFtIEEgdmFsaWQgSW5wdXRTdHJlYW0gcmVmZXJlbmNlIHRvIGFuIFhNTCBzdHJlYW0uCisgICAgICogQHBhcmFtIHN5c3RlbUlkIE11c3QgYmUgYSBTdHJpbmcgdGhhdCBjb25mb3JtcyB0byB0aGUgVVJJIHN5bnRheC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyZWFtU291cmNlKElucHV0U3RyZWFtIGlucHV0U3RyZWFtLCBTdHJpbmcgc3lzdGVtSWQpIHsKKyAgICAgICAgc2V0SW5wdXRTdHJlYW0oaW5wdXRTdHJlYW0pOworICAgICAgICBzZXRTeXN0ZW1JZChzeXN0ZW1JZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgU3RyZWFtU291cmNlIGZyb20gYSBjaGFyYWN0ZXIgcmVhZGVyLiAgTm9ybWFsbHksCisgICAgICogYSBzdHJlYW0gc2hvdWxkIGJlIHVzZWQgcmF0aGVyIHRoYW4gYSByZWFkZXIsIHNvIHRoYXQKKyAgICAgKiB0aGUgWE1MIHBhcnNlciBjYW4gcmVzb2x2ZSBjaGFyYWN0ZXIgZW5jb2Rpbmcgc3BlY2lmaWVkCisgICAgICogYnkgdGhlIFhNTCBkZWNsYXJhdGlvbi4gIEhvd2V2ZXIsIGluIG1hbnkgY2FzZXMgdGhlIGVuY29kaW5nCisgICAgICogb2YgdGhlIGlucHV0IHN0cmVhbSBpcyBhbHJlYWR5IHJlc29sdmVkLCBhcyBpbiB0aGUgY2FzZSBvZgorICAgICAqIHJlYWRpbmcgWE1MIGZyb20gYSBTdHJpbmdSZWFkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhZGVyIEEgdmFsaWQgUmVhZGVyIHJlZmVyZW5jZSB0byBhbiBYTUwgY2hhcmFjdGVyIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyZWFtU291cmNlKFJlYWRlciByZWFkZXIpIHsKKyAgICAgICAgc2V0UmVhZGVyKHJlYWRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgU3RyZWFtU291cmNlIGZyb20gYSBjaGFyYWN0ZXIgcmVhZGVyLiAgTm9ybWFsbHksCisgICAgICogYSBzdHJlYW0gc2hvdWxkIGJlIHVzZWQgcmF0aGVyIHRoYW4gYSByZWFkZXIsIHNvIHRoYXQKKyAgICAgKiB0aGUgWE1MIHBhcnNlciBtYXkgcmVzb2x2ZSBjaGFyYWN0ZXIgZW5jb2Rpbmcgc3BlY2lmaWVkCisgICAgICogYnkgdGhlIFhNTCBkZWNsYXJhdGlvbi4gIEhvd2V2ZXIsIGluIG1hbnkgY2FzZXMgdGhlIGVuY29kaW5nCisgICAgICogb2YgdGhlIGlucHV0IHN0cmVhbSBpcyBhbHJlYWR5IHJlc29sdmVkLCBhcyBpbiB0aGUgY2FzZSBvZgorICAgICAqIHJlYWRpbmcgWE1MIGZyb20gYSBTdHJpbmdSZWFkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhZGVyIEEgdmFsaWQgUmVhZGVyIHJlZmVyZW5jZSB0byBhbiBYTUwgY2hhcmFjdGVyIHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gc3lzdGVtSWQgTXVzdCBiZSBhIFN0cmluZyB0aGF0IGNvbmZvcm1zIHRvIHRoZSBVUkkgc3ludGF4LgorICAgICAqLworICAgIHB1YmxpYyBTdHJlYW1Tb3VyY2UoUmVhZGVyIHJlYWRlciwgU3RyaW5nIHN5c3RlbUlkKSB7CisgICAgICAgIHNldFJlYWRlcihyZWFkZXIpOworICAgICAgICBzZXRTeXN0ZW1JZChzeXN0ZW1JZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgU3RyZWFtU291cmNlIGZyb20gYSBVUkwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3lzdGVtSWQgTXVzdCBiZSBhIFN0cmluZyB0aGF0IGNvbmZvcm1zIHRvIHRoZSBVUkkgc3ludGF4LgorICAgICAqLworICAgIHB1YmxpYyBTdHJlYW1Tb3VyY2UoU3RyaW5nIHN5c3RlbUlkKSB7CisgICAgICAgIHRoaXMuc3lzdGVtSWQgPSBzeXN0ZW1JZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBTdHJlYW1Tb3VyY2UgZnJvbSBhIEZpbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZiBNdXN0IGEgbm9uLW51bGwgRmlsZSByZWZlcmVuY2UuCisgICAgICovCisgICAgcHVibGljIFN0cmVhbVNvdXJjZShGaWxlIGYpIHsKKyAgICAgICAgc2V0U3lzdGVtSWQoZik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBieXRlIHN0cmVhbSB0byBiZSB1c2VkIGFzIGlucHV0LiAgTm9ybWFsbHksCisgICAgICogYSBzdHJlYW0gc2hvdWxkIGJlIHVzZWQgcmF0aGVyIHRoYW4gYSByZWFkZXIsIHNvIHRoYXQKKyAgICAgKiB0aGUgWE1MIHBhcnNlciBjYW4gcmVzb2x2ZSBjaGFyYWN0ZXIgZW5jb2Rpbmcgc3BlY2lmaWVkCisgICAgICogYnkgdGhlIFhNTCBkZWNsYXJhdGlvbi4KKyAgICAgKgorICAgICAqIDxwPklmIHRoaXMgU291cmNlIG9iamVjdCBpcyB1c2VkIHRvIHByb2Nlc3MgYSBzdHlsZXNoZWV0LCBub3JtYWxseQorICAgICAqIHNldFN5c3RlbUlkIHNob3VsZCBhbHNvIGJlIGNhbGxlZCwgc28gdGhhdCByZWxhdGl2ZSBVUkwgcmVmZXJlbmNlcworICAgICAqIGNhbiBiZSByZXNvbHZlZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXRTdHJlYW0gQSB2YWxpZCBJbnB1dFN0cmVhbSByZWZlcmVuY2UgdG8gYW4gWE1MIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSkgeworICAgICAgICB0aGlzLmlucHV0U3RyZWFtID0gaW5wdXRTdHJlYW07CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBieXRlIHN0cmVhbSB0aGF0IHdhcyBzZXQgd2l0aCBzZXRCeXRlU3RyZWFtLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgYnl0ZSBzdHJlYW0gdGhhdCB3YXMgc2V0IHdpdGggc2V0Qnl0ZVN0cmVhbSwgb3IgbnVsbAorICAgICAqIGlmIHNldEJ5dGVTdHJlYW0gb3IgdGhlIEJ5dGVTdHJlYW0gY29uc3RydWN0b3Igd2FzIG5vdCBjYWxsZWQuCisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgeworICAgICAgICByZXR1cm4gaW5wdXRTdHJlYW07CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBpbnB1dCB0byBiZSBhIGNoYXJhY3RlciByZWFkZXIuICBOb3JtYWxseSwKKyAgICAgKiBhIHN0cmVhbSBzaG91bGQgYmUgdXNlZCByYXRoZXIgdGhhbiBhIHJlYWRlciwgc28gdGhhdAorICAgICAqIHRoZSBYTUwgcGFyc2VyIGNhbiByZXNvbHZlIGNoYXJhY3RlciBlbmNvZGluZyBzcGVjaWZpZWQKKyAgICAgKiBieSB0aGUgWE1MIGRlY2xhcmF0aW9uLiAgSG93ZXZlciwgaW4gbWFueSBjYXNlcyB0aGUgZW5jb2RpbmcKKyAgICAgKiBvZiB0aGUgaW5wdXQgc3RyZWFtIGlzIGFscmVhZHkgcmVzb2x2ZWQsIGFzIGluIHRoZSBjYXNlIG9mCisgICAgICogcmVhZGluZyBYTUwgZnJvbSBhIFN0cmluZ1JlYWRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFkZXIgQSB2YWxpZCBSZWFkZXIgcmVmZXJlbmNlIHRvIGFuIFhNTCBDaGFyYWN0ZXJTdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmVhZGVyKFJlYWRlciByZWFkZXIpIHsKKyAgICAgICAgdGhpcy5yZWFkZXIgPSByZWFkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBjaGFyYWN0ZXIgc3RyZWFtIHRoYXQgd2FzIHNldCB3aXRoIHNldFJlYWRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIGNoYXJhY3RlciBzdHJlYW0gdGhhdCB3YXMgc2V0IHdpdGggc2V0UmVhZGVyLCBvciBudWxsCisgICAgICogaWYgc2V0UmVhZGVyIG9yIHRoZSBSZWFkZXIgY29uc3RydWN0b3Igd2FzIG5vdCBjYWxsZWQuCisgICAgICovCisgICAgcHVibGljIFJlYWRlciBnZXRSZWFkZXIoKSB7CisgICAgICAgIHJldHVybiByZWFkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBwdWJsaWMgaWRlbnRpZmllciBmb3IgdGhpcyBTb3VyY2UuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcHVibGljIGlkZW50aWZpZXIgaXMgYWx3YXlzIG9wdGlvbmFsOiBpZiB0aGUgYXBwbGljYXRpb24KKyAgICAgKiB3cml0ZXIgaW5jbHVkZXMgb25lLCBpdCB3aWxsIGJlIHByb3ZpZGVkIGFzIHBhcnQgb2YgdGhlCisgICAgICogbG9jYXRpb24gaW5mb3JtYXRpb24uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBwdWJsaWMgaWRlbnRpZmllciBhcyBhIHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQdWJsaWNJZChTdHJpbmcgcHVibGljSWQpIHsKKyAgICAgICAgdGhpcy5wdWJsaWNJZCA9IHB1YmxpY0lkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgcHVibGljIGlkZW50aWZpZXIgdGhhdCB3YXMgc2V0IHdpdGggc2V0UHVibGljSWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBwdWJsaWMgaWRlbnRpZmllciB0aGF0IHdhcyBzZXQgd2l0aCBzZXRQdWJsaWNJZCwgb3IgbnVsbAorICAgICAqIGlmIHNldFB1YmxpY0lkIHdhcyBub3QgY2FsbGVkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKSB7CisgICAgICAgIHJldHVybiBwdWJsaWNJZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGlzIFNvdXJjZS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBvcHRpb25hbCBpZiB0aGVyZSBpcyBhIGJ5dGUgc3RyZWFtCisgICAgICogb3IgYSBjaGFyYWN0ZXIgc3RyZWFtLCBidXQgaXQgaXMgc3RpbGwgdXNlZnVsIHRvIHByb3ZpZGUgb25lLAorICAgICAqIHNpbmNlIHRoZSBhcHBsaWNhdGlvbiBjYW4gdXNlIGl0IHRvIHJlc29sdmUgcmVsYXRpdmUgVVJJcworICAgICAqIGFuZCBjYW4gaW5jbHVkZSBpdCBpbiBlcnJvciBtZXNzYWdlcyBhbmQgd2FybmluZ3MgKHRoZSBwYXJzZXIKKyAgICAgKiB3aWxsIGF0dGVtcHQgdG8gb3BlbiBhIGNvbm5lY3Rpb24gdG8gdGhlIFVSSSBvbmx5IGlmCisgICAgICogdGhlcmUgaXMgbm8gYnl0ZSBzdHJlYW0gb3IgY2hhcmFjdGVyIHN0cmVhbSBzcGVjaWZpZWQpLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgYXMgYSBVUkwgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCkgeworICAgICAgICB0aGlzLnN5c3RlbUlkID0gc3lzdGVtSWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBzeXN0ZW0gaWRlbnRpZmllciB0aGF0IHdhcyBzZXQgd2l0aCBzZXRTeXN0ZW1JZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIHN5c3RlbSBpZGVudGlmaWVyIHRoYXQgd2FzIHNldCB3aXRoIHNldFN5c3RlbUlkLCBvciBudWxsCisgICAgICogaWYgc2V0U3lzdGVtSWQgd2FzIG5vdCBjYWxsZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKKyAgICAgICAgcmV0dXJuIHN5c3RlbUlkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgc3lzdGVtIElEIGZyb20gYSBGaWxlIHJlZmVyZW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmIE11c3QgYSBub24tbnVsbCBGaWxlIHJlZmVyZW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChGaWxlIGYpIHsKKyAgICAgICAgdGhpcy5zeXN0ZW1JZCA9IEZpbGVQYXRoVG9VUkkuZmlsZXBhdGgyVVJJKGYuZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgIH0KKworICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBJbnRlcm5hbCBzdGF0ZS4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKyAgICAvKioKKyAgICAgKiBUaGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoaXMgaW5wdXQgc291cmNlLCBvciBudWxsLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHB1YmxpY0lkOworCisgICAgLyoqCisgICAgICogVGhlIHN5c3RlbSBpZGVudGlmaWVyIGFzIGEgVVJMIHN0cmluZywgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBzeXN0ZW1JZDsKKworICAgIC8qKgorICAgICAqIFRoZSBieXRlIHN0cmVhbSBmb3IgdGhpcyBTb3VyY2UsIG9yIG51bGwuCisgICAgICovCisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbTsKKworICAgIC8qKgorICAgICAqIFRoZSBjaGFyYWN0ZXIgc3RyZWFtIGZvciB0aGlzIFNvdXJjZSwgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFJlYWRlciByZWFkZXI7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3RyYW5zZm9ybS9zdHJlYW0vcGFja2FnZS5odG1sIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vc3RyZWFtL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZjU0YWJkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC90cmFuc2Zvcm0vc3RyZWFtL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDMwIEBACis8IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wIFRyYW5zaXRpb25hbC8vRU4iPgorPGh0bWw+Cis8aGVhZD4KKzxNRVRBIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04Ij4KKzx0aXRsZT5qYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbTwvdGl0bGU+Cis8L2hlYWQ+Cis8Ym9keT4KKzxwPlRoaXMgcGFja2FnZSBpbXBsZW1lbnRzIHN0cmVhbS0gYW5kIFVSSS0gc3BlY2lmaWMgdHJhbnNmb3JtYXRpb24gQVBJcy4KKwkgPC9wPgorPHA+VGhlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2V9IGNsYXNzCisJIHByb3ZpZGVzIG1ldGhvZHMgZm9yIHNwZWNpZnlpbmcge0BsaW5rIGphdmEuaW8uSW5wdXRTdHJlYW19IGlucHV0LAorCSB7QGxpbmsgamF2YS5pby5SZWFkZXJ9IGlucHV0LCBhbmQgVVJMIGlucHV0IGluIHRoZSBmb3JtIG9mIHN0cmluZ3MuIEV2ZW4KKwkgaWYgYW4gaW5wdXQgc3RyZWFtIG9yIHJlYWRlciBpcyBzcGVjaWZpZWQgYXMgdGhlIHNvdXJjZSwKKwkge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZSNzZXRTeXN0ZW1JZH0gc2hvdWxkIHN0aWxsCisJIGJlIGNhbGxlZCwgc28gdGhhdCB0aGUgdHJhbnNmb3JtZXIgY2FuIGtub3cgZnJvbSB3aGVyZSBpdCBzaG91bGQgcmVzb2x2ZQorCSByZWxhdGl2ZSBVUklzLiBUaGUgcHVibGljIGlkZW50aWZpZXIgaXMgYWx3YXlzIG9wdGlvbmFsOiBpZiB0aGUgYXBwbGljYXRpb24KKwkgd3JpdGVyIGluY2x1ZGVzIG9uZSwgaXQgd2lsbCBiZSBwcm92aWRlZCBhcyBwYXJ0IG9mIHRoZQorCSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yfSBpbmZvcm1hdGlvbi48L3A+Cis8cD5UaGUge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVJlc3VsdH0gY2xhc3MKKwkgcHJvdmlkZXMgbWV0aG9kcyBmb3Igc3BlY2lmeWluZyB7QGxpbmsgamF2YS5pby5PdXRwdXRTdHJlYW19LAorCSB7QGxpbmsgamF2YS5pby5Xcml0ZXJ9LCBvciBhbiBvdXRwdXQgc3lzdGVtIElELCBhcyB0aGUgb3V0cHV0IG9mIHRoZQorCSB0cmFuc2Zvcm1hdGlvbiByZXN1bHQuPC9wPgorPHA+Tm9ybWFsbHkgc3RyZWFtcyBzaG91bGQgYmUgdXNlZCByYXRoZXIgdGhhbiByZWFkZXJzIG9yIHdyaXRlcnMsIGZvcgorCSBib3RoIHRoZSBTb3VyY2UgYW5kIFJlc3VsdCwgc2luY2UgcmVhZGVycyBhbmQgd3JpdGVycyBhbHJlYWR5IGhhdmUgdGhlIGVuY29kaW5nCisJIGVzdGFibGlzaGVkIHRvIGFuZCBmcm9tIHRoZSBpbnRlcm5hbCBVbmljb2RlIGZvcm1hdC4gSG93ZXZlciwgdGhlcmUgYXJlIHRpbWVzCisJIHdoZW4gaXQgaXMgdXNlZnVsIHRvIHdyaXRlIHRvIGEgY2hhcmFjdGVyIHN0cmVhbSwgc3VjaCBhcyB3aGVuIHVzaW5nIGEKKwkgU3RyaW5nV3JpdGVyIGluIG9yZGVyIHRvIHdyaXRlIHRvIGEgU3RyaW5nLCBvciBpbiB0aGUgY2FzZSBvZiByZWFkaW5nIHNvdXJjZQorCSBYTUwgZnJvbSBhIFN0cmluZ1JlYWRlci48L3A+Cis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3ZhbGlkYXRpb24vU2NoZW1hLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3ZhbGlkYXRpb24vU2NoZW1hLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2RkNGJhNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdmFsaWRhdGlvbi9TY2hlbWEuamF2YQpAQCAtMCwwICsxLDkyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLy8gJElkOiBTY2hlbWEuamF2YSA0NDY1OTggMjAwNi0wOS0xNSAxMjo1NTo0MFogamVyZW1pYXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC52YWxpZGF0aW9uOworCisvKioKKyAqIEltbXV0YWJsZSBpbi1tZW1vcnkgcmVwcmVzZW50YXRpb24gb2YgZ3JhbW1hci4KKyAqCisgKiA8cD4KKyAqIFRoaXMgb2JqZWN0IHJlcHJlc2VudHMgYSBzZXQgb2YgY29uc3RyYWludHMgdGhhdCBjYW4gYmUgY2hlY2tlZC8KKyAqIGVuZm9yY2VkIGFnYWluc3QgYW4gWE1MIGRvY3VtZW50LgorICoKKyAqIDxwPgorICogQSB7QGxpbmsgU2NoZW1hfSBvYmplY3QgaXMgdGhyZWFkIHNhZmUgYW5kIGFwcGxpY2F0aW9ucyBhcmUKKyAqIGVuY291cmFnZWQgdG8gc2hhcmUgaXQgYWNyb3NzIG1hbnkgcGFyc2VycyBpbiBtYW55IHRocmVhZHMuCisgKgorICogPHA+CisgKiBBIHtAbGluayBTY2hlbWF9IG9iamVjdCBpcyBpbW11dGFibGUgaW4gdGhlIHNlbnNlIHRoYXQgaXQgc2hvdWxkbid0CisgKiBjaGFuZ2UgdGhlIHNldCBvZiBjb25zdHJhaW50cyBvbmNlIGl0IGlzIGNyZWF0ZWQuIEluIG90aGVyIHdvcmRzLAorICogaWYgYW4gYXBwbGljYXRpb24gdmFsaWRhdGVzIHRoZSBzYW1lIGRvY3VtZW50IHR3aWNlIGFnYWluc3QgdGhlIHNhbWUKKyAqIHtAbGluayBTY2hlbWF9LCBpdCBtdXN0IGFsd2F5cyBwcm9kdWNlIHRoZSBzYW1lIHJlc3VsdC4KKyAqCisgKiA8cD4KKyAqIEEge0BsaW5rIFNjaGVtYX0gb2JqZWN0IGlzIHVzdWFsbHkgY3JlYXRlZCBmcm9tIHtAbGluayBTY2hlbWFGYWN0b3J5fS4KKyAqCisgKiA8cD4KKyAqIFR3byBraW5kcyBvZiB2YWxpZGF0b3JzIGNhbiBiZSBjcmVhdGVkIGZyb20gYSB7QGxpbmsgU2NoZW1hfSBvYmplY3QuCisgKiBPbmUgaXMge0BsaW5rIFZhbGlkYXRvcn0sIHdoaWNoIHByb3ZpZGVzIGhpZ2hseS1sZXZlbCB2YWxpZGF0aW9uCisgKiBvcGVyYXRpb25zIHRoYXQgY292ZXIgdHlwaWNhbCB1c2UgY2FzZXMuIFRoZSBvdGhlciBpcworICoge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9LCB3aGljaCB3b3JrcyBvbiB0b3Agb2YgU0FYIGZvciBiZXR0ZXIKKyAqIG1vZHVsYXJpdHkuCisgKgorICogPHA+CisgKiBUaGlzIHNwZWNpZmljYXRpb24gZG9lcyBub3QgcmVmaW5lCisgKiB0aGUge0BsaW5rIGphdmEubGFuZy5PYmplY3QjZXF1YWxzKGphdmEubGFuZy5PYmplY3QpfSBtZXRob2QuCisgKiBJbiBvdGhlciB3b3JkcywgaWYgeW91IHBhcnNlIHRoZSBzYW1lIHNjaGVtYSB0d2ljZSwgeW91IG1heQorICogc3RpbGwgZ2V0IDxjb2RlPiFzY2hlbWFBLmVxdWFscyhzY2hlbWFCKTwvY29kZT4uCisgKgorICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86S29oc3VrZS5LYXdhZ3VjaGlAU3VuLmNvbSI+S29oc3VrZSBLYXdhZ3VjaGk8L2E+CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDQ0NjU5OCAkLCAkRGF0ZTogMjAwNi0wOS0xNSAwNTo1NTo0MCAtMDcwMCAoRnJpLCAxNSBTZXAgMjAwNikgJAorICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMS8iPlhNTCBTY2hlbWEgUGFydCAxOiBTdHJ1Y3R1cmVzPC9hPgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWwxMS8iPkV4dGVuc2libGUgTWFya3VwIExhbmd1YWdlIChYTUwpIDEuMTwvYT4KKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCI+RXh0ZW5zaWJsZSBNYXJrdXAgTGFuZ3VhZ2UgKFhNTCkgMS4wIChTZWNvbmQgRWRpdGlvbik8L2E+CisgKiBAc2luY2UgMS41CisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTY2hlbWEgeworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgZm9yIHRoZSBkZXJpdmVkIGNsYXNzLgorICAgICAqCisgICAgICogPHA+CisgICAgICogVGhlIGNvbnN0cnVjdG9yIGRvZXMgbm90aGluZy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU2NoZW1hKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcge0BsaW5rIFZhbGlkYXRvcn0gZm9yIHRoaXMge0BsaW5rIFNjaGVtYX0uCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBBIHZhbGlkYXRvciBlbmZvcmNlcy9jaGVja3MgdGhlIHNldCBvZiBjb25zdHJhaW50cyB0aGlzIG9iamVjdAorICAgICAqIHJlcHJlc2VudHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICBBbHdheXMgcmV0dXJuIGEgbm9uLW51bGwgdmFsaWQgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBWYWxpZGF0b3IgbmV3VmFsaWRhdG9yKCk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSBmb3IgdGhpcyB7QGxpbmsgU2NoZW1hfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4KKyAgICAgKiAgICAgIEFsd2F5cyByZXR1cm4gYSBub24tbnVsbCB2YWxpZCBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFZhbGlkYXRvckhhbmRsZXIgbmV3VmFsaWRhdG9ySGFuZGxlcigpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC92YWxpZGF0aW9uL1NjaGVtYUZhY3RvcnkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdmFsaWRhdGlvbi9TY2hlbWFGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjNlNDc5OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdmFsaWRhdGlvbi9TY2hlbWFGYWN0b3J5LmphdmEKQEAgLTAsMCArMSw2NzIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvLyAkSWQ6IFNjaGVtYUZhY3RvcnkuamF2YSA4ODQ5NTIgMjAwOS0xMS0yNyAxODo1NTowOFogbXJnbGF2YXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC52YWxpZGF0aW9uOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7CitpbXBvcnQgb3JnLnczYy5kb20ubHMuTFNSZXNvdXJjZVJlc29sdmVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247CisKKy8qKgorICogRmFjdG9yeSB0aGF0IGNyZWF0ZXMge0BsaW5rIFNjaGVtYX0gb2JqZWN0cyYjeDJFOyBFbnRyeS1wb2ludCB0bworICogdGhlIHZhbGlkYXRpb24gQVBJLgorICoKKyAqIDxwPgorICoge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IGlzIGEgc2NoZW1hIGNvbXBpbGVyLiBJdCByZWFkcyBleHRlcm5hbAorICogcmVwcmVzZW50YXRpb25zIG9mIHNjaGVtYXMgYW5kIHByZXBhcmVzIHRoZW0gZm9yIHZhbGlkYXRpb24uCisgKgorICogPHA+CisgKiBUaGUge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IGNsYXNzIGlzIG5vdCB0aHJlYWQtc2FmZS4gSW4gb3RoZXIgd29yZHMsCisgKiBpdCBpcyB0aGUgYXBwbGljYXRpb24ncyByZXNwb25zaWJpbGl0eSB0byBlbnN1cmUgdGhhdCBhdCBtb3N0CisgKiBvbmUgdGhyZWFkIGlzIHVzaW5nIGEge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IG9iamVjdCBhdCBhbnkKKyAqIGdpdmVuIG1vbWVudC4gSW1wbGVtZW50YXRpb25zIGFyZSBlbmNvdXJhZ2VkIHRvIG1hcmsgbWV0aG9kcworICogYXMgPHR0PnN5bmNocm9uaXplZDwvdHQ+IHRvIHByb3RlY3QgdGhlbXNlbHZlcyBmcm9tIGJyb2tlbiBjbGllbnRzLgorICoKKyAqIDxwPgorICoge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IGlzIG5vdCByZS1lbnRyYW50LiBXaGlsZSBvbmUgb2YgdGhlCisgKiA8Y29kZT5uZXdTY2hlbWE8L2NvZGU+IG1ldGhvZHMgaXMgYmVpbmcgaW52b2tlZCwgYXBwbGljYXRpb25zCisgKiBtYXkgbm90IGF0dGVtcHQgdG8gcmVjdXJzaXZlbHkgaW52b2tlIHRoZSA8Y29kZT5uZXdTY2hlbWE8L2NvZGU+IG1ldGhvZCwKKyAqIGV2ZW4gZnJvbSB0aGUgc2FtZSB0aHJlYWQuCisgKgorICogPGgyPjxhIG5hbWU9InNjaGVtYUxhbmd1YWdlIj48L2E+U2NoZW1hIExhbmd1YWdlPC9oMj4KKyAqIDxwPgorICogVGhpcyBzcGVjIHVzZXMgYSBuYW1lc3BhY2UgVVJJIHRvIGRlc2lnbmF0ZSBhIHNjaGVtYSBsYW5ndWFnZS4KKyAqIFRoZSBmb2xsb3dpbmcgdGFibGUgc2hvd3MgdGhlIHZhbHVlcyBkZWZpbmVkIGJ5IHRoaXMgc3BlY2lmaWNhdGlvbi4KKyAqIDxwPgorICogVG8gYmUgY29tcGxpYW50IHdpdGggdGhlIHNwZWMsIHRoZSBpbXBsZW1lbnRhdGlvbgorICogaXMgb25seSByZXF1aXJlZCB0byBzdXBwb3J0IFczQyBYTUwgU2NoZW1hIDEuMC4gSG93ZXZlciwKKyAqIGlmIGl0IGNob29zZXMgdG8gc3VwcG9ydCBvdGhlciBzY2hlbWEgbGFuZ3VhZ2VzIGxpc3RlZCBoZXJlLAorICogaXQgbXVzdCBjb25mb3JtIHRvIHRoZSByZWxldmFudCBiZWhhdmlvcnMgZGVzY3JpYmVkIGluIHRoaXMgc3BlYy4KKyAqCisgKiA8cD4KKyAqIFNjaGVtYSBsYW5ndWFnZXMgbm90IGxpc3RlZCBoZXJlIGFyZSBleHBlY3RlZCB0bworICogaW50cm9kdWNlIHRoZWlyIG93biBVUklzIHRvIHJlcHJlc2VudCB0aGVtc2VsdmVzLgorICogVGhlIHtAbGluayBTY2hlbWFGYWN0b3J5fSBjbGFzcyBpcyBjYXBhYmxlIG9mIGxvY2F0aW5nIG90aGVyCisgKiBpbXBsZW1lbnRhdGlvbnMgZm9yIG90aGVyIHNjaGVtYSBsYW5ndWFnZXMgYXQgcnVuLXRpbWUuCisgKgorICogPHA+CisgKiBOb3RlIHRoYXQgYmVjYXVzZSB0aGUgWE1MIERURCBpcyBzdHJvbmdseSB0aWVkIHRvIHRoZSBwYXJzaW5nIHByb2Nlc3MKKyAqIGFuZCBoYXMgYSBzaWduaWZpY2FudCBlZmZlY3Qgb24gdGhlIHBhcnNpbmcgcHJvY2VzcywgaXQgaXMgaW1wb3NzaWJsZQorICogdG8gZGVmaW5lIHRoZSBEVEQgdmFsaWRhdGlvbiBhcyBhIHByb2Nlc3MgaW5kZXBlbmRlbnQgZnJvbSBwYXJzaW5nLgorICogRm9yIHRoaXMgcmVhc29uLCB0aGlzIHNwZWNpZmljYXRpb24gZG9lcyBub3QgZGVmaW5lIHRoZSBzZW1hbnRpY3MgZm9yCisgKiB0aGUgWE1MIERURC4gVGhpcyBkb2Vzbid0IHByb2hpYml0IGltcGxlbWVudGVycyBmcm9tIGltcGxlbWVudGluZyBpdAorICogaW4gYSB3YXkgdGhleSBzZWUgZml0LCBidXQgPGVtPnVzZXJzIGFyZSB3YXJuZWQgdGhhdCBhbnkgRFRECisgKiB2YWxpZGF0aW9uIGltcGxlbWVudGVkIG9uIHRoaXMgaW50ZXJmYWNlIG5lY2Vzc2FyaWx5IGRldmlhdGUgZnJvbQorICogdGhlIFhNTCBEVEQgc2VtYW50aWNzIGFzIGRlZmluZWQgaW4gdGhlIFhNTCAxLjA8L2VtPi4KKyAqCisgKiA8dGFibGUgYm9yZGVyPSIxIiBjZWxscGFkZGluZz0iMiI+CisgKiAgIDx0aGVhZD4KKyAqICAgICA8dHI+CisgKiAgICAgICA8dGg+dmFsdWU8L3RoPgorICogICAgICAgPHRoPmxhbmd1YWdlPC90aD4KKyAqICAgICA8L3RyPgorICogICA8L3RoZWFkPgorICogICA8dGJvZHk+CisgKiAgICAgPHRyPgorICogICAgICAgPHRkPntAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI1czQ19YTUxfU0NIRU1BX05TX1VSSX0gKCI8Y29kZT5odHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYTwvY29kZT4iKTwvdGQ+CisgKiAgICAgICA8dGQ+PGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTEiPlczQyBYTUwgU2NoZW1hIDEuMDwvYT48L3RkPgorICogICAgIDwvdHI+CisgKiAgICAgPHRyPgorICogICAgICAgPHRkPntAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI1JFTEFYTkdfTlNfVVJJfSAoIjxjb2RlPmh0dHA6Ly9yZWxheG5nLm9yZy9ucy9zdHJ1Y3R1cmUvMS4wPC9jb2RlPiIpPC90ZD4KKyAqICAgICAgIDx0ZD48YSBocmVmPSJodHRwOi8vd3d3LnJlbGF4bmcub3JnLyI+UkVMQVggTkcgMS4wPC9hPjwvdGQ+CisgKiAgICAgPC90cj4KKyAqICAgPC90Ym9keT4KKyAqIDwvdGFibGU+CisgKgorICogQGF1dGhvciAgPGEgaHJlZj0ibWFpbHRvOktvaHN1a2UuS2F3YWd1Y2hpQFN1bi5jb20iPktvaHN1a2UgS2F3YWd1Y2hpPC9hPgorICogQHZlcnNpb24gJFJldmlzaW9uOiA4ODQ5NTIgJCwgJERhdGU6IDIwMDktMTEtMjcgMTA6NTU6MDggLTA4MDAgKEZyaSwgMjcgTm92IDIwMDkpICQKKyAqIEBzaW5jZSAxLjUKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFNjaGVtYUZhY3RvcnkgeworCisgICAgLyoqCisgICAgICogPHA+Q29uc3RydWN0b3IgZm9yIGRlcml2ZWQgY2xhc3Nlcy48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgY29uc3RydWN0b3IgZG9lcyBub3RoaW5nLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkRlcml2ZWQgY2xhc3NlcyBtdXN0IGNyZWF0ZSB7QGxpbmsgU2NoZW1hRmFjdG9yeX0gb2JqZWN0cyB0aGF0IGhhdmUKKyAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiB7QGxpbmsgRXJyb3JIYW5kbGVyfSBhbmQKKyAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfS48L3A+CisgICAgICovCisgICAgcHJvdGVjdGVkIFNjaGVtYUZhY3RvcnkoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+TG9va3VwIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZSA8Y29kZT5TY2hlbWFGYWN0b3J5PC9jb2RlPiB0aGF0IHN1cHBvcnRzIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBzY2hlbWEgbGFuZ3VhZ2UgYW5kIHJldHVybiBpdC48L3A+CisgICAgICoKKyAgICAgKiA8cD5UbyBmaW5kIGEgPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4gb2JqZWN0IGZvciBhIGdpdmVuIHNjaGVtYSBsYW5ndWFnZSwKKyAgICAgKiB0aGlzIG1ldGhvZCBsb29rcyB0aGUgZm9sbG93aW5nIHBsYWNlcyBpbiB0aGUgZm9sbG93aW5nIG9yZGVyCisgICAgICogd2hlcmUgInRoZSBjbGFzcyBsb2FkZXIiIHJlZmVycyB0byB0aGUgY29udGV4dCBjbGFzcyBsb2FkZXI6PC9wPgorICAgICAqIDxvbD4KKyAgICAgKiAgPGxpPgorICAgICAqICAgICBJZiB0aGUgc3lzdGVtIHByb3BlcnR5CisgICAgICogICAgIDxjb2RlPiJqYXZheC54bWwudmFsaWRhdGlvbi5TY2hlbWFGYWN0b3J5OjxpPnNjaGVtYUxhbmd1YWdlPC9pPiI8L2NvZGU+CisgICAgICogICAgIGlzIHByZXNlbnQgKHdoZXJlIDxpPnNjaGVtYUxhbmd1YWdlPC9pPiBpcyB0aGUgcGFyYW1ldGVyCisgICAgICogICAgIHRvIHRoaXMgbWV0aG9kKSwgdGhlbiBpdHMgdmFsdWUgaXMgcmVhZAorICAgICAqICAgICBhcyBhIGNsYXNzIG5hbWUuIFRoZSBtZXRob2Qgd2lsbCB0cnkgdG8KKyAgICAgKiAgICAgY3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgYnkgdXNpbmcgdGhlIGNsYXNzIGxvYWRlciwKKyAgICAgKiAgICAgYW5kIHJldHVybnMgaXQgaWYgaXQgaXMgc3VjY2Vzc2Z1bGx5IGNyZWF0ZWQuCisgICAgICogICA8L2xpPgorICAgICAqICAgPGxpPgorICAgICAqICAgICA8Y29kZT4kamF2YS5ob21lL2xpYi9qYXhwLnByb3BlcnRpZXM8L2NvZGU+IGlzIHJlYWQgYW5kCisgICAgICogICAgIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIGtleSBiZWluZyB0aGUgc3lzdGVtIHByb3BlcnR5IGFib3ZlCisgICAgICogICAgIGlzIGxvb2tlZCBmb3IuIElmIHByZXNlbnQsIHRoZSB2YWx1ZSBpcyBwcm9jZXNzZWQganVzdCBsaWtlIGFib3ZlLgorICAgICAqICAgPC9saT4KKyAgICAgKiAgIDxsaT4KKyAgICAgKiAgICAgPHA+VGhlIGNsYXNzIGxvYWRlciBpcyBhc2tlZCBmb3Igc2VydmljZSBwcm92aWRlciBwcm92aWRlci1jb25maWd1cmF0aW9uIGZpbGVzIG1hdGNoaW5nCisgICAgICogICAgIDxjb2RlPmphdmF4LnhtbC52YWxpZGF0aW9uLlNjaGVtYUZhY3Rvcnk8L2NvZGU+IGluIHRoZSByZXNvdXJjZSBkaXJlY3RvcnkgTUVUQS1JTkYvc2VydmljZXMuCisgICAgICogICAgIFNlZSB0aGUgSkFSIEZpbGUgU3BlY2lmaWNhdGlvbiBmb3IgZmlsZSBmb3JtYXQgYW5kIHBhcnNpbmcgcnVsZXMuCisgICAgICogICAgIEVhY2ggcG90ZW50aWFsIHNlcnZpY2UgcHJvdmlkZXIgaXMgcmVxdWlyZWQgdG8gaW1wbGVtZW50IHRoZSBtZXRob2Q6PC9wPgorICAgICAqICAgICA8cHJlPgorICAgICAqICAgICAgICB7QGxpbmsgI2lzU2NoZW1hTGFuZ3VhZ2VTdXBwb3J0ZWQoU3RyaW5nIHNjaGVtYUxhbmd1YWdlKX0KKyAgICAgKiAgICAgPC9wcmU+CisgICAgICogICAgIFRoZSBmaXJzdCBzZXJ2aWNlIHByb3ZpZGVyIGZvdW5kIGluIGNsYXNzIGxvYWRlciBvcmRlciB0aGF0IHN1cHBvcnRzIHRoZSBzcGVjaWZpZWQgc2NoZW1hIGxhbmd1YWdlIGlzIHJldHVybmVkLgorICAgICAqICAgPC9saT4KKyAgICAgKiAgIDxsaT4KKyAgICAgKiAgICAgUGxhdGZvcm0gZGVmYXVsdCA8Y29kZT5TY2hlbWFGYWN0b3J5PC9jb2RlPiBpcyBsb2NhdGVkCisgICAgICogICAgIGluIGEgaW1wbGVtZW50YXRpb24gc3BlY2lmaWMgd2F5LiBUaGVyZSBtdXN0IGJlIGEgcGxhdGZvcm0gZGVmYXVsdAorICAgICAqICAgICA8Y29kZT5TY2hlbWFGYWN0b3J5PC9jb2RlPiBmb3IgVzNDIFhNTCBTY2hlbWEuCisgICAgICogICA8L2xpPgorICAgICAqIDwvb2w+CisgICAgICoKKyAgICAgKiA8cD5JZiBldmVyeXRoaW5nIGZhaWxzLCB7QGxpbmsgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufSB3aWxsIGJlIHRocm93bi48L3A+CisgICAgICoKKyAgICAgKiA8cD48c3Ryb25nPlRpcCBmb3IgVHJvdWJsZS1zaG9vdGluZzo8L3N0cm9uZz48L3A+CisgICAgICogPHA+U2VlIHtAbGluayBqYXZhLnV0aWwuUHJvcGVydGllcyNsb2FkKGphdmEuaW8uSW5wdXRTdHJlYW0pfSBmb3IKKyAgICAgKiBleGFjdGx5IGhvdyBhIHByb3BlcnR5IGZpbGUgaXMgcGFyc2VkLiBJbiBwYXJ0aWN1bGFyLCBjb2xvbnMgJzonCisgICAgICogbmVlZCB0byBiZSBlc2NhcGVkIGluIGEgcHJvcGVydHkgZmlsZSwgc28gbWFrZSBzdXJlIHNjaGVtYSBsYW5ndWFnZQorICAgICAqIFVSSXMgYXJlIHByb3Blcmx5IGVzY2FwZWQgaW4gaXQuIEZvciBleGFtcGxlOjwvcD4KKyAgICAgKiA8cHJlPgorICAgICAqIGh0dHBcOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYT1vcmcuYWNtZS5mb28uWFNTY2hlbWFGYWN0b3J5CisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiBAcGFyYW0gc2NoZW1hTGFuZ3VhZ2UKKyAgICAgKiAgICAgIFNwZWNpZmllcyB0aGUgc2NoZW1hIGxhbmd1YWdlIHdoaWNoIHRoZSByZXR1cm5lZAorICAgICAqICAgICAgU2NoZW1hRmFjdG9yeSB3aWxsIHVuZGVyc3RhbmQuIFNlZQorICAgICAqICAgICAgPGEgaHJlZj0iI3NjaGVtYUxhbmd1YWdlIj50aGUgbGlzdCBvZiBhdmFpbGFibGUKKyAgICAgKiAgICAgIHNjaGVtYSBsYW5ndWFnZXM8L2E+IGZvciB0aGUgcG9zc2libGUgdmFsdWVzLgorICAgICAqCisgICAgICogQHJldHVybiBOZXcgaW5zdGFuY2Ugb2YgYSA8Y29kZT5TY2hlbWFGYWN0b3J5PC9jb2RlPgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgIElmIG5vIGltcGxlbWVudGF0aW9uIG9mIHRoZSBzY2hlbWEgbGFuZ3VhZ2UgaXMgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgSWYgdGhlIDx0dD5zY2hlbWFMYW5ndWFnZTwvdHQ+IHBhcmFtZXRlciBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU2NoZW1hRmFjdG9yeSBuZXdJbnN0YW5jZShTdHJpbmcgc2NoZW1hTGFuZ3VhZ2UpIHsKKyAgICAgICAgQ2xhc3NMb2FkZXIgY2w7CisgICAgICAgIGNsID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKworICAgICAgICBpZiAoY2wgPT0gbnVsbCkgeworICAgICAgICAgICAgLy9jbCA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCk7CisgICAgICAgICAgICAvL3VzZSB0aGUgY3VycmVudCBjbGFzcyBsb2FkZXIKKyAgICAgICAgICAgIGNsID0gU2NoZW1hRmFjdG9yeS5jbGFzcy5nZXRDbGFzc0xvYWRlcigpOworICAgICAgICB9CisKKyAgICAgICAgU2NoZW1hRmFjdG9yeSBmID0gbmV3IFNjaGVtYUZhY3RvcnlGaW5kZXIoY2wpLm5ld0ZhY3Rvcnkoc2NoZW1hTGFuZ3VhZ2UpOworICAgICAgICBpZiAoZiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKHNjaGVtYUxhbmd1YWdlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIHRoZSBuYW1lZCBpbXBsZW1lbnRhdGlvbiBvZiB7QGNvZGUgU2NoZW1hRmFjdG9yeX0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUgZmFjdG9yeUNsYXNzTmFtZX0gaXMgbm90IGF2YWlsYWJsZSwgY2Fubm90IGJlCisgICAgICogICAgIGluc3RhbnRpYXRlZCwgb3IgZG9lc24ndCBzdXBwb3J0IHtAY29kZSBzY2hlbWFMYW5ndWFnZX0uCisgICAgICogQHNpbmNlIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU2NoZW1hRmFjdG9yeSBuZXdJbnN0YW5jZShTdHJpbmcgc2NoZW1hTGFuZ3VhZ2UsIFN0cmluZyBmYWN0b3J5Q2xhc3NOYW1lLAorICAgICAgICAgICAgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIpIHsKKyAgICAgICAgaWYgKHNjaGVtYUxhbmd1YWdlID09IG51bGwgfHwgZmFjdG9yeUNsYXNzTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInNjaGVtYUxhbmd1YWdlID09IG51bGwgfHwgZmFjdG9yeUNsYXNzTmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNsYXNzTG9hZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIGNsYXNzTG9hZGVyID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3M8Pz4gdHlwZSA9IGNsYXNzTG9hZGVyICE9IG51bGwKKyAgICAgICAgICAgICAgICAgICAgPyBjbGFzc0xvYWRlci5sb2FkQ2xhc3MoZmFjdG9yeUNsYXNzTmFtZSkKKyAgICAgICAgICAgICAgICAgICAgOiBDbGFzcy5mb3JOYW1lKGZhY3RvcnlDbGFzc05hbWUpOworICAgICAgICAgICAgU2NoZW1hRmFjdG9yeSByZXN1bHQgPSAoU2NoZW1hRmFjdG9yeSkgdHlwZS5uZXdJbnN0YW5jZSgpOworICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsIHx8ICFyZXN1bHQuaXNTY2hlbWFMYW5ndWFnZVN1cHBvcnRlZChzY2hlbWFMYW5ndWFnZSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKHNjaGVtYUxhbmd1YWdlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihlKTsKKyAgICAgICAgfSBjYXRjaCAoSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGUpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5JcyBzcGVjaWZpZWQgc2NoZW1hIHN1cHBvcnRlZCBieSB0aGlzIDxjb2RlPlNjaGVtYUZhY3Rvcnk8L2NvZGU+PzwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzY2hlbWFMYW5ndWFnZSBTcGVjaWZpZXMgdGhlIHNjaGVtYSBsYW5ndWFnZSB3aGljaCB0aGUgcmV0dXJuZWQgPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4gd2lsbCB1bmRlcnN0YW5kLgorICAgICAqICAgIDxjb2RlPnNjaGVtYUxhbmd1YWdlPC9jb2RlPiBtdXN0IHNwZWNpZnkgYSA8YSBocmVmPSIjc2NoZW1hTGFuZ3VhZ2UiPnZhbGlkPC9hPiBzY2hlbWEgbGFuZ3VhZ2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIDxjb2RlPlNjaGVtYUZhY3Rvcnk8L2NvZGU+IHN1cHBvcnRzIDxjb2RlPnNjaGVtYUxhbmd1YWdlPC9jb2RlPiwgZWxzZSA8Y29kZT5mYWxzZTwvY29kZT4uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPnNjaGVtYUxhbmd1YWdlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiA8Y29kZT5zY2hlbWFMYW5ndWFnZS5sZW5ndGgoKSA9PSAwPC9jb2RlPgorICAgICAqICAgb3IgPGNvZGU+c2NoZW1hTGFuZ3VhZ2U8L2NvZGU+IGRvZXMgbm90IHNwZWNpZnkgYSA8YSBocmVmPSIjc2NoZW1hTGFuZ3VhZ2UiPnZhbGlkPC9hPiBzY2hlbWEgbGFuZ3VhZ2UuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNTY2hlbWFMYW5ndWFnZVN1cHBvcnRlZChTdHJpbmcgc2NoZW1hTGFuZ3VhZ2UpOworCisgICAgLyoqCisgICAgICogTG9vayB1cCB0aGUgdmFsdWUgb2YgYSBmZWF0dXJlIGZsYWcuCisgICAgICoKKyAgICAgKiA8cD5UaGUgZmVhdHVyZSBuYW1lIGlzIGFueSBmdWxseS1xdWFsaWZpZWQgVVJJLiAgSXQgaXMKKyAgICAgKiBwb3NzaWJsZSBmb3IgYSB7QGxpbmsgU2NoZW1hRmFjdG9yeX0gdG8gcmVjb2duaXplIGEgZmVhdHVyZSBuYW1lIGJ1dAorICAgICAqIHRlbXBvcmFyaWx5IGJlIHVuYWJsZSB0byByZXR1cm4gaXRzIHZhbHVlLgorICAgICAqCisgICAgICogPHA+SW1wbGVtZW50ZXJzIGFyZSBmcmVlIChhbmQgZW5jb3VyYWdlZCkgdG8gaW52ZW50IHRoZWlyIG93biBmZWF0dXJlcywKKyAgICAgKiB1c2luZyBuYW1lcyBidWlsdCBvbiB0aGVpciBvd24gVVJJcy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZmVhdHVyZSBuYW1lLCB3aGljaCBpcyBhIG5vbi1udWxsIGZ1bGx5LXF1YWxpZmllZCBVUkkuCisgICAgICogQHJldHVybiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZmVhdHVyZSAodHJ1ZSBvciBmYWxzZSkuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBmZWF0dXJlCisgICAgICogICAgICAgICAgICB2YWx1ZSBjYW4ndCBiZSBhc3NpZ25lZCBvciByZXRyaWV2ZWQuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUKKyAgICAgKiAgICAgICAgICAgIHtAbGluayBTY2hlbWFGYWN0b3J5fSByZWNvZ25pemVzIHRoZSBmZWF0dXJlIG5hbWUgYnV0CisgICAgICogICAgICAgICAgICBjYW5ub3QgZGV0ZXJtaW5lIGl0cyB2YWx1ZSBhdCB0aGlzIHRpbWUuCisgICAgICogQGV4Y2VwdGlvbiBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICBpZiB0aGUgbmFtZSBwYXJhbWV0ZXIgaXMgbnVsbC4KKyAgICAgKiBAc2VlICNzZXRGZWF0dXJlKFN0cmluZywgYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKworICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInRoZSBuYW1lIHBhcmFtZXRlciBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24obmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSB2YWx1ZSBvZiBhIGZlYXR1cmUgZmxhZy4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIEZlYXR1cmUgY2FuIGJlIHVzZWQgdG8gY29udHJvbCB0aGUgd2F5IGEge0BsaW5rIFNjaGVtYUZhY3Rvcnl9CisgICAgICogcGFyc2VzIHNjaGVtYXMsIGFsdGhvdWdoIHtAbGluayBTY2hlbWFGYWN0b3J5fXMgYXJlIG5vdCByZXF1aXJlZAorICAgICAqIHRvIHJlY29nbml6ZSBhbnkgc3BlY2lmaWMgZmVhdHVyZSBuYW1lcy48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgZmVhdHVyZSBuYW1lIGlzIGFueSBmdWxseS1xdWFsaWZpZWQgVVJJLiAgSXQgaXMKKyAgICAgKiBwb3NzaWJsZSBmb3IgYSB7QGxpbmsgU2NoZW1hRmFjdG9yeX0gdG8gZXhwb3NlIGEgZmVhdHVyZSB2YWx1ZSBidXQKKyAgICAgKiB0byBiZSB1bmFibGUgdG8gY2hhbmdlIHRoZSBjdXJyZW50IHZhbHVlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkFsbCBpbXBsZW1lbnRhdGlvbnMgYXJlIHJlcXVpcmVkIHRvIHN1cHBvcnQgdGhlIHtAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0ZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkd9IGZlYXR1cmUuCisgICAgICogV2hlbiB0aGUgZmVhdHVyZSBpczo8L3A+CisgICAgICogPHVsPgorICAgICAqICAgPGxpPgorICAgICAqICAgICA8Y29kZT50cnVlPC9jb2RlPjogdGhlIGltcGxlbWVudGF0aW9uIHdpbGwgbGltaXQgWE1MIHByb2Nlc3NpbmcgdG8gY29uZm9ybSB0byBpbXBsZW1lbnRhdGlvbiBsaW1pdHMuCisgICAgICogICAgIEV4YW1wbGVzIGluY2x1ZGUgZW50aXR5IGV4cGFuc2lvbiBsaW1pdHMgYW5kIFhNTCBTY2hlbWEgY29uc3RydWN0cyB0aGF0IHdvdWxkIGNvbnN1bWUgbGFyZ2UgYW1vdW50cyBvZiByZXNvdXJjZXMuCisgICAgICogICAgIElmIFhNTCBwcm9jZXNzaW5nIGlzIGxpbWl0ZWQgZm9yIHNlY3VyaXR5IHJlYXNvbnMsIGl0IHdpbGwgYmUgcmVwb3J0ZWQgdmlhIGEgY2FsbCB0byB0aGUgcmVnaXN0ZXJlZAorICAgICAqICAgICB7QGxpbmsgRXJyb3JIYW5kbGVyI2ZhdGFsRXJyb3Iob3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24pfS4KKyAgICAgKiAgICAgU2VlIHtAbGluayAgI3NldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyKX0uCisgICAgICogICA8L2xpPgorICAgICAqICAgPGxpPgorICAgICAqICAgICA8Y29kZT5mYWxzZTwvY29kZT46IHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsIHByb2Nlc3NpbmcgWE1MIGFjY29yZGluZyB0byB0aGUgWE1MIHNwZWNpZmljYXRpb25zIHdpdGhvdXQKKyAgICAgKiAgICAgcmVnYXJkIHRvIHBvc3NpYmxlIGltcGxlbWVudGF0aW9uIGxpbWl0cy4KKyAgICAgKiAgIDwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBmZWF0dXJlIG5hbWUsIHdoaWNoIGlzIGEgbm9uLW51bGwgZnVsbHktcXVhbGlmaWVkIFVSSS4KKyAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcXVlc3RlZCB2YWx1ZSBvZiB0aGUgZmVhdHVyZSAodHJ1ZSBvciBmYWxzZSkuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlIGZlYXR1cmUKKyAgICAgKiAgICAgICAgICAgIHZhbHVlIGNhbid0IGJlIGFzc2lnbmVkIG9yIHJldHJpZXZlZC4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBXaGVuIHRoZQorICAgICAqICAgICAgICAgICAge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IHJlY29nbml6ZXMgdGhlIGZlYXR1cmUgbmFtZSBidXQKKyAgICAgKiAgICAgICAgICAgIGNhbm5vdCBzZXQgdGhlIHJlcXVlc3RlZCB2YWx1ZS4KKyAgICAgKiBAZXhjZXB0aW9uIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgIGlmIHRoZSBuYW1lIHBhcmFtZXRlciBpcyBudWxsLgorICAgICAqCisgICAgICogQHNlZSAjZ2V0RmVhdHVyZShTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidGhlIG5hbWUgcGFyYW1ldGVyIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcHJvcGVydHkgbmFtZSBpcyBhbnkgZnVsbHktcXVhbGlmaWVkIFVSSS4gIEl0IGlzCisgICAgICogcG9zc2libGUgZm9yIGEge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IHRvIHJlY29nbml6ZSBhIHByb3BlcnR5IG5hbWUgYnV0CisgICAgICogdG8gYmUgdW5hYmxlIHRvIGNoYW5nZSB0aGUgY3VycmVudCB2YWx1ZS48L3A+CisgICAgICoKKyAgICAgKiA8cD57QGxpbmsgU2NoZW1hRmFjdG9yeX1zIGFyZSBub3QgcmVxdWlyZWQgdG8gcmVjb2duaXplIHNldHRpbmcKKyAgICAgKiBhbnkgc3BlY2lmaWMgcHJvcGVydHkgbmFtZXMuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIHByb3BlcnR5IG5hbWUsIHdoaWNoIGlzIGEgbm9uLW51bGwgZnVsbHktcXVhbGlmaWVkIFVSSS4KKyAgICAgKiBAcGFyYW0gb2JqZWN0IFRoZSByZXF1ZXN0ZWQgdmFsdWUgZm9yIHRoZSBwcm9wZXJ0eS4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlIHByb3BlcnR5CisgICAgICogICAgICAgICAgICB2YWx1ZSBjYW4ndCBiZSBhc3NpZ25lZCBvciByZXRyaWV2ZWQuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUKKyAgICAgKiAgICAgICAgICAgIHtAbGluayBTY2hlbWFGYWN0b3J5fSByZWNvZ25pemVzIHRoZSBwcm9wZXJ0eSBuYW1lIGJ1dAorICAgICAqICAgICAgICAgICAgY2Fubm90IHNldCB0aGUgcmVxdWVzdGVkIHZhbHVlLgorICAgICAqIEBleGNlcHRpb24gTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgaWYgdGhlIG5hbWUgcGFyYW1ldGVyIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIG5hbWUsIE9iamVjdCBvYmplY3QpIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInRoZSBuYW1lIHBhcmFtZXRlciBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24obmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9vayB1cCB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBwcm9wZXJ0eSBuYW1lIGlzIGFueSBmdWxseS1xdWFsaWZpZWQgVVJJLiAgSXQgaXMKKyAgICAgKiBwb3NzaWJsZSBmb3IgYSB7QGxpbmsgU2NoZW1hRmFjdG9yeX0gdG8gcmVjb2duaXplIGEgcHJvcGVydHkgbmFtZSBidXQKKyAgICAgKiB0ZW1wb3JhcmlseSBiZSB1bmFibGUgdG8gcmV0dXJuIGl0cyB2YWx1ZS48L3A+CisgICAgICoKKyAgICAgKiA8cD57QGxpbmsgU2NoZW1hRmFjdG9yeX1zIGFyZSBub3QgcmVxdWlyZWQgdG8gcmVjb2duaXplIGFueSBzcGVjaWZpYworICAgICAqIHByb3BlcnR5IG5hbWVzLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkltcGxlbWVudGVycyBhcmUgZnJlZSAoYW5kIGVuY291cmFnZWQpIHRvIGludmVudCB0aGVpciBvd24gcHJvcGVydGllcywKKyAgICAgKiB1c2luZyBuYW1lcyBidWlsdCBvbiB0aGVpciBvd24gVVJJcy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgcHJvcGVydHkgbmFtZSwgd2hpY2ggaXMgYSBub24tbnVsbCBmdWxseS1xdWFsaWZpZWQgVVJJLgorICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHByb3BlcnR5LgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBJZiB0aGUgcHJvcGVydHkKKyAgICAgKiAgICAgICAgICAgIHZhbHVlIGNhbid0IGJlIGFzc2lnbmVkIG9yIHJldHJpZXZlZC4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBXaGVuIHRoZQorICAgICAqICAgICAgICAgICAgWE1MUmVhZGVyIHJlY29nbml6ZXMgdGhlIHByb3BlcnR5IG5hbWUgYnV0CisgICAgICogICAgICAgICAgICBjYW5ub3QgZGV0ZXJtaW5lIGl0cyB2YWx1ZSBhdCB0aGlzIHRpbWUuCisgICAgICogQGV4Y2VwdGlvbiBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICBpZiB0aGUgbmFtZSBwYXJhbWV0ZXIgaXMgbnVsbC4KKyAgICAgKiBAc2VlICNzZXRQcm9wZXJ0eShTdHJpbmcsIE9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ0aGUgbmFtZSBwYXJhbWV0ZXIgaXMgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKG5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHtAbGluayBFcnJvckhhbmRsZXJ9IHRvIHJlY2VpdmUgZXJyb3JzIGVuY291bnRlcmVkCisgICAgICogZHVyaW5nIHRoZSA8Y29kZT5uZXdTY2hlbWE8L2NvZGU+IG1ldGhvZCBpbnZvY2F0aW9uLgorICAgICAqCisgICAgICogPHA+CisgICAgICogRXJyb3IgaGFuZGxlciBjYW4gYmUgdXNlZCB0byBjdXN0b21pemUgdGhlIGVycm9yIGhhbmRsaW5nIHByb2Nlc3MKKyAgICAgKiBkdXJpbmcgc2NoZW1hIHBhcnNpbmcuIFdoZW4gYW4ge0BsaW5rIEVycm9ySGFuZGxlcn0gaXMgc2V0LAorICAgICAqIGVycm9ycyBmb3VuZCBkdXJpbmcgdGhlIHBhcnNpbmcgb2Ygc2NoZW1hcyB3aWxsIGJlIGZpcnN0IHNlbnQKKyAgICAgKiB0byB0aGUge0BsaW5rIEVycm9ySGFuZGxlcn0uCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZXJyb3IgaGFuZGxlciBjYW4gYWJvcnQgdGhlIHBhcnNpbmcgb2YgYSBzY2hlbWEgaW1tZWRpYXRlbHkKKyAgICAgKiBieSB0aHJvd2luZyB7QGxpbmsgU0FYRXhjZXB0aW9ufSBmcm9tIHRoZSBoYW5kbGVyLiBPciBmb3IgZXhhbXBsZQorICAgICAqIGl0IGNhbiBwcmludCBhbiBlcnJvciB0byB0aGUgc2NyZWVuIGFuZCB0cnkgdG8gY29udGludWUgdGhlCisgICAgICogcHJvY2Vzc2luZyBieSByZXR1cm5pbmcgbm9ybWFsbHkgZnJvbSB0aGUge0BsaW5rIEVycm9ySGFuZGxlcn0KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIElmIGFueSB7QGxpbmsgVGhyb3dhYmxlfSAob3IgaW5zdGFuY2VzIG9mIGl0cyBkZXJpdmVkIGNsYXNzZXMpCisgICAgICogaXMgdGhyb3duIGZyb20gYW4ge0BsaW5rIEVycm9ySGFuZGxlcn0sCisgICAgICogdGhlIGNhbGxlciBvZiB0aGUgPGNvZGU+bmV3U2NoZW1hPC9jb2RlPiBtZXRob2Qgd2lsbCBiZSB0aHJvd24KKyAgICAgKiB0aGUgc2FtZSB7QGxpbmsgVGhyb3dhYmxlfSBvYmplY3QuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiB7QGxpbmsgU2NoZW1hRmFjdG9yeX0gaXMgbm90IGFsbG93ZWQgdG8KKyAgICAgKiB0aHJvdyB7QGxpbmsgU0FYRXhjZXB0aW9ufSB3aXRob3V0IGZpcnN0IHJlcG9ydGluZyBpdCB0bworICAgICAqIHtAbGluayBFcnJvckhhbmRsZXJ9LgorICAgICAqCisgICAgICogPHA+CisgICAgICogQXBwbGljYXRpb25zIGNhbiBjYWxsIHRoaXMgbWV0aG9kIGV2ZW4gZHVyaW5nIGEge0BsaW5rIFNjaGVtYX0KKyAgICAgKiBpcyBiZWluZyBwYXJzZWQuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBXaGVuIHRoZSB7QGxpbmsgRXJyb3JIYW5kbGVyfSBpcyBudWxsLCB0aGUgaW1wbGVtZW50YXRpb24gd2lsbAorICAgICAqIGJlaGF2ZSBhcyBpZiB0aGUgZm9sbG93aW5nIHtAbGluayBFcnJvckhhbmRsZXJ9IGlzIHNldDoKKyAgICAgKiA8cHJlPgorICAgICAqIGNsYXNzIERyYWNvbmlhbkVycm9ySGFuZGxlciBpbXBsZW1lbnRzIHtAbGluayBFcnJvckhhbmRsZXJ9IHsKKyAgICAgKiAgICAgcHVibGljIHZvaWQgZmF0YWxFcnJvcigge0BsaW5rIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9ufSBlICkgdGhyb3dzIHtAbGluayBTQVhFeGNlcHRpb259IHsKKyAgICAgKiAgICAgICAgIHRocm93IGU7CisgICAgICogICAgIH0KKyAgICAgKiAgICAgcHVibGljIHZvaWQgZXJyb3IoIHtAbGluayBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbn0gZSApIHRocm93cyB7QGxpbmsgU0FYRXhjZXB0aW9ufSB7CisgICAgICogICAgICAgICB0aHJvdyBlOworICAgICAqICAgICB9CisgICAgICogICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoIHtAbGluayBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbn0gZSApIHRocm93cyB7QGxpbmsgU0FYRXhjZXB0aW9ufSB7CisgICAgICogICAgICAgICAvLyBub29wCisgICAgICogICAgIH0KKyAgICAgKiB9CisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBXaGVuIGEgbmV3IHtAbGluayBTY2hlbWFGYWN0b3J5fSBvYmplY3QgaXMgY3JlYXRlZCwgaW5pdGlhbGx5CisgICAgICogdGhpcyBmaWVsZCBpcyBzZXQgdG8gbnVsbC4gVGhpcyBmaWVsZCB3aWxsIDxlbT5OT1Q8L2VtPiBiZQorICAgICAqIGluaGVyaXRlZCB0byB7QGxpbmsgU2NoZW1hfXMsIHtAbGluayBWYWxpZGF0b3J9cywgb3IKKyAgICAgKiB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn1zIHRoYXQgYXJlIGNyZWF0ZWQgZnJvbSB0aGlzIHtAbGluayBTY2hlbWFGYWN0b3J5fS4KKyAgICAgKgorICAgICAqCisgICAgICogQHBhcmFtICAgZXJyb3JIYW5kbGVyCisgICAgICogICAgICBBIG5ldyBlcnJvciBoYW5kbGVyIHRvIGJlIHNldC4gVGhpcyBwYXJhbWV0ZXIgY2FuIGJlIG51bGwuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlciBlcnJvckhhbmRsZXIpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY3VycmVudCB7QGxpbmsgRXJyb3JIYW5kbGVyfSBzZXQgdG8gdGhpcyB7QGxpbmsgU2NoZW1hRmFjdG9yeX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBvYmplY3QgdGhhdCB3YXMgbGFzdCBzZXQgdGhyb3VnaAorICAgICAqICAgICAgdGhlIHtAbGluayAjc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlcil9IG1ldGhvZCwgb3IgbnVsbAorICAgICAqICAgICAgaWYgdGhhdCBtZXRob2QgaGFzIG5ldmVyIGJlZW4gY2FsbGVkIHNpbmNlIHRoaXMge0BsaW5rIFNjaGVtYUZhY3Rvcnl9CisgICAgICogICAgICBoYXMgY3JlYXRlZC4KKyAgICAgKgorICAgICAqIEBzZWUgI3NldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIpCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHtAbGluayBMU1Jlc291cmNlUmVzb2x2ZXJ9IHRvIGN1c3RvbWl6ZQorICAgICAqIHJlc291cmNlIHJlc29sdXRpb24gd2hlbiBwYXJzaW5nIHNjaGVtYXMuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiB7QGxpbmsgU2NoZW1hRmFjdG9yeX0gdXNlcyBhIHtAbGluayBMU1Jlc291cmNlUmVzb2x2ZXJ9CisgICAgICogd2hlbiBpdCBuZWVkcyB0byBsb2NhdGUgZXh0ZXJuYWwgcmVzb3VyY2VzIHdoaWxlIHBhcnNpbmcgc2NoZW1hcywKKyAgICAgKiBhbHRob3VnaCBleGFjdGx5IHdoYXQgY29uc3RpdHV0ZXMgImxvY2F0aW5nIGV4dGVybmFsIHJlc291cmNlcyIgaXMKKyAgICAgKiB1cCB0byBlYWNoIHNjaGVtYSBsYW5ndWFnZS4gRm9yIGV4YW1wbGUsIGZvciBXM0MgWE1MIFNjaGVtYSwKKyAgICAgKiB0aGlzIGluY2x1ZGVzIGZpbGVzIDx0dD4mbHQ7aW5jbHVkZT48L3R0PmQgb3IgPHR0PiZsdDtpbXBvcnQ+PC90dD5lZCwKKyAgICAgKiBhbmQgRFREIHJlZmVyZW5jZWQgZnJvbSBzY2hlbWEgZmlsZXMsIGV0Yy4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIEFwcGxpY2F0aW9ucyBjYW4gY2FsbCB0aGlzIG1ldGhvZCBldmVuIGR1cmluZyBhIHtAbGluayBTY2hlbWF9CisgICAgICogaXMgYmVpbmcgcGFyc2VkLgorICAgICAqCisgICAgICogPHA+CisgICAgICogV2hlbiB0aGUge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0gaXMgbnVsbCwgdGhlIGltcGxlbWVudGF0aW9uIHdpbGwKKyAgICAgKiBiZWhhdmUgYXMgaWYgdGhlIGZvbGxvd2luZyB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfSBpcyBzZXQ6CisgICAgICogPHByZT4KKyAgICAgKiBjbGFzcyBEdW1iRE9NUmVzb3VyY2VSZXNvbHZlciBpbXBsZW1lbnRzIHtAbGluayBMU1Jlc291cmNlUmVzb2x2ZXJ9IHsKKyAgICAgKiAgICAgcHVibGljIHtAbGluayBvcmcudzNjLmRvbS5scy5MU0lucHV0fSByZXNvbHZlUmVzb3VyY2UoCisgICAgICogICAgICAgICBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIGJhc2VVUkkpIHsKKyAgICAgKgorICAgICAqICAgICAgICAgcmV0dXJuIG51bGw7IC8vIGFsd2F5cyByZXR1cm4gbnVsbAorICAgICAqICAgICB9CisgICAgICogfQorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogPHA+CisgICAgICogSWYgYSB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfSB0aHJvd3MgYSB7QGxpbmsgUnVudGltZUV4Y2VwdGlvbn0KKyAgICAgKiAgKG9yIGluc3RhbmNlcyBvZiBpdHMgZGVyaXZlZCBjbGFzc2VzKSwKKyAgICAgKiB0aGVuIHRoZSB7QGxpbmsgU2NoZW1hRmFjdG9yeX0gd2lsbCBhYm9ydCB0aGUgcGFyc2luZyBhbmQKKyAgICAgKiB0aGUgY2FsbGVyIG9mIHRoZSA8Y29kZT5uZXdTY2hlbWE8L2NvZGU+IG1ldGhvZCB3aWxsIHJlY2VpdmUKKyAgICAgKiB0aGUgc2FtZSB7QGxpbmsgUnVudGltZUV4Y2VwdGlvbn0uCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBXaGVuIGEgbmV3IHtAbGluayBTY2hlbWFGYWN0b3J5fSBvYmplY3QgaXMgY3JlYXRlZCwgaW5pdGlhbGx5CisgICAgICogdGhpcyBmaWVsZCBpcyBzZXQgdG8gbnVsbC4gIFRoaXMgZmllbGQgd2lsbCA8ZW0+Tk9UPC9lbT4gYmUKKyAgICAgKiBpbmhlcml0ZWQgdG8ge0BsaW5rIFNjaGVtYX1zLCB7QGxpbmsgVmFsaWRhdG9yfXMsIG9yCisgICAgICoge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9cyB0aGF0IGFyZSBjcmVhdGVkIGZyb20gdGhpcyB7QGxpbmsgU2NoZW1hRmFjdG9yeX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gICByZXNvdXJjZVJlc29sdmVyCisgICAgICogICAgICBBIG5ldyByZXNvdXJjZSByZXNvbHZlciB0byBiZSBzZXQuIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFJlc291cmNlUmVzb2x2ZXIoTFNSZXNvdXJjZVJlc29sdmVyIHJlc291cmNlUmVzb2x2ZXIpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY3VycmVudCB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfSBzZXQgdG8gdGhpcyB7QGxpbmsgU2NoZW1hRmFjdG9yeX0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBvYmplY3QgdGhhdCB3YXMgbGFzdCBzZXQgdGhyb3VnaAorICAgICAqICAgICAgdGhlIHtAbGluayAjc2V0UmVzb3VyY2VSZXNvbHZlcihMU1Jlc291cmNlUmVzb2x2ZXIpfSBtZXRob2QsIG9yIG51bGwKKyAgICAgKiAgICAgIGlmIHRoYXQgbWV0aG9kIGhhcyBuZXZlciBiZWVuIGNhbGxlZCBzaW5jZSB0aGlzIHtAbGluayBTY2hlbWFGYWN0b3J5fQorICAgICAqICAgICAgaGFzIGNyZWF0ZWQuCisgICAgICoKKyAgICAgKiBAc2VlICNzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyKQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBMU1Jlc291cmNlUmVzb2x2ZXIgZ2V0UmVzb3VyY2VSZXNvbHZlcigpOworCisgICAgLyoqCisgICAgICogPHA+UGFyc2VzIHRoZSBzcGVjaWZpZWQgc291cmNlIGFzIGEgc2NoZW1hIGFuZCByZXR1cm5zIGl0IGFzIGEgc2NoZW1hLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaXMgYSBjb252ZW5pZW5jZSBtZXRob2QgZm9yIHtAbGluayAjbmV3U2NoZW1hKFNvdXJjZVtdIHNjaGVtYXMpfS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gc2NoZW1hIFNvdXJjZSB0aGF0IHJlcHJlc2VudHMgYSBzY2hlbWEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5TY2hlbWE8L2NvZGU+IGZyb20gcGFyc2luZyA8Y29kZT5zY2hlbWE8L2NvZGU+LgorICAgICAqCisgICAgICogQHRocm93cyBTQVhFeGNlcHRpb24gSWYgYSBTQVggZXJyb3Igb2NjdXJzIGR1cmluZyBwYXJzaW5nLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPHR0PnNjaGVtYTwvdHQ+IGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIFNjaGVtYSBuZXdTY2hlbWEoU291cmNlIHNjaGVtYSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXdTY2hlbWEobmV3IFNvdXJjZVtde3NjaGVtYX0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlBhcnNlcyB0aGUgc3BlY2lmaWVkIDxjb2RlPkZpbGU8L2NvZGU+IGFzIGEgc2NoZW1hIGFuZCByZXR1cm5zIGl0IGFzIGEgPGNvZGU+U2NoZW1hPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kIGZvciB7QGxpbmsgI25ld1NjaGVtYShTb3VyY2Ugc2NoZW1hKX0uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHNjaGVtYSBGaWxlIHRoYXQgcmVwcmVzZW50cyBhIHNjaGVtYS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gTmV3IDxjb2RlPlNjaGVtYTwvY29kZT4gZnJvbSBwYXJzaW5nIDxjb2RlPnNjaGVtYTwvY29kZT4uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhIFNBWCBlcnJvciBvY2N1cnMgZHVyaW5nIHBhcnNpbmcuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8dHQ+c2NoZW1hPC90dD4gaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2NoZW1hIG5ld1NjaGVtYShGaWxlIHNjaGVtYSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXdTY2hlbWEobmV3IFN0cmVhbVNvdXJjZShzY2hlbWEpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5QYXJzZXMgdGhlIHNwZWNpZmllZCA8Y29kZT5VUkw8L2NvZGU+IGFzIGEgc2NoZW1hIGFuZCByZXR1cm5zIGl0IGFzIGEgPGNvZGU+U2NoZW1hPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kIGZvciB7QGxpbmsgI25ld1NjaGVtYShTb3VyY2Ugc2NoZW1hKX0uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHNjaGVtYSA8Y29kZT5VUkw8L2NvZGU+IHRoYXQgcmVwcmVzZW50cyBhIHNjaGVtYS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gTmV3IDxjb2RlPlNjaGVtYTwvY29kZT4gZnJvbSBwYXJzaW5nIDxjb2RlPnNjaGVtYTwvY29kZT4uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhIFNBWCBlcnJvciBvY2N1cnMgZHVyaW5nIHBhcnNpbmcuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8dHQ+c2NoZW1hPC90dD4gaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2NoZW1hIG5ld1NjaGVtYShVUkwgc2NoZW1hKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ld1NjaGVtYShuZXcgU3RyZWFtU291cmNlKHNjaGVtYS50b0V4dGVybmFsRm9ybSgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgc291cmNlKHMpIGFzIGEgc2NoZW1hIGFuZCByZXR1cm5zIGl0IGFzIGEgc2NoZW1hLgorICAgICAqCisgICAgICogPHA+CisgICAgICogVGhlIGNhbGxlZSB3aWxsIHJlYWQgYWxsIHRoZSB7QGxpbmsgU291cmNlfXMgYW5kIGNvbWJpbmUgdGhlbSBpbnRvIGEKKyAgICAgKiBzaW5nbGUgc2NoZW1hLiBUaGUgZXhhY3Qgc2VtYW50aWNzIG9mIHRoZSBjb21iaW5hdGlvbiBkZXBlbmRzIG9uIHRoZSBzY2hlbWEKKyAgICAgKiBsYW5ndWFnZSB0aGF0IHRoaXMge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IG9iamVjdCBpcyBjcmVhdGVkIGZvci4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFdoZW4gYW4ge0BsaW5rIEVycm9ySGFuZGxlcn0gaXMgc2V0LCB0aGUgY2FsbGVlIHdpbGwgcmVwb3J0IGFsbCB0aGUgZXJyb3JzCisgICAgICogZm91bmQgaW4gc291cmNlcyB0byB0aGUgaGFuZGxlci4gSWYgdGhlIGhhbmRsZXIgdGhyb3dzIGFuIGV4Y2VwdGlvbiwgaXQgd2lsbAorICAgICAqIGFib3J0IHRoZSBzY2hlbWEgY29tcGlsYXRpb24gYW5kIHRoZSBzYW1lIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93biBmcm9tCisgICAgICogdGhpcyBtZXRob2QuIEFsc28sIGFmdGVyIGFuIGVycm9yIGlzIHJlcG9ydGVkIHRvIGEgaGFuZGxlciwgdGhlIGNhbGxlZSBpcyBhbGxvd2VkCisgICAgICogdG8gYWJvcnQgdGhlIGZ1cnRoZXIgcHJvY2Vzc2luZyBieSB0aHJvd2luZyBpdC4gSWYgYW4gZXJyb3IgaGFuZGxlciBpcyBub3Qgc2V0LAorICAgICAqIHRoZSBjYWxsZWUgd2lsbCB0aHJvdyB0aGUgZmlyc3QgZXJyb3IgaXQgZmluZHMgaW4gdGhlIHNvdXJjZXMuCisgICAgICoKKyAgICAgKiA8aDI+VzNDIFhNTCBTY2hlbWEgMS4wPC9oMj4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcmVzdWx0aW5nIHNjaGVtYSBjb250YWlucyBjb21wb25lbnRzIGZyb20gdGhlIHNwZWNpZmllZCBzb3VyY2VzLgorICAgICAqIFRoZSBzYW1lIHJlc3VsdCB3b3VsZCBiZSBhY2hpZXZlZCBpZiBhbGwgdGhlc2Ugc291cmNlcyB3ZXJlCisgICAgICogaW1wb3J0ZWQsIHVzaW5nIGFwcHJvcHJpYXRlIHZhbHVlcyBmb3Igc2NoZW1hTG9jYXRpb24gYW5kIG5hbWVzcGFjZSwKKyAgICAgKiBpbnRvIGEgc2luZ2xlIHNjaGVtYSBkb2N1bWVudCB3aXRoIGEgZGlmZmVyZW50IHRhcmdldE5hbWVzcGFjZQorICAgICAqIGFuZCBubyBjb21wb25lbnRzIG9mIGl0cyBvd24sIGlmIHRoZSBpbXBvcnQgZWxlbWVudHMgd2VyZSBnaXZlbgorICAgICAqIGluIHRoZSBzYW1lIG9yZGVyIGFzIHRoZSBzb3VyY2VzLiAgU2VjdGlvbiA0LjIuMyBvZiB0aGUgWE1MIFNjaGVtYQorICAgICAqIHJlY29tbWVuZGF0aW9uIGRlc2NyaWJlcyB0aGUgb3B0aW9ucyBwcm9jZXNzb3JzIGhhdmUgaW4gdGhpcworICAgICAqIHJlZ2FyZC4gIFdoaWxlIGEgcHJvY2Vzc29yIHNob3VsZCBiZSBjb25zaXN0ZW50IGluIGl0cyB0cmVhdG1lbnQgb2YKKyAgICAgKiBKQVhQIHNjaGVtYSBzb3VyY2VzIGFuZCBYTUwgU2NoZW1hIGltcG9ydHMsIHRoZSBiZWhhdmlvciBiZXR3ZWVuCisgICAgICogSkFYUC1jb21wbGlhbnQgcGFyc2VycyBtYXkgdmFyeTsgaW4gcGFydGljdWxhciwgcGFyc2VycyBtYXkgY2hvb3NlCisgICAgICogdG8gaWdub3JlIGFsbCBidXQgdGhlIGZpcnN0ICZsdDtpbXBvcnQ+IGZvciBhIGdpdmVuIG5hbWVzcGFjZSwKKyAgICAgKiByZWdhcmRsZXNzIG9mIGluZm9ybWF0aW9uIHByb3ZpZGVkIGluIHNjaGVtYUxvY2F0aW9uLgorICAgICAqCisgICAgICogPHA+CisgICAgICogSWYgdGhlIHBhcnNlZCBzZXQgb2Ygc2NoZW1hcyBpbmNsdWRlcyBlcnJvcihzKSBhcworICAgICAqIHNwZWNpZmllZCBpbiB0aGUgc2VjdGlvbiA1LjEgb2YgdGhlIFhNTCBTY2hlbWEgc3BlYywgdGhlbgorICAgICAqIHRoZSBlcnJvciBtdXN0IGJlIHJlcG9ydGVkIHRvIHRoZSB7QGxpbmsgRXJyb3JIYW5kbGVyfS4KKyAgICAgKgorICAgICAqIDxoMj5SRUxBWCBORzwvaDI+CisgICAgICoKKyAgICAgKiA8cD5Gb3IgUkVMQVggTkcsIHRoaXMgbWV0aG9kIG11c3QgdGhyb3cge0BsaW5rIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufQorICAgICAqIGlmIDx0dD5zY2hlbWFzLmxlbmd0aCE9MTwvdHQ+LgorICAgICAqCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2NoZW1hcworICAgICAqICAgICAgaW5wdXRzIHRvIGJlIHBhcnNlZC4ge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IGlzIHJlcXVpcmVkCisgICAgICogICAgICB0byByZWNvZ25pemUge0BsaW5rIFN0cmVhbVNvdXJjZX0sCisgICAgICogICAgICB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYU291cmNlfSwKKyAgICAgKiAgICAgIGFuZCB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NU291cmNlfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4KKyAgICAgKiAgICAgIEFsd2F5cyByZXR1cm4gYSBub24tbnVsbCB2YWxpZCB7QGxpbmsgU2NoZW1hfSBvYmplY3QuCisgICAgICogICAgICBOb3RlIHRoYXQgd2hlbiBhbiBlcnJvciBoYXMgYmVlbiByZXBvcnRlZCwgdGhlcmUgaXMgbm8KKyAgICAgKiAgICAgIGd1YXJhbnRlZSB0aGF0IHRoZSByZXR1cm5lZCB7QGxpbmsgU2NoZW1hfSBvYmplY3QgaXMKKyAgICAgKiAgICAgIG1lYW5pbmdmdWwuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgICAqICAgICAgSWYgYW4gZXJyb3IgaXMgZm91bmQgZHVyaW5nIHByb2Nlc3NpbmcgdGhlIHNwZWNpZmllZCBpbnB1dHMuCisgICAgICogICAgICBXaGVuIGFuIHtAbGluayBFcnJvckhhbmRsZXJ9IGlzIHNldCwgZXJyb3JzIGFyZSByZXBvcnRlZCB0bworICAgICAqICAgICAgdGhlcmUgZmlyc3QuIFNlZSB7QGxpbmsgI3NldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIpfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICBJZiB0aGUgPGNvZGU+c2NoZW1hczwvY29kZT4gcGFyYW1ldGVyIGl0c2VsZiBpcyBudWxsIG9yCisgICAgICogICAgICBhbnkgaXRlbSBpbiB0aGUgYXJyYXkgaXMgbnVsbC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgSWYgYW55IGl0ZW0gaW4gdGhlIGFycmF5IGlzIG5vdCByZWNvZ25pemVkIGJ5IHRoaXMgbWV0aG9kLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgIElmIHRoZSBzY2hlbWEgbGFuZ3VhZ2UgZG9lc24ndCBzdXBwb3J0IHRoaXMgb3BlcmF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTY2hlbWEgbmV3U2NoZW1hKFNvdXJjZVtdIHNjaGVtYXMpIHRocm93cyBTQVhFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgc3BlY2lhbCB7QGxpbmsgU2NoZW1hfSBvYmplY3QuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZXhhY3Qgc2VtYW50aWNzIG9mIHRoZSByZXR1cm5lZCB7QGxpbmsgU2NoZW1hfSBvYmplY3QgZGVwZW5kcworICAgICAqIG9uIHRoZSBzY2hlbWEgbGFuZ3VhZ2UgdGhhdCB0aGlzIHtAbGluayBTY2hlbWFGYWN0b3J5fSBpcyBjcmVhdGVkCisgICAgICogZm9yLgorICAgICAqCisgICAgICogPHA+CisgICAgICogQWxzbywgaW1wbGVtZW50YXRpb25zIGFyZSBhbGxvd2VkIHRvIHVzZSBpbXBsZW1lbnRhdGlvbi1zcGVjaWZpYworICAgICAqIHByb3BlcnR5L2ZlYXR1cmUgdG8gYWx0ZXIgdGhlIHNlbWFudGljcyBvZiB0aGlzIG1ldGhvZC4KKyAgICAgKgorICAgICAqCisgICAgICogPGgyPlczQyBYTUwgU2NoZW1hIDEuMDwvaDI+CisgICAgICogPHA+CisgICAgICogRm9yIFhNTCBTY2hlbWEsIHRoaXMgbWV0aG9kIGNyZWF0ZXMgYSB7QGxpbmsgU2NoZW1hfSBvYmplY3QgdGhhdAorICAgICAqIHBlcmZvcm1zIHZhbGlkYXRpb24gYnkgdXNpbmcgbG9jYXRpb24gaGludHMgc3BlY2lmaWVkIGluIGRvY3VtZW50cy4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFRoZSByZXR1cm5lZCB7QGxpbmsgU2NoZW1hfSBvYmplY3QgYXNzdW1lcyB0aGF0IGlmIGRvY3VtZW50cworICAgICAqIHJlZmVyIHRvIHRoZSBzYW1lIFVSTCBpbiB0aGUgc2NoZW1hIGxvY2F0aW9uIGhpbnRzLAorICAgICAqIHRoZXkgd2lsbCBhbHdheXMgcmVzb2x2ZSB0byB0aGUgc2FtZSBzY2hlbWEgZG9jdW1lbnQuIFRoaXMKKyAgICAgKiBhc3N1bXB0aW9uIGFsbG93cyBpbXBsZW1lbnRhdGlvbnMgdG8gcmV1c2UgcGFyc2VkIHJlc3VsdHMgb2YKKyAgICAgKiBzY2hlbWEgZG9jdW1lbnRzIHNvIHRoYXQgbXVsdGlwbGUgdmFsaWRhdGlvbnMgYWdhaW5zdCB0aGUgc2FtZQorICAgICAqIHNjaGVtYSB3aWxsIHJ1biBmYXN0ZXIuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBOb3RlIHRoYXQgdGhlIHVzZSBvZiBzY2hlbWEgbG9jYXRpb24gaGludHMgaW50cm9kdWNlcyBhCisgICAgICogdnVsbmVyYWJpbGl0eSB0byBkZW5pYWwtb2Ytc2VydmljZSBhdHRhY2tzLgorICAgICAqCisgICAgICoKKyAgICAgKiA8aDI+UkVMQVggTkc8L2gyPgorICAgICAqIDxwPgorICAgICAqIFJFTEFYIE5HIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBvcGVyYXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICBBbHdheXMgcmV0dXJuIG5vbi1udWxsIHZhbGlkIHtAbGluayBTY2hlbWF9IG9iamVjdC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgIElmIHRoaXMgb3BlcmF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIGNhbGxlZS4KKyAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgICAqICAgICAgSWYgdGhpcyBvcGVyYXRpb24gaXMgc3VwcG9ydGVkIGJ1dCBmYWlsZWQgZm9yIHNvbWUgcmVhc29uLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTY2hlbWEgbmV3U2NoZW1hKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdmFsaWRhdGlvbi9TY2hlbWFGYWN0b3J5RmluZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3ZhbGlkYXRpb24vU2NoZW1hRmFjdG9yeUZpbmRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNhNmNiODMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3ZhbGlkYXRpb24vU2NoZW1hRmFjdG9yeUZpbmRlci5qYXZhCkBAIC0wLDAgKzEsNDEyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8vICRJZDogU2NoZW1hRmFjdG9yeUZpbmRlci5qYXZhIDcyNzM2NyAyMDA4LTEyLTE3IDEzOjA1OjI2WiBtcmdsYXZhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLnZhbGlkYXRpb247CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CitpbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKK2ltcG9ydCBsaWJjb3JlLmlvLklvVXRpbHM7CisKKy8qKgorICogSW1wbGVtZW50YXRpb24gb2Yge0BsaW5rIFNjaGVtYUZhY3RvcnkjbmV3SW5zdGFuY2UoU3RyaW5nKX0uCisgKgorICogQGF1dGhvciA8YSBocmVmPSJLb2hzdWtlLkthd2FndWNoaUBTdW4uY29tIj5Lb2hzdWtlIEthd2FndWNoaTwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogNzI3MzY3ICQsICREYXRlOiAyMDA4LTEyLTE3IDA1OjA1OjI2IC0wODAwIChXZWQsIDE3IERlYyAyMDA4KSAkCisgKiBAc2luY2UgMS41CisgKi8KK2ZpbmFsIGNsYXNzIFNjaGVtYUZhY3RvcnlGaW5kZXIgIHsKKworICAgIC8qKiBYTUwgU2NoZW1hIGxhbmd1YWdlIGlkZW50aWZpZXJzLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBXM0NfWE1MX1NDSEVNQTEwX05TX1VSSSA9ICJodHRwOi8vd3d3LnczLm9yZy9YTUwvWE1MU2NoZW1hL3YxLjAiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBXM0NfWE1MX1NDSEVNQTExX05TX1VSSSA9ICJodHRwOi8vd3d3LnczLm9yZy9YTUwvWE1MU2NoZW1hL3YxLjEiOworCisgICAgLyoqIGRlYnVnIHN1cHBvcnQgY29kZS4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGRlYnVnID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiA8cD5DYWNoZSBwcm9wZXJ0aWVzIGZvciBwZXJmb3JtYW5jZS48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgUHJvcGVydGllcyBjYWNoZVByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKworICAgIC8qKgorICAgICAqIDxwPkZpcnN0IHRpbWUgcmVxdWlyZXMgaW5pdGlhbGl6YXRpb24gb3ZlcmhlYWQuPC9wPgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gZmlyc3RUaW1lID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIERlZmF1bHQgY29sdW1ucyBwZXIgbGluZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9MSU5FX0xFTkdUSCA9IDgwOworCisgICAgc3RhdGljIHsKKyAgICAgICAgU3RyaW5nIHZhbCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF4cC5kZWJ1ZyIpOworICAgICAgICAvLyBBbGxvdyBzaW1wbHkgc2V0dGluZyB0aGUgcHJvcCB0byB0dXJuIG9uIGRlYnVnCisgICAgICAgIGRlYnVnID0gdmFsICE9IG51bGwgJiYgKCEgImZhbHNlIi5lcXVhbHModmFsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+Q29uZGl0aW9uYWwgZGVidWcgcHJpbnRpbmcuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG1zZyB0byBwcmludAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZGVidWdQcmludGxuKFN0cmluZyBtc2cpIHsKKyAgICAgICAgaWYgKGRlYnVnKSB7CisgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkpBWFA6ICIgKyBtc2cpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+PGNvZGU+Q2xhc3NMb2FkZXI8L2NvZGU+IHRvIHVzZSB0byBmaW5kIDxjb2RlPlNjaGVtYUZhY3Rvcnk8L2NvZGU+LjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyOworCisgICAgLyoqCisgICAgICogPHA+Q29uc3RydWN0b3IgdGhhdCBzcGVjaWZpZXMgPGNvZGU+Q2xhc3NMb2FkZXI8L2NvZGU+IHRvIHVzZQorICAgICAqIHRvIGZpbmQgPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGxvYWRlcgorICAgICAqICAgICAgdG8gYmUgdXNlZCB0byBsb2FkIHJlc291cmNlLCB7QGxpbmsgU2NoZW1hRmFjdG9yeX0sIGFuZAorICAgICAqICAgICAge0BsaW5rIFNjaGVtYUZhY3RvcnlMb2FkZXJ9IGltcGxlbWVudGF0aW9ucyBkdXJpbmcKKyAgICAgKiAgICAgIHRoZSByZXNvbHV0aW9uIHByb2Nlc3MuCisgICAgICogICAgICBJZiB0aGlzIHBhcmFtZXRlciBpcyBudWxsLCB0aGUgZGVmYXVsdCBzeXN0ZW0gY2xhc3MgbG9hZGVyCisgICAgICogICAgICB3aWxsIGJlIHVzZWQuCisgICAgICovCisgICAgcHVibGljIFNjaGVtYUZhY3RvcnlGaW5kZXIoQ2xhc3NMb2FkZXIgbG9hZGVyKSB7CisgICAgICAgIHRoaXMuY2xhc3NMb2FkZXIgPSBsb2FkZXI7CisgICAgICAgIGlmKCBkZWJ1ZyApIHsKKyAgICAgICAgICAgIGRlYnVnRGlzcGxheUNsYXNzTG9hZGVyKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZGVidWdEaXNwbGF5Q2xhc3NMb2FkZXIoKSB7CisgICAgICAgIGlmIChjbGFzc0xvYWRlciA9PSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpKSB7CisgICAgICAgICAgICBkZWJ1Z1ByaW50bG4oInVzaW5nIHRocmVhZCBjb250ZXh0IGNsYXNzIGxvYWRlciAoIitjbGFzc0xvYWRlcisiKSBmb3Igc2VhcmNoIik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAoY2xhc3NMb2FkZXIgPT0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKSkgeworICAgICAgICAgICAgZGVidWdQcmludGxuKCJ1c2luZyBzeXN0ZW0gY2xhc3MgbG9hZGVyICgiK2NsYXNzTG9hZGVyKyIpIGZvciBzZWFyY2giKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGRlYnVnUHJpbnRsbigidXNpbmcgY2xhc3MgbG9hZGVyICgiICsgY2xhc3NMb2FkZXIgKyAiKSBmb3Igc2VhcmNoIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+Q3JlYXRlcyBhIG5ldyB7QGxpbmsgU2NoZW1hRmFjdG9yeX0gb2JqZWN0IGZvciB0aGUgc3BlY2lmaWVkCisgICAgICogc2NoZW1hIGxhbmd1YWdlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzY2hlbWFMYW5ndWFnZQorICAgICAqICAgICAgU2VlIHtAbGluayBTY2hlbWFGYWN0b3J5IFNjaGVtYSBMYW5ndWFnZX0gdGFibGUgaW4gPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4KKyAgICAgKiAgICAgIGZvciB0aGUgbGlzdCBvZiBhdmFpbGFibGUgc2NoZW1hIGxhbmd1YWdlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGNhbGxlZSBmYWlscyB0byBjcmVhdGUgb25lLgorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgSWYgdGhlIDx0dD5zY2hlbWFMYW5ndWFnZTwvdHQ+IHBhcmFtZXRlciBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBTY2hlbWFGYWN0b3J5IG5ld0ZhY3RvcnkoU3RyaW5nIHNjaGVtYUxhbmd1YWdlKSB7CisgICAgICAgIGlmKHNjaGVtYUxhbmd1YWdlPT1udWxsKSAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIFNjaGVtYUZhY3RvcnkgZiA9IF9uZXdGYWN0b3J5KHNjaGVtYUxhbmd1YWdlKTsKKyAgICAgICAgaWYgKGRlYnVnKSB7CisgICAgICAgICAgICBpZiAoZiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZGVidWdQcmludGxuKCJmYWN0b3J5ICciICsgZi5nZXRDbGFzcygpLmdldE5hbWUoKSArICInIHdhcyBmb3VuZCBmb3IgIiArIHNjaGVtYUxhbmd1YWdlKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZGVidWdQcmludGxuKCJ1bmFibGUgdG8gZmluZCBhIGZhY3RvcnkgZm9yICIgKyBzY2hlbWFMYW5ndWFnZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGY7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+TG9va3VwIGEgPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4gZm9yIHRoZSBnaXZlbiA8Y29kZT5zY2hlbWFMYW5ndWFnZTwvY29kZT4uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHNjaGVtYUxhbmd1YWdlIFNjaGVtYSBsYW5ndWFnZSB0byBsb29rdXAgPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4gZm9yLgorICAgICAqCisgICAgICogQHJldHVybiA8Y29kZT5TY2hlbWFGYWN0b3J5PC9jb2RlPiBmb3IgdGhlIGdpdmVuIDxjb2RlPnNjaGVtYUxhbmd1YWdlPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwcml2YXRlIFNjaGVtYUZhY3RvcnkgX25ld0ZhY3RvcnkoU3RyaW5nIHNjaGVtYUxhbmd1YWdlKSB7CisgICAgICAgIFNjaGVtYUZhY3Rvcnkgc2Y7CisgICAgICAgIFN0cmluZyBwcm9wZXJ0eU5hbWUgPSBTRVJWSUNFX0NMQVNTLmdldE5hbWUoKSArICI6IiArIHNjaGVtYUxhbmd1YWdlOworCisgICAgICAgIC8vIHN5c3RlbSBwcm9wZXJ0eSBsb29rIHVwCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoZGVidWcpIGRlYnVnUHJpbnRsbigiTG9va2luZyB1cCBzeXN0ZW0gcHJvcGVydHkgJyIrcHJvcGVydHlOYW1lKyInIiApOworICAgICAgICAgICAgU3RyaW5nIHIgPSBTeXN0ZW0uZ2V0UHJvcGVydHkocHJvcGVydHlOYW1lKTsKKyAgICAgICAgICAgIGlmIChyICE9IG51bGwgJiYgci5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgICAgICAgICBpZiAoZGVidWcpIGRlYnVnUHJpbnRsbigiVGhlIHZhbHVlIGlzICciK3IrIiciKTsKKyAgICAgICAgICAgICAgICBzZiA9IGNyZWF0ZUluc3RhbmNlKHIpOworICAgICAgICAgICAgICAgIGlmKHNmIT1udWxsKSAgICByZXR1cm4gc2Y7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIGlmIChkZWJ1ZykgeworICAgICAgICAgICAgICAgIGRlYnVnUHJpbnRsbigiVGhlIHByb3BlcnR5IGlzIHVuZGVmaW5lZC4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBUaGUgVk0gcmFuIG91dCBvZiBtZW1vcnkgb3IgdGhlcmUgd2FzIHNvbWUgb3RoZXIgc2VyaW91cyBwcm9ibGVtLiBSZS10aHJvdy4KKyAgICAgICAgY2F0Y2ggKFZpcnR1YWxNYWNoaW5lRXJyb3Igdm1lKSB7CisgICAgICAgICAgICB0aHJvdyB2bWU7CisgICAgICAgIH0KKyAgICAgICAgLy8gVGhyZWFkRGVhdGggc2hvdWxkIGFsd2F5cyBiZSByZS10aHJvd24KKyAgICAgICAgY2F0Y2ggKFRocmVhZERlYXRoIHRkKSB7CisgICAgICAgICAgICB0aHJvdyB0ZDsKKyAgICAgICAgfQorICAgICAgICBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgIGlmKCBkZWJ1ZyApIHsKKyAgICAgICAgICAgICAgICBkZWJ1Z1ByaW50bG4oImZhaWxlZCB0byBsb29rIHVwIHN5c3RlbSBwcm9wZXJ0eSAnIitwcm9wZXJ0eU5hbWUrIiciICk7CisgICAgICAgICAgICAgICAgdC5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBqYXZhaCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5ob21lIik7CisgICAgICAgIFN0cmluZyBjb25maWdGaWxlID0gamF2YWggKyBGaWxlLnNlcGFyYXRvciArCisgICAgICAgICJsaWIiICsgRmlsZS5zZXBhcmF0b3IgKyAiamF4cC5wcm9wZXJ0aWVzIjsKKworICAgICAgICBTdHJpbmcgZmFjdG9yeUNsYXNzTmFtZSA9IG51bGwgOworCisgICAgICAgIC8vIHRyeSB0byByZWFkIGZyb20gJGphdmEuaG9tZS9saWIvamF4cC5wcm9wZXJ0aWVzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZihmaXJzdFRpbWUpeworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZChjYWNoZVByb3BzKXsKKyAgICAgICAgICAgICAgICAgICAgaWYoZmlyc3RUaW1lKXsKKyAgICAgICAgICAgICAgICAgICAgICAgIEZpbGUgZj1uZXcgRmlsZSggY29uZmlnRmlsZSApOworICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RUaW1lID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgICAgICBpZihmLmV4aXN0cygpKXsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVidWcpIGRlYnVnUHJpbnRsbigiUmVhZCBwcm9wZXJ0aWVzIGZpbGUgIiArIGYpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlUHJvcHMubG9hZChuZXcgRmlsZUlucHV0U3RyZWFtKGYpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZhY3RvcnlDbGFzc05hbWUgPSBjYWNoZVByb3BzLmdldFByb3BlcnR5KHByb3BlcnR5TmFtZSk7CisgICAgICAgICAgICBpZiAoZGVidWcpIGRlYnVnUHJpbnRsbigiZm91bmQgIiArIGZhY3RvcnlDbGFzc05hbWUgKyAiIGluICRqYXZhLmhvbWUvamF4cC5wcm9wZXJ0aWVzIik7CisKKyAgICAgICAgICAgIGlmIChmYWN0b3J5Q2xhc3NOYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZiA9IGNyZWF0ZUluc3RhbmNlKGZhY3RvcnlDbGFzc05hbWUpOworICAgICAgICAgICAgICAgIGlmKHNmICE9IG51bGwpeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2Y7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGlmIChkZWJ1ZykgeworICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gdHJ5IE1FVEEtSU5GL3NlcnZpY2VzIGZpbGVzCisgICAgICAgIGZvciAoVVJMIHJlc291cmNlIDogY3JlYXRlU2VydmljZUZpbGVJdGVyYXRvcigpKSB7CisgICAgICAgICAgICBpZiAoZGVidWcpIGRlYnVnUHJpbnRsbigibG9va2luZyBpbnRvICIgKyByZXNvdXJjZSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHNmID0gbG9hZEZyb21TZXJ2aWNlc0ZpbGUoc2NoZW1hTGFuZ3VhZ2UscmVzb3VyY2UudG9FeHRlcm5hbEZvcm0oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc291cmNlLm9wZW5TdHJlYW0oKSk7CisgICAgICAgICAgICAgICAgaWYoc2YhPW51bGwpICAgIHJldHVybiBzZjsKKyAgICAgICAgICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGlmKCBkZWJ1ZyApIHsKKyAgICAgICAgICAgICAgICAgICAgZGVidWdQcmludGxuKCJmYWlsZWQgdG8gcmVhZCAiK3Jlc291cmNlKTsKKyAgICAgICAgICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBwbGF0Zm9ybSBkZWZhdWx0cworICAgICAgICBpZiAoc2NoZW1hTGFuZ3VhZ2UuZXF1YWxzKFhNTENvbnN0YW50cy5XM0NfWE1MX1NDSEVNQV9OU19VUkkpIHx8IHNjaGVtYUxhbmd1YWdlLmVxdWFscyhXM0NfWE1MX1NDSEVNQTEwX05TX1VSSSkpIHsKKyAgICAgICAgICAgIGlmIChkZWJ1ZykgZGVidWdQcmludGxuKCJhdHRlbXB0aW5nIHRvIHVzZSB0aGUgcGxhdGZvcm0gZGVmYXVsdCBYTUwgU2NoZW1hIDEuMCB2YWxpZGF0b3IiKTsKKyAgICAgICAgICAgIHJldHVybiBjcmVhdGVJbnN0YW5jZSgib3JnLmFwYWNoZS54ZXJjZXMuamF4cC52YWxpZGF0aW9uLlhNTFNjaGVtYUZhY3RvcnkiKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChzY2hlbWFMYW5ndWFnZS5lcXVhbHMoVzNDX1hNTF9TQ0hFTUExMV9OU19VUkkpKSB7CisgICAgICAgICAgICBpZiAoZGVidWcpIGRlYnVnUHJpbnRsbigiYXR0ZW1wdGluZyB0byB1c2UgdGhlIHBsYXRmb3JtIGRlZmF1bHQgWE1MIFNjaGVtYSAxLjEgdmFsaWRhdG9yIik7CisgICAgICAgICAgICByZXR1cm4gY3JlYXRlSW5zdGFuY2UoIm9yZy5hcGFjaGUueGVyY2VzLmpheHAudmFsaWRhdGlvbi5YTUxTY2hlbWExMUZhY3RvcnkiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkZWJ1ZykgZGVidWdQcmludGxuKCJhbGwgdGhpbmdzIHdlcmUgdHJpZWQsIGJ1dCBub25lIHdhcyBmb3VuZC4gYmFpbGluZyBvdXQuIik7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkNyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgdGhlIHNwZWNpZmllZCBhbmQgcmV0dXJucyBpdC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2xhc3NOYW1lCisgICAgICogICAgICBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZSB0byBiZSBpbnN0YW50aWF0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIG51bGwKKyAgICAgKiAgICAgIGlmIGl0IGZhaWxzLiBFcnJvciBtZXNzYWdlcyB3aWxsIGJlIHByaW50ZWQgYnkgdGhpcyBtZXRob2QuCisgICAgICovCisgICAgU2NoZW1hRmFjdG9yeSBjcmVhdGVJbnN0YW5jZSggU3RyaW5nIGNsYXNzTmFtZSApIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChkZWJ1ZykgZGVidWdQcmludGxuKCJpbnN0YW50aWF0aW5nICIrY2xhc3NOYW1lKTsKKyAgICAgICAgICAgIENsYXNzIGNsYXp6OworICAgICAgICAgICAgaWYoIGNsYXNzTG9hZGVyIT1udWxsICkKKyAgICAgICAgICAgICAgICBjbGF6eiA9IGNsYXNzTG9hZGVyLmxvYWRDbGFzcyhjbGFzc05hbWUpOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIGNsYXp6ID0gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUpOworICAgICAgICAgICAgaWYoZGVidWcpICAgICAgIGRlYnVnUHJpbnRsbigibG9hZGVkIGl0IGZyb20gIit3aGljaChjbGF6eikpOworICAgICAgICAgICAgT2JqZWN0IG8gPSBjbGF6ei5uZXdJbnN0YW5jZSgpOworCisgICAgICAgICAgICBpZiggbyBpbnN0YW5jZW9mIFNjaGVtYUZhY3RvcnkgKQorICAgICAgICAgICAgICAgIHJldHVybiAoU2NoZW1hRmFjdG9yeSlvOworCisgICAgICAgICAgICBpZiAoZGVidWcpIGRlYnVnUHJpbnRsbihjbGFzc05hbWUrIiBpcyBub3QgYXNzaWduYWJsZSB0byAiK1NFUlZJQ0VfQ0xBU1MuZ2V0TmFtZSgpKTsKKyAgICAgICAgfQorICAgICAgICAvLyBUaGUgVk0gcmFuIG91dCBvZiBtZW1vcnkgb3IgdGhlcmUgd2FzIHNvbWUgb3RoZXIgc2VyaW91cyBwcm9ibGVtLiBSZS10aHJvdy4KKyAgICAgICAgY2F0Y2ggKFZpcnR1YWxNYWNoaW5lRXJyb3Igdm1lKSB7CisgICAgICAgICAgICB0aHJvdyB2bWU7CisgICAgICAgIH0KKyAgICAgICAgLy8gVGhyZWFkRGVhdGggc2hvdWxkIGFsd2F5cyBiZSByZS10aHJvd24KKyAgICAgICAgY2F0Y2ggKFRocmVhZERlYXRoIHRkKSB7CisgICAgICAgICAgICB0aHJvdyB0ZDsKKyAgICAgICAgfQorICAgICAgICBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgIGRlYnVnUHJpbnRsbigiZmFpbGVkIHRvIGluc3RhbnRpYXRlICIrY2xhc3NOYW1lKTsKKyAgICAgICAgICAgIGlmKGRlYnVnKSAgIHQucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiB7QGxpbmsgSXRlcmF0b3J9IHRoYXQgZW51bWVyYXRlcyBhbGwKKyAgICAgKiB0aGUgTUVUQS1JTkYvc2VydmljZXMgZmlsZXMgdGhhdCB3ZSBjYXJlLgorICAgICAqLworICAgIHByaXZhdGUgSXRlcmFibGU8VVJMPiBjcmVhdGVTZXJ2aWNlRmlsZUl0ZXJhdG9yKCkgeworICAgICAgICBpZiAoY2xhc3NMb2FkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIgPSBTY2hlbWFGYWN0b3J5RmluZGVyLmNsYXNzLmdldENsYXNzTG9hZGVyKCk7CisgICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuc2luZ2xldG9uKGNsYXNzTG9hZGVyLmdldFJlc291cmNlKFNFUlZJQ0VfSUQpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgRW51bWVyYXRpb248VVJMPiBlID0gY2xhc3NMb2FkZXIuZ2V0UmVzb3VyY2VzKFNFUlZJQ0VfSUQpOworICAgICAgICAgICAgICAgIGlmIChkZWJ1ZyAmJiAhZS5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgICAgICAgICBkZWJ1Z1ByaW50bG4oIm5vICIrU0VSVklDRV9JRCsiIGZpbGUgd2FzIGZvdW5kIik7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gd3JhcCBpdCBpbnRvIGFuIEl0ZXJhdG9yLgorICAgICAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5saXN0KGUpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGlmIChkZWJ1ZykgeworICAgICAgICAgICAgICAgICAgICBkZWJ1Z1ByaW50bG4oImZhaWxlZCB0byBlbnVtZXJhdGUgcmVzb3VyY2VzICIrU0VSVklDRV9JRCk7CisgICAgICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbXB0eVNldCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqIFNlYXJjaGVzIGZvciBhIFNjaGVtYUZhY3RvcnkgZm9yIGEgZ2l2ZW4gc2NoZW1hIGxhbmd1YWdlIGluIGEgTUVUQS1JTkYvc2VydmljZXMgZmlsZS4gKi8KKyAgICBwcml2YXRlIFNjaGVtYUZhY3RvcnkgbG9hZEZyb21TZXJ2aWNlc0ZpbGUoU3RyaW5nIHNjaGVtYUxhbmd1YWdlLCBTdHJpbmcgcmVzb3VyY2VOYW1lLCBJbnB1dFN0cmVhbSBpbikgeworCisgICAgICAgIGlmIChkZWJ1ZykgZGVidWdQcmludGxuKCJSZWFkaW5nICIrcmVzb3VyY2VOYW1lICk7CisKKyAgICAgICAgLy8gUmVhZCB0aGUgc2VydmljZSBwcm92aWRlciBuYW1lIGluIFVURi04IGFzIHNwZWNpZmllZCBpbgorICAgICAgICAvLyB0aGUgamFyIHNwZWMuICBVbmZvcnR1bmF0ZWx5IHRoaXMgZmFpbHMgaW4gTWljcm9zb2Z0CisgICAgICAgIC8vIFZKKyssIHdoaWNoIGRvZXMgbm90IGltcGxlbWVudCB0aGUgVVRGLTgKKyAgICAgICAgLy8gZW5jb2RpbmcuIFRoZW9yZXRpY2FsbHksIHdlIHNob3VsZCBzaW1wbHkgbGV0IGl0IGZhaWwgaW4KKyAgICAgICAgLy8gdGhhdCBjYXNlLCBzaW5jZSB0aGUgSlZNIGlzIG9idmlvdXNseSBicm9rZW4gaWYgaXQKKyAgICAgICAgLy8gZG9lc24ndCBzdXBwb3J0IHN1Y2ggYSBiYXNpYyBzdGFuZGFyZC4gIEJ1dCBzaW5jZSB0aGVyZQorICAgICAgICAvLyBhcmUgc3RpbGwgc29tZSB1c2VycyBhdHRlbXB0aW5nIHRvIHVzZSBWSisrIGZvcgorICAgICAgICAvLyBkZXZlbG9wbWVudCwgd2UgaGF2ZSBkcm9wcGVkIGluIGEgZmFsbGJhY2sgd2hpY2ggbWFrZXMgYQorICAgICAgICAvLyBzZWNvbmQgYXR0ZW1wdCB1c2luZyB0aGUgcGxhdGZvcm0ncyBkZWZhdWx0IGVuY29kaW5nLiBJbgorICAgICAgICAvLyBWSisrIHRoaXMgaXMgYXBwYXJlbnRseSBBU0NJSSwgd2hpY2ggaXMgYSBzdWJzZXQgb2YKKyAgICAgICAgLy8gVVRGLTguLi4gYW5kIHNpbmNlIHRoZSBzdHJpbmdzIHdlJ2xsIGJlIHJlYWRpbmcgaGVyZSBhcmUKKyAgICAgICAgLy8gYWxzbyBwcmltYXJpbHkgbGltaXRlZCB0byB0aGUgNy1iaXQgQVNDSUkgcmFuZ2UgKGF0CisgICAgICAgIC8vIGxlYXN0LCBpbiBFbmdsaXNoIHZlcnNpb25zKSwgdGhpcyBzaG91bGQgd29yayB3ZWxsCisgICAgICAgIC8vIGVub3VnaCB0byBrZWVwIHVzIG9uIHRoZSBhaXIgdW50aWwgd2UncmUgcmVhZHkgdG8KKyAgICAgICAgLy8gb2ZmaWNpYWxseSBkZWNvbW1pdCBmcm9tIFZKKysuIFtFZGl0ZWQgY29tbWVudCBmcm9tCisgICAgICAgIC8vIGprZXNzZWxtXQorICAgICAgICBCdWZmZXJlZFJlYWRlciByZDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJkID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihpbiwgIlVURi04IiksIERFRkFVTFRfTElORV9MRU5HVEgpOworICAgICAgICB9IGNhdGNoIChqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmQgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKGluKSwgREVGQVVMVF9MSU5FX0xFTkdUSCk7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgZmFjdG9yeUNsYXNzTmFtZSA9IG51bGw7CisgICAgICAgIFNjaGVtYUZhY3RvcnkgcmVzdWx0RmFjdG9yeSA9IG51bGw7CisgICAgICAgIC8vIFNlZSBzcGVjIGZvciBwcm92aWRlci1jb25maWd1cmF0aW9uIGZpbGVzOiBodHRwOi8vamF2YS5zdW4uY29tL2oyc2UvMS41LjAvZG9jcy9ndWlkZS9qYXIvamFyLmh0bWwjUHJvdmlkZXIlMjBDb25maWd1cmF0aW9uJTIwRmlsZQorICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmYWN0b3J5Q2xhc3NOYW1lID0gcmQucmVhZExpbmUoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIHgpIHsKKyAgICAgICAgICAgICAgICAvLyBObyBwcm92aWRlciBmb3VuZAorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGZhY3RvcnlDbGFzc05hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIElnbm9yZSBjb21tZW50cyBpbiB0aGUgcHJvdmlkZXItY29uZmlndXJhdGlvbiBmaWxlCisgICAgICAgICAgICAgICAgaW50IGhhc2hJbmRleCA9IGZhY3RvcnlDbGFzc05hbWUuaW5kZXhPZignIycpOworICAgICAgICAgICAgICAgIGlmIChoYXNoSW5kZXggIT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFjdG9yeUNsYXNzTmFtZSA9IGZhY3RvcnlDbGFzc05hbWUuc3Vic3RyaW5nKDAsIGhhc2hJbmRleCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gSWdub3JlIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2UKKyAgICAgICAgICAgICAgICBmYWN0b3J5Q2xhc3NOYW1lID0gZmFjdG9yeUNsYXNzTmFtZS50cmltKCk7CisKKyAgICAgICAgICAgICAgICAvLyBJZiB0aGVyZSdzIG5vIHRleHQgbGVmdCBvciBpZiB0aGlzIHdhcyBhIGJsYW5rIGxpbmUsIGdvIHRvIHRoZSBuZXh0IG9uZS4KKyAgICAgICAgICAgICAgICBpZiAoZmFjdG9yeUNsYXNzTmFtZS5sZW5ndGgoKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIC8vIEZvdW5kIHRoZSByaWdodCBTY2hlbWFGYWN0b3J5IGlmIGl0cyBpc1NjaGVtYUxhbmd1YWdlU3VwcG9ydGVkKHNjaGVtYUxhbmd1YWdlKSBtZXRob2QgcmV0dXJucyB0cnVlLgorICAgICAgICAgICAgICAgICAgICBTY2hlbWFGYWN0b3J5IGZvdW5kRmFjdG9yeSA9IChTY2hlbWFGYWN0b3J5KSBjcmVhdGVJbnN0YW5jZShmYWN0b3J5Q2xhc3NOYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kRmFjdG9yeS5pc1NjaGVtYUxhbmd1YWdlU3VwcG9ydGVkKHNjaGVtYUxhbmd1YWdlKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0RmFjdG9yeSA9IGZvdW5kRmFjdG9yeTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gaWdub3JlZCkge30KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkocmQpOworCisgICAgICAgIHJldHVybiByZXN1bHRGYWN0b3J5OworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENsYXNzIFNFUlZJQ0VfQ0xBU1MgPSBTY2hlbWFGYWN0b3J5LmNsYXNzOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRVJWSUNFX0lEID0gIk1FVEEtSU5GL3NlcnZpY2VzLyIgKyBTRVJWSUNFX0NMQVNTLmdldE5hbWUoKTsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB3aGljaCggQ2xhc3MgY2xhenogKSB7CisgICAgICAgIHJldHVybiB3aGljaCggY2xhenouZ2V0TmFtZSgpLCBjbGF6ei5nZXRDbGFzc0xvYWRlcigpICk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+U2VhcmNoIHRoZSBzcGVjaWZpZWQgY2xhc3Nsb2FkZXIgZm9yIHRoZSBnaXZlbiBjbGFzc25hbWUuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGNsYXNzbmFtZSB0aGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGNsYXNzIHRvIHNlYXJjaCBmb3IKKyAgICAgKiBAcGFyYW0gbG9hZGVyIHRoZSBjbGFzc2xvYWRlciB0byBzZWFyY2gKKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNvdXJjZSBsb2NhdGlvbiBvZiB0aGUgcmVzb3VyY2UsIG9yIG51bGwgaWYgaXQgd2Fzbid0IGZvdW5kCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHdoaWNoKFN0cmluZyBjbGFzc25hbWUsIENsYXNzTG9hZGVyIGxvYWRlcikgeworICAgICAgICBTdHJpbmcgY2xhc3NuYW1lQXNSZXNvdXJjZSA9IGNsYXNzbmFtZS5yZXBsYWNlKCcuJywgJy8nKSArICIuY2xhc3MiOworCisgICAgICAgIGlmIChsb2FkZXIgPT0gbnVsbCkgIGxvYWRlciA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCk7CisKKyAgICAgICAgVVJMIGl0ID0gbG9hZGVyLmdldFJlc291cmNlKGNsYXNzbmFtZUFzUmVzb3VyY2UpOworICAgICAgICByZXR1cm4gaXQgIT0gbnVsbCA/IGl0LnRvU3RyaW5nKCkgOiBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdmFsaWRhdGlvbi9TY2hlbWFGYWN0b3J5TG9hZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3ZhbGlkYXRpb24vU2NoZW1hRmFjdG9yeUxvYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJhYzBmZDcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3ZhbGlkYXRpb24vU2NoZW1hRmFjdG9yeUxvYWRlci5qYXZhCkBAIC0wLDAgKzEsMzEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLy8gJElkOiBTY2hlbWFGYWN0b3J5TG9hZGVyLmphdmEgNDQ4ODAxIDIwMDYtMDktMjIgMDQ6MTk6MjBaIG1yZ2xhdmFzICQKKworcGFja2FnZSBqYXZheC54bWwudmFsaWRhdGlvbjsKKworLyoqCisgKiA8cD5UaGlzIGNsYXNzIHdhcyByZW1vdmVkIGZyb20gSkFYUCAxLjMgYmVmb3JlIGl0IHdhcyBmaW5hbGl6ZWQgYnV0CisgKiB3YXMgbWlzdGFrZW5seSBpbmNsdWRlZCBpbiBKYXZhIDUuIEl0IG9ubHkgZXhpc3RzIG5vdyBmb3IgY29tcGF0aWJpbGl0eQorICogcmVhc29ucy4gQXBwbGljYXRpb25zIHNob3VsZCBhdm9pZCB1c2luZyBpdC48L3A+CisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTY2hlbWFGYWN0b3J5TG9hZGVyIHsKKworICAgIHByb3RlY3RlZCBTY2hlbWFGYWN0b3J5TG9hZGVyKCkge30KKyAgICBwdWJsaWMgYWJzdHJhY3QgU2NoZW1hRmFjdG9yeSBuZXdGYWN0b3J5KFN0cmluZyBzY2hlbWFMYW5ndWFnZSk7CisKK30gLy8gU2NoZW1hRmFjdG9yeUxvYWRlcgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC92YWxpZGF0aW9uL1R5cGVJbmZvUHJvdmlkZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdmFsaWRhdGlvbi9UeXBlSW5mb1Byb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWY1MzMyYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdmFsaWRhdGlvbi9UeXBlSW5mb1Byb3ZpZGVyLmphdmEKQEAgLTAsMCArMSwxODEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLy8gJElkOiBUeXBlSW5mb1Byb3ZpZGVyLmphdmEgODg0OTM5IDIwMDktMTEtMjcgMTg6MjA6NDZaIG1yZ2xhdmFzICQKKworcGFja2FnZSBqYXZheC54bWwudmFsaWRhdGlvbjsKKworaW1wb3J0IG9yZy53M2MuZG9tLlR5cGVJbmZvOworCisvKioKKyAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgYWNjZXNzIHRvIHRoZSB0eXBlIGluZm9ybWF0aW9uIGRldGVybWluZWQKKyAqIGJ5IHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfS4KKyAqCisgKiA8cD4KKyAqIFNvbWUgc2NoZW1hIGxhbmd1YWdlcywgc3VjaCBhcyBXM0MgWE1MIFNjaGVtYSwgZW5jb3VyYWdlcyBhIHZhbGlkYXRvcgorICogdG8gcmVwb3J0IHRoZSAidHlwZSIgaXQgYXNzaWducyB0byBlYWNoIGF0dHJpYnV0ZS9lbGVtZW50LgorICogVGhvc2UgYXBwbGljYXRpb25zIHdobyB3aXNoIHRvIGFjY2VzcyB0aGlzIHR5cGUgaW5mb3JtYXRpb24gY2FuIGludm9rZQorICogbWV0aG9kcyBkZWZpbmVkIG9uIHRoaXMgImludGVyZmFjZSIgdG8gYWNjZXNzIHN1Y2ggdHlwZSBpbmZvcm1hdGlvbi4KKyAqCisgKiA8cD4KKyAqIEltcGxlbWVudGF0aW9uIG9mIHRoaXMgImludGVyZmFjZSIgY2FuIGJlIG9idGFpbmVkIHRocm91Z2ggdGhlCisgKiB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlciNnZXRUeXBlSW5mb1Byb3ZpZGVyKCl9IG1ldGhvZC4KKyAqCisgKiBAYXV0aG9yICA8YSBocmVmPSJtYWlsdG86S29oc3VrZS5LYXdhZ3VjaGlAU3VuLmNvbSI+S29oc3VrZSBLYXdhZ3VjaGk8L2E+CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDg4NDkzOSAkLCAkRGF0ZTogMjAwOS0xMS0yNyAxMDoyMDo0NiAtMDgwMCAoRnJpLCAyNyBOb3YgMjAwOSkgJAorICogQHNlZSBvcmcudzNjLmRvbS5UeXBlSW5mbworICogQHNpbmNlIDEuNQorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgVHlwZUluZm9Qcm92aWRlciB7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBmb3IgdGhlIGRlcml2ZWQgY2xhc3MuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgY29uc3RydWN0b3IgZG9lcyBub3RoaW5nLgorICAgICAqLworICAgIHByb3RlY3RlZCBUeXBlSW5mb1Byb3ZpZGVyKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlJldHVybnMgdGhlIGltbXV0YWJsZSB7QGxpbmsgVHlwZUluZm99IG9iamVjdCBmb3IgdGhlIGN1cnJlbnQgZWxlbWVudC48L3A+CisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbWV0aG9kIG1heSBvbmx5IGJlIGNhbGxlZCBieSB0aGUgc3RhcnRFbGVtZW50IGFuZCBlbmRFbGVtZW50IGV2ZW50IG9mCisgICAgICogdGhlIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0gdGhhdCB0aGUgYXBwbGljYXRpb24gc2V0cyB0byB0aGUKKyAgICAgKiB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0uPC9wPgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgIElmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBmcm9tIG90aGVyIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0KKyAgICAgKiAgICAgIG1ldGhvZHMuCisgICAgICogQHJldHVybgorICAgICAqICAgICAgQW4gaW1tdXRhYmxlIHtAbGluayBUeXBlSW5mb30gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUKKyAgICAgKiAgICAgIHR5cGUgb2YgdGhlIGN1cnJlbnQgZWxlbWVudC4KKyAgICAgKiAgICAgIE5vdGUgdGhhdCB0aGUgY2FsbGVyIGNhbiBrZWVwIHJlZmVyZW5jZXMgdG8gdGhlIG9idGFpbmVkCisgICAgICogICAgICB7QGxpbmsgVHlwZUluZm99IGxvbmdlciB0aGFuIHRoZSBjYWxsYmFjayBzY29wZS4KKyAgICAgKgorICAgICAqICAgICAgT3RoZXJ3aXNlLCB0aGlzIG1ldGhvZCByZXR1cm5zCisgICAgICogICAgICBudWxsIGlmIHRoZSB2YWxpZGF0b3IgaXMgdW5hYmxlIHRvCisgICAgICogICAgICBkZXRlcm1pbmUgdGhlIHR5cGUgb2YgdGhlIGN1cnJlbnQgZWxlbWVudCBmb3Igc29tZSByZWFzb24KKyAgICAgKiAgICAgIChmb3IgZXhhbXBsZSwgaWYgdGhlIHZhbGlkYXRvciBpcyByZWNvdmVyaW5nIGZyb20KKyAgICAgKiAgICAgIGFuIGVhcmxpZXIgZXJyb3IuKQorICAgICAqCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFR5cGVJbmZvIGdldEVsZW1lbnRUeXBlSW5mbygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW1tdXRhYmxlIHtAbGluayBUeXBlSW5mb30gb2JqZWN0IGZvciB0aGUgc3BlY2lmaWVkCisgICAgICogYXR0cmlidXRlIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbWV0aG9kIG1heSBvbmx5IGJlIGNhbGxlZCBieSB0aGUgc3RhcnRFbGVtZW50IGV2ZW50IG9mCisgICAgICogdGhlIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0gdGhhdCB0aGUgYXBwbGljYXRpb24gc2V0cyB0byB0aGUKKyAgICAgKiB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgIFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlLiBUaGUgc2FtZSBpbmRleCBmb3IKKyAgICAgKiAgICAgIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguQXR0cmlidXRlc30gb2JqZWN0IHBhc3NlZCB0byB0aGUKKyAgICAgKiAgICAgIDx0dD5zdGFydEVsZW1lbnQ8L3R0PiBjYWxsYmFjay4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgSWYgdGhlIGluZGV4IGlzIGludmFsaWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgIElmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBmcm9tIG90aGVyIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0KKyAgICAgKiAgICAgIG1ldGhvZHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICBBbiBpbW11dGFibGUge0BsaW5rIFR5cGVJbmZvfSBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZQorICAgICAqICAgICAgdHlwZSBvZiB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZS4KKyAgICAgKiAgICAgIE5vdGUgdGhhdCB0aGUgY2FsbGVyIGNhbiBrZWVwIHJlZmVyZW5jZXMgdG8gdGhlIG9idGFpbmVkCisgICAgICogICAgICB7QGxpbmsgVHlwZUluZm99IGxvbmdlciB0aGFuIHRoZSBjYWxsYmFjayBzY29wZS4KKyAgICAgKgorICAgICAqICAgICAgT3RoZXJ3aXNlLCB0aGlzIG1ldGhvZCByZXR1cm5zCisgICAgICogICAgICBudWxsIGlmIHRoZSB2YWxpZGF0b3IgaXMgdW5hYmxlIHRvCisgICAgICogICAgICBkZXRlcm1pbmUgdGhlIHR5cGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFR5cGVJbmZvIGdldEF0dHJpYnV0ZVR5cGVJbmZvKGludCBpbmRleCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIDx0dD50cnVlPC90dD4gaWYgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUgaXMgZGV0ZXJtaW5lZAorICAgICAqIHRvIGJlIElELgorICAgICAqCisgICAgICogPHA+CisgICAgICogRXhhY3RseSBob3cgYW4gYXR0cmlidXRlIGlzICJkZXRlcm1pbmVkIHRvIGJlIElEIiBpcyB1cCB0byB0aGUKKyAgICAgKiBzY2hlbWEgbGFuZ3VhZ2UuIEluIGNhc2Ugb2YgVzNDIFhNTCBTY2hlbWEsIHRoaXMgbWVhbnMKKyAgICAgKiB0aGF0IHRoZSBhY3R1YWwgdHlwZSBvZiB0aGUgYXR0cmlidXRlIGlzIHRoZSBidWlsdC1pbiBJRCB0eXBlCisgICAgICogb3IgaXRzIGRlcml2ZWQgdHlwZS4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIEEge0BsaW5rIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcn0gdXNlcyB0aGlzIGluZm9ybWF0aW9uCisgICAgICogdG8gcHJvcGVybHkgaW1wbGVtZW50IHtAbGluayBvcmcudzNjLmRvbS5BdHRyI2lzSWQoKX0uCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgbWV0aG9kIG1heSBvbmx5IGJlIGNhbGxlZCBieSB0aGUgc3RhcnRFbGVtZW50IGV2ZW50IG9mCisgICAgICogdGhlIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0gdGhhdCB0aGUgYXBwbGljYXRpb24gc2V0cyB0byB0aGUKKyAgICAgKiB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXgKKyAgICAgKiAgICAgIFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlLiBUaGUgc2FtZSBpbmRleCBmb3IKKyAgICAgKiAgICAgIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguQXR0cmlidXRlc30gb2JqZWN0IHBhc3NlZCB0byB0aGUKKyAgICAgKiAgICAgIDx0dD5zdGFydEVsZW1lbnQ8L3R0PiBjYWxsYmFjay4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgSWYgdGhlIGluZGV4IGlzIGludmFsaWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICAgKiAgICAgIElmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBmcm9tIG90aGVyIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0KKyAgICAgKiAgICAgIG1ldGhvZHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUKKyAgICAgKiAgICAgIGlmIHRoZSB0eXBlIG9mIHRoZSBzcGVjaWZpZWQgYXR0cmlidXRlIGlzIElELgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzSWRBdHRyaWJ1dGUoaW50IGluZGV4KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgPHR0PmZhbHNlPC90dD4gaWYgdGhlIGF0dHJpYnV0ZSB3YXMgYWRkZWQgYnkgdGhlIHZhbGlkYXRvci4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIHByb3ZpZGVzIGluZm9ybWF0aW9uIG5lY2Vzc2FyeSBmb3IKKyAgICAgKiBhIHtAbGluayBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJ9IHRvIGRldGVybWluZSB3aGF0CisgICAgICogdGhlIERPTSB0cmVlIHNob3VsZCByZXR1cm4gZnJvbSB0aGUge0BsaW5rIG9yZy53M2MuZG9tLkF0dHIjZ2V0U3BlY2lmaWVkKCl9IG1ldGhvZC4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFRoZSBtZXRob2QgbWF5IG9ubHkgYmUgY2FsbGVkIGJ5IHRoZSBzdGFydEVsZW1lbnQgZXZlbnQgb2YKKyAgICAgKiB0aGUge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyfSB0aGF0IHRoZSBhcHBsaWNhdGlvbiBzZXRzIHRvIHRoZQorICAgICAqIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfS4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIEEgZ2VuZXJhbCBndWlkZWxpbmUgZm9yIHZhbGlkYXRvcnMgaXMgdG8gcmV0dXJuIHRydWUgaWYKKyAgICAgKiB0aGUgYXR0cmlidXRlIHdhcyBvcmlnaW5hbGx5IHByZXNlbnQgaW4gdGhlIHBpcGVsaW5lLCBhbmQKKyAgICAgKiBmYWxzZSBpZiBpdCB3YXMgYWRkZWQgYnkgdGhlIHZhbGlkYXRvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAorICAgICAqICAgICAgVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUuIFRoZSBzYW1lIGluZGV4IGZvcgorICAgICAqICAgICAgdGhlIHtAbGluayBvcmcueG1sLnNheC5BdHRyaWJ1dGVzfSBvYmplY3QgcGFzc2VkIHRvIHRoZQorICAgICAqICAgICAgPHR0PnN0YXJ0RWxlbWVudDwvdHQ+IGNhbGxiYWNrLgorICAgICAqCisgICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICBJZiB0aGUgaW5kZXggaXMgaW52YWxpZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgICAqICAgICAgSWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGZyb20gb3RoZXIge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyfQorICAgICAqICAgICAgbWV0aG9kcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4KKyAgICAgKiAgICAgIDx0dD50cnVlPC90dD4gaWYgdGhlIGF0dHJpYnV0ZSB3YXMgcHJlc2VudCBiZWZvcmUgdGhlIHZhbGlkYXRvcgorICAgICAqICAgICAgcHJvY2Vzc2VzIGlucHV0LiA8dHQ+ZmFsc2U8L3R0PiBpZiB0aGUgYXR0cmlidXRlIHdhcyBhZGRlZAorICAgICAqICAgICAgYnkgdGhlIHZhbGlkYXRvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc1NwZWNpZmllZChpbnQgaW5kZXgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC92YWxpZGF0aW9uL1ZhbGlkYXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC92YWxpZGF0aW9uL1ZhbGlkYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI0ZWUxY2EKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3ZhbGlkYXRpb24vVmFsaWRhdG9yLmphdmEKQEAgLTAsMCArMSw0MzcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLy8gJElkOiBWYWxpZGF0b3IuamF2YSA4ODg4ODQgMjAwOS0xMi0wOSAxNzozNjo0NlogbXJnbGF2YXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC52YWxpZGF0aW9uOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdDsKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5scy5MU1Jlc291cmNlUmVzb2x2ZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKKworLyoqCisgKiA8cD5BIHByb2Nlc3NvciB0aGF0IGNoZWNrcyBhbiBYTUwgZG9jdW1lbnQgYWdhaW5zdCB7QGxpbmsgU2NoZW1hfS48L3A+CisgKgorICogPHA+CisgKiBBIHZhbGlkYXRvciBpcyBhIHRocmVhZC11bnNhZmUgYW5kIG5vbi1yZWVudHJhbnQgb2JqZWN0LgorICogSW4gb3RoZXIgd29yZHMsIGl0IGlzIHRoZSBhcHBsaWNhdGlvbidzIHJlc3BvbnNpYmlsaXR5IHRvIG1ha2UKKyAqIHN1cmUgdGhhdCBvbmUge0BsaW5rIFZhbGlkYXRvcn0gb2JqZWN0IGlzIG5vdCB1c2VkIGZyb20KKyAqIG1vcmUgdGhhbiBvbmUgdGhyZWFkIGF0IGFueSBnaXZlbiB0aW1lLCBhbmQgd2hpbGUgdGhlIDx0dD52YWxpZGF0ZTwvdHQ+CisgKiBtZXRob2QgaXMgaW52b2tlZCwgYXBwbGljYXRpb25zIG1heSBub3QgcmVjdXJzaXZlbHkgY2FsbAorICogdGhlIDx0dD52YWxpZGF0ZTwvdHQ+IG1ldGhvZC4KKyAqIDxwPgorICoKKyAqIE5vdGUgdGhhdCB3aGlsZSB0aGUge0BsaW5rICN2YWxpZGF0ZShqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZSl9IGFuZCB7QGxpbmsgI3ZhbGlkYXRlKGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlLCBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdCl9CisgKiBtZXRob2RzIHRha2UgYSB7QGxpbmsgU291cmNlfSBpbnN0YW5jZSwgdGhlIDxjb2RlPlNvdXJjZTwvY29kZT4KKyAqIGluc3RhbmNlIG11c3QgYmUgYSA8Y29kZT5TQVhTb3VyY2U8L2NvZGU+LCA8Y29kZT5ET01Tb3VyY2U8L2NvZGU+LCA8Y29kZT5TdEFYU291cmNlPC9jb2RlPiBvciA8Y29kZT5TdHJlYW1Tb3VyY2U8L2NvZGU+LgorICoKKyAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpLb2hzdWtlLkthd2FndWNoaUBTdW4uY29tIj5Lb2hzdWtlIEthd2FndWNoaTwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogODg4ODg0ICQsICREYXRlOiAyMDA5LTEyLTA5IDA5OjM2OjQ2IC0wODAwIChXZWQsIDA5IERlYyAyMDA5KSAkCisgKiBAc2luY2UgMS41CisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBWYWxpZGF0b3IgeworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgZm9yIGRlcml2ZWQgY2xhc3Nlcy4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFRoZSBjb25zdHJ1Y3RvciBkb2VzIG5vdGhpbmcuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBEZXJpdmVkIGNsYXNzZXMgbXVzdCBjcmVhdGUge0BsaW5rIFZhbGlkYXRvcn0gb2JqZWN0cyB0aGF0IGhhdmUKKyAgICAgKiA8dHQ+bnVsbDwvdHQ+IHtAbGluayBFcnJvckhhbmRsZXJ9IGFuZAorICAgICAqIDx0dD5udWxsPC90dD4ge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0uCisgICAgICovCisgICAgcHJvdGVjdGVkIFZhbGlkYXRvcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5SZXNldCB0aGlzIDxjb2RlPlZhbGlkYXRvcjwvY29kZT4gdG8gaXRzIG9yaWdpbmFsIGNvbmZpZ3VyYXRpb24uPC9wPgorICAgICAqCisgICAgICogPHA+PGNvZGU+VmFsaWRhdG9yPC9jb2RlPiBpcyByZXNldCB0byB0aGUgc2FtZSBzdGF0ZSBhcyB3aGVuIGl0IHdhcyBjcmVhdGVkIHdpdGgKKyAgICAgKiB7QGxpbmsgU2NoZW1hI25ld1ZhbGlkYXRvcigpfS4KKyAgICAgKiA8Y29kZT5yZXNldCgpPC9jb2RlPiBpcyBkZXNpZ25lZCB0byBhbGxvdyB0aGUgcmV1c2Ugb2YgZXhpc3RpbmcgPGNvZGU+VmFsaWRhdG9yPC9jb2RlPnMKKyAgICAgKiB0aHVzIHNhdmluZyByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBjcmVhdGlvbiBvZiBuZXcgPGNvZGU+VmFsaWRhdG9yPC9jb2RlPnMuPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIHJlc2V0IDxjb2RlPlZhbGlkYXRvcjwvY29kZT4gaXMgbm90IGd1YXJhbnRlZWQgdG8gaGF2ZSB0aGUgc2FtZSB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfSBvciB7QGxpbmsgRXJyb3JIYW5kbGVyfQorICAgICAqIDxjb2RlPk9iamVjdDwvY29kZT5zLCBlLmcuIHtAbGluayBPYmplY3QjZXF1YWxzKE9iamVjdCBvYmopfS4gIEl0IGlzIGd1YXJhbnRlZWQgdG8gaGF2ZSBhIGZ1bmN0aW9uYWxseSBlcXVhbAorICAgICAqIDxjb2RlPkxTUmVzb3VyY2VSZXNvbHZlcjwvY29kZT4gYW5kIDxjb2RlPkVycm9ySGFuZGxlcjwvY29kZT4uPC9wPgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHJlc2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBWYWxpZGF0ZXMgdGhlIHNwZWNpZmllZCBpbnB1dC4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFRoaXMgaXMganVzdCBhIGNvbnZlbmllbmNlIG1ldGhvZCBvZjoKKyAgICAgKiA8cHJlPgorICAgICAqIHZhbGlkYXRlKHNvdXJjZSxudWxsKTsKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEBzZWUgI3NldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoU291cmNlIHNvdXJjZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICB2YWxpZGF0ZShzb3VyY2UsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFZhbGlkYXRlcyB0aGUgc3BlY2lmaWVkIGlucHV0IGFuZCBzZW5kIHRoZSBhdWdtZW50ZWQgdmFsaWRhdGlvbgorICAgICAqIHJlc3VsdCB0byB0aGUgc3BlY2lmaWVkIG91dHB1dC4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIHBsYWNlcyB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9ucyBvbiB0aGUgdHlwZXMgb2YKKyAgICAgKiB0aGUge0BsaW5rIFNvdXJjZX0ve0BsaW5rIFJlc3VsdH0gYWNjZXB0ZWQuCisgICAgICoKKyAgICAgKiA8aDQ+e0BsaW5rIFNvdXJjZX0ve0BsaW5rIFJlc3VsdH0gYWNjZXB0ZWQ6PC9oND4KKyAgICAgKiA8dGFibGUgYm9yZGVyPTE+CisgICAgICogPHRoZWFkPgorICAgICAqICA8dHI+CisgICAgICogICA8dGQ+PC90ZD4KKyAgICAgKiAgIDx0ZD57QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYU291cmNlfTwvdGQ+CisgICAgICogICA8dGQ+e0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZX08L3RkPgorICAgICAqICAgPHRkPntAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2V9PC90ZD4KKyAgICAgKiAgPC90cj4KKyAgICAgKiA8L3RoZWFkPgorICAgICAqIDx0Ym9keT4KKyAgICAgKiAgPHRyPgorICAgICAqICAgPHRkPjx0dD5udWxsPC90dD48L3RkPgorICAgICAqICAgPHRkPk9LPC90ZD4KKyAgICAgKiAgIDx0ZD5PSzwvdGQ+CisgICAgICogICA8dGQ+T0s8L3RkPgorICAgICAqICAgPHRkPk9LPC90ZD4KKyAgICAgKiAgPC90cj4KKyAgICAgKiAgPHRyPgorICAgICAqICAgPHRkPntAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhSZXN1bHR9PC90ZD4KKyAgICAgKiAgIDx0ZD5PSzwvdGQ+CisgICAgICogICA8dGQ+RXJyPC90ZD4KKyAgICAgKiAgIDx0ZD5FcnI8L3RkPgorICAgICAqICAgPHRkPkVycjwvdGQ+CisgICAgICogIDwvdHI+CisgICAgICogIDx0cj4KKyAgICAgKiAgIDx0ZD57QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NUmVzdWx0fTwvdGQ+CisgICAgICogICA8dGQ+RXJyPC90ZD4KKyAgICAgKiAgIDx0ZD5PSzwvdGQ+CisgICAgICogICA8dGQ+RXJyPC90ZD4KKyAgICAgKiAgIDx0ZD5FcnI8L3RkPgorICAgICAqICA8L3RyPgorICAgICAqICA8dHI+CisgICAgICogICA8dGQ+e0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVJlc3VsdH08L3RkPgorICAgICAqICAgPHRkPkVycjwvdGQ+CisgICAgICogICA8dGQ+RXJyPC90ZD4KKyAgICAgKiAgIDx0ZD5FcnI8L3RkPgorICAgICAqICAgPHRkPk9LPC90ZD4KKyAgICAgKiAgPC90cj4KKyAgICAgKiA8L3Rib2R5PgorICAgICAqIDwvdGFibGU+CisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUbyB2YWxpZGF0ZSBvbmUge0BsaW5rIFNvdXJjZX0gaW50byBhbm90aGVyIGtpbmQgb2Yge0BsaW5rIFJlc3VsdH0sIHVzZSB0aGUgaWRlbnRpdHkgdHJhbnNmb3JtZXIKKyAgICAgKiAoc2VlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSNuZXdUcmFuc2Zvcm1lcigpfSkuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBFcnJvcnMgZm91bmQgZHVyaW5nIHRoZSB2YWxpZGF0aW9uIGlzIHNlbnQgdG8gdGhlIHNwZWNpZmllZAorICAgICAqIHtAbGluayBFcnJvckhhbmRsZXJ9LgorICAgICAqCisgICAgICogPHA+CisgICAgICogSWYgYSBkb2N1bWVudCBpcyB2YWxpZCwgb3IgaWYgYSBkb2N1bWVudCBjb250YWlucyBzb21lIGVycm9ycworICAgICAqIGJ1dCBub25lIG9mIHRoZW0gd2VyZSBmYXRhbCBhbmQgdGhlIHtAbGluayBFcnJvckhhbmRsZXJ9IGRpZG4ndAorICAgICAqIHRocm93IGFueSBleGNlcHRpb24sIHRoZW4gdGhlIG1ldGhvZCByZXR1cm5zIG5vcm1hbGx5LgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZQorICAgICAqICAgICAgWE1MIHRvIGJlIHZhbGlkYXRlZC4gTXVzdCBub3QgYmUgbnVsbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZXN1bHQKKyAgICAgKiAgICAgIFRoZSB7QGxpbmsgUmVzdWx0fSBvYmplY3QgdGhhdCByZWNlaXZlcyAocG9zc2libHkgYXVnbWVudGVkKQorICAgICAqICAgICAgWE1MLiBUaGlzIHBhcmFtZXRlciBjYW4gYmUgbnVsbCBpZiB0aGUgY2FsbGVyIGlzIG5vdCBpbnRlcmVzdGVkCisgICAgICogICAgICBpbiBpdC4KKyAgICAgKgorICAgICAqICAgICAgTm90ZSB0aGF0IHdoZW4gYSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NUmVzdWx0fSBpcyB1c2VkLAorICAgICAqICAgICAgYSB2YWxpZGF0b3IgbWlnaHQganVzdCBwYXNzIHRoZSBzYW1lIERPTSBub2RlIGZyb20KKyAgICAgKiAgICAgIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01Tb3VyY2V9IHRvCisgICAgICogICAgICB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NUmVzdWx0fQorICAgICAqICAgICAgKGluIHdoaWNoIGNhc2UgPHR0PnNvdXJjZS5nZXROb2RlKCk9PXJlc3VsdC5nZXROb2RlKCk8L3R0PiksCisgICAgICogICAgICBpdCBtaWdodCBjb3B5IHRoZSBlbnRpcmUgRE9NIHRyZWUsIG9yIGl0IG1pZ2h0IGFsdGVyIHRoZQorICAgICAqICAgICAgbm9kZSBnaXZlbiBieSB0aGUgc291cmNlLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKiAgICAgIElmIHRoZSB7QGxpbmsgUmVzdWx0fSB0eXBlIGRvZXNuJ3QgbWF0Y2ggdGhlIHtAbGluayBTb3VyY2V9IHR5cGUsCisgICAgICogICAgICBvciBpZiB0aGUgc3BlY2lmaWVkIHNvdXJjZSBpcyBub3QgYQorICAgICAqICAgICAge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZX0sCisgICAgICogICAgICB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NU291cmNlfSBvcgorICAgICAqICAgICAge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZX0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgICAqICAgICAgSWYgdGhlIHtAbGluayBFcnJvckhhbmRsZXJ9IHRocm93cyBhIHtAbGluayBTQVhFeGNlcHRpb259IG9yCisgICAgICogICAgICBpZiBhIGZhdGFsIGVycm9yIGlzIGZvdW5kIGFuZCB0aGUge0BsaW5rIEVycm9ySGFuZGxlcn0gcmV0dXJucworICAgICAqICAgICAgbm9ybWFsbHkuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICBJZiB0aGUgdmFsaWRhdG9yIGlzIHByb2Nlc3NpbmcgYQorICAgICAqICAgICAge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZX0gYW5kIHRoZQorICAgICAqICAgICAgdW5kZXJseWluZyB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyfSB0aHJvd3MgYW4KKyAgICAgKiAgICAgIHtAbGluayBJT0V4Y2VwdGlvbn0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICBJZiB0aGUgPHR0PnNvdXJjZTwvdHQ+IHBhcmFtZXRlciBpcyBudWxsLgorICAgICAqCisgICAgICogQHNlZSAjdmFsaWRhdGUoU291cmNlKQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHZhbGlkYXRlKFNvdXJjZSBzb3VyY2UsIFJlc3VsdCByZXN1bHQpIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUge0BsaW5rIEVycm9ySGFuZGxlcn0gdG8gcmVjZWl2ZSBlcnJvcnMgZW5jb3VudGVyZWQKKyAgICAgKiBkdXJpbmcgdGhlIDxjb2RlPnZhbGlkYXRlPC9jb2RlPiBtZXRob2QgaW52b2NhdGlvbi4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIEVycm9yIGhhbmRsZXIgY2FuIGJlIHVzZWQgdG8gY3VzdG9taXplIHRoZSBlcnJvciBoYW5kbGluZyBwcm9jZXNzCisgICAgICogZHVyaW5nIGEgdmFsaWRhdGlvbi4gV2hlbiBhbiB7QGxpbmsgRXJyb3JIYW5kbGVyfSBpcyBzZXQsCisgICAgICogZXJyb3JzIGZvdW5kIGR1cmluZyB0aGUgdmFsaWRhdGlvbiB3aWxsIGJlIGZpcnN0IHNlbnQKKyAgICAgKiB0byB0aGUge0BsaW5rIEVycm9ySGFuZGxlcn0uCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZXJyb3IgaGFuZGxlciBjYW4gYWJvcnQgZnVydGhlciB2YWxpZGF0aW9uIGltbWVkaWF0ZWx5CisgICAgICogYnkgdGhyb3dpbmcge0BsaW5rIFNBWEV4Y2VwdGlvbn0gZnJvbSB0aGUgaGFuZGxlci4gT3IgZm9yIGV4YW1wbGUKKyAgICAgKiBpdCBjYW4gcHJpbnQgYW4gZXJyb3IgdG8gdGhlIHNjcmVlbiBhbmQgdHJ5IHRvIGNvbnRpbnVlIHRoZQorICAgICAqIHZhbGlkYXRpb24gYnkgcmV0dXJuaW5nIG5vcm1hbGx5IGZyb20gdGhlIHtAbGluayBFcnJvckhhbmRsZXJ9CisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBJZiBhbnkge0BsaW5rIFRocm93YWJsZX0gaXMgdGhyb3duIGZyb20gYW4ge0BsaW5rIEVycm9ySGFuZGxlcn0sCisgICAgICogdGhlIGNhbGxlciBvZiB0aGUgPGNvZGU+dmFsaWRhdGU8L2NvZGU+IG1ldGhvZCB3aWxsIGJlIHRocm93bgorICAgICAqIHRoZSBzYW1lIHtAbGluayBUaHJvd2FibGV9IG9iamVjdC4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIHtAbGluayBWYWxpZGF0b3J9IGlzIG5vdCBhbGxvd2VkIHRvCisgICAgICogdGhyb3cge0BsaW5rIFNBWEV4Y2VwdGlvbn0gd2l0aG91dCBmaXJzdCByZXBvcnRpbmcgaXQgdG8KKyAgICAgKiB7QGxpbmsgRXJyb3JIYW5kbGVyfS4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFdoZW4gdGhlIHtAbGluayBFcnJvckhhbmRsZXJ9IGlzIG51bGwsIHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsCisgICAgICogYmVoYXZlIGFzIGlmIHRoZSBmb2xsb3dpbmcge0BsaW5rIEVycm9ySGFuZGxlcn0gaXMgc2V0OgorICAgICAqIDxwcmU+CisgICAgICogY2xhc3MgRHJhY29uaWFuRXJyb3JIYW5kbGVyIGltcGxlbWVudHMge0BsaW5rIEVycm9ySGFuZGxlcn0geworICAgICAqICAgICBwdWJsaWMgdm9pZCBmYXRhbEVycm9yKCB7QGxpbmsgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb259IGUgKSB0aHJvd3Mge0BsaW5rIFNBWEV4Y2VwdGlvbn0geworICAgICAqICAgICAgICAgdGhyb3cgZTsKKyAgICAgKiAgICAgfQorICAgICAqICAgICBwdWJsaWMgdm9pZCBlcnJvcigge0BsaW5rIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9ufSBlICkgdGhyb3dzIHtAbGluayBTQVhFeGNlcHRpb259IHsKKyAgICAgKiAgICAgICAgIHRocm93IGU7CisgICAgICogICAgIH0KKyAgICAgKiAgICAgcHVibGljIHZvaWQgd2FybmluZygge0BsaW5rIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9ufSBlICkgdGhyb3dzIHtAbGluayBTQVhFeGNlcHRpb259IHsKKyAgICAgKiAgICAgICAgIC8vIG5vb3AKKyAgICAgKiAgICAgfQorICAgICAqIH0KKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFdoZW4gYSBuZXcge0BsaW5rIFZhbGlkYXRvcn0gb2JqZWN0IGlzIGNyZWF0ZWQsIGluaXRpYWxseQorICAgICAqIHRoaXMgZmllbGQgaXMgc2V0IHRvIG51bGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICBlcnJvckhhbmRsZXIKKyAgICAgKiAgICAgIEEgbmV3IGVycm9yIGhhbmRsZXIgdG8gYmUgc2V0LiBUaGlzIHBhcmFtZXRlciBjYW4gYmUgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlcik7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHtAbGluayBFcnJvckhhbmRsZXJ9IHNldCB0byB0aGlzIHtAbGluayBWYWxpZGF0b3J9LgorICAgICAqCisgICAgICogQHJldHVybgorICAgICAqICAgICAgVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgb2JqZWN0IHRoYXQgd2FzIGxhc3Qgc2V0IHRocm91Z2gKKyAgICAgKiAgICAgIHRoZSB7QGxpbmsgI3NldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIpfSBtZXRob2QsIG9yIG51bGwKKyAgICAgKiAgICAgIGlmIHRoYXQgbWV0aG9kIGhhcyBuZXZlciBiZWVuIGNhbGxlZCBzaW5jZSB0aGlzIHtAbGluayBWYWxpZGF0b3J9CisgICAgICogICAgICBoYXMgY3JlYXRlZC4KKyAgICAgKgorICAgICAqIEBzZWUgI3NldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIpCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHtAbGluayBMU1Jlc291cmNlUmVzb2x2ZXJ9IHRvIGN1c3RvbWl6ZQorICAgICAqIHJlc291cmNlIHJlc29sdXRpb24gd2hpbGUgaW4gYSB2YWxpZGF0aW9uIGVwaXNvZGUuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiB7QGxpbmsgVmFsaWRhdG9yfSB1c2VzIGEge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0KKyAgICAgKiB3aGVuIGl0IG5lZWRzIHRvIGxvY2F0ZSBleHRlcm5hbCByZXNvdXJjZXMgd2hpbGUgYSB2YWxpZGF0aW9uLAorICAgICAqIGFsdGhvdWdoIGV4YWN0bHkgd2hhdCBjb25zdGl0dXRlcyAibG9jYXRpbmcgZXh0ZXJuYWwgcmVzb3VyY2VzIiBpcworICAgICAqIHVwIHRvIGVhY2ggc2NoZW1hIGxhbmd1YWdlLgorICAgICAqCisgICAgICogPHA+CisgICAgICogV2hlbiB0aGUge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0gaXMgbnVsbCwgdGhlIGltcGxlbWVudGF0aW9uIHdpbGwKKyAgICAgKiBiZWhhdmUgYXMgaWYgdGhlIGZvbGxvd2luZyB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfSBpcyBzZXQ6CisgICAgICogPHByZT4KKyAgICAgKiBjbGFzcyBEdW1iTFNSZXNvdXJjZVJlc29sdmVyIGltcGxlbWVudHMge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0geworICAgICAqICAgICBwdWJsaWMge0BsaW5rIG9yZy53M2MuZG9tLmxzLkxTSW5wdXR9IHJlc29sdmVSZXNvdXJjZSgKKyAgICAgKiAgICAgICAgIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgYmFzZVVSSSkgeworICAgICAqCisgICAgICogICAgICAgICByZXR1cm4gbnVsbDsgLy8gYWx3YXlzIHJldHVybiBudWxsCisgICAgICogICAgIH0KKyAgICAgKiB9CisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBJZiBhIHtAbGluayBMU1Jlc291cmNlUmVzb2x2ZXJ9IHRocm93cyBhIHtAbGluayBSdW50aW1lRXhjZXB0aW9ufQorICAgICAqICAob3IgaW5zdGFuY2VzIG9mIGl0cyBkZXJpdmVkIGNsYXNzZXMpLAorICAgICAqIHRoZW4gdGhlIHtAbGluayBWYWxpZGF0b3J9IHdpbGwgYWJvcnQgdGhlIHBhcnNpbmcgYW5kCisgICAgICogdGhlIGNhbGxlciBvZiB0aGUgPGNvZGU+dmFsaWRhdGU8L2NvZGU+IG1ldGhvZCB3aWxsIHJlY2VpdmUKKyAgICAgKiB0aGUgc2FtZSB7QGxpbmsgUnVudGltZUV4Y2VwdGlvbn0uCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBXaGVuIGEgbmV3IHtAbGluayBWYWxpZGF0b3J9IG9iamVjdCBpcyBjcmVhdGVkLCBpbml0aWFsbHkKKyAgICAgKiB0aGlzIGZpZWxkIGlzIHNldCB0byBudWxsLgorICAgICAqCisgICAgICogQHBhcmFtICAgcmVzb3VyY2VSZXNvbHZlcgorICAgICAqICAgICAgQSBuZXcgcmVzb3VyY2UgcmVzb2x2ZXIgdG8gYmUgc2V0LiBUaGlzIHBhcmFtZXRlciBjYW4gYmUgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRSZXNvdXJjZVJlc29sdmVyKExTUmVzb3VyY2VSZXNvbHZlciByZXNvdXJjZVJlc29sdmVyKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGN1cnJlbnQge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0gc2V0IHRvIHRoaXMge0BsaW5rIFZhbGlkYXRvcn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBvYmplY3QgdGhhdCB3YXMgbGFzdCBzZXQgdGhyb3VnaAorICAgICAqICAgICAgdGhlIHtAbGluayAjc2V0UmVzb3VyY2VSZXNvbHZlcihMU1Jlc291cmNlUmVzb2x2ZXIpfSBtZXRob2QsIG9yIG51bGwKKyAgICAgKiAgICAgIGlmIHRoYXQgbWV0aG9kIGhhcyBuZXZlciBiZWVuIGNhbGxlZCBzaW5jZSB0aGlzIHtAbGluayBWYWxpZGF0b3J9CisgICAgICogICAgICBoYXMgY3JlYXRlZC4KKyAgICAgKgorICAgICAqIEBzZWUgI3NldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIpCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IExTUmVzb3VyY2VSZXNvbHZlciBnZXRSZXNvdXJjZVJlc29sdmVyKCk7CisKKworCisgICAgLyoqCisgICAgICogTG9vayB1cCB0aGUgdmFsdWUgb2YgYSBmZWF0dXJlIGZsYWcuCisgICAgICoKKyAgICAgKiA8cD5UaGUgZmVhdHVyZSBuYW1lIGlzIGFueSBmdWxseS1xdWFsaWZpZWQgVVJJLiAgSXQgaXMKKyAgICAgKiBwb3NzaWJsZSBmb3IgYSB7QGxpbmsgVmFsaWRhdG9yfSB0byByZWNvZ25pemUgYSBmZWF0dXJlIG5hbWUgYnV0CisgICAgICogdGVtcG9yYXJpbHkgYmUgdW5hYmxlIHRvIHJldHVybiBpdHMgdmFsdWUuCisgICAgICogU29tZSBmZWF0dXJlIHZhbHVlcyBtYXkgYmUgYXZhaWxhYmxlIG9ubHkgaW4gc3BlY2lmaWMKKyAgICAgKiBjb250ZXh0cywgc3VjaCBhcyBiZWZvcmUsIGR1cmluZywgb3IgYWZ0ZXIgYSB2YWxpZGF0aW9uLgorICAgICAqCisgICAgICogPHA+SW1wbGVtZW50b3JzIGFyZSBmcmVlIChhbmQgZW5jb3VyYWdlZCkgdG8gaW52ZW50IHRoZWlyIG93biBmZWF0dXJlcywKKyAgICAgKiB1c2luZyBuYW1lcyBidWlsdCBvbiB0aGVpciBvd24gVVJJcy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZmVhdHVyZSBuYW1lLCB3aGljaCBpcyBhIG5vbi1udWxsIGZ1bGx5LXF1YWxpZmllZCBVUkkuCisgICAgICogQHJldHVybiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZmVhdHVyZSAodHJ1ZSBvciBmYWxzZSkuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBmZWF0dXJlCisgICAgICogICAgICAgICAgICB2YWx1ZSBjYW4ndCBiZSBhc3NpZ25lZCBvciByZXRyaWV2ZWQuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUKKyAgICAgKiAgICAgICAgICAgIHtAbGluayBWYWxpZGF0b3J9IHJlY29nbml6ZXMgdGhlIGZlYXR1cmUgbmFtZSBidXQKKyAgICAgKiAgICAgICAgICAgIGNhbm5vdCBkZXRlcm1pbmUgaXRzIHZhbHVlIGF0IHRoaXMgdGltZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgV2hlbiB0aGUgbmFtZSBwYXJhbWV0ZXIgaXMgbnVsbC4KKyAgICAgKiBAc2VlICNzZXRGZWF0dXJlKFN0cmluZywgYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYobmFtZT09bnVsbCkgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ0aGUgbmFtZSBwYXJhbWV0ZXIgaXMgbnVsbCIpOworICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgZmVhdHVyZSBmbGFnLgorICAgICAqCisgICAgICogPHA+CisgICAgICogRmVhdHVyZSBjYW4gYmUgdXNlZCB0byBjb250cm9sIHRoZSB3YXkgYSB7QGxpbmsgVmFsaWRhdG9yfQorICAgICAqIHBhcnNlcyBzY2hlbWFzLCBhbHRob3VnaCB7QGxpbmsgVmFsaWRhdG9yfXMgYXJlIG5vdCByZXF1aXJlZAorICAgICAqIHRvIHJlY29nbml6ZSBhbnkgc3BlY2lmaWMgcHJvcGVydHkgbmFtZXMuPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIGZlYXR1cmUgbmFtZSBpcyBhbnkgZnVsbHktcXVhbGlmaWVkIFVSSS4gIEl0IGlzCisgICAgICogcG9zc2libGUgZm9yIGEge0BsaW5rIFZhbGlkYXRvcn0gdG8gZXhwb3NlIGEgZmVhdHVyZSB2YWx1ZSBidXQKKyAgICAgKiB0byBiZSB1bmFibGUgdG8gY2hhbmdlIHRoZSBjdXJyZW50IHZhbHVlLgorICAgICAqIFNvbWUgZmVhdHVyZSB2YWx1ZXMgbWF5IGJlIGltbXV0YWJsZSBvciBtdXRhYmxlIG9ubHkKKyAgICAgKiBpbiBzcGVjaWZpYyBjb250ZXh0cywgc3VjaCBhcyBiZWZvcmUsIGR1cmluZywgb3IgYWZ0ZXIKKyAgICAgKiBhIHZhbGlkYXRpb24uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIGZlYXR1cmUgbmFtZSwgd2hpY2ggaXMgYSBub24tbnVsbCBmdWxseS1xdWFsaWZpZWQgVVJJLgorICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVxdWVzdGVkIHZhbHVlIG9mIHRoZSBmZWF0dXJlICh0cnVlIG9yIGZhbHNlKS4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBJZiB0aGUgZmVhdHVyZQorICAgICAqICAgICAgICAgICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCisgICAgICogICAgICAgICAgICB7QGxpbmsgVmFsaWRhdG9yfSByZWNvZ25pemVzIHRoZSBmZWF0dXJlIG5hbWUgYnV0CisgICAgICogICAgICAgICAgICBjYW5ub3Qgc2V0IHRoZSByZXF1ZXN0ZWQgdmFsdWUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgICAgIFdoZW4gdGhlIG5hbWUgcGFyYW1ldGVyIGlzIG51bGwuCisgICAgICoKKyAgICAgKiBAc2VlICNnZXRGZWF0dXJlKFN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKSB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYobmFtZT09bnVsbCkgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ0aGUgbmFtZSBwYXJhbWV0ZXIgaXMgbnVsbCIpOworICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcHJvcGVydHkgbmFtZSBpcyBhbnkgZnVsbHktcXVhbGlmaWVkIFVSSS4gIEl0IGlzCisgICAgICogcG9zc2libGUgZm9yIGEge0BsaW5rIFZhbGlkYXRvcn0gdG8gcmVjb2duaXplIGEgcHJvcGVydHkgbmFtZSBidXQKKyAgICAgKiB0byBiZSB1bmFibGUgdG8gY2hhbmdlIHRoZSBjdXJyZW50IHZhbHVlLgorICAgICAqIFNvbWUgcHJvcGVydHkgdmFsdWVzIG1heSBiZSBpbW11dGFibGUgb3IgbXV0YWJsZSBvbmx5CisgICAgICogaW4gc3BlY2lmaWMgY29udGV4dHMsIHN1Y2ggYXMgYmVmb3JlLCBkdXJpbmcsIG9yIGFmdGVyCisgICAgICogYSB2YWxpZGF0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIDxwPntAbGluayBWYWxpZGF0b3J9cyBhcmUgbm90IHJlcXVpcmVkIHRvIHJlY29nbml6ZSBzZXR0aW5nCisgICAgICogYW55IHNwZWNpZmljIHByb3BlcnR5IG5hbWVzLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBwcm9wZXJ0eSBuYW1lLCB3aGljaCBpcyBhIG5vbi1udWxsIGZ1bGx5LXF1YWxpZmllZCBVUkkuCisgICAgICogQHBhcmFtIG9iamVjdCBUaGUgcmVxdWVzdGVkIHZhbHVlIGZvciB0aGUgcHJvcGVydHkuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eQorICAgICAqICAgICAgICAgICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCisgICAgICogICAgICAgICAgICB7QGxpbmsgVmFsaWRhdG9yfSByZWNvZ25pemVzIHRoZSBwcm9wZXJ0eSBuYW1lIGJ1dAorICAgICAqICAgICAgICAgICAgY2Fubm90IHNldCB0aGUgcmVxdWVzdGVkIHZhbHVlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICBXaGVuIHRoZSBuYW1lIHBhcmFtZXRlciBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBuYW1lLCBPYmplY3Qgb2JqZWN0KSB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYobmFtZT09bnVsbCkgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ0aGUgbmFtZSBwYXJhbWV0ZXIgaXMgbnVsbCIpOworICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb29rIHVwIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LgorICAgICAqCisgICAgICogPHA+VGhlIHByb3BlcnR5IG5hbWUgaXMgYW55IGZ1bGx5LXF1YWxpZmllZCBVUkkuICBJdCBpcworICAgICAqIHBvc3NpYmxlIGZvciBhIHtAbGluayBWYWxpZGF0b3J9IHRvIHJlY29nbml6ZSBhIHByb3BlcnR5IG5hbWUgYnV0CisgICAgICogdGVtcG9yYXJpbHkgYmUgdW5hYmxlIHRvIHJldHVybiBpdHMgdmFsdWUuCisgICAgICogU29tZSBwcm9wZXJ0eSB2YWx1ZXMgbWF5IGJlIGF2YWlsYWJsZSBvbmx5IGluIHNwZWNpZmljCisgICAgICogY29udGV4dHMsIHN1Y2ggYXMgYmVmb3JlLCBkdXJpbmcsIG9yIGFmdGVyIGEgdmFsaWRhdGlvbi48L3A+CisgICAgICoKKyAgICAgKiA8cD57QGxpbmsgVmFsaWRhdG9yfXMgYXJlIG5vdCByZXF1aXJlZCB0byByZWNvZ25pemUgYW55IHNwZWNpZmljCisgICAgICogcHJvcGVydHkgbmFtZXMuPC9wPgorICAgICAqCisgICAgICogPHA+SW1wbGVtZW50b3JzIGFyZSBmcmVlIChhbmQgZW5jb3VyYWdlZCkgdG8gaW52ZW50IHRoZWlyIG93biBwcm9wZXJ0aWVzLAorICAgICAqIHVzaW5nIG5hbWVzIGJ1aWx0IG9uIHRoZWlyIG93biBVUklzLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBwcm9wZXJ0eSBuYW1lLCB3aGljaCBpcyBhIG5vbi1udWxsIGZ1bGx5LXF1YWxpZmllZCBVUkkuCisgICAgICogQHJldHVybiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcHJvcGVydHkuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eQorICAgICAqICAgICAgICAgICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCisgICAgICogICAgICAgICAgICBYTUxSZWFkZXIgcmVjb2duaXplcyB0aGUgcHJvcGVydHkgbmFtZSBidXQKKyAgICAgKiAgICAgICAgICAgIGNhbm5vdCBkZXRlcm1pbmUgaXRzIHZhbHVlIGF0IHRoaXMgdGltZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgV2hlbiB0aGUgbmFtZSBwYXJhbWV0ZXIgaXMgbnVsbC4KKyAgICAgKiBAc2VlICNzZXRQcm9wZXJ0eShTdHJpbmcsIE9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYobmFtZT09bnVsbCkgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ0aGUgbmFtZSBwYXJhbWV0ZXIgaXMgbnVsbCIpOworICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3ZhbGlkYXRpb24vVmFsaWRhdG9ySGFuZGxlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC92YWxpZGF0aW9uL1ZhbGlkYXRvckhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NjA2MTkzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC92YWxpZGF0aW9uL1ZhbGlkYXRvckhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDQ1MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvLyAkSWQ6IFZhbGlkYXRvckhhbmRsZXIuamF2YSA0NDY1OTggMjAwNi0wOS0xNSAxMjo1NTo0MFogamVyZW1pYXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC52YWxpZGF0aW9uOworCitpbXBvcnQgb3JnLnczYy5kb20ubHMuTFNSZXNvdXJjZVJlc29sdmVyOworaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKKworLyoqCisgKiBTdHJlYW1pbmcgdmFsaWRhdG9yIHRoYXQgd29ya3Mgb24gU0FYIHN0cmVhbS4KKyAqCisgKiA8cD4KKyAqIEEge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9IG9iamVjdCBpcyBhIHRocmVhZC11bnNhZmUsIG5vbi1yZWVudHJhbnQgb2JqZWN0LgorICogSW4gb3RoZXIgd29yZHMsIGl0IGlzIHRoZSBhcHBsaWNhdGlvbidzIHJlc3BvbnNpYmlsaXR5IHRvIG1ha2UKKyAqIHN1cmUgdGhhdCBvbmUge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9IG9iamVjdCBpcyBub3QgdXNlZCBmcm9tCisgKiBtb3JlIHRoYW4gb25lIHRocmVhZCBhdCBhbnkgZ2l2ZW4gdGltZS4KKyAqCisgKiA8cD4KKyAqIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSBjaGVja3MgaWYgdGhlIFNBWCBldmVudHMgZm9sbG93CisgKiB0aGUgc2V0IG9mIGNvbnN0cmFpbnRzIGRlc2NyaWJlZCBpbiB0aGUgYXNzb2NpYXRlZCB7QGxpbmsgU2NoZW1hfSwKKyAqIGFuZCBhZGRpdGlvbmFsbHkgaXQgbWF5IG1vZGlmeSB0aGUgU0FYIGV2ZW50cyAoZm9yIGV4YW1wbGUKKyAqIGJ5IGFkZGluZyBkZWZhdWx0IHZhbHVlcywgZXRjLikKKyAqCisgKiA8cD4KKyAqIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSBleHRlbmRzIGZyb20ge0BsaW5rIENvbnRlbnRIYW5kbGVyfSwKKyAqIGJ1dCBpdCByZWZpbmVzIHRoZSB1bmRlcmx5aW5nIHtAbGluayBDb250ZW50SGFuZGxlcn0gaW4KKyAqIHRoZSBmb2xsb3dpbmcgd2F5OgorICogPG9sPgorICogIDxsaT5zdGFydEVsZW1lbnQvZW5kRWxlbWVudCBldmVudHMgbXVzdCByZWNlaXZlIG5vbi1udWxsIFN0cmluZworICogICAgICBmb3IgPGNvZGU+dXJpPC9jb2RlPiwgPGNvZGU+bG9jYWxOYW1lPC9jb2RlPiwgYW5kIDxjb2RlPnFuYW1lPC9jb2RlPiwKKyAqICAgICAgZXZlbiB0aG91Z2ggU0FYIGFsbG93cyBzb21lIG9mIHRoZW0gdG8gYmUgbnVsbC4KKyAqICAgICAgU2ltaWxhcmx5LCB0aGUgdXNlci1zcGVjaWZpZWQge0BsaW5rIENvbnRlbnRIYW5kbGVyfSB3aWxsIHJlY2VpdmUgbm9uLW51bGwKKyAqICAgICAgU3RyaW5ncyBmb3IgYWxsIHRocmVlIHBhcmFtZXRlcnMuCisgKgorICogIDxsaT5BcHBsaWNhdGlvbnMgbXVzdCBlbnN1cmUgdGhhdCB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0ncworICogICAgICB7QGxpbmsgQ29udGVudEhhbmRsZXIjc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyxTdHJpbmcpfSBhbmQKKyAqICAgICAge0BsaW5rIENvbnRlbnRIYW5kbGVyI2VuZFByZWZpeE1hcHBpbmcoU3RyaW5nKX0gYXJlIGludm9rZWQKKyAqICAgICAgcHJvcGVybHkuIFNpbWlsYXJseSwgdGhlIHVzZXItc3BlY2lmaWVkIHtAbGluayBDb250ZW50SGFuZGxlcn0KKyAqICAgICAgd2lsbCByZWNlaXZlIHN0YXJ0UHJlZml4TWFwcGluZy9lbmRQcmVmaXhNYXBwaW5nIGV2ZW50cy4KKyAqICAgICAgSWYgdGhlIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSBpbnRyb2R1Y2VzIGFkZGl0aW9uYWwgbmFtZXNwYWNlCisgKiAgICAgIGJpbmRpbmdzLCB0aGUgdXNlci1zcGVjaWZpZWQge0BsaW5rIENvbnRlbnRIYW5kbGVyfSB3aWxsIHJlY2VpdmUKKyAqICAgICAgYWRkaXRpb25hbCBzdGFydFByZWZpeE1hcHBpbmcvZW5kUHJlZml4TWFwcGluZyBldmVudHMuCisgKgorICogIDxsaT57QGxpbmsgb3JnLnhtbC5zYXguQXR0cmlidXRlc30gZm9yIHRoZQorICogICAgICB7QGxpbmsgQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50KFN0cmluZyxTdHJpbmcsU3RyaW5nLEF0dHJpYnV0ZXMpfSBtZXRob2QKKyAqICAgICAgbWF5IG9yIG1heSBub3QgaW5jbHVkZSB4bWxucyogYXR0cmlidXRlcy4KKyAqIDwvb2w+CisgKgorICogPHA+CisgKiBBIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSBpcyBhdXRvbWF0aWNhbGx5IHJlc2V0IGV2ZXJ5IHRpbWUKKyAqIHRoZSBzdGFydERvY3VtZW50IG1ldGhvZCBpcyBpbnZva2VkLgorICoKKyAqIDxoMj5SZWNvZ25pemVkIFByb3BlcnRpZXMgYW5kIEZlYXR1cmVzPC9oMj4KKyAqIDxwPgorICogVGhpcyBzcGVjIGRlZmluZXMgdGhlIGZvbGxvd2luZyBmZWF0dXJlIHRoYXQgbXVzdCBiZSByZWNvZ25pemVkCisgKiBieSBhbGwge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9IGltcGxlbWVudGF0aW9ucy4KKyAqCisgKiA8aDM+PGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZS1wcmVmaXhlczwvY29kZT48L2gzPgorICogPHA+CisgKiBUaGlzIGZlYXR1cmUgY29udHJvbHMgaG93IGEge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9IGludHJvZHVjZXMKKyAqIG5hbWVzcGFjZSBiaW5kaW5ncyB0aGF0IHdlcmUgbm90IHByZXNlbnQgaW4gdGhlIG9yaWdpbmFsIFNBWCBldmVudAorICogc3RyZWFtLgorICogV2hlbiB0aGlzIGZlYXR1cmUgaXMgc2V0IHRvIHRydWUsIGl0IG11c3QgbWFrZQorICogc3VyZSB0aGF0IHRoZSB1c2VyJ3Mge0BsaW5rIENvbnRlbnRIYW5kbGVyfSB3aWxsIHNlZQorICogdGhlIGNvcnJlc3BvbmRpbmcgPGNvZGU+eG1sbnMqPC9jb2RlPiBhdHRyaWJ1dGUgaW4KKyAqIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguQXR0cmlidXRlc30gb2JqZWN0IG9mIHRoZQorICoge0BsaW5rIENvbnRlbnRIYW5kbGVyI3N0YXJ0RWxlbWVudChTdHJpbmcsU3RyaW5nLFN0cmluZyxBdHRyaWJ1dGVzKX0KKyAqIGNhbGxiYWNrLiBPdGhlcndpc2UsIDxjb2RlPnhtbG5zKjwvY29kZT4gYXR0cmlidXRlcyBtdXN0IG5vdCBiZQorICogYWRkZWQgdG8ge0BsaW5rIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXN9IHRoYXQncyBwYXNzZWQgdG8gdGhlCisgKiB1c2VyLXNwZWNpZmllZCB7QGxpbmsgQ29udGVudEhhbmRsZXJ9LgorICogPHA+CisgKiAoTm90ZSB0aGF0IHJlZ2FyZGxlc3Mgb2YgdGhpcyBzd2l0Y2gsIG5hbWVzcGFjZSBiaW5kaW5ncyBhcmUKKyAqIGFsd2F5cyBub3RpZmllZCB0byBhcHBsaWNhdGlvbnMgdGhyb3VnaAorICoge0BsaW5rIENvbnRlbnRIYW5kbGVyI3N0YXJ0UHJlZml4TWFwcGluZyhTdHJpbmcsU3RyaW5nKX0gYW5kCisgKiB7QGxpbmsgQ29udGVudEhhbmRsZXIjZW5kUHJlZml4TWFwcGluZyhTdHJpbmcpfSBtZXRob2RzIG9mIHRoZQorICoge0BsaW5rIENvbnRlbnRIYW5kbGVyfSBzcGVjaWZpZWQgYnkgdGhlIHVzZXIuKQorICoKKyAqIDxwPgorICogTm90ZSB0aGF0IHRoaXMgZmVhdHVyZSBkb2VzIDxlbT5OT1Q8L2VtPiBhZmZlY3QgdGhlIHdheQorICogYSB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gcmVjZWl2ZXMgU0FYIGV2ZW50cy4gSXQgbWVyZWx5CisgKiBjaGFuZ2VzIHRoZSB3YXkgaXQgYXVnbWVudHMgU0FYIGV2ZW50cy4KKyAqCisgKiA8cD5UaGlzIGZlYXR1cmUgaXMgc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiBieSBkZWZhdWx0LjwvcD4KKyAqCisgKiBAYXV0aG9yICA8YSBocmVmPSJtYWlsdG86S29oc3VrZS5LYXdhZ3VjaGlAU3VuLmNvbSI+S29oc3VrZSBLYXdhZ3VjaGk8L2E+CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDQ0NjU5OCAkLCAkRGF0ZTogMjAwNi0wOS0xNSAwNTo1NTo0MCAtMDcwMCAoRnJpLCAxNSBTZXAgMjAwNikgJAorICogQHNpbmNlIDEuNQorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgVmFsaWRhdG9ySGFuZGxlciBpbXBsZW1lbnRzIENvbnRlbnRIYW5kbGVyIHsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIGZvciBkZXJpdmVkIGNsYXNzZXMuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgY29uc3RydWN0b3IgZG9lcyBub3RoaW5nLgorICAgICAqCisgICAgICogPHA+CisgICAgICogRGVyaXZlZCBjbGFzc2VzIG11c3QgY3JlYXRlIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSBvYmplY3RzIHRoYXQgaGF2ZQorICAgICAqIDx0dD5udWxsPC90dD4ge0BsaW5rIEVycm9ySGFuZGxlcn0gYW5kCisgICAgICogPHR0Pm51bGw8L3R0PiB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgVmFsaWRhdG9ySGFuZGxlcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IHdoaWNoIHJlY2VpdmVzCisgICAgICogdGhlIGF1Z21lbnRlZCB2YWxpZGF0aW9uIHJlc3VsdC4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFdoZW4gYSB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IGlzIHNwZWNpZmllZCwgYQorICAgICAqIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSB3aWxsIHdvcmsgYXMgYSBmaWx0ZXIKKyAgICAgKiBhbmQgYmFzaWNhbGx5IGNvcHkgdGhlIGluY29taW5nIGV2ZW50cyB0byB0aGUKKyAgICAgKiBzcGVjaWZpZWQge0BsaW5rIENvbnRlbnRIYW5kbGVyfS4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIEluIGRvaW5nIHNvLCBhIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSBtYXkgbW9kaWZ5CisgICAgICogdGhlIGV2ZW50cywgZm9yIGV4YW1wbGUgYnkgYWRkaW5nIGRlZmF1bHRlZCBhdHRyaWJ1dGVzLgorICAgICAqCisgICAgICogPHA+CisgICAgICogQSB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gbWF5IGJ1ZmZlciBldmVudHMgdG8gY2VydGFpbgorICAgICAqIGV4dGVudCwgYnV0IHRvIGFsbG93IHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSB0byBiZSB1c2VkCisgICAgICogYnkgYSBwYXJzZXIsIHRoZSBmb2xsb3dpbmcgcmVxdWlyZW1lbnQgaGFzIHRvIGJlIG1ldC4KKyAgICAgKgorICAgICAqIDxvbD4KKyAgICAgKiAgPGxpPldoZW4KKyAgICAgKiAgICAgIHtAbGluayBDb250ZW50SGFuZGxlciNzdGFydEVsZW1lbnQoU3RyaW5nLCBTdHJpbmcsIFN0cmluZywgQXR0cmlidXRlcyl9LAorICAgICAqICAgICAge0BsaW5rIENvbnRlbnRIYW5kbGVyI2VuZEVsZW1lbnQoU3RyaW5nLCBTdHJpbmcsIFN0cmluZyl9LAorICAgICAqICAgICAge0BsaW5rIENvbnRlbnRIYW5kbGVyI3N0YXJ0RG9jdW1lbnQoKX0sIG9yCisgICAgICogICAgICB7QGxpbmsgQ29udGVudEhhbmRsZXIjZW5kRG9jdW1lbnQoKX0KKyAgICAgKiAgICAgIGFyZSBpbnZva2VkIG9uIGEge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9LAorICAgICAqICAgICAgdGhlIHNhbWUgbWV0aG9kIG9uIHRoZSB1c2VyLXNwZWNpZmllZCB7QGxpbmsgQ29udGVudEhhbmRsZXJ9CisgICAgICogICAgICBtdXN0IGJlIGludm9rZWQgZm9yIHRoZSBzYW1lIGV2ZW50IGJlZm9yZSB0aGUgY2FsbGJhY2sKKyAgICAgKiAgICAgIHJldHVybnMuCisgICAgICogIDxsaT57QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gbWF5IG5vdCBpbnRyb2R1Y2UgbmV3IGVsZW1lbnRzIHRoYXQKKyAgICAgKiAgICAgIHdlcmUgbm90IHByZXNlbnQgaW4gdGhlIGlucHV0LgorICAgICAqCisgICAgICogIDxsaT57QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gbWF5IG5vdCByZW1vdmUgYXR0cmlidXRlcyB0aGF0IHdlcmUKKyAgICAgKiAgICAgIHByZXNlbnQgaW4gdGhlIGlucHV0LgorICAgICAqIDwvb2w+CisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBXaGVuIGEgY2FsbGJhY2sgbWV0aG9kIG9uIHRoZSBzcGVjaWZpZWQge0BsaW5rIENvbnRlbnRIYW5kbGVyfQorICAgICAqIHRocm93cyBhbiBleGNlcHRpb24sIHRoZSBzYW1lIGV4Y2VwdGlvbiBvYmplY3QgbXVzdCBiZSB0aHJvd24KKyAgICAgKiBmcm9tIHRoZSB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0uIFRoZSB7QGxpbmsgRXJyb3JIYW5kbGVyfQorICAgICAqIHNob3VsZCBub3QgYmUgbm90aWZpZWQgb2Ygc3VjaCBhbiBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgY2FsbGVkIGV2ZW4gZHVyaW5nIGEgbWlkZGxlIG9mIGEgdmFsaWRhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWNlaXZlcgorICAgICAqICAgICAgQSB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IG9yIGEgbnVsbCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRDb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlciByZWNlaXZlcik7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IHdoaWNoIHJlY2VpdmVzIHRoZQorICAgICAqIGF1Z21lbnRlZCB2YWxpZGF0aW9uIHJlc3VsdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4KKyAgICAgKiAgICAgIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIG9iamVjdCB0aGF0IHdhcyBsYXN0IHNldCB0aHJvdWdoCisgICAgICogICAgICB0aGUge0BsaW5rICNnZXRDb250ZW50SGFuZGxlcigpfSBtZXRob2QsIG9yIG51bGwKKyAgICAgKiAgICAgIGlmIHRoYXQgbWV0aG9kIGhhcyBuZXZlciBiZWVuIGNhbGxlZCBzaW5jZSB0aGlzIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfQorICAgICAqICAgICAgaGFzIGNyZWF0ZWQuCisgICAgICoKKyAgICAgKiBAc2VlICNzZXRDb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIoKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHtAbGluayBFcnJvckhhbmRsZXJ9IHRvIHJlY2VpdmUgZXJyb3JzIGVuY291bnRlcmVkCisgICAgICogZHVyaW5nIHRoZSB2YWxpZGF0aW9uLgorICAgICAqCisgICAgICogPHA+CisgICAgICogRXJyb3IgaGFuZGxlciBjYW4gYmUgdXNlZCB0byBjdXN0b21pemUgdGhlIGVycm9yIGhhbmRsaW5nIHByb2Nlc3MKKyAgICAgKiBkdXJpbmcgYSB2YWxpZGF0aW9uLiBXaGVuIGFuIHtAbGluayBFcnJvckhhbmRsZXJ9IGlzIHNldCwKKyAgICAgKiBlcnJvcnMgZm91bmQgZHVyaW5nIHRoZSB2YWxpZGF0aW9uIHdpbGwgYmUgZmlyc3Qgc2VudAorICAgICAqIHRvIHRoZSB7QGxpbmsgRXJyb3JIYW5kbGVyfS4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFRoZSBlcnJvciBoYW5kbGVyIGNhbiBhYm9ydCBmdXJ0aGVyIHZhbGlkYXRpb24gaW1tZWRpYXRlbHkKKyAgICAgKiBieSB0aHJvd2luZyB7QGxpbmsgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9ufSBmcm9tIHRoZSBoYW5kbGVyLiBPciBmb3IgZXhhbXBsZQorICAgICAqIGl0IGNhbiBwcmludCBhbiBlcnJvciB0byB0aGUgc2NyZWVuIGFuZCB0cnkgdG8gY29udGludWUgdGhlCisgICAgICogdmFsaWRhdGlvbiBieSByZXR1cm5pbmcgbm9ybWFsbHkgZnJvbSB0aGUge0BsaW5rIEVycm9ySGFuZGxlcn0KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIElmIGFueSB7QGxpbmsgVGhyb3dhYmxlfSBpcyB0aHJvd24gZnJvbSBhbiB7QGxpbmsgRXJyb3JIYW5kbGVyfSwKKyAgICAgKiB0aGUgc2FtZSB7QGxpbmsgVGhyb3dhYmxlfSBvYmplY3Qgd2lsbCBiZSB0aHJvd24gdG93YXJkIHRoZQorICAgICAqIHJvb3Qgb2YgdGhlIGNhbGwgc3RhY2suCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gaXMgbm90IGFsbG93ZWQgdG8KKyAgICAgKiB0aHJvdyB7QGxpbmsgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9ufSB3aXRob3V0IGZpcnN0IHJlcG9ydGluZyBpdCB0bworICAgICAqIHtAbGluayBFcnJvckhhbmRsZXJ9LgorICAgICAqCisgICAgICogPHA+CisgICAgICogV2hlbiB0aGUge0BsaW5rIEVycm9ySGFuZGxlcn0gaXMgbnVsbCwgdGhlIGltcGxlbWVudGF0aW9uIHdpbGwKKyAgICAgKiBiZWhhdmUgYXMgaWYgdGhlIGZvbGxvd2luZyB7QGxpbmsgRXJyb3JIYW5kbGVyfSBpcyBzZXQ6CisgICAgICogPHByZT4KKyAgICAgKiBjbGFzcyBEcmFjb25pYW5FcnJvckhhbmRsZXIgaW1wbGVtZW50cyB7QGxpbmsgRXJyb3JIYW5kbGVyfSB7CisgICAgICogICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoIHtAbGluayBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbn0gZSApIHRocm93cyB7QGxpbmsgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9ufSB7CisgICAgICogICAgICAgICB0aHJvdyBlOworICAgICAqICAgICB9CisgICAgICogICAgIHB1YmxpYyB2b2lkIGVycm9yKCB7QGxpbmsgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb259IGUgKSB0aHJvd3Mge0BsaW5rIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbn0geworICAgICAqICAgICAgICAgdGhyb3cgZTsKKyAgICAgKiAgICAgfQorICAgICAqICAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKCB7QGxpbmsgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb259IGUgKSB0aHJvd3Mge0BsaW5rIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbn0geworICAgICAqICAgICAgICAgLy8gbm9vcAorICAgICAqICAgICB9CisgICAgICogfQorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogPHA+CisgICAgICogV2hlbiBhIG5ldyB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gb2JqZWN0IGlzIGNyZWF0ZWQsIGluaXRpYWxseQorICAgICAqIHRoaXMgZmllbGQgaXMgc2V0IHRvIG51bGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICBlcnJvckhhbmRsZXIKKyAgICAgKiAgICAgIEEgbmV3IGVycm9yIGhhbmRsZXIgdG8gYmUgc2V0LiBUaGlzIHBhcmFtZXRlciBjYW4gYmUgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlcik7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHtAbGluayBFcnJvckhhbmRsZXJ9IHNldCB0byB0aGlzIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfS4KKyAgICAgKgorICAgICAqIEByZXR1cm4KKyAgICAgKiAgICAgIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIG9iamVjdCB0aGF0IHdhcyBsYXN0IHNldCB0aHJvdWdoCisgICAgICogICAgICB0aGUge0BsaW5rICNzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyKX0gbWV0aG9kLCBvciBudWxsCisgICAgICogICAgICBpZiB0aGF0IG1ldGhvZCBoYXMgbmV2ZXIgYmVlbiBjYWxsZWQgc2luY2UgdGhpcyB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0KKyAgICAgKiAgICAgIGhhcyBjcmVhdGVkLgorICAgICAqCisgICAgICogQHNlZSAjc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0gdG8gY3VzdG9taXplCisgICAgICogcmVzb3VyY2UgcmVzb2x1dGlvbiB3aGlsZSBpbiBhIHZhbGlkYXRpb24gZXBpc29kZS4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSB1c2VzIGEge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0KKyAgICAgKiB3aGVuIGl0IG5lZWRzIHRvIGxvY2F0ZSBleHRlcm5hbCByZXNvdXJjZXMgd2hpbGUgYSB2YWxpZGF0aW9uLAorICAgICAqIGFsdGhvdWdoIGV4YWN0bHkgd2hhdCBjb25zdGl0dXRlcyAibG9jYXRpbmcgZXh0ZXJuYWwgcmVzb3VyY2VzIiBpcworICAgICAqIHVwIHRvIGVhY2ggc2NoZW1hIGxhbmd1YWdlLgorICAgICAqCisgICAgICogPHA+CisgICAgICogV2hlbiB0aGUge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0gaXMgbnVsbCwgdGhlIGltcGxlbWVudGF0aW9uIHdpbGwKKyAgICAgKiBiZWhhdmUgYXMgaWYgdGhlIGZvbGxvd2luZyB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfSBpcyBzZXQ6CisgICAgICogPHByZT4KKyAgICAgKiBjbGFzcyBEdW1iTFNSZXNvdXJjZVJlc29sdmVyIGltcGxlbWVudHMge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0geworICAgICAqICAgICBwdWJsaWMge0BsaW5rIG9yZy53M2MuZG9tLmxzLkxTSW5wdXR9IHJlc29sdmVSZXNvdXJjZSgKKyAgICAgKiAgICAgICAgIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgYmFzZVVSSSkgeworICAgICAqCisgICAgICogICAgICAgICByZXR1cm4gbnVsbDsgLy8gYWx3YXlzIHJldHVybiBudWxsCisgICAgICogICAgIH0KKyAgICAgKiB9CisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBJZiBhIHtAbGluayBMU1Jlc291cmNlUmVzb2x2ZXJ9IHRocm93cyBhIHtAbGluayBSdW50aW1lRXhjZXB0aW9ufQorICAgICAqICAob3IgaW5zdGFuY2VzIG9mIGl0cyBkZXJpdmVkIGNsYXNzZXMpLAorICAgICAqIHRoZW4gdGhlIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSB3aWxsIGFib3J0IHRoZSBwYXJzaW5nIGFuZAorICAgICAqIHRoZSBjYWxsZXIgb2YgdGhlIDxjb2RlPnZhbGlkYXRlPC9jb2RlPiBtZXRob2Qgd2lsbCByZWNlaXZlCisgICAgICogdGhlIHNhbWUge0BsaW5rIFJ1bnRpbWVFeGNlcHRpb259LgorICAgICAqCisgICAgICogPHA+CisgICAgICogV2hlbiBhIG5ldyB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gb2JqZWN0IGlzIGNyZWF0ZWQsIGluaXRpYWxseQorICAgICAqIHRoaXMgZmllbGQgaXMgc2V0IHRvIG51bGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICByZXNvdXJjZVJlc29sdmVyCisgICAgICogICAgICBBIG5ldyByZXNvdXJjZSByZXNvbHZlciB0byBiZSBzZXQuIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFJlc291cmNlUmVzb2x2ZXIoTFNSZXNvdXJjZVJlc29sdmVyIHJlc291cmNlUmVzb2x2ZXIpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY3VycmVudCB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfSBzZXQgdG8gdGhpcyB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBvYmplY3QgdGhhdCB3YXMgbGFzdCBzZXQgdGhyb3VnaAorICAgICAqICAgICAgdGhlIHtAbGluayAjc2V0UmVzb3VyY2VSZXNvbHZlcihMU1Jlc291cmNlUmVzb2x2ZXIpfSBtZXRob2QsIG9yIG51bGwKKyAgICAgKiAgICAgIGlmIHRoYXQgbWV0aG9kIGhhcyBuZXZlciBiZWVuIGNhbGxlZCBzaW5jZSB0aGlzIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfQorICAgICAqICAgICAgaGFzIGNyZWF0ZWQuCisgICAgICoKKyAgICAgKiBAc2VlICNzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyKQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBMU1Jlc291cmNlUmVzb2x2ZXIgZ2V0UmVzb3VyY2VSZXNvbHZlcigpOworCisgICAgLyoqCisgICAgICogT2J0YWlucyB0aGUge0BsaW5rIFR5cGVJbmZvUHJvdmlkZXJ9IGltcGxlbWVudGF0aW9uIG9mIHRoaXMKKyAgICAgKiB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0uCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgb2J0YWluZWQge0BsaW5rIFR5cGVJbmZvUHJvdmlkZXJ9IGNhbiBiZSBxdWVyaWVkIGR1cmluZyBhIHBhcnNlCisgICAgICogdG8gYWNjZXNzIHRoZSB0eXBlIGluZm9ybWF0aW9uIGRldGVybWluZWQgYnkgdGhlIHZhbGlkYXRvci4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIFNvbWUgc2NoZW1hIGxhbmd1YWdlcyBkbyBub3QgZGVmaW5lIHRoZSBub3Rpb24gb2YgdHlwZSwKKyAgICAgKiBmb3IgdGhvc2UgbGFuZ3VhZ2VzLCB0aGlzIG1ldGhvZCBtYXkgbm90IGJlIHN1cHBvcnRlZC4KKyAgICAgKiBIb3dldmVyLCB0byBiZSBjb21wbGlhbnQgd2l0aCB0aGlzIHNwZWNpZmljYXRpb24sIGltcGxlbWVudGF0aW9ucworICAgICAqIGZvciBXM0MgWE1MIFNjaGVtYSAxLjAgbXVzdCBzdXBwb3J0IHRoaXMgb3BlcmF0aW9uLgorICAgICAqCisgICAgICogQHJldHVybgorICAgICAqICAgICAgbnVsbCBpZiB0aGUgdmFsaWRhdG9yIC8gc2NoZW1hIGxhbmd1YWdlIGRvZXMgbm90IHN1cHBvcnQKKyAgICAgKiAgICAgIHRoZSBub3Rpb24gb2Yge0BsaW5rIG9yZy53M2MuZG9tLlR5cGVJbmZvfS4KKyAgICAgKiAgICAgIE90aGVyd2lzZSBhIG5vbi1udWxsIHZhbGlkIHtAbGluayBUeXBlSW5mb1Byb3ZpZGVyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgVHlwZUluZm9Qcm92aWRlciBnZXRUeXBlSW5mb1Byb3ZpZGVyKCk7CisKKworICAgIC8qKgorICAgICAqIExvb2sgdXAgdGhlIHZhbHVlIG9mIGEgZmVhdHVyZSBmbGFnLgorICAgICAqCisgICAgICogPHA+VGhlIGZlYXR1cmUgbmFtZSBpcyBhbnkgZnVsbHktcXVhbGlmaWVkIFVSSS4gIEl0IGlzCisgICAgICogcG9zc2libGUgZm9yIGEge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9IHRvIHJlY29nbml6ZSBhIGZlYXR1cmUgbmFtZSBidXQKKyAgICAgKiB0ZW1wb3JhcmlseSBiZSB1bmFibGUgdG8gcmV0dXJuIGl0cyB2YWx1ZS4KKyAgICAgKiBTb21lIGZlYXR1cmUgdmFsdWVzIG1heSBiZSBhdmFpbGFibGUgb25seSBpbiBzcGVjaWZpYworICAgICAqIGNvbnRleHRzLCBzdWNoIGFzIGJlZm9yZSwgZHVyaW5nLCBvciBhZnRlciBhIHZhbGlkYXRpb24uCisgICAgICoKKyAgICAgKiA8cD5JbXBsZW1lbnRvcnMgYXJlIGZyZWUgKGFuZCBlbmNvdXJhZ2VkKSB0byBpbnZlbnQgdGhlaXIgb3duIGZlYXR1cmVzLAorICAgICAqIHVzaW5nIG5hbWVzIGJ1aWx0IG9uIHRoZWlyIG93biBVUklzLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBmZWF0dXJlIG5hbWUsIHdoaWNoIGlzIGEgbm9uLW51bGwgZnVsbHktcXVhbGlmaWVkIFVSSS4KKyAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBmZWF0dXJlICh0cnVlIG9yIGZhbHNlKS4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlIGZlYXR1cmUKKyAgICAgKiAgICAgICAgICAgIHZhbHVlIGNhbid0IGJlIGFzc2lnbmVkIG9yIHJldHJpZXZlZC4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBXaGVuIHRoZQorICAgICAqICAgICAgICAgICAge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9IHJlY29nbml6ZXMgdGhlIGZlYXR1cmUgbmFtZSBidXQKKyAgICAgKiAgICAgICAgICAgIGNhbm5vdCBkZXRlcm1pbmUgaXRzIHZhbHVlIGF0IHRoaXMgdGltZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgV2hlbiB0aGUgbmFtZSBwYXJhbWV0ZXIgaXMgbnVsbC4KKyAgICAgKiBAc2VlICNzZXRGZWF0dXJlKFN0cmluZywgYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYobmFtZT09bnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgZmVhdHVyZSBmbGFnLgorICAgICAqCisgICAgICogPHA+CisgICAgICogRmVhdHVyZSBjYW4gYmUgdXNlZCB0byBjb250cm9sIHRoZSB3YXkgYSB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0KKyAgICAgKiBwYXJzZXMgc2NoZW1hcywgYWx0aG91Z2gge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9cyBhcmUgbm90IHJlcXVpcmVkCisgICAgICogdG8gcmVjb2duaXplIGFueSBzcGVjaWZpYyBwcm9wZXJ0eSBuYW1lcy48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgZmVhdHVyZSBuYW1lIGlzIGFueSBmdWxseS1xdWFsaWZpZWQgVVJJLiAgSXQgaXMKKyAgICAgKiBwb3NzaWJsZSBmb3IgYSB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gdG8gZXhwb3NlIGEgZmVhdHVyZSB2YWx1ZSBidXQKKyAgICAgKiB0byBiZSB1bmFibGUgdG8gY2hhbmdlIHRoZSBjdXJyZW50IHZhbHVlLgorICAgICAqIFNvbWUgZmVhdHVyZSB2YWx1ZXMgbWF5IGJlIGltbXV0YWJsZSBvciBtdXRhYmxlIG9ubHkKKyAgICAgKiBpbiBzcGVjaWZpYyBjb250ZXh0cywgc3VjaCBhcyBiZWZvcmUsIGR1cmluZywgb3IgYWZ0ZXIKKyAgICAgKiBhIHZhbGlkYXRpb24uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIGZlYXR1cmUgbmFtZSwgd2hpY2ggaXMgYSBub24tbnVsbCBmdWxseS1xdWFsaWZpZWQgVVJJLgorICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVxdWVzdGVkIHZhbHVlIG9mIHRoZSBmZWF0dXJlICh0cnVlIG9yIGZhbHNlKS4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBJZiB0aGUgZmVhdHVyZQorICAgICAqICAgICAgICAgICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCisgICAgICogICAgICAgICAgICB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gcmVjb2duaXplcyB0aGUgZmVhdHVyZSBuYW1lIGJ1dAorICAgICAqICAgICAgICAgICAgY2Fubm90IHNldCB0aGUgcmVxdWVzdGVkIHZhbHVlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICBXaGVuIHRoZSBuYW1lIHBhcmFtZXRlciBpcyBudWxsLgorICAgICAqCisgICAgICogQHNlZSAjZ2V0RmVhdHVyZShTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmKG5hbWU9PW51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24obmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LgorICAgICAqCisgICAgICogPHA+VGhlIHByb3BlcnR5IG5hbWUgaXMgYW55IGZ1bGx5LXF1YWxpZmllZCBVUkkuICBJdCBpcworICAgICAqIHBvc3NpYmxlIGZvciBhIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSB0byByZWNvZ25pemUgYSBwcm9wZXJ0eSBuYW1lIGJ1dAorICAgICAqIHRvIGJlIHVuYWJsZSB0byBjaGFuZ2UgdGhlIGN1cnJlbnQgdmFsdWUuCisgICAgICogU29tZSBwcm9wZXJ0eSB2YWx1ZXMgbWF5IGJlIGltbXV0YWJsZSBvciBtdXRhYmxlIG9ubHkKKyAgICAgKiBpbiBzcGVjaWZpYyBjb250ZXh0cywgc3VjaCBhcyBiZWZvcmUsIGR1cmluZywgb3IgYWZ0ZXIKKyAgICAgKiBhIHZhbGlkYXRpb24uPC9wPgorICAgICAqCisgICAgICogPHA+e0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9cyBhcmUgbm90IHJlcXVpcmVkIHRvIHJlY29nbml6ZSBzZXR0aW5nCisgICAgICogYW55IHNwZWNpZmljIHByb3BlcnR5IG5hbWVzLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBwcm9wZXJ0eSBuYW1lLCB3aGljaCBpcyBhIG5vbi1udWxsIGZ1bGx5LXF1YWxpZmllZCBVUkkuCisgICAgICogQHBhcmFtIG9iamVjdCBUaGUgcmVxdWVzdGVkIHZhbHVlIGZvciB0aGUgcHJvcGVydHkuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlIHByb3BlcnR5CisgICAgICogICAgICAgICAgICB2YWx1ZSBjYW4ndCBiZSBhc3NpZ25lZCBvciByZXRyaWV2ZWQuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUKKyAgICAgKiAgICAgICAgICAgIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSByZWNvZ25pemVzIHRoZSBwcm9wZXJ0eSBuYW1lIGJ1dAorICAgICAqICAgICAgICAgICAgY2Fubm90IHNldCB0aGUgcmVxdWVzdGVkIHZhbHVlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICBXaGVuIHRoZSBuYW1lIHBhcmFtZXRlciBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBuYW1lLCBPYmplY3Qgb2JqZWN0KSB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYobmFtZT09bnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb29rIHVwIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LgorICAgICAqCisgICAgICogPHA+VGhlIHByb3BlcnR5IG5hbWUgaXMgYW55IGZ1bGx5LXF1YWxpZmllZCBVUkkuICBJdCBpcworICAgICAqIHBvc3NpYmxlIGZvciBhIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSB0byByZWNvZ25pemUgYSBwcm9wZXJ0eSBuYW1lIGJ1dAorICAgICAqIHRlbXBvcmFyaWx5IGJlIHVuYWJsZSB0byByZXR1cm4gaXRzIHZhbHVlLgorICAgICAqIFNvbWUgcHJvcGVydHkgdmFsdWVzIG1heSBiZSBhdmFpbGFibGUgb25seSBpbiBzcGVjaWZpYworICAgICAqIGNvbnRleHRzLCBzdWNoIGFzIGJlZm9yZSwgZHVyaW5nLCBvciBhZnRlciBhIHZhbGlkYXRpb24uPC9wPgorICAgICAqCisgICAgICogPHA+e0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9cyBhcmUgbm90IHJlcXVpcmVkIHRvIHJlY29nbml6ZSBhbnkgc3BlY2lmaWMKKyAgICAgKiBwcm9wZXJ0eSBuYW1lcy48L3A+CisgICAgICoKKyAgICAgKiA8cD5JbXBsZW1lbnRvcnMgYXJlIGZyZWUgKGFuZCBlbmNvdXJhZ2VkKSB0byBpbnZlbnQgdGhlaXIgb3duIHByb3BlcnRpZXMsCisgICAgICogdXNpbmcgbmFtZXMgYnVpbHQgb24gdGhlaXIgb3duIFVSSXMuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIHByb3BlcnR5IG5hbWUsIHdoaWNoIGlzIGEgbm9uLW51bGwgZnVsbHktcXVhbGlmaWVkIFVSSS4KKyAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eS4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlIHByb3BlcnR5CisgICAgICogICAgICAgICAgICB2YWx1ZSBjYW4ndCBiZSBhc3NpZ25lZCBvciByZXRyaWV2ZWQuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUKKyAgICAgKiAgICAgICAgICAgIFhNTFJlYWRlciByZWNvZ25pemVzIHRoZSBwcm9wZXJ0eSBuYW1lIGJ1dAorICAgICAqICAgICAgICAgICAgY2Fubm90IGRldGVybWluZSBpdHMgdmFsdWUgYXQgdGhpcyB0aW1lLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICBXaGVuIHRoZSBuYW1lIHBhcmFtZXRlciBpcyBudWxsLgorICAgICAqIEBzZWUgI3NldFByb3BlcnR5KFN0cmluZywgT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICBpZihuYW1lPT1udWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIHRocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKG5hbWUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwvdmFsaWRhdGlvbi9wYWNrYWdlLmh0bWwgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3ZhbGlkYXRpb24vcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI5ZjcxYTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3ZhbGlkYXRpb24vcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsOTEgQEAKKzwhRE9DVFlQRSBIVE1MIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCAzLjIgRmluYWwvL0VOIj4KKzwhLS0gJElkOiBwYWNrYWdlLmh0bWwgNTcwMTA0IDIwMDctMDgtMjcgMTM6Mjg6MjRaIG1yZ2xhdmFzICQgLS0+Cis8aHRtbD4KKwk8Ym9keSBiZ2NvbG9yPSJ3aGl0ZSI+CisJCTxwPgorCQkgICAgVGhpcyBwYWNrYWdlIHByb3ZpZGVzIGFuIEFQSSBmb3IgdmFsaWRhdGlvbiBvZiBYTUwgZG9jdW1lbnRzLiAgPGVtPlZhbGlkYXRpb248L2VtPiBpcyB0aGUgcHJvY2VzcyBvZiB2ZXJpZnlpbmcKKwkJICAgIHRoYXQgYW4gWE1MIGRvY3VtZW50IGlzIGFuIGluc3RhbmNlIG9mIGEgc3BlY2lmaWVkIFhNTCA8ZW0+c2NoZW1hPC9lbT4uICBBbiBYTUwgc2NoZW1hIGRlZmluZXMgdGhlCisJCSAgICBjb250ZW50IG1vZGVsIChhbHNvIGNhbGxlZCBhIDxlbT5ncmFtbWFyPC9lbT4gb3IgPGVtPnZvY2FidWxhcnk8L2VtPikgdGhhdCBpdHMgaW5zdGFuY2UgZG9jdW1lbnRzCisJCSAgICB3aWxsIHJlcHJlc2VudC4KKyAgICAgICAgPC9wPgorICAgICAgICA8cD4KKyAgICAgICAgICAgIFRoZXJlIGFyZSBhIG51bWJlciBvZiBwb3B1bGFyIHRlY2hub2xvZ2llcyBhdmFpbGFibGUgZm9yIGNyZWF0aW5nIGFuIFhNTCBzY2hlbWEuIFNvbWUgb2YgdGhlIG1vc3QKKyAgICAgICAgICAgIHBvcHVsYXIgaW5jbHVkZToKKyAgICAgICAgICAgIDx1bD4KKyAgICAgICAgICAgICAgICA8bGk+PHN0cm9uZz5Eb2N1bWVudCBUeXBlIERlZmluaXRpb24gKERURCk8L3N0cm9uZz4gLSBYTUwncyBidWlsdC1pbiBzY2hlbWEgbGFuZ3VhZ2UuPC9saT4KKyAgICAgICAgICAgICAgICA8bGk+PHN0cm9uZz48YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9YTUwvU2NoZW1hIj5XM0MgWE1MIFNjaGVtYSAoV1hTKTwvYT48L3N0cm9uZz4gLSBhbiBvYmplY3Qtb3JpZW50ZWQgWE1MIHNjaGVtYQorICAgICAgICAgICAgICAgICAgICBsYW5ndWFnZS4gV1hTIGFsc28gcHJvdmlkZXMgYSB0eXBlIHN5c3RlbSBmb3IgY29uc3RyYWluaW5nIHRoZSBjaGFyYWN0ZXIgZGF0YSBvZiBhbiBYTUwgZG9jdW1lbnQuCisgICAgICAgICAgICAgICAgICAgIFdYUyBpcyBtYWludGFpbmVkIGJ5IHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZyI+V29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSAoVzNDKTwvYT4gYW5kIGlzIGEgVzNDCisgICAgICAgICAgICAgICAgICAgIFJlY29tbWVuZGF0aW9uICh0aGF0IGlzLCBhIHJhdGlmaWVkIFczQyBzdGFuZGFyZCBzcGVjaWZpY2F0aW9uKS48L2xpPgorICAgICAgICAgICAgICAgIDxsaT48c3Ryb25nPjxhIGhyZWY9Imh0dHA6Ly93d3cucmVsYXhuZy5vcmciPlJFTEFYIE5HIChSTkcpPC9hPjwvc3Ryb25nPiAtIGEgcGF0dGVybi1iYXNlZCwKKyAgICAgICAgICAgICAgICAgICAgdXNlci1mcmllbmRseSBYTUwgc2NoZW1hIGxhbmd1YWdlLiBSTkcgc2NoZW1hcyBtYXkgYWxzbyB1c2UgdHlwZXMgdG8gY29uc3RyYWluIFhNTCBjaGFyYWN0ZXIgZGF0YS4KKyAgICAgICAgICAgICAgICAgICAgUk5HIGlzIG1haW50YWluZWQgYnkgdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cub2FzaXMtb3Blbi5vcmciPk9yZ2FuaXphdGlvbiBmb3IgdGhlIEFkdmFuY2VtZW50IG9mCisgICAgICAgICAgICAgICAgICAgIFN0cnVjdHVyZWQgSW5mb3JtYXRpb24gU3RhbmRhcmRzIChPQVNJUyk8L2E+IGFuZCBpcyBib3RoIGFuIE9BU0lTIGFuZCBhbgorICAgICAgICAgICAgICAgICAgICA8YSBocmVmPSJodHRwOi8vd3d3Lmlzby5vcmciPklTTyAoSW50ZXJuYXRpb25hbCBPcmdhbml6YXRpb24gZm9yIFN0YW5kYXJkaXphdGlvbik8L2E+IHN0YW5kYXJkLjwvbGk+CisgICAgICAgICAgICAgICAgPGxpPjxzdHJvbmc+PGEgaHJlZj0iaHR0cDovL3d3dy5zY2hlbWF0cm9uLmNvbS8iPlNjaGVtYXRyb248L2E+PC9zdHJvbmc+IC0gYSBydWxlcy1iYXNlZCBYTUwgc2NoZW1hCisgICAgICAgICAgICAgICAgbGFuZ3VhZ2UuIFdoZXJlYXMgRFRELCBXWFMsIGFuZCBSTkcgYXJlIGRlc2lnbmVkIHRvIGV4cHJlc3MgdGhlIHN0cnVjdHVyZSBvZiBhIGNvbnRlbnQgbW9kZWwsCisgICAgICAgICAgICAgICAgU2NoZW1hdHJvbiBpcyBkZXNpZ25lZCB0byBlbmZvcmNlIGluZGl2aWR1YWwgcnVsZXMgdGhhdCBhcmUgZGlmZmljdWx0IG9yIGltcG9zc2libGUgdG8gZXhwcmVzcworICAgICAgICAgICAgICAgIHdpdGggb3RoZXIgc2NoZW1hIGxhbmd1YWdlcy4gU2NoZW1hdHJvbiBpcyBpbnRlbmRlZCB0byBzdXBwbGVtZW50IGEgc2NoZW1hIHdyaXR0ZW4gaW4KKyAgICAgICAgICAgICAgICBzdHJ1Y3R1cmFsIHNjaGVtYSBsYW5ndWFnZSBzdWNoIGFzIHRoZSBhZm9yZW1lbnRpb25lZC4gU2NoZW1hdHJvbiBpcyBpbiB0aGUgcHJvY2VzcworICAgICAgICAgICAgICAgIG9mIGJlY29taW5nIGFuIElTTyBzdGFuZGFyZC48L2xpPgorICAgICAgICAgICAgPC91bD4KKyAgICAgICAgPC9wPgorICAgICAgICA8cD4KKwkJICAgIFByZXZpb3VzIHZlcnNpb25zIG9mIEpBWFAgc3VwcG9ydGVkIHZhbGlkYXRpb24gYXMgYSBmZWF0dXJlIG9mIGFuIFhNTCBwYXJzZXIsIHJlcHJlc2VudGVkIGJ5CisJCSAgICBlaXRoZXIgYSB7QGxpbmsgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyfSBvciB7QGxpbmsgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyfSBpbnN0YW5jZS4KKyAgICAgICAgPC9wPgorICAgICAgICA8cD4KKwkJICAgIFRoZSBKQVhQIHZhbGlkYXRpb24gQVBJIGRlY291cGxlcyB0aGUgdmFsaWRhdGlvbiBvZiBhbiBpbnN0YW5jZSBkb2N1bWVudCBmcm9tIHRoZSBwYXJzaW5nIG9mIGFuCisJCSAgICBYTUwgZG9jdW1lbnQuIFRoaXMgaXMgYWR2YW50YWdlb3VzIGZvciBzZXZlcmFsIHJlYXNvbnMsIHNvbWUgb2Ygd2hpY2ggYXJlOgorCQkgICAgPHVsPgorCQkgICAgICAgIDxsaT48c3Ryb25nPlN1cHBvcnQgZm9yIGFkZGl0aW9uYWwgc2NoZW1hIGxhbmd1YWdlcy48L3N0cm9uZz4gQXMgb2YgSkRLIDEuNSwgdGhlIHR3byBtb3N0CisJCSAgICAgICAgcG9wdWxhciBKQVhQIHBhcnNlciBpbXBsZW1lbnRhdGlvbnMsIENyaW1zb24gYW5kIFhlcmNlcywgb25seSBzdXBwb3J0IGEgc3Vic2V0IG9mIHRoZSBhdmFpbGFibGUKKwkJICAgICAgICBYTUwgc2NoZW1hIGxhbmd1YWdlcy4gVGhlIFZhbGlkYXRpb24gQVBJIHByb3ZpZGVzIGEgc3RhbmRhcmQgbWVjaGFuaXNtIHRocm91Z2ggd2hpY2ggYXBwbGljYXRpb25zCisJCSAgICAgICAgbWF5IHRha2Ugb2YgYWR2YW50YWdlIG9mIHNwZWNpYWxpemF0aW9uIHZhbGlkYXRpb24gbGlicmFyaWVzIHdoaWNoIHN1cHBvcnQgYWRkaXRpb25hbCBzY2hlbWEKKwkJICAgICAgICBsYW5ndWFnZXMuPC9saT4KKwkJICAgICAgICA8bGk+PHN0cm9uZz5FYXN5IHJ1bnRpbWUgY291cGxpbmcgb2YgYW4gWE1MIGluc3RhbmNlIGFuZCBzY2hlbWEuPC9zdHJvbmc+IFNwZWNpZnlpbmcgdGhlIGxvY2F0aW9uCisJCSAgICAgICAgb2YgYSBzY2hlbWEgdG8gdXNlIGZvciB2YWxpZGF0aW9uIHdpdGggSkFYUCBwYXJzZXJzIGNhbiBiZSBjb25mdXNpbmcuIFRoZSBWYWxpZGF0aW9uIEFQSSBtYWtlcyB0aGlzCisJCSAgICAgICAgcHJvY2VzcyBzaW1wbGUgKHNlZSA8YSBocmVmPSIjZXhhbXBsZS0xIj5leGFtcGxlPC9hPiBiZWxvdykuPC9saT4KKyAgICAgICAgICA8L3VsPgorCQk8L3A+CisJCTxwPgorICAgICAgICAgICAgPGEgbmFtZT0iZXhhbXBsZS0xIj48c3Ryb25nPlVzYWdlIGV4YW1wbGU8L3N0cm9uZz4uPC9hPiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgZGVtb25zdHJhdGVzIHZhbGlkYXRpbmcKKyAgICAgICAgICAgIGFuIFhNTCBkb2N1bWVudCB3aXRoIHRoZSBWYWxpZGF0aW9uIEFQSSAoZm9yIHJlYWRhYmlsaXR5LCBzb21lIGV4Y2VwdGlvbiBoYW5kbGluZyBpcyBub3Qgc2hvd24pOgorICAgICAgICAgICAgPHByZT4KKyAgICAgICAgICAgIAorICAgIC8vIHBhcnNlIGFuIFhNTCBkb2N1bWVudCBpbnRvIGEgRE9NIHRyZWUKKyAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IHBhcnNlckZhY3RvcnkgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisgICAgcGFyc2VyRmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKKyAgICBEb2N1bWVudEJ1aWxkZXIgcGFyc2VyID0gcGFyc2VyRmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKKyAgICBEb2N1bWVudCBkb2N1bWVudCA9IHBhcnNlci5wYXJzZShuZXcgRmlsZSgiaW5zdGFuY2UueG1sIikpOworCisgICAgLy8gY3JlYXRlIGEgU2NoZW1hRmFjdG9yeSBjYXBhYmxlIG9mIHVuZGVyc3RhbmRpbmcgV1hTIHNjaGVtYXMKKyAgICBTY2hlbWFGYWN0b3J5IGZhY3RvcnkgPSBTY2hlbWFGYWN0b3J5Lm5ld0luc3RhbmNlKFhNTENvbnN0YW50cy5XM0NfWE1MX1NDSEVNQV9OU19VUkkpOworCisgICAgLy8gbG9hZCBhIFdYUyBzY2hlbWEsIHJlcHJlc2VudGVkIGJ5IGEgU2NoZW1hIGluc3RhbmNlCisgICAgU291cmNlIHNjaGVtYUZpbGUgPSBuZXcgU3RyZWFtU291cmNlKG5ldyBGaWxlKCJteVNjaGVtYS54c2QiKSk7CisgICAgU2NoZW1hIHNjaGVtYSA9IGZhY3RvcnkubmV3U2NoZW1hKHNjaGVtYUZpbGUpOworCisgICAgLy8gY3JlYXRlIGEgVmFsaWRhdG9yIGluc3RhbmNlLCB3aGljaCBjYW4gYmUgdXNlZCB0byB2YWxpZGF0ZSBhbiBpbnN0YW5jZSBkb2N1bWVudAorICAgIFZhbGlkYXRvciB2YWxpZGF0b3IgPSBzY2hlbWEubmV3VmFsaWRhdG9yKCk7CisKKyAgICAvLyB2YWxpZGF0ZSB0aGUgRE9NIHRyZWUKKyAgICB0cnkgeworICAgICAgICB2YWxpZGF0b3IudmFsaWRhdGUobmV3IERPTVNvdXJjZShkb2N1bWVudCkpOworICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIGluc3RhbmNlIGRvY3VtZW50IGlzIGludmFsaWQhCisgICAgfQorPC9wcmU+CisJCTwvcD4KKwkJPHA+CisJCSAgICBUaGUgSkFYUCBwYXJzaW5nIEFQSSBoYXMgYmVlbiBpbnRlZ3JhdGVkIHdpdGggdGhlIFZhbGlkYXRpb24gQVBJLiBBcHBsaWNhdGlvbnMgbWF5IGNyZWF0ZSBhIHtAbGluayBqYXZheC54bWwudmFsaWRhdGlvbi5TY2hlbWF9IHdpdGggdGhlIHZhbGlkYXRpb24gQVBJCisJCSAgICBhbmQgYXNzb2NpYXRlIGl0IHdpdGggYSB7QGxpbmsgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeX0gb3IgYSB7QGxpbmsgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeX0gaW5zdGFuY2UKKwkJICAgIGJ5IHVzaW5nIHRoZSB7QGxpbmsgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSNzZXRTY2hlbWEoU2NoZW1hKX0gYW5kIHtAbGluayBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5I3NldFNjaGVtYShTY2hlbWEpfQorCQkgICAgbWV0aG9kcy4gPHN0cm9uZz5Zb3Ugc2hvdWxkIG5vdDwvc3Ryb25nPiBib3RoIHNldCBhIHNjaGVtYSBhbmQgY2FsbCA8Y29kZT5zZXRWYWxpZGF0aW5nKHRydWUpPC9jb2RlPiBvbiBhIHBhcnNlciBmYWN0b3J5LiBUaGUgZm9ybWVyIHRlY2huaXF1ZQorCQkgICAgd2lsbCBjYXVzZSBwYXJzZXJzIHRvIHVzZSB0aGUgbmV3IHZhbGlkYXRpb24gQVBJOyB0aGUgbGF0dGVyIHdpbGwgY2F1c2UgcGFyc2VycyB0byB1c2UgdGhlaXIgb3duIGludGVybmFsIHZhbGlkYXRpb24KKwkJICAgIGZhY2lsaXRpZXMuIDxzdHJvbmc+VHVybmluZyBvbiBib3RoIG9mIHRoZXNlIG9wdGlvbnMgc2ltdWx0YW5lb3VzbHkgd2lsbCBjYXVzZSBlaXRoZXIgcmVkdW5kYW50IGJlaGF2aW9yIG9yIGVycm9yIGNvbmRpdGlvbnMuPC9zdHJvbmc+CisgICAgICAgIDwvcD4KKyAgICAgICAgPHA+CisKKwk8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3hwYXRoL1hQYXRoLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3hwYXRoL1hQYXRoLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzAyN2I1OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGguamF2YQpAQCAtMCwwICsxLDI5OSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvLyAkSWQ6IFhQYXRoLmphdmEgNTY5OTk4IDIwMDctMDgtMjcgMDQ6NDA6MDJaIG1yZ2xhdmFzICQKKworcGFja2FnZSBqYXZheC54bWwueHBhdGg7CisKK2ltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLk5hbWVzcGFjZUNvbnRleHQ7CitpbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKKworLyoqCisgKiA8cD48Y29kZT5YUGF0aDwvY29kZT4gcHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBYUGF0aCBldmFsdWF0aW9uIGVudmlyb25tZW50IGFuZCBleHByZXNzaW9ucy48L3A+CisgKgorICogPHRhYmxlIGlkPSJYUGF0aC1ldmFsdWF0aW9uIiBib3JkZXI9IjEiIGNlbGxwYWRkaW5nPSIyIj4KKyAqICAgPHRoZWFkPgorICogICAgIDx0cj4KKyAqICAgICAgIDx0aCBjb2xzcGFuPSIyIj5FdmFsdWF0aW9uIG9mIFhQYXRoIEV4cHJlc3Npb25zLjwvdGg+CisgKiAgICAgPC90cj4KKyAqICAgPC90aGVhZD4KKyAqICAgPHRib2R5PgorICogICAgIDx0cj4KKyAqICAgICAgIDx0ZD5jb250ZXh0PC90ZD4KKyAqICAgICAgIDx0ZD4KKyAqICAgICAgICAgSWYgYSByZXF1ZXN0IGlzIG1hZGUgdG8gZXZhbHVhdGUgdGhlIGV4cHJlc3Npb24gaW4gdGhlIGFic2VuY2UKKyAqIG9mIGEgY29udGV4dCBpdGVtLCBhbiBlbXB0eSBkb2N1bWVudCBub2RlIHdpbGwgYmUgdXNlZCBmb3IgdGhlIGNvbnRleHQuCisgKiBGb3IgdGhlIHB1cnBvc2VzIG9mIGV2YWx1YXRpbmcgWFBhdGggZXhwcmVzc2lvbnMsIGEgRG9jdW1lbnRGcmFnbWVudAorICogaXMgdHJlYXRlZCBsaWtlIGEgRG9jdW1lbnQgbm9kZS4KKyAqICAgICAgPC90ZD4KKyAqICAgIDwvdHI+CisgKiAgICA8dHI+CisgKiAgICAgIDx0ZD52YXJpYWJsZXM8L3RkPgorICogICAgICA8dGQ+CisgKiAgICAgICAgSWYgdGhlIGV4cHJlc3Npb24gY29udGFpbnMgYSB2YXJpYWJsZSByZWZlcmVuY2UsIGl0cyB2YWx1ZSB3aWxsIGJlIGZvdW5kIHRocm91Z2ggdGhlIHtAbGluayBYUGF0aFZhcmlhYmxlUmVzb2x2ZXJ9CisgKiAgICAgICAgc2V0IHdpdGgge0BsaW5rICNzZXRYUGF0aFZhcmlhYmxlUmVzb2x2ZXIoWFBhdGhWYXJpYWJsZVJlc29sdmVyIHJlc29sdmVyKX0uCisgKiAgICAgICAgQW4ge0BsaW5rIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbn0gaXMgcmFpc2VkIGlmIHRoZSB2YXJpYWJsZSByZXNvbHZlciBpcyB1bmRlZmluZWQgb3IKKyAqICAgICAgICB0aGUgcmVzb2x2ZXIgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPiBmb3IgdGhlIHZhcmlhYmxlLgorICogICAgICAgIFRoZSB2YWx1ZSBvZiBhIHZhcmlhYmxlIG11c3QgYmUgaW1tdXRhYmxlIHRocm91Z2ggdGhlIGNvdXJzZSBvZiBhbnkgc2luZ2xlIGV2YWx1YXRpb24uPC9wPgorICogICAgICA8L3RkPgorICogICAgPC90cj4KKyAqICAgIDx0cj4KKyAqICAgICAgPHRkPmZ1bmN0aW9uczwvdGQ+CisgKiAgICAgIDx0ZD4KKyAqICAgICAgICBJZiB0aGUgZXhwcmVzc2lvbiBjb250YWlucyBhIGZ1bmN0aW9uIHJlZmVyZW5jZSwgdGhlIGZ1bmN0aW9uIHdpbGwgYmUgZm91bmQgdGhyb3VnaCB0aGUge0BsaW5rIFhQYXRoRnVuY3Rpb25SZXNvbHZlcn0KKyAqICAgICAgICBzZXQgd2l0aCB7QGxpbmsgI3NldFhQYXRoRnVuY3Rpb25SZXNvbHZlcihYUGF0aEZ1bmN0aW9uUmVzb2x2ZXIgcmVzb2x2ZXIpfS4KKyAqICAgICAgICBBbiB7QGxpbmsgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9ufSBpcyByYWlzZWQgaWYgdGhlIGZ1bmN0aW9uIHJlc29sdmVyIGlzIHVuZGVmaW5lZCBvcgorICogICAgICAgIHRoZSBmdW5jdGlvbiByZXNvbHZlciByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+IGZvciB0aGUgZnVuY3Rpb24uPC9wPgorICogICAgICA8L3RkPgorICogICAgPC90cj4KKyAqICAgIDx0cj4KKyAqICAgICAgPHRkPlFOYW1lczwvdGQ+CisgKiAgICAgIDx0ZD4KKyAqICAgICAgICBRTmFtZXMgaW4gdGhlIGV4cHJlc3Npb24gYXJlIHJlc29sdmVkIGFnYWluc3QgdGhlIFhQYXRoIG5hbWVzcGFjZSBjb250ZXh0CisgKiAgICAgICAgc2V0IHdpdGgge0BsaW5rICNzZXROYW1lc3BhY2VDb250ZXh0KE5hbWVzcGFjZUNvbnRleHQgbnNDb250ZXh0KX0uCisgKiAgICAgIDwvdGQ+CisgKiAgICA8L3RyPgorICogICAgPHRyPgorICogICAgICA8dGQ+cmVzdWx0PC90ZD4KKyAqICAgICAgPHRkPgorICogICAgICAgIFRoaXMgcmVzdWx0IG9mIGV2YWx1YXRpbmcgYW4gZXhwcmVzc2lvbiBpcyBjb252ZXJ0ZWQgdG8gYW4gaW5zdGFuY2Ugb2YgdGhlIGRlc2lyZWQgcmV0dXJuIHR5cGUuCisgKiAgICAgICAgVmFsaWQgcmV0dXJuIHR5cGVzIGFyZSBkZWZpbmVkIGluIHtAbGluayBYUGF0aENvbnN0YW50c30uCisgKiAgICAgICAgQ29udmVyc2lvbiB0byB0aGUgcmV0dXJuIHR5cGUgZm9sbG93cyBYUGF0aCBjb252ZXJzaW9uIHJ1bGVzLjwvcD4KKyAqICAgICAgPC90ZD4KKyAqICAgIDwvdHI+CisgKiA8L3RhYmxlPgorICoKKyAqIEBhdXRob3IgIDxhIGhyZWY9Ik5vcm1hbi5XYWxzaEBTdW4uY29tIj5Ob3JtYW4gV2Fsc2g8L2E+CisgKiBAYXV0aG9yICA8YSBocmVmPSJKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogNTY5OTk4ICQsICREYXRlOiAyMDA3LTA4LTI2IDIxOjQwOjAyIC0wNzAwIChTdW4sIDI2IEF1ZyAyMDA3KSAkCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoIj5YTUwgUGF0aCBMYW5ndWFnZSAoWFBhdGgpIFZlcnNpb24gMS4wPC9hPgorICogQHNpbmNlIDEuNQorICovCitwdWJsaWMgaW50ZXJmYWNlIFhQYXRoIHsKKworICAgIC8qKgorICAgICAqIDxwPlJlc2V0IHRoaXMgPGNvZGU+WFBhdGg8L2NvZGU+IHRvIGl0cyBvcmlnaW5hbCBjb25maWd1cmF0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIDxwPjxjb2RlPlhQYXRoPC9jb2RlPiBpcyByZXNldCB0byB0aGUgc2FtZSBzdGF0ZSBhcyB3aGVuIGl0IHdhcyBjcmVhdGVkIHdpdGgKKyAgICAgKiB7QGxpbmsgWFBhdGhGYWN0b3J5I25ld1hQYXRoKCl9LgorICAgICAqIDxjb2RlPnJlc2V0KCk8L2NvZGU+IGlzIGRlc2lnbmVkIHRvIGFsbG93IHRoZSByZXVzZSBvZiBleGlzdGluZyA8Y29kZT5YUGF0aDwvY29kZT5zCisgICAgICogdGh1cyBzYXZpbmcgcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGUgY3JlYXRpb24gb2YgbmV3IDxjb2RlPlhQYXRoPC9jb2RlPnMuPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIHJlc2V0IDxjb2RlPlhQYXRoPC9jb2RlPiBpcyBub3QgZ3VhcmFudGVlZCB0byBoYXZlIHRoZSBzYW1lIHtAbGluayBYUGF0aEZ1bmN0aW9uUmVzb2x2ZXJ9LCB7QGxpbmsgWFBhdGhWYXJpYWJsZVJlc29sdmVyfQorICAgICAqIG9yIHtAbGluayBOYW1lc3BhY2VDb250ZXh0fSA8Y29kZT5PYmplY3Q8L2NvZGU+cywgZS5nLiB7QGxpbmsgT2JqZWN0I2VxdWFscyhPYmplY3Qgb2JqKX0uCisgICAgICogSXQgaXMgZ3VhcmFudGVlZCB0byBoYXZlIGEgZnVuY3Rpb25hbGx5IGVxdWFsIDxjb2RlPlhQYXRoRnVuY3Rpb25SZXNvbHZlcjwvY29kZT4sIDxjb2RlPlhQYXRoVmFyaWFibGVSZXNvbHZlcjwvY29kZT4KKyAgICAgKiBhbmQgPGNvZGU+TmFtZXNwYWNlQ29udGV4dDwvY29kZT4uPC9wPgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlc2V0KCk7CisKKyAgICAvKioKKyAgICAgKiA8cD5Fc3RhYmxpc2ggYSB2YXJpYWJsZSByZXNvbHZlci48L3A+CisgICAgICoKKyAgICAgKiA8cD5BIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYgPGNvZGU+cmVzb2x2ZXI8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZXNvbHZlciBWYXJpYWJsZSByZXNvbHZlci4KKyAgICAgKgorICAgICAqICBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPnJlc29sdmVyPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRYUGF0aFZhcmlhYmxlUmVzb2x2ZXIoWFBhdGhWYXJpYWJsZVJlc29sdmVyIHJlc29sdmVyKTsKKworICAgIC8qKgorICAgICAgICogPHA+UmV0dXJuIHRoZSBjdXJyZW50IHZhcmlhYmxlIHJlc29sdmVyLjwvcD4KKyAgICAgICAqCisgICAgICAgKiA8cD48Y29kZT5udWxsPC9jb2RlPiBpcyByZXR1cm5lZCBpbiBubyB2YXJpYWJsZSByZXNvbHZlciBpcyBpbiBlZmZlY3QuPC9wPgorICAgICAgICoKKyAgICAgICAqIEByZXR1cm4gQ3VycmVudCB2YXJpYWJsZSByZXNvbHZlci4KKyAgICAgICAqLworICAgIHB1YmxpYyBYUGF0aFZhcmlhYmxlUmVzb2x2ZXIgZ2V0WFBhdGhWYXJpYWJsZVJlc29sdmVyKCk7CisKKyAgICAvKioKKyAgICAgICAqIDxwPkVzdGFibGlzaCBhIGZ1bmN0aW9uIHJlc29sdmVyLjwvcD4KKyAgICAgICAqCisgICAgICAgKiA8cD5BIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYgPGNvZGU+cmVzb2x2ZXI8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LjwvcD4KKyAgICAgICAqCisgICAgICAgKiBAcGFyYW0gcmVzb2x2ZXIgWFBhdGggZnVuY3Rpb24gcmVzb2x2ZXIuCisgICAgICAgKgorICAgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5yZXNvbHZlcjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRYUGF0aEZ1bmN0aW9uUmVzb2x2ZXIoWFBhdGhGdW5jdGlvblJlc29sdmVyIHJlc29sdmVyKTsKKworICAgIC8qKgorICAgICAgICogPHA+UmV0dXJuIHRoZSBjdXJyZW50IGZ1bmN0aW9uIHJlc29sdmVyLjwvcD4KKyAgICAgICAqCisgICAgICAgKiA8cD48Y29kZT5udWxsPC9jb2RlPiBpcyByZXR1cm5lZCBpbiBubyBmdW5jdGlvbiByZXNvbHZlciBpcyBpbiBlZmZlY3QuPC9wPgorICAgICAgICoKKyAgICAgICAqIEByZXR1cm4gQ3VycmVudCBmdW5jdGlvbiByZXNvbHZlci4KKyAgICAgICAqLworICAgIHB1YmxpYyBYUGF0aEZ1bmN0aW9uUmVzb2x2ZXIgZ2V0WFBhdGhGdW5jdGlvblJlc29sdmVyKCk7CisKKyAgICAvKioKKyAgICAgICAqIDxwPkVzdGFibGlzaCBhIG5hbWVzcGFjZSBjb250ZXh0LjwvcD4KKyAgICAgICAqCisgICAgICAgKiA8cD5BIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYgPGNvZGU+bnNDb250ZXh0PC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi48L3A+CisgICAgICAgKgorICAgICAgICogQHBhcmFtIG5zQ29udGV4dCBOYW1lc3BhY2UgY29udGV4dCB0byB1c2UuCisgICAgICAgKgorICAgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5uc0NvbnRleHQ8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TmFtZXNwYWNlQ29udGV4dChOYW1lc3BhY2VDb250ZXh0IG5zQ29udGV4dCk7CisKKyAgICAvKioKKyAgICAgICAqIDxwPlJldHVybiB0aGUgY3VycmVudCBuYW1lc3BhY2UgY29udGV4dC48L3A+CisgICAgICAgKgorICAgICAgICogPHA+PGNvZGU+bnVsbDwvY29kZT4gaXMgcmV0dXJuZWQgaW4gbm8gbmFtZXNwYWNlIGNvbnRleHQgaXMgaW4gZWZmZWN0LjwvcD4KKyAgICAgICAqCisgICAgICAgKiBAcmV0dXJuIEN1cnJlbnQgTmFtZXNwYWNlIGNvbnRleHQuCisgICAgICAgKi8KKyAgICBwdWJsaWMgTmFtZXNwYWNlQ29udGV4dCBnZXROYW1lc3BhY2VDb250ZXh0KCk7CisKKyAgICAvKioKKyAgICAgICAqIDxwPkNvbXBpbGUgYW4gWFBhdGggZXhwcmVzc2lvbiBmb3IgbGF0ZXIgZXZhbHVhdGlvbi48L3A+CisgICAgICAgKgorICAgICAgICogPHA+SWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4gY29udGFpbnMgYW55IHtAbGluayBYUGF0aEZ1bmN0aW9ufXMsCisgICAgICAgKiB0aGV5IG11c3QgYmUgYXZhaWxhYmxlIHZpYSB0aGUge0BsaW5rIFhQYXRoRnVuY3Rpb25SZXNvbHZlcn0uCisgICAgICAgKiBBbiB7QGxpbmsgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9ufSB3aWxsIGJlIHRocm93biBpZiB0aGUgPGNvZGU+WFBhdGhGdW5jdGlvbjwvY29kZT4KKyAgICAgICAqIGNhbm5vdCBiZSByZXNvbHZlZCB3aXRoIHRoZSA8Y29kZT5YUGF0aEZ1bmN0aW9uUmVzb2x2ZXI8L2NvZGU+LjwvcD4KKyAgICAgICAqCisgICAgICAgKiA8cD5JZiA8Y29kZT5leHByZXNzaW9uPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwgYSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KKyAgICAgICAqCisgICAgICAgKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgWFBhdGggZXhwcmVzc2lvbi4KKyAgICAgICAqCisgICAgICAgKiBAcmV0dXJuIENvbXBpbGVkIFhQYXRoIGV4cHJlc3Npb24uCisKKyAgICAgICAqIEB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIElmIDxjb2RlPmV4cHJlc3Npb248L2NvZGU+IGNhbm5vdCBiZSBjb21waWxlZC4KKyAgICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICAgKi8KKyAgICBwdWJsaWMgWFBhdGhFeHByZXNzaW9uIGNvbXBpbGUoU3RyaW5nIGV4cHJlc3Npb24pCisgICAgICAgIHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiA8cD5FdmFsdWF0ZSBhbiA8Y29kZT5YUGF0aDwvY29kZT4gZXhwcmVzc2lvbiBpbiB0aGUgc3BlY2lmaWVkIGNvbnRleHQgYW5kIHJldHVybiB0aGUgcmVzdWx0IGFzIHRoZSBzcGVjaWZpZWQgdHlwZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5TZWUgPGEgaHJlZj0iI1hQYXRoLWV2YWx1YXRpb24iPkV2YWx1YXRpb24gb2YgWFBhdGggRXhwcmVzc2lvbnM8L2E+IGZvciBjb250ZXh0IGl0ZW0gZXZhbHVhdGlvbiwKKyAgICAgKiB2YXJpYWJsZSwgZnVuY3Rpb24gYW5kIDxjb2RlPlFOYW1lPC9jb2RlPiByZXNvbHV0aW9uIGFuZCByZXR1cm4gdHlwZSBjb252ZXJzaW9uLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IGlzIG5vdCBvbmUgb2YgdGhlIHR5cGVzIGRlZmluZWQgaW4ge0BsaW5rIFhQYXRoQ29uc3RhbnRzfSAoCisgICAgICoge0BsaW5rIFhQYXRoQ29uc3RhbnRzI05VTUJFUiBOVU1CRVJ9LAorICAgICAqIHtAbGluayBYUGF0aENvbnN0YW50cyNTVFJJTkcgU1RSSU5HfSwKKyAgICAgKiB7QGxpbmsgWFBhdGhDb25zdGFudHMjQk9PTEVBTiBCT09MRUFOfSwKKyAgICAgKiB7QGxpbmsgWFBhdGhDb25zdGFudHMjTk9ERSBOT0RFfSBvcgorICAgICAqIHtAbGluayBYUGF0aENvbnN0YW50cyNOT0RFU0VUIE5PREVTRVR9KQorICAgICAqIHRoZW4gYW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgorICAgICAqCisgICAgICogPHA+SWYgYSA8Y29kZT5udWxsPC9jb2RlPiB2YWx1ZSBpcyBwcm92aWRlZCBmb3IKKyAgICAgKiA8Y29kZT5pdGVtPC9jb2RlPiwgYW4gZW1wdHkgZG9jdW1lbnQgd2lsbCBiZSB1c2VkIGZvciB0aGUKKyAgICAgKiBjb250ZXh0LgorICAgICAqIElmIDxjb2RlPmV4cHJlc3Npb248L2NvZGU+IG9yIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LCB0aGVuIGEKKyAgICAgKiA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBYUGF0aCBleHByZXNzaW9uLgorICAgICAqIEBwYXJhbSBpdGVtIFRoZSBzdGFydGluZyBjb250ZXh0IChub2RlIG9yIG5vZGUgbGlzdCwgZm9yIGV4YW1wbGUpLgorICAgICAqIEBwYXJhbSByZXR1cm5UeXBlIFRoZSBkZXNpcmVkIHJldHVybiB0eXBlLgorICAgICAqCisgICAgICogQHJldHVybiBSZXN1bHQgb2YgZXZhbHVhdGluZyBhbiBYUGF0aCBleHByZXNzaW9uIGFzIGFuIDxjb2RlPk9iamVjdDwvY29kZT4gb2YgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiBJZiA8Y29kZT5leHByZXNzaW9uPC9jb2RlPiBjYW5ub3QgYmUgZXZhbHVhdGVkLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IGlzIG5vdCBvbmUgb2YgdGhlIHR5cGVzIGRlZmluZWQgaW4ge0BsaW5rIFhQYXRoQ29uc3RhbnRzfS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPmV4cHJlc3Npb248L2NvZGU+IG9yIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZXZhbHVhdGUoU3RyaW5nIGV4cHJlc3Npb24sIE9iamVjdCBpdGVtLCBRTmFtZSByZXR1cm5UeXBlKQorICAgICAgICB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogPHA+RXZhbHVhdGUgYW4gWFBhdGggZXhwcmVzc2lvbiBpbiB0aGUgc3BlY2lmaWVkIGNvbnRleHQgYW5kIHJldHVybiB0aGUgcmVzdWx0IGFzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBjYWxscyB7QGxpbmsgI2V2YWx1YXRlKFN0cmluZyBleHByZXNzaW9uLCBPYmplY3QgaXRlbSwgUU5hbWUgcmV0dXJuVHlwZSl9IHdpdGggYSA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBvZgorICAgICAqIHtAbGluayBYUGF0aENvbnN0YW50cyNTVFJJTkd9LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlNlZSA8YSBocmVmPSIjWFBhdGgtZXZhbHVhdGlvbiI+RXZhbHVhdGlvbiBvZiBYUGF0aCBFeHByZXNzaW9uczwvYT4gZm9yIGNvbnRleHQgaXRlbSBldmFsdWF0aW9uLAorICAgICAqIHZhcmlhYmxlLCBmdW5jdGlvbiBhbmQgUU5hbWUgcmVzb2x1dGlvbiBhbmQgcmV0dXJuIHR5cGUgY29udmVyc2lvbi48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiBhIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIGlzIHByb3ZpZGVkIGZvcgorICAgICAqIDxjb2RlPml0ZW08L2NvZGU+LCBhbiBlbXB0eSBkb2N1bWVudCB3aWxsIGJlIHVzZWQgZm9yIHRoZQorICAgICAqIGNvbnRleHQuCisgICAgICogSWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIHRoZW4gYSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBYUGF0aCBleHByZXNzaW9uLgorICAgICAqIEBwYXJhbSBpdGVtIFRoZSBzdGFydGluZyBjb250ZXh0IChub2RlIG9yIG5vZGUgbGlzdCwgZm9yIGV4YW1wbGUpLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgPGNvZGU+U3RyaW5nPC9jb2RlPiB0aGF0IGlzIHRoZSByZXN1bHQgb2YgZXZhbHVhdGluZyB0aGUgZXhwcmVzc2lvbiBhbmQKKyAgICAgKiAgIGNvbnZlcnRpbmcgdGhlIHJlc3VsdCB0byBhIDxjb2RlPlN0cmluZzwvY29kZT4uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiBJZiA8Y29kZT5leHByZXNzaW9uPC9jb2RlPiBjYW5ub3QgYmUgZXZhbHVhdGVkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBldmFsdWF0ZShTdHJpbmcgZXhwcmVzc2lvbiwgT2JqZWN0IGl0ZW0pCisgICAgICAgIHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiA8cD5FdmFsdWF0ZSBhbiBYUGF0aCBleHByZXNzaW9uIGluIHRoZSBjb250ZXh0IG9mIHRoZSBzcGVjaWZpZWQgPGNvZGU+SW5wdXRTb3VyY2U8L2NvZGU+CisgICAgICogYW5kIHJldHVybiB0aGUgcmVzdWx0IGFzIHRoZSBzcGVjaWZpZWQgdHlwZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBidWlsZHMgYSBkYXRhIG1vZGVsIGZvciB0aGUge0BsaW5rIElucHV0U291cmNlfSBhbmQgY2FsbHMKKyAgICAgKiB7QGxpbmsgI2V2YWx1YXRlKFN0cmluZyBleHByZXNzaW9uLCBPYmplY3QgaXRlbSwgUU5hbWUgcmV0dXJuVHlwZSl9IG9uIHRoZSByZXN1bHRpbmcgZG9jdW1lbnQgb2JqZWN0LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlNlZSA8YSBocmVmPSIjWFBhdGgtZXZhbHVhdGlvbiI+RXZhbHVhdGlvbiBvZiBYUGF0aCBFeHByZXNzaW9uczwvYT4gZm9yIGNvbnRleHQgaXRlbSBldmFsdWF0aW9uLAorICAgICAqIHZhcmlhYmxlLCBmdW5jdGlvbiBhbmQgUU5hbWUgcmVzb2x1dGlvbiBhbmQgcmV0dXJuIHR5cGUgY29udmVyc2lvbi48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBpcyBub3Qgb25lIG9mIHRoZSB0eXBlcyBkZWZpbmVkIGluIHtAbGluayBYUGF0aENvbnN0YW50c30sCisgICAgICogdGhlbiBhbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiA8Y29kZT5leHByZXNzaW9uPC9jb2RlPiwgPGNvZGU+c291cmNlPC9jb2RlPiBvciA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwKKyAgICAgKiB0aGVuIGEgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgWFBhdGggZXhwcmVzc2lvbi4KKyAgICAgKiBAcGFyYW0gc291cmNlIFRoZSBpbnB1dCBzb3VyY2Ugb2YgdGhlIGRvY3VtZW50IHRvIGV2YWx1YXRlIG92ZXIuCisgICAgICogQHBhcmFtIHJldHVyblR5cGUgVGhlIGRlc2lyZWQgcmV0dXJuIHR5cGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSA8Y29kZT5PYmplY3Q8L2NvZGU+IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSByZXN1bHQgb2YgZXZhbHVhdGluZyB0aGUgZXhwcmVzc2lvbi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIElmIGV4cHJlc3Npb24gY2Fubm90IGJlIGV2YWx1YXRlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBpcyBub3Qgb25lIG9mIHRoZSB0eXBlcyBkZWZpbmVkIGluIHtAbGluayBYUGF0aENvbnN0YW50c30uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5leHByZXNzaW9uPC9jb2RlPiwgPGNvZGU+c291cmNlPC9jb2RlPiBvciA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPgorICAgICAqICAgaXMgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBldmFsdWF0ZSgKKyAgICAgICAgU3RyaW5nIGV4cHJlc3Npb24sCisgICAgICAgIElucHV0U291cmNlIHNvdXJjZSwKKyAgICAgICAgUU5hbWUgcmV0dXJuVHlwZSkKKyAgICAgICAgdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIDxwPkV2YWx1YXRlIGFuIFhQYXRoIGV4cHJlc3Npb24gaW4gdGhlIGNvbnRleHQgb2YgdGhlIHNwZWNpZmllZCA8Y29kZT5JbnB1dFNvdXJjZTwvY29kZT4KKyAgICAgKiBhbmQgcmV0dXJuIHRoZSByZXN1bHQgYXMgYSA8Y29kZT5TdHJpbmc8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGNhbGxzIHtAbGluayAjZXZhbHVhdGUoU3RyaW5nIGV4cHJlc3Npb24sIElucHV0U291cmNlIHNvdXJjZSwgUU5hbWUgcmV0dXJuVHlwZSl9IHdpdGggYQorICAgICAqIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IG9mIHtAbGluayBYUGF0aENvbnN0YW50cyNTVFJJTkd9LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlNlZSA8YSBocmVmPSIjWFBhdGgtZXZhbHVhdGlvbiI+RXZhbHVhdGlvbiBvZiBYUGF0aCBFeHByZXNzaW9uczwvYT4gZm9yIGNvbnRleHQgaXRlbSBldmFsdWF0aW9uLAorICAgICAqIHZhcmlhYmxlLCBmdW5jdGlvbiBhbmQgUU5hbWUgcmVzb2x1dGlvbiBhbmQgcmV0dXJuIHR5cGUgY29udmVyc2lvbi48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiA8Y29kZT5leHByZXNzaW9uPC9jb2RlPiBvciA8Y29kZT5zb3VyY2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LAorICAgICAqIHRoZW4gYSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBYUGF0aCBleHByZXNzaW9uLgorICAgICAqIEBwYXJhbSBzb3VyY2UgVGhlIDxjb2RlPklucHV0U291cmNlPC9jb2RlPiBvZiB0aGUgZG9jdW1lbnQgdG8gZXZhbHVhdGUgb3Zlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgdGhlIGV4cHJlc3Npb24gYW5kCisgICAgICogICBjb252ZXJ0aW5nIHRoZSByZXN1bHQgdG8gYSA8Y29kZT5TdHJpbmc8L2NvZGU+LgorICAgICAqCisgICAgICogQHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gSWYgZXhwcmVzc2lvbiBjYW5ub3QgYmUgZXZhbHVhdGVkLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4gb3IgPGNvZGU+c291cmNlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGV2YWx1YXRlKFN0cmluZyBleHByZXNzaW9uLCBJbnB1dFNvdXJjZSBzb3VyY2UpCisgICAgICAgIHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3hwYXRoL1hQYXRoQ29uc3RhbnRzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3hwYXRoL1hQYXRoQ29uc3RhbnRzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmZmMzYyMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhDb25zdGFudHMuamF2YQpAQCAtMCwwICsxLDc4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8vICRJZDogWFBhdGhDb25zdGFudHMuamF2YSA0NDY1OTggMjAwNi0wOS0xNSAxMjo1NTo0MFogamVyZW1pYXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC54cGF0aDsKKworaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWU7CisKKy8qKgorICogPHA+WFBhdGggY29uc3RhbnRzLjwvcD4KKyAqCisgKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLkNPTSI+Tm9ybWFuIFdhbHNoPC9hPgorICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86SmVmZi5TdXR0b3JAU3VuLkNPTSI+SmVmZiBTdXR0b3I8L2E+CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDQ0NjU5OCAkLCAkRGF0ZTogMjAwNi0wOS0xNSAwNTo1NTo0MCAtMDcwMCAoRnJpLCAxNSBTZXAgMjAwNikgJAorICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCI+WE1MIFBhdGggTGFuZ3VhZ2UgKFhQYXRoKSBWZXJzaW9uIDEuMDwvYT4KKyAqIEBzaW5jZSAxLjUKKyAqLworcHVibGljIGNsYXNzIFhQYXRoQ29uc3RhbnRzIHsKKworICAgIC8qKgorICAgICAqIDxwPlByaXZhdGUgY29uc3RydWN0b3IgdG8gcHJldmVudCBpbnN0YW50aWF0aW9uLjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIFhQYXRoQ29uc3RhbnRzKCkgeyB9CisKKyAgICAvKioKKyAgICAgKiA8cD5UaGUgWFBhdGggMS4wIG51bWJlciBkYXRhIHR5cGUuPC9wPgorICAgICAqCisgICAgICogPHA+TWFwcyB0byBKYXZhIHtAbGluayBEb3VibGV9LjwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFFOYW1lIE5VTUJFUiA9IG5ldyBRTmFtZSgiaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIiwgIk5VTUJFUiIpOworCisgICAgLyoqCisgICAgICogPHA+VGhlIFhQYXRoIDEuMCBzdHJpbmcgZGF0YSB0eXBlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPk1hcHMgdG8gSmF2YSB7QGxpbmsgU3RyaW5nfS48L3A+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBRTmFtZSBTVFJJTkcgPSBuZXcgUU5hbWUoImh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIsICJTVFJJTkciKTsKKworICAgIC8qKgorICAgICAqIDxwPlRoZSBYUGF0aCAxLjAgYm9vbGVhbiBkYXRhIHR5cGUuPC9wPgorICAgICAqCisgICAgICogPHA+TWFwcyB0byBKYXZhIHtAbGluayBCb29sZWFufS48L3A+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBRTmFtZSBCT09MRUFOID0gbmV3IFFOYW1lKCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iLCAiQk9PTEVBTiIpOworCisgICAgLyoqCisgICAgICogPHA+VGhlIFhQYXRoIDEuMCBOb2RlU2V0IGRhdGEgdHlwZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5NYXBzIHRvIEphdmEge0BsaW5rIG9yZy53M2MuZG9tLk5vZGVMaXN0fS48L3A+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBRTmFtZSBOT0RFU0VUID0gbmV3IFFOYW1lKCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iLCAiTk9ERVNFVCIpOworCisgICAgLyoqCisgICAgICogPHA+VGhlIFhQYXRoIDEuMCBOb2RlU2V0IGRhdGEgdHlwZS4KKyAgICAgKgorICAgICAqIDxwPk1hcHMgdG8gSmF2YSB7QGxpbmsgb3JnLnczYy5kb20uTm9kZX0uPC9wPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUU5hbWUgTk9ERSA9IG5ldyBRTmFtZSgiaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIiwgIk5PREUiKTsKKworICAgIC8qKgorICAgICAqIDxwPlRoZSBVUkkgZm9yIHRoZSBET00gb2JqZWN0IG1vZGVsLCAiaHR0cDovL2phdmEuc3VuLmNvbS9qYXhwL3hwYXRoL2RvbSIuPC9wPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9PQkpFQ1RfTU9ERUwgPSAiaHR0cDovL2phdmEuc3VuLmNvbS9qYXhwL3hwYXRoL2RvbSI7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3hwYXRoL1hQYXRoRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3hwYXRoL1hQYXRoRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGRiMzY5YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDk5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8vICRJZDogWFBhdGhFeGNlcHRpb24uamF2YSA0NDY1OTggMjAwNi0wOS0xNSAxMjo1NTo0MFogamVyZW1pYXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC54cGF0aDsKKworaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CisKKy8qKgorICogPGNvZGU+WFBhdGhFeGNlcHRpb248L2NvZGU+IHJlcHJlc2VudHMgYSBnZW5lcmljIFhQYXRoIGV4Y2VwdGlvbi48L3A+CisgKgorICogQGF1dGhvciAgPGEgaHJlZj0iTm9ybWFuLldhbHNoQFN1bi5jb20iPk5vcm1hbiBXYWxzaDwvYT4KKyAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5DT00iPkplZmYgU3V0dG9yPC9hPgorICogQHZlcnNpb24gJFJldmlzaW9uOiA0NDY1OTggJCwgJERhdGU6IDIwMDYtMDktMTUgMDU6NTU6NDAgLTA3MDAgKEZyaSwgMTUgU2VwIDIwMDYpICQKKyAqIEBzaW5jZSAxLjUKKyAqLworcHVibGljIGNsYXNzIFhQYXRoRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgZmluYWwgVGhyb3dhYmxlIGNhdXNlOworCisgICAgLyoqCisgICAgICogPHA+U3RyZWFtIFVuaXF1ZSBJZGVudGlmaWVyLjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTgzNzA4MDI2MDM3NDk4Njk4MEw7CisKKyAgICAvKioKKyAgICAgKiA8cD5Db25zdHJ1Y3RzIGEgbmV3IDxjb2RlPlhQYXRoRXhjZXB0aW9uPC9jb2RlPiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIDxjb2RlPm1lc3NhZ2U8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90IGluaXRpYWxpemVkLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIDxjb2RlPm1lc3NhZ2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LCB0aGVuIGEgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZGV0YWlsIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIFhQYXRoRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UpOworICAgICAgICBpZiAoIG1lc3NhZ2UgPT0gbnVsbCApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAoICJtZXNzYWdlIGNhbid0IGJlIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmNhdXNlID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5Db25zdHJ1Y3RzIGEgbmV3IDxjb2RlPlhQYXRoRXhjZXB0aW9uPC9jb2RlPiB3aXRoIHRoZSBzcGVjaWZpZWQgPGNvZGU+Y2F1c2U8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwgdGhlbiBhIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlIFRoZSBjYXVzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBYUGF0aEV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UgPT0gbnVsbCA/IG51bGwgOiBjYXVzZS50b1N0cmluZygpKTsKKyAgICAgICAgdGhpcy5jYXVzZSA9IGNhdXNlOworICAgICAgICBpZiAoIGNhdXNlID09IG51bGwgKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24gKCAiY2F1c2UgY2FuJ3QgYmUgbnVsbCIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFRocm93YWJsZSBnZXRDYXVzZSgpIHsKKyAgICAgICAgcmV0dXJuIGNhdXNlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHByaW50U3RhY2tUcmFjZSggamF2YS5pby5QcmludFN0cmVhbSBzICkgeworICAgICAgICBpZiggZ2V0Q2F1c2UoKSAhPSBudWxsICkgeworICAgICAgICAgICAgZ2V0Q2F1c2UoKS5wcmludFN0YWNrVHJhY2Uocyk7CisgICAgICAgICAgcy5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0gbGlua2VkIHRvIC0tLS0tLS0tLS0tLS0tLS0tLSIpOworICAgICAgICB9CisKKyAgICAgICAgc3VwZXIucHJpbnRTdGFja1RyYWNlKHMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHByaW50U3RhY2tUcmFjZSgpIHsKKyAgICAgICAgcHJpbnRTdGFja1RyYWNlKFN5c3RlbS5lcnIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHByaW50U3RhY2tUcmFjZShQcmludFdyaXRlciBzKSB7CisgICAgICAgIGlmKCBnZXRDYXVzZSgpICE9IG51bGwgKSB7CisgICAgICAgICAgICBnZXRDYXVzZSgpLnByaW50U3RhY2tUcmFjZShzKTsKKyAgICAgICAgICBzLnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLSBsaW5rZWQgdG8gLS0tLS0tLS0tLS0tLS0tLS0tIik7CisgICAgICAgIH0KKworICAgICAgICBzdXBlci5wcmludFN0YWNrVHJhY2Uocyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC94cGF0aC9YUGF0aEV4cHJlc3Npb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhFeHByZXNzaW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDE4MmQ5MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhFeHByZXNzaW9uLmphdmEKQEAgLTAsMCArMSwxODUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLy8gJElkOiBYUGF0aEV4cHJlc3Npb24uamF2YSA0NDY1OTggMjAwNi0wOS0xNSAxMjo1NTo0MFogamVyZW1pYXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC54cGF0aDsKKworaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWU7CitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CisKKy8qKgorICogPHA+PGNvZGU+WFBhdGhFeHByZXNzaW9uPC9jb2RlPiBwcm92aWRlcyBhY2Nlc3MgdG8gY29tcGlsZWQgWFBhdGggZXhwcmVzc2lvbnMuPC9wPgorICoKKyAqIDx0YWJsZSBpZD0iWFBhdGhFeHByZXNzaW9uLWV2YWx1YXRpb24iIGJvcmRlcj0iMSIgY2VsbHBhZGRpbmc9IjIiPgorICogICA8dGhlYWQ+CisgKiAgICAgPHRyPgorICogICAgICAgPHRoIGNvbHNwYW49IjIiPkV2YWx1YXRpb24gb2YgWFBhdGggRXhwcmVzc2lvbnMuPC90aD4KKyAqICAgICA8L3RyPgorICogICA8L3RoZWFkPgorICogICA8dGJvZHk+CisgKiAgICAgPHRyPgorICogICAgICAgPHRkPmNvbnRleHQ8L3RkPgorICogICAgICAgPHRkPgorICogICAgICAgICBJZiBhIHJlcXVlc3QgaXMgbWFkZSB0byBldmFsdWF0ZSB0aGUgZXhwcmVzc2lvbiBpbiB0aGUgYWJzZW5jZQorICogb2YgYSBjb250ZXh0IGl0ZW0sIGFuIGVtcHR5IGRvY3VtZW50IG5vZGUgd2lsbCBiZSB1c2VkIGZvciB0aGUgY29udGV4dC4KKyAqIEZvciB0aGUgcHVycG9zZXMgb2YgZXZhbHVhdGluZyBYUGF0aCBleHByZXNzaW9ucywgYSBEb2N1bWVudEZyYWdtZW50CisgKiBpcyB0cmVhdGVkIGxpa2UgYSBEb2N1bWVudCBub2RlLgorICogICAgICA8L3RkPgorICogICAgPC90cj4KKyAqICAgIDx0cj4KKyAqICAgICAgPHRkPnZhcmlhYmxlczwvdGQ+CisgKiAgICAgIDx0ZD4KKyAqICAgICAgICBJZiB0aGUgZXhwcmVzc2lvbiBjb250YWlucyBhIHZhcmlhYmxlIHJlZmVyZW5jZSwgaXRzIHZhbHVlIHdpbGwgYmUgZm91bmQgdGhyb3VnaCB0aGUge0BsaW5rIFhQYXRoVmFyaWFibGVSZXNvbHZlcn0uCisgKiAgICAgICAgQW4ge0BsaW5rIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbn0gaXMgcmFpc2VkIGlmIHRoZSB2YXJpYWJsZSByZXNvbHZlciBpcyB1bmRlZmluZWQgb3IKKyAqICAgICAgICB0aGUgcmVzb2x2ZXIgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPiBmb3IgdGhlIHZhcmlhYmxlLgorICogICAgICAgIFRoZSB2YWx1ZSBvZiBhIHZhcmlhYmxlIG11c3QgYmUgaW1tdXRhYmxlIHRocm91Z2ggdGhlIGNvdXJzZSBvZiBhbnkgc2luZ2xlIGV2YWx1YXRpb24uPC9wPgorICogICAgICA8L3RkPgorICogICAgPC90cj4KKyAqICAgIDx0cj4KKyAqICAgICAgPHRkPmZ1bmN0aW9uczwvdGQ+CisgKiAgICAgIDx0ZD4KKyAqICAgICAgICBJZiB0aGUgZXhwcmVzc2lvbiBjb250YWlucyBhIGZ1bmN0aW9uIHJlZmVyZW5jZSwgdGhlIGZ1bmN0aW9uIHdpbGwgYmUgZm91bmQgdGhyb3VnaCB0aGUge0BsaW5rIFhQYXRoRnVuY3Rpb25SZXNvbHZlcn0uCisgKiAgICAgICAgQW4ge0BsaW5rIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbn0gaXMgcmFpc2VkIGlmIHRoZSBmdW5jdGlvbiByZXNvbHZlciBpcyB1bmRlZmluZWQgb3IKKyAqICAgICAgICB0aGUgZnVuY3Rpb24gcmVzb2x2ZXIgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPiBmb3IgdGhlIGZ1bmN0aW9uLjwvcD4KKyAqICAgICAgPC90ZD4KKyAqICAgIDwvdHI+CisgKiAgICA8dHI+CisgKiAgICAgIDx0ZD5RTmFtZXM8L3RkPgorICogICAgICA8dGQ+CisgKiAgICAgICAgUU5hbWVzIGluIHRoZSBleHByZXNzaW9uIGFyZSByZXNvbHZlZCBhZ2FpbnN0IHRoZSBYUGF0aCBuYW1lc3BhY2UgY29udGV4dC4KKyAqICAgICAgPC90ZD4KKyAqICAgIDwvdHI+CisgKiAgICA8dHI+CisgKiAgICAgIDx0ZD5yZXN1bHQ8L3RkPgorICogICAgICA8dGQ+CisgKiAgICAgICAgVGhpcyByZXN1bHQgb2YgZXZhbHVhdGluZyBhbiBleHByZXNzaW9uIGlzIGNvbnZlcnRlZCB0byBhbiBpbnN0YW5jZSBvZiB0aGUgZGVzaXJlZCByZXR1cm4gdHlwZS4KKyAqICAgICAgICBWYWxpZCByZXR1cm4gdHlwZXMgYXJlIGRlZmluZWQgaW4ge0BsaW5rIFhQYXRoQ29uc3RhbnRzfS4KKyAqICAgICAgICBDb252ZXJzaW9uIHRvIHRoZSByZXR1cm4gdHlwZSBmb2xsb3dzIFhQYXRoIGNvbnZlcnNpb24gcnVsZXMuPC9wPgorICogICAgICA8L3RkPgorICogICAgPC90cj4KKyAqIDwvdGFibGU+CisgKgorICogQGF1dGhvciAgPGEgaHJlZj0ibWFpbHRvOk5vcm1hbi5XYWxzaEBTdW4uY29tIj5Ob3JtYW4gV2Fsc2g8L2E+CisgKiBAYXV0aG9yICA8YSBocmVmPSJtYWlsdG86SmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDQ0NjU5OCAkLCAkRGF0ZTogMjAwNi0wOS0xNSAwNTo1NTo0MCAtMDcwMCAoRnJpLCAxNSBTZXAgMjAwNikgJAorICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNzZWN0aW9uLUV4cHJlc3Npb25zIj5YTUwgUGF0aCBMYW5ndWFnZSAoWFBhdGgpIFZlcnNpb24gMS4wLCBFeHByZXNzaW9uczwvYT4KKyAqIEBzaW5jZSAxLjUKKyAqLworcHVibGljIGludGVyZmFjZSBYUGF0aEV4cHJlc3Npb24geworCisgICAgLyoqCisgICAgICogPHA+RXZhbHVhdGUgdGhlIGNvbXBpbGVkIFhQYXRoIGV4cHJlc3Npb24gaW4gdGhlIHNwZWNpZmllZCBjb250ZXh0IGFuZCByZXR1cm4gdGhlIHJlc3VsdCBhcyB0aGUgc3BlY2lmaWVkIHR5cGUuPC9wPgorICAgICAqCisgICAgICogPHA+U2VlIDxhIGhyZWY9IiNYUGF0aEV4cHJlc3Npb24tZXZhbHVhdGlvbiI+RXZhbHVhdGlvbiBvZiBYUGF0aCBFeHByZXNzaW9uczwvYT4gZm9yIGNvbnRleHQgaXRlbSBldmFsdWF0aW9uLAorICAgICAqIHZhcmlhYmxlLCBmdW5jdGlvbiBhbmQgUU5hbWUgcmVzb2x1dGlvbiBhbmQgcmV0dXJuIHR5cGUgY29udmVyc2lvbi48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBpcyBub3Qgb25lIG9mIHRoZSB0eXBlcyBkZWZpbmVkIGluIHtAbGluayBYUGF0aENvbnN0YW50c30sCisgICAgICogdGhlbiBhbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiBhIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIGlzIHByb3ZpZGVkIGZvcgorICAgICAqIDxjb2RlPml0ZW08L2NvZGU+LCBhbiBlbXB0eSBkb2N1bWVudCB3aWxsIGJlIHVzZWQgZm9yIHRoZQorICAgICAqIGNvbnRleHQuCisgICAgICogSWYgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIHRoZW4gYSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpdGVtIFRoZSBzdGFydGluZyBjb250ZXh0IChub2RlIG9yIG5vZGUgbGlzdCwgZm9yIGV4YW1wbGUpLgorICAgICAqIEBwYXJhbSByZXR1cm5UeXBlIFRoZSBkZXNpcmVkIHJldHVybiB0eXBlLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgPGNvZGU+T2JqZWN0PC9jb2RlPiB0aGF0IGlzIHRoZSByZXN1bHQgb2YgZXZhbHVhdGluZyB0aGUgZXhwcmVzc2lvbiBhbmQgY29udmVydGluZyB0aGUgcmVzdWx0IHRvCisgICAgICogICA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIElmIHRoZSBleHByZXNzaW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgbm90IG9uZSBvZiB0aGUgdHlwZXMgZGVmaW5lZCBpbiB7QGxpbmsgWFBhdGhDb25zdGFudHN9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZXZhbHVhdGUoT2JqZWN0IGl0ZW0sIFFOYW1lIHJldHVyblR5cGUpCisgICAgICAgIHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiA8cD5FdmFsdWF0ZSB0aGUgY29tcGlsZWQgWFBhdGggZXhwcmVzc2lvbiBpbiB0aGUgc3BlY2lmaWVkIGNvbnRleHQgYW5kIHJldHVybiB0aGUgcmVzdWx0IGFzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBjYWxscyB7QGxpbmsgI2V2YWx1YXRlKE9iamVjdCBpdGVtLCBRTmFtZSByZXR1cm5UeXBlKX0gd2l0aCBhIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IG9mCisgICAgICoge0BsaW5rIFhQYXRoQ29uc3RhbnRzI1NUUklOR30uPC9wPgorICAgICAqCisgICAgICogPHA+U2VlIDxhIGhyZWY9IiNYUGF0aEV4cHJlc3Npb24tZXZhbHVhdGlvbiI+RXZhbHVhdGlvbiBvZiBYUGF0aCBFeHByZXNzaW9uczwvYT4gZm9yIGNvbnRleHQgaXRlbSBldmFsdWF0aW9uLAorICAgICAqIHZhcmlhYmxlLCBmdW5jdGlvbiBhbmQgUU5hbWUgcmVzb2x1dGlvbiBhbmQgcmV0dXJuIHR5cGUgY29udmVyc2lvbi48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiBhIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIGlzIHByb3ZpZGVkIGZvcgorICAgICAqIDxjb2RlPml0ZW08L2NvZGU+LCBhbiBlbXB0eSBkb2N1bWVudCB3aWxsIGJlIHVzZWQgZm9yIHRoZQorICAgICAqIGNvbnRleHQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXRlbSBUaGUgc3RhcnRpbmcgY29udGV4dCAobm9kZSBvciBub2RlIGxpc3QsIGZvciBleGFtcGxlKS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgdGhlIGV4cHJlc3Npb24gYW5kIGNvbnZlcnRpbmcgdGhlIHJlc3VsdCB0byBhCisgICAgICogICA8Y29kZT5TdHJpbmc8L2NvZGU+LgorICAgICAqCisgICAgICogQHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gSWYgdGhlIGV4cHJlc3Npb24gY2Fubm90IGJlIGV2YWx1YXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGV2YWx1YXRlKE9iamVjdCBpdGVtKQorICAgICAgICB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogPHA+RXZhbHVhdGUgdGhlIGNvbXBpbGVkIFhQYXRoIGV4cHJlc3Npb24gaW4gdGhlIGNvbnRleHQgb2YgdGhlIHNwZWNpZmllZCA8Y29kZT5JbnB1dFNvdXJjZTwvY29kZT4gYW5kIHJldHVybiB0aGUgcmVzdWx0IGFzIHRoZQorICAgICAqIHNwZWNpZmllZCB0eXBlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGJ1aWxkcyBhIGRhdGEgbW9kZWwgZm9yIHRoZSB7QGxpbmsgSW5wdXRTb3VyY2V9IGFuZCBjYWxscworICAgICAqIHtAbGluayAjZXZhbHVhdGUoT2JqZWN0IGl0ZW0sIFFOYW1lIHJldHVyblR5cGUpfSBvbiB0aGUgcmVzdWx0aW5nIGRvY3VtZW50IG9iamVjdC48L3A+CisgICAgICoKKyAgICAgKiA8cD5TZWUgPGEgaHJlZj0iI1hQYXRoRXhwcmVzc2lvbi1ldmFsdWF0aW9uIj5FdmFsdWF0aW9uIG9mIFhQYXRoIEV4cHJlc3Npb25zPC9hPiBmb3IgY29udGV4dCBpdGVtIGV2YWx1YXRpb24sCisgICAgICogdmFyaWFibGUsIGZ1bmN0aW9uIGFuZCBRTmFtZSByZXNvbHV0aW9uIGFuZCByZXR1cm4gdHlwZSBjb252ZXJzaW9uLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IGlzIG5vdCBvbmUgb2YgdGhlIHR5cGVzIGRlZmluZWQgaW4ge0BsaW5rIFhQYXRoQ29uc3RhbnRzfSwKKyAgICAgKiB0aGVuIGFuIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIDxjb2RlPnNvdXJjZTwvY29kZT4gb3IgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sCisgICAgICogdGhlbiBhIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZSBUaGUgPGNvZGU+SW5wdXRTb3VyY2U8L2NvZGU+IG9mIHRoZSBkb2N1bWVudCB0byBldmFsdWF0ZSBvdmVyLgorICAgICAqIEBwYXJhbSByZXR1cm5UeXBlIFRoZSBkZXNpcmVkIHJldHVybiB0eXBlLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgPGNvZGU+T2JqZWN0PC9jb2RlPiB0aGF0IGlzIHRoZSByZXN1bHQgb2YgZXZhbHVhdGluZyB0aGUgZXhwcmVzc2lvbiBhbmQgY29udmVydGluZyB0aGUgcmVzdWx0IHRvCisgICAgICogICA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIElmIHRoZSBleHByZXNzaW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgbm90IG9uZSBvZiB0aGUgdHlwZXMgZGVmaW5lZCBpbiB7QGxpbmsgWFBhdGhDb25zdGFudHN9LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgIDxjb2RlPnNvdXJjZTwvY29kZT4gb3IgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBldmFsdWF0ZShJbnB1dFNvdXJjZSBzb3VyY2UsIFFOYW1lIHJldHVyblR5cGUpCisgICAgICAgIHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiA8cD5FdmFsdWF0ZSB0aGUgY29tcGlsZWQgWFBhdGggZXhwcmVzc2lvbiBpbiB0aGUgY29udGV4dCBvZiB0aGUgc3BlY2lmaWVkIDxjb2RlPklucHV0U291cmNlPC9jb2RlPiBhbmQgcmV0dXJuIHRoZSByZXN1bHQgYXMgYQorICAgICAqIDxjb2RlPlN0cmluZzwvY29kZT4uPC9wPgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgY2FsbHMge0BsaW5rICNldmFsdWF0ZShJbnB1dFNvdXJjZSBzb3VyY2UsIFFOYW1lIHJldHVyblR5cGUpfSB3aXRoIGEgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gb2YKKyAgICAgKiB7QGxpbmsgWFBhdGhDb25zdGFudHMjU1RSSU5HfS48L3A+CisgICAgICoKKyAgICAgKiA8cD5TZWUgPGEgaHJlZj0iI1hQYXRoRXhwcmVzc2lvbi1ldmFsdWF0aW9uIj5FdmFsdWF0aW9uIG9mIFhQYXRoIEV4cHJlc3Npb25zPC9hPiBmb3IgY29udGV4dCBpdGVtIGV2YWx1YXRpb24sCisgICAgICogdmFyaWFibGUsIGZ1bmN0aW9uIGFuZCBRTmFtZSByZXNvbHV0aW9uIGFuZCByZXR1cm4gdHlwZSBjb252ZXJzaW9uLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIDxjb2RlPnNvdXJjZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIHRoZW4gYSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzb3VyY2UgVGhlIDxjb2RlPklucHV0U291cmNlPC9jb2RlPiBvZiB0aGUgZG9jdW1lbnQgdG8gZXZhbHVhdGUgb3Zlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgdGhlIGV4cHJlc3Npb24gYW5kIGNvbnZlcnRpbmcgdGhlIHJlc3VsdCB0byBhCisgICAgICogICA8Y29kZT5TdHJpbmc8L2NvZGU+LgorICAgICAqCisgICAgICogQHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gSWYgdGhlIGV4cHJlc3Npb24gY2Fubm90IGJlIGV2YWx1YXRlZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmICA8Y29kZT5zb3VyY2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZXZhbHVhdGUoSW5wdXRTb3VyY2Ugc291cmNlKQorICAgICAgICB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC94cGF0aC9YUGF0aEV4cHJlc3Npb25FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjIxZmQ3YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw2MSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvLyAkSWQ6IFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbi5qYXZhIDQ0NjU5OCAyMDA2LTA5LTE1IDEyOjU1OjQwWiBqZXJlbWlhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLnhwYXRoOworCisvKioKKyAqIDxjb2RlPlhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbjwvY29kZT4gcmVwcmVzZW50cyBhbiBlcnJvciBpbiBhbiBYUGF0aCBleHByZXNzaW9uLjwvcD4KKyAqCisgKiBAYXV0aG9yICA8YSBocmVmPSJtYWlsdG86Tm9ybWFuLldhbHNoQFN1bi5jb20iPk5vcm1hbiBXYWxzaDwvYT4KKyAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogNDQ2NTk4ICQsICREYXRlOiAyMDA2LTA5LTE1IDA1OjU1OjQwIC0wNzAwIChGcmksIDE1IFNlcCAyMDA2KSAkCisgKiBAc2luY2UgMS41CisgKi8KK3B1YmxpYyBjbGFzcyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gZXh0ZW5kcyBYUGF0aEV4Y2VwdGlvbiB7CisKKyAgICAvKioKKyAgICAgKiA8cD5TdHJlYW0gVW5pcXVlIElkZW50aWZpZXIuPC9wPgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xODM3MDgwMjYwMzc0OTg2OTgwTDsKKworICAgIC8qKgorICAgICAqIDxwPkNvbnN0cnVjdHMgYSBuZXcgPGNvZGU+WFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uPC9jb2RlPiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIDxjb2RlPm1lc3NhZ2U8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90IGluaXRpYWxpemVkLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIDxjb2RlPm1lc3NhZ2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LCB0aGVuIGEgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZGV0YWlsIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5Db25zdHJ1Y3RzIGEgbmV3IDxjb2RlPlhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbjwvY29kZT4gd2l0aCB0aGUgc3BlY2lmaWVkIDxjb2RlPmNhdXNlPC9jb2RlPi48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIHRoZW4gYSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXVzZSBUaGUgY2F1c2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC94cGF0aC9YUGF0aEZhY3RvcnkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGIxYzFmYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhGYWN0b3J5LmphdmEKQEAgLTAsMCArMSwyOTIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLy8gJElkOiBYUGF0aEZhY3RvcnkuamF2YSA4ODg4ODkgMjAwOS0xMi0wOSAxNzo0MzoxOFogbXJnbGF2YXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC54cGF0aDsKKworLyoqCisgKiA8cD5BbiA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+IGluc3RhbmNlIGNhbiBiZSB1c2VkIHRvIGNyZWF0ZQorICoge0BsaW5rIGphdmF4LnhtbC54cGF0aC5YUGF0aH0gb2JqZWN0cy48L3A+CisgKgorICo8cD5TZWUge0BsaW5rICNuZXdJbnN0YW5jZShTdHJpbmcgdXJpKX0gZm9yIGxvb2t1cCBtZWNoYW5pc20uPC9wPgorICoKKyAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLmNvbSI+Tm9ybWFuIFdhbHNoPC9hPgorICogQGF1dGhvciAgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgorICogQHZlcnNpb24gJFJldmlzaW9uOiA4ODg4ODkgJCwgJERhdGU6IDIwMDktMTItMDkgMDk6NDM6MTggLTA4MDAgKFdlZCwgMDkgRGVjIDIwMDkpICQKKyAqIEBzaW5jZSAxLjUKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFhQYXRoRmFjdG9yeSB7CisKKworICAgIC8qKgorICAgICAqIDxwPlRoZSBkZWZhdWx0IHByb3BlcnR5IG5hbWUgYWNjb3JkaW5nIHRvIHRoZSBKQVhQIHNwZWMuPC9wPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfUFJPUEVSVFlfTkFNRSA9ICJqYXZheC54bWwueHBhdGguWFBhdGhGYWN0b3J5IjsKKworICAgIC8qKgorICAgICAqIDxwPkRlZmF1bHQgT2JqZWN0IE1vZGVsIFVSSS48L3A+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9PQkpFQ1RfTU9ERUxfVVJJID0gImh0dHA6Ly9qYXZhLnN1bi5jb20vamF4cC94cGF0aC9kb20iOworCisgICAgLyoqCisgICAgICogPHA+UHJvdGVjdGVkIGNvbnN0cnVjdG9yIGFzIHtAbGluayAjbmV3SW5zdGFuY2UoKX0sIHtAbGluayAjbmV3SW5zdGFuY2UoU3RyaW5nIHVyaSl9CisgICAgICogb3Ige0BsaW5rICNuZXdJbnN0YW5jZShTdHJpbmcgdXJpLCBTdHJpbmcgZmFjdG9yeUNsYXNzTmFtZSwgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIpfQorICAgICAqIHNob3VsZCBiZSB1c2VkIHRvIGNyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiBhbiA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+LjwvcD4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgWFBhdGhGYWN0b3J5KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkdldCBhIG5ldyA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+IGluc3RhbmNlIHVzaW5nIHRoZSBkZWZhdWx0IG9iamVjdCBtb2RlbCwKKyAgICAgKiB7QGxpbmsgI0RFRkFVTFRfT0JKRUNUX01PREVMX1VSSX0sCisgICAgICogdGhlIFczQyBET00uPC9wPgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgZnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQgdG86PC9wPgorICAgICAqIDxwcmU+CisgICAgICogICBuZXdJbnN0YW5jZShERUZBVUxUX09CSkVDVF9NT0RFTF9VUkkpCisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiA8cD5TaW5jZSB0aGUgaW1wbGVtZW50YXRpb24gZm9yIHRoZSBXM0MgRE9NIGlzIGFsd2F5cyBhdmFpbGFibGUsIHRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIgZmFpbC48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIEluc3RhbmNlIG9mIGFuIDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBYUGF0aEZhY3RvcnkgbmV3SW5zdGFuY2UoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gbmV3SW5zdGFuY2UoREVGQVVMVF9PQkpFQ1RfTU9ERUxfVVJJKTsKKyAgICAgICAgfQorICAgICAgICBjYXRjaCAoWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbiB4cGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiWFBhdGhGYWN0b3J5I25ld0luc3RhbmNlKCkgZmFpbGVkIHRvIGNyZWF0ZSBhbiBYUGF0aEZhY3RvcnkgZm9yIHRoZSBkZWZhdWx0IG9iamVjdCBtb2RlbDogIgorICAgICAgICAgICAgICAgICsgREVGQVVMVF9PQkpFQ1RfTU9ERUxfVVJJCisgICAgICAgICAgICAgICAgKyAiIHdpdGggdGhlIFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb246ICIKKyAgICAgICAgICAgICAgICArIHhwYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24udG9TdHJpbmcoKQorICAgICAgICAgICAgKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICogPHA+R2V0IGEgbmV3IDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBvYmplY3QgbW9kZWwuPC9wPgorICAgICoKKyAgICAqIDxwPlRvIGZpbmQgYSA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+IG9iamVjdCwKKyAgICAqIHRoaXMgbWV0aG9kIGxvb2tzIHRoZSBmb2xsb3dpbmcgcGxhY2VzIGluIHRoZSBmb2xsb3dpbmcgb3JkZXIgd2hlcmUgInRoZSBjbGFzcyBsb2FkZXIiIHJlZmVycyB0byB0aGUgY29udGV4dCBjbGFzcyBsb2FkZXI6PC9wPgorICAgICogPG9sPgorICAgICogICA8bGk+CisgICAgKiAgICAgSWYgdGhlIHN5c3RlbSBwcm9wZXJ0eSB7QGxpbmsgI0RFRkFVTFRfUFJPUEVSVFlfTkFNRX0gKyAiOnVyaSIgaXMgcHJlc2VudCwKKyAgICAqICAgICB3aGVyZSB1cmkgaXMgdGhlIHBhcmFtZXRlciB0byB0aGlzIG1ldGhvZCwgdGhlbiBpdHMgdmFsdWUgaXMgcmVhZCBhcyBhIGNsYXNzIG5hbWUuCisgICAgKiAgICAgVGhlIG1ldGhvZCB3aWxsIHRyeSB0byBjcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBieSB1c2luZyB0aGUgY2xhc3MgbG9hZGVyLAorICAgICogICAgIGFuZCByZXR1cm5zIGl0IGlmIGl0IGlzIHN1Y2Nlc3NmdWxseSBjcmVhdGVkLgorICAgICogICA8L2xpPgorICAgICogICA8bGk+CisgICAgKiAgICAgJHtqYXZhLmhvbWV9L2xpYi9qYXhwLnByb3BlcnRpZXMgaXMgcmVhZCBhbmQgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUga2V5IGJlaW5nIHRoZSBzeXN0ZW0gcHJvcGVydHkgYWJvdmUgaXMgbG9va2VkIGZvci4KKyAgICAqICAgICBJZiBwcmVzZW50LCB0aGUgdmFsdWUgaXMgcHJvY2Vzc2VkIGp1c3QgbGlrZSBhYm92ZS4KKyAgICAqICAgPC9saT4KKyAgICAqICAgPGxpPgorICAgICogICAgIFRoZSBjbGFzcyBsb2FkZXIgaXMgYXNrZWQgZm9yIHNlcnZpY2UgcHJvdmlkZXIgcHJvdmlkZXItY29uZmlndXJhdGlvbiBmaWxlcyBtYXRjaGluZyA8Y29kZT5qYXZheC54bWwueHBhdGguWFBhdGhGYWN0b3J5PC9jb2RlPgorICAgICogICAgIGluIHRoZSByZXNvdXJjZSBkaXJlY3RvcnkgTUVUQS1JTkYvc2VydmljZXMuCisgICAgKiAgICAgU2VlIHRoZSBKQVIgRmlsZSBTcGVjaWZpY2F0aW9uIGZvciBmaWxlIGZvcm1hdCBhbmQgcGFyc2luZyBydWxlcy4KKyAgICAqICAgICBFYWNoIHBvdGVudGlhbCBzZXJ2aWNlIHByb3ZpZGVyIGlzIHJlcXVpcmVkIHRvIGltcGxlbWVudCB0aGUgbWV0aG9kOgorICAgICogICAgIDxwcmU+CisgICAgKiAgICAgICB7QGxpbmsgI2lzT2JqZWN0TW9kZWxTdXBwb3J0ZWQoU3RyaW5nIG9iamVjdE1vZGVsKX0KKyAgICAqICAgICA8L3ByZT4KKyAgICAqICAgICBUaGUgZmlyc3Qgc2VydmljZSBwcm92aWRlciBmb3VuZCBpbiBjbGFzcyBsb2FkZXIgb3JkZXIgdGhhdCBzdXBwb3J0cyB0aGUgc3BlY2lmaWVkIG9iamVjdCBtb2RlbCBpcyByZXR1cm5lZC4KKyAgICAqICAgPC9saT4KKyAgICAqICAgPGxpPgorICAgICogICAgIFBsYXRmb3JtIGRlZmF1bHQgPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiBpcyBsb2NhdGVkIGluIGEgcGxhdGZvcm0gc3BlY2lmaWMgd2F5LgorICAgICogICAgIFRoZXJlIG11c3QgYmUgYSBwbGF0Zm9ybSBkZWZhdWx0IFhQYXRoRmFjdG9yeSBmb3IgdGhlIFczQyBET00sIGkuZS4ge0BsaW5rICNERUZBVUxUX09CSkVDVF9NT0RFTF9VUkl9LgorICAgICogICA8L2xpPgorICAgICogPC9vbD4KKyAgICAqIDxwPklmIGV2ZXJ5dGhpbmcgZmFpbHMsIGFuIDxjb2RlPlhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duLjwvcD4KKyAgICAqCisgICAgKiA8cD5UaXAgZm9yIFRyb3VibGUtc2hvb3Rpbmc6PC9wPgorICAgICogPHA+U2VlIHtAbGluayBqYXZhLnV0aWwuUHJvcGVydGllcyNsb2FkKGphdmEuaW8uSW5wdXRTdHJlYW0pfSBmb3IgZXhhY3RseSBob3cgYSBwcm9wZXJ0eSBmaWxlIGlzIHBhcnNlZC4KKyAgICAqIEluIHBhcnRpY3VsYXIsIGNvbG9ucyAnOicgbmVlZCB0byBiZSBlc2NhcGVkIGluIGEgcHJvcGVydHkgZmlsZSwgc28gbWFrZSBzdXJlIHRoZSBVUklzIGFyZSBwcm9wZXJseSBlc2NhcGVkIGluIGl0LgorICAgICogRm9yIGV4YW1wbGU6PC9wPgorICAgICogPHByZT4KKyAgICAqICAgaHR0cFw6Ly9qYXZhLnN1bi5jb20vamF4cC94cGF0aC9kb209b3JnLmFjbWUuRG9tWFBhdGhGYWN0b3J5CisgICAgKiA8L3ByZT4KKyAgICAqCisgICAgKiBAcGFyYW0gdXJpIElkZW50aWZpZXMgdGhlIHVuZGVybHlpbmcgb2JqZWN0IG1vZGVsLgorICAgICogICBUaGUgc3BlY2lmaWNhdGlvbiBvbmx5IGRlZmluZXMgdGhlIFVSSSB7QGxpbmsgI0RFRkFVTFRfT0JKRUNUX01PREVMX1VSSX0sCisgICAgKiAgIDxjb2RlPmh0dHA6Ly9qYXZhLnN1bi5jb20vamF4cC94cGF0aC9kb208L2NvZGU+IGZvciB0aGUgVzNDIERPTSwKKyAgICAqICAgdGhlIG9yZy53M2MuZG9tIHBhY2thZ2UsIGFuZCBpbXBsZW1lbnRhdGlvbnMgYXJlIGZyZWUgdG8gaW50cm9kdWNlIG90aGVyIFVSSXMgZm9yIG90aGVyIG9iamVjdCBtb2RlbHMuCisgICAgKgorICAgICogQHJldHVybiBJbnN0YW5jZSBvZiBhbiA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+LgorICAgICoKKyAgICAqIEB0aHJvd3MgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbiBJZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBtb2RlbCBpcyB1bmF2YWlsYWJsZS4KKyAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+dXJpPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPnVyaS5sZW5ndGgoKSA9PSAwPC9jb2RlPi4KKyAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgWFBhdGhGYWN0b3J5IG5ld0luc3RhbmNlKGZpbmFsIFN0cmluZyB1cmkpCisgICAgICAgIHRocm93cyBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHVyaSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgIlhQYXRoRmFjdG9yeSNuZXdJbnN0YW5jZShTdHJpbmcgdXJpKSBjYW5ub3QgYmUgY2FsbGVkIHdpdGggdXJpID09IG51bGwiCisgICAgICAgICAgICApOworICAgICAgICB9CisgICAgICAgIGlmICh1cmkubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiWFBhdGhGYWN0b3J5I25ld0luc3RhbmNlKFN0cmluZyB1cmkpIGNhbm5vdCBiZSBjYWxsZWQgd2l0aCB1cmkgPT0gXCJcIiIKKyAgICAgICAgICAgICk7CisgICAgICAgIH0KKyAgICAgICAgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpOworICAgICAgICBpZiAoY2xhc3NMb2FkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgLy91c2UgdGhlIGN1cnJlbnQgY2xhc3MgbG9hZGVyCisgICAgICAgICAgICBjbGFzc0xvYWRlciA9IFhQYXRoRmFjdG9yeS5jbGFzcy5nZXRDbGFzc0xvYWRlcigpOworICAgICAgICB9CisgICAgICAgIFhQYXRoRmFjdG9yeSB4cGF0aEZhY3RvcnkgPSBuZXcgWFBhdGhGYWN0b3J5RmluZGVyKGNsYXNzTG9hZGVyKS5uZXdGYWN0b3J5KHVyaSk7CisgICAgICAgIGlmICh4cGF0aEZhY3RvcnkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24oCisgICAgICAgICAgICAgICAgIk5vIFhQYXRoRmFjdG9yeSBpbXBsZW1lbnRhdGlvbiBmb3VuZCBmb3IgdGhlIG9iamVjdCBtb2RlbDogIgorICAgICAgICAgICAgICAgICsgdXJpCisgICAgICAgICAgICApOworICAgICAgICB9CisgICAgICAgIHJldHVybiB4cGF0aEZhY3Rvcnk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiBJbnN0YW5jZSBvZiBhbiA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+LgorICAgICAqCisgICAgICogQHRocm93cyBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uIElmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IG1vZGVsIGlzIHVuYXZhaWxhYmxlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+dXJpPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiA8Y29kZT51cmkubGVuZ3RoKCkgPT0gMDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBYUGF0aEZhY3RvcnkgbmV3SW5zdGFuY2UoU3RyaW5nIHVyaSwgU3RyaW5nIGZhY3RvcnlDbGFzc05hbWUsCisgICAgICAgICAgICBDbGFzc0xvYWRlciBjbGFzc0xvYWRlcikgdGhyb3dzIFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24geworICAgICAgICBpZiAodXJpID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiWFBhdGhGYWN0b3J5I25ld0luc3RhbmNlKFN0cmluZyB1cmkpIGNhbm5vdCBiZSBjYWxsZWQgd2l0aCB1cmkgPT0gbnVsbCIKKyAgICAgICAgICAgICk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHVyaS5sZW5ndGgoKSA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJYUGF0aEZhY3RvcnkjbmV3SW5zdGFuY2UoU3RyaW5nIHVyaSkgY2Fubm90IGJlIGNhbGxlZCB3aXRoIHVyaSA9PSBcIlwiIgorICAgICAgICAgICAgKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZmFjdG9yeUNsYXNzTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbigiZmFjdG9yeUNsYXNzTmFtZSBjYW5ub3QgYmUgbnVsbC4iKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2xhc3NMb2FkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgY2xhc3NMb2FkZXIgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpOworICAgICAgICB9CisgICAgICAgIFhQYXRoRmFjdG9yeSB4cGF0aEZhY3RvcnkgPSBuZXcgWFBhdGhGYWN0b3J5RmluZGVyKGNsYXNzTG9hZGVyKS5jcmVhdGVJbnN0YW5jZShmYWN0b3J5Q2xhc3NOYW1lKTsKKyAgICAgICAgaWYgKHhwYXRoRmFjdG9yeSA9PSBudWxsIHx8ICF4cGF0aEZhY3RvcnkuaXNPYmplY3RNb2RlbFN1cHBvcnRlZCh1cmkpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiTm8gWFBhdGhGYWN0b3J5IGltcGxlbWVudGF0aW9uIGZvdW5kIGZvciB0aGUgb2JqZWN0IG1vZGVsOiAiCisgICAgICAgICAgICAgICAgKyB1cmkKKyAgICAgICAgICAgICk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHhwYXRoRmFjdG9yeTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5JcyBzcGVjaWZpZWQgb2JqZWN0IG1vZGVsIHN1cHBvcnRlZCBieSB0aGlzIDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4/PC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdE1vZGVsIFNwZWNpZmllcyB0aGUgb2JqZWN0IG1vZGVsIHdoaWNoIHRoZSByZXR1cm5lZCA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+IHdpbGwgdW5kZXJzdGFuZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiBzdXBwb3J0cyA8Y29kZT5vYmplY3RNb2RlbDwvY29kZT4sIGVsc2UgPGNvZGU+ZmFsc2U8L2NvZGU+LgorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5vYmplY3RNb2RlbDwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgPGNvZGU+b2JqZWN0TW9kZWwubGVuZ3RoKCkgPT0gMDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNPYmplY3RNb2RlbFN1cHBvcnRlZChTdHJpbmcgb2JqZWN0TW9kZWwpOworCisgICAgLyoqCisgICAgICogPHA+U2V0IGEgZmVhdHVyZSBmb3IgdGhpcyA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+IGFuZCA8Y29kZT5YUGF0aDwvY29kZT5zIGNyZWF0ZWQgYnkgdGhpcyBmYWN0b3J5LjwvcD4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIEZlYXR1cmUgbmFtZXMgYXJlIGZ1bGx5IHF1YWxpZmllZCB7QGxpbmsgamF2YS5uZXQuVVJJfXMuCisgICAgICogSW1wbGVtZW50YXRpb25zIG1heSBkZWZpbmUgdGhlaXIgb3duIGZlYXR1cmVzLgorICAgICAqIEFuIHtAbGluayBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9ufSBpcyB0aHJvd24gaWYgdGhpcyA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+IG9yIHRoZSA8Y29kZT5YUGF0aDwvY29kZT5zCisgICAgICogIGl0IGNyZWF0ZXMgY2Fubm90IHN1cHBvcnQgdGhlIGZlYXR1cmUuCisgICAgICogSXQgaXMgcG9zc2libGUgZm9yIGFuIDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4gdG8gZXhwb3NlIGEgZmVhdHVyZSB2YWx1ZSBidXQgYmUgdW5hYmxlIHRvIGNoYW5nZSBpdHMgc3RhdGUuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogPHA+CisgICAgICogQWxsIGltcGxlbWVudGF0aW9ucyBhcmUgcmVxdWlyZWQgdG8gc3VwcG9ydCB0aGUge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lOR30gZmVhdHVyZS4KKyAgICAgKiBXaGVuIHRoZSBmZWF0dXJlIGlzIDxjb2RlPnRydWU8L2NvZGU+LCBhbnkgcmVmZXJlbmNlIHRvICBhbiBleHRlcm5hbCBmdW5jdGlvbiBpcyBhbiBlcnJvci4KKyAgICAgKiBVbmRlciB0aGVzZSBjb25kaXRpb25zLCB0aGUgaW1wbGVtZW50YXRpb24gbXVzdCBub3QgY2FsbCB0aGUge0BsaW5rIFhQYXRoRnVuY3Rpb25SZXNvbHZlcn0KKyAgICAgKiBhbmQgbXVzdCB0aHJvdyBhbiB7QGxpbmsgWFBhdGhGdW5jdGlvbkV4Y2VwdGlvbn0uCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgRmVhdHVyZSBuYW1lLgorICAgICAqIEBwYXJhbSB2YWx1ZSBJcyBmZWF0dXJlIHN0YXRlIDxjb2RlPnRydWU8L2NvZGU+IG9yIDxjb2RlPmZhbHNlPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGlzIDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4gb3IgdGhlIDxjb2RlPlhQYXRoPC9jb2RlPnMKKyAgICAgKiAgIGl0IGNyZWF0ZXMgY2Fubm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+bmFtZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkKKyAgICAgICAgdGhyb3dzIFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiA8cD5HZXQgdGhlIHN0YXRlIG9mIHRoZSBuYW1lZCBmZWF0dXJlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIEZlYXR1cmUgbmFtZXMgYXJlIGZ1bGx5IHF1YWxpZmllZCB7QGxpbmsgamF2YS5uZXQuVVJJfXMuCisgICAgICogSW1wbGVtZW50YXRpb25zIG1heSBkZWZpbmUgdGhlaXIgb3duIGZlYXR1cmVzLgorICAgICAqIEFuIHtAbGluayBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9ufSBpcyB0aHJvd24gaWYgdGhpcyA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+IG9yIHRoZSA8Y29kZT5YUGF0aDwvY29kZT5zCisgICAgICogaXQgY3JlYXRlcyBjYW5ub3Qgc3VwcG9ydCB0aGUgZmVhdHVyZS4KKyAgICAgKiBJdCBpcyBwb3NzaWJsZSBmb3IgYW4gPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiB0byBleHBvc2UgYSBmZWF0dXJlIHZhbHVlIGJ1dCBiZSB1bmFibGUgdG8gY2hhbmdlIGl0cyBzdGF0ZS4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBGZWF0dXJlIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFN0YXRlIG9mIHRoZSBuYW1lZCBmZWF0dXJlLgorICAgICAqCisgICAgICogQHRocm93cyBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uIGlmIHRoaXMgPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiBvciB0aGUgPGNvZGU+WFBhdGg8L2NvZGU+cworICAgICAqICAgaXQgY3JlYXRlcyBjYW5ub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5uYW1lPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKQorICAgICAgICB0aHJvd3MgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIDxwPkVzdGFibGlzaCBhIGRlZmF1bHQgdmFyaWFibGUgcmVzb2x2ZXIuPC9wPgorICAgICAqCisgICAgICogPHA+QW55IDxjb2RlPlhQYXRoPC9jb2RlPiBvYmplY3RzIGNvbnN0cnVjdGVkIGZyb20gdGhpcyBmYWN0b3J5IHdpbGwgdXNlCisgICAgICogdGhlIHNwZWNpZmllZCByZXNvbHZlciBieSBkZWZhdWx0LjwvcD4KKyAgICAgKgorICAgICAqIDxwPkEgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlzIHRocm93biBpZiA8Y29kZT5yZXNvbHZlcjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHJlc29sdmVyIFZhcmlhYmxlIHJlc29sdmVyLgorICAgICAqCisgICAgICogIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+cmVzb2x2ZXI8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFhQYXRoVmFyaWFibGVSZXNvbHZlcihYUGF0aFZhcmlhYmxlUmVzb2x2ZXIgcmVzb2x2ZXIpOworCisgICAgLyoqCisgICAgICAgKiA8cD5Fc3RhYmxpc2ggYSBkZWZhdWx0IGZ1bmN0aW9uIHJlc29sdmVyLjwvcD4KKyAgICAgICAqCisgICAgICAgKiA8cD5BbnkgPGNvZGU+WFBhdGg8L2NvZGU+IG9iamVjdHMgY29uc3RydWN0ZWQgZnJvbSB0aGlzIGZhY3Rvcnkgd2lsbCB1c2UKKyAgICAgICAqIHRoZSBzcGVjaWZpZWQgcmVzb2x2ZXIgYnkgZGVmYXVsdC48L3A+CisgICAgICAgKgorICAgICAgICogPHA+QSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duIGlmIDxjb2RlPnJlc29sdmVyPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi48L3A+CisgICAgICAgKgorICAgICAgICogQHBhcmFtIHJlc29sdmVyIFhQYXRoIGZ1bmN0aW9uIHJlc29sdmVyLgorICAgICAgICoKKyAgICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+cmVzb2x2ZXI8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0WFBhdGhGdW5jdGlvblJlc29sdmVyKFhQYXRoRnVuY3Rpb25SZXNvbHZlciByZXNvbHZlcik7CisKKyAgICAvKioKKyAgICAqIDxwPlJldHVybiBhIG5ldyA8Y29kZT5YUGF0aDwvY29kZT4gdXNpbmcgdGhlIHVuZGVybHlpbmcgb2JqZWN0CisgICAgKiBtb2RlbCBkZXRlcm1pbmVkIHdoZW4gdGhlIDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4gd2FzIGluc3RhbnRpYXRlZC48L3A+CisgICAgKgorICAgICogQHJldHVybiBOZXcgaW5zdGFuY2Ugb2YgYW4gPGNvZGU+WFBhdGg8L2NvZGU+LgorICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFhQYXRoIG5ld1hQYXRoKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3hwYXRoL1hQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBkMTliMjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3hwYXRoL1hQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDYxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8vICRJZDogWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbi5qYXZhIDQ0NjU5OCAyMDA2LTA5LTE1IDEyOjU1OjQwWiBqZXJlbWlhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLnhwYXRoOworCisvKioKKyAqIDxjb2RlPlhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb248L2NvZGU+IHJlcHJlc2VudHMgYSBjb25maWd1cmF0aW9uIGVycm9yIGluIGEgPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiBlbnZpcm9ubWVudC48L3A+CisgKgorICogQGF1dGhvciAgPGEgaHJlZj0ibWFpbHRvOk5vcm1hbi5XYWxzaEBTdW4uY29tIj5Ob3JtYW4gV2Fsc2g8L2E+CisgKiBAYXV0aG9yICA8YSBocmVmPSJtYWlsdG86SmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDQ0NjU5OCAkLCAkRGF0ZTogMjAwNi0wOS0xNSAwNTo1NTo0MCAtMDcwMCAoRnJpLCAxNSBTZXAgMjAwNikgJAorICogQHNpbmNlIDEuNQorICovCitwdWJsaWMgY2xhc3MgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleHRlbmRzIFhQYXRoRXhjZXB0aW9uIHsKKworICAgIC8qKgorICAgICAqIDxwPlN0cmVhbSBVbmlxdWUgSWRlbnRpZmllci48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTE4MzcwODAyNjAzNzQ5ODY5ODBMOworCisgICAgLyoqCisgICAgICogPHA+Q29uc3RydWN0cyBhIG5ldyA8Y29kZT5YUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uPC9jb2RlPiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIDxjb2RlPm1lc3NhZ2U8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90IGluaXRpYWxpemVkLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIDxjb2RlPm1lc3NhZ2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LCB0aGVuIGEgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZGV0YWlsIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+Q29uc3RydWN0cyBhIG5ldyA8Y29kZT5YUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uPC9jb2RlPiB3aXRoIHRoZSBzcGVjaWZpZWQgPGNvZGU+Y2F1c2U8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwgdGhlbiBhIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlIFRoZSBjYXVzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC94cGF0aC9YUGF0aEZhY3RvcnlGaW5kZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhGYWN0b3J5RmluZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjUyYTFkOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhGYWN0b3J5RmluZGVyLmphdmEKQEAgLTAsMCArMSwzNzEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLy8gJElkOiBYUGF0aEZhY3RvcnlGaW5kZXIuamF2YSA2NzA0MzIgMjAwOC0wNi0yMyAwMjowMjowOFogbXJnbGF2YXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC54cGF0aDsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZheC54bWwudmFsaWRhdGlvbi5TY2hlbWFGYWN0b3J5OworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKKworLyoqCisgKiBJbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgWFBhdGhGYWN0b3J5I25ld0luc3RhbmNlKFN0cmluZyl9LgorICoKKyAqIEBhdXRob3IgPGEgaHJlZj0iS29oc3VrZS5LYXdhZ3VjaGlAU3VuLmNvbSI+S29oc3VrZSBLYXdhZ3VjaGk8L2E+CisgKiBAdmVyc2lvbiAkUmV2aXNpb246IDY3MDQzMiAkLCAkRGF0ZTogMjAwOC0wNi0yMiAxOTowMjowOCAtMDcwMCAoU3VuLCAyMiBKdW4gMjAwOCkgJAorICogQHNpbmNlIDEuNQorICovCitmaW5hbCBjbGFzcyBYUGF0aEZhY3RvcnlGaW5kZXIgeworCisgICAgLyoqIGRlYnVnIHN1cHBvcnQgY29kZS4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGRlYnVnID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBEZWZhdWx0IGNvbHVtbnMgcGVyIGxpbmUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfTElORV9MRU5HVEggPSA4MDsKKworICAgIHN0YXRpYyB7CisgICAgICAgIFN0cmluZyB2YWwgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImpheHAuZGVidWciKTsKKyAgICAgICAgLy8gQWxsb3cgc2ltcGx5IHNldHRpbmcgdGhlIHByb3AgdG8gdHVybiBvbiBkZWJ1ZworICAgICAgICBkZWJ1ZyA9IHZhbCAhPSBudWxsICYmICghICJmYWxzZSIuZXF1YWxzKHZhbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkNhY2hlIHByb3BlcnRpZXMgZm9yIHBlcmZvcm1hbmNlLjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBQcm9wZXJ0aWVzIGNhY2hlUHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCisgICAgLyoqCisgICAgICogPHA+Rmlyc3QgdGltZSByZXF1aXJlcyBpbml0aWFsaXphdGlvbiBvdmVyaGVhZC48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBmaXJzdFRpbWUgPSB0cnVlOworCisgICAgLyoqCisgICAgICogPHA+Q29uZGl0aW9uYWwgZGVidWcgcHJpbnRpbmcuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG1zZyB0byBwcmludAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZGVidWdQcmludGxuKFN0cmluZyBtc2cpIHsKKyAgICAgICAgaWYgKGRlYnVnKSB7CisgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkpBWFA6ICIgKyBtc2cpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+PGNvZGU+Q2xhc3NMb2FkZXI8L2NvZGU+IHRvIHVzZSB0byBmaW5kIDxjb2RlPlNjaGVtYUZhY3Rvcnk8L2NvZGU+LjwvcD4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyOworCisgICAgLyoqCisgICAgICogPHA+Q29uc3RydWN0b3IgdGhhdCBzcGVjaWZpZXMgPGNvZGU+Q2xhc3NMb2FkZXI8L2NvZGU+IHRvIHVzZQorICAgICAqIHRvIGZpbmQgPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGxvYWRlcgorICAgICAqICAgICAgdG8gYmUgdXNlZCB0byBsb2FkIHJlc291cmNlLCB7QGxpbmsgU2NoZW1hRmFjdG9yeX0sIGFuZAorICAgICAqICAgICAge0Bjb2RlIFNjaGVtYUZhY3RvcnlMb2FkZXJ9IGltcGxlbWVudGF0aW9ucyBkdXJpbmcKKyAgICAgKiAgICAgIHRoZSByZXNvbHV0aW9uIHByb2Nlc3MuCisgICAgICogICAgICBJZiB0aGlzIHBhcmFtZXRlciBpcyBudWxsLCB0aGUgZGVmYXVsdCBzeXN0ZW0gY2xhc3MgbG9hZGVyCisgICAgICogICAgICB3aWxsIGJlIHVzZWQuCisgICAgICovCisgICAgcHVibGljIFhQYXRoRmFjdG9yeUZpbmRlcihDbGFzc0xvYWRlciBsb2FkZXIpIHsKKyAgICAgICAgdGhpcy5jbGFzc0xvYWRlciA9IGxvYWRlcjsKKyAgICAgICAgaWYgKGRlYnVnKSB7CisgICAgICAgICAgICBkZWJ1Z0Rpc3BsYXlDbGFzc0xvYWRlcigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGRlYnVnRGlzcGxheUNsYXNzTG9hZGVyKCkgeworICAgICAgICBpZiAoY2xhc3NMb2FkZXIgPT0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSkgeworICAgICAgICAgICAgZGVidWdQcmludGxuKCJ1c2luZyB0aHJlYWQgY29udGV4dCBjbGFzcyBsb2FkZXIgKCIgKyBjbGFzc0xvYWRlciArICIpIGZvciBzZWFyY2giKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjbGFzc0xvYWRlcj09Q2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKSkgeworICAgICAgICAgICAgZGVidWdQcmludGxuKCJ1c2luZyBzeXN0ZW0gY2xhc3MgbG9hZGVyICgiICsgY2xhc3NMb2FkZXIgKyAiKSBmb3Igc2VhcmNoIik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBkZWJ1Z1ByaW50bG4oInVzaW5nIGNsYXNzIGxvYWRlciAoIiArIGNsYXNzTG9hZGVyICsgIikgZm9yIHNlYXJjaCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkNyZWF0ZXMgYSBuZXcge0BsaW5rIFhQYXRoRmFjdG9yeX0gb2JqZWN0IGZvciB0aGUgc3BlY2lmaWVkCisgICAgICogc2NoZW1hIGxhbmd1YWdlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmkKKyAgICAgKiAgICAgICBJZGVudGlmaWVzIHRoZSB1bmRlcmx5aW5nIG9iamVjdCBtb2RlbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGNhbGxlZSBmYWlscyB0byBjcmVhdGUgb25lLgorICAgICAqCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAqICAgICAgSWYgdGhlIHBhcmFtZXRlciBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBYUGF0aEZhY3RvcnkgbmV3RmFjdG9yeShTdHJpbmcgdXJpKSB7CisgICAgICAgIGlmKHVyaT09bnVsbCkgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBYUGF0aEZhY3RvcnkgZiA9IF9uZXdGYWN0b3J5KHVyaSk7CisgICAgICAgIGlmIChkZWJ1ZykgeworICAgICAgICAgICAgaWYgKGYgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGRlYnVnUHJpbnRsbigiZmFjdG9yeSAnIiArIGYuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiJyB3YXMgZm91bmQgZm9yICIgKyB1cmkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkZWJ1Z1ByaW50bG4oInVuYWJsZSB0byBmaW5kIGEgZmFjdG9yeSBmb3IgIiArIHVyaSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGY7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+TG9va3VwIGEge0BsaW5rIFhQYXRoRmFjdG9yeX0gZm9yIHRoZSBnaXZlbiBvYmplY3QgbW9kZWwuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHVyaSBpZGVudGlmaWVzIHRoZSBvYmplY3QgbW9kZWwuCisgICAgICovCisgICAgcHJpdmF0ZSBYUGF0aEZhY3RvcnkgX25ld0ZhY3RvcnkoU3RyaW5nIHVyaSkgeworICAgICAgICBYUGF0aEZhY3RvcnkgeHBmOworICAgICAgICBTdHJpbmcgcHJvcGVydHlOYW1lID0gU0VSVklDRV9DTEFTUy5nZXROYW1lKCkgKyAiOiIgKyB1cmk7CisKKyAgICAgICAgLy8gc3lzdGVtIHByb3BlcnR5IGxvb2sgdXAKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChkZWJ1ZykgZGVidWdQcmludGxuKCJMb29raW5nIHVwIHN5c3RlbSBwcm9wZXJ0eSAnIitwcm9wZXJ0eU5hbWUrIiciICk7CisgICAgICAgICAgICBTdHJpbmcgciA9IFN5c3RlbS5nZXRQcm9wZXJ0eShwcm9wZXJ0eU5hbWUpOworICAgICAgICAgICAgaWYgKHIgIT0gbnVsbCAmJiByLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgICAgIGlmIChkZWJ1ZykgZGVidWdQcmludGxuKCJUaGUgdmFsdWUgaXMgJyIrcisiJyIpOworICAgICAgICAgICAgICAgIHhwZiA9IGNyZWF0ZUluc3RhbmNlKHIpOworICAgICAgICAgICAgICAgIGlmKHhwZiE9bnVsbCkgICAgcmV0dXJuIHhwZjsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZGVidWcpIHsKKyAgICAgICAgICAgICAgICBkZWJ1Z1ByaW50bG4oIlRoZSBwcm9wZXJ0eSBpcyB1bmRlZmluZWQuIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGphdmFoID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmhvbWUiKTsKKyAgICAgICAgU3RyaW5nIGNvbmZpZ0ZpbGUgPSBqYXZhaCArIEZpbGUuc2VwYXJhdG9yICsKKyAgICAgICAgImxpYiIgKyBGaWxlLnNlcGFyYXRvciArICJqYXhwLnByb3BlcnRpZXMiOworCisgICAgICAgIFN0cmluZyBmYWN0b3J5Q2xhc3NOYW1lID0gbnVsbCA7CisKKyAgICAgICAgLy8gdHJ5IHRvIHJlYWQgZnJvbSAkamF2YS5ob21lL2xpYi9qYXhwLnByb3BlcnRpZXMKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmKGZpcnN0VGltZSl7CisgICAgICAgICAgICAgICAgc3luY2hyb25pemVkKGNhY2hlUHJvcHMpeworICAgICAgICAgICAgICAgICAgICBpZihmaXJzdFRpbWUpeworICAgICAgICAgICAgICAgICAgICAgICAgRmlsZSBmPW5ldyBGaWxlKCBjb25maWdGaWxlICk7CisgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdFRpbWUgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmLmV4aXN0cygpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlYnVnKSBkZWJ1Z1ByaW50bG4oIlJlYWQgcHJvcGVydGllcyBmaWxlICIgKyBmKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZVByb3BzLmxvYWQobmV3IEZpbGVJbnB1dFN0cmVhbShmKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmYWN0b3J5Q2xhc3NOYW1lID0gY2FjaGVQcm9wcy5nZXRQcm9wZXJ0eShwcm9wZXJ0eU5hbWUpOworICAgICAgICAgICAgaWYgKGRlYnVnKSBkZWJ1Z1ByaW50bG4oImZvdW5kICIgKyBmYWN0b3J5Q2xhc3NOYW1lICsgIiBpbiAkamF2YS5ob21lL2pheHAucHJvcGVydGllcyIpOworCisgICAgICAgICAgICBpZiAoZmFjdG9yeUNsYXNzTmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgeHBmID0gY3JlYXRlSW5zdGFuY2UoZmFjdG9yeUNsYXNzTmFtZSk7CisgICAgICAgICAgICAgICAgaWYoeHBmICE9IG51bGwpeworICAgICAgICAgICAgICAgICAgICByZXR1cm4geHBmOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBpZiAoZGVidWcpIHsKKyAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHRyeSBNRVRBLUlORi9zZXJ2aWNlcyBmaWxlcworICAgICAgICBmb3IgKFVSTCByZXNvdXJjZSA6IGNyZWF0ZVNlcnZpY2VGaWxlSXRlcmF0b3IoKSkgeworICAgICAgICAgICAgaWYgKGRlYnVnKSBkZWJ1Z1ByaW50bG4oImxvb2tpbmcgaW50byAiICsgcmVzb3VyY2UpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB4cGYgPSBsb2FkRnJvbVNlcnZpY2VzRmlsZSh1cmksIHJlc291cmNlLnRvRXh0ZXJuYWxGb3JtKCksIHJlc291cmNlLm9wZW5TdHJlYW0oKSk7CisgICAgICAgICAgICAgICAgaWYoeHBmIT1udWxsKSAgICByZXR1cm4geHBmOworICAgICAgICAgICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgaWYoIGRlYnVnICkgeworICAgICAgICAgICAgICAgICAgICBkZWJ1Z1ByaW50bG4oImZhaWxlZCB0byByZWFkICIrcmVzb3VyY2UpOworICAgICAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHBsYXRmb3JtIGRlZmF1bHQKKyAgICAgICAgaWYodXJpLmVxdWFscyhYUGF0aEZhY3RvcnkuREVGQVVMVF9PQkpFQ1RfTU9ERUxfVVJJKSkgeworICAgICAgICAgICAgaWYgKGRlYnVnKSBkZWJ1Z1ByaW50bG4oImF0dGVtcHRpbmcgdG8gdXNlIHRoZSBwbGF0Zm9ybSBkZWZhdWx0IFczQyBET00gWFBhdGggbGliIik7CisgICAgICAgICAgICByZXR1cm4gY3JlYXRlSW5zdGFuY2UoIm9yZy5hcGFjaGUueHBhdGguamF4cC5YUGF0aEZhY3RvcnlJbXBsIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZGVidWcpIGRlYnVnUHJpbnRsbigiYWxsIHRoaW5ncyB3ZXJlIHRyaWVkLCBidXQgbm9uZSB3YXMgZm91bmQuIGJhaWxpbmcgb3V0LiIpOworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5DcmVhdGVzIGFuIGluc3RhbmNlIG9mIHRoZSBzcGVjaWZpZWQgYW5kIHJldHVybnMgaXQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGNsYXNzTmFtZQorICAgICAqICAgICAgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUgdG8gYmUgaW5zdGFudGlhdGVkLgorICAgICAqCisgICAgICogQHJldHVybiBudWxsCisgICAgICogICAgICBpZiBpdCBmYWlscy4gRXJyb3IgbWVzc2FnZXMgd2lsbCBiZSBwcmludGVkIGJ5IHRoaXMgbWV0aG9kLgorICAgICAqLworICAgIFhQYXRoRmFjdG9yeSBjcmVhdGVJbnN0YW5jZSggU3RyaW5nIGNsYXNzTmFtZSApIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChkZWJ1ZykgZGVidWdQcmludGxuKCJpbnN0YW50aWF0aW5nICIrY2xhc3NOYW1lKTsKKyAgICAgICAgICAgIENsYXNzIGNsYXp6OworICAgICAgICAgICAgaWYoIGNsYXNzTG9hZGVyIT1udWxsICkKKyAgICAgICAgICAgICAgICBjbGF6eiA9IGNsYXNzTG9hZGVyLmxvYWRDbGFzcyhjbGFzc05hbWUpOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIGNsYXp6ID0gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUpOworICAgICAgICAgICAgaWYoZGVidWcpICAgICAgIGRlYnVnUHJpbnRsbigibG9hZGVkIGl0IGZyb20gIit3aGljaChjbGF6eikpOworICAgICAgICAgICAgT2JqZWN0IG8gPSBjbGF6ei5uZXdJbnN0YW5jZSgpOworCisgICAgICAgICAgICBpZiggbyBpbnN0YW5jZW9mIFhQYXRoRmFjdG9yeSApCisgICAgICAgICAgICAgICAgcmV0dXJuIChYUGF0aEZhY3RvcnkpbzsKKworICAgICAgICAgICAgaWYgKGRlYnVnKSBkZWJ1Z1ByaW50bG4oY2xhc3NOYW1lKyIgaXMgbm90IGFzc2lnbmFibGUgdG8gIitTRVJWSUNFX0NMQVNTLmdldE5hbWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgLy8gVGhlIFZNIHJhbiBvdXQgb2YgbWVtb3J5IG9yIHRoZXJlIHdhcyBzb21lIG90aGVyIHNlcmlvdXMgcHJvYmxlbS4gUmUtdGhyb3cuCisgICAgICAgIGNhdGNoIChWaXJ0dWFsTWFjaGluZUVycm9yIHZtZSkgeworICAgICAgICAgICAgdGhyb3cgdm1lOworICAgICAgICB9CisgICAgICAgIC8vIFRocmVhZERlYXRoIHNob3VsZCBhbHdheXMgYmUgcmUtdGhyb3duCisgICAgICAgIGNhdGNoIChUaHJlYWREZWF0aCB0ZCkgeworICAgICAgICAgICAgdGhyb3cgdGQ7CisgICAgICAgIH0KKyAgICAgICAgY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgICBpZiAoZGVidWcpIHsKKyAgICAgICAgICAgICAgICBkZWJ1Z1ByaW50bG4oImZhaWxlZCB0byBpbnN0YW50aWF0ZSAiK2NsYXNzTmFtZSk7CisgICAgICAgICAgICAgICAgdC5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKiogU2VhcmNoZXMgZm9yIGEgWFBhdGhGYWN0b3J5IGZvciBhIGdpdmVuIHVyaSBpbiBhIE1FVEEtSU5GL3NlcnZpY2VzIGZpbGUuICovCisgICAgcHJpdmF0ZSBYUGF0aEZhY3RvcnkgbG9hZEZyb21TZXJ2aWNlc0ZpbGUoU3RyaW5nIHVyaSwgU3RyaW5nIHJlc291cmNlTmFtZSwgSW5wdXRTdHJlYW0gaW4pIHsKKworICAgICAgICBpZiAoZGVidWcpIGRlYnVnUHJpbnRsbigiUmVhZGluZyAiICsgcmVzb3VyY2VOYW1lICk7CisKKyAgICAgICAgQnVmZmVyZWRSZWFkZXIgcmQ7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZCA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaW4sICJVVEYtOCIpLCBERUZBVUxUX0xJTkVfTEVOR1RIKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJkID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihpbiksIERFRkFVTFRfTElORV9MRU5HVEgpOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGZhY3RvcnlDbGFzc05hbWU7CisgICAgICAgIFhQYXRoRmFjdG9yeSByZXN1bHRGYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgLy8gU2VlIHNwZWMgZm9yIHByb3ZpZGVyLWNvbmZpZ3VyYXRpb24gZmlsZXM6IGh0dHA6Ly9qYXZhLnN1bi5jb20vajJzZS8xLjUuMC9kb2NzL2d1aWRlL2phci9qYXIuaHRtbCNQcm92aWRlciUyMENvbmZpZ3VyYXRpb24lMjBGaWxlCisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZhY3RvcnlDbGFzc05hbWUgPSByZC5yZWFkTGluZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24geCkgeworICAgICAgICAgICAgICAgIC8vIE5vIHByb3ZpZGVyIGZvdW5kCisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZmFjdG9yeUNsYXNzTmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgLy8gSWdub3JlIGNvbW1lbnRzIGluIHRoZSBwcm92aWRlci1jb25maWd1cmF0aW9uIGZpbGUKKyAgICAgICAgICAgICAgICBpbnQgaGFzaEluZGV4ID0gZmFjdG9yeUNsYXNzTmFtZS5pbmRleE9mKCcjJyk7CisgICAgICAgICAgICAgICAgaWYgKGhhc2hJbmRleCAhPSAtMSkgeworICAgICAgICAgICAgICAgICAgICBmYWN0b3J5Q2xhc3NOYW1lID0gZmFjdG9yeUNsYXNzTmFtZS5zdWJzdHJpbmcoMCwgaGFzaEluZGV4KTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBJZ25vcmUgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZQorICAgICAgICAgICAgICAgIGZhY3RvcnlDbGFzc05hbWUgPSBmYWN0b3J5Q2xhc3NOYW1lLnRyaW0oKTsKKworICAgICAgICAgICAgICAgIC8vIElmIHRoZXJlJ3Mgbm8gdGV4dCBsZWZ0IG9yIGlmIHRoaXMgd2FzIGEgYmxhbmsgbGluZSwgZ28gdG8gdGhlIG5leHQgb25lLgorICAgICAgICAgICAgICAgIGlmIChmYWN0b3J5Q2xhc3NOYW1lLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgLy8gRm91bmQgdGhlIHJpZ2h0IFhQYXRoRmFjdG9yeSBpZiBpdHMgaXNPYmplY3RNb2RlbFN1cHBvcnRlZChTdHJpbmcgdXJpKSBtZXRob2QgcmV0dXJucyB0cnVlLgorICAgICAgICAgICAgICAgICAgICBYUGF0aEZhY3RvcnkgZm91bmRGYWN0b3J5ID0gY3JlYXRlSW5zdGFuY2UoZmFjdG9yeUNsYXNzTmFtZSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChmb3VuZEZhY3RvcnkuaXNPYmplY3RNb2RlbFN1cHBvcnRlZCh1cmkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRGYWN0b3J5ID0gZm91bmRGYWN0b3J5OworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkocmQpOworCisgICAgICAgIHJldHVybiByZXN1bHRGYWN0b3J5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4ge0BsaW5rIEl0ZXJhdG9yfSB0aGF0IGVudW1lcmF0ZXMgYWxsCisgICAgICogdGhlIE1FVEEtSU5GL3NlcnZpY2VzIGZpbGVzIHRoYXQgd2UgY2FyZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIEl0ZXJhYmxlPFVSTD4gY3JlYXRlU2VydmljZUZpbGVJdGVyYXRvcigpIHsKKyAgICAgICAgaWYgKGNsYXNzTG9hZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIFVSTCByZXNvdXJjZSA9IFhQYXRoRmFjdG9yeUZpbmRlci5jbGFzcy5nZXRDbGFzc0xvYWRlcigpLmdldFJlc291cmNlKFNFUlZJQ0VfSUQpOworICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnNpbmdsZXRvbihyZXNvdXJjZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEVudW1lcmF0aW9uPFVSTD4gZSA9IGNsYXNzTG9hZGVyLmdldFJlc291cmNlcyhTRVJWSUNFX0lEKTsKKyAgICAgICAgICAgICAgICBpZiAoZGVidWcgJiYgIWUuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZGVidWdQcmludGxuKCJubyAiK1NFUlZJQ0VfSUQrIiBmaWxlIHdhcyBmb3VuZCIpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5saXN0KGUpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGlmIChkZWJ1ZykgeworICAgICAgICAgICAgICAgICAgICBkZWJ1Z1ByaW50bG4oImZhaWxlZCB0byBlbnVtZXJhdGUgcmVzb3VyY2VzICIrU0VSVklDRV9JRCk7CisgICAgICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbXB0eVNldCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ2xhc3MgU0VSVklDRV9DTEFTUyA9IFhQYXRoRmFjdG9yeS5jbGFzczsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VSVklDRV9JRCA9ICJNRVRBLUlORi9zZXJ2aWNlcy8iICsgU0VSVklDRV9DTEFTUy5nZXROYW1lKCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgd2hpY2goIENsYXNzIGNsYXp6ICkgeworICAgICAgICByZXR1cm4gd2hpY2goIGNsYXp6LmdldE5hbWUoKSwgY2xhenouZ2V0Q2xhc3NMb2FkZXIoKSApOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlNlYXJjaCB0aGUgc3BlY2lmaWVkIGNsYXNzbG9hZGVyIGZvciB0aGUgZ2l2ZW4gY2xhc3NuYW1lLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbGFzc25hbWUgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBjbGFzcyB0byBzZWFyY2ggZm9yCisgICAgICogQHBhcmFtIGxvYWRlciB0aGUgY2xhc3Nsb2FkZXIgdG8gc2VhcmNoCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBzb3VyY2UgbG9jYXRpb24gb2YgdGhlIHJlc291cmNlLCBvciBudWxsIGlmIGl0IHdhc24ndCBmb3VuZAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB3aGljaChTdHJpbmcgY2xhc3NuYW1lLCBDbGFzc0xvYWRlciBsb2FkZXIpIHsKKyAgICAgICAgU3RyaW5nIGNsYXNzbmFtZUFzUmVzb3VyY2UgPSBjbGFzc25hbWUucmVwbGFjZSgnLicsICcvJykgKyAiLmNsYXNzIjsKKyAgICAgICAgaWYgKGxvYWRlcj09bnVsbCkgbG9hZGVyID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKTsKKworICAgICAgICBVUkwgaXQgPSBsb2FkZXIuZ2V0UmVzb3VyY2UoY2xhc3NuYW1lQXNSZXNvdXJjZSk7CisgICAgICAgIHJldHVybiBpdCAhPSBudWxsID8gaXQudG9TdHJpbmcoKSA6IG51bGw7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC94cGF0aC9YUGF0aEZ1bmN0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3hwYXRoL1hQYXRoRnVuY3Rpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZDgwMTY5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC94cGF0aC9YUGF0aEZ1bmN0aW9uLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvLyAkSWQ6IFhQYXRoRnVuY3Rpb24uamF2YSA0NDY1OTggMjAwNi0wOS0xNSAxMjo1NTo0MFogamVyZW1pYXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC54cGF0aDsKKworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIDxwPjxjb2RlPlhQYXRoRnVuY3Rpb248L2NvZGU+IHByb3ZpZGVzIGFjY2VzcyB0byBYUGF0aCBmdW5jdGlvbnMuPC9wPgorICoKKyAqIDxwPkZ1bmN0aW9ucyBhcmUgaWRlbnRpZmllZCBieSBRTmFtZSBhbmQgYXJpdHkgaW4gWFBhdGguPC9wPgorICoKKyAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLmNvbSI+Tm9ybWFuIFdhbHNoPC9hPgorICogQGF1dGhvciAgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgorICogQHZlcnNpb24gJFJldmlzaW9uOiA0NDY1OTggJCwgJERhdGU6IDIwMDYtMDktMTUgMDU6NTU6NDAgLTA3MDAgKEZyaSwgMTUgU2VwIDIwMDYpICQKKyAqIEBzaW5jZSAxLjUKKyAqLworcHVibGljIGludGVyZmFjZSBYUGF0aEZ1bmN0aW9uIHsKKyAgLyoqCisgICAqIDxwPkV2YWx1YXRlIHRoZSBmdW5jdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgYXJndW1lbnRzLjwvcD4KKyAgICoKKyAgICogPHA+VG8gdGhlIGdyZWF0ZXN0IGV4dGVudCBwb3NzaWJsZSwgc2lkZS1lZmZlY3RzIHNob3VsZCBiZSBhdm9pZGVkIGluIHRoZQorICAgKiBkZWZpbml0aW9uIG9mIGV4dGVuc2lvbiBmdW5jdGlvbnMuIFRoZSBpbXBsZW1lbnRhdGlvbiBldmFsdWF0aW5nIGFuCisgICAqIFhQYXRoIGV4cHJlc3Npb24gaXMgdW5kZXIgbm8gb2JsaWdhdGlvbiB0byBjYWxsIGV4dGVuc2lvbiBmdW5jdGlvbnMgaW4KKyAgICogYW55IHBhcnRpY3VsYXIgb3JkZXIgb3IgYW55IHBhcnRpY3VsYXIgbnVtYmVyIG9mIHRpbWVzLjwvcD4KKyAgICoKKyAgICogQHBhcmFtIGFyZ3MgVGhlIGFyZ3VtZW50cywgPGNvZGU+bnVsbDwvY29kZT4gaXMgYSB2YWxpZCB2YWx1ZS4KKyAgICoKKyAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgdGhlIDxjb2RlPlhQYXRoPC9jb2RlPiBmdW5jdGlvbiBhcyBhbiA8Y29kZT5PYmplY3Q8L2NvZGU+LgorICAgKgorICAgKiBAdGhyb3dzIFhQYXRoRnVuY3Rpb25FeGNlcHRpb24gSWYgPGNvZGU+YXJnczwvY29kZT4gY2Fubm90IGJlIGV2YWx1YXRlZCB3aXRoIHRoaXMgPGNvZGU+WFBhdGg8L2NvZGU+IGZ1bmN0aW9uLgorICAgKi8KKyAgcHVibGljIE9iamVjdCBldmFsdWF0ZShMaXN0IGFyZ3MpCisgICAgdGhyb3dzIFhQYXRoRnVuY3Rpb25FeGNlcHRpb247Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhGdW5jdGlvbkV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC94cGF0aC9YUGF0aEZ1bmN0aW9uRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjg5MDEyNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhGdW5jdGlvbkV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLy8gJElkOiBYUGF0aEZ1bmN0aW9uRXhjZXB0aW9uLmphdmEgNDQ2NTk4IDIwMDYtMDktMTUgMTI6NTU6NDBaIGplcmVtaWFzICQKKworcGFja2FnZSBqYXZheC54bWwueHBhdGg7CisKKy8qKgorICogPGNvZGU+WFBhdGhGdW5jdGlvbkV4Y2VwdGlvbjwvY29kZT4gcmVwcmVzZW50cyBhbiBlcnJvciB3aXRoIGFuIFhQYXRoIGZ1bmN0aW9uLjwvcD4KKyAqCisgKiBAYXV0aG9yICA8YSBocmVmPSJtYWlsdG86Tm9ybWFuLldhbHNoQFN1bi5jb20iPk5vcm1hbiBXYWxzaDwvYT4KKyAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogNDQ2NTk4ICQsICREYXRlOiAyMDA2LTA5LTE1IDA1OjU1OjQwIC0wNzAwIChGcmksIDE1IFNlcCAyMDA2KSAkCisgKiBAc2luY2UgMS41CisgKi8KK3B1YmxpYyBjbGFzcyBYUGF0aEZ1bmN0aW9uRXhjZXB0aW9uIGV4dGVuZHMgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIHsKKworICAgIC8qKgorICAgICAqIDxwPlN0cmVhbSBVbmlxdWUgSWRlbnRpZmllci48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTE4MzcwODAyNjAzNzQ5ODY5ODBMOworCisgICAgLyoqCisgICAgICogPHA+Q29uc3RydWN0cyBhIG5ldyA8Y29kZT5YUGF0aEZ1bmN0aW9uRXhjZXB0aW9uPC9jb2RlPiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIDxjb2RlPm1lc3NhZ2U8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90IGluaXRpYWxpemVkLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIDxjb2RlPm1lc3NhZ2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LCB0aGVuIGEgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZGV0YWlsIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIFhQYXRoRnVuY3Rpb25FeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICAgICAgc3VwZXIobWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+Q29uc3RydWN0cyBhIG5ldyA8Y29kZT5YUGF0aEZ1bmN0aW9uRXhjZXB0aW9uPC9jb2RlPiB3aXRoIHRoZSBzcGVjaWZpZWQgPGNvZGU+Y2F1c2U8L2NvZGU+LjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwgdGhlbiBhIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGNhdXNlIFRoZSBjYXVzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBYUGF0aEZ1bmN0aW9uRXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC94cGF0aC9YUGF0aEZ1bmN0aW9uUmVzb2x2ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhGdW5jdGlvblJlc29sdmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzgyMzZkNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhGdW5jdGlvblJlc29sdmVyLmphdmEKQEAgLTAsMCArMSw2MCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvLyAkSWQ6IFhQYXRoRnVuY3Rpb25SZXNvbHZlci5qYXZhIDQ0NjU5OCAyMDA2LTA5LTE1IDEyOjU1OjQwWiBqZXJlbWlhcyAkCisKK3BhY2thZ2UgamF2YXgueG1sLnhwYXRoOworCitpbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKKworLyoqCisgKiA8cD48Y29kZT5YUGF0aEZ1bmN0aW9uUmVzb2x2ZXI8L2NvZGU+IHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgc2V0IG9mIHVzZXIgZGVmaW5lZCA8Y29kZT5YUGF0aEZ1bmN0aW9uPC9jb2RlPnMuPC9wPgorICoKKyAqIDxwPlhQYXRoIGZ1bmN0aW9ucyBhcmUgcmVzb2x2ZWQgYnkgbmFtZSBhbmQgYXJpdHkuCisgKiBUaGUgcmVzb2x2ZXIgaXMgbm90IG5lZWRlZCBmb3IgWFBhdGggYnVpbHQtaW4gZnVuY3Rpb25zIGFuZCB0aGUgcmVzb2x2ZXIKKyAqIDxzdHJvbmc+PGVtPmNhbm5vdDwvZW0+PC9zdHJvbmc+IGJlIHVzZWQgdG8gb3ZlcnJpZGUgdGhvc2UgZnVuY3Rpb25zLjwvcD4KKyAqCisgKiA8cD5JbiBwYXJ0aWN1bGFyLCB0aGUgcmVzb2x2ZXIgaXMgb25seSBjYWxsZWQgZm9yIGZ1bmN0aW9ucyBpbiBhbiBhbm90aGVyCisgKiBuYW1lc3BhY2UgKGZ1bmN0aW9ucyB3aXRoIGFuIGV4cGxpY2l0IHByZWZpeCkuIFRoaXMgbWVhbnMgdGhhdCB5b3UgY2Fubm90CisgKiB1c2UgdGhlIDxjb2RlPlhQYXRoRnVuY3Rpb25SZXNvbHZlcjwvY29kZT4gdG8gaW1wbGVtZW50IHNwZWNpZmljYXRpb25zCisgKiBsaWtlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbGRzaWctY29yZS8iPlhNTC1TaWduYXR1cmUgU3ludGF4CisgKiBhbmQgUHJvY2Vzc2luZzwvYT4gd2hpY2ggZXh0ZW5kIHRoZSBmdW5jdGlvbiBsaWJyYXJ5IG9mIFhQYXRoIDEuMCBpbiB0aGUKKyAqIHNhbWUgbmFtZXNwYWNlLiBUaGlzIGlzIGEgY29uc2VxdWVuY2Ugb2YgdGhlIGRlc2lnbiBvZiB0aGUgcmVzb2x2ZXIuPC9wPgorICoKKyAqIDxwPklmIHlvdSB3aXNoIHRvIGltcGxlbWVudCBhZGRpdGlvbmFsIGJ1aWx0LWluIGZ1bmN0aW9ucywgeW91IHdpbGwgaGF2ZSB0bworICogZXh0ZW5kIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uIGRpcmVjdGx5LjwvcD4KKyAqCisgKiBAYXV0aG9yICA8YSBocmVmPSJtYWlsdG86Tm9ybWFuLldhbHNoQFN1bi5jb20iPk5vcm1hbiBXYWxzaDwvYT4KKyAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KKyAqIEB2ZXJzaW9uICRSZXZpc2lvbjogNDQ2NTk4ICQsICREYXRlOiAyMDA2LTA5LTE1IDA1OjU1OjQwIC0wNzAwIChGcmksIDE1IFNlcCAyMDA2KSAkCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2NvcmVsaWIiPlhNTCBQYXRoIExhbmd1YWdlIChYUGF0aCkgVmVyc2lvbiAxLjAsIENvcmUgRnVuY3Rpb24gTGlicmFyeTwvYT4KKyAqIEBzaW5jZSAxLjUKKyAqLworcHVibGljIGludGVyZmFjZSBYUGF0aEZ1bmN0aW9uUmVzb2x2ZXIgeworICAvKioKKyAgICogPHA+RmluZCBhIGZ1bmN0aW9uIGluIHRoZSBzZXQgb2YgYXZhaWxhYmxlIGZ1bmN0aW9ucy48L3A+CisgICAqCisgICAqIDxwPklmIDxjb2RlPmZ1bmN0aW9uTmFtZTwvY29kZT4gb3IgPGNvZGU+YXJpdHk8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LCB0aGVuIGEgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+CisgICAqCisgICAqIEBwYXJhbSBmdW5jdGlvbk5hbWUgVGhlIGZ1bmN0aW9uIG5hbWUuCisgICAqIEBwYXJhbSBhcml0eSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0aGF0IHRoZSByZXR1cm5lZCBmdW5jdGlvbiBtdXN0IGFjY2VwdC4KKyAgICoKKyAgICogQHJldHVybiBUaGUgZnVuY3Rpb24gb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm8gZnVuY3Rpb24gbmFtZWQgPGNvZGU+ZnVuY3Rpb25OYW1lPC9jb2RlPiB3aXRoIDxjb2RlPmFyaXR5PC9jb2RlPiBhcmd1bWVudHMgZXhpc3RzLgorICAgKgorICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPmZ1bmN0aW9uTmFtZTwvY29kZT4gb3IgPGNvZGU+YXJpdHk8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgKi8KKyAgcHVibGljIFhQYXRoRnVuY3Rpb24gcmVzb2x2ZUZ1bmN0aW9uKFFOYW1lIGZ1bmN0aW9uTmFtZSwgaW50IGFyaXR5KTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvWFBhdGhWYXJpYWJsZVJlc29sdmVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3hwYXRoL1hQYXRoVmFyaWFibGVSZXNvbHZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4OTM4YTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvamF2YXgveG1sL3hwYXRoL1hQYXRoVmFyaWFibGVSZXNvbHZlci5qYXZhCkBAIC0wLDAgKzEsNTEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLy8gJElkOiBYUGF0aFZhcmlhYmxlUmVzb2x2ZXIuamF2YSA0NDY1OTggMjAwNi0wOS0xNSAxMjo1NTo0MFogamVyZW1pYXMgJAorCitwYWNrYWdlIGphdmF4LnhtbC54cGF0aDsKKworaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWU7CisKKy8qKgorICogPHA+PGNvZGU+WFBhdGhWYXJpYWJsZVJlc29sdmVyPC9jb2RlPiBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlIHNldCBvZiB1c2VyIGRlZmluZWQgWFBhdGggdmFyaWFibGVzLjwvcD4KKyAqCisgKiA8cD5UaGUgPGNvZGU+WFBhdGhWYXJpYWJsZVJlc29sdmVyPC9jb2RlPiBhbmQgdGhlIFhQYXRoIGV2YWx1YXRvciBtdXN0IGFkaGVyZSB0byBhIGNvbnRyYWN0IHRoYXQKKyAqIGNhbm5vdCBiZSBkaXJlY3RseSBlbmZvcmNlZCBieSB0aGUgQVBJLiAgQWx0aG91Z2ggdmFyaWFibGVzIG1heSBiZSBtdXRhYmxlLAorICogdGhhdCBpcywgYW4gYXBwbGljYXRpb24gbWF5IHdpc2ggdG8gZXZhbHVhdGUgdGhlIHNhbWUgWFBhdGggZXhwcmVzc2lvbiBtb3JlCisgKiB0aGFuIG9uY2Ugd2l0aCBkaWZmZXJlbnQgdmFyaWFibGUgdmFsdWVzLCBpbiB0aGUgY291cnNlIG9mIGV2YWx1YXRpbmcgYW55CisgKiBzaW5nbGUgWFBhdGggZXhwcmVzc2lvbiwgYSB2YXJpYWJsZSdzIHZhbHVlIDxzdHJvbmc+PGVtPm11c3Q8L2VtPjwvc3Ryb25nPiBiZSBpbW11dGFibGUuPC9wPgorICoKKyAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLmNvbSI+Tm9ybWFuIFdhbHNoPC9hPgorICogQGF1dGhvciAgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgorICogQHZlcnNpb24gJFJldmlzaW9uOiA0NDY1OTggJCwgJERhdGU6IDIwMDYtMDktMTUgMDU6NTU6NDAgLTA3MDAgKEZyaSwgMTUgU2VwIDIwMDYpICQKKyAqIEBzaW5jZSAxLjUKKyAqLworcHVibGljIGludGVyZmFjZSBYUGF0aFZhcmlhYmxlUmVzb2x2ZXIgeworICAvKioKKyAgICogPHA+RmluZCBhIHZhcmlhYmxlIGluIHRoZSBzZXQgb2YgYXZhaWxhYmxlIHZhcmlhYmxlcy48L3A+CisgICAqCisgICAqIDxwPklmIDxjb2RlPnZhcmlhYmxlTmFtZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIHRoZW4gYSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KKyAgICoKKyAgICogQHBhcmFtIHZhcmlhYmxlTmFtZSBUaGUgPGNvZGU+UU5hbWU8L2NvZGU+IG9mIHRoZSB2YXJpYWJsZSBuYW1lLgorICAgKgorICAgKiBAcmV0dXJuIFRoZSB2YXJpYWJsZXMgdmFsdWUsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vIHZhcmlhYmxlIG5hbWVkIDxjb2RlPnZhcmlhYmxlTmFtZTwvY29kZT4KKyAgICogICBleGlzdHMuICBUaGUgdmFsdWUgcmV0dXJuZWQgbXVzdCBiZSBvZiBhIHR5cGUgYXBwcm9wcmlhdGUgZm9yIHRoZSB1bmRlcmx5aW5nIG9iamVjdCBtb2RlbC4KKyAgICoKKyAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT52YXJpYWJsZU5hbWU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgKi8KKyAgcHVibGljIE9iamVjdCByZXNvbHZlVmFyaWFibGUoUU5hbWUgdmFyaWFibGVOYW1lKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvcGFja2FnZS5odG1sIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2phdmF4L3htbC94cGF0aC9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWRlYjQ0OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9qYXZheC94bWwveHBhdGgvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMjYxIEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PgorPCEtLSAkSWQ6IHBhY2thZ2UuaHRtbCA1NzAxMDcgMjAwNy0wOC0yNyAxMzozMDoxOVogbXJnbGF2YXMgJCAtLT4KKworPCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBYSFRNTCAxLjAgU3RyaWN0Ly9FTiIKKyAgICAgICAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvVFIveGh0bWwxL0RURC94aHRtbDEtc3RyaWN0LmR0ZCI+Cis8aHRtbCB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI+Cis8aGVhZD4KKzx0aXRsZT5qYXZheC54bWwueHBhdGg8L3RpdGxlPgorPG1ldGEgbmFtZT0iQGF1dGhvciIgY29udGVudD0ibWFpbHRvOkJlbkBnYWxicmFpdGhzLm9yZyIgLz4KKzxtZXRhIG5hbWU9IkBhdXRob3IiIGNvbnRlbnQ9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLmNvbSIgLz4KKzxtZXRhIG5hbWU9IkBhdXRob3IiIGNvbnRlbnQ9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIiAvPgorPG1ldGEgbmFtZT0iQHZlcnNpb24iIGNvbnRlbnQ9IiRSZXZpc2lvbjogNTcwMTA3ICQsICREYXRlOiAyMDA3LTA4LTI3IDA2OjMwOjE5IC0wNzAwIChNb24sIDI3IEF1ZyAyMDA3KSAkIiAvPgorPG1ldGEgbmFtZT0iQHNlZSIgY29udGVudD0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgiIC8+Cis8bWV0YSBuYW1lPSJAc2luY2UiIGNvbnRlbnQ9IjEuNSIgLz4KKzwvaGVhZD4KKworPGJvZHk+CisKKzxwPlRoaXMgcGFja2FnZSBwcm92aWRlcyBhbiA8ZW0+b2JqZWN0LW1vZGVsIG5ldXRyYWw8L2VtPiBBUEkgZm9yIHRoZQorZXZhbHVhdGlvbiBvZiBYUGF0aCBleHByZXNzaW9ucyBhbmQgYWNjZXNzIHRvIHRoZSBldmFsdWF0aW9uCitlbnZpcm9ubWVudC4KKzwvcD4KKworPHA+VGhlIGZvbGxvd2luZyBYTUwgc3RhbmRhcmRzIGFwcGx5OjwvcD4KKworPHVsPgorPGxpPjxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoIj5YTUwgUGF0aCBMYW5ndWFnZSAoWFBhdGgpIFZlcnNpb24gMS4wPC9hPjwvbGk+Cis8L3VsPgorCis8aHIgLz4KKworPGgyPlhQYXRoIE92ZXJ2aWV3PC9oMj4KKworPHA+VGhlIFhQYXRoIGxhbmd1YWdlIHByb3ZpZGVzIGEgc2ltcGxlLCBjb25jaXNlIHN5bnRheCBmb3Igc2VsZWN0aW5nCitub2RlcyBmcm9tIGFuIFhNTCBkb2N1bWVudC4gWFBhdGggYWxzbyBwcm92aWRlcyBydWxlcyBmb3IgY29udmVydGluZyBhCitub2RlIGluIGFuIFhNTCBkb2N1bWVudCBvYmplY3QgbW9kZWwgKERPTSkgdHJlZSB0byBhIGJvb2xlYW4sIGRvdWJsZSwKK29yIHN0cmluZyB2YWx1ZS4gWFBhdGggaXMgYSBXM0MtZGVmaW5lZCBsYW5ndWFnZSBhbmQgYW4gb2ZmaWNpYWwgVzNDCityZWNvbW1lbmRhdGlvbjsgdGhlIFczQyBob3N0cyB0aGUgWE1MIFBhdGggTGFuZ3VhZ2UgKFhQYXRoKSBWZXJzaW9uCisxLjAgc3BlY2lmaWNhdGlvbi4KKzwvcD4KKworPHA+WFBhdGggc3RhcnRlZCBpbiBsaWZlIGluIDE5OTkgYXMgYSBzdXBwbGVtZW50IHRvIHRoZSBYU0xUIGFuZAorWFBvaW50ZXIgbGFuZ3VhZ2VzLCBidXQgaGFzIG1vcmUgcmVjZW50bHkgYmVjb21lIHBvcHVsYXIgYXMgYQorc3RhbmQtYWxvbmUgbGFuZ3VhZ2UsIGFzIGEgc2luZ2xlIFhQYXRoIGV4cHJlc3Npb24gY2FuIGJlIHVzZWQgdG8KK3JlcGxhY2UgbWFueSBsaW5lcyBvZiBET00gQVBJIGNvZGUuCis8L3A+CisKKzxoMz5YUGF0aCBFeHByZXNzaW9uczwvaDM+CisKKzxwPkFuIFhQYXRoIDxlbT5leHByZXNzaW9uPC9lbT4gaXMgY29tcG9zZWQgb2YgYSA8ZW0+bG9jYXRpb24KK3BhdGg8L2VtPiBhbmQgb25lIG9yIG1vcmUgb3B0aW9uYWwgPGVtPnByZWRpY2F0ZXM8L2VtPi4gRXhwcmVzc2lvbnMKK21heSBhbHNvIGluY2x1ZGUgWFBhdGggdmFyaWFibGVzLgorPC9wPgorCis8cD5UaGUgZm9sbG93aW5nIGlzIGFuIGV4YW1wbGUgb2YgYSBzaW1wbGUgWFBhdGggZXhwcmVzc2lvbjo8L3A+CisKKzxwcmU+CisvZm9vL2JhcgorPC9wcmU+CisKKzxwPlRoaXMgZXhhbXBsZSB3b3VsZCBzZWxlY3QgdGhlIDxjb2RlPiZsdDtiYXImZ3Q7PC9jb2RlPiBlbGVtZW50IGluCithbiBYTUwgZG9jdW1lbnQgc3VjaCBhcyB0aGUgZm9sbG93aW5nOjwvcD4KKworPHByZT4KKyZsdDtmb28mZ3Q7CismbHQ7YmFyLyZndDsKKyZsdDsvZm9vJmd0OworPC9wcmU+CisKKzxwPlRoZSBleHByZXNzaW9uIDxjb2RlPi9mb28vYmFyPC9jb2RlPiBpcyBhbiBleGFtcGxlIG9mIGEgbG9jYXRpb24KK3BhdGguIFdoaWxlIFhQYXRoIGxvY2F0aW9uIHBhdGhzIHJlc2VtYmxlIFVuaXgtc3R5bGUgZmlsZSBzeXN0ZW0KK3BhdGhzLCBhbiBpbXBvcnRhbnQgZGlzdGluY3Rpb24gaXMgdGhhdCBYUGF0aCBleHByZXNzaW9ucyByZXR1cm4KKzxlbT5hbGw8L2VtPiBub2RlcyB0aGF0IG1hdGNoIHRoZSBleHByZXNzaW9uLiBUaHVzLCBhbGwgdGhyZWUKKzxjb2RlPiZsdDtiYXImZ3Q7PC9jb2RlPiBlbGVtZW50cyBpbiB0aGUgZm9sbG93aW5nIGRvY3VtZW50IHdvdWxkIGJlCitzZWxlY3RlZCBieSB0aGUgPGNvZGU+L2Zvby9iYXI8L2NvZGU+IGV4cHJlc3Npb246PC9wPgorCis8cHJlPgorJmx0O2ZvbyZndDsKKyZsdDtiYXIvJmd0OworJmx0O2Jhci8mZ3Q7CismbHQ7YmFyLyZndDsKKyZsdDsvZm9vJmd0OworPC9wcmU+CisKKzxwPkEgc3BlY2lhbCBsb2NhdGlvbiBwYXRoIG9wZXJhdG9yLCA8Y29kZT4vLzwvY29kZT4sIHNlbGVjdHMgbm9kZXMgYXQKK2FueSBkZXB0aCBpbiBhbiBYTUwgZG9jdW1lbnQuIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBzZWxlY3RzIGFsbAorPGNvZGU+Jmx0O2JhciZndDs8L2NvZGU+IGVsZW1lbnRzIHJlZ2FyZGxlc3Mgb2YgdGhlaXIgbG9jYXRpb24gaW4gYQorZG9jdW1lbnQ6PC9wPgorCis8cHJlPgorLy9iYXIKKzwvcHJlPgorCis8cD5BIHdpbGRjYXJkIG9wZXJhdG9yLCAqLCBjYXVzZXMgYWxsIGVsZW1lbnQgbm9kZXMgdG8gYmUgc2VsZWN0ZWQuCitUaGUgZm9sbG93aW5nIGV4YW1wbGUgc2VsZWN0cyBhbGwgY2hpbGRyZW4gZWxlbWVudHMgb2YgYQorPGNvZGU+Jmx0O2ZvbyZndDs8L2NvZGU+IGVsZW1lbnQ6PC9wPgorCis8cHJlPgorL2Zvby8qCis8L3ByZT4KKworPHA+SW4gYWRkaXRpb24gdG8gZWxlbWVudCBub2RlcywgWFBhdGggbG9jYXRpb24gcGF0aHMgbWF5IGFsc28gYWRkcmVzcworYXR0cmlidXRlIG5vZGVzLCB0ZXh0IG5vZGVzLCBjb21tZW50IG5vZGVzLCBhbmQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbgorbm9kZXMuIFRoZSBmb2xsb3dpbmcgdGFibGUgZ2l2ZXMgZXhhbXBsZXMgb2YgbG9jYXRpb24gcGF0aHMgZm9yIGVhY2gKK29mIHRoZXNlIG5vZGUgdHlwZXM6PC9wPgorCis8dGFibGUgYm9yZGVyPSIxIj4KKzx0cj4KKzx0ZD5Mb2NhdGlvbiBQYXRoPC90ZD4KKzx0ZD5EZXNjcmlwdGlvbjwvdGQ+Cis8L3RyPgorPHRyPgorPHRkPgorPGNvZGU+L2Zvby9iYXIvPHN0cm9uZz5AaWQ8L3N0cm9uZz48L2NvZGU+Cis8L3RkPgorPHRkPlNlbGVjdHMgdGhlIGF0dHJpYnV0ZSA8Y29kZT5pZDwvY29kZT4gb2YgdGhlIDxjb2RlPiZsdDtiYXImZ3Q7PC9jb2RlPiBlbGVtZW50Cis8L3RkPgorPC90cj4KKzx0cj4KKzx0ZD48Y29kZT4vZm9vL2Jhci88c3Ryb25nPnRleHQoKTwvc3Ryb25nPjwvY29kZT4KKzwvdGQ+Cis8dGQ+U2VsZWN0cyB0aGUgdGV4dCBub2RlcyBvZiB0aGUgPGNvZGU+Jmx0O2JhciZndDs8L2NvZGU+IGVsZW1lbnQuIE5vCitkaXN0aW5jdGlvbiBpcyBtYWRlIGJldHdlZW4gZXNjYXBlZCBhbmQgbm9uLWVzY2FwZWQgY2hhcmFjdGVyIGRhdGEuCis8L3RkPgorPC90cj4KKzx0cj4KKzx0ZD48Y29kZT4vZm9vL2Jhci88c3Ryb25nPmNvbW1lbnQoKTwvc3Ryb25nPjwvY29kZT4KKzwvdGQ+Cis8dGQ+U2VsZWN0cyBhbGwgY29tbWVudCBub2RlcyBjb250YWluZWQgaW4gdGhlIDxjb2RlPiZsdDtiYXImZ3Q7PC9jb2RlPiBlbGVtZW50LgorPC90ZD4KKzwvdHI+Cis8dHI+Cis8dGQ+PGNvZGU+L2Zvby9iYXIvPHN0cm9uZz5wcm9jZXNzaW5nLWluc3RydWN0aW9uKCk8L3N0cm9uZz48L2NvZGU+Cis8L3RkPgorPHRkPlNlbGVjdHMgYWxsIHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24gbm9kZXMgY29udGFpbmVkIGluIHRoZQorPGNvZGU+Jmx0O2JhciZndDs8L2NvZGU+IGVsZW1lbnQuCis8L3RkPgorPC90cj4KKzwvdGFibGU+CisKKzxwPlByZWRpY2F0ZXMgYWxsb3cgZm9yIHJlZmluaW5nIHRoZSBub2RlcyBzZWxlY3RlZCBieSBhbiBYUGF0aAorbG9jYXRpb24gcGF0aC4gUHJlZGljYXRlcyBhcmUgb2YgdGhlIGZvcm0KKzxjb2RlPls8ZW0+ZXhwcmVzc2lvbjwvZW0+XTwvY29kZT4uIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBzZWxlY3RzIGFsbAorPGNvZGU+Jmx0O2ZvbyZndDs8L2NvZGU+IGVsZW1lbnRzIHRoYXQgY29udGFpbiBhbiA8Y29kZT5pbmNsdWRlPC9jb2RlPgorYXR0cmlidXRlIHdpdGggdGhlIHZhbHVlIG9mIDxjb2RlPnRydWU8L2NvZGU+OjwvcD4KKworPHByZT4KKy8vZm9vW0BpbmNsdWRlPSd0cnVlJ10KKzwvcHJlPgorCis8cD5QcmVkaWNhdGVzIG1heSBiZSBhcHBlbmRlZCB0byBlYWNoIG90aGVyIHRvIGZ1cnRoZXIgcmVmaW5lIGFuCitleHByZXNzaW9uLCBzdWNoIGFzOjwvcD4KKworPHByZT4KKy8vZm9vW0BpbmNsdWRlPSd0cnVlJ11bQG1vZGU9J2JhciddCis8L3ByZT4KKworPGgzPlVzaW5nIHRoZSBYUGF0aCBBUEk8L2gzPgorCis8cD4KK1RoZSBmb2xsb3dpbmcgZXhhbXBsZSBkZW1vbnN0cmF0ZXMgdXNpbmcgdGhlIFhQYXRoIEFQSSB0byBzZWxlY3Qgb25lCitvciBtb3JlIG5vZGVzIGZyb20gYW4gWE1MIGRvY3VtZW50OjwvcD4KKworPHByZT4KK1hQYXRoIHhwYXRoID0gWFBhdGhGYWN0b3J5Lm5ld0luc3RhbmNlKCkubmV3WFBhdGgoKTsKK1N0cmluZyBleHByZXNzaW9uID0gIi93aWRnZXRzL3dpZGdldCI7CitJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZSgid2lkZ2V0cy54bWwiKTsKK05vZGVTZXQgbm9kZXMgPSAoTm9kZVNldCkgeHBhdGguZXZhbHVhdGUoZXhwcmVzc2lvbiwgaW5wdXRTb3VyY2UsIFhQYXRoQ29uc3RhbnRzLk5PREVTRVQpOworPC9wcmU+CisKKzxoMz5YUGF0aCBFeHByZXNzaW9ucyBhbmQgVHlwZXM8L2gzPgorCis8cD5XaGlsZSBYUGF0aCBleHByZXNzaW9ucyBzZWxlY3Qgbm9kZXMgaW4gdGhlIFhNTCBkb2N1bWVudCwgdGhlIFhQYXRoCitBUEkgYWxsb3dzIHRoZSBzZWxlY3RlZCBub2RlcyB0byBiZSBjb2FsZXNjZWQgaW50byBvbmUgb2YgdGhlCitmb2xsb3dpbmcgb3RoZXIgZGF0YSB0eXBlczo8L3A+CisKKzx1bD4KKzxsaT48Y29kZT5Cb29sZWFuPC9jb2RlPjwvbGk+Cis8bGk+PGNvZGU+TnVtYmVyPC9jb2RlPjwvbGk+Cis8bGk+PGNvZGU+U3RyaW5nPC9jb2RlPjwvbGk+Cis8L3VsPgorCis8cD5UaGUgZGVzaXJlZCByZXR1cm4gdHlwZSBpcyBzcGVjaWZpZWQgYnkgYSB7QGxpbmsKK2phdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWV9IHBhcmFtZXRlciBpbiBtZXRob2QgY2FsbCB1c2VkIHRvIGV2YWx1YXRlCit0aGUgZXhwcmVzc2lvbiwgd2hpY2ggaXMgZWl0aGVyIGEgY2FsbCB0bworPGNvZGU+WFBhdGhFeHByZXNzaW9uLmV2YWx1YXRlKC4uLik8L2NvZGU+IG9yIHRvIG9uZSBvZiB0aGUKKzxjb2RlPlhQYXRoLmV2YWx1YXRlKC4uLik8L2NvZGU+IGNvbnZlbmllbmNlIG1ldGhvZHMuIFRoZSBhbGxvd2VkCitRTmFtZSB2YWx1ZXMgYXJlIHNwZWNpZmllZCBhcyBjb25zdGFudHMgaW4gdGhlIHtAbGluaworamF2YXgueG1sLnhwYXRoLlhQYXRoQ29uc3RhbnRzfSBjbGFzczsgdGhleSBhcmU6PC9wPgorCis8dWw+Cis8bGk+e0BsaW5rIGphdmF4LnhtbC54cGF0aC5YUGF0aENvbnN0YW50cyNOT0RFU0VUfTwvbGk+Cis8bGk+e0BsaW5rIGphdmF4LnhtbC54cGF0aC5YUGF0aENvbnN0YW50cyNOT0RFfTwvbGk+Cis8bGk+e0BsaW5rIGphdmF4LnhtbC54cGF0aC5YUGF0aENvbnN0YW50cyNTVFJJTkd9PC9saT4KKzxsaT57QGxpbmsgamF2YXgueG1sLnhwYXRoLlhQYXRoQ29uc3RhbnRzI0JPT0xFQU59PC9saT4KKzxsaT57QGxpbmsgamF2YXgueG1sLnhwYXRoLlhQYXRoQ29uc3RhbnRzI05VTUJFUn08L2xpPgorPC91bD4KKworPHA+V2hlbiBhIDxjb2RlPkJvb2xlYW48L2NvZGU+IHJldHVybiB0eXBlIGlzIHJlcXVlc3RlZCwKKzxjb2RlPkJvb2xlYW4uVFJVRTwvY29kZT4gaXMgcmV0dXJuZWQgaWYgb25lIG9yIG1vcmUgbm9kZXMgd2VyZQorc2VsZWN0ZWQ7IG90aGVyd2lzZSwgPGNvZGU+Qm9vbGVhbi5GQUxTRTwvY29kZT4gaXMgcmV0dXJuZWQuPC9wPgorCis8cD5UaGUgPGNvZGU+U3RyaW5nPC9jb2RlPiByZXR1cm4gdHlwZSBpcyBhIGNvbnZlbmllbmNlIGZvciByZXRyaWV2aW5nCit0aGUgY2hhcmFjdGVyIGRhdGEgZnJvbSBhIHRleHQgbm9kZSwgYXR0cmlidXRlIG5vZGUsIGNvbW1lbnQgbm9kZSwgb3IKK3Byb2Nlc3NpbmctaW5zdHJ1Y3Rpb24gbm9kZS4gV2hlbiB1c2VkIG9uIGFuIGVsZW1lbnQgbm9kZSwgdGhlIHZhbHVlCitvZiB0aGUgY2hpbGQgdGV4dCBub2RlcyBpcyByZXR1cm5lZC4KKzwvcD4KKworPHA+VGhlIDxjb2RlPk51bWJlcjwvY29kZT4gcmV0dXJuIHR5cGUgYXR0ZW1wdHMgdG8gY29hbGVzY2UgdGhlIHRleHQKK29mIGEgbm9kZSB0byBhIDxjb2RlPmRvdWJsZTwvY29kZT4gZGF0YSB0eXBlLgorPC9wPgorCis8aDM+WFBhdGggQ29udGV4dDwvaDM+CisKKzxwPlhQYXRoIGxvY2F0aW9uIHBhdGhzIG1heSBiZSByZWxhdGl2ZSB0byBhIHBhcnRpY3VsYXIgbm9kZSBpbiB0aGUKK2RvY3VtZW50LCBrbm93biBhcyB0aGUgPGNvZGU+Y29udGV4dDwvY29kZT4uIENvbnNpZGVyIHRoZSBmb2xsb3dpbmcKK1hNTCBkb2N1bWVudDo8L3A+CisKKzxwcmU+CismbHQ7d2lkZ2V0cyZndDsKKyZsdDt3aWRnZXQmZ3Q7CismbHQ7bWFudWZhY3R1cmVyLyZndDsKKyZsdDtkaW1lbnNpb25zLyZndDsKKyZsdDsvd2lkZ2V0Jmd0OworJmx0Oy93aWRnZXRzJmd0OworPC9wcmU+CisKKzxwPlRoZSA8Y29kZT4mbHQ7d2lkZ2V0Jmd0OzwvY29kZT4gZWxlbWVudCBjYW4gYmUgc2VsZWN0ZWQgd2l0aCB0aGUKK2ZvbGxvd2luZyBYUGF0aCBBUEkgY29kZTo8L3A+CisKKzxwcmU+CisvLyBwYXJzZSB0aGUgWE1MIGFzIGEgVzNDIERvY3VtZW50CitEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGJ1aWxkZXJGYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworYnVpbGRlckZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7CitEb2N1bWVudEJ1aWxkZXIgYnVpbGRlciA9IGJ1aWxkZXJGYWN0b3J5Lm5ld0RvY3VtZW50QnVpbGRlcigpOworRG9jdW1lbnQgZG9jdW1lbnQgPSBidWlsZGVyLnBhcnNlKG5ldyBGaWxlKCIvd2lkZ2V0cy54bWwiKSk7CisKK1hQYXRoIHhwYXRoID0gWFBhdGhGYWN0b3J5Lm5ld0luc3RhbmNlKCkubmV3WFBhdGgoKTsKK1N0cmluZyBleHByZXNzaW9uID0gIi93aWRnZXRzL3dpZGdldCI7CitOb2RlIHdpZGdldE5vZGUgPSAoTm9kZSkgeHBhdGguZXZhbHVhdGUoZXhwcmVzc2lvbiwgZG9jdW1lbnQsIFhQYXRoQ29uc3RhbnRzLk5PREUpOworPC9wcmU+CisKKzxwPldpdGggYSByZWZlcmVuY2UgdG8gdGhlIDxjb2RlPiZsdDt3aWRnZXQmZ3Q7PC9jb2RlPiBlbGVtZW50LCBhCityZWxhdGl2ZSBYUGF0aCBleHByZXNzaW9uIGNhbiBub3cgd3JpdHRlbiB0byBzZWxlY3QgdGhlCis8Y29kZT4mbHQ7bWFudWZhY3R1cmVyJmd0OzwvY29kZT4gY2hpbGQgZWxlbWVudDo8L3A+CisKKzxwcmU+CitYUGF0aCB4cGF0aCA9IFhQYXRoRmFjdG9yeS5uZXdJbnN0YW5jZSgpLm5ld1hQYXRoKCk7Cis8c3Ryb25nPlN0cmluZyBleHByZXNzaW9uID0gIm1hbnVmYWN0dXJlciI7PC9zdHJvbmc+CitOb2RlIG1hbnVmYWN0dXJlck5vZGUgPSAoTm9kZSkgeHBhdGguZXZhbHVhdGUoZXhwcmVzc2lvbiwgPHN0cm9uZz53aWRnZXROb2RlPC9zdHJvbmc+LCBYUGF0aENvbnN0YW50cy5OT0RFKTsKKzwvcHJlPgorCis8dWw+Cis8bGk+QXV0aG9yIDxhIGhyZWY9Im1haWx0bzpCZW5AZ2FsYnJhaXRocy5vcmciPkJlbiBHYWxicmFpdGg8L2E+PC9saT4KKzxsaT5BdXRob3IgPGEgaHJlZj0ibWFpbHRvOk5vcm1hbi5XYWxzaEBTdW4uY29tIj5Ob3JtYW4gV2Fsc2g8L2E+PC9saT4KKzxsaT5BdXRob3IgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPjwvbGk+Cis8bGk+U2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoIj5YTUwgUGF0aCBMYW5ndWFnZSAoWFBhdGgpIFZlcnNpb24gMS4wPC9hPjwvbGk+Cis8bGk+U2luY2UgMS41PC9saT4KKzwvdWw+CQkKKzwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2ljdS9Db2xsYXRpb25FbGVtZW50SXRlcmF0b3JJQ1UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2ljdS9Db2xsYXRpb25FbGVtZW50SXRlcmF0b3JJQ1UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNWNhYTBiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaWN1L0NvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcklDVS5qYXZhCkBAIC0wLDAgKzEsMjEzIEBACisvKioKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyogQ29weXJpZ2h0IChDKSAxOTk2LTIwMDUsIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kICAgICoKKyogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyoKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyovCisKK3BhY2thZ2UgbGliY29yZS5pY3U7CisKK2ltcG9ydCBqYXZhLnRleHQuQ2hhcmFjdGVySXRlcmF0b3I7CisKKy8qKgorKiBDb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciBKTkkgd3JhcHBlci4KKyogSXRlcmF0ZXMgb3ZlciB0aGUgY29sbGF0aW9uIGVsZW1lbnRzIG9mIGEgZGF0YSBzdHJpbmcuCisqIFRoZSBpdGVyYXRvciBzdXBwb3J0cyBib3RoIGZvcndhcmQgYW5kIGJhY2t3YXJkcyBmdWxsIGl0ZXJhdGlvbiwgaWUgaWYKKyogYmFja3dhcmRzIGl0ZXJhdGlvbiBpcyBwZXJmb3JtZWQgaW4gdGhlIG1pZHN0IG9mIGEgZm9yd2FyZCBpdGVyYXRpb24sIHRoZQorKiByZXN1bHQgaXMgdW5kZWZpbmVkLgorKiBUbyBwZXJmb3JtIGEgYmFja3dhcmRzIGl0ZXJhdGlvbiBpbiB0aGUgbWlkc3Qgb2YgYSBmb3J3YXJkIGl0ZXJhdGlvbiwKKyogcmVzZXQoKSBoYXMgdG8gYmUgY2FsbGVkLgorKiBUaGlzIHdpbGwgc2hpZnQgdGhlIHBvc2l0aW9uIHRvIGVpdGhlciB0aGUgc3RhcnQgb3IgdGhlIGxhc3QgY2hhcmFjdGVyIGluIHRoZQorKiBkYXRhIHN0cmluZyBkZXBlbmRpbmcgb24gd2hldGhlciBuZXh0KCkgaXMgY2FsbGVkIG9yIHByZXZpb3VzKCkuCisqIDxwcmU+CisqICAgUnVsZUJhc2VkQ29sbGF0b3IgY29sbCA9IENvbGxhdG9yLmdldEluc3RhbmNlKCk7CisqICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGl0ZXJhdG9yID0gY29sbC5nZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoImFiYyIpOworKiAgIGludCBjZSA9IDA7CisqICAgd2hpbGUgKGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKKyogICAgIGNlID0gaXRlcmF0b3IubmV4dCgpOworKiAgIH0KKyogICBpdGVyYXRvci5yZXNldCgpOworKiAgIHdoaWxlIChjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CisqICAgICBjZSA9IGl0ZXJhdG9yLnByZXZpb3VzKCk7CisqICAgfQorKiA8L3ByZT4KKyogQGF1dGhvciBzeW4gd2VlIHF1ZWsKKyogQHN0YWJsZSBJQ1UgMi40CisqLworcHVibGljIGZpbmFsIGNsYXNzIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcklDVSB7CisgICAgLy8gcHVibGljIGRhdGEgbWVtYmVyIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIC8qKgorICAgICAqIEBzdGFibGUgSUNVIDIuNAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5VTExPUkRFUiA9IDB4RkZGRkZGRkY7CisKKyAgICAvLyBwdWJsaWMgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgLyoqCisgICAgICogUmVzZXQgdGhlIGNvbGxhdGlvbiBlbGVtZW50cyB0byB0aGVpciBpbml0aWFsIHN0YXRlLgorICAgICAqIFRoaXMgd2lsbCBtb3ZlIHRoZSAnY3Vyc29yJyB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSB0ZXh0LgorICAgICAqIEBzdGFibGUgSUNVIDIuNAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgICAgICBOYXRpdmVDb2xsYXRpb24ucmVzZXQoYWRkcmVzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBvcmRlcmluZyBwcmlvcml0eSBvZiB0aGUgbmV4dCBjb2xsYXRpb24gZWxlbWVudCBpbiB0aGUgdGV4dC4KKyAgICAgKiBBIHNpbmdsZSBjaGFyYWN0ZXIgbWF5IGNvbnRhaW4gbW9yZSB0aGFuIG9uZSBjb2xsYXRpb24gZWxlbWVudC4KKyAgICAgKiBAcmV0dXJuIG5leHQgY29sbGF0aW9uIGVsZW1lbnRzIG9yZGVyaW5nLCBvciBOVUxMT1JERVIgaWYgdGhlIGVuZCBvZiB0aGUKKyAgICAgKiAgICAgICAgIHRleHQgaXMgcmVhY2hlZC4KKyAgICAgKiBAc3RhYmxlIElDVSAyLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IG5leHQoKSB7CisgICAgICAgIHJldHVybiBOYXRpdmVDb2xsYXRpb24ubmV4dChhZGRyZXNzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBwcmV2aW91cyBjb2xsYXRpb24gZWxlbWVudCBpbiB0aGUgdGV4dC4KKyAgICAgKiBBIHNpbmdsZSBjaGFyYWN0ZXIgbWF5IGNvbnRhaW4gbW9yZSB0aGFuIG9uZSBjb2xsYXRpb24gZWxlbWVudC4KKyAgICAgKiBAcmV0dXJuIHByZXZpb3VzIGNvbGxhdGlvbiBlbGVtZW50IG9yZGVyaW5nLCBvciBOVUxMT1JERVIgaWYgdGhlIGVuZCBvZgorICAgICAqICAgICAgICAgdGhlIHRleHQgaXMgcmVhY2hlZC4KKyAgICAgKiBAc3RhYmxlIElDVSAyLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHByZXZpb3VzKCkgeworICAgICAgICByZXR1cm4gTmF0aXZlQ29sbGF0aW9uLnByZXZpb3VzKGFkZHJlc3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZXMgdGhhdCBlbmQgd2l0aCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgY29tcGFyaXNvbiBvcmRlci4KKyAgICAgKiBAcGFyYW0gb3JkZXIgY29sbGF0aW9uIG9yZGVyIHJldHVybmVkIGJ5IHByZXZpb3VzIG9yIG5leHQuCisgICAgICogQHJldHVybiBtYXhpbXVtIHNpemUgb2YgdGhlIGV4cGFuc2lvbiBzZXF1ZW5jZXMgZW5kaW5nIHdpdGggdGhlIGNvbGxhdGlvbgorICAgICAqICAgICAgICAgICAgICBlbGVtZW50IG9yIDEgaWYgY29sbGF0aW9uIGVsZW1lbnQgZG9lcyBub3Qgb2NjdXIgYXQgdGhlIGVuZCBvZgorICAgICAqICAgICAgICAgICAgICBhbnkgZXhwYW5zaW9uIHNlcXVlbmNlCisgICAgICogQHN0YWJsZSBJQ1UgMi40CisgICAgICovCisgICAgcHVibGljIGludCBnZXRNYXhFeHBhbnNpb24oaW50IG9yZGVyKSB7CisgICAgICAgIHJldHVybiBOYXRpdmVDb2xsYXRpb24uZ2V0TWF4RXhwYW5zaW9uKGFkZHJlc3MsIG9yZGVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHRleHQgY29udGFpbmluZyB0aGUgY29sbGF0aW9uIGVsZW1lbnRzLgorICAgICAqIEBwYXJhbSBzb3VyY2UgdGV4dCBjb250YWluaW5nIHRoZSBjb2xsYXRpb24gZWxlbWVudHMuCisgICAgICogQHN0YWJsZSBJQ1UgMi40CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VGV4dChTdHJpbmcgc291cmNlKSB7CisgICAgICAgIE5hdGl2ZUNvbGxhdGlvbi5zZXRUZXh0KGFkZHJlc3MsIHNvdXJjZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGV4dChDaGFyYWN0ZXJJdGVyYXRvciBzb3VyY2UpIHsKKyAgICAgICAgTmF0aXZlQ29sbGF0aW9uLnNldFRleHQoYWRkcmVzcywgc291cmNlLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgb2Zmc2V0IG9mIHRoZSBjdXJyZW50IHNvdXJjZSBjaGFyYWN0ZXIuCisgICAgICogVGhpcyBpcyBhbiBvZmZzZXQgaW50byB0aGUgdGV4dCBvZiB0aGUgY2hhcmFjdGVyIGNvbnRhaW5pbmcgdGhlIGN1cnJlbnQKKyAgICAgKiBjb2xsYXRpb24gZWxlbWVudHMuCisgICAgICogQHJldHVybiBvZmZzZXQgb2YgdGhlIGN1cnJlbnQgc291cmNlIGNoYXJhY3Rlci4KKyAgICAgKiBAc3RhYmxlIElDVSAyLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE9mZnNldCgpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUNvbGxhdGlvbi5nZXRPZmZzZXQoYWRkcmVzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBvZmZzZXQgb2YgdGhlIGN1cnJlbnQgc291cmNlIGNoYXJhY3Rlci4KKyAgICAgKiBUaGlzIGlzIGFuIG9mZnNldCBpbnRvIHRoZSB0ZXh0IG9mIHRoZSBjaGFyYWN0ZXIgdG8gYmUgcHJvY2Vzc2VkLgorICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIGRlc2lyZWQgY2hhcmFjdGVyIG9mZnNldC4KKyAgICAgKiBAc3RhYmxlIElDVSAyLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRPZmZzZXQoaW50IG9mZnNldCkgeworICAgICAgICBOYXRpdmVDb2xsYXRpb24uc2V0T2Zmc2V0KGFkZHJlc3MsIG9mZnNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcHJpbWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KKyAgICAgKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgorICAgICAqIEByZXR1cm4gdGhlIHByaW1hcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCisgICAgICogQHN0YWJsZSBJQ1UgMi40CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgcHJpbWFyeU9yZGVyKGludCBvcmRlcikgeworICAgICAgICByZXR1cm4gKChvcmRlciAmIFBSSU1BUllfT1JERVJfTUFTS18pID4+IFBSSU1BUllfT1JERVJfU0hJRlRfKSAmCisgICAgICAgICAgICAgICAgVU5TSUdORURfMTZfQklUX01BU0tfOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNlY29uZGFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KKyAgICAgKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgorICAgICAqIEByZXR1cm4gdGhlIHNlY29uZGFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KKyAgICAgKiBAc3RhYmxlIElDVSAyLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBzZWNvbmRhcnlPcmRlcihpbnQgb3JkZXIpIHsKKyAgICAgICAgcmV0dXJuIChvcmRlciAmIFNFQ09OREFSWV9PUkRFUl9NQVNLXykgPj4gU0VDT05EQVJZX09SREVSX1NISUZUXzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSB0ZXJ0aWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KKyAgICAgKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgorICAgICAqIEByZXR1cm4gdGhlIHRlcnRpYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgorICAgICAqIEBzdGFibGUgSUNVIDIuNAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHRlcnRpYXJ5T3JkZXIoaW50IG9yZGVyKSB7CisgICAgICAgIHJldHVybiBvcmRlciAmIFRFUlRJQVJZX09SREVSX01BU0tfOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9ySUNVIGdldEluc3RhbmNlKGludCBjb2xsYXRvckFkZHJlc3MsIFN0cmluZyBzb3VyY2UpIHsKKyAgICAgICAgaW50IGl0ZXJhdG9yQWRkcmVzcyA9IE5hdGl2ZUNvbGxhdGlvbi5nZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29sbGF0b3JBZGRyZXNzLCBzb3VyY2UpOworICAgICAgICByZXR1cm4gbmV3IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcklDVShpdGVyYXRvckFkZHJlc3MpOworICAgIH0KKworICAgIHByaXZhdGUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9ySUNVKGludCBhZGRyZXNzKSB7CisgICAgICAgIHRoaXMuYWRkcmVzcyA9IGFkZHJlc3M7CisgICAgfQorCisgICAgLy8gcHJvdGVjdGVkIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIC8qKgorICAgICAqIEdhcmJhZ2UgY29sbGVjdGlvbi4KKyAgICAgKiBDbG9zZSBDIGNvbGxhdG9yIGFuZCByZWNsYWltIG1lbW9yeS4KKyAgICAgKiBAc3RhYmxlIElDVSAyLjQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNvbGxhdGlvbi5jbG9zZUVsZW1lbnRzKGFkZHJlc3MpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc3VwZXIuZmluYWxpemUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIHByaXZhdGUgZGF0YSBtZW1iZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICAvKioKKyAgICAgKiBDIGNvbGxhdG9yCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgYWRkcmVzczsKKworICAgIC8qKgorICAgICAqIElDVSBjb25zdGFudCBwcmltYXJ5IG9yZGVyIG1hc2sgZm9yIGNvbGxhdGlvbiBlbGVtZW50cworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBQUklNQVJZX09SREVSX01BU0tfID0gMHhmZmZmMDAwMDsKKyAgICAvKioKKyAgICAgKiBJQ1UgY29uc3RhbnQgc2Vjb25kYXJ5IG9yZGVyIG1hc2sgZm9yIGNvbGxhdGlvbiBlbGVtZW50cworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTRUNPTkRBUllfT1JERVJfTUFTS18gPSAweDAwMDBmZjAwOworICAgIC8qKgorICAgICAqIElDVSBjb25zdGFudCB0ZXJ0aWFyeSBvcmRlciBtYXNrIGZvciBjb2xsYXRpb24gZWxlbWVudHMKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVEVSVElBUllfT1JERVJfTUFTS18gPSAweDAwMDAwMGZmOworICAgIC8qKgorICAgICAqIElDVSBjb25zdGFudCBwcmltYXJ5IG9yZGVyIHNoaWZ0IGZvciBjb2xsYXRpb24gZWxlbWVudHMKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUFJJTUFSWV9PUkRFUl9TSElGVF8gPSAxNjsKKyAgICAvKioKKyAgICAgKiBJQ1UgY29uc3RhbnQgc2Vjb25kYXJ5IG9yZGVyIHNoaWZ0IGZvciBjb2xsYXRpb24gZWxlbWVudHMKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0VDT05EQVJZX09SREVSX1NISUZUXyA9IDg7CisgICAgLyoqCisgICAgICogVW5zaWduZWQgMTYgYml0IG1hc2sKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5TSUdORURfMTZfQklUX01BU0tfID0gMHgwMDAwRkZGRjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2ljdS9Db2xsYXRpb25LZXlJQ1UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2ljdS9Db2xsYXRpb25LZXlJQ1UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MTRkODQxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaWN1L0NvbGxhdGlvbktleUlDVS5qYXZhCkBAIC0wLDAgKzEsMTE3IEBACisvKioKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyogQ29weXJpZ2h0IChDKSAxOTk2LTIwMDUsIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kICAgICoKKyogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyoKKyoKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyovCisKK3BhY2thZ2UgbGliY29yZS5pY3U7CisKK2ltcG9ydCBqYXZhLnRleHQuQ29sbGF0aW9uS2V5OworCisvKioKKyAqIEEgY29uY3JldGUgaW1wbGVtZW50YXRpb24gb2YgdGhlIGFic3RyYWN0IGphdmEudGV4dC5Db2xsYXRpb25LZXkuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBDb2xsYXRpb25LZXlJQ1UgZXh0ZW5kcyBDb2xsYXRpb25LZXkgeworICAgIC8qKgorICAgICAqIFRoZSBrZXkuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gYnl0ZXM7CisKKyAgICAvKioKKyAgICAgKiBDYWNoZWQgaGFzaCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBoYXNoQ29kZTsKKworICAgIENvbGxhdGlvbktleUlDVShTdHJpbmcgc291cmNlLCBieXRlW10gYnl0ZXMpIHsKKyAgICAgICAgc3VwZXIoc291cmNlKTsKKyAgICAgICAgdGhpcy5ieXRlcyA9IGJ5dGVzOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGNvbXBhcmVUbyhDb2xsYXRpb25LZXkgb3RoZXIpIHsKKyAgICAgICAgLy8gR2V0IHRoZSBieXRlcyBmcm9tIHRoZSBvdGhlciBjb2xsYXRpb24ga2V5LgorICAgICAgICBmaW5hbCBieXRlW10gcmhzQnl0ZXM7CisgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIENvbGxhdGlvbktleUlDVSkgeworICAgICAgICAgICAgcmhzQnl0ZXMgPSAoKENvbGxhdGlvbktleUlDVSkgb3RoZXIpLmJ5dGVzOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmhzQnl0ZXMgPSBvdGhlci50b0J5dGVBcnJheSgpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGJ5dGVzID09IG51bGwgfHwgYnl0ZXMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIGlmIChyaHNCeXRlcyA9PSBudWxsIHx8IHJoc0J5dGVzLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAocmhzQnl0ZXMgPT0gbnVsbCB8fCByaHNCeXRlcy5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaW50IGNvdW50ID0gTWF0aC5taW4oYnl0ZXMubGVuZ3RoLCByaHNCeXRlcy5sZW5ndGgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyArK2kpIHsKKyAgICAgICAgICAgIGludCBzID0gYnl0ZXNbaV0gJiAweGZmOworICAgICAgICAgICAgaW50IHQgPSByaHNCeXRlc1tpXSAmIDB4ZmY7CisgICAgICAgICAgICBpZiAocyA8IHQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocyA+IHQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoYnl0ZXMubGVuZ3RoIDwgcmhzQnl0ZXMubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJ5dGVzLmxlbmd0aCA+IHJoc0J5dGVzLmxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmIChvYmplY3QgPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCEob2JqZWN0IGluc3RhbmNlb2YgQ29sbGF0aW9uS2V5KSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb21wYXJlVG8oKENvbGxhdGlvbktleSkgb2JqZWN0KSA9PSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBoYXNoIGNvZGUgZm9yIHRoaXMgQ29sbGF0aW9uS2V5LgorICAgICAqIENvbXB1dGUgdGhlIGhhc2ggYnkgaXRlcmF0aW5nIHNwYXJzZWx5IG92ZXIgYWJvdXQgMzIgKHVwIHRvIDYzKSBieXRlcworICAgICAqIHNwYWNlZCBldmVubHkgdGhyb3VnaCB0aGUgc3RyaW5nLiAgRm9yIGVhY2ggYnl0ZSwgbXVsdGlwbHkgdGhlIHByZXZpb3VzCisgICAgICogaGFzaCB2YWx1ZSBieSBhIHByaW1lIG51bWJlciBhbmQgYWRkIHRoZSBuZXcgYnl0ZSBpbiwgbGlrZSBhIGxpbmVhcgorICAgICAqIGNvbmdydWVudGlhbCByYW5kb20gbnVtYmVyIGdlbmVyYXRvciwgcHJvZHVjaW5nIGEgcHNldWRvLXJhbmRvbQorICAgICAqIGRldGVybWluaXN0aWMgdmFsdWUgd2VsbCBkaXN0cmlidXRlZCBvdmVyIHRoZSBvdXRwdXQgcmFuZ2UuCisgICAgICogQHJldHVybiBoYXNoIHZhbHVlIG9mIGNvbGxhdGlvbiBrZXkuIEhhc2ggdmFsdWUgaXMgbmV2ZXIgMC4KKyAgICAgKiBAc3RhYmxlIElDVSAyLjQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaWYgKGhhc2hDb2RlID09IDApIHsKKyAgICAgICAgICAgIGlmIChieXRlcyAhPSBudWxsICYmIGJ5dGVzLmxlbmd0aCAhPSAwKSB7CisgICAgICAgICAgICAgICAgaW50IGxlbiA9IGJ5dGVzLmxlbmd0aDsKKyAgICAgICAgICAgICAgICBpbnQgaW5jID0gKChsZW4gLSAzMikgLyAzMikgKyAxOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOykgeworICAgICAgICAgICAgICAgICAgICBoYXNoQ29kZSA9IChoYXNoQ29kZSAqIDM3KSArIGJ5dGVzW2ldOworICAgICAgICAgICAgICAgICAgICBpICs9IGluYzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaGFzaENvZGUgPT0gMCkgeworICAgICAgICAgICAgICAgIGhhc2hDb2RlID0gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzaENvZGU7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBieXRlW10gdG9CeXRlQXJyYXkoKSB7CisgICAgICAgIGlmIChieXRlcyA9PSBudWxsIHx8IGJ5dGVzLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnl0ZXMuY2xvbmUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvRXJyb3JDb2RlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvRXJyb3JDb2RlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzA5M2FmMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2ljdS9FcnJvckNvZGUuamF2YQpAQCAtMCwwICsxLDcxIEBACisvKioKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorKiBDb3B5cmlnaHQgKEMpIDE5OTYtMjAwNSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgICAqCisqIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorKgorKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisqLworCitwYWNrYWdlIGxpYmNvcmUuaWN1OworCisvKioKKyAqIEVycm9yIGV4Y2VwdGlvbiBjbGFzcyBtYXBwaW5nIElDVSBlcnJvciBjb2RlcyBvZiB0aGUgZW51bSBVRXJyb3JDb2RlCisgKiBAYXV0aG9yIHN5biB3ZWUgcXVlaworKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBFcnJvckNvZGUgZXh0ZW5kcyBFeGNlcHRpb24geworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0ZhaWx1cmUoaW50IGVycm9yKSB7CisgICAgICAgIHJldHVybiBlcnJvciA+IFVfWkVST19FUlJPUiAmJiBlcnJvciA8IFVfRVJST1JfTElNSVQ7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBSdW50aW1lRXhjZXB0aW9uIHRocm93RXhjZXB0aW9uKGludCBlcnJvcikgeworICAgICAgICBpZiAoZXJyb3IgPD0gVV9aRVJPX0VSUk9SICYmIGVycm9yID49IFVfRVJST1JfTElNSVQpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZXJyb3IpIHsKKyAgICAgICAgY2FzZSBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1I6CisgICAgICAgICAgICByZXR1cm4gbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihFUlJPUl9OQU1FU1tlcnJvcl0pOworICAgICAgICBjYXNlIFVfSU5ERVhfT1VUT0ZCT1VORFNfRVJST1I6CisgICAgICAgIGNhc2UgVV9CVUZGRVJfT1ZFUkZMT1dfRVJST1I6CisgICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihFUlJPUl9OQU1FU1tlcnJvcl0pOworICAgICAgICBjYXNlIFVfVU5TVVBQT1JURURfRVJST1I6CisgICAgICAgICAgICByZXR1cm4gbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKEVSUk9SX05BTUVTW2Vycm9yXSk7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oRVJST1JfTkFNRVNbZXJyb3JdKTsKKyAgICB9CisKKyAgICAvLyBUaGUgZXJyb3JzIG5lZWRlZCBieSBvdXIgQ2hhcnNldERlY29kZXJJQ1UvQ2hhcnNldEVuY29kZXJJQ1UuCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVV9aRVJPX0VSUk9SID0gMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SID0gMTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVV9JTkRFWF9PVVRPRkJPVU5EU19FUlJPUiA9IDg7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVV9JTlZBTElEX0NIQVJfRk9VTkQgPSAxMDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVX1RSVU5DQVRFRF9DSEFSX0ZPVU5EID0gMTE7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVV9JTExFR0FMX0NIQVJfRk9VTkQgPSAxMjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVX0JVRkZFUl9PVkVSRkxPV19FUlJPUiA9IDE1OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVX1VOU1VQUE9SVEVEX0VSUk9SID0gMTY7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVfRVJST1JfTElNSVQgPSAyMTsKKworICAgIC8vIFRPRE86IHRoaXMgbGlzdCBpcyBpbmNvbXBsZXRlOyBnZXQgdGhlc2UgZnJvbSBuYXRpdmUgY29kZSEKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfTkFNRVNbXSA9IHsKKyAgICAgICAgIlVfWkVST19FUlJPUiIsCisgICAgICAgICJVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1IiLAorICAgICAgICAiVV9NSVNTSU5HX1JFU09VUkNFX0VSUk9SIiwKKyAgICAgICAgIlVfSU5WQUxJRF9GT1JNQVRfRVJST1IiLAorICAgICAgICAiVV9GSUxFX0FDQ0VTU19FUlJPUiIsCisgICAgICAgICJVX0lOVEVSTkFMX1BST0dSQU1fRVJST1IiLAorICAgICAgICAiVV9NRVNTQUdFX1BBUlNFX0VSUk9SIiwKKyAgICAgICAgIlVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1IiLAorICAgICAgICAiVV9JTkRFWF9PVVRPRkJPVU5EU19FUlJPUiIsCisgICAgICAgICJVX1BBUlNFX0VSUk9SIiwKKyAgICAgICAgIlVfSU5WQUxJRF9DSEFSX0ZPVU5EIiwKKyAgICAgICAgIlVfVFJVTkNBVEVEX0NIQVJfRk9VTkQiLAorICAgICAgICAiVV9JTExFR0FMX0NIQVJfRk9VTkQiLAorICAgICAgICAiVV9JTlZBTElEX1RBQkxFX0ZPUk1BVCIsCisgICAgICAgICJVX0lOVkFMSURfVEFCTEVfRklMRSIsCisgICAgICAgICJVX0JVRkZFUl9PVkVSRkxPV19FUlJPUiIsCisgICAgICAgICJVX1VOU1VQUE9SVEVEX0VSUk9SIiwKKyAgICAgICAgIlVfUkVTT1VSQ0VfVFlQRV9NSVNNQVRDSCIsCisgICAgICAgICJVX0lMTEVHQUxfRVNDQVBFX1NFUVVFTkNFIiwKKyAgICAgICAgIlVfVU5TVVBQT1JURURfRVNDQVBFX1NFUVVFTkNFIgorICAgIH07Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvSUNVLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvSUNVLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2YzMzAzZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2ljdS9JQ1UuamF2YQpAQCAtMCwwICsxLDE3NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pY3U7CisKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCisvKioKKyAqIE1ha2VzIElDVSBkYXRhIGFjY2Vzc2libGUgdG8gSmF2YS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIElDVSB7CisgICAgLyoqCisgICAgICogQ2FjaGUgZm9yIElTTyBsYW5ndWFnZSBuYW1lcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBpc29MYW5ndWFnZXM7CisKKyAgICAvKioKKyAgICAgKiBDYWNoZSBmb3IgSVNPIGNvdW50cnkgbmFtZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gaXNvQ291bnRyaWVzOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBJU08gbGFuZ3VhZ2UgbmFtZXMgKHR3by1sZXR0ZXIgY29kZXMpLCBmZXRjaGVkIGVpdGhlcgorICAgICAqIGZyb20gSUNVJ3MgZGF0YWJhc2Ugb3IgZnJvbSBvdXIgbWVtb3J5IGNhY2hlLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmdbXSBnZXRJU09MYW5ndWFnZXMoKSB7CisgICAgICAgIGlmIChpc29MYW5ndWFnZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgaXNvTGFuZ3VhZ2VzID0gZ2V0SVNPTGFuZ3VhZ2VzTmF0aXZlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlzb0xhbmd1YWdlcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgSVNPIGNvdW50cnkgbmFtZXMgKHR3by1sZXR0ZXIgY29kZXMpLCBmZXRjaGVkIGVpdGhlcgorICAgICAqIGZyb20gSUNVJ3MgZGF0YWJhc2Ugb3IgZnJvbSBvdXIgbWVtb3J5IGNhY2hlLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmdbXSBnZXRJU09Db3VudHJpZXMoKSB7CisgICAgICAgIGlmIChpc29Db3VudHJpZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgaXNvQ291bnRyaWVzID0gZ2V0SVNPQ291bnRyaWVzTmF0aXZlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlzb0NvdW50cmllcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFwcHJvcHJpYXRlIHtAY29kZSBMb2NhbGV9IGdpdmVuIGEge0Bjb2RlIFN0cmluZ30gb2YgdGhlIGZvcm0gcmV0dXJuZWQKKyAgICAgKiBieSB7QGNvZGUgdG9TdHJpbmd9LiBUaGlzIGlzIHZlcnkgbGVuaWVudCwgYW5kIGRvZXNuJ3QgY2FyZSB3aGF0J3MgYmV0d2VlbiB0aGUgdW5kZXJzY29yZXM6CisgICAgICogdGhpcyBtZXRob2QgY2FuIHBhcnNlIHN0cmluZ3MgdGhhdCB7QGNvZGUgTG9jYWxlLnRvU3RyaW5nfSB3b24ndCBwcm9kdWNlLgorICAgICAqIFVzZWQgdG8gcmVtb3ZlIGR1cGxpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTG9jYWxlIGxvY2FsZUZyb21TdHJpbmcoU3RyaW5nIGxvY2FsZU5hbWUpIHsKKyAgICAgICAgaW50IGZpcnN0ID0gbG9jYWxlTmFtZS5pbmRleE9mKCdfJyk7CisgICAgICAgIGludCBzZWNvbmQgPSBsb2NhbGVOYW1lLmluZGV4T2YoJ18nLCBmaXJzdCArIDEpOworICAgICAgICBpZiAoZmlyc3QgPT0gLTEpIHsKKyAgICAgICAgICAgIC8vIExhbmd1YWdlIG9ubHkgKCJqYSIpLgorICAgICAgICAgICAgcmV0dXJuIG5ldyBMb2NhbGUobG9jYWxlTmFtZSk7CisgICAgICAgIH0gZWxzZSBpZiAoc2Vjb25kID09IC0xKSB7CisgICAgICAgICAgICAvLyBMYW5ndWFnZSBhbmQgY291bnRyeSAoImphX0pQIikuCisgICAgICAgICAgICByZXR1cm4gbmV3IExvY2FsZShsb2NhbGVOYW1lLnN1YnN0cmluZygwLCBmaXJzdCksIGxvY2FsZU5hbWUuc3Vic3RyaW5nKGZpcnN0ICsgMSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gTGFuZ3VhZ2UgYW5kIGNvdW50cnkgYW5kIHZhcmlhbnQgKCJqYV9KUF9UUkFESVRJT05BTCIpLgorICAgICAgICAgICAgcmV0dXJuIG5ldyBMb2NhbGUobG9jYWxlTmFtZS5zdWJzdHJpbmcoMCwgZmlyc3QpLCBsb2NhbGVOYW1lLnN1YnN0cmluZyhmaXJzdCArIDEsIHNlY29uZCksIGxvY2FsZU5hbWUuc3Vic3RyaW5nKHNlY29uZCArIDEpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgTG9jYWxlW10gbG9jYWxlc0Zyb21TdHJpbmdzKFN0cmluZ1tdIGxvY2FsZU5hbWVzKSB7CisgICAgICAgIC8vIFdlIG5lZWQgdG8gcmVtb3ZlIGR1cGxpY2F0ZXMgY2F1c2VkIGJ5IHRoZSBjb252ZXJzaW9uIG9mICJoZSIgdG8gIml3IiwgZXQgY2V0ZXJhLgorICAgICAgICAvLyBKYXZhIG5lZWRzIHRoZSBvYnNvbGV0ZSBjb2RlLCBJQ1UgbmVlZHMgdGhlIG1vZGVybiBjb2RlLCBidXQgd2UgbGV0IElDVSBrbm93IGFib3V0CisgICAgICAgIC8vIGJvdGggc28gdGhhdCB3ZSBuZXZlciBuZWVkIHRvIGNvbnZlcnQgYmFjayB3aGVuIHRhbGtpbmcgdG8gaXQuCisgICAgICAgIExpbmtlZEhhc2hTZXQ8TG9jYWxlPiBzZXQgPSBuZXcgTGlua2VkSGFzaFNldDxMb2NhbGU+KCk7CisgICAgICAgIGZvciAoU3RyaW5nIGxvY2FsZU5hbWUgOiBsb2NhbGVOYW1lcykgeworICAgICAgICAgICAgc2V0LmFkZChsb2NhbGVGcm9tU3RyaW5nKGxvY2FsZU5hbWUpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2V0LnRvQXJyYXkobmV3IExvY2FsZVtzZXQuc2l6ZSgpXSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgTG9jYWxlW10gYXZhaWxhYmxlTG9jYWxlc0NhY2hlOworICAgIHB1YmxpYyBzdGF0aWMgTG9jYWxlW10gZ2V0QXZhaWxhYmxlTG9jYWxlcygpIHsKKyAgICAgICAgaWYgKGF2YWlsYWJsZUxvY2FsZXNDYWNoZSA9PSBudWxsKSB7CisgICAgICAgICAgICBhdmFpbGFibGVMb2NhbGVzQ2FjaGUgPSBsb2NhbGVzRnJvbVN0cmluZ3MoZ2V0QXZhaWxhYmxlTG9jYWxlc05hdGl2ZSgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYXZhaWxhYmxlTG9jYWxlc0NhY2hlLmNsb25lKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBMb2NhbGVbXSBnZXRBdmFpbGFibGVCcmVha0l0ZXJhdG9yTG9jYWxlcygpIHsKKyAgICAgICAgcmV0dXJuIGxvY2FsZXNGcm9tU3RyaW5ncyhnZXRBdmFpbGFibGVCcmVha0l0ZXJhdG9yTG9jYWxlc05hdGl2ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIExvY2FsZVtdIGdldEF2YWlsYWJsZUNhbGVuZGFyTG9jYWxlcygpIHsKKyAgICAgICAgcmV0dXJuIGxvY2FsZXNGcm9tU3RyaW5ncyhnZXRBdmFpbGFibGVDYWxlbmRhckxvY2FsZXNOYXRpdmUoKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBMb2NhbGVbXSBnZXRBdmFpbGFibGVDb2xsYXRvckxvY2FsZXMoKSB7CisgICAgICAgIHJldHVybiBsb2NhbGVzRnJvbVN0cmluZ3MoZ2V0QXZhaWxhYmxlQ29sbGF0b3JMb2NhbGVzTmF0aXZlKCkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgTG9jYWxlW10gZ2V0QXZhaWxhYmxlRGF0ZUZvcm1hdExvY2FsZXMoKSB7CisgICAgICAgIHJldHVybiBsb2NhbGVzRnJvbVN0cmluZ3MoZ2V0QXZhaWxhYmxlRGF0ZUZvcm1hdExvY2FsZXNOYXRpdmUoKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBMb2NhbGVbXSBnZXRBdmFpbGFibGVEYXRlRm9ybWF0U3ltYm9sc0xvY2FsZXMoKSB7CisgICAgICAgIHJldHVybiBnZXRBdmFpbGFibGVEYXRlRm9ybWF0TG9jYWxlcygpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgTG9jYWxlW10gZ2V0QXZhaWxhYmxlRGVjaW1hbEZvcm1hdFN5bWJvbHNMb2NhbGVzKCkgeworICAgICAgICByZXR1cm4gZ2V0QXZhaWxhYmxlTnVtYmVyRm9ybWF0TG9jYWxlcygpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgTG9jYWxlW10gZ2V0QXZhaWxhYmxlTnVtYmVyRm9ybWF0TG9jYWxlcygpIHsKKyAgICAgICAgcmV0dXJuIGxvY2FsZXNGcm9tU3RyaW5ncyhnZXRBdmFpbGFibGVOdW1iZXJGb3JtYXRMb2NhbGVzTmF0aXZlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIElDVSB2ZXJzaW9uIGluIHVzZS4gVGhpcyBpcyAiNC40IiBmb3IgZ2luZ2VyYnJlYWQsIGZvciBleGFtcGxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIFN0cmluZyBnZXRJY3VWZXJzaW9uKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBVbmljb2RlIHZlcnNpb24gb3VyIElDVSBzdXBwb3J0cy4gVGhpcyBpcyAiNS4yIiBmb3IgZ2luZ2VyYnJlYWQsIGZvciBleGFtcGxlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIFN0cmluZyBnZXRVbmljb2RlVmVyc2lvbigpOworCisgICAgLy8gLS0tIENhc2UgbWFwcGluZy4KKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIFN0cmluZyB0b0xvd2VyQ2FzZShTdHJpbmcgcywgU3RyaW5nIGxvY2FsZU5hbWUpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIFN0cmluZyB0b1VwcGVyQ2FzZShTdHJpbmcgcywgU3RyaW5nIGxvY2FsZU5hbWUpOworCisgICAgLy8gLS0tIE5hdGl2ZSBtZXRob2RzIGFjY2Vzc2luZyBJQ1UncyBkYXRhYmFzZS4KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBTdHJpbmdbXSBnZXRBdmFpbGFibGVCcmVha0l0ZXJhdG9yTG9jYWxlc05hdGl2ZSgpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBTdHJpbmdbXSBnZXRBdmFpbGFibGVDYWxlbmRhckxvY2FsZXNOYXRpdmUoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgU3RyaW5nW10gZ2V0QXZhaWxhYmxlQ29sbGF0b3JMb2NhbGVzTmF0aXZlKCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIFN0cmluZ1tdIGdldEF2YWlsYWJsZURhdGVGb3JtYXRMb2NhbGVzTmF0aXZlKCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIFN0cmluZ1tdIGdldEF2YWlsYWJsZUxvY2FsZXNOYXRpdmUoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgU3RyaW5nW10gZ2V0QXZhaWxhYmxlTnVtYmVyRm9ybWF0TG9jYWxlc05hdGl2ZSgpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgU3RyaW5nW10gZ2V0QXZhaWxhYmxlQ3VycmVuY3lDb2RlcygpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIFN0cmluZyBnZXRDdXJyZW5jeUNvZGUoU3RyaW5nIGNvdW50cnlDb2RlKTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBTdHJpbmcgZ2V0Q3VycmVuY3lEaXNwbGF5TmFtZShTdHJpbmcgbG9jYWxlLCBTdHJpbmcgY3VycmVuY3lDb2RlKTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgZ2V0Q3VycmVuY3lGcmFjdGlvbkRpZ2l0cyhTdHJpbmcgY3VycmVuY3lDb2RlKTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBTdHJpbmcgZ2V0Q3VycmVuY3lTeW1ib2woU3RyaW5nIGxvY2FsZSwgU3RyaW5nIGN1cnJlbmN5Q29kZSk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBTdHJpbmcgZ2V0RGlzcGxheUNvdW50cnlOYXRpdmUoU3RyaW5nIGNvdW50cnlDb2RlLCBTdHJpbmcgbG9jYWxlKTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBTdHJpbmcgZ2V0RGlzcGxheUxhbmd1YWdlTmF0aXZlKFN0cmluZyBsYW5ndWFnZUNvZGUsIFN0cmluZyBsb2NhbGUpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIFN0cmluZyBnZXREaXNwbGF5VmFyaWFudE5hdGl2ZShTdHJpbmcgdmFyaWFudENvZGUsIFN0cmluZyBsb2NhbGUpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgU3RyaW5nIGdldElTTzNDb3VudHJ5TmF0aXZlKFN0cmluZyBsb2NhbGUpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIFN0cmluZyBnZXRJU08zTGFuZ3VhZ2VOYXRpdmUoU3RyaW5nIGxvY2FsZSk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBTdHJpbmcgYWRkTGlrZWx5U3VidGFncyhTdHJpbmcgbG9jYWxlKTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBTdHJpbmcgZ2V0U2NyaXB0KFN0cmluZyBsb2NhbGUpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIFN0cmluZ1tdIGdldElTT0xhbmd1YWdlc05hdGl2ZSgpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBTdHJpbmdbXSBnZXRJU09Db3VudHJpZXNOYXRpdmUoKTsKKworICAgIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBpbml0TG9jYWxlRGF0YUltcGwoU3RyaW5nIGxvY2FsZSwgTG9jYWxlRGF0YSByZXN1bHQpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaWN1L0xvY2FsZURhdGEuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2ljdS9Mb2NhbGVEYXRhLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjY4NzMwYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2ljdS9Mb2NhbGVEYXRhLmphdmEKQEAgLTAsMCArMSwzNDcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuaWN1OworCitpbXBvcnQgamF2YS50ZXh0LkRhdGVGb3JtYXQ7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCisvKioKKyAqIFBhc3NlcyBsb2NhbGUtc3BlY2lmaWMgZnJvbSBJQ1UgbmF0aXZlIGNvZGUgdG8gSmF2YS4KKyAqIDxwPgorICogTm90ZSB0aGF0IHlvdSBzaGFyZSB0aGVzZTsgeW91IG11c3Qgbm90IGFsdGVyIGFueSBvZiB0aGUgZmllbGRzLCBub3IgdGhlaXIgYXJyYXkgZWxlbWVudHMKKyAqIGluIHRoZSBjYXNlIG9mIGFycmF5cy4gSWYgeW91IGV2ZXIgZXhwb3NlIGFueSBvZiB0aGVzZSB0aGluZ3MgdG8gdXNlciBjb2RlLCB5b3UgbXVzdCBnaXZlCisgKiB0aGVtIGEgY2xvbmUgcmF0aGVyIHRoYW4gdGhlIG9yaWdpbmFsLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTG9jYWxlRGF0YSB7CisgICAgLy8gQSBjYWNoZSBmb3IgdGhlIGxvY2FsZS1zcGVjaWZpYyBkYXRhLgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEhhc2hNYXA8U3RyaW5nLCBMb2NhbGVEYXRhPiBsb2NhbGVEYXRhQ2FjaGUgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIExvY2FsZURhdGE+KCk7CisgICAgc3RhdGljIHsKKyAgICAgICAgLy8gRW5zdXJlIHRoYXQgd2UgcHVsbCBpbiB0aGUgbG9jYWxlIGRhdGEgZm9yIHRoZSByb290IGxvY2FsZSwgZW5fVVMsIGFuZCB0aGUKKyAgICAgICAgLy8gdXNlcidzIGRlZmF1bHQgbG9jYWxlLiAoQWxsIGRldmljZXMgbXVzdCBzdXBwb3J0IHRoZSByb290IGxvY2FsZSBhbmQgZW5fVVMsCisgICAgICAgIC8vIGFuZCB0aGV5J3JlIHVzZWQgZm9yIHZhcmlvdXMgc3lzdGVtIHRoaW5ncyBsaWtlIEhUVFAgaGVhZGVycy4pIFByZS1wb3B1bGF0aW5nCisgICAgICAgIC8vIHRoZSBjYWNoZSBpcyBlc3BlY2lhbGx5IHVzZWZ1bCBvbiBBbmRyb2lkIGJlY2F1c2Ugd2UnbGwgc2hhcmUgdGhpcyB2aWEgdGhlIFp5Z290ZS4KKyAgICAgICAgZ2V0KExvY2FsZS5ST09UKTsKKyAgICAgICAgZ2V0KExvY2FsZS5VUyk7CisgICAgICAgIGdldChMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvLyBVc2VkIGJ5IENhbGVuZGFyLgorICAgIHB1YmxpYyBJbnRlZ2VyIGZpcnN0RGF5T2ZXZWVrOworICAgIHB1YmxpYyBJbnRlZ2VyIG1pbmltYWxEYXlzSW5GaXJzdFdlZWs7CisKKyAgICAvLyBVc2VkIGJ5IERhdGVGb3JtYXRTeW1ib2xzLgorICAgIHB1YmxpYyBTdHJpbmdbXSBhbVBtOworICAgIHB1YmxpYyBTdHJpbmdbXSBlcmFzOworCisgICAgcHVibGljIFN0cmluZ1tdIGxvbmdNb250aE5hbWVzOworICAgIHB1YmxpYyBTdHJpbmdbXSBzaG9ydE1vbnRoTmFtZXM7CisgICAgcHVibGljIFN0cmluZ1tdIGxvbmdTdGFuZEFsb25lTW9udGhOYW1lczsKKyAgICBwdWJsaWMgU3RyaW5nW10gc2hvcnRTdGFuZEFsb25lTW9udGhOYW1lczsKKworICAgIHB1YmxpYyBTdHJpbmdbXSBsb25nV2Vla2RheU5hbWVzOworICAgIHB1YmxpYyBTdHJpbmdbXSBzaG9ydFdlZWtkYXlOYW1lczsKKyAgICBwdWJsaWMgU3RyaW5nW10gbG9uZ1N0YW5kQWxvbmVXZWVrZGF5TmFtZXM7CisgICAgcHVibGljIFN0cmluZ1tdIHNob3J0U3RhbmRBbG9uZVdlZWtkYXlOYW1lczsKKworICAgIHB1YmxpYyBTdHJpbmcgZnVsbFRpbWVGb3JtYXQ7CisgICAgcHVibGljIFN0cmluZyBsb25nVGltZUZvcm1hdDsKKyAgICBwdWJsaWMgU3RyaW5nIG1lZGl1bVRpbWVGb3JtYXQ7CisgICAgcHVibGljIFN0cmluZyBzaG9ydFRpbWVGb3JtYXQ7CisKKyAgICBwdWJsaWMgU3RyaW5nIGZ1bGxEYXRlRm9ybWF0OworICAgIHB1YmxpYyBTdHJpbmcgbG9uZ0RhdGVGb3JtYXQ7CisgICAgcHVibGljIFN0cmluZyBtZWRpdW1EYXRlRm9ybWF0OworICAgIHB1YmxpYyBTdHJpbmcgc2hvcnREYXRlRm9ybWF0OworCisgICAgLy8gVXNlZCBieSBEZWNpbWFsRm9ybWF0U3ltYm9scy4KKyAgICBwdWJsaWMgY2hhciB6ZXJvRGlnaXQ7CisgICAgcHVibGljIGNoYXIgZGVjaW1hbFNlcGFyYXRvcjsKKyAgICBwdWJsaWMgY2hhciBncm91cGluZ1NlcGFyYXRvcjsKKyAgICBwdWJsaWMgY2hhciBwYXR0ZXJuU2VwYXJhdG9yOworICAgIHB1YmxpYyBjaGFyIHBlcmNlbnQ7CisgICAgcHVibGljIGNoYXIgcGVyTWlsbDsKKyAgICBwdWJsaWMgY2hhciBtb25ldGFyeVNlcGFyYXRvcjsKKyAgICBwdWJsaWMgY2hhciBtaW51c1NpZ247CisgICAgcHVibGljIFN0cmluZyBleHBvbmVudFNlcGFyYXRvcjsKKyAgICBwdWJsaWMgU3RyaW5nIGluZmluaXR5OworICAgIHB1YmxpYyBTdHJpbmcgTmFOOworICAgIC8vIEFsc28gdXNlZCBieSBDdXJyZW5jeS4KKyAgICBwdWJsaWMgU3RyaW5nIGN1cnJlbmN5U3ltYm9sOworICAgIHB1YmxpYyBTdHJpbmcgaW50ZXJuYXRpb25hbEN1cnJlbmN5U3ltYm9sOworCisgICAgLy8gVXNlZCBieSBEZWNpbWFsRm9ybWF0IGFuZCBOdW1iZXJGb3JtYXQuCisgICAgcHVibGljIFN0cmluZyBudW1iZXJQYXR0ZXJuOworICAgIHB1YmxpYyBTdHJpbmcgaW50ZWdlclBhdHRlcm47CisgICAgcHVibGljIFN0cmluZyBjdXJyZW5jeVBhdHRlcm47CisgICAgcHVibGljIFN0cmluZyBwZXJjZW50UGF0dGVybjsKKworICAgIHByaXZhdGUgTG9jYWxlRGF0YSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc2hhcmVkIExvY2FsZURhdGEgZm9yIHRoZSBnaXZlbiBsb2NhbGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBMb2NhbGVEYXRhIGdldChMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIGlmIChsb2NhbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgbG9jYWxlID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgbG9jYWxlTmFtZSA9IGxvY2FsZS50b1N0cmluZygpOworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2FsZURhdGFDYWNoZSkgeworICAgICAgICAgICAgTG9jYWxlRGF0YSBsb2NhbGVEYXRhID0gbG9jYWxlRGF0YUNhY2hlLmdldChsb2NhbGVOYW1lKTsKKyAgICAgICAgICAgIGlmIChsb2NhbGVEYXRhICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbG9jYWxlRGF0YTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBMb2NhbGVEYXRhIG5ld0xvY2FsZURhdGEgPSBtYWtlTG9jYWxlRGF0YShsb2NhbGUpOworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2FsZURhdGFDYWNoZSkgeworICAgICAgICAgICAgTG9jYWxlRGF0YSBsb2NhbGVEYXRhID0gbG9jYWxlRGF0YUNhY2hlLmdldChsb2NhbGVOYW1lKTsKKyAgICAgICAgICAgIGlmIChsb2NhbGVEYXRhICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbG9jYWxlRGF0YTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGxvY2FsZURhdGFDYWNoZS5wdXQobG9jYWxlTmFtZSwgbmV3TG9jYWxlRGF0YSk7CisgICAgICAgICAgICByZXR1cm4gbmV3TG9jYWxlRGF0YTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIExvY2FsZURhdGEgbWFrZUxvY2FsZURhdGEoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBTdHJpbmcgbGFuZ3VhZ2UgPSBsb2NhbGUuZ2V0TGFuZ3VhZ2UoKTsKKyAgICAgICAgU3RyaW5nIGNvdW50cnkgPSBsb2NhbGUuZ2V0Q291bnRyeSgpOworICAgICAgICBTdHJpbmcgdmFyaWFudCA9IGxvY2FsZS5nZXRWYXJpYW50KCk7CisgICAgICAgIC8vIFN0YXJ0IHdpdGggZGF0YSBmcm9tIHRoZSBwYXJlbnQgKG5leHQtbW9zdC1zcGVjaWZpYykgbG9jYWxlLi4uCisgICAgICAgIExvY2FsZURhdGEgcmVzdWx0ID0gbmV3IExvY2FsZURhdGEoKTsKKyAgICAgICAgaWYgKCF2YXJpYW50LmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmVzdWx0Lm92ZXJyaWRlV2l0aERhdGFGcm9tKGdldChuZXcgTG9jYWxlKGxhbmd1YWdlLCBjb3VudHJ5LCAiIikpKTsKKyAgICAgICAgfSBlbHNlIGlmICghY291bnRyeS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHJlc3VsdC5vdmVycmlkZVdpdGhEYXRhRnJvbShnZXQobmV3IExvY2FsZShsYW5ndWFnZSwgIiIsICIiKSkpOworICAgICAgICB9IGVsc2UgaWYgKCFsYW5ndWFnZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHJlc3VsdC5vdmVycmlkZVdpdGhEYXRhRnJvbShnZXQoTG9jYWxlLlJPT1QpKTsKKyAgICAgICAgfQorICAgICAgICAvLyBPdmVycmlkZSB3aXRoIGRhdGEgZnJvbSB0aGlzIGxvY2FsZS4KKyAgICAgICAgcmVzdWx0Lm92ZXJyaWRlV2l0aERhdGFGcm9tKGluaXRMb2NhbGVEYXRhKGxvY2FsZSkpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gIkxvY2FsZURhdGFbIiArCisgICAgICAgICAgICAgICAgImZpcnN0RGF5T2ZXZWVrPSIgKyBmaXJzdERheU9mV2VlayArICIsIiArCisgICAgICAgICAgICAgICAgIm1pbmltYWxEYXlzSW5GaXJzdFdlZWs9IiArIG1pbmltYWxEYXlzSW5GaXJzdFdlZWsgKyAiLCIgKworICAgICAgICAgICAgICAgICJhbVBtPSIgKyBBcnJheXMudG9TdHJpbmcoYW1QbSkgKyAiLCIgKworICAgICAgICAgICAgICAgICJlcmFzPSIgKyBBcnJheXMudG9TdHJpbmcoZXJhcykgKyAiLCIgKworICAgICAgICAgICAgICAgICJsb25nTW9udGhOYW1lcz0iICsgQXJyYXlzLnRvU3RyaW5nKGxvbmdNb250aE5hbWVzKSArICIsIiArCisgICAgICAgICAgICAgICAgInNob3J0TW9udGhOYW1lcz0iICsgQXJyYXlzLnRvU3RyaW5nKHNob3J0TW9udGhOYW1lcykgKyAiLCIgKworICAgICAgICAgICAgICAgICJsb25nU3RhbmRBbG9uZU1vbnRoTmFtZXM9IiArIEFycmF5cy50b1N0cmluZyhsb25nU3RhbmRBbG9uZU1vbnRoTmFtZXMpICsgIiwiICsKKyAgICAgICAgICAgICAgICAic2hvcnRTdGFuZEFsb25lTW9udGhOYW1lcz0iICsgQXJyYXlzLnRvU3RyaW5nKHNob3J0U3RhbmRBbG9uZU1vbnRoTmFtZXMpICsgIiwiICsKKyAgICAgICAgICAgICAgICAibG9uZ1dlZWtkYXlOYW1lcz0iICsgQXJyYXlzLnRvU3RyaW5nKGxvbmdXZWVrZGF5TmFtZXMpICsgIiwiICsKKyAgICAgICAgICAgICAgICAic2hvcnRXZWVrZGF5TmFtZXM9IiArIEFycmF5cy50b1N0cmluZyhzaG9ydFdlZWtkYXlOYW1lcykgKyAiLCIgKworICAgICAgICAgICAgICAgICJsb25nU3RhbmRBbG9uZVdlZWtkYXlOYW1lcz0iICsgQXJyYXlzLnRvU3RyaW5nKGxvbmdTdGFuZEFsb25lV2Vla2RheU5hbWVzKSArICIsIiArCisgICAgICAgICAgICAgICAgInNob3J0U3RhbmRBbG9uZVdlZWtkYXlOYW1lcz0iICsgQXJyYXlzLnRvU3RyaW5nKHNob3J0U3RhbmRBbG9uZVdlZWtkYXlOYW1lcykgKyAiLCIgKworICAgICAgICAgICAgICAgICJmdWxsVGltZUZvcm1hdD0iICsgZnVsbFRpbWVGb3JtYXQgKyAiLCIgKworICAgICAgICAgICAgICAgICJsb25nVGltZUZvcm1hdD0iICsgbG9uZ1RpbWVGb3JtYXQgKyAiLCIgKworICAgICAgICAgICAgICAgICJtZWRpdW1UaW1lRm9ybWF0PSIgKyBtZWRpdW1UaW1lRm9ybWF0ICsgIiwiICsKKyAgICAgICAgICAgICAgICAic2hvcnRUaW1lRm9ybWF0PSIgKyBzaG9ydFRpbWVGb3JtYXQgKyAiLCIgKworICAgICAgICAgICAgICAgICJmdWxsRGF0ZUZvcm1hdD0iICsgZnVsbERhdGVGb3JtYXQgKyAiLCIgKworICAgICAgICAgICAgICAgICJsb25nRGF0ZUZvcm1hdD0iICsgbG9uZ0RhdGVGb3JtYXQgKyAiLCIgKworICAgICAgICAgICAgICAgICJtZWRpdW1EYXRlRm9ybWF0PSIgKyBtZWRpdW1EYXRlRm9ybWF0ICsgIiwiICsKKyAgICAgICAgICAgICAgICAic2hvcnREYXRlRm9ybWF0PSIgKyBzaG9ydERhdGVGb3JtYXQgKyAiLCIgKworICAgICAgICAgICAgICAgICJ6ZXJvRGlnaXQ9IiArIHplcm9EaWdpdCArICIsIiArCisgICAgICAgICAgICAgICAgImRlY2ltYWxTZXBhcmF0b3I9IiArIGRlY2ltYWxTZXBhcmF0b3IgKyAiLCIgKworICAgICAgICAgICAgICAgICJncm91cGluZ1NlcGFyYXRvcj0iICsgZ3JvdXBpbmdTZXBhcmF0b3IgKyAiLCIgKworICAgICAgICAgICAgICAgICJwYXR0ZXJuU2VwYXJhdG9yPSIgKyBwYXR0ZXJuU2VwYXJhdG9yICsgIiwiICsKKyAgICAgICAgICAgICAgICAicGVyY2VudD0iICsgcGVyY2VudCArICIsIiArCisgICAgICAgICAgICAgICAgInBlck1pbGw9IiArIHBlck1pbGwgKyAiLCIgKworICAgICAgICAgICAgICAgICJtb25ldGFyeVNlcGFyYXRvcj0iICsgbW9uZXRhcnlTZXBhcmF0b3IgKyAiLCIgKworICAgICAgICAgICAgICAgICJtaW51c1NpZ249IiArIG1pbnVzU2lnbiArICIsIiArCisgICAgICAgICAgICAgICAgImV4cG9uZW50U2VwYXJhdG9yPSIgKyBleHBvbmVudFNlcGFyYXRvciArICIsIiArCisgICAgICAgICAgICAgICAgImluZmluaXR5PSIgKyBpbmZpbml0eSArICIsIiArCisgICAgICAgICAgICAgICAgIk5hTj0iICsgTmFOICsgIiwiICsKKyAgICAgICAgICAgICAgICAiY3VycmVuY3lTeW1ib2w9IiArIGN1cnJlbmN5U3ltYm9sICsgIiwiICsKKyAgICAgICAgICAgICAgICAiaW50ZXJuYXRpb25hbEN1cnJlbmN5U3ltYm9sPSIgKyBpbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2wgKyAiLCIgKworICAgICAgICAgICAgICAgICJudW1iZXJQYXR0ZXJuPSIgKyBudW1iZXJQYXR0ZXJuICsgIiwiICsKKyAgICAgICAgICAgICAgICAiaW50ZWdlclBhdHRlcm49IiArIGludGVnZXJQYXR0ZXJuICsgIiwiICsKKyAgICAgICAgICAgICAgICAiY3VycmVuY3lQYXR0ZXJuPSIgKyBjdXJyZW5jeVBhdHRlcm4gKyAiLCIgKworICAgICAgICAgICAgICAgICJwZXJjZW50UGF0dGVybj0iICsgcGVyY2VudFBhdHRlcm4gKyAiXSI7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG92ZXJyaWRlV2l0aERhdGFGcm9tKExvY2FsZURhdGEgb3ZlcnJpZGVzKSB7CisgICAgICAgIGlmIChvdmVycmlkZXMuZmlyc3REYXlPZldlZWsgIT0gbnVsbCkgeworICAgICAgICAgICAgZmlyc3REYXlPZldlZWsgPSBvdmVycmlkZXMuZmlyc3REYXlPZldlZWs7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG92ZXJyaWRlcy5taW5pbWFsRGF5c0luRmlyc3RXZWVrICE9IG51bGwpIHsKKyAgICAgICAgICAgIG1pbmltYWxEYXlzSW5GaXJzdFdlZWsgPSBvdmVycmlkZXMubWluaW1hbERheXNJbkZpcnN0V2VlazsKKyAgICAgICAgfQorICAgICAgICBpZiAob3ZlcnJpZGVzLmFtUG0gIT0gbnVsbCkgeworICAgICAgICAgICAgYW1QbSA9IG92ZXJyaWRlcy5hbVBtOworICAgICAgICB9CisgICAgICAgIGlmIChvdmVycmlkZXMuZXJhcyAhPSBudWxsKSB7CisgICAgICAgICAgICBlcmFzID0gb3ZlcnJpZGVzLmVyYXM7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG92ZXJyaWRlcy5sb25nTW9udGhOYW1lcyAhPSBudWxsKSB7CisgICAgICAgICAgICBsb25nTW9udGhOYW1lcyA9IG92ZXJyaWRlcy5sb25nTW9udGhOYW1lczsKKyAgICAgICAgfQorICAgICAgICBpZiAob3ZlcnJpZGVzLnNob3J0TW9udGhOYW1lcyAhPSBudWxsKSB7CisgICAgICAgICAgICBzaG9ydE1vbnRoTmFtZXMgPSBvdmVycmlkZXMuc2hvcnRNb250aE5hbWVzOworICAgICAgICB9CisgICAgICAgIGlmIChvdmVycmlkZXMubG9uZ1N0YW5kQWxvbmVNb250aE5hbWVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxvbmdTdGFuZEFsb25lTW9udGhOYW1lcyA9IG92ZXJyaWRlcy5sb25nU3RhbmRBbG9uZU1vbnRoTmFtZXM7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG92ZXJyaWRlcy5zaG9ydFN0YW5kQWxvbmVNb250aE5hbWVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNob3J0U3RhbmRBbG9uZU1vbnRoTmFtZXMgPSBvdmVycmlkZXMuc2hvcnRTdGFuZEFsb25lTW9udGhOYW1lczsKKyAgICAgICAgfQorICAgICAgICBpZiAob3ZlcnJpZGVzLmxvbmdXZWVrZGF5TmFtZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgbG9uZ1dlZWtkYXlOYW1lcyA9IG92ZXJyaWRlcy5sb25nV2Vla2RheU5hbWVzOworICAgICAgICB9CisgICAgICAgIGlmIChvdmVycmlkZXMuc2hvcnRXZWVrZGF5TmFtZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgc2hvcnRXZWVrZGF5TmFtZXMgPSBvdmVycmlkZXMuc2hvcnRXZWVrZGF5TmFtZXM7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG92ZXJyaWRlcy5sb25nU3RhbmRBbG9uZVdlZWtkYXlOYW1lcyAhPSBudWxsKSB7CisgICAgICAgICAgICBsb25nU3RhbmRBbG9uZVdlZWtkYXlOYW1lcyA9IG92ZXJyaWRlcy5sb25nU3RhbmRBbG9uZVdlZWtkYXlOYW1lczsKKyAgICAgICAgfQorICAgICAgICBpZiAob3ZlcnJpZGVzLnNob3J0U3RhbmRBbG9uZVdlZWtkYXlOYW1lcyAhPSBudWxsKSB7CisgICAgICAgICAgICBzaG9ydFN0YW5kQWxvbmVXZWVrZGF5TmFtZXMgPSBvdmVycmlkZXMuc2hvcnRTdGFuZEFsb25lV2Vla2RheU5hbWVzOworICAgICAgICB9CisgICAgICAgIGlmIChvdmVycmlkZXMuZnVsbFRpbWVGb3JtYXQgIT0gbnVsbCkgeworICAgICAgICAgICAgZnVsbFRpbWVGb3JtYXQgPSBvdmVycmlkZXMuZnVsbFRpbWVGb3JtYXQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG92ZXJyaWRlcy5sb25nVGltZUZvcm1hdCAhPSBudWxsKSB7CisgICAgICAgICAgICBsb25nVGltZUZvcm1hdCA9IG92ZXJyaWRlcy5sb25nVGltZUZvcm1hdDsKKyAgICAgICAgfQorICAgICAgICBpZiAob3ZlcnJpZGVzLm1lZGl1bVRpbWVGb3JtYXQgIT0gbnVsbCkgeworICAgICAgICAgICAgbWVkaXVtVGltZUZvcm1hdCA9IG92ZXJyaWRlcy5tZWRpdW1UaW1lRm9ybWF0OworICAgICAgICB9CisgICAgICAgIGlmIChvdmVycmlkZXMuc2hvcnRUaW1lRm9ybWF0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNob3J0VGltZUZvcm1hdCA9IG92ZXJyaWRlcy5zaG9ydFRpbWVGb3JtYXQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG92ZXJyaWRlcy5mdWxsRGF0ZUZvcm1hdCAhPSBudWxsKSB7CisgICAgICAgICAgICBmdWxsRGF0ZUZvcm1hdCA9IG92ZXJyaWRlcy5mdWxsRGF0ZUZvcm1hdDsKKyAgICAgICAgfQorICAgICAgICBpZiAob3ZlcnJpZGVzLmxvbmdEYXRlRm9ybWF0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxvbmdEYXRlRm9ybWF0ID0gb3ZlcnJpZGVzLmxvbmdEYXRlRm9ybWF0OworICAgICAgICB9CisgICAgICAgIGlmIChvdmVycmlkZXMubWVkaXVtRGF0ZUZvcm1hdCAhPSBudWxsKSB7CisgICAgICAgICAgICBtZWRpdW1EYXRlRm9ybWF0ID0gb3ZlcnJpZGVzLm1lZGl1bURhdGVGb3JtYXQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG92ZXJyaWRlcy5zaG9ydERhdGVGb3JtYXQgIT0gbnVsbCkgeworICAgICAgICAgICAgc2hvcnREYXRlRm9ybWF0ID0gb3ZlcnJpZGVzLnNob3J0RGF0ZUZvcm1hdDsKKyAgICAgICAgfQorICAgICAgICBpZiAob3ZlcnJpZGVzLnplcm9EaWdpdCAhPSAnXDAnKSB7CisgICAgICAgICAgICB6ZXJvRGlnaXQgPSBvdmVycmlkZXMuemVyb0RpZ2l0OworICAgICAgICB9CisgICAgICAgIGlmIChvdmVycmlkZXMuZGVjaW1hbFNlcGFyYXRvciAhPSAnXDAnKSB7CisgICAgICAgICAgICBkZWNpbWFsU2VwYXJhdG9yID0gb3ZlcnJpZGVzLmRlY2ltYWxTZXBhcmF0b3I7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG92ZXJyaWRlcy5ncm91cGluZ1NlcGFyYXRvciAhPSAnXDAnKSB7CisgICAgICAgICAgICBncm91cGluZ1NlcGFyYXRvciA9IG92ZXJyaWRlcy5ncm91cGluZ1NlcGFyYXRvcjsKKyAgICAgICAgfQorICAgICAgICBpZiAob3ZlcnJpZGVzLnBhdHRlcm5TZXBhcmF0b3IgIT0gJ1wwJykgeworICAgICAgICAgICAgcGF0dGVyblNlcGFyYXRvciA9IG92ZXJyaWRlcy5wYXR0ZXJuU2VwYXJhdG9yOworICAgICAgICB9CisgICAgICAgIGlmIChvdmVycmlkZXMucGVyY2VudCAhPSAnXDAnKSB7CisgICAgICAgICAgICBwZXJjZW50ID0gb3ZlcnJpZGVzLnBlcmNlbnQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG92ZXJyaWRlcy5wZXJNaWxsICE9ICdcMCcpIHsKKyAgICAgICAgICAgIHBlck1pbGwgPSBvdmVycmlkZXMucGVyTWlsbDsKKyAgICAgICAgfQorICAgICAgICBpZiAob3ZlcnJpZGVzLm1vbmV0YXJ5U2VwYXJhdG9yICE9ICdcMCcpIHsKKyAgICAgICAgICAgIG1vbmV0YXJ5U2VwYXJhdG9yID0gb3ZlcnJpZGVzLm1vbmV0YXJ5U2VwYXJhdG9yOworICAgICAgICB9CisgICAgICAgIGlmIChvdmVycmlkZXMubWludXNTaWduICE9ICdcMCcpIHsKKyAgICAgICAgICAgIG1pbnVzU2lnbiA9IG92ZXJyaWRlcy5taW51c1NpZ247CisgICAgICAgIH0KKyAgICAgICAgaWYgKG92ZXJyaWRlcy5leHBvbmVudFNlcGFyYXRvciAhPSBudWxsKSB7CisgICAgICAgICAgICBleHBvbmVudFNlcGFyYXRvciA9IG92ZXJyaWRlcy5leHBvbmVudFNlcGFyYXRvcjsKKyAgICAgICAgfQorICAgICAgICBpZiAob3ZlcnJpZGVzLk5hTiAhPSBudWxsKSB7CisgICAgICAgICAgICBOYU4gPSBvdmVycmlkZXMuTmFOOworICAgICAgICB9CisgICAgICAgIGlmIChvdmVycmlkZXMuaW5maW5pdHkgIT0gbnVsbCkgeworICAgICAgICAgICAgaW5maW5pdHkgPSBvdmVycmlkZXMuaW5maW5pdHk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG92ZXJyaWRlcy5jdXJyZW5jeVN5bWJvbCAhPSBudWxsKSB7CisgICAgICAgICAgICBjdXJyZW5jeVN5bWJvbCA9IG92ZXJyaWRlcy5jdXJyZW5jeVN5bWJvbDsKKyAgICAgICAgfQorICAgICAgICBpZiAob3ZlcnJpZGVzLmludGVybmF0aW9uYWxDdXJyZW5jeVN5bWJvbCAhPSBudWxsKSB7CisgICAgICAgICAgICBpbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2wgPSBvdmVycmlkZXMuaW50ZXJuYXRpb25hbEN1cnJlbmN5U3ltYm9sOworICAgICAgICB9CisgICAgICAgIGlmIChvdmVycmlkZXMubnVtYmVyUGF0dGVybiAhPSBudWxsKSB7CisgICAgICAgICAgICBudW1iZXJQYXR0ZXJuID0gb3ZlcnJpZGVzLm51bWJlclBhdHRlcm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKG92ZXJyaWRlcy5pbnRlZ2VyUGF0dGVybiAhPSBudWxsKSB7CisgICAgICAgICAgICBpbnRlZ2VyUGF0dGVybiA9IG92ZXJyaWRlcy5pbnRlZ2VyUGF0dGVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAob3ZlcnJpZGVzLmN1cnJlbmN5UGF0dGVybiAhPSBudWxsKSB7CisgICAgICAgICAgICBjdXJyZW5jeVBhdHRlcm4gPSBvdmVycmlkZXMuY3VycmVuY3lQYXR0ZXJuOworICAgICAgICB9CisgICAgICAgIGlmIChvdmVycmlkZXMucGVyY2VudFBhdHRlcm4gIT0gbnVsbCkgeworICAgICAgICAgICAgcGVyY2VudFBhdHRlcm4gPSBvdmVycmlkZXMucGVyY2VudFBhdHRlcm47CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldERhdGVGb3JtYXQoaW50IHN0eWxlKSB7CisgICAgICAgIHN3aXRjaCAoc3R5bGUpIHsKKyAgICAgICAgY2FzZSBEYXRlRm9ybWF0LlNIT1JUOgorICAgICAgICAgICAgcmV0dXJuIHNob3J0RGF0ZUZvcm1hdDsKKyAgICAgICAgY2FzZSBEYXRlRm9ybWF0Lk1FRElVTToKKyAgICAgICAgICAgIHJldHVybiBtZWRpdW1EYXRlRm9ybWF0OworICAgICAgICBjYXNlIERhdGVGb3JtYXQuTE9ORzoKKyAgICAgICAgICAgIHJldHVybiBsb25nRGF0ZUZvcm1hdDsKKyAgICAgICAgY2FzZSBEYXRlRm9ybWF0LkZVTEw6CisgICAgICAgICAgICByZXR1cm4gZnVsbERhdGVGb3JtYXQ7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRUaW1lRm9ybWF0KGludCBzdHlsZSkgeworICAgICAgICBzd2l0Y2ggKHN0eWxlKSB7CisgICAgICAgIGNhc2UgRGF0ZUZvcm1hdC5TSE9SVDoKKyAgICAgICAgICAgIHJldHVybiBzaG9ydFRpbWVGb3JtYXQ7CisgICAgICAgIGNhc2UgRGF0ZUZvcm1hdC5NRURJVU06CisgICAgICAgICAgICByZXR1cm4gbWVkaXVtVGltZUZvcm1hdDsKKyAgICAgICAgY2FzZSBEYXRlRm9ybWF0LkxPTkc6CisgICAgICAgICAgICByZXR1cm4gbG9uZ1RpbWVGb3JtYXQ7CisgICAgICAgIGNhc2UgRGF0ZUZvcm1hdC5GVUxMOgorICAgICAgICAgICAgcmV0dXJuIGZ1bGxUaW1lRm9ybWF0OworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIExvY2FsZURhdGEgaW5pdExvY2FsZURhdGEoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBMb2NhbGVEYXRhIGxvY2FsZURhdGEgPSBuZXcgTG9jYWxlRGF0YSgpOworICAgICAgICBpZiAoIUlDVS5pbml0TG9jYWxlRGF0YUltcGwobG9jYWxlLnRvU3RyaW5nKCksIGxvY2FsZURhdGEpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoImNvdWxkbid0IGluaXRpYWxpemUgTG9jYWxlRGF0YSBmb3IgbG9jYWxlICIgKyBsb2NhbGUpOworICAgICAgICB9CisgICAgICAgIGlmIChsb2NhbGVEYXRhLmZ1bGxUaW1lRm9ybWF0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vIFRoZXJlIGFyZSBzb21lIGZ1bGwgdGltZSBmb3JtYXQgcGF0dGVybnMgaW4gSUNVIHRoYXQgdXNlIHRoZSBwYXR0ZXJuIGNoYXJhY3RlciAndicuCisgICAgICAgICAgICAvLyBKYXZhIGRvZXNuJ3QgYWNjZXB0IHRoaXMsIHNvIHdlIHJlcGxhY2UgaXQgd2l0aCAneicgd2hpY2ggaGFzIGFib3V0IHRoZSBzYW1lIHJlc3VsdAorICAgICAgICAgICAgLy8gYXMgJ3YnLCB0aGUgdGltZXpvbmUgbmFtZS4KKyAgICAgICAgICAgIC8vICd2JyAtPiAiUFQiLCAneicgLT4gIlBTVCIsIHYgaXMgdGhlIGdlbmVyaWMgdGltZXpvbmUgYW5kIHogdGhlIHN0YW5kYXJkIHR6CisgICAgICAgICAgICAvLyAidnZ2diIgLT4gIlBhY2lmaWMgVGltZSIsICJ6enp6IiAtPiAiUGFjaWZpYyBTdGFuZGFyZCBUaW1lIgorICAgICAgICAgICAgbG9jYWxlRGF0YS5mdWxsVGltZUZvcm1hdCA9IGxvY2FsZURhdGEuZnVsbFRpbWVGb3JtYXQucmVwbGFjZSgndicsICd6Jyk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxvY2FsZURhdGEubnVtYmVyUGF0dGVybiAhPSBudWxsKSB7CisgICAgICAgICAgICAvLyBUaGUgbnVtYmVyIHBhdHRlcm4gbWlnaHQgY29udGFpbiBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgc3VicGF0dGVybnMuIEFyYWJpYywgZm9yCisgICAgICAgICAgICAvLyBleGFtcGxlLCBtaWdodCBsb29rIGxpa2UgIiMsIyMwLiMjIzsjLCMjMC4jIyMtIiBiZWNhdXNlIHRoZSBtaW51cyBzaWduIHNob3VsZCBiZQorICAgICAgICAgICAgLy8gd3JpdHRlbiBsYXN0LiBNYWNlZG9uaWFuIHN1cHBvc2VkbHkgbG9va3Mgc29tZXRoaW5nIGxpa2UgIiMsIyMwLiMjIzsoIywjIzAuIyMjKSIuCisgICAgICAgICAgICAvLyAoVGhlIG5lZ2F0aXZlIHN1YnBhdHRlcm4gaXMgb3B0aW9uYWwsIHRob3VnaCwgYW5kIG5vdCBwcmVzZW50IGluIG1vc3QgbG9jYWxlcy4pCisgICAgICAgICAgICAvLyBCeSBvbmx5IHN3YWxsb3dpbmcgJyMnZXMgYW5kICcsJ3MgYWZ0ZXIgdGhlICcuJywgd2UgZW5zdXJlIHRoYXQgd2UgZG9uJ3QKKyAgICAgICAgICAgIC8vIGFjY2lkZW50YWxseSBlYXQgdG9vIG11Y2guCisgICAgICAgICAgICBsb2NhbGVEYXRhLmludGVnZXJQYXR0ZXJuID0gbG9jYWxlRGF0YS5udW1iZXJQYXR0ZXJuLnJlcGxhY2VBbGwoIlxcLlsjLF0qIiwgIiIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBsb2NhbGVEYXRhOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2ljdS9OYXRpdmVCcmVha0l0ZXJhdG9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvTmF0aXZlQnJlYWtJdGVyYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg4Y2ViNzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvTmF0aXZlQnJlYWtJdGVyYXRvci5qYXZhCkBAIC0wLDAgKzEsMTY1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmljdTsKKworaW1wb3J0IGphdmEudGV4dC5DaGFyYWN0ZXJJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnRleHQuU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworcHVibGljIGZpbmFsIGNsYXNzIE5hdGl2ZUJyZWFrSXRlcmF0b3IgaW1wbGVtZW50cyBDbG9uZWFibGUgeworICAgIC8vIEFjY2VwdGFibGUgdmFsdWVzIGZvciB0aGUgJ3R5cGUnIGZpZWxkLgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCSV9DSEFSX0lOU1RBTkNFID0gMTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQklfV09SRF9JTlNUQU5DRSA9IDI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJJX0xJTkVfSU5TVEFOQ0UgPSAzOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCSV9TRU5UX0lOU1RBTkNFID0gNDsKKworICAgIHByaXZhdGUgZmluYWwgaW50IGFkZHJlc3M7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdHlwZTsKKyAgICBwcml2YXRlIENoYXJhY3Rlckl0ZXJhdG9yIGNoYXJJdGVyOworCisgICAgcHJpdmF0ZSBOYXRpdmVCcmVha0l0ZXJhdG9yKGludCBhZGRyZXNzLCBpbnQgdHlwZSkgeworICAgICAgICB0aGlzLmFkZHJlc3MgPSBhZGRyZXNzOworICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgICAgICB0aGlzLmNoYXJJdGVyID0gbmV3IFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yKCIiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICBpbnQgY2xvbmVBZGRyID0gY2xvbmVJbXBsKHRoaXMuYWRkcmVzcyk7CisgICAgICAgIE5hdGl2ZUJyZWFrSXRlcmF0b3IgY2xvbmUgPSBuZXcgTmF0aXZlQnJlYWtJdGVyYXRvcihjbG9uZUFkZHIsIHRoaXMudHlwZSk7CisgICAgICAgIC8vIFRoZSBSSSBkb2Vzbid0IGNsb25lIHRoZSBDaGFyYWN0ZXJJdGVyYXRvci4KKyAgICAgICAgY2xvbmUuY2hhckl0ZXIgPSB0aGlzLmNoYXJJdGVyOworICAgICAgICByZXR1cm4gY2xvbmU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgaWYgKG9iamVjdCA9PSB0aGlzKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBOYXRpdmVCcmVha0l0ZXJhdG9yKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIC8vIFRPRE86IGlzIHRoaXMgc3VmZmljaWVudD8gc2hvdWxkbid0IHdlIGJlIGNoZWNraW5nIHRoZSB1bmRlcmx5aW5nIHJ1bGVzPworICAgICAgICBOYXRpdmVCcmVha0l0ZXJhdG9yIHJocyA9IChOYXRpdmVCcmVha0l0ZXJhdG9yKSBvYmplY3Q7CisgICAgICAgIHJldHVybiB0eXBlID09IHJocy50eXBlICYmIGNoYXJJdGVyLmVxdWFscyhyaHMuY2hhckl0ZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiA0MjsgLy8gTm8tb25lIHVzZXMgQnJlYWtJdGVyYXRvciBhcyBhIGhhc2gga2V5LgorICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2xvc2VCcmVha0l0ZXJhdG9ySW1wbCh0aGlzLmFkZHJlc3MpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc3VwZXIuZmluYWxpemUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBpbnQgY3VycmVudCgpIHsKKyAgICAgICAgcmV0dXJuIGN1cnJlbnRJbXBsKHRoaXMuYWRkcmVzcyk7CisgICAgfQorCisgICAgcHVibGljIGludCBmaXJzdCgpIHsKKyAgICAgICAgcmV0dXJuIGZpcnN0SW1wbCh0aGlzLmFkZHJlc3MpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZm9sbG93aW5nKGludCBvZmZzZXQpIHsKKyAgICAgICAgcmV0dXJuIGZvbGxvd2luZ0ltcGwodGhpcy5hZGRyZXNzLCBvZmZzZXQpOworICAgIH0KKworICAgIHB1YmxpYyBDaGFyYWN0ZXJJdGVyYXRvciBnZXRUZXh0KCkgeworICAgICAgICBpbnQgbmV3TG9jID0gY3VycmVudEltcGwodGhpcy5hZGRyZXNzKTsKKyAgICAgICAgdGhpcy5jaGFySXRlci5zZXRJbmRleChuZXdMb2MpOworICAgICAgICByZXR1cm4gdGhpcy5jaGFySXRlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGxhc3QoKSB7CisgICAgICAgIHJldHVybiBsYXN0SW1wbCh0aGlzLmFkZHJlc3MpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgbikgeworICAgICAgICByZXR1cm4gbmV4dEltcGwodGhpcy5hZGRyZXNzLCBuKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IG5leHQoKSB7CisgICAgICAgIHJldHVybiBuZXh0SW1wbCh0aGlzLmFkZHJlc3MsIDEpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgcHJldmlvdXMoKSB7CisgICAgICAgIHJldHVybiBwcmV2aW91c0ltcGwodGhpcy5hZGRyZXNzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUZXh0KENoYXJhY3Rlckl0ZXJhdG9yIG5ld1RleHQpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGZvciAoY2hhciBjID0gbmV3VGV4dC5maXJzdCgpOyBjICE9IENoYXJhY3Rlckl0ZXJhdG9yLkRPTkU7IGMgPSBuZXdUZXh0Lm5leHQoKSkgeworICAgICAgICAgICAgc2IuYXBwZW5kKGMpOworICAgICAgICB9CisgICAgICAgIHNldFRleHQoc2IudG9TdHJpbmcoKSwgbmV3VGV4dCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGV4dChTdHJpbmcgbmV3VGV4dCkgeworICAgICAgICBzZXRUZXh0KG5ld1RleHQsIG5ldyBTdHJpbmdDaGFyYWN0ZXJJdGVyYXRvcihuZXdUZXh0KSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNldFRleHQoU3RyaW5nIHMsIENoYXJhY3Rlckl0ZXJhdG9yIGl0KSB7CisgICAgICAgIHRoaXMuY2hhckl0ZXIgPSBpdDsKKyAgICAgICAgc2V0VGV4dEltcGwodGhpcy5hZGRyZXNzLCBzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0JvdW5kYXJ5KGludCBvZmZzZXQpIHsKKyAgICAgICAgcmV0dXJuIGlzQm91bmRhcnlJbXBsKHRoaXMuYWRkcmVzcywgb2Zmc2V0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IHByZWNlZGluZyhpbnQgb2Zmc2V0KSB7CisgICAgICAgIHJldHVybiBwcmVjZWRpbmdJbXBsKHRoaXMuYWRkcmVzcywgb2Zmc2V0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIE5hdGl2ZUJyZWFrSXRlcmF0b3IgZ2V0Q2hhcmFjdGVySW5zdGFuY2UoTG9jYWxlIHdoZXJlKSB7CisgICAgICAgIHJldHVybiBuZXcgTmF0aXZlQnJlYWtJdGVyYXRvcihnZXRDaGFyYWN0ZXJJbnN0YW5jZUltcGwod2hlcmUudG9TdHJpbmcoKSksIEJJX0NIQVJfSU5TVEFOQ0UpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgTmF0aXZlQnJlYWtJdGVyYXRvciBnZXRMaW5lSW5zdGFuY2UoTG9jYWxlIHdoZXJlKSB7CisgICAgICAgIHJldHVybiBuZXcgTmF0aXZlQnJlYWtJdGVyYXRvcihnZXRMaW5lSW5zdGFuY2VJbXBsKHdoZXJlLnRvU3RyaW5nKCkpLCBCSV9MSU5FX0lOU1RBTkNFKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIE5hdGl2ZUJyZWFrSXRlcmF0b3IgZ2V0U2VudGVuY2VJbnN0YW5jZShMb2NhbGUgd2hlcmUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBOYXRpdmVCcmVha0l0ZXJhdG9yKGdldFNlbnRlbmNlSW5zdGFuY2VJbXBsKHdoZXJlLnRvU3RyaW5nKCkpLCBCSV9TRU5UX0lOU1RBTkNFKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIE5hdGl2ZUJyZWFrSXRlcmF0b3IgZ2V0V29yZEluc3RhbmNlKExvY2FsZSB3aGVyZSkgeworICAgICAgICByZXR1cm4gbmV3IE5hdGl2ZUJyZWFrSXRlcmF0b3IoZ2V0V29yZEluc3RhbmNlSW1wbCh3aGVyZS50b1N0cmluZygpKSwgQklfV09SRF9JTlNUQU5DRSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGludCBnZXRDaGFyYWN0ZXJJbnN0YW5jZUltcGwoU3RyaW5nIGxvY2FsZSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGludCBnZXRXb3JkSW5zdGFuY2VJbXBsKFN0cmluZyBsb2NhbGUpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgZ2V0TGluZUluc3RhbmNlSW1wbChTdHJpbmcgbG9jYWxlKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IGdldFNlbnRlbmNlSW5zdGFuY2VJbXBsKFN0cmluZyBsb2NhbGUpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIGNsb3NlQnJlYWtJdGVyYXRvckltcGwoaW50IGFkZHJlc3MpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIHNldFRleHRJbXBsKGludCBhZGRyZXNzLCBTdHJpbmcgdGV4dCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGludCBjbG9uZUltcGwoaW50IGFkZHJlc3MpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgcHJlY2VkaW5nSW1wbChpbnQgYWRkcmVzcywgaW50IG9mZnNldCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gaXNCb3VuZGFyeUltcGwoaW50IGFkZHJlc3MsIGludCBvZmZzZXQpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgbmV4dEltcGwoaW50IGFkZHJlc3MsIGludCBuKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IHByZXZpb3VzSW1wbChpbnQgYWRkcmVzcyk7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGludCBjdXJyZW50SW1wbChpbnQgYWRkcmVzcyk7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGludCBmaXJzdEltcGwoaW50IGFkZHJlc3MpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgZm9sbG93aW5nSW1wbChpbnQgYWRkcmVzcywgaW50IG9mZnNldCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGludCBsYXN0SW1wbChpbnQgYWRkcmVzcyk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvTmF0aXZlQ29sbGF0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvTmF0aXZlQ29sbGF0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmY2MWM0OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2ljdS9OYXRpdmVDb2xsYXRpb24uamF2YQpAQCAtMCwwICsxLDQzIEBACisvKioKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyogQ29weXJpZ2h0IChDKSAxOTk2LTIwMDUsIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kICAgICoKKyogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyoKKyoKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyovCisKK3BhY2thZ2UgbGliY29yZS5pY3U7CisKKy8qKgorKiBQYWNrYWdlIHN0YXRpYyBjbGFzcyBmb3IgZGVjbGFyaW5nIGFsbCBuYXRpdmUgbWV0aG9kcyBmb3IgY29sbGF0aW9uIHVzZS4KKyogQGF1dGhvciBzeW4gd2VlIHF1ZWsKKyogQGludGVybmFsIElDVSAyLjQKKyovCitwdWJsaWMgZmluYWwgY2xhc3MgTmF0aXZlQ29sbGF0aW9uIHsKKyAgICBwcml2YXRlIE5hdGl2ZUNvbGxhdGlvbigpIHsKKyAgICB9CisKKyAgICAvLyBDb2xsYXRvci4KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIGNsb3NlQ29sbGF0b3IoaW50IGFkZHJlc3MpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBjb21wYXJlKGludCBhZGRyZXNzLCBTdHJpbmcgc291cmNlLCBTdHJpbmcgdGFyZ2V0KTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgZ2V0QXR0cmlidXRlKGludCBhZGRyZXNzLCBpbnQgdHlwZSk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IGdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihpbnQgYWRkcmVzcywgU3RyaW5nIHNvdXJjZSk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgU3RyaW5nIGdldFJ1bGVzKGludCBhZGRyZXNzKTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBieXRlW10gZ2V0U29ydEtleShpbnQgYWRkcmVzcywgU3RyaW5nIHNvdXJjZSk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IG9wZW5Db2xsYXRvcihTdHJpbmcgbG9jYWxlKTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgb3BlbkNvbGxhdG9yRnJvbVJ1bGVzKFN0cmluZyBydWxlcywgaW50IG5vcm1hbGl6YXRpb25Nb2RlLCBpbnQgY29sbGF0aW9uU3RyZW5ndGgpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBzYWZlQ2xvbmUoaW50IGFkZHJlc3MpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgc2V0QXR0cmlidXRlKGludCBhZGRyZXNzLCBpbnQgdHlwZSwgaW50IHZhbHVlKTsKKworICAgIC8vIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci4KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIGNsb3NlRWxlbWVudHMoaW50IGFkZHJlc3MpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBnZXRNYXhFeHBhbnNpb24oaW50IGFkZHJlc3MsIGludCBvcmRlcik7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IGdldE9mZnNldChpbnQgYWRkcmVzcyk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IG5leHQoaW50IGFkZHJlc3MpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBwcmV2aW91cyhpbnQgYWRkcmVzcyk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCByZXNldChpbnQgYWRkcmVzcyk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBzZXRPZmZzZXQoaW50IGFkZHJlc3MsIGludCBvZmZzZXQpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgc2V0VGV4dChpbnQgYWRkcmVzcywgU3RyaW5nIHNvdXJjZSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvTmF0aXZlQ29udmVydGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvTmF0aXZlQ29udmVydGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmQ4NjMwYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2ljdS9OYXRpdmVDb252ZXJ0ZXIuamF2YQpAQCAtMCwwICsxLDcyIEBACisvKioKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyogQ29weXJpZ2h0IChDKSAxOTk2LTIwMDYsIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kICAgICoKKyogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyoKKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyovCisKK3BhY2thZ2UgbGliY29yZS5pY3U7CisKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0RGVjb2RlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRFbmNvZGVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ29kaW5nRXJyb3JBY3Rpb247CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBOYXRpdmVDb252ZXJ0ZXIgeworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBkZWNvZGUobG9uZyBjb252ZXJ0ZXJIYW5kbGUsIGJ5dGVbXSBpbnB1dCwgaW50IGluRW5kLAorICAgICAgICAgICAgY2hhcltdIG91dHB1dCwgaW50IG91dEVuZCwgaW50W10gZGF0YSwgYm9vbGVhbiBmbHVzaCk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgZW5jb2RlKGxvbmcgY29udmVydGVySGFuZGxlLCBjaGFyW10gaW5wdXQsIGludCBpbkVuZCwKKyAgICAgICAgICAgIGJ5dGVbXSBvdXRwdXQsIGludCBvdXRFbmQsIGludFtdIGRhdGEsIGJvb2xlYW4gZmx1c2gpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgbG9uZyBvcGVuQ29udmVydGVyKFN0cmluZyBlbmNvZGluZyk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBjbG9zZUNvbnZlcnRlcihsb25nIGNvbnZlcnRlckhhbmRsZSk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHJlc2V0Qnl0ZVRvQ2hhcihsb25nIGNvbnZlcnRlckhhbmRsZSk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCByZXNldENoYXJUb0J5dGUobG9uZyBjb252ZXJ0ZXJIYW5kbGUpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgYnl0ZVtdIGdldFN1YnN0aXR1dGlvbkJ5dGVzKGxvbmcgY29udmVydGVySGFuZGxlKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBnZXRNYXhCeXRlc1BlckNoYXIobG9uZyBjb252ZXJ0ZXJIYW5kbGUpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBnZXRNaW5CeXRlc1BlckNoYXIobG9uZyBjb252ZXJ0ZXJIYW5kbGUpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGZsb2F0IGdldEF2ZUJ5dGVzUGVyQ2hhcihsb25nIGNvbnZlcnRlckhhbmRsZSk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgZmxvYXQgZ2V0QXZlQ2hhcnNQZXJCeXRlKGxvbmcgY29udmVydGVySGFuZGxlKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gY29udGFpbnMoU3RyaW5nIGNvbnZlcnRlck5hbWUxLCBTdHJpbmcgY29udmVydGVyTmFtZTIpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBjYW5FbmNvZGUobG9uZyBjb252ZXJ0ZXJIYW5kbGUsIGludCBjb2RlVW5pdCk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBTdHJpbmdbXSBnZXRBdmFpbGFibGVDaGFyc2V0TmFtZXMoKTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBDaGFyc2V0IGNoYXJzZXRGb3JOYW1lKFN0cmluZyBjaGFyc2V0TmFtZSk7CisKKyAgICAvLyBUcmFuc2xhdGVzIGZyb20gSmF2YSdzIGVudW0gdG8gdGhlIG1hZ2ljIG51bWJlcnMgI2RlZmluZWQgaW4gIk5hdGl2ZUNvbnZlcnRlci5jcHAiLgorICAgIHByaXZhdGUgc3RhdGljIGludCB0cmFuc2xhdGVDb2RpbmdFcnJvckFjdGlvbihDb2RpbmdFcnJvckFjdGlvbiBhY3Rpb24pIHsKKyAgICAgICAgaWYgKGFjdGlvbiA9PSBDb2RpbmdFcnJvckFjdGlvbi5SRVBPUlQpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbiA9PSBDb2RpbmdFcnJvckFjdGlvbi5JR05PUkUpIHsKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbiA9PSBDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFKSB7CisgICAgICAgICAgICByZXR1cm4gMjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOyAvLyBTb21lb25lIGNoYW5nZWQgdGhlIGVudW0uCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGludCBzZXRDYWxsYmFja0RlY29kZShsb25nIGNvbnZlcnRlckhhbmRsZSwgQ2hhcnNldERlY29kZXIgZGVjb2RlcikgeworICAgICAgICByZXR1cm4gc2V0Q2FsbGJhY2tEZWNvZGUoY29udmVydGVySGFuZGxlLAorICAgICAgICAgICAgICAgIHRyYW5zbGF0ZUNvZGluZ0Vycm9yQWN0aW9uKGRlY29kZXIubWFsZm9ybWVkSW5wdXRBY3Rpb24oKSksCisgICAgICAgICAgICAgICAgdHJhbnNsYXRlQ29kaW5nRXJyb3JBY3Rpb24oZGVjb2Rlci51bm1hcHBhYmxlQ2hhcmFjdGVyQWN0aW9uKCkpLAorICAgICAgICAgICAgICAgIGRlY29kZXIucmVwbGFjZW1lbnQoKSk7CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgc2V0Q2FsbGJhY2tEZWNvZGUobG9uZyBjb252ZXJ0ZXJIYW5kbGUsIGludCBvbk1hbGZvcm1lZElucHV0LCBpbnQgb25Vbm1hcHBhYmxlSW5wdXQsIFN0cmluZyBzdWJDaGFycyk7CisKKyAgICBwdWJsaWMgc3RhdGljIGludCBzZXRDYWxsYmFja0VuY29kZShsb25nIGNvbnZlcnRlckhhbmRsZSwgQ2hhcnNldEVuY29kZXIgZW5jb2RlcikgeworICAgICAgICByZXR1cm4gc2V0Q2FsbGJhY2tFbmNvZGUoY29udmVydGVySGFuZGxlLAorICAgICAgICAgICAgICAgIHRyYW5zbGF0ZUNvZGluZ0Vycm9yQWN0aW9uKGVuY29kZXIubWFsZm9ybWVkSW5wdXRBY3Rpb24oKSksCisgICAgICAgICAgICAgICAgdHJhbnNsYXRlQ29kaW5nRXJyb3JBY3Rpb24oZW5jb2Rlci51bm1hcHBhYmxlQ2hhcmFjdGVyQWN0aW9uKCkpLAorICAgICAgICAgICAgICAgIGVuY29kZXIucmVwbGFjZW1lbnQoKSk7CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgc2V0Q2FsbGJhY2tFbmNvZGUobG9uZyBjb252ZXJ0ZXJIYW5kbGUsIGludCBvbk1hbGZvcm1lZElucHV0LCBpbnQgb25Vbm1hcHBhYmxlSW5wdXQsIGJ5dGVbXSBzdWJCeXRlcyk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvTmF0aXZlRGVjaW1hbEZvcm1hdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaWN1L05hdGl2ZURlY2ltYWxGb3JtYXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NDc3NWU1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaWN1L05hdGl2ZURlY2ltYWxGb3JtYXQuamF2YQpAQCAtMCwwICsxLDY0MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pY3U7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnRGVjaW1hbDsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLm1hdGguUm91bmRpbmdNb2RlOworaW1wb3J0IGphdmEudGV4dC5BdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3I7CitpbXBvcnQgamF2YS50ZXh0LkF0dHJpYnV0ZWRTdHJpbmc7CitpbXBvcnQgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXRTeW1ib2xzOworaW1wb3J0IGphdmEudGV4dC5GaWVsZFBvc2l0aW9uOworaW1wb3J0IGphdmEudGV4dC5Gb3JtYXQ7CitpbXBvcnQgamF2YS50ZXh0Lk51bWJlckZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuUGFyc2VQb3NpdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ3VycmVuY3k7CitpbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBOYXRpdmVEZWNpbWFsRm9ybWF0IHsKKyAgICAvKioKKyAgICAgKiBDb25zdGFudHMgY29ycmVzcG9uZGluZyB0byB0aGUgbmF0aXZlIHR5cGUgVU51bWJlckZvcm1hdFN5bWJvbCwgZm9yIHNldFN5bWJvbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9ERUNJTUFMX1NFUEFSQVRPUl9TWU1CT0wgPSAwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX0dST1VQSU5HX1NFUEFSQVRPUl9TWU1CT0wgPSAxOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX1BBVFRFUk5fU0VQQVJBVE9SX1NZTUJPTCA9IDI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOVU1fUEVSQ0VOVF9TWU1CT0wgPSAzOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX1pFUk9fRElHSVRfU1lNQk9MID0gNDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9ESUdJVF9TWU1CT0wgPSA1OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX01JTlVTX1NJR05fU1lNQk9MID0gNjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9QTFVTX1NJR05fU1lNQk9MID0gNzsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9DVVJSRU5DWV9TWU1CT0wgPSA4OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX0lOVExfQ1VSUkVOQ1lfU1lNQk9MID0gOTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9NT05FVEFSWV9TRVBBUkFUT1JfU1lNQk9MID0gMTA7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOVU1fRVhQT05FTlRJQUxfU1lNQk9MID0gMTE7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOVU1fUEVSTUlMTF9TWU1CT0wgPSAxMjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9QQURfRVNDQVBFX1NZTUJPTCA9IDEzOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX0lORklOSVRZX1NZTUJPTCA9IDE0OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX05BTl9TWU1CT0wgPSAxNTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9TSUdOSUZJQ0FOVF9ESUdJVF9TWU1CT0wgPSAxNjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9NT05FVEFSWV9HUk9VUElOR19TRVBBUkFUT1JfU1lNQk9MID0gMTc7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOVU1fRk9STUFUX1NZTUJPTF9DT1VOVCA9IDE4OworCisgICAgLyoqCisgICAgICogQ29uc3RhbnRzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG5hdGl2ZSB0eXBlIFVOdW1iZXJGb3JtYXRBdHRyaWJ1dGUsIGZvcgorICAgICAqIGdldEF0dHJpYnV0ZS9zZXRBdHRyaWJ1dGUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOVU1fUEFSU0VfSU5UX09OTFkgPSAwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX0dST1VQSU5HX1VTRUQgPSAxOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX0RFQ0lNQUxfQUxXQVlTX1NIT1dOID0gMjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9NQVhfSU5URUdFUl9ESUdJVFMgPSAzOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX01JTl9JTlRFR0VSX0RJR0lUUyA9IDQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOVU1fSU5URUdFUl9ESUdJVFMgPSA1OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX01BWF9GUkFDVElPTl9ESUdJVFMgPSA2OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX01JTl9GUkFDVElPTl9ESUdJVFMgPSA3OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX0ZSQUNUSU9OX0RJR0lUUyA9IDg7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOVU1fTVVMVElQTElFUiA9IDk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOVU1fR1JPVVBJTkdfU0laRSA9IDEwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX1JPVU5ESU5HX01PREUgPSAxMTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9ST1VORElOR19JTkNSRU1FTlQgPSAxMjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9GT1JNQVRfV0lEVEggPSAxMzsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9QQURESU5HX1BPU0lUSU9OID0gMTQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOVU1fU0VDT05EQVJZX0dST1VQSU5HX1NJWkUgPSAxNTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9TSUdOSUZJQ0FOVF9ESUdJVFNfVVNFRCA9IDE2OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX01JTl9TSUdOSUZJQ0FOVF9ESUdJVFMgPSAxNzsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9NQVhfU0lHTklGSUNBTlRfRElHSVRTID0gMTg7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOVU1fTEVOSUVOVF9QQVJTRSA9IDE5OworCisgICAgLyoqCisgICAgICogQ29uc3RhbnRzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG5hdGl2ZSB0eXBlIFVOdW1iZXJGb3JtYXRUZXh0QXR0cmlidXRlLCBmb3IKKyAgICAgKiBnZXRUZXh0QXR0cmlidXRlL3NldFRleHRBdHRyaWJ1dGUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOVU1fUE9TSVRJVkVfUFJFRklYID0gMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9QT1NJVElWRV9TVUZGSVggPSAxOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBVTlVNX05FR0FUSVZFX1BSRUZJWCA9IDI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOVU1fTkVHQVRJVkVfU1VGRklYID0gMzsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9QQURESU5HX0NIQVJBQ1RFUiA9IDQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOVU1fQ1VSUkVOQ1lfQ09ERSA9IDU7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOVU1fREVGQVVMVF9SVUxFU0VUID0gNjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5VTV9QVUJMSUNfUlVMRVNFVFMgPSA3OworCisgICAgLyoqCisgICAgICogVGhlIGFkZHJlc3Mgb2YgdGhlIElDVSBEZWNpbWFsRm9ybWF0KiBvbiB0aGUgbmF0aXZlIGhlYXAuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgYWRkcmVzczsKKworICAgIC8qKgorICAgICAqIFRoZSBsYXN0IHBhdHRlcm4gd2UgZ2F2ZSB0byBJQ1UsIHNvIHdlIGNhbiBtYWtlIHJlcGVhdGVkIGFwcGxpY2F0aW9ucyBjaGVhcC4KKyAgICAgKiBUaGlzIGhlbHBzIGluIGNhc2VzIGxpa2UgU3RyaW5nLmZvcm1hdCgiJS4yZiwlLjJmXG4iLCB4LCB5KSB3aGVyZSB0aGUgRGVjaW1hbEZvcm1hdCBpcworICAgICAqIHJldXNlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBsYXN0UGF0dGVybjsKKworICAgIC8vIFRPRE86IHN0b3JlIGFsbCB0aGVzZSBpbiBEZWNpbWFsRm9ybWF0IGluc3RlYWQhCisgICAgcHJpdmF0ZSBib29sZWFuIG5lZ1ByZWZOdWxsOworICAgIHByaXZhdGUgYm9vbGVhbiBuZWdTdWZmTnVsbDsKKyAgICBwcml2YXRlIGJvb2xlYW4gcG9zUHJlZk51bGw7CisgICAgcHJpdmF0ZSBib29sZWFuIHBvc1N1ZmZOdWxsOworCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgYm9vbGVhbiBwYXJzZUJpZ0RlY2ltYWw7CisKKyAgICAvKioKKyAgICAgKiBDYWNoZSB0aGUgQmlnRGVjaW1hbCBmb3JtIG9mIHRoZSBtdWx0aXBsaWVyLiBUaGlzIGlzIG51bGwgdW50aWwgd2UndmUKKyAgICAgKiBmb3JtYXR0ZWQgYSBCaWdEZWNpbWFsICh3aXRoIGEgbXVsdGlwbGllciB0aGF0IGlzIG5vdCAxKSwgb3IgdGhlIHVzZXIgaGFzCisgICAgICogZXhwbGljaXRseSBjYWxsZWQge0BsaW5rICNzZXRNdWx0aXBsaWVyKGludCl9IHdpdGggYW55IG11bHRpcGxpZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBCaWdEZWNpbWFsIG11bHRpcGxpZXJCaWdEZWNpbWFsID0gbnVsbDsKKworICAgIHB1YmxpYyBOYXRpdmVEZWNpbWFsRm9ybWF0KFN0cmluZyBwYXR0ZXJuLCBEZWNpbWFsRm9ybWF0U3ltYm9scyBkZnMpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoaXMuYWRkcmVzcyA9IG9wZW4ocGF0dGVybiwgZGZzLmdldEN1cnJlbmN5U3ltYm9sKCksCisgICAgICAgICAgICAgICAgICAgIGRmcy5nZXREZWNpbWFsU2VwYXJhdG9yKCksIGRmcy5nZXREaWdpdCgpLCBkZnMuZ2V0RXhwb25lbnRTZXBhcmF0b3IoKSwKKyAgICAgICAgICAgICAgICAgICAgZGZzLmdldEdyb3VwaW5nU2VwYXJhdG9yKCksIGRmcy5nZXRJbmZpbml0eSgpLAorICAgICAgICAgICAgICAgICAgICBkZnMuZ2V0SW50ZXJuYXRpb25hbEN1cnJlbmN5U3ltYm9sKCksIGRmcy5nZXRNaW51c1NpZ24oKSwKKyAgICAgICAgICAgICAgICAgICAgZGZzLmdldE1vbmV0YXJ5RGVjaW1hbFNlcGFyYXRvcigpLCBkZnMuZ2V0TmFOKCksIGRmcy5nZXRQYXR0ZXJuU2VwYXJhdG9yKCksCisgICAgICAgICAgICAgICAgICAgIGRmcy5nZXRQZXJjZW50KCksIGRmcy5nZXRQZXJNaWxsKCksIGRmcy5nZXRaZXJvRGlnaXQoKSk7CisgICAgICAgICAgICB0aGlzLmxhc3RQYXR0ZXJuID0gcGF0dGVybjsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICB0aHJvdyBucGU7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gcmUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInN5bnRheCBlcnJvcjogIiArIHJlLmdldE1lc3NhZ2UoKSArICI6ICIgKyBwYXR0ZXJuKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFVzZWQgc28gamF2YS51dGlsLkZvcm1hdHRlciBkb2Vzbid0IG5lZWQgdG8gYWxsb2NhdGUgRGVjaW1hbEZvcm1hdFN5bWJvbHMgaW5zdGFuY2VzLgorICAgIHB1YmxpYyBOYXRpdmVEZWNpbWFsRm9ybWF0KFN0cmluZyBwYXR0ZXJuLCBMb2NhbGVEYXRhIGRhdGEpIHsKKyAgICAgICAgdGhpcy5hZGRyZXNzID0gb3BlbihwYXR0ZXJuLCBkYXRhLmN1cnJlbmN5U3ltYm9sLAorICAgICAgICAgICAgICAgIGRhdGEuZGVjaW1hbFNlcGFyYXRvciwgJyMnLCBkYXRhLmV4cG9uZW50U2VwYXJhdG9yLCBkYXRhLmdyb3VwaW5nU2VwYXJhdG9yLAorICAgICAgICAgICAgICAgIGRhdGEuaW5maW5pdHksIGRhdGEuaW50ZXJuYXRpb25hbEN1cnJlbmN5U3ltYm9sLCBkYXRhLm1pbnVzU2lnbiwKKyAgICAgICAgICAgICAgICBkYXRhLm1vbmV0YXJ5U2VwYXJhdG9yLCBkYXRhLk5hTiwgZGF0YS5wYXR0ZXJuU2VwYXJhdG9yLAorICAgICAgICAgICAgICAgIGRhdGEucGVyY2VudCwgZGF0YS5wZXJNaWxsLCBkYXRhLnplcm9EaWdpdCk7CisgICAgICAgIHRoaXMubGFzdFBhdHRlcm4gPSBwYXR0ZXJuOworICAgIH0KKworICAgIC8vIFVzZWQgdG8gaW1wbGVtZW50IGNsb25lLgorICAgIHByaXZhdGUgTmF0aXZlRGVjaW1hbEZvcm1hdChOYXRpdmVEZWNpbWFsRm9ybWF0IG90aGVyKSB7CisgICAgICAgIHRoaXMuYWRkcmVzcyA9IGNsb25lSW1wbChvdGhlci5hZGRyZXNzKTsKKyAgICAgICAgdGhpcy5sYXN0UGF0dGVybiA9IG90aGVyLmxhc3RQYXR0ZXJuOworICAgICAgICB0aGlzLm5lZ1ByZWZOdWxsID0gb3RoZXIubmVnUHJlZk51bGw7CisgICAgICAgIHRoaXMubmVnU3VmZk51bGwgPSBvdGhlci5uZWdTdWZmTnVsbDsKKyAgICAgICAgdGhpcy5wb3NQcmVmTnVsbCA9IG90aGVyLnBvc1ByZWZOdWxsOworICAgICAgICB0aGlzLnBvc1N1ZmZOdWxsID0gb3RoZXIucG9zU3VmZk51bGw7CisgICAgfQorCisgICAgLy8gVE9ETzogcmVtb3ZlIHRoaXMgYW5kIGp1c3QgaGF2ZSBEZWNpbWFsRm9ybWF0Lmhhc2hDb2RlIGRvIHRoZSByaWdodCB0aGluZyBpdHNlbGYuCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UG9zaXRpdmVQcmVmaXgoKS5oYXNoQ29kZSgpOworICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHsKKyAgICAgICAgaWYgKGFkZHJlc3MgIT0gMCkgeworICAgICAgICAgICAgY2xvc2UoYWRkcmVzcyk7CisgICAgICAgICAgICBhZGRyZXNzID0gMDsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHJldHVybiBuZXcgTmF0aXZlRGVjaW1hbEZvcm1hdCh0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3RlOiB0aGlzIGRvZXNuJ3QgY2hlY2sgdGhhdCB0aGUgdW5kZXJseWluZyBuYXRpdmUgRGVjaW1hbEZvcm1hdCBvYmplY3RzJyBjb25maWd1cmVkCisgICAgICogbmF0aXZlIERlY2ltYWxGb3JtYXRTeW1ib2xzIG9iamVjdHMgYXJlIGVxdWFsLiBJdCBpcyBhc3N1bWVkIHRoYXQgdGhlCisgICAgICogY2FsbGVyIChEZWNpbWFsRm9ybWF0KSB3aWxsIGNoZWNrIHRoZSBEZWNpbWFsRm9ybWF0U3ltYm9scyBvYmplY3RzCisgICAgICogaW5zdGVhZCwgZm9yIHBlcmZvcm1hbmNlLgorICAgICAqCisgICAgICogVGhpcyBpcyBhbHNvIHVucmVhc29uYWJseSBleHBlbnNpdmUsIGNhbGxpbmcgZG93biB0byBKTkkgbXVsdGlwbGUgdGltZXMuCisgICAgICoKKyAgICAgKiBUT0RPOiByZW1vdmUgdGhpcyBhbmQganVzdCBoYXZlIERlY2ltYWxGb3JtYXQuZXF1YWxzIGRvIHRoZSByaWdodCB0aGluZyBpdHNlbGYuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgaWYgKG9iamVjdCA9PSB0aGlzKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBOYXRpdmVEZWNpbWFsRm9ybWF0KSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIE5hdGl2ZURlY2ltYWxGb3JtYXQgb2JqID0gKE5hdGl2ZURlY2ltYWxGb3JtYXQpIG9iamVjdDsKKyAgICAgICAgaWYgKG9iai5hZGRyZXNzID09IHRoaXMuYWRkcmVzcykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG9iai50b1BhdHRlcm4oKS5lcXVhbHModGhpcy50b1BhdHRlcm4oKSkgJiYKKyAgICAgICAgICAgICAgICBvYmouaXNEZWNpbWFsU2VwYXJhdG9yQWx3YXlzU2hvd24oKSA9PSB0aGlzLmlzRGVjaW1hbFNlcGFyYXRvckFsd2F5c1Nob3duKCkgJiYKKyAgICAgICAgICAgICAgICBvYmouZ2V0R3JvdXBpbmdTaXplKCkgPT0gdGhpcy5nZXRHcm91cGluZ1NpemUoKSAmJgorICAgICAgICAgICAgICAgIG9iai5nZXRNdWx0aXBsaWVyKCkgPT0gdGhpcy5nZXRNdWx0aXBsaWVyKCkgJiYKKyAgICAgICAgICAgICAgICBvYmouZ2V0TmVnYXRpdmVQcmVmaXgoKS5lcXVhbHModGhpcy5nZXROZWdhdGl2ZVByZWZpeCgpKSAmJgorICAgICAgICAgICAgICAgIG9iai5nZXROZWdhdGl2ZVN1ZmZpeCgpLmVxdWFscyh0aGlzLmdldE5lZ2F0aXZlU3VmZml4KCkpICYmCisgICAgICAgICAgICAgICAgb2JqLmdldFBvc2l0aXZlUHJlZml4KCkuZXF1YWxzKHRoaXMuZ2V0UG9zaXRpdmVQcmVmaXgoKSkgJiYKKyAgICAgICAgICAgICAgICBvYmouZ2V0UG9zaXRpdmVTdWZmaXgoKS5lcXVhbHModGhpcy5nZXRQb3NpdGl2ZVN1ZmZpeCgpKSAmJgorICAgICAgICAgICAgICAgIG9iai5nZXRNYXhpbXVtSW50ZWdlckRpZ2l0cygpID09IHRoaXMuZ2V0TWF4aW11bUludGVnZXJEaWdpdHMoKSAmJgorICAgICAgICAgICAgICAgIG9iai5nZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoKSA9PSB0aGlzLmdldE1heGltdW1GcmFjdGlvbkRpZ2l0cygpICYmCisgICAgICAgICAgICAgICAgb2JqLmdldE1pbmltdW1JbnRlZ2VyRGlnaXRzKCkgPT0gdGhpcy5nZXRNaW5pbXVtSW50ZWdlckRpZ2l0cygpICYmCisgICAgICAgICAgICAgICAgb2JqLmdldE1pbmltdW1GcmFjdGlvbkRpZ2l0cygpID09IHRoaXMuZ2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKCkgJiYKKyAgICAgICAgICAgICAgICBvYmouaXNHcm91cGluZ1VzZWQoKSA9PSB0aGlzLmlzR3JvdXBpbmdVc2VkKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29waWVzIHRoZSBEZWNpbWFsRm9ybWF0U3ltYm9scyBzZXR0aW5ncyBpbnRvIG91ciBuYXRpdmUgcGVlciBpbiBidWxrLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERlY2ltYWxGb3JtYXRTeW1ib2xzKGZpbmFsIERlY2ltYWxGb3JtYXRTeW1ib2xzIGRmcykgeworICAgICAgICBzZXREZWNpbWFsRm9ybWF0U3ltYm9scyh0aGlzLmFkZHJlc3MsIGRmcy5nZXRDdXJyZW5jeVN5bWJvbCgpLCBkZnMuZ2V0RGVjaW1hbFNlcGFyYXRvcigpLAorICAgICAgICAgICAgICAgIGRmcy5nZXREaWdpdCgpLCBkZnMuZ2V0RXhwb25lbnRTZXBhcmF0b3IoKSwgZGZzLmdldEdyb3VwaW5nU2VwYXJhdG9yKCksCisgICAgICAgICAgICAgICAgZGZzLmdldEluZmluaXR5KCksIGRmcy5nZXRJbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2woKSwgZGZzLmdldE1pbnVzU2lnbigpLAorICAgICAgICAgICAgICAgIGRmcy5nZXRNb25ldGFyeURlY2ltYWxTZXBhcmF0b3IoKSwgZGZzLmdldE5hTigpLCBkZnMuZ2V0UGF0dGVyblNlcGFyYXRvcigpLAorICAgICAgICAgICAgICAgIGRmcy5nZXRQZXJjZW50KCksIGRmcy5nZXRQZXJNaWxsKCksIGRmcy5nZXRaZXJvRGlnaXQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RGVjaW1hbEZvcm1hdFN5bWJvbHMoZmluYWwgTG9jYWxlRGF0YSBsb2NhbGVEYXRhKSB7CisgICAgICAgIHNldERlY2ltYWxGb3JtYXRTeW1ib2xzKHRoaXMuYWRkcmVzcywgbG9jYWxlRGF0YS5jdXJyZW5jeVN5bWJvbCwgbG9jYWxlRGF0YS5kZWNpbWFsU2VwYXJhdG9yLAorICAgICAgICAgICAgICAgICcjJywgbG9jYWxlRGF0YS5leHBvbmVudFNlcGFyYXRvciwgbG9jYWxlRGF0YS5ncm91cGluZ1NlcGFyYXRvciwKKyAgICAgICAgICAgICAgICBsb2NhbGVEYXRhLmluZmluaXR5LCBsb2NhbGVEYXRhLmludGVybmF0aW9uYWxDdXJyZW5jeVN5bWJvbCwgbG9jYWxlRGF0YS5taW51c1NpZ24sCisgICAgICAgICAgICAgICAgbG9jYWxlRGF0YS5tb25ldGFyeVNlcGFyYXRvciwgbG9jYWxlRGF0YS5OYU4sIGxvY2FsZURhdGEucGF0dGVyblNlcGFyYXRvciwKKyAgICAgICAgICAgICAgICBsb2NhbGVEYXRhLnBlcmNlbnQsIGxvY2FsZURhdGEucGVyTWlsbCwgbG9jYWxlRGF0YS56ZXJvRGlnaXQpOworICAgIH0KKworICAgIHB1YmxpYyBjaGFyW10gZm9ybWF0QmlnRGVjaW1hbChCaWdEZWNpbWFsIHZhbHVlLCBGaWVsZFBvc2l0aW9uIGZpZWxkKSB7CisgICAgICAgIEZpZWxkUG9zaXRpb25JdGVyYXRvciBmcGkgPSBGaWVsZFBvc2l0aW9uSXRlcmF0b3IuZm9yRmllbGRQb3NpdGlvbihmaWVsZCk7CisgICAgICAgIGNoYXJbXSByZXN1bHQgPSBmb3JtYXREaWdpdExpc3QodGhpcy5hZGRyZXNzLCB2YWx1ZS50b1N0cmluZygpLCBmcGkpOworICAgICAgICBpZiAoZnBpICE9IG51bGwpIHsKKyAgICAgICAgICAgIEZpZWxkUG9zaXRpb25JdGVyYXRvci5zZXRGaWVsZFBvc2l0aW9uKGZwaSwgZmllbGQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIGNoYXJbXSBmb3JtYXRCaWdJbnRlZ2VyKEJpZ0ludGVnZXIgdmFsdWUsIEZpZWxkUG9zaXRpb24gZmllbGQpIHsKKyAgICAgICAgRmllbGRQb3NpdGlvbkl0ZXJhdG9yIGZwaSA9IEZpZWxkUG9zaXRpb25JdGVyYXRvci5mb3JGaWVsZFBvc2l0aW9uKGZpZWxkKTsKKyAgICAgICAgY2hhcltdIHJlc3VsdCA9IGZvcm1hdERpZ2l0TGlzdCh0aGlzLmFkZHJlc3MsIHZhbHVlLnRvU3RyaW5nKDEwKSwgZnBpKTsKKyAgICAgICAgaWYgKGZwaSAhPSBudWxsKSB7CisgICAgICAgICAgICBGaWVsZFBvc2l0aW9uSXRlcmF0b3Iuc2V0RmllbGRQb3NpdGlvbihmcGksIGZpZWxkKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBjaGFyW10gZm9ybWF0TG9uZyhsb25nIHZhbHVlLCBGaWVsZFBvc2l0aW9uIGZpZWxkKSB7CisgICAgICAgIEZpZWxkUG9zaXRpb25JdGVyYXRvciBmcGkgPSBGaWVsZFBvc2l0aW9uSXRlcmF0b3IuZm9yRmllbGRQb3NpdGlvbihmaWVsZCk7CisgICAgICAgIGNoYXJbXSByZXN1bHQgPSBmb3JtYXRMb25nKHRoaXMuYWRkcmVzcywgdmFsdWUsIGZwaSk7CisgICAgICAgIGlmIChmcGkgIT0gbnVsbCkgeworICAgICAgICAgICAgRmllbGRQb3NpdGlvbkl0ZXJhdG9yLnNldEZpZWxkUG9zaXRpb24oZnBpLCBmaWVsZCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgY2hhcltdIGZvcm1hdERvdWJsZShkb3VibGUgdmFsdWUsIEZpZWxkUG9zaXRpb24gZmllbGQpIHsKKyAgICAgICAgRmllbGRQb3NpdGlvbkl0ZXJhdG9yIGZwaSA9IEZpZWxkUG9zaXRpb25JdGVyYXRvci5mb3JGaWVsZFBvc2l0aW9uKGZpZWxkKTsKKyAgICAgICAgY2hhcltdIHJlc3VsdCA9IGZvcm1hdERvdWJsZSh0aGlzLmFkZHJlc3MsIHZhbHVlLCBmcGkpOworICAgICAgICBpZiAoZnBpICE9IG51bGwpIHsKKyAgICAgICAgICAgIEZpZWxkUG9zaXRpb25JdGVyYXRvci5zZXRGaWVsZFBvc2l0aW9uKGZwaSwgZmllbGQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYXBwbHlMb2NhbGl6ZWRQYXR0ZXJuKFN0cmluZyBwYXR0ZXJuKSB7CisgICAgICAgIGFwcGx5UGF0dGVybih0aGlzLmFkZHJlc3MsIHRydWUsIHBhdHRlcm4pOworICAgICAgICBsYXN0UGF0dGVybiA9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYXBwbHlQYXR0ZXJuKFN0cmluZyBwYXR0ZXJuKSB7CisgICAgICAgIGlmIChsYXN0UGF0dGVybiAhPSBudWxsICYmIHBhdHRlcm4uZXF1YWxzKGxhc3RQYXR0ZXJuKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGFwcGx5UGF0dGVybih0aGlzLmFkZHJlc3MsIGZhbHNlLCBwYXR0ZXJuKTsKKyAgICAgICAgbGFzdFBhdHRlcm4gPSBwYXR0ZXJuOworICAgIH0KKworICAgIHB1YmxpYyBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcihPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmICghKG9iamVjdCBpbnN0YW5jZW9mIE51bWJlcikpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBOdW1iZXIgbnVtYmVyID0gKE51bWJlcikgb2JqZWN0OworICAgICAgICBGaWVsZFBvc2l0aW9uSXRlcmF0b3IgZnBJdGVyID0gbmV3IEZpZWxkUG9zaXRpb25JdGVyYXRvcigpOworICAgICAgICBTdHJpbmcgdGV4dDsKKyAgICAgICAgaWYgKG51bWJlciBpbnN0YW5jZW9mIEJpZ0ludGVnZXIgfHwgbnVtYmVyIGluc3RhbmNlb2YgQmlnRGVjaW1hbCkgeworICAgICAgICAgICAgdGV4dCA9IG5ldyBTdHJpbmcoZm9ybWF0RGlnaXRMaXN0KHRoaXMuYWRkcmVzcywgbnVtYmVyLnRvU3RyaW5nKCksIGZwSXRlcikpOworICAgICAgICB9IGVsc2UgaWYgKG51bWJlciBpbnN0YW5jZW9mIERvdWJsZSB8fCBudW1iZXIgaW5zdGFuY2VvZiBGbG9hdCkgeworICAgICAgICAgICAgZG91YmxlIGR2ID0gbnVtYmVyLmRvdWJsZVZhbHVlKCk7CisgICAgICAgICAgICB0ZXh0ID0gbmV3IFN0cmluZyhmb3JtYXREb3VibGUodGhpcy5hZGRyZXNzLCBkdiwgZnBJdGVyKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBsb25nIGx2ID0gbnVtYmVyLmxvbmdWYWx1ZSgpOworICAgICAgICAgICAgdGV4dCA9IG5ldyBTdHJpbmcoZm9ybWF0TG9uZyh0aGlzLmFkZHJlc3MsIGx2LCBmcEl0ZXIpKTsKKyAgICAgICAgfQorCisgICAgICAgIEF0dHJpYnV0ZWRTdHJpbmcgYXMgPSBuZXcgQXR0cmlidXRlZFN0cmluZyh0ZXh0KTsKKworICAgICAgICB3aGlsZSAoZnBJdGVyLm5leHQoKSkgeworICAgICAgICAgICAgRm9ybWF0LkZpZWxkIGZpZWxkID0gZnBJdGVyLmZpZWxkKCk7CisgICAgICAgICAgICBhcy5hZGRBdHRyaWJ1dGUoZmllbGQsIGZpZWxkLCBmcEl0ZXIuc3RhcnQoKSwgZnBJdGVyLmxpbWl0KCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gcmV0dXJuIHRoZSBDaGFyYWN0ZXJJdGVyYXRvciBmcm9tIEF0dHJpYnV0ZWRTdHJpbmcKKyAgICAgICAgcmV0dXJuIGFzLmdldEl0ZXJhdG9yKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgbWFrZVNjYWxlUG9zaXRpdmUoaW50IHNjYWxlLCBTdHJpbmdCdWlsZGVyIHZhbCkgeworICAgICAgICBpZiAoc2NhbGUgPCAwKSB7CisgICAgICAgICAgICBzY2FsZSA9IC1zY2FsZTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBzY2FsZTsgaSA+IDA7IGktLSkgeworICAgICAgICAgICAgICAgIHZhbC5hcHBlbmQoJzAnKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNjYWxlID0gMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2NhbGU7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyB0b0xvY2FsaXplZFBhdHRlcm4oKSB7CisgICAgICAgIHJldHVybiB0b1BhdHRlcm5JbXBsKHRoaXMuYWRkcmVzcywgdHJ1ZSk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyB0b1BhdHRlcm4oKSB7CisgICAgICAgIHJldHVybiB0b1BhdHRlcm5JbXBsKHRoaXMuYWRkcmVzcywgZmFsc2UpOworICAgIH0KKworICAgIHB1YmxpYyBOdW1iZXIgcGFyc2UoU3RyaW5nIHN0cmluZywgUGFyc2VQb3NpdGlvbiBwb3NpdGlvbikgeworICAgICAgICByZXR1cm4gcGFyc2UoYWRkcmVzcywgc3RyaW5nLCBwb3NpdGlvbiwgcGFyc2VCaWdEZWNpbWFsKTsKKyAgICB9CisKKyAgICAvLyBzdGFydCBnZXR0ZXIgYW5kIHNldHRlcgorCisgICAgcHVibGljIGludCBnZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoKSB7CisgICAgICAgIHJldHVybiBnZXRBdHRyaWJ1dGUodGhpcy5hZGRyZXNzLCBVTlVNX01BWF9GUkFDVElPTl9ESUdJVFMpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0TWF4aW11bUludGVnZXJEaWdpdHMoKSB7CisgICAgICAgIHJldHVybiBnZXRBdHRyaWJ1dGUodGhpcy5hZGRyZXNzLCBVTlVNX01BWF9JTlRFR0VSX0RJR0lUUyk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRNaW5pbXVtRnJhY3Rpb25EaWdpdHMoKSB7CisgICAgICAgIHJldHVybiBnZXRBdHRyaWJ1dGUodGhpcy5hZGRyZXNzLCBVTlVNX01JTl9GUkFDVElPTl9ESUdJVFMpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0TWluaW11bUludGVnZXJEaWdpdHMoKSB7CisgICAgICAgIHJldHVybiBnZXRBdHRyaWJ1dGUodGhpcy5hZGRyZXNzLCBVTlVNX01JTl9JTlRFR0VSX0RJR0lUUyk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRHcm91cGluZ1NpemUoKSB7CisgICAgICAgIHJldHVybiBnZXRBdHRyaWJ1dGUodGhpcy5hZGRyZXNzLCBVTlVNX0dST1VQSU5HX1NJWkUpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0TXVsdGlwbGllcigpIHsKKyAgICAgICAgcmV0dXJuIGdldEF0dHJpYnV0ZSh0aGlzLmFkZHJlc3MsIFVOVU1fTVVMVElQTElFUik7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXROZWdhdGl2ZVByZWZpeCgpIHsKKyAgICAgICAgaWYgKG5lZ1ByZWZOdWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0VGV4dEF0dHJpYnV0ZSh0aGlzLmFkZHJlc3MsIFVOVU1fTkVHQVRJVkVfUFJFRklYKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5lZ2F0aXZlU3VmZml4KCkgeworICAgICAgICBpZiAobmVnU3VmZk51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRUZXh0QXR0cmlidXRlKHRoaXMuYWRkcmVzcywgVU5VTV9ORUdBVElWRV9TVUZGSVgpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UG9zaXRpdmVQcmVmaXgoKSB7CisgICAgICAgIGlmIChwb3NQcmVmTnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldFRleHRBdHRyaWJ1dGUodGhpcy5hZGRyZXNzLCBVTlVNX1BPU0lUSVZFX1BSRUZJWCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRQb3NpdGl2ZVN1ZmZpeCgpIHsKKyAgICAgICAgaWYgKHBvc1N1ZmZOdWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0VGV4dEF0dHJpYnV0ZSh0aGlzLmFkZHJlc3MsIFVOVU1fUE9TSVRJVkVfU1VGRklYKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RlY2ltYWxTZXBhcmF0b3JBbHdheXNTaG93bigpIHsKKyAgICAgICAgcmV0dXJuIGdldEF0dHJpYnV0ZSh0aGlzLmFkZHJlc3MsIFVOVU1fREVDSU1BTF9BTFdBWVNfU0hPV04pICE9IDA7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNQYXJzZUJpZ0RlY2ltYWwoKSB7CisgICAgICAgIHJldHVybiBwYXJzZUJpZ0RlY2ltYWw7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNQYXJzZUludGVnZXJPbmx5KCkgeworICAgICAgICByZXR1cm4gZ2V0QXR0cmlidXRlKHRoaXMuYWRkcmVzcywgVU5VTV9QQVJTRV9JTlRfT05MWSkgIT0gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0dyb3VwaW5nVXNlZCgpIHsKKyAgICAgICAgcmV0dXJuIGdldEF0dHJpYnV0ZSh0aGlzLmFkZHJlc3MsIFVOVU1fR1JPVVBJTkdfVVNFRCkgIT0gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXREZWNpbWFsU2VwYXJhdG9yQWx3YXlzU2hvd24oYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICBpbnQgaSA9IHZhbHVlID8gLTEgOiAwOworICAgICAgICBzZXRBdHRyaWJ1dGUodGhpcy5hZGRyZXNzLCBVTlVNX0RFQ0lNQUxfQUxXQVlTX1NIT1dOLCBpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRDdXJyZW5jeShDdXJyZW5jeSBjdXJyZW5jeSkgeworICAgICAgICBzZXRTeW1ib2wodGhpcy5hZGRyZXNzLCBVTlVNX0NVUlJFTkNZX1NZTUJPTCwgY3VycmVuY3kuZ2V0U3ltYm9sKCkpOworICAgICAgICBzZXRTeW1ib2wodGhpcy5hZGRyZXNzLCBVTlVNX0lOVExfQ1VSUkVOQ1lfU1lNQk9MLCBjdXJyZW5jeS5nZXRDdXJyZW5jeUNvZGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0R3JvdXBpbmdTaXplKGludCB2YWx1ZSkgeworICAgICAgICBzZXRBdHRyaWJ1dGUodGhpcy5hZGRyZXNzLCBVTlVNX0dST1VQSU5HX1NJWkUsIHZhbHVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRHcm91cGluZ1VzZWQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICBpbnQgaSA9IHZhbHVlID8gLTEgOiAwOworICAgICAgICBzZXRBdHRyaWJ1dGUodGhpcy5hZGRyZXNzLCBVTlVNX0dST1VQSU5HX1VTRUQsIGkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldE1heGltdW1GcmFjdGlvbkRpZ2l0cyhpbnQgdmFsdWUpIHsKKyAgICAgICAgc2V0QXR0cmlidXRlKHRoaXMuYWRkcmVzcywgVU5VTV9NQVhfRlJBQ1RJT05fRElHSVRTLCB2YWx1ZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0TWF4aW11bUludGVnZXJEaWdpdHMoaW50IHZhbHVlKSB7CisgICAgICAgIHNldEF0dHJpYnV0ZSh0aGlzLmFkZHJlc3MsIFVOVU1fTUFYX0lOVEVHRVJfRElHSVRTLCB2YWx1ZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKGludCB2YWx1ZSkgeworICAgICAgICBzZXRBdHRyaWJ1dGUodGhpcy5hZGRyZXNzLCBVTlVNX01JTl9GUkFDVElPTl9ESUdJVFMsIHZhbHVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRNaW5pbXVtSW50ZWdlckRpZ2l0cyhpbnQgdmFsdWUpIHsKKyAgICAgICAgc2V0QXR0cmlidXRlKHRoaXMuYWRkcmVzcywgVU5VTV9NSU5fSU5URUdFUl9ESUdJVFMsIHZhbHVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRNdWx0aXBsaWVyKGludCB2YWx1ZSkgeworICAgICAgICBzZXRBdHRyaWJ1dGUodGhpcy5hZGRyZXNzLCBVTlVNX01VTFRJUExJRVIsIHZhbHVlKTsKKyAgICAgICAgLy8gVXBkYXRlIHRoZSBjYWNoZWQgQmlnRGVjaW1hbCBmb3IgbXVsdGlwbGllci4KKyAgICAgICAgbXVsdGlwbGllckJpZ0RlY2ltYWwgPSBCaWdEZWNpbWFsLnZhbHVlT2YodmFsdWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldE5lZ2F0aXZlUHJlZml4KFN0cmluZyB2YWx1ZSkgeworICAgICAgICBuZWdQcmVmTnVsbCA9IHZhbHVlID09IG51bGw7CisgICAgICAgIGlmICghbmVnUHJlZk51bGwpIHsKKyAgICAgICAgICAgIHNldFRleHRBdHRyaWJ1dGUodGhpcy5hZGRyZXNzLCBVTlVNX05FR0FUSVZFX1BSRUZJWCwgdmFsdWUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0TmVnYXRpdmVTdWZmaXgoU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIG5lZ1N1ZmZOdWxsID0gdmFsdWUgPT0gbnVsbDsKKyAgICAgICAgaWYgKCFuZWdTdWZmTnVsbCkgeworICAgICAgICAgICAgc2V0VGV4dEF0dHJpYnV0ZSh0aGlzLmFkZHJlc3MsIFVOVU1fTkVHQVRJVkVfU1VGRklYLCB2YWx1ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRQb3NpdGl2ZVByZWZpeChTdHJpbmcgdmFsdWUpIHsKKyAgICAgICAgcG9zUHJlZk51bGwgPSB2YWx1ZSA9PSBudWxsOworICAgICAgICBpZiAoIXBvc1ByZWZOdWxsKSB7CisgICAgICAgICAgICBzZXRUZXh0QXR0cmlidXRlKHRoaXMuYWRkcmVzcywgVU5VTV9QT1NJVElWRV9QUkVGSVgsIHZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFBvc2l0aXZlU3VmZml4KFN0cmluZyB2YWx1ZSkgeworICAgICAgICBwb3NTdWZmTnVsbCA9IHZhbHVlID09IG51bGw7CisgICAgICAgIGlmICghcG9zU3VmZk51bGwpIHsKKyAgICAgICAgICAgIHNldFRleHRBdHRyaWJ1dGUodGhpcy5hZGRyZXNzLCBVTlVNX1BPU0lUSVZFX1NVRkZJWCwgdmFsdWUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0UGFyc2VCaWdEZWNpbWFsKGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgICAgcGFyc2VCaWdEZWNpbWFsID0gdmFsdWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0UGFyc2VJbnRlZ2VyT25seShib29sZWFuIHZhbHVlKSB7CisgICAgICAgIGludCBpID0gdmFsdWUgPyAtMSA6IDA7CisgICAgICAgIHNldEF0dHJpYnV0ZSh0aGlzLmFkZHJlc3MsIFVOVU1fUEFSU0VfSU5UX09OTFksIGkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYXBwbHlQYXR0ZXJuKGludCBhZGRyLCBib29sZWFuIGxvY2FsaXplZCwgU3RyaW5nIHBhdHRlcm4pIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFwcGx5UGF0dGVybkltcGwoYWRkciwgbG9jYWxpemVkLCBwYXR0ZXJuKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICB0aHJvdyBucGU7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gcmUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInN5bnRheCBlcnJvcjogIiArIHJlLmdldE1lc3NhZ2UoKSArICI6ICIgKyBwYXR0ZXJuKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFJvdW5kaW5nTW9kZShSb3VuZGluZ01vZGUgcm91bmRpbmdNb2RlLCBkb3VibGUgcm91bmRpbmdJbmNyZW1lbnQpIHsKKyAgICAgICAgZmluYWwgaW50IG5hdGl2ZVJvdW5kaW5nTW9kZTsKKyAgICAgICAgc3dpdGNoIChyb3VuZGluZ01vZGUpIHsKKyAgICAgICAgY2FzZSBDRUlMSU5HOiBuYXRpdmVSb3VuZGluZ01vZGUgPSAwOyBicmVhazsKKyAgICAgICAgY2FzZSBGTE9PUjogbmF0aXZlUm91bmRpbmdNb2RlID0gMTsgYnJlYWs7CisgICAgICAgIGNhc2UgRE9XTjogbmF0aXZlUm91bmRpbmdNb2RlID0gMjsgYnJlYWs7CisgICAgICAgIGNhc2UgVVA6IG5hdGl2ZVJvdW5kaW5nTW9kZSA9IDM7IGJyZWFrOworICAgICAgICBjYXNlIEhBTEZfRVZFTjogbmF0aXZlUm91bmRpbmdNb2RlID0gNDsgYnJlYWs7CisgICAgICAgIGNhc2UgSEFMRl9ET1dOOiBuYXRpdmVSb3VuZGluZ01vZGUgPSA1OyBicmVhazsKKyAgICAgICAgY2FzZSBIQUxGX1VQOiBuYXRpdmVSb3VuZGluZ01vZGUgPSA2OyBicmVhazsKKyAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CisgICAgICAgIH0KKyAgICAgICAgc2V0Um91bmRpbmdNb2RlKGFkZHJlc3MsIG5hdGl2ZVJvdW5kaW5nTW9kZSwgcm91bmRpbmdJbmNyZW1lbnQpOworICAgIH0KKworICAgIC8vIFV0aWxpdHkgdG8gZ2V0IGluZm9ybWF0aW9uIGFib3V0IGZpZWxkIHBvc2l0aW9ucyBmcm9tIG5hdGl2ZSAoSUNVKSBjb2RlLgorICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEZpZWxkUG9zaXRpb25JdGVyYXRvciB7CisgICAgICAgIHByaXZhdGUgaW50W10gZGF0YTsKKyAgICAgICAgcHJpdmF0ZSBpbnQgcG9zID0gLTM7IC8vIHNvIGZpcnN0IGNhbGwgdG8gbmV4dCgpIGxlYXZlcyBwb3MgYXQgMAorCisgICAgICAgIHByaXZhdGUgRmllbGRQb3NpdGlvbkl0ZXJhdG9yKCkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN0YXRpYyBGaWVsZFBvc2l0aW9uSXRlcmF0b3IgZm9yRmllbGRQb3NpdGlvbihGaWVsZFBvc2l0aW9uIGZwKSB7CisgICAgICAgICAgICBpZiAoZnAgIT0gbnVsbCAmJiBmcC5nZXRGaWVsZCgpICE9IC0xKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWVsZFBvc2l0aW9uSXRlcmF0b3IoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGdldE5hdGl2ZUZpZWxkUG9zaXRpb25JZChGaWVsZFBvc2l0aW9uIGZwKSB7CisgICAgICAgICAgICAvLyBOT1RFOiAtMSwgMCwgYW5kIDEgd2VyZSB0aGUgb25seSB2YWxpZCBvcmlnaW5hbCBqYXZhIGZpZWxkIHZhbHVlcworICAgICAgICAgICAgLy8gZm9yIE51bWJlckZvcm1hdC4gIFRoZXkgdGFrZSBwcmVjZWRlbmNlLiAgVGhpcyBhc3N1bWVzIGFueSBvdGhlcgorICAgICAgICAgICAgLy8gdmFsdWUgaXMgYSBtaXN0YWtlIGFuZCB0aGUgYWN0dWFsIHZhbHVlIGlzIGluIHRoZSBhdHRyaWJ1dGUuCisgICAgICAgICAgICAvLyBDbGllbnRzIGNhbiBjb25zdHJ1Y3QgRmllbGRQb3NpdGlvbiBjb21iaW5pbmcgYW55IGF0dHJpYnV0ZSB3aXRoIGFueSBmaWVsZAorICAgICAgICAgICAgLy8gdmFsdWUsIHdoaWNoIGlzIGp1c3Qgd3JvbmcsIGJ1dCB0aGVyZSB5b3UgZ28uCisKKyAgICAgICAgICAgIGludCBpZCA9IGZwLmdldEZpZWxkKCk7CisgICAgICAgICAgICBpZiAoaWQgPCAtMSB8fCBpZCA+IDEpIHsKKyAgICAgICAgICAgICAgICBpZCA9IC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGlkID09IC0xKSB7CisgICAgICAgICAgICAgICAgRm9ybWF0LkZpZWxkIGF0dHIgPSBmcC5nZXRGaWVsZEF0dHJpYnV0ZSgpOworICAgICAgICAgICAgICAgIGlmIChhdHRyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZHNbaV0uZXF1YWxzKGF0dHIpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQgPSBpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGlkOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBzZXRGaWVsZFBvc2l0aW9uKEZpZWxkUG9zaXRpb25JdGVyYXRvciBmcGksIEZpZWxkUG9zaXRpb24gZnApIHsKKyAgICAgICAgICAgIGlmIChmcGkgIT0gbnVsbCAmJiBmcCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW50IGZpZWxkID0gZ2V0TmF0aXZlRmllbGRQb3NpdGlvbklkKGZwKTsKKyAgICAgICAgICAgICAgICBpZiAoZmllbGQgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGZwaS5uZXh0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmcGkuZmllbGRJZCgpID09IGZpZWxkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnAuc2V0QmVnaW5JbmRleChmcGkuc3RhcnQoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnAuc2V0RW5kSW5kZXgoZnBpLmxpbWl0KCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gbmV4dCgpIHsKKyAgICAgICAgICAgIC8vIGlmIHBvcyA9PSBkYXRhLmxlbmd0aCwgd2UndmUgYWxyZWFkeSByZXR1cm5lZCBmYWxzZSBvbmNlCisgICAgICAgICAgICBpZiAoZGF0YSA9PSBudWxsIHx8IHBvcyA9PSBkYXRhLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwb3MgKz0gMzsKKyAgICAgICAgICAgIHJldHVybiBwb3MgPCBkYXRhLmxlbmd0aDsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCBjaGVja1ZhbGlkKCkgeworICAgICAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCB8fCBwb3MgPCAwIHx8IHBvcyA9PSBkYXRhLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGZpZWxkSWQoKSB7CisgICAgICAgICAgICByZXR1cm4gZGF0YVtwb3NdOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEZvcm1hdC5GaWVsZCBmaWVsZCgpIHsKKyAgICAgICAgICAgIGNoZWNrVmFsaWQoKTsKKyAgICAgICAgICAgIHJldHVybiBmaWVsZHNbZGF0YVtwb3NdXTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgc3RhcnQoKSB7CisgICAgICAgICAgICBjaGVja1ZhbGlkKCk7CisgICAgICAgICAgICByZXR1cm4gZGF0YVtwb3MgKyAxXTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgbGltaXQoKSB7CisgICAgICAgICAgICBjaGVja1ZhbGlkKCk7CisgICAgICAgICAgICByZXR1cm4gZGF0YVtwb3MgKyAyXTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgc3RhdGljIEZvcm1hdC5GaWVsZCBmaWVsZHNbXSA9IHsKKyAgICAgICAgICAgIC8vIFRoZSBvbGQgamF2YSBmaWVsZCB2YWx1ZXMgd2VyZSAwIGZvciBpbnRlZ2VyIGFuZCAxIGZvciBmcmFjdGlvbi4KKyAgICAgICAgICAgIC8vIFRoZSBuZXcgamF2YSBmaWVsZCBhdHRyaWJ1dGVzIGFyZSBhbGwgb2JqZWN0cy4gIElDVSBhc3NpZ25zIHRoZSB2YWx1ZXMKKyAgICAgICAgICAgIC8vIHN0YXJ0aW5nIGZyb20gMCBpbiB0aGUgZm9sbG93aW5nIG9yZGVyOyBub3RlIHRoYXQgaW50ZWdlciBhbmQKKyAgICAgICAgICAgIC8vIGZyYWN0aW9uIHBvc2l0aW9ucyBtYXRjaCB0aGUgb2xkIGZpZWxkIHZhbHVlcy4KKyAgICAgICAgICAgIE51bWJlckZvcm1hdC5GaWVsZC5JTlRFR0VSLAorICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLkZSQUNUSU9OLAorICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLkRFQ0lNQUxfU0VQQVJBVE9SLAorICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLkVYUE9ORU5UX1NZTUJPTCwKKyAgICAgICAgICAgIE51bWJlckZvcm1hdC5GaWVsZC5FWFBPTkVOVF9TSUdOLAorICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLkVYUE9ORU5ULAorICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLkdST1VQSU5HX1NFUEFSQVRPUiwKKyAgICAgICAgICAgIE51bWJlckZvcm1hdC5GaWVsZC5DVVJSRU5DWSwKKyAgICAgICAgICAgIE51bWJlckZvcm1hdC5GaWVsZC5QRVJDRU5ULAorICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLlBFUk1JTExFLAorICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLlNJR04sCisgICAgICAgIH07CisKKyAgICAgICAgLy8gY2FsbGVkIGJ5IG5hdGl2ZQorICAgICAgICBwcml2YXRlIHZvaWQgc2V0RGF0YShpbnRbXSBkYXRhKSB7CisgICAgICAgICAgICB0aGlzLmRhdGEgPSBkYXRhOworICAgICAgICAgICAgdGhpcy5wb3MgPSAtMzsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIGFwcGx5UGF0dGVybkltcGwoaW50IGFkZHIsIGJvb2xlYW4gbG9jYWxpemVkLCBTdHJpbmcgcGF0dGVybik7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGludCBjbG9uZUltcGwoaW50IGFkZHIpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIGNsb3NlKGludCBhZGRyKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgY2hhcltdIGZvcm1hdExvbmcoaW50IGFkZHIsIGxvbmcgdmFsdWUsIEZpZWxkUG9zaXRpb25JdGVyYXRvciBpdGVyKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgY2hhcltdIGZvcm1hdERvdWJsZShpbnQgYWRkciwgZG91YmxlIHZhbHVlLCBGaWVsZFBvc2l0aW9uSXRlcmF0b3IgaXRlcik7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGNoYXJbXSBmb3JtYXREaWdpdExpc3QoaW50IGFkZHIsIFN0cmluZyB2YWx1ZSwgRmllbGRQb3NpdGlvbkl0ZXJhdG9yIGl0ZXIpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgZ2V0QXR0cmlidXRlKGludCBhZGRyLCBpbnQgc3ltYm9sKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgU3RyaW5nIGdldFRleHRBdHRyaWJ1dGUoaW50IGFkZHIsIGludCBzeW1ib2wpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgb3BlbihTdHJpbmcgcGF0dGVybiwgU3RyaW5nIGN1cnJlbmN5U3ltYm9sLAorICAgICAgICAgICAgY2hhciBkZWNpbWFsU2VwYXJhdG9yLCBjaGFyIGRpZ2l0LCBTdHJpbmcgZXhwb25lbnRTZXBhcmF0b3IsIGNoYXIgZ3JvdXBpbmdTZXBhcmF0b3IsCisgICAgICAgICAgICBTdHJpbmcgaW5maW5pdHksIFN0cmluZyBpbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2wsIGNoYXIgbWludXNTaWduLAorICAgICAgICAgICAgY2hhciBtb25ldGFyeURlY2ltYWxTZXBhcmF0b3IsIFN0cmluZyBuYW4sIGNoYXIgcGF0dGVyblNlcGFyYXRvciwgY2hhciBwZXJjZW50LAorICAgICAgICAgICAgY2hhciBwZXJNaWxsLCBjaGFyIHplcm9EaWdpdCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIE51bWJlciBwYXJzZShpbnQgYWRkciwgU3RyaW5nIHN0cmluZywgUGFyc2VQb3NpdGlvbiBwb3NpdGlvbiwgYm9vbGVhbiBwYXJzZUJpZ0RlY2ltYWwpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIHNldERlY2ltYWxGb3JtYXRTeW1ib2xzKGludCBhZGRyLCBTdHJpbmcgY3VycmVuY3lTeW1ib2wsCisgICAgICAgICAgICBjaGFyIGRlY2ltYWxTZXBhcmF0b3IsIGNoYXIgZGlnaXQsIFN0cmluZyBleHBvbmVudFNlcGFyYXRvciwgY2hhciBncm91cGluZ1NlcGFyYXRvciwKKyAgICAgICAgICAgIFN0cmluZyBpbmZpbml0eSwgU3RyaW5nIGludGVybmF0aW9uYWxDdXJyZW5jeVN5bWJvbCwgY2hhciBtaW51c1NpZ24sCisgICAgICAgICAgICBjaGFyIG1vbmV0YXJ5RGVjaW1hbFNlcGFyYXRvciwgU3RyaW5nIG5hbiwgY2hhciBwYXR0ZXJuU2VwYXJhdG9yLCBjaGFyIHBlcmNlbnQsCisgICAgICAgICAgICBjaGFyIHBlck1pbGwsIGNoYXIgemVyb0RpZ2l0KTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgdm9pZCBzZXRTeW1ib2woaW50IGFkZHIsIGludCBzeW1ib2wsIFN0cmluZyBzdHIpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIHNldEF0dHJpYnV0ZShpbnQgYWRkciwgaW50IHN5bWJvbCwgaW50IGkpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIHNldFJvdW5kaW5nTW9kZShpbnQgYWRkciwgaW50IHJvdW5kaW5nTW9kZSwgZG91YmxlIHJvdW5kaW5nSW5jcmVtZW50KTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgdm9pZCBzZXRUZXh0QXR0cmlidXRlKGludCBhZGRyLCBpbnQgc3ltYm9sLCBTdHJpbmcgc3RyKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgU3RyaW5nIHRvUGF0dGVybkltcGwoaW50IGFkZHIsIGJvb2xlYW4gbG9jYWxpemVkKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2ljdS9OYXRpdmVJRE4uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2ljdS9OYXRpdmVJRE4uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YmY1Y2IxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaWN1L05hdGl2ZUlETi5qYXZhCkBAIC0wLDAgKzEsNDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuaWN1OworCitwdWJsaWMgZmluYWwgY2xhc3MgTmF0aXZlSUROIHsKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b0FTQ0lJKFN0cmluZyBzLCBpbnQgZmxhZ3MpIHsKKyAgICAgICAgcmV0dXJuIGNvbnZlcnQocywgZmxhZ3MsIHRydWUpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvVW5pY29kZShTdHJpbmcgcywgaW50IGZsYWdzKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gY29udmVydChzLCBmbGFncywgZmFsc2UpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIFRoZSBSSSBkb2N1bWVudGF0aW9uIGV4cGxpY2l0bHkgc3RhdGVzIHRoYXQgdGhpcyBtZXRob2QgY2FuJ3QgZmFpbC4KKyAgICAgICAgICAgIC8vIElDVTRDIGRpc2FncmVlcywgYXMgZG9lcyB0aGUgUkkgaW4gcHJhY3RpY2UuCisgICAgICAgICAgICAvLyBUaGUgUkkganVzdCByZXR1cm5zIHRoZSBpbnB1dCBzdHJpbmcgaWYgaXQgY2FuJ3QKKyAgICAgICAgICAgIHJldHVybiBzOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGNvbnZlcnQoU3RyaW5nIHMsIGludCBmbGFncywgYm9vbGVhbiB0b0FzY2lpKSB7CisgICAgICAgIGlmIChzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb252ZXJ0SW1wbChzLCBmbGFncywgdG9Bc2NpaSk7CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBTdHJpbmcgY29udmVydEltcGwoU3RyaW5nIHMsIGludCBmbGFncywgYm9vbGVhbiB0b0FzY2lpKTsKKworICAgIHByaXZhdGUgTmF0aXZlSUROKCkge30KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2ljdS9OYXRpdmVOb3JtYWxpemVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvTmF0aXZlTm9ybWFsaXplci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1ZDhkYTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvTmF0aXZlTm9ybWFsaXplci5qYXZhCkBAIC0wLDAgKzEsNDcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuaWN1OworCitpbXBvcnQgamF2YS50ZXh0Lk5vcm1hbGl6ZXIuRm9ybTsKKworcHVibGljIGZpbmFsIGNsYXNzIE5hdGl2ZU5vcm1hbGl6ZXIgeworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc05vcm1hbGl6ZWQoQ2hhclNlcXVlbmNlIHNyYywgRm9ybSBmb3JtKSB7CisgICAgICAgIHJldHVybiBpc05vcm1hbGl6ZWRJbXBsKHNyYy50b1N0cmluZygpLCB0b1VOb3JtYWxpemF0aW9uTW9kZShmb3JtKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgbm9ybWFsaXplKENoYXJTZXF1ZW5jZSBzcmMsIEZvcm0gZm9ybSkgeworICAgICAgICByZXR1cm4gbm9ybWFsaXplSW1wbChzcmMudG9TdHJpbmcoKSwgdG9VTm9ybWFsaXphdGlvbk1vZGUoZm9ybSkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGludCB0b1VOb3JtYWxpemF0aW9uTW9kZShGb3JtIGZvcm0pIHsKKyAgICAgICAgLy8gVHJhbnNsYXRlcyBKYXZhIGVudW0gY29uc3RhbnRzIHRvIElDVSBpbnQgY29uc3RhbnRzLgorICAgICAgICAvLyBTZWUgVU5vcm1hbGl6YXRpb25Nb2RlIGluICJ1bmljb2RlL3Vub3JtLmgiLiBTdGFibGUgQVBJIHNpbmNlIElDVSAyLjAuCisgICAgICAgIHN3aXRjaCAoZm9ybSkgeworICAgICAgICBjYXNlIE5GQzogcmV0dXJuIDQ7CisgICAgICAgIGNhc2UgTkZEOiByZXR1cm4gMjsKKyAgICAgICAgY2FzZSBORktDOiByZXR1cm4gNTsKKyAgICAgICAgY2FzZSBORktEOiByZXR1cm4gMzsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoInVua25vd24gTm9ybWFsaXplci5Gb3JtICIgKyBmb3JtKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgU3RyaW5nIG5vcm1hbGl6ZUltcGwoU3RyaW5nIHNyYywgaW50IGZvcm0pOworCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gaXNOb3JtYWxpemVkSW1wbChTdHJpbmcgc3JjLCBpbnQgZm9ybSk7CisKKyAgICBwcml2YXRlIE5hdGl2ZU5vcm1hbGl6ZXIoKSB7fQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaWN1L05hdGl2ZVBsdXJhbFJ1bGVzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvTmF0aXZlUGx1cmFsUnVsZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40N2NjNzZiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaWN1L05hdGl2ZVBsdXJhbFJ1bGVzLmphdmEKQEAgLTAsMCArMSw2NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pY3U7CisKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCisvKioKKyAqIFByb3ZpZGVzIGFjY2VzcyB0byBJQ1UncworICogPGEgaHJlZj0iaHR0cDovL2ljdS1wcm9qZWN0Lm9yZy9hcGlyZWYvaWN1NGMvY2xhc3NQbHVyYWxSdWxlcy5odG1sIj5QbHVyYWxSdWxlczwvYT4gY2xhc3MuCisgKiBUaGlzIGlzIG5vdCBuZWNlc3NhcnkgZm9yIEphdmEgQVBJLCBidXQgaXMgdXNlZCBieSBmcmFtZXdvcmtzL2Jhc2UncyByZXNvdXJjZXMgc3lzdGVtIHRvCisgKiBlYXNlIGxvY2FsaXphdGlvbiBvZiBzdHJpbmdzIHRvIGxhbmd1YWdlcyB3aXRoIGNvbXBsZXggZ3JhbW1hdGljYWwgcnVsZXMgcmVnYXJkaW5nIG51bWJlci4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE5hdGl2ZVBsdXJhbFJ1bGVzIHsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBaRVJPICA9IDA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FICAgPSAxOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRXTyAgID0gMjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGRVcgICA9IDM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFOWSAgPSA0OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9USEVSID0gNTsKKworICAgIHByaXZhdGUgZmluYWwgaW50IGFkZHJlc3M7CisKKyAgICBwcml2YXRlIE5hdGl2ZVBsdXJhbFJ1bGVzKGludCBhZGRyZXNzKSB7CisgICAgICAgIHRoaXMuYWRkcmVzcyA9IGFkZHJlc3M7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbGl6ZUltcGwoYWRkcmVzcyk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzdXBlci5maW5hbGl6ZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBOYXRpdmVQbHVyYWxSdWxlcyBmb3JMb2NhbGUoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICByZXR1cm4gbmV3IE5hdGl2ZVBsdXJhbFJ1bGVzKGZvckxvY2FsZUltcGwobG9jYWxlLnRvU3RyaW5nKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb25zdGFudCBkZWZpbmVkIGluIHRoaXMgY2xhc3MgY29ycmVzcG9uZGluZworICAgICAqIHRvIHRoZSBmaXJzdCBydWxlIHRoYXQgbWF0Y2hlcyB0aGUgZ2l2ZW4gdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGludCBxdWFudGl0eUZvckludChpbnQgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIHF1YW50aXR5Rm9ySW50SW1wbChhZGRyZXNzLCB2YWx1ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIHZvaWQgZmluYWxpemVJbXBsKGludCBhZGRyZXNzKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IGZvckxvY2FsZUltcGwoU3RyaW5nIGxvY2FsZU5hbWUpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgcXVhbnRpdHlGb3JJbnRJbXBsKGludCBhZGRyZXNzLCBpbnQgdmFsdWUpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaWN1L1J1bGVCYXNlZENvbGxhdG9ySUNVLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvUnVsZUJhc2VkQ29sbGF0b3JJQ1UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMDM2Yzk4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaWN1L1J1bGVCYXNlZENvbGxhdG9ySUNVLmphdmEKQEAgLTAsMCArMSwxNTQgQEAKKy8qKgorKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorKiBDb3B5cmlnaHQgKEMpIDE5OTYtMjAwNSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgICAgKgorKiBvdGhlcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgorKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorKgorKgorKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorKi8KKworcGFja2FnZSBsaWJjb3JlLmljdTsKKworaW1wb3J0IGphdmEudGV4dC5DaGFyYWN0ZXJJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnRleHQuQ29sbGF0aW9uS2V5OworaW1wb3J0IGphdmEudGV4dC5QYXJzZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCitwdWJsaWMgZmluYWwgY2xhc3MgUnVsZUJhc2VkQ29sbGF0b3JJQ1UgaW1wbGVtZW50cyBDbG9uZWFibGUgeworICAgIC8vIFZhbHVlcyBmcm9tIHRoZSBuYXRpdmUgVUNvbEF0dHJpYnV0ZVZhbHVlIGVudW0uCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkFMVUVfREVGQVVMVCA9IC0xOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZBTFVFX1BSSU1BUlkgPSAwOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZBTFVFX1NFQ09OREFSWSA9IDE7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkFMVUVfVEVSVElBUlkgPSAyOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZBTFVFX0RFRkFVTFRfU1RSRU5HVEggPSBWQUxVRV9URVJUSUFSWTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQUxVRV9RVUFURVJOQVJZID0gMzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQUxVRV9JREVOVElDQUwgPSAxNTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQUxVRV9PRkYgPSAxNjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQUxVRV9PTiA9IDE3OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZBTFVFX1NISUZURUQgPSAyMDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQUxVRV9OT05fSUdOT1JBQkxFID0gMjE7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkFMVUVfTE9XRVJfRklSU1QgPSAyNDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQUxVRV9VUFBFUl9GSVJTVCA9IDI1OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZBTFVFX09OX1dJVEhPVVRfSEFOR1VMID0gMjg7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkFMVUVfQVRUUklCVVRFX1ZBTFVFX0NPVU5UID0gMjk7CisKKyAgICAvLyBWYWx1ZXMgZnJvbSB0aGUgVUNvbEF0dHJpYnV0ZSBlbnVtLgorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZSRU5DSF9DT0xMQVRJT04gPSAwOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFMVEVSTkFURV9IQU5ETElORyA9IDE7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0FTRV9GSVJTVCA9IDI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0FTRV9MRVZFTCA9IDM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVDT01QT1NJVElPTl9NT0RFID0gNDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJFTkdUSCA9IDU7CisKKyAgICAvLyBUaGUgYWRkcmVzcyBvZiB0aGUgSUNVNEMgbmF0aXZlIHBlZXIuCisgICAgcHJpdmF0ZSBpbnQgYWRkcmVzczsKKworICAgIHB1YmxpYyBSdWxlQmFzZWRDb2xsYXRvcklDVShTdHJpbmcgcnVsZXMpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChydWxlcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBhZGRyZXNzID0gTmF0aXZlQ29sbGF0aW9uLm9wZW5Db2xsYXRvckZyb21SdWxlcyhydWxlcywgVkFMVUVfT0ZGLCBWQUxVRV9ERUZBVUxUX1NUUkVOR1RIKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUnVsZUJhc2VkQ29sbGF0b3JJQ1UoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBhZGRyZXNzID0gTmF0aXZlQ29sbGF0aW9uLm9wZW5Db2xsYXRvcihsb2NhbGUudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBSdWxlQmFzZWRDb2xsYXRvcklDVShpbnQgYWRkcmVzcykgeworICAgICAgICB0aGlzLmFkZHJlc3MgPSBhZGRyZXNzOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHJldHVybiBuZXcgUnVsZUJhc2VkQ29sbGF0b3JJQ1UoTmF0aXZlQ29sbGF0aW9uLnNhZmVDbG9uZShhZGRyZXNzKSk7CisgICAgfQorCisgICAgcHVibGljIGludCBjb21wYXJlKFN0cmluZyBzb3VyY2UsIFN0cmluZyB0YXJnZXQpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUNvbGxhdGlvbi5jb21wYXJlKGFkZHJlc3MsIHNvdXJjZSwgdGFyZ2V0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldERlY29tcG9zaXRpb24oKSB7CisgICAgICAgIHJldHVybiBOYXRpdmVDb2xsYXRpb24uZ2V0QXR0cmlidXRlKGFkZHJlc3MsIERFQ09NUE9TSVRJT05fTU9ERSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RGVjb21wb3NpdGlvbihpbnQgbW9kZSkgeworICAgICAgICBOYXRpdmVDb2xsYXRpb24uc2V0QXR0cmlidXRlKGFkZHJlc3MsIERFQ09NUE9TSVRJT05fTU9ERSwgbW9kZSk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRTdHJlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUNvbGxhdGlvbi5nZXRBdHRyaWJ1dGUoYWRkcmVzcywgU1RSRU5HVEgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN0cmVuZ3RoKGludCBzdHJlbmd0aCkgeworICAgICAgICBOYXRpdmVDb2xsYXRpb24uc2V0QXR0cmlidXRlKGFkZHJlc3MsIFNUUkVOR1RILCBzdHJlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0QXR0cmlidXRlKGludCB0eXBlLCBpbnQgdmFsdWUpIHsKKyAgICAgICAgTmF0aXZlQ29sbGF0aW9uLnNldEF0dHJpYnV0ZShhZGRyZXNzLCB0eXBlLCB2YWx1ZSk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRBdHRyaWJ1dGUoaW50IHR5cGUpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUNvbGxhdGlvbi5nZXRBdHRyaWJ1dGUoYWRkcmVzcywgdHlwZSk7CisgICAgfQorCisgICAgcHVibGljIENvbGxhdGlvbktleSBnZXRDb2xsYXRpb25LZXkoU3RyaW5nIHNvdXJjZSkgeworICAgICAgICBpZiAoc291cmNlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSBrZXkgPSBOYXRpdmVDb2xsYXRpb24uZ2V0U29ydEtleShhZGRyZXNzLCBzb3VyY2UpOworICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgQ29sbGF0aW9uS2V5SUNVKHNvdXJjZSwga2V5KTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFJ1bGVzKCkgeworICAgICAgICByZXR1cm4gTmF0aXZlQ29sbGF0aW9uLmdldFJ1bGVzKGFkZHJlc3MpOworICAgIH0KKworICAgIHB1YmxpYyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3JJQ1UgZ2V0Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKFN0cmluZyBzb3VyY2UpIHsKKyAgICAgICAgcmV0dXJuIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcklDVS5nZXRJbnN0YW5jZShhZGRyZXNzLCBzb3VyY2UpOworICAgIH0KKworICAgIHB1YmxpYyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3JJQ1UgZ2V0Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKENoYXJhY3Rlckl0ZXJhdG9yIGl0KSB7CisgICAgICAgIC8vIFdlIG9ubHkgaW1wbGVtZW50IHRoZSBTdHJpbmctYmFzZWQgQVBJLCBzbyBidWlsZCBhIHN0cmluZyBmcm9tIHRoZSBpdGVyYXRvci4KKyAgICAgICAgcmV0dXJuIGdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjaGFyYWN0ZXJJdGVyYXRvclRvU3RyaW5nKGl0KSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgY2hhcmFjdGVySXRlcmF0b3JUb1N0cmluZyhDaGFyYWN0ZXJJdGVyYXRvciBpdCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGZvciAoY2hhciBjaCA9IGl0LmN1cnJlbnQoKTsgY2ggIT0gQ2hhcmFjdGVySXRlcmF0b3IuRE9ORTsgY2ggPSBpdC5uZXh0KCkpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoY2gpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIDQyOyAvLyBOby1vbmUgdXNlcyBSdWxlQmFzZWRDb2xsYXRvcklDVSBhcyBhIGhhc2gga2V5LgorICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhTdHJpbmcgc291cmNlLCBTdHJpbmcgdGFyZ2V0KSB7CisgICAgICAgIHJldHVybiAoY29tcGFyZShzb3VyY2UsIHRhcmdldCkgPT0gMCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgIGlmIChvYmplY3QgPT0gIHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghKG9iamVjdCBpbnN0YW5jZW9mIFJ1bGVCYXNlZENvbGxhdG9ySUNVKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9ySUNVIHJocyA9IChSdWxlQmFzZWRDb2xsYXRvcklDVSkgb2JqZWN0OworICAgICAgICByZXR1cm4gZ2V0UnVsZXMoKS5lcXVhbHMocmhzLmdldFJ1bGVzKCkpICYmCisgICAgICAgICAgICAgICAgZ2V0U3RyZW5ndGgoKSA9PSByaHMuZ2V0U3RyZW5ndGgoKSAmJgorICAgICAgICAgICAgICAgIGdldERlY29tcG9zaXRpb24oKSA9PSByaHMuZ2V0RGVjb21wb3NpdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ29sbGF0aW9uLmNsb3NlQ29sbGF0b3IoYWRkcmVzcyk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzdXBlci5maW5hbGl6ZSgpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaWN1L1RpbWVab25lcy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaWN1L1RpbWVab25lcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlMjc5ODUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pY3UvVGltZVpvbmVzLmphdmEKQEAgLTAsMCArMSwxNDMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuaWN1OworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29tcGFyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5UaW1lWm9uZTsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuQmFzaWNMcnVDYWNoZTsKKworLyoqCisgKiBQcm92aWRlcyBhY2Nlc3MgdG8gSUNVJ3MgdGltZSB6b25lIGRhdGEuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBUaW1lWm9uZXMgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGF2YWlsYWJsZVRpbWVab25lcyA9IFRpbWVab25lLmdldEF2YWlsYWJsZUlEcygpOworCisgICAgLyoKKyAgICAgKiBPZmZzZXRzIGludG8gdGhlIGFycmF5cyByZXR1cm5lZCBieSBEYXRlRm9ybWF0U3ltYm9scy5nZXRab25lU3RyaW5ncy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTFNPTl9OQU1FID0gMDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX05BTUUgPSAxOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1JUX05BTUUgPSAyOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfTkFNRV9EU1QgPSAzOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1JUX05BTUVfRFNUID0gNDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOQU1FX0NPVU5UID0gNTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFpvbmVTdHJpbmdzQ2FjaGUgY2FjaGVkWm9uZVN0cmluZ3MgPSBuZXcgWm9uZVN0cmluZ3NDYWNoZSgpOworICAgIHN0YXRpYyB7CisgICAgICAgIC8vIEVuc3VyZSB0aGF0IHdlIHB1bGwgaW4gdGhlIHpvbmUgc3RyaW5ncyBmb3IgdGhlIHJvb3QgbG9jYWxlLCBlbl9VUywgYW5kIHRoZQorICAgICAgICAvLyB1c2VyJ3MgZGVmYXVsdCBsb2NhbGUuIChBbGwgZGV2aWNlcyBtdXN0IHN1cHBvcnQgdGhlIHJvb3QgbG9jYWxlIGFuZCBlbl9VUywKKyAgICAgICAgLy8gYW5kIHRoZXkncmUgdXNlZCBmb3IgdmFyaW91cyBzeXN0ZW0gdGhpbmdzIGxpa2UgSFRUUCBoZWFkZXJzLikgUHJlLXBvcHVsYXRpbmcKKyAgICAgICAgLy8gdGhlIGNhY2hlIGlzIGVzcGVjaWFsbHkgdXNlZnVsIG9uIEFuZHJvaWQgYmVjYXVzZSB3ZSdsbCBzaGFyZSB0aGlzIHZpYSB0aGUgWnlnb3RlLgorICAgICAgICBjYWNoZWRab25lU3RyaW5ncy5nZXQoTG9jYWxlLlJPT1QpOworICAgICAgICBjYWNoZWRab25lU3RyaW5ncy5nZXQoTG9jYWxlLlVTKTsKKyAgICAgICAgY2FjaGVkWm9uZVN0cmluZ3MuZ2V0KExvY2FsZS5nZXREZWZhdWx0KCkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgWm9uZVN0cmluZ3NDYWNoZSBleHRlbmRzIEJhc2ljTHJ1Q2FjaGU8TG9jYWxlLCBTdHJpbmdbXVtdPiB7CisgICAgICAgIC8vIERlLWR1cGxpY2F0ZSB0aGUgc3RyaW5ncyAoaHR0cDovL2IvMjY3MjA1NykuCisgICAgICAgIHByaXZhdGUgZmluYWwgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4gaW50ZXJuVGFibGUgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKworICAgICAgICBwdWJsaWMgWm9uZVN0cmluZ3NDYWNoZSgpIHsKKyAgICAgICAgICAgIC8vIFdlIG1ha2Ugcm9vbSBmb3IgYWxsIHRoZSB0aW1lIHpvbmVzIGtub3duIHRvIHRoZSBzeXN0ZW0sIHNpbmNlIGVhY2ggc2V0IG9mIHN0cmluZ3MKKyAgICAgICAgICAgIC8vIGlzbid0IHBhcnRpY3VsYXJseSBsYXJnZSAoYW5kIHdlIHJlbW92ZSBkdXBsaWNhdGVzKSwgYnV0IGlzIGN1cnJlbnRseSAoSG9uZXljb21iKQorICAgICAgICAgICAgLy8gcmVhbGx5IGV4cGVuc2l2ZSB0byBjb21wdXRlLgorICAgICAgICAgICAgLy8gSWYgeW91IGNoYW5nZSB0aGlzLCB5b3UgbWlnaHQgd2FudCB0byBjaGFuZ2UgdGhlIHNjb3BlIG9mIHRoZSBpbnRlcm4gdGFibGUgdG9vLgorICAgICAgICAgICAgc3VwZXIoYXZhaWxhYmxlVGltZVpvbmVzLmxlbmd0aCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIFN0cmluZ1tdW10gY3JlYXRlKExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgICAgIGxvbmcgc3RhcnQsIG5hdGl2ZVN0YXJ0OworICAgICAgICAgICAgc3RhcnQgPSBuYXRpdmVTdGFydCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICAgICAgU3RyaW5nW11bXSByZXN1bHQgPSBnZXRab25lU3RyaW5nc0ltcGwobG9jYWxlLnRvU3RyaW5nKCksIGF2YWlsYWJsZVRpbWVab25lcyk7CisgICAgICAgICAgICBsb25nIG5hdGl2ZUVuZCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICAgICAgaW50ZXJuU3RyaW5ncyhyZXN1bHQpOworICAgICAgICAgICAgLy8gRW5kaW5nIHVwIGluIHRoaXMgbWV0aG9kIHRvbyBvZnRlbiBpcyBhbiBlYXN5IHdheSB0byBtYWtlIHlvdXIgYXBwIHNsb3csIHNvIHdlIGVuc3VyZQorICAgICAgICAgICAgLy8gaXQncyBlYXN5IHRvIHRlbGwgZnJvbSB0aGUgbG9nIChhKSB3aGF0IHdlIHdlcmUgZG9pbmcsIChiKSBob3cgbG9uZyBpdCB0b29rLCBhbmQKKyAgICAgICAgICAgIC8vIChjKSB0aGF0IGl0J3MgYWxsIElDVSdzIGZhdWx0LgorICAgICAgICAgICAgbG9uZyBlbmQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgICAgIGxvbmcgZHVyYXRpb24gPSBlbmQgLSBzdGFydDsKKyAgICAgICAgICAgIGxvbmcgbmF0aXZlRHVyYXRpb24gPSBuYXRpdmVFbmQgLSBuYXRpdmVTdGFydDsKKyAgICAgICAgICAgIFN5c3RlbS5sb2dJKCJMb2FkZWQgdGltZSB6b25lIG5hbWVzIGZvciAiICsgbG9jYWxlICsgIiBpbiAiICsgZHVyYXRpb24gKyAibXMiICsKKyAgICAgICAgICAgICAgICAgICAgIiAoIiArIG5hdGl2ZUR1cmF0aW9uICsgIm1zIGluIElDVSkiKTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIGludGVyblN0cmluZ3MoU3RyaW5nW11bXSByZXN1bHQpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVzdWx0Lmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDE7IGogPCBOQU1FX0NPVU5UOyArK2opIHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG9yaWdpbmFsID0gcmVzdWx0W2ldW2pdOworICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbm9uRHVwbGljYXRlID0gaW50ZXJuVGFibGUuZ2V0KG9yaWdpbmFsKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5vbkR1cGxpY2F0ZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcm5UYWJsZS5wdXQob3JpZ2luYWwsIG9yaWdpbmFsKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFtpXVtqXSA9IG5vbkR1cGxpY2F0ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbXBhcmF0b3I8U3RyaW5nW10+IFpPTkVfU1RSSU5HU19DT01QQVJBVE9SID0gbmV3IENvbXBhcmF0b3I8U3RyaW5nW10+KCkgeworICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoU3RyaW5nW10gbGhzLCBTdHJpbmdbXSByaHMpIHsKKyAgICAgICAgICAgIHJldHVybiBsaHNbT0xTT05fTkFNRV0uY29tcGFyZVRvKHJoc1tPTFNPTl9OQU1FXSk7CisgICAgICAgIH0KKyAgICB9OworCisgICAgcHJpdmF0ZSBUaW1lWm9uZXMoKSB7fQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXBwcm9wcmlhdGUgc3RyaW5nIGZyb20gJ3pvbmVTdHJpbmdzJy4gVXNlZCB3aXRoIGdldFpvbmVTdHJpbmdzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldERpc3BsYXlOYW1lKFN0cmluZ1tdW10gem9uZVN0cmluZ3MsIFN0cmluZyBpZCwgYm9vbGVhbiBkYXlsaWdodCwgaW50IHN0eWxlKSB7CisgICAgICAgIFN0cmluZ1tdIG5lZWRsZSA9IG5ldyBTdHJpbmdbXSB7IGlkIH07CisgICAgICAgIGludCBpbmRleCA9IEFycmF5cy5iaW5hcnlTZWFyY2goem9uZVN0cmluZ3MsIG5lZWRsZSwgWk9ORV9TVFJJTkdTX0NPTVBBUkFUT1IpOworICAgICAgICBpZiAoaW5kZXggPj0gMCkgeworICAgICAgICAgICAgU3RyaW5nW10gcm93ID0gem9uZVN0cmluZ3NbaW5kZXhdOworICAgICAgICAgICAgaWYgKGRheWxpZ2h0KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChzdHlsZSA9PSBUaW1lWm9uZS5MT05HKSA/IHJvd1tMT05HX05BTUVfRFNUXSA6IHJvd1tTSE9SVF9OQU1FX0RTVF07CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiAoc3R5bGUgPT0gVGltZVpvbmUuTE9ORykgPyByb3dbTE9OR19OQU1FXSA6IHJvd1tTSE9SVF9OQU1FXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHRpbWUgem9uZSBzdHJpbmdzLCBhcyB1c2VkIGJ5IERhdGVGb3JtYXRTeW1ib2xzLmdldFpvbmVTdHJpbmdzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW11bXSBnZXRab25lU3RyaW5ncyhMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIGlmIChsb2NhbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgbG9jYWxlID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2FjaGVkWm9uZVN0cmluZ3MuZ2V0KGxvY2FsZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIHRoZSB0aW1lIHpvbmUgaWRzIGluIHVzZSBpbiB0aGUgY291bnRyeSBjb3JyZXNwb25kaW5nIHRvCisgICAgICogdGhlIGdpdmVuIGxvY2FsZS4gVGhpcyBpcyBub3QgbmVjZXNzYXJ5IGZvciBKYXZhIEFQSSwgYnV0IGlzIHVzZWQgYnkgdGVsZXBob255IGFzIGEKKyAgICAgKiBmYWxsYmFjay4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZ1tdIGZvckxvY2FsZShMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIHJldHVybiBmb3JDb3VudHJ5Q29kZShsb2NhbGUuZ2V0Q291bnRyeSgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgU3RyaW5nW10gZm9yQ291bnRyeUNvZGUoU3RyaW5nIGNvdW50cnlDb2RlKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgU3RyaW5nW11bXSBnZXRab25lU3RyaW5nc0ltcGwoU3RyaW5nIGxvY2FsZSwgU3RyaW5nW10gdGltZVpvbmVJZHMpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW50ZXJuYWwvU3RyaW5nUG9vbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW50ZXJuYWwvU3RyaW5nUG9vbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmZTM4ZjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pbnRlcm5hbC9TdHJpbmdQb29sLmphdmEKQEAgLTAsMCArMSw2NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pbnRlcm5hbDsKKworLyoqCisgKiBBIHBvb2wgb2Ygc3RyaW5nIGluc3RhbmNlcy4gVW5saWtlIHRoZSB7QGxpbmsgU3RyaW5nI2ludGVybigpIFZNJ3MKKyAqIGludGVybmVkIHN0cmluZ3N9LCB0aGlzIHBvb2wgcHJvdmlkZXMgbm8gZ3VhcmFudGVlIG9mIHJlZmVyZW5jZSBlcXVhbGl0eS4KKyAqIEl0IGlzIGludGVuZGVkIG9ubHkgdG8gc2F2ZSBhbGxvY2F0aW9ucy4gVGhpcyBjbGFzcyBpcyBub3QgdGhyZWFkIHNhZmUuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTdHJpbmdQb29sIHsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nW10gcG9vbCA9IG5ldyBTdHJpbmdbNTEyXTsKKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gY29udGVudEVxdWFscyhTdHJpbmcgcywgY2hhcltdIGNoYXJzLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHsKKyAgICAgICAgaWYgKHMubGVuZ3RoKCkgIT0gbGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKGNoYXJzW3N0YXJ0ICsgaV0gIT0gcy5jaGFyQXQoaSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBlcXVhbCB0byB7QGNvZGUgbmV3IFN0cmluZyhhcnJheSwgc3RhcnQsIGxlbmd0aCl9LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0KGNoYXJbXSBhcnJheSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIC8vIENvbXB1dGUgYW4gYXJiaXRyYXJ5IGhhc2ggb2YgdGhlIGNvbnRlbnQKKyAgICAgICAgaW50IGhhc2hDb2RlID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDwgc3RhcnQgKyBsZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaGFzaENvZGUgPSAoaGFzaENvZGUgKiAzMSkgKyBhcnJheVtpXTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFBpY2sgYSBidWNrZXQgdXNpbmcgRG91ZyBMZWEncyBzdXBwbGVtZW50YWwgc2Vjb25kYXJ5SGFzaCBmdW5jdGlvbiAoZnJvbSBIYXNoTWFwKQorICAgICAgICBoYXNoQ29kZSBePSAoaGFzaENvZGUgPj4+IDIwKSBeIChoYXNoQ29kZSA+Pj4gMTIpOworICAgICAgICBoYXNoQ29kZSBePSAoaGFzaENvZGUgPj4+IDcpIF4gKGhhc2hDb2RlID4+PiA0KTsKKyAgICAgICAgaW50IGluZGV4ID0gaGFzaENvZGUgJiAocG9vbC5sZW5ndGggLSAxKTsKKworICAgICAgICBTdHJpbmcgcG9vbGVkID0gcG9vbFtpbmRleF07CisgICAgICAgIGlmIChwb29sZWQgIT0gbnVsbCAmJiBjb250ZW50RXF1YWxzKHBvb2xlZCwgYXJyYXksIHN0YXJ0LCBsZW5ndGgpKSB7CisgICAgICAgICAgICByZXR1cm4gcG9vbGVkOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IG5ldyBTdHJpbmcoYXJyYXksIHN0YXJ0LCBsZW5ndGgpOworICAgICAgICBwb29sW2luZGV4XSA9IHJlc3VsdDsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9Bc3luY2hyb25vdXNDbG9zZU1vbml0b3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL0FzeW5jaHJvbm91c0Nsb3NlTW9uaXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYyZWVjMjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9Bc3luY2hyb25vdXNDbG9zZU1vbml0b3IuamF2YQpAQCAtMCwwICsxLDI2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmlvOworCitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKKworcHVibGljIGZpbmFsIGNsYXNzIEFzeW5jaHJvbm91c0Nsb3NlTW9uaXRvciB7CisgICAgcHJpdmF0ZSBBc3luY2hyb25vdXNDbG9zZU1vbml0b3IoKSB7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBzaWduYWxCbG9ja2VkVGhyZWFkcyhGaWxlRGVzY3JpcHRvciBmZCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9CYXNlNjQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL0Jhc2U2NC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU0NjQzYjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9CYXNlNjQuamF2YQpAQCAtMCwwICsxLDE2MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKi8KKworcGFja2FnZSBsaWJjb3JlLmlvOworCitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0czsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuRW1wdHlBcnJheTsKKworLyoqCisgKiA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMDQ1LnR4dCI+QmFzZTY0PC9hPiBlbmNvZGVyL2RlY29kZXIuCisgKiBJbiB2aW9sYXRpb24gb2YgdGhlIFJGQywgdGhpcyBlbmNvZGVyIGRvZXNuJ3Qgd3JhcCBsaW5lcyBhdCA3NiBjb2x1bW5zLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQmFzZTY0IHsKKyAgICBwcml2YXRlIEJhc2U2NCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBkZWNvZGUoYnl0ZVtdIGluKSB7CisgICAgICAgIHJldHVybiBkZWNvZGUoaW4sIGluLmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gZGVjb2RlKGJ5dGVbXSBpbiwgaW50IGxlbikgeworICAgICAgICAvLyBhcHByb3hpbWF0ZSBvdXRwdXQgbGVuZ3RoCisgICAgICAgIGludCBsZW5ndGggPSBsZW4gLyA0ICogMzsKKyAgICAgICAgLy8gcmV0dXJuIGFuIGVtcHR5IGFycmF5IG9uIGVtcHR5IG9yIHNob3J0IGlucHV0IHdpdGhvdXQgcGFkZGluZworICAgICAgICBpZiAobGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBFbXB0eUFycmF5LkJZVEU7CisgICAgICAgIH0KKyAgICAgICAgLy8gdGVtcG9yYXJ5IGFycmF5CisgICAgICAgIGJ5dGVbXSBvdXQgPSBuZXcgYnl0ZVtsZW5ndGhdOworICAgICAgICAvLyBudW1iZXIgb2YgcGFkZGluZyBjaGFyYWN0ZXJzICgnPScpCisgICAgICAgIGludCBwYWQgPSAwOworICAgICAgICBieXRlIGNocjsKKyAgICAgICAgLy8gY29tcHV0ZSB0aGUgbnVtYmVyIG9mIHRoZSBwYWRkaW5nIGNoYXJhY3RlcnMKKyAgICAgICAgLy8gYW5kIGFkanVzdCB0aGUgbGVuZ3RoIG9mIHRoZSBpbnB1dAorICAgICAgICBmb3IgKDs7bGVuLS0pIHsKKyAgICAgICAgICAgIGNociA9IGluW2xlbi0xXTsKKyAgICAgICAgICAgIC8vIHNraXAgdGhlIG5ldXRyYWwgY2hhcmFjdGVycworICAgICAgICAgICAgaWYgKChjaHIgPT0gJ1xuJykgfHwgKGNociA9PSAnXHInKSB8fAorICAgICAgICAgICAgICAgICAgICAoY2hyID09ICcgJykgfHwgKGNociA9PSAnXHQnKSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGNociA9PSAnPScpIHsKKyAgICAgICAgICAgICAgICBwYWQrKzsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gaW5kZXggaW4gdGhlIG91dHB1dCBhcnJheQorICAgICAgICBpbnQgb3V0SW5kZXggPSAwOworICAgICAgICAvLyBpbmRleCBpbiB0aGUgaW5wdXQgYXJyYXkKKyAgICAgICAgaW50IGluSW5kZXggPSAwOworICAgICAgICAvLyBob2xkcyB0aGUgdmFsdWUgb2YgdGhlIGlucHV0IGNoYXJhY3RlcgorICAgICAgICBpbnQgYml0cyA9IDA7CisgICAgICAgIC8vIGhvbGRzIHRoZSB2YWx1ZSBvZiB0aGUgaW5wdXQgcXVhbnR1bQorICAgICAgICBpbnQgcXVhbnR1bSA9IDA7CisgICAgICAgIGZvciAoaW50IGk9MDsgaTxsZW47IGkrKykgeworICAgICAgICAgICAgY2hyID0gaW5baV07CisgICAgICAgICAgICAvLyBza2lwIHRoZSBuZXV0cmFsIGNoYXJhY3RlcnMKKyAgICAgICAgICAgIGlmICgoY2hyID09ICdcbicpIHx8IChjaHIgPT0gJ1xyJykgfHwKKyAgICAgICAgICAgICAgICAgICAgKGNociA9PSAnICcpIHx8IChjaHIgPT0gJ1x0JykpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICgoY2hyID49ICdBJykgJiYgKGNociA8PSAnWicpKSB7CisgICAgICAgICAgICAgICAgLy8gY2hhciBBU0NJSSB2YWx1ZQorICAgICAgICAgICAgICAgIC8vICBBICAgIDY1ICAgIDAKKyAgICAgICAgICAgICAgICAvLyAgWiAgICA5MCAgICAyNSAoQVNDSUkgLSA2NSkKKyAgICAgICAgICAgICAgICBiaXRzID0gY2hyIC0gNjU7CisgICAgICAgICAgICB9IGVsc2UgaWYgKChjaHIgPj0gJ2EnKSAmJiAoY2hyIDw9ICd6JykpIHsKKyAgICAgICAgICAgICAgICAvLyBjaGFyIEFTQ0lJIHZhbHVlCisgICAgICAgICAgICAgICAgLy8gIGEgICAgOTcgICAgMjYKKyAgICAgICAgICAgICAgICAvLyAgeiAgICAxMjIgICA1MSAoQVNDSUkgLSA3MSkKKyAgICAgICAgICAgICAgICBiaXRzID0gY2hyIC0gNzE7CisgICAgICAgICAgICB9IGVsc2UgaWYgKChjaHIgPj0gJzAnKSAmJiAoY2hyIDw9ICc5JykpIHsKKyAgICAgICAgICAgICAgICAvLyBjaGFyIEFTQ0lJIHZhbHVlCisgICAgICAgICAgICAgICAgLy8gIDAgICAgNDggICAgNTIKKyAgICAgICAgICAgICAgICAvLyAgOSAgICA1NyAgICA2MSAoQVNDSUkgKyA0KQorICAgICAgICAgICAgICAgIGJpdHMgPSBjaHIgKyA0OworICAgICAgICAgICAgfSBlbHNlIGlmIChjaHIgPT0gJysnKSB7CisgICAgICAgICAgICAgICAgYml0cyA9IDYyOworICAgICAgICAgICAgfSBlbHNlIGlmIChjaHIgPT0gJy8nKSB7CisgICAgICAgICAgICAgICAgYml0cyA9IDYzOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIGFwcGVuZCB0aGUgdmFsdWUgdG8gdGhlIHF1YW50dW0KKyAgICAgICAgICAgIHF1YW50dW0gPSAocXVhbnR1bSA8PCA2KSB8IChieXRlKSBiaXRzOworICAgICAgICAgICAgaWYgKGluSW5kZXglNCA9PSAzKSB7CisgICAgICAgICAgICAgICAgLy8gNCBjaGFyYWN0ZXJzIHdlcmUgcmVhZCwgc28gbWFrZSB0aGUgb3V0cHV0OgorICAgICAgICAgICAgICAgIG91dFtvdXRJbmRleCsrXSA9IChieXRlKSAocXVhbnR1bSA+PiAxNik7CisgICAgICAgICAgICAgICAgb3V0W291dEluZGV4KytdID0gKGJ5dGUpIChxdWFudHVtID4+IDgpOworICAgICAgICAgICAgICAgIG91dFtvdXRJbmRleCsrXSA9IChieXRlKSBxdWFudHVtOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW5JbmRleCsrOworICAgICAgICB9CisgICAgICAgIGlmIChwYWQgPiAwKSB7CisgICAgICAgICAgICAvLyBhZGp1c3QgdGhlIHF1YW50dW0gdmFsdWUgYWNjb3JkaW5nIHRvIHRoZSBwYWRkaW5nCisgICAgICAgICAgICBxdWFudHVtID0gcXVhbnR1bSA8PCAoNipwYWQpOworICAgICAgICAgICAgLy8gbWFrZSBvdXRwdXQKKyAgICAgICAgICAgIG91dFtvdXRJbmRleCsrXSA9IChieXRlKSAocXVhbnR1bSA+PiAxNik7CisgICAgICAgICAgICBpZiAocGFkID09IDEpIHsKKyAgICAgICAgICAgICAgICBvdXRbb3V0SW5kZXgrK10gPSAoYnl0ZSkgKHF1YW50dW0gPj4gOCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gY3JlYXRlIHRoZSByZXN1bHRpbmcgYXJyYXkKKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW291dEluZGV4XTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShvdXQsIDAsIHJlc3VsdCwgMCwgb3V0SW5kZXgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBtYXAgPSBuZXcgYnl0ZVtdCisgICAgICAgIHsnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnLCAnRycsICdIJywgJ0knLCAnSicsICdLJywgJ0wnLCAnTScsICdOJywKKyAgICAgICAgICdPJywgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsICdVJywgJ1YnLCAnVycsICdYJywgJ1knLCAnWicsICdhJywgJ2InLAorICAgICAgICAgJ2MnLCAnZCcsICdlJywgJ2YnLCAnZycsICdoJywgJ2knLCAnaicsICdrJywgJ2wnLCAnbScsICduJywgJ28nLCAncCcsCisgICAgICAgICAncScsICdyJywgJ3MnLCAndCcsICd1JywgJ3YnLCAndycsICd4JywgJ3knLCAneicsICcwJywgJzEnLCAnMicsICczJywKKyAgICAgICAgICc0JywgJzUnLCAnNicsICc3JywgJzgnLCAnOScsICcrJywgJy8nfTsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGVuY29kZShieXRlW10gaW4pIHsKKyAgICAgICAgaW50IGxlbmd0aCA9IChpbi5sZW5ndGggKyAyKSAqIDQgLyAzOworICAgICAgICBieXRlW10gb3V0ID0gbmV3IGJ5dGVbbGVuZ3RoXTsKKyAgICAgICAgaW50IGluZGV4ID0gMCwgZW5kID0gaW4ubGVuZ3RoIC0gaW4ubGVuZ3RoICUgMzsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbmQ7IGkgKz0gMykgeworICAgICAgICAgICAgb3V0W2luZGV4KytdID0gbWFwWyhpbltpXSAmIDB4ZmYpID4+IDJdOworICAgICAgICAgICAgb3V0W2luZGV4KytdID0gbWFwWygoaW5baV0gJiAweDAzKSA8PCA0KSB8ICgoaW5baSsxXSAmIDB4ZmYpID4+IDQpXTsKKyAgICAgICAgICAgIG91dFtpbmRleCsrXSA9IG1hcFsoKGluW2krMV0gJiAweDBmKSA8PCAyKSB8ICgoaW5baSsyXSAmIDB4ZmYpID4+IDYpXTsKKyAgICAgICAgICAgIG91dFtpbmRleCsrXSA9IG1hcFsoaW5baSsyXSAmIDB4M2YpXTsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGluLmxlbmd0aCAlIDMpIHsKKyAgICAgICAgICAgIGNhc2UgMToKKyAgICAgICAgICAgICAgICBvdXRbaW5kZXgrK10gPSBtYXBbKGluW2VuZF0gJiAweGZmKSA+PiAyXTsKKyAgICAgICAgICAgICAgICBvdXRbaW5kZXgrK10gPSBtYXBbKGluW2VuZF0gJiAweDAzKSA8PCA0XTsKKyAgICAgICAgICAgICAgICBvdXRbaW5kZXgrK10gPSAnPSc7CisgICAgICAgICAgICAgICAgb3V0W2luZGV4KytdID0gJz0nOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAyOgorICAgICAgICAgICAgICAgIG91dFtpbmRleCsrXSA9IG1hcFsoaW5bZW5kXSAmIDB4ZmYpID4+IDJdOworICAgICAgICAgICAgICAgIG91dFtpbmRleCsrXSA9IG1hcFsoKGluW2VuZF0gJiAweDAzKSA8PCA0KSB8ICgoaW5bZW5kKzFdICYgMHhmZikgPj4gNCldOworICAgICAgICAgICAgICAgIG91dFtpbmRleCsrXSA9IG1hcFsoKGluW2VuZCsxXSAmIDB4MGYpIDw8IDIpXTsKKyAgICAgICAgICAgICAgICBvdXRbaW5kZXgrK10gPSAnPSc7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcob3V0LCAwLCBpbmRleCwgQ2hhcnNldHMuVVNfQVNDSUkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL0Jsb2NrR3VhcmRPcy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vQmxvY2tHdWFyZE9zLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGYyODU4ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL0Jsb2NrR3VhcmRPcy5qYXZhCkBAIC0wLDAgKzEsMTk4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmlvOworCitpbXBvcnQgZGFsdmlrLnN5c3RlbS5CbG9ja0d1YXJkOworaW1wb3J0IGRhbHZpay5zeXN0ZW0uU29ja2V0VGFnZ2VyOworaW1wb3J0IGphdmEuaW8uRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgc3RhdGljIGxpYmNvcmUuaW8uT3NDb25zdGFudHMuKjsKKworLyoqCisgKiBJbmZvcm1zIEJsb2NrR3VhcmQgb2YgYW55IGFjdGl2aXR5IGl0IHNob3VsZCBiZSBhd2FyZSBvZi4KKyAqLworcHVibGljIGNsYXNzIEJsb2NrR3VhcmRPcyBleHRlbmRzIEZvcndhcmRpbmdPcyB7CisgICAgcHVibGljIEJsb2NrR3VhcmRPcyhPcyBvcykgeworICAgICAgICBzdXBlcihvcyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBGaWxlRGVzY3JpcHRvciB0YWdTb2NrZXQoRmlsZURlc2NyaXB0b3IgZmQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTb2NrZXRUYWdnZXIuZ2V0KCkudGFnKGZkKTsKKyAgICAgICAgICAgIHJldHVybiBmZDsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFcnJub0V4Y2VwdGlvbigic29ja2V0IiwgRUlOVkFMLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB1bnRhZ1NvY2tldChGaWxlRGVzY3JpcHRvciBmZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldFRhZ2dlci5nZXQoKS51bnRhZyhmZCk7CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXJybm9FeGNlcHRpb24oInNvY2tldCIsIEVJTlZBTCwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIEZpbGVEZXNjcmlwdG9yIGFjY2VwdChGaWxlRGVzY3JpcHRvciBmZCwgSW5ldFNvY2tldEFkZHJlc3MgcGVlckFkZHJlc3MpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIEJsb2NrR3VhcmQuZ2V0VGhyZWFkUG9saWN5KCkub25OZXR3b3JrKCk7CisgICAgICAgIHJldHVybiB0YWdTb2NrZXQob3MuYWNjZXB0KGZkLCBwZWVyQWRkcmVzcykpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBjbG9zZShGaWxlRGVzY3JpcHRvciBmZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChTX0lTU09DSyhMaWJjb3JlLm9zLmZzdGF0KGZkKS5zdF9tb2RlKSkgeworICAgICAgICAgICAgICAgIGlmIChpc0xpbmdlclNvY2tldChmZCkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGZkIGlzIGEgc29ja2V0IHdpdGggU09fTElOR0VSIHNldCwgd2UgbWlnaHQgYmxvY2sgaW5kZWZpbml0ZWx5LgorICAgICAgICAgICAgICAgICAgICAvLyBXZSBhbGxvdyBub24tbGluZ2VyIHNvY2tldHMgc28gdGhhdCBhcHBzIGNhbiBjbG9zZSB0aGVpciBuZXR3b3JrCisgICAgICAgICAgICAgICAgICAgIC8vIGNvbm5lY3Rpb25zIGluIG1ldGhvZHMgbGlrZSBvbkRlc3Ryb3kgd2hpY2ggd2lsbCBydW4gb24gdGhlIFVJIHRocmVhZC4KKyAgICAgICAgICAgICAgICAgICAgQmxvY2tHdWFyZC5nZXRUaHJlYWRQb2xpY3koKS5vbk5ldHdvcmsoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdW50YWdTb2NrZXQoZmQpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICAvLyBXZSdyZSBjYWxsZWQgdmlhIFNvY2tldC5jbG9zZSAod2hpY2ggZG9lc24ndCBhc2sgZm9yIHVzIHRvIGJlIGNhbGxlZCksIHNvIHdlCisgICAgICAgICAgICAvLyBtdXN0IG5vdCB0aHJvdyBoZXJlLCBiZWNhdXNlIFNvY2tldC5jbG9zZSBtdXN0IG5vdCB0aHJvdyBpZiBhc2tlZCB0byBjbG9zZSBhbgorICAgICAgICAgICAgLy8gYWxyZWFkeS1jbG9zZWQgc29ja2V0LiBBbHNvLCB0aGUgcGFzc2VkLWluIEZpbGVEZXNjcmlwdG9yIGlzbid0IG5lY2Vzc2FyaWx5CisgICAgICAgICAgICAvLyBhIHNvY2tldCBhdCBhbGwuCisgICAgICAgIH0KKyAgICAgICAgb3MuY2xvc2UoZmQpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNMaW5nZXJTb2NrZXQoRmlsZURlc2NyaXB0b3IgZmQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cnVjdExpbmdlciBsaW5nZXIgPSBMaWJjb3JlLm9zLmdldHNvY2tvcHRMaW5nZXIoZmQsIFNPTF9TT0NLRVQsIFNPX0xJTkdFUik7CisgICAgICAgIHJldHVybiBsaW5nZXIuaXNPbigpICYmIGxpbmdlci5sX2xpbmdlciA+IDA7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNvbm5lY3QoRmlsZURlc2NyaXB0b3IgZmQsIEluZXRBZGRyZXNzIGFkZHJlc3MsIGludCBwb3J0KSB0aHJvd3MgRXJybm9FeGNlcHRpb24geworICAgICAgICBCbG9ja0d1YXJkLmdldFRocmVhZFBvbGljeSgpLm9uTmV0d29yaygpOworICAgICAgICBvcy5jb25uZWN0KGZkLCBhZGRyZXNzLCBwb3J0KTsKKyAgICB9CisKKyAgICAvLyBUT0RPOiBVbnRhZyBuZXdGZCB3aGVuIG5lZWRlZCBmb3IgZHVwMihGaWxlRGVzY3JpcHRvciBvbGRGZCwgaW50IG5ld0ZkKQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGZkYXRhc3luYyhGaWxlRGVzY3JpcHRvciBmZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsKKyAgICAgICAgQmxvY2tHdWFyZC5nZXRUaHJlYWRQb2xpY3koKS5vbldyaXRlVG9EaXNrKCk7CisgICAgICAgIG9zLmZkYXRhc3luYyhmZCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGZzeW5jKEZpbGVEZXNjcmlwdG9yIGZkKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geworICAgICAgICBCbG9ja0d1YXJkLmdldFRocmVhZFBvbGljeSgpLm9uV3JpdGVUb0Rpc2soKTsKKyAgICAgICAgb3MuZnN5bmMoZmQpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBmdHJ1bmNhdGUoRmlsZURlc2NyaXB0b3IgZmQsIGxvbmcgbGVuZ3RoKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geworICAgICAgICBCbG9ja0d1YXJkLmdldFRocmVhZFBvbGljeSgpLm9uV3JpdGVUb0Rpc2soKTsKKyAgICAgICAgb3MuZnRydW5jYXRlKGZkLCBsZW5ndGgpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgRmlsZURlc2NyaXB0b3Igb3BlbihTdHJpbmcgcGF0aCwgaW50IGZsYWdzLCBpbnQgbW9kZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsKKyAgICAgICAgQmxvY2tHdWFyZC5nZXRUaHJlYWRQb2xpY3koKS5vblJlYWRGcm9tRGlzaygpOworICAgICAgICBpZiAoKG1vZGUgJiBPX0FDQ01PREUpICE9IE9fUkRPTkxZKSB7CisgICAgICAgICAgICBCbG9ja0d1YXJkLmdldFRocmVhZFBvbGljeSgpLm9uV3JpdGVUb0Rpc2soKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gb3Mub3BlbihwYXRoLCBmbGFncywgbW9kZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgcG9sbChTdHJ1Y3RQb2xsZmRbXSBmZHMsIGludCB0aW1lb3V0TXMpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIEdyZWF0ZXIgdGhhbiAwIGlzIGEgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgYW5kIC0xIG1lYW5zICJibG9jayBmb3JldmVyIiwKKyAgICAgICAgLy8gYnV0IDAgbWVhbnMgInBvbGwgYW5kIHJldHVybiBpbW1lZGlhdGVseSIsIHdoaWNoIHNob3VsZG4ndCBiZSBzdWJqZWN0IHRvIEJsb2NrR3VhcmQuCisgICAgICAgIGlmICh0aW1lb3V0TXMgIT0gMCkgeworICAgICAgICAgICAgQmxvY2tHdWFyZC5nZXRUaHJlYWRQb2xpY3koKS5vbk5ldHdvcmsoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gb3MucG9sbChmZHMsIHRpbWVvdXRNcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgcHJlYWQoRmlsZURlc2NyaXB0b3IgZmQsIEJ5dGVCdWZmZXIgYnVmZmVyLCBsb25nIG9mZnNldCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsKKyAgICAgICAgQmxvY2tHdWFyZC5nZXRUaHJlYWRQb2xpY3koKS5vblJlYWRGcm9tRGlzaygpOworICAgICAgICByZXR1cm4gb3MucHJlYWQoZmQsIGJ1ZmZlciwgb2Zmc2V0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCBwcmVhZChGaWxlRGVzY3JpcHRvciBmZCwgYnl0ZVtdIGJ5dGVzLCBpbnQgYnl0ZU9mZnNldCwgaW50IGJ5dGVDb3VudCwgbG9uZyBvZmZzZXQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIEJsb2NrR3VhcmQuZ2V0VGhyZWFkUG9saWN5KCkub25SZWFkRnJvbURpc2soKTsKKyAgICAgICAgcmV0dXJuIG9zLnByZWFkKGZkLCBieXRlcywgYnl0ZU9mZnNldCwgYnl0ZUNvdW50LCBvZmZzZXQpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHB3cml0ZShGaWxlRGVzY3JpcHRvciBmZCwgQnl0ZUJ1ZmZlciBidWZmZXIsIGxvbmcgb2Zmc2V0KSB0aHJvd3MgRXJybm9FeGNlcHRpb24geworICAgICAgICBCbG9ja0d1YXJkLmdldFRocmVhZFBvbGljeSgpLm9uV3JpdGVUb0Rpc2soKTsKKyAgICAgICAgcmV0dXJuIG9zLnB3cml0ZShmZCwgYnVmZmVyLCBvZmZzZXQpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHB3cml0ZShGaWxlRGVzY3JpcHRvciBmZCwgYnl0ZVtdIGJ5dGVzLCBpbnQgYnl0ZU9mZnNldCwgaW50IGJ5dGVDb3VudCwgbG9uZyBvZmZzZXQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIEJsb2NrR3VhcmQuZ2V0VGhyZWFkUG9saWN5KCkub25Xcml0ZVRvRGlzaygpOworICAgICAgICByZXR1cm4gb3MucHdyaXRlKGZkLCBieXRlcywgYnl0ZU9mZnNldCwgYnl0ZUNvdW50LCBvZmZzZXQpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHJlYWQoRmlsZURlc2NyaXB0b3IgZmQsIEJ5dGVCdWZmZXIgYnVmZmVyKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geworICAgICAgICBCbG9ja0d1YXJkLmdldFRocmVhZFBvbGljeSgpLm9uUmVhZEZyb21EaXNrKCk7CisgICAgICAgIHJldHVybiBvcy5yZWFkKGZkLCBidWZmZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHJlYWQoRmlsZURlc2NyaXB0b3IgZmQsIGJ5dGVbXSBieXRlcywgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIEJsb2NrR3VhcmQuZ2V0VGhyZWFkUG9saWN5KCkub25SZWFkRnJvbURpc2soKTsKKyAgICAgICAgcmV0dXJuIG9zLnJlYWQoZmQsIGJ5dGVzLCBieXRlT2Zmc2V0LCBieXRlQ291bnQpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHJlYWR2KEZpbGVEZXNjcmlwdG9yIGZkLCBPYmplY3RbXSBidWZmZXJzLCBpbnRbXSBvZmZzZXRzLCBpbnRbXSBieXRlQ291bnRzKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geworICAgICAgICBCbG9ja0d1YXJkLmdldFRocmVhZFBvbGljeSgpLm9uUmVhZEZyb21EaXNrKCk7CisgICAgICAgIHJldHVybiBvcy5yZWFkdihmZCwgYnVmZmVycywgb2Zmc2V0cywgYnl0ZUNvdW50cyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgcmVjdmZyb20oRmlsZURlc2NyaXB0b3IgZmQsIEJ5dGVCdWZmZXIgYnVmZmVyLCBpbnQgZmxhZ3MsIEluZXRTb2NrZXRBZGRyZXNzIHNyY0FkZHJlc3MpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIEJsb2NrR3VhcmQuZ2V0VGhyZWFkUG9saWN5KCkub25OZXR3b3JrKCk7CisgICAgICAgIHJldHVybiBvcy5yZWN2ZnJvbShmZCwgYnVmZmVyLCBmbGFncywgc3JjQWRkcmVzcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgcmVjdmZyb20oRmlsZURlc2NyaXB0b3IgZmQsIGJ5dGVbXSBieXRlcywgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQsIGludCBmbGFncywgSW5ldFNvY2tldEFkZHJlc3Mgc3JjQWRkcmVzcykgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsKKyAgICAgICAgQmxvY2tHdWFyZC5nZXRUaHJlYWRQb2xpY3koKS5vbk5ldHdvcmsoKTsKKyAgICAgICAgcmV0dXJuIG9zLnJlY3Zmcm9tKGZkLCBieXRlcywgYnl0ZU9mZnNldCwgYnl0ZUNvdW50LCBmbGFncywgc3JjQWRkcmVzcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgc2VuZHRvKEZpbGVEZXNjcmlwdG9yIGZkLCBCeXRlQnVmZmVyIGJ1ZmZlciwgaW50IGZsYWdzLCBJbmV0QWRkcmVzcyBpbmV0QWRkcmVzcywgaW50IHBvcnQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIEJsb2NrR3VhcmQuZ2V0VGhyZWFkUG9saWN5KCkub25OZXR3b3JrKCk7CisgICAgICAgIHJldHVybiBvcy5zZW5kdG8oZmQsIGJ1ZmZlciwgZmxhZ3MsIGluZXRBZGRyZXNzLCBwb3J0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCBzZW5kdG8oRmlsZURlc2NyaXB0b3IgZmQsIGJ5dGVbXSBieXRlcywgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQsIGludCBmbGFncywgSW5ldEFkZHJlc3MgaW5ldEFkZHJlc3MsIGludCBwb3J0KSB0aHJvd3MgRXJybm9FeGNlcHRpb24geworICAgICAgICAvLyBXZSBwZXJtaXQgZGF0YWdyYW1zIHdpdGhvdXQgaG9zdG5hbWUgbG9va3Vwcy4KKyAgICAgICAgaWYgKGluZXRBZGRyZXNzICE9IG51bGwpIHsKKyAgICAgICAgICAgIEJsb2NrR3VhcmQuZ2V0VGhyZWFkUG9saWN5KCkub25OZXR3b3JrKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG9zLnNlbmR0byhmZCwgYnl0ZXMsIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCwgZmxhZ3MsIGluZXRBZGRyZXNzLCBwb3J0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIEZpbGVEZXNjcmlwdG9yIHNvY2tldChpbnQgZG9tYWluLCBpbnQgdHlwZSwgaW50IHByb3RvY29sKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gdGFnU29ja2V0KG9zLnNvY2tldChkb21haW4sIHR5cGUsIHByb3RvY29sKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgd3JpdGUoRmlsZURlc2NyaXB0b3IgZmQsIEJ5dGVCdWZmZXIgYnVmZmVyKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geworICAgICAgICBCbG9ja0d1YXJkLmdldFRocmVhZFBvbGljeSgpLm9uV3JpdGVUb0Rpc2soKTsKKyAgICAgICAgcmV0dXJuIG9zLndyaXRlKGZkLCBidWZmZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHdyaXRlKEZpbGVEZXNjcmlwdG9yIGZkLCBieXRlW10gYnl0ZXMsIGludCBieXRlT2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgRXJybm9FeGNlcHRpb24geworICAgICAgICBCbG9ja0d1YXJkLmdldFRocmVhZFBvbGljeSgpLm9uV3JpdGVUb0Rpc2soKTsKKyAgICAgICAgcmV0dXJuIG9zLndyaXRlKGZkLCBieXRlcywgYnl0ZU9mZnNldCwgYnl0ZUNvdW50KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCB3cml0ZXYoRmlsZURlc2NyaXB0b3IgZmQsIE9iamVjdFtdIGJ1ZmZlcnMsIGludFtdIG9mZnNldHMsIGludFtdIGJ5dGVDb3VudHMpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIEJsb2NrR3VhcmQuZ2V0VGhyZWFkUG9saWN5KCkub25Xcml0ZVRvRGlzaygpOworICAgICAgICByZXR1cm4gb3Mud3JpdGV2KGZkLCBidWZmZXJzLCBvZmZzZXRzLCBieXRlQ291bnRzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9CdWZmZXJJdGVyYXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vQnVmZmVySXRlcmF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZjNhZDQ3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vQnVmZmVySXRlcmF0b3IuamF2YQpAQCAtMCwwICsxLDYyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmlvOworCisvKioKKyAqIEl0ZXJhdGVzIG92ZXIgYmlnLSBvciBsaXR0bGUtZW5kaWFuIGJ5dGVzLiBTZWUge0BsaW5rIE1lbW9yeU1hcHBlZEZpbGUjYmlnRW5kaWFuSXRlcmF0b3J9IGFuZAorICoge0BsaW5rIE1lbW9yeU1hcHBlZEZpbGUjbGl0dGxlRW5kaWFuSXRlcmF0b3J9LgorICoKKyAqIEBoaWRlIGRvbid0IG1ha2UgdGhpcyBwdWJsaWMgd2l0aG91dCBhZGRpbmcgYm91bmRzIGNoZWNraW5nLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQnVmZmVySXRlcmF0b3IgeworICAgIC8qKgorICAgICAqIFNlZWtzIHRvIHRoZSBhYnNvbHV0ZSBwb3NpdGlvbiB7QGNvZGUgb2Zmc2V0fSwgbWVhc3VyZWQgaW4gYnl0ZXMgZnJvbSB0aGUgc3RhcnQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2VlayhpbnQgb2Zmc2V0KTsKKworICAgIC8qKgorICAgICAqIFNraXBzIGZvcndhcmRzIG9yIGJhY2t3YXJkcyB7QGNvZGUgYnl0ZUNvdW50fSBieXRlcyBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNraXAoaW50IGJ5dGVDb3VudCk7CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMge0Bjb2RlIGJ5dGVDb3VudH0gYnl0ZXMgZnJvbSB0aGUgY3VycmVudCBwb3NpdGlvbiBpbnRvIHtAY29kZSBkc3R9LCBzdGFydGluZyBhdAorICAgICAqIHtAY29kZSBkc3RPZmZzZXR9LCBhbmQgYWR2YW5jZXMgdGhlIGN1cnJlbnQgcG9zaXRpb24ge0Bjb2RlIGJ5dGVDb3VudH0gYnl0ZXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcmVhZEJ5dGVBcnJheShieXRlW10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgYnl0ZUNvdW50KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGJ5dGUgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24sIGFuZCBhZHZhbmNlcyB0aGUgY3VycmVudCBwb3NpdGlvbiBvbmUgYnl0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYnl0ZSByZWFkQnl0ZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgMzItYml0IGludCBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiwgYW5kIGFkdmFuY2VzIHRoZSBjdXJyZW50IHBvc2l0aW9uIGZvdXIgYnl0ZXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCByZWFkSW50KCk7CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMge0Bjb2RlIGludENvdW50fSAzMi1iaXQgaW50cyBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uIGludG8ge0Bjb2RlIGRzdH0sIHN0YXJ0aW5nIGF0CisgICAgICoge0Bjb2RlIGRzdE9mZnNldH0sIGFuZCBhZHZhbmNlcyB0aGUgY3VycmVudCBwb3NpdGlvbiB7QGNvZGUgNCAqIGludENvdW50fSBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCByZWFkSW50QXJyYXkoaW50W10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgaW50Q291bnQpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgMTYtYml0IHNob3J0IGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uLCBhbmQgYWR2YW5jZXMgdGhlIGN1cnJlbnQgcG9zaXRpb24gdHdvIGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBzaG9ydCByZWFkU2hvcnQoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL0Rpc2tMcnVDYWNoZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vRGlza0xydUNhY2hlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWNjMTMwMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL0Rpc2tMcnVDYWNoZS5qYXZhCkBAIC0wLDAgKzEsODA0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmlvOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRXcml0ZXI7CitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5FT0ZFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVXcml0ZXI7CitpbXBvcnQgamF2YS5pby5GaWx0ZXJPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW1Xcml0ZXI7CitpbXBvcnQgamF2YS5pby5Xcml0ZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0czsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ2FsbGFibGU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JTZXJ2aWNlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkxpbmtlZEJsb2NraW5nUXVldWU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0OworCisvKioKKyAqIEEgY2FjaGUgdGhhdCB1c2VzIGEgYm91bmRlZCBhbW91bnQgb2Ygc3BhY2Ugb24gYSBmaWxlc3lzdGVtLiBFYWNoIGNhY2hlCisgKiBlbnRyeSBoYXMgYSBzdHJpbmcga2V5IGFuZCBhIGZpeGVkIG51bWJlciBvZiB2YWx1ZXMuIFZhbHVlcyBhcmUgYnl0ZQorICogc2VxdWVuY2VzLCBhY2Nlc3NpYmxlIGFzIHN0cmVhbXMgb3IgZmlsZXMuIEVhY2ggdmFsdWUgbXVzdCBiZSBiZXR3ZWVuIHtAY29kZQorICogMH0gYW5kIHtAY29kZSBJbnRlZ2VyLk1BWF9WQUxVRX0gYnl0ZXMgaW4gbGVuZ3RoLgorICoKKyAqIDxwPlRoZSBjYWNoZSBzdG9yZXMgaXRzIGRhdGEgaW4gYSBkaXJlY3Rvcnkgb24gdGhlIGZpbGVzeXN0ZW0uIFRoaXMKKyAqIGRpcmVjdG9yeSBtdXN0IGJlIGV4Y2x1c2l2ZSB0byB0aGUgY2FjaGU7IHRoZSBjYWNoZSBtYXkgZGVsZXRlIG9yIG92ZXJ3cml0ZQorICogZmlsZXMgZnJvbSBpdHMgZGlyZWN0b3J5LiBJdCBpcyBhbiBlcnJvciBmb3IgbXVsdGlwbGUgcHJvY2Vzc2VzIHRvIHVzZSB0aGUKKyAqIHNhbWUgY2FjaGUgZGlyZWN0b3J5IGF0IHRoZSBzYW1lIHRpbWUuCisgKgorICogPHA+VGhpcyBjYWNoZSBsaW1pdHMgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IGl0IHdpbGwgc3RvcmUgb24gdGhlCisgKiBmaWxlc3lzdGVtLiBXaGVuIHRoZSBudW1iZXIgb2Ygc3RvcmVkIGJ5dGVzIGV4Y2VlZHMgdGhlIGxpbWl0LCB0aGUgY2FjaGUgd2lsbAorICogcmVtb3ZlIGVudHJpZXMgaW4gdGhlIGJhY2tncm91bmQgdW50aWwgdGhlIGxpbWl0IGlzIHNhdGlzZmllZC4gVGhlIGxpbWl0IGlzCisgKiBub3Qgc3RyaWN0OiB0aGUgY2FjaGUgbWF5IHRlbXBvcmFyaWx5IGV4Y2VlZCBpdCB3aGlsZSB3YWl0aW5nIGZvciBmaWxlcyB0byBiZQorICogZGVsZXRlZC4gVGhlIGxpbWl0IGRvZXMgbm90IGluY2x1ZGUgZmlsZXN5c3RlbSBvdmVyaGVhZCBvciB0aGUgY2FjaGUKKyAqIGpvdXJuYWwgc28gc3BhY2Utc2Vuc2l0aXZlIGFwcGxpY2F0aW9ucyBzaG91bGQgc2V0IGEgY29uc2VydmF0aXZlIGxpbWl0LgorICoKKyAqIDxwPkNsaWVudHMgY2FsbCB7QGxpbmsgI2VkaXR9IHRvIGNyZWF0ZSBvciB1cGRhdGUgdGhlIHZhbHVlcyBvZiBhbiBlbnRyeS4gQW4KKyAqIGVudHJ5IG1heSBoYXZlIG9ubHkgb25lIGVkaXRvciBhdCBvbmUgdGltZTsgaWYgYSB2YWx1ZSBpcyBub3QgYXZhaWxhYmxlIHRvIGJlCisgKiBlZGl0ZWQgdGhlbiB7QGxpbmsgI2VkaXR9IHdpbGwgcmV0dXJuIG51bGwuCisgKiA8dWw+CisgKiAgICAgPGxpPldoZW4gYW4gZW50cnkgaXMgYmVpbmcgPHN0cm9uZz5jcmVhdGVkPC9zdHJvbmc+IGl0IGlzIG5lY2Vzc2FyeSB0bworICogICAgICAgICBzdXBwbHkgYSBmdWxsIHNldCBvZiB2YWx1ZXM7IHRoZSBlbXB0eSB2YWx1ZSBzaG91bGQgYmUgdXNlZCBhcyBhCisgKiAgICAgICAgIHBsYWNlaG9sZGVyIGlmIG5lY2Vzc2FyeS4KKyAqICAgICA8bGk+V2hlbiBhbiBlbnRyeSBpcyBiZWluZyA8c3Ryb25nPmNyZWF0ZWQ8L3N0cm9uZz4sIGl0IGlzIG5vdCBuZWNlc3NhcnkKKyAqICAgICAgICAgdG8gc3VwcGx5IGRhdGEgZm9yIGV2ZXJ5IHZhbHVlOyB2YWx1ZXMgZGVmYXVsdCB0byB0aGVpciBwcmV2aW91cworICogICAgICAgICB2YWx1ZS4KKyAqIDwvdWw+CisgKiBFdmVyeSB7QGxpbmsgI2VkaXR9IGNhbGwgbXVzdCBiZSBtYXRjaGVkIGJ5IGEgY2FsbCB0byB7QGxpbmsgRWRpdG9yI2NvbW1pdH0KKyAqIG9yIHtAbGluayBFZGl0b3IjYWJvcnR9LiBDb21taXR0aW5nIGlzIGF0b21pYzogYSByZWFkIG9ic2VydmVzIHRoZSBmdWxsIHNldAorICogb2YgdmFsdWVzIGFzIHRoZXkgd2VyZSBiZWZvcmUgb3IgYWZ0ZXIgdGhlIGNvbW1pdCwgYnV0IG5ldmVyIGEgbWl4IG9mIHZhbHVlcy4KKyAqCisgKiA8cD5DbGllbnRzIGNhbGwge0BsaW5rICNnZXR9IHRvIHJlYWQgYSBzbmFwc2hvdCBvZiBhbiBlbnRyeS4gVGhlIHJlYWQgd2lsbAorICogb2JzZXJ2ZSB0aGUgdmFsdWUgYXQgdGhlIHRpbWUgdGhhdCB7QGxpbmsgI2dldH0gd2FzIGNhbGxlZC4gVXBkYXRlcyBhbmQKKyAqIHJlbW92YWxzIGFmdGVyIHRoZSBjYWxsIGRvIG5vdCBpbXBhY3Qgb25nb2luZyByZWFkcy4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGlzIHRvbGVyYW50IG9mIHNvbWUgSS9PIGVycm9ycy4gSWYgZmlsZXMgYXJlIG1pc3NpbmcgZnJvbSB0aGUKKyAqIGZpbGVzeXN0ZW0sIHRoZSBjb3JyZXNwb25kaW5nIGVudHJpZXMgd2lsbCBiZSBkcm9wcGVkIGZyb20gdGhlIGNhY2hlLiBJZgorICogYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHdyaXRpbmcgYSBjYWNoZSB2YWx1ZSwgdGhlIGVkaXQgd2lsbCBmYWlsIHNpbGVudGx5LgorICogQ2FsbGVycyBzaG91bGQgaGFuZGxlIG90aGVyIHByb2JsZW1zIGJ5IGNhdGNoaW5nIHtAY29kZSBJT0V4Y2VwdGlvbn0gYW5kCisgKiByZXNwb25kaW5nIGFwcHJvcHJpYXRlbHkuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBEaXNrTHJ1Q2FjaGUgaW1wbGVtZW50cyBDbG9zZWFibGUgeworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgSk9VUk5BTF9GSUxFID0gImpvdXJuYWwiOworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgSk9VUk5BTF9GSUxFX1RNUCA9ICJqb3VybmFsLnRtcCI7CisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBNQUdJQyA9ICJsaWJjb3JlLmlvLkRpc2tMcnVDYWNoZSI7CisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBWRVJTSU9OXzEgPSAiMSI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENMRUFOID0gIkNMRUFOIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRElSVFkgPSAiRElSVFkiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRU1PVkUgPSAiUkVNT1ZFIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVBRCA9ICJSRUFEIjsKKworICAgIC8qCisgICAgICogVGhpcyBjYWNoZSB1c2VzIGEgam91cm5hbCBmaWxlIG5hbWVkICJqb3VybmFsIi4gQSB0eXBpY2FsIGpvdXJuYWwgZmlsZQorICAgICAqIGxvb2tzIGxpa2UgdGhpczoKKyAgICAgKiAgICAgbGliY29yZS5pby5EaXNrTHJ1Q2FjaGUKKyAgICAgKiAgICAgMQorICAgICAqICAgICAxMDAKKyAgICAgKiAgICAgMgorICAgICAqCisgICAgICogICAgIENMRUFOIDM0MDAzMzBkMWRmYzdmM2Y3ZjRiOGQ0ZDgwM2RmY2Y2IDgzMiAyMTA1NAorICAgICAqICAgICBESVJUWSAzMzVjNGM2MDI4MTcxY2ZkZGZiYWFlMWE5YzMxM2M1MgorICAgICAqICAgICBDTEVBTiAzMzVjNGM2MDI4MTcxY2ZkZGZiYWFlMWE5YzMxM2M1MiAzOTM0IDIzNDIKKyAgICAgKiAgICAgUkVNT1ZFIDMzNWM0YzYwMjgxNzFjZmRkZmJhYWUxYTljMzEzYzUyCisgICAgICogICAgIERJUlRZIDFhYjk2YTE3MWZhZWVlZTM4NDk2ZDhiMzMwNzcxYTdhCisgICAgICogICAgIENMRUFOIDFhYjk2YTE3MWZhZWVlZTM4NDk2ZDhiMzMwNzcxYTdhIDE2MDAgMjM0CisgICAgICogICAgIFJFQUQgMzM1YzRjNjAyODE3MWNmZGRmYmFhZTFhOWMzMTNjNTIKKyAgICAgKiAgICAgUkVBRCAzNDAwMzMwZDFkZmM3ZjNmN2Y0YjhkNGQ4MDNkZmNmNgorICAgICAqCisgICAgICogVGhlIGZpcnN0IGZpdmUgbGluZXMgb2YgdGhlIGpvdXJuYWwgZm9ybSBpdHMgaGVhZGVyLiBUaGV5IGFyZSB0aGUKKyAgICAgKiBjb25zdGFudCBzdHJpbmcgImxpYmNvcmUuaW8uRGlza0xydUNhY2hlIiwgdGhlIGRpc2sgY2FjaGUncyB2ZXJzaW9uLAorICAgICAqIHRoZSBhcHBsaWNhdGlvbidzIHZlcnNpb24sIHRoZSB2YWx1ZSBjb3VudCwgYW5kIGEgYmxhbmsgbGluZS4KKyAgICAgKgorICAgICAqIEVhY2ggb2YgdGhlIHN1YnNlcXVlbnQgbGluZXMgaW4gdGhlIGZpbGUgaXMgYSByZWNvcmQgb2YgdGhlIHN0YXRlIG9mIGEKKyAgICAgKiBjYWNoZSBlbnRyeS4gRWFjaCBsaW5lIGNvbnRhaW5zIHNwYWNlLXNlcGFyYXRlZCB2YWx1ZXM6IGEgc3RhdGUsIGEga2V5LAorICAgICAqIGFuZCBvcHRpb25hbCBzdGF0ZS1zcGVjaWZpYyB2YWx1ZXMuCisgICAgICogICBvIERJUlRZIGxpbmVzIHRyYWNrIHRoYXQgYW4gZW50cnkgaXMgYWN0aXZlbHkgYmVpbmcgY3JlYXRlZCBvciB1cGRhdGVkLgorICAgICAqICAgICBFdmVyeSBzdWNjZXNzZnVsIERJUlRZIGFjdGlvbiBzaG91bGQgYmUgZm9sbG93ZWQgYnkgYSBDTEVBTiBvciBSRU1PVkUKKyAgICAgKiAgICAgYWN0aW9uLiBESVJUWSBsaW5lcyB3aXRob3V0IGEgbWF0Y2hpbmcgQ0xFQU4gb3IgUkVNT1ZFIGluZGljYXRlIHRoYXQKKyAgICAgKiAgICAgdGVtcG9yYXJ5IGZpbGVzIG1heSBuZWVkIHRvIGJlIGRlbGV0ZWQuCisgICAgICogICBvIENMRUFOIGxpbmVzIHRyYWNrIGEgY2FjaGUgZW50cnkgdGhhdCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcHVibGlzaGVkCisgICAgICogICAgIGFuZCBtYXkgYmUgcmVhZC4gQSBwdWJsaXNoIGxpbmUgaXMgZm9sbG93ZWQgYnkgdGhlIGxlbmd0aHMgb2YgZWFjaCBvZgorICAgICAqICAgICBpdHMgdmFsdWVzLgorICAgICAqICAgbyBSRUFEIGxpbmVzIHRyYWNrIGFjY2Vzc2VzIGZvciBMUlUuCisgICAgICogICBvIFJFTU9WRSBsaW5lcyB0cmFjayBlbnRyaWVzIHRoYXQgaGF2ZSBiZWVuIGRlbGV0ZWQuCisgICAgICoKKyAgICAgKiBUaGUgam91cm5hbCBmaWxlIGlzIGFwcGVuZGVkIHRvIGFzIGNhY2hlIG9wZXJhdGlvbnMgb2NjdXIuIFRoZSBqb3VybmFsIG1heQorICAgICAqIG9jY2FzaW9uYWxseSBiZSBjb21wYWN0ZWQgYnkgZHJvcHBpbmcgcmVkdW5kYW50IGxpbmVzLiBBIHRlbXBvcmFyeSBmaWxlIG5hbWVkCisgICAgICogImpvdXJuYWwudG1wIiB3aWxsIGJlIHVzZWQgZHVyaW5nIGNvbXBhY3Rpb247IHRoYXQgZmlsZSBzaG91bGQgYmUgZGVsZXRlZCBpZgorICAgICAqIGl0IGV4aXN0cyB3aGVuIHRoZSBjYWNoZSBpcyBvcGVuZWQuCisgICAgICovCisKKyAgICBwcml2YXRlIGZpbmFsIEZpbGUgZGlyZWN0b3J5OworICAgIHByaXZhdGUgZmluYWwgRmlsZSBqb3VybmFsRmlsZTsKKyAgICBwcml2YXRlIGZpbmFsIEZpbGUgam91cm5hbEZpbGVUbXA7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgYXBwVmVyc2lvbjsKKyAgICBwcml2YXRlIGZpbmFsIGxvbmcgbWF4U2l6ZTsKKyAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZUNvdW50OworICAgIHByaXZhdGUgbG9uZyBzaXplID0gMDsKKyAgICBwcml2YXRlIFdyaXRlciBqb3VybmFsV3JpdGVyOworICAgIHByaXZhdGUgZmluYWwgTGlua2VkSGFzaE1hcDxTdHJpbmcsIEVudHJ5PiBscnVFbnRyaWVzCisgICAgICAgICAgICA9IG5ldyBMaW5rZWRIYXNoTWFwPFN0cmluZywgRW50cnk+KDAsIDAuNzVmLCB0cnVlKTsKKyAgICBwcml2YXRlIGludCByZWR1bmRhbnRPcENvdW50OworCisgICAgLyoqIFRoaXMgY2FjaGUgdXNlcyBhIHNpbmdsZSBiYWNrZ3JvdW5kIHRocmVhZCB0byBldmljdCBlbnRyaWVzLiAqLworICAgIHByaXZhdGUgZmluYWwgRXhlY3V0b3JTZXJ2aWNlIGV4ZWN1dG9yU2VydmljZSA9IG5ldyBUaHJlYWRQb29sRXhlY3V0b3IoMCwgMSwKKyAgICAgICAgICAgIDYwTCwgVGltZVVuaXQuU0VDT05EUywgbmV3IExpbmtlZEJsb2NraW5nUXVldWU8UnVubmFibGU+KCkpOworICAgIHByaXZhdGUgZmluYWwgQ2FsbGFibGU8Vm9pZD4gY2xlYW51cENhbGxhYmxlID0gbmV3IENhbGxhYmxlPFZvaWQ+KCkgeworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFZvaWQgY2FsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgc3luY2hyb25pemVkIChEaXNrTHJ1Q2FjaGUudGhpcykgeworICAgICAgICAgICAgICAgIGlmIChqb3VybmFsV3JpdGVyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7IC8vIGNsb3NlZAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0cmltVG9TaXplKCk7CisgICAgICAgICAgICAgICAgaWYgKGpvdXJuYWxSZWJ1aWxkUmVxdWlyZWQoKSkgeworICAgICAgICAgICAgICAgICAgICByZWJ1aWxkSm91cm5hbCgpOworICAgICAgICAgICAgICAgICAgICByZWR1bmRhbnRPcENvdW50ID0gMDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBwcml2YXRlIERpc2tMcnVDYWNoZShGaWxlIGRpcmVjdG9yeSwgaW50IGFwcFZlcnNpb24sIGludCB2YWx1ZUNvdW50LCBsb25nIG1heFNpemUpIHsKKyAgICAgICAgdGhpcy5kaXJlY3RvcnkgPSBkaXJlY3Rvcnk7CisgICAgICAgIHRoaXMuYXBwVmVyc2lvbiA9IGFwcFZlcnNpb247CisgICAgICAgIHRoaXMuam91cm5hbEZpbGUgPSBuZXcgRmlsZShkaXJlY3RvcnksIEpPVVJOQUxfRklMRSk7CisgICAgICAgIHRoaXMuam91cm5hbEZpbGVUbXAgPSBuZXcgRmlsZShkaXJlY3RvcnksIEpPVVJOQUxfRklMRV9UTVApOworICAgICAgICB0aGlzLnZhbHVlQ291bnQgPSB2YWx1ZUNvdW50OworICAgICAgICB0aGlzLm1heFNpemUgPSBtYXhTaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIE9wZW5zIHRoZSBjYWNoZSBpbiB7QGNvZGUgZGlyZWN0b3J5fSwgY3JlYXRpbmcgYSBjYWNoZSBpZiBub25lIGV4aXN0cworICAgICAqIHRoZXJlLgorICAgICAqCisgICAgICogQHBhcmFtIGRpcmVjdG9yeSBhIHdyaXRhYmxlIGRpcmVjdG9yeQorICAgICAqIEBwYXJhbSBhcHBWZXJzaW9uCisgICAgICogQHBhcmFtIHZhbHVlQ291bnQgdGhlIG51bWJlciBvZiB2YWx1ZXMgcGVyIGNhY2hlIGVudHJ5LiBNdXN0IGJlIHBvc2l0aXZlLgorICAgICAqIEBwYXJhbSBtYXhTaXplIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0aGlzIGNhY2hlIHNob3VsZCB1c2UgdG8gc3RvcmUKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHJlYWRpbmcgb3Igd3JpdGluZyB0aGUgY2FjaGUgZGlyZWN0b3J5IGZhaWxzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBEaXNrTHJ1Q2FjaGUgb3BlbihGaWxlIGRpcmVjdG9yeSwgaW50IGFwcFZlcnNpb24sIGludCB2YWx1ZUNvdW50LCBsb25nIG1heFNpemUpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAobWF4U2l6ZSA8PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJtYXhTaXplIDw9IDAiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodmFsdWVDb3VudCA8PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ2YWx1ZUNvdW50IDw9IDAiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHByZWZlciB0byBwaWNrIHVwIHdoZXJlIHdlIGxlZnQgb2ZmCisgICAgICAgIERpc2tMcnVDYWNoZSBjYWNoZSA9IG5ldyBEaXNrTHJ1Q2FjaGUoZGlyZWN0b3J5LCBhcHBWZXJzaW9uLCB2YWx1ZUNvdW50LCBtYXhTaXplKTsKKyAgICAgICAgaWYgKGNhY2hlLmpvdXJuYWxGaWxlLmV4aXN0cygpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNhY2hlLnJlYWRKb3VybmFsKCk7CisgICAgICAgICAgICAgICAgY2FjaGUucHJvY2Vzc0pvdXJuYWwoKTsKKyAgICAgICAgICAgICAgICBjYWNoZS5qb3VybmFsV3JpdGVyID0gbmV3IEJ1ZmZlcmVkV3JpdGVyKG5ldyBGaWxlV3JpdGVyKGNhY2hlLmpvdXJuYWxGaWxlLCB0cnVlKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNhY2hlOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gam91cm5hbElzQ29ycnVwdCkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5sb2dXKCJEaXNrTHJ1Q2FjaGUgIiArIGRpcmVjdG9yeSArICIgaXMgY29ycnVwdDogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBqb3VybmFsSXNDb3JydXB0LmdldE1lc3NhZ2UoKSArICIsIHJlbW92aW5nIik7CisgICAgICAgICAgICAgICAgY2FjaGUuZGVsZXRlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBjcmVhdGUgYSBuZXcgZW1wdHkgY2FjaGUKKyAgICAgICAgZGlyZWN0b3J5Lm1rZGlycygpOworICAgICAgICBjYWNoZSA9IG5ldyBEaXNrTHJ1Q2FjaGUoZGlyZWN0b3J5LCBhcHBWZXJzaW9uLCB2YWx1ZUNvdW50LCBtYXhTaXplKTsKKyAgICAgICAgY2FjaGUucmVidWlsZEpvdXJuYWwoKTsKKyAgICAgICAgcmV0dXJuIGNhY2hlOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkSm91cm5hbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShqb3VybmFsRmlsZSkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIG1hZ2ljID0gU3RyZWFtcy5yZWFkQXNjaWlMaW5lKGluKTsKKyAgICAgICAgICAgIFN0cmluZyB2ZXJzaW9uID0gU3RyZWFtcy5yZWFkQXNjaWlMaW5lKGluKTsKKyAgICAgICAgICAgIFN0cmluZyBhcHBWZXJzaW9uU3RyaW5nID0gU3RyZWFtcy5yZWFkQXNjaWlMaW5lKGluKTsKKyAgICAgICAgICAgIFN0cmluZyB2YWx1ZUNvdW50U3RyaW5nID0gU3RyZWFtcy5yZWFkQXNjaWlMaW5lKGluKTsKKyAgICAgICAgICAgIFN0cmluZyBibGFuayA9IFN0cmVhbXMucmVhZEFzY2lpTGluZShpbik7CisgICAgICAgICAgICBpZiAoIU1BR0lDLmVxdWFscyhtYWdpYykKKyAgICAgICAgICAgICAgICAgICAgfHwgIVZFUlNJT05fMS5lcXVhbHModmVyc2lvbikKKyAgICAgICAgICAgICAgICAgICAgfHwgIUludGVnZXIudG9TdHJpbmcoYXBwVmVyc2lvbikuZXF1YWxzKGFwcFZlcnNpb25TdHJpbmcpCisgICAgICAgICAgICAgICAgICAgIHx8ICFJbnRlZ2VyLnRvU3RyaW5nKHZhbHVlQ291bnQpLmVxdWFscyh2YWx1ZUNvdW50U3RyaW5nKQorICAgICAgICAgICAgICAgICAgICB8fCAhIiIuZXF1YWxzKGJsYW5rKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigidW5leHBlY3RlZCBqb3VybmFsIGhlYWRlcjogWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgbWFnaWMgKyAiLCAiICsgdmVyc2lvbiArICIsICIgKyB2YWx1ZUNvdW50U3RyaW5nICsgIiwgIiArIGJsYW5rICsgIl0iKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICByZWFkSm91cm5hbExpbmUoU3RyZWFtcy5yZWFkQXNjaWlMaW5lKGluKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGVuZE9mSm91cm5hbCkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBJb1V0aWxzLmNsb3NlUXVpZXRseShpbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZEpvdXJuYWxMaW5lKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmdbXSBwYXJ0cyA9IGxpbmUuc3BsaXQoIiAiKTsKKyAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA8IDIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigidW5leHBlY3RlZCBqb3VybmFsIGxpbmU6ICIgKyBsaW5lKTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBrZXkgPSBwYXJ0c1sxXTsKKyAgICAgICAgaWYgKHBhcnRzWzBdLmVxdWFscyhSRU1PVkUpICYmIHBhcnRzLmxlbmd0aCA9PSAyKSB7CisgICAgICAgICAgICBscnVFbnRyaWVzLnJlbW92ZShrZXkpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgRW50cnkgZW50cnkgPSBscnVFbnRyaWVzLmdldChrZXkpOworICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgZW50cnkgPSBuZXcgRW50cnkoa2V5KTsKKyAgICAgICAgICAgIGxydUVudHJpZXMucHV0KGtleSwgZW50cnkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHBhcnRzWzBdLmVxdWFscyhDTEVBTikgJiYgcGFydHMubGVuZ3RoID09IDIgKyB2YWx1ZUNvdW50KSB7CisgICAgICAgICAgICBlbnRyeS5yZWFkYWJsZSA9IHRydWU7CisgICAgICAgICAgICBlbnRyeS5jdXJyZW50RWRpdG9yID0gbnVsbDsKKyAgICAgICAgICAgIGVudHJ5LnNldExlbmd0aHMoQXJyYXlzLmNvcHlPZlJhbmdlKHBhcnRzLCAyLCBwYXJ0cy5sZW5ndGgpKTsKKyAgICAgICAgfSBlbHNlIGlmIChwYXJ0c1swXS5lcXVhbHMoRElSVFkpICYmIHBhcnRzLmxlbmd0aCA9PSAyKSB7CisgICAgICAgICAgICBlbnRyeS5jdXJyZW50RWRpdG9yID0gbmV3IEVkaXRvcihlbnRyeSk7CisgICAgICAgIH0gZWxzZSBpZiAocGFydHNbMF0uZXF1YWxzKFJFQUQpICYmIHBhcnRzLmxlbmd0aCA9PSAyKSB7CisgICAgICAgICAgICAvLyB0aGlzIHdvcmsgd2FzIGFscmVhZHkgZG9uZSBieSBjYWxsaW5nIGxydUVudHJpZXMuZ2V0KCkKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigidW5leHBlY3RlZCBqb3VybmFsIGxpbmU6ICIgKyBsaW5lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGVzIHRoZSBpbml0aWFsIHNpemUgYW5kIGNvbGxlY3RzIGdhcmJhZ2UgYXMgYSBwYXJ0IG9mIG9wZW5pbmcgdGhlCisgICAgICogY2FjaGUuIERpcnR5IGVudHJpZXMgYXJlIGFzc3VtZWQgdG8gYmUgaW5jb25zaXN0ZW50IGFuZCB3aWxsIGJlIGRlbGV0ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHByb2Nlc3NKb3VybmFsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZGVsZXRlSWZFeGlzdHMoam91cm5hbEZpbGVUbXApOworICAgICAgICBmb3IgKEl0ZXJhdG9yPEVudHJ5PiBpID0gbHJ1RW50cmllcy52YWx1ZXMoKS5pdGVyYXRvcigpOyBpLmhhc05leHQoKTsgKSB7CisgICAgICAgICAgICBFbnRyeSBlbnRyeSA9IGkubmV4dCgpOworICAgICAgICAgICAgaWYgKGVudHJ5LmN1cnJlbnRFZGl0b3IgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IHQgPSAwOyB0IDwgdmFsdWVDb3VudDsgdCsrKSB7CisgICAgICAgICAgICAgICAgICAgIHNpemUgKz0gZW50cnkubGVuZ3Roc1t0XTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGVudHJ5LmN1cnJlbnRFZGl0b3IgPSBudWxsOworICAgICAgICAgICAgICAgIGZvciAoaW50IHQgPSAwOyB0IDwgdmFsdWVDb3VudDsgdCsrKSB7CisgICAgICAgICAgICAgICAgICAgIGRlbGV0ZUlmRXhpc3RzKGVudHJ5LmdldENsZWFuRmlsZSh0KSk7CisgICAgICAgICAgICAgICAgICAgIGRlbGV0ZUlmRXhpc3RzKGVudHJ5LmdldERpcnR5RmlsZSh0KSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGkucmVtb3ZlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGpvdXJuYWwgdGhhdCBvbWl0cyByZWR1bmRhbnQgaW5mb3JtYXRpb24uIFRoaXMgcmVwbGFjZXMgdGhlCisgICAgICogY3VycmVudCBqb3VybmFsIGlmIGl0IGV4aXN0cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIHJlYnVpbGRKb3VybmFsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGpvdXJuYWxXcml0ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgam91cm5hbFdyaXRlci5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgV3JpdGVyIHdyaXRlciA9IG5ldyBCdWZmZXJlZFdyaXRlcihuZXcgRmlsZVdyaXRlcihqb3VybmFsRmlsZVRtcCkpOworICAgICAgICB3cml0ZXIud3JpdGUoTUFHSUMpOworICAgICAgICB3cml0ZXIud3JpdGUoIlxuIik7CisgICAgICAgIHdyaXRlci53cml0ZShWRVJTSU9OXzEpOworICAgICAgICB3cml0ZXIud3JpdGUoIlxuIik7CisgICAgICAgIHdyaXRlci53cml0ZShJbnRlZ2VyLnRvU3RyaW5nKGFwcFZlcnNpb24pKTsKKyAgICAgICAgd3JpdGVyLndyaXRlKCJcbiIpOworICAgICAgICB3cml0ZXIud3JpdGUoSW50ZWdlci50b1N0cmluZyh2YWx1ZUNvdW50KSk7CisgICAgICAgIHdyaXRlci53cml0ZSgiXG4iKTsKKyAgICAgICAgd3JpdGVyLndyaXRlKCJcbiIpOworCisgICAgICAgIGZvciAoRW50cnkgZW50cnkgOiBscnVFbnRyaWVzLnZhbHVlcygpKSB7CisgICAgICAgICAgICBpZiAoZW50cnkuY3VycmVudEVkaXRvciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKERJUlRZICsgJyAnICsgZW50cnkua2V5ICsgJ1xuJyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShDTEVBTiArICcgJyArIGVudHJ5LmtleSArIGVudHJ5LmdldExlbmd0aHMoKSArICdcbicpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgd3JpdGVyLmNsb3NlKCk7CisgICAgICAgIGpvdXJuYWxGaWxlVG1wLnJlbmFtZVRvKGpvdXJuYWxGaWxlKTsKKyAgICAgICAgam91cm5hbFdyaXRlciA9IG5ldyBCdWZmZXJlZFdyaXRlcihuZXcgRmlsZVdyaXRlcihqb3VybmFsRmlsZSwgdHJ1ZSkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZGVsZXRlSWZFeGlzdHMoRmlsZSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgTGliY29yZS5vcy5yZW1vdmUoZmlsZS5nZXRQYXRoKCkpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgaWYgKGVycm5vRXhjZXB0aW9uLmVycm5vICE9IE9zQ29uc3RhbnRzLkVOT0VOVCkgeworICAgICAgICAgICAgICAgIHRocm93IGVycm5vRXhjZXB0aW9uLnJldGhyb3dBc0lPRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgc25hcHNob3Qgb2YgdGhlIGVudHJ5IG5hbWVkIHtAY29kZSBrZXl9LCBvciBudWxsIGlmIGl0IGRvZXNuJ3QKKyAgICAgKiBleGlzdCBpcyBub3QgY3VycmVudGx5IHJlYWRhYmxlLiBJZiBhIHZhbHVlIGlzIHJldHVybmVkLCBpdCBpcyBtb3ZlZCB0bworICAgICAqIHRoZSBoZWFkIG9mIHRoZSBMUlUgcXVldWUuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTbmFwc2hvdCBnZXQoU3RyaW5nIGtleSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgdmFsaWRhdGVLZXkoa2V5KTsKKyAgICAgICAgRW50cnkgZW50cnkgPSBscnVFbnRyaWVzLmdldChrZXkpOworICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWVudHJ5LnJlYWRhYmxlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIE9wZW4gYWxsIHN0cmVhbXMgZWFnZXJseSB0byBndWFyYW50ZWUgdGhhdCB3ZSBzZWUgYSBzaW5nbGUgcHVibGlzaGVkCisgICAgICAgICAqIHNuYXBzaG90LiBJZiB3ZSBvcGVuZWQgc3RyZWFtcyBsYXppbHkgdGhlbiB0aGUgc3RyZWFtcyBjb3VsZCBjb21lCisgICAgICAgICAqIGZyb20gZGlmZmVyZW50IGVkaXRzLgorICAgICAgICAgKi8KKyAgICAgICAgSW5wdXRTdHJlYW1bXSBpbnMgPSBuZXcgSW5wdXRTdHJlYW1bdmFsdWVDb3VudF07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbHVlQ291bnQ7IGkrKykgeworICAgICAgICAgICAgICAgIGluc1tpXSA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZW50cnkuZ2V0Q2xlYW5GaWxlKGkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGEgZmlsZSBtdXN0IGhhdmUgYmVlbiBkZWxldGVkIG1hbnVhbGx5IQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICByZWR1bmRhbnRPcENvdW50Kys7CisgICAgICAgIGpvdXJuYWxXcml0ZXIuYXBwZW5kKFJFQUQgKyAnICcgKyBrZXkgKyAnXG4nKTsKKyAgICAgICAgaWYgKGpvdXJuYWxSZWJ1aWxkUmVxdWlyZWQoKSkgeworICAgICAgICAgICAgZXhlY3V0b3JTZXJ2aWNlLnN1Ym1pdChjbGVhbnVwQ2FsbGFibGUpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ldyBTbmFwc2hvdChpbnMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gZWRpdG9yIGZvciB0aGUgZW50cnkgbmFtZWQge0Bjb2RlIGtleX0sIG9yIG51bGwgaWYgaXQgY2Fubm90CisgICAgICogY3VycmVudGx5IGJlIGVkaXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEVkaXRvciBlZGl0KFN0cmluZyBrZXkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgIHZhbGlkYXRlS2V5KGtleSk7CisgICAgICAgIEVudHJ5IGVudHJ5ID0gbHJ1RW50cmllcy5nZXQoa2V5KTsKKyAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKKyAgICAgICAgICAgIGVudHJ5ID0gbmV3IEVudHJ5KGtleSk7CisgICAgICAgICAgICBscnVFbnRyaWVzLnB1dChrZXksIGVudHJ5KTsKKyAgICAgICAgfSBlbHNlIGlmIChlbnRyeS5jdXJyZW50RWRpdG9yICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgRWRpdG9yIGVkaXRvciA9IG5ldyBFZGl0b3IoZW50cnkpOworICAgICAgICBlbnRyeS5jdXJyZW50RWRpdG9yID0gZWRpdG9yOworCisgICAgICAgIC8vIGZsdXNoIHRoZSBqb3VybmFsIGJlZm9yZSBjcmVhdGluZyBmaWxlcyB0byBwcmV2ZW50IGZpbGUgbGVha3MKKyAgICAgICAgam91cm5hbFdyaXRlci53cml0ZShESVJUWSArICcgJyArIGtleSArICdcbicpOworICAgICAgICBqb3VybmFsV3JpdGVyLmZsdXNoKCk7CisgICAgICAgIHJldHVybiBlZGl0b3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGlyZWN0b3J5IHdoZXJlIHRoaXMgY2FjaGUgc3RvcmVzIGl0cyBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyBGaWxlIGdldERpcmVjdG9yeSgpIHsKKyAgICAgICAgcmV0dXJuIGRpcmVjdG9yeTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0aGF0IHRoaXMgY2FjaGUgc2hvdWxkIHVzZSB0byBzdG9yZQorICAgICAqIGl0cyBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIG1heFNpemUoKSB7CisgICAgICAgIHJldHVybiBtYXhTaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyBjdXJyZW50bHkgYmVpbmcgdXNlZCB0byBzdG9yZSB0aGUgdmFsdWVzIGluCisgICAgICogdGhpcyBjYWNoZS4gVGhpcyBtYXkgYmUgZ3JlYXRlciB0aGFuIHRoZSBtYXggc2l6ZSBpZiBhIGJhY2tncm91bmQKKyAgICAgKiBkZWxldGlvbiBpcyBwZW5kaW5nLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgbG9uZyBzaXplKCkgeworICAgICAgICByZXR1cm4gc2l6ZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIGNvbXBsZXRlRWRpdChFZGl0b3IgZWRpdG9yLCBib29sZWFuIHN1Y2Nlc3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEVudHJ5IGVudHJ5ID0gZWRpdG9yLmVudHJ5OworICAgICAgICBpZiAoZW50cnkuY3VycmVudEVkaXRvciAhPSBlZGl0b3IpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGlmIHRoaXMgZWRpdCBpcyBjcmVhdGluZyB0aGUgZW50cnkgZm9yIHRoZSBmaXJzdCB0aW1lLCBldmVyeSBpbmRleCBtdXN0IGhhdmUgYSB2YWx1ZQorICAgICAgICBpZiAoc3VjY2VzcyAmJiAhZW50cnkucmVhZGFibGUpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsdWVDb3VudDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKCFlbnRyeS5nZXREaXJ0eUZpbGUoaSkuZXhpc3RzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZWRpdG9yLmFib3J0KCk7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oImVkaXQgZGlkbid0IGNyZWF0ZSBmaWxlICIgKyBpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbHVlQ291bnQ7IGkrKykgeworICAgICAgICAgICAgRmlsZSBkaXJ0eSA9IGVudHJ5LmdldERpcnR5RmlsZShpKTsKKyAgICAgICAgICAgIGlmIChzdWNjZXNzKSB7CisgICAgICAgICAgICAgICAgaWYgKGRpcnR5LmV4aXN0cygpKSB7CisgICAgICAgICAgICAgICAgICAgIEZpbGUgY2xlYW4gPSBlbnRyeS5nZXRDbGVhbkZpbGUoaSk7CisgICAgICAgICAgICAgICAgICAgIGRpcnR5LnJlbmFtZVRvKGNsZWFuKTsKKyAgICAgICAgICAgICAgICAgICAgbG9uZyBvbGRMZW5ndGggPSBlbnRyeS5sZW5ndGhzW2ldOworICAgICAgICAgICAgICAgICAgICBsb25nIG5ld0xlbmd0aCA9IGNsZWFuLmxlbmd0aCgpOworICAgICAgICAgICAgICAgICAgICBlbnRyeS5sZW5ndGhzW2ldID0gbmV3TGVuZ3RoOworICAgICAgICAgICAgICAgICAgICBzaXplID0gc2l6ZSAtIG9sZExlbmd0aCArIG5ld0xlbmd0aDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGRlbGV0ZUlmRXhpc3RzKGRpcnR5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJlZHVuZGFudE9wQ291bnQrKzsKKyAgICAgICAgZW50cnkuY3VycmVudEVkaXRvciA9IG51bGw7CisgICAgICAgIGlmIChlbnRyeS5yZWFkYWJsZSB8IHN1Y2Nlc3MpIHsKKyAgICAgICAgICAgIGVudHJ5LnJlYWRhYmxlID0gdHJ1ZTsKKyAgICAgICAgICAgIGpvdXJuYWxXcml0ZXIud3JpdGUoQ0xFQU4gKyAnICcgKyBlbnRyeS5rZXkgKyBlbnRyeS5nZXRMZW5ndGhzKCkgKyAnXG4nKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGxydUVudHJpZXMucmVtb3ZlKGVudHJ5LmtleSk7CisgICAgICAgICAgICBqb3VybmFsV3JpdGVyLndyaXRlKFJFTU9WRSArICcgJyArIGVudHJ5LmtleSArICdcbicpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHNpemUgPiBtYXhTaXplIHx8IGpvdXJuYWxSZWJ1aWxkUmVxdWlyZWQoKSkgeworICAgICAgICAgICAgZXhlY3V0b3JTZXJ2aWNlLnN1Ym1pdChjbGVhbnVwQ2FsbGFibGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV2Ugb25seSByZWJ1aWxkIHRoZSBqb3VybmFsIHdoZW4gaXQgd2lsbCBoYWx2ZSB0aGUgc2l6ZSBvZiB0aGUgam91cm5hbAorICAgICAqIGFuZCBlbGltaW5hdGUgYXQgbGVhc3QgMjAwMCBvcHMuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGpvdXJuYWxSZWJ1aWxkUmVxdWlyZWQoKSB7CisgICAgICAgIGZpbmFsIGludCBSRURVTkRBTlRfT1BfQ09NUEFDVF9USFJFU0hPTEQgPSAyMDAwOworICAgICAgICByZXR1cm4gcmVkdW5kYW50T3BDb3VudCA+PSBSRURVTkRBTlRfT1BfQ09NUEFDVF9USFJFU0hPTEQKKyAgICAgICAgICAgICAgICAmJiByZWR1bmRhbnRPcENvdW50ID49IGxydUVudHJpZXMuc2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERyb3BzIHRoZSBlbnRyeSBmb3Ige0Bjb2RlIGtleX0gaWYgaXQgZXhpc3RzIGFuZCBjYW4gYmUgcmVtb3ZlZC4gRW50cmllcworICAgICAqIGFjdGl2ZWx5IGJlaW5nIGVkaXRlZCBjYW5ub3QgYmUgcmVtb3ZlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBhbiBlbnRyeSB3YXMgcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gcmVtb3ZlKFN0cmluZyBrZXkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgIHZhbGlkYXRlS2V5KGtleSk7CisgICAgICAgIEVudHJ5IGVudHJ5ID0gbHJ1RW50cmllcy5nZXQoa2V5KTsKKyAgICAgICAgaWYgKGVudHJ5ID09IG51bGwgfHwgZW50cnkuY3VycmVudEVkaXRvciAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbHVlQ291bnQ7IGkrKykgeworICAgICAgICAgICAgRmlsZSBmaWxlID0gZW50cnkuZ2V0Q2xlYW5GaWxlKGkpOworICAgICAgICAgICAgaWYgKCFmaWxlLmRlbGV0ZSgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJmYWlsZWQgdG8gZGVsZXRlICIgKyBmaWxlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNpemUgLT0gZW50cnkubGVuZ3Roc1tpXTsKKyAgICAgICAgICAgIGVudHJ5Lmxlbmd0aHNbaV0gPSAwOworICAgICAgICB9CisKKyAgICAgICAgcmVkdW5kYW50T3BDb3VudCsrOworICAgICAgICBqb3VybmFsV3JpdGVyLmFwcGVuZChSRU1PVkUgKyAnICcgKyBrZXkgKyAnXG4nKTsKKyAgICAgICAgbHJ1RW50cmllcy5yZW1vdmUoa2V5KTsKKworICAgICAgICBpZiAoam91cm5hbFJlYnVpbGRSZXF1aXJlZCgpKSB7CisgICAgICAgICAgICBleGVjdXRvclNlcnZpY2Uuc3VibWl0KGNsZWFudXBDYWxsYWJsZSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBjYWNoZSBoYXMgYmVlbiBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDbG9zZWQoKSB7CisgICAgICAgIHJldHVybiBqb3VybmFsV3JpdGVyID09IG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrTm90Q2xvc2VkKCkgeworICAgICAgICBpZiAoam91cm5hbFdyaXRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJjYWNoZSBpcyBjbG9zZWQiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZvcmNlIGJ1ZmZlcmVkIG9wZXJhdGlvbnMgdG8gdGhlIGZpbGVzeXN0ZW0uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGZsdXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgdHJpbVRvU2l6ZSgpOworICAgICAgICBqb3VybmFsV3JpdGVyLmZsdXNoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgY2FjaGUuIFN0b3JlZCB2YWx1ZXMgd2lsbCByZW1haW4gb24gdGhlIGZpbGVzeXN0ZW0uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGpvdXJuYWxXcml0ZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOyAvLyBhbHJlYWR5IGNsb3NlZAorICAgICAgICB9CisgICAgICAgIGZvciAoRW50cnkgZW50cnkgOiBuZXcgQXJyYXlMaXN0PEVudHJ5PihscnVFbnRyaWVzLnZhbHVlcygpKSkgeworICAgICAgICAgICAgaWYgKGVudHJ5LmN1cnJlbnRFZGl0b3IgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGVudHJ5LmN1cnJlbnRFZGl0b3IuYWJvcnQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0cmltVG9TaXplKCk7CisgICAgICAgIGpvdXJuYWxXcml0ZXIuY2xvc2UoKTsKKyAgICAgICAgam91cm5hbFdyaXRlciA9IG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRyaW1Ub1NpemUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3aGlsZSAoc2l6ZSA+IG1heFNpemUpIHsKKyAgICAgICAgICAgIE1hcC5FbnRyeTxTdHJpbmcsIEVudHJ5PiB0b0V2aWN0ID0gbHJ1RW50cmllcy5lbGRlc3QoKTsKKyAgICAgICAgICAgIHJlbW92ZSh0b0V2aWN0LmdldEtleSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGUgY2FjaGUgYW5kIGRlbGV0ZXMgYWxsIG9mIGl0cyBzdG9yZWQgdmFsdWVzLiBUaGlzIHdpbGwgZGVsZXRlCisgICAgICogYWxsIGZpbGVzIGluIHRoZSBjYWNoZSBkaXJlY3RvcnkgaW5jbHVkaW5nIGZpbGVzIHRoYXQgd2VyZW4ndCBjcmVhdGVkIGJ5CisgICAgICogdGhlIGNhY2hlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRlbGV0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNsb3NlKCk7CisgICAgICAgIElvVXRpbHMuZGVsZXRlQ29udGVudHMoZGlyZWN0b3J5KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdmFsaWRhdGVLZXkoU3RyaW5nIGtleSkgeworICAgICAgICBpZiAoa2V5LmNvbnRhaW5zKCIgIikgfHwga2V5LmNvbnRhaW5zKCJcbiIpIHx8IGtleS5jb250YWlucygiXHIiKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgImtleXMgbXVzdCBub3QgY29udGFpbiBzcGFjZXMgb3IgbmV3bGluZXM6IFwiIiArIGtleSArICJcIiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGlucHV0U3RyZWFtVG9TdHJpbmcoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBTdHJlYW1zLnJlYWRGdWxseShuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaW4sIENoYXJzZXRzLlVURl84KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBzbmFwc2hvdCBvZiB0aGUgdmFsdWVzIGZvciBhbiBlbnRyeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFNuYXBzaG90IGltcGxlbWVudHMgQ2xvc2VhYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBJbnB1dFN0cmVhbVtdIGluczsKKworICAgICAgICBwcml2YXRlIFNuYXBzaG90KElucHV0U3RyZWFtW10gaW5zKSB7CisgICAgICAgICAgICB0aGlzLmlucyA9IGluczsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIHRoZSB1bmJ1ZmZlcmVkIHN0cmVhbSB3aXRoIHRoZSB2YWx1ZSBmb3Ige0Bjb2RlIGluZGV4fS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbShpbnQgaW5kZXgpIHsKKyAgICAgICAgICAgIHJldHVybiBpbnNbaW5kZXhdOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIHN0cmluZyB2YWx1ZSBmb3Ige0Bjb2RlIGluZGV4fS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nKGludCBpbmRleCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBpbnB1dFN0cmVhbVRvU3RyaW5nKGdldElucHV0U3RyZWFtKGluZGV4KSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgICAgICBmb3IgKElucHV0U3RyZWFtIGluIDogaW5zKSB7CisgICAgICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkoaW4pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRWRpdHMgdGhlIHZhbHVlcyBmb3IgYW4gZW50cnkuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGNsYXNzIEVkaXRvciB7CisgICAgICAgIHByaXZhdGUgZmluYWwgRW50cnkgZW50cnk7CisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBoYXNFcnJvcnM7CisKKyAgICAgICAgcHJpdmF0ZSBFZGl0b3IoRW50cnkgZW50cnkpIHsKKyAgICAgICAgICAgIHRoaXMuZW50cnkgPSBlbnRyeTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZXR1cm5zIGFuIHVuYnVmZmVyZWQgaW5wdXQgc3RyZWFtIHRvIHJlYWQgdGhlIGxhc3QgY29tbWl0dGVkIHZhbHVlLAorICAgICAgICAgKiBvciBudWxsIGlmIG5vIHZhbHVlIGhhcyBiZWVuIGNvbW1pdHRlZC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBuZXdJbnB1dFN0cmVhbShpbnQgaW5kZXgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKERpc2tMcnVDYWNoZS50aGlzKSB7CisgICAgICAgICAgICAgICAgaWYgKGVudHJ5LmN1cnJlbnRFZGl0b3IgIT0gdGhpcykgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICghZW50cnkucmVhZGFibGUpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRmlsZUlucHV0U3RyZWFtKGVudHJ5LmdldENsZWFuRmlsZShpbmRleCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJldHVybnMgdGhlIGxhc3QgY29tbWl0dGVkIHZhbHVlIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIG5vIHZhbHVlCisgICAgICAgICAqIGhhcyBiZWVuIGNvbW1pdHRlZC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nKGludCBpbmRleCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIElucHV0U3RyZWFtIGluID0gbmV3SW5wdXRTdHJlYW0oaW5kZXgpOworICAgICAgICAgICAgcmV0dXJuIGluICE9IG51bGwgPyBpbnB1dFN0cmVhbVRvU3RyaW5nKGluKSA6IG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyBhIG5ldyB1bmJ1ZmZlcmVkIG91dHB1dCBzdHJlYW0gdG8gd3JpdGUgdGhlIHZhbHVlIGF0CisgICAgICAgICAqIHtAY29kZSBpbmRleH0uIElmIHRoZSB1bmRlcmx5aW5nIG91dHB1dCBzdHJlYW0gZW5jb3VudGVycyBlcnJvcnMKKyAgICAgICAgICogd2hlbiB3cml0aW5nIHRvIHRoZSBmaWxlc3lzdGVtLCB0aGlzIGVkaXQgd2lsbCBiZSBhYm9ydGVkIHdoZW4KKyAgICAgICAgICoge0BsaW5rICNjb21taXR9IGlzIGNhbGxlZC4gVGhlIHJldHVybmVkIG91dHB1dCBzdHJlYW0gZG9lcyBub3QgdGhyb3cKKyAgICAgICAgICogSU9FeGNlcHRpb25zLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIE91dHB1dFN0cmVhbSBuZXdPdXRwdXRTdHJlYW0oaW50IGluZGV4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgc3luY2hyb25pemVkIChEaXNrTHJ1Q2FjaGUudGhpcykgeworICAgICAgICAgICAgICAgIGlmIChlbnRyeS5jdXJyZW50RWRpdG9yICE9IHRoaXMpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEZhdWx0SGlkaW5nT3V0cHV0U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKGVudHJ5LmdldERpcnR5RmlsZShpbmRleCkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTZXRzIHRoZSB2YWx1ZSBhdCB7QGNvZGUgaW5kZXh9IHRvIHtAY29kZSB2YWx1ZX0uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCBzZXQoaW50IGluZGV4LCBTdHJpbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBXcml0ZXIgd3JpdGVyID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgd3JpdGVyID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihuZXdPdXRwdXRTdHJlYW0oaW5kZXgpLCBDaGFyc2V0cy5VVEZfOCk7CisgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKHZhbHVlKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkod3JpdGVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb21taXRzIHRoaXMgZWRpdCBzbyBpdCBpcyB2aXNpYmxlIHRvIHJlYWRlcnMuICBUaGlzIHJlbGVhc2VzIHRoZQorICAgICAgICAgKiBlZGl0IGxvY2sgc28gYW5vdGhlciBlZGl0IG1heSBiZSBzdGFydGVkIG9uIHRoZSBzYW1lIGtleS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyB2b2lkIGNvbW1pdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoaGFzRXJyb3JzKSB7CisgICAgICAgICAgICAgICAgY29tcGxldGVFZGl0KHRoaXMsIGZhbHNlKTsKKyAgICAgICAgICAgICAgICByZW1vdmUoZW50cnkua2V5KTsgLy8gdGhlIHByZXZpb3VzIGVudHJ5IGlzIHN0YWxlCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGNvbXBsZXRlRWRpdCh0aGlzLCB0cnVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBBYm9ydHMgdGhpcyBlZGl0LiBUaGlzIHJlbGVhc2VzIHRoZSBlZGl0IGxvY2sgc28gYW5vdGhlciBlZGl0IG1heSBiZQorICAgICAgICAgKiBzdGFydGVkIG9uIHRoZSBzYW1lIGtleS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyB2b2lkIGFib3J0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGNvbXBsZXRlRWRpdCh0aGlzLCBmYWxzZSk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIGNsYXNzIEZhdWx0SGlkaW5nT3V0cHV0U3RyZWFtIGV4dGVuZHMgRmlsdGVyT3V0cHV0U3RyZWFtIHsKKyAgICAgICAgICAgIHByaXZhdGUgRmF1bHRIaWRpbmdPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgICAgICAgICAgIHN1cGVyKG91dCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCB3cml0ZShpbnQgb25lQnl0ZSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIG91dC53cml0ZShvbmVCeXRlKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGhhc0Vycm9ycyA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIG91dC53cml0ZShidWZmZXIsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGhhc0Vycm9ycyA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBoYXNFcnJvcnMgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGZsdXNoKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgaGFzRXJyb3JzID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIGNsYXNzIEVudHJ5IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcga2V5OworCisgICAgICAgIC8qKiBMZW5ndGhzIG9mIHRoaXMgZW50cnkncyBmaWxlcy4gKi8KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBsb25nW10gbGVuZ3RoczsKKworICAgICAgICAvKiogVHJ1ZSBpZiB0aGlzIGVudHJ5IGhhcyBldmVyIGJlZW4gcHVibGlzaGVkICovCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiByZWFkYWJsZTsKKworICAgICAgICAvKiogVGhlIG9uZ29pbmcgZWRpdCBvciBudWxsIGlmIHRoaXMgZW50cnkgaXMgbm90IGJlaW5nIGVkaXRlZC4gKi8KKyAgICAgICAgcHJpdmF0ZSBFZGl0b3IgY3VycmVudEVkaXRvcjsKKworICAgICAgICBwcml2YXRlIEVudHJ5KFN0cmluZyBrZXkpIHsKKyAgICAgICAgICAgIHRoaXMua2V5ID0ga2V5OworICAgICAgICAgICAgdGhpcy5sZW5ndGhzID0gbmV3IGxvbmdbdmFsdWVDb3VudF07CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldExlbmd0aHMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICAgICAgZm9yIChsb25nIHNpemUgOiBsZW5ndGhzKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnICcpLmFwcGVuZChzaXplKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTZXQgbGVuZ3RocyB1c2luZyBkZWNpbWFsIG51bWJlcnMgbGlrZSAiMTAxMjMiLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSB2b2lkIHNldExlbmd0aHMoU3RyaW5nW10gc3RyaW5ncykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChzdHJpbmdzLmxlbmd0aCAhPSB2YWx1ZUNvdW50KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgaW52YWxpZExlbmd0aHMoc3RyaW5ncyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdHJpbmdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGxlbmd0aHNbaV0gPSBMb25nLnBhcnNlTG9uZyhzdHJpbmdzW2ldKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IGludmFsaWRMZW5ndGhzKHN0cmluZ3MpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBJT0V4Y2VwdGlvbiBpbnZhbGlkTGVuZ3RocyhTdHJpbmdbXSBzdHJpbmdzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJ1bmV4cGVjdGVkIGpvdXJuYWwgbGluZTogIiArIEFycmF5cy50b1N0cmluZyhzdHJpbmdzKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgRmlsZSBnZXRDbGVhbkZpbGUoaW50IGkpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgRmlsZShkaXJlY3RvcnksIGtleSArICIuIiArIGkpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEZpbGUgZ2V0RGlydHlGaWxlKGludCBpKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEZpbGUoZGlyZWN0b3J5LCBrZXkgKyAiLiIgKyBpICsgIi50bXAiKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL0Vycm5vRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9FcnJub0V4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY0ODRjZTkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9FcnJub0V4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlNvY2tldEV4Y2VwdGlvbjsKKworLyoqCisgKiBBIGNoZWNrZWQgZXhjZXB0aW9uIHRocm93biB3aGVuIHtAbGluayBPc30gbWV0aG9kcyBmYWlsLiBUaGlzIGV4Y2VwdGlvbiBjb250YWlucyB0aGUgbmF0aXZlCisgKiBlcnJubyB2YWx1ZSwgZm9yIGNvbXBhcmlzb24gYWdhaW5zdCB0aGUgY29uc3RhbnRzIGluIHtAbGluayBPc0NvbnN0YW50c30sIHNob3VsZCBzb3BoaXN0aWNhdGVkCisgKiBjYWxsZXJzIG5lZWQgdG8gYWRqdXN0IHRoZWlyIGJlaGF2aW9yIGJhc2VkIG9uIHRoZSBleGFjdCBmYWlsdXJlLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRXJybm9FeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGZ1bmN0aW9uTmFtZTsKKyAgICBwdWJsaWMgZmluYWwgaW50IGVycm5vOworCisgICAgcHVibGljIEVycm5vRXhjZXB0aW9uKFN0cmluZyBmdW5jdGlvbk5hbWUsIGludCBlcnJubykgeworICAgICAgICB0aGlzLmZ1bmN0aW9uTmFtZSA9IGZ1bmN0aW9uTmFtZTsKKyAgICAgICAgdGhpcy5lcnJubyA9IGVycm5vOworICAgIH0KKworICAgIHB1YmxpYyBFcnJub0V4Y2VwdGlvbihTdHJpbmcgZnVuY3Rpb25OYW1lLCBpbnQgZXJybm8sIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICBzdXBlcihjYXVzZSk7CisgICAgICAgIHRoaXMuZnVuY3Rpb25OYW1lID0gZnVuY3Rpb25OYW1lOworICAgICAgICB0aGlzLmVycm5vID0gZXJybm87CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhlIHN0YXNoZWQgZnVuY3Rpb24gbmFtZSBhbmQgZXJybm8gdmFsdWUgdG8gYSBodW1hbi1yZWFkYWJsZSBzdHJpbmcuCisgICAgICogV2UgZG8gdGhpcyBoZXJlIHJhdGhlciB0aGFuIGluIHRoZSBjb25zdHJ1Y3RvciBzbyB0aGF0IGNhbGxlcnMgb25seSBwYXkgZm9yCisgICAgICogdGhpcyBpZiB0aGV5IG5lZWQgaXQuCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKyAgICAgICAgU3RyaW5nIGVycm5vTmFtZSA9IE9zQ29uc3RhbnRzLmVycm5vTmFtZShlcnJubyk7CisgICAgICAgIGlmIChlcnJub05hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgZXJybm9OYW1lID0gImVycm5vICIgKyBlcnJubzsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgZGVzY3JpcHRpb24gPSBMaWJjb3JlLm9zLnN0cmVycm9yKGVycm5vKTsKKyAgICAgICAgcmV0dXJuIGZ1bmN0aW9uTmFtZSArICIgZmFpbGVkOiAiICsgZXJybm9OYW1lICsgIiAoIiArIGRlc2NyaXB0aW9uICsgIikiOworICAgIH0KKworICAgIHB1YmxpYyBJT0V4Y2VwdGlvbiByZXRocm93QXNJT0V4Y2VwdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIElPRXhjZXB0aW9uIG5ld0V4Y2VwdGlvbiA9IG5ldyBJT0V4Y2VwdGlvbihnZXRNZXNzYWdlKCkpOworICAgICAgICBuZXdFeGNlcHRpb24uaW5pdENhdXNlKHRoaXMpOworICAgICAgICB0aHJvdyBuZXdFeGNlcHRpb247CisgICAgfQorCisgICAgcHVibGljIFNvY2tldEV4Y2VwdGlvbiByZXRocm93QXNTb2NrZXRFeGNlcHRpb24oKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbihnZXRNZXNzYWdlKCksIHRoaXMpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL0ZvcndhcmRpbmdPcy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vRm9yd2FyZGluZ09zLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmM4ZTU2MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL0ZvcndhcmRpbmdPcy5qYXZhCkBAIC0wLDAgKzEsMTI4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmlvOworCitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0U29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgbGliY29yZS51dGlsLk11dGFibGVJbnQ7CitpbXBvcnQgbGliY29yZS51dGlsLk11dGFibGVMb25nOworCisvKioKKyAqIFN1YmNsYXNzIHRoaXMgaWYgeW91IHdhbnQgdG8gb3ZlcnJpZGUgc29tZSB7QGxpbmsgT3N9IG1ldGhvZHMgYnV0IG90aGVyd2lzZSBkZWxlZ2F0ZS4KKyAqLworcHVibGljIGNsYXNzIEZvcndhcmRpbmdPcyBpbXBsZW1lbnRzIE9zIHsKKyAgICBwcm90ZWN0ZWQgZmluYWwgT3Mgb3M7CisKKyAgICBwdWJsaWMgRm9yd2FyZGluZ09zKE9zIG9zKSB7CisgICAgICAgIHRoaXMub3MgPSBvczsKKyAgICB9CisKKyAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3IgYWNjZXB0KEZpbGVEZXNjcmlwdG9yIGZkLCBJbmV0U29ja2V0QWRkcmVzcyBwZWVyQWRkcmVzcykgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLmFjY2VwdChmZCwgcGVlckFkZHJlc3MpOyB9CisgICAgcHVibGljIGJvb2xlYW4gYWNjZXNzKFN0cmluZyBwYXRoLCBpbnQgbW9kZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLmFjY2VzcyhwYXRoLCBtb2RlKTsgfQorICAgIHB1YmxpYyB2b2lkIGJpbmQoRmlsZURlc2NyaXB0b3IgZmQsIEluZXRBZGRyZXNzIGFkZHJlc3MsIGludCBwb3J0KSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyBvcy5iaW5kKGZkLCBhZGRyZXNzLCBwb3J0KTsgfQorICAgIHB1YmxpYyB2b2lkIGNobW9kKFN0cmluZyBwYXRoLCBpbnQgbW9kZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgb3MuY2htb2QocGF0aCwgbW9kZSk7IH0KKyAgICBwdWJsaWMgdm9pZCBjbG9zZShGaWxlRGVzY3JpcHRvciBmZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgb3MuY2xvc2UoZmQpOyB9CisgICAgcHVibGljIHZvaWQgY29ubmVjdChGaWxlRGVzY3JpcHRvciBmZCwgSW5ldEFkZHJlc3MgYWRkcmVzcywgaW50IHBvcnQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IG9zLmNvbm5lY3QoZmQsIGFkZHJlc3MsIHBvcnQpOyB9CisgICAgcHVibGljIEZpbGVEZXNjcmlwdG9yIGR1cChGaWxlRGVzY3JpcHRvciBvbGRGZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLmR1cChvbGRGZCk7IH0KKyAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3IgZHVwMihGaWxlRGVzY3JpcHRvciBvbGRGZCwgaW50IG5ld0ZkKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyByZXR1cm4gb3MuZHVwMihvbGRGZCwgbmV3RmQpOyB9CisgICAgcHVibGljIFN0cmluZ1tdIGVudmlyb24oKSB7IHJldHVybiBvcy5lbnZpcm9uKCk7IH0KKyAgICBwdWJsaWMgaW50IGZjbnRsVm9pZChGaWxlRGVzY3JpcHRvciBmZCwgaW50IGNtZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLmZjbnRsVm9pZChmZCwgY21kKTsgfQorICAgIHB1YmxpYyBpbnQgZmNudGxMb25nKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgY21kLCBsb25nIGFyZykgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLmZjbnRsTG9uZyhmZCwgY21kLCBhcmcpOyB9CisgICAgcHVibGljIGludCBmY250bEZsb2NrKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgY21kLCBTdHJ1Y3RGbG9jayBhcmcpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy5mY250bEZsb2NrKGZkLCBjbWQsIGFyZyk7IH0KKyAgICBwdWJsaWMgdm9pZCBmZGF0YXN5bmMoRmlsZURlc2NyaXB0b3IgZmQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IG9zLmZkYXRhc3luYyhmZCk7IH0KKyAgICBwdWJsaWMgU3RydWN0U3RhdCBmc3RhdChGaWxlRGVzY3JpcHRvciBmZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLmZzdGF0KGZkKTsgfQorICAgIHB1YmxpYyBTdHJ1Y3RTdGF0RnMgZnN0YXRmcyhGaWxlRGVzY3JpcHRvciBmZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLmZzdGF0ZnMoZmQpOyB9CisgICAgcHVibGljIHZvaWQgZnN5bmMoRmlsZURlc2NyaXB0b3IgZmQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IG9zLmZzeW5jKGZkKTsgfQorICAgIHB1YmxpYyB2b2lkIGZ0cnVuY2F0ZShGaWxlRGVzY3JpcHRvciBmZCwgbG9uZyBsZW5ndGgpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IG9zLmZ0cnVuY2F0ZShmZCwgbGVuZ3RoKTsgfQorICAgIHB1YmxpYyBTdHJpbmcgZ2FpX3N0cmVycm9yKGludCBlcnJvcikgeyByZXR1cm4gb3MuZ2FpX3N0cmVycm9yKGVycm9yKTsgfQorICAgIHB1YmxpYyBJbmV0QWRkcmVzc1tdIGdldGFkZHJpbmZvKFN0cmluZyBub2RlLCBTdHJ1Y3RBZGRyaW5mbyBoaW50cykgdGhyb3dzIEdhaUV4Y2VwdGlvbiB7IHJldHVybiBvcy5nZXRhZGRyaW5mbyhub2RlLCBoaW50cyk7IH0KKyAgICBwdWJsaWMgaW50IGdldGVnaWQoKSB7IHJldHVybiBvcy5nZXRlZ2lkKCk7IH0KKyAgICBwdWJsaWMgaW50IGdldGV1aWQoKSB7IHJldHVybiBvcy5nZXRldWlkKCk7IH0KKyAgICBwdWJsaWMgaW50IGdldGdpZCgpIHsgcmV0dXJuIG9zLmdldGdpZCgpOyB9CisgICAgcHVibGljIFN0cmluZyBnZXRlbnYoU3RyaW5nIG5hbWUpIHsgcmV0dXJuIG9zLmdldGVudihuYW1lKTsgfQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0bmFtZWluZm8oSW5ldEFkZHJlc3MgYWRkcmVzcywgaW50IGZsYWdzKSB0aHJvd3MgR2FpRXhjZXB0aW9uIHsgcmV0dXJuIG9zLmdldG5hbWVpbmZvKGFkZHJlc3MsIGZsYWdzKTsgfQorICAgIHB1YmxpYyBpbnQgZ2V0cGlkKCkgeyByZXR1cm4gb3MuZ2V0cGlkKCk7IH0KKyAgICBwdWJsaWMgaW50IGdldHBwaWQoKSB7IHJldHVybiBvcy5nZXRwcGlkKCk7IH0KKyAgICBwdWJsaWMgU3RydWN0UGFzc3dkIGdldHB3bmFtKFN0cmluZyBuYW1lKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyByZXR1cm4gb3MuZ2V0cHduYW0obmFtZSk7IH0KKyAgICBwdWJsaWMgU3RydWN0UGFzc3dkIGdldHB3dWlkKGludCB1aWQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy5nZXRwd3VpZCh1aWQpOyB9CisgICAgcHVibGljIFNvY2tldEFkZHJlc3MgZ2V0c29ja25hbWUoRmlsZURlc2NyaXB0b3IgZmQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy5nZXRzb2NrbmFtZShmZCk7IH0KKyAgICBwdWJsaWMgaW50IGdldHNvY2tvcHRCeXRlKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgbGV2ZWwsIGludCBvcHRpb24pIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy5nZXRzb2Nrb3B0Qnl0ZShmZCwgbGV2ZWwsIG9wdGlvbik7IH0KKyAgICBwdWJsaWMgSW5ldEFkZHJlc3MgZ2V0c29ja29wdEluQWRkcihGaWxlRGVzY3JpcHRvciBmZCwgaW50IGxldmVsLCBpbnQgb3B0aW9uKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyByZXR1cm4gb3MuZ2V0c29ja29wdEluQWRkcihmZCwgbGV2ZWwsIG9wdGlvbik7IH0KKyAgICBwdWJsaWMgaW50IGdldHNvY2tvcHRJbnQoRmlsZURlc2NyaXB0b3IgZmQsIGludCBsZXZlbCwgaW50IG9wdGlvbikgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLmdldHNvY2tvcHRJbnQoZmQsIGxldmVsLCBvcHRpb24pOyB9CisgICAgcHVibGljIFN0cnVjdExpbmdlciBnZXRzb2Nrb3B0TGluZ2VyKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgbGV2ZWwsIGludCBvcHRpb24pIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy5nZXRzb2Nrb3B0TGluZ2VyKGZkLCBsZXZlbCwgb3B0aW9uKTsgfQorICAgIHB1YmxpYyBTdHJ1Y3RUaW1ldmFsIGdldHNvY2tvcHRUaW1ldmFsKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgbGV2ZWwsIGludCBvcHRpb24pIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy5nZXRzb2Nrb3B0VGltZXZhbChmZCwgbGV2ZWwsIG9wdGlvbik7IH0KKyAgICBwdWJsaWMgaW50IGdldHVpZCgpIHsgcmV0dXJuIG9zLmdldHVpZCgpOyB9CisgICAgcHVibGljIFN0cmluZyBpZl9pbmRleHRvbmFtZShpbnQgaW5kZXgpIHsgcmV0dXJuIG9zLmlmX2luZGV4dG9uYW1lKGluZGV4KTsgfQorICAgIHB1YmxpYyBJbmV0QWRkcmVzcyBpbmV0X3B0b24oaW50IGZhbWlseSwgU3RyaW5nIGFkZHJlc3MpIHsgcmV0dXJuIG9zLmluZXRfcHRvbihmYW1pbHksIGFkZHJlc3MpOyB9CisgICAgcHVibGljIEluZXRBZGRyZXNzIGlvY3RsSW5ldEFkZHJlc3MoRmlsZURlc2NyaXB0b3IgZmQsIGludCBjbWQsIFN0cmluZyBpbnRlcmZhY2VOYW1lKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyByZXR1cm4gb3MuaW9jdGxJbmV0QWRkcmVzcyhmZCwgY21kLCBpbnRlcmZhY2VOYW1lKTsgfQorICAgIHB1YmxpYyBpbnQgaW9jdGxJbnQoRmlsZURlc2NyaXB0b3IgZmQsIGludCBjbWQsIE11dGFibGVJbnQgYXJnKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyByZXR1cm4gb3MuaW9jdGxJbnQoZmQsIGNtZCwgYXJnKTsgfQorICAgIHB1YmxpYyBib29sZWFuIGlzYXR0eShGaWxlRGVzY3JpcHRvciBmZCkgeyByZXR1cm4gb3MuaXNhdHR5KGZkKTsgfQorICAgIHB1YmxpYyB2b2lkIGtpbGwoaW50IHBpZCwgaW50IHNpZ25hbCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgb3Mua2lsbChwaWQsIHNpZ25hbCk7IH0KKyAgICBwdWJsaWMgdm9pZCBsaXN0ZW4oRmlsZURlc2NyaXB0b3IgZmQsIGludCBiYWNrbG9nKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyBvcy5saXN0ZW4oZmQsIGJhY2tsb2cpOyB9CisgICAgcHVibGljIGxvbmcgbHNlZWsoRmlsZURlc2NyaXB0b3IgZmQsIGxvbmcgb2Zmc2V0LCBpbnQgd2hlbmNlKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyByZXR1cm4gb3MubHNlZWsoZmQsIG9mZnNldCwgd2hlbmNlKTsgfQorICAgIHB1YmxpYyBTdHJ1Y3RTdGF0IGxzdGF0KFN0cmluZyBwYXRoKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyByZXR1cm4gb3MubHN0YXQocGF0aCk7IH0KKyAgICBwdWJsaWMgdm9pZCBtaW5jb3JlKGxvbmcgYWRkcmVzcywgbG9uZyBieXRlQ291bnQsIGJ5dGVbXSB2ZWN0b3IpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IG9zLm1pbmNvcmUoYWRkcmVzcywgYnl0ZUNvdW50LCB2ZWN0b3IpOyB9CisgICAgcHVibGljIHZvaWQgbWtkaXIoU3RyaW5nIHBhdGgsIGludCBtb2RlKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyBvcy5ta2RpcihwYXRoLCBtb2RlKTsgfQorICAgIHB1YmxpYyB2b2lkIG1sb2NrKGxvbmcgYWRkcmVzcywgbG9uZyBieXRlQ291bnQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IG9zLm1sb2NrKGFkZHJlc3MsIGJ5dGVDb3VudCk7IH0KKyAgICBwdWJsaWMgbG9uZyBtbWFwKGxvbmcgYWRkcmVzcywgbG9uZyBieXRlQ291bnQsIGludCBwcm90LCBpbnQgZmxhZ3MsIEZpbGVEZXNjcmlwdG9yIGZkLCBsb25nIG9mZnNldCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLm1tYXAoYWRkcmVzcywgYnl0ZUNvdW50LCBwcm90LCBmbGFncywgZmQsIG9mZnNldCk7IH0KKyAgICBwdWJsaWMgdm9pZCBtc3luYyhsb25nIGFkZHJlc3MsIGxvbmcgYnl0ZUNvdW50LCBpbnQgZmxhZ3MpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IG9zLm1zeW5jKGFkZHJlc3MsIGJ5dGVDb3VudCwgZmxhZ3MpOyB9CisgICAgcHVibGljIHZvaWQgbXVubG9jayhsb25nIGFkZHJlc3MsIGxvbmcgYnl0ZUNvdW50KSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyBvcy5tdW5sb2NrKGFkZHJlc3MsIGJ5dGVDb3VudCk7IH0KKyAgICBwdWJsaWMgdm9pZCBtdW5tYXAobG9uZyBhZGRyZXNzLCBsb25nIGJ5dGVDb3VudCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgb3MubXVubWFwKGFkZHJlc3MsIGJ5dGVDb3VudCk7IH0KKyAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3Igb3BlbihTdHJpbmcgcGF0aCwgaW50IGZsYWdzLCBpbnQgbW9kZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLm9wZW4ocGF0aCwgZmxhZ3MsIG1vZGUpOyB9CisgICAgcHVibGljIEZpbGVEZXNjcmlwdG9yW10gcGlwZSgpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy5waXBlKCk7IH0KKyAgICBwdWJsaWMgaW50IHBvbGwoU3RydWN0UG9sbGZkW10gZmRzLCBpbnQgdGltZW91dE1zKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyByZXR1cm4gb3MucG9sbChmZHMsIHRpbWVvdXRNcyk7IH0KKyAgICBwdWJsaWMgaW50IHByZWFkKEZpbGVEZXNjcmlwdG9yIGZkLCBCeXRlQnVmZmVyIGJ1ZmZlciwgbG9uZyBvZmZzZXQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy5wcmVhZChmZCwgYnVmZmVyLCBvZmZzZXQpOyB9CisgICAgcHVibGljIGludCBwcmVhZChGaWxlRGVzY3JpcHRvciBmZCwgYnl0ZVtdIGJ5dGVzLCBpbnQgYnl0ZU9mZnNldCwgaW50IGJ5dGVDb3VudCwgbG9uZyBvZmZzZXQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy5wcmVhZChmZCwgYnl0ZXMsIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCwgb2Zmc2V0KTsgfQorICAgIHB1YmxpYyBpbnQgcHdyaXRlKEZpbGVEZXNjcmlwdG9yIGZkLCBCeXRlQnVmZmVyIGJ1ZmZlciwgbG9uZyBvZmZzZXQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy5wd3JpdGUoZmQsIGJ1ZmZlciwgb2Zmc2V0KTsgfQorICAgIHB1YmxpYyBpbnQgcHdyaXRlKEZpbGVEZXNjcmlwdG9yIGZkLCBieXRlW10gYnl0ZXMsIGludCBieXRlT2Zmc2V0LCBpbnQgYnl0ZUNvdW50LCBsb25nIG9mZnNldCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLnB3cml0ZShmZCwgYnl0ZXMsIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCwgb2Zmc2V0KTsgfQorICAgIHB1YmxpYyBpbnQgcmVhZChGaWxlRGVzY3JpcHRvciBmZCwgQnl0ZUJ1ZmZlciBidWZmZXIpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy5yZWFkKGZkLCBidWZmZXIpOyB9CisgICAgcHVibGljIGludCByZWFkKEZpbGVEZXNjcmlwdG9yIGZkLCBieXRlW10gYnl0ZXMsIGludCBieXRlT2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyByZXR1cm4gb3MucmVhZChmZCwgYnl0ZXMsIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCk7IH0KKyAgICBwdWJsaWMgaW50IHJlYWR2KEZpbGVEZXNjcmlwdG9yIGZkLCBPYmplY3RbXSBidWZmZXJzLCBpbnRbXSBvZmZzZXRzLCBpbnRbXSBieXRlQ291bnRzKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyByZXR1cm4gb3MucmVhZHYoZmQsIGJ1ZmZlcnMsIG9mZnNldHMsIGJ5dGVDb3VudHMpOyB9CisgICAgcHVibGljIGludCByZWN2ZnJvbShGaWxlRGVzY3JpcHRvciBmZCwgQnl0ZUJ1ZmZlciBidWZmZXIsIGludCBmbGFncywgSW5ldFNvY2tldEFkZHJlc3Mgc3JjQWRkcmVzcykgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLnJlY3Zmcm9tKGZkLCBidWZmZXIsIGZsYWdzLCBzcmNBZGRyZXNzKTsgfQorICAgIHB1YmxpYyBpbnQgcmVjdmZyb20oRmlsZURlc2NyaXB0b3IgZmQsIGJ5dGVbXSBieXRlcywgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQsIGludCBmbGFncywgSW5ldFNvY2tldEFkZHJlc3Mgc3JjQWRkcmVzcykgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLnJlY3Zmcm9tKGZkLCBieXRlcywgYnl0ZU9mZnNldCwgYnl0ZUNvdW50LCBmbGFncywgc3JjQWRkcmVzcyk7IH0KKyAgICBwdWJsaWMgdm9pZCByZW1vdmUoU3RyaW5nIHBhdGgpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IG9zLnJlbW92ZShwYXRoKTsgfQorICAgIHB1YmxpYyB2b2lkIHJlbmFtZShTdHJpbmcgb2xkUGF0aCwgU3RyaW5nIG5ld1BhdGgpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IG9zLnJlbmFtZShvbGRQYXRoLCBuZXdQYXRoKTsgfQorICAgIHB1YmxpYyBsb25nIHNlbmRmaWxlKEZpbGVEZXNjcmlwdG9yIG91dEZkLCBGaWxlRGVzY3JpcHRvciBpbkZkLCBNdXRhYmxlTG9uZyBpbk9mZnNldCwgbG9uZyBieXRlQ291bnQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy5zZW5kZmlsZShvdXRGZCwgaW5GZCwgaW5PZmZzZXQsIGJ5dGVDb3VudCk7IH0KKyAgICBwdWJsaWMgaW50IHNlbmR0byhGaWxlRGVzY3JpcHRvciBmZCwgQnl0ZUJ1ZmZlciBidWZmZXIsIGludCBmbGFncywgSW5ldEFkZHJlc3MgaW5ldEFkZHJlc3MsIGludCBwb3J0KSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyByZXR1cm4gb3Muc2VuZHRvKGZkLCBidWZmZXIsIGZsYWdzLCBpbmV0QWRkcmVzcywgcG9ydCk7IH0KKyAgICBwdWJsaWMgaW50IHNlbmR0byhGaWxlRGVzY3JpcHRvciBmZCwgYnl0ZVtdIGJ5dGVzLCBpbnQgYnl0ZU9mZnNldCwgaW50IGJ5dGVDb3VudCwgaW50IGZsYWdzLCBJbmV0QWRkcmVzcyBpbmV0QWRkcmVzcywgaW50IHBvcnQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy5zZW5kdG8oZmQsIGJ5dGVzLCBieXRlT2Zmc2V0LCBieXRlQ291bnQsIGZsYWdzLCBpbmV0QWRkcmVzcywgcG9ydCk7IH0KKyAgICBwdWJsaWMgdm9pZCBzZXRlZ2lkKGludCBlZ2lkKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyBvcy5zZXRlZ2lkKGVnaWQpOyB9CisgICAgcHVibGljIHZvaWQgc2V0ZXVpZChpbnQgZXVpZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgb3Muc2V0ZXVpZChldWlkKTsgfQorICAgIHB1YmxpYyB2b2lkIHNldGdpZChpbnQgZ2lkKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyBvcy5zZXRnaWQoZ2lkKTsgfQorICAgIHB1YmxpYyB2b2lkIHNldHNvY2tvcHRCeXRlKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgbGV2ZWwsIGludCBvcHRpb24sIGludCB2YWx1ZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgb3Muc2V0c29ja29wdEJ5dGUoZmQsIGxldmVsLCBvcHRpb24sIHZhbHVlKTsgfQorICAgIHB1YmxpYyB2b2lkIHNldHNvY2tvcHRJZnJlcShGaWxlRGVzY3JpcHRvciBmZCwgaW50IGxldmVsLCBpbnQgb3B0aW9uLCBTdHJpbmcgdmFsdWUpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IG9zLnNldHNvY2tvcHRJZnJlcShmZCwgbGV2ZWwsIG9wdGlvbiwgdmFsdWUpOyB9CisgICAgcHVibGljIHZvaWQgc2V0c29ja29wdEludChGaWxlRGVzY3JpcHRvciBmZCwgaW50IGxldmVsLCBpbnQgb3B0aW9uLCBpbnQgdmFsdWUpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IG9zLnNldHNvY2tvcHRJbnQoZmQsIGxldmVsLCBvcHRpb24sIHZhbHVlKTsgfQorICAgIHB1YmxpYyB2b2lkIHNldHNvY2tvcHRJcE1yZXFuKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgbGV2ZWwsIGludCBvcHRpb24sIGludCB2YWx1ZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgb3Muc2V0c29ja29wdElwTXJlcW4oZmQsIGxldmVsLCBvcHRpb24sIHZhbHVlKTsgfQorICAgIHB1YmxpYyB2b2lkIHNldHNvY2tvcHRHcm91cFJlcShGaWxlRGVzY3JpcHRvciBmZCwgaW50IGxldmVsLCBpbnQgb3B0aW9uLCBTdHJ1Y3RHcm91cFJlcSB2YWx1ZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgb3Muc2V0c29ja29wdEdyb3VwUmVxKGZkLCBsZXZlbCwgb3B0aW9uLCB2YWx1ZSk7IH0KKyAgICBwdWJsaWMgdm9pZCBzZXRzb2Nrb3B0TGluZ2VyKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgbGV2ZWwsIGludCBvcHRpb24sIFN0cnVjdExpbmdlciB2YWx1ZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgb3Muc2V0c29ja29wdExpbmdlcihmZCwgbGV2ZWwsIG9wdGlvbiwgdmFsdWUpOyB9CisgICAgcHVibGljIHZvaWQgc2V0c29ja29wdFRpbWV2YWwoRmlsZURlc2NyaXB0b3IgZmQsIGludCBsZXZlbCwgaW50IG9wdGlvbiwgU3RydWN0VGltZXZhbCB2YWx1ZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgb3Muc2V0c29ja29wdFRpbWV2YWwoZmQsIGxldmVsLCBvcHRpb24sIHZhbHVlKTsgfQorICAgIHB1YmxpYyB2b2lkIHNldHVpZChpbnQgdWlkKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyBvcy5zZXR1aWQodWlkKTsgfQorICAgIHB1YmxpYyB2b2lkIHNodXRkb3duKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgaG93KSB0aHJvd3MgRXJybm9FeGNlcHRpb24geyBvcy5zaHV0ZG93bihmZCwgaG93KTsgfQorICAgIHB1YmxpYyBGaWxlRGVzY3JpcHRvciBzb2NrZXQoaW50IGRvbWFpbiwgaW50IHR5cGUsIGludCBwcm90b2NvbCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLnNvY2tldChkb21haW4sIHR5cGUsIHByb3RvY29sKTsgfQorICAgIHB1YmxpYyBTdHJ1Y3RTdGF0IHN0YXQoU3RyaW5nIHBhdGgpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy5zdGF0KHBhdGgpOyB9CisgICAgcHVibGljIFN0cnVjdFN0YXRGcyBzdGF0ZnMoU3RyaW5nIHBhdGgpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy5zdGF0ZnMocGF0aCk7IH0KKyAgICBwdWJsaWMgU3RyaW5nIHN0cmVycm9yKGludCBlcnJubykgeyByZXR1cm4gb3Muc3RyZXJyb3IoZXJybm8pOyB9CisgICAgcHVibGljIHZvaWQgc3ltbGluayhTdHJpbmcgb2xkUGF0aCwgU3RyaW5nIG5ld1BhdGgpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IG9zLnN5bWxpbmsob2xkUGF0aCwgbmV3UGF0aCk7IH0KKyAgICBwdWJsaWMgbG9uZyBzeXNjb25mKGludCBuYW1lKSB7IHJldHVybiBvcy5zeXNjb25mKG5hbWUpOyB9CisgICAgcHVibGljIFN0cnVjdFV0c25hbWUgdW5hbWUoKSB7IHJldHVybiBvcy51bmFtZSgpOyB9CisgICAgcHVibGljIGludCB3YWl0cGlkKGludCBwaWQsIE11dGFibGVJbnQgc3RhdHVzLCBpbnQgb3B0aW9ucykgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLndhaXRwaWQocGlkLCBzdGF0dXMsIG9wdGlvbnMpOyB9CisgICAgcHVibGljIGludCB3cml0ZShGaWxlRGVzY3JpcHRvciBmZCwgQnl0ZUJ1ZmZlciBidWZmZXIpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy53cml0ZShmZCwgYnVmZmVyKTsgfQorICAgIHB1YmxpYyBpbnQgd3JpdGUoRmlsZURlc2NyaXB0b3IgZmQsIGJ5dGVbXSBieXRlcywgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7IHJldHVybiBvcy53cml0ZShmZCwgYnl0ZXMsIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCk7IH0KKyAgICBwdWJsaWMgaW50IHdyaXRldihGaWxlRGVzY3JpcHRvciBmZCwgT2JqZWN0W10gYnVmZmVycywgaW50W10gb2Zmc2V0cywgaW50W10gYnl0ZUNvdW50cykgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsgcmV0dXJuIG9zLndyaXRldihmZCwgYnVmZmVycywgb2Zmc2V0cywgYnl0ZUNvdW50cyk7IH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL0dhaUV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vR2FpRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDgxNDNkYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL0dhaUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuaW87CisKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKK2ltcG9ydCBsaWJjb3JlLmlvLk9zQ29uc3RhbnRzOworCisvKioKKyAqIEFuIHVuY2hlY2tlZCBleGNlcHRpb24gdGhyb3duIHdoZW4gdGhlIHtAbGluayBPc30ge0Bjb2RlIGdldGFkZHJpbmZvfSBvciB7QGNvZGUgZ2V0bmFtZWluZm99CisgKiBtZXRob2RzIGZhaWwuIFRoaXMgZXhjZXB0aW9uIGNvbnRhaW5zIHRoZSBuYXRpdmUgZXJyb3IgdmFsdWUsIGZvciBjb21wYXJpc29uIGFnYWluc3QgdGhlCisgKiB7QGNvZGUgR0FJX30gY29uc3RhbnRzIGluIHtAbGluayBPc0NvbnN0YW50c30sIHNob3VsZCBzb3BoaXN0aWNhdGVkCisgKiBjYWxsZXJzIG5lZWQgdG8gYWRqdXN0IHRoZWlyIGJlaGF2aW9yIGJhc2VkIG9uIHRoZSBleGFjdCBmYWlsdXJlLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgR2FpRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZnVuY3Rpb25OYW1lOworICAgIHB1YmxpYyBmaW5hbCBpbnQgZXJyb3I7CisKKyAgICBwdWJsaWMgR2FpRXhjZXB0aW9uKFN0cmluZyBmdW5jdGlvbk5hbWUsIGludCBlcnJvcikgeworICAgICAgICB0aGlzLmZ1bmN0aW9uTmFtZSA9IGZ1bmN0aW9uTmFtZTsKKyAgICAgICAgdGhpcy5lcnJvciA9IGVycm9yOworICAgIH0KKworICAgIHB1YmxpYyBHYWlFeGNlcHRpb24oU3RyaW5nIGZ1bmN0aW9uTmFtZSwgaW50IGVycm9yLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgICAgc3VwZXIoY2F1c2UpOworICAgICAgICB0aGlzLmZ1bmN0aW9uTmFtZSA9IGZ1bmN0aW9uTmFtZTsKKyAgICAgICAgdGhpcy5lcnJvciA9IGVycm9yOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIHRoZSBzdGFzaGVkIGZ1bmN0aW9uIG5hbWUgYW5kIGVycm9yIHZhbHVlIHRvIGEgaHVtYW4tcmVhZGFibGUgc3RyaW5nLgorICAgICAqIFdlIGRvIHRoaXMgaGVyZSByYXRoZXIgdGhhbiBpbiB0aGUgY29uc3RydWN0b3Igc28gdGhhdCBjYWxsZXJzIG9ubHkgcGF5IGZvcgorICAgICAqIHRoaXMgaWYgdGhleSBuZWVkIGl0LgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2UoKSB7CisgICAgICAgIFN0cmluZyBnYWlOYW1lID0gT3NDb25zdGFudHMuZ2FpTmFtZShlcnJvcik7CisgICAgICAgIGlmIChnYWlOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIGdhaU5hbWUgPSAiR0FJXyBlcnJvciAiICsgZXJyb3I7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIGRlc2NyaXB0aW9uID0gTGliY29yZS5vcy5nYWlfc3RyZXJyb3IoZXJyb3IpOworICAgICAgICByZXR1cm4gZnVuY3Rpb25OYW1lICsgIiBmYWlsZWQ6ICIgKyBnYWlOYW1lICsgIiAoIiArIGRlc2NyaXB0aW9uICsgIikiOworICAgIH0KKworICAgIHB1YmxpYyBVbmtub3duSG9zdEV4Y2VwdGlvbiByZXRocm93QXNVbmtub3duSG9zdEV4Y2VwdGlvbihTdHJpbmcgZGV0YWlsTWVzc2FnZSkgdGhyb3dzIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgVW5rbm93bkhvc3RFeGNlcHRpb24gbmV3RXhjZXB0aW9uID0gbmV3IFVua25vd25Ib3N0RXhjZXB0aW9uKGRldGFpbE1lc3NhZ2UpOworICAgICAgICBuZXdFeGNlcHRpb24uaW5pdENhdXNlKHRoaXMpOworICAgICAgICB0aHJvdyBuZXdFeGNlcHRpb247CisgICAgfQorCisgICAgcHVibGljIFVua25vd25Ib3N0RXhjZXB0aW9uIHJldGhyb3dBc1Vua25vd25Ib3N0RXhjZXB0aW9uKCkgdGhyb3dzIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgcmV0aHJvd0FzVW5rbm93bkhvc3RFeGNlcHRpb24oZ2V0TWVzc2FnZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9IZWFwQnVmZmVySXRlcmF0b3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL0hlYXBCdWZmZXJJdGVyYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzZTQ1N2UKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9IZWFwQnVmZmVySXRlcmF0b3IuamF2YQpAQCAtMCwwICsxLDg2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmlvOworCitpbXBvcnQgamF2YS5uaW8uQnl0ZU9yZGVyOworaW1wb3J0IGxpYmNvcmUuaW8uTWVtb3J5OworCisvKioKKyAqIEl0ZXJhdGVzIG92ZXIgYmlnLSBvciBsaXR0bGUtZW5kaWFuIGJ5dGVzIGluIGEgSmF2YSBieXRlW10uCisgKgorICogQGhpZGUgZG9uJ3QgbWFrZSB0aGlzIHB1YmxpYyB3aXRob3V0IGFkZGluZyBib3VuZHMgY2hlY2tpbmcuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBIZWFwQnVmZmVySXRlcmF0b3IgZXh0ZW5kcyBCdWZmZXJJdGVyYXRvciB7CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gYnVmZmVyOworICAgIHByaXZhdGUgZmluYWwgaW50IG9mZnNldDsKKyAgICBwcml2YXRlIGZpbmFsIGludCBieXRlQ291bnQ7CisgICAgcHJpdmF0ZSBmaW5hbCBCeXRlT3JkZXIgb3JkZXI7CisKKyAgICBwcml2YXRlIGludCBwb3NpdGlvbjsKKworICAgIEhlYXBCdWZmZXJJdGVyYXRvcihieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50LCBCeXRlT3JkZXIgb3JkZXIpIHsKKyAgICAgICAgdGhpcy5idWZmZXIgPSBidWZmZXI7CisgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0OworICAgICAgICB0aGlzLmJ5dGVDb3VudCA9IGJ5dGVDb3VudDsKKyAgICAgICAgdGhpcy5vcmRlciA9IG9yZGVyOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNlZWsoaW50IG9mZnNldCkgeworICAgICAgICBwb3NpdGlvbiA9IG9mZnNldDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBza2lwKGludCBieXRlQ291bnQpIHsKKyAgICAgICAgcG9zaXRpb24gKz0gYnl0ZUNvdW50OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWRCeXRlQXJyYXkoYnl0ZVtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGJ5dGVDb3VudCkgeworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZmZlciwgb2Zmc2V0ICsgcG9zaXRpb24sIGRzdCwgZHN0T2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICBwb3NpdGlvbiArPSBieXRlQ291bnQ7CisgICAgfQorCisgICAgcHVibGljIGJ5dGUgcmVhZEJ5dGUoKSB7CisgICAgICAgIGJ5dGUgcmVzdWx0ID0gYnVmZmVyW29mZnNldCArIHBvc2l0aW9uXTsKKyAgICAgICAgKytwb3NpdGlvbjsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IHJlYWRJbnQoKSB7CisgICAgICAgIGludCByZXN1bHQgPSBNZW1vcnkucGVla0ludChidWZmZXIsIG9mZnNldCArIHBvc2l0aW9uLCBvcmRlcik7CisgICAgICAgIHBvc2l0aW9uICs9IFNpemVPZi5JTlQ7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZEludEFycmF5KGludFtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGludENvdW50KSB7CisgICAgICAgIGZpbmFsIGludCBieXRlQ291bnQgPSBpbnRDb3VudCAqIFNpemVPZi5JTlQ7CisgICAgICAgIE1lbW9yeS51bnNhZmVCdWxrR2V0KGRzdCwgZHN0T2Zmc2V0LCBieXRlQ291bnQsIGJ1ZmZlciwgb2Zmc2V0ICsgcG9zaXRpb24sIFNpemVPZi5JTlQsIG9yZGVyLm5lZWRzU3dhcCk7CisgICAgICAgIHBvc2l0aW9uICs9IGJ5dGVDb3VudDsKKyAgICB9CisKKyAgICBwdWJsaWMgc2hvcnQgcmVhZFNob3J0KCkgeworICAgICAgICBzaG9ydCByZXN1bHQgPSBNZW1vcnkucGVla1Nob3J0KGJ1ZmZlciwgb2Zmc2V0ICsgcG9zaXRpb24sIG9yZGVyKTsKKyAgICAgICAgcG9zaXRpb24gKz0gU2l6ZU9mLlNIT1JUOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgaXRlcmF0b3Igb3ZlciB7QGNvZGUgYnVmZmVyfSwgc3RhcnRpbmcgYXQge0Bjb2RlIG9mZnNldH0gYW5kIGNvbnRpbnVpbmcgZm9yCisgICAgICoge0Bjb2RlIGJ5dGVDb3VudH0gYnl0ZXMuIEl0ZW1zIGxhcmdlciB0aGFuIGEgYnl0ZSBhcmUgaW50ZXJwcmV0ZWQgdXNpbmcgdGhlIGdpdmVuIGJ5dGUgb3JkZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBCdWZmZXJJdGVyYXRvciBpdGVyYXRvcihieXRlW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50LCBCeXRlT3JkZXIgb3JkZXIpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBIZWFwQnVmZmVySXRlcmF0b3IoYnVmZmVyLCBvZmZzZXQsIGJ5dGVDb3VudCwgb3JkZXIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL0lvQnJpZGdlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9Jb0JyaWRnZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiOGQ4YWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9Jb0JyaWRnZS5qYXZhCkBAIC0wLDAgKzEsNTk2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmlvOworCitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkJpbmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuQ29ubmVjdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5EYXRhZ3JhbVBhY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0NEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuSW5ldDZBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0Lk5ldHdvcmtJbnRlcmZhY2U7CitpbXBvcnQgamF2YS5uZXQuUG9ydFVucmVhY2hhYmxlRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlNvY2tldE9wdGlvbnM7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0VGltZW91dEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgc3RhdGljIGxpYmNvcmUuaW8uT3NDb25zdGFudHMuKjsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuTXV0YWJsZUludDsKKworLyoqCisgKiBJbXBsZW1lbnRzIGphdmEuaW8vamF2YS5uZXQvamF2YS5uaW8gc2VtYW50aWNzIGluIHRlcm1zIG9mIHRoZSB1bmRlcmx5aW5nIFBPU0lYIHN5c3RlbSBjYWxscy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIElvQnJpZGdlIHsKKworICAgIHByaXZhdGUgSW9CcmlkZ2UoKSB7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBpbnQgYXZhaWxhYmxlKEZpbGVEZXNjcmlwdG9yIGZkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgTXV0YWJsZUludCBhdmFpbGFibGUgPSBuZXcgTXV0YWJsZUludCgwKTsKKyAgICAgICAgICAgIExpYmNvcmUub3MuaW9jdGxJbnQoZmQsIEZJT05SRUFELCBhdmFpbGFibGUpOworICAgICAgICAgICAgaWYgKGF2YWlsYWJsZS52YWx1ZSA8IDApIHsKKyAgICAgICAgICAgICAgICAvLyBJZiB0aGUgZmQgcmVmZXJzIHRvIGEgcmVndWxhciBmaWxlLCB0aGUgcmVzdWx0IGlzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4KKyAgICAgICAgICAgICAgICAvLyB0aGUgZmlsZSBzaXplIGFuZCB0aGUgZmlsZSBwb3NpdGlvbi4gVGhpcyBtYXkgYmUgbmVnYXRpdmUgaWYgdGhlIHBvc2l0aW9uCisgICAgICAgICAgICAgICAgLy8gaXMgcGFzdCB0aGUgZW5kIG9mIHRoZSBmaWxlLiBJZiB0aGUgZmQgcmVmZXJzIHRvIGEgc3BlY2lhbCBmaWxlIG1hc3F1ZXJhZGluZworICAgICAgICAgICAgICAgIC8vIGFzIGEgcmVndWxhciBmaWxlLCB0aGUgcmVzdWx0IG1heSBiZSBuZWdhdGl2ZSBiZWNhdXNlIHRoZSBzcGVjaWFsIGZpbGUKKyAgICAgICAgICAgICAgICAvLyBtYXkgYXBwZWFyIHRvIGhhdmUgemVybyBzaXplIGFuZCB5ZXQgYSBwcmV2aW91cyByZWFkIGNhbGwgbWF5IGhhdmUKKyAgICAgICAgICAgICAgICAvLyByZWFkIHNvbWUgYW1vdW50IG9mIGRhdGEgYW5kIGNhdXNlZCB0aGUgZmlsZSBwb3NpdGlvbiB0byBiZSBhZHZhbmNlZC4KKyAgICAgICAgICAgICAgICBhdmFpbGFibGUudmFsdWUgPSAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGF2YWlsYWJsZS52YWx1ZTsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIGlmIChlcnJub0V4Y2VwdGlvbi5lcnJubyA9PSBFTk9UVFkpIHsKKyAgICAgICAgICAgICAgICAvLyBUaGUgZmQgaXMgdW53aWxsaW5nIHRvIG9waW5lIGFib3V0IGl0cyByZWFkIGJ1ZmZlci4KKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IGVycm5vRXhjZXB0aW9uLnJldGhyb3dBc0lPRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBiaW5kKEZpbGVEZXNjcmlwdG9yIGZkLCBJbmV0QWRkcmVzcyBhZGRyZXNzLCBpbnQgcG9ydCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhZGRyZXNzIGluc3RhbmNlb2YgSW5ldDZBZGRyZXNzICYmICgoSW5ldDZBZGRyZXNzKSBhZGRyZXNzKS5nZXRTY29wZUlkKCkgPT0gMCkgeworICAgICAgICAgICAgLy8gTGludXggd29uJ3QgbGV0IHlvdSBiaW5kIGEgbGluay1sb2NhbCBhZGRyZXNzIHdpdGhvdXQgYSBzY29wZSBpZC4gRmluZCBvbmUuCisgICAgICAgICAgICBOZXR3b3JrSW50ZXJmYWNlIG5pZiA9IE5ldHdvcmtJbnRlcmZhY2UuZ2V0QnlJbmV0QWRkcmVzcyhhZGRyZXNzKTsKKyAgICAgICAgICAgIGlmIChuaWYgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oIkNhbid0IGJpbmQgdG8gYSBsaW5rLWxvY2FsIGFkZHJlc3Mgd2l0aG91dCBhIHNjb3BlIGlkOiAiICsgYWRkcmVzcyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGFkZHJlc3MgPSBJbmV0NkFkZHJlc3MuZ2V0QnlBZGRyZXNzKGFkZHJlc3MuZ2V0SG9zdE5hbWUoKSwgYWRkcmVzcy5nZXRBZGRyZXNzKCksIG5pZi5nZXRJbmRleCgpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFVua25vd25Ib3N0RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGV4KTsgLy8gQ2FuJ3QgaGFwcGVuLgorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMaWJjb3JlLm9zLmJpbmQoZmQsIGFkZHJlc3MsIHBvcnQpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IEJpbmRFeGNlcHRpb24oZXJybm9FeGNlcHRpb24uZ2V0TWVzc2FnZSgpLCBlcnJub0V4Y2VwdGlvbik7CisgICAgICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIENvbm5lY3RzIHNvY2tldCAnZmQnIHRvICdpbmV0QWRkcmVzcycgb24gJ3BvcnQnLCB3aXRoIG5vIHRpbWVvdXQuIFRoZSBsYWNrIG9mIGEgdGltZW91dAorICAgICAqIG1lYW5zIHRoaXMgbWV0aG9kIHdvbid0IHRocm93IFNvY2tldFRpbWVvdXRFeGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGNvbm5lY3QoRmlsZURlc2NyaXB0b3IgZmQsIEluZXRBZGRyZXNzIGluZXRBZGRyZXNzLCBpbnQgcG9ydCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gSW9CcmlkZ2UuY29ubmVjdChmZCwgaW5ldEFkZHJlc3MsIHBvcnQsIDApOworICAgICAgICB9IGNhdGNoIChTb2NrZXRUaW1lb3V0RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZXgpOyAvLyBDYW4ndCBoYXBwZW4gZm9yIGEgY29ubmVjdCB3aXRob3V0IGEgdGltZW91dC4KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbm5lY3RzIHNvY2tldCAnZmQnIHRvICdpbmV0QWRkcmVzcycgb24gJ3BvcnQnLCB3aXRoIGEgdGhlIGdpdmVuICd0aW1lb3V0TXMnLgorICAgICAqIFVzZSB0aW1lb3V0TXMgPT0gMCBmb3IgYSBibG9ja2luZyBjb25uZWN0IHdpdGggbm8gdGltZW91dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gY29ubmVjdChGaWxlRGVzY3JpcHRvciBmZCwgSW5ldEFkZHJlc3MgaW5ldEFkZHJlc3MsIGludCBwb3J0LCBpbnQgdGltZW91dE1zKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uLCBTb2NrZXRUaW1lb3V0RXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBjb25uZWN0RXJybm8oZmQsIGluZXRBZGRyZXNzLCBwb3J0LCB0aW1lb3V0TXMpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IENvbm5lY3RFeGNlcHRpb24oY29ubmVjdERldGFpbChpbmV0QWRkcmVzcywgcG9ydCwgdGltZW91dE1zLCBlcnJub0V4Y2VwdGlvbiksIGVycm5vRXhjZXB0aW9uKTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBleDsgLy8gV2UgZG9uJ3Qgd2FudCB0byBkb3VibHkgd3JhcCB0aGVzZS4KKyAgICAgICAgfSBjYXRjaCAoU29ja2V0VGltZW91dEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgZXg7IC8vIFdlIGRvbid0IHdhbnQgdG8gZG91Ymx5IHdyYXAgdGhlc2UuCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gY29ubmVjdEVycm5vKEZpbGVEZXNjcmlwdG9yIGZkLCBJbmV0QWRkcmVzcyBpbmV0QWRkcmVzcywgaW50IHBvcnQsIGludCB0aW1lb3V0TXMpIHRocm93cyBFcnJub0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICAvLyBXaXRoIG5vIHRpbWVvdXQsIGp1c3QgY2FsbCBjb25uZWN0KDIpIGRpcmVjdGx5LgorICAgICAgICBpZiAodGltZW91dE1zID09IDApIHsKKyAgICAgICAgICAgIExpYmNvcmUub3MuY29ubmVjdChmZCwgaW5ldEFkZHJlc3MsIHBvcnQpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICAvLyBXaXRoIGEgdGltZW91dCwgd2Ugc2V0IHRoZSBzb2NrZXQgdG8gbm9uLWJsb2NraW5nLCBjb25uZWN0KDIpLCBhbmQgdGhlbiBsb29wCisgICAgICAgIC8vIHVzaW5nIHBvbGwoMikgdG8gZGVjaWRlIHdoZXRoZXIgd2UncmUgY29ubmVjdGVkLCB3aGV0aGVyIHdlIHNob3VsZCBrZWVwIHdhaXRpbmcsCisgICAgICAgIC8vIG9yIHdoZXRoZXIgd2UndmUgc2VlbiBhIHBlcm1hbmVudCBmYWlsdXJlIGFuZCBzaG91bGQgZ2l2ZSB1cC4KKyAgICAgICAgbG9uZyBmaW5pc2hUaW1lTXMgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIHRpbWVvdXRNczsKKyAgICAgICAgSW9VdGlscy5zZXRCbG9ja2luZyhmZCwgZmFsc2UpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBMaWJjb3JlLm9zLmNvbm5lY3QoZmQsIGluZXRBZGRyZXNzLCBwb3J0KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gV2UgY29ubmVjdGVkIGltbWVkaWF0ZWx5LgorICAgICAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICBpZiAoZXJybm9FeGNlcHRpb24uZXJybm8gIT0gRUlOUFJPR1JFU1MpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb247CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIEVJTlBST0dSRVNTIG1lYW5zIHdlIHNob3VsZCBrZWVwIHRyeWluZy4uLgorICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHJlbWFpbmluZ1RpbWVvdXRNczsKKyAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICByZW1haW5pbmdUaW1lb3V0TXMgPSAoaW50KSAoZmluaXNoVGltZU1zIC0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworICAgICAgICAgICAgICAgIGlmIChyZW1haW5pbmdUaW1lb3V0TXMgPD0gMCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU29ja2V0VGltZW91dEV4Y2VwdGlvbihjb25uZWN0RGV0YWlsKGluZXRBZGRyZXNzLCBwb3J0LCB0aW1lb3V0TXMsIG51bGwpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IHdoaWxlICghSW9CcmlkZ2UuaXNDb25uZWN0ZWQoZmQsIGluZXRBZGRyZXNzLCBwb3J0LCB0aW1lb3V0TXMsIHJlbWFpbmluZ1RpbWVvdXRNcykpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7IC8vIE9yIHdlJ2QgaGF2ZSB0aHJvd24uCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBJb1V0aWxzLnNldEJsb2NraW5nKGZkLCB0cnVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBjb25uZWN0RGV0YWlsKEluZXRBZGRyZXNzIGluZXRBZGRyZXNzLCBpbnQgcG9ydCwgaW50IHRpbWVvdXRNcywgRXJybm9FeGNlcHRpb24gY2F1c2UpIHsKKyAgICAgICAgU3RyaW5nIGRldGFpbCA9ICJmYWlsZWQgdG8gY29ubmVjdCB0byAiICsgaW5ldEFkZHJlc3MgKyAiIChwb3J0ICIgKyBwb3J0ICsgIikiOworICAgICAgICBpZiAodGltZW91dE1zID4gMCkgeworICAgICAgICAgICAgZGV0YWlsICs9ICIgYWZ0ZXIgIiArIHRpbWVvdXRNcyArICJtcyI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNhdXNlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGRldGFpbCArPSAiOiAiICsgY2F1c2UuZ2V0TWVzc2FnZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkZXRhaWw7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGNsb3NlU29ja2V0KEZpbGVEZXNjcmlwdG9yIGZkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIWZkLnZhbGlkKCkpIHsKKyAgICAgICAgICAgIC8vIFNvY2tldC5jbG9zZSBkb2Vzbid0IHRocm93IGlmIHlvdSB0cnkgdG8gY2xvc2UgYW4gYWxyZWFkeS1jbG9zZWQgc29ja2V0LgorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGludCBpbnRGZCA9IGZkLmdldEludCQoKTsKKyAgICAgICAgZmQuc2V0SW50JCgtMSk7CisgICAgICAgIEZpbGVEZXNjcmlwdG9yIG9sZEZkID0gbmV3IEZpbGVEZXNjcmlwdG9yKCk7CisgICAgICAgIG9sZEZkLnNldEludCQoaW50RmQpOworICAgICAgICBBc3luY2hyb25vdXNDbG9zZU1vbml0b3Iuc2lnbmFsQmxvY2tlZFRocmVhZHMob2xkRmQpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgTGliY29yZS5vcy5jbG9zZShvbGRGZCk7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAvLyBUT0RPOiBhcmUgdGhlcmUgYW55IGNhc2VzIGluIHdoaWNoIHdlIHNob3VsZCB0aHJvdz8KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0Nvbm5lY3RlZChGaWxlRGVzY3JpcHRvciBmZCwgSW5ldEFkZHJlc3MgaW5ldEFkZHJlc3MsIGludCBwb3J0LCBpbnQgdGltZW91dE1zLCBpbnQgcmVtYWluaW5nVGltZW91dE1zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBFcnJub0V4Y2VwdGlvbiBjYXVzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cnVjdFBvbGxmZFtdIHBvbGxGZHMgPSBuZXcgU3RydWN0UG9sbGZkW10geyBuZXcgU3RydWN0UG9sbGZkKCkgfTsKKyAgICAgICAgICAgIHBvbGxGZHNbMF0uZmQgPSBmZDsKKyAgICAgICAgICAgIHBvbGxGZHNbMF0uZXZlbnRzID0gKHNob3J0KSBQT0xMT1VUOworICAgICAgICAgICAgaW50IHJjID0gTGliY29yZS5vcy5wb2xsKHBvbGxGZHMsIHJlbWFpbmluZ1RpbWVvdXRNcyk7CisgICAgICAgICAgICBpZiAocmMgPT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gVGltZW91dC4KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBjb25uZWN0RXJyb3IgPSBMaWJjb3JlLm9zLmdldHNvY2tvcHRJbnQoZmQsIFNPTF9TT0NLRVQsIFNPX0VSUk9SKTsKKyAgICAgICAgICAgIGlmIChjb25uZWN0RXJyb3IgPT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOyAvLyBTdWNjZXNzIQorICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IEVycm5vRXhjZXB0aW9uKCJpc0Nvbm5lY3RlZCIsIGNvbm5lY3RFcnJvcik7IC8vIFRoZSBjb25uZWN0KDIpIGZhaWxlZC4KKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIGlmIChlcnJub0V4Y2VwdGlvbi5lcnJubyA9PSBFSU5UUikgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gUHVudCBhbmQgYXNrIHRoZSBjYWxsZXIgdG8gdHJ5IGFnYWluLgorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBjYXVzZSA9IGVycm5vRXhjZXB0aW9uOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIFRPRE86IGlzIGl0IHJlYWxseSBoZWxwZnVsL25lY2Vzc2FyeSB0byB0aHJvdyBzbyBtYW55IGRpZmZlcmVudCBleGNlcHRpb25zPworICAgICAgICBTdHJpbmcgZGV0YWlsID0gY29ubmVjdERldGFpbChpbmV0QWRkcmVzcywgcG9ydCwgdGltZW91dE1zLCBjYXVzZSk7CisgICAgICAgIGlmIChjYXVzZS5lcnJubyA9PSBFQ09OTlJFU0VUIHx8IGNhdXNlLmVycm5vID09IEVDT05OUkVGVVNFRCB8fAorICAgICAgICBjYXVzZS5lcnJubyA9PSBFQUREUk5PVEFWQUlMIHx8IGNhdXNlLmVycm5vID09IEVBRERSSU5VU0UgfHwKKyAgICAgICAgY2F1c2UuZXJybm8gPT0gRU5FVFVOUkVBQ0gpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDb25uZWN0RXhjZXB0aW9uKGRldGFpbCwgY2F1c2UpOworICAgICAgICB9IGVsc2UgaWYgKGNhdXNlLmVycm5vID09IEVBQ0NFUykgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKGRldGFpbCwgY2F1c2UpOworICAgICAgICB9IGVsc2UgaWYgKGNhdXNlLmVycm5vID09IEVUSU1FRE9VVCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNvY2tldFRpbWVvdXRFeGNlcHRpb24oZGV0YWlsLCBjYXVzZSk7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbihkZXRhaWwsIGNhdXNlKTsKKyAgICB9CisKKyAgICAvLyBTb2NrZXQgb3B0aW9ucyB1c2VkIGJ5IGphdmEubmV0IGJ1dCBub3QgZXhwb3NlZCBpbiBTb2NrZXRPcHRpb25zLgorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpBVkFfTUNBU1RfSk9JTl9HUk9VUCA9IDE5OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpBVkFfTUNBU1RfTEVBVkVfR1JPVVAgPSAyMDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBKQVZBX0lQX01VTFRJQ0FTVF9UVEwgPSAxNzsKKworICAgIC8qKgorICAgICAqIGphdmEubmV0IGhhcyBpdHMgb3duIHNvY2tldCBvcHRpb25zIHNpbWlsYXIgdG8gdGhlIHVuZGVybHlpbmcgVW5peCBvbmVzLiBXZSBwYXBlciBvdmVyIHRoZQorICAgICAqIGRpZmZlcmVuY2VzIGhlcmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBPYmplY3QgZ2V0U29ja2V0T3B0aW9uKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgb3B0aW9uKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBnZXRTb2NrZXRPcHRpb25FcnJubyhmZCwgb3B0aW9uKTsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRocm93IGVycm5vRXhjZXB0aW9uLnJldGhyb3dBc1NvY2tldEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgT2JqZWN0IGdldFNvY2tldE9wdGlvbkVycm5vKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgb3B0aW9uKSB0aHJvd3MgRXJybm9FeGNlcHRpb24sIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHN3aXRjaCAob3B0aW9uKSB7CisgICAgICAgIGNhc2UgU29ja2V0T3B0aW9ucy5JUF9NVUxUSUNBU1RfSUY6CisgICAgICAgICAgICAvLyBUaGlzIGlzIElQdjQtb25seS4KKyAgICAgICAgICAgIHJldHVybiBMaWJjb3JlLm9zLmdldHNvY2tvcHRJbkFkZHIoZmQsIElQUFJPVE9fSVAsIElQX01VTFRJQ0FTVF9JRik7CisgICAgICAgIGNhc2UgU29ja2V0T3B0aW9ucy5JUF9NVUxUSUNBU1RfSUYyOgorICAgICAgICAgICAgLy8gVGhpcyBpcyBJUHY2LW9ubHkuCisgICAgICAgICAgICByZXR1cm4gTGliY29yZS5vcy5nZXRzb2Nrb3B0SW50KGZkLCBJUFBST1RPX0lQVjYsIElQVjZfTVVMVElDQVNUX0lGKTsKKyAgICAgICAgY2FzZSBTb2NrZXRPcHRpb25zLklQX01VTFRJQ0FTVF9MT09QOgorICAgICAgICAgICAgLy8gU2luY2Ugc2V0dGluZyB0aGlzIGZyb20gamF2YS5uZXQgYWx3YXlzIHNldHMgSVB2NCBhbmQgSVB2NiB0byB0aGUgc2FtZSB2YWx1ZSwKKyAgICAgICAgICAgIC8vIGl0IGRvZXNuJ3QgbWF0dGVyIHdoaWNoIHdlIHJldHVybi4KKyAgICAgICAgICAgIHJldHVybiBib29sZWFuRnJvbUludChMaWJjb3JlLm9zLmdldHNvY2tvcHRJbnQoZmQsIElQUFJPVE9fSVBWNiwgSVBWNl9NVUxUSUNBU1RfTE9PUCkpOworICAgICAgICBjYXNlIElvQnJpZGdlLkpBVkFfSVBfTVVMVElDQVNUX1RUTDoKKyAgICAgICAgICAgIC8vIFNpbmNlIHNldHRpbmcgdGhpcyBmcm9tIGphdmEubmV0IGFsd2F5cyBzZXRzIElQdjQgYW5kIElQdjYgdG8gdGhlIHNhbWUgdmFsdWUsCisgICAgICAgICAgICAvLyBpdCBkb2Vzbid0IG1hdHRlciB3aGljaCB3ZSByZXR1cm4uCisgICAgICAgICAgICByZXR1cm4gTGliY29yZS5vcy5nZXRzb2Nrb3B0SW50KGZkLCBJUFBST1RPX0lQVjYsIElQVjZfTVVMVElDQVNUX0hPUFMpOworICAgICAgICBjYXNlIFNvY2tldE9wdGlvbnMuSVBfVE9TOgorICAgICAgICAgICAgLy8gU2luY2Ugc2V0dGluZyB0aGlzIGZyb20gamF2YS5uZXQgYWx3YXlzIHNldHMgSVB2NCBhbmQgSVB2NiB0byB0aGUgc2FtZSB2YWx1ZSwKKyAgICAgICAgICAgIC8vIGl0IGRvZXNuJ3QgbWF0dGVyIHdoaWNoIHdlIHJldHVybi4KKyAgICAgICAgICAgIHJldHVybiBMaWJjb3JlLm9zLmdldHNvY2tvcHRJbnQoZmQsIElQUFJPVE9fSVBWNiwgSVBWNl9UQ0xBU1MpOworICAgICAgICBjYXNlIFNvY2tldE9wdGlvbnMuU09fQlJPQURDQVNUOgorICAgICAgICAgICAgcmV0dXJuIGJvb2xlYW5Gcm9tSW50KExpYmNvcmUub3MuZ2V0c29ja29wdEludChmZCwgU09MX1NPQ0tFVCwgU09fQlJPQURDQVNUKSk7CisgICAgICAgIGNhc2UgU29ja2V0T3B0aW9ucy5TT19LRUVQQUxJVkU6CisgICAgICAgICAgICByZXR1cm4gYm9vbGVhbkZyb21JbnQoTGliY29yZS5vcy5nZXRzb2Nrb3B0SW50KGZkLCBTT0xfU09DS0VULCBTT19LRUVQQUxJVkUpKTsKKyAgICAgICAgY2FzZSBTb2NrZXRPcHRpb25zLlNPX0xJTkdFUjoKKyAgICAgICAgICAgIFN0cnVjdExpbmdlciBsaW5nZXIgPSBMaWJjb3JlLm9zLmdldHNvY2tvcHRMaW5nZXIoZmQsIFNPTF9TT0NLRVQsIFNPX0xJTkdFUik7CisgICAgICAgICAgICBpZiAoIWxpbmdlci5pc09uKCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbGluZ2VyLmxfbGluZ2VyOworICAgICAgICBjYXNlIFNvY2tldE9wdGlvbnMuU09fT09CSU5MSU5FOgorICAgICAgICAgICAgcmV0dXJuIGJvb2xlYW5Gcm9tSW50KExpYmNvcmUub3MuZ2V0c29ja29wdEludChmZCwgU09MX1NPQ0tFVCwgU09fT09CSU5MSU5FKSk7CisgICAgICAgIGNhc2UgU29ja2V0T3B0aW9ucy5TT19SQ1ZCVUY6CisgICAgICAgICAgICByZXR1cm4gTGliY29yZS5vcy5nZXRzb2Nrb3B0SW50KGZkLCBTT0xfU09DS0VULCBTT19TTkRCVUYpOworICAgICAgICBjYXNlIFNvY2tldE9wdGlvbnMuU09fUkVVU0VBRERSOgorICAgICAgICAgICAgcmV0dXJuIGJvb2xlYW5Gcm9tSW50KExpYmNvcmUub3MuZ2V0c29ja29wdEludChmZCwgU09MX1NPQ0tFVCwgU09fUkVVU0VBRERSKSk7CisgICAgICAgIGNhc2UgU29ja2V0T3B0aW9ucy5TT19TTkRCVUY6CisgICAgICAgICAgICByZXR1cm4gTGliY29yZS5vcy5nZXRzb2Nrb3B0SW50KGZkLCBTT0xfU09DS0VULCBTT19TTkRCVUYpOworICAgICAgICBjYXNlIFNvY2tldE9wdGlvbnMuU09fVElNRU9VVDoKKyAgICAgICAgICAgIHJldHVybiAoaW50KSBMaWJjb3JlLm9zLmdldHNvY2tvcHRUaW1ldmFsKGZkLCBTT0xfU09DS0VULCBTT19SQ1ZUSU1FTykudG9NaWxsaXMoKTsKKyAgICAgICAgY2FzZSBTb2NrZXRPcHRpb25zLlRDUF9OT0RFTEFZOgorICAgICAgICAgICAgcmV0dXJuIGJvb2xlYW5Gcm9tSW50KExpYmNvcmUub3MuZ2V0c29ja29wdEludChmZCwgSVBQUk9UT19UQ1AsIFRDUF9OT0RFTEFZKSk7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKCJVbmtub3duIHNvY2tldCBvcHRpb246ICIgKyBvcHRpb24pOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBib29sZWFuRnJvbUludChpbnQgaSkgeworICAgICAgICByZXR1cm4gKGkgIT0gMCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGJvb2xlYW5Ub0ludChib29sZWFuIGIpIHsKKyAgICAgICAgcmV0dXJuIGIgPyAxIDogMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm5ldCBoYXMgaXRzIG93biBzb2NrZXQgb3B0aW9ucyBzaW1pbGFyIHRvIHRoZSB1bmRlcmx5aW5nIFVuaXggb25lcy4gV2UgcGFwZXIgb3ZlciB0aGUKKyAgICAgKiBkaWZmZXJlbmNlcyBoZXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRTb2NrZXRPcHRpb24oRmlsZURlc2NyaXB0b3IgZmQsIGludCBvcHRpb24sIE9iamVjdCB2YWx1ZSkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXRTb2NrZXRPcHRpb25FcnJubyhmZCwgb3B0aW9uLCB2YWx1ZSk7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyBlcnJub0V4Y2VwdGlvbi5yZXRocm93QXNTb2NrZXRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgc2V0U29ja2V0T3B0aW9uRXJybm8oRmlsZURlc2NyaXB0b3IgZmQsIGludCBvcHRpb24sIE9iamVjdCB2YWx1ZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uLCBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBzd2l0Y2ggKG9wdGlvbikgeworICAgICAgICBjYXNlIFNvY2tldE9wdGlvbnMuSVBfTVVMVElDQVNUX0lGOgorICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJVc2UgSVBfTVVMVElDQVNUX0lGMiBvbiBBbmRyb2lkIik7CisgICAgICAgIGNhc2UgU29ja2V0T3B0aW9ucy5JUF9NVUxUSUNBU1RfSUYyOgorICAgICAgICAgICAgLy8gQWx0aG91Z2ggSVB2NiB3YXMgY2xlYW5lZCB1cCB0byB1c2UgaW50LCBJUHY0IHVzZXMgYW4gaXBfbXJlcW4gY29udGFpbmluZyBhbiBpbnQuCisgICAgICAgICAgICBMaWJjb3JlLm9zLnNldHNvY2tvcHRJcE1yZXFuKGZkLCBJUFBST1RPX0lQLCBJUF9NVUxUSUNBU1RfSUYsIChJbnRlZ2VyKSB2YWx1ZSk7CisgICAgICAgICAgICBMaWJjb3JlLm9zLnNldHNvY2tvcHRJbnQoZmQsIElQUFJPVE9fSVBWNiwgSVBWNl9NVUxUSUNBU1RfSUYsIChJbnRlZ2VyKSB2YWx1ZSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIGNhc2UgU29ja2V0T3B0aW9ucy5JUF9NVUxUSUNBU1RfTE9PUDoKKyAgICAgICAgICAgIC8vIEFsdGhvdWdoIElQdjYgd2FzIGNsZWFuZWQgdXAgdG8gdXNlIGludCwgSVB2NCBtdWx0aWNhc3QgbG9vcGJhY2sgdXNlcyBhIGJ5dGUuCisgICAgICAgICAgICBMaWJjb3JlLm9zLnNldHNvY2tvcHRCeXRlKGZkLCBJUFBST1RPX0lQLCBJUF9NVUxUSUNBU1RfTE9PUCwgYm9vbGVhblRvSW50KChCb29sZWFuKSB2YWx1ZSkpOworICAgICAgICAgICAgTGliY29yZS5vcy5zZXRzb2Nrb3B0SW50KGZkLCBJUFBST1RPX0lQVjYsIElQVjZfTVVMVElDQVNUX0xPT1AsIGJvb2xlYW5Ub0ludCgoQm9vbGVhbikgdmFsdWUpKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgY2FzZSBJb0JyaWRnZS5KQVZBX0lQX01VTFRJQ0FTVF9UVEw6CisgICAgICAgICAgICAvLyBBbHRob3VnaCBJUHY2IHdhcyBjbGVhbmVkIHVwIHRvIHVzZSBpbnQsIGFuZCBJUHY0IG5vbi1tdWx0aWNhc3QgVFRMIHVzZXMgaW50LAorICAgICAgICAgICAgLy8gSVB2NCBtdWx0aWNhc3QgVFRMIHVzZXMgYSBieXRlLgorICAgICAgICAgICAgTGliY29yZS5vcy5zZXRzb2Nrb3B0Qnl0ZShmZCwgSVBQUk9UT19JUCwgSVBfTVVMVElDQVNUX1RUTCwgKEludGVnZXIpIHZhbHVlKTsKKyAgICAgICAgICAgIExpYmNvcmUub3Muc2V0c29ja29wdEludChmZCwgSVBQUk9UT19JUFY2LCBJUFY2X01VTFRJQ0FTVF9IT1BTLCAoSW50ZWdlcikgdmFsdWUpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICBjYXNlIFNvY2tldE9wdGlvbnMuSVBfVE9TOgorICAgICAgICAgICAgTGliY29yZS5vcy5zZXRzb2Nrb3B0SW50KGZkLCBJUFBST1RPX0lQLCBJUF9UT1MsIChJbnRlZ2VyKSB2YWx1ZSk7CisgICAgICAgICAgICBMaWJjb3JlLm9zLnNldHNvY2tvcHRJbnQoZmQsIElQUFJPVE9fSVBWNiwgSVBWNl9UQ0xBU1MsIChJbnRlZ2VyKSB2YWx1ZSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIGNhc2UgU29ja2V0T3B0aW9ucy5TT19CUk9BRENBU1Q6CisgICAgICAgICAgICBMaWJjb3JlLm9zLnNldHNvY2tvcHRJbnQoZmQsIFNPTF9TT0NLRVQsIFNPX0JST0FEQ0FTVCwgYm9vbGVhblRvSW50KChCb29sZWFuKSB2YWx1ZSkpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICBjYXNlIFNvY2tldE9wdGlvbnMuU09fS0VFUEFMSVZFOgorICAgICAgICAgICAgTGliY29yZS5vcy5zZXRzb2Nrb3B0SW50KGZkLCBTT0xfU09DS0VULCBTT19LRUVQQUxJVkUsIGJvb2xlYW5Ub0ludCgoQm9vbGVhbikgdmFsdWUpKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgY2FzZSBTb2NrZXRPcHRpb25zLlNPX0xJTkdFUjoKKyAgICAgICAgICAgIGJvb2xlYW4gb24gPSBmYWxzZTsKKyAgICAgICAgICAgIGludCBzZWNvbmRzID0gMDsKKyAgICAgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEludGVnZXIpIHsKKyAgICAgICAgICAgICAgICBvbiA9IHRydWU7CisgICAgICAgICAgICAgICAgc2Vjb25kcyA9IE1hdGgubWluKChJbnRlZ2VyKSB2YWx1ZSwgNjU1MzUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3RydWN0TGluZ2VyIGxpbmdlciA9IG5ldyBTdHJ1Y3RMaW5nZXIoYm9vbGVhblRvSW50KG9uKSwgc2Vjb25kcyk7CisgICAgICAgICAgICBMaWJjb3JlLm9zLnNldHNvY2tvcHRMaW5nZXIoZmQsIFNPTF9TT0NLRVQsIFNPX0xJTkdFUiwgbGluZ2VyKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgY2FzZSBTb2NrZXRPcHRpb25zLlNPX09PQklOTElORToKKyAgICAgICAgICAgIExpYmNvcmUub3Muc2V0c29ja29wdEludChmZCwgU09MX1NPQ0tFVCwgU09fT09CSU5MSU5FLCBib29sZWFuVG9JbnQoKEJvb2xlYW4pIHZhbHVlKSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIGNhc2UgU29ja2V0T3B0aW9ucy5TT19SQ1ZCVUY6CisgICAgICAgICAgICBMaWJjb3JlLm9zLnNldHNvY2tvcHRJbnQoZmQsIFNPTF9TT0NLRVQsIFNPX1JDVkJVRiwgKEludGVnZXIpIHZhbHVlKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgY2FzZSBTb2NrZXRPcHRpb25zLlNPX1JFVVNFQUREUjoKKyAgICAgICAgICAgIExpYmNvcmUub3Muc2V0c29ja29wdEludChmZCwgU09MX1NPQ0tFVCwgU09fUkVVU0VBRERSLCBib29sZWFuVG9JbnQoKEJvb2xlYW4pIHZhbHVlKSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIGNhc2UgU29ja2V0T3B0aW9ucy5TT19TTkRCVUY6CisgICAgICAgICAgICBMaWJjb3JlLm9zLnNldHNvY2tvcHRJbnQoZmQsIFNPTF9TT0NLRVQsIFNPX1NOREJVRiwgKEludGVnZXIpIHZhbHVlKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgY2FzZSBTb2NrZXRPcHRpb25zLlNPX1RJTUVPVVQ6CisgICAgICAgICAgICBpbnQgbWlsbGlzID0gKEludGVnZXIpIHZhbHVlOworICAgICAgICAgICAgU3RydWN0VGltZXZhbCB0diA9IFN0cnVjdFRpbWV2YWwuZnJvbU1pbGxpcyhtaWxsaXMpOworICAgICAgICAgICAgTGliY29yZS5vcy5zZXRzb2Nrb3B0VGltZXZhbChmZCwgU09MX1NPQ0tFVCwgU09fUkNWVElNRU8sIHR2KTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgY2FzZSBTb2NrZXRPcHRpb25zLlRDUF9OT0RFTEFZOgorICAgICAgICAgICAgTGliY29yZS5vcy5zZXRzb2Nrb3B0SW50KGZkLCBJUFBST1RPX1RDUCwgVENQX05PREVMQVksIGJvb2xlYW5Ub0ludCgoQm9vbGVhbikgdmFsdWUpKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgY2FzZSBJb0JyaWRnZS5KQVZBX01DQVNUX0pPSU5fR1JPVVA6CisgICAgICAgIGNhc2UgSW9CcmlkZ2UuSkFWQV9NQ0FTVF9MRUFWRV9HUk9VUDoKKyAgICAgICAgICAgIFN0cnVjdEdyb3VwUmVxIGdyb3VwUmVxID0gKFN0cnVjdEdyb3VwUmVxKSB2YWx1ZTsKKyAgICAgICAgICAgIGludCBsZXZlbCA9IChncm91cFJlcS5ncl9ncm91cCBpbnN0YW5jZW9mIEluZXQ0QWRkcmVzcykgPyBJUFBST1RPX0lQIDogSVBQUk9UT19JUFY2OworICAgICAgICAgICAgaW50IG9wID0gKG9wdGlvbiA9PSBKQVZBX01DQVNUX0pPSU5fR1JPVVApID8gTUNBU1RfSk9JTl9HUk9VUCA6IE1DQVNUX0xFQVZFX0dST1VQOworICAgICAgICAgICAgTGliY29yZS5vcy5zZXRzb2Nrb3B0R3JvdXBSZXEoZmQsIGxldmVsLCBvcCwgZ3JvdXBSZXEpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbigiVW5rbm93biBzb2NrZXQgb3B0aW9uOiAiICsgb3B0aW9uKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8gb25seSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHdoZW4gb3BlbmluZyBmaWxlcywgcmVnYXJkbGVzcyBvZiB3aGF0IGFjdHVhbGx5CisgICAgICogd2VudCB3cm9uZy4gQWRkaXRpb25hbGx5LCBqYXZhLmlvIGlzIG1vcmUgcmVzdHJpY3RpdmUgdGhhbiBQT1NJWCB3aGVuIGl0IGNvbWVzIHRvIG9wZW5pbmcKKyAgICAgKiBkaXJlY3RvcmllczogUE9TSVggc2F5cyByZWFkLW9ubHkgaXMgb2theSwgYnV0IGphdmEuaW8gZG9lc24ndCBldmVuIGFsbG93IHRoYXQuIFdlIGFsc28KKyAgICAgKiBoYXZlIGFuIEFuZHJvaWQtc3BlY2lmaWMgaGFjayB0byBhbHRlciB0aGUgZGVmYXVsdCBwZXJtaXNzaW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEZpbGVEZXNjcmlwdG9yIG9wZW4oU3RyaW5nIHBhdGgsIGludCBmbGFncykgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGVEZXNjcmlwdG9yIGZkID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIE9uIEFuZHJvaWQsIHdlIGRvbid0IHdhbnQgZGVmYXVsdCBwZXJtaXNzaW9ucyB0byBhbGxvdyBnbG9iYWwgYWNjZXNzLgorICAgICAgICAgICAgaW50IG1vZGUgPSAoKGZsYWdzICYgT19BQ0NNT0RFKSA9PSBPX1JET05MWSkgPyAwIDogMDYwMDsKKyAgICAgICAgICAgIGZkID0gTGliY29yZS5vcy5vcGVuKHBhdGgsIGZsYWdzLCBtb2RlKTsKKyAgICAgICAgICAgIGlmIChmZC52YWxpZCgpKSB7CisgICAgICAgICAgICAgICAgLy8gUG9zaXggb3BlbigyKSBmYWlscyB3aXRoIEVJU0RJUiBvbmx5IGlmIHlvdSBhc2sgZm9yIHdyaXRlIHBlcm1pc3Npb24uCisgICAgICAgICAgICAgICAgLy8gSmF2YSBkaXNhbGxvd3MgcmVhZGluZyBkaXJlY3RvcmllcyB0b28uCisgICAgICAgICAgICAgICAgaWYgKFNfSVNESVIoTGliY29yZS5vcy5mc3RhdChmZCkuc3RfbW9kZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm5vRXhjZXB0aW9uKCJvcGVuIiwgRUlTRElSKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZmQ7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmIChmZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIElvVXRpbHMuY2xvc2UoZmQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBleCA9IG5ldyBGaWxlTm90Rm91bmRFeGNlcHRpb24ocGF0aCArICI6ICIgKyBlcnJub0V4Y2VwdGlvbi5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgZXguaW5pdENhdXNlKGVycm5vRXhjZXB0aW9uKTsKKyAgICAgICAgICAgIHRocm93IGV4OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pbyB0aGlua3MgdGhhdCBhIHJlYWQgYXQgRU9GIGlzIGFuIGVycm9yIGFuZCBzaG91bGQgcmV0dXJuIC0xLCBjb250cmFyeSB0byB0cmFkaXRpb25hbAorICAgICAqIFVuaXggcHJhY3RpY2Ugd2hlcmUgeW91J2QgcmVhZCB1bnRpbCB5b3UgZ290IDAgYnl0ZXMgKGFuZCBhbnkgZnV0dXJlIHJlYWQgd291bGQgcmV0dXJuIC0xKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCByZWFkKEZpbGVEZXNjcmlwdG9yIGZkLCBieXRlW10gYnl0ZXMsIGludCBieXRlT2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChieXRlcy5sZW5ndGgsIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIGlmIChieXRlQ291bnQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCByZWFkQ291bnQgPSBMaWJjb3JlLm9zLnJlYWQoZmQsIGJ5dGVzLCBieXRlT2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICAgICAgaWYgKHJlYWRDb3VudCA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJlYWRDb3VudDsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIGlmIChlcnJub0V4Y2VwdGlvbi5lcnJubyA9PSBFQUdBSU4pIHsKKyAgICAgICAgICAgICAgICAvLyBXZSByZXR1cm4gMCByYXRoZXIgdGhhbiB0aHJvdyBpZiB3ZSB0cnkgdG8gcmVhZCBmcm9tIGFuIGVtcHR5IG5vbi1ibG9ja2luZyBwaXBlLgorICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzSU9FeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8gYWx3YXlzIHdyaXRlcyBldmVyeSBieXRlIGl0J3MgYXNrZWQgdG8sIG9yIGZhaWxzIHdpdGggYW4gZXJyb3IuIChUaGF0IGlzLCB1bmxpa2UKKyAgICAgKiBVbml4IGl0IG5ldmVyIGp1c3Qgd3JpdGVzIGFzIG1hbnkgYnl0ZXMgYXMgaGFwcGVucyB0byBiZSBjb252ZW5pZW50LikKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgd3JpdGUoRmlsZURlc2NyaXB0b3IgZmQsIGJ5dGVbXSBieXRlcywgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEFycmF5cy5jaGVja09mZnNldEFuZENvdW50KGJ5dGVzLmxlbmd0aCwgYnl0ZU9mZnNldCwgYnl0ZUNvdW50KTsKKyAgICAgICAgaWYgKGJ5dGVDb3VudCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdoaWxlIChieXRlQ291bnQgPiAwKSB7CisgICAgICAgICAgICAgICAgaW50IGJ5dGVzV3JpdHRlbiA9IExpYmNvcmUub3Mud3JpdGUoZmQsIGJ5dGVzLCBieXRlT2Zmc2V0LCBieXRlQ291bnQpOworICAgICAgICAgICAgICAgIGJ5dGVDb3VudCAtPSBieXRlc1dyaXR0ZW47CisgICAgICAgICAgICAgICAgYnl0ZU9mZnNldCArPSBieXRlc1dyaXR0ZW47CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyBlcnJub0V4Y2VwdGlvbi5yZXRocm93QXNJT0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBpbnQgc2VuZHRvKEZpbGVEZXNjcmlwdG9yIGZkLCBieXRlW10gYnl0ZXMsIGludCBieXRlT2Zmc2V0LCBpbnQgYnl0ZUNvdW50LCBpbnQgZmxhZ3MsIEluZXRBZGRyZXNzIGluZXRBZGRyZXNzLCBpbnQgcG9ydCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYm9vbGVhbiBpc0RhdGFncmFtID0gKGluZXRBZGRyZXNzICE9IG51bGwpOworICAgICAgICBpZiAoIWlzRGF0YWdyYW0gJiYgYnl0ZUNvdW50IDw9IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGludCByZXN1bHQ7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXN1bHQgPSBMaWJjb3JlLm9zLnNlbmR0byhmZCwgYnl0ZXMsIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCwgZmxhZ3MsIGluZXRBZGRyZXNzLCBwb3J0KTsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IG1heWJlVGhyb3dBZnRlclNlbmR0byhpc0RhdGFncmFtLCBlcnJub0V4Y2VwdGlvbik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGludCBzZW5kdG8oRmlsZURlc2NyaXB0b3IgZmQsIEJ5dGVCdWZmZXIgYnVmZmVyLCBpbnQgZmxhZ3MsIEluZXRBZGRyZXNzIGluZXRBZGRyZXNzLCBpbnQgcG9ydCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYm9vbGVhbiBpc0RhdGFncmFtID0gKGluZXRBZGRyZXNzICE9IG51bGwpOworICAgICAgICBpZiAoIWlzRGF0YWdyYW0gJiYgYnVmZmVyLnJlbWFpbmluZygpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGludCByZXN1bHQ7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXN1bHQgPSBMaWJjb3JlLm9zLnNlbmR0byhmZCwgYnVmZmVyLCBmbGFncywgaW5ldEFkZHJlc3MsIHBvcnQpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgcmVzdWx0ID0gbWF5YmVUaHJvd0FmdGVyU2VuZHRvKGlzRGF0YWdyYW0sIGVycm5vRXhjZXB0aW9uKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGludCBtYXliZVRocm93QWZ0ZXJTZW5kdG8oYm9vbGVhbiBpc0RhdGFncmFtLCBFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpc0RhdGFncmFtKSB7CisgICAgICAgICAgICBpZiAoZXJybm9FeGNlcHRpb24uZXJybm8gPT0gRUNPTk5SRVNFVCB8fCBlcnJub0V4Y2VwdGlvbi5lcnJubyA9PSBFQ09OTlJFRlVTRUQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChlcnJub0V4Y2VwdGlvbi5lcnJubyA9PSBFQUdBSU4gfHwgZXJybm9FeGNlcHRpb24uZXJybm8gPT0gRVdPVUxEQkxPQ0spIHsKKyAgICAgICAgICAgICAgICAvLyBXZSB3ZXJlIGFza2VkIHRvIHdyaXRlIHRvIGEgbm9uLWJsb2NraW5nIHNvY2tldCwgYnV0IHdlcmUgdG9sZAorICAgICAgICAgICAgICAgIC8vIGl0IHdvdWxkIGJsb2NrLCBzbyByZXBvcnQgIm5vIGJ5dGVzIHdyaXR0ZW4iLgorICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRocm93IGVycm5vRXhjZXB0aW9uLnJldGhyb3dBc1NvY2tldEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgaW50IHJlY3Zmcm9tKGJvb2xlYW4gaXNSZWFkLCBGaWxlRGVzY3JpcHRvciBmZCwgYnl0ZVtdIGJ5dGVzLCBpbnQgYnl0ZU9mZnNldCwgaW50IGJ5dGVDb3VudCwgaW50IGZsYWdzLCBEYXRhZ3JhbVBhY2tldCBwYWNrZXQsIGJvb2xlYW4gaXNDb25uZWN0ZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByZXN1bHQ7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBzcmNBZGRyZXNzID0gKHBhY2tldCAhPSBudWxsICYmICFpc0Nvbm5lY3RlZCkgPyBuZXcgSW5ldFNvY2tldEFkZHJlc3MoKSA6IG51bGw7CisgICAgICAgICAgICByZXN1bHQgPSBMaWJjb3JlLm9zLnJlY3Zmcm9tKGZkLCBieXRlcywgYnl0ZU9mZnNldCwgYnl0ZUNvdW50LCBmbGFncywgc3JjQWRkcmVzcyk7CisgICAgICAgICAgICByZXN1bHQgPSBwb3N0UmVjdmZyb20oaXNSZWFkLCBwYWNrZXQsIGlzQ29ubmVjdGVkLCBzcmNBZGRyZXNzLCByZXN1bHQpOworICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgcmVzdWx0ID0gbWF5YmVUaHJvd0FmdGVyUmVjdmZyb20oaXNSZWFkLCBpc0Nvbm5lY3RlZCwgZXJybm9FeGNlcHRpb24pOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBpbnQgcmVjdmZyb20oYm9vbGVhbiBpc1JlYWQsIEZpbGVEZXNjcmlwdG9yIGZkLCBCeXRlQnVmZmVyIGJ1ZmZlciwgaW50IGZsYWdzLCBEYXRhZ3JhbVBhY2tldCBwYWNrZXQsIGJvb2xlYW4gaXNDb25uZWN0ZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByZXN1bHQ7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBzcmNBZGRyZXNzID0gKHBhY2tldCAhPSBudWxsICYmICFpc0Nvbm5lY3RlZCkgPyBuZXcgSW5ldFNvY2tldEFkZHJlc3MoKSA6IG51bGw7CisgICAgICAgICAgICByZXN1bHQgPSBMaWJjb3JlLm9zLnJlY3Zmcm9tKGZkLCBidWZmZXIsIGZsYWdzLCBzcmNBZGRyZXNzKTsKKyAgICAgICAgICAgIHJlc3VsdCA9IHBvc3RSZWN2ZnJvbShpc1JlYWQsIHBhY2tldCwgaXNDb25uZWN0ZWQsIHNyY0FkZHJlc3MsIHJlc3VsdCk7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICByZXN1bHQgPSBtYXliZVRocm93QWZ0ZXJSZWN2ZnJvbShpc1JlYWQsIGlzQ29ubmVjdGVkLCBlcnJub0V4Y2VwdGlvbik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgcG9zdFJlY3Zmcm9tKGJvb2xlYW4gaXNSZWFkLCBEYXRhZ3JhbVBhY2tldCBwYWNrZXQsIGJvb2xlYW4gaXNDb25uZWN0ZWQsIEluZXRTb2NrZXRBZGRyZXNzIHNyY0FkZHJlc3MsIGludCBieXRlQ291bnQpIHsKKyAgICAgICAgaWYgKGlzUmVhZCAmJiBieXRlQ291bnQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGlmIChwYWNrZXQgIT0gbnVsbCkgeworICAgICAgICAgICAgcGFja2V0LnNldExlbmd0aChieXRlQ291bnQpOworICAgICAgICAgICAgaWYgKCFpc0Nvbm5lY3RlZCkgeworICAgICAgICAgICAgICAgIHBhY2tldC5zZXRBZGRyZXNzKHNyY0FkZHJlc3MuZ2V0QWRkcmVzcygpKTsKKyAgICAgICAgICAgICAgICBwYWNrZXQuc2V0UG9ydChzcmNBZGRyZXNzLmdldFBvcnQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ5dGVDb3VudDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgbWF5YmVUaHJvd0FmdGVyUmVjdmZyb20oYm9vbGVhbiBpc1JlYWQsIGJvb2xlYW4gaXNDb25uZWN0ZWQsIEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uLCBTb2NrZXRUaW1lb3V0RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzUmVhZCkgeworICAgICAgICAgICAgaWYgKGVycm5vRXhjZXB0aW9uLmVycm5vID09IEVBR0FJTiB8fCBlcnJub0V4Y2VwdGlvbi5lcnJubyA9PSBFV09VTERCTE9DSykgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBlcnJub0V4Y2VwdGlvbi5yZXRocm93QXNTb2NrZXRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RlZCAmJiBlcnJub0V4Y2VwdGlvbi5lcnJubyA9PSBFQ09OTlJFRlVTRUQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUG9ydFVucmVhY2hhYmxlRXhjZXB0aW9uKCIiLCBlcnJub0V4Y2VwdGlvbik7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm5vRXhjZXB0aW9uLmVycm5vID09IEVBR0FJTiB8fCBlcnJub0V4Y2VwdGlvbi5lcnJubyA9PSBFV09VTERCTE9DSykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTb2NrZXRUaW1lb3V0RXhjZXB0aW9uKGVycm5vRXhjZXB0aW9uKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzU29ja2V0RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIEZpbGVEZXNjcmlwdG9yIHNvY2tldChib29sZWFuIHN0cmVhbSkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGVEZXNjcmlwdG9yIGZkOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmQgPSBMaWJjb3JlLm9zLnNvY2tldChBRl9JTkVUNiwgc3RyZWFtID8gU09DS19TVFJFQU0gOiBTT0NLX0RHUkFNLCAwKTsKKworICAgICAgICAgICAgLy8gVGhlIFJGQyAoaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzQ5My50eHQpIHNheXMgdGhhdCBJUFY2X01VTFRJQ0FTVF9IT1BTIGRlZmF1bHRzCisgICAgICAgICAgICAvLyB0byAxLiBUaGUgTGludXgga2VybmVsIChhdCBsZWFzdCB1cCB0byAyLjYuMzgpIGFjY2lkZW50YWxseSBkZWZhdWx0cyB0byA2NCAod2hpY2gKKyAgICAgICAgICAgIC8vIHdvdWxkIGJlIGNvcnJlY3QgZm9yIHRoZSAqdW5pY2FzdCogaG9wIGxpbWl0KS4KKyAgICAgICAgICAgIC8vIFNlZSBodHRwOi8vd3d3LnNwaW5pY3MubmV0L2xpc3RzL25ldGRldi9tc2cxMjkwMjIuaHRtbCwgdGhvdWdoIG5vIHBhdGNoIGFwcGVhcnMgdG8KKyAgICAgICAgICAgIC8vIGhhdmUgYmVlbiBhcHBsaWVkIGFzIGEgcmVzdWx0IG9mIHRoYXQgZGlzY3Vzc2lvbi4gSWYgdGhhdCBidWcgaXMgZXZlciBmaXhlZCwgd2UgY2FuCisgICAgICAgICAgICAvLyByZW1vdmUgdGhpcyBjb2RlLiBVbnRpbCB0aGVuLCB3ZSBtYW51YWxseSBzZXQgdGhlIGhvcCBsaW1pdCBvbiBJUHY2IGRhdGFncmFtIHNvY2tldHMuCisgICAgICAgICAgICAvLyAoSVB2NCBpcyBhbHJlYWR5IGNvcnJlY3QuKQorICAgICAgICAgICAgaWYgKCFzdHJlYW0pIHsKKyAgICAgICAgICAgICAgICBMaWJjb3JlLm9zLnNldHNvY2tvcHRJbnQoZmQsIElQUFJPVE9fSVBWNiwgSVBWNl9NVUxUSUNBU1RfSE9QUywgMSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBmZDsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRocm93IGVycm5vRXhjZXB0aW9uLnJldGhyb3dBc1NvY2tldEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBJbmV0QWRkcmVzcyBnZXRTb2NrZXRMb2NhbEFkZHJlc3MoRmlsZURlc2NyaXB0b3IgZmQpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldEFkZHJlc3Mgc2EgPSBMaWJjb3JlLm9zLmdldHNvY2tuYW1lKGZkKTsKKyAgICAgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIGlzYSA9IChJbmV0U29ja2V0QWRkcmVzcykgc2E7CisgICAgICAgICAgICByZXR1cm4gaXNhLmdldEFkZHJlc3MoKTsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlcnJub0V4Y2VwdGlvbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGludCBnZXRTb2NrZXRMb2NhbFBvcnQoRmlsZURlc2NyaXB0b3IgZmQpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldEFkZHJlc3Mgc2EgPSBMaWJjb3JlLm9zLmdldHNvY2tuYW1lKGZkKTsKKyAgICAgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIGlzYSA9IChJbmV0U29ja2V0QWRkcmVzcykgc2E7CisgICAgICAgICAgICByZXR1cm4gaXNhLmdldFBvcnQoKTsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlcnJub0V4Y2VwdGlvbik7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9Jb1V0aWxzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9Jb1V0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjQzZDhkOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL0lvVXRpbHMuamF2YQpAQCAtMCwwICsxLDE0OCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pbzsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlOworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRzOworaW1wb3J0IHN0YXRpYyBsaWJjb3JlLmlvLk9zQ29uc3RhbnRzLio7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBJb1V0aWxzIHsKKyAgICBwcml2YXRlIElvVXRpbHMoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbHMgY2xvc2UoMikgb24gJ2ZkJy4gQWxzbyByZXNldHMgdGhlIGludGVybmFsIGludCB0byAtMS4gRG9lcyBub3RoaW5nIGlmICdmZCcgaXMgbnVsbAorICAgICAqIG9yIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGNsb3NlKEZpbGVEZXNjcmlwdG9yIGZkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGZkICE9IG51bGwgJiYgZmQudmFsaWQoKSkgeworICAgICAgICAgICAgICAgIExpYmNvcmUub3MuY2xvc2UoZmQpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFcnJub0V4Y2VwdGlvbiBlcnJub0V4Y2VwdGlvbikgeworICAgICAgICAgICAgdGhyb3cgZXJybm9FeGNlcHRpb24ucmV0aHJvd0FzSU9FeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyAnY2xvc2VhYmxlJywgaWdub3JpbmcgYW55IGNoZWNrZWQgZXhjZXB0aW9ucy4gRG9lcyBub3RoaW5nIGlmICdjbG9zZWFibGUnIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGNsb3NlUXVpZXRseShBdXRvQ2xvc2VhYmxlIGNsb3NlYWJsZSkgeworICAgICAgICBpZiAoY2xvc2VhYmxlICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2xvc2VhYmxlLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJldGhyb3duKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgcmV0aHJvd247CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzICdmZCcsIGlnbm9yaW5nIGFueSBleGNlcHRpb25zLiBEb2VzIG5vdGhpbmcgaWYgJ2ZkJyBpcyBudWxsIG9yIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGNsb3NlUXVpZXRseShGaWxlRGVzY3JpcHRvciBmZCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW9VdGlscy5jbG9zZShmZCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyAnc29ja2V0JywgaWdub3JpbmcgYW55IGV4Y2VwdGlvbnMuIERvZXMgbm90aGluZyBpZiAnc29ja2V0JyBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjbG9zZVF1aWV0bHkoU29ja2V0IHNvY2tldCkgeworICAgICAgICBpZiAoc29ja2V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyAnZmQnIHRvIGJlIGJsb2NraW5nIG9yIG5vbi1ibG9ja2luZywgYWNjb3JkaW5nIHRvIHRoZSBzdGF0ZSBvZiAnYmxvY2tpbmcnLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRCbG9ja2luZyhGaWxlRGVzY3JpcHRvciBmZCwgYm9vbGVhbiBibG9ja2luZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBmbGFncyA9IExpYmNvcmUub3MuZmNudGxWb2lkKGZkLCBGX0dFVEZMKTsKKyAgICAgICAgICAgIGlmICghYmxvY2tpbmcpIHsKKyAgICAgICAgICAgICAgICBmbGFncyB8PSBPX05PTkJMT0NLOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmbGFncyAmPSB+T19OT05CTE9DSzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIExpYmNvcmUub3MuZmNudGxMb25nKGZkLCBGX1NFVEZMLCBmbGFncyk7CisgICAgICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGVycm5vRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyBlcnJub0V4Y2VwdGlvbi5yZXRocm93QXNJT0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29udGVudHMgb2YgJ3BhdGgnIGFzIGEgYnl0ZSBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSByZWFkRmlsZUFzQnl0ZUFycmF5KFN0cmluZyBwYXRoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcmVhZEZpbGVBc0J5dGVzKHBhdGgpLnRvQnl0ZUFycmF5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29udGVudHMgb2YgJ3BhdGgnIGFzIGEgc3RyaW5nLiBUaGUgY29udGVudHMgYXJlIGFzc3VtZWQgdG8gYmUgVVRGLTguCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgcmVhZEZpbGVBc1N0cmluZyhTdHJpbmcgcGF0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHJlYWRGaWxlQXNCeXRlcyhwYXRoKS50b1N0cmluZyhDaGFyc2V0cy5VVEZfOCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgVW5zYWZlQnl0ZVNlcXVlbmNlIHJlYWRGaWxlQXNCeXRlcyhTdHJpbmcgcGF0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUmFuZG9tQWNjZXNzRmlsZSBmID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSBuZXcgUmFuZG9tQWNjZXNzRmlsZShwYXRoLCAiciIpOworICAgICAgICAgICAgVW5zYWZlQnl0ZVNlcXVlbmNlIGJ5dGVzID0gbmV3IFVuc2FmZUJ5dGVTZXF1ZW5jZSgoaW50KSBmLmxlbmd0aCgpKTsKKyAgICAgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVs4MTkyXTsKKyAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgaW50IGJ5dGVDb3VudCA9IGYucmVhZChidWZmZXIpOworICAgICAgICAgICAgICAgIGlmIChieXRlQ291bnQgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJ5dGVzOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBieXRlcy53cml0ZShidWZmZXIsIDAsIGJ5dGVDb3VudCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBJb1V0aWxzLmNsb3NlUXVpZXRseShmKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlY3Vyc2l2ZWx5IGRlbGV0ZSBldmVyeXRoaW5nIGluIHtAY29kZSBkaXJ9LgorICAgICAqLworICAgIC8vIFRPRE86IHRoaXMgc2hvdWxkIHNwZWNpZnkgcGF0aHMgYXMgU3RyaW5ncyByYXRoZXIgdGhhbiBhcyBGaWxlcworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBkZWxldGVDb250ZW50cyhGaWxlIGRpcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZVtdIGZpbGVzID0gZGlyLmxpc3RGaWxlcygpOworICAgICAgICBpZiAoZmlsZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibm90IGEgZGlyZWN0b3J5OiAiICsgZGlyKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKEZpbGUgZmlsZSA6IGZpbGVzKSB7CisgICAgICAgICAgICBpZiAoZmlsZS5pc0RpcmVjdG9yeSgpKSB7CisgICAgICAgICAgICAgICAgZGVsZXRlQ29udGVudHMoZmlsZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIWZpbGUuZGVsZXRlKCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oImZhaWxlZCB0byBkZWxldGUgZmlsZTogIiArIGZpbGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vTGliY29yZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vTGliY29yZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVmNTdmOTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9MaWJjb3JlLmphdmEKQEAgLTAsMCArMSwyMyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pbzsKKworcHVibGljIGZpbmFsIGNsYXNzIExpYmNvcmUgeworICAgIHByaXZhdGUgTGliY29yZSgpIHsgfQorCisgICAgcHVibGljIHN0YXRpYyBPcyBvcyA9IG5ldyBCbG9ja0d1YXJkT3MobmV3IFBvc2l4KCkpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vTWVtb3J5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9NZW1vcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YmYxYWNiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vTWVtb3J5LmphdmEKQEAgLTAsMCArMSwxNzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pbzsKKworaW1wb3J0IGphdmEuaW8uRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLkJ5dGVPcmRlcjsKKworLyoqCisgKiBVbnNhZmUgYWNjZXNzIHRvIG1lbW9yeS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE1lbW9yeSB7CisgICAgcHJpdmF0ZSBNZW1vcnkoKSB7IH0KKworICAgIC8qKgorICAgICAqIFVzZWQgdG8gb3B0aW1pemUgbmlvIGhlYXAgYnVmZmVyIGJ1bGsgZ2V0IG9wZXJhdGlvbnMuICdkc3QnIG11c3QgYmUgYSBwcmltaXRpdmUgYXJyYXkuCisgICAgICogJ2RzdE9mZnNldCcgaXMgbWVhc3VyZWQgaW4gdW5pdHMgb2YgJ3NpemVvZkVsZW1lbnRzJyBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHVuc2FmZUJ1bGtHZXQoT2JqZWN0IGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGJ5dGVDb3VudCwKKyAgICAgICAgICAgIGJ5dGVbXSBzcmMsIGludCBzcmNPZmZzZXQsIGludCBzaXplb2ZFbGVtZW50cywgYm9vbGVhbiBzd2FwKTsKKworICAgIC8qKgorICAgICAqIFVzZWQgdG8gb3B0aW1pemUgbmlvIGhlYXAgYnVmZmVyIGJ1bGsgcHV0IG9wZXJhdGlvbnMuICdzcmMnIG11c3QgYmUgYSBwcmltaXRpdmUgYXJyYXkuCisgICAgICogJ3NyY09mZnNldCcgaXMgbWVhc3VyZWQgaW4gdW5pdHMgb2YgJ3NpemVvZkVsZW1lbnRzJyBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHVuc2FmZUJ1bGtQdXQoYnl0ZVtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGJ5dGVDb3VudCwKKyAgICAgICAgICAgIE9iamVjdCBzcmMsIGludCBzcmNPZmZzZXQsIGludCBzaXplb2ZFbGVtZW50cywgYm9vbGVhbiBzd2FwKTsKKworICAgIHB1YmxpYyBzdGF0aWMgaW50IHBlZWtJbnQoYnl0ZVtdIHNyYywgaW50IG9mZnNldCwgQnl0ZU9yZGVyIG9yZGVyKSB7CisgICAgICAgIGlmIChvcmRlciA9PSBCeXRlT3JkZXIuQklHX0VORElBTikgeworICAgICAgICAgICAgcmV0dXJuICgoKHNyY1tvZmZzZXQrK10gJiAweGZmKSA8PCAyNCkgfAorICAgICAgICAgICAgICAgICAgICAoKHNyY1tvZmZzZXQrK10gJiAweGZmKSA8PCAxNikgfAorICAgICAgICAgICAgICAgICAgICAoKHNyY1tvZmZzZXQrK10gJiAweGZmKSA8PCAgOCkgfAorICAgICAgICAgICAgICAgICAgICAoKHNyY1tvZmZzZXQgIF0gJiAweGZmKSA8PCAgMCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuICgoKHNyY1tvZmZzZXQrK10gJiAweGZmKSA8PCAgMCkgfAorICAgICAgICAgICAgICAgICAgICAoKHNyY1tvZmZzZXQrK10gJiAweGZmKSA8PCAgOCkgfAorICAgICAgICAgICAgICAgICAgICAoKHNyY1tvZmZzZXQrK10gJiAweGZmKSA8PCAxNikgfAorICAgICAgICAgICAgICAgICAgICAoKHNyY1tvZmZzZXQgIF0gJiAweGZmKSA8PCAyNCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBsb25nIHBlZWtMb25nKGJ5dGVbXSBzcmMsIGludCBvZmZzZXQsIEJ5dGVPcmRlciBvcmRlcikgeworICAgICAgICBpZiAob3JkZXIgPT0gQnl0ZU9yZGVyLkJJR19FTkRJQU4pIHsKKyAgICAgICAgICAgIGludCBoID0gKChzcmNbb2Zmc2V0KytdICYgMHhmZikgPDwgMjQpIHwKKyAgICAgICAgICAgICAgICAgICAgKChzcmNbb2Zmc2V0KytdICYgMHhmZikgPDwgMTYpIHwKKyAgICAgICAgICAgICAgICAgICAgKChzcmNbb2Zmc2V0KytdICYgMHhmZikgPDwgIDgpIHwKKyAgICAgICAgICAgICAgICAgICAgKChzcmNbb2Zmc2V0KytdICYgMHhmZikgPDwgIDApOworICAgICAgICAgICAgaW50IGwgPSAoKHNyY1tvZmZzZXQrK10gJiAweGZmKSA8PCAyNCkgfAorICAgICAgICAgICAgICAgICAgICAoKHNyY1tvZmZzZXQrK10gJiAweGZmKSA8PCAxNikgfAorICAgICAgICAgICAgICAgICAgICAoKHNyY1tvZmZzZXQrK10gJiAweGZmKSA8PCAgOCkgfAorICAgICAgICAgICAgICAgICAgICAoKHNyY1tvZmZzZXQgIF0gJiAweGZmKSA8PCAgMCk7CisgICAgICAgICAgICByZXR1cm4gKCgobG9uZykgaCkgPDwgMzJMKSB8ICgobG9uZykgbCkgJiAweGZmZmZmZmZmTDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGludCBsID0gKChzcmNbb2Zmc2V0KytdICYgMHhmZikgPDwgIDApIHwKKyAgICAgICAgICAgICAgICAgICAgKChzcmNbb2Zmc2V0KytdICYgMHhmZikgPDwgIDgpIHwKKyAgICAgICAgICAgICAgICAgICAgKChzcmNbb2Zmc2V0KytdICYgMHhmZikgPDwgMTYpIHwKKyAgICAgICAgICAgICAgICAgICAgKChzcmNbb2Zmc2V0KytdICYgMHhmZikgPDwgMjQpOworICAgICAgICAgICAgaW50IGggPSAoKHNyY1tvZmZzZXQrK10gJiAweGZmKSA8PCAgMCkgfAorICAgICAgICAgICAgICAgICAgICAoKHNyY1tvZmZzZXQrK10gJiAweGZmKSA8PCAgOCkgfAorICAgICAgICAgICAgICAgICAgICAoKHNyY1tvZmZzZXQrK10gJiAweGZmKSA8PCAxNikgfAorICAgICAgICAgICAgICAgICAgICAoKHNyY1tvZmZzZXQgIF0gJiAweGZmKSA8PCAyNCk7CisgICAgICAgICAgICByZXR1cm4gKCgobG9uZykgaCkgPDwgMzJMKSB8ICgobG9uZykgbCkgJiAweGZmZmZmZmZmTDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgc2hvcnQgcGVla1Nob3J0KGJ5dGVbXSBzcmMsIGludCBvZmZzZXQsIEJ5dGVPcmRlciBvcmRlcikgeworICAgICAgICBpZiAob3JkZXIgPT0gQnl0ZU9yZGVyLkJJR19FTkRJQU4pIHsKKyAgICAgICAgICAgIHJldHVybiAoc2hvcnQpICgoc3JjW29mZnNldF0gPDwgOCkgfCAoc3JjW29mZnNldCArIDFdICYgMHhmZikpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIChzaG9ydCkgKChzcmNbb2Zmc2V0ICsgMV0gPDwgOCkgfCAoc3JjW29mZnNldF0gJiAweGZmKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcG9rZUludChieXRlW10gZHN0LCBpbnQgb2Zmc2V0LCBpbnQgdmFsdWUsIEJ5dGVPcmRlciBvcmRlcikgeworICAgICAgICBpZiAob3JkZXIgPT0gQnl0ZU9yZGVyLkJJR19FTkRJQU4pIHsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQrK10gPSAoYnl0ZSkgKCh2YWx1ZSA+PiAyNCkgJiAweGZmKTsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQrK10gPSAoYnl0ZSkgKCh2YWx1ZSA+PiAxNikgJiAweGZmKTsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQrK10gPSAoYnl0ZSkgKCh2YWx1ZSA+PiAgOCkgJiAweGZmKTsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQgIF0gPSAoYnl0ZSkgKCh2YWx1ZSA+PiAgMCkgJiAweGZmKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQrK10gPSAoYnl0ZSkgKCh2YWx1ZSA+PiAgMCkgJiAweGZmKTsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQrK10gPSAoYnl0ZSkgKCh2YWx1ZSA+PiAgOCkgJiAweGZmKTsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQrK10gPSAoYnl0ZSkgKCh2YWx1ZSA+PiAxNikgJiAweGZmKTsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQgIF0gPSAoYnl0ZSkgKCh2YWx1ZSA+PiAyNCkgJiAweGZmKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBwb2tlTG9uZyhieXRlW10gZHN0LCBpbnQgb2Zmc2V0LCBsb25nIHZhbHVlLCBCeXRlT3JkZXIgb3JkZXIpIHsKKyAgICAgICAgaWYgKG9yZGVyID09IEJ5dGVPcmRlci5CSUdfRU5ESUFOKSB7CisgICAgICAgICAgICBpbnQgaSA9IChpbnQpICh2YWx1ZSA+PiAzMik7CisgICAgICAgICAgICBkc3Rbb2Zmc2V0KytdID0gKGJ5dGUpICgoaSA+PiAyNCkgJiAweGZmKTsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQrK10gPSAoYnl0ZSkgKChpID4+IDE2KSAmIDB4ZmYpOworICAgICAgICAgICAgZHN0W29mZnNldCsrXSA9IChieXRlKSAoKGkgPj4gIDgpICYgMHhmZik7CisgICAgICAgICAgICBkc3Rbb2Zmc2V0KytdID0gKGJ5dGUpICgoaSA+PiAgMCkgJiAweGZmKTsKKyAgICAgICAgICAgIGkgPSAoaW50KSB2YWx1ZTsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQrK10gPSAoYnl0ZSkgKChpID4+IDI0KSAmIDB4ZmYpOworICAgICAgICAgICAgZHN0W29mZnNldCsrXSA9IChieXRlKSAoKGkgPj4gMTYpICYgMHhmZik7CisgICAgICAgICAgICBkc3Rbb2Zmc2V0KytdID0gKGJ5dGUpICgoaSA+PiAgOCkgJiAweGZmKTsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQgIF0gPSAoYnl0ZSkgKChpID4+ICAwKSAmIDB4ZmYpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW50IGkgPSAoaW50KSB2YWx1ZTsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQrK10gPSAoYnl0ZSkgKChpID4+ICAwKSAmIDB4ZmYpOworICAgICAgICAgICAgZHN0W29mZnNldCsrXSA9IChieXRlKSAoKGkgPj4gIDgpICYgMHhmZik7CisgICAgICAgICAgICBkc3Rbb2Zmc2V0KytdID0gKGJ5dGUpICgoaSA+PiAxNikgJiAweGZmKTsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQrK10gPSAoYnl0ZSkgKChpID4+IDI0KSAmIDB4ZmYpOworICAgICAgICAgICAgaSA9IChpbnQpICh2YWx1ZSA+PiAzMik7CisgICAgICAgICAgICBkc3Rbb2Zmc2V0KytdID0gKGJ5dGUpICgoaSA+PiAgMCkgJiAweGZmKTsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQrK10gPSAoYnl0ZSkgKChpID4+ICA4KSAmIDB4ZmYpOworICAgICAgICAgICAgZHN0W29mZnNldCsrXSA9IChieXRlKSAoKGkgPj4gMTYpICYgMHhmZik7CisgICAgICAgICAgICBkc3Rbb2Zmc2V0ICBdID0gKGJ5dGUpICgoaSA+PiAyNCkgJiAweGZmKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBwb2tlU2hvcnQoYnl0ZVtdIGRzdCwgaW50IG9mZnNldCwgc2hvcnQgdmFsdWUsIEJ5dGVPcmRlciBvcmRlcikgeworICAgICAgICBpZiAob3JkZXIgPT0gQnl0ZU9yZGVyLkJJR19FTkRJQU4pIHsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQrK10gPSAoYnl0ZSkgKCh2YWx1ZSA+PiA4KSAmIDB4ZmYpOworICAgICAgICAgICAgZHN0W29mZnNldCAgXSA9IChieXRlKSAoKHZhbHVlID4+IDApICYgMHhmZik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBkc3Rbb2Zmc2V0KytdID0gKGJ5dGUpICgodmFsdWUgPj4gMCkgJiAweGZmKTsKKyAgICAgICAgICAgIGRzdFtvZmZzZXQgIF0gPSAoYnl0ZSkgKCh2YWx1ZSA+PiA4KSAmIDB4ZmYpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29waWVzICdieXRlQ291bnQnIGJ5dGVzIGZyb20gdGhlIHNvdXJjZSB0byB0aGUgZGVzdGluYXRpb24uIFRoZSBvYmplY3RzIGFyZSBlaXRoZXIKKyAgICAgKiBpbnN0YW5jZXMgb2YgRGlyZWN0Qnl0ZUJ1ZmZlciBvciBieXRlW10uIFRoZSBvZmZzZXRzIGluIHRoZSBieXRlW10gY2FzZSBtdXN0IGluY2x1ZGUKKyAgICAgKiB0aGUgQnVmZmVyLmFycmF5T2Zmc2V0IGlmIHRoZSBhcnJheSBjYW1lIGZyb20gYSBCdWZmZXIuYXJyYXkgY2FsbC4gV2UgY291bGQgbWFrZSB0aGlzCisgICAgICogcHJpdmF0ZSBhbmQgcHJvdmlkZSB0aGUgZm91ciB0eXBlLXNhZmUgdmFyaWFudHMsIGJ1dCB0aGVuIEJ5dGVCdWZmZXIucHV0KEJ5dGVCdWZmZXIpCisgICAgICogd291bGQgbmVlZCB0byB3b3JrIG91dCB3aGljaCB0byBjYWxsIGJhc2VkIG9uIHdoZXRoZXIgdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gYnVmZmVycworICAgICAqIGFyZSBkaXJlY3Qgb3Igbm90LgorICAgICAqCisgICAgICogQGhpZGUgbWFrZSB0eXBlLXNhZmUgYmVmb3JlIG1ha2luZyBwdWJsaWM/CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBtZW1tb3ZlKE9iamVjdCBkc3RPYmplY3QsIGludCBkc3RPZmZzZXQsIE9iamVjdCBzcmNPYmplY3QsIGludCBzcmNPZmZzZXQsIGxvbmcgYnl0ZUNvdW50KTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJ5dGUgcGVla0J5dGUoaW50IGFkZHJlc3MpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBwZWVrSW50KGludCBhZGRyZXNzLCBib29sZWFuIHN3YXApOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGxvbmcgcGVla0xvbmcoaW50IGFkZHJlc3MsIGJvb2xlYW4gc3dhcCk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgc2hvcnQgcGVla1Nob3J0KGludCBhZGRyZXNzLCBib29sZWFuIHN3YXApOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBwZWVrQnl0ZUFycmF5KGludCBhZGRyZXNzLCBieXRlW10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgYnl0ZUNvdW50KTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHBlZWtDaGFyQXJyYXkoaW50IGFkZHJlc3MsIGNoYXJbXSBkc3QsIGludCBkc3RPZmZzZXQsIGludCBjaGFyQ291bnQsIGJvb2xlYW4gc3dhcCk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBwZWVrRG91YmxlQXJyYXkoaW50IGFkZHJlc3MsIGRvdWJsZVtdIGRzdCwgaW50IGRzdE9mZnNldCwgaW50IGRvdWJsZUNvdW50LCBib29sZWFuIHN3YXApOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgcGVla0Zsb2F0QXJyYXkoaW50IGFkZHJlc3MsIGZsb2F0W10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgZmxvYXRDb3VudCwgYm9vbGVhbiBzd2FwKTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHBlZWtJbnRBcnJheShpbnQgYWRkcmVzcywgaW50W10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgaW50Q291bnQsIGJvb2xlYW4gc3dhcCk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBwZWVrTG9uZ0FycmF5KGludCBhZGRyZXNzLCBsb25nW10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgbG9uZ0NvdW50LCBib29sZWFuIHN3YXApOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgcGVla1Nob3J0QXJyYXkoaW50IGFkZHJlc3MsIHNob3J0W10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgc2hvcnRDb3VudCwgYm9vbGVhbiBzd2FwKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgcG9rZUJ5dGUoaW50IGFkZHJlc3MsIGJ5dGUgdmFsdWUpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgcG9rZUludChpbnQgYWRkcmVzcywgaW50IHZhbHVlLCBib29sZWFuIHN3YXApOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgcG9rZUxvbmcoaW50IGFkZHJlc3MsIGxvbmcgdmFsdWUsIGJvb2xlYW4gc3dhcCk7CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBwb2tlU2hvcnQoaW50IGFkZHJlc3MsIHNob3J0IHZhbHVlLCBib29sZWFuIHN3YXApOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBwb2tlQnl0ZUFycmF5KGludCBhZGRyZXNzLCBieXRlW10gc3JjLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgcG9rZUNoYXJBcnJheShpbnQgYWRkcmVzcywgY2hhcltdIHNyYywgaW50IG9mZnNldCwgaW50IGNvdW50LCBib29sZWFuIHN3YXApOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgcG9rZURvdWJsZUFycmF5KGludCBhZGRyZXNzLCBkb3VibGVbXSBzcmMsIGludCBvZmZzZXQsIGludCBjb3VudCwgYm9vbGVhbiBzd2FwKTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHBva2VGbG9hdEFycmF5KGludCBhZGRyZXNzLCBmbG9hdFtdIHNyYywgaW50IG9mZnNldCwgaW50IGNvdW50LCBib29sZWFuIHN3YXApOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgcG9rZUludEFycmF5KGludCBhZGRyZXNzLCBpbnRbXSBzcmMsIGludCBvZmZzZXQsIGludCBjb3VudCwgYm9vbGVhbiBzd2FwKTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHBva2VMb25nQXJyYXkoaW50IGFkZHJlc3MsIGxvbmdbXSBzcmMsIGludCBvZmZzZXQsIGludCBjb3VudCwgYm9vbGVhbiBzd2FwKTsKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHBva2VTaG9ydEFycmF5KGludCBhZGRyZXNzLCBzaG9ydFtdIHNyYywgaW50IG9mZnNldCwgaW50IGNvdW50LCBib29sZWFuIHN3YXApOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vTWVtb3J5TWFwcGVkRmlsZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vTWVtb3J5TWFwcGVkRmlsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjMTA2ZGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9NZW1vcnlNYXBwZWRGaWxlLmphdmEKQEAgLTAsMCArMSw5MyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pbzsKKworaW1wb3J0IGphdmEuaW8uRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGU7CitpbXBvcnQgamF2YS5uaW8uQnl0ZU9yZGVyOworaW1wb3J0IGphdmEubmlvLk5pb1V0aWxzOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkZpbGVDaGFubmVsOworaW1wb3J0IGxpYmNvcmUuaW8uRXJybm9FeGNlcHRpb247CitpbXBvcnQgbGliY29yZS5pby5MaWJjb3JlOworaW1wb3J0IGxpYmNvcmUuaW8uTWVtb3J5OworaW1wb3J0IHN0YXRpYyBsaWJjb3JlLmlvLk9zQ29uc3RhbnRzLio7CisKKy8qKgorICogQSBtZW1vcnktbWFwcGVkIGZpbGUuIFVzZSB7QGxpbmsgI21tYXB9IHRvIG1hcCBhIGZpbGUsIHtAbGluayAjY2xvc2V9IHRvIHVubWFwIGEgZmlsZSwKKyAqIGFuZCBlaXRoZXIge0BsaW5rICNiaWdFbmRpYW5JdGVyYXRvcn0gb3Ige0BsaW5rICNsaXR0bGVFbmRpYW5JdGVyYXRvcn0gdG8gZ2V0IGEgc2Vla2FibGUKKyAqIHtAbGluayBCdWZmZXJJdGVyYXRvcn0gb3ZlciB0aGUgbWFwcGVkIGRhdGEuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBNZW1vcnlNYXBwZWRGaWxlIGltcGxlbWVudHMgQXV0b0Nsb3NlYWJsZSB7CisgICAgcHJpdmF0ZSBsb25nIGFkZHJlc3M7CisgICAgcHJpdmF0ZSBmaW5hbCBsb25nIHNpemU7CisKKyAgICAvKioKKyAgICAgKiBVc2UgdGhpcyBpZiB5b3UndmUgY2FsbGVkIHtAY29kZSBtbWFwfSB5b3Vyc2VsZi4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWVtb3J5TWFwcGVkRmlsZShsb25nIGFkZHJlc3MsIGxvbmcgc2l6ZSkgeworICAgICAgICB0aGlzLmFkZHJlc3MgPSBhZGRyZXNzOworICAgICAgICB0aGlzLnNpemUgPSBzaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVzZSB0aGlzIHRvIG1tYXAgdGhlIHdob2xlIGZpbGUgcmVhZC1vbmx5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTWVtb3J5TWFwcGVkRmlsZSBtbWFwUk8oU3RyaW5nIHBhdGgpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIEZpbGVEZXNjcmlwdG9yIGZkID0gTGliY29yZS5vcy5vcGVuKHBhdGgsIE9fUkRPTkxZLCAwKTsKKyAgICAgICAgbG9uZyBzaXplID0gTGliY29yZS5vcy5mc3RhdChmZCkuc3Rfc2l6ZTsKKyAgICAgICAgbG9uZyBhZGRyZXNzID0gTGliY29yZS5vcy5tbWFwKDBMLCBzaXplLCBQUk9UX1JFQUQsIE1BUF9TSEFSRUQsIGZkLCAwKTsKKyAgICAgICAgTGliY29yZS5vcy5jbG9zZShmZCk7CisgICAgICAgIHJldHVybiBuZXcgTWVtb3J5TWFwcGVkRmlsZShhZGRyZXNzLCBzaXplKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVbm1hcHMgdGhpcyBtZW1vcnktbWFwcGVkIGZpbGUgdXNpbmcgbXVubWFwKDIpLiBUaGlzIGlzIGEgbm8tb3AgaWYgY2xvc2UgaGFzIGFscmVhZHkgYmVlbgorICAgICAqIGNhbGxlZC4gTm90ZSB0aGF0IHRoaXMgY2xhc3MgZG9lcyA8aT5ub3Q8L2k+IHVzZSBmaW5hbGl6YXRpb247IHlvdSBtdXN0IGNhbGwge0Bjb2RlIGNsb3NlfQorICAgICAqIHlvdXJzZWxmLgorICAgICAqCisgICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCBpbnZhbGlkYXRlcyBhbnkgaXRlcmF0b3JzIG92ZXIgdGhpcyB7QGNvZGUgTWVtb3J5TWFwcGVkRmlsZX0uIEl0IGlzIGFuCisgICAgICogZXJyb3IgdG8gdXNlIHN1Y2ggYW4gaXRlcmF0b3IgYWZ0ZXIgY2FsbGluZyB7QGNvZGUgY2xvc2V9LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhZGRyZXNzICE9IDApIHsKKyAgICAgICAgICAgIExpYmNvcmUub3MubXVubWFwKGFkZHJlc3MsIHNpemUpOworICAgICAgICAgICAgYWRkcmVzcyA9IDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbmV3IGl0ZXJhdG9yIHRoYXQgdHJlYXRzIHRoZSBtYXBwZWQgZGF0YSBhcyBiaWctZW5kaWFuLgorICAgICAqLworICAgIHB1YmxpYyBCdWZmZXJJdGVyYXRvciBiaWdFbmRpYW5JdGVyYXRvcigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBOaW9CdWZmZXJJdGVyYXRvcigoaW50KSBhZGRyZXNzLCAoaW50KSBzaXplLCBCeXRlT3JkZXIubmF0aXZlT3JkZXIoKSAhPSBCeXRlT3JkZXIuQklHX0VORElBTik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBpdGVyYXRvciB0aGF0IHRyZWF0cyB0aGUgbWFwcGVkIGRhdGEgYXMgbGl0dGxlLWVuZGlhbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVmZmVySXRlcmF0b3IgbGl0dGxlRW5kaWFuSXRlcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBuZXcgTmlvQnVmZmVySXRlcmF0b3IoKGludCkgYWRkcmVzcywgKGludCkgc2l6ZSwgQnl0ZU9yZGVyLm5hdGl2ZU9yZGVyKCkgIT0gQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNpemUgaW4gYnl0ZXMgb2YgdGhlIG1lbW9yeS1tYXBwZWQgcmVnaW9uLgorICAgICAqLworICAgIHB1YmxpYyBsb25nIHNpemUoKSB7CisgICAgICAgIHJldHVybiBzaXplOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL05pb0J1ZmZlckl0ZXJhdG9yLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9OaW9CdWZmZXJJdGVyYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFlMjllNTkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9OaW9CdWZmZXJJdGVyYXRvci5qYXZhCkBAIC0wLDAgKzEsNzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuaW87CisKK2ltcG9ydCBsaWJjb3JlLmlvLk1lbW9yeTsKKworLyoqCisgKiBJdGVyYXRlcyBvdmVyIGJpZy0gb3IgbGl0dGxlLWVuZGlhbiBieXRlcyBvbiB0aGUgbmF0aXZlIGhlYXAuCisgKiBTZWUge0BsaW5rIE1lbW9yeU1hcHBlZEZpbGUjYmlnRW5kaWFuSXRlcmF0b3J9IGFuZCB7QGxpbmsgTWVtb3J5TWFwcGVkRmlsZSNsaXR0bGVFbmRpYW5JdGVyYXRvcn0uCisgKgorICogQGhpZGUgZG9uJ3QgbWFrZSB0aGlzIHB1YmxpYyB3aXRob3V0IGFkZGluZyBib3VuZHMgY2hlY2tpbmcuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBOaW9CdWZmZXJJdGVyYXRvciBleHRlbmRzIEJ1ZmZlckl0ZXJhdG9yIHsKKyAgICBwcml2YXRlIGZpbmFsIGludCBhZGRyZXNzOworICAgIHByaXZhdGUgZmluYWwgaW50IHNpemU7CisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHN3YXA7CisKKyAgICBwcml2YXRlIGludCBwb3NpdGlvbjsKKworICAgIE5pb0J1ZmZlckl0ZXJhdG9yKGludCBhZGRyZXNzLCBpbnQgc2l6ZSwgYm9vbGVhbiBzd2FwKSB7CisgICAgICAgIHRoaXMuYWRkcmVzcyA9IGFkZHJlc3M7CisgICAgICAgIHRoaXMuc2l6ZSA9IHNpemU7CisgICAgICAgIHRoaXMuc3dhcCA9IHN3YXA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2VlayhpbnQgb2Zmc2V0KSB7CisgICAgICAgIHBvc2l0aW9uID0gb2Zmc2V0OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNraXAoaW50IGJ5dGVDb3VudCkgeworICAgICAgICBwb3NpdGlvbiArPSBieXRlQ291bnQ7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZEJ5dGVBcnJheShieXRlW10gZHN0LCBpbnQgZHN0T2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB7CisgICAgICAgIE1lbW9yeS5wZWVrQnl0ZUFycmF5KGFkZHJlc3MgKyBwb3NpdGlvbiwgZHN0LCBkc3RPZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIHBvc2l0aW9uICs9IGJ5dGVDb3VudDsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZSByZWFkQnl0ZSgpIHsKKyAgICAgICAgYnl0ZSByZXN1bHQgPSBNZW1vcnkucGVla0J5dGUoYWRkcmVzcyArIHBvc2l0aW9uKTsKKyAgICAgICAgKytwb3NpdGlvbjsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IHJlYWRJbnQoKSB7CisgICAgICAgIGludCByZXN1bHQgPSBNZW1vcnkucGVla0ludChhZGRyZXNzICsgcG9zaXRpb24sIHN3YXApOworICAgICAgICBwb3NpdGlvbiArPSBTaXplT2YuSU5UOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWRJbnRBcnJheShpbnRbXSBkc3QsIGludCBkc3RPZmZzZXQsIGludCBpbnRDb3VudCkgeworICAgICAgICBNZW1vcnkucGVla0ludEFycmF5KGFkZHJlc3MgKyBwb3NpdGlvbiwgZHN0LCBkc3RPZmZzZXQsIGludENvdW50LCBzd2FwKTsKKyAgICAgICAgcG9zaXRpb24gKz0gU2l6ZU9mLklOVCAqIGludENvdW50OworICAgIH0KKworICAgIHB1YmxpYyBzaG9ydCByZWFkU2hvcnQoKSB7CisgICAgICAgIHNob3J0IHJlc3VsdCA9IE1lbW9yeS5wZWVrU2hvcnQoYWRkcmVzcyArIHBvc2l0aW9uLCBzd2FwKTsKKyAgICAgICAgcG9zaXRpb24gKz0gU2l6ZU9mLlNIT1JUOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL09zLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9Pcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ2MzdiNjcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9Pcy5qYXZhCkBAIC0wLDAgKzEsMTIyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmlvOworCitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0U29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgbGliY29yZS51dGlsLk11dGFibGVJbnQ7CitpbXBvcnQgbGliY29yZS51dGlsLk11dGFibGVMb25nOworCitwdWJsaWMgaW50ZXJmYWNlIE9zIHsKKyAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3IgYWNjZXB0KEZpbGVEZXNjcmlwdG9yIGZkLCBJbmV0U29ja2V0QWRkcmVzcyBwZWVyQWRkcmVzcykgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBib29sZWFuIGFjY2VzcyhTdHJpbmcgcGF0aCwgaW50IG1vZGUpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBiaW5kKEZpbGVEZXNjcmlwdG9yIGZkLCBJbmV0QWRkcmVzcyBhZGRyZXNzLCBpbnQgcG9ydCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyB2b2lkIGNobW9kKFN0cmluZyBwYXRoLCBpbnQgbW9kZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyB2b2lkIGNsb3NlKEZpbGVEZXNjcmlwdG9yIGZkKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIHZvaWQgY29ubmVjdChGaWxlRGVzY3JpcHRvciBmZCwgSW5ldEFkZHJlc3MgYWRkcmVzcywgaW50IHBvcnQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3IgZHVwKEZpbGVEZXNjcmlwdG9yIG9sZEZkKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIEZpbGVEZXNjcmlwdG9yIGR1cDIoRmlsZURlc2NyaXB0b3Igb2xkRmQsIGludCBuZXdGZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBTdHJpbmdbXSBlbnZpcm9uKCk7CisgICAgcHVibGljIGludCBmY250bFZvaWQoRmlsZURlc2NyaXB0b3IgZmQsIGludCBjbWQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgaW50IGZjbnRsTG9uZyhGaWxlRGVzY3JpcHRvciBmZCwgaW50IGNtZCwgbG9uZyBhcmcpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgaW50IGZjbnRsRmxvY2soRmlsZURlc2NyaXB0b3IgZmQsIGludCBjbWQsIFN0cnVjdEZsb2NrIGFyZykgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyB2b2lkIGZkYXRhc3luYyhGaWxlRGVzY3JpcHRvciBmZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBTdHJ1Y3RTdGF0IGZzdGF0KEZpbGVEZXNjcmlwdG9yIGZkKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIFN0cnVjdFN0YXRGcyBmc3RhdGZzKEZpbGVEZXNjcmlwdG9yIGZkKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIHZvaWQgZnN5bmMoRmlsZURlc2NyaXB0b3IgZmQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBmdHJ1bmNhdGUoRmlsZURlc2NyaXB0b3IgZmQsIGxvbmcgbGVuZ3RoKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIFN0cmluZyBnYWlfc3RyZXJyb3IoaW50IGVycm9yKTsKKyAgICBwdWJsaWMgSW5ldEFkZHJlc3NbXSBnZXRhZGRyaW5mbyhTdHJpbmcgbm9kZSwgU3RydWN0QWRkcmluZm8gaGludHMpIHRocm93cyBHYWlFeGNlcHRpb247CisgICAgcHVibGljIGludCBnZXRlZ2lkKCk7CisgICAgcHVibGljIGludCBnZXRldWlkKCk7CisgICAgcHVibGljIGludCBnZXRnaWQoKTsKKyAgICBwdWJsaWMgU3RyaW5nIGdldGVudihTdHJpbmcgbmFtZSk7CisgICAgLyogVE9ETzogYnJlYWsgaW50byBnZXRuYW1laW5mb0hvc3QgYW5kIGdldG5hbWVpbmZvU2VydmljZT8gKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldG5hbWVpbmZvKEluZXRBZGRyZXNzIGFkZHJlc3MsIGludCBmbGFncykgdGhyb3dzIEdhaUV4Y2VwdGlvbjsKKyAgICBwdWJsaWMgaW50IGdldHBpZCgpOworICAgIHB1YmxpYyBpbnQgZ2V0cHBpZCgpOworICAgIHB1YmxpYyBTdHJ1Y3RQYXNzd2QgZ2V0cHduYW0oU3RyaW5nIG5hbWUpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgU3RydWN0UGFzc3dkIGdldHB3dWlkKGludCB1aWQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgU29ja2V0QWRkcmVzcyBnZXRzb2NrbmFtZShGaWxlRGVzY3JpcHRvciBmZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBpbnQgZ2V0c29ja29wdEJ5dGUoRmlsZURlc2NyaXB0b3IgZmQsIGludCBsZXZlbCwgaW50IG9wdGlvbikgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBJbmV0QWRkcmVzcyBnZXRzb2Nrb3B0SW5BZGRyKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgbGV2ZWwsIGludCBvcHRpb24pIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgaW50IGdldHNvY2tvcHRJbnQoRmlsZURlc2NyaXB0b3IgZmQsIGludCBsZXZlbCwgaW50IG9wdGlvbikgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBTdHJ1Y3RMaW5nZXIgZ2V0c29ja29wdExpbmdlcihGaWxlRGVzY3JpcHRvciBmZCwgaW50IGxldmVsLCBpbnQgb3B0aW9uKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIFN0cnVjdFRpbWV2YWwgZ2V0c29ja29wdFRpbWV2YWwoRmlsZURlc2NyaXB0b3IgZmQsIGludCBsZXZlbCwgaW50IG9wdGlvbikgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBpbnQgZ2V0dWlkKCk7CisgICAgcHVibGljIFN0cmluZyBpZl9pbmRleHRvbmFtZShpbnQgaW5kZXgpOworICAgIHB1YmxpYyBJbmV0QWRkcmVzcyBpbmV0X3B0b24oaW50IGZhbWlseSwgU3RyaW5nIGFkZHJlc3MpOworICAgIHB1YmxpYyBJbmV0QWRkcmVzcyBpb2N0bEluZXRBZGRyZXNzKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgY21kLCBTdHJpbmcgaW50ZXJmYWNlTmFtZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBpbnQgaW9jdGxJbnQoRmlsZURlc2NyaXB0b3IgZmQsIGludCBjbWQsIE11dGFibGVJbnQgYXJnKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIGJvb2xlYW4gaXNhdHR5KEZpbGVEZXNjcmlwdG9yIGZkKTsKKyAgICBwdWJsaWMgdm9pZCBraWxsKGludCBwaWQsIGludCBzaWduYWwpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBsaXN0ZW4oRmlsZURlc2NyaXB0b3IgZmQsIGludCBiYWNrbG9nKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIGxvbmcgbHNlZWsoRmlsZURlc2NyaXB0b3IgZmQsIGxvbmcgb2Zmc2V0LCBpbnQgd2hlbmNlKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIFN0cnVjdFN0YXQgbHN0YXQoU3RyaW5nIHBhdGgpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBtaW5jb3JlKGxvbmcgYWRkcmVzcywgbG9uZyBieXRlQ291bnQsIGJ5dGVbXSB2ZWN0b3IpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBta2RpcihTdHJpbmcgcGF0aCwgaW50IG1vZGUpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBtbG9jayhsb25nIGFkZHJlc3MsIGxvbmcgYnl0ZUNvdW50KSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIGxvbmcgbW1hcChsb25nIGFkZHJlc3MsIGxvbmcgYnl0ZUNvdW50LCBpbnQgcHJvdCwgaW50IGZsYWdzLCBGaWxlRGVzY3JpcHRvciBmZCwgbG9uZyBvZmZzZXQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBtc3luYyhsb25nIGFkZHJlc3MsIGxvbmcgYnl0ZUNvdW50LCBpbnQgZmxhZ3MpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBtdW5sb2NrKGxvbmcgYWRkcmVzcywgbG9uZyBieXRlQ291bnQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBtdW5tYXAobG9uZyBhZGRyZXNzLCBsb25nIGJ5dGVDb3VudCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBGaWxlRGVzY3JpcHRvciBvcGVuKFN0cmluZyBwYXRoLCBpbnQgZmxhZ3MsIGludCBtb2RlKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIEZpbGVEZXNjcmlwdG9yW10gcGlwZSgpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICAvKiBUT0RPOiBpZiB3ZSB1c2VkIHRoZSBub24tc3RhbmRhcmQgcHBvbGwoMikgYmVoaW5kIHRoZSBzY2VuZXMsIHdlIGNvdWxkIHRha2UgYSBsb25nIHRpbWVvdXQuICovCisgICAgcHVibGljIGludCBwb2xsKFN0cnVjdFBvbGxmZFtdIGZkcywgaW50IHRpbWVvdXRNcykgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBpbnQgcHJlYWQoRmlsZURlc2NyaXB0b3IgZmQsIEJ5dGVCdWZmZXIgYnVmZmVyLCBsb25nIG9mZnNldCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBpbnQgcHJlYWQoRmlsZURlc2NyaXB0b3IgZmQsIGJ5dGVbXSBieXRlcywgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQsIGxvbmcgb2Zmc2V0KSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIGludCBwd3JpdGUoRmlsZURlc2NyaXB0b3IgZmQsIEJ5dGVCdWZmZXIgYnVmZmVyLCBsb25nIG9mZnNldCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBpbnQgcHdyaXRlKEZpbGVEZXNjcmlwdG9yIGZkLCBieXRlW10gYnl0ZXMsIGludCBieXRlT2Zmc2V0LCBpbnQgYnl0ZUNvdW50LCBsb25nIG9mZnNldCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBpbnQgcmVhZChGaWxlRGVzY3JpcHRvciBmZCwgQnl0ZUJ1ZmZlciBidWZmZXIpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgaW50IHJlYWQoRmlsZURlc2NyaXB0b3IgZmQsIGJ5dGVbXSBieXRlcywgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgaW50IHJlYWR2KEZpbGVEZXNjcmlwdG9yIGZkLCBPYmplY3RbXSBidWZmZXJzLCBpbnRbXSBvZmZzZXRzLCBpbnRbXSBieXRlQ291bnRzKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIGludCByZWN2ZnJvbShGaWxlRGVzY3JpcHRvciBmZCwgQnl0ZUJ1ZmZlciBidWZmZXIsIGludCBmbGFncywgSW5ldFNvY2tldEFkZHJlc3Mgc3JjQWRkcmVzcykgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBpbnQgcmVjdmZyb20oRmlsZURlc2NyaXB0b3IgZmQsIGJ5dGVbXSBieXRlcywgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQsIGludCBmbGFncywgSW5ldFNvY2tldEFkZHJlc3Mgc3JjQWRkcmVzcykgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyB2b2lkIHJlbW92ZShTdHJpbmcgcGF0aCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyB2b2lkIHJlbmFtZShTdHJpbmcgb2xkUGF0aCwgU3RyaW5nIG5ld1BhdGgpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgaW50IHNlbmR0byhGaWxlRGVzY3JpcHRvciBmZCwgQnl0ZUJ1ZmZlciBidWZmZXIsIGludCBmbGFncywgSW5ldEFkZHJlc3MgaW5ldEFkZHJlc3MsIGludCBwb3J0KSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIGludCBzZW5kdG8oRmlsZURlc2NyaXB0b3IgZmQsIGJ5dGVbXSBieXRlcywgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQsIGludCBmbGFncywgSW5ldEFkZHJlc3MgaW5ldEFkZHJlc3MsIGludCBwb3J0KSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIGxvbmcgc2VuZGZpbGUoRmlsZURlc2NyaXB0b3Igb3V0RmQsIEZpbGVEZXNjcmlwdG9yIGluRmQsIE11dGFibGVMb25nIGluT2Zmc2V0LCBsb25nIGJ5dGVDb3VudCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyB2b2lkIHNldGVnaWQoaW50IGVnaWQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBzZXRldWlkKGludCBldWlkKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIHZvaWQgc2V0Z2lkKGludCBnaWQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBzZXRzb2Nrb3B0Qnl0ZShGaWxlRGVzY3JpcHRvciBmZCwgaW50IGxldmVsLCBpbnQgb3B0aW9uLCBpbnQgdmFsdWUpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBzZXRzb2Nrb3B0SWZyZXEoRmlsZURlc2NyaXB0b3IgZmQsIGludCBsZXZlbCwgaW50IG9wdGlvbiwgU3RyaW5nIHZhbHVlKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIHZvaWQgc2V0c29ja29wdEludChGaWxlRGVzY3JpcHRvciBmZCwgaW50IGxldmVsLCBpbnQgb3B0aW9uLCBpbnQgdmFsdWUpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBzZXRzb2Nrb3B0SXBNcmVxbihGaWxlRGVzY3JpcHRvciBmZCwgaW50IGxldmVsLCBpbnQgb3B0aW9uLCBpbnQgdmFsdWUpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBzZXRzb2Nrb3B0R3JvdXBSZXEoRmlsZURlc2NyaXB0b3IgZmQsIGludCBsZXZlbCwgaW50IG9wdGlvbiwgU3RydWN0R3JvdXBSZXEgdmFsdWUpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBzZXRzb2Nrb3B0TGluZ2VyKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgbGV2ZWwsIGludCBvcHRpb24sIFN0cnVjdExpbmdlciB2YWx1ZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyB2b2lkIHNldHNvY2tvcHRUaW1ldmFsKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgbGV2ZWwsIGludCBvcHRpb24sIFN0cnVjdFRpbWV2YWwgdmFsdWUpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgdm9pZCBzZXR1aWQoaW50IHVpZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyB2b2lkIHNodXRkb3duKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgaG93KSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIEZpbGVEZXNjcmlwdG9yIHNvY2tldChpbnQgZG9tYWluLCBpbnQgdHlwZSwgaW50IHByb3RvY29sKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIFN0cnVjdFN0YXQgc3RhdChTdHJpbmcgcGF0aCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIC8qIFRPRE86IHJlcGxhY2Ugc3RhdGZzIHdpdGggc3RhdHZmcy4gKi8KKyAgICBwdWJsaWMgU3RydWN0U3RhdEZzIHN0YXRmcyhTdHJpbmcgcGF0aCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBTdHJpbmcgc3RyZXJyb3IoaW50IGVycm5vKTsKKyAgICBwdWJsaWMgdm9pZCBzeW1saW5rKFN0cmluZyBvbGRQYXRoLCBTdHJpbmcgbmV3UGF0aCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBsb25nIHN5c2NvbmYoaW50IG5hbWUpOworICAgIHB1YmxpYyBTdHJ1Y3RVdHNuYW1lIHVuYW1lKCk7CisgICAgcHVibGljIGludCB3YWl0cGlkKGludCBwaWQsIE11dGFibGVJbnQgc3RhdHVzLCBpbnQgb3B0aW9ucykgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBpbnQgd3JpdGUoRmlsZURlc2NyaXB0b3IgZmQsIEJ5dGVCdWZmZXIgYnVmZmVyKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIGludCB3cml0ZShGaWxlRGVzY3JpcHRvciBmZCwgYnl0ZVtdIGJ5dGVzLCBpbnQgYnl0ZU9mZnNldCwgaW50IGJ5dGVDb3VudCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBpbnQgd3JpdGV2KEZpbGVEZXNjcmlwdG9yIGZkLCBPYmplY3RbXSBidWZmZXJzLCBpbnRbXSBvZmZzZXRzLCBpbnRbXSBieXRlQ291bnRzKSB0aHJvd3MgRXJybm9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9Pc0NvbnN0YW50cy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vT3NDb25zdGFudHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42OGExNjVjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vT3NDb25zdGFudHMuamF2YQpAQCAtMCwwICsxLDcyNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pbzsKKworcHVibGljIGZpbmFsIGNsYXNzIE9zQ29uc3RhbnRzIHsKKyAgICBwcml2YXRlIE9zQ29uc3RhbnRzKCkgeyB9CisKKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gU19JU0JMSyhpbnQgbW9kZSkgeyByZXR1cm4gKG1vZGUgJiBTX0lGTVQpID09IFNfSUZCTEs7IH0KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gU19JU0NIUihpbnQgbW9kZSkgeyByZXR1cm4gKG1vZGUgJiBTX0lGTVQpID09IFNfSUZDSFI7IH0KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gU19JU0RJUihpbnQgbW9kZSkgeyByZXR1cm4gKG1vZGUgJiBTX0lGTVQpID09IFNfSUZESVI7IH0KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gU19JU0ZJRk8oaW50IG1vZGUpIHsgcmV0dXJuIChtb2RlICYgU19JRk1UKSA9PSBTX0lGSUZPOyB9CisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIFNfSVNSRUcoaW50IG1vZGUpIHsgcmV0dXJuIChtb2RlICYgU19JRk1UKSA9PSBTX0lGUkVHOyB9CisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIFNfSVNMTksoaW50IG1vZGUpIHsgcmV0dXJuIChtb2RlICYgU19JRk1UKSA9PSBTX0lGTE5LOyB9CisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIFNfSVNTT0NLKGludCBtb2RlKSB7IHJldHVybiAobW9kZSAmIFNfSUZNVCkgPT0gU19JRlNPQ0s7IH0KKworICAgIHB1YmxpYyBzdGF0aWMgaW50IFdFWElUU1RBVFVTKGludCBzdGF0dXMpIHsgcmV0dXJuIChzdGF0dXMgJiAweGZmMDApID4+IDg7IH0KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gV0NPUkVEVU1QKGludCBzdGF0dXMpIHsgcmV0dXJuIChzdGF0dXMgJiAweDgwKSAhPSAwOyB9CisgICAgcHVibGljIHN0YXRpYyBpbnQgV1RFUk1TSUcoaW50IHN0YXR1cykgeyByZXR1cm4gc3RhdHVzICYgMHg3ZjsgfQorICAgIHB1YmxpYyBzdGF0aWMgaW50IFdTVE9QU0lHKGludCBzdGF0dXMpIHsgcmV0dXJuIFdFWElUU1RBVFVTKHN0YXR1cyk7IH0KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gV0lGRVhJVEVEKGludCBzdGF0dXMpIHsgcmV0dXJuIChXVEVSTVNJRyhzdGF0dXMpID09IDApOyB9CisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIFdJRlNUT1BQRUQoaW50IHN0YXR1cykgeyByZXR1cm4gKFdURVJNU0lHKHN0YXR1cykgPT0gMHg3Zik7IH0KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gV0lGU0lHTkFMRUQoaW50IHN0YXR1cykgeyByZXR1cm4gKFdURVJNU0lHKHN0YXR1cyArIDEpID49IDIpOyB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBRl9JTkVUID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBRl9JTkVUNiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUZfVU5JWCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUZfVU5TUEVDID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBSV9BRERSQ09ORklHID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBSV9BTEwgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFJX0NBTk9OTkFNRSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUlfTlVNRVJJQ0hPU1QgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFJX05VTUVSSUNTRVJWID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBSV9QQVNTSVZFID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBSV9WNE1BUFBFRCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRTJCSUcgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVBQ0NFUyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUFERFJJTlVTRSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUFERFJOT1RBVkFJTCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUFGTk9TVVBQT1JUID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFQUdBSU4gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVBSV9BR0FJTiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUFJX0JBREZMQUdTID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFQUlfRkFJTCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUFJX0ZBTUlMWSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUFJX01FTU9SWSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUFJX05PREFUQSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUFJX05PTkFNRSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUFJX09WRVJGTE9XID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFQUlfU0VSVklDRSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUFJX1NPQ0tUWVBFID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFQUlfU1lTVEVNID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFQUxSRUFEWSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUJBREYgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVCQURNU0cgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVCVVNZID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFQ0FOQ0VMRUQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVDSElMRCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUNPTk5BQk9SVEVEID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFQ09OTlJFRlVTRUQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVDT05OUkVTRVQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVERUFETEsgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVERVNUQUREUlJFUSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRURPTSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRURRVU9UID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFRVhJU1QgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVGQVVMVCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUZCSUcgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVIT1NUVU5SRUFDSCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUlEUk0gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVJTFNFUSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUlOUFJPR1JFU1MgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVJTlRSID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFSU5WQUwgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVJTyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUlTQ09OTiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUlTRElSID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTE9PUCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU1GSUxFID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTUxJTksgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVNU0dTSVpFID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTVVMVElIT1AgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOQU1FVE9PTE9ORyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5FVERPV04gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVORVRSRVNFVCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5FVFVOUkVBQ0ggPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVORklMRSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5PQlVGUyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5PREFUQSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5PREVWID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTk9FTlQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOT0VYRUMgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOT0xDSyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5PTElOSyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5PTUVNID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTk9NU0cgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOT1BST1RPT1BUID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTk9TUEMgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOT1NSID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTk9TVFIgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOT1NZUyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5PVENPTk4gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOT1RESVIgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOT1RFTVBUWSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5PVFNPQ0sgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOT1RTVVAgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOT1RUWSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5YSU8gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVPUE5PVFNVUFAgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVPVkVSRkxPVyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVBFUk0gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVQSVBFID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUFJPVE8gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVQUk9UT05PU1VQUE9SVCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVBST1RPVFlQRSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJBTkdFID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUk9GUyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVNQSVBFID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFU1JDSCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVNUQUxFID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFVElNRSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVRJTUVET1VUID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFVFhUQlNZID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFV09VTERCTE9DSyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVhERVYgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVYSVRfRkFJTFVSRSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVhJVF9TVUNDRVNTID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGRF9DTE9FWEVDID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSU9OUkVBRCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRl9EVVBGRCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRl9HRVRGRCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRl9HRVRGTCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRl9HRVRMSyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRl9HRVRMSzY0ID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGX0dFVE9XTiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRl9PSyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRl9SRExDSyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRl9TRVRGRCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRl9TRVRGTCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRl9TRVRMSyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRl9TRVRMSzY0ID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGX1NFVExLVyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRl9TRVRMS1c2NCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRl9TRVRPV04gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZfVU5MQ0sgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZfV1JMQ0sgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElGRl9BTExNVUxUSSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSUZGX0FVVE9NRURJQSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSUZGX0JST0FEQ0FTVCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSUZGX0RFQlVHID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJRkZfRFlOQU1JQyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSUZGX0xPT1BCQUNLID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJRkZfTUFTVEVSID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJRkZfTVVMVElDQVNUID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJRkZfTk9BUlAgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElGRl9OT1RSQUlMRVJTID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJRkZfUE9JTlRPUE9JTlQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElGRl9QT1JUU0VMID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJRkZfUFJPTUlTQyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSUZGX1JVTk5JTkcgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElGRl9TTEFWRSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSUZGX1VQID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJUFBST1RPX0lDTVAgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElQUFJPVE9fSVAgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElQUFJPVE9fSVBWNiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSVBQUk9UT19SQVcgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElQUFJPVE9fVENQID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJUFBST1RPX1VEUCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSVBWNl9DSEVDS1NVTSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSVBWNl9NVUxUSUNBU1RfSE9QUyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSVBWNl9NVUxUSUNBU1RfSUYgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElQVjZfTVVMVElDQVNUX0xPT1AgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElQVjZfUkVDVkRTVE9QVFMgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElQVjZfUkVDVkhPUExJTUlUID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJUFY2X1JFQ1ZIT1BPUFRTID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJUFY2X1JFQ1ZQS1RJTkZPID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJUFY2X1JFQ1ZSVEhEUiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSVBWNl9SRUNWVENMQVNTID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJUFY2X1RDTEFTUyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSVBWNl9VTklDQVNUX0hPUFMgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElQVjZfVjZPTkxZID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJUF9NVUxUSUNBU1RfSUYgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElQX01VTFRJQ0FTVF9MT09QID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJUF9NVUxUSUNBU1RfVFRMID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJUF9UT1MgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElQX1RUTCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX0ZJWEVEID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVBfUFJJVkFURSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX1NIQVJFRCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUNBU1RfSk9JTl9HUk9VUCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUNBU1RfTEVBVkVfR1JPVVAgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1DTF9DVVJSRU5UID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQ0xfRlVUVVJFID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNU0dfQ1RSVU5DID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNU0dfRE9OVFJPVVRFID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNU0dfRU9SID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNU0dfT09CID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNU0dfUEVFSyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTVNHX1RSVU5DID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNU0dfV0FJVEFMTCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTVNfQVNZTkMgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1TX0lOVkFMSURBVEUgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1TX1NZTkMgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5JX0RHUkFNID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOSV9OQU1FUkVRRCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTklfTk9GUUROID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOSV9OVU1FUklDSE9TVCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTklfTlVNRVJJQ1NFUlYgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9fQUNDTU9ERSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT19BUFBFTkQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9fQ1JFQVQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9fRVhDTCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT19OT0NUVFkgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9fTk9OQkxPQ0sgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9fUkRPTkxZID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPX1JEV1IgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9fU1lOQyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT19UUlVOQyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT19XUk9OTFkgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBPTExFUlIgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBPTExIVVAgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBPTExJTiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUE9MTE5WQUwgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBPTExPVVQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBPTExQUkkgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBPTExSREJBTkQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBPTExSRE5PUk0gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBPTExXUkJBTkQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBPTExXUk5PUk0gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBST1RfRVhFQyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJPVF9OT05FID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUk9UX1JFQUQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBST1RfV1JJVEUgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJfT0sgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFRUtfQ1VSID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRUVLX0VORCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VFS19TRVQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIVVRfUkQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIVVRfUkRXUiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hVVF9XUiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lHQUJSVCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lHQUxSTSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lHQlVTID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSUdDSExEID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSUdDT05UID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSUdGUEUgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJR0hVUCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lHSUxMID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSUdJTlQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJR0lPID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSUdLSUxMID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSUdQSVBFID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSUdQUk9GID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSUdQV1IgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJR1FVSVQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJR1JUTUFYID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSUdSVE1JTiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lHU0VHViA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lHU1RLRkxUID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSUdTVE9QID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSUdTWVMgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJR1RFUk0gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJR1RSQVAgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJR1RTVFAgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJR1RUSU4gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJR1RUT1UgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJR1VSRyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lHVVNSMSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lHVVNSMiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lHVlRBTFJNID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSUdXSU5DSCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lHWENQVSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lHWEZTWiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lPQ0dJRkFERFIgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJT0NHSUZCUkRBRERSID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSU9DR0lGRFNUQUREUiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lPQ0dJRk5FVE1BU0sgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNPQ0tfREdSQU0gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNPQ0tfUkFXID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT0NLX1NFUVBBQ0tFVCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09DS19TVFJFQU0gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNPTF9TT0NLRVQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNPX0JJTkRUT0RFVklDRSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fQlJPQURDQVNUID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT19ERUJVRyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fRE9OVFJPVVRFID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT19FUlJPUiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fS0VFUEFMSVZFID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT19MSU5HRVIgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNPX09PQklOTElORSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fUkNWQlVGID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT19SQ1ZMT1dBVCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fUkNWVElNRU8gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNPX1JFVVNFQUREUiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fU05EQlVGID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT19TTkRMT1dBVCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fU05EVElNRU8gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNPX1RZUEUgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUREVSUl9GSUxFTk8gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNURElOX0ZJTEVOTyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RET1VUX0ZJTEVOTyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JRkJMSyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JRkNIUiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JRkRJUiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JRklGTyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JRkxOSyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JRk1UID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTX0lGUkVHID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTX0lGU09DSyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JUkdSUCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JUk9USCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JUlVTUiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JUldYRyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JUldYTyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JUldYVSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JU0dJRCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JU1VJRCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JU1ZUWCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JV0dSUCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JV09USCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JV1VTUiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JWEdSUCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JWE9USCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19JWFVTUiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVENQX05PREVMQVkgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdDT05USU5VRUQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdFWElURUQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdOT0hBTkcgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdOT1dBSVQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdTVE9QUEVEID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXVU5UUkFDRUQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdfT0sgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFhfT0sgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ18yX0NIQVJfVEVSTSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDXzJfQ19CSU5EID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfMl9DX0RFViA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDXzJfQ19WRVJTSU9OID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfMl9GT1JUX0RFViA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDXzJfRk9SVF9SVU4gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ18yX0xPQ0FMRURFRiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDXzJfU1dfREVWID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfMl9VUEUgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ18yX1ZFUlNJT04gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19BSU9fTElTVElPX01BWCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX0FJT19NQVggPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19BSU9fUFJJT19ERUxUQV9NQVggPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19BUkdfTUFYID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfQVNZTkNIUk9OT1VTX0lPID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfQVRFWElUX01BWCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX0FWUEhZU19QQUdFUyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX0JDX0JBU0VfTUFYID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfQkNfRElNX01BWCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX0JDX1NDQUxFX01BWCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX0JDX1NUUklOR19NQVggPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19DSElMRF9NQVggPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19DTEtfVENLID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfQ09MTF9XRUlHSFRTX01BWCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX0RFTEFZVElNRVJfTUFYID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfRVhQUl9ORVNUX01BWCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX0ZTWU5DID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfR0VUR1JfUl9TSVpFX01BWCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX0dFVFBXX1JfU0laRV9NQVggPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19JT1ZfTUFYID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfSk9CX0NPTlRST0wgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19MSU5FX01BWCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX0xPR0lOX05BTUVfTUFYID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfTUFQUEVEX0ZJTEVTID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfTUVNTE9DSyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX01FTUxPQ0tfUkFOR0UgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19NRU1PUllfUFJPVEVDVElPTiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX01FU1NBR0VfUEFTU0lORyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX01RX09QRU5fTUFYID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfTVFfUFJJT19NQVggPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19OR1JPVVBTX01BWCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX05QUk9DRVNTT1JTX0NPTkYgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19OUFJPQ0VTU09SU19PTkxOID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfT1BFTl9NQVggPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19QQUdFU0laRSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1BBR0VfU0laRSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1BBU1NfTUFYID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfUEhZU19QQUdFUyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1BSSU9SSVRJWkVEX0lPID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfUFJJT1JJVFlfU0NIRURVTElORyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1JFQUxUSU1FX1NJR05BTFMgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19SRV9EVVBfTUFYID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfUlRTSUdfTUFYID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfU0FWRURfSURTID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfU0VNQVBIT1JFUyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1NFTV9OU0VNU19NQVggPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19TRU1fVkFMVUVfTUFYID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfU0hBUkVEX01FTU9SWV9PQkpFQ1RTID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfU0lHUVVFVUVfTUFYID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfU1RSRUFNX01BWCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1NZTkNIUk9OSVpFRF9JTyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1RIUkVBRFMgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19USFJFQURfQVRUUl9TVEFDS0FERFIgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19USFJFQURfQVRUUl9TVEFDS1NJWkUgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19USFJFQURfREVTVFJVQ1RPUl9JVEVSQVRJT05TID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfVEhSRUFEX0tFWVNfTUFYID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfVEhSRUFEX1BSSU9SSVRZX1NDSEVEVUxJTkcgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19USFJFQURfUFJJT19JTkhFUklUID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfVEhSRUFEX1BSSU9fUFJPVEVDVCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1RIUkVBRF9TQUZFX0ZVTkNUSU9OUyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1RIUkVBRF9TVEFDS19NSU4gPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19USFJFQURfVEhSRUFEU19NQVggPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19USU1FUlMgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19USU1FUl9NQVggPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19UVFlfTkFNRV9NQVggPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19UWk5BTUVfTUFYID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfVkVSU0lPTiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1hCUzVfSUxQMzJfT0ZGMzIgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19YQlM1X0lMUDMyX09GRkJJRyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1hCUzVfTFA2NF9PRkY2NCA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1hCUzVfTFBCSUdfT0ZGQklHID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfWE9QRU5fQ1JZUFQgPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19YT1BFTl9FTkhfSTE4TiA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1hPUEVOX0xFR0FDWSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1hPUEVOX1JFQUxUSU1FID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfWE9QRU5fUkVBTFRJTUVfVEhSRUFEUyA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1hPUEVOX1NITSA9IHBsYWNlaG9sZGVyKCk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NDX1hPUEVOX1VOSVggPSBwbGFjZWhvbGRlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9TQ19YT1BFTl9WRVJTSU9OID0gcGxhY2Vob2xkZXIoKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfU0NfWE9QRU5fWENVX1ZFUlNJT04gPSBwbGFjZWhvbGRlcigpOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2FpTmFtZShpbnQgZXJyb3IpIHsKKyAgICAgICAgaWYgKGVycm9yID09IEVBSV9BR0FJTikgeworICAgICAgICAgICAgcmV0dXJuICJFQUlfQUdBSU4iOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJvciA9PSBFQUlfQkFERkxBR1MpIHsKKyAgICAgICAgICAgIHJldHVybiAiRUFJX0JBREZMQUdTIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJyb3IgPT0gRUFJX0ZBSUwpIHsKKyAgICAgICAgICAgIHJldHVybiAiRUFJX0ZBSUwiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJvciA9PSBFQUlfRkFNSUxZKSB7CisgICAgICAgICAgICByZXR1cm4gIkVBSV9GQU1JTFkiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJvciA9PSBFQUlfTUVNT1JZKSB7CisgICAgICAgICAgICByZXR1cm4gIkVBSV9NRU1PUlkiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJvciA9PSBFQUlfTk9EQVRBKSB7CisgICAgICAgICAgICByZXR1cm4gIkVBSV9OT0RBVEEiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJvciA9PSBFQUlfTk9OQU1FKSB7CisgICAgICAgICAgICByZXR1cm4gIkVBSV9OT05BTUUiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJvciA9PSBFQUlfT1ZFUkZMT1cpIHsKKyAgICAgICAgICAgIHJldHVybiAiRUFJX09WRVJGTE9XIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJyb3IgPT0gRUFJX1NFUlZJQ0UpIHsKKyAgICAgICAgICAgIHJldHVybiAiRUFJX1NFUlZJQ0UiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJvciA9PSBFQUlfU09DS1RZUEUpIHsKKyAgICAgICAgICAgIHJldHVybiAiRUFJX1NPQ0tUWVBFIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJyb3IgPT0gRUFJX1NZU1RFTSkgeworICAgICAgICAgICAgcmV0dXJuICJFQUlfU1lTVEVNIjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBlcnJub05hbWUoaW50IGVycm5vKSB7CisgICAgICAgIGlmIChlcnJubyA9PSBFMkJJRykgeworICAgICAgICAgICAgcmV0dXJuICJFMkJJRyI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVBQ0NFUykgeworICAgICAgICAgICAgcmV0dXJuICJFQUNDRVMiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFQUREUklOVVNFKSB7CisgICAgICAgICAgICByZXR1cm4gIkVBRERSSU5VU0UiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFQUREUk5PVEFWQUlMKSB7CisgICAgICAgICAgICByZXR1cm4gIkVBRERSTk9UQVZBSUwiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFQUZOT1NVUFBPUlQpIHsKKyAgICAgICAgICAgIHJldHVybiAiRUFGTk9TVVBQT1JUIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRUFHQUlOKSB7CisgICAgICAgICAgICByZXR1cm4gIkVBR0FJTiI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVBTFJFQURZKSB7CisgICAgICAgICAgICByZXR1cm4gIkVBTFJFQURZIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRUJBREYpIHsKKyAgICAgICAgICAgIHJldHVybiAiRUJBREYiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFQkFETVNHKSB7CisgICAgICAgICAgICByZXR1cm4gIkVCQURNU0ciOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFQlVTWSkgeworICAgICAgICAgICAgcmV0dXJuICJFQlVTWSI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVDQU5DRUxFRCkgeworICAgICAgICAgICAgcmV0dXJuICJFQ0FOQ0VMRUQiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFQ0hJTEQpIHsKKyAgICAgICAgICAgIHJldHVybiAiRUNISUxEIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRUNPTk5BQk9SVEVEKSB7CisgICAgICAgICAgICByZXR1cm4gIkVDT05OQUJPUlRFRCI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVDT05OUkVGVVNFRCkgeworICAgICAgICAgICAgcmV0dXJuICJFQ09OTlJFRlVTRUQiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFQ09OTlJFU0VUKSB7CisgICAgICAgICAgICByZXR1cm4gIkVDT05OUkVTRVQiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFREVBRExLKSB7CisgICAgICAgICAgICByZXR1cm4gIkVERUFETEsiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFREVTVEFERFJSRVEpIHsKKyAgICAgICAgICAgIHJldHVybiAiRURFU1RBRERSUkVRIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRURPTSkgeworICAgICAgICAgICAgcmV0dXJuICJFRE9NIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRURRVU9UKSB7CisgICAgICAgICAgICByZXR1cm4gIkVEUVVPVCI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVFWElTVCkgeworICAgICAgICAgICAgcmV0dXJuICJFRVhJU1QiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFRkFVTFQpIHsKKyAgICAgICAgICAgIHJldHVybiAiRUZBVUxUIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRUZCSUcpIHsKKyAgICAgICAgICAgIHJldHVybiAiRUZCSUciOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFSE9TVFVOUkVBQ0gpIHsKKyAgICAgICAgICAgIHJldHVybiAiRUhPU1RVTlJFQUNIIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRUlEUk0pIHsKKyAgICAgICAgICAgIHJldHVybiAiRUlEUk0iOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFSUxTRVEpIHsKKyAgICAgICAgICAgIHJldHVybiAiRUlMU0VRIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRUlOUFJPR1JFU1MpIHsKKyAgICAgICAgICAgIHJldHVybiAiRUlOUFJPR1JFU1MiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFSU5UUikgeworICAgICAgICAgICAgcmV0dXJuICJFSU5UUiI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVJTlZBTCkgeworICAgICAgICAgICAgcmV0dXJuICJFSU5WQUwiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFSU8pIHsKKyAgICAgICAgICAgIHJldHVybiAiRUlPIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRUlTQ09OTikgeworICAgICAgICAgICAgcmV0dXJuICJFSVNDT05OIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRUlTRElSKSB7CisgICAgICAgICAgICByZXR1cm4gIkVJU0RJUiI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVMT09QKSB7CisgICAgICAgICAgICByZXR1cm4gIkVMT09QIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRU1GSUxFKSB7CisgICAgICAgICAgICByZXR1cm4gIkVNRklMRSI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVNTElOSykgeworICAgICAgICAgICAgcmV0dXJuICJFTUxJTksiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFTVNHU0laRSkgeworICAgICAgICAgICAgcmV0dXJuICJFTVNHU0laRSI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVNVUxUSUhPUCkgeworICAgICAgICAgICAgcmV0dXJuICJFTVVMVElIT1AiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFTkFNRVRPT0xPTkcpIHsKKyAgICAgICAgICAgIHJldHVybiAiRU5BTUVUT09MT05HIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRU5FVERPV04pIHsKKyAgICAgICAgICAgIHJldHVybiAiRU5FVERPV04iOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFTkVUUkVTRVQpIHsKKyAgICAgICAgICAgIHJldHVybiAiRU5FVFJFU0VUIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRU5FVFVOUkVBQ0gpIHsKKyAgICAgICAgICAgIHJldHVybiAiRU5FVFVOUkVBQ0giOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFTkZJTEUpIHsKKyAgICAgICAgICAgIHJldHVybiAiRU5GSUxFIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRU5PQlVGUykgeworICAgICAgICAgICAgcmV0dXJuICJFTk9CVUZTIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRU5PREFUQSkgeworICAgICAgICAgICAgcmV0dXJuICJFTk9EQVRBIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRU5PREVWKSB7CisgICAgICAgICAgICByZXR1cm4gIkVOT0RFViI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVOT0VOVCkgeworICAgICAgICAgICAgcmV0dXJuICJFTk9FTlQiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFTk9FWEVDKSB7CisgICAgICAgICAgICByZXR1cm4gIkVOT0VYRUMiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFTk9MQ0spIHsKKyAgICAgICAgICAgIHJldHVybiAiRU5PTENLIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRU5PTElOSykgeworICAgICAgICAgICAgcmV0dXJuICJFTk9MSU5LIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRU5PTUVNKSB7CisgICAgICAgICAgICByZXR1cm4gIkVOT01FTSI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVOT01TRykgeworICAgICAgICAgICAgcmV0dXJuICJFTk9NU0ciOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFTk9QUk9UT09QVCkgeworICAgICAgICAgICAgcmV0dXJuICJFTk9QUk9UT09QVCI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVOT1NQQykgeworICAgICAgICAgICAgcmV0dXJuICJFTk9TUEMiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFTk9TUikgeworICAgICAgICAgICAgcmV0dXJuICJFTk9TUiI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVOT1NUUikgeworICAgICAgICAgICAgcmV0dXJuICJFTk9TVFIiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFTk9TWVMpIHsKKyAgICAgICAgICAgIHJldHVybiAiRU5PU1lTIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRU5PVENPTk4pIHsKKyAgICAgICAgICAgIHJldHVybiAiRU5PVENPTk4iOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFTk9URElSKSB7CisgICAgICAgICAgICByZXR1cm4gIkVOT1RESVIiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFTk9URU1QVFkpIHsKKyAgICAgICAgICAgIHJldHVybiAiRU5PVEVNUFRZIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRU5PVFNPQ0spIHsKKyAgICAgICAgICAgIHJldHVybiAiRU5PVFNPQ0siOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFTk9UU1VQKSB7CisgICAgICAgICAgICByZXR1cm4gIkVOT1RTVVAiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFTk9UVFkpIHsKKyAgICAgICAgICAgIHJldHVybiAiRU5PVFRZIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRU5YSU8pIHsKKyAgICAgICAgICAgIHJldHVybiAiRU5YSU8iOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFT1BOT1RTVVBQKSB7CisgICAgICAgICAgICByZXR1cm4gIkVPUE5PVFNVUFAiOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFT1ZFUkZMT1cpIHsKKyAgICAgICAgICAgIHJldHVybiAiRU9WRVJGTE9XIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRVBFUk0pIHsKKyAgICAgICAgICAgIHJldHVybiAiRVBFUk0iOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFUElQRSkgeworICAgICAgICAgICAgcmV0dXJuICJFUElQRSI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVQUk9UTykgeworICAgICAgICAgICAgcmV0dXJuICJFUFJPVE8iOworICAgICAgICB9CisgICAgICAgIGlmIChlcnJubyA9PSBFUFJPVE9OT1NVUFBPUlQpIHsKKyAgICAgICAgICAgIHJldHVybiAiRVBST1RPTk9TVVBQT1JUIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRVBST1RPVFlQRSkgeworICAgICAgICAgICAgcmV0dXJuICJFUFJPVE9UWVBFIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRVJBTkdFKSB7CisgICAgICAgICAgICByZXR1cm4gIkVSQU5HRSI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVST0ZTKSB7CisgICAgICAgICAgICByZXR1cm4gIkVST0ZTIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRVNQSVBFKSB7CisgICAgICAgICAgICByZXR1cm4gIkVTUElQRSI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVTUkNIKSB7CisgICAgICAgICAgICByZXR1cm4gIkVTUkNIIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRVNUQUxFKSB7CisgICAgICAgICAgICByZXR1cm4gIkVTVEFMRSI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVUSU1FKSB7CisgICAgICAgICAgICByZXR1cm4gIkVUSU1FIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRVRJTUVET1VUKSB7CisgICAgICAgICAgICByZXR1cm4gIkVUSU1FRE9VVCI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVUWFRCU1kpIHsKKyAgICAgICAgICAgIHJldHVybiAiRVRYVEJTWSI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm5vID09IEVXT1VMREJMT0NLKSB7CisgICAgICAgICAgICByZXR1cm4gIkVXT1VMREJMT0NLIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJybm8gPT0gRVhERVYpIHsKKyAgICAgICAgICAgIHJldHVybiAiRVhERVYiOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIGluaXRDb25zdGFudHMoKTsKKworICAgIC8vIEEgaGFjayB0byBhdm9pZCB0aGVzZSBjb25zdGFudHMgYmVpbmcgaW5saW5lZCBieSBqYXZhYy4uLgorICAgIHByaXZhdGUgc3RhdGljIGludCBwbGFjZWhvbGRlcigpIHsgcmV0dXJuIDA7IH0KKyAgICAvLyAuLi5iZWNhdXNlIHdlIHdhbnQgdG8gaW5pdGlhbGl6ZSB0aGVtIGF0IHJ1bnRpbWUuCisgICAgc3RhdGljIHsKKyAgICAgICAgaW5pdENvbnN0YW50cygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL1Bvc2l4LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9Qb3NpeC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdiYmY0OWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9Qb3NpeC5qYXZhCkBAIC0wLDAgKzEsMTgyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmlvOworCitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0U29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uTmlvVXRpbHM7CitpbXBvcnQgbGliY29yZS51dGlsLk11dGFibGVJbnQ7CitpbXBvcnQgbGliY29yZS51dGlsLk11dGFibGVMb25nOworCitwdWJsaWMgZmluYWwgY2xhc3MgUG9zaXggaW1wbGVtZW50cyBPcyB7CisgICAgUG9zaXgoKSB7IH0KKworICAgIHB1YmxpYyBuYXRpdmUgRmlsZURlc2NyaXB0b3IgYWNjZXB0KEZpbGVEZXNjcmlwdG9yIGZkLCBJbmV0U29ja2V0QWRkcmVzcyBwZWVyQWRkcmVzcykgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgYm9vbGVhbiBhY2Nlc3MoU3RyaW5nIHBhdGgsIGludCBtb2RlKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSB2b2lkIGJpbmQoRmlsZURlc2NyaXB0b3IgZmQsIEluZXRBZGRyZXNzIGFkZHJlc3MsIGludCBwb3J0KSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSB2b2lkIGNobW9kKFN0cmluZyBwYXRoLCBpbnQgbW9kZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCBjbG9zZShGaWxlRGVzY3JpcHRvciBmZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCBjb25uZWN0KEZpbGVEZXNjcmlwdG9yIGZkLCBJbmV0QWRkcmVzcyBhZGRyZXNzLCBpbnQgcG9ydCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgRmlsZURlc2NyaXB0b3IgZHVwKEZpbGVEZXNjcmlwdG9yIG9sZEZkKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSBGaWxlRGVzY3JpcHRvciBkdXAyKEZpbGVEZXNjcmlwdG9yIG9sZEZkLCBpbnQgbmV3RmQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgbmF0aXZlIFN0cmluZ1tdIGVudmlyb24oKTsKKyAgICBwdWJsaWMgbmF0aXZlIGludCBmY250bFZvaWQoRmlsZURlc2NyaXB0b3IgZmQsIGludCBjbWQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgbmF0aXZlIGludCBmY250bExvbmcoRmlsZURlc2NyaXB0b3IgZmQsIGludCBjbWQsIGxvbmcgYXJnKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSBpbnQgZmNudGxGbG9jayhGaWxlRGVzY3JpcHRvciBmZCwgaW50IGNtZCwgU3RydWN0RmxvY2sgYXJnKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSB2b2lkIGZkYXRhc3luYyhGaWxlRGVzY3JpcHRvciBmZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgU3RydWN0U3RhdCBmc3RhdChGaWxlRGVzY3JpcHRvciBmZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgU3RydWN0U3RhdEZzIGZzdGF0ZnMoRmlsZURlc2NyaXB0b3IgZmQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgbmF0aXZlIHZvaWQgZnN5bmMoRmlsZURlc2NyaXB0b3IgZmQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgbmF0aXZlIHZvaWQgZnRydW5jYXRlKEZpbGVEZXNjcmlwdG9yIGZkLCBsb25nIGxlbmd0aCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgU3RyaW5nIGdhaV9zdHJlcnJvcihpbnQgZXJyb3IpOworICAgIHB1YmxpYyBuYXRpdmUgSW5ldEFkZHJlc3NbXSBnZXRhZGRyaW5mbyhTdHJpbmcgbm9kZSwgU3RydWN0QWRkcmluZm8gaGludHMpIHRocm93cyBHYWlFeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSBpbnQgZ2V0ZWdpZCgpOworICAgIHB1YmxpYyBuYXRpdmUgaW50IGdldGV1aWQoKTsKKyAgICBwdWJsaWMgbmF0aXZlIGludCBnZXRnaWQoKTsKKyAgICBwdWJsaWMgbmF0aXZlIFN0cmluZyBnZXRlbnYoU3RyaW5nIG5hbWUpOworICAgIHB1YmxpYyBuYXRpdmUgU3RyaW5nIGdldG5hbWVpbmZvKEluZXRBZGRyZXNzIGFkZHJlc3MsIGludCBmbGFncykgdGhyb3dzIEdhaUV4Y2VwdGlvbjsKKyAgICBwdWJsaWMgbmF0aXZlIGludCBnZXRwaWQoKTsKKyAgICBwdWJsaWMgbmF0aXZlIGludCBnZXRwcGlkKCk7CisgICAgcHVibGljIG5hdGl2ZSBTdHJ1Y3RQYXNzd2QgZ2V0cHduYW0oU3RyaW5nIG5hbWUpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgbmF0aXZlIFN0cnVjdFBhc3N3ZCBnZXRwd3VpZChpbnQgdWlkKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSBTb2NrZXRBZGRyZXNzIGdldHNvY2tuYW1lKEZpbGVEZXNjcmlwdG9yIGZkKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSBpbnQgZ2V0c29ja29wdEJ5dGUoRmlsZURlc2NyaXB0b3IgZmQsIGludCBsZXZlbCwgaW50IG9wdGlvbikgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgSW5ldEFkZHJlc3MgZ2V0c29ja29wdEluQWRkcihGaWxlRGVzY3JpcHRvciBmZCwgaW50IGxldmVsLCBpbnQgb3B0aW9uKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSBpbnQgZ2V0c29ja29wdEludChGaWxlRGVzY3JpcHRvciBmZCwgaW50IGxldmVsLCBpbnQgb3B0aW9uKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSBTdHJ1Y3RMaW5nZXIgZ2V0c29ja29wdExpbmdlcihGaWxlRGVzY3JpcHRvciBmZCwgaW50IGxldmVsLCBpbnQgb3B0aW9uKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSBTdHJ1Y3RUaW1ldmFsIGdldHNvY2tvcHRUaW1ldmFsKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgbGV2ZWwsIGludCBvcHRpb24pIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgbmF0aXZlIGludCBnZXR1aWQoKTsKKyAgICBwdWJsaWMgbmF0aXZlIFN0cmluZyBpZl9pbmRleHRvbmFtZShpbnQgaW5kZXgpOworICAgIHB1YmxpYyBuYXRpdmUgSW5ldEFkZHJlc3MgaW5ldF9wdG9uKGludCBmYW1pbHksIFN0cmluZyBhZGRyZXNzKTsKKyAgICBwdWJsaWMgbmF0aXZlIEluZXRBZGRyZXNzIGlvY3RsSW5ldEFkZHJlc3MoRmlsZURlc2NyaXB0b3IgZmQsIGludCBjbWQsIFN0cmluZyBpbnRlcmZhY2VOYW1lKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSBpbnQgaW9jdGxJbnQoRmlsZURlc2NyaXB0b3IgZmQsIGludCBjbWQsIE11dGFibGVJbnQgYXJnKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSBib29sZWFuIGlzYXR0eShGaWxlRGVzY3JpcHRvciBmZCk7CisgICAgcHVibGljIG5hdGl2ZSB2b2lkIGtpbGwoaW50IHBpZCwgaW50IHNpZ25hbCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCBsaXN0ZW4oRmlsZURlc2NyaXB0b3IgZmQsIGludCBiYWNrbG9nKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSBsb25nIGxzZWVrKEZpbGVEZXNjcmlwdG9yIGZkLCBsb25nIG9mZnNldCwgaW50IHdoZW5jZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgU3RydWN0U3RhdCBsc3RhdChTdHJpbmcgcGF0aCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCBtaW5jb3JlKGxvbmcgYWRkcmVzcywgbG9uZyBieXRlQ291bnQsIGJ5dGVbXSB2ZWN0b3IpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgbmF0aXZlIHZvaWQgbWtkaXIoU3RyaW5nIHBhdGgsIGludCBtb2RlKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSB2b2lkIG1sb2NrKGxvbmcgYWRkcmVzcywgbG9uZyBieXRlQ291bnQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgbmF0aXZlIGxvbmcgbW1hcChsb25nIGFkZHJlc3MsIGxvbmcgYnl0ZUNvdW50LCBpbnQgcHJvdCwgaW50IGZsYWdzLCBGaWxlRGVzY3JpcHRvciBmZCwgbG9uZyBvZmZzZXQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgbmF0aXZlIHZvaWQgbXN5bmMobG9uZyBhZGRyZXNzLCBsb25nIGJ5dGVDb3VudCwgaW50IGZsYWdzKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSB2b2lkIG11bmxvY2sobG9uZyBhZGRyZXNzLCBsb25nIGJ5dGVDb3VudCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCBtdW5tYXAobG9uZyBhZGRyZXNzLCBsb25nIGJ5dGVDb3VudCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgRmlsZURlc2NyaXB0b3Igb3BlbihTdHJpbmcgcGF0aCwgaW50IGZsYWdzLCBpbnQgbW9kZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgRmlsZURlc2NyaXB0b3JbXSBwaXBlKCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgaW50IHBvbGwoU3RydWN0UG9sbGZkW10gZmRzLCBpbnQgdGltZW91dE1zKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIGludCBwcmVhZChGaWxlRGVzY3JpcHRvciBmZCwgQnl0ZUJ1ZmZlciBidWZmZXIsIGxvbmcgb2Zmc2V0KSB0aHJvd3MgRXJybm9FeGNlcHRpb24geworICAgICAgICBpZiAoYnVmZmVyLmlzRGlyZWN0KCkpIHsKKyAgICAgICAgICAgIHJldHVybiBwcmVhZEJ5dGVzKGZkLCBidWZmZXIsIGJ1ZmZlci5wb3NpdGlvbigpLCBidWZmZXIucmVtYWluaW5nKCksIG9mZnNldCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gcHJlYWRCeXRlcyhmZCwgTmlvVXRpbHMudW5zYWZlQXJyYXkoYnVmZmVyKSwgTmlvVXRpbHMudW5zYWZlQXJyYXlPZmZzZXQoYnVmZmVyKSArIGJ1ZmZlci5wb3NpdGlvbigpLCBidWZmZXIucmVtYWluaW5nKCksIG9mZnNldCk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIGludCBwcmVhZChGaWxlRGVzY3JpcHRvciBmZCwgYnl0ZVtdIGJ5dGVzLCBpbnQgYnl0ZU9mZnNldCwgaW50IGJ5dGVDb3VudCwgbG9uZyBvZmZzZXQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRoaXMgaW5kaXJlY3Rpb24gaXNuJ3Qgc3RyaWN0bHkgbmVjZXNzYXJ5LCBidXQgZW5zdXJlcyB0aGF0IG91ciBwdWJsaWMgaW50ZXJmYWNlIGlzIHR5cGUgc2FmZS4KKyAgICAgICAgcmV0dXJuIHByZWFkQnl0ZXMoZmQsIGJ5dGVzLCBieXRlT2Zmc2V0LCBieXRlQ291bnQsIG9mZnNldCk7CisgICAgfQorICAgIHByaXZhdGUgbmF0aXZlIGludCBwcmVhZEJ5dGVzKEZpbGVEZXNjcmlwdG9yIGZkLCBPYmplY3QgYnVmZmVyLCBpbnQgYnVmZmVyT2Zmc2V0LCBpbnQgYnl0ZUNvdW50LCBsb25nIG9mZnNldCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBpbnQgcHdyaXRlKEZpbGVEZXNjcmlwdG9yIGZkLCBCeXRlQnVmZmVyIGJ1ZmZlciwgbG9uZyBvZmZzZXQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChidWZmZXIuaXNEaXJlY3QoKSkgeworICAgICAgICAgICAgcmV0dXJuIHB3cml0ZUJ5dGVzKGZkLCBidWZmZXIsIGJ1ZmZlci5wb3NpdGlvbigpLCBidWZmZXIucmVtYWluaW5nKCksIG9mZnNldCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gcHdyaXRlQnl0ZXMoZmQsIE5pb1V0aWxzLnVuc2FmZUFycmF5KGJ1ZmZlciksIE5pb1V0aWxzLnVuc2FmZUFycmF5T2Zmc2V0KGJ1ZmZlcikgKyBidWZmZXIucG9zaXRpb24oKSwgYnVmZmVyLnJlbWFpbmluZygpLCBvZmZzZXQpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyBpbnQgcHdyaXRlKEZpbGVEZXNjcmlwdG9yIGZkLCBieXRlW10gYnl0ZXMsIGludCBieXRlT2Zmc2V0LCBpbnQgYnl0ZUNvdW50LCBsb25nIG9mZnNldCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGhpcyBpbmRpcmVjdGlvbiBpc24ndCBzdHJpY3RseSBuZWNlc3NhcnksIGJ1dCBlbnN1cmVzIHRoYXQgb3VyIHB1YmxpYyBpbnRlcmZhY2UgaXMgdHlwZSBzYWZlLgorICAgICAgICByZXR1cm4gcHdyaXRlQnl0ZXMoZmQsIGJ5dGVzLCBieXRlT2Zmc2V0LCBieXRlQ291bnQsIG9mZnNldCk7CisgICAgfQorICAgIHByaXZhdGUgbmF0aXZlIGludCBwd3JpdGVCeXRlcyhGaWxlRGVzY3JpcHRvciBmZCwgT2JqZWN0IGJ1ZmZlciwgaW50IGJ1ZmZlck9mZnNldCwgaW50IGJ5dGVDb3VudCwgbG9uZyBvZmZzZXQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgaW50IHJlYWQoRmlsZURlc2NyaXB0b3IgZmQsIEJ5dGVCdWZmZXIgYnVmZmVyKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geworICAgICAgICBpZiAoYnVmZmVyLmlzRGlyZWN0KCkpIHsKKyAgICAgICAgICAgIHJldHVybiByZWFkQnl0ZXMoZmQsIGJ1ZmZlciwgYnVmZmVyLnBvc2l0aW9uKCksIGJ1ZmZlci5yZW1haW5pbmcoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gcmVhZEJ5dGVzKGZkLCBOaW9VdGlscy51bnNhZmVBcnJheShidWZmZXIpLCBOaW9VdGlscy51bnNhZmVBcnJheU9mZnNldChidWZmZXIpICsgYnVmZmVyLnBvc2l0aW9uKCksIGJ1ZmZlci5yZW1haW5pbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIGludCByZWFkKEZpbGVEZXNjcmlwdG9yIGZkLCBieXRlW10gYnl0ZXMsIGludCBieXRlT2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgRXJybm9FeGNlcHRpb24geworICAgICAgICAvLyBUaGlzIGluZGlyZWN0aW9uIGlzbid0IHN0cmljdGx5IG5lY2Vzc2FyeSwgYnV0IGVuc3VyZXMgdGhhdCBvdXIgcHVibGljIGludGVyZmFjZSBpcyB0eXBlIHNhZmUuCisgICAgICAgIHJldHVybiByZWFkQnl0ZXMoZmQsIGJ5dGVzLCBieXRlT2Zmc2V0LCBieXRlQ291bnQpOworICAgIH0KKyAgICBwcml2YXRlIG5hdGl2ZSBpbnQgcmVhZEJ5dGVzKEZpbGVEZXNjcmlwdG9yIGZkLCBPYmplY3QgYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSBpbnQgcmVhZHYoRmlsZURlc2NyaXB0b3IgZmQsIE9iamVjdFtdIGJ1ZmZlcnMsIGludFtdIG9mZnNldHMsIGludFtdIGJ5dGVDb3VudHMpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgaW50IHJlY3Zmcm9tKEZpbGVEZXNjcmlwdG9yIGZkLCBCeXRlQnVmZmVyIGJ1ZmZlciwgaW50IGZsYWdzLCBJbmV0U29ja2V0QWRkcmVzcyBzcmNBZGRyZXNzKSB0aHJvd3MgRXJybm9FeGNlcHRpb24geworICAgICAgICBpZiAoYnVmZmVyLmlzRGlyZWN0KCkpIHsKKyAgICAgICAgICAgIHJldHVybiByZWN2ZnJvbUJ5dGVzKGZkLCBidWZmZXIsIGJ1ZmZlci5wb3NpdGlvbigpLCBidWZmZXIucmVtYWluaW5nKCksIGZsYWdzLCBzcmNBZGRyZXNzKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiByZWN2ZnJvbUJ5dGVzKGZkLCBOaW9VdGlscy51bnNhZmVBcnJheShidWZmZXIpLCBOaW9VdGlscy51bnNhZmVBcnJheU9mZnNldChidWZmZXIpICsgYnVmZmVyLnBvc2l0aW9uKCksIGJ1ZmZlci5yZW1haW5pbmcoKSwgZmxhZ3MsIHNyY0FkZHJlc3MpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyBpbnQgcmVjdmZyb20oRmlsZURlc2NyaXB0b3IgZmQsIGJ5dGVbXSBieXRlcywgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQsIGludCBmbGFncywgSW5ldFNvY2tldEFkZHJlc3Mgc3JjQWRkcmVzcykgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGhpcyBpbmRpcmVjdGlvbiBpc24ndCBzdHJpY3RseSBuZWNlc3NhcnksIGJ1dCBlbnN1cmVzIHRoYXQgb3VyIHB1YmxpYyBpbnRlcmZhY2UgaXMgdHlwZSBzYWZlLgorICAgICAgICByZXR1cm4gcmVjdmZyb21CeXRlcyhmZCwgYnl0ZXMsIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCwgZmxhZ3MsIHNyY0FkZHJlc3MpOworICAgIH0KKyAgICBwcml2YXRlIG5hdGl2ZSBpbnQgcmVjdmZyb21CeXRlcyhGaWxlRGVzY3JpcHRvciBmZCwgT2JqZWN0IGJ1ZmZlciwgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQsIGludCBmbGFncywgSW5ldFNvY2tldEFkZHJlc3Mgc3JjQWRkcmVzcykgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCByZW1vdmUoU3RyaW5nIHBhdGgpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgbmF0aXZlIHZvaWQgcmVuYW1lKFN0cmluZyBvbGRQYXRoLCBTdHJpbmcgbmV3UGF0aCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgbG9uZyBzZW5kZmlsZShGaWxlRGVzY3JpcHRvciBvdXRGZCwgRmlsZURlc2NyaXB0b3IgaW5GZCwgTXV0YWJsZUxvbmcgaW5PZmZzZXQsIGxvbmcgYnl0ZUNvdW50KSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIGludCBzZW5kdG8oRmlsZURlc2NyaXB0b3IgZmQsIEJ5dGVCdWZmZXIgYnVmZmVyLCBpbnQgZmxhZ3MsIEluZXRBZGRyZXNzIGluZXRBZGRyZXNzLCBpbnQgcG9ydCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGJ1ZmZlci5pc0RpcmVjdCgpKSB7CisgICAgICAgICAgICByZXR1cm4gc2VuZHRvQnl0ZXMoZmQsIGJ1ZmZlciwgYnVmZmVyLnBvc2l0aW9uKCksIGJ1ZmZlci5yZW1haW5pbmcoKSwgZmxhZ3MsIGluZXRBZGRyZXNzLCBwb3J0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBzZW5kdG9CeXRlcyhmZCwgTmlvVXRpbHMudW5zYWZlQXJyYXkoYnVmZmVyKSwgTmlvVXRpbHMudW5zYWZlQXJyYXlPZmZzZXQoYnVmZmVyKSArIGJ1ZmZlci5wb3NpdGlvbigpLCBidWZmZXIucmVtYWluaW5nKCksIGZsYWdzLCBpbmV0QWRkcmVzcywgcG9ydCk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIGludCBzZW5kdG8oRmlsZURlc2NyaXB0b3IgZmQsIGJ5dGVbXSBieXRlcywgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQsIGludCBmbGFncywgSW5ldEFkZHJlc3MgaW5ldEFkZHJlc3MsIGludCBwb3J0KSB0aHJvd3MgRXJybm9FeGNlcHRpb24geworICAgICAgICAvLyBUaGlzIGluZGlyZWN0aW9uIGlzbid0IHN0cmljdGx5IG5lY2Vzc2FyeSwgYnV0IGVuc3VyZXMgdGhhdCBvdXIgcHVibGljIGludGVyZmFjZSBpcyB0eXBlIHNhZmUuCisgICAgICAgIHJldHVybiBzZW5kdG9CeXRlcyhmZCwgYnl0ZXMsIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCwgZmxhZ3MsIGluZXRBZGRyZXNzLCBwb3J0KTsKKyAgICB9CisgICAgcHJpdmF0ZSBuYXRpdmUgaW50IHNlbmR0b0J5dGVzKEZpbGVEZXNjcmlwdG9yIGZkLCBPYmplY3QgYnVmZmVyLCBpbnQgYnl0ZU9mZnNldCwgaW50IGJ5dGVDb3VudCwgaW50IGZsYWdzLCBJbmV0QWRkcmVzcyBpbmV0QWRkcmVzcywgaW50IHBvcnQpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgbmF0aXZlIHZvaWQgc2V0ZWdpZChpbnQgZWdpZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCBzZXRldWlkKGludCBldWlkKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSB2b2lkIHNldGdpZChpbnQgZ2lkKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSB2b2lkIHNldHNvY2tvcHRCeXRlKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgbGV2ZWwsIGludCBvcHRpb24sIGludCB2YWx1ZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCBzZXRzb2Nrb3B0SWZyZXEoRmlsZURlc2NyaXB0b3IgZmQsIGludCBsZXZlbCwgaW50IG9wdGlvbiwgU3RyaW5nIHZhbHVlKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSB2b2lkIHNldHNvY2tvcHRJbnQoRmlsZURlc2NyaXB0b3IgZmQsIGludCBsZXZlbCwgaW50IG9wdGlvbiwgaW50IHZhbHVlKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSB2b2lkIHNldHNvY2tvcHRJcE1yZXFuKEZpbGVEZXNjcmlwdG9yIGZkLCBpbnQgbGV2ZWwsIGludCBvcHRpb24sIGludCB2YWx1ZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCBzZXRzb2Nrb3B0R3JvdXBSZXEoRmlsZURlc2NyaXB0b3IgZmQsIGludCBsZXZlbCwgaW50IG9wdGlvbiwgU3RydWN0R3JvdXBSZXEgdmFsdWUpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgbmF0aXZlIHZvaWQgc2V0c29ja29wdExpbmdlcihGaWxlRGVzY3JpcHRvciBmZCwgaW50IGxldmVsLCBpbnQgb3B0aW9uLCBTdHJ1Y3RMaW5nZXIgdmFsdWUpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgbmF0aXZlIHZvaWQgc2V0c29ja29wdFRpbWV2YWwoRmlsZURlc2NyaXB0b3IgZmQsIGludCBsZXZlbCwgaW50IG9wdGlvbiwgU3RydWN0VGltZXZhbCB2YWx1ZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCBzZXR1aWQoaW50IHVpZCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCBzaHV0ZG93bihGaWxlRGVzY3JpcHRvciBmZCwgaW50IGhvdykgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgRmlsZURlc2NyaXB0b3Igc29ja2V0KGludCBkb21haW4sIGludCB0eXBlLCBpbnQgcHJvdG9jb2wpIHRocm93cyBFcnJub0V4Y2VwdGlvbjsKKyAgICBwdWJsaWMgbmF0aXZlIFN0cnVjdFN0YXQgc3RhdChTdHJpbmcgcGF0aCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgU3RydWN0U3RhdEZzIHN0YXRmcyhTdHJpbmcgcGF0aCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgU3RyaW5nIHN0cmVycm9yKGludCBlcnJubyk7CisgICAgcHVibGljIG5hdGl2ZSB2b2lkIHN5bWxpbmsoU3RyaW5nIG9sZFBhdGgsIFN0cmluZyBuZXdQYXRoKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIG5hdGl2ZSBsb25nIHN5c2NvbmYoaW50IG5hbWUpOworICAgIHB1YmxpYyBuYXRpdmUgU3RydWN0VXRzbmFtZSB1bmFtZSgpOworICAgIHB1YmxpYyBuYXRpdmUgaW50IHdhaXRwaWQoaW50IHBpZCwgTXV0YWJsZUludCBzdGF0dXMsIGludCBvcHRpb25zKSB0aHJvd3MgRXJybm9FeGNlcHRpb247CisgICAgcHVibGljIGludCB3cml0ZShGaWxlRGVzY3JpcHRvciBmZCwgQnl0ZUJ1ZmZlciBidWZmZXIpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChidWZmZXIuaXNEaXJlY3QoKSkgeworICAgICAgICAgICAgcmV0dXJuIHdyaXRlQnl0ZXMoZmQsIGJ1ZmZlciwgYnVmZmVyLnBvc2l0aW9uKCksIGJ1ZmZlci5yZW1haW5pbmcoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gd3JpdGVCeXRlcyhmZCwgTmlvVXRpbHMudW5zYWZlQXJyYXkoYnVmZmVyKSwgTmlvVXRpbHMudW5zYWZlQXJyYXlPZmZzZXQoYnVmZmVyKSArIGJ1ZmZlci5wb3NpdGlvbigpLCBidWZmZXIucmVtYWluaW5nKCkpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyBpbnQgd3JpdGUoRmlsZURlc2NyaXB0b3IgZmQsIGJ5dGVbXSBieXRlcywgaW50IGJ5dGVPZmZzZXQsIGludCBieXRlQ291bnQpIHRocm93cyBFcnJub0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRoaXMgaW5kaXJlY3Rpb24gaXNuJ3Qgc3RyaWN0bHkgbmVjZXNzYXJ5LCBidXQgZW5zdXJlcyB0aGF0IG91ciBwdWJsaWMgaW50ZXJmYWNlIGlzIHR5cGUgc2FmZS4KKyAgICAgICAgcmV0dXJuIHdyaXRlQnl0ZXMoZmQsIGJ5dGVzLCBieXRlT2Zmc2V0LCBieXRlQ291bnQpOworICAgIH0KKyAgICBwcml2YXRlIG5hdGl2ZSBpbnQgd3JpdGVCeXRlcyhGaWxlRGVzY3JpcHRvciBmZCwgT2JqZWN0IGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCkgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworICAgIHB1YmxpYyBuYXRpdmUgaW50IHdyaXRldihGaWxlRGVzY3JpcHRvciBmZCwgT2JqZWN0W10gYnVmZmVycywgaW50W10gb2Zmc2V0cywgaW50W10gYnl0ZUNvdW50cykgdGhyb3dzIEVycm5vRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vU2l6ZU9mLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9TaXplT2YuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MjhmYmZjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vU2l6ZU9mLmphdmEKQEAgLTAsMCArMSwyOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pbzsKKworcHVibGljIGZpbmFsIGNsYXNzIFNpemVPZiB7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0hBUiA9IDI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRE9VQkxFID0gODsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGTE9BVCA9IDQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UID0gNDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HID0gODsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9SVCA9IDI7CisKKyAgICBwcml2YXRlIFNpemVPZigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9TdHJlYW1zLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9TdHJlYW1zLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2JhZDRhNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL1N0cmVhbXMuamF2YQpAQCAtMCwwICsxLDIxNiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRU9GRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNSZWZlcmVuY2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBTdHJlYW1zIHsKKyAgICBwcml2YXRlIHN0YXRpYyBBdG9taWNSZWZlcmVuY2U8Ynl0ZVtdPiBza2lwQnVmZmVyID0gbmV3IEF0b21pY1JlZmVyZW5jZTxieXRlW10+KCk7CisKKyAgICBwcml2YXRlIFN0cmVhbXMoKSB7fQorCisgICAgLyoqCisgICAgICogSW1wbGVtZW50cyBJbnB1dFN0cmVhbS5yZWFkKGludCkgaW4gdGVybXMgb2YgSW5wdXRTdHJlYW0ucmVhZChieXRlW10sIGludCwgaW50KS4KKyAgICAgKiBJbnB1dFN0cmVhbSBhc3N1bWVzIHRoYXQgeW91IGltcGxlbWVudCBJbnB1dFN0cmVhbS5yZWFkKGludCkgYW5kIHByb3ZpZGVzIGRlZmF1bHQKKyAgICAgKiBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlIG90aGVycywgYnV0IG9mdGVuIHRoZSBvcHBvc2l0ZSBpcyBtb3JlIGVmZmljaWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCByZWFkU2luZ2xlQnl0ZShJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlWzFdOworICAgICAgICBpbnQgcmVzdWx0ID0gaW4ucmVhZChidWZmZXIsIDAsIDEpOworICAgICAgICByZXR1cm4gKHJlc3VsdCAhPSAtMSkgPyBidWZmZXJbMF0gJiAweGZmIDogLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW1wbGVtZW50cyBPdXRwdXRTdHJlYW0ud3JpdGUoaW50KSBpbiB0ZXJtcyBvZiBPdXRwdXRTdHJlYW0ud3JpdGUoYnl0ZVtdLCBpbnQsIGludCkuCisgICAgICogT3V0cHV0U3RyZWFtIGFzc3VtZXMgdGhhdCB5b3UgaW1wbGVtZW50IE91dHB1dFN0cmVhbS53cml0ZShpbnQpIGFuZCBwcm92aWRlcyBkZWZhdWx0CisgICAgICogaW1wbGVtZW50YXRpb25zIG9mIHRoZSBvdGhlcnMsIGJ1dCBvZnRlbiB0aGUgb3Bwb3NpdGUgaXMgbW9yZSBlZmZpY2llbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlU2luZ2xlQnl0ZShPdXRwdXRTdHJlYW0gb3V0LCBpbnQgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlWzFdOworICAgICAgICBidWZmZXJbMF0gPSAoYnl0ZSkgKGIgJiAweGZmKTsKKyAgICAgICAgb3V0LndyaXRlKGJ1ZmZlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlsbHMgJ2RzdCcgd2l0aCBieXRlcyBmcm9tICdpbicsIHRocm93aW5nIEVPRkV4Y2VwdGlvbiBpZiBpbnN1ZmZpY2llbnQgYnl0ZXMgYXJlIGF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcmVhZEZ1bGx5KElucHV0U3RyZWFtIGluLCBieXRlW10gZHN0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZWFkRnVsbHkoaW4sIGRzdCwgMCwgZHN0Lmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgZXhhY3RseSAnYnl0ZUNvdW50JyBieXRlcyBmcm9tICdpbicgKGludG8gJ2RzdCcgYXQgb2Zmc2V0ICdvZmZzZXQnKSwgYW5kIHRocm93cworICAgICAqIEVPRkV4Y2VwdGlvbiBpZiBpbnN1ZmZpY2llbnQgYnl0ZXMgYXJlIGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIFVzZWQgdG8gaW1wbGVtZW50IHtAbGluayBqYXZhLmlvLkRhdGFJbnB1dFN0cmVhbSNyZWFkRnVsbHkoYnl0ZVtdLCBpbnQsIGludCl9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCByZWFkRnVsbHkoSW5wdXRTdHJlYW0gaW4sIGJ5dGVbXSBkc3QsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChieXRlQ291bnQgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGlmIChpbiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImluID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZHN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiZHN0ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChkc3QubGVuZ3RoLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgIHdoaWxlIChieXRlQ291bnQgPiAwKSB7CisgICAgICAgICAgICBpbnQgYnl0ZXNSZWFkID0gaW4ucmVhZChkc3QsIG9mZnNldCwgYnl0ZUNvdW50KTsKKyAgICAgICAgICAgIGlmIChieXRlc1JlYWQgPCAwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgb2Zmc2V0ICs9IGJ5dGVzUmVhZDsKKyAgICAgICAgICAgIGJ5dGVDb3VudCAtPSBieXRlc1JlYWQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgYnl0ZVtdIGNvbnRhaW5pbmcgdGhlIHJlbWFpbmRlciBvZiAnaW4nLCBjbG9zaW5nIGl0IHdoZW4gZG9uZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSByZWFkRnVsbHkoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gcmVhZEZ1bGx5Tm9DbG9zZShpbik7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGJ5dGVbXSBjb250YWluaW5nIHRoZSByZW1haW5kZXIgb2YgJ2luJy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSByZWFkRnVsbHlOb0Nsb3NlKElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZXMgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVsxMDI0XTsKKyAgICAgICAgaW50IGNvdW50OworICAgICAgICB3aGlsZSAoKGNvdW50ID0gaW4ucmVhZChidWZmZXIpKSAhPSAtMSkgeworICAgICAgICAgICAgYnl0ZXMud3JpdGUoYnVmZmVyLCAwLCBjb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ5dGVzLnRvQnl0ZUFycmF5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmVtYWluZGVyIG9mICdyZWFkZXInIGFzIGEgc3RyaW5nLCBjbG9zaW5nIGl0IHdoZW4gZG9uZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyByZWFkRnVsbHkoUmVhZGVyIHJlYWRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZ1dyaXRlciB3cml0ZXIgPSBuZXcgU3RyaW5nV3JpdGVyKCk7CisgICAgICAgICAgICBjaGFyW10gYnVmZmVyID0gbmV3IGNoYXJbMTAyNF07CisgICAgICAgICAgICBpbnQgY291bnQ7CisgICAgICAgICAgICB3aGlsZSAoKGNvdW50ID0gcmVhZGVyLnJlYWQoYnVmZmVyKSkgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoYnVmZmVyLCAwLCBjb3VudCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gd3JpdGVyLnRvU3RyaW5nKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICByZWFkZXIuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBza2lwQWxsKElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBkbyB7CisgICAgICAgICAgICBpbi5za2lwKExvbmcuTUFYX1ZBTFVFKTsKKyAgICAgICAgfSB3aGlsZSAoaW4ucmVhZCgpICE9IC0xKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxsIHtAY29kZSBpbi5yZWFkKCl9IHJlcGVhdGVkbHkgdW50aWwgZWl0aGVyIHRoZSBzdHJlYW0gaXMgZXhoYXVzdGVkIG9yCisgICAgICoge0Bjb2RlIGJ5dGVDb3VudH0gYnl0ZXMgaGF2ZSBiZWVuIHJlYWQuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCByZXVzZXMgdGhlIHNraXAgYnVmZmVyIGJ1dCBpcyBjYXJlZnVsIHRvIG5ldmVyIHVzZSBpdCBhdAorICAgICAqIHRoZSBzYW1lIHRpbWUgdGhhdCBhbm90aGVyIHN0cmVhbSBpcyB1c2luZyBpdC4gT3RoZXJ3aXNlIHN0cmVhbXMgdGhhdCB1c2UKKyAgICAgKiB0aGUgY2FsbGVyJ3MgYnVmZmVyIGZvciBjb25zaXN0ZW5jeSBjaGVja3MgbGlrZSBDUkMgY291bGQgYmUgY2xvYmJlcmVkIGJ5CisgICAgICogb3RoZXIgdGhyZWFkcy4gQSB0aHJlYWQtbG9jYWwgYnVmZmVyIGlzIGFsc28gaW5zdWZmaWNpZW50IGJlY2F1c2Ugc29tZQorICAgICAqIHN0cmVhbXMgbWF5IGNhbGwgb3RoZXIgc3RyZWFtcyBpbiB0aGVpciBza2lwKCkgbWV0aG9kLCBhbHNvIGNsb2JiZXJpbmcgdGhlCisgICAgICogYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBza2lwQnlSZWFkaW5nKElucHV0U3RyZWFtIGluLCBsb25nIGJ5dGVDb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gYWNxdWlyZSB0aGUgc2hhcmVkIHNraXAgYnVmZmVyLgorICAgICAgICBieXRlW10gYnVmZmVyID0gc2tpcEJ1ZmZlci5nZXRBbmRTZXQobnVsbCk7CisgICAgICAgIGlmIChidWZmZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgYnVmZmVyID0gbmV3IGJ5dGVbNDA5Nl07CisgICAgICAgIH0KKworICAgICAgICBsb25nIHNraXBwZWQgPSAwOworICAgICAgICB3aGlsZSAoc2tpcHBlZCA8IGJ5dGVDb3VudCkgeworICAgICAgICAgICAgaW50IHRvUmVhZCA9IChpbnQpIE1hdGgubWluKGJ5dGVDb3VudCAtIHNraXBwZWQsIGJ1ZmZlci5sZW5ndGgpOworICAgICAgICAgICAgaW50IHJlYWQgPSBpbi5yZWFkKGJ1ZmZlciwgMCwgdG9SZWFkKTsKKyAgICAgICAgICAgIGlmIChyZWFkID09IC0xKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBza2lwcGVkICs9IHJlYWQ7CisgICAgICAgICAgICBpZiAocmVhZCA8IHRvUmVhZCkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gcmVsZWFzZSB0aGUgc2hhcmVkIHNraXAgYnVmZmVyLgorICAgICAgICBza2lwQnVmZmVyLnNldChidWZmZXIpOworCisgICAgICAgIHJldHVybiBza2lwcGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcGllcyBhbGwgb2YgdGhlIGJ5dGVzIGZyb20ge0Bjb2RlIGlufSB0byB7QGNvZGUgb3V0fS4gTmVpdGhlciBzdHJlYW0gaXMgY2xvc2VkLgorICAgICAqIFJldHVybnMgdGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyB0cmFuc2ZlcnJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBjb3B5KElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgdG90YWwgPSAwOworICAgICAgICBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbODE5Ml07CisgICAgICAgIGludCBjOworICAgICAgICB3aGlsZSAoKGMgPSBpbi5yZWFkKGJ1ZmZlcikpICE9IC0xKSB7CisgICAgICAgICAgICB0b3RhbCArPSBjOworICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZmZlciwgMCwgYyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRvdGFsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIEFTQ0lJIGNoYXJhY3RlcnMgdXAgdG8gYnV0IG5vdCBpbmNsdWRpbmcgdGhlIG5leHQgIlxyXG4iLCBvcgorICAgICAqICJcbiIuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIGphdmEuaW8uRU9GRXhjZXB0aW9uIGlmIHRoZSBzdHJlYW0gaXMgZXhoYXVzdGVkIGJlZm9yZSB0aGUgbmV4dCBuZXdsaW5lCisgICAgICogICAgIGNoYXJhY3Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyByZWFkQXNjaWlMaW5lKElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBUT0RPOiBzdXBwb3J0IFVURi04IGhlcmUgaW5zdGVhZAorCisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoODApOworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgaW50IGMgPSBpbi5yZWFkKCk7CisgICAgICAgICAgICBpZiAoYyA9PSAtMSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PSAnXG4nKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoKGNoYXIpIGMpOworICAgICAgICB9CisgICAgICAgIGludCBsZW5ndGggPSByZXN1bHQubGVuZ3RoKCk7CisgICAgICAgIGlmIChsZW5ndGggPiAwICYmIHJlc3VsdC5jaGFyQXQobGVuZ3RoIC0gMSkgPT0gJ1xyJykgeworICAgICAgICAgICAgcmVzdWx0LnNldExlbmd0aChsZW5ndGggLSAxKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vU3RydWN0QWRkcmluZm8uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL1N0cnVjdEFkZHJpbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGM4MTgxZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL1N0cnVjdEFkZHJpbmZvLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pbzsKKworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworCisvKioKKyAqIEluZm9ybWF0aW9uIHJldHVybmVkL3Rha2VuIGJ5IGdldGFkZHJpbmZvKDMpLiBDb3JyZXNwb25kcyB0byBDJ3Mge0Bjb2RlIHN0cnVjdCBhZGRyaW5mb30gZnJvbQorICogPGEgaHJlZj0iaHR0cDovL3B1YnMub3Blbmdyb3VwLm9yZy9vbmxpbmVwdWJzLzAwOTY5NTM5OS9iYXNlZGVmcy9uZXRkYi5oLmh0bWwiPiZsdDtuZXRkYi5oJmd0OzwvYT4KKyAqCisgKiBUT0RPOiB3ZSBjdXJyZW50bHkgb25seSBfdGFrZV8gYSBTdHJ1Y3RBZGRyaW5mbzsgZ2V0YWRkcmluZm8gcmV0dXJucyBhbiBJbmV0QWRkcmVzc1tdLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU3RydWN0QWRkcmluZm8geworICAgIC8qKiBGbGFncyBkZXNjcmliaW5nIHRoZSBraW5kIG9mIGxvb2t1cCB0byBiZSBkb25lLiAoU3VjaCBhcyBBSV9BRERSQ09ORklHLikgKi8KKyAgICBwdWJsaWMgaW50IGFpX2ZsYWdzOworCisgICAgLyoqIERlc2lyZWQgYWRkcmVzcyBmYW1pbHkgZm9yIHJlc3VsdHMuIChTdWNoIGFzIEFGX0lORVQ2IGZvciBJUHY2LiBBRl9VTlNQRUMgbWVhbnMgImFueSIuKSAqLworICAgIHB1YmxpYyBpbnQgYWlfZmFtaWx5OworCisgICAgLyoqIFNvY2tldCB0eXBlLiAoU3VjaCBhcyBTT0NLX0RHUkFNLiAwIG1lYW5zICJhbnkiLikgKi8KKyAgICBwdWJsaWMgaW50IGFpX3NvY2t0eXBlOworCisgICAgLyoqIFByb3RvY29sLiAoU3VjaCBhcyBJUFBST1RPX0lQVjYgSVB2Ni4gMCBtZWFucyAiYW55Ii4pICovCisgICAgcHVibGljIGludCBhaV9wcm90b2NvbDsKKworICAgIC8qKiBBZGRyZXNzIGxlbmd0aC4gKE5vdCB1c2VmdWwgaW4gSmF2YS4pICovCisgICAgLy8gcHVibGljIGludCBhaV9hZGRybGVuOworCisgICAgLyoqIEFkZHJlc3MuICovCisgICAgcHVibGljIEluZXRBZGRyZXNzIGFpX2FkZHI7CisKKyAgICAvKiogQ2Fub25pY2FsIG5hbWUgb2Ygc2VydmljZSBsb2NhdGlvbiAoaWYgQUlfQ0FOT05OQU1FIHByb3ZpZGVkIGluIGFpX2ZsYWdzKS4gKi8KKyAgICAvLyBwdWJsaWMgU3RyaW5nIGFpX2Nhbm9ubmFtZTsKKworICAgIC8qKiBOZXh0IGVsZW1lbnQgaW4gbGlua2VkIGxpc3QuICovCisgICAgcHVibGljIFN0cnVjdEFkZHJpbmZvIGFpX25leHQ7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9TdHJ1Y3RGbG9jay5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vU3RydWN0RmxvY2suamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMWMyOWRmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vU3RydWN0RmxvY2suamF2YQpAQCAtMCwwICsxLDM5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmlvOworCisvKioKKyAqIEluZm9ybWF0aW9uIHJldHVybmVkL3Rha2VuIGJ5IGZjbnRsKDIpIEZfR0VURkwgYW5kIEZfU0VURkwuIENvcnJlc3BvbmRzIHRvIEMncworICoge0Bjb2RlIHN0cnVjdCBmbG9ja30gZnJvbQorICogPGEgaHJlZj0iaHR0cDovL3B1YnMub3Blbmdyb3VwLm9yZy9vbmxpbmVwdWJzLzk2OTk5MTk3OTkvYmFzZWRlZnMvZmNudGwuaC5odG1sIj4mbHQ7ZmNudGwuaCZndDs8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTdHJ1Y3RGbG9jayB7CisgICAgLyoqIFRoZSBvcGVyYXRpb24gdHlwZSwgb25lIG9mIEZfUkRMQ0ssIEZfV1JMQ0ssIG9yIEZfVU5MQ0suICovCisgICAgcHVibGljIHNob3J0IGxfdHlwZTsKKworICAgIC8qKiBIb3cgdG8gaW50ZXJwcmV0IGxfc3RhcnQsIG9uZSBvZiBTRUVLX0NVUiwgU0VFS19FTkQsIFNFRUtfU0VULiAqLworICAgIHB1YmxpYyBzaG9ydCBsX3doZW5jZTsKKworICAgIC8qKiBTdGFydCBvZmZzZXQuICovCisgICAgcHVibGljIGxvbmcgbF9zdGFydDsgLypvZmZfdCovCisKKyAgICAvKiogQnl0ZSBjb3VudCB0byBvcGVyYXRlIG9uLiAqLworICAgIHB1YmxpYyBsb25nIGxfbGVuOyAvKm9mZl90Ki8KKworICAgIC8qKiBQcm9jZXNzIGJsb2NraW5nIG91ciBsb2NrIChmaWxsZWQgaW4gYnkgRl9HRVRMSywgb3RoZXJ3aXNlIHVudXNlZCkuICovCisgICAgcHVibGljIGludCBsX3BpZDsgLypwaWRfdCovCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9TdHJ1Y3RHcm91cFJlcS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vU3RydWN0R3JvdXBSZXEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYmRmNzgzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vU3RydWN0R3JvdXBSZXEuamF2YQpAQCAtMCwwICsxLDM2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmlvOworCitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CisKKy8qKgorICogQ29ycmVzcG9uZHMgdG8gQydzIHtAY29kZSBzdHJ1Y3QgZ3JvdXBfcmVxfS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFN0cnVjdEdyb3VwUmVxIHsKKyAgICBwdWJsaWMgZmluYWwgaW50IGdyX2ludGVyZmFjZTsKKyAgICBwdWJsaWMgZmluYWwgSW5ldEFkZHJlc3MgZ3JfZ3JvdXA7CisKKyAgICBwdWJsaWMgU3RydWN0R3JvdXBSZXEoaW50IGdyX2ludGVyZmFjZSwgSW5ldEFkZHJlc3MgZ3JfZ3JvdXApIHsKKyAgICAgICAgdGhpcy5ncl9pbnRlcmZhY2UgPSBncl9pbnRlcmZhY2U7CisgICAgICAgIHRoaXMuZ3JfZ3JvdXAgPSBncl9ncm91cDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuICJTdHJ1Y3RHcm91cFJlcVtncl9pbnRlcmZhY2U9IiArIGdyX2ludGVyZmFjZSArICIsZ3JfZ3JvdXA9IiArIGdyX2dyb3VwICsgIl0iOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL1N0cnVjdExpbmdlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vU3RydWN0TGluZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWYxNDlhZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL1N0cnVjdExpbmdlci5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuaW87CisKKy8qKgorICogQ29ycmVzcG9uZHMgdG8gQydzIHtAY29kZSBzdHJ1Y3QgbGluZ2VyfSBmcm9tCisgKiA8YSBocmVmPSJodHRwOi8vcHVicy5vcGVuZ3JvdXAub3JnL29ubGluZXB1YnMvOTY5OTkxOTc5OS9iYXNlZGVmcy9zeXNfc29ja2V0LmguaHRtbCI+Jmx0O3N5cy9zb2NrZXQuaCZndDs8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTdHJ1Y3RMaW5nZXIgeworICAgIC8qKiBXaGV0aGVyIG9yIG5vdCBsaW5nZXIgaXMgZW5hYmxlZC4gTm9uLXplcm8gaXMgb24uICovCisgICAgcHVibGljIGZpbmFsIGludCBsX29ub2ZmOworCisgICAgLyoqIExpbmdlciB0aW1lIGluIHNlY29uZHMuICovCisgICAgcHVibGljIGZpbmFsIGludCBsX2xpbmdlcjsKKworICAgIHB1YmxpYyBTdHJ1Y3RMaW5nZXIoaW50IGxfb25vZmYsIGludCBsX2xpbmdlcikgeworICAgICAgICB0aGlzLmxfb25vZmYgPSBsX29ub2ZmOworICAgICAgICB0aGlzLmxfbGluZ2VyID0gbF9saW5nZXI7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNPbigpIHsKKyAgICAgICAgcmV0dXJuIGxfb25vZmYgIT0gMDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuICJTdHJ1Y3RMaW5nZXJbbF9vbm9mZj0iICsgbF9vbm9mZiArICIsbF9saW5nZXI9IiArIGxfbGluZ2VyICsgIl0iOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL1N0cnVjdFBhc3N3ZC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vU3RydWN0UGFzc3dkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmY1ZTA1OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL1N0cnVjdFBhc3N3ZC5qYXZhCkBAIC0wLDAgKzEsMzggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuaW87CisKKy8qKgorICogSW5mb3JtYXRpb24gcmV0dXJuZWQgYnkgZ2V0cHduYW0oMykgYW5kIGdldHB3dWlkKDMpLiBDb3JyZXNwb25kcyB0byBDJ3MKKyAqIHtAY29kZSBzdHJ1Y3QgcGFzc3dkfSBmcm9tCisgKiA8YSBocmVmPSJodHRwOi8vcHVicy5vcGVuZ3JvdXAub3JnL29ubGluZXB1YnMvOTY5OTkxOTc5OS9iYXNlZGVmcy9wd2QuaC5odG1sIj4mbHQ7cHdkLmgmZ3Q7PC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU3RydWN0UGFzc3dkIHsKKyAgICBwdWJsaWMgU3RyaW5nIHB3X25hbWU7CisgICAgcHVibGljIGludCBwd191aWQ7IC8qIHVpZF90ICovCisgICAgcHVibGljIGludCBwd19naWQ7IC8qIGdpZF90ICovCisgICAgcHVibGljIFN0cmluZyBwd19kaXI7CisgICAgcHVibGljIFN0cmluZyBwd19zaGVsbDsKKworICAgIHB1YmxpYyBTdHJ1Y3RQYXNzd2QoU3RyaW5nIHB3X25hbWUsIGludCBwd191aWQsIGludCBwd19naWQsIFN0cmluZyBwd19kaXIsIFN0cmluZyBwd19zaGVsbCkgeworICAgICAgICB0aGlzLnB3X25hbWUgPSBwd19uYW1lOworICAgICAgICB0aGlzLnB3X3VpZCA9IHB3X3VpZDsKKyAgICAgICAgdGhpcy5wd19naWQgPSBwd19naWQ7CisgICAgICAgIHRoaXMucHdfZGlyID0gcHdfZGlyOworICAgICAgICB0aGlzLnB3X3NoZWxsID0gcHdfc2hlbGw7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vU3RydWN0UG9sbGZkLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9TdHJ1Y3RQb2xsZmQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNjU5ZDZlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vU3RydWN0UG9sbGZkLmphdmEKQEAgLTAsMCArMSw0OCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pbzsKKworaW1wb3J0IGphdmEuaW8uRmlsZURlc2NyaXB0b3I7CisKKy8qKgorICogQ29ycmVzcG9uZHMgdG8gQydzIHtAY29kZSBzdHJ1Y3QgcG9sbGZkfSBmcm9tCisgKiA8YSBocmVmPSJodHRwOi8vcHVicy5vcGVuZ3JvdXAub3JnL29ubGluZXB1YnMvOTY5OTkxOTc5OS9iYXNlZGVmcy9wb2xsLmguaHRtbCI+Jmx0O3BvbGwuaCZndDs8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTdHJ1Y3RQb2xsZmQgeworICAgIC8qKiBUaGUgZmlsZSBkZXNjcmlwdG9yIHRvIHBvbGwuICovCisgICAgcHVibGljIEZpbGVEZXNjcmlwdG9yIGZkOworCisgICAgLyoqCisgICAgICogVGhlIGV2ZW50cyB3ZSdyZSBpbnRlcmVzdGVkIGluLiBQT0xMSU4gY29ycmVzcG9uZHMgdG8gYmVpbmcgaW4gc2VsZWN0KDIpJ3MgcmVhZCBmZCBzZXQsCisgICAgICogUE9MTE9VVCB0byB0aGUgd3JpdGUgZmQgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBzaG9ydCBldmVudHM7CisKKyAgICAvKiogVGhlIGV2ZW50cyB0aGF0IGFjdHVhbGx5IGhhcHBlbmVkLiAqLworICAgIHB1YmxpYyBzaG9ydCByZXZlbnRzOworCisgICAgLyoqCisgICAgICogQSBub24tc3RhbmRhcmQgZXh0ZW5zaW9uIHRoYXQgbGV0cyBjYWxsZXJzIGNvbnZlbmllbnRseSBtYXAgYmFjayB0byB0aGUgb2JqZWN0CisgICAgICogdGhlaXIgZmQgYmVsb25ncyB0by4gVGhpcyBpcyB1c2VkIGJ5IFNlbGVjdG9yLCBmb3IgZXhhbXBsZSwgdG8gYXNzb2NpYXRlIGVhY2gKKyAgICAgKiBGaWxlRGVzY3JpcHRvciB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIFNlbGVjdGlvbktleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IHVzZXJEYXRhOworCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiAiU3RydWN0UG9sbGZkW2ZkPSIgKyBmZCArICIsZXZlbnRzPSIgKyBldmVudHMgKyAiLHJldmVudHM9IiArIHJldmVudHMgKyAiXSI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vU3RydWN0U3RhdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vU3RydWN0U3RhdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA1ZWNjYTcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9TdHJ1Y3RTdGF0LmphdmEKQEAgLTAsMCArMSw5MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pbzsKKworLyoqCisgKiBGaWxlIGluZm9ybWF0aW9uIHJldHVybmVkIGJ5IGZzdGF0KDIpLCBsc3RhdCgyKSwgYW5kIHN0YXQoMikuIENvcnJlc3BvbmRzIHRvIEMncworICoge0Bjb2RlIHN0cnVjdCBzdGF0fSBmcm9tCisgKiA8YSBocmVmPSJodHRwOi8vd3d3Lm9wZW5ncm91cC5vcmcvb25saW5lcHVicy8wMDAwOTUzOTkvYmFzZWRlZnMvc3lzL3N0YXQuaC5odG1sIj4mbHQ7c3RhdC5oJmd0OzwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFN0cnVjdFN0YXQgeworICAgIC8qKiBEZXZpY2UgSUQgb2YgZGV2aWNlIGNvbnRhaW5pbmcgZmlsZS4gKi8KKyAgICBwdWJsaWMgZmluYWwgbG9uZyBzdF9kZXY7IC8qZGV2X3QqLworCisgICAgLyoqIEZpbGUgc2VyaWFsIG51bWJlciAoaW5vZGUpLiAqLworICAgIHB1YmxpYyBmaW5hbCBsb25nIHN0X2lubzsgLyppbm9fdCovCisKKyAgICAvKiogTW9kZSAocGVybWlzc2lvbnMpIG9mIGZpbGUuICovCisgICAgcHVibGljIGZpbmFsIGludCBzdF9tb2RlOyAvKm1vZGVfdCovCisKKyAgICAvKiogTnVtYmVyIG9mIGhhcmQgbGlua3MgdG8gdGhlIGZpbGUuICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgc3Rfbmxpbms7IC8qbmxpbmtfdCovCisKKyAgICAvKiogVXNlciBJRCBvZiBmaWxlLiAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgc3RfdWlkOyAvKnVpZF90Ki8KKworICAgIC8qKiBHcm91cCBJRCBvZiBmaWxlLiAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgc3RfZ2lkOyAvKmdpZF90Ki8KKworICAgIC8qKiBEZXZpY2UgSUQgKGlmIGZpbGUgaXMgY2hhcmFjdGVyIG9yIGJsb2NrIHNwZWNpYWwpLiAqLworICAgIHB1YmxpYyBmaW5hbCBsb25nIHN0X3JkZXY7IC8qZGV2X3QqLworCisgICAgLyoqCisgICAgICogRm9yIHJlZ3VsYXIgZmlsZXMsIHRoZSBmaWxlIHNpemUgaW4gYnl0ZXMuCisgICAgICogRm9yIHN5bWJvbGljIGxpbmtzLCB0aGUgbGVuZ3RoIGluIGJ5dGVzIG9mIHRoZSBwYXRobmFtZSBjb250YWluZWQgaW4gdGhlIHN5bWJvbGljIGxpbmsuCisgICAgICogRm9yIGEgc2hhcmVkIG1lbW9yeSBvYmplY3QsIHRoZSBsZW5ndGggaW4gYnl0ZXMuCisgICAgICogRm9yIGEgdHlwZWQgbWVtb3J5IG9iamVjdCwgdGhlIGxlbmd0aCBpbiBieXRlcy4KKyAgICAgKiBGb3Igb3RoZXIgZmlsZSB0eXBlcywgdGhlIHVzZSBvZiB0aGlzIGZpZWxkIGlzIHVuc3BlY2lmaWVkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBsb25nIHN0X3NpemU7IC8qb2ZmX3QqLworCisgICAgLyoqIFRpbWUgb2YgbGFzdCBhY2Nlc3MuICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgc3RfYXRpbWU7IC8qdGltZV90Ki8KKworICAgIC8qKiBUaW1lIG9mIGxhc3QgZGF0YSBtb2RpZmljYXRpb24uICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgc3RfbXRpbWU7IC8qdGltZV90Ki8KKworICAgIC8qKiBUaW1lIG9mIGxhc3Qgc3RhdHVzIGNoYW5nZS4gKi8KKyAgICBwdWJsaWMgZmluYWwgbG9uZyBzdF9jdGltZTsgLyp0aW1lX3QqLworCisgICAgLyoqCisgICAgICogQSBmaWxlIHN5c3RlbS1zcGVjaWZpYyBwcmVmZXJyZWQgSS9PIGJsb2NrIHNpemUgZm9yIHRoaXMgb2JqZWN0LgorICAgICAqIEZvciBzb21lIGZpbGUgc3lzdGVtIHR5cGVzLCB0aGlzIG1heSB2YXJ5IGZyb20gZmlsZSB0byBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBsb25nIHN0X2Jsa3NpemU7IC8qYmxrc2l6ZV90Ki8KKworICAgIC8qKiBOdW1iZXIgb2YgYmxvY2tzIGFsbG9jYXRlZCBmb3IgdGhpcyBvYmplY3QuICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgc3RfYmxvY2tzOyAvKmJsa2NudF90Ki8KKworICAgIFN0cnVjdFN0YXQobG9uZyBzdF9kZXYsIGxvbmcgc3RfaW5vLCBpbnQgc3RfbW9kZSwgbG9uZyBzdF9ubGluaywgaW50IHN0X3VpZCwgaW50IHN0X2dpZCwKKyAgICAgICAgICAgIGxvbmcgc3RfcmRldiwgbG9uZyBzdF9zaXplLCBsb25nIHN0X2F0aW1lLCBsb25nIHN0X210aW1lLCBsb25nIHN0X2N0aW1lLAorICAgICAgICAgICAgbG9uZyBzdF9ibGtzaXplLCBsb25nIHN0X2Jsb2NrcykgeworICAgICAgICB0aGlzLnN0X2RldiA9IHN0X2RldjsKKyAgICAgICAgdGhpcy5zdF9pbm8gPSBzdF9pbm87CisgICAgICAgIHRoaXMuc3RfbW9kZSA9IHN0X21vZGU7CisgICAgICAgIHRoaXMuc3RfbmxpbmsgPSBzdF9ubGluazsKKyAgICAgICAgdGhpcy5zdF91aWQgPSBzdF91aWQ7CisgICAgICAgIHRoaXMuc3RfZ2lkID0gc3RfZ2lkOworICAgICAgICB0aGlzLnN0X3JkZXYgPSBzdF9yZGV2OworICAgICAgICB0aGlzLnN0X3NpemUgPSBzdF9zaXplOworICAgICAgICB0aGlzLnN0X2F0aW1lID0gc3RfYXRpbWU7CisgICAgICAgIHRoaXMuc3RfbXRpbWUgPSBzdF9tdGltZTsKKyAgICAgICAgdGhpcy5zdF9jdGltZSA9IHN0X2N0aW1lOworICAgICAgICB0aGlzLnN0X2Jsa3NpemUgPSBzdF9ibGtzaXplOworICAgICAgICB0aGlzLnN0X2Jsb2NrcyA9IHN0X2Jsb2NrczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9TdHJ1Y3RTdGF0RnMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL1N0cnVjdFN0YXRGcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYwM2RjODYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9TdHJ1Y3RTdGF0RnMuamF2YQpAQCAtMCwwICsxLDYxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmlvOworCisvKioKKyAqIEZpbGUgaW5mb3JtYXRpb24gcmV0dXJuZWQgYnkgZnN0YXRmcygyKSBhbmQgc3RhdGZzKDIpLgorICoKKyAqIFRPRE86IHRoaXMgc2hvdWxkIGJlIHtAY29kZSBzdHJ1Y3Qgc3RhdHZmc30sIGJ1dCBCaW9uaWMgZG9lc24ndCBzdXBwb3J0IHRoYXQgeWV0LgorICogQGhpZGUgdW50aWwgdGhlIFRPRE8gaXMgZml4ZWQuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTdHJ1Y3RTdGF0RnMgeworICAgIC8qKiBGaWxlIHN5c3RlbSBibG9jayBzaXplICh1c2VkIGZvciBibG9jayBjb3VudHMpLiAqLworICAgIHB1YmxpYyBmaW5hbCBsb25nIGZfYnNpemU7IC8qdW5zaWduZWQgbG9uZyovCisKKyAgICAvKiogVG90YWwgYmxvY2sgY291bnQuICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgZl9ibG9ja3M7IC8qZnNibGtjbnRfdCovCisKKyAgICAvKiogRnJlZSBibG9jayBjb3VudC4gKi8KKyAgICBwdWJsaWMgZmluYWwgbG9uZyBmX2JmcmVlOyAvKmZzYmxrY250X3QqLworCisgICAgLyoqIEZyZWUgYmxvY2sgY291bnQgYXZhaWxhYmxlIHRvIG5vbi1yb290LiAqLworICAgIHB1YmxpYyBmaW5hbCBsb25nIGZfYmF2YWlsOyAvKmZzYmxrY250X3QqLworCisgICAgLyoqIFRvdGFsIGZpbGUgKGlub2RlKSBjb3VudC4gKi8KKyAgICBwdWJsaWMgZmluYWwgbG9uZyBmX2ZpbGVzOyAvKmZzZmlsY250X3QqLworCisgICAgLyoqIEZyZWUgZmlsZSAoaW5vZGUpIGNvdW50LiAqLworICAgIHB1YmxpYyBmaW5hbCBsb25nIGZfZmZyZWU7IC8qZnNmaWxjbnRfdCovCisKKyAgICAvKiogTWF4aW11bSBmaWxlbmFtZSBsZW5ndGguICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgZl9uYW1lbWF4OyAvKnVuc2lnbmVkIGxvbmcqLworCisgICAgLyoqIEZ1bmRhbWVudGFsIGZpbGUgc3lzdGVtIGJsb2NrIHNpemUuICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgZl9mcnNpemU7IC8qdW5zaWduZWQgbG9uZyovCisKKyAgICBTdHJ1Y3RTdGF0RnMobG9uZyBmX2JzaXplLCBsb25nIGZfYmxvY2tzLCBsb25nIGZfYmZyZWUsIGxvbmcgZl9iYXZhaWwsCisgICAgICAgICAgICBsb25nIGZfZmlsZXMsIGxvbmcgZl9mZnJlZSwgbG9uZyBmX25hbWVtYXgsIGxvbmcgZl9mcnNpemUpIHsKKyAgICAgICAgdGhpcy5mX2JzaXplID0gZl9ic2l6ZTsKKyAgICAgICAgdGhpcy5mX2Jsb2NrcyA9IGZfYmxvY2tzOworICAgICAgICB0aGlzLmZfYmZyZWUgPSBmX2JmcmVlOworICAgICAgICB0aGlzLmZfYmF2YWlsID0gZl9iYXZhaWw7CisgICAgICAgIHRoaXMuZl9maWxlcyA9IGZfZmlsZXM7CisgICAgICAgIHRoaXMuZl9mZnJlZSA9IGZfZmZyZWU7CisgICAgICAgIHRoaXMuZl9uYW1lbWF4ID0gZl9uYW1lbWF4OworICAgICAgICB0aGlzLmZfZnJzaXplID0gZl9mcnNpemU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vU3RydWN0VGltZXZhbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvaW8vU3RydWN0VGltZXZhbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBlZDM1MDkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9TdHJ1Y3RUaW1ldmFsLmphdmEKQEAgLTAsMCArMSw0OCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pbzsKKworLyoqCisgKiBDb3JyZXNwb25kcyB0byBDJ3Mge0Bjb2RlIHN0cnVjdCB0aW1ldmFsfSBmcm9tCisgKiA8YSBocmVmPSJodHRwOi8vcHVicy5vcGVuZ3JvdXAub3JnL29ubGluZXB1YnMvOTY5OTkxOTc5OS9iYXNlZGVmcy9zeXNfdGltZS5oLmh0bWwiPiZsdDtzeXMvdGltZS5oJmd0OzwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFN0cnVjdFRpbWV2YWwgeworICAgIC8qKiBTZWNvbmRzLiAqLworICAgIHB1YmxpYyBmaW5hbCBsb25nIHR2X3NlYzsKKworICAgIC8qKiBNaWNyb3NlY29uZHMuICovCisgICAgcHVibGljIGZpbmFsIGxvbmcgdHZfdXNlYzsKKworICAgIHByaXZhdGUgU3RydWN0VGltZXZhbChsb25nIHR2X3NlYywgbG9uZyB0dl91c2VjKSB7CisgICAgICAgIHRoaXMudHZfc2VjID0gdHZfc2VjOworICAgICAgICB0aGlzLnR2X3VzZWMgPSB0dl91c2VjOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RydWN0VGltZXZhbCBmcm9tTWlsbGlzKGxvbmcgbWlsbGlzKSB7CisgICAgICAgIGxvbmcgdHZfc2VjID0gbWlsbGlzIC8gMTAwMDsKKyAgICAgICAgbG9uZyB0dl91c2VjID0gKG1pbGxpcyAtICh0dl9zZWMgKiAxMDAwKSkgKiAxMDAwOworICAgICAgICByZXR1cm4gbmV3IFN0cnVjdFRpbWV2YWwodHZfc2VjLCB0dl91c2VjKTsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyB0b01pbGxpcygpIHsKKyAgICAgICAgcmV0dXJuICh0dl9zZWMgKiAxMDAwKSArICh0dl91c2VjIC8gMTAwMCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiAiU3RydWN0VGltZXZhbFt0dl9zZWM9IiArIHR2X3NlYyArICIsdHZfdXNlYz0iICsgdHZfdXNlYyArICJdIjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9TdHJ1Y3RVdHNuYW1lLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9pby9TdHJ1Y3RVdHNuYW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTZhOGU0MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL2lvL1N0cnVjdFV0c25hbWUuamF2YQpAQCAtMCwwICsxLDQ3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmlvOworCisvKioKKyAqIEluZm9ybWF0aW9uIHJldHVybmVkIGJ5IHVuYW1lKDIpLiBDb3JyZXNwb25kcyB0byBDJ3MKKyAqIHtAY29kZSBzdHJ1Y3QgdXRzbmFtZX0gZnJvbQorICogPGEgaHJlZj0iaHR0cDovL3B1YnMub3Blbmdyb3VwLm9yZy9vbmxpbmVwdWJzLzk2OTk5MTk3OTkvYmFzZWRlZnMvc3lzX3V0c25hbWUuaC5odG1sIj4mbHQ7c3lzL3V0c25hbWUuaCZndDs8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTdHJ1Y3RVdHNuYW1lIHsKKyAgICAvKiogVGhlIE9TIG5hbWUsIHN1Y2ggYXMgIkxpbnV4Ii4gKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIHN5c25hbWU7CisKKyAgICAvKiogVGhlIG1hY2hpbmUncyB1bnF1YWxpZmllZCBuYW1lIG9uIHNvbWUgaW1wbGVtZW50YXRpb24tZGVmaW5lZCBuZXR3b3JrLiAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgbm9kZW5hbWU7CisKKyAgICAvKiogVGhlIE9TIHJlbGVhc2UsIHN1Y2ggYXMgIjIuNi4zNS0yNy1nZW5lcmljIi4gKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIHJlbGVhc2U7CisKKyAgICAvKiogVGhlIE9TIHZlcnNpb24sIHN1Y2ggYXMgIiM0OC1VYnVudHUgU01QIFR1ZSBGZWIgMjIgMjA6MjU6MjkgVVRDIDIwMTEiLiAqLworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgdmVyc2lvbjsKKworICAgIC8qKiBUaGUgbWFjaGluZSBhcmNoaXRlY3R1cmUsIHN1Y2ggYXMgImFybXY3bCIgb3IgIng4Nl82NCIuICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBtYWNoaW5lOworCisgICAgU3RydWN0VXRzbmFtZShTdHJpbmcgc3lzbmFtZSwgU3RyaW5nIG5vZGVuYW1lLCBTdHJpbmcgcmVsZWFzZSwgU3RyaW5nIHZlcnNpb24sIFN0cmluZyBtYWNoaW5lKSB7CisgICAgICAgIHRoaXMuc3lzbmFtZSA9IHN5c25hbWU7CisgICAgICAgIHRoaXMubm9kZW5hbWUgPSBub2RlbmFtZTsKKyAgICAgICAgdGhpcy5yZWxlYXNlID0gcmVsZWFzZTsKKyAgICAgICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjsKKyAgICAgICAgdGhpcy5tYWNoaW5lID0gbWFjaGluZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9tYXRoL01hdGhVdGlscy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbWF0aC9NYXRoVXRpbHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNDc0MDE0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbWF0aC9NYXRoVXRpbHMuamF2YQpAQCAtMCwwICsxLDQ4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLm1hdGg7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBNYXRoVXRpbHMgeworICAgIHByaXZhdGUgTWF0aFV0aWxzKCkgeyB9CisKKyAgICAvKioKKyAgICAgKiBBbiBhcnJheSB3aXRoIHBvd2VycyBvZiB0ZW4gdGhhdCBmaXQgaW4gdGhlIHR5cGUgPGNvZGU+bG9uZzwvY29kZT4KKyAgICAgKiAoPGNvZGU+MTBeMCwxMF4xLC4uLiwxMF4xODwvY29kZT4pLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZ1tdIExPTkdfUE9XRVJTX09GX1RFTiA9IG5ldyBsb25nW10geworICAgICAgICAxTCwKKyAgICAgICAgMTBMLAorICAgICAgICAxMDBMLAorICAgICAgICAxMDAwTCwKKyAgICAgICAgMTAwMDBMLAorICAgICAgICAxMDAwMDBMLAorICAgICAgICAxMDAwMDAwTCwKKyAgICAgICAgMTAwMDAwMDBMLAorICAgICAgICAxMDAwMDAwMDBMLAorICAgICAgICAxMDAwMDAwMDAwTCwKKyAgICAgICAgMTAwMDAwMDAwMDBMLAorICAgICAgICAxMDAwMDAwMDAwMDBMLAorICAgICAgICAxMDAwMDAwMDAwMDAwTCwKKyAgICAgICAgMTAwMDAwMDAwMDAwMDBMLAorICAgICAgICAxMDAwMDAwMDAwMDAwMDBMLAorICAgICAgICAxMDAwMDAwMDAwMDAwMDAwTCwKKyAgICAgICAgMTAwMDAwMDAwMDAwMDAwMDBMLAorICAgICAgICAxMDAwMDAwMDAwMDAwMDAwMDBMLAorICAgICAgICAxMDAwMDAwMDAwMDAwMDAwMDAwTCwKKyAgICB9OworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvTWltZVV0aWxzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvTWltZVV0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODM3MWM2OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9NaW1lVXRpbHMuamF2YQpAQCAtMCwwICsxLDQ3OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKKy8qKgorICogVXRpbGl0aWVzIGZvciBkZWFsaW5nIHdpdGggTUlNRSB0eXBlcy4KKyAqIFVzZWQgdG8gaW1wbGVtZW50IGphdmEubmV0LlVSTENvbm5lY3Rpb24gYW5kIGFuZHJvaWQud2Via2l0Lk1pbWVUeXBlTWFwLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTWltZVV0aWxzIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IG1pbWVUeXBlVG9FeHRlbnNpb25NYXAgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gZXh0ZW5zaW9uVG9NaW1lVHlwZU1hcCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOworCisgICAgc3RhdGljIHsKKyAgICAgICAgLy8gVGhlIGZvbGxvd2luZyB0YWJsZSBpcyBiYXNlZCBvbiAvZXRjL21pbWUudHlwZXMgZGF0YSBtaW51cworICAgICAgICAvLyBjaGVtaWNhbC8qIE1JTUUgdHlwZXMgYW5kIE1JTUUgdHlwZXMgdGhhdCBkb24ndCBtYXAgdG8gYW55CisgICAgICAgIC8vIGZpbGUgZXh0ZW5zaW9ucy4gV2UgYWxzbyBleGNsdWRlIHRvcC1sZXZlbCBkb21haW4gbmFtZXMgdG8KKyAgICAgICAgLy8gZGVhbCB3aXRoIGNhc2VzIGxpa2U6CisgICAgICAgIC8vCisgICAgICAgIC8vIG1haWwuZ29vZ2xlLmNvbS9hL2dvb2dsZS5jb20KKyAgICAgICAgLy8KKyAgICAgICAgLy8gYW5kICJhY3RpdmUiIE1JTUUgdHlwZXMgKGR1ZSB0byBwb3RlbnRpYWwgc2VjdXJpdHkgaXNzdWVzKS4KKworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL2FuZHJldy1pbnNldCIsICJleiIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL2RzcHR5cGUiLCAidHNwIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vZnV0dXJlc3BsYXNoIiwgInNwbCIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL2h0YSIsICJodGEiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi9tYWMtYmluaGV4NDAiLCAiaHF4Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vbWFjLWNvbXBhY3Rwcm8iLCAiY3B0Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vbWF0aGVtYXRpY2EiLCAibmIiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi9tc2FjY2VzcyIsICJtZGIiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi9vZGEiLCAib2RhIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vb2dnIiwgIm9nZyIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3BkZiIsICJwZGYiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi9wZ3Ata2V5cyIsICJrZXkiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi9wZ3Atc2lnbmF0dXJlIiwgInBncCIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3BpY3MtcnVsZXMiLCAicHJmIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vcmFyIiwgInJhciIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3JkZit4bWwiLCAicmRmIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vcnNzK3htbCIsICJyc3MiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi96aXAiLCAiemlwIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLmFuZHJvaWQucGFja2FnZS1hcmNoaXZlIiwgImFwayIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5jaW5kZXJlbGxhIiwgImNkeSIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5tcy1wa2kuc3RsIiwgInN0bCIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQuZGF0YWJhc2UiLCAib2RiIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5mb3JtdWxhIiwgIm9kZiIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQuZ3JhcGhpY3MiLCAib2RnIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5ncmFwaGljcy10ZW1wbGF0ZSIsICJvdGciKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LmltYWdlIiwgIm9kaSIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQuc3ByZWFkc2hlZXQiLCAib2RzIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5zcHJlYWRzaGVldC10ZW1wbGF0ZSIsICJvdHMiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LnRleHQiLCAib2R0Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC50ZXh0LW1hc3RlciIsICJvZG0iKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LnRleHQtdGVtcGxhdGUiLCAib3R0Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC50ZXh0LXdlYiIsICJvdGgiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi92bmQuZ29vZ2xlLWVhcnRoLmttbCt4bWwiLCAia21sIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLmdvb2dsZS1lYXJ0aC5rbXoiLCAia216Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vbXN3b3JkIiwgImRvYyIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL21zd29yZCIsICJkb3QiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQud29yZHByb2Nlc3NpbmdtbC5kb2N1bWVudCIsICJkb2N4Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LndvcmRwcm9jZXNzaW5nbWwudGVtcGxhdGUiLCAiZG90eCIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5tcy1leGNlbCIsICJ4bHMiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi92bmQubXMtZXhjZWwiLCAieGx0Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuc2hlZXQiLCAieGxzeCIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnRlbXBsYXRlIiwgInhsdHgiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi92bmQubXMtcG93ZXJwb2ludCIsICJwcHQiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi92bmQubXMtcG93ZXJwb2ludCIsICJwb3QiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi92bmQubXMtcG93ZXJwb2ludCIsICJwcHMiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwucHJlc2VudGF0aW9uIiwgInBwdHgiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwudGVtcGxhdGUiLCAicG90eCIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5zbGlkZXNob3ciLCAicHBzeCIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5yaW0uY29kIiwgImNvZCIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5zbWFmIiwgIm1tZiIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5zdGFyZGl2aXNpb24uY2FsYyIsICJzZGMiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi92bmQuc3RhcmRpdmlzaW9uLmRyYXciLCAic2RhIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLnN0YXJkaXZpc2lvbi5pbXByZXNzIiwgInNkZCIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5zdGFyZGl2aXNpb24uaW1wcmVzcyIsICJzZHAiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi92bmQuc3RhcmRpdmlzaW9uLm1hdGgiLCAic21mIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLnN0YXJkaXZpc2lvbi53cml0ZXIiLCAic2R3Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLnN0YXJkaXZpc2lvbi53cml0ZXIiLCAidm9yIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLnN0YXJkaXZpc2lvbi53cml0ZXItZ2xvYmFsIiwgInNnbCIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5zdW4ueG1sLmNhbGMiLCAic3hjIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLnN1bi54bWwuY2FsYy50ZW1wbGF0ZSIsICJzdGMiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi92bmQuc3VuLnhtbC5kcmF3IiwgInN4ZCIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5zdW4ueG1sLmRyYXcudGVtcGxhdGUiLCAic3RkIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLnN1bi54bWwuaW1wcmVzcyIsICJzeGkiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi92bmQuc3VuLnhtbC5pbXByZXNzLnRlbXBsYXRlIiwgInN0aSIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5zdW4ueG1sLm1hdGgiLCAic3htIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLnN1bi54bWwud3JpdGVyIiwgInN4dyIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC5zdW4ueG1sLndyaXRlci5nbG9iYWwiLCAic3hnIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24vdm5kLnN1bi54bWwud3JpdGVyLnRlbXBsYXRlIiwgInN0dyIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3ZuZC52aXNpbyIsICJ2c2QiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LWFiaXdvcmQiLCAiYWJ3Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1hcHBsZS1kaXNraW1hZ2UiLCAiZG1nIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1iY3BpbyIsICJiY3BpbyIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtYml0dG9ycmVudCIsICJ0b3JyZW50Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1jZGYiLCAiY2RmIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1jZGxpbmsiLCAidmNkIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1jaGVzcy1wZ24iLCAicGduIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1jcGlvIiwgImNwaW8iKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LWRlYmlhbi1wYWNrYWdlIiwgImRlYiIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtZGViaWFuLXBhY2thZ2UiLCAidWRlYiIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtZGlyZWN0b3IiLCAiZGNyIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1kaXJlY3RvciIsICJkaXIiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LWRpcmVjdG9yIiwgImR4ciIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtZG1zIiwgImRtcyIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtZG9vbSIsICJ3YWQiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LWR2aSIsICJkdmkiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LWZsYWMiLCAiZmxhYyIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtZm9udCIsICJwZmEiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LWZvbnQiLCAicGZiIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1mb250IiwgImdzZiIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtZm9udCIsICJwY2YiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LWZvbnQiLCAicGNmLloiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LWZyZWVtaW5kIiwgIm1tIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1mdXR1cmVzcGxhc2giLCAic3BsIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1nbnVtZXJpYyIsICJnbnVtZXJpYyIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtZ28tc2dmIiwgInNnZiIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtZ3JhcGhpbmctY2FsY3VsYXRvciIsICJnY2YiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LWd0YXIiLCAiZ3RhciIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtZ3RhciIsICJ0Z3oiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LWd0YXIiLCAidGF6Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1oZGYiLCAiaGRmIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1pY2EiLCAiaWNhIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1pbnRlcm5ldC1zaWdudXAiLCAiaW5zIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1pbnRlcm5ldC1zaWdudXAiLCAiaXNwIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1pcGhvbmUiLCAiaWlpIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1pc285NjYwLWltYWdlIiwgImlzbyIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtam1vbCIsICJqbXoiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LWtjaGFydCIsICJjaHJ0Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1raWxsdXN0cmF0b3IiLCAia2lsIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1rb2FuIiwgInNrcCIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gta29hbiIsICJza2QiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LWtvYW4iLCAic2t0Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1rb2FuIiwgInNrbSIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gta3ByZXNlbnRlciIsICJrcHIiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LWtwcmVzZW50ZXIiLCAia3B0Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1rc3ByZWFkIiwgImtzcCIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gta3dvcmQiLCAia3dkIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1rd29yZCIsICJrd3QiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LWxhdGV4IiwgImxhdGV4Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1saGEiLCAibGhhIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1semgiLCAibHpoIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1sengiLCAibHp4Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1tYWtlciIsICJmcm0iKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LW1ha2VyIiwgIm1ha2VyIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1tYWtlciIsICJmcmFtZSIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtbWFrZXIiLCAiZmIiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LW1ha2VyIiwgImJvb2siKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LW1ha2VyIiwgImZiZG9jIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1taWYiLCAibWlmIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1tcy13bWQiLCAid21kIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1tcy13bXoiLCAid216Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1tc2kiLCAibXNpIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1ucy1wcm94eS1hdXRvY29uZmlnIiwgInBhYyIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtbndjIiwgIm53YyIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtb2JqZWN0IiwgIm8iKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LW96LWFwcGxpY2F0aW9uIiwgIm96YSIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtcGtjczEyIiwgInAxMiIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtcGtjczctY2VydHJlcXJlc3AiLCAicDdyIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1wa2NzNy1jcmwiLCAiY3JsIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1xdWlja3RpbWVwbGF5ZXIiLCAicXRsIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1zaGFyIiwgInNoYXIiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LXNob2Nrd2F2ZS1mbGFzaCIsICJzd2YiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LXN0dWZmaXQiLCAic2l0Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC1zdjRjcGlvIiwgInN2NGNwaW8iKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LXN2NGNyYyIsICJzdjRjcmMiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LXRhciIsICJ0YXIiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LXRleGluZm8iLCAidGV4aW5mbyIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtdGV4aW5mbyIsICJ0ZXhpIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC10cm9mZiIsICJ0Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC10cm9mZiIsICJyb2ZmIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC10cm9mZi1tYW4iLCAibWFuIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC11c3RhciIsICJ1c3RhciIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtd2Fpcy1zb3VyY2UiLCAic3JjIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC13aW5neiIsICJ3eiIpOworICAgICAgICBhZGQoImFwcGxpY2F0aW9uL3gtd2ViYXJjaGl2ZSIsICJ3ZWJhcmNoaXZlIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC13ZWJhcmNoaXZlLXhtbCIsICJ3ZWJhcmNoaXZleG1sIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC14NTA5LWNhLWNlcnQiLCAiY3J0Iik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veC14NTA5LXVzZXItY2VydCIsICJjcnQiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LXhjZiIsICJ4Y2YiKTsKKyAgICAgICAgYWRkKCJhcHBsaWNhdGlvbi94LXhmaWciLCAiZmlnIik7CisgICAgICAgIGFkZCgiYXBwbGljYXRpb24veGh0bWwreG1sIiwgInhodG1sIik7CisgICAgICAgIGFkZCgiYXVkaW8vM2dwcCIsICIzZ3BwIik7CisgICAgICAgIGFkZCgiYXVkaW8vYW1yIiwgImFtciIpOworICAgICAgICBhZGQoImF1ZGlvL2Jhc2ljIiwgInNuZCIpOworICAgICAgICBhZGQoImF1ZGlvL21pZGkiLCAibWlkIik7CisgICAgICAgIGFkZCgiYXVkaW8vbWlkaSIsICJtaWRpIik7CisgICAgICAgIGFkZCgiYXVkaW8vbWlkaSIsICJrYXIiKTsKKyAgICAgICAgYWRkKCJhdWRpby9taWRpIiwgInhtZiIpOworICAgICAgICBhZGQoImF1ZGlvL21vYmlsZS14bWYiLCAibXhtZiIpOworICAgICAgICBhZGQoImF1ZGlvL21wZWciLCAibXBnYSIpOworICAgICAgICBhZGQoImF1ZGlvL21wZWciLCAibXBlZ2EiKTsKKyAgICAgICAgYWRkKCJhdWRpby9tcGVnIiwgIm1wMiIpOworICAgICAgICBhZGQoImF1ZGlvL21wZWciLCAibXAzIik7CisgICAgICAgIGFkZCgiYXVkaW8vbXBlZyIsICJtNGEiKTsKKyAgICAgICAgYWRkKCJhdWRpby9tcGVndXJsIiwgIm0zdSIpOworICAgICAgICBhZGQoImF1ZGlvL3Bycy5zaWQiLCAic2lkIik7CisgICAgICAgIGFkZCgiYXVkaW8veC1haWZmIiwgImFpZiIpOworICAgICAgICBhZGQoImF1ZGlvL3gtYWlmZiIsICJhaWZmIik7CisgICAgICAgIGFkZCgiYXVkaW8veC1haWZmIiwgImFpZmMiKTsKKyAgICAgICAgYWRkKCJhdWRpby94LWdzbSIsICJnc20iKTsKKyAgICAgICAgYWRkKCJhdWRpby94LW1wZWd1cmwiLCAibTN1Iik7CisgICAgICAgIGFkZCgiYXVkaW8veC1tcy13bWEiLCAid21hIik7CisgICAgICAgIGFkZCgiYXVkaW8veC1tcy13YXgiLCAid2F4Iik7CisgICAgICAgIGFkZCgiYXVkaW8veC1wbi1yZWFsYXVkaW8iLCAicmEiKTsKKyAgICAgICAgYWRkKCJhdWRpby94LXBuLXJlYWxhdWRpbyIsICJybSIpOworICAgICAgICBhZGQoImF1ZGlvL3gtcG4tcmVhbGF1ZGlvIiwgInJhbSIpOworICAgICAgICBhZGQoImF1ZGlvL3gtcmVhbGF1ZGlvIiwgInJhIik7CisgICAgICAgIGFkZCgiYXVkaW8veC1zY3BscyIsICJwbHMiKTsKKyAgICAgICAgYWRkKCJhdWRpby94LXNkMiIsICJzZDIiKTsKKyAgICAgICAgYWRkKCJhdWRpby94LXdhdiIsICJ3YXYiKTsKKyAgICAgICAgYWRkKCJpbWFnZS9ibXAiLCAiYm1wIik7CisgICAgICAgIGFkZCgiaW1hZ2UvZ2lmIiwgImdpZiIpOworICAgICAgICBhZGQoImltYWdlL2ljbyIsICJjdXIiKTsKKyAgICAgICAgYWRkKCJpbWFnZS9pY28iLCAiaWNvIik7CisgICAgICAgIGFkZCgiaW1hZ2UvaWVmIiwgImllZiIpOworICAgICAgICBhZGQoImltYWdlL2pwZWciLCAianBlZyIpOworICAgICAgICBhZGQoImltYWdlL2pwZWciLCAianBnIik7CisgICAgICAgIGFkZCgiaW1hZ2UvanBlZyIsICJqcGUiKTsKKyAgICAgICAgYWRkKCJpbWFnZS9wY3giLCAicGN4Iik7CisgICAgICAgIGFkZCgiaW1hZ2UvcG5nIiwgInBuZyIpOworICAgICAgICBhZGQoImltYWdlL3N2Zyt4bWwiLCAic3ZnIik7CisgICAgICAgIGFkZCgiaW1hZ2Uvc3ZnK3htbCIsICJzdmd6Iik7CisgICAgICAgIGFkZCgiaW1hZ2UvdGlmZiIsICJ0aWZmIik7CisgICAgICAgIGFkZCgiaW1hZ2UvdGlmZiIsICJ0aWYiKTsKKyAgICAgICAgYWRkKCJpbWFnZS92bmQuZGp2dSIsICJkanZ1Iik7CisgICAgICAgIGFkZCgiaW1hZ2Uvdm5kLmRqdnUiLCAiZGp2Iik7CisgICAgICAgIGFkZCgiaW1hZ2Uvdm5kLndhcC53Ym1wIiwgIndibXAiKTsKKyAgICAgICAgYWRkKCJpbWFnZS94LWNtdS1yYXN0ZXIiLCAicmFzIik7CisgICAgICAgIGFkZCgiaW1hZ2UveC1jb3JlbGRyYXciLCAiY2RyIik7CisgICAgICAgIGFkZCgiaW1hZ2UveC1jb3JlbGRyYXdwYXR0ZXJuIiwgInBhdCIpOworICAgICAgICBhZGQoImltYWdlL3gtY29yZWxkcmF3dGVtcGxhdGUiLCAiY2R0Iik7CisgICAgICAgIGFkZCgiaW1hZ2UveC1jb3JlbHBob3RvcGFpbnQiLCAiY3B0Iik7CisgICAgICAgIGFkZCgiaW1hZ2UveC1pY29uIiwgImljbyIpOworICAgICAgICBhZGQoImltYWdlL3gtamciLCAiYXJ0Iik7CisgICAgICAgIGFkZCgiaW1hZ2UveC1qbmciLCAiam5nIik7CisgICAgICAgIGFkZCgiaW1hZ2UveC1tcy1ibXAiLCAiYm1wIik7CisgICAgICAgIGFkZCgiaW1hZ2UveC1waG90b3Nob3AiLCAicHNkIik7CisgICAgICAgIGFkZCgiaW1hZ2UveC1wb3J0YWJsZS1hbnltYXAiLCAicG5tIik7CisgICAgICAgIGFkZCgiaW1hZ2UveC1wb3J0YWJsZS1iaXRtYXAiLCAicGJtIik7CisgICAgICAgIGFkZCgiaW1hZ2UveC1wb3J0YWJsZS1ncmF5bWFwIiwgInBnbSIpOworICAgICAgICBhZGQoImltYWdlL3gtcG9ydGFibGUtcGl4bWFwIiwgInBwbSIpOworICAgICAgICBhZGQoImltYWdlL3gtcmdiIiwgInJnYiIpOworICAgICAgICBhZGQoImltYWdlL3gteGJpdG1hcCIsICJ4Ym0iKTsKKyAgICAgICAgYWRkKCJpbWFnZS94LXhwaXhtYXAiLCAieHBtIik7CisgICAgICAgIGFkZCgiaW1hZ2UveC14d2luZG93ZHVtcCIsICJ4d2QiKTsKKyAgICAgICAgYWRkKCJtb2RlbC9pZ2VzIiwgImlncyIpOworICAgICAgICBhZGQoIm1vZGVsL2lnZXMiLCAiaWdlcyIpOworICAgICAgICBhZGQoIm1vZGVsL21lc2giLCAibXNoIik7CisgICAgICAgIGFkZCgibW9kZWwvbWVzaCIsICJtZXNoIik7CisgICAgICAgIGFkZCgibW9kZWwvbWVzaCIsICJzaWxvIik7CisgICAgICAgIGFkZCgidGV4dC9jYWxlbmRhciIsICJpY3MiKTsKKyAgICAgICAgYWRkKCJ0ZXh0L2NhbGVuZGFyIiwgImljeiIpOworICAgICAgICBhZGQoInRleHQvY29tbWEtc2VwYXJhdGVkLXZhbHVlcyIsICJjc3YiKTsKKyAgICAgICAgYWRkKCJ0ZXh0L2NzcyIsICJjc3MiKTsKKyAgICAgICAgYWRkKCJ0ZXh0L2h0bWwiLCAiaHRtIik7CisgICAgICAgIGFkZCgidGV4dC9odG1sIiwgImh0bWwiKTsKKyAgICAgICAgYWRkKCJ0ZXh0L2gzMjMiLCAiMzIzIik7CisgICAgICAgIGFkZCgidGV4dC9pdWxzIiwgInVscyIpOworICAgICAgICBhZGQoInRleHQvbWF0aG1sIiwgIm1tbCIpOworICAgICAgICAvLyBhZGQgIi50eHQiIGZpcnN0IHNvIGl0IHdpbGwgYmUgdGhlIGRlZmF1bHQgZm9yIEV4dGVuc2lvbkZyb21NaW1lVHlwZQorICAgICAgICBhZGQoInRleHQvcGxhaW4iLCAidHh0Iik7CisgICAgICAgIGFkZCgidGV4dC9wbGFpbiIsICJhc2MiKTsKKyAgICAgICAgYWRkKCJ0ZXh0L3BsYWluIiwgInRleHQiKTsKKyAgICAgICAgYWRkKCJ0ZXh0L3BsYWluIiwgImRpZmYiKTsKKyAgICAgICAgYWRkKCJ0ZXh0L3BsYWluIiwgInBvIik7ICAgICAvLyByZXNlcnZlICJwb3QiIGZvciB2bmQubXMtcG93ZXJwb2ludAorICAgICAgICBhZGQoInRleHQvcmljaHRleHQiLCAicnR4Iik7CisgICAgICAgIGFkZCgidGV4dC9ydGYiLCAicnRmIik7CisgICAgICAgIGFkZCgidGV4dC90ZXhtYWNzIiwgInRzIik7CisgICAgICAgIGFkZCgidGV4dC90ZXh0IiwgInBocHMiKTsKKyAgICAgICAgYWRkKCJ0ZXh0L3RhYi1zZXBhcmF0ZWQtdmFsdWVzIiwgInRzdiIpOworICAgICAgICBhZGQoInRleHQveG1sIiwgInhtbCIpOworICAgICAgICBhZGQoInRleHQveC1iaWJ0ZXgiLCAiYmliIik7CisgICAgICAgIGFkZCgidGV4dC94LWJvbyIsICJib28iKTsKKyAgICAgICAgYWRkKCJ0ZXh0L3gtYysraGRyIiwgImgrKyIpOworICAgICAgICBhZGQoInRleHQveC1jKytoZHIiLCAiaHBwIik7CisgICAgICAgIGFkZCgidGV4dC94LWMrK2hkciIsICJoeHgiKTsKKyAgICAgICAgYWRkKCJ0ZXh0L3gtYysraGRyIiwgImhoIik7CisgICAgICAgIGFkZCgidGV4dC94LWMrK3NyYyIsICJjKysiKTsKKyAgICAgICAgYWRkKCJ0ZXh0L3gtYysrc3JjIiwgImNwcCIpOworICAgICAgICBhZGQoInRleHQveC1jKytzcmMiLCAiY3h4Iik7CisgICAgICAgIGFkZCgidGV4dC94LWNoZHIiLCAiaCIpOworICAgICAgICBhZGQoInRleHQveC1jb21wb25lbnQiLCAiaHRjIik7CisgICAgICAgIGFkZCgidGV4dC94LWNzaCIsICJjc2giKTsKKyAgICAgICAgYWRkKCJ0ZXh0L3gtY3NyYyIsICJjIik7CisgICAgICAgIGFkZCgidGV4dC94LWRzcmMiLCAiZCIpOworICAgICAgICBhZGQoInRleHQveC1oYXNrZWxsIiwgImhzIik7CisgICAgICAgIGFkZCgidGV4dC94LWphdmEiLCAiamF2YSIpOworICAgICAgICBhZGQoInRleHQveC1saXRlcmF0ZS1oYXNrZWxsIiwgImxocyIpOworICAgICAgICBhZGQoInRleHQveC1tb2MiLCAibW9jIik7CisgICAgICAgIGFkZCgidGV4dC94LXBhc2NhbCIsICJwIik7CisgICAgICAgIGFkZCgidGV4dC94LXBhc2NhbCIsICJwYXMiKTsKKyAgICAgICAgYWRkKCJ0ZXh0L3gtcGNzLWdjZCIsICJnY2QiKTsKKyAgICAgICAgYWRkKCJ0ZXh0L3gtc2V0ZXh0IiwgImV0eCIpOworICAgICAgICBhZGQoInRleHQveC10Y2wiLCAidGNsIik7CisgICAgICAgIGFkZCgidGV4dC94LXRleCIsICJ0ZXgiKTsKKyAgICAgICAgYWRkKCJ0ZXh0L3gtdGV4IiwgImx0eCIpOworICAgICAgICBhZGQoInRleHQveC10ZXgiLCAic3R5Iik7CisgICAgICAgIGFkZCgidGV4dC94LXRleCIsICJjbHMiKTsKKyAgICAgICAgYWRkKCJ0ZXh0L3gtdmNhbGVuZGFyIiwgInZjcyIpOworICAgICAgICBhZGQoInRleHQveC12Y2FyZCIsICJ2Y2YiKTsKKyAgICAgICAgYWRkKCJ2aWRlby8zZ3BwIiwgIjNncHAiKTsKKyAgICAgICAgYWRkKCJ2aWRlby8zZ3BwIiwgIjNncCIpOworICAgICAgICBhZGQoInZpZGVvLzNncHAiLCAiM2cyIik7CisgICAgICAgIGFkZCgidmlkZW8vZGwiLCAiZGwiKTsKKyAgICAgICAgYWRkKCJ2aWRlby9kdiIsICJkaWYiKTsKKyAgICAgICAgYWRkKCJ2aWRlby9kdiIsICJkdiIpOworICAgICAgICBhZGQoInZpZGVvL2ZsaSIsICJmbGkiKTsKKyAgICAgICAgYWRkKCJ2aWRlby9tNHYiLCAibTR2Iik7CisgICAgICAgIGFkZCgidmlkZW8vbXBlZyIsICJtcGVnIik7CisgICAgICAgIGFkZCgidmlkZW8vbXBlZyIsICJtcGciKTsKKyAgICAgICAgYWRkKCJ2aWRlby9tcGVnIiwgIm1wZSIpOworICAgICAgICBhZGQoInZpZGVvL21wNCIsICJtcDQiKTsKKyAgICAgICAgYWRkKCJ2aWRlby9tcGVnIiwgIlZPQiIpOworICAgICAgICBhZGQoInZpZGVvL3F1aWNrdGltZSIsICJxdCIpOworICAgICAgICBhZGQoInZpZGVvL3F1aWNrdGltZSIsICJtb3YiKTsKKyAgICAgICAgYWRkKCJ2aWRlby92bmQubXBlZ3VybCIsICJteHUiKTsKKyAgICAgICAgYWRkKCJ2aWRlby94LWxhLWFzZiIsICJsc2YiKTsKKyAgICAgICAgYWRkKCJ2aWRlby94LWxhLWFzZiIsICJsc3giKTsKKyAgICAgICAgYWRkKCJ2aWRlby94LW1uZyIsICJtbmciKTsKKyAgICAgICAgYWRkKCJ2aWRlby94LW1zLWFzZiIsICJhc2YiKTsKKyAgICAgICAgYWRkKCJ2aWRlby94LW1zLWFzZiIsICJhc3giKTsKKyAgICAgICAgYWRkKCJ2aWRlby94LW1zLXdtIiwgIndtIik7CisgICAgICAgIGFkZCgidmlkZW8veC1tcy13bXYiLCAid212Iik7CisgICAgICAgIGFkZCgidmlkZW8veC1tcy13bXgiLCAid214Iik7CisgICAgICAgIGFkZCgidmlkZW8veC1tcy13dngiLCAid3Z4Iik7CisgICAgICAgIGFkZCgidmlkZW8veC1tc3ZpZGVvIiwgImF2aSIpOworICAgICAgICBhZGQoInZpZGVvL3gtc2dpLW1vdmllIiwgIm1vdmllIik7CisgICAgICAgIGFkZCgieC1jb25mZXJlbmNlL3gtY29vbHRhbGsiLCAiaWNlIik7CisgICAgICAgIGFkZCgieC1lcG9jL3gtc2lzeC1hcHAiLCAic2lzeCIpOworICAgICAgICBhcHBseU92ZXJyaWRlcygpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYWRkKFN0cmluZyBtaW1lVHlwZSwgU3RyaW5nIGV4dGVuc2lvbikgeworICAgICAgICAvLworICAgICAgICAvLyBpZiB3ZSBoYXZlIGFuIGV4aXN0aW5nIHggLS0+IHkgbWFwcGluZywgd2UgZG8gbm90IHdhbnQgdG8KKyAgICAgICAgLy8gb3ZlcnJpZGUgaXQgd2l0aCBhbm90aGVyIG1hcHBpbmcgeCAtLT4gPworICAgICAgICAvLyB0aGlzIGlzIG1vc3RseSBiZWNhdXNlIG9mIHRoZSB3YXkgdGhlIG1pbWUtdHlwZSBtYXAgYmVsb3cKKyAgICAgICAgLy8gaXMgY29uc3RydWN0ZWQgKGlmIGEgbWltZSB0eXBlIG1hcHMgdG8gc2V2ZXJhbCBleHRlbnNpb25zCisgICAgICAgIC8vIHRoZSBmaXJzdCBleHRlbnNpb24gaXMgY29uc2lkZXJlZCB0aGUgbW9zdCBwb3B1bGFyIGFuZCBpcworICAgICAgICAvLyBhZGRlZCBmaXJzdDsgd2UgZG8gbm90IHdhbnQgdG8gb3ZlcndyaXRlIGl0IGxhdGVyKS4KKyAgICAgICAgLy8KKyAgICAgICAgaWYgKCFtaW1lVHlwZVRvRXh0ZW5zaW9uTWFwLmNvbnRhaW5zS2V5KG1pbWVUeXBlKSkgeworICAgICAgICAgICAgbWltZVR5cGVUb0V4dGVuc2lvbk1hcC5wdXQobWltZVR5cGUsIGV4dGVuc2lvbik7CisgICAgICAgIH0KKyAgICAgICAgZXh0ZW5zaW9uVG9NaW1lVHlwZU1hcC5wdXQoZXh0ZW5zaW9uLCBtaW1lVHlwZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgSW5wdXRTdHJlYW0gZ2V0Q29udGVudFR5cGVzUHJvcGVydGllc1N0cmVhbSgpIHsKKyAgICAgICAgLy8gVXNlciBvdmVycmlkZT8KKyAgICAgICAgU3RyaW5nIHVzZXJUYWJsZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiY29udGVudC50eXBlcy51c2VyLnRhYmxlIik7CisgICAgICAgIGlmICh1c2VyVGFibGUgIT0gbnVsbCkgeworICAgICAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUodXNlclRhYmxlKTsKKyAgICAgICAgICAgIGlmIChmLmV4aXN0cygpKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWxlSW5wdXRTdHJlYW0oZik7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFN0YW5kYXJkIGxvY2F0aW9uPworICAgICAgICBGaWxlIGYgPSBuZXcgRmlsZShTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaG9tZSIpLCAibGliIiArIEZpbGUuc2VwYXJhdG9yICsgImNvbnRlbnQtdHlwZXMucHJvcGVydGllcyIpOworICAgICAgICBpZiAoZi5leGlzdHMoKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEZpbGVJbnB1dFN0cmVhbShmKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgaXNuJ3Qgd2hhdCB0aGUgUkkgZG9lcy4gVGhlIFJJIGRvZXNuJ3QgaGF2ZSBoYXJkLWNvZGVkIGRlZmF1bHRzLCBzbyBzdXBwbHlpbmcgeW91cgorICAgICAqIG93biAiY29udGVudC50eXBlcy51c2VyLnRhYmxlIiBtZWFucyB5b3UgZG9uJ3QgZ2V0IGFueSBvZiB0aGUgYnVpbHQtaW5zLCBhbmQgdGhlIGJ1aWx0LWlucworICAgICAqIGNvbWUgZnJvbSAiJEpBVkFfSE9NRS9saWIvY29udGVudC10eXBlcy5wcm9wZXJ0aWVzIi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGFwcGx5T3ZlcnJpZGVzKCkgeworICAgICAgICAvLyBHZXQgdGhlIGFwcHJvcHJpYXRlIElucHV0U3RyZWFtIHRvIHJlYWQgb3ZlcnJpZGVzIGZyb20sIGlmIGFueS4KKyAgICAgICAgSW5wdXRTdHJlYW0gc3RyZWFtID0gZ2V0Q29udGVudFR5cGVzUHJvcGVydGllc1N0cmVhbSgpOworICAgICAgICBpZiAoc3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIFJlYWQgdGhlIHByb3BlcnRpZXMgZmlsZS4uLgorICAgICAgICAgICAgICAgIFByb3BlcnRpZXMgb3ZlcnJpZGVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgICAgICBvdmVycmlkZXMubG9hZChzdHJlYW0pOworICAgICAgICAgICAgICAgIC8vIEFuZCB0cmFuc2xhdGUgaXRzIG1hcHBpbmcgdG8gb3Vycy4uLgorICAgICAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PE9iamVjdCwgT2JqZWN0PiBlbnRyeSA6IG92ZXJyaWRlcy5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBleHRlbnNpb24gPSAoU3RyaW5nKSBlbnRyeS5nZXRLZXkoKTsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1pbWVUeXBlID0gKFN0cmluZykgZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgICAgICAgICAgYWRkKG1pbWVUeXBlLCBleHRlbnNpb24pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgc3RyZWFtLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgTWltZVV0aWxzKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gTUlNRSB0eXBlIGhhcyBhbiBlbnRyeSBpbiB0aGUgbWFwLgorICAgICAqIEBwYXJhbSBtaW1lVHlwZSBBIE1JTUUgdHlwZSAoaS5lLiB0ZXh0L3BsYWluKQorICAgICAqIEByZXR1cm4gVHJ1ZSBpZmYgdGhlcmUgaXMgYSBtaW1lVHlwZSBlbnRyeSBpbiB0aGUgbWFwLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBoYXNNaW1lVHlwZShTdHJpbmcgbWltZVR5cGUpIHsKKyAgICAgICAgaWYgKG1pbWVUeXBlID09IG51bGwgfHwgbWltZVR5cGUuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG1pbWVUeXBlVG9FeHRlbnNpb25NYXAuY29udGFpbnNLZXkobWltZVR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIE1JTUUgdHlwZSBmb3IgdGhlIGdpdmVuIGV4dGVuc2lvbi4KKyAgICAgKiBAcGFyYW0gZXh0ZW5zaW9uIEEgZmlsZSBleHRlbnNpb24gd2l0aG91dCB0aGUgbGVhZGluZyAnLicKKyAgICAgKiBAcmV0dXJuIFRoZSBNSU1FIHR5cGUgZm9yIHRoZSBnaXZlbiBleHRlbnNpb24gb3IgbnVsbCBpZmYgdGhlcmUgaXMgbm9uZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBndWVzc01pbWVUeXBlRnJvbUV4dGVuc2lvbihTdHJpbmcgZXh0ZW5zaW9uKSB7CisgICAgICAgIGlmIChleHRlbnNpb24gPT0gbnVsbCB8fCBleHRlbnNpb24uaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZXh0ZW5zaW9uVG9NaW1lVHlwZU1hcC5nZXQoZXh0ZW5zaW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIGV4dGVuc2lvbiBoYXMgYSByZWdpc3RlcmVkIE1JTUUgdHlwZS4KKyAgICAgKiBAcGFyYW0gZXh0ZW5zaW9uIEEgZmlsZSBleHRlbnNpb24gd2l0aG91dCB0aGUgbGVhZGluZyAnLicKKyAgICAgKiBAcmV0dXJuIFRydWUgaWZmIHRoZXJlIGlzIGFuIGV4dGVuc2lvbiBlbnRyeSBpbiB0aGUgbWFwLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBoYXNFeHRlbnNpb24oU3RyaW5nIGV4dGVuc2lvbikgeworICAgICAgICBpZiAoZXh0ZW5zaW9uID09IG51bGwgfHwgZXh0ZW5zaW9uLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBleHRlbnNpb25Ub01pbWVUeXBlTWFwLmNvbnRhaW5zS2V5KGV4dGVuc2lvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmVnaXN0ZXJlZCBleHRlbnNpb24gZm9yIHRoZSBnaXZlbiBNSU1FIHR5cGUuIE5vdGUgdGhhdCBzb21lCisgICAgICogTUlNRSB0eXBlcyBtYXAgdG8gbXVsdGlwbGUgZXh0ZW5zaW9ucy4gVGhpcyBjYWxsIHdpbGwgcmV0dXJuIHRoZSBtb3N0CisgICAgICogY29tbW9uIGV4dGVuc2lvbiBmb3IgdGhlIGdpdmVuIE1JTUUgdHlwZS4KKyAgICAgKiBAcGFyYW0gbWltZVR5cGUgQSBNSU1FIHR5cGUgKGkuZS4gdGV4dC9wbGFpbikKKyAgICAgKiBAcmV0dXJuIFRoZSBleHRlbnNpb24gZm9yIHRoZSBnaXZlbiBNSU1FIHR5cGUgb3IgbnVsbCBpZmYgdGhlcmUgaXMgbm9uZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBndWVzc0V4dGVuc2lvbkZyb21NaW1lVHlwZShTdHJpbmcgbWltZVR5cGUpIHsKKyAgICAgICAgaWYgKG1pbWVUeXBlID09IG51bGwgfHwgbWltZVR5cGUuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbWltZVR5cGVUb0V4dGVuc2lvbk1hcC5nZXQobWltZVR5cGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9SYXdTb2NrZXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9SYXdTb2NrZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYjI5ZmIwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L1Jhd1NvY2tldC5qYXZhCkBAIC0wLDAgKzEsMTI3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLm5ldDsKKworaW1wb3J0IGRhbHZpay5zeXN0ZW0uQ2xvc2VHdWFyZDsKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuU29ja2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgbGliY29yZS5pby5Jb0JyaWRnZTsKKworLyoqCisgKiBUaGlzIGNsYXNzIGFsbG93cyByYXcgTDIgcGFja2V0cyB0byBiZSBzZW50IGFuZCByZWNlaXZlZCB2aWEgdGhlCisgKiBzcGVjaWZpZWQgbmV0d29yayBpbnRlcmZhY2UuICBUaGUgcmVjZWl2ZS1zaWRlIGltcGxlbWVudGF0aW9uIGlzCisgKiByZXN0cmljdGVkIHRvIFVEUCBwYWNrZXRzIGZvciBlZmZpY2llbmN5LgorICoKKyAqIEBoaWRlCisgKi8KK3B1YmxpYyBjbGFzcyBSYXdTb2NrZXQgaW1wbGVtZW50cyBDbG9zZWFibGUgeworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIGNyZWF0ZShGaWxlRGVzY3JpcHRvciBmZCwgU3RyaW5nIGludGVyZmFjZU5hbWUpCisgICAgICAgICAgICB0aHJvd3MgU29ja2V0RXhjZXB0aW9uOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgc2VuZFBhY2tldChGaWxlRGVzY3JpcHRvciBmZCwKKyAgICAgICAgU3RyaW5nIGludGVyZmFjZU5hbWUsIGJ5dGVbXSBkZXN0TWFjLCBieXRlW10gcGFja2V0LCBpbnQgb2Zmc2V0LAorICAgICAgICBpbnQgYnl0ZUNvdW50KTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IHJlY3ZQYWNrZXQoRmlsZURlc2NyaXB0b3IgZmQsIGJ5dGVbXSBwYWNrZXQsCisgICAgICAgIGludCBvZmZzZXQsIGludCBieXRlQ291bnQsIGludCBkZXN0UG9ydCwgaW50IHRpbWVvdXRNaWxsaXMpOworCisgICAgcHJpdmF0ZSBmaW5hbCBGaWxlRGVzY3JpcHRvciBmZDsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBtSW50ZXJmYWNlTmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIENsb3NlR3VhcmQgZ3VhcmQgPSBDbG9zZUd1YXJkLmdldCgpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIHNvY2tldCBvbiB0aGUgc3BlY2lmaWVkIGludGVyZmFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmF3U29ja2V0KFN0cmluZyBpbnRlcmZhY2VOYW1lKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgbUludGVyZmFjZU5hbWUgPSBpbnRlcmZhY2VOYW1lOworICAgICAgICBmZCA9IG5ldyBGaWxlRGVzY3JpcHRvcigpOworICAgICAgICBjcmVhdGUoZmQsIG1JbnRlcmZhY2VOYW1lKTsKKyAgICAgICAgZ3VhcmQub3BlbigiY2xvc2UiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHJhdyBwYWNrZXQgaW50byB0aGUgc3BlY2lmaWVkIGJ1ZmZlciwgd2l0aCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgdGltZW91dC4gIFBhY2tldHMgbm90IGRlc3RpbmVkIGZvciB0aGUgZGVzaXJlZCBVRFAKKyAgICAgKiBwb3J0IGFyZSBkaXNjYXJkZWQuICBSZXR1cm5zIHRoZSBsZW5ndGggYWN0dWFsbHkgcmVhZC4gIE5vCisgICAgICogaW5kaWNhdGlvbiBvZiBvdmVyZmxvdyBpcyBzaWduYWxlZC4gIFRoZSBwYWNrZXQgZGF0YSB3aWxsIHN0YXJ0CisgICAgICogYXQgdGhlIElQIGhlYWRlciAoRXRoZXJuZXRJSSBkZXN0L3NvdXJjZS90eXBlIGhlYWRlcnMgYXJlCisgICAgICogcmVtb3ZlZCkuCisgICAgICovCisgICAgcHVibGljIGludCByZWFkKGJ5dGVbXSBwYWNrZXQsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQsIGludCBkZXN0UG9ydCwKKyAgICAgICAgaW50IHRpbWVvdXRNaWxsaXMpIHsKKyAgICAgICAgaWYgKHBhY2tldCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInBhY2tldCA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChwYWNrZXQubGVuZ3RoLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisKKyAgICAgICAgaWYgKGRlc3RQb3J0IDwgMCB8fCBkZXN0UG9ydCA+IDY1NTM1KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQb3J0IG91dCBvZiByYW5nZTogIgorICAgICAgICAgICAgICAgICsgZGVzdFBvcnQpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHJlY3ZQYWNrZXQoZmQsIHBhY2tldCwgb2Zmc2V0LCBieXRlQ291bnQsIGRlc3RQb3J0LAorICAgICAgICAgICAgdGltZW91dE1pbGxpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGEgcmF3IHBhY2tldCB0byB0aGUgZGVzaXJlZCBpbnRlcmZhY2UuICBBIEwyIGhlYWRlciB3aWxsCisgICAgICogYmUgYWRkZWQgd2hpY2ggaW5jbHVkZXMgdGhlIHNwZWNpZmllZCBkZXN0aW5hdGlvbiBhZGRyZXNzLCBvdXIKKyAgICAgKiBzb3VyY2UgTUFDLCBhbmQgdGhlIElQIHR5cGUuICBUaGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvcgorICAgICAqIGNvbXB1dGluZyBjb3JyZWN0IElQLWhlYWRlciBhbmQgcGF5bG9hZCBjaGVja3N1bXMuCisgICAgICovCisgICAgcHVibGljIGludCB3cml0ZShieXRlW10gZGVzdE1hYywgYnl0ZVtdIHBhY2tldCwgaW50IG9mZnNldCwgaW50IGJ5dGVDb3VudCkgeworICAgICAgICBpZiAoZGVzdE1hYyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImRlc3RNYWMgPT0gbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHBhY2tldCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInBhY2tldCA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChwYWNrZXQubGVuZ3RoLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisKKyAgICAgICAgaWYgKGRlc3RNYWMubGVuZ3RoICE9IDYpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk1BQyBsZW5ndGggbXVzdCBiZSA2OiAiCisgICAgICAgICAgICAgICAgKyBkZXN0TWFjLmxlbmd0aCk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gc2VuZFBhY2tldChmZCwgbUludGVyZmFjZU5hbWUsIGRlc3RNYWMsIHBhY2tldCwgb2Zmc2V0LAorICAgICAgICAgICAgYnl0ZUNvdW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhlIHNvY2tldC4gIEFmdGVyIHRoaXMgbWV0aG9kIGlzIGludm9rZWQsIHN1YnNlcXVlbnQKKyAgICAgKiByZWFkL3dyaXRlIG9wZXJhdGlvbnMgd2lsbCBmYWlsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZ3VhcmQuY2xvc2UoKTsKKyAgICAgICAgSW9CcmlkZ2UuY2xvc2VTb2NrZXQoZmQpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGd1YXJkICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBndWFyZC53YXJuSWZPcGVuKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjbG9zZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc3VwZXIuZmluYWxpemUoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9VcmlDb2RlYy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L1VyaUNvZGVjLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTExYTAxNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9VcmlDb2RlYy5qYXZhCkBAIC0wLDAgKzEsMjE0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUubmV0OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuVVJJU3ludGF4RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRzOworCisvKioKKyAqIEVuY29kZXMgYW5kIGRlY29kZXMge0Bjb2RlIGFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZH0gY29udGVudC4KKyAqIFN1YmNsYXNzZXMgZGVmaW5lIGV4YWN0bHkgd2hpY2ggY2hhcmFjdGVycyBhcmUgbGVnYWwuCisgKgorICogPHA+QnkgZGVmYXVsdCwgVVRGLTggaXMgdXNlZCB0byBlbmNvZGUgZXNjYXBlZCBjaGFyYWN0ZXJzLiBBIHNpbmdsZSBpbnB1dAorICogY2hhcmFjdGVyIGxpa2UgIlx1MDA4MCIgbWF5IGJlIGVuY29kZWQgdG8gbXVsdGlwbGUgb2N0ZXRzIGxpa2UgJUMyJTgwLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgVXJpQ29kZWMgeworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHtAY29kZSBjfSBkb2VzIG5vdCBuZWVkIHRvIGJlIGVzY2FwZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IGJvb2xlYW4gaXNSZXRhaW5lZChjaGFyIGMpOworCisgICAgLyoqCisgICAgICogVGhyb3dzIGlmIHtAY29kZSBzfSBpcyBpbnZhbGlkIGFjY29yZGluZyB0byB0aGlzIGVuY29kZXIuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFN0cmluZyB2YWxpZGF0ZShTdHJpbmcgdXJpLCBpbnQgc3RhcnQsIGludCBlbmQsIFN0cmluZyBuYW1lKQorICAgICAgICAgICAgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IGVuZDsgKSB7CisgICAgICAgICAgICBjaGFyIGNoID0gdXJpLmNoYXJBdChpKTsKKyAgICAgICAgICAgIGlmICgoY2ggPj0gJ2EnICYmIGNoIDw9ICd6JykKKyAgICAgICAgICAgICAgICAgICAgfHwgKGNoID49ICdBJyAmJiBjaCA8PSAnWicpCisgICAgICAgICAgICAgICAgICAgIHx8IChjaCA+PSAnMCcgJiYgY2ggPD0gJzknKQorICAgICAgICAgICAgICAgICAgICB8fCBpc1JldGFpbmVkKGNoKSkgeworICAgICAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gJyUnKSB7CisgICAgICAgICAgICAgICAgaWYgKGkgKyAyID49IGVuZCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVVJJU3ludGF4RXhjZXB0aW9uKHVyaSwgIkluY29tcGxldGUgJSBzZXF1ZW5jZSBpbiAiICsgbmFtZSwgaSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGludCBkMSA9IGhleFRvSW50KHVyaS5jaGFyQXQoaSArIDEpKTsKKyAgICAgICAgICAgICAgICBpbnQgZDIgPSBoZXhUb0ludCh1cmkuY2hhckF0KGkgKyAyKSk7CisgICAgICAgICAgICAgICAgaWYgKGQxID09IC0xIHx8IGQyID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBVUklTeW50YXhFeGNlcHRpb24odXJpLCAiSW52YWxpZCAlIHNlcXVlbmNlOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyB1cmkuc3Vic3RyaW5nKGksIGkgKyAzKSArICIgaW4gIiArIG5hbWUsIGkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpICs9IDM7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBVUklTeW50YXhFeGNlcHRpb24odXJpLCAiSWxsZWdhbCBjaGFyYWN0ZXIgaW4gIiArIG5hbWUsIGkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB1cmkuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRocm93cyBpZiB7QGNvZGUgc30gY29udGFpbnMgY2hhcmFjdGVycyB0aGF0IGFyZSBub3QgbGV0dGVycywgZGlnaXRzIG9yCisgICAgICogaW4ge0Bjb2RlIGxlZ2FsfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdmFsaWRhdGVTaW1wbGUoU3RyaW5nIHMsIFN0cmluZyBsZWdhbCkKKyAgICAgICAgICAgIHRocm93cyBVUklTeW50YXhFeGNlcHRpb24geworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHMubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgY2hhciBjaCA9IHMuY2hhckF0KGkpOworICAgICAgICAgICAgaWYgKCEoKGNoID49ICdhJyAmJiBjaCA8PSAneicpCisgICAgICAgICAgICAgICAgICAgIHx8IChjaCA+PSAnQScgJiYgY2ggPD0gJ1onKQorICAgICAgICAgICAgICAgICAgICB8fCAoY2ggPj0gJzAnICYmIGNoIDw9ICc5JykKKyAgICAgICAgICAgICAgICAgICAgfHwgbGVnYWwuaW5kZXhPZihjaCkgPiAtMSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVVJJU3ludGF4RXhjZXB0aW9uKHMsICJJbGxlZ2FsIGNoYXJhY3RlciIsIGkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlcyB7QGNvZGUgc30gYW5kIGFwcGVuZHMgdGhlIHJlc3VsdCB0byB7QGNvZGUgYnVpbGRlcn0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXNQYXJ0aWFsbHlFbmNvZGVkIHRydWUgdG8gZml4IGlucHV0IHRoYXQgaGFzIGFscmVhZHkgYmVlbgorICAgICAqICAgICBwYXJ0aWFsbHkgb3IgZnVsbHkgZW5jb2RlZC4gRm9yIGV4YW1wbGUsIGlucHV0IG9mICJoZWxsbyUyMHdvcmxkIiBpcworICAgICAqICAgICB1bmNoYW5nZWQgd2l0aCBpc1BhcnRpYWxseUVuY29kZWQ9dHJ1ZSBidXQgd291bGQgYmUgZG91YmxlLWVzY2FwZWQgdG8KKyAgICAgKiAgICAgImhlbGxvJTI1MjB3b3JsZCIgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhcHBlbmRFbmNvZGVkKFN0cmluZ0J1aWxkZXIgYnVpbGRlciwgU3RyaW5nIHMsIENoYXJzZXQgY2hhcnNldCwKKyAgICAgICAgICAgIGJvb2xlYW4gaXNQYXJ0aWFsbHlFbmNvZGVkKSB7CisgICAgICAgIGlmIChzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaW50IGVzY2FwZVN0YXJ0ID0gLTE7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcy5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBjaGFyIGMgPSBzLmNoYXJBdChpKTsKKyAgICAgICAgICAgIGlmICgoYyA+PSAnYScgJiYgYyA8PSAneicpCisgICAgICAgICAgICAgICAgICAgIHx8IChjID49ICdBJyAmJiBjIDw9ICdaJykKKyAgICAgICAgICAgICAgICAgICAgfHwgKGMgPj0gJzAnICYmIGMgPD0gJzknKQorICAgICAgICAgICAgICAgICAgICB8fCBpc1JldGFpbmVkKGMpCisgICAgICAgICAgICAgICAgICAgIHx8IChjID09ICclJyAmJiBpc1BhcnRpYWxseUVuY29kZWQpKSB7CisgICAgICAgICAgICAgICAgaWYgKGVzY2FwZVN0YXJ0ICE9IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIGFwcGVuZEhleChidWlsZGVyLCBzLnN1YnN0cmluZyhlc2NhcGVTdGFydCwgaSksIGNoYXJzZXQpOworICAgICAgICAgICAgICAgICAgICBlc2NhcGVTdGFydCA9IC0xOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoYyA9PSAnJScgJiYgaXNQYXJ0aWFsbHlFbmNvZGVkKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgYW4gZW5jb2RlZCAzLWNoYXJhY3RlciBzZXF1ZW5jZSBsaWtlICIlMjAiCisgICAgICAgICAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKHMsIGksIGkgKyAzKTsKKyAgICAgICAgICAgICAgICAgICAgaSArPSAyOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PSAnICcpIHsKKyAgICAgICAgICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoJysnKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZChjKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKGVzY2FwZVN0YXJ0ID09IC0xKSB7CisgICAgICAgICAgICAgICAgZXNjYXBlU3RhcnQgPSBpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChlc2NhcGVTdGFydCAhPSAtMSkgeworICAgICAgICAgICAgYXBwZW5kSGV4KGJ1aWxkZXIsIHMuc3Vic3RyaW5nKGVzY2FwZVN0YXJ0LCBzLmxlbmd0aCgpKSwgY2hhcnNldCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGVuY29kZShTdHJpbmcgcywgQ2hhcnNldCBjaGFyc2V0KSB7CisgICAgICAgIC8vIEd1ZXNzIGEgYml0IGxhcmdlciBmb3IgZW5jb2RlZCBmb3JtCisgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKHMubGVuZ3RoKCkgKyAxNik7CisgICAgICAgIGFwcGVuZEVuY29kZWQoYnVpbGRlciwgcywgY2hhcnNldCwgZmFsc2UpOworICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGFwcGVuZEVuY29kZWQoU3RyaW5nQnVpbGRlciBidWlsZGVyLCBTdHJpbmcgcykgeworICAgICAgICBhcHBlbmRFbmNvZGVkKGJ1aWxkZXIsIHMsIENoYXJzZXRzLlVURl84LCBmYWxzZSk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHZvaWQgYXBwZW5kUGFydGlhbGx5RW5jb2RlZChTdHJpbmdCdWlsZGVyIGJ1aWxkZXIsIFN0cmluZyBzKSB7CisgICAgICAgIGFwcGVuZEVuY29kZWQoYnVpbGRlciwgcywgQ2hhcnNldHMuVVRGXzgsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBjb252ZXJ0UGx1cyB0cnVlIHRvIGNvbnZlcnQgJysnIHRvICcgJy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBkZWNvZGUoU3RyaW5nIHMsIGJvb2xlYW4gY29udmVydFBsdXMsIENoYXJzZXQgY2hhcnNldCkgeworICAgICAgICBpZiAocy5pbmRleE9mKCclJykgPT0gLTEgJiYgKCFjb252ZXJ0UGx1cyB8fCBzLmluZGV4T2YoJysnKSA9PSAtMSkpIHsKKyAgICAgICAgICAgIHJldHVybiBzOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcihzLmxlbmd0aCgpKTsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzLmxlbmd0aCgpOykgeworICAgICAgICAgICAgY2hhciBjID0gcy5jaGFyQXQoaSk7CisgICAgICAgICAgICBpZiAoYyA9PSAnJScpIHsKKyAgICAgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgICAgIGlmIChpICsgMiA+PSBzLmxlbmd0aCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbmNvbXBsZXRlICUgc2VxdWVuY2UgYXQ6ICIgKyBpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpbnQgZDEgPSBoZXhUb0ludChzLmNoYXJBdChpICsgMSkpOworICAgICAgICAgICAgICAgICAgICBpbnQgZDIgPSBoZXhUb0ludChzLmNoYXJBdChpICsgMikpOworICAgICAgICAgICAgICAgICAgICBpZiAoZDEgPT0gLTEgfHwgZDIgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgJSBzZXF1ZW5jZSAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcy5zdWJzdHJpbmcoaSwgaSArIDMpICsgIiBhdCAiICsgaSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgb3V0LndyaXRlKChieXRlKSAoKGQxIDw8IDQpICsgZDIpKTsKKyAgICAgICAgICAgICAgICAgICAgaSArPSAzOworICAgICAgICAgICAgICAgIH0gd2hpbGUgKGkgPCBzLmxlbmd0aCgpICYmIHMuY2hhckF0KGkpID09ICclJyk7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChuZXcgU3RyaW5nKG91dC50b0J5dGVBcnJheSgpLCBjaGFyc2V0KSk7CisgICAgICAgICAgICAgICAgb3V0LnJlc2V0KCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmIChjb252ZXJ0UGx1cyAmJiBjID09ICcrJykgeworICAgICAgICAgICAgICAgICAgICBjID0gJyAnOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGMpOworICAgICAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTGlrZSB7QGxpbmsgQ2hhcmFjdGVyI2RpZ2l0fSwgYnV0IHdpdGhvdXQgc3VwcG9ydCBmb3Igbm9uLUFTQ0lJCisgICAgICogY2hhcmFjdGVycy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgaGV4VG9JbnQoY2hhciBjKSB7CisgICAgICAgIGlmICgnMCcgPD0gYyAmJiBjIDw9ICc5JykgeworICAgICAgICAgICAgcmV0dXJuIGMgLSAnMCc7CisgICAgICAgIH0gZWxzZSBpZiAoJ2EnIDw9IGMgJiYgYyA8PSAnZicpIHsKKyAgICAgICAgICAgIHJldHVybiAxMCArIChjIC0gJ2EnKTsKKyAgICAgICAgfSBlbHNlIGlmICgnQScgPD0gYyAmJiBjIDw9ICdGJykgeworICAgICAgICAgICAgcmV0dXJuIDEwICsgKGMgLSAnQScpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZGVjb2RlKFN0cmluZyBzKSB7CisgICAgICAgIHJldHVybiBkZWNvZGUocywgZmFsc2UsIENoYXJzZXRzLlVURl84KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGFwcGVuZEhleChTdHJpbmdCdWlsZGVyIGJ1aWxkZXIsIFN0cmluZyBzLCBDaGFyc2V0IGNoYXJzZXQpIHsKKyAgICAgICAgZm9yIChieXRlIGIgOiBzLmdldEJ5dGVzKGNoYXJzZXQpKSB7CisgICAgICAgICAgICBhcHBlbmRIZXgoYnVpbGRlciwgYik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGFwcGVuZEhleChTdHJpbmdCdWlsZGVyIHNiLCBieXRlIGIpIHsKKyAgICAgICAgc2IuYXBwZW5kKCclJyk7CisgICAgICAgIHNiLmFwcGVuZChCeXRlLnRvSGV4U3RyaW5nKGIsIHRydWUpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9BYnN0cmFjdEh0dHBJbnB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvQWJzdHJhY3RIdHRwSW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MGY3NmI3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvQWJzdHJhY3RIdHRwSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDEwNyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5uZXQuaHR0cDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5DYWNoZVJlcXVlc3Q7CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworCisvKioKKyAqIEFuIGlucHV0IHN0cmVhbSBmb3IgdGhlIGJvZHkgb2YgYW4gSFRUUCByZXNwb25zZS4KKyAqCisgKiA8cD5TaW5jZSBhIHNpbmdsZSBzb2NrZXQncyBpbnB1dCBzdHJlYW0gbWF5IGJlIHVzZWQgdG8gcmVhZCBtdWx0aXBsZSBIVFRQCisgKiByZXNwb25zZXMgZnJvbSB0aGUgc2FtZSBzZXJ2ZXIsIHN1YmNsYXNzZXMgc2hvdWxkbid0IGNsb3NlIHRoZSBzb2NrZXQgc3RyZWFtLgorICoKKyAqIDxwPkEgc2lkZSBlZmZlY3Qgb2YgcmVhZGluZyBhbiBIVFRQIHJlc3BvbnNlIGlzIHRoYXQgdGhlIHJlc3BvbnNlIGNhY2hlCisgKiBpcyBwb3B1bGF0ZWQuIElmIHRoZSBzdHJlYW0gaXMgY2xvc2VkIGVhcmx5LCB0aGF0IGNhY2hlIGVudHJ5IHdpbGwgYmUKKyAqIGludmFsaWRhdGVkLgorICovCithYnN0cmFjdCBjbGFzcyBBYnN0cmFjdEh0dHBJbnB1dFN0cmVhbSBleHRlbmRzIElucHV0U3RyZWFtIHsKKyAgICBwcm90ZWN0ZWQgZmluYWwgSW5wdXRTdHJlYW0gaW47CisgICAgcHJvdGVjdGVkIGZpbmFsIEh0dHBFbmdpbmUgaHR0cEVuZ2luZTsKKyAgICBwcml2YXRlIGZpbmFsIENhY2hlUmVxdWVzdCBjYWNoZVJlcXVlc3Q7CisgICAgcHJpdmF0ZSBmaW5hbCBPdXRwdXRTdHJlYW0gY2FjaGVCb2R5OworICAgIHByb3RlY3RlZCBib29sZWFuIGNsb3NlZDsKKworICAgIEFic3RyYWN0SHR0cElucHV0U3RyZWFtKElucHV0U3RyZWFtIGluLCBIdHRwRW5naW5lIGh0dHBFbmdpbmUsCisgICAgICAgICAgICBDYWNoZVJlcXVlc3QgY2FjaGVSZXF1ZXN0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLmluID0gaW47CisgICAgICAgIHRoaXMuaHR0cEVuZ2luZSA9IGh0dHBFbmdpbmU7CisKKyAgICAgICAgT3V0cHV0U3RyZWFtIGNhY2hlQm9keSA9IGNhY2hlUmVxdWVzdCAhPSBudWxsID8gY2FjaGVSZXF1ZXN0LmdldEJvZHkoKSA6IG51bGw7CisKKyAgICAgICAgLy8gc29tZSBhcHBzIHJldHVybiBhIG51bGwgYm9keTsgZm9yIGNvbXBhdGliaWxpdHkgd2UgdHJlYXQgdGhhdCBsaWtlIGEgbnVsbCBjYWNoZSByZXF1ZXN0CisgICAgICAgIGlmIChjYWNoZUJvZHkgPT0gbnVsbCkgeworICAgICAgICAgICAgY2FjaGVSZXF1ZXN0ID0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuY2FjaGVCb2R5ID0gY2FjaGVCb2R5OworICAgICAgICB0aGlzLmNhY2hlUmVxdWVzdCA9IGNhY2hlUmVxdWVzdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiByZWFkKCkgaXMgaW1wbGVtZW50ZWQgdXNpbmcgcmVhZChieXRlW10sIGludCwgaW50KSBzbyBzdWJjbGFzc2VzIG9ubHkKKyAgICAgKiBuZWVkIHRvIG92ZXJyaWRlIHRoZSBsYXR0ZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBmaW5hbCBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBTdHJlYW1zLnJlYWRTaW5nbGVCeXRlKHRoaXMpOworICAgIH0KKworICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGNoZWNrTm90Q2xvc2VkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNsb3NlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJzdHJlYW0gY2xvc2VkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBjYWNoZVdyaXRlKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNhY2hlQm9keSAhPSBudWxsKSB7CisgICAgICAgICAgICBjYWNoZUJvZHkud3JpdGUoYnVmZmVyLCBvZmZzZXQsIGNvdW50KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGUgY2FjaGUgZW50cnkgYW5kIG1ha2VzIHRoZSBzb2NrZXQgYXZhaWxhYmxlIGZvciByZXVzZS4gVGhpcworICAgICAqIHNob3VsZCBiZSBpbnZva2VkIHdoZW4gdGhlIGVuZCBvZiB0aGUgYm9keSBoYXMgYmVlbiByZWFjaGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGVuZE9mSW5wdXQoYm9vbGVhbiByZXVzZVNvY2tldCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNhY2hlUmVxdWVzdCAhPSBudWxsKSB7CisgICAgICAgICAgICBjYWNoZUJvZHkuY2xvc2UoKTsKKyAgICAgICAgfQorICAgICAgICBodHRwRW5naW5lLnJlbGVhc2UocmV1c2VTb2NrZXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGxzIGFib3J0IG9uIHRoZSBjYWNoZSBlbnRyeSBhbmQgZGlzY29ubmVjdHMgdGhlIHNvY2tldC4gVGhpcworICAgICAqIHNob3VsZCBiZSBpbnZva2VkIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgY2xvc2VkIHVuZXhwZWN0ZWRseSB0bworICAgICAqIGludmFsaWRhdGUgdGhlIGNhY2hlIGVudHJ5IGFuZCB0byBwcmV2ZW50IHRoZSBIVFRQIGNvbm5lY3Rpb24gZnJvbQorICAgICAqIGJlaW5nIHJldXNlZC4gSFRUUCBtZXNzYWdlcyBhcmUgc2VudCBpbiBzZXJpYWwgc28gd2hlbmV2ZXIgYSBtZXNzYWdlCisgICAgICogY2Fubm90IGJlIHJlYWQgdG8gY29tcGxldGlvbiwgc3Vic2VxdWVudCBtZXNzYWdlcyBjYW5ub3QgYmUgcmVhZAorICAgICAqIGVpdGhlciBhbmQgdGhlIGNvbm5lY3Rpb24gbXVzdCBiZSBkaXNjYXJkZWQuCisgICAgICoKKyAgICAgKiA8cD5BbiBlYXJsaWVyIGltcGxlbWVudGF0aW9uIHNraXBwZWQgdGhlIHJlbWFpbmluZyBieXRlcywgYnV0IHRoaXMKKyAgICAgKiByZXF1aXJlcyB0aGF0IHRoZSBlbnRpcmUgdHJhbnNmZXIgYmUgY29tcGxldGVkLiBJZiB0aGUgaW50ZW50aW9uIHdhcworICAgICAqIHRvIGNhbmNlbCB0aGUgdHJhbnNmZXIsIGNsb3NpbmcgdGhlIGNvbm5lY3Rpb24gaXMgdGhlIG9ubHkgc29sdXRpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgdW5leHBlY3RlZEVuZE9mSW5wdXQoKSB7CisgICAgICAgIGlmIChjYWNoZVJlcXVlc3QgIT0gbnVsbCkgeworICAgICAgICAgICAgY2FjaGVSZXF1ZXN0LmFib3J0KCk7CisgICAgICAgIH0KKyAgICAgICAgaHR0cEVuZ2luZS5yZWxlYXNlKGZhbHNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9BYnN0cmFjdEh0dHBPdXRwdXRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0Fic3RyYWN0SHR0cE91dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFlMWI0N2IKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9BYnN0cmFjdEh0dHBPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLm5ldC5odHRwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworLyoqCisgKiBBbiBvdXRwdXQgc3RyZWFtIGZvciB0aGUgYm9keSBvZiBhbiBIVFRQIHJlcXVlc3QuCisgKgorICogPHA+U2luY2UgYSBzaW5nbGUgc29ja2V0J3Mgb3V0cHV0IHN0cmVhbSBtYXkgYmUgdXNlZCB0byB3cml0ZSBtdWx0aXBsZSBIVFRQCisgKiByZXF1ZXN0cyB0byB0aGUgc2FtZSBzZXJ2ZXIsIHN1YmNsYXNzZXMgc2hvdWxkIG5vdCBjbG9zZSB0aGUgc29ja2V0IHN0cmVhbS4KKyAqLworYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RIdHRwT3V0cHV0U3RyZWFtIGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBjbG9zZWQ7CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGZpbmFsIHZvaWQgd3JpdGUoaW50IGRhdGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlKG5ldyBieXRlW10geyAoYnl0ZSkgZGF0YSB9KTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBjaGVja05vdENsb3NlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjbG9zZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigic3RyZWFtIGNsb3NlZCIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvQ2h1bmtlZElucHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9DaHVua2VkSW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MWNmZjdhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvQ2h1bmtlZElucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxMTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUubmV0Lmh0dHA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuQ2FjaGVSZXF1ZXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworCisvKioKKyAqIEFuIEhUVFAgYm9keSB3aXRoIGFsdGVybmF0aW5nIGNodW5rIHNpemVzIGFuZCBjaHVuayBib2RpZXMuCisgKi8KK2ZpbmFsIGNsYXNzIENodW5rZWRJbnB1dFN0cmVhbSBleHRlbmRzIEFic3RyYWN0SHR0cElucHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUlOX0xBU1RfQ0hVTktfTEVOR1RIID0gIlxyXG4wXHJcblxyXG4iLmxlbmd0aCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOT19DSFVOS19ZRVQgPSAtMTsKKyAgICBwcml2YXRlIGludCBieXRlc1JlbWFpbmluZ0luQ2h1bmsgPSBOT19DSFVOS19ZRVQ7CisgICAgcHJpdmF0ZSBib29sZWFuIGhhc01vcmVDaHVua3MgPSB0cnVlOworCisgICAgQ2h1bmtlZElucHV0U3RyZWFtKElucHV0U3RyZWFtIGlzLCBDYWNoZVJlcXVlc3QgY2FjaGVSZXF1ZXN0LAorICAgICAgICAgICAgSHR0cEVuZ2luZSBodHRwRW5naW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihpcywgaHR0cEVuZ2luZSwgY2FjaGVSZXF1ZXN0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCByZWFkKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisKKyAgICAgICAgaWYgKCFoYXNNb3JlQ2h1bmtzKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJ5dGVzUmVtYWluaW5nSW5DaHVuayA9PSAwIHx8IGJ5dGVzUmVtYWluaW5nSW5DaHVuayA9PSBOT19DSFVOS19ZRVQpIHsKKyAgICAgICAgICAgIHJlYWRDaHVua1NpemUoKTsKKyAgICAgICAgICAgIGlmICghaGFzTW9yZUNodW5rcykgeworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpbnQgcmVhZCA9IGluLnJlYWQoYnVmZmVyLCBvZmZzZXQsIE1hdGgubWluKGNvdW50LCBieXRlc1JlbWFpbmluZ0luQ2h1bmspKTsKKyAgICAgICAgaWYgKHJlYWQgPT0gLTEpIHsKKyAgICAgICAgICAgIHVuZXhwZWN0ZWRFbmRPZklucHV0KCk7IC8vIHRoZSBzZXJ2ZXIgZGlkbid0IHN1cHBseSB0aGUgcHJvbWlzZWQgY2h1bmsgbGVuZ3RoCisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInVuZXhwZWN0ZWQgZW5kIG9mIHN0cmVhbSIpOworICAgICAgICB9CisgICAgICAgIGJ5dGVzUmVtYWluaW5nSW5DaHVuayAtPSByZWFkOworICAgICAgICBjYWNoZVdyaXRlKGJ1ZmZlciwgb2Zmc2V0LCByZWFkKTsKKworICAgICAgICAvKgorICAgICAgICAgKiBJZiB3ZSdyZSBhdCB0aGUgZW5kIG9mIGEgY2h1bmsgYW5kIHRoZSBuZXh0IGNodW5rIHNpemUgaXMgcmVhZGFibGUsCisgICAgICAgICAqIHJlYWQgaXQhIFJlYWRpbmcgdGhlIGxhc3QgY2h1bmsgY2F1c2VzIHRoZSB1bmRlcmx5aW5nIGNvbm5lY3Rpb24gdG8KKyAgICAgICAgICogYmUgcmVjeWNsZWQgYW5kIHdlIHdhbnQgdG8gZG8gdGhhdCBhcyBlYXJseSBhcyBwb3NzaWJsZS4gT3RoZXJ3aXNlCisgICAgICAgICAqIHNlbGYtZGVsaW1pdGluZyBzdHJlYW1zIGxpa2UgZ3ppcCB3aWxsIG5ldmVyIGJlIHJlY3ljbGVkLgorICAgICAgICAgKiBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTcwNTkKKyAgICAgICAgICovCisgICAgICAgIGlmIChieXRlc1JlbWFpbmluZ0luQ2h1bmsgPT0gMCAmJiBpbi5hdmFpbGFibGUoKSA+PSBNSU5fTEFTVF9DSFVOS19MRU5HVEgpIHsKKyAgICAgICAgICAgIHJlYWRDaHVua1NpemUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZWFkOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkQ2h1bmtTaXplKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gcmVhZCB0aGUgc3VmZml4IG9mIHRoZSBwcmV2aW91cyBjaHVuaworICAgICAgICBpZiAoYnl0ZXNSZW1haW5pbmdJbkNodW5rICE9IE5PX0NIVU5LX1lFVCkgeworICAgICAgICAgICAgU3RyZWFtcy5yZWFkQXNjaWlMaW5lKGluKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgY2h1bmtTaXplU3RyaW5nID0gU3RyZWFtcy5yZWFkQXNjaWlMaW5lKGluKTsKKyAgICAgICAgaW50IGluZGV4ID0gY2h1bmtTaXplU3RyaW5nLmluZGV4T2YoIjsiKTsKKyAgICAgICAgaWYgKGluZGV4ICE9IC0xKSB7CisgICAgICAgICAgICBjaHVua1NpemVTdHJpbmcgPSBjaHVua1NpemVTdHJpbmcuc3Vic3RyaW5nKDAsIGluZGV4KTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYnl0ZXNSZW1haW5pbmdJbkNodW5rID0gSW50ZWdlci5wYXJzZUludChjaHVua1NpemVTdHJpbmcudHJpbSgpLCAxNik7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkV4cGVjdGVkIGEgaGV4IGNodW5rIHNpemUsIGJ1dCB3YXMgIiArIGNodW5rU2l6ZVN0cmluZyk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJ5dGVzUmVtYWluaW5nSW5DaHVuayA9PSAwKSB7CisgICAgICAgICAgICBoYXNNb3JlQ2h1bmtzID0gZmFsc2U7CisgICAgICAgICAgICBodHRwRW5naW5lLnJlYWRUcmFpbGVycygpOworICAgICAgICAgICAgZW5kT2ZJbnB1dCh0cnVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgIGlmICghaGFzTW9yZUNodW5rcyB8fCBieXRlc1JlbWFpbmluZ0luQ2h1bmsgPT0gTk9fQ0hVTktfWUVUKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gTWF0aC5taW4oaW4uYXZhaWxhYmxlKCksIGJ5dGVzUmVtYWluaW5nSW5DaHVuayk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNsb3NlZCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgaWYgKGhhc01vcmVDaHVua3MpIHsKKyAgICAgICAgICAgIHVuZXhwZWN0ZWRFbmRPZklucHV0KCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9DaHVua2VkT3V0cHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9DaHVua2VkT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGI2NWY3YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0NodW5rZWRPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDEzMyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5uZXQuaHR0cDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBBbiBIVFRQIGJvZHkgd2l0aCBhbHRlcm5hdGluZyBjaHVuayBzaXplcyBhbmQgY2h1bmsgYm9kaWVzLiBDaHVua3MgYXJlCisgKiBidWZmZXJlZCB1bnRpbCB7QGNvZGUgbWF4Q2h1bmtMZW5ndGh9IGJ5dGVzIGFyZSByZWFkeSwgYXQgd2hpY2ggcG9pbnQgdGhlCisgKiBjaHVuayBpcyB3cml0dGVuIGFuZCB0aGUgYnVmZmVyIGlzIGNsZWFyZWQuCisgKi8KK2ZpbmFsIGNsYXNzIENodW5rZWRPdXRwdXRTdHJlYW0gZXh0ZW5kcyBBYnN0cmFjdEh0dHBPdXRwdXRTdHJlYW0geworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBDUkxGID0geyAnXHInLCAnXG4nIH07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIEhFWF9ESUdJVFMgPSB7CisgICAgICAgICcwJywgJzEnLCAnMicsICczJywgJzQnLCAnNScsICc2JywgJzcnLCAnOCcsICc5JywgJ2EnLCAnYicsICdjJywgJ2QnLCAnZScsICdmJworICAgIH07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIEZJTkFMX0NIVU5LID0gbmV3IGJ5dGVbXSB7ICcwJywgJ1xyJywgJ1xuJywgJ1xyJywgJ1xuJyB9OworCisgICAgLyoqIFNjcmF0Y2ggc3BhY2UgZm9yIHVwIHRvIDggaGV4IGRpZ2l0cywgYW5kIHRoZW4gYSBjb25zdGFudCBDUkxGICovCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gaGV4ID0geyAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAnXHInLCAnXG4nIH07CisKKyAgICBwcml2YXRlIGZpbmFsIE91dHB1dFN0cmVhbSBzb2NrZXRPdXQ7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbWF4Q2h1bmtMZW5ndGg7CisgICAgcHJpdmF0ZSBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnVmZmVyZWRDaHVuazsKKworCisgICAgcHVibGljIENodW5rZWRPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIHNvY2tldE91dCwgaW50IG1heENodW5rTGVuZ3RoKSB7CisgICAgICAgIHRoaXMuc29ja2V0T3V0ID0gc29ja2V0T3V0OworICAgICAgICB0aGlzLm1heENodW5rTGVuZ3RoID0gTWF0aC5tYXgoMSwgZGF0YUxlbmd0aChtYXhDaHVua0xlbmd0aCkpOworICAgICAgICB0aGlzLmJ1ZmZlcmVkQ2h1bmsgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKG1heENodW5rTGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhbW91bnQgb2YgZGF0YSB0aGF0IGNhbiBiZSB0cmFuc21pdHRlZCBpbiBhIGNodW5rIHdob3NlIHRvdGFsCisgICAgICogbGVuZ3RoIChkYXRhK2hlYWRlcnMpIGlzIHtAY29kZSBkYXRhUGx1c0hlYWRlckxlbmd0aH0uIFRoaXMgaXMgcHJlc3VtYWJseQorICAgICAqIHVzZWZ1bCB0byBtYXRjaCBzaXplcyB3aXRoIHdpcmUtcHJvdG9jb2wgcGFja2V0cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBkYXRhTGVuZ3RoKGludCBkYXRhUGx1c0hlYWRlckxlbmd0aCkgeworICAgICAgICBpbnQgaGVhZGVyTGVuZ3RoID0gNDsgLy8gIlxyXG4iIGFmdGVyIHRoZSBzaXplIHBsdXMgYW5vdGhlciAiXHJcbiIgYWZ0ZXIgdGhlIGRhdGEKKyAgICAgICAgZm9yIChpbnQgaSA9IGRhdGFQbHVzSGVhZGVyTGVuZ3RoIC0gaGVhZGVyTGVuZ3RoOyBpID4gMDsgaSA+Pj0gNCkgeworICAgICAgICAgICAgaGVhZGVyTGVuZ3RoKys7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRhdGFQbHVzSGVhZGVyTGVuZ3RoIC0gaGVhZGVyTGVuZ3RoOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgd3JpdGUoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGNvdW50KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBjb3VudCk7CisKKyAgICAgICAgd2hpbGUgKGNvdW50ID4gMCkgeworICAgICAgICAgICAgaW50IG51bUJ5dGVzV3JpdHRlbjsKKworICAgICAgICAgICAgaWYgKGJ1ZmZlcmVkQ2h1bmsuc2l6ZSgpID4gMCB8fCBjb3VudCA8IG1heENodW5rTGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgLy8gZmlsbCB0aGUgYnVmZmVyZWQgY2h1bmsgYW5kIHRoZW4gbWF5YmUgd3JpdGUgdGhhdCB0byB0aGUgc3RyZWFtCisgICAgICAgICAgICAgICAgbnVtQnl0ZXNXcml0dGVuID0gTWF0aC5taW4oY291bnQsIG1heENodW5rTGVuZ3RoIC0gYnVmZmVyZWRDaHVuay5zaXplKCkpOworICAgICAgICAgICAgICAgIC8vIFRPRE86IHNraXAgdW5uZWNlc3NhcnkgY29waWVzIGZyb20gYnVmZmVyLT5idWZmZXJlZENodW5rPworICAgICAgICAgICAgICAgIGJ1ZmZlcmVkQ2h1bmsud3JpdGUoYnVmZmVyLCBvZmZzZXQsIG51bUJ5dGVzV3JpdHRlbik7CisgICAgICAgICAgICAgICAgaWYgKGJ1ZmZlcmVkQ2h1bmsuc2l6ZSgpID09IG1heENodW5rTGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIHdyaXRlQnVmZmVyZWRDaHVua1RvU29ja2V0KCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIHdyaXRlIGEgc2luZ2xlIGNodW5rIG9mIHNpemUgbWF4Q2h1bmtMZW5ndGggdG8gdGhlIHN0cmVhbQorICAgICAgICAgICAgICAgIG51bUJ5dGVzV3JpdHRlbiA9IG1heENodW5rTGVuZ3RoOworICAgICAgICAgICAgICAgIHdyaXRlSGV4KG51bUJ5dGVzV3JpdHRlbik7CisgICAgICAgICAgICAgICAgc29ja2V0T3V0LndyaXRlKGJ1ZmZlciwgb2Zmc2V0LCBudW1CeXRlc1dyaXR0ZW4pOworICAgICAgICAgICAgICAgIHNvY2tldE91dC53cml0ZShDUkxGKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgb2Zmc2V0ICs9IG51bUJ5dGVzV3JpdHRlbjsKKyAgICAgICAgICAgIGNvdW50IC09IG51bUJ5dGVzV3JpdHRlbjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWl2YWxlbnQgdG8sIGJ1dCBjaGVhcGVyIHRoYW4gd3JpdGluZyBJbnRlZ2VyLnRvSGV4U3RyaW5nKCkuZ2V0Qnl0ZXMoKQorICAgICAqIGZvbGxvd2VkIGJ5IENSTEYuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlSGV4KGludCBpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgY3Vyc29yID0gODsKKyAgICAgICAgZG8geworICAgICAgICAgICAgaGV4Wy0tY3Vyc29yXSA9IEhFWF9ESUdJVFNbaSAmIDB4Zl07CisgICAgICAgIH0gd2hpbGUgKChpID4+Pj0gNCkgIT0gMCk7CisgICAgICAgIHNvY2tldE91dC53cml0ZShoZXgsIGN1cnNvciwgaGV4Lmxlbmd0aCAtIGN1cnNvcik7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjbG9zZWQpIHsKKyAgICAgICAgICAgIHJldHVybjsgLy8gZG9uJ3QgdGhyb3c7IHRoaXMgc3RyZWFtIG1pZ2h0IGhhdmUgYmVlbiBjbG9zZWQgb24gdGhlIGNhbGxlcidzIGJlaGFsZgorICAgICAgICB9CisgICAgICAgIHdyaXRlQnVmZmVyZWRDaHVua1RvU29ja2V0KCk7CisgICAgICAgIHNvY2tldE91dC5mbHVzaCgpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY2xvc2VkKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgd3JpdGVCdWZmZXJlZENodW5rVG9Tb2NrZXQoKTsKKyAgICAgICAgc29ja2V0T3V0LndyaXRlKEZJTkFMX0NIVU5LKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVCdWZmZXJlZENodW5rVG9Tb2NrZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgc2l6ZSA9IGJ1ZmZlcmVkQ2h1bmsuc2l6ZSgpOworICAgICAgICBpZiAoc2l6ZSA8PSAwKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICB3cml0ZUhleChzaXplKTsKKyAgICAgICAgYnVmZmVyZWRDaHVuay53cml0ZVRvKHNvY2tldE91dCk7CisgICAgICAgIGJ1ZmZlcmVkQ2h1bmsucmVzZXQoKTsKKyAgICAgICAgc29ja2V0T3V0LndyaXRlKENSTEYpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0ZpeGVkTGVuZ3RoSW5wdXRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0ZpeGVkTGVuZ3RoSW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMDkxYWY3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvRml4ZWRMZW5ndGhJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNzIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUubmV0Lmh0dHA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuQ2FjaGVSZXF1ZXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogQW4gSFRUUCBib2R5IHdpdGggYSBmaXhlZCBsZW5ndGggc3BlY2lmaWVkIGluIGFkdmFuY2UuCisgKi8KK2ZpbmFsIGNsYXNzIEZpeGVkTGVuZ3RoSW5wdXRTdHJlYW0gZXh0ZW5kcyBBYnN0cmFjdEh0dHBJbnB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBpbnQgYnl0ZXNSZW1haW5pbmc7CisKKyAgICBwdWJsaWMgRml4ZWRMZW5ndGhJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpcywgQ2FjaGVSZXF1ZXN0IGNhY2hlUmVxdWVzdCwKKyAgICAgICAgICAgIEh0dHBFbmdpbmUgaHR0cEVuZ2luZSwgaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoaXMsIGh0dHBFbmdpbmUsIGNhY2hlUmVxdWVzdCk7CisgICAgICAgIGJ5dGVzUmVtYWluaW5nID0gbGVuZ3RoOworICAgICAgICBpZiAoYnl0ZXNSZW1haW5pbmcgPT0gMCkgeworICAgICAgICAgICAgZW5kT2ZJbnB1dCh0cnVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWZmZXIubGVuZ3RoLCBvZmZzZXQsIGNvdW50KTsKKyAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgaWYgKGJ5dGVzUmVtYWluaW5nID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBpbnQgcmVhZCA9IGluLnJlYWQoYnVmZmVyLCBvZmZzZXQsIE1hdGgubWluKGNvdW50LCBieXRlc1JlbWFpbmluZykpOworICAgICAgICBpZiAocmVhZCA9PSAtMSkgeworICAgICAgICAgICAgdW5leHBlY3RlZEVuZE9mSW5wdXQoKTsgLy8gdGhlIHNlcnZlciBkaWRuJ3Qgc3VwcGx5IHRoZSBwcm9taXNlZCBjb250ZW50IGxlbmd0aAorICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJ1bmV4cGVjdGVkIGVuZCBvZiBzdHJlYW0iKTsKKyAgICAgICAgfQorICAgICAgICBieXRlc1JlbWFpbmluZyAtPSByZWFkOworICAgICAgICBjYWNoZVdyaXRlKGJ1ZmZlciwgb2Zmc2V0LCByZWFkKTsKKyAgICAgICAgaWYgKGJ5dGVzUmVtYWluaW5nID09IDApIHsKKyAgICAgICAgICAgIGVuZE9mSW5wdXQodHJ1ZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlYWQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgcmV0dXJuIGJ5dGVzUmVtYWluaW5nID09IDAgPyAwIDogTWF0aC5taW4oaW4uYXZhaWxhYmxlKCksIGJ5dGVzUmVtYWluaW5nKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY2xvc2VkKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgaWYgKGJ5dGVzUmVtYWluaW5nICE9IDApIHsKKyAgICAgICAgICAgIHVuZXhwZWN0ZWRFbmRPZklucHV0KCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9GaXhlZExlbmd0aE91dHB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvRml4ZWRMZW5ndGhPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NjFlZWQ5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvRml4ZWRMZW5ndGhPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDYxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLm5ldC5odHRwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIEFuIEhUVFAgYm9keSB3aXRoIGEgZml4ZWQgbGVuZ3RoIGtub3duIGluIGFkdmFuY2UuCisgKi8KK2ZpbmFsIGNsYXNzIEZpeGVkTGVuZ3RoT3V0cHV0U3RyZWFtIGV4dGVuZHMgQWJzdHJhY3RIdHRwT3V0cHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIGZpbmFsIE91dHB1dFN0cmVhbSBzb2NrZXRPdXQ7CisgICAgcHJpdmF0ZSBpbnQgYnl0ZXNSZW1haW5pbmc7CisKKyAgICBwdWJsaWMgRml4ZWRMZW5ndGhPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIHNvY2tldE91dCwgaW50IGJ5dGVzUmVtYWluaW5nKSB7CisgICAgICAgIHRoaXMuc29ja2V0T3V0ID0gc29ja2V0T3V0OworICAgICAgICB0aGlzLmJ5dGVzUmVtYWluaW5nID0gYnl0ZXNSZW1haW5pbmc7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgIGlmIChjb3VudCA+IGJ5dGVzUmVtYWluaW5nKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oImV4cGVjdGVkICIgKyBieXRlc1JlbWFpbmluZyArICIgYnl0ZXMgYnV0IHJlY2VpdmVkICIgKyBjb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgc29ja2V0T3V0LndyaXRlKGJ1ZmZlciwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgIGJ5dGVzUmVtYWluaW5nIC09IGNvdW50OworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjbG9zZWQpIHsKKyAgICAgICAgICAgIHJldHVybjsgLy8gZG9uJ3QgdGhyb3c7IHRoaXMgc3RyZWFtIG1pZ2h0IGhhdmUgYmVlbiBjbG9zZWQgb24gdGhlIGNhbGxlcidzIGJlaGFsZgorICAgICAgICB9CisgICAgICAgIHNvY2tldE91dC5mbHVzaCgpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjbG9zZWQpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBjbG9zZWQgPSB0cnVlOworICAgICAgICBpZiAoYnl0ZXNSZW1haW5pbmcgPiAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInVuZXhwZWN0ZWQgZW5kIG9mIHN0cmVhbSIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvSGVhZGVyUGFyc2VyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9IZWFkZXJQYXJzZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMWUwOWY5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvSGVhZGVyUGFyc2VyLmphdmEKQEAgLTAsMCArMSwxMTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUubmV0Lmh0dHA7CisKK2ZpbmFsIGNsYXNzIEhlYWRlclBhcnNlciB7CisKKyAgICBwdWJsaWMgaW50ZXJmYWNlIENhY2hlQ29udHJvbEhhbmRsZXIgeworICAgICAgICB2b2lkIGhhbmRsZShTdHJpbmcgZGlyZWN0aXZlLCBTdHJpbmcgcGFyYW1ldGVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhIGNvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIGNhY2hlIGNvbnRyb2wgaGVhZGVyIHZhbHVlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcGFyc2VDYWNoZUNvbnRyb2woU3RyaW5nIHZhbHVlLCBDYWNoZUNvbnRyb2xIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICAgICAgaW50IHBvcyA9IDA7CisgICAgICAgIHdoaWxlIChwb3MgPCB2YWx1ZS5sZW5ndGgoKSkgeworICAgICAgICAgICAgaW50IHRva2VuU3RhcnQgPSBwb3M7CisgICAgICAgICAgICBwb3MgPSBza2lwVW50aWwodmFsdWUsIHBvcywgIj0sIik7CisgICAgICAgICAgICBTdHJpbmcgZGlyZWN0aXZlID0gdmFsdWUuc3Vic3RyaW5nKHRva2VuU3RhcnQsIHBvcykudHJpbSgpOworCisgICAgICAgICAgICBpZiAocG9zID09IHZhbHVlLmxlbmd0aCgpIHx8IHZhbHVlLmNoYXJBdChwb3MpID09ICcsJykgeworICAgICAgICAgICAgICAgIHBvcysrOyAvLyBjb25zdW1lICcsJyAoaWYgbmVjZXNzYXJ5KQorICAgICAgICAgICAgICAgIGhhbmRsZXIuaGFuZGxlKGRpcmVjdGl2ZSwgbnVsbCk7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHBvcysrOyAvLyBjb25zdW1lICc9JworICAgICAgICAgICAgcG9zID0gc2tpcFdoaXRlc3BhY2UodmFsdWUsIHBvcyk7CisKKyAgICAgICAgICAgIFN0cmluZyBwYXJhbWV0ZXI7CisKKyAgICAgICAgICAgIC8vIHF1b3RlZCBzdHJpbmcKKyAgICAgICAgICAgIGlmIChwb3MgPCB2YWx1ZS5sZW5ndGgoKSAmJiB2YWx1ZS5jaGFyQXQocG9zKSA9PSAnXCInKSB7CisgICAgICAgICAgICAgICAgcG9zKys7IC8vIGNvbnN1bWUgJyInIG9wZW4gcXVvdGUKKyAgICAgICAgICAgICAgICBpbnQgcGFyYW1ldGVyU3RhcnQgPSBwb3M7CisgICAgICAgICAgICAgICAgcG9zID0gc2tpcFVudGlsKHZhbHVlLCBwb3MsICJcIiIpOworICAgICAgICAgICAgICAgIHBhcmFtZXRlciA9IHZhbHVlLnN1YnN0cmluZyhwYXJhbWV0ZXJTdGFydCwgcG9zKTsKKyAgICAgICAgICAgICAgICBwb3MrKzsgLy8gY29uc3VtZSAnIicgY2xvc2UgcXVvdGUgKGlmIG5lY2Vzc2FyeSkKKworICAgICAgICAgICAgLy8gdW5xdW90ZWQgc3RyaW5nCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGludCBwYXJhbWV0ZXJTdGFydCA9IHBvczsKKyAgICAgICAgICAgICAgICBwb3MgPSBza2lwVW50aWwodmFsdWUsIHBvcywgIiwiKTsKKyAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgPSB2YWx1ZS5zdWJzdHJpbmcocGFyYW1ldGVyU3RhcnQsIHBvcykudHJpbSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBoYW5kbGVyLmhhbmRsZShkaXJlY3RpdmUsIHBhcmFtZXRlcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGluZGV4IGluIHtAY29kZSBpbnB1dH0gYXQgb3IgYWZ0ZXIge0Bjb2RlIHBvc30gdGhhdAorICAgICAqIGNvbnRhaW5zIGEgY2hhcmFjdGVyIGZyb20ge0Bjb2RlIGNoYXJhY3RlcnN9LiBSZXR1cm5zIHRoZSBpbnB1dCBsZW5ndGggaWYKKyAgICAgKiBub25lIG9mIHRoZSByZXF1ZXN0ZWQgY2hhcmFjdGVycyBjYW4gYmUgZm91bmQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHNraXBVbnRpbChTdHJpbmcgaW5wdXQsIGludCBwb3MsIFN0cmluZyBjaGFyYWN0ZXJzKSB7CisgICAgICAgIGZvciAoOyBwb3MgPCBpbnB1dC5sZW5ndGgoKTsgcG9zKyspIHsKKyAgICAgICAgICAgIGlmIChjaGFyYWN0ZXJzLmluZGV4T2YoaW5wdXQuY2hhckF0KHBvcykpICE9IC0xKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHBvczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IG5vbi13aGl0ZXNwYWNlIGNoYXJhY3RlciBpbiB7QGNvZGUgaW5wdXR9IHRoYXQgaXMgd2hpdGUKKyAgICAgKiBzcGFjZS4gUmVzdWx0IGlzIHVuZGVmaW5lZCBpZiBpbnB1dCBjb250YWlucyBuZXdsaW5lIGNoYXJhY3RlcnMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHNraXBXaGl0ZXNwYWNlKFN0cmluZyBpbnB1dCwgaW50IHBvcykgeworICAgICAgICBmb3IgKDsgcG9zIDwgaW5wdXQubGVuZ3RoKCk7IHBvcysrKSB7CisgICAgICAgICAgICBjaGFyIGMgPSBpbnB1dC5jaGFyQXQocG9zKTsKKyAgICAgICAgICAgIGlmIChjICE9ICcgJyAmJiBjICE9ICdcdCcpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcG9zOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMge0Bjb2RlIHZhbHVlfSBhcyBhIHBvc2l0aXZlIGludGVnZXIsIG9yIDAgaWYgaXQgaXMgbmVnYXRpdmUsIG9yCisgICAgICogLTEgaWYgaXQgY2Fubm90IGJlIHBhcnNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBwYXJzZVNlY29uZHMoU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsb25nIHNlY29uZHMgPSBMb25nLnBhcnNlTG9uZyh2YWx1ZSk7CisgICAgICAgICAgICBpZiAoc2Vjb25kcyA+IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIEludGVnZXIuTUFYX1ZBTFVFOworICAgICAgICAgICAgfSBlbHNlIGlmIChzZWNvbmRzIDwgMCkgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gKGludCkgc2Vjb25kczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0h0dHBDb25uZWN0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9IdHRwQ29ubmVjdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc1NmVkYjgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9IdHRwQ29ubmVjdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzU0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUubmV0Lmh0dHA7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlByb3h5OworaW1wb3J0IGphdmEubmV0LlByb3h5U2VsZWN0b3I7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0OworaW1wb3J0IGphdmEubmV0LlNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlNvY2tldFRpbWVvdXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJJOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuSG9zdG5hbWVWZXJpZmllcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3Rvcnk7CitpbXBvcnQgbGliY29yZS5pby5Jb1V0aWxzOworaW1wb3J0IGxpYmNvcmUudXRpbC5PYmplY3RzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2UuT3BlblNTTFNvY2tldEltcGw7CisKKy8qKgorICogSG9sZHMgdGhlIHNvY2tldHMgYW5kIHN0cmVhbXMgb2YgYW4gSFRUUCBvciBIVFRQUyBjb25uZWN0aW9uLCB3aGljaCBtYXkgYmUKKyAqIHVzZWQgZm9yIG11bHRpcGxlIEhUVFAgcmVxdWVzdC9yZXNwb25zZSBleGNoYW5nZXMuIENvbm5lY3Rpb25zIG1heSBiZSBkaXJlY3QKKyAqIHRvIHRoZSBvcmlnaW4gc2VydmVyIG9yIHZpYSBhIHByb3h5LiBDcmVhdGUgYW4gaW5zdGFuY2UgdXNpbmcgdGhlIHtAbGluaworICogQWRkcmVzc30gaW5uZXIgY2xhc3MuCisgKgorICogPHA+RG8gbm90IGNvbmZ1c2UgdGhpcyBjbGFzcyB3aXRoIHRoZSBtaXNuYW1lZCB7QGNvZGUgSHR0cFVSTENvbm5lY3Rpb259LAorICogd2hpY2ggaXNuJ3Qgc28gbXVjaCBhIGNvbm5lY3Rpb24gYXMgYSBzaW5nbGUgcmVxdWVzdC9yZXNwb25zZSBwYWlyLgorICovCitmaW5hbCBjbGFzcyBIdHRwQ29ubmVjdGlvbiB7CisgICAgcHJpdmF0ZSBmaW5hbCBBZGRyZXNzIGFkZHJlc3M7CisKKyAgICBwcml2YXRlIGZpbmFsIFNvY2tldCBzb2NrZXQ7CisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbTsKKyAgICBwcml2YXRlIE91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW07CisKKyAgICBwcml2YXRlIFNTTFNvY2tldCB1bnZlcmlmaWVkU29ja2V0OworICAgIHByaXZhdGUgU1NMU29ja2V0IHNzbFNvY2tldDsKKyAgICBwcml2YXRlIElucHV0U3RyZWFtIHNzbElucHV0U3RyZWFtOworICAgIHByaXZhdGUgT3V0cHV0U3RyZWFtIHNzbE91dHB1dFN0cmVhbTsKKworICAgIHByaXZhdGUgSHR0cENvbm5lY3Rpb24oQWRkcmVzcyBjb25maWcsIGludCBjb25uZWN0VGltZW91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5hZGRyZXNzID0gY29uZmlnOworCisgICAgICAgIC8qCisgICAgICAgICAqIFRyeSBlYWNoIG9mIHRoZSBob3N0J3MgYWRkcmVzc2VzIGZvciBiZXN0IGJlaGF2aW9yIGluIG1peGVkIElQdjQvSVB2NgorICAgICAgICAgKiBlbnZpcm9ubWVudHMuIFNlZSBodHRwOi8vYi8yODc2OTI3CisgICAgICAgICAqIFRPRE86IGFkZCBhIGhpZGRlbiBtZXRob2Qgc28gdGhhdCBTb2NrZXQudHJ5QWxsQWRkcmVzc2VzIGNhbiBkb2VzIHRoaXMgZm9yIHVzCisgICAgICAgICAqLworICAgICAgICBTb2NrZXQgc29ja2V0Q2FuZGlkYXRlID0gbnVsbDsKKyAgICAgICAgSW5ldEFkZHJlc3NbXSBhZGRyZXNzZXMgPSBJbmV0QWRkcmVzcy5nZXRBbGxCeU5hbWUoY29uZmlnLnNvY2tldEhvc3QpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFkZHJlc3Nlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc29ja2V0Q2FuZGlkYXRlID0gKGNvbmZpZy5wcm94eSAhPSBudWxsICYmIGNvbmZpZy5wcm94eS50eXBlKCkgIT0gUHJveHkuVHlwZS5IVFRQKQorICAgICAgICAgICAgICAgICAgICA/IG5ldyBTb2NrZXQoY29uZmlnLnByb3h5KQorICAgICAgICAgICAgICAgICAgICA6IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc29ja2V0Q2FuZGlkYXRlLmNvbm5lY3QoCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoYWRkcmVzc2VzW2ldLCBjb25maWcuc29ja2V0UG9ydCksIGNvbm5lY3RUaW1lb3V0KTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBpZiAoaSA9PSBhZGRyZXNzZXMubGVuZ3RoIC0gMSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuc29ja2V0ID0gc29ja2V0Q2FuZGlkYXRlOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgSHR0cENvbm5lY3Rpb24gY29ubmVjdChVUkkgdXJpLCBQcm94eSBwcm94eSwgYm9vbGVhbiByZXF1aXJlc1R1bm5lbCwKKyAgICAgICAgICAgIGludCBjb25uZWN0VGltZW91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogVHJ5IGFuIGV4cGxpY2l0bHktc3BlY2lmaWVkIHByb3h5LgorICAgICAgICAgKi8KKyAgICAgICAgaWYgKHByb3h5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIEFkZHJlc3MgYWRkcmVzcyA9IChwcm94eS50eXBlKCkgPT0gUHJveHkuVHlwZS5ESVJFQ1QpCisgICAgICAgICAgICAgICAgICAgID8gbmV3IEFkZHJlc3ModXJpKQorICAgICAgICAgICAgICAgICAgICA6IG5ldyBBZGRyZXNzKHVyaSwgcHJveHksIHJlcXVpcmVzVHVubmVsKTsKKyAgICAgICAgICAgIHJldHVybiBIdHRwQ29ubmVjdGlvblBvb2wuSU5TVEFOQ0UuZ2V0KGFkZHJlc3MsIGNvbm5lY3RUaW1lb3V0KTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIFRyeSBjb25uZWN0aW5nIHRvIGVhY2ggb2YgdGhlIHByb3hpZXMgcHJvdmlkZWQgYnkgdGhlIFByb3h5U2VsZWN0b3IKKyAgICAgICAgICogdW50aWwgYSBjb25uZWN0aW9uIHN1Y2NlZWRzLgorICAgICAgICAgKi8KKyAgICAgICAgUHJveHlTZWxlY3RvciBzZWxlY3RvciA9IFByb3h5U2VsZWN0b3IuZ2V0RGVmYXVsdCgpOworICAgICAgICBMaXN0PFByb3h5PiBwcm94eUxpc3QgPSBzZWxlY3Rvci5zZWxlY3QodXJpKTsKKyAgICAgICAgaWYgKHByb3h5TGlzdCAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKFByb3h5IHNlbGVjdGVkUHJveHkgOiBwcm94eUxpc3QpIHsKKyAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWRQcm94eS50eXBlKCkgPT0gUHJveHkuVHlwZS5ESVJFQ1QpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHNhbWUgYXMgTk9fUFJPWFkKKyAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogaWYgdGhlIHNlbGVjdG9yIHJlY29tbWVuZHMgYSBkaXJlY3QgY29ubmVjdGlvbiwgYXR0ZW1wdCB0aGF0PworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgQWRkcmVzcyBhZGRyZXNzID0gbmV3IEFkZHJlc3ModXJpLCBzZWxlY3RlZFByb3h5LCByZXF1aXJlc1R1bm5lbCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBIdHRwQ29ubmVjdGlvblBvb2wuSU5TVEFOQ0UuZ2V0KGFkZHJlc3MsIGNvbm5lY3RUaW1lb3V0KTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGZhaWxlZCB0byBjb25uZWN0LCB0ZWxsIGl0IHRvIHRoZSBzZWxlY3RvcgorICAgICAgICAgICAgICAgICAgICBzZWxlY3Rvci5jb25uZWN0RmFpbGVkKHVyaSwgc2VsZWN0ZWRQcm94eS5hZGRyZXNzKCksIGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIFRyeSBhIGRpcmVjdCBjb25uZWN0aW9uLiBJZiB0aGlzIGZhaWxzLCB0aGlzIG1ldGhvZCB3aWxsIHRocm93LgorICAgICAgICAgKi8KKyAgICAgICAgcmV0dXJuIEh0dHBDb25uZWN0aW9uUG9vbC5JTlNUQU5DRS5nZXQobmV3IEFkZHJlc3ModXJpKSwgY29ubmVjdFRpbWVvdXQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGNsb3NlU29ja2V0QW5kU3RyZWFtcygpIHsKKyAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkoc3NsT3V0cHV0U3RyZWFtKTsKKyAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkoc3NsSW5wdXRTdHJlYW0pOworICAgICAgICBJb1V0aWxzLmNsb3NlUXVpZXRseShzc2xTb2NrZXQpOworICAgICAgICBJb1V0aWxzLmNsb3NlUXVpZXRseShvdXRwdXRTdHJlYW0pOworICAgICAgICBJb1V0aWxzLmNsb3NlUXVpZXRseShpbnB1dFN0cmVhbSk7CisgICAgICAgIElvVXRpbHMuY2xvc2VRdWlldGx5KHNvY2tldCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U29UaW1lb3V0KGludCByZWFkVGltZW91dCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHNvY2tldC5zZXRTb1RpbWVvdXQocmVhZFRpbWVvdXQpOworICAgIH0KKworICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNzbFNvY2tldCAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoc3NsT3V0cHV0U3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzc2xPdXRwdXRTdHJlYW0gPSBzc2xTb2NrZXQuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gc3NsT3V0cHV0U3RyZWFtOworICAgICAgICB9IGVsc2UgaWYob3V0cHV0U3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgICAgIG91dHB1dFN0cmVhbSA9IHNvY2tldC5nZXRPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gb3V0cHV0U3RyZWFtOworICAgIH0KKworICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzc2xTb2NrZXQgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKHNzbElucHV0U3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzc2xJbnB1dFN0cmVhbSA9IHNzbFNvY2tldC5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHNzbElucHV0U3RyZWFtOworICAgICAgICB9IGVsc2UgaWYgKGlucHV0U3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBCdWZmZXIgdGhlIHNvY2tldCBzdHJlYW0gdG8gcGVybWl0IGVmZmljaWVudCBwYXJzaW5nIG9mIEhUVFAKKyAgICAgICAgICAgICAqIGhlYWRlcnMgYW5kIGNodW5rIHNpemVzLiBCZW5jaG1hcmtzIHN1Z2dlc3QgMTI4IGlzIHN1ZmZpY2llbnQuCisgICAgICAgICAgICAgKiBXZSBjYW5ub3QgYnVmZmVyIHdoZW4gc2V0dGluZyB1cCBhIHR1bm5lbCBiZWNhdXNlIHdlIG1heSBjb25zdW1lCisgICAgICAgICAgICAgKiBieXRlcyBpbnRlbmRlZCBmb3IgdGhlIFNTTCBzb2NrZXQuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGludCBidWZmZXJTaXplID0gMTI4OworICAgICAgICAgICAgaW5wdXRTdHJlYW0gPSBhZGRyZXNzLnJlcXVpcmVzVHVubmVsCisgICAgICAgICAgICAgICAgICAgID8gc29ja2V0LmdldElucHV0U3RyZWFtKCkKKyAgICAgICAgICAgICAgICAgICAgOiBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShzb2NrZXQuZ2V0SW5wdXRTdHJlYW0oKSwgYnVmZmVyU2l6ZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlucHV0U3RyZWFtOworICAgIH0KKworICAgIHByb3RlY3RlZCBTb2NrZXQgZ2V0U29ja2V0KCkgeworICAgICAgICByZXR1cm4gc3NsU29ja2V0ICE9IG51bGwgPyBzc2xTb2NrZXQgOiBzb2NrZXQ7CisgICAgfQorCisgICAgcHVibGljIEFkZHJlc3MgZ2V0QWRkcmVzcygpIHsKKyAgICAgICAgcmV0dXJuIGFkZHJlc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuIHtAY29kZSBTU0xTb2NrZXR9IGFuZCBwZXJmb3JtIHRoZSBTU0wgaGFuZHNoYWtlCisgICAgICogKHBlcmZvcm1pbmcgY2VydGlmaWNhdGUgdmFsaWRhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzc2xTb2NrZXRGYWN0b3J5IFNvdXJjZSBvZiBuZXcge0Bjb2RlIFNTTFNvY2tldH0gaW5zdGFuY2VzLgorICAgICAqIEBwYXJhbSB0bHNUb2xlcmFudCBJZiB0cnVlLCBhc3N1bWUgc2VydmVyIGNhbiBoYW5kbGUgY29tbW9uCisgICAgICogVExTIGV4dGVuc2lvbnMgYW5kIFNTTCBkZWZsYXRlIGNvbXByZXNzaW9uLiBJZiBmYWxzZSwgdXNlCisgICAgICogYW4gU1NMMyBvbmx5IGZhbGxiYWNrIG1vZGUgd2l0aG91dCBjb21wcmVzc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXR1cFNlY3VyZVNvY2tldChTU0xTb2NrZXRGYWN0b3J5IHNzbFNvY2tldEZhY3RvcnksIGJvb2xlYW4gdGxzVG9sZXJhbnQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBjcmVhdGUgdGhlIHdyYXBwZXIgb3ZlciBjb25uZWN0ZWQgc29ja2V0CisgICAgICAgIHVudmVyaWZpZWRTb2NrZXQgPSAoU1NMU29ja2V0KSBzc2xTb2NrZXRGYWN0b3J5LmNyZWF0ZVNvY2tldChzb2NrZXQsCisgICAgICAgICAgICAgICAgYWRkcmVzcy51cmlIb3N0LCBhZGRyZXNzLnVyaVBvcnQsIHRydWUgLyogYXV0b0Nsb3NlICovKTsKKyAgICAgICAgLy8gdGxzVG9sZXJhbnQgbWltaWNzIENocm9tZSdzIGJlaGF2aW9yCisgICAgICAgIGlmICh0bHNUb2xlcmFudCAmJiB1bnZlcmlmaWVkU29ja2V0IGluc3RhbmNlb2YgT3BlblNTTFNvY2tldEltcGwpIHsKKyAgICAgICAgICAgIE9wZW5TU0xTb2NrZXRJbXBsIG9wZW5Tc2xTb2NrZXQgPSAoT3BlblNTTFNvY2tldEltcGwpIHVudmVyaWZpZWRTb2NrZXQ7CisgICAgICAgICAgICBvcGVuU3NsU29ja2V0LnNldEVuYWJsZWRDb21wcmVzc2lvbk1ldGhvZHMobmV3IFN0cmluZ1tdIHsgIlpMSUIifSk7CisgICAgICAgICAgICBvcGVuU3NsU29ja2V0LnNldFVzZVNlc3Npb25UaWNrZXRzKHRydWUpOworICAgICAgICAgICAgb3BlblNzbFNvY2tldC5zZXRIb3N0bmFtZShhZGRyZXNzLnNvY2tldEhvc3QpOworICAgICAgICAgICAgLy8gdXNlIFNTTFNvY2tldEZhY3RvcnkgZGVmYXVsdCBlbmFibGVkIHByb3RvY29scworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdW52ZXJpZmllZFNvY2tldC5zZXRFbmFibGVkUHJvdG9jb2xzKG5ldyBTdHJpbmcgW10geyAiU1NMdjMiIH0pOworICAgICAgICB9CisgICAgICAgIC8vIGZvcmNlIGhhbmRzaGFrZSwgd2hpY2ggY2FuIHRocm93CisgICAgICAgIHVudmVyaWZpZWRTb2NrZXQuc3RhcnRIYW5kc2hha2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYW4ge0Bjb2RlIFNTTFNvY2tldH0gdGhhdCBpcyBub3Qgb25seSBjb25uZWN0ZWQgYnV0IGhhcworICAgICAqIGFsc28gcGFzc2VkIGhvc3RuYW1lIHZlcmlmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3N0bmFtZVZlcmlmaWVyIFVzZWQgdG8gdmVyaWZ5IHRoZSBob3N0bmFtZSB3ZQorICAgICAqIGNvbm5lY3RlZCB0byBpcyBhbiBhY2NlcHRhYmxlIG1hdGNoIGZvciB0aGUgcGVlciBjZXJ0aWZpY2F0ZQorICAgICAqIGNoYWluIG9mIHRoZSBTU0xTZXNzaW9uLgorICAgICAqLworICAgIHB1YmxpYyBTU0xTb2NrZXQgdmVyaWZ5U2VjdXJlU29ja2V0SG9zdG5hbWUoSG9zdG5hbWVWZXJpZmllciBob3N0bmFtZVZlcmlmaWVyKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFob3N0bmFtZVZlcmlmaWVyLnZlcmlmeShhZGRyZXNzLnVyaUhvc3QsIHVudmVyaWZpZWRTb2NrZXQuZ2V0U2Vzc2lvbigpKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJIb3N0bmFtZSAnIiArIGFkZHJlc3MudXJpSG9zdCArICInIHdhcyBub3QgdmVyaWZpZWQiKTsKKyAgICAgICAgfQorICAgICAgICBzc2xTb2NrZXQgPSB1bnZlcmlmaWVkU29ja2V0OworICAgICAgICByZXR1cm4gc3NsU29ja2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhbiB7QGNvZGUgU1NMU29ja2V0fSBpZiBhbHJlYWR5IGNvbm5lY3RlZCwgb3RoZXJ3aXNlIG51bGwuCisgICAgICovCisgICAgcHVibGljIFNTTFNvY2tldCBnZXRTZWN1cmVTb2NrZXRJZkNvbm5lY3RlZCgpIHsKKyAgICAgICAgcmV0dXJuIHNzbFNvY2tldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGNvbm5lY3Rpb24gaXMgZnVuY3Rpb25hbC4gVGhpcyB1c2VzIGEgc2hhbWVmdWwgaGFjaworICAgICAqIHRvIHBlZWsgYSBieXRlIGZyb20gdGhlIHNvY2tldC4KKyAgICAgKi8KKyAgICBib29sZWFuIGlzU3RhbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIWlzRWxpZ2libGVGb3JSZWN5Y2xpbmcoKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IGdldElucHV0U3RyZWFtKCk7CisgICAgICAgIGlmIChpbi5hdmFpbGFibGUoKSA+IDApIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIFNvY2tldCBzb2NrZXQgPSBnZXRTb2NrZXQoKTsKKyAgICAgICAgaW50IHNvVGltZW91dCA9IHNvY2tldC5nZXRTb1RpbWVvdXQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNvY2tldC5zZXRTb1RpbWVvdXQoMSk7CisgICAgICAgICAgICBpbi5tYXJrKDEpOworICAgICAgICAgICAgaW50IGJ5dGVSZWFkID0gaW4ucmVhZCgpOworICAgICAgICAgICAgaWYgKGJ5dGVSZWFkICE9IC0xKSB7CisgICAgICAgICAgICAgICAgaW4ucmVzZXQoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gdGhlIHNvY2tldCBpcyByZXBvcnRpbmcgYWxsIGRhdGEgcmVhZDsgaXQncyBzdGFsZQorICAgICAgICB9IGNhdGNoIChTb2NrZXRUaW1lb3V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gdGhlIGNvbm5lY3Rpb24gaXMgbm90IHN0YWxlOyBob29yYXkKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7IC8vIHRoZSBjb25uZWN0aW9uIGlzIHN0YWxlLCB0aGUgcmVhZCBvciBzb1RpbWVvdXQgZmFpbGVkLgorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc29ja2V0LnNldFNvVGltZW91dChzb1RpbWVvdXQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgY29ubmVjdGlvbiBpcyBlbGlnaWJsZSB0byBiZSByZWN5Y2xlZC4gVGhpcworICAgICAqIGlzIGxpa2Uge0BsaW5rICNpc1N0YWxlfSBleGNlcHQgdGhhdCBpdCBkb2Vzbid0IHRyeSB0byBhY3R1YWxseQorICAgICAqIHBlcmZvcm0gYW55IEkvTy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0VsaWdpYmxlRm9yUmVjeWNsaW5nKCkgeworICAgICAgICByZXR1cm4gIXNvY2tldC5pc0Nsb3NlZCgpCisgICAgICAgICAgICAgICAgJiYgIXNvY2tldC5pc0lucHV0U2h1dGRvd24oKQorICAgICAgICAgICAgICAgICYmICFzb2NrZXQuaXNPdXRwdXRTaHV0ZG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgYWRkcmVzcyBoYXMgdHdvIHBhcnRzOiB0aGUgYWRkcmVzcyB3ZSBjb25uZWN0IHRvIGRpcmVjdGx5IGFuZCB0aGUKKyAgICAgKiBvcmlnaW4gYWRkcmVzcyBvZiB0aGUgcmVzb3VyY2UuIFRoZXNlIGFyZSB0aGUgc2FtZSB1bmxlc3MgYSBwcm94eSBpcworICAgICAqIGJlaW5nIHVzZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBBZGRyZXNzIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBQcm94eSBwcm94eTsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHJlcXVpcmVzVHVubmVsOworICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyB1cmlIb3N0OworICAgICAgICBwcml2YXRlIGZpbmFsIGludCB1cmlQb3J0OworICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBzb2NrZXRIb3N0OworICAgICAgICBwcml2YXRlIGZpbmFsIGludCBzb2NrZXRQb3J0OworCisgICAgICAgIHB1YmxpYyBBZGRyZXNzKFVSSSB1cmkpIHsKKyAgICAgICAgICAgIHRoaXMucHJveHkgPSBudWxsOworICAgICAgICAgICAgdGhpcy5yZXF1aXJlc1R1bm5lbCA9IGZhbHNlOworICAgICAgICAgICAgdGhpcy51cmlIb3N0ID0gdXJpLmdldEhvc3QoKTsKKyAgICAgICAgICAgIHRoaXMudXJpUG9ydCA9IHVyaS5nZXRFZmZlY3RpdmVQb3J0KCk7CisgICAgICAgICAgICB0aGlzLnNvY2tldEhvc3QgPSB1cmlIb3N0OworICAgICAgICAgICAgdGhpcy5zb2NrZXRQb3J0ID0gdXJpUG9ydDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBAcGFyYW0gcmVxdWlyZXNUdW5uZWwgdHJ1ZSBpZiB0aGUgSFRUUCBjb25uZWN0aW9uIG5lZWRzIHRvIHR1bm5lbCBvbmUKKyAgICAgICAgICogICAgIHByb3RvY29sIG92ZXIgYW5vdGhlciwgc3VjaCBhcyB3aGVuIHVzaW5nIEhUVFBTIHRocm91Z2ggYW4gSFRUUAorICAgICAgICAgKiAgICAgcHJveHkuIFdoZW4gZG9pbmcgc28sIHdlIG11c3QgYXZvaWQgYnVmZmVyaW5nIGJ5dGVzIGludGVuZGVkIGZvcgorICAgICAgICAgKiAgICAgdGhlIGhpZ2hlci1sZXZlbCBwcm90b2NvbC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBBZGRyZXNzKFVSSSB1cmksIFByb3h5IHByb3h5LCBib29sZWFuIHJlcXVpcmVzVHVubmVsKSB7CisgICAgICAgICAgICB0aGlzLnByb3h5ID0gcHJveHk7CisgICAgICAgICAgICB0aGlzLnJlcXVpcmVzVHVubmVsID0gcmVxdWlyZXNUdW5uZWw7CisgICAgICAgICAgICB0aGlzLnVyaUhvc3QgPSB1cmkuZ2V0SG9zdCgpOworICAgICAgICAgICAgdGhpcy51cmlQb3J0ID0gdXJpLmdldEVmZmVjdGl2ZVBvcnQoKTsKKworICAgICAgICAgICAgU29ja2V0QWRkcmVzcyBwcm94eUFkZHJlc3MgPSBwcm94eS5hZGRyZXNzKCk7CisgICAgICAgICAgICBpZiAoIShwcm94eUFkZHJlc3MgaW5zdGFuY2VvZiBJbmV0U29ja2V0QWRkcmVzcykpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQcm94eS5hZGRyZXNzKCkgaXMgbm90IGFuIEluZXRTb2NrZXRBZGRyZXNzOiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIHByb3h5QWRkcmVzcy5nZXRDbGFzcygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIHByb3h5U29ja2V0QWRkcmVzcyA9IChJbmV0U29ja2V0QWRkcmVzcykgcHJveHlBZGRyZXNzOworICAgICAgICAgICAgdGhpcy5zb2NrZXRIb3N0ID0gcHJveHlTb2NrZXRBZGRyZXNzLmdldEhvc3ROYW1lKCk7CisgICAgICAgICAgICB0aGlzLnNvY2tldFBvcnQgPSBwcm94eVNvY2tldEFkZHJlc3MuZ2V0UG9ydCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFByb3h5IGdldFByb3h5KCkgeworICAgICAgICAgICAgcmV0dXJuIHByb3h5OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKKyAgICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIEFkZHJlc3MpIHsKKyAgICAgICAgICAgICAgICBBZGRyZXNzIHRoYXQgPSAoQWRkcmVzcykgb3RoZXI7CisgICAgICAgICAgICAgICAgcmV0dXJuIE9iamVjdHMuZXF1YWwodGhpcy5wcm94eSwgdGhhdC5wcm94eSkKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIHRoaXMudXJpSG9zdC5lcXVhbHModGhhdC51cmlIb3N0KQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy51cmlQb3J0ID09IHRoYXQudXJpUG9ydAorICAgICAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy5yZXF1aXJlc1R1bm5lbCA9PSB0aGF0LnJlcXVpcmVzVHVubmVsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICBpbnQgcmVzdWx0ID0gMTc7CisgICAgICAgICAgICByZXN1bHQgPSAzMSAqIHJlc3VsdCArIHVyaUhvc3QuaGFzaENvZGUoKTsKKyAgICAgICAgICAgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgdXJpUG9ydDsKKyAgICAgICAgICAgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgKHByb3h5ICE9IG51bGwgPyBwcm94eS5oYXNoQ29kZSgpIDogMCk7CisgICAgICAgICAgICByZXN1bHQgPSAzMSAqIHJlc3VsdCArIChyZXF1aXJlc1R1bm5lbCA/IDEgOiAwKTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSHR0cENvbm5lY3Rpb24gY29ubmVjdChpbnQgY29ubmVjdFRpbWVvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEh0dHBDb25uZWN0aW9uKHRoaXMsIGNvbm5lY3RUaW1lb3V0KTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0h0dHBDb25uZWN0aW9uUG9vbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvSHR0cENvbm5lY3Rpb25Qb29sLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjFlOTRkZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0h0dHBDb25uZWN0aW9uUG9vbC5qYXZhCkBAIC0wLDAgKzEsMTE4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUubmV0Lmh0dHA7CisKK2ltcG9ydCBkYWx2aWsuc3lzdGVtLlNvY2tldFRhZ2dlcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBBIHBvb2wgb2YgSFRUUCBjb25uZWN0aW9ucy4gVGhpcyBjbGFzcyBleHBvc2VzIGl0cyB0dW5pbmcgcGFyYW1ldGVycyBhcworICogc3lzdGVtIHByb3BlcnRpZXM6CisgKiA8dWw+CisgKiAgIDxsaT57QGNvZGUgaHR0cC5rZWVwQWxpdmV9IHRydWUgaWYgSFRUUCBjb25uZWN0aW9ucyBzaG91bGQgYmUgcG9vbGVkIGF0CisgKiAgICAgICBhbGwuIERlZmF1bHQgaXMgdHJ1ZS4KKyAqICAgPGxpPntAY29kZSBodHRwLm1heENvbm5lY3Rpb25zfSBtYXhpbXVtIG51bWJlciBvZiBjb25uZWN0aW9ucyB0byBlYWNoIFVSSS4KKyAqICAgICAgIERlZmF1bHQgaXMgNS4KKyAqIDwvdWw+CisgKgorICogPHA+VGhpcyBjbGFzcyA8aT5kb2Vzbid0PC9pPiBhZGp1c3QgaXRzIGNvbmZpZ3VyYXRpb24gYXMgc3lzdGVtIHByb3BlcnRpZXMKKyAqIGFyZSBjaGFuZ2VkLiBUaGlzIGFzc3VtZXMgdGhhdCB0aGUgYXBwbGljYXRpb25zIHRoYXQgc2V0IHRoZXNlIHBhcmFtZXRlcnMgZG8KKyAqIHNvIGJlZm9yZSBtYWtpbmcgSFRUUCBjb25uZWN0aW9ucywgYW5kIHRoYXQgdGhpcyBjbGFzcyBpcyBpbml0aWFsaXplZCBsYXppbHkuCisgKi8KK2ZpbmFsIGNsYXNzIEh0dHBDb25uZWN0aW9uUG9vbCB7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEh0dHBDb25uZWN0aW9uUG9vbCBJTlNUQU5DRSA9IG5ldyBIdHRwQ29ubmVjdGlvblBvb2woKTsKKworICAgIHByaXZhdGUgZmluYWwgaW50IG1heENvbm5lY3Rpb25zOworICAgIHByaXZhdGUgZmluYWwgSGFzaE1hcDxIdHRwQ29ubmVjdGlvbi5BZGRyZXNzLCBMaXN0PEh0dHBDb25uZWN0aW9uPj4gY29ubmVjdGlvblBvb2wKKyAgICAgICAgICAgID0gbmV3IEhhc2hNYXA8SHR0cENvbm5lY3Rpb24uQWRkcmVzcywgTGlzdDxIdHRwQ29ubmVjdGlvbj4+KCk7CisKKyAgICBwcml2YXRlIEh0dHBDb25uZWN0aW9uUG9vbCgpIHsKKyAgICAgICAgU3RyaW5nIGtlZXBBbGl2ZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiaHR0cC5rZWVwQWxpdmUiKTsKKyAgICAgICAgaWYgKGtlZXBBbGl2ZSAhPSBudWxsICYmICFCb29sZWFuLnBhcnNlQm9vbGVhbihrZWVwQWxpdmUpKSB7CisgICAgICAgICAgICBtYXhDb25uZWN0aW9ucyA9IDA7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgbWF4Q29ubmVjdGlvbnNTdHJpbmcgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImh0dHAubWF4Q29ubmVjdGlvbnMiKTsKKyAgICAgICAgdGhpcy5tYXhDb25uZWN0aW9ucyA9IG1heENvbm5lY3Rpb25zU3RyaW5nICE9IG51bGwKKyAgICAgICAgICAgICAgICA/IEludGVnZXIucGFyc2VJbnQobWF4Q29ubmVjdGlvbnNTdHJpbmcpCisgICAgICAgICAgICAgICAgOiA1OworICAgIH0KKworICAgIHB1YmxpYyBIdHRwQ29ubmVjdGlvbiBnZXQoSHR0cENvbm5lY3Rpb24uQWRkcmVzcyBhZGRyZXNzLCBpbnQgY29ubmVjdFRpbWVvdXQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBGaXJzdCB0cnkgdG8gcmV1c2UgYW4gZXhpc3RpbmcgSFRUUCBjb25uZWN0aW9uLgorICAgICAgICBzeW5jaHJvbml6ZWQgKGNvbm5lY3Rpb25Qb29sKSB7CisgICAgICAgICAgICBMaXN0PEh0dHBDb25uZWN0aW9uPiBjb25uZWN0aW9ucyA9IGNvbm5lY3Rpb25Qb29sLmdldChhZGRyZXNzKTsKKyAgICAgICAgICAgIGlmIChjb25uZWN0aW9ucyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgd2hpbGUgKCFjb25uZWN0aW9ucy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgSHR0cENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IGNvbm5lY3Rpb25zLnJlbW92ZShjb25uZWN0aW9ucy5zaXplKCkgLSAxKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFjb25uZWN0aW9uLmlzU3RhbGUoKSkgeyAvLyBUT0RPOiB0aGlzIG9wIGRvZXMgSS9PIQorICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2luY2UgU29ja2V0IGlzIHJlY3ljbGVkLCByZS10YWcgYmVmb3JlIHVzaW5nCisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTb2NrZXQgc29ja2V0ID0gY29ubmVjdGlvbi5nZXRTb2NrZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIFNvY2tldFRhZ2dlci5nZXQoKS50YWcoc29ja2V0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb25uZWN0aW9uOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25Qb29sLnJlbW92ZShhZGRyZXNzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIFdlIGNvdWxkbid0IGZpbmQgYSByZXVzYWJsZSBjb25uZWN0aW9uLCBzbyB3ZSBuZWVkIHRvIGNyZWF0ZSBhIG5ldworICAgICAgICAgKiBjb25uZWN0aW9uLiBXZSdyZSBjYXJlZnVsIG5vdCB0byBkbyBzbyB3aGlsZSBob2xkaW5nIGEgbG9jayEKKyAgICAgICAgICovCisgICAgICAgIHJldHVybiBhZGRyZXNzLmNvbm5lY3QoY29ubmVjdFRpbWVvdXQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlY3ljbGUoSHR0cENvbm5lY3Rpb24gY29ubmVjdGlvbikgeworICAgICAgICBmaW5hbCBTb2NrZXQgc29ja2V0ID0gY29ubmVjdGlvbi5nZXRTb2NrZXQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldFRhZ2dlci5nZXQoKS51bnRhZyhzb2NrZXQpOworICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gV2hlbiB1bmFibGUgdG8gcmVtb3ZlIHRhZ2dpbmcsIHNraXAgcmVjeWNsaW5nIGFuZCBjbG9zZQorICAgICAgICAgICAgU3lzdGVtLmxvZ1coIlVuYWJsZSB0byB1bnRhZ1NvY2tldCgpOiAiICsgZSk7CisgICAgICAgICAgICBjb25uZWN0aW9uLmNsb3NlU29ja2V0QW5kU3RyZWFtcygpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG1heENvbm5lY3Rpb25zID4gMCAmJiBjb25uZWN0aW9uLmlzRWxpZ2libGVGb3JSZWN5Y2xpbmcoKSkgeworICAgICAgICAgICAgSHR0cENvbm5lY3Rpb24uQWRkcmVzcyBhZGRyZXNzID0gY29ubmVjdGlvbi5nZXRBZGRyZXNzKCk7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGNvbm5lY3Rpb25Qb29sKSB7CisgICAgICAgICAgICAgICAgTGlzdDxIdHRwQ29ubmVjdGlvbj4gY29ubmVjdGlvbnMgPSBjb25uZWN0aW9uUG9vbC5nZXQoYWRkcmVzcyk7CisgICAgICAgICAgICAgICAgaWYgKGNvbm5lY3Rpb25zID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMgPSBuZXcgQXJyYXlMaXN0PEh0dHBDb25uZWN0aW9uPigpOworICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uUG9vbC5wdXQoYWRkcmVzcywgY29ubmVjdGlvbnMpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvbnMuc2l6ZSgpIDwgbWF4Q29ubmVjdGlvbnMpIHsKKyAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuYWRkKGNvbm5lY3Rpb24pOworICAgICAgICAgICAgICAgICAgICByZXR1cm47IC8vIGtlZXAgdGhlIGNvbm5lY3Rpb24gb3BlbgorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIGRvbid0IGNsb3NlIHN0cmVhbXMgd2hpbGUgaG9sZGluZyBhIGxvY2shCisgICAgICAgIGNvbm5lY3Rpb24uY2xvc2VTb2NrZXRBbmRTdHJlYW1zKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvSHR0cERhdGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0h0dHBEYXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTQxY2Y4MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0h0dHBEYXRlLmphdmEKQEAgLTAsMCArMSw5MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5uZXQuaHR0cDsKKworaW1wb3J0IGphdmEudGV4dC5EYXRlRm9ybWF0OworaW1wb3J0IGphdmEudGV4dC5QYXJzZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnRleHQuU2ltcGxlRGF0ZUZvcm1hdDsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5UaW1lWm9uZTsKKworLyoqCisgKiBCZXN0LWVmZm9ydCBwYXJzZXIgZm9yIEhUVFAgZGF0ZXMuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBIdHRwRGF0ZSB7CisKKyAgICAvKioKKyAgICAgKiBNb3N0IHdlYnNpdGVzIHNlcnZlIGNvb2tpZXMgaW4gdGhlIGJsZXNzZWQgZm9ybWF0LiBFYWdlcmx5IGNyZWF0ZSB0aGUgcGFyc2VyIHRvIGVuc3VyZSBzdWNoCisgICAgICogY29va2llcyBhcmUgb24gdGhlIGZhc3QgcGF0aC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUaHJlYWRMb2NhbDxEYXRlRm9ybWF0PiBTVEFOREFSRF9EQVRFX0ZPUk1BVAorICAgICAgICAgICAgPSBuZXcgVGhyZWFkTG9jYWw8RGF0ZUZvcm1hdD4oKSB7CisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgRGF0ZUZvcm1hdCBpbml0aWFsVmFsdWUoKSB7CisgICAgICAgICAgICBEYXRlRm9ybWF0IHJmYzExMjMgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgiRUVFLCBkZCBNTU0geXl5eSBISDptbTpzcyB6enoiLCBMb2NhbGUuVVMpOworICAgICAgICAgICAgcmZjMTEyMy5zZXRUaW1lWm9uZShUaW1lWm9uZS5nZXRUaW1lWm9uZSgiVVRDIikpOworICAgICAgICAgICAgcmV0dXJuIHJmYzExMjM7CisgICAgICAgIH0KKyAgICB9OworCisgICAgLyoqCisgICAgICogSWYgd2UgZmFpbCB0byBwYXJzZSBhIGRhdGUgaW4gYSBub24tc3RhbmRhcmQgZm9ybWF0LCB0cnkgZWFjaCBvZiB0aGVzZSBmb3JtYXRzIGluIHNlcXVlbmNlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIEJST1dTRVJfQ09NUEFUSUJMRV9EQVRFX0ZPUk1BVFMgPSBuZXcgU3RyaW5nW10geworICAgICAgICAgICAgLyogVGhpcyBsaXN0IGNvbWVzIGZyb20gIHtAY29kZSBvcmcuYXBhY2hlLmh0dHAuaW1wbC5jb29raWUuQnJvd3NlckNvbXBhdFNwZWN9LiAqLworICAgICAgICAgICAgIkVFRUUsIGRkLU1NTS15eSBISDptbTpzcyB6enoiLCAvLyBSRkMgMTAzNgorICAgICAgICAgICAgIkVFRSBNTU0gZCBISDptbTpzcyB5eXl5IiwgLy8gQU5TSSBDIGFzY3RpbWUoKQorICAgICAgICAgICAgIkVFRSwgZGQtTU1NLXl5eXkgSEg6bW06c3MgeiIsCisgICAgICAgICAgICAiRUVFLCBkZC1NTU0teXl5eSBISC1tbS1zcyB6IiwKKyAgICAgICAgICAgICJFRUUsIGRkIE1NTSB5eSBISDptbTpzcyB6IiwKKyAgICAgICAgICAgICJFRUUgZGQtTU1NLXl5eXkgSEg6bW06c3MgeiIsCisgICAgICAgICAgICAiRUVFIGRkIE1NTSB5eXl5IEhIOm1tOnNzIHoiLAorICAgICAgICAgICAgIkVFRSBkZC1NTU0teXl5eSBISC1tbS1zcyB6IiwKKyAgICAgICAgICAgICJFRUUgZGQtTU1NLXl5IEhIOm1tOnNzIHoiLAorICAgICAgICAgICAgIkVFRSBkZCBNTU0geXkgSEg6bW06c3MgeiIsCisgICAgICAgICAgICAiRUVFLGRkLU1NTS15eSBISDptbTpzcyB6IiwKKyAgICAgICAgICAgICJFRUUsZGQtTU1NLXl5eXkgSEg6bW06c3MgeiIsCisgICAgICAgICAgICAiRUVFLCBkZC1NTS15eXl5IEhIOm1tOnNzIHoiLAorCisgICAgICAgICAgICAvKiBSSSBidWcgNjY0MTMxNSBjbGFpbXMgYSBjb29raWUgb2YgdGhpcyBmb3JtYXQgd2FzIG9uY2Ugc2VydmVkIGJ5IHd3dy55YWhvby5jb20gKi8KKyAgICAgICAgICAgICJFRUUgTU1NIGQgeXl5eSBISDptbTpzcyB6IiwKKyAgICB9OworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGF0ZSBmb3Ige0Bjb2RlIHZhbHVlfS4gUmV0dXJucyBudWxsIGlmIHRoZSB2YWx1ZSBjb3VsZG4ndCBiZQorICAgICAqIHBhcnNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIERhdGUgcGFyc2UoU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gU1RBTkRBUkRfREFURV9GT1JNQVQuZ2V0KCkucGFyc2UodmFsdWUpOworICAgICAgICB9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBpZ25vcmUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKFN0cmluZyBmb3JtYXRTdHJpbmcgOiBCUk9XU0VSX0NPTVBBVElCTEVfREFURV9GT1JNQVRTKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2ltcGxlRGF0ZUZvcm1hdChmb3JtYXRTdHJpbmcsIExvY2FsZS5VUykucGFyc2UodmFsdWUpOworICAgICAgICAgICAgfSBjYXRjaCAoUGFyc2VFeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyaW5nIGZvciB7QGNvZGUgdmFsdWV9LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGZvcm1hdChEYXRlIHZhbHVlKSB7CisgICAgICAgIHJldHVybiBTVEFOREFSRF9EQVRFX0ZPUk1BVC5nZXQoKS5mb3JtYXQodmFsdWUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0h0dHBFbmdpbmUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0h0dHBFbmdpbmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNWYyOGY1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvSHR0cEVuZ2luZS5qYXZhCkBAIC0wLDAgKzEsODA3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUubmV0Lmh0dHA7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEubmV0LkNhY2hlUmVxdWVzdDsKK2ltcG9ydCBqYXZhLm5ldC5DYWNoZVJlc3BvbnNlOworaW1wb3J0IGphdmEubmV0LkNvb2tpZUhhbmRsZXI7CitpbXBvcnQgamF2YS5uZXQuSHR0cFVSTENvbm5lY3Rpb247CitpbXBvcnQgamF2YS5uZXQuUHJveHk7CitpbXBvcnQgamF2YS5uZXQuUmVzcG9uc2VDYWNoZTsKK2ltcG9ydCBqYXZhLm5ldC5VUkk7CitpbXBvcnQgamF2YS5uZXQuVVJJU3ludGF4RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC56aXAuR1pJUElucHV0U3RyZWFtOworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKK2ltcG9ydCBsaWJjb3JlLmlvLlN0cmVhbXM7CitpbXBvcnQgbGliY29yZS51dGlsLkVtcHR5QXJyYXk7CisKKy8qKgorICogSGFuZGxlcyBhIHNpbmdsZSBIVFRQIHJlcXVlc3QvcmVzcG9uc2UgcGFpci4gRWFjaCBIVFRQIGVuZ2luZSBmb2xsb3dzIHRoaXMKKyAqIGxpZmVjeWNsZToKKyAqIDxvbD4KKyAqICAgICA8bGk+SXQgaXMgY3JlYXRlZC4KKyAqICAgICA8bGk+VGhlIEhUVFAgcmVxdWVzdCBtZXNzYWdlIGlzIHNlbnQgd2l0aCBzZW5kUmVxdWVzdCgpLiBPbmNlIHRoZSByZXF1ZXN0CisgKiAgICAgICAgIGlzIHNlbnQgaXQgaXMgYW4gZXJyb3IgdG8gbW9kaWZ5IHRoZSByZXF1ZXN0IGhlYWRlcnMuIEFmdGVyCisgKiAgICAgICAgIHNlbmRSZXF1ZXN0KCkgaGFzIGJlZW4gY2FsbGVkIHRoZSByZXF1ZXN0IGJvZHkgY2FuIGJlIHdyaXR0ZW4gdG8gaWYKKyAqICAgICAgICAgaXQgZXhpc3RzLgorICogICAgIDxsaT5UaGUgSFRUUCByZXNwb25zZSBtZXNzYWdlIGlzIHJlYWQgd2l0aCByZWFkUmVzcG9uc2UoKS4gQWZ0ZXIgdGhlCisgKiAgICAgICAgIHJlc3BvbnNlIGhhcyBiZWVuIHJlYWQgdGhlIHJlc3BvbnNlIGhlYWRlcnMgYW5kIGJvZHkgY2FuIGJlIHJlYWQuCisgKiAgICAgICAgIEFsbCByZXNwb25zZXMgaGF2ZSBhIHJlc3BvbnNlIGJvZHkgaW5wdXQgc3RyZWFtLCB0aG91Z2ggaW4gc29tZQorICogICAgICAgICBpbnN0YW5jZXMgdGhpcyBzdHJlYW0gaXMgZW1wdHkuCisgKiA8L29sPgorICoKKyAqIDxwPlRoZSByZXF1ZXN0IGFuZCByZXNwb25zZSBtYXkgYmUgc2VydmVkIGJ5IHRoZSBIVFRQIHJlc3BvbnNlIGNhY2hlLCBieSB0aGUKKyAqIG5ldHdvcmssIG9yIGJ5IGJvdGggaW4gdGhlIGV2ZW50IG9mIGEgY29uZGl0aW9uYWwgR0VULgorICoKKyAqIDxwPlRoaXMgY2xhc3MgbWF5IGhvbGQgYSBzb2NrZXQgY29ubmVjdGlvbiB0aGF0IG5lZWRzIHRvIGJlIHJlbGVhc2VkIG9yCisgKiByZWN5Y2xlZC4gQnkgZGVmYXVsdCwgdGhpcyBzb2NrZXQgY29ubmVjdGlvbiBpcyBoZWxkIHdoZW4gdGhlIGxhc3QgYnl0ZSBvZgorICogdGhlIHJlc3BvbnNlIGlzIGNvbnN1bWVkLiBUbyByZWxlYXNlIHRoZSBjb25uZWN0aW9uIHdoZW4gaXQgaXMgbm8gbG9uZ2VyCisgKiByZXF1aXJlZCwgdXNlIHtAbGluayAjYXV0b21hdGljYWxseVJlbGVhc2VDb25uZWN0aW9uVG9Qb29sKCl9LgorICovCitwdWJsaWMgY2xhc3MgSHR0cEVuZ2luZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ2FjaGVSZXNwb25zZSBCQURfR0FURVdBWV9SRVNQT05TRSA9IG5ldyBDYWNoZVJlc3BvbnNlKCkgeworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gZ2V0SGVhZGVycygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IHJlc3VsdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PigpOworICAgICAgICAgICAgcmVzdWx0LnB1dChudWxsLCBDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KCJIVFRQLzEuMSA1MDIgQmFkIEdhdGV3YXkiKSk7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0Qm9keSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKEVtcHR5QXJyYXkuQllURSk7CisgICAgICAgIH0KKyAgICB9OworCisgICAgLyoqCisgICAgICogVGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHRvIGJ1ZmZlciB3aGVuIHNlbmRpbmcgaGVhZGVycyBhbmQgYSByZXF1ZXN0CisgICAgICogYm9keS4gV2hlbiB0aGUgaGVhZGVycyBhbmQgYm9keSBjYW4gYmUgc2VudCBpbiBhIHNpbmdsZSB3cml0ZSwgdGhlCisgICAgICogcmVxdWVzdCBjb21wbGV0ZXMgc29vbmVyLiBJbiBvbmUgV2lGaSBiZW5jaG1hcmssIHVzaW5nIGEgbGFyZ2UgZW5vdWdoCisgICAgICogYnVmZmVyIHNwZWQgdXAgc29tZSB1cGxvYWRzIGJ5IGhhbGYuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9SRVFVRVNUX0JVRkZFUl9MRU5HVEggPSAzMjc2ODsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfQ0hVTktfTEVOR1RIID0gMTAyNDsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE9QVElPTlMgPSAiT1BUSU9OUyI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VUID0gIkdFVCI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSEVBRCA9ICJIRUFEIjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQT1NUID0gIlBPU1QiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBVVCA9ICJQVVQiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERFTEVURSA9ICJERUxFVEUiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRSQUNFID0gIlRSQUNFIjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDT05ORUNUID0gIkNPTk5FQ1QiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9DT05USU5VRSA9IDEwMDsKKworICAgIC8qKgorICAgICAqIEhUVFAgMS4xIGRvZXNuJ3Qgc3BlY2lmeSBob3cgbWFueSByZWRpcmVjdHMgdG8gZm9sbG93LCBidXQgSFRUUC8xLjAKKyAgICAgKiByZWNvbW1lbmRlZCA1LiBodHRwOi8vd3d3LnczLm9yZy9Qcm90b2NvbHMvSFRUUC8xLjAvc3BlYy5odG1sI0NvZGUzeHgKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfUkVESVJFQ1RTID0gNTsKKworICAgIHByb3RlY3RlZCBmaW5hbCBIdHRwVVJMQ29ubmVjdGlvbkltcGwgcG9saWN5OworCisgICAgcHJvdGVjdGVkIGZpbmFsIFN0cmluZyBtZXRob2Q7CisKKyAgICBwcml2YXRlIFJlc3BvbnNlU291cmNlIHJlc3BvbnNlU291cmNlOworCisgICAgcHJvdGVjdGVkIEh0dHBDb25uZWN0aW9uIGNvbm5lY3Rpb247CisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBzb2NrZXRJbjsKKyAgICBwcml2YXRlIE91dHB1dFN0cmVhbSBzb2NrZXRPdXQ7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIHN0cmVhbSBidWZmZXJzIHRoZSByZXF1ZXN0IGhlYWRlcnMgYW5kIHRoZSByZXF1ZXN0IGJvZHkgd2hlbiB0aGVpcgorICAgICAqIGNvbWJpbmVkIHNpemUgaXMgbGVzcyB0aGFuIE1BWF9SRVFVRVNUX0JVRkZFUl9MRU5HVEguIEJ5IGNvbWJpbmluZyB0aGVtCisgICAgICogd2UgY2FuIHNhdmUgc29ja2V0IHdyaXRlcywgd2hpY2ggaW4gdHVybiBzYXZlcyBhIHBhY2tldCB0cmFuc21pc3Npb24uCisgICAgICogVGhpcyBpcyBzb2NrZXRPdXQgaWYgdGhlIHJlcXVlc3Qgc2l6ZSBpcyBsYXJnZSBvciB1bmtub3duLgorICAgICAqLworICAgIHByaXZhdGUgT3V0cHV0U3RyZWFtIHJlcXVlc3RPdXQ7CisgICAgcHJpdmF0ZSBBYnN0cmFjdEh0dHBPdXRwdXRTdHJlYW0gcmVxdWVzdEJvZHlPdXQ7CisKKyAgICBwcml2YXRlIElucHV0U3RyZWFtIHJlc3BvbnNlQm9keUluOworCisgICAgcHJpdmF0ZSBmaW5hbCBSZXNwb25zZUNhY2hlIHJlc3BvbnNlQ2FjaGUgPSBSZXNwb25zZUNhY2hlLmdldERlZmF1bHQoKTsKKyAgICBwcml2YXRlIENhY2hlUmVzcG9uc2UgY2FjaGVSZXNwb25zZTsKKyAgICBwcml2YXRlIENhY2hlUmVxdWVzdCBjYWNoZVJlcXVlc3Q7CisKKyAgICAvKiogVGhlIHRpbWUgd2hlbiB0aGUgcmVxdWVzdCBoZWFkZXJzIHdlcmUgd3JpdHRlbiwgb3IgLTEgaWYgdGhleSBoYXZlbid0IGJlZW4gd3JpdHRlbiB5ZXQuICovCisgICAgcHJpdmF0ZSBsb25nIHNlbnRSZXF1ZXN0TWlsbGlzID0gLTE7CisKKyAgICAvKioKKyAgICAgKiBUcnVlIGlmIHRoaXMgY2xpZW50IGFkZGVkIGFuICJBY2NlcHQtRW5jb2Rpbmc6IGd6aXAiIGhlYWRlciBmaWVsZCBhbmQgaXMKKyAgICAgKiB0aGVyZWZvcmUgcmVzcG9uc2libGUgZm9yIGFsc28gZGVjb21wcmVzc2luZyB0aGUgdHJhbnNmZXIgc3RyZWFtLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiB0cmFuc3BhcmVudEd6aXA7CisKKyAgICBib29sZWFuIHNlbmRDaHVua2VkOworCisgICAgLyoqCisgICAgICogVGhlIHZlcnNpb24gdGhpcyBjbGllbnQgd2lsbCB1c2UuIEVpdGhlciAwIGZvciBIVFRQLzEuMCwgb3IgMSBmb3IKKyAgICAgKiBIVFRQLzEuMS4gVXBvbiByZWNlaXZpbmcgYSBub24tSFRUUC8xLjEgcmVzcG9uc2UsIHRoaXMgY2xpZW50CisgICAgICogYXV0b21hdGljYWxseSBzZXRzIGl0cyB2ZXJzaW9uIHRvIEhUVFAvMS4wLgorICAgICAqLworICAgIC8vIFRPRE86IGlzIEhUVFAgbWlub3IgdmVyc2lvbiB0cmFja2VkIGFjcm9zcyBIdHRwRW5naW5lcz8KKyAgICBwcml2YXRlIGludCBodHRwTWlub3JWZXJzaW9uID0gMTsgLy8gQXNzdW1lIEhUVFAvMS4xCisKKyAgICBwcml2YXRlIGZpbmFsIFVSSSB1cmk7CisKKyAgICBwcml2YXRlIGZpbmFsIFJlcXVlc3RIZWFkZXJzIHJlcXVlc3RIZWFkZXJzOworCisgICAgLyoqIE51bGwgdW50aWwgYSByZXNwb25zZSBpcyByZWNlaXZlZCBmcm9tIHRoZSBuZXR3b3JrIG9yIHRoZSBjYWNoZSAqLworICAgIHByaXZhdGUgUmVzcG9uc2VIZWFkZXJzIHJlc3BvbnNlSGVhZGVyczsKKworICAgIC8qCisgICAgICogVGhlIGNhY2hlIHJlc3BvbnNlIGN1cnJlbnRseSBiZWluZyB2YWxpZGF0ZWQgb24gYSBjb25kaXRpb25hbCBnZXQuIE51bGwKKyAgICAgKiBpZiB0aGUgY2FjaGVkIHJlc3BvbnNlIGRvZXNuJ3QgZXhpc3Qgb3IgZG9lc24ndCBuZWVkIHZhbGlkYXRpb24uIElmIHRoZQorICAgICAqIGNvbmRpdGlvbmFsIGdldCBzdWNjZWVkcywgdGhlc2Ugd2lsbCBiZSB1c2VkIGZvciB0aGUgcmVzcG9uc2UgaGVhZGVycyBhbmQKKyAgICAgKiBib2R5LiBJZiBpdCBmYWlscywgdGhlc2UgYmUgY2xvc2VkIGFuZCBzZXQgdG8gbnVsbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFJlc3BvbnNlSGVhZGVycyBjYWNoZWRSZXNwb25zZUhlYWRlcnM7CisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBjYWNoZWRSZXNwb25zZUJvZHk7CisKKyAgICAvKioKKyAgICAgKiBUcnVlIGlmIHRoZSBzb2NrZXQgY29ubmVjdGlvbiBzaG91bGQgYmUgcmVsZWFzZWQgdG8gdGhlIGNvbm5lY3Rpb24gcG9vbAorICAgICAqIHdoZW4gdGhlIHJlc3BvbnNlIGhhcyBiZWVuIGZ1bGx5IHJlYWQuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGF1dG9tYXRpY2FsbHlSZWxlYXNlQ29ubmVjdGlvblRvUG9vbDsKKworICAgIC8qKiBUcnVlIGlmIHRoZSBzb2NrZXQgY29ubmVjdGlvbiBpcyBubyBsb25nZXIgbmVlZGVkIGJ5IHRoaXMgZW5naW5lLiAqLworICAgIHByaXZhdGUgYm9vbGVhbiBjb25uZWN0aW9uUmVsZWFzZWQ7CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gcmVxdWVzdEhlYWRlcnMgdGhlIGNsaWVudCdzIHN1cHBsaWVkIHJlcXVlc3QgaGVhZGVycy4gVGhpcyBjbGFzcworICAgICAqICAgICBjcmVhdGVzIGEgcHJpdmF0ZSBjb3B5IHRoYXQgaXQgY2FuIG11dGF0ZS4KKyAgICAgKiBAcGFyYW0gY29ubmVjdGlvbiB0aGUgY29ubmVjdGlvbiB1c2VkIGZvciBhbiBpbnRlcm1lZGlhdGUgcmVzcG9uc2UKKyAgICAgKiAgICAgaW1tZWRpYXRlbHkgcHJpb3IgdG8gdGhpcyByZXF1ZXN0L3Jlc3BvbnNlIHBhaXIsIHN1Y2ggYXMgYSBzYW1lLWhvc3QKKyAgICAgKiAgICAgcmVkaXJlY3QuIFRoaXMgZW5naW5lIGFzc3VtZXMgb3duZXJzaGlwIG9mIHRoZSBjb25uZWN0aW9uIGFuZCBtdXN0CisgICAgICogICAgIHJlbGVhc2UgaXQgd2hlbiBpdCBpcyB1bm5lZWRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSHR0cEVuZ2luZShIdHRwVVJMQ29ubmVjdGlvbkltcGwgcG9saWN5LCBTdHJpbmcgbWV0aG9kLCBSYXdIZWFkZXJzIHJlcXVlc3RIZWFkZXJzLAorICAgICAgICAgICAgSHR0cENvbm5lY3Rpb24gY29ubmVjdGlvbiwgUmV0cnlhYmxlT3V0cHV0U3RyZWFtIHJlcXVlc3RCb2R5T3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLnBvbGljeSA9IHBvbGljeTsKKyAgICAgICAgdGhpcy5tZXRob2QgPSBtZXRob2Q7CisgICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247CisgICAgICAgIHRoaXMucmVxdWVzdEJvZHlPdXQgPSByZXF1ZXN0Qm9keU91dDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdXJpID0gcG9saWN5LmdldFVSTCgpLnRvVVJJTGVuaWVudCgpOworICAgICAgICB9IGNhdGNoIChVUklTeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGUpOworICAgICAgICB9CisKKyAgICAgICAgdGhpcy5yZXF1ZXN0SGVhZGVycyA9IG5ldyBSZXF1ZXN0SGVhZGVycyh1cmksIG5ldyBSYXdIZWFkZXJzKHJlcXVlc3RIZWFkZXJzKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmlndXJlcyBvdXQgd2hhdCB0aGUgcmVzcG9uc2Ugc291cmNlIHdpbGwgYmUsIGFuZCBvcGVucyBhIHNvY2tldCB0byB0aGF0CisgICAgICogc291cmNlIGlmIG5lY2Vzc2FyeS4gUHJlcGFyZXMgdGhlIHJlcXVlc3QgaGVhZGVycyBhbmQgZ2V0cyByZWFkeSB0byBzdGFydAorICAgICAqIHdyaXRpbmcgdGhlIHJlcXVlc3QgYm9keSBpZiBpdCBleGlzdHMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgc2VuZFJlcXVlc3QoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAocmVzcG9uc2VTb3VyY2UgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgcHJlcGFyZVJhd1JlcXVlc3RIZWFkZXJzKCk7CisgICAgICAgIGluaXRSZXNwb25zZVNvdXJjZSgpOworICAgICAgICBpZiAocmVzcG9uc2VDYWNoZSBpbnN0YW5jZW9mIEh0dHBSZXNwb25zZUNhY2hlKSB7CisgICAgICAgICAgICAoKEh0dHBSZXNwb25zZUNhY2hlKSByZXNwb25zZUNhY2hlKS50cmFja1Jlc3BvbnNlKHJlc3BvbnNlU291cmNlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIFRoZSByYXcgcmVzcG9uc2Ugc291cmNlIG1heSByZXF1aXJlIHRoZSBuZXR3b3JrLCBidXQgdGhlIHJlcXVlc3QKKyAgICAgICAgICogaGVhZGVycyBtYXkgZm9yYmlkIG5ldHdvcmsgdXNlLiBJbiB0aGF0IGNhc2UsIGRpc3Bvc2Ugb2YgdGhlIG5ldHdvcmsKKyAgICAgICAgICogcmVzcG9uc2UgYW5kIHVzZSBhIEJBRF9HQVRFV0FZIHJlc3BvbnNlIGluc3RlYWQuCisgICAgICAgICAqLworICAgICAgICBpZiAocmVxdWVzdEhlYWRlcnMuaXNPbmx5SWZDYWNoZWQoKSAmJiByZXNwb25zZVNvdXJjZS5yZXF1aXJlc0Nvbm5lY3Rpb24oKSkgeworICAgICAgICAgICAgaWYgKHJlc3BvbnNlU291cmNlID09IFJlc3BvbnNlU291cmNlLkNPTkRJVElPTkFMX0NBQ0hFKSB7CisgICAgICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkoY2FjaGVkUmVzcG9uc2VCb2R5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMucmVzcG9uc2VTb3VyY2UgPSBSZXNwb25zZVNvdXJjZS5DQUNIRTsKKyAgICAgICAgICAgIHRoaXMuY2FjaGVSZXNwb25zZSA9IEJBRF9HQVRFV0FZX1JFU1BPTlNFOworICAgICAgICAgICAgUmF3SGVhZGVycyByYXdSZXNwb25zZUhlYWRlcnMgPSBSYXdIZWFkZXJzLmZyb21NdWx0aW1hcChjYWNoZVJlc3BvbnNlLmdldEhlYWRlcnMoKSk7CisgICAgICAgICAgICBzZXRSZXNwb25zZShuZXcgUmVzcG9uc2VIZWFkZXJzKHVyaSwgcmF3UmVzcG9uc2VIZWFkZXJzKSwgY2FjaGVSZXNwb25zZS5nZXRCb2R5KCkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHJlc3BvbnNlU291cmNlLnJlcXVpcmVzQ29ubmVjdGlvbigpKSB7CisgICAgICAgICAgICBzZW5kU29ja2V0UmVxdWVzdCgpOworICAgICAgICB9IGVsc2UgaWYgKGNvbm5lY3Rpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgSHR0cENvbm5lY3Rpb25Qb29sLklOU1RBTkNFLnJlY3ljbGUoY29ubmVjdGlvbik7CisgICAgICAgICAgICBjb25uZWN0aW9uID0gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemUgdGhlIHNvdXJjZSBmb3IgdGhpcyByZXNwb25zZS4gSXQgbWF5IGJlIGNvcnJlY3RlZCBsYXRlciBpZiB0aGUKKyAgICAgKiByZXF1ZXN0IGhlYWRlcnMgZm9yYmlkcyBuZXR3b3JrIHVzZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdFJlc3BvbnNlU291cmNlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmVzcG9uc2VTb3VyY2UgPSBSZXNwb25zZVNvdXJjZS5ORVRXT1JLOworICAgICAgICBpZiAoIXBvbGljeS5nZXRVc2VDYWNoZXMoKSB8fCByZXNwb25zZUNhY2hlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIENhY2hlUmVzcG9uc2UgY2FuZGlkYXRlID0gcmVzcG9uc2VDYWNoZS5nZXQodXJpLCBtZXRob2QsCisgICAgICAgICAgICAgICAgcmVxdWVzdEhlYWRlcnMuZ2V0SGVhZGVycygpLnRvTXVsdGltYXAoKSk7CisgICAgICAgIGlmIChjYW5kaWRhdGUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PiByZXNwb25zZUhlYWRlcnNNYXAgPSBjYW5kaWRhdGUuZ2V0SGVhZGVycygpOworICAgICAgICBjYWNoZWRSZXNwb25zZUJvZHkgPSBjYW5kaWRhdGUuZ2V0Qm9keSgpOworICAgICAgICBpZiAoIWFjY2VwdENhY2hlUmVzcG9uc2VUeXBlKGNhbmRpZGF0ZSkKKyAgICAgICAgICAgICAgICB8fCByZXNwb25zZUhlYWRlcnNNYXAgPT0gbnVsbAorICAgICAgICAgICAgICAgIHx8IGNhY2hlZFJlc3BvbnNlQm9keSA9PSBudWxsKSB7CisgICAgICAgICAgICBJb1V0aWxzLmNsb3NlUXVpZXRseShjYWNoZWRSZXNwb25zZUJvZHkpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgUmF3SGVhZGVycyByYXdSZXNwb25zZUhlYWRlcnMgPSBSYXdIZWFkZXJzLmZyb21NdWx0aW1hcChyZXNwb25zZUhlYWRlcnNNYXApOworICAgICAgICBjYWNoZWRSZXNwb25zZUhlYWRlcnMgPSBuZXcgUmVzcG9uc2VIZWFkZXJzKHVyaSwgcmF3UmVzcG9uc2VIZWFkZXJzKTsKKyAgICAgICAgbG9uZyBub3cgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgdGhpcy5yZXNwb25zZVNvdXJjZSA9IGNhY2hlZFJlc3BvbnNlSGVhZGVycy5jaG9vc2VSZXNwb25zZVNvdXJjZShub3csIHJlcXVlc3RIZWFkZXJzKTsKKyAgICAgICAgaWYgKHJlc3BvbnNlU291cmNlID09IFJlc3BvbnNlU291cmNlLkNBQ0hFKSB7CisgICAgICAgICAgICB0aGlzLmNhY2hlUmVzcG9uc2UgPSBjYW5kaWRhdGU7CisgICAgICAgICAgICBzZXRSZXNwb25zZShjYWNoZWRSZXNwb25zZUhlYWRlcnMsIGNhY2hlZFJlc3BvbnNlQm9keSk7CisgICAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2VTb3VyY2UgPT0gUmVzcG9uc2VTb3VyY2UuQ09ORElUSU9OQUxfQ0FDSEUpIHsKKyAgICAgICAgICAgIHRoaXMuY2FjaGVSZXNwb25zZSA9IGNhbmRpZGF0ZTsKKyAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZVNvdXJjZSA9PSBSZXNwb25zZVNvdXJjZS5ORVRXT1JLKSB7CisgICAgICAgICAgICBJb1V0aWxzLmNsb3NlUXVpZXRseShjYWNoZWRSZXNwb25zZUJvZHkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc2VuZFNvY2tldFJlcXVlc3QoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY29ubmVjdGlvbiA9PSBudWxsKSB7CisgICAgICAgICAgICBjb25uZWN0KCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc29ja2V0T3V0ICE9IG51bGwgfHwgcmVxdWVzdE91dCAhPSBudWxsIHx8IHNvY2tldEluICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHNvY2tldE91dCA9IGNvbm5lY3Rpb24uZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIHJlcXVlc3RPdXQgPSBzb2NrZXRPdXQ7CisgICAgICAgIHNvY2tldEluID0gY29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpOworCisgICAgICAgIGlmIChoYXNSZXF1ZXN0Qm9keSgpKSB7CisgICAgICAgICAgICBpbml0UmVxdWVzdEJvZHlPdXQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbm5lY3QgdG8gdGhlIG9yaWdpbiBzZXJ2ZXIgZWl0aGVyIGRpcmVjdGx5IG9yIHZpYSBhIHByb3h5LgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGNvbm5lY3QoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY29ubmVjdGlvbiA9PSBudWxsKSB7CisgICAgICAgICAgICBjb25uZWN0aW9uID0gb3BlblNvY2tldENvbm5lY3Rpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCBmaW5hbCBIdHRwQ29ubmVjdGlvbiBvcGVuU29ja2V0Q29ubmVjdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEh0dHBDb25uZWN0aW9uIHJlc3VsdCA9IEh0dHBDb25uZWN0aW9uLmNvbm5lY3QoCisgICAgICAgICAgICAgICAgdXJpLCBwb2xpY3kuZ2V0UHJveHkoKSwgcmVxdWlyZXNUdW5uZWwoKSwgcG9saWN5LmdldENvbm5lY3RUaW1lb3V0KCkpOworICAgICAgICBQcm94eSBwcm94eSA9IHJlc3VsdC5nZXRBZGRyZXNzKCkuZ2V0UHJveHkoKTsKKyAgICAgICAgaWYgKHByb3h5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHBvbGljeS5zZXRQcm94eShwcm94eSk7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0LnNldFNvVGltZW91dChwb2xpY3kuZ2V0UmVhZFRpbWVvdXQoKSk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgaW5pdFJlcXVlc3RCb2R5T3V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGNodW5rTGVuZ3RoID0gcG9saWN5LmdldENodW5rTGVuZ3RoKCk7CisgICAgICAgIGlmIChjaHVua0xlbmd0aCA+IDAgfHwgcmVxdWVzdEhlYWRlcnMuaXNDaHVua2VkKCkpIHsKKyAgICAgICAgICAgIHNlbmRDaHVua2VkID0gdHJ1ZTsKKyAgICAgICAgICAgIGlmIChjaHVua0xlbmd0aCA9PSAtMSkgeworICAgICAgICAgICAgICAgIGNodW5rTGVuZ3RoID0gREVGQVVMVF9DSFVOS19MRU5HVEg7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoc29ja2V0T3V0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIk5vIHNvY2tldCB0byB3cml0ZSB0bzsgd2FzIGEgUE9TVCBjYWNoZWQ/Iik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoaHR0cE1pbm9yVmVyc2lvbiA9PSAwKSB7CisgICAgICAgICAgICBzZW5kQ2h1bmtlZCA9IGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgaW50IGZpeGVkQ29udGVudExlbmd0aCA9IHBvbGljeS5nZXRGaXhlZENvbnRlbnRMZW5ndGgoKTsKKyAgICAgICAgaWYgKHJlcXVlc3RCb2R5T3V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vIHJlcXVlc3QgYm9keSB3YXMgYWxyZWFkeSBpbml0aWFsaXplZCBieSB0aGUgcHJlZGVjZXNzb3IgSFRUUCBlbmdpbmUKKyAgICAgICAgfSBlbHNlIGlmIChmaXhlZENvbnRlbnRMZW5ndGggIT0gLTEpIHsKKyAgICAgICAgICAgIHdyaXRlUmVxdWVzdEhlYWRlcnMoZml4ZWRDb250ZW50TGVuZ3RoKTsKKyAgICAgICAgICAgIHJlcXVlc3RCb2R5T3V0ID0gbmV3IEZpeGVkTGVuZ3RoT3V0cHV0U3RyZWFtKHJlcXVlc3RPdXQsIGZpeGVkQ29udGVudExlbmd0aCk7CisgICAgICAgIH0gZWxzZSBpZiAoc2VuZENodW5rZWQpIHsKKyAgICAgICAgICAgIHdyaXRlUmVxdWVzdEhlYWRlcnMoLTEpOworICAgICAgICAgICAgcmVxdWVzdEJvZHlPdXQgPSBuZXcgQ2h1bmtlZE91dHB1dFN0cmVhbShyZXF1ZXN0T3V0LCBjaHVua0xlbmd0aCk7CisgICAgICAgIH0gZWxzZSBpZiAocmVxdWVzdEhlYWRlcnMuZ2V0Q29udGVudExlbmd0aCgpICE9IC0xKSB7CisgICAgICAgICAgICB3cml0ZVJlcXVlc3RIZWFkZXJzKHJlcXVlc3RIZWFkZXJzLmdldENvbnRlbnRMZW5ndGgoKSk7CisgICAgICAgICAgICByZXF1ZXN0Qm9keU91dCA9IG5ldyBSZXRyeWFibGVPdXRwdXRTdHJlYW0ocmVxdWVzdEhlYWRlcnMuZ2V0Q29udGVudExlbmd0aCgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlcXVlc3RCb2R5T3V0ID0gbmV3IFJldHJ5YWJsZU91dHB1dFN0cmVhbSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIGJvZHkgdGhlIHJlc3BvbnNlIGJvZHksIG9yIG51bGwgaWYgaXQgZG9lc24ndCBleGlzdCBvciBpc24ndAorICAgICAqICAgICBhdmFpbGFibGUuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNldFJlc3BvbnNlKFJlc3BvbnNlSGVhZGVycyBoZWFkZXJzLCBJbnB1dFN0cmVhbSBib2R5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGhpcy5yZXNwb25zZUJvZHlJbiAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5yZXNwb25zZUhlYWRlcnMgPSBoZWFkZXJzOworICAgICAgICB0aGlzLmh0dHBNaW5vclZlcnNpb24gPSByZXNwb25zZUhlYWRlcnMuZ2V0SGVhZGVycygpLmdldEh0dHBNaW5vclZlcnNpb24oKTsKKyAgICAgICAgaWYgKGJvZHkgIT0gbnVsbCkgeworICAgICAgICAgICAgaW5pdENvbnRlbnRTdHJlYW0oYm9keSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaGFzUmVxdWVzdEJvZHkoKSB7CisgICAgICAgIHJldHVybiBtZXRob2QgPT0gUE9TVCB8fCBtZXRob2QgPT0gUFVUOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHJlcXVlc3QgYm9keSBvciBudWxsIGlmIHRoaXMgcmVxdWVzdCBkb2Vzbid0IGhhdmUgYSBib2R5LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBPdXRwdXRTdHJlYW0gZ2V0UmVxdWVzdEJvZHkoKSB7CisgICAgICAgIGlmIChyZXNwb25zZVNvdXJjZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlcXVlc3RCb2R5T3V0OworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc1Jlc3BvbnNlKCkgeworICAgICAgICByZXR1cm4gcmVzcG9uc2VIZWFkZXJzICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFJlcXVlc3RIZWFkZXJzIGdldFJlcXVlc3RIZWFkZXJzKCkgeworICAgICAgICByZXR1cm4gcmVxdWVzdEhlYWRlcnM7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFJlc3BvbnNlSGVhZGVycyBnZXRSZXNwb25zZUhlYWRlcnMoKSB7CisgICAgICAgIGlmIChyZXNwb25zZUhlYWRlcnMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXNwb25zZUhlYWRlcnM7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIGludCBnZXRSZXNwb25zZUNvZGUoKSB7CisgICAgICAgIGlmIChyZXNwb25zZUhlYWRlcnMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXNwb25zZUhlYWRlcnMuZ2V0SGVhZGVycygpLmdldFJlc3BvbnNlQ29kZSgpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBJbnB1dFN0cmVhbSBnZXRSZXNwb25zZUJvZHkoKSB7CisgICAgICAgIGlmIChyZXNwb25zZUhlYWRlcnMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXNwb25zZUJvZHlJbjsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgQ2FjaGVSZXNwb25zZSBnZXRDYWNoZVJlc3BvbnNlKCkgeworICAgICAgICByZXR1cm4gY2FjaGVSZXNwb25zZTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgSHR0cENvbm5lY3Rpb24gZ2V0Q29ubmVjdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIGNvbm5lY3Rpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHtAY29kZSBjYWNoZVJlc3BvbnNlfSBpcyBvZiB0aGUgcmlnaHQgdHlwZS4gVGhpcworICAgICAqIGNvbmRpdGlvbiBpcyBuZWNlc3NhcnkgYnV0IG5vdCBzdWZmaWNpZW50IGZvciB0aGUgY2FjaGVkIHJlc3BvbnNlIHRvCisgICAgICogYmUgdXNlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBhY2NlcHRDYWNoZVJlc3BvbnNlVHlwZShDYWNoZVJlc3BvbnNlIGNhY2hlUmVzcG9uc2UpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG1heWJlQ2FjaGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBBcmUgd2UgY2FjaGluZyBhdCBhbGw/CisgICAgICAgIGlmICghcG9saWN5LmdldFVzZUNhY2hlcygpIHx8IHJlc3BvbnNlQ2FjaGUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLy8gU2hvdWxkIHdlIGNhY2hlIHRoaXMgcmVzcG9uc2UgZm9yIHRoaXMgcmVxdWVzdD8KKyAgICAgICAgaWYgKCFyZXNwb25zZUhlYWRlcnMuaXNDYWNoZWFibGUocmVxdWVzdEhlYWRlcnMpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICAvLyBPZmZlciB0aGlzIHJlcXVlc3QgdG8gdGhlIGNhY2hlLgorICAgICAgICBjYWNoZVJlcXVlc3QgPSByZXNwb25zZUNhY2hlLnB1dCh1cmksIGdldEh0dHBDb25uZWN0aW9uVG9DYWNoZSgpKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgSHR0cFVSTENvbm5lY3Rpb24gZ2V0SHR0cENvbm5lY3Rpb25Ub0NhY2hlKCkgeworICAgICAgICByZXR1cm4gcG9saWN5OworICAgIH0KKworICAgIC8qKgorICAgICAqIENhdXNlIHRoZSBzb2NrZXQgY29ubmVjdGlvbiB0byBiZSByZWxlYXNlZCB0byB0aGUgY29ubmVjdGlvbiBwb29sIHdoZW4KKyAgICAgKiBpdCBpcyBubyBsb25nZXIgbmVlZGVkLiBJZiBpdCBpcyBhbHJlYWR5IHVubmVlZGVkLCBpdCB3aWxsIGJlIHBvb2xlZAorICAgICAqIGltbWVkaWF0ZWx5LgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGF1dG9tYXRpY2FsbHlSZWxlYXNlQ29ubmVjdGlvblRvUG9vbCgpIHsKKyAgICAgICAgYXV0b21hdGljYWxseVJlbGVhc2VDb25uZWN0aW9uVG9Qb29sID0gdHJ1ZTsKKyAgICAgICAgaWYgKGNvbm5lY3Rpb24gIT0gbnVsbCAmJiBjb25uZWN0aW9uUmVsZWFzZWQpIHsKKyAgICAgICAgICAgIEh0dHBDb25uZWN0aW9uUG9vbC5JTlNUQU5DRS5yZWN5Y2xlKGNvbm5lY3Rpb24pOworICAgICAgICAgICAgY29ubmVjdGlvbiA9IG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWxlYXNlcyB0aGlzIGVuZ2luZSBzbyB0aGF0IGl0cyByZXNvdXJjZXMgbWF5IGJlIGVpdGhlciByZXVzZWQgb3IKKyAgICAgKiBjbG9zZWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgcmVsZWFzZShib29sZWFuIHJldXNhYmxlKSB7CisgICAgICAgIC8vIElmIHRoZSByZXNwb25zZSBib2R5IGNvbWVzIGZyb20gdGhlIGNhY2hlLCBjbG9zZSBpdC4KKyAgICAgICAgaWYgKHJlc3BvbnNlQm9keUluID09IGNhY2hlZFJlc3BvbnNlQm9keSkgeworICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkocmVzcG9uc2VCb2R5SW4pOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFjb25uZWN0aW9uUmVsZWFzZWQgJiYgY29ubmVjdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICBjb25uZWN0aW9uUmVsZWFzZWQgPSB0cnVlOworCisgICAgICAgICAgICAvLyBXZSBjYW5ub3QgcmV1c2Ugc29ja2V0cyB0aGF0IGhhdmUgaW5jb21wbGV0ZSBvdXRwdXQuCisgICAgICAgICAgICBpZiAocmVxdWVzdEJvZHlPdXQgIT0gbnVsbCAmJiAhcmVxdWVzdEJvZHlPdXQuY2xvc2VkKSB7CisgICAgICAgICAgICAgICAgcmV1c2FibGUgPSBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gSWYgdGhlIGhlYWRlcnMgc3BlY2lmeSB0aGF0IHRoZSBjb25uZWN0aW9uIHNob3VsZG4ndCBiZSByZXVzZWQsIGRvbid0IHJldXNlIGl0LgorICAgICAgICAgICAgaWYgKGhhc0Nvbm5lY3Rpb25DbG9zZUhlYWRlcigpKSB7CisgICAgICAgICAgICAgICAgcmV1c2FibGUgPSBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHJlc3BvbnNlQm9keUluIGluc3RhbmNlb2YgVW5rbm93bkxlbmd0aEh0dHBJbnB1dFN0cmVhbSkgeworICAgICAgICAgICAgICAgIHJldXNhYmxlID0gZmFsc2U7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChyZXVzYWJsZSAmJiByZXNwb25zZUJvZHlJbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgLy8gV2UgbXVzdCBkaXNjYXJkIHRoZSByZXNwb25zZSBib2R5IGJlZm9yZSB0aGUgY29ubmVjdGlvbiBjYW4gYmUgcmV1c2VkLgorICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFN0cmVhbXMuc2tpcEFsbChyZXNwb25zZUJvZHlJbik7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICByZXVzYWJsZSA9IGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKCFyZXVzYWJsZSkgeworICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uY2xvc2VTb2NrZXRBbmRTdHJlYW1zKCk7CisgICAgICAgICAgICAgICAgY29ubmVjdGlvbiA9IG51bGw7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGF1dG9tYXRpY2FsbHlSZWxlYXNlQ29ubmVjdGlvblRvUG9vbCkgeworICAgICAgICAgICAgICAgIEh0dHBDb25uZWN0aW9uUG9vbC5JTlNUQU5DRS5yZWN5Y2xlKGNvbm5lY3Rpb24pOworICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGluaXRDb250ZW50U3RyZWFtKElucHV0U3RyZWFtIHRyYW5zZmVyU3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodHJhbnNwYXJlbnRHemlwICYmIHJlc3BvbnNlSGVhZGVycy5pc0NvbnRlbnRFbmNvZGluZ0d6aXAoKSkgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIElmIHRoZSByZXNwb25zZSB3YXMgdHJhbnNwYXJlbnRseSBnemlwcGVkLCByZW1vdmUgdGhlIGd6aXAgaGVhZGVyIGZpZWxkCisgICAgICAgICAgICAgKiBzbyBjbGllbnRzIGRvbid0IGRvdWJsZSBkZWNvbXByZXNzLiBodHRwOi8vYi8zMDA5ODI4CisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHJlc3BvbnNlSGVhZGVycy5zdHJpcENvbnRlbnRFbmNvZGluZygpOworICAgICAgICAgICAgcmVzcG9uc2VCb2R5SW4gPSBuZXcgR1pJUElucHV0U3RyZWFtKHRyYW5zZmVyU3RyZWFtKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlc3BvbnNlQm9keUluID0gdHJhbnNmZXJTdHJlYW07CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIElucHV0U3RyZWFtIGdldFRyYW5zZmVyU3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFoYXNSZXNwb25zZUJvZHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBGaXhlZExlbmd0aElucHV0U3RyZWFtKHNvY2tldEluLCBjYWNoZVJlcXVlc3QsIHRoaXMsIDApOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHJlc3BvbnNlSGVhZGVycy5pc0NodW5rZWQoKSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBDaHVua2VkSW5wdXRTdHJlYW0oc29ja2V0SW4sIGNhY2hlUmVxdWVzdCwgdGhpcyk7CisgICAgICAgIH0KKworICAgICAgICBpZiAocmVzcG9uc2VIZWFkZXJzLmdldENvbnRlbnRMZW5ndGgoKSAhPSAtMSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBGaXhlZExlbmd0aElucHV0U3RyZWFtKHNvY2tldEluLCBjYWNoZVJlcXVlc3QsIHRoaXMsCisgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlSGVhZGVycy5nZXRDb250ZW50TGVuZ3RoKCkpOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogV3JhcCB0aGUgaW5wdXQgc3RyZWFtIGZyb20gdGhlIEh0dHBDb25uZWN0aW9uIChyYXRoZXIgdGhhbgorICAgICAgICAgKiBqdXN0IHJldHVybmluZyAic29ja2V0SW4iIGRpcmVjdGx5IGhlcmUpLCBzbyB0aGF0IHdlIGNhbiBjb250cm9sCisgICAgICAgICAqIGl0cyB1c2UgYWZ0ZXIgdGhlIHJlZmVyZW5jZSBlc2NhcGVzLgorICAgICAgICAgKi8KKyAgICAgICAgcmV0dXJuIG5ldyBVbmtub3duTGVuZ3RoSHR0cElucHV0U3RyZWFtKHNvY2tldEluLCBjYWNoZVJlcXVlc3QsIHRoaXMpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkUmVzcG9uc2VIZWFkZXJzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUmF3SGVhZGVycyBoZWFkZXJzOworICAgICAgICBkbyB7CisgICAgICAgICAgICBoZWFkZXJzID0gbmV3IFJhd0hlYWRlcnMoKTsKKyAgICAgICAgICAgIGhlYWRlcnMuc2V0U3RhdHVzTGluZShTdHJlYW1zLnJlYWRBc2NpaUxpbmUoc29ja2V0SW4pKTsKKyAgICAgICAgICAgIHJlYWRIZWFkZXJzKGhlYWRlcnMpOworICAgICAgICB9IHdoaWxlIChoZWFkZXJzLmdldFJlc3BvbnNlQ29kZSgpID09IEhUVFBfQ09OVElOVUUpOworICAgICAgICBzZXRSZXNwb25zZShuZXcgUmVzcG9uc2VIZWFkZXJzKHVyaSwgaGVhZGVycyksIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgcmVzcG9uc2UgbXVzdCBoYXZlIGEgKHBvc3NpYmx5IDAtbGVuZ3RoKSBib2R5LgorICAgICAqIFNlZSBSRkMgMjYxNiBzZWN0aW9uIDQuMy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNSZXNwb25zZUJvZHkoKSB7CisgICAgICAgIGludCByZXNwb25zZUNvZGUgPSByZXNwb25zZUhlYWRlcnMuZ2V0SGVhZGVycygpLmdldFJlc3BvbnNlQ29kZSgpOworICAgICAgICBpZiAobWV0aG9kICE9IEhFQUQKKyAgICAgICAgICAgICAgICAmJiBtZXRob2QgIT0gQ09OTkVDVAorICAgICAgICAgICAgICAgICYmIChyZXNwb25zZUNvZGUgPCBIVFRQX0NPTlRJTlVFIHx8IHJlc3BvbnNlQ29kZSA+PSAyMDApCisgICAgICAgICAgICAgICAgJiYgcmVzcG9uc2VDb2RlICE9IEh0dHBVUkxDb25uZWN0aW9uSW1wbC5IVFRQX05PX0NPTlRFTlQKKyAgICAgICAgICAgICAgICAmJiByZXNwb25zZUNvZGUgIT0gSHR0cFVSTENvbm5lY3Rpb25JbXBsLkhUVFBfTk9UX01PRElGSUVEKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIElmIHRoZSBDb250ZW50LUxlbmd0aCBvciBUcmFuc2Zlci1FbmNvZGluZyBoZWFkZXJzIGRpc2FncmVlIHdpdGggdGhlCisgICAgICAgICAqIHJlc3BvbnNlIGNvZGUsIHRoZSByZXNwb25zZSBpcyBtYWxmb3JtZWQuIEZvciBiZXN0IGNvbXBhdGliaWxpdHksIHdlCisgICAgICAgICAqIGhvbm9yIHRoZSBoZWFkZXJzLgorICAgICAgICAgKi8KKyAgICAgICAgaWYgKHJlc3BvbnNlSGVhZGVycy5nZXRDb250ZW50TGVuZ3RoKCkgIT0gLTEgfHwgcmVzcG9uc2VIZWFkZXJzLmlzQ2h1bmtlZCgpKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmFpbGVycyBhcmUgaGVhZGVycyBpbmNsdWRlZCBhZnRlciB0aGUgbGFzdCBjaHVuayBvZiBhIHJlc3BvbnNlIGVuY29kZWQKKyAgICAgKiB3aXRoIGNodW5rZWQgZW5jb2RpbmcuCisgICAgICovCisgICAgZmluYWwgdm9pZCByZWFkVHJhaWxlcnMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZWFkSGVhZGVycyhyZXNwb25zZUhlYWRlcnMuZ2V0SGVhZGVycygpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZEhlYWRlcnMoUmF3SGVhZGVycyBoZWFkZXJzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBwYXJzZSB0aGUgcmVzdWx0IGhlYWRlcnMgdW50aWwgdGhlIGZpcnN0IGJsYW5rIGxpbmUKKyAgICAgICAgU3RyaW5nIGxpbmU7CisgICAgICAgIHdoaWxlICghKGxpbmUgPSBTdHJlYW1zLnJlYWRBc2NpaUxpbmUoc29ja2V0SW4pKS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIGhlYWRlcnMuYWRkTGluZShsaW5lKTsKKyAgICAgICAgfQorCisgICAgICAgIENvb2tpZUhhbmRsZXIgY29va2llSGFuZGxlciA9IENvb2tpZUhhbmRsZXIuZ2V0RGVmYXVsdCgpOworICAgICAgICBpZiAoY29va2llSGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgICAgICBjb29raWVIYW5kbGVyLnB1dCh1cmksIGhlYWRlcnMudG9NdWx0aW1hcCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFByZXBhcmVzIHRoZSBIVFRQIGhlYWRlcnMgYW5kIHNlbmRzIHRoZW0gdG8gdGhlIHNlcnZlci4KKyAgICAgKgorICAgICAqIDxwPkZvciBzdHJlYW1pbmcgcmVxdWVzdHMgd2l0aCBhIGJvZHksIGhlYWRlcnMgbXVzdCBiZSBwcmVwYXJlZAorICAgICAqIDxzdHJvbmc+YmVmb3JlPC9zdHJvbmc+IHRoZSBvdXRwdXQgc3RyZWFtIGhhcyBiZWVuIHdyaXR0ZW4gdG8uIE90aGVyd2lzZQorICAgICAqIHRoZSBib2R5IHdvdWxkIG5lZWQgdG8gYmUgYnVmZmVyZWQhCisgICAgICoKKyAgICAgKiA8cD5Gb3Igbm9uLXN0cmVhbWluZyByZXF1ZXN0cyB3aXRoIGEgYm9keSwgaGVhZGVycyBtdXN0IGJlIHByZXBhcmVkCisgICAgICogPHN0cm9uZz5hZnRlcjwvc3Ryb25nPiB0aGUgb3V0cHV0IHN0cmVhbSBoYXMgYmVlbiB3cml0dGVuIHRvIGFuZCBjbG9zZWQuCisgICAgICogVGhpcyBlbnN1cmVzIHRoYXQgdGhlIHtAY29kZSBDb250ZW50LUxlbmd0aH0gaGVhZGVyIGZpZWxkIHJlY2VpdmVzIHRoZQorICAgICAqIHByb3BlciB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb250ZW50TGVuZ3RoIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhlIHJlcXVlc3QgYm9keSwgb3IgLTEgaWYKKyAgICAgKiAgICAgIHRoZSByZXF1ZXN0IGJvZHkgbGVuZ3RoIGlzIHVua25vd24uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlUmVxdWVzdEhlYWRlcnMoaW50IGNvbnRlbnRMZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzZW50UmVxdWVzdE1pbGxpcyAhPSAtMSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgUmF3SGVhZGVycyBoZWFkZXJzVG9TZW5kID0gZ2V0TmV0d29ya1JlcXVlc3RIZWFkZXJzKCk7CisgICAgICAgIGJ5dGVbXSBieXRlcyA9IGhlYWRlcnNUb1NlbmQudG9IZWFkZXJTdHJpbmcoKS5nZXRCeXRlcyhDaGFyc2V0cy5JU09fODg1OV8xKTsKKworICAgICAgICBpZiAoY29udGVudExlbmd0aCAhPSAtMSAmJiBieXRlcy5sZW5ndGggKyBjb250ZW50TGVuZ3RoIDw9IE1BWF9SRVFVRVNUX0JVRkZFUl9MRU5HVEgpIHsKKyAgICAgICAgICAgIHJlcXVlc3RPdXQgPSBuZXcgQnVmZmVyZWRPdXRwdXRTdHJlYW0oc29ja2V0T3V0LCBieXRlcy5sZW5ndGggKyBjb250ZW50TGVuZ3RoKTsKKyAgICAgICAgfQorCisgICAgICAgIHNlbnRSZXF1ZXN0TWlsbGlzID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgIHJlcXVlc3RPdXQud3JpdGUoYnl0ZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhlYWRlcnMgdG8gc2VuZCBvbiBhIG5ldHdvcmsgcmVxdWVzdC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgYWRkcyB0aGUgY29udGVudCBsZW5ndGggYW5kIGNvbnRlbnQtdHlwZSBoZWFkZXJzLCB3aGljaCBhcmUKKyAgICAgKiBuZWl0aGVyIG5lZWRlZCBub3Iga25vd24gd2hlbiBxdWVyeWluZyB0aGUgcmVzcG9uc2UgY2FjaGUuCisgICAgICoKKyAgICAgKiA8cD5JdCB1cGRhdGVzIHRoZSBzdGF0dXMgbGluZSwgd2hpY2ggbWF5IG5lZWQgdG8gYmUgZnVsbHkgcXVhbGlmaWVkIGlmCisgICAgICogdGhlIGNvbm5lY3Rpb24gaXMgdXNpbmcgYSBwcm94eS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUmF3SGVhZGVycyBnZXROZXR3b3JrUmVxdWVzdEhlYWRlcnMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXF1ZXN0SGVhZGVycy5nZXRIZWFkZXJzKCkuc2V0U3RhdHVzTGluZShnZXRSZXF1ZXN0TGluZSgpKTsKKworICAgICAgICBpbnQgZml4ZWRDb250ZW50TGVuZ3RoID0gcG9saWN5LmdldEZpeGVkQ29udGVudExlbmd0aCgpOworICAgICAgICBpZiAoZml4ZWRDb250ZW50TGVuZ3RoICE9IC0xKSB7CisgICAgICAgICAgICByZXF1ZXN0SGVhZGVycy5zZXRDb250ZW50TGVuZ3RoKGZpeGVkQ29udGVudExlbmd0aCk7CisgICAgICAgIH0gZWxzZSBpZiAoc2VuZENodW5rZWQpIHsKKyAgICAgICAgICAgIHJlcXVlc3RIZWFkZXJzLnNldENodW5rZWQoKTsKKyAgICAgICAgfSBlbHNlIGlmIChyZXF1ZXN0Qm9keU91dCBpbnN0YW5jZW9mIFJldHJ5YWJsZU91dHB1dFN0cmVhbSkgeworICAgICAgICAgICAgaW50IGNvbnRlbnRMZW5ndGggPSAoKFJldHJ5YWJsZU91dHB1dFN0cmVhbSkgcmVxdWVzdEJvZHlPdXQpLmNvbnRlbnRMZW5ndGgoKTsKKyAgICAgICAgICAgIHJlcXVlc3RIZWFkZXJzLnNldENvbnRlbnRMZW5ndGgoY29udGVudExlbmd0aCk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcmVxdWVzdEhlYWRlcnMuZ2V0SGVhZGVycygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBvcHVsYXRlcyByZXF1ZXN0SGVhZGVycyB3aXRoIGRlZmF1bHRzIGFuZCBjb29raWVzLgorICAgICAqCisgICAgICogPHA+VGhpcyBjbGllbnQgZG9lc24ndCBzcGVjaWZ5IGEgZGVmYXVsdCB7QGNvZGUgQWNjZXB0fSBoZWFkZXIgYmVjYXVzZSBpdAorICAgICAqIGRvZXNuJ3Qga25vdyB3aGF0IGNvbnRlbnQgdHlwZXMgdGhlIGFwcGxpY2F0aW9uIGlzIGludGVyZXN0ZWQgaW4uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHByZXBhcmVSYXdSZXF1ZXN0SGVhZGVycygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJlcXVlc3RIZWFkZXJzLmdldEhlYWRlcnMoKS5zZXRTdGF0dXNMaW5lKGdldFJlcXVlc3RMaW5lKCkpOworCisgICAgICAgIGlmIChyZXF1ZXN0SGVhZGVycy5nZXRVc2VyQWdlbnQoKSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXF1ZXN0SGVhZGVycy5zZXRVc2VyQWdlbnQoZ2V0RGVmYXVsdFVzZXJBZ2VudCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChyZXF1ZXN0SGVhZGVycy5nZXRIb3N0KCkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmVxdWVzdEhlYWRlcnMuc2V0SG9zdChnZXRPcmlnaW5BZGRyZXNzKHBvbGljeS5nZXRVUkwoKSkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGh0dHBNaW5vclZlcnNpb24gPiAwICYmIHJlcXVlc3RIZWFkZXJzLmdldENvbm5lY3Rpb24oKSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXF1ZXN0SGVhZGVycy5zZXRDb25uZWN0aW9uKCJLZWVwLUFsaXZlIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAocmVxdWVzdEhlYWRlcnMuZ2V0QWNjZXB0RW5jb2RpbmcoKSA9PSBudWxsKSB7CisgICAgICAgICAgICB0cmFuc3BhcmVudEd6aXAgPSB0cnVlOworICAgICAgICAgICAgcmVxdWVzdEhlYWRlcnMuc2V0QWNjZXB0RW5jb2RpbmcoImd6aXAiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChoYXNSZXF1ZXN0Qm9keSgpICYmIHJlcXVlc3RIZWFkZXJzLmdldENvbnRlbnRUeXBlKCkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmVxdWVzdEhlYWRlcnMuc2V0Q29udGVudFR5cGUoImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCIpOworICAgICAgICB9CisKKyAgICAgICAgbG9uZyBpZk1vZGlmaWVkU2luY2UgPSBwb2xpY3kuZ2V0SWZNb2RpZmllZFNpbmNlKCk7CisgICAgICAgIGlmIChpZk1vZGlmaWVkU2luY2UgIT0gMCkgeworICAgICAgICAgICAgcmVxdWVzdEhlYWRlcnMuc2V0SWZNb2RpZmllZFNpbmNlKG5ldyBEYXRlKGlmTW9kaWZpZWRTaW5jZSkpOworICAgICAgICB9CisKKyAgICAgICAgQ29va2llSGFuZGxlciBjb29raWVIYW5kbGVyID0gQ29va2llSGFuZGxlci5nZXREZWZhdWx0KCk7CisgICAgICAgIGlmIChjb29raWVIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlcXVlc3RIZWFkZXJzLmFkZENvb2tpZXMoCisgICAgICAgICAgICAgICAgICAgIGNvb2tpZUhhbmRsZXIuZ2V0KHVyaSwgcmVxdWVzdEhlYWRlcnMuZ2V0SGVhZGVycygpLnRvTXVsdGltYXAoKSkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0UmVxdWVzdExpbmUoKSB7CisgICAgICAgIFN0cmluZyBwcm90b2NvbCA9IChodHRwTWlub3JWZXJzaW9uID09IDApID8gIkhUVFAvMS4wIiA6ICJIVFRQLzEuMSI7CisgICAgICAgIHJldHVybiBtZXRob2QgKyAiICIgKyByZXF1ZXN0U3RyaW5nKCkgKyAiICIgKyBwcm90b2NvbDsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyByZXF1ZXN0U3RyaW5nKCkgeworICAgICAgICBVUkwgdXJsID0gcG9saWN5LmdldFVSTCgpOworICAgICAgICBpZiAoaW5jbHVkZUF1dGhvcml0eUluUmVxdWVzdExpbmUoKSkgeworICAgICAgICAgICAgcmV0dXJuIHVybC50b1N0cmluZygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgU3RyaW5nIGZpbGVPbmx5ID0gdXJsLmdldEZpbGUoKTsKKyAgICAgICAgICAgIGlmIChmaWxlT25seSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgZmlsZU9ubHkgPSAiLyI7CisgICAgICAgICAgICB9IGVsc2UgaWYgKCFmaWxlT25seS5zdGFydHNXaXRoKCIvIikpIHsKKyAgICAgICAgICAgICAgICBmaWxlT25seSA9ICIvIiArIGZpbGVPbmx5OworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZpbGVPbmx5OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSByZXF1ZXN0IGxpbmUgc2hvdWxkIGNvbnRhaW4gdGhlIGZ1bGwgVVJMIHdpdGggaG9zdAorICAgICAqIGFuZCBwb3J0IChsaWtlICJHRVQgaHR0cDovL2FuZHJvaWQuY29tL2ZvbyBIVFRQLzEuMSIpIG9yIG9ubHkgdGhlIHBhdGgKKyAgICAgKiAobGlrZSAiR0VUIC9mb28gSFRUUC8xLjEiKS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaXMgbm9uLWZpbmFsIGJlY2F1c2UgZm9yIEhUVFBTIGl0J3MgbmV2ZXIgbmVjZXNzYXJ5IHRvIHN1cHBseSB0aGUKKyAgICAgKiBmdWxsIFVSTCwgZXZlbiBpZiBhIHByb3h5IGlzIGluIHVzZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpbmNsdWRlQXV0aG9yaXR5SW5SZXF1ZXN0TGluZSgpIHsKKyAgICAgICAgcmV0dXJuIHBvbGljeS51c2luZ1Byb3h5KCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGZpbmFsIFN0cmluZyBnZXREZWZhdWx0VXNlckFnZW50KCkgeworICAgICAgICBTdHJpbmcgYWdlbnQgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImh0dHAuYWdlbnQiKTsKKyAgICAgICAgcmV0dXJuIGFnZW50ICE9IG51bGwgPyBhZ2VudCA6ICgiSmF2YSIgKyBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEudmVyc2lvbiIpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaGFzQ29ubmVjdGlvbkNsb3NlSGVhZGVyKCkgeworICAgICAgICByZXR1cm4gKHJlc3BvbnNlSGVhZGVycyAhPSBudWxsICYmIHJlc3BvbnNlSGVhZGVycy5oYXNDb25uZWN0aW9uQ2xvc2UoKSkKKyAgICAgICAgICAgICAgICB8fCByZXF1ZXN0SGVhZGVycy5oYXNDb25uZWN0aW9uQ2xvc2UoKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgZmluYWwgU3RyaW5nIGdldE9yaWdpbkFkZHJlc3MoVVJMIHVybCkgeworICAgICAgICBpbnQgcG9ydCA9IHVybC5nZXRQb3J0KCk7CisgICAgICAgIFN0cmluZyByZXN1bHQgPSB1cmwuZ2V0SG9zdCgpOworICAgICAgICBpZiAocG9ydCA+IDAgJiYgcG9ydCAhPSBwb2xpY3kuZ2V0RGVmYXVsdFBvcnQoKSkgeworICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgIjoiICsgcG9ydDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByb3RlY3RlZCBib29sZWFuIHJlcXVpcmVzVHVubmVsKCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmx1c2hlcyB0aGUgcmVtYWluaW5nIHJlcXVlc3QgaGVhZGVyIGFuZCBib2R5LCBwYXJzZXMgdGhlIEhUVFAgcmVzcG9uc2UKKyAgICAgKiBoZWFkZXJzIGFuZCBzdGFydHMgcmVhZGluZyB0aGUgSFRUUCByZXNwb25zZSBib2R5IGlmIGl0IGV4aXN0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCByZWFkUmVzcG9uc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaGFzUmVzcG9uc2UoKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHJlc3BvbnNlU291cmNlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oInJlYWRSZXNwb25zZSgpIHdpdGhvdXQgc2VuZFJlcXVlc3QoKSIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFyZXNwb25zZVNvdXJjZS5yZXF1aXJlc0Nvbm5lY3Rpb24oKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHNlbnRSZXF1ZXN0TWlsbGlzID09IC0xKSB7CisgICAgICAgICAgICBpbnQgY29udGVudExlbmd0aCA9IHJlcXVlc3RCb2R5T3V0IGluc3RhbmNlb2YgUmV0cnlhYmxlT3V0cHV0U3RyZWFtCisgICAgICAgICAgICAgICAgICAgID8gKChSZXRyeWFibGVPdXRwdXRTdHJlYW0pIHJlcXVlc3RCb2R5T3V0KS5jb250ZW50TGVuZ3RoKCkKKyAgICAgICAgICAgICAgICAgICAgOiAtMTsKKyAgICAgICAgICAgIHdyaXRlUmVxdWVzdEhlYWRlcnMoY29udGVudExlbmd0aCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAocmVxdWVzdEJvZHlPdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVxdWVzdEJvZHlPdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIGlmIChyZXF1ZXN0Qm9keU91dCBpbnN0YW5jZW9mIFJldHJ5YWJsZU91dHB1dFN0cmVhbSkgeworICAgICAgICAgICAgICAgICgoUmV0cnlhYmxlT3V0cHV0U3RyZWFtKSByZXF1ZXN0Qm9keU91dCkud3JpdGVUb1NvY2tldChyZXF1ZXN0T3V0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJlcXVlc3RPdXQuZmx1c2goKTsKKyAgICAgICAgcmVxdWVzdE91dCA9IHNvY2tldE91dDsKKworICAgICAgICByZWFkUmVzcG9uc2VIZWFkZXJzKCk7CisgICAgICAgIHJlc3BvbnNlSGVhZGVycy5zZXRMb2NhbFRpbWVzdGFtcHMoc2VudFJlcXVlc3RNaWxsaXMsIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKworICAgICAgICBpZiAocmVzcG9uc2VTb3VyY2UgPT0gUmVzcG9uc2VTb3VyY2UuQ09ORElUSU9OQUxfQ0FDSEUpIHsKKyAgICAgICAgICAgIGlmIChjYWNoZWRSZXNwb25zZUhlYWRlcnMudmFsaWRhdGUocmVzcG9uc2VIZWFkZXJzKSkgeworICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZUNhY2hlIGluc3RhbmNlb2YgSHR0cFJlc3BvbnNlQ2FjaGUpIHsKKyAgICAgICAgICAgICAgICAgICAgKChIdHRwUmVzcG9uc2VDYWNoZSkgcmVzcG9uc2VDYWNoZSkudHJhY2tDb25kaXRpb25hbENhY2hlSGl0KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIERpc2NhcmQgdGhlIG5ldHdvcmsgcmVzcG9uc2UgYm9keS4gQ29tYmluZSB0aGUgaGVhZGVycy4KKyAgICAgICAgICAgICAgICByZWxlYXNlKHRydWUpOworICAgICAgICAgICAgICAgIHNldFJlc3BvbnNlKGNhY2hlZFJlc3BvbnNlSGVhZGVycy5jb21iaW5lKHJlc3BvbnNlSGVhZGVycyksIGNhY2hlZFJlc3BvbnNlQm9keSk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBJb1V0aWxzLmNsb3NlUXVpZXRseShjYWNoZWRSZXNwb25zZUJvZHkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKGhhc1Jlc3BvbnNlQm9keSgpKSB7CisgICAgICAgICAgICBtYXliZUNhY2hlKCk7IC8vIHJlZW50cmFudC4gdGhpcyBjYWxscyBpbnRvIHVzZXIgY29kZSB3aGljaCBtYXkgY2FsbCBiYWNrIGludG8gdGhpcyEKKyAgICAgICAgfQorCisgICAgICAgIGluaXRDb250ZW50U3RyZWFtKGdldFRyYW5zZmVyU3RyZWFtKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0h0dHBIYW5kbGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9IdHRwSGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUxNjhmNDIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9IdHRwSGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5uZXQuaHR0cDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuUHJveHk7CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEubmV0LlVSTENvbm5lY3Rpb247CitpbXBvcnQgamF2YS5uZXQuVVJMU3RyZWFtSGFuZGxlcjsKKworcHVibGljIGZpbmFsIGNsYXNzIEh0dHBIYW5kbGVyIGV4dGVuZHMgVVJMU3RyZWFtSGFuZGxlciB7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIFVSTENvbm5lY3Rpb24gb3BlbkNvbm5lY3Rpb24oVVJMIHUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgSHR0cFVSTENvbm5lY3Rpb25JbXBsKHUsIGdldERlZmF1bHRQb3J0KCkpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgVVJMQ29ubmVjdGlvbiBvcGVuQ29ubmVjdGlvbihVUkwgdXJsLCBQcm94eSBwcm94eSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHVybCA9PSBudWxsIHx8IHByb3h5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInVybCA9PSBudWxsIHx8IHByb3h5ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEh0dHBVUkxDb25uZWN0aW9uSW1wbCh1cmwsIGdldERlZmF1bHRQb3J0KCksIHByb3h5KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIGludCBnZXREZWZhdWx0UG9ydCgpIHsKKyAgICAgICAgcmV0dXJuIDgwOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0h0dHBSZXNwb25zZUNhY2hlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9IdHRwUmVzcG9uc2VDYWNoZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2MDQyYjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9IdHRwUmVzcG9uc2VDYWNoZS5qYXZhCkBAIC0wLDAgKzEsNTQ0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLm5ldC5odHRwOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRXcml0ZXI7CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWx0ZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbHRlck91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW1Xcml0ZXI7CitpbXBvcnQgamF2YS5pby5Xcml0ZXI7CitpbXBvcnQgamF2YS5uZXQuQ2FjaGVSZXF1ZXN0OworaW1wb3J0IGphdmEubmV0LkNhY2hlUmVzcG9uc2U7CitpbXBvcnQgamF2YS5uZXQuSHR0cFVSTENvbm5lY3Rpb247CitpbXBvcnQgamF2YS5uZXQuUmVzcG9uc2VDYWNoZTsKK2ltcG9ydCBqYXZhLm5ldC5TZWN1cmVDYWNoZVJlc3BvbnNlOworaW1wb3J0IGphdmEubmV0LlVSSTsKK2ltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldHM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLkh0dHBzVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUuaW8uQmFzZTY0OworaW1wb3J0IGxpYmNvcmUuaW8uRGlza0xydUNhY2hlOworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKK2ltcG9ydCBsaWJjb3JlLmlvLlN0cmVhbXM7CisKKy8qKgorICogQ2FjaGUgcmVzcG9uc2VzIGluIGEgZGlyZWN0b3J5IG9uIHRoZSBmaWxlIHN5c3RlbS4gTW9zdCBjbGllbnRzIHNob3VsZCB1c2UKKyAqIHtAY29kZSBhbmRyb2lkLm5ldC5IdHRwUmVzcG9uc2VDYWNoZX0sIHRoZSBzdGFibGUsIGRvY3VtZW50ZWQgZnJvbnQgZW5kIGZvcgorICogdGhpcy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEh0dHBSZXNwb25zZUNhY2hlIGV4dGVuZHMgUmVzcG9uc2VDYWNoZSB7CisgICAgLy8gVE9ETzogYWRkIEFQSXMgdG8gaXRlcmF0ZSB0aGUgY2FjaGU/CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFZFUlNJT04gPSAyMDExMDU7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEVOVFJZX01FVEFEQVRBID0gMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRU5UUllfQk9EWSA9IDE7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEVOVFJZX0NPVU5UID0gMjsKKworICAgIHByaXZhdGUgZmluYWwgRGlza0xydUNhY2hlIGNhY2hlOworCisgICAgLyogcmVhZCBhbmQgd3JpdGUgc3RhdGlzdGljcywgYWxsIGd1YXJkZWQgYnkgJ3RoaXMnICovCisgICAgcHJpdmF0ZSBpbnQgd3JpdGVTdWNjZXNzQ291bnQ7CisgICAgcHJpdmF0ZSBpbnQgd3JpdGVBYm9ydENvdW50OworICAgIHByaXZhdGUgaW50IG5ldHdvcmtDb3VudDsKKyAgICBwcml2YXRlIGludCBoaXRDb3VudDsKKyAgICBwcml2YXRlIGludCByZXF1ZXN0Q291bnQ7CisKKyAgICBwdWJsaWMgSHR0cFJlc3BvbnNlQ2FjaGUoRmlsZSBkaXJlY3RvcnksIGxvbmcgbWF4U2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2FjaGUgPSBEaXNrTHJ1Q2FjaGUub3BlbihkaXJlY3RvcnksIFZFUlNJT04sIEVOVFJZX0NPVU5ULCBtYXhTaXplKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyB1cmlUb0tleShVUkkgdXJpKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1lc3NhZ2VEaWdlc3QgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJNRDUiKTsKKyAgICAgICAgICAgIGJ5dGVbXSBtZDVieXRlcyA9IG1lc3NhZ2VEaWdlc3QuZGlnZXN0KHVyaS50b1N0cmluZygpLmdldEJ5dGVzKENoYXJzZXRzLlVURl84KSk7CisgICAgICAgICAgICByZXR1cm4gSW50ZWdyYWxUb1N0cmluZy5ieXRlc1RvSGV4U3RyaW5nKG1kNWJ5dGVzLCBmYWxzZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIENhY2hlUmVzcG9uc2UgZ2V0KFVSSSB1cmksIFN0cmluZyByZXF1ZXN0TWV0aG9kLAorICAgICAgICAgICAgTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PiByZXF1ZXN0SGVhZGVycykgeworICAgICAgICBTdHJpbmcga2V5ID0gdXJpVG9LZXkodXJpKTsKKyAgICAgICAgRGlza0xydUNhY2hlLlNuYXBzaG90IHNuYXBzaG90OworICAgICAgICBFbnRyeSBlbnRyeTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNuYXBzaG90ID0gY2FjaGUuZ2V0KGtleSk7CisgICAgICAgICAgICBpZiAoc25hcHNob3QgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZW50cnkgPSBuZXcgRW50cnkobmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oc25hcHNob3QuZ2V0SW5wdXRTdHJlYW0oRU5UUllfTUVUQURBVEEpKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEdpdmUgdXAgYmVjYXVzZSB0aGUgY2FjaGUgY2Fubm90IGJlIHJlYWQuCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghZW50cnkubWF0Y2hlcyh1cmksIHJlcXVlc3RNZXRob2QsIHJlcXVlc3RIZWFkZXJzKSkgeworICAgICAgICAgICAgc25hcHNob3QuY2xvc2UoKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgSW5wdXRTdHJlYW0gYm9keSA9IG5ld0JvZHlJbnB1dFN0cmVhbShzbmFwc2hvdCk7CisgICAgICAgIHJldHVybiBlbnRyeS5pc0h0dHBzKCkKKyAgICAgICAgICAgICAgICA/IGVudHJ5Lm5ld1NlY3VyZUNhY2hlUmVzcG9uc2UoYm9keSkKKyAgICAgICAgICAgICAgICA6IGVudHJ5Lm5ld0NhY2hlUmVzcG9uc2UoYm9keSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnB1dCBzdHJlYW0gdGhhdCByZWFkcyB0aGUgYm9keSBvZiBhIHNuYXBzaG90LCBjbG9zaW5nIHRoZQorICAgICAqIHNuYXBzaG90IHdoZW4gdGhlIHN0cmVhbSBpcyBjbG9zZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBuZXdCb2R5SW5wdXRTdHJlYW0oZmluYWwgRGlza0xydUNhY2hlLlNuYXBzaG90IHNuYXBzaG90KSB7CisgICAgICAgIHJldHVybiBuZXcgRmlsdGVySW5wdXRTdHJlYW0oc25hcHNob3QuZ2V0SW5wdXRTdHJlYW0oRU5UUllfQk9EWSkpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgc25hcHNob3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBzdXBlci5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgQ2FjaGVSZXF1ZXN0IHB1dChVUkkgdXJpLCBVUkxDb25uZWN0aW9uIHVybENvbm5lY3Rpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghKHVybENvbm5lY3Rpb24gaW5zdGFuY2VvZiBIdHRwVVJMQ29ubmVjdGlvbikpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gaHR0cENvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHVybENvbm5lY3Rpb247CisgICAgICAgIFN0cmluZyByZXF1ZXN0TWV0aG9kID0gaHR0cENvbm5lY3Rpb24uZ2V0UmVxdWVzdE1ldGhvZCgpOworICAgICAgICBTdHJpbmcga2V5ID0gdXJpVG9LZXkodXJpKTsKKworICAgICAgICBpZiAocmVxdWVzdE1ldGhvZC5lcXVhbHMoSHR0cEVuZ2luZS5QT1NUKQorICAgICAgICAgICAgICAgIHx8IHJlcXVlc3RNZXRob2QuZXF1YWxzKEh0dHBFbmdpbmUuUFVUKQorICAgICAgICAgICAgICAgIHx8IHJlcXVlc3RNZXRob2QuZXF1YWxzKEh0dHBFbmdpbmUuREVMRVRFKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjYWNoZS5yZW1vdmUoa2V5KTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgICAgICAvLyBUaGUgY2FjaGUgY2Fubm90IGJlIHdyaXR0ZW4uCisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBlbHNlIGlmICghcmVxdWVzdE1ldGhvZC5lcXVhbHMoSHR0cEVuZ2luZS5HRVQpKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogRG9uJ3QgY2FjaGUgbm9uLUdFVCByZXNwb25zZXMuIFdlJ3JlIHRlY2huaWNhbGx5IGFsbG93ZWQgdG8gY2FjaGUKKyAgICAgICAgICAgICAqIEhFQUQgcmVxdWVzdHMgYW5kIHNvbWUgUE9TVCByZXF1ZXN0cywgYnV0IHRoZSBjb21wbGV4aXR5IG9mIGRvaW5nCisgICAgICAgICAgICAgKiBzbyBpcyBoaWdoIGFuZCB0aGUgYmVuZWZpdCBpcyBsb3cuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgSHR0cEVuZ2luZSBodHRwRW5naW5lID0gZ2V0SHR0cEVuZ2luZShodHRwQ29ubmVjdGlvbik7CisgICAgICAgIGlmIChodHRwRW5naW5lID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIERvbid0IGNhY2hlIHVubGVzcyB0aGUgSFRUUCBpbXBsZW1lbnRhdGlvbiBpcyBvdXJzLgorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBSZXNwb25zZUhlYWRlcnMgcmVzcG9uc2UgPSBodHRwRW5naW5lLmdldFJlc3BvbnNlSGVhZGVycygpOworICAgICAgICBpZiAocmVzcG9uc2UuaGFzVmFyeUFsbCgpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIFJhd0hlYWRlcnMgdmFyeUhlYWRlcnMgPSBodHRwRW5naW5lLmdldFJlcXVlc3RIZWFkZXJzKCkuZ2V0SGVhZGVycygpLmdldEFsbCgKKyAgICAgICAgICAgICAgICByZXNwb25zZS5nZXRWYXJ5RmllbGRzKCkpOworICAgICAgICBFbnRyeSBlbnRyeSA9IG5ldyBFbnRyeSh1cmksIHZhcnlIZWFkZXJzLCBodHRwQ29ubmVjdGlvbik7CisgICAgICAgIERpc2tMcnVDYWNoZS5FZGl0b3IgZWRpdG9yID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVkaXRvciA9IGNhY2hlLmVkaXQoa2V5KTsKKyAgICAgICAgICAgIGlmIChlZGl0b3IgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZW50cnkud3JpdGVUbyhlZGl0b3IpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBDYWNoZVJlcXVlc3RJbXBsKGVkaXRvcik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEdpdmUgdXAgYmVjYXVzZSB0aGUgY2FjaGUgY2Fubm90IGJlIHdyaXR0ZW4uCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmIChlZGl0b3IgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBlZGl0b3IuYWJvcnQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgSHR0cEVuZ2luZSBnZXRIdHRwRW5naW5lKEh0dHBVUkxDb25uZWN0aW9uIGh0dHBDb25uZWN0aW9uKSB7CisgICAgICAgIGlmIChodHRwQ29ubmVjdGlvbiBpbnN0YW5jZW9mIEh0dHBVUkxDb25uZWN0aW9uSW1wbCkgeworICAgICAgICAgICAgcmV0dXJuICgoSHR0cFVSTENvbm5lY3Rpb25JbXBsKSBodHRwQ29ubmVjdGlvbikuZ2V0SHR0cEVuZ2luZSgpOworICAgICAgICB9IGVsc2UgaWYgKGh0dHBDb25uZWN0aW9uIGluc3RhbmNlb2YgSHR0cHNVUkxDb25uZWN0aW9uSW1wbCkgeworICAgICAgICAgICAgcmV0dXJuICgoSHR0cHNVUkxDb25uZWN0aW9uSW1wbCkgaHR0cENvbm5lY3Rpb24pLmdldEh0dHBFbmdpbmUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIERpc2tMcnVDYWNoZSBnZXRDYWNoZSgpIHsKKyAgICAgICAgcmV0dXJuIGNhY2hlOworICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldFdyaXRlQWJvcnRDb3VudCgpIHsKKyAgICAgICAgcmV0dXJuIHdyaXRlQWJvcnRDb3VudDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRXcml0ZVN1Y2Nlc3NDb3VudCgpIHsKKyAgICAgICAgcmV0dXJuIHdyaXRlU3VjY2Vzc0NvdW50OworICAgIH0KKworICAgIHN5bmNocm9uaXplZCB2b2lkIHRyYWNrUmVzcG9uc2UoUmVzcG9uc2VTb3VyY2Ugc291cmNlKSB7CisgICAgICAgIHJlcXVlc3RDb3VudCsrOworCisgICAgICAgIHN3aXRjaCAoc291cmNlKSB7CisgICAgICAgIGNhc2UgQ0FDSEU6CisgICAgICAgICAgICBoaXRDb3VudCsrOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgQ09ORElUSU9OQUxfQ0FDSEU6CisgICAgICAgIGNhc2UgTkVUV09SSzoKKyAgICAgICAgICAgIG5ldHdvcmtDb3VudCsrOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzeW5jaHJvbml6ZWQgdm9pZCB0cmFja0NvbmRpdGlvbmFsQ2FjaGVIaXQoKSB7CisgICAgICAgIGhpdENvdW50Kys7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0TmV0d29ya0NvdW50KCkgeworICAgICAgICByZXR1cm4gbmV0d29ya0NvdW50OworICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldEhpdENvdW50KCkgeworICAgICAgICByZXR1cm4gaGl0Q291bnQ7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0UmVxdWVzdENvdW50KCkgeworICAgICAgICByZXR1cm4gcmVxdWVzdENvdW50OworICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgY2xhc3MgQ2FjaGVSZXF1ZXN0SW1wbCBleHRlbmRzIENhY2hlUmVxdWVzdCB7CisgICAgICAgIHByaXZhdGUgZmluYWwgRGlza0xydUNhY2hlLkVkaXRvciBlZGl0b3I7CisgICAgICAgIHByaXZhdGUgT3V0cHV0U3RyZWFtIGNhY2hlT3V0OworICAgICAgICBwcml2YXRlIGJvb2xlYW4gZG9uZTsKKyAgICAgICAgcHJpdmF0ZSBPdXRwdXRTdHJlYW0gYm9keTsKKworICAgICAgICBwdWJsaWMgQ2FjaGVSZXF1ZXN0SW1wbChmaW5hbCBEaXNrTHJ1Q2FjaGUuRWRpdG9yIGVkaXRvcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRoaXMuZWRpdG9yID0gZWRpdG9yOworICAgICAgICAgICAgdGhpcy5jYWNoZU91dCA9IGVkaXRvci5uZXdPdXRwdXRTdHJlYW0oRU5UUllfQk9EWSk7CisgICAgICAgICAgICB0aGlzLmJvZHkgPSBuZXcgRmlsdGVyT3V0cHV0U3RyZWFtKGNhY2hlT3V0KSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVkIChIdHRwUmVzcG9uc2VDYWNoZS50aGlzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9uZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVTdWNjZXNzQ291bnQrKzsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBzdXBlci5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICBlZGl0b3IuY29tbWl0KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBhYm9ydCgpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoSHR0cFJlc3BvbnNlQ2FjaGUudGhpcykgeworICAgICAgICAgICAgICAgIGlmIChkb25lKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CisgICAgICAgICAgICAgICAgd3JpdGVBYm9ydENvdW50Kys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBJb1V0aWxzLmNsb3NlUXVpZXRseShjYWNoZU91dCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGVkaXRvci5hYm9ydCgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0Qm9keSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gYm9keTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEVudHJ5IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgdXJpOworICAgICAgICBwcml2YXRlIGZpbmFsIFJhd0hlYWRlcnMgdmFyeUhlYWRlcnM7CisgICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHJlcXVlc3RNZXRob2Q7CisgICAgICAgIHByaXZhdGUgZmluYWwgUmF3SGVhZGVycyByZXNwb25zZUhlYWRlcnM7CisgICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGNpcGhlclN1aXRlOworICAgICAgICBwcml2YXRlIGZpbmFsIENlcnRpZmljYXRlW10gcGVlckNlcnRpZmljYXRlczsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBDZXJ0aWZpY2F0ZVtdIGxvY2FsQ2VydGlmaWNhdGVzOworCisgICAgICAgIC8qCisgICAgICAgICAqIFJlYWRzIGFuIGVudHJ5IGZyb20gYW4gaW5wdXQgc3RyZWFtLiBBIHR5cGljYWwgZW50cnkgbG9va3MgbGlrZSB0aGlzOgorICAgICAgICAgKiAgIGh0dHA6Ly9nb29nbGUuY29tL2ZvbworICAgICAgICAgKiAgIEdFVAorICAgICAgICAgKiAgIDIKKyAgICAgICAgICogICBBY2NlcHQtTGFuZ3VhZ2U6IGZyLUNBCisgICAgICAgICAqICAgQWNjZXB0LUNoYXJzZXQ6IFVURi04CisgICAgICAgICAqICAgSFRUUC8xLjEgMjAwIE9LCisgICAgICAgICAqICAgMworICAgICAgICAgKiAgIENvbnRlbnQtVHlwZTogaW1hZ2UvcG5nCisgICAgICAgICAqICAgQ29udGVudC1MZW5ndGg6IDEwMAorICAgICAgICAgKiAgIENhY2hlLUNvbnRyb2w6IG1heC1hZ2U9NjAwCisgICAgICAgICAqCisgICAgICAgICAqIEEgdHlwaWNhbCBIVFRQUyBmaWxlIGxvb2tzIGxpa2UgdGhpczoKKyAgICAgICAgICogICBodHRwczovL2dvb2dsZS5jb20vZm9vCisgICAgICAgICAqICAgR0VUCisgICAgICAgICAqICAgMgorICAgICAgICAgKiAgIEFjY2VwdC1MYW5ndWFnZTogZnItQ0EKKyAgICAgICAgICogICBBY2NlcHQtQ2hhcnNldDogVVRGLTgKKyAgICAgICAgICogICBIVFRQLzEuMSAyMDAgT0sKKyAgICAgICAgICogICAzCisgICAgICAgICAqICAgQ29udGVudC1UeXBlOiBpbWFnZS9wbmcKKyAgICAgICAgICogICBDb250ZW50LUxlbmd0aDogMTAwCisgICAgICAgICAqICAgQ2FjaGUtQ29udHJvbDogbWF4LWFnZT02MDAKKyAgICAgICAgICoKKyAgICAgICAgICogICBBRVNfMjU2X1dJVEhfTUQ1CisgICAgICAgICAqICAgMgorICAgICAgICAgKiAgIGJhc2U2NC1lbmNvZGVkIHBlZXJDZXJ0aWZpY2F0ZVswXQorICAgICAgICAgKiAgIGJhc2U2NC1lbmNvZGVkIHBlZXJDZXJ0aWZpY2F0ZVsxXQorICAgICAgICAgKiAgIC0xCisgICAgICAgICAqCisgICAgICAgICAqIFRoZSBmaWxlIGlzIG5ld2xpbmUgc2VwYXJhdGVkLiBUaGUgZmlyc3QgdHdvIGxpbmVzIGFyZSB0aGUgVVJMIGFuZAorICAgICAgICAgKiB0aGUgcmVxdWVzdCBtZXRob2QuIE5leHQgaXMgdGhlIG51bWJlciBvZiBIVFRQIFZhcnkgcmVxdWVzdCBoZWFkZXIKKyAgICAgICAgICogbGluZXMsIGZvbGxvd2VkIGJ5IHRob3NlIGxpbmVzLgorICAgICAgICAgKgorICAgICAgICAgKiBOZXh0IGlzIHRoZSByZXNwb25zZSBzdGF0dXMgbGluZSwgZm9sbG93ZWQgYnkgdGhlIG51bWJlciBvZiBIVFRQCisgICAgICAgICAqIHJlc3BvbnNlIGhlYWRlciBsaW5lcywgZm9sbG93ZWQgYnkgdGhvc2UgbGluZXMuCisgICAgICAgICAqCisgICAgICAgICAqIEhUVFBTIHJlc3BvbnNlcyBhbHNvIGNvbnRhaW4gU1NMIHNlc3Npb24gaW5mb3JtYXRpb24uIFRoaXMgYmVnaW5zCisgICAgICAgICAqIHdpdGggYSBibGFuayBsaW5lLCBhbmQgdGhlbiBhIGxpbmUgY29udGFpbmluZyB0aGUgY2lwaGVyIHN1aXRlLiBOZXh0CisgICAgICAgICAqIGlzIHRoZSBsZW5ndGggb2YgdGhlIHBlZXIgY2VydGlmaWNhdGUgY2hhaW4uIFRoZXNlIGNlcnRpZmljYXRlcyBhcmUKKyAgICAgICAgICogYmFzZTY0LWVuY29kZWQgYW5kIGFwcGVhciBlYWNoIG9uIHRoZWlyIG93biBsaW5lLiBUaGUgbmV4dCBsaW5lCisgICAgICAgICAqIGNvbnRhaW5zIHRoZSBsZW5ndGggb2YgdGhlIGxvY2FsIGNlcnRpZmljYXRlIGNoYWluLiBUaGVzZQorICAgICAgICAgKiBjZXJ0aWZpY2F0ZXMgYXJlIGFsc28gYmFzZTY0LWVuY29kZWQgYW5kIGFwcGVhciBlYWNoIG9uIHRoZWlyIG93bgorICAgICAgICAgKiBsaW5lLiBBIGxlbmd0aCBvZiAtMSBpcyB1c2VkIHRvIGVuY29kZSBhIG51bGwgYXJyYXkuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgRW50cnkoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHVyaSA9IFN0cmVhbXMucmVhZEFzY2lpTGluZShpbik7CisgICAgICAgICAgICAgICAgcmVxdWVzdE1ldGhvZCA9IFN0cmVhbXMucmVhZEFzY2lpTGluZShpbik7CisgICAgICAgICAgICAgICAgdmFyeUhlYWRlcnMgPSBuZXcgUmF3SGVhZGVycygpOworICAgICAgICAgICAgICAgIGludCB2YXJ5UmVxdWVzdEhlYWRlckxpbmVDb3VudCA9IHJlYWRJbnQoaW4pOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFyeVJlcXVlc3RIZWFkZXJMaW5lQ291bnQ7IGkrKykgeworICAgICAgICAgICAgICAgICAgICB2YXJ5SGVhZGVycy5hZGRMaW5lKFN0cmVhbXMucmVhZEFzY2lpTGluZShpbikpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHJlc3BvbnNlSGVhZGVycyA9IG5ldyBSYXdIZWFkZXJzKCk7CisgICAgICAgICAgICAgICAgcmVzcG9uc2VIZWFkZXJzLnNldFN0YXR1c0xpbmUoU3RyZWFtcy5yZWFkQXNjaWlMaW5lKGluKSk7CisgICAgICAgICAgICAgICAgaW50IHJlc3BvbnNlSGVhZGVyTGluZUNvdW50ID0gcmVhZEludChpbik7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXNwb25zZUhlYWRlckxpbmVDb3VudDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlSGVhZGVycy5hZGRMaW5lKFN0cmVhbXMucmVhZEFzY2lpTGluZShpbikpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChpc0h0dHBzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGJsYW5rID0gU3RyZWFtcy5yZWFkQXNjaWlMaW5lKGluKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFibGFuay5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiZXhwZWN0ZWQgXCJcIiBidXQgd2FzIFwiIiArIGJsYW5rICsgIlwiIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgY2lwaGVyU3VpdGUgPSBTdHJlYW1zLnJlYWRBc2NpaUxpbmUoaW4pOworICAgICAgICAgICAgICAgICAgICBwZWVyQ2VydGlmaWNhdGVzID0gcmVhZENlcnRBcnJheShpbik7CisgICAgICAgICAgICAgICAgICAgIGxvY2FsQ2VydGlmaWNhdGVzID0gcmVhZENlcnRBcnJheShpbik7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgY2lwaGVyU3VpdGUgPSBudWxsOworICAgICAgICAgICAgICAgICAgICBwZWVyQ2VydGlmaWNhdGVzID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgbG9jYWxDZXJ0aWZpY2F0ZXMgPSBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFbnRyeShVUkkgdXJpLCBSYXdIZWFkZXJzIHZhcnlIZWFkZXJzLCBIdHRwVVJMQ29ubmVjdGlvbiBodHRwQ29ubmVjdGlvbikgeworICAgICAgICAgICAgdGhpcy51cmkgPSB1cmkudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIHRoaXMudmFyeUhlYWRlcnMgPSB2YXJ5SGVhZGVyczsKKyAgICAgICAgICAgIHRoaXMucmVxdWVzdE1ldGhvZCA9IGh0dHBDb25uZWN0aW9uLmdldFJlcXVlc3RNZXRob2QoKTsKKyAgICAgICAgICAgIHRoaXMucmVzcG9uc2VIZWFkZXJzID0gUmF3SGVhZGVycy5mcm9tTXVsdGltYXAoaHR0cENvbm5lY3Rpb24uZ2V0SGVhZGVyRmllbGRzKCkpOworCisgICAgICAgICAgICBpZiAoaXNIdHRwcygpKSB7CisgICAgICAgICAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGh0dHBzQ29ubmVjdGlvbiA9IChIdHRwc1VSTENvbm5lY3Rpb24pIGh0dHBDb25uZWN0aW9uOworICAgICAgICAgICAgICAgIGNpcGhlclN1aXRlID0gaHR0cHNDb25uZWN0aW9uLmdldENpcGhlclN1aXRlKCk7CisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVbXSBwZWVyQ2VydGlmaWNhdGVzTm9uRmluYWwgPSBudWxsOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHBlZXJDZXJ0aWZpY2F0ZXNOb25GaW5hbCA9IGh0dHBzQ29ubmVjdGlvbi5nZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHBlZXJDZXJ0aWZpY2F0ZXMgPSBwZWVyQ2VydGlmaWNhdGVzTm9uRmluYWw7CisgICAgICAgICAgICAgICAgbG9jYWxDZXJ0aWZpY2F0ZXMgPSBodHRwc0Nvbm5lY3Rpb24uZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgY2lwaGVyU3VpdGUgPSBudWxsOworICAgICAgICAgICAgICAgIHBlZXJDZXJ0aWZpY2F0ZXMgPSBudWxsOworICAgICAgICAgICAgICAgIGxvY2FsQ2VydGlmaWNhdGVzID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oRGlza0xydUNhY2hlLkVkaXRvciBlZGl0b3IpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBPdXRwdXRTdHJlYW0gb3V0ID0gZWRpdG9yLm5ld091dHB1dFN0cmVhbSgwKTsKKyAgICAgICAgICAgIFdyaXRlciB3cml0ZXIgPSBuZXcgQnVmZmVyZWRXcml0ZXIobmV3IE91dHB1dFN0cmVhbVdyaXRlcihvdXQsIENoYXJzZXRzLlVURl84KSk7CisKKyAgICAgICAgICAgIHdyaXRlci53cml0ZSh1cmkgKyAnXG4nKTsKKyAgICAgICAgICAgIHdyaXRlci53cml0ZShyZXF1ZXN0TWV0aG9kICsgJ1xuJyk7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoSW50ZWdlci50b1N0cmluZyh2YXJ5SGVhZGVycy5sZW5ndGgoKSkgKyAnXG4nKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFyeUhlYWRlcnMubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSh2YXJ5SGVhZGVycy5nZXRGaWVsZE5hbWUoaSkgKyAiOiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIHZhcnlIZWFkZXJzLmdldFZhbHVlKGkpICsgJ1xuJyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHdyaXRlci53cml0ZShyZXNwb25zZUhlYWRlcnMuZ2V0U3RhdHVzTGluZSgpICsgJ1xuJyk7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoSW50ZWdlci50b1N0cmluZyhyZXNwb25zZUhlYWRlcnMubGVuZ3RoKCkpICsgJ1xuJyk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlc3BvbnNlSGVhZGVycy5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKHJlc3BvbnNlSGVhZGVycy5nZXRGaWVsZE5hbWUoaSkgKyAiOiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIHJlc3BvbnNlSGVhZGVycy5nZXRWYWx1ZShpKSArICdcbicpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoaXNIdHRwcygpKSB7CisgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCdcbicpOworICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShjaXBoZXJTdWl0ZSArICdcbicpOworICAgICAgICAgICAgICAgIHdyaXRlQ2VydEFycmF5KHdyaXRlciwgcGVlckNlcnRpZmljYXRlcyk7CisgICAgICAgICAgICAgICAgd3JpdGVDZXJ0QXJyYXkod3JpdGVyLCBsb2NhbENlcnRpZmljYXRlcyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc0h0dHBzKCkgeworICAgICAgICAgICAgcmV0dXJuIHVyaS5zdGFydHNXaXRoKCJodHRwczovLyIpOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBpbnQgcmVhZEludChJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIFN0cmluZyBpbnRTdHJpbmcgPSBTdHJlYW1zLnJlYWRBc2NpaUxpbmUoaW4pOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gSW50ZWdlci5wYXJzZUludChpbnRTdHJpbmcpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oImV4cGVjdGVkIGFuIGludCBidXQgd2FzIFwiIiArIGludFN0cmluZyArICJcIiIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBDZXJ0aWZpY2F0ZVtdIHJlYWRDZXJ0QXJyYXkoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpbnQgbGVuZ3RoID0gcmVhZEludChpbik7CisgICAgICAgICAgICBpZiAobGVuZ3RoID09IC0xKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZXJ0aWZpY2F0ZUZhY3RvcnkgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVbXSByZXN1bHQgPSBuZXcgQ2VydGlmaWNhdGVbbGVuZ3RoXTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlc3VsdC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbGluZSA9IFN0cmVhbXMucmVhZEFzY2lpTGluZShpbik7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBieXRlcyA9IEJhc2U2NC5kZWNvZGUobGluZS5nZXRCeXRlcyhDaGFyc2V0cy5VU19BU0NJSSkpOworICAgICAgICAgICAgICAgICAgICByZXN1bHRbaV0gPSBjZXJ0aWZpY2F0ZUZhY3RvcnkuZ2VuZXJhdGVDZXJ0aWZpY2F0ZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZXMpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgd3JpdGVDZXJ0QXJyYXkoV3JpdGVyIHdyaXRlciwgQ2VydGlmaWNhdGVbXSBjZXJ0aWZpY2F0ZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoY2VydGlmaWNhdGVzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIi0xXG4iKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShJbnRlZ2VyLnRvU3RyaW5nKGNlcnRpZmljYXRlcy5sZW5ndGgpICsgJ1xuJyk7CisgICAgICAgICAgICAgICAgZm9yIChDZXJ0aWZpY2F0ZSBjZXJ0aWZpY2F0ZSA6IGNlcnRpZmljYXRlcykgeworICAgICAgICAgICAgICAgICAgICBieXRlW10gYnl0ZXMgPSBjZXJ0aWZpY2F0ZS5nZXRFbmNvZGVkKCk7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsaW5lID0gQmFzZTY0LmVuY29kZShieXRlcyk7CisgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShsaW5lICsgJ1xuJyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gbWF0Y2hlcyhVUkkgdXJpLCBTdHJpbmcgcmVxdWVzdE1ldGhvZCwKKyAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IHJlcXVlc3RIZWFkZXJzKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpcy51cmkuZXF1YWxzKHVyaS50b1N0cmluZygpKQorICAgICAgICAgICAgICAgICAgICAmJiB0aGlzLnJlcXVlc3RNZXRob2QuZXF1YWxzKHJlcXVlc3RNZXRob2QpCisgICAgICAgICAgICAgICAgICAgICYmIG5ldyBSZXNwb25zZUhlYWRlcnModXJpLCByZXNwb25zZUhlYWRlcnMpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnZhcnlNYXRjaGVzKHZhcnlIZWFkZXJzLnRvTXVsdGltYXAoKSwgcmVxdWVzdEhlYWRlcnMpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIENhY2hlUmVzcG9uc2UgbmV3Q2FjaGVSZXNwb25zZShmaW5hbCBJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBDYWNoZVJlc3BvbnNlKCkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PiBnZXRIZWFkZXJzKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2VIZWFkZXJzLnRvTXVsdGltYXAoKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIElucHV0U3RyZWFtIGdldEJvZHkoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFNlY3VyZUNhY2hlUmVzcG9uc2UgbmV3U2VjdXJlQ2FjaGVSZXNwb25zZShmaW5hbCBJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBTZWN1cmVDYWNoZVJlc3BvbnNlKCkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PiBnZXRIZWFkZXJzKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2VIZWFkZXJzLnRvTXVsdGltYXAoKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIElucHV0U3RyZWFtIGdldEJvZHkoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbjsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyBnZXRDaXBoZXJTdWl0ZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNpcGhlclN1aXRlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgTGlzdDxDZXJ0aWZpY2F0ZT4gZ2V0U2VydmVyQ2VydGlmaWNhdGVDaGFpbigpCisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICBpZiAocGVlckNlcnRpZmljYXRlcyA9PSBudWxsIHx8IHBlZXJDZXJ0aWZpY2F0ZXMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbihudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gQXJyYXlzLmFzTGlzdChwZWVyQ2VydGlmaWNhdGVzLmNsb25lKCkpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgUHJpbmNpcGFsIGdldFBlZXJQcmluY2lwYWwoKSB0aHJvd3MgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICBpZiAocGVlckNlcnRpZmljYXRlcyA9PSBudWxsIHx8IHBlZXJDZXJ0aWZpY2F0ZXMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbihudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChYNTA5Q2VydGlmaWNhdGUpIHBlZXJDZXJ0aWZpY2F0ZXNbMF0pLmdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBMaXN0PENlcnRpZmljYXRlPiBnZXRMb2NhbENlcnRpZmljYXRlQ2hhaW4oKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChsb2NhbENlcnRpZmljYXRlcyA9PSBudWxsIHx8IGxvY2FsQ2VydGlmaWNhdGVzLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gQXJyYXlzLmFzTGlzdChsb2NhbENlcnRpZmljYXRlcy5jbG9uZSgpKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFByaW5jaXBhbCBnZXRMb2NhbFByaW5jaXBhbCgpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGxvY2FsQ2VydGlmaWNhdGVzID09IG51bGwgfHwgbG9jYWxDZXJ0aWZpY2F0ZXMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKFg1MDlDZXJ0aWZpY2F0ZSkgbG9jYWxDZXJ0aWZpY2F0ZXNbMF0pLmdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0h0dHBVUkxDb25uZWN0aW9uSW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvSHR0cFVSTENvbm5lY3Rpb25JbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGRiYWY4YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0h0dHBVUkxDb25uZWN0aW9uSW1wbC5qYXZhCkBAIC0wLDAgKzEsNTAxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUubmV0Lmh0dHA7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuQXV0aGVudGljYXRvcjsKK2ltcG9ydCBqYXZhLm5ldC5IdHRwUmV0cnlFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSHR0cFVSTENvbm5lY3Rpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuUGFzc3dvcmRBdXRoZW50aWNhdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Qcm90b2NvbEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Qcm94eTsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRQZXJtaXNzaW9uOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGxpYmNvcmUuaW8uQmFzZTY0OworCisvKioKKyAqIFRoaXMgaW1wbGVtZW50YXRpb24gdXNlcyBIdHRwRW5naW5lIHRvIHNlbmQgcmVxdWVzdHMgYW5kIHJlY2VpdmUgcmVzcG9uc2VzLgorICogVGhpcyBjbGFzcyBtYXkgdXNlIG11bHRpcGxlIEh0dHBFbmdpbmVzIHRvIGZvbGxvdyByZWRpcmVjdHMsIGF1dGhlbnRpY2F0aW9uCisgKiByZXRyaWVzLCBldGMuIHRvIHJldHJpZXZlIHRoZSBmaW5hbCByZXNwb25zZSBib2R5LgorICoKKyAqIDxoMz5XaGF0IGRvZXMgJ2Nvbm5lY3RlZCcgbWVhbj88L2gzPgorICogVGhpcyBjbGFzcyBpbmhlcml0cyBhIHtAY29kZSBjb25uZWN0ZWR9IGZpZWxkIGZyb20gdGhlIHN1cGVyY2xhc3MuIFRoYXQgZmllbGQKKyAqIGlzIDxzdHJvbmc+bm90PC9zdHJvbmc+IHVzZWQgdG8gaW5kaWNhdGUgbm90IHdoZXRoZXIgdGhpcyBVUkxDb25uZWN0aW9uIGlzCisgKiBjdXJyZW50bHkgY29ubmVjdGVkLiBJbnN0ZWFkLCBpdCBpbmRpY2F0ZXMgd2hldGhlciBhIGNvbm5lY3Rpb24gaGFzIGV2ZXIgYmVlbgorICogYXR0ZW1wdGVkLiBPbmNlIGEgY29ubmVjdGlvbiBoYXMgYmVlbiBhdHRlbXB0ZWQsIGNlcnRhaW4gcHJvcGVydGllcyAocmVxdWVzdAorICogaGVhZGVyIGZpZWxkcywgcmVxdWVzdCBtZXRob2QsIGV0Yy4pIGFyZSBpbW11dGFibGUuIFRlc3QgdGhlIHtAY29kZQorICogY29ubmVjdGlvbn0gZmllbGQgb24gdGhpcyBjbGFzcyBmb3IgbnVsbC9ub24tbnVsbCB0byBkZXRlcm1pbmUgb2YgYW4gaW5zdGFuY2UKKyAqIGlzIGN1cnJlbnRseSBjb25uZWN0ZWQgdG8gYSBzZXJ2ZXIuCisgKi8KK2NsYXNzIEh0dHBVUkxDb25uZWN0aW9uSW1wbCBleHRlbmRzIEh0dHBVUkxDb25uZWN0aW9uIHsKKworICAgIHByaXZhdGUgZmluYWwgaW50IGRlZmF1bHRQb3J0OworCisgICAgcHJpdmF0ZSBQcm94eSBwcm94eTsKKworICAgIHByaXZhdGUgZmluYWwgUmF3SGVhZGVycyByYXdSZXF1ZXN0SGVhZGVycyA9IG5ldyBSYXdIZWFkZXJzKCk7CisKKyAgICBwcml2YXRlIGludCByZWRpcmVjdGlvbkNvdW50OworCisgICAgcHJvdGVjdGVkIElPRXhjZXB0aW9uIGh0dHBFbmdpbmVGYWlsdXJlOworICAgIHByb3RlY3RlZCBIdHRwRW5naW5lIGh0dHBFbmdpbmU7CisKKyAgICBwcm90ZWN0ZWQgSHR0cFVSTENvbm5lY3Rpb25JbXBsKFVSTCB1cmwsIGludCBwb3J0KSB7CisgICAgICAgIHN1cGVyKHVybCk7CisgICAgICAgIGRlZmF1bHRQb3J0ID0gcG9ydDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgSHR0cFVSTENvbm5lY3Rpb25JbXBsKFVSTCB1cmwsIGludCBwb3J0LCBQcm94eSBwcm94eSkgeworICAgICAgICB0aGlzKHVybCwgcG9ydCk7CisgICAgICAgIHRoaXMucHJveHkgPSBwcm94eTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGZpbmFsIHZvaWQgY29ubmVjdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGluaXRIdHRwRW5naW5lKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBodHRwRW5naW5lLnNlbmRSZXF1ZXN0KCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGh0dHBFbmdpbmVGYWlsdXJlID0gZTsKKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGZpbmFsIHZvaWQgZGlzY29ubmVjdCgpIHsKKyAgICAgICAgLy8gQ2FsbGluZyBkaXNjb25uZWN0KCkgYmVmb3JlIGEgY29ubmVjdGlvbiBleGlzdHMgc2hvdWxkIGhhdmUgbm8gZWZmZWN0LgorICAgICAgICBpZiAoaHR0cEVuZ2luZSAhPSBudWxsKSB7CisgICAgICAgICAgICBodHRwRW5naW5lLnJlbGVhc2UoZmFsc2UpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnB1dCBzdHJlYW0gZnJvbSB0aGUgc2VydmVyIGluIHRoZSBjYXNlIG9mIGVycm9yIHN1Y2ggYXMgdGhlCisgICAgICogcmVxdWVzdGVkIGZpbGUgKHR4dCwgaHRtLCBodG1sKSBpcyBub3QgZm91bmQgb24gdGhlIHJlbW90ZSBzZXJ2ZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBmaW5hbCBJbnB1dFN0cmVhbSBnZXRFcnJvclN0cmVhbSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEh0dHBFbmdpbmUgcmVzcG9uc2UgPSBnZXRSZXNwb25zZSgpOworICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhhc1Jlc3BvbnNlQm9keSgpCisgICAgICAgICAgICAgICAgICAgICYmIHJlc3BvbnNlLmdldFJlc3BvbnNlQ29kZSgpID49IEhUVFBfQkFEX1JFUVVFU1QpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2UuZ2V0UmVzcG9uc2VCb2R5KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQgYXQge0Bjb2RlIHBvc2l0aW9ufS4gUmV0dXJucyBudWxsIGlmIHRoZXJlCisgICAgICogYXJlIGZld2VyIHRoYW4ge0Bjb2RlIHBvc2l0aW9ufSBoZWFkZXJzLgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgZmluYWwgU3RyaW5nIGdldEhlYWRlckZpZWxkKGludCBwb3NpdGlvbikgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGdldFJlc3BvbnNlKCkuZ2V0UmVzcG9uc2VIZWFkZXJzKCkuZ2V0SGVhZGVycygpLmdldFZhbHVlKHBvc2l0aW9uKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQgY29ycmVzcG9uZGluZyB0byB0aGUge0Bjb2RlIGZpZWxkTmFtZX0sIG9yCisgICAgICogbnVsbCBpZiB0aGVyZSBpcyBubyBzdWNoIGZpZWxkLiBJZiB0aGUgZmllbGQgaGFzIG11bHRpcGxlIHZhbHVlcywgdGhlCisgICAgICogbGFzdCB2YWx1ZSBpcyByZXR1cm5lZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIGZpbmFsIFN0cmluZyBnZXRIZWFkZXJGaWVsZChTdHJpbmcgZmllbGROYW1lKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSYXdIZWFkZXJzIHJhd0hlYWRlcnMgPSBnZXRSZXNwb25zZSgpLmdldFJlc3BvbnNlSGVhZGVycygpLmdldEhlYWRlcnMoKTsKKyAgICAgICAgICAgIHJldHVybiBmaWVsZE5hbWUgPT0gbnVsbAorICAgICAgICAgICAgICAgICAgICA/IHJhd0hlYWRlcnMuZ2V0U3RhdHVzTGluZSgpCisgICAgICAgICAgICAgICAgICAgIDogcmF3SGVhZGVycy5nZXQoZmllbGROYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGZpbmFsIFN0cmluZyBnZXRIZWFkZXJGaWVsZEtleShpbnQgcG9zaXRpb24pIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBnZXRSZXNwb25zZSgpLmdldFJlc3BvbnNlSGVhZGVycygpLmdldEhlYWRlcnMoKS5nZXRGaWVsZE5hbWUocG9zaXRpb24pOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgZmluYWwgTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PiBnZXRIZWFkZXJGaWVsZHMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0UmVzcG9uc2UoKS5nZXRSZXNwb25zZUhlYWRlcnMoKS5nZXRIZWFkZXJzKCkudG9NdWx0aW1hcCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgZmluYWwgTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PiBnZXRSZXF1ZXN0UHJvcGVydGllcygpIHsKKyAgICAgICAgaWYgKGNvbm5lY3RlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgIkNhbm5vdCBhY2Nlc3MgcmVxdWVzdCBoZWFkZXIgZmllbGRzIGFmdGVyIGNvbm5lY3Rpb24gaXMgc2V0Iik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJhd1JlcXVlc3RIZWFkZXJzLnRvTXVsdGltYXAoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGZpbmFsIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFkb0lucHV0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUHJvdG9jb2xFeGNlcHRpb24oIlRoaXMgcHJvdG9jb2wgZG9lcyBub3Qgc3VwcG9ydCBpbnB1dCIpOworICAgICAgICB9CisKKyAgICAgICAgSHR0cEVuZ2luZSByZXNwb25zZSA9IGdldFJlc3BvbnNlKCk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogaWYgdGhlIHJlcXVlc3RlZCBmaWxlIGRvZXMgbm90IGV4aXN0LCB0aHJvdyBhbiBleGNlcHRpb24gZm9ybWVybHkgdGhlCisgICAgICAgICAqIEVycm9yIHBhZ2UgZnJvbSB0aGUgc2VydmVyIHdhcyByZXR1cm5lZCBpZiB0aGUgcmVxdWVzdGVkIGZpbGUgd2FzCisgICAgICAgICAqIHRleHQvaHRtbCB0aGlzIGhhcyBjaGFuZ2VkIHRvIHJldHVybiBGaWxlTm90Rm91bmRFeGNlcHRpb24gZm9yIGFsbAorICAgICAgICAgKiBmaWxlIHR5cGVzCisgICAgICAgICAqLworICAgICAgICBpZiAoZ2V0UmVzcG9uc2VDb2RlKCkgPj0gSFRUUF9CQURfUkVRVUVTVCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEZpbGVOb3RGb3VuZEV4Y2VwdGlvbih1cmwudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICBJbnB1dFN0cmVhbSByZXN1bHQgPSByZXNwb25zZS5nZXRSZXNwb25zZUJvZHkoKTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIk5vIHJlc3BvbnNlIGJvZHkgZXhpc3RzOyByZXNwb25zZUNvZGU9IiArIGdldFJlc3BvbnNlQ29kZSgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgZmluYWwgT3V0cHV0U3RyZWFtIGdldE91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNvbm5lY3QoKTsKKworICAgICAgICBPdXRwdXRTdHJlYW0gcmVzdWx0ID0gaHR0cEVuZ2luZS5nZXRSZXF1ZXN0Qm9keSgpOworICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBQcm90b2NvbEV4Y2VwdGlvbigibWV0aG9kIGRvZXMgbm90IHN1cHBvcnQgYSByZXF1ZXN0IGJvZHk6ICIgKyBtZXRob2QpOworICAgICAgICB9IGVsc2UgaWYgKGh0dHBFbmdpbmUuaGFzUmVzcG9uc2UoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFByb3RvY29sRXhjZXB0aW9uKCJjYW5ub3Qgd3JpdGUgcmVxdWVzdCBib2R5IGFmdGVyIHJlc3BvbnNlIGhhcyBiZWVuIHJlYWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBmaW5hbCBQZXJtaXNzaW9uIGdldFBlcm1pc3Npb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgY29ubmVjdFRvQWRkcmVzcyA9IGdldENvbm5lY3RUb0hvc3QoKSArICI6IiArIGdldENvbm5lY3RUb1BvcnQoKTsKKyAgICAgICAgcmV0dXJuIG5ldyBTb2NrZXRQZXJtaXNzaW9uKGNvbm5lY3RUb0FkZHJlc3MsICJjb25uZWN0LCByZXNvbHZlIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0Q29ubmVjdFRvSG9zdCgpIHsKKyAgICAgICAgcmV0dXJuIHVzaW5nUHJveHkoKQorICAgICAgICAgICAgICAgID8gKChJbmV0U29ja2V0QWRkcmVzcykgcHJveHkuYWRkcmVzcygpKS5nZXRIb3N0TmFtZSgpCisgICAgICAgICAgICAgICAgOiBnZXRVUkwoKS5nZXRIb3N0KCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgZ2V0Q29ubmVjdFRvUG9ydCgpIHsKKyAgICAgICAgaW50IGhvc3RQb3J0ID0gdXNpbmdQcm94eSgpCisgICAgICAgICAgICAgICAgPyAoKEluZXRTb2NrZXRBZGRyZXNzKSBwcm94eS5hZGRyZXNzKCkpLmdldFBvcnQoKQorICAgICAgICAgICAgICAgIDogZ2V0VVJMKCkuZ2V0UG9ydCgpOworICAgICAgICByZXR1cm4gaG9zdFBvcnQgPCAwID8gZ2V0RGVmYXVsdFBvcnQoKSA6IGhvc3RQb3J0OworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgZmluYWwgU3RyaW5nIGdldFJlcXVlc3RQcm9wZXJ0eShTdHJpbmcgZmllbGQpIHsKKyAgICAgICAgaWYgKGZpZWxkID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiByYXdSZXF1ZXN0SGVhZGVycy5nZXQoZmllbGQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBpbml0SHR0cEVuZ2luZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChodHRwRW5naW5lRmFpbHVyZSAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBodHRwRW5naW5lRmFpbHVyZTsKKyAgICAgICAgfSBlbHNlIGlmIChodHRwRW5naW5lICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGNvbm5lY3RlZCA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoZG9PdXRwdXQpIHsKKyAgICAgICAgICAgICAgICBpZiAobWV0aG9kID09IEh0dHBFbmdpbmUuR0VUKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIHRoZXkgYXJlIHJlcXVlc3RpbmcgYSBzdHJlYW0gdG8gd3JpdGUgdG8uIFRoaXMgaW1wbGllcyBhIFBPU1QgbWV0aG9kCisgICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9IEh0dHBFbmdpbmUuUE9TVDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG1ldGhvZCAhPSBIdHRwRW5naW5lLlBPU1QgJiYgbWV0aG9kICE9IEh0dHBFbmdpbmUuUFVUKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSByZXF1ZXN0IG1ldGhvZCBpcyBuZWl0aGVyIFBPU1Qgbm9yIFBVVCwgdGhlbiB5b3UncmUgbm90IHdyaXRpbmcKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFByb3RvY29sRXhjZXB0aW9uKG1ldGhvZCArICIgZG9lcyBub3Qgc3VwcG9ydCB3cml0aW5nIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaHR0cEVuZ2luZSA9IG5ld0h0dHBFbmdpbmUobWV0aG9kLCByYXdSZXF1ZXN0SGVhZGVycywgbnVsbCwgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGh0dHBFbmdpbmVGYWlsdXJlID0gZTsKKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgSFRUUCBlbmdpbmUuIFRoaXMgaG9vayBtZXRob2QgaXMgbm9uLWZpbmFsIHNvIGl0IGNhbiBiZQorICAgICAqIG92ZXJyaWRkZW4gYnkgSHR0cHNVUkxDb25uZWN0aW9uSW1wbC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSHR0cEVuZ2luZSBuZXdIdHRwRW5naW5lKFN0cmluZyBtZXRob2QsIFJhd0hlYWRlcnMgcmVxdWVzdEhlYWRlcnMsCisgICAgICAgICAgICBIdHRwQ29ubmVjdGlvbiBjb25uZWN0aW9uLCBSZXRyeWFibGVPdXRwdXRTdHJlYW0gcmVxdWVzdEJvZHkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgSHR0cEVuZ2luZSh0aGlzLCBtZXRob2QsIHJlcXVlc3RIZWFkZXJzLCBjb25uZWN0aW9uLCByZXF1ZXN0Qm9keSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWdncmVzc2l2ZWx5IHRyaWVzIHRvIGdldCB0aGUgZmluYWwgSFRUUCByZXNwb25zZSwgcG90ZW50aWFsbHkgbWFraW5nCisgICAgICogbWFueSBIVFRQIHJlcXVlc3RzIGluIHRoZSBwcm9jZXNzIGluIG9yZGVyIHRvIGNvcGUgd2l0aCByZWRpcmVjdHMgYW5kCisgICAgICogYXV0aGVudGljYXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBIdHRwRW5naW5lIGdldFJlc3BvbnNlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW5pdEh0dHBFbmdpbmUoKTsKKworICAgICAgICBpZiAoaHR0cEVuZ2luZS5oYXNSZXNwb25zZSgpKSB7CisgICAgICAgICAgICByZXR1cm4gaHR0cEVuZ2luZTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgIGh0dHBFbmdpbmUuc2VuZFJlcXVlc3QoKTsKKyAgICAgICAgICAgICAgICBodHRwRW5naW5lLnJlYWRSZXNwb25zZSgpOworCisgICAgICAgICAgICAgICAgUmV0cnkgcmV0cnkgPSBwcm9jZXNzUmVzcG9uc2VIZWFkZXJzKCk7CisgICAgICAgICAgICAgICAgaWYgKHJldHJ5ID09IFJldHJ5Lk5PTkUpIHsKKyAgICAgICAgICAgICAgICAgICAgaHR0cEVuZ2luZS5hdXRvbWF0aWNhbGx5UmVsZWFzZUNvbm5lY3Rpb25Ub1Bvb2woKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgKiBUaGUgZmlyc3QgcmVxdWVzdCB3YXMgaW5zdWZmaWNpZW50LiBQcmVwYXJlIGZvciBhbm90aGVyLi4uCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgU3RyaW5nIHJldHJ5TWV0aG9kID0gbWV0aG9kOworICAgICAgICAgICAgICAgIE91dHB1dFN0cmVhbSByZXF1ZXN0Qm9keSA9IGh0dHBFbmdpbmUuZ2V0UmVxdWVzdEJvZHkoKTsKKworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogQWx0aG91Z2ggUkZDIDI2MTYgMTAuMy4yIHNwZWNpZmllcyB0aGF0IGEgSFRUUF9NT1ZFRF9QRVJNCisgICAgICAgICAgICAgICAgICogcmVkaXJlY3Qgc2hvdWxkIGtlZXAgdGhlIHNhbWUgbWV0aG9kLCBDaHJvbWUsIEZpcmVmb3ggYW5kIHRoZQorICAgICAgICAgICAgICAgICAqIFJJIGFsbCBpc3N1ZSBHRVRzIHdoZW4gZm9sbG93aW5nIGFueSByZWRpcmVjdC4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBpbnQgcmVzcG9uc2VDb2RlID0gZ2V0UmVzcG9uc2VDb2RlKCk7CisgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlQ29kZSA9PSBIVFRQX01VTFRfQ0hPSUNFIHx8IHJlc3BvbnNlQ29kZSA9PSBIVFRQX01PVkVEX1BFUk0KKyAgICAgICAgICAgICAgICAgICAgICAgIHx8IHJlc3BvbnNlQ29kZSA9PSBIVFRQX01PVkVEX1RFTVAgfHwgcmVzcG9uc2VDb2RlID09IEhUVFBfU0VFX09USEVSKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHJ5TWV0aG9kID0gSHR0cEVuZ2luZS5HRVQ7CisgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RCb2R5ID0gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAocmVxdWVzdEJvZHkgIT0gbnVsbCAmJiAhKHJlcXVlc3RCb2R5IGluc3RhbmNlb2YgUmV0cnlhYmxlT3V0cHV0U3RyZWFtKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSHR0cFJldHJ5RXhjZXB0aW9uKCJDYW5ub3QgcmV0cnkgc3RyZWFtZWQgSFRUUCBib2R5IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBodHRwRW5naW5lLmdldFJlc3BvbnNlQ29kZSgpKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAocmV0cnkgPT0gUmV0cnkuRElGRkVSRU5UX0NPTk5FQ1RJT04pIHsKKyAgICAgICAgICAgICAgICAgICAgaHR0cEVuZ2luZS5hdXRvbWF0aWNhbGx5UmVsZWFzZUNvbm5lY3Rpb25Ub1Bvb2woKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBodHRwRW5naW5lLnJlbGVhc2UodHJ1ZSk7CisKKyAgICAgICAgICAgICAgICBodHRwRW5naW5lID0gbmV3SHR0cEVuZ2luZShyZXRyeU1ldGhvZCwgcmF3UmVxdWVzdEhlYWRlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICBodHRwRW5naW5lLmdldENvbm5lY3Rpb24oKSwgKFJldHJ5YWJsZU91dHB1dFN0cmVhbSkgcmVxdWVzdEJvZHkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGh0dHBFbmdpbmU7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGh0dHBFbmdpbmVGYWlsdXJlID0gZTsKKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBIdHRwRW5naW5lIGdldEh0dHBFbmdpbmUoKSB7CisgICAgICAgIHJldHVybiBodHRwRW5naW5lOworICAgIH0KKworICAgIGVudW0gUmV0cnkgeworICAgICAgICBOT05FLAorICAgICAgICBTQU1FX0NPTk5FQ1RJT04sCisgICAgICAgIERJRkZFUkVOVF9DT05ORUNUSU9OCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmV0cnkgYWN0aW9uIHRvIHRha2UgZm9yIHRoZSBjdXJyZW50IHJlc3BvbnNlIGhlYWRlcnMuIFRoZQorICAgICAqIGhlYWRlcnMsIHByb3h5IGFuZCB0YXJnZXQgVVJMIG9yIHRoaXMgY29ubmVjdGlvbiBtYXkgYmUgYWRqdXN0ZWQgdG8KKyAgICAgKiBwcmVwYXJlIGZvciBhIGZvbGxvdyB1cCByZXF1ZXN0LgorICAgICAqLworICAgIHByaXZhdGUgUmV0cnkgcHJvY2Vzc1Jlc3BvbnNlSGVhZGVycygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN3aXRjaCAoZ2V0UmVzcG9uc2VDb2RlKCkpIHsKKyAgICAgICAgY2FzZSBIVFRQX1BST1hZX0FVVEg6CisgICAgICAgICAgICBpZiAoIXVzaW5nUHJveHkoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICJSZWNlaXZlZCBIVFRQX1BST1hZX0FVVEggKDQwNykgY29kZSB3aGlsZSBub3QgdXNpbmcgcHJveHkiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIGZhbGwtdGhyb3VnaAorICAgICAgICBjYXNlIEhUVFBfVU5BVVRIT1JJWkVEOgorICAgICAgICAgICAgYm9vbGVhbiBjcmVkZW50aWFsc0ZvdW5kID0gcHJvY2Vzc0F1dGhIZWFkZXIoZ2V0UmVzcG9uc2VDb2RlKCksCisgICAgICAgICAgICAgICAgICAgIGh0dHBFbmdpbmUuZ2V0UmVzcG9uc2VIZWFkZXJzKCksIHJhd1JlcXVlc3RIZWFkZXJzKTsKKyAgICAgICAgICAgIHJldHVybiBjcmVkZW50aWFsc0ZvdW5kID8gUmV0cnkuU0FNRV9DT05ORUNUSU9OIDogUmV0cnkuTk9ORTsKKworICAgICAgICBjYXNlIEhUVFBfTVVMVF9DSE9JQ0U6CisgICAgICAgIGNhc2UgSFRUUF9NT1ZFRF9QRVJNOgorICAgICAgICBjYXNlIEhUVFBfTU9WRURfVEVNUDoKKyAgICAgICAgY2FzZSBIVFRQX1NFRV9PVEhFUjoKKyAgICAgICAgICAgIGlmICghZ2V0SW5zdGFuY2VGb2xsb3dSZWRpcmVjdHMoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBSZXRyeS5OT05FOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCsrcmVkaXJlY3Rpb25Db3VudCA+IEh0dHBFbmdpbmUuTUFYX1JFRElSRUNUUykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBQcm90b2NvbEV4Y2VwdGlvbigiVG9vIG1hbnkgcmVkaXJlY3RzIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTdHJpbmcgbG9jYXRpb24gPSBnZXRIZWFkZXJGaWVsZCgiTG9jYXRpb24iKTsKKyAgICAgICAgICAgIGlmIChsb2NhdGlvbiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIFJldHJ5Lk5PTkU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBVUkwgcHJldmlvdXNVcmwgPSB1cmw7CisgICAgICAgICAgICB1cmwgPSBuZXcgVVJMKHByZXZpb3VzVXJsLCBsb2NhdGlvbik7CisgICAgICAgICAgICBpZiAoIXByZXZpb3VzVXJsLmdldFByb3RvY29sKCkuZXF1YWxzKHVybC5nZXRQcm90b2NvbCgpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBSZXRyeS5OT05FOyAvLyB0aGUgc2NoZW1lIGNoYW5nZWQ7IGRvbid0IHJldHJ5LgorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHByZXZpb3VzVXJsLmdldEhvc3QoKS5lcXVhbHModXJsLmdldEhvc3QoKSkKKyAgICAgICAgICAgICAgICAgICAgJiYgcHJldmlvdXNVcmwuZ2V0RWZmZWN0aXZlUG9ydCgpID09IHVybC5nZXRFZmZlY3RpdmVQb3J0KCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gUmV0cnkuU0FNRV9DT05ORUNUSU9OOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gUmV0cnkuRElGRkVSRU5UX0NPTk5FQ1RJT047CisgICAgICAgICAgICB9CisKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHJldHVybiBSZXRyeS5OT05FOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhY3QgdG8gYSBmYWlsZWQgYXV0aG9yaXphdGlvbiByZXNwb25zZSBieSBsb29raW5nIHVwIG5ldyBjcmVkZW50aWFscy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBjcmVkZW50aWFscyBoYXZlIGJlZW4gYWRkZWQgdG8gc3VjY2Vzc29yUmVxdWVzdEhlYWRlcnMKKyAgICAgKiAgICAgYW5kIGFub3RoZXIgcmVxdWVzdCBzaG91bGQgYmUgYXR0ZW1wdGVkLgorICAgICAqLworICAgIGZpbmFsIGJvb2xlYW4gcHJvY2Vzc0F1dGhIZWFkZXIoaW50IHJlc3BvbnNlQ29kZSwgUmVzcG9uc2VIZWFkZXJzIHJlc3BvbnNlLAorICAgICAgICAgICAgUmF3SGVhZGVycyBzdWNjZXNzb3JSZXF1ZXN0SGVhZGVycykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHJlc3BvbnNlQ29kZSAhPSBIVFRQX1BST1hZX0FVVEggJiYgcmVzcG9uc2VDb2RlICE9IEhUVFBfVU5BVVRIT1JJWkVEKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBrZWVwIGFza2luZyBmb3IgdXNlcm5hbWUvcGFzc3dvcmQgdW50aWwgYXV0aG9yaXplZAorICAgICAgICBTdHJpbmcgY2hhbGxlbmdlID0gcmVzcG9uc2VDb2RlID09IEhUVFBfUFJPWFlfQVVUSAorICAgICAgICAgICAgICAgID8gcmVzcG9uc2UuZ2V0UHJveHlBdXRoZW50aWNhdGUoKQorICAgICAgICAgICAgICAgIDogcmVzcG9uc2UuZ2V0V3d3QXV0aGVudGljYXRlKCk7CisgICAgICAgIGlmIChjaGFsbGVuZ2UgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJSZWNlaXZlZCBhdXRoZW50aWNhdGlvbiBjaGFsbGVuZ2UgaXMgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBjcmVkZW50aWFscyA9IGdldEF1dGhvcml6YXRpb25DcmVkZW50aWFscyhjaGFsbGVuZ2UpOworICAgICAgICBpZiAoY3JlZGVudGlhbHMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBjb3VsZCBub3QgZmluZCBjcmVkZW50aWFscywgZW5kIHJlcXVlc3QgY3ljbGUKKyAgICAgICAgfQorCisgICAgICAgIC8vIGFkZCBhdXRob3JpemF0aW9uIGNyZWRlbnRpYWxzLCBieXBhc3NpbmcgdGhlIGFscmVhZHktY29ubmVjdGVkIGNoZWNrCisgICAgICAgIFN0cmluZyBmaWVsZE5hbWUgPSByZXNwb25zZUNvZGUgPT0gSFRUUF9QUk9YWV9BVVRICisgICAgICAgICAgICAgICAgPyAiUHJveHktQXV0aG9yaXphdGlvbiIKKyAgICAgICAgICAgICAgICA6ICJBdXRob3JpemF0aW9uIjsKKyAgICAgICAgc3VjY2Vzc29yUmVxdWVzdEhlYWRlcnMuc2V0KGZpZWxkTmFtZSwgY3JlZGVudGlhbHMpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhdXRob3JpemF0aW9uIGNyZWRlbnRpYWxzIG9uIHRoZSBiYXNlIG9mIHByb3ZpZGVkIGNoYWxsZW5nZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBnZXRBdXRob3JpemF0aW9uQ3JlZGVudGlhbHMoU3RyaW5nIGNoYWxsZW5nZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGlkeCA9IGNoYWxsZW5nZS5pbmRleE9mKCIgIik7CisgICAgICAgIGlmIChpZHggPT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBzY2hlbWUgPSBjaGFsbGVuZ2Uuc3Vic3RyaW5nKDAsIGlkeCk7CisgICAgICAgIGludCByZWFsbSA9IGNoYWxsZW5nZS5pbmRleE9mKCJyZWFsbT1cIiIpICsgNzsKKyAgICAgICAgU3RyaW5nIHByb21wdCA9IG51bGw7CisgICAgICAgIGlmIChyZWFsbSAhPSAtMSkgeworICAgICAgICAgICAgaW50IGVuZCA9IGNoYWxsZW5nZS5pbmRleE9mKCciJywgcmVhbG0pOworICAgICAgICAgICAgaWYgKGVuZCAhPSAtMSkgeworICAgICAgICAgICAgICAgIHByb21wdCA9IGNoYWxsZW5nZS5zdWJzdHJpbmcocmVhbG0sIGVuZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gdXNlIHRoZSBnbG9iYWwgYXV0aGVudGljYXRvciB0byBnZXQgdGhlIHBhc3N3b3JkCisgICAgICAgIFBhc3N3b3JkQXV0aGVudGljYXRpb24gcGEgPSBBdXRoZW50aWNhdG9yLnJlcXVlc3RQYXNzd29yZEF1dGhlbnRpY2F0aW9uKAorICAgICAgICAgICAgICAgIGdldENvbm5lY3RUb0luZXRBZGRyZXNzKCksIGdldENvbm5lY3RUb1BvcnQoKSwgdXJsLmdldFByb3RvY29sKCksIHByb21wdCwgc2NoZW1lKTsKKyAgICAgICAgaWYgKHBhID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIC8vIGJhc2U2NCBlbmNvZGUgdGhlIHVzZXJuYW1lIGFuZCBwYXNzd29yZAorICAgICAgICBTdHJpbmcgdXNlcm5hbWVBbmRQYXNzd29yZCA9IHBhLmdldFVzZXJOYW1lKCkgKyAiOiIgKyBuZXcgU3RyaW5nKHBhLmdldFBhc3N3b3JkKCkpOworICAgICAgICBieXRlW10gYnl0ZXMgPSB1c2VybmFtZUFuZFBhc3N3b3JkLmdldEJ5dGVzKENoYXJzZXRzLklTT184ODU5XzEpOworICAgICAgICBTdHJpbmcgZW5jb2RlZCA9IEJhc2U2NC5lbmNvZGUoYnl0ZXMpOworICAgICAgICByZXR1cm4gc2NoZW1lICsgIiAiICsgZW5jb2RlZDsKKyAgICB9CisKKyAgICBwcml2YXRlIEluZXRBZGRyZXNzIGdldENvbm5lY3RUb0luZXRBZGRyZXNzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHVzaW5nUHJveHkoKQorICAgICAgICAgICAgICAgID8gKChJbmV0U29ja2V0QWRkcmVzcykgcHJveHkuYWRkcmVzcygpKS5nZXRBZGRyZXNzKCkKKyAgICAgICAgICAgICAgICA6IEluZXRBZGRyZXNzLmdldEJ5TmFtZShnZXRVUkwoKS5nZXRIb3N0KCkpOworICAgIH0KKworICAgIGZpbmFsIGludCBnZXREZWZhdWx0UG9ydCgpIHsKKyAgICAgICAgcmV0dXJuIGRlZmF1bHRQb3J0OworICAgIH0KKworICAgIC8qKiBAc2VlIEh0dHBVUkxDb25uZWN0aW9uI3NldEZpeGVkTGVuZ3RoU3RyZWFtaW5nTW9kZShpbnQpICovCisgICAgZmluYWwgaW50IGdldEZpeGVkQ29udGVudExlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIGZpeGVkQ29udGVudExlbmd0aDsKKyAgICB9CisKKyAgICAvKiogQHNlZSBIdHRwVVJMQ29ubmVjdGlvbiNzZXRDaHVua2VkU3RyZWFtaW5nTW9kZShpbnQpICovCisgICAgZmluYWwgaW50IGdldENodW5rTGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gY2h1bmtMZW5ndGg7CisgICAgfQorCisgICAgZmluYWwgUHJveHkgZ2V0UHJveHkoKSB7CisgICAgICAgIHJldHVybiBwcm94eTsKKyAgICB9CisKKyAgICBmaW5hbCB2b2lkIHNldFByb3h5KFByb3h5IHByb3h5KSB7CisgICAgICAgIHRoaXMucHJveHkgPSBwcm94eTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGZpbmFsIGJvb2xlYW4gdXNpbmdQcm94eSgpIHsKKyAgICAgICAgcmV0dXJuIChwcm94eSAhPSBudWxsICYmIHByb3h5LnR5cGUoKSAhPSBQcm94eS5UeXBlLkRJUkVDVCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgZ2V0UmVzcG9uc2VNZXNzYWdlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGdldFJlc3BvbnNlKCkuZ2V0UmVzcG9uc2VIZWFkZXJzKCkuZ2V0SGVhZGVycygpLmdldFJlc3BvbnNlTWVzc2FnZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgZmluYWwgaW50IGdldFJlc3BvbnNlQ29kZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXRSZXNwb25zZSgpLmdldFJlc3BvbnNlQ29kZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgZmluYWwgdm9pZCBzZXRSZXF1ZXN0UHJvcGVydHkoU3RyaW5nIGZpZWxkLCBTdHJpbmcgbmV3VmFsdWUpIHsKKyAgICAgICAgaWYgKGNvbm5lY3RlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiQ2Fubm90IHNldCByZXF1ZXN0IHByb3BlcnR5IGFmdGVyIGNvbm5lY3Rpb24gaXMgbWFkZSIpOworICAgICAgICB9CisgICAgICAgIGlmIChmaWVsZCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImZpZWxkID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICByYXdSZXF1ZXN0SGVhZGVycy5zZXQoZmllbGQsIG5ld1ZhbHVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGZpbmFsIHZvaWQgYWRkUmVxdWVzdFByb3BlcnR5KFN0cmluZyBmaWVsZCwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIGlmIChjb25uZWN0ZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkNhbm5vdCBhZGQgcmVxdWVzdCBwcm9wZXJ0eSBhZnRlciBjb25uZWN0aW9uIGlzIG1hZGUiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZmllbGQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJmaWVsZCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgcmF3UmVxdWVzdEhlYWRlcnMuYWRkKGZpZWxkLCB2YWx1ZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvSHR0cHNIYW5kbGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9IdHRwc0hhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZDliYTcyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvSHR0cHNIYW5kbGVyLmphdmEKQEAgLTAsMCArMSw0MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLm5ldC5odHRwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Qcm94eTsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5uZXQuVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkxTdHJlYW1IYW5kbGVyOworCitwdWJsaWMgZmluYWwgY2xhc3MgSHR0cHNIYW5kbGVyIGV4dGVuZHMgVVJMU3RyZWFtSGFuZGxlciB7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIFVSTENvbm5lY3Rpb24gb3BlbkNvbm5lY3Rpb24oVVJMIHVybCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBIdHRwc1VSTENvbm5lY3Rpb25JbXBsKHVybCwgZ2V0RGVmYXVsdFBvcnQoKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBVUkxDb25uZWN0aW9uIG9wZW5Db25uZWN0aW9uKFVSTCB1cmwsIFByb3h5IHByb3h5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodXJsID09IG51bGwgfHwgcHJveHkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigidXJsID09IG51bGwgfHwgcHJveHkgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgSHR0cHNVUkxDb25uZWN0aW9uSW1wbCh1cmwsIGdldERlZmF1bHRQb3J0KCksIHByb3h5KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIGludCBnZXREZWZhdWx0UG9ydCgpIHsKKyAgICAgICAgcmV0dXJuIDQ0MzsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9IdHRwc1VSTENvbm5lY3Rpb25JbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9IdHRwc1VSTENvbm5lY3Rpb25JbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWU1ZTdjMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL0h0dHBzVVJMQ29ubmVjdGlvbkltcGwuamF2YQpAQCAtMCwwICsxLDU3NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5uZXQuaHR0cDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5DYWNoZVJlc3BvbnNlOworaW1wb3J0IGphdmEubmV0Lkh0dHBVUkxDb25uZWN0aW9uOworaW1wb3J0IGphdmEubmV0LlByb3RvY29sRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlByb3h5OworaW1wb3J0IGphdmEubmV0LlNlY3VyZUNhY2hlUmVzcG9uc2U7CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YXgubmV0LnNzbC5IdHRwc1VSTENvbm5lY3Rpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xIYW5kc2hha2VFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldDsKKworZmluYWwgY2xhc3MgSHR0cHNVUkxDb25uZWN0aW9uSW1wbCBleHRlbmRzIEh0dHBzVVJMQ29ubmVjdGlvbiB7CisKKyAgICAvKiogSHR0cFVybENvbm5lY3Rpb25EZWxlZ2F0ZSBhbGxvd3MgcmV1c2Ugb2YgSHR0cFVSTENvbm5lY3Rpb25JbXBsICovCisgICAgcHJpdmF0ZSBmaW5hbCBIdHRwVXJsQ29ubmVjdGlvbkRlbGVnYXRlIGRlbGVnYXRlOworCisgICAgcHJvdGVjdGVkIEh0dHBzVVJMQ29ubmVjdGlvbkltcGwoVVJMIHVybCwgaW50IHBvcnQpIHsKKyAgICAgICAgc3VwZXIodXJsKTsKKyAgICAgICAgZGVsZWdhdGUgPSBuZXcgSHR0cFVybENvbm5lY3Rpb25EZWxlZ2F0ZSh1cmwsIHBvcnQpOworICAgIH0KKworICAgIHByb3RlY3RlZCBIdHRwc1VSTENvbm5lY3Rpb25JbXBsKFVSTCB1cmwsIGludCBwb3J0LCBQcm94eSBwcm94eSkgeworICAgICAgICBzdXBlcih1cmwpOworICAgICAgICBkZWxlZ2F0ZSA9IG5ldyBIdHRwVXJsQ29ubmVjdGlvbkRlbGVnYXRlKHVybCwgcG9ydCwgcHJveHkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja0Nvbm5lY3RlZCgpIHsKKyAgICAgICAgaWYgKGRlbGVnYXRlLmdldFNTTFNvY2tldCgpID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkNvbm5lY3Rpb24gaGFzIG5vdCB5ZXQgYmVlbiBlc3RhYmxpc2hlZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgSHR0cEVuZ2luZSBnZXRIdHRwRW5naW5lKCkgeworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0SHR0cEVuZ2luZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2lwaGVyU3VpdGUoKSB7CisgICAgICAgIFNlY3VyZUNhY2hlUmVzcG9uc2UgY2FjaGVSZXNwb25zZSA9IGRlbGVnYXRlLmdldENhY2hlUmVzcG9uc2UoKTsKKyAgICAgICAgaWYgKGNhY2hlUmVzcG9uc2UgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGNhY2hlUmVzcG9uc2UuZ2V0Q2lwaGVyU3VpdGUoKTsKKyAgICAgICAgfQorICAgICAgICBjaGVja0Nvbm5lY3RlZCgpOworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0U1NMU29ja2V0KCkuZ2V0U2Vzc2lvbigpLmdldENpcGhlclN1aXRlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENlcnRpZmljYXRlW10gZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKSB7CisgICAgICAgIFNlY3VyZUNhY2hlUmVzcG9uc2UgY2FjaGVSZXNwb25zZSA9IGRlbGVnYXRlLmdldENhY2hlUmVzcG9uc2UoKTsKKyAgICAgICAgaWYgKGNhY2hlUmVzcG9uc2UgIT0gbnVsbCkgeworICAgICAgICAgICAgTGlzdDxDZXJ0aWZpY2F0ZT4gcmVzdWx0ID0gY2FjaGVSZXNwb25zZS5nZXRMb2NhbENlcnRpZmljYXRlQ2hhaW4oKTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQgIT0gbnVsbCA/IHJlc3VsdC50b0FycmF5KG5ldyBDZXJ0aWZpY2F0ZVtyZXN1bHQuc2l6ZSgpXSkgOiBudWxsOworICAgICAgICB9CisgICAgICAgIGNoZWNrQ29ubmVjdGVkKCk7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZS5nZXRTU0xTb2NrZXQoKS5nZXRTZXNzaW9uKCkuZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVbXSBnZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSB0aHJvd3MgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24geworICAgICAgICBTZWN1cmVDYWNoZVJlc3BvbnNlIGNhY2hlUmVzcG9uc2UgPSBkZWxlZ2F0ZS5nZXRDYWNoZVJlc3BvbnNlKCk7CisgICAgICAgIGlmIChjYWNoZVJlc3BvbnNlICE9IG51bGwpIHsKKyAgICAgICAgICAgIExpc3Q8Q2VydGlmaWNhdGU+IHJlc3VsdCA9IGNhY2hlUmVzcG9uc2UuZ2V0U2VydmVyQ2VydGlmaWNhdGVDaGFpbigpOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCAhPSBudWxsID8gcmVzdWx0LnRvQXJyYXkobmV3IENlcnRpZmljYXRlW3Jlc3VsdC5zaXplKCldKSA6IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tDb25uZWN0ZWQoKTsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmdldFNTTFNvY2tldCgpLmdldFNlc3Npb24oKS5nZXRQZWVyQ2VydGlmaWNhdGVzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFByaW5jaXBhbCBnZXRQZWVyUHJpbmNpcGFsKCkgdGhyb3dzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIHsKKyAgICAgICAgU2VjdXJlQ2FjaGVSZXNwb25zZSBjYWNoZVJlc3BvbnNlID0gZGVsZWdhdGUuZ2V0Q2FjaGVSZXNwb25zZSgpOworICAgICAgICBpZiAoY2FjaGVSZXNwb25zZSAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gY2FjaGVSZXNwb25zZS5nZXRQZWVyUHJpbmNpcGFsKCk7CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tDb25uZWN0ZWQoKTsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmdldFNTTFNvY2tldCgpLmdldFNlc3Npb24oKS5nZXRQZWVyUHJpbmNpcGFsKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFByaW5jaXBhbCBnZXRMb2NhbFByaW5jaXBhbCgpIHsKKyAgICAgICAgU2VjdXJlQ2FjaGVSZXNwb25zZSBjYWNoZVJlc3BvbnNlID0gZGVsZWdhdGUuZ2V0Q2FjaGVSZXNwb25zZSgpOworICAgICAgICBpZiAoY2FjaGVSZXNwb25zZSAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gY2FjaGVSZXNwb25zZS5nZXRMb2NhbFByaW5jaXBhbCgpOworICAgICAgICB9CisgICAgICAgIGNoZWNrQ29ubmVjdGVkKCk7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZS5nZXRTU0xTb2NrZXQoKS5nZXRTZXNzaW9uKCkuZ2V0TG9jYWxQcmluY2lwYWwoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkaXNjb25uZWN0KCkgeworICAgICAgICBkZWxlZ2F0ZS5kaXNjb25uZWN0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldEVycm9yU3RyZWFtKCkgeworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0RXJyb3JTdHJlYW0oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldFJlcXVlc3RNZXRob2QoKSB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZS5nZXRSZXF1ZXN0TWV0aG9kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRSZXNwb25zZUNvZGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0UmVzcG9uc2VDb2RlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRSZXNwb25zZU1lc3NhZ2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0UmVzcG9uc2VNZXNzYWdlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UmVxdWVzdE1ldGhvZChTdHJpbmcgbWV0aG9kKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworICAgICAgICBkZWxlZ2F0ZS5zZXRSZXF1ZXN0TWV0aG9kKG1ldGhvZCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gdXNpbmdQcm94eSgpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLnVzaW5nUHJveHkoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRJbnN0YW5jZUZvbGxvd1JlZGlyZWN0cygpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmdldEluc3RhbmNlRm9sbG93UmVkaXJlY3RzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0SW5zdGFuY2VGb2xsb3dSZWRpcmVjdHMoYm9vbGVhbiBmb2xsb3dSZWRpcmVjdHMpIHsKKyAgICAgICAgZGVsZWdhdGUuc2V0SW5zdGFuY2VGb2xsb3dSZWRpcmVjdHMoZm9sbG93UmVkaXJlY3RzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjb25uZWN0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY29ubmVjdGVkID0gdHJ1ZTsKKyAgICAgICAgZGVsZWdhdGUuY29ubmVjdCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGdldEFsbG93VXNlckludGVyYWN0aW9uKCkgeworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0QWxsb3dVc2VySW50ZXJhY3Rpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGdldENvbnRlbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0Q29udGVudCgpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSAvLyBTcGVjIGRvZXMgbm90IGdlbmVyaWZ5CisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBnZXRDb250ZW50KENsYXNzW10gdHlwZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZS5nZXRDb250ZW50KHR5cGVzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRFbmNvZGluZygpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmdldENvbnRlbnRFbmNvZGluZygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0Q29udGVudExlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmdldENvbnRlbnRMZW5ndGgoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgeworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0Q29udGVudFR5cGUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXREYXRlKCkgeworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0RGF0ZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGdldERlZmF1bHRVc2VDYWNoZXMoKSB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZS5nZXREZWZhdWx0VXNlQ2FjaGVzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0RG9JbnB1dCgpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmdldERvSW5wdXQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXREb091dHB1dCgpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmdldERvT3V0cHV0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0RXhwaXJhdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmdldEV4cGlyYXRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldEhlYWRlckZpZWxkKGludCBwb3MpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmdldEhlYWRlckZpZWxkKHBvcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gZ2V0SGVhZGVyRmllbGRzKCkgeworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0SGVhZGVyRmllbGRzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gZ2V0UmVxdWVzdFByb3BlcnRpZXMoKSB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZS5nZXRSZXF1ZXN0UHJvcGVydGllcygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGFkZFJlcXVlc3RQcm9wZXJ0eShTdHJpbmcgZmllbGQsIFN0cmluZyBuZXdWYWx1ZSkgeworICAgICAgICBkZWxlZ2F0ZS5hZGRSZXF1ZXN0UHJvcGVydHkoZmllbGQsIG5ld1ZhbHVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldEhlYWRlckZpZWxkKFN0cmluZyBrZXkpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmdldEhlYWRlckZpZWxkKGtleSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0SGVhZGVyRmllbGREYXRlKFN0cmluZyBmaWVsZCwgbG9uZyBkZWZhdWx0VmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmdldEhlYWRlckZpZWxkRGF0ZShmaWVsZCwgZGVmYXVsdFZhbHVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldEhlYWRlckZpZWxkSW50KFN0cmluZyBmaWVsZCwgaW50IGRlZmF1bHRWYWx1ZSkgeworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0SGVhZGVyRmllbGRJbnQoZmllbGQsIGRlZmF1bHRWYWx1ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRIZWFkZXJGaWVsZEtleShpbnQgcG9zbikgeworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0SGVhZGVyRmllbGRLZXkocG9zbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0SWZNb2RpZmllZFNpbmNlKCkgeworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0SWZNb2RpZmllZFNpbmNlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmdldElucHV0U3RyZWFtKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0TGFzdE1vZGlmaWVkKCkgeworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0TGFzdE1vZGlmaWVkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFBlcm1pc3Npb24gZ2V0UGVybWlzc2lvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZS5nZXRQZXJtaXNzaW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRSZXF1ZXN0UHJvcGVydHkoU3RyaW5nIGZpZWxkKSB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZS5nZXRSZXF1ZXN0UHJvcGVydHkoZmllbGQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBVUkwgZ2V0VVJMKCkgeworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0VVJMKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0VXNlQ2FjaGVzKCkgeworICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0VXNlQ2FjaGVzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0QWxsb3dVc2VySW50ZXJhY3Rpb24oYm9vbGVhbiBuZXdWYWx1ZSkgeworICAgICAgICBkZWxlZ2F0ZS5zZXRBbGxvd1VzZXJJbnRlcmFjdGlvbihuZXdWYWx1ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RGVmYXVsdFVzZUNhY2hlcyhib29sZWFuIG5ld1ZhbHVlKSB7CisgICAgICAgIGRlbGVnYXRlLnNldERlZmF1bHRVc2VDYWNoZXMobmV3VmFsdWUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldERvSW5wdXQoYm9vbGVhbiBuZXdWYWx1ZSkgeworICAgICAgICBkZWxlZ2F0ZS5zZXREb0lucHV0KG5ld1ZhbHVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXREb091dHB1dChib29sZWFuIG5ld1ZhbHVlKSB7CisgICAgICAgIGRlbGVnYXRlLnNldERvT3V0cHV0KG5ld1ZhbHVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRJZk1vZGlmaWVkU2luY2UobG9uZyBuZXdWYWx1ZSkgeworICAgICAgICBkZWxlZ2F0ZS5zZXRJZk1vZGlmaWVkU2luY2UobmV3VmFsdWUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFJlcXVlc3RQcm9wZXJ0eShTdHJpbmcgZmllbGQsIFN0cmluZyBuZXdWYWx1ZSkgeworICAgICAgICBkZWxlZ2F0ZS5zZXRSZXF1ZXN0UHJvcGVydHkoZmllbGQsIG5ld1ZhbHVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRVc2VDYWNoZXMoYm9vbGVhbiBuZXdWYWx1ZSkgeworICAgICAgICBkZWxlZ2F0ZS5zZXRVc2VDYWNoZXMobmV3VmFsdWUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldENvbm5lY3RUaW1lb3V0KGludCB0aW1lb3V0KSB7CisgICAgICAgIGRlbGVnYXRlLnNldENvbm5lY3RUaW1lb3V0KHRpbWVvdXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0Q29ubmVjdFRpbWVvdXQoKSB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZS5nZXRDb25uZWN0VGltZW91dCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFJlYWRUaW1lb3V0KGludCB0aW1lb3V0KSB7CisgICAgICAgIGRlbGVnYXRlLnNldFJlYWRUaW1lb3V0KHRpbWVvdXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0UmVhZFRpbWVvdXQoKSB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZS5nZXRSZWFkVGltZW91dCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZS50b1N0cmluZygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEZpeGVkTGVuZ3RoU3RyZWFtaW5nTW9kZShpbnQgY29udGVudExlbmd0aCkgeworICAgICAgICBkZWxlZ2F0ZS5zZXRGaXhlZExlbmd0aFN0cmVhbWluZ01vZGUoY29udGVudExlbmd0aCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0Q2h1bmtlZFN0cmVhbWluZ01vZGUoaW50IGNodW5rTGVuZ3RoKSB7CisgICAgICAgIGRlbGVnYXRlLnNldENodW5rZWRTdHJlYW1pbmdNb2RlKGNodW5rTGVuZ3RoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIGNsYXNzIEh0dHBVcmxDb25uZWN0aW9uRGVsZWdhdGUgZXh0ZW5kcyBIdHRwVVJMQ29ubmVjdGlvbkltcGwgeworICAgICAgICBwcml2YXRlIEh0dHBVcmxDb25uZWN0aW9uRGVsZWdhdGUoVVJMIHVybCwgaW50IHBvcnQpIHsKKyAgICAgICAgICAgIHN1cGVyKHVybCwgcG9ydCk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIEh0dHBVcmxDb25uZWN0aW9uRGVsZWdhdGUoVVJMIHVybCwgaW50IHBvcnQsIFByb3h5IHByb3h5KSB7CisgICAgICAgICAgICBzdXBlcih1cmwsIHBvcnQsIHByb3h5KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgSHR0cEVuZ2luZSBuZXdIdHRwRW5naW5lKFN0cmluZyBtZXRob2QsIFJhd0hlYWRlcnMgcmVxdWVzdEhlYWRlcnMsCisgICAgICAgICAgICAgICAgSHR0cENvbm5lY3Rpb24gY29ubmVjdGlvbiwgUmV0cnlhYmxlT3V0cHV0U3RyZWFtIHJlcXVlc3RCb2R5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG5ldyBIdHRwc0VuZ2luZSh0aGlzLCBtZXRob2QsIHJlcXVlc3RIZWFkZXJzLCBjb25uZWN0aW9uLCByZXF1ZXN0Qm9keSwKKyAgICAgICAgICAgICAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uSW1wbC50aGlzKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTZWN1cmVDYWNoZVJlc3BvbnNlIGdldENhY2hlUmVzcG9uc2UoKSB7CisgICAgICAgICAgICBIdHRwc0VuZ2luZSBlbmdpbmUgPSAoSHR0cHNFbmdpbmUpIGh0dHBFbmdpbmU7CisgICAgICAgICAgICByZXR1cm4gZW5naW5lICE9IG51bGwgPyAoU2VjdXJlQ2FjaGVSZXNwb25zZSkgZW5naW5lLmdldENhY2hlUmVzcG9uc2UoKSA6IG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU1NMU29ja2V0IGdldFNTTFNvY2tldCgpIHsKKyAgICAgICAgICAgIEh0dHBzRW5naW5lIGVuZ2luZSA9IChIdHRwc0VuZ2luZSkgaHR0cEVuZ2luZTsKKyAgICAgICAgICAgIHJldHVybiBlbmdpbmUgIT0gbnVsbCA/IGVuZ2luZS5zc2xTb2NrZXQgOiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgSHR0cHNFbmdpbmUgZXh0ZW5kcyBIdHRwRW5naW5lIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogTG9jYWwgc3Rhc2ggb2YgSHR0cHNFbmdpbmUuY29ubmVjdGlvbi5zc2xTb2NrZXQgZm9yIGFuc3dlcmluZworICAgICAgICAgKiBxdWVyaWVzIHN1Y2ggYXMgZ2V0Q2lwaGVyU3VpdGUgZXZlbiBhZnRlcgorICAgICAgICAgKiBodHRwc0VuZ2luZS5Db25uZWN0aW9uIGhhcyBiZWVuIHJlY3ljbGVkLiBJdCdzIHByZXNlbmNlIGlzIGFsc28KKyAgICAgICAgICogdXNlZCB0byB0ZWxsIGlmIHRoZSBIdHRwc1VSTENvbm5lY3Rpb24gaXMgY29uc2lkZXJlZCBjb25uZWN0ZWQsCisgICAgICAgICAqIGFzIG9wcG9zZWQgdG8gdGhlIGNvbm5lY3RlZCBmaWVsZCBvZiBVUkxDb25uZWN0aW9uIG9yIHRoZSBhCisgICAgICAgICAqIG5vbi1udWxsIGNvbm5lY3QgaW4gSHR0cFVSTENvbm5lY3Rpb25JbXBsCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIFNTTFNvY2tldCBzc2xTb2NrZXQ7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBIdHRwc1VSTENvbm5lY3Rpb25JbXBsIGVuY2xvc2luZzsKKworICAgICAgICAvKioKKyAgICAgICAgICogQHBhcmFtIHBvbGljeSB0aGUgSHR0cFVSTENvbm5lY3Rpb25JbXBsIHdpdGggY29ubmVjdGlvbiBjb25maWd1cmF0aW9uCisgICAgICAgICAqIEBwYXJhbSBlbmNsb3NpbmcgdGhlIEh0dHBzVVJMQ29ubmVjdGlvbiB3aXRoIEhUVFBTIGZlYXR1cmVzCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIEh0dHBzRW5naW5lKEh0dHBVUkxDb25uZWN0aW9uSW1wbCBwb2xpY3ksIFN0cmluZyBtZXRob2QsIFJhd0hlYWRlcnMgcmVxdWVzdEhlYWRlcnMsCisgICAgICAgICAgICAgICAgSHR0cENvbm5lY3Rpb24gY29ubmVjdGlvbiwgUmV0cnlhYmxlT3V0cHV0U3RyZWFtIHJlcXVlc3RCb2R5LAorICAgICAgICAgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbkltcGwgZW5jbG9zaW5nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIocG9saWN5LCBtZXRob2QsIHJlcXVlc3RIZWFkZXJzLCBjb25uZWN0aW9uLCByZXF1ZXN0Qm9keSk7CisgICAgICAgICAgICB0aGlzLnNzbFNvY2tldCA9IGNvbm5lY3Rpb24gIT0gbnVsbCA/IGNvbm5lY3Rpb24uZ2V0U2VjdXJlU29ja2V0SWZDb25uZWN0ZWQoKSA6IG51bGw7CisgICAgICAgICAgICB0aGlzLmVuY2xvc2luZyA9IGVuY2xvc2luZzsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBjb25uZWN0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIC8vIGZpcnN0IHRyeSBhbiBTU0wgY29ubmVjdGlvbiB3aXRoIGNvbXByZXNzaW9uIGFuZAorICAgICAgICAgICAgLy8gdmFyaW91cyBUTFMgZXh0ZW5zaW9ucyBlbmFibGVkLCBpZiBpdCBmYWlscyAoYW5kIGl0cworICAgICAgICAgICAgLy8gbm90IHVuaGVhcmQgb2YgdGhhdCBpdCB3aWxsKSBmYWxsYmFjayB0byBhIG1vcmUKKyAgICAgICAgICAgIC8vIGJhcmVib25lcyBjb25uZWN0aW9ucworICAgICAgICAgICAgYm9vbGVhbiBjb25uZWN0aW9uUmV1c2VkOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjb25uZWN0aW9uUmV1c2VkID0gbWFrZVNzbENvbm5lY3Rpb24odHJ1ZSk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gSWYgdGhlIHByb2JsZW0gd2FzIGEgQ2VydGlmaWNhdGVFeGNlcHRpb24gZnJvbSB0aGUgWDUwOVRydXN0TWFuYWdlciwKKyAgICAgICAgICAgICAgICAvLyBkbyBub3QgcmV0cnksIHdlIGRpZG4ndCBoYXZlIGFuIGFicnVwdCBzZXJ2ZXIgaW5pdGlhdGVkIGV4Y2VwdGlvbi4KKyAgICAgICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFNTTEhhbmRzaGFrZUV4Y2VwdGlvbgorICAgICAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDYXVzZSgpIGluc3RhbmNlb2YgQ2VydGlmaWNhdGVFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmVsZWFzZShmYWxzZSk7CisgICAgICAgICAgICAgICAgY29ubmVjdGlvblJldXNlZCA9IG1ha2VTc2xDb25uZWN0aW9uKGZhbHNlKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKCFjb25uZWN0aW9uUmV1c2VkKSB7CisgICAgICAgICAgICAgICAgc3NsU29ja2V0ID0gY29ubmVjdGlvbi52ZXJpZnlTZWN1cmVTb2NrZXRIb3N0bmFtZShlbmNsb3NpbmcuZ2V0SG9zdG5hbWVWZXJpZmllcigpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBBdHRlbXB0IHRvIG1ha2UgYW4gaHR0cHMgY29ubmVjdGlvbi4gUmV0dXJucyB0cnVlIGlmIGEKKyAgICAgICAgICogY29ubmVjdGlvbiB3YXMgcmV1c2VkLCBmYWxzZSBvdGhlcndpc2UuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSB0bHNUb2xlcmFudCBJZiB0cnVlLCBhc3N1bWUgc2VydmVyIGNhbiBoYW5kbGUgY29tbW9uCisgICAgICAgICAqIFRMUyBleHRlbnNpb25zIGFuZCBTU0wgZGVmbGF0ZSBjb21wcmVzc2lvbi4gSWYgZmFsc2UsIHVzZQorICAgICAgICAgKiBhbiBTU0wzIG9ubHkgZmFsbGJhY2sgbW9kZSB3aXRob3V0IGNvbXByZXNzaW9uLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIG1ha2VTc2xDb25uZWN0aW9uKGJvb2xlYW4gdGxzVG9sZXJhbnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBtYWtlIGFuIFNTTCBUdW5uZWwgb24gdGhlIGZpcnN0IG1lc3NhZ2UgcGFpciBvZiBlYWNoIFNTTCArIHByb3h5IGNvbm5lY3Rpb24KKyAgICAgICAgICAgIGlmIChjb25uZWN0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjb25uZWN0aW9uID0gb3BlblNvY2tldENvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvbi5nZXRBZGRyZXNzKCkuZ2V0UHJveHkoKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIG1ha2VUdW5uZWwocG9saWN5LCBjb25uZWN0aW9uLCBnZXRSZXF1ZXN0SGVhZGVycygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGlmIHN1cGVyLm1ha2VDb25uZWN0aW9uIHJldHVybmVkIGEgY29ubmVjdGlvbiBmcm9tIHRoZQorICAgICAgICAgICAgLy8gcG9vbCwgc3NsU29ja2V0IG5lZWRzIHRvIGJlIGluaXRpYWxpemVkIGhlcmUuIElmIGl0IGlzCisgICAgICAgICAgICAvLyBhIG5ldyBjb25uZWN0aW9uLCBpdCB3aWxsIGJlIGluaXRpYWxpemVkIGJ5CisgICAgICAgICAgICAvLyBnZXRTZWN1cmVTb2NrZXQgYmVsb3cuCisgICAgICAgICAgICBzc2xTb2NrZXQgPSBjb25uZWN0aW9uLmdldFNlY3VyZVNvY2tldElmQ29ubmVjdGVkKCk7CisKKyAgICAgICAgICAgIC8vIHdlIGFscmVhZHkgaGF2ZSBhbiBTU0wgY29ubmVjdGlvbiwKKyAgICAgICAgICAgIGlmIChzc2xTb2NrZXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjb25uZWN0aW9uLnNldHVwU2VjdXJlU29ja2V0KGVuY2xvc2luZy5nZXRTU0xTb2NrZXRGYWN0b3J5KCksIHRsc1RvbGVyYW50KTsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBUbyBtYWtlIGFuIEhUVFBTIGNvbm5lY3Rpb24gb3ZlciBhbiBIVFRQIHByb3h5LCBzZW5kIGFuIHVuZW5jcnlwdGVkCisgICAgICAgICAqIENPTk5FQ1QgcmVxdWVzdCB0byBjcmVhdGUgdGhlIHByb3h5IGNvbm5lY3Rpb24uIFRoaXMgbWF5IG5lZWQgdG8gYmUKKyAgICAgICAgICogcmV0cmllZCBpZiB0aGUgcHJveHkgcmVxdWlyZXMgYXV0aG9yaXphdGlvbi4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgdm9pZCBtYWtlVHVubmVsKEh0dHBVUkxDb25uZWN0aW9uSW1wbCBwb2xpY3ksIEh0dHBDb25uZWN0aW9uIGNvbm5lY3Rpb24sCisgICAgICAgICAgICAgICAgUmVxdWVzdEhlYWRlcnMgcmVxdWVzdEhlYWRlcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBSYXdIZWFkZXJzIHJhd1JlcXVlc3RIZWFkZXJzID0gcmVxdWVzdEhlYWRlcnMuZ2V0SGVhZGVycygpOworICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICBIdHRwRW5naW5lIGNvbm5lY3QgPSBuZXcgUHJveHlDb25uZWN0RW5naW5lKHBvbGljeSwgcmF3UmVxdWVzdEhlYWRlcnMsIGNvbm5lY3Rpb24pOworICAgICAgICAgICAgICAgIGNvbm5lY3Quc2VuZFJlcXVlc3QoKTsKKyAgICAgICAgICAgICAgICBjb25uZWN0LnJlYWRSZXNwb25zZSgpOworCisgICAgICAgICAgICAgICAgaW50IHJlc3BvbnNlQ29kZSA9IGNvbm5lY3QuZ2V0UmVzcG9uc2VDb2RlKCk7CisgICAgICAgICAgICAgICAgc3dpdGNoIChjb25uZWN0LmdldFJlc3BvbnNlQ29kZSgpKSB7CisgICAgICAgICAgICAgICAgY2FzZSBIVFRQX09LOgorICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgY2FzZSBIVFRQX1BST1hZX0FVVEg6CisgICAgICAgICAgICAgICAgICAgIHJhd1JlcXVlc3RIZWFkZXJzID0gbmV3IFJhd0hlYWRlcnMocmF3UmVxdWVzdEhlYWRlcnMpOworICAgICAgICAgICAgICAgICAgICBib29sZWFuIGNyZWRlbnRpYWxzRm91bmQgPSBwb2xpY3kucHJvY2Vzc0F1dGhIZWFkZXIoSFRUUF9QUk9YWV9BVVRILAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3QuZ2V0UmVzcG9uc2VIZWFkZXJzKCksIHJhd1JlcXVlc3RIZWFkZXJzKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNyZWRlbnRpYWxzRm91bmQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJGYWlsZWQgdG8gYXV0aGVudGljYXRlIHdpdGggcHJveHkiKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5leHBlY3RlZCByZXNwb25zZSBjb2RlIGZvciBDT05ORUNUOiAiICsgcmVzcG9uc2VDb2RlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIGJvb2xlYW4gYWNjZXB0Q2FjaGVSZXNwb25zZVR5cGUoQ2FjaGVSZXNwb25zZSBjYWNoZVJlc3BvbnNlKSB7CisgICAgICAgICAgICByZXR1cm4gY2FjaGVSZXNwb25zZSBpbnN0YW5jZW9mIFNlY3VyZUNhY2hlUmVzcG9uc2U7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIGJvb2xlYW4gaW5jbHVkZUF1dGhvcml0eUluUmVxdWVzdExpbmUoKSB7CisgICAgICAgICAgICAvLyBFdmVuIGlmIHRoZXJlIGlzIGEgcHJveHksIGl0IGlzbid0IGludm9sdmVkLiBBbHdheXMgcmVxdWVzdCBqdXN0IHRoZSBmaWxlLgorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBIdHRwVVJMQ29ubmVjdGlvbiBnZXRIdHRwQ29ubmVjdGlvblRvQ2FjaGUoKSB7CisgICAgICAgICAgICByZXR1cm4gZW5jbG9zaW5nOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgUHJveHlDb25uZWN0RW5naW5lIGV4dGVuZHMgSHR0cEVuZ2luZSB7CisgICAgICAgIHB1YmxpYyBQcm94eUNvbm5lY3RFbmdpbmUoSHR0cFVSTENvbm5lY3Rpb25JbXBsIHBvbGljeSwgUmF3SGVhZGVycyByZXF1ZXN0SGVhZGVycywKKyAgICAgICAgICAgICAgICBIdHRwQ29ubmVjdGlvbiBjb25uZWN0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIocG9saWN5LCBIdHRwRW5naW5lLkNPTk5FQ1QsIHJlcXVlc3RIZWFkZXJzLCBjb25uZWN0aW9uLCBudWxsKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBJZiB3ZSdyZSBlc3RhYmxpc2hpbmcgYW4gSFRUUFMgdHVubmVsIHdpdGggQ09OTkVDVCAoUkZDIDI4MTcgNS4yKSwgc2VuZAorICAgICAgICAgKiBvbmx5IHRoZSBtaW5pbXVtIHNldCBvZiBoZWFkZXJzLiBUaGlzIGF2b2lkcyBzZW5kaW5nIHBvdGVudGlhbGx5CisgICAgICAgICAqIHNlbnNpdGl2ZSBkYXRhIGxpa2UgSFRUUCBjb29raWVzIHRvIHRoZSBwcm94eSB1bmVuY3J5cHRlZC4KKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgUmF3SGVhZGVycyBnZXROZXR3b3JrUmVxdWVzdEhlYWRlcnMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgUmVxdWVzdEhlYWRlcnMgcHJpdmF0ZUhlYWRlcnMgPSBnZXRSZXF1ZXN0SGVhZGVycygpOworICAgICAgICAgICAgVVJMIHVybCA9IHBvbGljeS5nZXRVUkwoKTsKKworICAgICAgICAgICAgUmF3SGVhZGVycyByZXN1bHQgPSBuZXcgUmF3SGVhZGVycygpOworICAgICAgICAgICAgcmVzdWx0LnNldFN0YXR1c0xpbmUoIkNPTk5FQ1QgIiArIHVybC5nZXRIb3N0KCkgKyAiOiIgKyB1cmwuZ2V0RWZmZWN0aXZlUG9ydCgpCisgICAgICAgICAgICAgICAgICAgICsgIiBIVFRQLzEuMSIpOworCisgICAgICAgICAgICAvLyBBbHdheXMgc2V0IEhvc3QgYW5kIFVzZXItQWdlbnQuCisgICAgICAgICAgICBTdHJpbmcgaG9zdCA9IHByaXZhdGVIZWFkZXJzLmdldEhvc3QoKTsKKyAgICAgICAgICAgIGlmIChob3N0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBob3N0ID0gZ2V0T3JpZ2luQWRkcmVzcyh1cmwpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0LnNldCgiSG9zdCIsIGhvc3QpOworCisgICAgICAgICAgICBTdHJpbmcgdXNlckFnZW50ID0gcHJpdmF0ZUhlYWRlcnMuZ2V0VXNlckFnZW50KCk7CisgICAgICAgICAgICBpZiAodXNlckFnZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB1c2VyQWdlbnQgPSBnZXREZWZhdWx0VXNlckFnZW50KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHQuc2V0KCJVc2VyLUFnZW50IiwgdXNlckFnZW50KTsKKworICAgICAgICAgICAgLy8gQ29weSBvdmVyIHRoZSBQcm94eS1BdXRob3JpemF0aW9uIGhlYWRlciBpZiBpdCBleGlzdHMuCisgICAgICAgICAgICBTdHJpbmcgcHJveHlBdXRob3JpemF0aW9uID0gcHJpdmF0ZUhlYWRlcnMuZ2V0UHJveHlBdXRob3JpemF0aW9uKCk7CisgICAgICAgICAgICBpZiAocHJveHlBdXRob3JpemF0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuc2V0KCJQcm94eS1BdXRob3JpemF0aW9uIiwgcHJveHlBdXRob3JpemF0aW9uKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gQWx3YXlzIHNldCB0aGUgUHJveHktQ29ubmVjdGlvbiB0byBLZWVwLUFsaXZlIGZvciB0aGUgYmVuZWZpdCBvZgorICAgICAgICAgICAgLy8gSFRUUC8xLjAgcHJveGllcyBsaWtlIFNxdWlkLgorICAgICAgICAgICAgcmVzdWx0LnNldCgiUHJveHktQ29ubmVjdGlvbiIsICJLZWVwLUFsaXZlIik7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBib29sZWFuIHJlcXVpcmVzVHVubmVsKCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9SYXdIZWFkZXJzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9SYXdIZWFkZXJzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjFiNDhmMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL1Jhd0hlYWRlcnMuamF2YQpAQCAtMCwwICsxLDI5NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLm5ldC5odHRwOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwLkVudHJ5OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CisKKy8qKgorICogVGhlIEhUVFAgc3RhdHVzIGFuZCB1bnBhcnNlZCBoZWFkZXIgZmllbGRzIG9mIGEgc2luZ2xlIEhUVFAgbWVzc2FnZS4gVmFsdWVzCisgKiBhcmUgcmVwcmVzZW50ZWQgYXMgdW5pbnRlcnByZXRlZCBzdHJpbmdzOyB1c2Uge0BsaW5rIFJlcXVlc3RIZWFkZXJzfSBhbmQKKyAqIHtAbGluayBSZXNwb25zZUhlYWRlcnN9IGZvciBpbnRlcnByZXRlZCBoZWFkZXJzLiBUaGlzIGNsYXNzIG1haW50YWlucyB0aGUKKyAqIG9yZGVyIG9mIHRoZSBoZWFkZXIgZmllbGRzIHdpdGhpbiB0aGUgSFRUUCBtZXNzYWdlLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgdHJhY2tzIGZpZWxkcyBsaW5lLWJ5LWxpbmUuIEEgZmllbGQgd2l0aCBtdWx0aXBsZSBjb21tYS0KKyAqIHNlcGFyYXRlZCB2YWx1ZXMgb24gdGhlIHNhbWUgbGluZSB3aWxsIGJlIHRyZWF0ZWQgYXMgYSBmaWVsZCB3aXRoIGEgc2luZ2xlCisgKiB2YWx1ZSBieSB0aGlzIGNsYXNzLiBJdCBpcyB0aGUgY2FsbGVyJ3MgcmVzcG9uc2liaWxpdHkgdG8gZGV0ZWN0IGFuZCBzcGxpdAorICogb24gY29tbWFzIGlmIHRoZWlyIGZpZWxkIHBlcm1pdHMgbXVsdGlwbGUgdmFsdWVzLiBUaGlzIHNpbXBsaWZpZXMgdXNlIG9mCisgKiBzaW5nbGUtdmFsdWVkIGZpZWxkcyB3aG9zZSB2YWx1ZXMgcm91dGluZWx5IGNvbnRhaW4gY29tbWFzLCBzdWNoIGFzIGNvb2tpZXMKKyAqIG9yIGRhdGVzLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgdHJpbXMgd2hpdGVzcGFjZSBmcm9tIHZhbHVlcy4gSXQgbmV2ZXIgcmV0dXJucyB2YWx1ZXMgd2l0aAorICogbGVhZGluZyBvciB0cmFpbGluZyB3aGl0ZXNwYWNlLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUmF3SGVhZGVycyB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29tcGFyYXRvcjxTdHJpbmc+IEZJRUxEX05BTUVfQ09NUEFSQVRPUiA9IG5ldyBDb21wYXJhdG9yPFN0cmluZz4oKSB7CisgICAgICAgIEBGaW5kQnVnc1N1cHByZXNzV2FybmluZ3MoIkVTX0NPTVBBUklOR19QQVJBTUVURVJfU1RSSU5HX1dJVEhfRVEiKQorICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBjb21wYXJlKFN0cmluZyBhLCBTdHJpbmcgYikgeworICAgICAgICAgICAgaWYgKGEgPT0gYikgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfSBlbHNlIGlmIChhID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gU3RyaW5nLkNBU0VfSU5TRU5TSVRJVkVfT1JERVIuY29tcGFyZShhLCBiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH07CisKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8U3RyaW5nPiBuYW1lc0FuZFZhbHVlcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigyMCk7CisgICAgcHJpdmF0ZSBTdHJpbmcgc3RhdHVzTGluZTsKKyAgICBwcml2YXRlIGludCBodHRwTWlub3JWZXJzaW9uID0gMTsKKyAgICBwcml2YXRlIGludCByZXNwb25zZUNvZGUgPSAtMTsKKyAgICBwcml2YXRlIFN0cmluZyByZXNwb25zZU1lc3NhZ2U7CisKKyAgICBwdWJsaWMgUmF3SGVhZGVycygpIHt9CisKKyAgICBwdWJsaWMgUmF3SGVhZGVycyhSYXdIZWFkZXJzIGNvcHlGcm9tKSB7CisgICAgICAgIG5hbWVzQW5kVmFsdWVzLmFkZEFsbChjb3B5RnJvbS5uYW1lc0FuZFZhbHVlcyk7CisgICAgICAgIHN0YXR1c0xpbmUgPSBjb3B5RnJvbS5zdGF0dXNMaW5lOworICAgICAgICBodHRwTWlub3JWZXJzaW9uID0gY29weUZyb20uaHR0cE1pbm9yVmVyc2lvbjsKKyAgICAgICAgcmVzcG9uc2VDb2RlID0gY29weUZyb20ucmVzcG9uc2VDb2RlOworICAgICAgICByZXNwb25zZU1lc3NhZ2UgPSBjb3B5RnJvbS5yZXNwb25zZU1lc3NhZ2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcmVzcG9uc2Ugc3RhdHVzIGxpbmUgKGxpa2UgIkhUVFAvMS4wIDIwMCBPSyIpIG9yIHJlcXVlc3QgbGluZQorICAgICAqIChsaWtlICJHRVQgLyBIVFRQLzEuMSIpLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN0YXR1c0xpbmUoU3RyaW5nIHN0YXR1c0xpbmUpIHsKKyAgICAgICAgc3RhdHVzTGluZSA9IHN0YXR1c0xpbmUudHJpbSgpOworICAgICAgICB0aGlzLnN0YXR1c0xpbmUgPSBzdGF0dXNMaW5lOworCisgICAgICAgIGlmIChzdGF0dXNMaW5lID09IG51bGwgfHwgIXN0YXR1c0xpbmUuc3RhcnRzV2l0aCgiSFRUUC8iKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHN0YXR1c0xpbmUgPSBzdGF0dXNMaW5lLnRyaW0oKTsKKyAgICAgICAgaW50IG1hcmsgPSBzdGF0dXNMaW5lLmluZGV4T2YoIiAiKSArIDE7CisgICAgICAgIGlmIChtYXJrID09IDApIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3RhdHVzTGluZS5jaGFyQXQobWFyayAtIDIpICE9ICcxJykgeworICAgICAgICAgICAgdGhpcy5odHRwTWlub3JWZXJzaW9uID0gMDsKKyAgICAgICAgfQorICAgICAgICBpbnQgbGFzdCA9IG1hcmsgKyAzOworICAgICAgICBpZiAobGFzdCA+IHN0YXR1c0xpbmUubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgIGxhc3QgPSBzdGF0dXNMaW5lLmxlbmd0aCgpOworICAgICAgICB9CisgICAgICAgIHRoaXMucmVzcG9uc2VDb2RlID0gSW50ZWdlci5wYXJzZUludChzdGF0dXNMaW5lLnN1YnN0cmluZyhtYXJrLCBsYXN0KSk7CisgICAgICAgIGlmIChsYXN0ICsgMSA8PSBzdGF0dXNMaW5lLmxlbmd0aCgpKSB7CisgICAgICAgICAgICB0aGlzLnJlc3BvbnNlTWVzc2FnZSA9IHN0YXR1c0xpbmUuc3Vic3RyaW5nKGxhc3QgKyAxKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RhdHVzTGluZSgpIHsKKyAgICAgICAgcmV0dXJuIHN0YXR1c0xpbmU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RhdHVzIGxpbmUncyBIVFRQIG1pbm9yIHZlcnNpb24uIFRoaXMgcmV0dXJucyAwIGZvciBIVFRQLzEuMAorICAgICAqIGFuZCAxIGZvciBIVFRQLzEuMS4gVGhpcyByZXR1cm5zIDEgaWYgdGhlIEhUVFAgdmVyc2lvbiBpcyB1bmtub3duLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SHR0cE1pbm9yVmVyc2lvbigpIHsKKyAgICAgICAgcmV0dXJuIGh0dHBNaW5vclZlcnNpb24gIT0gLTEgPyBodHRwTWlub3JWZXJzaW9uIDogMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBIVFRQIHN0YXR1cyBjb2RlIG9yIC0xIGlmIGl0IGlzIHVua25vd24uCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSZXNwb25zZUNvZGUoKSB7CisgICAgICAgIHJldHVybiByZXNwb25zZUNvZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgSFRUUCBzdGF0dXMgbWVzc2FnZSBvciBudWxsIGlmIGl0IGlzIHVua25vd24uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRSZXNwb25zZU1lc3NhZ2UoKSB7CisgICAgICAgIHJldHVybiByZXNwb25zZU1lc3NhZ2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkIGFuIEhUVFAgaGVhZGVyIGxpbmUgY29udGFpbmluZyBhIGZpZWxkIG5hbWUsIGEgbGl0ZXJhbCBjb2xvbiwgYW5kIGEKKyAgICAgKiB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRMaW5lKFN0cmluZyBsaW5lKSB7CisgICAgICAgIGludCBpbmRleCA9IGxpbmUuaW5kZXhPZigiOiIpOworICAgICAgICBpZiAoaW5kZXggPT0gLTEpIHsKKyAgICAgICAgICAgIGFkZCgiIiwgbGluZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBhZGQobGluZS5zdWJzdHJpbmcoMCwgaW5kZXgpLCBsaW5lLnN1YnN0cmluZyhpbmRleCArIDEpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCBhIGZpZWxkIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGQoU3RyaW5nIGZpZWxkTmFtZSwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIGlmIChmaWVsZE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiZmllbGROYW1lID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIEdpdmVuIG51bGwgdmFsdWVzLCB0aGUgUkkgc2VuZHMgYSBtYWxmb3JtZWQgZmllbGQgbGluZSBsaWtlCisgICAgICAgICAgICAgKiAiQWNjZXB0XHJcbiIuIEZvciBwbGF0Zm9ybSBjb21wYXRpYmlsaXR5IGFuZCBIVFRQIGNvbXBsaWFuY2UsIHdlCisgICAgICAgICAgICAgKiBwcmludCBhIHdhcm5pbmcgYW5kIGlnbm9yZSBudWxsIHZhbHVlcy4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgU3lzdGVtLmxvZ1coIklnbm9yaW5nIEhUVFAgaGVhZGVyIGZpZWxkICciICsgZmllbGROYW1lICsgIicgYmVjYXVzZSBpdHMgdmFsdWUgaXMgbnVsbCIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIG5hbWVzQW5kVmFsdWVzLmFkZChmaWVsZE5hbWUpOworICAgICAgICBuYW1lc0FuZFZhbHVlcy5hZGQodmFsdWUudHJpbSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZW1vdmVBbGwoU3RyaW5nIGZpZWxkTmFtZSkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5hbWVzQW5kVmFsdWVzLnNpemUoKTsgaSArPSAyKSB7CisgICAgICAgICAgICBpZiAoZmllbGROYW1lLmVxdWFsc0lnbm9yZUNhc2UobmFtZXNBbmRWYWx1ZXMuZ2V0KGkpKSkgeworICAgICAgICAgICAgICAgIG5hbWVzQW5kVmFsdWVzLnJlbW92ZShpKTsgLy8gZmllbGQgbmFtZQorICAgICAgICAgICAgICAgIG5hbWVzQW5kVmFsdWVzLnJlbW92ZShpKTsgLy8gdmFsdWUKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGFkZEFsbChTdHJpbmcgZmllbGROYW1lLCBMaXN0PFN0cmluZz4gaGVhZGVyRmllbGRzKSB7CisgICAgICAgIGZvciAoU3RyaW5nIHZhbHVlIDogaGVhZGVyRmllbGRzKSB7CisgICAgICAgICAgICBhZGQoZmllbGROYW1lLCB2YWx1ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgYSBmaWVsZCB3aXRoIHRoZSBzcGVjaWZpZWQgdmFsdWUuIElmIHRoZSBmaWVsZCBpcyBub3QgZm91bmQsIGl0IGlzCisgICAgICogYWRkZWQuIElmIHRoZSBmaWVsZCBpcyBmb3VuZCwgdGhlIGV4aXN0aW5nIHZhbHVlcyBhcmUgcmVwbGFjZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0KFN0cmluZyBmaWVsZE5hbWUsIFN0cmluZyB2YWx1ZSkgeworICAgICAgICByZW1vdmVBbGwoZmllbGROYW1lKTsKKyAgICAgICAgYWRkKGZpZWxkTmFtZSwgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBmaWVsZCB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIGludCBsZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBuYW1lc0FuZFZhbHVlcy5zaXplKCkgLyAyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZpZWxkIGF0IHtAY29kZSBwb3NpdGlvbn0gb3IgbnVsbCBpZiB0aGF0IGlzIG91dCBvZiByYW5nZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZpZWxkTmFtZShpbnQgaW5kZXgpIHsKKyAgICAgICAgaW50IGZpZWxkTmFtZUluZGV4ID0gaW5kZXggKiAyOworICAgICAgICBpZiAoZmllbGROYW1lSW5kZXggPCAwIHx8IGZpZWxkTmFtZUluZGV4ID49IG5hbWVzQW5kVmFsdWVzLnNpemUoKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5hbWVzQW5kVmFsdWVzLmdldChmaWVsZE5hbWVJbmRleCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgYXQge0Bjb2RlIGluZGV4fSBvciBudWxsIGlmIHRoYXQgaXMgb3V0IG9mIHJhbmdlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoaW50IGluZGV4KSB7CisgICAgICAgIGludCB2YWx1ZUluZGV4ID0gaW5kZXggKiAyICsgMTsKKyAgICAgICAgaWYgKHZhbHVlSW5kZXggPCAwIHx8IHZhbHVlSW5kZXggPj0gbmFtZXNBbmRWYWx1ZXMuc2l6ZSgpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmFtZXNBbmRWYWx1ZXMuZ2V0KHZhbHVlSW5kZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxhc3QgdmFsdWUgY29ycmVzcG9uZGluZyB0byB0aGUgc3BlY2lmaWVkIGZpZWxkLCBvciBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0KFN0cmluZyBmaWVsZE5hbWUpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IG5hbWVzQW5kVmFsdWVzLnNpemUoKSAtIDI7IGkgPj0gMDsgaSAtPSAyKSB7CisgICAgICAgICAgICBpZiAoZmllbGROYW1lLmVxdWFsc0lnbm9yZUNhc2UobmFtZXNBbmRWYWx1ZXMuZ2V0KGkpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuYW1lc0FuZFZhbHVlcy5nZXQoaSArIDEpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBmaWVsZE5hbWVzIGEgY2FzZS1pbnNlbnNpdGl2ZSBzZXQgb2YgSFRUUCBoZWFkZXIgZmllbGQgbmFtZXMuCisgICAgICovCisgICAgcHVibGljIFJhd0hlYWRlcnMgZ2V0QWxsKFNldDxTdHJpbmc+IGZpZWxkTmFtZXMpIHsKKyAgICAgICAgUmF3SGVhZGVycyByZXN1bHQgPSBuZXcgUmF3SGVhZGVycygpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5hbWVzQW5kVmFsdWVzLnNpemUoKTsgaSArPSAyKSB7CisgICAgICAgICAgICBTdHJpbmcgZmllbGROYW1lID0gbmFtZXNBbmRWYWx1ZXMuZ2V0KGkpOworICAgICAgICAgICAgaWYgKGZpZWxkTmFtZXMuY29udGFpbnMoZmllbGROYW1lKSkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQoZmllbGROYW1lLCBuYW1lc0FuZFZhbHVlcy5nZXQoaSArIDEpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgdG9IZWFkZXJTdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoMjU2KTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZChzdGF0dXNMaW5lKS5hcHBlbmQoIlxyXG4iKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuYW1lc0FuZFZhbHVlcy5zaXplKCk7IGkgKz0gMikgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChuYW1lc0FuZFZhbHVlcy5nZXQoaSkpLmFwcGVuZCgiOiAiKQorICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKG5hbWVzQW5kVmFsdWVzLmdldChpICsgMSkpLmFwcGVuZCgiXHJcbiIpOworICAgICAgICB9CisgICAgICAgIHJlc3VsdC5hcHBlbmQoIlxyXG4iKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaW1tdXRhYmxlIG1hcCBjb250YWluaW5nIGVhY2ggZmllbGQgdG8gaXRzIGxpc3Qgb2YgdmFsdWVzLiBUaGUKKyAgICAgKiBzdGF0dXMgbGluZSBpcyBtYXBwZWQgdG8gbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PiB0b011bHRpbWFwKCkgeworICAgICAgICBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IHJlc3VsdCA9IG5ldyBUcmVlTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PihGSUVMRF9OQU1FX0NPTVBBUkFUT1IpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5hbWVzQW5kVmFsdWVzLnNpemUoKTsgaSArPSAyKSB7CisgICAgICAgICAgICBTdHJpbmcgZmllbGROYW1lID0gbmFtZXNBbmRWYWx1ZXMuZ2V0KGkpOworICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gbmFtZXNBbmRWYWx1ZXMuZ2V0KGkgKyAxKTsKKworICAgICAgICAgICAgTGlzdDxTdHJpbmc+IGFsbFZhbHVlcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICAgICAgTGlzdDxTdHJpbmc+IG90aGVyVmFsdWVzID0gcmVzdWx0LmdldChmaWVsZE5hbWUpOworICAgICAgICAgICAgaWYgKG90aGVyVmFsdWVzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhbGxWYWx1ZXMuYWRkQWxsKG90aGVyVmFsdWVzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFsbFZhbHVlcy5hZGQodmFsdWUpOworICAgICAgICAgICAgcmVzdWx0LnB1dChmaWVsZE5hbWUsIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoYWxsVmFsdWVzKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHN0YXR1c0xpbmUgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0LnB1dChudWxsLCBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KENvbGxlY3Rpb25zLnNpbmdsZXRvbkxpc3Qoc3RhdHVzTGluZSkpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKHJlc3VsdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBmcm9tIHRoZSBnaXZlbiBtYXAgb2YgZmllbGRzIHRvIHZhbHVlcy4gSWYKKyAgICAgKiBwcmVzZW50LCB0aGUgbnVsbCBmaWVsZCdzIGxhc3QgZWxlbWVudCB3aWxsIGJlIHVzZWQgdG8gc2V0IHRoZSBzdGF0dXMKKyAgICAgKiBsaW5lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUmF3SGVhZGVycyBmcm9tTXVsdGltYXAoTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PiBtYXApIHsKKyAgICAgICAgUmF3SGVhZGVycyByZXN1bHQgPSBuZXcgUmF3SGVhZGVycygpOworICAgICAgICBmb3IgKEVudHJ5PFN0cmluZywgTGlzdDxTdHJpbmc+PiBlbnRyeSA6IG1hcC5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICBTdHJpbmcgZmllbGROYW1lID0gZW50cnkuZ2V0S2V5KCk7CisgICAgICAgICAgICBMaXN0PFN0cmluZz4gdmFsdWVzID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgIGlmIChmaWVsZE5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hZGRBbGwoZmllbGROYW1lLCB2YWx1ZXMpOworICAgICAgICAgICAgfSBlbHNlIGlmICghdmFsdWVzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5zZXRTdGF0dXNMaW5lKHZhbHVlcy5nZXQodmFsdWVzLnNpemUoKSAtIDEpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL1JlcXVlc3RIZWFkZXJzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9SZXF1ZXN0SGVhZGVycy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNiNTM2Y2UKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9SZXF1ZXN0SGVhZGVycy5qYXZhCkBAIC0wLDAgKzEsMjkyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLm5ldC5odHRwOworCitpbXBvcnQgamF2YS5uZXQuVVJJOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogUGFyc2VkIEhUVFAgcmVxdWVzdCBoZWFkZXJzLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUmVxdWVzdEhlYWRlcnMgeworICAgIHByaXZhdGUgZmluYWwgVVJJIHVyaTsKKyAgICBwcml2YXRlIGZpbmFsIFJhd0hlYWRlcnMgaGVhZGVyczsKKworICAgIC8qKiBEb24ndCB1c2UgYSBjYWNoZSB0byBzYXRpc2Z5IHRoaXMgcmVxdWVzdC4gKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gbm9DYWNoZTsKKyAgICBwcml2YXRlIGludCBtYXhBZ2VTZWNvbmRzID0gLTE7CisgICAgcHJpdmF0ZSBpbnQgbWF4U3RhbGVTZWNvbmRzID0gLTE7CisgICAgcHJpdmF0ZSBpbnQgbWluRnJlc2hTZWNvbmRzID0gLTE7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGZpZWxkJ3MgbmFtZSAib25seS1pZi1jYWNoZWQiIGlzIG1pc2xlYWRpbmcuIEl0IGFjdHVhbGx5IG1lYW5zICJkbworICAgICAqIG5vdCB1c2UgdGhlIG5ldHdvcmsiLiBJdCBpcyBzZXQgYnkgYSBjbGllbnQgd2hvIG9ubHkgd2FudHMgdG8gbWFrZSBhCisgICAgICogcmVxdWVzdCBpZiBpdCBjYW4gYmUgZnVsbHkgc2F0aXNmaWVkIGJ5IHRoZSBjYWNoZS4gQ2FjaGVkIHJlc3BvbnNlcyB0aGF0CisgICAgICogd291bGQgcmVxdWlyZSB2YWxpZGF0aW9uIChpZS4gY29uZGl0aW9uYWwgZ2V0cykgYXJlIG5vdCBwZXJtaXR0ZWQgaWYgdGhpcworICAgICAqIGhlYWRlciBpcyBzZXQuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIG9ubHlJZkNhY2hlZDsKKworICAgIC8qKgorICAgICAqIFRydWUgaWYgdGhlIHJlcXVlc3QgY29udGFpbnMgYW4gYXV0aG9yaXphdGlvbiBmaWVsZC4gQWx0aG91Z2ggdGhpcyBpc24ndAorICAgICAqIG5lY2Vzc2FyaWx5IGEgc2hhcmVkIGNhY2hlLCBpdCBmb2xsb3dzIHRoZSBzcGVjJ3Mgc3RyaWN0IHJlcXVpcmVtZW50cyBmb3IKKyAgICAgKiBzaGFyZWQgY2FjaGVzLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBoYXNBdXRob3JpemF0aW9uOworCisgICAgcHJpdmF0ZSBpbnQgY29udGVudExlbmd0aCA9IC0xOworICAgIHByaXZhdGUgU3RyaW5nIHRyYW5zZmVyRW5jb2Rpbmc7CisgICAgcHJpdmF0ZSBTdHJpbmcgdXNlckFnZW50OworICAgIHByaXZhdGUgU3RyaW5nIGhvc3Q7CisgICAgcHJpdmF0ZSBTdHJpbmcgY29ubmVjdGlvbjsKKyAgICBwcml2YXRlIFN0cmluZyBhY2NlcHRFbmNvZGluZzsKKyAgICBwcml2YXRlIFN0cmluZyBjb250ZW50VHlwZTsKKyAgICBwcml2YXRlIFN0cmluZyBpZk1vZGlmaWVkU2luY2U7CisgICAgcHJpdmF0ZSBTdHJpbmcgaWZOb25lTWF0Y2g7CisgICAgcHJpdmF0ZSBTdHJpbmcgcHJveHlBdXRob3JpemF0aW9uOworCisgICAgcHVibGljIFJlcXVlc3RIZWFkZXJzKFVSSSB1cmksIFJhd0hlYWRlcnMgaGVhZGVycykgeworICAgICAgICB0aGlzLnVyaSA9IHVyaTsKKyAgICAgICAgdGhpcy5oZWFkZXJzID0gaGVhZGVyczsKKworICAgICAgICBIZWFkZXJQYXJzZXIuQ2FjaGVDb250cm9sSGFuZGxlciBoYW5kbGVyID0gbmV3IEhlYWRlclBhcnNlci5DYWNoZUNvbnRyb2xIYW5kbGVyKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGhhbmRsZShTdHJpbmcgZGlyZWN0aXZlLCBTdHJpbmcgcGFyYW1ldGVyKSB7CisgICAgICAgICAgICAgICAgaWYgKGRpcmVjdGl2ZS5lcXVhbHNJZ25vcmVDYXNlKCJuby1jYWNoZSIpKSB7CisgICAgICAgICAgICAgICAgICAgIG5vQ2FjaGUgPSB0cnVlOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aXZlLmVxdWFsc0lnbm9yZUNhc2UoIm1heC1hZ2UiKSkgeworICAgICAgICAgICAgICAgICAgICBtYXhBZ2VTZWNvbmRzID0gSGVhZGVyUGFyc2VyLnBhcnNlU2Vjb25kcyhwYXJhbWV0ZXIpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aXZlLmVxdWFsc0lnbm9yZUNhc2UoIm1heC1zdGFsZSIpKSB7CisgICAgICAgICAgICAgICAgICAgIG1heFN0YWxlU2Vjb25kcyA9IEhlYWRlclBhcnNlci5wYXJzZVNlY29uZHMocGFyYW1ldGVyKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRpcmVjdGl2ZS5lcXVhbHNJZ25vcmVDYXNlKCJtaW4tZnJlc2giKSkgeworICAgICAgICAgICAgICAgICAgICBtaW5GcmVzaFNlY29uZHMgPSBIZWFkZXJQYXJzZXIucGFyc2VTZWNvbmRzKHBhcmFtZXRlcik7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkaXJlY3RpdmUuZXF1YWxzSWdub3JlQ2FzZSgib25seS1pZi1jYWNoZWQiKSkgeworICAgICAgICAgICAgICAgICAgICBvbmx5SWZDYWNoZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGhlYWRlcnMubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIGZpZWxkTmFtZSA9IGhlYWRlcnMuZ2V0RmllbGROYW1lKGkpOworICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gaGVhZGVycy5nZXRWYWx1ZShpKTsKKyAgICAgICAgICAgIGlmICgiQ2FjaGUtQ29udHJvbCIuZXF1YWxzSWdub3JlQ2FzZShmaWVsZE5hbWUpKSB7CisgICAgICAgICAgICAgICAgSGVhZGVyUGFyc2VyLnBhcnNlQ2FjaGVDb250cm9sKHZhbHVlLCBoYW5kbGVyKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIlByYWdtYSIuZXF1YWxzSWdub3JlQ2FzZShmaWVsZE5hbWUpKSB7CisgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmVxdWFsc0lnbm9yZUNhc2UoIm5vLWNhY2hlIikpIHsKKyAgICAgICAgICAgICAgICAgICAgbm9DYWNoZSA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmICgiSWYtTm9uZS1NYXRjaCIuZXF1YWxzSWdub3JlQ2FzZShmaWVsZE5hbWUpKSB7CisgICAgICAgICAgICAgICAgaWZOb25lTWF0Y2ggPSB2YWx1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIklmLU1vZGlmaWVkLVNpbmNlIi5lcXVhbHNJZ25vcmVDYXNlKGZpZWxkTmFtZSkpIHsKKyAgICAgICAgICAgICAgICBpZk1vZGlmaWVkU2luY2UgPSB2YWx1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIkF1dGhvcml6YXRpb24iLmVxdWFsc0lnbm9yZUNhc2UoZmllbGROYW1lKSkgeworICAgICAgICAgICAgICAgIGhhc0F1dGhvcml6YXRpb24gPSB0cnVlOworICAgICAgICAgICAgfSBlbHNlIGlmICgiQ29udGVudC1MZW5ndGgiLmVxdWFsc0lnbm9yZUNhc2UoZmllbGROYW1lKSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRMZW5ndGggPSBJbnRlZ2VyLnBhcnNlSW50KHZhbHVlKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIlRyYW5zZmVyLUVuY29kaW5nIi5lcXVhbHNJZ25vcmVDYXNlKGZpZWxkTmFtZSkpIHsKKyAgICAgICAgICAgICAgICB0cmFuc2ZlckVuY29kaW5nID0gdmFsdWU7CisgICAgICAgICAgICB9IGVsc2UgaWYgKCJVc2VyLUFnZW50Ii5lcXVhbHNJZ25vcmVDYXNlKGZpZWxkTmFtZSkpIHsKKyAgICAgICAgICAgICAgICB1c2VyQWdlbnQgPSB2YWx1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIkhvc3QiLmVxdWFsc0lnbm9yZUNhc2UoZmllbGROYW1lKSkgeworICAgICAgICAgICAgICAgIGhvc3QgPSB2YWx1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIkNvbm5lY3Rpb24iLmVxdWFsc0lnbm9yZUNhc2UoZmllbGROYW1lKSkgeworICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSB2YWx1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIkFjY2VwdC1FbmNvZGluZyIuZXF1YWxzSWdub3JlQ2FzZShmaWVsZE5hbWUpKSB7CisgICAgICAgICAgICAgICAgYWNjZXB0RW5jb2RpbmcgPSB2YWx1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIkNvbnRlbnQtVHlwZSIuZXF1YWxzSWdub3JlQ2FzZShmaWVsZE5hbWUpKSB7CisgICAgICAgICAgICAgICAgY29udGVudFR5cGUgPSB2YWx1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIlByb3h5LUF1dGhvcml6YXRpb24iLmVxdWFsc0lnbm9yZUNhc2UoZmllbGROYW1lKSkgeworICAgICAgICAgICAgICAgIHByb3h5QXV0aG9yaXphdGlvbiA9IHZhbHVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNDaHVua2VkKCkgeworICAgICAgICByZXR1cm4gImNodW5rZWQiLmVxdWFsc0lnbm9yZUNhc2UodHJhbnNmZXJFbmNvZGluZyk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaGFzQ29ubmVjdGlvbkNsb3NlKCkgeworICAgICAgICByZXR1cm4gImNsb3NlIi5lcXVhbHNJZ25vcmVDYXNlKGNvbm5lY3Rpb24pOworICAgIH0KKworICAgIHB1YmxpYyBVUkkgZ2V0VXJpKCkgeworICAgICAgICByZXR1cm4gdXJpOworICAgIH0KKworICAgIHB1YmxpYyBSYXdIZWFkZXJzIGdldEhlYWRlcnMoKSB7CisgICAgICAgIHJldHVybiBoZWFkZXJzOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzTm9DYWNoZSgpIHsKKyAgICAgICAgcmV0dXJuIG5vQ2FjaGU7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRNYXhBZ2VTZWNvbmRzKCkgeworICAgICAgICByZXR1cm4gbWF4QWdlU2Vjb25kczsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldE1heFN0YWxlU2Vjb25kcygpIHsKKyAgICAgICAgcmV0dXJuIG1heFN0YWxlU2Vjb25kczsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldE1pbkZyZXNoU2Vjb25kcygpIHsKKyAgICAgICAgcmV0dXJuIG1pbkZyZXNoU2Vjb25kczsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc09ubHlJZkNhY2hlZCgpIHsKKyAgICAgICAgcmV0dXJuIG9ubHlJZkNhY2hlZDsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNBdXRob3JpemF0aW9uKCkgeworICAgICAgICByZXR1cm4gaGFzQXV0aG9yaXphdGlvbjsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldENvbnRlbnRMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBjb250ZW50TGVuZ3RoOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHJhbnNmZXJFbmNvZGluZygpIHsKKyAgICAgICAgcmV0dXJuIHRyYW5zZmVyRW5jb2Rpbmc7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRVc2VyQWdlbnQoKSB7CisgICAgICAgIHJldHVybiB1c2VyQWdlbnQ7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRIb3N0KCkgeworICAgICAgICByZXR1cm4gaG9zdDsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbm5lY3Rpb24oKSB7CisgICAgICAgIHJldHVybiBjb25uZWN0aW9uOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWNjZXB0RW5jb2RpbmcoKSB7CisgICAgICAgIHJldHVybiBhY2NlcHRFbmNvZGluZzsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgeworICAgICAgICByZXR1cm4gY29udGVudFR5cGU7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRJZk1vZGlmaWVkU2luY2UoKSB7CisgICAgICAgIHJldHVybiBpZk1vZGlmaWVkU2luY2U7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRJZk5vbmVNYXRjaCgpIHsKKyAgICAgICAgcmV0dXJuIGlmTm9uZU1hdGNoOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJveHlBdXRob3JpemF0aW9uKCkgeworICAgICAgICByZXR1cm4gcHJveHlBdXRob3JpemF0aW9uOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENodW5rZWQoKSB7CisgICAgICAgIGlmICh0aGlzLnRyYW5zZmVyRW5jb2RpbmcgIT0gbnVsbCkgeworICAgICAgICAgICAgaGVhZGVycy5yZW1vdmVBbGwoIlRyYW5zZmVyLUVuY29kaW5nIik7CisgICAgICAgIH0KKyAgICAgICAgaGVhZGVycy5hZGQoIlRyYW5zZmVyLUVuY29kaW5nIiwgImNodW5rZWQiKTsKKyAgICAgICAgdGhpcy50cmFuc2ZlckVuY29kaW5nID0gImNodW5rZWQiOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRMZW5ndGgoaW50IGNvbnRlbnRMZW5ndGgpIHsKKyAgICAgICAgaWYgKHRoaXMuY29udGVudExlbmd0aCAhPSAtMSkgeworICAgICAgICAgICAgaGVhZGVycy5yZW1vdmVBbGwoIkNvbnRlbnQtTGVuZ3RoIik7CisgICAgICAgIH0KKyAgICAgICAgaGVhZGVycy5hZGQoIkNvbnRlbnQtTGVuZ3RoIiwgSW50ZWdlci50b1N0cmluZyhjb250ZW50TGVuZ3RoKSk7CisgICAgICAgIHRoaXMuY29udGVudExlbmd0aCA9IGNvbnRlbnRMZW5ndGg7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VXNlckFnZW50KFN0cmluZyB1c2VyQWdlbnQpIHsKKyAgICAgICAgaWYgKHRoaXMudXNlckFnZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGhlYWRlcnMucmVtb3ZlQWxsKCJVc2VyLUFnZW50Iik7CisgICAgICAgIH0KKyAgICAgICAgaGVhZGVycy5hZGQoIlVzZXItQWdlbnQiLCB1c2VyQWdlbnQpOworICAgICAgICB0aGlzLnVzZXJBZ2VudCA9IHVzZXJBZ2VudDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRIb3N0KFN0cmluZyBob3N0KSB7CisgICAgICAgIGlmICh0aGlzLmhvc3QgIT0gbnVsbCkgeworICAgICAgICAgICAgaGVhZGVycy5yZW1vdmVBbGwoIkhvc3QiKTsKKyAgICAgICAgfQorICAgICAgICBoZWFkZXJzLmFkZCgiSG9zdCIsIGhvc3QpOworICAgICAgICB0aGlzLmhvc3QgPSBob3N0OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbm5lY3Rpb24oU3RyaW5nIGNvbm5lY3Rpb24pIHsKKyAgICAgICAgaWYgKHRoaXMuY29ubmVjdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICBoZWFkZXJzLnJlbW92ZUFsbCgiQ29ubmVjdGlvbiIpOworICAgICAgICB9CisgICAgICAgIGhlYWRlcnMuYWRkKCJDb25uZWN0aW9uIiwgY29ubmVjdGlvbik7CisgICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0QWNjZXB0RW5jb2RpbmcoU3RyaW5nIGFjY2VwdEVuY29kaW5nKSB7CisgICAgICAgIGlmICh0aGlzLmFjY2VwdEVuY29kaW5nICE9IG51bGwpIHsKKyAgICAgICAgICAgIGhlYWRlcnMucmVtb3ZlQWxsKCJBY2NlcHQtRW5jb2RpbmciKTsKKyAgICAgICAgfQorICAgICAgICBoZWFkZXJzLmFkZCgiQWNjZXB0LUVuY29kaW5nIiwgYWNjZXB0RW5jb2RpbmcpOworICAgICAgICB0aGlzLmFjY2VwdEVuY29kaW5nID0gYWNjZXB0RW5jb2Rpbmc7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q29udGVudFR5cGUoU3RyaW5nIGNvbnRlbnRUeXBlKSB7CisgICAgICAgIGlmICh0aGlzLmNvbnRlbnRUeXBlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGhlYWRlcnMucmVtb3ZlQWxsKCJDb250ZW50LVR5cGUiKTsKKyAgICAgICAgfQorICAgICAgICBoZWFkZXJzLmFkZCgiQ29udGVudC1UeXBlIiwgY29udGVudFR5cGUpOworICAgICAgICB0aGlzLmNvbnRlbnRUeXBlID0gY29udGVudFR5cGU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SWZNb2RpZmllZFNpbmNlKERhdGUgZGF0ZSkgeworICAgICAgICBpZiAoaWZNb2RpZmllZFNpbmNlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGhlYWRlcnMucmVtb3ZlQWxsKCJJZi1Nb2RpZmllZC1TaW5jZSIpOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBmb3JtYXR0ZWREYXRlID0gSHR0cERhdGUuZm9ybWF0KGRhdGUpOworICAgICAgICBoZWFkZXJzLmFkZCgiSWYtTW9kaWZpZWQtU2luY2UiLCBmb3JtYXR0ZWREYXRlKTsKKyAgICAgICAgaWZNb2RpZmllZFNpbmNlID0gZm9ybWF0dGVkRGF0ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJZk5vbmVNYXRjaChTdHJpbmcgaWZOb25lTWF0Y2gpIHsKKyAgICAgICAgaWYgKHRoaXMuaWZOb25lTWF0Y2ggIT0gbnVsbCkgeworICAgICAgICAgICAgaGVhZGVycy5yZW1vdmVBbGwoIklmLU5vbmUtTWF0Y2giKTsKKyAgICAgICAgfQorICAgICAgICBoZWFkZXJzLmFkZCgiSWYtTm9uZS1NYXRjaCIsIGlmTm9uZU1hdGNoKTsKKyAgICAgICAgdGhpcy5pZk5vbmVNYXRjaCA9IGlmTm9uZU1hdGNoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgcmVxdWVzdCBjb250YWlucyBjb25kaXRpb25zIHRoYXQgc2F2ZSB0aGUgc2VydmVyIGZyb20KKyAgICAgKiBzZW5kaW5nIGEgcmVzcG9uc2UgdGhhdCB0aGUgY2xpZW50IGhhcyBsb2NhbGx5LiBXaGVuIHRoZSBjYWxsZXIgYWRkcworICAgICAqIGNvbmRpdGlvbnMsIHRoaXMgY2FjaGUgd29uJ3QgcGFydGljaXBhdGUgaW4gdGhlIHJlcXVlc3QuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzQ29uZGl0aW9ucygpIHsKKyAgICAgICAgcmV0dXJuIGlmTW9kaWZpZWRTaW5jZSAhPSBudWxsIHx8IGlmTm9uZU1hdGNoICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYWRkQ29va2llcyhNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IGFsbENvb2tpZUhlYWRlcnMpIHsKKyAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBMaXN0PFN0cmluZz4+IGVudHJ5IDogYWxsQ29va2llSGVhZGVycy5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICBTdHJpbmcga2V5ID0gZW50cnkuZ2V0S2V5KCk7CisgICAgICAgICAgICBpZiAoIkNvb2tpZSIuZXF1YWxzSWdub3JlQ2FzZShrZXkpIHx8ICJDb29raWUyIi5lcXVhbHNJZ25vcmVDYXNlKGtleSkpIHsKKyAgICAgICAgICAgICAgICBoZWFkZXJzLmFkZEFsbChrZXksIGVudHJ5LmdldFZhbHVlKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvUmVzcG9uc2VIZWFkZXJzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9SZXNwb25zZUhlYWRlcnMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZDhjYzQwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvUmVzcG9uc2VIZWFkZXJzLmphdmEKQEAgLTAsMCArMSw1MTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUubmV0Lmh0dHA7CisKK2ltcG9ydCBqYXZhLm5ldC5IdHRwVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkk7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZVNldDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdDsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuT2JqZWN0czsKKworLyoqCisgKiBQYXJzZWQgSFRUUCByZXNwb25zZSBoZWFkZXJzLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUmVzcG9uc2VIZWFkZXJzIHsKKworICAgIC8qKiBIVFRQIGhlYWRlciBuYW1lIGZvciB0aGUgbG9jYWwgdGltZSB3aGVuIHRoZSByZXF1ZXN0IHdhcyBzZW50LiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRU5UX01JTExJUyA9ICJYLUFuZHJvaWQtU2VudC1NaWxsaXMiOworCisgICAgLyoqIEhUVFAgaGVhZGVyIG5hbWUgZm9yIHRoZSBsb2NhbCB0aW1lIHdoZW4gdGhlIHJlc3BvbnNlIHdhcyByZWNlaXZlZC4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVDRUlWRURfTUlMTElTID0gIlgtQW5kcm9pZC1SZWNlaXZlZC1NaWxsaXMiOworCisgICAgcHJpdmF0ZSBmaW5hbCBVUkkgdXJpOworICAgIHByaXZhdGUgZmluYWwgUmF3SGVhZGVycyBoZWFkZXJzOworCisgICAgLyoqIFRoZSBzZXJ2ZXIncyB0aW1lIHdoZW4gdGhpcyByZXNwb25zZSB3YXMgc2VydmVkLCBpZiBrbm93bi4gKi8KKyAgICBwcml2YXRlIERhdGUgc2VydmVkRGF0ZTsKKworICAgIC8qKiBUaGUgbGFzdCBtb2RpZmllZCBkYXRlIG9mIHRoZSByZXNwb25zZSwgaWYga25vd24uICovCisgICAgcHJpdmF0ZSBEYXRlIGxhc3RNb2RpZmllZDsKKworICAgIC8qKgorICAgICAqIFRoZSBleHBpcmF0aW9uIGRhdGUgb2YgdGhlIHJlc3BvbnNlLCBpZiBrbm93bi4gSWYgYm90aCB0aGlzIGZpZWxkIGFuZCB0aGUKKyAgICAgKiBtYXggYWdlIGFyZSBzZXQsIHRoZSBtYXggYWdlIGlzIHByZWZlcnJlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIERhdGUgZXhwaXJlczsKKworICAgIC8qKgorICAgICAqIEV4dGVuc2lvbiBoZWFkZXIgc2V0IGJ5IEh0dHBVUkxDb25uZWN0aW9uSW1wbCBzcGVjaWZ5aW5nIHRoZSB0aW1lc3RhbXAKKyAgICAgKiB3aGVuIHRoZSBIVFRQIHJlcXVlc3Qgd2FzIGZpcnN0IGluaXRpYXRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGxvbmcgc2VudFJlcXVlc3RNaWxsaXM7CisKKyAgICAvKioKKyAgICAgKiBFeHRlbnNpb24gaGVhZGVyIHNldCBieSBIdHRwVVJMQ29ubmVjdGlvbkltcGwgc3BlY2lmeWluZyB0aGUgdGltZXN0YW1wCisgICAgICogd2hlbiB0aGUgSFRUUCByZXNwb25zZSB3YXMgZmlyc3QgcmVjZWl2ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBsb25nIHJlY2VpdmVkUmVzcG9uc2VNaWxsaXM7CisKKyAgICAvKioKKyAgICAgKiBJbiB0aGUgcmVzcG9uc2UsIHRoaXMgZmllbGQncyBuYW1lICJuby1jYWNoZSIgaXMgbWlzbGVhZGluZy4gSXQgZG9lc24ndAorICAgICAqIHByZXZlbnQgdXMgZnJvbSBjYWNoaW5nIHRoZSByZXNwb25zZTsgaXQgb25seSBtZWFucyB3ZSBoYXZlIHRvIHZhbGlkYXRlCisgICAgICogdGhlIHJlc3BvbnNlIHdpdGggdGhlIG9yaWdpbiBzZXJ2ZXIgYmVmb3JlIHJldHVybmluZyBpdC4gV2UgY2FuIGRvIHRoaXMKKyAgICAgKiB3aXRoIGEgY29uZGl0aW9uYWwgZ2V0LgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBub0NhY2hlOworCisgICAgLyoqIElmIHRydWUsIHRoaXMgcmVzcG9uc2Ugc2hvdWxkIG5vdCBiZSBjYWNoZWQuICovCisgICAgcHJpdmF0ZSBib29sZWFuIG5vU3RvcmU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZHVyYXRpb24gcGFzdCB0aGUgcmVzcG9uc2UncyBzZXJ2ZWQgZGF0ZSB0aGF0IGl0IGNhbiBiZSBzZXJ2ZWQKKyAgICAgKiB3aXRob3V0IHZhbGlkYXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbWF4QWdlU2Vjb25kcyA9IC0xOworCisgICAgLyoqCisgICAgICogVGhlICJzLW1heGFnZSIgZGlyZWN0aXZlIGlzIHRoZSBtYXggYWdlIGZvciBzaGFyZWQgY2FjaGVzLiBOb3QgdG8gYmUKKyAgICAgKiBjb25mdXNlZCB3aXRoICJtYXgtYWdlIiBmb3Igbm9uLXNoYXJlZCBjYWNoZXMsIEFzIGluIEZpcmVmb3ggYW5kIENocm9tZSwKKyAgICAgKiB0aGlzIGRpcmVjdGl2ZSBpcyBub3QgaG9ub3JlZCBieSB0aGlzIGNhY2hlLgorICAgICAqLworICAgIHByaXZhdGUgaW50IHNNYXhBZ2VTZWNvbmRzID0gLTE7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIHJlcXVlc3QgaGVhZGVyIGZpZWxkJ3MgbmFtZSAib25seS1pZi1jYWNoZWQiIGlzIG1pc2xlYWRpbmcuIEl0CisgICAgICogYWN0dWFsbHkgbWVhbnMgImRvIG5vdCB1c2UgdGhlIG5ldHdvcmsiLiBJdCBpcyBzZXQgYnkgYSBjbGllbnQgd2hvIG9ubHkKKyAgICAgKiB3YW50cyB0byBtYWtlIGEgcmVxdWVzdCBpZiBpdCBjYW4gYmUgZnVsbHkgc2F0aXNmaWVkIGJ5IHRoZSBjYWNoZS4KKyAgICAgKiBDYWNoZWQgcmVzcG9uc2VzIHRoYXQgd291bGQgcmVxdWlyZSB2YWxpZGF0aW9uIChpZS4gY29uZGl0aW9uYWwgZ2V0cykgYXJlCisgICAgICogbm90IHBlcm1pdHRlZCBpZiB0aGlzIGhlYWRlciBpcyBzZXQuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGlzUHVibGljOworICAgIHByaXZhdGUgYm9vbGVhbiBtdXN0UmV2YWxpZGF0ZTsKKyAgICBwcml2YXRlIFN0cmluZyBldGFnOworICAgIHByaXZhdGUgaW50IGFnZVNlY29uZHMgPSAtMTsKKworICAgIC8qKiBDYXNlLWluc2Vuc2l0aXZlIHNldCBvZiBmaWVsZCBuYW1lcy4gKi8KKyAgICBwcml2YXRlIFNldDxTdHJpbmc+IHZhcnlGaWVsZHMgPSBDb2xsZWN0aW9ucy5lbXB0eVNldCgpOworCisgICAgcHJpdmF0ZSBTdHJpbmcgY29udGVudEVuY29kaW5nOworICAgIHByaXZhdGUgU3RyaW5nIHRyYW5zZmVyRW5jb2Rpbmc7CisgICAgcHJpdmF0ZSBpbnQgY29udGVudExlbmd0aCA9IC0xOworICAgIHByaXZhdGUgU3RyaW5nIGNvbm5lY3Rpb247CisgICAgcHJpdmF0ZSBTdHJpbmcgcHJveHlBdXRoZW50aWNhdGU7CisgICAgcHJpdmF0ZSBTdHJpbmcgd3d3QXV0aGVudGljYXRlOworCisgICAgcHVibGljIFJlc3BvbnNlSGVhZGVycyhVUkkgdXJpLCBSYXdIZWFkZXJzIGhlYWRlcnMpIHsKKyAgICAgICAgdGhpcy51cmkgPSB1cmk7CisgICAgICAgIHRoaXMuaGVhZGVycyA9IGhlYWRlcnM7CisKKyAgICAgICAgSGVhZGVyUGFyc2VyLkNhY2hlQ29udHJvbEhhbmRsZXIgaGFuZGxlciA9IG5ldyBIZWFkZXJQYXJzZXIuQ2FjaGVDb250cm9sSGFuZGxlcigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBoYW5kbGUoU3RyaW5nIGRpcmVjdGl2ZSwgU3RyaW5nIHBhcmFtZXRlcikgeworICAgICAgICAgICAgICAgIGlmIChkaXJlY3RpdmUuZXF1YWxzSWdub3JlQ2FzZSgibm8tY2FjaGUiKSkgeworICAgICAgICAgICAgICAgICAgICBub0NhY2hlID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRpcmVjdGl2ZS5lcXVhbHNJZ25vcmVDYXNlKCJuby1zdG9yZSIpKSB7CisgICAgICAgICAgICAgICAgICAgIG5vU3RvcmUgPSB0cnVlOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aXZlLmVxdWFsc0lnbm9yZUNhc2UoIm1heC1hZ2UiKSkgeworICAgICAgICAgICAgICAgICAgICBtYXhBZ2VTZWNvbmRzID0gSGVhZGVyUGFyc2VyLnBhcnNlU2Vjb25kcyhwYXJhbWV0ZXIpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aXZlLmVxdWFsc0lnbm9yZUNhc2UoInMtbWF4YWdlIikpIHsKKyAgICAgICAgICAgICAgICAgICAgc01heEFnZVNlY29uZHMgPSBIZWFkZXJQYXJzZXIucGFyc2VTZWNvbmRzKHBhcmFtZXRlcik7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkaXJlY3RpdmUuZXF1YWxzSWdub3JlQ2FzZSgicHVibGljIikpIHsKKyAgICAgICAgICAgICAgICAgICAgaXNQdWJsaWMgPSB0cnVlOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aXZlLmVxdWFsc0lnbm9yZUNhc2UoIm11c3QtcmV2YWxpZGF0ZSIpKSB7CisgICAgICAgICAgICAgICAgICAgIG11c3RSZXZhbGlkYXRlID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBoZWFkZXJzLmxlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgICAgIFN0cmluZyBmaWVsZE5hbWUgPSBoZWFkZXJzLmdldEZpZWxkTmFtZShpKTsKKyAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IGhlYWRlcnMuZ2V0VmFsdWUoaSk7CisgICAgICAgICAgICBpZiAoIkNhY2hlLUNvbnRyb2wiLmVxdWFsc0lnbm9yZUNhc2UoZmllbGROYW1lKSkgeworICAgICAgICAgICAgICAgIEhlYWRlclBhcnNlci5wYXJzZUNhY2hlQ29udHJvbCh2YWx1ZSwgaGFuZGxlcik7CisgICAgICAgICAgICB9IGVsc2UgaWYgKCJEYXRlIi5lcXVhbHNJZ25vcmVDYXNlKGZpZWxkTmFtZSkpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZWREYXRlID0gSHR0cERhdGUucGFyc2UodmFsdWUpOworICAgICAgICAgICAgfSBlbHNlIGlmICgiRXhwaXJlcyIuZXF1YWxzSWdub3JlQ2FzZShmaWVsZE5hbWUpKSB7CisgICAgICAgICAgICAgICAgZXhwaXJlcyA9IEh0dHBEYXRlLnBhcnNlKHZhbHVlKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIkxhc3QtTW9kaWZpZWQiLmVxdWFsc0lnbm9yZUNhc2UoZmllbGROYW1lKSkgeworICAgICAgICAgICAgICAgIGxhc3RNb2RpZmllZCA9IEh0dHBEYXRlLnBhcnNlKHZhbHVlKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIkVUYWciLmVxdWFsc0lnbm9yZUNhc2UoZmllbGROYW1lKSkgeworICAgICAgICAgICAgICAgIGV0YWcgPSB2YWx1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIlByYWdtYSIuZXF1YWxzSWdub3JlQ2FzZShmaWVsZE5hbWUpKSB7CisgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmVxdWFsc0lnbm9yZUNhc2UoIm5vLWNhY2hlIikpIHsKKyAgICAgICAgICAgICAgICAgICAgbm9DYWNoZSA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmICgiQWdlIi5lcXVhbHNJZ25vcmVDYXNlKGZpZWxkTmFtZSkpIHsKKyAgICAgICAgICAgICAgICBhZ2VTZWNvbmRzID0gSGVhZGVyUGFyc2VyLnBhcnNlU2Vjb25kcyh2YWx1ZSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKCJWYXJ5Ii5lcXVhbHNJZ25vcmVDYXNlKGZpZWxkTmFtZSkpIHsKKyAgICAgICAgICAgICAgICAvLyBSZXBsYWNlIHRoZSBpbW11dGFibGUgZW1wdHkgc2V0IHdpdGggc29tZXRoaW5nIHdlIGNhbiBtdXRhdGUuCisgICAgICAgICAgICAgICAgaWYgKHZhcnlGaWVsZHMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgICAgIHZhcnlGaWVsZHMgPSBuZXcgVHJlZVNldDxTdHJpbmc+KFN0cmluZy5DQVNFX0lOU0VOU0lUSVZFX09SREVSKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZm9yIChTdHJpbmcgdmFyeUZpZWxkIDogdmFsdWUuc3BsaXQoIiwiKSkgeworICAgICAgICAgICAgICAgICAgICB2YXJ5RmllbGRzLmFkZCh2YXJ5RmllbGQudHJpbSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKCJDb250ZW50LUVuY29kaW5nIi5lcXVhbHNJZ25vcmVDYXNlKGZpZWxkTmFtZSkpIHsKKyAgICAgICAgICAgICAgICBjb250ZW50RW5jb2RpbmcgPSB2YWx1ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIlRyYW5zZmVyLUVuY29kaW5nIi5lcXVhbHNJZ25vcmVDYXNlKGZpZWxkTmFtZSkpIHsKKyAgICAgICAgICAgICAgICB0cmFuc2ZlckVuY29kaW5nID0gdmFsdWU7CisgICAgICAgICAgICB9IGVsc2UgaWYgKCJDb250ZW50LUxlbmd0aCIuZXF1YWxzSWdub3JlQ2FzZShmaWVsZE5hbWUpKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgY29udGVudExlbmd0aCA9IEludGVnZXIucGFyc2VJbnQodmFsdWUpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmICgiQ29ubmVjdGlvbiIuZXF1YWxzSWdub3JlQ2FzZShmaWVsZE5hbWUpKSB7CisgICAgICAgICAgICAgICAgY29ubmVjdGlvbiA9IHZhbHVlOworICAgICAgICAgICAgfSBlbHNlIGlmICgiUHJveHktQXV0aGVudGljYXRlIi5lcXVhbHNJZ25vcmVDYXNlKGZpZWxkTmFtZSkpIHsKKyAgICAgICAgICAgICAgICBwcm94eUF1dGhlbnRpY2F0ZSA9IHZhbHVlOworICAgICAgICAgICAgfSBlbHNlIGlmICgiV1dXLUF1dGhlbnRpY2F0ZSIuZXF1YWxzSWdub3JlQ2FzZShmaWVsZE5hbWUpKSB7CisgICAgICAgICAgICAgICAgd3d3QXV0aGVudGljYXRlID0gdmFsdWU7CisgICAgICAgICAgICB9IGVsc2UgaWYgKFNFTlRfTUlMTElTLmVxdWFsc0lnbm9yZUNhc2UoZmllbGROYW1lKSkgeworICAgICAgICAgICAgICAgIHNlbnRSZXF1ZXN0TWlsbGlzID0gTG9uZy5wYXJzZUxvbmcodmFsdWUpOworICAgICAgICAgICAgfSBlbHNlIGlmIChSRUNFSVZFRF9NSUxMSVMuZXF1YWxzSWdub3JlQ2FzZShmaWVsZE5hbWUpKSB7CisgICAgICAgICAgICAgICAgcmVjZWl2ZWRSZXNwb25zZU1pbGxpcyA9IExvbmcucGFyc2VMb25nKHZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzQ29udGVudEVuY29kaW5nR3ppcCgpIHsKKyAgICAgICAgcmV0dXJuICJnemlwIi5lcXVhbHNJZ25vcmVDYXNlKGNvbnRlbnRFbmNvZGluZyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc3RyaXBDb250ZW50RW5jb2RpbmcoKSB7CisgICAgICAgIGNvbnRlbnRFbmNvZGluZyA9IG51bGw7CisgICAgICAgIGhlYWRlcnMucmVtb3ZlQWxsKCJDb250ZW50LUVuY29kaW5nIik7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNDaHVua2VkKCkgeworICAgICAgICByZXR1cm4gImNodW5rZWQiLmVxdWFsc0lnbm9yZUNhc2UodHJhbnNmZXJFbmNvZGluZyk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaGFzQ29ubmVjdGlvbkNsb3NlKCkgeworICAgICAgICByZXR1cm4gImNsb3NlIi5lcXVhbHNJZ25vcmVDYXNlKGNvbm5lY3Rpb24pOworICAgIH0KKworICAgIHB1YmxpYyBVUkkgZ2V0VXJpKCkgeworICAgICAgICByZXR1cm4gdXJpOworICAgIH0KKworICAgIHB1YmxpYyBSYXdIZWFkZXJzIGdldEhlYWRlcnMoKSB7CisgICAgICAgIHJldHVybiBoZWFkZXJzOworICAgIH0KKworICAgIHB1YmxpYyBEYXRlIGdldFNlcnZlZERhdGUoKSB7CisgICAgICAgIHJldHVybiBzZXJ2ZWREYXRlOworICAgIH0KKworICAgIHB1YmxpYyBEYXRlIGdldExhc3RNb2RpZmllZCgpIHsKKyAgICAgICAgcmV0dXJuIGxhc3RNb2RpZmllZDsKKyAgICB9CisKKyAgICBwdWJsaWMgRGF0ZSBnZXRFeHBpcmVzKCkgeworICAgICAgICByZXR1cm4gZXhwaXJlczsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc05vQ2FjaGUoKSB7CisgICAgICAgIHJldHVybiBub0NhY2hlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzTm9TdG9yZSgpIHsKKyAgICAgICAgcmV0dXJuIG5vU3RvcmU7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRNYXhBZ2VTZWNvbmRzKCkgeworICAgICAgICByZXR1cm4gbWF4QWdlU2Vjb25kczsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFNNYXhBZ2VTZWNvbmRzKCkgeworICAgICAgICByZXR1cm4gc01heEFnZVNlY29uZHM7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNQdWJsaWMoKSB7CisgICAgICAgIHJldHVybiBpc1B1YmxpYzsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc011c3RSZXZhbGlkYXRlKCkgeworICAgICAgICByZXR1cm4gbXVzdFJldmFsaWRhdGU7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRFdGFnKCkgeworICAgICAgICByZXR1cm4gZXRhZzsKKyAgICB9CisKKyAgICBwdWJsaWMgU2V0PFN0cmluZz4gZ2V0VmFyeUZpZWxkcygpIHsKKyAgICAgICAgcmV0dXJuIHZhcnlGaWVsZHM7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRDb250ZW50RW5jb2RpbmcoKSB7CisgICAgICAgIHJldHVybiBjb250ZW50RW5jb2Rpbmc7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRDb250ZW50TGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gY29udGVudExlbmd0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbm5lY3Rpb24oKSB7CisgICAgICAgIHJldHVybiBjb25uZWN0aW9uOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJveHlBdXRoZW50aWNhdGUoKSB7CisgICAgICAgIHJldHVybiBwcm94eUF1dGhlbnRpY2F0ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFd3d0F1dGhlbnRpY2F0ZSgpIHsKKyAgICAgICAgcmV0dXJuIHd3d0F1dGhlbnRpY2F0ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRMb2NhbFRpbWVzdGFtcHMobG9uZyBzZW50UmVxdWVzdE1pbGxpcywgbG9uZyByZWNlaXZlZFJlc3BvbnNlTWlsbGlzKSB7CisgICAgICAgIHRoaXMuc2VudFJlcXVlc3RNaWxsaXMgPSBzZW50UmVxdWVzdE1pbGxpczsKKyAgICAgICAgaGVhZGVycy5hZGQoU0VOVF9NSUxMSVMsIExvbmcudG9TdHJpbmcoc2VudFJlcXVlc3RNaWxsaXMpKTsKKyAgICAgICAgdGhpcy5yZWNlaXZlZFJlc3BvbnNlTWlsbGlzID0gcmVjZWl2ZWRSZXNwb25zZU1pbGxpczsKKyAgICAgICAgaGVhZGVycy5hZGQoUkVDRUlWRURfTUlMTElTLCBMb25nLnRvU3RyaW5nKHJlY2VpdmVkUmVzcG9uc2VNaWxsaXMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGFnZSBvZiB0aGUgcmVzcG9uc2UsIGluIG1pbGxpc2Vjb25kcy4gVGhlIGNhbGN1bGF0aW9uCisgICAgICogaXMgc3BlY2lmaWVkIGJ5IFJGQyAyNjE2LCAxMy4yLjMgQWdlIENhbGN1bGF0aW9ucy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGxvbmcgY29tcHV0ZUFnZShsb25nIG5vd01pbGxpcykgeworICAgICAgICBsb25nIGFwcGFyZW50UmVjZWl2ZWRBZ2UgPSBzZXJ2ZWREYXRlICE9IG51bGwKKyAgICAgICAgICAgICAgICA/IE1hdGgubWF4KDAsIHJlY2VpdmVkUmVzcG9uc2VNaWxsaXMgLSBzZXJ2ZWREYXRlLmdldFRpbWUoKSkKKyAgICAgICAgICAgICAgICA6IDA7CisgICAgICAgIGxvbmcgcmVjZWl2ZWRBZ2UgPSBhZ2VTZWNvbmRzICE9IC0xCisgICAgICAgICAgICAgICAgPyBNYXRoLm1heChhcHBhcmVudFJlY2VpdmVkQWdlLCBUaW1lVW5pdC5TRUNPTkRTLnRvTWlsbGlzKGFnZVNlY29uZHMpKQorICAgICAgICAgICAgICAgIDogYXBwYXJlbnRSZWNlaXZlZEFnZTsKKyAgICAgICAgbG9uZyByZXNwb25zZUR1cmF0aW9uID0gcmVjZWl2ZWRSZXNwb25zZU1pbGxpcyAtIHNlbnRSZXF1ZXN0TWlsbGlzOworICAgICAgICBsb25nIHJlc2lkZW50RHVyYXRpb24gPSBub3dNaWxsaXMgLSByZWNlaXZlZFJlc3BvbnNlTWlsbGlzOworICAgICAgICByZXR1cm4gcmVjZWl2ZWRBZ2UgKyByZXNwb25zZUR1cmF0aW9uICsgcmVzaWRlbnREdXJhdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRoYXQgdGhlIHJlc3BvbnNlIHdhcyBmcmVzaCBmb3IsCisgICAgICogc3RhcnRpbmcgZnJvbSB0aGUgc2VydmVkIGRhdGUuCisgICAgICovCisgICAgcHJpdmF0ZSBsb25nIGNvbXB1dGVGcmVzaG5lc3NMaWZldGltZSgpIHsKKyAgICAgICAgaWYgKG1heEFnZVNlY29uZHMgIT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiBUaW1lVW5pdC5TRUNPTkRTLnRvTWlsbGlzKG1heEFnZVNlY29uZHMpOworICAgICAgICB9IGVsc2UgaWYgKGV4cGlyZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgbG9uZyBzZXJ2ZWRNaWxsaXMgPSBzZXJ2ZWREYXRlICE9IG51bGwgPyBzZXJ2ZWREYXRlLmdldFRpbWUoKSA6IHJlY2VpdmVkUmVzcG9uc2VNaWxsaXM7CisgICAgICAgICAgICBsb25nIGRlbHRhID0gZXhwaXJlcy5nZXRUaW1lKCkgLSBzZXJ2ZWRNaWxsaXM7CisgICAgICAgICAgICByZXR1cm4gZGVsdGEgPiAwID8gZGVsdGEgOiAwOworICAgICAgICB9IGVsc2UgaWYgKGxhc3RNb2RpZmllZCAhPSBudWxsICYmIHVyaS5nZXRSYXdRdWVyeSgpID09IG51bGwpIHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBBcyByZWNvbW1lbmRlZCBieSB0aGUgSFRUUCBSRkMgYW5kIGltcGxlbWVudGVkIGluIEZpcmVmb3gsIHRoZQorICAgICAgICAgICAgICogbWF4IGFnZSBvZiBhIGRvY3VtZW50IHNob3VsZCBiZSBkZWZhdWx0ZWQgdG8gMTAlIG9mIHRoZQorICAgICAgICAgICAgICogZG9jdW1lbnQncyBhZ2UgYXQgdGhlIHRpbWUgaXQgd2FzIHNlcnZlZC4gRGVmYXVsdCBleHBpcmF0aW9uCisgICAgICAgICAgICAgKiBkYXRlcyBhcmVuJ3QgdXNlZCBmb3IgVVJJcyBjb250YWluaW5nIGEgcXVlcnkuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGxvbmcgc2VydmVkTWlsbGlzID0gc2VydmVkRGF0ZSAhPSBudWxsID8gc2VydmVkRGF0ZS5nZXRUaW1lKCkgOiBzZW50UmVxdWVzdE1pbGxpczsKKyAgICAgICAgICAgIGxvbmcgZGVsdGEgPSBzZXJ2ZWRNaWxsaXMgLSBsYXN0TW9kaWZpZWQuZ2V0VGltZSgpOworICAgICAgICAgICAgcmV0dXJuIGRlbHRhID4gMCA/IChkZWx0YSAvIDEwKSA6IDA7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIGNvbXB1dGVGcmVzaG5lc3NMaWZldGltZSB1c2VkIGEgaGV1cmlzdGljLiBJZiB3ZSB1c2VkIGEKKyAgICAgKiBoZXVyaXN0aWMgdG8gc2VydmUgYSBjYWNoZWQgcmVzcG9uc2Ugb2xkZXIgdGhhbiAyNCBob3Vycywgd2UgYXJlIHJlcXVpcmVkCisgICAgICogdG8gYXR0YWNoIGEgd2FybmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNGcmVzaG5lc3NMaWZldGltZUhldXJpc3RpYygpIHsKKyAgICAgICAgcmV0dXJuIG1heEFnZVNlY29uZHMgPT0gLTEgJiYgZXhwaXJlcyA9PSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHJlc3BvbnNlIGNhbiBiZSBzdG9yZWQgdG8gbGF0ZXIgc2VydmUgYW5vdGhlcgorICAgICAqIHJlcXVlc3QuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDYWNoZWFibGUoUmVxdWVzdEhlYWRlcnMgcmVxdWVzdCkgeworICAgICAgICAvKgorICAgICAgICAgKiBBbHdheXMgZ28gdG8gbmV0d29yayBmb3IgdW5jYWNoZWFibGUgcmVzcG9uc2UgY29kZXMgKFJGQyAyNjE2LCAxMy40KSwKKyAgICAgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHN1cHBvcnQgY2FjaGluZyBwYXJ0aWFsIGNvbnRlbnQuCisgICAgICAgICAqLworICAgICAgICBpbnQgcmVzcG9uc2VDb2RlID0gaGVhZGVycy5nZXRSZXNwb25zZUNvZGUoKTsKKyAgICAgICAgaWYgKHJlc3BvbnNlQ29kZSAhPSBIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX09LCisgICAgICAgICAgICAgICAgJiYgcmVzcG9uc2VDb2RlICE9IEh0dHBVUkxDb25uZWN0aW9uLkhUVFBfTk9UX0FVVEhPUklUQVRJVkUKKyAgICAgICAgICAgICAgICAmJiByZXNwb25zZUNvZGUgIT0gSHR0cFVSTENvbm5lY3Rpb24uSFRUUF9NVUxUX0NIT0lDRQorICAgICAgICAgICAgICAgICYmIHJlc3BvbnNlQ29kZSAhPSBIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX01PVkVEX1BFUk0KKyAgICAgICAgICAgICAgICAmJiByZXNwb25zZUNvZGUgIT0gSHR0cFVSTENvbm5lY3Rpb24uSFRUUF9HT05FKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBSZXNwb25zZXMgdG8gYXV0aG9yaXplZCByZXF1ZXN0cyBhcmVuJ3QgY2FjaGVhYmxlIHVubGVzcyB0aGV5IGluY2x1ZGUKKyAgICAgICAgICogYSAncHVibGljJywgJ211c3QtcmV2YWxpZGF0ZScgb3IgJ3MtbWF4YWdlJyBkaXJlY3RpdmUuCisgICAgICAgICAqLworICAgICAgICBpZiAocmVxdWVzdC5oYXNBdXRob3JpemF0aW9uKCkKKyAgICAgICAgICAgICAgICAmJiAhaXNQdWJsaWMKKyAgICAgICAgICAgICAgICAmJiAhbXVzdFJldmFsaWRhdGUKKyAgICAgICAgICAgICAgICAmJiBzTWF4QWdlU2Vjb25kcyA9PSAtMSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG5vU3RvcmUpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiBhIFZhcnkgaGVhZGVyIGNvbnRhaW5zIGFuIGFzdGVyaXNrLiBTdWNoIHJlc3BvbnNlcyBjYW5ub3QKKyAgICAgKiBiZSBjYWNoZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzVmFyeUFsbCgpIHsKKyAgICAgICAgcmV0dXJuIHZhcnlGaWVsZHMuY29udGFpbnMoIioiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgbm9uZSBvZiB0aGUgVmFyeSBoZWFkZXJzIG9uIHRoaXMgcmVzcG9uc2UgaGF2ZSBjaGFuZ2VkCisgICAgICogYmV0d2VlbiB7QGNvZGUgY2FjaGVkUmVxdWVzdH0gYW5kIHtAY29kZSBuZXdSZXF1ZXN0fS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB2YXJ5TWF0Y2hlcyhNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IGNhY2hlZFJlcXVlc3QsCisgICAgICAgICAgICBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IG5ld1JlcXVlc3QpIHsKKyAgICAgICAgZm9yIChTdHJpbmcgZmllbGQgOiB2YXJ5RmllbGRzKSB7CisgICAgICAgICAgICBpZiAoIU9iamVjdHMuZXF1YWwoY2FjaGVkUmVxdWVzdC5nZXQoZmllbGQpLCBuZXdSZXF1ZXN0LmdldChmaWVsZCkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNvdXJjZSB0byBzYXRpc2Z5IHtAY29kZSByZXF1ZXN0fSBnaXZlbiB0aGlzIGNhY2hlZCByZXNwb25zZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzcG9uc2VTb3VyY2UgY2hvb3NlUmVzcG9uc2VTb3VyY2UobG9uZyBub3dNaWxsaXMsIFJlcXVlc3RIZWFkZXJzIHJlcXVlc3QpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogSWYgdGhpcyByZXNwb25zZSBzaG91bGRuJ3QgaGF2ZSBiZWVuIHN0b3JlZCwgaXQgc2hvdWxkIG5ldmVyIGJlIHVzZWQKKyAgICAgICAgICogYXMgYSByZXNwb25zZSBzb3VyY2UuIFRoaXMgY2hlY2sgc2hvdWxkIGJlIHJlZHVuZGFudCBhcyBsb25nIGFzIHRoZQorICAgICAgICAgKiBwZXJzaXN0ZW5jZSBzdG9yZSBpcyB3ZWxsLWJlaGF2ZWQgYW5kIHRoZSBydWxlcyBhcmUgY29uc3RhbnQuCisgICAgICAgICAqLworICAgICAgICBpZiAoIWlzQ2FjaGVhYmxlKHJlcXVlc3QpKSB7CisgICAgICAgICAgICByZXR1cm4gUmVzcG9uc2VTb3VyY2UuTkVUV09SSzsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChyZXF1ZXN0LmlzTm9DYWNoZSgpIHx8IHJlcXVlc3QuaGFzQ29uZGl0aW9ucygpKSB7CisgICAgICAgICAgICByZXR1cm4gUmVzcG9uc2VTb3VyY2UuTkVUV09SSzsKKyAgICAgICAgfQorCisgICAgICAgIGxvbmcgYWdlTWlsbGlzID0gY29tcHV0ZUFnZShub3dNaWxsaXMpOworICAgICAgICBsb25nIGZyZXNoTWlsbGlzID0gY29tcHV0ZUZyZXNobmVzc0xpZmV0aW1lKCk7CisKKyAgICAgICAgaWYgKHJlcXVlc3QuZ2V0TWF4QWdlU2Vjb25kcygpICE9IC0xKSB7CisgICAgICAgICAgICBmcmVzaE1pbGxpcyA9IE1hdGgubWluKGZyZXNoTWlsbGlzLAorICAgICAgICAgICAgICAgICAgICBUaW1lVW5pdC5TRUNPTkRTLnRvTWlsbGlzKHJlcXVlc3QuZ2V0TWF4QWdlU2Vjb25kcygpKSk7CisgICAgICAgIH0KKworICAgICAgICBsb25nIG1pbkZyZXNoTWlsbGlzID0gMDsKKyAgICAgICAgaWYgKHJlcXVlc3QuZ2V0TWluRnJlc2hTZWNvbmRzKCkgIT0gLTEpIHsKKyAgICAgICAgICAgIG1pbkZyZXNoTWlsbGlzID0gVGltZVVuaXQuU0VDT05EUy50b01pbGxpcyhyZXF1ZXN0LmdldE1pbkZyZXNoU2Vjb25kcygpKTsKKyAgICAgICAgfQorCisgICAgICAgIGxvbmcgbWF4U3RhbGVNaWxsaXMgPSAwOworICAgICAgICBpZiAoIW11c3RSZXZhbGlkYXRlICYmIHJlcXVlc3QuZ2V0TWF4U3RhbGVTZWNvbmRzKCkgIT0gLTEpIHsKKyAgICAgICAgICAgIG1heFN0YWxlTWlsbGlzID0gVGltZVVuaXQuU0VDT05EUy50b01pbGxpcyhyZXF1ZXN0LmdldE1heFN0YWxlU2Vjb25kcygpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghbm9DYWNoZSAmJiBhZ2VNaWxsaXMgKyBtaW5GcmVzaE1pbGxpcyA8IGZyZXNoTWlsbGlzICsgbWF4U3RhbGVNaWxsaXMpIHsKKyAgICAgICAgICAgIGlmIChhZ2VNaWxsaXMgKyBtaW5GcmVzaE1pbGxpcyA+PSBmcmVzaE1pbGxpcykgeworICAgICAgICAgICAgICAgIGhlYWRlcnMuYWRkKCJXYXJuaW5nIiwgIjExMCBIdHRwVVJMQ29ubmVjdGlvbiBcIlJlc3BvbnNlIGlzIHN0YWxlXCIiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhZ2VNaWxsaXMgPiBUaW1lVW5pdC5IT1VSUy50b01pbGxpcygyNCkgJiYgaXNGcmVzaG5lc3NMaWZldGltZUhldXJpc3RpYygpKSB7CisgICAgICAgICAgICAgICAgaGVhZGVycy5hZGQoIldhcm5pbmciLCAiMTEzIEh0dHBVUkxDb25uZWN0aW9uIFwiSGV1cmlzdGljIGV4cGlyYXRpb25cIiIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIFJlc3BvbnNlU291cmNlLkNBQ0hFOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGxhc3RNb2RpZmllZCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXF1ZXN0LnNldElmTW9kaWZpZWRTaW5jZShsYXN0TW9kaWZpZWQpOworICAgICAgICB9IGVsc2UgaWYgKHNlcnZlZERhdGUgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVxdWVzdC5zZXRJZk1vZGlmaWVkU2luY2Uoc2VydmVkRGF0ZSk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZXRhZyAhPSBudWxsKSB7CisgICAgICAgICAgICByZXF1ZXN0LnNldElmTm9uZU1hdGNoKGV0YWcpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHJlcXVlc3QuaGFzQ29uZGl0aW9ucygpCisgICAgICAgICAgICAgICAgPyBSZXNwb25zZVNvdXJjZS5DT05ESVRJT05BTF9DQUNIRQorICAgICAgICAgICAgICAgIDogUmVzcG9uc2VTb3VyY2UuTkVUV09SSzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBjYWNoZWQgcmVzcG9uc2Ugc2hvdWxkIGJlIHVzZWQ7IGZhbHNlIGlmIHRoZQorICAgICAqIG5ldHdvcmsgcmVzcG9uc2Ugc2hvdWxkIGJlIHVzZWQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gdmFsaWRhdGUoUmVzcG9uc2VIZWFkZXJzIG5ldHdvcmtSZXNwb25zZSkgeworICAgICAgICBpZiAobmV0d29ya1Jlc3BvbnNlLmhlYWRlcnMuZ2V0UmVzcG9uc2VDb2RlKCkgPT0gSHR0cFVSTENvbm5lY3Rpb24uSFRUUF9OT1RfTU9ESUZJRUQpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVGhlIEhUVFAgc3BlYyBzYXlzIHRoYXQgaWYgdGhlIG5ldHdvcmsncyByZXNwb25zZSBpcyBvbGRlciB0aGFuIG91cgorICAgICAgICAgKiBjYWNoZWQgcmVzcG9uc2UsIHdlIG1heSByZXR1cm4gdGhlIGNhY2hlJ3MgcmVzcG9uc2UuIExpa2UgQ2hyb21lIChidXQKKyAgICAgICAgICogdW5saWtlIEZpcmVmb3gpLCB0aGlzIGNsaWVudCBwcmVmZXJzIHRvIHJldHVybiB0aGUgbmV3ZXIgcmVzcG9uc2UuCisgICAgICAgICAqLworICAgICAgICBpZiAobGFzdE1vZGlmaWVkICE9IG51bGwKKyAgICAgICAgICAgICAgICAmJiBuZXR3b3JrUmVzcG9uc2UubGFzdE1vZGlmaWVkICE9IG51bGwKKyAgICAgICAgICAgICAgICAmJiBuZXR3b3JrUmVzcG9uc2UubGFzdE1vZGlmaWVkLmdldFRpbWUoKSA8IGxhc3RNb2RpZmllZC5nZXRUaW1lKCkpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbWJpbmVzIHRoaXMgY2FjaGVkIGhlYWRlciB3aXRoIGEgbmV0d29yayBoZWFkZXIgYXMgZGVmaW5lZCBieSBSRkMgMjYxNiwKKyAgICAgKiAxMy41LjMuCisgICAgICovCisgICAgcHVibGljIFJlc3BvbnNlSGVhZGVycyBjb21iaW5lKFJlc3BvbnNlSGVhZGVycyBuZXR3b3JrKSB7CisgICAgICAgIFJhd0hlYWRlcnMgcmVzdWx0ID0gbmV3IFJhd0hlYWRlcnMoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGhlYWRlcnMubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIGZpZWxkTmFtZSA9IGhlYWRlcnMuZ2V0RmllbGROYW1lKGkpOworICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gaGVhZGVycy5nZXRWYWx1ZShpKTsKKyAgICAgICAgICAgIGlmIChmaWVsZE5hbWUuZXF1YWxzKCJXYXJuaW5nIikgJiYgdmFsdWUuc3RhcnRzV2l0aCgiMSIpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7IC8vIGRyb3AgMTAwLWxldmVsIGZyZXNobmVzcyB3YXJuaW5ncworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFpc0VuZFRvRW5kKGZpZWxkTmFtZSkgfHwgbmV0d29yay5oZWFkZXJzLmdldChmaWVsZE5hbWUpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYWRkKGZpZWxkTmFtZSwgdmFsdWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuZXR3b3JrLmhlYWRlcnMubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIGZpZWxkTmFtZSA9IG5ldHdvcmsuaGVhZGVycy5nZXRGaWVsZE5hbWUoaSk7CisgICAgICAgICAgICBpZiAoaXNFbmRUb0VuZChmaWVsZE5hbWUpKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChmaWVsZE5hbWUsIG5ldHdvcmsuaGVhZGVycy5nZXRWYWx1ZShpKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlSGVhZGVycyh1cmksIHJlc3VsdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHtAY29kZSBmaWVsZE5hbWV9IGlzIGFuIGVuZC10by1lbmQgSFRUUCBoZWFkZXIsIGFzCisgICAgICogZGVmaW5lZCBieSBSRkMgMjYxNiwgMTMuNS4xLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNFbmRUb0VuZChTdHJpbmcgZmllbGROYW1lKSB7CisgICAgICAgIHJldHVybiAhZmllbGROYW1lLmVxdWFsc0lnbm9yZUNhc2UoIkNvbm5lY3Rpb24iKQorICAgICAgICAgICAgICAgICYmICFmaWVsZE5hbWUuZXF1YWxzSWdub3JlQ2FzZSgiS2VlcC1BbGl2ZSIpCisgICAgICAgICAgICAgICAgJiYgIWZpZWxkTmFtZS5lcXVhbHNJZ25vcmVDYXNlKCJQcm94eS1BdXRoZW50aWNhdGUiKQorICAgICAgICAgICAgICAgICYmICFmaWVsZE5hbWUuZXF1YWxzSWdub3JlQ2FzZSgiUHJveHktQXV0aG9yaXphdGlvbiIpCisgICAgICAgICAgICAgICAgJiYgIWZpZWxkTmFtZS5lcXVhbHNJZ25vcmVDYXNlKCJURSIpCisgICAgICAgICAgICAgICAgJiYgIWZpZWxkTmFtZS5lcXVhbHNJZ25vcmVDYXNlKCJUcmFpbGVycyIpCisgICAgICAgICAgICAgICAgJiYgIWZpZWxkTmFtZS5lcXVhbHNJZ25vcmVDYXNlKCJUcmFuc2Zlci1FbmNvZGluZyIpCisgICAgICAgICAgICAgICAgJiYgIWZpZWxkTmFtZS5lcXVhbHNJZ25vcmVDYXNlKCJVcGdyYWRlIik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvUmVzcG9uc2VTb3VyY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL1Jlc3BvbnNlU291cmNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzMxZTM3ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL1Jlc3BvbnNlU291cmNlLmphdmEKQEAgLTAsMCArMSw0MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5uZXQuaHR0cDsKKworZW51bSBSZXNwb25zZVNvdXJjZSB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHJlc3BvbnNlIGZyb20gdGhlIGNhY2hlIGltbWVkaWF0ZWx5LgorICAgICAqLworICAgIENBQ0hFLAorCisgICAgLyoqCisgICAgICogTWFrZSBhIGNvbmRpdGlvbmFsIHJlcXVlc3QgdG8gdGhlIGhvc3QsIHJldHVybmluZyB0aGUgY2FjaGUgcmVzcG9uc2UgaWYKKyAgICAgKiB0aGUgY2FjaGUgaXMgdmFsaWQgYW5kIHRoZSBuZXR3b3JrIHJlc3BvbnNlIG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBDT05ESVRJT05BTF9DQUNIRSwKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgcmVzcG9uc2UgZnJvbSB0aGUgbmV0d29yay4KKyAgICAgKi8KKyAgICBORVRXT1JLOworCisgICAgcHVibGljIGJvb2xlYW4gcmVxdWlyZXNDb25uZWN0aW9uKCkgeworICAgICAgICByZXR1cm4gdGhpcyA9PSBDT05ESVRJT05BTF9DQUNIRSB8fCB0aGlzID09IE5FVFdPUks7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvUmV0cnlhYmxlT3V0cHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvaHR0cC9SZXRyeWFibGVPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42N2JiNWI4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvUmV0cnlhYmxlT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw3MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5uZXQuaHR0cDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBBbiBIVFRQIHJlcXVlc3QgYm9keSB0aGF0J3MgY29tcGxldGVseSBidWZmZXJlZCBpbiBtZW1vcnkuIFRoaXMgYWxsb3dzCisgKiB0aGUgcG9zdCBib2R5IHRvIGJlIHRyYW5zcGFyZW50bHkgcmUtc2VudCBpZiB0aGUgSFRUUCByZXF1ZXN0IG11c3QgYmUKKyAqIHNlbnQgbXVsdGlwbGUgdGltZXMuCisgKi8KK2ZpbmFsIGNsYXNzIFJldHJ5YWJsZU91dHB1dFN0cmVhbSBleHRlbmRzIEFic3RyYWN0SHR0cE91dHB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbGltaXQ7CisgICAgcHJpdmF0ZSBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gY29udGVudDsKKworICAgIHB1YmxpYyBSZXRyeWFibGVPdXRwdXRTdHJlYW0oaW50IGxpbWl0KSB7CisgICAgICAgIHRoaXMubGltaXQgPSBsaW1pdDsKKyAgICAgICAgdGhpcy5jb250ZW50ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbShsaW1pdCk7CisgICAgfQorCisgICAgcHVibGljIFJldHJ5YWJsZU91dHB1dFN0cmVhbSgpIHsKKyAgICAgICAgdGhpcy5saW1pdCA9IC0xOworICAgICAgICB0aGlzLmNvbnRlbnQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjbG9zZWQpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBjbG9zZWQgPSB0cnVlOworICAgICAgICBpZiAoY29udGVudC5zaXplKCkgPCBsaW1pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJjb250ZW50LWxlbmd0aCBwcm9taXNlZCAiCisgICAgICAgICAgICAgICAgICAgICsgbGltaXQgKyAiIGJ5dGVzLCBidXQgcmVjZWl2ZWQgIiArIGNvbnRlbnQuc2l6ZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgd3JpdGUoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGNvdW50KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgIGlmIChsaW1pdCAhPSAtMSAmJiBjb250ZW50LnNpemUoKSA+IGxpbWl0IC0gY291bnQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiZXhjZWVkZWQgY29udGVudC1sZW5ndGggbGltaXQgb2YgIiArIGxpbWl0ICsgIiBieXRlcyIpOworICAgICAgICB9CisgICAgICAgIGNvbnRlbnQud3JpdGUoYnVmZmVyLCBvZmZzZXQsIGNvdW50KTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBjb250ZW50TGVuZ3RoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2xvc2UoKTsKKyAgICAgICAgcmV0dXJuIGNvbnRlbnQuc2l6ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlVG9Tb2NrZXQoT3V0cHV0U3RyZWFtIHNvY2tldE91dCkgdGhyb3dzIElPRXhjZXB0aW9uICB7CisgICAgICAgIGNvbnRlbnQud3JpdGVUbyhzb2NrZXRPdXQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL1Vua25vd25MZW5ndGhIdHRwSW5wdXRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC9odHRwL1Vua25vd25MZW5ndGhIdHRwSW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hODIyNGEzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvVW5rbm93bkxlbmd0aEh0dHBJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUubmV0Lmh0dHA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuQ2FjaGVSZXF1ZXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogQW4gSFRUUCBwYXlsb2FkIHRlcm1pbmF0ZWQgYnkgdGhlIGVuZCBvZiB0aGUgc29ja2V0IHN0cmVhbS4KKyAqLworZmluYWwgY2xhc3MgVW5rbm93bkxlbmd0aEh0dHBJbnB1dFN0cmVhbSBleHRlbmRzIEFic3RyYWN0SHR0cElucHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIGJvb2xlYW4gaW5wdXRFeGhhdXN0ZWQ7CisKKyAgICBVbmtub3duTGVuZ3RoSHR0cElucHV0U3RyZWFtKElucHV0U3RyZWFtIGlzLCBDYWNoZVJlcXVlc3QgY2FjaGVSZXF1ZXN0LAorICAgICAgICAgICAgSHR0cEVuZ2luZSBodHRwRW5naW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihpcywgaHR0cEVuZ2luZSwgY2FjaGVSZXF1ZXN0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCByZWFkKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQXJyYXlzLmNoZWNrT2Zmc2V0QW5kQ291bnQoYnVmZmVyLmxlbmd0aCwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgIGNoZWNrTm90Q2xvc2VkKCk7CisgICAgICAgIGlmIChpbiA9PSBudWxsIHx8IGlucHV0RXhoYXVzdGVkKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgaW50IHJlYWQgPSBpbi5yZWFkKGJ1ZmZlciwgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgIGlmIChyZWFkID09IC0xKSB7CisgICAgICAgICAgICBpbnB1dEV4aGF1c3RlZCA9IHRydWU7CisgICAgICAgICAgICBlbmRPZklucHV0KGZhbHNlKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBjYWNoZVdyaXRlKGJ1ZmZlciwgb2Zmc2V0LCByZWFkKTsKKyAgICAgICAgcmV0dXJuIHJlYWQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tOb3RDbG9zZWQoKTsKKyAgICAgICAgcmV0dXJuIGluID09IG51bGwgPyAwIDogaW4uYXZhaWxhYmxlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGNsb3NlZCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGNsb3NlZCA9IHRydWU7CisgICAgICAgIGlmICghaW5wdXRFeGhhdXN0ZWQpIHsKKyAgICAgICAgICAgIHVuZXhwZWN0ZWRFbmRPZklucHV0KCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvdXJsL0ZpbGVIYW5kbGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvdXJsL0ZpbGVIYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDkyMTQ5MAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC91cmwvRmlsZUhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDEwNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLm5ldC51cmw7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlByb3h5OworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTFN0cmVhbUhhbmRsZXI7CisKKy8qKgorICogVGhpcyBpcyB0aGUgaGFuZGxlciB0aGF0IGlzIHJlc3BvbnNpYmxlIGZvciByZWFkaW5nIGZpbGVzIGZyb20gdGhlIGZpbGUKKyAqIHN5c3RlbS4KKyAqLworcHVibGljIGNsYXNzIEZpbGVIYW5kbGVyIGV4dGVuZHMgVVJMU3RyZWFtSGFuZGxlciB7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29ubmVjdGlvbiB0byB0aGUgYSBmaWxlIHBvaW50ZWQgYnkgdGhpcyA8Y29kZT5VUkw8L2NvZGU+IGluCisgICAgICogdGhlIGZpbGUgc3lzdGVtCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEgY29ubmVjdGlvbiB0byB0aGUgcmVzb3VyY2UgcG9pbnRlZCBieSB0aGlzIHVybC4KKyAgICAgKiBAcGFyYW0gdXJsCisgICAgICogICAgICAgICAgICBVUkwgVGhlIFVSTCB0byB3aGljaCB0aGUgY29ubmVjdGlvbiBpcyBwb2ludGluZyB0bworICAgICAqCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFVSTENvbm5lY3Rpb24gb3BlbkNvbm5lY3Rpb24oVVJMIHVybCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG9wZW5Db25uZWN0aW9uKHVybCwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGJlaGF2aW9yIG9mIHRoaXMgbWV0aG9kIGlzIHRoZSBzYW1lIGFzIG9wZW5Db25uZWN0aW9uKFVSTCkuCisgICAgICogPGNvZGU+cHJveHk8L2NvZGU+IGlzIG5vdCB1c2VkIGluIEZpbGVVUkxDb25uZWN0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHVybAorICAgICAqICAgICAgICAgICAgdGhlIFVSTCB3aGljaCB0aGUgY29ubmVjdGlvbiBpcyBwb2ludGluZyB0bworICAgICAqIEBwYXJhbSBwcm94eQorICAgICAqICAgICAgICAgICAgUHJveHkKKyAgICAgKiBAcmV0dXJuIGEgY29ubmVjdGlvbiB0byB0aGUgcmVzb3VyY2UgcG9pbnRlZCBieSB0aGlzIHVybC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGhhbmRsZXIgZmFpbHMgdG8gZXN0YWJsaXNoIGEgY29ubmVjdGlvbi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSB1cmwgYXJndW1lbnQgaXMgbnVsbC4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgdGhlIHByb3RvY29sIGhhbmRsZXIgZG9lc24ndCBzdXBwb3J0IHRoaXMgbWV0aG9kLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBVUkxDb25uZWN0aW9uIG9wZW5Db25uZWN0aW9uKFVSTCB1cmwsIFByb3h5IHByb3h5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodXJsID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInVybCA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgaG9zdCA9IHVybC5nZXRIb3N0KCk7CisgICAgICAgIGlmIChob3N0ID09IG51bGwgfHwgaG9zdC5pc0VtcHR5KCkgfHwgaG9zdC5lcXVhbHNJZ25vcmVDYXNlKCJsb2NhbGhvc3QiKSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWxlVVJMQ29ubmVjdGlvbih1cmwpOworICAgICAgICB9CisKKyAgICAgICAgLy8gSWYgYSBob3N0bmFtZSBpcyBzcGVjaWZpZWQgdHJ5IHRvIGdldCB0aGUgcmVzb3VyY2UgdXNpbmcgRlRQCisgICAgICAgIFVSTCBmdHBVUkwgPSBuZXcgVVJMKCJmdHAiLCBob3N0LCB1cmwuZ2V0RmlsZSgpKTsKKyAgICAgICAgcmV0dXJuIChwcm94eSA9PSBudWxsKSA/IGZ0cFVSTC5vcGVuQ29ubmVjdGlvbigpIDogZnRwVVJMLm9wZW5Db25uZWN0aW9uKHByb3h5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSB0aGUgPGNvZGU+c3RyaW5nPC9jb2RlPnN0ciBpbnRvIDxjb2RlPlVSTDwvY29kZT4gdSB3aGljaAorICAgICAqIGFscmVhZHkgaGF2ZSB0aGUgY29udGV4dCBwcm9wZXJ0aWVzLiBUaGUgc3RyaW5nIGdlbmVyYWxseSBoYXZlIHRoZQorICAgICAqIGZvbGxvd2luZyBmb3JtYXQ6IDxjb2RlPjxjZW50ZXI+L2M6L3dpbmRvd3Mvd2luLmluaTwvY2VudGVyPjwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJsCisgICAgICogICAgICAgICAgICBUaGUgVVJMIG9iamVjdCB0aGF0J3MgcGFyc2VkIGludG8KKyAgICAgKiBAcGFyYW0gc3BlYworICAgICAqICAgICAgICAgICAgVGhlIHN0cmluZyBlcXVpdmFsZW50IG9mIHRoZSBzcGVjaWZpY2F0aW9uIFVSTAorICAgICAqIEBwYXJhbSBzdGFydAorICAgICAqICAgICAgICAgICAgVGhlIGluZGV4IGluIHRoZSBzcGVjIHN0cmluZyBmcm9tIHdoaWNoIHRvIGJlZ2luIHBhcnNpbmcKKyAgICAgKiBAcGFyYW0gZW5kCisgICAgICogICAgICAgICAgICBUaGUgaW5kZXggdG8gc3RvcCBwYXJzaW5nCisgICAgICoKKyAgICAgKiBAc2VlIGphdmEubmV0LlVSTFN0cmVhbUhhbmRsZXIjdG9FeHRlcm5hbEZvcm0oVVJMKQorICAgICAqIEBzZWUgamF2YS5uZXQuVVJMCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgcGFyc2VVUkwoVVJMIHVybCwgU3RyaW5nIHNwZWMsIGludCBzdGFydCwgaW50IGVuZCkgeworICAgICAgICBpZiAoZW5kIDwgc3RhcnQpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcGFyc2VTdHJpbmcgPSAiIjsKKyAgICAgICAgaWYgKHN0YXJ0IDwgZW5kKSB7CisgICAgICAgICAgICBwYXJzZVN0cmluZyA9IHNwZWMuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpLnJlcGxhY2UoJ1xcJywgJy8nKTsKKyAgICAgICAgfQorICAgICAgICBzdXBlci5wYXJzZVVSTCh1cmwsIHBhcnNlU3RyaW5nLCAwLCBwYXJzZVN0cmluZy5sZW5ndGgoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L3VybC9GaWxlVVJMQ29ubmVjdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L3VybC9GaWxlVVJMQ29ubmVjdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJjNDExNjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvdXJsL0ZpbGVVUkxDb25uZWN0aW9uLmphdmEKQEAgLTAsMCArMSwyMDcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5uZXQudXJsOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZVBlcm1pc3Npb247CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEubmV0LlVSTENvbm5lY3Rpb247CitpbXBvcnQgbGliY29yZS5uZXQuVXJpQ29kZWM7CisKKy8qKgorICogVGhpcyBzdWJjbGFzcyBleHRlbmRzIDxjb2RlPlVSTENvbm5lY3Rpb248L2NvZGU+LgorICogPHA+CisgKiBUaGlzIGNsYXNzIGlzIHJlc3BvbnNpYmxlIGZvciBjb25uZWN0aW5nLCBnZXR0aW5nIGNvbnRlbnQgYW5kIGlucHV0IHN0cmVhbSBvZgorICogdGhlIGZpbGUuCisgKi8KK3B1YmxpYyBjbGFzcyBGaWxlVVJMQ29ubmVjdGlvbiBleHRlbmRzIFVSTENvbm5lY3Rpb24geworCisgICAgU3RyaW5nIGZpbGVOYW1lOworCisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBpczsKKworICAgIHByaXZhdGUgaW50IGxlbmd0aCA9IC0xOworCisgICAgcHJpdmF0ZSBib29sZWFuIGlzRGlyOworCisgICAgcHJpdmF0ZSBGaWxlUGVybWlzc2lvbiBwZXJtaXNzaW9uOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiA8Y29kZT5GaWxlVVJMQ29ubmVjdGlvbjwvY29kZT4gZm9yIGVzdGFibGlzaGluZworICAgICAqIGEgY29ubmVjdGlvbiB0byB0aGUgZmlsZSBwb2ludGVkIGJ5IHRoaXMgPGNvZGU+VVJMPGNvZGU+CisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJsIFRoZSBVUkwgdGhpcyBjb25uZWN0aW9uIGlzIGNvbm5lY3RlZCB0bworICAgICAqLworICAgIHB1YmxpYyBGaWxlVVJMQ29ubmVjdGlvbihVUkwgdXJsKSB7CisgICAgICAgIHN1cGVyKHVybCk7CisgICAgICAgIGZpbGVOYW1lID0gdXJsLmdldEZpbGUoKTsKKyAgICAgICAgaWYgKGZpbGVOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIGZpbGVOYW1lID0gIiI7CisgICAgICAgIH0KKyAgICAgICAgZmlsZU5hbWUgPSBVcmlDb2RlYy5kZWNvZGUoZmlsZU5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kcyB3aWxsIGF0dGVtcHQgdG8gb2J0YWluIHRoZSBpbnB1dCBzdHJlYW0gb2YgdGhlIGZpbGUgcG9pbnRlZAorICAgICAqIGJ5IHRoaXMgPGNvZGU+VVJMPC9jb2RlPi4gSWYgdGhlIGZpbGUgaXMgYSBkaXJlY3RvcnksIGl0IHdpbGwgcmV0dXJuCisgICAgICogdGhhdCBkaXJlY3RvcnkgbGlzdGluZyBhcyBhbiBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSU8gZXJyb3Igb2NjdXJzIHdoaWxlIGNvbm5lY3RpbmcKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjb25uZWN0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoZmlsZU5hbWUpOworICAgICAgICBpZiAoZi5pc0RpcmVjdG9yeSgpKSB7CisgICAgICAgICAgICBpc0RpciA9IHRydWU7CisgICAgICAgICAgICBpcyA9IGdldERpcmVjdG9yeUxpc3RpbmcoZik7CisgICAgICAgICAgICAvLyB1c2UgLTEgZm9yIHRoZSBjb250ZW50TGVuZ3RoCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZikpOworICAgICAgICAgICAgbG9uZyBsZW5ndGhBc0xvbmcgPSBmLmxlbmd0aCgpOworICAgICAgICAgICAgbGVuZ3RoID0gbGVuZ3RoQXNMb25nIDw9IEludGVnZXIuTUFYX1ZBTFVFID8gKGludCkgbGVuZ3RoQXNMb25nIDogSW50ZWdlci5NQVhfVkFMVUU7CisgICAgICAgIH0KKyAgICAgICAgY29ubmVjdGVkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhlIGZpbGUgaW4gYnl0ZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGZpbGUKKyAgICAgKgorICAgICAqIEBzZWUgI2dldENvbnRlbnRUeXBlKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldENvbnRlbnRMZW5ndGgoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoIWNvbm5lY3RlZCkgeworICAgICAgICAgICAgICAgIGNvbm5lY3QoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZGVmYXVsdCBpcyAtMQorICAgICAgICB9CisgICAgICAgIHJldHVybiBsZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29udGVudCB0eXBlIG9mIHRoZSByZXNvdXJjZS4gSnVzdCB0YWtlcyBhIGd1ZXNzIGJhc2VkIG9uIHRoZQorICAgICAqIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb250ZW50IHR5cGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKCFjb25uZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICBjb25uZWN0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiAiY29udGVudC91bmtub3duIjsKKyAgICAgICAgfQorICAgICAgICBpZiAoaXNEaXIpIHsKKyAgICAgICAgICAgIHJldHVybiAidGV4dC9wbGFpbiI7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGd1ZXNzQ29udGVudFR5cGVGcm9tTmFtZSh1cmwuZ2V0RmlsZSgpKTsKKyAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlc3VsdCA9IGd1ZXNzQ29udGVudFR5cGVGcm9tU3RyZWFtKGlzKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gSWdub3JlCisgICAgICAgIH0KKyAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuICJjb250ZW50L3Vua25vd24iOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRpcmVjdG9yeSBsaXN0aW5nIG9mIHRoZSBmaWxlIGNvbXBvbmVudCBhcyBhbiBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBpbnB1dCBzdHJlYW0gb2YgdGhlIGRpcmVjdG9yeSBsaXN0aW5nCisgICAgICovCisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBnZXREaXJlY3RvcnlMaXN0aW5nKEZpbGUgZikgeworICAgICAgICBTdHJpbmcgZmlsZUxpc3RbXSA9IGYubGlzdCgpOworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZXMgPSBuZXcgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgUHJpbnRTdHJlYW0gb3V0ID0gbmV3IFByaW50U3RyZWFtKGJ5dGVzKTsKKyAgICAgICAgb3V0LnByaW50KCI8dGl0bGU+RGlyZWN0b3J5IExpc3Rpbmc8L3RpdGxlPlxuIik7CisgICAgICAgIG91dC5wcmludCgiPGJhc2UgaHJlZj1cImZpbGU6Iik7CisgICAgICAgIG91dC5wcmludChmLmdldFBhdGgoKS5yZXBsYWNlKCdcXCcsICcvJykgKyAiL1wiPjxoMT4iICsgZi5nZXRQYXRoKCkKKyAgICAgICAgICAgICAgICArICI8L2gxPlxuPGhyPlxuIik7CisgICAgICAgIGludCBpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZmlsZUxpc3QubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG91dC5wcmludChmaWxlTGlzdFtpXSArICI8YnI+XG4iKTsKKyAgICAgICAgfQorICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgcmV0dXJuIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcy50b0J5dGVBcnJheSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbnB1dCBzdHJlYW0gb2YgdGhlIG9iamVjdCByZWZlcnJlZCB0byBieSB0aGlzCisgICAgICogPGNvZGU+VVJMQ29ubmVjdGlvbjwvY29kZT4KKyAgICAgKgorICAgICAqIEZpbGUgU2FtcGxlIDogIi9aSVAyMTEvKy9oYXJtb255L3Rvb2xzL2phdmFjL3Jlc291cmNlcy9qYXZhYy5wcm9wZXJ0aWVzIgorICAgICAqIEludmFsaWQgRmlsZSBTYW1wbGU6CisgICAgICogIi9aSVAvKy9oYXJtb255L3Rvb2xzL2phdmFjL3Jlc291cmNlcy9qYXZhYy5wcm9wZXJ0aWVzIgorICAgICAqICJaSVAyMTEvKy9oYXJtb255L3Rvb2xzL2phdmFjL3Jlc291cmNlcy9qYXZhYy5wcm9wZXJ0aWVzIgorICAgICAqCisgICAgICogQHJldHVybiBpbnB1dCBzdHJlYW0gb2YgdGhlIG9iamVjdAorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIElPIGVycm9yIG9jY3VycworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghY29ubmVjdGVkKSB7CisgICAgICAgICAgICBjb25uZWN0KCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHBlcm1pc3Npb24sIGluIHRoaXMgY2FzZSB0aGUgc3ViY2xhc3MsIEZpbGVQZXJtaXNzaW9uIG9iamVjdAorICAgICAqIHdoaWNoIHJlcHJlc2VudHMgdGhlIHBlcm1pc3Npb24gbmVjZXNzYXJ5IGZvciB0aGlzIFVSTENvbm5lY3Rpb24gdG8KKyAgICAgKiBlc3RhYmxpc2ggdGhlIGNvbm5lY3Rpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwZXJtaXNzaW9uIHJlcXVpcmVkIGZvciB0aGlzIFVSTENvbm5lY3Rpb24uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSU8gZXhjZXB0aW9uIG9jY3VycyB3aGlsZSBjcmVhdGluZyB0aGUgcGVybWlzc2lvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uIGdldFBlcm1pc3Npb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAocGVybWlzc2lvbiA9PSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgcGF0aCA9IGZpbGVOYW1lOworICAgICAgICAgICAgaWYgKEZpbGUuc2VwYXJhdG9yQ2hhciAhPSAnLycpIHsKKyAgICAgICAgICAgICAgICBwYXRoID0gcGF0aC5yZXBsYWNlKCcvJywgRmlsZS5zZXBhcmF0b3JDaGFyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBlcm1pc3Npb24gPSBuZXcgRmlsZVBlcm1pc3Npb24ocGF0aCwgInJlYWQiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcGVybWlzc2lvbjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvdXJsL0Z0cEhhbmRsZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC91cmwvRnRwSGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM0MmE0OTkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvdXJsL0Z0cEhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDY5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUubmV0LnVybDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuUHJveHk7CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEubmV0LlVSTENvbm5lY3Rpb247CitpbXBvcnQgamF2YS5uZXQuVVJMU3RyZWFtSGFuZGxlcjsKKworcHVibGljIGNsYXNzIEZ0cEhhbmRsZXIgZXh0ZW5kcyBVUkxTdHJlYW1IYW5kbGVyIHsKKyAgICAvKioKKyAgICAgKiBPcGVuIGEgVVJMQ29ubmVjdGlvbiBvbiB0aGUgZ2l2ZW4gVVJMLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBVUkxDb25uZWN0aW9uIG9wZW5Db25uZWN0aW9uKFVSTCB1KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3IEZ0cFVSTENvbm5lY3Rpb24odSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvbm5lY3Rpb24sIHdoaWNoIGlzIGVzdGFibGlzaGVkIHZpYSB0aGUgPGNvZGU+cHJveHk8L2NvZGU+LAorICAgICAqIHRvIHRoZSBGVFAgc2VydmVyIHNwZWNpZmllZCBieSB0aGlzIDxjb2RlPlVSTDwvY29kZT4uIElmCisgICAgICogPGNvZGU+cHJveHk8L2NvZGU+IGlzIERJUkVDVCB0eXBlLCB0aGUgY29ubmVjdGlvbiBpcyBtYWRlIGluIG5vcm1hbAorICAgICAqIHdheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmwKKyAgICAgKiAgICAgICAgICAgIHRoZSBVUkwgd2hpY2ggdGhlIGNvbm5lY3Rpb24gaXMgcG9pbnRpbmcgdG8KKyAgICAgKiBAcGFyYW0gcHJveHkKKyAgICAgKiAgICAgICAgICAgIHRoZSBwcm94eSB3aGljaCBpcyB1c2VkIHRvIG1ha2UgdGhlIGNvbm5lY3Rpb24KKyAgICAgKiBAcmV0dXJuIGEgY29ubmVjdGlvbiB0byB0aGUgcmVzb3VyY2UgcG9pbnRlZCBieSB0aGlzIHVybC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGlzIGhhbmRsZXIgZmFpbHMgdG8gZXN0YWJsaXNoIGEgY29ubmVjdGlvbi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFueSBhcmd1bWVudCBpcyBudWxsIG9yIHRoZSB0eXBlIG9mIHByb3h5IGlzIHdyb25nLgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiB0aGUgcHJvdG9jb2wgaGFuZGxlciBkb2Vzbid0IHN1cHBvcnQgdGhpcyBtZXRob2QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIFVSTENvbm5lY3Rpb24gb3BlbkNvbm5lY3Rpb24oVVJMIHVybCwgUHJveHkgcHJveHkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh1cmwgPT0gbnVsbCB8fCBwcm94eSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ1cmwgPT0gbnVsbCB8fCBwcm94eSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBGdHBVUkxDb25uZWN0aW9uKHVybCwgcHJveHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgZGVmYXVsdCBwb3J0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgZ2V0RGVmYXVsdFBvcnQoKSB7CisgICAgICAgIHJldHVybiAyMTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvdXJsL0Z0cFVSTENvbm5lY3Rpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC91cmwvRnRwVVJMQ29ubmVjdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUxNjg0MjgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvdXJsL0Z0cFVSTENvbm5lY3Rpb24uamF2YQpAQCAtMCwwICsxLDUwMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLm5ldC51cmw7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5FT0ZFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0U29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Qcm94eTsKK2ltcG9ydCBqYXZhLm5ldC5Qcm94eVNlbGVjdG9yOworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0UGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkk7CitpbXBvcnQgamF2YS5uZXQuVVJJU3ludGF4RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTFN0cmVhbUhhbmRsZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0czsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK3B1YmxpYyBjbGFzcyBGdHBVUkxDb25uZWN0aW9uIGV4dGVuZHMgVVJMQ29ubmVjdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRlRQX1BPUlQgPSAyMTsKKworICAgIC8vIEZUUCBSZXBseSBDb25zdGFudHMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRlRQX0RBVEFPUEVOID0gMTI1OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEZUUF9PUEVOREFUQSA9IDE1MDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGVFBfT0sgPSAyMDA7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRlRQX1VTRVJSRUFEWSA9IDIyMDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGVFBfVFJBTlNGRVJPSyA9IDIyNjsKKworICAgIC8vIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGVFBfUEFTViA9IDIyNzsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGVFBfTE9HR0VESU4gPSAyMzA7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRlRQX0ZJTEVPSyA9IDI1MDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGVFBfUEFTV0QgPSAzMzE7CisKKyAgICAvLyBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRlRQX0RBVEFFUlJPUiA9IDQ1MTsKKworICAgIC8vIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGVFBfRVJST1IgPSA1MDA7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRlRQX05PVEZPVU5EID0gNTUwOworCisgICAgcHJpdmF0ZSBTb2NrZXQgY29udHJvbFNvY2tldDsKKworICAgIHByaXZhdGUgU29ja2V0IGRhdGFTb2NrZXQ7CisKKyAgICBwcml2YXRlIFNlcnZlclNvY2tldCBhY2NlcHRTb2NrZXQ7CisKKyAgICBwcml2YXRlIElucHV0U3RyZWFtIGN0cmxJbnB1dDsKKworICAgIHByaXZhdGUgSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW07CisKKyAgICBwcml2YXRlIE91dHB1dFN0cmVhbSBjdHJsT3V0cHV0OworCisgICAgcHJpdmF0ZSBpbnQgZGF0YVBvcnQ7CisKKyAgICBwcml2YXRlIFN0cmluZyB1c2VybmFtZSA9ICJhbm9ueW1vdXMiOworCisgICAgcHJpdmF0ZSBTdHJpbmcgcGFzc3dvcmQgPSAiIjsKKworICAgIHByaXZhdGUgU3RyaW5nIHJlcGx5Q29kZTsKKworICAgIHByaXZhdGUgU3RyaW5nIGhvc3ROYW1lOworCisgICAgcHJpdmF0ZSBQcm94eSBwcm94eTsKKworICAgIHByaXZhdGUgUHJveHkgY3VycmVudFByb3h5OworCisgICAgcHJpdmF0ZSBVUkkgdXJpOworCisgICAgLyoqCisgICAgICogRnRwVVJMQ29ubmVjdGlvbiBjb25zdHJ1Y3RvciBjb21tZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHVybAorICAgICAqLworICAgIHByb3RlY3RlZCBGdHBVUkxDb25uZWN0aW9uKFVSTCB1cmwpIHsKKyAgICAgICAgc3VwZXIodXJsKTsKKyAgICAgICAgaG9zdE5hbWUgPSB1cmwuZ2V0SG9zdCgpOworICAgICAgICBTdHJpbmcgcGFyc2UgPSB1cmwuZ2V0VXNlckluZm8oKTsKKyAgICAgICAgaWYgKHBhcnNlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGludCBzcGxpdCA9IHBhcnNlLmluZGV4T2YoJzonKTsKKyAgICAgICAgICAgIGlmIChzcGxpdCA+PSAwKSB7CisgICAgICAgICAgICAgICAgdXNlcm5hbWUgPSBwYXJzZS5zdWJzdHJpbmcoMCwgc3BsaXQpOworICAgICAgICAgICAgICAgIHBhc3N3b3JkID0gcGFyc2Uuc3Vic3RyaW5nKHNwbGl0ICsgMSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHVzZXJuYW1lID0gcGFyc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdXJpID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHVyaSA9IHVybC50b1VSSSgpOworICAgICAgICB9IGNhdGNoIChVUklTeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZG8gbm90aGluZy4KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZ0cFVSTENvbm5lY3Rpb24gY29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJsCisgICAgICogQHBhcmFtIHByb3h5CisgICAgICovCisgICAgcHJvdGVjdGVkIEZ0cFVSTENvbm5lY3Rpb24oVVJMIHVybCwgUHJveHkgcHJveHkpIHsKKyAgICAgICAgdGhpcyh1cmwpOworICAgICAgICB0aGlzLnByb3h5ID0gcHJveHk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hhbmdlIHRoZSBzZXJ2ZXIgZGlyZWN0b3J5IHRvIHRoYXQgc3BlY2lmaWVkIGluIHRoZSBVUkwKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY2QoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgaWR4ID0gdXJsLmdldEZpbGUoKS5sYXN0SW5kZXhPZignLycpOworCisgICAgICAgIGlmIChpZHggPiAwKSB7CisgICAgICAgICAgICBTdHJpbmcgZGlyID0gdXJsLmdldEZpbGUoKS5zdWJzdHJpbmcoMCwgaWR4KTsKKyAgICAgICAgICAgIHdyaXRlKCJDV0QgIiArIGRpciArICJcclxuIik7CisgICAgICAgICAgICBpbnQgcmVwbHkgPSBnZXRSZXBseSgpOworICAgICAgICAgICAgaWYgKHJlcGx5ICE9IEZUUF9GSUxFT0sgJiYgZGlyLmxlbmd0aCgpID4gMCAmJiBkaXIuY2hhckF0KDApID09ICcvJykgeworICAgICAgICAgICAgICAgIHdyaXRlKCJDV0QgIiArIGRpci5zdWJzdHJpbmcoMSkgKyAiXHJcbiIpOworICAgICAgICAgICAgICAgIHJlcGx5ID0gZ2V0UmVwbHkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChyZXBseSAhPSBGVFBfRklMRU9LKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJVbmFibGUgdG8gY2hhbmdlIGRpcmVjdG9yaWVzIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFc3RhYmxpc2hlcyB0aGUgY29ubmVjdGlvbiB0byB0aGUgcmVzb3VyY2Ugc3BlY2lmaWVkIGJ5IHRoaXMKKyAgICAgKiA8Y29kZT5VUkw8L2NvZGU+CisgICAgICoKKyAgICAgKiBAc2VlICNjb25uZWN0ZWQKKyAgICAgKiBAc2VlIGphdmEuaW8uSU9FeGNlcHRpb24KKyAgICAgKiBAc2VlIFVSTFN0cmVhbUhhbmRsZXIKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjb25uZWN0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVXNlIHN5c3RlbS13aWRlIFByb3h5U2VsZWN0IHRvIHNlbGVjdCBwcm94eSBsaXN0LAorICAgICAgICAvLyB0aGVuIHRyeSB0byBjb25uZWN0IHZpYSBlbGVtZW50cyBpbiB0aGUgcHJveHkgbGlzdC4KKyAgICAgICAgTGlzdDxQcm94eT4gcHJveHlMaXN0ID0gbnVsbDsKKyAgICAgICAgaWYgKHByb3h5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHByb3h5TGlzdCA9IG5ldyBBcnJheUxpc3Q8UHJveHk+KDEpOworICAgICAgICAgICAgcHJveHlMaXN0LmFkZChwcm94eSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBQcm94eVNlbGVjdG9yIHNlbGVjdG9yID0gUHJveHlTZWxlY3Rvci5nZXREZWZhdWx0KCk7CisgICAgICAgICAgICBpZiAoc2VsZWN0b3IgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHByb3h5TGlzdCA9IHNlbGVjdG9yLnNlbGVjdCh1cmkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChwcm94eUxpc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgY3VycmVudFByb3h5ID0gbnVsbDsKKyAgICAgICAgICAgIGNvbm5lY3RJbnRlcm5hbCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgUHJveHlTZWxlY3RvciBzZWxlY3RvciA9IFByb3h5U2VsZWN0b3IuZ2V0RGVmYXVsdCgpOworICAgICAgICAgICAgSXRlcmF0b3I8UHJveHk+IGl0ZXIgPSBwcm94eUxpc3QuaXRlcmF0b3IoKTsKKyAgICAgICAgICAgIGJvb2xlYW4gY29ubmVjdE9LID0gZmFsc2U7CisgICAgICAgICAgICBTdHJpbmcgZmFpbHVyZVJlYXNvbiA9ICIiOworICAgICAgICAgICAgd2hpbGUgKGl0ZXIuaGFzTmV4dCgpICYmICFjb25uZWN0T0spIHsKKyAgICAgICAgICAgICAgICBjdXJyZW50UHJveHkgPSBpdGVyLm5leHQoKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBjb25uZWN0SW50ZXJuYWwoKTsKKyAgICAgICAgICAgICAgICAgICAgY29ubmVjdE9LID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbHVyZVJlYXNvbiA9IGlvZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCk7CisgICAgICAgICAgICAgICAgICAgIC8vIElmIGNvbm5lY3QgZmFpbGVkLCBjYWxsYmFjayAiY29ubmVjdEZhaWxlZCIKKyAgICAgICAgICAgICAgICAgICAgLy8gc2hvdWxkIGJlIGludm9rZWQuCisgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RvciAhPSBudWxsICYmIFByb3h5Lk5PX1BST1hZICE9IGN1cnJlbnRQcm94eSkgeworICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3IuY29ubmVjdEZhaWxlZCh1cmksIGN1cnJlbnRQcm94eS5hZGRyZXNzKCksIGlvZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIWNvbm5lY3RPSykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5hYmxlIHRvIGNvbm5lY3QgdG8gc2VydmVyOiAiICsgZmFpbHVyZVJlYXNvbik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY29ubmVjdEludGVybmFsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHBvcnQgPSB1cmwuZ2V0UG9ydCgpOworICAgICAgICBpbnQgY29ubmVjdFRpbWVvdXQgPSBnZXRDb25uZWN0VGltZW91dCgpOworICAgICAgICBpZiAocG9ydCA8PSAwKSB7CisgICAgICAgICAgICBwb3J0ID0gRlRQX1BPUlQ7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGN1cnJlbnRQcm94eSA9PSBudWxsIHx8IFByb3h5LlR5cGUuSFRUUCA9PSBjdXJyZW50UHJveHkudHlwZSgpKSB7CisgICAgICAgICAgICBjb250cm9sU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY29udHJvbFNvY2tldCA9IG5ldyBTb2NrZXQoY3VycmVudFByb3h5KTsKKyAgICAgICAgfQorICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBhZGRyID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKGhvc3ROYW1lLCBwb3J0KTsKKyAgICAgICAgY29udHJvbFNvY2tldC5jb25uZWN0KGFkZHIsIGNvbm5lY3RUaW1lb3V0KTsKKyAgICAgICAgY29ubmVjdGVkID0gdHJ1ZTsKKyAgICAgICAgY3RybE91dHB1dCA9IGNvbnRyb2xTb2NrZXQuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGN0cmxJbnB1dCA9IGNvbnRyb2xTb2NrZXQuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgbG9naW4oKTsKKyAgICAgICAgc2V0VHlwZSgpOworICAgICAgICBpZiAoIWdldERvSW5wdXQoKSkgeworICAgICAgICAgICAgY2QoKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhY2NlcHRTb2NrZXQgPSBuZXcgU2VydmVyU29ja2V0KDApOworICAgICAgICAgICAgZGF0YVBvcnQgPSBhY2NlcHRTb2NrZXQuZ2V0TG9jYWxQb3J0KCk7CisgICAgICAgICAgICAvKiBDYW5ub3Qgc2V0IFJFVVNFQUREUiBzbyB3ZSBuZWVkIHRvIHNlbmQgYSBQT1JUIGNvbW1hbmQgKi8KKyAgICAgICAgICAgIHBvcnQoKTsKKyAgICAgICAgICAgIGlmIChjb25uZWN0VGltZW91dCA9PSAwKSB7CisgICAgICAgICAgICAgICAgLy8gc2V0IHRpbWVvdXQgcmF0aGVyIHRoYW4gemVybyBhcyBiZWZvcmUKKyAgICAgICAgICAgICAgICBjb25uZWN0VGltZW91dCA9IDMwMDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhY2NlcHRTb2NrZXQuc2V0U29UaW1lb3V0KGdldENvbm5lY3RUaW1lb3V0KCkpOworICAgICAgICAgICAgaWYgKGdldERvSW5wdXQoKSkgeworICAgICAgICAgICAgICAgIGdldEZpbGUoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc2VuZEZpbGUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGRhdGFTb2NrZXQgPSBhY2NlcHRTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgICAgICBkYXRhU29ja2V0LnNldFNvVGltZW91dChnZXRSZWFkVGltZW91dCgpKTsKKyAgICAgICAgICAgIGFjY2VwdFNvY2tldC5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ291bGQgbm90IGVzdGFibGlzaCBkYXRhIGNvbm5lY3Rpb24iKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZ2V0RG9JbnB1dCgpKSB7CisgICAgICAgICAgICBpbnB1dFN0cmVhbSA9IG5ldyBGdHBVUkxJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICAgICAgbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oZGF0YVNvY2tldC5nZXRJbnB1dFN0cmVhbSgpKSwgY29udHJvbFNvY2tldCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb250ZW50IHR5cGUgb2YgdGhlIHJlc291cmNlLiBKdXN0IHRha2VzIGEgZ3Vlc3MgYmFzZWQgb24gdGhlCisgICAgICogbmFtZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgeworICAgICAgICBTdHJpbmcgcmVzdWx0ID0gZ3Vlc3NDb250ZW50VHlwZUZyb21OYW1lKHVybC5nZXRGaWxlKCkpOworICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAiY29udGVudC91bmtub3duIjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBnZXRGaWxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHJlcGx5OworICAgICAgICBTdHJpbmcgZmlsZSA9IHVybC5nZXRGaWxlKCk7CisgICAgICAgIHdyaXRlKCJSRVRSICIgKyBmaWxlICsgIlxyXG4iKTsKKyAgICAgICAgcmVwbHkgPSBnZXRSZXBseSgpOworICAgICAgICBpZiAocmVwbHkgPT0gRlRQX05PVEZPVU5EICYmIGZpbGUubGVuZ3RoKCkgPiAwICYmIGZpbGUuY2hhckF0KDApID09ICcvJykgeworICAgICAgICAgICAgd3JpdGUoIlJFVFIgIiArIGZpbGUuc3Vic3RyaW5nKDEpICsgIlxyXG4iKTsKKyAgICAgICAgICAgIHJlcGx5ID0gZ2V0UmVwbHkoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShyZXBseSA9PSBGVFBfT1BFTkRBVEEgfHwgcmVwbHkgPT0gRlRQX1RSQU5TRkVST0spKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRmlsZU5vdEZvdW5kRXhjZXB0aW9uKCJVbmFibGUgdG8gcmV0cmlldmUgZmlsZTogIiArIHJlcGx5KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBpbnB1dCBzdHJlYW0gZm9yIHdyaXRpbmcgdG8gdGhpcyBVUkwgQ29ubmVjdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIGlucHV0IHN0cmVhbSB0byB3cml0ZSB0bworICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBDYW5ub3QgcmVhZCBmcm9tIFVSTCBvciBlcnJvciBjcmVhdGluZyBJbnB1dFN0cmVhbQorICAgICAqCisgICAgICogQHNlZSAjZ2V0Q29udGVudCgpCisgICAgICogQHNlZSAjZ2V0T3V0cHV0U3RyZWFtKCkKKyAgICAgKiBAc2VlIGphdmEuaW8uSW5wdXRTdHJlYW0KKyAgICAgKiBAc2VlIGphdmEuaW8uSU9FeGNlcHRpb24KKyAgICAgKgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghY29ubmVjdGVkKSB7CisgICAgICAgICAgICBjb25uZWN0KCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlucHV0U3RyZWFtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHBlcm1pc3Npb24gb2JqZWN0IChpbiB0aGlzIGNhc2UsIFNvY2tldFBlcm1pc3Npb24pIHdpdGggdGhlCisgICAgICogaG9zdCBhbmQgdGhlIHBvcnQgbnVtYmVyIGFzIHRoZSB0YXJnZXQgbmFtZSBhbmQgInJlc29sdmUsIGNvbm5lY3QiIGFzIHRoZQorICAgICAqIGFjdGlvbiBsaXN0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcGVybWlzc2lvbiBvYmplY3QgcmVxdWlyZWQgZm9yIHRoaXMgY29ubmVjdGlvbgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aHJvd24gd2hlbiBhbiBJTyBleGNlcHRpb24gb2NjdXJzIGR1cmluZyB0aGUgY3JlYXRpb24gb2YgdGhlCisgICAgICogICAgICAgICAgICAgcGVybWlzc2lvbiBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFBlcm1pc3Npb24gZ2V0UGVybWlzc2lvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBwb3J0ID0gdXJsLmdldFBvcnQoKTsKKyAgICAgICAgaWYgKHBvcnQgPD0gMCkgeworICAgICAgICAgICAgcG9ydCA9IEZUUF9QT1JUOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU29ja2V0UGVybWlzc2lvbihob3N0TmFtZSArICI6IiArIHBvcnQsICJjb25uZWN0LCByZXNvbHZlIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG91dHB1dCBzdHJlYW0gZm9yIHdyaXRpbmcgdG8gdGhpcyBVUkwgQ29ubmVjdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIG91dHB1dCBzdHJlYW0gdG8gd3JpdGUgdG8KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgd2hlbiB0aGUgT3V0cHV0U3RyZWFtIGNvdWxkIG5vdCBiZSBjcmVhdGVkCisgICAgICoKKyAgICAgKiBAc2VlICNnZXRDb250ZW50KCkKKyAgICAgKiBAc2VlICNnZXRJbnB1dFN0cmVhbSgpCisgICAgICogQHNlZSBqYXZhLmlvLklPRXhjZXB0aW9uCisgICAgICoKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT3V0cHV0U3RyZWFtIGdldE91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghY29ubmVjdGVkKSB7CisgICAgICAgICAgICBjb25uZWN0KCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRhdGFTb2NrZXQuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgZ2V0UmVwbHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gY29kZSA9IG5ldyBieXRlWzNdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvZGUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGZpbmFsIGludCB0bXAgPSBjdHJsSW5wdXQucmVhZCgpOworICAgICAgICAgICAgaWYgKHRtcCA9PSAtMSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvZGVbaV0gPSAoYnl0ZSkgdG1wOworICAgICAgICB9CisgICAgICAgIHJlcGx5Q29kZSA9IG5ldyBTdHJpbmcoY29kZSwgMCwgY29kZS5sZW5ndGgsIENoYXJzZXRzLklTT184ODU5XzEpOworCisgICAgICAgIGJvb2xlYW4gbXVsdGlsaW5lID0gZmFsc2U7CisgICAgICAgIGlmIChjdHJsSW5wdXQucmVhZCgpID09ICctJykgeworICAgICAgICAgICAgbXVsdGlsaW5lID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZWFkTGluZSgpOyAvKiBTa2lwIHRoZSByZXN0IG9mIHRoZSBmaXJzdCBsaW5lICovCisgICAgICAgIGlmIChtdWx0aWxpbmUpIHsKKyAgICAgICAgICAgIHdoaWxlIChyZWFkTXVsdGlMaW5lKCkpIHsvKiBSZWFkIGFsbCBvZiBhIG11bHRpbGluZSByZXBseSAqLworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLnBhcnNlSW50KHJlcGx5Q29kZSk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyAoSU9FeGNlcHRpb24pKG5ldyBJT0V4Y2VwdGlvbigicmVwbHkgY29kZSBpcyBpbnZhbGlkIikuaW5pdENhdXNlKGUpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBsb2dpbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByZXBseTsKKyAgICAgICAgcmVwbHkgPSBnZXRSZXBseSgpOworICAgICAgICBpZiAocmVwbHkgPT0gRlRQX1VTRVJSRUFEWSkgeworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJVbmFibGUgdG8gY29ubmVjdCB0byBzZXJ2ZXI6ICIgKyB1cmwuZ2V0SG9zdCgpKTsKKyAgICAgICAgfQorICAgICAgICB3cml0ZSgiVVNFUiAiICsgdXNlcm5hbWUgKyAiXHJcbiIpOworICAgICAgICByZXBseSA9IGdldFJlcGx5KCk7CisgICAgICAgIGlmIChyZXBseSA9PSBGVFBfUEFTV0QgfHwgcmVwbHkgPT0gRlRQX0xPR0dFRElOKSB7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlVuYWJsZSB0byBsb2cgaW4gdG8gc2VydmVyIChVU0VSKTogIiArIHVybC5nZXRIb3N0KCkpOworICAgICAgICB9CisgICAgICAgIGlmIChyZXBseSA9PSBGVFBfUEFTV0QpIHsKKyAgICAgICAgICAgIHdyaXRlKCJQQVNTICIgKyBwYXNzd29yZCArICJcclxuIik7CisgICAgICAgICAgICByZXBseSA9IGdldFJlcGx5KCk7CisgICAgICAgICAgICBpZiAoIShyZXBseSA9PSBGVFBfT0sgfHwgcmVwbHkgPT0gRlRQX1VTRVJSRUFEWSB8fCByZXBseSA9PSBGVFBfTE9HR0VESU4pKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJVbmFibGUgdG8gbG9nIGluIHRvIHNlcnZlciAoUEFTUyk6ICIgKyB1cmwuZ2V0SG9zdCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwb3J0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGUoIlBPUlQgIgorICAgICAgICAgICAgICAgICsgY29udHJvbFNvY2tldC5nZXRMb2NhbEFkZHJlc3MoKS5nZXRIb3N0QWRkcmVzcygpLnJlcGxhY2UoJy4nLAorICAgICAgICAgICAgICAgICAgICAgICAgJywnKSArICcsJyArIChkYXRhUG9ydCA+PiA4KSArICcsJworICAgICAgICAgICAgICAgICsgKGRhdGFQb3J0ICYgMjU1KQorICAgICAgICAgICAgICAgICsgIlxyXG4iKTsKKyAgICAgICAgaWYgKGdldFJlcGx5KCkgIT0gRlRQX09LKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlVuYWJsZSB0byBjb25maWd1cmUgZGF0YSBwb3J0Iik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGEgbGluZSBvZiB0ZXh0IGFuZCByZXR1cm4gaXQgZm9yIHBvc3NpYmxlIHBhcnNpbmcKKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyByZWFkTGluZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBpbnQgYzsKKyAgICAgICAgd2hpbGUgKChjID0gY3RybElucHV0LnJlYWQoKSkgIT0gJ1xuJykgeworICAgICAgICAgICAgc2IuYXBwZW5kKChjaGFyKSBjKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gcmVhZE11bHRpTGluZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBsaW5lID0gcmVhZExpbmUoKTsKKyAgICAgICAgaWYgKGxpbmUubGVuZ3RoKCkgPCA0KSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAobGluZS5zdWJzdHJpbmcoMCwgMykuZXF1YWxzKHJlcGx5Q29kZSkKKyAgICAgICAgICAgICAgICAmJiAobGluZS5jaGFyQXQoMykgPT0gKGNoYXIpIDMyKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIElzc3VlIHRoZSBTVE9SIGNvbW1hbmQgdG8gdGhlIHNlcnZlciB3aXRoIHRoZSBmaWxlIGFzIHRoZSBwYXJhbWV0ZXIKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2VuZEZpbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgcmVwbHk7CisgICAgICAgIHdyaXRlKCJTVE9SICIKKyAgICAgICAgICAgICAgICArIHVybC5nZXRGaWxlKCkuc3Vic3RyaW5nKHVybC5nZXRGaWxlKCkubGFzdEluZGV4T2YoJy8nKSArIDEsCisgICAgICAgICAgICAgICAgICAgICAgICB1cmwuZ2V0RmlsZSgpLmxlbmd0aCgpKSArICJcclxuIik7CisgICAgICAgIHJlcGx5ID0gZ2V0UmVwbHkoKTsKKyAgICAgICAgaWYgKCEocmVwbHkgPT0gRlRQX09QRU5EQVRBIHx8IHJlcGx5ID09IEZUUF9PSyB8fCByZXBseSA9PSBGVFBfREFUQU9QRU4pKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlVuYWJsZSB0byBzdG9yZSBmaWxlIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGZsYWcgaWYgdGhpcyA8Y29kZT5VUkxDb25uZWN0aW9uPC9jb2RlPiBzdXBwb3J0cyBpbnB1dCAocmVhZCkuCisgICAgICogSXQgY2Fubm90IGJlIHNldCBhZnRlciB0aGUgY29ubmVjdGlvbiBpcyBtYWRlLiBGdHBVUkxDb25uZWN0aW9ucyBjYW5ub3QKKyAgICAgKiBzdXBwb3J0IGJvdGggaW5wdXQgYW5kIG91dHB1dAorICAgICAqCisgICAgICogQHBhcmFtIG5ld1ZhbHVlICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFcnJvcgorICAgICAqICAgICAgICAgICAgIHdoZW4gdGhpcyBtZXRob2QgYXR0ZW1wdHMgdG8gY2hhbmdlIHRoZSBmbGFnIGFmdGVyIGNvbm5lY3RlZAorICAgICAqCisgICAgICogQHNlZSAjZG9JbnB1dAorICAgICAqIEBzZWUgI2dldERvSW5wdXQoKQorICAgICAqIEBzZWUgamF2YS5sYW5nLklsbGVnYWxBY2Nlc3NFcnJvcgorICAgICAqIEBzZWUgI3NldERvSW5wdXQoYm9vbGVhbikKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXREb0lucHV0KGJvb2xlYW4gbmV3VmFsdWUpIHsKKyAgICAgICAgaWYgKGNvbm5lY3RlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBY2Nlc3NFcnJvcigpOworICAgICAgICB9CisgICAgICAgIHRoaXMuZG9JbnB1dCA9IG5ld1ZhbHVlOworICAgICAgICB0aGlzLmRvT3V0cHV0ID0gIW5ld1ZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZmxhZyBpZiB0aGlzIDxjb2RlPlVSTENvbm5lY3Rpb248L2NvZGU+IHN1cHBvcnRzIG91dHB1dChyZWFkKS4KKyAgICAgKiBJdCBjYW5ub3QgYmUgc2V0IGFmdGVyIHRoZSBjb25uZWN0aW9uIGlzIG1hZGUuXCBGdHBVUkxDb25uZWN0aW9ucyBjYW5ub3QKKyAgICAgKiBzdXBwb3J0IGJvdGggaW5wdXQgYW5kIG91dHB1dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdWYWx1ZQorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQWNjZXNzRXJyb3IKKyAgICAgKiAgICAgICAgICAgICB3aGVuIHRoaXMgbWV0aG9kIGF0dGVtcHRzIHRvIGNoYW5nZSB0aGUgZmxhZyBhZnRlciBjb25uZWN0ZWQKKyAgICAgKgorICAgICAqIEBzZWUgI2RvT3V0cHV0CisgICAgICogQHNlZSBqYXZhLmxhbmcuSWxsZWdhbEFjY2Vzc0Vycm9yCisgICAgICogQHNlZSAjc2V0RG9PdXRwdXQoYm9vbGVhbikKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXREb091dHB1dChib29sZWFuIG5ld1ZhbHVlKSB7CisgICAgICAgIGlmIChjb25uZWN0ZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQWNjZXNzRXJyb3IoKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmRvT3V0cHV0ID0gbmV3VmFsdWU7CisgICAgICAgIHRoaXMuZG9JbnB1dCA9ICFuZXdWYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHR5cGUgb2YgdGhlIGZpbGUgdHJhbnNmZXIuIE9ubHkgSW1hZ2UgaXMgc3VwcG9ydGVkCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNldFR5cGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3cml0ZSgiVFlQRSBJXHJcbiIpOworICAgICAgICBpZiAoZ2V0UmVwbHkoKSAhPSBGVFBfT0spIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5hYmxlIHRvIHNldCB0cmFuc2ZlciB0eXBlIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGUoU3RyaW5nIGNvbW1hbmQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGN0cmxPdXRwdXQud3JpdGUoY29tbWFuZC5nZXRCeXRlcyhDaGFyc2V0cy5JU09fODg1OV8xKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L3VybC9GdHBVUkxJbnB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L3VybC9GdHBVUkxJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJhODg2NWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvdXJsL0Z0cFVSTElucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw4MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLm5ldC51cmw7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuU29ja2V0OworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKKworLyoqCisgKiBUaGlzIGNsYXNzIGFzc29jaWF0ZXMgYSBnaXZlbiBpbnB1dFN0cmVhbSB3aXRoIGEgY29udHJvbCBzb2NrZXQuIFRoaXMgZW5zdXJlcworICogdGhlIGNvbnRyb2wgc29ja2V0IE9iamVjdCBzdGF5cyBsaXZlIHdoaWxlIHRoZSBzdHJlYW0gaXMgaW4gdXNlCisgKi8KK2NsYXNzIEZ0cFVSTElucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworCisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBpczsgLy8gQWN0dWFsIGlucHV0IHN0cmVhbQorCisgICAgcHJpdmF0ZSBTb2NrZXQgY29udHJvbFNvY2tldDsKKworICAgIHB1YmxpYyBGdHBVUkxJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpcywgU29ja2V0IGNvbnRyb2xTb2NrZXQpIHsKKyAgICAgICAgdGhpcy5pcyA9IGlzOworICAgICAgICB0aGlzLmNvbnRyb2xTb2NrZXQgPSBjb250cm9sU29ja2V0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBpcy5yZWFkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGJ5dGVbXSBidWYsIGludCBvZmYsIGludCBuYnl0ZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBpcy5yZWFkKGJ1Ziwgb2ZmLCBuYnl0ZXMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZXNldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlzLnJlc2V0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIG1hcmsoaW50IGxpbWl0KSB7CisgICAgICAgIGlzLm1hcmsobGltaXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hcmtTdXBwb3J0ZWQoKSB7CisgICAgICAgIHJldHVybiBpcy5tYXJrU3VwcG9ydGVkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgIElvVXRpbHMuY2xvc2VRdWlldGx5KGlzKTsKKyAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkoY29udHJvbFNvY2tldCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gaXMuYXZhaWxhYmxlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgc2tpcChsb25nIGJ5dGVDb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGlzLnNraXAoYnl0ZUNvdW50KTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC91cmwvSmFySGFuZGxlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L3VybC9KYXJIYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2EwMmNhMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC91cmwvSmFySGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsMTA3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUubmV0LnVybDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTFN0cmVhbUhhbmRsZXI7CisKK3B1YmxpYyBjbGFzcyBKYXJIYW5kbGVyIGV4dGVuZHMgVVJMU3RyZWFtSGFuZGxlciB7CisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvbm5lY3Rpb24gdG8gdGhlIGphciBmaWxlIHBvaW50ZWQgYnkgdGhpcyA8Y29kZT5VUkw8L2NvZGU+CisgICAgICogaW4gdGhlIGZpbGUgc3lzdGVtCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGphdmEubmV0LlVSTENvbm5lY3Rpb24gQSBjb25uZWN0aW9uIHRvIHRoZSByZXNvdXJjZSBwb2ludGVkIGJ5CisgICAgICogICAgICAgICB0aGlzIHVybC4KKyAgICAgKiBAcGFyYW0gdQorICAgICAqICAgICAgICAgICAgamF2YS5uZXQuVVJMIFRoZSBVUkwgdG8gd2hpY2ggdGhlIGNvbm5lY3Rpb24gaXMgcG9pbnRpbmcgdG8KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB0aHJvd24gaWYgYW4gSU8gZXJyb3Igb2NjdXJzIHdoZW4gdGhpcyBtZXRob2QgdHJpZXMgdG8KKyAgICAgKiAgICAgICAgICAgICBlc3RhYmxpc2ggY29ubmVjdGlvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgVVJMQ29ubmVjdGlvbiBvcGVuQ29ubmVjdGlvbihVUkwgdSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBKYXJVUkxDb25uZWN0aW9uSW1wbCh1KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmwKKyAgICAgKiAgICAgICAgICAgIFVSTCB0aGUgY29udGV4dCBVUkwKKyAgICAgKiBAcGFyYW0gc3BlYworICAgICAqICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB0aGUgc3BlYyBzdHJpbmcKKyAgICAgKiBAcGFyYW0gc3RhcnQKKyAgICAgKiAgICAgICAgICAgIGludCB0aGUgbG9jYXRpb24gdG8gc3RhcnQgcGFyc2luZyBmcm9tCisgICAgICogQHBhcmFtIGxpbWl0CisgICAgICogICAgICAgICAgICBpbnQgdGhlIGxvY2F0aW9uIHdoZXJlIHBhcnNpbmcgZW5kcworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHBhcnNlVVJMKFVSTCB1cmwsIFN0cmluZyBzcGVjLCBpbnQgc3RhcnQsIGludCBsaW1pdCkgeworICAgICAgICBTdHJpbmcgZmlsZSA9IHVybC5nZXRGaWxlKCk7CisgICAgICAgIGlmIChmaWxlID09IG51bGwpIHsKKyAgICAgICAgICAgIGZpbGUgPSAiIjsKKyAgICAgICAgfQorICAgICAgICBpZiAobGltaXQgPiBzdGFydCkgeworICAgICAgICAgICAgc3BlYyA9IHNwZWMuc3Vic3RyaW5nKHN0YXJ0LCBsaW1pdCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzcGVjID0gIiI7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNwZWMuaW5kZXhPZigiIS8iKSA9PSAtMSAmJiAoZmlsZS5pbmRleE9mKCIhLyIpID09IC0xKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJDYW5ub3QgZmluZCBcIiEvXCIiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZmlsZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIGZpbGUgPSBzcGVjOworICAgICAgICB9IGVsc2UgaWYgKHNwZWMuY2hhckF0KDApID09ICcvJykgeworICAgICAgICAgICAgZmlsZSA9IGZpbGUuc3Vic3RyaW5nKDAsIGZpbGUuaW5kZXhPZignIScpICsgMSkgKyBzcGVjOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW50IGlkeCA9IGZpbGUuaW5kZXhPZignIScpOworICAgICAgICAgICAgU3RyaW5nIHRtcEZpbGUgPSBmaWxlLnN1YnN0cmluZyhpZHggKyAxLCBmaWxlLmxhc3RJbmRleE9mKCcvJykgKyAxKSArIHNwZWM7CisgICAgICAgICAgICB0bXBGaWxlID0gVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aCh0bXBGaWxlLCB0cnVlKTsKKyAgICAgICAgICAgIGZpbGUgPSBmaWxlLnN1YnN0cmluZygwLCBpZHggKyAxKSArIHRtcEZpbGU7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgdGhlIGVtYmVkZGVkIHVybCBpcyB2YWxpZAorICAgICAgICAgICAgbmV3IFVSTChmaWxlKTsKKyAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIHNldFVSTCh1cmwsICJqYXIiLCAiIiwgLTEsIG51bGwsIG51bGwsIGZpbGUsIG51bGwsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEJ1aWxkIGFuZCByZXR1cm4gdGhlIGV4dGVybmFsaXplZCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdXJsLgorICAgICAqCisgICAgICogQHJldHVybiBTdHJpbmcgdGhlIGV4dGVybmFsaXplZCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdXJsCisgICAgICogQHBhcmFtIHVybAorICAgICAqICAgICAgICAgICAgYSBVUkwKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHRvRXh0ZXJuYWxGb3JtKFVSTCB1cmwpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIHNiLmFwcGVuZCgiamFyOiIpOworICAgICAgICBzYi5hcHBlbmQodXJsLmdldEZpbGUoKSk7CisgICAgICAgIFN0cmluZyByZWYgPSB1cmwuZ2V0UmVmKCk7CisgICAgICAgIGlmIChyZWYgIT0gbnVsbCkgeworICAgICAgICAgICAgc2IuYXBwZW5kKHJlZik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L3VybC9KYXJVUkxDb25uZWN0aW9uSW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvbmV0L3VybC9KYXJVUkxDb25uZWN0aW9uSW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlhMmM4OTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvdXJsL0phclVSTENvbm5lY3Rpb25JbXBsLmphdmEKQEAgLTAsMCArMSwzODYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5uZXQudXJsOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5Db250ZW50SGFuZGxlcjsKK2ltcG9ydCBqYXZhLm5ldC5Db250ZW50SGFuZGxlckZhY3Rvcnk7CitpbXBvcnQgamF2YS5uZXQuSmFyVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmEudXRpbC5qYXIuSmFyRW50cnk7CitpbXBvcnQgamF2YS51dGlsLmphci5KYXJGaWxlOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRmlsZTsKK2ltcG9ydCBsaWJjb3JlLm5ldC5VcmlDb2RlYzsKKworLyoqCisgKiBUaGlzIHN1YmNsYXNzIGV4dGVuZHMge0Bjb2RlIFVSTENvbm5lY3Rpb259LgorICogPHA+CisgKgorICogVGhpcyBjbGFzcyBpcyByZXNwb25zaWJsZSBmb3IgY29ubmVjdGluZyBhbmQgcmV0cmlldmluZyByZXNvdXJjZXMgZnJvbSBhIEphcgorICogZmlsZSB3aGljaCBjYW4gYmUgYW55d2hlcmUgdGhhdCBjYW4gYmUgcmVmZXJyZWQgdG8gYnkgYW4gVVJMLgorICovCitwdWJsaWMgY2xhc3MgSmFyVVJMQ29ubmVjdGlvbkltcGwgZXh0ZW5kcyBKYXJVUkxDb25uZWN0aW9uIHsKKworICAgIHN0YXRpYyBIYXNoTWFwPFVSTCwgSmFyRmlsZT4gamFyQ2FjaGUgPSBuZXcgSGFzaE1hcDxVUkwsIEphckZpbGU+KCk7CisKKyAgICBwcml2YXRlIFVSTCBqYXJGaWxlVVJMOworCisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBqYXJJbnB1dDsKKworICAgIHByaXZhdGUgSmFyRmlsZSBqYXJGaWxlOworCisgICAgcHJpdmF0ZSBKYXJFbnRyeSBqYXJFbnRyeTsKKworICAgIHByaXZhdGUgYm9vbGVhbiBjbG9zZWQ7CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gdXJsCisgICAgICogICAgICAgICAgICB0aGUgVVJMIG9mIHRoZSBKQVIKKyAgICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZSBVUkwgaXMgbWFsZm9ybWVkCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBvcGVuaW5nIHRoZSBjb25uZWN0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBKYXJVUkxDb25uZWN0aW9uSW1wbChVUkwgdXJsKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLAorICAgICAgICAgICAgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcih1cmwpOworICAgICAgICBqYXJGaWxlVVJMID0gZ2V0SmFyRmlsZVVSTCgpOworICAgICAgICBqYXJGaWxlVVJMQ29ubmVjdGlvbiA9IGphckZpbGVVUkwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEubmV0LlVSTENvbm5lY3Rpb24jY29ubmVjdCgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY29ubmVjdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghY29ubmVjdGVkKSB7CisgICAgICAgICAgICBmaW5kSmFyRmlsZSgpOyAvLyBlbnN1cmUgdGhlIGZpbGUgY2FuIGJlIGZvdW5kCisgICAgICAgICAgICBmaW5kSmFyRW50cnkoKTsgLy8gZW5zdXJlIHRoZSBlbnRyeSwgaWYgYW55LCBjYW4gYmUgZm91bmQKKyAgICAgICAgICAgIGNvbm5lY3RlZCA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBKYXIgZmlsZSByZWZlcnJlZCBieSB0aGlzIHtAY29kZSBVUkxDb25uZWN0aW9ufS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIEpBUiBmaWxlIHJlZmVyZW5jZWQgYnkgdGhpcyBjb25uZWN0aW9uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgdGhyb3duIGlmIGFuIElPIGVycm9yIG9jY3VycyB3aGlsZSBjb25uZWN0aW5nIHRvIHRoZQorICAgICAqICAgICAgICAgICAgIHJlc291cmNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBKYXJGaWxlIGdldEphckZpbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjb25uZWN0KCk7CisgICAgICAgIHJldHVybiBqYXJGaWxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIEphciBmaWxlIHJlZmVycmVkIGJ5IHRoaXMge0Bjb2RlIFVSTENvbm5lY3Rpb259CisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSU8gZXJyb3Igb2NjdXJzIHdoaWxlIGNvbm5lY3RpbmcgdG8gdGhlIHJlc291cmNlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBmaW5kSmFyRmlsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEphckZpbGUgamFyID0gbnVsbDsKKyAgICAgICAgaWYgKGdldFVzZUNhY2hlcygpKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGphckNhY2hlKSB7CisgICAgICAgICAgICAgICAgamFyRmlsZSA9IGphckNhY2hlLmdldChqYXJGaWxlVVJMKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChqYXJGaWxlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBqYXIgPSBvcGVuSmFyRmlsZSgpOworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoamFyQ2FjaGUpIHsKKyAgICAgICAgICAgICAgICAgICAgamFyRmlsZSA9IGphckNhY2hlLmdldChqYXJGaWxlVVJMKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGphckZpbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgamFyQ2FjaGUucHV0KGphckZpbGVVUkwsIGphcik7CisgICAgICAgICAgICAgICAgICAgICAgICBqYXJGaWxlID0gamFyOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgamFyLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBqYXJGaWxlID0gb3BlbkphckZpbGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChqYXJGaWxlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgSmFyRmlsZSBvcGVuSmFyRmlsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChqYXJGaWxlVVJMLmdldFByb3RvY29sKCkuZXF1YWxzKCJmaWxlIikpIHsKKyAgICAgICAgICAgIFN0cmluZyBkZWNvZGVkRmlsZSA9IFVyaUNvZGVjLmRlY29kZShqYXJGaWxlVVJMLmdldEZpbGUoKSk7CisgICAgICAgICAgICByZXR1cm4gbmV3IEphckZpbGUobmV3IEZpbGUoZGVjb2RlZEZpbGUpLCB0cnVlLCBaaXBGaWxlLk9QRU5fUkVBRCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBpcyA9IGphckZpbGVVUkwub3BlbkNvbm5lY3Rpb24oKS5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIGZvcyA9IG51bGw7CisgICAgICAgICAgICAgICAgSmFyRmlsZSByZXN1bHQgPSBudWxsOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIEZpbGUgdGVtcEphciA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoImh5amFyXyIsICIudG1wIiwgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgIHRlbXBKYXIuZGVsZXRlT25FeGl0KCk7CisgICAgICAgICAgICAgICAgICAgIGZvcyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKHRlbXBKYXIpOworICAgICAgICAgICAgICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbNDA5Nl07CisgICAgICAgICAgICAgICAgICAgIGludCBuYnl0ZXMgPSAwOworICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKG5ieXRlcyA9IGlzLnJlYWQoYnVmKSkgPiAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZm9zLndyaXRlKGJ1ZiwgMCwgbmJ5dGVzKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBmb3MuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBKYXJGaWxlKHRlbXBKYXIsIHRydWUsIFppcEZpbGUuT1BFTl9SRUFEIHwgWmlwRmlsZS5PUEVOX0RFTEVURSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICBpZiAoZm9zICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9zLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBpZiAoaXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIEphckVudHJ5IG9mIHRoZSBlbnRyeSByZWZlcmVuY2VkIGJ5IHRoaXMge0Bjb2RlCisgICAgICogVVJMQ29ubmVjdGlvbn0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBKYXJFbnRyeSByZWZlcmVuY2VkCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgYW4gSU8gZXJyb3Igb2NjdXJzIHdoaWxlIGdldHRpbmcgdGhlIGVudHJ5CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEphckVudHJ5IGdldEphckVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY29ubmVjdCgpOworICAgICAgICByZXR1cm4gamFyRW50cnk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb29rIHVwIHRoZSBKYXJFbnRyeSBvZiB0aGUgZW50cnkgcmVmZXJlbmNlZCBieSB0aGlzIHtAY29kZQorICAgICAqIFVSTENvbm5lY3Rpb259LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBmaW5kSmFyRW50cnkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoZ2V0RW50cnlOYW1lKCkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGphckVudHJ5ID0gamFyRmlsZS5nZXRKYXJFbnRyeShnZXRFbnRyeU5hbWUoKSk7CisgICAgICAgIGlmIChqYXJFbnRyeSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRmlsZU5vdEZvdW5kRXhjZXB0aW9uKGdldEVudHJ5TmFtZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gaW5wdXQgc3RyZWFtIGZvciByZWFkaW5nIGZyb20gdGhpcyBVUkwgQ29ubmVjdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGlucHV0IHN0cmVhbQorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIElPIGVycm9yIG9jY3VycyB3aGlsZSBjb25uZWN0aW5nIHRvIHRoZSByZXNvdXJjZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY2xvc2VkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJKYXJVUkxDb25uZWN0aW9uIElucHV0U3RyZWFtIGhhcyBiZWVuIGNsb3NlZCIpOworICAgICAgICB9CisgICAgICAgIGNvbm5lY3QoKTsKKyAgICAgICAgaWYgKGphcklucHV0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBqYXJJbnB1dDsKKyAgICAgICAgfQorICAgICAgICBpZiAoamFyRW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJKYXIgZW50cnkgbm90IHNwZWNpZmllZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBqYXJJbnB1dCA9IG5ldyBKYXJVUkxDb25uZWN0aW9uSW5wdXRTdHJlYW0oamFyRmlsZQorICAgICAgICAgICAgICAgIC5nZXRJbnB1dFN0cmVhbShqYXJFbnRyeSksIGphckZpbGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNvbnRlbnQgdHlwZSBvZiB0aGUgcmVzb3VyY2UuIEZvciBqYXIgZmlsZSBpdHNlbGYKKyAgICAgKiAieC1qYXZhL2phciIgc2hvdWxkIGJlIHJldHVybmVkLCBmb3IgamFyIGVudHJpZXMgdGhlIGNvbnRlbnQgdHlwZSBvZiB0aGUKKyAgICAgKiBlbnRyeSBzaG91bGQgYmUgcmV0dXJuZWQuIFJldHVybnMgbm9uLW51bGwgcmVzdWx0cyAoImNvbnRlbnQvdW5rbm93biIgZm9yCisgICAgICogdW5rbm93biB0eXBlcykuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb250ZW50IHR5cGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgeworICAgICAgICBpZiAodXJsLmdldEZpbGUoKS5lbmRzV2l0aCgiIS8iKSkgeworICAgICAgICAgICAgLy8gdGhlIHR5cGUgZm9yIGphciBmaWxlIGl0c2VsZiBpcyBhbHdheXMgIngtamF2YS9qYXIiCisgICAgICAgICAgICByZXR1cm4gIngtamF2YS9qYXIiOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBjVHlwZSA9IG51bGw7CisgICAgICAgIFN0cmluZyBlbnRyeU5hbWUgPSBnZXRFbnRyeU5hbWUoKTsKKworICAgICAgICBpZiAoZW50cnlOYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGFuIEphciBFbnRyeSwgZ2V0IHRoZSBjb250ZW50IHR5cGUgZnJvbSB0aGUgbmFtZQorICAgICAgICAgICAgY1R5cGUgPSBndWVzc0NvbnRlbnRUeXBlRnJvbU5hbWUoZW50cnlOYW1lKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY29ubmVjdCgpOworICAgICAgICAgICAgICAgIGNUeXBlID0gamFyRmlsZVVSTENvbm5lY3Rpb24uZ2V0Q29udGVudFR5cGUoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgICAgIC8vIElnbm9yZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChjVHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICBjVHlwZSA9ICJjb250ZW50L3Vua25vd24iOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjVHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb250ZW50IGxlbmd0aCBvZiB0aGUgcmVzb3VyY2UuIFRlc3QgY2FzZXMgcmV2ZWFsIHRoYXQgaWYgdGhlCisgICAgICogVVJMIGlzIHJlZmVycmluZyB0byBhIEphciBmaWxlLCB0aGlzIG1ldGhvZCBhbnN3ZXJzIGEgY29udGVudC1sZW5ndGgKKyAgICAgKiByZXR1cm5lZCBieSBVUkxDb25uZWN0aW9uLiBGb3IgamFyIGVudHJ5IGl0IHNob3VsZCByZXR1cm4gaXQncyBzaXplLgorICAgICAqIE90aGVyd2lzZSwgaXQgd2lsbCByZXR1cm4gLTEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb250ZW50IGxlbmd0aAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0Q29udGVudExlbmd0aCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm5lY3QoKTsKKyAgICAgICAgICAgIGlmIChqYXJFbnRyeSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGphckZpbGVVUkxDb25uZWN0aW9uLmdldENvbnRlbnRMZW5ndGgoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAoaW50KSBnZXRKYXJFbnRyeSgpLmdldFNpemUoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gSWdub3JlZAorICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBvYmplY3QgcG9pbnRlZCBieSB0aGlzIHtAY29kZSBVUkx9LiBJZiB0aGlzIFVSTENvbm5lY3Rpb24gaXMKKyAgICAgKiBwb2ludGluZyB0byBhIEphciBGaWxlIChubyBKYXIgRW50cnkpLCB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiBhIHtAY29kZQorICAgICAqIEphckZpbGV9IElmIHRoZXJlIGlzIGEgSmFyIEVudHJ5LCBpdCB3aWxsIHJldHVybiB0aGUgb2JqZWN0IGNvcnJlc3BvbmRpbmcKKyAgICAgKiB0byB0aGUgSmFyIGVudHJ5IGNvbnRlbnQgdHlwZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBub24tbnVsbCBvYmplY3QKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiBhbiBJTyBlcnJvciBvY2N1cnJlZAorICAgICAqCisgICAgICogQHNlZSBDb250ZW50SGFuZGxlcgorICAgICAqIEBzZWUgQ29udGVudEhhbmRsZXJGYWN0b3J5CisgICAgICogQHNlZSBqYXZhLmlvLklPRXhjZXB0aW9uCisgICAgICogQHNlZSAjc2V0Q29udGVudEhhbmRsZXJGYWN0b3J5KENvbnRlbnRIYW5kbGVyRmFjdG9yeSkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGdldENvbnRlbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjb25uZWN0KCk7CisgICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIEphciBFbnRyeSwgcmV0dXJuIGEgSmFyRmlsZQorICAgICAgICBpZiAoamFyRW50cnkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGphckZpbGU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHN1cGVyLmdldENvbnRlbnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwZXJtaXNzaW9uLCBpbiB0aGlzIGNhc2UgdGhlIHN1YmNsYXNzLCBGaWxlUGVybWlzc2lvbiBvYmplY3QKKyAgICAgKiB3aGljaCByZXByZXNlbnRzIHRoZSBwZXJtaXNzaW9uIG5lY2Vzc2FyeSBmb3IgdGhpcyBVUkxDb25uZWN0aW9uIHRvCisgICAgICogZXN0YWJsaXNoIHRoZSBjb25uZWN0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcGVybWlzc2lvbiByZXF1aXJlZCBmb3IgdGhpcyBVUkxDb25uZWN0aW9uLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHRocm93biB3aGVuIGFuIElPIGV4Y2VwdGlvbiBvY2N1cnMgd2hpbGUgY3JlYXRpbmcgdGhlCisgICAgICogICAgICAgICAgICAgcGVybWlzc2lvbi4KKyAgICAgKi8KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBQZXJtaXNzaW9uIGdldFBlcm1pc3Npb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gamFyRmlsZVVSTENvbm5lY3Rpb24uZ2V0UGVybWlzc2lvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGdldFVzZUNhY2hlcygpIHsKKyAgICAgICAgcmV0dXJuIGphckZpbGVVUkxDb25uZWN0aW9uLmdldFVzZUNhY2hlcygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFVzZUNhY2hlcyhib29sZWFuIHVzZWNhY2hlcykgeworICAgICAgICBqYXJGaWxlVVJMQ29ubmVjdGlvbi5zZXRVc2VDYWNoZXModXNlY2FjaGVzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXREZWZhdWx0VXNlQ2FjaGVzKCkgeworICAgICAgICByZXR1cm4gamFyRmlsZVVSTENvbm5lY3Rpb24uZ2V0RGVmYXVsdFVzZUNhY2hlcygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldERlZmF1bHRVc2VDYWNoZXMoYm9vbGVhbiBkZWZhdWx0dXNlY2FjaGVzKSB7CisgICAgICAgIGphckZpbGVVUkxDb25uZWN0aW9uLnNldERlZmF1bHRVc2VDYWNoZXMoZGVmYXVsdHVzZWNhY2hlcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoZSBjYWNoZWQgZmlsZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGNsb3NlQ2FjaGVkRmlsZXMoKSB7CisgICAgICAgIFNldDxNYXAuRW50cnk8VVJMLCBKYXJGaWxlPj4gcyA9IGphckNhY2hlLmVudHJ5U2V0KCk7CisgICAgICAgIHN5bmNocm9uaXplZCAoamFyQ2FjaGUpIHsKKyAgICAgICAgICAgIEl0ZXJhdG9yPE1hcC5FbnRyeTxVUkwsIEphckZpbGU+PiBpID0gcy5pdGVyYXRvcigpOworICAgICAgICAgICAgd2hpbGUgKGkuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgWmlwRmlsZSB6aXAgPSBpLm5leHQoKS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgICAgICAgICBpZiAoemlwICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHppcC5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAvLyBJZ25vcmVkCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBKYXJVUkxDb25uZWN0aW9uSW5wdXRTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJJbnB1dFN0cmVhbSB7CisgICAgICAgIGZpbmFsIEphckZpbGUgamFyRmlsZTsKKworICAgICAgICBwcm90ZWN0ZWQgSmFyVVJMQ29ubmVjdGlvbklucHV0U3RyZWFtKElucHV0U3RyZWFtIGluLCBKYXJGaWxlIGZpbGUpIHsKKyAgICAgICAgICAgIHN1cGVyKGluKTsKKyAgICAgICAgICAgIGphckZpbGUgPSBmaWxlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyLmNsb3NlKCk7CisgICAgICAgICAgICBpZiAoIWdldFVzZUNhY2hlcygpKSB7CisgICAgICAgICAgICAgICAgY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBqYXJGaWxlLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvdXJsL1VybFV0aWxzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS9uZXQvdXJsL1VybFV0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWQ1ZjI3ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL25ldC91cmwvVXJsVXRpbHMuamF2YQpAQCAtMCwwICsxLDE0MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5uZXQudXJsOworCitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworcHVibGljIGZpbmFsIGNsYXNzIFVybFV0aWxzIHsKKyAgICBwcml2YXRlIFVybFV0aWxzKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHBhdGggd2lsbCByZWxhdGl2ZSBwYXRoIHNlZ21lbnRzIGxpa2UgIi4uIiBhbmQgIi4iIHJlc29sdmVkLgorICAgICAqIFRoZSByZXR1cm5lZCBwYXRoIHdpbGwgbm90IG5lY2Vzc2FyaWx5IHN0YXJ0IHdpdGggYSAiLyIgY2hhcmFjdGVyLiBUaGlzCisgICAgICogaGFuZGxlcyAiLi4iIGFuZCAiLiIgc2VnbWVudHMgYXQgYm90aCB0aGUgYmVnaW5uaW5nIGFuZCBlbmQgb2YgdGhlIHBhdGguCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGlzY2FyZFJlbGF0aXZlUHJlZml4IHRydWUgdG8gcmVtb3ZlIGxlYWRpbmcgIi4uIiBzZWdtZW50cyBmcm9tCisgICAgICogICAgIHRoZSBwYXRoLiBUaGlzIGlzIGFwcHJvcHJpYXRlIGZvciBwYXRocyB0aGF0IGFyZSBrbm93biB0byBiZQorICAgICAqICAgICBhYnNvbHV0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBjYW5vbmljYWxpemVQYXRoKFN0cmluZyBwYXRoLCBib29sZWFuIGRpc2NhcmRSZWxhdGl2ZVByZWZpeCkgeworICAgICAgICAvLyB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBjdXJyZW50IHBhdGggc2VnbWVudAorICAgICAgICBpbnQgc2VnbWVudFN0YXJ0ID0gMDsKKworICAgICAgICAvLyB0aGUgbnVtYmVyIG9mIHNlZ21lbnRzIHNlZW4gdGh1cyBmYXIgdGhhdCBjYW4gYmUgZXJhc2VkIGJ5IHNlcXVlbmNlcyBvZiAnLi4nLgorICAgICAgICBpbnQgZGVsZXRhYmxlU2VnbWVudHMgPSAwOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IHBhdGgubGVuZ3RoKCk7ICkgeworICAgICAgICAgICAgaW50IG5leHRTZWdtZW50U3RhcnQ7CisgICAgICAgICAgICBpZiAoaSA9PSBwYXRoLmxlbmd0aCgpKSB7CisgICAgICAgICAgICAgICAgbmV4dFNlZ21lbnRTdGFydCA9IGk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHBhdGguY2hhckF0KGkpID09ICcvJykgeworICAgICAgICAgICAgICAgIG5leHRTZWdtZW50U3RhcnQgPSBpICsgMTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogV2UndmUgZW5jb3VudGVyZWQgZWl0aGVyIHRoZSBlbmQgb2YgYSBzZWdtZW50IG9yIHRoZSBlbmQgb2YgdGhlCisgICAgICAgICAgICAgKiBjb21wbGV0ZSBwYXRoLiBJZiB0aGUgZmluYWwgc2VnbWVudCB3YXMgIi4iIG9yICIuLiIsIHJlbW92ZSB0aGUKKyAgICAgICAgICAgICAqIGFwcHJvcHJpYXRlIHNlZ21lbnRzIG9mIHRoZSBwYXRoLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAoaSA9PSBzZWdtZW50U3RhcnQgKyAxICYmIHBhdGgucmVnaW9uTWF0Y2hlcyhzZWdtZW50U3RhcnQsICIuIiwgMCwgMSkpIHsKKyAgICAgICAgICAgICAgICAvLyBHaXZlbiAiYWJjL2RlZi8uL2doaSIsIHJlbW92ZSAiLi8iIHRvIGdldCAiYWJjL2RlZi9naGkiLgorICAgICAgICAgICAgICAgIHBhdGggPSBwYXRoLnN1YnN0cmluZygwLCBzZWdtZW50U3RhcnQpICsgcGF0aC5zdWJzdHJpbmcobmV4dFNlZ21lbnRTdGFydCk7CisgICAgICAgICAgICAgICAgaSA9IHNlZ21lbnRTdGFydDsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA9PSBzZWdtZW50U3RhcnQgKyAyICYmIHBhdGgucmVnaW9uTWF0Y2hlcyhzZWdtZW50U3RhcnQsICIuLiIsIDAsIDIpKSB7CisgICAgICAgICAgICAgICAgaWYgKGRlbGV0YWJsZVNlZ21lbnRzID4gMCB8fCBkaXNjYXJkUmVsYXRpdmVQcmVmaXgpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gR2l2ZW4gImFiYy9kZWYvLi4vZ2hpIiwgcmVtb3ZlICJkZWYvLi4vIiB0byBnZXQgImFiYy9naGkiLgorICAgICAgICAgICAgICAgICAgICBkZWxldGFibGVTZWdtZW50cy0tOworICAgICAgICAgICAgICAgICAgICBpbnQgcHJldlNlZ21lbnRTdGFydCA9IHBhdGgubGFzdEluZGV4T2YoJy8nLCBzZWdtZW50U3RhcnQgLSAyKSArIDE7CisgICAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXRoLnN1YnN0cmluZygwLCBwcmV2U2VnbWVudFN0YXJ0KSArIHBhdGguc3Vic3RyaW5nKG5leHRTZWdtZW50U3RhcnQpOworICAgICAgICAgICAgICAgICAgICBpID0gc2VnbWVudFN0YXJ0ID0gcHJldlNlZ21lbnRTdGFydDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAvLyBUaGVyZSdzIG5vIHNlZ21lbnQgdG8gZGVsZXRlOyB0aGlzICIuLiIgc2VnbWVudCBtdXN0IGJlIHJldGFpbmVkLgorICAgICAgICAgICAgICAgICAgICBpKys7CisgICAgICAgICAgICAgICAgICAgIHNlZ21lbnRTdGFydCA9IGk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAoaSA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgZGVsZXRhYmxlU2VnbWVudHMrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgICAgIHNlZ21lbnRTdGFydCA9IGk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHBhdGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHBhdGggdGhhdCBjYW4gYmUgc2FmZWx5IGNvbmNhdGVuYXRlZCB3aXRoIHtAY29kZSBhdXRob3JpdHl9LiBJZgorICAgICAqIHRoZSBhdXRob3JpdHkgaXMgbnVsbCBvciBlbXB0eSwgdGhpcyBjYW4gYmUgYW55IHBhdGguIE90aGVyd2lzZSB0aGUgcGF0aHMKKyAgICAgKiBydW4gdG9nZXRoZXIgbGlrZSB7QGNvZGUgaHR0cDovL2FuZHJvaWQuY29taW5kZXguaHRtbH0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgYXV0aG9yaXR5U2FmZVBhdGgoU3RyaW5nIGF1dGhvcml0eSwgU3RyaW5nIHBhdGgpIHsKKyAgICAgICAgaWYgKGF1dGhvcml0eSAhPSBudWxsICYmICFhdXRob3JpdHkuaXNFbXB0eSgpICYmICFwYXRoLmlzRW1wdHkoKSAmJiAhcGF0aC5zdGFydHNXaXRoKCIvIikpIHsKKyAgICAgICAgICAgIHJldHVybiAiLyIgKyBwYXRoOworICAgICAgICB9CisgICAgICAgIHJldHVybiBwYXRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNjaGVtZSBwcmVmaXggbGlrZSAiaHR0cCIgZnJvbSB0aGUgVVJMIHNwZWMsIG9yIG51bGwgaWYgdGhlCisgICAgICogc3BlYyBkb2Vzbid0IHN0YXJ0IHdpdGggYSBzY2hlbWUuIFNjaGVtZSBwcmVmaXhlcyBtYXRjaCB0aGlzIHBhdHRlcm46CisgICAgICoge0Bjb2RlIGFscGhhICggYWxwaGEgfCBkaWdpdCB8ICcrJyB8ICctJyB8ICcuJyApKiAnOid9CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0U2NoZW1lUHJlZml4KFN0cmluZyBzcGVjKSB7CisgICAgICAgIGludCBjb2xvbiA9IHNwZWMuaW5kZXhPZignOicpOworCisgICAgICAgIGlmIChjb2xvbiA8IDEpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb2xvbjsgaSsrKSB7CisgICAgICAgICAgICBjaGFyIGMgPSBzcGVjLmNoYXJBdChpKTsKKyAgICAgICAgICAgIGlmICghaXNWYWxpZFNjaGVtZUNoYXIoaSwgYykpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBzcGVjLnN1YnN0cmluZygwLCBjb2xvbikudG9Mb3dlckNhc2UoTG9jYWxlLlVTKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNWYWxpZFNjaGVtZUNoYXIoaW50IGluZGV4LCBjaGFyIGMpIHsKKyAgICAgICAgaWYgKChjID49ICdhJyAmJiBjIDw9ICd6JykgfHwgKGMgPj0gJ0EnICYmIGMgPD0gJ1onKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGluZGV4ID4gMCAmJiAoKGMgPj0gJzAnICYmIGMgPD0gJzknKSB8fCBjID09ICcrJyB8fCBjID09ICctJyB8fCBjID09ICcuJykpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhciBvZiB7QGNvZGUgY2hhcnN9IGluIHtAY29kZSBzdHJpbmd9CisgICAgICogYm91bmRlZCBiZXR3ZWVuIHtAY29kZSBzdGFydH0gYW5kIHtAY29kZSBlbmR9LiBUaGlzIHJldHVybnMge0Bjb2RlIGVuZH0KKyAgICAgKiBpZiBub25lIG9mIHRoZSBjaGFyYWN0ZXJzIGV4aXN0IGluIHRoZSByZXF1ZXN0ZWQgcmFuZ2UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZmluZEZpcnN0T2YoU3RyaW5nIHN0cmluZywgU3RyaW5nIGNoYXJzLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHsKKyAgICAgICAgICAgIGNoYXIgYyA9IHN0cmluZy5jaGFyQXQoaSk7CisgICAgICAgICAgICBpZiAoY2hhcnMuaW5kZXhPZihjKSAhPSAtMSkgeworICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvdXRpbC9CYXNpY0xydUNhY2hlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL0Jhc2ljTHJ1Q2FjaGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xM2FiM2RiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvdXRpbC9CYXNpY0xydUNhY2hlLmphdmEKQEAgLTAsMCArMSwxMjEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogQSBtaW5pbWFsIGxlYXN0LXJlY2VudGx5LXVzZWQgY2FjaGUgZm9yIGxpYmNvcmUuIFByZWZlciB7QGNvZGUKKyAqIGFuZHJvaWQudXRpbC5McnVDYWNoZX0gd2hlcmUgdGhhdCBpcyBhdmFpbGFibGUuCisgKi8KK3B1YmxpYyBjbGFzcyBCYXNpY0xydUNhY2hlPEssIFY+IHsKKyAgICBwcml2YXRlIGZpbmFsIExpbmtlZEhhc2hNYXA8SywgVj4gbWFwOworICAgIHByaXZhdGUgZmluYWwgaW50IG1heFNpemU7CisKKyAgICBwdWJsaWMgQmFzaWNMcnVDYWNoZShpbnQgbWF4U2l6ZSkgeworICAgICAgICBpZiAobWF4U2l6ZSA8PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJtYXhTaXplIDw9IDAiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLm1heFNpemUgPSBtYXhTaXplOworICAgICAgICB0aGlzLm1hcCA9IG5ldyBMaW5rZWRIYXNoTWFwPEssIFY+KDAsIDAuNzVmLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBmb3Ige0Bjb2RlIGtleX0gaWYgaXQgZXhpc3RzIGluIHRoZSBjYWNoZSBvciBjYW4gYmUKKyAgICAgKiBjcmVhdGVkIGJ5IHtAY29kZSAjY3JlYXRlfS4gSWYgYSB2YWx1ZSB3YXMgcmV0dXJuZWQsIGl0IGlzIG1vdmVkIHRvIHRoZQorICAgICAqIGhlYWQgb2YgdGhlIHF1ZXVlLiBUaGlzIHJldHVybnMgbnVsbCBpZiBhIHZhbHVlIGlzIG5vdCBjYWNoZWQgYW5kIGNhbm5vdAorICAgICAqIGJlIGNyZWF0ZWQuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBmaW5hbCBWIGdldChLIGtleSkgeworICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgViByZXN1bHQgPSBtYXAuZ2V0KGtleSk7CisgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIHJlc3VsdCA9IGNyZWF0ZShrZXkpOworCisgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgeworICAgICAgICAgICAgbWFwLnB1dChrZXksIHJlc3VsdCk7CisgICAgICAgICAgICB0cmltVG9TaXplKG1heFNpemUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FjaGVzIHtAY29kZSB2YWx1ZX0gZm9yIHtAY29kZSBrZXl9LiBUaGUgdmFsdWUgaXMgbW92ZWQgdG8gdGhlIGhlYWQgb2YKKyAgICAgKiB0aGUgcXVldWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZSBtYXBwZWQgYnkge0Bjb2RlIGtleX0uIEFsdGhvdWdoIHRoYXQgZW50cnkgaXMKKyAgICAgKiAgICAgbm8gbG9uZ2VyIGNhY2hlZCwgaXQgaGFzIG5vdCBiZWVuIHBhc3NlZCB0byB7QGxpbmsgI2VudHJ5RXZpY3RlZH0uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBmaW5hbCBWIHB1dChLIGtleSwgViB2YWx1ZSkgeworICAgICAgICBpZiAoa2V5ID09IG51bGwgfHwgdmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBWIHByZXZpb3VzID0gbWFwLnB1dChrZXksIHZhbHVlKTsKKyAgICAgICAgdHJpbVRvU2l6ZShtYXhTaXplKTsKKyAgICAgICAgcmV0dXJuIHByZXZpb3VzOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0cmltVG9TaXplKGludCBtYXhTaXplKSB7CisgICAgICAgIHdoaWxlIChtYXAuc2l6ZSgpID4gbWF4U2l6ZSkgeworICAgICAgICAgICAgTWFwLkVudHJ5PEssIFY+IHRvRXZpY3QgPSBtYXAuZWxkZXN0KCk7CisKKyAgICAgICAgICAgIEsga2V5ID0gdG9FdmljdC5nZXRLZXkoKTsKKyAgICAgICAgICAgIFYgdmFsdWUgPSB0b0V2aWN0LmdldFZhbHVlKCk7CisgICAgICAgICAgICBtYXAucmVtb3ZlKGtleSk7CisKKyAgICAgICAgICAgIGVudHJ5RXZpY3RlZChrZXksIHZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGxlZCBmb3IgZW50cmllcyB0aGF0IGhhdmUgcmVhY2hlZCB0aGUgdGFpbCBvZiB0aGUgbGVhc3QgcmVjZW50bHkgdXNlZAorICAgICAqIHF1ZXVlIGFuZCBhcmUgYmUgcmVtb3ZlZC4gVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZG9lcyBub3RoaW5nLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGVudHJ5RXZpY3RlZChLIGtleSwgViB2YWx1ZSkge30KKworICAgIC8qKgorICAgICAqIENhbGxlZCBhZnRlciBhIGNhY2hlIG1pc3MgdG8gY29tcHV0ZSBhIHZhbHVlIGZvciB0aGUgY29ycmVzcG9uZGluZyBrZXkuCisgICAgICogUmV0dXJucyB0aGUgY29tcHV0ZWQgdmFsdWUgb3IgbnVsbCBpZiBubyB2YWx1ZSBjYW4gYmUgY29tcHV0ZWQuIFRoZQorICAgICAqIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcmV0dXJucyBudWxsLgorICAgICAqLworICAgIHByb3RlY3RlZCBWIGNyZWF0ZShLIGtleSkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29weSBvZiB0aGUgY3VycmVudCBjb250ZW50cyBvZiB0aGUgY2FjaGUsIG9yZGVyZWQgZnJvbSBsZWFzdAorICAgICAqIHJlY2VudGx5IGFjY2Vzc2VkIHRvIG1vc3QgcmVjZW50bHkgYWNjZXNzZWQuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBmaW5hbCBNYXA8SywgVj4gc25hcHNob3QoKSB7CisgICAgICAgIHJldHVybiBuZXcgTGlua2VkSGFzaE1hcDxLLCBWPihtYXApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsZWFyIHRoZSBjYWNoZSwgY2FsbGluZyB7QGxpbmsgI2VudHJ5RXZpY3RlZH0gb24gZWFjaCByZW1vdmVkIGVudHJ5LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgZmluYWwgdm9pZCBldmljdEFsbCgpIHsKKyAgICAgICAgdHJpbVRvU2l6ZSgwKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL0NvbGxlY3Rpb25VdGlscy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvdXRpbC9Db2xsZWN0aW9uVXRpbHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NWMyYWU2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvdXRpbC9Db2xsZWN0aW9uVXRpbHMuamF2YQpAQCAtMCwwICsxLDk4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLnV0aWw7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmLlJlZmVyZW5jZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuQ29tcGFyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBDb2xsZWN0aW9uVXRpbHMgeworICAgIHByaXZhdGUgQ29sbGVjdGlvblV0aWxzKCkge30KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igb3ZlciB0aGUgdmFsdWVzIHJlZmVyZW5jZWQgYnkgdGhlIGVsZW1lbnRzIG9mIHtAY29kZQorICAgICAqIGl0ZXJhYmxlfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0cmltIHRydWUgdG8gcmVtb3ZlIHJlZmVyZW5jZSBvYmplY3RzIGZyb20gdGhlIGl0ZXJhYmxlIGFmdGVyCisgICAgICogICAgIHRoZWlyIHJlZmVyZW5jZWQgdmFsdWVzIGhhdmUgYmVlbiBjbGVhcmVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFQ+IEl0ZXJhYmxlPFQ+IGRlcmVmZXJlbmNlSXRlcmFibGUoCisgICAgICAgICAgICBmaW5hbCBJdGVyYWJsZTw/IGV4dGVuZHMgUmVmZXJlbmNlPFQ+PiBpdGVyYWJsZSwgZmluYWwgYm9vbGVhbiB0cmltKSB7CisgICAgICAgIHJldHVybiBuZXcgSXRlcmFibGU8VD4oKSB7CisgICAgICAgICAgICBwdWJsaWMgSXRlcmF0b3I8VD4gaXRlcmF0b3IoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcjxUPigpIHsKKyAgICAgICAgICAgICAgICAgICAgcHJpdmF0ZSBmaW5hbCBJdGVyYXRvcjw/IGV4dGVuZHMgUmVmZXJlbmNlPFQ+PiBkZWxlZ2F0ZSA9IGl0ZXJhYmxlLml0ZXJhdG9yKCk7CisgICAgICAgICAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiByZW1vdmVJc09rYXk7CisgICAgICAgICAgICAgICAgICAgIHByaXZhdGUgVCBuZXh0OworCisgICAgICAgICAgICAgICAgICAgIHByaXZhdGUgdm9pZCBjb21wdXRlTmV4dCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUlzT2theSA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKG5leHQgPT0gbnVsbCAmJiBkZWxlZ2F0ZS5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0ID0gZGVsZWdhdGUubmV4dCgpLmdldCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0cmltICYmIG5leHQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxlZ2F0ZS5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbXB1dGVOZXh0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV4dCAhPSBudWxsOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBUIG5leHQoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWhhc05leHQoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIFQgcmVzdWx0ID0gbmV4dDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUlzT2theSA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICBuZXh0ID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXJlbW92ZUlzT2theSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGRlbGVnYXRlLnJlbW92ZSgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb3J0cyBhbmQgcmVtb3ZlcyBkdXBsaWNhdGUgZWxlbWVudHMgZnJvbSB7QGNvZGUgbGlzdH0uIFRoaXMgbWV0aG9kIGRvZXMKKyAgICAgKiBub3QgdXNlIHtAbGluayBPYmplY3QjZXF1YWxzfTogb25seSB0aGUgY29tcGFyYXRvciBkZWZpbmVzIGVxdWFsaXR5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgPFQ+IHZvaWQgcmVtb3ZlRHVwbGljYXRlcyhMaXN0PFQ+IGxpc3QsIENvbXBhcmF0b3I8PyBzdXBlciBUPiBjb21wYXJhdG9yKSB7CisgICAgICAgIENvbGxlY3Rpb25zLnNvcnQobGlzdCwgY29tcGFyYXRvcik7CisgICAgICAgIGludCBqID0gMTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBsaXN0LnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICBpZiAoY29tcGFyYXRvci5jb21wYXJlKGxpc3QuZ2V0KGogLSAxKSwgbGlzdC5nZXQoaSkpICE9IDApIHsKKyAgICAgICAgICAgICAgICBUIG9iamVjdCA9IGxpc3QuZ2V0KGkpOworICAgICAgICAgICAgICAgIGxpc3Quc2V0KGorKywgb2JqZWN0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoaiA8IGxpc3Quc2l6ZSgpKSB7CisgICAgICAgICAgICBsaXN0LnN1Ykxpc3QoaiwgbGlzdC5zaXplKCkpLmNsZWFyKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL0VtcHR5QXJyYXkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL3V0aWwvRW1wdHlBcnJheS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZjOTk4NzgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL0VtcHR5QXJyYXkuamF2YQpAQCAtMCwwICsxLDMzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLnV0aWw7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBFbXB0eUFycmF5IHsKKyAgICBwcml2YXRlIEVtcHR5QXJyYXkoKSB7fQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBib29sZWFuW10gQk9PTEVBTiA9IG5ldyBib29sZWFuWzBdOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZVtdIEJZVEUgPSBuZXcgYnl0ZVswXTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNoYXJbXSBDSEFSID0gbmV3IGNoYXJbMF07CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBkb3VibGVbXSBET1VCTEUgPSBuZXcgZG91YmxlWzBdOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50W10gSU5UID0gbmV3IGludFswXTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3M8Pz5bXSBDTEFTUyA9IG5ldyBDbGFzc1swXTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdFtdIE9CSkVDVCA9IG5ldyBPYmplY3RbMF07CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBTVFJJTkcgPSBuZXcgU3RyaW5nWzBdOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVGhyb3dhYmxlW10gVEhST1dBQkxFID0gbmV3IFRocm93YWJsZVswXTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0YWNrVHJhY2VFbGVtZW50W10gU1RBQ0tfVFJBQ0VfRUxFTUVOVCA9IG5ldyBTdGFja1RyYWNlRWxlbWVudFswXTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL3V0aWwvTXV0YWJsZUJvb2xlYW4uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL3V0aWwvTXV0YWJsZUJvb2xlYW4uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNTlhOGY5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvdXRpbC9NdXRhYmxlQm9vbGVhbi5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUudXRpbDsKKworcHVibGljIGZpbmFsIGNsYXNzIE11dGFibGVCb29sZWFuIHsKKyAgICBwdWJsaWMgYm9vbGVhbiB2YWx1ZTsKKworICAgIHB1YmxpYyBNdXRhYmxlQm9vbGVhbihib29sZWFuIHZhbHVlKSB7CisgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL011dGFibGVCeXRlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL011dGFibGVCeXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTNmNzgwYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL3V0aWwvTXV0YWJsZUJ5dGUuamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLnV0aWw7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBNdXRhYmxlQnl0ZSB7CisgICAgcHVibGljIGJ5dGUgdmFsdWU7CisKKyAgICBwdWJsaWMgTXV0YWJsZUJ5dGUoYnl0ZSB2YWx1ZSkgeworICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvdXRpbC9NdXRhYmxlQ2hhci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvdXRpbC9NdXRhYmxlQ2hhci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjYWZjM2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL011dGFibGVDaGFyLmphdmEKQEAgLTAsMCArMSwyNSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS51dGlsOworCitwdWJsaWMgZmluYWwgY2xhc3MgTXV0YWJsZUNoYXIgeworICAgIHB1YmxpYyBjaGFyIHZhbHVlOworCisgICAgcHVibGljIE11dGFibGVDaGFyKGNoYXIgdmFsdWUpIHsKKyAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL3V0aWwvTXV0YWJsZURvdWJsZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvdXRpbC9NdXRhYmxlRG91YmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDQ3M2FlNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL3V0aWwvTXV0YWJsZURvdWJsZS5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUudXRpbDsKKworcHVibGljIGZpbmFsIGNsYXNzIE11dGFibGVEb3VibGUgeworICAgIHB1YmxpYyBkb3VibGUgdmFsdWU7CisKKyAgICBwdWJsaWMgTXV0YWJsZURvdWJsZShkb3VibGUgdmFsdWUpIHsKKyAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL3V0aWwvTXV0YWJsZUZsb2F0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL011dGFibGVGbG9hdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4MWZiYTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL011dGFibGVGbG9hdC5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUudXRpbDsKKworcHVibGljIGZpbmFsIGNsYXNzIE11dGFibGVGbG9hdCB7CisgICAgcHVibGljIGZsb2F0IHZhbHVlOworCisgICAgcHVibGljIE11dGFibGVGbG9hdChmbG9hdCB2YWx1ZSkgeworICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvdXRpbC9NdXRhYmxlSW50LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL011dGFibGVJbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOGZlYjNhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvdXRpbC9NdXRhYmxlSW50LmphdmEKQEAgLTAsMCArMSwyNSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS51dGlsOworCitwdWJsaWMgZmluYWwgY2xhc3MgTXV0YWJsZUludCB7CisgICAgcHVibGljIGludCB2YWx1ZTsKKworICAgIHB1YmxpYyBNdXRhYmxlSW50KGludCB2YWx1ZSkgeworICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvdXRpbC9NdXRhYmxlTG9uZy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvdXRpbC9NdXRhYmxlTG9uZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFkOWI3OGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL011dGFibGVMb25nLmphdmEKQEAgLTAsMCArMSwyNSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS51dGlsOworCitwdWJsaWMgZmluYWwgY2xhc3MgTXV0YWJsZUxvbmcgeworICAgIHB1YmxpYyBsb25nIHZhbHVlOworCisgICAgcHVibGljIE11dGFibGVMb25nKGxvbmcgdmFsdWUpIHsKKyAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL3V0aWwvTXV0YWJsZVNob3J0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL011dGFibGVTaG9ydC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc4YjRjMzMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL011dGFibGVTaG9ydC5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUudXRpbDsKKworcHVibGljIGZpbmFsIGNsYXNzIE11dGFibGVTaG9ydCB7CisgICAgcHVibGljIHNob3J0IHZhbHVlOworCisgICAgcHVibGljIE11dGFibGVTaG9ydChzaG9ydCB2YWx1ZSkgeworICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvdXRpbC9PYmplY3RzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL09iamVjdHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ODE3MzE2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL2xpYmNvcmUvdXRpbC9PYmplY3RzLmphdmEKQEAgLTAsMCArMSwzMiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS51dGlsOworCitwdWJsaWMgZmluYWwgY2xhc3MgT2JqZWN0cyB7CisgICAgcHJpdmF0ZSBPYmplY3RzKCkge30KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0d28gcG9zc2libHktbnVsbCBvYmplY3RzIGFyZSBlcXVhbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZXF1YWwoT2JqZWN0IGEsIE9iamVjdCBiKSB7CisgICAgICAgIHJldHVybiBhID09IGIgfHwgKGEgIT0gbnVsbCAmJiBhLmVxdWFscyhiKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBpbnQgaGFzaENvZGUoT2JqZWN0IG8pIHsKKyAgICAgICAgcmV0dXJuIChvID09IG51bGwpID8gMCA6IG8uaGFzaENvZGUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL1NuZWFreVRocm93LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL1NuZWFreVRocm93LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTkxMTc4OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL3V0aWwvU25lYWt5VGhyb3cuamF2YQpAQCAtMCwwICsxLDcwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUudXRpbDsKKworLyoqCisgKiBFeHBsb2l0cyBhIHdlYWtuZXNzIGluIHRoZSBydW50aW1lIHRvIHRocm93IGFuIGFyYml0cmFyeSB0aHJvd2FibGUgd2l0aG91dAorICogdGhlIHRyYWRpdGlvbmFsIGRlY2xhcmF0aW9uLiA8c3Ryb25nPlRoaXMgaXMgYSBkYW5nZXJvdXMgQVBJIHRoYXQgc2hvdWxkIGJlCisgKiB1c2VkIHdpdGggZ3JlYXQgY2F1dGlvbi48L3N0cm9uZz4gVHlwaWNhbGx5IHRoaXMgaXMgdXNlZnVsIHdoZW4gcmV0aHJvd2luZworICogdGhyb3dhYmxlcyB0aGF0IGFyZSBvZiBhIGtub3duIHJhbmdlIG9mIHR5cGVzLgorICoKKyAqIDxwPlRoZSBmb2xsb3dpbmcgY29kZSBtdXN0IGVudW1lcmF0ZSBzZXZlcmFsIHR5cGVzIHRvIHJldGhyb3c6CisgKiA8cHJlPgorICogcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICogICAgIFRocm93YWJsZSB0aHJvd24gPSBudWxsOworICogICAgIC4uLgorICoKKyAqICAgICBpZiAodGhyb3duICE9IG51bGwpIHsKKyAqICAgICAgICAgaWYgKHRocm93biBpbnN0YW5jZW9mIElPRXhjZXB0aW9uKSB7CisgKiAgICAgICAgICAgICB0aHJvdyAoSU9FeGNlcHRpb24pIHRocm93bjsKKyAqICAgICAgICAgfSBlbHNlIGlmICh0aHJvd24gaW5zdGFuY2VvZiBSdW50aW1lRXhjZXB0aW9uKSB7CisgKiAgICAgICAgICAgICB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikgdGhyb3duOworICogICAgICAgICB9IGVsc2UgaWYgKHRocm93biBpbnN0YW5jZW9mIEVycm9yKSB7CisgKiAgICAgICAgICAgICB0aHJvdyAoRXJyb3IpIHRocm93bjsKKyAqICAgICAgICAgfSBlbHNlIHsKKyAqICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICogICAgICAgICB9CisgKiAgICAgfQorICogfTwvcHJlPgorICogV2l0aCBTbmVha3lUaHJvdywgcmV0aHJvd2luZyBpcyBlYXNpZXI6CisgKiA8cHJlPgorICogcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICogICAgIFRocm93YWJsZSB0aHJvd24gPSBudWxsOworICogICAgIC4uLgorICoKKyAqICAgICBpZiAodGhyb3duICE9IG51bGwpIHsKKyAqICAgICAgICAgU25lYWt5VGhyb3cuc25lYWt5VGhyb3codGhyb3duKTsKKyAqICAgICB9CisgKiB9PC9wcmU+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTbmVha3lUaHJvdyB7CisgICAgcHJpdmF0ZSBTbmVha3lUaHJvdygpIHt9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc25lYWt5VGhyb3coVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgU25lYWt5VGhyb3cuPEVycm9yPnNuZWFreVRocm93Mih0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHBsb2l0cyB1bnNhZmV0eSB0byB0aHJvdyBhbiBleGNlcHRpb24gdGhhdCB0aGUgY29tcGlsZXIgd291bGRuJ3QgcGVybWl0CisgICAgICogYnV0IHRoYXQgdGhlIHJ1bnRpbWUgZG9lc24ndCBjaGVjay4gU2VlIEphdmEgUHV6emxlcnMgIzQzLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHByaXZhdGUgc3RhdGljIDxUIGV4dGVuZHMgVGhyb3dhYmxlPiB2b2lkIHNuZWFreVRocm93MihUaHJvd2FibGUgdCkgdGhyb3dzIFQgeworICAgICAgICB0aHJvdyAoVCkgdDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL1pvbmVJbmZvLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL1pvbmVJbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWE4Y2FmMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL3V0aWwvWm9uZUluZm8uamF2YQpAQCAtMCwwICsxLDI2MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS51dGlsOworCitpbXBvcnQgamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQ7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuRm9ybWF0dGVyOworaW1wb3J0IGphdmEudXRpbC5UaW1lWm9uZTsKKworLyoqCisgKiBPdXIgY29uY3JldGUgVGltZVpvbmUgaW1wbGVtZW50YXRpb24sIGJhY2tlZCBieSB6b25laW5mbyBkYXRhLgorICoKKyAqIEBoaWRlIC0gdXNlZCB0byBpbXBsZW1lbnQgVGltZVpvbmUKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFpvbmVJbmZvIGV4dGVuZHMgVGltZVpvbmUgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgTUlMTElTRUNPTkRTX1BFUl9EQVkgPSAyNCAqIDYwICogNjAgKiAxMDAwOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgTUlMTElTRUNPTkRTX1BFUl80MDBfWUVBUlMgPQorICAgICAgICAgICAgTUlMTElTRUNPTkRTX1BFUl9EQVkgKiAoNDAwICogMzY1ICsgMTAwIC0gMyk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIFVOSVhfT0ZGU0VUID0gNjIxNjcyMTkyMDAwMDBMOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gTk9STUFMID0gbmV3IGludFtdIHsKKyAgICAgICAgMCwgMzEsIDU5LCA5MCwgMTIwLCAxNTEsIDE4MSwgMjEyLCAyNDMsIDI3MywgMzA0LCAzMzQsCisgICAgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludFtdIExFQVAgPSBuZXcgaW50W10geworICAgICAgICAwLCAzMSwgNjAsIDkxLCAxMjEsIDE1MiwgMTgyLCAyMTMsIDI0NCwgMjc0LCAzMDUsIDMzNSwKKyAgICB9OworCisgICAgcHJpdmF0ZSBpbnQgbVJhd09mZnNldDsKKworICAgIHByaXZhdGUgZmluYWwgaW50IG1FYXJsaWVzdFJhd09mZnNldDsKKworICAgIHByaXZhdGUgZmluYWwgaW50W10gbVRyYW5zaXRpb25zOworICAgIHByaXZhdGUgZmluYWwgaW50W10gbU9mZnNldHM7CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gbVR5cGVzOworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIG1Jc0RzdHM7CisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIG1Vc2VEc3Q7CisKKyAgICBab25lSW5mbyhTdHJpbmcgbmFtZSwgaW50W10gdHJhbnNpdGlvbnMsIGJ5dGVbXSB0eXBlLCBpbnRbXSBnbXRPZmZzZXRzLCBieXRlW10gaXNEc3RzKSB7CisgICAgICAgIG1UcmFuc2l0aW9ucyA9IHRyYW5zaXRpb25zOworICAgICAgICBtVHlwZXMgPSB0eXBlOworICAgICAgICBtSXNEc3RzID0gaXNEc3RzOworICAgICAgICBzZXRJRChuYW1lKTsKKworICAgICAgICAvLyBVc2UgdGhlIGxhdGVzdCBub24tZGF5bGlnaHQgb2Zmc2V0IChpZiBhbnkpIGFzIHRoZSByYXcgb2Zmc2V0LgorICAgICAgICBpbnQgbGFzdFN0ZDsKKyAgICAgICAgZm9yIChsYXN0U3RkID0gbVRyYW5zaXRpb25zLmxlbmd0aCAtIDE7IGxhc3RTdGQgPj0gMDsgbGFzdFN0ZC0tKSB7CisgICAgICAgICAgICBpZiAobUlzRHN0c1ttVHlwZXNbbGFzdFN0ZF0gJiAweGZmXSA9PSAwKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxhc3RTdGQgPCAwKSB7CisgICAgICAgICAgICBsYXN0U3RkID0gMDsKKyAgICAgICAgfQorICAgICAgICBpZiAobGFzdFN0ZCA+PSBtVHlwZXMubGVuZ3RoKSB7CisgICAgICAgICAgICBtUmF3T2Zmc2V0ID0gZ210T2Zmc2V0c1swXTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG1SYXdPZmZzZXQgPSBnbXRPZmZzZXRzW21UeXBlc1tsYXN0U3RkXSAmIDB4ZmZdOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ2FjaGUgdGhlIG9sZGVzdCBrbm93biByYXcgb2Zmc2V0LCBpbiBjYXNlIHdlJ3JlIGFza2VkIGFib3V0IHRpbWVzIHRoYXQgcHJlZGF0ZSBvdXIKKyAgICAgICAgLy8gdHJhbnNpdGlvbiBkYXRhLgorICAgICAgICBpbnQgZmlyc3RTdGQgPSAtMTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtVHJhbnNpdGlvbnMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIGlmIChtSXNEc3RzW21UeXBlc1tpXSAmIDB4ZmZdID09IDApIHsKKyAgICAgICAgICAgICAgICBmaXJzdFN0ZCA9IGk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaW50IGVhcmxpZXN0UmF3T2Zmc2V0ID0gKGZpcnN0U3RkICE9IC0xKSA/IGdtdE9mZnNldHNbbVR5cGVzW2ZpcnN0U3RkXSAmIDB4ZmZdIDogbVJhd09mZnNldDsKKworICAgICAgICAvLyBSYXRoZXIgdGhhbiBrZWVwIG9mZnNldHMgZnJvbSBVVEMsIHdlIHVzZSBvZmZzZXRzIGZyb20gbG9jYWwgdGltZSwgc28gdGhlIHJhdyBvZmZzZXQKKyAgICAgICAgLy8gY2FuIGJlIGNoYW5nZWQgYW5kIGF1dG9tYXRpY2FsbHkgYWZmZWN0IGFsbCB0aGUgb2Zmc2V0cy4KKyAgICAgICAgbU9mZnNldHMgPSBnbXRPZmZzZXRzOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1PZmZzZXRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBtT2Zmc2V0c1tpXSAtPSBtUmF3T2Zmc2V0OworICAgICAgICB9CisKKyAgICAgICAgLy8gSXMgdGhpcyB6b25lIHN0aWxsIG9ic2VydmluZyBEU1Q/CisgICAgICAgIC8vIFdlIGRvbid0IGNhcmUgaWYgdGhleSd2ZSBoaXN0b3JpY2FsbHkgdXNlZCBpdDogbW9zdCBwbGFjZXMgaGF2ZSBhdCBsZWFzdCBvbmNlLgorICAgICAgICAvLyBXZSB3YW50IHRvIGtub3cgd2hldGhlciB0aGUgbGFzdCAic2NoZWR1bGUgaW5mbyIgKHRoZSB1bml4IHRpbWVzIGluIHRoZSBtVHJhbnNpdGlvbnMKKyAgICAgICAgLy8gYXJyYXkpIGlzIGluIHRoZSBmdXR1cmUuIElmIGl0IGlzLCBEU1QgaXMgc3RpbGwgcmVsZXZhbnQuCisgICAgICAgIC8vIFNlZSBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTg3Ny4KKyAgICAgICAgLy8gVGhpcyB0ZXN0IG1lYW5zIHRoYXQgZm9yIHNvbWV3aGVyZSBsaWtlIE1vcm9jY28sIHdoaWNoIHRyaWVkIERTVCBpbiAyMDA5IGJ1dCBoYXMKKyAgICAgICAgLy8gbm8gZnV0dXJlIHBsYW5zIChhbmQgdGh1cyBubyBmdXR1cmUgc2NoZWR1bGUgaW5mbykgd2lsbCByZXBvcnQgInRydWUiIGZyb20KKyAgICAgICAgLy8gdXNlRGF5bGlnaHRUaW1lIGF0IHRoZSBzdGFydCBvZiAyMDA5IGJ1dCAiZmFsc2UiIGF0IHRoZSBlbmQuIFRoaXMgc2VlbXMgYXBwcm9wcmlhdGUuCisgICAgICAgIGJvb2xlYW4gdXNlc0RzdCA9IGZhbHNlOworICAgICAgICBsb25nIGN1cnJlbnRVbml4VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC8gMTAwMDsKKyAgICAgICAgaWYgKG1UcmFuc2l0aW9ucy5sZW5ndGggPiAwKSB7CisgICAgICAgICAgICAvLyAoV2UncmUgcmVhbGx5IGRlYWxpbmcgd2l0aCB1aW50MzJfdCB2YWx1ZXMsIHNvIGxvbmcgaXMgbW9zdCBjb252ZW5pZW50IGluIEphdmEuKQorICAgICAgICAgICAgbG9uZyBsYXRlc3RTY2hlZHVsZVRpbWUgPSAoKGxvbmcpIG1UcmFuc2l0aW9uc1ttVHJhbnNpdGlvbnMubGVuZ3RoIC0gMV0pICYgMHhmZmZmZmZmZjsKKyAgICAgICAgICAgIGlmIChjdXJyZW50VW5peFRpbWUgPCBsYXRlc3RTY2hlZHVsZVRpbWUpIHsKKyAgICAgICAgICAgICAgICB1c2VzRHN0ID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBtVXNlRHN0ID0gdXNlc0RzdDsKKworICAgICAgICBtUmF3T2Zmc2V0ICo9IDEwMDA7CisgICAgICAgIG1FYXJsaWVzdFJhd09mZnNldCA9IGVhcmxpZXN0UmF3T2Zmc2V0ICogMTAwMDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldE9mZnNldChpbnQgZXJhLCBpbnQgeWVhciwgaW50IG1vbnRoLCBpbnQgZGF5LCBpbnQgZGF5T2ZXZWVrLCBpbnQgbWlsbGlzKSB7CisgICAgICAgIC8vIFhYWCBUaGlzIGFzc3VtZXMgR3JlZ29yaWFuIGFsd2F5czsgQ2FsZW5kYXIgc3dpdGNoZXMgZnJvbQorICAgICAgICAvLyBKdWxpYW4gdG8gR3JlZ29yaWFuIGluIDE1ODIuICBXaGF0IGNhbGVuZGFyIHN5c3RlbSBhcmUgdGhlCisgICAgICAgIC8vIGFyZ3VtZW50cyBzdXBwb3NlZCB0byBjb21lIGZyb20/CisKKyAgICAgICAgbG9uZyBjYWxjID0gKHllYXIgLyA0MDApICogTUlMTElTRUNPTkRTX1BFUl80MDBfWUVBUlM7CisgICAgICAgIHllYXIgJT0gNDAwOworCisgICAgICAgIGNhbGMgKz0geWVhciAqICgzNjUgKiBNSUxMSVNFQ09ORFNfUEVSX0RBWSk7CisgICAgICAgIGNhbGMgKz0gKCh5ZWFyICsgMykgLyA0KSAqIE1JTExJU0VDT05EU19QRVJfREFZOworCisgICAgICAgIGlmICh5ZWFyID4gMCkgeworICAgICAgICAgICAgY2FsYyAtPSAoKHllYXIgLSAxKSAvIDEwMCkgKiBNSUxMSVNFQ09ORFNfUEVSX0RBWTsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gaXNMZWFwID0gKHllYXIgPT0gMCB8fCAoeWVhciAlIDQgPT0gMCAmJiB5ZWFyICUgMTAwICE9IDApKTsKKyAgICAgICAgaW50W10gbWxlbiA9IGlzTGVhcCA/IExFQVAgOiBOT1JNQUw7CisKKyAgICAgICAgY2FsYyArPSBtbGVuW21vbnRoXSAqIE1JTExJU0VDT05EU19QRVJfREFZOworICAgICAgICBjYWxjICs9IChkYXkgLSAxKSAqIE1JTExJU0VDT05EU19QRVJfREFZOworICAgICAgICBjYWxjICs9IG1pbGxpczsKKworICAgICAgICBjYWxjIC09IG1SYXdPZmZzZXQ7CisgICAgICAgIGNhbGMgLT0gVU5JWF9PRkZTRVQ7CisKKyAgICAgICAgcmV0dXJuIGdldE9mZnNldChjYWxjKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldE9mZnNldChsb25nIHdoZW4pIHsKKyAgICAgICAgaW50IHVuaXggPSAoaW50KSAod2hlbiAvIDEwMDApOworICAgICAgICBpbnQgdHJhbnNpdGlvbiA9IEFycmF5cy5iaW5hcnlTZWFyY2gobVRyYW5zaXRpb25zLCB1bml4KTsKKyAgICAgICAgaWYgKHRyYW5zaXRpb24gPCAwKSB7CisgICAgICAgICAgICB0cmFuc2l0aW9uID0gfnRyYW5zaXRpb24gLSAxOworICAgICAgICAgICAgaWYgKHRyYW5zaXRpb24gPCAwKSB7CisgICAgICAgICAgICAgICAgLy8gQXNzdW1lIHRoYXQgYWxsIHRpbWVzIGJlZm9yZSBvdXIgZmlyc3QgdHJhbnNpdGlvbiBjb3JyZXNwb25kIHRvIHRoZQorICAgICAgICAgICAgICAgIC8vIG9sZGVzdC1rbm93biBub24tZGF5bGlnaHQgb2Zmc2V0LiBUaGUgb2J2aW91cyBhbHRlcm5hdGl2ZSB3b3VsZCBiZSB0bworICAgICAgICAgICAgICAgIC8vIHVzZSB0aGUgY3VycmVudCByYXcgb2Zmc2V0LCBidXQgdGhhdCBzZWVtcyBsaWtlIGEgZ3JlYXRlciBsZWFwIG9mIGZhaXRoLgorICAgICAgICAgICAgICAgIHJldHVybiBtRWFybGllc3RSYXdPZmZzZXQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG1SYXdPZmZzZXQgKyBtT2Zmc2V0c1ttVHlwZXNbdHJhbnNpdGlvbl0gJiAweGZmXSAqIDEwMDA7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGluRGF5bGlnaHRUaW1lKERhdGUgdGltZSkgeworICAgICAgICBsb25nIHdoZW4gPSB0aW1lLmdldFRpbWUoKTsKKyAgICAgICAgaW50IHVuaXggPSAoaW50KSAod2hlbiAvIDEwMDApOworICAgICAgICBpbnQgdHJhbnNpdGlvbiA9IEFycmF5cy5iaW5hcnlTZWFyY2gobVRyYW5zaXRpb25zLCB1bml4KTsKKyAgICAgICAgaWYgKHRyYW5zaXRpb24gPCAwKSB7CisgICAgICAgICAgICB0cmFuc2l0aW9uID0gfnRyYW5zaXRpb24gLSAxOworICAgICAgICAgICAgaWYgKHRyYW5zaXRpb24gPCAwKSB7CisgICAgICAgICAgICAgICAgLy8gQXNzdW1lIHRoYXQgYWxsIHRpbWVzIGJlZm9yZSBvdXIgZmlyc3QgdHJhbnNpdGlvbiBhcmUgbm9uLWRheWxpZ2h0LgorICAgICAgICAgICAgICAgIC8vIFRyYW5zaXRpb24gZGF0YSB0ZW5kcyB0byBzdGFydCB3aXRoIGEgdHJhbnNpdGlvbiB0byBkYXlsaWdodCwgc28ganVzdAorICAgICAgICAgICAgICAgIC8vIGNvcHlpbmcgdGhlIGZpcnN0IHRyYW5zaXRpb24gd291bGQgYXNzdW1lIHRoZSBvcHBvc2l0ZS4KKyAgICAgICAgICAgICAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTE0Mzk1CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBtSXNEc3RzW21UeXBlc1t0cmFuc2l0aW9uXSAmIDB4ZmZdID09IDE7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgZ2V0UmF3T2Zmc2V0KCkgeworICAgICAgICByZXR1cm4gbVJhd09mZnNldDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2V0UmF3T2Zmc2V0KGludCBvZmYpIHsKKyAgICAgICAgbVJhd09mZnNldCA9IG9mZjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gdXNlRGF5bGlnaHRUaW1lKCkgeworICAgICAgICByZXR1cm4gbVVzZURzdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzU2FtZVJ1bGVzKFRpbWVab25lIHRpbWVab25lKSB7CisgICAgICAgIGlmICghKHRpbWVab25lIGluc3RhbmNlb2YgWm9uZUluZm8pKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgWm9uZUluZm8gb3RoZXIgPSAoWm9uZUluZm8pIHRpbWVab25lOworICAgICAgICBpZiAobVVzZURzdCAhPSBvdGhlci5tVXNlRHN0KSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFtVXNlRHN0KSB7CisgICAgICAgICAgICByZXR1cm4gbVJhd09mZnNldCA9PSBvdGhlci5tUmF3T2Zmc2V0OworICAgICAgICB9CisgICAgICAgIHJldHVybiBtUmF3T2Zmc2V0ID09IG90aGVyLm1SYXdPZmZzZXQKKyAgICAgICAgICAgICAgICAvLyBBcnJheXMuZXF1YWxzIHJldHVybnMgdHJ1ZSBpZiBib3RoIGFycmF5cyBhcmUgbnVsbAorICAgICAgICAgICAgICAgICYmIEFycmF5cy5lcXVhbHMobU9mZnNldHMsIG90aGVyLm1PZmZzZXRzKQorICAgICAgICAgICAgICAgICYmIEFycmF5cy5lcXVhbHMobUlzRHN0cywgb3RoZXIubUlzRHN0cykKKyAgICAgICAgICAgICAgICAmJiBBcnJheXMuZXF1YWxzKG1UeXBlcywgb3RoZXIubVR5cGVzKQorICAgICAgICAgICAgICAgICYmIEFycmF5cy5lcXVhbHMobVRyYW5zaXRpb25zLCBvdGhlci5tVHJhbnNpdGlvbnMpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBab25lSW5mbykpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBab25lSW5mbyBvdGhlciA9IChab25lSW5mbykgb2JqOworICAgICAgICByZXR1cm4gZ2V0SUQoKS5lcXVhbHMob3RoZXIuZ2V0SUQoKSkgJiYgaGFzU2FtZVJ1bGVzKG90aGVyKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBmaW5hbCBpbnQgcHJpbWUgPSAzMTsKKyAgICAgICAgaW50IHJlc3VsdCA9IDE7CisgICAgICAgIHJlc3VsdCA9IHByaW1lICogcmVzdWx0ICsgZ2V0SUQoKS5oYXNoQ29kZSgpOworICAgICAgICByZXN1bHQgPSBwcmltZSAqIHJlc3VsdCArIEFycmF5cy5oYXNoQ29kZShtT2Zmc2V0cyk7CisgICAgICAgIHJlc3VsdCA9IHByaW1lICogcmVzdWx0ICsgQXJyYXlzLmhhc2hDb2RlKG1Jc0RzdHMpOworICAgICAgICByZXN1bHQgPSBwcmltZSAqIHJlc3VsdCArIG1SYXdPZmZzZXQ7CisgICAgICAgIHJlc3VsdCA9IHByaW1lICogcmVzdWx0ICsgQXJyYXlzLmhhc2hDb2RlKG1UcmFuc2l0aW9ucyk7CisgICAgICAgIHJlc3VsdCA9IHByaW1lICogcmVzdWx0ICsgQXJyYXlzLmhhc2hDb2RlKG1UeXBlcyk7CisgICAgICAgIHJlc3VsdCA9IHByaW1lICogcmVzdWx0ICsgKG1Vc2VEc3QgPyAxMjMxIDogMTIzNyk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIC8vIEZpcnN0IHRoZSBiYXNpY3MuLi4KKyAgICAgICAgc2IuYXBwZW5kKGdldENsYXNzKCkuZ2V0TmFtZSgpICsgIlsiICsgZ2V0SUQoKSArICIsbVJhd09mZnNldD0iICsgbVJhd09mZnNldCArCisgICAgICAgICAgICAgICAgIixtVXNlRHN0PSIgKyBtVXNlRHN0ICsgIl0iKTsKKyAgICAgICAgLy8gLi4uZm9sbG93ZWQgYnkgYSB6ZHVtcCgxKS1saWtlIGRlc2NyaXB0aW9uIG9mIGFsbCBvdXIgdHJhbnNpdGlvbiBkYXRhLgorICAgICAgICBzYi5hcHBlbmQoIlxuIik7CisgICAgICAgIEZvcm1hdHRlciBmID0gbmV3IEZvcm1hdHRlcihzYik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbVRyYW5zaXRpb25zLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICBpbnQgdHlwZSA9IG1UeXBlc1tpXSAmIDB4ZmY7CisgICAgICAgICAgICBTdHJpbmcgdXRjVGltZSA9IGZvcm1hdFRpbWUobVRyYW5zaXRpb25zW2ldLCBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiVVRDIikpOworICAgICAgICAgICAgU3RyaW5nIGxvY2FsVGltZSA9IGZvcm1hdFRpbWUobVRyYW5zaXRpb25zW2ldLCB0aGlzKTsKKyAgICAgICAgICAgIGludCBvZmZzZXQgPSBtT2Zmc2V0c1t0eXBlXTsKKyAgICAgICAgICAgIGludCBnbXRPZmZzZXQgPSBtUmF3T2Zmc2V0LzEwMDAgKyBvZmZzZXQ7CisgICAgICAgICAgICBmLmZvcm1hdCgiJTRkIDogdGltZT0lMTFkICVzID0gJXMgaXNEc3Q9JWQgb2Zmc2V0PSU1ZCBnbXRPZmZzZXQ9JWRcbiIsCisgICAgICAgICAgICAgICAgICAgIGksIG1UcmFuc2l0aW9uc1tpXSwgdXRjVGltZSwgbG9jYWxUaW1lLCBtSXNEc3RzW3R5cGVdLCBvZmZzZXQsIGdtdE9mZnNldCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGZvcm1hdFRpbWUoaW50IHMsIFRpbWVab25lIHR6KSB7CisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgc2RmID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoIkVFRSBNTU0gZGQgSEg6bW06c3MgeXl5eSB6enoiKTsKKyAgICAgICAgc2RmLnNldFRpbWVab25lKHR6KTsKKyAgICAgICAgbG9uZyBtcyA9ICgobG9uZykgcykgKiAxMDAwTDsKKyAgICAgICAgcmV0dXJuIHNkZi5mb3JtYXQobmV3IERhdGUobXMpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL1pvbmVJbmZvREIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9saWJjb3JlL3V0aWwvWm9uZUluZm9EQi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5YjY3ODQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvbGliY29yZS91dGlsL1pvbmVJbmZvREIuamF2YQpAQCAtMCwwICsxLDI3NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGU7CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlT3JkZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWwuTWFwTW9kZTsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRzOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CitpbXBvcnQgbGliY29yZS5pby5CdWZmZXJJdGVyYXRvcjsKK2ltcG9ydCBsaWJjb3JlLmlvLkVycm5vRXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUuaW8uSW9VdGlsczsKK2ltcG9ydCBsaWJjb3JlLmlvLk1lbW9yeU1hcHBlZEZpbGU7CisKKy8vIFRPRE86IHJlcGFja2FnZSB0aGlzIGNsYXNzLCB1c2VkIGJ5IGZyYW1ld29ya3MvYmFzZS4KK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS5pbnRlcm5hbC51dGlsLlRpbWV6b25lR2V0dGVyOworCisvKioKKyAqIEEgY2xhc3MgdXNlZCB0byBpbml0aWFsaXplIHRoZSB0aW1lIHpvbmUgZGF0YWJhc2UuICBUaGlzIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlCisgKiAnem9uZWluZm8nIGRhdGFiYXNlIGFzIHRoZSBzb3VyY2Ugb2YgdGltZSB6b25lIGluZm9ybWF0aW9uLiAgSG93ZXZlciwgdG8gY29uc2VydmUKKyAqIGRpc2sgc3BhY2UgdGhlIGRhdGEgZm9yIGFsbCB0aW1lIHpvbmVzIGFyZSBjb25jYXRlbmF0ZWQgaW50byBhIHNpbmdsZSBmaWxlLCBhbmQgYQorICogc2Vjb25kIGZpbGUgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc3RhcnRpbmcgcG9zaXRpb24gb2YgZWFjaCB0aW1lIHpvbmUgcmVjb3JkLiAgQQorICogdGhpcmQgZmlsZSBpbmRpY2F0ZXMgdGhlIHZlcnNpb24gb2YgdGhlIHpvbmVpbmZvIGRhdGFiYXNlIHVzZWQgdG8gZ2VuZXJhdGUgdGhlIGRhdGEuCisgKgorICogQGhpZGUgLSB1c2VkIHRvIGltcGxlbWVudCBUaW1lWm9uZQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgWm9uZUluZm9EQiB7CisgICAgLyoqCisgICAgICogVGhlIGRpcmVjdG9yeSBjb250YWluaW5nIHRoZSB0aW1lIHpvbmUgZGF0YWJhc2UgZmlsZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFpPTkVfRElSRUNUT1JZX05BTUUgPQorICAgICAgICAgICAgU3lzdGVtLmdldGVudigiQU5EUk9JRF9ST09UIikgKyAiL3Vzci9zaGFyZS96b25laW5mby8iOworCisgICAgLyoqCisgICAgICogVGhlIG5hbWUgb2YgdGhlIGZpbGUgY29udGFpbmluZyB0aGUgY29uY2F0ZW5hdGVkIHRpbWUgem9uZSByZWNvcmRzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBaT05FX0ZJTEVfTkFNRSA9IFpPTkVfRElSRUNUT1JZX05BTUUgKyAiem9uZWluZm8uZGF0IjsKKworICAgIC8qKgorICAgICAqIFRoZSBuYW1lIG9mIHRoZSBmaWxlIGNvbnRhaW5pbmcgdGhlIGluZGV4IHRvIGVhY2ggdGltZSB6b25lIHJlY29yZCB3aXRoaW4KKyAgICAgKiB0aGUgem9uZWluZm8uZGF0IGZpbGUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIElOREVYX0ZJTEVfTkFNRSA9IFpPTkVfRElSRUNUT1JZX05BTUUgKyAiem9uZWluZm8uaWR4IjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdCBMT0NLID0gbmV3IE9iamVjdCgpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFZFUlNJT04gPSByZWFkVmVyc2lvbigpOworCisgICAgLyoqCisgICAgICogUmF0aGVyIHRoYW4gb3BlbiwgcmVhZCwgYW5kIGNsb3NlIHRoZSBiaWcgZGF0YSBmaWxlIGVhY2ggdGltZSB3ZSBsb29rIHVwIGEgdGltZSB6b25lLAorICAgICAqIHdlIG1hcCB0aGUgYmlnIGRhdGEgZmlsZSBkdXJpbmcgc3RhcnR1cCwgYW5kIHRoZW4ganVzdCB1c2UgdGhlIE1lbW9yeU1hcHBlZEZpbGUuCisgICAgICoKKyAgICAgKiBBdCB0aGUgbW9tZW50LCB0aGlzICJiaWciIGRhdGEgZmlsZSBpcyBhYm91dCA1MDAgS2lCLiBBdCBzb21lIHBvaW50LCB0aGF0IHdpbGwgYmUgc21hbGwKKyAgICAgKiBlbm91Z2ggdGhhdCB3ZSdsbCBqdXN0IGtlZXAgdGhlIGJ5dGVbXSBpbiBtZW1vcnkuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWVtb3J5TWFwcGVkRmlsZSBBTExfWk9ORV9EQVRBID0gbWFwRGF0YSgpOworCisgICAgLyoqCisgICAgICogVGhlICdpZHMnIGFycmF5IGNvbnRhaW5zIHRpbWUgem9uZSBpZHMgc29ydGVkIGFscGhhYmV0aWNhbGx5LCBmb3IgYmluYXJ5IHNlYXJjaGluZy4KKyAgICAgKiBUaGUgb3RoZXIgdHdvIGFycmF5cyBhcmUgaW4gdGhlIHNhbWUgb3JkZXIuICdieXRlT2Zmc2V0cycgZ2l2ZXMgdGhlIGJ5dGUgb2Zmc2V0CisgICAgICogaW50byAiem9uZWluZm8uZGF0IiBvZiBlYWNoIHRpbWUgem9uZSwgYW5kICdyYXdVdGNPZmZzZXRzJyBnaXZlcyB0aGUgdGltZSB6b25lJ3MKKyAgICAgKiByYXcgVVRDIG9mZnNldC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBpZHM7CisgICAgcHJpdmF0ZSBzdGF0aWMgaW50W10gYnl0ZU9mZnNldHM7CisgICAgcHJpdmF0ZSBzdGF0aWMgaW50W10gcmF3VXRjT2Zmc2V0czsKKyAgICBzdGF0aWMgeworICAgICAgICByZWFkSW5kZXgoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFpvbmVJbmZvREIoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIGZpbGUgaW5kaWNhdGluZyB0aGUgZGF0YWJhc2UgdmVyc2lvbiBpbiB1c2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHJlYWRWZXJzaW9uKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnl0ZVtdIGJ5dGVzID0gSW9VdGlscy5yZWFkRmlsZUFzQnl0ZUFycmF5KFpPTkVfRElSRUNUT1JZX05BTUUgKyAiem9uZWluZm8udmVyc2lvbiIpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoYnl0ZXMsIDAsIGJ5dGVzLmxlbmd0aCwgQ2hhcnNldHMuSVNPXzg4NTlfMSkudHJpbSgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgTWVtb3J5TWFwcGVkRmlsZSBtYXBEYXRhKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIE1lbW9yeU1hcHBlZEZpbGUubW1hcFJPKFpPTkVfRklMRV9OQU1FKTsKKyAgICAgICAgfSBjYXRjaCAoRXJybm9FeGNlcHRpb24gZXJybm9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlcnJub0V4Y2VwdGlvbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUcmFkaXRpb25hbGx5LCBVbml4IHN5c3RlbXMgaGF2ZSBvbmUgZmlsZSBwZXIgdGltZSB6b25lLiBXZSBoYXZlIG9uZSBiaWcgZGF0YSBmaWxlLCB3aGljaAorICAgICAqIGlzIGp1c3QgYSBjb25jYXRlbmF0aW9uIG9mIHJlZ3VsYXIgdGltZSB6b25lIGZpbGVzLiBUbyBhbGxvdyByYW5kb20gYWNjZXNzIGludG8gdGhpcyBiaWcKKyAgICAgKiBkYXRhIGZpbGUsIHdlIGFsc28gaGF2ZSBhbiBpbmRleC4gV2UgcmVhZCB0aGUgaW5kZXggYXQgc3RhcnR1cCwgYW5kIGtlZXAgaXQgaW4gbWVtb3J5IHNvCisgICAgICogd2UgY2FuIGJpbmFyeSBzZWFyY2ggYnkgaWQgd2hlbiB3ZSBuZWVkIHRpbWUgem9uZSBkYXRhLgorICAgICAqCisgICAgICogVGhlIGZvcm1hdCBvZiB0aGlzIGZpbGUgaXMsIEkgYmVsaWV2ZSwgQW5kcm9pZCdzIG93biwgYW5kIHVuZG9jdW1lbnRlZC4KKyAgICAgKgorICAgICAqIEFsbCB0aGlzIGNvZGUgYXNzdW1lcyBzdHJpbmdzIGFyZSBVUy1BU0NJSS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHJlYWRJbmRleCgpIHsKKyAgICAgICAgTWVtb3J5TWFwcGVkRmlsZSBtYXBwZWRGaWxlID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1hcHBlZEZpbGUgPSBNZW1vcnlNYXBwZWRGaWxlLm1tYXBSTyhJTkRFWF9GSUxFX05BTUUpOworICAgICAgICAgICAgcmVhZEluZGV4KG1hcHBlZEZpbGUpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihleCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBJb1V0aWxzLmNsb3NlUXVpZXRseShtYXBwZWRGaWxlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcmVhZEluZGV4KE1lbW9yeU1hcHBlZEZpbGUgbWFwcGVkRmlsZSkgdGhyb3dzIEVycm5vRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ1ZmZlckl0ZXJhdG9yIGl0ID0gbWFwcGVkRmlsZS5iaWdFbmRpYW5JdGVyYXRvcigpOworCisgICAgICAgIC8vIFRoZSBkYXRhYmFzZSByZXNlcnZlcyA0MCBieXRlcyBmb3IgZWFjaCBpZC4KKyAgICAgICAgZmluYWwgaW50IFNJWkVPRl9UWk5BTUUgPSA0MDsKKyAgICAgICAgLy8gVGhlIGRhdGFiYXNlIHVzZXMgMzItYml0ICg0IGJ5dGUpIGludGVnZXJzLgorICAgICAgICBmaW5hbCBpbnQgU0laRU9GX1RaSU5UID0gNDsKKworICAgICAgICBieXRlW10gaWRCeXRlcyA9IG5ldyBieXRlW1NJWkVPRl9UWk5BTUVdOworICAgICAgICBpbnQgbnVtRW50cmllcyA9IChpbnQpIG1hcHBlZEZpbGUuc2l6ZSgpIC8gKFNJWkVPRl9UWk5BTUUgKyAzKlNJWkVPRl9UWklOVCk7CisKKyAgICAgICAgY2hhcltdIGlkQ2hhcnMgPSBuZXcgY2hhcltudW1FbnRyaWVzICogU0laRU9GX1RaTkFNRV07CisgICAgICAgIGludFtdIGlkRW5kID0gbmV3IGludFtudW1FbnRyaWVzXTsKKyAgICAgICAgaW50IGlkT2Zmc2V0ID0gMDsKKworICAgICAgICBieXRlT2Zmc2V0cyA9IG5ldyBpbnRbbnVtRW50cmllc107CisgICAgICAgIHJhd1V0Y09mZnNldHMgPSBuZXcgaW50W251bUVudHJpZXNdOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtRW50cmllczsgaSsrKSB7CisgICAgICAgICAgICBpdC5yZWFkQnl0ZUFycmF5KGlkQnl0ZXMsIDAsIGlkQnl0ZXMubGVuZ3RoKTsKKyAgICAgICAgICAgIGJ5dGVPZmZzZXRzW2ldID0gaXQucmVhZEludCgpOworICAgICAgICAgICAgaW50IGxlbmd0aCA9IGl0LnJlYWRJbnQoKTsKKyAgICAgICAgICAgIGlmIChsZW5ndGggPCA0NCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigibGVuZ3RoIGluIGluZGV4IGZpbGUgPCBzaXplb2YodHpoZWFkKSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmF3VXRjT2Zmc2V0c1tpXSA9IGl0LnJlYWRJbnQoKTsKKworICAgICAgICAgICAgLy8gRG9uJ3QgaW5jbHVkZSBudWxsIGNoYXJzIGluIHRoZSBTdHJpbmcKKyAgICAgICAgICAgIGludCBsZW4gPSBpZEJ5dGVzLmxlbmd0aDsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbGVuOyBqKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoaWRCeXRlc1tqXSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZENoYXJzW2lkT2Zmc2V0KytdID0gKGNoYXIpIChpZEJ5dGVzW2pdICYgMHhGRik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlkRW5kW2ldID0gaWRPZmZzZXQ7CisgICAgICAgIH0KKworICAgICAgICAvLyBXZSBjcmVhdGUgb25lIHN0cmluZyBjb250YWluaW5nIGFsbCB0aGUgaWRzLCBhbmQgdGhlbiBicmVhayB0aGF0IGludG8gc3Vic3RyaW5ncy4KKyAgICAgICAgLy8gVGhpcyB3YXksIGFsbCBpZHMgc2hhcmUgYSBzaW5nbGUgY2hhcltdIG9uIHRoZSBoZWFwLgorICAgICAgICBTdHJpbmcgYWxsSWRzID0gbmV3IFN0cmluZyhpZENoYXJzLCAwLCBpZE9mZnNldCk7CisgICAgICAgIGlkcyA9IG5ldyBTdHJpbmdbbnVtRW50cmllc107CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtRW50cmllczsgaSsrKSB7CisgICAgICAgICAgICBpZHNbaV0gPSBhbGxJZHMuc3Vic3RyaW5nKGkgPT0gMCA/IDAgOiBpZEVuZFtpIC0gMV0sIGlkRW5kW2ldKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFRpbWVab25lIG1ha2VUaW1lWm9uZShTdHJpbmcgaWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFdvcmsgb3V0IHdoZXJlIGluIHRoZSBiaWcgZGF0YSBmaWxlIHRoaXMgdGltZSB6b25lIGlzLgorICAgICAgICBpbnQgaW5kZXggPSBBcnJheXMuYmluYXJ5U2VhcmNoKGlkcywgaWQpOworICAgICAgICBpZiAoaW5kZXggPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEJ1ZmZlckl0ZXJhdG9yIGRhdGEgPSBBTExfWk9ORV9EQVRBLmJpZ0VuZGlhbkl0ZXJhdG9yKCk7CisgICAgICAgIGRhdGEuc2tpcChieXRlT2Zmc2V0c1tpbmRleF0pOworCisgICAgICAgIC8vIFZhcmlhYmxlIG5hbWVzIGJlZ2lubmluZyB0emhfIGNvcnJlc3BvbmQgdG8gdGhvc2UgaW4gInR6ZmlsZS5oIi4KKyAgICAgICAgLy8gQ2hlY2sgdHpoX21hZ2ljLgorICAgICAgICBpZiAoZGF0YS5yZWFkSW50KCkgIT0gMHg1NDVhNjk2NikgeyAvLyAiVFppZiIKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgLy8gU2tpcCB0aGUgdW5pbnRlcmVzdGluZyBwYXJ0IG9mIHRoZSBoZWFkZXIuCisgICAgICAgIGRhdGEuc2tpcCgyOCk7CisKKyAgICAgICAgLy8gUmVhZCB0aGUgc2l6ZXMgb2YgdGhlIGFycmF5cyB3ZSdyZSBhYm91dCB0byByZWFkLgorICAgICAgICBpbnQgdHpoX3RpbWVjbnQgPSBkYXRhLnJlYWRJbnQoKTsKKyAgICAgICAgaW50IHR6aF90eXBlY250ID0gZGF0YS5yZWFkSW50KCk7CisKKyAgICAgICAgZGF0YS5za2lwKDQpOyAvLyBTa2lwIHR6aF9jaGFyY250LgorCisgICAgICAgIGludFtdIHRyYW5zaXRpb25zID0gbmV3IGludFt0emhfdGltZWNudF07CisgICAgICAgIGRhdGEucmVhZEludEFycmF5KHRyYW5zaXRpb25zLCAwLCB0cmFuc2l0aW9ucy5sZW5ndGgpOworCisgICAgICAgIGJ5dGVbXSB0eXBlID0gbmV3IGJ5dGVbdHpoX3RpbWVjbnRdOworICAgICAgICBkYXRhLnJlYWRCeXRlQXJyYXkodHlwZSwgMCwgdHlwZS5sZW5ndGgpOworCisgICAgICAgIGludFtdIGdtdE9mZnNldHMgPSBuZXcgaW50W3R6aF90eXBlY250XTsKKyAgICAgICAgYnl0ZVtdIGlzRHN0cyA9IG5ldyBieXRlW3R6aF90eXBlY250XTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0emhfdHlwZWNudDsgKytpKSB7CisgICAgICAgICAgICBnbXRPZmZzZXRzW2ldID0gZGF0YS5yZWFkSW50KCk7CisgICAgICAgICAgICBpc0RzdHNbaV0gPSBkYXRhLnJlYWRCeXRlKCk7CisgICAgICAgICAgICAvLyBXZSBza2lwIHRoZSBhYmJyZXZpYXRpb24gaW5kZXguIFRoaXMgd291bGQgbGV0IHVzIHByb3ZpZGUgaGlzdG9yaWNhbGx5LWFjY3VyYXRlCisgICAgICAgICAgICAvLyB0aW1lIHpvbmUgYWJicmV2aWF0aW9ucyAoc3VjaCBhcyAiQUhTVCIsICJZU1QiLCBhbmQgIkFLU1QiIGZvciBzdGFuZGFyZCB0aW1lIGluCisgICAgICAgICAgICAvLyBBbWVyaWNhL0FuY2hvcmFnZSBpbiAxOTgyLCAxOTgzLCBhbmQgMTk4NCByZXNwZWN0aXZlbHkpLiBJQ1Ugb25seSBrbm93cyB0aGUgY3VycmVudAorICAgICAgICAgICAgLy8gbmFtZXMsIHRob3VnaCwgc28gZXZlbiBpZiB3ZSBkaWQgdXNlIHRoaXMgZGF0YSB0byBwcm92aWRlIHRoZSBjb3JyZWN0IGFiYnJldmlhdGlvbnMKKyAgICAgICAgICAgIC8vIGZvciBlbl9VUywgd2Ugd291bGRuJ3QgYmUgYWJsZSB0byBwcm92aWRlIGNvcnJlY3QgYWJicmV2aWF0aW9ucyBmb3Igb3RoZXIgbG9jYWxlcywKKyAgICAgICAgICAgIC8vIG5vciB3b3VsZCB3ZSBiZSBhYmxlIHRvIHByb3ZpZGUgY29ycmVjdCBsb25nIGZvcm1zIChzdWNoIGFzICJZdWtvbiBTdGFuZGFyZCBUaW1lIikKKyAgICAgICAgICAgIC8vIGZvciBhbnkgbG9jYWxlLiAoVGhlIFJJIGRvZXNuJ3QgZG8gYW55IGJldHRlciB0aGFuIHVzIGhlcmUgZWl0aGVyLikKKyAgICAgICAgICAgIGRhdGEuc2tpcCgxKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgWm9uZUluZm8oaWQsIHRyYW5zaXRpb25zLCB0eXBlLCBnbXRPZmZzZXRzLCBpc0RzdHMpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gZ2V0QXZhaWxhYmxlSURzKCkgeworICAgICAgICByZXR1cm4gaWRzLmNsb25lKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmdbXSBnZXRBdmFpbGFibGVJRHMoaW50IHJhd09mZnNldCkgeworICAgICAgICBMaXN0PFN0cmluZz4gbWF0Y2hlcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBmb3IgKGludCBpID0gMCwgZW5kID0gcmF3VXRjT2Zmc2V0cy5sZW5ndGg7IGkgPCBlbmQ7IGkrKykgeworICAgICAgICAgICAgaWYgKHJhd1V0Y09mZnNldHNbaV0gPT0gcmF3T2Zmc2V0KSB7CisgICAgICAgICAgICAgICAgbWF0Y2hlcy5hZGQoaWRzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbWF0Y2hlcy50b0FycmF5KG5ldyBTdHJpbmdbbWF0Y2hlcy5zaXplKCldKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFRpbWVab25lIGdldFN5c3RlbURlZmF1bHQoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoTE9DSykgeworICAgICAgICAgICAgVGltZXpvbmVHZXR0ZXIgdHpHZXR0ZXIgPSBUaW1lem9uZUdldHRlci5nZXRJbnN0YW5jZSgpOworICAgICAgICAgICAgU3RyaW5nIHpvbmVOYW1lID0gdHpHZXR0ZXIgIT0gbnVsbCA/IHR6R2V0dGVyLmdldElkKCkgOiBudWxsOworICAgICAgICAgICAgaWYgKHpvbmVOYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB6b25lTmFtZSA9IHpvbmVOYW1lLnRyaW0oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh6b25lTmFtZSA9PSBudWxsIHx8IHpvbmVOYW1lLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIC8vIHVzZSBsb2NhbHRpbWUgZm9yIHRoZSBzaW11bGF0b3IKKyAgICAgICAgICAgICAgICAvLyBUT0RPOiB3aGF0IGRvZXMgdGhhdCBjb3JyZXNwb25kIHRvPworICAgICAgICAgICAgICAgIHpvbmVOYW1lID0gImxvY2FsdGltZSI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gVGltZVpvbmUuZ2V0VGltZVpvbmUoem9uZU5hbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBUaW1lWm9uZSBnZXRUaW1lWm9uZShTdHJpbmcgaWQpIHsKKyAgICAgICAgaWYgKGlkID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gbWFrZVRpbWVab25lKGlkKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRWZXJzaW9uKCkgeworICAgICAgICByZXR1cm4gVkVSU0lPTjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by9pbnRlcm5hbC9OdWxsQ2lwaGVyU3BpLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by9pbnRlcm5hbC9OdWxsQ2lwaGVyU3BpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjcwZjYzYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL2ludGVybmFsL051bGxDaXBoZXJTcGkuamF2YQpAQCAtMCwwICsxLDE3MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQm9yaXMgVi4gS3V6bmV0c292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by5pbnRlcm5hbDsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CitpbXBvcnQgamF2YXguY3J5cHRvLkJhZFBhZGRpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXguY3J5cHRvLkNpcGhlclNwaTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2hvcnRCdWZmZXJFeGNlcHRpb247CisKKy8qKgorICogQ2lwaGVyU3BpIGltcGxlbWVudGF0aW9uIGZvciBqYXZheC5jcnlwdG8uTnVsbENpcGhlcgorICoKKyAqLworcHVibGljIGNsYXNzIE51bGxDaXBoZXJTcGkgZXh0ZW5kcyBDaXBoZXJTcGkgeworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZW5naW5lU2V0TW9kZShTdHJpbmcgYXJnMCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIC8vIERvIG5vdGhpbmcKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVTZXRQYWRkaW5nKFN0cmluZyBhcmcwKSB0aHJvd3MgTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIERvIG5vdGhpbmcKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGVuZ2luZUdldEJsb2NrU2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBlbmdpbmVHZXRPdXRwdXRTaXplKGludCBpbnB1dExlbikgeworICAgICAgICByZXR1cm4gaW5wdXRMZW47CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGVbXSBlbmdpbmVHZXRJVigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBieXRlWzhdOyAvLyBjb21wYXRpYmxlIHdpdGggUkkKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQWxnb3JpdGhtUGFyYW1ldGVycyBlbmdpbmVHZXRQYXJhbWV0ZXJzKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVJbml0KGludCBvcG1vZGUsIEtleSBrZXksIFNlY3VyZVJhbmRvbSByYW5kb20pCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIC8vIERvIG5vdGhpbmcKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVJbml0KGludCBvcG1vZGUsIEtleSBrZXksIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1zLAorICAgICAgICAgICAgU2VjdXJlUmFuZG9tIHJhbmRvbSkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gRG8gbm90aGluZworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGVuZ2luZUluaXQoaW50IG9wbW9kZSwgS2V5IGtleSwgQWxnb3JpdGhtUGFyYW1ldGVycyBwYXJhbXMsCisgICAgICAgICAgICBTZWN1cmVSYW5kb20gcmFuZG9tKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICAvLyBEbyBub3RoaW5nCisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGVbXSBlbmdpbmVVcGRhdGUoYnl0ZVtdIGlucHV0LCBpbnQgaW5wdXRPZmZzZXQsIGludCBpbnB1dExlbikgeworICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW2lucHV0TGVuXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShpbnB1dCwgaW5wdXRPZmZzZXQsIHJlc3VsdCwgMCwgaW5wdXRMZW4pOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZW5naW5lVXBkYXRlKGJ5dGVbXSBpbnB1dCwgaW50IGlucHV0T2Zmc2V0LCBpbnQgaW5wdXRMZW4sCisgICAgICAgICAgICBieXRlW10gb3V0cHV0LCBpbnQgb3V0cHV0T2Zmc2V0KSB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24geworICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShpbnB1dCwgaW5wdXRPZmZzZXQsIG91dHB1dCwgb3V0cHV0T2Zmc2V0LCBpbnB1dExlbik7CisgICAgICAgIHJldHVybiBpbnB1dExlbjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGVuZ2luZVVwZGF0ZShCeXRlQnVmZmVyIGlucHV0LCBCeXRlQnVmZmVyIG91dHB1dCkKKyAgICAgICAgICAgIHRocm93cyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpbnB1dCA9PSBudWxsIHx8IG91dHB1dCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgcmVzdWx0ID0gaW5wdXQubGltaXQoKSAtIGlucHV0LnBvc2l0aW9uKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXRwdXQucHV0KGlucHV0KTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5uaW8uQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNob3J0QnVmZmVyRXhjZXB0aW9uKCJvdXRwdXQgYnVmZmVyIHRvbyBzbWFsbCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGVbXSBlbmdpbmVEb0ZpbmFsKGJ5dGVbXSBpbnB1dCwgaW50IGlucHV0T2Zmc2V0LCBpbnQgaW5wdXRMZW4pCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiwgQmFkUGFkZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpbnB1dCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5naW5lVXBkYXRlKGlucHV0LCBpbnB1dE9mZnNldCwgaW5wdXRMZW4pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZW5naW5lRG9GaW5hbChieXRlW10gaW5wdXQsIGludCBpbnB1dE9mZnNldCwgaW50IGlucHV0TGVuLAorICAgICAgICAgICAgYnl0ZVtdIG91dHB1dCwgaW50IG91dHB1dE9mZnNldCkgdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiwgQmFkUGFkZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByZXN1bHQgPSBlbmdpbmVVcGRhdGUoaW5wdXQsIGlucHV0T2Zmc2V0LCBpbnB1dExlbiwgb3V0cHV0LAorICAgICAgICAgICAgICAgIG91dHB1dE9mZnNldCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBlbmdpbmVEb0ZpbmFsKEJ5dGVCdWZmZXIgaW5wdXQsIEJ5dGVCdWZmZXIgb3V0cHV0KQorICAgICAgICAgICAgdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uLCBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uLAorICAgICAgICAgICAgQmFkUGFkZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBlbmdpbmVVcGRhdGUoaW5wdXQsIG91dHB1dCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGVbXSBlbmdpbmVXcmFwKEtleSBrZXkpIHRocm93cyBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uLCBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEtleSBlbmdpbmVVbndyYXAoYnl0ZVtdIHdyYXBwZWRLZXksIFN0cmluZyB3cmFwcGVkS2V5QWxnb3JpdGhtLAorICAgICAgICAgICAgaW50IHdyYXBwZWRLZXlUeXBlKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZW5naW5lR2V0S2V5U2l6ZShLZXkga2V5KSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkva2VybmVsL3ZtL1N0cmluZ1V0aWxzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2tlcm5lbC92bS9TdHJpbmdVdGlscy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAxZDBlMzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2tlcm5lbC92bS9TdHJpbmdVdGlscy5qYXZhCkBAIC0wLDAgKzEsNjMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5rZXJuZWwudm07CisKKy8qKgorICogU3RyaW5nIHV0aWxpdHkgZnVuY3Rpb25zLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU3RyaW5nVXRpbHMgeworICAgIC8qKgorICAgICAqIFRoaXMgY2xhc3MgaXMgdW5pbnN0YW50aWFibGUuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmdVdGlscygpIHsKKyAgICAgICAgLy8gVGhpcyBzcGFjZSBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsuCisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tYmluZSBhIGxpc3Qgb2Ygc3RyaW5ncyBpbiBhbiA8Y29kZT5PYmplY3RbXTwvY29kZT4gaW50byBhIHNpbmdsZQorICAgICAqIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsaXN0IG5vbi1udWxsOyB0aGUgc3RyaW5ncyB0byBjb21iaW5lCisgICAgICogQHJldHVybiBub24tbnVsbDsgdGhlIGNvbWJpbmVkIGZvcm0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBjb21iaW5lU3RyaW5ncyhPYmplY3RbXSBsaXN0KSB7CisgICAgICAgIGludCBsaXN0TGVuZ3RoID0gbGlzdC5sZW5ndGg7CisKKyAgICAgICAgc3dpdGNoIChsaXN0TGVuZ3RoKSB7CisgICAgICAgICAgICBjYXNlIDA6IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gIiI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYXNlIDE6IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gKFN0cmluZykgbGlzdFswXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGludCBzdHJMZW5ndGggPSAwOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGlzdExlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBzdHJMZW5ndGggKz0gKChTdHJpbmcpIGxpc3RbaV0pLmxlbmd0aCgpOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKHN0ckxlbmd0aCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsaXN0TGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZChsaXN0W2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbGFuZy9hbm5vdGF0aW9uL0Fubm90YXRpb25GYWN0b3J5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2xhbmcvYW5ub3RhdGlvbi9Bbm5vdGF0aW9uRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNmZDEzZjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2xhbmcvYW5ub3RhdGlvbi9Bbm5vdGF0aW9uRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMzE3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5sYW5nLmFubm90YXRpb247CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5JbmNvbXBsZXRlQW5ub3RhdGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uSGFuZGxlcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuUHJveHk7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5XZWFrSGFzaE1hcDsKK2ltcG9ydCBzdGF0aWMgb3JnLmFwYWNoZS5oYXJtb255LmxhbmcuYW5ub3RhdGlvbi5Bbm5vdGF0aW9uTWVtYmVyLkFSUkFZOworaW1wb3J0IHN0YXRpYyBvcmcuYXBhY2hlLmhhcm1vbnkubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb25NZW1iZXIuRVJST1I7CisKKy8qKgorICogVGhlIGFubm90YXRpb24gaW1wbGVtZW50YXRpb24gYmFzZWQgb24gZHluYW1pY2FsbHkgZ2VuZXJhdGVkIHByb3h5IGluc3RhbmNlcy4KKyAqIEl0IGNvbmZvcm1zIHRvIGFsbCByZXF1aXJlbWVudHMgc3RhdGVkIGluIHB1YmxpYyBBUElzLCBzZWUgaW4gcGFydGljdWxhcgorICoge0BsaW5rIGphdmEubGFuZy5yZWZsZWN0LkFubm90YXRlZEVsZW1lbnQgamF2YS5sYW5nLnJlZmxlY3QuQW5ub3RhdGVkRWxlbWVudH0KKyAqIGFuZCB7QGxpbmsgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbiBqYXZhLmxhbmcuYW5ub3RhdGlvbi5Bbm5vdGF0aW9ufS4KKyAqIE5hbWVseSwgYW5ub3RhdGlvbiBpbnN0YW5jZXMgYXJlIGltbXV0YWJsZSBhbmQgc2VyaWFsaXphYmxlOyB0aGV5IHByb3ZpZGUKKyAqIGNvbmZvcm1pbmcgYWNjZXNzIHRvIGFubm90YXRpb24gbWVtYmVyIHZhbHVlcyBhbmQgcmVxdWlyZWQgaW1wbGVtZW50YXRpb25zIG9mCisgKiBtZXRob2RzIGRlY2xhcmVkIGluIEFubm90YXRpb24gaW50ZXJmYWNlLgorICoKKyAqIEBzZWUgYW5kcm9pZC5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbk1lbWJlcgorICogQHNlZSBqYXZhLmxhbmcuYW5ub3RhdGlvbi5Bbm5vdGF0aW9uCisgKgorICogQGF1dGhvciBBbGV4ZXkgVi4gVmFybGFtb3YsIFNlcmd1ZWkgUy4gWmFwcmV5ZXYKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworQFN1cHByZXNzV2FybmluZ3MoeyJzZXJpYWwifSkKK3B1YmxpYyBmaW5hbCBjbGFzcyBBbm5vdGF0aW9uRmFjdG9yeSBpbXBsZW1lbnRzIEludm9jYXRpb25IYW5kbGVyLCBTZXJpYWxpemFibGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgdHJhbnNpZW50CisgICAgTWFwPENsYXNzPD8gZXh0ZW5kcyBBbm5vdGF0aW9uPiwgQW5ub3RhdGlvbk1lbWJlcltdPgorICAgIGNhY2hlID0gbmV3IFdlYWtIYXNoTWFwPENsYXNzPD8gZXh0ZW5kcyBBbm5vdGF0aW9uPiwgQW5ub3RhdGlvbk1lbWJlcltdPigpOworCisgICAgLyoqCisgICAgICogUmVmbGVjdHMgc3BlY2lmaWVkIGFubm90YXRpb24gdHlwZSBhbmQgcmV0dXJucyBhbiBhcnJheQorICAgICAqIG9mIG1lbWJlciBlbGVtZW50IGRlZmluaXRpb25zIHdpdGggZGVmYXVsdCB2YWx1ZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBBbm5vdGF0aW9uTWVtYmVyW10gZ2V0RWxlbWVudHNEZXNjcmlwdGlvbihDbGFzczw/IGV4dGVuZHMgQW5ub3RhdGlvbj4gYW5ub3RhdGlvblR5cGUgKSB7CisgICAgICAgIEFubm90YXRpb25NZW1iZXJbXSBkZXNjID0gY2FjaGUuZ2V0KGFubm90YXRpb25UeXBlKTsKKyAgICAgICAgaWYgKGRlc2MgPT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKCFhbm5vdGF0aW9uVHlwZS5pc0Fubm90YXRpb24oKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlR5cGUgaXMgbm90IGFubm90YXRpb246ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgYW5ub3RhdGlvblR5cGUuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIE1ldGhvZFtdIG0gPSBhbm5vdGF0aW9uVHlwZS5nZXREZWNsYXJlZE1ldGhvZHMoKTsKKyAgICAgICAgICAgIGRlc2MgPSBuZXcgQW5ub3RhdGlvbk1lbWJlclttLmxlbmd0aF07CisgICAgICAgICAgICBpbnQgaWR4ID0gMDsKKyAgICAgICAgICAgIGZvciAoTWV0aG9kIGVsZW1lbnQgOiBtKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBlbGVtZW50LmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICBDbGFzczw/PiB0eXBlID0gZWxlbWVudC5nZXRSZXR1cm5UeXBlKCk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZGVzY1tpZHhdID0gbmV3IEFubm90YXRpb25NZW1iZXIobmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmdldERlZmF1bHRWYWx1ZSgpLCB0eXBlLCBlbGVtZW50KTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgICAgICAgICBkZXNjW2lkeF0gPSBuZXcgQW5ub3RhdGlvbk1lbWJlcihuYW1lLCB0LCB0eXBlLCBlbGVtZW50KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWR4Kys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYWNoZS5wdXQoYW5ub3RhdGlvblR5cGUsIGRlc2MpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkZXNjOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb3ZpZGVzIGEgbmV3IGFubm90YXRpb24gaW5zdGFuY2UuCisgICAgICogQHBhcmFtIGFubm90YXRpb25UeXBlIHRoZSBhbm5vdGF0aW9uIHR5cGUgZGVmaW5pdGlvbgorICAgICAqIEBwYXJhbSBlbGVtZW50cyBuYW1lLXZhbHVlIHBhaXJzIHJlcHJlc2VudGluZyBlbGVtZW50cyBvZiB0aGUgYW5ub3RhdGlvbgorICAgICAqIEByZXR1cm4gYSBuZXcgYW5ub3RhdGlvbiBpbnN0YW5jZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQW5ub3RhdGlvbiBjcmVhdGVBbm5vdGF0aW9uKAorICAgICAgICAgICAgQ2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+IGFubm90YXRpb25UeXBlLAorICAgICAgICAgICAgQW5ub3RhdGlvbk1lbWJlcltdIGVsZW1lbnRzKQorICAgIHsKKyAgICAgICAgQW5ub3RhdGlvbkZhY3RvcnkgYW50biA9IG5ldyBBbm5vdGF0aW9uRmFjdG9yeShhbm5vdGF0aW9uVHlwZSwgZWxlbWVudHMpOworICAgICAgICByZXR1cm4gKEFubm90YXRpb24pUHJveHkubmV3UHJveHlJbnN0YW5jZSggYW5ub3RhdGlvblR5cGUuZ2V0Q2xhc3NMb2FkZXIoKSwKKyAgICAgICAgICAgICAgICBuZXcgQ2xhc3NbXXthbm5vdGF0aW9uVHlwZX0sIGFudG4pOworICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgQ2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+IGtsYXp6OworICAgIHByaXZhdGUgQW5ub3RhdGlvbk1lbWJlcltdIGVsZW1lbnRzOworCisgICAgLyoqCisgICAgICogTmV3IGluc3RhbmNlcyBzaG91bGQgbm90IGJlIGNyZWF0ZWQgZGlyZWN0bHksIHVzZSBmYWN0b3J5IG1ldGhvZAorICAgICAqIHtAbGluayAjY3JlYXRlQW5ub3RhdGlvbihDbGFzcywgQW5ub3RhdGlvbk1lbWJlcltdKSBjcmVhdGVBbm5vdGF0aW9uKCl9CisgICAgICogaW5zdGVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrbHp6IGNsYXNzIGRlZmluaW5nIHRoZSBhbm5vdGF0aW9uIHR5cGUKKyAgICAgKiBAcGFyYW0gdmFsdWVzIGFjdHVhbCBlbGVtZW50IHZhbHVlcworICAgICAqLworICAgIHByaXZhdGUgQW5ub3RhdGlvbkZhY3RvcnkoQ2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+IGtsenosIEFubm90YXRpb25NZW1iZXJbXSB2YWx1ZXMpIHsKKyAgICAgICAga2xhenogPSBrbHp6OworICAgICAgICBBbm5vdGF0aW9uTWVtYmVyW10gZGVmcyA9IGdldEVsZW1lbnRzRGVzY3JpcHRpb24oa2xhenopOworICAgICAgICBpZiAodmFsdWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIGVsZW1lbnRzID0gZGVmczsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vbWVyZ2UgZGVmYXVsdCBhbmQgYWN0dWFsIHZhbHVlcworICAgICAgICAgICAgZWxlbWVudHMgPSBuZXcgQW5ub3RhdGlvbk1lbWJlcltkZWZzLmxlbmd0aF07CisgICAgICAgICAgICBuZXh0OiBmb3IgKGludCBpID0gZWxlbWVudHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0gKXsKKyAgICAgICAgICAgICAgICBmb3IgKEFubm90YXRpb25NZW1iZXIgdmFsIDogdmFsdWVzKXsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHZhbC5uYW1lLmVxdWFscyhkZWZzW2ldLm5hbWUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50c1tpXSA9IHZhbC5zZXREZWZpbml0aW9uKGRlZnNbaV0pOworICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgbmV4dDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbGVtZW50c1tpXSA9IGRlZnNbaV07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB0aGUgb2JqZWN0LCBvYnRhaW5zIGFjdHVhbCBtZW1iZXIgZGVmaW5pdGlvbnMgZm9yIHRoZSBhbm5vdGF0aW9uIHR5cGUsCisgICAgICogYW5kIG1lcmdlcyBkZXNlcmlhbGl6ZWQgdmFsdWVzIHdpdGggdGhlIG5ldyBkZWZpbml0aW9ucy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBvcy5kZWZhdWx0UmVhZE9iamVjdCgpOworICAgICAgICAvLyBBbm5vdGF0aW9uIHR5cGUgbWVtYmVycyBjYW4gYmUgY2hhbmdlZCBhcmJpdHJhcmlseQorICAgICAgICAvLyBTbyB0aGVyZSBtYXkgYmUgem9tYmkgZWxlbWVudHMgZnJvbSB0aGUgcHJldmlvdXMgbGlmZTsKKyAgICAgICAgLy8gdGhleSBoYXJkbHkgZml0IGludG8gdGhpcyBuZXcgYW5ub3RhdGlvbidzIGluY2FybmF0aW9uLAorICAgICAgICAvLyBhcyB3ZSBoYXZlIG5vIGRlZmluaW5nIG1ldGhvZHMgZm9yIHRoZW0uCisgICAgICAgIC8vIFJlYXNvbmFibHkganVzdCBkcm9wIHN1Y2ggZWxlbWVudHMsCisgICAgICAgIC8vIGJ1dCBzZWVtcyBiZXR0ZXIgdG8ga2VlcCB0aGVtIGZvciBjb21wYXRpYmlsaXR5CisgICAgICAgIEFubm90YXRpb25NZW1iZXJbXSBkZWZzID0gZ2V0RWxlbWVudHNEZXNjcmlwdGlvbihrbGF6eik7CisgICAgICAgIEFubm90YXRpb25NZW1iZXJbXSBvbGQgPSBlbGVtZW50czsKKyAgICAgICAgTGlzdDxBbm5vdGF0aW9uTWVtYmVyPiBtZXJnZWQgPSBuZXcgQXJyYXlMaXN0PEFubm90YXRpb25NZW1iZXI+KAorICAgICAgICAgICAgICAgIGRlZnMubGVuZ3RoICsgb2xkLmxlbmd0aCk7CisgICAgICAgIG5leHRPbGQ6IGZvciAoQW5ub3RhdGlvbk1lbWJlciBlbDEgOiBvbGQpIHsKKyAgICAgICAgICAgIGZvciAoQW5ub3RhdGlvbk1lbWJlciBlbDIgOiBkZWZzKSB7CisgICAgICAgICAgICAgICAgaWYgKGVsMi5uYW1lLmVxdWFscyhlbDEubmFtZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWUgbmV4dE9sZDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtZXJnZWQuYWRkKGVsMSk7IC8vcGhhbnRvbSBlbGVtZW50CisgICAgICAgIH0KKyAgICAgICAgbmV4dE5ldzogZm9yIChBbm5vdGF0aW9uTWVtYmVyIGRlZiA6IGRlZnMpeworICAgICAgICAgICAgZm9yIChBbm5vdGF0aW9uTWVtYmVyIHZhbCA6IG9sZCl7CisgICAgICAgICAgICAgICAgaWYgKHZhbC5uYW1lLmVxdWFscyhkZWYubmFtZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gbm90aGluZyB0byBkbyBhYm91dCBjYWNoZWQgZXJyb3JzIChpZiBhbnkpCisgICAgICAgICAgICAgICAgICAgIC8vIGFueXdheSB0aGV5IHJlbWFpbiByZWxldmFudCB0byB2YWx1ZXMKKyAgICAgICAgICAgICAgICAgICAgbWVyZ2VkLmFkZCh2YWwuc2V0RGVmaW5pdGlvbihkZWYpKTsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWUgbmV4dE5ldzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtZXJnZWQuYWRkKGRlZik7IC8vIGJyYW5kIG5ldyBlbGVtZW50CisgICAgICAgIH0KKyAgICAgICAgZWxlbWVudHMgPSBtZXJnZWQudG9BcnJheShuZXcgQW5ub3RhdGlvbk1lbWJlclttZXJnZWQuc2l6ZSgpXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHJlcHJlc2VudHMgdGhlIHNhbWUgYW5ub3RhdGlvbiBpbnN0YW5jZS4KKyAgICAgKiBUaGF0IGlzLCBpZiBpdCBpbXBsZW1lbnRzIHRoZSBzYW1lIGFubm90YXRpb24gdHlwZSBhbmQKKyAgICAgKiByZXR1cm5zIHRoZSBzYW1lIGVsZW1lbnQgdmFsdWVzLgorICAgICAqIDxicj5Ob3RlLCBhY3R1YWwgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbiBtZWNoYW5pc20gZG9lcyBub3QgbWF0dGVyIC0gaXQgbWF5CisgICAgICogZGlmZmVyIGNvbXBsZXRlbHkgZnJvbSB0aGlzIGNsYXNzLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcGFzc2VkIG9iamVjdCBpcyBlcXVpdmFsZW50IGFubm90YXRpb24gaW5zdGFuY2UsCisgICAgICogZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEBzZWUgYW5kcm9pZC5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbk1lbWJlciNlcXVhbHMoT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgIGlmIChvYmogPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFrbGF6ei5pc0luc3RhbmNlKG9iaikpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBPYmplY3QgaGFuZGxlciA9IG51bGw7CisgICAgICAgIGlmIChQcm94eS5pc1Byb3h5Q2xhc3Mob2JqLmdldENsYXNzKCkpCisgICAgICAgICAgICAgICAgJiYgKGhhbmRsZXIgPSBQcm94eS5nZXRJbnZvY2F0aW9uSGFuZGxlcihvYmopKSBpbnN0YW5jZW9mIEFubm90YXRpb25GYWN0b3J5ICkgeworICAgICAgICAgICAgQW5ub3RhdGlvbkZhY3Rvcnkgb3RoZXIgPSAoQW5ub3RhdGlvbkZhY3RvcnkpIGhhbmRsZXI7CisgICAgICAgICAgICBpZiAoZWxlbWVudHMubGVuZ3RoICE9IG90aGVyLmVsZW1lbnRzLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG5leHQ6IGZvciAoQW5ub3RhdGlvbk1lbWJlciBlbDEgOiBlbGVtZW50cyl7CisgICAgICAgICAgICAgICAgZm9yIChBbm5vdGF0aW9uTWVtYmVyIGVsMiA6IG90aGVyLmVsZW1lbnRzKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChlbDEuZXF1YWxzKGVsMikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIG5leHQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBlbmNvdW50ZXJlZCBmb3JlaWduIGFubm90YXRpb24gaW1wbGVtZW50YXRvbgorICAgICAgICAgICAgLy8gc28gaGF2ZSB0byBvYnRhaW4gZWxlbWVudCB2YWx1ZXMgdmlhIGludm9jYXRpb24KKyAgICAgICAgICAgIC8vIG9mIGNvcnJlc3BvbmRpbmcgbWV0aG9kcworICAgICAgICAgICAgZm9yIChmaW5hbCBBbm5vdGF0aW9uTWVtYmVyIGVsIDogZWxlbWVudHMpIHsKKyAgICAgICAgICAgICAgICBpZiAoZWwudGFnID09IEVSUk9SKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIHVuZGVmaW5lZCB2YWx1ZSBpcyBpbmNvbXBhcmFibGUgKHRyYW5zY2VuZGVudCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBpZiAoIWVsLmRlZmluaW5nTWV0aG9kLmlzQWNjZXNzaWJsZSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBlbC5kZWZpbmluZ01ldGhvZC5zZXRBY2Nlc3NpYmxlKHRydWUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIE9iamVjdCBvdGhlclZhbHVlID0gZWwuZGVmaW5pbmdNZXRob2QuaW52b2tlKG9iaik7CisgICAgICAgICAgICAgICAgICAgIGlmIChvdGhlclZhbHVlICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWwudGFnID09IEFSUkFZKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFlbC5lcXVhbEFycmF5VmFsdWUob3RoZXJWYWx1ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFlbC52YWx1ZS5lcXVhbHMob3RoZXJWYWx1ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlbC52YWx1ZSAhPSBBbm5vdGF0aW9uTWVtYmVyLk5PX1ZBTFVFKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgaGFzaCBjb2RlIGNvbXBvc2VkIGFzIGEgc3VtIG9mIGhhc2ggY29kZXMgb2YgbWVtYmVyIGVsZW1lbnRzLAorICAgICAqIGluY2x1ZGluZyBlbGVtZW50cyB3aXRoIGRlZmF1bHQgdmFsdWVzLgorICAgICAqIEBzZWUgYW5kcm9pZC5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbk1lbWJlciNoYXNoQ29kZSgpCisgICAgICovCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaW50IGhhc2ggPSAwOworICAgICAgICBmb3IgKEFubm90YXRpb25NZW1iZXIgZWxlbWVudCA6IGVsZW1lbnRzKSB7CisgICAgICAgICAgICBoYXNoICs9IGVsZW1lbnQuaGFzaENvZGUoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm92aWRlcyBkZXRhaWxlZCBkZXNjcmlwdGlvbiBvZiB0aGlzIGFubm90YXRpb24gaW5zdGFuY2UsCisgICAgICogaW5jbHVkaW5nIGFsbCBtZW1iZXIgbmFtZS12YWx1ZXMgcGFpcnMuCisgICAgICogQHJldHVybiBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBhbm5vdGF0aW9uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICByZXN1bHQuYXBwZW5kKCdAJyk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQoa2xhenouZ2V0TmFtZSgpKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZCgnKCcpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICBpZiAoaSAhPSAwKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiLCAiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoZWxlbWVudHNbaV0pOworICAgICAgICB9CisgICAgICAgIHJlc3VsdC5hcHBlbmQoJyknKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyBhIG1ldGhvZCBpbnZvY2F0aW9uIHJlcXVlc3QgdG8gdGhpcyBhbm5vdGF0aW9uIGluc3RhbmNlLgorICAgICAqIFJlY29nbml6ZXMgdGhlIG1ldGhvZHMgZGVjbGFyZWQgaW4gdGhlCisgICAgICoge0BsaW5rIGphdmEubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb24gamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbn0KKyAgICAgKiBpbnRlcmZhY2UsIGFuZCBtZW1iZXItZGVmaW5pbmcgbWV0aG9kcyBvZiB0aGUgaW1wbGVtZW50ZWQgYW5ub3RhdGlvbiB0eXBlLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSBzcGVjaWZpZWQgbWV0aG9kIGlzIG5vbmUgb2YgdGhlIGFib3ZlCisgICAgICogQHJldHVybiB0aGUgaW52b2NhdGlvbiByZXN1bHQKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGludm9rZShPYmplY3QgcHJveHksIE1ldGhvZCBtZXRob2QsIE9iamVjdFtdIGFyZ3MpIHRocm93cyBUaHJvd2FibGUKKyAgICB7CisgICAgICAgIFN0cmluZyBuYW1lID0gbWV0aG9kLmdldE5hbWUoKTsKKyAgICAgICAgQ2xhc3NbXSBwYXJhbXMgPSBtZXRob2QuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgaWYgKHBhcmFtcy5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgaWYgKCJhbm5vdGF0aW9uVHlwZSIuZXF1YWxzKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGtsYXp6OworICAgICAgICAgICAgfSBlbHNlIGlmICgidG9TdHJpbmciLmVxdWFscyhuYW1lKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0b1N0cmluZygpOworICAgICAgICAgICAgfSBlbHNlIGlmICgiaGFzaENvZGUiLmVxdWFscyhuYW1lKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBoYXNoQ29kZSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB0aGlzIG11c3QgYmUgZWxlbWVudCB2YWx1ZSByZXF1ZXN0CisgICAgICAgICAgICBBbm5vdGF0aW9uTWVtYmVyIGVsZW1lbnQgPSBudWxsOworICAgICAgICAgICAgZm9yIChBbm5vdGF0aW9uTWVtYmVyIGVsIDogZWxlbWVudHMpIHsKKyAgICAgICAgICAgICAgICBpZiAobmFtZS5lcXVhbHMoZWwubmFtZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IGVsOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZWxlbWVudCA9PSBudWxsIHx8ICFtZXRob2QuZXF1YWxzKGVsZW1lbnQuZGVmaW5pbmdNZXRob2QpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihtZXRob2QudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IGVsZW1lbnQudmFsaWRhdGVWYWx1ZSgpOworICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbmNvbXBsZXRlQW5ub3RhdGlvbkV4Y2VwdGlvbihrbGF6eiwgbmFtZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChwYXJhbXMubGVuZ3RoID09IDEgJiYgcGFyYW1zWzBdID09IE9iamVjdC5jbGFzcyAmJiAiZXF1YWxzIi5lcXVhbHMobmFtZSkpeworICAgICAgICAgICAgcmV0dXJuIEJvb2xlYW4udmFsdWVPZihlcXVhbHMoYXJnc1swXSkpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgIkludmFsaWQgbWV0aG9kIGZvciBhbm5vdGF0aW9uIHR5cGU6ICIgKyBtZXRob2QpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbGFuZy9hbm5vdGF0aW9uL0Fubm90YXRpb25NZW1iZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbGFuZy9hbm5vdGF0aW9uL0Fubm90YXRpb25NZW1iZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNjQzMzJhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sYW5nL2Fubm90YXRpb24vQW5ub3RhdGlvbk1lbWJlci5qYXZhCkBAIC0wLDAgKzEsMzg3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5sYW5nLmFubm90YXRpb247CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvblR5cGVNaXNtYXRjaEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5BcnJheTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgbWVtYmVyIGVsZW1lbnQgb2YgYW4gYW5ub3RhdGlvbi4KKyAqIEl0IGNvbnNpc3RzIG9mIG5hbWUgYW5kIHZhbHVlLCBzdXBwbGVtZW50ZWQgd2l0aCBlbGVtZW50CisgKiBkZWZpbml0aW9uIGluZm9ybWF0aW9uIChzdWNoIGFzIGRlY2xhcmVkIHR5cGUgb2YgZWxlbWVudCkuCisgKiA8YnI+VGhlIHZhbHVlIG1heSBiZSBvbmUgb2YgdGhlIGZvbGxvd2luZyB0eXBlczoKKyAqIDx1bD4KKyAqIDxsaT4gYm94ZWQgcHJpbWl0aXZlCisgKiA8bGk+IENsYXNzCisgKiA8bGk+IGVudW0gY29uc3RhbnQKKyAqIDxsaT4gYW5ub3RhdGlvbiAobmVzdGVkKQorICogPGxpPiBvbmUtZGltZW5zaW9uYWwgYXJyYXkgb2YgdGhlIGFib3ZlCisgKiA8bGk+IFRocm93YWJsZQorICogPC91bD4KKyAqIFRoZSBsYXN0IHR5cGUgaXMgc3BlY2lmaWMgZm9yIHRoaXMgaW1wbGVtZW50YXRpb247IGEgVGhyb3dhYmxlIHZhbHVlCisgKiBtZWFucyB0aGF0IHRoZSBlcnJvciBvY2N1cmVkIGR1cmluZyBwYXJzaW5nIG9yIHJlc29sdXRpb24gb2YgY29ycmVzcG9uZGluZworICogY2xhc3MtZGF0YSBzdHJ1Y3R1cmVzIGFuZCB0aHJvd2luZyBpcyBkZWxheWVkIHVudGlsIHRoZSBlbGVtZW50CisgKiBpcyByZXF1ZXN0ZWQgZm9yIHZhbHVlLgorICoKKyAqIEBzZWUgYW5kcm9pZC5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbkZhY3RvcnkKKyAqCisgKiBAYXV0aG9yIEFsZXhleSBWLiBWYXJsYW1vdiwgU2VyZ3VlaSBTLiBaYXByZXlldgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCitAU3VwcHJlc3NXYXJuaW5ncyh7InNlcmlhbCJ9KQorcHVibGljIGNsYXNzIEFubm90YXRpb25NZW1iZXIgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgLyoqCisgICAgICogVGFnIGRlc2NyaXB0aW9uIG9mIGEgVGhyb3dhYmxlIHZhbHVlIHR5cGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBjaGFyIEVSUk9SID0gJyEnOworCisgICAgLyoqCisgICAgICogVGFnIGRlc2NyaXB0aW9uIG9mIGFuIGFycmF5IHZhbHVlIHR5cGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBjaGFyIEFSUkFZID0gJ1snOworCisgICAgLyoqCisgICAgICogVGFnIGRlc2NyaXB0aW9uIG9mIGFsbCB2YWx1ZSB0eXBlcyBleGNlcHQgYXJyYXlzIGFuZCBUaHJvd2FibGVzLgorICAgICAqLworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgY2hhciBPVEhFUiA9ICcqJzsKKworLy8gICAgcHVibGljIHN0YXRpYyBmaW5hbCBjaGFyIElOVCA9ICdJJzsKKy8vICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBDSEFSID0gJ0MnOworLy8gICAgcHVibGljIHN0YXRpYyBmaW5hbCBjaGFyIERPVUJMRSA9ICdEJzsKKy8vICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBGTE9BVCA9ICdGJzsKKy8vICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBCWVRFID0gJ0InOworLy8gICAgcHVibGljIHN0YXRpYyBmaW5hbCBjaGFyIExPTkcgPSAnSic7CisvLyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNoYXIgU0hPUlQgPSAnUyc7CisvLyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNoYXIgQk9PTCA9ICdaJzsKKy8vICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBDTEFTUyA9ICdjJzsKKy8vICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBFTlVNID0gJ2UnOworLy8gICAgcHVibGljIHN0YXRpYyBmaW5hbCBjaGFyIEFOVE4gPSAnQCc7CisKKyAgICBwcml2YXRlIGVudW0gRGVmYXVsdFZhbHVlcyB7Tk9fVkFMVUV9CisKKyAgICAvKioKKyAgICAgKiBTaW5nbGV0b24gcmVwcmVzZW50aW5nIG1pc3NpbmcgZWxlbWVudCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIE9iamVjdCBOT19WQUxVRSA9IERlZmF1bHRWYWx1ZXMuTk9fVkFMVUU7CisKKyAgICBwcm90ZWN0ZWQgZmluYWwgU3RyaW5nIG5hbWU7CisgICAgcHJvdGVjdGVkIGZpbmFsIE9iamVjdCB2YWx1ZTsgLy8gYSBwcmltaXRpdmUgdmFsdWUgaXMgd3JhcHBlZCB0byB0aGUgY29ycmVzcG9uZGluZyB3cmFwcGVyIGNsYXNzCisgICAgcHJvdGVjdGVkIGZpbmFsIGNoYXIgdGFnOworICAgIC8vIG5vIHNlbnNlIHRvIHNlcmlhbGl6ZSBkZWZpbml0aW9uIGluZm8gYXMgaXQgY2FuIGJlIGNoYW5nZWQgYXJiaXRyYXJpbHkKKyAgICBwcm90ZWN0ZWQgdHJhbnNpZW50IENsYXNzPD8+IGVsZW1lbnRUeXBlOworICAgIHByb3RlY3RlZCB0cmFuc2llbnQgTWV0aG9kIGRlZmluaW5nTWV0aG9kOworCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGVsZW1lbnQgd2l0aCBzcGVjaWZpZWQgbmFtZSBhbmQgdmFsdWUuCisgICAgICogRGVmaW5pdGlvbiBpbmZvIHdpbGwgYmUgcHJvdmlkZWQgbGF0ZXIgd2hlbiB0aGlzCisgICAgICogZWxlbWVudCBiZWNvbWVzIGFjdHVhbCBhbm5vdGF0aW9uIG1lbWJlci4KKyAgICAgKiBAcGFyYW0gbmFtZSBlbGVtZW50IG5hbWUsIG11c3Qgbm90IGJlIG51bGwKKyAgICAgKiBAcGFyYW0gdmFsIGVsZW1lbnQgdmFsdWUsIHNob3VsZCBiZSBvZiBhZGRtaXNzaWJsZSB0eXBlLAorICAgICAqIGFzIHNwZWNpZmllZCBpbiB0aGUgZGVzY3JpcHRpb24gb2YgdGhpcyBjbGFzcworICAgICAqCisgICAgICogQHNlZSAjc2V0RGVmaW5pdGlvbihBbm5vdGF0aW9uTWVtYmVyKQorICAgICAqLworICAgIHB1YmxpYyBBbm5vdGF0aW9uTWVtYmVyKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsKSB7CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgIHZhbHVlID0gdmFsID09IG51bGwgPyBOT19WQUxVRSA6IHZhbDsKKyAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgVGhyb3dhYmxlKSB7CisgICAgICAgICAgICB0YWcgPSBFUlJPUjsKKyAgICAgICAgfSBlbHNlIGlmICh2YWx1ZS5nZXRDbGFzcygpLmlzQXJyYXkoKSkgeworICAgICAgICAgICAgdGFnID0gQVJSQVk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0YWcgPSBPVEhFUjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIGNvbXBsZXRlbHkgZGVmaW5lZCBlbGVtZW50LgorICAgICAqIEBwYXJhbSBuYW1lIGVsZW1lbnQgbmFtZSwgbXVzdCBub3QgYmUgbnVsbAorICAgICAqIEBwYXJhbSB2YWx1ZSBlbGVtZW50IHZhbHVlLCBzaG91bGQgYmUgb2YgYWRkbWlzc2libGUgdHlwZSwKKyAgICAgKiBhcyBzcGVjaWZpZWQgaW4gdGhlIGRlc2NyaXB0aW9uIG9mIHRoaXMgY2xhc3MKKyAgICAgKiBAcGFyYW0gbSBlbGVtZW50LWRlZmluaW5nIG1ldGhvZCwgcmVmbGVjdGVkIG9uIHRoZSBhbm5vdGF0aW9uIHR5cGUKKyAgICAgKiBAcGFyYW0gdHlwZSBkZWNsYXJlZCB0eXBlIG9mIHRoaXMgZWxlbWVudAorICAgICAqIChyZXR1cm4gdHlwZSBvZiB0aGUgZGVmaW5pbmcgbWV0aG9kKQorICAgICAqLworICAgIHB1YmxpYyBBbm5vdGF0aW9uTWVtYmVyKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsLCBDbGFzcyB0eXBlLCBNZXRob2QgbSkgeworICAgICAgICB0aGlzKG5hbWUsIHZhbCk7CisKKyAgICAgICAgZGVmaW5pbmdNZXRob2QgPSBtOworCisgICAgICAgIGlmICh0eXBlID09IGludC5jbGFzcykgeworICAgICAgICAgICAgZWxlbWVudFR5cGUgPSBJbnRlZ2VyLmNsYXNzOworICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gYm9vbGVhbi5jbGFzcykgeworICAgICAgICAgICAgZWxlbWVudFR5cGUgPSBCb29sZWFuLmNsYXNzOworICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gY2hhci5jbGFzcykgeworICAgICAgICAgICAgZWxlbWVudFR5cGUgPSBDaGFyYWN0ZXIuY2xhc3M7CisgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBmbG9hdC5jbGFzcykgeworICAgICAgICAgICAgZWxlbWVudFR5cGUgPSBGbG9hdC5jbGFzczsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGRvdWJsZS5jbGFzcykgeworICAgICAgICAgICAgZWxlbWVudFR5cGUgPSBEb3VibGUuY2xhc3M7CisgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBsb25nLmNsYXNzKSB7CisgICAgICAgICAgICBlbGVtZW50VHlwZSA9IExvbmcuY2xhc3M7CisgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBzaG9ydC5jbGFzcykgeworICAgICAgICAgICAgZWxlbWVudFR5cGUgPSBTaG9ydC5jbGFzczsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGJ5dGUuY2xhc3MpIHsKKyAgICAgICAgICAgIGVsZW1lbnRUeXBlID0gQnl0ZS5jbGFzczsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGVsZW1lbnRUeXBlID0gdHlwZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbGxzIGluIGVsZW1lbnQncyBkZWZpbml0aW9uIGluZm8gYW5kIHJldHVybnMgdGhpcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQW5ub3RhdGlvbk1lbWJlciBzZXREZWZpbml0aW9uKEFubm90YXRpb25NZW1iZXIgY29weSkgeworICAgICAgICBkZWZpbmluZ01ldGhvZCA9IGNvcHkuZGVmaW5pbmdNZXRob2Q7CisgICAgICAgIGVsZW1lbnRUeXBlID0gY29weS5lbGVtZW50VHlwZTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyByZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGlzIGFubm90YXRpb24gdmFsdWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgaWYgKHRhZyA9PSBBUlJBWSkgeworICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKDgwKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZChuYW1lKS5hcHBlbmQoIj1bIik7CisgICAgICAgICAgICBpbnQgbGVuID0gQXJyYXkuZ2V0TGVuZ3RoKHZhbHVlKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoaSAhPSAwKSBzYi5hcHBlbmQoIiwgIik7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKEFycmF5LmdldCh2YWx1ZSwgaSkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHNiLmFwcGVuZCgiXSIpLnRvU3RyaW5nKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gbmFtZSsgIj0iICt2YWx1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCByZXByZXNlbnRzIGVxdWFsIGVsZW1lbnQKKyAgICAgKiAoZXF1aXZhbGVudCBuYW1lLXZhbHVlIHBhaXIpLgorICAgICAqIDxicj4gQSBzcGVjaWFsIGNhc2UgaXMgdGhlIGNvbnRhaW5lZCBUaHJvd2FibGUgdmFsdWU7IGl0IGlzIGNvbnNpZGVyZWQKKyAgICAgKiB0cmFuc2NlbmRlbnQgc28gbm8gb3RoZXIgZWxlbWVudCB3b3VsZCBiZSBlcXVhbC4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgcGFzc2VkIG9iamVjdCBpcyBlcXVpdmFsZW50IGVsZW1lbnQgcmVwcmVzZW50YXRpb24sCisgICAgICogZmFsc2Ugb3RoZXJ3aXNlCisgICAgICogQHNlZSAjZXF1YWxBcnJheVZhbHVlKE9iamVjdCkKKyAgICAgKiBAc2VlIGphdmEubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb24jZXF1YWxzKE9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKKyAgICAgICAgICAgIC8vIG5vdCBhIG1lcmUgb3B0aW1pemF0aW9uLAorICAgICAgICAgICAgLy8gdGhpcyBpcyBuZWVkZWQgZm9yIGNvbnNpc3RlbmN5IHdpdGggaGFzaENvZGUoKQorICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIEFubm90YXRpb25NZW1iZXIpIHsKKyAgICAgICAgICAgIEFubm90YXRpb25NZW1iZXIgdGhhdCA9IChBbm5vdGF0aW9uTWVtYmVyKW9iajsKKyAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyh0aGF0Lm5hbWUpICYmIHRhZyA9PSB0aGF0LnRhZykgeworICAgICAgICAgICAgICAgIGlmICh0YWcgPT0gQVJSQVkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVxdWFsQXJyYXlWYWx1ZSh0aGF0LnZhbHVlKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRhZyA9PSBFUlJPUikgeworICAgICAgICAgICAgICAgICAgICAvLyB1bmRlZmluZWQgdmFsdWUgaXMgaW5jb21wYXJhYmxlICh0cmFuc2NlbmRlbnQpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuZXF1YWxzKHRoYXQudmFsdWUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBjb250YWluZWQgdmFsdWUgYW5kIGEgcGFzc2VkIG9iamVjdCBhcmUgZXF1YWwgYXJyYXlzLAorICAgICAqIGZhbHNlIG90aGVyd2lzZS4gQXBwcm9wcmlhdGUgb3ZlcmxvYWRlZCBtZXRob2Qgb2YgQXJyYXlzLmVxdWFscygpCisgICAgICogaXMgdXNlZCBmb3IgZXF1YWxpdHkgdGVzdGluZy4KKyAgICAgKiBAc2VlIGphdmEudXRpbC5BcnJheXMjZXF1YWxzKGphdmEubGFuZy5PYmplY3RbXSwgamF2YS5sYW5nLk9iamVjdFtdKQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdmFsdWUgaXMgYXJyYXkgYW5kIGlzIGVxdWFsIHRvIHNwZWNpZmllZCBvYmplY3QsCisgICAgICogZmFsc2Ugb3RoZXJ3aXNlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxBcnJheVZhbHVlKE9iamVjdCBvdGhlclZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIE9iamVjdFtdICYmIG90aGVyVmFsdWUgaW5zdGFuY2VvZiBPYmplY3RbXSkgeworICAgICAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMoKE9iamVjdFtdKXZhbHVlLCAoT2JqZWN0W10pb3RoZXJWYWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgQ2xhc3MgdHlwZSA9IHZhbHVlLmdldENsYXNzKCk7CisgICAgICAgIGlmICh0eXBlICE9IG90aGVyVmFsdWUuZ2V0Q2xhc3MoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmICh0eXBlID09IGludFtdLmNsYXNzKSB7CisgICAgICAgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscygoaW50W10pdmFsdWUsIChpbnRbXSlvdGhlclZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGJ5dGVbXS5jbGFzcykgeworICAgICAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMoKGJ5dGVbXSl2YWx1ZSwgKGJ5dGVbXSlvdGhlclZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IHNob3J0W10uY2xhc3MpIHsKKyAgICAgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKChzaG9ydFtdKXZhbHVlLCAoc2hvcnRbXSlvdGhlclZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGxvbmdbXS5jbGFzcykgeworICAgICAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMoKGxvbmdbXSl2YWx1ZSwgKGxvbmdbXSlvdGhlclZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGNoYXJbXS5jbGFzcykgeworICAgICAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMoKGNoYXJbXSl2YWx1ZSwgKGNoYXJbXSlvdGhlclZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGJvb2xlYW5bXS5jbGFzcykgeworICAgICAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMoKGJvb2xlYW5bXSl2YWx1ZSwgKGJvb2xlYW5bXSlvdGhlclZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGZsb2F0W10uY2xhc3MpIHsKKyAgICAgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKChmbG9hdFtdKXZhbHVlLCAoZmxvYXRbXSlvdGhlclZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGRvdWJsZVtdLmNsYXNzKSB7CisgICAgICAgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscygoZG91YmxlW10pdmFsdWUsIChkb3VibGVbXSlvdGhlclZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZXMgaGFzaCBjb2RlIG9mIHRoaXMgZWxlbWVudC4gVGhlIGZvcm11bGEgaXMgYXMgZm9sbG93czoKKyAgICAgKiA8Y29kZT4gKG5hbWUuaGFzaENvZGUoKSAqIDEyNykgXiB2YWx1ZS5oYXNoQ29kZSgpIDwvY29kZT4KKyAgICAgKiA8YnI+SWYgdmFsdWUgaXMgYW4gYXJyYXksIG9uZSBvZiBvdmVybG9hZGVkIEFycmF5cy5oYXNoQ29kZSgpCisgICAgICogbWV0aG9kcyBpcyB1c2VkLgorICAgICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZQorICAgICAqIEBzZWUgamF2YS51dGlsLkFycmF5cyNoYXNoQ29kZShqYXZhLmxhbmcuT2JqZWN0W10pCisgICAgICogQHNlZSBqYXZhLmxhbmcuYW5ub3RhdGlvbi5Bbm5vdGF0aW9uI2hhc2hDb2RlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBpbnQgaGFzaCA9IG5hbWUuaGFzaENvZGUoKSAqIDEyNzsKKyAgICAgICAgaWYgKHRhZyA9PSBBUlJBWSkgeworICAgICAgICAgICAgQ2xhc3MgdHlwZSA9IHZhbHVlLmdldENsYXNzKCk7CisgICAgICAgICAgICBpZiAodHlwZSA9PSBpbnRbXS5jbGFzcykgeworICAgICAgICAgICAgICAgIHJldHVybiBoYXNoIF4gQXJyYXlzLmhhc2hDb2RlKChpbnRbXSl2YWx1ZSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gYnl0ZVtdLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGhhc2ggXiBBcnJheXMuaGFzaENvZGUoKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gc2hvcnRbXS5jbGFzcykgeworICAgICAgICAgICAgICAgIHJldHVybiBoYXNoIF4gQXJyYXlzLmhhc2hDb2RlKChzaG9ydFtdKXZhbHVlKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBsb25nW10uY2xhc3MpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gaGFzaCBeIEFycmF5cy5oYXNoQ29kZSgobG9uZ1tdKXZhbHVlKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBjaGFyW10uY2xhc3MpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gaGFzaCBeIEFycmF5cy5oYXNoQ29kZSgoY2hhcltdKXZhbHVlKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBib29sZWFuW10uY2xhc3MpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gaGFzaCBeIEFycmF5cy5oYXNoQ29kZSgoYm9vbGVhbltdKXZhbHVlKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBmbG9hdFtdLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGhhc2ggXiBBcnJheXMuaGFzaENvZGUoKGZsb2F0W10pdmFsdWUpOworICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGRvdWJsZVtdLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGhhc2ggXiBBcnJheXMuaGFzaENvZGUoKGRvdWJsZVtdKXZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBoYXNoIF4gQXJyYXlzLmhhc2hDb2RlKChPYmplY3RbXSl2YWx1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gaGFzaCBeIHZhbHVlLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaHJvd3MgY29udGFpbmVkIGVycm9yIChpZiBhbnkpIHdpdGggYSByZW5ld2VkIHN0YWNrIHRyYWNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJldGhyb3dFcnJvcigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBpZiAodGFnID09IEVSUk9SKSB7CisgICAgICAgICAgICAvLyBuZWVkIHRvIHRocm93IGNsb25lZCBleGNlcHRpb24gZm9yIHRocmVhZCBzYWZldHkKKyAgICAgICAgICAgIC8vIGJlc2lkZXMgaXQgaXMgYmV0dGVyIHRvIHByb3ZpZGUgYWN0dWFsIHN0YWNrIHRyYWNlCisgICAgICAgICAgICAvLyByYXRoZXIgdGhhbiByZWNvcmRlZCBkdXJpbmcgcGFyc2luZworCisgICAgICAgICAgICAvLyBmaXJzdCBjaGVjayBmb3IgZXhwZWN0ZWQgdHlwZXMKKyAgICAgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFR5cGVOb3RQcmVzZW50RXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgVHlwZU5vdFByZXNlbnRFeGNlcHRpb24gdG5wZSA9IChUeXBlTm90UHJlc2VudEV4Y2VwdGlvbil2YWx1ZTsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZU5vdFByZXNlbnRFeGNlcHRpb24odG5wZS50eXBlTmFtZSgpLCB0bnBlLmdldENhdXNlKCkpOworICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEVudW1Db25zdGFudE5vdFByZXNlbnRFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICBFbnVtQ29uc3RhbnROb3RQcmVzZW50RXhjZXB0aW9uIGVjbnBlID0gKEVudW1Db25zdGFudE5vdFByZXNlbnRFeGNlcHRpb24pdmFsdWU7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVudW1Db25zdGFudE5vdFByZXNlbnRFeGNlcHRpb24oZWNucGUuZW51bVR5cGUoKSwgZWNucGUuY29uc3RhbnROYW1lKCkpOworICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEFycmF5U3RvcmVFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICBBcnJheVN0b3JlRXhjZXB0aW9uIGFzZSA9IChBcnJheVN0b3JlRXhjZXB0aW9uKXZhbHVlOworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBcnJheVN0b3JlRXhjZXB0aW9uKGFzZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gZ290IHNvbWUgb3RoZXIgZXJyb3IsIGhhdmUgdG8gZ28gd2l0aCBkZWVwIGNsb25pbmcKKyAgICAgICAgICAgIC8vIHZpYSBzZXJpYWxpemF0aW9uIG1lY2hhbmlzbQorICAgICAgICAgICAgVGhyb3dhYmxlIGVycm9yID0gKFRocm93YWJsZSl2YWx1ZTsKKyAgICAgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50W10gc3RlID0gZXJyb3IuZ2V0U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgIHN0ZSA9PSBudWxsID8gNTEyIDogKHN0ZS5sZW5ndGggKyAxKSAqIDgwKTsKKyAgICAgICAgICAgIE9iamVjdE91dHB1dFN0cmVhbSBvb3MgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKGJvcyk7CisgICAgICAgICAgICBvb3Mud3JpdGVPYmplY3QoZXJyb3IpOworICAgICAgICAgICAgb29zLmZsdXNoKCk7CisgICAgICAgICAgICBvb3MuY2xvc2UoKTsKKyAgICAgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShib3MKKyAgICAgICAgICAgICAgICAgICAgLnRvQnl0ZUFycmF5KCkpOworICAgICAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0gb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKGJpcyk7CisgICAgICAgICAgICBlcnJvciA9IChUaHJvd2FibGUpb2lzLnJlYWRPYmplY3QoKTsKKyAgICAgICAgICAgIG9pcy5jbG9zZSgpOworCisgICAgICAgICAgICB0aHJvdyBlcnJvcjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFZhbGlkYXRlcyBjb250YWluZWQgdmFsdWUgYWdhaW5zdCBpdHMgbWVtYmVyIGRlZmluaXRpb24KKyAgICAgKiBhbmQgaWYgb2sgcmV0dXJucyB0aGUgdmFsdWUuCisgICAgICogT3RoZXJ3aXNlLCBpZiB0aGUgdmFsdWUgdHlwZSBtaXNtYXRjaGVzIGRlZmluaXRpb24KKyAgICAgKiBvciB0aGUgdmFsdWUgaXRzZWxmIGRlc2NyaWJlcyBhbiBlcnJvciwKKyAgICAgKiB0aHJvd3MgYXBwcm9wcmlhdGUgZXhjZXB0aW9uLgorICAgICAqIDxicj4gTm90ZSwgdGhpcyBtZXRob2QgbWF5IHJldHVybiBudWxsIGlmIHRoaXMgZWxlbWVudCB3YXMgY29uc3RydWN0ZWQKKyAgICAgKiB3aXRoIHN1Y2ggdmFsdWUuCisgICAgICoKKyAgICAgKiBAc2VlICNyZXRocm93RXJyb3IoKQorICAgICAqIEBzZWUgI2NvcHlWYWx1ZSgpCisgICAgICogQHJldHVybiBhY3R1YWwgdmFsaWQgdmFsdWUgb3IgbnVsbCBpZiBubyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgdmFsaWRhdGVWYWx1ZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBpZiAodGFnID09IEVSUk9SKSB7CisgICAgICAgICAgICByZXRocm93RXJyb3IoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodmFsdWUgPT0gTk9fVkFMVUUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGlmIChlbGVtZW50VHlwZSA9PSB2YWx1ZS5nZXRDbGFzcygpCisgICAgICAgICAgICAgICAgfHwgZWxlbWVudFR5cGUuaXNJbnN0YW5jZSh2YWx1ZSkpIHsgLy8gbmVzdGVkIGFubm90YXRpb24gdmFsdWUKKyAgICAgICAgICAgIHJldHVybiBjb3B5VmFsdWUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBbm5vdGF0aW9uVHlwZU1pc21hdGNoRXhjZXB0aW9uKGRlZmluaW5nTWV0aG9kLAorICAgICAgICAgICAgICAgICAgICB2YWx1ZS5nZXRDbGFzcygpLmdldE5hbWUoKSk7CisgICAgICAgIH0KKworICAgIH0KKworCisgICAgLyoqCisgICAgICogUHJvdmlkZXMgbXV0YXRpb24tc2FmZSBhY2Nlc3MgdG8gY29udGFpbmVkIHZhbHVlLiBUaGF0IGlzLCBjYWxsZXIgaXMgZnJlZQorICAgICAqIHRvIG1vZGlmeSB0aGUgcmV0dXJuZWQgdmFsdWUsIGl0IHdpbGwgbm90IGFmZmVjdCB0aGUgY29udGFpbmVkIGRhdGEgdmFsdWUuCisgICAgICogQHJldHVybiBjbG9uZWQgdmFsdWUgaWYgaXQgaXMgbXV0YWJsZSBvciB0aGUgb3JpZ2luYWwgaW1tdXRhYmxlIHZhbHVlCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBjb3B5VmFsdWUoKSB0aHJvd3MgVGhyb3dhYmxlCisgICAgeworICAgICAgICBpZiAodGFnICE9IEFSUkFZIHx8IEFycmF5LmdldExlbmd0aCh2YWx1ZSkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIHZhbHVlOworICAgICAgICB9CisgICAgICAgIENsYXNzIHR5cGUgPSB2YWx1ZS5nZXRDbGFzcygpOworICAgICAgICBpZiAodHlwZSA9PSBpbnRbXS5jbGFzcykgeworICAgICAgICAgICAgcmV0dXJuICgoaW50W10pdmFsdWUpLmNsb25lKCk7CisgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBieXRlW10uY2xhc3MpIHsKKyAgICAgICAgICAgIHJldHVybiAoKGJ5dGVbXSl2YWx1ZSkuY2xvbmUoKTsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IHNob3J0W10uY2xhc3MpIHsKKyAgICAgICAgICAgIHJldHVybiAoKHNob3J0W10pdmFsdWUpLmNsb25lKCk7CisgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBsb25nW10uY2xhc3MpIHsKKyAgICAgICAgICAgIHJldHVybiAoKGxvbmdbXSl2YWx1ZSkuY2xvbmUoKTsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IGNoYXJbXS5jbGFzcykgeworICAgICAgICAgICAgcmV0dXJuICgoY2hhcltdKXZhbHVlKS5jbG9uZSgpOworICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gYm9vbGVhbltdLmNsYXNzKSB7CisgICAgICAgICAgICByZXR1cm4gKChib29sZWFuW10pdmFsdWUpLmNsb25lKCk7CisgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBmbG9hdFtdLmNsYXNzKSB7CisgICAgICAgICAgICByZXR1cm4gKChmbG9hdFtdKXZhbHVlKS5jbG9uZSgpOworICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gZG91YmxlW10uY2xhc3MpIHsKKyAgICAgICAgICAgIHJldHVybiAoKGRvdWJsZVtdKXZhbHVlKS5jbG9uZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoKE9iamVjdFtdKXZhbHVlKS5jbG9uZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS9pbnRlcm5hbC91dGlsL1RpbWV6b25lR2V0dGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvaW50ZXJuYWwvdXRpbC9UaW1lem9uZUdldHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEzMWVjYzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvaW50ZXJuYWwvdXRpbC9UaW1lem9uZUdldHRlci5qYXZhCkBAIC0wLDAgKzEsNTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLmludGVybmFsLnV0aWw7CisKKy8qKgorICogVGhpcyBjbGFzcyBwcm92aWRlcyBhIHdheSB0byBhZGQgYW4gaW1wbGVtZW50YXRpb24gc3BlY2lmaWMgd2F5IHRvCisgKiBhY2Nlc3MgdGhlIGN1cnJlbnQgdGltZXpvbmUuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBUaW1lem9uZUdldHRlciB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBUaW1lem9uZUdldHRlciBpbnN0YW5jZTsKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyB0aGUgc2luZ2xldG9uIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRpbWV6b25lR2V0dGVyIHRoZSBzaW5nbGUgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFRpbWV6b25lR2V0dGVyIGdldEluc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gaW5zdGFuY2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc2luZ2xldG9uIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5zdGFuY2UKKyAgICAgKiAgICAgICAgICAgIFRpbWV6b25lR2V0dGVyIHRoZSBzaW5nbGUgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0SW5zdGFuY2UoVGltZXpvbmVHZXR0ZXIgZ2V0dGVyKSB7CisgICAgICAgIGlmIChpbnN0YW5jZSAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlRpbWV6b25lR2V0dGVyIGluc3RhbmNlIGFscmVhZHkgc2V0Iik7CisgICAgICAgIH0KKyAgICAgICAgaW5zdGFuY2UgPSBnZXR0ZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIHRoZSBJRCBvZiB0aGUgY3VycmVudCB0aW1lIHpvbmUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFN0cmluZyB0aGUgSUQgb2YgdGhlIGN1cnJlbnQgdGltZSB6b25lLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0SWQoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS9sYW5nL3JlZmxlY3QvR2VuZXJpY1NpZ25hdHVyZVBhcnNlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL2xhbmcvcmVmbGVjdC9HZW5lcmljU2lnbmF0dXJlUGFyc2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDkwZGFhZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS9sYW5nL3JlZmxlY3QvR2VuZXJpY1NpZ25hdHVyZVBhcnNlci5qYXZhCkBAIC0wLDAgKzEsNTA4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5HZW5lcmljRGVjbGFyYXRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuR2VuZXJpY1NpZ25hdHVyZUZvcm1hdEVycm9yOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5UeXBlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGVWYXJpYWJsZTsKKworLyoqCisgKiBJbXBsZW1lbnRzIGEgcGFyc2VyIGZvciB0aGUgZ2VuZXJpY3Mgc2lnbmF0dXJlIGF0dHJpYnV0ZS4KKyAqIFVzZXMgYSB0b3AtZG93biwgcmVjdXJzaXZlIGRlc2NlbnQgcGFyc2luZyBhcHByb2FjaCBmb3IgdGhlIGZvbGxvd2luZyBncmFtbWFyOgorICogPHByZT4KKyAqIENsYXNzU2lnbmF0dXJlIDo6PQorICogICAgIE9wdEZvcm1hbFR5cGVQYXJhbXMgU3VwZXJjbGFzc1NpZ25hdHVyZSB7U3VwZXJpbnRlcmZhY2VTaWduYXR1cmV9LgorICogU3VwZXJjbGFzc1NpZ25hdHVyZSA6Oj0gQ2xhc3NUeXBlU2lnbmF0dXJlLgorICogU3VwZXJpbnRlcmZhY2VTaWduYXR1cmUgOjo9IENsYXNzVHlwZVNpZ25hdHVyZS4KKyAqCisgKiBPcHRGb3JtYWxUeXBlUGFyYW1zIDo6PQorICogICAgIFsiPCIgRm9ybWFsVHlwZVBhcmFtZXRlciB7Rm9ybWFsVHlwZVBhcmFtZXRlcn0gIj4iXS4KKyAqCisgKiBGb3JtYWxUeXBlUGFyYW1ldGVyIDo6PSBJZGVudCBDbGFzc0JvdW5kIHtJbnRlcmZhY2VCb3VuZH0uCisgKiBDbGFzc0JvdW5kIDo6PSAiOiIgW0ZpZWxkVHlwZVNpZ25hdHVyZV0uCisgKiBJbnRlcmZhY2VCb3VuZCA6Oj0gIjoiIEZpZWxkVHlwZVNpZ25hdHVyZS4KKyAqCisgKiBGaWVsZFR5cGVTaWduYXR1cmUgOjo9CisgKiAgICAgQ2xhc3NUeXBlU2lnbmF0dXJlIHwgQXJyYXlUeXBlU2lnbmF0dXJlIHwgVHlwZVZhcmlhYmxlU2lnbmF0dXJlLgorICogQXJyYXlUeXBlU2lnbmF0dXJlIDo6PSAiWyIgVHlwU2lnbmF0dXJlLgorICoKKyAqIENsYXNzVHlwZVNpZ25hdHVyZSA6Oj0KKyAqICAgICAiTCIge0lkZW50ICIvIn0gSWRlbnQgT3B0VHlwZUFyZ3VtZW50cyB7Ii4iIElkZW50IE9wdFR5cGVBcmd1bWVudHN9ICI7Ii4KKyAqCisgKiBPcHRUeXBlQXJndW1lbnRzIDo6PSAiPCIgVHlwZUFyZ3VtZW50IHtUeXBlQXJndW1lbnR9ICI+Ii4KKyAqCisgKiBUeXBlQXJndW1lbnQgOjo9IChbV2lsZGNhcmRJbmRpY2F0b3JdIEZpZWxkVHlwZVNpZ25hdHVyZSkgfCAiKiIuCisgKiBXaWxkY2FyZEluZGljYXRvciA6Oj0gIisiIHwgIi0iLgorICoKKyAqIFR5cGVWYXJpYWJsZVNpZ25hdHVyZSA6Oj0gIlQiIElkZW50ICI7Ii4KKyAqCisgKiBUeXBTaWduYXR1cmUgOjo9IEZpZWxkVHlwZVNpZ25hdHVyZSB8IEJhc2VUeXBlLgorICogQmFzZVR5cGUgOjo9ICJCIiB8ICJDIiB8ICJEIiB8ICJGIiB8ICJJIiB8ICJKIiB8ICJTIiB8ICJaIi4KKyAqCisgKiBNZXRob2RUeXBlU2lnbmF0dXJlIDo6PQorICogICAgIE9wdEZvcm1hbFR5cGVQYXJhbXMgIigiIHtUeXBlU2lnbmF0dXJlfSAiKSIgUmV0dXJuVHlwZSB7VGhyb3dzU2lnbmF0dXJlfS4KKyAqIFRocm93c1NpZ25hdHVyZSA6Oj0gKCJeIiBDbGFzc1R5cGVTaWduYXR1cmUpIHwgKCJeIiBUeXBlVmFyaWFibGVTaWduYXR1cmUpLgorICoKKyAqIFJldHVyblR5cGUgOjo9IFR5cFNpZ25hdHVyZSB8IFZvaWREZXNjcmlwdG9yLgorICogVm9pZERlc2NyaXB0b3IgOjo9ICJWIi4KKyAqIDwvcHJlPgorICovCitwdWJsaWMgY2xhc3MgR2VuZXJpY1NpZ25hdHVyZVBhcnNlciB7CisKKyAgICBwdWJsaWMgTGlzdE9mVHlwZXMgZXhjZXB0aW9uVHlwZXM7CisgICAgcHVibGljIExpc3RPZlR5cGVzIHBhcmFtZXRlclR5cGVzOworICAgIHB1YmxpYyBUeXBlVmFyaWFibGVbXSBmb3JtYWxUeXBlUGFyYW1ldGVyczsKKyAgICBwdWJsaWMgVHlwZSByZXR1cm5UeXBlOworICAgIHB1YmxpYyBUeXBlIGZpZWxkVHlwZTsKKyAgICBwdWJsaWMgTGlzdE9mVHlwZXMgaW50ZXJmYWNlVHlwZXM7CisgICAgcHVibGljIFR5cGUgc3VwZXJjbGFzc1R5cGU7CisgICAgcHVibGljIENsYXNzTG9hZGVyIGxvYWRlcjsKKworICAgIEdlbmVyaWNEZWNsYXJhdGlvbiBnZW5lcmljRGVjbDsKKworICAgIC8qCisgICAgICogUGFyc2VyOgorICAgICAqLworICAgIGNoYXIgc3ltYm9sOyAvLyAwOiBlb2Y7IGVsc2UgdmFsaWQgdGVybSBzeW1ib2wgb3IgZmlyc3QgY2hhciBvZiBpZGVudGlmaWVyLgorICAgIFN0cmluZyBpZGVudGlmaWVyOworCisKKyAgICAvKgorICAgICAqIFNjYW5uZXI6CisgICAgICogZW9mIGlzIHByaXZhdGUgdG8gdGhlIHNjYW4gbWV0aG9kcworICAgICAqIGFuZCBpdCdzIHNldCBvbmx5IHdoZW4gYSBzY2FuIGlzIGlzc3VlZCBhdCB0aGUgZW5kIG9mIHRoZSBidWZmZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGVvZjsKKworICAgIGNoYXJbXSBidWZmZXI7CisgICAgaW50IHBvczsKKworICAgIHB1YmxpYyBHZW5lcmljU2lnbmF0dXJlUGFyc2VyKENsYXNzTG9hZGVyIGxvYWRlcikgeworICAgICAgICB0aGlzLmxvYWRlciA9IGxvYWRlcjsKKyAgICB9CisKKyAgICB2b2lkIHNldElucHV0KEdlbmVyaWNEZWNsYXJhdGlvbiBnZW5lcmljRGVjbCwgU3RyaW5nIGlucHV0KSB7CisgICAgICAgIGlmIChpbnB1dCAhPSBudWxsKSB7CisgICAgICAgICAgICB0aGlzLmdlbmVyaWNEZWNsID0gZ2VuZXJpY0RlY2w7CisgICAgICAgICAgICB0aGlzLmJ1ZmZlciA9IGlucHV0LnRvQ2hhckFycmF5KCk7CisgICAgICAgICAgICB0aGlzLmVvZiA9IGZhbHNlOworICAgICAgICAgICAgc2NhblN5bWJvbCgpOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgdGhpcy5lb2YgPSB0cnVlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBnZW5lcmljIHNpZ25hdHVyZSBvZiBhIGNsYXNzIGFuZCBjcmVhdGVzIHRoZSBkYXRhIHN0cnVjdHVyZQorICAgICAqIHJlcHJlc2VudGluZyB0aGUgc2lnbmF0dXJlLgorICAgICAqCisgICAgICogQHBhcmFtIGdlbmVyaWNEZWNsIHRoZSBHZW5lcmljRGVjbGFyYXRpb24gY2FsbGluZyB0aGlzIG1ldGhvZAorICAgICAqIEBwYXJhbSBzaWduYXR1cmUgdGhlIGdlbmVyaWMgc2lnbmF0dXJlIG9mIHRoZSBjbGFzcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHBhcnNlRm9yQ2xhc3MoR2VuZXJpY0RlY2xhcmF0aW9uIGdlbmVyaWNEZWNsLAorICAgICAgICAgICAgU3RyaW5nIHNpZ25hdHVyZSkgeworICAgICAgICBzZXRJbnB1dChnZW5lcmljRGVjbCwgc2lnbmF0dXJlKTsKKyAgICAgICAgaWYgKCFlb2YpIHsKKyAgICAgICAgICAgIHBhcnNlQ2xhc3NTaWduYXR1cmUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmKGdlbmVyaWNEZWNsIGluc3RhbmNlb2YgQ2xhc3MpIHsKKyAgICAgICAgICAgICAgICBDbGFzcyBjID0gKENsYXNzKSBnZW5lcmljRGVjbDsKKyAgICAgICAgICAgICAgICB0aGlzLmZvcm1hbFR5cGVQYXJhbWV0ZXJzID0gTGlzdE9mVmFyaWFibGVzLkVNUFRZOworICAgICAgICAgICAgICAgIHRoaXMuc3VwZXJjbGFzc1R5cGUgPSBjLmdldFN1cGVyY2xhc3MoKTsKKyAgICAgICAgICAgICAgICB0aGlzLmludGVyZmFjZVR5cGVzID0gbmV3IExpc3RPZlR5cGVzKGMuZ2V0SW50ZXJmYWNlcygpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhpcy5mb3JtYWxUeXBlUGFyYW1ldGVycyA9IExpc3RPZlZhcmlhYmxlcy5FTVBUWTsKKyAgICAgICAgICAgICAgICB0aGlzLnN1cGVyY2xhc3NUeXBlID0gT2JqZWN0LmNsYXNzOworICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJmYWNlVHlwZXMgPSBMaXN0T2ZUeXBlcy5FTVBUWTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgZ2VuZXJpYyBzaWduYXR1cmUgb2YgYSBtZXRob2QgYW5kIGNyZWF0ZXMgdGhlIGRhdGEgc3RydWN0dXJlCisgICAgICogcmVwcmVzZW50aW5nIHRoZSBzaWduYXR1cmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZ2VuZXJpY0RlY2wgdGhlIEdlbmVyaWNEZWNsYXJhdGlvbiBjYWxsaW5nIHRoaXMgbWV0aG9kCisgICAgICogQHBhcmFtIHNpZ25hdHVyZSB0aGUgZ2VuZXJpYyBzaWduYXR1cmUgb2YgdGhlIGNsYXNzCisgICAgICovCisgICAgcHVibGljIHZvaWQgcGFyc2VGb3JNZXRob2QoR2VuZXJpY0RlY2xhcmF0aW9uIGdlbmVyaWNEZWNsLAorICAgICAgICAgICAgU3RyaW5nIHNpZ25hdHVyZSwgQ2xhc3M8Pz5bXSByYXdFeGNlcHRpb25UeXBlcykgeworICAgICAgICBzZXRJbnB1dChnZW5lcmljRGVjbCwgc2lnbmF0dXJlKTsKKyAgICAgICAgaWYgKCFlb2YpIHsKKyAgICAgICAgICAgIHBhcnNlTWV0aG9kVHlwZVNpZ25hdHVyZShyYXdFeGNlcHRpb25UeXBlcyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZihnZW5lcmljRGVjbCBpbnN0YW5jZW9mIE1ldGhvZCkgeworICAgICAgICAgICAgICAgIE1ldGhvZCBtID0gKE1ldGhvZCkgZ2VuZXJpY0RlY2w7CisgICAgICAgICAgICAgICAgdGhpcy5mb3JtYWxUeXBlUGFyYW1ldGVycyA9IExpc3RPZlZhcmlhYmxlcy5FTVBUWTsKKyAgICAgICAgICAgICAgICB0aGlzLnBhcmFtZXRlclR5cGVzID0gbmV3IExpc3RPZlR5cGVzKG0uZ2V0UGFyYW1ldGVyVHlwZXMoKSk7CisgICAgICAgICAgICAgICAgdGhpcy5leGNlcHRpb25UeXBlcyA9IG5ldyBMaXN0T2ZUeXBlcyhtLmdldEV4Y2VwdGlvblR5cGVzKCkpOworICAgICAgICAgICAgICAgIHRoaXMucmV0dXJuVHlwZSA9IG0uZ2V0UmV0dXJuVHlwZSgpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aGlzLmZvcm1hbFR5cGVQYXJhbWV0ZXJzID0gTGlzdE9mVmFyaWFibGVzLkVNUFRZOworICAgICAgICAgICAgICAgIHRoaXMucGFyYW1ldGVyVHlwZXMgPSBMaXN0T2ZUeXBlcy5FTVBUWTsKKyAgICAgICAgICAgICAgICB0aGlzLmV4Y2VwdGlvblR5cGVzID0gTGlzdE9mVHlwZXMuRU1QVFk7CisgICAgICAgICAgICAgICAgdGhpcy5yZXR1cm5UeXBlID0gdm9pZC5jbGFzczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgZ2VuZXJpYyBzaWduYXR1cmUgb2YgYSBjb25zdHJ1Y3RvciBhbmQgY3JlYXRlcyB0aGUgZGF0YQorICAgICAqIHN0cnVjdHVyZSByZXByZXNlbnRpbmcgdGhlIHNpZ25hdHVyZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBnZW5lcmljRGVjbCB0aGUgR2VuZXJpY0RlY2xhcmF0aW9uIGNhbGxpbmcgdGhpcyBtZXRob2QKKyAgICAgKiBAcGFyYW0gc2lnbmF0dXJlIHRoZSBnZW5lcmljIHNpZ25hdHVyZSBvZiB0aGUgY2xhc3MKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwYXJzZUZvckNvbnN0cnVjdG9yKEdlbmVyaWNEZWNsYXJhdGlvbiBnZW5lcmljRGVjbCwKKyAgICAgICAgICAgIFN0cmluZyBzaWduYXR1cmUsIENsYXNzPD8+W10gcmF3RXhjZXB0aW9uVHlwZXMpIHsKKyAgICAgICAgc2V0SW5wdXQoZ2VuZXJpY0RlY2wsIHNpZ25hdHVyZSk7CisgICAgICAgIGlmICghZW9mKSB7CisgICAgICAgICAgICBwYXJzZU1ldGhvZFR5cGVTaWduYXR1cmUocmF3RXhjZXB0aW9uVHlwZXMpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYoZ2VuZXJpY0RlY2wgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikgeworICAgICAgICAgICAgICAgIENvbnN0cnVjdG9yIGMgPSAoQ29uc3RydWN0b3IpIGdlbmVyaWNEZWNsOworICAgICAgICAgICAgICAgIHRoaXMuZm9ybWFsVHlwZVBhcmFtZXRlcnMgPSBMaXN0T2ZWYXJpYWJsZXMuRU1QVFk7CisgICAgICAgICAgICAgICAgdGhpcy5wYXJhbWV0ZXJUeXBlcyA9IG5ldyBMaXN0T2ZUeXBlcyhjLmdldFBhcmFtZXRlclR5cGVzKCkpOworICAgICAgICAgICAgICAgIHRoaXMuZXhjZXB0aW9uVHlwZXMgPSBuZXcgTGlzdE9mVHlwZXMoYy5nZXRFeGNlcHRpb25UeXBlcygpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhpcy5mb3JtYWxUeXBlUGFyYW1ldGVycyA9IExpc3RPZlZhcmlhYmxlcy5FTVBUWTsKKyAgICAgICAgICAgICAgICB0aGlzLnBhcmFtZXRlclR5cGVzID0gTGlzdE9mVHlwZXMuRU1QVFk7CisgICAgICAgICAgICAgICAgdGhpcy5leGNlcHRpb25UeXBlcyA9IExpc3RPZlR5cGVzLkVNUFRZOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBnZW5lcmljIHNpZ25hdHVyZSBvZiBhIGZpZWxkIGFuZCBjcmVhdGVzIHRoZSBkYXRhIHN0cnVjdHVyZQorICAgICAqIHJlcHJlc2VudGluZyB0aGUgc2lnbmF0dXJlLgorICAgICAqCisgICAgICogQHBhcmFtIGdlbmVyaWNEZWNsIHRoZSBHZW5lcmljRGVjbGFyYXRpb24gY2FsbGluZyB0aGlzIG1ldGhvZAorICAgICAqIEBwYXJhbSBzaWduYXR1cmUgdGhlIGdlbmVyaWMgc2lnbmF0dXJlIG9mIHRoZSBjbGFzcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHBhcnNlRm9yRmllbGQoR2VuZXJpY0RlY2xhcmF0aW9uIGdlbmVyaWNEZWNsLAorICAgICAgICAgICAgU3RyaW5nIHNpZ25hdHVyZSkgeworICAgICAgICBzZXRJbnB1dChnZW5lcmljRGVjbCwgc2lnbmF0dXJlKTsKKyAgICAgICAgaWYgKCFlb2YpIHsKKyAgICAgICAgICAgIHRoaXMuZmllbGRUeXBlID0gcGFyc2VGaWVsZFR5cGVTaWduYXR1cmUoKTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgLy8KKyAgICAvLyBQYXJzZXI6CisgICAgLy8KKworICAgIHZvaWQgcGFyc2VDbGFzc1NpZ25hdHVyZSgpIHsKKyAgICAgICAgLy8gQ2xhc3NTaWduYXR1cmUgOjo9CisgICAgICAgIC8vIE9wdEZvcm1hbFR5cGVQYXJhbWV0ZXJzIFN1cGVyY2xhc3NTaWduYXR1cmUge1N1cGVyaW50ZXJmYWNlU2lnbmF0dXJlfS4KKworICAgICAgICBwYXJzZU9wdEZvcm1hbFR5cGVQYXJhbWV0ZXJzKCk7CisKKyAgICAgICAgLy8gU3VwZXJjbGFzc1NpZ25hdHVyZSA6Oj0gQ2xhc3NUeXBlU2lnbmF0dXJlLgorICAgICAgICB0aGlzLnN1cGVyY2xhc3NUeXBlID0gcGFyc2VDbGFzc1R5cGVTaWduYXR1cmUoKTsKKworICAgICAgICBpbnRlcmZhY2VUeXBlcyA9IG5ldyBMaXN0T2ZUeXBlcygxNik7CisgICAgICAgIHdoaWxlIChzeW1ib2wgPiAwKSB7CisgICAgICAgICAgICAvLyBTdXBlcmludGVyZmFjZVNpZ25hdHVyZSA6Oj0gQ2xhc3NUeXBlU2lnbmF0dXJlLgorICAgICAgICAgICAgaW50ZXJmYWNlVHlwZXMuYWRkKHBhcnNlQ2xhc3NUeXBlU2lnbmF0dXJlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgdm9pZCBwYXJzZU9wdEZvcm1hbFR5cGVQYXJhbWV0ZXJzKCkgeworICAgICAgICAvLyBPcHRGb3JtYWxUeXBlUGFyYW1ldGVycyA6Oj0KKyAgICAgICAgLy8gWyI8IiBGb3JtYWxUeXBlUGFyYW1ldGVyIHtGb3JtYWxUeXBlUGFyYW1ldGVyfSAiPiJdLgorCisgICAgICAgIExpc3RPZlZhcmlhYmxlcyB0eXBlUGFyYW1zID0gbmV3IExpc3RPZlZhcmlhYmxlcygpOworCisgICAgICAgIGlmIChzeW1ib2wgPT0gJzwnKSB7CisgICAgICAgICAgICBzY2FuU3ltYm9sKCk7CisgICAgICAgICAgICB0eXBlUGFyYW1zLmFkZChwYXJzZUZvcm1hbFR5cGVQYXJhbWV0ZXIoKSk7CisgICAgICAgICAgICB3aGlsZSAoKHN5bWJvbCAhPSAnPicpICYmIChzeW1ib2wgPiAwKSkgeworICAgICAgICAgICAgICAgIHR5cGVQYXJhbXMuYWRkKHBhcnNlRm9ybWFsVHlwZVBhcmFtZXRlcigpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGV4cGVjdCgnPicpOworICAgICAgICB9CisgICAgICAgIHRoaXMuZm9ybWFsVHlwZVBhcmFtZXRlcnMgPSB0eXBlUGFyYW1zLmdldEFycmF5KCk7CisgICAgfQorCisgICAgSW1wbEZvclZhcmlhYmxlPEdlbmVyaWNEZWNsYXJhdGlvbj4gcGFyc2VGb3JtYWxUeXBlUGFyYW1ldGVyKCkgeworICAgICAgICAvLyBGb3JtYWxUeXBlUGFyYW1ldGVyIDo6PSBJZGVudCBDbGFzc0JvdW5kIHtJbnRlcmZhY2VCb3VuZH0uCisKKyAgICAgICAgc2NhbklkZW50aWZpZXIoKTsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBpZGVudGlmaWVyLmludGVybigpOyAvLyBGSVhNRTogaXMgdGhpcyBvLmsuPworCisgICAgICAgIExpc3RPZlR5cGVzIGJvdW5kcyA9IG5ldyBMaXN0T2ZUeXBlcyg4KTsKKworICAgICAgICAvLyBDbGFzc0JvdW5kIDo6PSAiOiIgW0ZpZWxkVHlwZVNpZ25hdHVyZV0uCisgICAgICAgIGV4cGVjdCgnOicpOworICAgICAgICBpZiAoc3ltYm9sID09ICdMJyB8fCBzeW1ib2wgPT0gJ1snIHx8IHN5bWJvbCA9PSAnVCcpIHsKKyAgICAgICAgICAgIGJvdW5kcy5hZGQocGFyc2VGaWVsZFR5cGVTaWduYXR1cmUoKSk7CisgICAgICAgIH0KKworICAgICAgICB3aGlsZSAoc3ltYm9sID09ICc6JykgeworICAgICAgICAgICAgLy8gSW50ZXJmYWNlQm91bmQgOjo9ICI6IiBGaWVsZFR5cGVTaWduYXR1cmUuCisgICAgICAgICAgICBzY2FuU3ltYm9sKCk7CisgICAgICAgICAgICBib3VuZHMuYWRkKHBhcnNlRmllbGRUeXBlU2lnbmF0dXJlKCkpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ldyBJbXBsRm9yVmFyaWFibGU8R2VuZXJpY0RlY2xhcmF0aW9uPihnZW5lcmljRGVjbCwgbmFtZSwgYm91bmRzKTsKKyAgICB9CisKKyAgICBUeXBlIHBhcnNlRmllbGRUeXBlU2lnbmF0dXJlKCkgeworICAgICAgICAvLyBGaWVsZFR5cGVTaWduYXR1cmUgOjo9IENsYXNzVHlwZVNpZ25hdHVyZSB8IEFycmF5VHlwZVNpZ25hdHVyZQorICAgICAgICAvLyAgICAgICAgIHwgVHlwZVZhcmlhYmxlU2lnbmF0dXJlLgorCisgICAgICAgIHN3aXRjaCAoc3ltYm9sKSB7CisgICAgICAgIGNhc2UgJ0wnOgorICAgICAgICAgICAgcmV0dXJuIHBhcnNlQ2xhc3NUeXBlU2lnbmF0dXJlKCk7CisgICAgICAgIGNhc2UgJ1snOgorICAgICAgICAgICAgLy8gQXJyYXlUeXBlU2lnbmF0dXJlIDo6PSAiWyIgVHlwU2lnbmF0dXJlLgorICAgICAgICAgICAgc2NhblN5bWJvbCgpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBJbXBsRm9yQXJyYXkocGFyc2VUeXBlU2lnbmF0dXJlKCkpOworICAgICAgICBjYXNlICdUJzoKKyAgICAgICAgICAgIHJldHVybiBwYXJzZVR5cGVWYXJpYWJsZVNpZ25hdHVyZSgpOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgdGhyb3cgbmV3IEdlbmVyaWNTaWduYXR1cmVGb3JtYXRFcnJvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgVHlwZSBwYXJzZUNsYXNzVHlwZVNpZ25hdHVyZSgpIHsKKyAgICAgICAgLy8gQ2xhc3NUeXBlU2lnbmF0dXJlIDo6PSAiTCIge0lkZW50ICIvIn0gSWRlbnQKKyAgICAgICAgLy8gICAgICAgICBPcHRUeXBlQXJndW1lbnRzIHsiLiIgSWRlbnQgT3B0VHlwZUFyZ3VtZW50c30gIjsiLgorCisgICAgICAgIGV4cGVjdCgnTCcpOworCisgICAgICAgIFN0cmluZ0J1aWxkZXIgcXVhbElkZW50ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgc2NhbklkZW50aWZpZXIoKTsKKyAgICAgICAgd2hpbGUgKHN5bWJvbCA9PSAnLycpIHsKKyAgICAgICAgICAgIHNjYW5TeW1ib2woKTsKKyAgICAgICAgICAgIHF1YWxJZGVudC5hcHBlbmQoaWRlbnRpZmllcikuYXBwZW5kKCIuIik7CisgICAgICAgICAgICBzY2FuSWRlbnRpZmllcigpOworICAgICAgICB9CisKKyAgICAgICAgcXVhbElkZW50LmFwcGVuZCh0aGlzLmlkZW50aWZpZXIpOworCisgICAgICAgIExpc3RPZlR5cGVzIHR5cGVBcmdzID0gcGFyc2VPcHRUeXBlQXJndW1lbnRzKCk7CisgICAgICAgIEltcGxGb3JUeXBlIHBhcmVudFR5cGUgPQorICAgICAgICAgICAgICAgIG5ldyBJbXBsRm9yVHlwZShudWxsLCBxdWFsSWRlbnQudG9TdHJpbmcoKSwgdHlwZUFyZ3MsIGxvYWRlcik7CisgICAgICAgIEltcGxGb3JUeXBlIHR5cGUgPSBwYXJlbnRUeXBlOworCisgICAgICAgIHdoaWxlIChzeW1ib2wgPT0gJy4nKSB7CisgICAgICAgICAgICAvLyBEZWFsIHdpdGggTWVtYmVyIENsYXNzZXM6CisgICAgICAgICAgICBzY2FuU3ltYm9sKCk7CisgICAgICAgICAgICBzY2FuSWRlbnRpZmllcigpOworICAgICAgICAgICAgcXVhbElkZW50LmFwcGVuZCgiJCIpLmFwcGVuZChpZGVudGlmaWVyKTsgLy8gRklYTUU6IGlzICIkIiBjb3JyZWN0PworICAgICAgICAgICAgdHlwZUFyZ3MgPSBwYXJzZU9wdFR5cGVBcmd1bWVudHMoKTsKKyAgICAgICAgICAgIHR5cGUgPSBuZXcgSW1wbEZvclR5cGUocGFyZW50VHlwZSwgcXVhbElkZW50LnRvU3RyaW5nKCksIHR5cGVBcmdzLAorICAgICAgICAgICAgICAgICAgICBsb2FkZXIpOworICAgICAgICB9CisKKyAgICAgICAgZXhwZWN0KCc7Jyk7CisKKyAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgfQorCisgICAgTGlzdE9mVHlwZXMgcGFyc2VPcHRUeXBlQXJndW1lbnRzKCkgeworICAgICAgICAvLyBPcHRUeXBlQXJndW1lbnRzIDo6PSAiPCIgVHlwZUFyZ3VtZW50IHtUeXBlQXJndW1lbnR9ICI+Ii4KKworICAgICAgICBMaXN0T2ZUeXBlcyB0eXBlQXJncyA9IG5ldyBMaXN0T2ZUeXBlcyg4KTsKKyAgICAgICAgaWYgKHN5bWJvbCA9PSAnPCcpIHsKKyAgICAgICAgICAgIHNjYW5TeW1ib2woKTsKKworICAgICAgICAgICAgdHlwZUFyZ3MuYWRkKHBhcnNlVHlwZUFyZ3VtZW50KCkpOworICAgICAgICAgICAgd2hpbGUgKChzeW1ib2wgIT0gJz4nKSAmJiAoc3ltYm9sID4gMCkpIHsKKyAgICAgICAgICAgICAgICB0eXBlQXJncy5hZGQocGFyc2VUeXBlQXJndW1lbnQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBleHBlY3QoJz4nKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHlwZUFyZ3M7CisgICAgfQorCisgICAgVHlwZSBwYXJzZVR5cGVBcmd1bWVudCgpIHsKKyAgICAgICAgLy8gVHlwZUFyZ3VtZW50IDo6PSAoWyIrIiB8ICItIl0gRmllbGRUeXBlU2lnbmF0dXJlKSB8ICIqIi4KKyAgICAgICAgTGlzdE9mVHlwZXMgZXh0ZW5kc0JvdW5kID0gbmV3IExpc3RPZlR5cGVzKDEpOworICAgICAgICBMaXN0T2ZUeXBlcyBzdXBlckJvdW5kID0gbmV3IExpc3RPZlR5cGVzKDEpOworICAgICAgICBpZiAoc3ltYm9sID09ICcqJykgeworICAgICAgICAgICAgc2NhblN5bWJvbCgpOworICAgICAgICAgICAgZXh0ZW5kc0JvdW5kLmFkZChPYmplY3QuY2xhc3MpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBJbXBsRm9yV2lsZGNhcmQoZXh0ZW5kc0JvdW5kLCBzdXBlckJvdW5kKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChzeW1ib2wgPT0gJysnKSB7CisgICAgICAgICAgICBzY2FuU3ltYm9sKCk7CisgICAgICAgICAgICBleHRlbmRzQm91bmQuYWRkKHBhcnNlRmllbGRUeXBlU2lnbmF0dXJlKCkpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBJbXBsRm9yV2lsZGNhcmQoZXh0ZW5kc0JvdW5kLCBzdXBlckJvdW5kKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChzeW1ib2wgPT0gJy0nKSB7CisgICAgICAgICAgICBzY2FuU3ltYm9sKCk7CisgICAgICAgICAgICBzdXBlckJvdW5kLmFkZChwYXJzZUZpZWxkVHlwZVNpZ25hdHVyZSgpKTsKKyAgICAgICAgICAgIGV4dGVuZHNCb3VuZC5hZGQoT2JqZWN0LmNsYXNzKTsKKyAgICAgICAgICAgIHJldHVybiBuZXcgSW1wbEZvcldpbGRjYXJkKGV4dGVuZHNCb3VuZCwgc3VwZXJCb3VuZCk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gcGFyc2VGaWVsZFR5cGVTaWduYXR1cmUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEltcGxGb3JWYXJpYWJsZTxHZW5lcmljRGVjbGFyYXRpb24+IHBhcnNlVHlwZVZhcmlhYmxlU2lnbmF0dXJlKCkgeworICAgICAgICAvLyBUeXBlVmFyaWFibGVTaWduYXR1cmUgOjo9ICJUIiBJZGVudCAiOyIuCisgICAgICAgIGV4cGVjdCgnVCcpOworICAgICAgICBzY2FuSWRlbnRpZmllcigpOworICAgICAgICBleHBlY3QoJzsnKTsKKyAgICAgICAgLy8gUmVmZXJlbmNlIHRvIHR5cGUgdmFyaWFibGU6CisgICAgICAgIC8vIE5vdGU6IHdlIGRvbid0IGtub3cgdGhlIGRlY2xhcmluZyBHZW5lcmljRGVjbGFyYXRpb24geWV0LgorICAgICAgICByZXR1cm4gbmV3IEltcGxGb3JWYXJpYWJsZTxHZW5lcmljRGVjbGFyYXRpb24+KGdlbmVyaWNEZWNsLCBpZGVudGlmaWVyKTsKKyAgICB9CisKKyAgICBUeXBlIHBhcnNlVHlwZVNpZ25hdHVyZSgpIHsKKyAgICAgICAgc3dpdGNoIChzeW1ib2wpIHsKKyAgICAgICAgY2FzZSAnQic6IHNjYW5TeW1ib2woKTsgcmV0dXJuIGJ5dGUuY2xhc3M7CisgICAgICAgIGNhc2UgJ0MnOiBzY2FuU3ltYm9sKCk7IHJldHVybiBjaGFyLmNsYXNzOworICAgICAgICBjYXNlICdEJzogc2NhblN5bWJvbCgpOyByZXR1cm4gZG91YmxlLmNsYXNzOworICAgICAgICBjYXNlICdGJzogc2NhblN5bWJvbCgpOyByZXR1cm4gZmxvYXQuY2xhc3M7CisgICAgICAgIGNhc2UgJ0knOiBzY2FuU3ltYm9sKCk7IHJldHVybiBpbnQuY2xhc3M7CisgICAgICAgIGNhc2UgJ0onOiBzY2FuU3ltYm9sKCk7IHJldHVybiBsb25nLmNsYXNzOworICAgICAgICBjYXNlICdTJzogc2NhblN5bWJvbCgpOyByZXR1cm4gc2hvcnQuY2xhc3M7CisgICAgICAgIGNhc2UgJ1onOiBzY2FuU3ltYm9sKCk7IHJldHVybiBib29sZWFuLmNsYXNzOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgLy8gTm90IGFuIGVsZW1lbnRhcnkgdHlwZSwgYnV0IGEgRmllbGRUeXBlU2lnbmF0dXJlLgorICAgICAgICAgICAgcmV0dXJuIHBhcnNlRmllbGRUeXBlU2lnbmF0dXJlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gcmF3RXhjZXB0aW9uVHlwZXMgdGhlIG5vbi1nZW5lcmljIGV4Y2VwdGlvbnMuIFRoaXMgaXMgbmVjZXNzYXJ5CisgICAgICogICAgIGJlY2F1c2UgdGhlIHNpZ25hdHVyZSBtYXkgb21pdCB0aGUgZXhjZXB0aW9ucyB3aGVuIG5vbmUgYXJlIGdlbmVyaWMuCisgICAgICogICAgIE1heSBiZSBudWxsIGZvciBtZXRob2RzIHRoYXQgZGVjbGFyZSBubyBleGNlcHRpb25zLgorICAgICAqLworICAgIHZvaWQgcGFyc2VNZXRob2RUeXBlU2lnbmF0dXJlKENsYXNzPD8+W10gcmF3RXhjZXB0aW9uVHlwZXMpIHsKKyAgICAgICAgLy8gTWV0aG9kVHlwZVNpZ25hdHVyZSA6Oj0gW0Zvcm1hbFR5cGVQYXJhbWV0ZXJzXQorICAgICAgICAvLyAgICAgICAgICIoIiB7VHlwZVNpZ25hdHVyZX0gIikiIFJldHVyblR5cGUge1Rocm93c1NpZ25hdHVyZX0uCisKKyAgICAgICAgcGFyc2VPcHRGb3JtYWxUeXBlUGFyYW1ldGVycygpOworCisgICAgICAgIHBhcmFtZXRlclR5cGVzID0gbmV3IExpc3RPZlR5cGVzKDE2KTsKKyAgICAgICAgZXhwZWN0KCcoJyk7CisgICAgICAgIHdoaWxlIChzeW1ib2wgIT0gJyknICYmIChzeW1ib2wgPiAwKSkgeworICAgICAgICAgICAgcGFyYW1ldGVyVHlwZXMuYWRkKHBhcnNlVHlwZVNpZ25hdHVyZSgpKTsKKyAgICAgICAgfQorICAgICAgICBleHBlY3QoJyknKTsKKworICAgICAgICByZXR1cm5UeXBlID0gcGFyc2VSZXR1cm5UeXBlKCk7CisKKyAgICAgICAgaWYgKHN5bWJvbCA9PSAnXicpIHsKKyAgICAgICAgICAgIGV4Y2VwdGlvblR5cGVzID0gbmV3IExpc3RPZlR5cGVzKDgpOworICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIHNjYW5TeW1ib2woKTsKKworICAgICAgICAgICAgICAgIC8vIFRocm93c1NpZ25hdHVyZSA6Oj0gKCJeIiBDbGFzc1R5cGVTaWduYXR1cmUpIHwKKyAgICAgICAgICAgICAgICAvLyAgICAgKCJeIiBUeXBlVmFyaWFibGVTaWduYXR1cmUpLgorICAgICAgICAgICAgICAgIGlmIChzeW1ib2wgPT0gJ1QnKSB7CisgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvblR5cGVzLmFkZChwYXJzZVR5cGVWYXJpYWJsZVNpZ25hdHVyZSgpKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBleGNlcHRpb25UeXBlcy5hZGQocGFyc2VDbGFzc1R5cGVTaWduYXR1cmUoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSB3aGlsZSAoc3ltYm9sID09ICdeJyk7CisgICAgICAgIH0gZWxzZSBpZiAocmF3RXhjZXB0aW9uVHlwZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgZXhjZXB0aW9uVHlwZXMgPSBuZXcgTGlzdE9mVHlwZXMocmF3RXhjZXB0aW9uVHlwZXMpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZXhjZXB0aW9uVHlwZXMgPSBuZXcgTGlzdE9mVHlwZXMoMCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBUeXBlIHBhcnNlUmV0dXJuVHlwZSgpIHsKKyAgICAgICAgLy8gUmV0dXJuVHlwZSA6Oj0gVHlwZVNpZ25hdHVyZSB8ICJWIi4KKyAgICAgICAgaWYgKHN5bWJvbCAhPSAnVicpIHsgcmV0dXJuIHBhcnNlVHlwZVNpZ25hdHVyZSgpOyB9CisgICAgICAgIGVsc2UgeyBzY2FuU3ltYm9sKCk7IHJldHVybiB2b2lkLmNsYXNzOyB9CisgICAgfQorCisKKyAgICAvLworICAgIC8vIFNjYW5uZXI6CisgICAgLy8KKworICAgIHZvaWQgc2NhblN5bWJvbCgpIHsKKyAgICAgICAgaWYgKCFlb2YpIHsKKyAgICAgICAgICAgIGlmIChwb3MgPCBidWZmZXIubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgc3ltYm9sID0gYnVmZmVyW3Bvc107CisgICAgICAgICAgICAgICAgcG9zKys7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHN5bWJvbCA9IDA7CisgICAgICAgICAgICAgICAgZW9mID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBHZW5lcmljU2lnbmF0dXJlRm9ybWF0RXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHZvaWQgZXhwZWN0KGNoYXIgYykgeworICAgICAgICBpZiAoc3ltYm9sID09IGMpIHsKKyAgICAgICAgICAgIHNjYW5TeW1ib2woKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBHZW5lcmljU2lnbmF0dXJlRm9ybWF0RXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGJvb2xlYW4gaXNTdG9wU3ltYm9sKGNoYXIgY2gpIHsKKyAgICAgICAgc3dpdGNoIChjaCkgeworICAgICAgICBjYXNlICc6JzoKKyAgICAgICAgY2FzZSAnLyc6CisgICAgICAgIGNhc2UgJzsnOgorICAgICAgICBjYXNlICc8JzoKKyAgICAgICAgY2FzZSAnLic6CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gUFJFOiBzeW1ib2wgaXMgdGhlIGZpcnN0IGNoYXIgb2YgdGhlIGlkZW50aWZpZXIuCisgICAgLy8gUE9TVDogc3ltYm9sID0gdGhlIG5leHQgc3ltYm9sIEFGVEVSIHRoZSBpZGVudGlmaWVyLgorICAgIHZvaWQgc2NhbklkZW50aWZpZXIoKSB7CisgICAgICAgIGlmICghZW9mKSB7CisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIGlkZW50QnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoMzIpOworICAgICAgICAgICAgaWYgKCFpc1N0b3BTeW1ib2woc3ltYm9sKSkgeworICAgICAgICAgICAgICAgIGlkZW50QnVmLmFwcGVuZChzeW1ib2wpOworICAgICAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICAgICAgY2hhciBjaCA9IGJ1ZmZlcltwb3NdOworICAgICAgICAgICAgICAgICAgICBpZiAoKGNoID49ICdhJykgJiYgKGNoIDw9ICd6JykgfHwgKGNoID49ICdBJykgJiYgKGNoIDw9ICdaJykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAhaXNTdG9wU3ltYm9sKGNoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRCdWYuYXBwZW5kKGJ1ZmZlcltwb3NdKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBvcysrOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllciA9IGlkZW50QnVmLnRvU3RyaW5nKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBzY2FuU3ltYm9sKCk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IHdoaWxlIChwb3MgIT0gYnVmZmVyLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgaWRlbnRpZmllciA9IGlkZW50QnVmLnRvU3RyaW5nKCk7CisgICAgICAgICAgICAgICAgc3ltYm9sID0gMDsKKyAgICAgICAgICAgICAgICBlb2YgPSB0cnVlOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBJZGVudCBzdGFydHMgd2l0aCBpbmNvcnJlY3QgY2hhci4KKyAgICAgICAgICAgICAgICBzeW1ib2wgPSAwOworICAgICAgICAgICAgICAgIGVvZiA9IHRydWU7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEdlbmVyaWNTaWduYXR1cmVGb3JtYXRFcnJvcigpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IEdlbmVyaWNTaWduYXR1cmVGb3JtYXRFcnJvcigpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvbGFuZy9yZWZsZWN0L0ltcGxGb3JBcnJheS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL2xhbmcvcmVmbGVjdC9JbXBsRm9yQXJyYXkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOWI3NmIxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL2xhbmcvcmVmbGVjdC9JbXBsRm9yQXJyYXkuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5HZW5lcmljQXJyYXlUeXBlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGU7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBJbXBsRm9yQXJyYXkgaW1wbGVtZW50cyBHZW5lcmljQXJyYXlUeXBlIHsKKyAgICBwcml2YXRlIGZpbmFsIFR5cGUgY29tcG9uZW50VHlwZTsKKworICAgIHB1YmxpYyBJbXBsRm9yQXJyYXkoVHlwZSBjb21wb25lbnRUeXBlKSB7CisgICAgICAgIHRoaXMuY29tcG9uZW50VHlwZSA9IGNvbXBvbmVudFR5cGU7CisgICAgfQorCisgICAgcHVibGljIFR5cGUgZ2V0R2VuZXJpY0NvbXBvbmVudFR5cGUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gKChJbXBsRm9yVHlwZSljb21wb25lbnRUeXBlKS5nZXRSZXNvbHZlZFR5cGUoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBjb21wb25lbnRUeXBlOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIGNvbXBvbmVudFR5cGUudG9TdHJpbmcoKSArICJbXSI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL2xhbmcvcmVmbGVjdC9JbXBsRm9yVHlwZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL2xhbmcvcmVmbGVjdC9JbXBsRm9yVHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxZjA1ZDQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvbGFuZy9yZWZsZWN0L0ltcGxGb3JUeXBlLmphdmEKQEAgLTAsMCArMSw4OCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkubGFuZy5yZWZsZWN0OworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuUGFyYW1ldGVyaXplZFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVHlwZTsKKworcHVibGljIGZpbmFsIGNsYXNzIEltcGxGb3JUeXBlIGltcGxlbWVudHMgUGFyYW1ldGVyaXplZFR5cGUgeworICAgIHByaXZhdGUgZmluYWwgTGlzdE9mVHlwZXMgYXJnczsKKyAgICBwcml2YXRlIGZpbmFsIEltcGxGb3JUeXBlIG93bmVyVHlwZTA7IC8vIFBvdGVudGlhbGx5IHVucmVzb2x2ZWQuCisgICAgcHJpdmF0ZSBUeXBlIG93bmVyVHlwZVJlczsKKyAgICBwcml2YXRlIENsYXNzIHJhd1R5cGU7IC8vIEFscmVhZHkgcmVzb2x2ZWQuCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcmF3VHlwZU5hbWU7CisgICAgcHJpdmF0ZSBDbGFzc0xvYWRlciBsb2FkZXI7CisKKworICAgIHB1YmxpYyBJbXBsRm9yVHlwZShJbXBsRm9yVHlwZSBvd25lclR5cGUsIFN0cmluZyByYXdUeXBlTmFtZSwKKyAgICAgICAgICAgIExpc3RPZlR5cGVzIGFyZ3MsIENsYXNzTG9hZGVyIGxvYWRlcikgeworICAgICAgICB0aGlzLm93bmVyVHlwZTAgPSBvd25lclR5cGU7CisgICAgICAgIHRoaXMucmF3VHlwZU5hbWUgPSByYXdUeXBlTmFtZTsKKyAgICAgICAgdGhpcy5hcmdzID0gYXJnczsKKyAgICAgICAgdGhpcy5sb2FkZXIgPSBsb2FkZXI7CisgICAgfQorCisKKyAgICBwdWJsaWMgVHlwZVtdIGdldEFjdHVhbFR5cGVBcmd1bWVudHMoKSB7CisgICAgICAgIC8vIEFTU1VNUFRJT046IGFyZ3MgaXMgbmV2ZXIgbnVsbCEhIQorICAgICAgICByZXR1cm4gYXJncy5nZXRSZXNvbHZlZFR5cGVzKCkuY2xvbmUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgVHlwZSBnZXRPd25lclR5cGUoKSB7CisgICAgICAgIGlmIChvd25lclR5cGVSZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKG93bmVyVHlwZTAgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG93bmVyVHlwZVJlcyA9IG93bmVyVHlwZTAuZ2V0UmVzb2x2ZWRUeXBlKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG93bmVyVHlwZVJlcyA9IGdldFJhd1R5cGUoKS5nZXREZWNsYXJpbmdDbGFzcygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBvd25lclR5cGVSZXM7CisgICAgfQorCisgICAgcHVibGljIENsYXNzIGdldFJhd1R5cGUoKSB7CisgICAgICAgIGlmIChyYXdUeXBlID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIEhlcmUgdGhlIGFjdHVhbCBsb2FkaW5nIG9mIHRoZSBjbGFzcyBoYXMgdG8gYmUgcGVyZm9ybWVkIGFuZCB0aGUKKyAgICAgICAgICAgIC8vIEV4Y2VwdGlvbnMgaGF2ZSB0byBiZSByZS10aHJvd24gVHlwZU5vdFByZXNlbnQuLi4KKyAgICAgICAgICAgIC8vIEhvdyB0byBkZWFsIHdpdGggbWVtYmVyIChuZXN0ZWQpIGNsYXNzZXM/CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJhd1R5cGUgPSBDbGFzcy5mb3JOYW1lKHJhd1R5cGVOYW1lLCBmYWxzZSwgbG9hZGVyKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlTm90UHJlc2VudEV4Y2VwdGlvbihyYXdUeXBlTmFtZSwgZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJhd1R5cGU7CisgICAgfQorCisKKyAgICBUeXBlIGdldFJlc29sdmVkVHlwZSgpIHsKKyAgICAgICAgaWYgKGFyZ3MuZ2V0UmVzb2x2ZWRUeXBlcygpLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0UmF3VHlwZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgc2IuYXBwZW5kKHJhd1R5cGVOYW1lKTsKKyAgICAgICAgaWYgKGFyZ3MubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIjwiKS5hcHBlbmQoYXJncykuYXBwZW5kKCI+Iik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL2xhbmcvcmVmbGVjdC9JbXBsRm9yVmFyaWFibGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS9sYW5nL3JlZmxlY3QvSW1wbEZvclZhcmlhYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzgzZDIyMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS9sYW5nL3JlZmxlY3QvSW1wbEZvclZhcmlhYmxlLmphdmEKQEAgLTAsMCArMSwxMzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLmxhbmcucmVmbGVjdDsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkdlbmVyaWNEZWNsYXJhdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5UeXBlVmFyaWFibGU7CisKKworcHVibGljIGZpbmFsIGNsYXNzIEltcGxGb3JWYXJpYWJsZTxEIGV4dGVuZHMgR2VuZXJpY0RlY2xhcmF0aW9uPiBpbXBsZW1lbnRzIFR5cGVWYXJpYWJsZTxEPiB7CisgICAgcHJpdmF0ZSBJbXBsRm9yVmFyaWFibGU8RD4gZm9ybWFsVmFyOworICAgIHByaXZhdGUgZmluYWwgR2VuZXJpY0RlY2xhcmF0aW9uIGRlY2xPZlZhclVzZXI7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbmFtZTsKKyAgICBwcml2YXRlIEQgZ2VuZXJpY0RlY2xhcmF0aW9uOworICAgIHByaXZhdGUgTGlzdE9mVHlwZXMgYm91bmRzOworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgIGlmKCEobyBpbnN0YW5jZW9mIFR5cGVWYXJpYWJsZSkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBUeXBlVmFyaWFibGU8Pz4gdGhhdCA9IChUeXBlVmFyaWFibGU8Pz4pIG87CisgICAgICAgIHJldHVybiBnZXROYW1lKCkuZXF1YWxzKHRoYXQuZ2V0TmFtZSgpKSAmJgorICAgICAgICAgICAgICAgIGdldEdlbmVyaWNEZWNsYXJhdGlvbigpLmVxdWFscyh0aGF0LmdldEdlbmVyaWNEZWNsYXJhdGlvbigpKTsKKyAgICB9CisKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiAzMSAqIGdldE5hbWUoKS5oYXNoQ29kZSgpICsgZ2V0R2VuZXJpY0RlY2xhcmF0aW9uKCkuaGFzaENvZGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gZ2VuZXJpY0RlY2wgZGVjbGFyYXRpb24gd2hlcmUgYSB0eXBlIHZhcmlhYmxlIGlzIGRlY2xhcmVkCisgICAgICogQHBhcmFtIG5hbWUgdHlwZSB2YXJpYWJsZSBuYW1lCisgICAgICogQHBhcmFtIGJvdW5kcyBjbGFzcyBhbmQgaW50ZXJmYWNlIGJvdW5kcworICAgICAqLworICAgIEltcGxGb3JWYXJpYWJsZShEIGdlbmVyaWNEZWNsLCBTdHJpbmcgbmFtZSwgTGlzdE9mVHlwZXMgYm91bmRzKSB7CisgICAgICAgIHRoaXMuZ2VuZXJpY0RlY2xhcmF0aW9uID0gZ2VuZXJpY0RlY2w7CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgIHRoaXMuYm91bmRzID0gYm91bmRzOworICAgICAgICB0aGlzLmZvcm1hbFZhciA9IHRoaXM7CisgICAgICAgIHRoaXMuZGVjbE9mVmFyVXNlciA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIGdlbmVyaWNEZWNsIGRlY2xhcmF0aW9uIHdoZXJlIGEgdHlwZSB2YXJpYWJsZSBpcyB1c2VkCisgICAgICogQHBhcmFtIG5hbWUgdHlwZSB2YXJpYWJsZSBuYW1lCisgICAgICovCisgICAgSW1wbEZvclZhcmlhYmxlKEQgZ2VuZXJpY0RlY2wsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgIHRoaXMuZGVjbE9mVmFyVXNlciA9IGdlbmVyaWNEZWNsOworICAgIH0KKworICAgIHN0YXRpYyBUeXBlVmFyaWFibGUgZmluZEZvcm1hbFZhcihHZW5lcmljRGVjbGFyYXRpb24gbGF5ZXIsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIFR5cGVWYXJpYWJsZVtdIGZvcm1hbFZhcnMgPSBsYXllci5nZXRUeXBlUGFyYW1ldGVycygpOworICAgICAgICBmb3IgKFR5cGVWYXJpYWJsZSB2YXIgOiBmb3JtYWxWYXJzKSB7CisgICAgICAgICAgICBpZiAobmFtZS5lcXVhbHModmFyLmdldE5hbWUoKSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdmFyOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIHJlc29sdmUoKSBsb29rcyB1cCB0aGUgbmV4dCBsZXZlbCBvbmx5LCBpZiBudWxsIGlzIHJldHVybmVkCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIEdlbmVyaWNEZWNsYXJhdGlvbiBuZXh0TGF5ZXIoR2VuZXJpY0RlY2xhcmF0aW9uIGRlY2wpIHsKKyAgICAgICAgaWYgKGRlY2wgaW5zdGFuY2VvZiBDbGFzcykgeworICAgICAgICAgICAgLy8gRklYTUU6IElzIHRoZSBmb2xsb3dpbmcgaGllcmFyY2h5IGNvcnJlY3Q/OgorICAgICAgICAgICAgQ2xhc3MgY2wgPSAoQ2xhc3MpZGVjbDsKKyAgICAgICAgICAgIGRlY2wgPSBjbC5nZXRFbmNsb3NpbmdNZXRob2QoKTsKKyAgICAgICAgICAgIGlmIChkZWNsICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZGVjbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGRlY2wgPSBjbC5nZXRFbmNsb3NpbmdDb25zdHJ1Y3RvcigpOworICAgICAgICAgICAgaWYgKGRlY2wgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBkZWNsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGNsLmdldEVuY2xvc2luZ0NsYXNzKCk7CisgICAgICAgIH0gZWxzZSBpZiAoZGVjbCBpbnN0YW5jZW9mIE1ldGhvZCkgeworICAgICAgICAgICAgcmV0dXJuICgoTWV0aG9kKWRlY2wpLmdldERlY2xhcmluZ0NsYXNzKCk7CisgICAgICAgIH0gZWxzZSBpZiAoZGVjbCBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSB7CisgICAgICAgICAgICByZXR1cm4gKChDb25zdHJ1Y3RvcilkZWNsKS5nZXREZWNsYXJpbmdDbGFzcygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICB2b2lkIHJlc29sdmUoKSB7CisgICAgICAgIGlmIChmb3JtYWxWYXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIEdlbmVyaWNEZWNsYXJhdGlvbiBjdXJMYXllciA9IGRlY2xPZlZhclVzZXI7CisgICAgICAgIFR5cGVWYXJpYWJsZSB2YXI7CisgICAgICAgIHdoaWxlICgodmFyID0gZmluZEZvcm1hbFZhcihjdXJMYXllciwgbmFtZSkpID09IG51bGwpIHsKKyAgICAgICAgICAgIGN1ckxheWVyID0gbmV4dExheWVyKGN1ckxheWVyKTsKKyAgICAgICAgICAgIGlmIChjdXJMYXllciA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJpbGxlZ2FsIHR5cGUgdmFyaWFibGUgcmVmZXJlbmNlIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZm9ybWFsVmFyID0gKEltcGxGb3JWYXJpYWJsZTxEPikgdmFyOworICAgICAgICB0aGlzLmdlbmVyaWNEZWNsYXJhdGlvbiA9IGZvcm1hbFZhci5nZW5lcmljRGVjbGFyYXRpb247CisgICAgICAgIHRoaXMuYm91bmRzID0gZm9ybWFsVmFyLmJvdW5kczsKKyAgICB9CisKKyAgICBwdWJsaWMgVHlwZVtdIGdldEJvdW5kcygpIHsKKyAgICAgICAgcmVzb2x2ZSgpOworICAgICAgICByZXR1cm4gYm91bmRzLmdldFJlc29sdmVkVHlwZXMoKS5jbG9uZSgpOworICAgIH0KKworICAgIHB1YmxpYyBEIGdldEdlbmVyaWNEZWNsYXJhdGlvbigpIHsKKyAgICAgICAgcmVzb2x2ZSgpOworICAgICAgICByZXR1cm4gZ2VuZXJpY0RlY2xhcmF0aW9uOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL2xhbmcvcmVmbGVjdC9JbXBsRm9yV2lsZGNhcmQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS9sYW5nL3JlZmxlY3QvSW1wbEZvcldpbGRjYXJkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjA2MDVmMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS9sYW5nL3JlZmxlY3QvSW1wbEZvcldpbGRjYXJkLmphdmEKQEAgLTAsMCArMSw3MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkubGFuZy5yZWZsZWN0OworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWFsZm9ybWVkUGFyYW1ldGVyaXplZFR5cGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5XaWxkY2FyZFR5cGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworcHVibGljIGZpbmFsIGNsYXNzIEltcGxGb3JXaWxkY2FyZCBpbXBsZW1lbnRzIFdpbGRjYXJkVHlwZSB7CisKKyAgICBwcml2YXRlIGZpbmFsIExpc3RPZlR5cGVzIGV4dGVuZHNCb3VuZCwgc3VwZXJCb3VuZDsKKworICAgIHB1YmxpYyBJbXBsRm9yV2lsZGNhcmQoTGlzdE9mVHlwZXMgZXh0ZW5kc0JvdW5kLCBMaXN0T2ZUeXBlcyBzdXBlckJvdW5kKSB7CisgICAgICAgIHRoaXMuZXh0ZW5kc0JvdW5kID0gZXh0ZW5kc0JvdW5kOworICAgICAgICB0aGlzLnN1cGVyQm91bmQgPSBzdXBlckJvdW5kOworICAgIH0KKworICAgIHB1YmxpYyBUeXBlW10gZ2V0TG93ZXJCb3VuZHMoKSB0aHJvd3MgVHlwZU5vdFByZXNlbnRFeGNlcHRpb24sCisgICAgICAgICAgICBNYWxmb3JtZWRQYXJhbWV0ZXJpemVkVHlwZUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzdXBlckJvdW5kLmdldFJlc29sdmVkVHlwZXMoKS5jbG9uZSgpOworICAgIH0KKworICAgIHB1YmxpYyBUeXBlW10gZ2V0VXBwZXJCb3VuZHMoKSB0aHJvd3MgVHlwZU5vdFByZXNlbnRFeGNlcHRpb24sCisgICAgICAgICAgICBNYWxmb3JtZWRQYXJhbWV0ZXJpemVkVHlwZUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBleHRlbmRzQm91bmQuZ2V0UmVzb2x2ZWRUeXBlcygpLmNsb25lKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgIGlmKCEobyBpbnN0YW5jZW9mIFdpbGRjYXJkVHlwZSkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBXaWxkY2FyZFR5cGUgdGhhdCA9IChXaWxkY2FyZFR5cGUpIG87CisgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKGdldExvd2VyQm91bmRzKCksIHRoYXQuZ2V0TG93ZXJCb3VuZHMoKSkgJiYKKyAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKGdldFVwcGVyQm91bmRzKCksIHRoYXQuZ2V0VXBwZXJCb3VuZHMoKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIDMxICogQXJyYXlzLmhhc2hDb2RlKGdldExvd2VyQm91bmRzKCkpICsKKyAgICAgICAgICAgICAgICBBcnJheXMuaGFzaENvZGUoZ2V0VXBwZXJCb3VuZHMoKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCI/Iik7CisgICAgICAgIGlmICgoZXh0ZW5kc0JvdW5kLmxlbmd0aCgpID09IDEgJiYgZXh0ZW5kc0JvdW5kLmdldFJlc29sdmVkVHlwZXMoKVswXSAhPSBPYmplY3QuY2xhc3MpCisgICAgICAgICAgICAgICAgfHwgZXh0ZW5kc0JvdW5kLmxlbmd0aCgpID4gMSkgeworICAgICAgICAgICAgc2IuYXBwZW5kKCIgZXh0ZW5kcyAiKS5hcHBlbmQoZXh0ZW5kc0JvdW5kKTsKKyAgICAgICAgfSBlbHNlIGlmIChzdXBlckJvdW5kLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgc2IuYXBwZW5kKCIgc3VwZXIgIikuYXBwZW5kKHN1cGVyQm91bmQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS9sYW5nL3JlZmxlY3QvTGlzdE9mVHlwZXMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS9sYW5nL3JlZmxlY3QvTGlzdE9mVHlwZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OTQ3MGY1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL2xhbmcvcmVmbGVjdC9MaXN0T2ZUeXBlcy5qYXZhCkBAIC0wLDAgKzEsNzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLmxhbmcucmVmbGVjdDsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworcHVibGljIGZpbmFsIGNsYXNzIExpc3RPZlR5cGVzIHsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIExpc3RPZlR5cGVzIEVNUFRZID0gbmV3IExpc3RPZlR5cGVzKDApOworCisgICAgcHJpdmF0ZSBmaW5hbCBBcnJheUxpc3Q8VHlwZT4gdHlwZXM7CisgICAgcHJpdmF0ZSBUeXBlW10gcmVzb2x2ZWRUeXBlczsKKworICAgIExpc3RPZlR5cGVzKGludCBjYXBhY2l0eSkgeworICAgICAgICB0eXBlcyA9IG5ldyBBcnJheUxpc3Q8VHlwZT4oY2FwYWNpdHkpOworICAgIH0KKworICAgIExpc3RPZlR5cGVzKFR5cGVbXSB0eXBlcykgeworICAgICAgICB0aGlzLnR5cGVzID0gbmV3IEFycmF5TGlzdDxUeXBlPih0eXBlcy5sZW5ndGgpOworICAgICAgICBmb3IgKFR5cGUgdHlwZSA6IHR5cGVzKSB7CisgICAgICAgICAgICB0aGlzLnR5cGVzLmFkZCh0eXBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHZvaWQgYWRkKFR5cGUgdHlwZSkgeworICAgICAgICBpZiAodHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInR5cGUgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHR5cGVzLmFkZCh0eXBlKTsKKyAgICB9CisKKyAgICBpbnQgbGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gdHlwZXMuc2l6ZSgpOworICAgIH0KKworICAgIHB1YmxpYyBUeXBlW10gZ2V0UmVzb2x2ZWRUeXBlcygpIHsKKyAgICAgICAgVHlwZVtdIHJlc3VsdCA9IHJlc29sdmVkVHlwZXM7CisgICAgICAgIHJldHVybiByZXN1bHQgIT0gbnVsbCA/IHJlc3VsdCA6IChyZXNvbHZlZFR5cGVzID0gcmVzb2x2ZVR5cGVzKHR5cGVzKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBUeXBlW10gcmVzb2x2ZVR5cGVzKExpc3Q8VHlwZT4gdW5yZXNvbHZlZCkgeworICAgICAgICBUeXBlW10gcmVzdWx0ID0gbmV3IFR5cGVbdW5yZXNvbHZlZC5zaXplKCldOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHVucmVzb2x2ZWQuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIFR5cGUgdHlwZSA9IHVucmVzb2x2ZWQuZ2V0KGkpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXN1bHRbaV0gPSAoKEltcGxGb3JUeXBlKSB0eXBlKS5nZXRSZXNvbHZlZFR5cGUoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0W2ldID0gdHlwZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdHlwZXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChpID4gMCkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIiwgIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHR5cGVzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS9sYW5nL3JlZmxlY3QvTGlzdE9mVmFyaWFibGVzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvbGFuZy9yZWZsZWN0L0xpc3RPZlZhcmlhYmxlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBlNzU3YWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvbGFuZy9yZWZsZWN0L0xpc3RPZlZhcmlhYmxlcy5qYXZhCkBAIC0wLDAgKzEsMzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLmxhbmcucmVmbGVjdDsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGVWYXJpYWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworCitjbGFzcyBMaXN0T2ZWYXJpYWJsZXMgeworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZVZhcmlhYmxlW10gRU1QVFkgPSBuZXcgSW1wbEZvclZhcmlhYmxlWzBdOworCisgICAgQXJyYXlMaXN0PFR5cGVWYXJpYWJsZTw/Pj4gYXJyYXkgPSBuZXcgQXJyYXlMaXN0PFR5cGVWYXJpYWJsZTw/Pj4oKTsKKworICAgIHZvaWQgYWRkIChUeXBlVmFyaWFibGU8Pz4gZWxlbSkgeworICAgICAgICBhcnJheS5hZGQoZWxlbSk7CisgICAgfQorCisgICAgVHlwZVZhcmlhYmxlPD8+W10gZ2V0QXJyYXkoKSB7CisgICAgICAgIFR5cGVWYXJpYWJsZTw/PltdIGEgPSBuZXcgVHlwZVZhcmlhYmxlW2FycmF5LnNpemUoKV07CisgICAgICAgIHJldHVybiBhcnJheS50b0FycmF5KGEpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS9sYW5nL3JlZmxlY3QvVHlwZXMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS9sYW5nL3JlZmxlY3QvVHlwZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZDcwMGZjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL2xhbmcvcmVmbGVjdC9UeXBlcy5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLmxhbmcucmVmbGVjdDsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGU7CisKK3B1YmxpYyBjbGFzcyBUeXBlcyB7CisKKyAgICBwdWJsaWMgc3RhdGljIFR5cGVbXSBnZXRDbG9uZWRUeXBlQXJyYXkoTGlzdE9mVHlwZXMgdHlwZXMpIHsKKyAgICAgICAgcmV0dXJuIHR5cGVzLmdldFJlc29sdmVkVHlwZXMoKS5jbG9uZSgpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgVHlwZSBnZXRUeXBlKFR5cGUgdHlwZSkgeworICAgICAgICBpZiAodHlwZSBpbnN0YW5jZW9mIEltcGxGb3JUeXBlKSB7CisgICAgICAgICAgICByZXR1cm4gKChJbXBsRm9yVHlwZSl0eXBlKS5nZXRSZXNvbHZlZFR5cGUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiB0eXBlOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3V0aWwvRGVsZXRlT25FeGl0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdXRpbC9EZWxldGVPbkV4aXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZmEwNGZkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3V0aWwvRGVsZXRlT25FeGl0LmphdmEKQEAgLTAsMCArMSw3OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS51dGlsOworCisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CisKKy8qKgorICogSW1wbGVtZW50cyB0aGUgYWN0dWFsIERlbGV0ZU9uRXhpdCBtZWNoYW5pc20uIElzIHJlZ2lzdGVyZWQgYXMgYSBzaHV0ZG93bgorICogaG9vayBpbiB0aGUgUnVudGltZSwgb25jZSBpdCBpcyBhY3R1YWxseSBiZWluZyB1c2VkLgorICovCitwdWJsaWMgY2xhc3MgRGVsZXRlT25FeGl0IGV4dGVuZHMgVGhyZWFkIHsKKworICAgIC8qKgorICAgICAqIE91ciBzaW5nbGV0b24gaW5zdGFuY2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgRGVsZXRlT25FeGl0IGluc3RhbmNlOworCisgICAgLyoqCisgICAgICogT3VyIGxpc3Qgb2YgZmlsZXMgc2NoZWR1bGVkIGZvciBkZWxldGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIEFycmF5TGlzdDxTdHJpbmc+IGZpbGVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIG91ciBzaW5nbGV0b24gaW5zdGFuY2UsIGNyZWF0aW5nIGl0IGlmIG5lY2Vzc2FyeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBEZWxldGVPbkV4aXQgZ2V0SW5zdGFuY2UoKSB7CisgICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKSB7CisgICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBEZWxldGVPbkV4aXQoKTsKKyAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmFkZFNodXRkb3duSG9vayhpbnN0YW5jZSk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gaW5zdGFuY2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2NoZWR1bGVzIGEgZmlsZSBmb3IgZGVsZXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZW5hbWUgVGhlIGZpbGUgdG8gZGVsZXRlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZEZpbGUoU3RyaW5nIGZpbGVuYW1lKSB7CisgICAgICAgIHN5bmNocm9uaXplZChmaWxlcykgeworICAgICAgICAgICAgaWYgKCFmaWxlcy5jb250YWlucyhmaWxlbmFtZSkpIHsKKyAgICAgICAgICAgICAgICBmaWxlcy5hZGQoZmlsZW5hbWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRG9lcyB0aGUgYWN0dWFsIHdvcmsuIE5vdGUgd2UgKGEpIGZpcnN0IHNvcnQgdGhlIGZpbGVzIGxleGljb2dyYXBoaWNhbGx5CisgICAgICogYW5kIHRoZW4gKGIpIGRlbGV0ZSB0aGVtIGluIHJldmVyc2Ugb3JkZXIuIFRoaXMgaXMgdG8gbWFrZSBzdXJlIGZpbGVzCisgICAgICogZ2V0IGRlbGV0ZWQgYmVmb3JlIHRoZWlyIHBhcmVudCBkaXJlY3Rvcmllcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgIENvbGxlY3Rpb25zLnNvcnQoZmlsZXMpOworICAgICAgICBmb3IgKGludCBpID0gZmlsZXMuc2l6ZSgpIC0gMTsgaSA+PSAwOyBpLS0pIHsKKyAgICAgICAgICAgIG5ldyBGaWxlKGZpbGVzLmdldChpKSkuZGVsZXRlKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdXRpbC9Ud29LZXlIYXNoTWFwLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdXRpbC9Ud29LZXlIYXNoTWFwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzVlNmM2MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS91dGlsL1R3b0tleUhhc2hNYXAuamF2YQpAQCAtMCwwICsxLDU2NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkFic3RyYWN0Q29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQWJzdHJhY3RNYXA7CitpbXBvcnQgamF2YS51dGlsLkFic3RyYWN0U2V0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworLyoqCisgKgorICogUmVkdWN0aXZlIGhhc2ggd2l0aCB0d28ga2V5cworICoKKyAqLworcHVibGljIGNsYXNzIFR3b0tleUhhc2hNYXA8RSwgSywgVj4gZXh0ZW5kcyBBYnN0cmFjdE1hcDxTdHJpbmcsIFY+IHsKKworICAgIHN0YXRpYyBmaW5hbCBmbG9hdCBERUZBVUxUX0xPQURfRkFDVE9SID0gMC43NWY7CisgICAgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0lOSVRJQUxfU0laRSA9IDE2OworCisgICAgcHJpdmF0ZSBTZXQ8TWFwLkVudHJ5PFN0cmluZywgVj4+IGVudHJ5U2V0OworICAgIHByaXZhdGUgQ29sbGVjdGlvbjxWPiB2YWx1ZXM7CisgICAgcHJpdmF0ZSBpbnQgc2l6ZTsKKyAgICBwcml2YXRlIGludCBhcnJTaXplOworICAgIHByaXZhdGUgaW50IG1vZENvdW50OworCisgICAgcHJpdmF0ZSBFbnRyeTxFLCBLLCBWPltdIGFycjsKKworICAgIHByaXZhdGUgZmxvYXQgbG9hZEZhY3RvcjsKKyAgICBpbnQgdGhyZXNob2xkID0gMDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gZW1wdHkgSGFzaE1hcAorICAgICAqLworICAgIHB1YmxpYyBUd29LZXlIYXNoTWFwKCkgeworICAgICAgICB0aGlzKERFRkFVTFRfSU5JVElBTF9TSVpFLCBERUZBVUxUX0xPQURfRkFDVE9SKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIGVtcHR5IEhhc2hNYXAKKyAgICAgKgorICAgICAqIEBwYXJhbSBpbml0aWFsQ2FwYWNpdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgVHdvS2V5SGFzaE1hcChpbnQgaW5pdGlhbENhcGFjaXR5KSB7CisgICAgICAgIHRoaXMoaW5pdGlhbENhcGFjaXR5LCBERUZBVUxUX0xPQURfRkFDVE9SKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIGVtcHR5IEhhc2hNYXAKKyAgICAgKgorICAgICAqIEBwYXJhbSBpbml0aWFsQ2FwYWNpdHkKKyAgICAgKiBAcGFyYW0gaW5pdGlhbExvYWRGYWN0b3IKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgVHdvS2V5SGFzaE1hcChpbnQgaW5pdGlhbENhcGFjaXR5LCBmbG9hdCBpbml0aWFsTG9hZEZhY3RvcikgeworICAgICAgICBpZiAoaW5pdGlhbENhcGFjaXR5IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaW5pdGlhbENhcGFjaXR5IHNob3VsZCBiZSA+PSAwIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGluaXRpYWxMb2FkRmFjdG9yIDw9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJpbml0aWFsTG9hZEZhY3RvciBzaG91bGQgYmUgPiAwIik7CisgICAgICAgIH0KKyAgICAgICAgbG9hZEZhY3RvciA9IGluaXRpYWxMb2FkRmFjdG9yOworICAgICAgICBpZiAoaW5pdGlhbENhcGFjaXR5ID09IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgICBpbml0aWFsQ2FwYWNpdHktLTsKKyAgICAgICAgfQorICAgICAgICBhcnJTaXplID0gaW5pdGlhbENhcGFjaXR5ID4gMCA/IGluaXRpYWxDYXBhY2l0eSA6IDE7CisgICAgICAgIHRocmVzaG9sZCA9IChpbnQpIChhcnJTaXplICogbG9hZEZhY3Rvcik7CisgICAgICAgIGFyciA9IG5ldyBFbnRyeVthcnJTaXplICsgMV07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvbGxlY3Rpb24gdmlldyBvZiB0aGUgdmFsdWVzCisgICAgICovCisgICAgcHVibGljIENvbGxlY3Rpb248Vj4gdmFsdWVzKCkgeworICAgICAgICBpZiAodmFsdWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHZhbHVlcyA9IG5ldyBWYWx1ZXNDb2xsZWN0aW9uSW1wbCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB2YWx1ZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvbGxlY3Rpb24gdmlldyBvZiB0aGUgbWFwcGluZ3MKKyAgICAgKi8KKyAgICBwdWJsaWMgU2V0PE1hcC5FbnRyeTxTdHJpbmcsIFY+PiBlbnRyeVNldCgpIHsKKyAgICAgICAgaWYgKGVudHJ5U2V0ID09IG51bGwpIHsKKyAgICAgICAgICAgIGVudHJ5U2V0ID0gbmV3IEVudHJ5U2V0SW1wbCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbnRyeVNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbGVhcnMgdGhlIG1hcAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBtb2RDb3VudCsrOworICAgICAgICBzaXplID0gMDsKKyAgICAgICAgQXJyYXlzLmZpbGwoYXJyLCAwLCBhcnIubGVuZ3RoLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBtYXBwaW5nIGZvciB0aGUga2V5cworICAgICAqCisgICAgICogQHBhcmFtIGtleTEKKyAgICAgKiBAcGFyYW0ga2V5MgorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwdWJsaWMgViByZW1vdmUoT2JqZWN0IGtleTEsIE9iamVjdCBrZXkyKSB7CisgICAgICAgIEVudHJ5PEUsIEssIFY+IGUgPSByZW1vdmVFbnRyeShrZXkxLCBrZXkyKTsKKyAgICAgICAgcmV0dXJuIChlICE9IG51bGwpID8gZS52YWx1ZSA6IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzb2NpYXRlcyB0aGUgc3BlY2lmaWVkIHZhbHVlIHdpdGggdGhlIHNwZWNpZmllZCBrZXlzIGluIHRoaXMgbWFwCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5MQorICAgICAqIEBwYXJhbSBrZXkyCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHB1YmxpYyBWIHB1dChFIGtleTEsIEsga2V5MiwgViB2YWx1ZSkgeworICAgICAgICBpZiAoa2V5MSA9PSBudWxsICYmIGtleTIgPT0gbnVsbCkgeworICAgICAgICAgICAgaW50IGluZGV4ID0gYXJyU2l6ZTsKKyAgICAgICAgICAgIGlmIChhcnJbaW5kZXhdID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhcnJbaW5kZXhdID0gY3JlYXRlRW50cnkoMCwgbnVsbCwgbnVsbCwgdmFsdWUsIG51bGwpOworICAgICAgICAgICAgICAgIHNpemUrKzsKKyAgICAgICAgICAgICAgICBtb2RDb3VudCsrOworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBWIG9sZFZhbHVlID0gYXJyW2luZGV4XS52YWx1ZTsKKyAgICAgICAgICAgICAgICBhcnJbaW5kZXhdLnZhbHVlID0gdmFsdWU7CisgICAgICAgICAgICAgICAgcmV0dXJuIG9sZFZhbHVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaW50IGhhc2ggPSBrZXkxLmhhc2hDb2RlKCkgKyBrZXkyLmhhc2hDb2RlKCk7CisgICAgICAgIGludCBpbmRleCA9IChoYXNoICYgMHg3ZmZmZmZmZikgJSBhcnJTaXplOworICAgICAgICBFbnRyeTxFLCBLLCBWPiBlID0gYXJyW2luZGV4XTsKKworICAgICAgICB3aGlsZSAoZSAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoaGFzaCA9PSBlLmhhc2ggJiYga2V5MS5lcXVhbHMoZS5nZXRLZXkxKCkpCisgICAgICAgICAgICAgICAgICAgICYmIGtleTIuZXF1YWxzKGUuZ2V0S2V5MigpKSkgeworICAgICAgICAgICAgICAgIFYgb2xkVmFsdWUgPSBlLnZhbHVlOworICAgICAgICAgICAgICAgIGUudmFsdWUgPSB2YWx1ZTsKKyAgICAgICAgICAgICAgICByZXR1cm4gb2xkVmFsdWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlID0gZS5uZXh0OworICAgICAgICB9CisKKyAgICAgICAgYXJyW2luZGV4XSA9IGNyZWF0ZUVudHJ5KGhhc2gsIGtleTEsIGtleTIsIHZhbHVlLCBhcnJbaW5kZXhdKTsKKyAgICAgICAgc2l6ZSsrOworICAgICAgICBtb2RDb3VudCsrOworCisgICAgICAgIGlmIChzaXplID4gdGhyZXNob2xkKSB7CisgICAgICAgICAgICByZWhhc2goKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWhhc2ggdGhlIG1hcAorICAgICAqCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgdm9pZCByZWhhc2goKSB7CisgICAgICAgIGludCBuZXdBcnJTaXplID0gKGFyclNpemUgKyAxKSAqIDIgKyAxOworICAgICAgICBpZiAobmV3QXJyU2l6ZSA8IDApIHsKKyAgICAgICAgICAgIG5ld0FyclNpemUgPSBJbnRlZ2VyLk1BWF9WQUxVRSAtIDE7CisgICAgICAgIH0KKyAgICAgICAgRW50cnk8RSwgSywgVj5bXSBuZXdBcnIgPSBuZXcgRW50cnlbbmV3QXJyU2l6ZSArIDFdOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyLmxlbmd0aCAtIDE7IGkrKykgeworICAgICAgICAgICAgRW50cnk8RSwgSywgVj4gZW50cnkgPSBhcnJbaV07CisgICAgICAgICAgICB3aGlsZSAoZW50cnkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIEVudHJ5PEUsIEssIFY+IG5leHQgPSBlbnRyeS5uZXh0OworCisgICAgICAgICAgICAgICAgaW50IG5ld0luZGV4ID0gKGVudHJ5Lmhhc2ggJiAweDdmZmZmZmZmKSAlIG5ld0FyclNpemU7CisgICAgICAgICAgICAgICAgZW50cnkubmV4dCA9IG5ld0FycltuZXdJbmRleF07CisgICAgICAgICAgICAgICAgbmV3QXJyW25ld0luZGV4XSA9IGVudHJ5OworCisgICAgICAgICAgICAgICAgZW50cnkgPSBuZXh0OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIG5ld0FycltuZXdBcnJTaXplXSA9IGFyclthcnJTaXplXTsgLy8gbW92ZSBudWxsIGVudHJ5CisgICAgICAgIGFyclNpemUgPSBuZXdBcnJTaXplOworCisgICAgICAgIC8vIFRoZSBtYXhpbXVtIGFycmF5IHNpemUgaXMgcmVhY2hlZCwgaW5jcmVhc2VkIGxvYWRGYWN0b3IKKyAgICAgICAgLy8gd2lsbCBrZWVwIGFycmF5IGZyb20gZnVydGhlciBncm93aW5nCisgICAgICAgIGlmIChhcnJTaXplID09IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgICBsb2FkRmFjdG9yICo9IDEwOworICAgICAgICB9CisgICAgICAgIHRocmVzaG9sZCA9IChpbnQpIChhcnJTaXplICogbG9hZEZhY3Rvcik7CisgICAgICAgIGFyciA9IG5ld0FycjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBtYXAgY29udGFpbnMgYSBtYXBwaW5nIGZvciB7QGNvZGUga2V5MX0gYW5kIHtAY29kZSBrZXkyfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0tleShPYmplY3Qga2V5MSwgT2JqZWN0IGtleTIpIHsKKyAgICAgICAgcmV0dXJuIGZpbmRFbnRyeShrZXkxLCBrZXkyKSAhPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdmFsdWUgYnkga2V5cworICAgICAqCisgICAgICogQHBhcmFtIGtleTEKKyAgICAgKiBAcGFyYW0ga2V5MgorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwdWJsaWMgViBnZXQoT2JqZWN0IGtleTEsIE9iamVjdCBrZXkyKSB7CisgICAgICAgIEVudHJ5PEUsIEssIFY+IGUgPSBmaW5kRW50cnkoa2V5MSwga2V5Mik7CisgICAgICAgIGlmIChlICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBlLnZhbHVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIG1hcCBjb250YWlucyBubyBrZXktdmFsdWUgbWFwcGluZ3MKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICByZXR1cm4gc2l6ZSA9PSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBtYXBwaW5ncworICAgICAqLworICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIHNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBuZXcgZW50cnkKKyAgICAgKgorICAgICAqIEBwYXJhbSBoYXNoQ29kZQorICAgICAqIEBwYXJhbSBrZXkxCisgICAgICogQHBhcmFtIGtleTIKKyAgICAgKiBAcGFyYW0gdmFsdWUKKyAgICAgKiBAcGFyYW0gbmV4dAorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBFbnRyeTxFLCBLLCBWPiBjcmVhdGVFbnRyeShpbnQgaGFzaENvZGUsIEUga2V5MSwgSyBrZXkyLCBWIHZhbHVlLAorICAgICAgICAgICAgRW50cnk8RSwgSywgVj4gbmV4dCkgeworICAgICAgICByZXR1cm4gbmV3IEVudHJ5PEUsIEssIFY+KGhhc2hDb2RlLCBrZXkxLCBrZXkyLCB2YWx1ZSwgbmV4dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBlbnRyaWVzIGl0ZXJhdG9yCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgSXRlcmF0b3I8TWFwLkVudHJ5PFN0cmluZywgVj4+IGNyZWF0ZUVudHJ5U2V0SXRlcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBuZXcgRW50cnlJdGVyYXRvckltcGwoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHZhbHVlcyBpdGVyYXRvcgorICAgICAqCisgICAgICogQHJldHVybgorICAgICAqLworICAgIEl0ZXJhdG9yPFY+IGNyZWF0ZVZhbHVlQ29sbGVjdGlvbkl0ZXJhdG9yKCkgeworICAgICAgICByZXR1cm4gbmV3IFZhbHVlSXRlcmF0b3JJbXBsKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW50cnkgaW1wbGVtZW50YXRpb24gZm9yIHRoZSBUd29LZXlIYXNoTWFwIGNsYXNzCisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEVudHJ5PEUsIEssIFY+IGltcGxlbWVudHMgTWFwLkVudHJ5PFN0cmluZywgVj4geworICAgICAgICBpbnQgaGFzaDsKKyAgICAgICAgRSBrZXkxOworICAgICAgICBLIGtleTI7CisgICAgICAgIFYgdmFsdWU7CisgICAgICAgIEVudHJ5PEUsIEssIFY+IG5leHQ7CisKKyAgICAgICAgcHVibGljIEVudHJ5KGludCBoYXNoLCBFIGtleTEsIEsga2V5MiwgViB2YWx1ZSwgRW50cnk8RSwgSywgVj4gbmV4dCkgeworICAgICAgICAgICAgdGhpcy5oYXNoID0gaGFzaDsKKyAgICAgICAgICAgIHRoaXMua2V5MSA9IGtleTE7CisgICAgICAgICAgICB0aGlzLmtleTIgPSBrZXkyOworICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgICAgICAgICAgdGhpcy5uZXh0ID0gbmV4dDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0S2V5KCkgeworICAgICAgICAgICAgcmV0dXJuIGtleTEudG9TdHJpbmcoKSArIGtleTIudG9TdHJpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFIGdldEtleTEoKSB7CisgICAgICAgICAgICByZXR1cm4ga2V5MTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBLIGdldEtleTIoKSB7CisgICAgICAgICAgICByZXR1cm4ga2V5MjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBWIGdldFZhbHVlKCkgeworICAgICAgICAgICAgcmV0dXJuIHZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFYgc2V0VmFsdWUoViB2YWx1ZSkgeworICAgICAgICAgICAgViBvbGRWYWx1ZSA9IHRoaXMudmFsdWU7CisgICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgICAgICAgICByZXR1cm4gb2xkVmFsdWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgRW50cnkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBFbnRyeTw/LCA/LCA/PiBlID0gKEVudHJ5PD8sID8sID8+KSBvYmo7CisgICAgICAgICAgICBPYmplY3QgZ2V0S2V5MSA9IGUuZ2V0S2V5MSgpOworICAgICAgICAgICAgT2JqZWN0IGdldEtleTIgPSBlLmdldEtleTIoKTsKKyAgICAgICAgICAgIE9iamVjdCBnZXRWYWx1ZSA9IGUuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgIGlmICgoa2V5MSA9PSBudWxsICYmIGdldEtleTEgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgfHwgKGtleTIgPT0gbnVsbCAmJiBnZXRLZXkyICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIHx8ICh2YWx1ZSA9PSBudWxsICYmIGdldFZhbHVlICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIHx8ICFrZXkxLmVxdWFscyhlLmdldEtleTEoKSkgfHwgIWtleTIuZXF1YWxzKGUuZ2V0S2V5MigpKQorICAgICAgICAgICAgICAgICAgICB8fCAhdmFsdWUuZXF1YWxzKGdldFZhbHVlKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgICAgIGludCBoYXNoMSA9IChrZXkxID09IG51bGwgPyAwIDoga2V5MS5oYXNoQ29kZSgpKTsKKyAgICAgICAgICAgIGludCBoYXNoMiA9IChrZXkyID09IG51bGwgPyAwIDoga2V5Mi5oYXNoQ29kZSgpKTsKKyAgICAgICAgICAgIHJldHVybiAoaGFzaDEgKyBoYXNoMikgXiAodmFsdWUgPT0gbnVsbCA/IDAgOiB2YWx1ZS5oYXNoQ29kZSgpKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgY2xhc3MgRW50cnlTZXRJbXBsIGV4dGVuZHMgQWJzdHJhY3RTZXQ8TWFwLkVudHJ5PFN0cmluZywgVj4+IHsKKyAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgcmV0dXJuIHNpemU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgICAgIFR3b0tleUhhc2hNYXAudGhpcy5jbGVhcigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgICAgIHJldHVybiBzaXplID09IDA7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3Qgb2JqKSB7CisgICAgICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBFbnRyeSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEVudHJ5PD8sID8sID8+IGVudHJ5ID0gKEVudHJ5PD8sID8sID8+KSBvYmo7CisgICAgICAgICAgICBFbnRyeTxFLCBLLCBWPiBlbnRyeTIgPSBmaW5kRW50cnkoZW50cnkuZ2V0S2V5MSgpLCBlbnRyeS5nZXRLZXkyKCkpOworICAgICAgICAgICAgaWYgKGVudHJ5MiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgIE9iamVjdCB2YWx1ZTIgPSBlbnRyeTIuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgIHJldHVybiB2YWx1ZSA9PSBudWxsID8gdmFsdWUyID09IG51bGwgOiB2YWx1ZS5lcXVhbHModmFsdWUyKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3Qgb2JqKSB7CisgICAgICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBFbnRyeSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVtb3ZlRW50cnkoKChFbnRyeSkgb2JqKS5nZXRLZXkxKCksICgoRW50cnkpIG9iaikuZ2V0S2V5MigpKSAhPSBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEl0ZXJhdG9yPE1hcC5FbnRyeTxTdHJpbmcsIFY+PiBpdGVyYXRvcigpIHsKKyAgICAgICAgICAgIHJldHVybiBjcmVhdGVFbnRyeVNldEl0ZXJhdG9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBJdGVyYXRlcyBFbnRyaWVzIGluc2lkZSB0aGUgTWFwCisgICAgY2xhc3MgRW50cnlJdGVyYXRvckltcGwgaW1wbGVtZW50cyBJdGVyYXRvcjxNYXAuRW50cnk8U3RyaW5nLCBWPj4geworICAgICAgICBwcml2YXRlIGludCBzdGFydE1vZENvdW50OworICAgICAgICBwcml2YXRlIGJvb2xlYW4gZm91bmQ7CisgICAgICAgIHByaXZhdGUgaW50IGN1cnIgPSAtMTsKKyAgICAgICAgcHJpdmF0ZSBpbnQgcmV0dXJuZWRfaW5kZXggPSAtMTsKKyAgICAgICAgcHJpdmF0ZSBFbnRyeTxFLCBLLCBWPiBjdXJyX2VudHJ5OworICAgICAgICBwcml2YXRlIEVudHJ5PEUsIEssIFY+IHJldHVybmVkX2VudHJ5OworCisgICAgICAgIEVudHJ5SXRlcmF0b3JJbXBsKCkgeworICAgICAgICAgICAgc3RhcnRNb2RDb3VudCA9IG1vZENvdW50OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIGlmIChmb3VuZCkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGN1cnJfZW50cnkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGN1cnJfZW50cnkgPSBjdXJyX2VudHJ5Lm5leHQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY3Vycl9lbnRyeSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgZm9yIChjdXJyKys7IGN1cnIgPCBhcnIubGVuZ3RoICYmIGFycltjdXJyXSA9PSBudWxsOyBjdXJyKyspIHsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoY3VyciA8IGFyci5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgY3Vycl9lbnRyeSA9IGFycltjdXJyXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZm91bmQgPSAoY3Vycl9lbnRyeSAhPSBudWxsKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBNYXAuRW50cnk8U3RyaW5nLCBWPiBuZXh0KCkgeworICAgICAgICAgICAgaWYgKG1vZENvdW50ICE9IHN0YXJ0TW9kQ291bnQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFoYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOworICAgICAgICAgICAgcmV0dXJuZWRfaW5kZXggPSBjdXJyOworICAgICAgICAgICAgcmV0dXJuZWRfZW50cnkgPSBjdXJyX2VudHJ5OworICAgICAgICAgICAgcmV0dXJuIChNYXAuRW50cnk8U3RyaW5nLCBWPikgY3Vycl9lbnRyeTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgIGlmIChyZXR1cm5lZF9pbmRleCA9PSAtMSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKG1vZENvdW50ICE9IHN0YXJ0TW9kQ291bnQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBFbnRyeTxFLCBLLCBWPiBwID0gbnVsbDsKKyAgICAgICAgICAgIEVudHJ5PEUsIEssIFY+IGUgPSBhcnJbcmV0dXJuZWRfaW5kZXhdOworICAgICAgICAgICAgd2hpbGUgKGUgIT0gcmV0dXJuZWRfZW50cnkpIHsKKyAgICAgICAgICAgICAgICBwID0gZTsKKyAgICAgICAgICAgICAgICBlID0gZS5uZXh0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHAgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHAubmV4dCA9IHJldHVybmVkX2VudHJ5Lm5leHQ7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFycltyZXR1cm5lZF9pbmRleF0gPSByZXR1cm5lZF9lbnRyeS5uZXh0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2l6ZS0tOworICAgICAgICAgICAgbW9kQ291bnQrKzsKKyAgICAgICAgICAgIHN0YXJ0TW9kQ291bnQrKzsKKyAgICAgICAgICAgIHJldHVybmVkX2luZGV4ID0gLTE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIEVudHJ5PEUsIEssIFY+IGZpbmRFbnRyeShPYmplY3Qga2V5MSwgT2JqZWN0IGtleTIpIHsKKyAgICAgICAgaWYgKGtleTEgPT0gbnVsbCAmJiBrZXkyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBhcnJbYXJyU2l6ZV07CisgICAgICAgIH0KKworICAgICAgICBpbnQgaGFzaCA9IGtleTEuaGFzaENvZGUoKSArIGtleTIuaGFzaENvZGUoKTsKKyAgICAgICAgaW50IGluZGV4ID0gKGhhc2ggJiAweDdmZmZmZmZmKSAlIGFyclNpemU7CisgICAgICAgIEVudHJ5PEUsIEssIFY+IGUgPSBhcnJbaW5kZXhdOworCisgICAgICAgIHdoaWxlIChlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChoYXNoID09IGUuaGFzaCAmJiBrZXkxLmVxdWFscyhlLmdldEtleTEoKSkKKyAgICAgICAgICAgICAgICAgICAgJiYga2V5Mi5lcXVhbHMoZS5nZXRLZXkyKCkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlID0gZS5uZXh0OworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8vIFJlbW92ZXMgZW50cnkKKyAgICBwcml2YXRlIGZpbmFsIEVudHJ5PEUsIEssIFY+IHJlbW92ZUVudHJ5KE9iamVjdCBrZXkxLCBPYmplY3Qga2V5MikgeworICAgICAgICBpZiAoa2V5MSA9PSBudWxsICYmIGtleTIgPT0gbnVsbCkgeworICAgICAgICAgICAgaW50IGluZGV4ID0gYXJyU2l6ZTsKKyAgICAgICAgICAgIGlmIChhcnJbaW5kZXhdICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBFbnRyeTxFLCBLLCBWPiByZXQgPSBhcnJbaW5kZXhdOworICAgICAgICAgICAgICAgIGFycltpbmRleF0gPSBudWxsOworICAgICAgICAgICAgICAgIHNpemUtLTsKKyAgICAgICAgICAgICAgICBtb2RDb3VudCsrOworICAgICAgICAgICAgICAgIHJldHVybiByZXQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIGludCBoYXNoID0ga2V5MS5oYXNoQ29kZSgpICsga2V5Mi5oYXNoQ29kZSgpOworICAgICAgICBpbnQgaW5kZXggPSAoaGFzaCAmIDB4N2ZmZmZmZmYpICUgYXJyU2l6ZTsKKworICAgICAgICBFbnRyeTxFLCBLLCBWPiBlID0gYXJyW2luZGV4XTsKKyAgICAgICAgRW50cnk8RSwgSywgVj4gcHJldiA9IGU7CisgICAgICAgIHdoaWxlIChlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChoYXNoID09IGUuaGFzaCAmJiBrZXkxLmVxdWFscyhlLmdldEtleTEoKSkKKyAgICAgICAgICAgICAgICAgICAgJiYga2V5Mi5lcXVhbHMoZS5nZXRLZXkyKCkpKSB7CisgICAgICAgICAgICAgICAgaWYgKHByZXYgPT0gZSkgeworICAgICAgICAgICAgICAgICAgICBhcnJbaW5kZXhdID0gZS5uZXh0OworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHByZXYubmV4dCA9IGUubmV4dDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc2l6ZS0tOworICAgICAgICAgICAgICAgIG1vZENvdW50Kys7CisgICAgICAgICAgICAgICAgcmV0dXJuIGU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHByZXYgPSBlOworICAgICAgICAgICAgZSA9IGUubmV4dDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbiBpbnN0YW5jZSBpcyByZXR1cm5lZCBieSB0aGUgdmFsdWVzKCkgY2FsbC4KKyAgICAgKi8KKyAgICBjbGFzcyBWYWx1ZXNDb2xsZWN0aW9uSW1wbCBleHRlbmRzIEFic3RyYWN0Q29sbGVjdGlvbjxWPiB7CisgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBzaXplOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgICAgICBUd29LZXlIYXNoTWFwLnRoaXMuY2xlYXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICByZXR1cm4gc2l6ZSA9PSAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEl0ZXJhdG9yPFY+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVZhbHVlQ29sbGVjdGlvbkl0ZXJhdG9yKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3Qgb2JqKSB7CisgICAgICAgICAgICByZXR1cm4gY29udGFpbnNWYWx1ZShvYmopOworICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgVmFsdWVJdGVyYXRvckltcGwgaW1wbGVtZW50cyBJdGVyYXRvcjxWPiB7CisgICAgICAgIHByaXZhdGUgRW50cnlJdGVyYXRvckltcGwgaXRyOworCisgICAgICAgIFZhbHVlSXRlcmF0b3JJbXBsKCkgeworICAgICAgICAgICAgdGhpcy5pdHIgPSBuZXcgRW50cnlJdGVyYXRvckltcGwoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBWIG5leHQoKSB7CisgICAgICAgICAgICByZXR1cm4gaXRyLm5leHQoKS5nZXRWYWx1ZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgeworICAgICAgICAgICAgaXRyLnJlbW92ZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiBpdHIuaGFzTmV4dCgpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9Qcml2YXRlS2V5SW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9Qcml2YXRlS2V5SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ3YWNlYjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L1ByaXZhdGVLZXlJbXBsLmphdmEKQEAgLTAsMCArMSw2NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKKworLyoqCisgKiBQcml2YXRlS2V5SW1wbAorICovCitwdWJsaWMgY2xhc3MgUHJpdmF0ZUtleUltcGwgaW1wbGVtZW50cyBQcml2YXRlS2V5IHsKKworICAgIC8qCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDc3NzY0OTc0ODI1MzM3OTAyNzlMOworCisgICAgcHJpdmF0ZSBTdHJpbmcgYWxnb3JpdGhtOworCisgICAgcHJpdmF0ZSBieXRlW10gZW5jb2Rpbmc7CisKKyAgICBwdWJsaWMgUHJpdmF0ZUtleUltcGwoU3RyaW5nIGFsZ29yaXRobSkgeworICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgcmV0dXJuIGFsZ29yaXRobTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgcmV0dXJuICJQS0NTIzgiOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKworICAgICAgICBieXRlW10gdG9SZXR1cm4gPSBuZXcgYnl0ZVtlbmNvZGluZy5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVuY29kaW5nLCAwLCB0b1JldHVybiwgMCwgZW5jb2RpbmcubGVuZ3RoKTsKKworICAgICAgICByZXR1cm4gdG9SZXR1cm47CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0QWxnb3JpdGhtKFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgdGhpcy5hbGdvcml0aG0gPSBhbGdvcml0aG07CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RW5jb2RpbmcoYnl0ZVtdIGVuY29kaW5nKSB7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBuZXcgYnl0ZVtlbmNvZGluZy5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVuY29kaW5nLCAwLCB0aGlzLmVuY29kaW5nLCAwLCBlbmNvZGluZy5sZW5ndGgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9QdWJsaWNLZXlJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L1B1YmxpY0tleUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kY2NjNzJkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9QdWJsaWNLZXlJbXBsLmphdmEKQEAgLTAsMCArMSw3MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworCisKKy8qKgorICogUHVibGljS2V5SW1wbAorICovCitwdWJsaWMgY2xhc3MgUHVibGljS2V5SW1wbCBpbXBsZW1lbnRzIFB1YmxpY0tleSB7CisKKyAgICAvKioKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzE3OTAyMjUxNjgxOTUzNDA3NUw7CisKKworICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kaW5nOworCisgICAgcHJpdmF0ZSBTdHJpbmcgYWxnb3JpdGhtOworCisKKyAgICBwdWJsaWMgUHVibGljS2V5SW1wbChTdHJpbmcgYWxnb3JpdGhtKSB7CisgICAgICAgIHRoaXMuYWxnb3JpdGhtID0gYWxnb3JpdGhtOworICAgIH0KKworCisgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiBhbGdvcml0aG07CisgICAgfQorCisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgcmV0dXJuICJYLjUwOSI7CisgICAgfQorCisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtlbmNvZGluZy5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVuY29kaW5nLCAwLCByZXN1bHQsIDAsIGVuY29kaW5nLmxlbmd0aCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCBzZXRBbGdvcml0aG0oU3RyaW5nIGFsZ29yaXRobSkgeworICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nKGJ5dGVbXSBlbmNvZGluZykgeworICAgICAgICB0aGlzLmVuY29kaW5nID0gbmV3IGJ5dGVbZW5jb2RpbmcubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShlbmNvZGluZywgMCwgdGhpcy5lbmNvZGluZywgMCwgZW5jb2RpbmcubGVuZ3RoKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvU3lzdGVtU2NvcGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvU3lzdGVtU2NvcGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OWNmNTZiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9TeXN0ZW1TY29wZS5qYXZhCkBAIC0wLDAgKzEsMTU4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGVrc2VpIFkuIFNlbWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LklkZW50aXR5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuSWRlbnRpdHlTY29wZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleU1hbmFnZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CisKKy8qKgorICogQHNlZSBqYXZhLnNlY3VyaXR5LklkZW50aXR5U2NvcGUKKyAqLworCitwdWJsaWMgY2xhc3MgU3lzdGVtU2NvcGUgZXh0ZW5kcyBJZGVudGl0eVNjb3BlIHsKKworICAgIC8qKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDgxMDI4NTY5NzkzMjUyMjYwN0w7CisKKyAgICAvLyBJZGVudGl0aWVzIGhhc2g6IGtleSBpcyB0aGUgaWRlbnRpdHkgbmFtZQorICAgIHByaXZhdGUgSGFzaHRhYmxlIG5hbWVzID0gbmV3IEhhc2h0YWJsZSgpOworCisgICAgLy8gSWRlbnRpdGllcyBoYXNoOiBrZXkgaXMgdGhlIHB1YmxpYyBrZXkKKyAgICBwcml2YXRlIEhhc2h0YWJsZSBrZXlzID0gbmV3IEhhc2h0YWJsZSgpOworCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LklkZW50aXR5U2NvcGUjSWRlbnRpdHlTY29wZSgpCisgICAgICovCisgICAgcHVibGljIFN5c3RlbVNjb3BlKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5JZGVudGl0eVNjb3BlI0lkZW50aXR5U2NvcGUoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBTeXN0ZW1TY29wZShTdHJpbmcgbmFtZSkgeworICAgICAgICBzdXBlcihuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuSWRlbnRpdHlTY29wZSNJZGVudGl0eVNjb3BlKFN0cmluZywgSWRlbnRpdHlTY29wZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3lzdGVtU2NvcGUoU3RyaW5nIG5hbWUsIElkZW50aXR5U2NvcGUgc2NvcGUpCisgICAgICAgICAgICB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKG5hbWUsIHNjb3BlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuSWRlbnRpdHlTY29wZSNzaXplKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgIHJldHVybiBuYW1lcy5zaXplKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LklkZW50aXR5U2NvcGUjZ2V0SWRlbnRpdHkoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIElkZW50aXR5IGdldElkZW50aXR5KFN0cmluZyBuYW1lKSB7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoSWRlbnRpdHkpIG5hbWVzLmdldChuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuSWRlbnRpdHlTY29wZSNnZXRJZGVudGl0eShqYXZhLnNlY3VyaXR5LlB1YmxpY0tleSkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIElkZW50aXR5IGdldElkZW50aXR5KFB1YmxpY0tleSBrZXkpIHsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKElkZW50aXR5KSBrZXlzLmdldChrZXkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5JZGVudGl0eVNjb3BlI2FkZElkZW50aXR5KGphdmEuc2VjdXJpdHkuSWRlbnRpdHkpCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFkZElkZW50aXR5KElkZW50aXR5IGlkZW50aXR5KSB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpZGVudGl0eSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImlkZW50aXR5ID09IG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBuYW1lID0gaWRlbnRpdHkuZ2V0TmFtZSgpOworICAgICAgICBpZiAobmFtZXMuY29udGFpbnNLZXkobmFtZSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uKCJuYW1lICciICsgbmFtZSArICInIGlzIGFscmVhZHkgdXNlZCIpOworICAgICAgICB9CisKKyAgICAgICAgUHVibGljS2V5IGtleSA9IGlkZW50aXR5LmdldFB1YmxpY0tleSgpOworICAgICAgICBpZiAoa2V5ICE9IG51bGwgJiYga2V5cy5jb250YWluc0tleShrZXkpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbigia2V5ICciICsga2V5ICsgIicgaXMgYWxyZWFkeSB1c2VkIik7CisgICAgICAgIH0KKworICAgICAgICBuYW1lcy5wdXQobmFtZSwgaWRlbnRpdHkpOworICAgICAgICBpZiAoa2V5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGtleXMucHV0KGtleSwgaWRlbnRpdHkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LklkZW50aXR5U2NvcGUjcmVtb3ZlSWRlbnRpdHkoamF2YS5zZWN1cml0eS5JZGVudGl0eSkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVtb3ZlSWRlbnRpdHkoSWRlbnRpdHkgaWRlbnRpdHkpCisgICAgICAgICAgICB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiB7CisKKyAgICAgICAgLy9FeGNlcHRpb24gY2F1Z2h0ID0gbnVsbDsKKyAgICAgICAgaWYgKGlkZW50aXR5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiaWRlbnRpdHkgPT0gbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBpZGVudGl0eS5nZXROYW1lKCk7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIGNvbnRhaW5zID0gbmFtZXMuY29udGFpbnNLZXkobmFtZSk7CisgICAgICAgIG5hbWVzLnJlbW92ZShuYW1lKTsKKworICAgICAgICBQdWJsaWNLZXkga2V5ID0gaWRlbnRpdHkuZ2V0UHVibGljS2V5KCk7CisKKyAgICAgICAgaWYgKGtleSAhPSBudWxsKSB7CisgICAgICAgICAgICBjb250YWlucyA9IGNvbnRhaW5zIHx8IGtleXMuY29udGFpbnNLZXkoa2V5KTsKKyAgICAgICAgICAgIGtleXMucmVtb3ZlKGtleSk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWNvbnRhaW5zKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbigiaWRlbnRpdHkgbm90IGZvdW5kIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuSWRlbnRpdHlTY29wZSNpZGVudGl0aWVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bWVyYXRpb24gaWRlbnRpdGllcygpIHsKKyAgICAgICAgcmV0dXJuIG5hbWVzLmVsZW1lbnRzKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFBbnkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xQW55LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDU1ZjJiZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xQW55LmphdmEKQEAgLTAsMCArMSwxMTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292LCBTdGVwYW4gTS4gTWlzaHVyYQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBBU04uMSBBTlkgdHlwZS4KKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9hc24xLmVsaWJlbC50bS5mci9lbi9zdGFuZGFyZHMvaW5kZXguaHRtIj5BU04uMTwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEFTTjFBbnkgZXh0ZW5kcyBBU04xVHlwZSB7CisKKyAgICAvKiogZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFTTjFBbnkgQVNOMT0gbmV3IEFTTjFBbnkoKTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgQVNOLjEgQU5ZIHR5cGUKKyAgICAgKgorICAgICAqIFRoZSBjb25zdHJ1Y3RvciBpcyBwcm92aWRlZCBmb3IgaW5oZXJpdGFuY2UgcHVycG9zZXMKKyAgICAgKiB3aGVuIHRoZXJlIGlzIGEgbmVlZCB0byBjcmVhdGUgYSBjdXN0b20gQVNOLjEgQU5ZIHR5cGUuCisgICAgICogVG8gZ2V0IGEgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpdCBpcyByZWNvbW1lbmRlZCB0byB1c2UKKyAgICAgKiBnZXRJbnN0YW5jZSgpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQVNOMUFueSgpIHsKKyAgICAgICAgc3VwZXIoVEFHX0FOWSk7IC8vIGhhcyBub3QgdGFnIG51bWJlcgorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgQVNOLjEgQU5ZIHR5cGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gd29ya3Mgd2l0aCBmdWxsIGVuY29kaW5nCisgICAgICogdGhhdCBpcyByZXByZXNlbnRlZCBhcyByYXcgYnl0ZSBhcnJheS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQVNOLjEgQU5ZIHR5cGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQVNOMUFueSBnZXRJbnN0YW5jZSgpIHsKKyAgICAgICAgcmV0dXJuIEFTTjE7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgcHJvdmlkZWQgaWRlbnRpZmllci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpZGVudGlmaWVyIC0gaWRlbnRpZmllciB0byBiZSB2ZXJpZmllZAorICAgICAqIEByZXR1cm4gLSB0cnVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gY2hlY2tUYWcoaW50IGlkZW50aWZpZXIpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7IC8vYWxsIHRhZ3MgYXJlIE9LCisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBkZWNvZGUoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIG9ubHkgcmVhZCBjb250ZW50LCBkb2Vzbid0IGNoZWNrIGl0CisgICAgICAgIGluLnJlYWRDb250ZW50KCk7CisKKyAgICAgICAgaWYgKGluLmlzVmVyaWZ5KSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0RGVjb2RlZE9iamVjdChpbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXh0cmFjdHMgYXJyYXkgb2YgYnl0ZXMgdGhhdCByZXByZXNlbnRzIGZ1bGwgZW5jb2RpbmcgZnJvbSBCRVIgaW5wdXQKKyAgICAgKiBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4gQkVSIGlucHV0IHN0cmVhbQorICAgICAqIEByZXR1cm4gYXJyYXkgb2YgYnl0ZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBieXRlc0VuY29kZWQgPSBuZXcgYnl0ZVtpbi5vZmZzZXQgLSBpbi50YWdPZmZzZXRdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGluLmJ1ZmZlciwgaW4udGFnT2Zmc2V0LCBieXRlc0VuY29kZWQsIDAsCisgICAgICAgICAgICAgICAgYnl0ZXNFbmNvZGVkLmxlbmd0aCk7CisgICAgICAgIHJldHVybiBieXRlc0VuY29kZWQ7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5jb2RlQVNOKEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LmVuY29kZUFOWSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVuY29kZUNvbnRlbnQoQmVyT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgICBvdXQuZW5jb2RlQU5ZKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RW5jb2RpbmdDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0Lmxlbmd0aCA9ICgoYnl0ZVtdKSBvdXQuY29udGVudCkubGVuZ3RoOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0RW5jb2RlZExlbmd0aChCZXJPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIHJldHVybiBvdXQubGVuZ3RoOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xQml0U3RyaW5nLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMUJpdFN0cmluZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmExYWM3YjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMUJpdFN0cmluZy5qYXZhCkBAIC0wLDAgKzEsMTk2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdiwgU3RlcGFuIE0uIE1pc2h1cmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgbGliY29yZS51dGlsLkVtcHR5QXJyYXk7CisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIEFTTi4xIEJpdHN0cmluZyB0eXBlLgorICoKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2FzbjEuZWxpYmVsLnRtLmZyL2VuL3N0YW5kYXJkcy9pbmRleC5odG0iPkFTTi4xPC9hPgorICovCitwdWJsaWMgY2xhc3MgQVNOMUJpdFN0cmluZyBleHRlbmRzIEFTTjFTdHJpbmdUeXBlIHsKKworICAgIC8vIGRlZmF1bHQgaW1wbGVtZW50YXRpb24KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBBU04xQml0U3RyaW5nIEFTTjEgPSBuZXcgQVNOMUJpdFN0cmluZygpOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBBU04uMSBCaXRzdHJpbmcgdHlwZQorICAgICAqCisgICAgICogVGhlIGNvbnN0cnVjdG9yIGlzIHByb3ZpZGVkIGZvciBpbmhlcml0YW5jZSBwdXJwb3NlcworICAgICAqIHdoZW4gdGhlcmUgaXMgYSBuZWVkIHRvIGNyZWF0ZSBhIGN1c3RvbSBBU04uMSBCaXRzdHJpbmcgdHlwZS4KKyAgICAgKiBUbyBnZXQgYSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGl0IGlzIHJlY29tbWVuZGVkIHRvIHVzZQorICAgICAqIGdldEluc3RhbmNlKCkgbWV0aG9kLgorICAgICAqLworICAgIHB1YmxpYyBBU04xQml0U3RyaW5nKCkgeworICAgICAgICBzdXBlcihUQUdfQklUU1RSSU5HKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFTTi4xIEJpdHN0cmluZyB0eXBlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24KKyAgICAgKgorICAgICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHdvcmtzIHdpdGggZW5jb2RpbmcKKyAgICAgKiB0aGF0IGlzIHJlcHJlc2VudGVkIGFzIEJpdFN0cmluZyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFTTi4xIEJpdHN0cmluZyB0eXBlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24KKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJpdFN0cmluZworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQVNOMUJpdFN0cmluZyBnZXRJbnN0YW5jZSgpIHsKKyAgICAgICAgcmV0dXJuIEFTTjE7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZGVjb2RlKEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbi5yZWFkQml0U3RyaW5nKCk7CisKKyAgICAgICAgaWYgKGluLmlzVmVyaWZ5KSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0RGVjb2RlZE9iamVjdChpbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXh0cmFjdHMgQml0U3RyaW5nIG9iamVjdCBmcm9tIEJFUiBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4gLSBCRVIgaW5wdXQgc3RyZWFtCisgICAgICogQHJldHVybiBCaXRTdHJpbmcgb2JqZWN0CisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbaW4ubGVuZ3RoIC0gMV07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoaW4uYnVmZmVyLCBpbi5jb250ZW50T2Zmc2V0ICsgMSwgYnl0ZXMsIDAsCisgICAgICAgICAgICAgICAgaW4ubGVuZ3RoIC0gMSk7CisgICAgICAgIHJldHVybiBuZXcgQml0U3RyaW5nKGJ5dGVzLCBpbi5idWZmZXJbaW4uY29udGVudE9mZnNldF0pOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBlbmNvZGVDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LmVuY29kZUJpdFN0cmluZygpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZ0NvbnRlbnQoQmVyT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgICBvdXQubGVuZ3RoID0gKChCaXRTdHJpbmcpIG91dC5jb250ZW50KS5ieXRlcy5sZW5ndGggKyAxOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIEFTTi4xIE5hbWVkIEJpdHN0cmluZyB0eXBlCisgICAgICoKKyAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB3b3JrcyB3aXRoIGVuY29kaW5nCisgICAgICogdGhhdCBpcyBtYXBwZWQgdG8gYXJyYXkgb2YgYm9vbGVhbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEFTTjFOYW1lZEJpdExpc3QgZXh0ZW5kcyBBU04xQml0U3RyaW5nIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIFNFVF9NQVNLID0geyAoYnl0ZSkgMTI4LCA2NCwgMzIsIDE2LCA4LCA0LCAyLCAxfTsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQml0U3RyaW5nIGVtcHR5U3RyaW5nID0gbmV3IEJpdFN0cmluZyhFbXB0eUFycmF5LkJZVEUsIDApOworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5ERUZJTklURV9TSVpFID0gLTE7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbWluQml0czsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbWF4Qml0czsKKworICAgICAgICBwdWJsaWMgQVNOMU5hbWVkQml0TGlzdChpbnQgbWluQml0cykgeworICAgICAgICAgICAgdGhpcy5taW5CaXRzID0gbWluQml0czsKKyAgICAgICAgICAgIHRoaXMubWF4Qml0cyA9IElOREVGSU5JVEVfU0laRTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBib29sZWFuW10gdmFsdWU7CisKKyAgICAgICAgICAgIGludCB1bnVzZWRCaXRzID0gaW4uYnVmZmVyW2luLmNvbnRlbnRPZmZzZXRdOworICAgICAgICAgICAgaW50IGJpdHNOdW1iZXIgPSAoaW4ubGVuZ3RoIC0gMSkgKiA4IC0gdW51c2VkQml0czsKKworICAgICAgICAgICAgaWYgKG1heEJpdHMgPT0gSU5ERUZJTklURV9TSVpFKSB7CisgICAgICAgICAgICAgICAgaWYgKG1pbkJpdHMgPT0gSU5ERUZJTklURV9TSVpFKSB7CisgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gbmV3IGJvb2xlYW5bYml0c051bWJlcl07CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGJpdHNOdW1iZXIgPiBtaW5CaXRzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IG5ldyBib29sZWFuW2JpdHNOdW1iZXJdOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBuZXcgYm9vbGVhblttaW5CaXRzXTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKGJpdHNOdW1iZXIgPiBtYXhCaXRzKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJBU04uMSBOYW1lZCBCaXRzdHJpbmc6IHNpemUgY29uc3RyYWludHMiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdmFsdWUgPSBuZXcgYm9vbGVhblttYXhCaXRzXTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGJpdHNOdW1iZXIgPT0gMCkgeworICAgICAgICAgICAgICAgIC8vIGVtcHR5IGJpdCBzdHJpbmcKKyAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGludCBpID0gMTsKKyAgICAgICAgICAgIGludCBqID0gMDsKKyAgICAgICAgICAgIGJ5dGUgb2N0ZXQgPSBpbi5idWZmZXJbaW4uY29udGVudE9mZnNldCArIGldOworICAgICAgICAgICAgZm9yIChpbnQgc2l6ZSA9IGluLmxlbmd0aCAtIDE7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IDg7IGsrKywgaisrKSB7CisgICAgICAgICAgICAgICAgICAgIHZhbHVlW2pdID0gKFNFVF9NQVNLW2tdICYgb2N0ZXQpICE9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgICAgICBvY3RldCA9IGluLmJ1ZmZlcltpbi5jb250ZW50T2Zmc2V0ICsgaV07CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGZpbmFsIG9jdGV0CisgICAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8ICg4IC0gdW51c2VkQml0cyk7IGsrKywgaisrKSB7CisgICAgICAgICAgICAgICAgdmFsdWVbal0gPSAoU0VUX01BU0tba10gJiBvY3RldCkgIT0gMDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIHZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nQ29udGVudChCZXJPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgICAgICBib29sZWFuW10gdG9FbmNvZGUgPSAoYm9vbGVhbltdKSBvdXQuY29udGVudDsKKworICAgICAgICAgICAgaW50IGluZGV4ID0gdG9FbmNvZGUubGVuZ3RoIC0gMTsKKyAgICAgICAgICAgIHdoaWxlIChpbmRleCA+IC0xICYmICF0b0VuY29kZVtpbmRleF0pIHsKKyAgICAgICAgICAgICAgICBpbmRleC0tOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoaW5kZXggPT0gLTEpIHsKKyAgICAgICAgICAgICAgICBvdXQuY29udGVudCA9IGVtcHR5U3RyaW5nOworICAgICAgICAgICAgICAgIG91dC5sZW5ndGggPSAxOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpbnQgdW51c2VkQml0cyA9IDcgLSBpbmRleCAlIDg7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbaW5kZXggLyA4ICsgMV07CisKKyAgICAgICAgICAgICAgICBpbnQgaiA9IDA7CisgICAgICAgICAgICAgICAgaW5kZXggPSBieXRlcy5sZW5ndGggLSAxOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5kZXg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IDg7IGsrKywgaisrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAodG9FbmNvZGVbal0pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlc1tpXSA9IChieXRlKSAoYnl0ZXNbaV0gfCBTRVRfTUFTS1trXSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvL2ZpbmFsIG9jdGV0CisgICAgICAgICAgICAgICAgZm9yIChpbnQgayA9IDA7IGsgPCAoOCAtIHVudXNlZEJpdHMpOyBrKyssIGorKykgeworICAgICAgICAgICAgICAgICAgICBpZiAodG9FbmNvZGVbal0pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzW2luZGV4XSA9IChieXRlKSAoYnl0ZXNbaW5kZXhdIHwgU0VUX01BU0tba10pOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgb3V0LmNvbnRlbnQgPSBuZXcgQml0U3RyaW5nKGJ5dGVzLCB1bnVzZWRCaXRzKTsKKyAgICAgICAgICAgICAgICBvdXQubGVuZ3RoID0gYnl0ZXMubGVuZ3RoICsgMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xQm9vbGVhbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFCb29sZWFuLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTlkMmE2NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xQm9vbGVhbi5qYXZhCkBAIC0wLDAgKzEsOTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292LCBTdGVwYW4gTS4gTWlzaHVyYQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBBU04uMSBCb29sZWFuIHR5cGUuCisgKgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vYXNuMS5lbGliZWwudG0uZnIvZW4vc3RhbmRhcmRzL2luZGV4Lmh0bSI+QVNOLjE8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBBU04xQm9vbGVhbiBleHRlbmRzIEFTTjFQcmltaXRpdmUgeworCisgICAgLyoqIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBBU04xQm9vbGVhbiBBU04xID0gbmV3IEFTTjFCb29sZWFuKCk7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIEFTTi4xIEJvb2xlYW4gdHlwZQorICAgICAqCisgICAgICogVGhlIGNvbnN0cnVjdG9yIGlzIHByb3ZpZGVkIGZvciBpbmhlcml0YW5jZSBwdXJwb3NlcworICAgICAqIHdoZW4gdGhlcmUgaXMgYSBuZWVkIHRvIGNyZWF0ZSBhIGN1c3RvbSBBU04uMSBCb29sZWFuIHR5cGUuCisgICAgICogVG8gZ2V0IGEgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpdCBpcyByZWNvbW1lbmRlZCB0byB1c2UKKyAgICAgKiBnZXRJbnN0YW5jZSgpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQVNOMUJvb2xlYW4oKSB7CisgICAgICAgIHN1cGVyKFRBR19CT09MRUFOKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFTTi4xIEJvb2xlYW4gdHlwZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uCisgICAgICoKKyAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB3b3JrcyB3aXRoIGVuY29kaW5nCisgICAgICogdGhhdCBpcyByZXByZXNlbnRlZCBhcyBCb29sZWFuIG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQVNOLjEgQm9vbGVhbiB0eXBlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEFTTjFCb29sZWFuIGdldEluc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gQVNOMTsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGRlY29kZShCZXJJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW4ucmVhZEJvb2xlYW4oKTsKKworICAgICAgICBpZiAoaW4uaXNWZXJpZnkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXREZWNvZGVkT2JqZWN0KGluKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHRyYWN0cyBCb29sZWFuIG9iamVjdCBmcm9tIEJFUiBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4gLSBCRVIgaW5wdXQgc3RyZWFtCisgICAgICogQHJldHVybiBqYXZhLmxhbmcuQm9vbGVhbiBvYmplY3QKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaW4uYnVmZmVyW2luLmNvbnRlbnRPZmZzZXRdID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBCb29sZWFuLkZBTFNFOworICAgICAgICB9CisgICAgICAgIHJldHVybiBCb29sZWFuLlRSVUU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5jb2RlQ29udGVudChCZXJPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIG91dC5lbmNvZGVCb29sZWFuKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RW5jb2RpbmdDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0Lmxlbmd0aCA9IDE7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFDaG9pY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xQ2hvaWNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTBlYTQ4YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xQ2hvaWNlLmphdmEKQEAgLTAsMCArMSwzMzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdiwgU3RlcGFuIE0uIE1pc2h1cmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKKworCisvKioKKyAqIFRoaXMgYWJzdHJhY3QgY2xhc3MgcmVwcmVzZW50cyBBU04uMSBDaG9pY2UgdHlwZS4KKyAqCisgKiBUbyBpbXBsZW1lbnQgY3VzdG9tIEFTTi4xIGNob2ljZSB0eXBlIGFuIGFwcGxpY2F0aW9uIGNsYXNzCisgKiBtdXN0IHByb3ZpZGUgaW1wbGVtZW50YXRpb24gZm9yIHRoZSBmb2xsb3dpbmcgbWV0aG9kczoKKyAqICAgICBnZXRJbmRleCgpCisgKiAgICAgZ2V0T2JqZWN0VG9FbmNvZGUoKQorICoKKyAqIFRoZXJlIGFyZSB0d28gd2F5cyB0byBpbXBsZW1lbnQgY3VzdG9tIEFTTi4xIGNob2ljZSB0eXBlOgorICogd2l0aCBhcHBsaWNhdGlvbiBjbGFzcyB0aGF0IHJlcHJlc2VudHMgQVNOLjEgY3VzdG9tIGNob2ljZSB0eXBlIG9yIHdpdGhvdXQuCisgKiBUaGUga2V5IHBvaW50IGlzIGhvdyBhIHZhbHVlIG9mIGNob2ljZSB0eXBlIGlzIHN0b3JlZCBieSBhcHBsaWNhdGlvbiBjbGFzc2VzLgorICoKKyAqIEZvciBleGFtcGxlLCBsZXQncyBjb25zaWRlciB0aGUgZm9sbG93aW5nIEFTTi4xIG5vdGF0aW9ucworICogKHNlZSBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCkKKyAqCisgKiBUaW1lIDo6PSBDSE9JQ0UgeworICogICAgICAgdXRjVGltZSAgICAgICAgVVRDVGltZSwKKyAqICAgICAgIGdlbmVyYWxUaW1lICAgIEdlbmVyYWxpemVkVGltZQorICogfQorICoKKyAqIFZhbGlkaXR5IDo6PSBTRVFVRU5DRSB7CisgKiAgICAgICBub3RCZWZvcmUgICAgICBUaW1lLAorICogICAgICAgbm90QWZ0ZXIgICAgICAgVGltZQorICogIH0KKyAqCisgKiAxKUZpcnN0IGFwcHJvYWNoOgorICogTm8gYXBwbGljYXRpb24gY2xhc3MgdG8gcmVwcmVzZW50IEFTTi4xIFRpbWUgbm90YXRpb24KKyAqCisgKiBUaGUgVGltZSBub3RhdGlvbiBpcyBhIGNob2ljZSBvZiBkaWZmZXJlbnQgdGltZSBmb3JtYXRzOiBVVEMgYW5kIEdlbmVyYWxpemVkLgorICogQm90aCBvZiB0aGVtIGFyZSBtYXBwZWQgdG8gamF2YS51dGlsLkRhdGUgb2JqZWN0LCBzbyBhbiBhcHBsaWNhdGlvbgorICogY2xhc3MgdGhhdCByZXByZXNlbnRzIEFTTi4xIFZhbGlkaXR5IG5vdGF0aW9uIG1heSBrZWVwIHZhbHVlcworICogYXMgRGF0ZSBvYmplY3RzLgorICoKKyAqIFNvIGEgY3VzdG9tIEFTTi4xIFRpbWUgY2hvaWNlIHR5cGUgc2hvdWxkIG1hcCBpdHMgbm90YXRpb24gdG8gRGF0ZSBvYmplY3QuCisgKgorICogY2xhc3MgVGltZSB7CisgKgorICogICAgIC8vIGN1c3RvbSBBU04uMSBjaG9pY2UgY2xhc3M6IG1hcHMgVGltZSB0byBpcyBub3RhdGlvbgorICogICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMUNob2ljZSBhc24xID0gbmV3IEFTTjFDaG9pY2UobmV3IEFTTjFUeXBlW10geworICogICAgICAgICBBU04xR2VuZXJhbGl6ZWRUaW1lLmFzbjEsIEFTTjFVVENUaW1lLmFzbjEgfSkgeworICoKKyAqICAgICAgICAgcHVibGljIGludCBnZXRJbmRleChqYXZhLmxhbmcuT2JqZWN0IG9iamVjdCkgeworICogICAgICAgICAgICAgcmV0dXJuIDA7IC8vIGFsd2F5cyBlbmNvZGUgYXMgQVNOMUdlbmVyYWxpemVkVGltZQorICogICAgICAgICB9CisgKgorICogICAgICAgICBwdWJsaWMgT2JqZWN0IGdldE9iamVjdFRvRW5jb2RlKE9iamVjdCBvYmplY3QpIHsKKyAqCisgKiAgICAgICAgICAgICAvLyBBIHZhbHVlIHRvIGJlIGVuY29kZWQgdmFsdWUgaXMgYSBEYXRlIG9iamVjdAorICogICAgICAgICAgICAgLy8gcGFzcyBpdCB0byBjdXN0b20gdGltZSBjbGFzcworICogICAgICAgICAgICAgcmV0dXJuIG9iamVjdDsKKyAqICAgICAgICAgfQorICogICAgIH07CisgKiB9CisgKgorICogY2xhc3MgVmFsaWRpdHkgeworICoKKyAqICAgICBwcml2YXRlIERhdGUgbm90QmVmb3JlOyAgICAvLyBjaG9pY2UgYXMgRGF0ZQorICogICAgIHByaXZhdGUgRGF0ZSBub3RBZnRlcjsgICAgIC8vIGNob2ljZSBhcyBEYXRlCisgKgorICogICAgIC4uLiAvLyBjb25zdHJ1Y3RvcnMgYW5kIG90aGVyIG1ldGhvZHMgZ28gaGVyZQorICoKKyAqICAgICAvLyBjdXN0b20gQVNOLjEgc2VxdWVuY2UgY2xhc3M6IG1hcHMgVmFsaWRpdHkgY2xhc3MgdG8gaXMgbm90YXRpb24KKyAqICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBBU04xCisgKiAgICAgICAgID0gbmV3IEFTTjFTZXF1ZW5jZShuZXcgQVNOMVR5cGVbXSB7VGltZS5hc24xLCBUaW1lLmFzbjEgfSkgeworICoKKyAqICAgICAgICAgcHJvdGVjdGVkIE9iamVjdCBnZXRPYmplY3QoT2JqZWN0W10gdmFsdWVzKSB7CisgKgorICogICAgICAgICAgICAgLy8gQVNOLjEgVGltZSBjaG9pY2UgcGFzc2VkIERhdGEgb2JqZWN0IC0gdXNlIGl0CisgKiAgICAgICAgICAgICByZXR1cm4gbmV3IFZhbGlkaXR5KChEYXRlKSB2YWx1ZXNbMF0sIChEYXRlKSB2YWx1ZXNbMV0pOworICogICAgICAgICB9CisgKgorICogICAgICAgICBwcm90ZWN0ZWQgdm9pZCBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCwgT2JqZWN0W10gdmFsdWVzKSB7CisgKgorICogICAgICAgICAgICAgVmFsaWRpdHkgdmFsaWRpdHkgPSAoVmFsaWRpdHkpIG9iamVjdDsKKyAqCisgKiAgICAgICAgICAgICAvLyBwYXNzIERhdGUgb2JqZWN0cyB0byBBU04uMSBUaW1lIGNob2ljZQorICogICAgICAgICAgICAgdmFsdWVzWzBdID0gdmFsaWRpdHkubm90QmVmb3JlOworICogICAgICAgICAgICAgdmFsdWVzWzFdID0gdmFsaWRpdHkubm90QWZ0ZXI7CisgKiAgICAgICAgIH0KKyAqICAgICB9CisgKiB9CisgKgorICogMilTZWNvbmQgYXBwcm9hY2g6CisgKiBUaGVyZSBpcyBhbiBhcHBsaWNhdGlvbiBjbGFzcyB0byByZXByZXNlbnQgQVNOLjEgVGltZSBub3RhdGlvbgorICoKKyAqIElmIGl0IGlzIGEgbWF0dGVyIHdoYXQgdGltZSBmb3JtYXQgc2hvdWxkIGJlIHVzZWQgdG8gZGVjb2RlL2VuY29kZQorICogRGF0ZSBvYmplY3RzIGEgY2xhc3MgdG8gcmVwcmVzZW50IEFTTi4xIFRpbWUgbm90YXRpb24gbXVzdCBiZSBjcmVhdGVkLgorICoKKyAqIEZvciBleGFtcGxlLAorICoKKyAqIGNsYXNzIFRpbWUgeworICoKKyAqICAgICBwcml2YXRlIERhdGUgdXRjVGltZTsKKyAqICAgICBwcml2YXRlIERhdGUgZ1RpbWU7CisgKgorICogICAgIC4uLiAvLyBjb25zdHJ1Y3RvcnMgYW5kIG90aGVyIG1ldGhvZHMgZ28gaGVyZQorICoKKyAqICAgICAvLyBjdXN0b20gQVNOLjEgY2hvaWNlIGNsYXNzOiBtYXBzIFRpbWUgdG8gaXMgbm90YXRpb24KKyAqICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFDaG9pY2UgYXNuMSA9IG5ldyBBU04xQ2hvaWNlKG5ldyBBU04xVHlwZVtdIHsKKyAqICAgICAgICAgQVNOMUdlbmVyYWxpemVkVGltZS5hc24xLCBBU04xVVRDVGltZS5hc24xIH0pIHsKKyAqCisgKiAgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICoKKyAqICAgICAgICAgICAgIC8vIGNyZWF0ZSBUaW1lIG9iamVjdCB0byBwYXNzIGFzIGRlY29kZWQgdmFsdWUKKyAqICAgICAgICAgICAgIFRpbWUgdGltZSA9IG5ldyBUaW1lKCk7CisgKgorICogICAgICAgICAgICAgaWYgKGluLmNob2ljZUluZGV4PT0wKSB7CisgKiAgICAgICAgICAgICAgICAgLy8gd2UgZGVjb2RlZCBHZW5lcmFsaXplZFRpbWUKKyAqICAgICAgICAgICAgICAgICAvLyBzdG9yZSBkZWNvZGVkIERhdGUgdmFsdWUgaW4gY29ycmVzcG9uZGluZyBmaWVsZAorICogICAgICAgICAgICAgICAgIHRpbWUuZ1RpbWUgPSBpbi5jb250ZW50OworICogICAgICAgICAgICAgICAgIC8vIHJldHVybiBpdAorICogICAgICAgICAgICAgICAgIHJldHVybiB0aW1lOworICogICAgICAgICAgICAgfSBlbHNlIHsKKyAqICAgICAgICAgICAgICAgICAvLyB3ZSBkZWNvZGVkIFVUQ1RpbWUKKyAqICAgICAgICAgICAgICAgICAvLyBzdG9yZSBkZWNvZGVkIERhdGUgdmFsdWUgaW4gY29ycmVzcG9uZGluZyBmaWVsZAorICogICAgICAgICAgICAgICAgIHRpbWUudXRjVGltZSA9IGluLmNvbnRlbnQ7CisgKiAgICAgICAgICAgICAgICAgLy8gcmV0dXJuIGl0CisgKiAgICAgICAgICAgICAgICAgcmV0dXJuIHRpbWU7CisgKiAgICAgICAgICAgICB9CisgKiAgICAgICAgIH0KKyAqCisgKiAgICAgICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXgoamF2YS5sYW5nLk9iamVjdCBvYmplY3QpIHsKKyAqICAgICAgICAgICAgIFRpbWUgdGltZSA9IChUaW1lKW9iamVjdDsKKyAqICAgICAgICAgICAgIGlmKHRpbWUudXRjVGltZSE9bnVsbCl7CisgKiAgICAgICAgICAgICAgICAgLy8gZW5jb2RlIERhdGUgYXMgVVRDVGltZQorICogICAgICAgICAgICAgICAgIHJldHVybiAxOworICogICAgICAgICAgICAgfSBlbHNlIHsKKyAqICAgICAgICAgICAgICAgICAvLyBvdGhlcndpc2UgZW5jb2RlIERhdGUgYXMgR2VuZXJhbGl6ZWRUaW1lCisgKiAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgKiAgICAgICAgICAgICB9CisgKiAgICAgICAgIH0KKyAqCisgKiAgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0T2JqZWN0VG9FbmNvZGUoT2JqZWN0IG9iamVjdCkgeworICogICAgICAgICAgICAgVGltZSB0aW1lID0gKFRpbWUpb2JqZWN0OworICogICAgICAgICAgICAgaWYodGltZS51dGNUaW1lIT1udWxsKXsKKyAqICAgICAgICAgICAgICAgICAvLyBlbmNvZGUgRGF0ZSBhcyBVVENUaW1lCisgKiAgICAgICAgICAgICAgICAgcmV0dXJuIDE7CisgKiAgICAgICAgICAgICB9IGVsc2UgeworICogICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSBlbmNvZGUgRGF0ZSBhcyBHZW5lcmFsaXplZFRpbWUKKyAqICAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAqICAgICAgICAgICAgIH0KKyAqICAgICAgICAgfQorICogICAgIH07CisgKiB9CisgKgorICogU28gbm93IFZhbGlkaXR5IGNsYXNzIG11c3Qga2VlcCBhbGwgdmFsdWVzIGluIFRpbWUgb2JqZWN0CisgKiBhbmQgaXRzIGN1c3RvbSBBU04uMSBzZXF1ZW5jZSBjbGFzcyBtdXN0IGhhbmRsZSB0aGlzIGNsYXNzIG9mIG9iamVjdHMKKyAqCisgKiBjbGFzcyBWYWxpZGl0eSB7CisgKgorICogICAgIHByaXZhdGUgVGltZSBub3RCZWZvcmU7ICAgIC8vIG5vdyBpdCBpcyBhIFRpbWUhISEKKyAqICAgICBwcml2YXRlIFRpbWUgbm90QWZ0ZXI7ICAgICAvLyBub3cgaXQgaXMgYSBUaW1lISEhCisgKgorICogICAgIC4uLiAvLyBjb25zdHJ1Y3RvcnMgYW5kIG90aGVyIG1ldGhvZHMgZ28gaGVyZQorICoKKyAqICAgICAvLyBjdXN0b20gQVNOLjEgc2VxdWVuY2UgY2xhc3M6IG1hcHMgVmFsaWRpdHkgY2xhc3MgdG8gaXMgbm90YXRpb24KKyAqICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBBU04xCisgKiAgICAgICAgID0gbmV3IEFTTjFTZXF1ZW5jZShuZXcgQVNOMVR5cGVbXSB7VGltZS5hc24xLCBUaW1lLmFzbjEgfSkgeworICoKKyAqICAgICAgICAgcHJvdGVjdGVkIE9iamVjdCBnZXRPYmplY3QoT2JqZWN0W10gdmFsdWVzKSB7CisgKgorICogICAgICAgICAgICAgLy8gV2UndmUgZ290dGVuIFRpbWUgb2JqZWN0cyBoZXJlICEhIQorICogICAgICAgICAgICAgcmV0dXJuIG5ldyBWYWxpZGl0eSgoVGltZSkgdmFsdWVzWzBdLCAoVGltZSkgdmFsdWVzWzFdKTsKKyAqICAgICAgICAgfQorICoKKyAqICAgICAgICAgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykgeworICoKKyAqICAgICAgICAgICAgIFZhbGlkaXR5IHZhbGlkaXR5ID0gKFZhbGlkaXR5KSBvYmplY3Q7CisgKgorICogICAgICAgICAgICAgLy8gcGFzcyBUaW1lIG9iamVjdHMgdG8gQVNOLjEgVGltZSBjaG9pY2UKKyAqICAgICAgICAgICAgIHZhbHVlc1swXSA9IHZhbGlkaXR5Lm5vdEJlZm9yZTsKKyAqICAgICAgICAgICAgIHZhbHVlc1sxXSA9IHZhbGlkaXR5Lm5vdEFmdGVyOworICogICAgICAgICB9CisgKiAgICAgfQorICogfQorICoKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2FzbjEuZWxpYmVsLnRtLmZyL2VuL3N0YW5kYXJkcy9pbmRleC5odG0iPkFTTi4xPC9hPgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQVNOMUNob2ljZSBleHRlbmRzIEFTTjFUeXBlIHsKKyAgICBwdWJsaWMgZmluYWwgQVNOMVR5cGVbXSB0eXBlOworCisgICAgLyoqCisgICAgICogaWRlbnRpZmllcnMgdGFibGU6IFsyXVtudW1iZXIgb2YgZGlzdGluY3QgaWRlbnRpZmllcnNdCisgICAgICogaWRlbnRpZmllcnNbMF06IHN0b3JlcyBpZGVudGlmaWVycyAoaW5jbHVkZXMgbmVzdGVkIGNob2ljZXMpCisgICAgICogaWRlbnRpZmllcnNbMV06IHN0b3JlcyBpZGVudGlmaWVycycgaW5kZXhlcyBpbiBhcnJheSBvZiB0eXBlcworICAgICAqLworICAgIHByaXZhdGUgZmluYWwgaW50W11bXSBpZGVudGlmaWVyczsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgQVNOLjEgY2hvaWNlIHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZSAtCisgICAgICogICAgICAgICAgICBhbiBhcnJheSBvZiBvbmUgb3IgbW9yZSBBU04uMSB0eXBlIGFsdGVybmF0aXZlcy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAtCisgICAgICogICAgICAgICAgICAgdHlwZSBwYXJhbWV0ZXIgaXMgaW52YWxpZAorICAgICAqLworICAgIHB1YmxpYyBBU04xQ2hvaWNlKEFTTjFUeXBlW10gdHlwZSkgeworICAgICAgICBzdXBlcihUQUdfQ0hPSUNFKTsgLy8gaGFzIG5vdCB0YWcgbnVtYmVyCisKKyAgICAgICAgaWYgKHR5cGUubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkFTTi4xIGNob2ljZSB0eXBlIE1VU1QgaGF2ZSBhdCBsZWFzdCBvbmUgYWx0ZXJuYXRpdmU6ICIgKyBnZXRDbGFzcygpLmdldE5hbWUoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBjcmVhdGUgbWFwIG9mIGFsbCBpZGVudGlmaWVycworICAgICAgICBUcmVlTWFwPEJpZ0ludGVnZXIsIEJpZ0ludGVnZXI+IG1hcCA9IG5ldyBUcmVlTWFwPEJpZ0ludGVnZXIsIEJpZ0ludGVnZXI+KCk7CisgICAgICAgIGZvciAoaW50IGluZGV4ID0gMDsgaW5kZXggPCB0eXBlLmxlbmd0aDsgaW5kZXgrKykgeworICAgICAgICAgICAgQVNOMVR5cGUgdCA9IHR5cGVbaW5kZXhdOworCisgICAgICAgICAgICBpZiAodCBpbnN0YW5jZW9mIEFTTjFBbnkpIHsKKyAgICAgICAgICAgICAgICAvLyBBU04uMSBBTlkgaXMgbm90IGFsbG93ZWQsCisgICAgICAgICAgICAgICAgLy8gZXZlbiBpdCBpcyBhIHNpbmdsZSBjb21wb25lbnQgKG5vdCBnb29kIGZvciBuZXN0ZWQgY2hvaWNlcykKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJBU04uMSBjaG9pY2UgdHlwZSBNVVNUIGhhdmUgYWx0ZXJuYXRpdmVzIHdpdGggZGlzdGluY3QgdGFnczogIiArIGdldENsYXNzKCkuZ2V0TmFtZSgpKTsgLy8gRklYTUUgbmFtZQorICAgICAgICAgICAgfSBlbHNlIGlmICh0IGluc3RhbmNlb2YgQVNOMUNob2ljZSkgeworCisgICAgICAgICAgICAgICAgLy8gYWRkIGFsbCBjaG9pY2UncyBpZGVudGlmaWVycworICAgICAgICAgICAgICAgIGludFtdW10gY2hvaWNlVG9BZGQgPSAoKEFTTjFDaG9pY2UpIHQpLmlkZW50aWZpZXJzOworICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgY2hvaWNlVG9BZGRbMF0ubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgYWRkSWRlbnRpZmllcihtYXAsIGNob2ljZVRvQWRkWzBdW2pdLCBpbmRleCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBhZGQgcHJpbWl0aXZlIGlkZW50aWZpZXIKKyAgICAgICAgICAgIGlmICh0LmNoZWNrVGFnKHQuaWQpKSB7CisgICAgICAgICAgICAgICAgYWRkSWRlbnRpZmllcihtYXAsIHQuaWQsIGluZGV4KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gYWRkIGNvbnN0cnVjdGVkIGlkZW50aWZpZXIKKyAgICAgICAgICAgIGlmICh0LmNoZWNrVGFnKHQuY29uc3RySWQpKSB7CisgICAgICAgICAgICAgICAgYWRkSWRlbnRpZmllcihtYXAsIHQuY29uc3RySWQsIGluZGV4KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIGZpbGwgaWRlbnRpZmllcnMgYXJyYXkKKyAgICAgICAgaW50IHNpemUgPSBtYXAuc2l6ZSgpOworICAgICAgICBpZGVudGlmaWVycyA9IG5ldyBpbnRbMl1bc2l6ZV07CisgICAgICAgIEl0ZXJhdG9yPE1hcC5FbnRyeTxCaWdJbnRlZ2VyLCBCaWdJbnRlZ2VyPj4gaXQgPSBtYXAuZW50cnlTZXQoKS5pdGVyYXRvcigpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBNYXAuRW50cnk8QmlnSW50ZWdlciwgQmlnSW50ZWdlcj4gZW50cnkgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICBCaWdJbnRlZ2VyIGlkZW50aWZpZXIgPSBlbnRyeS5nZXRLZXkoKTsKKworICAgICAgICAgICAgaWRlbnRpZmllcnNbMF1baV0gPSBpZGVudGlmaWVyLmludFZhbHVlKCk7CisgICAgICAgICAgICBpZGVudGlmaWVyc1sxXVtpXSA9IGVudHJ5LmdldFZhbHVlKCkuaW50VmFsdWUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFkZElkZW50aWZpZXIoVHJlZU1hcDxCaWdJbnRlZ2VyLCBCaWdJbnRlZ2VyPiBtYXAsIGludCBpZGVudGlmaWVyLCBpbnQgaW5kZXgpeworICAgICAgICBpZiAobWFwLnB1dChCaWdJbnRlZ2VyLnZhbHVlT2YoaWRlbnRpZmllciksIEJpZ0ludGVnZXIudmFsdWVPZihpbmRleCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkFTTi4xIGNob2ljZSB0eXBlIE1VU1QgaGF2ZSBhbHRlcm5hdGl2ZXMgIgorICAgICAgICAgICAgICAgICAgICArICJ3aXRoIGRpc3RpbmN0IHRhZ3M6ICIgKyBnZXRDbGFzcygpLmdldE5hbWUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB3aGV0aGVyIG9uZSBvZiBjaG9pY2UgYWx0ZXJuYXRpdmVzIGhhcyB0aGUgc2FtZSBpZGVudGlmaWVyIG9yIG5vdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpZGVudGlmaWVyIC0KKyAgICAgKiAgICAgICAgICAgIEFTTi4xIGlkZW50aWZpZXIgdG8gYmUgdmVyaWZpZWQKKyAgICAgKiBAcmV0dXJuIC0gdHJ1ZSBpZiBvbmUgb2YgY2hvaWNlIGFsdGVybmF0aXZlcyBoYXMgdGhlIHNhbWUgaWRlbnRpZmllciwKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZSBmYWxzZTsKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBjaGVja1RhZyhpbnQgaWRlbnRpZmllcikgeworICAgICAgICByZXR1cm4gQXJyYXlzLmJpbmFyeVNlYXJjaChpZGVudGlmaWVyc1swXSwgaWRlbnRpZmllcikgPj0gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGRlY29kZShCZXJJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGluZGV4ID0gQXJyYXlzLmJpbmFyeVNlYXJjaChpZGVudGlmaWVyc1swXSwgaW4udGFnKTsKKyAgICAgICAgaWYgKGluZGV4IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIkZhaWxlZCB0byBkZWNvZGUgQVNOLjEgY2hvaWNlIHR5cGUuICBObyBhbHRlcm5hdGl2ZXMgd2VyZSBmb3VuZCBmb3IgIiArIGdldENsYXNzKCkuZ2V0TmFtZSgpKTsvLyBGSVhNRSBtZXNzYWdlCisgICAgICAgIH0KKworICAgICAgICBpbmRleCA9IGlkZW50aWZpZXJzWzFdW2luZGV4XTsKKworICAgICAgICBpbi5jb250ZW50ID0gdHlwZVtpbmRleF0uZGVjb2RlKGluKTsKKworICAgICAgICAvLyBzZXQgaW5kZXggZm9yIGdldERlY29kZWRPYmplY3QgbWV0aG9kCisgICAgICAgIGluLmNob2ljZUluZGV4ID0gaW5kZXg7CisKKyAgICAgICAgaWYgKGluLmlzVmVyaWZ5KSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0RGVjb2RlZE9iamVjdChpbik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5jb2RlQVNOKEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgZW5jb2RlQ29udGVudChvdXQpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIGVuY29kZUNvbnRlbnQoQmVyT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgICBvdXQuZW5jb2RlQ2hvaWNlKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0SW5kZXgoT2JqZWN0IG9iamVjdCk7CisKKyAgICBwdWJsaWMgYWJzdHJhY3QgT2JqZWN0IGdldE9iamVjdFRvRW5jb2RlKE9iamVjdCBvYmplY3QpOworCisgICAgcHVibGljIGZpbmFsIHZvaWQgc2V0RW5jb2RpbmdDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LmdldENob2ljZUxlbmd0aCh0aGlzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMUNvbnN0YW50cy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFDb25zdGFudHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZTM2OTgyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFDb25zdGFudHMuamF2YQpAQCAtMCwwICsxLDk2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xOworCisvKioKKyAqIEFTTi4xIGFuZCBzb21lIG90aGVyIGNvbnN0YW50cyBob2xkZXIgaW50ZXJmYWNlCisgKgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vYXNuMS5lbGliZWwudG0uZnIvZW4vc3RhbmRhcmRzL2luZGV4Lmh0bSI+QVNOLjE8L2E+CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQVNOMUNvbnN0YW50cyB7CisgICAgLyoqCisgICAgICogVGFnIGNsYXNzZXMKKyAgICAgKi8KKyAgICBpbnQgQ0xBU1NfVU5JVkVSU0FMID0gMDsKKyAgICBpbnQgQ0xBU1NfQVBQTElDQVRJT04gPSA2NDsKKyAgICBpbnQgQ0xBU1NfQ09OVEVYVFNQRUNJRklDID0gMTI4OworICAgIGludCBDTEFTU19QUklWQVRFID0gMTkyOworCisgICAgLyoqCisgICAgICogVGFnIFByaW1pdGl2ZS9Db25zdHJ1Y3RlZCAoUC9DKSBmbGFnCisgICAgICovCisgICAgaW50IFBDX1BSSU1JVElWRSA9IDA7CisgICAgaW50IFBDX0NPTlNUUlVDVEVEID0gMzI7CisKKyAgICAvKioKKyAgICAgKiBVbml2ZXJzYWwgY2xhc3MgdGFnIGFzc2lnbm1lbnRzCisgICAgICovCisgICAgaW50IFRBR19CT09MRUFOID0gMTsKKyAgICBpbnQgVEFHX0lOVEVHRVIgPSAyOworICAgIGludCBUQUdfQklUU1RSSU5HID0gMzsKKyAgICBpbnQgVEFHX09DVEVUU1RSSU5HID0gNDsKKyAgICBpbnQgVEFHX05VTEwgPSA1OworICAgIGludCBUQUdfT0lEID0gNjsKKyAgICBpbnQgVEFHX09CSkRFU0NSSVBUT1IgPSA3OworICAgIGludCBUQUdfRVhURVJOQUwgPSA4OworICAgIGludCBUQUdfSU5TVEFOQ0VPRiA9IFRBR19FWFRFUk5BTDsKKyAgICBpbnQgVEFHX1JFQUwgPSA5OworICAgIGludCBUQUdfRU5VTSA9IDEwOworICAgIGludCBUQUdfRU1CRURERURQRFYgPSAxMTsKKyAgICBpbnQgVEFHX1VURjhTVFJJTkcgPSAxMjsKKyAgICBpbnQgVEFHX1JFTEFUSVZFT0lEID0gMTM7CisgICAgaW50IFRBR19TRVFVRU5DRSA9IDE2OworICAgIGludCBUQUdfU0VRVUVOQ0VPRiA9IFRBR19TRVFVRU5DRTsKKyAgICBpbnQgVEFHX1NFVCA9IDE3OworICAgIGludCBUQUdfU0VUT0YgPSBUQUdfU0VUOworICAgIGludCBUQUdfTlVNRVJJQ1NUUklORyA9IDE4OworICAgIGludCBUQUdfUFJJTlRBQkxFU1RSSU5HID0gMTk7CisgICAgaW50IFRBR19URUxFVEVYU1RSSU5HID0gMjA7CisgICAgaW50IFRBR19UNjFTVFJJTkcgPSBUQUdfVEVMRVRFWFNUUklORzsKKyAgICBpbnQgVEFHX1ZJREVPVEVYU1RSSU5HID0gMjE7CisgICAgaW50IFRBR19JQTVTVFJJTkcgPSAyMjsKKyAgICBpbnQgVEFHX1VUQ1RJTUUgPSAyMzsKKyAgICBpbnQgVEFHX0dFTkVSQUxJWkVEVElNRSA9IDI0OworICAgIGludCBUQUdfR1JBUEhJQ1NUUklORyA9IDI1OworICAgIGludCBUQUdfVklTSUJMRVNUUklORyA9IDI2OworICAgIGludCBUQUdfSVNPNjQ2U1RSSU5HID0gVEFHX1ZJU0lCTEVTVFJJTkc7CisgICAgaW50IFRBR19HRU5FUkFMU1RSSU5HID0gMjc7CisgICAgaW50IFRBR19VTklWRVJTQUxTVFJJTkcgPSAyODsKKyAgICBpbnQgVEFHX0JNUFNUUklORyA9IDMwOworCisgICAgaW50IFRBR19DX0JJVFNUUklORyA9IFRBR19CSVRTVFJJTkcgfCBQQ19DT05TVFJVQ1RFRDsKKyAgICBpbnQgVEFHX0NfT0NURVRTVFJJTkcgPSBUQUdfT0NURVRTVFJJTkcgfCBQQ19DT05TVFJVQ1RFRDsKKyAgICBpbnQgVEFHX0NfVVRGOFNUUklORyA9IFRBR19VVEY4U1RSSU5HIHwgUENfQ09OU1RSVUNURUQ7CisgICAgaW50IFRBR19DX1NFUVVFTkNFID0gVEFHX1NFUVVFTkNFIHwgUENfQ09OU1RSVUNURUQ7CisgICAgaW50IFRBR19DX1NFUVVFTkNFT0YgPSBUQUdfU0VRVUVOQ0VPRiB8IFBDX0NPTlNUUlVDVEVEOworICAgIGludCBUQUdfQ19TRVQgPSBUQUdfU0VUIHwgUENfQ09OU1RSVUNURUQ7CisgICAgaW50IFRBR19DX1NFVE9GID0gVEFHX1NFVE9GIHwgUENfQ09OU1RSVUNURUQ7CisgICAgaW50IFRBR19DX1VUQ1RJTUUgPSBUQUdfVVRDVElNRSB8IFBDX0NPTlNUUlVDVEVEOworICAgIGludCBUQUdfQ19HRU5FUkFMSVpFRFRJTUUgPSBUQUdfR0VORVJBTElaRURUSU1FIHwgUENfQ09OU1RSVUNURUQ7CisKKyAgICAvKioKKyAgICAgKiBOb3QgZnJvbSB0aGUgQVNOLjEgc3BlY3MuIEZvciBpbXBsZW1lbnRhdGlvbiBwdXJwb3Nlcy4KKyAgICAgKi8KKyAgICBpbnQgVEFHX0FOWSA9IDA7CisgICAgaW50IFRBR19DSE9JQ0UgPSBUQUdfQU5ZOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFDb25zdHJ1Y3RlZC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFDb25zdHJ1Y3RlZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFkZDAyYjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMUNvbnN0cnVjdGVkLmphdmEKQEAgLTAsMCArMSw1NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YsIFN0ZXBhbiBNLiBNaXNodXJhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjE7CisKKworLyoqCisgKiBUaGlzIGFic3RyYWN0IGNsYXNzIGlzIHRoZSBzdXBlciBjbGFzcyBmb3IgYWxsIGNvbnN0cnVjdGVkIEFTTi4xIHR5cGVzCisgKgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vYXNuMS5lbGliZWwudG0uZnIvZW4vc3RhbmRhcmRzL2luZGV4Lmh0bSI+QVNOLjE8L2E+CisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBBU04xQ29uc3RydWN0ZWQgZXh0ZW5kcyBBU04xVHlwZSB7CisKKyAgICBwcm90ZWN0ZWQgQVNOMUNvbnN0cnVjdGVkKGludCB0YWdOdW1iZXIpIHsKKyAgICAgICAgc3VwZXIoQ0xBU1NfVU5JVkVSU0FMLCB0YWdOdW1iZXIpOworICAgIH0KKworICAgIHByb3RlY3RlZCBBU04xQ29uc3RydWN0ZWQoaW50IHRhZ0NsYXNzLCBpbnQgdGFnTnVtYmVyKSB7CisgICAgICAgIHN1cGVyKHRhZ0NsYXNzLCB0YWdOdW1iZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHByb3ZpZGVkIGlkZW50aWZpZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaWRlbnRpZmllciAtIGlkZW50aWZpZXIgdG8gYmUgdmVyaWZpZWQKKyAgICAgKiBAcmV0dXJuIC0gdHJ1ZSBpZiBpZGVudGlmaWVyIGNvcnJlc3BvbmQgdG8gY29uc3RydWN0ZWQgaWRlbnRpZmllciBvZgorICAgICAqICAgICAgICAgICB0aGlzIEFTTi4xIHR5cGUsIG90aGVyd2lzZSBmYWxzZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGNoZWNrVGFnKGludCBpZGVudGlmaWVyKSB7CisgICAgICAgIHJldHVybiB0aGlzLmNvbnN0cklkID09IGlkZW50aWZpZXI7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5jb2RlQVNOKEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LmVuY29kZVRhZyhjb25zdHJJZCk7CisgICAgICAgIGVuY29kZUNvbnRlbnQob3V0KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMUVudW1lcmF0ZWQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xRW51bWVyYXRlZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjY2VhOTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMUVudW1lcmF0ZWQuamF2YQpAQCAtMCwwICsxLDg4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBTdGVwYW4gTS4gTWlzaHVyYQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIEFTTi4xIEVudW1lcmF0ZWQgdHlwZS4KKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9hc24xLmVsaWJlbC50bS5mci9lbi9zdGFuZGFyZHMvaW5kZXguaHRtIj5BU04uMTwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEFTTjFFbnVtZXJhdGVkIGV4dGVuZHMgQVNOMVByaW1pdGl2ZSB7CisKKyAgICAvLyBkZWZhdWx0IGltcGxlbWVudGF0aW9uCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQVNOMUVudW1lcmF0ZWQgQVNOMSA9IG5ldyBBU04xRW51bWVyYXRlZCgpOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBBU04uMSBFbnVtZXJhdGVkIHR5cGUKKyAgICAgKgorICAgICAqIFRoZSBjb25zdHJ1Y3RvciBpcyBwcm92aWRlZCBmb3IgaW5oZXJpdGFuY2UgcHVycG9zZXMKKyAgICAgKiB3aGVuIHRoZXJlIGlzIGEgbmVlZCB0byBjcmVhdGUgYSBjdXN0b20gQVNOLjEgRW51bWVyYXRlZCB0eXBlLgorICAgICAqIFRvIGdldCBhIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gaXQgaXMgcmVjb21tZW5kZWQgdG8gdXNlCisgICAgICogZ2V0SW5zdGFuY2UoKSBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIEFTTjFFbnVtZXJhdGVkKCkgeworICAgICAgICBzdXBlcihUQUdfRU5VTSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBFbnVtZXJhdGVkIHR5cGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gd29ya3Mgd2l0aCBlbmNvZGluZworICAgICAqIHRoYXQgaXMgcmVwcmVzZW50ZWQgYXMgYnl0ZSBhcnJheS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQVNOLjEgRW51bWVyYXRlZCB0eXBlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEFTTjFFbnVtZXJhdGVkIGdldEluc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gQVNOMTsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGRlY29kZShCZXJJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW4ucmVhZEVudW1lcmF0ZWQoKTsKKworICAgICAgICBpZiAoaW4uaXNWZXJpZnkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXREZWNvZGVkT2JqZWN0KGluKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHRyYWN0cyBhcnJheSBvZiBieXRlcyBmcm9tIEJFUiBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFycmF5IG9mIGJ5dGVzCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gQXJyYXlzLmNvcHlPZlJhbmdlKGluLmJ1ZmZlciwgaW4uY29udGVudE9mZnNldCwgaW4uY29udGVudE9mZnNldCArIGluLmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5jb2RlQ29udGVudChCZXJPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIG91dC5lbmNvZGVJbnRlZ2VyKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RW5jb2RpbmdDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0Lmxlbmd0aCA9ICgoYnl0ZVtdKSBvdXQuY29udGVudCkubGVuZ3RoOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xRXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxN2VlOGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292LCBTdGVwYW4gTS4gTWlzaHVyYQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBUaHJvd24gYnkgZGVjb2Rlci9lbmNvZGVyIHN0cmVhbSB0byBpbmRpY2F0ZSB2aW9sYXRpb24gb2YgZW5jb2RpbmcgcnVsZXMuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBBU04xRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworCisgICAgLyoqIEBzZXJpYWwgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzU2MTk4MTI2Mzk4OTEyMzk4N0w7CisKKyAgICBwdWJsaWMgQVNOMUV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSl7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xRXhwbGljaXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xRXhwbGljaXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NWUyMTY3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFFeHBsaWNpdC5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292LCBTdGVwYW4gTS4gTWlzaHVyYQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgZXhwbGljaXRseSB0YWdnZWQgQVNOLjEgdHlwZS4KKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9hc24xLmVsaWJlbC50bS5mci9lbi9zdGFuZGFyZHMvaW5kZXguaHRtIj5BU04uMTwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEFTTjFFeHBsaWNpdCBleHRlbmRzIEFTTjFDb25zdHJ1Y3RlZCB7CisKKyAgICAvKiogVGFnZ2VkIHR5cGUgKi8KKyAgICBwdWJsaWMgZmluYWwgQVNOMVR5cGUgdHlwZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgZXhwbGljaXRseSB0YWdnZWQgQVNOLjEgdHlwZQorICAgICAqIHdpdGggY29udGV4dC1zcGVjaWZpYyB0YWcgY2xhc3MgYW5kIHNwZWNpZmllZCB0YWcgbnVtYmVyLgorICAgICAqCisgICAgICogQHBhcmFtIHRhZ051bWJlciAtIEFTTi4xIHRhZyBudW1iZXIKKyAgICAgKiBAcGFyYW0gdHlwZSAtIEFTTi4xIHR5cGUgdG8gYmUgdGFnZ2VkCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gLSBpZiB0YWdOdW1iZXIgaXMgaW52YWxpZAorICAgICAqLworICAgIHB1YmxpYyBBU04xRXhwbGljaXQoaW50IHRhZ051bWJlciwgQVNOMVR5cGUgdHlwZSkgeworICAgICAgICB0aGlzKENMQVNTX0NPTlRFWFRTUEVDSUZJQywgdGFnTnVtYmVyLCB0eXBlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGV4cGxpY2l0bHkgdGFnZ2VkIEFTTi4xIHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGFnQ2xhc3MgLSBBU04uMSB0YWcgY2xhc3MuCisgICAgICogQHBhcmFtIHRhZ051bWJlciAtIEFTTi4xIHRhZyBudW1iZXIKKyAgICAgKiBAcGFyYW0gdHlwZSAtIEFTTi4xIHR5cGUgdG8gYmUgdGFnZ2VkCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gLSBpZiB0YWdDbGFzcyBvciB0YWdOdW1iZXIgaXMgaW52YWxpZAorICAgICAqLworICAgIHB1YmxpYyBBU04xRXhwbGljaXQoaW50IHRhZ0NsYXNzLCBpbnQgdGFnTnVtYmVyLCBBU04xVHlwZSB0eXBlKSB7CisgICAgICAgIHN1cGVyKHRhZ0NsYXNzLCB0YWdOdW1iZXIpOworICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZGVjb2RlKEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY29uc3RySWQgIT0gaW4udGFnKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiQVNOLjEgZXhwbGljaXRseSB0YWdnZWQgdHlwZSBpcyBleHBlY3RlZCBhdCBbIiArCisgICAgICAgICAgICAgICAgICAgIGluLnRhZ09mZnNldCArICJdLiBFeHBlY3RlZCB0YWc6ICIgKyBJbnRlZ2VyLnRvSGV4U3RyaW5nKGNvbnN0cklkKSArICIsICIgKworICAgICAgICAgICAgICAgICAgICAiYnV0IGVuY291bnRlcmVkIHRhZyAiICsgSW50ZWdlci50b0hleFN0cmluZyhpbi50YWcpKTsKKyAgICAgICAgfQorICAgICAgICBpbi5uZXh0KCk7CisKKyAgICAgICAgaW4uY29udGVudCA9IHR5cGUuZGVjb2RlKGluKTsKKworICAgICAgICBpZiAoaW4uaXNWZXJpZnkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXREZWNvZGVkT2JqZWN0KGluKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmNvZGVDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LmVuY29kZUV4cGxpY2l0KHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nQ29udGVudChCZXJPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIG91dC5nZXRFeHBsaWNpdExlbmd0aCh0aGlzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCkgKyAiIGZvciB0eXBlICIgKyB0eXBlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xR2VuZXJhbGl6ZWRUaW1lLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMUdlbmVyYWxpemVkVGltZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2NGViZTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMUdlbmVyYWxpemVkVGltZS5qYXZhCkBAIC0wLDAgKzEsMTA0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdiwgU3RlcGFuIE0uIE1pc2h1cmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0czsKK2ltcG9ydCBqYXZhLnRleHQuU2ltcGxlRGF0ZUZvcm1hdDsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIEFTTi4xIEdlbmVyYWxpemVkVGltZSB0eXBlLgorICoKKyAqIEBzZWUgaHR0cDovL2FzbjEuZWxpYmVsLnRtLmZyL2VuL3N0YW5kYXJkcy9pbmRleC5odG0KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEFTTjFHZW5lcmFsaXplZFRpbWUgZXh0ZW5kcyBBU04xVGltZSB7CisKKyAgICAvLyBkZWZhdWx0IGltcGxlbWVudGF0aW9uCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQVNOMUdlbmVyYWxpemVkVGltZSBBU04xID0gbmV3IEFTTjFHZW5lcmFsaXplZFRpbWUoKTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgQVNOLjEgR2VuZXJhbGl6ZWRUaW1lIHR5cGUKKyAgICAgKgorICAgICAqIFRoZSBjb25zdHJ1Y3RvciBpcyBwcm92aWRlZCBmb3IgaW5oZXJpdGFuY2UgcHVycG9zZXMKKyAgICAgKiB3aGVuIHRoZXJlIGlzIGEgbmVlZCB0byBjcmVhdGUgYSBjdXN0b20gQVNOLjEgR2VuZXJhbGl6ZWRUaW1lIHR5cGUuCisgICAgICogVG8gZ2V0IGEgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpdCBpcyByZWNvbW1lbmRlZCB0byB1c2UKKyAgICAgKiBnZXRJbnN0YW5jZSgpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQVNOMUdlbmVyYWxpemVkVGltZSgpIHsKKyAgICAgICAgc3VwZXIoVEFHX0dFTkVSQUxJWkVEVElNRSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBHZW5lcmFsaXplZFRpbWUgdHlwZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uCisgICAgICoKKyAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB3b3JrcyB3aXRoIGVuY29kaW5nCisgICAgICogdGhhdCBpcyByZXByZXNlbnRlZCBhcyBEYXRlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQVNOLjEgR2VuZXJhbGl6ZWRUaW1lIHR5cGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQVNOMUdlbmVyYWxpemVkVGltZSBnZXRJbnN0YW5jZSgpIHsKKyAgICAgICAgcmV0dXJuIEFTTjE7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBkZWNvZGUoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGluLnJlYWRHZW5lcmFsaXplZFRpbWUoKTsKKworICAgICAgICBpZiAoaW4uaXNWZXJpZnkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXREZWNvZGVkT2JqZWN0KGluKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmNvZGVDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LmVuY29kZUdlbmVyYWxpemVkVGltZSgpOworICAgIH0KKworICAgIC8vIEZJWE1FIHN1cHBvcnQgb25seSBvbmUgZm9ybWF0IGZvciBlbmNvZGluZywgZG8gd2UgbmVlZCBvdGhlcnM/CisgICAgLy8KKyAgICAvLyBBY2NvcmRpbmcgdG8gWC42ODA6CisgICAgLy8gZm91ciBkaWdpdCB5ZWFyLCBzZWNvbmRzIGFsd2F5cyBwcmVzZW50ZWQKKyAgICAvLyBhbmQgZnJhY3Rpb25hbC1zZWNvbmRzIGVsZW1lbnRzIHdpdGhvdXQKKyAgICAvLyB0cmFpbGluZyAwJ3MgKG11c3QgYmUgY3V0IGxhdGVyIGZyb20gY29udGVudCkKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VOX1BBVFRFUk4gPSAieXl5eU1NZGRISG1tc3MuU1NTIjsKKworICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nQ29udGVudChCZXJPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgc2RmID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoR0VOX1BBVFRFUk4pOworICAgICAgICBzZGYuc2V0VGltZVpvbmUoVGltZVpvbmUuZ2V0VGltZVpvbmUoIlVUQyIpKTsKKyAgICAgICAgU3RyaW5nIHRlbXAgPSBzZGYuZm9ybWF0KG91dC5jb250ZW50KTsKKyAgICAgICAgLy8gY3V0IG9mZiB0cmFpbGluZyAwcworICAgICAgICBpbnQgbnVsbElkOworICAgICAgICBpbnQgY3Vyckxlbmd0aDsKKyAgICAgICAgd2hpbGUgKCgobnVsbElkID0gdGVtcC5sYXN0SW5kZXhPZignMCcsIGN1cnJMZW5ndGggPSB0ZW1wLmxlbmd0aCgpIC0gMSkpICE9IC0xKQorICAgICAgICAgICAgICAgICYgKG51bGxJZCA9PSBjdXJyTGVuZ3RoKSkgeworICAgICAgICAgICAgdGVtcCA9IHRlbXAuc3Vic3RyaW5nKDAsIG51bGxJZCk7CisgICAgICAgIH0KKyAgICAgICAgLy8gZGVhbCB3aXRoIHBvaW50IChjdXQgb2ZmIGlmIGl0IGlzIGxhc3QgY2hhcikKKyAgICAgICAgaWYgKHRlbXAuY2hhckF0KGN1cnJMZW5ndGgpID09ICcuJykgeworICAgICAgICAgICAgdGVtcCA9IHRlbXAuc3Vic3RyaW5nKDAsIGN1cnJMZW5ndGgpOworICAgICAgICB9CisKKyAgICAgICAgb3V0LmNvbnRlbnQgPSAodGVtcCArICJaIikuZ2V0Qnl0ZXMoQ2hhcnNldHMuVVRGXzgpOworICAgICAgICBvdXQubGVuZ3RoID0gKChieXRlW10pIG91dC5jb250ZW50KS5sZW5ndGg7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFJbXBsaWNpdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFJbXBsaWNpdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIxYzRlYzYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMUltcGxpY2l0LmphdmEKQEAgLTAsMCArMSwxNDEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292LCBTdGVwYW4gTS4gTWlzaHVyYQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworCisvKioKKyAqIEltcGxpY2l0bHkgdGFnZ2VkIEFTTi4xIHR5cGUuCisgKgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vYXNuMS5lbGliZWwudG0uZnIvZW4vc3RhbmRhcmRzL2luZGV4Lmh0bSI+QVNOLjE8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBBU04xSW1wbGljaXQgZXh0ZW5kcyBBU04xVHlwZSB7CisKKyAgICAvKiogcHJpbWl0aXZlIHR5cGUgb2YgdGFnZ2luZyAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUQUdHSU5HX1BSSU1JVElWRSA9IDA7CisKKyAgICAvKiogY29uc3RydWN0ZWQgdHlwZSBvZiB0YWdnaW5nICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRBR0dJTkdfQ09OU1RSVUNURUQgPSAxOworCisgICAgLyoqIHN0cmluZyB0eXBlIG9mIHRhZ2dpbmcgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVEFHR0lOR19TVFJJTkcgPSAyOworCisgICAgLyoqIHRhZ2dlZCBBU04uMSB0eXBlICovCisgICAgcHJpdmF0ZSBmaW5hbCBBU04xVHlwZSB0eXBlOworCisgICAgLyoqCisgICAgICogdHlwZSBvZiB0YWdnaW5nLiBUaGVyZSBhcmUgdGhyZWUgb2YgdGhlbQorICAgICAqIDEpIHByaW1pdGl2ZTogb25seSBwcmltaXRpdmUgaWRlbnRpZmllciBpcyB2YWxpZAorICAgICAqIDIpIGNvbnN0cnVjdGVkOiBvbmx5IGNvbnN0cnVjdGVkIGlkZW50aWZpZXIgaXMgdmFsaWQKKyAgICAgKiAzKSBzdHJpbmc6IGJvdGggaWRlbnRpZmllcnMgYXJlIHZhbGlkCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdGFnZ2luZ1R5cGU7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGltcGxpY2l0bHkgdGFnZ2VkIEFTTi4xIHR5cGUKKyAgICAgKiB3aXRoIGNvbnRleHQtc3BlY2lmaWMgdGFnIGNsYXNzIGFuZCBzcGVjaWZpZWQgdGFnIG51bWJlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YWdOdW1iZXIgLSBBU04uMSB0YWcgbnVtYmVyCisgICAgICogQHBhcmFtIHR5cGUgLSBBU04uMSB0eXBlIHRvIGJlIHRhZ2dlZAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIC0gaWYgdGFnTnVtYmVyIG9yIHR5cGUgaXMgaW52YWxpZAorICAgICAqLworICAgIHB1YmxpYyBBU04xSW1wbGljaXQoaW50IHRhZ051bWJlciwgQVNOMVR5cGUgdHlwZSkgeworICAgICAgICBzdXBlcihDTEFTU19DT05URVhUU1BFQ0lGSUMsIHRhZ051bWJlcik7CisKKyAgICAgICAgaWYgKCh0eXBlIGluc3RhbmNlb2YgQVNOMUNob2ljZSkgfHwgKHR5cGUgaW5zdGFuY2VvZiBBU04xQW55KSkgeworICAgICAgICAgICAgLy8gQWNjb3JkaW5nIHRvIFguNjgwOgorICAgICAgICAgICAgLy8gJ1RoZSBJTVBMSUNJVCBhbHRlcm5hdGl2ZSBzaGFsbCBub3QgYmUgdXNlZCBpZiB0aGUgdHlwZQorICAgICAgICAgICAgLy8gZGVmaW5lZCBieSAiVHlwZSIgaXMgYW4gdW50YWdnZWQgY2hvaWNlIHR5cGUgb3IgYW4KKyAgICAgICAgICAgIC8vIHVudGFnZ2VkIG9wZW4gdHlwZScKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkltcGxpY2l0IHRhZ2dpbmcgY2FuIG5vdCBiZSB1c2VkIGZvciBBU04uMSBBTlkgb3IgQ0hPSUNFIHR5cGUiKTsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisKKyAgICAgICAgaWYgKHR5cGUuY2hlY2tUYWcodHlwZS5pZCkpIHsKKyAgICAgICAgICAgIGlmICh0eXBlLmNoZWNrVGFnKHR5cGUuY29uc3RySWQpKSB7CisgICAgICAgICAgICAgICAgLy8gdGhlIGJhc2UgZW5jb2RpbmcgY2FuIGJlIHByaW1pdGl2ZSBvdCBjb25zdHJ1Y3RlZAorICAgICAgICAgICAgICAgIC8vIHVzZSBib3RoIGVuY29kaW5ncworICAgICAgICAgICAgICAgIHRhZ2dpbmdUeXBlID0gVEFHR0lOR19TVFJJTkc7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBiYXNlIGVuY29kaW5nIGlzIHByaW1pdGl2ZSB1c2UgcHJpbWl0aXZlIGVuY29kaW5nCisgICAgICAgICAgICAgICAgdGFnZ2luZ1R5cGUgPSBUQUdHSU5HX1BSSU1JVElWRTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIGlmIHRoZSBiYXNlIGVuY29kaW5nIGlzIGNvbnN0cnVjdGVkIHVzZSBjb25zdHJ1Y3RlZCBlbmNvZGluZworICAgICAgICAgICAgdGFnZ2luZ1R5cGUgPSBUQUdHSU5HX0NPTlNUUlVDVEVEOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gY2hlY2tUYWcoaW50IGlkZW50aWZpZXIpIHsKKyAgICAgICAgc3dpdGNoICh0YWdnaW5nVHlwZSkgeworICAgICAgICBjYXNlIFRBR0dJTkdfUFJJTUlUSVZFOgorICAgICAgICAgICAgcmV0dXJuIGlkID09IGlkZW50aWZpZXI7CisgICAgICAgIGNhc2UgVEFHR0lOR19DT05TVFJVQ1RFRDoKKyAgICAgICAgICAgIHJldHVybiBjb25zdHJJZCA9PSBpZGVudGlmaWVyOworICAgICAgICBkZWZhdWx0OiAvLyBUQUdHSU5HX1NUUklORworICAgICAgICAgICAgcmV0dXJuIGlkID09IGlkZW50aWZpZXIgfHwgY29uc3RySWQgPT0gaWRlbnRpZmllcjsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZGVjb2RlKEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIWNoZWNrVGFnKGluLnRhZykpIHsKKyAgICAgICAgICAgIC8vIEZJWE1FIG5lZWQgbG9vayBmb3IgdGFnZ2luZyB0eXBlCisgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiQVNOLjEgaW1wbGljaXRseSB0YWdnZWQgdHlwZSBleHBlY3RlZCBhdCAiICsKKyAgICAgICAgICAgICAgICAgICAgIlsiICsgaW4udGFnT2Zmc2V0ICsgIl0uIEV4cGVjdGVkIHRhZzogIiArIEludGVnZXIudG9IZXhTdHJpbmcoaWQpICsgIiwgIiArCisgICAgICAgICAgICAgICAgICAgICJidXQgZ290ICIgKyBJbnRlZ2VyLnRvSGV4U3RyaW5nKGluLnRhZykpOworICAgICAgICB9CisKKyAgICAgICAgLy8gc3Vic3RpdHV0ZSBpZGVudGlmaWVyIGZvciBmdXJ0aGVyIGRlY29kaW5nCisgICAgICAgIGlmIChpZCA9PSBpbi50YWcpIHsKKyAgICAgICAgICAgIGluLnRhZyA9IHR5cGUuaWQ7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpbi50YWcgPSB0eXBlLmNvbnN0cklkOworICAgICAgICB9CisgICAgICAgIGluLmNvbnRlbnQgPSB0eXBlLmRlY29kZShpbik7CisKKyAgICAgICAgaWYgKGluLmlzVmVyaWZ5KSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0RGVjb2RlZE9iamVjdChpbik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5jb2RlQVNOKEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgLy9GSVhNRSBuZWVkIGFub3RoZXIgd2F5IGZvciBzcGVjaWZ5aW5nIGlkZW50aWZpZXIgdG8gYmUgZW5jb2RlZAorICAgICAgICBpZiAodGFnZ2luZ1R5cGUgPT0gVEFHR0lOR19DT05TVFJVQ1RFRCkgeworICAgICAgICAgICAgb3V0LmVuY29kZVRhZyhjb25zdHJJZCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBvdXQuZW5jb2RlVGFnKGlkKTsKKyAgICAgICAgfQorICAgICAgICBlbmNvZGVDb250ZW50KG91dCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5jb2RlQ29udGVudChCZXJPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIHR5cGUuZW5jb2RlQ29udGVudChvdXQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nQ29udGVudChCZXJPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIHR5cGUuc2V0RW5jb2RpbmdDb250ZW50KG91dCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFJbnRlZ2VyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMUludGVnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZjMzZDA5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFJbnRlZ2VyLmphdmEKQEAgLTAsMCArMSwxMjIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292LCBTdGVwYW4gTS4gTWlzaHVyYQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKKworLyoqCisgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgQVNOLjEgSW50ZWdlciB0eXBlLgorICoKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2FzbjEuZWxpYmVsLnRtLmZyL2VuL3N0YW5kYXJkcy9pbmRleC5odG0iPkFTTi4xPC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQVNOMUludGVnZXIgZXh0ZW5kcyBBU04xUHJpbWl0aXZlIHsKKworICAgIC8qKiBkZWZhdWx0IGltcGxlbWVudGF0aW9uICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQVNOMUludGVnZXIgQVNOMSA9IG5ldyBBU04xSW50ZWdlcigpOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBBU04uMSBJbnRlZ2VyIHR5cGUKKyAgICAgKgorICAgICAqIFRoZSBjb25zdHJ1Y3RvciBpcyBwcm92aWRlZCBmb3IgaW5oZXJpdGFuY2UgcHVycG9zZXMKKyAgICAgKiB3aGVuIHRoZXJlIGlzIGEgbmVlZCB0byBjcmVhdGUgYSBjdXN0b20gQVNOLjEgSW50ZWdlciB0eXBlLgorICAgICAqIFRvIGdldCBhIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gaXQgaXMgcmVjb21tZW5kZWQgdG8gdXNlCisgICAgICogZ2V0SW5zdGFuY2UoKSBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIEFTTjFJbnRlZ2VyKCkgeworICAgICAgICBzdXBlcihUQUdfSU5URUdFUik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBJbnRlZ2VyIHR5cGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gd29ya3Mgd2l0aCBlbmNvZGluZworICAgICAqIHRoYXQgaXMgcmVwcmVzZW50ZWQgYXMgYnl0ZSBhcnJheSBpbiB0d28ncy1jb21wbGVtZW50IG5vdGF0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBBU04uMSBJbnRlZ2VyIHR5cGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQVNOMUludGVnZXIgZ2V0SW5zdGFuY2UoKSB7CisgICAgICAgIHJldHVybiBBU04xOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZGVjb2RlKEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbi5yZWFkSW50ZWdlcigpOworCisgICAgICAgIGlmIChpbi5pc1ZlcmlmeSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldERlY29kZWRPYmplY3QoaW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4dHJhY3RzIGFycmF5IG9mIGJ5dGVzIGZyb20gQkVSIGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYXJyYXkgb2YgYnl0ZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBieXRlc0VuY29kZWQgPSBuZXcgYnl0ZVtpbi5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGluLmJ1ZmZlciwgaW4uY29udGVudE9mZnNldCwgYnl0ZXNFbmNvZGVkLCAwLAorICAgICAgICAgICAgICAgIGluLmxlbmd0aCk7CisgICAgICAgIHJldHVybiBieXRlc0VuY29kZWQ7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5jb2RlQ29udGVudChCZXJPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIG91dC5lbmNvZGVJbnRlZ2VyKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RW5jb2RpbmdDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0Lmxlbmd0aCA9ICgoYnl0ZVtdKSBvdXQuY29udGVudCkubGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIGRlY29kZWQgQVNOLjEgSW50ZWdlciB0byBpbnQgdmFsdWUuCisgICAgICogSWYgdGhlIG9iamVjdCByZXByZXNlbnRzIGFuIGludGVnZXIgdmFsdWUKKyAgICAgKiBsYXJnZXIgdGhhbiAzMiBiaXRzLCB0aGUgaGlnaCBiaXRzIHdpbGwgYmUgbG9zdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZWNvZGVkIGEgZGVjb2RlZCBvYmplY3QgY29ycmVzcG9uZGluZyB0byB0aGlzIHR5cGUKKyAgICAgKiBAcmV0dXJuIGRlY29kZWQgaW50IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHRvSW50VmFsdWUoT2JqZWN0IGRlY29kZWQpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKChieXRlW10pIGRlY29kZWQpLmludFZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgZGVjb2RlZCBBU04uMSBJbnRlZ2VyIHRvIGEgQmlnSW50ZWdlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZWNvZGVkIGEgZGVjb2RlZCBvYmplY3QgY29ycmVzcG9uZGluZyB0byB0aGlzIHR5cGUKKyAgICAgKiBAcmV0dXJuIGRlY29kZWQgQmlnSW50ZWdlciB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEJpZ0ludGVnZXIgdG9CaWdJbnRlZ2VyVmFsdWUoT2JqZWN0IGRlY29kZWQpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKChieXRlW10pIGRlY29kZWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIHByaW1pdGl2ZSBpbnQgdmFsdWUgdG8gYSBmb3JtIG1vc3Qgc3VpdGFibGUgZm9yIGVuY29kaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlIHByaW1pdGl2ZSB2YWx1ZSB0byBiZSBlbmNvZGVkCisgICAgICogQHJldHVybiBvYmplY3Qgc3VpdGFibGUgZm9yIGVuY29kaW5nCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBPYmplY3QgZnJvbUludFZhbHVlKGludCB2YWx1ZSkgeworICAgICAgICByZXR1cm4gQmlnSW50ZWdlci52YWx1ZU9mKHZhbHVlKS50b0J5dGVBcnJheSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xT2N0ZXRTdHJpbmcuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xT2N0ZXRTdHJpbmcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YjM0NGY3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFPY3RldFN0cmluZy5qYXZhCkBAIC0wLDAgKzEsODYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292LCBTdGVwYW4gTS4gTWlzaHVyYQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIEFTTi4xIG9jdGV0IHN0cmluZyB0eXBlLgorICoKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2FzbjEuZWxpYmVsLnRtLmZyL2VuL3N0YW5kYXJkcy9pbmRleC5odG0iPkFTTi4xPC9hPgorICovCitwdWJsaWMgY2xhc3MgQVNOMU9jdGV0U3RyaW5nIGV4dGVuZHMgQVNOMVN0cmluZ1R5cGUgeworCisgICAgLyoqIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBBU04xT2N0ZXRTdHJpbmcgQVNOMSA9IG5ldyBBU04xT2N0ZXRTdHJpbmcoKTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgQVNOLjEgb2N0ZXQgc3RyaW5nIHR5cGUKKyAgICAgKgorICAgICAqIFRoZSBjb25zdHJ1Y3RvciBpcyBwcm92aWRlZCBmb3IgaW5oZXJpdGFuY2UgcHVycG9zZXMKKyAgICAgKiB3aGVuIHRoZXJlIGlzIGEgbmVlZCB0byBjcmVhdGUgYSBjdXN0b20gQVNOLjEgb2N0ZXQgc3RyaW5nIHR5cGUuCisgICAgICogVG8gZ2V0IGEgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpdCBpcyByZWNvbW1lbmRlZCB0byB1c2UKKyAgICAgKiBnZXRJbnN0YW5jZSgpIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQVNOMU9jdGV0U3RyaW5nKCkgeworICAgICAgICBzdXBlcihUQUdfT0NURVRTVFJJTkcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgQVNOLjEgb2N0ZXQgc3RyaW5nIHR5cGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gd29ya3Mgd2l0aCBlbmNvZGluZworICAgICAqIHRoYXQgaXMgcmVwcmVzZW50ZWQgYXMgYnl0ZSBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEFTTjFPY3RldFN0cmluZyBnZXRJbnN0YW5jZSgpIHsKKyAgICAgICAgcmV0dXJuIEFTTjE7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZGVjb2RlKEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbi5yZWFkT2N0ZXRTdHJpbmcoKTsKKworICAgICAgICBpZiAoaW4uaXNWZXJpZnkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXREZWNvZGVkT2JqZWN0KGluKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHRyYWN0cyBhcnJheSBvZiBieXRlcyBmcm9tIEJFUiBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFycmF5IG9mIGJ5dGVzCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIEFycmF5cy5jb3B5T2ZSYW5nZShpbi5idWZmZXIsIGluLmNvbnRlbnRPZmZzZXQsIGluLmNvbnRlbnRPZmZzZXQgKyBpbi5sZW5ndGgpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBlbmNvZGVDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LmVuY29kZU9jdGV0U3RyaW5nKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nQ29udGVudChCZXJPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIG91dC5sZW5ndGggPSAoKGJ5dGVbXSkgb3V0LmNvbnRlbnQpLmxlbmd0aDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMU9pZC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFPaWQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTI2YjgyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFPaWQuamF2YQpAQCAtMCwwICsxLDE5NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YsIFN0ZXBhbiBNLiBNaXNodXJhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjE7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIEFTTi4xIE9iamVjdCBJZGVudGlmaWVyIHR5cGUuCisgKgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vYXNuMS5lbGliZWwudG0uZnIvZW4vc3RhbmRhcmRzL2luZGV4Lmh0bSI+QVNOLjE8L2E+CisgKi8KK3B1YmxpYyBjbGFzcyBBU04xT2lkIGV4dGVuZHMgQVNOMVByaW1pdGl2ZSB7CisKKyAgICAvKiogZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFTTjFPaWQgQVNOMSA9IG5ldyBBU04xT2lkKCk7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIEFTTi4xIE9iamVjdCBJZGVudGlmaWVyIHR5cGUKKyAgICAgKgorICAgICAqIFRoZSBjb25zdHJ1Y3RvciBpcyBwcm92aWRlZCBmb3IgaW5oZXJpdGFuY2UgcHVycG9zZXMKKyAgICAgKiB3aGVuIHRoZXJlIGlzIGEgbmVlZCB0byBjcmVhdGUgYSBjdXN0b20gQVNOLjEgT2JqZWN0IElkZW50aWZpZXIgdHlwZS4KKyAgICAgKiBUbyBnZXQgYSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGl0IGlzIHJlY29tbWVuZGVkIHRvIHVzZQorICAgICAqIGdldEluc3RhbmNlKCkgbWV0aG9kLgorICAgICAqLworICAgIHB1YmxpYyBBU04xT2lkKCkgeworICAgICAgICBzdXBlcihUQUdfT0lEKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFTTi4xIE9iamVjdCBJZGVudGlmaWVyIHR5cGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gd29ya3Mgd2l0aCBlbmNvZGluZworICAgICAqIHRoYXQgaXMgcmVwcmVzZW50ZWQgYXMgYXJyYXkgb2YgaW50ZWdlcnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFTTi4xIE9iamVjdCBJZGVudGlmaWVyIHR5cGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQVNOMU9pZCBnZXRJbnN0YW5jZSgpIHsKKyAgICAgICAgcmV0dXJuIEFTTjE7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBkZWNvZGUoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGluLnJlYWRPSUQoKTsKKworICAgICAgICBpZiAoaW4uaXNWZXJpZnkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXREZWNvZGVkT2JqZWN0KGluKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHRyYWN0cyBhcnJheSBvZiBpbnRlZ2VycyBmcm9tIEJFUiBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFycmF5IG9mIGludGVnZXJzCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQWxsb2NhdGUgYW5kIGRlY29kZQorICAgICAgICBpbnQgb2lkRWxlbWVudCA9IGluLm9pZEVsZW1lbnQ7CisgICAgICAgIGludFtdIG9pZCA9IG5ldyBpbnRbb2lkRWxlbWVudF07CisgICAgICAgIGZvciAoaW50IGlkID0gMSwgaSA9IDA7IGlkIDwgb2lkLmxlbmd0aDsgaWQrKywgaSsrKSB7CisgICAgICAgICAgICBpbnQgb2N0ZXQgPSBpbi5idWZmZXJbaW4uY29udGVudE9mZnNldCArIGldOworICAgICAgICAgICAgb2lkRWxlbWVudCA9IG9jdGV0ICYgMHg3RjsKKyAgICAgICAgICAgIHdoaWxlICgob2N0ZXQgJiAweDgwKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgICAgIG9jdGV0ID0gaW4uYnVmZmVyW2luLmNvbnRlbnRPZmZzZXQgKyBpXTsKKyAgICAgICAgICAgICAgICBvaWRFbGVtZW50ID0gb2lkRWxlbWVudCA8PCA3IHwgKG9jdGV0ICYgMHg3Zik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBvaWRbaWRdID0gb2lkRWxlbWVudDsKKyAgICAgICAgfQorICAgICAgICAvLyBTcGVjaWFsIGhhbmRsaW5nIGZvciB0aGUgZmlyc3QgcGFja2VkIE9JRCBlbGVtZW50CisgICAgICAgIGlmIChvaWRbMV0gPiA3OSkgeworICAgICAgICAgICAgb2lkWzBdID0gMjsKKyAgICAgICAgICAgIG9pZFsxXSA9IG9pZFsxXSAtIDgwOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgb2lkWzBdID0gb2lkWzFdIC8gNDA7CisgICAgICAgICAgICBvaWRbMV0gPSBvaWRbMV0gJSA0MDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gb2lkOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVuY29kZUNvbnRlbnQoQmVyT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgICBvdXQuZW5jb2RlT0lEKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RW5jb2RpbmdDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgaW50W10gb2lkID0gKGludFtdKSBvdXQuY29udGVudDsKKworICAgICAgICBpbnQgbGVuZ3RoID0gMDsKKworICAgICAgICAvLyBmaXJzdCBzdWJpZGVudGlmaWVyCisgICAgICAgIGludCBlbGVtID0gb2lkWzBdICogNDAgKyBvaWRbMV07CisgICAgICAgIGlmIChlbGVtID09IDApIHsKKyAgICAgICAgICAgIGxlbmd0aCA9IDE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmb3IgKDsgZWxlbSA+IDA7IGVsZW0gPSBlbGVtID4+IDcpIHsKKyAgICAgICAgICAgICAgICBsZW5ndGgrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHRoZSByZXN0IG9mIHN1YmlkZW50aWZpZXJzCisgICAgICAgIGZvciAoaW50IGkgPSAyOyBpIDwgb2lkLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAob2lkW2ldID09IDApIHsKKyAgICAgICAgICAgICAgICBsZW5ndGgrKzsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZvciAoZWxlbSA9IG9pZFtpXTsgZWxlbSA+IDA7IGVsZW0gPSBlbGVtID4+IDcpIHsKKyAgICAgICAgICAgICAgICBsZW5ndGgrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBvdXQubGVuZ3RoID0gbGVuZ3RoOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFTTjFPaWQgU1RSSU5HX09JRCA9IG5ldyBBU04xT2lkKCkgeworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCisgICAgICAgICAgICAvL1NwZWNpYWwgaGFuZGxpbmcgZm9yIHRoZSBmaXJzdCBwYWNrZWQgT0lEIGVsZW1lbnQKKyAgICAgICAgICAgIGludCBvY3RldCA9IGluLmJ1ZmZlcltpbi5jb250ZW50T2Zmc2V0XTsKKyAgICAgICAgICAgIGludCBlbGVtZW50ID0gb2N0ZXQgJiAweDdGOworCisgICAgICAgICAgICBpbnQgaW5kZXggPSAwOworICAgICAgICAgICAgd2hpbGUgKChvY3RldCAmIDB4ODApICE9IDApIHsKKyAgICAgICAgICAgICAgICBpbmRleCsrOworICAgICAgICAgICAgICAgIG9jdGV0ID0gaW4uYnVmZmVyW2luLmNvbnRlbnRPZmZzZXQgKyBpbmRleF07CisgICAgICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQgPDwgNyB8IChvY3RldCAmIDB4N0YpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZWxlbWVudCA+IDc5KSB7CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnMicpOworICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJy4nKTsKKyAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGVsZW1lbnQgLSA4MCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoZWxlbWVudCAvIDQwKTsKKyAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCcuJyk7CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChlbGVtZW50ICUgNDApOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB0aGUgcmVzdCBvZiBzdWJpZGVudGlmaWVycworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDI7IGogPCBpbi5vaWRFbGVtZW50OyBqKyspIHsKKyAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCcuJyk7CisKKyAgICAgICAgICAgICAgICBpbmRleCsrOworICAgICAgICAgICAgICAgIG9jdGV0ID0gaW4uYnVmZmVyW2luLmNvbnRlbnRPZmZzZXQgKyBpbmRleF07CisgICAgICAgICAgICAgICAgZWxlbWVudCA9IG9jdGV0ICYgMHg3RjsKKworICAgICAgICAgICAgICAgIHdoaWxlICgob2N0ZXQgJiAweDgwKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGluZGV4Kys7CisgICAgICAgICAgICAgICAgICAgIG9jdGV0ID0gaW4uYnVmZmVyW2luLmNvbnRlbnRPZmZzZXQgKyBpbmRleF07CisgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50IDw8IDcgfCAob2N0ZXQgJiAweDdmKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGVsZW1lbnQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2V0RW5jb2RpbmdDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgICAgIC8vRklYTUUgdGhpcyBpcyBhIHN0dWIgZm9yIGEgd2hpbGUKKyAgICAgICAgICAgIG91dC5jb250ZW50ID0gT2JqZWN0SWRlbnRpZmllci50b0ludEFycmF5KChTdHJpbmcpIG91dC5jb250ZW50KTsKKyAgICAgICAgICAgIHN1cGVyLnNldEVuY29kaW5nQ29udGVudChvdXQpOworICAgICAgICB9CisgICAgfTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgQVNOLjEgT2JqZWN0IElkZW50aWZpZXIgdHlwZSBpbXBsZW1lbnRhdGlvbgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB3b3JrcyB3aXRoIGVuY29kaW5nCisgICAgICogdGhhdCBpcyBtYXBwZWQgdG8gamF2YS5sYW5nLlN0cmluZyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFTTi4xIE9iamVjdCBJZGVudGlmaWVyIHR5cGUgaW1wbGVtZW50YXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEFTTjFPaWQgZ2V0SW5zdGFuY2VGb3JTdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBTVFJJTkdfT0lEOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xUHJpbWl0aXZlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMVByaW1pdGl2ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRkMjUzNzkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMVByaW1pdGl2ZS5qYXZhCkBAIC0wLDAgKzEsNTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292LCBTdGVwYW4gTS4gTWlzaHVyYQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xOworCisKKy8qKgorICogVGhpcyBhYnN0cmFjdCBjbGFzcyBpcyB0aGUgc3VwZXIgY2xhc3MgZm9yIGFsbCBwcmltaXRpdmUgQVNOLjEgdHlwZXMKKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9hc24xLmVsaWJlbC50bS5mci9lbi9zdGFuZGFyZHMvaW5kZXguaHRtIj5BU04uMTwvYT4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEFTTjFQcmltaXRpdmUgZXh0ZW5kcyBBU04xVHlwZSB7CisKKyAgICBwdWJsaWMgQVNOMVByaW1pdGl2ZShpbnQgdGFnTnVtYmVyKSB7CisgICAgICAgIHN1cGVyKHRhZ051bWJlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgcHJvdmlkZWQgaWRlbnRpZmllci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpZGVudGlmaWVyIGlkZW50aWZpZXIgdG8gYmUgdmVyaWZpZWQKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgaWRlbnRpZmllciBjb3JyZXNwb25kIHRvIHByaW1pdGl2ZSBpZGVudGlmaWVyIG9mIHRoaXMKKyAgICAgKiAgICAgQVNOLjEgdHlwZSwgb3RoZXJ3aXNlIGZhbHNlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gY2hlY2tUYWcoaW50IGlkZW50aWZpZXIpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuaWQgPT0gaWRlbnRpZmllcjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmNvZGVBU04oQmVyT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgICBvdXQuZW5jb2RlVGFnKGlkKTsKKyAgICAgICAgZW5jb2RlQ29udGVudChvdXQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xU2VxdWVuY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xU2VxdWVuY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMjljYjU3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFTZXF1ZW5jZS5qYXZhCkBAIC0wLDAgKzEsNTUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292LCBTdGVwYW4gTS4gTWlzaHVyYQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBBU04uMSBTZXF1ZW5jZSB0eXBlLgorICoKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2FzbjEuZWxpYmVsLnRtLmZyL2VuL3N0YW5kYXJkcy9pbmRleC5odG0iPkFTTi4xPC9hPgorICovCitwdWJsaWMgY2xhc3MgQVNOMVNlcXVlbmNlIGV4dGVuZHMgQVNOMVR5cGVDb2xsZWN0aW9uIHsKKworICAgIHB1YmxpYyBBU04xU2VxdWVuY2UoQVNOMVR5cGVbXSB0eXBlKSB7CisgICAgICAgIHN1cGVyKFRBR19TRVFVRU5DRSwgdHlwZSk7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBkZWNvZGUoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGluLnJlYWRTZXF1ZW5jZSh0aGlzKTsKKworICAgICAgICBpZiAoaW4uaXNWZXJpZnkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXREZWNvZGVkT2JqZWN0KGluKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBlbmNvZGVDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LmVuY29kZVNlcXVlbmNlKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldEVuY29kaW5nQ29udGVudChCZXJPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIG91dC5nZXRTZXF1ZW5jZUxlbmd0aCh0aGlzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMVNlcXVlbmNlT2YuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xU2VxdWVuY2VPZi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1NDllYjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMVNlcXVlbmNlT2YuamF2YQpAQCAtMCwwICsxLDU2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdiwgU3RlcGFuIE0uIE1pc2h1cmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKworLyoqCisgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgQVNOLjEgU2VxdWVuY2UgT0YgdHlwZS4KKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9hc24xLmVsaWJlbC50bS5mci9lbi9zdGFuZGFyZHMvaW5kZXguaHRtIj5BU04uMTwvYT4KKyAqLworcHVibGljIGNsYXNzIEFTTjFTZXF1ZW5jZU9mIGV4dGVuZHMgQVNOMVZhbHVlQ29sbGVjdGlvbiB7CisKKyAgICBwdWJsaWMgQVNOMVNlcXVlbmNlT2YoQVNOMVR5cGUgdHlwZSkgeworICAgICAgICBzdXBlcihUQUdfU0VRVUVOQ0UsIHR5cGUpOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZGVjb2RlKEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbi5yZWFkU2VxdWVuY2VPZih0aGlzKTsKKworICAgICAgICBpZiAoaW4uaXNWZXJpZnkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXREZWNvZGVkT2JqZWN0KGluKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBlbmNvZGVDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LmVuY29kZVNlcXVlbmNlT2YodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHZvaWQgc2V0RW5jb2RpbmdDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LmdldFNlcXVlbmNlT2ZMZW5ndGgodGhpcyk7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMVNldC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFTZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZmYwYzY0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFTZXQuamF2YQpAQCAtMCwwICsxLDU1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdiwgU3RlcGFuIE0uIE1pc2h1cmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKworLyoqCisgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgQVNOLjEgU2V0IHR5cGUuCisgKgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vYXNuMS5lbGliZWwudG0uZnIvZW4vc3RhbmRhcmRzL2luZGV4Lmh0bSI+QVNOLjE8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBBU04xU2V0IGV4dGVuZHMgQVNOMVR5cGVDb2xsZWN0aW9uIHsKKworICAgIHB1YmxpYyBBU04xU2V0KEFTTjFUeXBlW10gdHlwZSkgeworICAgICAgICBzdXBlcihUQUdfU0VULCB0eXBlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGRlY29kZShCZXJJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW4ucmVhZFNldCh0aGlzKTsKKworICAgICAgICBpZihpbi5pc1ZlcmlmeSl7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0RGVjb2RlZE9iamVjdChpbik7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHZvaWQgZW5jb2RlQ29udGVudChCZXJPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIG91dC5lbmNvZGVTZXQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHZvaWQgc2V0RW5jb2RpbmdDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LmdldFNldExlbmd0aCh0aGlzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMVNldE9mLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMVNldE9mLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGFmMjIxYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xU2V0T2YuamF2YQpAQCAtMCwwICsxLDU2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdiwgU3RlcGFuIE0uIE1pc2h1cmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKworLyoqCisgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgQVNOLjEgU2V0T2YgdHlwZS4KKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9hc24xLmVsaWJlbC50bS5mci9lbi9zdGFuZGFyZHMvaW5kZXguaHRtIj5BU04uMTwvYT4KKyAqLworcHVibGljIGNsYXNzIEFTTjFTZXRPZiBleHRlbmRzIEFTTjFWYWx1ZUNvbGxlY3Rpb24geworCisgICAgcHVibGljIEFTTjFTZXRPZihBU04xVHlwZSB0eXBlKSB7CisgICAgICAgIHN1cGVyKFRBR19TRVRPRiwgdHlwZSk7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBkZWNvZGUoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGluLnJlYWRTZXRPZih0aGlzKTsKKworICAgICAgICBpZiAoaW4uaXNWZXJpZnkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXREZWNvZGVkT2JqZWN0KGluKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBlbmNvZGVDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LmVuY29kZVNldE9mKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldEVuY29kaW5nQ29udGVudChCZXJPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIG91dC5nZXRTZXRPZkxlbmd0aCh0aGlzKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xU3RyaW5nVHlwZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFTdHJpbmdUeXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzFmNWIwZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xU3RyaW5nVHlwZS5qYXZhCkBAIC0wLDAgKzEsMTIwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdiwgU3RlcGFuIE0uIE1pc2h1cmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0czsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIHRoZSBzdXBlciBjbGFzcyBmb3IgYWxsIHN0cmluZyBBU04uMSB0eXBlcworICoKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2FzbjEuZWxpYmVsLnRtLmZyL2VuL3N0YW5kYXJkcy9pbmRleC5odG0iPkFTTi4xPC9hPgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQVNOMVN0cmluZ1R5cGUgZXh0ZW5kcyBBU04xVHlwZSB7CisKKyAgICAvLyBUT0RPOiB3aGF0IGFib3V0IGRlZmluaW5nIHRoZW0gYXMgc2VwYXJhdGUgY2xhc3Nlcz8KKyAgICAvLyBUT0RPOiBjaGVjayBkZWNvZGVkL2VuY29kZWQgY2hhcmFjdGVycworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVN0cmluZ1R5cGUgQk1QU1RSSU5HID0gbmV3IEFTTjFTdHJpbmdUeXBlKAorICAgICAgICAgICAgVEFHX0JNUFNUUklORykgeworICAgIH07CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTdHJpbmdUeXBlIElBNVNUUklORyA9IG5ldyBBU04xU3RyaW5nVHlwZSgKKyAgICAgICAgICAgIFRBR19JQTVTVFJJTkcpIHsKKyAgICB9OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xU3RyaW5nVHlwZSBHRU5FUkFMU1RSSU5HID0gbmV3IEFTTjFTdHJpbmdUeXBlKAorICAgICAgICAgICAgVEFHX0dFTkVSQUxTVFJJTkcpIHsKKyAgICB9OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xU3RyaW5nVHlwZSBQUklOVEFCTEVTVFJJTkcgPSBuZXcgQVNOMVN0cmluZ1R5cGUoCisgICAgICAgICAgICBUQUdfUFJJTlRBQkxFU1RSSU5HKSB7CisgICAgfTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVN0cmluZ1R5cGUgVEVMRVRFWFNUUklORyA9IG5ldyBBU04xU3RyaW5nVHlwZSgKKyAgICAgICAgICAgIFRBR19URUxFVEVYU1RSSU5HKSB7CisgICAgfTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVN0cmluZ1R5cGUgVU5JVkVSU0FMU1RSSU5HID0gbmV3IEFTTjFTdHJpbmdUeXBlKAorICAgICAgICAgICAgVEFHX1VOSVZFUlNBTFNUUklORykgeworICAgIH07CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTdHJpbmdUeXBlIFVURjhTVFJJTkcgPSBuZXcgQVNOMVN0cmluZ1R5cGUoVEFHX1VURjhTVFJJTkcpIHsKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGluLmJ1ZmZlciwgaW4uY29udGVudE9mZnNldCwgaW4ubGVuZ3RoLCBDaGFyc2V0cy5VVEZfOCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2V0RW5jb2RpbmdDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBieXRlcyA9ICgoU3RyaW5nKSBvdXQuY29udGVudCkuZ2V0Qnl0ZXMoQ2hhcnNldHMuVVRGXzgpOworICAgICAgICAgICAgb3V0LmNvbnRlbnQgPSBieXRlczsKKyAgICAgICAgICAgIG91dC5sZW5ndGggPSBieXRlcy5sZW5ndGg7CisgICAgICAgIH0KKyAgICB9OworCisgICAgcHVibGljIEFTTjFTdHJpbmdUeXBlKGludCB0YWdOdW1iZXIpIHsKKyAgICAgICAgc3VwZXIodGFnTnVtYmVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBwcm92aWRlZCBpZGVudGlmaWVyLgorICAgICAqCisgICAgICogQHBhcmFtIGlkZW50aWZpZXIgaWRlbnRpZmllciB0byBiZSB2ZXJpZmllZAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBpZGVudGlmaWVyIGNvcnJlc3BvbmQgdG8gcHJpbWl0aXZlIG9yIGNvbnN0cnVjdGVkCisgICAgICogICAgIGlkZW50aWZpZXIgb2YgdGhpcyBBU04uMSBzdHJpbmcgdHlwZSwgb3RoZXJ3aXNlIGZhbHNlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gY2hlY2tUYWcoaW50IGlkZW50aWZpZXIpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuaWQgPT0gaWRlbnRpZmllciB8fCB0aGlzLmNvbnN0cklkID09IGlkZW50aWZpZXI7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBkZWNvZGUoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGluLnJlYWRTdHJpbmcodGhpcyk7CisKKyAgICAgICAgaWYgKGluLmlzVmVyaWZ5KSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0RGVjb2RlZE9iamVjdChpbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXh0cmFjdHMgU3RyaW5nIG9iamVjdCBmcm9tIEJFUiBpbnB1dCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvKiBUbyBlbnN1cmUgd2UgZ2V0IHRoZSBjb3JyZWN0IGVuY29kaW5nIG9uIG5vbi1BU0NJSSBwbGF0Zm9ybXMsIHNwZWNpZnkKKyAgICAgICAgICAgdGhhdCB3ZSB3aXNoIHRvIGNvbnZlcnQgZnJvbSBBU0NJSSB0byB0aGUgZGVmYXVsdCBwbGF0Zm9ybSBlbmNvZGluZyAqLworICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhpbi5idWZmZXIsIGluLmNvbnRlbnRPZmZzZXQsIGluLmxlbmd0aCwgQ2hhcnNldHMuSVNPXzg4NTlfMSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5jb2RlQVNOKEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LmVuY29kZVRhZyhpZCk7CisgICAgICAgIGVuY29kZUNvbnRlbnQob3V0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmNvZGVDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LmVuY29kZVN0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nQ29udGVudChCZXJPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIGJ5dGVbXSBieXRlcyA9ICgoU3RyaW5nKSBvdXQuY29udGVudCkuZ2V0Qnl0ZXMoQ2hhcnNldHMuVVRGXzgpOworICAgICAgICBvdXQuY29udGVudCA9IGJ5dGVzOworICAgICAgICBvdXQubGVuZ3RoID0gYnl0ZXMubGVuZ3RoOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xVGltZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFUaW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzMwY2FjNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xVGltZS5qYXZhCkBAIC0wLDAgKzEsNTQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFN0ZXBhbiBNLiBNaXNodXJhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjE7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLlRpbWVab25lOworCisKKy8qKgorICogQWJzdHJhY3QgY2xhc3MgdG8gcmVwcmVzZW50IEFTTi4xIHRpbWUgdHlwZXMKKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9hc24xLmVsaWJlbC50bS5mci9lbi9zdGFuZGFyZHMvaW5kZXguaHRtIj5BU04uMTwvYT4KKyAqLworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQVNOMVRpbWUgZXh0ZW5kcyBBU04xU3RyaW5nVHlwZSB7CisKKyAgICBwdWJsaWMgQVNOMVRpbWUoaW50IHRhZ051bWJlcikgeworICAgICAgICBzdXBlcih0YWdOdW1iZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEdyZWdvcmlhbkNhbGVuZGFyIGMgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkdNVCIpKTsKKyAgICAgICAgYy5zZXQoQ2FsZW5kYXIuWUVBUiwgaW4udGltZXNbMF0pOworICAgICAgICBjLnNldChDYWxlbmRhci5NT05USCwgaW4udGltZXNbMV0tMSk7CisgICAgICAgIGMuc2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCwgaW4udGltZXNbMl0pOworICAgICAgICBjLnNldChDYWxlbmRhci5IT1VSX09GX0RBWSwgaW4udGltZXNbM10pOworICAgICAgICBjLnNldChDYWxlbmRhci5NSU5VVEUsIGluLnRpbWVzWzRdKTsKKyAgICAgICAgYy5zZXQoQ2FsZW5kYXIuU0VDT05ELCBpbi50aW1lc1s1XSk7CisgICAgICAgIGMuc2V0KENhbGVuZGFyLk1JTExJU0VDT05ELCBpbi50aW1lc1s2XSk7CisgICAgICAgIHJldHVybiBjLmdldFRpbWUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMVR5cGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xVHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJjNTBmNWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMVR5cGUuamF2YQpAQCAtMCwwICsxLDE3MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YsIFN0ZXBhbiBNLiBNaXNodXJhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjE7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKKworLyoqCisgKiBUaGlzIGFic3RyYWN0IGNsYXNzIGlzIHRoZSBzdXBlciBjbGFzcyBmb3IgYWxsIEFTTi4xIHR5cGVzCisgKgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vYXNuMS5lbGliZWwudG0uZnIvZW4vc3RhbmRhcmRzL2luZGV4Lmh0bSI+QVNOLjE8L2E+CisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBBU04xVHlwZSBpbXBsZW1lbnRzIEFTTjFDb25zdGFudHMgeworCisgICAgLyoqIEludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgcHJpbWl0aXZlIGlkZW50aWZpZXIuICovCisgICAgcHVibGljIGZpbmFsIGludCBpZDsKKworICAgIC8qKiBJbnRlZ2VyIHJlcHJlc2VudGF0aW9uIG9mIGNvbnN0cnVjdGVkIGlkZW50aWZpZXIuICovCisgICAgcHVibGljIGZpbmFsIGludCBjb25zdHJJZDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBwcmltaXRpdmUsIHVuaXZlcnNhbCBBU04uMSB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIHRhZ051bWJlciAtIEFTTi4xIHRhZyBudW1iZXIKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAtIGlmIHRhZ051bWJlciBpcyBpbnZhbGlkCisgICAgICovCisgICAgcHVibGljIEFTTjFUeXBlKGludCB0YWdOdW1iZXIpIHsKKyAgICAgICAgdGhpcyhDTEFTU19VTklWRVJTQUwsIHRhZ051bWJlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBBU04uMSB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIHRhZ0NsYXNzIC0gdGFnIGNsYXNzLiBNVVNUIGJlCisgICAgICogICAgIENMQVNTX1VOSVZFUlNBTCwgQ0xBU1NfQVBQTElDQVRJT04sIENMQVNTX0NPTlRFWFRTUEVDSUZJQywgQ0xBU1NfUFJJVkFURQorICAgICAqIEBwYXJhbSB0YWdOdW1iZXIgLSBBU04uMSB0YWcgbnVtYmVyLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIC0gaWYgdGFnQ2xhc3Mgb3IgdGFnTnVtYmVyIGlzIGludmFsaWQKKyAgICAgKi8KKyAgICBwdWJsaWMgQVNOMVR5cGUoaW50IHRhZ0NsYXNzLCBpbnQgdGFnTnVtYmVyKSB7CisgICAgICAgIGlmICh0YWdOdW1iZXIgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ0YWdOdW1iZXIgPCAwIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAodGFnQ2xhc3MgIT0gQ0xBU1NfVU5JVkVSU0FMICYmIHRhZ0NsYXNzICE9IENMQVNTX0FQUExJQ0FUSU9OCisgICAgICAgICAgICAgICAgJiYgdGFnQ2xhc3MgIT0gQ0xBU1NfQ09OVEVYVFNQRUNJRklDCisgICAgICAgICAgICAgICAgJiYgdGFnQ2xhc3MgIT0gQ0xBU1NfUFJJVkFURSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaW52YWxpZCB0YWdDbGFzcyIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHRhZ051bWJlciA8IDMxKSB7CisgICAgICAgICAgICAvLyBzaG9ydCBmb3JtCisgICAgICAgICAgICB0aGlzLmlkID0gdGFnQ2xhc3MgKyB0YWdOdW1iZXI7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBsb25nIGZvcm0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInRhZyBsb25nIGZvcm0gbm90IGltcGxlbWVudGVkIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5jb25zdHJJZCA9IHRoaXMuaWQgKyBQQ19DT05TVFJVQ1RFRDsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgT2JqZWN0IGRlY29kZShieXRlW10gZW5jb2RlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGRlY29kZShuZXcgRGVySW5wdXRTdHJlYW0oZW5jb2RlZCkpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBPYmplY3QgZGVjb2RlKGJ5dGVbXSBlbmNvZGVkLCBpbnQgb2Zmc2V0LCBpbnQgZW5jb2RpbmdMZW4pCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gZGVjb2RlKG5ldyBEZXJJbnB1dFN0cmVhbShlbmNvZGVkLCBvZmZzZXQsIGVuY29kaW5nTGVuKSk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIE9iamVjdCBkZWNvZGUoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBkZWNvZGUobmV3IERlcklucHV0U3RyZWFtKGluKSk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHZvaWQgdmVyaWZ5KGJ5dGVbXSBlbmNvZGVkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBEZXJJbnB1dFN0cmVhbSBkZWNvZGVyID0gbmV3IERlcklucHV0U3RyZWFtKGVuY29kZWQpOworICAgICAgICBkZWNvZGVyLnNldFZlcmlmeSgpOworICAgICAgICBkZWNvZGUoZGVjb2Rlcik7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHZvaWQgdmVyaWZ5KElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBEZXJJbnB1dFN0cmVhbSBkZWNvZGVyID0gbmV3IERlcklucHV0U3RyZWFtKGluKTsKKyAgICAgICAgZGVjb2Rlci5zZXRWZXJpZnkoKTsKKyAgICAgICAgZGVjb2RlKGRlY29kZXIpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBieXRlW10gZW5jb2RlKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgRGVyT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBEZXJPdXRwdXRTdHJlYW0odGhpcywgb2JqZWN0KTsKKyAgICAgICAgcmV0dXJuIG91dC5lbmNvZGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlY29kZXMgQVNOLjEgdHlwZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3VycyBvciB0aGUgZW5kIG9mIHRoZSBzdHJlYW0gaXMgcmVhY2hlZAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBPYmplY3QgZGVjb2RlKEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBwcm92aWRlZCBpZGVudGlmaWVyLgorICAgICAqCisgICAgICogQHBhcmFtIGlkZW50aWZpZXIgaWRlbnRpZmllciB0byBiZSB2ZXJpZmllZAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBpZGVudGlmaWVyIGlzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEFTTi4xIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBjaGVja1RhZyhpbnQgaWRlbnRpZmllcik7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGRlY29kZWQgb2JqZWN0LgorICAgICAqCisgICAgICogRGVyaXZlZCBjbGFzc2VzIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZCB0byBwcm92aWRlIGNyZWF0aW9uIGZvciBhCisgICAgICogc2VsZWN0ZWQgY2xhc3Mgb2Ygb2JqZWN0cyBkdXJpbmcgZGVjb2RpbmcuCisgICAgICoKKyAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIGFuIG9iamVjdCBjcmVhdGVkIGJ5IGRlY29kaW5nIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBpbi5jb250ZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuY29kZXMgQVNOLjEgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBlbmNvZGVBU04oQmVyT3V0cHV0U3RyZWFtIG91dCk7CisKKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBlbmNvZGVDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpOworCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RW5jb2RpbmdDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpOworCisgICAgcHVibGljIGludCBnZXRFbmNvZGVkTGVuZ3RoKEJlck91dHB1dFN0cmVhbSBvdXQpIHsgLy9GSVhNRSBuYW1lCisgICAgICAgIC8vdGFnIGxlbmd0aAorICAgICAgICBpbnQgbGVuID0gMTsgLy9GSVhNRSB0YWcgbGVuZ3RoID0gMS4gd2hhdCBhYm91dCBsb25nIGZvcm0/CisgICAgICAgIC8vZm9yICg7IHRhZyA+IDA7IHRhZyA9IHRhZyA+PiA4LCBsZW4rKyk7CisKKyAgICAgICAgLy8gbGVuZ3RoIGxlbmd0aCA6LSkKKyAgICAgICAgbGVuKys7CisgICAgICAgIGlmIChvdXQubGVuZ3RoID4gMTI3KSB7CisKKyAgICAgICAgICAgIGxlbisrOworICAgICAgICAgICAgZm9yIChpbnQgY3VyID0gb3V0Lmxlbmd0aCA+PiA4OyBjdXIgPiAwOyBsZW4rKykgeworICAgICAgICAgICAgICAgIGN1ciA9IGN1ciA+PiA4OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGxlbiArPSBvdXQubGVuZ3RoOworCisgICAgICAgIHJldHVybiBsZW47CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIC8vIFRPRE8gZGVjaWRlIHdoZXRoZXIgdGhpcyBtZXRob2QgaXMgbmVjZXNzYXJ5CisgICAgICAgIHJldHVybiBnZXRDbGFzcygpLmdldE5hbWUoKSArICIodGFnOiAweCIgKyBJbnRlZ2VyLnRvSGV4U3RyaW5nKDB4ZmYgJiB0aGlzLmlkKSArICIpIjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMVR5cGVDb2xsZWN0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMVR5cGVDb2xsZWN0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjQ5OWZhMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xVHlwZUNvbGxlY3Rpb24uamF2YQpAQCAtMCwwICsxLDg4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdiwgU3RlcGFuIE0uIE1pc2h1cmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMTsKKworCisvKioKKyAqIFRoaXMgYWJzdHJhY3QgY2xhc3MgcmVwcmVzZW50cyBBU04uMSB0eXBlIHRoYXQgaXMgYSBjb2xsZWN0aW9uIG9mIEFTTi4xIHR5cGVzLgorICoKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2FzbjEuZWxpYmVsLnRtLmZyL2VuL3N0YW5kYXJkcy9pbmRleC5odG0iPkFTTi4xPC9hPgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQVNOMVR5cGVDb2xsZWN0aW9uIGV4dGVuZHMgQVNOMUNvbnN0cnVjdGVkIHsKKworICAgIHB1YmxpYyBmaW5hbCBBU04xVHlwZVtdIHR5cGU7CisKKyAgICBwdWJsaWMgZmluYWwgYm9vbGVhbltdIE9QVElPTkFMOworCisgICAgcHVibGljIGZpbmFsIE9iamVjdFtdIERFRkFVTFQ7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIEFTTi4xIGNvbGxlY3Rpb24gdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YWdOdW1iZXIgQVNOLjEgdGFnIG51bWJlcgorICAgICAqIEBwYXJhbSB0eXBlIGEgY29sbGVjdGlvbiBvZiBvbmUgb3IgbW9yZSBBU04uMSB0eXBlcy4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0YWdOdW1iZXIgaXMgaW52YWxpZAorICAgICAqLworICAgIHByb3RlY3RlZCBBU04xVHlwZUNvbGxlY3Rpb24oaW50IHRhZ051bWJlciwgQVNOMVR5cGVbXSB0eXBlKSB7CisgICAgICAgIHN1cGVyKHRhZ051bWJlcik7CisgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgICAgIHRoaXMuT1BUSU9OQUwgPSBuZXcgYm9vbGVhblt0eXBlLmxlbmd0aF07CisgICAgICAgIHRoaXMuREVGQVVMVCA9IG5ldyBPYmplY3RbdHlwZS5sZW5ndGhdOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgYSBjb2xsZWN0aW9uIGNvbXBvbmVudCBhcyBvcHRpb25hbAorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IGFuIGluZGV4IG9mIGEgY29tcG9uZW50CisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0T3B0aW9uYWwoaW50IGluZGV4KSB7CisgICAgICAgIE9QVElPTkFMW2luZGV4XSA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBhIGRlZmF1bHQgdmFsdWUgZm9yIGEgY29sbGVjdGlvbiBjb21wb25lbnQuCisgICAgICogVGhlIGNvbXBvbmVudCBhbHNvIGJlY2FtZSBhbiBvcHRpb25hbCBjb21wb25lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0IGEgY29tcG9uZW50J3MgZGVmYXVsdCB2YWx1ZQorICAgICAqIEBwYXJhbSBpbmRleCBhbiBpbmRleCBvZiBhIGNvbXBvbmVudAorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIHNldERlZmF1bHQoT2JqZWN0IG9iamVjdCwgaW50IGluZGV4KSB7CisgICAgICAgIE9QVElPTkFMW2luZGV4XSA9IHRydWU7CisgICAgICAgIERFRkFVTFRbaW5kZXhdID0gb2JqZWN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb3ZpZGVzIGFuIG9iamVjdCdzIHZhbHVlcyB0byBiZSBlbmNvZGVkCisgICAgICoKKyAgICAgKiBEZXJpdmVkIGNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIHByb3ZpZGUKKyAgICAgKiBlbmNvZGluZyBmb3IgYSBzZWxlY3RlZCBjbGFzcyBvZiBvYmplY3RzLgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0IGFuIG9iamVjdCB0byBiZSBlbmNvZGVkCisgICAgICogQHBhcmFtIHZhbHVlcyBhbiBhcnJheSB0byBzdG9yZSBhbiBvYmplY3QncyB2YWx1ZXMgdG8gYmUgZW5jb2RlZAorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkFTTi4xIHR5cGUgaXMgbm90IGRlc2lnbmVkIHRvIGJlIGVuY29kZWQ6ICIgKyBnZXRDbGFzcygpLmdldE5hbWUoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFVVENUaW1lLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQVNOMVVUQ1RpbWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYmM4ZjRiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFVVENUaW1lLmphdmEKQEAgLTAsMCArMSwxMDIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjE7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldHM7CitpbXBvcnQgamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQ7CitpbXBvcnQgamF2YS51dGlsLlRpbWVab25lOworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBBU04uMSBVVENUaW1lIHR5cGUKKyAqCisgKiBAc2VlIGh0dHA6Ly9hc24xLmVsaWJlbC50bS5mci9lbi9zdGFuZGFyZHMvaW5kZXguaHRtCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBBU04xVVRDVGltZSBleHRlbmRzIEFTTjFUaW1lIHsKKworICAgIC8qKiBMZW5ndGggZm9yIHRoZSBwYXR0ZXJuOiBZWU1NRERoaG1tJ1onICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVVRDX0hNID0gMTE7CisKKyAgICAvKiogTGVuZ3RoIGZvciB0aGUgcGF0dGVybjogWVlNTUREaGhtbXNzJ1onICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVVRDX0hNUyA9IDEzOworCisgICAgLyoqIExlbmd0aCBmb3IgdGhlIHBhdHRlcm46IFlZTU1ERGhobW0oJysnLyctJyloaG1tICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVVRDX0xPQ0FMX0hNID0gMTU7CisKKyAgICAvKiogTGVuZ3RoIGZvciB0aGUgcGF0dGVybjogWVlNTUREaGhtbXNzKCcrJy8nLScpaGhtbSAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVUQ19MT0NBTF9ITVMgPSAxNzsKKworICAgIC8qKiBkZWZhdWx0IGltcGxlbWVudGF0aW9uICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQVNOMVVUQ1RpbWUgQVNOMSA9IG5ldyBBU04xVVRDVGltZSgpOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBBU04uMSBVVENUaW1lIHR5cGUKKyAgICAgKgorICAgICAqIFRoZSBjb25zdHJ1Y3RvciBpcyBwcm92aWRlZCBmb3IgaW5oZXJpdGFuY2UgcHVycG9zZXMKKyAgICAgKiB3aGVuIHRoZXJlIGlzIGEgbmVlZCB0byBjcmVhdGUgYSBjdXN0b20gQVNOLjEgVVRDVGltZSB0eXBlLgorICAgICAqIFRvIGdldCBhIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gaXQgaXMgcmVjb21tZW5kZWQgdG8gdXNlCisgICAgICogZ2V0SW5zdGFuY2UoKSBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIEFTTjFVVENUaW1lKCkgeworICAgICAgICBzdXBlcihUQUdfVVRDVElNRSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBVVENUaW1lIHR5cGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gd29ya3Mgd2l0aCBlbmNvZGluZworICAgICAqIHRoYXQgaXMgcmVwcmVzZW50ZWQgYXMgRGF0ZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFTTi4xIFVUQ1RpbWUgdHlwZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBBU04xVVRDVGltZSBnZXRJbnN0YW5jZSgpIHsKKyAgICAgICAgcmV0dXJuIEFTTjE7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZGVjb2RlKEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbi5yZWFkVVRDVGltZSgpOworCisgICAgICAgIGlmIChpbi5pc1ZlcmlmeSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldERlY29kZWRPYmplY3QoaW4pOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBlbmNvZGVDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LmVuY29kZVVUQ1RpbWUoKTsKKyAgICB9CisKKyAgICAvLyBGSVhNRSBzdXBwb3J0IG9ubHkgb25lIGZvcm1hdCBmb3IgZW5jb2RpbmcsIGRvIHdlIG5lZWQgb3RoZXJzPworICAgIC8vCisgICAgLy8gQWNjb3JkaW5nIHRvIFguNjgwIGNvb3JkaW5hdGVkIHVuaXZlcnNhbCB0aW1lIGZvcm1hdDoKKyAgICAvLyB0d28gZGlnaXQgeWVhciwgc2Vjb25kcyBhbHdheXMgcHJlc2VudGVkLAorICAgIC8vIG5vIGZyYWN0aW9uYWwtc2Vjb25kcyBlbGVtZW50cywgJ1onIGF0IHRoZSBlbmQKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVRDX1BBVFRFUk4gPSAieXlNTWRkSEhtbXNzJ1onIjsKKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZ0NvbnRlbnQoQmVyT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IHNkZiA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KFVUQ19QQVRURVJOKTsKKyAgICAgICAgc2RmLnNldFRpbWVab25lKFRpbWVab25lLmdldFRpbWVab25lKCJVVEMiKSk7CisgICAgICAgIG91dC5jb250ZW50ID0gc2RmLmZvcm1hdChvdXQuY29udGVudCkuZ2V0Qnl0ZXMoQ2hhcnNldHMuVVRGXzgpOworICAgICAgICBvdXQubGVuZ3RoID0gKChieXRlW10pIG91dC5jb250ZW50KS5sZW5ndGg7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0FTTjFWYWx1ZUNvbGxlY3Rpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xVmFsdWVDb2xsZWN0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzUxODg4YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9BU04xVmFsdWVDb2xsZWN0aW9uLmphdmEKQEAgLTAsMCArMSw2MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YsIFN0ZXBhbiBNLiBNaXNodXJhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjE7CisKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKKworCisvKioKKyAqIFRoaXMgYWJzdHJhY3QgY2xhc3MgcmVwcmVzZW50cyBBU04uMSBjb2xsZWN0aW9uIHR5cGUuCisgKgorICogVGhlIHZhbHVlIGZvciBzdWNoIHR5cGUgaXMgYSBjb2xsZWN0aW9uIG9mIHplcm8gb3IKKyAqIG1vcmUgb2NjdXJyZW5jZXMgb2YgYSBwcm92aWRlZCB0eXBlLgorICoKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2FzbjEuZWxpYmVsLnRtLmZyL2VuL3N0YW5kYXJkcy9pbmRleC5odG0iPkFTTi4xPC9hPgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQVNOMVZhbHVlQ29sbGVjdGlvbiBleHRlbmRzIEFTTjFDb25zdHJ1Y3RlZCB7CisKKyAgICAvKiogQSB2YWx1ZSBjb2xsZWN0aW9uIG9mIHRoaXMgQVNOLjEgdHlwZSAqLworICAgIHB1YmxpYyBmaW5hbCBBU04xVHlwZSB0eXBlOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBBU04xIGNvbGxlY3Rpb24gdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQVNOMVZhbHVlQ29sbGVjdGlvbihpbnQgdGFnTnVtYmVyLCBBU04xVHlwZSB0eXBlKSB7CisgICAgICAgIHN1cGVyKHRhZ051bWJlcik7CisgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvdmlkZXMgYW4gb2JqZWN0J3MgdmFsdWVzIHRvIGJlIGVuY29kZWQKKyAgICAgKgorICAgICAqIERlcml2ZWQgY2xhc3NlcyBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcHJvdmlkZQorICAgICAqIGVuY29kaW5nIGZvciBhIHNlbGVjdGVkIGNsYXNzIG9mIG9iamVjdHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gLSBhbiBvYmplY3QgdG8gYmUgZW5jb2RlZAorICAgICAqIEByZXR1cm4gLSBhIGNvbGxlY3Rpb24gb2Ygb2JqZWN0J3MgdmFsdWVzIHRvIGJlIGVuY29kZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sbGVjdGlvbjw/PiBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICByZXR1cm4gKENvbGxlY3Rpb248Pz4pIG9iamVjdDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQmVySW5wdXRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9CZXJJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRjMWZkMzcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQmVySW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDgzNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YsIFN0ZXBhbiBNLiBNaXNodXJhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjE7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKKworCisvKioKKyAqIERlY29kZXMgQVNOLjEgdHlwZXMgZW5jb2RlZCB3aXRoIEJFUiAoWC42OTApCisgKgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vYXNuMS5lbGliZWwudG0uZnIvZW4vc3RhbmRhcmRzL2luZGV4Lmh0bSI+QVNOLjE8L2E+CisgKi8KKworcHVibGljIGNsYXNzIEJlcklucHV0U3RyZWFtIHsKKworICAgIHByaXZhdGUgZmluYWwgSW5wdXRTdHJlYW0gaW47CisgICAgcHJvdGVjdGVkIGJ5dGVbXSBidWZmZXI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcG9zaXRpb24gaW4gdGhlIGJ1ZmZlci4KKyAgICAgKiBOZXh0IHJlYWQgbXVzdCBwbGFjZSBkYXRhIGludG8gdGhlIGJ1ZmZlciBmcm9tIHRoaXMgb2Zmc2V0CisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBvZmZzZXQgPSAwOworCisgICAgLyoqCisgICAgICogVGhlIGJ1ZmZlciBpbmNyZW1lbnQgc2l6ZS4KKyAgICAgKiBNdXN0IGJlIHJlYXNvbmFibGUgYmlnIHRvIHJlYWxsb2NhdGUgbWVtb3J5IG5vdCB0byBvZnRlbi4KKyAgICAgKiBQcmltYXJ5IGlzIHVzZWQgZm9yIGRlY29kaW5nIGluZGVmaW5pdGUgbGVuZ3RoIGVuY29kaW5nCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJVRl9JTkNSRUFTRV9TSVpFID0gMTAyNCAqIDE2OworCisgICAgLyoqIEluZGljYXRlcyBpbmRlZmluaXRlIGxlbmd0aCBvZiB0aGUgY3VycmVudCB0eXBlICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgSU5ERUZJTklUX0xFTkdUSCA9IC0xOworCisgICAgLyoqIEN1cnJlbnQgZGVjb2RlZCB0YWcgKi8KKyAgICBwdWJsaWMgaW50IHRhZzsKKworICAgIC8qKiBDdXJyZW50IGRlY29kZWQgbGVuZ3RoICovCisgICAgcHJvdGVjdGVkIGludCBsZW5ndGg7CisKKyAgICAvKiogQ3VycmVudCBkZWNvZGVkIGNvbnRlbnQgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGNvbnRlbnQ7CisKKyAgICAvKiogQ3VycmVudCBkZWNvZGVkIHRhZyBvZmZzZXQgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHRhZ09mZnNldDsKKworICAgIC8qKiBDdXJyZW50IGRlY29kZWQgY29udGVudCBvZmZzZXQgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGNvbnRlbnRPZmZzZXQ7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHN0cmVhbSBmb3IgZGVjb2RpbmcuCisgICAgICovCisgICAgcHVibGljIEJlcklucHV0U3RyZWFtKGJ5dGVbXSBlbmNvZGVkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKGVuY29kZWQsIDAsIGVuY29kZWQubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHN0cmVhbSBmb3IgZGVjb2RpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW5jb2RlZCBieXRlcyBhcnJheSB0byBiZSBkZWNvZGVkCisgICAgICogQHBhcmFtIG9mZnNldCB0aGUgZW5jb2Rpbmcgb2Zmc2V0CisgICAgICogQHBhcmFtIGV4cGVjdGVkTGVuZ3RoIGV4cGVjdGVkIGxlbmd0aCBvZiBmdWxsIGVuY29kaW5nLCB0aGlzIGluY2x1ZGVzCisgICAgICogICAgIGlkZW50aWZpZXIsIGxlbmd0aCBhbiBjb250ZW50IG9jdGV0cworICAgICAqLworICAgIHB1YmxpYyBCZXJJbnB1dFN0cmVhbShieXRlW10gZW5jb2RlZCwgaW50IG9mZnNldCwgaW50IGV4cGVjdGVkTGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLmluID0gbnVsbDsKKyAgICAgICAgdGhpcy5idWZmZXIgPSBlbmNvZGVkOworICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDsKKworICAgICAgICBuZXh0KCk7CisKKyAgICAgICAgLy8gY29tcGFyZSBleHBlY3RlZCBhbmQgZGVjb2RlZCBsZW5ndGgKKyAgICAgICAgaWYgKGxlbmd0aCAhPSBJTkRFRklOSVRfTEVOR1RICisgICAgICAgICAgICAgICAgJiYgKG9mZnNldCArIGV4cGVjdGVkTGVuZ3RoKSAhPSAodGhpcy5vZmZzZXQgKyB0aGlzLmxlbmd0aCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJXcm9uZyBjb250ZW50IGxlbmd0aCIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBzdHJlYW0gZm9yIGRlY29kaW5nLgorICAgICAqCisgICAgICogQWxsb2NhdGVzIGluaXRpYWwgYnVmZmVyIG9mIGRlZmF1bHQgc2l6ZQorICAgICAqLworICAgIHB1YmxpYyBCZXJJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhpbiwgQlVGX0lOQ1JFQVNFX1NJWkUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgc3RyZWFtIGZvciBkZWNvZGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbml0aWFsU2l6ZSB0aGUgaW50ZXJuYWwgYnVmZmVyIGluaXRpYWwgc2l6ZQorICAgICAqLworICAgIHB1YmxpYyBCZXJJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbiwgaW50IGluaXRpYWxTaXplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLmluID0gaW47CisgICAgICAgIGJ1ZmZlciA9IG5ldyBieXRlW2luaXRpYWxTaXplXTsKKworICAgICAgICBuZXh0KCk7CisKKyAgICAgICAgaWYgKGxlbmd0aCAhPSBJTkRFRklOSVRfTEVOR1RIKSB7CisgICAgICAgICAgICAvLyBpbnB1dCBzdHJlYW0gaGFzIGRlZmluaXRlIGxlbmd0aCBlbmNvZGluZworICAgICAgICAgICAgLy8gY2hlY2sgYWxsb2NhdGVkIGxlbmd0aCB0byBhdm9pZCBmdXJ0aGVyIHJlYWxsb2NhdGlvbnMKKyAgICAgICAgICAgIGlmIChidWZmZXIubGVuZ3RoIDwgKGxlbmd0aCArIG9mZnNldCkpIHsKKyAgICAgICAgICAgICAgICBieXRlW10gbmV3QnVmZmVyID0gbmV3IGJ5dGVbbGVuZ3RoICsgb2Zmc2V0XTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZmZlciwgMCwgbmV3QnVmZmVyLCAwLCBvZmZzZXQpOworICAgICAgICAgICAgICAgIGJ1ZmZlciA9IG5ld0J1ZmZlcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlzSW5kZWZpbmVkTGVuZ3RoID0gdHJ1ZTsKKyAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJEZWNvZGluZyBpbmRlZmluaXRlIGxlbmd0aCBlbmNvZGluZyBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhpcyBzdHJlYW0gdG8gaW5pdGlhbCBzdGF0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbmNvZGVkIGEgbmV3IGJ5dGVzIGFycmF5IHRvIGJlIGRlY29kZWQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHJlc2V0KGJ5dGVbXSBlbmNvZGVkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBidWZmZXIgPSBlbmNvZGVkOworICAgICAgICBuZXh0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVjb2RlcyBuZXh0IGVuY29kZWQgdHlwZS4KKyAgICAgKiBJbml0aWFsaXplcyB0YWcsIGxlbmd0aCwgdGFnT2Zmc2V0IGFuZCBjb250ZW50T2Zmc2V0IHZhcmlhYmxlcworICAgICAqCisgICAgICogQHJldHVybiBuZXh0IGRlY29kZWQgdGFnCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBlcnJvciBvY2N1cmVkCisgICAgICovCisgICAgcHVibGljIGludCBuZXh0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGFnT2Zmc2V0ID0gb2Zmc2V0OworCisgICAgICAgIC8vIHJlYWQgdGFnCisgICAgICAgIHRhZyA9IHJlYWQoKTsKKworICAgICAgICAvLyByZWFkIGxlbmd0aAorICAgICAgICBsZW5ndGggPSByZWFkKCk7CisgICAgICAgIGlmIChsZW5ndGggIT0gMHg4MCkgeyAvLyBkZWZpbml0ZSBmb3JtCisgICAgICAgICAgICAvLyBsb25nIG9yIHNob3J0IGxlbmd0aCBmb3JtCisgICAgICAgICAgICBpZiAoKGxlbmd0aCAmIDB4ODApICE9IDApIHsgLy8gbG9uZyBmb3JtCisgICAgICAgICAgICAgICAgaW50IG51bU9jdGV0cyA9IGxlbmd0aCAmIDB4N0Y7CisKKyAgICAgICAgICAgICAgICBpZiAobnVtT2N0ZXRzID4gNSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiVG9vIGxvbmcgZW5jb2RpbmcgYXQgWyIgKyB0YWdPZmZzZXQgKyAiXSIpOyAvL0ZJWE1FIG1lc3NhZ2UKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBjb2xsZWN0IHRoaXMgdmFsdWUgbGVuZ3RoCisgICAgICAgICAgICAgICAgbGVuZ3RoID0gcmVhZCgpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgbnVtT2N0ZXRzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGNoID0gcmVhZCgpOworICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSAobGVuZ3RoIDw8IDgpICsgY2g7Ly9yZWFkKCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGxlbmd0aCA+IDB4RkZGRkZGKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJUb28gbG9uZyBlbmNvZGluZyBhdCBbIiArIHRhZ09mZnNldCArICJdIik7IC8vRklYTUUgbWVzc2FnZQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsgLy9pbmRlZmluaXRlIGZvcm0KKyAgICAgICAgICAgIGxlbmd0aCA9IElOREVGSU5JVF9MRU5HVEg7CisgICAgICAgIH0KKyAgICAgICAgY29udGVudE9mZnNldCA9IG9mZnNldDsKKworICAgICAgICByZXR1cm4gdGFnOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGUgZW5jb2RpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBnZXRMZW5ndGgoYnl0ZVtdIGVuY29kaW5nKSB7CisgICAgICAgIGludCBsZW5ndGggPSBlbmNvZGluZ1sxXSAmIDB4RkY7CisgICAgICAgIGludCBudW1PY3RldHMgPSAwOworICAgICAgICBpZiAoKGxlbmd0aCAmIDB4ODApICE9IDApIHsgLy8gbG9uZyBmb3JtCisgICAgICAgICAgICBudW1PY3RldHMgPSBsZW5ndGggJiAweDdGOworCisgICAgICAgICAgICAvLyBjb2xsZWN0IHRoaXMgdmFsdWUgbGVuZ3RoCisgICAgICAgICAgICBsZW5ndGggPSBlbmNvZGluZ1syXSAmIDB4RkY7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMzsgaSA8IG51bU9jdGV0cyArIDI7IGkrKykgeworICAgICAgICAgICAgICAgIGxlbmd0aCA9IChsZW5ndGggPDwgOCkgKyAoZW5jb2RpbmdbaV0gJiAweEZGKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyAgICB0YWcgbGVuZ3RoIGxvbmdfZm9ybSBjb250ZW50CisgICAgICAgIHJldHVybiAxICsgMSArIG51bU9jdGV0cyArIGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvZGVzIEFTTi4xIGJpdHN0cmluZyB0eXBlCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVhZEJpdFN0cmluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0YWcgPT0gQVNOMUNvbnN0YW50cy5UQUdfQklUU1RSSU5HKSB7CisKKyAgICAgICAgICAgIGlmIChsZW5ndGggPT0gMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJBU04uMSBCaXRzdHJpbmc6IHdyb25nIGxlbmd0aC4gVGFnIGF0IFsiICsgdGFnT2Zmc2V0ICsgIl0iKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmVhZENvbnRlbnQoKTsKKworICAgICAgICAgICAgLy8gY29udGVudDogY2hlY2sgdW51c2VkIGJpdHMKKyAgICAgICAgICAgIGlmIChidWZmZXJbY29udGVudE9mZnNldF0gPiA3KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIkFTTi4xIEJpdHN0cmluZzogd3JvbmcgY29udGVudCBhdCBbIiArIGNvbnRlbnRPZmZzZXQKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIl0uIEEgbnVtYmVyIG9mIHVudXNlZCBiaXRzIE1VU1QgYmUgaW4gcmFuZ2UgMCB0byA3Iik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChsZW5ndGggPT0gMSAmJiBidWZmZXJbY29udGVudE9mZnNldF0gIT0gMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJBU04uMSBCaXRzdHJpbmc6IHdyb25nIGNvbnRlbnQgYXQgWyIgKyBjb250ZW50T2Zmc2V0CisgICAgICAgICAgICAgICAgICAgICAgICArICJdLiBGb3IgZW1wdHkgc3RyaW5nIHVudXNlZCBiaXRzIE1VU1QgYmUgMCIpOworICAgICAgICAgICAgfQorCisgICAgICAgIH0gZWxzZSBpZiAodGFnID09IEFTTjFDb25zdGFudHMuVEFHX0NfQklUU1RSSU5HKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiRGVjb2RpbmcgY29uc3RydWN0ZWQgQVNOLjEgYml0c3RyaW5nICB0eXBlIGlzIG5vdCBwcm92aWRlZCIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgZXhwZWN0ZWQoImJpdHN0cmluZyIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVjb2RlcyBBU04uMSBFbnVtZXJhdGVkIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZWFkRW51bWVyYXRlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0YWcgIT0gQVNOMUNvbnN0YW50cy5UQUdfRU5VTSkgeworICAgICAgICAgICAgdGhyb3cgZXhwZWN0ZWQoImVudW1lcmF0ZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNoZWNrIGVuY29kZWQgbGVuZ3RoCisgICAgICAgIGlmIChsZW5ndGggPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIkFTTi4xIGVudW1lcmF0ZWQ6IHdyb25nIGxlbmd0aCBmb3IgaWRlbnRpZmllciBhdCBbIgorICAgICAgICAgICAgICAgICAgICArIHRhZ09mZnNldCArICJdIik7CisgICAgICAgIH0KKworICAgICAgICByZWFkQ29udGVudCgpOworCisgICAgICAgIC8vIGNoZWNrIGVuY29kZWQgY29udGVudAorICAgICAgICBpZiAobGVuZ3RoID4gMSkgeworICAgICAgICAgICAgaW50IGJpdHMgPSBidWZmZXJbY29udGVudE9mZnNldF0gJiAweEZGOworICAgICAgICAgICAgaWYgKGJ1ZmZlcltjb250ZW50T2Zmc2V0ICsgMV0gPCAwKSB7CisgICAgICAgICAgICAgICAgYml0cyArPSAweDEwMDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGJpdHMgPT0gMCB8fCBiaXRzID09IDB4MUZGKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIkFTTi4xIGVudW1lcmF0ZWQ6IHdyb25nIGNvbnRlbnQgYXQgWyIgKyBjb250ZW50T2Zmc2V0CisgICAgICAgICAgICAgICAgICAgICAgICArICJdLiBBbiBpbnRlZ2VyIE1VU1QgYmUgZW5jb2RlZCBpbiBtaW5pbXVtIG51bWJlciBvZiBvY3RldHMiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIERlY29kZXMgQVNOLjEgYm9vbGVhbiB0eXBlCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVhZEJvb2xlYW4oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGFnICE9IEFTTjFDb25zdGFudHMuVEFHX0JPT0xFQU4pIHsKKyAgICAgICAgICAgIHRocm93IGV4cGVjdGVkKCJib29sZWFuIik7CisgICAgICAgIH0KKworICAgICAgICAvLyBjaGVjayBlbmNvZGVkIGxlbmd0aAorICAgICAgICBpZiAobGVuZ3RoICE9IDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJXcm9uZyBsZW5ndGggZm9yIEFTTi4xIGJvb2xlYW4gYXQgWyIgKyB0YWdPZmZzZXQgKyAiXSIpOworICAgICAgICB9CisKKyAgICAgICAgcmVhZENvbnRlbnQoKTsKKyAgICB9CisKKyAgICAvKiogVGhlIGxhc3QgY2hvaWNlIGluZGV4ICovCisgICAgcHVibGljIGludCBjaG9pY2VJbmRleDsKKworICAgIC8qKiBLZWVwcyBsYXN0IGRlY29kZWQ6IHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgc2Vjb25kLCBtaWxsaXNlY29uZCAqLworICAgIHB1YmxpYyBpbnRbXSB0aW1lczsKKworICAgIC8qKgorICAgICAqIERlY29kZXMgQVNOLjEgR2VuZXJhbGl6ZWRUaW1lIHR5cGUKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgZXJyb3Igb2NjdXJlZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlYWRHZW5lcmFsaXplZFRpbWUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGFnID09IEFTTjFDb25zdGFudHMuVEFHX0dFTkVSQUxJWkVEVElNRSkgeworICAgICAgICAgICAgLy8gRklYTUU6IGFueSBvdGhlciBvcHRpbWl6YXRpb25zPworICAgICAgICAgICAgcmVhZENvbnRlbnQoKTsKKyAgICAgICAgICAgIC8vIEZJWE1FIHN0b3JlIHN0cmluZyBzb21ld2hlcmUgdG8gYWxsb3cgYSBjdXN0b20gdGltZSB0eXBlIHBlcmZvcm0KKyAgICAgICAgICAgIC8vIGFkZGl0aW9uYWwgY2hlY2tzCisKKyAgICAgICAgICAgIC8vIGNoZWNrIHN5bnRheDogdGhlIGxhc3QgY2hhciBNVVNUIGJlIFoKKyAgICAgICAgICAgIGlmIChidWZmZXJbb2Zmc2V0IC0gMV0gIT0gJ1onKSB7CisgICAgICAgICAgICAgICAgLy8gRklYTUUgc3VwcG9ydCBvbmx5IGZvcm1hdCB0aGF0IGlzIGFjY2VwdGFibGUgZm9yIERFUgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJBU04uMSBHZW5lcmFsaXplZFRpbWU6IGVuY29kZWQgZm9ybWF0IGlzIG5vdCBpbXBsZW1lbnRlZCIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBjaGVjayBzeW50YXg6IE1VU1QgYmUgWVlZWU1NRERISE1NU1NbKC4vLClERERdJ1onCisgICAgICAgICAgICBpZiAobGVuZ3RoICE9IDE1ICYmIChsZW5ndGggPCAxNyB8fCBsZW5ndGggPiAxOSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiQVNOLjEgR2VuZXJhbGl6ZWRUaW1lIHdyb25nbHkgZW5jb2RlZCBhdCBbIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBjb250ZW50T2Zmc2V0ICsgIl0iKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gY2hlY2sgY29udGVudDogbWlsbGlzZWNvbmRzCisgICAgICAgICAgICBpZiAobGVuZ3RoID4gMTYpIHsKKyAgICAgICAgICAgICAgICBieXRlIGNoYXIxNCA9IGJ1ZmZlcltjb250ZW50T2Zmc2V0ICsgMTRdOworICAgICAgICAgICAgICAgIGlmIChjaGFyMTQgIT0gJy4nICYmIGNoYXIxNCAhPSAnLCcpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIkFTTi4xIEdlbmVyYWxpemVkVGltZSB3cm9uZ2x5IGVuY29kZWQgYXQgWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGNvbnRlbnRPZmZzZXQgKyAiXSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHRpbWVzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aW1lcyA9IG5ldyBpbnRbN107CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aW1lc1swXSA9IHN0clRvSW50KGNvbnRlbnRPZmZzZXQsIDQpOyAvLyB5ZWFyCisgICAgICAgICAgICB0aW1lc1sxXSA9IHN0clRvSW50KGNvbnRlbnRPZmZzZXQgKyA0LCAyKTsgLy8gbW9udGgKKyAgICAgICAgICAgIHRpbWVzWzJdID0gc3RyVG9JbnQoY29udGVudE9mZnNldCArIDYsIDIpOyAvLyBkYXkKKyAgICAgICAgICAgIHRpbWVzWzNdID0gc3RyVG9JbnQoY29udGVudE9mZnNldCArIDgsIDIpOyAvLyBob3VyCisgICAgICAgICAgICB0aW1lc1s0XSA9IHN0clRvSW50KGNvbnRlbnRPZmZzZXQgKyAxMCwgMik7IC8vIG1pbnV0ZQorICAgICAgICAgICAgdGltZXNbNV0gPSBzdHJUb0ludChjb250ZW50T2Zmc2V0ICsgMTIsIDIpOyAvLyBzZWNvbmQKKworICAgICAgICAgICAgaWYgKGxlbmd0aCA+IDE2KSB7CisgICAgICAgICAgICAgICAgLy8gRklYTUUgb3B0aW1pemUgbWUKKyAgICAgICAgICAgICAgICB0aW1lc1s2XSA9IHN0clRvSW50KGNvbnRlbnRPZmZzZXQgKyAxNSwgbGVuZ3RoIC0gMTYpOworCisgICAgICAgICAgICAgICAgaWYgKGxlbmd0aCA9PSAxNykgeworICAgICAgICAgICAgICAgICAgICB0aW1lc1s2XSA9IHRpbWVzWzZdICogMTAwOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobGVuZ3RoID09IDE4KSB7CisgICAgICAgICAgICAgICAgICAgIHRpbWVzWzZdID0gdGltZXNbNl0gKiAxMDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIEZJWE1FIGNoZWNrIGFsbCB2YWx1ZXMgZm9yIHZhbGlkIG51bWJlcnMhISEKKyAgICAgICAgfSBlbHNlIGlmICh0YWcgPT0gQVNOMUNvbnN0YW50cy5UQUdfQ19HRU5FUkFMSVpFRFRJTUUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJEZWNvZGluZyBjb25zdHJ1Y3RlZCBBU04uMSBHZW5lcmFsaXplZFRpbWUgdHlwZSBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBleHBlY3RlZCgiR2VuZXJhbGl6ZWRUaW1lIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvZGVzIEFTTi4xIFVUQ1RpbWUgdHlwZQorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJzIG9yIHRoZSBlbmQgb2YgdGhlIHN0cmVhbSBpcyByZWFjaGVkCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVhZFVUQ1RpbWUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGFnID09IEFTTjFDb25zdGFudHMuVEFHX1VUQ1RJTUUpIHsKKyAgICAgICAgICAgIHN3aXRjaCAobGVuZ3RoKSB7CisgICAgICAgICAgICBjYXNlIEFTTjFVVENUaW1lLlVUQ19ITToKKyAgICAgICAgICAgIGNhc2UgQVNOMVVUQ1RpbWUuVVRDX0hNUzoKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgQVNOMVVUQ1RpbWUuVVRDX0xPQ0FMX0hNOgorICAgICAgICAgICAgY2FzZSBBU04xVVRDVGltZS5VVENfTE9DQUxfSE1TOgorICAgICAgICAgICAgICAgIC8vIEZJWE1FIG9ubHkgY29vcmRpbmF0ZWQgdW5pdmVyc2FsIHRpbWUgZm9ybWF0cyBhcmUgc3VwcG9ydGVkCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIkFTTi4xIFVUQ1RpbWU6IGxvY2FsIHRpbWUgZm9ybWF0IGlzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIkFTTi4xIFVUQ1RpbWU6IHdyb25nIGxlbmd0aCwgaWRlbnRpZmllciBhdCAiICsgdGFnT2Zmc2V0KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gRklYTUU6IGFueSBvdGhlciBvcHRpbWl6YXRpb25zPworICAgICAgICAgICAgcmVhZENvbnRlbnQoKTsKKworICAgICAgICAgICAgLy8gRklYTUUgc3RvcmUgc3RyaW5nIHNvbWV3aGVyZSB0byBhbGxvdyBhIGN1c3RvbSB0aW1lIHR5cGUgcGVyZm9ybQorICAgICAgICAgICAgLy8gYWRkaXRpb25hbCBjaGVja3MKKworICAgICAgICAgICAgLy8gY2hlY2sgc3ludGF4OiB0aGUgbGFzdCBjaGFyIE1VU1QgYmUgWgorICAgICAgICAgICAgaWYgKGJ1ZmZlcltvZmZzZXQgLSAxXSAhPSAnWicpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiQVNOLjEgVVRDVGltZSB3cm9uZ2x5IGVuY29kZWQgYXQgWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgY29udGVudE9mZnNldCArICddJyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICh0aW1lcyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGltZXMgPSBuZXcgaW50WzddOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0aW1lc1swXSA9IHN0clRvSW50KGNvbnRlbnRPZmZzZXQsIDIpOyAvLyB5ZWFyCisgICAgICAgICAgICBpZiAodGltZXNbMF0gPiA0OSkgeworICAgICAgICAgICAgICAgIHRpbWVzWzBdICs9IDE5MDA7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRpbWVzWzBdICs9IDIwMDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRpbWVzWzFdID0gc3RyVG9JbnQoY29udGVudE9mZnNldCArIDIsIDIpOyAvLyBtb250aAorICAgICAgICAgICAgdGltZXNbMl0gPSBzdHJUb0ludChjb250ZW50T2Zmc2V0ICsgNCwgMik7IC8vIGRheQorICAgICAgICAgICAgdGltZXNbM10gPSBzdHJUb0ludChjb250ZW50T2Zmc2V0ICsgNiwgMik7IC8vIGhvdXIKKyAgICAgICAgICAgIHRpbWVzWzRdID0gc3RyVG9JbnQoY29udGVudE9mZnNldCArIDgsIDIpOyAvLyBtaW51dGUKKworICAgICAgICAgICAgaWYgKGxlbmd0aCA9PSBBU04xVVRDVGltZS5VVENfSE1TKSB7CisgICAgICAgICAgICAgICAgdGltZXNbNV0gPSBzdHJUb0ludChjb250ZW50T2Zmc2V0ICsgMTAsIDIpOyAvLyBzZWNvbmQKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gRklYTUUgY2hlY2sgYWxsIHRpbWUgdmFsdWVzIGZvciB2YWxpZCBudW1iZXJzISEhCisgICAgICAgIH0gZWxzZSBpZiAodGFnID09IEFTTjFDb25zdGFudHMuVEFHX0NfVVRDVElNRSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIkRlY29kaW5nIGNvbnN0cnVjdGVkIEFTTi4xIFVUQ1RpbWUgdHlwZSBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBleHBlY3RlZCgiVVRDVGltZSIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgc3RyVG9JbnQoaW50IG9mZiwgaW50IGNvdW50KSB0aHJvd3MgQVNOMUV4Y2VwdGlvbiB7CisgICAgICAgIGludCByZXN1bHQgPSAwOworICAgICAgICBmb3IgKGludCBpID0gb2ZmLCBlbmQgPSBvZmYgKyBjb3VudDsgaSA8IGVuZDsgaSsrKSB7CisgICAgICAgICAgICBpbnQgYyA9IGJ1ZmZlcltpXSAtIDQ4OworICAgICAgICAgICAgaWYgKGMgPCAwIHx8IGMgPiA5KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIlRpbWUgZW5jb2RpbmcgaGFzIGludmFsaWQgY2hhciIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICogMTAgKyBjOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVjb2RlcyBBU04uMSBJbnRlZ2VyIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZWFkSW50ZWdlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0YWcgIT0gQVNOMUNvbnN0YW50cy5UQUdfSU5URUdFUikgeworICAgICAgICAgICAgdGhyb3cgZXhwZWN0ZWQoImludGVnZXIiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNoZWNrIGVuY29kZWQgbGVuZ3RoCisgICAgICAgIGlmIChsZW5ndGggPCAxKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiV3JvbmcgbGVuZ3RoIGZvciBBU04uMSBpbnRlZ2VyIGF0IFsiICsgdGFnT2Zmc2V0ICsgIl0iKTsKKyAgICAgICAgfQorCisgICAgICAgIHJlYWRDb250ZW50KCk7CisKKyAgICAgICAgLy8gY2hlY2sgZW5jb2RlZCBjb250ZW50CisgICAgICAgIGlmIChsZW5ndGggPiAxKSB7CisgICAgICAgICAgICBieXRlIGZpcnN0Qnl0ZSA9IGJ1ZmZlcltvZmZzZXQgLSBsZW5ndGhdOworICAgICAgICAgICAgYnl0ZSBzZWNvbmRCeXRlID0gKGJ5dGUpIChidWZmZXJbb2Zmc2V0IC0gbGVuZ3RoICsgMV0gJiAweDgwKTsKKworICAgICAgICAgICAgaWYgKGZpcnN0Qnl0ZSA9PSAwICYmIHNlY29uZEJ5dGUgPT0gMCB8fCBmaXJzdEJ5dGUgPT0gKGJ5dGUpIDB4RkYKKyAgICAgICAgICAgICAgICAgICAgJiYgc2Vjb25kQnl0ZSA9PSAoYnl0ZSkgMHg4MCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJXcm9uZyBjb250ZW50IGZvciBBU04uMSBpbnRlZ2VyIGF0IFsiICsgKG9mZnNldCAtIGxlbmd0aCkgKyAiXS4gQW4gaW50ZWdlciBNVVNUIGJlIGVuY29kZWQgaW4gbWluaW11bSBudW1iZXIgb2Ygb2N0ZXRzIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvZGVzIEFTTi4xIE9jdGV0c3RyaW5nIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZWFkT2N0ZXRTdHJpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGFnID09IEFTTjFDb25zdGFudHMuVEFHX09DVEVUU1RSSU5HKSB7CisgICAgICAgICAgICByZWFkQ29udGVudCgpOworICAgICAgICB9IGVsc2UgaWYgKHRhZyA9PSBBU04xQ29uc3RhbnRzLlRBR19DX09DVEVUU1RSSU5HKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiRGVjb2RpbmcgY29uc3RydWN0ZWQgQVNOLjEgb2N0ZXQgc3RyaW5nIHR5cGUgaXMgbm90IHN1cHBvcnRlZCIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgZXhwZWN0ZWQoIm9jdGV0c3RyaW5nIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIEFTTjFFeGNlcHRpb24gZXhwZWN0ZWQoU3RyaW5nIHdoYXQpIHRocm93cyBBU04xRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIkFTTi4xICIgKyB3aGF0ICsgIiBpZGVudGlmaWVyIGV4cGVjdGVkIGF0IFsiICsgdGFnT2Zmc2V0ICsgIl0sIGdvdCAiICsgSW50ZWdlci50b0hleFN0cmluZyh0YWcpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IG9pZEVsZW1lbnQ7CisKKyAgICAvKioKKyAgICAgKiBEZWNvZGVzIEFTTi4xIE9iamVjdElkZW50aWZpZXIgdHlwZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlYWRPSUQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGFnICE9IEFTTjFDb25zdGFudHMuVEFHX09JRCkgeworICAgICAgICAgICAgdGhyb3cgZXhwZWN0ZWQoIk9JRCIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gY2hlY2sgZW5jb2RlZCBsZW5ndGgKKyAgICAgICAgaWYgKGxlbmd0aCA8IDEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJXcm9uZyBsZW5ndGggZm9yIEFTTi4xIG9iamVjdCBpZGVudGlmaWVyIGF0IFsiICsgdGFnT2Zmc2V0ICsgIl0iKTsKKyAgICAgICAgfQorCisgICAgICAgIHJlYWRDb250ZW50KCk7CisKKyAgICAgICAgLy8gY2hlY2sgY29udGVudDogbGFzdCBlbmNvZGVkIGJ5dGUgKDh0aCBiaXQgTVVTVCBiZSB6ZXJvKQorICAgICAgICBpZiAoKGJ1ZmZlcltvZmZzZXQgLSAxXSAmIDB4ODApICE9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJXcm9uZyBlbmNvZGluZyBhdCBbIiArIChvZmZzZXQgLSAxKSArICJdIik7CisgICAgICAgIH0KKworICAgICAgICBvaWRFbGVtZW50ID0gMTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKywgKytvaWRFbGVtZW50KSB7CisgICAgICAgICAgICB3aGlsZSAoKGJ1ZmZlcltjb250ZW50T2Zmc2V0ICsgaV0gJiAweDgwKSA9PSAweDgwKSB7CisgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVjb2RlcyBBU04uMSBTZXF1ZW5jZSB0eXBlCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVhZFNlcXVlbmNlKEFTTjFTZXF1ZW5jZSBzZXF1ZW5jZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRhZyAhPSBBU04xQ29uc3RhbnRzLlRBR19DX1NFUVVFTkNFKSB7CisgICAgICAgICAgICB0aHJvdyBleHBlY3RlZCgic2VxdWVuY2UiKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBiZWdPZmZzZXQgPSBvZmZzZXQ7CisgICAgICAgIGludCBlbmRPZmZzZXQgPSBiZWdPZmZzZXQgKyBsZW5ndGg7CisKKyAgICAgICAgQVNOMVR5cGVbXSB0eXBlID0gc2VxdWVuY2UudHlwZTsKKworICAgICAgICBpbnQgaSA9IDA7CisKKyAgICAgICAgaWYgKGlzVmVyaWZ5KSB7CisKKyAgICAgICAgICAgIGZvciAoOyAob2Zmc2V0IDwgZW5kT2Zmc2V0KSAmJiAoaSA8IHR5cGUubGVuZ3RoKTsgaSsrKSB7CisKKyAgICAgICAgICAgICAgICBuZXh0KCk7CisgICAgICAgICAgICAgICAgd2hpbGUgKCF0eXBlW2ldLmNoZWNrVGFnKHRhZykpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgd2hldGhlciBpdCBpcyBvcHRpb25hbCBjb21wb25lbnQgb3Igbm90CisgICAgICAgICAgICAgICAgICAgIGlmICghc2VxdWVuY2UuT1BUSU9OQUxbaV0gfHwgKGkgPT0gdHlwZS5sZW5ndGggLSAxKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIkFTTi4xIFNlcXVlbmNlOiBtYW5kYXRvcnkgdmFsdWUgaXMgbWlzc2luZyBhdCBbIiArIHRhZ09mZnNldCArICJdIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHR5cGVbaV0uZGVjb2RlKHRoaXMpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBjaGVjayB0aGUgcmVzdCBvZiBjb21wb25lbnRzCisgICAgICAgICAgICBmb3IgKDsgaSA8IHR5cGUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoIXNlcXVlbmNlLk9QVElPTkFMW2ldKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJBU04uMSBTZXF1ZW5jZTogbWFuZGF0b3J5IHZhbHVlIGlzIG1pc3NpbmcgYXQgWyIgKyB0YWdPZmZzZXQgKyAiXSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW50IHNlcVRhZ09mZnNldCA9IHRhZ09mZnNldDsgLy9zdG9yZSB0YWcgb2Zmc2V0CisKKyAgICAgICAgICAgIE9iamVjdFtdIHZhbHVlcyA9IG5ldyBPYmplY3RbdHlwZS5sZW5ndGhdOworICAgICAgICAgICAgZm9yICg7IChvZmZzZXQgPCBlbmRPZmZzZXQpICYmIChpIDwgdHlwZS5sZW5ndGgpOyBpKyspIHsKKworICAgICAgICAgICAgICAgIG5leHQoKTsKKyAgICAgICAgICAgICAgICB3aGlsZSAoIXR5cGVbaV0uY2hlY2tUYWcodGFnKSkgeworICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayB3aGV0aGVyIGl0IGlzIG9wdGlvbmFsIGNvbXBvbmVudCBvciBub3QKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFzZXF1ZW5jZS5PUFRJT05BTFtpXSB8fCAoaSA9PSB0eXBlLmxlbmd0aCAtIDEpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiQVNOLjEgU2VxdWVuY2U6IG1hbmRhdG9yeSB2YWx1ZSBpcyBtaXNzaW5nIGF0IFsiICsgdGFnT2Zmc2V0ICsgIl0iKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vIHNldHMgZGVmYXVsdCB2YWx1ZQorICAgICAgICAgICAgICAgICAgICBpZiAoc2VxdWVuY2UuREVGQVVMVFtpXSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXNbaV0gPSBzZXF1ZW5jZS5ERUZBVUxUW2ldOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdmFsdWVzW2ldID0gdHlwZVtpXS5kZWNvZGUodGhpcyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGNoZWNrIHRoZSByZXN0IG9mIGNvbXBvbmVudHMKKyAgICAgICAgICAgIGZvciAoOyBpIDwgdHlwZS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGlmICghc2VxdWVuY2UuT1BUSU9OQUxbaV0pIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIkFTTi4xIFNlcXVlbmNlOiBtYW5kYXRvcnkgdmFsdWUgaXMgbWlzc2luZyBhdCBbIiArIHRhZ09mZnNldCArICJdIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChzZXF1ZW5jZS5ERUZBVUxUW2ldICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdmFsdWVzW2ldID0gc2VxdWVuY2UuREVGQVVMVFtpXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb250ZW50ID0gdmFsdWVzOworCisgICAgICAgICAgICB0YWdPZmZzZXQgPSBzZXFUYWdPZmZzZXQ7IC8vcmV0cmlldmUgdGFnIG9mZnNldAorICAgICAgICB9CisKKyAgICAgICAgaWYgKG9mZnNldCAhPSBlbmRPZmZzZXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJXcm9uZyBlbmNvZGluZyBhdCBbIiArIGJlZ09mZnNldCArICJdLiBDb250ZW50J3MgbGVuZ3RoIGFuZCBlbmNvZGVkIGxlbmd0aCBhcmUgbm90IHRoZSBzYW1lIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvZGVzIEFTTi4xIFNlcXVlbmNlT2YgdHlwZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlYWRTZXF1ZW5jZU9mKEFTTjFTZXF1ZW5jZU9mIHNlcXVlbmNlT2YpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0YWcgIT0gQVNOMUNvbnN0YW50cy5UQUdfQ19TRVFVRU5DRU9GKSB7CisgICAgICAgICAgICB0aHJvdyBleHBlY3RlZCgic2VxdWVuY2VPZiIpOworICAgICAgICB9CisKKyAgICAgICAgZGVjb2RlVmFsdWVDb2xsZWN0aW9uKHNlcXVlbmNlT2YpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlY29kZXMgQVNOLjEgU2V0IHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZWFkU2V0KEFTTjFTZXQgc2V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGFnICE9IEFTTjFDb25zdGFudHMuVEFHX0NfU0VUKSB7CisgICAgICAgICAgICB0aHJvdyBleHBlY3RlZCgic2V0Iik7CisgICAgICAgIH0KKworICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiRGVjb2RpbmcgQVNOLjEgU2V0IHR5cGUgaXMgbm90IHN1cHBvcnRlZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlY29kZXMgQVNOLjEgU2V0T2YgdHlwZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlYWRTZXRPZihBU04xU2V0T2Ygc2V0T2YpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0YWcgIT0gQVNOMUNvbnN0YW50cy5UQUdfQ19TRVRPRikgeworICAgICAgICAgICAgdGhyb3cgZXhwZWN0ZWQoInNldE9mIik7CisgICAgICAgIH0KKworICAgICAgICBkZWNvZGVWYWx1ZUNvbGxlY3Rpb24oc2V0T2YpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBkZWNvZGVWYWx1ZUNvbGxlY3Rpb24oQVNOMVZhbHVlQ29sbGVjdGlvbiBjb2xsZWN0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgYmVnT2Zmc2V0ID0gb2Zmc2V0OworICAgICAgICBpbnQgZW5kT2Zmc2V0ID0gYmVnT2Zmc2V0ICsgbGVuZ3RoOworCisgICAgICAgIEFTTjFUeXBlIHR5cGUgPSBjb2xsZWN0aW9uLnR5cGU7CisKKyAgICAgICAgaWYgKGlzVmVyaWZ5KSB7CisgICAgICAgICAgICB3aGlsZSAoZW5kT2Zmc2V0ID4gb2Zmc2V0KSB7CisgICAgICAgICAgICAgICAgbmV4dCgpOworICAgICAgICAgICAgICAgIHR5cGUuZGVjb2RlKHRoaXMpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW50IHNlcVRhZ09mZnNldCA9IHRhZ09mZnNldDsgLy9zdG9yZSB0YWcgb2Zmc2V0CisKKyAgICAgICAgICAgIEFycmF5TGlzdDxPYmplY3Q+IHZhbHVlcyA9IG5ldyBBcnJheUxpc3Q8T2JqZWN0PigpOworICAgICAgICAgICAgd2hpbGUgKGVuZE9mZnNldCA+IG9mZnNldCkgeworICAgICAgICAgICAgICAgIG5leHQoKTsKKyAgICAgICAgICAgICAgICB2YWx1ZXMuYWRkKHR5cGUuZGVjb2RlKHRoaXMpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdmFsdWVzLnRyaW1Ub1NpemUoKTsKKyAgICAgICAgICAgIGNvbnRlbnQgPSB2YWx1ZXM7CisKKyAgICAgICAgICAgIHRhZ09mZnNldCA9IHNlcVRhZ09mZnNldDsgLy9yZXRyaWV2ZSB0YWcgb2Zmc2V0CisgICAgICAgIH0KKworICAgICAgICBpZiAob2Zmc2V0ICE9IGVuZE9mZnNldCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIldyb25nIGVuY29kaW5nIGF0IFsiICsgYmVnT2Zmc2V0ICsgIl0uIENvbnRlbnQncyBsZW5ndGggYW5kIGVuY29kZWQgbGVuZ3RoIGFyZSBub3QgdGhlIHNhbWUiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIERlY29kZXMgQVNOLjEgU3RyaW5nIHR5cGUKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3VycyBvciB0aGUgZW5kIG9mIHRoZSBzdHJlYW0gaXMgcmVhY2hlZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlYWRTdHJpbmcoQVNOMVN0cmluZ1R5cGUgdHlwZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRhZyA9PSB0eXBlLmlkKSB7CisgICAgICAgICAgICByZWFkQ29udGVudCgpOworICAgICAgICB9IGVsc2UgaWYgKHRhZyA9PSB0eXBlLmNvbnN0cklkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiRGVjb2RpbmcgY29uc3RydWN0ZWQgQVNOLjEgc3RyaW5nIHR5cGUgaXMgbm90IHByb3ZpZGVkIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBleHBlY3RlZCgic3RyaW5nIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGVuY29kZWQgYXJyYXkuCisgICAgICoKKyAgICAgKiBNVVNUIGJlIGludm9rZWQgYWZ0ZXIgZGVjb2RpbmcgY29ycmVzcG9uZGluZyBBU04uMSBub3RhdGlvbgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgYnl0ZVtdIGVuY29kZWQgPSBuZXcgYnl0ZVtvZmZzZXQgLSB0YWdPZmZzZXRdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZmZlciwgdGFnT2Zmc2V0LCBlbmNvZGVkLCAwLCBlbmNvZGVkLmxlbmd0aCk7CisgICAgICAgIHJldHVybiBlbmNvZGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgaW50ZXJuYWwgYnVmZmVyIHVzZWQgZm9yIGRlY29kaW5nCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGJ5dGVbXSBnZXRCdWZmZXIoKSB7CisgICAgICAgIHJldHVybiBidWZmZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBsZW5ndGggb2YgdGhlIGN1cnJlbnQgY29udGVudCBmb3IgZGVjb2RpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IGdldExlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IG9mZnNldAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0T2Zmc2V0KCkgeworICAgICAgICByZXR1cm4gb2Zmc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgZW5kIG9mZnNldCBmb3IgdGhlIGN1cnJlbnQgZW5jb2RlZCB0eXBlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIGludCBnZXRFbmRPZmZzZXQoKSB7CisgICAgICAgIHJldHVybiBvZmZzZXQgKyBsZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBzdGFydCBvZmZzZXQgZm9yIHRoZSBjdXJyZW50IGVuY29kZWQgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0VGFnT2Zmc2V0KCkgeworICAgICAgICByZXR1cm4gdGFnT2Zmc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB2ZXJpZnkgb3Igc3RvcmUgbW9kZS4KKyAgICAgKgorICAgICAqIEluIHN0b3JlIG1vZGUgYSBkZWNvZGVkIGNvbnRlbnQgaXMgc3RvcmVkIGluIGEgbmV3bHkgYWxsb2NhdGVkCisgICAgICogYXBwcm9wcmlhdGUgb2JqZWN0LiBUaGUgPGNvZGU+Y29udGVudDwvY29kZT4gdmFyaWFibGUgaG9sZHMKKyAgICAgKiBhIHJlZmVyZW5jZSB0byB0aGUgbGFzdCBjcmVhdGVkIG9iamVjdC4KKyAgICAgKgorICAgICAqIEluIHZlcmlmeSBtb2RlIGEgZGVjb2RlZCBjb250ZW50IGlzIG5vdCBzdG9yZWQuCisgICAgICovCisgICAgLy8gRklYTUUgaXQgaXMgdXNlZCBvbmx5IGZvciBvbmUgY2FzZQorICAgIC8vIGRlY29kaW5nIFBDS1MjOCBQcml2YXRlIEtleSBJbmZvIG5vdGF0aW9uCisgICAgLy8gcmVtb3ZlIHRoaXMgb3B0aW9uIGJlY2F1c2UgaXQgZG9lcyBkZWNvZGluZyBtb3JlIGNvbXBsZXgKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc1ZlcmlmeTsKKworICAgIC8qKgorICAgICAqIFNldHMgdmVyaWZ5IG1vZGUuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgc2V0VmVyaWZ5KCkgeworICAgICAgICBpc1ZlcmlmeSA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIGRlZmluZWQgb3IgaW5kZWZpbmVkIHJlYWRpbmcgbW9kZSBmb3IgYXNzb2NpYXRlZCBJbnB1dFN0cmVhbS4KKyAgICAgKgorICAgICAqIFRoaXMgbW9kZSBpcyBkZWZpbmVkIGJ5IHJlYWRpbmcgYSBsZW5ndGgKKyAgICAgKiBmb3IgYSBmaXJzdCBBU04uMSB0eXBlIGZyb20gSW5wdXRTdHJlYW0uCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNJbmRlZmluZWRMZW5ndGg7CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB0aGUgbmV4dCBlbmNvZGVkIGJ5dGUgZnJvbSB0aGUgZW5jb2RlZCBpbnB1dCBzdHJlYW0uCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG9mZnNldCA9PSBidWZmZXIubGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiVW5leHBlY3RlZCBlbmQgb2YgZW5jb2RpbmciKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChpbiA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gYnVmZmVyW29mZnNldCsrXSAmIDB4RkY7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpbnQgb2N0ZXQgPSBpbi5yZWFkKCk7CisgICAgICAgICAgICBpZiAob2N0ZXQgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiVW5leHBlY3RlZCBlbmQgb2YgZW5jb2RpbmciKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IChieXRlKSBvY3RldDsKKworICAgICAgICAgICAgcmV0dXJuIG9jdGV0OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIG5leHQgZW5jb2RlZCBjb250ZW50IGZyb20gdGhlIGVuY29kZWQgaW5wdXQgc3RyZWFtLgorICAgICAqIFRoZSBtZXRob2QgTVVTVCBiZSB1c2VkIGZvciByZWFkaW5nIGEgcHJpbWl0aXZlIGVuY29kZWQgY29udGVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZWFkQ29udGVudCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChvZmZzZXQgKyBsZW5ndGggPiBidWZmZXIubGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiVW5leHBlY3RlZCBlbmQgb2YgZW5jb2RpbmciKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChpbiA9PSBudWxsKSB7CisgICAgICAgICAgICBvZmZzZXQgKz0gbGVuZ3RoOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW50IGJ5dGVzUmVhZCA9IGluLnJlYWQoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7CisKKyAgICAgICAgICAgIGlmIChieXRlc1JlYWQgIT0gbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgLy8gaWYgaW5wdXQgc3RyZWFtIGRpZG4ndCByZXR1cm4gYWxsIGRhdGEgYXQgb25jZQorICAgICAgICAgICAgICAgIC8vIHRyeSB0byByZWFkIGl0IGluIHNldmVyYWwgYmxvY2tzCisgICAgICAgICAgICAgICAgaW50IGMgPSBieXRlc1JlYWQ7CisgICAgICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgICAgICBpZiAoYyA8IDEgfHwgYnl0ZXNSZWFkID4gbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiRmFpbGVkIHRvIHJlYWQgZW5jb2RlZCBjb250ZW50Iik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYyA9IGluLnJlYWQoYnVmZmVyLCBvZmZzZXQgKyBieXRlc1JlYWQsIGxlbmd0aCAtIGJ5dGVzUmVhZCk7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVhZCArPSBjOworICAgICAgICAgICAgICAgIH0gd2hpbGUgKGJ5dGVzUmVhZCAhPSBsZW5ndGgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBvZmZzZXQgKz0gbGVuZ3RoOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhbGxvY2F0ZXMgdGhlIGJ1ZmZlciBpbiBvcmRlciB0byBtYWtlIGl0CisgICAgICogZXhhY3RseSB0aGUgc2l6ZSBvZiBkYXRhIGl0IGNvbnRhaW5zCisgICAgICovCisgICAgcHVibGljIHZvaWQgY29tcGFjdEJ1ZmZlcigpIHsKKyAgICAgICAgaWYgKG9mZnNldCAhPSBidWZmZXIubGVuZ3RoKSB7CisgICAgICAgICAgICBieXRlW10gbmV3QnVmZmVyID0gbmV3IGJ5dGVbb2Zmc2V0XTsKKyAgICAgICAgICAgIC8vIHJlc3RvcmUgYnVmZmVyIGNvbnRlbnQKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCAwLCBuZXdCdWZmZXIsIDAsIG9mZnNldCk7CisgICAgICAgICAgICAvLyBzZXQgbmV3IGJ1ZmZlcgorICAgICAgICAgICAgYnVmZmVyID0gbmV3QnVmZmVyOworICAgICAgICB9CisgICAgfQorICAgIHByaXZhdGUgT2JqZWN0W11bXSBwb29sOworCisgICAgcHVibGljIHZvaWQgcHV0KE9iamVjdCBrZXksIE9iamVjdCBlbnRyeSkgeworICAgICAgICBpZiAocG9vbCA9PSBudWxsKSB7CisgICAgICAgICAgICBwb29sID0gbmV3IE9iamVjdFsyXVsxMF07CisgICAgICAgIH0KKworICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgIGZvciAoOyBpIDwgcG9vbFswXS5sZW5ndGggJiYgcG9vbFswXVtpXSAhPSBudWxsOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChwb29sWzBdW2ldID09IGtleSkgeworICAgICAgICAgICAgICAgIHBvb2xbMV1baV0gPSBlbnRyeTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoaSA9PSBwb29sWzBdLmxlbmd0aCkgeworICAgICAgICAgICAgT2JqZWN0W11bXSBuZXdQb29sID0gbmV3IE9iamVjdFtwb29sWzBdLmxlbmd0aCAqIDJdWzJdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShwb29sWzBdLCAwLCBuZXdQb29sWzBdLCAwLCBwb29sWzBdLmxlbmd0aCk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHBvb2xbMV0sIDAsIG5ld1Bvb2xbMV0sIDAsIHBvb2xbMF0ubGVuZ3RoKTsKKyAgICAgICAgICAgIHBvb2wgPSBuZXdQb29sOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcG9vbFswXVtpXSA9IGtleTsKKyAgICAgICAgICAgIHBvb2xbMV1baV0gPSBlbnRyeTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0KE9iamVjdCBrZXkpIHsKKyAgICAgICAgaWYgKHBvb2wgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBvb2xbMF0ubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChwb29sWzBdW2ldID09IGtleSkgeworICAgICAgICAgICAgICAgIHJldHVybiBwb29sWzFdW2ldOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9CZXJPdXRwdXRTdHJlYW0uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9CZXJPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNmIyNmJiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0Jlck91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMjAzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdiwgU3RlcGFuIE0uIE1pc2h1cmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMTsKKworCisvKioKKyAqIEVuY29kZXMgQVNOLjEgdHlwZXMgd2l0aCBCRVIgKFguNjkwKQorICoKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2FzbjEuZWxpYmVsLnRtLmZyL2VuL3N0YW5kYXJkcy9pbmRleC5odG0iPkFTTi4xPC9hPgorICovCitwdWJsaWMgY2xhc3MgQmVyT3V0cHV0U3RyZWFtIHsKKworICAgIC8qKiBFbmNvZGVkIGJ5dGUgYXJyYXkgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGVuY29kZWQ7CisKKyAgICAvKiogY3VycmVudCBvZmZzZXQgKi8KKyAgICBwcm90ZWN0ZWQgaW50IG9mZnNldDsKKworICAgIC8qKiBDdXJyZW50IGVuY29kZWQgbGVuZ3RoICovCisgICAgcHVibGljIGludCBsZW5ndGg7CisKKyAgICAvKiogQ3VycmVudCBlbmNvZGVkIGNvbnRlbnQgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGNvbnRlbnQ7CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBlbmNvZGVUYWcoaW50IHRhZykgeworICAgICAgICBlbmNvZGVkW29mZnNldCsrXSA9IChieXRlKSB0YWc7IC8vRklYTUUgbG9uZyBmb3JtPworCisgICAgICAgIGlmIChsZW5ndGggPiAxMjcpIHsgLy9sb25nIGZvcm0KKyAgICAgICAgICAgIGludCBlTGVuID0gbGVuZ3RoID4+IDg7CisgICAgICAgICAgICBieXRlIG51bU9jdGV0cyA9IDE7CisgICAgICAgICAgICBmb3IgKDsgZUxlbiA+IDA7IGVMZW4gPSBlTGVuID4+IDgpIHsKKyAgICAgICAgICAgICAgICBudW1PY3RldHMrKzsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZW5jb2RlZFtvZmZzZXRdID0gKGJ5dGUpIChudW1PY3RldHMgfCAweDgwKTsKKyAgICAgICAgICAgIG9mZnNldCsrOworCisgICAgICAgICAgICBlTGVuID0gbGVuZ3RoOworICAgICAgICAgICAgaW50IG51bU9mZnNldCA9IG9mZnNldCArIG51bU9jdGV0cyAtIDE7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bU9jdGV0czsgaSsrLCBlTGVuID0gZUxlbiA+PiA4KSB7CisgICAgICAgICAgICAgICAgZW5jb2RlZFtudW1PZmZzZXQgLSBpXSA9IChieXRlKSBlTGVuOyAvL0ZJWE1FIGxvbmcgdmFsdWU/CisgICAgICAgICAgICB9CisgICAgICAgICAgICBvZmZzZXQgKz0gbnVtT2N0ZXRzOworICAgICAgICB9IGVsc2UgeyAvL3Nob3J0IGZvcm0KKyAgICAgICAgICAgIGVuY29kZWRbb2Zmc2V0KytdID0gKGJ5dGUpIGxlbmd0aDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVuY29kZUFOWSgpIHsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShjb250ZW50LCAwLCBlbmNvZGVkLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIG9mZnNldCArPSBsZW5ndGg7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5jb2RlQml0U3RyaW5nKCkgeworICAgICAgICAvL0ZJWE1FIGNoZWNrIGVuY29kaW5nCisgICAgICAgIEJpdFN0cmluZyBiU3RyID0gKEJpdFN0cmluZykgY29udGVudDsKKyAgICAgICAgZW5jb2RlZFtvZmZzZXRdID0gKGJ5dGUpIGJTdHIudW51c2VkQml0czsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShiU3RyLmJ5dGVzLCAwLCBlbmNvZGVkLCBvZmZzZXQgKyAxLCBsZW5ndGggLSAxKTsKKyAgICAgICAgb2Zmc2V0ICs9IGxlbmd0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmNvZGVCb29sZWFuKCkgeworICAgICAgICBpZiAoKEJvb2xlYW4pIGNvbnRlbnQpIHsKKyAgICAgICAgICAgIGVuY29kZWRbb2Zmc2V0XSA9IChieXRlKSAweEZGOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZW5jb2RlZFtvZmZzZXRdID0gMHgwMDsKKyAgICAgICAgfQorICAgICAgICBvZmZzZXQrKzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmNvZGVDaG9pY2UoQVNOMUNob2ljZSBjaG9pY2UpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIklzIG5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsgLy9GSVhNRQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVuY29kZUV4cGxpY2l0KEFTTjFFeHBsaWNpdCBleHBsaWNpdCkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSXMgbm90IGltcGxlbWVudGVkIHlldCIpOyAvL0ZJWE1FCisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5jb2RlR2VuZXJhbGl6ZWRUaW1lKCkgeworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNvbnRlbnQsIDAsIGVuY29kZWQsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgb2Zmc2V0ICs9IGxlbmd0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmNvZGVVVENUaW1lKCkgeworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNvbnRlbnQsIDAsIGVuY29kZWQsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgb2Zmc2V0ICs9IGxlbmd0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmNvZGVJbnRlZ2VyKCkgeworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNvbnRlbnQsIDAsIGVuY29kZWQsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgb2Zmc2V0ICs9IGxlbmd0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmNvZGVPY3RldFN0cmluZygpIHsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShjb250ZW50LCAwLCBlbmNvZGVkLCBvZmZzZXQsIGxlbmd0aCk7CisgICAgICAgIG9mZnNldCArPSBsZW5ndGg7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5jb2RlT0lEKCkgeworCisgICAgICAgIGludFtdIG9pZCA9IChpbnRbXSkgY29udGVudDsKKworICAgICAgICBpbnQgb2lkTGVuID0gbGVuZ3RoOworCisgICAgICAgIC8vIGFsbCBzdWJpZGVudGlmaWVycyBleGNlcHQgZmlyc3QKKyAgICAgICAgaW50IGVsZW07CisgICAgICAgIGZvciAoaW50IGkgPSBvaWQubGVuZ3RoIC0gMTsgaSA+IDE7IGktLSwgb2lkTGVuLS0pIHsKKyAgICAgICAgICAgIGVsZW0gPSBvaWRbaV07CisgICAgICAgICAgICBpZiAoZWxlbSA+IDEyNykgeworICAgICAgICAgICAgICAgIGVuY29kZWRbb2Zmc2V0ICsgb2lkTGVuIC0gMV0gPSAoYnl0ZSkgKGVsZW0gJiAweDdGKTsKKyAgICAgICAgICAgICAgICBlbGVtID0gZWxlbSA+PiA3OworICAgICAgICAgICAgICAgIGZvciAoOyBlbGVtID4gMDspIHsKKyAgICAgICAgICAgICAgICAgICAgb2lkTGVuLS07CisgICAgICAgICAgICAgICAgICAgIGVuY29kZWRbb2Zmc2V0ICsgb2lkTGVuIC0gMV0gPSAoYnl0ZSkgKGVsZW0gfCAweDgwKTsKKyAgICAgICAgICAgICAgICAgICAgZWxlbSA9IGVsZW0gPj4gNzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGVuY29kZWRbb2Zmc2V0ICsgb2lkTGVuIC0gMV0gPSAoYnl0ZSkgZWxlbTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIGZpcnN0IHN1YmlkZW50aWZpZXIKKyAgICAgICAgZWxlbSA9IG9pZFswXSAqIDQwICsgb2lkWzFdOworICAgICAgICBpZiAoZWxlbSA+IDEyNykgeworICAgICAgICAgICAgZW5jb2RlZFtvZmZzZXQgKyBvaWRMZW4gLSAxXSA9IChieXRlKSAoZWxlbSAmIDB4N0YpOworICAgICAgICAgICAgZWxlbSA9IGVsZW0gPj4gNzsKKyAgICAgICAgICAgIGZvciAoOyBlbGVtID4gMDspIHsKKyAgICAgICAgICAgICAgICBvaWRMZW4tLTsKKyAgICAgICAgICAgICAgICBlbmNvZGVkW29mZnNldCArIG9pZExlbiAtIDFdID0gKGJ5dGUpIChlbGVtIHwgMHg4MCk7CisgICAgICAgICAgICAgICAgZWxlbSA9IGVsZW0gPj4gNzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGVuY29kZWRbb2Zmc2V0ICsgb2lkTGVuIC0gMV0gPSAoYnl0ZSkgZWxlbTsKKyAgICAgICAgfQorCisgICAgICAgIG9mZnNldCArPSBsZW5ndGg7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5jb2RlU2VxdWVuY2UoQVNOMVNlcXVlbmNlIHNlcXVlbmNlKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJcyBub3QgaW1wbGVtZW50ZWQgeWV0Iik7IC8vRklYTUUKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmNvZGVTZXF1ZW5jZU9mKEFTTjFTZXF1ZW5jZU9mIHNlcXVlbmNlT2YpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIklzIG5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsgLy9GSVhNRQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVuY29kZVNldChBU04xU2V0IHNldCkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSXMgbm90IGltcGxlbWVudGVkIHlldCIpOyAvL0ZJWE1FCisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5jb2RlU2V0T2YoQVNOMVNldE9mIHNldE9mKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJcyBub3QgaW1wbGVtZW50ZWQgeWV0Iik7IC8vRklYTUUKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmNvZGVTdHJpbmcoKSB7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY29udGVudCwgMCwgZW5jb2RlZCwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICBvZmZzZXQgKz0gbGVuZ3RoOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGdldENob2ljZUxlbmd0aChBU04xQ2hvaWNlIGNob2ljZSkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSXMgbm90IGltcGxlbWVudGVkIHlldCIpOyAvL0ZJWE1FCisgICAgfQorCisgICAgcHVibGljIHZvaWQgZ2V0RXhwbGljaXRMZW5ndGgoQVNOMUV4cGxpY2l0IHNlcXVlbmNlKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJcyBub3QgaW1wbGVtZW50ZWQgeWV0Iik7IC8vRklYTUUKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBnZXRTZXF1ZW5jZUxlbmd0aChBU04xU2VxdWVuY2Ugc2VxdWVuY2UpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIklzIG5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsgLy9GSVhNRQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGdldFNlcXVlbmNlT2ZMZW5ndGgoQVNOMVNlcXVlbmNlT2Ygc2VxdWVuY2UpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIklzIG5vdCBpbXBsZW1lbnRlZCB5ZXQiKTsgLy9GSVhNRQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGdldFNldExlbmd0aChBU04xU2V0IHNldCkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSXMgbm90IGltcGxlbWVudGVkIHlldCIpOyAvL0ZJWE1FCisgICAgfQorCisgICAgcHVibGljIHZvaWQgZ2V0U2V0T2ZMZW5ndGgoQVNOMVNldE9mIHNldE9mKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJcyBub3QgaW1wbGVtZW50ZWQgeWV0Iik7IC8vRklYTUUKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQml0U3RyaW5nLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvQml0U3RyaW5nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjA1NzllZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9CaXRTdHJpbmcuamF2YQpAQCAtMCwwICsxLDk4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4ZXkgVi4gVmFybGFtb3YsIFN0ZXBhbiBNLiBNaXNodXJhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjE7CisKKy8qKgorICogUmVwcmVzZW50cyBBU04uMSBiaXQgc3RyaW5nIHZhbHVlCisgKgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vYXNuMS5lbGliZWwudG0uZnIvZW4vc3RhbmRhcmRzL2luZGV4Lmh0bSI+QVNOLjE8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBCaXRTdHJpbmcgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIFNFVF9NQVNLID0geyAoYnl0ZSkgMTI4LCA2NCwgMzIsIDE2LCA4LCA0LCAyLCAxIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gUkVTRVRfTUFTSyA9IHsgMHg3ZiwgKGJ5dGUpIDB4YmYsIChieXRlKSAweGRmLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZWYsIChieXRlKSAweGY3LCAoYnl0ZSkgMHhmYiwgKGJ5dGUpIDB4ZmQsIChieXRlKSAweGZlLCB9OworCisgICAgLyoqIFNlcXVlbmNlIG9mIGJpdHMgcGFkZGVkIHdpdGggdW51c2VkIGJpdHMuICovCisgICAgcHVibGljIGZpbmFsIGJ5dGVbXSBieXRlczsKKworICAgIC8qKiBOdW1iZXIgb2YgdW51c2VkIGJpdHMgaW4gdGhlIGxhc3QgYnl0ZS4gKi8KKyAgICBwdWJsaWMgZmluYWwgaW50IHVudXNlZEJpdHM7CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gYnl0ZXMgYXJyYXkgb2YgYnl0ZXMgdGhhdCByZXByZXNlbnRzIGJpdCBzdHJpbmcsCisgICAgICogICAgICAgICAgICAgICAgaW5jbHVkaW5nIHVudXNlZCBiaXRzCisgICAgICogQHBhcmFtIHVudXNlZEJpdHMgbnVtYmVyIG9mIHVudXNlZCBiaXRzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gLSBpZiBwYXJhbWV0ZXJzIGFyZSBpbnZhbGlkCisgICAgICovCisgICAgcHVibGljIEJpdFN0cmluZyhieXRlW10gYnl0ZXMsIGludCB1bnVzZWRCaXRzKSB7CisgICAgICAgIC8vIGNvbnN0cmFpbnRzIGFyZSBzZXQgYWNjb3JkaW5nIFguNjkwCisgICAgICAgIGlmICh1bnVzZWRCaXRzIDwgMCB8fCB1bnVzZWRCaXRzID4gNykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTnVtYmVyIG9mIHVudXNlZCBiaXRzIE1VU1QgYmUgaW4gcmFuZ2UgMC03Iik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoYnl0ZXMubGVuZ3RoID09IDAgJiYgdW51c2VkQml0cyAhPSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGb3IgZW1wdHkgYml0IHN0cmluZyB1bnVzZWQgYml0cyBNVVNUIGJlIDAiKTsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuYnl0ZXMgPSBieXRlczsKKyAgICAgICAgdGhpcy51bnVzZWRCaXRzID0gdW51c2VkQml0czsKKyAgICB9CisKKyAgICBwdWJsaWMgQml0U3RyaW5nKGJvb2xlYW5bXSB2YWx1ZXMpIHsKKyAgICAgICAgdW51c2VkQml0cyA9IHZhbHVlcy5sZW5ndGggJSA4OworICAgICAgICBpbnQgc2l6ZSA9IHZhbHVlcy5sZW5ndGggLyA4OworICAgICAgICBpZiAodW51c2VkQml0cyAhPSAwKSB7CisgICAgICAgICAgICBzaXplKys7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZXMgPSBuZXcgYnl0ZVtzaXplXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHNldEJpdChpLCB2YWx1ZXNbaV0pOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZ2V0Qml0KGludCBiaXQpIHsKKyAgICAgICAgaW50IG9mZnNldCA9IGJpdCAlIDg7CisgICAgICAgIGludCBpbmRleCA9IGJpdCAvIDg7CisgICAgICAgIHJldHVybiAoYnl0ZXNbaW5kZXhdICYgU0VUX01BU0tbb2Zmc2V0XSkgIT0gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRCaXQoaW50IGJpdCwgYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICBpbnQgb2Zmc2V0ID0gYml0ICUgODsKKyAgICAgICAgaW50IGluZGV4ID0gYml0IC8gODsKKyAgICAgICAgaWYgKHZhbHVlKSB7CisgICAgICAgICAgICBieXRlc1tpbmRleF0gfD0gU0VUX01BU0tbb2Zmc2V0XTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJ5dGVzW2luZGV4XSAmPSBSRVNFVF9NQVNLW29mZnNldF07CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbltdIHRvQm9vbGVhbkFycmF5KCkgeworICAgICAgICBib29sZWFuW10gcmVzdWx0ID0gbmV3IGJvb2xlYW5bYnl0ZXMubGVuZ3RoICogOCAtIHVudXNlZEJpdHNdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlc3VsdC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgcmVzdWx0W2ldID0gZ2V0Qml0KGkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0RlcklucHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvRGVySW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZmRkYjgyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0RlcklucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxNTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFN0ZXBhbiBNLiBNaXNodXJhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjE7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKKy8qKgorICogRGVjb2RlcyBBU04uMSB0eXBlcyBlbmNvZGVkIHdpdGggREVSIChYLjY5MCkKKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9hc24xLmVsaWJlbC50bS5mci9lbi9zdGFuZGFyZHMvaW5kZXguaHRtIj5BU04uMTwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIERlcklucHV0U3RyZWFtIGV4dGVuZHMgQmVySW5wdXRTdHJlYW0geworCisgICAgLyoqIG1hc2sgZm9yIHZlcmlmeWluZyB1bnVzZWQgYml0cyBmb3IgQVNOLjEgYml0c3RyaW5nICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIFVOVVNFRF9CSVRTX01BU0sgPSBuZXcgYnl0ZVtdIHsgMHgwMSwgMHgwMywKKyAgICAgICAgICAgIDB4MDcsIDB4MEYsIDB4MUYsIDB4M0YsIDB4N0YgfTsKKworICAgIHB1YmxpYyBEZXJJbnB1dFN0cmVhbShieXRlW10gZW5jb2RlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoZW5jb2RlZCwgMCwgZW5jb2RlZC5sZW5ndGgpOworICAgIH0KKworICAgIHB1YmxpYyBEZXJJbnB1dFN0cmVhbShieXRlW10gZW5jb2RlZCwgaW50IG9mZnNldCwgaW50IGVuY29kaW5nTGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihlbmNvZGVkLCBvZmZzZXQsIGVuY29kaW5nTGVuKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRGVySW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKGluKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IG5leHQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgdGFnID0gc3VwZXIubmV4dCgpOworCisgICAgICAgIGlmIChsZW5ndGggPT0gSU5ERUZJTklUX0xFTkdUSCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIkRFUjogb25seSBkZWZpbml0ZSBsZW5ndGggZW5jb2RpbmcgTVVTVCBiZSB1c2VkIik7CisgICAgICAgIH0KKworICAgICAgICAvLyBGSVhNRSBhZGQgY2hlY2s6IGxlbmd0aCBlbmNvZGluZyB1c2VzIG1pbmltdW0gbnVtYmVyIG9mIG9jdGV0cworCisgICAgICAgIHJldHVybiB0YWc7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZEJpdFN0cmluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0YWcgPT0gQVNOMUNvbnN0YW50cy5UQUdfQ19CSVRTVFJJTkcpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJBU04uMSBiaXRzdHJpbmc6IGNvbnN0cnVjdGVkIGlkZW50aWZpZXIgYXQgWyIgKyB0YWdPZmZzZXQKKyAgICAgICAgICAgICAgICAgICAgKyAiXS4gTm90IHZhbGlkIGZvciBERVIuIik7CisgICAgICAgIH0KKworICAgICAgICBzdXBlci5yZWFkQml0U3RyaW5nKCk7CisKKyAgICAgICAgLy9jaGVjazogdW51c2VkIGJpdHMgdmFsdWVzIC0gTVVTVCBiZSAwCisgICAgICAgIGlmIChsZW5ndGggPiAxCisgICAgICAgICAgICAgICAgJiYgYnVmZmVyW2NvbnRlbnRPZmZzZXRdICE9IDAKKyAgICAgICAgICAgICAgICAmJiAoYnVmZmVyW29mZnNldCAtIDFdICYgVU5VU0VEX0JJVFNfTUFTS1tidWZmZXJbY29udGVudE9mZnNldF0gLSAxXSkgIT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIkFTTi4xIGJpdHN0cmluZzogd3JvbmcgY29udGVudCBhdCBbIiArIGNvbnRlbnRPZmZzZXQKKyAgICAgICAgICAgICAgICAgICAgKyAiXS4gREVSIHJlcXVpcmVzIHplcm8gdW51c2VkIGJpdHMgaW4gZmluYWwgb2N0ZXQuIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkQm9vbGVhbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnJlYWRCb29sZWFuKCk7CisKKyAgICAgICAgLy8gY2hlY2sgZW5jb2RlZCBjb250ZW50CisgICAgICAgIGlmIChidWZmZXJbY29udGVudE9mZnNldF0gIT0gMCAmJiBidWZmZXJbY29udGVudE9mZnNldF0gIT0gKGJ5dGUpIDB4RkYpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJBU04uMSBib29sZWFuOiB3cm9uZyBjb250ZW50IGF0IFsiICsgY29udGVudE9mZnNldAorICAgICAgICAgICAgICAgICAgICArICJdLiBERVIgYWxsb3dzIG9ubHkgMHgwMCBvciAweEZGIHZhbHVlcyIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZE9jdGV0U3RyaW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRhZyA9PSBBU04xQ29uc3RhbnRzLlRBR19DX09DVEVUU1RSSU5HKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiQVNOLjEgb2N0ZXRzdHJpbmc6IGNvbnN0cnVjdGVkIGlkZW50aWZpZXIgYXQgWyIgKyB0YWdPZmZzZXQKKyAgICAgICAgICAgICAgICAgICAgKyAiXS4gTm90IHZhbGlkIGZvciBERVIuIik7CisgICAgICAgIH0KKyAgICAgICAgc3VwZXIucmVhZE9jdGV0U3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZFNlcXVlbmNlKEFTTjFTZXF1ZW5jZSBzZXF1ZW5jZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8KKyAgICAgICAgLy8gQWNjb3JkaW5nIHRvIEFTTi4xIERFUiBzcGVjLiBzZXF1ZW5jZSBNVVNUIG5vdCBpbmNsdWRlCisgICAgICAgIC8vIGFueSBlbmNvZGluZyB3aGljaCB2YWx1ZSBpcyBlcXVhbCB0byBpdHMgZGVmYXVsdCB2YWx1ZQorICAgICAgICAvLworICAgICAgICAvLyBWZXJpZmljYXRpb24gb2YgdGhpcyBhc3NlcnRpb24gaXMgbm90IGltcGxlbWVudGVkCisgICAgICAgIC8vCisgICAgICAgIHN1cGVyLnJlYWRTZXF1ZW5jZShzZXF1ZW5jZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZFNldE9mKEFTTjFTZXRPZiBzZXRPZikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8KKyAgICAgICAgLy8gQWNjb3JkaW5nIHRvIEFTTi4xIERFUiBzcGVjLiBzZXQgb2YgTVVTVCBhcHBlYXIgaW4KKyAgICAgICAgLy8gYXNjZW5kaW5nIG9yZGVyIChzaG9ydCBjb21wb25lbnQgYXJlIHBhZGRlZCBmb3IgY29tcGFyaXNvbikKKyAgICAgICAgLy8KKyAgICAgICAgLy8gVmVyaWZpY2F0aW9uIG9mIHRoaXMgYXNzZXJ0aW9uIGlzIG5vdCBpbXBsZW1lbnRlZAorICAgICAgICAvLworICAgICAgICBzdXBlci5yZWFkU2V0T2Yoc2V0T2YpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWRTdHJpbmcoQVNOMVN0cmluZ1R5cGUgdHlwZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRhZyA9PSB0eXBlLmNvbnN0cklkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQVNOMUV4Y2VwdGlvbigiQVNOLjEgc3RyaW5nOiBjb25zdHJ1Y3RlZCBpZGVudGlmaWVyIGF0IFsiICsgdGFnT2Zmc2V0CisgICAgICAgICAgICAgICAgICAgICsgIl0uIE5vdCB2YWxpZCBmb3IgREVSLiIpOworICAgICAgICB9CisgICAgICAgIHN1cGVyLnJlYWRTdHJpbmcodHlwZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZFVUQ1RpbWUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGFnID09IEFTTjFDb25zdGFudHMuVEFHX0NfVVRDVElNRSkgeworICAgICAgICAgICAgLy8gSXQgaXMgYSBzdHJpbmcgdHlwZSBhbmQgaXQgY2FuIGJlIGVuY29kZWQgYXMgcHJpbWl0aXZlIG9yIGNvbnN0cnVjdGVkLgorICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIkFTTi4xIFVUQ1RpbWU6IGNvbnN0cnVjdGVkIGlkZW50aWZpZXIgYXQgWyIgKyB0YWdPZmZzZXQKKyAgICAgICAgICAgICAgICAgICAgKyAiXS4gTm90IHZhbGlkIGZvciBERVIuIik7CisgICAgICAgIH0KKworICAgICAgICAvLyBjaGVjayBmb3JtYXQ6IERFUiB1c2VzIFlZTU1EREhITU1TUydaJyBvbmx5CisgICAgICAgIGlmIChsZW5ndGggIT0gQVNOMVVUQ1RpbWUuVVRDX0hNUykgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFTTjFFeGNlcHRpb24oIkFTTi4xIFVUQ1RpbWU6IHdyb25nIGZvcm1hdCBmb3IgREVSLCBpZGVudGlmaWVyIGF0IFsiCisgICAgICAgICAgICAgICAgICAgICsgdGFnT2Zmc2V0ICsgIl0iKTsKKyAgICAgICAgfQorCisgICAgICAgIHN1cGVyLnJlYWRVVENUaW1lKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZEdlbmVyYWxpemVkVGltZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0YWcgPT0gQVNOMUNvbnN0YW50cy5UQUdfQ19HRU5FUkFMSVpFRFRJTUUpIHsKKyAgICAgICAgICAgIC8vIEl0IGlzIGEgc3RyaW5nIHR5cGUgYW5kIGl0IGNhbiBiZSBlbmNvZGVkIGFzIHByaW1pdGl2ZSBvciBjb25zdHJ1Y3RlZC4KKyAgICAgICAgICAgIHRocm93IG5ldyBBU04xRXhjZXB0aW9uKCJBU04uMSBHZW5lcmFsaXplZFRpbWU6IGNvbnN0cnVjdGVkIGlkZW50aWZpZXIgYXQgWyIKKyAgICAgICAgICAgICAgICAgICAgKyB0YWdPZmZzZXQgKyAiXS4gTm90IHZhbGlkIGZvciBERVIuIik7CisgICAgICAgIH0KKworICAgICAgICBzdXBlci5yZWFkR2VuZXJhbGl6ZWRUaW1lKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0Rlck91dHB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL0Rlck91dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU5YzRhYjcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2FzbjEvRGVyT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwyMjQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292LCBTdGVwYW4gTS4gTWlzaHVyYQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xOworCitpbXBvcnQgbGliY29yZS51dGlsLk9iamVjdHM7CisKKworLyoqCisgKiBFbmNvZGVzIEFTTi4xIHR5cGVzIHdpdGggREVSIChYLjY5MCkKKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9hc24xLmVsaWJlbC50bS5mci9lbi9zdGFuZGFyZHMvaW5kZXguaHRtIj5BU04uMTwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIERlck91dHB1dFN0cmVhbSBleHRlbmRzIEJlck91dHB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IGluaXRTaXplID0gMzI7CisgICAgcHJpdmF0ZSBpbnQgaW5kZXg7CisgICAgcHJpdmF0ZSBpbnRbXVtdIGxlbiA9IG5ldyBpbnRbaW5pdFNpemVdW107CisgICAgcHJpdmF0ZSBPYmplY3RbXVtdIHZhbCA9IG5ldyBPYmplY3RbaW5pdFNpemVdW107CisKKyAgICBwdWJsaWMgRGVyT3V0cHV0U3RyZWFtKEFTTjFUeXBlIGFzbjEsIE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgY29udGVudCA9IG9iamVjdDsKKyAgICAgICAgaW5kZXggPSAtMTsKKyAgICAgICAgYXNuMS5zZXRFbmNvZGluZ0NvbnRlbnQodGhpcyk7CisgICAgICAgIGVuY29kZWQgPSBuZXcgYnl0ZVthc24xLmdldEVuY29kZWRMZW5ndGgodGhpcyldOworICAgICAgICBpbmRleCA9IDA7CisgICAgICAgIGFzbjEuZW5jb2RlQVNOKHRoaXMpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBlbmNvZGVDaG9pY2UoQVNOMUNob2ljZSBjaG9pY2UpIHsKKyAgICAgICAgQVNOMVR5cGUgdHlwZSA9IChBU04xVHlwZSkgdmFsW2luZGV4XVswXTsKKyAgICAgICAgY29udGVudCA9IHZhbFtpbmRleF1bMV07CisgICAgICAgIGluZGV4Kys7CisgICAgICAgIHR5cGUuZW5jb2RlQVNOKHRoaXMpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBlbmNvZGVFeHBsaWNpdChBU04xRXhwbGljaXQgZXhwbGljaXQpIHsKKyAgICAgICAgY29udGVudCA9IHZhbFtpbmRleF1bMF07CisgICAgICAgIGxlbmd0aCA9IGxlbltpbmRleF1bMF07CisgICAgICAgIGluZGV4Kys7CisgICAgICAgIGV4cGxpY2l0LnR5cGUuZW5jb2RlQVNOKHRoaXMpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBlbmNvZGVTZXF1ZW5jZShBU04xU2VxdWVuY2Ugc2VxdWVuY2UpIHsKKyAgICAgICAgQVNOMVR5cGVbXSB0eXBlID0gc2VxdWVuY2UudHlwZTsKKworICAgICAgICBPYmplY3RbXSB2YWx1ZXMgPSB2YWxbaW5kZXhdOworICAgICAgICBpbnRbXSBjb21wTGVucyA9IGxlbltpbmRleF07CisKKyAgICAgICAgaW5kZXgrKzsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAodmFsdWVzW2ldID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY29udGVudCA9IHZhbHVlc1tpXTsKKyAgICAgICAgICAgIGxlbmd0aCA9IGNvbXBMZW5zW2ldOworCisgICAgICAgICAgICB0eXBlW2ldLmVuY29kZUFTTih0aGlzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBlbmNvZGVTZXF1ZW5jZU9mKEFTTjFTZXF1ZW5jZU9mIHNlcXVlbmNlT2YpIHsKKyAgICAgICAgZW5jb2RlVmFsdWVDb2xsZWN0aW9uKHNlcXVlbmNlT2YpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBlbmNvZGVTZXRPZihBU04xU2V0T2Ygc2V0T2YpIHsKKyAgICAgICAgZW5jb2RlVmFsdWVDb2xsZWN0aW9uKHNldE9mKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZW5jb2RlVmFsdWVDb2xsZWN0aW9uKEFTTjFWYWx1ZUNvbGxlY3Rpb24gY29sbGVjdGlvbikgeworICAgICAgICBPYmplY3RbXSB2YWx1ZXMgPSB2YWxbaW5kZXhdOworICAgICAgICBpbnRbXSBjb21wTGVucyA9IGxlbltpbmRleF07CisKKyAgICAgICAgaW5kZXgrKzsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNvbnRlbnQgPSB2YWx1ZXNbaV07CisgICAgICAgICAgICBsZW5ndGggPSBjb21wTGVuc1tpXTsKKyAgICAgICAgICAgIGNvbGxlY3Rpb24udHlwZS5lbmNvZGVBU04odGhpcyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcHVzaChpbnRbXSBsZW5ndGhzLCBPYmplY3RbXSB2YWx1ZXMpIHsKKyAgICAgICAgaW5kZXgrKzsKKyAgICAgICAgaWYgKGluZGV4ID09IHZhbC5sZW5ndGgpIHsKKworICAgICAgICAgICAgaW50W11bXSBuZXdMZW4gPSBuZXcgaW50W3ZhbC5sZW5ndGggKiAyXVtdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShsZW4sIDAsIG5ld0xlbiwgMCwgdmFsLmxlbmd0aCk7CisgICAgICAgICAgICBsZW4gPSBuZXdMZW47CisKKyAgICAgICAgICAgIE9iamVjdFtdW10gbmV3VmFsID0gbmV3IE9iamVjdFt2YWwubGVuZ3RoICogMl1bXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsLCAwLCBuZXdWYWwsIDAsIHZhbC5sZW5ndGgpOworICAgICAgICAgICAgdmFsID0gbmV3VmFsOworICAgICAgICB9CisgICAgICAgIGxlbltpbmRleF0gPSBsZW5ndGhzOworICAgICAgICB2YWxbaW5kZXhdID0gdmFsdWVzOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBnZXRDaG9pY2VMZW5ndGgoQVNOMUNob2ljZSBjaG9pY2UpIHsKKyAgICAgICAgaW50IGkgPSBjaG9pY2UuZ2V0SW5kZXgoY29udGVudCk7CisgICAgICAgIGNvbnRlbnQgPSBjaG9pY2UuZ2V0T2JqZWN0VG9FbmNvZGUoY29udGVudCk7CisKKyAgICAgICAgT2JqZWN0W10gdmFsdWVzID0gbmV3IE9iamVjdFtdIHsgY2hvaWNlLnR5cGVbaV0sIGNvbnRlbnQgfTsKKworICAgICAgICBwdXNoKG51bGwsIHZhbHVlcyk7CisKKyAgICAgICAgY2hvaWNlLnR5cGVbaV0uc2V0RW5jb2RpbmdDb250ZW50KHRoaXMpOworCisgICAgICAgIC8vIGluIGNhc2UgaWYgd2UgZ2V0IGNvbnRlbnQgYnl0ZXMgd2hpbGUgZ2V0dGluZyBpdHMgbGVuZ3RoCisgICAgICAgIC8vIEZJWE1FIHdoYXQgYWJvdXQgcmVtb3ZlIGl0OiBuZWVkIHJlZGVzaWduCisgICAgICAgIHZhbHVlc1sxXSA9IGNvbnRlbnQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGdldEV4cGxpY2l0TGVuZ3RoKEFTTjFFeHBsaWNpdCBleHBsaWNpdCkgeworICAgICAgICBPYmplY3RbXSB2YWx1ZXMgPSBuZXcgT2JqZWN0WzFdOworICAgICAgICBpbnRbXSBjb21wTGVucyA9IG5ldyBpbnRbMV07CisKKyAgICAgICAgdmFsdWVzWzBdID0gY29udGVudDsKKworICAgICAgICBwdXNoKGNvbXBMZW5zLCB2YWx1ZXMpOworCisgICAgICAgIGV4cGxpY2l0LnR5cGUuc2V0RW5jb2RpbmdDb250ZW50KHRoaXMpOworCisgICAgICAgIC8vIGluIGNhc2UgaWYgd2UgZ2V0IGNvbnRlbnQgYnl0ZXMgd2hpbGUgZ2V0dGluZyBpdHMgbGVuZ3RoCisgICAgICAgIC8vIEZJWE1FIHdoYXQgYWJvdXQgcmVtb3ZlIGl0OiBuZWVkIHJlZGVzaWduCisgICAgICAgIHZhbHVlc1swXSA9IGNvbnRlbnQ7CisgICAgICAgIGNvbXBMZW5zWzBdID0gbGVuZ3RoOworCisgICAgICAgIGxlbmd0aCA9IGV4cGxpY2l0LnR5cGUuZ2V0RW5jb2RlZExlbmd0aCh0aGlzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZ2V0U2VxdWVuY2VMZW5ndGgoQVNOMVNlcXVlbmNlIHNlcXVlbmNlKSB7CisgICAgICAgIEFTTjFUeXBlW10gdHlwZSA9IHNlcXVlbmNlLnR5cGU7CisKKyAgICAgICAgT2JqZWN0W10gdmFsdWVzID0gbmV3IE9iamVjdFt0eXBlLmxlbmd0aF07CisgICAgICAgIGludFtdIGNvbXBMZW5zID0gbmV3IGludFt0eXBlLmxlbmd0aF07CisKKyAgICAgICAgc2VxdWVuY2UuZ2V0VmFsdWVzKGNvbnRlbnQsIHZhbHVlcyk7CisKKyAgICAgICAgcHVzaChjb21wTGVucywgdmFsdWVzKTsKKworICAgICAgICBpbnQgc2VxTGVuID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAvLyBjaGVjayBvcHRpb25hbCB0eXBlcworICAgICAgICAgICAgaWYgKHZhbHVlc1tpXSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWYgKHNlcXVlbmNlLk9QVElPTkFMW2ldKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCk7Ly9GSVhNRSB0eXBlICYgbWVzc2FnZQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKE9iamVjdHMuZXF1YWwoc2VxdWVuY2UuREVGQVVMVFtpXSwgdmFsdWVzW2ldKSkgeworICAgICAgICAgICAgICAgIHZhbHVlc1tpXSA9IG51bGw7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNvbnRlbnQgPSB2YWx1ZXNbaV07CisKKyAgICAgICAgICAgIHR5cGVbaV0uc2V0RW5jb2RpbmdDb250ZW50KHRoaXMpOworCisgICAgICAgICAgICBjb21wTGVuc1tpXSA9IGxlbmd0aDsKKworICAgICAgICAgICAgLy8gaW4gY2FzZSBpZiB3ZSBnZXQgY29udGVudCBieXRlcyB3aGlsZSBnZXR0aW5nIGl0cyBsZW5ndGgKKyAgICAgICAgICAgIC8vIEZJWE1FIHdoYXQgYWJvdXQgcmVtb3ZlIGl0OiBuZWVkIHJlZGVzaWduCisgICAgICAgICAgICB2YWx1ZXNbaV0gPSBjb250ZW50OworCisgICAgICAgICAgICBzZXFMZW4gKz0gdHlwZVtpXS5nZXRFbmNvZGVkTGVuZ3RoKHRoaXMpOworICAgICAgICB9CisgICAgICAgIGxlbmd0aCA9IHNlcUxlbjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZ2V0U2VxdWVuY2VPZkxlbmd0aChBU04xU2VxdWVuY2VPZiBzZXF1ZW5jZSkgeworICAgICAgICBnZXRWYWx1ZU9mTGVuZ3RoKHNlcXVlbmNlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZ2V0U2V0T2ZMZW5ndGgoQVNOMVNldE9mIHNldE9mKSB7CisgICAgICAgIGdldFZhbHVlT2ZMZW5ndGgoc2V0T2YpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBnZXRWYWx1ZU9mTGVuZ3RoKEFTTjFWYWx1ZUNvbGxlY3Rpb24gY29sbGVjdGlvbikgeworICAgICAgICAvL0ZJWE1FIHdoYXQgYWJvdXQgYW5vdGhlciB3YXk/CisgICAgICAgIE9iamVjdFtdIGN2ID0gY29sbGVjdGlvbi5nZXRWYWx1ZXMoY29udGVudCkudG9BcnJheSgpOworCisgICAgICAgIE9iamVjdFtdIHZhbHVlcyA9IG5ldyBPYmplY3RbY3YubGVuZ3RoXTsKKyAgICAgICAgaW50W10gY29tcExlbnMgPSBuZXcgaW50W3ZhbHVlcy5sZW5ndGhdOworCisgICAgICAgIHB1c2goY29tcExlbnMsIHZhbHVlcyk7CisgICAgICAgIGludCBzZXFMZW4gPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykgeworCisgICAgICAgICAgICBjb250ZW50ID0gY3ZbaV07CisKKyAgICAgICAgICAgIGNvbGxlY3Rpb24udHlwZS5zZXRFbmNvZGluZ0NvbnRlbnQodGhpcyk7CisKKyAgICAgICAgICAgIGNvbXBMZW5zW2ldID0gbGVuZ3RoOworCisgICAgICAgICAgICAvLyBpbiBjYXNlIGlmIHdlIGdldCBjb250ZW50IGJ5dGVzIHdoaWxlIGdldHRpbmcgaXRzIGxlbmd0aAorICAgICAgICAgICAgLy8gRklYTUUgd2hhdCBhYm91dCByZW1vdmUgaXQ6IG5lZWQgcmVkZXNpZ24KKyAgICAgICAgICAgIHZhbHVlc1tpXSA9IGNvbnRlbnQ7CisKKyAgICAgICAgICAgIHNlcUxlbiArPSBjb2xsZWN0aW9uLnR5cGUuZ2V0RW5jb2RlZExlbmd0aCh0aGlzKTsKKyAgICAgICAgfQorICAgICAgICBsZW5ndGggPSBzZXFMZW47CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9hc24xL09iamVjdElkZW50aWZpZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9PYmplY3RJZGVudGlmaWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjQxNDBlNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvYXNuMS9PYmplY3RJZGVudGlmaWVyLmphdmEKQEAgLTAsMCArMSwyNjcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFN0ZXBhbiBNLiBNaXNodXJhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjE7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCisvKioKKyAqIEluc3RhbmNlIG9mIHRoaXMgY2xhc3MgcmVwcmVzZW50cyBPYmplY3RJZGVudGlmaWVyIChPSUQpLgorICoKKyAqIEFjY29yZGluZyB0byBYLjY5MDoKKyAqIE9JRCBpcyByZXByZXNlbnRlZCBhcyBhIHNlcXVlbmNlIG9mIHN1YmlkZW50aWZpZXIuCisgKiBFYWNoIHN1YmlkZW50aWZpZXIgaXMgcmVwcmVzZW50ZWQgYXMgbm9uIG5lZ2F0aXZlIGludGVnZXIgdmFsdWUuCisgKiBUaGVyZSBhcmUgYXQgbGVhc3QgMiBzdWJpZGVudGlmaWVycyBpbiB0aGUgc2VxdWVuY2UuCisgKgorICogVmFsaWQgdmFsdWVzIGZvciBmaXJzdCBzdWJpZGVudGlmaWVyIGFyZSAwLCAxIGFuZCAyLgorICogSWYgdGhlIGZpcnN0IHN1YmlkZW50aWZpZXIgaGFzIDAgb3IgMSB2YWx1ZSB0aGUgc2Vjb25kCisgKiBzdWJpZGVudGlmaWVyIG11c3QgYmUgbGVzcyB0aGVuIDQwLgorICoKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2FzbjEuZWxpYmVsLnRtLmZyL2VuL3N0YW5kYXJkcy9pbmRleC5odG0iPkFTTi4xPC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgT2JqZWN0SWRlbnRpZmllciB7CisKKyAgICAvKiogT0lEIGFzIGFycmF5IG9mIGludGVnZXJzICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnRbXSBvaWQ7CisKKyAgICAvKiogT0lEIGFzIHN0cmluZyAqLworICAgIHByaXZhdGUgU3RyaW5nIHNvaWQ7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIE9iamVjdElkZW50aWZpZXIoT0lEKSBmcm9tIGFycmF5IG9mIGludGVnZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIG9pZCBhcnJheSBvZiBpbnRlZ2VycworICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIG9pZCBpcyBpbnZhbGlkIG9yIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0SWRlbnRpZmllcihpbnRbXSBvaWQpIHsKKyAgICAgICAgdmFsaWRhdGUob2lkKTsKKyAgICAgICAgdGhpcy5vaWQgPSBvaWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBPYmplY3RJZGVudGlmaWVyKE9JRCkgZnJvbSBzdHJpbmcgcmVwcmVzZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyT2lkIG9pZCBzdHJpbmcKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBvaWQgc3RyaW5nIGlzIGludmFsaWQgb3IgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBPYmplY3RJZGVudGlmaWVyKFN0cmluZyBzdHJPaWQpIHsKKyAgICAgICAgdGhpcy5vaWQgPSB0b0ludEFycmF5KHN0ck9pZCk7CisgICAgICAgIHRoaXMuc29pZCA9IHN0ck9pZDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgIGlmICh0aGlzID09IG8pIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChvID09IG51bGwgfHwgdGhpcy5nZXRDbGFzcygpICE9IG8uZ2V0Q2xhc3MoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKG9pZCwgKChPYmplY3RJZGVudGlmaWVyKSBvKS5vaWQpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBpZiAoc29pZCA9PSBudWxsKSB7CisgICAgICAgICAgICBzb2lkID0gdG9TdHJpbmcob2lkKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc29pZDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgLy8gRklYTUUgY2hhbmdlIG1lIHRvIEFycmF5cy5oYXNoQ29kZShpbnRbXSkKKyAgICAgICAgaW50IGludEhhc2ggPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9pZC5sZW5ndGggJiYgaSA8IDQ7IGkrKykgeworICAgICAgICAgICAgaW50SGFzaCArPSBvaWRbaV0gPDwgKDggKiBpKTsgLy9UT0RPIHdoYXQgYWJvdXQgdG8gZmluZCBiZXR0ZXIgb25lPworICAgICAgICB9CisgICAgICAgIHJldHVybiBpbnRIYXNoICYgMHg3RkZGRkZGRjsgLy8gb25seSBwb3NpdGl2ZQorICAgIH0KKworICAgIC8qKgorICAgICAqIFZhbGlkYXRlcyBPYmplY3RJZGVudGlmaWVyIChPSUQpLgorICAgICAqCisgICAgICogQHBhcmFtIG9pZCBvaWQgYXMgYXJyYXkgb2YgaW50ZWdlcnMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBvaWQgaXMgaW52YWxpZCBvciBudWxsCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHZhbGlkYXRlKGludFtdIG9pZCkgeworICAgICAgICBpZiAob2lkID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm9pZCA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAob2lkLmxlbmd0aCA8IDIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk9JRCBNVVNUIGhhdmUgYXQgbGVhc3QgMiBzdWJpZGVudGlmaWVycyIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG9pZFswXSA+IDIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJWYWxpZCB2YWx1ZXMgZm9yIGZpcnN0IHN1YmlkZW50aWZpZXIgYXJlIDAsIDEgYW5kIDIiKTsKKyAgICAgICAgfSBlbHNlIGlmIChvaWRbMF0gIT0gMiAmJiBvaWRbMV0gPiAzOSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSWYgdGhlIGZpcnN0IHN1YmlkZW50aWZpZXIgaGFzIDAgb3IgMSB2YWx1ZSB0aGUgIgorICAgICAgICAgICAgICAgICAgICArICJzZWNvbmQgc3ViaWRlbnRpZmllciB2YWx1ZSBNVVNUIGJlIGxlc3MgdGhhbiA0MCIpOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgYW5PaWQgOiBvaWQpIHsKKyAgICAgICAgICAgIGlmIChhbk9pZCA8IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJTdWJpZGVudGlmaWVyIE1VU1QgaGF2ZSBwb3NpdGl2ZSB2YWx1ZSIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgT0lELgorICAgICAqCisgICAgICogTm90ZTogaXQgaXMgc3VwcG9zZWQgdGhhdCBwYXNzZWQgYXJyYXkgb2YgaW50ZWdlcnMKKyAgICAgKiBjb250YWlucyB2YWxpZCBPSUQgdmFsdWUsIHNvIG5vIGNoZWNrcyBhcmUgcGVyZm9ybWVkLgorICAgICAqCisgICAgICogQHBhcmFtIG9pZCBvaWQgYXMgYXJyYXkgb2YgaW50ZWdlcnMKKyAgICAgKiBAcmV0dXJuIG9pZCBzdHJpbmcgcmVwcmVzZW50YXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b1N0cmluZyhpbnRbXSBvaWQpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKDMgKiBvaWQubGVuZ3RoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9pZC5sZW5ndGggLSAxOyArK2kpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZChvaWRbaV0pOworICAgICAgICAgICAgc2IuYXBwZW5kKCcuJyk7CisgICAgICAgIH0KKyAgICAgICAgc2IuYXBwZW5kKG9pZFtvaWQubGVuZ3RoIC0gMV0pOworICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIE9iamVjdElkZW50aWZpZXIgKE9JRCkgZnJvbSBzdHJpbmcgcmVwcmVzZW50YXRpb24uCisgICAgICoKKyAgICAgKiBTdHJpbmcgcmVwcmVzZW50YXRpb24gaXMgZGVmaW5lZCBieSB0aGUgZm9sbG93aW5nIHN5bnRheDoKKyAgICAgKiAgICAgT0lEID0gc3ViaWRlbnRpZmllciAxKigiLiIgc3ViaWRlbnRpZmllcikKKyAgICAgKiAgICAgc3ViaWRlbnRpZmllciA9IDEqKGRpZ2l0KQorICAgICAqCisgICAgICogQHBhcmFtIHN0ciBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgT0lECisgICAgICogQHJldHVybiBvaWQgYXMgYXJyYXkgb2YgaW50ZWdlcnMKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBvaWQgc3RyaW5nIGlzIGludmFsaWQgb3IgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50W10gdG9JbnRBcnJheShTdHJpbmcgc3RyKSB7CisgICAgICAgIHJldHVybiB0b0ludEFycmF5KHN0ciwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBzdHJpbmcgaXMgYSB2YWxpZCBPYmplY3RJZGVudGlmaWVyCisgICAgICogKE9JRCkgcmVwcmVzZW50YXRpb24uCisgICAgICoKKyAgICAgKiBTdHJpbmcgcmVwcmVzZW50YXRpb24gaXMgZGVmaW5lZCBhcyBmb3Ige0BsaW5rICN0b0ludEFycmF5fS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHIgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIE9JRAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBvaWRTdHJpbmcgaGFzIHZhbGlkIHN5bnRheCBvciBmYWxzZSBpZiBub3QKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNPSUQoU3RyaW5nIHN0cikgeworICAgICAgICByZXR1cm4gdG9JbnRBcnJheShzdHIsIGZhbHNlKSAhPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgT2JqZWN0SWRlbnRpZmllciAoT0lEKSBmcm9tIHN0cmluZyByZXByZXNlbnRhdGlvbi4KKyAgICAgKgorICAgICAqIFN0cmluZyByZXByZXNlbnRhdGlvbiBpcyBkZWZpbmVkIGJ5IHRoZSBmb2xsb3dpbmcgc3ludGF4OgorICAgICAqICAgICBPSUQgPSBzdWJpZGVudGlmaWVyIDEqKCIuIiBzdWJpZGVudGlmaWVyKQorICAgICAqICAgICBzdWJpZGVudGlmaWVyID0gMSooZGlnaXQpCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBPSUQKKyAgICAgKiBAcmV0dXJuIG9pZCBhcyBhcnJheSBvZiBpbnRlZ2VycyBvciBudWxsIGlmIHRoZSBvaWQgc3RyaW5nIGlzCisgICAgICogaW52YWxpZCBvciBudWxsIGFuZCBzaG91bGRUaHJvdyBpcyBmYWxzZQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIG9pZCBzdHJpbmcgaXMgaW52YWxpZCBvciBudWxsIGFuZAorICAgICAqIHNob3VsZFRocm93IGlzIHRydWUKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBpbnRbXSB0b0ludEFycmF5KFN0cmluZyBzdHIsIGJvb2xlYW4gc2hvdWxkVGhyb3cpIHsKKyAgICAgICAgaWYgKHN0ciA9PSBudWxsKSB7CisgICAgICAgICAgICBpZiAoISBzaG91bGRUaHJvdykgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaW50IGxlbmd0aCA9IHN0ci5sZW5ndGgoKTsKKyAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICBpZiAoISBzaG91bGRUaHJvdykgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW5jb3JyZWN0IHN5bnRheCIpOworICAgICAgICB9CisKKyAgICAgICAgaW50IGNvdW50ID0gMTsgLy8gbnVtYmVyIG9mIHN1YmlkZW50aWZpZXJzCisgICAgICAgIGJvb2xlYW4gd2FzRG90ID0gdHJ1ZTsgLy8gaW5kaWNhdGVzIHdoZXRoZXIgY2hhciBiZWZvcmUgd2FzIGRvdCBvciBub3QuCisgICAgICAgIGNoYXIgYzsgLy8gY3VycmVudCBjaGFyCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGMgPSBzdHIuY2hhckF0KGkpOworICAgICAgICAgICAgaWYgKGMgPT0gJy4nKSB7CisgICAgICAgICAgICAgICAgaWYgKHdhc0RvdCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoISBzaG91bGRUaHJvdykgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW5jb3JyZWN0IHN5bnRheCIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB3YXNEb3QgPSB0cnVlOworICAgICAgICAgICAgICAgIGNvdW50Kys7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGMgPj0gJzAnICYmIGMgPD0gJzknKSB7CisgICAgICAgICAgICAgICAgd2FzRG90ID0gZmFsc2U7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmICghIHNob3VsZFRocm93KSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbmNvcnJlY3Qgc3ludGF4Iik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAod2FzRG90KSB7CisgICAgICAgICAgICAvLyB0aGUgbGFzdCBjaGFyIGlzIGRvdAorICAgICAgICAgICAgaWYgKCEgc2hvdWxkVGhyb3cpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkluY29ycmVjdCBzeW50YXgiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjb3VudCA8IDIpIHsKKyAgICAgICAgICAgIGlmICghIHNob3VsZFRocm93KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbmNvcnJlY3Qgc3ludGF4Iik7CisgICAgICAgIH0KKworICAgICAgICBpbnRbXSBvaWQgPSBuZXcgaW50W2NvdW50XTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDAsIGogPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGMgPSBzdHIuY2hhckF0KGkpOworICAgICAgICAgICAgaWYgKGMgPT0gJy4nKSB7CisgICAgICAgICAgICAgICAgaisrOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBvaWRbal0gPSBvaWRbal0gKiAxMCArIGMgLSA0ODsgLy8gJzAnID0gNDgKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChvaWRbMF0gPiAyKSB7CisgICAgICAgICAgICBpZiAoISBzaG91bGRUaHJvdykgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW5jb3JyZWN0IHN5bnRheCIpOworICAgICAgICB9IGVsc2UgaWYgKG9pZFswXSAhPSAyICYmIG9pZFsxXSA+IDM5KSB7CisgICAgICAgICAgICBpZiAoISBzaG91bGRUaHJvdykgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW5jb3JyZWN0IHN5bnRheCIpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG9pZDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2ZvcnRyZXNzL0VuZ2luZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9mb3J0cmVzcy9FbmdpbmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YTY3YWMyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9mb3J0cmVzcy9FbmdpbmUuamF2YQpAQCAtMCwwICsxLDE4MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQm9yaXMgVi4gS3V6bmV0c292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmZvcnRyZXNzOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGNvbW1vbiBmdW5jdGlvbmFsaXR5IGZvciBQcm92aWRlciBzdXBwbGllZAorICogY2xhc3Nlcy4gVGhlIHVzYWdlIHBhdHRlcm4gaXMgdG8gYWxsb2NhdGUgc3RhdGljIEVuZ2luZSBpbnN0YW5jZQorICogcGVyIHNlcnZpY2UgdHlwZSBhbmQgc3luY2hyb25pemUgb24gdGhhdCBpbnN0YW5jZSBkdXJpbmcgY2FsbHMgdG8KKyAqIHtAY29kZSBnZXRJbnN0YW5jZX0gYW5kIHJldHJlaXZhbCBvZiB0aGUgc2VsZWN0ZWQge0Bjb2RlIFByb3ZpZGVyfQorICogYW5kIFNlcnZpY2UgUHJvdmlkZXIgSW50ZXJmYWNlIChTUEkpIHJlc3VsdHMuIFJldHJlaXZpbmcgdGhlCisgKiByZXN1bHRzIHdpdGgge0Bjb2RlIGdldFByb3ZpZGVyfSBhbmQge0Bjb2RlIGdldFNwaX0gc2V0cyB0aGUKKyAqIGludGVybmFsIHtAY29kZSBFbmdpbmV9IHZhbHVlcyB0byBudWxsIHRvIHByZXZlbnQgbWVtb3J5IGxlYWtzLgorICoKKyAqIDxwPgorICoKKyAqIEZvciBleGFtcGxlOiA8cHJlPiAgIHtAY29kZQorICogICBwdWJsaWMgY2xhc3MgRm9vIHsKKyAqCisgKiAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFbmdpbmUgRU5HSU5FID0gbmV3IEVuZ2luZSgiRm9vIik7CisgKgorICogICAgICAgcHJpdmF0ZSBmaW5hbCBGb29TcGkgc3BpOworICogICAgICAgcHJpdmF0ZSBmaW5hbCBQcm92aWRlciBwcm92aWRlcjsKKyAqICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGFsZ29yaXRobTsKKyAqCisgKiAgICAgICBwcm90ZWN0ZWQgRm9vKEZvb1NwaSBzcGksCisgKiAgICAgICAgICAgICAgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyLAorICogICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYWxnb3JpdGhtKSB7CisgKiAgICAgICAgICAgdGhpcy5zcGkgPSBzcGk7CisgKiAgICAgICAgICAgdGhpcy5wcm92aWRlciA9IHByb3ZpZGVyOworICogICAgICAgICAgIHRoaXMuYWxnb3JpdGhtID0gYWxnb3JpdGhtOworICogICAgICAgfQorICoKKyAqICAgICAgIHB1YmxpYyBzdGF0aWMgRm9vIGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pIHsKKyAqICAgICAgICAgICBFbmdpbmUuU3BpQW5kUHJvdmlkZXIgc2FwID0gRU5HSU5FLmdldEluc3RhbmNlKGFsZ29yaXRobSwgbnVsbCk7CisgKiAgICAgICAgICAgcmV0dXJuIG5ldyBGb28oKEZvb1NwaSkgc2FwLnNwaSwgc2FwLnByb3ZpZGVyLCBhbGdvcml0aG0pOworICogICAgICAgfQorICoKKyAqICAgICAgIHB1YmxpYyBzdGF0aWMgRm9vIGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKSB7CisgKiAgICAgICAgICAgT2JqZWN0IHNwaSA9IEVOR0lORS5nZXRJbnN0YW5jZShhbGdvcml0aG0sIHByb3ZpZGVyLCBudWxsKTsKKyAqICAgICAgICAgICByZXR1cm4gbmV3IEZvbygoRm9vU3BpKSBzcGksIHByb3ZpZGVyLCBhbGdvcml0aG0pOworICogICAgICAgfQorICoKKyAqICAgICAgIC4uLgorICoKKyAqIH08L3ByZT4KKyAqLworcHVibGljIGNsYXNzIEVuZ2luZSB7CisKKyAgICAvKioKKyAgICAgKiBBY2Nlc3MgdG8gcGFja2FnZSB2aXNpYmxlIGFwaSBpbiBqYXZhLnNlY3VyaXR5CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTZWN1cml0eUFjY2VzcyBkb29yOworCisgICAgLyoqCisgICAgICogU2VydmljZSBuYW1lIHN1Y2ggYXMgQ2lwaGVyIG9yIFNTTENvbnRleHQKKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBzZXJ2aWNlTmFtZTsKKworICAgIC8qKgorICAgICAqIFByZXZpb3VzIHJlc3VsdCBmb3IgZ2V0SW5zdGFuY2UoU3RyaW5nLCBPYmplY3QpIG9wdGltaXphdGlvbi4KKyAgICAgKiBPbmx5IHRoaXMgbm9uLVByb3ZpZGVyIHZlcnNpb24gb2YgZ2V0SW5zdGFuY2UgaXMgb3B0aW1pemVkCisgICAgICogc2luY2UgdGhlIHRoZSBQcm92aWRlciB2ZXJzaW9uIGRvZXMgbm90IHJlcXVpcmUgYW4gZXhwZW5zaXZlCisgICAgICogU2VydmljZXMuZ2V0U2VydmljZSBjYWxsLgorICAgICAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgU2VydmljZUNhY2hlRW50cnkgc2VydmljZUNhY2hlOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU2VydmljZUNhY2hlRW50cnkgeworICAgICAgICAvKiogdXNlZCB0byB0ZXN0IGZvciBjYWNoZSBoaXQgKi8KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgYWxnb3JpdGhtOworICAgICAgICAvKiogdXNlZCB0byB0ZXN0IGZvciBjYWNoZSB2YWxpZGl0eSAqLworICAgICAgICBwcml2YXRlIGZpbmFsIGludCByZWZyZXNoTnVtYmVyOworICAgICAgICAvKiogY2FjaGVkIHJlc3VsdCAqLworICAgICAgICBwcml2YXRlIGZpbmFsIFByb3ZpZGVyLlNlcnZpY2Ugc2VydmljZTsKKworICAgICAgICBwcml2YXRlIFNlcnZpY2VDYWNoZUVudHJ5KFN0cmluZyBhbGdvcml0aG0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHJlZnJlc2hOdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJvdmlkZXIuU2VydmljZSBzZXJ2aWNlKSB7CisgICAgICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICAgICAgICAgIHRoaXMucmVmcmVzaE51bWJlciA9IHJlZnJlc2hOdW1iZXI7CisgICAgICAgICAgICB0aGlzLnNlcnZpY2UgPSBzZXJ2aWNlOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBTcGlBbmRQcm92aWRlciB7CisgICAgICAgIHB1YmxpYyBmaW5hbCBPYmplY3Qgc3BpOworICAgICAgICBwdWJsaWMgZmluYWwgUHJvdmlkZXIgcHJvdmlkZXI7CisgICAgICAgIHByaXZhdGUgU3BpQW5kUHJvdmlkZXIoT2JqZWN0IHNwaSwgUHJvdmlkZXIgcHJvdmlkZXIpIHsKKyAgICAgICAgICAgIHRoaXMuc3BpID0gc3BpOworICAgICAgICAgICAgdGhpcy5wcm92aWRlciA9IHByb3ZpZGVyOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIEVuZ2luZSBvYmplY3QKKyAgICAgKgorICAgICAqIEBwYXJhbSBzZXJ2aWNlCisgICAgICovCisgICAgcHVibGljIEVuZ2luZShTdHJpbmcgc2VydmljZSkgeworICAgICAgICB0aGlzLnNlcnZpY2VOYW1lID0gc2VydmljZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kcyB0aGUgYXBwcm9wcmlhdGUgc2VydmljZSBpbXBsZW1lbnRhdGlvbiBhbmQgcmV0dXJucyBhbgorICAgICAqIHtAY29kZSBTcGlBbmRQcm92aWRlcn0gaW5zdGFuY2UgY29udGFpbmluZyBhIHJlZmVyZW5jZSB0byBTUEkKKyAgICAgKiBhbmQgaXRzIHtAY29kZSBQcm92aWRlcn0KKyAgICAgKi8KKyAgICBwdWJsaWMgU3BpQW5kUHJvdmlkZXIgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgT2JqZWN0IHBhcmFtKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhbGdvcml0aG0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbigiTnVsbCBhbGdvcml0aG0gbmFtZSIpOworICAgICAgICB9CisgICAgICAgIFNlcnZpY2VzLnJlZnJlc2goKTsKKyAgICAgICAgUHJvdmlkZXIuU2VydmljZSBzZXJ2aWNlOworICAgICAgICBTZXJ2aWNlQ2FjaGVFbnRyeSBjYWNoZUVudHJ5ID0gdGhpcy5zZXJ2aWNlQ2FjaGU7CisgICAgICAgIGlmIChjYWNoZUVudHJ5ICE9IG51bGwKKyAgICAgICAgICAgICAgICAmJiBjYWNoZUVudHJ5LmFsZ29yaXRobS5lcXVhbHNJZ25vcmVDYXNlKGFsZ29yaXRobSkKKyAgICAgICAgICAgICAgICAmJiBTZXJ2aWNlcy5yZWZyZXNoTnVtYmVyID09IGNhY2hlRW50cnkucmVmcmVzaE51bWJlcikgeworICAgICAgICAgICAgc2VydmljZSA9IGNhY2hlRW50cnkuc2VydmljZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChTZXJ2aWNlcy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBub3RGb3VuZChzZXJ2aWNlTmFtZSwgYWxnb3JpdGhtKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN0cmluZyBuYW1lID0gdGhpcy5zZXJ2aWNlTmFtZSArICIuIiArIGFsZ29yaXRobS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpOworICAgICAgICAgICAgc2VydmljZSA9IFNlcnZpY2VzLmdldFNlcnZpY2UobmFtZSk7CisgICAgICAgICAgICBpZiAoc2VydmljZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbm90Rm91bmQoc2VydmljZU5hbWUsIGFsZ29yaXRobSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aGlzLnNlcnZpY2VDYWNoZSA9IG5ldyBTZXJ2aWNlQ2FjaGVFbnRyeShhbGdvcml0aG0sIFNlcnZpY2VzLnJlZnJlc2hOdW1iZXIsIHNlcnZpY2UpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU3BpQW5kUHJvdmlkZXIoc2VydmljZS5uZXdJbnN0YW5jZShwYXJhbSksIHNlcnZpY2UuZ2V0UHJvdmlkZXIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgdGhlIGFwcHJvcHJpYXRlIHNlcnZpY2UgaW1wbGVtZW50YXRpb24gYW5kIHJldHVybnMgYW5kCisgICAgICogaW5zdGFuY2Ugb2YgdGhlIGNsYXNzIHRoYXQgaW1wbGVtZW50cyBjb3JyZXNwb25kaW5nIFNlcnZpY2UKKyAgICAgKiBQcm92aWRlciBJbnRlcmZhY2UuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBQcm92aWRlciBwcm92aWRlciwgT2JqZWN0IHBhcmFtKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhbGdvcml0aG0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbigiYWxnb3JpdGhtID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlci5TZXJ2aWNlIHNlcnZpY2UgPSBwcm92aWRlci5nZXRTZXJ2aWNlKHNlcnZpY2VOYW1lLCBhbGdvcml0aG0pOworICAgICAgICBpZiAoc2VydmljZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBub3RGb3VuZChzZXJ2aWNlTmFtZSwgYWxnb3JpdGhtKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2VydmljZS5uZXdJbnN0YW5jZShwYXJhbSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbm90Rm91bmQoU3RyaW5nIHNlcnZpY2VOYW1lLCBTdHJpbmcgYWxnb3JpdGhtKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oc2VydmljZU5hbWUgKyAiICIgKyBhbGdvcml0aG0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgaW1wbGVtZW50YXRpb24gbm90IGZvdW5kIik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9mb3J0cmVzcy9TZWN1cml0eUFjY2Vzcy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9mb3J0cmVzcy9TZWN1cml0eUFjY2Vzcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJlM2UwY2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2ZvcnRyZXNzL1NlY3VyaXR5QWNjZXNzLmphdmEKQEAgLTAsMCArMSw1NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQm9yaXMgVi4gS3V6bmV0c292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmZvcnRyZXNzOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKgorICogVGhpcyBpbnRlcmZhY2UgcHJvdmlkZXMgYWNjZXNzIHRvIHBhY2thZ2UgdmlzaWJsZSBhcGkgaW4gamF2YS5zZWN1cml0eQorICoKKyAqLworcHVibGljIGludGVyZmFjZSBTZWN1cml0eUFjY2VzcyB7CisgICAgLyoqCisgICAgICogQWNjZXNzIHRvIFNlY3VyaXR5LnJlbnVtUHJvdmlkZXJzKCkKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbnVtUHJvdmlkZXJzKCk7CisKKyAgICAvKioKKyAgICAgKiBBY2Nlc3MgdG8gU2VydmljZS5nZXRBbGlhc2VzKCkKKyAgICAgKiBAcGFyYW0gcworICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxTdHJpbmc+IGdldEFsaWFzZXMoUHJvdmlkZXIuU2VydmljZSBzKTsKKworICAgIC8qKgorICAgICAqIEFjY2VzcyB0byBQcm92aWRlci5nZXRTZXJ2aWNlKFN0cmluZyB0eXBlKQorICAgICAqIEBwYXJhbSBwCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIFByb3ZpZGVyLlNlcnZpY2UgZ2V0U2VydmljZShQcm92aWRlciBwLCBTdHJpbmcgdHlwZSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2ZvcnRyZXNzL1NlcnZpY2VzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L2ZvcnRyZXNzL1NlcnZpY2VzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDk3ZTBmNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvZm9ydHJlc3MvU2VydmljZXMuamF2YQpAQCAtMCwwICsxLDIzNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQm9yaXMgVi4gS3V6bmV0c292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmZvcnRyZXNzOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCisKKy8qKgorICogVGhpcyBjbGFzcyBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBhbGwgcmVnaXN0ZXJlZCBwcm92aWRlcnMgYW5kIHByZWZlcnJlZAorICogaW1wbGVtZW50YXRpb25zIGZvciBhbGwgInNlcnZpY2VOYW1lLmFsZ05hbWUiLgorICoKKyAqLworCitwdWJsaWMgY2xhc3MgU2VydmljZXMgeworCisgICAgLy8gVGhlIEhhc2hNYXAgdGhhdCBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBwcmVmZXJyZWQgaW1wbGVtZW50YXRpb25zIGZvcgorICAgIC8vIGFsbCBzZXJ2aWNlTmFtZS5hbGdOYW1lIGluIHRoZSByZWdpc3RlcmVkIHByb3ZpZGVycy4KKyAgICAvLyBTZXQgdGhlIGluaXRpYWwgc2l6ZSB0byA2MDAgc28gd2UgZG9uJ3QgZ3JvdyB0byAxMDI0IGJ5IGRlZmF1bHQgYmVjYXVzZQorICAgIC8vIGluaXRpYWxpemF0aW9uIGFkZHMgYSBmZXcgZW50cmllcyBtb3JlIHRoYW4gdGhlIGdyb3d0aCB0aHJlc2hvbGQuCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPFN0cmluZywgUHJvdmlkZXIuU2VydmljZT4gc2VydmljZXMKKyAgICAgICAgICAgID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBQcm92aWRlci5TZXJ2aWNlPig2MDApOworICAgIC8vIFNhdmUgZGVmYXVsdCBTZWN1cmVSYW5kb20gc2VydmljZSBhcyB3ZWxsLgorICAgIC8vIEF2b2lkcyBzaW1pbGFyIHByb3ZpZGVyL3NlcnZpY2VzIGl0ZXJhdGlvbiBpbiBTZWN1cmVSYW5kb20gY29uc3RydWN0b3IKKyAgICBwcml2YXRlIHN0YXRpYyBQcm92aWRlci5TZXJ2aWNlIHNlY3VyZVJhbmRvbTsKKworICAgIC8vIE5lZWQgcmVmcmVzaCBmbGFnCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBuZWVkUmVmcmVzaDsgLy8gPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIFJlZnJlc2ggbnVtYmVyCisgICAgICovCisgICAgc3RhdGljIGludCByZWZyZXNoTnVtYmVyID0gMTsKKworICAgIC8vIFJlZ2lzdGVyZWQgcHJvdmlkZXJzCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTGlzdDxQcm92aWRlcj4gcHJvdmlkZXJzID0gbmV3IEFycmF5TGlzdDxQcm92aWRlcj4oMjApOworCisgICAgLy8gSGFzaCBmb3IgcXVpY2sgcHJvdmlkZXIgYWNjZXNzIGJ5IG5hbWUKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8U3RyaW5nLCBQcm92aWRlcj4gcHJvdmlkZXJzTmFtZXMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFByb3ZpZGVyPigyMCk7CisgICAgc3RhdGljIHsKKyAgICAgICAgbG9hZFByb3ZpZGVycygpOworICAgIH0KKworICAgIC8vIExvYWQgc3RhdGljYWxseSByZWdpc3RlcmVkIHByb3ZpZGVycyBhbmQgaW5pdCBTZXJ2aWNlcyBJbmZvCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBsb2FkUHJvdmlkZXJzKCkgeworICAgICAgICBTdHJpbmcgcHJvdmlkZXJDbGFzc05hbWUgPSBudWxsOworICAgICAgICBpbnQgaSA9IDE7CisgICAgICAgIENsYXNzTG9hZGVyIGNsID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKTsKKyAgICAgICAgUHJvdmlkZXIgcDsKKworICAgICAgICB3aGlsZSAoKHByb3ZpZGVyQ2xhc3NOYW1lID0gU2VjdXJpdHkuZ2V0UHJvcGVydHkoInNlY3VyaXR5LnByb3ZpZGVyLiIKKyAgICAgICAgICAgICAgICArIGkrKykpICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcCA9IChQcm92aWRlcikgQ2xhc3MKKyAgICAgICAgICAgICAgICAgICAgICAgIC5mb3JOYW1lKHByb3ZpZGVyQ2xhc3NOYW1lLnRyaW0oKSwgdHJ1ZSwgY2wpCisgICAgICAgICAgICAgICAgICAgICAgICAubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgICAgICAgICBwcm92aWRlcnMuYWRkKHApOworICAgICAgICAgICAgICAgIHByb3ZpZGVyc05hbWVzLnB1dChwLmdldE5hbWUoKSwgcCk7CisgICAgICAgICAgICAgICAgaW5pdFNlcnZpY2VJbmZvKHApOworICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7IC8vIGlnbm9yZSBFeGNlcHRpb25zCisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIEVuZ2luZS5kb29yLnJlbnVtUHJvdmlkZXJzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyByZWdpc3RlcmVkIHByb3ZpZGVycworICAgICAqCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUHJvdmlkZXJbXSBnZXRQcm92aWRlcnMoKSB7CisgICAgICAgIHJldHVybiBwcm92aWRlcnMudG9BcnJheShuZXcgUHJvdmlkZXJbcHJvdmlkZXJzLnNpemUoKV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgcmVnaXN0ZXJlZCBwcm92aWRlcnMgYXMgTGlzdAorICAgICAqCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTGlzdDxQcm92aWRlcj4gZ2V0UHJvdmlkZXJzTGlzdCgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBBcnJheUxpc3Q8UHJvdmlkZXI+KHByb3ZpZGVycyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJvdmlkZXIgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUKKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUHJvdmlkZXIgZ2V0UHJvdmlkZXIoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHByb3ZpZGVyc05hbWVzLmdldChuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIGEgcHJvdmlkZXIgYXQgYSBzcGVjaWZpZWQgcG9zaXRpb24KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcm92aWRlcgorICAgICAqIEBwYXJhbSBwb3NpdGlvbgorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBpbnNlcnRQcm92aWRlckF0KFByb3ZpZGVyIHByb3ZpZGVyLCBpbnQgcG9zaXRpb24pIHsKKyAgICAgICAgaW50IHNpemUgPSBwcm92aWRlcnMuc2l6ZSgpOworICAgICAgICBpZiAoKHBvc2l0aW9uIDwgMSkgfHwgKHBvc2l0aW9uID4gc2l6ZSkpIHsKKyAgICAgICAgICAgIHBvc2l0aW9uID0gc2l6ZSArIDE7CisgICAgICAgIH0KKyAgICAgICAgcHJvdmlkZXJzLmFkZChwb3NpdGlvbiAtIDEsIHByb3ZpZGVyKTsKKyAgICAgICAgcHJvdmlkZXJzTmFtZXMucHV0KHByb3ZpZGVyLmdldE5hbWUoKSwgcHJvdmlkZXIpOworICAgICAgICBzZXROZWVkUmVmcmVzaCgpOworICAgICAgICByZXR1cm4gcG9zaXRpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgcHJvdmlkZXIKKyAgICAgKgorICAgICAqIEBwYXJhbSBwcm92aWRlck51bWJlcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCByZW1vdmVQcm92aWRlcihpbnQgcHJvdmlkZXJOdW1iZXIpIHsKKyAgICAgICAgUHJvdmlkZXIgcCA9IHByb3ZpZGVycy5yZW1vdmUocHJvdmlkZXJOdW1iZXIgLSAxKTsKKyAgICAgICAgcHJvdmlkZXJzTmFtZXMucmVtb3ZlKHAuZ2V0TmFtZSgpKTsKKyAgICAgICAgc2V0TmVlZFJlZnJlc2goKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKgorICAgICAqIEFkZHMgaW5mb3JtYXRpb24gYWJvdXQgcHJvdmlkZXIgc2VydmljZXMgaW50byBIYXNoTWFwLgorICAgICAqCisgICAgICogQHBhcmFtIHAKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgaW5pdFNlcnZpY2VJbmZvKFByb3ZpZGVyIHApIHsKKyAgICAgICAgZm9yIChQcm92aWRlci5TZXJ2aWNlIHNlcnYgOiBwLmdldFNlcnZpY2VzKCkpIHsKKyAgICAgICAgICAgIFN0cmluZyB0eXBlID0gc2Vydi5nZXRUeXBlKCk7CisgICAgICAgICAgICBpZiAoc2VjdXJlUmFuZG9tID09IG51bGwgJiYgdHlwZS5lcXVhbHMoIlNlY3VyZVJhbmRvbSIpKSB7CisgICAgICAgICAgICAgICAgc2VjdXJlUmFuZG9tID0gc2VydjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN0cmluZyBrZXkgPSB0eXBlICsgIi4iICsgc2Vydi5nZXRBbGdvcml0aG0oKS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpOworICAgICAgICAgICAgaWYgKCFzZXJ2aWNlcy5jb250YWluc0tleShrZXkpKSB7CisgICAgICAgICAgICAgICAgc2VydmljZXMucHV0KGtleSwgc2Vydik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKFN0cmluZyBhbGlhcyA6IEVuZ2luZS5kb29yLmdldEFsaWFzZXMoc2VydikpIHsKKyAgICAgICAgICAgICAgICBrZXkgPSB0eXBlICsgIi4iICsgYWxpYXMudG9VcHBlckNhc2UoTG9jYWxlLlVTKTsKKyAgICAgICAgICAgICAgICBpZiAoIXNlcnZpY2VzLmNvbnRhaW5zS2V5KGtleSkpIHsKKyAgICAgICAgICAgICAgICAgICAgc2VydmljZXMucHV0KGtleSwgc2Vydik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICoKKyAgICAgKiBVcGRhdGVzIHNlcnZpY2VzIGhhc2h0YWJsZSBmb3IgYWxsIHJlZ2lzdGVyZWQgcHJvdmlkZXJzCisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdXBkYXRlU2VydmljZUluZm8oKSB7CisgICAgICAgIHNlcnZpY2VzLmNsZWFyKCk7CisgICAgICAgIHNlY3VyZVJhbmRvbSA9IG51bGw7CisgICAgICAgIGZvciAoUHJvdmlkZXIgcCA6IHByb3ZpZGVycykgeworICAgICAgICAgICAgaW5pdFNlcnZpY2VJbmZvKHApOworICAgICAgICB9CisgICAgICAgIG5lZWRSZWZyZXNoID0gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHNlcnZpY2VzIGNvbnRhaW4gYW55IHByb3ZpZGVyIGluZm9ybWF0aW9uCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICByZXR1cm4gc2VydmljZXMuaXNFbXB0eSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgc2VydmljZSBkZXNjcmlwdGlvbi4KKyAgICAgKiBDYWxsIHJlZnJlc2goKSBiZWZvcmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5IGluIHRoZSBmb3JtYXQgVFlQRS5BTEdPUklUSE0KKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBQcm92aWRlci5TZXJ2aWNlIGdldFNlcnZpY2UoU3RyaW5nIGtleSkgeworICAgICAgICByZXR1cm4gc2VydmljZXMuZ2V0KGtleSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBTZWN1cmVSYW5kb20gc2VydmljZSBkZXNjcmlwdGlvbi4KKyAgICAgKiBDYWxsIHJlZnJlc2goKSBiZWZvcmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBQcm92aWRlci5TZXJ2aWNlIGdldFNlY3VyZVJhbmRvbVNlcnZpY2UoKSB7CisgICAgICAgIHJldHVybiBzZWN1cmVSYW5kb207CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IGZsYWcgbmVlZFJlZnJlc2gKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXROZWVkUmVmcmVzaCgpIHsKKyAgICAgICAgbmVlZFJlZnJlc2ggPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlZnJlc2ggc2VydmljZXMgaW5mbworICAgICAqCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHJlZnJlc2goKSB7CisgICAgICAgIGlmIChuZWVkUmVmcmVzaCkgeworICAgICAgICAgICAgcmVmcmVzaE51bWJlcisrOworICAgICAgICAgICAgdXBkYXRlU2VydmljZUluZm8oKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcGtjczEwL0NlcnRpZmljYXRpb25SZXF1ZXN0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3BrY3MxMC9DZXJ0aWZpY2F0aW9uUmVxdWVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNkMzZkMzcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3BrY3MxMC9DZXJ0aWZpY2F0aW9uUmVxdWVzdC5qYXZhCkBAIC0wLDAgKzEsMTEyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUCisgKiBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUKKyAqIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCisgKiB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wa2NzMTA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xQml0U3RyaW5nOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXF1ZW5jZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CaXRTdHJpbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuQWxnb3JpdGhtSWRlbnRpZmllcjsKKworLyoqCisgKiBUaGUgY2xhc3MgaW1wbGVtZW50cyB0aGUgQVNOLjEgREVSIGVuY29kaW5nIGFuZCBkZWNvZGluZyBvZiB0aGUgUEtDUyMxMAorICogQ2VydGlmaWNhdGUgU2lnbmluZyBSZXF1ZXN0IChDU1IpLiBJdHMgQVNOIG5vdGF0aW9uIGlzIGFzIGZvbGxvd3M6CisgKgorICogQ2VydGlmaWNhdGlvblJlcXVlc3QgOjo9IFNFUVVFTkNFIHsKKyAqICAgY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbywKKyAqICAgc2lnbmF0dXJlQWxnb3JpdGhtIFNpZ25hdHVyZUFsZ29yaXRobUlkZW50aWZpZXIsCisgKiAgIHNpZ25hdHVyZSBTaWduYXR1cmUKKyAqIH0KKyAqCisgKiBTaWduYXR1cmVBbGdvcml0aG1JZGVudGlmaWVyIDo6PSBBbGdvcml0aG1JZGVudGlmaWVyCisgKgorICogU2lnbmF0dXJlIDo6PSBCSVQgU1RSSU5HCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBDZXJ0aWZpY2F0aW9uUmVxdWVzdCB7CisKKyAgICAvKiogdGhlIHZhbHVlIG9mIGNlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8gaW5mbzsKKworICAgIC8qKiB0aGUgdmFsdWUgb2Ygc2lnbmF0dXJlQWxnb3JpdGhtIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIEFsZ29yaXRobUlkZW50aWZpZXIgYWxnSWQ7CisKKyAgICAvKiogdGhlIHZhbHVlIG9mIHNpZ25hdHVyZSBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBieXRlW10gc2lnbmF0dXJlOworCisgICAgLyoqIHRoZSBBU04uMSBlbmNvZGVkIGZvcm0gb2YgQ2VydGlmaWNhdGlvblJlcXVlc3QgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGluZzsKKworICAgIHB1YmxpYyBDZXJ0aWZpY2F0aW9uUmVxdWVzdChDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8gaW5mbywKKyAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIgYWxnSWQsIGJ5dGVbXSBzaWduYXR1cmUpIHsKKyAgICAgICAgdGhpcy5pbmZvID0gaW5mbzsKKyAgICAgICAgdGhpcy5hbGdJZCA9IGFsZ0lkOworICAgICAgICB0aGlzLnNpZ25hdHVyZSA9IHNpZ25hdHVyZS5jbG9uZSgpOworICAgIH0KKworICAgIHByaXZhdGUgQ2VydGlmaWNhdGlvblJlcXVlc3QoQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIGluZm8sCisgICAgICAgICAgICBBbGdvcml0aG1JZGVudGlmaWVyIGFsZ0lkLCBieXRlW10gc2lnbmF0dXJlLCBieXRlW10gZW5jb2RpbmcpIHsKKyAgICAgICAgdGhpcyhpbmZvLCBhbGdJZCwgc2lnbmF0dXJlKTsKKyAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgIH0KKworICAgIHB1YmxpYyBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8gZ2V0SW5mbygpIHsKKyAgICAgICAgcmV0dXJuIGluZm87CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRTaWduYXR1cmUoKSB7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtzaWduYXR1cmUubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzaWduYXR1cmUsIDAsIHJlc3VsdCwgMCwgc2lnbmF0dXJlLmxlbmd0aCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBlbmNvZGVkIGZvcm0gb2YgdGhpcyBDZXJ0aWZpY2F0aW9uUmVxdWVzdCB2YWx1ZS4KKyAgICAgKiBAcmV0dXJuIGEgYnl0ZSBhcnJheSBjb250YWluaW5nIEFTTi4xIGVuY29kZSBmb3JtLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIGVuY29kaW5nID0gQ2VydGlmaWNhdGlvblJlcXVlc3QuQVNOMS5lbmNvZGUodGhpcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVuY29kaW5nOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVNlcXVlbmNlIEFTTjEgPSBuZXcgQVNOMVNlcXVlbmNlKG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mby5BU04xLCAgLy8gaW5mbworICAgICAgICAgICAgQWxnb3JpdGhtSWRlbnRpZmllci5BU04xLCAgICAgICAvLyBzaWduYXR1cmVBbGdvcml0aG0KKyAgICAgICAgICAgIEFTTjFCaXRTdHJpbmcuZ2V0SW5zdGFuY2UoKSB9KSAgLy8gc2lnbmF0dXJlCisgICAgeworCisgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgT2JqZWN0W10gdmFsdWVzID0gKE9iamVjdFtdKSBpbi5jb250ZW50OworICAgICAgICAgICAgcmV0dXJuIG5ldyBDZXJ0aWZpY2F0aW9uUmVxdWVzdCgKKyAgICAgICAgICAgICAgICAgICAgKENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbykgdmFsdWVzWzBdLAorICAgICAgICAgICAgICAgICAgICAoQWxnb3JpdGhtSWRlbnRpZmllcikgdmFsdWVzWzFdLAorICAgICAgICAgICAgICAgICAgICAoKEJpdFN0cmluZykgdmFsdWVzWzJdKS5ieXRlcywKKyAgICAgICAgICAgICAgICAgICAgaW4uZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKyAgICAgICAgICAgIENlcnRpZmljYXRpb25SZXF1ZXN0IGNlcnRSZXEgPSAoQ2VydGlmaWNhdGlvblJlcXVlc3QpIG9iamVjdDsKKyAgICAgICAgICAgIHZhbHVlc1swXSA9IGNlcnRSZXEuaW5mbzsKKyAgICAgICAgICAgIHZhbHVlc1sxXSA9IGNlcnRSZXEuYWxnSWQ7CisgICAgICAgICAgICB2YWx1ZXNbMl0gPSBuZXcgQml0U3RyaW5nKGNlcnRSZXEuc2lnbmF0dXJlLCAwKTsKKyAgICAgICAgfQorICAgIH07Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcGtjczEwL0NlcnRpZmljYXRpb25SZXF1ZXN0SW5mby5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wa2NzMTAvQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDEzZjk1MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcGtjczEwL0NlcnRpZmljYXRpb25SZXF1ZXN0SW5mby5qYXZhCkBAIC0wLDAgKzEsMTM0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUCisgKiBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUKKyAqIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCisgKiB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wa2NzMTA7CisKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xSW1wbGljaXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUludGVnZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXRPZjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwMS5BdHRyaWJ1dGVUeXBlQW5kVmFsdWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDEuTmFtZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5TdWJqZWN0UHVibGljS2V5SW5mbzsKKworLyoqCisgKiBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8gOjo9IFNFUVVFTkNFIHsKKyAqICAgdmVyc2lvbiBWZXJzaW9uLAorICogICBzdWJqZWN0IE5hbWUsCisgKiAgIHN1YmplY3RQdWJsaWNLZXlJbmZvIFN1YmplY3RQdWJsaWNLZXlJbmZvLAorICogICBhdHRyaWJ1dGVzIFswXSBJTVBMSUNJVCBBdHRyaWJ1dGVzIH0KKyAqCisgKiBWZXJzaW9uIDo6PSBJTlRFR0VSCisgKgorICogQXR0cmlidXRlcyA6Oj0gU0VUIE9GIEF0dHJpYnV0ZQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIHsKKyAgICBwcml2YXRlIGZpbmFsIGludCB2ZXJzaW9uOworCisgICAgLyoqIHRoZSB2YWx1ZSBvZiBzdWJqZWN0IGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIE5hbWUgc3ViamVjdDsKKworICAgIC8qKiB0aGUgdmFsdWUgb2Ygc3ViamVjdFB1YmxpY0tleUluZm8gZmllbGQgb2YgdGhlIHN0cnVjdHVyZSAqLworICAgIHByaXZhdGUgZmluYWwgU3ViamVjdFB1YmxpY0tleUluZm8gc3ViamVjdFB1YmxpY0tleUluZm87CisKKyAgICAvKiogdGhlIHZhbHVlIG9mIGF0dHJpYnV0ZXMgZmllbGQgb2YgdGhlIHN0cnVjdHVyZSAqLworICAgIHByaXZhdGUgZmluYWwgTGlzdDw/PiBhdHRyaWJ1dGVzOworCisgICAgLyoqIHRoZSBBU04uMSBlbmNvZGVkIGZvcm0gb2YgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvICovCisgICAgcHJpdmF0ZSBieXRlW10gZW5jb2Rpbmc7CisKKyAgICBwcml2YXRlIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyhpbnQgdmVyc2lvbiwgTmFtZSBzdWJqZWN0LAorICAgICAgICAgICAgU3ViamVjdFB1YmxpY0tleUluZm8gc3ViamVjdFB1YmxpY0tleUluZm8sIExpc3Q8Pz4gYXR0cmlidXRlcywgYnl0ZSBbXSBlbmNvZGluZykgeworICAgICAgICB0aGlzLnZlcnNpb24gPSB2ZXJzaW9uOworICAgICAgICB0aGlzLnN1YmplY3QgPSBzdWJqZWN0OworICAgICAgICB0aGlzLnN1YmplY3RQdWJsaWNLZXlJbmZvID0gc3ViamVjdFB1YmxpY0tleUluZm87CisgICAgICAgIHRoaXMuYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXM7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICB9CisKKyAgICBwdWJsaWMgTmFtZSBnZXRTdWJqZWN0KCkgeworICAgICAgICByZXR1cm4gc3ViamVjdDsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFZlcnNpb24oKSB7CisgICAgICAgIHJldHVybiB2ZXJzaW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgQVNOLjEgZW5jb2RlZCBmb3JtIG9mIHRoaXMgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvLgorICAgICAqIEByZXR1cm4gYSBieXRlIGFycmF5IGNvbnRhaW5pbmcgQVNOLjEgZW5jb2RlIGZvcm0uCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSBBU04xLmVuY29kZSh0aGlzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiLS0gQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvOiIpOworICAgICAgICByZXMuYXBwZW5kKCJcbiB2ZXJzaW9uOiAiKTsKKyAgICAgICAgcmVzLmFwcGVuZCh2ZXJzaW9uKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG4gc3ViamVjdDogIik7CisgICAgICAgIHJlcy5hcHBlbmQoc3ViamVjdC5nZXROYW1lKFg1MDBQcmluY2lwYWwuQ0FOT05JQ0FMKSk7CisgICAgICAgIHJlcy5hcHBlbmQoIlxuIHN1YmplY3RQdWJsaWNLZXlJbmZvOiAiKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG5cdCBhbGdvcml0aG06ICIpOworICAgICAgICByZXMuYXBwZW5kKHN1YmplY3RQdWJsaWNLZXlJbmZvLmdldEFsZ29yaXRobUlkZW50aWZpZXIoKS5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgIHJlcy5hcHBlbmQoIlxuXHQgcHVibGljIGtleTogIikuYXBwZW5kKHN1YmplY3RQdWJsaWNLZXlJbmZvLmdldFB1YmxpY0tleSgpKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG4gYXR0cmlidXRlczogIik7CisgICAgICAgIGlmIChhdHRyaWJ1dGVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlcy5hcHBlbmQoYXR0cmlidXRlcy50b1N0cmluZygpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlcy5hcHBlbmQoIm5vbmUiKTsKKyAgICAgICAgfQorICAgICAgICByZXMuYXBwZW5kKCJcbi0tIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyBFbmRcbiIpOworICAgICAgICByZXR1cm4gcmVzLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xU2VxdWVuY2UgQVNOMSA9IG5ldyBBU04xU2VxdWVuY2UobmV3IEFTTjFUeXBlW10geworICAgICAgICAgICAgQVNOMUludGVnZXIuZ2V0SW5zdGFuY2UoKSwgICAgICAgICAgICAgIC8vIHZlcnNpb24KKyAgICAgICAgICAgIE5hbWUuQVNOMSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzdWJqZWN0CisgICAgICAgICAgICBTdWJqZWN0UHVibGljS2V5SW5mby5BU04xLCAgICAgICAgICAgICAgLy8gc3ViamVjdFB1YmxpY0tleUluZm8KKyAgICAgICAgICAgIG5ldyBBU04xSW1wbGljaXQoMCwgbmV3IEFTTjFTZXRPZigKKyAgICAgICAgICAgICAgICAgICAgQXR0cmlidXRlVHlwZUFuZFZhbHVlLkFTTjEpKSAgICAvLyBhdHRyaWJ1dGVzCisgICAgICAgICAgICB9KSB7CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgT2JqZWN0W10gdmFsdWVzID0gKE9iamVjdFtdKSBpbi5jb250ZW50OworICAgICAgICAgICAgcmV0dXJuIG5ldyBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8oCisgICAgICAgICAgICAgICAgICAgIEFTTjFJbnRlZ2VyLnRvSW50VmFsdWUodmFsdWVzWzBdKSwKKyAgICAgICAgICAgICAgICAgICAgKE5hbWUpIHZhbHVlc1sxXSwKKyAgICAgICAgICAgICAgICAgICAgKFN1YmplY3RQdWJsaWNLZXlJbmZvKSB2YWx1ZXNbMl0sCisgICAgICAgICAgICAgICAgICAgIChMaXN0PD8+KSB2YWx1ZXNbM10sCisgICAgICAgICAgICAgICAgICAgIGluLmdldEVuY29kZWQoKSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykgeworICAgICAgICAgICAgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIGNlcnRSZXFJbmZvID0gKENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbykgb2JqZWN0OworICAgICAgICAgICAgdmFsdWVzWzBdID0gQVNOMUludGVnZXIuZnJvbUludFZhbHVlKGNlcnRSZXFJbmZvLnZlcnNpb24pOworICAgICAgICAgICAgdmFsdWVzWzFdID0gY2VydFJlcUluZm8uc3ViamVjdDsKKyAgICAgICAgICAgIHZhbHVlc1syXSA9IGNlcnRSZXFJbmZvLnN1YmplY3RQdWJsaWNLZXlJbmZvOworICAgICAgICAgICAgdmFsdWVzWzNdID0gY2VydFJlcUluZm8uYXR0cmlidXRlczsKKyAgICAgICAgfQorICAgIH07Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcGtjczcvQXV0aGVudGljYXRlZEF0dHJpYnV0ZXMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcGtjczcvQXV0aGVudGljYXRlZEF0dHJpYnV0ZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YTA4YTE2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wa2NzNy9BdXRoZW50aWNhdGVkQXR0cmlidXRlcy5qYXZhCkBAIC0wLDAgKzEsNjYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEJvcmlzIEt1em5ldHNvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkucGtjczc7CisKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2V0T2Y7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQmVySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDEuQXR0cmlidXRlVHlwZUFuZFZhbHVlOworCisvKioKKyAqIEFzIGRlZmluZWQgaW4gUEtDUyAjNzogQ3J5cHRvZ3JhcGhpYyBNZXNzYWdlIFN5bnRheCBTdGFuZGFyZAorICogKGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzMTUudHh0KToKKyAqIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIGlzIGEgc2V0IG9mIGF0dHJpYnV0ZXMgdGhhdCBhcmUgc2lnbmVkIChpLmUuLCBhdXRoZW50aWNhdGVkKSBieSB0aGUgc2lnbmVyCisgKi8KK2ZpbmFsIGNsYXNzIEF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIHsKKyAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGluZzsKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8QXR0cmlidXRlVHlwZUFuZFZhbHVlPiBhdXRoZW50aWNhdGVkQXR0cmlidXRlczsKKworICAgIHByaXZhdGUgQXV0aGVudGljYXRlZEF0dHJpYnV0ZXMoYnl0ZVtdIGVuY29kaW5nLAorICAgICAgICAgICAgTGlzdDxBdHRyaWJ1dGVUeXBlQW5kVmFsdWU+IGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzKSB7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICAgICAgdGhpcy5hdXRoZW50aWNhdGVkQXR0cmlidXRlcyA9IGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZT4gZ2V0QXR0cmlidXRlcygpIHsKKyAgICAgICAgcmV0dXJuIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgQVNOLjEgZW5jb2RlZCBmb3JtIG9mIHRoaXMgYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSBBU04xLmVuY29kZSh0aGlzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xU2V0T2YgQVNOMSA9CisgICAgICAgIG5ldyBBU04xU2V0T2YoQXR0cmlidXRlVHlwZUFuZFZhbHVlLkFTTjEpIHsKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBBdXRoZW50aWNhdGVkQXR0cmlidXRlcyhpbi5nZXRFbmNvZGVkKCksCisgICAgICAgICAgICAgICAgICAgIChMaXN0PEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZT4pIGluLmNvbnRlbnQpOworICAgICAgICB9CisgICAgfTsKK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wa2NzNy9Db250ZW50SW5mby5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wa2NzNy9Db250ZW50SW5mby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4ZDMwNzYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3BrY3M3L0NvbnRlbnRJbmZvLmphdmEKQEAgLTAsMCArMSwxNTMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEJvcmlzIEt1em5ldHNvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkucGtjczc7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUFueTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xRXhwbGljaXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMU9jdGV0U3RyaW5nOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFPaWQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworCisvKioKKyAqIEFzIGRlZmluZWQgaW4gUEtDUyAjNzogQ3J5cHRvZ3JhcGhpYyBNZXNzYWdlIFN5bnRheCBTdGFuZGFyZAorICogKGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzMTUudHh0KQorICoKKyAqIENvbnRlbnRJbmZvIDo6PSBTRVFVRU5DRSB7CisgKiAgICAgICBjb250ZW50VHlwZSAgQ29udGVudFR5cGUsCisgKiAgICAgICBjb250ZW50ICAgICAgWzBdIEVYUExJQ0lUIEFOWSBERUZJTkVEIEJZIGNvbnRlbnRUeXBlIE9QVElPTkFMCisgKiAgICAgfQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQ29udGVudEluZm8geworCisgICAgLy8gT0lEcworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50W10gREFUQSA9IG5ldyBpbnRbXSB7MSwgMiwgODQwLCAxMTM1NDksIDEsIDcsIDF9OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50W10gU0lHTkVEX0RBVEEgPSBuZXcgaW50W10gezEsIDIsIDg0MCwgMTEzNTQ5LCAxLCA3LCAyfTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludFtdIEVOVkVMT1BFRF9EQVRBID0gbmV3IGludFtdIHsxLCAyLCA4NDAsIDExMzU0OSwgMSwgNywgM307CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnRbXSBTSUdORURfQU5EX0VOVkVMT1BFRF9EQVRBID0gbmV3IGludFtdIHsxLCAyLCA4NDAsIDExMzU0OSwgMSwgNywgNH07CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnRbXSBESUdFU1RFRF9EQVRBID0gbmV3IGludFtdIHsxLCAyLCA4NDAsIDExMzU0OSwgMSwgNywgNX07CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnRbXSBFTkNSWVBURURfREFUQSA9IG5ldyBpbnRbXSB7MSwgMiwgODQwLCAxMTM1NDksIDEsIDcsIDZ9OworCisgICAgcHJpdmF0ZSBmaW5hbCBpbnRbXSBvaWQ7CisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgY29udGVudDsKKyAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGluZzsKKworICAgIHByaXZhdGUgQ29udGVudEluZm8oaW50W10gb2lkLCBPYmplY3QgY29udGVudCwgYnl0ZVtdIGVuY29kaW5nKSB7CisgICAgICAgIHRoaXMub2lkID0gb2lkOworICAgICAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50OworICAgICAgICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgfQorCisgICAgcHVibGljIFNpZ25lZERhdGEgZ2V0U2lnbmVkRGF0YSgpIHsKKyAgICAgICAgaWYgKEFycmF5cy5lcXVhbHMob2lkLCBTSUdORURfREFUQSkpIHsKKyAgICAgICAgICAgIHJldHVybiAoU2lnbmVkRGF0YSljb250ZW50OworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29udGVudCgpIHsKKyAgICAgICAgcmV0dXJuIGNvbnRlbnQ7CisgICAgfQorCisgICAgcHVibGljIGludFtdIGdldENvbnRlbnRUeXBlKCkgeworICAgICAgICByZXR1cm4gb2lkOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIGVuY29kaW5nID0gQVNOMS5lbmNvZGUodGhpcyk7CisgICAgICAgIH0KKyAgICAgICAgLy8gTm90ZTogdGhpcyBpcyBpbnRlcm5hbCBvYmplY3QgYW5kIGNhbiBub3QgYmUgYWNjZXNzaWJsZSBmcm9tCisgICAgICAgIC8vIHB1YmxpYyBBUEksIHNvIGVuY29kaW5nIGlzIG5vdCBjb3BpZWQuIFRoZSBjbGFzc2VzIHdoaWNoIHVzZQorICAgICAgICAvLyB0aGlzIGNsYXNzIHNob3VsZCBjb3B5IGVuY29kaW5nIGJlZm9yZSBwYXNzaW5nIGl0IG91dC4KKyAgICAgICAgcmV0dXJuIGVuY29kaW5nOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlcyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIHJlcy5hcHBlbmQoIj09PT0gQ29udGVudEluZm86Iik7CisgICAgICAgIHJlcy5hcHBlbmQoIlxuPT0gQ29udGVudFR5cGUgKE9JRCk6ICIpOworICAgICAgICBmb3IgKGludCBpIDogb2lkKSB7CisgICAgICAgICAgICByZXMuYXBwZW5kKGkpOworICAgICAgICAgICAgcmVzLmFwcGVuZCgnICcpOworICAgICAgICB9CisgICAgICAgIHJlcy5hcHBlbmQoIlxuPT0gQ29udGVudDogIik7CisgICAgICAgIGlmIChjb250ZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlcy5hcHBlbmQoIlxuIik7CisgICAgICAgICAgICByZXMuYXBwZW5kKGNvbnRlbnQudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmVzLmFwcGVuZCgiXG49PSBDb250ZW50IEVuZCIpOworICAgICAgICByZXMuYXBwZW5kKCJcbj09PT0gQ29udGVudEluZm8gRW5kXG4iKTsKKyAgICAgICAgcmV0dXJuIHJlcy50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVNlcXVlbmNlIEFTTjEgPQorICAgICAgICBuZXcgQVNOMVNlcXVlbmNlKG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgICAgICBBU04xT2lkLmdldEluc3RhbmNlKCksCisgICAgICAgICAgICAgICAgbmV3IEFTTjFFeHBsaWNpdCgwLCBBU04xQW55LmdldEluc3RhbmNlKCkpCisgICAgICAgICAgICAgICAgfSkgIHsKKyAgICAgICAgeworICAgICAgICAgICAgc2V0T3B0aW9uYWwoMSk7IC8vIGNvbnRlbnQgaXMgb3B0aW9uYWwKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCwgT2JqZWN0W10gdmFsdWVzKSB7CisgICAgICAgICAgICBDb250ZW50SW5mbyBjaSA9IChDb250ZW50SW5mbykgb2JqZWN0OworICAgICAgICAgICAgdmFsdWVzWzBdID0gY2kub2lkOworICAgICAgICAgICAgaWYgKGNpLmNvbnRlbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmIChBcnJheXMuZXF1YWxzKGNpLm9pZCwgREFUQSkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNpLmNvbnRlbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzWzFdID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU04xT2N0ZXRTdHJpbmcuZ2V0SW5zdGFuY2UoKS5lbmNvZGUoY2kuY29udGVudCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNpLmNvbnRlbnQgaW5zdGFuY2VvZiBTaWduZWREYXRhKSB7CisgICAgICAgICAgICAgICAgICAgIHZhbHVlc1sxXSA9IFNpZ25lZERhdGEuQVNOMS5lbmNvZGUoY2kuY29udGVudCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdmFsdWVzWzFdID0gY2kuY29udGVudDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgT2JqZWN0W10gdmFsdWVzID0gKE9iamVjdFtdKSBpbi5jb250ZW50OworICAgICAgICAgICAgaW50W10gb2lkID0gKGludFtdKSB2YWx1ZXNbMF07CisgICAgICAgICAgICBpZiAoQXJyYXlzLmVxdWFscyhvaWQsIERBVEEpKSB7CisgICAgICAgICAgICAgICAgaWYgKHZhbHVlc1sxXSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ29udGVudEluZm8ob2lkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTjFPY3RldFN0cmluZy5nZXRJbnN0YW5jZSgpLmRlY29kZSgoYnl0ZVtdKXZhbHVlc1sxXSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW4uZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgICAgICAgICB9ICBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDb250ZW50SW5mbygoaW50W10pdmFsdWVzWzBdLCBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluLmdldEVuY29kZWQoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKEFycmF5cy5lcXVhbHMob2lkLCBTSUdORURfREFUQSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbnRlbnRJbmZvKChpbnRbXSl2YWx1ZXNbMF0sCisgICAgICAgICAgICAgICAgICAgICAgICBTaWduZWREYXRhLkFTTjEuZGVjb2RlKChieXRlW10pdmFsdWVzWzFdKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGluLmdldEVuY29kZWQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IENvbnRlbnRJbmZvKChpbnRbXSkgdmFsdWVzWzBdLCB2YWx1ZXNbMV0sIGluLmdldEVuY29kZWQoKSk7CisgICAgICAgIH0KKyAgIH07Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3BrY3M3L1NpZ25lZERhdGEuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcGtjczcvU2lnbmVkRGF0YS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVhZjI0NWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3BrY3M3L1NpZ25lZERhdGEuamF2YQpAQCAtMCwwICsxLDE0NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQm9yaXMgS3V6bmV0c292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wa2NzNzsKKworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFJbXBsaWNpdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xSW50ZWdlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2VxdWVuY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNldE9mOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LkFsZ29yaXRobUlkZW50aWZpZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuQ2VydGlmaWNhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuQ2VydGlmaWNhdGVMaXN0OworCisKKy8qKgorICogQXMgZGVmaW5lZCBpbiBQS0NTICM3OiBDcnlwdG9ncmFwaGljIE1lc3NhZ2UgU3ludGF4IFN0YW5kYXJkCisgKiAoaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjMxNS50eHQpCisgKgorICogU2lnbmVkRGF0YSA6Oj0gU0VRVUVOQ0UgeworICogICB2ZXJzaW9uIFZlcnNpb24sCisgKiAgIGRpZ2VzdEFsZ29yaXRobXMgRGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllcnMsCisgKiAgIGNvbnRlbnRJbmZvIENvbnRlbnRJbmZvLAorICogICBjZXJ0aWZpY2F0ZXMKKyAqICAgICBbMF0gSU1QTElDSVQgRXh0ZW5kZWRDZXJ0aWZpY2F0ZXNBbmRDZXJ0aWZpY2F0ZXMgT1BUSU9OQUwsCisgKiAgIGNybHMKKyAqICAgICBbMV0gSU1QTElDSVQgQ2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdHMgT1BUSU9OQUwsCisgKiAgIHNpZ25lckluZm9zIFNpZ25lckluZm9zIH0KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFNpZ25lZERhdGEgeworICAgIHByaXZhdGUgZmluYWwgaW50IHZlcnNpb247CisgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PD8+IGRpZ2VzdEFsZ29yaXRobXM7CisgICAgcHJpdmF0ZSBmaW5hbCBDb250ZW50SW5mbyBjb250ZW50SW5mbzsKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8Q2VydGlmaWNhdGU+IGNlcnRpZmljYXRlczsKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8Q2VydGlmaWNhdGVMaXN0PiBjcmxzOworICAgIHByaXZhdGUgZmluYWwgTGlzdDxTaWduZXJJbmZvPiBzaWduZXJJbmZvczsKKworICAgIHByaXZhdGUgU2lnbmVkRGF0YShpbnQgdmVyc2lvbiwgTGlzdDw/PiBkaWdlc3RBbGdvcml0aG1zLCBDb250ZW50SW5mbyBjb250ZW50SW5mbywKKyAgICAgICAgICAgIExpc3Q8Q2VydGlmaWNhdGU+IGNlcnRpZmljYXRlcywgTGlzdDxDZXJ0aWZpY2F0ZUxpc3Q+IGNybHMsCisgICAgICAgICAgICBMaXN0PFNpZ25lckluZm8+IHNpZ25lckluZm9zKSB7CisgICAgICAgIHRoaXMudmVyc2lvbiA9IHZlcnNpb247CisgICAgICAgIHRoaXMuZGlnZXN0QWxnb3JpdGhtcyA9IGRpZ2VzdEFsZ29yaXRobXM7CisgICAgICAgIHRoaXMuY29udGVudEluZm8gPSBjb250ZW50SW5mbzsKKyAgICAgICAgdGhpcy5jZXJ0aWZpY2F0ZXMgPSBjZXJ0aWZpY2F0ZXM7CisgICAgICAgIHRoaXMuY3JscyA9IGNybHM7CisgICAgICAgIHRoaXMuc2lnbmVySW5mb3MgPSBzaWduZXJJbmZvczsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxDZXJ0aWZpY2F0ZT4gZ2V0Q2VydGlmaWNhdGVzKCkgeworICAgICAgICByZXR1cm4gY2VydGlmaWNhdGVzOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PENlcnRpZmljYXRlTGlzdD4gZ2V0Q1JMcygpIHsKKyAgICAgICAgcmV0dXJuIGNybHM7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8U2lnbmVySW5mbz4gZ2V0U2lnbmVySW5mb3MoKSB7CisgICAgICAgIHJldHVybiBzaWduZXJJbmZvczsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFZlcnNpb24oKSB7CisgICAgICAgIHJldHVybiB2ZXJzaW9uOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlcyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIHJlcy5hcHBlbmQoIi0tLS0gU2lnbmVkRGF0YToiKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG52ZXJzaW9uOiAiKTsKKyAgICAgICAgcmVzLmFwcGVuZCh2ZXJzaW9uKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG5kaWdlc3RBbGdvcml0aG1zOiAiKTsKKyAgICAgICAgcmVzLmFwcGVuZChkaWdlc3RBbGdvcml0aG1zLnRvU3RyaW5nKCkpOworICAgICAgICByZXMuYXBwZW5kKCJcbmNvbnRlbnRJbmZvOiAiKTsKKyAgICAgICAgcmVzLmFwcGVuZChjb250ZW50SW5mby50b1N0cmluZygpKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG5jZXJ0aWZpY2F0ZXM6ICIpOworICAgICAgICBpZiAoY2VydGlmaWNhdGVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlcy5hcHBlbmQoY2VydGlmaWNhdGVzLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIHJlcy5hcHBlbmQoIlxuY3JsczogIik7CisgICAgICAgIGlmIChjcmxzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlcy5hcHBlbmQoY3Jscy50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICByZXMuYXBwZW5kKCJcbnNpZ25lckluZm9zOlxuIik7CisgICAgICAgIHJlcy5hcHBlbmQoc2lnbmVySW5mb3MudG9TdHJpbmcoKSk7CisgICAgICAgIHJlcy5hcHBlbmQoIlxuLS0tLSBTaWduZWREYXRhIEVuZFxuXSIpOworICAgICAgICByZXR1cm4gcmVzLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xU2VxdWVuY2UgQVNOMSA9IG5ldyBBU04xU2VxdWVuY2UobmV3IEFTTjFUeXBlW10geworICAgICAgICAgICAgQVNOMUludGVnZXIuZ2V0SW5zdGFuY2UoKSwKKyAgICAgICAgICAgIG5ldyBBU04xU2V0T2YoQWxnb3JpdGhtSWRlbnRpZmllci5BU04xKSwKKyAgICAgICAgICAgIENvbnRlbnRJbmZvLkFTTjEsCisgICAgICAgICAgICBuZXcgQVNOMUltcGxpY2l0KDAsIG5ldyBBU04xU2V0T2YoQ2VydGlmaWNhdGUuQVNOMSkpLAorICAgICAgICAgICAgbmV3IEFTTjFJbXBsaWNpdCgxLCBuZXcgQVNOMVNldE9mKENlcnRpZmljYXRlTGlzdC5BU04xKSksCisgICAgICAgICAgICBuZXcgQVNOMVNldE9mKFNpZ25lckluZm8uQVNOMSkKKyAgICAgICAgICAgIH0pIHsKKyAgICAgICAgeworICAgICAgICAgICAgc2V0T3B0aW9uYWwoMyk7IC8vIGNlcnRpZmljYXRlcyBpcyBvcHRpb25hbAorICAgICAgICAgICAgc2V0T3B0aW9uYWwoNCk7IC8vIGNybHMgaXMgb3B0aW9uYWwKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCwgT2JqZWN0W10gdmFsdWVzKSB7CisgICAgICAgICAgICBTaWduZWREYXRhIHNkID0gKFNpZ25lZERhdGEpIG9iamVjdDsKKyAgICAgICAgICAgIHZhbHVlc1swXSA9IG5ldyBieXRlW10geyhieXRlKXNkLnZlcnNpb259OworICAgICAgICAgICAgdmFsdWVzWzFdID0gc2QuZGlnZXN0QWxnb3JpdGhtczsKKyAgICAgICAgICAgIHZhbHVlc1syXSA9IHNkLmNvbnRlbnRJbmZvOworICAgICAgICAgICAgdmFsdWVzWzNdID0gc2QuY2VydGlmaWNhdGVzOworICAgICAgICAgICAgdmFsdWVzWzRdID0gc2QuY3JsczsKKyAgICAgICAgICAgIHZhbHVlc1s1XSA9IHNkLnNpZ25lckluZm9zOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgT2JqZWN0W10gdmFsdWVzID0gKE9iamVjdFtdKSBpbi5jb250ZW50OworICAgICAgICAgICAgcmV0dXJuIG5ldyBTaWduZWREYXRhKAorICAgICAgICAgICAgICAgICAgICAgICAgQVNOMUludGVnZXIudG9JbnRWYWx1ZSh2YWx1ZXNbMF0pLAorICAgICAgICAgICAgICAgICAgICAgICAgKExpc3Q8Pz4pIHZhbHVlc1sxXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIChDb250ZW50SW5mbykgdmFsdWVzWzJdLAorICAgICAgICAgICAgICAgICAgICAgICAgKExpc3Q8Q2VydGlmaWNhdGU+KSB2YWx1ZXNbM10sCisgICAgICAgICAgICAgICAgICAgICAgICAoTGlzdDxDZXJ0aWZpY2F0ZUxpc3Q+KSB2YWx1ZXNbNF0sCisgICAgICAgICAgICAgICAgICAgICAgICAoTGlzdDxTaWduZXJJbmZvPikgdmFsdWVzWzVdCisgICAgICAgICAgICAgICAgICAgICk7CisgICAgICAgIH0KKyAgICB9OworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3BrY3M3L1NpZ25lckluZm8uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcGtjczcvU2lnbmVySW5mby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJhYWEwOTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3BrY3M3L1NpZ25lckluZm8uamF2YQpAQCAtMCwwICsxLDIwNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQm9yaXMgS3V6bmV0c292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wa2NzNzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUltcGxpY2l0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFJbnRlZ2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFPY3RldFN0cmluZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2VxdWVuY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNldE9mOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTAxLkF0dHJpYnV0ZVR5cGVBbmRWYWx1ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwMS5OYW1lOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LkFsZ29yaXRobUlkZW50aWZpZXI7CisKKworLyoqCisgKiBBcyBkZWZpbmVkIGluIFBLQ1MgIzc6IENyeXB0b2dyYXBoaWMgTWVzc2FnZSBTeW50YXggU3RhbmRhcmQKKyAqIChodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzE1LnR4dCkKKyAqCisgKiBTaWduZXJJbmZvIDo6PSBTRVFVRU5DRSB7CisgKiAgIHZlcnNpb24gVmVyc2lvbiwKKyAqICAgaXNzdWVyQW5kU2VyaWFsTnVtYmVyIElzc3VlckFuZFNlcmlhbE51bWJlciwKKyAqICAgZGlnZXN0QWxnb3JpdGhtIERpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXIsCisgKiAgIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzCisgKiAgICAgWzBdIElNUExJQ0lUIEF0dHJpYnV0ZXMgT1BUSU9OQUwsCisgKiAgIGRpZ2VzdEVuY3J5cHRpb25BbGdvcml0aG0KKyAqICAgICBEaWdlc3RFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciwKKyAqICAgZW5jcnlwdGVkRGlnZXN0IEVuY3J5cHRlZERpZ2VzdCwKKyAqICAgdW5hdXRoZW50aWNhdGVkQXR0cmlidXRlcworICogICAgIFsxXSBJTVBMSUNJVCBBdHRyaWJ1dGVzIE9QVElPTkFMCisgKiAgfQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU2lnbmVySW5mbyB7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmVyc2lvbjsKKyAgICBwcml2YXRlIGZpbmFsIFg1MDBQcmluY2lwYWwgaXNzdWVyOworICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBzZXJpYWxOdW1iZXI7CisgICAgcHJpdmF0ZSBmaW5hbCBBbGdvcml0aG1JZGVudGlmaWVyIGRpZ2VzdEFsZ29yaXRobTsKKyAgICBwcml2YXRlIGZpbmFsIEF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzOworICAgIHByaXZhdGUgZmluYWwgQWxnb3JpdGhtSWRlbnRpZmllciBkaWdlc3RFbmNyeXB0aW9uQWxnb3JpdGhtOworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGVuY3J5cHRlZERpZ2VzdDsKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8Pz4gdW5hdXRoZW50aWNhdGVkQXR0cmlidXRlczsKKworICAgIHByaXZhdGUgU2lnbmVySW5mbyhpbnQgdmVyc2lvbiwKKyAgICAgICAgICAgIE9iamVjdFtdIGlzc3VlckFuZFNlcmlhbE51bWJlciwKKyAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIgZGlnZXN0QWxnb3JpdGhtLAorICAgICAgICAgICAgQXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMsCisgICAgICAgICAgICBBbGdvcml0aG1JZGVudGlmaWVyIGRpZ2VzdEVuY3J5cHRpb25BbGdvcml0aG0sCisgICAgICAgICAgICBieXRlW10gZW5jcnlwdGVkRGlnZXN0LAorICAgICAgICAgICAgTGlzdDw/PiB1bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzKSB7CisgICAgICAgIHRoaXMudmVyc2lvbiA9IHZlcnNpb247CisgICAgICAgIHRoaXMuaXNzdWVyID0gKChOYW1lKWlzc3VlckFuZFNlcmlhbE51bWJlclswXSkuZ2V0WDUwMFByaW5jaXBhbCgpOworICAgICAgICB0aGlzLnNlcmlhbE51bWJlciA9IEFTTjFJbnRlZ2VyLnRvQmlnSW50ZWdlclZhbHVlKGlzc3VlckFuZFNlcmlhbE51bWJlclsxXSk7CisgICAgICAgIHRoaXMuZGlnZXN0QWxnb3JpdGhtID0gZGlnZXN0QWxnb3JpdGhtOworICAgICAgICB0aGlzLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzID0gYXV0aGVudGljYXRlZEF0dHJpYnV0ZXM7CisgICAgICAgIHRoaXMuZGlnZXN0RW5jcnlwdGlvbkFsZ29yaXRobSA9IGRpZ2VzdEVuY3J5cHRpb25BbGdvcml0aG07CisgICAgICAgIHRoaXMuZW5jcnlwdGVkRGlnZXN0ID0gZW5jcnlwdGVkRGlnZXN0OworICAgICAgICB0aGlzLnVuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgPSB1bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzOworICAgIH0KKworICAgIHB1YmxpYyBYNTAwUHJpbmNpcGFsIGdldElzc3VlcigpIHsKKyAgICAgICAgcmV0dXJuIGlzc3VlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRTZXJpYWxOdW1iZXIoKSB7CisgICAgICAgIHJldHVybiBzZXJpYWxOdW1iZXI7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXREaWdlc3RBbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiBkaWdlc3RBbGdvcml0aG0uZ2V0QWxnb3JpdGhtKCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXREaWdlc3RFbmNyeXB0aW9uQWxnb3JpdGhtKCkgeworICAgICAgICByZXR1cm4gZGlnZXN0RW5jcnlwdGlvbkFsZ29yaXRobS5nZXRBbGdvcml0aG0oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxBdHRyaWJ1dGVUeXBlQW5kVmFsdWU+IGdldEF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzKCkgeworICAgICAgICBpZiAoYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzLmdldEF0dHJpYnV0ZXMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWRBdXRoZW50aWNhdGVkQXR0cmlidXRlcygpIHsKKyAgICAgICAgaWYgKGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBhdXRoZW50aWNhdGVkQXR0cmlidXRlcy5nZXRFbmNvZGVkKCk7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNyeXB0ZWREaWdlc3QoKSB7CisgICAgICAgIHJldHVybiBlbmNyeXB0ZWREaWdlc3Q7CisgICAgfQorCisKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlcyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIHJlcy5hcHBlbmQoIi0tIFNpZ25lckluZm86Iik7CisgICAgICAgIHJlcy5hcHBlbmQoIlxuIHZlcnNpb24gOiAiKTsKKyAgICAgICAgcmVzLmFwcGVuZCh2ZXJzaW9uKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG5pc3N1ZXJBbmRTZXJpYWxOdW1iZXI6ICAiKTsKKyAgICAgICAgcmVzLmFwcGVuZChpc3N1ZXIpOworICAgICAgICByZXMuYXBwZW5kKCIgICAiKTsKKyAgICAgICAgcmVzLmFwcGVuZChzZXJpYWxOdW1iZXIpOworICAgICAgICByZXMuYXBwZW5kKCJcbmRpZ2VzdEFsZ29yaXRobTogICIpOworICAgICAgICByZXMuYXBwZW5kKGRpZ2VzdEFsZ29yaXRobS50b1N0cmluZygpKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG5hdXRoZW50aWNhdGVkQXR0cmlidXRlczogICIpOworICAgICAgICBpZiAoYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzLmFwcGVuZChhdXRoZW50aWNhdGVkQXR0cmlidXRlcy50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICByZXMuYXBwZW5kKCJcbmRpZ2VzdEVuY3J5cHRpb25BbGdvcml0aG06ICIpOworICAgICAgICByZXMuYXBwZW5kKGRpZ2VzdEVuY3J5cHRpb25BbGdvcml0aG0udG9TdHJpbmcoKSk7CisgICAgICAgIHJlcy5hcHBlbmQoIlxudW5hdXRoZW50aWNhdGVkQXR0cmlidXRlczogIik7CisgICAgICAgIGlmICh1bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlcy5hcHBlbmQodW5hdXRoZW50aWNhdGVkQXR0cmlidXRlcy50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICByZXMuYXBwZW5kKCJcbi0tIFNpZ25lckluZm8gRW5kXG4iKTsKKyAgICAgICAgcmV0dXJuIHJlcy50b1N0cmluZygpOworICAgIH0KKworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xU2VxdWVuY2UgSVNTVUVSX0FORF9TRVJJQUxfTlVNQkVSID0KKyAgICAgICAgICAgIG5ldyBBU04xU2VxdWVuY2UobmV3IEFTTjFUeXBlW10geworICAgICAgICAgICAgICAgIE5hbWUuQVNOMSwgICAgICAgICAgICAgICAgICAgICAgIC8vIGlzc3VlcgorICAgICAgICAgICAgICAgIEFTTjFJbnRlZ2VyLmdldEluc3RhbmNlKCksICAgICAgIC8vIHNlcmlhbE51bWJlcgorICAgICAgICAgICAgfSkKKyAgICAgICAgeworICAgICAgICAgICAgLy8gbWV0aG9kIHRvIGVuY29kZQorICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKyAgICAgICAgICAgICAgICBPYmplY3QgW10gaXNzQW5kU2VyaWFsID0gKE9iamVjdFtdKW9iamVjdDsKKyAgICAgICAgICAgICAgICB2YWx1ZXNbMF0gPSBpc3NBbmRTZXJpYWxbMF07CisgICAgICAgICAgICAgICAgdmFsdWVzWzFdID0gaXNzQW5kU2VyaWFsWzFdOworICAgICAgICB9CisgICAgfTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVNlcXVlbmNlIEFTTjEgPQorICAgICAgICBuZXcgQVNOMVNlcXVlbmNlKG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgICAgICBBU04xSW50ZWdlci5nZXRJbnN0YW5jZSgpLCAgICAgICAgIC8vdmVyc2lvbgorICAgICAgICAgICAgICAgIElTU1VFUl9BTkRfU0VSSUFMX05VTUJFUiwKKyAgICAgICAgICAgICAgICBBbGdvcml0aG1JZGVudGlmaWVyLkFTTjEsICAgICAgICAgICAvL2RpZ2VzdEFsZ29yaXRobQorICAgICAgICAgICAgICAgIG5ldyBBU04xSW1wbGljaXQoMCwgQXV0aGVudGljYXRlZEF0dHJpYnV0ZXMuQVNOMSksLy9hdXRoZW50aWNhdGVkQXR0cmlidXRlcworICAgICAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIuQVNOMSwgICAgICAgICAgICAvL2RpZ2VzdEVuY3J5cHRpb25BbGdvcml0aG0KKyAgICAgICAgICAgICAgICBBU04xT2N0ZXRTdHJpbmcuZ2V0SW5zdGFuY2UoKSwgICAgICAgLy9lbmNyeXB0ZWREaWdlc3QKKyAgICAgICAgICAgICAgICAgbmV3IEFTTjFJbXBsaWNpdCgxLCBuZXcgQVNOMVNldE9mKAorICAgICAgICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZS5BU04xKSksLy91bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzCisgICAgICAgICAgICAgICAgfSkgIHsKKyAgICAgICAgeworICAgICAgICAgICAgc2V0T3B0aW9uYWwoMyk7IC8vIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIGlzIG9wdGlvbmFsCisgICAgICAgICAgICBzZXRPcHRpb25hbCg2KTsgLy8gdW5hdXRoZW50aWNhdGVkQXR0cmlidXRlcyBpcyBvcHRpb25hbAorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKyAgICAgICAgICAgIFNpZ25lckluZm8gc2kgPSAoU2lnbmVySW5mbykgb2JqZWN0OworICAgICAgICAgICAgdmFsdWVzWzBdID0gbmV3IGJ5dGVbXSB7KGJ5dGUpc2kudmVyc2lvbn07CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHZhbHVlc1sxXSA9IG5ldyBPYmplY3RbXSB7IG5ldyBOYW1lKHNpLmlzc3Vlci5nZXROYW1lKCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgc2kuc2VyaWFsTnVtYmVyLnRvQnl0ZUFycmF5KCkgfTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBUaGUgZXhjZXB0aW9uIGlzIG5ldmVyIHRocm93biwgYmVjYXVzZSBzaS5pc3N1ZXIKKyAgICAgICAgICAgICAgICAvLyBpcyBjcmVhdGVkIHVzaW5nIE5hbWUuZ2V0WDUwMFByaW5jaXBhbCgpLgorICAgICAgICAgICAgICAgIC8vIFRocm93IGEgUnVudGltZUV4Y2VwdGlvbiBqdXN0IHRvIGJlIHNhZmUuCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkZhaWxlZCB0byBlbmNvZGUgaXNzdWVyIG5hbWUiLCBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHZhbHVlc1syXSA9IHNpLmRpZ2VzdEFsZ29yaXRobTsKKyAgICAgICAgICAgIHZhbHVlc1szXSA9IHNpLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzOworICAgICAgICAgICAgdmFsdWVzWzRdID0gc2kuZGlnZXN0RW5jcnlwdGlvbkFsZ29yaXRobTsKKyAgICAgICAgICAgIHZhbHVlc1s1XSA9IHNpLmVuY3J5cHRlZERpZ2VzdDsKKyAgICAgICAgICAgIHZhbHVlc1s2XSA9IHNpLnVuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXM7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB7CisgICAgICAgICAgICBPYmplY3RbXSB2YWx1ZXMgPSAoT2JqZWN0W10pIGluLmNvbnRlbnQ7CisgICAgICAgICAgICByZXR1cm4gbmV3IFNpZ25lckluZm8oCisgICAgICAgICAgICAgICAgICAgICAgICBBU04xSW50ZWdlci50b0ludFZhbHVlKHZhbHVlc1swXSksCisgICAgICAgICAgICAgICAgICAgICAgICAoT2JqZWN0W10pIHZhbHVlc1sxXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIChBbGdvcml0aG1JZGVudGlmaWVyKSB2YWx1ZXNbMl0sCisgICAgICAgICAgICAgICAgICAgICAgICAoQXV0aGVudGljYXRlZEF0dHJpYnV0ZXMpIHZhbHVlc1szXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIChBbGdvcml0aG1JZGVudGlmaWVyKSB2YWx1ZXNbNF0sCisgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZVtdKSB2YWx1ZXNbNV0sCisgICAgICAgICAgICAgICAgICAgICAgICAoTGlzdCkgdmFsdWVzWzZdCisgICAgICAgICAgICAgICAgICAgICk7CisgICAgICAgIH0KKyAgIH07Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3BrY3M4L1ByaXZhdGVLZXlJbmZvLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3BrY3M4L1ByaXZhdGVLZXlJbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDAwYmY4NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcGtjczgvUHJpdmF0ZUtleUluZm8uamF2YQpAQCAtMCwwICsxLDEyOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wa2NzODsKKworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFJbXBsaWNpdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xSW50ZWdlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xT2N0ZXRTdHJpbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXRPZjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwMS5BdHRyaWJ1dGVUeXBlQW5kVmFsdWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuQWxnb3JpdGhtSWRlbnRpZmllcjsKKworLyoqCisgKiBUaGUgY2xhc3MgaW1wbGVtZW50cyB0aGUgQVNOLjEgREVSIGVuY29kaW5nIGFuZCBkZWNvZGluZyBvZiB0aGUgUEtDUyM4CisgKiBQcml2YXRlS2V5SW5mbyBoYXZpbmcgdGhlIGZvbGxvd2luZyBBU04uMSBub3RhdGlvbjoKKyAqCisgKiAgUHJpdmF0ZUtleUluZm8gOjo9IFNFUVVFTkNFIHsKKyAqICAgICAgdmVyc2lvbiBWZXJzaW9uLAorICogICAgICBwcml2YXRlS2V5QWxnb3JpdGhtIFByaXZhdGVLZXlBbGdvcml0aG1JZGVudGlmaWVyLAorICogICAgICBwcml2YXRlS2V5IFByaXZhdGVLZXksCisgKiAgICAgIGF0dHJpYnV0ZXMgWzBdIElNUExJQ0lUIEF0dHJpYnV0ZXMgT1BUSU9OQUwgfQorICoKKyAqICBWZXJzaW9uIDo6PSBJTlRFR0VSCisgKgorICogIFByaXZhdGVLZXlBbGdvcml0aG1JZGVudGlmaWVyIDo6PSBBbGdvcml0aG1JZGVudGlmaWVyCisgKgorICogIFByaXZhdGVLZXkgOjo9IE9DVEVUIFNUUklORworICoKKyAqICBBdHRyaWJ1dGVzIDo6PSBTRVQgT0YgQXR0cmlidXRlCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBQcml2YXRlS2V5SW5mbyB7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmVyc2lvbjsKKyAgICBwcml2YXRlIGZpbmFsIEFsZ29yaXRobUlkZW50aWZpZXIgcHJpdmF0ZUtleUFsZ29yaXRobTsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBwcml2YXRlS2V5OworICAgIHByaXZhdGUgZmluYWwgTGlzdDw/PiBhdHRyaWJ1dGVzOworICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kaW5nOworCisgICAgcHVibGljIFByaXZhdGVLZXlJbmZvKGludCB2ZXJzaW9uLCBBbGdvcml0aG1JZGVudGlmaWVyIHByaXZhdGVLZXlBbGdvcml0aG0sCisgICAgICAgICAgICBieXRlW10gcHJpdmF0ZUtleSwgTGlzdCBhdHRyaWJ1dGVzKSB7CisgICAgICAgIHRoaXMudmVyc2lvbiA9IHZlcnNpb247CisgICAgICAgIHRoaXMucHJpdmF0ZUtleUFsZ29yaXRobSA9IHByaXZhdGVLZXlBbGdvcml0aG07CisgICAgICAgIHRoaXMucHJpdmF0ZUtleSA9IHByaXZhdGVLZXk7CisgICAgICAgIHRoaXMuYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXM7CisgICAgfQorCisgICAgcHJpdmF0ZSBQcml2YXRlS2V5SW5mbyhpbnQgdmVyc2lvbiwKKyAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIgcHJpdmF0ZUtleUFsZ29yaXRobSwgYnl0ZVtdIHByaXZhdGVLZXksCisgICAgICAgICAgICBMaXN0IGF0dHJpYnV0ZXMsIGJ5dGVbXSBlbmNvZGluZykgeworICAgICAgICB0aGlzKHZlcnNpb24sIHByaXZhdGVLZXlBbGdvcml0aG0sIHByaXZhdGVLZXksIGF0dHJpYnV0ZXMpOworICAgICAgICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRWZXJzaW9uKCkgeworICAgICAgICByZXR1cm4gdmVyc2lvbjsKKyAgICB9CisKKyAgICBwdWJsaWMgQWxnb3JpdGhtSWRlbnRpZmllciBnZXRBbGdvcml0aG1JZGVudGlmaWVyKCkgeworICAgICAgICByZXR1cm4gcHJpdmF0ZUtleUFsZ29yaXRobTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdCBnZXRBdHRyaWJ1dGVzKCkgeworICAgICAgICByZXR1cm4gYXR0cmlidXRlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBPQ1RFVCBTVFJJTkcuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRQcml2YXRlS2V5KCkgeworICAgICAgICByZXR1cm4gcHJpdmF0ZUtleTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFTTi4xIGVuY29kZWQgZm9ybSBvZiB0aGlzIFByaXZhdGVLZXlJbmZvLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIGVuY29kaW5nID0gQVNOMS5lbmNvZGUodGhpcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVuY29kaW5nOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVNlcXVlbmNlIEFTTjEgPSBuZXcgQVNOMVNlcXVlbmNlKG5ldyBBU04xVHlwZVtdIHsKKworICAgIEFTTjFJbnRlZ2VyLmdldEluc3RhbmNlKCksIC8vIHZlcnNpb24KKyAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIuQVNOMSwgLy8gQWxnb3JpdGhtSWRlbnRpZmllcgorICAgICAgICAgICAgQVNOMU9jdGV0U3RyaW5nLmdldEluc3RhbmNlKCksIC8vIHByaXZhdGVLZXkKKworICAgICAgICAgICAgbmV3IEFTTjFJbXBsaWNpdCgwLCBuZXcgQVNOMVNldE9mKEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZS5BU04xKSkgLy8gYXR0cmlidXRlcworICAgICAgICAgICAgfSkgeworCisgICAgICAgIHsKKyAgICAgICAgICAgIHNldE9wdGlvbmFsKDMpOyAvLyBhdHRyaWJ1dGVzIGFyZSBPUFRJT05BTAorICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB7CisgICAgICAgICAgICBPYmplY3RbXSB2YWx1ZXMgPSAoT2JqZWN0W10pIGluLmNvbnRlbnQ7CisgICAgICAgICAgICByZXR1cm4gbmV3IFByaXZhdGVLZXlJbmZvKEFTTjFJbnRlZ2VyLnRvSW50VmFsdWUodmFsdWVzWzBdKSwKKyAgICAgICAgICAgICAgICAgICAgKEFsZ29yaXRobUlkZW50aWZpZXIpIHZhbHVlc1sxXSwgKGJ5dGVbXSkgdmFsdWVzWzJdLAorICAgICAgICAgICAgICAgICAgICAoTGlzdCkgdmFsdWVzWzNdLCBpbi5nZXRFbmNvZGVkKCkpOworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykgeworICAgICAgICAgICAgUHJpdmF0ZUtleUluZm8gcHJpdmF0ZUtleUluZm8gPSAoUHJpdmF0ZUtleUluZm8pIG9iamVjdDsKKyAgICAgICAgICAgIHZhbHVlc1swXSA9IEFTTjFJbnRlZ2VyLmZyb21JbnRWYWx1ZShwcml2YXRlS2V5SW5mby52ZXJzaW9uKTsKKyAgICAgICAgICAgIHZhbHVlc1sxXSA9IHByaXZhdGVLZXlJbmZvLnByaXZhdGVLZXlBbGdvcml0aG07CisgICAgICAgICAgICB2YWx1ZXNbMl0gPSBwcml2YXRlS2V5SW5mby5wcml2YXRlS2V5OworICAgICAgICAgICAgdmFsdWVzWzNdID0gcHJpdmF0ZUtleUluZm8uYXR0cmlidXRlczsKKyAgICAgICAgfQorICAgIH07Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Byb3ZpZGVyL2NlcnQvQ2FjaGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY2VydC9DYWNoZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEyYzViNGMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Byb3ZpZGVyL2NlcnQvQ2FjaGUuamF2YQpAQCAtMCwwICsxLDMyNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wcm92aWRlci5jZXJ0OworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBUaGUgY2FjaGluZyBtZWNoYW5pc20gZGVzaWduZWQgdG8gc3BlZWQgdXAgdGhlIHByb2Nlc3MKKyAqIG9mIENlcnRpZmljYXRlcy9DUkxzIGdlbmVyYXRpb24gaW4gdGhlIGNhc2Ugb2YgdGhlaXIgcmVwZWF0ZWQKKyAqIGdlbmVyYXRpb24uCisgKgorICogSXQga2VlcHMgY29ycmVzcG9uZGVuY2VzIGJldHdlZW4gT2JqZWN0cyAoQ2VydGlmaWNhdGVzIG9yIENMUnMpCisgKiBhbmQgYXJyYXlzIG9mIGJ5dGVzIG9uIHRoZSBiYXNlIG9mIHdoaWNoIHRoZSBPYmplY3RzIGhhdmUgYmVlbiBnZW5lcmF0ZWQsCisgKiBhbmQgcHJvdmlkZXMgdGhlIG1lYW5zIHRvIGRldGVybWluZSB3aGV0aGVyIGl0IGNvbnRhaW5zIHRoZSBvYmplY3QgYnVpbHQgb24KKyAqIHRoZSBiYXNlIG9mIHBhcnRpY3VsYXIgZW5jb2RlZCBmb3JtIG9yIG5vdC4gSWYgdGhlcmUgYXJlIHN1Y2gKKyAqIG9iamVjdHMgdGhleSBhcmUgcmV0dXJuZWQgZnJvbSB0aGUgY2FjaGUsIGlmIG5vdCAtIG5ld2x5IGdlbmVyYXRlZAorICogb2JqZWN0cyBjYW4gYmUgc2F2ZWQgaW4gdGhlIGNhY2hlLjxicj4KKyAqCisgKiBUaGUgcHJvY2VzcyBvZiBDZXJ0aWZpY2F0ZS9DUkwgZ2VuZXJhdGlvbgorICogKGltcGxlbWVudGVkIGluIDxjb2RlPlg1MDlDZXJ0RmFjdG9yeUltcGw8L2NvZGU+KSBpcyBhY2NvbXBhbmllZCB3aXRoCisgKiBwcmVyZWFkaW5nIG9mIHRoZSBiZWdpbm5pbmcgb2YgZW5jb2RlZCBmb3JtLiBUaGlzIHByZWZpeCBpcyB1c2VkIHRvIGRldGVybWluZQorICogd2hldGhlciBwcm92aWRlZCBmb3JtIGlzIFBFTSBlbmNvZGluZyBvciBub3QuPGJyPgorICoKKyAqIFNvIHRoZSB1c2Ugb2YgdGhlIHByZWZpeCBpcyB0aGUgZmlyc3QgcG9pbnQgdG8gKGFwcHJveGltYXRlbHkpCisgKiBkZXRlcm1pbmUgd2hldGhlciBvYmplY3QgdG8gYmUgZ2VuZXJhdGVkIGlzIGluIHRoZSBjYWNoZSBvciBub3QuCisgKgorICogVGhlIGZhaWx1cmUgb2YgdGhlIHByZWRldGVybWluYXRpb24gcHJvY2VzcyB0ZWxscyB1cyB0aGF0IHRoZXJlIHdlcmUgbm90CisgKiBvYmplY3QgZ2VuZXJhdGVkIGZyb20gdGhlIGVuY29kZWQgZm9ybSB3aXRoIHN1Y2ggcHJlZml4IGFuZCB3ZSBzaG91bGQKKyAqIGdlbmVyYXRlIChkZWNvZGUpIHRoZSBvYmplY3QuIElmIHByZWRldGVybWluYXRpb24gaXMgc3VjY2Vzc2Z1bCwKKyAqIHdlIGNvbmR1Y3QgdGhlIGFjY3VyYXRlIHNlYXJjaCBvbiB0aGUgYmFzZSBvZiB3aG9sZSBlbmNvZGVkIGZvcm0uIDxicj4KKyAqCisgKiBTbyB0byBzcGVlZCB1cCB0aGUgb2JqZWN0IGdlbmVyYXRpb24gcHJvY2VzcyB0aGlzIGNhY2hpbmcgbWVjaGFuaXNtIHByb3ZpZGVzCisgKiB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uYWxpdHk6PGJyPgorICoKKyAqICAgICAgMS4gV2l0aCBoYXZpbmcgb2YgdGhlIGJlZ2lubmluZyBvZiB0aGUgZW5jb2RlZCBmb3JtIChwcmVmaXgpCisgKiBpdCBpcyBwb3NzaWJsZSB0byBwcmVkZXRlcm1pbmUgd2hldGhlciBvYmplY3QgaGFzIGFscmVhZHkgYmVlbgorICogZ2VuZXJhdGVkIG9uIHRoZSBiYXNlIG9mIHRoZSBlbmNvZGluZyB3aXRoIHRoZSBTSU1JTEFSIHByZWZpeCBvciBub3QuCisgKiBUaGlzIHByb2Nlc3MgaXMgbm90IGNvbXB1dGF0aW9uYWxseSBleHBlbnNpdmUgYW5kIHRha2VzIGEgbGl0dGxlIHRpbWUuCisgKiBCdXQgaXQgcHJldmVudHMgdXMgZnJvbSB1c2Ugb2YgZXhwZW5zaXZlIGZ1bGwgZW5jb2RpbmcKKyAqIHNlYXJjaCBpbiB0aGUgY2FzZSBvZiBpdHMgZmFpbHVyZS48YnI+CisgKgorICogICAgICAyLiBJZiBwcmVkZXRlcm1pbmF0aW9uIGVuZHMgd2l0aCBzdWNjZXNzLCB0aGUgd2hvbGUgZW5jb2RpbmcKKyAqIGZvcm0gc2hvdWxkIGJlIHByb3ZpZGVkIHRvIG1ha2UgdGhlIGZpbmFsIGFuc3dlcjogd2hldGhlciBvYmplY3QgaGFzCisgKiBhbHJlYWR5IGJlZW4gZ2VuZXJhdGVkIG9uIHRoZSBiYXNlIG9mIHRoaXMgUEFSVElDVUxBUiBlbmNvZGVkIGZvcm0gb3Igbm90LgorICogSWYgaXQgaXMgc28gLSB0aGUgY2FjaGVkIG9iamVjdCBpcyByZXR1cm5lZCBmcm9tIHRoZSBjYWNoZSwKKyAqIGlmIG5vdCAtIG5ldyBvYmplY3Qgc2hvdWxkIGJlIGdlbmVyYXRlZCBhbmQgc2F2ZWQgaW4gdGhlIGNhY2hlLjxicj4KKyAqCisgKiBOb3RlOiBUaGUgbGVuZ3RoIG9mIHRoZSBwcmVmaXhlcyBvZiB0aGUgZW5jb2RlZCBmb3JtcyBzaG91bGQgbm90IGJlCisgKiBsZXNzIHRoYW4gY29ycmVzcG9uZGVuY2UgKGRlZmF1bHQgdmFsdWUgaXMgMjgpLgorICovCitwdWJsaWMgY2xhc3MgQ2FjaGUgeworCisgICAgLy8gSGFzaCBjb2RlIGNvbnNpc3Qgb2YgNiBieXRlczogQUFCQjAwCisgICAgLy8gd2hlcmU6CisgICAgLy8gQUEgLSAyIGJ5dGVzIGZvciBwcmVmaXggaGFzaAorICAgIC8vICAgICAgdmFsdWUgZ2VuZXJhdGVkIG9uIHRoZSBiYXNlIG9mIHRoZSBwcmVmaXggb2YgZW5jb2RpbmcKKyAgICAvLyBCQiAtIDIgYnl0ZXMgZm9yIHRhaWwgaGFzaAorICAgIC8vICAgICAgdmFsdWUgZ2VuZXJhdGVkIG9uIHRoZSBiYXNlIG9mIHRoZSB0YWlsIG9mIGVuY29kaW5nCisgICAgLy8gMDAgLSAyIHJlc2VydmVkIGJ5dGVzIGVxdWFscyB0byAwCisgICAgLy8KKyAgICAvLyBOb3RlLCB0aGF0IGl0IGlzIHBvc3NpYmxlIGZvciAyIGRpZmZlcmVudCBhcnJheXMgdG8gaGF2ZQorICAgIC8vIHRoZSBzaW1pbGFyIGhhc2ggY29kZXMuCisKKyAgICAvLyBUaGUgbWFza3MgdG8gd29yayB3aXRoIGhhc2ggY29kZXM6CisgICAgLy8gdGhlIGhhc2ggY29kZSB3aXRob3V0IHRoZSByZXNlcnZlZCBieXRlcworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgSEFTSF9NQVNLID0gMHhGRkZGRkZGRkZGRkYwMDAwTDsKKyAgICAvLyB0aGUgaGFzaCBjb2RlIG9mIHRoZSBwcmVmaXgKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIFBSRUZJWF9IQVNIX01BU0sgPSAweEZGRkZGRkZGMDAwMDAwMDBMOworICAgIC8vIHRoZSBpbmRleCB2YWx1ZSBjb250YWluZWQgaW4gcmVzZXJ2ZWQgYnl0ZXMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgIElOREVYX01BU0sgPSAweDAwRkZGRjsKKworICAgIC8vIHNpemUgb2YgdGhlIGNhY2hlCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgY2FjaGVfc2l6ZTsKKyAgICAvLyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdoaWNoIHdpbGwgYmUgdXNlZCBmb3IgYXJyYXkgaGFzaCBnZW5lcmF0aW9uLgorICAgIHByaXZhdGUgZmluYWwgaW50IHByZWZpeF9zaXplOworCisgICAgLy8gVGhlIGZvbGxvd2luZyAzIGFycmF5cyBjb250YWluIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBjYWNoZWQgb2JqZWN0cy4KKyAgICAvLyBUaGlzIGluZm9ybWF0aW9uIGluY2x1ZGVzOiBoYXNoIG9mIHRoZSBhcnJheSwgZW5jb2RlZCBmb3JtIG9mIHRoZSBvYmplY3QsCisgICAgLy8gYW5kIHRoZSBvYmplY3QgaXRzZWxmLgorICAgIC8vIFRoZSBoYXNoLWVuY29kaW5nLW9iamVjdCBjb3JyZXNwb25kZW5jZSBpcyBtYWRlIGJ5IG1lYW5zIG9mIGluZGV4CisgICAgLy8gaW4gdGhlIHBhcnRpY3VsYXIgYXJyYXkuIEkuZS4gZm9yIGluZGV4IE4gaGFzaCBjb250YWluZWQgaW4gaGFzaGVzW05dCisgICAgLy8gY29ycmVzcG9uZHMgdG8gdGhlIGVuY29kaW5nIGNvbnRhaW5lZCBpbiBlbmNvZGluZ3NbTl0gd2hpY2ggY29ycmVzcG9uZHMKKyAgICAvLyB0byB0aGUgb2JqZWN0IGNhY2hlZCBhdCBjYWNoZVtOXQorCisgICAgLy8gYXJyYXkgY29udGFpbmluZyB0aGUgaGFzaCBjb2RlcyBvZiBlbmNvZGluZ3MKKyAgICBwcml2YXRlIGZpbmFsIGxvbmdbXSBoYXNoZXM7CisgICAgLy8gYXJyYXkgY29udGFpbmluZyB0aGUgZW5jb2RpbmdzIG9mIHRoZSBjYWNoZWQgb2JqZWN0cworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdW10gZW5jb2RpbmdzOworICAgIC8vIGFycmF5IGNvbnRhaW5pbmcgdGhlIGNhY2hlZCBvYmplY3RzCisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3RbXSBjYWNoZTsKKworICAgIC8vIFRoaXMgYXJyYXkgaXMgdXNlZCB0byBzcGVlZCB1cCB0aGUgcHJvY2VzcyBvZiB0aGUgc2VhcmNoIGluIHRoZSBjYWNoZS4KKyAgICAvLyBUaGlzIGlzIGFuIG9yZGVyZWQgYXJyYXkgb2YgdGhlIGhhc2ggY29kZXMgZnJvbSAnaGFzaGVzJyBhcnJheSAoZGVzY3JpYmVkCisgICAgLy8gYWJvdmUpIHdpdGggbGFzdCAyIChyZXNlcnZlZCkgYnl0ZXMgZXF1YWxzIHRvIHRoZSBpbmRleCBvZgorICAgIC8vIHRoZSBoYXNoIGluIHRoZSAnaGFzaGVzJyBhcnJheS4gSS5lLiBoYXNoIGNvZGUgQUJDRDAwIHdpdGggaW5kZXggMTAgaW4KKyAgICAvLyB0aGUgaGFzaGVzIGFycmF5IHdpbGwgYmUgcmVwcmVzZW50ZWQgaW4gdGhpcyBhcnJheSBhcyBBQkNEMEEgKDEwPT0weDBBKQorICAgIC8vIFNvIHRoaXMgYXJyYXkgY29udGFpbnMgb3JkZXJlZCA8aGFzaCB0byBpbmRleD4gY29ycmVzcG9uZGVuY2VzLgorICAgIC8vIE5vdGUsIHRoYXQgZXZlcnkgaXRlbSBpbiB0aGlzIGFycmF5IGlzIHVuaXF1ZS4KKyAgICBwcml2YXRlIGZpbmFsIGxvbmdbXSBoYXNoZXNfaWR4OworCisgICAgLy8gdGhlIGluZGV4IG9mIHRoZSBsYXN0IGNhY2hlZCBvYmplY3QKKyAgICBwcml2YXRlIGludCBsYXN0X2NhY2hlZCA9IDA7CisgICAgLy8gY2FjaGUgcG9wdWxhdGlvbiBpbmRpY2F0b3IKKyAgICBwcml2YXRlIGJvb2xlYW4gY2FjaGVfaXNfZnVsbCA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgQ2FjaGUgb2JqZWN0LgorICAgICAqIEBwYXJhbSBwcmVmX3NpemUgc3BlY2lmaWVzIGhvdyBtYW55IGxlYWRpbmcvdHJhaWxpbmcgYnl0ZXMgb2Ygb2JqZWN0J3MKKyAgICAgKiBlbmNvZGVkIGZvcm0gd2lsbCBiZSB1c2VkIGZvciBoYXNoIGNvbXB1dGF0aW9uCisgICAgICogQHBhcmFtIHNpemUgY2FwYWNpdHkgb2YgdGhlIGNhY2hlIHRvIGJlIGNyZWF0ZWQuCisgICAgICovCisgICAgcHVibGljIENhY2hlKGludCBwcmVmX3NpemUsIGludCBzaXplKSB7CisgICAgICAgIGNhY2hlX3NpemUgPSBzaXplOworICAgICAgICBwcmVmaXhfc2l6ZSA9IHByZWZfc2l6ZTsKKyAgICAgICAgaGFzaGVzID0gbmV3IGxvbmdbY2FjaGVfc2l6ZV07CisgICAgICAgIGhhc2hlc19pZHggPSBuZXcgbG9uZ1tjYWNoZV9zaXplXTsKKyAgICAgICAgZW5jb2RpbmdzID0gbmV3IGJ5dGVbY2FjaGVfc2l6ZV1bXTsKKyAgICAgICAgY2FjaGUgPSBuZXcgT2JqZWN0W2NhY2hlX3NpemVdOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIENhY2hlIG9iamVjdCBvZiBzaXplIG9mIDkuCisgICAgICogQHBhcmFtIHByZWZfc2l6ZSBzcGVjaWZpZXMgaG93IG1hbnkgbGVhZGluZy90cmFpbGluZyBieXRlcyBvZiBvYmplY3QncworICAgICAqIGVuY29kZWQgZm9ybSB3aWxsIGJlIHVzZWQgZm9yIGhhc2ggY29tcHV0YXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2FjaGUoaW50IHByZWZfc2l6ZSkgeworICAgICAgICB0aGlzKHByZWZfc2l6ZSwgOSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgQ2FjaGUgb2JqZWN0IG9mIHNpemUgb2YgOS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2FjaGUoKSB7CisgICAgICAgIHRoaXMoMjgsIDkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhhc2ggY29kZSBmb3IgdGhlIGFycmF5LiBUaGlzIGNvZGUgaXMgdXNlZCB0bworICAgICAqIHByZWRldGVybWluZSB3aGV0aGVyIHRoZSBvYmplY3Qgd2FzIGJ1aWx0IG9uIHRoZSBiYXNlIG9mIHRoZQorICAgICAqIHNpbWlsYXIgZW5jb2Rpbmcgb3Igbm90IChieSBtZWFucyBvZiA8Y29kZT5jb250YWlucyhsb25nKTwvY29kZT4gbWV0aG9kKSwKKyAgICAgKiB0byBleGFjdGx5IGRldGVybWluZSB3aGV0aGVyIG9iamVjdCBpcyBjb250YWluZWQgaW4gdGhlIGNhY2hlIG9yIG5vdCwKKyAgICAgKiBhbmQgdG8gcHV0IHRoZSBvYmplY3QgaW4gdGhlIGNhY2hlLgorICAgICAqIE5vdGU6IHBhcmFtZXRlciBhcnJheSBzaG91bGQgYmUgb2YgbGVuZ3RoIG5vdCBsZXNzIHRoYW4KKyAgICAgKiBzcGVjaWZpZWQgYnkgPGNvZGU+cHJlZml4X3NpemU8L2NvZGU+IChkZWZhdWx0IDI4KQorICAgICAqIEBwYXJhbSBhcnIgdGhlIGJ5dGUgYXJyYXkgY29udGFpbmluZyBhdCBsZWFzdCBwcmVmaXhfc2l6ZSBsZWFkaW5nIGJ5dGVzCisgICAgICogb2YgdGhlIGVuY29kaW5nLgorICAgICAqIEByZXR1cm4gaGFzaCBjb2RlIGZvciBzcGVjaWZpZWQgZW5jb2RpbmcgcHJlZml4CisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0SGFzaChieXRlW10gYXJyKSB7CisgICAgICAgIGxvbmcgaGFzaCA9IDA7CisgICAgICAgIGZvciAoaW50IGk9MTsgaTxwcmVmaXhfc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBoYXNoICs9IChhcnJbaV0gJiAweEZGKTsKKyAgICAgICAgfSAvLyBpdCB0YWtlcyBhYm91dCAyIGJ5dGVzIGZvciBwcmVmaXhfc2l6ZSA9PSAyOAorCisgICAgICAgIC8vIHNoaWZ0IHRvIHRoZSBjb3JyZWN0IHBsYWNlCisgICAgICAgIGhhc2ggPSBoYXNoIDw8IDMyOworICAgICAgICByZXR1cm4gaGFzaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhlcmUgYXJlIGFueSBvYmplY3QgaW4gdGhlIGNhY2hlIGdlbmVyYXRlZAorICAgICAqIG9uIHRoZSBiYXNlIG9mIGVuY29kaW5nIHdpdGggcHJlZml4IGNvcnJlc3BvbmRpbmcKKyAgICAgKiB0byB0aGUgc3BlY2lmaWVkIGhhc2ggY29kZS4KKyAgICAgKiBAcGFyYW0gcHJlZml4X2hhc2ggdGhlIGhhc2ggY29kZSBmb3IgdGhlIHByZWZpeAorICAgICAqIG9mIHRoZSBlbmNvZGluZyAocmV0cmlldmVkIGJ5IG1ldGhvZCA8Y29kZT5nZXRIYXNoKGJ5dGVbXSkpPC9jb2RlPgorICAgICAqIEByZXR1cm4gZmFsc2UgaWYgdGhlcmUgd2VyZSBub3QgYW55IG9iamVjdCBnZW5lcmF0ZWQKKyAgICAgKiBvbiB0aGUgYmFzZSBvZiBlbmNvZGluZyB3aXRoIHNwZWNpZmllZCBoYXNoIGNvZGUsIHRydWUKKyAgICAgKiBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMobG9uZyBwcmVmaXhfaGFzaCkgeworICAgICAgICBpZiAocHJlZml4X2hhc2ggPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGludCBpZHggPSAtMSpBcnJheXMuYmluYXJ5U2VhcmNoKGhhc2hlc19pZHgsIHByZWZpeF9oYXNoKS0xOworICAgICAgICBpZiAoaWR4ID09IGNhY2hlX3NpemUpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiAoaGFzaGVzX2lkeFtpZHhdICYgUFJFRklYX0hBU0hfTUFTSykgPT0gcHJlZml4X2hhc2g7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBvYmplY3QgYnVpbHQgb24gdGhlIGJhc2Ugb24gdGhlIHNwZWNpZmllZCBlbmNvZGVkCisgICAgICogZm9ybSBpZiBpdCBpcyBjb250YWluZWQgaW4gdGhlIGNhY2hlIGFuZCBudWxsIG90aGVyd2lzZS4KKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBjb21wdXRhdGlvbmFsbHkgZXhwZW5zaXZlIGFuZCBzaG91bGQgYmUgY2FsbGVkIG9ubHkgaWYKKyAgICAgKiB0aGUgbWV0aG9kIDxjb2RlPmNvbnRhaW5zKGxvbmcpPC9jb2RlPiBmb3IgdGhlIGhhc2ggY29kZSByZXR1cm5lZCB0cnVlLgorICAgICAqIEBwYXJhbSBoYXNoIHRoZSBoYXNoIGNvZGUgZm9yIHRoZSBwcmVmaXggb2YgdGhlIGVuY29kaW5nCisgICAgICogKHJldHJpZXZlZCBieSBtZXRob2QgPGNvZGU+Z2V0SGFzaChieXRlW10pPC9jb2RlPikKKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcgZW5jb2RlZCBmb3JtIG9mIHRoZSByZXF1aXJlZCBvYmplY3QuCisgICAgICogQHJldHVybiB0aGUgb2JqZWN0IGNvcnJlc3BvbmRpbmcgdG8gc3BlY2lmaWVkIGVuY29kaW5nIG9yIG51bGwgaWYKKyAgICAgKiB0aGVyZSBpcyBubyBzdWNoIGNvcnJlc3BvbmRlbmNlLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0KGxvbmcgaGFzaCwgYnl0ZVtdIGVuY29kaW5nKSB7CisgICAgICAgIGhhc2ggfD0gZ2V0U3VmZkhhc2goZW5jb2RpbmcpOworICAgICAgICBpZiAoaGFzaCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpbnQgaWR4ID0gLTEqQXJyYXlzLmJpbmFyeVNlYXJjaChoYXNoZXNfaWR4LCBoYXNoKS0xOworICAgICAgICBpZiAoaWR4ID09IGNhY2hlX3NpemUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHdoaWxlICgoaGFzaGVzX2lkeFtpZHhdICYgSEFTSF9NQVNLKSA9PSBoYXNoKSB7CisgICAgICAgICAgICBpbnQgaSA9IChpbnQpIChoYXNoZXNfaWR4W2lkeF0gJiBJTkRFWF9NQVNLKSAtIDE7CisgICAgICAgICAgICBpZiAoQXJyYXlzLmVxdWFscyhlbmNvZGluZywgZW5jb2RpbmdzW2ldKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBjYWNoZVtpXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlkeCsrOworICAgICAgICAgICAgaWYgKGlkeCA9PSBjYWNoZV9zaXplKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHV0cyB0aGUgb2JqZWN0IGludG8gdGhlIGNhY2hlLgorICAgICAqIEBwYXJhbSBoYXNoIGhhc2ggY29kZSBmb3IgdGhlIHByZWZpeCBvZiB0aGUgZW5jb2RpbmcKKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGVuY29kZWQgZm9ybSBvZiB0aGUgb2JqZWN0CisgICAgICogQHBhcmFtIG9iamVjdCB0aGUgb2JqZWN0IHRvIGJlIHNhdmVkIGluIHRoZSBjYWNoZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1dChsb25nIGhhc2gsIGJ5dGVbXSBlbmNvZGluZywgT2JqZWN0IG9iamVjdCkgeworICAgICAgICAvLyBjaGVjayBmb3IgZW1wdHkgc3BhY2UgaW4gdGhlIGNhY2hlCisgICAgICAgIGlmIChsYXN0X2NhY2hlZCA9PSBjYWNoZV9zaXplKSB7CisgICAgICAgICAgICAvLyBzbyBjYWNoZSBpcyBmdWxsLCB3aWxsIGVyYXNlIHRoZSBmaXJzdCBlbnRyeSBpbiB0aGUKKyAgICAgICAgICAgIC8vIGNhY2hlIChvbGRlc3QgZW50cnkpLiBpdCBjb3VsZCBiZSBiZXR0ZXIgdG8gdGhyb3cgb3V0CisgICAgICAgICAgICAvLyByYXJlbHkgdXNlZCB2YWx1ZSBpbnN0ZWFkIG9mIG9sZGVzdCBvbmUuLgorICAgICAgICAgICAgbGFzdF9jYWNoZWQgPSAwOworICAgICAgICAgICAgY2FjaGVfaXNfZnVsbCA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgLy8gaW5kZXggcG9pbnRpbmcgdG8gdGhlIGl0ZW0gb2YgdGhlIHRhYmxlIHRvIGJlIG92ZXJ3cml0dGVuCisgICAgICAgIGludCBpbmRleCA9IGxhc3RfY2FjaGVkKys7CisKKyAgICAgICAgLy8gaW1wcm92ZSB0aGUgaGFzaCB2YWx1ZSB3aXRoIGluZm8gZnJvbSB0aGUgdGFpbCBvZiBlbmNvZGluZworICAgICAgICBoYXNoIHw9IGdldFN1ZmZIYXNoKGVuY29kaW5nKTsKKworICAgICAgICBpZiAoY2FjaGVfaXNfZnVsbCkgeworICAgICAgICAgICAgLy8gaW5kZXhpbmcgaGFzaCB2YWx1ZSB0byBiZSBvdmVyd3JpdHRlbjoKKyAgICAgICAgICAgIGxvbmcgaWR4X2hhc2ggPSAoaGFzaGVzW2luZGV4XSB8IChpbmRleCsxKSk7CisgICAgICAgICAgICBpbnQgaWR4ID0gQXJyYXlzLmJpbmFyeVNlYXJjaChoYXNoZXNfaWR4LCBpZHhfaGFzaCk7CisgICAgICAgICAgICBpZiAoaWR4IDwgMCkgeworICAgICAgICAgICAgICAgIC8vIGl0IHdpbGwgbmV2ZXIgaGFwcGVuIGJlY2F1c2Ugd2UgdXNlIHNhdmVkIGhhc2ggdmFsdWUKKyAgICAgICAgICAgICAgICAvLyAoaGFzaGVzW2luZGV4XSkKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIldBUk5JTkchICIraWR4KTsKKyAgICAgICAgICAgICAgICBpZHggPSAtKGlkeCArIDEpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbG9uZyBuZXdfaGFzaF9pZHggPSAoaGFzaCB8IChpbmRleCArIDEpKTsKKyAgICAgICAgICAgIGludCBuZXdfaWR4ID0gQXJyYXlzLmJpbmFyeVNlYXJjaChoYXNoZXNfaWR4LCBuZXdfaGFzaF9pZHgpOworICAgICAgICAgICAgaWYgKG5ld19pZHggPj0gMCkgeworICAgICAgICAgICAgICAgIC8vIGl0J3MgcG9zc2libGUgd2hlbiB3ZSB3cml0ZSB0aGUgc2FtZSBoYXNoIGluIHRoZSBzYW1lIGNlbGwKKyAgICAgICAgICAgICAgICBpZiAoaWR4ICE9IG5ld19pZHgpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gaXQgd2lsbCBuZXZlciBoYXBwZW4gYmVjYXVzZSB3ZSB1c2UgdGhlIHNhbWUKKyAgICAgICAgICAgICAgICAgICAgLy8gaGFzaCBhbmQgdGhlIHNhbWUgaW5kZXggaW4gaGFzaCB0YWJsZQorICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIldBUk5JTkc6ICIpOworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj4+IGlkeDogIitpZHgrIiBuZXdfaWR4OiAiK25ld19pZHgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgbmV3X2lkeCA9IC0obmV3X2lkeCArIDEpOworICAgICAgICAgICAgICAgIC8vIHJlcGxhY2UgaW4gc29ydGVkIGFycmF5CisgICAgICAgICAgICAgICAgaWYgKG5ld19pZHggPiBpZHgpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShoYXNoZXNfaWR4LCBpZHgrMSwgaGFzaGVzX2lkeCwgaWR4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld19pZHggLSBpZHggLSAxKTsKKyAgICAgICAgICAgICAgICAgICAgaGFzaGVzX2lkeFtuZXdfaWR4LTFdID0gbmV3X2hhc2hfaWR4OworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaWR4ID4gbmV3X2lkeCkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGhhc2hlc19pZHgsIG5ld19pZHgsIGhhc2hlc19pZHgsIG5ld19pZHgrMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZHggLSBuZXdfaWR4KTsKKyAgICAgICAgICAgICAgICAgICAgaGFzaGVzX2lkeFtuZXdfaWR4XSA9IG5ld19oYXNoX2lkeDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBpZHggPT0gbmV3X2lkeAorICAgICAgICAgICAgICAgICAgICBoYXNoZXNfaWR4W25ld19pZHhdID0gbmV3X2hhc2hfaWR4OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGxvbmcgaWR4X2hhc2ggPSAoaGFzaCB8IChpbmRleCArIDEpKTsKKyAgICAgICAgICAgIGludCBpZHggPSBBcnJheXMuYmluYXJ5U2VhcmNoKGhhc2hlc19pZHgsIGlkeF9oYXNoKTsKKyAgICAgICAgICAgIGlmIChpZHggPCAwKSB7CisgICAgICAgICAgICAgICAgLy8gaXQgd2lsbCBhbHdheXMgYmUgdHJ1ZSBiZWNhdXNlIGlkeF9oYXNoIGRlcGVuZHMgb24gaW5kZXgKKyAgICAgICAgICAgICAgICBpZHggPSAtKGlkeCArIDEpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWR4ID0gaWR4IC0gMTsKKyAgICAgICAgICAgIGlmIChpZHggIT0gY2FjaGVfc2l6ZSAtIGluZGV4IC0gMSkgeworICAgICAgICAgICAgICAgIC8vIGlmIG5vdCBpbiB0aGUgY2VsbCBjb250YWluaW5nIDAgKGZyZWUgY2VsbCksIGRvIGNvcHk6CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShoYXNoZXNfaWR4LCBjYWNoZV9zaXplIC0gaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICBoYXNoZXNfaWR4LCBjYWNoZV9zaXplIC0gaW5kZXggLSAxLAorICAgICAgICAgICAgICAgICAgICAgICAgaWR4IC0gKGNhY2hlX3NpemUgLSBpbmRleCkgKyAxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGhhc2hlc19pZHhbaWR4XSA9IGlkeF9oYXNoOworICAgICAgICB9CisgICAgICAgIC8vIG92ZXJ3cml0ZSB0aGUgdmFsdWVzIGluIHRoZSB0YWJsZXM6CisgICAgICAgIGhhc2hlc1tpbmRleF0gPSBoYXNoOworICAgICAgICBlbmNvZGluZ3NbaW5kZXhdID0gZW5jb2Rpbmc7CisgICAgICAgIGNhY2hlW2luZGV4XSA9IG9iamVjdDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgYnVpbHQgb24gdGhlIGJhc2Ugb2YgdGhlIHRhaWwgb2YgdGhlIGVuY29kZWQgZm9ybQorICAgIC8vIEBwYXJhbSBhcnIgLSB0aGUgYXJyYXkgY29udGFpbmluZyBhdCBsZWFzdCBwcmVmaXhfc2l6ZSB0cmFpbGluZyBieXRlcworICAgIC8vIG9mIGVuY29kZWQgZm9ybQorICAgIHByaXZhdGUgbG9uZyBnZXRTdWZmSGFzaChieXRlW10gYXJyKSB7CisgICAgICAgIGxvbmcgaGFzaF9hZGRvbiA9IDA7CisgICAgICAgIGZvciAoaW50IGk9YXJyLmxlbmd0aC0xOyBpPmFyci5sZW5ndGggLSBwcmVmaXhfc2l6ZTsgaS0tKSB7CisgICAgICAgICAgICBoYXNoX2FkZG9uICs9IChhcnJbaV0gJiAweEZGKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzaF9hZGRvbiA8PCAxNjsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY2VydC9EUkxDZXJ0RmFjdG9yeS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jZXJ0L0RSTENlcnRGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzkwYmU2NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY2VydC9EUkxDZXJ0RmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsNDQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkucHJvdmlkZXIuY2VydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBEUkxDZXJ0RmFjdG9yeSBleHRlbmRzIFByb3ZpZGVyIHsKKyAgICAvKioKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTcyNjk2NTA3Nzk2MDUxOTU4NzlMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyB0aGUgaW5zdGFuY2Ugb2YgdGhlIGNlcnRpZmljYXRlIGZhY3RvcnkgcHJvdmlkZXIuCisgICAgICovCisgICAgcHVibGljIERSTENlcnRGYWN0b3J5KCkgeworICAgICAgICAvLyBzcGVjaWZpY2F0aW9uIG9mIHRoZSBwcm92aWRlciBuYW1lLCB2ZXJzaW9uLCBhbmQgZGVzY3JpcHRpb24uCisgICAgICAgIHN1cGVyKCJEUkxDZXJ0RmFjdG9yeSIsIDEuMCwgIkFTTi4xLCBERVIsIFBraVBhdGgsIFBLQ1M3Iik7CisgICAgICAgIC8vIHJlZ2lzdGVyIHRoZSBzZXJ2aWNlCisgICAgICAgIHB1dCgiQ2VydGlmaWNhdGVGYWN0b3J5Llg1MDkiLCAib3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnByb3ZpZGVyLmNlcnQuWDUwOUNlcnRGYWN0b3J5SW1wbCIpOworICAgICAgICAvLyBtYXBwaW5nIHRoZSBhbGlhcworICAgICAgICBwdXQoIkFsZy5BbGlhcy5DZXJ0aWZpY2F0ZUZhY3RvcnkuWC41MDkiLCAiWDUwOSIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY2VydC9YNTA5Q1JMRW50cnlJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Byb3ZpZGVyL2NlcnQvWDUwOUNSTEVudHJ5SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM4NTAwZTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Byb3ZpZGVyL2NlcnQvWDUwOUNSTEVudHJ5SW1wbC5qYXZhCkBAIC0wLDAgKzEsMTc5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnByb3ZpZGVyLmNlcnQ7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ1JMRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMRW50cnk7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5FeHRlbnNpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuRXh0ZW5zaW9uczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5UQlNDZXJ0TGlzdDsKKworLyoqCisgKiBJbXBsZW1lbnRhdGlvbiBvZiBYNTA5Q1JMRW50cnkuIEl0IHdyYXBzIHRoZSBpbnN0YW5jZQorICogb2Ygb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuVEJTQ2VydExpc3QuUmV2b2tlZENlcnRpZmljYXRlCisgKiBvYnRhaW5lZCBkdXJpbmcgdGhlIGRlY29kaW5nIG9mIFRCU0NlcnRMaXN0IHN1YnN0cnVjdHVyZQorICogb2YgdGhlIENlcnRpZmljYXRlTGlzdCBzdHJ1Y3R1cmUgd2hpY2ggaXMgYW4gWC41MDkgZm9ybSBvZiBDUkwuCisgKiAoc2VlIFJGQyAzMjgwIGF0IGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KQorICogTm9ybWFsbHkgdGhlIGluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIGFyZSBjb25zdHJ1Y3RlZCBieSBpbnZvbHZpbmcKKyAqIFg1MDlDUkxJbXBsIG9iamVjdC4KKyAqIEBzZWUgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuVEJTQ2VydExpc3QKKyAqIEBzZWUgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnByb3ZpZGVyLmNlcnQuWDUwOUNSTEltcGwKKyAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDUkxFbnRyeQorICovCitwdWJsaWMgY2xhc3MgWDUwOUNSTEVudHJ5SW1wbCBleHRlbmRzIFg1MDlDUkxFbnRyeSB7CisKKyAgICAvLyB0aGUgY3JsIGVudHJ5IG9iamVjdCB0byBiZSB3cmFwcGVkIGluIFg1MDlDUkxFbnRyeQorICAgIHByaXZhdGUgZmluYWwgVEJTQ2VydExpc3QuUmV2b2tlZENlcnRpZmljYXRlIHJjZXJ0OworICAgIC8vIHRoZSBleHRlbnNpb25zIG9mIHRoZSBlbnRyeQorICAgIHByaXZhdGUgZmluYWwgRXh0ZW5zaW9ucyBleHRlbnNpb25zOworICAgIC8vIGlzc3VlciBvZiB0aGUgcmV2b2tlZCBjZXJ0aWZpY2F0ZSBkZXNjcmliZWQgYnkgdGhpcyBjcmwgZW50cnkKKyAgICBwcml2YXRlIGZpbmFsIFg1MDBQcmluY2lwYWwgaXNzdWVyOworCisgICAgLy8gZW5jb2RlZCBmb3JtIG9mIHRoaXMgcmV2b2tlZCBjZXJ0aWZpY2F0ZSBlbnRyeQorICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kaW5nOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvbiB0aGUgYmFzZSBvZiBleGlzdGluZworICAgICAqIDxjb2RlPlRCU0NlcnRMaXN0LlJldm9rZWRDZXJ0aWZpY2F0ZTwvY29kZT4gb2JqZWN0IGFuZAorICAgICAqIGluZm9ybWF0aW9uIGFib3V0IHRoZSBpc3N1ZXIgb2YgcmV2b2tlZCBjZXJ0aWZpY2F0ZS4KKyAgICAgKiBJZiBzcGVjaWZpZWQgaXNzdWVyIGlzIG51bGwsIGl0IGlzIHN1cHBvc2VkIHRoYXQgaXNzdWVyCisgICAgICogb2YgdGhlIHJldm9rZWQgY2VydGlmaWNhdGUgaXMgdGhlIHNhbWUgYXMgZm9yIGludm9sdmluZyBDUkwuCisgICAgICovCisgICAgcHVibGljIFg1MDlDUkxFbnRyeUltcGwoVEJTQ2VydExpc3QuUmV2b2tlZENlcnRpZmljYXRlIHJjZXJ0LAorICAgICAgICAgICAgWDUwMFByaW5jaXBhbCBpc3N1ZXIpIHsKKyAgICAgICAgdGhpcy5yY2VydCA9IHJjZXJ0OworICAgICAgICB0aGlzLmV4dGVuc2lvbnMgPSByY2VydC5nZXRDcmxFbnRyeUV4dGVuc2lvbnMoKTsKKyAgICAgICAgdGhpcy5pc3N1ZXIgPSBpc3N1ZXI7CisgICAgfQorCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gLS0tLS0tIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMRW50cnkgbWV0aG9kIGltcGxlbWVudGF0aW9ucyAtLS0tLS0tCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMRW50cnkjZ2V0RW5jb2RlZCgpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mbworICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHRocm93cyBDUkxFeGNlcHRpb24geworICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSByY2VydC5nZXRFbmNvZGVkKCk7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW2VuY29kaW5nLmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZW5jb2RpbmcsIDAsIHJlc3VsdCwgMCwgZW5jb2RpbmcubGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMRW50cnkjZ2V0U2VyaWFsTnVtYmVyKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0U2VyaWFsTnVtYmVyKCkgeworICAgICAgICByZXR1cm4gcmNlcnQuZ2V0VXNlckNlcnRpZmljYXRlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNSTEVudHJ5I2dldENlcnRpZmljYXRlSXNzdWVyKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIFg1MDBQcmluY2lwYWwgZ2V0Q2VydGlmaWNhdGVJc3N1ZXIoKSB7CisgICAgICAgIHJldHVybiBpc3N1ZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNSTEVudHJ5I2dldFJldm9jYXRpb25EYXRlKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0UmV2b2NhdGlvbkRhdGUoKSB7CisgICAgICAgIHJldHVybiByY2VydC5nZXRSZXZvY2F0aW9uRGF0ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDUkxFbnRyeSNoYXNFeHRlbnNpb25zKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzRXh0ZW5zaW9ucygpIHsKKyAgICAgICAgcmV0dXJuIChleHRlbnNpb25zICE9IG51bGwpICYmIChleHRlbnNpb25zLnNpemUoKSAhPSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMRW50cnkjdG9TdHJpbmcoKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gIlg1MDlDUkxFbnRyeUltcGw6ICIrcmNlcnQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAvLyAtLS0tLS0gamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlFeHRlbnNpb24gbWV0aG9kIGltcGxlbWVudGF0aW9ucyAtLS0tLS0KKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlFeHRlbnNpb24jZ2V0Tm9uQ3JpdGljYWxFeHRlbnNpb25PSURzKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIFNldCBnZXROb25Dcml0aWNhbEV4dGVuc2lvbk9JRHMoKSB7CisgICAgICAgIGlmIChleHRlbnNpb25zID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBleHRlbnNpb25zLmdldE5vbkNyaXRpY2FsRXh0ZW5zaW9ucygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlFeHRlbnNpb24jZ2V0Q3JpdGljYWxFeHRlbnNpb25PSURzKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIFNldCBnZXRDcml0aWNhbEV4dGVuc2lvbk9JRHMoKSB7CisgICAgICAgIGlmIChleHRlbnNpb25zID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBleHRlbnNpb25zLmdldENyaXRpY2FsRXh0ZW5zaW9ucygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlFeHRlbnNpb24jZ2V0RXh0ZW5zaW9uVmFsdWUoU3RyaW5nKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEV4dGVuc2lvblZhbHVlKFN0cmluZyBvaWQpIHsKKyAgICAgICAgaWYgKGV4dGVuc2lvbnMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgRXh0ZW5zaW9uIGV4dCA9IGV4dGVuc2lvbnMuZ2V0RXh0ZW5zaW9uQnlPSUQob2lkKTsKKyAgICAgICAgcmV0dXJuIChleHQgPT0gbnVsbCkgPyBudWxsIDogZXh0LmdldFJhd0V4dG5WYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlFeHRlbnNpb24jaGFzVW5zdXBwb3J0ZWRDcml0aWNhbEV4dGVuc2lvbigpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mbworICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc1Vuc3VwcG9ydGVkQ3JpdGljYWxFeHRlbnNpb24oKSB7CisgICAgICAgIGlmIChleHRlbnNpb25zID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZXh0ZW5zaW9ucy5oYXNVbnN1cHBvcnRlZENyaXRpY2FsKCk7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Byb3ZpZGVyL2NlcnQvWDUwOUNSTEltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY2VydC9YNTA5Q1JMSW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEzNGQ4ZjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Byb3ZpZGVyL2NlcnQvWDUwOUNSTEltcGwuamF2YQpAQCAtMCwwICsxLDUwNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wcm92aWRlci5jZXJ0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DUkxFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMRW50cnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnV0aWxzLkFsZ05hbWVNYXBwZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuQ2VydGlmaWNhdGVMaXN0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LkV4dGVuc2lvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5FeHRlbnNpb25zOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LlRCU0NlcnRMaXN0OworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgWDUwOUNSTC4gSXQgd3JhcHMKKyAqIHRoZSBpbnN0YW5jZSBvZiBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5DZXJ0aWZpY2F0ZUxpc3QKKyAqIGJ1aWx0IG9uIHRoZSBiYXNlIG9mIHByb3ZpZGVkIEFTTi4xIERFUiBlbmNvZGVkIGZvcm0gb2YKKyAqIENlcnRpZmljYXRlTGlzdCBzdHJ1Y3R1cmUgKGFzIHNwZWNpZmllZCBpbiBSRkMgMzI4MAorICogaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpLgorICogSW1wbGVtZW50YXRpb24gc3VwcG9ydHMgd29yayB3aXRoIGluZGlyZWN0IENSTHMuCisgKiBAc2VlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LkNlcnRpZmljYXRlTGlzdAorICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNSTAorICovCitwdWJsaWMgY2xhc3MgWDUwOUNSTEltcGwgZXh0ZW5kcyBYNTA5Q1JMIHsKKworICAgIC8vIHRoZSBjb3JlIG9iamVjdCB0byBiZSB3cmFwcGVkIGluIFg1MDlDUkwKKyAgICBwcml2YXRlIGZpbmFsIENlcnRpZmljYXRlTGlzdCBjcmw7CisKKyAgICAvLyBUbyBzcGVlZCB1cCBhY2Nlc3MgdG8gdGhlIGluZm8sIHRoZSBmb2xsb3dpbmcgZmllbGRzCisgICAgLy8gY2FjaGUgdmFsdWVzIHJldHJpZXZlZCBmcm9tIHRoZSBDZXJ0aWZpY2F0ZUxpc3Qgb2JqZWN0CisgICAgcHJpdmF0ZSBmaW5hbCBUQlNDZXJ0TGlzdCB0YnNDZXJ0TGlzdDsKKyAgICBwcml2YXRlIGJ5dGVbXSB0YnNDZXJ0TGlzdEVuY29kaW5nOworICAgIHByaXZhdGUgZmluYWwgRXh0ZW5zaW9ucyBleHRlbnNpb25zOworICAgIHByaXZhdGUgWDUwMFByaW5jaXBhbCBpc3N1ZXI7CisgICAgcHJpdmF0ZSBBcnJheUxpc3QgZW50cmllczsKKyAgICBwcml2YXRlIGludCBlbnRyaWVzU2l6ZTsKKyAgICBwcml2YXRlIGJ5dGVbXSBzaWduYXR1cmU7CisgICAgcHJpdmF0ZSBTdHJpbmcgc2lnQWxnT0lEOworICAgIHByaXZhdGUgU3RyaW5nIHNpZ0FsZ05hbWU7CisgICAgcHJpdmF0ZSBieXRlW10gc2lnQWxnUGFyYW1zOworCisgICAgLy8gZW5jb2RlZCBmb3JtIG9mIGNybAorICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kaW5nOworCisgICAgLy8gaW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNpZ25hdHVyZSBhbGdvcml0aG0gcGFyYW1ldGVycyBhcmUgbnVsbAorICAgIHByaXZhdGUgYm9vbGVhbiBudWxsU2lnQWxnUGFyYW1zOworICAgIC8vIGluZGljYXRlcyB3aGV0aGVyIHRoZSBjcmwgZW50cmllcyBoYXZlIGFscmVhZHkgYmVlbiByZXRyaWV2ZWQKKyAgICAvLyBmcm9tIENlcnRpZmljYXRlTGlzdCBvYmplY3QgKGNybCkKKyAgICBwcml2YXRlIGJvb2xlYW4gZW50cmllc1JldHJpZXZlZDsKKworICAgIC8vIGluZGljYXRlcyB3aGV0aGVyIHRoaXMgWC41MDkgQ1JMIGlzIGRpcmVjdCBvciBpbmRpcmVjdAorICAgIC8vIChzZWUgcmZjIDMyODAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQsIHAgNS4pCisgICAgcHJpdmF0ZSBib29sZWFuIGlzSW5kaXJlY3RDUkw7CisgICAgLy8gaWYgY3JsIGlzIGluZGlyZWN0LCB0aGlzIGZpZWxkIGhvbGRzIGFuIGluZm8gYWJvdXQgaG93CisgICAgLy8gbWFueSBvZiB0aGUgbGVhZGluZyBjZXJ0aWZpY2F0ZXMgaW4gdGhlIGxpc3QgYXJlIGlzc3VlZAorICAgIC8vIGJ5IHRoZSBzYW1lIGlzc3VlciBhcyBDUkwuCisgICAgcHJpdmF0ZSBpbnQgbm9uSW5kaXJlY3RFbnRyaWVzU2l6ZTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgWC41MDkgQ1JMIGJ5IHdyYXBwaW5nIG9mIHRoZSBzcGVjaWZpZWQgQ2VydGlmaWNhdGVMaXN0IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgWDUwOUNSTEltcGwoQ2VydGlmaWNhdGVMaXN0IGNybCkgeworICAgICAgICB0aGlzLmNybCA9IGNybDsKKyAgICAgICAgdGhpcy50YnNDZXJ0TGlzdCA9IGNybC5nZXRUYnNDZXJ0TGlzdCgpOworICAgICAgICB0aGlzLmV4dGVuc2lvbnMgPSB0YnNDZXJ0TGlzdC5nZXRDcmxFeHRlbnNpb25zKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBYLjUwOSBDUkwgb24gdGhlIGJhc2Ugb2YgQVNOLjEgREVSIGVuY29kZWQgZm9ybSBvZgorICAgICAqIHRoZSBDUkwgKENlcnRpZmljYXRlTGlzdCBzdHJ1Y3R1cmUgZGVzY3JpYmVkIGluIFJGQyAzMjgwKQorICAgICAqIHByb3ZpZGVkIHZpYSBpbnB1dCBzdHJlYW0uCisgICAgICogQHRocm93cyBDUkxFeGNlcHRpb24gaWYgZGVjb2RpbmcgZXJyb3JzIG9jY3VyLgorICAgICAqLworICAgIHB1YmxpYyBYNTA5Q1JMSW1wbChJbnB1dFN0cmVhbSBpbikgdGhyb3dzIENSTEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBkZWNvZGUgQ2VydGlmaWNhdGVMaXN0IHN0cnVjdHVyZQorICAgICAgICAgICAgdGhpcy5jcmwgPSAoQ2VydGlmaWNhdGVMaXN0KSBDZXJ0aWZpY2F0ZUxpc3QuQVNOMS5kZWNvZGUoaW4pOworICAgICAgICAgICAgdGhpcy50YnNDZXJ0TGlzdCA9IGNybC5nZXRUYnNDZXJ0TGlzdCgpOworICAgICAgICAgICAgdGhpcy5leHRlbnNpb25zID0gdGJzQ2VydExpc3QuZ2V0Q3JsRXh0ZW5zaW9ucygpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ1JMRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBYLjUwOSBDUkwgb24gdGhlIGJhc2Ugb2YgQVNOLjEgREVSIGVuY29kZWQgZm9ybSBvZgorICAgICAqIHRoZSBDUkwgKENlcnRpZmljYXRlTGlzdCBzdHJ1Y3R1cmUgZGVzY3JpYmVkIGluIFJGQyAzMjgwKQorICAgICAqIHByb3ZpZGVkIHZpYSBhcnJheSBvZiBieXRlcy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGRlY29kaW5nIGVycm9ycyBvY2N1ci4KKyAgICAgKi8KKyAgICBwdWJsaWMgWDUwOUNSTEltcGwoYnl0ZVtdIGVuY29kaW5nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKChDZXJ0aWZpY2F0ZUxpc3QpIENlcnRpZmljYXRlTGlzdC5BU04xLmRlY29kZShlbmNvZGluZykpOworICAgIH0KKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIC8vIC0tLS0tIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMIGFic3RyYWN0IG1ldGhvZCBpbXBsZW1lbnRhdGlvbnMgLS0tLQorICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNSTCNnZXRFbmNvZGVkKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgdGhyb3dzIENSTEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IGNybC5nZXRFbmNvZGVkKCk7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW2VuY29kaW5nLmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZW5jb2RpbmcsIDAsIHJlc3VsdCwgMCwgZW5jb2RpbmcubGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMI2dldFZlcnNpb24oKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFZlcnNpb24oKSB7CisgICAgICAgIHJldHVybiB0YnNDZXJ0TGlzdC5nZXRWZXJzaW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNSTCNnZXRJc3N1ZXJETigpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mbworICAgICAqLworICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0SXNzdWVyRE4oKSB7CisgICAgICAgIGlmIChpc3N1ZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgaXNzdWVyID0gdGJzQ2VydExpc3QuZ2V0SXNzdWVyKCkuZ2V0WDUwMFByaW5jaXBhbCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpc3N1ZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNSTCNnZXRJc3N1ZXJYNTAwUHJpbmNpcGFsKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIFg1MDBQcmluY2lwYWwgZ2V0SXNzdWVyWDUwMFByaW5jaXBhbCgpIHsKKyAgICAgICAgaWYgKGlzc3VlciA9PSBudWxsKSB7CisgICAgICAgICAgICBpc3N1ZXIgPSB0YnNDZXJ0TGlzdC5nZXRJc3N1ZXIoKS5nZXRYNTAwUHJpbmNpcGFsKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlzc3VlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMI2dldFRoaXNVcGRhdGUoKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0ZSBnZXRUaGlzVXBkYXRlKCkgeworICAgICAgICByZXR1cm4gdGJzQ2VydExpc3QuZ2V0VGhpc1VwZGF0ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDUkwjZ2V0TmV4dFVwZGF0ZSgpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mbworICAgICAqLworICAgIHB1YmxpYyBEYXRlIGdldE5leHRVcGRhdGUoKSB7CisgICAgICAgIHJldHVybiB0YnNDZXJ0TGlzdC5nZXROZXh0VXBkYXRlKCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBSZXRyaWV2ZXMgdGhlIGNybCBlbnRyaWVzIChUQlNDZXJ0TGlzdC5SZXZva2VkQ2VydGlmaWNhdGUgb2JqZWN0cykKKyAgICAgKiBmcm9tIHRoZSBUQlNDZXJ0TGlzdCBzdHJ1Y3R1cmUgYW5kIGNvbnZlcnRzIHRoZW0gdG8gdGhlCisgICAgICogWDUwOUNSTEVudHJ5SW1wbCBvYmplY3RzCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJldHJpZXZlRW50cmllcygpIHsKKyAgICAgICAgZW50cmllc1JldHJpZXZlZCA9IHRydWU7CisgICAgICAgIExpc3QgcmNlcnRzID0gdGJzQ2VydExpc3QuZ2V0UmV2b2tlZENlcnRpZmljYXRlcygpOworICAgICAgICBpZiAocmNlcnRzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBlbnRyaWVzU2l6ZSA9IHJjZXJ0cy5zaXplKCk7CisgICAgICAgIGVudHJpZXMgPSBuZXcgQXJyYXlMaXN0KGVudHJpZXNTaXplKTsKKyAgICAgICAgLy8gbnVsbCBtZWFucyB0aGF0IHJldm9rZWQgY2VydGlmaWNhdGUgaXNzdWVyIGlzIHRoZSBzYW1lIGFzIENSTCBpc3N1ZXIKKyAgICAgICAgWDUwMFByaW5jaXBhbCByY2VydElzc3VlciA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGk9MDsgaTxlbnRyaWVzU2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBUQlNDZXJ0TGlzdC5SZXZva2VkQ2VydGlmaWNhdGUgcmNlcnQgPQorICAgICAgICAgICAgICAgIChUQlNDZXJ0TGlzdC5SZXZva2VkQ2VydGlmaWNhdGUpIHJjZXJ0cy5nZXQoaSk7CisgICAgICAgICAgICBYNTAwUHJpbmNpcGFsIGlzcyA9IHJjZXJ0LmdldElzc3VlcigpOworICAgICAgICAgICAgaWYgKGlzcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgLy8gY2VydGlmaWNhdGUgaXNzdWVyIGRpZmZlcnMgZnJvbSBDUkwgaXNzdWVyCisgICAgICAgICAgICAgICAgLy8gYW5kIENSTCBpcyBpbmRpcmVjdC4KKyAgICAgICAgICAgICAgICByY2VydElzc3VlciA9IGlzczsKKyAgICAgICAgICAgICAgICBpc0luZGlyZWN0Q1JMID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAvLyByZW1lbWJlciBob3cgbWFueSBsZWFkaW5nIHJldm9rZWQgY2VydGlmaWNhdGVzIGluIHRoZQorICAgICAgICAgICAgICAgIC8vIGxpc3QgYXJlIGlzc3VlZCBieSB0aGUgc2FtZSBpc3N1ZXIgYXMgaXNzdWVyIG9mIENSTAorICAgICAgICAgICAgICAgIC8vICh0aGVzZSBjZXJ0aWZpY2F0ZXMgYXJlIGZpcnN0IGluIHRoZSBsaXN0KQorICAgICAgICAgICAgICAgIG5vbkluZGlyZWN0RW50cmllc1NpemUgPSBpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZW50cmllcy5hZGQobmV3IFg1MDlDUkxFbnRyeUltcGwocmNlcnQsIHJjZXJ0SXNzdWVyKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2hlcyBmb3IgY2VydGlmaWNhdGUgaW4gQ1JMLgorICAgICAqIFRoaXMgbWV0aG9kIHN1cHBvcnRzIGluZGlyZWN0IENSTHM6IGlmIENSTCBpcyBpbmRpcmVjdCBtZXRob2QgdGFrZXMKKyAgICAgKiBpbnRvIGFjY291bnQgc2VyaWFsIG51bWJlciBhbmQgaXNzdWVyIG9mIHRoZSBjZXJ0aWZpY2F0ZSwKKyAgICAgKiBpZiBDUkwgaXNzdWVkIGJ5IENBIChpLmUuIGl0IGlzIG5vdCBpbmRpcmVjdCkgc2VhcmNoIGlzIGRvbmUgb25seQorICAgICAqIGJ5IHNlcmlhbCBudW1iZXIgb2YgdGhlIHNwZWNpZmllZCBjZXJ0aWZpY2F0ZS4KKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMI2dldFJldm9rZWRDZXJ0aWZpY2F0ZShYNTA5Q2VydGlmaWNhdGUpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mbworICAgICAqLworICAgIHB1YmxpYyBYNTA5Q1JMRW50cnkgZ2V0UmV2b2tlZENlcnRpZmljYXRlKFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0aWZpY2F0ZSkgeworICAgICAgICBpZiAoY2VydGlmaWNhdGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFlbnRyaWVzUmV0cmlldmVkKSB7CisgICAgICAgICAgICByZXRyaWV2ZUVudHJpZXMoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZW50cmllcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBCaWdJbnRlZ2VyIHNlcmlhbE4gPSBjZXJ0aWZpY2F0ZS5nZXRTZXJpYWxOdW1iZXIoKTsKKyAgICAgICAgaWYgKGlzSW5kaXJlY3RDUkwpIHsKKyAgICAgICAgICAgIC8vIHNlYXJjaCBpbiBpbmRpcmVjdCBjcmwKKyAgICAgICAgICAgIFg1MDBQcmluY2lwYWwgY2VydElzc3VlciA9IGNlcnRpZmljYXRlLmdldElzc3Vlclg1MDBQcmluY2lwYWwoKTsKKyAgICAgICAgICAgIGlmIChjZXJ0SXNzdWVyLmVxdWFscyhnZXRJc3N1ZXJYNTAwUHJpbmNpcGFsKCkpKSB7CisgICAgICAgICAgICAgICAgLy8gY2VydGlmaWNhdGUgaXNzdWVyIGlzIENSTCBpc3N1ZXIKKyAgICAgICAgICAgICAgICBjZXJ0SXNzdWVyID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxlbnRyaWVzU2l6ZTsgaSsrKSB7CisgICAgICAgICAgICAgICAgWDUwOUNSTEVudHJ5IGVudHJ5ID0gKFg1MDlDUkxFbnRyeSkgZW50cmllcy5nZXQoaSk7CisgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhlIHNlcmlhbCBudW1iZXIgb2YgcmV2b2tlZCBjZXJ0aWZpY2F0ZQorICAgICAgICAgICAgICAgIGlmIChzZXJpYWxOLmVxdWFscyhlbnRyeS5nZXRTZXJpYWxOdW1iZXIoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gcmV2b2tlZCBjZXJ0aWZpY2F0ZSBpc3N1ZXIKKyAgICAgICAgICAgICAgICAgICAgWDUwMFByaW5jaXBhbCBpc3MgPSBlbnRyeS5nZXRDZXJ0aWZpY2F0ZUlzc3VlcigpOworICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGUgaXNzdWVyIG9mIHJldm9rZWQgY2VydGlmaWNhdGUKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNlcnRJc3N1ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2VydGlmaWNhdGUgaXNzdWVyIGlzIG5vdCBhIENSTCBpc3N1ZXIsIHNvCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBpc3N1ZXJzIGZvciBlcXVhbGl0eQorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNlcnRJc3N1ZXIuZXF1YWxzKGlzcykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW50cnk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJvdGggY2VydGlmaWNhdGVzIHdhcyBpc3N1ZWQgYnkgQ1JMIGlzc3VlcgorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVudHJ5OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gc2VhcmNoIGluIENBJ3MgKG5vbiBpbmRpcmVjdCkgY3JsOiBqdXN0IGxvb2sgdXAgdGhlIHNlcmlhbCBudW1iZXIKKyAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxlbnRyaWVzU2l6ZTsgaSsrKSB7CisgICAgICAgICAgICAgICAgWDUwOUNSTEVudHJ5IGVudHJ5ID0gKFg1MDlDUkxFbnRyeSkgZW50cmllcy5nZXQoaSk7CisgICAgICAgICAgICAgICAgaWYgKHNlcmlhbE4uZXF1YWxzKGVudHJ5LmdldFNlcmlhbE51bWJlcigpKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW50cnk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1ldGhvZCBzZWFyY2hlcyBmb3IgQ1JMIGVudHJ5IHdpdGggc3BlY2lmaWVkIHNlcmlhbCBudW1iZXIuCisgICAgICogVGhlIG1ldGhvZCB3aWxsIHNlYXJjaCBvbmx5IGNlcnRpZmljYXRlIGlzc3VlZCBieSBDUkwncyBpc3N1ZXIuCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNSTCNnZXRSZXZva2VkQ2VydGlmaWNhdGUoQmlnSW50ZWdlcikKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIFg1MDlDUkxFbnRyeSBnZXRSZXZva2VkQ2VydGlmaWNhdGUoQmlnSW50ZWdlciBzZXJpYWxOdW1iZXIpIHsKKyAgICAgICAgaWYgKCFlbnRyaWVzUmV0cmlldmVkKSB7CisgICAgICAgICAgICByZXRyaWV2ZUVudHJpZXMoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZW50cmllcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpPTA7IGk8bm9uSW5kaXJlY3RFbnRyaWVzU2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBYNTA5Q1JMRW50cnkgZW50cnkgPSAoWDUwOUNSTEVudHJ5KSBlbnRyaWVzLmdldChpKTsKKyAgICAgICAgICAgIGlmIChzZXJpYWxOdW1iZXIuZXF1YWxzKGVudHJ5LmdldFNlcmlhbE51bWJlcigpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBlbnRyeTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMI2dldFJldm9rZWRDZXJ0aWZpY2F0ZXMoKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgU2V0PD8gZXh0ZW5kcyBYNTA5Q1JMRW50cnk+IGdldFJldm9rZWRDZXJ0aWZpY2F0ZXMoKSB7CisgICAgICAgIGlmICghZW50cmllc1JldHJpZXZlZCkgeworICAgICAgICAgICAgcmV0cmlldmVFbnRyaWVzKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVudHJpZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBIYXNoU2V0KGVudHJpZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDUkwjZ2V0VEJTQ2VydExpc3QoKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldFRCU0NlcnRMaXN0KCkgdGhyb3dzIENSTEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0YnNDZXJ0TGlzdEVuY29kaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIHRic0NlcnRMaXN0RW5jb2RpbmcgPSB0YnNDZXJ0TGlzdC5nZXRFbmNvZGVkKCk7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW3Ric0NlcnRMaXN0RW5jb2RpbmcubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0YnNDZXJ0TGlzdEVuY29kaW5nLCAwLAorICAgICAgICAgICAgICAgIHJlc3VsdCwgMCwgdGJzQ2VydExpc3RFbmNvZGluZy5sZW5ndGgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDUkwjZ2V0U2lnbmF0dXJlKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRTaWduYXR1cmUoKSB7CisgICAgICAgIGlmIChzaWduYXR1cmUgPT0gbnVsbCkgeworICAgICAgICAgICAgc2lnbmF0dXJlID0gY3JsLmdldFNpZ25hdHVyZVZhbHVlKCk7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW3NpZ25hdHVyZS5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHNpZ25hdHVyZSwgMCwgcmVzdWx0LCAwLCBzaWduYXR1cmUubGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMI2dldFNpZ0FsZ05hbWUoKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFNpZ0FsZ05hbWUoKSB7CisgICAgICAgIGlmIChzaWdBbGdPSUQgPT0gbnVsbCkgeworICAgICAgICAgICAgc2lnQWxnT0lEID0gdGJzQ2VydExpc3QuZ2V0U2lnbmF0dXJlKCkuZ2V0QWxnb3JpdGhtKCk7CisgICAgICAgICAgICBzaWdBbGdOYW1lID0gQWxnTmFtZU1hcHBlci5tYXAyQWxnTmFtZShzaWdBbGdPSUQpOworICAgICAgICAgICAgaWYgKHNpZ0FsZ05hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNpZ0FsZ05hbWUgPSBzaWdBbGdPSUQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNpZ0FsZ05hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNSTCNnZXRTaWdBbGdPSUQoKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFNpZ0FsZ09JRCgpIHsKKyAgICAgICAgaWYgKHNpZ0FsZ09JRCA9PSBudWxsKSB7CisgICAgICAgICAgICBzaWdBbGdPSUQgPSB0YnNDZXJ0TGlzdC5nZXRTaWduYXR1cmUoKS5nZXRBbGdvcml0aG0oKTsKKyAgICAgICAgICAgIHNpZ0FsZ05hbWUgPSBBbGdOYW1lTWFwcGVyLm1hcDJBbGdOYW1lKHNpZ0FsZ09JRCk7CisgICAgICAgICAgICBpZiAoc2lnQWxnTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2lnQWxnTmFtZSA9IHNpZ0FsZ09JRDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2lnQWxnT0lEOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDUkwjZ2V0U2lnQWxnUGFyYW1zKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRTaWdBbGdQYXJhbXMoKSB7CisgICAgICAgIGlmIChudWxsU2lnQWxnUGFyYW1zKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoc2lnQWxnUGFyYW1zID09IG51bGwpIHsKKyAgICAgICAgICAgIHNpZ0FsZ1BhcmFtcyA9IHRic0NlcnRMaXN0LmdldFNpZ25hdHVyZSgpLmdldFBhcmFtZXRlcnMoKTsKKyAgICAgICAgICAgIGlmIChzaWdBbGdQYXJhbXMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG51bGxTaWdBbGdQYXJhbXMgPSB0cnVlOworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBzaWdBbGdQYXJhbXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNSTCN2ZXJpZnkoUHVibGljS2V5IGtleSkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIHZvaWQgdmVyaWZ5KFB1YmxpY0tleSBrZXkpCisgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgQ1JMRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW52YWxpZEtleUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgU2lnbmF0dXJlIHNpZ25hdHVyZSA9IFNpZ25hdHVyZS5nZXRJbnN0YW5jZShnZXRTaWdBbGdOYW1lKCkpOworICAgICAgICBzaWduYXR1cmUuaW5pdFZlcmlmeShrZXkpOworICAgICAgICBieXRlW10gdGJzRW5jb2RpbmcgPSB0YnNDZXJ0TGlzdC5nZXRFbmNvZGVkKCk7CisgICAgICAgIHNpZ25hdHVyZS51cGRhdGUodGJzRW5jb2RpbmcsIDAsIHRic0VuY29kaW5nLmxlbmd0aCk7CisgICAgICAgIGlmICghc2lnbmF0dXJlLnZlcmlmeShjcmwuZ2V0U2lnbmF0dXJlVmFsdWUoKSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTaWduYXR1cmVFeGNlcHRpb24oIlNpZ25hdHVyZSB3YXMgbm90IHZlcmlmaWVkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMI3ZlcmlmeShQdWJsaWNLZXkga2V5LCBTdHJpbmcgc2lnUHJvdmlkZXIpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mbworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5LCBTdHJpbmcgc2lnUHJvdmlkZXIpCisgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgQ1JMRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW52YWxpZEtleUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgU2lnbmF0dXJlIHNpZ25hdHVyZSA9IFNpZ25hdHVyZS5nZXRJbnN0YW5jZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0U2lnQWxnTmFtZSgpLCBzaWdQcm92aWRlcik7CisgICAgICAgIHNpZ25hdHVyZS5pbml0VmVyaWZ5KGtleSk7CisgICAgICAgIGJ5dGVbXSB0YnNFbmNvZGluZyA9IHRic0NlcnRMaXN0LmdldEVuY29kZWQoKTsKKyAgICAgICAgc2lnbmF0dXJlLnVwZGF0ZSh0YnNFbmNvZGluZywgMCwgdGJzRW5jb2RpbmcubGVuZ3RoKTsKKyAgICAgICAgaWYgKCFzaWduYXR1cmUudmVyaWZ5KGNybC5nZXRTaWduYXR1cmVWYWx1ZSgpKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNpZ25hdHVyZUV4Y2VwdGlvbigiU2lnbmF0dXJlIHdhcyBub3QgdmVyaWZpZWQiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIC8vIC0tLS0tLSBqYXZhLnNlY3VyaXR5LmNlcnQuQ1JMIGFic3RyYWN0IG1ldGhvZCBpbXBsZW1lbnRhdGlvbnMgLS0tLS0tLQorICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuQ1JMI2lzUmV2b2tlZChDZXJ0aWZpY2F0ZSkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNSZXZva2VkKENlcnRpZmljYXRlIGNlcnQpIHsKKyAgICAgICAgaWYgKCEoY2VydCBpbnN0YW5jZW9mIFg1MDlDZXJ0aWZpY2F0ZSkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0UmV2b2tlZENlcnRpZmljYXRlKChYNTA5Q2VydGlmaWNhdGUpIGNlcnQpICE9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuQ1JMI3RvU3RyaW5nKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIGNybC50b1N0cmluZygpOworICAgIH0KKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIC8vIC0tLS0tLSBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUV4dGVuc2lvbiBtZXRob2QgaW1wbGVtZW50YXRpb25zIC0tLS0tLQorICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUV4dGVuc2lvbiNnZXROb25Dcml0aWNhbEV4dGVuc2lvbk9JRHMoKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgU2V0IGdldE5vbkNyaXRpY2FsRXh0ZW5zaW9uT0lEcygpIHsKKyAgICAgICAgaWYgKGV4dGVuc2lvbnMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGV4dGVuc2lvbnMuZ2V0Tm9uQ3JpdGljYWxFeHRlbnNpb25zKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUV4dGVuc2lvbiNnZXRDcml0aWNhbEV4dGVuc2lvbk9JRHMoKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgU2V0IGdldENyaXRpY2FsRXh0ZW5zaW9uT0lEcygpIHsKKyAgICAgICAgaWYgKGV4dGVuc2lvbnMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGV4dGVuc2lvbnMuZ2V0Q3JpdGljYWxFeHRlbnNpb25zKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUV4dGVuc2lvbiNnZXRFeHRlbnNpb25WYWx1ZShTdHJpbmcpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mbworICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RXh0ZW5zaW9uVmFsdWUoU3RyaW5nIG9pZCkgeworICAgICAgICBpZiAoZXh0ZW5zaW9ucyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBFeHRlbnNpb24gZXh0ID0gZXh0ZW5zaW9ucy5nZXRFeHRlbnNpb25CeU9JRChvaWQpOworICAgICAgICByZXR1cm4gKGV4dCA9PSBudWxsKSA/IG51bGwgOiBleHQuZ2V0UmF3RXh0blZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUV4dGVuc2lvbiNoYXNVbnN1cHBvcnRlZENyaXRpY2FsRXh0ZW5zaW9uKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzVW5zdXBwb3J0ZWRDcml0aWNhbEV4dGVuc2lvbigpIHsKKyAgICAgICAgaWYgKGV4dGVuc2lvbnMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBleHRlbnNpb25zLmhhc1Vuc3VwcG9ydGVkQ3JpdGljYWwoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Byb3ZpZGVyL2NlcnQvWDUwOUNlcnRGYWN0b3J5SW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jZXJ0L1g1MDlDZXJ0RmFjdG9yeUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MjA3MDAyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jZXJ0L1g1MDlDZXJ0RmFjdG9yeUltcGwuamF2YQpAQCAtMCwwICsxLDg1NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wcm92aWRlci5jZXJ0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldHM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNSTDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ1JMRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3RvcnlTcGk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDUkw7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgbGliY29yZS5pby5CYXNlNjQ7CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQmVySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnBrY3M3LkNvbnRlbnRJbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wa2NzNy5TaWduZWREYXRhOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LkNlcnRpZmljYXRlTGlzdDsKKworLyoqCisgKiBYNTA5IENlcnRpZmljYXRlIEZhY3RvcnkgU2VydmljZSBQcm92aWRlciBJbnRlcmZhY2UgSW1wbGVtZW50YXRpb24uCisgKiBJdCBzdXBwb3J0cyBDUkxzIGFuZCBDZXJ0aWZpY2F0ZXMgaW4gKFBFTSkgQVNOLjEgREVSIGVuY29kZWQgZm9ybSwKKyAqIGFuZCBDZXJ0aWZpY2F0aW9uIFBhdGhzIGluIFBraVBhdGggYW5kIFBLQ1M3IGZvcm1hdHMuCisgKiBGb3IgQ2VydGlmaWNhdGVzIGFuZCBDUkxzIGZhY3RvcnkgbWFpbnRhaW5zIHRoZSBjYWNoaW5nCisgKiBtZWNoYW5pc21zIGFsbG93aW5nIHRvIHNwZWVkIHVwIHJlcGVhdGVkIENlcnRpZmljYXRlL0NSTAorICogZ2VuZXJhdGlvbi4KKyAqIEBzZWUgQ2FjaGUKKyAqLworcHVibGljIGNsYXNzIFg1MDlDZXJ0RmFjdG9yeUltcGwgZXh0ZW5kcyBDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkgeworCisgICAgLy8gbnVtYmVyIG9mIGxlYWRpbmcvdHJhaWxpbmcgYnl0ZXMgdXNlZCBmb3IgY2VydCBoYXNoIGNvbXB1dGF0aW9uCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENFUlRfQ0FDSEVfU0VFRF9MRU5HVEggPSAyODsKKyAgICAvLyBjZXJ0aWZpY2F0ZSBjYWNoZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENhY2hlIENFUlRfQ0FDSEUgPSBuZXcgQ2FjaGUoQ0VSVF9DQUNIRV9TRUVEX0xFTkdUSCk7CisgICAgLy8gbnVtYmVyIG9mIGxlYWRpbmcvdHJhaWxpbmcgYnl0ZXMgdXNlZCBmb3IgY3JsIGhhc2ggY29tcHV0YXRpb24KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ1JMX0NBQ0hFX1NFRURfTEVOR1RIID0gMjQ7CisgICAgLy8gY3JsIGNhY2hlCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ2FjaGUgQ1JMX0NBQ0hFID0gbmV3IENhY2hlKENSTF9DQUNIRV9TRUVEX0xFTkdUSCk7CisKKyAgICAvKioKKyAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLgorICAgICAqIENyZWF0ZXMgdGhlIGluc3RhbmNlIG9mIENlcnRpZmljYXRlIEZhY3RvcnkgU1BJIHJlYWR5IGZvciB1c2UuCisgICAgICovCisgICAgcHVibGljIFg1MDlDZXJ0RmFjdG9yeUltcGwoKSB7IH0KKworICAgIC8qKgorICAgICAqIEdlbmVyYXRlcyB0aGUgWC41MDkgY2VydGlmaWNhdGUgZnJvbSB0aGUgZGF0YSBpbiB0aGUgc3RyZWFtLgorICAgICAqIFRoZSBkYXRhIGluIHRoZSBzdHJlYW0gY2FuIGJlIGVpdGhlciBpbiBBU04uMSBERVIgZW5jb2RlZCBYLjUwOQorICAgICAqIGNlcnRpZmljYXRlLCBvciBQRU0gKEJhc2U2NCBlbmNvZGluZyBib3VuZGVkIGJ5CisgICAgICogPGNvZGU+Ii0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLSI8L2NvZGU+IGF0IHRoZSBiZWdpbm5pbmcgYW5kCisgICAgICogPGNvZGU+Ii0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0iPC9jb2RlPiBhdCB0aGUgZW5kKSByZXByZXNlbnRhdGlvbgorICAgICAqIG9mIHRoZSBmb3JtZXIgZW5jb2RlZCBmb3JtLgorICAgICAqCisgICAgICogQmVmb3JlIHRoZSBnZW5lcmF0aW9uIHRoZSBlbmNvZGVkIGZvcm0gaXMgbG9va2VkIHVwIGluCisgICAgICogdGhlIGNhY2hlLiBJZiB0aGUgY2FjaGUgY29udGFpbnMgdGhlIGNlcnRpZmljYXRlIHdpdGggcmVxdWVzdGVkIGVuY29kZWQKKyAgICAgKiBmb3JtIGl0IGlzIHJldHVybmVkIGZyb20gaXQsIG90aGVyd2lzZSBpdCBpcyBnZW5lcmF0ZWQgYnkgQVNOLjEKKyAgICAgKiBkZWNvZGVyLgorICAgICAqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5U3BpI2VuZ2luZUdlbmVyYXRlQ2VydGlmaWNhdGUoSW5wdXRTdHJlYW0pCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mbworICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZSBlbmdpbmVHZW5lcmF0ZUNlcnRpZmljYXRlKElucHV0U3RyZWFtIGluU3RyZWFtKQorICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluU3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigiaW5TdHJlYW0gPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoIWluU3RyZWFtLm1hcmtTdXBwb3J0ZWQoKSkgeworICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgbWFyayBzdXBwb3J0aW5nIHdyYXBwZXIKKyAgICAgICAgICAgICAgICBpblN0cmVhbSA9IG5ldyBSZXN0b3JpbmdJbnB1dFN0cmVhbShpblN0cmVhbSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBtYXJrIGlzIG5lZWRlZCB0byByZWNvZ25pemUgdGhlIGZvcm1hdCBvZiB0aGUgcHJvdmlkZWQgZW5jb2RpbmcKKyAgICAgICAgICAgIC8vIChBU04uMSBvciBQRU0pCisgICAgICAgICAgICBpblN0cmVhbS5tYXJrKDEpOworICAgICAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgcHJvdmlkZWQgY2VydGlmaWNhdGUgaXMgaW4gUEVNIGVuY29kZWQgZm9ybQorICAgICAgICAgICAgaWYgKGluU3RyZWFtLnJlYWQoKSA9PSAnLScpIHsKKyAgICAgICAgICAgICAgICAvLyBkZWNvZGUgUEVNLCByZXRyaWV2ZSBDUkwKKyAgICAgICAgICAgICAgICByZXR1cm4gZ2V0Q2VydGlmaWNhdGUoZGVjb2RlUEVNKGluU3RyZWFtLCBDRVJUX0JPVU5EX1NVRkZJWCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpblN0cmVhbS5yZXNldCgpOworICAgICAgICAgICAgICAgIC8vIHJldHJpZXZlIENSTAorICAgICAgICAgICAgICAgIHJldHVybiBnZXRDZXJ0aWZpY2F0ZShpblN0cmVhbSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdlbmVyYXRlcyB0aGUgY29sbGVjdGlvbiBvZiB0aGUgY2VydGlmaWNhdGVzIG9uIHRoZSBiYXNlIG9mIHByb3ZpZGVkCisgICAgICogdmlhIGlucHV0IHN0cmVhbSBlbmNvZGluZ3MuCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5U3BpI2VuZ2luZUdlbmVyYXRlQ2VydGlmaWNhdGVzKElucHV0U3RyZWFtKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sbGVjdGlvbjw/IGV4dGVuZHMgQ2VydGlmaWNhdGU+CisgICAgICAgICAgICBlbmdpbmVHZW5lcmF0ZUNlcnRpZmljYXRlcyhJbnB1dFN0cmVhbSBpblN0cmVhbSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBpZiAoaW5TdHJlYW0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKCJpblN0cmVhbSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgQXJyYXlMaXN0PENlcnRpZmljYXRlPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PENlcnRpZmljYXRlPigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKCFpblN0cmVhbS5tYXJrU3VwcG9ydGVkKCkpIHsKKyAgICAgICAgICAgICAgICAvLyBjcmVhdGUgdGhlIG1hcmsgc3VwcG9ydGluZyB3cmFwcGVyCisgICAgICAgICAgICAgICAgaW5TdHJlYW0gPSBuZXcgUmVzdG9yaW5nSW5wdXRTdHJlYW0oaW5TdHJlYW0pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gaWYgaXQgaXMgUEVNIGVuY29kZWQgZm9ybSB0aGlzIGFycmF5IHdpbGwgY29udGFpbiB0aGUgZW5jb2RpbmcKKyAgICAgICAgICAgIC8vIHNvICgoaXQgaXMgUEVNKSA8LT4gKGVuY29kaW5nICE9IG51bGwpKQorICAgICAgICAgICAgYnl0ZVtdIGVuY29kaW5nID0gbnVsbDsKKyAgICAgICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgYnkgU0VRVUVOQ0UgQVNOLjEgdGFnLCB1c2VkIGZvcgorICAgICAgICAgICAgLy8gcmVjb2duaXppbmcgdGhlIGRhdGEgZm9ybWF0CisgICAgICAgICAgICAvLyAoaXMgaXQgUEtDUzcgQ29udGVudEluZm8gc3RydWN0dXJlLCBYLjUwOSBDZXJ0aWZpY2F0ZSwgb3IKKyAgICAgICAgICAgIC8vIHVuc3VwcG9ydGVkIGVuY29kaW5nKQorICAgICAgICAgICAgaW50IHNlY29uZF9hc24xX3RhZyA9IC0xOworICAgICAgICAgICAgaW5TdHJlYW0ubWFyaygxKTsKKyAgICAgICAgICAgIGludCBjaDsKKyAgICAgICAgICAgIHdoaWxlICgoY2ggPSBpblN0cmVhbS5yZWFkKCkpICE9IC0xKSB7CisgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgaXQgaXMgUEVNIGVuY29kZWQgZm9ybQorICAgICAgICAgICAgICAgIGlmIChjaCA9PSAnLScpIHsgLy8gYmVnaW5uaW5nIG9mIFBFTSBlbmNvZGluZyAoJy0nIGNoYXIpCisgICAgICAgICAgICAgICAgICAgIC8vIGRlY29kZSBQRU0gY2h1bmsgYW5kIHN0b3JlIGl0cyBjb250ZW50IChBU04uMSBlbmNvZGluZykKKyAgICAgICAgICAgICAgICAgICAgZW5jb2RpbmcgPSBkZWNvZGVQRU0oaW5TdHJlYW0sIEZSRUVfQk9VTkRfU1VGRklYKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09IDB4MzApIHsgLy8gYmVnaW5uaW5nIG9mIEFTTi4xIHNlcXVlbmNlICgweDMwKQorICAgICAgICAgICAgICAgICAgICBlbmNvZGluZyA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgIGluU3RyZWFtLnJlc2V0KCk7CisgICAgICAgICAgICAgICAgICAgIC8vIHByZXBhcmUgZm9yIGRhdGEgZm9ybWF0IGRldGVybWluYXRpb24KKyAgICAgICAgICAgICAgICAgICAgaW5TdHJlYW0ubWFyayhDRVJUX0NBQ0hFX1NFRURfTEVOR1RIKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyB1bnN1cHBvcnRlZCBkYXRhCisgICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuc2l6ZSgpID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigiVW5zdXBwb3J0ZWQgZW5jb2RpbmciKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGl0IGNhbiBiZSB0cmFpbGluZyB1c2VyIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBzbyBrZWVwIGl0IGluIHRoZSBzdHJlYW0KKyAgICAgICAgICAgICAgICAgICAgICAgIGluU3RyZWFtLnJlc2V0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIENoZWNrIHRoZSBkYXRhIGZvcm1hdAorICAgICAgICAgICAgICAgIEJlcklucHV0U3RyZWFtIGluID0gKGVuY29kaW5nID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXcgQmVySW5wdXRTdHJlYW0oaW5TdHJlYW0pCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBuZXcgQmVySW5wdXRTdHJlYW0oZW5jb2RpbmcpOworICAgICAgICAgICAgICAgIC8vIHJlYWQgdGhlIG5leHQgQVNOLjEgdGFnCisgICAgICAgICAgICAgICAgc2Vjb25kX2FzbjFfdGFnID0gaW4ubmV4dCgpOyAvLyBpblN0cmVhbSBwb3NpdGlvbiBjaGFuZ2VkCisgICAgICAgICAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8ga2VlcCB3aG9sZSBzdHJ1Y3R1cmUgaW4gdGhlIHN0cmVhbQorICAgICAgICAgICAgICAgICAgICBpblN0cmVhbS5yZXNldCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBpdCBpcyBhIFRCU0NlcnRpZmljYXRlIHN0cnVjdHVyZQorICAgICAgICAgICAgICAgIGlmIChzZWNvbmRfYXNuMV90YWcgIT0gQVNOMUNvbnN0YW50cy5UQUdfQ19TRVFVRU5DRSkgeworICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LnNpemUoKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGVyZSB3ZXJlIG5vdCByZWFkIFguNTA5IENlcnRpZmljYXRlcywgc28KKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJyZWFrIHRoZSBjeWNsZSBhbmQgY2hlY2sKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdoZXRoZXIgaXQgaXMgUEtDUzcgc3RydWN0dXJlCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGl0IGNhbiBiZSB0cmFpbGluZyB1c2VyIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBzbyByZXR1cm4gd2hhdCB3ZSBhbHJlYWR5IHJlYWQKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChnZXRDZXJ0aWZpY2F0ZShpblN0cmVhbSkpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChnZXRDZXJ0aWZpY2F0ZShlbmNvZGluZykpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIG1hcmsgZm9yIHRoZSBuZXh0IGl0ZXJhdGlvbgorICAgICAgICAgICAgICAgIGluU3RyZWFtLm1hcmsoMSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocmVzdWx0LnNpemUoKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgLy8gc29tZSBDZXJ0aWZpY2F0ZXMgaGF2ZSBiZWVuIHJlYWQKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PSAtMSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigiVGhlcmUgaXMgbm8gZGF0YSBpbiB0aGUgc3RyZWFtIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBlbHNlOiBjaGVjayBpZiBpdCBpcyBQS0NTNworICAgICAgICAgICAgaWYgKHNlY29uZF9hc24xX3RhZyA9PSBBU04xQ29uc3RhbnRzLlRBR19PSUQpIHsKKyAgICAgICAgICAgICAgICAvLyBpdCBpcyBQS0NTNyBDb250ZW50SW5mbyBzdHJ1Y3R1cmUsIHNvIGRlY29kZSBpdAorICAgICAgICAgICAgICAgIENvbnRlbnRJbmZvIGluZm8gPSAoQ29udGVudEluZm8pCisgICAgICAgICAgICAgICAgICAgICgoZW5jb2RpbmcgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgID8gQ29udGVudEluZm8uQVNOMS5kZWNvZGUoZW5jb2RpbmcpCisgICAgICAgICAgICAgICAgICAgICAgICA6IENvbnRlbnRJbmZvLkFTTjEuZGVjb2RlKGluU3RyZWFtKSk7CisgICAgICAgICAgICAgICAgLy8gcmV0cmlldmUgU2lnbmVkRGF0YQorICAgICAgICAgICAgICAgIFNpZ25lZERhdGEgZGF0YSA9IGluZm8uZ2V0U2lnbmVkRGF0YSgpOworICAgICAgICAgICAgICAgIGlmIChkYXRhID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKCJJbnZhbGlkIFBLQ1M3IGRhdGEgcHJvdmlkZWQiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgTGlzdDxvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5DZXJ0aWZpY2F0ZT4gY2VydHMgPSBkYXRhLmdldENlcnRpZmljYXRlcygpOworICAgICAgICAgICAgICAgIGlmIChjZXJ0cyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAob3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuQ2VydGlmaWNhdGUgY2VydCA6IGNlcnRzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYWRkKG5ldyBYNTA5Q2VydEltcGwoY2VydCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBlbHNlOiBVbmtub3duIGRhdGEgZm9ybWF0CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oIlVuc3VwcG9ydGVkIGVuY29kaW5nIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRmFjdG9yeVNwaSNlbmdpbmVHZW5lcmF0ZUNSTChJbnB1dFN0cmVhbSkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIENSTCBlbmdpbmVHZW5lcmF0ZUNSTChJbnB1dFN0cmVhbSBpblN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBDUkxFeGNlcHRpb24geworICAgICAgICBpZiAoaW5TdHJlYW0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENSTEV4Y2VwdGlvbigiaW5TdHJlYW0gPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoIWluU3RyZWFtLm1hcmtTdXBwb3J0ZWQoKSkgeworICAgICAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgbWFyayBzdXBwb3J0aW5nIHdyYXBwZXIKKyAgICAgICAgICAgICAgICAvLyBNYXJrIGlzIG5lZWRlZCB0byByZWNvZ25pemUgdGhlIGZvcm1hdAorICAgICAgICAgICAgICAgIC8vIG9mIHByb3ZpZGVkIGVuY29kaW5nIGZvcm0gKEFTTi4xIG9yIFBFTSkKKyAgICAgICAgICAgICAgICBpblN0cmVhbSA9IG5ldyBSZXN0b3JpbmdJbnB1dFN0cmVhbShpblN0cmVhbSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpblN0cmVhbS5tYXJrKDEpOworICAgICAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgcHJvdmlkZWQgY3JsIGlzIGluIFBFTSBlbmNvZGVkIGZvcm0KKyAgICAgICAgICAgIGlmIChpblN0cmVhbS5yZWFkKCkgPT0gJy0nKSB7CisgICAgICAgICAgICAgICAgLy8gZGVjb2RlIFBFTSwgcmV0cmlldmUgQ1JMCisgICAgICAgICAgICAgICAgcmV0dXJuIGdldENSTChkZWNvZGVQRU0oaW5TdHJlYW0sIEZSRUVfQk9VTkRfU1VGRklYKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGluU3RyZWFtLnJlc2V0KCk7CisgICAgICAgICAgICAgICAgLy8gcmV0cmlldmUgQ1JMCisgICAgICAgICAgICAgICAgcmV0dXJuIGdldENSTChpblN0cmVhbSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDUkxFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3RvcnlTcGkjZW5naW5lR2VuZXJhdGVDUkxzKElucHV0U3RyZWFtKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sbGVjdGlvbjw/IGV4dGVuZHMgQ1JMPiBlbmdpbmVHZW5lcmF0ZUNSTHMoSW5wdXRTdHJlYW0gaW5TdHJlYW0pCisgICAgICAgICAgICB0aHJvd3MgQ1JMRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluU3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDUkxFeGNlcHRpb24oImluU3RyZWFtID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBBcnJheUxpc3Q8Q1JMPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PENSTD4oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICghaW5TdHJlYW0ubWFya1N1cHBvcnRlZCgpKSB7CisgICAgICAgICAgICAgICAgaW5TdHJlYW0gPSBuZXcgUmVzdG9yaW5nSW5wdXRTdHJlYW0oaW5TdHJlYW0pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gaWYgaXQgaXMgUEVNIGVuY29kZWQgZm9ybSB0aGlzIGFycmF5IHdpbGwgY29udGFpbiB0aGUgZW5jb2RpbmcKKyAgICAgICAgICAgIC8vIHNvICgoaXQgaXMgUEVNKSA8LT4gKGVuY29kaW5nICE9IG51bGwpKQorICAgICAgICAgICAgYnl0ZVtdIGVuY29kaW5nID0gbnVsbDsKKyAgICAgICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgYnkgU0VRVUVOQ0UgQVNOLjEgdGFnLCB1c2VkIGZvcgorICAgICAgICAgICAgLy8gcmVjb2duaXppbmcgdGhlIGRhdGEgZm9ybWF0CisgICAgICAgICAgICAvLyAoaXMgaXQgUEtDUzcgQ29udGVudEluZm8gc3RydWN0dXJlLCBYLjUwOSBDUkwsIG9yCisgICAgICAgICAgICAvLyB1bnN1cHBvcnRlZCBlbmNvZGluZykKKyAgICAgICAgICAgIGludCBzZWNvbmRfYXNuMV90YWcgPSAtMTsKKyAgICAgICAgICAgIGluU3RyZWFtLm1hcmsoMSk7CisgICAgICAgICAgICBpbnQgY2g7CisgICAgICAgICAgICB3aGlsZSAoKGNoID0gaW5TdHJlYW0ucmVhZCgpKSAhPSAtMSkgeworICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIGl0IGlzIFBFTSBlbmNvZGVkIGZvcm0KKyAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJy0nKSB7IC8vIGJlZ2lubmluZyBvZiBQRU0gZW5jb2RpbmcgKCctJyBjaGFyKQorICAgICAgICAgICAgICAgICAgICAvLyBkZWNvZGUgUEVNIGNodW5rIGFuZCBzdG9yZSBpdHMgY29udGVudCAoQVNOLjEgZW5jb2RpbmcpCisgICAgICAgICAgICAgICAgICAgIGVuY29kaW5nID0gZGVjb2RlUEVNKGluU3RyZWFtLCBGUkVFX0JPVU5EX1NVRkZJWCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PSAweDMwKSB7IC8vIGJlZ2lubmluZyBvZiBBU04uMSBzZXF1ZW5jZSAoMHgzMCkKKyAgICAgICAgICAgICAgICAgICAgZW5jb2RpbmcgPSBudWxsOworICAgICAgICAgICAgICAgICAgICBpblN0cmVhbS5yZXNldCgpOworICAgICAgICAgICAgICAgICAgICAvLyBwcmVwYXJlIGZvciBkYXRhIGZvcm1hdCBkZXRlcm1pbmF0aW9uCisgICAgICAgICAgICAgICAgICAgIGluU3RyZWFtLm1hcmsoQ1JMX0NBQ0hFX1NFRURfTEVOR1RIKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyB1bnN1cHBvcnRlZCBkYXRhCisgICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuc2l6ZSgpID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDUkxFeGNlcHRpb24oIlVuc3VwcG9ydGVkIGVuY29kaW5nIik7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBpdCBjYW4gYmUgdHJhaWxpbmcgdXNlciBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgLy8gc28ga2VlcCBpdCBpbiB0aGUgc3RyZWFtCisgICAgICAgICAgICAgICAgICAgICAgICBpblN0cmVhbS5yZXNldCgpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBDaGVjayB0aGUgZGF0YSBmb3JtYXQKKyAgICAgICAgICAgICAgICBCZXJJbnB1dFN0cmVhbSBpbiA9IChlbmNvZGluZyA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3IEJlcklucHV0U3RyZWFtKGluU3RyZWFtKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbmV3IEJlcklucHV0U3RyZWFtKGVuY29kaW5nKTsKKyAgICAgICAgICAgICAgICAvLyByZWFkIHRoZSBuZXh0IEFTTi4xIHRhZworICAgICAgICAgICAgICAgIHNlY29uZF9hc24xX3RhZyA9IGluLm5leHQoKTsKKyAgICAgICAgICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAvLyBrZWVwIHdob2xlIHN0cnVjdHVyZSBpbiB0aGUgc3RyZWFtCisgICAgICAgICAgICAgICAgICAgIGluU3RyZWFtLnJlc2V0KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIGl0IGlzIGEgVEJTQ2VydExpc3Qgc3RydWN0dXJlCisgICAgICAgICAgICAgICAgaWYgKHNlY29uZF9hc24xX3RhZyAhPSBBU04xQ29uc3RhbnRzLlRBR19DX1NFUVVFTkNFKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuc2l6ZSgpID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZXJlIHdlcmUgbm90IHJlYWQgWC41MDkgQ1JMcywgc28KKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJyZWFrIHRoZSBjeWNsZSBhbmQgY2hlY2sKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdoZXRoZXIgaXQgaXMgUEtDUzcgc3RydWN0dXJlCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGl0IGNhbiBiZSB0cmFpbGluZyB1c2VyIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBzbyByZXR1cm4gd2hhdCB3ZSBhbHJlYWR5IHJlYWQKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChnZXRDUkwoaW5TdHJlYW0pKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQoZ2V0Q1JMKGVuY29kaW5nKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaW5TdHJlYW0ubWFyaygxKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChyZXN1bHQuc2l6ZSgpICE9IDApIHsKKyAgICAgICAgICAgICAgICAvLyB0aGUgc3RyZWFtIHdhcyByZWFkIG91dAorICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09IC0xKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENSTEV4Y2VwdGlvbigiVGhlcmUgaXMgbm8gZGF0YSBpbiB0aGUgc3RyZWFtIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBlbHNlOiBjaGVjayBpZiBpdCBpcyBQS0NTNworICAgICAgICAgICAgaWYgKHNlY29uZF9hc24xX3RhZyA9PSBBU04xQ29uc3RhbnRzLlRBR19PSUQpIHsKKyAgICAgICAgICAgICAgICAvLyBpdCBpcyBQS0NTNyBDb250ZW50SW5mbyBzdHJ1Y3R1cmUsIHNvIGRlY29kZSBpdAorICAgICAgICAgICAgICAgIENvbnRlbnRJbmZvIGluZm8gPSAoQ29udGVudEluZm8pCisgICAgICAgICAgICAgICAgICAgICgoZW5jb2RpbmcgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgID8gQ29udGVudEluZm8uQVNOMS5kZWNvZGUoZW5jb2RpbmcpCisgICAgICAgICAgICAgICAgICAgICAgICA6IENvbnRlbnRJbmZvLkFTTjEuZGVjb2RlKGluU3RyZWFtKSk7CisgICAgICAgICAgICAgICAgLy8gcmV0cmlldmUgU2lnbmVkRGF0YQorICAgICAgICAgICAgICAgIFNpZ25lZERhdGEgZGF0YSA9IGluZm8uZ2V0U2lnbmVkRGF0YSgpOworICAgICAgICAgICAgICAgIGlmIChkYXRhID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENSTEV4Y2VwdGlvbigiSW52YWxpZCBQS0NTNyBkYXRhIHByb3ZpZGVkIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIExpc3Q8Q2VydGlmaWNhdGVMaXN0PiBjcmxzID0gZGF0YS5nZXRDUkxzKCk7CisgICAgICAgICAgICAgICAgaWYgKGNybHMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBmb3IgKENlcnRpZmljYXRlTGlzdCBjcmwgOiBjcmxzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYWRkKG5ldyBYNTA5Q1JMSW1wbChjcmwpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gZWxzZTogVW5rbm93biBkYXRhIGZvcm1hdAorICAgICAgICAgICAgdGhyb3cgbmV3IENSTEV4Y2VwdGlvbigiVW5zdXBwb3J0ZWQgZW5jb2RpbmciKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENSTEV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRmFjdG9yeVNwaSNlbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKElucHV0U3RyZWFtKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydFBhdGggZW5naW5lR2VuZXJhdGVDZXJ0UGF0aChJbnB1dFN0cmVhbSBpblN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpblN0cmVhbSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oImluU3RyZWFtID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5naW5lR2VuZXJhdGVDZXJ0UGF0aChpblN0cmVhbSwgIlBraVBhdGgiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3RvcnlTcGkjZW5naW5lR2VuZXJhdGVDZXJ0UGF0aChJbnB1dFN0cmVhbSxTdHJpbmcpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mbworICAgICAqLworICAgIHB1YmxpYyBDZXJ0UGF0aCBlbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKAorICAgICAgICAgICAgSW5wdXRTdHJlYW0gaW5TdHJlYW0sIFN0cmluZyBlbmNvZGluZykgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluU3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigiaW5TdHJlYW0gPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmICghaW5TdHJlYW0ubWFya1N1cHBvcnRlZCgpKSB7CisgICAgICAgICAgICBpblN0cmVhbSA9IG5ldyBSZXN0b3JpbmdJbnB1dFN0cmVhbShpblN0cmVhbSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluU3RyZWFtLm1hcmsoMSk7CisgICAgICAgICAgICBpbnQgY2g7CisKKyAgICAgICAgICAgIC8vIGNoZWNrIGlmIGl0IGlzIFBFTSBlbmNvZGVkIGZvcm0KKyAgICAgICAgICAgIGlmICgoY2ggPSBpblN0cmVhbS5yZWFkKCkpID09ICctJykgeworICAgICAgICAgICAgICAgIC8vIGRlY29kZSBQRU0gY2h1bmsgaW50byBBU04uMSBmb3JtIGFuZCBkZWNvZGUgQ2VydFBhdGggb2JqZWN0CisgICAgICAgICAgICAgICAgcmV0dXJuIFg1MDlDZXJ0UGF0aEltcGwuZ2V0SW5zdGFuY2UoCisgICAgICAgICAgICAgICAgICAgICAgICBkZWNvZGVQRU0oaW5TdHJlYW0sIEZSRUVfQk9VTkRfU1VGRklYKSwgZW5jb2RpbmcpOworICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PSAweDMwKSB7IC8vIEFTTi4xIFNlcXVlbmNlCisgICAgICAgICAgICAgICAgaW5TdHJlYW0ucmVzZXQoKTsKKyAgICAgICAgICAgICAgICAvLyBkZWNvZGUgQVNOLjEgZm9ybQorICAgICAgICAgICAgICAgIHJldHVybiBYNTA5Q2VydFBhdGhJbXBsLmdldEluc3RhbmNlKGluU3RyZWFtLCBlbmNvZGluZyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigiVW5zdXBwb3J0ZWQgZW5jb2RpbmciKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5U3BpI2VuZ2luZUdlbmVyYXRlQ2VydFBhdGgoTGlzdCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIENlcnRQYXRoIGVuZ2luZUdlbmVyYXRlQ2VydFBhdGgoTGlzdCBjZXJ0aWZpY2F0ZXMpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3IFg1MDlDZXJ0UGF0aEltcGwoY2VydGlmaWNhdGVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3RvcnlTcGkjZW5naW5lR2V0Q2VydFBhdGhFbmNvZGluZ3MoKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3I8U3RyaW5nPiBlbmdpbmVHZXRDZXJ0UGF0aEVuY29kaW5ncygpIHsKKyAgICAgICAgcmV0dXJuIFg1MDlDZXJ0UGF0aEltcGwuZW5jb2RpbmdzLml0ZXJhdG9yKCk7CisgICAgfQorCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFN0YWZmIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gUEVNX0JFR0lOID0gIi0tLS0tQkVHSU4iLmdldEJ5dGVzKENoYXJzZXRzLlVURl84KTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gUEVNX0VORCA9ICItLS0tLUVORCIuZ2V0Qnl0ZXMoQ2hhcnNldHMuVVRGXzgpOworICAgIC8qKgorICAgICAqIENvZGUgZGVzY3JpYmluZyBmcmVlIGZvcm1hdCBmb3IgUEVNIGJvdW5kYXJ5IHN1ZmZpeDoKKyAgICAgKiAiXi0tLS0tQkVHSU4uKlxuIiAgICAgICAgIGF0IHRoZSBiZWdpbm5pbmcsIGFuZDxicj4KKyAgICAgKiAiXG4tLS0tLUVORC4qKEVPRnxcbikkIiAgIGF0IHRoZSBlbmQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIEZSRUVfQk9VTkRfU1VGRklYID0gbnVsbDsKKyAgICAvKioKKyAgICAgKiBDb2RlIGRlc2NyaWJpbmcgUEVNIGJvdW5kYXJ5IHN1ZmZpeCBmb3IgWC41MDkgY2VydGlmaWNhdGU6CisgICAgICogIl4tLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIgICBhdCB0aGUgYmVnaW5uaW5nLCBhbmQ8YnI+CisgICAgICogIlxuLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLSIgICBhdCB0aGUgZW5kLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBDRVJUX0JPVU5EX1NVRkZJWCA9ICIgQ0VSVElGSUNBVEUtLS0tLSIuZ2V0Qnl0ZXMoQ2hhcnNldHMuVVRGXzgpOworCisgICAgLyoqCisgICAgICogTWV0aG9kIHJldHJpZXZlcyB0aGUgUEVNIGVuY29kZWQgZGF0YSBmcm9tIHRoZSBzdHJlYW0KKyAgICAgKiBhbmQgcmV0dXJucyBpdHMgZGVjb2RlZCByZXByZXNlbnRhdGlvbi4KKyAgICAgKiBNZXRob2QgY2hlY2tzIGNvcnJlY3RuZXNzIG9mIFBFTSBib3VuZGFyaWVzLiBJdCBzdXBwb3NlcyB0aGF0CisgICAgICogdGhlIGZpcnN0ICctJyBvZiB0aGUgb3BlbmluZyBib3VuZGFyeSBoYXMgYWxyZWFkeSBiZWVuIHJlYWQgZnJvbQorICAgICAqIHRoZSBzdHJlYW0uIFNvIGZpcnN0IG9mIGFsbCBpdCBjaGVja3MgdGhhdCB0aGUgbGVhZGluZyBieXRlcworICAgICAqIGFyZSBlcXVhbCB0byAiLS0tLS1CRUdJTiIgYm91bmRhcnkgcHJlZml4LiBUaGFuIGlmIGJvdW5kYXJ5X3N1ZmZpeAorICAgICAqIGlzIG5vdCBudWxsLCBpdCBjaGVja3MgdGhhdCBuZXh0IGJ5dGVzIGVxdWFsIHRvIGJvdW5kYXJ5X3N1ZmZpeAorICAgICAqICsgbmV3IGxpbmUgY2hhcltzXSAoW0NSXUxGKS4KKyAgICAgKiBJZiBib3VuZGFyeV9zdWZmaXggcGFyYW1ldGVyIGlzIG51bGwsIG1ldGhvZCBzdXBwb3NlcyBmcmVlIHN1ZmZpeAorICAgICAqIGZvcm1hdCBhbmQgc2tpcHMgYW55IGJ5dGVzIHVudGlsIHRoZSBuZXcgbGluZS48YnI+CisgICAgICogQWZ0ZXIgdGhlIG9wZW5pbmcgYm91bmRhcnkgaGFzIGJlZW4gcmVhZCBhbmQgY2hlY2tlZCwgdGhlIG1ldGhvZAorICAgICAqIHJlYWQgQmFzZTY0IGVuY29kZWQgZGF0YSB1bnRpbCBjbG9zaW5nIFBFTSBib3VuZGFyeSBpcyBub3QgcmVhY2hlZC48YnI+CisgICAgICogVGhhbiBpdCBjaGVja3MgY2xvc2luZyBib3VuZGFyeSAtIGl0IHNob3VsZCBzdGFydCB3aXRoIG5ldyBsaW5lICsKKyAgICAgKiAiLS0tLS1FTkQiICsgYm91bmRhcnlfc3VmZml4LiBJZiBib3VuZGFyeV9zdWZmaXggaXMgbnVsbCwKKyAgICAgKiBhbnkgY2hhcmFjdGVycyBhcmUgc2tpcHBlZCB1bnRpbCB0aGUgbmV3IGxpbmUuPGJyPgorICAgICAqIEFmdGVyIHRoaXMgYW55IHRyYWlsaW5nIG5ldyBsaW5lIGNoYXJhY3RlcnMgYXJlIHNraXBwZWQgZnJvbSB0aGUgc3RyZWFtLAorICAgICAqIEJhc2U2NCBlbmNvZGluZyBpcyBkZWNvZGVkIGFuZCByZXR1cm5lZC4KKyAgICAgKiBAcGFyYW0gaW5TdHJlYW0gdGhlIHN0cmVhbSBjb250YWluaW5nIHRoZSBQRU0gZW5jb2RpbmcuCisgICAgICogQHBhcmFtIGJvdW5kYXJ5X3N1ZmZpeCB0aGUgc3VmZml4IG9mIGV4cGVjdGVkIFBFTSBtdWx0aXBhcnQKKyAgICAgKiBib3VuZGFyeSBkZWxpbWl0ZXIuPGJyPgorICAgICAqIElmIGl0IGlzIG51bGwsIHRoYXQgYW55IGNoYXJhY3RlciBzZXF1ZW5jZXMgYXJlIGFjY2VwdGVkLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgUEVNIGJvdW5kYXJ5IGRlbGltaXRlciBkb2VzIG5vdCBjb21wbHkKKyAgICAgKiB3aXRoIGV4cGVjdGVkIG9yIHNvbWUgSS9PIG9yIGRlY29kaW5nIHByb2JsZW1zIG9jY3VyLgorICAgICAqLworICAgIHByaXZhdGUgYnl0ZVtdIGRlY29kZVBFTShJbnB1dFN0cmVhbSBpblN0cmVhbSwgYnl0ZVtdIGJvdW5kYXJ5X3N1ZmZpeCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGNoOyAvLyB0aGUgY2hhciB0byBiZSByZWFkCisgICAgICAgIC8vIGNoZWNrIGFuZCBza2lwIG9wZW5pbmcgYm91bmRhcnkgZGVsaW1pdGVyCisgICAgICAgIC8vIChmaXJzdCAnLScgaXMgc3VwcG9zZWQgYXMgYWxyZWFkeSByZWFkKQorICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IFBFTV9CRUdJTi5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgaWYgKFBFTV9CRUdJTltpXSAhPSAoY2ggPSBpblN0cmVhbS5yZWFkKCkpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAiSW5jb3JyZWN0IFBFTSBlbmNvZGluZzogJy0tLS0tQkVHSU4iCisgICAgICAgICAgICAgICAgICAgICsgKChib3VuZGFyeV9zdWZmaXggPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgID8gIiIgOiBuZXcgU3RyaW5nKGJvdW5kYXJ5X3N1ZmZpeCkpCisgICAgICAgICAgICAgICAgICAgICsgIicgaXMgZXhwZWN0ZWQgYXMgb3BlbmluZyBkZWxpbWl0ZXIgYm91bmRhcnkuIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJvdW5kYXJ5X3N1ZmZpeCA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyByZWFkIChza2lwKSB0aGUgdHJhaWxpbmcgY2hhcmFjdGVycyBvZgorICAgICAgICAgICAgLy8gdGhlIGJlZ2lubmluZyBQRU0gYm91bmRhcnkgZGVsaW1pdGVyCisgICAgICAgICAgICB3aGlsZSAoKGNoID0gaW5TdHJlYW0ucmVhZCgpKSAhPSAnXG4nKSB7CisgICAgICAgICAgICAgICAgaWYgKGNoID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW5jb3JyZWN0IFBFTSBlbmNvZGluZzogRU9GIGJlZm9yZSBjb250ZW50Iik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGJvdW5kYXJ5X3N1ZmZpeC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChib3VuZGFyeV9zdWZmaXhbaV0gIT0gaW5TdHJlYW0ucmVhZCgpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW5jb3JyZWN0IFBFTSBlbmNvZGluZzogJy0tLS0tQkVHSU4iICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKGJvdW5kYXJ5X3N1ZmZpeCkgKyAiJyBpcyBleHBlY3RlZCBhcyBvcGVuaW5nIGRlbGltaXRlciBib3VuZGFyeS4iKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyByZWFkIG5ldyBsaW5lIGNoYXJhY3RlcnMKKyAgICAgICAgICAgIGlmICgoY2ggPSBpblN0cmVhbS5yZWFkKCkpID09ICdccicpIHsKKyAgICAgICAgICAgICAgICAvLyBDUiBoYXMgYmVlbiByZWFkLCBub3cgcmVhZCBMRiBjaGFyYWN0ZXIKKyAgICAgICAgICAgICAgICBjaCA9IGluU3RyZWFtLnJlYWQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjaCAhPSAnXG4nKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbmNvcnJlY3QgUEVNIGVuY29kaW5nOiBuZXdsaW5lIGV4cGVjdGVkIGFmdGVyICIgKworICAgICAgICAgICAgICAgICAgICAgICAgIm9wZW5pbmcgZGVsaW1pdGVyIGJvdW5kYXJ5Iik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaW50IHNpemUgPSAxMDI0OyAvLyB0aGUgc2l6ZSBvZiB0aGUgYnVmZmVyIGNvbnRhaW5pbmcgQmFzZTY0IGRhdGEKKyAgICAgICAgYnl0ZVtdIGJ1ZmYgPSBuZXcgYnl0ZVtzaXplXTsKKyAgICAgICAgaW50IGluZGV4ID0gMDsKKyAgICAgICAgLy8gcmVhZCBieXRlcyB3aGlsZSBlbmRpbmcgYm91bmRhcnkgZGVsaW1pdGVyIGlzIG5vdCByZWFjaGVkCisgICAgICAgIHdoaWxlICgoY2ggPSBpblN0cmVhbS5yZWFkKCkpICE9ICctJykgeworICAgICAgICAgICAgaWYgKGNoID09IC0xKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbmNvcnJlY3QgQmFzZTY0IGVuY29kaW5nOiBFT0Ygd2l0aG91dCBjbG9zaW5nIGRlbGltaXRlciIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnVmZltpbmRleCsrXSA9IChieXRlKSBjaDsKKyAgICAgICAgICAgIGlmIChpbmRleCA9PSBzaXplKSB7CisgICAgICAgICAgICAgICAgLy8gZW5sYXJnZSB0aGUgYnVmZmVyCisgICAgICAgICAgICAgICAgYnl0ZVtdIG5ld2J1ZmYgPSBuZXcgYnl0ZVtzaXplKzEwMjRdOworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZiwgMCwgbmV3YnVmZiwgMCwgc2l6ZSk7CisgICAgICAgICAgICAgICAgYnVmZiA9IG5ld2J1ZmY7CisgICAgICAgICAgICAgICAgc2l6ZSArPSAxMDI0OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChidWZmW2luZGV4LTFdICE9ICdcbicpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW5jb3JyZWN0IEJhc2U2NCBlbmNvZGluZzogbmV3bGluZSBleHBlY3RlZCBiZWZvcmUgIiArCisgICAgICAgICAgICAgICAgICAgICJjbG9zaW5nIGJvdW5kYXJ5IGRlbGltaXRlciIpOworICAgICAgICB9CisgICAgICAgIC8vIGNoZWNrIGFuZCBza2lwIGNsb3NpbmcgYm91bmRhcnkgZGVsaW1pdGVyIHByZWZpeAorICAgICAgICAvLyAoZmlyc3QgJy0nIHdhcyByZWFkKQorICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IFBFTV9FTkQubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIGlmIChQRU1fRU5EW2ldICE9IGluU3RyZWFtLnJlYWQoKSkgeworICAgICAgICAgICAgICAgIHRocm93IGJhZEVuZChib3VuZGFyeV9zdWZmaXgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChib3VuZGFyeV9zdWZmaXggPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gcmVhZCAoc2tpcCkgdGhlIHRyYWlsaW5nIGNoYXJhY3RlcnMgb2YKKyAgICAgICAgICAgIC8vIHRoZSBjbG9zaW5nIFBFTSBib3VuZGFyeSBkZWxpbWl0ZXIKKyAgICAgICAgICAgIHdoaWxlICgoKGNoID0gaW5TdHJlYW0ucmVhZCgpKSAhPSAtMSkgJiYgKGNoICE9ICdcbicpICYmIChjaCAhPSAnXHInKSkgeworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGJvdW5kYXJ5X3N1ZmZpeC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChib3VuZGFyeV9zdWZmaXhbaV0gIT0gaW5TdHJlYW0ucmVhZCgpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IGJhZEVuZChib3VuZGFyeV9zdWZmaXgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBza2lwIHRyYWlsaW5nIGxpbmUgYnJlYWtzCisgICAgICAgIGluU3RyZWFtLm1hcmsoMSk7CisgICAgICAgIHdoaWxlICgoKGNoID0gaW5TdHJlYW0ucmVhZCgpKSAhPSAtMSkgJiYgKGNoID09ICdcbicgfHwgY2ggPT0gJ1xyJykpIHsKKyAgICAgICAgICAgIGluU3RyZWFtLm1hcmsoMSk7CisgICAgICAgIH0KKyAgICAgICAgaW5TdHJlYW0ucmVzZXQoKTsKKyAgICAgICAgYnVmZiA9IEJhc2U2NC5kZWNvZGUoYnVmZiwgaW5kZXgpOworICAgICAgICBpZiAoYnVmZiA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkluY29ycmVjdCBCYXNlNjQgZW5jb2RpbmciKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnVmZjsKKyAgICB9CisKKyAgICBwcml2YXRlIElPRXhjZXB0aW9uIGJhZEVuZChieXRlW10gYm91bmRhcnlfc3VmZml4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgcyA9IChib3VuZGFyeV9zdWZmaXggPT0gbnVsbCkgPyAiIiA6IG5ldyBTdHJpbmcoYm91bmRhcnlfc3VmZml4KTsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbmNvcnJlY3QgUEVNIGVuY29kaW5nOiAnLS0tLS1FTkQiICsgcyArICInIGlzIGV4cGVjdGVkIGFzIGNsb3NpbmcgZGVsaW1pdGVyIGJvdW5kYXJ5LiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSBkYXRhIG9mIHNwZWNpZmllZCBsZW5ndGggZnJvbSBzb3VyY2UKKyAgICAgKiBhbmQgcmV0dXJucyBpdCBhcyBhbiBhcnJheS4KKyAgICAgKiBAcmV0dXJuIHRoZSBieXRlIGFycmF5IGNvbnRhaW5lZCByZWFkIGRhdGEgb3IKKyAgICAgKiBudWxsIGlmIHRoZSBzdHJlYW0gY29udGFpbnMgbm90IGVub3VnaCBkYXRhCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBzb21lIEkvTyBlcnJvciBoYXMgYmVlbiBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBieXRlW10gcmVhZEJ5dGVzKElucHV0U3RyZWFtIHNvdXJjZSwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtsZW5ndGhdOworICAgICAgICBmb3IgKGludCBpPTA7IGk8bGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGludCBieXRpayA9IHNvdXJjZS5yZWFkKCk7CisgICAgICAgICAgICBpZiAoYnl0aWsgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdFtpXSA9IChieXRlKSBieXRpazsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIENlcnRpZmljYXRlIG9iamVjdCBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcm92aWRlZCBlbmNvZGluZy4KKyAgICAgKiBSZXN1bHRpbmcgb2JqZWN0IGlzIHJldHJpZXZlZCBmcm9tIHRoZSBjYWNoZQorICAgICAqIGlmIGl0IGNvbnRhaW5zIHN1Y2ggY29ycmVzcG9uZGVuY2UKKyAgICAgKiBhbmQgaXMgY29uc3RydWN0ZWQgb24gdGhlIGJhc2Ugb2YgZW5jb2RpbmcKKyAgICAgKiBhbmQgc3RvcmVkIGluIHRoZSBjYWNoZSBvdGhlcndpc2UuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBzb21lIGRlY29kaW5nIGVycm9ycyBvY2N1cgorICAgICAqIChpbiB0aGUgY2FzZSBvZiBjYWNoZSBtaXNzKS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBDZXJ0aWZpY2F0ZSBnZXRDZXJ0aWZpY2F0ZShieXRlW10gZW5jb2RpbmcpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGVuY29kaW5nLmxlbmd0aCA8IENFUlRfQ0FDSEVfU0VFRF9MRU5HVEgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigiZW5jb2RpbmcubGVuZ3RoIDwgQ0VSVF9DQUNIRV9TRUVEX0xFTkdUSCIpOworICAgICAgICB9CisgICAgICAgIHN5bmNocm9uaXplZCAoQ0VSVF9DQUNIRSkgeworICAgICAgICAgICAgbG9uZyBoYXNoID0gQ0VSVF9DQUNIRS5nZXRIYXNoKGVuY29kaW5nKTsKKyAgICAgICAgICAgIGlmIChDRVJUX0NBQ0hFLmNvbnRhaW5zKGhhc2gpKSB7CisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgcmVzID0KKyAgICAgICAgICAgICAgICAgICAgKENlcnRpZmljYXRlKSBDRVJUX0NBQ0hFLmdldChoYXNoLCBlbmNvZGluZyk7CisgICAgICAgICAgICAgICAgaWYgKHJlcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXM7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgQ2VydGlmaWNhdGUgcmVzID0gbmV3IFg1MDlDZXJ0SW1wbChlbmNvZGluZyk7CisgICAgICAgICAgICBDRVJUX0NBQ0hFLnB1dChoYXNoLCBlbmNvZGluZywgcmVzKTsKKyAgICAgICAgICAgIHJldHVybiByZXM7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBDZXJ0aWZpY2F0ZSBvYmplY3QgY29ycmVzcG9uZGluZyB0byB0aGUgZW5jb2RpbmcgcHJvdmlkZWQKKyAgICAgKiBieSB0aGUgc3RyZWFtLgorICAgICAqIFJlc3VsdGluZyBvYmplY3QgaXMgcmV0cmlldmVkIGZyb20gdGhlIGNhY2hlCisgICAgICogaWYgaXQgY29udGFpbnMgc3VjaCBjb3JyZXNwb25kZW5jZQorICAgICAqIGFuZCBpcyBjb25zdHJ1Y3RlZCBvbiB0aGUgYmFzZSBvZiBlbmNvZGluZworICAgICAqIGFuZCBzdG9yZWQgaW4gdGhlIGNhY2hlIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHNvbWUgZGVjb2RpbmcgZXJyb3JzIG9jY3VyCisgICAgICogKGluIHRoZSBjYXNlIG9mIGNhY2hlIG1pc3MpLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIENlcnRpZmljYXRlIGdldENlcnRpZmljYXRlKElucHV0U3RyZWFtIGluU3RyZWFtKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAoQ0VSVF9DQUNIRSkgeworICAgICAgICAgICAgaW5TdHJlYW0ubWFyayhDRVJUX0NBQ0hFX1NFRURfTEVOR1RIKTsKKyAgICAgICAgICAgIC8vIHJlYWQgdGhlIHByZWZpeCBvZiB0aGUgZW5jb2RpbmcKKyAgICAgICAgICAgIGJ5dGVbXSBidWZmID0gcmVhZEJ5dGVzKGluU3RyZWFtLCBDRVJUX0NBQ0hFX1NFRURfTEVOR1RIKTsKKyAgICAgICAgICAgIGluU3RyZWFtLnJlc2V0KCk7CisgICAgICAgICAgICBpZiAoYnVmZiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKCJJbnB1dFN0cmVhbSBkb2Vzbid0IGNvbnRhaW4gZW5vdWdoIGRhdGEiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGxvbmcgaGFzaCA9IENFUlRfQ0FDSEUuZ2V0SGFzaChidWZmKTsKKyAgICAgICAgICAgIGlmIChDRVJUX0NBQ0hFLmNvbnRhaW5zKGhhc2gpKSB7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGVuY29kaW5nID0gbmV3IGJ5dGVbQmVySW5wdXRTdHJlYW0uZ2V0TGVuZ3RoKGJ1ZmYpXTsKKyAgICAgICAgICAgICAgICBpZiAoZW5jb2RpbmcubGVuZ3RoIDwgQ0VSVF9DQUNIRV9TRUVEX0xFTkdUSCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oIkJhZCBDZXJ0aWZpY2F0ZSBlbmNvZGluZyIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBTdHJlYW1zLnJlYWRGdWxseShpblN0cmVhbSwgZW5jb2RpbmcpOworICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIHJlcyA9IChDZXJ0aWZpY2F0ZSkgQ0VSVF9DQUNIRS5nZXQoaGFzaCwgZW5jb2RpbmcpOworICAgICAgICAgICAgICAgIGlmIChyZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXMgPSBuZXcgWDUwOUNlcnRJbXBsKGVuY29kaW5nKTsKKyAgICAgICAgICAgICAgICBDRVJUX0NBQ0hFLnB1dChoYXNoLCBlbmNvZGluZywgcmVzKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpblN0cmVhbS5yZXNldCgpOworICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIHJlcyA9IG5ldyBYNTA5Q2VydEltcGwoaW5TdHJlYW0pOworICAgICAgICAgICAgICAgIENFUlRfQ0FDSEUucHV0KGhhc2gsIHJlcy5nZXRFbmNvZGVkKCksIHJlcyk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIENSTCBvYmplY3QgY29ycmVzcG9uZGluZyB0byB0aGUgcHJvdmlkZWQgZW5jb2RpbmcuCisgICAgICogUmVzdWx0aW5nIG9iamVjdCBpcyByZXRyaWV2ZWQgZnJvbSB0aGUgY2FjaGUKKyAgICAgKiBpZiBpdCBjb250YWlucyBzdWNoIGNvcnJlc3BvbmRlbmNlCisgICAgICogYW5kIGlzIGNvbnN0cnVjdGVkIG9uIHRoZSBiYXNlIG9mIGVuY29kaW5nCisgICAgICogYW5kIHN0b3JlZCBpbiB0aGUgY2FjaGUgb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgc29tZSBkZWNvZGluZyBlcnJvcnMgb2NjdXIKKyAgICAgKiAoaW4gdGhlIGNhc2Ugb2YgY2FjaGUgbWlzcykuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgQ1JMIGdldENSTChieXRlW10gZW5jb2RpbmcpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBDUkxFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGVuY29kaW5nLmxlbmd0aCA8IENSTF9DQUNIRV9TRUVEX0xFTkdUSCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENSTEV4Y2VwdGlvbigiZW5jb2RpbmcubGVuZ3RoIDwgQ1JMX0NBQ0hFX1NFRURfTEVOR1RIIik7CisgICAgICAgIH0KKyAgICAgICAgc3luY2hyb25pemVkIChDUkxfQ0FDSEUpIHsKKyAgICAgICAgICAgIGxvbmcgaGFzaCA9IENSTF9DQUNIRS5nZXRIYXNoKGVuY29kaW5nKTsKKyAgICAgICAgICAgIGlmIChDUkxfQ0FDSEUuY29udGFpbnMoaGFzaCkpIHsKKyAgICAgICAgICAgICAgICBYNTA5Q1JMIHJlcyA9IChYNTA5Q1JMKSBDUkxfQ0FDSEUuZ2V0KGhhc2gsIGVuY29kaW5nKTsKKyAgICAgICAgICAgICAgICBpZiAocmVzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBYNTA5Q1JMIHJlcyA9IG5ldyBYNTA5Q1JMSW1wbChlbmNvZGluZyk7CisgICAgICAgICAgICBDUkxfQ0FDSEUucHV0KGhhc2gsIGVuY29kaW5nLCByZXMpOworICAgICAgICAgICAgcmV0dXJuIHJlczsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIENSTCBvYmplY3QgY29ycmVzcG9uZGluZyB0byB0aGUgZW5jb2RpbmcgcHJvdmlkZWQKKyAgICAgKiBieSB0aGUgc3RyZWFtLgorICAgICAqIFJlc3VsdGluZyBvYmplY3QgaXMgcmV0cmlldmVkIGZyb20gdGhlIGNhY2hlCisgICAgICogaWYgaXQgY29udGFpbnMgc3VjaCBjb3JyZXNwb25kZW5jZQorICAgICAqIGFuZCBpcyBjb25zdHJ1Y3RlZCBvbiB0aGUgYmFzZSBvZiBlbmNvZGluZworICAgICAqIGFuZCBzdG9yZWQgaW4gdGhlIGNhY2hlIG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHNvbWUgZGVjb2RpbmcgZXJyb3JzIG9jY3VyCisgICAgICogKGluIHRoZSBjYXNlIG9mIGNhY2hlIG1pc3MpLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIENSTCBnZXRDUkwoSW5wdXRTdHJlYW0gaW5TdHJlYW0pCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBDUkxFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChDUkxfQ0FDSEUpIHsKKyAgICAgICAgICAgIGluU3RyZWFtLm1hcmsoQ1JMX0NBQ0hFX1NFRURfTEVOR1RIKTsKKyAgICAgICAgICAgIGJ5dGVbXSBidWZmID0gcmVhZEJ5dGVzKGluU3RyZWFtLCBDUkxfQ0FDSEVfU0VFRF9MRU5HVEgpOworICAgICAgICAgICAgLy8gcmVhZCB0aGUgcHJlZml4IG9mIHRoZSBlbmNvZGluZworICAgICAgICAgICAgaW5TdHJlYW0ucmVzZXQoKTsKKyAgICAgICAgICAgIGlmIChidWZmID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ1JMRXhjZXB0aW9uKCJJbnB1dFN0cmVhbSBkb2Vzbid0IGNvbnRhaW4gZW5vdWdoIGRhdGEiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGxvbmcgaGFzaCA9IENSTF9DQUNIRS5nZXRIYXNoKGJ1ZmYpOworICAgICAgICAgICAgaWYgKENSTF9DQUNIRS5jb250YWlucyhoYXNoKSkgeworICAgICAgICAgICAgICAgIGJ5dGVbXSBlbmNvZGluZyA9IG5ldyBieXRlW0JlcklucHV0U3RyZWFtLmdldExlbmd0aChidWZmKV07CisgICAgICAgICAgICAgICAgaWYgKGVuY29kaW5nLmxlbmd0aCA8IENSTF9DQUNIRV9TRUVEX0xFTkdUSCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ1JMRXhjZXB0aW9uKCJCYWQgQ1JMIGVuY29kaW5nIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIFN0cmVhbXMucmVhZEZ1bGx5KGluU3RyZWFtLCBlbmNvZGluZyk7CisgICAgICAgICAgICAgICAgQ1JMIHJlcyA9IChDUkwpIENSTF9DQUNIRS5nZXQoaGFzaCwgZW5jb2RpbmcpOworICAgICAgICAgICAgICAgIGlmIChyZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXMgPSBuZXcgWDUwOUNSTEltcGwoZW5jb2RpbmcpOworICAgICAgICAgICAgICAgIENSTF9DQUNIRS5wdXQoaGFzaCwgZW5jb2RpbmcsIHJlcyk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgWDUwOUNSTCByZXMgPSBuZXcgWDUwOUNSTEltcGwoaW5TdHJlYW0pOworICAgICAgICAgICAgICAgIENSTF9DQUNIRS5wdXQoaGFzaCwgcmVzLmdldEVuY29kZWQoKSwgcmVzKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUaGlzIGNsYXNzIGV4dGVuZHMgYW55IGV4aXN0aW5nIGlucHV0IHN0cmVhbSB3aXRoCisgICAgICogbWFyayBmdW5jdGlvbmFsaXR5LiBJdCBhY3RzIGFzIGEgd3JhcHBlciBvdmVyIHRoZQorICAgICAqIHN0cmVhbSBhbmQgc3VwcG9ydHMgcmVzZXQgdG8gdGhlCisgICAgICogbWFya2VkIHN0YXRlIHdpdGggcmVhZGxpbWl0IG5vIG1vcmUgdGhhbiBCVUZGX1NJWkUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgUmVzdG9yaW5nSW5wdXRTdHJlYW0gZXh0ZW5kcyBJbnB1dFN0cmVhbSB7CisKKyAgICAgICAgLy8gd3JhcHBlZCBpbnB1dCBzdHJlYW0KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBJbnB1dFN0cmVhbSBpblN0cmVhbTsKKyAgICAgICAgLy8gc3BlY2lmaWVzIGhvdyBtdWNoIG9mIHRoZSByZWFkIGRhdGEgaXMgYnVmZmVyZWQKKyAgICAgICAgLy8gYWZ0ZXIgdGhlIG1hcmsgaGFzIGJlZW4gc2V0IHVwCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCVUZGX1NJWkUgPSAzMjsKKyAgICAgICAgLy8gYnVmZmVyIHRvIGtlZXAgdGhlIGJ5dGVzIHJlYWQgYWZ0ZXIgdGhlIG1hcmsgaGFzIGJlZW4gc2V0IHVwCisgICAgICAgIHByaXZhdGUgZmluYWwgaW50W10gYnVmZiA9IG5ldyBpbnRbQlVGRl9TSVpFKjJdOworICAgICAgICAvLyBwb3NpdGlvbiBvZiB0aGUgbmV4dCBieXRlIHRvIHJlYWQsCisgICAgICAgIC8vIHRoZSB2YWx1ZSBvZiAtMSBpbmRpY2F0ZXMgdGhhdCB0aGUgYnVmZmVyIGlzIG5vdCB1c2VkCisgICAgICAgIC8vIChtYXJrIHdhcyBub3Qgc2V0IHVwIG9yIHdhcyBpbnZhbGlkYXRlZCwgb3IgcmVzZXQgdG8gdGhlIG1hcmtlZAorICAgICAgICAvLyBwb3NpdGlvbiBoYXMgYmVlbiBkb25lIGFuZCBhbGwgdGhlIGJ1ZmZlcmVkIGRhdGEgd2FzIHJlYWQgb3V0KQorICAgICAgICBwcml2YXRlIGludCBwb3MgPSAtMTsKKyAgICAgICAgLy8gcG9zaXRpb24gb2YgdGhlIGxhc3QgYnVmZmVyZWQgYnl0ZQorICAgICAgICBwcml2YXRlIGludCBiYXIgPSAwOworICAgICAgICAvLyBwb3NpdGlvbiBpbiB0aGUgYnVmZmVyIHdoZXJlIHRoZSBtYXJrIGJlY29tZXMgaW52YWxpZGF0ZWQKKyAgICAgICAgcHJpdmF0ZSBpbnQgZW5kID0gMDsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyB0aGUgbWFyayBzdXBwb3J0aW5nIHdyYXBwZXIgb3ZlciB0aGUgc3RyZWFtLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFJlc3RvcmluZ0lucHV0U3RyZWFtKElucHV0U3RyZWFtIGluU3RyZWFtKSB7CisgICAgICAgICAgICB0aGlzLmluU3RyZWFtID0gaW5TdHJlYW07CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIChiYXIgLSBwb3MpICsgaW5TdHJlYW0uYXZhaWxhYmxlKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaW5TdHJlYW0uY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBtYXJrKGludCByZWFkbGltaXQpIHsKKyAgICAgICAgICAgIGlmIChwb3MgPCAwKSB7CisgICAgICAgICAgICAgICAgcG9zID0gMDsKKyAgICAgICAgICAgICAgICBiYXIgPSAwOworICAgICAgICAgICAgICAgIGVuZCA9IEJVRkZfU0laRSAtIDE7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGVuZCA9IChwb3MgKyBCVUZGX1NJWkUgLSAxKSAlIEJVRkZfU0laRTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBtYXJrU3VwcG9ydGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmVhZHMgdGhlIGJ5dGUgZnJvbSB0aGUgc3RyZWFtLiBJZiBtYXJrIGhhcyBiZWVuIHNldCB1cAorICAgICAgICAgKiBhbmQgd2FzIG5vdCBpbnZhbGlkYXRlZCBieXRlIGlzIHJlYWQgZnJvbSB0aGUgdW5kZXJseWluZworICAgICAgICAgKiBzdHJlYW0gYW5kIHNhdmVkIGludG8gdGhlIGJ1ZmZlci4gSWYgdGhlIGN1cnJlbnQgcmVhZCBwb3NpdGlvbgorICAgICAgICAgKiBoYXMgYmVlbiByZXNldCB0byB0aGUgbWFya2VkIHBvc2l0aW9uIGFuZCB0aGVyZSBhcmUgcmVtYWluaW5nCisgICAgICAgICAqIGJ5dGVzIGluIHRoZSBidWZmZXIsIHRoZSBieXRlIGlzIHRha2VuIGZyb20gaXQuIEluIHRoZSBvdGhlciBjYXNlcworICAgICAgICAgKiAoaWYgbWFyayBoYXMgYmVlbiBpbnZhbGlkYXRlZCwgb3IgdGhlcmUgYXJlIG5vIGJ1ZmZlcmVkIGJ5dGVzKQorICAgICAgICAgKiB0aGUgYnl0ZSBpcyB0YWtlbiBkaXJlY3RseSBmcm9tIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBhbmQgaXQgaXMKKyAgICAgICAgICogcmV0dXJuZWQgd2l0aG91dCBzYXZpbmcgdG8gdGhlIGJ1ZmZlci4KKyAgICAgICAgICoKKyAgICAgICAgICogQHNlZSBqYXZhLmlvLklucHV0U3RyZWFtI3JlYWQoKQorICAgICAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgLy8gaWYgYnVmZmVyIGlzIGN1cnJlbnRseSB1c2VkCisgICAgICAgICAgICBpZiAocG9zID49IDApIHsKKyAgICAgICAgICAgICAgICAvLyBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBidWZmZXIKKyAgICAgICAgICAgICAgICBpbnQgY3VyID0gcG9zICUgQlVGRl9TSVpFOworICAgICAgICAgICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIGJ1ZmZlciBjb250YWlucyB0aGUgZGF0YSB0byBiZSByZWFkCisgICAgICAgICAgICAgICAgaWYgKGN1ciA8IGJhcikgeworICAgICAgICAgICAgICAgICAgICAvLyByZXR1cm4gdGhlIGRhdGEgZnJvbSB0aGUgYnVmZmVyCisgICAgICAgICAgICAgICAgICAgIHBvcysrOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gYnVmZltjdXJdOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBjaGVjayB3aGV0aGVyIGJ1ZmZlciBoYXMgZnJlZSBzcGFjZQorICAgICAgICAgICAgICAgIGlmIChjdXIgIT0gZW5kKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGl0IGhhcywgc28gcmVhZCB0aGUgZGF0YSBmcm9tIHRoZSB3cmFwcGVkIHN0cmVhbQorICAgICAgICAgICAgICAgICAgICAvLyBhbmQgcGxhY2UgaXQgaW4gdGhlIGJ1ZmZlcgorICAgICAgICAgICAgICAgICAgICBidWZmW2N1cl0gPSBpblN0cmVhbS5yZWFkKCk7CisgICAgICAgICAgICAgICAgICAgIGJhciA9IGN1cisxOworICAgICAgICAgICAgICAgICAgICBwb3MrKzsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJ1ZmZbY3VyXTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAvLyBidWZmZXIgaWYgZnVsbCBhbmQgY2FuIG5vdCBvcGVyYXRlCisgICAgICAgICAgICAgICAgICAgIC8vIGFueSBtb3JlLCBzbyBpbnZhbGlkYXRlIHRoZSBtYXJrIHBvc2l0aW9uCisgICAgICAgICAgICAgICAgICAgIC8vIGFuZCB0dXJuIG9mZiB0aGUgdXNpbmcgb2YgYnVmZmVyCisgICAgICAgICAgICAgICAgICAgIHBvcyA9IC0xOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIGJ1ZmZlciBpcyBub3QgdXNlZCwgc28gcmV0dXJuIHRoZSBkYXRhIGZyb20gdGhlIHdyYXBwZWQgc3RyZWFtCisgICAgICAgICAgICByZXR1cm4gaW5TdHJlYW0ucmVhZCgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGludCByZWFkX2I7CisgICAgICAgICAgICBpbnQgaTsKKyAgICAgICAgICAgIGZvciAoaT0wOyBpPGxlbjsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKChyZWFkX2IgPSByZWFkKCkpID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAoaSA9PSAwKSA/IC0xIDogaTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYltvZmYraV0gPSAoYnl0ZSkgcmVhZF9iOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaWYgKHBvcyA+PSAwKSB7CisgICAgICAgICAgICAgICAgcG9zID0gKGVuZCArIDEpICUgQlVGRl9TSVpFOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNvdWxkIG5vdCByZXNldCB0aGUgc3RyZWFtOiAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICJwb3NpdGlvbiBiZWNhbWUgaW52YWxpZCBvciBzdHJlYW0gaGFzIG5vdCBiZWVuIG1hcmtlZCIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jZXJ0L1g1MDlDZXJ0SW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jZXJ0L1g1MDlDZXJ0SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2YWRjNDQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Byb3ZpZGVyL2NlcnQvWDUwOUNlcnRJbXBsLmphdmEKQEAgLTAsMCArMSw0NDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkucHJvdmlkZXIuY2VydDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLlJTQVB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS51dGlscy5BbGdOYW1lTWFwcGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LkNlcnRpZmljYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LkV4dGVuc2lvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5FeHRlbnNpb25zOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LlRCU0NlcnRpZmljYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2UuT3BlblNTTFNpZ25hdHVyZTsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIFg1MDlDZXJ0aWZpY2F0ZS4gSXQgd3JhcHMKKyAqIHRoZSBpbnN0YW5jZSBvZiBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5DZXJ0aWZpY2F0ZQorICogYnVpbHQgb24gdGhlIGJhc2Ugb2YgcHJvdmlkZWQgQVNOLjEgREVSIGVuY29kZWQgZm9ybSBvZgorICogQ2VydGlmaWNhdGUgc3RydWN0dXJlIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODAKKyAqIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KS4KKyAqIEBzZWUgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuQ2VydGlmaWNhdGUKKyAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgWDUwOUNlcnRJbXBsIGV4dGVuZHMgWDUwOUNlcnRpZmljYXRlIHsKKworICAgIC8qKiBAc2VyaWFsICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjk3MjI0ODcyOTQ0NjczNjE1NEw7CisKKyAgICAvKiogdGhlIGNvcmUgb2JqZWN0IHRvIGJlIHdyYXBwZWQgaW4gWDUwOUNlcnRpZmljYXRlICovCisgICAgcHJpdmF0ZSBmaW5hbCBDZXJ0aWZpY2F0ZSBjZXJ0aWZpY2F0ZTsKKworICAgIC8vIHRvIHNwZWVkIHVwIGFjY2VzcyB0byB0aGUgaW5mbywgdGhlIGZvbGxvd2luZyBmaWVsZHMKKyAgICAvLyBjYWNoZSB2YWx1ZXMgcmV0cmlldmVkIGZyb20gdGhlIGNlcnRpZmljYXRlIG9iamVjdCwKKyAgICAvLyBpbml0aWFsaXplZCB1c2luZyB0aGUgInNpbmdsZS1jaGVjayBpZGlvbSIuCisgICAgcHJpdmF0ZSBmaW5hbCBUQlNDZXJ0aWZpY2F0ZSB0YnNDZXJ0OworICAgIHByaXZhdGUgZmluYWwgRXh0ZW5zaW9ucyBleHRlbnNpb25zOworICAgIHByaXZhdGUgdm9sYXRpbGUgbG9uZyBub3RCZWZvcmUgPSAtMTsKKyAgICBwcml2YXRlIHZvbGF0aWxlIGxvbmcgbm90QWZ0ZXIgPSAtMTsKKyAgICBwcml2YXRlIHZvbGF0aWxlIEJpZ0ludGVnZXIgc2VyaWFsTnVtYmVyOworICAgIHByaXZhdGUgdm9sYXRpbGUgWDUwMFByaW5jaXBhbCBpc3N1ZXI7CisgICAgcHJpdmF0ZSB2b2xhdGlsZSBYNTAwUHJpbmNpcGFsIHN1YmplY3Q7CisgICAgcHJpdmF0ZSB2b2xhdGlsZSBieXRlW10gdGJzQ2VydGlmaWNhdGU7CisgICAgcHJpdmF0ZSB2b2xhdGlsZSBieXRlW10gc2lnbmF0dXJlOworICAgIHByaXZhdGUgdm9sYXRpbGUgU3RyaW5nIHNpZ0FsZ05hbWU7CisgICAgcHJpdmF0ZSB2b2xhdGlsZSBTdHJpbmcgc2lnQWxnT0lEOworICAgIHByaXZhdGUgdm9sYXRpbGUgYnl0ZVtdIHNpZ0FsZ1BhcmFtczsKKyAgICAvLyBpbmRpY2F0ZXMgd2hldGhlciB0aGUgc2lnbmF0dXJlIGFsZ29yaXRobSBwYXJhbWV0ZXJzIGFyZSBudWxsCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIG51bGxTaWdBbGdQYXJhbXM7CisgICAgcHJpdmF0ZSB2b2xhdGlsZSBQdWJsaWNLZXkgcHVibGljS2V5OworCisgICAgLy8gZW5jb2Rpbmcgb2YgdGhlIGNlcnRpZmljYXRlCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBieXRlW10gZW5jb2Rpbmc7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIHRoZSBpbnN0YW5jZSBvbiB0aGUgYmFzZSBvZiBBU04uMSBlbmNvZGVkCisgICAgICogZm9ybSBvZiBYLjUwOSBjZXJ0aWZpY2F0ZSBwcm92aWRlZCB2aWEgc3RyZWFtIHBhcmFtZXRlci4KKyAgICAgKiBAcGFyYW0gaW4gaW5wdXQgc3RyZWFtIGNvbnRhaW5pbmcgQVNOLjEgZW5jb2RlZCBmb3JtIG9mIGNlcnRpZmljYXRlLgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24gaWYgc29tZSBkZWNvZGluZyBwcm9ibGVtcyBvY2N1ci4KKyAgICAgKi8KKyAgICBwdWJsaWMgWDUwOUNlcnRJbXBsKElucHV0U3RyZWFtIGluKSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gZGVjb2RlIHRoZSBDZXJ0aWZpY2F0ZSBvYmplY3QKKyAgICAgICAgICAgIHRoaXMuY2VydGlmaWNhdGUgPSAoQ2VydGlmaWNhdGUpIENlcnRpZmljYXRlLkFTTjEuZGVjb2RlKGluKTsKKyAgICAgICAgICAgIC8vIGNhY2hlIHRoZSB2YWx1ZXMgb2YgVEJTQ2VydGlmaWNhdGUgYW5kIEV4dGVuc2lvbnMKKyAgICAgICAgICAgIHRoaXMudGJzQ2VydCA9IGNlcnRpZmljYXRlLmdldFRic0NlcnRpZmljYXRlKCk7CisgICAgICAgICAgICB0aGlzLmV4dGVuc2lvbnMgPSB0YnNDZXJ0LmdldEV4dGVuc2lvbnMoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyB0aGUgaW5zdGFuY2Ugb24gdGhlIGJhc2Ugb2YgZXhpc3RpbmcgQ2VydGlmaWNhdGUgb2JqZWN0IHRvCisgICAgICogYmUgd3JhcHBlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgWDUwOUNlcnRJbXBsKENlcnRpZmljYXRlIGNlcnRpZmljYXRlKSB7CisgICAgICAgIHRoaXMuY2VydGlmaWNhdGUgPSBjZXJ0aWZpY2F0ZTsKKyAgICAgICAgLy8gY2FjaGUgdGhlIHZhbHVlcyBvZiBUQlNDZXJ0aWZpY2F0ZSBhbmQgRXh0ZW5zaW9ucworICAgICAgICB0aGlzLnRic0NlcnQgPSBjZXJ0aWZpY2F0ZS5nZXRUYnNDZXJ0aWZpY2F0ZSgpOworICAgICAgICB0aGlzLmV4dGVuc2lvbnMgPSB0YnNDZXJ0LmdldEV4dGVuc2lvbnMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIHRoZSBpbnN0YW5jZSBvbiB0aGUgYmFzZSBvZiBBU04uMSBlbmNvZGVkCisgICAgICogZm9ybSBvZiBYLjUwOSBjZXJ0aWZpY2F0ZSBwcm92aWRlZCB2aWEgYXJyYXkgb2YgYnl0ZXMuCisgICAgICogQHBhcmFtIGVuY29kaW5nIGJ5dGUgYXJyYXkgY29udGFpbmluZyBBU04uMSBlbmNvZGVkIGZvcm0gb2YgY2VydGlmaWNhdGUuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBzb21lIGRlY29kaW5nIHByb2JsZW1zIG9jY3VyLgorICAgICAqLworICAgIHB1YmxpYyBYNTA5Q2VydEltcGwoYnl0ZVtdIGVuY29kaW5nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzKChDZXJ0aWZpY2F0ZSkgQ2VydGlmaWNhdGUuQVNOMS5kZWNvZGUoZW5jb2RpbmcpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjaGVja1ZhbGlkaXR5KCkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24sIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24geworICAgICAgICBjaGVja1ZhbGlkaXR5KFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjaGVja1ZhbGlkaXR5KERhdGUgZGF0ZSkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24sIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24geworICAgICAgICBjaGVja1ZhbGlkaXR5KGRhdGUuZ2V0VGltZSgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tWYWxpZGl0eShsb25nIHRpbWUpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRpbWUgPCBnZXROb3RCZWZvcmVJbnRlcm5hbCgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbigiY3VycmVudCB0aW1lOiAiICsgbmV3IERhdGUodGltZSkKKyAgICAgICAgICAgICAgICArICIsIHZhbGlkYXRpb24gdGltZTogIiArIG5ldyBEYXRlKGdldE5vdEJlZm9yZUludGVybmFsKCkpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodGltZSA+IGdldE5vdEFmdGVySW50ZXJuYWwoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbigiY3VycmVudCB0aW1lOiAiICsgbmV3IERhdGUodGltZSkKKyAgICAgICAgICAgICAgICArICIsIGV4cGlyYXRpb24gdGltZTogIiArIG5ldyBEYXRlKGdldE5vdEFmdGVySW50ZXJuYWwoKSkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRWZXJzaW9uKCkgeworICAgICAgICByZXR1cm4gdGJzQ2VydC5nZXRWZXJzaW9uKCkgKyAxOworICAgIH0KKworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFNlcmlhbE51bWJlcigpIHsKKyAgICAgICAgQmlnSW50ZWdlciByZXN1bHQgPSBzZXJpYWxOdW1iZXI7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgc2VyaWFsTnVtYmVyID0gcmVzdWx0ID0gdGJzQ2VydC5nZXRTZXJpYWxOdW1iZXIoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0SXNzdWVyRE4oKSB7CisgICAgICAgIHJldHVybiBnZXRJc3N1ZXJYNTAwUHJpbmNpcGFsKCk7CisgICAgfQorCisgICAgcHVibGljIFg1MDBQcmluY2lwYWwgZ2V0SXNzdWVyWDUwMFByaW5jaXBhbCgpIHsKKyAgICAgICAgWDUwMFByaW5jaXBhbCByZXN1bHQgPSBpc3N1ZXI7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gcmV0cmlldmUgdGhlIGlzc3VlcidzIHByaW5jaXBhbAorICAgICAgICAgICAgaXNzdWVyID0gcmVzdWx0ID0gdGJzQ2VydC5nZXRJc3N1ZXIoKS5nZXRYNTAwUHJpbmNpcGFsKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgUHJpbmNpcGFsIGdldFN1YmplY3RETigpIHsKKyAgICAgICAgcmV0dXJuIGdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCk7CisgICAgfQorCisgICAgcHVibGljIFg1MDBQcmluY2lwYWwgZ2V0U3ViamVjdFg1MDBQcmluY2lwYWwoKSB7CisgICAgICAgIFg1MDBQcmluY2lwYWwgcmVzdWx0ID0gc3ViamVjdDsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyByZXRyaWV2ZSB0aGUgc3ViamVjdCdzIHByaW5jaXBhbAorICAgICAgICAgICAgc3ViamVjdCA9IHJlc3VsdCA9IHRic0NlcnQuZ2V0U3ViamVjdCgpLmdldFg1MDBQcmluY2lwYWwoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBEYXRlIGdldE5vdEJlZm9yZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBEYXRlKGdldE5vdEJlZm9yZUludGVybmFsKCkpOworICAgIH0KKworICAgIHByaXZhdGUgbG9uZyBnZXROb3RCZWZvcmVJbnRlcm5hbCgpIHsKKyAgICAgICAgbG9uZyByZXN1bHQgPSBub3RCZWZvcmU7CisgICAgICAgIGlmIChyZXN1bHQgPT0gLTEpIHsKKyAgICAgICAgICAgIG5vdEJlZm9yZSA9IHJlc3VsdCA9IHRic0NlcnQuZ2V0VmFsaWRpdHkoKS5nZXROb3RCZWZvcmUoKS5nZXRUaW1lKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgRGF0ZSBnZXROb3RBZnRlcigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBEYXRlKGdldE5vdEFmdGVySW50ZXJuYWwoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBsb25nIGdldE5vdEFmdGVySW50ZXJuYWwoKSB7CisgICAgICAgIGxvbmcgcmVzdWx0ID0gbm90QWZ0ZXI7CisgICAgICAgIGlmIChyZXN1bHQgPT0gLTEpIHsKKyAgICAgICAgICAgIG5vdEFmdGVyID0gcmVzdWx0ID0gdGJzQ2VydC5nZXRWYWxpZGl0eSgpLmdldE5vdEFmdGVyKCkuZ2V0VGltZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRUQlNDZXJ0aWZpY2F0ZSgpIHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGdldFRic0NlcnRpZmljYXRlSW50ZXJuYWwoKS5jbG9uZSgpOworICAgIH0KKworICAgIHByaXZhdGUgYnl0ZVtdIGdldFRic0NlcnRpZmljYXRlSW50ZXJuYWwoKSB7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSB0YnNDZXJ0aWZpY2F0ZTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICB0YnNDZXJ0aWZpY2F0ZSA9IHJlc3VsdCA9IHRic0NlcnQuZ2V0RW5jb2RlZCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRTaWduYXR1cmUoKSB7CisgICAgICAgIHJldHVybiBnZXRTaWduYXR1cmVJbnRlcm5hbCgpLmNsb25lKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBieXRlW10gZ2V0U2lnbmF0dXJlSW50ZXJuYWwoKSB7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBzaWduYXR1cmU7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgc2lnbmF0dXJlID0gcmVzdWx0ID0gY2VydGlmaWNhdGUuZ2V0U2lnbmF0dXJlVmFsdWUoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2lnQWxnTmFtZSgpIHsKKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IHNpZ0FsZ05hbWU7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHNpZ0FsZ09JRExvY2FsID0gZ2V0U2lnQWxnT0lEKCk7CisgICAgICAgICAgICAvLyByZXRyaWV2ZSB0aGUgbmFtZSBvZiB0aGUgc2lnbmluZyBhbGdvcml0aG0KKyAgICAgICAgICAgIHJlc3VsdCA9IEFsZ05hbWVNYXBwZXIubWFwMkFsZ05hbWUoc2lnQWxnT0lETG9jYWwpOworICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgLy8gaWYgY291bGQgbm90IGJlIGZvdW5kLCB1c2UgT0lEIGFzIGEgbmFtZQorICAgICAgICAgICAgICAgIHJlc3VsdCA9IHNpZ0FsZ09JRExvY2FsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2lnQWxnTmFtZSA9IHJlc3VsdDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2lnQWxnT0lEKCkgeworICAgICAgICBTdHJpbmcgcmVzdWx0ID0gc2lnQWxnT0lEOworICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIGlmIGluZm8gd2FzIG5vdCByZXRyaWV2ZWQgKGFuZCBjYWNoZWQpLCBkbyBpdDoKKyAgICAgICAgICAgIHNpZ0FsZ09JRCA9IHJlc3VsdCA9IHRic0NlcnQuZ2V0U2lnbmF0dXJlKCkuZ2V0QWxnb3JpdGhtKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldFNpZ0FsZ1BhcmFtcygpIHsKKyAgICAgICAgaWYgKG51bGxTaWdBbGdQYXJhbXMpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBzaWdBbGdQYXJhbXM7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0ID0gdGJzQ2VydC5nZXRTaWduYXR1cmUoKS5nZXRQYXJhbWV0ZXJzKCk7CisgICAgICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBudWxsU2lnQWxnUGFyYW1zID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNpZ0FsZ1BhcmFtcyA9IHJlc3VsdDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuW10gZ2V0SXNzdWVyVW5pcXVlSUQoKSB7CisgICAgICAgIHJldHVybiB0YnNDZXJ0LmdldElzc3VlclVuaXF1ZUlEKCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW5bXSBnZXRTdWJqZWN0VW5pcXVlSUQoKSB7CisgICAgICAgIHJldHVybiB0YnNDZXJ0LmdldFN1YmplY3RVbmlxdWVJRCgpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuW10gZ2V0S2V5VXNhZ2UoKSB7CisgICAgICAgIGlmIChleHRlbnNpb25zID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBleHRlbnNpb25zLnZhbHVlT2ZLZXlVc2FnZSgpOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PFN0cmluZz4gZ2V0RXh0ZW5kZWRLZXlVc2FnZSgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24geworICAgICAgICBpZiAoZXh0ZW5zaW9ucyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvbnMudmFsdWVPZkV4dGVuZGVkS2V5VXNhZ2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0QmFzaWNDb25zdHJhaW50cygpIHsKKyAgICAgICAgaWYgKGV4dGVuc2lvbnMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIEludGVnZXIuTUFYX1ZBTFVFOworICAgICAgICB9CisgICAgICAgIHJldHVybiBleHRlbnNpb25zLnZhbHVlT2ZCYXNpY0NvbnN0cmFpbnMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQ29sbGVjdGlvbjxMaXN0PD8+PiBnZXRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcygpIHRocm93cyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24geworICAgICAgICBpZiAoZXh0ZW5zaW9ucyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gUmV0cmlldmUgdGhlIGV4dGVuc2lvbiB2YWx1ZSBmcm9tIHRoZSBjYWNoZWQgZXh0ZW5zaW9ucyBvYmplY3QKKyAgICAgICAgICAgIC8vIFRoaXMgZXh0ZW5zaW9uIGlzIG5vdCBjaGVja2VkIGZvciBjb3JyZWN0bmVzcyBkdXJpbmcKKyAgICAgICAgICAgIC8vIGNlcnRpZmljYXRlIGdlbmVyYXRpb24sIHNvIG5vdyBpdCBjYW4gdGhyb3cgZXhjZXB0aW9uCisgICAgICAgICAgICByZXR1cm4gZXh0ZW5zaW9ucy52YWx1ZU9mU3ViamVjdEFsdGVybmF0aXZlTmFtZSgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlI2dldElzc3VlckFsdGVybmF0aXZlTmFtZXMoKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBDb2xsZWN0aW9uPExpc3Q8Pz4+IGdldElzc3VlckFsdGVybmF0aXZlTmFtZXMoKSB0aHJvd3MgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGV4dGVuc2lvbnMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFJldHJpZXZlIHRoZSBleHRlbnNpb24gdmFsdWUgZnJvbSB0aGUgY2FjaGVkIGV4dGVuc2lvbnMgb2JqZWN0CisgICAgICAgICAgICAvLyBUaGlzIGV4dGVuc2lvbiBpcyBub3QgY2hlY2tlZCBmb3IgY29ycmVjdG5lc3MgZHVyaW5nCisgICAgICAgICAgICAvLyBjZXJ0aWZpY2F0ZSBnZW5lcmF0aW9uLCBzbyBub3cgaXQgY2FuIHRocm93IGV4Y2VwdGlvbgorICAgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvbnMudmFsdWVPZklzc3VlckFsdGVybmF0aXZlTmFtZSgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGdldEVuY29kZWRJbnRlcm5hbCgpLmNsb25lKCk7CisgICAgfQorICAgIHByaXZhdGUgYnl0ZVtdIGdldEVuY29kZWRJbnRlcm5hbCgpIHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IGVuY29kaW5nOworICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSByZXN1bHQgPSBjZXJ0aWZpY2F0ZS5nZXRFbmNvZGVkKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFB1YmxpY0tleSBnZXRQdWJsaWNLZXkoKSB7CisgICAgICAgIFB1YmxpY0tleSByZXN1bHQgPSBwdWJsaWNLZXk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgcHVibGljS2V5ID0gcmVzdWx0ID0gdGJzQ2VydC5nZXRTdWJqZWN0UHVibGljS2V5SW5mbygpLmdldFB1YmxpY0tleSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBjZXJ0aWZpY2F0ZS50b1N0cmluZygpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCB2ZXJpZnkoUHVibGljS2V5IGtleSkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBJbnZhbGlkS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisKKyAgICAgICAgU2lnbmF0dXJlIHNpZ25hdHVyZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZ25hdHVyZSA9IE9wZW5TU0xTaWduYXR1cmUuZ2V0SW5zdGFuY2UoZ2V0U2lnQWxnTmFtZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgIHNpZ25hdHVyZSA9IFNpZ25hdHVyZS5nZXRJbnN0YW5jZShnZXRTaWdBbGdOYW1lKCkpOworICAgICAgICB9CisgICAgICAgIHNpZ25hdHVyZS5pbml0VmVyaWZ5KGtleSk7CisgICAgICAgIC8vIHJldHJpZXZlIHRoZSBlbmNvZGluZyBvZiB0aGUgVEJTQ2VydGlmaWNhdGUgc3RydWN0dXJlCisgICAgICAgIGJ5dGVbXSB0YnNDZXJ0aWZpY2F0ZUxvY2FsID0gZ2V0VGJzQ2VydGlmaWNhdGVJbnRlcm5hbCgpOworICAgICAgICAvLyBjb21wdXRlIGFuZCB2ZXJpZnkgdGhlIHNpZ25hdHVyZQorICAgICAgICBzaWduYXR1cmUudXBkYXRlKHRic0NlcnRpZmljYXRlTG9jYWwsIDAsIHRic0NlcnRpZmljYXRlTG9jYWwubGVuZ3RoKTsKKyAgICAgICAgaWYgKCFzaWduYXR1cmUudmVyaWZ5KGNlcnRpZmljYXRlLmdldFNpZ25hdHVyZVZhbHVlKCkpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU2lnbmF0dXJlRXhjZXB0aW9uKCJTaWduYXR1cmUgd2FzIG5vdCB2ZXJpZmllZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5LCBTdHJpbmcgc2lnUHJvdmlkZXIpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLCBTaWduYXR1cmVFeGNlcHRpb24geworCisgICAgICAgIFNpZ25hdHVyZSBzaWduYXR1cmU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoc2lnUHJvdmlkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNpZ25hdHVyZSA9IE9wZW5TU0xTaWduYXR1cmUuZ2V0SW5zdGFuY2UoZ2V0U2lnQWxnTmFtZSgpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc2lnbmF0dXJlID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKGdldFNpZ0FsZ05hbWUoKSwgc2lnUHJvdmlkZXIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgc2lnbmF0dXJlID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKGdldFNpZ0FsZ05hbWUoKSwgc2lnUHJvdmlkZXIpOworICAgICAgICB9CisgICAgICAgIHNpZ25hdHVyZS5pbml0VmVyaWZ5KGtleSk7CisgICAgICAgIC8vIHJldHJpZXZlIHRoZSBlbmNvZGluZyBvZiB0aGUgVEJTQ2VydGlmaWNhdGUgc3RydWN0dXJlCisgICAgICAgIGJ5dGVbXSB0YnNDZXJ0aWZpY2F0ZUxvY2FsID0gZ2V0VGJzQ2VydGlmaWNhdGVJbnRlcm5hbCgpOworICAgICAgICAvLyBjb21wdXRlIGFuZCB2ZXJpZnkgdGhlIHNpZ25hdHVyZQorICAgICAgICBzaWduYXR1cmUudXBkYXRlKHRic0NlcnRpZmljYXRlTG9jYWwsIDAsIHRic0NlcnRpZmljYXRlTG9jYWwubGVuZ3RoKTsKKyAgICAgICAgaWYgKCFzaWduYXR1cmUudmVyaWZ5KGNlcnRpZmljYXRlLmdldFNpZ25hdHVyZVZhbHVlKCkpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU2lnbmF0dXJlRXhjZXB0aW9uKCJTaWduYXR1cmUgd2FzIG5vdCB2ZXJpZmllZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTZXQ8U3RyaW5nPiBnZXROb25Dcml0aWNhbEV4dGVuc2lvbk9JRHMoKSB7CisgICAgICAgIGlmIChleHRlbnNpb25zID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIC8vIHJldHJpZXZlIHRoZSBpbmZvIGZyb20gdGhlIGNhY2hlZCBleHRlbnNpb25zIG9iamVjdAorICAgICAgICByZXR1cm4gZXh0ZW5zaW9ucy5nZXROb25Dcml0aWNhbEV4dGVuc2lvbnMoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFNldDxTdHJpbmc+IGdldENyaXRpY2FsRXh0ZW5zaW9uT0lEcygpIHsKKyAgICAgICAgaWYgKGV4dGVuc2lvbnMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgLy8gcmV0cmlldmUgdGhlIGluZm8gZnJvbSB0aGUgY2FjaGVkIGV4dGVuc2lvbnMgb2JqZWN0CisgICAgICAgIHJldHVybiBleHRlbnNpb25zLmdldENyaXRpY2FsRXh0ZW5zaW9ucygpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYnl0ZVtdIGdldEV4dGVuc2lvblZhbHVlKFN0cmluZyBvaWQpIHsKKyAgICAgICAgaWYgKGV4dGVuc2lvbnMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgLy8gcmV0cmlldmUgdGhlIGluZm8gZnJvbSB0aGUgY2FjaGVkIGV4dGVuc2lvbnMgb2JqZWN0CisgICAgICAgIEV4dGVuc2lvbiBleHQgPSBleHRlbnNpb25zLmdldEV4dGVuc2lvbkJ5T0lEKG9pZCk7CisgICAgICAgIHJldHVybiAoZXh0ID09IG51bGwpID8gbnVsbCA6IGV4dC5nZXRSYXdFeHRuVmFsdWUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzVW5zdXBwb3J0ZWRDcml0aWNhbEV4dGVuc2lvbigpIHsKKyAgICAgICAgaWYgKGV4dGVuc2lvbnMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIC8vIHJldHJpZXZlIHRoZSBpbmZvIGZyb20gdGhlIGNhY2hlZCBleHRlbnNpb25zIG9iamVjdAorICAgICAgICByZXR1cm4gZXh0ZW5zaW9ucy5oYXNVbnN1cHBvcnRlZENyaXRpY2FsKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Byb3ZpZGVyL2NlcnQvWDUwOUNlcnRQYXRoSW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jZXJ0L1g1MDlDZXJ0UGF0aEltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNjVkMzQ1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jZXJ0L1g1MDlDZXJ0UGF0aEltcGwuamF2YQpAQCAtMCwwICsxLDQxNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wcm92aWRlci5jZXJ0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xQW55OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFFeHBsaWNpdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xSW1wbGljaXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMU9pZDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2VxdWVuY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlT2Y7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVR5cGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQmVySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnBrY3M3LkNvbnRlbnRJbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wa2NzNy5TaWduZWREYXRhOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LkNlcnRpZmljYXRlOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgWC41MDkgQ2VydFBhdGguIFRoaXMgaW1wbGVtZW50YXRpb24KKyAqIHByb3ZpZGVzIGFiaWxpdHkgdG8gY3JlYXRlIHRoZSBpbnN0YW5jZSBvZiBYLjUwOSBDZXJ0aWZpY2F0aW9uIFBhdGgKKyAqIGJ5IHNldmVyYWwgbWVhbnM6PGJyPgorICoKKyAqICZuYnNwOyAgMS4gSXQgY2FuIGJlIGNyZWF0ZWQgb3ZlciB0aGUgbGlzdCBvZiBYLjUwOSBjZXJ0aWZpY2F0ZXMKKyAqIChpbXBsZW1lbnRhdGlvbnMgb2YgWDUwOUNlcnRpZmljYXRlIGNsYXNzKSBwcm92aWRlZCBpbiBjb25zdHJ1Y3Rvci48YnI+CisgKgorICogJm5ic3A7ICAyLiBJdCBjYW4gYmUgY3JlYXRlZCBieSBtZWFucyBvZiA8Y29kZT5nZXRJbnN0YW5jZTwvY29kZT4gbWV0aG9kcworICogb24gdGhlIGJhc2Ugb2YgdGhlIGZvbGxvd2luZyBBU04uMSBERVIgZW5jb2RlZCBmb3Jtczo8YnI+CisgKgorICogJm5ic3A7Jm5ic3A7ICAtIFBraVBhdGggYXMgZGVmaW5lZCBpbgorICogSVRVLVQgUmVjb21tZW5kYXRpb24gWC41MDkoMjAwMCkgQ29ycmlnZW5kdW0gMSgyMDAxKQorICogKGNhbiBiZSBzZWVuIGF0CisgKiBmdHA6Ly9mdHAuYnVsbC5jb20vcHViL09TSWRpcmVjdG9yeS9EZWZlY3RSZXNvbHV0aW9uL1RlY2huaWNhbENvcnJpZ2VuZGEvQXBwcm92ZWRUZWNobmljYWxDb3JyaWdlbmRhVG9YLjUwOS84JTdDWC41MDktVEMxKDR0aCkucGRmKQorICogPGJyPgorICogJm5ic3A7Jm5ic3A7ICAtIFBLQ1MgIzcgU2lnbmVkRGF0YSBvYmplY3QgcHJvdmlkZWQgaW4gdGhlIGZvcm0gb2YKKyAqIENvbnRlbnRJbmZvIHN0cnVjdHVyZS4gQ2VydFBhdGggb2JqZWN0IGlzIGdlbmVyYXRlZCBvbiB0aGUgYmFzZSBvZgorICogY2VydGlmaWNhdGVzIHByZXNlbnRlZCBpbiA8Y29kZT5jZXJ0aWZpY2F0ZXM8L2NvZGU+IGZpZWxkIG9mIHRoZSBTaWduZWREYXRhCisgKiBvYmplY3Qgd2hpY2ggaW4gaXRzIHR1cm4gaXMgcmV0cmlldmVkIGZyb20gQ29udGVudEluZm8gc3RydWN0dXJlLgorICogKHNlZSBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzE1LnR4dAorICogZm9yIG1vcmUgaW5mbyBvbiBQS0NTICM3KQorICogPGJyPgorICogJm5ic3A7CisgKi8KK3B1YmxpYyBjbGFzcyBYNTA5Q2VydFBhdGhJbXBsIGV4dGVuZHMgQ2VydFBhdGggeworCisgICAgLyoqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDc5ODk3NTUxMDYyMDk1MTU0MzZMOworCisgICAgLy8gc3VwcG9ydGVkIGVuY29kaW5nIHR5cGVzOgorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBLSV9QQVRIID0gMDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQS0NTNyA9IDE7CisKKyAgICAvLyBzdXBwb3J0ZWQgZW5jb2RpbmcgbmFtZXMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBlbmNvZGluZ3NBcnIgPSBuZXcgU3RyaW5nW10geyJQa2lQYXRoIiwgIlBLQ1M3In07CisgICAgc3RhdGljIGZpbmFsIExpc3QgZW5jb2RpbmdzID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChBcnJheXMuYXNMaXN0KGVuY29kaW5nc0FycikpOworICAgIC8vIHRoZSBsaXN0IG9mIGNlcnRpZmljYXRlcyByZXByZXNlbnRpbmcgdGhpcyBjZXJ0aWZpY2F0aW9uIHBhdGgKKyAgICBwcml2YXRlIGZpbmFsIExpc3QgY2VydGlmaWNhdGVzOworICAgIC8vIFBraVBhdGggZW5jb2Rpbmcgb2YgdGhlIGNlcnRpZmljYXRpb24gcGF0aAorICAgIHByaXZhdGUgYnl0ZVtdIHBraVBhdGhFbmNvZGluZzsKKyAgICAvLyBQS0NTNyBlbmNvZGluZyBvZiB0aGUgY2VydGlmaWNhdGlvbiBwYXRoCisgICAgcHJpdmF0ZSBieXRlW10gcGtjczdFbmNvZGluZzsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgWC41MDkgQ2VydGlmaWNhdGlvbiBQYXRoIG92ZXIgdGhlIHNwZWNpZmllZAorICAgICAqIGxpc3Qgb2YgY2VydGlmaWNhdGVzLgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24gaWYgc29tZSBvZiB0aGUgb2JqZWN0IGluIHRoZSBsaXN0CisgICAgICogaXMgbm90IGFuIGluc3RhbmNlIG9mIHN1YmNsYXNzIG9mIFg1MDlDZXJ0aWZpY2F0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgWDUwOUNlcnRQYXRoSW1wbChMaXN0IGNlcnRzKSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBzdXBlcigiWC41MDkiKTsKKyAgICAgICAgaW50IHNpemUgPSBjZXJ0cy5zaXplKCk7CisgICAgICAgIGNlcnRpZmljYXRlcyA9IG5ldyBBcnJheUxpc3Qoc2l6ZSk7CisgICAgICAgIGZvciAoaW50IGk9MDsgaTxzaXplOyBpKyspIHsKKyAgICAgICAgICAgIE9iamVjdCBjZXJ0ID0gY2VydHMuZ2V0KGkpOworICAgICAgICAgICAgaWYgKCEoY2VydCBpbnN0YW5jZW9mIFg1MDlDZXJ0aWZpY2F0ZSkgKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgIk9uZSBvZiB0aGUgcHJvdmlkZWQgY2VydGlmaWNhdGVzIGlzIG5vdCBhbiBYNTA5IGNlcnRpZmljYXRlIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjZXJ0aWZpY2F0ZXMuYWRkKGNlcnQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBJbnRlcm5hbGx5IHVzZWQgY29uc3RydWN0b3IuCisgICAgICogQ3JlYXRlcyBhbiBYLjUwOSBDZXJ0aWZpY2F0aW9uIFBhdGggb3ZlciB0aGUgc3BlY2lmaWVkCisgICAgICogbGlzdCBvZiBjZXJ0aWZpY2F0ZXMgYW5kIHRoZWlyIGVuY29kZWQgZm9ybSBvZiBzcGVjaWZpZWQgdHlwZS4KKyAgICAgKiBAcGFyYW0gY2VydHMgLSB0aGUgbGlzdCBvZiBjZXJ0aWZpY2F0ZXMKKyAgICAgKiBAcGFyYW0gdHlwZSAtIHRoZSB0eXBlIG9mIHRoZSBlbmNvZGVkIGZvcm0gb24gdGhlIGJhc2Ugb2Ygd2hpY2gKKyAgICAgKiB0aGlzIGxpc3Qgb2YgY2VydGlmaWNhdGVzIGhhZCBiZWVuIGJ1aWx0LgorICAgICAqIEBwYXJhbSBlbmNvZGluZyAtIGVuY29kZWQgZm9ybSBvZiBjZXJ0aWZpY2F0aW9uIHBhdGguCisgICAgICovCisgICAgcHJpdmF0ZSBYNTA5Q2VydFBhdGhJbXBsKExpc3QgY2VydHMsIGludCB0eXBlLCBieXRlW10gZW5jb2RpbmcpIHsKKyAgICAgICAgc3VwZXIoIlguNTA5Iik7CisgICAgICAgIGlmICh0eXBlID09IFBLSV9QQVRIKSB7CisgICAgICAgICAgICB0aGlzLnBraVBhdGhFbmNvZGluZyA9IGVuY29kaW5nOworICAgICAgICB9IGVsc2UgeyAvLyBQS0NTNworICAgICAgICAgICAgdGhpcy5wa2NzN0VuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgICAgIH0KKyAgICAgICAgLy8gV2UgZG8gbm90IG5lZWQgdGhlIHR5cGUgY2hlY2sgYW5kIGxpc3QgY2xvbmluZyBoZXJlLAorICAgICAgICAvLyBiZWNhdXNlIGl0IGhhcyBiZWVuIGRvbmUgZHVyaW5nIGRlY29kaW5nLgorICAgICAgICBjZXJ0aWZpY2F0ZXMgPSBjZXJ0czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgY2VydGlmaWNhdGlvbiBwYXRoIG9iamVjdCBvbiB0aGUgYmFzZSBvZiBQa2lQYXRoCisgICAgICogZW5jb2RlZCBmb3JtIHByb3ZpZGVkIHZpYSBpbnB1dCBzdHJlYW0uCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBpZiBzb21lIHByb2JsZW1zIG9jY3VycmVkIGR1cmluZworICAgICAqIHRoZSBkZWNvZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFg1MDlDZXJ0UGF0aEltcGwgZ2V0SW5zdGFuY2UoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gKFg1MDlDZXJ0UGF0aEltcGwpIEFTTjEuZGVjb2RlKGluKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKCJJbmNvcnJlY3QgZW5jb2RlZCBmb3JtOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGNlcnRpZmljYXRpb24gcGF0aCBvYmplY3Qgb24gdGhlIGJhc2Ugb2YgZW5jb2RpbmcgcHJvdmlkZWQgdmlhCisgICAgICogaW5wdXQgc3RyZWFtLiBUaGUgZm9ybWF0IG9mIHByb3ZpZGVkIGVuY29kZWQgZm9ybSBpcyBzcGVjaWZpZWQgYnkKKyAgICAgKiBwYXJhbWV0ZXIgPGNvZGU+ZW5jb2Rpbmc8L2NvZGU+LgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24gaWYgc3BlY2lmaWVkIGVuY29kaW5nIGZvcm0gaXMgbm90IHN1cHBvcnRlZCwKKyAgICAgKiBvciBzb21lIHByb2JsZW1zIG9jY3VycmVkIGR1cmluZyB0aGUgZGVjb2RpbmcuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBYNTA5Q2VydFBhdGhJbXBsIGdldEluc3RhbmNlKElucHV0U3RyZWFtIGluLCBTdHJpbmcgZW5jb2RpbmcpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBpZiAoIWVuY29kaW5ncy5jb250YWlucyhlbmNvZGluZykpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigiVW5zdXBwb3J0ZWQgZW5jb2RpbmciKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGVuY29kaW5nc0FyclswXS5lcXVhbHMoZW5jb2RpbmcpKSB7CisgICAgICAgICAgICAgICAgLy8gZ2VuZXJhdGUgdGhlIG9iamVjdCBmcm9tIFBraVBhdGggZW5jb2RlZCBmb3JtCisgICAgICAgICAgICAgICAgcmV0dXJuIChYNTA5Q2VydFBhdGhJbXBsKSBBU04xLmRlY29kZShpbik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIGdlbmVyYXRlIHRoZSBvYmplY3QgZnJvbSBQS0NTICM3IGVuY29kZWQgZm9ybQorICAgICAgICAgICAgICAgIENvbnRlbnRJbmZvIGNpID0gKENvbnRlbnRJbmZvKSBDb250ZW50SW5mby5BU04xLmRlY29kZShpbik7CisgICAgICAgICAgICAgICAgU2lnbmVkRGF0YSBzZCA9IGNpLmdldFNpZ25lZERhdGEoKTsKKyAgICAgICAgICAgICAgICBpZiAoc2QgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkluY29ycmVjdCBQS0NTNyBlbmNvZGVkIGZvcm06IG1pc3Npbmcgc2lnbmVkIGRhdGEiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgTGlzdDxDZXJ0aWZpY2F0ZT4gY2VydHMgPSBzZC5nZXRDZXJ0aWZpY2F0ZXMoKTsKKyAgICAgICAgICAgICAgICBpZiAoY2VydHMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAvLyBlbXB0eSBjaGFpbiBvZiBjZXJ0aWZpY2F0ZXMKKyAgICAgICAgICAgICAgICAgICAgY2VydHMgPSBuZXcgQXJyYXlMaXN0PENlcnRpZmljYXRlPigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBMaXN0PFg1MDlDZXJ0SW1wbD4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxYNTA5Q2VydEltcGw+KCk7CisgICAgICAgICAgICAgICAgZm9yIChDZXJ0aWZpY2F0ZSBjZXJ0IDogY2VydHMpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChuZXcgWDUwOUNlcnRJbXBsKGNlcnQpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBYNTA5Q2VydFBhdGhJbXBsKHJlc3VsdCwgUEtDUzcsIGNpLmdldEVuY29kZWQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigiSW5jb3JyZWN0IGVuY29kZWQgZm9ybTogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdlbmVyYXRlcyBjZXJ0aWZpY2F0aW9uIHBhdGggb2JqZWN0IG9uIHRoZSBiYXNlIG9mIFBraVBhdGgKKyAgICAgKiBlbmNvZGVkIGZvcm0gcHJvdmlkZWQgdmlhIGFycmF5IG9mIGJ5dGVzLgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24gaWYgc29tZSBwcm9ibGVtcyBvY2N1cnJlZCBkdXJpbmcKKyAgICAgKiB0aGUgZGVjb2RpbmcuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBYNTA5Q2VydFBhdGhJbXBsIGdldEluc3RhbmNlKGJ5dGVbXSBpbikgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiAoWDUwOUNlcnRQYXRoSW1wbCkgQVNOMS5kZWNvZGUoaW4pOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oIkluY29ycmVjdCBlbmNvZGVkIGZvcm06ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZXMgY2VydGlmaWNhdGlvbiBwYXRoIG9iamVjdCBvbiB0aGUgYmFzZSBvZiBlbmNvZGluZyBwcm92aWRlZCB2aWEKKyAgICAgKiBhcnJheSBvZiBieXRlcy4gVGhlIGZvcm1hdCBvZiBwcm92aWRlZCBlbmNvZGVkIGZvcm0gaXMgc3BlY2lmaWVkIGJ5CisgICAgICogcGFyYW1ldGVyIDxjb2RlPmVuY29kaW5nPC9jb2RlPi4KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIGlmIHNwZWNpZmllZCBlbmNvZGluZyBmb3JtIGlzIG5vdCBzdXBwb3J0ZWQsCisgICAgICogb3Igc29tZSBwcm9ibGVtcyBvY2N1cnJlZCBkdXJpbmcgdGhlIGRlY29kaW5nLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgWDUwOUNlcnRQYXRoSW1wbCBnZXRJbnN0YW5jZShieXRlW10gaW4sIFN0cmluZyBlbmNvZGluZykKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghZW5jb2RpbmdzLmNvbnRhaW5zKGVuY29kaW5nKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKCJVbnN1cHBvcnRlZCBlbmNvZGluZyIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoZW5jb2RpbmdzQXJyWzBdLmVxdWFscyhlbmNvZGluZykpIHsKKyAgICAgICAgICAgICAgICAvLyBnZW5lcmF0ZSB0aGUgb2JqZWN0IGZyb20gUGtpUGF0aCBlbmNvZGVkIGZvcm0KKyAgICAgICAgICAgICAgICByZXR1cm4gKFg1MDlDZXJ0UGF0aEltcGwpIEFTTjEuZGVjb2RlKGluKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gZ2VuZXJhdGUgdGhlIG9iamVjdCBmcm9tIFBLQ1MgIzcgZW5jb2RlZCBmb3JtCisgICAgICAgICAgICAgICAgQ29udGVudEluZm8gY2kgPSAoQ29udGVudEluZm8pIENvbnRlbnRJbmZvLkFTTjEuZGVjb2RlKGluKTsKKyAgICAgICAgICAgICAgICBTaWduZWREYXRhIHNkID0gY2kuZ2V0U2lnbmVkRGF0YSgpOworICAgICAgICAgICAgICAgIGlmIChzZCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigiSW5jb3JyZWN0IFBLQ1M3IGVuY29kZWQgZm9ybTogbWlzc2luZyBzaWduZWQgZGF0YSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBMaXN0PENlcnRpZmljYXRlPiBjZXJ0cyA9IHNkLmdldENlcnRpZmljYXRlcygpOworICAgICAgICAgICAgICAgIGlmIChjZXJ0cyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGNlcnRzID0gbmV3IEFycmF5TGlzdDxDZXJ0aWZpY2F0ZT4oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgTGlzdDxYNTA5Q2VydEltcGw+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8WDUwOUNlcnRJbXBsPigpOworICAgICAgICAgICAgICAgIGZvciAoQ2VydGlmaWNhdGUgY2VydCA6IGNlcnRzKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQobmV3IFg1MDlDZXJ0SW1wbChjZXJ0KSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBuZXcgWDUwOUNlcnRQYXRoSW1wbChyZXN1bHQsIFBLQ1M3LCBjaS5nZXRFbmNvZGVkKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oIkluY29ycmVjdCBlbmNvZGVkIGZvcm06ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAvLyAtLS0tIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aCBhYnN0cmFjdCBtZXRob2QgaW1wbGVtZW50YXRpb25zIC0tLS0KKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoI2dldENlcnRpZmljYXRlcygpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mbworICAgICAqLworICAgIHB1YmxpYyBMaXN0IGdldENlcnRpZmljYXRlcygpIHsKKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoY2VydGlmaWNhdGVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aCNnZXRFbmNvZGVkKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgdGhyb3dzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24geworICAgICAgICBpZiAocGtpUGF0aEVuY29kaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIHBraVBhdGhFbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtwa2lQYXRoRW5jb2RpbmcubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShwa2lQYXRoRW5jb2RpbmcsIDAsIHJlc3VsdCwgMCwgcGtpUGF0aEVuY29kaW5nLmxlbmd0aCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGgjZ2V0RW5jb2RlZChTdHJpbmcpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mbworICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZChTdHJpbmcgZW5jb2RpbmcpIHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFlbmNvZGluZ3MuY29udGFpbnMoZW5jb2RpbmcpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbigiVW5zdXBwb3J0ZWQgZW5jb2RpbmciKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZW5jb2RpbmdzQXJyWzBdLmVxdWFscyhlbmNvZGluZykpIHsKKyAgICAgICAgICAgIC8vIFBraVBhdGggZW5jb2RlZCBmb3JtCisgICAgICAgICAgICByZXR1cm4gZ2V0RW5jb2RlZCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gUEtDUzcgZW5jb2RlZCBmb3JtCisgICAgICAgICAgICBpZiAocGtjczdFbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcGtjczdFbmNvZGluZyA9IFBLQ1M3X1NJR05FRF9EQVRBX09CSkVDVC5lbmNvZGUodGhpcyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbcGtjczdFbmNvZGluZy5sZW5ndGhdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShwa2NzN0VuY29kaW5nLCAwLCByZXN1bHQsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGtjczdFbmNvZGluZy5sZW5ndGgpOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoI2dldEVuY29kaW5ncygpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mbworICAgICAqLworICAgIHB1YmxpYyBJdGVyYXRvciBnZXRFbmNvZGluZ3MoKSB7CisgICAgICAgIHJldHVybiBlbmNvZGluZ3MuaXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBU04uMSBERVIgRW5jb2Rlci9EZWNvZGVyIGZvciBQa2lQYXRoIHN0cnVjdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZU9mIEFTTjEgPQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEFTTjFTZXF1ZW5jZU9mKEFTTjFBbnkuZ2V0SW5zdGFuY2UoKSkgeworCisgICAgICAgIC8qKgorICAgICAgICAgKiBCdWlsZHMgdGhlIGluc3RhbmNlIG9mIFg1MDlDZXJ0UGF0aEltcGwgb24gdGhlIGJhc2Ugb2YgdGhlIGxpc3QKKyAgICAgICAgICogb2YgQVNOLjEgZW5jb2RpbmdzIG9mIFguNTA5IGNlcnRpZmljYXRlcyBwcm92aWRlZCB2aWEKKyAgICAgICAgICogUGtpUGF0aCBzdHJ1Y3R1cmUuCisgICAgICAgICAqIFRoaXMgbWV0aG9kIHBhcnRpY2lwYXRlcyBpbiBkZWNvZGluZyBwcm9jZXNzLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgLy8gcmV0cmlldmUgdGhlIGRlY29kZWQgY29udGVudAorICAgICAgICAgICAgTGlzdCBlbmNvZGluZ3MgPSAoTGlzdCkgaW4uY29udGVudDsKKyAgICAgICAgICAgIGludCBzaXplID0gZW5jb2RpbmdzLnNpemUoKTsKKyAgICAgICAgICAgIExpc3QgY2VydGlmaWNhdGVzID0gbmV3IEFycmF5TGlzdChzaXplKTsKKyAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxzaXplOyBpKyspIHsKKyAgICAgICAgICAgICAgICAvLyBjcmVhdGUgdGhlIFguNTA5IGNlcnRpZmljYXRlIG9uIHRoZSBiYXNlIG9mIGl0cyBlbmNvZGVkIGZvcm0KKyAgICAgICAgICAgICAgICAvLyBhbmQgYWRkIGl0IHRvIHRoZSBsaXN0LgorICAgICAgICAgICAgICAgIGNlcnRpZmljYXRlcy5hZGQoCisgICAgICAgICAgICAgICAgICAgIG5ldyBYNTA5Q2VydEltcGwoKENlcnRpZmljYXRlKQorICAgICAgICAgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUuQVNOMS5kZWNvZGUoKGJ5dGVbXSkgZW5jb2RpbmdzLmdldChpKSkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIGNyZWF0ZSBhbmQgcmV0dXJuIHRoZSByZXN1bHRpbmcgb2JqZWN0CisgICAgICAgICAgICByZXR1cm4gbmV3IFg1MDlDZXJ0UGF0aEltcGwoCisgICAgICAgICAgICAgICAgICAgIGNlcnRpZmljYXRlcywgUEtJX1BBVEgsIGluLmdldEVuY29kZWQoKSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgQ29sbGVjdGlvbiBvZiB0aGUgZW5jb2RlZCBmb3JtIG9mIGNlcnRpZmljYXRlcyBjb250YWluZWQKKyAgICAgICAgICogaW4gdGhlIFg1MDlDZXJ0UGF0aEltcGwgb2JqZWN0IHRvIGJlIGVuY29kZWQuCisgICAgICAgICAqIFRoaXMgbWV0aG9kIHBhcnRpY2lwYXRlcyBpbiBlbmNvZGluZyBwcm9jZXNzLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIENvbGxlY3Rpb24gZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIC8vIG9iamVjdCB0byBiZSBlbmNvZGVkCisgICAgICAgICAgICBYNTA5Q2VydFBhdGhJbXBsIGNwID0gKFg1MDlDZXJ0UGF0aEltcGwpIG9iamVjdDsKKyAgICAgICAgICAgIC8vIGlmIGl0IGhhcyBubyBjZXJ0aWZpY2F0ZXMgaW4gaXQgLSBjcmVhdGUgdGhlIHNlcXVlbmNlIG9mIHNpemUgMAorICAgICAgICAgICAgaWYgKGNwLmNlcnRpZmljYXRlcyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBzaXplID0gY3AuY2VydGlmaWNhdGVzLnNpemUoKTsKKyAgICAgICAgICAgIExpc3QgZW5jb2RpbmdzID0gbmV3IEFycmF5TGlzdChzaXplKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPHNpemU7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIGVuY29kZWQgZm9ybSBvZiBjZXJ0aWZpY2F0ZSBhbmQgcGxhY2UgaXQgaW50byB0aGUKKyAgICAgICAgICAgICAgICAgICAgLy8gbGlzdCB0byBiZSBlbmNvZGVkIGluIFBraVBhdGggZm9ybWF0CisgICAgICAgICAgICAgICAgICAgIGVuY29kaW5ncy5hZGQoKChYNTA5Q2VydGlmaWNhdGUpIGNwLmNlcnRpZmljYXRlcy5nZXQoaSkpLmdldEVuY29kZWQoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRW5jb2RpbmcgRXJyb3Igb2NjdXJyZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBlbmNvZGluZ3M7CisgICAgICAgIH0KKyAgICB9OworCisKKyAgICAvLworICAgIC8vIGVuY29kZXIgZm9yIFBLQ1MjNyBTaWduZWREYXRhCisgICAgLy8gaXQgaXMgYXNzdW1lZCB0aGF0IG9ubHkgY2VydGlmaWNhdGUgZmllbGQgaXMgaW1wb3J0YW50CisgICAgLy8gYWxsIG90aGVyIGZpZWxkcyBjb250YWluIHByZWNhbGN1bGF0ZWQgZW5jb2RpbmdzOgorICAgIC8vCisgICAgLy8gZW5jb2RlcyBYNTA5Q2VydFBhdGhJbXBsIG9iamVjdHMKKyAgICAvLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBBU04xX1NJR05FRF9EQVRBID0gbmV3IEFTTjFTZXF1ZW5jZSgKKyAgICAgICAgICAgIG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gdmVyc2lvbiAsZGlnZXN0QWxnb3JpdGhtcywgY29udGVudCBpbmZvCisgICAgICAgICAgICAgICAgICAgIEFTTjFBbnkuZ2V0SW5zdGFuY2UoKSwKKyAgICAgICAgICAgICAgICAgICAgLy8gY2VydGlmaWNhdGVzCisgICAgICAgICAgICAgICAgICAgIG5ldyBBU04xSW1wbGljaXQoMCwgQVNOMSksCisgICAgICAgICAgICAgICAgICAgIC8vIHNldCBvZiBjcmxzIGlzIG9wdGlvbmFsIGFuZCBpcyBtaXNzZWQgaGVyZQorICAgICAgICAgICAgICAgICAgICBBU04xQW55LmdldEluc3RhbmNlKCksLy8gc2lnbmVycyBpbmZvCisgICAgICAgICAgICB9KSB7CisKKyAgICAgICAgLy8gcHJlY2FsY3VsYXRlZCBBU04uMSBlbmNvZGluZ3MgZm9yCisgICAgICAgIC8vIHZlcnNpb24gLGRpZ2VzdEFsZ29yaXRobXMsIGNvbnRlbnQgaW5mbyBmaWVsZCBvZiBTaWduZWREYXRhCisgICAgICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIFBSRUNBTENVTEFURURfSEVBRCA9IG5ldyBieXRlW10geyAweDAyLCAweDAxLAorICAgICAgICAgICAgICAgIDB4MDEsLy8gdmVyc2lvbiAodjEpCisgICAgICAgICAgICAgICAgMHgzMSwgMHgwMCwvLyBlbXB0eSBzZXQgb2YgRGlnZXN0QWxnb3JpdGhtcworICAgICAgICAgICAgICAgIDB4MzAsIDB4MDMsIDB4MDYsIDB4MDEsIDB4MDAgLy8gZW1wdHkgQ29udGVudEluZm8gd2l0aCBvaWQ9MAorICAgICAgICB9OworCisgICAgICAgIC8vIHByZWNhbGN1bGF0ZWQgZW1wdHkgc2V0IG9mIFNpZ25lckluZm9zCisgICAgICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIFNJR05FUlNfSU5GTyA9IG5ldyBieXRlW10geyAweDMxLCAweDAwIH07CisKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykgeworICAgICAgICAgICAgdmFsdWVzWzBdID0gUFJFQ0FMQ1VMQVRFRF9IRUFEOworICAgICAgICAgICAgdmFsdWVzWzFdID0gb2JqZWN0OyAvLyBwYXNzIFg1MDlDZXJ0UGF0aEltcGwgb2JqZWN0CisgICAgICAgICAgICB2YWx1ZXNbMl0gPSBTSUdORVJTX0lORk87CisgICAgICAgIH0KKworICAgICAgICAvLyBzdHViIHRvIHByZXZlbnQgdXNpbmcgdGhlIGluc3RhbmNlIGFzIGRlY29kZXIKKyAgICAgICAgcHVibGljIE9iamVjdCBkZWNvZGUoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgdXNlIG9mIGVuY29kZXIgZm9yIFBLQ1MjNyBTaWduZWREYXRhIG9iamVjdCIpOworICAgICAgICB9CisgICAgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBQS0NTN19TSUdORURfREFUQV9PQkpFQ1QgPSBuZXcgQVNOMVNlcXVlbmNlKAorICAgICAgICAgICAgbmV3IEFTTjFUeXBlW10geyBBU04xQW55LmdldEluc3RhbmNlKCksIC8vIGNvbnRlbnRUeXBlCisgICAgICAgICAgICAgICAgICAgIG5ldyBBU04xRXhwbGljaXQoMCwgQVNOMV9TSUdORURfREFUQSkgLy8gU2lnbmVkRGF0YQorICAgICAgICAgICAgfSkgeworCisgICAgICAgIC8vIHByZWNhbGN1bGF0ZWQgQVNOLjEgZW5jb2RpbmcgZm9yIFNpZ25lZERhdGEgb2JqZWN0IG9pZAorICAgICAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBTSUdORURfREFUQV9PSUQgPSBBU04xT2lkLmdldEluc3RhbmNlKCkuZW5jb2RlKAorICAgICAgICAgICAgICAgIENvbnRlbnRJbmZvLlNJR05FRF9EQVRBKTsKKworICAgICAgICBwcm90ZWN0ZWQgdm9pZCBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCwgT2JqZWN0W10gdmFsdWVzKSB7CisgICAgICAgICAgICB2YWx1ZXNbMF0gPSBTSUdORURfREFUQV9PSUQ7CisgICAgICAgICAgICB2YWx1ZXNbMV0gPSBvYmplY3Q7IC8vIHBhc3MgWDUwOUNlcnRQYXRoSW1wbCBvYmplY3QKKyAgICAgICAgfQorCisgICAgICAgIC8vIHN0dWIgdG8gcHJldmVudCB1c2luZyB0aGUgaW5zdGFuY2UgYXMgZGVjb2RlcgorICAgICAgICBwdWJsaWMgT2JqZWN0IGRlY29kZShCZXJJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCB1c2Ugb2YgZW5jb2RlciBmb3IgUEtDUyM3IFNpZ25lZERhdGEgb2JqZWN0Iik7CisgICAgICAgIH0KKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vQ3J5cHRvUHJvdmlkZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY3J5cHRvL0NyeXB0b1Byb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzBhMjQ0OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY3J5cHRvL0NyeXB0b1Byb3ZpZGVyLmphdmEKQEAgLTAsMCArMSw4MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkucHJvdmlkZXIuY3J5cHRvOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKKworLyoqCisgKiBJbXBsZW1lbnRhdGlvbiBvZiBQcm92aWRlciBmb3IgU2VjdXJlUmFuZG9tLCBNZXNzYWdlRGlnZXN0IGFuZCBTaWduYXR1cmUKKyAqIHVzaW5nIGEgU2VjdXJlIEhhc2ggQWxnb3JpdGhtLCBTSEEtMTsKKyAqIHNlZSBTRUNVUkUgSEFTSCBTVEFOREFSRCwgRklQUyBQVUIgMTgwLTEgKGh0dHA6Ly93d3cuaXRsLm5pc3QuZ292L2ZpcHNwdWJzL2ZpcDE4MC0xLmh0bSkgPEJSPgorICogPEJSPgorICogVGhlIGltcGxlbWVudGF0aW9uIHN1cHBvcnRzICJTSEExUFJORyIsICJTSEEtMSIgYW5kICJTSEExd2l0aERTQSIgYWxnb3JpdGhtcyBkZXNjcmliZWQgaW4KKyAqIEphdmFUTSBDcnlwdG9ncmFwaHkgQXJjaGl0ZWN0dXJlLCBBUEkgU3BlY2lmaWNhdGlvbiAmIFJlZmVyZW5jZQorICovCisKK3B1YmxpYyBmaW5hbCBjbGFzcyBDcnlwdG9Qcm92aWRlciBleHRlbmRzIFByb3ZpZGVyIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDc5OTEyMDI4Njg0MjM0NTk1OThMOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIFByb3ZpZGVyIGFuZCBwdXRzIHBhcmFtZXRlcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgQ3J5cHRvUHJvdmlkZXIoKSB7CisKKyAgICAgICAgc3VwZXIoIkNyeXB0byIsIDEuMCwgIkhBUk1PTlkgKFNIQTEgZGlnZXN0OyBTZWN1cmVSYW5kb207IFNIQTF3aXRoRFNBIHNpZ25hdHVyZSkiKTsKKworICAgICAgICAvLyAgbmFtZXMgb2YgY2xhc3NlcyBpbXBsZW1lbnRpbmcgc2VydmljZXMKKyAgICAgICAgZmluYWwgU3RyaW5nIE1EX05BTUUgPSAib3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnByb3ZpZGVyLmNyeXB0by5TSEExX01lc3NhZ2VEaWdlc3RJbXBsIjsKKyAgICAgICAgZmluYWwgU3RyaW5nIFNSX05BTUUgPSAib3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnByb3ZpZGVyLmNyeXB0by5TSEExUFJOR19TZWN1cmVSYW5kb21JbXBsIjsKKworICAgICAgICBmaW5hbCBTdHJpbmcgU0lHTl9OQU1FID0gIm9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wcm92aWRlci5jcnlwdG8uU0hBMXdpdGhEU0FfU2lnbmF0dXJlSW1wbCI7CisKKyAgICAgICAgZmluYWwgU3RyaW5nIFNJR05fQUxJQVMgPSAiU0hBMXdpdGhEU0EiOworCisKKyAgICAgICAgZmluYWwgU3RyaW5nIEtFWUZfTkFNRSA9ICJvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkucHJvdmlkZXIuY3J5cHRvLkRTQUtleUZhY3RvcnlJbXBsIjsKKworICAgICAgICBwdXQoIk1lc3NhZ2VEaWdlc3QuU0hBLTEiLCBNRF9OQU1FKTsKKyAgICAgICAgcHV0KCJNZXNzYWdlRGlnZXN0LlNIQS0xIEltcGxlbWVudGVkSW4iLCAiU29mdHdhcmUiKTsKKyAgICAgICAgcHV0KCJBbGcuQWxpYXMuTWVzc2FnZURpZ2VzdC5TSEExIiwgIlNIQS0xIik7CisgICAgICAgIHB1dCgiQWxnLkFsaWFzLk1lc3NhZ2VEaWdlc3QuU0hBIiwgIlNIQS0xIik7CisKKyAgICAgICAgaWYgKFJhbmRvbUJpdHNTdXBwbGllci5pc1NlcnZpY2VBdmFpbGFibGUoKSkgeworICAgICAgICAgICAgcHV0KCJTZWN1cmVSYW5kb20uU0hBMVBSTkciLCBTUl9OQU1FKTsKKyAgICAgICAgICAgIHB1dCgiU2VjdXJlUmFuZG9tLlNIQTFQUk5HIEltcGxlbWVudGVkSW4iLCAiU29mdHdhcmUiKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1dCgiU2lnbmF0dXJlLlNIQTF3aXRoRFNBIiwgU0lHTl9OQU1FKTsKKyAgICAgICAgcHV0KCJTaWduYXR1cmUuU0hBMXdpdGhEU0EgSW1wbGVtZW50ZWRJbiIsICJTb2Z0d2FyZSIpOworICAgICAgICBwdXQoIkFsZy5BbGlhcy5TaWduYXR1cmUuU0hBd2l0aERTQSIsIFNJR05fQUxJQVMpOworICAgICAgICBwdXQoIkFsZy5BbGlhcy5TaWduYXR1cmUuRFNBd2l0aFNIQTEiLCBTSUdOX0FMSUFTKTsKKyAgICAgICAgcHV0KCJBbGcuQWxpYXMuU2lnbmF0dXJlLlNIQTEvRFNBIiwgU0lHTl9BTElBUyk7CisgICAgICAgIHB1dCgiQWxnLkFsaWFzLlNpZ25hdHVyZS5TSEEvRFNBIiwgU0lHTl9BTElBUyk7CisgICAgICAgIHB1dCgiQWxnLkFsaWFzLlNpZ25hdHVyZS5TSEEtMS9EU0EiLCBTSUdOX0FMSUFTKTsKKyAgICAgICAgcHV0KCJBbGcuQWxpYXMuU2lnbmF0dXJlLkRTQSIsIFNJR05fQUxJQVMpOworICAgICAgICBwdXQoIkFsZy5BbGlhcy5TaWduYXR1cmUuRFNTIiwgU0lHTl9BTElBUyk7CisKKyAgICAgICAgcHV0KCJBbGcuQWxpYXMuU2lnbmF0dXJlLk9JRC4xLjIuODQwLjEwMDQwLjQuMyIsIFNJR05fQUxJQVMpOworICAgICAgICBwdXQoIkFsZy5BbGlhcy5TaWduYXR1cmUuMS4yLjg0MC4xMDA0MC40LjMiLCBTSUdOX0FMSUFTKTsKKyAgICAgICAgcHV0KCJBbGcuQWxpYXMuU2lnbmF0dXJlLjEuMy4xNC4zLjIuMTMiLCBTSUdOX0FMSUFTKTsKKyAgICAgICAgcHV0KCJBbGcuQWxpYXMuU2lnbmF0dXJlLjEuMy4xNC4zLjIuMjciLCBTSUdOX0FMSUFTKTsKKworICAgICAgICBwdXQoIktleUZhY3RvcnkuRFNBIiwgS0VZRl9OQU1FKTsKKyAgICAgICAgcHV0KCJLZXlGYWN0b3J5LkRTQSBJbXBsZW1lbnRlZEluIiwgIlNvZnR3YXJlIik7CisgICAgICAgIHB1dCgiQWxnLkFsaWFzLktleUZhY3RvcnkuMS4zLjE0LjMuMi4xMiIsICJEU0EiKTsKKyAgICAgICAgcHV0KCJBbGcuQWxpYXMuS2V5RmFjdG9yeS4xLjIuODQwLjEwMDQwLjQuMSIsICJEU0EiKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Byb3ZpZGVyL2NyeXB0by9EU0FLZXlGYWN0b3J5SW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vRFNBS2V5RmFjdG9yeUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42OTBkMTZlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vRFNBS2V5RmFjdG9yeUltcGwuamF2YQpAQCAtMCwwICsxLDIxNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkucHJvdmlkZXIuY3J5cHRvOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5RmFjdG9yeVNwaTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLkRTQVBhcmFtczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuRFNBUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuRFNBUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5EU0FQcml2YXRlS2V5U3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRFNBUHVibGljS2V5U3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuSW52YWxpZEtleVNwZWNFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLktleVNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLlBLQ1M4RW5jb2RlZEtleVNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLlg1MDlFbmNvZGVkS2V5U3BlYzsKKworcHVibGljIGNsYXNzIERTQUtleUZhY3RvcnlJbXBsIGV4dGVuZHMgS2V5RmFjdG9yeVNwaSB7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBnZW5lcmF0ZXMgYSBEU0FQcml2YXRlS2V5IG9iamVjdCBmcm9tIHRoZSBwcm92aWRlZCBrZXkgc3BlY2lmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbQorICAgICAqICAgIGtleVNwZWMgLSB0aGUgc3BlY2lmaWNhdGlvbiAoa2V5IG1hdGVyaWFsKSBmb3IgdGhlIERTQVByaXZhdGVLZXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgYSBEU0FQcml2YXRlS2V5IG9iamVjdAorICAgICAqCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbgorICAgICAqICAgICBpZiAia2V5U3BlYyIgaXMgbmVpdGhlciBEU0FQcml2YXRlS2V5U3BlYyBub3IgUEtDUzhFbmNvZGVkS2V5U3BlYworICAgICAqLworICAgIHByb3RlY3RlZCBQcml2YXRlS2V5IGVuZ2luZUdlbmVyYXRlUHJpdmF0ZShLZXlTcGVjIGtleVNwZWMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24geworCisgICAgICAgIGlmIChrZXlTcGVjICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChrZXlTcGVjIGluc3RhbmNlb2YgRFNBUHJpdmF0ZUtleVNwZWMpIHsKKworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRFNBUHJpdmF0ZUtleUltcGwoKERTQVByaXZhdGVLZXlTcGVjKSBrZXlTcGVjKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChrZXlTcGVjIGluc3RhbmNlb2YgUEtDUzhFbmNvZGVkS2V5U3BlYykgeworCisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBEU0FQcml2YXRlS2V5SW1wbCgoUEtDUzhFbmNvZGVkS2V5U3BlYykga2V5U3BlYyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKCIna2V5U3BlYycgaXMgbmVpdGhlciBEU0FQcml2YXRlS2V5U3BlYyBub3IgUEtDUzhFbmNvZGVkS2V5U3BlYyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGdlbmVyYXRlcyBhIERTQVB1YmxpY0tleSBvYmplY3QgZnJvbSB0aGUgcHJvdmlkZWQga2V5IHNwZWNpZmljYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0KKyAgICAgKiAgICBrZXlTcGVjIC0gdGhlIHNwZWNpZmljYXRpb24gKGtleSBtYXRlcmlhbCkgZm9yIHRoZSBEU0FQdWJsaWNLZXkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgYSBEU0FQdWJsaWNLZXkgb2JqZWN0CisgICAgICoKKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICogICAgIGlmICJrZXlTcGVjIiBpcyBuZWl0aGVyIERTQVB1YmxpY0tleVNwZWMgbm9yIFg1MDlFbmNvZGVkS2V5U3BlYworICAgICAqLworICAgIHByb3RlY3RlZCBQdWJsaWNLZXkgZW5naW5lR2VuZXJhdGVQdWJsaWMoS2V5U3BlYyBrZXlTcGVjKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIHsKKworICAgICAgICBpZiAoa2V5U3BlYyAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoa2V5U3BlYyBpbnN0YW5jZW9mIERTQVB1YmxpY0tleVNwZWMpIHsKKworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRFNBUHVibGljS2V5SW1wbCgoRFNBUHVibGljS2V5U3BlYykga2V5U3BlYyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoa2V5U3BlYyBpbnN0YW5jZW9mIFg1MDlFbmNvZGVkS2V5U3BlYykgeworCisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBEU0FQdWJsaWNLZXlJbXBsKChYNTA5RW5jb2RlZEtleVNwZWMpIGtleVNwZWMpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbigiJ2tleVNwZWMnIGlzIG5laXRoZXIgRFNBUHVibGljS2V5U3BlYyBub3IgWDUwOUVuY29kZWRLZXlTcGVjIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhIHNwZWNpZmljYXRpb24gZm9yIHRoZSBzdXBwbGllZCBrZXkuCisgICAgICoKKyAgICAgKiBUaGUgc3BlY2lmaWNhdGlvbiB3aWxsIGJlIHJldHVybmVkIGluIHRoZSBmb3JtIG9mIGFuIG9iamVjdCBvZiB0aGUgdHlwZQorICAgICAqIHNwZWNpZmllZCBieSBrZXlTcGVjLgorICAgICAqCisgICAgICogQHBhcmFtIGtleSAtCisgICAgICogICAgICAgICAgICBlaXRoZXIgRFNBUHJpdmF0ZUtleSBvciBEU0FQdWJsaWNLZXkKKyAgICAgKiBAcGFyYW0ga2V5U3BlYyAtCisgICAgICogICAgICAgICAgICBlaXRoZXIgRFNBUHJpdmF0ZUtleVNwZWMuY2xhc3Mgb3IgRFNBUHVibGljS2V5U3BlYy5jbGFzcworICAgICAqCisgICAgICogQHJldHVybiBlaXRoZXIgYSBEU0FQcml2YXRlS2V5U3BlYyBvciBhIERTQVB1YmxpY0tleVNwZWMKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBpZiAia2V5U3BlYyIgaXMgbm90IGEgc3BlY2lmaWNhdGlvbiBmb3IgRFNBUHVibGljS2V5IG9yCisgICAgICogICAgICAgICAgICAgRFNBUHJpdmF0ZUtleQorICAgICAqLworICAgIHByb3RlY3RlZCA8VCBleHRlbmRzIEtleVNwZWM+IFQgZW5naW5lR2V0S2V5U3BlYyhLZXkga2V5LCBDbGFzczxUPiBrZXlTcGVjKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIHsKKworICAgICAgICBCaWdJbnRlZ2VyIHAsIHEsIGcsIHgsIHk7CisKKyAgICAgICAgaWYgKGtleSAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoa2V5U3BlYyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJrZXlTcGVjID09IG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChrZXkgaW5zdGFuY2VvZiBEU0FQcml2YXRlS2V5KSB7CisgICAgICAgICAgICAgICAgRFNBUHJpdmF0ZUtleSBwcml2YXRlS2V5ID0gKERTQVByaXZhdGVLZXkpIGtleTsKKworICAgICAgICAgICAgICAgIGlmIChrZXlTcGVjLmVxdWFscyhEU0FQcml2YXRlS2V5U3BlYy5jbGFzcykpIHsKKworICAgICAgICAgICAgICAgICAgICB4ID0gcHJpdmF0ZUtleS5nZXRYKCk7CisKKyAgICAgICAgICAgICAgICAgICAgRFNBUGFyYW1zIHBhcmFtcyA9IHByaXZhdGVLZXkuZ2V0UGFyYW1zKCk7CisKKyAgICAgICAgICAgICAgICAgICAgcCA9IHBhcmFtcy5nZXRQKCk7CisgICAgICAgICAgICAgICAgICAgIHEgPSBwYXJhbXMuZ2V0USgpOworICAgICAgICAgICAgICAgICAgICBnID0gcGFyYW1zLmdldEcoKTsKKworICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpIChuZXcgRFNBUHJpdmF0ZUtleVNwZWMoeCwgcCwgcSwgZykpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChrZXlTcGVjLmVxdWFscyhQS0NTOEVuY29kZWRLZXlTcGVjLmNsYXNzKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpIChuZXcgUEtDUzhFbmNvZGVkS2V5U3BlYyhrZXkuZ2V0RW5jb2RlZCgpKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKCIna2V5U3BlYycgaXMgbmVpdGhlciBEU0FQcml2YXRlS2V5U3BlYyBub3IgUEtDUzhFbmNvZGVkS2V5U3BlYyIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoa2V5IGluc3RhbmNlb2YgRFNBUHVibGljS2V5KSB7CisgICAgICAgICAgICAgICAgRFNBUHVibGljS2V5IHB1YmxpY0tleSA9IChEU0FQdWJsaWNLZXkpIGtleTsKKworICAgICAgICAgICAgICAgIGlmIChrZXlTcGVjLmVxdWFscyhEU0FQdWJsaWNLZXlTcGVjLmNsYXNzKSkgeworCisgICAgICAgICAgICAgICAgICAgIHkgPSBwdWJsaWNLZXkuZ2V0WSgpOworCisgICAgICAgICAgICAgICAgICAgIERTQVBhcmFtcyBwYXJhbXMgPSBwdWJsaWNLZXkuZ2V0UGFyYW1zKCk7CisKKyAgICAgICAgICAgICAgICAgICAgcCA9IHBhcmFtcy5nZXRQKCk7CisgICAgICAgICAgICAgICAgICAgIHEgPSBwYXJhbXMuZ2V0USgpOworICAgICAgICAgICAgICAgICAgICBnID0gcGFyYW1zLmdldEcoKTsKKworICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpIChuZXcgRFNBUHVibGljS2V5U3BlYyh5LCBwLCBxLCBnKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGtleVNwZWMuZXF1YWxzKFg1MDlFbmNvZGVkS2V5U3BlYy5jbGFzcykpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChUKSAobmV3IFg1MDlFbmNvZGVkS2V5U3BlYyhrZXkuZ2V0RW5jb2RlZCgpKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKCIna2V5U3BlYycgaXMgbmVpdGhlciBEU0FQdWJsaWNLZXlTcGVjIG5vciBYNTA5RW5jb2RlZEtleVNwZWMiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleVNwZWNFeGNlcHRpb24oIidrZXknIGlzIG5laXRoZXIgRFNBUHVibGljS2V5IG5vciBEU0FQcml2YXRlS2V5Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIG1ldGhvZCBnZW5lcmF0ZXMgYSBEU0FQdWJsaWNLZXkgb2JqZWN0IGZyb20gdGhlIHByb3ZpZGVkIGtleS4KKyAgICAgKgorICAgICAqIEBwYXJhbQorICAgICAqICAgIGtleSAtIGEgRFNBUHVibGljS2V5IG9iamVjdCBvciBEU0FQcml2YXRlS2V5IG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4KKyAgICAgKiAgICBvYmplY3Qgb2YgdGhlIHNhbWUgdHlwZSBhcyB0aGUgImtleSIgYXJndW1lbnQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqICAgICBpZiAia2V5IiBpcyBuZWl0aGVyIERTQVB1YmxpY0tleSBub3IgRFNBUHJpdmF0ZUtleQorICAgICAqLworICAgIHByb3RlY3RlZCBLZXkgZW5naW5lVHJhbnNsYXRlS2V5KEtleSBrZXkpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKworICAgICAgICBpZiAoa2V5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChrZXkgaW5zdGFuY2VvZiBEU0FQcml2YXRlS2V5KSB7CisKKyAgICAgICAgICAgICAgICBEU0FQcml2YXRlS2V5IHByaXZhdGVLZXkgPSAoRFNBUHJpdmF0ZUtleSkga2V5OworICAgICAgICAgICAgICAgIERTQVBhcmFtcyBwYXJhbXMgPSBwcml2YXRlS2V5LmdldFBhcmFtcygpOworCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVuZ2luZUdlbmVyYXRlUHJpdmF0ZShuZXcgRFNBUHJpdmF0ZUtleVNwZWMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpdmF0ZUtleS5nZXRYKCksIHBhcmFtcy5nZXRQKCksIHBhcmFtcy5nZXRRKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zLmdldEcoKSkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gQWN0dWFsbHkgdGhpcyBleGNlcHRpb24gc2hvdWxkbid0IGJlIHRocm93bgorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbigiQVRURU5USU9OOiBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbjogIiArIGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGtleSBpbnN0YW5jZW9mIERTQVB1YmxpY0tleSkgeworCisgICAgICAgICAgICAgICAgRFNBUHVibGljS2V5IHB1YmxpY0tleSA9IChEU0FQdWJsaWNLZXkpIGtleTsKKyAgICAgICAgICAgICAgICBEU0FQYXJhbXMgcGFyYW1zID0gcHVibGljS2V5LmdldFBhcmFtcygpOworCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVuZ2luZUdlbmVyYXRlUHVibGljKG5ldyBEU0FQdWJsaWNLZXlTcGVjKHB1YmxpY0tleQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRZKCksIHBhcmFtcy5nZXRQKCksIHBhcmFtcy5nZXRRKCksIHBhcmFtcworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRHKCkpKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIEFjdHVhbGx5IHRoaXMgZXhjZXB0aW9uIHNob3VsZG4ndCBiZSB0aHJvd24KKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oIkFUVEVOVElPTjogSW52YWxpZEtleVNwZWNFeGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oIidrZXknIGlzIG5laXRoZXIgRFNBUHVibGljS2V5IG5vciBEU0FQcml2YXRlS2V5Iik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Byb3ZpZGVyL2NyeXB0by9EU0FQcml2YXRlS2V5SW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vRFNBUHJpdmF0ZUtleUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMGZjNzY2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vRFNBUHJpdmF0ZUtleUltcGwuamF2YQpAQCAtMCwwICsxLDE1OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworIC8qCisgICogVE9ETworICAqIDEuIFRoZSBjbGFzcyBleHRlbmRzIHRoZSBQcml2YXRlS2V5SW1wbCBjbGFzcyBpbiAib3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5IiBwYWNrYWdlLgorICAqCisgICogMi4gU2VlIGEgY29tcGF0aWJpbGl0eSB3aXRoIFJJIGNvbW1lbnRzCisgICogICAgaW4gdGhlIGJlbG93ICJEU0FQcml2YXRlS2V5SW1wbChQS0NTOEVuY29kZWRLZXlTcGVjIGtleVNwZWMpIiBjb25zdHJ1Y3Rvci4KKyAgKi8KKworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wcm92aWRlci5jcnlwdG87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uTm90QWN0aXZlRXhjZXB0aW9uOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5EU0FQYXJhbXM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLkRTQVByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkRTQVBhcmFtZXRlclNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkRTQVByaXZhdGVLZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5JbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuUEtDUzhFbmNvZGVkS2V5U3BlYzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuUHJpdmF0ZUtleUltcGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUludGVnZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnBrY3M4LlByaXZhdGVLZXlJbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS51dGlscy5BbGdOYW1lTWFwcGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LkFsZ29yaXRobUlkZW50aWZpZXI7CisKKy8qKgorICogVGhlIGNsYXNzIHByb3ZpZGVzIERTQVByaXZhdGVLZXkgZnVuY3Rpb25hbGl0eSBieSBleHRlbmRpbmcgYSBjbGFzcyBpbXBsZW1lbnRpbmcgUHJpdmF0ZUtleQorICogYW5kIGltcGxlbWVudGluZyBtZXRob2RzIGRlZmluZWQgaW4gYm90aCBpbnRlcmZhY2VzLCBEU0FLZXkgYW5kIERTQVByaXZhdGVLZXkKKyAqLworcHVibGljIGNsYXNzIERTQVByaXZhdGVLZXlJbXBsIGV4dGVuZHMgUHJpdmF0ZUtleUltcGwgaW1wbGVtZW50cyBEU0FQcml2YXRlS2V5IHsKKworICAgIC8qKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDcxNjIyNzYxNDEwNDk1MDA4MUw7CisKKyAgICBwcml2YXRlIEJpZ0ludGVnZXIgeCwgZywgcCwgcTsKKworICAgIHByaXZhdGUgdHJhbnNpZW50IERTQVBhcmFtcyBwYXJhbXM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIG9iamVjdCBmcm9tIERTQVByaXZhdGVLZXlTcGVjLgorICAgICAqCisgICAgICogQHBhcmFtIGtleVNwZWMgLSBhIERTQVByaXZhdGVLZXlTcGVjIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBEU0FQcml2YXRlS2V5SW1wbChEU0FQcml2YXRlS2V5U3BlYyBrZXlTcGVjKSB7CisKKyAgICAgICAgc3VwZXIoIkRTQSIpOworCisgICAgICAgIFByaXZhdGVLZXlJbmZvIHBraTsKKworICAgICAgICBnID0ga2V5U3BlYy5nZXRHKCk7CisgICAgICAgIHAgPSBrZXlTcGVjLmdldFAoKTsKKyAgICAgICAgcSA9IGtleVNwZWMuZ2V0USgpOworCisgICAgICAgIFRocmVlSW50ZWdlclNlcXVlbmNlIHRocmVlSW50cyA9IG5ldyBUaHJlZUludGVnZXJTZXF1ZW5jZShwCisgICAgICAgICAgICAgICAgLnRvQnl0ZUFycmF5KCksIHEudG9CeXRlQXJyYXkoKSwgZy50b0J5dGVBcnJheSgpKTsKKworICAgICAgICBBbGdvcml0aG1JZGVudGlmaWVyIGFpID0gbmV3IEFsZ29yaXRobUlkZW50aWZpZXIoQWxnTmFtZU1hcHBlcgorICAgICAgICAgICAgICAgIC5tYXAyT0lEKCJEU0EiKSwKKyAgICAgICAgICAgICAgICB0aHJlZUludHMuZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgeCA9IGtleVNwZWMuZ2V0WCgpOworCisgICAgICAgIHBraSA9IG5ldyBQcml2YXRlS2V5SW5mbygwLCBhaSwgQVNOMUludGVnZXIuZ2V0SW5zdGFuY2UoKS5lbmNvZGUoCisgICAgICAgICAgICAgICAgeC50b0J5dGVBcnJheSgpKSwgbnVsbCk7CisKKyAgICAgICAgc2V0RW5jb2RpbmcocGtpLmdldEVuY29kZWQoKSk7CisKKyAgICAgICAgcGFyYW1zID0gbmV3IERTQVBhcmFtZXRlclNwZWMocCwgcSwgZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBvYmplY3QgZnJvbSBQS0NTOEVuY29kZWRLZXlTcGVjLgorICAgICAqCisgICAgICogQHBhcmFtIGtleVNwZWMgLSBhIFhQS0NTOEVuY29kZWRLZXlTcGVjIG9iamVjdAorICAgICAqCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiAtIGlmIGtleSBkYXRhIGNhbm5vdCBiZSBvYnRhaW4gZnJvbSBlbmNvZGVkIGZvcm1hdAorICAgICAqLworICAgIHB1YmxpYyBEU0FQcml2YXRlS2V5SW1wbChQS0NTOEVuY29kZWRLZXlTcGVjIGtleVNwZWMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24geworCisgICAgICAgIHN1cGVyKCJEU0EiKTsKKworICAgICAgICBBbGdvcml0aG1JZGVudGlmaWVyIGFpOworICAgICAgICBUaHJlZUludGVnZXJTZXF1ZW5jZSB0aHJlZUludHMgPSBudWxsOworCisgICAgICAgIFN0cmluZyBhbGcsIGFsZ05hbWU7CisKKyAgICAgICAgYnl0ZVtdIGVuY29kaW5nID0ga2V5U3BlYy5nZXRFbmNvZGVkKCk7CisKKyAgICAgICAgUHJpdmF0ZUtleUluZm8gcHJpdmF0ZUtleUluZm8gPSBudWxsOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcml2YXRlS2V5SW5mbyA9IChQcml2YXRlS2V5SW5mbykgUHJpdmF0ZUtleUluZm8uQVNOMQorICAgICAgICAgICAgICAgICAgICAuZGVjb2RlKGVuY29kaW5nKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKCJGYWlsZWQgdG8gZGVjb2RlIGtleVNwZWMgZW5jb2Rpbmc6ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB4ID0gbmV3IEJpZ0ludGVnZXIoKGJ5dGVbXSkgQVNOMUludGVnZXIuZ2V0SW5zdGFuY2UoKS5kZWNvZGUoCisgICAgICAgICAgICAgICAgICAgIHByaXZhdGVLZXlJbmZvLmdldFByaXZhdGVLZXkoKSkpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleVNwZWNFeGNlcHRpb24oIkZhaWxlZCB0byBkZWNvZGUgcGFyYW1ldGVyczogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgYWkgPSBwcml2YXRlS2V5SW5mby5nZXRBbGdvcml0aG1JZGVudGlmaWVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aHJlZUludHMgPSAoVGhyZWVJbnRlZ2VyU2VxdWVuY2UpIFRocmVlSW50ZWdlclNlcXVlbmNlLkFTTjEKKyAgICAgICAgICAgICAgICAgICAgLmRlY29kZShhaS5nZXRQYXJhbWV0ZXJzKCkpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleVNwZWNFeGNlcHRpb24oIkZhaWxlZCB0byBkZWNvZGUgcGFyYW1ldGVyczogIiArIGUpOworICAgICAgICB9CisgICAgICAgIHAgPSBuZXcgQmlnSW50ZWdlcih0aHJlZUludHMucCk7CisgICAgICAgIHEgPSBuZXcgQmlnSW50ZWdlcih0aHJlZUludHMucSk7CisgICAgICAgIGcgPSBuZXcgQmlnSW50ZWdlcih0aHJlZUludHMuZyk7CisgICAgICAgIHBhcmFtcyA9IG5ldyBEU0FQYXJhbWV0ZXJTcGVjKHAsIHEsIGcpOworICAgICAgICBzZXRFbmNvZGluZyhlbmNvZGluZyk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogdGhlIGZvbGxvd2luZyBjb2RlIGltcGxlbWVudHMgUkkgYmVoYXZpb3IKKyAgICAgICAgICovCisgICAgICAgIGFsZyA9IGFpLmdldEFsZ29yaXRobSgpOworICAgICAgICBhbGdOYW1lID0gQWxnTmFtZU1hcHBlci5tYXAyQWxnTmFtZShhbGcpOworICAgICAgICBzZXRBbGdvcml0aG0oYWxnTmFtZSA9PSBudWxsID8gYWxnIDogYWxnTmFtZSk7CisgICAgfQorCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0WCgpIHsKKyAgICAgICAgcmV0dXJuIHg7CisgICAgfQorCisgICAgcHVibGljIERTQVBhcmFtcyBnZXRQYXJhbXMoKSB7CisgICAgICAgIHJldHVybiBwYXJhbXM7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSBpbikgdGhyb3dzIE5vdEFjdGl2ZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBpbi5kZWZhdWx0UmVhZE9iamVjdCgpOworICAgICAgICBwYXJhbXMgPSBuZXcgRFNBUGFyYW1ldGVyU3BlYyhwLCBxLCBnKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY3J5cHRvL0RTQVB1YmxpY0tleUltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY3J5cHRvL0RTQVB1YmxpY0tleUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YjM1OTcwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vRFNBUHVibGljS2V5SW1wbC5qYXZhCkBAIC0wLDAgKzEsMTcxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisgLyoKKyAgKiBUT0RPCisgICogMS4gVGhlIGNsYXNzIGV4dGVuZHMgdGhlIFB1YmxpY0tleUltcGwgY2xhc3MgaW4gIm9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eSIgcGFja2FnZS4KKyAgKgorICAqIDIuIFRoZSBjbGFzcyB1c2VzIG1ldGhvZHMgaW4gdGhlIGF1eGlsaWFyeSBub24tcHVibGljICJUaHJlZUludGVnZXJTZXF1ZW5jZSIgY2xhc3MKKyAgKiAgICBkZWZpbmVkIGFsb25nIHdpdGggdGhlICJEU0FQcml2YXRlS2V5SW1wbCIgY2xhc3MuCisgICoKKyAgKiAzLiBTZWUgYSBjb21wYXRpYmlsaXR5IHdpdGggUkkgY29tbWVudHMKKyAgKiAgICBpbiB0aGUgYmVsb3cgIkRTQVB1YmxpY0tleUltcGwoWDUwOUVuY29kZWRLZXlTcGVjIGtleVNwZWMpIiBjb25zdHJ1Y3Rvci4KKyAgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkucHJvdmlkZXIuY3J5cHRvOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk5vdEFjdGl2ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuRFNBUGFyYW1zOworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5EU0FQdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkRTQVBhcmFtZXRlclNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkRTQVB1YmxpY0tleVNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkludmFsaWRLZXlTcGVjRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5YNTA5RW5jb2RlZEtleVNwZWM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LlB1YmxpY0tleUltcGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUludGVnZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnV0aWxzLkFsZ05hbWVNYXBwZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuQWxnb3JpdGhtSWRlbnRpZmllcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5TdWJqZWN0UHVibGljS2V5SW5mbzsKKworLyoqCisgKiBUaGUgY2xhc3MgcHJvdmlkZXMgRFNBUHVibGljS2V5IGZ1bmN0aW9uYWxpdHkgYnkgZXh0ZW5kaW5nIGEgY2xhc3MgaW1wbGVtZW50aW5nIFB1YmxpY0tleQorICogYW5kIGltcGxlbWVudGluZyBtZXRob2RzIGRlZmluZWQgaW4gYm90aCBpbnRlcmZhY2VzLCBEU0FLZXkgYW5kIERTQVB1YmxpY0tleQorICovCitwdWJsaWMgY2xhc3MgRFNBUHVibGljS2V5SW1wbCBleHRlbmRzIFB1YmxpY0tleUltcGwgaW1wbGVtZW50cyBEU0FQdWJsaWNLZXkgeworCisgICAgLyoqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yMjc5NjcyMTMxMzEwOTc4MzM2TDsKKworICAgIHByaXZhdGUgQmlnSW50ZWdlciB5LCBnLCBwLCBxOworCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgRFNBUGFyYW1zIHBhcmFtczsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgb2JqZWN0IGZyb20gRFNBUHVibGljS2V5U3BlYy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXlTcGVjIC0gYSBEU0FQdWJsaWNLZXlTcGVjIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBEU0FQdWJsaWNLZXlJbXBsKERTQVB1YmxpY0tleVNwZWMga2V5U3BlYykgeworCisgICAgICAgIHN1cGVyKCJEU0EiKTsKKworICAgICAgICBTdWJqZWN0UHVibGljS2V5SW5mbyBzcGtpOworCisgICAgICAgIHAgPSBrZXlTcGVjLmdldFAoKTsKKyAgICAgICAgcSA9IGtleVNwZWMuZ2V0USgpOworICAgICAgICBnID0ga2V5U3BlYy5nZXRHKCk7CisKKyAgICAgICAgVGhyZWVJbnRlZ2VyU2VxdWVuY2UgdGhyZWVJbnRzID0gbmV3IFRocmVlSW50ZWdlclNlcXVlbmNlKHAKKyAgICAgICAgICAgICAgICAudG9CeXRlQXJyYXkoKSwgcS50b0J5dGVBcnJheSgpLCBnLnRvQnl0ZUFycmF5KCkpOworCisgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIgYWkgPSBuZXcgQWxnb3JpdGhtSWRlbnRpZmllcihBbGdOYW1lTWFwcGVyCisgICAgICAgICAgICAgICAgLm1hcDJPSUQoIkRTQSIpLAorICAgICAgICAgICAgICAgIHRocmVlSW50cy5nZXRFbmNvZGVkKCkpOworCisgICAgICAgIHkgPSBrZXlTcGVjLmdldFkoKTsKKworICAgICAgICBzcGtpID0gbmV3IFN1YmplY3RQdWJsaWNLZXlJbmZvKGFpLCBBU04xSW50ZWdlci5nZXRJbnN0YW5jZSgpLmVuY29kZSgKKyAgICAgICAgICAgICAgICB5LnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgc2V0RW5jb2Rpbmcoc3BraS5nZXRFbmNvZGVkKCkpOworCisgICAgICAgIHBhcmFtcyA9IChEU0FQYXJhbXMpIChuZXcgRFNBUGFyYW1ldGVyU3BlYyhwLCBxLCBnKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBvYmplY3QgZnJvbSBYNTA5RW5jb2RlZEtleVNwZWMuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5U3BlYyAtIGEgWDUwOUVuY29kZWRLZXlTcGVjIG9iamVjdAorICAgICAqCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiAtIGlmIGtleSBkYXRhIGNhbm5vdCBiZSBvYnRhaW4gZnJvbSBlbmNvZGVkIGZvcm1hdAorICAgICAqLworICAgIHB1YmxpYyBEU0FQdWJsaWNLZXlJbXBsKFg1MDlFbmNvZGVkS2V5U3BlYyBrZXlTcGVjKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIHsKKworICAgICAgICBzdXBlcigiRFNBIik7CisKKyAgICAgICAgQWxnb3JpdGhtSWRlbnRpZmllciBhaTsKKyAgICAgICAgVGhyZWVJbnRlZ2VyU2VxdWVuY2UgdGhyZWVJbnRzID0gbnVsbDsKKworICAgICAgICBTdWJqZWN0UHVibGljS2V5SW5mbyBzdWJqZWN0UHVibGljS2V5SW5mbyA9IG51bGw7CisKKyAgICAgICAgYnl0ZVtdIGVuY29kaW5nID0ga2V5U3BlYy5nZXRFbmNvZGVkKCk7CisKKyAgICAgICAgU3RyaW5nIGFsZywgYWxnTmFtZTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3ViamVjdFB1YmxpY0tleUluZm8gPSAoU3ViamVjdFB1YmxpY0tleUluZm8pIFN1YmplY3RQdWJsaWNLZXlJbmZvLkFTTjEKKyAgICAgICAgICAgICAgICAgICAgLmRlY29kZShlbmNvZGluZyk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbigiRmFpbGVkIHRvIGRlY29kZSBrZXlTcGVjIGVuY29kaW5nOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgeSA9IG5ldyBCaWdJbnRlZ2VyKChieXRlW10pIEFTTjFJbnRlZ2VyLmdldEluc3RhbmNlKCkuZGVjb2RlKAorICAgICAgICAgICAgICAgICAgICBzdWJqZWN0UHVibGljS2V5SW5mby5nZXRTdWJqZWN0UHVibGljS2V5KCkpKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKCJGYWlsZWQgdG8gZGVjb2RlIHBhcmFtZXRlcnM6ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFpID0gc3ViamVjdFB1YmxpY0tleUluZm8uZ2V0QWxnb3JpdGhtSWRlbnRpZmllcigpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aHJlZUludHMgPSAoVGhyZWVJbnRlZ2VyU2VxdWVuY2UpIFRocmVlSW50ZWdlclNlcXVlbmNlLkFTTjEKKyAgICAgICAgICAgICAgICAgICAgLmRlY29kZShhaS5nZXRQYXJhbWV0ZXJzKCkpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleVNwZWNFeGNlcHRpb24oIkZhaWxlZCB0byBkZWNvZGUgcGFyYW1ldGVyczogIiArIGUpOworICAgICAgICB9CisgICAgICAgIHAgPSBuZXcgQmlnSW50ZWdlcih0aHJlZUludHMucCk7CisgICAgICAgIHEgPSBuZXcgQmlnSW50ZWdlcih0aHJlZUludHMucSk7CisgICAgICAgIGcgPSBuZXcgQmlnSW50ZWdlcih0aHJlZUludHMuZyk7CisgICAgICAgIHBhcmFtcyA9IChEU0FQYXJhbXMpIChuZXcgRFNBUGFyYW1ldGVyU3BlYyhwLCBxLCBnKSk7CisKKyAgICAgICAgc2V0RW5jb2RpbmcoZW5jb2RpbmcpOworCisgICAgICAgIC8qCisgICAgICAgICAqIHRoZSBmb2xsb3dpbmcgY29kZSBpbXBsZW1lbnRzIFJJIGJlaGF2aW9yCisgICAgICAgICAqLworICAgICAgICBhbGcgPSBhaS5nZXRBbGdvcml0aG0oKTsKKyAgICAgICAgYWxnTmFtZSA9IEFsZ05hbWVNYXBwZXIubWFwMkFsZ05hbWUoYWxnKTsKKyAgICAgICAgc2V0QWxnb3JpdGhtKGFsZ05hbWUgPT0gbnVsbCA/IGFsZyA6IGFsZ05hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4KKyAgICAgKiAgICAgIGEgdmFsdWUgb2YgYSBwdWJsaWMga2V5ICh5KS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRZKCkgeworICAgICAgICByZXR1cm4geTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgIERTQSBrZXkgcGFyYW1ldGVycyAocCwgcSwgZykuCisgICAgICovCisgICAgcHVibGljIERTQVBhcmFtcyBnZXRQYXJhbXMoKSB7CisgICAgICAgIHJldHVybiBwYXJhbXM7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSBpbikgdGhyb3dzIE5vdEFjdGl2ZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBpbi5kZWZhdWx0UmVhZE9iamVjdCgpOworICAgICAgICBwYXJhbXMgPSBuZXcgRFNBUGFyYW1ldGVyU3BlYyhwLCBxLCBnKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY3J5cHRvL1JhbmRvbUJpdHNTdXBwbGllci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vUmFuZG9tQml0c1N1cHBsaWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzg2MjEzMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY3J5cHRvL1JhbmRvbUJpdHNTdXBwbGllci5qYXZhCkBAIC0wLDAgKzEsMTYxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnByb3ZpZGVyLmNyeXB0bzsKKworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlckV4Y2VwdGlvbjsKKworLyoqCisgKiAgVGhlIHN0YXRpYyBjbGFzcyBwcm92aWRpbmcgYWNjZXNzIG9uIExpbnV4IHBsYXRmb3JtCisgKiAgdG8gc3lzdGVtIG1lYW5zIGZvciBnZW5lcmF0aW5nIHRydWUgcmFuZG9tIGJpdHMuIDxCUj4KKyAqCisgKiAgVGhlIHNvdXJjZSBmb3IgdHJ1ZSByYW5kb20gYml0cyBpcyBvbmUgb2YgTGludXgncyBkZXZpY2VzICIvZGV2L3VyYW5kb20iIG9yCisgKiAgIi9kZXYvcmFuZG9tIiBkZXBlbmRzIG9uIHdoaWNoIG9uZSBpcyBhdmFpbGFibGU7IGlmIGJvdGggdGhlIGZpcnN0IGlzIHVzZWQuIDxCUj4KKyAqCisgKiAgSWYgbm8gZGV2aWNlIGF2YWlsYWJsZSB0aGUgc2VydmljZSBpcyBub3QgYXZhaWxhYmxlLAorICogIHRoYXQgaXMsIHByb3ZpZGVyIHNob3VsZG4ndCByZWdpc3RlciB0aGUgYWxnb3JpdGhtLiA8QlI+CisgKi8KK3B1YmxpYyBjbGFzcyBSYW5kb21CaXRzU3VwcGxpZXIgaW1wbGVtZW50cyBTSEExX0RhdGEgeworCisKKyAgICAvKioKKyAgICAgKiBJbnB1dFN0cmVhbSB0byByZWFkIGZyb20gZGV2aWNlCisgICAgICoKKyAgICAgKiBVc2luZyBhIEJ1ZmZlcmVkSW5wdXRTdHJlYW0gbGVhZHMgdG8gcHJvYmxlbXMKKyAgICAgKiBvbiBBbmRyb2lkIGluIHJhcmUgY2FzZXMsIHNpbmNlIHRoZQorICAgICAqIEJ1ZmZlcmVkSW5wdXRTdHJlYW0ncyBhdmFpbGFibGUoKSBpc3N1ZXMgYW4KKyAgICAgKiBpb2N0bCgpLCBhbmQgdGhlIHBzZXVkbyBkZXZpY2UgZG9lc24ndCBzZWVtCisgICAgICogdG8gbGlrZSB0aGF0LiBTaW5jZSB3ZSdyZSByZWFkaW5nIGJpZ2dlcgorICAgICAqIGNodW5rcyBhbmQgbm90IHNpbmdsZSBieXRlcywgdGhlIEZpbGVJbnB1dFN0cmVhbQorICAgICAqIHNob3VsZG4ndCBiZSBzbG93ZXIsIHNvIHdlIHVzZSB0aGF0LiBTYW1lIG1pZ2h0CisgICAgICogYXBwbHkgdG8gb3RoZXIgTGludXggcGxhdGZvcm1zLgorICAgICAqCisgICAgICogVE9ETzogdGhlIGFib3ZlIGRvZXNuJ3Qgc291bmQgdHJ1ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBGaWxlSW5wdXRTdHJlYW0gZmlzID0gbnVsbDsKKworICAgIC8qKgorICAgICAqIEZpbGUgdG8gY29ubmVjdCB0byBkZXZpY2UKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBGaWxlIHJhbmRvbUZpbGUgPSBudWxsOworCisgICAgLyoqCisgICAgICogdmFsdWUgb2YgZmllbGQgaXMgInRydWUiIG9ubHkgaWYgYSBkZXZpY2UgaXMgYXZhaWxhYmxlCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBzZXJ2aWNlQXZhaWxhYmxlID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiAgbmFtZXMgb2YgcmFuZG9tIGRldmljZXMgb24gTGludXggcGxhdGZvcm0KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVWSUNFX05BTUVTW10gPSB7ICIvZGV2L3VyYW5kb20iIC8qLCAiL2Rldi9yYW5kb20iICovIH07CisKKyAgICBzdGF0aWMgeworICAgICAgICBmb3IgKFN0cmluZyBkZXZpY2VOYW1lIDogREVWSUNFX05BTUVTKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEZpbGUgZmlsZSA9IG5ldyBGaWxlKGRldmljZU5hbWUpOworICAgICAgICAgICAgICAgIGlmIChmaWxlLmNhblJlYWQoKSkgeworICAgICAgICAgICAgICAgICAgICBmaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpOworICAgICAgICAgICAgICAgICAgICByYW5kb21GaWxlID0gZmlsZTsKKyAgICAgICAgICAgICAgICAgICAgc2VydmljZUF2YWlsYWJsZSA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogVGhlIG1ldGhvZCBpcyBjYWxsZWQgYnkgcHJvdmlkZXIgdG8gZGV0ZXJtaW5lIGlmIGEgZGV2aWNlIGlzIGF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgYm9vbGVhbiBpc1NlcnZpY2VBdmFpbGFibGUoKSB7CisgICAgICAgIHJldHVybiBzZXJ2aWNlQXZhaWxhYmxlOworICAgIH0KKworCisgICAgLyoqCisgICAgICogT24gcGxhdGZvcm1zIHdpdGggInJhbmRvbSIgZGV2aWNlcyBhdmFpbGFibGUsCisgICAgICogdGhlIG1ldGhvZCByZWFkcyByYW5kb20gYnl0ZXMgZnJvbSB0aGUgZGV2aWNlLiAgPEJSPgorICAgICAqCisgICAgICogSW4gY2FzZSBvZiBhbnkgcnVudGltZSBmYWlsdXJlIFByb3ZpZGVyRXhjZXB0aW9uIGdldHMgdGhyb3duLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHN5bmNocm9uaXplZCBieXRlW10gZ2V0VW5peERldmljZVJhbmRvbShpbnQgbnVtQnl0ZXMpIHsKKworICAgICAgICBieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVtudW1CeXRlc107CisKKyAgICAgICAgaW50IHRvdGFsID0gMDsKKyAgICAgICAgaW50IGJ5dGVzUmVhZDsKKyAgICAgICAgaW50IG9mZnNldCA9IDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKCA7IDsgKSB7CisKKyAgICAgICAgICAgICAgICBieXRlc1JlYWQgPSBmaXMucmVhZChieXRlcywgb2Zmc2V0LCBudW1CeXRlcy10b3RhbCk7CisKKworICAgICAgICAgICAgICAgIC8vIHRoZSBiZWxvdyBjYXNlIHNob3VsZCBub3Qgb2NjdXIgYmVjYXVzZSAvZGV2L3JhbmRvbSBvciAvZGV2L3VyYW5kb20gaXMgYSBzcGVjaWFsIGZpbGUKKyAgICAgICAgICAgICAgICAvLyBoZW5jZSwgaWYgaXQgaXMgaGFwcGVuZWQgdGhlcmUgaXMgc29tZSBpbnRlcm5hbCBwcm9ibGVtCisgICAgICAgICAgICAgICAgaWYgKCBieXRlc1JlYWQgPT0gLTEgKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQcm92aWRlckV4Y2VwdGlvbigiYnl0ZXNSZWFkID09IC0xIik7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdG90YWwgICs9IGJ5dGVzUmVhZDsKKyAgICAgICAgICAgICAgICBvZmZzZXQgKz0gYnl0ZXNSZWFkOworCisgICAgICAgICAgICAgICAgaWYgKCB0b3RhbCA+PSBudW1CeXRlcyApIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisKKyAgICAgICAgICAgIC8vIGFjdHVhbGx5IHRoZXJlIHNob3VsZCBiZSBubyBJT0V4Y2VwdGlvbiBiZWNhdXNlIGRldmljZSBpcyBhIHNwZWNpYWwgZmlsZTsKKyAgICAgICAgICAgIC8vIGhlbmNlLCB0aGVyZSBpcyBlaXRoZXIgc29tZSBpbnRlcm5hbCBwcm9ibGVtIG9yLCBmb3IgaW5zdGFuY2UsCisgICAgICAgICAgICAvLyBkZXZpY2Ugd2FzIHJlbW92ZWQgaW4gcnVudGltZSwgb3Igc29tZXRoaW5nIGVsc2UKKyAgICAgICAgICAgIHRocm93IG5ldyBQcm92aWRlckV4Y2VwdGlvbigiQVRURU5USU9OOiBJT0V4Y2VwdGlvbiBpbiBSYW5kb21CaXRzU3VwcGxpZXIuZ2V0TGludXhSYW5kb21CaXRzKCk6ICIgKyBlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnl0ZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIG1ldGhvZCByZXR1cm5zIGJ5dGUgYXJyYXkgb2YgcmVxdWVzdGVkIGxlbmd0aCBwcm92aWRlZCBzZXJ2aWNlIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBQcm92aWRlckV4Y2VwdGlvbiBnZXRzIHRocm93biBvdGhlcndpc2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0KKyAgICAgKiAgICAgICBudW1CeXRlcyAtIGxlbmd0aCBvZiBieXRlcyByZXF1ZXN0ZWQKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICAgYnl0ZSBhcnJheQorICAgICAqIEB0aHJvd3MKKyAgICAgKiAgICAgICBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gLSBpZiBudW1CeXRlcyA8PSAwCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gZ2V0UmFuZG9tQml0cyhpbnQgbnVtQnl0ZXMpIHsKKyAgICAgICAgaWYgKG51bUJ5dGVzIDw9IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oSW50ZWdlci50b1N0cmluZyhudW1CeXRlcykpOworICAgICAgICB9CisKKyAgICAgICAgLy8gV2UgaGF2ZSBiZWVuIHVuYWJsZSB0byBnZXQgYSByYW5kb20gZGV2aWNlIG9yIGZhbGwgYmFjayB0byB0aGUKKyAgICAgICAgLy8gbmF0aXZlIHNlY3VyaXR5IG1vZHVsZSBjb2RlIC0gdGhyb3cgYW4gZXhjZXB0aW9uLgorICAgICAgICBpZiAoICFzZXJ2aWNlQXZhaWxhYmxlICkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFByb3ZpZGVyRXhjZXB0aW9uKCJBVFRFTlRJT046IHNlcnZpY2UgaXMgbm90IGF2YWlsYWJsZSA6IG5vIHJhbmRvbSBkZXZpY2VzIik7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZ2V0VW5peERldmljZVJhbmRvbShudW1CeXRlcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vU0hBMUltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY3J5cHRvL1NIQTFJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDQyYjkwMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY3J5cHRvL1NIQTFJbXBsLmphdmEKQEAgLTAsMCArMSwyNDcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyogQGF1dGhvciBZdXJpIEEuIEtyb3BhY2hldgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnByb3ZpZGVyLmNyeXB0bzsKKworCisvKioKKyAqIFRoaXMgY2xhc3MgY29udGFpbnMgbWV0aG9kcyBwcm92aWRpbmcgU0hBLTEgZnVuY3Rpb25hbGl0eSB0byB1c2UgaW4gY2xhc3Nlcy4gPEJSPgorICogVGhlIG1ldGhvZHMgc3VwcG9ydCB0aGUgYWxnb3JpdGhtIGRlc2NyaWJlZCBpbiAiU0VDVVJFIEhBU0ggU1RBTkRBUkQiLCBGSVBTIFBVQiAxODAtMiwgPEJSPgorICogImh0dHA6Ly9jc3JjLm5pc3QuZ292L3B1YmxpY2F0aW9ucy9maXBzL2ZpcHMxODAtMi9maXBzMTgwLTIucGRmIiAgICAgIDxCUj4KKyAqIDxCUj4KKyAqIFRoZSBjbGFzcyBjb250YWlucyB0d28gcGFja2FnZSBsZXZlbCBhY2Nlc3MgbWV0aG9kcywgLQorICogInZvaWQgdXBkYXRlSGFzaChpbnRbXSwgYnl0ZVtdLCBpbnQsIGludCkiIGFuZCAidm9pZCBjb21wdXRlSGFzaChpbnRbXSkiLCAtCisgKiBwZXJmb3JtaW5nIHRoZSBmb2xsb3dpbmcgb3BlcmF0aW9ucy4gPEJSPgorICogPEJSPgorICogVGhlICJ1cGRhdGVIYXNoKC4uKSIgbWV0aG9kIGFwcGVuZHMgbmV3IGJ5dGVzIHRvIGV4aXN0aW5nIG9uZXMKKyAqIHdpdGhpbiBsaW1pdCBvZiBhIGZyYW1lIG9mIDY0IGJ5dGVzICgxNiB3b3JkcykuCisgKiBPbmNlIGEgbGVuZ3RoIG9mIGFjY3VtdWxhdGVkIGJ5dGVzIHJlYWNoZXMgdGhlIGxpbWl0CisgKiB0aGUgImNvbXB1dGVIYXNoKGludFtdKSIgbWV0aG9kIGlzIGludm9rZWQgb24gdGhlIGZyYW1lIHRvIGNvbXB1dGUgdXBkYXRlZCBoYXNoLAorICogYW5kIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhlIGZyYW1lIGlzIHNldCB0byAwLgorICogVGh1cywgYWZ0ZXIgYXBwZW5kaW5nIGFsbCBieXRlcywgdGhlIGZyYW1lIGNvbnRhaW4gb25seSB0aG9zZSBieXRlcworICogdGhhdCB3ZXJlIG5vdCB1c2VkIGluIGNvbXB1dGluZyBmaW5hbCBoYXNoIHZhbHVlIHlldC4gPEJSPgorICogPEJSPgorICogVGhlICJjb21wdXRlSGFzaCguLikiIG1ldGhvZCBnZW5lcmF0ZXMgYSAxNjAgYml0IGhhc2ggdmFsdWUgdXNpbmcKKyAqIGEgNTEyIGJpdCBtZXNzYWdlIHN0b3JlZCBpbiBmaXJzdCAxNiB3b3JkcyBvZiBpbnRbXSBhcnJheSBhcmd1bWVudCBhbmQKKyAqIGN1cnJlbnQgaGFzaCB2YWx1ZSBzdG9yZWQgaW4gZml2ZSB3b3JkcywgYmVnaW5uaW5nIEhBU0hfT0ZGU0VULCBvZiB0aGUgYXJyYXkgYXJndW1lbnQuCisgKiBDb21wdXRhdGlvbiBpcyBkb25lIGFjY29yZGluZyB0byBTSEEtMSBhbGdvcml0aG0uIDxCUj4KKyAqIDxCUj4KKyAqIFRoZSByZXN1bHRpbmcgaGFzaCB2YWx1ZSByZXBsYWNlcyB0aGUgcHJldmlvdXMgaGFzaCB2YWx1ZSBpbiB0aGUgYXJyYXk7CisgKiBvcmlnaW5hbCBiaXRzIG9mIHRoZSBtZXNzYWdlIGFyZSBub3QgcHJlc2VydmVkLgorICovCisKKworcHVibGljIGNsYXNzIFNIQTFJbXBsIGltcGxlbWVudHMgU0hBMV9EYXRhIHsKKworCisgICAgLyoqCisgICAgICogVGhlIG1ldGhvZCBnZW5lcmF0ZXMgYSAxNjAgYml0IGhhc2ggdmFsdWUgdXNpbmcKKyAgICAgKiBhIDUxMiBiaXQgbWVzc2FnZSBzdG9yZWQgaW4gZmlyc3QgMTYgd29yZHMgb2YgaW50W10gYXJyYXkgYXJndW1lbnQgYW5kCisgICAgICogY3VycmVudCBoYXNoIHZhbHVlIHN0b3JlZCBpbiBmaXZlIHdvcmRzLCBiZWdpbm5pbmcgT0ZGU0VUKzEsIG9mIHRoZSBhcnJheSBhcmd1bWVudC4KKyAgICAgKiBDb21wdXRhdGlvbiBpcyBkb25lIGFjY29yZGluZyB0byBTSEEtMSBhbGdvcml0aG0uCisgICAgICoKKyAgICAgKiBUaGUgcmVzdWx0aW5nIGhhc2ggdmFsdWUgcmVwbGFjZXMgdGhlIHByZXZpb3VzIGhhc2ggdmFsdWUgaW4gdGhlIGFycmF5OworICAgICAqIG9yaWdpbmFsIGJpdHMgb2YgdGhlIG1lc3NhZ2UgYXJlIG5vdCBwcmVzZXJ2ZWQuCisgICAgICoKKyAgICAgKiBObyBjaGVja3Mgb24gYXJndW1lbnQgc3VwcGxpZWQsIHRoYXQgaXMsCisgICAgICogYSBjYWxsaW5nIG1ldGhvZCBpcyByZXNwb25zaWJsZSBmb3Igc3VjaCBjaGVja3MuCisgICAgICogSW4gY2FzZSBvZiBpbmNvcnJlY3QgYXJyYXkgcGFzc2VkIHRvIHRoZSBtZXRob2QKKyAgICAgKiBlaXRoZXIgTlBFIG9yIEluZGV4T3V0T2ZCb3VuZEV4Y2VwdGlvbiBnZXRzIHRocm93biBieSBKVk0uCisgICAgICoKKyAgICAgKiBAcGFyYW1zCisgICAgICogICAgICAgIGFyclcgLSBpbnRlZ2VyIGFycmF5OyBhcnJXLmxlbmd0aCA+PSAoQllURVNfT0ZGU0VUKzYpOyA8QlI+CisgICAgICogICAgICAgICAgICAgICBvbmx5IGZpcnN0IChCWVRFU19PRkZTRVQrNikgd29yZHMgYXJlIHVzZWQKKyAgICAgKi8KKyAgICBzdGF0aWMgdm9pZCBjb21wdXRlSGFzaChpbnRbXSBhcnJXKSB7CisKKyAgICAgICAgaW50ICBhID0gYXJyV1tIQVNIX09GRlNFVCAgIF07CisgICAgICAgIGludCAgYiA9IGFycldbSEFTSF9PRkZTRVQgKzFdOworICAgICAgICBpbnQgIGMgPSBhcnJXW0hBU0hfT0ZGU0VUICsyXTsKKyAgICAgICAgaW50ICBkID0gYXJyV1tIQVNIX09GRlNFVCArM107CisgICAgICAgIGludCAgZSA9IGFycldbSEFTSF9PRkZTRVQgKzRdOworCisgICAgICAgIGludCB0ZW1wOworCisgICAgICAgIC8vIEluIHRoaXMgaW1wbGVtZW50YXRpb24gdGhlICJkLiBGb3IgdCA9IDAgdG8gNzkgZG8iIGxvb3AKKyAgICAgICAgLy8gaXMgc3BsaXQgaW50byBmb3VyIGxvb3BzLiBUaGUgZm9sbG93aW5nIGNvbnN0YW50czoKKyAgICAgICAgLy8gICAgIEsgPSA1QTgyNzk5OSAgIDAgPD0gdCA8PSAxOQorICAgICAgICAvLyAgICAgSyA9IDZFRDlFQkExICAyMCA8PSB0IDw9IDM5CisgICAgICAgIC8vICAgICBLID0gOEYxQkJDREMgIDQwIDw9IHQgPD0gNTkKKyAgICAgICAgLy8gICAgIEsgPSBDQTYyQzFENiAgNjAgPD0gdCA8PSA3OQorICAgICAgICAvLyBhcmUgaGV4IGxpdGVyYWxzIGluIHRoZSBsb29wcy4KKworICAgICAgICBmb3IgKCBpbnQgdCA9IDE2OyB0IDwgODAgOyB0KysgKSB7CisKKyAgICAgICAgICAgIHRlbXAgID0gYXJyV1t0LTNdIF4gYXJyV1t0LThdIF4gYXJyV1t0LTE0XSBeIGFycldbdC0xNl07CisgICAgICAgICAgICBhcnJXW3RdID0gKCB0ZW1wPDwxICkgfCAoIHRlbXA+Pj4zMSApOworICAgICAgICB9CisKKyAgICAgICAgZm9yICggaW50IHQgPSAwIDsgdCA8IDIwIDsgdCsrICkgeworCisgICAgICAgICAgICB0ZW1wID0gKCAoIGE8PDUgKSB8ICggYT4+PjI3ICkgICApICsKKyAgICAgICAgICAgICAgICAgICAoICggYiAmIGMpIHwgKCh+YikgJiBkKSAgICkgKworICAgICAgICAgICAgICAgICAgICggZSArIGFycldbdF0gKyAweDVBODI3OTk5ICkgOworICAgICAgICAgICAgZSA9IGQ7CisgICAgICAgICAgICBkID0gYzsKKyAgICAgICAgICAgIGMgPSAoIGI8PDMwICkgfCAoIGI+Pj4yICkgOworICAgICAgICAgICAgYiA9IGE7CisgICAgICAgICAgICBhID0gdGVtcDsKKyAgICAgICAgfQorICAgICAgICBmb3IgKCBpbnQgdCA9IDIwIDsgdCA8IDQwIDsgdCsrICkgeworCisgICAgICAgICAgICB0ZW1wID0gKCgoIGE8PDUgKSB8ICggYT4+PjI3ICkpKSArIChiIF4gYyBeIGQpICsgKGUgKyBhcnJXW3RdICsgMHg2RUQ5RUJBMSkgOworICAgICAgICAgICAgZSA9IGQ7CisgICAgICAgICAgICBkID0gYzsKKyAgICAgICAgICAgIGMgPSAoIGI8PDMwICkgfCAoIGI+Pj4yICkgOworICAgICAgICAgICAgYiA9IGE7CisgICAgICAgICAgICBhID0gdGVtcDsKKyAgICAgICAgfQorICAgICAgICBmb3IgKCBpbnQgdCA9IDQwIDsgdCA8IDYwIDsgdCsrICkgeworCisgICAgICAgICAgICB0ZW1wID0gKCggYTw8NSApIHwgKCBhPj4+MjcgKSkgKyAoKGIgJiBjKSB8IChiICYgZCkgfCAoYyAmIGQpKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGUgKyBhcnJXW3RdICsgMHg4RjFCQkNEQykgOworICAgICAgICAgICAgZSA9IGQ7CisgICAgICAgICAgICBkID0gYzsKKyAgICAgICAgICAgIGMgPSAoIGI8PDMwICkgfCAoIGI+Pj4yICkgOworICAgICAgICAgICAgYiA9IGE7CisgICAgICAgICAgICBhID0gdGVtcDsKKyAgICAgICAgfQorICAgICAgICBmb3IgKCBpbnQgdCA9IDYwIDsgdCA8IDgwIDsgdCsrICkgeworCisgICAgICAgICAgICB0ZW1wID0gKCgoIGE8PDUgKSB8ICggYT4+PjI3ICkpKSArIChiIF4gYyBeIGQpICsgKGUgKyBhcnJXW3RdICsgMHhDQTYyQzFENikgOworICAgICAgICAgICAgZSA9IGQ7CisgICAgICAgICAgICBkID0gYzsKKyAgICAgICAgICAgIGMgPSAoIGI8PDMwICkgfCAoIGI+Pj4yICkgOworICAgICAgICAgICAgYiA9IGE7CisgICAgICAgICAgICBhID0gdGVtcDsKKyAgICAgICAgfQorCisgICAgICAgIGFycldbSEFTSF9PRkZTRVQgICBdICs9IGE7CisgICAgICAgIGFycldbSEFTSF9PRkZTRVQgKzFdICs9IGI7CisgICAgICAgIGFycldbSEFTSF9PRkZTRVQgKzJdICs9IGM7CisgICAgICAgIGFycldbSEFTSF9PRkZTRVQgKzNdICs9IGQ7CisgICAgICAgIGFycldbSEFTSF9PRkZTRVQgKzRdICs9IGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIG1ldGhvZCBhcHBlbmRzIG5ldyBieXRlcyB0byBleGlzdGluZyBvbmVzCisgICAgICogd2l0aGluIGxpbWl0IG9mIGEgZnJhbWUgb2YgNjQgYnl0ZXMgKDE2IHdvcmRzKS4KKyAgICAgKgorICAgICAqIE9uY2UgYSBsZW5ndGggb2YgYWNjdW11bGF0ZWQgYnl0ZXMgcmVhY2hlcyB0aGUgbGltaXQKKyAgICAgKiB0aGUgImNvbXB1dGVIYXNoKGludFtdKSIgbWV0aG9kIGlzIGludm9rZWQgb24gdGhlIGFycmF5IHRvIGNvbXB1dGUgdXBkYXRlZCBoYXNoLAorICAgICAqIGFuZCB0aGUgbnVtYmVyIG9mIGJ5dGVzIGluIHRoZSBmcmFtZSBpcyBzZXQgdG8gMC4KKyAgICAgKiBUaHVzLCBhZnRlciBhcHBlbmRpbmcgYWxsIGJ5dGVzLCB0aGUgYXJyYXkgY29udGFpbiBvbmx5IHRob3NlIGJ5dGVzCisgICAgICogdGhhdCB3ZXJlIG5vdCB1c2VkIGluIGNvbXB1dGluZyBmaW5hbCBoYXNoIHZhbHVlIHlldC4KKyAgICAgKgorICAgICAqIE5vIGNoZWNrcyBvbiBhcmd1bWVudHMgcGFzc2VkIHRvIHRoZSBtZXRob2QsIHRoYXQgaXMsCisgICAgICogYSBjYWxsaW5nIG1ldGhvZCBpcyByZXNwb25zaWJsZSBmb3Igc3VjaCBjaGVja3MuCisgICAgICoKKyAgICAgKiBAcGFyYW1zCisgICAgICogICAgICAgIGludEFycmF5ICAtIGludCBhcnJheSBjb250YWluaW5nIGJ5dGVzIHRvIHdoaWNoIHRvIGFwcGVuZDsKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgaW50QXJyYXkubGVuZ3RoID49IChCWVRFU19PRkZTRVQrNikKKyAgICAgKiBAcGFyYW1zCisgICAgICogICAgICAgIGJ5dGVJbnB1dCAtIGFycmF5IG9mIGJ5dGVzIHRvIHVzZSBmb3IgdGhlIHVwZGF0ZQorICAgICAqIEBwYXJhbXMKKyAgICAgKiAgICAgICAgZnJvbSAgICAgIC0gdGhlIG9mZnNldCB0byBzdGFydCBpbiB0aGUgImJ5dGVJbnB1dCIgYXJyYXkKKyAgICAgKiBAcGFyYW1zCisgICAgICogICAgICAgIHRvICAgICAgICAtIGEgbnVtYmVyIG9mIHRoZSBsYXN0IGJ5dGUgaW4gdGhlIGlucHV0IGFycmF5IHRvIHVzZSwKKyAgICAgKiAgICAgICAgICAgICAgICB0aGF0IGlzLCBmb3IgZmlyc3QgYnl0ZSAidG8iPT0wLCBmb3IgbGFzdCBieXRlICJ0byI9PWlucHV0Lmxlbmd0aC0xCisgICAgICovCisgICAgc3RhdGljIHZvaWQgdXBkYXRlSGFzaChpbnRbXSBpbnRBcnJheSwgYnl0ZVtdIGJ5dGVJbnB1dCwgaW50IGZyb21CeXRlLCBpbnQgdG9CeXRlKSB7CisKKyAgICAgICAgLy8gQXMgaW50QXJyYXkgY29udGFpbnMgYSBwYWNrZWQgYnl0ZXMKKyAgICAgICAgLy8gdGhlIGJ1ZmZlcidzIGluZGV4IGlzIGluIHRoZSBpbnRBcnJheVtCWVRFU19PRkZTRVRdIGVsZW1lbnQKKworICAgICAgICBpbnQgaW5kZXggPSBpbnRBcnJheVtCWVRFU19PRkZTRVRdOworICAgICAgICBpbnQgaSA9IGZyb21CeXRlOworICAgICAgICBpbnQgbWF4V29yZDsKKyAgICAgICAgaW50IG5CeXRlczsKKworICAgICAgICBpbnQgd29yZEluZGV4ID0gaW5kZXggPj4yOworICAgICAgICBpbnQgYnl0ZUluZGV4ID0gaW5kZXggJiAweDAzOworCisgICAgICAgIGludEFycmF5W0JZVEVTX09GRlNFVF0gPSAoIGluZGV4ICsgdG9CeXRlIC0gZnJvbUJ5dGUgKyAxICkgJiAwNzcgOworCisgICAgICAgIC8vIEluIGdlbmVyYWwgY2FzZSB0aGVyZSBhcmUgMyBzdGFnZXMgOgorICAgICAgICAvLyAtIGFwcGVuZGluZyBieXRlcyB0byBub24tZnVsbCB3b3JkLAorICAgICAgICAvLyAtIHdyaXRpbmcgNCBieXRlcyBpbnRvIGVtcHR5IHdvcmRzLAorICAgICAgICAvLyAtIHdyaXRpbmcgbGVzcyB0aGFuIDQgYnl0ZXMgaW4gbGFzdCB3b3JkCisKKyAgICAgICAgaWYgKCBieXRlSW5kZXggIT0gMCApIHsgICAgICAgLy8gYXBwZW5kaW5nIGJ5dGVzIGluIG5vbi1mdWxsIHdvcmQgKGFzIGlmKQorCisgICAgICAgICAgICBmb3IgKCA7ICggaSA8PSB0b0J5dGUgKSAmJiAoIGJ5dGVJbmRleCA8IDQgKSA7IGkrKyApIHsKKyAgICAgICAgICAgICAgICBpbnRBcnJheVt3b3JkSW5kZXhdIHw9ICggYnl0ZUlucHV0W2ldICYgMHhGRiApIDw8ICgoMyAtIGJ5dGVJbmRleCk8PDMpIDsKKyAgICAgICAgICAgICAgICBieXRlSW5kZXgrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICggYnl0ZUluZGV4ID09IDQgKSB7CisgICAgICAgICAgICAgICAgd29yZEluZGV4Kys7CisgICAgICAgICAgICAgICAgaWYgKCB3b3JkSW5kZXggPT0gMTYgKSB7ICAgICAgICAgIC8vIGludEFycmF5IGlzIGZ1bGwsIGNvbXB1dGluZyBoYXNoCisKKyAgICAgICAgICAgICAgICAgICAgY29tcHV0ZUhhc2goaW50QXJyYXkpOworICAgICAgICAgICAgICAgICAgICB3b3JkSW5kZXggPSAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICggaSA+IHRvQnl0ZSApIHsgICAgICAgICAgICAgICAgIC8vIGFsbCBpbnB1dCBieXRlcyBhcHBlbmRlZAorICAgICAgICAgICAgICAgIHJldHVybiA7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyB3cml0aW5nIGZ1bGwgd29yZHMKKworICAgICAgICBtYXhXb3JkID0gKHRvQnl0ZSAtIGkgKyAxKSA+PiAyOyAgICAgICAgICAgLy8gIyBvZiByZW1haW5pbmcgZnVsbCB3b3JkcywgbWF5IGJlICIwIgorICAgICAgICBmb3IgKCBpbnQgayA9IDA7IGsgPCBtYXhXb3JkIDsgaysrICkgeworCisgICAgICAgICAgICBpbnRBcnJheVt3b3JkSW5kZXhdID0gKCAoKGludCkgYnl0ZUlucHV0W2kgICBdICYgMHhGRikgPDwyNCApIHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoICgoaW50KSBieXRlSW5wdXRbaSArMV0gJiAweEZGKSA8PDE2ICkgfAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICggKChpbnQpIGJ5dGVJbnB1dFtpICsyXSAmIDB4RkYpIDw8OCAgKSB8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCAoKGludCkgYnl0ZUlucHV0W2kgKzNdICYgMHhGRikgICAgICApICA7CisgICAgICAgICAgICBpICs9IDQ7CisgICAgICAgICAgICB3b3JkSW5kZXgrKzsKKworICAgICAgICAgICAgaWYgKCB3b3JkSW5kZXggPCAxNiApIHsgICAgIC8vIGJ1ZmZlciBpcyBub3QgZnVsbCB5ZXQKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvbXB1dGVIYXNoKGludEFycmF5KTsgICAgICAvLyBidWZmZXIgaXMgZnVsbCwgY29tcHV0aW5nIGhhc2gKKyAgICAgICAgICAgIHdvcmRJbmRleCA9IDA7CisgICAgICAgIH0KKworICAgICAgICAvLyB3cml0aW5nIGxhc3QgaW5jb21wbGV0ZSB3b3JkCisgICAgICAgIC8vIGFmdGVyIHdyaXRpbmcgZnJlZSBieXRlIHBvc2l0aW9ucyBhcmUgc2V0IHRvICIwInMKKworICAgICAgICBuQnl0ZXMgPSB0b0J5dGUgLSBpICsxOworICAgICAgICBpZiAoIG5CeXRlcyAhPSAwICkgeworCisgICAgICAgICAgICBpbnQgdyA9ICAoKGludCkgYnl0ZUlucHV0W2ldICYgMHhGRikgPDwyNCA7CisKKyAgICAgICAgICAgIGlmICggbkJ5dGVzICE9IDEgKSB7CisgICAgICAgICAgICAgICAgdyB8PSAoKGludCkgYnl0ZUlucHV0W2kgKzFdICYgMHhGRikgPDwxNiA7CisgICAgICAgICAgICAgICAgaWYgKCBuQnl0ZXMgIT0gMikgeworICAgICAgICAgICAgICAgICAgICB3IHw9ICgoaW50KSBieXRlSW5wdXRbaSArMl0gJiAweEZGKSA8PDggOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludEFycmF5W3dvcmRJbmRleF0gPSB3OworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIDsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY3J5cHRvL1NIQTFQUk5HX1NlY3VyZVJhbmRvbUltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY3J5cHRvL1NIQTFQUk5HX1NlY3VyZVJhbmRvbUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNDIwZmJlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vU0hBMVBSTkdfU2VjdXJlUmFuZG9tSW1wbC5qYXZhCkBAIC0wLDAgKzEsNTI5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnByb3ZpZGVyLmNyeXB0bzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb21TcGk7CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworaW1wb3J0IGxpYmNvcmUudXRpbC5FbXB0eUFycmF5OworCisvKioKKyAqIFRoaXMgY2xhc3MgZXh0ZW5kcyB0aGUgU2VjdXJlUmFuZG9tU3BpIGNsYXNzIGltcGxlbWVudGluZyBhbGwgaXRzIGFic3RyYWN0IG1ldGhvZHMuIDxCUj4KKyAqIDxCUj4KKyAqIFRvIGdlbmVyYXRlIHBzZXVkby1yYW5kb20gYml0cywgdGhlIGltcGxlbWVudGF0aW9uIHVzZXMgdGVjaG5pcXVlIGRlc2NyaWJlZCBpbgorICogdGhlICJSYW5kb20gTnVtYmVyIEdlbmVyYXRvciAoUk5HKSBhbGdvcml0aG1zIiBzZWN0aW9uLCBBcHBlbmRpeCBBLAorICogSmF2YVRNIENyeXB0b2dyYXBoeSBBcmNoaXRlY3R1cmUsIEFQSSBTcGVjaWZpY2F0aW9uJlJlZmVyZW5jZSA8QlI+CisgKiA8QlI+CisgKiBUaGUgY2xhc3MgaW1wbGVtZW50cyB0aGUgU2VyaWFsaXphYmxlIGludGVyZmFjZS4KKyAqLworCitwdWJsaWMgY2xhc3MgU0hBMVBSTkdfU2VjdXJlUmFuZG9tSW1wbCBleHRlbmRzIFNlY3VyZVJhbmRvbVNwaSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSwgU0hBMV9EYXRhIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDI4MzczNjc5NzIxMjE1OTY3NUw7CisKKyAgICAvLyBjb25zdGFudHMgdG8gdXNlIGluIGV4cHJlc3Npb25zIG9wZXJhdGluZyBvbiBieXRlcyBpbiBpbnQgYW5kIGxvbmcgdmFyaWFibGVzOgorICAgIC8vIEVORF9GTEFHUyAtIGZpbmFsIGJ5dGVzIGluIHdvcmRzIHRvIGFwcGVuZCB0byBtZXNzYWdlOworICAgIC8vICAgICAgICAgICAgIHNlZSAiY2guNS4xIFBhZGRpbmcgdGhlIE1lc3NhZ2UsIEZJUFMgMTgwLTIiCisgICAgLy8gUklHSFQxICAgIC0gc2hpZnRzIHRvIHJpZ2h0IGZvciBsZWZ0IGhhbGYgb2YgbG9uZworICAgIC8vIFJJR0hUMiAgICAtIHNoaWZ0cyB0byByaWdodCBmb3IgcmlnaHQgaGFsZiBvZiBsb25nCisgICAgLy8gTEVGVCAgICAgIC0gc2hpZnRzIHRvIGxlZnQgZm9yIGJ5dGVzCisgICAgLy8gTUFTSyAgICAgIC0gbWFzayB0byBzZWxlY3QgY291bnRlcidzIGJ5dGVzIGFmdGVyIHNoaWZ0IHRvIHJpZ2h0CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnRbXSBFTkRfRkxBR1MgPSB7IDB4ODAwMDAwMDAsIDB4ODAwMDAwLCAweDgwMDAsIDB4ODAgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludFtdIFJJR0hUMSA9IHsgMCwgNDAsIDQ4LCA1NiB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gUklHSFQyID0geyAwLCA4LCAxNiwgMjQgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludFtdIExFRlQgPSB7IDAsIDI0LCAxNiwgOCB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gTUFTSyA9IHsgMHhGRkZGRkZGRiwgMHgwMEZGRkZGRiwgMHgwMDAwRkZGRiwKKyAgICAgICAgICAgIDB4MDAwMDAwRkYgfTsKKworICAgIC8vIEhBU0hCWVRFU19UT19VU0UgZGVmaW5lcyAjIG9mIGJ5dGVzIHJldHVybmVkIGJ5ICJjb21wdXRlSGFzaChieXRlW10pIgorICAgIC8vIHRvIHVzZSB0byBmb3JtIGJ5dGUgYXJyYXkgcmV0dXJuaW5nIGJ5IHRoZSAibmV4dEJ5dGVzKGJ5dGVbXSkiIG1ldGhvZAorICAgIC8vIE5vdGUsIHRoYXQgdGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIG1vcmUgYnl0ZXMgdGhhbiBpdCBpcyBkZWZpbmVkCisgICAgLy8gaW4gdGhlIGFib3ZlIHNwZWNpZmljYXRpb24uCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEhBU0hCWVRFU19UT19VU0UgPSAyMDsKKworICAgIC8vIHZhbHVlIG9mIDE2IGRlZmluZWQgaW4gdGhlICJTRUNVUkUgSEFTSCBTVEFOREFSRCIsIEZJUFMgUFVCIDE4MC0yCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEZSQU1FX0xFTkdUSCA9IDE2OworCisgICAgLy8gbWlzY2VsbGFuZW91cyBjb25zdGFudHMgZGVmaW5lZCBpbiB0aGlzIGltcGxlbWVudGF0aW9uOgorICAgIC8vIENPVU5URVJfQkFTRSAtIGluaXRpYWwgdmFsdWUgdG8gc2V0IHRvICJjb3VudGVyIiBiZWZvcmUgY29tcHV0aW5nICJuZXh0Qnl0ZXMoLi4pIjsKKyAgICAvLyAgICAgICAgICAgICAgICBub3RlLCB0aGF0IHRoZSBleGFjdCB2YWx1ZSBpcyBub3QgZGVmaW5lZCBpbiBTVEFOREFSRAorICAgIC8vIEhBU0hDT1BZX09GRlNFVCAgIC0gb2Zmc2V0IGZvciBjb3B5IG9mIGN1cnJlbnQgaGFzaCBpbiAiY29waWVzIiBhcnJheQorICAgIC8vIEVYVFJBRlJBTUVfT0ZGU0VUIC0gb2Zmc2V0IGZvciBleHRyYSBmcmFtZSBpbiAiY29waWVzIiBhcnJheTsKKyAgICAvLyAgICAgICAgICAgICAgICAgICAgIGFzIHRoZSBleHRyYSBmcmFtZSBmb2xsb3dzIHRoZSBjdXJyZW50IGhhc2ggZnJhbWUsCisgICAgLy8gICAgICAgICAgICAgICAgICAgICBFWFRSQUZSQU1FX09GRlNFVCBpcyBlcXVhbCB0byBsZW5ndGggb2YgY3VycmVudCBoYXNoIGZyYW1lCisgICAgLy8gRlJBTUVfT0ZGU0VUICAgICAgLSBvZmZzZXQgZm9yIGZyYW1lIGluICJjb3BpZXMiIGFycmF5CisgICAgLy8gTUFYX0JZVEVTIC0gbWF4aW11bSAjIG9mIHNlZWQgYnl0ZXMgcHJvY2Vzc2luZyB3aGljaCBkb2Vzbid0IHJlcXVpcmUgZXh0cmEgZnJhbWUKKyAgICAvLyAgICAgICAgICAgICBzZWUgKDEpIGNvbW1lbnRzIG9uIHVzYWdlIG9mICJzZWVkIiBhcnJheSBiZWxvdyBhbmQKKyAgICAvLyAgICAgICAgICAgICAoMikgY29tbWVudHMgaW4gImVuZ2luZU5leHRCeXRlcyhieXRlW10pIiBtZXRob2QKKyAgICAvLworICAgIC8vIFVOREVGSU5FRCAgLSB0aHJlZSBzdGF0ZXMgb2YgZW5naW5lOyBpbml0aWFsbHkgaXRzIHN0YXRlIGlzICJVTkRFRklORUQiCisgICAgLy8gU0VUX1NFRUQgICAgIGNhbGwgdG8gImVuZ2luZVNldFNlZWQiICBzZXRzIHVwICJTRVRfU0VFRCIgc3RhdGUsCisgICAgLy8gTkVYVF9CWVRFUyAgIGNhbGwgdG8gImVuZ2luZU5leHRCeXRlIiBzZXRzIHVwICJORVhUX0JZVEVTIiBzdGF0ZQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENPVU5URVJfQkFTRSA9IDA7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSEFTSENPUFlfT0ZGU0VUID0gMDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBFWFRSQUZSQU1FX09GRlNFVCA9IDU7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRlJBTUVfT0ZGU0VUID0gMjE7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0JZVEVTID0gNDg7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5ERUZJTkVEID0gMDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTRVRfU0VFRCA9IDE7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTkVYVF9CWVRFUyA9IDI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTSEExUFJOR19TZWN1cmVSYW5kb21JbXBsIG15UmFuZG9tOworCisgICAgLy8gU3RydWN0dXJlIG9mICJzZWVkIiBhcnJheToKKyAgICAvLyAtICAwLTc5IC0gd29yZHMgZm9yIGNvbXB1dGluZyBoYXNoCisgICAgLy8gLSA4MCAgICAtIHVudXNlZAorICAgIC8vIC0gODEgICAgLSAjIG9mIHNlZWQgYnl0ZXMgaW4gY3VycmVudCBzZWVkIGZyYW1lCisgICAgLy8gLSA4Mi04NiAtIDUgd29yZHMsIGN1cnJlbnQgc2VlZCBoYXNoCisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50W10gc2VlZDsKKworICAgIC8vIHRvdGFsIGxlbmd0aCBvZiBzZWVkIGJ5dGVzLCBpbmNsdWRpbmcgYWxsIHByb2Nlc3NlZAorICAgIHByaXZhdGUgdHJhbnNpZW50IGxvbmcgc2VlZExlbmd0aDsKKworICAgIC8vIFN0cnVjdHVyZSBvZiAiY29waWVzIiBhcnJheQorICAgIC8vIC0gIDAtNCAgLSA1IHdvcmRzLCBjb3B5IG9mIGN1cnJlbnQgc2VlZCBoYXNoCisgICAgLy8gLSAgNS0yMCAtIGV4dHJhIDE2IHdvcmRzIGZyYW1lOworICAgIC8vICAgICAgICAgICBpcyB1c2VkIGlmIGZpbmFsIHBhZGRpbmcgZXhjZWVkcyA1MTItYml0IGxlbmd0aAorICAgIC8vIC0gMjEtMzYgLSAxNiB3b3JkIGZyYW1lIHRvIHN0b3JlIGEgY29weSBvZiByZW1haW5pbmcgYnl0ZXMKKyAgICBwcml2YXRlIHRyYW5zaWVudCBpbnRbXSBjb3BpZXM7CisKKyAgICAvLyByZWFkeSAibmV4dCIgYnl0ZXM7IG5lZWRlZCBiZWNhdXNlIHdvcmRzIGFyZSByZXR1cm5lZAorICAgIHByaXZhdGUgdHJhbnNpZW50IGJ5dGVbXSBuZXh0Qnl0ZXM7CisKKyAgICAvLyBpbmRleCBvZiB1c2VkIGJ5dGVzIGluICJuZXh0Qnl0ZXMiIGFycmF5CisgICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IG5leHRCSW5kZXg7CisKKyAgICAvLyB2YXJpYWJsZSByZXF1aXJlZCBhY2NvcmRpbmcgdG8gIlNFQ1VSRSBIQVNIIFNUQU5EQVJEIgorICAgIHByaXZhdGUgdHJhbnNpZW50IGxvbmcgY291bnRlcjsKKworICAgIC8vIGNvbnRhaW5zIGludCB2YWx1ZSBjb3JyZXNwb25kaW5nIHRvIGVuZ2luZSdzIGN1cnJlbnQgc3RhdGUKKyAgICBwcml2YXRlIHRyYW5zaWVudCBpbnQgc3RhdGU7CisKKyAgICAvLyBUaGUgInNlZWQiIGFycmF5IGlzIHVzZWQgdG8gY29tcHV0ZSBib3RoICJjdXJyZW50IHNlZWQgaGFzaCIgYW5kICJuZXh0IGJ5dGVzIi4KKyAgICAvLworICAgIC8vIEFzIHRoZSAiU0hBMSIgYWxnb3JpdGhtIGNvbXB1dGVzIGEgaGFzaCBvZiBlbnRpcmUgc2VlZCBieSBzcGxpdHRpbmcgaXQgaW50bworICAgIC8vIGEgbnVtYmVyIG9mIHRoZSA1MTItYml0IGxlbmd0aCBmcmFtZXMgKDUxMiBiaXRzID0gNjQgYnl0ZXMgPSAxNiB3b3JkcyksCisgICAgLy8gImN1cnJlbnQgc2VlZCBoYXNoIiBpcyBhIGhhc2ggKDUgd29yZHMsIDIwIGJ5dGVzKSBmb3IgYWxsIHByZXZpb3VzIGZ1bGwgZnJhbWVzOworICAgIC8vIHJlbWFpbmluZyBieXRlcyBhcmUgc3RvcmVkIGluIHRoZSAwLTE1IHdvcmQgZnJhbWUgb2YgdGhlICJzZWVkIiBhcnJheS4KKyAgICAvLworICAgIC8vIEFzIGZvciBjYWxjdWxhdGluZyAibmV4dCBieXRlcyIsCisgICAgLy8gYm90aCByZW1haW5pbmcgYnl0ZXMgYW5kICJjdXJyZW50IHNlZWQgaGFzaCIgYXJlIHVzZWQsCisgICAgLy8gdG8gcHJlc2VydmUgdGhlIGxhdHRlciBmb3IgZm9sbG93aW5nICJzZXRTZWVkKC4uKSIgY29tbWFuZHMsCisgICAgLy8gdGhlIGZvbGxvd2luZyB0ZWNobmlxdWUgaXMgdXNlZDoKKyAgICAvLyAtIHVwb24gZ2V0dGluZyAibmV4dEJ5dGVzKGJ5dGVbXSkiIGludm9rZWQsIHNpbmdsZSBvciBmaXJzdCBpbiByb3csCisgICAgLy8gICB3aGljaCByZXF1aXJlcyBjb21wdXRpbmcgbmV3IGhhc2gsIHRoYXQgaXMsCisgICAgLy8gICB0aGVyZSBpcyBubyBtb3JlIGJ5dGVzIHJlbWFpbmluZyBmcm9tIHByZXZpb3VzICJuZXh0IGJ5dGVzIiBjb21wdXRhdGlvbiwKKyAgICAvLyAgIHJlbWFpbmluZyBieXRlcyBhcmUgY29waWVkIGludG8gdGhlIDIxLTM2IHdvcmQgZnJhbWUgb2YgdGhlICJjb3BpZXMiIGFycmF5OworICAgIC8vIC0gdXBvbiBnZXR0aW5nICJzZXRTZWVkKGJ5dGVbXSkiIGludm9rZWQsIHNpbmdsZSBvciBmaXJzdCBpbiByb3csCisgICAgLy8gICByZW1haW5pbmcgYnl0ZXMgYXJlIGNvcGllZCBiYWNrLgorCisgICAgLyoqCisgICAgICogIENyZWF0ZXMgb2JqZWN0IGFuZCBzZXRzIGltcGxlbWVudGF0aW9uIHZhcmlhYmxlcyB0byB0aGVpciBpbml0aWFsIHZhbHVlcworICAgICAqLworICAgIHB1YmxpYyBTSEExUFJOR19TZWN1cmVSYW5kb21JbXBsKCkgeworCisgICAgICAgIHNlZWQgPSBuZXcgaW50W0hBU0hfT0ZGU0VUICsgRVhUUkFGUkFNRV9PRkZTRVRdOworICAgICAgICBzZWVkW0hBU0hfT0ZGU0VUXSA9IEgwOworICAgICAgICBzZWVkW0hBU0hfT0ZGU0VUICsgMV0gPSBIMTsKKyAgICAgICAgc2VlZFtIQVNIX09GRlNFVCArIDJdID0gSDI7CisgICAgICAgIHNlZWRbSEFTSF9PRkZTRVQgKyAzXSA9IEgzOworICAgICAgICBzZWVkW0hBU0hfT0ZGU0VUICsgNF0gPSBINDsKKworICAgICAgICBzZWVkTGVuZ3RoID0gMDsKKyAgICAgICAgY29waWVzID0gbmV3IGludFsyICogRlJBTUVfTEVOR1RIICsgRVhUUkFGUkFNRV9PRkZTRVRdOworICAgICAgICBuZXh0Qnl0ZXMgPSBuZXcgYnl0ZVtESUdFU1RfTEVOR1RIXTsKKyAgICAgICAgbmV4dEJJbmRleCA9IEhBU0hCWVRFU19UT19VU0U7CisgICAgICAgIGNvdW50ZXIgPSBDT1VOVEVSX0JBU0U7CisgICAgICAgIHN0YXRlID0gVU5ERUZJTkVEOworICAgIH0KKworICAgIC8qCisgICAgICogVGhlIG1ldGhvZCBpbnZva2VzIHRoZSBTSEExSW1wbCdzICJ1cGRhdGVIYXNoKC4uKSIgbWV0aG9kCisgICAgICogdG8gdXBkYXRlIGN1cnJlbnQgc2VlZCBmcmFtZSBhbmQKKyAgICAgKiB0byBjb21wdXRlIG5ldyBpbnRlcm1lZGlhdGUgaGFzaCB2YWx1ZSBpZiB0aGUgZnJhbWUgaXMgZnVsbC4KKyAgICAgKgorICAgICAqIEFmdGVyIHRoYXQgaXQgY29tcHV0ZXMgYSBsZW5ndGggb2Ygd2hvbGUgc2VlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgdXBkYXRlU2VlZChieXRlW10gYnl0ZXMpIHsKKworICAgICAgICAvLyBvbiBjYWxsOiAgICJzZWVkIiBjb250YWlucyBjdXJyZW50IGJ5dGVzIGFuZCBjdXJyZW50IGhhc2g7CisgICAgICAgIC8vIG9uIHJldHVybjogInNlZWQiIGNvbnRhaW5zIG5ldyBjdXJyZW50IGJ5dGVzIGFuZCBwb3NzaWJseSBuZXcgY3VycmVudCBoYXNoCisgICAgICAgIC8vICAgICAgICAgICAgaWYgYWZ0ZXIgYWRkaW5nLCBzZWVkIGJ5dGVzIG92ZXJmaWxsIGl0cyBidWZmZXIKKyAgICAgICAgU0hBMUltcGwudXBkYXRlSGFzaChzZWVkLCBieXRlcywgMCwgYnl0ZXMubGVuZ3RoIC0gMSk7CisKKyAgICAgICAgc2VlZExlbmd0aCArPSBieXRlcy5sZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hhbmdlcyBjdXJyZW50IHNlZWQgYnkgc3VwcGxlbWVudGluZyBhIHNlZWQgYXJndW1lbnQgdG8gdGhlIGN1cnJlbnQgc2VlZCwKKyAgICAgKiBpZiB0aGlzIGFscmVhZHkgc2V0OworICAgICAqIHRoZSBhcmd1bWVudCBpcyB1c2VkIGFzIGZpcnN0IHNlZWQgb3RoZXJ3aXNlLiA8QlI+CisgICAgICoKKyAgICAgKiBUaGUgbWV0aG9kIG92ZXJyaWRlcyAiZW5naW5lU2V0U2VlZChieXRlW10pIiBpbiBjbGFzcyBTZWN1cmVSYW5kb21TcGkuCisgICAgICoKKyAgICAgKiBAcGFyYW0KKyAgICAgKiAgICAgICBzZWVkIC0gYnl0ZSBhcnJheQorICAgICAqIEB0aHJvd3MKKyAgICAgKiAgICAgICBOdWxsUG9pbnRlckV4Y2VwdGlvbiAtIGlmIG51bGwgaXMgcGFzc2VkIHRvIHRoZSAic2VlZCIgYXJndW1lbnQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgZW5naW5lU2V0U2VlZChieXRlW10gc2VlZCkgeworCisgICAgICAgIGlmIChzZWVkID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigic2VlZCA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc3RhdGUgPT0gTkVYVF9CWVRFUykgeyAvLyBmaXJzdCBzZXRTZWVkIGFmdGVyIE5leHRCeXRlczsgcmVzdG9yaW5nIGhhc2gKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY29waWVzLCBIQVNIQ09QWV9PRkZTRVQsIHRoaXMuc2VlZCwgSEFTSF9PRkZTRVQsCisgICAgICAgICAgICAgICAgICAgIEVYVFJBRlJBTUVfT0ZGU0VUKTsKKyAgICAgICAgfQorICAgICAgICBzdGF0ZSA9IFNFVF9TRUVEOworCisgICAgICAgIGlmIChzZWVkLmxlbmd0aCAhPSAwKSB7CisgICAgICAgICAgICB1cGRhdGVTZWVkKHNlZWQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHJlcXVpcmVkIG51bWJlciBvZiByYW5kb20gYnl0ZXMuIDxCUj4KKyAgICAgKgorICAgICAqIFRoZSBtZXRob2Qgb3ZlcnJpZGVzICJlbmdpbmVHZW5lcmF0ZVNlZWQgKGludCkiIGluIGNsYXNzIFNlY3VyZVJhbmRvbVNwaS4gPEJSPgorICAgICAqCisgICAgICogQHBhcmFtCisgICAgICogICAgICAgbnVtQnl0ZXMgLSBudW1iZXIgb2YgYnl0ZXMgdG8gcmV0dXJuOyBzaG91bGQgYmUgPj0gMC4KKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICAgYnl0ZSBhcnJheSBjb250YWluaW5nIGJpdHMgaW4gb3JkZXIgZnJvbSBsZWZ0IHRvIHJpZ2h0CisgICAgICogQHRocm93cworICAgICAqICAgICAgIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gLSBpZiBudW1CeXRlcyA8IDAKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIGJ5dGVbXSBlbmdpbmVHZW5lcmF0ZVNlZWQoaW50IG51bUJ5dGVzKSB7CisKKyAgICAgICAgYnl0ZVtdIG15Qnl0ZXM7IC8vIGJ5dGVbXSBmb3IgYnl0ZXMgcmV0dXJuZWQgYnkgIm5leHRCeXRlcygpIgorCisgICAgICAgIGlmIChudW1CeXRlcyA8IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbihJbnRlZ2VyLnRvU3RyaW5nKG51bUJ5dGVzKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG51bUJ5dGVzID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBFbXB0eUFycmF5LkJZVEU7CisgICAgICAgIH0KKworICAgICAgICBpZiAobXlSYW5kb20gPT0gbnVsbCkgeworICAgICAgICAgICAgbXlSYW5kb20gPSBuZXcgU0hBMVBSTkdfU2VjdXJlUmFuZG9tSW1wbCgpOworICAgICAgICAgICAgbXlSYW5kb20uZW5naW5lU2V0U2VlZChSYW5kb21CaXRzU3VwcGxpZXIuZ2V0UmFuZG9tQml0cyhESUdFU1RfTEVOR1RIKSk7CisgICAgICAgIH0KKworICAgICAgICBteUJ5dGVzID0gbmV3IGJ5dGVbbnVtQnl0ZXNdOworICAgICAgICBteVJhbmRvbS5lbmdpbmVOZXh0Qnl0ZXMobXlCeXRlcyk7CisKKyAgICAgICAgcmV0dXJuIG15Qnl0ZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHJhbmRvbSBieXRlcyBpbnRvIGFuIGFycmF5IHN1cHBsaWVkLgorICAgICAqIEJpdHMgaW4gYSBieXRlIGFyZSBmcm9tIGxlZnQgdG8gcmlnaHQuIDxCUj4KKyAgICAgKgorICAgICAqIFRvIGdlbmVyYXRlIHJhbmRvbSBieXRlcywgdGhlICJleHBhbnNpb24gb2Ygc291cmNlIGJpdHMiIG1ldGhvZCBpcyB1c2VkLAorICAgICAqIHRoYXQgaXMsCisgICAgICogdGhlIGN1cnJlbnQgc2VlZCB3aXRoIGEgNjQtYml0IGNvdW50ZXIgYXBwZW5kZWQgaXMgdXNlZCB0byBjb21wdXRlIG5ldyBiaXRzLgorICAgICAqIFRoZSBjb3VudGVyIGlzIGluY3JlbWVudGVkIGJ5IDEgZm9yIGVhY2ggMjAtYnl0ZSBvdXRwdXQuIDxCUj4KKyAgICAgKgorICAgICAqIFRoZSBtZXRob2Qgb3ZlcnJpZGVzIGVuZ2luZU5leHRCeXRlcyBpbiBjbGFzcyBTZWN1cmVSYW5kb21TcGkuCisgICAgICoKKyAgICAgKiBAcGFyYW0KKyAgICAgKiAgICAgICBieXRlcyAtIGJ5dGUgYXJyYXkgdG8gYmUgZmlsbGVkIGluIHdpdGggYnl0ZXMKKyAgICAgKiBAdGhyb3dzCisgICAgICogICAgICAgTnVsbFBvaW50ZXJFeGNlcHRpb24gLSBpZiBudWxsIGlzIHBhc3NlZCB0byB0aGUgImJ5dGVzIiBhcmd1bWVudAorICAgICAqLworICAgIHByb3RlY3RlZCBzeW5jaHJvbml6ZWQgdm9pZCBlbmdpbmVOZXh0Qnl0ZXMoYnl0ZVtdIGJ5dGVzKSB7CisKKyAgICAgICAgaW50IGksIG47CisKKyAgICAgICAgbG9uZyBiaXRzOyAvLyBudW1iZXIgb2YgYml0cyByZXF1aXJlZCBieSBTZWN1cmUgSGFzaCBTdGFuZGFyZAorICAgICAgICBpbnQgbmV4dEJ5dGVUb1JldHVybjsgLy8gaW5kZXggb2YgcmVhZHkgYnl0ZXMgaW4gImJ5dGVzIiBhcnJheQorICAgICAgICBpbnQgbGFzdFdvcmQ7IC8vIGluZGV4IG9mIGxhc3Qgd29yZCBpbiBmcmFtZSBjb250YWluaW5nIGJ5dGVzCisgICAgICAgIGZpbmFsIGludCBleHRyYWJ5dGVzID0gNzsvLyAjIG9mIGJ5dGVzIHRvIGFkZCBpbiBvcmRlciB0byBjb21wdXRlciAjIG9mIDggYnl0ZSB3b3JkcworCisgICAgICAgIGlmIChieXRlcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImJ5dGVzID09IG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIGxhc3RXb3JkID0gc2VlZFtCWVRFU19PRkZTRVRdID09IDAgPyAwCisgICAgICAgICAgICAgICAgOiAoc2VlZFtCWVRFU19PRkZTRVRdICsgZXh0cmFieXRlcykgPj4gMyAtIDE7CisKKyAgICAgICAgaWYgKHN0YXRlID09IFVOREVGSU5FRCkgeworCisgICAgICAgICAgICAvLyBubyBzZWVkIHN1cHBsaWVkIGJ5IHVzZXIsIGhlbmNlIGl0IGlzIGdlbmVyYXRlZCB0aHVzIHJhbmRvbWl6aW5nIGludGVybmFsIHN0YXRlCisgICAgICAgICAgICB1cGRhdGVTZWVkKFJhbmRvbUJpdHNTdXBwbGllci5nZXRSYW5kb21CaXRzKERJR0VTVF9MRU5HVEgpKTsKKyAgICAgICAgICAgIG5leHRCSW5kZXggPSBIQVNIQllURVNfVE9fVVNFOworCisgICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT0gU0VUX1NFRUQpIHsKKworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzZWVkLCBIQVNIX09GRlNFVCwgY29waWVzLCBIQVNIQ09QWV9PRkZTRVQsCisgICAgICAgICAgICAgICAgICAgIEVYVFJBRlJBTUVfT0ZGU0VUKTsKKworICAgICAgICAgICAgLy8gcG9zc2libGUgY2FzZXMgZm9yIDY0LWJ5dGUgZnJhbWU6CisgICAgICAgICAgICAvLworICAgICAgICAgICAgLy8gc2VlZCBieXRlcyA8IDQ4ICAgICAgLSByZW1haW5pbmcgYnl0ZXMgYXJlIGVub3VnaCBmb3IgYWxsLCA4IGNvdW50ZXIgYnl0ZXMsCisgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgIDB4ODAsIGFuZCA4IHNlZWRMZW5ndGggYnl0ZXM7IG5vIGV4dHJhIGZyYW1lIHJlcXVpcmVkCisgICAgICAgICAgICAvLyA0OCA8IHNlZWQgYnl0ZXMgPCA1NiAtIHJlbWFpbmluZyA5IGJ5dGVzIGFyZSBmb3IgMHg4MCBhbmQgOCBjb3VudGVyIGJ5dGVzCisgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhIGZyYW1lIGNvbnRhaW5zIG9ubHkgc2VlZExlbmd0aCB2YWx1ZSBhdCB0aGUgZW5kCisgICAgICAgICAgICAvLyBzZWVkIGJ5dGVzID4gNTUgICAgICAtIGV4dHJhIGZyYW1lIGNvbnRhaW5zIGJvdGggY291bnRlcidzIGJ5dGVzCisgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgIGF0IHRoZSBiZWdpbm5pbmcgYW5kIHNlZWRMZW5ndGggdmFsdWUgYXQgdGhlIGVuZDsKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgbm90ZSwgdGhhdCBiZWdpbm5pbmcgZXh0cmEgYnl0ZXMgYXJlIG5vdCBtb3JlIHRoYW4gOCwKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgdGhhdCBpcywgb25seSAyIGV4dHJhIHdvcmRzIG1heSBiZSB1c2VkCisKKyAgICAgICAgICAgIC8vIG5vIG5lZWQgdG8gc2V0IHRvICIwIiAzIHdvcmRzIGFmdGVyICJsYXN0V29yZCIgYW5kCisgICAgICAgICAgICAvLyBtb3JlIHRoYW4gdHdvIHdvcmRzIGJlaGluZCBmcmFtZQorICAgICAgICAgICAgZm9yIChpID0gbGFzdFdvcmQgKyAzOyBpIDwgRlJBTUVfTEVOR1RIICsgMjsgaSsrKSB7CisgICAgICAgICAgICAgICAgc2VlZFtpXSA9IDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGJpdHMgPSAoc2VlZExlbmd0aCA8PCAzKSArIDY0OyAvLyB0cmFuc2Zvcm1pbmcgIyBvZiBieXRlcyBpbnRvICMgb2YgYml0cworCisgICAgICAgICAgICAvLyBwdXR0aW5nICMgb2YgYml0cyBpbnRvIHR3byBsYXN0IHdvcmRzICgxNCwxNSkgb2YgMTYgd29yZCBmcmFtZSBpbgorICAgICAgICAgICAgLy8gc2VlZCBvciBjb3BpZXMgYXJyYXkgZGVwZW5kaW5nIG9uIHRvdGFsIGxlbmd0aCBhZnRlciBwYWRkaW5nCisgICAgICAgICAgICBpZiAoc2VlZFtCWVRFU19PRkZTRVRdIDwgTUFYX0JZVEVTKSB7CisgICAgICAgICAgICAgICAgc2VlZFsxNF0gPSAoaW50KSAoYml0cyA+Pj4gMzIpOworICAgICAgICAgICAgICAgIHNlZWRbMTVdID0gKGludCkgKGJpdHMgJiAweEZGRkZGRkZGKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgY29waWVzW0VYVFJBRlJBTUVfT0ZGU0VUICsgMTRdID0gKGludCkgKGJpdHMgPj4+IDMyKTsKKyAgICAgICAgICAgICAgICBjb3BpZXNbRVhUUkFGUkFNRV9PRkZTRVQgKyAxNV0gPSAoaW50KSAoYml0cyAmIDB4RkZGRkZGRkYpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBuZXh0QkluZGV4ID0gSEFTSEJZVEVTX1RPX1VTRTsgLy8gc2tpcHBpbmcgcmVtYWluaW5nIHJhbmRvbSBiaXRzCisgICAgICAgIH0KKyAgICAgICAgc3RhdGUgPSBORVhUX0JZVEVTOworCisgICAgICAgIGlmIChieXRlcy5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgbmV4dEJ5dGVUb1JldHVybiA9IDA7CisKKyAgICAgICAgLy8gcG9zc2libHkgbm90IGFsbCBvZiBIQVNIQllURVNfVE9fVVNFIGJ5dGVzIHdlcmUgdXNlZCBwcmV2aW91cyB0aW1lCisgICAgICAgIG4gPSAoSEFTSEJZVEVTX1RPX1VTRSAtIG5leHRCSW5kZXgpIDwgKGJ5dGVzLmxlbmd0aCAtIG5leHRCeXRlVG9SZXR1cm4pID8gSEFTSEJZVEVTX1RPX1VTRQorICAgICAgICAgICAgICAgIC0gbmV4dEJJbmRleAorICAgICAgICAgICAgICAgIDogYnl0ZXMubGVuZ3RoIC0gbmV4dEJ5dGVUb1JldHVybjsKKyAgICAgICAgaWYgKG4gPiAwKSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5leHRCeXRlcywgbmV4dEJJbmRleCwgYnl0ZXMsIG5leHRCeXRlVG9SZXR1cm4sIG4pOworICAgICAgICAgICAgbmV4dEJJbmRleCArPSBuOworICAgICAgICAgICAgbmV4dEJ5dGVUb1JldHVybiArPSBuOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG5leHRCeXRlVG9SZXR1cm4gPj0gYnl0ZXMubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm47IC8vIHJldHVybiBiZWNhdXNlICJieXRlc1tdIiBhcmUgZmlsbGVkIGluCisgICAgICAgIH0KKworICAgICAgICBuID0gc2VlZFtCWVRFU19PRkZTRVRdICYgMHgwMzsKKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgaWYgKG4gPT0gMCkgeworCisgICAgICAgICAgICAgICAgc2VlZFtsYXN0V29yZF0gPSAoaW50KSAoY291bnRlciA+Pj4gMzIpOworICAgICAgICAgICAgICAgIHNlZWRbbGFzdFdvcmQgKyAxXSA9IChpbnQpIChjb3VudGVyICYgMHhGRkZGRkZGRik7CisgICAgICAgICAgICAgICAgc2VlZFtsYXN0V29yZCArIDJdID0gRU5EX0ZMQUdTWzBdOworCisgICAgICAgICAgICB9IGVsc2UgeworCisgICAgICAgICAgICAgICAgc2VlZFtsYXN0V29yZF0gfD0gKGludCkgKChjb3VudGVyID4+PiBSSUdIVDFbbl0pICYgTUFTS1tuXSk7CisgICAgICAgICAgICAgICAgc2VlZFtsYXN0V29yZCArIDFdID0gKGludCkgKChjb3VudGVyID4+PiBSSUdIVDJbbl0pICYgMHhGRkZGRkZGRik7CisgICAgICAgICAgICAgICAgc2VlZFtsYXN0V29yZCArIDJdID0gKGludCkgKChjb3VudGVyIDw8IExFRlRbbl0pIHwgRU5EX0ZMQUdTW25dKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzZWVkW0JZVEVTX09GRlNFVF0gPiBNQVhfQllURVMpIHsKKyAgICAgICAgICAgICAgICBjb3BpZXNbRVhUUkFGUkFNRV9PRkZTRVRdID0gc2VlZFtGUkFNRV9MRU5HVEhdOworICAgICAgICAgICAgICAgIGNvcGllc1tFWFRSQUZSQU1FX09GRlNFVCArIDFdID0gc2VlZFtGUkFNRV9MRU5HVEggKyAxXTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU0hBMUltcGwuY29tcHV0ZUhhc2goc2VlZCk7CisKKyAgICAgICAgICAgIGlmIChzZWVkW0JZVEVTX09GRlNFVF0gPiBNQVhfQllURVMpIHsKKworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2VlZCwgMCwgY29waWVzLCBGUkFNRV9PRkZTRVQsIEZSQU1FX0xFTkdUSCk7CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShjb3BpZXMsIEVYVFJBRlJBTUVfT0ZGU0VULCBzZWVkLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVfTEVOR1RIKTsKKworICAgICAgICAgICAgICAgIFNIQTFJbXBsLmNvbXB1dGVIYXNoKHNlZWQpOworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY29waWVzLCBGUkFNRV9PRkZTRVQsIHNlZWQsIDAsIEZSQU1FX0xFTkdUSCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb3VudGVyKys7CisKKyAgICAgICAgICAgIGludCBqID0gMDsKKyAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBFWFRSQUZSQU1FX09GRlNFVDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaW50IGsgPSBzZWVkW0hBU0hfT0ZGU0VUICsgaV07CisgICAgICAgICAgICAgICAgbmV4dEJ5dGVzW2pdID0gKGJ5dGUpIChrID4+PiAyNCk7IC8vIGdldHRpbmcgZmlyc3QgIGJ5dGUgZnJvbSBsZWZ0CisgICAgICAgICAgICAgICAgbmV4dEJ5dGVzW2ogKyAxXSA9IChieXRlKSAoayA+Pj4gMTYpOyAvLyBnZXR0aW5nIHNlY29uZCBieXRlIGZyb20gbGVmdAorICAgICAgICAgICAgICAgIG5leHRCeXRlc1tqICsgMl0gPSAoYnl0ZSkgKGsgPj4+IDgpOyAvLyBnZXR0aW5nIHRoaXJkICBieXRlIGZyb20gbGVmdAorICAgICAgICAgICAgICAgIG5leHRCeXRlc1tqICsgM10gPSAoYnl0ZSkgKGspOyAvLyBnZXR0aW5nIGZvdXJ0aCBieXRlIGZyb20gbGVmdAorICAgICAgICAgICAgICAgIGogKz0gNDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgbmV4dEJJbmRleCA9IDA7CisgICAgICAgICAgICBqID0gSEFTSEJZVEVTX1RPX1VTRSA8IChieXRlcy5sZW5ndGggLSBuZXh0Qnl0ZVRvUmV0dXJuKSA/IEhBU0hCWVRFU19UT19VU0UKKyAgICAgICAgICAgICAgICAgICAgOiBieXRlcy5sZW5ndGggLSBuZXh0Qnl0ZVRvUmV0dXJuOworCisgICAgICAgICAgICBpZiAoaiA+IDApIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5leHRCeXRlcywgMCwgYnl0ZXMsIG5leHRCeXRlVG9SZXR1cm4sIGopOworICAgICAgICAgICAgICAgIG5leHRCeXRlVG9SZXR1cm4gKz0gajsKKyAgICAgICAgICAgICAgICBuZXh0QkluZGV4ICs9IGo7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChuZXh0Qnl0ZVRvUmV0dXJuID49IGJ5dGVzLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBvb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgaW50W10gaW50RGF0YSA9IG51bGw7CisKKyAgICAgICAgZmluYWwgaW50IG9ubHlfaGFzaCA9IEVYVFJBRlJBTUVfT0ZGU0VUOworICAgICAgICBmaW5hbCBpbnQgaGFzaGVzX2FuZF9mcmFtZSA9IEVYVFJBRlJBTUVfT0ZGU0VUICogMiArIEZSQU1FX0xFTkdUSDsKKyAgICAgICAgZmluYWwgaW50IGhhc2hlc19hbmRfZnJhbWVfZXh0cmEgPSBFWFRSQUZSQU1FX09GRlNFVCAqIDIgKyBGUkFNRV9MRU5HVEgKKyAgICAgICAgICAgICAgICAqIDI7CisKKyAgICAgICAgb29zLndyaXRlTG9uZyhzZWVkTGVuZ3RoKTsKKyAgICAgICAgb29zLndyaXRlTG9uZyhjb3VudGVyKTsKKyAgICAgICAgb29zLndyaXRlSW50KHN0YXRlKTsKKyAgICAgICAgb29zLndyaXRlSW50KHNlZWRbQllURVNfT0ZGU0VUXSk7CisKKyAgICAgICAgaW50IG5SZW1haW5pbmcgPSAoc2VlZFtCWVRFU19PRkZTRVRdICsgMykgPj4gMjsgLy8gY29udmVydGluZyBieXRlcyBpbiB3b3JkcworICAgICAgICAvLyByZXN1bHQgbWF5IGJlIDAKKyAgICAgICAgaWYgKHN0YXRlICE9IE5FWFRfQllURVMpIHsKKworICAgICAgICAgICAgLy8gZWl0aGVyIHRoZSBzdGF0ZSBpcyBVTkRFRklORUQgb3IgcHJldmlvdXMgbWV0aG9kIHdhcyAic2V0U2VlZCguLikiCisgICAgICAgICAgICAvLyBzbyBpbiAic2VlZFtdIiB0byBzZXJpYWxpemUgYXJlIHJlbWFpbmluZyBieXRlcyAoc2VlZFswLW5SZW1haW5pbmddKSBhbmQKKyAgICAgICAgICAgIC8vIGN1cnJlbnQgaGFzaCAoc2VlZFs4Mi04Nl0pCisKKyAgICAgICAgICAgIGludERhdGEgPSBuZXcgaW50W29ubHlfaGFzaCArIG5SZW1haW5pbmddOworCisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHNlZWQsIDAsIGludERhdGEsIDAsIG5SZW1haW5pbmcpOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzZWVkLCBIQVNIX09GRlNFVCwgaW50RGF0YSwgblJlbWFpbmluZywKKyAgICAgICAgICAgICAgICAgICAgRVhUUkFGUkFNRV9PRkZTRVQpOworCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBwcmV2aW91cyBtZXRob2Qgd2FzICJuZXh0Qnl0ZXMoLi4pIgorICAgICAgICAgICAgLy8gc28sIGRhdGEgdG8gc2VyaWFsaXplIGFyZSBhbGwgdGhlIGFib3ZlICh0d28gZmlyc3QgYXJlIGluICJjb3BpZXMiIGFycmF5KQorICAgICAgICAgICAgLy8gYW5kIGN1cnJlbnQgd29yZHMgaW4gYm90aCBmcmFtZSBhbmQgZXh0cmEgZnJhbWUgKGFzIGlmKQorCisgICAgICAgICAgICBpbnQgb2Zmc2V0ID0gMDsKKyAgICAgICAgICAgIGlmIChzZWVkW0JZVEVTX09GRlNFVF0gPCBNQVhfQllURVMpIHsgLy8gbm8gZXh0cmEgZnJhbWUKKworICAgICAgICAgICAgICAgIGludERhdGEgPSBuZXcgaW50W2hhc2hlc19hbmRfZnJhbWUgKyBuUmVtYWluaW5nXTsKKworICAgICAgICAgICAgfSBlbHNlIHsgLy8gZXh0cmEgZnJhbWUgaXMgdXNlZAorCisgICAgICAgICAgICAgICAgaW50RGF0YSA9IG5ldyBpbnRbaGFzaGVzX2FuZF9mcmFtZV9leHRyYSArIG5SZW1haW5pbmddOworCisgICAgICAgICAgICAgICAgaW50RGF0YVtvZmZzZXRdID0gc2VlZFtGUkFNRV9MRU5HVEhdOworICAgICAgICAgICAgICAgIGludERhdGFbb2Zmc2V0ICsgMV0gPSBzZWVkW0ZSQU1FX0xFTkdUSCArIDFdOworICAgICAgICAgICAgICAgIGludERhdGFbb2Zmc2V0ICsgMl0gPSBzZWVkW0ZSQU1FX0xFTkdUSCArIDE0XTsKKyAgICAgICAgICAgICAgICBpbnREYXRhW29mZnNldCArIDNdID0gc2VlZFtGUkFNRV9MRU5HVEggKyAxNV07CisgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2VlZCwgMCwgaW50RGF0YSwgb2Zmc2V0LCBGUkFNRV9MRU5HVEgpOworICAgICAgICAgICAgb2Zmc2V0ICs9IEZSQU1FX0xFTkdUSDsKKworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShjb3BpZXMsIEZSQU1FX0xFTkdUSCArIEVYVFJBRlJBTUVfT0ZGU0VULCBpbnREYXRhLAorICAgICAgICAgICAgICAgICAgICBvZmZzZXQsIG5SZW1haW5pbmcpOworICAgICAgICAgICAgb2Zmc2V0ICs9IG5SZW1haW5pbmc7CisKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY29waWVzLCAwLCBpbnREYXRhLCBvZmZzZXQsIEVYVFJBRlJBTUVfT0ZGU0VUKTsKKyAgICAgICAgICAgIG9mZnNldCArPSBFWFRSQUZSQU1FX09GRlNFVDsKKworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzZWVkLCBIQVNIX09GRlNFVCwgaW50RGF0YSwgb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICBFWFRSQUZSQU1FX09GRlNFVCk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnREYXRhLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBvb3Mud3JpdGVJbnQoaW50RGF0YVtpXSk7CisgICAgICAgIH0KKworICAgICAgICBvb3Mud3JpdGVJbnQobmV4dEJJbmRleCk7CisgICAgICAgIG9vcy53cml0ZShuZXh0Qnl0ZXMsIG5leHRCSW5kZXgsIEhBU0hCWVRFU19UT19VU0UgLSBuZXh0QkluZGV4KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBvaXMpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworCisgICAgICAgIHNlZWQgPSBuZXcgaW50W0hBU0hfT0ZGU0VUICsgRVhUUkFGUkFNRV9PRkZTRVRdOworICAgICAgICBjb3BpZXMgPSBuZXcgaW50WzIgKiBGUkFNRV9MRU5HVEggKyBFWFRSQUZSQU1FX09GRlNFVF07CisgICAgICAgIG5leHRCeXRlcyA9IG5ldyBieXRlW0RJR0VTVF9MRU5HVEhdOworCisgICAgICAgIHNlZWRMZW5ndGggPSBvaXMucmVhZExvbmcoKTsKKyAgICAgICAgY291bnRlciA9IG9pcy5yZWFkTG9uZygpOworICAgICAgICBzdGF0ZSA9IG9pcy5yZWFkSW50KCk7CisgICAgICAgIHNlZWRbQllURVNfT0ZGU0VUXSA9IG9pcy5yZWFkSW50KCk7CisKKyAgICAgICAgaW50IG5SZW1haW5pbmcgPSAoc2VlZFtCWVRFU19PRkZTRVRdICsgMykgPj4gMjsgLy8gY29udmVydGluZyBieXRlcyBpbiB3b3JkcworCisgICAgICAgIGlmIChzdGF0ZSAhPSBORVhUX0JZVEVTKSB7CisKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgblJlbWFpbmluZzsgaSsrKSB7CisgICAgICAgICAgICAgICAgc2VlZFtpXSA9IG9pcy5yZWFkSW50KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEVYVFJBRlJBTUVfT0ZGU0VUOyBpKyspIHsKKyAgICAgICAgICAgICAgICBzZWVkW0hBU0hfT0ZGU0VUICsgaV0gPSBvaXMucmVhZEludCgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKHNlZWRbQllURVNfT0ZGU0VUXSA+PSBNQVhfQllURVMpIHsKKworICAgICAgICAgICAgICAgIC8vIHJlYWRpbmcgbmV4dCBieXRlcyBpbiBzZWVkIGV4dHJhIGZyYW1lCisgICAgICAgICAgICAgICAgc2VlZFtGUkFNRV9MRU5HVEhdID0gb2lzLnJlYWRJbnQoKTsKKyAgICAgICAgICAgICAgICBzZWVkW0ZSQU1FX0xFTkdUSCArIDFdID0gb2lzLnJlYWRJbnQoKTsKKyAgICAgICAgICAgICAgICBzZWVkW0ZSQU1FX0xFTkdUSCArIDE0XSA9IG9pcy5yZWFkSW50KCk7CisgICAgICAgICAgICAgICAgc2VlZFtGUkFNRV9MRU5HVEggKyAxNV0gPSBvaXMucmVhZEludCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gcmVhZGluZyBuZXh0IGJ5dGVzIGluIHNlZWQgZnJhbWUKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgRlJBTUVfTEVOR1RIOyBpKyspIHsKKyAgICAgICAgICAgICAgICBzZWVkW2ldID0gb2lzLnJlYWRJbnQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIHJlYWRpbmcgcmVtYWluaW5nIHNlZWQgYnl0ZXMKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgblJlbWFpbmluZzsgaSsrKSB7CisgICAgICAgICAgICAgICAgY29waWVzW0ZSQU1FX0xFTkdUSCArIEVYVFJBRlJBTUVfT0ZGU0VUICsgaV0gPSBvaXMucmVhZEludCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gcmVhZGluZyBjb3B5IG9mIGN1cnJlbnQgaGFzaAorICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBFWFRSQUZSQU1FX09GRlNFVDsgaSsrKSB7CisgICAgICAgICAgICAgICAgY29waWVzW2ldID0gb2lzLnJlYWRJbnQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIHJlYWRpbmcgY3VycmVudCBoYXNoCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEVYVFJBRlJBTUVfT0ZGU0VUOyBpKyspIHsKKyAgICAgICAgICAgICAgICBzZWVkW0hBU0hfT0ZGU0VUICsgaV0gPSBvaXMucmVhZEludCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgbmV4dEJJbmRleCA9IG9pcy5yZWFkSW50KCk7CisgICAgICAgIFN0cmVhbXMucmVhZEZ1bGx5KG9pcywgbmV4dEJ5dGVzLCBuZXh0QkluZGV4LCBIQVNIQllURVNfVE9fVVNFIC0gbmV4dEJJbmRleCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vU0hBMV9EYXRhLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Byb3ZpZGVyL2NyeXB0by9TSEExX0RhdGEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNTU5NTc2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vU0hBMV9EYXRhLmphdmEKQEAgLTAsMCArMSw4MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorKiBAYXV0aG9yIFl1cmkgQS4gS3JvcGFjaGV2CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkucHJvdmlkZXIuY3J5cHRvOworCisKKy8qKgorICogVGhpcyBpbnRlcmZhY2UgY29udGFpbnMgOiA8QlI+CisgKiAtIGEgc2V0IG9mIGNvbnN0YW50IHZhbHVlcywgSDAtSDQsIGRlZmluZWQgaW4gIlNFQ1VSRSBIQVNIIFNUQU5EQVJEIiwgRklQUyBQVUIgMTgwLTIgOzxCUj4KKyAqIC0gaW1wbGVtZW50YXRpb24gY29uc3RhbnQgdmFsdWVzIHRvIHVzZSBpbiBjbGFzc2VzIHVzaW5nIFNIQS0xIGFsZ29yaXRobS4gICAgPEJSPgorICovCisKKworcHVibGljIGludGVyZmFjZSBTSEExX0RhdGEgeworCisKKyAgICAvKioKKyAgICAgKiAgY29uc3RhbnQgZGVmaW5lZCBpbiAiU0VDVVJFIEhBU0ggU1RBTkRBUkQiCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGludCBIMCA9IDB4Njc0NTIzMDE7CisKKworICAgIC8qKgorICAgICAqICBjb25zdGFudCBkZWZpbmVkIGluICJTRUNVUkUgSEFTSCBTVEFOREFSRCIKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgaW50IEgxID0gMHhFRkNEQUI4OTsKKworCisgICAgLyoqCisgICAgICogIGNvbnN0YW50IGRlZmluZWQgaW4gIlNFQ1VSRSBIQVNIIFNUQU5EQVJEIgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBpbnQgSDIgPSAweDk4QkFEQ0ZFOworCisKKyAgICAvKioKKyAgICAgKiAgY29uc3RhbnQgZGVmaW5lZCBpbiAiU0VDVVJFIEhBU0ggU1RBTkRBUkQiCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGludCBIMyA9IDB4MTAzMjU0NzY7CisKKworICAgIC8qKgorICAgICAqICBjb25zdGFudCBkZWZpbmVkIGluICJTRUNVUkUgSEFTSCBTVEFOREFSRCIKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgaW50IEg0ID0gMHhDM0QyRTFGMDsKKworCisgICAgLyoqCisgICAgICogb2Zmc2V0IGluIGJ1ZmZlciB0byBzdG9yZSBudW1iZXIgb2YgYnl0ZXMgaW4gMC0xNSB3b3JkIGZyYW1lCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGludCBCWVRFU19PRkZTRVQgPSA4MTsKKworCisgICAgLyoqCisgICAgICogb2Zmc2V0IGluIGJ1ZmZlciB0byBzdG9yZSBjdXJyZW50IGhhc2ggdmFsdWUKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgaW50IEhBU0hfT0ZGU0VUID0gODI7CisKKworICAgIC8qKgorICAgICAqICMgb2YgYnl0ZXMgaW4gSDAtSDQgd29yZHM7IDxCUj4KKyAgICAgKiBpbiB0aGlzIGltcGxlbWVudGF0aW9uICMgaXMgc2V0IHRvIDIwIChpbiBnZW5lcmFsICMgdmFyaWVzIGZyb20gMSB0byAyMCkKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgaW50IERJR0VTVF9MRU5HVEggPSAyMDsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY3J5cHRvL1NIQTFfTWVzc2FnZURpZ2VzdEltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvcHJvdmlkZXIvY3J5cHRvL1NIQTFfTWVzc2FnZURpZ2VzdEltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MTIyM2I3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vU0hBMV9NZXNzYWdlRGlnZXN0SW1wbC5qYXZhCkBAIC0wLDAgKzEsMzA4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnByb3ZpZGVyLmNyeXB0bzsKKworCitpbXBvcnQgamF2YS5zZWN1cml0eS5EaWdlc3RFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0U3BpOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKworLyoqCisgKiBUaGlzIGNsYXNzIGV4dGVuZHMgdGhlIE1lc3NhZ2VEaWdlc3RTcGkgY2xhc3MgaW1wbGVtZW50aW5nIGFsbCBpdHMgYWJzdHJhY3QgbWV0aG9kczsKKyAqIGl0IG92ZXJyaWRlcyB0aGUgIk9iamVjdCBjbG9uZSgpIiBhbmQgImludCBlbmdpbmVHZXREaWdlc3RMZW5ndGgoKSIgbWV0aG9kcy4gPEJSPgorICogVGhlIGNsYXNzIGltcGxlbWVudHMgdGhlIENsb25lYWJsZSBpbnRlcmZhY2UuCisgKi8KKworCitwdWJsaWMgY2xhc3MgU0hBMV9NZXNzYWdlRGlnZXN0SW1wbCBleHRlbmRzIE1lc3NhZ2VEaWdlc3RTcGkgaW1wbGVtZW50cyBDbG9uZWFibGUsIFNIQTFfRGF0YSB7CisgICAgcHJpdmF0ZSBpbnRbXSBidWZmZXI7ICAgICAgICAvLyBidWZmZXIgaGFzIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gLSAgMC0xNiAtIGZyYW1lIGZvciBhY2N1bXVsYXRpbmcgYSBtZXNzYWdlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAtIDE3LTc5IC0gZm9yIFNIQTFJbXBsIG1ldGhvZHMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIC0gODAgICAgLSB1bnVzZWQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIC0gODEgICAgLSB0byBzdG9yZSBsZW5ndGggb2YgdGhlIG1lc3NhZ2UKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIC0gODItODYgLSBmcmFtZSBmb3IgY3VycmVudCBtZXNzYWdlIGRpZ2VzdAorCisgICAgcHJpdmF0ZSBieXRlW10gb25lQnl0ZTsgICAgICAvLyBvbmUgYnl0ZSBidWZmZXIgbmVlZGVkIHRvIHVzZSBpbiBlbmdpbmVVcGRhdGUoYnl0ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhdmluZyBidWZmZXIgYXMgcHJpdmF0ZSBmaWVsZCBpcyBqdXN0IG9wdGltaXphdGlvbgorCisgICAgcHJpdmF0ZSBsb25nIG1lc3NhZ2VMZW5ndGg7ICAgLy8gdG90YWwgbGVuZ3RoIG9mIGJ5dGVzIHN1cHBsaWVkIGJ5IHVzZXIKKworCisgICAgLyoqCisgICAgICogIFRoZSBjb25zdHJ1Y3RvciBjcmVhdGVzIG5lZWRlZCBidWZmZXJzIGFuZCBzZXRzIHRoZSBlbmdpbmUgYXQgaW5pdGlhbCBzdGF0ZQorICAgICAqLworICAgIHB1YmxpYyBTSEExX01lc3NhZ2VEaWdlc3RJbXBsKCkgeworCisgICAgICAgIC8vIEJZVEVTX09GRlNFVCArNiBpcyBtaW5pbWFsIGxlbmd0aCByZXF1aXJlZCBieSBtZXRob2RzIGluIFNIQTFJbXBsCisgICAgICAgIGJ1ZmZlciAgPSBuZXcgaW50W0JZVEVTX09GRlNFVCArNl07CisKKyAgICAgICAgb25lQnl0ZSA9IG5ldyBieXRlWzFdOworCisgICAgICAgIGVuZ2luZVJlc2V0KCk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBUaGUgbWV0aG9kIHBlcmZvcm1zIGZpbmFsIGFjdGlvbnMgYW5kIGludm9rZXMgdGhlICJjb21wdXRlSGFzaChpbnRbXSkiIG1ldGhvZC4KKyAgICAgKiBJbiBjYXNlIGlmIHRoZXJlIGlzIG5vIGVub3VnaCB3b3JkcyBpbiBjdXJyZW50IGZyYW1lCisgICAgICogYWZ0ZXIgcHJvY2Vzc2luZyBpdHMgZGF0YSwgZXh0cmEgZnJhbWUgaXMgcHJlcGFyZWQgYW5kCisgICAgICogdGhlICJjb21wdXRlSGFzaChpbnRbXSkiIG1ldGhvZCBpcyBpbnZva2VkIHNlY29uZCB0aW1lLiA8QlI+CisgICAgICoKKyAgICAgKiBBZnRlciBwcm9jZXNzaW5nLCB0aGUgbWV0aG9kIHJlc2V0cyBlbmdpbmUncyBzdGF0ZQorICAgICAqCisgICAgICogQHBhcmFtCisgICAgICogICAgICAgZGlnZXN0IC0gYnl0ZSBhcnJheQorICAgICAqIEBwYXJhbQorICAgICAqICAgICAgIG9mZnNldCAtIG9mZnNldCBpbiBkaWdlc3QKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcHJvY2Vzc0RpZ2VzdChieXRlW10gZGlnZXN0LCBpbnQgb2Zmc2V0KSB7CisKKyAgICAgICAgaW50IGksIGo7ICAgICAgICAgLy8gaW1wbGVtZW50YXRpb24gdmFyaWFibGVzCisgICAgICAgIGludCBsYXN0V29yZDsgICAgIC8vCisKKyAgICAgICAgbG9uZyBuQml0cyA9IG1lc3NhZ2VMZW5ndGggPDwzIDsgIC8vIGxlbmd0aCBoYXMgdG8gYmUgY2FsY3VsYXRlZCBiZWZvcmUgcGFkZGluZworCisgICAgICAgIGVuZ2luZVVwZGF0ZSggKGJ5dGUpIDB4ODAgKTsgICAgICAvLyBiZWdpbm5pbmcgYnl0ZSBpbiBwYWRkaW5nCisKKyAgICAgICAgaSA9IDA7ICAgICAgICAgICAgICAgICAgICAgLy8gaSBjb250YWlucyBudW1iZXIgb2YgYmVnaW5uaW5nIHdvcmQgZm9yIGZvbGxvd2luZyBsb29wCisKKyAgICAgICAgbGFzdFdvcmQgPSAoYnVmZmVyW0JZVEVTX09GRlNFVF0gKyAzKT4+MiA7ICAvLyBjb21wdXRpbmcgb2YgIyBvZiBmdWxsIHdvcmRzIGJ5IHNoaWZ0aW5nCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIyBvZiBieXRlcworCisgICAgICAgIC8vIHBvc3NpYmxlIGNhc2VzOgorICAgICAgICAvLworICAgICAgICAvLyAtIGJ1ZmZlcltCWVRFU19PRkZTRVRdID09IDAgLSBidWZmZXIgZnJhbWUgaXMgZW1wdHksCisgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgIHBhZGRpbmcgYnl0ZSB3YXMgNjR0aCBpbiBwcmV2aW91cyBmcmFtZQorICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50IGZyYW1lIHNob3VsZCBjb250YWluIG9ubHkgbWVzc2FnZSdzIGxlbmd0aAorICAgICAgICAvLworICAgICAgICAvLyAtIGxhc3RXb3JkIDwgMTQgLSB0d28gbGFzdCwgdGhlc2UgYXJlIDE0ICYgMTUsIHdvcmRzIGluIDE2IHdvcmQgZnJhbWUgYXJlIGZyZWU7CisgICAgICAgIC8vICAgICAgICAgICAgICAgICAgIG5vIGV4dHJhIGZyYW1lIG5lZWRlZAorICAgICAgICAvLyAtIGxhc3RXb3JkID0gMTQgLSBvbmx5IG9uZSBsYXN0LCBuYW1lbHkgMTUtdGgsIHdvcmQgaW4gZnJhbWUgZG9lc24ndCBjb250YWluIGJ5dGVzOworICAgICAgICAvLyAgICAgICAgICAgICAgICAgICBleHRyYSBmcmFtZSBpcyBuZWVkZWQKKyAgICAgICAgLy8gLSBsYXN0V29yZCA+IDE0IC0gbGFzdCB3b3JkIGluIGZyYW1lIGlzIG5vdCBmdWxsOworICAgICAgICAvLyAgICAgICAgICAgICAgICAgICBleHRyYSBmcmFtZSBpcyBuZWVkZWQKKworICAgICAgICBpZiAoIGJ1ZmZlcltCWVRFU19PRkZTRVRdICE9IDAgKSB7CisKKyAgICAgICAgICAgIGlmICggbGFzdFdvcmQgPCAxNSApIHsKKyAgICAgICAgICAgICAgICBpID0gbGFzdFdvcmQ7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmICggbGFzdFdvcmQgPT0gMTUgKSB7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclsxNV0gPSAwOyAgICAgICAvLyBsYXN0IHdvcmQgaW4gZnJhbWUgaXMgc2V0IHRvICIwIgorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBTSEExSW1wbC5jb21wdXRlSGFzaChidWZmZXIpOworICAgICAgICAgICAgICAgIGkgPSAwOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIEFycmF5cy5maWxsKGJ1ZmZlciwgaSwgMTQsIDApOworCisgICAgICAgIGJ1ZmZlclsxNF0gPSAoaW50KSggbkJpdHMgPj4+MzIgKTsKKyAgICAgICAgYnVmZmVyWzE1XSA9IChpbnQpKCBuQml0cyAmIDB4RkZGRkZGRkYgKTsKKyAgICAgICAgU0hBMUltcGwuY29tcHV0ZUhhc2goYnVmZmVyKTsKKworICAgICAgICAvLyBjb252ZXJ0aW5nIDUtd29yZCBmcmFtZSBpbnRvIDIwIGJ5dGVzCisgICAgICAgIGogPSBvZmZzZXQ7CisgICAgICAgIGZvciAoIGkgPSBIQVNIX09GRlNFVDsgaSA8IEhBU0hfT0ZGU0VUICs1OyBpKysgKSB7CisgICAgICAgICAgICBpbnQgayA9IGJ1ZmZlcltpXTsKKyAgICAgICAgICAgIGRpZ2VzdFtqICBdID0gKGJ5dGUpICggayA+Pj4yNCApOyAgIC8vIGdldHRpbmcgZmlyc3QgIGJ5dGUgZnJvbSBsZWZ0CisgICAgICAgICAgICBkaWdlc3RbaisxXSA9IChieXRlKSAoIGsgPj4+MTYgKTsgICAvLyBnZXR0aW5nIHNlY29uZCBieXRlIGZyb20gbGVmdAorICAgICAgICAgICAgZGlnZXN0W2orMl0gPSAoYnl0ZSkgKCBrID4+PiA4ICk7ICAgLy8gZ2V0dGluZyB0aGlyZCAgYnl0ZSBmcm9tIGxlZnQKKyAgICAgICAgICAgIGRpZ2VzdFtqKzNdID0gKGJ5dGUpICggayAgICAgICApOyAgIC8vIGdldHRpbmcgZm91cnRoIGJ5dGUgZnJvbSBsZWZ0CisgICAgICAgICAgICBqICs9IDQ7CisgICAgICAgIH0KKworICAgICAgICBlbmdpbmVSZXNldCgpOworICAgIH0KKworICAgIC8vICBtZXRob2RzIHNwZWNpZmllZCBpbiBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3RTcGkKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSAiZGVlcCIgY29weSBvZiB0aGlzIFNIQTFNREltcGwgb2JqZWN0LiA8QlI+CisgICAgICoKKyAgICAgKiBUaGUgbWV0aG9kIG92ZXJyaWRlcyAiY2xvbmUoKSIgaW4gY2xhc3MgT2JqZWN0LiA8QlI+CisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgICAgYSBjbG9uZSBvZiB0aGlzIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICBTSEExX01lc3NhZ2VEaWdlc3RJbXBsIGNsb25lT2JqID0gKFNIQTFfTWVzc2FnZURpZ2VzdEltcGwpIHN1cGVyLmNsb25lKCk7CisgICAgICAgIGNsb25lT2JqLmJ1ZmZlciA9IGJ1ZmZlci5jbG9uZSgpOworICAgICAgICBjbG9uZU9iai5vbmVCeXRlID0gb25lQnl0ZS5jbG9uZSgpOworICAgICAgICByZXR1cm4gY2xvbmVPYmo7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlcyBhIG1lc3NhZ2UgZGlnZXN0IHZhbHVlLiA8QlI+CisgICAgICoKKyAgICAgKiBUaGUgbWV0aG9kIHJlc2V0cyB0aGUgZW5naW5lLiA8QlI+CisgICAgICoKKyAgICAgKiBUaGUgbWV0aG9kIG92ZXJyaWRlcyAiZW5naW5lRGlnZXN0KCkiIGluIGNsYXNzIE1lc3NhZ2VEaWdlc3RTcGkuIDxCUj4KKyAgICAgKgorICAgICAqIEByZXR1cm4KKyAgICAgKiAgICAgICBieXRlIGFycmF5IGNvbnRhaW5pbmcgbWVzc2FnZSBkaWdlc3QgdmFsdWUKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuZ2luZURpZ2VzdCgpIHsKKyAgICAgICAgYnl0ZVtdIGhhc2ggPSBuZXcgYnl0ZVtESUdFU1RfTEVOR1RIXTsKKyAgICAgICAgcHJvY2Vzc0RpZ2VzdChoYXNoLCAwKTsKKyAgICAgICAgcmV0dXJuIGhhc2g7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlcyBtZXNzYWdlIGRpZ2VzdCB2YWx1ZS4KKyAgICAgKiBVcG9uIHJldHVybiwgdGhlIHZhbHVlIGlzIHN0b3JlZCBpbiAiYnVmIiBidWZmZXIgYmVnaW5uaW5nICJvZmZzZXQiIGJ5dGUuIDxCUj4KKyAgICAgKgorICAgICAqIFRoZSBtZXRob2QgcmVzZXRzIHRoZSBlbmdpbmUuIDxCUj4KKyAgICAgKgorICAgICAqIFRoZSBtZXRob2Qgb3ZlcnJpZGVzICJlbmdpbmVEaWdlc3QoYnl0ZVtdLGludCxpbnQpIGluIGNsYXNzIE1lc3NhZ2VEaWdlc3RTcGkuCisgICAgICoKKyAgICAgKiBAcGFyYW0KKyAgICAgKiAgICAgICBidWYgICAgYnl0ZSBhcnJheSB0byBzdG9yZSBhIG1lc3NhZ2UgZGlnZXN0IHJldHVybmVkCisgICAgICogQHBhcmFtCisgICAgICogICAgICAgb2Zmc2V0IGEgcG9zaXRpb24gaW4gdGhlIGFycmF5IGZvciBmaXJzdCBieXRlIG9mIHRoZSBtZXNzYWdlIGRpZ2VzdAorICAgICAqIEBwYXJhbQorICAgICAqICAgICAgIGxlbiAgICBudW1iZXIgb2YgYnl0ZXMgd2l0aGluIGJ1ZmZlciBhbGxvdHRlZCBmb3IgdGhlIG1lc3NhZ2UgZGlnZXN0OworICAgICAqICAgICAgICAgICAgICAgIGFzIHRoaXMgaW1wbGVtZW50YXRpb24gZG9lc24ndCBwcm92aWRlIHBhcnRpYWwgZGlnZXN0cywKKyAgICAgKiAgICAgICAgICAgICAgICBsZW4gc2hvdWxkIGJlID49IDIwLCBEaWdlc3RFeGNlcHRpb24gaXMgdGhyb3duIG90aGVyd2lzZQorICAgICAqIEByZXR1cm4KKyAgICAgKiAgICAgICB0aGUgbGVuZ3RoIG9mIHRoZSBtZXNzYWdlIGRpZ2VzdCBzdG9yZWQgaW4gdGhlICJidWYiIGJ1ZmZlcjsKKyAgICAgKiAgICAgICBpbiB0aGlzIGltcGxlbWVudGF0aW9uIHRoZSBsZW5ndGg9MjAKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICBpZiBudWxsIGlzIHBhc3NlZCB0byB0aGUgImJ1ZiIgYXJndW1lbnQgPEJSPgorICAgICAqICAgICAgICAgICAgICAgaWYgb2Zmc2V0ICsgbGVuID4gYnVmLmxlbmd0aCAgPEJSPgorICAgICAqICAgICAgICAgICAgICAgaWYgb2Zmc2V0ID4gYnVmLmxlbmd0aCBvciBsZW4gPiBidWYubGVuZ3RoCisgICAgICoKKyAgICAgKiBAdGhyb3dzIERpZ2VzdEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgaWYgbGVuIDwgMjAKKyAgICAgKgorICAgICAqIEB0aHJvd3MgIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgaWYgb2Zmc2V0IDwgMAorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgZW5naW5lRGlnZXN0KGJ5dGVbXSBidWYsIGludCBvZmZzZXQsIGludCBsZW4pIHRocm93cyBEaWdlc3RFeGNlcHRpb24geworICAgICAgICBpZiAoYnVmID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImJ1ZiA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9mZnNldCA+IGJ1Zi5sZW5ndGggfHwgbGVuID4gYnVmLmxlbmd0aCB8fCAobGVuICsgb2Zmc2V0KSA+IGJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobGVuIDwgRElHRVNUX0xFTkdUSCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IERpZ2VzdEV4Y2VwdGlvbigibGVuIDwgRElHRVNUX0xFTkdUSCIpOworICAgICAgICB9CisgICAgICAgIGlmIChvZmZzZXQgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldCk7CisgICAgICAgIH0KKworICAgICAgICBwcm9jZXNzRGlnZXN0KGJ1Ziwgb2Zmc2V0KTsKKworICAgICAgICByZXR1cm4gRElHRVNUX0xFTkdUSDsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBtZXNzYWdlIGRpZ2VzdCBsZW5ndGguIDxCUj4KKyAgICAgKgorICAgICAqIFRoZSBtZXRob2Qgb3ZlcnJpZGVzICJlbmdpbmVHZXREaWdlc3RMZW5ndGgoKSIgaW4gY2xhc3MgTWVzc2FnZURpZ2VzdFNwaS4gPEJSPgorICAgICAqCisgICAgICogQHJldHVybgorICAgICAqICAgICAgICB0b3RhbCBsZW5ndGggb2YgY3VycmVudCBtZXNzYWdlIGRpZ2VzdCBhcyBhbiBpbnQgdmFsdWUKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGVuZ2luZUdldERpZ2VzdExlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIERJR0VTVF9MRU5HVEg7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhlIGVuZ2luZS4gPEJSPgorICAgICAqCisgICAgICogVGhlIG1ldGhvZCBvdmVycmlkZXMgImVuZ2luZVJlc2V0KCkiIGluIGNsYXNzIE1lc3NhZ2VEaWdlc3RTcGkuIDxCUj4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVSZXNldCgpIHsKKworICAgICAgICBtZXNzYWdlTGVuZ3RoID0gMDsKKworICAgICAgICBidWZmZXJbQllURVNfT0ZGU0VUXSA9IDA7CisgICAgICAgIGJ1ZmZlcltIQVNIX09GRlNFVCAgIF0gPSBIMDsKKyAgICAgICAgYnVmZmVyW0hBU0hfT0ZGU0VUICsxXSA9IEgxOworICAgICAgICBidWZmZXJbSEFTSF9PRkZTRVQgKzJdID0gSDI7CisgICAgICAgIGJ1ZmZlcltIQVNIX09GRlNFVCArM10gPSBIMzsKKyAgICAgICAgYnVmZmVyW0hBU0hfT0ZGU0VUICs0XSA9IEg0OworICAgIH0KKworCisgICAgLyoqCisgICAgICogU3VwcGxlbWVudHMgYSBieXRlIHRvIGN1cnJlbnQgbWVzc2FnZS4gPEJSPgorICAgICAqCisgICAgICogVGhlIG1ldGhvZCBvdmVycmlkZXMgImVuZ2luZVVwZGF0ZShieXRlKSIgaW4gY2xhc3MgTWVzc2FnZURpZ2VzdFNwaS4gPEJSPgorICAgICAqCisgICAgICogQHBhcmFtCisgICAgICogICAgICAgaW5wdXQgYnl0ZSB0byBhZGQgdG8gY3VycmVudCBtZXNzYWdlCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGUgaW5wdXQpIHsKKworICAgICAgICBvbmVCeXRlWzBdID0gaW5wdXQ7CisgICAgICAgIFNIQTFJbXBsLnVwZGF0ZUhhc2goIGJ1ZmZlciwgb25lQnl0ZSwgMCwgMCApOworICAgICAgICBtZXNzYWdlTGVuZ3RoKys7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGN1cnJlbnQgbWVzc2FnZS4gPEJSPgorICAgICAqCisgICAgICogVGhlIG1ldGhvZCBvdmVycmlkZXMgImVuZ2luZVVwZGF0ZShieXRlW10saW50LGludCkiIGluIGNsYXNzIE1lc3NhZ2VEaWdlc3RTcGkuIDxCUj4KKyAgICAgKgorICAgICAqIFRoZSBtZXRob2Qgc2lsZW50bHkgcmV0dXJucyBpZiAibGVuIiA8PSAwLgorICAgICAqCisgICAgICogQHBhcmFtCisgICAgICogICAgICAgaW5wdXQgIGEgYnl0ZSBhcnJheQorICAgICAqIEBwYXJhbQorICAgICAqICAgICAgIG9mZnNldCBhIG51bWJlciBvZiBmaXJzdCBieXRlIGluIHRoZSAiaW5wdXQiIGFycmF5IHRvIHVzZSBmb3IgdXBkYXRpbmcKKyAgICAgKiBAcGFyYW0KKyAgICAgKiAgICAgICBsZW4gICAgYSBudW1iZXIgb2YgYnl0ZXMgdG8gdXNlCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgaWYgbnVsbCBpcyBwYXNzZWQgdG8gdGhlICJidWYiIGFyZ3VtZW50CisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIGlmIG9mZnNldCA+IGJ1Zi5sZW5ndGggb3IgbGVuID4gYnVmLmxlbmd0aCBvcgorICAgICAqICAgICAgICAgICAgICAgIChsZW4gKyBvZmZzZXQpID4gYnVmLmxlbmd0aAorICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgb2Zmc2V0IDwgMAorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShieXRlW10gaW5wdXQsIGludCBvZmZzZXQsIGludCBsZW4pIHsKKyAgICAgICAgaWYgKGlucHV0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImlucHV0ID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobGVuIDw9IDApIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAob2Zmc2V0IDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQpOworICAgICAgICB9CisgICAgICAgIGlmIChvZmZzZXQgPiBpbnB1dC5sZW5ndGggfHwgbGVuID4gaW5wdXQubGVuZ3RoIHx8IChsZW4gKyBvZmZzZXQpID4gaW5wdXQubGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBTSEExSW1wbC51cGRhdGVIYXNoKGJ1ZmZlciwgaW5wdXQsIG9mZnNldCwgb2Zmc2V0ICsgbGVuIC0xICk7CisgICAgICAgIG1lc3NhZ2VMZW5ndGggKz0gbGVuOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vU0hBMXdpdGhEU0FfU2lnbmF0dXJlSW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vU0hBMXdpdGhEU0FfU2lnbmF0dXJlSW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyYTljNmQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Byb3ZpZGVyL2NyeXB0by9TSEExd2l0aERTQV9TaWduYXR1cmVJbXBsLmphdmEKQEAgLTAsMCArMSw0MjMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnByb3ZpZGVyLmNyeXB0bzsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuRFNBS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5EU0FQYXJhbXM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLkRTQVByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLkRTQVB1YmxpY0tleTsKKworcHVibGljIGNsYXNzIFNIQTF3aXRoRFNBX1NpZ25hdHVyZUltcGwgZXh0ZW5kcyBTaWduYXR1cmUgeworCisgICAgcHJpdmF0ZSBNZXNzYWdlRGlnZXN0IG1zZ0RpZ2VzdDsKKworICAgIHByaXZhdGUgRFNBS2V5IGRzYUtleTsKKworICAgIC8qKgorICAgICAqIFRoZSBzb2xvIGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBTSEExd2l0aERTQV9TaWduYXR1cmVJbXBsKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisKKyAgICAgICAgc3VwZXIoIlNIQTF3aXRoRFNBIik7CisKKyAgICAgICAgbXNnRGlnZXN0ID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZSgiU0hBMSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlcHJlY2F0ZWQgbWV0aG9kLgorICAgICAqCisgICAgICogQHJldHVybgorICAgICAqICAgIG51bGwKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgT2JqZWN0IGVuZ2luZUdldFBhcmFtZXRlcihTdHJpbmcgcGFyYW0pCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwYXJhbSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyB0aGlzIHNpZ25hdHVyZSBvYmplY3Qgd2l0aCBQcml2YXRlS2V5IG9iamVjdAorICAgICAqIHBhc3NlZCBhcyBhcmd1bWVudCB0byB0aGUgbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtcworICAgICAqICAgIHByaXZhdGVLZXkgRFNBUHJpdmF0ZUtleSBvYmplY3QKKyAgICAgKiBAdGhyb3dzCisgICAgICogICAgSW52YWxpZEtleUV4Y2VwdGlvbiBpZiBwcml2YXRlS2V5IGlzIG5vdCBEU0FQcml2YXRlS2V5IG9iamVjdAorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXRTaWduKFByaXZhdGVLZXkgcHJpdmF0ZUtleSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKworICAgICAgICBEU0FQYXJhbXMgcGFyYW1zOworCisgICAgICAgIC8vIHBhcmFtZXRlcnMgYW5kIHByaXZhdGUga2V5CisgICAgICAgIEJpZ0ludGVnZXIgcCwgcSwgeDsKKworICAgICAgICBpbnQgbjsKKworICAgICAgICBpZiAocHJpdmF0ZUtleSA9PSBudWxsIHx8ICEocHJpdmF0ZUtleSBpbnN0YW5jZW9mIERTQVByaXZhdGVLZXkpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgcGFyYW1zID0gKChEU0FQcml2YXRlS2V5KSBwcml2YXRlS2V5KS5nZXRQYXJhbXMoKTsKKyAgICAgICAgcCA9IHBhcmFtcy5nZXRQKCk7CisgICAgICAgIHEgPSBwYXJhbXMuZ2V0USgpOworICAgICAgICB4ID0gKChEU0FQcml2YXRlS2V5KSBwcml2YXRlS2V5KS5nZXRYKCk7CisKKyAgICAgICAgLy8gY2hlY2tzIGRlc2NyaWJlZCBpbiBEU0Egc3RhbmRhcmQKKyAgICAgICAgbiA9IHAuYml0TGVuZ3RoKCk7CisgICAgICAgIGlmIChwLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLnZhbHVlT2YoMSkpICE9IDEgfHwgbiA8IDUxMiB8fCBuID4gMTAyNCB8fCAobiAmIDA3NykgIT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oImJhZCBwIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHEuc2lnbnVtKCkgIT0gMSAmJiBxLmJpdExlbmd0aCgpICE9IDE2MCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oImJhZCBxIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHguc2lnbnVtKCkgIT0gMSB8fCB4LmNvbXBhcmVUbyhxKSAhPSAtMSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oInggPD0gMCB8fCB4ID49IHEiKTsKKyAgICAgICAgfQorCisgICAgICAgIGRzYUtleSA9IChEU0FLZXkpIHByaXZhdGVLZXk7CisKKyAgICAgICAgbXNnRGlnZXN0LnJlc2V0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhpcyBzaWduYXR1cmUgb2JqZWN0IHdpdGggUHVibGljS2V5IG9iamVjdAorICAgICAqIHBhc3NlZCBhcyBhcmd1bWVudCB0byB0aGUgbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtcworICAgICAqICAgIHB1YmxpY0tleSBEU0FQdWJsaWNLZXkgb2JqZWN0CisgICAgICogQHRocm93cworICAgICAqICAgIEludmFsaWRLZXlFeGNlcHRpb24gaWYgcHVibGljS2V5IGlzIG5vdCBEU0FQdWJsaWNLZXkgb2JqZWN0CisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdFZlcmlmeShQdWJsaWNLZXkgcHVibGljS2V5KQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24geworCisgICAgICAgIC8vIHBhcmFtZXRlcnMgYW5kIHB1YmxpYyBrZXkKKyAgICAgICAgQmlnSW50ZWdlciBwLCBxLCB5OworCisgICAgICAgIGludCBuMTsKKworICAgICAgICBpZiAocHVibGljS2V5ID09IG51bGwgfHwgIShwdWJsaWNLZXkgaW5zdGFuY2VvZiBEU0FQdWJsaWNLZXkpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbigicHVibGljS2V5IGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBEU0FQdWJsaWNLZXkiKTsKKyAgICAgICAgfQorCisgICAgICAgIERTQVBhcmFtcyBwYXJhbXMgPSAoKERTQVB1YmxpY0tleSkgcHVibGljS2V5KS5nZXRQYXJhbXMoKTsKKyAgICAgICAgcCA9IHBhcmFtcy5nZXRQKCk7CisgICAgICAgIHEgPSBwYXJhbXMuZ2V0USgpOworICAgICAgICB5ID0gKChEU0FQdWJsaWNLZXkpIHB1YmxpY0tleSkuZ2V0WSgpOworCisgICAgICAgIC8vIGNoZWNrcyBkZXNjcmliZWQgaW4gRFNBIHN0YW5kYXJkCisgICAgICAgIG4xID0gcC5iaXRMZW5ndGgoKTsKKyAgICAgICAgaWYgKHAuY29tcGFyZVRvKEJpZ0ludGVnZXIudmFsdWVPZigxKSkgIT0gMSB8fCBuMSA8IDUxMiB8fCBuMSA+IDEwMjQgfHwgKG4xICYgMDc3KSAhPSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbigiYmFkIHAiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocS5zaWdudW0oKSAhPSAxIHx8IHEuYml0TGVuZ3RoKCkgIT0gMTYwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbigiYmFkIHEiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoeS5zaWdudW0oKSAhPSAxKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbigieSA8PSAwIik7CisgICAgICAgIH0KKworICAgICAgICBkc2FLZXkgPSAoRFNBS2V5KSBwdWJsaWNLZXk7CisKKyAgICAgICAgbXNnRGlnZXN0LnJlc2V0KCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBEZXByZWNhdGVkIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MKKyAgICAgKiAgICBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lU2V0UGFyYW1ldGVyKFN0cmluZyBwYXJhbSwgT2JqZWN0IHZhbHVlKSB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwYXJhbSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInBhcmFtID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbigiaW52YWxpZCBwYXJhbWV0ZXIgZm9yIHRoaXMgZW5naW5lIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBzaWduYXR1cmUgYnl0ZXMgYXMgYnl0ZSBhcnJheSBjb250YWluaW5nCisgICAgICogQVNOMSByZXByZXNlbnRhdGlvbiBmb3IgdHdvIEJpZ0ludGVnZXIgb2JqZWN0cworICAgICAqIHdoaWNoIGlzIFNFUVVFTkNFIG9mIHR3byBJTlRFR0VSUy4KKyAgICAgKiBMZW5ndGggb2Ygc2VxdWVuY2UgdmFyaWVzIGZyb20gbGVzcyB0aGFuIDQ2IHRvIDQ4LgorICAgICAqCisgICAgICogUmVzZXRzIG9iamVjdCB0byB0aGUgc3RhdGUgaXQgd2FzIGluCisgICAgICogd2hlbiBwcmV2aW91cyBjYWxsIHRvIGVpdGhlciAiaW5pdFNpZ24iIG1ldGhvZCB3YXMgY2FsbGVkLgorICAgICAqCisgICAgICogQHJldHVybgorICAgICAqICAgIGJ5dGUgYXJyYXkgY29udGFpbmluZyBzaWduYXR1cmUgaW4gQVNOMSByZXByZXNlbnRhdGlvbgorICAgICAqIEB0aHJvd3MKKyAgICAgKiAgICBTaWduYXR1cmVFeGNlcHRpb24gaWYgb2JqZWN0J3Mgc3RhdGUgaXMgbm90IFNJR04gb3IKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgc2lnbmF0dXJlIGFsZ29yaXRobSBjYW5ub3QgcHJvY2VzcyBkYXRhCisgICAgICovCisKKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuZ2luZVNpZ24oKSB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKworICAgICAgICAvLyBuYW1lcyBvZiBiZWxvdyBCaWdJbnRlZ2VycyBhcmUgdGhlIHNhbWUgYXMgdGhleSBhcmUgZGVmaW5lZCBpbiBEU0Egc3RhbmRhcmQKKyAgICAgICAgQmlnSW50ZWdlciByID0gbnVsbDsKKyAgICAgICAgQmlnSW50ZWdlciBzID0gbnVsbDsKKyAgICAgICAgQmlnSW50ZWdlciBrID0gbnVsbDsKKworICAgICAgICAvLyBwYXJhbWV0ZXJzIGFuZCBwcml2YXRlIGtleQorICAgICAgICBCaWdJbnRlZ2VyIHAsIHEsIGcsIHg7CisKKyAgICAgICAgLy8gQmlnSW50ZWdlciBmb3IgbWVzc2FnZSBkaWdlc3QKKyAgICAgICAgQmlnSW50ZWdlciBkaWdlc3RCSTsKKworICAgICAgICAvLyB2YXJpb3VzIGJ5dGUgYXJyYXkgYmVpbmcgdXNlZCBpbiBjb21wdXRpbmcgc2lnbmF0dXJlCisgICAgICAgIGJ5dGVbXSByYW5kb21CeXRlczsKKyAgICAgICAgYnl0ZVtdIHJCeXRlczsKKyAgICAgICAgYnl0ZVtdIHNCeXRlczsKKyAgICAgICAgYnl0ZVtdIHNpZ25hdHVyZTsKKworICAgICAgICBpbnQgbiwgbjEsIG4yOworCisgICAgICAgIERTQVBhcmFtcyBwYXJhbXM7CisKKyAgICAgICAgaWYgKGFwcFJhbmRvbSA9PSBudWxsKSB7CisgICAgICAgICAgICBhcHBSYW5kb20gPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIH0KKworICAgICAgICBwYXJhbXMgPSBkc2FLZXkuZ2V0UGFyYW1zKCk7CisgICAgICAgIHAgPSBwYXJhbXMuZ2V0UCgpOworICAgICAgICBxID0gcGFyYW1zLmdldFEoKTsKKyAgICAgICAgZyA9IHBhcmFtcy5nZXRHKCk7CisgICAgICAgIHggPSAoKERTQVByaXZhdGVLZXkpIGRzYUtleSkuZ2V0WCgpOworCisgICAgICAgIC8vIGZvcm1pbmcgc2lnbmF0dXJlIGFjY29yZGluZyBhbGdvcml0aG0gZGVzY3JpYmVkIGluIGNoYXB0ZXIgNSBvZiBEU0Egc3RhbmRhcmQKKworICAgICAgICBkaWdlc3RCSSA9IG5ldyBCaWdJbnRlZ2VyKDEsIG1zZ0RpZ2VzdC5kaWdlc3QoKSk7CisKKyAgICAgICAgcmFuZG9tQnl0ZXMgPSBuZXcgYnl0ZVsyMF07CisKKyAgICAgICAgZm9yICg7OykgeworCisgICAgICAgICAgICBhcHBSYW5kb20ubmV4dEJ5dGVzKHJhbmRvbUJ5dGVzKTsKKworICAgICAgICAgICAgayA9IG5ldyBCaWdJbnRlZ2VyKDEsIHJhbmRvbUJ5dGVzKTsKKyAgICAgICAgICAgIGlmIChrLmNvbXBhcmVUbyhxKSAhPSAtMSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgciA9IGcubW9kUG93KGssIHApLm1vZChxKTsKKyAgICAgICAgICAgIGlmIChyLnNpZ251bSgpID09IDApIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcyA9IGsubW9kSW52ZXJzZShxKS5tdWx0aXBseShkaWdlc3RCSS5hZGQoeC5tdWx0aXBseShyKSkubW9kKHEpKQorICAgICAgICAgICAgICAgICAgICAubW9kKHEpOworCisgICAgICAgICAgICBpZiAocy5zaWdudW0oKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBmb3JtaW5nIHNpZ25hdHVyZSdzIEFTTjEgcmVwcmVzZW50YXRpb24gd2hpY2ggaXMgU0VRVUVOQ0Ugb2YgdHdvIElOVEVHRVJzCisgICAgICAgIC8vCisgICAgICAgIHJCeXRlcyA9IHIudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgbjEgPSByQnl0ZXMubGVuZ3RoOworICAgICAgICBpZiAoKHJCeXRlc1swXSAmIDB4ODApICE9IDApIHsKKyAgICAgICAgICAgIG4xKys7CisgICAgICAgIH0KKyAgICAgICAgc0J5dGVzID0gcy50b0J5dGVBcnJheSgpOworICAgICAgICBuMiA9IHNCeXRlcy5sZW5ndGg7CisgICAgICAgIGlmICgoc0J5dGVzWzBdICYgMHg4MCkgIT0gMCkgeworICAgICAgICAgICAgbjIrKzsKKyAgICAgICAgfQorCisgICAgICAgIHNpZ25hdHVyZSA9IG5ldyBieXRlWzYgKyBuMSArIG4yXTsgLy8gNDggaXMgbWF4LiBwb3NzaWJsZSBsZW5ndGggb2Ygc2lnbmF0dXJlCisgICAgICAgIHNpZ25hdHVyZVswXSA9IChieXRlKSAweDMwOyAvLyBBU04xIFNFUVVFTkNFIHRhZworICAgICAgICBzaWduYXR1cmVbMV0gPSAoYnl0ZSkgKDQgKyBuMSArIG4yKTsgLy8gdG90YWwgbGVuZ3RoIG9mIHR3byBJTlRFR0VScworICAgICAgICBzaWduYXR1cmVbMl0gPSAoYnl0ZSkgMHgwMjsgLy8gQVNOMSBJTlRFR0VSIHRhZworICAgICAgICBzaWduYXR1cmVbM10gPSAoYnl0ZSkgbjE7IC8vIGxlbmd0aCBvZiByCisgICAgICAgIHNpZ25hdHVyZVs0ICsgbjFdID0gKGJ5dGUpIDB4MDI7IC8vIEFTTjEgSU5URUdFUiB0YWcKKyAgICAgICAgc2lnbmF0dXJlWzUgKyBuMV0gPSAoYnl0ZSkgbjI7IC8vIGxlbmd0aCBvZiBzCisKKyAgICAgICAgaWYgKG4xID09IHJCeXRlcy5sZW5ndGgpIHsKKyAgICAgICAgICAgIG4gPSA0OworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbiA9IDU7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShyQnl0ZXMsIDAsIHNpZ25hdHVyZSwgbiwgckJ5dGVzLmxlbmd0aCk7CisKKyAgICAgICAgaWYgKG4yID09IHNCeXRlcy5sZW5ndGgpIHsKKyAgICAgICAgICAgIG4gPSA2ICsgbjE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBuID0gNyArIG4xOworICAgICAgICB9CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc0J5dGVzLCAwLCBzaWduYXR1cmUsIG4sIHNCeXRlcy5sZW5ndGgpOworCisgICAgICAgIHJldHVybiBzaWduYXR1cmU7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlcyBkYXRhIHRvIHNpZ24gb3IgdG8gdmVyaWZ5LgorICAgICAqCisgICAgICogQHBhcmFtcworICAgICAqICAgIGIgYnl0ZSB0byB1cGRhdGUKKyAgICAgKiBAdGhyb3dzCisgICAgICogICAgU2lnbmF0dXJlRXhjZXB0aW9uIGlmIG9iamVjdCB3YXMgbm90IGluaXRpYWxpemVkIGZvciBzaWduaW5nIG9yIHZlcmlmeWluZworICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShieXRlIGIpIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworCisgICAgICAgIG1zZ0RpZ2VzdC51cGRhdGUoYik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlcyBkYXRhIHRvIHNpZ24gb3IgdG8gdmVyaWZ5LgorICAgICAqCisgICAgICogQHBhcmFtcworICAgICAqICAgIGIgYnl0ZSBhcnJheSBjb250YWluaW5nIGJ5dGVzIHRvIHVwZGF0ZQorICAgICAqIEBwYXJhbXMKKyAgICAgKiAgICBvZmYgb2Zmc2V0IGluIGJ5dGUgYXJyYXkgdG8gc3RhcnQgZnJvbQorICAgICAqIEBwYXJhbXMKKyAgICAgKiAgICBsZW4gbnVtYmVyIG9mIGJ5dGVzIHRvIHVzZSBmb3IgdXBkYXRpbmcKKyAgICAgKiBAdGhyb3dzCisgICAgICogICAgU2lnbmF0dXJlRXhjZXB0aW9uIGlmIG9iamVjdCB3YXMgbm90IGluaXRpYWxpemVkIGZvciBzaWduaW5nIG9yIHZlcmlmeWluZworICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikKKyAgICAgICAgICAgIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworCisgICAgICAgIG1zZ0RpZ2VzdC51cGRhdGUoYiwgb2ZmLCBsZW4pOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBjaGVja1NpZ25hdHVyZShieXRlW10gc2lnQnl0ZXMsIGludCBvZmZzZXQsIGludCBsZW5ndGgpCisgICAgICAgICAgICB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKworICAgICAgICAvLyBuYW1lcyBvZiBiZWxvdyBCaWdJbnRlZ2VycyBhcmUgdGhlIHNhbWUgYXMgdGhleSBhcmUgZGVmaW5lZCBpbiBEU0Egc3RhbmRhcmQKKyAgICAgICAgQmlnSW50ZWdlciByLCBzLCB3OworICAgICAgICBCaWdJbnRlZ2VyIHUxLCB1MiwgdjsKKworICAgICAgICAvLyBwYXJhbWV0ZXJzIGFuZCBwdWJsaWMga2V5CisgICAgICAgIEJpZ0ludGVnZXIgcCwgcSwgZywgeTsKKworICAgICAgICBEU0FQYXJhbXMgcGFyYW1zOworCisgICAgICAgIGludCBuMSwgbjI7CisKKyAgICAgICAgYnl0ZVtdIGJ5dGVzOworICAgICAgICBieXRlW10gZGlnZXN0OworCisgICAgICAgIC8vIGNoZWNraW5nIHVwIG9uIHNpZ25hdHVyZSdzIEFTTjEKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ5dGUgZHVtbXk7CisgICAgICAgICAgICBuMSA9IHNpZ0J5dGVzW29mZnNldCArIDNdOworICAgICAgICAgICAgbjIgPSBzaWdCeXRlc1tvZmZzZXQgKyBuMSArIDVdOworCisgICAgICAgICAgICBpZiAoc2lnQnl0ZXNbb2Zmc2V0ICsgMF0gIT0gMHgzMCB8fCBzaWdCeXRlc1tvZmZzZXQgKyAyXSAhPSAyCisgICAgICAgICAgICAgICAgICAgIHx8IHNpZ0J5dGVzW29mZnNldCArIG4xICsgNF0gIT0gMgorICAgICAgICAgICAgICAgICAgICB8fCBzaWdCeXRlc1tvZmZzZXQgKyAxXSAhPSAobjEgKyBuMiArIDQpIHx8IG4xID4gMjEKKyAgICAgICAgICAgICAgICAgICAgfHwgbjIgPiAyMQorICAgICAgICAgICAgICAgICAgICB8fCAobGVuZ3RoICE9IDAgJiYgKHNpZ0J5dGVzW29mZnNldCArIDFdICsgMikgPiBsZW5ndGgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNpZ25hdHVyZUV4Y2VwdGlvbigic2lnbmF0dXJlIGJ5dGVzIGhhdmUgaW52YWxpZCBlbmNvZGluZyIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBkdW1teSA9IHNpZ0J5dGVzWzUgKyBuMSArIG4yXTsgLy8gdG8gY2hlY2sgbGVuZ3RoIG9mIHNpZ0J5dGVzCisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU2lnbmF0dXJlRXhjZXB0aW9uKCJiYWQgYXJndW1lbnQ6IGJ5dGVbXSBpcyB0b28gc21hbGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIGRpZ2VzdCA9IG1zZ0RpZ2VzdC5kaWdlc3QoKTsKKworICAgICAgICBieXRlcyA9IG5ldyBieXRlW24xXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzaWdCeXRlcywgb2Zmc2V0ICsgNCwgYnl0ZXMsIDAsIG4xKTsKKyAgICAgICAgciA9IG5ldyBCaWdJbnRlZ2VyKGJ5dGVzKTsKKworICAgICAgICBieXRlcyA9IG5ldyBieXRlW24yXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzaWdCeXRlcywgb2Zmc2V0ICsgNiArIG4xLCBieXRlcywgMCwgbjIpOworICAgICAgICBzID0gbmV3IEJpZ0ludGVnZXIoYnl0ZXMpOworCisgICAgICAgIHBhcmFtcyA9IGRzYUtleS5nZXRQYXJhbXMoKTsKKyAgICAgICAgcCA9IHBhcmFtcy5nZXRQKCk7CisgICAgICAgIHEgPSBwYXJhbXMuZ2V0USgpOworICAgICAgICBnID0gcGFyYW1zLmdldEcoKTsKKyAgICAgICAgeSA9ICgoRFNBUHVibGljS2V5KSBkc2FLZXkpLmdldFkoKTsKKworICAgICAgICAvLyBmb3JtaW5nIHNpZ25hdHVyZSBhY2NvcmRpbmcgYWxnb3JpdGhtIGRlc2NyaWJlZCBpbiBjaGFwdGVyIDYgb2YgRFNBIHN0YW5kYXJkCisKKyAgICAgICAgaWYgKHIuc2lnbnVtKCkgIT0gMSB8fCByLmNvbXBhcmVUbyhxKSAhPSAtMSB8fCBzLnNpZ251bSgpICE9IDEKKyAgICAgICAgICAgICAgICB8fCBzLmNvbXBhcmVUbyhxKSAhPSAtMSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgdyA9IHMubW9kSW52ZXJzZShxKTsKKworICAgICAgICB1MSA9IChuZXcgQmlnSW50ZWdlcigxLCBkaWdlc3QpKS5tdWx0aXBseSh3KS5tb2QocSk7CisgICAgICAgIHUyID0gci5tdWx0aXBseSh3KS5tb2QocSk7CisKKyAgICAgICAgdiA9IGcubW9kUG93KHUxLCBwKS5tdWx0aXBseSh5Lm1vZFBvdyh1MiwgcCkpLm1vZChwKS5tb2QocSk7CisKKyAgICAgICAgaWYgKHYuY29tcGFyZVRvKHIpICE9IDApIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWZXJpZmllcyB0aGUgc2lnbmF0dXJlIGJ5dGVzLgorICAgICAqCisgICAgICogQHBhcmFtcworICAgICAqICAgIHNpZ0J5dGVzIGJ5dGUgYXJyYXkgd2l0aCBzaWduYXR1cmUgYnl0ZXMgdG8gdmVyaWZ5LgorICAgICAqIEByZXR1cm4KKyAgICAgKiAgICB0cnVlIGlmIHNpZ25hdHVyZSBieXRlcyB3ZXJlIHZlcmlmaWVkLCBmYWxzZSBvdGhlcndpc2UKKyAgICAgKiBAdGhyb3dzCisgICAgICogICAgU2lnbmF0dXJlRXhjZXB0aW9uIGlmIG9iamVjdCdzIHN0YXRlIGlzIG5vdCBWRVJJRlkgb3IKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgc2lnbmF0dXJlIGZvcm1hdCBpcyBub3QgQVNOMSByZXByZXNlbnRhdGlvbiBvcgorICAgICAqICAgICAgICAgICAgICAgICAgICAgICBzaWduYXR1cmUgYWxnb3JpdGhtIGNhbm5vdCBwcm9jZXNzIGRhdGEKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBlbmdpbmVWZXJpZnkoYnl0ZVtdIHNpZ0J5dGVzKSB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNpZ0J5dGVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigic2lnQnl0ZXMgPT0gbnVsbCIpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGNoZWNrU2lnbmF0dXJlKHNpZ0J5dGVzLCAwLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWZXJpZmllcyB0aGUgc2lnbmF0dXJlIGJ5dGVzLgorICAgICAqCisgICAgICogQHBhcmFtcworICAgICAqICAgIHNpZ0J5dGVzIGJ5dGUgYXJyYXkgd2l0aCBzaWduYXR1cmUgYnl0ZXMgdG8gdmVyaWZ5LgorICAgICAqIEBwYXJhbXMKKyAgICAgKiAgICBvZmZzZXQgaW5kZXggaW4gc2lnQnl0ZXMgdG8gc3RhcnQgZnJvbQorICAgICAqIEBwYXJhbXMKKyAgICAgKiAgICBsZW5ndGggbnVtYmVyIG9mIGJ5dGVzIGFsbG90dGVkIGZvciBzaWduYXR1cmUKKyAgICAgKiBAcmV0dXJuCisgICAgICogICAgdHJ1ZSBpZiBzaWduYXR1cmUgYnl0ZXMgd2VyZSB2ZXJpZmllZCwgZmFsc2Ugb3RoZXJ3aXNlCisgICAgICogQHRocm93cworICAgICAqICAgIFNpZ25hdHVyZUV4Y2VwdGlvbiBpZiBvYmplY3QncyBzdGF0ZSBpcyBub3QgVkVSSUZZIG9yCisgICAgICogICAgICAgICAgICAgICAgICAgICAgIHNpZ25hdHVyZSBmb3JtYXQgaXMgbm90IEFTTjEgcmVwcmVzZW50YXRpb24gb3IKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgc2lnbmF0dXJlIGFsZ29yaXRobSBjYW5ub3QgcHJvY2VzcyBkYXRhCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gZW5naW5lVmVyaWZ5KGJ5dGVbXSBzaWdCeXRlcywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICByZXR1cm4gY2hlY2tTaWduYXR1cmUoc2lnQnl0ZXMsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Byb3ZpZGVyL2NyeXB0by9UaHJlZUludGVnZXJTZXF1ZW5jZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vVGhyZWVJbnRlZ2VyU2VxdWVuY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZjQyMzJhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS9wcm92aWRlci9jcnlwdG8vVGhyZWVJbnRlZ2VyU2VxdWVuY2UuamF2YQpAQCAtMCwwICsxLDczIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnByb3ZpZGVyLmNyeXB0bzsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFJbnRlZ2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXF1ZW5jZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKKworCisvKioKKyAqIFRoZSBhdXhpbGlhcnkgY2xhc3MgcHJvdmlkaW5nIG1lYW5zIHRvIHByb2Nlc3MgQVNOMVNlcXVlbmNlIG9mIHRocmVlIEludGVnZXJzLgorICogU3VjaCBzZXF1ZW5jZXMgYXJlIHBhcnRzIG9mIEFTTjEgZW5jb2RlZCBmb3JtYXRzIGZvciBEU0EgcHJpdmF0ZSBhbmQgcHVibGljIGtleXMuCisgKi8KK2NsYXNzIFRocmVlSW50ZWdlclNlcXVlbmNlIHsKKworICAgIGJ5dGVbXSBwLCBxLCBnOworCisgICAgcHJpdmF0ZSBieXRlW10gZW5jb2Rpbmc7CisKKyAgICBUaHJlZUludGVnZXJTZXF1ZW5jZShieXRlW10gcCwgYnl0ZVtdIHEsIGJ5dGVbXSBnKSB7CisKKyAgICAgICAgdGhpcy5wID0gcDsKKyAgICAgICAgdGhpcy5xID0gcTsKKyAgICAgICAgdGhpcy5nID0gZzsKKyAgICAgICAgZW5jb2RpbmcgPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIGVuY29kaW5nID0gQVNOMS5lbmNvZGUodGhpcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVuY29kaW5nOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVNlcXVlbmNlIEFTTjEgPSBuZXcgQVNOMVNlcXVlbmNlKG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgIEFTTjFJbnRlZ2VyLmdldEluc3RhbmNlKCksIEFTTjFJbnRlZ2VyLmdldEluc3RhbmNlKCksCisgICAgICAgICAgICBBU04xSW50ZWdlci5nZXRJbnN0YW5jZSgpIH0pIHsKKworICAgICAgICBwcm90ZWN0ZWQgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHsKKworICAgICAgICAgICAgT2JqZWN0W10gdmFsdWVzID0gKE9iamVjdFtdKSBpbi5jb250ZW50OworCisgICAgICAgICAgICByZXR1cm4gbmV3IFRocmVlSW50ZWdlclNlcXVlbmNlKChieXRlW10pIHZhbHVlc1swXSwKKyAgICAgICAgICAgICAgICAgICAgKGJ5dGVbXSkgdmFsdWVzWzFdLCAoYnl0ZVtdKSB2YWx1ZXNbMl0pOworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykgeworCisgICAgICAgICAgICBUaHJlZUludGVnZXJTZXF1ZW5jZSBteVNlcSA9IChUaHJlZUludGVnZXJTZXF1ZW5jZSkgb2JqZWN0OworCisgICAgICAgICAgICB2YWx1ZXNbMF0gPSBteVNlcS5wOworICAgICAgICAgICAgdmFsdWVzWzFdID0gbXlTZXEucTsKKyAgICAgICAgICAgIHZhbHVlc1syXSA9IG15U2VxLmc7CisgICAgICAgIH0KKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS91dGlscy9BbGdOYW1lTWFwcGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3V0aWxzL0FsZ05hbWVNYXBwZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YWQ1MzczCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS91dGlscy9BbGdOYW1lTWFwcGVyLmphdmEKQEAgLTAsMCArMSwyMDQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnV0aWxzOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwLkVudHJ5OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuT2JqZWN0SWRlbnRpZmllcjsKKworLyoqCisgKiBQcm92aWRlcyBBbGdvcml0aG0gTmFtZSB0byBPSUQgYW5kIE9JRCB0byBBbGdvcml0aG0gTmFtZSBtYXBwaW5ncy4gU29tZSBrbm93bgorICogbWFwcGluZ3MgYXJlIGhhcmRjb2RlZC4gVHJpZXMgdG8gb2J0YWluIGFkZGl0aW9uYWwgbWFwcGluZ3MgZnJvbSBpbnN0YWxsZWQKKyAqIHByb3ZpZGVycyBkdXJpbmcgaW5pdGlhbGl6YXRpb24uCisgKi8KK3B1YmxpYyBjbGFzcyBBbGdOYW1lTWFwcGVyIHsKKworICAgIC8vIFdpbGwgc2VhcmNoIE9JRCBtYXBwaW5ncyBmb3IgdGhlc2Ugc2VydmljZXMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBzZXJ2aWNlTmFtZSA9IHsKKyAgICAgICAgICAgICJDaXBoZXIiLAorICAgICAgICAgICAgIkFsZ29yaXRobVBhcmFtZXRlcnMiLAorICAgICAgICAgICAgIlNpZ25hdHVyZSIKKyAgICB9OworCisgICAgLy8gVGhlc2UgbWFwcGluZ3MgQ0FOIE5PVCBiZSBvdmVycmlkZGVuCisgICAgLy8gYnkgdGhlIG9uZXMgZnJvbSBhdmFpbGFibGUgcHJvdmlkZXJzCisgICAgLy8gZHVyaW5nIG1hcHMgaW5pdGlhbGl6YXRpb24KKyAgICAvLyAoc291cmNlOiBodHRwOi8vYXNuMS5lbGliZWwudG0uZnIpOgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdW10ga25vd25BbGdNYXBwaW5ncyA9IHsKKyAgICAgICAgeyIxLjIuODQwLjEwMDQwLjQuMSIsICAgICAgICJEU0EifSwKKyAgICAgICAgeyIxLjIuODQwLjEwMDQwLjQuMyIsICAgICAgICJTSEExd2l0aERTQSJ9LAorICAgICAgICB7IjEuMi44NDAuMTEzNTQ5LjEuMS4xIiwgICAgIlJTQSJ9LAorICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLXJlbW92ZWQKKyAgICAgICAgLy8gRHJvcHBpbmcgTUQyCisgICAgICAgIC8vIHsiMS4yLjg0MC4xMTM1NDkuMS4xLjIiLCAgICAiTUQyd2l0aFJTQSJ9LAorICAgICAgICAvLyBFTkQgYW5kcm9pZC1yZW1vdmVkCisgICAgICAgIHsiMS4yLjg0MC4xMTM1NDkuMS4xLjQiLCAgICAiTUQ1d2l0aFJTQSJ9LAorICAgICAgICB7IjEuMi44NDAuMTEzNTQ5LjEuMS41IiwgICAgIlNIQTF3aXRoUlNBIn0sCisgICAgICAgIHsiMS4yLjg0MC4xMTM1NDkuMS4zLjEiLCAgICAiRGlmZmllSGVsbG1hbiJ9LAorICAgICAgICB7IjEuMi44NDAuMTEzNTQ5LjEuNS4zIiwgICAgInBiZVdpdGhNRDVBbmRERVMtQ0JDIn0sCisgICAgICAgIHsiMS4yLjg0MC4xMTM1NDkuMS4xMi4xLjMiLCAicGJlV2l0aFNIQUFuZDMtS2V5VHJpcGxlREVTLUNCQyJ9LAorICAgICAgICB7IjEuMi44NDAuMTEzNTQ5LjEuMTIuMS42IiwgInBiZVdpdGhTSEFBbmQ0MEJpdFJDMi1DQkMifSwKKyAgICAgICAgeyIxLjIuODQwLjExMzU0OS4zLjIiLCAgICAgICJSQzItQ0JDIn0sCisgICAgICAgIHsiMS4yLjg0MC4xMTM1NDkuMy4zIiwgICAgICAiUkMyLUVCQyJ9LAorICAgICAgICB7IjEuMi44NDAuMTEzNTQ5LjMuNCIsICAgICAgIlJDNCJ9LAorICAgICAgICB7IjEuMi44NDAuMTEzNTQ5LjMuNSIsICAgICAgIlJDNFdpdGhNQUMifSwKKyAgICAgICAgeyIxLjIuODQwLjExMzU0OS4zLjYiLCAgICAgICJERVN4LUNCQyJ9LAorICAgICAgICB7IjEuMi44NDAuMTEzNTQ5LjMuNyIsICAgICAgIlRyaXBsZURFUy1DQkMifSwKKyAgICAgICAgeyIxLjIuODQwLjExMzU0OS4zLjgiLCAgICAgICJyYzVDQkMifSwKKyAgICAgICAgeyIxLjIuODQwLjExMzU0OS4zLjkiLCAgICAgICJSQzUtQ0JDIn0sCisgICAgICAgIHsiMS4yLjg0MC4xMTM1NDkuMy4xMCIsICAgICAiREVTQ0RNRiJ9LAorICAgICAgICB7IjIuMjMuNDIuOS4xMS40LjEiLCAgICAgICAgIkVDRFNBIn0sCisgICAgfTsKKyAgICAvLyBNYXBzIGFsZyBuYW1lIHRvIE9JRAorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gYWxnMk9pZE1hcCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOworICAgIC8vIE1hcHMgT0lEIHRvIGFsZyBuYW1lCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBvaWQyQWxnTWFwID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgLy8gTWFwcyBhbGlhc2VzIHRvIGFsZyBuYW1lcworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gYWxnQWxpYXNlc01hcCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOworCisgICAgc3RhdGljIHsKKyAgICAgICAgZm9yIChTdHJpbmdbXSBlbGVtZW50IDoga25vd25BbGdNYXBwaW5ncykgeworICAgICAgICAgICAgU3RyaW5nIGFsZ1VDID0gZWxlbWVudFsxXS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpOworICAgICAgICAgICAgYWxnMk9pZE1hcC5wdXQoYWxnVUMsIGVsZW1lbnRbMF0pOworICAgICAgICAgICAgb2lkMkFsZ01hcC5wdXQoZWxlbWVudFswXSwgYWxnVUMpOworICAgICAgICAgICAgLy8gbWFwIHVwcGVyIGNhc2UgYWxnIG5hbWUgdG8gaXRzIG9yaWdpbmFsIG5hbWUKKyAgICAgICAgICAgIGFsZ0FsaWFzZXNNYXAucHV0KGFsZ1VDLCBlbGVtZW50WzFdKTsKKyAgICAgICAgfQorICAgICAgICAvLworICAgICAgICAvLyBOb3cgc2VhcmNoIHByb3ZpZGVycyBmb3IgbWFwcGluZ3MgbGlrZQorICAgICAgICAvLyBBbGcuQWxpYXMuPHNlcnZpY2U+LjxPSUQtSU5UUy1ET1QtU0VQQVJBVEVEPj08YWxnLW5hbWU+CisgICAgICAgIC8vICBvcgorICAgICAgICAvLyBBbGcuQWxpYXMuPHNlcnZpY2U+Lk9JRC48T0lELUlOVFMtRE9ULVNFUEFSQVRFRD49PGFsZy1uYW1lPgorICAgICAgICAvLworICAgICAgICBQcm92aWRlcltdIHBsID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKCk7CisgICAgICAgIGZvciAoUHJvdmlkZXIgZWxlbWVudCA6IHBsKSB7CisgICAgICAgICAgICBzZWxlY3RFbnRyaWVzKGVsZW1lbnQpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gTm8gaW5zdGFuY2VzCisgICAgcHJpdmF0ZSBBbGdOYW1lTWFwcGVyKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgT0lEIGZvciBhbGdOYW1lCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnTmFtZSBhbGdvcml0aG0gbmFtZSB0byBiZSBtYXBwZWQKKyAgICAgKiBAcmV0dXJuIE9JRCBhcyBTdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBtYXAyT0lEKFN0cmluZyBhbGdOYW1lKSB7CisgICAgICAgIC8vIGFsZzJPaWRNYXAgbWFwIGNvbnRhaW5zIHVwcGVyIGNhc2Uga2V5cworICAgICAgICByZXR1cm4gYWxnMk9pZE1hcC5nZXQoYWxnTmFtZS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFsZ05hbWUgZm9yIE9JRAorICAgICAqCisgICAgICogQHBhcmFtIG9pZCBPSUQgdG8gYmUgbWFwcGVkCisgICAgICogQHJldHVybiBhbGdvcml0aG0gbmFtZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG1hcDJBbGdOYW1lKFN0cmluZyBvaWQpIHsKKyAgICAgICAgLy8gb2lkMkFsZ01hcCBtYXAgY29udGFpbnMgdXBwZXIgY2FzZSB2YWx1ZXMKKyAgICAgICAgU3RyaW5nIGFsZ1VDID0gb2lkMkFsZ01hcC5nZXQob2lkKTsKKyAgICAgICAgLy8gaWYgbm90IG51bGwgdGhlcmUgaXMgYWx3YXlzIG1hcCBVQy0+T3JpZworICAgICAgICByZXR1cm4gYWxnVUMgPT0gbnVsbCA/IG51bGwgOiBhbGdBbGlhc2VzTWFwLmdldChhbGdVQyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBbGdvcml0aG0gbmFtZSBmb3IgZ2l2ZW4gYWxnb3JpdGhtIGFsaWFzCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnTmFtZSAtIGFsaWFzCisgICAgICogQHJldHVybiBhbGdvcml0aG0gbmFtZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFN0YW5kYXJkTmFtZShTdHJpbmcgYWxnTmFtZSkgeworICAgICAgICByZXR1cm4gYWxnQWxpYXNlc01hcC5nZXQoYWxnTmFtZS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpKTsKKyAgICB9CisKKyAgICAvLyBTZWFyY2hlcyBnaXZlbiBwcm92aWRlciBmb3IgbWFwcGluZ3MgbGlrZQorICAgIC8vIEFsZy5BbGlhcy48c2VydmljZT4uPE9JRC1JTlRTLURPVC1TRVBBUkFURUQ+PTxhbGctbmFtZT4KKyAgICAvLyAgb3IKKyAgICAvLyBBbGcuQWxpYXMuPHNlcnZpY2U+Lk9JRC48T0lELUlOVFMtRE9ULVNFUEFSQVRFRD49PGFsZy1uYW1lPgorICAgIC8vIFB1dHMgbWFwcGluZ3MgZm91bmQgaW50byBhcHByb3ByaWF0ZSBpbnRlcm5hbCBtYXBzCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBzZWxlY3RFbnRyaWVzKFByb3ZpZGVyIHApIHsKKyAgICAgICAgU2V0PE1hcC5FbnRyeTxPYmplY3QsIE9iamVjdD4+IGVudHJ5U2V0ID0gcC5lbnRyeVNldCgpOworICAgICAgICBmb3IgKFN0cmluZyBzZXJ2aWNlIDogc2VydmljZU5hbWUpIHsKKyAgICAgICAgICAgIFN0cmluZyBrZXlQcmZpeDJmaW5kID0gIkFsZy5BbGlhcy4iICsgc2VydmljZSArICIuIjsKKyAgICAgICAgICAgIGZvciAoRW50cnk8T2JqZWN0LCBPYmplY3Q+IG1lIDogZW50cnlTZXQpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcga2V5ID0gKFN0cmluZyltZS5nZXRLZXkoKTsKKyAgICAgICAgICAgICAgICBpZiAoa2V5LnN0YXJ0c1dpdGgoa2V5UHJmaXgyZmluZCkpIHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGFsaWFzID0ga2V5LnN1YnN0cmluZyhrZXlQcmZpeDJmaW5kLmxlbmd0aCgpKTsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGFsZyA9IChTdHJpbmcpbWUuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGFsZ1VDID0gYWxnLnRvVXBwZXJDYXNlKExvY2FsZS5VUyk7CisgICAgICAgICAgICAgICAgICAgIGlmIChpc09JRChhbGlhcykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhbGlhcy5zdGFydHNXaXRoKCJPSUQuIikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGlhcyA9IGFsaWFzLnN1YnN0cmluZyg0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIERvIG5vdCBvdmVyd3JpdGUgYWxyZWFkeSBrbm93biBtYXBwaW5ncworICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBvaWQyQWxnQ29udGFpbnMgPSBvaWQyQWxnTWFwLmNvbnRhaW5zS2V5KGFsaWFzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gYWxnMk9pZENvbnRhaW5zID0gYWxnMk9pZE1hcC5jb250YWluc0tleShhbGdVQyk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW9pZDJBbGdDb250YWlucyB8fCAhYWxnMk9pZENvbnRhaW5zKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFvaWQyQWxnQ29udGFpbnMpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2lkMkFsZ01hcC5wdXQoYWxpYXMsIGFsZ1VDKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhbGcyT2lkQ29udGFpbnMpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxnMk9pZE1hcC5wdXQoYWxnVUMsIGFsaWFzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWFwIHVwcGVyIGNhc2UgYWxnIG5hbWUgdG8gaXRzIG9yaWdpbmFsIG5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGdBbGlhc2VzTWFwLnB1dChhbGdVQywgYWxnKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERvIG5vdCBvdmVycmlkZSBrbm93biBzdGFuZGFyZCBuYW1lcworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFhbGdBbGlhc2VzTWFwLmNvbnRhaW5zS2V5KGFsaWFzLnRvVXBwZXJDYXNlKExvY2FsZS5VUykpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhbGdBbGlhc2VzTWFwLnB1dChhbGlhcy50b1VwcGVyQ2FzZShMb2NhbGUuVVMpLCBhbGcpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHBhcmFtZXRlciByZXByZXNlbnRzIE9JRAorICAgICAqCisgICAgICogQHBhcmFtIGFsaWFzIGFsaWFzIHRvIGJlIGNoZWNrZWQKKyAgICAgKiBAcmV0dXJuICd0cnVlJyBpZiBwYXJhbWV0ZXIgcmVwcmVzZW50cyBPSUQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNPSUQoU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIHJldHVybiBPYmplY3RJZGVudGlmaWVyLmlzT0lEKG5vcm1hbGl6ZShhbGlhcykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgbGVhZGluZyAiT0lELiIgZnJvbSBvaWQgU3RyaW5nIHBhc3NlZAorICAgICAqCisgICAgICogQHBhcmFtIG9pZCBzdHJpbmcgdGhhdCBtYXkgY29udGFpbiBsZWFkaW5nICJPSUQuIgorICAgICAqIEByZXR1cm4gc3RyaW5nIHBhc3NlZCB3aXRob3V0IGxlYWRpbmcgIk9JRC4iCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgbm9ybWFsaXplKFN0cmluZyBvaWQpIHsKKyAgICAgICAgcmV0dXJuIG9pZC5zdGFydHNXaXRoKCJPSUQuIikKKyAgICAgICAgICAgID8gb2lkLnN1YnN0cmluZyg0KQorICAgICAgICAgICAgOiBvaWQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS91dGlscy9BcnJheS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS91dGlscy9BcnJheS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU4MmNhN2QKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3V0aWxzL0FycmF5LmphdmEKQEAgLTAsMCArMSwxMTIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnV0aWxzOworCisKKy8qKgorICogVXRpbGl0eSBjbGFzcyBmb3IgYXJyYXlzCisgKgorICovCitwdWJsaWMgY2xhc3MgQXJyYXkgeworCisgICAgLy8gTm8gaW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MKKyAgICBwcml2YXRlIEFycmF5KCkgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEJ5dGVzQXNTdHJpbmcoYnl0ZVtdIGRhdGEpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcihkYXRhLmxlbmd0aCAqIDMpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoQnl0ZS50b0hleFN0cmluZyhkYXRhW2ldLCBmYWxzZSkpOworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnICcpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXByZXNlbnRzIDxjb2RlPmFycmF5PC9jb2RlPiBhcyA8Y29kZT5TdHJpbmc8L2NvZGU+CisgICAgICogZm9yIHByaW50aW5nLiBBcnJheSBsZW5ndGggY2FuIGJlIHVwIHRvIDMyNzY3CisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJyYXkgdG8gYmUgcmVwcmVzZW50ZWQgYXMgPGNvZGU+U3RyaW5nPC9jb2RlPgorICAgICAqCisgICAgICogQHJldHVybiA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uIG9mIHRoZSA8Y29kZT5hcnJheTwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b1N0cmluZyhieXRlW10gYXJyYXksIFN0cmluZyBwcmVmaXgpIHsKKyAgICAgICAgLy8gUHJlZml4ZXMgdG8gYmUgYWRkZWQgdG8gdGhlIG9mZnNldCB2YWx1ZXMKKyAgICAgICAgLy8gaW4gPGNvZGU+U3RyaW5nIHRvU3RyaW5nKGJ5dGVbXSwgU3RyaW5nKTwvY29kZT4gbWV0aG9kCisgICAgICAgIGZpbmFsIFN0cmluZ1tdIG9mZnNldFByZWZpeCA9IHsKKyAgICAgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICAgICAiMDAwIiwKKyAgICAgICAgICAgICAgICAiMDAiLAorICAgICAgICAgICAgICAgICIwIiwKKyAgICAgICAgICAgICAgICAiIgorICAgICAgICB9OworICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBjaGFyRm9ybSA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGludCBpPTA7CisgICAgICAgIGZvciAoaT0wOyBpPGFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoaSUxNiA9PSAwKSB7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKHByZWZpeCk7CisgICAgICAgICAgICAgICAgLy8gcHV0IG9mZnNldAorICAgICAgICAgICAgICAgIFN0cmluZyBvZmZzZXQgPSBJbnRlZ2VyLnRvSGV4U3RyaW5nKGkpOworICAgICAgICAgICAgICAgIHNiLmFwcGVuZChvZmZzZXRQcmVmaXhbb2Zmc2V0Lmxlbmd0aCgpXSk7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKG9mZnNldCk7CisgICAgICAgICAgICAgICAgLy8gY2xlYXIgY2hhciBmb3JtIGZvciBuZXcgbGluZQorICAgICAgICAgICAgICAgIGNoYXJGb3JtLmRlbGV0ZSgwLCBjaGFyRm9ybS5sZW5ndGgoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBwdXQgZGVsaW1pdGVyCisgICAgICAgICAgICBzYi5hcHBlbmQoJyAnKTsKKyAgICAgICAgICAgIC8vIHB1dCBjdXJyZW50IGJ5dGUKKyAgICAgICAgICAgIHNiLmFwcGVuZChCeXRlLnRvSGV4U3RyaW5nKGFycmF5W2ldLCBmYWxzZSkpOworICAgICAgICAgICAgLy8gZm9ybSBjaGFyYWN0ZXIgcmVwcmVzZW50YXRpb24gcGFydAorICAgICAgICAgICAgaW50IGN1cnJlbnRCeXRlID0gKDB4ZmYgJiBhcnJheVtpXSk7CisgICAgICAgICAgICBjaGFyIGN1cnJlbnRDaGFyID0gKGNoYXIpKGN1cnJlbnRCeXRlICYgMHhmZmZmKTsKKyAgICAgICAgICAgIC8vIEZJWE1FIGlmIG5lZWRlZCAoaG93IHRvIGRpc3Rpbmd1aXNoIFBSSU5UQUJMRSBjaGFycz8pCisgICAgICAgICAgICBjaGFyRm9ybS5hcHBlbmQoCisgICAgICAgICAgICAgICAgICAgIChDaGFyYWN0ZXIuaXNJU09Db250cm9sKGN1cnJlbnRDaGFyKSA/ICcuJyA6IGN1cnJlbnRDaGFyKSk7CisgICAgICAgICAgICAvLyBBZGQgYWRkaXRpb25hbCBkZWxpbWl0ZXIgZm9yIGVhY2ggOCB2YWx1ZXMKKyAgICAgICAgICAgIGlmICgoaSsxKSU4ID09IDApIHsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoJyAnKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIEFkZCBjaGFyYWN0ZXIgcmVwcmVzZW50YXRpb24gZm9yIGVhY2ggbGluZQorICAgICAgICAgICAgaWYgKChpKzEpJTE2ID09IDApIHsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoJyAnKTsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoY2hhckZvcm0udG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCdcbicpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIGZvcm0gbGFzdCBsaW5lCisgICAgICAgIGlmIChpJTE2ICE9IDApIHsKKyAgICAgICAgICAgIGludCB3czJhZGQgPSAxNiAtIGklMTY7CisgICAgICAgICAgICBmb3IgKGludCBqPTA7IGo8d3MyYWRkOyBqKyspIHsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIiAgICIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHdzMmFkZCA+IDgpIHsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoJyAnKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNiLmFwcGVuZCgiICAiKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZChjaGFyRm9ybS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgnXG4nKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3V0aWxzL0phclV0aWxzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3V0aWxzL0phclV0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzBhMTNmNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdXRpbHMvSmFyVXRpbHMuamF2YQpAQCAtMCwwICsxLDIxNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQm9yaXMgS3V6bmV0c292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS51dGlsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5QcmluY2lwYWw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpbmtlZExpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQmVySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnBrY3M3LkNvbnRlbnRJbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wa2NzNy5TaWduZWREYXRhOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wa2NzNy5TaWduZXJJbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wcm92aWRlci5jZXJ0Llg1MDlDZXJ0SW1wbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwMS5BdHRyaWJ1dGVUeXBlQW5kVmFsdWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZS5PcGVuU1NMU2lnbmF0dXJlOworCitwdWJsaWMgY2xhc3MgSmFyVXRpbHMgeworCisgICAgLy8gYXMgZGVmaW5lZCBpbiBQS0NTICM5OiBTZWxlY3RlZCBBdHRyaWJ1dGUgVHlwZXM6CisgICAgLy8gaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjk4NS50eHQKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnRbXSBNRVNTQUdFX0RJR0VTVF9PSUQgPQorICAgICAgICBuZXcgaW50W10gezEsIDIsIDg0MCwgMTEzNTQ5LCAxLCA5LCA0fTsKKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGhhbmRsZSBhbGwgdGhlIHdvcmsgd2l0aCAgUEtDUzcsIEFTTjEgZW5jb2RpbmcsIHNpZ25hdHVyZSB2ZXJpZnlpbmcsCisgICAgICogYW5kIGNlcnRpZmljYXRpb24gcGF0aCBidWlsZGluZy4KKyAgICAgKiBTZWUgYWxzbyBQS0NTICM3OiBDcnlwdG9ncmFwaGljIE1lc3NhZ2UgU3ludGF4IFN0YW5kYXJkOgorICAgICAqIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzMTUudHh0CisgICAgICogQHBhcmFtIHNpZ25hdHVyZSAtIHRoZSBpbnB1dCBzdHJlYW0gb2Ygc2lnbmF0dXJlIGZpbGUgdG8gYmUgdmVyaWZpZWQKKyAgICAgKiBAcGFyYW0gc2lnbmF0dXJlQmxvY2sgLSB0aGUgaW5wdXQgc3RyZWFtIG9mIGNvcnJlc3BvbmRpbmcgc2lnbmF0dXJlIGJsb2NrIGZpbGUKKyAgICAgKiBAcmV0dXJuIGFycmF5IG9mIGNlcnRpZmljYXRlcyB1c2VkIHRvIHZlcmlmeSB0aGUgc2lnbmF0dXJlIGZpbGUKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIC0gaWYgc29tZSBlcnJvcnMgb2NjdXJzIGR1cmluZyByZWFkaW5nIGZyb20gdGhlIHN0cmVhbQorICAgICAqIEB0aHJvd3MgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIC0gaWYgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiBwcm9jZXNzIGZhaWxzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDZXJ0aWZpY2F0ZVtdIHZlcmlmeVNpZ25hdHVyZShJbnB1dFN0cmVhbSBzaWduYXR1cmUsIElucHV0U3RyZWFtCisgICAgICAgICAgICBzaWduYXR1cmVCbG9jaykgdGhyb3dzIElPRXhjZXB0aW9uLCBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24geworCisgICAgICAgIEJlcklucHV0U3RyZWFtIGJpcyA9IG5ldyBCZXJJbnB1dFN0cmVhbShzaWduYXR1cmVCbG9jayk7CisgICAgICAgIENvbnRlbnRJbmZvIGluZm8gPSAoQ29udGVudEluZm8pQ29udGVudEluZm8uQVNOMS5kZWNvZGUoYmlzKTsKKyAgICAgICAgU2lnbmVkRGF0YSBzaWduZWREYXRhID0gaW5mby5nZXRTaWduZWREYXRhKCk7CisgICAgICAgIGlmIChzaWduZWREYXRhID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiTm8gU2lnbmVkRGF0YSBmb3VuZCIpOworICAgICAgICB9CisgICAgICAgIENvbGxlY3Rpb248b3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuQ2VydGlmaWNhdGU+IGVuY0NlcnRzCisgICAgICAgICAgICAgICAgPSBzaWduZWREYXRhLmdldENlcnRpZmljYXRlcygpOworICAgICAgICBpZiAoZW5jQ2VydHMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBYNTA5Q2VydGlmaWNhdGVbXSBjZXJ0cyA9IG5ldyBYNTA5Q2VydGlmaWNhdGVbZW5jQ2VydHMuc2l6ZSgpXTsKKyAgICAgICAgaW50IGkgPSAwOworICAgICAgICBmb3IgKG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LkNlcnRpZmljYXRlIGVuY0NlcnQgOiBlbmNDZXJ0cykgeworICAgICAgICAgICAgY2VydHNbaSsrXSA9IG5ldyBYNTA5Q2VydEltcGwoZW5jQ2VydCk7CisgICAgICAgIH0KKworICAgICAgICBMaXN0PFNpZ25lckluZm8+IHNpZ0luZm9zID0gc2lnbmVkRGF0YS5nZXRTaWduZXJJbmZvcygpOworICAgICAgICBTaWduZXJJbmZvIHNpZ0luZm87CisgICAgICAgIGlmICghc2lnSW5mb3MuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBzaWdJbmZvID0gc2lnSW5mb3MuZ2V0KDApOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvLyBJc3N1ZXIKKyAgICAgICAgWDUwMFByaW5jaXBhbCBpc3N1ZXIgPSBzaWdJbmZvLmdldElzc3VlcigpOworCisgICAgICAgIC8vIENlcnRpZmljYXRlIHNlcmlhbCBudW1iZXIKKyAgICAgICAgQmlnSW50ZWdlciBzbnVtID0gc2lnSW5mby5nZXRTZXJpYWxOdW1iZXIoKTsKKworICAgICAgICAvLyBMb2NhdGUgdGhlIGNlcnRpZmljYXRlCisgICAgICAgIGludCBpc3N1ZXJTZXJ0SW5kZXggPSAwOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY2VydHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChpc3N1ZXIuZXF1YWxzKGNlcnRzW2ldLmdldElzc3VlckROKCkpICYmCisgICAgICAgICAgICAgICAgICAgIHNudW0uZXF1YWxzKGNlcnRzW2ldLmdldFNlcmlhbE51bWJlcigpKSkgeworICAgICAgICAgICAgICAgIGlzc3VlclNlcnRJbmRleCA9IGk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGkgPT0gY2VydHMubGVuZ3RoKSB7IC8vIE5vIGlzc3VlciBjZXJ0aWZpY2F0ZSBmb3VuZAorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBpZiAoY2VydHNbaXNzdWVyU2VydEluZGV4XS5oYXNVbnN1cHBvcnRlZENyaXRpY2FsRXh0ZW5zaW9uKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigiQ2FuIG5vdCByZWNvZ25pemUgYSBjcml0aWNhbCBleHRlbnNpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEdldCBTaWduYXR1cmUgaW5zdGFuY2UKKyAgICAgICAgU2lnbmF0dXJlIHNpZyA9IG51bGw7CisgICAgICAgIFN0cmluZyBkYSA9IHNpZ0luZm8uZ2V0RGlnZXN0QWxnb3JpdGhtKCk7CisgICAgICAgIFN0cmluZyBkZWEgPSBzaWdJbmZvLmdldERpZ2VzdEVuY3J5cHRpb25BbGdvcml0aG0oKTsKKyAgICAgICAgU3RyaW5nIGFsZyA9IG51bGw7CisgICAgICAgIGlmIChkYSAhPSBudWxsICYmIGRlYSAhPSBudWxsKSB7CisgICAgICAgICAgICBhbGcgPSBkYSArICJ3aXRoIiArICBkZWE7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHNpZyA9IE9wZW5TU0xTaWduYXR1cmUuZ2V0SW5zdGFuY2UoYWxnKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7fQorICAgICAgICB9CisgICAgICAgIGlmIChzaWcgPT0gbnVsbCkgeworICAgICAgICAgICAgYWxnID0gZGE7CisgICAgICAgICAgICBpZiAoYWxnID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2lnID0gT3BlblNTTFNpZ25hdHVyZS5nZXRJbnN0YW5jZShhbGcpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzaWcuaW5pdFZlcmlmeShjZXJ0c1tpc3N1ZXJTZXJ0SW5kZXhdKTsKKworICAgICAgICAvLyBJZiB0aGUgYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgZmllbGQgb2YgU2lnbmVySW5mbyBjb250YWlucyBtb3JlIHRoYW4gemVybyBhdHRyaWJ1dGVzLAorICAgICAgICAvLyBjb21wdXRlIHRoZSBtZXNzYWdlIGRpZ2VzdCBvbiB0aGUgQVNOLjEgREVSIGVuY29kaW5nIG9mIHRoZSBBdHRyaWJ1dGVzIHZhbHVlLgorICAgICAgICAvLyBPdGhlcndpc2UsIGNvbXB1dGUgdGhlIG1lc3NhZ2UgZGlnZXN0IG9uIHRoZSBkYXRhLgorICAgICAgICBMaXN0PEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZT4gYXRyID0gc2lnSW5mby5nZXRBdXRoZW50aWNhdGVkQXR0cmlidXRlcygpOworCisgICAgICAgIGJ5dGVbXSBzZkJ5dGVzID0gbmV3IGJ5dGVbc2lnbmF0dXJlLmF2YWlsYWJsZSgpXTsKKyAgICAgICAgc2lnbmF0dXJlLnJlYWQoc2ZCeXRlcyk7CisKKyAgICAgICAgaWYgKGF0ciA9PSBudWxsKSB7CisgICAgICAgICAgICBzaWcudXBkYXRlKHNmQnl0ZXMpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc2lnLnVwZGF0ZShzaWdJbmZvLmdldEVuY29kZWRBdXRoZW50aWNhdGVkQXR0cmlidXRlcygpKTsKKworICAgICAgICAgICAgLy8gSWYgdGhlIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIGZpZWxkIGNvbnRhaW5zIHRoZSBtZXNzYWdlLWRpZ2VzdCBhdHRyaWJ1dGUsCisgICAgICAgICAgICAvLyB2ZXJpZnkgdGhhdCBpdCBlcXVhbHMgdGhlIGNvbXB1dGVkIGRpZ2VzdCBvZiB0aGUgc2lnbmF0dXJlIGZpbGUKKyAgICAgICAgICAgIGJ5dGVbXSBleGlzdGluZ0RpZ2VzdCA9IG51bGw7CisgICAgICAgICAgICBmb3IgKEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZSBhIDogYXRyKSB7CisgICAgICAgICAgICAgICAgaWYgKEFycmF5cy5lcXVhbHMoYS5nZXRUeXBlKCkuZ2V0T2lkKCksIE1FU1NBR0VfRElHRVNUX09JRCkpIHsKKy8vVE9ETyB2YWx1ZSAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdEaWdlc3QgPSBhLkF0dHJpYnV0ZVZhbHVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChleGlzdGluZ0RpZ2VzdCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBtZCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2Uoc2lnSW5mby5nZXREaWdlc3RBbGdvcml0aG0oKSk7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGNvbXB1dGVkRGlnZXN0ID0gbWQuZGlnZXN0KHNmQnl0ZXMpOworICAgICAgICAgICAgICAgIGlmICghQXJyYXlzLmVxdWFscyhleGlzdGluZ0RpZ2VzdCwgY29tcHV0ZWREaWdlc3QpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigiSW5jb3JyZWN0IE1EIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKCFzaWcudmVyaWZ5KHNpZ0luZm8uZ2V0RW5jcnlwdGVkRGlnZXN0KCkpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oIkluY29ycmVjdCBzaWduYXR1cmUiKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjcmVhdGVDaGFpbihjZXJ0c1tpc3N1ZXJTZXJ0SW5kZXhdLCBjZXJ0cyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgWDUwOUNlcnRpZmljYXRlW10gY3JlYXRlQ2hhaW4oWDUwOUNlcnRpZmljYXRlICBzaWduZXIsIFg1MDlDZXJ0aWZpY2F0ZVtdIGNhbmRpZGF0ZXMpIHsKKyAgICAgICAgTGlua2VkTGlzdCBjaGFpbiA9IG5ldyBMaW5rZWRMaXN0KCk7CisgICAgICAgIGNoYWluLmFkZCgwLCBzaWduZXIpOworCisgICAgICAgIC8vIFNpZ25lciBpcyBzZWxmLXNpZ25lZAorICAgICAgICBpZiAoc2lnbmVyLmdldFN1YmplY3RETigpLmVxdWFscyhzaWduZXIuZ2V0SXNzdWVyRE4oKSkpeworICAgICAgICAgICAgcmV0dXJuIChYNTA5Q2VydGlmaWNhdGVbXSljaGFpbi50b0FycmF5KG5ldyBYNTA5Q2VydGlmaWNhdGVbMV0pOworICAgICAgICB9CisKKyAgICAgICAgUHJpbmNpcGFsIGlzc3VlciA9IHNpZ25lci5nZXRJc3N1ZXJETigpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgaXNzdWVyQ2VydDsKKyAgICAgICAgaW50IGNvdW50ID0gMTsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIGlzc3VlckNlcnQgPSBmaW5kQ2VydChpc3N1ZXIsIGNhbmRpZGF0ZXMpOworICAgICAgICAgICAgaWYoIGlzc3VlckNlcnQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2hhaW4uYWRkKGlzc3VlckNlcnQpOworICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgICAgIGlmIChpc3N1ZXJDZXJ0LmdldFN1YmplY3RETigpLmVxdWFscyhpc3N1ZXJDZXJ0LmdldElzc3VlckROKCkpKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpc3N1ZXIgPSBpc3N1ZXJDZXJ0LmdldElzc3VlckROKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChYNTA5Q2VydGlmaWNhdGVbXSljaGFpbi50b0FycmF5KG5ldyBYNTA5Q2VydGlmaWNhdGVbY291bnRdKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBYNTA5Q2VydGlmaWNhdGUgZmluZENlcnQoUHJpbmNpcGFsIGlzc3VlciwgWDUwOUNlcnRpZmljYXRlW10gY2FuZGlkYXRlcykgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNhbmRpZGF0ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChpc3N1ZXIuZXF1YWxzKGNhbmRpZGF0ZXNbaV0uZ2V0U3ViamVjdEROKCkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNhbmRpZGF0ZXNbaV07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3V0aWxzL09iamVjdElkZW50aWZpZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdXRpbHMvT2JqZWN0SWRlbnRpZmllci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU4N2M0YTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3V0aWxzL09iamVjdElkZW50aWZpZXIuamF2YQpAQCAtMCwwICsxLDIxNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBWLiBFc2luLCBTdGVwYW4gTS4gTWlzaHVyYQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS51dGlsczsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogSW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyByZXByZXNlbnRzIE9iamVjdElkZW50aWZpZXIgKE9JRCkuCisgKgorICogT0lEIGlzIHJlcHJlc2VudGVkIGFzIGEgc2VxdWVuY2Ugb2Ygc3ViaWRlbnRpZmllci4KKyAqIEVhY2ggc3ViaWRlbnRpZmllciBpcyByZXByZXNlbnRlZCBhcyBub24gbmVnYXRpdmUgaW50ZWdlciB2YWx1ZS4KKyAqIFRoZXJlIGFyZSBhdCBsZWFzdCAyIHN1YmlkZW50aWZpZXJzIGluIHRoZSBzZXF1ZW5jZS4KKyAqCisgKiBWYWxpZCB2YWx1ZXMgZm9yIGZpcnN0IHN1YmlkZW50aWZpZXIgYXJlIDAsIDEgYW5kIDIuCisgKiBJZiB0aGUgZmlyc3Qgc3ViaWRlbnRpZmllciBoYXMgMCBvciAxIHZhbHVlIHRoZSBzZWNvbmQKKyAqIHN1YmlkZW50aWZpZXIgTVVTVCBiZSBsZXNzIHRoZW4gNDAuCisgKgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vYXNuMS5lbGliZWwudG0uZnIvZW4vc3RhbmRhcmRzL2luZGV4Lmh0bSI+QVNOLjE8L2E+CisgKi8KKworcHVibGljIGZpbmFsIGNsYXNzIE9iamVjdElkZW50aWZpZXIgeworCisgICAgLy9PSUQgYXMgYXJyYXkgb2YgaW50ZWdlcnMKKyAgICBwcml2YXRlIGZpbmFsIGludFtdIG9pZDsKKworICAgIC8vaGFzaCBjb2RlCisgICAgcHJpdmF0ZSBpbnQgaGFzaCA9IC0xOworCisgICAgLy9PSUQgYXMgc3RyaW5nCisgICAgcHJpdmF0ZSBTdHJpbmcgc29pZDsKKworICAgIC8vIHN0b3JlcyB0aGUgZm9sbG93aW5nOiAiT0lELiIgKyBzb2lkCisgICAgcHJpdmF0ZSBTdHJpbmcgc09JRDsKKworICAgIC8vIE9JRCBhbGlhcyBuYW1lCisgICAgcHJpdmF0ZSBTdHJpbmcgbmFtZTsKKworICAgIC8vIE9JRCdzIGdyb3VwCisgICAgcHJpdmF0ZSBPYmplY3QgZ3JvdXA7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIE9iamVjdElkZW50aWZpZXIoT0lEKSBmcm9tIGFycmF5IG9mIGludGVnZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIG9pZCAtIGFycmF5IG9mIGludGVnZXJzCisgICAgICogQHJldHVybiAtIE9JRCBvYmplY3QKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICAgICAtIGlmIG9pZCBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gLSBpZiBvaWQgaXMgaW52YWxpZAorICAgICAqLworICAgIHB1YmxpYyBPYmplY3RJZGVudGlmaWVyKGludFtdIG9pZCkgeworCisgICAgICAgIHZhbGlkYXRlT2lkKG9pZCk7CisKKyAgICAgICAgdGhpcy5vaWQgPSBvaWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBPYmplY3RJZGVudGlmaWVyKE9JRCkgZnJvbSBhcnJheSBvZiBpbnRlZ2Vycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvaWQgLSBhcnJheSBvZiBpbnRlZ2VycworICAgICAqIEBwYXJhbSBuYW1lIC0gbmFtZSBvZiBPSUQKKyAgICAgKiBAcGFyYW0gb2lkR3JvdXAgLSBPSUQncyBncm91cC4gSXMgdXNlZCB0byBzZXBhcmF0ZSBkaWZmZXJlbnQgT0lEJ3MKKyAgICAgKiBAcmV0dXJuIC0gT0lEIG9iamVjdAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gICAgIC0gaWYgb2lkIGlzIG51bGwKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAtIGlmIG9pZCBpcyBpbnZhbGlkCisgICAgICovCisgICAgcHVibGljIE9iamVjdElkZW50aWZpZXIoaW50W10gb2lkLCBTdHJpbmcgbmFtZSwgT2JqZWN0IG9pZEdyb3VwKSB7CisgICAgICAgIHRoaXMob2lkKTsKKworICAgICAgICBpZiAob2lkR3JvdXAgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJvaWRHcm91cCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5ncm91cCA9IG9pZEdyb3VwOworCisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgIHRvT0lEU3RyaW5nKCk7IC8vIGluaXQgc29pZCAmIHNPSUQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIE9JRC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gb2lkCisgICAgICovCisgICAgcHVibGljIGludFtdIGdldE9pZCgpIHsKKyAgICAgICAgcmV0dXJuIG9pZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIE9JRCdzIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgT0lEJ3MgZ3JvdXAuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGdyb3VwCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRHcm91cCgpIHsKKyAgICAgICAgcmV0dXJuIGdyb3VwOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIG9iamVjdCB3aXRoIE9JRCBmb3IgZXF1YWxpdHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgb2JqZWN0IGlzIE9iamVjdElkZW50aWZpZXIgYW5kIGl0IGhhcyB0aGUgc2FtZQorICAgICAqICAgICAgICAgcmVwcmVzZW50YXRpb24gYXMgYXJyYXkgb2YgaW50ZWdlcnMsIG90aGVyd2lzZSBmYWxzZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICBpZiAodGhpcyA9PSBvKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAobyA9PSBudWxsIHx8IHRoaXMuZ2V0Q2xhc3MoKSAhPSBvLmdldENsYXNzKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscyhvaWQsICgoT2JqZWN0SWRlbnRpZmllcikgbykub2lkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQgIk9JRC4iIHRvIHRoZSBiZWdpbm5pbmcgb2Ygc3RyaW5nIHJlcHJlc2VudGF0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBvaWQgYXMgc3RyaW5nCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b09JRFN0cmluZygpIHsKKyAgICAgICAgaWYgKHNPSUQgPT0gbnVsbCkgeworICAgICAgICAgICAgc09JRCA9ICJPSUQuIiArIHRvU3RyaW5nKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNPSUQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3ZlcnJpZGVzIE9iamVjdC50b1N0cmluZygpCisgICAgICoKKyAgICAgKiBAcmV0dXJuIG9pZCBhcyBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBpZiAoc29pZCA9PSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoNCAqIG9pZC5sZW5ndGgpOworCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9pZC5sZW5ndGggLSAxOyArK2kpIHsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQob2lkW2ldKTsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoJy4nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNiLmFwcGVuZChvaWRbb2lkLmxlbmd0aCAtIDFdKTsKKyAgICAgICAgICAgIHNvaWQgPSBzYi50b1N0cmluZygpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzb2lkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCNoYXNoQ29kZSgpCisgICAgICovCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgaWYgKGhhc2ggPT0gLTEpIHsKKyAgICAgICAgICAgIGhhc2ggPSBoYXNoSW50QXJyYXkob2lkKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWYWxpZGF0ZXMgT2JqZWN0SWRlbnRpZmllciAoT0lEKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvaWQgLSBvaWQgYXMgYXJyYXkgb2YgaW50ZWdlcnMKKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICAgICAtIGlmIG9pZCBpcyBudWxsCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gLSBpZiBvaWQgaXMgaW52YWxpZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB2YWxpZGF0ZU9pZChpbnRbXSBvaWQpIHsKKworICAgICAgICBpZiAob2lkID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigib2lkID09IG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChvaWQubGVuZ3RoIDwgMikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiT0lEIE1VU1QgaGF2ZSBhdCBsZWFzdCAyIHN1YmlkZW50aWZpZXJzIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAob2lkWzBdID4gMikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVmFsaWQgdmFsdWVzIGZvciBmaXJzdCBzdWJpZGVudGlmaWVyIGFyZSAwLCAxIGFuZCAyIik7CisgICAgICAgIH0gZWxzZSBpZiAob2lkWzBdICE9IDIgJiYgb2lkWzFdID4gMzkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklmIHRoZSBmaXJzdCBzdWJpZGVudGlmaWVyIGhhcyAwIG9yIDEgdmFsdWUgdGhlIHNlY29uZCBzdWJpZGVudGlmaWVyIHZhbHVlIE1VU1QgYmUgbGVzcyB0aGFuIDQwIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGhhc2ggY29kZSBmb3IgYXJyYXkgb2YgaW50ZWdlcnMKKyAgICAgKgorICAgICAqIEBwYXJhbSBvaWQgLSBhcnJheSBvZiBpbnRlZ2VycworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IGhhc2hJbnRBcnJheShpbnRbXSBhcnJheSkgeworICAgICAgICBpbnQgaW50SGFzaCA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoICYmIGkgPCA0OyBpKyspIHsKKyAgICAgICAgICAgIGludEhhc2ggKz0gYXJyYXlbaV0gPDwgKDggKiBpKTsgLy9UT0RPIHdoYXQgYWJvdXQgdG8gZmluZCBiZXR0ZXIgb25lPworICAgICAgICB9CisgICAgICAgIHJldHVybiBpbnRIYXNoICYgMHg3RkZGRkZGRjsgLy8gb25seSBwb3NpdGl2ZQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwMS9BdHRyaWJ1dGVUeXBlQW5kVmFsdWUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwMS9BdHRyaWJ1dGVUeXBlQW5kVmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OWY1YjNlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTAxL0F0dHJpYnV0ZVR5cGVBbmRWYWx1ZS5qYXZhCkBAIC0wLDAgKzEsNDYwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgVi4gRXNpbiwgU3RlcGFuIE0uIE1pc2h1cmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwMTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0czsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUNvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xT2lkOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXF1ZW5jZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU3RyaW5nVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnV0aWxzLk9iamVjdElkZW50aWZpZXI7CisKKworLyoqCisgKiBYLjUwMSBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZSB7CisKKyAgICAvKioga25vd24gYXR0cmlidXRlIHR5cGVzIGZvciBSRkMxNzc5IChzZWUgVGFibGUgMSkgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBIYXNoTWFwPFN0cmluZywgT2JqZWN0SWRlbnRpZmllcj4gUkZDMTc3OV9OQU1FUworICAgICAgICAgICAgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIE9iamVjdElkZW50aWZpZXI+KDEwKTsKKworICAgIC8qKiBrbm93biBrZXl3b3JkcyBhdHRyaWJ1dGUgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBIYXNoTWFwPFN0cmluZywgT2JqZWN0SWRlbnRpZmllcj4gS05PV05fTkFNRVMKKyAgICAgICAgICAgID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBPYmplY3RJZGVudGlmaWVyPigzMCk7CisKKyAgICAvKioga25vd24gYXR0cmlidXRlIHR5cGVzIGZvciBSRkMyMjUzIChzZWUgMi4zLiAgQ29udmVydGluZyBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUpICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSGFzaE1hcDxTdHJpbmcsIE9iamVjdElkZW50aWZpZXI+IFJGQzIyNTNfTkFNRVMKKyAgICAgICAgICAgID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBPYmplY3RJZGVudGlmaWVyPigxMCk7CisKKyAgICAvKioga25vd24gYXR0cmlidXRlIHR5cGVzIGZvciBSRkMyNDU5IChzZWUgQVBJIHNwZWMuKSAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEhhc2hNYXA8U3RyaW5nLCBPYmplY3RJZGVudGlmaWVyPiBSRkMyNDU5X05BTUVTCisgICAgICAgICAgICA9IG5ldyBIYXNoTWFwPFN0cmluZywgT2JqZWN0SWRlbnRpZmllcj4oMTApOworCisgICAgLyoqIENvdW50cnkgY29kZSBhdHRyaWJ1dGUgKG5hbWUgZnJvbSBSRkMgMTc3OSkgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RJZGVudGlmaWVyIEMKKyAgICAgICAgICAgID0gbmV3IE9iamVjdElkZW50aWZpZXIobmV3IGludFtdIHsgMiwgNSwgNCwgNiB9LCAiQyIsIFJGQzE3NzlfTkFNRVMpOworCisgICAgLyoqIENvbW1vbiBuYW1lIGF0dHJpYnV0ZSAobmFtZSBmcm9tIFJGQyAxNzc5KSAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdElkZW50aWZpZXIgQ04KKyAgICAgICAgICAgID0gbmV3IE9iamVjdElkZW50aWZpZXIobmV3IGludFtdIHsgMiwgNSwgNCwgMyB9LCAiQ04iLCBSRkMxNzc5X05BTUVTKTsKKworICAgIC8qKiBEb21haW4gY29tcG9uZW50IGF0dHJpYnV0ZSAobmFtZSBmcm9tIFJGQyAyMjUzKSAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdElkZW50aWZpZXIgREMgPSBuZXcgT2JqZWN0SWRlbnRpZmllcigKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7IDAsIDksIDIzNDIsIDE5MjAwMzAwLCAxMDAsIDEsIDI1IH0sICJEQyIsIFJGQzIyNTNfTkFNRVMpOworCisgICAgLyoqIEROIHF1YWxpZmllciBhdHRyaWJ1dGUgKG5hbWUgZnJvbSBBUEkgc3BlYykgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RJZGVudGlmaWVyIEROUQorICAgICAgICAgICAgPSBuZXcgT2JqZWN0SWRlbnRpZmllcihuZXcgaW50W10geyAyLCA1LCA0LCA0NiB9LCAiRE5RIiwgUkZDMjQ1OV9OQU1FUyk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RJZGVudGlmaWVyIEROUVVBTElGSUVSCisgICAgICAgICAgICA9IG5ldyBPYmplY3RJZGVudGlmaWVyKG5ldyBpbnRbXSB7IDIsIDUsIDQsIDQ2IH0sICJETlFVQUxJRklFUiIsIFJGQzI0NTlfTkFNRVMpOworCisgICAgLyoqIEVtYWlsIEFkZHJlc3MgYXR0cmlidXRlIChuYW1lIGZyb20gQVBJIHNwZWMpICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0SWRlbnRpZmllciBFTUFJTEFERFJFU1MgPSBuZXcgT2JqZWN0SWRlbnRpZmllcigKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7IDEsIDIsIDg0MCwgMTEzNTQ5LCAxLCA5LCAxfSwgIkVNQUlMQUREUkVTUyIsIFJGQzI0NTlfTkFNRVMpOworCisgICAgLyoqIEdlbmVyYXRpb24gYXR0cmlidXRlIChxdWFsaWZpZXMgYW4gaW5kaXZpZHVhbCdzIG5hbWUpIChuYW1lIGZyb20gQVBJIHNwZWMpICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0SWRlbnRpZmllciBHRU5FUkFUSU9OCisgICAgICAgICAgICA9IG5ldyBPYmplY3RJZGVudGlmaWVyKG5ldyBpbnRbXSB7IDIsIDUsIDQsIDQ0IH0sICJHRU5FUkFUSU9OIiwgUkZDMjQ1OV9OQU1FUyk7CisKKyAgICAvKiogR2l2ZW4gbmFtZSBhdHRyaWJ1dGUgKG5hbWUgZnJvbSBBUEkgc3BlYykgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RJZGVudGlmaWVyIEdJVkVOTkFNRQorICAgICAgICAgICAgPSBuZXcgT2JqZWN0SWRlbnRpZmllcihuZXcgaW50W10geyAyLCA1LCA0LCA0MiB9LCAiR0lWRU5OQU1FIiwgUkZDMjQ1OV9OQU1FUyk7CisKKyAgICAvKiogSW5pdGlhbHMgYXR0cmlidXRlIChpbml0aWFscyBvZiBhbiBpbmRpdmlkdWFsJ3MgbmFtZSkgKG5hbWUgZnJvbSBBUEkgc3BlYykgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RJZGVudGlmaWVyIElOSVRJQUxTCisgICAgICAgICAgICA9IG5ldyBPYmplY3RJZGVudGlmaWVyKG5ldyBpbnRbXSB7IDIsIDUsIDQsIDQzIH0sICJJTklUSUFMUyIsIFJGQzI0NTlfTkFNRVMpOworCisgICAgLyoqIE5hbWUgb2YgYSBsb2NhbGl0eSBhdHRyaWJ1dGUgKG5hbWUgZnJvbSBSRkMgMTc3OSkgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RJZGVudGlmaWVyIEwKKyAgICAgICAgICAgID0gbmV3IE9iamVjdElkZW50aWZpZXIobmV3IGludFtdIHsgMiwgNSwgNCwgNyB9LCAiTCIsIFJGQzE3NzlfTkFNRVMpOworCisgICAgLyoqIE9yZ2FuaXphdGlvbiBuYW1lIGF0dHJpYnV0ZSAobmFtZSBmcm9tIFJGQyAxNzc5KSAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdElkZW50aWZpZXIgTworICAgICAgICAgICAgPSBuZXcgT2JqZWN0SWRlbnRpZmllcihuZXcgaW50W10geyAyLCA1LCA0LCAxMCB9LCAiTyIsIFJGQzE3NzlfTkFNRVMpOworCisgICAgLyoqIE9yZ2FuaXphdGlvbmFsIHVuaXQgbmFtZSBhdHRyaWJ1dGUgKG5hbWUgZnJvbSBSRkMgMTc3OSkgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RJZGVudGlmaWVyIE9VCisgICAgICAgICAgICA9IG5ldyBPYmplY3RJZGVudGlmaWVyKG5ldyBpbnRbXSB7IDIsIDUsIDQsIDExIH0sICJPVSIsIFJGQzE3NzlfTkFNRVMpOworCisgICAgLyoqIFNlcmlhbCBudW1iZXIgYXR0cmlidXRlIChzZXJpYWwgbnVtYmVyIG9mIGEgZGV2aWNlKSAobmFtZSBmcm9tIEFQSSBzcGVjKSAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdElkZW50aWZpZXIgU0VSSUFMTlVNQkVSCisgICAgICAgICAgICA9IG5ldyBPYmplY3RJZGVudGlmaWVyKG5ldyBpbnRbXSB7IDIsIDUsIDQsIDUgfSwgIlNFUklBTE5VTUJFUiIsIFJGQzI0NTlfTkFNRVMpOworCisgICAgLyoqIEF0dHJpYnV0ZSBmb3IgdGhlIGZ1bGwgbmFtZSBvZiBhIHN0YXRlIG9yIHByb3ZpbmNlIChuYW1lIGZyb20gUkZDIDE3NzkpICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0SWRlbnRpZmllciBTVAorICAgICAgICAgICAgPSBuZXcgT2JqZWN0SWRlbnRpZmllcihuZXcgaW50W10geyAyLCA1LCA0LCA4IH0sICJTVCIsIFJGQzE3NzlfTkFNRVMpOworCisgICAgLyoqIFN0cmVldCBhdHRyaWJ1dGUgKG5hbWUgZnJvbSBSRkMgMTc3OSkgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RJZGVudGlmaWVyIFNUUkVFVAorICAgICAgICAgICAgPSBuZXcgT2JqZWN0SWRlbnRpZmllcihuZXcgaW50W10geyAyLCA1LCA0LCA5IH0sICJTVFJFRVQiLCBSRkMxNzc5X05BTUVTKTsKKworICAgIC8qKiBTdXJuYW1lIGF0dHJpYnV0ZSAoY29tZXMgZnJvbSBhbiBpbmRpdmlkdWFsJ3MgcGFyZW50IG5hbWUpIChuYW1lIGZyb20gQVBJIHNwZWMpICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0SWRlbnRpZmllciBTVVJOQU1FCisgICAgICAgICAgICA9IG5ldyBPYmplY3RJZGVudGlmaWVyKG5ldyBpbnRbXSB7IDIsIDUsIDQsIDQgfSwgIlNVUk5BTUUiLCBSRkMyNDU5X05BTUVTKTsKKworICAgIC8qKiBUaXRsZSBhdHRyaWJ1dGUgKG9iamVjdCBpbiBhbiBvcmdhbml6YXRpb24pKG5hbWUgZnJvbSBBUEkgc3BlYykgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RJZGVudGlmaWVyIFQKKyAgICAgICAgICAgID0gbmV3IE9iamVjdElkZW50aWZpZXIobmV3IGludFtdIHsgMiwgNSwgNCwgMTIgfSwgIlQiLCBSRkMyNDU5X05BTUVTKTsKKworICAgIC8qKiBVc2VyIGlkZW50aWZpZXIgYXR0cmlidXRlIChuYW1lIGZyb20gUkZDIDIyNTMpICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0SWRlbnRpZmllciBVSUQgPSBuZXcgT2JqZWN0SWRlbnRpZmllcigKKyAgICAgICAgICAgIG5ldyBpbnRbXXsgMCwgOSwgMjM0MiwgMTkyMDAzMDAsIDEwMCwgMSwgMSB9LCAiVUlEIiwgUkZDMjI1M19OQU1FUyk7CisKKyAgICAvKiogcG9vbCdzIGNhcGFjaXR5ICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENBUEFDSVRZID0gMTA7CisKKyAgICAvKiogcG9vbCdzIHNpemUgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0laRSA9IDEwOworCisgICAgLyoqIHBvb2w6IGNvbnRhaW5zIGFsbCByZWNvZ25pemFibGUgYXR0cmlidXRlIHR5cGUga2V5d29yZHMgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RJZGVudGlmaWVyW11bXSBLTk9XTl9PSURTID0gbmV3IE9iamVjdElkZW50aWZpZXJbU0laRV1bQ0FQQUNJVFldOworCisgICAgc3RhdGljIHsKKyAgICAgICAgUkZDMTc3OV9OQU1FUy5wdXQoQ04uZ2V0TmFtZSgpLCBDTik7CisgICAgICAgIFJGQzE3NzlfTkFNRVMucHV0KEwuZ2V0TmFtZSgpLCBMKTsKKyAgICAgICAgUkZDMTc3OV9OQU1FUy5wdXQoU1QuZ2V0TmFtZSgpLCBTVCk7CisgICAgICAgIFJGQzE3NzlfTkFNRVMucHV0KE8uZ2V0TmFtZSgpLCBPKTsKKyAgICAgICAgUkZDMTc3OV9OQU1FUy5wdXQoT1UuZ2V0TmFtZSgpLCBPVSk7CisgICAgICAgIFJGQzE3NzlfTkFNRVMucHV0KEMuZ2V0TmFtZSgpLCBDKTsKKyAgICAgICAgUkZDMTc3OV9OQU1FUy5wdXQoU1RSRUVULmdldE5hbWUoKSwgU1RSRUVUKTsKKworICAgICAgICBSRkMyMjUzX05BTUVTLnB1dEFsbChSRkMxNzc5X05BTUVTKTsKKyAgICAgICAgUkZDMjI1M19OQU1FUy5wdXQoREMuZ2V0TmFtZSgpLCBEQyk7CisgICAgICAgIFJGQzIyNTNfTkFNRVMucHV0KFVJRC5nZXROYW1lKCksIFVJRCk7CisKKyAgICAgICAgUkZDMjQ1OV9OQU1FUy5wdXQoRE5RLmdldE5hbWUoKSwgRE5RKTsKKyAgICAgICAgUkZDMjQ1OV9OQU1FUy5wdXQoRE5RVUFMSUZJRVIuZ2V0TmFtZSgpLCBETlFVQUxJRklFUik7CisgICAgICAgIFJGQzI0NTlfTkFNRVMucHV0KEVNQUlMQUREUkVTUy5nZXROYW1lKCksIEVNQUlMQUREUkVTUyk7CisgICAgICAgIFJGQzI0NTlfTkFNRVMucHV0KEdFTkVSQVRJT04uZ2V0TmFtZSgpLCBHRU5FUkFUSU9OKTsKKyAgICAgICAgUkZDMjQ1OV9OQU1FUy5wdXQoR0lWRU5OQU1FLmdldE5hbWUoKSwgR0lWRU5OQU1FKTsKKyAgICAgICAgUkZDMjQ1OV9OQU1FUy5wdXQoSU5JVElBTFMuZ2V0TmFtZSgpLCBJTklUSUFMUyk7CisgICAgICAgIFJGQzI0NTlfTkFNRVMucHV0KFNFUklBTE5VTUJFUi5nZXROYW1lKCksIFNFUklBTE5VTUJFUik7CisgICAgICAgIFJGQzI0NTlfTkFNRVMucHV0KFNVUk5BTUUuZ2V0TmFtZSgpLCBTVVJOQU1FKTsKKyAgICAgICAgUkZDMjQ1OV9OQU1FUy5wdXQoVC5nZXROYW1lKCksIFQpOworCisgICAgICAgIC8vIGFkZCBmcm9tIFJGQzIyNTMgKGluY2x1ZGVzIFJGQzE3NzkpCisgICAgICAgIGZvciAoT2JqZWN0SWRlbnRpZmllciBvYmplY3RJZGVudGlmaWVyIDogUkZDMjI1M19OQU1FUy52YWx1ZXMoKSkgeworICAgICAgICAgICAgYWRkT0lEKG9iamVjdElkZW50aWZpZXIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gYWRkIGF0dHJpYnV0ZXMgZnJvbSBSRkMyNDU5CisgICAgICAgIGZvciAoT2JqZWN0SWRlbnRpZmllciBvIDogUkZDMjQ1OV9OQU1FUy52YWx1ZXMoKSkgeworICAgICAgICAgICAgLy9kb24ndCBhZGQgRE5RVUFMSUZJRVIgYmVjYXVzZSBpdCBoYXMgdGhlIHNhbWUgb2lkIGFzIEROUQorICAgICAgICAgICAgaWYgKCEobyA9PSBETlFVQUxJRklFUikpIHsKKyAgICAgICAgICAgICAgICBhZGRPSUQobyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBLTk9XTl9OQU1FUy5wdXRBbGwoUkZDMjI1M19OQU1FUyk7IC8vIFJGQzIyNTMgaW5jbHVkZXMgUkZDMTc3OQorICAgICAgICBLTk9XTl9OQU1FUy5wdXRBbGwoUkZDMjQ1OV9OQU1FUyk7CisgICAgfQorCisgICAgLyoqIEF0dHJpYnV0ZSB0eXBlICovCisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3RJZGVudGlmaWVyIG9pZDsKKworICAgIC8qKiBBdHRyaWJ1dGUgdmFsdWUgKi8KKyAgICBwcml2YXRlIGZpbmFsIEF0dHJpYnV0ZVZhbHVlIHZhbHVlOworCisgICAgLy8gZm9yIGRlY29kZXIgb25seQorICAgIHByaXZhdGUgQXR0cmlidXRlVHlwZUFuZFZhbHVlKGludFtdIG9pZCwgQXR0cmlidXRlVmFsdWUgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdElkZW50aWZpZXIgdGhpc09pZCA9IGdldE9JRChvaWQpOworICAgICAgICBpZiAodGhpc09pZCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aGlzT2lkID0gbmV3IE9iamVjdElkZW50aWZpZXIob2lkKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLm9pZCA9IHRoaXNPaWQ7CisgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZSB3aXRoIE9JRCBhbmQgQXR0cmlidXRlVmFsdWUuIFBhcnNlcyBPSUQKKyAgICAgKiBzdHJpbmcgcmVwcmVzZW50YXRpb24KKyAgICAgKgorICAgICAqIEBwYXJhbSBzT2lkCisgICAgICogICAgICAgICAgICBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgT0lECisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogICAgICAgICAgICBhdHRyaWJ1dGUgdmFsdWUKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgT0lEIGNhbiBub3QgYmUgY3JlYXRlZCBmcm9tIGl0cyBzdHJpbmcgcmVwcmVzZW50YXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgQXR0cmlidXRlVHlwZUFuZFZhbHVlKFN0cmluZyBzT2lkLCBBdHRyaWJ1dGVWYWx1ZSB2YWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNPaWQuY2hhckF0KDApID49ICcwJyAmJiBzT2lkLmNoYXJBdCgwKSA8PSAnOScpIHsKKyAgICAgICAgICAgIGludFtdIGFycmF5ID0gb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuT2JqZWN0SWRlbnRpZmllci50b0ludEFycmF5KHNPaWQpOworICAgICAgICAgICAgT2JqZWN0SWRlbnRpZmllciB0aGlzT2lkID0gZ2V0T0lEKGFycmF5KTsKKyAgICAgICAgICAgIGlmICh0aGlzT2lkID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aGlzT2lkID0gbmV3IE9iamVjdElkZW50aWZpZXIoYXJyYXkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy5vaWQgPSB0aGlzT2lkOworCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aGlzLm9pZCA9IEtOT1dOX05BTUVTLmdldChzT2lkLnRvVXBwZXJDYXNlKExvY2FsZS5VUykpOworICAgICAgICAgICAgaWYgKHRoaXMub2lkID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlVucmVjb2duaXphYmxlIGF0dHJpYnV0ZSBuYW1lOiAiICsgc09pZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgQXR0cmlidXRlVHlwZUFuZFZhbHVlIHN0cmluZyByZXByZXNlbnRhdGlvbgorICAgICAqCisgICAgICogQHBhcmFtIGF0dHJGb3JtYXQgLSBmb3JtYXQgb2YgRE4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhcHBlbmROYW1lKFN0cmluZyBhdHRyRm9ybWF0LCBTdHJpbmdCdWlsZGVyIHNiKSB7CisgICAgICAgIGJvb2xlYW4gaGV4Rm9ybWF0ID0gZmFsc2U7CisgICAgICAgIGlmIChYNTAwUHJpbmNpcGFsLlJGQzE3NzkuZXF1YWxzKGF0dHJGb3JtYXQpKSB7CisgICAgICAgICAgICBpZiAoUkZDMTc3OV9OQU1FUyA9PSBvaWQuZ2V0R3JvdXAoKSkgeworICAgICAgICAgICAgICAgIHNiLmFwcGVuZChvaWQuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKG9pZC50b09JRFN0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc2IuYXBwZW5kKCc9Jyk7CisgICAgICAgICAgICBpZiAodmFsdWUuZXNjYXBlZFN0cmluZyA9PSB2YWx1ZS5nZXRIZXhTdHJpbmcoKSkgeworICAgICAgICAgICAgICAgIHNiLmFwcGVuZCh2YWx1ZS5nZXRIZXhTdHJpbmcoKS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUuZXNjYXBlZFN0cmluZy5sZW5ndGgoKSAhPSB2YWx1ZS5yYXdTdHJpbmcubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgICAgICAvLyB3YXMgZXNjYXBlZAorICAgICAgICAgICAgICAgIHZhbHVlLmFwcGVuZFFFU3RyaW5nKHNiKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKHZhbHVlLmVzY2FwZWRTdHJpbmcpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgT2JqZWN0IGdyb3VwID0gb2lkLmdldEdyb3VwKCk7CisgICAgICAgICAgICAvLyBSRkMyMjUzIGluY2x1ZGVzIG5hbWVzIGZyb20gUkZDMTc3OQorICAgICAgICAgICAgaWYgKFJGQzE3NzlfTkFNRVMgPT0gZ3JvdXAgfHwgUkZDMjI1M19OQU1FUyA9PSBncm91cCkgeworICAgICAgICAgICAgICAgIHNiLmFwcGVuZChvaWQuZ2V0TmFtZSgpKTsKKworICAgICAgICAgICAgICAgIGlmIChYNTAwUHJpbmNpcGFsLkNBTk9OSUNBTC5lcXVhbHMoYXR0ckZvcm1hdCkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gb25seSBQcmludGFibGVTdHJpbmcgYW5kIFVURjhTdHJpbmcgaW4gc3RyaW5nIGZvcm1hdAorICAgICAgICAgICAgICAgICAgICAvLyBhbGwgb3RoZXJzIGFyZSBvdXRwdXQgaW4gaGV4IGZvcm1hdAorICAgICAgICAgICAgICAgICAgICAvLyBubyBoZXggZm9yIHRlbGV0ZXg7IHNlZSBodHRwOi8vYi8yMTAyMTkxCisgICAgICAgICAgICAgICAgICAgIGludCB0YWcgPSB2YWx1ZS5nZXRUYWcoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFBU04xU3RyaW5nVHlwZS5VVEY4U1RSSU5HLmNoZWNrVGFnKHRhZykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAhQVNOMVN0cmluZ1R5cGUuUFJJTlRBQkxFU1RSSU5HLmNoZWNrVGFnKHRhZykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAhQVNOMVN0cmluZ1R5cGUuVEVMRVRFWFNUUklORy5jaGVja1RhZyh0YWcpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBoZXhGb3JtYXQgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHNiLmFwcGVuZChvaWQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgaGV4Rm9ybWF0ID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc2IuYXBwZW5kKCc9Jyk7CisKKyAgICAgICAgICAgIGlmIChoZXhGb3JtYXQpIHsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQodmFsdWUuZ2V0SGV4U3RyaW5nKCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAoWDUwMFByaW5jaXBhbC5DQU5PTklDQUwuZXF1YWxzKGF0dHJGb3JtYXQpKSB7CisgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZCh2YWx1ZS5tYWtlQ2Fub25pY2FsKCkpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZCh2YWx1ZS5lc2NhcGVkU3RyaW5nKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHR5cGUgb2YgdGhlIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZQorICAgICAqLworICAgIHB1YmxpYyBPYmplY3RJZGVudGlmaWVyIGdldFR5cGUoKSB7CisgICAgICAgIHJldHVybiBvaWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWNjb3JkaW5nIHRvIFJGQyAzMjgwIChodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCkKKyAgICAgKiBYLjUwMSBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgc3RydWN0dXJlIGlzIGRlZmluZWQgYXMgZm9sbG93czoKKyAgICAgKgorICAgICAqICAgQXR0cmlidXRlVHlwZUFuZFZhbHVlIDo6PSBTRVFVRU5DRSB7CisgICAgICogICAgICB0eXBlICAgICBBdHRyaWJ1dGVUeXBlLAorICAgICAqICAgICAgdmFsdWUgICAgQXR0cmlidXRlVmFsdWUgfQorICAgICAqCisgICAgICogICAgQXR0cmlidXRlVHlwZSA6Oj0gT0JKRUNUIElERU5USUZJRVIKKyAgICAgKgorICAgICAqICAgIEF0dHJpYnV0ZVZhbHVlIDo6PSBBTlkgREVGSU5FRCBCWSBBdHRyaWJ1dGVUeXBlCisgICAgICogICAgLi4uCisgICAgICogICAgRGlyZWN0b3J5U3RyaW5nIDo6PSBDSE9JQ0UgeworICAgICAqICAgICAgICAgIHRlbGV0ZXhTdHJpbmcgICAgICAgICAgIFRlbGV0ZXhTdHJpbmcgKFNJWkUgKDEuLk1BWCkpLAorICAgICAqICAgICAgICAgIHByaW50YWJsZVN0cmluZyAgICAgICAgIFByaW50YWJsZVN0cmluZyAoU0laRSAoMS4uTUFYKSksCisgICAgICogICAgICAgICAgdW5pdmVyc2FsU3RyaW5nICAgICAgICAgVW5pdmVyc2FsU3RyaW5nIChTSVpFICgxLi5NQVgpKSwKKyAgICAgKiAgICAgICAgICB1dGY4U3RyaW5nICAgICAgICAgICAgICBVVEY4U3RyaW5nIChTSVpFICgxLi4gTUFYKSksCisgICAgICogICAgICAgICAgYm1wU3RyaW5nICAgICAgICAgICAgICAgQk1QU3RyaW5nIChTSVpFICgxLi5NQVgpKSB9CisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFUeXBlIGF0dHJpYnV0ZVZhbHVlID0gbmV3IEFTTjFUeXBlKEFTTjFDb25zdGFudHMuVEFHX1BSSU5UQUJMRVNUUklORykgeworCisgICAgICAgIHB1YmxpYyBib29sZWFuIGNoZWNrVGFnKGludCB0YWcpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBkZWNvZGUoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBGSVhNRSB3aGF0IGFib3V0IGNvbnN0cj8/PworICAgICAgICAgICAgU3RyaW5nIHN0ciA9IG51bGw7CisgICAgICAgICAgICBpZiAoRGlyZWN0b3J5U3RyaW5nLkFTTjEuY2hlY2tUYWcoaW4udGFnKSkgeworICAgICAgICAgICAgICAgIC8vIGhhcyBzdHJpbmcgcmVwcmVzZW50YXRpb24KKyAgICAgICAgICAgICAgICBzdHIgPSAoU3RyaW5nKSBEaXJlY3RvcnlTdHJpbmcuQVNOMS5kZWNvZGUoaW4pOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBnZXRzIG9jdGV0cyBvbmx5CisgICAgICAgICAgICAgICAgaW4ucmVhZENvbnRlbnQoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYnl0ZVtdIGJ5dGVzRW5jb2RlZCA9IG5ldyBieXRlW2luLmdldE9mZnNldCgpIC0gaW4uZ2V0VGFnT2Zmc2V0KCldOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShpbi5nZXRCdWZmZXIoKSwgaW4uZ2V0VGFnT2Zmc2V0KCksIGJ5dGVzRW5jb2RlZCwKKyAgICAgICAgICAgICAgICAgICAgMCwgYnl0ZXNFbmNvZGVkLmxlbmd0aCk7CisKKyAgICAgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlVmFsdWUoc3RyLCBieXRlc0VuY29kZWQsIGluLnRhZyk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgLy8gc3R1YiB0byBhdm9pZCB3cm9uZyBkZWNvZGVyIHVzYWdlCisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiQXR0cmlidXRlVmFsdWUgZ2V0RGVjb2RlZE9iamVjdCBNVVNUIE5PVCBiZSBpbnZva2VkIik7CisgICAgICAgIH0KKworICAgICAgICAvLworICAgICAgICAvLyBFbmNvZGUKKyAgICAgICAgLy8KKyAgICAgICAgcHVibGljIHZvaWQgZW5jb2RlQVNOKEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgICAgIEF0dHJpYnV0ZVZhbHVlIGF2ID0gKEF0dHJpYnV0ZVZhbHVlKSBvdXQuY29udGVudDsKKworICAgICAgICAgICAgaWYgKGF2LmVuY29kZWQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5jb250ZW50ID0gYXYuZW5jb2RlZDsKKyAgICAgICAgICAgICAgICBvdXQuZW5jb2RlQU5ZKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG91dC5lbmNvZGVUYWcoYXYuZ2V0VGFnKCkpOworICAgICAgICAgICAgICAgIG91dC5jb250ZW50ID0gYXYuYnl0ZXM7CisgICAgICAgICAgICAgICAgb3V0LmVuY29kZVN0cmluZygpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0RW5jb2RpbmdDb250ZW50KEJlck91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICAgICAgICAgIEF0dHJpYnV0ZVZhbHVlIGF2ID0gKEF0dHJpYnV0ZVZhbHVlKSBvdXQuY29udGVudDsKKworICAgICAgICAgICAgaWYgKGF2LmVuY29kZWQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC5sZW5ndGggPSBhdi5lbmNvZGVkLmxlbmd0aDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKGF2LmdldFRhZygpID09IEFTTjFDb25zdGFudHMuVEFHX1VURjhTVFJJTkcpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LmNvbnRlbnQgPSBhdi5yYXdTdHJpbmc7CisgICAgICAgICAgICAgICAgICAgIEFTTjFTdHJpbmdUeXBlLlVURjhTVFJJTkcuc2V0RW5jb2RpbmdDb250ZW50KG91dCk7CisgICAgICAgICAgICAgICAgICAgIGF2LmJ5dGVzID0gKGJ5dGVbXSkgb3V0LmNvbnRlbnQ7CisgICAgICAgICAgICAgICAgICAgIG91dC5jb250ZW50ID0gYXY7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYXYuYnl0ZXMgPSBhdi5yYXdTdHJpbmcuZ2V0Qnl0ZXMoQ2hhcnNldHMuVVRGXzgpOworICAgICAgICAgICAgICAgICAgICBvdXQubGVuZ3RoID0gYXYuYnl0ZXMubGVuZ3RoOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGVuY29kZUNvbnRlbnQoQmVyT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgICAgICAgLy8gc3R1YiB0byBhdm9pZCB3cm9uZyBlbmNvZGVyIHVzYWdlCisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiQXR0cmlidXRlVmFsdWUgZW5jb2RlQ29udGVudCBNVVNUIE5PVCBiZSBpbnZva2VkIik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBnZXRFbmNvZGVkTGVuZ3RoKEJlck91dHB1dFN0cmVhbSBvdXQpIHsgLy9GSVhNRSBuYW1lCisgICAgICAgICAgICBBdHRyaWJ1dGVWYWx1ZSBhdiA9IChBdHRyaWJ1dGVWYWx1ZSkgb3V0LmNvbnRlbnQ7CisgICAgICAgICAgICBpZiAoYXYuZW5jb2RlZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG91dC5sZW5ndGg7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRFbmNvZGVkTGVuZ3RoKG91dCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xU2VxdWVuY2UgQVNOMSA9IG5ldyBBU04xU2VxdWVuY2UobmV3IEFTTjFUeXBlW10geworICAgICAgICAgICAgQVNOMU9pZC5nZXRJbnN0YW5jZSgpLCBhdHRyaWJ1dGVWYWx1ZSB9KSB7CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIE9iamVjdFtdIHZhbHVlcyA9IChPYmplY3RbXSkgaW4uY29udGVudDsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlVHlwZUFuZFZhbHVlKChpbnRbXSkgdmFsdWVzWzBdLCAoQXR0cmlidXRlVmFsdWUpIHZhbHVlc1sxXSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykgeworICAgICAgICAgICAgQXR0cmlidXRlVHlwZUFuZFZhbHVlIGF0YXYgPSAoQXR0cmlidXRlVHlwZUFuZFZhbHVlKSBvYmplY3Q7CisgICAgICAgICAgICB2YWx1ZXNbMF0gPSBhdGF2Lm9pZC5nZXRPaWQoKTsKKyAgICAgICAgICAgIHZhbHVlc1sxXSA9IGF0YXYudmFsdWU7CisgICAgICAgIH0KKyAgICB9OworCisgICAgLyoqCisgICAgICogUmV0dXJucyBrbm93biBPSUQgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBPYmplY3RJZGVudGlmaWVyIGdldE9JRChpbnRbXSBvaWQpIHsKKyAgICAgICAgaW50IGluZGV4ID0gaGFzaEludEFycmF5KG9pZCkgJSBDQVBBQ0lUWTsKKworICAgICAgICAvLyBsb29rIGZvciBPSUQgaW4gdGhlIHBvb2wKKyAgICAgICAgT2JqZWN0SWRlbnRpZmllcltdIGxpc3QgPSBLTk9XTl9PSURTW2luZGV4XTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGxpc3RbaV0gIT0gbnVsbDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoQXJyYXlzLmVxdWFscyhvaWQsIGxpc3RbaV0uZ2V0T2lkKCkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGxpc3RbaV07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBrbm93biBPSUQgdG8gcG9vbC4KKyAgICAgKiBmb3Igc3RhdGljIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZSBpbml0aWFsaXphdGlvbiBvbmx5CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhZGRPSUQoT2JqZWN0SWRlbnRpZmllciBvaWQpIHsKKyAgICAgICAgaW50W10gbmV3T2lkID0gb2lkLmdldE9pZCgpOworICAgICAgICBpbnQgaW5kZXggPSBoYXNoSW50QXJyYXkobmV3T2lkKSAlIENBUEFDSVRZOworCisgICAgICAgIC8vIGxvb2sgZm9yIE9JRCBpbiB0aGUgcG9vbAorICAgICAgICBPYmplY3RJZGVudGlmaWVyW10gbGlzdCA9IEtOT1dOX09JRFNbaW5kZXhdOworICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgIGZvciAoOyBsaXN0W2ldICE9IG51bGw7IGkrKykgeworICAgICAgICAgICAgLy8gY2hlY2sgd3Jvbmcgc3RhdGljIGluaXRpYWxpemF0aW9uOiBubyBkdXBsaWNhdGUgT0lEcworICAgICAgICAgICAgaWYgKEFycmF5cy5lcXVhbHMobmV3T2lkLCBsaXN0W2ldLmdldE9pZCgpKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiT2JqZWN0SWRlbnRpZmllcjogaW52YWxpZCBzdGF0aWMgaW5pdGlhbGl6YXRpb247ICIgKworICAgICAgICAgICAgICAgICAgICAgICAgImR1cGxpY2F0ZSBPSURzOiAiICsgb2lkLmdldE5hbWUoKSArICIgIiArIGxpc3RbaV0uZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIGNoZWNrIDogdG8gYXZvaWQgTlBFCisgICAgICAgIGlmIChpID09IChDQVBBQ0lUWSAtIDEpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIk9iamVjdElkZW50aWZpZXI6IGludmFsaWQgc3RhdGljIGluaXRpYWxpemF0aW9uOyAiICsKKyAgICAgICAgICAgICAgICAgICAgInNtYWxsIE9JRCBwb29sIGNhcGFjaXR5Iik7CisgICAgICAgIH0KKyAgICAgICAgbGlzdFtpXSA9IG9pZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGhhc2ggZm9yIGFycmF5IG9mIGludGVnZXJzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCBoYXNoSW50QXJyYXkoaW50W10gb2lkKSB7CisgICAgICAgIGludCBpbnRIYXNoID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvaWQubGVuZ3RoICYmIGkgPCA0OyBpKyspIHsKKyAgICAgICAgICAgIGludEhhc2ggKz0gb2lkW2ldIDw8ICg4ICogaSk7IC8vVE9ETyB3aGF0IGFib3V0IHRvIGZpbmQgYmV0dGVyIG9uZT8KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW50SGFzaCAmIDB4N0ZGRkZGRkY7IC8vIG9ubHkgcG9zaXRpdmUKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDEvQXR0cmlidXRlVHlwZUFuZFZhbHVlQ29tcGFyYXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTAxL0F0dHJpYnV0ZVR5cGVBbmRWYWx1ZUNvbXBhcmF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNjBjNjJkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTAxL0F0dHJpYnV0ZVR5cGVBbmRWYWx1ZUNvbXBhcmF0b3IuamF2YQpAQCAtMCwwICsxLDEwMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFYuIEVzaW4KKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwMTsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEudXRpbC5Db21wYXJhdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS51dGlscy5PYmplY3RJZGVudGlmaWVyOworCisvKioKKyAqIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZSBjb21wYXJhdG9yCisgKgorICovCitwdWJsaWMgY2xhc3MgQXR0cmlidXRlVHlwZUFuZFZhbHVlQ29tcGFyYXRvciBpbXBsZW1lbnRzIENvbXBhcmF0b3IsIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTI4NjQ3MTg0MjAwNzEwMzEzMkw7CisKKyAgICAvKioKKyAgICAgKiBjb21wYXJlcyB0d28gQXR0cmlidXRlVHlwZUFuZFZhbHVlcworICAgICAqCisgICAgICogQHBhcmFtIG9iajEKKyAgICAgKiAgICAgICAgICAgIGZpcnN0IEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZQorICAgICAqIEBwYXJhbSBvYmoyCisgICAgICogICAgICAgICAgICBzZWNvbmQgQXR0cmlidXRlVHlwZUFuZFZhbHVlCisgICAgICogQHJldHVybiAtMSBvZiBmaXJzdCBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgImxlc3MiIHRoYW4gc2Vjb25kCisgICAgICogICAgICAgICBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgMSBvdGhlcndpc2UsIDAgaWYgdGhleSBhcmUgZXF1YWwKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmUoT2JqZWN0IG9iajEsIE9iamVjdCBvYmoyKSB7CisgICAgICAgIGlmIChvYmoxID09IG9iajIpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgQXR0cmlidXRlVHlwZUFuZFZhbHVlIGF0YXYxID0gKEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZSkgb2JqMTsKKyAgICAgICAgQXR0cmlidXRlVHlwZUFuZFZhbHVlIGF0YXYyID0gKEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZSkgb2JqMjsKKyAgICAgICAgU3RyaW5nIGt3MSA9IGF0YXYxLmdldFR5cGUoKS5nZXROYW1lKCk7CisgICAgICAgIFN0cmluZyBrdzIgPSBhdGF2Mi5nZXRUeXBlKCkuZ2V0TmFtZSgpOworICAgICAgICBpZiAoa3cxICE9IG51bGwgJiYga3cyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBpZiAoa3cxID09IG51bGwgJiYga3cyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisgICAgICAgIGlmIChrdzEgIT0gbnVsbCAmJiBrdzIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGt3MS5jb21wYXJlVG8oa3cyKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjb21wYXRlT2lkcyhhdGF2MS5nZXRUeXBlKCksIGF0YXYyLmdldFR5cGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogY29tcGFyZXMgdHdvIE9iamVjdCBpZGVudGlmaWVycworICAgICAqCisgICAgICogQHBhcmFtIG9pZDEKKyAgICAgKiAgICAgICAgICAgIGZpcnN0IE9JRAorICAgICAqIEBwYXJhbSBvaWQyCisgICAgICogICAgICAgICAgICBzZWNvbmQgT0lECisgICAgICogQHJldHVybiAtMSBvZiBmaXJzdCBPSUQgImxlc3MiIHRoYW4gc2Vjb25kIE9JRCAxIG90aGVyd2lzZSwgMCBpZiB0aGV5IGFyZQorICAgICAqICAgICAgICAgZXF1YWwKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgY29tcGF0ZU9pZHMoT2JqZWN0SWRlbnRpZmllciBvaWQxLCBPYmplY3RJZGVudGlmaWVyIG9pZDIpIHsKKyAgICAgICAgaWYgKG9pZDEgPT0gb2lkMikgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBpbnRbXSBpb2lkMSA9IG9pZDEuZ2V0T2lkKCk7CisgICAgICAgIGludFtdIGlvaWQyID0gb2lkMi5nZXRPaWQoKTsKKyAgICAgICAgaW50IG1pbiA9IGlvaWQxLmxlbmd0aCA8IGlvaWQyLmxlbmd0aCA/IGlvaWQxLmxlbmd0aCA6IGlvaWQyLmxlbmd0aDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtaW47ICsraSkgeworICAgICAgICAgICAgaWYgKGlvaWQxW2ldIDwgaW9pZDJbaV0pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaW9pZDFbaV0gPiBpb2lkMltpXSkgeworICAgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKChpICsgMSkgPT0gaW9pZDEubGVuZ3RoICYmIChpICsgMSkgPCBpb2lkMi5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoKGkgKyAxKSA8IGlvaWQxLmxlbmd0aCAmJiAoaSArIDEpID09IGlvaWQyLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiAwOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwMS9BdHRyaWJ1dGVWYWx1ZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTAxL0F0dHJpYnV0ZVZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjM2OWQwZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwMS9BdHRyaWJ1dGVWYWx1ZS5qYXZhCkBAIC0wLDAgKzEsMjc5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgVi4gRXNpbgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTAxOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU3RyaW5nVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5EZXJJbnB1dFN0cmVhbTsKKworLyoqCisgKiBYLjUwMSBBdHRyaWJ1dGUgVmFsdWUKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEF0dHJpYnV0ZVZhbHVlIHsKKworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIHdhc0VuY29kZWQ7CisKKyAgICBwdWJsaWMgU3RyaW5nIGVzY2FwZWRTdHJpbmc7CisKKyAgICBwcml2YXRlIFN0cmluZyBoZXhTdHJpbmc7CisKKyAgICBwcml2YXRlIGludCB0YWcgPSAtMTsKKworICAgIHB1YmxpYyBieXRlW10gZW5jb2RlZDsKKworICAgIHB1YmxpYyBieXRlW10gYnl0ZXM7IC8vRklYTUUgcmVtb3ZlPz8/IGJ5dGVzIHRvIGJlIGVuY29kZWQKKworICAgIHB1YmxpYyBib29sZWFuIGhhc1FFOyAvLyByYXcgc3RyaW5nIGNvbnRhaW5zICciJyBvciAnXCcKKworICAgIHB1YmxpYyBTdHJpbmcgcmF3U3RyaW5nOworCisgICAgcHVibGljIEF0dHJpYnV0ZVZhbHVlKFN0cmluZyBwYXJzZWRTdHJpbmcsIGJvb2xlYW4gaGFzUW9yRSkgeworICAgICAgICB3YXNFbmNvZGVkID0gZmFsc2U7CisKKyAgICAgICAgdGhpcy5oYXNRRSA9IGhhc1FvckU7CisKKyAgICAgICAgdGhpcy5yYXdTdHJpbmcgPSBwYXJzZWRTdHJpbmc7CisgICAgICAgIHRoaXMuZXNjYXBlZFN0cmluZyA9IG1ha2VFc2NhcGVkKHJhd1N0cmluZyk7CisgICAgfQorCisgICAgcHVibGljIEF0dHJpYnV0ZVZhbHVlKFN0cmluZyBoZXhTdHJpbmcsIGJ5dGVbXSBlbmNvZGVkKSB7CisgICAgICAgIHdhc0VuY29kZWQgPSB0cnVlOworCisgICAgICAgIHRoaXMuaGV4U3RyaW5nID0gaGV4U3RyaW5nOworICAgICAgICB0aGlzLmVuY29kZWQgPSBlbmNvZGVkOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEZXJJbnB1dFN0cmVhbSBpbiA9IG5ldyBEZXJJbnB1dFN0cmVhbShlbmNvZGVkKTsKKworICAgICAgICAgICAgdGFnID0gaW4udGFnOworCisgICAgICAgICAgICBpZiAoRGlyZWN0b3J5U3RyaW5nLkFTTjEuY2hlY2tUYWcodGFnKSkgeworICAgICAgICAgICAgICAgIC8vIGhhcyBzdHJpbmcgcmVwcmVzZW50YXRpb24KKyAgICAgICAgICAgICAgICB0aGlzLnJhd1N0cmluZyA9IChTdHJpbmcpIERpcmVjdG9yeVN0cmluZy5BU04xLmRlY29kZShpbik7CisgICAgICAgICAgICAgICAgdGhpcy5lc2NhcGVkU3RyaW5nID0gbWFrZUVzY2FwZWQocmF3U3RyaW5nKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhpcy5yYXdTdHJpbmcgPSBoZXhTdHJpbmc7CisgICAgICAgICAgICAgICAgdGhpcy5lc2NhcGVkU3RyaW5nID0gaGV4U3RyaW5nOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlID0gbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOyAvL0ZJWE1FIG1lc3NhZ2UKKyAgICAgICAgICAgIGlhZS5pbml0Q2F1c2UoZSk7CisgICAgICAgICAgICB0aHJvdyBpYWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgQXR0cmlidXRlVmFsdWUoU3RyaW5nIHJhd1N0cmluZywgYnl0ZVtdIGVuY29kZWQsIGludCB0YWcpIHsKKyAgICAgICAgd2FzRW5jb2RlZCA9IHRydWU7CisKKyAgICAgICAgdGhpcy5lbmNvZGVkID0gZW5jb2RlZDsKKyAgICAgICAgdGhpcy50YWcgPSB0YWc7CisKKyAgICAgICAgaWYgKHJhd1N0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aGlzLnJhd1N0cmluZyA9IGdldEhleFN0cmluZygpOworICAgICAgICAgICAgdGhpcy5lc2NhcGVkU3RyaW5nID0gaGV4U3RyaW5nOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhpcy5yYXdTdHJpbmcgPSByYXdTdHJpbmc7CisgICAgICAgICAgICB0aGlzLmVzY2FwZWRTdHJpbmcgPSBtYWtlRXNjYXBlZChyYXdTdHJpbmcpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZSBzdHJpbmcgaXMgUHJpbnRhYmxlU3RyaW5nIChzZWUgWC42ODApCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1ByaW50YWJsZVN0cmluZyhTdHJpbmcgc3RyKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpPCBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgICAgICAgICAgY2hhciBjaCA9IHN0ci5jaGFyQXQoaSk7CisgICAgICAgICAgICBpZiAoIShjaCA9PSAweDIwCisgICAgICAgICAgICB8fCBjaCA+PSAweDI3ICYmIGNoPD0gMHgyOSAvLyAnKCkKKyAgICAgICAgICAgIHx8IGNoID49IDB4MkIgJiYgY2g8PSAweDNBIC8vICssLS4vMC05OgorICAgICAgICAgICAgfHwgY2ggPT0gJz0nCisgICAgICAgICAgICB8fCBjaCA9PSAnPycKKyAgICAgICAgICAgIHx8IGNoID49ICdBJyAmJiBjaDw9ICdaJworICAgICAgICAgICAgfHwgY2ggPj0gJ2EnICYmIGNoPD0gJ3onKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFRhZygpIHsKKyAgICAgICAgaWYgKHRhZyA9PSAtMSkgeworICAgICAgICAgICAgdGFnID0gaXNQcmludGFibGVTdHJpbmcocmF3U3RyaW5nKQorICAgICAgICAgICAgICAgICAgICA/IEFTTjFTdHJpbmdUeXBlLlBSSU5UQUJMRVNUUklORy5pZAorICAgICAgICAgICAgICAgICAgICA6IEFTTjFTdHJpbmdUeXBlLlVURjhTVFJJTkcuaWQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRhZzsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEhleFN0cmluZygpIHsKKyAgICAgICAgaWYgKGhleFN0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBpZiAoIXdhc0VuY29kZWQpIHsKKyAgICAgICAgICAgICAgICAvL0ZJWE1FIG9wdGltaXplIG1lOiB3aGF0IGFib3V0IHJldXNhYmxlIE91dHB1dFN0cmVhbT8/PworICAgICAgICAgICAgICAgIGVuY29kZWQgPSBpc1ByaW50YWJsZVN0cmluZyhyYXdTdHJpbmcpCisgICAgICAgICAgICAgICAgICAgICAgICA/IEFTTjFTdHJpbmdUeXBlLlBSSU5UQUJMRVNUUklORy5lbmNvZGUocmF3U3RyaW5nKQorICAgICAgICAgICAgICAgICAgICAgICAgOiBBU04xU3RyaW5nVHlwZS5VVEY4U1RSSU5HLmVuY29kZShyYXdTdHJpbmcpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKGVuY29kZWQubGVuZ3RoICogMiArIDEpOworICAgICAgICAgICAgYnVmLmFwcGVuZCgnIycpOworCisgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgYzsgaSA8IGVuY29kZWQubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBjID0gKGVuY29kZWRbaV0gPj4gNCkgJiAweDBGOworICAgICAgICAgICAgICAgIGlmIChjIDwgMTApIHsKKyAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgoY2hhcikgKGMgKyA0OCkpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoKGNoYXIpIChjICsgODcpKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBjID0gZW5jb2RlZFtpXSAmIDB4MEY7CisgICAgICAgICAgICAgICAgaWYgKGMgPCAxMCkgeworICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKChjaGFyKSAoYyArIDQ4KSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgoY2hhcikgKGMgKyA4NykpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGhleFN0cmluZyA9IGJ1Zi50b1N0cmluZygpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBoZXhTdHJpbmc7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYXBwZW5kUUVTdHJpbmcoU3RyaW5nQnVpbGRlciBzYikgeworICAgICAgICBzYi5hcHBlbmQoJyInKTsKKyAgICAgICAgaWYgKGhhc1FFKSB7CisgICAgICAgICAgICBjaGFyIGM7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJhd1N0cmluZy5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgYyA9IHJhd1N0cmluZy5jaGFyQXQoaSk7CisgICAgICAgICAgICAgICAgaWYgKGMgPT0gJyInIHx8IGMgPT0gJ1xcJykgeworICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoJ1xcJyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHNiLmFwcGVuZChjKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZChyYXdTdHJpbmcpOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZCgnIicpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVzY2FwZXM6CisgICAgICogMSkgY2hhcnMgIiwiLCAiKyIsICIiIiwgIlwiLCAiPCIsICI+IiwgIjsiIChSRkMgMjI1MykKKyAgICAgKiAyKSBjaGFycyAiIyIsICI9IiAocmVxdWlyZWQgYnkgUkZDIDE3NzkpCisgICAgICogMykgYSBzcGFjZSBjaGFyIGF0IHRoZSBiZWdpbm5pbmcgb3IgZW5kCisgICAgICogNCkgYWNjb3JkaW5nIHRvIHRoZSByZXF1aXJlbWVudCB0byBiZSBSRkMgMTc3OSBjb21wYXRpYmxlOgorICAgICAqICAgICcjJyBjaGFyIGlzIGVzY2FwZWQgaW4gYW55IHBvc2l0aW9uCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgbWFrZUVzY2FwZWQoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgaW50IGxlbmd0aCA9IG5hbWUubGVuZ3RoKCk7CisgICAgICAgIGlmIChsZW5ndGggPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcihsZW5ndGggKiAyKTsKKworICAgICAgICBmb3IgKGludCBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7CisgICAgICAgICAgICBjaGFyIGNoID0gbmFtZS5jaGFyQXQoaW5kZXgpOworICAgICAgICAgICAgc3dpdGNoIChjaCkgeworICAgICAgICAgICAgY2FzZSAnICc6CisgICAgICAgICAgICAgICAgaWYgKGluZGV4ID09IDAgfHwgaW5kZXggPT0gKGxlbmd0aCAtIDEpKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGVzY2FwZSBmaXJzdCBvciBsYXN0IHNwYWNlCisgICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJ1xcJyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJyAnKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSAnIic6CisgICAgICAgICAgICBjYXNlICdcXCc6CisgICAgICAgICAgICAgICAgaGFzUUUgPSB0cnVlOworICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJ1xcJyk7CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChjaCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgJywnOgorICAgICAgICAgICAgY2FzZSAnKyc6CisgICAgICAgICAgICBjYXNlICc8JzoKKyAgICAgICAgICAgIGNhc2UgJz4nOgorICAgICAgICAgICAgY2FzZSAnOyc6CisgICAgICAgICAgICBjYXNlICcjJzogLy8gcmVxdWlyZWQgYnkgUkZDIDE3NzkKKyAgICAgICAgICAgIGNhc2UgJz0nOiAvLyByZXF1aXJlZCBieSBSRkMgMTc3OQorICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJ1xcJyk7CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChjaCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChjaCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBtYWtlQ2Fub25pY2FsKCkgeworICAgICAgICBpbnQgbGVuZ3RoID0gcmF3U3RyaW5nLmxlbmd0aCgpOworICAgICAgICBpZiAobGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiByYXdTdHJpbmc7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcihsZW5ndGggKiAyKTsKKworICAgICAgICBpbnQgaW5kZXggPSAwOworICAgICAgICBpZiAocmF3U3RyaW5nLmNoYXJBdCgwKSA9PSAnIycpIHsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJ1xcJyk7CisgICAgICAgICAgICBidWYuYXBwZW5kKCcjJyk7CisgICAgICAgICAgICBpbmRleCsrOworICAgICAgICB9CisKKyAgICAgICAgaW50IGJ1Zkxlbmd0aDsKKyAgICAgICAgZm9yICg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7CisgICAgICAgICAgICBjaGFyIGNoID0gcmF3U3RyaW5nLmNoYXJBdChpbmRleCk7CisKKyAgICAgICAgICAgIHN3aXRjaCAoY2gpIHsKKyAgICAgICAgICAgIGNhc2UgJyAnOgorICAgICAgICAgICAgICAgIGJ1Zkxlbmd0aCA9IGJ1Zi5sZW5ndGgoKTsKKyAgICAgICAgICAgICAgICBpZiAoYnVmTGVuZ3RoID09IDAgfHwgYnVmLmNoYXJBdChidWZMZW5ndGggLSAxKSA9PSAnICcpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJyAnKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSAnIic6CisgICAgICAgICAgICBjYXNlICdcXCc6CisgICAgICAgICAgICBjYXNlICcsJzoKKyAgICAgICAgICAgIGNhc2UgJysnOgorICAgICAgICAgICAgY2FzZSAnPCc6CisgICAgICAgICAgICBjYXNlICc+JzoKKyAgICAgICAgICAgIGNhc2UgJzsnOgorICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJ1xcJyk7CisKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChjaCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvL3JlbW92ZSB0cmFpbGluZyBzcGFjZXMKKyAgICAgICAgZm9yIChidWZMZW5ndGggPSBidWYubGVuZ3RoKCkgLSAxOyBidWZMZW5ndGggPiAtMQorICAgICAgICAgICAgICAgICYmIGJ1Zi5jaGFyQXQoYnVmTGVuZ3RoKSA9PSAnICc7IGJ1Zkxlbmd0aC0tKSB7CisgICAgICAgIH0KKyAgICAgICAgYnVmLnNldExlbmd0aChidWZMZW5ndGggKyAxKTsKKworICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTAxL0RpcmVjdG9yeVN0cmluZy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTAxL0RpcmVjdG9yeVN0cmluZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkwMjQ0MmYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDEvRGlyZWN0b3J5U3RyaW5nLmphdmEKQEAgLTAsMCArMSw2NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTAxOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUNob2ljZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU3RyaW5nVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKKworCisvKioKKyAqIFRoZSBjbGFzcyBlbmNhcHN1bGF0ZXMgdGhlIEFTTi4xIERFUiBlbmNvZGluZy9kZWNvZGluZyB3b3JrCisgKiB3aXRoIHRoZSBEaXJlY3RvcnlTdHJpbmcgc3RydWN0dXJlCisgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIC0KKyAqICBJbnRlcm5ldCBYLjUwOSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgorICogIENlcnRpZmljYXRlIGFuZCBDZXJ0aWZpY2F0ZSBSZXZvY2F0aW9uIExpc3QgKENSTCkgUHJvZmlsZS4KKyAqICBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCk6CisgKgorICogPHByZT4KKyAqICAgRGlyZWN0b3J5U3RyaW5nIDo6PSBDSE9JQ0UgeworICogICAgICAgIHRlbGV0ZXhTdHJpbmcgICAgICAgICAgICAgVGVsZXRleFN0cmluZyAgIChTSVpFICgxLi5NQVgpKSwKKyAqICAgICAgICBwcmludGFibGVTdHJpbmcgICAgICAgICAgIFByaW50YWJsZVN0cmluZyAoU0laRSAoMS4uTUFYKSksCisgKiAgICAgICAgdW5pdmVyc2FsU3RyaW5nICAgICAgICAgICBVbml2ZXJzYWxTdHJpbmcgKFNJWkUgKDEuLk1BWCkpLAorICogICAgICAgIHV0ZjhTdHJpbmcgICAgICAgICAgICAgIFVURjhTdHJpbmcgICAgICAoU0laRSAoMS4uTUFYKSksCisgKiAgICAgICAgYm1wU3RyaW5nICAgICAgICAgICAgICAgQk1QU3RyaW5nICAgICAgIChTSVpFICgxLi5NQVgpKQorICogICB9CisgKiA8L3ByZT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIERpcmVjdG9yeVN0cmluZyB7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFDaG9pY2UgQVNOMSA9IG5ldyBBU04xQ2hvaWNlKG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgQVNOMVN0cmluZ1R5cGUuVEVMRVRFWFNUUklORywKKyAgICAgICAgICAgQVNOMVN0cmluZ1R5cGUuUFJJTlRBQkxFU1RSSU5HLAorICAgICAgICAgICBBU04xU3RyaW5nVHlwZS5VTklWRVJTQUxTVFJJTkcsCisgICAgICAgICAgIEFTTjFTdHJpbmdUeXBlLlVURjhTVFJJTkcsCisgICAgICAgICAgIEFTTjFTdHJpbmdUeXBlLkJNUFNUUklORyB9KSB7CisKKyAgICAgICAgcHVibGljIGludCBnZXRJbmRleChqYXZhLmxhbmcuT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIDE7IC8vIGFsd2F5cyBjb2RlIGFzIEFTTjEgcHJpbnRhYmxlU3RyaW5nCisgICAgICAgICAgICAvL3JldHVybiA0OyAvLyBhbHdheXMgY29kZSBhcyBBU04xIHV0ZjhTdHJpbmcKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0T2JqZWN0VG9FbmNvZGUoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuIC8qKFN0cmluZykqLyBvYmplY3Q7CisgICAgICAgIH0KKyAgICB9OworfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDEvTmFtZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTAxL05hbWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42Mjk4NjRiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTAxL05hbWUuamF2YQpAQCAtMCwwICsxLDI0OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFYuIEVzaW4KKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwMTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlT2Y7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNldE9mOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkRlcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LkROUGFyc2VyOworCisKKy8qKgorICogWC41MDEgTmFtZQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTmFtZSB7CisKKyAgICAvKiogQVNOLjEgREVSIGVuY29kaW5nIG9mIE5hbWUgKi8KKyAgICBwcml2YXRlIHZvbGF0aWxlIGJ5dGVbXSBlbmNvZGVkOworCisgICAgLyoqIFJGQzE3Nzkgc3RyaW5nICovCisgICAgcHJpdmF0ZSBTdHJpbmcgcmZjMTc3OVN0cmluZzsKKworICAgIC8qKiBSRkMyMjUzIHN0cmluZyAqLworICAgIHByaXZhdGUgU3RyaW5nIHJmYzIyNTNTdHJpbmc7CisKKyAgICAvKiogQ0FOT05JQ0FMIHN0cmluZyAqLworICAgIHByaXZhdGUgU3RyaW5nIGNhbm9uaWNhbFN0cmluZzsKKworICAgIC8qKiBDb2xsZWN0aW9uIG9mIFJETnMgKi8KKyAgICBwcml2YXRlIExpc3Q8TGlzdDxBdHRyaWJ1dGVUeXBlQW5kVmFsdWU+PiByZG47CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIG5ldyA8Y29kZT5OYW1lPC9jb2RlPiBpbnN0YW5jZSBmcm9tIGl0cyBERVIgZW5jb2RpbmcKKyAgICAgKgorICAgICAqIEBwYXJhbSBlbmNvZGluZyAtIEFTTi4xIERFUiBlbmNvZGluZworICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gLSBpZiBlbmNvZGluZyBpcyB3cm9uZworICAgICAqLworICAgIHB1YmxpYyBOYW1lKGJ5dGVbXSBlbmNvZGluZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgRGVySW5wdXRTdHJlYW0gaW4gPSBuZXcgRGVySW5wdXRTdHJlYW0oZW5jb2RpbmcpOworCisgICAgICAgIGlmIChpbi5nZXRFbmRPZmZzZXQoKSAhPSBlbmNvZGluZy5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiV3JvbmcgY29udGVudCBsZW5ndGgiKTsKKyAgICAgICAgfQorCisgICAgICAgIEFTTjEuZGVjb2RlKGluKTsKKworICAgICAgICB0aGlzLnJkbiA9IChMaXN0PExpc3Q8QXR0cmlidXRlVHlwZUFuZFZhbHVlPj4pIGluLmNvbnRlbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBuZXcgPGNvZGU+TmFtZTwvY29kZT4gaW5zdGFuY2UKKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIC0gTmFtZSBhcyBTdHJpbmcKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIC0gaWYgc3RyaW5nIGlzIHdyb25nCisgICAgICovCisgICAgcHVibGljIE5hbWUoU3RyaW5nIG5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJkbiA9IG5ldyBETlBhcnNlcihuYW1lKS5wYXJzZSgpOworICAgIH0KKworICAgIHByaXZhdGUgTmFtZShMaXN0PExpc3Q8QXR0cmlidXRlVHlwZUFuZFZhbHVlPj4gcmRuKSB7CisgICAgICAgIHRoaXMucmRuID0gcmRuOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgPGNvZGU+WDUwMFByaW5jaXBhbDwvY29kZT4gaW5zdGFuY2UgY29ycmVzcG9uZGluZyB0byB0aGlzCisgICAgICogPGNvZGU+TmFtZTwvY29kZT4gaW5zdGFuY2UKKyAgICAgKgorICAgICAqIEByZXR1cm4gZXF1aXZhbGVudCBYNTAwUHJpbmNpcGFsIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBYNTAwUHJpbmNpcGFsIGdldFg1MDBQcmluY2lwYWwoKXsKKyAgICAgICAgcmV0dXJuIG5ldyBYNTAwUHJpbmNpcGFsKGdldEVuY29kZWQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBSZWxhdGl2ZSBEaXN0aW5ndWlzaGVkIE5hbWUgYXMgPGNvZGU+U3RyaW5nPC9jb2RlPiBhY2NvcmRpbmcKKyAgICAgKiB0aGUgZm9ybWF0IHJlcXVlc3RlZAorICAgICAqCisgICAgICogQHBhcmFtIGZvcm1hdCBvbmUgb2YgWDUwMFByaW5jaXBhbC5DQU5PTklDQUwsIFg1MDBQcmluY2lwYWwuUkZDMTc3OSwgb3IKKyAgICAgKiAgICAgWDUwMFByaW5jaXBhbC5SRkMyMjUzLCBjYXNlIGluc2Vuc2l0aXZlCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKFN0cmluZyBmb3JtYXQpIHsKKyAgICAgICAgLy8KKyAgICAgICAgLy8gY2hlY2sgWDUwMFByaW5jaXBhbCBjb25zdGFudHMgZmlyc3QKKyAgICAgICAgLy8KKyAgICAgICAgaWYgKFg1MDBQcmluY2lwYWwuUkZDMTc3OS5lcXVhbHMoZm9ybWF0KSkgeworCisgICAgICAgICAgICBpZiAocmZjMTc3OVN0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmZjMTc3OVN0cmluZyA9IGdldE5hbWUwKGZvcm1hdCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmZjMTc3OVN0cmluZzsKKworICAgICAgICB9IGVsc2UgaWYgKFg1MDBQcmluY2lwYWwuUkZDMjI1My5lcXVhbHMoZm9ybWF0KSkgeworCisgICAgICAgICAgICBpZiAocmZjMjI1M1N0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmZjMjI1M1N0cmluZyA9IGdldE5hbWUwKGZvcm1hdCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmZjMjI1M1N0cmluZzsKKworICAgICAgICB9IGVsc2UgaWYgKFg1MDBQcmluY2lwYWwuQ0FOT05JQ0FMLmVxdWFscyhmb3JtYXQpKSB7CisKKyAgICAgICAgICAgIGlmIChjYW5vbmljYWxTdHJpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGNhbm9uaWNhbFN0cmluZyA9IGdldE5hbWUwKGZvcm1hdCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gY2Fub25pY2FsU3RyaW5nOworCisgICAgICAgIH0KKyAgICAgICAgLy8KKyAgICAgICAgLy8gY29tcGFyZSBpZ25vcmUgY2FzZQorICAgICAgICAvLworICAgICAgICBlbHNlIGlmIChYNTAwUHJpbmNpcGFsLlJGQzE3NzkuZXF1YWxzSWdub3JlQ2FzZShmb3JtYXQpKSB7CisKKyAgICAgICAgICAgIGlmIChyZmMxNzc5U3RyaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZmMxNzc5U3RyaW5nID0gZ2V0TmFtZTAoWDUwMFByaW5jaXBhbC5SRkMxNzc5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiByZmMxNzc5U3RyaW5nOworCisgICAgICAgIH0gZWxzZSBpZiAoWDUwMFByaW5jaXBhbC5SRkMyMjUzLmVxdWFsc0lnbm9yZUNhc2UoZm9ybWF0KSkgeworCisgICAgICAgICAgICBpZiAocmZjMjI1M1N0cmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmZjMjI1M1N0cmluZyA9IGdldE5hbWUwKFg1MDBQcmluY2lwYWwuUkZDMjI1Myk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmZjMjI1M1N0cmluZzsKKworICAgICAgICB9IGVsc2UgaWYgKFg1MDBQcmluY2lwYWwuQ0FOT05JQ0FMLmVxdWFsc0lnbm9yZUNhc2UoZm9ybWF0KSkgeworCisgICAgICAgICAgICBpZiAoY2Fub25pY2FsU3RyaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjYW5vbmljYWxTdHJpbmcgPSBnZXROYW1lMChYNTAwUHJpbmNpcGFsLkNBTk9OSUNBTCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gY2Fub25pY2FsU3RyaW5nOworCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbGxlZ2FsIGZvcm1hdDogIiArIGZvcm1hdCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIFJlbGF0aXZlIERpc3Rpbmd1aXNoZWQgTmFtZSBhcyA8Y29kZT5TdHJpbmc8L2NvZGU+IGFjY29yZGluZworICAgICAqIHRoZSBmb3JtYXQgcmVxdWVzdGVkLCBmb3JtYXQgaXMgaW50IHZhbHVlCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0TmFtZTAoU3RyaW5nIGZvcm1hdCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIG5hbWUgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCisgICAgICAgIC8vIHN0YXJ0aW5nIHdpdGggdGhlIGxhc3QgZWxlbWVudCBhbmQgbW92aW5nIHRvIHRoZSBmaXJzdC4KKyAgICAgICAgZm9yIChpbnQgaSA9IHJkbi5zaXplKCkgLSAxOyBpID49IDA7IGktLSkgeworICAgICAgICAgICAgTGlzdDxBdHRyaWJ1dGVUeXBlQW5kVmFsdWU+IGF0YXZMaXN0ID0gcmRuLmdldChpKTsKKworICAgICAgICAgICAgaWYgKFg1MDBQcmluY2lwYWwuQ0FOT05JQ0FMID09IGZvcm1hdCkgeworICAgICAgICAgICAgICAgIGF0YXZMaXN0ID0gbmV3IEFycmF5TGlzdDxBdHRyaWJ1dGVUeXBlQW5kVmFsdWU+KGF0YXZMaXN0KTsKKyAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy5zb3J0KGF0YXZMaXN0LCBuZXcgQXR0cmlidXRlVHlwZUFuZFZhbHVlQ29tcGFyYXRvcigpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gUmVsYXRpdmUgRGlzdGluZ3Vpc2hlZCBOYW1lIHRvIHN0cmluZworICAgICAgICAgICAgSXRlcmF0b3I8QXR0cmlidXRlVHlwZUFuZFZhbHVlPiBpdCA9IGF0YXZMaXN0Lml0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgQXR0cmlidXRlVHlwZUFuZFZhbHVlIGF0dHJpYnV0ZVR5cGVBbmRWYWx1ZSA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgICAgICBhdHRyaWJ1dGVUeXBlQW5kVmFsdWUuYXBwZW5kTmFtZShmb3JtYXQsIG5hbWUpOworICAgICAgICAgICAgICAgIGlmIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gbXVsdGktdmFsdWVkIFJETgorICAgICAgICAgICAgICAgICAgICBpZiAoWDUwMFByaW5jaXBhbC5SRkMxNzc5ID09IGZvcm1hdCkgeworICAgICAgICAgICAgICAgICAgICAgICAgbmFtZS5hcHBlbmQoIiArICIpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgbmFtZS5hcHBlbmQoJysnKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGkgIT0gMCkgeworICAgICAgICAgICAgICAgIG5hbWUuYXBwZW5kKCcsJyk7CisgICAgICAgICAgICAgICAgaWYgKGZvcm1hdCA9PSBYNTAwUHJpbmNpcGFsLlJGQzE3NzkpIHsKKyAgICAgICAgICAgICAgICAgICAgbmFtZS5hcHBlbmQoJyAnKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgc05hbWUgPSBuYW1lLnRvU3RyaW5nKCk7CisgICAgICAgIGlmIChYNTAwUHJpbmNpcGFsLkNBTk9OSUNBTC5lcXVhbHMoZm9ybWF0KSkgeworICAgICAgICAgICAgc05hbWUgPSBzTmFtZS50b0xvd2VyQ2FzZShMb2NhbGUuVVMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGVuY29kZWQgZm9ybSBvZiBETgorICAgICAqCisgICAgICogQHJldHVybiByZXR1cm4gZW5jb2RpbmcsIG5vIGNvcHlpbmcgaXMgcGVyZm9ybWVkCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICBpZiAoZW5jb2RlZCA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGVkID0gQVNOMS5lbmNvZGUodGhpcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVuY29kZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWNjb3JkaW5nIHRvIFJGQyAzMjgwIChodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCkKKyAgICAgKiBYLjUwMSBOYW1lIHN0cnVjdHVyZSBpcyBkZWZpbmVkIGFzIGZvbGxvd3M6CisgICAgICoKKyAgICAgKiBOYW1lIDo6PSBDSE9JQ0UgeworICAgICAqICAgICBSRE5TZXF1ZW5jZSB9CisgICAgICoKKyAgICAgKiBSRE5TZXF1ZW5jZSA6Oj0gU0VRVUVOQ0UgT0YgUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZQorICAgICAqCisgICAgICogUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZSA6Oj0KKyAgICAgKiAgICAgU0VUIE9GIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZQorICAgICAqCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xU2V0T2YgQVNOMV9SRE4gPSBuZXcgQVNOMVNldE9mKAorICAgICAgICAgICAgQXR0cmlidXRlVHlwZUFuZFZhbHVlLkFTTjEpOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xU2VxdWVuY2VPZiBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZU9mKEFTTjFfUkROKSB7CisKKyAgICAgICAgcHVibGljIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IE5hbWUoKExpc3Q8TGlzdDxBdHRyaWJ1dGVUeXBlQW5kVmFsdWU+PikgaW4uY29udGVudCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgQ29sbGVjdGlvbiBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuICgoTmFtZSkgb2JqZWN0KS5yZG47CisgICAgICAgIH0KKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0FjY2Vzc0Rlc2NyaXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvQWNjZXNzRGVzY3JpcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZjJmZTZkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0FjY2Vzc0Rlc2NyaXB0aW9uLmphdmEKQEAgLTAsMCArMSw5NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFPaWQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLk9iamVjdElkZW50aWZpZXI7CisKKy8qKgorICogVGhlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgQVNOLjEgREVSIGVuY29kaW5nL2RlY29kaW5nIHdvcmsKKyAqIHdpdGggdGhlIEFjY2Vzc0Rlc2NyaXB0aW9uIHdoaWNoIGlzIGEgcGFydCBvZiBYLjUwOSBmcmFtZXdvcmsKKyAqIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODAgLQorICogIEludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUuCisgKiAgQ2VydGlmaWNhdGUgYW5kIENlcnRpZmljYXRlIFJldm9jYXRpb24gTGlzdCAoQ1JMKSBQcm9maWxlLgorICogIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KToKKyAqCisgKiAgQWNjZXNzRGVzY3JpcHRpb24gIDo6PSAgU0VRVUVOQ0UgeworICogICAgICBhY2Nlc3NNZXRob2QgICAgICAgICAgT0JKRUNUIElERU5USUZJRVIsCisgKiAgICAgIGFjY2Vzc0xvY2F0aW9uICAgICAgICBHZW5lcmFsTmFtZSAgfQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQWNjZXNzRGVzY3JpcHRpb24geworCisgICAgLyoqIHRoZSB2YWx1ZSBvZiBhY2Nlc3MgbWV0aG9kICovCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgYWNjZXNzTWV0aG9kOworCisgICAgLyoqIHRoZSB2YWx1ZSBvZiBhY2Nlc3NMb2NhdGlvbiAqLworICAgIHByaXZhdGUgZmluYWwgR2VuZXJhbE5hbWUgYWNjZXNzTG9jYXRpb247CisKKyAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGluZzsKKworICAgIHByaXZhdGUgQWNjZXNzRGVzY3JpcHRpb24oU3RyaW5nIGFjY2Vzc01ldGhvZCwgR2VuZXJhbE5hbWUgYWNjZXNzTG9jYXRpb24sIGJ5dGVbXSBlbmNvZGluZykgeworICAgICAgICB0aGlzLmFjY2Vzc01ldGhvZCA9IGFjY2Vzc01ldGhvZDsKKyAgICAgICAgdGhpcy5hY2Nlc3NMb2NhdGlvbiA9IGFjY2Vzc0xvY2F0aW9uOworICAgICAgICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBlbmNvZGVkIGZvcm0gb2YgdGhpcyBYLjUwOSBBY2Nlc3NEZXNjcmlwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXMgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICByZXMuYXBwZW5kKCJcbi0tIEFjY2Vzc0Rlc2NyaXB0aW9uOiIpOworICAgICAgICByZXMuYXBwZW5kKCJcbmFjY2Vzc01ldGhvZDogICIpOworICAgICAgICByZXMuYXBwZW5kKGFjY2Vzc01ldGhvZCk7CisgICAgICAgIHJlcy5hcHBlbmQoIlxuYWNjZXNzTG9jYXRpb246ICAiKTsKKyAgICAgICAgcmVzLmFwcGVuZChhY2Nlc3NMb2NhdGlvbik7CisgICAgICAgIHJlcy5hcHBlbmQoIlxuLS0gQWNjZXNzRGVzY3JpcHRpb24gRU5EXG4iKTsKKyAgICAgICAgcmV0dXJuIHJlcy50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEN1c3RvbSBBY2Nlc3NEZXNjcmlwdGlvbiBERVIgZW5jb2Rlci9kZWNvZGVyCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xU2VxdWVuY2UgQVNOMSA9IG5ldyBBU04xU2VxdWVuY2UobmV3IEFTTjFUeXBlW10geworICAgICAgICAgICAgQVNOMU9pZC5nZXRJbnN0YW5jZSgpLAorICAgICAgICAgICAgR2VuZXJhbE5hbWUuQVNOMSB9KSB7CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgT2JqZWN0W10gdmFsdWVzID0gKE9iamVjdFtdKSBpbi5jb250ZW50OworICAgICAgICAgICAgcmV0dXJuIG5ldyBBY2Nlc3NEZXNjcmlwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgT2JqZWN0SWRlbnRpZmllci50b1N0cmluZygoaW50W10pIHZhbHVlc1swXSksCisgICAgICAgICAgICAgICAgICAgIChHZW5lcmFsTmFtZSkgdmFsdWVzWzFdLCBpbi5nZXRFbmNvZGVkKCkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKyAgICAgICAgICAgIEFjY2Vzc0Rlc2NyaXB0aW9uIGFkID0gKEFjY2Vzc0Rlc2NyaXB0aW9uKSBvYmplY3Q7CisgICAgICAgICAgICB2YWx1ZXNbMF0gPSBPYmplY3RJZGVudGlmaWVyLnRvSW50QXJyYXkoYWQuYWNjZXNzTWV0aG9kKTsKKyAgICAgICAgICAgIHZhbHVlc1sxXSA9IGFkLmFjY2Vzc0xvY2F0aW9uOworICAgICAgICB9CisgICAgfTsKK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0FsZ29yaXRobUlkZW50aWZpZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9BbGdvcml0aG1JZGVudGlmaWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWFiMTJlNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9BbGdvcml0aG1JZGVudGlmaWVyLmphdmEKQEAgLTAsMCArMSwxNjIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUFueTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xT2lkOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXF1ZW5jZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5PYmplY3RJZGVudGlmaWVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS51dGlscy5BbGdOYW1lTWFwcGVyOworCisKKy8qKgorICogVGhlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgQVNOLjEgREVSIGVuY29kaW5nL2RlY29kaW5nIHdvcmsKKyAqIHdpdGggdGhlIEFsZ29yaXRobSBJZGVudGlmaWVyIHdoaWNoIGlzIGEgcGFydCBvZiBYLjUwOSBjZXJ0aWZpY2F0ZQorICogKGFzIHNwZWNpZmllZCBpbiBSRkMgMzI4MCAtCisgKiAgSW50ZXJuZXQgWC41MDkgUHVibGljIEtleSBJbmZyYXN0cnVjdHVyZS4KKyAqICBDZXJ0aWZpY2F0ZSBhbmQgQ2VydGlmaWNhdGUgUmV2b2NhdGlvbiBMaXN0IChDUkwpIFByb2ZpbGUuCisgKiAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpOgorICoKKyAqIDxwcmU+CisgKiAgQWxnb3JpdGhtSWRlbnRpZmllciA6Oj0gU0VRVUVOQ0UgeworICogICAgICBhbGdvcml0aG0gT0JKRUNUIElERU5USUZJRVIsCisgKiAgICAgIHBhcmFtZXRlcnMgQU5ZIERFRklORUQgQlkgYWxnb3JpdGhtIE9QVElPTkFMCisgKiAgfQorICogPC9wcmU+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBBbGdvcml0aG1JZGVudGlmaWVyIHsKKyAgICAvKiogdGhlIHZhbHVlIG9mIGFsZ29yaXRobSBmaWVsZCAqLworICAgIHByaXZhdGUgU3RyaW5nIGFsZ29yaXRobTsKKyAgICAvKiogdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobSAqLworICAgIHByaXZhdGUgU3RyaW5nIGFsZ29yaXRobU5hbWU7CisgICAgLyoqIHRoZSB2YWx1ZSBvZiBwYXJhbWV0ZXJzIGZpZWxkICovCisgICAgcHJpdmF0ZSBieXRlW10gcGFyYW1ldGVyczsKKyAgICAvKiogdGhlIGVuY29kaW5nIG9mIEFsZ29yaXRobUlkZW50aWZpZXIgdmFsdWUgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGluZzsKKworICAgIHB1YmxpYyBBbGdvcml0aG1JZGVudGlmaWVyKFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgdGhpcyhhbGdvcml0aG0sIG51bGwsIG51bGwpOworICAgIH0KKworICAgIHB1YmxpYyBBbGdvcml0aG1JZGVudGlmaWVyKFN0cmluZyBhbGdvcml0aG0sIGJ5dGVbXSBwYXJhbWV0ZXJzKSB7CisgICAgICAgIHRoaXMoYWxnb3JpdGhtLCBwYXJhbWV0ZXJzLCBudWxsKTsKKyAgICB9CisKKyAgICBwcml2YXRlIEFsZ29yaXRobUlkZW50aWZpZXIoU3RyaW5nIGFsZ29yaXRobSwgYnl0ZVtdIHBhcmFtZXRlcnMsIGJ5dGVbXSBlbmNvZGluZykgeworICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICAgICAgdGhpcy5wYXJhbWV0ZXJzID0gcGFyYW1ldGVyczsKKyAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGFsZ29yaXRobSBmaWVsZCBvZiB0aGUgc3RydWN0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICByZXR1cm4gYWxnb3JpdGhtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobSBjb3JyZXNwb25kaW5nIHRvCisgICAgICogaXRzIE9JRC4gSWYgdGhlcmUgaXMgbm8gdGhlIHN1Y2ggY29ycmVzcG9uZGVuY2UsCisgICAgICogYWxnb3JpdGhtIE9JRCBpcyByZXR1cm5lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobU5hbWUoKSB7CisgICAgICAgIGlmIChhbGdvcml0aG1OYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIGFsZ29yaXRobU5hbWUgPSBBbGdOYW1lTWFwcGVyLm1hcDJBbGdOYW1lKGFsZ29yaXRobSk7CisgICAgICAgICAgICBpZiAoYWxnb3JpdGhtTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgYWxnb3JpdGhtTmFtZSA9IGFsZ29yaXRobTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYWxnb3JpdGhtTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBwYXJhbWV0ZXJzIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRQYXJhbWV0ZXJzKCkgeworICAgICAgICByZXR1cm4gcGFyYW1ldGVyczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFTTi4xIGVuY29kZWQgZm9ybSBvZiB0aGlzIFguNTA5IEFsZ29yaXRobUlkZW50aWZpZXIgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSBBU04xLmVuY29kZSh0aGlzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgYWkpIHsKKyAgICAgICAgaWYgKCEoYWkgaW5zdGFuY2VvZiBBbGdvcml0aG1JZGVudGlmaWVyKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIgYWxnaWQgPSAoQWxnb3JpdGhtSWRlbnRpZmllcikgYWk7CisgICAgICAgIHJldHVybiAoYWxnb3JpdGhtLmVxdWFscyhhbGdpZC5hbGdvcml0aG0pKQorICAgICAgICAgICAgJiYgKChwYXJhbWV0ZXJzID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgID8gYWxnaWQucGFyYW1ldGVycyA9PSBudWxsCisgICAgICAgICAgICAgICAgICAgIDogQXJyYXlzLmVxdWFscyhwYXJhbWV0ZXJzLCBhbGdpZC5wYXJhbWV0ZXJzKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiBhbGdvcml0aG0uaGFzaENvZGUoKSAqIDM3ICsgKHBhcmFtZXRlcnMgIT0gbnVsbCA/IEFycmF5cy5oYXNoQ29kZShwYXJhbWV0ZXJzKSA6IDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGR1bXBWYWx1ZShTdHJpbmdCdWlsZGVyIHNiKSB7CisgICAgICAgIHNiLmFwcGVuZChnZXRBbGdvcml0aG1OYW1lKCkpOworICAgICAgICBpZiAocGFyYW1ldGVycyA9PSBudWxsKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIiwgbm8gcGFyYW1zLCAiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiLCBwYXJhbXMgdW5wYXJzZWQsICIpOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZCgiT0lEID0gIik7CisgICAgICAgIHNiLmFwcGVuZChnZXRBbGdvcml0aG0oKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3VzdG9tIEFsZ29yaXRobUlkZW50aWZpZXIgREVSIGVuY29kZXIvZGVjb2RlcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVNlcXVlbmNlIEFTTjEgPSBuZXcgQVNOMVNlcXVlbmNlKG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgIEFTTjFPaWQuZ2V0SW5zdGFuY2UoKSwgQVNOMUFueS5nZXRJbnN0YW5jZSgpIH0pIHsKKyAgICAgICAgeworICAgICAgICAgICAgc2V0T3B0aW9uYWwoMSk7IC8vIHBhcmFtZXRlcnMgYXJlIG9wdGlvbmFsCisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB7CisgICAgICAgICAgICBPYmplY3RbXSB2YWx1ZXMgPSAoT2JqZWN0W10pIGluLmNvbnRlbnQ7CisgICAgICAgICAgICByZXR1cm4gbmV3IEFsZ29yaXRobUlkZW50aWZpZXIoT2JqZWN0SWRlbnRpZmllcgorICAgICAgICAgICAgICAgICAgICAudG9TdHJpbmcoKGludFtdKSB2YWx1ZXNbMF0pLCAoYnl0ZVtdKSB2YWx1ZXNbMV0pOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKworICAgICAgICAgICAgQWxnb3JpdGhtSWRlbnRpZmllciBhSUQgPSAoQWxnb3JpdGhtSWRlbnRpZmllcikgb2JqZWN0OworCisgICAgICAgICAgICB2YWx1ZXNbMF0gPSBPYmplY3RJZGVudGlmaWVyLnRvSW50QXJyYXkoYUlELmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgICAgIHZhbHVlc1sxXSA9IGFJRC5nZXRQYXJhbWV0ZXJzKCk7CisgICAgICAgIH0KKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0FsdGVybmF0aXZlTmFtZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0FsdGVybmF0aXZlTmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY0NmU3ZDAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvQWx0ZXJuYXRpdmVOYW1lLmphdmEKQEAgLTAsMCArMSw2NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSB2YWx1ZXMgb2YgU3ViamVjdCBBbHRlcm5hdGl2ZSBOYW1lCisgKiAoT0lEIGlzIDIuNS4yOS4xNykgYW5kIElzc3VlciBBbHRlcm5hdGl2ZSBOYW1lIGV4dGVuc2lvbnMKKyAqIChPSUQgaXMgMi41LjI5LjE4KS48YnI+CisgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGVzZSBleHRlbnNpb25zIHNlZSBSRkMgMzI4MAorICogYXQgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEFsdGVybmF0aXZlTmFtZSBleHRlbmRzIEV4dGVuc2lvblZhbHVlIHsKKworICAgIC8vIGNvbnN0YW50cyBpbmRpY2F0aW5nIHdoaWNoIGFsdGVybmF0aXZlIG5hbWUgaXMgcHJlc2VudGVkCisgICAgLy8gYnkgdGhpcyBvYmplY3QKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJvb2xlYW4gSVNTVUVSID0gZmFsc2U7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBib29sZWFuIFNVQkpFQ1QgPSB0cnVlOworCisgICAgLyoqIGluZGljYXRpbmcgd2hpY2ggYWx0ZXJuYXRpdmUgbmFtZSBpcyBwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3QgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gd2hpY2g7CisgICAgLyoqIHRoZSBhbHRlcm5hdGl2ZSBuYW1lcyAqLworICAgIHByaXZhdGUgR2VuZXJhbE5hbWVzIGFsdGVybmF0aXZlTmFtZXM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBleHRlbnNpb24gb2JqZWN0IG9uIHRoZSBiYXNlIG9mIGl0cyBlbmNvZGVkIGZvcm0uCisgICAgICogQHBhcmFtIHdoaWNoIHNwZWNpZmllcyB3aGljaCBhbHRlcm5hdGl2ZSBuYW1lcyBhcmUgZ2l2ZW4KKyAgICAgKiAoU3ViamVjdCdzIG9yIElzc3VlcidzKQorICAgICAqLworICAgIHB1YmxpYyBBbHRlcm5hdGl2ZU5hbWUoYm9vbGVhbiB3aGljaCwgYnl0ZVtdIGVuY29kaW5nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihlbmNvZGluZyk7CisgICAgICAgIHRoaXMud2hpY2ggPSB3aGljaDsKKyAgICAgICAgdGhpcy5hbHRlcm5hdGl2ZU5hbWVzID0gKEdlbmVyYWxOYW1lcykgR2VuZXJhbE5hbWVzLkFTTjEuZGVjb2RlKGVuY29kaW5nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFTTi4xIGVuY29kZWQgZm9ybSBvZiB0aGlzIFguNTA5IEFsdGVybmF0aXZlTmFtZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSBHZW5lcmFsTmFtZXMuQVNOMS5lbmNvZGUoYWx0ZXJuYXRpdmVOYW1lcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVuY29kaW5nOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBkdW1wVmFsdWUoU3RyaW5nQnVpbGRlciBzYiwgU3RyaW5nIHByZWZpeCkgeworICAgICAgICBzYi5hcHBlbmQocHJlZml4KS5hcHBlbmQoKHdoaWNoKSA/ICJTdWJqZWN0IiA6ICJJc3N1ZXIiKS5hcHBlbmQoIiBBbHRlcm5hdGl2ZSBOYW1lcyBbXG4iKTsKKyAgICAgICAgYWx0ZXJuYXRpdmVOYW1lcy5kdW1wVmFsdWUoc2IsIHByZWZpeCArICIgICIpOworICAgICAgICBzYi5hcHBlbmQocHJlZml4KS5hcHBlbmQoIl1cbiIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9BdXRob3JpdHlLZXlJZGVudGlmaWVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvQXV0aG9yaXR5S2V5SWRlbnRpZmllci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJlNDNiYTcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvQXV0aG9yaXR5S2V5SWRlbnRpZmllci5qYXZhCkBAIC0wLDAgKzEsMTMyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFJbXBsaWNpdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xSW50ZWdlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xT2N0ZXRTdHJpbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS51dGlscy5BcnJheTsKKworLyoqCisgKiBUaGUgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBBU04uMSBERVIgZW5jb2RpbmcvZGVjb2Rpbmcgd29yaworICogd2l0aCBBdXRob3JpdHkgS2V5IElkZW50aWZpZXIgRXh0ZW5zaW9uIChPSUQgPSAyLjUuMjkuMzUpLgorICogKGFzIHNwZWNpZmllZCBpbiBSRkMgMzI4MCAtCisgKiAgSW50ZXJuZXQgWC41MDkgUHVibGljIEtleSBJbmZyYXN0cnVjdHVyZS4KKyAqICBDZXJ0aWZpY2F0ZSBhbmQgQ2VydGlmaWNhdGUgUmV2b2NhdGlvbiBMaXN0IChDUkwpIFByb2ZpbGUuCisgKiAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpOgorICoKKyAqIDxwcmU+CisgKiAgIGlkLWNlLWF1dGhvcml0eUtleUlkZW50aWZpZXIgT0JKRUNUIElERU5USUZJRVIgOjo9ICB7IGlkLWNlIDM1IH0KKyAqCisgKiAgIEF1dGhvcml0eUtleUlkZW50aWZpZXIgOjo9IFNFUVVFTkNFIHsKKyAqICAgICAga2V5SWRlbnRpZmllciAgICAgICAgICAgICBbMF0gS2V5SWRlbnRpZmllciAgICAgICAgICAgT1BUSU9OQUwsCisgKiAgICAgIGF1dGhvcml0eUNlcnRJc3N1ZXIgICAgICAgWzFdIEdlbmVyYWxOYW1lcyAgICAgICAgICAgIE9QVElPTkFMLAorICogICAgICBhdXRob3JpdHlDZXJ0U2VyaWFsTnVtYmVyIFsyXSBDZXJ0aWZpY2F0ZVNlcmlhbE51bWJlciBPUFRJT05BTCAgfQorICoKKyAqICAgS2V5SWRlbnRpZmllciA6Oj0gT0NURVQgU1RSSU5HCisgKiA8L3ByZT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEF1dGhvcml0eUtleUlkZW50aWZpZXIgZXh0ZW5kcyBFeHRlbnNpb25WYWx1ZSB7CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10ga2V5SWRlbnRpZmllcjsKKyAgICBwcml2YXRlIGZpbmFsIEdlbmVyYWxOYW1lcyBhdXRob3JpdHlDZXJ0SXNzdWVyOworICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBhdXRob3JpdHlDZXJ0U2VyaWFsTnVtYmVyOworCisgICAgcHVibGljIEF1dGhvcml0eUtleUlkZW50aWZpZXIoYnl0ZVtdIGtleUlkZW50aWZpZXIsCisgICAgICAgICAgICBHZW5lcmFsTmFtZXMgYXV0aG9yaXR5Q2VydElzc3VlciwKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgYXV0aG9yaXR5Q2VydFNlcmlhbE51bWJlcikgeworICAgICAgICB0aGlzLmtleUlkZW50aWZpZXIgPSBrZXlJZGVudGlmaWVyOworICAgICAgICB0aGlzLmF1dGhvcml0eUNlcnRJc3N1ZXIgPSBhdXRob3JpdHlDZXJ0SXNzdWVyOworICAgICAgICB0aGlzLmF1dGhvcml0eUNlcnRTZXJpYWxOdW1iZXIgPSBhdXRob3JpdHlDZXJ0U2VyaWFsTnVtYmVyOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgQXV0aG9yaXR5S2V5SWRlbnRpZmllciBkZWNvZGUoYnl0ZVtdIGVuY29kaW5nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBBdXRob3JpdHlLZXlJZGVudGlmaWVyIGFraSA9IChBdXRob3JpdHlLZXlJZGVudGlmaWVyKSBBU04xLmRlY29kZShlbmNvZGluZyk7CisgICAgICAgIGFraS5lbmNvZGluZyA9IGVuY29kaW5nOworICAgICAgICByZXR1cm4gYWtpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZHVtcFZhbHVlKFN0cmluZ0J1aWxkZXIgc2IsIFN0cmluZyBwcmVmaXgpIHsKKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJBdXRob3JpdHlLZXlJZGVudGlmaWVyIFtcbiIpOworICAgICAgICBpZiAoa2V5SWRlbnRpZmllciAhPSBudWxsKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQocHJlZml4KS5hcHBlbmQoIiAga2V5SWRlbnRpZmllcjpcbiIpOworICAgICAgICAgICAgc2IuYXBwZW5kKEFycmF5LnRvU3RyaW5nKGtleUlkZW50aWZpZXIsIHByZWZpeCArICIgICAgIikpOworICAgICAgICB9CisgICAgICAgIGlmIChhdXRob3JpdHlDZXJ0SXNzdWVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZChwcmVmaXgpLmFwcGVuZCgiICBhdXRob3JpdHlDZXJ0SXNzdWVyOiBbXG4iKTsKKyAgICAgICAgICAgIGF1dGhvcml0eUNlcnRJc3N1ZXIuZHVtcFZhbHVlKHNiLCBwcmVmaXggKyAiICAgICIpOworICAgICAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCIgIF1cbiIpOworICAgICAgICB9CisgICAgICAgIGlmIChhdXRob3JpdHlDZXJ0U2VyaWFsTnVtYmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZChwcmVmaXgpLmFwcGVuZCgiICBhdXRob3JpdHlDZXJ0U2VyaWFsTnVtYmVyOiAiKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZChhdXRob3JpdHlDZXJ0U2VyaWFsTnVtYmVyKS5hcHBlbmQoJ1xuJyk7CisgICAgICAgIH0KKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJdXG4iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFUeXBlIEFTTjEgPSBuZXcgQVNOMVNlcXVlbmNlKAorICAgICAgICAgICAgbmV3IEFTTjFUeXBlW10geworICAgICAgICAgICAgICAgIG5ldyBBU04xSW1wbGljaXQoMCwgQVNOMU9jdGV0U3RyaW5nLmdldEluc3RhbmNlKCkpLAorICAgICAgICAgICAgICAgIG5ldyBBU04xSW1wbGljaXQoMSwgR2VuZXJhbE5hbWVzLkFTTjEpLAorICAgICAgICAgICAgICAgIG5ldyBBU04xSW1wbGljaXQoMiwgQVNOMUludGVnZXIuZ2V0SW5zdGFuY2UoKSksCisgICAgICAgICAgICB9KSB7CisgICAgICAgIHsKKyAgICAgICAgICAgIHNldE9wdGlvbmFsKDApOworICAgICAgICAgICAgc2V0T3B0aW9uYWwoMSk7CisgICAgICAgICAgICBzZXRPcHRpb25hbCgyKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBPYmplY3RbXSB2YWx1ZXMgPSAoT2JqZWN0W10pIGluLmNvbnRlbnQ7CisKKyAgICAgICAgICAgIGJ5dGVbXSBlbmMgPSAoYnl0ZVtdKSB2YWx1ZXNbMl07CisgICAgICAgICAgICBCaWdJbnRlZ2VyIGF1dGhvcml0eUNlcnRTZXJpYWxOdW1iZXIgPSBudWxsOworICAgICAgICAgICAgaWYgKGVuYyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYXV0aG9yaXR5Q2VydFNlcmlhbE51bWJlciA9IG5ldyBCaWdJbnRlZ2VyKGVuYyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBuZXcgQXV0aG9yaXR5S2V5SWRlbnRpZmllcigoYnl0ZVtdKSB2YWx1ZXNbMF0sCisgICAgICAgICAgICAgICAgICAgIChHZW5lcmFsTmFtZXMpIHZhbHVlc1sxXSwgYXV0aG9yaXR5Q2VydFNlcmlhbE51bWJlcik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykgeworICAgICAgICAgICAgQXV0aG9yaXR5S2V5SWRlbnRpZmllciBha2lkID0gKEF1dGhvcml0eUtleUlkZW50aWZpZXIpIG9iamVjdDsKKyAgICAgICAgICAgIHZhbHVlc1swXSA9IGFraWQua2V5SWRlbnRpZmllcjsKKyAgICAgICAgICAgIHZhbHVlc1sxXSA9IGFraWQuYXV0aG9yaXR5Q2VydElzc3VlcjsKKyAgICAgICAgICAgIGlmIChha2lkLmF1dGhvcml0eUNlcnRTZXJpYWxOdW1iZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHZhbHVlc1syXSA9IGFraWQuYXV0aG9yaXR5Q2VydFNlcmlhbE51bWJlci50b0J5dGVBcnJheSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9CYXNpY0NvbnN0cmFpbnRzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvQmFzaWNDb25zdHJhaW50cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZhNDczZjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvQmFzaWNDb25zdHJhaW50cy5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xQm9vbGVhbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xSW50ZWdlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2VxdWVuY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVR5cGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQmVySW5wdXRTdHJlYW07CisKKy8qKgorICogQmFzaWMgQ29uc3RyYWludHMgRXh0ZW5zaW9uIChPSUQgPT0gMi41LjI5LjE5KS4KKyAqCisgKiBUaGUgQVNOLjEgZGVmaW5pdGlvbiBmb3IgQmFzaWMgQ29uc3RyYWludHMgRXh0ZW5zaW9uIGlzOgorICoKKyAqIDxwcmU+CisgKiAgIGlkLWNlLWJhc2ljQ29uc3RyYWludHMgT0JKRUNUIElERU5USUZJRVIgOjo9ICB7IGlkLWNlIDE5IH0KKyAqCisgKiAgIEJhc2ljQ29uc3RyYWludHMgOjo9IFNFUVVFTkNFIHsKKyAqICAgICAgICBjYSAgICAgICAgICAgICAgICAgICAgICBCT09MRUFOIERFRkFVTFQgRkFMU0UsCisgKiAgICAgICAgcGF0aExlbkNvbnN0cmFpbnQgICAgICAgSU5URUdFUiAoMC4uTUFYKSBPUFRJT05BTAorICogICB9CisgKiA8L3ByZT4KKyAqIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODApCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBCYXNpY0NvbnN0cmFpbnRzIGV4dGVuZHMgRXh0ZW5zaW9uVmFsdWUgeworICAgIC8qKiBpcyBDQSAqLworICAgIHByaXZhdGUgYm9vbGVhbiBjYSA9IGZhbHNlOworICAgIC8qKiBwYXRoIGxlbiBjb25zdHJhaW50ICovCisgICAgcHJpdmF0ZSBpbnQgcGF0aExlbkNvbnN0cmFpbnQgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIGV4dGVuc2lvbiBvYmplY3Qgb24gdGhlIGJhc2Ugb2YgaXRzIGVuY29kZWQgZm9ybS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmFzaWNDb25zdHJhaW50cyhieXRlW10gZW5jb2RpbmcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKGVuY29kaW5nKTsKKyAgICAgICAgT2JqZWN0W10gdmFsdWVzID0gKE9iamVjdFtdKSBBU04xLmRlY29kZShlbmNvZGluZyk7CisgICAgICAgIGNhID0gKEJvb2xlYW4pIHZhbHVlc1swXTsKKyAgICAgICAgaWYgKHZhbHVlc1sxXSAhPSBudWxsKSB7CisgICAgICAgICAgICBwYXRoTGVuQ29uc3RyYWludCA9IG5ldyBCaWdJbnRlZ2VyKChieXRlW10pIHZhbHVlc1sxXSkuaW50VmFsdWUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0UGF0aExlbkNvbnN0cmFpbnQoKSB7CisgICAgICAgIHJldHVybiBwYXRoTGVuQ29uc3RyYWludDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBlbmNvZGVkIGZvcm0gb2YgdGhlIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKG5ldyBPYmplY3RbXXtjYSwgQmlnSW50ZWdlci52YWx1ZU9mKHBhdGhMZW5Db25zdHJhaW50KSB9KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZHVtcFZhbHVlKFN0cmluZ0J1aWxkZXIgc2IsIFN0cmluZyBwcmVmaXgpIHsKKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJCYXNpY0NvbnN0cmFpbnRzIFtcbiIpLmFwcGVuZChwcmVmaXgpCisgICAgICAgICAgICAuYXBwZW5kKCIgIENBOiAiKS5hcHBlbmQoY2EpCisgICAgICAgICAgICAuYXBwZW5kKCJcbiAgIikuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJwYXRoTGVuQ29uc3RyYWludDogIikKKyAgICAgICAgICAgIC5hcHBlbmQocGF0aExlbkNvbnN0cmFpbnQpLmFwcGVuZCgnXG4nKS5hcHBlbmQocHJlZml4KQorICAgICAgICAgICAgLmFwcGVuZCgiXVxuIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQVNOLjEgRW5jb2Rlci9EZWNvZGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVR5cGUgQVNOMSA9IG5ldyBBU04xU2VxdWVuY2UobmV3IEFTTjFUeXBlW10geworICAgICAgICAgICAgQVNOMUJvb2xlYW4uZ2V0SW5zdGFuY2UoKSwgQVNOMUludGVnZXIuZ2V0SW5zdGFuY2UoKSB9KSB7CisgICAgICAgIHsKKyAgICAgICAgICAgIHNldERlZmF1bHQoQm9vbGVhbi5GQUxTRSwgMCk7CisgICAgICAgICAgICBzZXRPcHRpb25hbCgxKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBpbi5jb250ZW50OworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykgeworICAgICAgICAgICAgT2JqZWN0W10gYXJyYXkgPSAoT2JqZWN0W10pIG9iamVjdDsKKyAgICAgICAgICAgIHZhbHVlc1swXSA9IGFycmF5WzBdOworICAgICAgICAgICAgdmFsdWVzWzFdID0gKChCaWdJbnRlZ2VyKSBhcnJheVsxXSkudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgfQorICAgIH07Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvQ1JMRGlzdHJpYnV0aW9uUG9pbnRzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvQ1JMRGlzdHJpYnV0aW9uUG9pbnRzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTA4MGFkZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9DUkxEaXN0cmlidXRpb25Qb2ludHMuamF2YQpAQCAtMCwwICsxLDExMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2VxdWVuY2VPZjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKKworLyoqCisgKiBUaGUgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBBU04uMSBERVIgZW5jb2RpbmcvZGVjb2Rpbmcgd29yaworICogd2l0aCB0aGUgQ1JMIERpc3RyaWJ1dGlvbiBQb2ludHMgd2hpY2ggaXMgdGhlIHBhcnQgb2YgWC41MDkgQ2VydGlmaWNhdGUKKyAqIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODAgLQorICogIEludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUuCisgKiAgQ2VydGlmaWNhdGUgYW5kIENlcnRpZmljYXRlIFJldm9jYXRpb24gTGlzdCAoQ1JMKSBQcm9maWxlLgorICogIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KToKKyAqCisgKiA8cHJlPgorICogIENSTERpc3RyaWJ1dGlvblBvaW50cyA6Oj0gU0VRVUVOQ0UgU0laRSAoMS4uTUFYKSBPRiBEaXN0cmlidXRpb25Qb2ludAorICoKKyAqICBEaXN0cmlidXRpb25Qb2ludCA6Oj0gU0VRVUVOQ0UgeworICogICAgICAgIGRpc3RyaWJ1dGlvblBvaW50ICAgICAgIFswXSAgICAgRGlzdHJpYnV0aW9uUG9pbnROYW1lIE9QVElPTkFMLAorICogICAgICAgIHJlYXNvbnMgICAgICAgICAgICAgICAgIFsxXSAgICAgUmVhc29uRmxhZ3MgT1BUSU9OQUwsCisgKiAgICAgICAgY1JMSXNzdWVyICAgICAgICAgICAgICAgWzJdICAgICBHZW5lcmFsTmFtZXMgT1BUSU9OQUwKKyAqICB9CisgKgorICogIERpc3RyaWJ1dGlvblBvaW50TmFtZSA6Oj0gQ0hPSUNFIHsKKyAqICAgICAgICBmdWxsTmFtZSAgICAgICAgICAgICAgICBbMF0gICAgIEdlbmVyYWxOYW1lcywKKyAqICAgICAgICBuYW1lUmVsYXRpdmVUb0NSTElzc3VlciBbMV0gICAgIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUKKyAqICB9CisgKgorICogIFJlYXNvbkZsYWdzIDo6PSBCSVQgU1RSSU5HIHsKKyAqICAgICAgICB1bnVzZWQgICAgICAgICAgICAgICAgICAoMCksCisgKiAgICAgICAga2V5Q29tcHJvbWlzZSAgICAgICAgICAgKDEpLAorICogICAgICAgIGNBQ29tcHJvbWlzZSAgICAgICAgICAgICgyKSwKKyAqICAgICAgICBhZmZpbGlhdGlvbkNoYW5nZWQgICAgICAoMyksCisgKiAgICAgICAgc3VwZXJzZWRlZCAgICAgICAgICAgICAgKDQpLAorICogICAgICAgIGNlc3NhdGlvbk9mT3BlcmF0aW9uICAgICg1KSwKKyAqICAgICAgICBjZXJ0aWZpY2F0ZUhvbGQgICAgICAgICAoNiksCisgKiAgICAgICAgcHJpdmlsZWdlV2l0aGRyYXduICAgICAgKDcpLAorICogICAgICAgIGFBQ29tcHJvbWlzZSAgICAgICAgICAgICg4KQorICogIH0KKyAqIDwvcHJlPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQ1JMRGlzdHJpYnV0aW9uUG9pbnRzIGV4dGVuZHMgRXh0ZW5zaW9uVmFsdWUgeworICAgIHByaXZhdGUgTGlzdDxEaXN0cmlidXRpb25Qb2ludD4gZGlzdHJpYnV0aW9uUG9pbnRzOworICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kaW5nOworCisgICAgcHJpdmF0ZSBDUkxEaXN0cmlidXRpb25Qb2ludHMoTGlzdDxEaXN0cmlidXRpb25Qb2ludD4gZGlzdHJpYnV0aW9uUG9pbnRzLCBieXRlW10gZW5jb2RpbmcpIHsKKyAgICAgICAgaWYgKChkaXN0cmlidXRpb25Qb2ludHMgPT0gbnVsbCkgfHwgKGRpc3RyaWJ1dGlvblBvaW50cy5zaXplKCkgPT0gMCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImRpc3RyaWJ1dGlvblBvaW50cyBhcmUgZW1wdHkiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmRpc3RyaWJ1dGlvblBvaW50cyA9IGRpc3RyaWJ1dGlvblBvaW50czsKKyAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIENSTERpc3RyaWJ1dGlvblBvaW50cyBkZWNvZGUoYnl0ZVtdIGVuY29kaW5nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gKENSTERpc3RyaWJ1dGlvblBvaW50cykgQVNOMS5kZWNvZGUoZW5jb2RpbmcpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBkdW1wVmFsdWUoU3RyaW5nQnVpbGRlciBzYiwgU3RyaW5nIHByZWZpeCkgeworICAgICAgICBzYi5hcHBlbmQocHJlZml4KS5hcHBlbmQoIkNSTCBEaXN0cmlidXRpb24gUG9pbnRzOiBbXG4iKTsKKyAgICAgICAgaW50IG51bWJlciA9IDA7CisgICAgICAgIGZvciAoRGlzdHJpYnV0aW9uUG9pbnQgZGlzdHJpYnV0aW9uUG9pbnQgOiBkaXN0cmlidXRpb25Qb2ludHMpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZChwcmVmaXgpLmFwcGVuZCgiICBbIikuYXBwZW5kKCsrbnVtYmVyKS5hcHBlbmQoIl1cbiIpOworICAgICAgICAgICAgZGlzdHJpYnV0aW9uUG9pbnQuZHVtcFZhbHVlKHNiLCBwcmVmaXggKyAiICAiKTsKKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQocHJlZml4KS5hcHBlbmQoIl1cbiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEN1c3RvbSBYLjUwOSBkZWNvZGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVR5cGUgQVNOMSA9IG5ldyBBU04xU2VxdWVuY2VPZihEaXN0cmlidXRpb25Qb2ludC5BU04xKSB7CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQ1JMRGlzdHJpYnV0aW9uUG9pbnRzKChMaXN0PERpc3RyaWJ1dGlvblBvaW50PikgaW4uY29udGVudCwgaW4uZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgQ29sbGVjdGlvbjw/PiBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgQ1JMRGlzdHJpYnV0aW9uUG9pbnRzIGRwcyA9IChDUkxEaXN0cmlidXRpb25Qb2ludHMpIG9iamVjdDsKKyAgICAgICAgICAgIHJldHVybiBkcHMuZGlzdHJpYnV0aW9uUG9pbnRzOworICAgICAgICB9CisgICAgfTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9DUkxOdW1iZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9DUkxOdW1iZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMDM4MDY4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0NSTE51bWJlci5qYXZhCkBAIC0wLDAgKzEsNzMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFJbnRlZ2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworCisvKioKKyAqIENSTCBFbnRyeSdzIENSTCBOdW1iZXIgRXh0ZW5zaW9uIChPSUQgPSAyLjUuMjkuMjApLgorICogPHByZT4KKyAqICAgaWQtY2UtY1JMTnVtYmVyIE9CSkVDVCBJREVOVElGSUVSIDo6PSB7IGlkLWNlIDIwIH0KKyAqCisgKiAgIENSTE51bWJlciA6Oj0gSU5URUdFUiAoMC4uTUFYKQorICogPC9wcmU+CisgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQ1JMTnVtYmVyIGV4dGVuZHMgRXh0ZW5zaW9uVmFsdWUgeworICAgIC8qKiBjcmwgbnVtYmVyIHZhbHVlICovCisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIG51bWJlcjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgdGhlIG9iamVjdCBvbiB0aGUgYmFzZSBvZiBpdHMgZW5jb2RlZCBmb3JtLgorICAgICAqLworICAgIHB1YmxpYyBDUkxOdW1iZXIoYnl0ZVtdIGVuY29kaW5nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihlbmNvZGluZyk7CisgICAgICAgIG51bWJlciA9IG5ldyBCaWdJbnRlZ2VyKChieXRlW10pIEFTTjEuZGVjb2RlKGVuY29kaW5nKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW52YWxpZGl0eSBkYXRlLgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldE51bWJlcigpIHsKKyAgICAgICAgcmV0dXJuIG51bWJlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFTTi4xIGVuY29kZWQgZm9ybSBvZiB0aGlzIFguNTA5IENSTE51bWJlciB2YWx1ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSBBU04xLmVuY29kZShudW1iZXIudG9CeXRlQXJyYXkoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVuY29kaW5nOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBkdW1wVmFsdWUoU3RyaW5nQnVpbGRlciBzYiwgU3RyaW5nIHByZWZpeCkgeworICAgICAgICBzYi5hcHBlbmQocHJlZml4KS5hcHBlbmQoIkNSTCBOdW1iZXI6IFsgIikuYXBwZW5kKG51bWJlcikuYXBwZW5kKCIgXVxuIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQVNOLjEgRW5jb2Rlci9EZWNvZGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVR5cGUgQVNOMSA9IEFTTjFJbnRlZ2VyLmdldEluc3RhbmNlKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvQ2VydGlmaWNhdGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9DZXJ0aWZpY2F0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ0YmIyOWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvQ2VydGlmaWNhdGUuamF2YQpAQCAtMCwwICsxLDEzNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUJpdFN0cmluZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2VxdWVuY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVR5cGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQmVySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQml0U3RyaW5nOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS51dGlscy5BcnJheTsKKworLyoqCisgKiBUaGUgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBBU04uMSBERVIgZW5jb2RpbmcvZGVjb2Rpbmcgd29yaworICogd2l0aCB0aGUgWC41MDkgY2VydGlmaWNhdGUuIEl0cyBBU04gbm90YXRpb24gaXMgYXMgZm9sbG93cworICogKGFzIHNwZWNpZmllZCBpbiBSRkMgMzI4MCAtCisgKiAgSW50ZXJuZXQgWC41MDkgUHVibGljIEtleSBJbmZyYXN0cnVjdHVyZS4KKyAqICBDZXJ0aWZpY2F0ZSBhbmQgQ2VydGlmaWNhdGUgUmV2b2NhdGlvbiBMaXN0IChDUkwpIFByb2ZpbGUuCisgKiAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpOgorICoKKyAqIDxwcmU+CisgKiAgQ2VydGlmaWNhdGUgIDo6PSAgU0VRVUVOQ0UgIHsKKyAqICAgICAgdGJzQ2VydGlmaWNhdGUgICAgICAgVEJTQ2VydGlmaWNhdGUsCisgKiAgICAgIHNpZ25hdHVyZUFsZ29yaXRobSAgIEFsZ29yaXRobUlkZW50aWZpZXIsCisgKiAgICAgIHNpZ25hdHVyZVZhbHVlICAgICAgIEJJVCBTVFJJTkcKKyAqICB9CisgKiA8L3ByZT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIENlcnRpZmljYXRlIHsKKyAgICAvKiogdGhlIHZhbHVlIG9mIHRic0NlcnRpZmljYXRlIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIFRCU0NlcnRpZmljYXRlIHRic0NlcnRpZmljYXRlOworICAgIC8qKiB0aGUgdmFsdWUgb2Ygc2lnbmF0dXJlQWxnb3JpdGhtIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIEFsZ29yaXRobUlkZW50aWZpZXIgc2lnbmF0dXJlQWxnb3JpdGhtOworICAgIC8qKiB0aGUgdmFsdWUgb2Ygc2lnbmF0dXJlVmFsdWUgZmllbGQgb2YgdGhlIHN0cnVjdHVyZSAqLworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIHNpZ25hdHVyZVZhbHVlOworICAgIC8qKiB0aGUgQVNOLjEgZW5jb2RlZCBmb3JtIG9mIENlcnRpZmljYXRlICovCisgICAgcHJpdmF0ZSBieXRlW10gZW5jb2Rpbmc7CisKKyAgICBwdWJsaWMgQ2VydGlmaWNhdGUoVEJTQ2VydGlmaWNhdGUgdGJzQ2VydGlmaWNhdGUsCisgICAgICAgICAgICAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIgc2lnbmF0dXJlQWxnb3JpdGhtLAorICAgICAgICAgICAgICAgICAgICAgICBieXRlW10gc2lnbmF0dXJlVmFsdWUpIHsKKyAgICAgICAgdGhpcy50YnNDZXJ0aWZpY2F0ZSA9IHRic0NlcnRpZmljYXRlOworICAgICAgICB0aGlzLnNpZ25hdHVyZUFsZ29yaXRobSA9IHNpZ25hdHVyZUFsZ29yaXRobTsKKyAgICAgICAgdGhpcy5zaWduYXR1cmVWYWx1ZSA9IG5ldyBieXRlW3NpZ25hdHVyZVZhbHVlLmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2lnbmF0dXJlVmFsdWUsIDAsIHRoaXMuc2lnbmF0dXJlVmFsdWUsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lnbmF0dXJlVmFsdWUubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIENlcnRpZmljYXRlKFRCU0NlcnRpZmljYXRlIHRic0NlcnRpZmljYXRlLAorICAgICAgICAgICAgICAgICAgICAgICBBbGdvcml0aG1JZGVudGlmaWVyIHNpZ25hdHVyZUFsZ29yaXRobSwKKyAgICAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIHNpZ25hdHVyZVZhbHVlLCBieXRlW10gZW5jb2RpbmcpIHsKKyAgICAgICAgdGhpcyh0YnNDZXJ0aWZpY2F0ZSwgc2lnbmF0dXJlQWxnb3JpdGhtLCBzaWduYXR1cmVWYWx1ZSk7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0YnNDZXJ0aWZpY2F0ZSBmaWVsZCBvZiB0aGUgc3RydWN0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBUQlNDZXJ0aWZpY2F0ZSBnZXRUYnNDZXJ0aWZpY2F0ZSgpIHsKKyAgICAgICAgcmV0dXJuIHRic0NlcnRpZmljYXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHNpZ25hdHVyZVZhbHVlIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRTaWduYXR1cmVWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIHNpZ25hdHVyZVZhbHVlLmNsb25lKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZCgiWC41MDkgQ2VydGlmaWNhdGU6XG5bXG4iKTsKKyAgICAgICAgdGJzQ2VydGlmaWNhdGUuZHVtcFZhbHVlKHJlc3VsdCk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQoIlxuICBBbGdvcml0aG06IFsiKTsKKyAgICAgICAgc2lnbmF0dXJlQWxnb3JpdGhtLmR1bXBWYWx1ZShyZXN1bHQpOworICAgICAgICByZXN1bHQuYXBwZW5kKCddJyk7CisgICAgICAgIHJlc3VsdC5hcHBlbmQoIlxuICBTaWduYXR1cmUgVmFsdWU6XG4iKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZChBcnJheS50b1N0cmluZyhzaWduYXR1cmVWYWx1ZSwgIiIpKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZCgnXScpOworICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBlbmNvZGVkIGZvcm0gb2YgdGhpcyBYLjUwOSBUQlNDZXJ0aWZpY2F0ZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IENlcnRpZmljYXRlLkFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBYLjUwOSBDZXJ0aWZpY2F0ZSBlbmNvZGVyL2RlY29kZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xU2VxdWVuY2UgQVNOMSA9CisgICAgICAgIG5ldyBBU04xU2VxdWVuY2UobmV3IEFTTjFUeXBlW10KKyAgICAgICAgICAgICAgICB7VEJTQ2VydGlmaWNhdGUuQVNOMSwgQWxnb3JpdGhtSWRlbnRpZmllci5BU04xLCBBU04xQml0U3RyaW5nLmdldEluc3RhbmNlKCl9KSB7CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgT2JqZWN0W10gdmFsdWVzID0gKE9iamVjdFtdKSBpbi5jb250ZW50OworICAgICAgICAgICAgcmV0dXJuIG5ldyBDZXJ0aWZpY2F0ZSgKKyAgICAgICAgICAgICAgICAgICAgKFRCU0NlcnRpZmljYXRlKSB2YWx1ZXNbMF0sCisgICAgICAgICAgICAgICAgICAgIChBbGdvcml0aG1JZGVudGlmaWVyKSB2YWx1ZXNbMV0sCisgICAgICAgICAgICAgICAgICAgICgoQml0U3RyaW5nKSB2YWx1ZXNbMl0pLmJ5dGVzLCAvLyBGSVhNRSBrZWVwIGFzIEJpdFN0cmluZyBvYmplY3QKKyAgICAgICAgICAgICAgICAgICAgaW4uZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCwgT2JqZWN0W10gdmFsdWVzKSB7CisgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBjZXJ0ID0gKENlcnRpZmljYXRlKSBvYmplY3Q7CisgICAgICAgICAgICB2YWx1ZXNbMF0gPSBjZXJ0LnRic0NlcnRpZmljYXRlOworICAgICAgICAgICAgdmFsdWVzWzFdID0gY2VydC5zaWduYXR1cmVBbGdvcml0aG07CisgICAgICAgICAgICB2YWx1ZXNbMl0gPSBuZXcgQml0U3RyaW5nKGNlcnQuc2lnbmF0dXJlVmFsdWUsIDApOworICAgICAgICB9CisgICAgfTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9DZXJ0aWZpY2F0ZUlzc3Vlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0NlcnRpZmljYXRlSXNzdWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTQ0ZmY4ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9DZXJ0aWZpY2F0ZUlzc3Vlci5qYXZhCkBAIC0wLDAgKzEsODUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXF1ZW5jZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwMS5OYW1lOworCisvKioKKyAqIENSTCBFbnRyeSdzIENlcnRpZmljYXRlIElzc3VlciBFeHRlbnNpb24gKE9JRCA9IDIuNS4yOS4yOSkuCisgKiBJdCBpcyBhIENSTCBlbnRyeSBleHRlbnNpb24gYW5kIGNvbnRhaW5zIHRoZSBHZW5lcmFsTmFtZXMgZGVzY3JpYmluZworICogdGhlIGlzc3VlciBvZiByZXZva2VkIGNlcnRpZmljYXRlLiBJdHMgQVNOLjEgbm90YXRpb24gaXMgYXMgZm9sbG93czoKKyAqIDxwcmU+CisgKiAgIGlkLWNlLWNlcnRpZmljYXRlSXNzdWVyICAgT0JKRUNUIElERU5USUZJRVIgOjo9IHsgaWQtY2UgMjkgfQorICoKKyAqICAgY2VydGlmaWNhdGVJc3N1ZXIgOjo9ICAgICBHZW5lcmFsTmFtZXMKKyAqIDwvcHJlPgorICogKGFzIHNwZWNpZmllZCBpbiBSRkMgMzI4MCkKKyAqIEluIGphdmEgaW1wbGVtZW50YXRpb24gaXQgaXMgcHJlc3VtZWQgdGhhdCBHZW5lcmFsTmFtZXMgY29uc2lzdCBvZgorICogb25lIGVsZW1lbnQgYW5kIGl0cyB0eXBlIGlzIGRpcmVjdG9yeU5hbWUuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBDZXJ0aWZpY2F0ZUlzc3VlciBleHRlbmRzIEV4dGVuc2lvblZhbHVlIHsKKyAgICAvKiogY2VydGlmaWNhdGUgaXNzdWVyIHZhbHVlICovCisgICAgcHJpdmF0ZSBYNTAwUHJpbmNpcGFsIGlzc3VlcjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IG9uIHRoZSBiYXNlIG9mIGl0cyBlbmNvZGVkIGZvcm0uCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlSXNzdWVyKGJ5dGVbXSBlbmNvZGluZykgeworICAgICAgICBzdXBlcihlbmNvZGluZyk7CisgICAgfQorCisgICAgcHVibGljIFg1MDBQcmluY2lwYWwgZ2V0SXNzdWVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzc3VlciA9PSBudWxsKSB7CisgICAgICAgICAgICBpc3N1ZXIgPSAoWDUwMFByaW5jaXBhbCkgQVNOMS5kZWNvZGUoZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaXNzdWVyOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBkdW1wVmFsdWUoU3RyaW5nQnVpbGRlciBzYiwgU3RyaW5nIHByZWZpeCkgeworICAgICAgICBzYi5hcHBlbmQocHJlZml4KS5hcHBlbmQoIkNlcnRpZmljYXRlIElzc3VlcjogIik7CisgICAgICAgIGlmIChpc3N1ZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpc3N1ZXIgPSBnZXRJc3N1ZXIoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBpbmNvcnJlY3QgZXh0ZW5zaW9uIHZhbHVlIGVuY29kaW5nCisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCJVbnBhcnNlYWJsZSAoaW5jb3JyZWN0ISkgZXh0ZW5zaW9uIHZhbHVlOlxuIik7CisgICAgICAgICAgICAgICAgc3VwZXIuZHVtcFZhbHVlKHNiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQoaXNzdWVyKS5hcHBlbmQoJ1xuJyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQVNOLjEgRW5jb2Rlci9EZWNvZGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVR5cGUgQVNOMSA9IG5ldyBBU04xU2VxdWVuY2UobmV3IEFTTjFUeXBlW10geyBHZW5lcmFsTmFtZS5BU04xIH0pIHsKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgcmV0dXJuICgoTmFtZSkgKChHZW5lcmFsTmFtZSkgKChPYmplY3RbXSkgaW4uY29udGVudClbMF0pCisgICAgICAgICAgICAgICAgICAgIC5nZXROYW1lKCkpLmdldFg1MDBQcmluY2lwYWwoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCwgT2JqZWN0W10gdmFsdWVzKSB7CisgICAgICAgICAgICB2YWx1ZXNbMF0gPSBvYmplY3Q7CisgICAgICAgIH0KKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0NlcnRpZmljYXRlTGlzdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0NlcnRpZmljYXRlTGlzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg1ZDg3ODkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvQ2VydGlmaWNhdGVMaXN0LmphdmEKQEAgLTAsMCArMSwxMzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFCaXRTdHJpbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJpdFN0cmluZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudXRpbHMuQXJyYXk7CisKKy8qKgorICogVGhlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgQVNOLjEgREVSIGVuY29kaW5nL2RlY29kaW5nIHdvcmsKKyAqIHdpdGggdGhlIFguNTA5IENSTC4gSXRzIEFTTiBub3RhdGlvbiBpcyBhcyBmb2xsb3dzCisgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIC0KKyAqICBJbnRlcm5ldCBYLjUwOSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgorICogIENlcnRpZmljYXRlIGFuZCBDZXJ0aWZpY2F0ZSBSZXZvY2F0aW9uIExpc3QgKENSTCkgUHJvZmlsZS4KKyAqICBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCk6CisgKgorICogPHByZT4KKyAqICBDZXJ0aWZpY2F0ZUxpc3QgIDo6PSAgU0VRVUVOQ0UgIHsKKyAqICAgICAgIHRic0NlcnRMaXN0ICAgICAgICAgIFRCU0NlcnRMaXN0LAorICogICAgICAgc2lnbmF0dXJlQWxnb3JpdGhtICAgQWxnb3JpdGhtSWRlbnRpZmllciwKKyAqICAgICAgIHNpZ25hdHVyZVZhbHVlICAgICAgIEJJVCBTVFJJTkcKKyAqICB9CisgKiA8L3ByZT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIENlcnRpZmljYXRlTGlzdCB7CisgICAgLyoqIHRoZSB2YWx1ZSBvZiB0YnNDZXJ0TGlzdCBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBmaW5hbCBUQlNDZXJ0TGlzdCB0YnNDZXJ0TGlzdDsKKyAgICAvKiogdGhlIHZhbHVlIG9mIHNpZ25hdHVyZUFsZ29yaXRobSBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBmaW5hbCBBbGdvcml0aG1JZGVudGlmaWVyIHNpZ25hdHVyZUFsZ29yaXRobTsKKyAgICAvKiogdGhlIHZhbHVlIG9mIHNpZ25hdHVyZVZhbHVlIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBzaWduYXR1cmVWYWx1ZTsKKyAgICAvKiogdGhlIEFTTi4xIGVuY29kZWQgZm9ybSBvZiBDZXJ0TGlzdCAqLworICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kaW5nOworCisgICAgcHVibGljIENlcnRpZmljYXRlTGlzdChUQlNDZXJ0TGlzdCB0YnNDZXJ0TGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgQWxnb3JpdGhtSWRlbnRpZmllciBzaWduYXR1cmVBbGdvcml0aG0sCisgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBzaWduYXR1cmVWYWx1ZSkgeworICAgICAgICB0aGlzLnRic0NlcnRMaXN0ID0gdGJzQ2VydExpc3Q7CisgICAgICAgIHRoaXMuc2lnbmF0dXJlQWxnb3JpdGhtID0gc2lnbmF0dXJlQWxnb3JpdGhtOworICAgICAgICB0aGlzLnNpZ25hdHVyZVZhbHVlID0gbmV3IGJ5dGVbc2lnbmF0dXJlVmFsdWUubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzaWduYXR1cmVWYWx1ZSwgMCwgdGhpcy5zaWduYXR1cmVWYWx1ZSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduYXR1cmVWYWx1ZS5sZW5ndGgpOworICAgIH0KKworICAgIHByaXZhdGUgQ2VydGlmaWNhdGVMaXN0KFRCU0NlcnRMaXN0IHRic0NlcnRMaXN0LAorICAgICAgICAgICAgICAgICAgICAgICBBbGdvcml0aG1JZGVudGlmaWVyIHNpZ25hdHVyZUFsZ29yaXRobSwKKyAgICAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIHNpZ25hdHVyZVZhbHVlLCBieXRlW10gZW5jb2RpbmcpIHsKKyAgICAgICAgdGhpcyh0YnNDZXJ0TGlzdCwgc2lnbmF0dXJlQWxnb3JpdGhtLCBzaWduYXR1cmVWYWx1ZSk7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0YnNDZXJ0TGlzdCBmaWVsZCBvZiB0aGUgc3RydWN0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBUQlNDZXJ0TGlzdCBnZXRUYnNDZXJ0TGlzdCgpIHsKKyAgICAgICAgcmV0dXJuIHRic0NlcnRMaXN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHNpZ25hdHVyZVZhbHVlIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRTaWduYXR1cmVWYWx1ZSgpIHsKKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW3NpZ25hdHVyZVZhbHVlLmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2lnbmF0dXJlVmFsdWUsIDAsIHJlc3VsdCwgMCwgc2lnbmF0dXJlVmFsdWUubGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICB0YnNDZXJ0TGlzdC5kdW1wVmFsdWUocmVzdWx0KTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZCgiXG5TaWduYXR1cmUgVmFsdWU6XG4iKTsKKyAgICAgICAgcmVzdWx0LmFwcGVuZChBcnJheS50b1N0cmluZyhzaWduYXR1cmVWYWx1ZSwgIiIpKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgQVNOLjEgZW5jb2RlZCBmb3JtIG9mIHRoaXMgWC41MDkgVEJTQ2VydExpc3QgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSBDZXJ0aWZpY2F0ZUxpc3QuQVNOMS5lbmNvZGUodGhpcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVuY29kaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIFguNTA5IENlcnRMaXN0IGVuY29kZXIvZGVjb2Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBBU04xID0KKyAgICAgICAgbmV3IEFTTjFTZXF1ZW5jZShuZXcgQVNOMVR5cGVbXQorICAgICAgICAgICAgICAgIHtUQlNDZXJ0TGlzdC5BU04xLCBBbGdvcml0aG1JZGVudGlmaWVyLkFTTjEsCisgICAgICAgICAgICAgICAgICAgIEFTTjFCaXRTdHJpbmcuZ2V0SW5zdGFuY2UoKX0pIHsKKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB7CisgICAgICAgICAgICBPYmplY3RbXSB2YWx1ZXMgPSAoT2JqZWN0W10pIGluLmNvbnRlbnQ7CisgICAgICAgICAgICByZXR1cm4gbmV3IENlcnRpZmljYXRlTGlzdCgKKyAgICAgICAgICAgICAgICAgICAgKFRCU0NlcnRMaXN0KSB2YWx1ZXNbMF0sCisgICAgICAgICAgICAgICAgICAgIChBbGdvcml0aG1JZGVudGlmaWVyKSB2YWx1ZXNbMV0sCisgICAgICAgICAgICAgICAgICAgICgoQml0U3RyaW5nKSB2YWx1ZXNbMl0pLmJ5dGVzLCAvLyBGSVhNRSBrZWVwIGFzIEJpdFN0cmluZyBvYmplY3QKKyAgICAgICAgICAgICAgICAgICAgaW4uZ2V0RW5jb2RlZCgpCisgICAgICAgICAgICAgICAgICAgICk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykgeworICAgICAgICAgICAgQ2VydGlmaWNhdGVMaXN0IGNlcnRpZmljYXRlTGlzdCA9IChDZXJ0aWZpY2F0ZUxpc3QpIG9iamVjdDsKKyAgICAgICAgICAgIHZhbHVlc1swXSA9IGNlcnRpZmljYXRlTGlzdC50YnNDZXJ0TGlzdDsKKyAgICAgICAgICAgIHZhbHVlc1sxXSA9IGNlcnRpZmljYXRlTGlzdC5zaWduYXR1cmVBbGdvcml0aG07CisgICAgICAgICAgICB2YWx1ZXNbMl0gPSBuZXcgQml0U3RyaW5nKGNlcnRpZmljYXRlTGlzdC5zaWduYXR1cmVWYWx1ZSwgMCk7CisgICAgICAgIH0KKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0NlcnRpZmljYXRlUG9saWNpZXMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9DZXJ0aWZpY2F0ZVBvbGljaWVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWYyOTU5YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9DZXJ0aWZpY2F0ZVBvbGljaWVzLmphdmEKQEAgLTAsMCArMSwxMTcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2VxdWVuY2VPZjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKKworLyoqCisgKiBUaGUgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBBU04uMSBERVIgZW5jb2RpbmcvZGVjb2Rpbmcgd29yaworICogd2l0aCBDZXJ0aWZpY2F0ZSBQb2xpY2llcyBzdHJ1Y3R1cmUgd2hpY2ggaXMgYSBwYXJ0IG9mIFguNTA5IGNlcnRpZmljYXRlCisgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIC0KKyAqICBJbnRlcm5ldCBYLjUwOSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgorICogIENlcnRpZmljYXRlIGFuZCBDZXJ0aWZpY2F0ZSBSZXZvY2F0aW9uIExpc3QgKENSTCkgUHJvZmlsZS4KKyAqICBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCk6CisgKgorICogPHByZT4KKyAqICAgY2VydGlmaWNhdGVQb2xpY2llcyA6Oj0gU0VRVUVOQ0UgU0laRSAoMS4uTUFYKSBPRiBQb2xpY3lJbmZvcm1hdGlvbgorICogPC9wcmU+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBDZXJ0aWZpY2F0ZVBvbGljaWVzIGV4dGVuZHMgRXh0ZW5zaW9uVmFsdWUgeworICAgIC8qKiB0aGUgdmFsdWVzIG9mIHBvbGljeUluZm9ybWF0aW9uIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIExpc3Q8UG9saWN5SW5mb3JtYXRpb24+IHBvbGljeUluZm9ybWF0aW9uczsKKyAgICAvKiogdGhlIEFTTi4xIGVuY29kZWQgZm9ybSBvZiBDZXJ0aWZpY2F0ZVBvbGljaWVzICovCisgICAgcHJpdmF0ZSBieXRlW10gZW5jb2Rpbmc7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIHZhbHVlIG9mIENlcnRpZmljYXRlUG9saWNpZXMuCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlUG9saWNpZXMoKSB7fQorCisgICAgcHVibGljIHN0YXRpYyBDZXJ0aWZpY2F0ZVBvbGljaWVzIGRlY29kZShieXRlW10gZW5jb2RpbmcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIENlcnRpZmljYXRlUG9saWNpZXMgY3BzID0gKChDZXJ0aWZpY2F0ZVBvbGljaWVzKSBBU04xLmRlY29kZShlbmNvZGluZykpOworICAgICAgICBjcHMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICAgICAgcmV0dXJuIGNwczsKKyAgICB9CisKKyAgICBwcml2YXRlIENlcnRpZmljYXRlUG9saWNpZXMoTGlzdDxQb2xpY3lJbmZvcm1hdGlvbj4gcG9saWN5SW5mb3JtYXRpb25zLCBieXRlW10gZW5jb2RpbmcpIHsKKyAgICAgICAgdGhpcy5wb2xpY3lJbmZvcm1hdGlvbnMgPSBwb2xpY3lJbmZvcm1hdGlvbnM7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZXMgb2YgcG9saWN5SW5mb3JtYXRpb24gZmllbGQgb2YgdGhlIHN0cnVjdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxQb2xpY3lJbmZvcm1hdGlvbj4gZ2V0UG9saWN5SW5mb3JtYXRpb25zKCkgeworICAgICAgICByZXR1cm4gbmV3IEFycmF5TGlzdDxQb2xpY3lJbmZvcm1hdGlvbj4ocG9saWN5SW5mb3JtYXRpb25zKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVQb2xpY2llcyBhZGRQb2xpY3lJbmZvcm1hdGlvbihQb2xpY3lJbmZvcm1hdGlvbiBwb2xpY3lJbmZvcm1hdGlvbikgeworICAgICAgICBlbmNvZGluZyA9IG51bGw7CisgICAgICAgIGlmIChwb2xpY3lJbmZvcm1hdGlvbnMgPT0gbnVsbCkgeworICAgICAgICAgICAgcG9saWN5SW5mb3JtYXRpb25zID0gbmV3IEFycmF5TGlzdDxQb2xpY3lJbmZvcm1hdGlvbj4oKTsKKyAgICAgICAgfQorICAgICAgICBwb2xpY3lJbmZvcm1hdGlvbnMuYWRkKHBvbGljeUluZm9ybWF0aW9uKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBlbmNvZGVkIGZvcm0gb2YgdGhpcyBYLjUwOSBDZXJ0aWZpY2F0ZVBvbGljaWVzIHZhbHVlLgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZHVtcFZhbHVlKFN0cmluZ0J1aWxkZXIgc2IsIFN0cmluZyBwcmVmaXgpIHsKKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJDZXJ0aWZpY2F0ZVBvbGljaWVzIFtcbiIpOworICAgICAgICBmb3IgKFBvbGljeUluZm9ybWF0aW9uIHBvbGljeUluZm9ybWF0aW9uIDogcG9saWN5SW5mb3JtYXRpb25zKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQocHJlZml4KTsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiICAiKTsKKyAgICAgICAgICAgIHBvbGljeUluZm9ybWF0aW9uLmR1bXBWYWx1ZShzYik7CisgICAgICAgICAgICBzYi5hcHBlbmQoJ1xuJyk7CisgICAgICAgIH0KKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJdXG4iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBU04uMSBERVIgWC41MDkgQ2VydGlmaWNhdGVQb2xpY2llcyBlbmNvZGVyL2RlY29kZXIgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xVHlwZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZU9mKFBvbGljeUluZm9ybWF0aW9uLkFTTjEpIHsKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBDZXJ0aWZpY2F0ZVBvbGljaWVzKChMaXN0PFBvbGljeUluZm9ybWF0aW9uPikgaW4uY29udGVudCwgaW4uZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgQ29sbGVjdGlvbiBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgQ2VydGlmaWNhdGVQb2xpY2llcyBjcHMgPSAoQ2VydGlmaWNhdGVQb2xpY2llcykgb2JqZWN0OworICAgICAgICAgICAgcmV0dXJuIGNwcy5wb2xpY3lJbmZvcm1hdGlvbnM7CisgICAgICAgIH0KKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0ROUGFyc2VyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvRE5QYXJzZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ODBhYjA1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0ROUGFyc2VyLmphdmEKQEAgLTAsMCArMSw0NDAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBWLiBFc2luLCBTdGVwYW4gTS4gTWlzaHVyYQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTAxLkF0dHJpYnV0ZVR5cGVBbmRWYWx1ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwMS5BdHRyaWJ1dGVWYWx1ZTsKKworCisvKioKKyAqIERpc3Rpbmd1aXNoZWQgTmFtZSBQYXJzZXIuCisgKgorICogUGFyc2VzIGEgZGlzdGluZ3Vpc2hlZCBuYW1lKEROKSBzdHJpbmcgYWNjb3JkaW5nCisgKiBCTkYgc3ludGF4IHNwZWNpZmllZCBpbiBSRkMgMjI1MyBhbmQgUkZDIDE3NzkKKyAqCisgKiBSRkMgMjI1MzogTGlnaHR3ZWlnaHQgRGlyZWN0b3J5IEFjY2VzcyBQcm90b2NvbCAodjMpOgorICogICAgICAgICAgIFVURi04IFN0cmluZyBSZXByZXNlbnRhdGlvbiBvZiBEaXN0aW5ndWlzaGVkIE5hbWVzCisgKiAgIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyNTMudHh0CisgKgorICogUkZDIDE3Nzk6IEEgU3RyaW5nIFJlcHJlc2VudGF0aW9uIG9mIERpc3Rpbmd1aXNoZWQgTmFtZXMKKyAqICAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMTc3OS50eHQKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEROUGFyc2VyIHsKKyAgICBwcml2YXRlIGludCBwb3M7CisgICAgcHJpdmF0ZSBpbnQgYmVnOworICAgIHByaXZhdGUgaW50IGVuZDsKKworICAgIC8qKiBkaXN0aW5ndWlzaGVkIG5hbWUgY2hhcnMgKi8KKyAgICBwcml2YXRlIGZpbmFsIGNoYXJbXSBjaGFyczsKKworICAgIC8qKiByYXcgc3RyaW5nIGNvbnRhaW5zICciJyBvciAnXCcgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaGFzUUU7CisKKyAgICAvKiogREVSIGVuY29kaW5nIG9mIGN1cnJlbnRseSBwYXJzZWQgaXRlbSAqLworICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kZWQ7CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gZG4gLSBkaXN0aW5ndWlzaGVkIG5hbWUgc3RyaW5nIHRvIGJlIHBhcnNlZAorICAgICAqLworICAgIHB1YmxpYyBETlBhcnNlcihTdHJpbmcgZG4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJzID0gZG4udG9DaGFyQXJyYXkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGF0dHJpYnV0ZSB0eXBlOiAoQUxQSEEgMSprZXljaGFyKSAvIG9pZAorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIG5leHRBVCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGhhc1FFID0gZmFsc2U7IC8vIHJlc2V0CisKKyAgICAgICAgLy8gc2tpcCBwcmVjZWRpbmcgc3BhY2UgY2hhcnMsIHRoZXkgY2FuIHByZXNlbnQgYWZ0ZXIKKyAgICAgICAgLy8gY29tbWEgb3Igc2VtaWNvbG9uIChjb21wYXRpYmlsaXR5IHdpdGggUkZDIDE3NzkpCisgICAgICAgIGZvciAoOyBwb3MgPCBjaGFycy5sZW5ndGggJiYgY2hhcnNbcG9zXSA9PSAnICc7IHBvcysrKSB7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBvcyA9PSBjaGFycy5sZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOyAvLyByZWFjaGVkIHRoZSBlbmQgb2YgRE4KKyAgICAgICAgfQorCisgICAgICAgIC8vIG1hcmsgdGhlIGJlZ2lubmluZyBvZiBhdHRyaWJ1dGUgdHlwZQorICAgICAgICBiZWcgPSBwb3M7CisKKyAgICAgICAgLy8gYXR0cmlidXRlIHR5cGUgY2hhcnMKKyAgICAgICAgcG9zKys7CisgICAgICAgIGZvciAoOyBwb3MgPCBjaGFycy5sZW5ndGggJiYgY2hhcnNbcG9zXSAhPSAnPScgJiYgY2hhcnNbcG9zXSAhPSAnICc7IHBvcysrKSB7CisgICAgICAgICAgICAvLyB3ZSBkb24ndCBmb2xsb3cgZXhhY3QgQk5GIHN5bnRheCBoZXJlOgorICAgICAgICAgICAgLy8gYWNjZXB0IGFueSBjaGFyIGV4Y2VwdCBzcGFjZSBhbmQgJz0nCisgICAgICAgIH0KKyAgICAgICAgaWYgKHBvcyA+PSBjaGFycy5sZW5ndGgpIHsKKyAgICAgICAgICAgIC8vIHVuZXhwZWN0ZWQgZW5kIG9mIEROCisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkludmFsaWQgZGlzdGluZ3Vpc2hlZCBuYW1lIHN0cmluZyIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gbWFyayB0aGUgZW5kIG9mIGF0dHJpYnV0ZSB0eXBlCisgICAgICAgIGVuZCA9IHBvczsKKworICAgICAgICAvLyBza2lwIHRyYWlsaW5nIHNwYWNlIGNoYXJzIGJldHdlZW4gYXR0cmlidXRlIHR5cGUgYW5kICc9JworICAgICAgICAvLyAoY29tcGF0aWJpbGl0eSB3aXRoIFJGQyAxNzc5KQorICAgICAgICBpZiAoY2hhcnNbcG9zXSA9PSAnICcpIHsKKyAgICAgICAgICAgIGZvciAoOyBwb3MgPCBjaGFycy5sZW5ndGggJiYgY2hhcnNbcG9zXSAhPSAnPScgJiYgY2hhcnNbcG9zXSA9PSAnICc7IHBvcysrKSB7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChjaGFyc1twb3NdICE9ICc9JyB8fCBwb3MgPT0gY2hhcnMubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgLy8gdW5leHBlY3RlZCBlbmQgb2YgRE4KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkludmFsaWQgZGlzdGluZ3Vpc2hlZCBuYW1lIHN0cmluZyIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcG9zKys7IC8vc2tpcCAnPScgY2hhcgorCisgICAgICAgIC8vIHNraXAgc3BhY2UgY2hhcnMgYmV0d2VlbiAnPScgYW5kIGF0dHJpYnV0ZSB2YWx1ZQorICAgICAgICAvLyAoY29tcGF0aWJpbGl0eSB3aXRoIFJGQyAxNzc5KQorICAgICAgICBmb3IgKDsgcG9zIDwgY2hhcnMubGVuZ3RoICYmIGNoYXJzW3Bvc10gPT0gJyAnOyBwb3MrKykgeworICAgICAgICB9CisKKyAgICAgICAgLy8gaW4gY2FzZSBvZiBvaWQgYXR0cmlidXRlIHR5cGUgc2tpcCBpdHMgcHJlZml4OiAib2lkLiIgb3IgIk9JRC4iCisgICAgICAgIC8vIChjb21wYXRpYmlsaXR5IHdpdGggUkZDIDE3NzkpCisgICAgICAgIGlmICgoZW5kIC0gYmVnID4gNCkgJiYgKGNoYXJzW2JlZyArIDNdID09ICcuJykKKyAgICAgICAgICAgICAgICAmJiAoY2hhcnNbYmVnXSA9PSAnTycgfHwgY2hhcnNbYmVnXSA9PSAnbycpCisgICAgICAgICAgICAgICAgJiYgKGNoYXJzW2JlZyArIDFdID09ICdJJyB8fCBjaGFyc1tiZWcgKyAxXSA9PSAnaScpCisgICAgICAgICAgICAgICAgJiYgKGNoYXJzW2JlZyArIDJdID09ICdEJyB8fCBjaGFyc1tiZWcgKyAyXSA9PSAnZCcpKSB7CisgICAgICAgICAgICBiZWcgKz0gNDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGNoYXJzLCBiZWcsIGVuZCAtIGJlZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHF1b3RlZCBhdHRyaWJ1dGUgdmFsdWU6IFFVT1RBVElPTiAqKCBxdW90ZWNoYXIgLyBwYWlyICkgUVVPVEFUSU9OCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgcXVvdGVkQVYoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBwb3MrKzsKKyAgICAgICAgYmVnID0gcG9zOworICAgICAgICBlbmQgPSBiZWc7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBpZiAocG9zID09IGNoYXJzLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIC8vIHVuZXhwZWN0ZWQgZW5kIG9mIEROCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbnZhbGlkIGRpc3Rpbmd1aXNoZWQgbmFtZSBzdHJpbmciKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGNoYXJzW3Bvc10gPT0gJyInKSB7CisgICAgICAgICAgICAgICAgLy8gZW5jbG9zaW5nIHF1b3RhdGlvbiB3YXMgZm91bmQKKyAgICAgICAgICAgICAgICBwb3MrKzsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hhcnNbcG9zXSA9PSAnXFwnKSB7CisgICAgICAgICAgICAgICAgY2hhcnNbZW5kXSA9IGdldEVzY2FwZWQoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gc2hpZnQgY2hhcjogcmVxdWlyZWQgZm9yIHN0cmluZyB3aXRoIGVzY2FwZWQgY2hhcnMKKyAgICAgICAgICAgICAgICBjaGFyc1tlbmRdID0gY2hhcnNbcG9zXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBvcysrOworICAgICAgICAgICAgZW5kKys7CisgICAgICAgIH0KKworICAgICAgICAvLyBza2lwIHRyYWlsaW5nIHNwYWNlIGNoYXJzIGJlZm9yZSBjb21tYSBvciBzZW1pY29sb24uCisgICAgICAgIC8vIChjb21wYXRpYmlsaXR5IHdpdGggUkZDIDE3NzkpCisgICAgICAgIGZvciAoOyBwb3MgPCBjaGFycy5sZW5ndGggJiYgY2hhcnNbcG9zXSA9PSAnICc7IHBvcysrKSB7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhjaGFycywgYmVnLCBlbmQgLSBiZWcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBoZXggc3RyaW5nIGF0dHJpYnV0ZSB2YWx1ZTogIiMiIGhleHN0cmluZworICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGhleEFWKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBvcyArIDQgPj0gY2hhcnMubGVuZ3RoKSB7CisgICAgICAgICAgICAvLyBlbmNvZGVkIGJ5dGUgYXJyYXkgIG11c3QgYmUgbm90IGxlc3MgdGhlbiA0IGMKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW52YWxpZCBkaXN0aW5ndWlzaGVkIG5hbWUgc3RyaW5nIik7CisgICAgICAgIH0KKworICAgICAgICBiZWcgPSBwb3M7IC8vIHN0b3JlICcjJyBwb3NpdGlvbgorICAgICAgICBwb3MrKzsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIC8vIGNoZWNrIGZvciBlbmQgb2YgYXR0cmlidXRlIHZhbHVlCisgICAgICAgICAgICAvLyBsb29rcyBmb3Igc3BhY2UgYW5kIGNvbXBvbmVudCBzZXBhcmF0b3JzCisgICAgICAgICAgICBpZiAocG9zID09IGNoYXJzLmxlbmd0aCB8fCBjaGFyc1twb3NdID09ICcrJyB8fCBjaGFyc1twb3NdID09ICcsJworICAgICAgICAgICAgICAgICAgICB8fCBjaGFyc1twb3NdID09ICc7JykgeworICAgICAgICAgICAgICAgIGVuZCA9IHBvczsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGNoYXJzW3Bvc10gPT0gJyAnKSB7CisgICAgICAgICAgICAgICAgZW5kID0gcG9zOworICAgICAgICAgICAgICAgIHBvcysrOworICAgICAgICAgICAgICAgIC8vIHNraXAgdHJhaWxpbmcgc3BhY2UgY2hhcnMgYmVmb3JlIGNvbW1hIG9yIHNlbWljb2xvbi4KKyAgICAgICAgICAgICAgICAvLyAoY29tcGF0aWJpbGl0eSB3aXRoIFJGQyAxNzc5KQorICAgICAgICAgICAgICAgIGZvciAoOyBwb3MgPCBjaGFycy5sZW5ndGggJiYgY2hhcnNbcG9zXSA9PSAnICc7IHBvcysrKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfSBlbHNlIGlmIChjaGFyc1twb3NdID49ICdBJyAmJiBjaGFyc1twb3NdIDw9ICdGJykgeworICAgICAgICAgICAgICAgIGNoYXJzW3Bvc10gKz0gMzI7IC8vdG8gbG93IGNhc2UKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcG9zKys7CisgICAgICAgIH0KKworICAgICAgICAvLyB2ZXJpZnkgbGVuZ3RoIG9mIGhleCBzdHJpbmcKKyAgICAgICAgLy8gZW5jb2RlZCBieXRlIGFycmF5ICBtdXN0IGJlIG5vdCBsZXNzIHRoZW4gNCBhbmQgbXVzdCBiZSBldmVuIG51bWJlcgorICAgICAgICBpbnQgaGV4TGVuID0gZW5kIC0gYmVnOyAvLyBza2lwIGZpcnN0ICcjJyBjaGFyCisgICAgICAgIGlmIChoZXhMZW4gPCA1IHx8IChoZXhMZW4gJiAxKSA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkludmFsaWQgZGlzdGluZ3Vpc2hlZCBuYW1lIHN0cmluZyIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gZ2V0IGJ5dGUgZW5jb2RpbmcgZnJvbSBzdHJpbmcgcmVwcmVzZW50YXRpb24KKyAgICAgICAgZW5jb2RlZCA9IG5ldyBieXRlW2hleExlbiAvIDJdOworICAgICAgICBmb3IgKGludCBpID0gMCwgcCA9IGJlZyArIDE7IGkgPCBlbmNvZGVkLmxlbmd0aDsgcCArPSAyLCBpKyspIHsKKyAgICAgICAgICAgIGVuY29kZWRbaV0gPSAoYnl0ZSkgZ2V0Qnl0ZShwKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGNoYXJzLCBiZWcsIGhleExlbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHN0cmluZyBhdHRyaWJ1dGUgdmFsdWU6ICooIHN0cmluZ2NoYXIgLyBwYWlyICkuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZXNjYXBlZEFWKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYmVnID0gcG9zOworICAgICAgICBlbmQgPSBwb3M7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBpZiAocG9zID49IGNoYXJzLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIC8vIHRoZSBlbmQgb2YgRE4gaGFzIGJlZW4gZm91bmQKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhjaGFycywgYmVnLCBlbmQgLSBiZWcpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzd2l0Y2ggKGNoYXJzW3Bvc10pIHsKKyAgICAgICAgICAgIGNhc2UgJysnOgorICAgICAgICAgICAgY2FzZSAnLCc6CisgICAgICAgICAgICBjYXNlICc7JzoKKyAgICAgICAgICAgICAgICAvLyBzZXBhcmF0b3IgY2hhciBoYXMgYmVlZCBmb3VuZAorICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGNoYXJzLCBiZWcsIGVuZCAtIGJlZyk7CisgICAgICAgICAgICBjYXNlICdcXCc6CisgICAgICAgICAgICAgICAgLy8gZXNjYXBlZCBjaGFyCisgICAgICAgICAgICAgICAgY2hhcnNbZW5kKytdID0gZ2V0RXNjYXBlZCgpOworICAgICAgICAgICAgICAgIHBvcysrOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAnICc6CisgICAgICAgICAgICAgICAgLy8gbmVlZCB0byBmaWd1cmUgb3V0IHdoZXRoZXIgc3BhY2UgZGVmaW5lcworICAgICAgICAgICAgICAgIC8vIHRoZSBlbmQgb2YgYXR0cmlidXRlIHZhbHVlIG9yIG5vdAorICAgICAgICAgICAgICAgIGludCBjdXIgPSBlbmQ7CisKKyAgICAgICAgICAgICAgICBwb3MrKzsKKyAgICAgICAgICAgICAgICBjaGFyc1tlbmQrK10gPSAnICc7CisKKyAgICAgICAgICAgICAgICBmb3IgKDsgcG9zIDwgY2hhcnMubGVuZ3RoICYmIGNoYXJzW3Bvc10gPT0gJyAnOyBwb3MrKykgeworICAgICAgICAgICAgICAgICAgICBjaGFyc1tlbmQrK10gPSAnICc7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChwb3MgPT0gY2hhcnMubGVuZ3RoIHx8IGNoYXJzW3Bvc10gPT0gJywnIHx8IGNoYXJzW3Bvc10gPT0gJysnCisgICAgICAgICAgICAgICAgICAgICAgICB8fCBjaGFyc1twb3NdID09ICc7JykgeworICAgICAgICAgICAgICAgICAgICAvLyBzZXBhcmF0b3IgY2hhciBvciB0aGUgZW5kIG9mIEROIGhhcyBiZWVkIGZvdW5kCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGNoYXJzLCBiZWcsIGN1ciAtIGJlZyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICBjaGFyc1tlbmQrK10gPSBjaGFyc1twb3NdOworICAgICAgICAgICAgICAgIHBvcysrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBlc2NhcGVkIGNoYXIKKyAgICAgKi8KKyAgICBwcml2YXRlIGNoYXIgZ2V0RXNjYXBlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHBvcysrOworICAgICAgICBpZiAocG9zID09IGNoYXJzLmxlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbnZhbGlkIGRpc3Rpbmd1aXNoZWQgbmFtZSBzdHJpbmciKTsKKyAgICAgICAgfQorCisgICAgICAgIGNoYXIgY2ggPSBjaGFyc1twb3NdOworICAgICAgICBzd2l0Y2ggKGNoKSB7CisgICAgICAgIGNhc2UgJyInOgorICAgICAgICBjYXNlICdcXCc6CisgICAgICAgICAgICBoYXNRRSA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gY2g7CisgICAgICAgIGNhc2UgJywnOgorICAgICAgICBjYXNlICc9JzoKKyAgICAgICAgY2FzZSAnKyc6CisgICAgICAgIGNhc2UgJzwnOgorICAgICAgICBjYXNlICc+JzoKKyAgICAgICAgY2FzZSAnIyc6CisgICAgICAgIGNhc2UgJzsnOgorICAgICAgICBjYXNlICcgJzoKKyAgICAgICAgY2FzZSAnKic6CisgICAgICAgIGNhc2UgJyUnOgorICAgICAgICBjYXNlICdfJzoKKyAgICAgICAgICAgIC8vRklYTUU6IGVzY2FwaW5nIGlzIGFsbG93ZWQgb25seSBmb3IgbGVhZGluZyBvciB0cmFpbGluZyBzcGFjZSBjaGFyCisgICAgICAgICAgICByZXR1cm4gY2g7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAvLyBSRkMgZG9lc24ndCBleHBsaWNpdGx5IHNheSB0aGF0IGVzY2FwZWQgaGV4IHBhaXIgaXMKKyAgICAgICAgICAgIC8vIGludGVycHJldGVkIGFzIFVURi04IGNoYXIuIEl0IG9ubHkgY29udGFpbnMgYW4gZXhhbXBsZSBvZiBzdWNoIEROLgorICAgICAgICAgICAgcmV0dXJuIGdldFVURjgoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIERlY29kZXMgYSBVVEYtOCBjaGFyLgorICAgICAqLworICAgIHByb3RlY3RlZCBjaGFyIGdldFVURjgoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgcmVzID0gZ2V0Qnl0ZShwb3MpOworICAgICAgICBwb3MrKzsgLy9GSVhNRSB0bXAKKworICAgICAgICBpZiAocmVzIDwgMTI4KSB7IC8vIG9uZSBieXRlOiAwLTdGCisgICAgICAgICAgICByZXR1cm4gKGNoYXIpIHJlczsKKyAgICAgICAgfSBlbHNlIGlmIChyZXMgPj0gMTkyICYmIHJlcyA8PSAyNDcpIHsKKworICAgICAgICAgICAgaW50IGNvdW50OworICAgICAgICAgICAgaWYgKHJlcyA8PSAyMjMpIHsgLy8gdHdvIGJ5dGVzOiBDMC1ERgorICAgICAgICAgICAgICAgIGNvdW50ID0gMTsKKyAgICAgICAgICAgICAgICByZXMgPSByZXMgJiAweDFGOworICAgICAgICAgICAgfSBlbHNlIGlmIChyZXMgPD0gMjM5KSB7IC8vIHRocmVlIGJ5dGVzOiBFMC1FRgorICAgICAgICAgICAgICAgIGNvdW50ID0gMjsKKyAgICAgICAgICAgICAgICByZXMgPSByZXMgJiAweDBGOworICAgICAgICAgICAgfSBlbHNlIHsgLy8gZm91ciBieXRlczogRjAtRjcKKyAgICAgICAgICAgICAgICBjb3VudCA9IDM7CisgICAgICAgICAgICAgICAgcmVzID0gcmVzICYgMHgwNzsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IGI7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgICAgICAgICAgICBwb3MrKzsKKyAgICAgICAgICAgICAgICBpZiAocG9zID09IGNoYXJzLmxlbmd0aCB8fCBjaGFyc1twb3NdICE9ICdcXCcpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDB4M0Y7IC8vRklYTUUgZmFpbGVkIHRvIGRlY29kZSBVVEYtOCBjaGFyIC0gcmV0dXJuICc/JworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBwb3MrKzsKKworICAgICAgICAgICAgICAgIGIgPSBnZXRCeXRlKHBvcyk7CisgICAgICAgICAgICAgICAgcG9zKys7IC8vRklYTUUgdG1wCisgICAgICAgICAgICAgICAgaWYgKChiICYgMHhDMCkgIT0gMHg4MCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gMHgzRjsgLy9GSVhNRSBmYWlsZWQgdG8gZGVjb2RlIFVURi04IGNoYXIgLSByZXR1cm4gJz8nCisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcmVzID0gKHJlcyA8PCA2KSArIChiICYgMHgzRik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gKGNoYXIpIHJlczsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiAweDNGOyAvL0ZJWE1FIGZhaWxlZCB0byBkZWNvZGUgVVRGLTggY2hhciAtIHJldHVybiAnPycKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYnl0ZSByZXByZXNlbnRhdGlvbiBvZiBhIGNoYXIgcGFpcgorICAgICAqIFRoZSBjaGFyIHBhaXIgaXMgY29tcG9zZWQgb2YgRE4gY2hhciBpbgorICAgICAqIHNwZWNpZmllZCAncG9zaXRpb24nIGFuZCB0aGUgbmV4dCBjaGFyCisgICAgICogQWNjb3JkaW5nIHRvIEJORiBzeW50YXg6CisgICAgICogaGV4Y2hhciAgICA9IERJR0lUIC8gIkEiIC8gIkIiIC8gIkMiIC8gIkQiIC8gIkUiIC8gIkYiCisgICAgICogICAgICAgICAgICAgICAgICAgICAvICJhIiAvICJiIiAvICJjIiAvICJkIiAvICJlIiAvICJmIgorICAgICAqLworICAgIHByaXZhdGUgaW50IGdldEJ5dGUoaW50IHBvc2l0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoKHBvc2l0aW9uICsgMSkgPj0gY2hhcnMubGVuZ3RoKSB7CisgICAgICAgICAgICAvLyB0byBhdm9pZCBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW52YWxpZCBkaXN0aW5ndWlzaGVkIG5hbWUgc3RyaW5nIik7CisgICAgICAgIH0KKworICAgICAgICBpbnQgYjEgPSBjaGFyc1twb3NpdGlvbl07CisgICAgICAgIGlmIChiMSA+PSAnMCcgJiYgYjEgPD0gJzknKSB7CisgICAgICAgICAgICBiMSA9IGIxIC0gJzAnOworICAgICAgICB9IGVsc2UgaWYgKGIxID49ICdhJyAmJiBiMSA8PSAnZicpIHsKKyAgICAgICAgICAgIGIxID0gYjEgLSA4NzsgLy8gODcgPSAnYScgLSAxMAorICAgICAgICB9IGVsc2UgaWYgKGIxID49ICdBJyAmJiBiMSA8PSAnRicpIHsKKyAgICAgICAgICAgIGIxID0gYjEgLSA1NTsgLy8gNTUgPSAnQScgLSAxMAorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbnZhbGlkIGRpc3Rpbmd1aXNoZWQgbmFtZSBzdHJpbmciKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCBiMiA9IGNoYXJzW3Bvc2l0aW9uICsgMV07CisgICAgICAgIGlmIChiMiA+PSAnMCcgJiYgYjIgPD0gJzknKSB7CisgICAgICAgICAgICBiMiA9IGIyIC0gJzAnOworICAgICAgICB9IGVsc2UgaWYgKGIyID49ICdhJyAmJiBiMiA8PSAnZicpIHsKKyAgICAgICAgICAgIGIyID0gYjIgLSA4NzsgLy8gODcgPSAnYScgLSAxMAorICAgICAgICB9IGVsc2UgaWYgKGIyID49ICdBJyAmJiBiMiA8PSAnRicpIHsKKyAgICAgICAgICAgIGIyID0gYjIgLSA1NTsgLy8gNTUgPSAnQScgLSAxMAorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbnZhbGlkIGRpc3Rpbmd1aXNoZWQgbmFtZSBzdHJpbmciKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiAoYjEgPDwgNCkgKyBiMjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgRE4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBsaXN0IG9mIFJlbGF0aXZlIERpc3Rpbmd1aXNoZWQgTmFtZXMoUk5EKSwKKyAgICAgKiAgICAgICAgIGVhY2ggUkROIGlzIHJlcHJlc2VudGVkIGFzIGEgbGlzdCBvZiBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgb2JqZWN0cworICAgICAqLworICAgIHB1YmxpYyBMaXN0PExpc3Q8QXR0cmlidXRlVHlwZUFuZFZhbHVlPj4gcGFyc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBMaXN0PExpc3Q8QXR0cmlidXRlVHlwZUFuZFZhbHVlPj4gbGlzdCA9IG5ldyBBcnJheUxpc3Q8TGlzdDxBdHRyaWJ1dGVUeXBlQW5kVmFsdWU+PigpOworCisgICAgICAgIFN0cmluZyBhdHRUeXBlID0gbmV4dEFUKCk7CisgICAgICAgIGlmIChhdHRUeXBlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBsaXN0OyAvL2VtcHR5IGxpc3Qgb2YgUkROcworICAgICAgICB9CisKKyAgICAgICAgTGlzdDxBdHRyaWJ1dGVUeXBlQW5kVmFsdWU+IGF0YXYgPSBuZXcgQXJyYXlMaXN0PEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZT4oKTsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIGlmIChwb3MgPT0gY2hhcnMubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgLy9lbXB0eSBBdHRyaWJ1dGUgVmFsdWUKKyAgICAgICAgICAgICAgICBhdGF2LmFkZChuZXcgQXR0cmlidXRlVHlwZUFuZFZhbHVlKGF0dFR5cGUsIG5ldyBBdHRyaWJ1dGVWYWx1ZSgiIiwgZmFsc2UpKSk7CisgICAgICAgICAgICAgICAgbGlzdC5hZGQoMCwgYXRhdik7CisgICAgICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHN3aXRjaCAoY2hhcnNbcG9zXSkgeworICAgICAgICAgICAgY2FzZSAnIic6CisgICAgICAgICAgICAgICAgYXRhdi5hZGQobmV3IEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZShhdHRUeXBlLCBuZXcgQXR0cmlidXRlVmFsdWUocXVvdGVkQVYoKSwgaGFzUUUpKSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICcjJzoKKyAgICAgICAgICAgICAgICBhdGF2LmFkZChuZXcgQXR0cmlidXRlVHlwZUFuZFZhbHVlKGF0dFR5cGUsIG5ldyBBdHRyaWJ1dGVWYWx1ZShoZXhBVigpLCBlbmNvZGVkKSkpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAnKyc6CisgICAgICAgICAgICBjYXNlICcsJzoKKyAgICAgICAgICAgIGNhc2UgJzsnOiAvLyBjb21wYXRpYmlsaXR5IHdpdGggUkZDIDE3Nzk6IHNlbWljb2xvbiBjYW4gc2VwYXJhdGUgUkROcworICAgICAgICAgICAgICAgIC8vZW1wdHkgYXR0cmlidXRlIHZhbHVlCisgICAgICAgICAgICAgICAgYXRhdi5hZGQobmV3IEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZShhdHRUeXBlLCBuZXcgQXR0cmlidXRlVmFsdWUoIiIsIGZhbHNlKSkpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICBhdGF2LmFkZChuZXcgQXR0cmlidXRlVHlwZUFuZFZhbHVlKGF0dFR5cGUsIG5ldyBBdHRyaWJ1dGVWYWx1ZSgKKyAgICAgICAgICAgICAgICAgICAgICAgIGVzY2FwZWRBVigpLCBoYXNRRSkpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHBvcyA+PSBjaGFycy5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBsaXN0LmFkZCgwLCBhdGF2KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbGlzdDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGNoYXJzW3Bvc10gPT0gJywnIHx8IGNoYXJzW3Bvc10gPT0gJzsnKSB7CisgICAgICAgICAgICAgICAgbGlzdC5hZGQoMCwgYXRhdik7CisgICAgICAgICAgICAgICAgYXRhdiA9IG5ldyBBcnJheUxpc3Q8QXR0cmlidXRlVHlwZUFuZFZhbHVlPigpOworICAgICAgICAgICAgfSBlbHNlIGlmIChjaGFyc1twb3NdICE9ICcrJykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW52YWxpZCBkaXN0aW5ndWlzaGVkIG5hbWUgc3RyaW5nIik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHBvcysrOworICAgICAgICAgICAgYXR0VHlwZSA9IG5leHRBVCgpOworICAgICAgICAgICAgaWYgKGF0dFR5cGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW52YWxpZCBkaXN0aW5ndWlzaGVkIG5hbWUgc3RyaW5nIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvRGlzdHJpYnV0aW9uUG9pbnQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9EaXN0cmlidXRpb25Qb2ludC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4MmQ0YTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvRGlzdHJpYnV0aW9uUG9pbnQuamF2YQpAQCAtMCwwICsxLDEyOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xRXhwbGljaXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUltcGxpY2l0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXF1ZW5jZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKKworLyoqCisgKiBUaGUgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBBU04uMSBERVIgZW5jb2RpbmcvZGVjb2Rpbmcgd29yaworICogd2l0aCB0aGUgRGlzdHJpYnV0aW9uUG9pbnQgc3RydWN0dXJlIHdoaWNoIGlzIHRoZSBwYXJ0IG9mIFguNTA5IENSTAorICogKGFzIHNwZWNpZmllZCBpbiBSRkMgMzI4MCAtCisgKiAgSW50ZXJuZXQgWC41MDkgUHVibGljIEtleSBJbmZyYXN0cnVjdHVyZS4KKyAqICBDZXJ0aWZpY2F0ZSBhbmQgQ2VydGlmaWNhdGUgUmV2b2NhdGlvbiBMaXN0IChDUkwpIFByb2ZpbGUuCisgKiAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpOgorICoKKyAqIDxwcmU+CisgKiAgQ1JMRGlzdHJpYnV0aW9uUG9pbnRzIDo6PSBTRVFVRU5DRSBTSVpFICgxLi5NQVgpIE9GIERpc3RyaWJ1dGlvblBvaW50CisgKgorICogIERpc3RyaWJ1dGlvblBvaW50IDo6PSBTRVFVRU5DRSB7CisgKiAgICAgICAgZGlzdHJpYnV0aW9uUG9pbnQgICAgICAgWzBdICAgICBEaXN0cmlidXRpb25Qb2ludE5hbWUgT1BUSU9OQUwsCisgKiAgICAgICAgcmVhc29ucyAgICAgICAgICAgICAgICAgWzFdICAgICBSZWFzb25GbGFncyBPUFRJT05BTCwKKyAqICAgICAgICBjUkxJc3N1ZXIgICAgICAgICAgICAgICBbMl0gICAgIEdlbmVyYWxOYW1lcyBPUFRJT05BTAorICogIH0KKyAqCisgKiAgRGlzdHJpYnV0aW9uUG9pbnROYW1lIDo6PSBDSE9JQ0UgeworICogICAgICAgIGZ1bGxOYW1lICAgICAgICAgICAgICAgIFswXSAgICAgR2VuZXJhbE5hbWVzLAorICogICAgICAgIG5hbWVSZWxhdGl2ZVRvQ1JMSXNzdWVyIFsxXSAgICAgUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZQorICogIH0KKyAqCisgKiAgUmVhc29uRmxhZ3MgOjo9IEJJVCBTVFJJTkcgeworICogICAgICAgIHVudXNlZCAgICAgICAgICAgICAgICAgICgwKSwKKyAqICAgICAgICBrZXlDb21wcm9taXNlICAgICAgICAgICAoMSksCisgKiAgICAgICAgY0FDb21wcm9taXNlICAgICAgICAgICAgKDIpLAorICogICAgICAgIGFmZmlsaWF0aW9uQ2hhbmdlZCAgICAgICgzKSwKKyAqICAgICAgICBzdXBlcnNlZGVkICAgICAgICAgICAgICAoNCksCisgKiAgICAgICAgY2Vzc2F0aW9uT2ZPcGVyYXRpb24gICAgKDUpLAorICogICAgICAgIGNlcnRpZmljYXRlSG9sZCAgICAgICAgICg2KSwKKyAqICAgICAgICBwcml2aWxlZ2VXaXRoZHJhd24gICAgICAoNyksCisgKiAgICAgICAgYUFDb21wcm9taXNlICAgICAgICAgICAgKDgpCisgKiAgfQorICogPC9wcmU+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBEaXN0cmlidXRpb25Qb2ludCB7CisgICAgcHJpdmF0ZSBmaW5hbCBEaXN0cmlidXRpb25Qb2ludE5hbWUgZGlzdHJpYnV0aW9uUG9pbnQ7CisgICAgcHJpdmF0ZSBmaW5hbCBSZWFzb25GbGFncyByZWFzb25zOworICAgIHByaXZhdGUgZmluYWwgR2VuZXJhbE5hbWVzIGNSTElzc3VlcjsKKworICAgIHB1YmxpYyBEaXN0cmlidXRpb25Qb2ludChEaXN0cmlidXRpb25Qb2ludE5hbWUgZGlzdHJpYnV0aW9uUG9pbnQsCisgICAgICAgICAgICBSZWFzb25GbGFncyByZWFzb25zLCBHZW5lcmFsTmFtZXMgY1JMSXNzdWVyKSB7CisgICAgICAgIGlmICgocmVhc29ucyAhPSBudWxsKSAmJiAoZGlzdHJpYnV0aW9uUG9pbnQgPT0gbnVsbCkgJiYgKGNSTElzc3VlciA9PSBudWxsKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRGlzdHJpYnV0aW9uUG9pbnQgTVVTVCBOT1QgY29uc2lzdCBvZiBvbmx5IHRoZSByZWFzb25zIGZpZWxkIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5kaXN0cmlidXRpb25Qb2ludCA9IGRpc3RyaWJ1dGlvblBvaW50OworICAgICAgICB0aGlzLnJlYXNvbnMgPSByZWFzb25zOworICAgICAgICB0aGlzLmNSTElzc3VlciA9IGNSTElzc3VlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBkdW1wVmFsdWUoU3RyaW5nQnVpbGRlciBzYiwgU3RyaW5nIHByZWZpeCkgeworICAgICAgICBzYi5hcHBlbmQocHJlZml4KTsKKyAgICAgICAgc2IuYXBwZW5kKCJEaXN0cmlidXRpb24gUG9pbnQ6IFtcbiIpOworICAgICAgICBpZiAoZGlzdHJpYnV0aW9uUG9pbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgZGlzdHJpYnV0aW9uUG9pbnQuZHVtcFZhbHVlKHNiLCBwcmVmaXggKyAiICAiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocmVhc29ucyAhPSBudWxsKSB7CisgICAgICAgICAgICByZWFzb25zLmR1bXBWYWx1ZShzYiwgcHJlZml4ICsgIiAgIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNSTElzc3VlciAhPSBudWxsKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQocHJlZml4KTsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiICBDUkwgSXNzdWVyOiBbXG4iKTsKKyAgICAgICAgICAgIGNSTElzc3Vlci5kdW1wVmFsdWUoc2IsIHByZWZpeCArICIgICAgIik7CisgICAgICAgICAgICBzYi5hcHBlbmQocHJlZml4KTsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiICBdXG4iKTsKKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQocHJlZml4KTsKKyAgICAgICAgc2IuYXBwZW5kKCJdXG4iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDdXN0b20gWC41MDkgZGVjb2Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZShuZXcgQVNOMVR5cGVbXSB7CisgICAgICAgICAgICAgICAgbmV3IEFTTjFFeHBsaWNpdCgwLCBEaXN0cmlidXRpb25Qb2ludE5hbWUuQVNOMSksCisgICAgICAgICAgICAgICAgbmV3IEFTTjFJbXBsaWNpdCgxLCBSZWFzb25GbGFncy5BU04xKSwKKyAgICAgICAgICAgICAgICBuZXcgQVNOMUltcGxpY2l0KDIsIEdlbmVyYWxOYW1lcy5BU04xKQorICAgICAgICAgICAgfSkgeworICAgICAgICB7CisgICAgICAgICAgICBzZXRPcHRpb25hbCgwKTsKKyAgICAgICAgICAgIHNldE9wdGlvbmFsKDEpOworICAgICAgICAgICAgc2V0T3B0aW9uYWwoMik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgT2JqZWN0W10gdmFsdWVzID0gKE9iamVjdFtdKSBpbi5jb250ZW50OworICAgICAgICAgICAgcmV0dXJuIG5ldyBEaXN0cmlidXRpb25Qb2ludCgoRGlzdHJpYnV0aW9uUG9pbnROYW1lKSB2YWx1ZXNbMF0sCisgICAgICAgICAgICAgICAgICAgIChSZWFzb25GbGFncykgdmFsdWVzWzFdLCAoR2VuZXJhbE5hbWVzKSB2YWx1ZXNbMl0pOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKyAgICAgICAgICAgIERpc3RyaWJ1dGlvblBvaW50IGRwID0gKERpc3RyaWJ1dGlvblBvaW50KSBvYmplY3Q7CisgICAgICAgICAgICB2YWx1ZXNbMF0gPSBkcC5kaXN0cmlidXRpb25Qb2ludDsKKyAgICAgICAgICAgIHZhbHVlc1sxXSA9IGRwLnJlYXNvbnM7CisgICAgICAgICAgICB2YWx1ZXNbMl0gPSBkcC5jUkxJc3N1ZXI7CisgICAgICAgIH0KKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0Rpc3RyaWJ1dGlvblBvaW50TmFtZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0Rpc3RyaWJ1dGlvblBvaW50TmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg5M2MyY2UKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvRGlzdHJpYnV0aW9uUG9pbnROYW1lLmphdmEKQEAgLTAsMCArMSwxMjcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUNob2ljZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xSW1wbGljaXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVR5cGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQmVySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDEuTmFtZTsKKworLyoqCisgKiBUaGUgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBBU04uMSBERVIgZW5jb2RpbmcvZGVjb2Rpbmcgd29yaworICogd2l0aCB0aGUgRGlzdHJpYnV0aW9uUG9pbnROYW1lIHN0cnVjdHVyZSB3aGljaCBpcyB0aGUgcGFydAorICogb2YgWC41MDkgQ1JMCisgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIC0KKyAqICBJbnRlcm5ldCBYLjUwOSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgorICogIENlcnRpZmljYXRlIGFuZCBDZXJ0aWZpY2F0ZSBSZXZvY2F0aW9uIExpc3QgKENSTCkgUHJvZmlsZS4KKyAqICBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCk6CisgKgorICogPHByZT4KKyAqICBDUkxEaXN0cmlidXRpb25Qb2ludHMgOjo9IFNFUVVFTkNFIFNJWkUgKDEuLk1BWCkgT0YgRGlzdHJpYnV0aW9uUG9pbnQKKyAqCisgKiAgRGlzdHJpYnV0aW9uUG9pbnQgOjo9IFNFUVVFTkNFIHsKKyAqICAgICAgICBkaXN0cmlidXRpb25Qb2ludCAgICAgICBbMF0gICAgIERpc3RyaWJ1dGlvblBvaW50TmFtZSBPUFRJT05BTCwKKyAqICAgICAgICByZWFzb25zICAgICAgICAgICAgICAgICBbMV0gICAgIFJlYXNvbkZsYWdzIE9QVElPTkFMLAorICogICAgICAgIGNSTElzc3VlciAgICAgICAgICAgICAgIFsyXSAgICAgR2VuZXJhbE5hbWVzIE9QVElPTkFMCisgKiAgfQorICoKKyAqICBEaXN0cmlidXRpb25Qb2ludE5hbWUgOjo9IENIT0lDRSB7CisgKiAgICAgICAgZnVsbE5hbWUgICAgICAgICAgICAgICAgWzBdICAgICBHZW5lcmFsTmFtZXMsCisgKiAgICAgICAgbmFtZVJlbGF0aXZlVG9DUkxJc3N1ZXIgWzFdICAgICBSZWxhdGl2ZURpc3Rpbmd1aXNoZWROYW1lCisgKiAgfQorICoKKyAqICBSZWFzb25GbGFncyA6Oj0gQklUIFNUUklORyB7CisgKiAgICAgICAgdW51c2VkICAgICAgICAgICAgICAgICAgKDApLAorICogICAgICAgIGtleUNvbXByb21pc2UgICAgICAgICAgICgxKSwKKyAqICAgICAgICBjQUNvbXByb21pc2UgICAgICAgICAgICAoMiksCisgKiAgICAgICAgYWZmaWxpYXRpb25DaGFuZ2VkICAgICAgKDMpLAorICogICAgICAgIHN1cGVyc2VkZWQgICAgICAgICAgICAgICg0KSwKKyAqICAgICAgICBjZXNzYXRpb25PZk9wZXJhdGlvbiAgICAoNSksCisgKiAgICAgICAgY2VydGlmaWNhdGVIb2xkICAgICAgICAgKDYpLAorICogICAgICAgIHByaXZpbGVnZVdpdGhkcmF3biAgICAgICg3KSwKKyAqICAgICAgICBhQUNvbXByb21pc2UgICAgICAgICAgICAoOCkKKyAqICB9CisgKiA8L3ByZT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIERpc3RyaWJ1dGlvblBvaW50TmFtZSB7CisgICAgcHJpdmF0ZSBmaW5hbCBHZW5lcmFsTmFtZXMgZnVsbE5hbWU7CisgICAgcHJpdmF0ZSBmaW5hbCBOYW1lIG5hbWVSZWxhdGl2ZVRvQ1JMSXNzdWVyOworCisgICAgcHVibGljIERpc3RyaWJ1dGlvblBvaW50TmFtZShHZW5lcmFsTmFtZXMgZnVsbE5hbWUpIHsKKyAgICAgICAgdGhpcy5mdWxsTmFtZSA9IGZ1bGxOYW1lOworICAgICAgICB0aGlzLm5hbWVSZWxhdGl2ZVRvQ1JMSXNzdWVyID0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgRGlzdHJpYnV0aW9uUG9pbnROYW1lKE5hbWUgbmFtZVJlbGF0aXZlVG9DUkxJc3N1ZXIpIHsKKyAgICAgICAgdGhpcy5mdWxsTmFtZSA9IG51bGw7CisgICAgICAgIHRoaXMubmFtZVJlbGF0aXZlVG9DUkxJc3N1ZXIgPSBuYW1lUmVsYXRpdmVUb0NSTElzc3VlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBkdW1wVmFsdWUoU3RyaW5nQnVpbGRlciBzYiwgU3RyaW5nIHByZWZpeCkgeworICAgICAgICBzYi5hcHBlbmQocHJlZml4KTsKKyAgICAgICAgc2IuYXBwZW5kKCJEaXN0cmlidXRpb24gUG9pbnQgTmFtZTogW1xuIik7CisgICAgICAgIGlmIChmdWxsTmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICBmdWxsTmFtZS5kdW1wVmFsdWUoc2IsIHByZWZpeCArICIgICIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc2IuYXBwZW5kKHByZWZpeCk7CisgICAgICAgICAgICBzYi5hcHBlbmQoIiAgIik7CisgICAgICAgICAgICBzYi5hcHBlbmQobmFtZVJlbGF0aXZlVG9DUkxJc3N1ZXIuZ2V0TmFtZShYNTAwUHJpbmNpcGFsLlJGQzIyNTMpKTsKKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQocHJlZml4KTsKKyAgICAgICAgc2IuYXBwZW5kKCJdXG4iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFDaG9pY2UgQVNOMSA9IG5ldyBBU04xQ2hvaWNlKG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgIG5ldyBBU04xSW1wbGljaXQoMCwgR2VuZXJhbE5hbWVzLkFTTjEpLAorICAgICAgICAgICAgbmV3IEFTTjFJbXBsaWNpdCgxLCBOYW1lLkFTTjFfUkROKSB9KSB7CisKKyAgICAgICAgcHVibGljIGludCBnZXRJbmRleChqYXZhLmxhbmcuT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgRGlzdHJpYnV0aW9uUG9pbnROYW1lIGRwbiA9IChEaXN0cmlidXRpb25Qb2ludE5hbWUpIG9iamVjdDsKKyAgICAgICAgICAgIHJldHVybiAoZHBuLmZ1bGxOYW1lID09IG51bGwpID8gMSA6IDA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgRGlzdHJpYnV0aW9uUG9pbnROYW1lIHJlc3VsdCA9IG51bGw7CisgICAgICAgICAgICBpZiAoaW4uY2hvaWNlSW5kZXggPT0gMCkgeworICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBEaXN0cmlidXRpb25Qb2ludE5hbWUoKEdlbmVyYWxOYW1lcykgaW4uY29udGVudCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIG5vdGU6IEFTTi4xIGRlY29kZXIgd2lsbCByZXBvcnQgYW4gZXJyb3IgaWYgaW5kZXgKKyAgICAgICAgICAgICAgICAvLyBpcyBuZWl0aGVyIDAgb3IgMQorICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBEaXN0cmlidXRpb25Qb2ludE5hbWUoKE5hbWUpIGluLmNvbnRlbnQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0T2JqZWN0VG9FbmNvZGUoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgRGlzdHJpYnV0aW9uUG9pbnROYW1lIGRwbiA9IChEaXN0cmlidXRpb25Qb2ludE5hbWUpIG9iamVjdDsKKyAgICAgICAgICAgIGlmIChkcG4uZnVsbE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBkcG4ubmFtZVJlbGF0aXZlVG9DUkxJc3N1ZXI7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBkcG4uZnVsbE5hbWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0VESVBhcnR5TmFtZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0VESVBhcnR5TmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ2NGU2NWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvRURJUGFydHlOYW1lLmphdmEKQEAgLTAsMCArMSwxMDIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFFeHBsaWNpdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2VxdWVuY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVR5cGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQmVySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDEuRGlyZWN0b3J5U3RyaW5nOworCisvKioKKyAqIFRoZSBjbGFzcyBlbmNhcHN1bGF0ZXMgdGhlIEFTTi4xIERFUiBlbmNvZGluZy9kZWNvZGluZyB3b3JrCisgKiB3aXRoIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlIHdoaWNoIGlzIGEgc3VicGFydCBvZiBHZW5lcmFsTmFtZQorICogKGFzIHNwZWNpZmllZCBpbiBSRkMgMzI4MCAtCisgKiAgSW50ZXJuZXQgWC41MDkgUHVibGljIEtleSBJbmZyYXN0cnVjdHVyZS4KKyAqICBDZXJ0aWZpY2F0ZSBhbmQgQ2VydGlmaWNhdGUgUmV2b2NhdGlvbiBMaXN0IChDUkwpIFByb2ZpbGUuCisgKiAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpOgorICoKKyAqIDxwcmU+CisgKiAgIEVESVBhcnR5TmFtZSA6Oj0gU0VRVUVOQ0UgeworICogICAgICAgIG5hbWVBc3NpZ25lciAgICAgICAgICAgIFswXSAgICAgRGlyZWN0b3J5U3RyaW5nIE9QVElPTkFMLAorICogICAgICAgIHBhcnR5TmFtZSAgICAgICAgICAgICAgIFsxXSAgICAgRGlyZWN0b3J5U3RyaW5nCisgKiAgIH0KKyAqCisgKiAgIERpcmVjdG9yeVN0cmluZyA6Oj0gQ0hPSUNFIHsKKyAqICAgICAgICB0ZWxldGV4U3RyaW5nICAgICAgICAgICAgIFRlbGV0ZXhTdHJpbmcgICAoU0laRSAoMS4uTUFYKSksCisgKiAgICAgICAgcHJpbnRhYmxlU3RyaW5nICAgICAgICAgICBQcmludGFibGVTdHJpbmcgKFNJWkUgKDEuLk1BWCkpLAorICogICAgICAgIHVuaXZlcnNhbFN0cmluZyAgICAgICAgICAgVW5pdmVyc2FsU3RyaW5nIChTSVpFICgxLi5NQVgpKSwKKyAqICAgICAgICB1dGY4U3RyaW5nICAgICAgICAgICAgICBVVEY4U3RyaW5nICAgICAgKFNJWkUgKDEuLk1BWCkpLAorICogICAgICAgIGJtcFN0cmluZyAgICAgICAgICAgICAgIEJNUFN0cmluZyAgICAgICAoU0laRSAoMS4uTUFYKSkKKyAqICAgfQorICogPC9wcmU+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBFRElQYXJ0eU5hbWUgeworICAgIC8qKiB0aGUgdmFsdWUgb2YgbmFtZUFzc2lnbmVyIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBuYW1lQXNzaWduZXI7CisgICAgLyoqIHRoZSB2YWx1ZSBvZiBwYXJ0eU5hbWUgZmllbGQgb2YgdGhlIHN0cnVjdHVyZSAqLworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHBhcnR5TmFtZTsKKyAgICAvKiogdGhlIEFTTi4xIGVuY29kZWQgZm9ybSBvZiBFRElQYXJ0eU5hbWUgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGluZzsKKworICAgIHByaXZhdGUgRURJUGFydHlOYW1lKFN0cmluZyBuYW1lQXNzaWduZXIsIFN0cmluZyBwYXJ0eU5hbWUsIGJ5dGVbXSBlbmNvZGluZykgeworICAgICAgICB0aGlzLm5hbWVBc3NpZ25lciA9IG5hbWVBc3NpZ25lcjsKKyAgICAgICAgdGhpcy5wYXJ0eU5hbWUgPSBwYXJ0eU5hbWU7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFTTi4xIGVuY29kZWQgZm9ybSBvZiB0aGlzIFguNTA5IEVESVBhcnR5TmFtZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBU04uMSBERVIgWC41MDkgRURJUGFydHlOYW1lIGVuY29kZXIvZGVjb2RlciBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZSgKKyAgICAgICAgICAgIG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgICAgICBuZXcgQVNOMUV4cGxpY2l0KDAsIERpcmVjdG9yeVN0cmluZy5BU04xKSwKKyAgICAgICAgICAgICAgICBuZXcgQVNOMUV4cGxpY2l0KDEsIERpcmVjdG9yeVN0cmluZy5BU04xKQorICAgICAgICAgICAgfSkgeworICAgICAgICB7CisgICAgICAgICAgICBzZXRPcHRpb25hbCgwKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgICAgIE9iamVjdFtdIHZhbHVlcyA9IChPYmplY3RbXSkgaW4uY29udGVudDsKKyAgICAgICAgICAgIHJldHVybiBuZXcgRURJUGFydHlOYW1lKChTdHJpbmcpIHZhbHVlc1swXSwgKFN0cmluZykgdmFsdWVzWzFdLAorICAgICAgICAgICAgICAgICAgICBpbi5nZXRFbmNvZGVkKCkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKyAgICAgICAgICAgIEVESVBhcnR5TmFtZSBlcG4gPSAoRURJUGFydHlOYW1lKSBvYmplY3Q7CisgICAgICAgICAgICB2YWx1ZXNbMF0gPSBlcG4ubmFtZUFzc2lnbmVyOworICAgICAgICAgICAgdmFsdWVzWzFdID0gZXBuLnBhcnR5TmFtZTsKKyAgICAgICAgfQorICAgIH07Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvRXh0ZW5kZWRLZXlVc2FnZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0V4dGVuZGVkS2V5VXNhZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YTkxNTAzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0V4dGVuZGVkS2V5VXNhZ2UuamF2YQpAQCAtMCwwICsxLDEwMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFPaWQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlT2Y7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVR5cGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQmVySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuT2JqZWN0SWRlbnRpZmllcjsKKworLyoqCisgKiBFeHRlbmRlZCBLZXkgVXNhZ2UgRXh0ZW5zaW9uIChPSUQgPT0gMi41LjI5LjM3KS4KKyAqCisgKiBUaGUgQVNOLjEgZGVmaW5pdGlvbiBmb3IgRXh0ZW5kZWQgS2V5IFVzYWdlIEV4dGVuc2lvbiBpczoKKyAqCisgKiA8cHJlPgorICogIGlkLWNlLWV4dEtleVVzYWdlIE9CSkVDVCBJREVOVElGSUVSIDo6PSB7IGlkLWNlIDM3IH0KKyAqCisgKiAgRXh0S2V5VXNhZ2VTeW50YXggOjo9IFNFUVVFTkNFIFNJWkUgKDEuLk1BWCkgT0YgS2V5UHVycG9zZUlkCisgKgorICogIEtleVB1cnBvc2VJZCA6Oj0gT0JKRUNUIElERU5USUZJRVIKKyAqIDwvcHJlPgorICogKGFzIHNwZWNpZmllZCBpbiBSRkMgMzI4MCAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEV4dGVuZGVkS2V5VXNhZ2UgZXh0ZW5kcyBFeHRlbnNpb25WYWx1ZSB7CisKKyAgICAvLyB0aGUgdmFsdWUgb2YgZXh0ZW5zaW9uCisgICAgcHJpdmF0ZSBMaXN0PFN0cmluZz4ga2V5czsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIGV4dGVuc2lvbiBvYmplY3Qgb24gdGhlIGJhc2Ugb2YgaXRzIGVuY29kZWQgZm9ybS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRXh0ZW5kZWRLZXlVc2FnZShieXRlW10gZW5jb2RpbmcpIHsKKyAgICAgICAgc3VwZXIoZW5jb2RpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxpc3Qgb2Ygc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIE9JRHMgY29ycmVzcG9uZGluZworICAgICAqIHRvIGtleSBwdXJwb3NlIElEcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxTdHJpbmc+IGdldEV4dGVuZGVkS2V5VXNhZ2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoa2V5cyA9PSBudWxsKSB7CisgICAgICAgICAgICBrZXlzID0gKExpc3Q8U3RyaW5nPikgQVNOMS5kZWNvZGUoZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4ga2V5czsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSBBU04xLmVuY29kZShrZXlzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGR1bXBWYWx1ZShTdHJpbmdCdWlsZGVyIHNiLCBTdHJpbmcgcHJlZml4KSB7CisgICAgICAgIHNiLmFwcGVuZChwcmVmaXgpLmFwcGVuZCgiRXh0ZW5kZWQgS2V5IFVzYWdlOiAiKTsKKyAgICAgICAgaWYgKGtleXMgPT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlzID0gZ2V0RXh0ZW5kZWRLZXlVc2FnZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGluY29ycmVjdCBleHRlbnNpb24gdmFsdWUgZW5jb2RpbmcKKyAgICAgICAgICAgICAgICBzdXBlci5kdW1wVmFsdWUoc2IpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQoJ1snKTsKKyAgICAgICAgZm9yIChJdGVyYXRvcjw/PiBpdCA9IGtleXMuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOykgeworICAgICAgICAgICAgc2IuYXBwZW5kKCIgXCIiKS5hcHBlbmQoaXQubmV4dCgpKS5hcHBlbmQoJyInKTsKKyAgICAgICAgICAgIGlmIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoJywnKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQoIiBdXG4iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBU04uMSBFbmNvZGVyL0RlY29kZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xVHlwZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZU9mKG5ldyBBU04xT2lkKCkgeworICAgICAgICBwdWJsaWMgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpbnRbXSBvaWQgPSAoaW50W10pIHN1cGVyLmdldERlY29kZWRPYmplY3QoaW4pOworICAgICAgICAgICAgcmV0dXJuIE9iamVjdElkZW50aWZpZXIudG9TdHJpbmcob2lkKTsKKyAgICAgICAgfQorICAgIH0pOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0V4dGVuc2lvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0V4dGVuc2lvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU1MDExZTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvRXh0ZW5zaW9uLmphdmEKQEAgLTAsMCArMSwzOTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xQm9vbGVhbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xT2N0ZXRTdHJpbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMU9pZDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2VxdWVuY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVR5cGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQmVySW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuT2JqZWN0SWRlbnRpZmllcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudXRpbHMuQXJyYXk7CisKKy8qKgorICogVGhlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgQVNOLjEgREVSIGVuY29kaW5nL2RlY29kaW5nIHdvcmsKKyAqIHdpdGggdGhlIEV4dGVuc2lvbiBwYXJ0IG9mIFguNTA5IGNlcnRpZmljYXRlCisgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIC0KKyAqICBJbnRlcm5ldCBYLjUwOSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgorICogIENlcnRpZmljYXRlIGFuZCBDZXJ0aWZpY2F0ZSBSZXZvY2F0aW9uIExpc3QgKENSTCkgUHJvZmlsZS4KKyAqICBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCk6CisgKgorICogPHByZT4KKyAqICBFeHRlbnNpb24gIDo6PSAgU0VRVUVOQ0UgIHsKKyAqICAgICAgIGV4dG5JRCAgICAgIE9CSkVDVCBJREVOVElGSUVSLAorICogICAgICAgY3JpdGljYWwgICAgQk9PTEVBTiBERUZBVUxUIEZBTFNFLAorICogICAgICAgZXh0blZhbHVlICAgT0NURVQgU1RSSU5HCisgKiAgfQorICogPC9wcmU+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBFeHRlbnNpb24geworICAgIC8vIGNyaXRpY2FsIGNvbnN0YW50cworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYm9vbGVhbiBDUklUSUNBTCA9IHRydWU7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBib29sZWFuIE5PTl9DUklUSUNBTCA9IGZhbHNlOworCisgICAgLy8gY29uc3RhbnRzOiB0aGUgZXh0ZW5zaW9uIE9JRHMKKyAgICAvLyBjZXJ0aWZpY2F0ZSBleHRlbnNpb25zOgorICAgIHN0YXRpYyBmaW5hbCBpbnRbXSBTVUJKX0RJUkVDVE9SWV9BVFRSUyA9IHsyLCA1LCAyOSwgOX07CisgICAgc3RhdGljIGZpbmFsIGludFtdIFNVQkpfS0VZX0lEID0gezIsIDUsIDI5LCAxNH07CisgICAgc3RhdGljIGZpbmFsIGludFtdIEtFWV9VU0FHRSA9IHsyLCA1LCAyOSwgMTV9OworICAgIHN0YXRpYyBmaW5hbCBpbnRbXSBQUklWQVRFX0tFWV9VU0FHRV9QRVJJT0QgPSB7MiwgNSwgMjksIDE2fTsKKyAgICBzdGF0aWMgZmluYWwgaW50W10gU1VCSkVDVF9BTFRfTkFNRSA9IHsyLCA1LCAyOSwgMTd9OworICAgIHN0YXRpYyBmaW5hbCBpbnRbXSBJU1NVRVJfQUxURVJOQVRJVkVfTkFNRSA9IHsyLCA1LCAyOSwgMTh9OworICAgIHN0YXRpYyBmaW5hbCBpbnRbXSBCQVNJQ19DT05TVFJBSU5UUyA9IHsyLCA1LCAyOSwgMTl9OworICAgIHN0YXRpYyBmaW5hbCBpbnRbXSBOQU1FX0NPTlNUUkFJTlRTID0gezIsIDUsIDI5LCAzMH07CisgICAgc3RhdGljIGZpbmFsIGludFtdIENSTF9ESVNUUl9QT0lOVFMgPSB7MiwgNSwgMjksIDMxfTsKKyAgICBzdGF0aWMgZmluYWwgaW50W10gQ0VSVElGSUNBVEVfUE9MSUNJRVMgPSB7MiwgNSwgMjksIDMyfTsKKyAgICBzdGF0aWMgZmluYWwgaW50W10gUE9MSUNZX01BUFBJTkdTID0gezIsIDUsIDI5LCAzM307CisgICAgc3RhdGljIGZpbmFsIGludFtdIEFVVEhfS0VZX0lEID0gezIsIDUsIDI5LCAzNX07CisgICAgc3RhdGljIGZpbmFsIGludFtdIFBPTElDWV9DT05TVFJBSU5UUyA9IHsyLCA1LCAyOSwgMzZ9OworICAgIHN0YXRpYyBmaW5hbCBpbnRbXSBFWFRFTkRFRF9LRVlfVVNBR0UgPSB7MiwgNSwgMjksIDM3fTsKKyAgICBzdGF0aWMgZmluYWwgaW50W10gRlJFU0hFU1RfQ1JMID0gezIsIDUsIDI5LCA0Nn07CisgICAgc3RhdGljIGZpbmFsIGludFtdIElOSElCSVRfQU5ZX1BPTElDWSA9IHsyLCA1LCAyOSwgNTR9OworICAgIHN0YXRpYyBmaW5hbCBpbnRbXSBBVVRIT1JJVFlfSU5GT19BQ0NFU1MgPQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7MSwgMywgNiwgMSwgNSwgNSwgNywgMSwgMX07CisgICAgc3RhdGljIGZpbmFsIGludFtdIFNVQkpFQ1RfSU5GT19BQ0NFU1MgPQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7MSwgMywgNiwgMSwgNSwgNSwgNywgMSwgMTF9OworICAgIC8vIGNybCBleHRlbnNpb25zOgorICAgIHN0YXRpYyBmaW5hbCBpbnRbXSBJU1NVSU5HX0RJU1RSX1BPSU5UID0gezIsIDUsIDI5LCAyOH07CisgICAgLy8gY3JsIGVudHJ5IGV4dGVuc2lvbnM6CisgICAgc3RhdGljIGZpbmFsIGludFtdIENSTF9OVU1CRVIgPSB7MiwgNSwgMjksIDIwfTsKKyAgICBzdGF0aWMgZmluYWwgaW50W10gQ0VSVElGSUNBVEVfSVNTVUVSID0gezIsIDUsIDI5LCAyOX07CisgICAgc3RhdGljIGZpbmFsIGludFtdIElOVkFMSURJVFlfREFURSA9IHsyLCA1LCAyOSwgMjR9OworICAgIHN0YXRpYyBmaW5hbCBpbnRbXSBSRUFTT05fQ09ERSA9IHsyLCA1LCAyOSwgMjF9OworICAgIHN0YXRpYyBmaW5hbCBpbnRbXSBJU1NVSU5HX0RJU1RSX1BPSU5UUyA9IHsyLCA1LCAyOSwgMjh9OworCisgICAgLy8gdGhlIHZhbHVlIG9mIGV4dG5JRCBmaWVsZCBvZiB0aGUgc3RydWN0dXJlCisgICAgcHJpdmF0ZSBmaW5hbCBpbnRbXSBleHRuSUQ7CisgICAgcHJpdmF0ZSBTdHJpbmcgZXh0bklEX3N0cjsKKyAgICAvLyB0aGUgdmFsdWUgb2YgY3JpdGljYWwgZmllbGQgb2YgdGhlIHN0cnVjdHVyZQorICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBjcml0aWNhbDsKKyAgICAvLyB0aGUgdmFsdWUgb2YgZXh0blZhbHVlIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBleHRuVmFsdWU7CisgICAgLy8gdGhlIEFTTi4xIGVuY29kZWQgZm9ybSBvZiBFeHRlbnNpb24KKyAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGluZzsKKyAgICAvLyB0aGUgcmF3IChub3QgZGVjb2RlZCkgdmFsdWUgb2YgZXh0blZhbHVlIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUKKyAgICBwcml2YXRlIGJ5dGVbXSByYXdFeHRuVmFsdWU7CisgICAgLy8gdGhlIGRlY29kZWQgZXh0ZW5zaW9uIHZhbHVlCisgICAgcHJvdGVjdGVkIEV4dGVuc2lvblZhbHVlIGV4dG5WYWx1ZU9iamVjdDsKKyAgICAvLyB0ZWxscyB3aGV0aGVyIGV4dGVuc2lvbiB2YWx1ZSBoYXMgYmVlbiBkZWNvZGVkIG9yIG5vdAorICAgIHByaXZhdGUgYm9vbGVhbiB2YWx1ZURlY29kZWQgPSBmYWxzZTsKKworICAgIHB1YmxpYyBFeHRlbnNpb24oU3RyaW5nIGV4dG5JRCwgYm9vbGVhbiBjcml0aWNhbCwKKyAgICAgICAgICAgIEV4dGVuc2lvblZhbHVlIGV4dG5WYWx1ZU9iamVjdCkgeworICAgICAgICB0aGlzLmV4dG5JRF9zdHIgPSBleHRuSUQ7CisgICAgICAgIHRoaXMuZXh0bklEID0gT2JqZWN0SWRlbnRpZmllci50b0ludEFycmF5KGV4dG5JRCk7CisgICAgICAgIHRoaXMuY3JpdGljYWwgPSBjcml0aWNhbDsKKyAgICAgICAgdGhpcy5leHRuVmFsdWVPYmplY3QgPSBleHRuVmFsdWVPYmplY3Q7CisgICAgICAgIHRoaXMudmFsdWVEZWNvZGVkID0gdHJ1ZTsKKyAgICAgICAgdGhpcy5leHRuVmFsdWUgPSBleHRuVmFsdWVPYmplY3QuZ2V0RW5jb2RlZCgpOworICAgIH0KKworICAgIHB1YmxpYyBFeHRlbnNpb24oU3RyaW5nIGV4dG5JRCwgYm9vbGVhbiBjcml0aWNhbCwgYnl0ZVtdIGV4dG5WYWx1ZSkgeworICAgICAgICB0aGlzLmV4dG5JRF9zdHIgPSBleHRuSUQ7CisgICAgICAgIHRoaXMuZXh0bklEID0gT2JqZWN0SWRlbnRpZmllci50b0ludEFycmF5KGV4dG5JRCk7CisgICAgICAgIHRoaXMuY3JpdGljYWwgPSBjcml0aWNhbDsKKyAgICAgICAgdGhpcy5leHRuVmFsdWUgPSBleHRuVmFsdWU7CisgICAgfQorCisgICAgcHVibGljIEV4dGVuc2lvbihpbnRbXSBleHRuSUQsIGJvb2xlYW4gY3JpdGljYWwsIGJ5dGVbXSBleHRuVmFsdWUpIHsKKyAgICAgICAgdGhpcy5leHRuSUQgPSBleHRuSUQ7CisgICAgICAgIHRoaXMuY3JpdGljYWwgPSBjcml0aWNhbDsKKyAgICAgICAgdGhpcy5leHRuVmFsdWUgPSBleHRuVmFsdWU7CisgICAgfQorCisgICAgcHVibGljIEV4dGVuc2lvbihTdHJpbmcgZXh0bklELCBieXRlW10gZXh0blZhbHVlKSB7CisgICAgICAgIHRoaXMoZXh0bklELCBOT05fQ1JJVElDQUwsIGV4dG5WYWx1ZSk7CisgICAgfQorCisgICAgcHVibGljIEV4dGVuc2lvbihpbnRbXSBleHRuSUQsIGJ5dGVbXSBleHRuVmFsdWUpIHsKKyAgICAgICAgdGhpcyhleHRuSUQsIE5PTl9DUklUSUNBTCwgZXh0blZhbHVlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIEV4dGVuc2lvbihpbnRbXSBleHRuSUQsIGJvb2xlYW4gY3JpdGljYWwsIGJ5dGVbXSBleHRuVmFsdWUsCisgICAgICAgICAgICBieXRlW10gcmF3RXh0blZhbHVlLCBieXRlW10gZW5jb2RpbmcsCisgICAgICAgICAgICBFeHRlbnNpb25WYWx1ZSBkZWNvZGVkRXh0VmFsdWUpIHsKKyAgICAgICAgdGhpcyhleHRuSUQsIGNyaXRpY2FsLCBleHRuVmFsdWUpOworICAgICAgICB0aGlzLnJhd0V4dG5WYWx1ZSA9IHJhd0V4dG5WYWx1ZTsKKyAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgICAgICB0aGlzLmV4dG5WYWx1ZU9iamVjdCA9IGRlY29kZWRFeHRWYWx1ZTsKKyAgICAgICAgdGhpcy52YWx1ZURlY29kZWQgPSAoZGVjb2RlZEV4dFZhbHVlICE9IG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGV4dG5JRCBmaWVsZCBvZiB0aGUgc3RydWN0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RXh0bklEKCkgeworICAgICAgICBpZiAoZXh0bklEX3N0ciA9PSBudWxsKSB7CisgICAgICAgICAgICBleHRuSURfc3RyID0gT2JqZWN0SWRlbnRpZmllci50b1N0cmluZyhleHRuSUQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBleHRuSURfc3RyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGNyaXRpY2FsIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0Q3JpdGljYWwoKSB7CisgICAgICAgIHJldHVybiBjcml0aWNhbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBleHRuVmFsdWUgZmllbGQgb2YgdGhlIHN0cnVjdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEV4dG5WYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIGV4dG5WYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByYXcgKHVuZGVjb2RlZCBvY3RldCBzdHJpbmcpIHZhbHVlIG9mIGV4dG5WYWx1ZQorICAgICAqIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRSYXdFeHRuVmFsdWUoKSB7CisgICAgICAgIGlmIChyYXdFeHRuVmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmF3RXh0blZhbHVlID0gQVNOMU9jdGV0U3RyaW5nLmdldEluc3RhbmNlKCkuZW5jb2RlKGV4dG5WYWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJhd0V4dG5WYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFTTi4xIGVuY29kZWQgZm9ybSBvZiB0aGlzIFguNTA5IEV4dGVuc2lvbiB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEV4dGVuc2lvbi5BU04xLmVuY29kZSh0aGlzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgZXh0KSB7CisgICAgICAgIGlmICghKGV4dCBpbnN0YW5jZW9mIEV4dGVuc2lvbikpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBFeHRlbnNpb24gZXh0ZW5zaW9uID0gKEV4dGVuc2lvbikgZXh0OworICAgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscyhleHRuSUQsIGV4dGVuc2lvbi5leHRuSUQpCisgICAgICAgICAgICAmJiAoY3JpdGljYWwgPT0gZXh0ZW5zaW9uLmNyaXRpY2FsKQorICAgICAgICAgICAgJiYgQXJyYXlzLmVxdWFscyhleHRuVmFsdWUsIGV4dGVuc2lvbi5leHRuVmFsdWUpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gKEFycmF5cy5oYXNoQ29kZShleHRuSUQpICogMzcgKyAoY3JpdGljYWwgPyAxIDogMCkpICogMzcgKyBBcnJheXMuaGFzaENvZGUoZXh0blZhbHVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRXh0ZW5zaW9uVmFsdWUgZ2V0RGVjb2RlZEV4dGVuc2lvblZhbHVlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCF2YWx1ZURlY29kZWQpIHsKKyAgICAgICAgICAgIGRlY29kZUV4dGVuc2lvblZhbHVlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGV4dG5WYWx1ZU9iamVjdDsKKyAgICB9CisKKyAgICBwdWJsaWMgS2V5VXNhZ2UgZ2V0S2V5VXNhZ2VWYWx1ZSgpIHsKKyAgICAgICAgaWYgKCF2YWx1ZURlY29kZWQpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZGVjb2RlRXh0ZW5zaW9uVmFsdWUoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoZXh0blZhbHVlT2JqZWN0IGluc3RhbmNlb2YgS2V5VXNhZ2UpIHsKKyAgICAgICAgICAgIHJldHVybiAoS2V5VXNhZ2UpIGV4dG5WYWx1ZU9iamVjdDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIEJhc2ljQ29uc3RyYWludHMgZ2V0QmFzaWNDb25zdHJhaW50c1ZhbHVlKCkgeworICAgICAgICBpZiAoIXZhbHVlRGVjb2RlZCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBkZWNvZGVFeHRlbnNpb25WYWx1ZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChleHRuVmFsdWVPYmplY3QgaW5zdGFuY2VvZiBCYXNpY0NvbnN0cmFpbnRzKSB7CisgICAgICAgICAgICByZXR1cm4gKEJhc2ljQ29uc3RyYWludHMpIGV4dG5WYWx1ZU9iamVjdDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGRlY29kZUV4dGVuc2lvblZhbHVlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHZhbHVlRGVjb2RlZCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHZhbHVlRGVjb2RlZCA9IHRydWU7CisgICAgICAgIGlmIChBcnJheXMuZXF1YWxzKGV4dG5JRCwgU1VCSl9LRVlfSUQpKSB7CisgICAgICAgICAgICBleHRuVmFsdWVPYmplY3QgPSBTdWJqZWN0S2V5SWRlbnRpZmllci5kZWNvZGUoZXh0blZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmIChBcnJheXMuZXF1YWxzKGV4dG5JRCwgS0VZX1VTQUdFKSkgeworICAgICAgICAgICAgZXh0blZhbHVlT2JqZWN0ID0gbmV3IEtleVVzYWdlKGV4dG5WYWx1ZSk7CisgICAgICAgIH0gZWxzZSBpZiAoQXJyYXlzLmVxdWFscyhleHRuSUQsIFNVQkpFQ1RfQUxUX05BTUUpKSB7CisgICAgICAgICAgICBleHRuVmFsdWVPYmplY3QgPSBuZXcgQWx0ZXJuYXRpdmVOYW1lKAorICAgICAgICAgICAgICAgICAgICBBbHRlcm5hdGl2ZU5hbWUuU1VCSkVDVCwgZXh0blZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmIChBcnJheXMuZXF1YWxzKGV4dG5JRCwgSVNTVUVSX0FMVEVSTkFUSVZFX05BTUUpKSB7CisgICAgICAgICAgICBleHRuVmFsdWVPYmplY3QgPSBuZXcgQWx0ZXJuYXRpdmVOYW1lKAorICAgICAgICAgICAgICAgICAgICBBbHRlcm5hdGl2ZU5hbWUuU1VCSkVDVCwgZXh0blZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmIChBcnJheXMuZXF1YWxzKGV4dG5JRCwgQkFTSUNfQ09OU1RSQUlOVFMpKSB7CisgICAgICAgICAgICBleHRuVmFsdWVPYmplY3QgPSBuZXcgQmFzaWNDb25zdHJhaW50cyhleHRuVmFsdWUpOworICAgICAgICB9IGVsc2UgaWYgKEFycmF5cy5lcXVhbHMoZXh0bklELCBOQU1FX0NPTlNUUkFJTlRTKSkgeworICAgICAgICAgICAgZXh0blZhbHVlT2JqZWN0ID0gTmFtZUNvbnN0cmFpbnRzLmRlY29kZShleHRuVmFsdWUpOworICAgICAgICB9IGVsc2UgaWYgKEFycmF5cy5lcXVhbHMoZXh0bklELCBDRVJUSUZJQ0FURV9QT0xJQ0lFUykpIHsKKyAgICAgICAgICAgIGV4dG5WYWx1ZU9iamVjdCA9IENlcnRpZmljYXRlUG9saWNpZXMuZGVjb2RlKGV4dG5WYWx1ZSk7CisgICAgICAgIH0gZWxzZSBpZiAoQXJyYXlzLmVxdWFscyhleHRuSUQsIEFVVEhfS0VZX0lEKSkgeworICAgICAgICAgICAgZXh0blZhbHVlT2JqZWN0ID0gQXV0aG9yaXR5S2V5SWRlbnRpZmllci5kZWNvZGUoZXh0blZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmIChBcnJheXMuZXF1YWxzKGV4dG5JRCwgUE9MSUNZX0NPTlNUUkFJTlRTKSkgeworICAgICAgICAgICAgZXh0blZhbHVlT2JqZWN0ID0gbmV3IFBvbGljeUNvbnN0cmFpbnRzKGV4dG5WYWx1ZSk7CisgICAgICAgIH0gZWxzZSBpZiAoQXJyYXlzLmVxdWFscyhleHRuSUQsIEVYVEVOREVEX0tFWV9VU0FHRSkpIHsKKyAgICAgICAgICAgIGV4dG5WYWx1ZU9iamVjdCA9IG5ldyBFeHRlbmRlZEtleVVzYWdlKGV4dG5WYWx1ZSk7CisgICAgICAgIH0gZWxzZSBpZiAoQXJyYXlzLmVxdWFscyhleHRuSUQsIElOSElCSVRfQU5ZX1BPTElDWSkpIHsKKyAgICAgICAgICAgIGV4dG5WYWx1ZU9iamVjdCA9IG5ldyBJbmhpYml0QW55UG9saWN5KGV4dG5WYWx1ZSk7CisgICAgICAgIH0gZWxzZSBpZiAoQXJyYXlzLmVxdWFscyhleHRuSUQsIENFUlRJRklDQVRFX0lTU1VFUikpIHsKKyAgICAgICAgICAgIGV4dG5WYWx1ZU9iamVjdCA9IG5ldyBDZXJ0aWZpY2F0ZUlzc3VlcihleHRuVmFsdWUpOworICAgICAgICB9IGVsc2UgaWYgKEFycmF5cy5lcXVhbHMoZXh0bklELCBDUkxfRElTVFJfUE9JTlRTKSkgeworICAgICAgICAgICAgZXh0blZhbHVlT2JqZWN0ID0gQ1JMRGlzdHJpYnV0aW9uUG9pbnRzLmRlY29kZShleHRuVmFsdWUpOworICAgICAgICB9IGVsc2UgaWYgKEFycmF5cy5lcXVhbHMoZXh0bklELCBDRVJUSUZJQ0FURV9JU1NVRVIpKSB7CisgICAgICAgICAgICBleHRuVmFsdWVPYmplY3QgPSBuZXcgUmVhc29uQ29kZShleHRuVmFsdWUpOworICAgICAgICB9IGVsc2UgaWYgKEFycmF5cy5lcXVhbHMoZXh0bklELCBJTlZBTElESVRZX0RBVEUpKSB7CisgICAgICAgICAgICBleHRuVmFsdWVPYmplY3QgPSBuZXcgSW52YWxpZGl0eURhdGUoZXh0blZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmIChBcnJheXMuZXF1YWxzKGV4dG5JRCwgUkVBU09OX0NPREUpKSB7CisgICAgICAgICAgICBleHRuVmFsdWVPYmplY3QgPSBuZXcgUmVhc29uQ29kZShleHRuVmFsdWUpOworICAgICAgICB9IGVsc2UgaWYgKEFycmF5cy5lcXVhbHMoZXh0bklELCBDUkxfTlVNQkVSKSkgeworICAgICAgICAgICAgZXh0blZhbHVlT2JqZWN0ID0gbmV3IENSTE51bWJlcihleHRuVmFsdWUpOworICAgICAgICB9IGVsc2UgaWYgKEFycmF5cy5lcXVhbHMoZXh0bklELCBJU1NVSU5HX0RJU1RSX1BPSU5UUykpIHsKKyAgICAgICAgICAgIGV4dG5WYWx1ZU9iamVjdCA9IElzc3VpbmdEaXN0cmlidXRpb25Qb2ludC5kZWNvZGUoZXh0blZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmIChBcnJheXMuZXF1YWxzKGV4dG5JRCwgQVVUSE9SSVRZX0lORk9fQUNDRVNTKSkgeworICAgICAgICAgICAgZXh0blZhbHVlT2JqZWN0ID0gSW5mb0FjY2Vzc1N5bnRheC5kZWNvZGUoZXh0blZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmIChBcnJheXMuZXF1YWxzKGV4dG5JRCwgU1VCSkVDVF9JTkZPX0FDQ0VTUykpIHsKKyAgICAgICAgICAgIGV4dG5WYWx1ZU9iamVjdCA9IEluZm9BY2Nlc3NTeW50YXguZGVjb2RlKGV4dG5WYWx1ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBkdW1wVmFsdWUoU3RyaW5nQnVpbGRlciBzYiwgU3RyaW5nIHByZWZpeCkgeworICAgICAgICBzYi5hcHBlbmQoIk9JRDogIikuYXBwZW5kKGdldEV4dG5JRCgpKS5hcHBlbmQoIiwgQ3JpdGljYWw6ICIpLmFwcGVuZChjcml0aWNhbCkuYXBwZW5kKCdcbicpOworICAgICAgICBpZiAoIXZhbHVlRGVjb2RlZCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBkZWNvZGVFeHRlbnNpb25WYWx1ZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChleHRuVmFsdWVPYmplY3QgIT0gbnVsbCkgeworICAgICAgICAgICAgZXh0blZhbHVlT2JqZWN0LmR1bXBWYWx1ZShzYiwgcHJlZml4KTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICAvLyBlbHNlOiBkdW1wIHVucGFyc2VkIGhleCByZXByZXNlbnRhdGlvbgorICAgICAgICBzYi5hcHBlbmQocHJlZml4KTsKKyAgICAgICAgaWYgKEFycmF5cy5lcXVhbHMoZXh0bklELCBTVUJKX0RJUkVDVE9SWV9BVFRSUykpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiU3ViamVjdCBEaXJlY3RvcnkgQXR0cmlidXRlcyBFeHRlbnNpb24iKTsKKyAgICAgICAgfSBlbHNlIGlmIChBcnJheXMuZXF1YWxzKGV4dG5JRCwgU1VCSl9LRVlfSUQpKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIlN1YmplY3QgS2V5IElkZW50aWZpZXIgRXh0ZW5zaW9uIik7CisgICAgICAgIH0gZWxzZSBpZiAoQXJyYXlzLmVxdWFscyhleHRuSUQsIEtFWV9VU0FHRSkpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiS2V5IFVzYWdlIEV4dGVuc2lvbiIpOworICAgICAgICB9IGVsc2UgaWYgKEFycmF5cy5lcXVhbHMoZXh0bklELCBQUklWQVRFX0tFWV9VU0FHRV9QRVJJT0QpKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIlByaXZhdGUgS2V5IFVzYWdlIFBlcmlvZCBFeHRlbnNpb24iKTsKKyAgICAgICAgfSBlbHNlIGlmIChBcnJheXMuZXF1YWxzKGV4dG5JRCwgU1VCSkVDVF9BTFRfTkFNRSkpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiU3ViamVjdCBBbHRlcm5hdGl2ZSBOYW1lIEV4dGVuc2lvbiIpOworICAgICAgICB9IGVsc2UgaWYgKEFycmF5cy5lcXVhbHMoZXh0bklELCBJU1NVRVJfQUxURVJOQVRJVkVfTkFNRSkpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiSXNzdWVyIEFsdGVybmF0aXZlIE5hbWUgRXh0ZW5zaW9uIik7CisgICAgICAgIH0gZWxzZSBpZiAoQXJyYXlzLmVxdWFscyhleHRuSUQsIEJBU0lDX0NPTlNUUkFJTlRTKSkgeworICAgICAgICAgICAgc2IuYXBwZW5kKCJCYXNpYyBDb25zdHJhaW50cyBFeHRlbnNpb24iKTsKKyAgICAgICAgfSBlbHNlIGlmIChBcnJheXMuZXF1YWxzKGV4dG5JRCwgTkFNRV9DT05TVFJBSU5UUykpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiTmFtZSBDb25zdHJhaW50cyBFeHRlbnNpb24iKTsKKyAgICAgICAgfSBlbHNlIGlmIChBcnJheXMuZXF1YWxzKGV4dG5JRCwgQ1JMX0RJU1RSX1BPSU5UUykpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiQ1JMIERpc3RyaWJ1dGlvbiBQb2ludHMgRXh0ZW5zaW9uIik7CisgICAgICAgIH0gZWxzZSBpZiAoQXJyYXlzLmVxdWFscyhleHRuSUQsIENFUlRJRklDQVRFX1BPTElDSUVTKSkgeworICAgICAgICAgICAgc2IuYXBwZW5kKCJDZXJ0aWZpY2F0ZSBQb2xpY2llcyBFeHRlbnNpb24iKTsKKyAgICAgICAgfSBlbHNlIGlmIChBcnJheXMuZXF1YWxzKGV4dG5JRCwgUE9MSUNZX01BUFBJTkdTKSkgeworICAgICAgICAgICAgc2IuYXBwZW5kKCJQb2xpY3kgTWFwcGluZ3MgRXh0ZW5zaW9uIik7CisgICAgICAgIH0gZWxzZSBpZiAoQXJyYXlzLmVxdWFscyhleHRuSUQsIEFVVEhfS0VZX0lEKSkgeworICAgICAgICAgICAgc2IuYXBwZW5kKCJBdXRob3JpdHkgS2V5IElkZW50aWZpZXIgRXh0ZW5zaW9uIik7CisgICAgICAgIH0gZWxzZSBpZiAoQXJyYXlzLmVxdWFscyhleHRuSUQsIFBPTElDWV9DT05TVFJBSU5UUykpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiUG9saWN5IENvbnN0cmFpbnRzIEV4dGVuc2lvbiIpOworICAgICAgICB9IGVsc2UgaWYgKEFycmF5cy5lcXVhbHMoZXh0bklELCBFWFRFTkRFRF9LRVlfVVNBR0UpKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIkV4dGVuZGVkIEtleSBVc2FnZSBFeHRlbnNpb24iKTsKKyAgICAgICAgfSBlbHNlIGlmIChBcnJheXMuZXF1YWxzKGV4dG5JRCwgSU5ISUJJVF9BTllfUE9MSUNZKSkgeworICAgICAgICAgICAgc2IuYXBwZW5kKCJJbmhpYml0IEFueS1Qb2xpY3kgRXh0ZW5zaW9uIik7CisgICAgICAgIH0gZWxzZSBpZiAoQXJyYXlzLmVxdWFscyhleHRuSUQsIEFVVEhPUklUWV9JTkZPX0FDQ0VTUykpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiQXV0aG9yaXR5IEluZm9ybWF0aW9uIEFjY2VzcyBFeHRlbnNpb24iKTsKKyAgICAgICAgfSBlbHNlIGlmIChBcnJheXMuZXF1YWxzKGV4dG5JRCwgU1VCSkVDVF9JTkZPX0FDQ0VTUykpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiU3ViamVjdCBJbmZvcm1hdGlvbiBBY2Nlc3MgRXh0ZW5zaW9uIik7CisgICAgICAgIH0gZWxzZSBpZiAoQXJyYXlzLmVxdWFscyhleHRuSUQsIElOVkFMSURJVFlfREFURSkpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiSW52YWxpZGl0eSBEYXRlIEV4dGVuc2lvbiIpOworICAgICAgICB9IGVsc2UgaWYgKEFycmF5cy5lcXVhbHMoZXh0bklELCBDUkxfTlVNQkVSKSkgeworICAgICAgICAgICAgc2IuYXBwZW5kKCJDUkwgTnVtYmVyIEV4dGVuc2lvbiIpOworICAgICAgICB9IGVsc2UgaWYgKEFycmF5cy5lcXVhbHMoZXh0bklELCBSRUFTT05fQ09ERSkpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiUmVhc29uIENvZGUgRXh0ZW5zaW9uIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIlVua25vd24gRXh0ZW5zaW9uIik7CisgICAgICAgIH0KKyAgICAgICAgc2IuYXBwZW5kKCdcbicpLmFwcGVuZChwcmVmaXgpLmFwcGVuZCgiVW5wYXJzZWQgRXh0ZW5zaW9uIFZhbHVlOlxuIik7CisgICAgICAgIHNiLmFwcGVuZChBcnJheS50b1N0cmluZyhleHRuVmFsdWUsIHByZWZpeCkpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogWC41MDkgRXh0ZW5zaW9uIGVuY29kZXIvZGVjb2Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZShuZXcgQVNOMVR5cGVbXSB7CisgICAgICAgICAgICBBU04xT2lkLmdldEluc3RhbmNlKCksCisgICAgICAgICAgICBBU04xQm9vbGVhbi5nZXRJbnN0YW5jZSgpLAorICAgICAgICAgICAgbmV3IEFTTjFPY3RldFN0cmluZygpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICAvLyBmaXJzdCAtIGRlY29kZWQgb2N0ZXQgc3RyaW5nLAorICAgICAgICAgICAgICAgICAgICAvLyBzZWNvbmQgLSByYXcgZW5jb2Rpbmcgb2Ygb2N0ZXQgc3RyaW5nCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgT2JqZWN0W10KKyAgICAgICAgICAgICAgICAgICAgICAgIHtzdXBlci5nZXREZWNvZGVkT2JqZWN0KGluKSwgaW4uZ2V0RW5jb2RlZCgpfTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0pIHsKKyAgICAgICAgeworICAgICAgICAgICAgc2V0RGVmYXVsdChCb29sZWFuLkZBTFNFLCAxKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBPYmplY3RbXSB2YWx1ZXMgPSAoT2JqZWN0W10pIGluLmNvbnRlbnQ7CisKKyAgICAgICAgICAgIGludFtdIG9pZCA9IChpbnRbXSkgdmFsdWVzWzBdOworICAgICAgICAgICAgYnl0ZVtdIGV4dG5WYWx1ZSA9IChieXRlW10pICgoT2JqZWN0W10pIHZhbHVlc1syXSlbMF07CisgICAgICAgICAgICBieXRlW10gcmF3RXh0blZhbHVlID0gKGJ5dGVbXSkgKChPYmplY3RbXSkgdmFsdWVzWzJdKVsxXTsKKworICAgICAgICAgICAgRXh0ZW5zaW9uVmFsdWUgZGVjb2RlZEV4dFZhbHVlID0gbnVsbDsKKyAgICAgICAgICAgIC8vIGRlY29kZSBLZXkgVXNhZ2UgYW5kIEJhc2ljIENvbnN0cmFpbnRzIGV4dGVuc2lvbiB2YWx1ZXMKKyAgICAgICAgICAgIGlmIChBcnJheXMuZXF1YWxzKG9pZCwgS0VZX1VTQUdFKSkgeworICAgICAgICAgICAgICAgIGRlY29kZWRFeHRWYWx1ZSA9IG5ldyBLZXlVc2FnZShleHRuVmFsdWUpOworICAgICAgICAgICAgfSBlbHNlIGlmIChBcnJheXMuZXF1YWxzKG9pZCwgQkFTSUNfQ09OU1RSQUlOVFMpKSB7CisgICAgICAgICAgICAgICAgZGVjb2RlZEV4dFZhbHVlID0gbmV3IEJhc2ljQ29uc3RyYWludHMoZXh0blZhbHVlKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIG5ldyBFeHRlbnNpb24oKGludFtdKSB2YWx1ZXNbMF0sIChCb29sZWFuKSB2YWx1ZXNbMV0sCisgICAgICAgICAgICAgICAgICAgIGV4dG5WYWx1ZSwgcmF3RXh0blZhbHVlLCBpbi5nZXRFbmNvZGVkKCksIGRlY29kZWRFeHRWYWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykgeworICAgICAgICAgICAgRXh0ZW5zaW9uIGV4dCA9IChFeHRlbnNpb24pIG9iamVjdDsKKyAgICAgICAgICAgIHZhbHVlc1swXSA9IGV4dC5leHRuSUQ7CisgICAgICAgICAgICB2YWx1ZXNbMV0gPSAoZXh0LmNyaXRpY2FsKSA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0U7CisgICAgICAgICAgICB2YWx1ZXNbMl0gPSBleHQuZXh0blZhbHVlOworICAgICAgICB9CisgICAgfTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9FeHRlbnNpb25WYWx1ZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0V4dGVuc2lvblZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjJlOTE1OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9FeHRlbnNpb25WYWx1ZS5qYXZhCkBAIC0wLDAgKzEsNTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudXRpbHMuQXJyYXk7CisKKy8qKgorICogQmFzZSBjbGFzcyBmb3IgZXh0ZW5zaW9uIHZhbHVlIHN0cnVjdHVyZXMuCisgKi8KK3B1YmxpYyBjbGFzcyBFeHRlbnNpb25WYWx1ZSB7CisKKyAgICAvKiogRW5jb2RlZCBmb3JtIG9mIHRoZSBleHRlbnNpb24uICovCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmNvZGluZzsKKworICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLworICAgIHB1YmxpYyBFeHRlbnNpb25WYWx1ZSgpIHt9CisKKyAgICAvKiogQ3JlYXRlcyB0aGUgb2JqZWN0IG9uIHRoZSBiYXNlIG9mIGl0cyBlbmNvZGVkIGZvcm0uICovCisgICAgcHVibGljIEV4dGVuc2lvblZhbHVlKGJ5dGVbXSBlbmNvZGluZykgeworICAgICAgICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgfQorCisgICAgLyoqIFJldHVybnMgZW5jb2RlZCBmb3JtIG9mIHRoZSBvYmplY3QuICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICByZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZHVtcFZhbHVlKFN0cmluZ0J1aWxkZXIgc2IsIFN0cmluZyBwcmVmaXgpIHsKKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJVbnBhcnNlYWJsZSBleHRlbnNpb24gdmFsdWU6XG4iKTsKKyAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIGVuY29kaW5nID0gZ2V0RW5jb2RlZCgpOworICAgICAgICB9CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIk5VTExcbiIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc2IuYXBwZW5kKEFycmF5LnRvU3RyaW5nKGVuY29kaW5nLCBwcmVmaXgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGR1bXBWYWx1ZShTdHJpbmdCdWlsZGVyIHNiKSB7CisgICAgICAgIGR1bXBWYWx1ZShzYiwgIiIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9FeHRlbnNpb25zLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvRXh0ZW5zaW9ucy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMzMzZiMGQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvRXh0ZW5zaW9ucy5qYXZhCkBAIC0wLDAgKzEsMzU2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXF1ZW5jZU9mOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworCisvKioKKyAqIFRoZSBjbGFzcyBlbmNhcHN1bGF0ZXMgdGhlIEFTTi4xIERFUiBlbmNvZGluZy9kZWNvZGluZyB3b3JrCisgKiB3aXRoIHRoZSBFeHRlbnNpb25zIHBhcnQgb2YgWC41MDkgY2VydGlmaWNhdGUKKyAqIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODAgLQorICogIEludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUuCisgKiAgQ2VydGlmaWNhdGUgYW5kIENlcnRpZmljYXRlIFJldm9jYXRpb24gTGlzdCAoQ1JMKSBQcm9maWxlLgorICogIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KToKKyAqCisgKiA8cHJlPgorICogIEV4dGVuc2lvbnMgIDo6PSAgU0VRVUVOQ0UgU0laRSAoMS4uTUFYKSBPRiBFeHRlbnNpb24KKyAqIDwvcHJlPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRXh0ZW5zaW9ucyB7CisKKyAgICAvLyBTdXBwb3J0ZWQgY3JpdGljYWwgZXh0ZW5zaW9ucyBvaWRzOgorICAgIHByaXZhdGUgc3RhdGljIExpc3QgU1VQUE9SVEVEX0NSSVRJQ0FMID0gQXJyYXlzLmFzTGlzdCgKKyAgICAgICAgICAgICIyLjUuMjkuMTUiLCAiMi41LjI5LjE5IiwgIjIuNS4yOS4zMiIsICIyLjUuMjkuMTciLAorICAgICAgICAgICAgIjIuNS4yOS4zMCIsICIyLjUuMjkuMzYiLCAiMi41LjI5LjM3IiwgIjIuNS4yOS41NCIpOworCisgICAgLy8gdGhlIHZhbHVlcyBvZiBleHRlbnNpb25zIG9mIHRoZSBzdHJ1Y3R1cmUKKyAgICBwcml2YXRlIExpc3Q8RXh0ZW5zaW9uPiBleHRlbnNpb25zOworICAgIHByaXZhdGUgU2V0PFN0cmluZz4gY3JpdGljYWw7CisgICAgcHJpdmF0ZSBTZXQ8U3RyaW5nPiBub25jcml0aWNhbDsKKyAgICAvLyB0aGUgZmxhZyBzaG93aW5nIGlzIHRoZXJlIGFueSB1bnN1cHBvcnRlZCBjcml0aWNhbCBleHRlbnNpb24KKyAgICAvLyBpbiB0aGUgbGlzdCBvZiBleHRlbnNpb25zIG9yIG5vdC4KKyAgICBwcml2YXRlIGJvb2xlYW4gaGFzVW5zdXBwb3J0ZWQ7CisgICAgLy8gbWFwIGNvbnRhaW5pbmcgdGhlIG9pZCBvZiBleHRlbnNpb25zIGFzIGEga2V5cyBhbmQKKyAgICAvLyBFeHRlbnNpb24gb2JqZWN0cyBhcyB2YWx1ZXMKKyAgICBwcml2YXRlIEhhc2hNYXA8U3RyaW5nLCBFeHRlbnNpb24+IG9pZE1hcDsKKyAgICAvLyB0aGUgQVNOLjEgZW5jb2RlZCBmb3JtIG9mIEV4dGVuc2lvbnMKKyAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGluZzsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgdmFsdWUgb2YgRXh0ZW5zaW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRXh0ZW5zaW9ucygpIHt9CisKKyAgICBwdWJsaWMgRXh0ZW5zaW9ucyhMaXN0PEV4dGVuc2lvbj4gZXh0ZW5zaW9ucykgeworICAgICAgICB0aGlzLmV4dGVuc2lvbnMgPSBleHRlbnNpb25zOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIChleHRlbnNpb25zID09IG51bGwpID8gMCA6IGV4dGVuc2lvbnMuc2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxpc3Qgb2YgY3JpdGljYWwgZXh0ZW5zaW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2V0PFN0cmluZz4gZ2V0Q3JpdGljYWxFeHRlbnNpb25zKCkgeworICAgICAgICBpZiAoY3JpdGljYWwgPT0gbnVsbCkgeworICAgICAgICAgICAgbWFrZU9pZHNMaXN0cygpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjcml0aWNhbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIGNyaXRpY2FsIGV4dGVuc2lvbnMuCisgICAgICovCisgICAgcHVibGljIFNldDxTdHJpbmc+IGdldE5vbkNyaXRpY2FsRXh0ZW5zaW9ucygpIHsKKyAgICAgICAgaWYgKG5vbmNyaXRpY2FsID09IG51bGwpIHsKKyAgICAgICAgICAgIG1ha2VPaWRzTGlzdHMoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbm9uY3JpdGljYWw7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaGFzVW5zdXBwb3J0ZWRDcml0aWNhbCgpIHsKKyAgICAgICAgaWYgKGNyaXRpY2FsID09IG51bGwpIHsKKyAgICAgICAgICAgIG1ha2VPaWRzTGlzdHMoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzVW5zdXBwb3J0ZWQ7CisgICAgfQorCisgICAgLy8KKyAgICAvLyBNYWtlcyB0aGUgc2VwYXJhdGVkIGxpc3RzIHdpdGggb2lkcyBvZiBjcml0aWNhbAorICAgIC8vIGFuZCBub24tY3JpdGljYWwgZXh0ZW5zaW9ucworICAgIC8vCisgICAgcHJpdmF0ZSB2b2lkIG1ha2VPaWRzTGlzdHMoKSB7CisgICAgICAgIGlmIChleHRlbnNpb25zID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpbnQgc2l6ZSA9IGV4dGVuc2lvbnMuc2l6ZSgpOworICAgICAgICBjcml0aWNhbCA9IG5ldyBIYXNoU2V0PFN0cmluZz4oc2l6ZSk7CisgICAgICAgIG5vbmNyaXRpY2FsID0gbmV3IEhhc2hTZXQ8U3RyaW5nPihzaXplKTsKKyAgICAgICAgZm9yIChFeHRlbnNpb24gZXh0ZW5zaW9uIDogZXh0ZW5zaW9ucykgeworICAgICAgICAgICAgU3RyaW5nIG9pZCA9IGV4dGVuc2lvbi5nZXRFeHRuSUQoKTsKKyAgICAgICAgICAgIGlmIChleHRlbnNpb24uZ2V0Q3JpdGljYWwoKSkgeworICAgICAgICAgICAgICAgIGlmICghU1VQUE9SVEVEX0NSSVRJQ0FMLmNvbnRhaW5zKG9pZCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaGFzVW5zdXBwb3J0ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjcml0aWNhbC5hZGQob2lkKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgbm9uY3JpdGljYWwuYWRkKG9pZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZXMgb2YgZXh0ZW5zaW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRXh0ZW5zaW9uIGdldEV4dGVuc2lvbkJ5T0lEKFN0cmluZyBvaWQpIHsKKyAgICAgICAgaWYgKGV4dGVuc2lvbnMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9pZE1hcCA9PSBudWxsKSB7CisgICAgICAgICAgICBvaWRNYXAgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIEV4dGVuc2lvbj4oKTsKKyAgICAgICAgICAgIGZvciAoRXh0ZW5zaW9uIGV4dGVuc2lvbiA6IGV4dGVuc2lvbnMpIHsKKyAgICAgICAgICAgICAgICBvaWRNYXAucHV0KGV4dGVuc2lvbi5nZXRFeHRuSUQoKSwgZXh0ZW5zaW9uKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gb2lkTWFwLmdldChvaWQpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgS2V5IFVzYWdlIGV4dGVuc2lvbiAoT0lEID09IDIuNS4yOS4xNSkuCisgICAgICogVGhlIEFTTi4xIGRlZmluaXRpb24gb2YgS2V5IFVzYWdlIEV4dGVuc2lvbiBpczoKKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogaWQtY2Uta2V5VXNhZ2UgT0JKRUNUIElERU5USUZJRVIgOjo9ICB7IGlkLWNlIDE1IH0KKyAgICAgKgorICAgICAqIEtleVVzYWdlIDo6PSBCSVQgU1RSSU5HIHsKKyAgICAgKiAgICAgZGlnaXRhbFNpZ25hdHVyZSAgICAgICAgKDApLAorICAgICAqICAgICBub25SZXB1ZGlhdGlvbiAgICAgICAgICAoMSksCisgICAgICogICAgIGtleUVuY2lwaGVybWVudCAgICAgICAgICgyKSwKKyAgICAgKiAgICAgZGF0YUVuY2lwaGVybWVudCAgICAgICAgKDMpLAorICAgICAqICAgICBrZXlBZ3JlZW1lbnQgICAgICAgICAgICAoNCksCisgICAgICogICAgIGtleUNlcnRTaWduICAgICAgICAgICAgICg1KSwKKyAgICAgKiAgICAgY1JMU2lnbiAgICAgICAgICAgICAgICAgKDYpLAorICAgICAqICAgICBlbmNpcGhlck9ubHkgICAgICAgICAgICAoNyksCisgICAgICogICAgIGRlY2lwaGVyT25seSAgICAgICAgICAgICg4KQorICAgICAqIH0KKyAgICAgKiA8L3ByZT4KKyAgICAgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwKQorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgS2V5IFVzYWdlIEV4dGVuc2lvbiBpZiBpdCBpcyBpbiB0aGUgbGlzdCwKKyAgICAgKiBhbmQgbnVsbCBpZiB0aGVyZSBpcyBubyBzdWNoIGV4dGVuc2lvbiBvciBpdHMgdmFsdWUgY2FuIG5vdCBiZSBkZWNvZGVkCisgICAgICogb3RoZXJ3aXNlLiBOb3RlLCB0aGF0IHRoZSBsZW5ndGggb2YgcmV0dXJuZWQgYXJyYXkgY2FuIGJlIGdyZWF0ZXIKKyAgICAgKiB0aGFuIDkuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW5bXSB2YWx1ZU9mS2V5VXNhZ2UoKSB7CisgICAgICAgIEV4dGVuc2lvbiBleHRlbnNpb24gPSBnZXRFeHRlbnNpb25CeU9JRCgiMi41LjI5LjE1Iik7CisgICAgICAgIEtleVVzYWdlIGtVc2FnZTsKKyAgICAgICAgaWYgKChleHRlbnNpb24gPT0gbnVsbCkgfHwgKChrVXNhZ2UgPSBleHRlbnNpb24uZ2V0S2V5VXNhZ2VWYWx1ZSgpKSA9PSBudWxsKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGtVc2FnZS5nZXRLZXlVc2FnZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIEV4dGVuZGVkIEtleSBVc2FnZSBleHRlbnNpb24gKE9JRCA9PSAyLjUuMjkuMzcpLgorICAgICAqIFRoZSBBU04uMSBkZWZpbml0aW9uIG9mIEV4dGVuZGVkIEtleSBVc2FnZSBFeHRlbnNpb24gaXM6CisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqICBpZC1jZS1leHRLZXlVc2FnZSBPQkpFQ1QgSURFTlRJRklFUiA6Oj0geyBpZC1jZSAzNyB9CisgICAgICoKKyAgICAgKiAgRXh0S2V5VXNhZ2VTeW50YXggOjo9IFNFUVVFTkNFIFNJWkUgKDEuLk1BWCkgT0YgS2V5UHVycG9zZUlkCisgICAgICoKKyAgICAgKiAgS2V5UHVycG9zZUlkIDo6PSBPQkpFQ1QgSURFTlRJRklFUgorICAgICAqIDwvcHJlPgorICAgICAqIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODApCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBsaXN0IHdpdGggc3RyaW5nIHJlcHJlc2VudGF0aW9ucyBvZiBLZXlQdXJwb3NlSWQncyBPSURzCisgICAgICogYW5kIG51bGwKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGV4dGVuc2lvbiB3YXMgaW5jb3JyZWN0bHkgZW5jb2RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxTdHJpbmc+IHZhbHVlT2ZFeHRlbmRlZEtleVVzYWdlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgRXh0ZW5zaW9uIGV4dGVuc2lvbiA9IGdldEV4dGVuc2lvbkJ5T0lEKCIyLjUuMjkuMzciKTsKKyAgICAgICAgaWYgKGV4dGVuc2lvbiA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKChFeHRlbmRlZEtleVVzYWdlKSBleHRlbnNpb24uZ2V0RGVjb2RlZEV4dGVuc2lvblZhbHVlKCkpLmdldEV4dGVuZGVkS2V5VXNhZ2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBCYXNpYyBDb25zdHJhaW50cyBFeHRlbnNpb24gKE9JRCA9IDIuNS4yOS4xOSkuCisgICAgICogVGhlIEFTTi4xIGRlZmluaXRpb24gb2YgQmFzaWMgQ29uc3RyYWludHMgRXh0ZW5zaW9uIGlzOgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiAgIGlkLWNlLWJhc2ljQ29uc3RyYWludHMgT0JKRUNUIElERU5USUZJRVIgOjo9ICB7IGlkLWNlIDE5IH0KKyAgICAgKgorICAgICAqICAgQmFzaWNDb25zdHJhaW50cyA6Oj0gU0VRVUVOQ0UgeworICAgICAqICAgICAgICBjQSAgICAgICAgICAgICAgICAgICAgICBCT09MRUFOIERFRkFVTFQgRkFMU0UsCisgICAgICogICAgICAgIHBhdGhMZW5Db25zdHJhaW50ICAgICAgIElOVEVHRVIgKDAuLk1BWCkgT1BUSU9OQUwKKyAgICAgKiAgIH0KKyAgICAgKiA8L3ByZT4KKyAgICAgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwKQorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgcGF0aExlbkNvbnN0cmFpbnQgZmllbGQgaWYgZXh0ZW5zaW9uIHByZXNlbnRzLAorICAgICAqIGFuZCBJbnRlZ2VyLk1BWF9WQUxVRSBpZiBkb2VzIG5vdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHZhbHVlT2ZCYXNpY0NvbnN0cmFpbnMoKSB7CisgICAgICAgIEV4dGVuc2lvbiBleHRlbnNpb24gPSBnZXRFeHRlbnNpb25CeU9JRCgiMi41LjI5LjE5Iik7CisgICAgICAgIEJhc2ljQ29uc3RyYWludHMgYmM7CisgICAgICAgIGlmICgoZXh0ZW5zaW9uID09IG51bGwpIHx8ICgoYmMgPSBleHRlbnNpb24uZ2V0QmFzaWNDb25zdHJhaW50c1ZhbHVlKCkpID09IG51bGwpKSB7CisgICAgICAgICAgICByZXR1cm4gSW50ZWdlci5NQVhfVkFMVUU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJjLmdldFBhdGhMZW5Db25zdHJhaW50KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgU3ViamVjdCBBbHRlcm5hdGl2ZSBOYW1lIChPSUQgPSAyLjUuMjkuMTcpLgorICAgICAqIFRoZSBBU04uMSBkZWZpbml0aW9uIGZvciBTdWJqZWN0IEFsdGVybmF0aXZlIE5hbWUgaXM6CisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqICBpZC1jZS1zdWJqZWN0QWx0TmFtZSBPQkpFQ1QgSURFTlRJRklFUiA6Oj0gIHsgaWQtY2UgMTcgfQorICAgICAqCisgICAgICogIFN1YmplY3RBbHROYW1lIDo6PSBHZW5lcmFsTmFtZXMKKyAgICAgKiA8L3ByZT4KKyAgICAgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwKQorICAgICAqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBjb2xsZWN0aW9uIG9mIHBhaXJzOgorICAgICAqIChJbnRlZ2VyICh0YWcpLCBPYmplY3QgKG5hbWUgdmFsdWUpKSBpZiBleHRlbnNpb24gcHJlc2VudHMsIGFuZAorICAgICAqIG51bGwgaWYgZG9lcyBub3QuCisgICAgICovCisgICAgcHVibGljIENvbGxlY3Rpb248TGlzdDw/Pj4gdmFsdWVPZlN1YmplY3RBbHRlcm5hdGl2ZU5hbWUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBFeHRlbnNpb24gZXh0ZW5zaW9uID0gZ2V0RXh0ZW5zaW9uQnlPSUQoIjIuNS4yOS4xNyIpOworICAgICAgICBpZiAoZXh0ZW5zaW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoKEdlbmVyYWxOYW1lcykgR2VuZXJhbE5hbWVzLkFTTjEuZGVjb2RlKGV4dGVuc2lvbi5nZXRFeHRuVmFsdWUoKSkpLmdldFBhaXJzTGlzdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIElzc3VlciBBbHRlcm5hdGl2ZSBOYW1lIEV4dGVuc2lvbiAoT0lEID0gMi41LjI5LjE4KS4KKyAgICAgKiBUaGUgQVNOLjEgZGVmaW5pdGlvbiBmb3IgSXNzdWVyIEFsdGVybmF0aXZlIE5hbWUgaXM6CisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqICAgaWQtY2UtaXNzdWVyQWx0TmFtZSBPQkpFQ1QgSURFTlRJRklFUiA6Oj0gIHsgaWQtY2UgMTggfQorICAgICAqCisgICAgICogICBJc3N1ZXJBbHROYW1lIDo6PSBHZW5lcmFsTmFtZXMKKyAgICAgKiA8L3ByZT4KKyAgICAgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwKQorICAgICAqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBjb2xsZWN0aW9uIG9mIHBhaXJzOgorICAgICAqIChJbnRlZ2VyICh0YWcpLCBPYmplY3QgKG5hbWUgdmFsdWUpKSBpZiBleHRlbnNpb24gcHJlc2VudHMsIGFuZAorICAgICAqIG51bGwgaWYgZG9lcyBub3QuCisgICAgICovCisgICAgcHVibGljIENvbGxlY3Rpb248TGlzdDw/Pj4gdmFsdWVPZklzc3VlckFsdGVybmF0aXZlTmFtZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEV4dGVuc2lvbiBleHRlbnNpb24gPSBnZXRFeHRlbnNpb25CeU9JRCgiMi41LjI5LjE4Iik7CisgICAgICAgIGlmIChleHRlbnNpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuICgoR2VuZXJhbE5hbWVzKSBHZW5lcmFsTmFtZXMuQVNOMS5kZWNvZGUoZXh0ZW5zaW9uLmdldEV4dG5WYWx1ZSgpKSkuZ2V0UGFpcnNMaXN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgQ2VydGlmaWNhdGUgSXNzdWVyIEV4dGVuc2lvbiAoT0lEID0gMi41LjI5LjI5KS4KKyAgICAgKiBJdCBpcyBhIENSTCBlbnRyeSBleHRlbnNpb24gYW5kIGNvbnRhaW5zIHRoZSBHZW5lcmFsTmFtZXMgZGVzY3JpYmluZworICAgICAqIHRoZSBpc3N1ZXIgb2YgcmV2b2tlZCBjZXJ0aWZpY2F0ZS4gSXRzIEFTTi4xIG5vdGF0aW9uIGlzIGFzIGZvbGxvd3M6CisgICAgICogPHByZT4KKyAgICAgKiAgIGlkLWNlLWNlcnRpZmljYXRlSXNzdWVyICAgT0JKRUNUIElERU5USUZJRVIgOjo9IHsgaWQtY2UgMjkgfQorICAgICAqCisgICAgICogICBjZXJ0aWZpY2F0ZUlzc3VlciA6Oj0gICAgIEdlbmVyYWxOYW1lcworICAgICAqIDwvcHJlPgorICAgICAqIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODApCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiBDZXJ0aWZpY2F0ZSBJc3N1ZXIgRXh0ZW5zaW9uCisgICAgICovCisgICAgcHVibGljIFg1MDBQcmluY2lwYWwgdmFsdWVPZkNlcnRpZmljYXRlSXNzdWVyRXh0ZW5zaW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgRXh0ZW5zaW9uIGV4dGVuc2lvbiA9IGdldEV4dGVuc2lvbkJ5T0lEKCIyLjUuMjkuMjkiKTsKKyAgICAgICAgaWYgKGV4dGVuc2lvbiA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKChDZXJ0aWZpY2F0ZUlzc3VlcikgZXh0ZW5zaW9uLmdldERlY29kZWRFeHRlbnNpb25WYWx1ZSgpKS5nZXRJc3N1ZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFTTi4xIGVuY29kZWQgZm9ybSBvZiB0aGlzIFguNTA5IEV4dGVuc2lvbnMgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSBBU04xLmVuY29kZSh0aGlzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKKyAgICAgICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBFeHRlbnNpb25zKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIEV4dGVuc2lvbnMgdGhhdCA9IChFeHRlbnNpb25zKSBvdGhlcjsKKyAgICAgICAgcmV0dXJuICh0aGlzLmV4dGVuc2lvbnMgPT0gbnVsbCB8fCB0aGlzLmV4dGVuc2lvbnMuaXNFbXB0eSgpKQorICAgICAgICAgICAgICAgICAgICA/ICh0aGF0LmV4dGVuc2lvbnMgPT0gbnVsbCB8fCB0aGF0LmV4dGVuc2lvbnMuaXNFbXB0eSgpKQorICAgICAgICAgICAgICAgICAgICA6ICh0aGlzLmV4dGVuc2lvbnMuZXF1YWxzKHRoYXQuZXh0ZW5zaW9ucykpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICBpbnQgaGFzaENvZGUgPSAwOworICAgICAgICBpZiAoZXh0ZW5zaW9ucyAhPSBudWxsKSB7CisgICAgICAgICAgICBoYXNoQ29kZSA9IGV4dGVuc2lvbnMuaGFzaENvZGUoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFzaENvZGU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZHVtcFZhbHVlKFN0cmluZ0J1aWxkZXIgc2IsIFN0cmluZyBwcmVmaXgpIHsKKyAgICAgICAgaWYgKGV4dGVuc2lvbnMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGludCBudW0gPSAxOworICAgICAgICBmb3IgKEV4dGVuc2lvbiBleHRlbnNpb246IGV4dGVuc2lvbnMpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgnXG4nKS5hcHBlbmQocHJlZml4KS5hcHBlbmQoJ1snKS5hcHBlbmQobnVtKyspLmFwcGVuZCgiXTogIik7CisgICAgICAgICAgICBleHRlbnNpb24uZHVtcFZhbHVlKHNiLCBwcmVmaXgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3VzdG9tIFguNTA5IEV4dGVuc2lvbnMgZGVjb2Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFUeXBlIEFTTjEgPSBuZXcgQVNOMVNlcXVlbmNlT2YoRXh0ZW5zaW9uLkFTTjEpIHsKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBFeHRlbnNpb25zKChMaXN0PEV4dGVuc2lvbj4pIGluLmNvbnRlbnQpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBDb2xsZWN0aW9uIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICBFeHRlbnNpb25zIGV4dGVuc2lvbnMgPSAoRXh0ZW5zaW9ucykgb2JqZWN0OworICAgICAgICAgICAgcmV0dXJuIChleHRlbnNpb25zLmV4dGVuc2lvbnMgPT0gbnVsbCkgPyBuZXcgQXJyYXlMaXN0KCkgOiBleHRlbnNpb25zLmV4dGVuc2lvbnM7CisgICAgICAgIH0KKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0dlbmVyYWxOYW1lLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvR2VuZXJhbE5hbWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kODE4OGJlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0dlbmVyYWxOYW1lLmphdmEKQEAgLTAsMCArMSw3MTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292LCBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlVSSTsKK2ltcG9ydCBqYXZhLm5ldC5VUklTeW50YXhFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVW5rbm93bkhvc3RFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFDaG9pY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUltcGxpY2l0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFPY3RldFN0cmluZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xT2lkOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTdHJpbmdUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLk9iamVjdElkZW50aWZpZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnV0aWxzLkFycmF5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTAxLk5hbWU7CisKKy8qKgorICogVGhlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgQVNOLjEgREVSIGVuY29kaW5nL2RlY29kaW5nIHdvcmsKKyAqIHdpdGggdGhlIEdlbmVyYWxOYW1lIHN0cnVjdHVyZSB3aGljaCBpcyBhIHBhcnQgb2YgWC41MDkgY2VydGlmaWNhdGUKKyAqIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODAgLQorICogIEludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUuCisgKiAgQ2VydGlmaWNhdGUgYW5kIENlcnRpZmljYXRlIFJldm9jYXRpb24gTGlzdCAoQ1JMKSBQcm9maWxlLgorICogIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KToKKyAqCisgKiA8cHJlPgorICoKKyAqICAgR2VuZXJhbE5hbWU6Oj0gQ0hPSUNFIHsKKyAqICAgICAgICBvdGhlck5hbWUgICAgICAgICAgICAgICAgICAgICAgIFswXSAgICAgT3RoZXJOYW1lLAorICogICAgICAgIHJmYzgyMk5hbWUgICAgICAgICAgICAgICAgICAgICAgWzFdICAgICBJQTVTdHJpbmcsCisgKiAgICAgICAgZE5TTmFtZSAgICAgICAgICAgICAgICAgICAgICAgICBbMl0gICAgIElBNVN0cmluZywKKyAqICAgICAgICB4NDAwQWRkcmVzcyAgICAgICAgICAgICAgICAgICAgIFszXSAgICAgT1JBZGRyZXNzLAorICogICAgICAgIGRpcmVjdG9yeU5hbWUgICAgICAgICAgICAgICAgICAgWzRdICAgICBOYW1lLAorICogICAgICAgIGVkaVBhcnR5TmFtZSAgICAgICAgICAgICAgICAgICAgWzVdICAgICBFRElQYXJ0eU5hbWUsCisgKiAgICAgICAgdW5pZm9ybVJlc291cmNlSWRlbnRpZmllciAgICAgICBbNl0gICAgIElBNVN0cmluZywKKyAqICAgICAgICBpUEFkZHJlc3MgICAgICAgICAgICAgICAgICAgICAgIFs3XSAgICAgT0NURVQgU1RSSU5HLAorICogICAgICAgIHJlZ2lzdGVyZWRJRCAgICAgICAgICAgICAgICAgICAgWzhdICAgICBPQkpFQ1QgSURFTlRJRklFUgorICogICB9CisgKgorICogICBPdGhlck5hbWU6Oj0gU0VRVUVOQ0UgeworICogICAgICAgIHR5cGUtaWQgICAgT0JKRUNUIElERU5USUZJRVIsCisgKiAgICAgICAgdmFsdWUgICAgICBbMF0gRVhQTElDSVQgQU5ZIERFRklORUQgQlkgdHlwZS1pZAorICogICB9CisgKgorICogICBFRElQYXJ0eU5hbWU6Oj0gU0VRVUVOQ0UgeworICogICAgICAgIG5hbWVBc3NpZ25lciAgICAgICAgICAgIFswXSAgICAgRGlyZWN0b3J5U3RyaW5nIE9QVElPTkFMLAorICogICAgICAgIHBhcnR5TmFtZSAgICAgICAgICAgICAgIFsxXSAgICAgRGlyZWN0b3J5U3RyaW5nCisgKiAgIH0KKyAqCisgKiAgIERpcmVjdG9yeVN0cmluZzo6PSBDSE9JQ0UgeworICogICAgICAgIHRlbGV0ZXhTdHJpbmcgICAgICAgICAgICAgVGVsZXRleFN0cmluZyAgIChTSVpFICgxLi5NQVgpKSwKKyAqICAgICAgICBwcmludGFibGVTdHJpbmcgICAgICAgICAgIFByaW50YWJsZVN0cmluZyAoU0laRSAoMS4uTUFYKSksCisgKiAgICAgICAgdW5pdmVyc2FsU3RyaW5nICAgICAgICAgICBVbml2ZXJzYWxTdHJpbmcgKFNJWkUgKDEuLk1BWCkpLAorICogICAgICAgIHV0ZjhTdHJpbmcgICAgICAgICAgICAgIFVURjhTdHJpbmcgICAgICAoU0laRSAoMS4uTUFYKSksCisgKiAgICAgICAgYm1wU3RyaW5nICAgICAgICAgICAgICAgQk1QU3RyaW5nICAgICAgIChTSVpFICgxLi5NQVgpKQorICogICB9CisgKgorICogPC9wcmU+CisgKgorICogPHA+VGhpcyBjbGFzcyBkb2Vzbid0IHN1cHBvcnQgbWFza2VkIGFkZHJlc3NlcyBsaWtlICIxMC45LjguMC8yNTUuMjU1LjI1NS4wIi4KKyAqIFRoZXNlIGFyZSBvbmx5IG5lY2Vzc2FyeSBmb3IgTmFtZUNvbnN0cmFpbnRzLCB3aGljaCBhcmUgbm90IGV4cG9zZWQgaW4gdGhlCisgKiBKYXZhIGNlcnRpZmljYXRlIEFQSS4KKyAqCisgKiBAc2VlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5Lk5hbWVDb25zdHJhaW50cworICogQHNlZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5HZW5lcmFsU3VidHJlZQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgR2VuZXJhbE5hbWUgeworCisgICAgLyoqCisgICAgICogVGhlIHZhbHVlcyBvZiB0aGUgdGFncyBvZiBmaWVsZHMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPVEhFUl9OQU1FID0gMDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRkM4MjJfTkFNRSA9IDE7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRE5TX05BTUUgPSAyOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFg0MDBfQUREUiA9IDM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRElSX05BTUUgPSA0OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVESVBfTkFNRSA9IDU7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVVJfSUQgPSA2OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElQX0FERFIgPSA3OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFR19JRCA9IDg7CisKKyAgICAvLyBBU04xIGVuY29kZXJzL2RlY29kZXJzIGZvciBuYW1lIGNob2ljZXMKKyAgICBwcml2YXRlIHN0YXRpYyBBU04xVHlwZVtdIG5hbWVBU04xID0gbmV3IEFTTjFUeXBlWzldOworCisgICAgc3RhdGljIHsKKyAgICAgICAgbmFtZUFTTjFbT1RIRVJfTkFNRV0gPSBPdGhlck5hbWUuQVNOMTsKKyAgICAgICAgbmFtZUFTTjFbUkZDODIyX05BTUVdID0gQVNOMVN0cmluZ1R5cGUuSUE1U1RSSU5HOworICAgICAgICBuYW1lQVNOMVtETlNfTkFNRV0gPSBBU04xU3RyaW5nVHlwZS5JQTVTVFJJTkc7CisgICAgICAgIG5hbWVBU04xW1VSX0lEXSA9IEFTTjFTdHJpbmdUeXBlLklBNVNUUklORzsKKyAgICAgICAgbmFtZUFTTjFbWDQwMF9BRERSXSA9IE9SQWRkcmVzcy5BU04xOworICAgICAgICBuYW1lQVNOMVtESVJfTkFNRV0gPSBOYW1lLkFTTjE7CisgICAgICAgIG5hbWVBU04xW0VESVBfTkFNRV0gPSBFRElQYXJ0eU5hbWUuQVNOMTsKKyAgICAgICAgbmFtZUFTTjFbSVBfQUREUl0gPSBBU04xT2N0ZXRTdHJpbmcuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgbmFtZUFTTjFbUkVHX0lEXSA9IEFTTjFPaWQuZ2V0SW5zdGFuY2UoKTsKKyAgICB9CisKKyAgICAvKiogdGhlIHRhZyBvZiB0aGUgbmFtZSB0eXBlICovCisgICAgcHJpdmF0ZSBpbnQgdGFnOworICAgIC8qKiB0aGUgbmFtZSB2YWx1ZSAoY2FuIGJlIFN0cmluZyBvciBieXRlIGFycmF5KSAqLworICAgIHByaXZhdGUgT2JqZWN0IG5hbWU7CisgICAgLyoqIHRoZSBBU04uMSBlbmNvZGVkIGZvcm0gb2YgR2VuZXJhbE5hbWUgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGluZzsKKyAgICAvKiogdGhlIEFTTi4xIGVuY29kZWQgZm9ybSBvZiBHZW5lcmFsTmFtZSdzIGZpZWxkICovCisgICAgcHJpdmF0ZSBieXRlW10gbmFtZV9lbmNvZGluZzsKKworICAgIC8qKgorICAgICAqIE1ha2VzIHRoZSBHZW5lcmFsTmFtZSBvYmplY3QgZnJvbSB0aGUgdGFnIHR5cGUgYW5kIGNvcnJlc3BvbmRpbmcKKyAgICAgKiB3ZWxsIGVzdGFibGlzaGVkIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgbmFtZSB2YWx1ZS4KKyAgICAgKiBUaGUgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIFs3XSBpUEFkZHJlc3MgaXMgc3VjaCBhczoKKyAgICAgKiAgRm9yIElQIHY0LCBhcyBzcGVjaWZpZWQgaW4gUkZDIDc5MSwgdGhlIGFkZHJlc3MgbXVzdAorICAgICAqICBjb250YWluIGV4YWN0bHkgNCBieXRlIGNvbXBvbmVudC4gIEZvciBJUCB2NiwgYXMgc3BlY2lmaWVkIGluCisgICAgICogIFJGQyAxODgzLCB0aGUgYWRkcmVzcyBtdXN0IGNvbnRhaW4gZXhhY3RseSAxNiBieXRlIGNvbXBvbmVudC4KKyAgICAgKiAgSWYgR2VuZXJhbE5hbWUgc3RydWN0dXJlIGlzIHVzZWQgYXMgYSBwYXJ0IG9mIE5hbWUgQ29uc3RyYWludHMKKyAgICAgKiAgZXh0ZW5zaW9uLCB0byByZXByZXNlbnQgYW4gYWRkcmVzcyByYW5nZSB0aGUgbnVtYmVyIG9mIGFkZHJlc3MKKyAgICAgKiAgY29tcG9uZW50IGlzIGRvdWJsZWQgKHRvIDggYW5kIDMyIGJ5dGVzIHJlc3BlY3RpdmVseSkuCisgICAgICogTm90ZSB0aGF0IHRoZSBuYW1lczoKKyAgICAgKiBbMF0gb3RoZXJOYW1lLCBbM10geDQwMEFkZHJlc3MsIFs1XSBlZGlQYXJ0eU5hbWUKKyAgICAgKiAgIGhhdmUgbm8gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiwgc28gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLgorICAgICAqIFRvIG1ha2UgdGhlIEdlbmVyYWxOYW1lIG9iamVjdCB3aXRoIHN1Y2ggbmFtZXMgdXNlIGFub3RoZXIgY29uc3RydWN0b3IuCisgICAgICogQHBhcmFtIHRhZyBpcyBhbiBpbnRlZ2VyIHdoaWNoIHZhbHVlIGNvcnJlc3BvbmRzIHRvIHRoZSBuYW1lIHR5cGUuCisgICAgICogQHBhcmFtIG5hbWUgaXMgYSBuYW1lIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHRhZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgR2VuZXJhbE5hbWUoaW50IHRhZywgU3RyaW5nIG5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigibmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy50YWcgPSB0YWc7CisgICAgICAgIHN3aXRjaCAodGFnKSB7CisgICAgICAgICAgICBjYXNlIE9USEVSX05BTUUgOgorICAgICAgICAgICAgY2FzZSBYNDAwX0FERFIgOgorICAgICAgICAgICAgY2FzZSBFRElQX05BTUUgOgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5rbm93biBzdHJpbmcgcmVwcmVzZW50YXRpb24gZm9yIHR5cGUgWyIgKyB0YWcgKyAiXSIpOworICAgICAgICAgICAgY2FzZSBETlNfTkFNRSA6CisgICAgICAgICAgICAgICAgLy8gYWNjb3JkaW5nIHRvIFJGQyAzMjgwIHAuMzQgdGhlIEROUyBuYW1lIHNob3VsZCBiZQorICAgICAgICAgICAgICAgIC8vIGNoZWNrZWQgYWdhaW5zdCB0aGUKKyAgICAgICAgICAgICAgICAvLyBSRkMgMTAzNCBwLjEwICgzLjUuIFByZWZlcnJlZCBuYW1lIHN5bnRheCk6CisgICAgICAgICAgICAgICAgY2hlY2tETlMobmFtZSk7CisgICAgICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgVVJfSUQgOgorICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoZSB1bmlmb3JtUmVzb3VyY2VJZGVudGlmaWVyIGZvciBjb3JyZWN0bmVzcworICAgICAgICAgICAgICAgIC8vIGFjY29yZGluZyB0byBSRkMgMzI4MCBwLjM0CisgICAgICAgICAgICAgICAgY2hlY2tVUkkobmFtZSk7CisgICAgICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgUkZDODIyX05BTUUgOgorICAgICAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFJFR19JRDoKKyAgICAgICAgICAgICAgICB0aGlzLm5hbWUgPSBvaWRTdHJUb0ludHMobmFtZSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIERJUl9OQU1FIDoKKyAgICAgICAgICAgICAgICB0aGlzLm5hbWUgPSBuZXcgTmFtZShuYW1lKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgSVBfQUREUiA6CisgICAgICAgICAgICAgICAgdGhpcy5uYW1lID0gaXBTdHJUb0J5dGVzKG5hbWUpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlVua25vd24gdHlwZTogWyIgKyB0YWcgKyAiXSIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIEdlbmVyYWxOYW1lKE90aGVyTmFtZSBuYW1lKSB7CisgICAgICAgIHRoaXMudGFnID0gT1RIRVJfTkFNRTsKKyAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgR2VuZXJhbE5hbWUoT1JBZGRyZXNzIG5hbWUpIHsKKyAgICAgICAgdGhpcy50YWcgPSBYNDAwX0FERFI7CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgfQorCisgICAgcHVibGljIEdlbmVyYWxOYW1lKE5hbWUgbmFtZSkgeworICAgICAgICB0aGlzLnRhZyA9IERJUl9OQU1FOworICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgIH0KKworICAgIHB1YmxpYyBHZW5lcmFsTmFtZShFRElQYXJ0eU5hbWUgbmFtZSkgeworICAgICAgICB0aGlzLnRhZyA9IEVESVBfTkFNRTsKKyAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICB9CisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgZm9yIHR5cGUgWzddIGlQQWRkcmVzcy4KKyAgICAgKiBuYW1lIGlzIGFuIGFycmF5IG9mIGJ5dGVzIHN1Y2ggYXM6CisgICAgICogIEZvciBJUCB2NCwgYXMgc3BlY2lmaWVkIGluIFJGQyA3OTEsIHRoZSBhZGRyZXNzIG11c3QKKyAgICAgKiAgY29udGFpbiBleGFjdGx5IDQgYnl0ZSBjb21wb25lbnQuICBGb3IgSVAgdjYsIGFzIHNwZWNpZmllZCBpbgorICAgICAqICBSRkMgMTg4MywgdGhlIGFkZHJlc3MgbXVzdCBjb250YWluIGV4YWN0bHkgMTYgYnl0ZSBjb21wb25lbnQuCisgICAgICogIElmIEdlbmVyYWxOYW1lIHN0cnVjdHVyZSBpcyB1c2VkIGFzIGEgcGFydCBvZiBOYW1lIENvbnN0cmFpbnRzCisgICAgICogIGV4dGVuc2lvbiwgdG8gcmVwcmVzZW50IGFuIGFkZHJlc3MgcmFuZ2UgdGhlIG51bWJlciBvZiBhZGRyZXNzCisgICAgICogIGNvbXBvbmVudCBpcyBkb3VibGVkICh0byA4IGFuZCAzMiBieXRlcyByZXNwZWN0aXZlbHkpLgorICAgICAqLworICAgIHB1YmxpYyBHZW5lcmFsTmFtZShieXRlW10gbmFtZSkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBsZW5ndGggPSBuYW1lLmxlbmd0aDsKKyAgICAgICAgaWYgKGxlbmd0aCAhPSA0ICYmIGxlbmd0aCAhPSA4ICYmIGxlbmd0aCAhPSAxNiAmJiBsZW5ndGggIT0gMzIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm5hbWUubGVuZ3RoIGludmFsaWQiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnRhZyA9IElQX0FERFI7CisgICAgICAgIHRoaXMubmFtZSA9IG5ldyBieXRlW25hbWUubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShuYW1lLCAwLCB0aGlzLm5hbWUsIDAsIG5hbWUubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIHZhbHVlIG9mIEdlbmVyYWxOYW1lLgorICAgICAqIEBwYXJhbSB0YWcgaXMgYW4gaW50ZWdlciB3aGljaCB2YWx1ZSBjb3JyZXNwb25kcworICAgICAqIHRvIHRoZSBuYW1lIHR5cGUgKDAtOCksCisgICAgICogQHBhcmFtIG5hbWUgaXMgYSBERVIgZW5jb2RlZCBmb3Igb2YgdGhlIG5hbWUgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgR2VuZXJhbE5hbWUoaW50IHRhZywgYnl0ZVtdIG5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCh0YWcgPCAwKSB8fCAodGFnID4gOCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiR2VuZXJhbE5hbWU6IHVua25vd24gdGFnOiAiICsgdGFnKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnRhZyA9IHRhZzsKKyAgICAgICAgdGhpcy5uYW1lX2VuY29kaW5nID0gbmV3IGJ5dGVbbmFtZS5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5hbWUsIDAsIHRoaXMubmFtZV9lbmNvZGluZywgMCwgbmFtZS5sZW5ndGgpOworICAgICAgICB0aGlzLm5hbWUgPSBuYW1lQVNOMVt0YWddLmRlY29kZSh0aGlzLm5hbWVfZW5jb2RpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRhZyBvZiB0aGUgbmFtZSBpbiB0aGUgc3RydWN0dXJlCisgICAgICovCisgICAgcHVibGljIGludCBnZXRUYWcoKSB7CisgICAgICAgIHJldHVybiB0YWc7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIG5hbWUuCisgICAgICogVGhlIGNsYXNzIG9mIG5hbWUgb2JqZWN0IGRlcGVuZHMgb24gdGhlIHRhZyBhcyBmb2xsb3dzOgorICAgICAqIFswXSBvdGhlck5hbWUgLSBPdGhlck5hbWUgb2JqZWN0LAorICAgICAqIFsxXSByZmM4MjJOYW1lIC0gU3RyaW5nIG9iamVjdCwKKyAgICAgKiBbMl0gZE5TTmFtZSAtIFN0cmluZyBvYmplY3QsCisgICAgICogWzNdIHg0MDBBZGRyZXNzIC0gT1JBZGRyZXNzIG9iamVjdCwKKyAgICAgKiBbNF0gZGlyZWN0b3J5TmFtZSAtIGluc3RhbmNlIG9mIE5hbWUgb2JqZWN0LAorICAgICAqIFs1XSBlZGlQYXJ0eU5hbWUgLSBFRElQYXJ0eU5hbWUgb2JqZWN0LAorICAgICAqIFs2XSB1bmlmb3JtUmVzb3VyY2VJZGVudGlmaWVyIC0gU3RyaW5nIG9iamVjdCwKKyAgICAgKiBbN10gaVBBZGRyZXNzIC0gYXJyYXkgb2YgYnl0ZXMgc3VjaCBhczoKKyAgICAgKiAgRm9yIElQIHY0LCBhcyBzcGVjaWZpZWQgaW4gUkZDIDc5MSwgdGhlIGFkZHJlc3MgbXVzdAorICAgICAqICBjb250YWluIGV4YWN0bHkgNCBieXRlIGNvbXBvbmVudC4gIEZvciBJUCB2NiwgYXMgc3BlY2lmaWVkIGluCisgICAgICogIFJGQyAxODgzLCB0aGUgYWRkcmVzcyBtdXN0IGNvbnRhaW4gZXhhY3RseSAxNiBieXRlIGNvbXBvbmVudC4KKyAgICAgKiAgSWYgR2VuZXJhbE5hbWUgc3RydWN0dXJlIGlzIHVzZWQgYXMgYSBwYXJ0IG9mIE5hbWUgQ29uc3RyYWludHMKKyAgICAgKiAgZXh0ZW5zaW9uLCB0byByZXByZXNlbnQgYW4gYWRkcmVzcyByYW5nZSB0aGUgbnVtYmVyIG9mIGFkZHJlc3MKKyAgICAgKiAgY29tcG9uZW50IGlzIGRvdWJsZWQgKHRvIDggYW5kIDMyIGJ5dGVzIHJlc3BlY3RpdmVseSkuCisgICAgICogWzhdIHJlZ2lzdGVyZWRJRCAtIFN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKKyAgICAgICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBHZW5lcmFsTmFtZSkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBHZW5lcmFsTmFtZSBnbmFtZSA9IChHZW5lcmFsTmFtZSkgb3RoZXI7CisgICAgICAgIGlmICh0aGlzLnRhZyAhPSBnbmFtZS50YWcpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2godGFnKSB7CisgICAgICAgICAgICBjYXNlIFJGQzgyMl9OQU1FOgorICAgICAgICAgICAgY2FzZSBETlNfTkFNRToKKyAgICAgICAgICAgIGNhc2UgVVJfSUQ6CisgICAgICAgICAgICAgICAgcmV0dXJuICgoU3RyaW5nKSBuYW1lKS5lcXVhbHNJZ25vcmVDYXNlKAorICAgICAgICAgICAgICAgICAgICAgICAgKFN0cmluZykgZ25hbWUuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGNhc2UgUkVHX0lEOgorICAgICAgICAgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKChpbnRbXSkgbmFtZSwgKGludFtdKSBnbmFtZS5uYW1lKTsKKyAgICAgICAgICAgIGNhc2UgSVBfQUREUjoKKyAgICAgICAgICAgICAgICAvLyBpUEFkZHJlc3MgWzddLCBjaGVjayBieSB1c2luZyByYW5nZXMuCisgICAgICAgICAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMoKGJ5dGVbXSkgbmFtZSwgKGJ5dGVbXSkgZ25hbWUubmFtZSk7CisgICAgICAgICAgICBjYXNlIERJUl9OQU1FOgorICAgICAgICAgICAgY2FzZSBYNDAwX0FERFI6CisgICAgICAgICAgICBjYXNlIE9USEVSX05BTUU6CisgICAgICAgICAgICBjYXNlIEVESVBfTkFNRToKKyAgICAgICAgICAgICAgICByZXR1cm4gQXJyYXlzLmVxdWFscyhnZXRFbmNvZGVkKCksIGduYW1lLmdldEVuY29kZWQoKSk7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIC8vIHNob3VsZCBuZXZlciBoYXBwZW4KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgc3dpdGNoICh0YWcpIHsKKyAgICAgICAgY2FzZSBSRkM4MjJfTkFNRToKKyAgICAgICAgY2FzZSBETlNfTkFNRToKKyAgICAgICAgY2FzZSBVUl9JRDoKKyAgICAgICAgY2FzZSBSRUdfSUQ6CisgICAgICAgIGNhc2UgSVBfQUREUjoKKyAgICAgICAgICAgIHJldHVybiBuYW1lLmhhc2hDb2RlKCk7CisgICAgICAgIGNhc2UgRElSX05BTUU6CisgICAgICAgIGNhc2UgWDQwMF9BRERSOgorICAgICAgICBjYXNlIE9USEVSX05BTUU6CisgICAgICAgIGNhc2UgRURJUF9OQU1FOgorICAgICAgICAgICAgcmV0dXJuIEFycmF5cy5oYXNoQ29kZShnZXRFbmNvZGVkKCkpOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgdGhlIG90aGVyIGdlbmVyYWwgbmFtZSBpcyBhY2NlcHRhYmxlIGJ5IHRoaXMgb2JqZWN0LgorICAgICAqIFRoZSBuYW1lIGlzIGFjY2VwdGFibGUgaWYgaXQgaGFzIHRoZSBzYW1lIHR5cGUgbmFtZSBhbmQgaXRzCisgICAgICogbmFtZSB2YWx1ZSBpcyBlcXVhbCB0byBuYW1lIHZhbHVlIG9mIHRoaXMgb2JqZWN0LiBBbHNvIHRoZSBuYW1lCisgICAgICogaXMgYWNjZXB0YWJsZSBpZiB0aGlzIGdlbmVyYWwgbmFtZSBvYmplY3QgaXMgYSBwYXJ0IG9mIG5hbWUKKyAgICAgKiBjb25zdHJhaW50cyBhbmQgdGhlIHNwZWNpZmllZCBuYW1lIGlzIHNhdGlzZmllZCB0aGUgcmVzdHJpY3Rpb24KKyAgICAgKiBwcm92aWRlZCBieSB0aGlzIG9iamVjdCAoZm9yIG1vcmUgZGV0YWlsIHNlZSBzZWN0aW9uIDQuMi4xLjExCisgICAgICogb2YgcmZjIDMyODApLgorICAgICAqIE5vdGUgdGhhdCBmb3IgWDQwMEFkZHJlc3MgWzNdIGNoZWNrIHByb2NlZHVyZSBpcyB1bmNsZWFyIHNvIG1ldGhvZAorICAgICAqIGp1c3QgY2hlY2tzIHRoZSBlcXVhbGl0eSBvZiBlbmNvZGVkIGZvcm1zLgorICAgICAqIEZvciBvdGhlck5hbWUgWzBdLCBlZGlQYXJ0eU5hbWUgWzVdLCBhbmQgcmVnaXN0ZXJlZElEIFs4XQorICAgICAqIHRoZSBjaGVjayBwcm9jZWR1cmUgaWYgbm90IGRlZmluZWQgYnkgcmZjIDMyODAgYW5kIGZvciBuYW1lcyBvZgorICAgICAqIHRoZXNlIHR5cGVzIHRoaXMgbWV0aG9kIGFsc28gY2hlY2tzIG9ubHkgZm9yIGVxdWFsaXR5IG9mIGVuY29kZWQgZm9ybXMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNBY2NlcHRhYmxlKEdlbmVyYWxOYW1lIGduYW1lKSB7CisgICAgICAgIGlmICh0aGlzLnRhZyAhPSBnbmFtZS5nZXRUYWcoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAodGhpcy50YWcpIHsKKyAgICAgICAgICAgIGNhc2UgUkZDODIyX05BTUU6CisgICAgICAgICAgICAgICAgLy8gTWFpbCBhZGRyZXNzIFsxXToKKyAgICAgICAgICAgICAgICAvLyBhQGIuYyAtIHBhcnRpY3VsYXIgYWRkcmVzcyBpcyBhY2NlcHRhYmxlIGJ5IHRoZSBzYW1lIGFkZHJlc3MsCisgICAgICAgICAgICAgICAgLy8gb3IgYnkgYi5jIC0gaG9zdCBuYW1lLgorICAgICAgICAgICAgICAgIHJldHVybiAoKFN0cmluZykgZ25hbWUuZ2V0TmFtZSgpKS50b0xvd2VyQ2FzZShMb2NhbGUuVVMpCisgICAgICAgICAgICAgICAgICAgIC5lbmRzV2l0aCgoKFN0cmluZykgbmFtZSkudG9Mb3dlckNhc2UoTG9jYWxlLlVTKSk7CisgICAgICAgICAgICBjYXNlIEROU19OQU1FOgorICAgICAgICAgICAgICAgIC8vIEROUyBuYW1lIFsyXSB0aGF0IGNhbiBiZSBjb25zdHJ1Y3RlZCBieSBzaW1wbHkgYWRkaW5nCisgICAgICAgICAgICAgICAgLy8gdG8gdGhlIGxlZnQgaGFuZCBzaWRlIG9mIHRoZSBuYW1lIHNhdGlzZmllcyB0aGUgbmFtZQorICAgICAgICAgICAgICAgIC8vIGNvbnN0cmFpbnQ6IGFhYS5hYS5hYSBzYXRpc2ZpZXMgdG8gYWFhLmFhLmFhLCBhYS5hYSwgLi4KKyAgICAgICAgICAgICAgICBTdHJpbmcgZG5zID0gKFN0cmluZykgbmFtZTsKKyAgICAgICAgICAgICAgICBTdHJpbmcgX2RucyA9IChTdHJpbmcpIGduYW1lLmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICBpZiAoZG5zLmVxdWFsc0lnbm9yZUNhc2UoX2RucykpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9kbnMudG9Mb3dlckNhc2UoTG9jYWxlLlVTKS5lbmRzV2l0aCgiLiIgKyBkbnMudG9Mb3dlckNhc2UoTG9jYWxlLlVTKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgY2FzZSBVUl9JRDoKKyAgICAgICAgICAgICAgICAvLyBGb3IgVVJJcyB0aGUgY29uc3RyYWludCAiLnh5ei5jb20iIGlzIHNhdGlzZmllZCBieSBib3RoCisgICAgICAgICAgICAgICAgLy8gYWJjLnh5ei5jb20gYW5kIGFiYy5kZWYueHl6LmNvbS4gIEhvd2V2ZXIsIHRoZSBjb25zdHJhaW50CisgICAgICAgICAgICAgICAgLy8gIi54eXouY29tIiBpcyBub3Qgc2F0aXNmaWVkIGJ5ICJ4eXouY29tIi4KKyAgICAgICAgICAgICAgICAvLyBXaGVuIHRoZSBjb25zdHJhaW50IGRvZXMgbm90IGJlZ2luIHdpdGggYSBwZXJpb2QsIGl0CisgICAgICAgICAgICAgICAgLy8gc3BlY2lmaWVzIGEgaG9zdC4KKyAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IHRoZSBob3N0IGZyb20gVVJJOgorICAgICAgICAgICAgICAgIFN0cmluZyB1cmkgPSAoU3RyaW5nKSBuYW1lOworICAgICAgICAgICAgICAgIGludCBiZWdpbiA9IHVyaS5pbmRleE9mKCI6Ly8iKSszOworICAgICAgICAgICAgICAgIGludCBlbmQgPSB1cmkuaW5kZXhPZignLycsIGJlZ2luKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcgaG9zdCA9IChlbmQgPT0gLTEpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gdXJpLnN1YnN0cmluZyhiZWdpbikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB1cmkuc3Vic3RyaW5nKGJlZ2luLCBlbmQpOworICAgICAgICAgICAgICAgIHVyaSA9IChTdHJpbmcpIGduYW1lLmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICBiZWdpbiA9IHVyaS5pbmRleE9mKCI6Ly8iKSszOworICAgICAgICAgICAgICAgIGVuZCA9IHVyaS5pbmRleE9mKCcvJywgYmVnaW4pOworICAgICAgICAgICAgICAgIFN0cmluZyBfaG9zdCA9IChlbmQgPT0gLTEpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gdXJpLnN1YnN0cmluZyhiZWdpbikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB1cmkuc3Vic3RyaW5nKGJlZ2luLCBlbmQpOworICAgICAgICAgICAgICAgIGlmIChob3N0LnN0YXJ0c1dpdGgoIi4iKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2hvc3QudG9Mb3dlckNhc2UoTG9jYWxlLlVTKS5lbmRzV2l0aChob3N0LnRvTG93ZXJDYXNlKExvY2FsZS5VUykpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBob3N0LmVxdWFsc0lnbm9yZUNhc2UoX2hvc3QpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhc2UgSVBfQUREUjoKKyAgICAgICAgICAgICAgICAvLyBpUEFkZHJlc3MgWzddLCBjaGVjayBieSB1c2luZyByYW5nZXMuCisgICAgICAgICAgICAgICAgYnl0ZVtdIGFkZHJlc3MgPSAoYnl0ZVtdKSBuYW1lOworICAgICAgICAgICAgICAgIGJ5dGVbXSBfYWRkcmVzcyA9IChieXRlW10pIGduYW1lLmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gYWRkcmVzcy5sZW5ndGg7CisgICAgICAgICAgICAgICAgaW50IF9sZW5ndGggPSBfYWRkcmVzcy5sZW5ndGg7CisgICAgICAgICAgICAgICAgaWYgKGxlbmd0aCA9PSBfbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKGFkZHJlc3MsIF9hZGRyZXNzKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGxlbmd0aCA9PSAyKl9sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBfYWRkcmVzcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogc2hvdWxkIHRoZSAybmQgSVAgYWRkcmVzcyBiZSB0cmVhdGVkIGFzIGEgcmFuZ2Ugb3IgYXMgYSBtYXNrPworICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9jdGV0ID0gX2FkZHJlc3NbaV0gJiAweGZmOworICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1pbiA9IGFkZHJlc3NbaV0gJiAweGZmOworICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1heCA9IGFkZHJlc3NbaSArIF9sZW5ndGhdICYgMHhmZjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICgob2N0ZXQgPCBtaW4pIHx8IChvY3RldCA+IG1heCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhc2UgRElSX05BTUU6CisgICAgICAgICAgICAgICAgLy8gRklYTUU6IGZhbHNlOgorICAgICAgICAgICAgICAgIC8vIGRpcmVjdG9yeU5hbWUgYWNjb3JkaW5nIHRvIDQuMS4yLjQKKyAgICAgICAgICAgICAgICAvLyBjb21wYXJpbmcgdGhlIGVuY29kZWQgZm9ybXMgb2YgdGhlIG5hbWVzCisgICAgICAgICAgICAgICAgLy9UT0RPOgorICAgICAgICAgICAgICAgIC8vTGVnYWN5IGltcGxlbWVudGF0aW9ucyBleGlzdCB3aGVyZSBhbiBSRkMgODIyIG5hbWUKKyAgICAgICAgICAgICAgICAvL2lzIGVtYmVkZGVkIGluIHRoZSBzdWJqZWN0IGRpc3Rpbmd1aXNoZWQgbmFtZSBpbiBhbgorICAgICAgICAgICAgICAgIC8vYXR0cmlidXRlIG9mIHR5cGUgRW1haWxBZGRyZXNzCisgICAgICAgICAgICBjYXNlIFg0MDBfQUREUjoKKyAgICAgICAgICAgIGNhc2UgT1RIRVJfTkFNRToKKyAgICAgICAgICAgIGNhc2UgRURJUF9OQU1FOgorICAgICAgICAgICAgY2FzZSBSRUdfSUQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMoZ2V0RW5jb2RlZCgpLCBnbmFtZS5nZXRFbmNvZGVkKCkpOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIGxpc3QgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBHZW5lcmFsTmFtZSBvYmplY3QuCisgICAgICogVGhlIGZpcnN0IGVudHJ5IG9mIHRoZSBsaXN0IGlzIGFuIEludGVnZXIgb2JqZWN0IHJlcHJlc2VudGluZworICAgICAqIHRoZSB0eXBlIG9mIG1hbmUgKDAtOCksIGFuZCB0aGUgc2Vjb25kIGVudHJ5IGlzIGEgdmFsdWUgb2YgdGhlIG5hbWU6CisgICAgICogc3RyaW5nIG9yIEFTTi4xIERFUiBlbmNvZGVkIGZvcm0gZGVwZW5kaW5nIG9uIHRoZSB0eXBlIGFzIGZvbGxvd3M6CisgICAgICogcmZjODIyTmFtZSwgZE5TTmFtZSwgdW5pZm9ybVJlc291cmNlSWRlbnRpZmllciBuYW1lcyBhcmUgcmV0dXJuZWQKKyAgICAgKiBhcyBTdHJpbmdzLCB1c2luZyB0aGUgc3RyaW5nIGZvcm1hdHMgZm9yIHRob3NlIHR5cGVzIChyZmMgMzI4MCkKKyAgICAgKiBJUCB2NCBhZGRyZXNzIG5hbWVzIGFyZSByZXR1cm5lZCB1c2luZyBkb3R0ZWQgcXVhZCBub3RhdGlvbi4KKyAgICAgKiBJUCB2NiBhZGRyZXNzIG5hbWVzIGFyZSByZXR1cm5lZCBpbiB0aGUgZm9ybSAicDE6cDI6Li4uOnA4IiwKKyAgICAgKiB3aGVyZSBwMS1wOCBhcmUgaGV4YWRlY2ltYWwgdmFsdWVzIHJlcHJlc2VudGluZyB0aGUgZWlnaHQgMTYtYml0CisgICAgICogcGllY2VzIG9mIHRoZSBhZGRyZXNzLiByZWdpc3RlcmVkSUQgbmFtZSBhcmUgcmV0dXJuZWQgYXMgU3RyaW5ncworICAgICAqIHJlcHJlc2VudGVkIGFzIGEgc2VyaWVzIG9mIG5vbm5lZ2F0aXZlIGludGVnZXJzIHNlcGFyYXRlZCBieSBwZXJpb2RzLgorICAgICAqIEFuZCBkaXJlY3RvcnkgbmFtZXMgKGRpc3Rpbmd1aXNoZWQgbmFtZXMpIGFyZSByZXR1cm5lZCBpbgorICAgICAqIFJGQyAyMjUzIHN0cmluZyBmb3JtYXQuCisgICAgICogb3RoZXJOYW1lLCBYNDAwQWRkcmVzcywgZWRpUGFydHlOYW1lIHJldHVybmVkIGFzIGJ5dGUgYXJyYXlzCisgICAgICogY29udGFpbmluZyB0aGUgQVNOLjEgREVSIGVuY29kZWQgZm9ybSBvZiB0aGUgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxPYmplY3Q+IGdldEFzTGlzdCgpIHsKKyAgICAgICAgQXJyYXlMaXN0PE9iamVjdD4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxPYmplY3Q+KCk7CisgICAgICAgIHJlc3VsdC5hZGQodGFnKTsKKyAgICAgICAgc3dpdGNoICh0YWcpIHsKKyAgICAgICAgICAgIGNhc2UgT1RIRVJfTkFNRToKKyAgICAgICAgICAgICAgICByZXN1bHQuYWRkKCgoT3RoZXJOYW1lKSBuYW1lKS5nZXRFbmNvZGVkKCkpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBSRkM4MjJfTkFNRToKKyAgICAgICAgICAgIGNhc2UgRE5TX05BTUU6CisgICAgICAgICAgICBjYXNlIFVSX0lEOgorICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQobmFtZSk7IC8vIFN0cmluZworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBSRUdfSUQ6CisgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChPYmplY3RJZGVudGlmaWVyLnRvU3RyaW5nKChpbnRbXSkgbmFtZSkpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBYNDAwX0FERFI6CisgICAgICAgICAgICAgICAgcmVzdWx0LmFkZCgoKE9SQWRkcmVzcykgbmFtZSkuZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRElSX05BTUU6IC8vIGRpcmVjdG9yeU5hbWUgaXMgcmV0dXJuZWQgYXMgYSBTdHJpbmcKKyAgICAgICAgICAgICAgICByZXN1bHQuYWRkKCgoTmFtZSkgbmFtZSkuZ2V0TmFtZShYNTAwUHJpbmNpcGFsLlJGQzIyNTMpKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRURJUF9OQU1FOgorICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQoKChFRElQYXJ0eU5hbWUpIG5hbWUpLmdldEVuY29kZWQoKSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIElQX0FERFI6IC8vaVBBZGRyZXNzIGlzIHJldHVybmVkIGFzIGEgU3RyaW5nLCBub3QgYXMgYSBieXRlIGFycmF5CisgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChpcEJ5dGVzVG9TdHIoKGJ5dGVbXSkgbmFtZSkpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVzdWx0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmcgcmVzdWx0ID0gIiI7CisgICAgICAgIHN3aXRjaCAodGFnKSB7CisgICAgICAgICAgICBjYXNlIE9USEVSX05BTUU6CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gIm90aGVyTmFtZVswXTogIgorICAgICAgICAgICAgICAgICAgICAgICAgICsgQXJyYXkuZ2V0Qnl0ZXNBc1N0cmluZyhnZXRFbmNvZGVkKCkpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBSRkM4MjJfTkFNRToKKyAgICAgICAgICAgICAgICByZXN1bHQgPSAicmZjODIyTmFtZVsxXTogIiArIG5hbWU7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIEROU19OQU1FOgorICAgICAgICAgICAgICAgIHJlc3VsdCA9ICJkTlNOYW1lWzJdOiAiICsgbmFtZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgVVJfSUQ6CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gInVuaWZvcm1SZXNvdXJjZUlkZW50aWZpZXJbNl06ICIgKyBuYW1lOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBSRUdfSUQ6CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gInJlZ2lzdGVyZWRJRFs4XTogIiArIE9iamVjdElkZW50aWZpZXIudG9TdHJpbmcoKGludFtdKSBuYW1lKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgWDQwMF9BRERSOgorICAgICAgICAgICAgICAgIHJlc3VsdCA9ICJ4NDAwQWRkcmVzc1szXTogIgorICAgICAgICAgICAgICAgICAgICAgICAgICsgQXJyYXkuZ2V0Qnl0ZXNBc1N0cmluZyhnZXRFbmNvZGVkKCkpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBESVJfTkFNRToKKyAgICAgICAgICAgICAgICByZXN1bHQgPSAiZGlyZWN0b3J5TmFtZVs0XTogIgorICAgICAgICAgICAgICAgICAgICAgICAgICsgKChOYW1lKSBuYW1lKS5nZXROYW1lKFg1MDBQcmluY2lwYWwuUkZDMjI1Myk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIEVESVBfTkFNRToKKyAgICAgICAgICAgICAgICByZXN1bHQgPSAiZWRpUGFydHlOYW1lWzVdOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgKyBBcnJheS5nZXRCeXRlc0FzU3RyaW5nKGdldEVuY29kZWQoKSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIElQX0FERFI6CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gImlQQWRkcmVzc1s3XTogIiArIGlwQnl0ZXNUb1N0cigoYnl0ZVtdKSBuYW1lKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgLy8gc2hvdWxkIG5ldmVyIGhhcHBlbgorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBlbmNvZGVkIGZvcm0gb2YgdGhpcyBYLjUwOSBHZW5lcmFsTmFtZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIHRoZSBlbmNvZGVkIHZhbHVlIG9mIHRoZSBuYW1lIHdpdGhvdXQgdGhlIHRhZyBhc3NvY2lhdGVkCisgICAgICogICAgICAgICB3aXRoIHRoZSBuYW1lIGluIHRoZSBHZW5lcmFsTmFtZSBzdHJ1Y3R1cmUKKyAgICAgKiBAdGhyb3dzICBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZE5hbWUoKSB7CisgICAgICAgIGlmIChuYW1lX2VuY29kaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIG5hbWVfZW5jb2RpbmcgPSBuYW1lQVNOMVt0YWddLmVuY29kZShuYW1lKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmFtZV9lbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgdGhlIGNvcnJlY3RuZXNzIG9mIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgRE5TIG5hbWUuCisgICAgICogVGhlIGNvcnJlY3RuZXNzIGlzIGNoZWNrZWQgYXMgc3BlY2lmaWVkIGluIFJGQyAxMDM0IHAuIDEwLCBhbmQgbW9kaWZpZWQKKyAgICAgKiBieSBSRkMgMTEyMyAoc2VjdGlvbiAyLjEpLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjaGVja0ROUyhTdHJpbmcgZG5zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc3RyaW5nID0gZG5zLnRvTG93ZXJDYXNlKExvY2FsZS5VUyk7CisgICAgICAgIGludCBsZW5ndGggPSBzdHJpbmcubGVuZ3RoKCk7CisgICAgICAgIC8vIGluZGljYXRlcyBpZiBpdCBpcyBhIGZpcnN0IGxldHRlciBvZiB0aGUgbGFiZWwKKyAgICAgICAgYm9vbGVhbiBmaXJzdF9sZXR0ZXIgPSB0cnVlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjaGFyIGNoID0gc3RyaW5nLmNoYXJBdChpKTsKKyAgICAgICAgICAgIGlmIChmaXJzdF9sZXR0ZXIpIHsKKyAgICAgICAgICAgICAgICBpZiAoKGxlbmd0aCA+IDIpICYmIChjaCA9PSAnKicpICYmIChzdHJpbmcuY2hhckF0KDEpID09ICcuJykpIHsKKyAgICAgICAgICAgICAgICAgICAgZmlyc3RfbGV0dGVyID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoKGNoID4gJ3onIHx8IGNoIDwgJ2EnKSAmJiAoY2ggPCAnMCcgfHwgY2ggPiAnOScpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRE5TIG5hbWUgbXVzdCBzdGFydCB3aXRoIGEgbGV0dGVyOiAiICsgZG5zKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmlyc3RfbGV0dGVyID0gZmFsc2U7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoISgoY2ggPj0gJ2EnICYmIGNoIDw9ICd6JykgfHwgKGNoID49ICcwJyAmJiBjaCA8PSAnOScpCisgICAgICAgICAgICAgICAgICAgIHx8IChjaCA9PSAnLScpIHx8IChjaCA9PSAnLicpKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW5jb3JyZWN0IEROUyBuYW1lOiAiICsgZG5zKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjaCA9PSAnLicpIHsKKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGUgZW5kIG9mIHRoZSBwcmV2aW91cyBsYWJlbCwgaXQgc2hvdWxkIG5vdAorICAgICAgICAgICAgICAgIC8vIGJlICctJyBzaWduCisgICAgICAgICAgICAgICAgaWYgKHN0cmluZy5jaGFyQXQoaS0xKSA9PSAnLScpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbmNvcnJlY3QgRE5TIG5hbWU6IGxhYmVsIGVuZHMgd2l0aCAnLSc6ICIgKyBkbnMpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmaXJzdF9sZXR0ZXIgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHRoZSBjb3JyZWN0bmVzcyBvZiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIFVSSSBuYW1lLgorICAgICAqIFRoZSBjb3JyZWN0bmVzcyBpcyBjaGVja2VkIGFzIHBvaW50ZWQgb3V0IGluIFJGQyAzMjgwIHAuIDM0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjaGVja1VSSShTdHJpbmcgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgVVJJIHVyID0gbmV3IFVSSSh1cmkpOworICAgICAgICAgICAgaWYgKHVyLmdldFNjaGVtZSgpID09IG51bGwgfHwgdXIuZ2V0UmF3U2NoZW1lU3BlY2lmaWNQYXJ0KCkuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJObyBzY2hlbWUgb3Igc2NoZW1lLXNwZWNpZmljLXBhcnQgaW4gdW5pZm9ybVJlc291cmNlSWRlbnRpZmllcjogIiArIHVyaSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIXVyLmlzQWJzb2x1dGUoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUmVsYXRpdmUgdW5pZm9ybVJlc291cmNlSWRlbnRpZmllcjogIiArIHVyaSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFVSSVN5bnRheEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyAoSU9FeGNlcHRpb24pIG5ldyBJT0V4Y2VwdGlvbigiQmFkIHJlcHJlc2VudGF0aW9uIG9mIHVuaWZvcm1SZXNvdXJjZUlkZW50aWZpZXI6ICIgKyB1cmkpLmluaXRDYXVzZShlKTsKKworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgT0lEIGludG8gYXJyYXkgb2YgaW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludFtdIG9pZFN0clRvSW50cyhTdHJpbmcgb2lkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgbGVuZ3RoID0gb2lkLmxlbmd0aCgpOworICAgICAgICBpZiAob2lkLmNoYXJBdChsZW5ndGgtMSkgPT0gJy4nKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkJhZCBPSUQ6ICIgKyBvaWQpOworICAgICAgICB9CisgICAgICAgIGludFtdIHJlc3VsdCA9IG5ldyBpbnRbbGVuZ3RoLzIrMV07IC8vIGJlc3QgY2FzZTogYS5iLmMuZC5lCisgICAgICAgIGludCBudW1iZXIgPSAwOyAvLyB0aGUgbnVtYmVyIG9mIE9JRCdzIGNvbXBvbmVudHMKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaW50IHZhbHVlID0gMDsKKyAgICAgICAgICAgIGludCBwb3MgPSBpOworICAgICAgICAgICAgZm9yICg7IGkgPCBsZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGNoYXIgY2ggPSBvaWQuY2hhckF0KGkpOworICAgICAgICAgICAgICAgIGlmICgoY2ggPCAnMCcpIHx8IChjaCA+ICc5JykpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHZhbHVlID0gMTAgKiB2YWx1ZSArIChjaCAtICcwJyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaSA9PSBwb3MpIHsKKyAgICAgICAgICAgICAgICAvLyB0aGUgbnVtYmVyIHdhcyBub3QgcmVhZAorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQmFkIE9JRDogIiArIG9pZCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHRbbnVtYmVyKytdID0gdmFsdWU7CisgICAgICAgICAgICBpZiAoaSA9PSBsZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNoYXIgY2ggPSBvaWQuY2hhckF0KGkpOworICAgICAgICAgICAgaWYgKGNoICE9ICcuJykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQmFkIE9JRDogIiArIG9pZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKG51bWJlciA8IDIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiT0lEIHNob3VsZCBjb25zaXN0IG9mIG5vIGxlc3MgdGhhbiAyIGNvbXBvbmVudHM6ICIgKyBvaWQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBBcnJheXMuY29weU9mUmFuZ2UocmVzdWx0LCAwLCBudW1iZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGJ5dGVzIG9mIHRoZSBnaXZlbiBJUCBhZGRyZXNzIG9yIG1hc2tlZCBJUCBhZGRyZXNzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIGlwU3RyVG9CeXRlcyhTdHJpbmcgaXApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghSW5ldEFkZHJlc3MuaXNOdW1lcmljKGlwKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJOb3QgYW4gSVAgYWRkcmVzczogIiArIGlwKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gSW5ldEFkZHJlc3MuZ2V0QnlOYW1lKGlwKS5nZXRBZGRyZXNzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyaW5nIGZvcm0gb2YgdGhlIGdpdmVuIElQIGFkZHJlc3MuIEFkZHJlc3NlcyBvZiBsZW5ndGggMngKKyAgICAgKiB0aGUgY2Fub25pY2FsIGxlbmd0aCBhcmUgdHJlYXRlZCBhcyBhIHJvdXRlL21hc2sgcGFpci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBpcEJ5dGVzVG9TdHIoYnl0ZVtdIGlwKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gSW5ldEFkZHJlc3MuZ2V0QnlBZGRyZXNzKG51bGwsIGlwKS5nZXRIb3N0QWRkcmVzcygpOworICAgICAgICB9IGNhdGNoIChVbmtub3duSG9zdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbmV4cGVjdGVkIElQIGFkZHJlc3M6ICIgKyBBcnJheXMudG9TdHJpbmcoaXApKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMUNob2ljZSBBU04xID0gbmV3IEFTTjFDaG9pY2UobmV3IEFTTjFUeXBlW10geworICAgICAgICAgICBuZXcgQVNOMUltcGxpY2l0KDAsIE90aGVyTmFtZS5BU04xKSwKKyAgICAgICAgICAgbmV3IEFTTjFJbXBsaWNpdCgxLCBBU04xU3RyaW5nVHlwZS5JQTVTVFJJTkcpLAorICAgICAgICAgICBuZXcgQVNOMUltcGxpY2l0KDIsIEFTTjFTdHJpbmdUeXBlLklBNVNUUklORyksCisgICAgICAgICAgIG5ldyBBU04xSW1wbGljaXQoMywgT1JBZGRyZXNzLkFTTjEpLAorICAgICAgICAgICBuZXcgQVNOMUltcGxpY2l0KDQsIE5hbWUuQVNOMSksCisgICAgICAgICAgIG5ldyBBU04xSW1wbGljaXQoNSwgRURJUGFydHlOYW1lLkFTTjEpLAorICAgICAgICAgICBuZXcgQVNOMUltcGxpY2l0KDYsIEFTTjFTdHJpbmdUeXBlLklBNVNUUklORyksCisgICAgICAgICAgIG5ldyBBU04xSW1wbGljaXQoNywgQVNOMU9jdGV0U3RyaW5nLmdldEluc3RhbmNlKCkpLAorICAgICAgICAgICBuZXcgQVNOMUltcGxpY2l0KDgsIEFTTjFPaWQuZ2V0SW5zdGFuY2UoKSkgfSkgeworCisgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0T2JqZWN0VG9FbmNvZGUoT2JqZWN0IHZhbHVlKSB7CisgICAgICAgICAgICByZXR1cm4gKChHZW5lcmFsTmFtZSkgdmFsdWUpLm5hbWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldEluZGV4KGphdmEubGFuZy5PYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gICgoR2VuZXJhbE5hbWUpIG9iamVjdCkudGFnOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIEdlbmVyYWxOYW1lIHJlc3VsdDsKKyAgICAgICAgICAgIHN3aXRjaCAoaW4uY2hvaWNlSW5kZXgpIHsKKyAgICAgICAgICAgICAgICBjYXNlIE9USEVSX05BTUU6IC8vIE90aGVyTmFtZQorICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBuZXcgR2VuZXJhbE5hbWUoKE90aGVyTmFtZSkgaW4uY29udGVudCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgUkZDODIyX05BTUU6IC8vIHJmYzgyMk5hbWUKKyAgICAgICAgICAgICAgICBjYXNlIEROU19OQU1FOiAvLyBkTlNOYW1lCisgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBHZW5lcmFsTmFtZShpbi5jaG9pY2VJbmRleCwgKFN0cmluZykgaW4uY29udGVudCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgWDQwMF9BRERSOgorICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBuZXcgR2VuZXJhbE5hbWUoKE9SQWRkcmVzcykgaW4uY29udGVudCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgRElSX05BTUU6IC8vIGRpcmVjdG9yeU5hbWUgKFguNTAwIE5hbWUpCisgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBHZW5lcmFsTmFtZSgoTmFtZSkgaW4uY29udGVudCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgRURJUF9OQU1FOiAvLyBlZGlQYXJ0eU5hbWUKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IEdlbmVyYWxOYW1lKChFRElQYXJ0eU5hbWUpIGluLmNvbnRlbnQpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIFVSX0lEOiAvLyB1bmlmb3JtUmVzb3VyY2VJZGVudGlmaWVyCisgICAgICAgICAgICAgICAgICAgIFN0cmluZyB1cmkgPSAoU3RyaW5nKSBpbi5jb250ZW50OworICAgICAgICAgICAgICAgICAgICBpZiAodXJpLmluZGV4T2YoIjoiKSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJHZW5lcmFsTmFtZTogc2NoZW1lIGlzIG1pc3NpbmcgaW4gVVJJOiAiICsgdXJpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBuZXcgR2VuZXJhbE5hbWUoaW4uY2hvaWNlSW5kZXgsIHVyaSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgSVBfQUREUjogLy8gaVBBZGRyZXNzCisgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBHZW5lcmFsTmFtZSgoYnl0ZVtdKSBpbi5jb250ZW50KTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSBSRUdfSUQ6IC8vIHJlZ2lzdGVyZWRJRAorICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBuZXcgR2VuZXJhbE5hbWUoaW4uY2hvaWNlSW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0SWRlbnRpZmllci50b1N0cmluZygoaW50W10pIGluLmNvbnRlbnQpKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJHZW5lcmFsTmFtZTogdW5rbm93biB0YWc6ICIgKyBpbi5jaG9pY2VJbmRleCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHQuZW5jb2RpbmcgPSBpbi5nZXRFbmNvZGVkKCk7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgfTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9HZW5lcmFsTmFtZXMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9HZW5lcmFsTmFtZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45M2M0YWYxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0dlbmVyYWxOYW1lcy5qYXZhCkBAIC0wLDAgKzEsMTM0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXF1ZW5jZU9mOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworCisKKy8qKgorICogVGhlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgQVNOLjEgREVSIGVuY29kaW5nL2RlY29kaW5nIHdvcmsKKyAqIHdpdGggdGhlIEdlbmVyYWxOYW1lcyBzdHJ1Y3R1cmUgd2hpY2ggaXMgYSBwYXJ0IG9mIFguNTA5IGNlcnRpZmljYXRlCisgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIC0KKyAqICBJbnRlcm5ldCBYLjUwOSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgorICogIENlcnRpZmljYXRlIGFuZCBDZXJ0aWZpY2F0ZSBSZXZvY2F0aW9uIExpc3QgKENSTCkgUHJvZmlsZS4KKyAqICBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCk6CisgKgorICoKKyAqIDxwcmU+CisgKiAgIEdlbmVyYWxOYW1lcyA6Oj0gU0VRVUVOQ0UgU0laRSAoMS4uTUFYKSBPRiBHZW5lcmFsTmFtZQorICogPC9wcmU+CisgKgorICogQHNlZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5OYW1lQ29uc3RyYWludHMKKyAqIEBzZWUgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuR2VuZXJhbFN1YnRyZWUKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEdlbmVyYWxOYW1lcyB7CisgICAgLyoqIHRoZSB2YWx1ZXMgb2YgR2VuZXJhbE5hbWUgKi8KKyAgICBwcml2YXRlIExpc3Q8R2VuZXJhbE5hbWU+IGdlbmVyYWxOYW1lczsKKyAgICAvKiogdGhlIEFTTi4xIGVuY29kZWQgZm9ybSBvZiBHZW5lcmFsTmFtZXMgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGluZzsKKworICAgIHB1YmxpYyBHZW5lcmFsTmFtZXMoKSB7CisgICAgICAgIGdlbmVyYWxOYW1lcyA9IG5ldyBBcnJheUxpc3Q8R2VuZXJhbE5hbWU+KCk7CisgICAgfQorCisgICAgcHVibGljIEdlbmVyYWxOYW1lcyhMaXN0PEdlbmVyYWxOYW1lPiBnZW5lcmFsTmFtZXMpIHsKKyAgICAgICAgdGhpcy5nZW5lcmFsTmFtZXMgPSBnZW5lcmFsTmFtZXM7CisgICAgfQorCisgICAgcHJpdmF0ZSBHZW5lcmFsTmFtZXMoTGlzdDxHZW5lcmFsTmFtZT4gZ2VuZXJhbE5hbWVzLCBieXRlW10gZW5jb2RpbmcpIHsKKyAgICAgICAgdGhpcy5nZW5lcmFsTmFtZXMgPSBnZW5lcmFsTmFtZXM7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIHZhbHVlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxHZW5lcmFsTmFtZT4gZ2V0TmFtZXMoKSB7CisgICAgICAgIGlmICgoZ2VuZXJhbE5hbWVzID09IG51bGwpIHx8IChnZW5lcmFsTmFtZXMuc2l6ZSgpID09IDApKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IEFycmF5TGlzdDxHZW5lcmFsTmFtZT4oZ2VuZXJhbE5hbWVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb2xsZWN0aW9uIG9mIHBhaXJzOiAoSW50ZWdlciAodGFnKSwgT2JqZWN0IChuYW1lIHZhbHVlKSkqCisgICAgICovCisgICAgcHVibGljIENvbGxlY3Rpb248TGlzdDw/Pj4gZ2V0UGFpcnNMaXN0KCkgeworICAgICAgICBDb2xsZWN0aW9uPExpc3Q8Pz4+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8TGlzdDw/Pj4oKTsKKyAgICAgICAgaWYgKGdlbmVyYWxOYW1lcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgICAgIGZvciAoR2VuZXJhbE5hbWUgZ2VuZXJhbE5hbWUgOiBnZW5lcmFsTmFtZXMpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hZGQoZ2VuZXJhbE5hbWUuZ2V0QXNMaXN0KCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYWRkTmFtZShHZW5lcmFsTmFtZSBuYW1lKSB7CisgICAgICAgIGVuY29kaW5nID0gbnVsbDsKKyAgICAgICAgaWYgKGdlbmVyYWxOYW1lcyA9PSBudWxsKSB7CisgICAgICAgICAgICBnZW5lcmFsTmFtZXMgPSBuZXcgQXJyYXlMaXN0PEdlbmVyYWxOYW1lPigpOworICAgICAgICB9CisgICAgICAgIGdlbmVyYWxOYW1lcy5hZGQobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBlbmNvZGVkIGZvcm0gb2YgdGhpcyBYLjUwOSBHZW5lcmFsTmFtZXMgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSBBU04xLmVuY29kZSh0aGlzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZHVtcFZhbHVlKFN0cmluZ0J1aWxkZXIgc2IsIFN0cmluZyBwcmVmaXgpIHsKKyAgICAgICAgaWYgKGdlbmVyYWxOYW1lcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZm9yIChHZW5lcmFsTmFtZSBnZW5lcmFsTmFtZSA6IGdlbmVyYWxOYW1lcykgeworICAgICAgICAgICAgc2IuYXBwZW5kKHByZWZpeCk7CisgICAgICAgICAgICBzYi5hcHBlbmQoZ2VuZXJhbE5hbWUpOworICAgICAgICAgICAgc2IuYXBwZW5kKCdcbicpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQVNOLjEgREVSIFguNTA5IEdlbmVyYWxOYW1lcyBlbmNvZGVyL2RlY29kZXIgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xVHlwZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZU9mKEdlbmVyYWxOYW1lLkFTTjEpIHsKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBHZW5lcmFsTmFtZXMoKExpc3Q8R2VuZXJhbE5hbWU+KSBpbi5jb250ZW50LCBpbi5nZXRFbmNvZGVkKCkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBDb2xsZWN0aW9uIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICBHZW5lcmFsTmFtZXMgZ25zID0gKEdlbmVyYWxOYW1lcykgb2JqZWN0OworICAgICAgICAgICAgcmV0dXJuIGducy5nZW5lcmFsTmFtZXM7CisgICAgICAgIH0KKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0dlbmVyYWxTdWJ0cmVlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvR2VuZXJhbFN1YnRyZWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40Mjk4N2I2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0dlbmVyYWxTdWJ0cmVlLmphdmEKQEAgLTAsMCArMSwxMjggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292LCBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xSW1wbGljaXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUludGVnZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworCisvKioKKyAqIFRoZSBjbGFzcyBlbmNhcHN1bGF0ZXMgdGhlIEFTTi4xIERFUiBlbmNvZGluZy9kZWNvZGluZyB3b3JrCisgKiB3aXRoIHRoZSBHZW5lcmFsU3VidHJlZSBzdHJ1Y3R1cmUgd2hpY2ggaXMgYSBwYXJ0IG9mIFguNTA5IGNlcnRpZmljYXRlOgorICogKGFzIHNwZWNpZmllZCBpbiBSRkMgMzI4MCAtCisgKiAgSW50ZXJuZXQgWC41MDkgUHVibGljIEtleSBJbmZyYXN0cnVjdHVyZS4KKyAqICBDZXJ0aWZpY2F0ZSBhbmQgQ2VydGlmaWNhdGUgUmV2b2NhdGlvbiBMaXN0IChDUkwpIFByb2ZpbGUuCisgKiAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpOgorICoKKyAqIDxwcmU+CisgKgorICogICBHZW5lcmFsU3VidHJlZSA6Oj0gU0VRVUVOQ0UgeworICogICAgICAgIGJhc2UgICAgICAgICAgICAgICAgICAgIEdlbmVyYWxOYW1lLAorICogICAgICAgIG1pbmltdW0gICAgICAgICBbMF0gICAgIEJhc2VEaXN0YW5jZSBERUZBVUxUIDAsCisgKiAgICAgICAgbWF4aW11bSAgICAgICAgIFsxXSAgICAgQmFzZURpc3RhbmNlIE9QVElPTkFMIH0KKyAqCisgKiAgIEJhc2VEaXN0YW5jZSA6Oj0gSU5URUdFUiAoMC4uTUFYKQorICoKKyAqIDwvcHJlPgorICoKKyAqIEBzZWUgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuTmFtZUNvbnN0cmFpbnRzCisgKiBAc2VlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LkdlbmVyYWxOYW1lCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBHZW5lcmFsU3VidHJlZSB7CisgICAgLyoqIHRoZSB2YWx1ZSBvZiBiYXNlIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIEdlbmVyYWxOYW1lIGJhc2U7CisgICAgLyoqIHRoZSB2YWx1ZSBvZiBtaW5pbXVtIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBtaW5pbXVtOworICAgIC8qKiB0aGUgdmFsdWUgb2YgbWF4aW11bSBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbWF4aW11bTsKKyAgICAvKiogdGhlIEFTTi4xIGVuY29kZWQgZm9ybSBvZiBHZW5lcmFsU3VidHJlZSAqLworICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kaW5nOworCisgICAgcHVibGljIEdlbmVyYWxTdWJ0cmVlKEdlbmVyYWxOYW1lIGJhc2UsIGludCBtaW5pbXVtLCBpbnQgbWF4aW11bSkgeworICAgICAgICB0aGlzLmJhc2UgPSBiYXNlOworICAgICAgICB0aGlzLm1pbmltdW0gPSBtaW5pbXVtOworICAgICAgICB0aGlzLm1heGltdW0gPSBtYXhpbXVtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGJhc2UgZmllbGQgb2YgdGhlIHN0cnVjdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgR2VuZXJhbE5hbWUgZ2V0QmFzZSgpIHsKKyAgICAgICAgcmV0dXJuIGJhc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBlbmNvZGVkIGZvcm0gb2YgdGhpcyBYLjUwOSBHZW5lcmFsU3VidHJlZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBkdW1wVmFsdWUoU3RyaW5nQnVpbGRlciBzYiwgU3RyaW5nIHByZWZpeCkgeworICAgICAgICBzYi5hcHBlbmQocHJlZml4KS5hcHBlbmQoIkdlbmVyYWwgU3VidHJlZTogW1xuIik7CisgICAgICAgIHNiLmFwcGVuZChwcmVmaXgpLmFwcGVuZCgiICBiYXNlOiAiKS5hcHBlbmQoYmFzZSkuYXBwZW5kKCdcbicpOworICAgICAgICBzYi5hcHBlbmQocHJlZml4KS5hcHBlbmQoIiAgbWluaW11bTogIikuYXBwZW5kKG1pbmltdW0pLmFwcGVuZCgnXG4nKTsKKyAgICAgICAgaWYgKG1heGltdW0gPj0gMCkgeworICAgICAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCIgIG1heGltdW06ICIpLmFwcGVuZChtYXhpbXVtKS5hcHBlbmQoJ1xuJyk7CisgICAgICAgIH0KKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJdXG4iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBU04uMSBERVIgWC41MDkgR2VuZXJhbFN1YnRyZWUgZW5jb2Rlci9kZWNvZGVyIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVNlcXVlbmNlIEFTTjEgPSBuZXcgQVNOMVNlcXVlbmNlKG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgIEdlbmVyYWxOYW1lLkFTTjEsCisgICAgICAgICAgICBuZXcgQVNOMUltcGxpY2l0KDAsIEFTTjFJbnRlZ2VyLmdldEluc3RhbmNlKCkpLAorICAgICAgICAgICAgbmV3IEFTTjFJbXBsaWNpdCgxLCBBU04xSW50ZWdlci5nZXRJbnN0YW5jZSgpKSB9KSB7CisgICAgICAgIHsKKyAgICAgICAgICAgIHNldERlZmF1bHQobmV3IGJ5dGVbXSB7MH0sIDEpOyAgLy8gbWluaW11bSAwCisgICAgICAgICAgICBzZXRPcHRpb25hbCgyKTsgICAgICAgICAgICAgICAgIC8vIG1heGltdW0gb3B0aW9uYWwKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgICAgIE9iamVjdFtdIHZhbHVlcyA9IChPYmplY3RbXSkgaW4uY29udGVudDsKKyAgICAgICAgICAgIGludCBtYXhpbXVtID0gLTE7IC8vIGlzIG9wdGlvbmFsIG1heGltdW0gbWlzc2luZz8KKyAgICAgICAgICAgIGlmICh2YWx1ZXNbMl0gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG1heGltdW0gPSBBU04xSW50ZWdlci50b0ludFZhbHVlKHZhbHVlc1syXSk7IC8vIG5vIQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBHZW5lcmFsU3VidHJlZSgoR2VuZXJhbE5hbWUpIHZhbHVlc1swXSwKKyAgICAgICAgICAgICAgICAgICAgQVNOMUludGVnZXIudG9JbnRWYWx1ZSh2YWx1ZXNbMV0pLAorICAgICAgICAgICAgICAgICAgICBtYXhpbXVtKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCwgT2JqZWN0W10gdmFsdWVzKSB7CisgICAgICAgICAgICBHZW5lcmFsU3VidHJlZSBncyA9IChHZW5lcmFsU3VidHJlZSkgb2JqZWN0OworICAgICAgICAgICAgdmFsdWVzWzBdID0gZ3MuYmFzZTsKKyAgICAgICAgICAgIHZhbHVlc1sxXSA9IEFTTjFJbnRlZ2VyLmZyb21JbnRWYWx1ZShncy5taW5pbXVtKTsKKyAgICAgICAgICAgIGlmIChncy5tYXhpbXVtID4gLTEpIHsKKyAgICAgICAgICAgICAgICB2YWx1ZXNbMl0gPSBBU04xSW50ZWdlci5mcm9tSW50VmFsdWUoZ3MubWF4aW11bSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0dlbmVyYWxTdWJ0cmVlcy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0dlbmVyYWxTdWJ0cmVlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM0ZjRiYzcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvR2VuZXJhbFN1YnRyZWVzLmphdmEKQEAgLTAsMCArMSw5MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5OworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2VxdWVuY2VPZjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKKworLyoqCisgKiBUaGUgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBBU04uMSBERVIgZW5jb2RpbmcvZGVjb2Rpbmcgd29yaworICogd2l0aCB0aGUgR2VuZXJhbFN1YnRyZWVzIHN0cnVjdHVyZSB3aGljaCBpcyBhIHBhcnQgb2YgWC41MDkgY2VydGlmaWNhdGU6CisgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIC0KKyAqICBJbnRlcm5ldCBYLjUwOSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgorICogIENlcnRpZmljYXRlIGFuZCBDZXJ0aWZpY2F0ZSBSZXZvY2F0aW9uIExpc3QgKENSTCkgUHJvZmlsZS4KKyAqICBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCk6CisgKgorICogPHByZT4KKyAqICAgR2VuZXJhbFN1YnRyZWVzIDo6PSBTRVFVRU5DRSBTSVpFICgxLi5NQVgpIE9GIEdlbmVyYWxTdWJ0cmVlCisgKiA8L3ByZT4KKyAqCisgKiBAc2VlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5Lk5hbWVDb25zdHJhaW50cworICogQHNlZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5HZW5lcmFsU3VidHJlZQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgR2VuZXJhbFN1YnRyZWVzIHsKKyAgICAvKiogdGhlIGxpc3Qgb2YgdmFsdWVzIG9mIEdlbmVyYWxTdWJ0cmVlcyAqLworICAgIHByaXZhdGUgTGlzdDxHZW5lcmFsU3VidHJlZT4gZ2VuZXJhbFN1YnRyZWVzOworICAgIC8qKiB0aGUgQVNOLjEgZW5jb2RlZCBmb3JtIG9mIEdlbmVyYWxTdWJ0cmVlcyAqLworICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kaW5nOworCisgICAgcHVibGljIEdlbmVyYWxTdWJ0cmVlcyhMaXN0PEdlbmVyYWxTdWJ0cmVlPiBnZW5lcmFsU3VidHJlZXMpIHsKKyAgICAgICAgLy8gVE9ETzogdGhlIHNpemUgc2hvdWxkIG5vdCBiZSBsZXNzIHRoYW4gb25lCisgICAgICAgIHRoaXMuZ2VuZXJhbFN1YnRyZWVzID0gZ2VuZXJhbFN1YnRyZWVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxpc3Qgb2YgdmFsdWVzIG9mIHN1YnRyZWVzLgorICAgICAqLworICAgIHB1YmxpYyBMaXN0PEdlbmVyYWxTdWJ0cmVlPiBnZXRTdWJ0cmVlcygpIHsKKyAgICAgICAgcmV0dXJuIGdlbmVyYWxTdWJ0cmVlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFTTi4xIGVuY29kZWQgZm9ybSBvZiB0aGlzIFguNTA5IEFsZ29yaXRobUlkZW50aWZpZXIgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSBBU04xLmVuY29kZSh0aGlzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgLyoqCisgICAgICogQVNOLjEgREVSIFguNTA5IEdlbmVyYWxTdWJ0cmVlcyBlbmNvZGVyL2RlY29kZXIgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xVHlwZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZU9mKEdlbmVyYWxTdWJ0cmVlLkFTTjEpIHsKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBHZW5lcmFsU3VidHJlZXMoKExpc3Q8R2VuZXJhbFN1YnRyZWU+KSBpbi5jb250ZW50KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgQ29sbGVjdGlvbiBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgR2VuZXJhbFN1YnRyZWVzIGdzcyA9IChHZW5lcmFsU3VidHJlZXMpIG9iamVjdDsKKyAgICAgICAgICAgIHJldHVybiAoZ3NzLmdlbmVyYWxTdWJ0cmVlcyA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICA/IG5ldyBBcnJheUxpc3Q8R2VuZXJhbFN1YnRyZWU+KCkKKyAgICAgICAgICAgICAgICAgICAgOiBnc3MuZ2VuZXJhbFN1YnRyZWVzOworICAgICAgICB9CisgICAgfTsKK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0luZm9BY2Nlc3NTeW50YXguamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9JbmZvQWNjZXNzU3ludGF4LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2QwZGQ0ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9JbmZvQWNjZXNzU3ludGF4LmphdmEKQEAgLTAsMCArMSwxMTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXF1ZW5jZU9mOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworCisvKioKKyAqIFRoZSBjbGFzcyBlbmNhcHN1bGF0ZXMgdGhlIEFTTi4xIERFUiBlbmNvZGluZy9kZWNvZGluZyB3b3JrCisgKiB3aXRoIHRoZSBTdWJqZWN0SW5mb0FjY2Vzc1N5bnRheCBhbmQgQXV0aG9yaXR5SW5mb0FjY2Vzc1N5bnRheAorICogd2hpY2ggYXJlIGEgcGFydCBvZiBYLjUwOSBmcmFtZXdvcmsKKyAqIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODAgLQorICogIEludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUuCisgKiAgQ2VydGlmaWNhdGUgYW5kIENlcnRpZmljYXRlIFJldm9jYXRpb24gTGlzdCAoQ1JMKSBQcm9maWxlLgorICogIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KToKKyAqCisgKiAgU3ViamVjdEluZm9BY2Nlc3NTeW50YXggIDo6PQorICogICAgICBTRVFVRU5DRSBTSVpFICgxLi5NQVgpIE9GIEFjY2Vzc0Rlc2NyaXB0aW9ucworCisgKiAgQXV0aG9yaXR5SW5mb0FjY2Vzc1N5bnRheCAgOjo9CisgKiAgICAgIFNFUVVFTkNFIFNJWkUgKDEuLk1BWCkgT0YgQWNjZXNzRGVzY3JpcHRpb25zCisgKgorICogIEFjY2Vzc0Rlc2NyaXB0aW9uICA6Oj0gIFNFUVVFTkNFIHsKKyAqICAgICAgYWNjZXNzTWV0aG9kICAgICAgICAgIE9CSkVDVCBJREVOVElGSUVSLAorICogICAgICBhY2Nlc3NMb2NhdGlvbiAgICAgICAgR2VuZXJhbE5hbWUgIH0KKyAqCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBJbmZvQWNjZXNzU3ludGF4IGV4dGVuZHMgRXh0ZW5zaW9uVmFsdWUgeworICAgIHByaXZhdGUgZmluYWwgTGlzdDw/PiBhY2Nlc3NEZXNjcmlwdGlvbnM7CisKKyAgICBwcml2YXRlIEluZm9BY2Nlc3NTeW50YXgoTGlzdDw/PiBhY2Nlc3NEZXNjcmlwdGlvbnMsIGJ5dGVbXSBlbmNvZGluZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFjY2Vzc0Rlc2NyaXB0aW9ucyA9PSBudWxsIHx8IGFjY2Vzc0Rlc2NyaXB0aW9ucy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQWNjZXNzRGVzY3JpcHRpb25zIGxpc3QgaXMgbnVsbCBvciBlbXB0eSIpOworICAgICAgICB9CisgICAgICAgIHRoaXMuYWNjZXNzRGVzY3JpcHRpb25zID0gYWNjZXNzRGVzY3JpcHRpb25zOworICAgICAgICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBlbmNvZGVkIGZvcm0gb2YgdGhpcyBYLjUwOSBJbmZvQWNjZXNzU3ludGF4LgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIEluZm9BY2Nlc3NTeW50YXggZGVjb2RlKGJ5dGVbXSBlbmNvZGluZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuICgoSW5mb0FjY2Vzc1N5bnRheCkgQVNOMS5kZWNvZGUoZW5jb2RpbmcpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXMgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICByZXMuYXBwZW5kKCJcbi0tLS0gSW5mb0FjY2Vzc1N5bnRheDoiKTsKKyAgICAgICAgaWYgKGFjY2Vzc0Rlc2NyaXB0aW9ucyAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKE9iamVjdCBhY2Nlc3NEZXNjcmlwdGlvbiA6IGFjY2Vzc0Rlc2NyaXB0aW9ucykgeworICAgICAgICAgICAgICAgIHJlcy5hcHBlbmQoJ1xuJyk7CisgICAgICAgICAgICAgICAgcmVzLmFwcGVuZChhY2Nlc3NEZXNjcmlwdGlvbik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmVzLmFwcGVuZCgiXG4tLS0tIEluZm9BY2Nlc3NTeW50YXggRU5EXG4iKTsKKyAgICAgICAgcmV0dXJuIHJlcy50b1N0cmluZygpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBkdW1wVmFsdWUoU3RyaW5nQnVpbGRlciBzYiwgU3RyaW5nIHByZWZpeCkgeworICAgICAgICBzYi5hcHBlbmQocHJlZml4KS5hcHBlbmQoIkFjY2Vzc0Rlc2NyaXB0aW9uczpcbiIpOworICAgICAgICBpZiAoYWNjZXNzRGVzY3JpcHRpb25zID09IG51bGwgfHwgYWNjZXNzRGVzY3JpcHRpb25zLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgc2IuYXBwZW5kKCJOVUxMXG4iKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZvciAoT2JqZWN0IGFjY2Vzc0Rlc2NyaXB0aW9uIDogYWNjZXNzRGVzY3JpcHRpb25zKSB7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKGFjY2Vzc0Rlc2NyaXB0aW9uLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBBU04uMSBERVIgWC41MDkgQXV0aG9yaXR5SW5mb0FjY2Vzc1N5bnRheCBhbmQgU3ViamVjdEluZm9BY2Nlc3NTeW50YXgKKyAgICAgKiBlbmNvZGVyL2RlY29kZXIgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xVHlwZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZU9mKEFjY2Vzc0Rlc2NyaXB0aW9uLkFTTjEpIHsKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgSW5mb0FjY2Vzc1N5bnRheCgoTGlzdDw/PikgaW4uY29udGVudCwgaW4uZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgQ29sbGVjdGlvbiBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgcmV0dXJuICgoSW5mb0FjY2Vzc1N5bnRheCkgb2JqZWN0KS5hY2Nlc3NEZXNjcmlwdGlvbnM7CisgICAgICAgIH0KKyAgICB9OworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvSW5oaWJpdEFueVBvbGljeS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0luaGliaXRBbnlQb2xpY3kuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMjc0NzFlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0luaGliaXRBbnlQb2xpY3kuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xSW50ZWdlcjsKKworLyoqCisgKiBJbmhpYml0QW55UG9saWN5IENlcnRpZmljYXRlIEV4dGVuc2lvbiAoT0lEID0gMi41LjI5LjU0KQorICogSXRzIEFTTi4xIG5vdGF0aW9uIGlzIGFzIGZvbGxvd3M6CisgKiA8cHJlPgorICogIGlkLWNlLWluaGliaXRBbnlQb2xpY3kgT0JKRUNUIElERU5USUZJRVIgOjo9ICB7IGlkLWNlIDU0IH0KKyAqCisgKiAgSW5oaWJpdEFueVBvbGljeSA6Oj0gU2tpcENlcnRzCisgKgorICogIFNraXBDZXJ0cyA6Oj0gSU5URUdFUiAoMC4uTUFYKQorICogPC9wcmU+CisgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEluaGliaXRBbnlQb2xpY3kgZXh0ZW5kcyBFeHRlbnNpb25WYWx1ZSB7CisKKyAgICAvKiogdGhlIHZhbHVlIG9mIHRoZSBleHRlbnNpb24gKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBza2lwQ2VydHM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCBvbiB0aGUgYmFzZSBvZiBpdHMgZW5jb2RlZCBmb3JtLgorICAgICAqLworICAgIHB1YmxpYyBJbmhpYml0QW55UG9saWN5KGJ5dGVbXSBlbmNvZGluZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoZW5jb2RpbmcpOworICAgICAgICB0aGlzLnNraXBDZXJ0cyA9IG5ldyBCaWdJbnRlZ2VyKChieXRlW10pCisgICAgICAgICAgICAgICAgQVNOMUludGVnZXIuZ2V0SW5zdGFuY2UoKS5kZWNvZGUoZW5jb2RpbmcpKS5pbnRWYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgQVNOLjEgZW5jb2RlZCBmb3JtIG9mIHRoZSBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIGVuY29kaW5nID0gQVNOMUludGVnZXIuZ2V0SW5zdGFuY2UoKQorICAgICAgICAgICAgICAgIC5lbmNvZGUoQVNOMUludGVnZXIuZnJvbUludFZhbHVlKHNraXBDZXJ0cykpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZHVtcFZhbHVlKFN0cmluZ0J1aWxkZXIgc2IsIFN0cmluZyBwcmVmaXgpIHsKKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJJbmhpYml0IEFueS1Qb2xpY3k6ICIpLmFwcGVuZChza2lwQ2VydHMpLmFwcGVuZCgnXG4nKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvSW52YWxpZGl0eURhdGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9JbnZhbGlkaXR5RGF0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI3YzE4NDcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvSW52YWxpZGl0eURhdGUuamF2YQpAQCAtMCwwICsxLDcxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xR2VuZXJhbGl6ZWRUaW1lOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworCisvKioKKyAqIENSTCBFbnRyeSdzIEludmFsaWRpdHkgRGF0ZSBFeHRlbnNpb24gKE9JRCA9IDIuNS4yOS4yNCkuCisgKiA8cHJlPgorICogICBpZC1jZS1pbnZhbGlkaXR5RGF0ZSBPQkpFQ1QgSURFTlRJRklFUiA6Oj0geyBpZC1jZSAyNCB9CisgKgorICogICBpbnZhbGlkaXR5RGF0ZSA6Oj0gIEdlbmVyYWxpemVkVGltZQorICogPC9wcmU+CisgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSW52YWxpZGl0eURhdGUgZXh0ZW5kcyBFeHRlbnNpb25WYWx1ZSB7CisgICAgLyoqIGludmFsaWRpdHkgZGF0ZSB2YWx1ZSAqLworICAgIHByaXZhdGUgZmluYWwgRGF0ZSBkYXRlOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyB0aGUgb2JqZWN0IG9uIHRoZSBiYXNlIG9mIGl0cyBlbmNvZGVkIGZvcm0uCisgICAgICovCisgICAgcHVibGljIEludmFsaWRpdHlEYXRlKGJ5dGVbXSBlbmNvZGluZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoZW5jb2RpbmcpOworICAgICAgICBkYXRlID0gKERhdGUpIEFTTjEuZGVjb2RlKGVuY29kaW5nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbnZhbGlkaXR5IGRhdGUuCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0RGF0ZSgpIHsKKyAgICAgICAgcmV0dXJuIGRhdGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBlbmNvZGVkIGZvcm0gb2YgdGhpcyBYLjUwOSBJbnZhbGlkaXR5RGF0ZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSBBU04xLmVuY29kZShkYXRlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGR1bXBWYWx1ZShTdHJpbmdCdWlsZGVyIHNiLCBTdHJpbmcgcHJlZml4KSB7CisgICAgICAgIHNiLmFwcGVuZChwcmVmaXgpLmFwcGVuZCgiSW52YWxpZGl0eSBEYXRlOiBbICIpLmFwcGVuZChkYXRlKS5hcHBlbmQoIiBdXG4iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBU04uMSBFbmNvZGVyL0RlY29kZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xVHlwZSBBU04xID0gQVNOMUdlbmVyYWxpemVkVGltZS5nZXRJbnN0YW5jZSgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0lzc3VpbmdEaXN0cmlidXRpb25Qb2ludC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L0lzc3VpbmdEaXN0cmlidXRpb25Qb2ludC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE3NTMzYTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvSXNzdWluZ0Rpc3RyaWJ1dGlvblBvaW50LmphdmEKQEAgLTAsMCArMSwxNzcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFCb29sZWFuOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFFeHBsaWNpdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xSW1wbGljaXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworCisvKioKKyAqIENSTCdzIElzc3VpbmcgRGlzdHJpYnV0aW9uIFBvaW50IEV4dGVuc2lvbiAoT0lEID0gMi41LjI5LjI4KS4KKyAqIDxwcmU+CisgKiAgIGlkLWNlLWlzc3VpbmdEaXN0cmlidXRpb25Qb2ludCBPQkpFQ1QgSURFTlRJRklFUiA6Oj0geyBpZC1jZSAyOCB9CisgKgorICogICBpc3N1aW5nRGlzdHJpYnV0aW9uUG9pbnQgOjo9IFNFUVVFTkNFIHsKKyAqICAgICAgZGlzdHJpYnV0aW9uUG9pbnQgICAgICAgICAgWzBdIERpc3RyaWJ1dGlvblBvaW50TmFtZSBPUFRJT05BTCwKKyAqICAgICAgb25seUNvbnRhaW5zVXNlckNlcnRzICAgICAgWzFdIEJPT0xFQU4gREVGQVVMVCBGQUxTRSwKKyAqICAgICAgb25seUNvbnRhaW5zQ0FDZXJ0cyAgICAgICAgWzJdIEJPT0xFQU4gREVGQVVMVCBGQUxTRSwKKyAqICAgICAgb25seVNvbWVSZWFzb25zICAgICAgICAgICAgWzNdIFJlYXNvbkZsYWdzIE9QVElPTkFMLAorICogICAgICBpbmRpcmVjdENSTCAgICAgICAgICAgICAgICBbNF0gQk9PTEVBTiBERUZBVUxUIEZBTFNFLAorICogICAgICBvbmx5Q29udGFpbnNBdHRyaWJ1dGVDZXJ0cyBbNV0gQk9PTEVBTiBERUZBVUxUIEZBTFNFCisgKiAgIH0KKyAqIDwvcHJlPgorICogKGFzIHNwZWNpZmllZCBpbiBSRkMgMzI4MCBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCkKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIElzc3VpbmdEaXN0cmlidXRpb25Qb2ludCBleHRlbmRzIEV4dGVuc2lvblZhbHVlIHsKKyAgICAvLyB2YWx1ZXMgb2YgdGhlIGZpZWxkcyBvZiB0aGUgc3RydWN0dXJlCisgICAgcHJpdmF0ZSBEaXN0cmlidXRpb25Qb2ludE5hbWUgZGlzdHJpYnV0aW9uUG9pbnQ7CisgICAgcHJpdmF0ZSBib29sZWFuIG9ubHlDb250YWluc1VzZXJDZXJ0cyA9IGZhbHNlOworICAgIHByaXZhdGUgYm9vbGVhbiBvbmx5Q29udGFpbnNDQUNlcnRzID0gZmFsc2U7CisgICAgcHJpdmF0ZSBSZWFzb25GbGFncyBvbmx5U29tZVJlYXNvbnM7CisgICAgcHJpdmF0ZSBib29sZWFuIGluZGlyZWN0Q1JMID0gZmFsc2U7CisgICAgcHJpdmF0ZSBib29sZWFuIG9ubHlDb250YWluc0F0dHJpYnV0ZUNlcnRzID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIHRoZSBvYmplY3Qgb24gdGhlIGJhc2Ugb2YgaXRzIGRpc3RyaWJ1dGlvblBvaW50IGFuZAorICAgICAqIG9ubHlTb21lUmVhc29ucyBmaWVsZHMgdmFsdWVzLgorICAgICAqLworICAgIHB1YmxpYyBJc3N1aW5nRGlzdHJpYnV0aW9uUG9pbnQoRGlzdHJpYnV0aW9uUG9pbnROYW1lIGRpc3RyaWJ1dGlvblBvaW50LAorICAgICAgICAgICAgUmVhc29uRmxhZ3Mgb25seVNvbWVSZWFzb25zKSB7CisgICAgICAgIHRoaXMuZGlzdHJpYnV0aW9uUG9pbnQgPSBkaXN0cmlidXRpb25Qb2ludDsKKyAgICAgICAgdGhpcy5vbmx5U29tZVJlYXNvbnMgPSBvbmx5U29tZVJlYXNvbnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgZXh0ZW5zaW9uIG9iamVjdCBvbiB0aGUgYmFzZSBvZiBpdHMgZW5jb2RlZCBmb3JtLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgSXNzdWluZ0Rpc3RyaWJ1dGlvblBvaW50IGRlY29kZShieXRlW10gZW5jb2RpbmcpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBJc3N1aW5nRGlzdHJpYnV0aW9uUG9pbnQgaWRwID0KKyAgICAgICAgICAgIChJc3N1aW5nRGlzdHJpYnV0aW9uUG9pbnQpIEFTTjEuZGVjb2RlKGVuY29kaW5nKTsKKyAgICAgICAgaWRwLmVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgICAgIHJldHVybiBpZHA7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2Ygb25seUNvbnRhaW5zVXNlckNlcnRzIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0T25seUNvbnRhaW5zVXNlckNlcnRzKGJvb2xlYW4gb25seUNvbnRhaW5zVXNlckNlcnRzKSB7CisgICAgICAgIHRoaXMub25seUNvbnRhaW5zVXNlckNlcnRzID0gb25seUNvbnRhaW5zVXNlckNlcnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIG9ubHlDb250YWluc0NBQ2VydHMgZmllbGQgb2YgdGhlIHN0cnVjdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRPbmx5Q29udGFpbnNDQUNlcnRzKGJvb2xlYW4gb25seUNvbnRhaW5zQ0FDZXJ0cykgeworICAgICAgICB0aGlzLm9ubHlDb250YWluc0NBQ2VydHMgPSBvbmx5Q29udGFpbnNDQUNlcnRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGluZGlyZWN0Q1JMIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SW5kaXJlY3RDUkwoYm9vbGVhbiBpbmRpcmVjdENSTCkgeworICAgICAgICB0aGlzLmluZGlyZWN0Q1JMID0gaW5kaXJlY3RDUkw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFsdWUgb2Ygb25seUNvbnRhaW5zQXR0cmlidXRlQ2VydHMgZmllbGQgb2YgdGhlIHN0cnVjdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRPbmx5Q29udGFpbnNBdHRyaWJ1dGVDZXJ0cygKKyAgICAgICAgICAgIGJvb2xlYW4gb25seUNvbnRhaW5zQXR0cmlidXRlQ2VydHMpIHsKKyAgICAgICAgdGhpcy5vbmx5Q29udGFpbnNBdHRyaWJ1dGVDZXJ0cyA9IG9ubHlDb250YWluc0F0dHJpYnV0ZUNlcnRzOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZHVtcFZhbHVlKFN0cmluZ0J1aWxkZXIgc2IsIFN0cmluZyBwcmVmaXgpIHsKKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJJc3N1aW5nIERpc3RyaWJ1dGlvbiBQb2ludDogW1xuIik7CisgICAgICAgIGlmIChkaXN0cmlidXRpb25Qb2ludCAhPSBudWxsKSB7CisgICAgICAgICAgICBkaXN0cmlidXRpb25Qb2ludC5kdW1wVmFsdWUoc2IsICIgICIgKyBwcmVmaXgpOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZChwcmVmaXgpLmFwcGVuZCgiICBvbmx5Q29udGFpbnNVc2VyQ2VydHM6ICIpLmFwcGVuZChvbmx5Q29udGFpbnNVc2VyQ2VydHMpLmFwcGVuZCgnXG4nKTsKKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCIgIG9ubHlDb250YWluc0NBQ2VydHM6ICIpLmFwcGVuZChvbmx5Q29udGFpbnNDQUNlcnRzKS5hcHBlbmQoJ1xuJyk7CisgICAgICAgIGlmIChvbmx5U29tZVJlYXNvbnMgIT0gbnVsbCkgeworICAgICAgICAgICAgb25seVNvbWVSZWFzb25zLmR1bXBWYWx1ZShzYiwgcHJlZml4ICsgIiAgIik7CisgICAgICAgIH0KKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCIgIGluZGlyZWN0Q1JMOiAiKS5hcHBlbmQoaW5kaXJlY3RDUkwpLmFwcGVuZCgnXG4nKTsKKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCIgIG9ubHlDb250YWluc0F0dHJpYnV0ZUNlcnRzOiAiKS5hcHBlbmQob25seUNvbnRhaW5zQXR0cmlidXRlQ2VydHMpLmFwcGVuZCgnXG4nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBU04uMSBFbmNvZGVyL0RlY29kZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xVHlwZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZSgKKyAgICAgICAgICAgIG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgICAgICAvLyBBU04uMSBwcm9oaWJpdHMgaW1wbGljaXRseSB0YWdnZWQgQ0hPSUNFCisgICAgICAgICAgICAgICAgbmV3IEFTTjFFeHBsaWNpdCgwLCBEaXN0cmlidXRpb25Qb2ludE5hbWUuQVNOMSksCisgICAgICAgICAgICAgICAgbmV3IEFTTjFJbXBsaWNpdCgxLCBBU04xQm9vbGVhbi5nZXRJbnN0YW5jZSgpKSwKKyAgICAgICAgICAgICAgICBuZXcgQVNOMUltcGxpY2l0KDIsIEFTTjFCb29sZWFuLmdldEluc3RhbmNlKCkpLAorICAgICAgICAgICAgICAgIG5ldyBBU04xSW1wbGljaXQoMywgUmVhc29uRmxhZ3MuQVNOMSksCisgICAgICAgICAgICAgICAgbmV3IEFTTjFJbXBsaWNpdCg0LCBBU04xQm9vbGVhbi5nZXRJbnN0YW5jZSgpKSwKKyAgICAgICAgICAgICAgICBuZXcgQVNOMUltcGxpY2l0KDUsIEFTTjFCb29sZWFuLmdldEluc3RhbmNlKCkpCisgICAgICAgICAgICB9KSB7CisgICAgICAgIHsKKyAgICAgICAgICAgIHNldE9wdGlvbmFsKDApOworICAgICAgICAgICAgc2V0T3B0aW9uYWwoMyk7CisgICAgICAgICAgICBzZXREZWZhdWx0KEJvb2xlYW4uRkFMU0UsIDEpOworICAgICAgICAgICAgc2V0RGVmYXVsdChCb29sZWFuLkZBTFNFLCAyKTsKKyAgICAgICAgICAgIHNldERlZmF1bHQoQm9vbGVhbi5GQUxTRSwgNCk7CisgICAgICAgICAgICBzZXREZWZhdWx0KEJvb2xlYW4uRkFMU0UsIDUpOworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB7CisgICAgICAgICAgICBPYmplY3RbXSB2YWx1ZXMgPSAoT2JqZWN0W10pIGluLmNvbnRlbnQ7CisgICAgICAgICAgICBJc3N1aW5nRGlzdHJpYnV0aW9uUG9pbnQgaWRwID0gbmV3IElzc3VpbmdEaXN0cmlidXRpb25Qb2ludCgKKyAgICAgICAgICAgICAgICAgICAgKERpc3RyaWJ1dGlvblBvaW50TmFtZSkgdmFsdWVzWzBdLCAoUmVhc29uRmxhZ3MpIHZhbHVlc1szXSk7CisgICAgICAgICAgICBpZHAuZW5jb2RpbmcgPSBpbi5nZXRFbmNvZGVkKCk7CisgICAgICAgICAgICBpZiAodmFsdWVzWzFdICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZHAuc2V0T25seUNvbnRhaW5zVXNlckNlcnRzKChCb29sZWFuKSB2YWx1ZXNbMV0pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHZhbHVlc1syXSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWRwLnNldE9ubHlDb250YWluc0NBQ2VydHMoKEJvb2xlYW4pIHZhbHVlc1syXSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodmFsdWVzWzRdICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZHAuc2V0SW5kaXJlY3RDUkwoKEJvb2xlYW4pIHZhbHVlc1s0XSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodmFsdWVzWzVdICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZHAuc2V0T25seUNvbnRhaW5zQXR0cmlidXRlQ2VydHMoKEJvb2xlYW4pIHZhbHVlc1s1XSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gaWRwOworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykgeworICAgICAgICAgICAgSXNzdWluZ0Rpc3RyaWJ1dGlvblBvaW50IGlkcCA9IChJc3N1aW5nRGlzdHJpYnV0aW9uUG9pbnQpIG9iamVjdDsKKyAgICAgICAgICAgIHZhbHVlc1swXSA9IGlkcC5kaXN0cmlidXRpb25Qb2ludDsKKyAgICAgICAgICAgIHZhbHVlc1sxXSA9IChpZHAub25seUNvbnRhaW5zVXNlckNlcnRzKSA/IEJvb2xlYW4uVFJVRSA6IG51bGw7CisgICAgICAgICAgICB2YWx1ZXNbMl0gPSAoaWRwLm9ubHlDb250YWluc0NBQ2VydHMpID8gQm9vbGVhbi5UUlVFIDogbnVsbDsKKyAgICAgICAgICAgIHZhbHVlc1szXSA9IGlkcC5vbmx5U29tZVJlYXNvbnM7CisgICAgICAgICAgICB2YWx1ZXNbNF0gPSAoaWRwLmluZGlyZWN0Q1JMKSA/IEJvb2xlYW4uVFJVRSA6IG51bGw7CisgICAgICAgICAgICB2YWx1ZXNbNV0gPSAoaWRwLm9ubHlDb250YWluc0F0dHJpYnV0ZUNlcnRzKSA/IEJvb2xlYW4uVFJVRSA6IG51bGw7CisgICAgICAgIH0KKyAgICB9OworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvS2V5VXNhZ2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9LZXlVc2FnZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMzY2IxNjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvS2V5VXNhZ2UuamF2YQpAQCAtMCwwICsxLDk4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xQml0U3RyaW5nOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworCisvKioKKyAqIEtleSBVc2FnZSBFeHRlbnNpb24gKE9JRCA9IDIuNS4yOS4xNSkuCisgKgorICogVGhlIEFTTi4xIGRlZmluaXRpb24gZm9yIEtleSBVc2FnZSBFeHRlbnNpb24gaXM6CisgKgorICogPHByZT4KKyAqIGlkLWNlLWtleVVzYWdlIE9CSkVDVCBJREVOVElGSUVSIDo6PSAgeyBpZC1jZSAxNSB9CisgKgorICogS2V5VXNhZ2UgOjo9IEJJVCBTVFJJTkcgeworICogICAgIGRpZ2l0YWxTaWduYXR1cmUgICAgICAgICgwKSwKKyAqICAgICBub25SZXB1ZGlhdGlvbiAgICAgICAgICAoMSksCisgKiAgICAga2V5RW5jaXBoZXJtZW50ICAgICAgICAgKDIpLAorICogICAgIGRhdGFFbmNpcGhlcm1lbnQgICAgICAgICgzKSwKKyAqICAgICBrZXlBZ3JlZW1lbnQgICAgICAgICAgICAoNCksCisgKiAgICAga2V5Q2VydFNpZ24gICAgICAgICAgICAgKDUpLAorICogICAgIGNSTFNpZ24gICAgICAgICAgICAgICAgICg2KSwKKyAqICAgICBlbmNpcGhlck9ubHkgICAgICAgICAgICAoNyksCisgKiAgICAgZGVjaXBoZXJPbmx5ICAgICAgICAgICAgKDgpCisgKiB9CisgKiA8L3ByZT4KKyAqIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBLZXlVc2FnZSBleHRlbmRzIEV4dGVuc2lvblZhbHVlIHsKKworICAgIC8qKiBUaGUgbmFtZXMgb2YgdGhlIHVzYWdlcy4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBVU0FHRVMgPSB7CisgICAgICAgICJkaWdpdGFsU2lnbmF0dXJlIiwKKyAgICAgICAgIm5vblJlcHVkaWF0aW9uIiwKKyAgICAgICAgImtleUVuY2lwaGVybWVudCIsCisgICAgICAgICJkYXRhRW5jaXBoZXJtZW50IiwKKyAgICAgICAgImtleUFncmVlbWVudCIsCisgICAgICAgICJrZXlDZXJ0U2lnbiIsCisgICAgICAgICJjUkxTaWduIiwKKyAgICAgICAgImVuY2lwaGVyT25seSIsCisgICAgICAgICJkZWNpcGhlck9ubHkiLAorICAgIH07CisKKyAgICAvKiogdGhlIHZhbHVlIG9mIGV4dGVuc2lvbiAqLworICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbltdIGtleVVzYWdlOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgZXh0ZW5zaW9uIG9iamVjdCBvbiB0aGUgYmFzZSBvZiBpdHMgZW5jb2RlZCBmb3JtLgorICAgICAqLworICAgIHB1YmxpYyBLZXlVc2FnZShieXRlW10gZW5jb2RpbmcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKGVuY29kaW5nKTsKKyAgICAgICAgdGhpcy5rZXlVc2FnZSA9IChib29sZWFuW10pIEFTTjEuZGVjb2RlKGVuY29kaW5nKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbltdIGdldEtleVVzYWdlKCkgeworICAgICAgICByZXR1cm4ga2V5VXNhZ2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIGVuY29kaW5nID0gQVNOMS5lbmNvZGUoa2V5VXNhZ2UpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZHVtcFZhbHVlKFN0cmluZ0J1aWxkZXIgc2IsIFN0cmluZyBwcmVmaXgpIHsKKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJLZXlVc2FnZSBbXG4iKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrZXlVc2FnZS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKGtleVVzYWdlW2ldKSB7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCIgICIpLmFwcGVuZChVU0FHRVNbaV0pLmFwcGVuZCgnXG4nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQocHJlZml4KS5hcHBlbmQoIl1cbiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFguNTA5IEV4dGVuc2lvbiB2YWx1ZSBlbmNvZGVyL2RlY29kZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQVNOMVR5cGUgQVNOMSA9IG5ldyBBU04xQml0U3RyaW5nLkFTTjFOYW1lZEJpdExpc3QoOSk7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9OYW1lQ29uc3RyYWludHMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9OYW1lQ29uc3RyYWludHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZTc1MzBjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L05hbWVDb25zdHJhaW50cy5qYXZhCkBAIC0wLDAgKzEsMjgyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdiwgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUltcGxpY2l0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFPY3RldFN0cmluZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2VxdWVuY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVR5cGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQmVySW5wdXRTdHJlYW07CisKKy8qKgorICogVGhlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgQVNOLjEgREVSIGVuY29kaW5nL2RlY29kaW5nIHdvcmsKKyAqIHdpdGggdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmUgd2hpY2ggaXMgYSBwYXJ0IG9mIFguNTA5IGNlcnRpZmljYXRlCisgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIC0KKyAqICBJbnRlcm5ldCBYLjUwOSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgorICogIENlcnRpZmljYXRlIGFuZCBDZXJ0aWZpY2F0ZSBSZXZvY2F0aW9uIExpc3QgKENSTCkgUHJvZmlsZS4KKyAqICBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCk6CisgKgorICogPHByZT4KKyAqCisgKiAgIE5hbWVDb25zdHJhaW50cyA6Oj0gU0VRVUVOQ0UgeworICogICAgICAgIHBlcm1pdHRlZFN1YnRyZWVzICAgICAgIFswXSAgICAgR2VuZXJhbFN1YnRyZWVzIE9QVElPTkFMLAorICogICAgICAgIGV4Y2x1ZGVkU3VidHJlZXMgICAgICAgIFsxXSAgICAgR2VuZXJhbFN1YnRyZWVzIE9QVElPTkFMIH0KKyAqCisgKiAgIEdlbmVyYWxTdWJ0cmVlcyA6Oj0gU0VRVUVOQ0UgU0laRSAoMS4uTUFYKSBPRiBHZW5lcmFsU3VidHJlZQorICoKKyAqIDwvcHJlPgorICoKKyAqIEBzZWUgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuR2VuZXJhbFN1YnRyZWUKKyAqIEBzZWUgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuR2VuZXJhbE5hbWUKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE5hbWVDb25zdHJhaW50cyBleHRlbmRzIEV4dGVuc2lvblZhbHVlIHsKKyAgICAvKiogdGhlIHZhbHVlIG9mIHBlcm1pdHRlZFN1YnRyZWVzIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIEdlbmVyYWxTdWJ0cmVlcyBwZXJtaXR0ZWRTdWJ0cmVlczsKKyAgICAvKiogdGhlIHZhbHVlIG9mIGV4Y2x1ZGVkU3VidHJlZXMgZmllbGQgb2YgdGhlIHN0cnVjdHVyZSAqLworICAgIHByaXZhdGUgZmluYWwgR2VuZXJhbFN1YnRyZWVzIGV4Y2x1ZGVkU3VidHJlZXM7CisgICAgLyoqIHRoZSBBU04uMSBlbmNvZGVkIGZvcm0gb2YgTmFtZUNvbnN0cmFpbnRzICovCisgICAgcHJpdmF0ZSBieXRlW10gZW5jb2Rpbmc7CisKKyAgICBwcml2YXRlIEFycmF5TGlzdDxHZW5lcmFsTmFtZT5bXSBwZXJtaXR0ZWRfbmFtZXM7CisgICAgcHJpdmF0ZSBBcnJheUxpc3Q8R2VuZXJhbE5hbWU+W10gZXhjbHVkZWRfbmFtZXM7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIDxjb2RlPk5hbWVDb25zdHJhaW5zPC9jb2RlPiBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgTmFtZUNvbnN0cmFpbnRzKEdlbmVyYWxTdWJ0cmVlcyBwZXJtaXR0ZWRTdWJ0cmVlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYWxTdWJ0cmVlcyBleGNsdWRlZFN1YnRyZWVzKSB7CisgICAgICAgIGlmIChwZXJtaXR0ZWRTdWJ0cmVlcyAhPSBudWxsKSB7CisgICAgICAgICAgICBMaXN0PEdlbmVyYWxTdWJ0cmVlPiBwcyA9IHBlcm1pdHRlZFN1YnRyZWVzLmdldFN1YnRyZWVzKCk7CisgICAgICAgICAgICBpZiAocHMgPT0gbnVsbCB8fCBwcy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJwZXJtaXR0ZWRTdWJ0cmVlcyBhcmUgZW1wdHkiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoZXhjbHVkZWRTdWJ0cmVlcyAhPSBudWxsKSB7CisgICAgICAgICAgICBMaXN0PEdlbmVyYWxTdWJ0cmVlPiBlcyA9IGV4Y2x1ZGVkU3VidHJlZXMuZ2V0U3VidHJlZXMoKTsKKyAgICAgICAgICAgIGlmIChlcyA9PSBudWxsIHx8IGVzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImV4Y2x1ZGVkU3VidHJlZXMgYXJlIGVtcHR5Iik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5wZXJtaXR0ZWRTdWJ0cmVlcyA9IHBlcm1pdHRlZFN1YnRyZWVzOworICAgICAgICB0aGlzLmV4Y2x1ZGVkU3VidHJlZXMgPSBleGNsdWRlZFN1YnRyZWVzOworICAgIH0KKworICAgIHByaXZhdGUgTmFtZUNvbnN0cmFpbnRzKEdlbmVyYWxTdWJ0cmVlcyBwZXJtaXR0ZWRTdWJ0cmVlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmFsU3VidHJlZXMgZXhjbHVkZWRTdWJ0cmVlcywgYnl0ZVtdIGVuY29kaW5nKSB7CisgICAgICAgIHRoaXMocGVybWl0dGVkU3VidHJlZXMsIGV4Y2x1ZGVkU3VidHJlZXMpOworICAgICAgICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBOYW1lQ29uc3RyYWludHMgZGVjb2RlKGJ5dGVbXSBlbmNvZGluZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIChOYW1lQ29uc3RyYWludHMpIEFTTjEuZGVjb2RlKGVuY29kaW5nKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSBBU04xLmVuY29kZSh0aGlzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJlcGFyZSB0aGUgZGF0YSBzdHJ1Y3R1cmUgdG8gc3BlZWQgdXAgdGhlIGNoZWNraW5nIHByb2Nlc3MuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHByZXBhcmVOYW1lcygpIHsKKyAgICAgICAgLy8gYXJyYXkgb2YgbGlzdHMgd2l0aCBwZXJtaXR0ZWQgR2VuZXJhbCBOYW1lcyBkaXZpZGVkIGJ5IHR5cGUKKyAgICAgICAgcGVybWl0dGVkX25hbWVzID0gbmV3IEFycmF5TGlzdFs5XTsKKyAgICAgICAgaWYgKHBlcm1pdHRlZFN1YnRyZWVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoR2VuZXJhbFN1YnRyZWUgZ2VuZXJhbFN1YnRyZWUgOiBwZXJtaXR0ZWRTdWJ0cmVlcy5nZXRTdWJ0cmVlcygpKSB7CisgICAgICAgICAgICAgICAgR2VuZXJhbE5hbWUgbmFtZSA9IGdlbmVyYWxTdWJ0cmVlLmdldEJhc2UoKTsKKyAgICAgICAgICAgICAgICBpbnQgdGFnID0gbmFtZS5nZXRUYWcoKTsKKyAgICAgICAgICAgICAgICBpZiAocGVybWl0dGVkX25hbWVzW3RhZ10gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBwZXJtaXR0ZWRfbmFtZXNbdGFnXSA9IG5ldyBBcnJheUxpc3Q8R2VuZXJhbE5hbWU+KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHBlcm1pdHRlZF9uYW1lc1t0YWddLmFkZChuYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBhcnJheSBvZiBsaXN0cyB3aXRoIGV4Y2x1ZGVkIEdlbmVyYWwgTmFtZXMgZGl2aWRlZCBieSB0eXBlCisgICAgICAgIGV4Y2x1ZGVkX25hbWVzID0gbmV3IEFycmF5TGlzdFs5XTsKKyAgICAgICAgaWYgKGV4Y2x1ZGVkU3VidHJlZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChHZW5lcmFsU3VidHJlZSBnZW5lcmFsU3VidHJlZSA6IGV4Y2x1ZGVkU3VidHJlZXMuZ2V0U3VidHJlZXMoKSkgeworICAgICAgICAgICAgICAgIEdlbmVyYWxOYW1lIG5hbWUgPSBnZW5lcmFsU3VidHJlZS5nZXRCYXNlKCk7CisgICAgICAgICAgICAgICAgaW50IHRhZyA9IG5hbWUuZ2V0VGFnKCk7CisgICAgICAgICAgICAgICAgaWYgKGV4Y2x1ZGVkX25hbWVzW3RhZ10gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBleGNsdWRlZF9uYW1lc1t0YWddID0gbmV3IEFycmF5TGlzdDxHZW5lcmFsTmFtZT4oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZXhjbHVkZWRfbmFtZXNbdGFnXS5hZGQobmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBjZXJ0aWZpY2F0ZSBleHRlbnNpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBnZXRFeHRlbnNpb25WYWx1ZShYNTA5Q2VydGlmaWNhdGUgY2VydCwgU3RyaW5nIE9JRCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnl0ZVtdIGJ5dGVzID0gY2VydC5nZXRFeHRlbnNpb25WYWx1ZShPSUQpOworICAgICAgICAgICAgaWYgKGJ5dGVzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAoYnl0ZVtdKSBBU04xT2N0ZXRTdHJpbmcuZ2V0SW5zdGFuY2UoKS5kZWNvZGUoYnl0ZXMpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGx5IHRoZSBuYW1lIHJlc3RyaWN0aW9ucyBzcGVjaWZpZWQgYnkgdGhpcyBOYW1lQ29uc3RyYWludHMKKyAgICAgKiBpbnN0YW5jZSB0byB0aGUgc3ViamVjdCBkaXN0aW5ndWlzaGVkIG5hbWUgYW5kIHN1YmplY3QgYWx0ZXJuYXRpdmUKKyAgICAgKiBuYW1lcyBvZiBzcGVjaWZpZWQgWDUwOUNlcnRpZmljYXRlLiBSZXN0cmljdGlvbnMgYXBwbHkgb25seQorICAgICAqIGlmIHNwZWNpZmllZCBuYW1lIGZvcm0gaXMgcHJlc2VudCBpbiB0aGUgY2VydGlmaWNhdGUuCisgICAgICogVGhlIHJlc3RyaWN0aW9ucyBhcmUgYXBwbGllZCBhY2NvcmRpbmcgdGhlIFJGQyAzMjgwCisgICAgICogKHNlZSA0LjIuMS4xMSBOYW1lIENvbnN0cmFpbnRzKSwgZXhjZXB0aW5nIHRoYXQgcmVzdHJpY3Rpb25zIGFyZSBhcHBsaWVkCisgICAgICogYW5kIHRvIENBIGNlcnRpZmljYXRlcywgYW5kIHRvIGNlcnRpZmljYXRlcyB3aGljaCBpc3N1ZXIgYW5kIHN1YmplY3QKKyAgICAgKiBuYW1lcyB0aGUgc2FtZSAoaS5lLiBtZXRob2QgZG9lcyBub3QgY2hlY2sgaWYgaXQgQ0EncyBjZXJ0aWZpY2F0ZSBvciBub3QsCisgICAgICogb3IgaWYgdGhlIG5hbWVzIGRpZmZlciBvciBub3QuIFRoaXMgY2hlY2sgaWYgaXQgaXMgbmVlZGVkIHNob3VsZCBiZSBkb25lCisgICAgICogYnkgY2FsbGVyIGJlZm9yZSBjYWxsaW5nIHRoaXMgbWV0aG9kKS4KKyAgICAgKiBAcGFyYW0gICBjZXJ0IFguNTA5IENlcnRpZmljYXRlIHRvIGJlIGNoZWNrZWQuCisgICAgICogQHJldHVybiAgdHJ1ZSBpZiB0aGUgY2VydGlmaWNhdGUgaXMgYWNjZXB0YWJsZSBhY2NvcmRpbmcKKyAgICAgKiAgICAgICAgICB0aGVzZSBOYW1lQ29uc3RyYWludHMgcmVzdHJpY3Rpb25zCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNBY2NlcHRhYmxlKFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0KSB7CisgICAgICAgIGlmIChwZXJtaXR0ZWRfbmFtZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgcHJlcGFyZU5hbWVzKCk7CisgICAgICAgIH0KKworICAgICAgICBieXRlW10gYnl0ZXMgPSBnZXRFeHRlbnNpb25WYWx1ZShjZXJ0LCAiMi41LjI5LjE3Iik7CisgICAgICAgIExpc3Q8R2VuZXJhbE5hbWU+IG5hbWVzOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmFtZXMgPSAoYnl0ZXMgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICA/IG5ldyBBcnJheUxpc3Q8R2VuZXJhbE5hbWU+KDEpIC8vIHdpbGwgY2hlY2sgdGhlIHN1YmplY3QgZmllbGQgb25seQorICAgICAgICAgICAgICAgIDogKChHZW5lcmFsTmFtZXMpIEdlbmVyYWxOYW1lcy5BU04xLmRlY29kZShieXRlcykpLmdldE5hbWVzKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIHRoZSBjZXJ0aWZpY2F0ZSBpcyBicm9rZW47CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmICgoZXhjbHVkZWRfbmFtZXNbNF0gIT0gbnVsbCkgfHwgKHBlcm1pdHRlZF9uYW1lc1s0XSAhPSBudWxsKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBuYW1lcy5hZGQobmV3IEdlbmVyYWxOYW1lKDQsCisgICAgICAgICAgICAgICAgICAgICAgICBjZXJ0LmdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCkuZ2V0TmFtZSgpKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gc2hvdWxkIG5ldmVyIGJlIGhhcHBlbmVkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlzQWNjZXB0YWJsZShuYW1lcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgaWYgdGhpcyBsaXN0IG9mIG5hbWVzIGlzIGFjY2VwdGFibGUgYWNjb3JkaW5nIHRvIHRoaXMKKyAgICAgKiBOYW1lQ29uc3RyYWludHMgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQWNjZXB0YWJsZShMaXN0PEdlbmVyYWxOYW1lPiBuYW1lcykgeworICAgICAgICBpZiAocGVybWl0dGVkX25hbWVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHByZXBhcmVOYW1lcygpOworICAgICAgICB9CisKKyAgICAgICAgLy8gY2hlY2sgbWFwOiBzaG93cyB3aGljaCB0eXBlcyBvZiBwZXJtaXR0ZWQgYWx0ZXJuYXRpdmUgbmFtZXMgYXJlCisgICAgICAgIC8vIHByZXNlbnRlZCBpbiB0aGUgY2VydGlmaWNhdGUKKyAgICAgICAgYm9vbGVhbltdIHR5cGVzX3ByZXNlbnRlZCA9IG5ldyBib29sZWFuWzldOworICAgICAgICAvLyBjaGVjayBtYXA6IHNob3dzIGlmIHBlcm1pdHRlZCBuYW1lIG9mIHByZXNlbnRlZCB0eXBlIGlzIGZvdW5kCisgICAgICAgIC8vIGFtb25nIHRoZSBjZXJ0aWZpY2F0ZSdzIGFsdGVybmF0aXZlIG5hbWVzCisgICAgICAgIGJvb2xlYW5bXSBwZXJtaXR0ZWRfZm91bmQgPSBuZXcgYm9vbGVhbls5XTsKKyAgICAgICAgZm9yIChHZW5lcmFsTmFtZSBuYW1lIDogbmFtZXMpIHsKKyAgICAgICAgICAgIGludCB0eXBlID0gbmFtZS5nZXRUYWcoKTsKKyAgICAgICAgICAgIC8vIHNlYXJjaCB0aGUgbmFtZSBpbiBleGNsdWRlZCBuYW1lcworICAgICAgICAgICAgaWYgKGV4Y2x1ZGVkX25hbWVzW3R5cGVdICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGV4Y2x1ZGVkX25hbWVzW3R5cGVdLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChleGNsdWRlZF9uYW1lc1t0eXBlXS5nZXQoaSkuaXNBY2NlcHRhYmxlKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBTZWFyY2ggdGhlIG5hbWUgaW4gcGVybWl0dGVkIG5hbWVzCisgICAgICAgICAgICAvLyAoaWYgd2UgYWxyZWFkeSBmb3VuZCB0aGUgbmFtZSBvZiBzdWNoIHR5cGUgYmV0d2VlbiB0aGUgYWx0CisgICAgICAgICAgICAvLyBuYW1lcyAtIHdlIGRvIG5vdCBuZWVkIHRvIGNoZWNrIG90aGVycykKKyAgICAgICAgICAgIGlmICgocGVybWl0dGVkX25hbWVzW3R5cGVdICE9IG51bGwpICYmICghcGVybWl0dGVkX2ZvdW5kW3R5cGVdKSkgeworICAgICAgICAgICAgICAgIHR5cGVzX3ByZXNlbnRlZFt0eXBlXSA9IHRydWU7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwZXJtaXR0ZWRfbmFtZXNbdHlwZV0uc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHBlcm1pdHRlZF9uYW1lc1t0eXBlXS5nZXQoaSkuaXNBY2NlcHRhYmxlKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3VuZCBvbmUgcGVybWl0dGVkIG5hbWUgb2Ygc3VjaCB0eXBlCisgICAgICAgICAgICAgICAgICAgICAgICBwZXJtaXR0ZWRfZm91bmRbdHlwZV0gPSB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZvciAoaW50IHR5cGUgPSAwOyB0eXBlIDwgOTsgdHlwZSsrKSB7CisgICAgICAgICAgICBpZiAodHlwZXNfcHJlc2VudGVkW3R5cGVdICYmICFwZXJtaXR0ZWRfZm91bmRbdHlwZV0pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGR1bXBWYWx1ZShTdHJpbmdCdWlsZGVyIHNiLCBTdHJpbmcgcHJlZml4KSB7CisgICAgICAgIHNiLmFwcGVuZChwcmVmaXgpLmFwcGVuZCgiTmFtZSBDb25zdHJhaW50czogW1xuIik7CisgICAgICAgIGlmIChwZXJtaXR0ZWRTdWJ0cmVlcyAhPSBudWxsKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQocHJlZml4KS5hcHBlbmQoIiAgUGVybWl0dGVkOiBbXG4iKTsKKyAgICAgICAgICAgIGZvciAoR2VuZXJhbFN1YnRyZWUgZ2VuZXJhbFN1YnRyZWUgOiBwZXJtaXR0ZWRTdWJ0cmVlcy5nZXRTdWJ0cmVlcygpKSB7CisgICAgICAgICAgICAgICAgZ2VuZXJhbFN1YnRyZWUuZHVtcFZhbHVlKHNiLCBwcmVmaXggKyAiICAgICIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCIgIF1cbiIpOworICAgICAgICB9CisgICAgICAgIGlmIChleGNsdWRlZFN1YnRyZWVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZChwcmVmaXgpLmFwcGVuZCgiICBFeGNsdWRlZDogW1xuIik7CisgICAgICAgICAgICBmb3IgKEdlbmVyYWxTdWJ0cmVlIGdlbmVyYWxTdWJ0cmVlIDogZXhjbHVkZWRTdWJ0cmVlcy5nZXRTdWJ0cmVlcygpKSB7CisgICAgICAgICAgICAgICAgZ2VuZXJhbFN1YnRyZWUuZHVtcFZhbHVlKHNiLCBwcmVmaXggKyAiICAgICIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCIgIF1cbiIpOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZCgnXG4nKS5hcHBlbmQocHJlZml4KS5hcHBlbmQoIl1cbiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFguNTA5IE5hbWVDb25zdHJhaW50cyBlbmNvZGVyL2RlY29kZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xU2VxdWVuY2UgQVNOMSA9IG5ldyBBU04xU2VxdWVuY2UobmV3IEFTTjFUeXBlW10geworICAgICAgICAgICAgbmV3IEFTTjFJbXBsaWNpdCgwLCBHZW5lcmFsU3VidHJlZXMuQVNOMSksCisgICAgICAgICAgICBuZXcgQVNOMUltcGxpY2l0KDEsIEdlbmVyYWxTdWJ0cmVlcy5BU04xKSB9KSB7CisgICAgICAgIHsKKyAgICAgICAgICAgIHNldE9wdGlvbmFsKDApOworICAgICAgICAgICAgc2V0T3B0aW9uYWwoMSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB7CisgICAgICAgICAgICBPYmplY3RbXSB2YWx1ZXMgPSAoT2JqZWN0W10pIGluLmNvbnRlbnQ7CisgICAgICAgICAgICByZXR1cm4gbmV3IE5hbWVDb25zdHJhaW50cygKKyAgICAgICAgICAgICAgICAgICAgKEdlbmVyYWxTdWJ0cmVlcykgdmFsdWVzWzBdLAorICAgICAgICAgICAgICAgICAgICAoR2VuZXJhbFN1YnRyZWVzKSB2YWx1ZXNbMV0sCisgICAgICAgICAgICAgICAgICAgIGluLmdldEVuY29kZWQoKSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykgeworICAgICAgICAgICAgTmFtZUNvbnN0cmFpbnRzIG5jID0gKE5hbWVDb25zdHJhaW50cykgb2JqZWN0OworICAgICAgICAgICAgdmFsdWVzWzBdID0gbmMucGVybWl0dGVkU3VidHJlZXM7CisgICAgICAgICAgICB2YWx1ZXNbMV0gPSBuYy5leGNsdWRlZFN1YnRyZWVzOworICAgICAgICB9CisgICAgfTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9PUkFkZHJlc3MuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9PUkFkZHJlc3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZTZiMGE3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L09SQWRkcmVzcy5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXF1ZW5jZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKKworLyoqCisgKiBUaGUgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBBU04uMSBERVIgZW5jb2RpbmcvZGVjb2Rpbmcgd29yaworICogd2l0aCB0aGUgT1JBZGRyZXNzIHN0cnVjdHVyZSB3aGljaCBpcyBhIHBhcnQgb2YgWC41MDkgY2VydGlmaWNhdGU6CisgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIC0KKyAqICBJbnRlcm5ldCBYLjUwOSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgorICogIENlcnRpZmljYXRlIGFuZCBDZXJ0aWZpY2F0ZSBSZXZvY2F0aW9uIExpc3QgKENSTCkgUHJvZmlsZS4KKyAqICBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCk6CisgKgorICogPHByZT4KKyAqIE9SQWRkcmVzcyA6Oj0gU0VRVUVOQ0UgeworICogICBidWlsdC1pbi1zdGFuZGFyZC1hdHRyaWJ1dGVzIEJ1aWx0SW5TdGFuZGFyZEF0dHJpYnV0ZXMsCisgKiAgIGJ1aWx0LWluLWRvbWFpbi1kZWZpbmVkLWF0dHJpYnV0ZXMKKyAqICAgICAgICAgICAgICAgICAgIEJ1aWx0SW5Eb21haW5EZWZpbmVkQXR0cmlidXRlcyBPUFRJT05BTCwKKyAqICAgZXh0ZW5zaW9uLWF0dHJpYnV0ZXMgRXh0ZW5zaW9uQXR0cmlidXRlcyBPUFRJT05BTAorICogfQorICogPC9wcmU+CisgKgorICogVE9ETzogdGhpcyBjbGFzcyBuZWVkcyB0byBiZSBmaW5pc2hlZC4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE9SQWRkcmVzcyB7CisKKyAgICAvKiogdGhlIEFTTi4xIGVuY29kZWQgZm9ybSBvZiBPUkFkZHJlc3MgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGluZzsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgQVNOLjEgZW5jb2RlZCBmb3JtIG9mIHRoaXMgWC41MDkgT1JBZGRyZXNzIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIGVuY29kaW5nID0gQVNOMS5lbmNvZGUodGhpcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVuY29kaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFTTi4xIERFUiBYLjUwOSBPUkFkZHJlc3MgZW5jb2Rlci9kZWNvZGVyIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVNlcXVlbmNlIEFTTjEgPSBuZXcgQVNOMVNlcXVlbmNlKG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgIG5ldyBBU04xU2VxdWVuY2UobmV3IEFTTjFUeXBlW10ge30pIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykge30KKyAgICAgICAgICAgIH19KSB7CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBPUkFkZHJlc3MoKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgZmluYWwgT2JqZWN0IGZvbyA9IG5ldyBPYmplY3QoKTsKKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykgeworICAgICAgICAgICAgdmFsdWVzWzBdID0gZm9vOworICAgICAgICB9CisgICAgfTsKK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L090aGVyTmFtZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L090aGVyTmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNiODNmMmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvT3RoZXJOYW1lLmphdmEKQEAgLTAsMCArMSwxMDMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFBbnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUV4cGxpY2l0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFPaWQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLk9iamVjdElkZW50aWZpZXI7CisKKy8qKgorICogVGhlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgQVNOLjEgREVSIGVuY29kaW5nL2RlY29kaW5nIHdvcmsKKyAqIHdpdGggT3RoZXJOYW1lIHN0cnVjdHVyZSB3aGljaCBpcyBhIHN1YnBhcnQgb2YgR2VuZXJhbE5hbWUKKyAqIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODAgLQorICogIEludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUuCisgKiAgQ2VydGlmaWNhdGUgYW5kIENlcnRpZmljYXRlIFJldm9jYXRpb24gTGlzdCAoQ1JMKSBQcm9maWxlLgorICogIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KToKKyAqCisgKiA8cHJlPgorICogICBPdGhlck5hbWUgOjo9IFNFUVVFTkNFIHsKKyAqICAgICAgICB0eXBlLWlkICAgIE9CSkVDVCBJREVOVElGSUVSLAorICogICAgICAgIHZhbHVlICAgICAgWzBdIEVYUExJQ0lUIEFOWSBERUZJTkVEIEJZIHR5cGUtaWQKKyAqICAgfQorICogPC9wcmU+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBPdGhlck5hbWUgeworICAgIC8qKiB0aGUgdmFsdWUgb2YgdHlwZUlEIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIFN0cmluZyB0eXBlSUQ7CisgICAgLyoqIHRoZSB2YWx1ZSBvZiB2YWx1ZSBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBieXRlW10gdmFsdWU7CisgICAgLyoqIHRoZSBBU04uMSBlbmNvZGVkIGZvcm0gb2YgT3RoZXJOYW1lICovCisgICAgcHJpdmF0ZSBieXRlW10gZW5jb2Rpbmc7CisKKyAgICBwdWJsaWMgT3RoZXJOYW1lKFN0cmluZyB0eXBlSUQsIGJ5dGVbXSB2YWx1ZSkgeworICAgICAgICB0aGlzKHR5cGVJRCwgdmFsdWUsIG51bGwpOworICAgIH0KKworICAgIHByaXZhdGUgT3RoZXJOYW1lKFN0cmluZyB0eXBlSUQsIGJ5dGVbXSB2YWx1ZSwgYnl0ZVtdIGVuY29kaW5nKSB7CisgICAgICAgIHRoaXMudHlwZUlEID0gdHlwZUlEOworICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB2YWx1ZSBmaWVsZCBvZiB0aGUgc3RydWN0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0VmFsdWUoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFTTi4xIGVuY29kZWQgZm9ybSBvZiB0aGlzIFguNTA5IE90aGVyTmFtZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBU04uMSBERVIgWC41MDkgT3RoZXJOYW1lIGVuY29kZXIvZGVjb2RlciBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZShuZXcgQVNOMVR5cGVbXSB7CisgICAgICAgICAgICBBU04xT2lkLmdldEluc3RhbmNlKCksCisgICAgICAgICAgICBuZXcgQVNOMUV4cGxpY2l0KDAsIEFTTjFBbnkuZ2V0SW5zdGFuY2UoKSkgfSkgeworCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgICAgIE9iamVjdFtdIHZhbHVlcyA9IChPYmplY3RbXSkgaW4uY29udGVudDsKKyAgICAgICAgICAgIHJldHVybiBuZXcgT3RoZXJOYW1lKE9iamVjdElkZW50aWZpZXIudG9TdHJpbmcoKGludFtdKSB2YWx1ZXNbMF0pLAorICAgICAgICAgICAgICAgICAgICAoYnl0ZVtdKSB2YWx1ZXNbMV0sIGluLmdldEVuY29kZWQoKSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykgeworICAgICAgICAgICAgT3RoZXJOYW1lIG9uID0gKE90aGVyTmFtZSkgb2JqZWN0OworICAgICAgICAgICAgdmFsdWVzWzBdID0gT2JqZWN0SWRlbnRpZmllci50b0ludEFycmF5KG9uLnR5cGVJRCk7CisgICAgICAgICAgICB2YWx1ZXNbMV0gPSBvbi52YWx1ZTsKKyAgICAgICAgfQorICAgIH07Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9Qb2xpY3lDb25zdHJhaW50cy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L1BvbGljeUNvbnN0cmFpbnRzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWM0ZDRmMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9Qb2xpY3lDb25zdHJhaW50cy5qYXZhCkBAIC0wLDAgKzEsMTM2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdiwgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xSW1wbGljaXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUludGVnZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworCisvKioKKyAqIFRoZSBjbGFzcyBlbmNhcHN1bGF0ZXMgdGhlIEFTTi4xIERFUiBlbmNvZGluZy9kZWNvZGluZyB3b3JrCisgKiB3aXRoIFBvbGljeUNvbnN0cmFpbnRzIHN0cnVjdHVyZSB3aGljaCBpcyBhIHBhcnQgb2YgWC41MDkgY2VydGlmaWNhdGUKKyAqIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODAgLQorICogIEludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUuCisgKiAgQ2VydGlmaWNhdGUgYW5kIENlcnRpZmljYXRlIFJldm9jYXRpb24gTGlzdCAoQ1JMKSBQcm9maWxlLgorICogIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KToKKyAqCisgKiA8cHJlPgorICoKKyAqICBQb2xpY3lDb25zdHJhaW50cyA6Oj0gU0VRVUVOQ0UgeworICogICAgICAgcmVxdWlyZUV4cGxpY2l0UG9saWN5ICAgICAgICAgICBbMF0gU2tpcENlcnRzIE9QVElPTkFMLAorICogICAgICAgaW5oaWJpdFBvbGljeU1hcHBpbmcgICAgICAgICAgICBbMV0gU2tpcENlcnRzIE9QVElPTkFMIH0KKyAqCisgKiAgU2tpcENlcnRzIDo6PSBJTlRFR0VSICgwLi5NQVgpCisgKgorICogPC9wcmU+CisgKgorICogVE9ETzogVGhpcyBjbGFzcyBpcyBub3QgZnVsbHkgaW1wbGVtZW50ZWQuCisgKgorICogQHNlZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5HZW5lcmFsU3VidHJlZQorICogQHNlZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5HZW5lcmFsTmFtZQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUG9saWN5Q29uc3RyYWludHMgZXh0ZW5kcyBFeHRlbnNpb25WYWx1ZSB7CisgICAgLyoqIHRoZSB2YWx1ZSBvZiByZXF1aXJlRXhwbGljaXRQb2xpY3kgZmllbGQgb2YgdGhlIHN0cnVjdHVyZSAqLworICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciByZXF1aXJlRXhwbGljaXRQb2xpY3k7CisgICAgLyoqIHRoZSB2YWx1ZSBvZiBpbmhpYml0UG9saWN5TWFwcGluZyBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIGluaGliaXRQb2xpY3lNYXBwaW5nOworICAgIC8qKiB0aGUgQVNOLjEgZW5jb2RlZCBmb3JtIG9mIFBvbGljeUNvbnN0cmFpbnRzICovCisgICAgcHJpdmF0ZSBieXRlW10gZW5jb2Rpbmc7CisKKyAgICBwdWJsaWMgUG9saWN5Q29uc3RyYWludHMoQmlnSW50ZWdlciByZXF1aXJlRXhwbGljaXRQb2xpY3ksCisgICAgICAgICAgICBCaWdJbnRlZ2VyIGluaGliaXRQb2xpY3lNYXBwaW5nKSB7CisgICAgICAgIHRoaXMucmVxdWlyZUV4cGxpY2l0UG9saWN5ID0gcmVxdWlyZUV4cGxpY2l0UG9saWN5OworICAgICAgICB0aGlzLmluaGliaXRQb2xpY3lNYXBwaW5nID0gaW5oaWJpdFBvbGljeU1hcHBpbmc7CisgICAgfQorCisgICAgcHVibGljIFBvbGljeUNvbnN0cmFpbnRzKGJ5dGVbXSBlbmNvZGluZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoZW5jb2RpbmcpOworICAgICAgICBQb2xpY3lDb25zdHJhaW50cyBwYyA9IChQb2xpY3lDb25zdHJhaW50cykgQVNOMS5kZWNvZGUoZW5jb2RpbmcpOworICAgICAgICB0aGlzLnJlcXVpcmVFeHBsaWNpdFBvbGljeSA9IHBjLnJlcXVpcmVFeHBsaWNpdFBvbGljeTsKKyAgICAgICAgdGhpcy5pbmhpYml0UG9saWN5TWFwcGluZyA9IHBjLmluaGliaXRQb2xpY3lNYXBwaW5nOworICAgIH0KKworICAgIHByaXZhdGUgUG9saWN5Q29uc3RyYWludHMoQmlnSW50ZWdlciByZXF1aXJlRXhwbGljaXRQb2xpY3ksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBpbmhpYml0UG9saWN5TWFwcGluZywgYnl0ZVtdIGVuY29kaW5nKSB7CisgICAgICAgIHRoaXMocmVxdWlyZUV4cGxpY2l0UG9saWN5LCBpbmhpYml0UG9saWN5TWFwcGluZyk7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFTTi4xIGVuY29kZWQgZm9ybSBvZiB0aGlzIFguNTA5IFBvbGljeUNvbnN0cmFpbnRzIHZhbHVlLgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZHVtcFZhbHVlKFN0cmluZ0J1aWxkZXIgc2IsIFN0cmluZyBwcmVmaXgpIHsKKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJQb2xpY3lDb25zdHJhaW50czogW1xuIik7CisgICAgICAgIGlmIChyZXF1aXJlRXhwbGljaXRQb2xpY3kgIT0gbnVsbCkgeworICAgICAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCIgIHJlcXVpcmVFeHBsaWNpdFBvbGljeTogIikuYXBwZW5kKHJlcXVpcmVFeHBsaWNpdFBvbGljeSkuYXBwZW5kKCdcbicpOworICAgICAgICB9CisgICAgICAgIGlmIChpbmhpYml0UG9saWN5TWFwcGluZyAhPSBudWxsKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQocHJlZml4KS5hcHBlbmQoIiAgaW5oaWJpdFBvbGljeU1hcHBpbmc6ICIpLmFwcGVuZChpbmhpYml0UG9saWN5TWFwcGluZykuYXBwZW5kKCdcbicpOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZChwcmVmaXgpLmFwcGVuZCgiXVxuIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogWC41MDkgUG9saWN5Q29uc3RyYWludHMgZW5jb2Rlci9kZWNvZGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVNlcXVlbmNlIEFTTjEgPSBuZXcgQVNOMVNlcXVlbmNlKG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgIG5ldyBBU04xSW1wbGljaXQoMCwgQVNOMUludGVnZXIuZ2V0SW5zdGFuY2UoKSksCisgICAgICAgICAgICBuZXcgQVNOMUltcGxpY2l0KDEsIEFTTjFJbnRlZ2VyLmdldEluc3RhbmNlKCkpIH0pIHsKKyAgICAgICAgeworICAgICAgICAgICAgc2V0T3B0aW9uYWwoMCk7CisgICAgICAgICAgICBzZXRPcHRpb25hbCgxKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgICAgIE9iamVjdFtdIHZhbHVlcyA9IChPYmplY3RbXSkgaW4uY29udGVudDsKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgcmVxdWlyZUV4cGxpY2l0UG9saWN5ID0gbnVsbDsKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgaW5oaWJpdFBvbGljeU1hcHBpbmcgPSBudWxsOworICAgICAgICAgICAgaWYgKHZhbHVlc1swXSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmVxdWlyZUV4cGxpY2l0UG9saWN5ID0gbmV3IEJpZ0ludGVnZXIoKGJ5dGVbXSkgdmFsdWVzWzBdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh2YWx1ZXNbMV0gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGluaGliaXRQb2xpY3lNYXBwaW5nID0gbmV3IEJpZ0ludGVnZXIoKGJ5dGVbXSkgdmFsdWVzWzFdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBuZXcgUG9saWN5Q29uc3RyYWludHMoCisgICAgICAgICAgICAgICAgcmVxdWlyZUV4cGxpY2l0UG9saWN5LCBpbmhpYml0UG9saWN5TWFwcGluZywKKyAgICAgICAgICAgICAgICAgICAgaW4uZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCwgT2JqZWN0W10gdmFsdWVzKSB7CisgICAgICAgICAgICBQb2xpY3lDb25zdHJhaW50cyBwYyA9IChQb2xpY3lDb25zdHJhaW50cykgb2JqZWN0OworICAgICAgICAgICAgdmFsdWVzWzBdID0gcGMucmVxdWlyZUV4cGxpY2l0UG9saWN5LnRvQnl0ZUFycmF5KCk7CisgICAgICAgICAgICB2YWx1ZXNbMV0gPSBwYy5pbmhpYml0UG9saWN5TWFwcGluZy50b0J5dGVBcnJheSgpOworICAgICAgICB9CisgICAgfTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9Qb2xpY3lJbmZvcm1hdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L1BvbGljeUluZm9ybWF0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzdiZDBiMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9Qb2xpY3lJbmZvcm1hdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xQW55OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFPaWQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLk9iamVjdElkZW50aWZpZXI7CisKKy8qKgorICogVGhlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgQVNOLjEgREVSIGVuY29kaW5nL2RlY29kaW5nIHdvcmsKKyAqIHdpdGggUG9saWN5SW5mb3JtYXRpb24gc3RydWN0dXJlIHdoaWNoIGlzIGEgc3VicGFydCBvZiBjZXJ0aWZpY2F0ZVBvbGljaWVzCisgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIC0KKyAqICBJbnRlcm5ldCBYLjUwOSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgorICogIENlcnRpZmljYXRlIGFuZCBDZXJ0aWZpY2F0ZSBSZXZvY2F0aW9uIExpc3QgKENSTCkgUHJvZmlsZS4KKyAqICBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCk6CisgKgorICogPHByZT4KKyAqICBQb2xpY3lJbmZvcm1hdGlvbiA6Oj0gU0VRVUVOQ0UgeworICogICAgICAgcG9saWN5SWRlbnRpZmllciAgIENlcnRQb2xpY3lJZCwKKyAqICAgICAgIHBvbGljeVF1YWxpZmllcnMgICBTRVFVRU5DRSBTSVpFICgxLi5NQVgpIE9GCisgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb2xpY3lRdWFsaWZpZXJJbmZvIE9QVElPTkFMCisgKiAgfQorICogPC9wcmU+CisgKgorICogVE9ETzogVGhpcyBjbGFzcyBpcyBub3QgZnVsbHkgaW1wbGVtZW50ZWQsIGltcGxlbWVudGVkIG9ubHkgd29yaworICogd2l0aCBPSURzLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUG9saWN5SW5mb3JtYXRpb24geworICAgIC8qKiB0aGUgdmFsdWUgb2YgcG9saWN5SWRlbnRpZmllciBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcG9saWN5SWRlbnRpZmllcjsKKyAgICAvKiogdGhlIEFTTi4xIGVuY29kZWQgZm9ybSBvZiBQb2xpY3lJbmZvcm1hdGlvbiAqLworICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kaW5nOworCisgICAgcHVibGljIFBvbGljeUluZm9ybWF0aW9uKFN0cmluZyBwb2xpY3lJZGVudGlmaWVyKSB7CisgICAgICAgIHRoaXMucG9saWN5SWRlbnRpZmllciA9IHBvbGljeUlkZW50aWZpZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgcG9saWN5SWRlbnRpZmllciBmaWVsZCBvZiB0aGUgc3RydWN0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UG9saWN5SWRlbnRpZmllcigpIHsKKyAgICAgICAgcmV0dXJuIHBvbGljeUlkZW50aWZpZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBlbmNvZGVkIGZvcm0gb2YgdGhpcyBYLjUwOSBQb2xpY3lJbmZvcm1hdGlvbiB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBkdW1wVmFsdWUoU3RyaW5nQnVpbGRlciBzYikgeworICAgICAgICBzYi5hcHBlbmQoIlBvbGljeSBJZGVudGlmaWVyIFsiKS5hcHBlbmQocG9saWN5SWRlbnRpZmllcikuYXBwZW5kKCddJyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQVNOLjEgREVSIFguNTA5IFBvbGljeUluZm9ybWF0aW9uIGVuY29kZXIvZGVjb2RlciBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZSgKKyAgICAgICAgICAgIG5ldyBBU04xVHlwZVtdIHsgQVNOMU9pZC5nZXRJbnN0YW5jZSgpLCBBU04xQW55LmdldEluc3RhbmNlKCkgfSkgeworICAgICAgICB7CisgICAgICAgICAgICBzZXRPcHRpb25hbCgxKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgICAgIE9iamVjdFtdIHZhbHVlcyA9IChPYmplY3RbXSkgaW4uY29udGVudDsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUG9saWN5SW5mb3JtYXRpb24oT2JqZWN0SWRlbnRpZmllci50b1N0cmluZygoaW50W10pIHZhbHVlc1swXSkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKyAgICAgICAgICAgIFBvbGljeUluZm9ybWF0aW9uIHBpID0gKFBvbGljeUluZm9ybWF0aW9uKSBvYmplY3Q7CisgICAgICAgICAgICB2YWx1ZXNbMF0gPSBPYmplY3RJZGVudGlmaWVyLnRvSW50QXJyYXkocGkucG9saWN5SWRlbnRpZmllcik7CisgICAgICAgIH0KKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L1BvbGljeVF1YWxpZmllckluZm8uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9Qb2xpY3lRdWFsaWZpZXJJbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTZhYTYzMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9Qb2xpY3lRdWFsaWZpZXJJbmZvLmphdmEKQEAgLTAsMCArMSw1NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFBbnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMU9pZDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2VxdWVuY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVR5cGU7CisKKworLyoqCisvKioKKyAqIFRoZSBjbGFzcyBlbmNhcHN1bGF0ZXMgdGhlIEFTTi4xIERFUiBkZWNvZGluZyB3b3JrCisgKiB3aXRoIFBvbGljeVF1YWxpZmllckluZm8gc3RydWN0dXJlCisgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIC0KKyAqICBJbnRlcm5ldCBYLjUwOSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgorICogIENlcnRpZmljYXRlIGFuZCBDZXJ0aWZpY2F0ZSBSZXZvY2F0aW9uIExpc3QgKENSTCkgUHJvZmlsZS4KKyAqICBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCk6CisgKgorICogPHByZT4KKyAqICAgIFBvbGljeVF1YWxpZmllckluZm8gOjo9IFNFUVVFTkNFIHsKKyAqICAgICAgICBwb2xpY3lRdWFsaWZpZXJJZCAgUG9saWN5UXVhbGlmaWVySWQsCisgKiAgICAgICAgcXVhbGlmaWVyICAgICAgICAgIEFOWSBERUZJTkVEIEJZIHBvbGljeVF1YWxpZmllcklkIH0KKyAqCisgKiAgICBQb2xpY3lRdWFsaWZpZXJJZCA6Oj0KKyAqICAgICAgICBPQkpFQ1QgSURFTlRJRklFUiAoIGlkLXF0LWNwcyB8IGlkLXF0LXVub3RpY2UgKQorICoKKyAqIDwvcHJlPgorICoKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFBvbGljeVF1YWxpZmllckluZm8geworICAgIC8vIENvbnRhaW5zIG9ubHkgQVNOMSBERVIgZGVjb2RlciBjdXJyZW50bHkKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBBU04xID0KKyAgICAgICAgbmV3IEFTTjFTZXF1ZW5jZShuZXcgQVNOMVR5cGVbXSB7QVNOMU9pZC5nZXRJbnN0YW5jZSgpLCBBU04xQW55LmdldEluc3RhbmNlKCl9KSB7CisgICAgfTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9Qcml2YXRlS2V5VXNhZ2VQZXJpb2QuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9Qcml2YXRlS2V5VXNhZ2VQZXJpb2QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Y2IyY2I5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L1ByaXZhdGVLZXlVc2FnZVBlcmlvZC5qYXZhCkBAIC0wLDAgKzEsMTEyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xR2VuZXJhbGl6ZWRUaW1lOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFJbXBsaWNpdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2VxdWVuY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVR5cGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQmVySW5wdXRTdHJlYW07CisKKy8qKgorICogVGhlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgQVNOLjEgREVSIGVuY29kaW5nL2RlY29kaW5nIHdvcmsKKyAqIHdpdGggdGhlIGZvbGxvd2luZyBjZXJ0aWZpY2F0ZSBleHRlbnNpb24gKE9JRDogMi41LjI5LjE2KQorICogKGFzIHNwZWNpZmllZCBpbiBSRkMgMzI4MCAtCisgKiAgSW50ZXJuZXQgWC41MDkgUHVibGljIEtleSBJbmZyYXN0cnVjdHVyZS4KKyAqICBDZXJ0aWZpY2F0ZSBhbmQgQ2VydGlmaWNhdGUgUmV2b2NhdGlvbiBMaXN0IChDUkwpIFByb2ZpbGUuCisgKiAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpOgorICoKKyAqIDxwcmU+CisgKiBQcml2YXRlS2V5VXNhZ2VQZXJpb2QgOjo9IFNFUVVFTkNFIHsKKyAqICAgICAgbm90QmVmb3JlICAgICAgIFswXSAgICAgR2VuZXJhbGl6ZWRUaW1lIE9QVElPTkFMLAorICogICAgICBub3RBZnRlciAgICAgICAgWzFdICAgICBHZW5lcmFsaXplZFRpbWUgT1BUSU9OQUwKKyAqIH0KKyAqIDwvcHJlPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUHJpdmF0ZUtleVVzYWdlUGVyaW9kIHsKKyAgICAvKiogdGhlIHZhbHVlIG9mIG5vdEJlZm9yZURhdGUgZmllbGQgb2YgdGhlIHN0cnVjdHVyZSAqLworICAgIHByaXZhdGUgZmluYWwgRGF0ZSBub3RCZWZvcmVEYXRlOworICAgIC8qKiB0aGUgdmFsdWUgb2Ygbm90QWZ0ZXJEYXRlIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIERhdGUgbm90QWZ0ZXJEYXRlOworICAgIC8qKiB0aGUgQVNOLjEgZW5jb2RlZCBmb3JtIG9mIFByaXZhdGVLZXlVc2FnZVBlcmlvZCAqLworICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kaW5nOworCisgICAgcHVibGljIFByaXZhdGVLZXlVc2FnZVBlcmlvZChEYXRlIG5vdEJlZm9yZURhdGUsIERhdGUgbm90QWZ0ZXJEYXRlKSB7CisgICAgICAgIHRoaXMobm90QmVmb3JlRGF0ZSwgbm90QWZ0ZXJEYXRlLCBudWxsKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFByaXZhdGVLZXlVc2FnZVBlcmlvZChEYXRlIG5vdEJlZm9yZURhdGUsIERhdGUgbm90QWZ0ZXJEYXRlLCBieXRlW10gZW5jb2RpbmcpIHsKKyAgICAgICAgdGhpcy5ub3RCZWZvcmVEYXRlID0gbm90QmVmb3JlRGF0ZTsKKyAgICAgICAgdGhpcy5ub3RBZnRlckRhdGUgPSBub3RBZnRlckRhdGU7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBub3RCZWZvcmUgZmllbGQgb2YgdGhlIHN0cnVjdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0ZSBnZXROb3RCZWZvcmUoKSB7CisgICAgICAgIHJldHVybiBub3RCZWZvcmVEYXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIG5vdEFmdGVyIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUuCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0Tm90QWZ0ZXIoKSB7CisgICAgICAgIHJldHVybiBub3RBZnRlckRhdGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBlbmNvZGVkIGZvcm0gb2YgdGhpcyBYLjUwOSBQcml2YXRlS2V5VXNhZ2VQZXJpb2QgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RpbmcgPSBBU04xLmVuY29kZSh0aGlzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgLyoqCisgICAgICogQVNOLjEgREVSIFguNTA5IFByaXZhdGVLZXlVc2FnZVBlcmlvZCBlbmNvZGVyL2RlY29kZXIgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xU2VxdWVuY2UgQVNOMSA9IG5ldyBBU04xU2VxdWVuY2UobmV3IEFTTjFUeXBlW10geworICAgICAgICAgICAgbmV3IEFTTjFJbXBsaWNpdCgwLCBBU04xR2VuZXJhbGl6ZWRUaW1lLmdldEluc3RhbmNlKCkpLAorICAgICAgICAgICAgbmV3IEFTTjFJbXBsaWNpdCgxLCBBU04xR2VuZXJhbGl6ZWRUaW1lLmdldEluc3RhbmNlKCkpIH0pIHsKKyAgICAgICAgeworICAgICAgICAgICAgc2V0T3B0aW9uYWwoMCk7CisgICAgICAgICAgICBzZXRPcHRpb25hbCgxKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgICAgIE9iamVjdFtdIHZhbHVlcyA9IChPYmplY3RbXSlpbi5jb250ZW50OworICAgICAgICAgICAgcmV0dXJuIG5ldyBQcml2YXRlS2V5VXNhZ2VQZXJpb2QoKERhdGUpIHZhbHVlc1swXSwgKERhdGUpIHZhbHVlc1sxXSwgaW4uZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCwgT2JqZWN0W10gdmFsdWVzKSB7CisgICAgICAgICAgICBQcml2YXRlS2V5VXNhZ2VQZXJpb2QgcGt1cCA9IChQcml2YXRlS2V5VXNhZ2VQZXJpb2QpIG9iamVjdDsKKyAgICAgICAgICAgIHZhbHVlc1swXSA9IHBrdXAubm90QmVmb3JlRGF0ZTsKKyAgICAgICAgICAgIHZhbHVlc1sxXSA9IHBrdXAubm90QWZ0ZXJEYXRlOworICAgICAgICB9CisgICAgfTsKK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L1JlYXNvbkNvZGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9SZWFzb25Db2RlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTgzZWNkZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9SZWFzb25Db2RlLmphdmEKQEAgLTAsMCArMSwxMTUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFFbnVtZXJhdGVkOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworCisvKioKKyAqIENSTCBFbnRyeSdzIFJlYXNvbiBDb2RlIEV4dGVuc2lvbiAoT0lEID0gMi41LjI5LjIxKS4KKyAqIDxwcmU+CisgKiAgaWQtY2UtY1JMUmVhc29uIE9CSkVDVCBJREVOVElGSUVSIDo6PSB7IGlkLWNlIDIxIH0KKyAqCisgKiAgLS0gcmVhc29uQ29kZSA6Oj0geyBDUkxSZWFzb24gfQorICogIENSTFJlYXNvbiA6Oj0gRU5VTUVSQVRFRCB7CisgKiAgICAgICB1bnNwZWNpZmllZCAgICAgICAgICAgICAoMCksCisgKiAgICAgICBrZXlDb21wcm9taXNlICAgICAgICAgICAoMSksCisgKiAgICAgICBjQUNvbXByb21pc2UgICAgICAgICAgICAoMiksCisgKiAgICAgICBhZmZpbGlhdGlvbkNoYW5nZWQgICAgICAoMyksCisgKiAgICAgICBzdXBlcnNlZGVkICAgICAgICAgICAgICAoNCksCisgKiAgICAgICBjZXNzYXRpb25PZk9wZXJhdGlvbiAgICAoNSksCisgKiAgICAgICBjZXJ0aWZpY2F0ZUhvbGQgICAgICAgICAoNiksCisgKiAgICAgICByZW1vdmVGcm9tQ1JMICAgICAgICAgICAoOCksCisgKiAgICAgICBwcml2aWxlZ2VXaXRoZHJhd24gICAgICAoOSksCisgKiAgICAgICBhQUNvbXByb21pc2UgICAgICAgICAgICgxMCkKKyAqICB9CisgKiA8L3ByZT4KKyAqIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBSZWFzb25Db2RlIGV4dGVuZHMgRXh0ZW5zaW9uVmFsdWUgeworCisgICAgLy8gcHJlZGVmaW5lZCByZWFzb24gY29kZSB2YWx1ZXMKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgVU5TUEVDSUZJRUQgPSAwOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBLRVlfQ09NUFJPTUlTRSA9IDE7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIENBX0NPTVBST01JU0UgPSAyOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBBRkZJTElBVElPTl9DSEFOR0VEID0gMzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgU1VQRVJTRURFRCA9IDQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIENFU1NBVElPTl9PRl9PUEVSQVRJT04gPSA1OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBDRVJUSUZJQ0FURV9IT0xEID0gNjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgUkVNT1ZFX0ZST01fQ1JMID0gODsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgUFJJVklMRUdFX1dJVEhEUkFXTiA9IDk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIEFBX0NPTVBST01JU0UgPSAxMDsKKworICAgIC8vIHRoZSByZWFzb24gY29kZSB2YWx1ZQorICAgIHByaXZhdGUgZmluYWwgYnl0ZSBjb2RlOworCisgICAgcHVibGljIFJlYXNvbkNvZGUoYnl0ZVtdIGVuY29kaW5nKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihlbmNvZGluZyk7CisgICAgICAgIHRoaXMuY29kZSA9ICgoYnl0ZVtdKSBBU04xLmRlY29kZShlbmNvZGluZykpWzBdOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKG5ldyBieXRlW10geyBjb2RlIH0pOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZHVtcFZhbHVlKFN0cmluZ0J1aWxkZXIgc2IsIFN0cmluZyBwcmVmaXgpIHsKKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJSZWFzb24gQ29kZTogWyAiKTsKKyAgICAgICAgc3dpdGNoIChjb2RlKSB7CisgICAgICAgIGNhc2UgVU5TUEVDSUZJRUQ6CisgICAgICAgICAgICBzYi5hcHBlbmQoInVuc3BlY2lmaWVkIik7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBLRVlfQ09NUFJPTUlTRToKKyAgICAgICAgICAgIHNiLmFwcGVuZCgia2V5Q29tcHJvbWlzZSIpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgQ0FfQ09NUFJPTUlTRToKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiY0FDb21wcm9taXNlIik7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBBRkZJTElBVElPTl9DSEFOR0VEOgorICAgICAgICAgICAgc2IuYXBwZW5kKCJhZmZpbGlhdGlvbkNoYW5nZWQiKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFNVUEVSU0VERUQ6CisgICAgICAgICAgICBzYi5hcHBlbmQoInN1cGVyc2VkZWQiKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIENFU1NBVElPTl9PRl9PUEVSQVRJT046CisgICAgICAgICAgICBzYi5hcHBlbmQoImNlc3NhdGlvbk9mT3BlcmF0aW9uIik7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBDRVJUSUZJQ0FURV9IT0xEOgorICAgICAgICAgICAgc2IuYXBwZW5kKCJjZXJ0aWZpY2F0ZUhvbGQiKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFJFTU9WRV9GUk9NX0NSTDoKKyAgICAgICAgICAgIHNiLmFwcGVuZCgicmVtb3ZlRnJvbUNSTCIpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgUFJJVklMRUdFX1dJVEhEUkFXTjoKKyAgICAgICAgICAgIHNiLmFwcGVuZCgicHJpdmlsZWdlV2l0aGRyYXduIik7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBBQV9DT01QUk9NSVNFOgorICAgICAgICAgICAgc2IuYXBwZW5kKCJhQUNvbXByb21pc2UiKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZCgiIF1cbiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFTTi4xIEVuY29kZXIvRGVjb2Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFUeXBlIEFTTjEgPSBBU04xRW51bWVyYXRlZC5nZXRJbnN0YW5jZSgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L1JlYXNvbkZsYWdzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvUmVhc29uRmxhZ3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MjMxZTYxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L1JlYXNvbkZsYWdzLmphdmEKQEAgLTAsMCArMSwxMDUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUJpdFN0cmluZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJPdXRwdXRTdHJlYW07CisKKy8qKgorICogVGhlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgQVNOLjEgREVSIGVuY29kaW5nL2RlY29kaW5nIHdvcmsKKyAqIHdpdGggdGhlIGZvbGxvd2luZyBwYXJ0IG9mIFguNTA5IENSTAorICogKGFzIHNwZWNpZmllZCBpbiBSRkMgMzI4MCAtCisgKiAgSW50ZXJuZXQgWC41MDkgUHVibGljIEtleSBJbmZyYXN0cnVjdHVyZS4KKyAqICBDZXJ0aWZpY2F0ZSBhbmQgQ2VydGlmaWNhdGUgUmV2b2NhdGlvbiBMaXN0IChDUkwpIFByb2ZpbGUuCisgKiAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpOgorICoKKyAqIDxwcmU+CisgKiAgUmVhc29uRmxhZ3MgOjo9IEJJVCBTVFJJTkcgeworICogICAgICAgIHVudXNlZCAgICAgICAgICAgICAgICAgICgwKSwKKyAqICAgICAgICBrZXlDb21wcm9taXNlICAgICAgICAgICAoMSksCisgKiAgICAgICAgY0FDb21wcm9taXNlICAgICAgICAgICAgKDIpLAorICogICAgICAgIGFmZmlsaWF0aW9uQ2hhbmdlZCAgICAgICgzKSwKKyAqICAgICAgICBzdXBlcnNlZGVkICAgICAgICAgICAgICAoNCksCisgKiAgICAgICAgY2Vzc2F0aW9uT2ZPcGVyYXRpb24gICAgKDUpLAorICogICAgICAgIGNlcnRpZmljYXRlSG9sZCAgICAgICAgICg2KSwKKyAqICAgICAgICBwcml2aWxlZ2VXaXRoZHJhd24gICAgICAoNyksCisgKiAgICAgICAgYUFDb21wcm9taXNlICAgICAgICAgICAgKDgpCisgKiAgfQorICogIDwvcHJlPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUmVhc29uRmxhZ3MgeworCisgICAgLyoqCisgICAgICogVGhlIG5hbWVzIG9mIHRoZSByZWFzb25zLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBSRUFTT05TID0geworICAgICAgICAidW51c2VkIiwKKyAgICAgICAgImtleUNvbXByb21pc2UiLAorICAgICAgICAiY0FDb21wcm9taXNlIiwKKyAgICAgICAgImFmZmlsaWF0aW9uQ2hhbmdlZCIsCisgICAgICAgICJzdXBlcnNlZGVkIiwKKyAgICAgICAgImNlc3NhdGlvbk9mT3BlcmF0aW9uIiwKKyAgICAgICAgImNlcnRpZmljYXRlSG9sZCIsCisgICAgICAgICJwcml2aWxlZ2VXaXRoZHJhd24iLAorICAgICAgICAiYUFDb21wcm9taXNlIgorICAgIH07CisKKyAgICAvKiogdGhlIHZhbHVlIG9mIGV4dGVuc2lvbiAqLworICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbltdIGZsYWdzOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgZXh0ZW5zaW9uIG9iamVjdCBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbiBmbGFncy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVhc29uRmxhZ3MoYm9vbGVhbltdIGZsYWdzKSB7CisgICAgICAgIHRoaXMuZmxhZ3MgPSBmbGFnczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBkdW1wVmFsdWUoU3RyaW5nQnVpbGRlciBzYiwgU3RyaW5nIHByZWZpeCkgeworICAgICAgICBzYi5hcHBlbmQocHJlZml4KTsKKyAgICAgICAgc2IuYXBwZW5kKCJSZWFzb25GbGFncyBbXG4iKTsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPGZsYWdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoZmxhZ3NbaV0pIHsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQocHJlZml4KS5hcHBlbmQoIiAgIikuYXBwZW5kKFJFQVNPTlNbaV0pLmFwcGVuZCgnXG4nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzYi5hcHBlbmQocHJlZml4KTsKKyAgICAgICAgc2IuYXBwZW5kKCJdXG4iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBU04uMSBFbmNvZGVyL0RlY29kZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xQml0U3RyaW5nIEFTTjEgPQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBBU04xQml0U3RyaW5nLkFTTjFOYW1lZEJpdExpc3QoUkVBU09OUy5sZW5ndGgpIHsKKyAgICAgICAgcHVibGljIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWFzb25GbGFncygoYm9vbGVhbltdKSBzdXBlci5nZXREZWNvZGVkT2JqZWN0KGluKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZ0NvbnRlbnQoQmVyT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgICAgICAgb3V0LmNvbnRlbnQgPSAoKFJlYXNvbkZsYWdzKSBvdXQuY29udGVudCkuZmxhZ3M7CisgICAgICAgICAgICBzdXBlci5zZXRFbmNvZGluZ0NvbnRlbnQob3V0KTsKKyAgICAgICAgfQorICAgIH07Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvU3ViamVjdEtleUlkZW50aWZpZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9TdWJqZWN0S2V5SWRlbnRpZmllci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc0MTUwMDIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvU3ViamVjdEtleUlkZW50aWZpZXIuamF2YQpAQCAtMCwwICsxLDczIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xT2N0ZXRTdHJpbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnV0aWxzLkFycmF5OworCisvKioKKyAqIFN1YmplY3QgS2V5IElkZW50aWZpZXIgRXh0ZW5zaW9uIChPSUQgPSAyLjUuMjkuMTQpLgorICoKKyAqIFRoZSBBU04uMSBkZWZpbml0aW9uIGZvciBleHRlbnNpb24gaXM6CisgKgorICogPHByZT4KKyAqICBpZC1jZS1zdWJqZWN0S2V5SWRlbnRpZmllciBPQkpFQ1QgSURFTlRJRklFUiA6Oj0gIHsgaWQtY2UgMTQgfQorICoKKyAqICBTdWJqZWN0S2V5SWRlbnRpZmllciA6Oj0gS2V5SWRlbnRpZmllcgorICoKKyAqICBLZXlJZGVudGlmaWVyIDo6PSBPQ1RFVCBTVFJJTkcKKyAqIDwvcHJlPgorICogKGFzIHNwZWNpZmllZCBpbiBSRkMgMzI4MCBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCkKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFN1YmplY3RLZXlJZGVudGlmaWVyIGV4dGVuZHMgRXh0ZW5zaW9uVmFsdWUgeworCisgICAgLy8gdGhlIHZhbHVlIG9mIGtleSBpZGVudGlmaWVyCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10ga2V5SWRlbnRpZmllcjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIG9iamVjdCBvbiB0aGUgYmFzZSBvZiB0aGUgdmFsdWUgb2Yga2V5IGlkZW50aWZpZXIuCisgICAgICovCisgICAgcHVibGljIFN1YmplY3RLZXlJZGVudGlmaWVyKGJ5dGVbXSBrZXlJZGVudGlmaWVyKSB7CisgICAgICAgIHRoaXMua2V5SWRlbnRpZmllciA9IGtleUlkZW50aWZpZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBvYmplY3Qgb24gdGhlIGJhc2Ugb2YgaXRzIGVuY29kZWQgZm9ybS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN1YmplY3RLZXlJZGVudGlmaWVyIGRlY29kZShieXRlW10gZW5jb2RpbmcpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdWJqZWN0S2V5SWRlbnRpZmllciByZXMgPSBuZXcgU3ViamVjdEtleUlkZW50aWZpZXIoKGJ5dGVbXSkKKyAgICAgICAgICAgICAgICBBU04xT2N0ZXRTdHJpbmcuZ2V0SW5zdGFuY2UoKS5kZWNvZGUoZW5jb2RpbmcpKTsKKyAgICAgICAgcmVzLmVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIGVuY29kaW5nID0gQVNOMU9jdGV0U3RyaW5nLmdldEluc3RhbmNlKCkuZW5jb2RlKGtleUlkZW50aWZpZXIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZHVtcFZhbHVlKFN0cmluZ0J1aWxkZXIgc2IsIFN0cmluZyBwcmVmaXgpIHsKKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJTdWJqZWN0S2V5SWRlbnRpZmllcjogW1xuIik7CisgICAgICAgIHNiLmFwcGVuZChBcnJheS50b1N0cmluZyhrZXlJZGVudGlmaWVyLCBwcmVmaXgpKTsKKyAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJdXG4iKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvU3ViamVjdFB1YmxpY0tleUluZm8uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9TdWJqZWN0UHVibGljS2V5SW5mby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU0NWQ0ODkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvU3ViamVjdFB1YmxpY0tleUluZm8uamF2YQpAQCAtMCwwICsxLDE1MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlGYWN0b3J5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5JbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuWDUwOUVuY29kZWRLZXlTcGVjOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFCaXRTdHJpbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJpdFN0cmluZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudXRpbHMuQWxnTmFtZU1hcHBlcjsKKworLyoqCisgKiBUaGUgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBBU04uMSBERVIgZW5jb2RpbmcvZGVjb2Rpbmcgd29yaworICogd2l0aCB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZSB3aGljaCBpcyBhIHBhcnQgb2YgWC41MDkgY2VydGlmaWNhdGUKKyAqIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODAgLQorICogIEludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUuCisgKiAgQ2VydGlmaWNhdGUgYW5kIENlcnRpZmljYXRlIFJldm9jYXRpb24gTGlzdCAoQ1JMKSBQcm9maWxlLgorICogIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KToKKyAqCisgKiA8cHJlPgorICogIFN1YmplY3RQdWJsaWNLZXlJbmZvICA6Oj0gIFNFUVVFTkNFICB7CisgKiAgICAgIGFsZ29yaXRobSAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIsCisgKiAgICAgIHN1YmplY3RQdWJsaWNLZXkgICAgIEJJVCBTVFJJTkcKKyAqICB9CisgKiA8L3ByZT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFN1YmplY3RQdWJsaWNLZXlJbmZvIHsKKyAgICAvKiogdGhlIHZhbHVlIG9mIGFsZ29yaXRobUlEIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIEFsZ29yaXRobUlkZW50aWZpZXIgYWxnb3JpdGhtSUQ7CisgICAgLyoqIHRoZSB2YWx1ZSBvZiBzdWJqZWN0UHVibGljS2V5IGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBzdWJqZWN0UHVibGljS2V5OworICAgIC8qKiB0aGUgcHVibGljIGtleSBjb3JyZXNwb25kaW5nIHRvIHRoaXMgU3ViamVjdFB1YmxpY0tleUluZm8gKi8KKyAgICBwcml2YXRlIFB1YmxpY0tleSBwdWJsaWNLZXk7CisgICAgLyoqIHRoZSB2YWx1ZSBvZiB1bnVzZWRCaXRzIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGludCB1bnVzZWRCaXRzOworICAgIC8qKiB0aGUgQVNOLjEgZW5jb2RlZCBmb3JtIG9mIFN1YmplY3RQdWJsaWNLZXlJbmZvICovCisgICAgcHJpdmF0ZSBieXRlW10gZW5jb2Rpbmc7CisKKyAgICBwdWJsaWMgU3ViamVjdFB1YmxpY0tleUluZm8oQWxnb3JpdGhtSWRlbnRpZmllciBhbGdJRCwgYnl0ZVtdIHN1YmplY3RQdWJsaWNLZXkpIHsKKyAgICAgICAgdGhpcyhhbGdJRCwgc3ViamVjdFB1YmxpY0tleSwgMCk7CisgICAgfQorCisgICAgcHVibGljIFN1YmplY3RQdWJsaWNLZXlJbmZvKEFsZ29yaXRobUlkZW50aWZpZXIgYWxnSUQsIGJ5dGVbXSBzdWJqZWN0UHVibGljS2V5LCBpbnQgdW51c2VkKSB7CisgICAgICAgIHRoaXMoYWxnSUQsIHN1YmplY3RQdWJsaWNLZXksIDAsIG51bGwpOworICAgIH0KKworICAgIHByaXZhdGUgU3ViamVjdFB1YmxpY0tleUluZm8oQWxnb3JpdGhtSWRlbnRpZmllciBhbGdJRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBzdWJqZWN0UHVibGljS2V5LCBpbnQgdW51c2VkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIGVuY29kaW5nKSB7CisgICAgICAgIHRoaXMuYWxnb3JpdGhtSUQgPSBhbGdJRDsKKyAgICAgICAgdGhpcy5zdWJqZWN0UHVibGljS2V5ID0gc3ViamVjdFB1YmxpY0tleTsKKyAgICAgICAgdGhpcy51bnVzZWRCaXRzID0gdW51c2VkOworICAgICAgICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYWxnb3JpdGhtSWRlbnRpZmllciBmaWVsZCBvZiB0aGUgc3RydWN0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBBbGdvcml0aG1JZGVudGlmaWVyIGdldEFsZ29yaXRobUlkZW50aWZpZXIoKSB7CisgICAgICAgIHJldHVybiBhbGdvcml0aG1JRDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBzdWJqZWN0UHVibGljS2V5IGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRTdWJqZWN0UHVibGljS2V5KCkgeworICAgICAgICByZXR1cm4gc3ViamVjdFB1YmxpY0tleTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFTTi4xIGVuY29kZWQgZm9ybSBvZiB0aGlzIFguNTA5IFN1YmplY3RQdWJsaWNLZXlJbmZvIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHsKKyAgICAgICAgICAgIGVuY29kaW5nID0gQVNOMS5lbmNvZGUodGhpcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVuY29kaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgVGhlIFB1YmxpY0tleSBjb3JyZXNwb25kaW5nIHRvIHRoaXMgU3ViamVjdFB1YmxpY0tleUluZm8KKyAgICAgKiBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHVibGljS2V5IGdldFB1YmxpY0tleSgpIHsKKyAgICAgICAgaWYgKHB1YmxpY0tleSA9PSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgYWxnX29pZCA9IGFsZ29yaXRobUlELmdldEFsZ29yaXRobSgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgYWxnID0KKyAgICAgICAgICAgICAgICAgICAgQWxnTmFtZU1hcHBlci5tYXAyQWxnTmFtZShhbGdfb2lkKTsKKworICAgICAgICAgICAgICAgIGlmIChhbGcgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBhbGcgPSBhbGdfb2lkOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBwdWJsaWNLZXkgPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKGFsZykKKyAgICAgICAgICAgICAgICAgICAgLmdlbmVyYXRlUHVibGljKG5ldyBYNTA5RW5jb2RlZEtleVNwZWMoZ2V0RW5jb2RlZCgpKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHB1YmxpY0tleSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcHVibGljS2V5ID0gbmV3IFg1MDlQdWJsaWNLZXkoYWxnX29pZCwgZ2V0RW5jb2RlZCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgc3ViamVjdFB1YmxpY0tleSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHB1YmxpY0tleTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZShuZXcgQVNOMVR5cGVbXSB7CisgICAgICAgICAgICBBbGdvcml0aG1JZGVudGlmaWVyLkFTTjEsIEFTTjFCaXRTdHJpbmcuZ2V0SW5zdGFuY2UoKSB9KSB7CisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgICAgIE9iamVjdFtdIHZhbHVlcyA9IChPYmplY3RbXSkgaW4uY29udGVudDsKKyAgICAgICAgICAgIHJldHVybiBuZXcgU3ViamVjdFB1YmxpY0tleUluZm8oCisgICAgICAgICAgICAgICAgICAgIChBbGdvcml0aG1JZGVudGlmaWVyKSB2YWx1ZXNbMF0sCisgICAgICAgICAgICAgICAgICAgICgoQml0U3RyaW5nKSB2YWx1ZXNbMV0pLmJ5dGVzLAorICAgICAgICAgICAgICAgICAgICAoKEJpdFN0cmluZykgdmFsdWVzWzFdKS51bnVzZWRCaXRzLAorICAgICAgICAgICAgICAgICAgICBpbi5nZXRFbmNvZGVkKCkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKyAgICAgICAgICAgIFN1YmplY3RQdWJsaWNLZXlJbmZvIHNwa2kgPSAoU3ViamVjdFB1YmxpY0tleUluZm8pIG9iamVjdDsKKyAgICAgICAgICAgIHZhbHVlc1swXSA9IHNwa2kuYWxnb3JpdGhtSUQ7CisgICAgICAgICAgICB2YWx1ZXNbMV0gPSBuZXcgQml0U3RyaW5nKHNwa2kuc3ViamVjdFB1YmxpY0tleSwgc3BraS51bnVzZWRCaXRzKTsKKyAgICAgICAgfQorICAgIH07Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9UQlNDZXJ0TGlzdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L1RCU0NlcnRMaXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWFkODk5MAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9UQlNDZXJ0TGlzdC5qYXZhCkBAIC0wLDAgKzEsMzY3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUV4cGxpY2l0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFJbnRlZ2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXF1ZW5jZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2VxdWVuY2VPZjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwMS5OYW1lOworCisKKy8qKgorICogVGhlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgQVNOLjEgREVSIGVuY29kaW5nL2RlY29kaW5nIHdvcmsKKyAqIHdpdGggVEJTQ2VydExpc3Qgc3RydWN0dXJlIHdoaWNoIGlzIHRoZSBwYXJ0IG9mIFguNTA5IENSTAorICogKGFzIHNwZWNpZmllZCBpbiBSRkMgMzI4MCAtCisgKiAgSW50ZXJuZXQgWC41MDkgUHVibGljIEtleSBJbmZyYXN0cnVjdHVyZS4KKyAqICBDZXJ0aWZpY2F0ZSBhbmQgQ2VydGlmaWNhdGUgUmV2b2NhdGlvbiBMaXN0IChDUkwpIFByb2ZpbGUuCisgKiAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpOgorICoKKyAqIDxwcmU+CisgKiAgIFRCU0NlcnRMaXN0ICA6Oj0gIFNFUVVFTkNFICB7CisgKiAgICAgICAgdmVyc2lvbiAgICAgICAgICAgICAgICAgVmVyc2lvbiBPUFRJT05BTCwKKyAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tIGlmIHByZXNlbnQsIE1VU1QgYmUgdjIKKyAqICAgICAgICBzaWduYXR1cmUgICAgICAgICAgICAgICBBbGdvcml0aG1JZGVudGlmaWVyLAorICogICAgICAgIGlzc3VlciAgICAgICAgICAgICAgICAgIE5hbWUsCisgKiAgICAgICAgdGhpc1VwZGF0ZSAgICAgICAgICAgICAgVGltZSwKKyAqICAgICAgICBuZXh0VXBkYXRlICAgICAgICAgICAgICBUaW1lIE9QVElPTkFMLAorICogICAgICAgIHJldm9rZWRDZXJ0aWZpY2F0ZXMgICAgIFNFUVVFTkNFIE9GIFNFUVVFTkNFICB7CisgKiAgICAgICAgICAgICB1c2VyQ2VydGlmaWNhdGUgICAgICAgICBDZXJ0aWZpY2F0ZVNlcmlhbE51bWJlciwKKyAqICAgICAgICAgICAgIHJldm9jYXRpb25EYXRlICAgICAgICAgIFRpbWUsCisgKiAgICAgICAgICAgICBjcmxFbnRyeUV4dGVuc2lvbnMgICAgICBFeHRlbnNpb25zIE9QVElPTkFMCisgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLSBpZiBwcmVzZW50LCBNVVNUIGJlIHYyCisgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9ICBPUFRJT05BTCwKKyAqICAgICAgICBjcmxFeHRlbnNpb25zICAgICAgICAgICBbMF0gIEVYUExJQ0lUIEV4dGVuc2lvbnMgT1BUSU9OQUwKKyAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tIGlmIHByZXNlbnQsIE1VU1QgYmUgdjIKKyAqICAgfQorICogPC9wcmU+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBUQlNDZXJ0TGlzdCB7CisgICAgLyoqIHRoZSB2YWx1ZSBvZiB2ZXJzaW9uIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCB2ZXJzaW9uOworICAgIC8qKiB0aGUgdmFsdWUgb2Ygc2lnbmF0dXJlIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIEFsZ29yaXRobUlkZW50aWZpZXIgc2lnbmF0dXJlOworICAgIC8qKiB0aGUgdmFsdWUgb2YgaXNzdWVyIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIE5hbWUgaXNzdWVyOworICAgIC8qKiB0aGUgdmFsdWUgb2YgdGhpc1VwZGF0ZSBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBmaW5hbCBEYXRlIHRoaXNVcGRhdGU7CisgICAgLyoqIHRoZSB2YWx1ZSBvZiBuZXh0VXBkYXRlIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIERhdGUgbmV4dFVwZGF0ZTsKKyAgICAvKiogdGhlIHZhbHVlIG9mIHJldm9rZWRDZXJ0aWZpY2F0ZXMgb2YgdGhlIHN0cnVjdHVyZSAqLworICAgIHByaXZhdGUgZmluYWwgTGlzdDxSZXZva2VkQ2VydGlmaWNhdGU+IHJldm9rZWRDZXJ0aWZpY2F0ZXM7CisgICAgLyoqIHRoZSB2YWx1ZSBvZiBjcmxFeHRlbnNpb25zIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIEV4dGVuc2lvbnMgY3JsRXh0ZW5zaW9uczsKKyAgICAvKiogdGhlIEFTTi4xIGVuY29kZWQgZm9ybSBvZiBUQlNDZXJ0TGlzdCAqLworICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kaW5nOworCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBSZXZva2VkQ2VydGlmaWNhdGUgeworICAgICAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgdXNlckNlcnRpZmljYXRlOworICAgICAgICBwcml2YXRlIGZpbmFsIERhdGUgcmV2b2NhdGlvbkRhdGU7CisgICAgICAgIHByaXZhdGUgZmluYWwgRXh0ZW5zaW9ucyBjcmxFbnRyeUV4dGVuc2lvbnM7CisKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzc3VlclJldHJpZXZlZDsKKyAgICAgICAgcHJpdmF0ZSBYNTAwUHJpbmNpcGFsIGlzc3VlcjsKKyAgICAgICAgcHJpdmF0ZSBieXRlW10gZW5jb2Rpbmc7CisKKyAgICAgICAgcHVibGljIFJldm9rZWRDZXJ0aWZpY2F0ZShCaWdJbnRlZ2VyIHVzZXJDZXJ0aWZpY2F0ZSwKKyAgICAgICAgICAgICAgICBEYXRlIHJldm9jYXRpb25EYXRlLCBFeHRlbnNpb25zIGNybEVudHJ5RXh0ZW5zaW9ucykgeworICAgICAgICAgICAgdGhpcy51c2VyQ2VydGlmaWNhdGUgPSB1c2VyQ2VydGlmaWNhdGU7CisgICAgICAgICAgICB0aGlzLnJldm9jYXRpb25EYXRlID0gcmV2b2NhdGlvbkRhdGU7CisgICAgICAgICAgICB0aGlzLmNybEVudHJ5RXh0ZW5zaW9ucyA9IGNybEVudHJ5RXh0ZW5zaW9uczsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFeHRlbnNpb25zIGdldENybEVudHJ5RXh0ZW5zaW9ucygpIHsKKyAgICAgICAgICAgIHJldHVybiBjcmxFbnRyeUV4dGVuc2lvbnM7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRVc2VyQ2VydGlmaWNhdGUoKSB7CisgICAgICAgICAgICByZXR1cm4gdXNlckNlcnRpZmljYXRlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIERhdGUgZ2V0UmV2b2NhdGlvbkRhdGUoKSB7CisgICAgICAgICAgICByZXR1cm4gcmV2b2NhdGlvbkRhdGU7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgQ2VydGlmaWNhdGUgSXNzdWVyIEV4dGVuc2lvbiwgaWYgaXQgaXMKKyAgICAgICAgICogcHJlc2VudGVkLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFg1MDBQcmluY2lwYWwgZ2V0SXNzdWVyKCkgeworICAgICAgICAgICAgaWYgKGNybEVudHJ5RXh0ZW5zaW9ucyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIWlzc3VlclJldHJpZXZlZCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGlzc3VlciA9CisgICAgICAgICAgICAgICAgICAgICAgICBjcmxFbnRyeUV4dGVuc2lvbnMudmFsdWVPZkNlcnRpZmljYXRlSXNzdWVyRXh0ZW5zaW9uKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpc3N1ZXJSZXRyaWV2ZWQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGlzc3VlcjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgZW5jb2RpbmcgPSBBU04xLmVuY29kZSh0aGlzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgcmMpIHsKKyAgICAgICAgICAgIGlmICghKHJjIGluc3RhbmNlb2YgUmV2b2tlZENlcnRpZmljYXRlKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFJldm9rZWRDZXJ0aWZpY2F0ZSByY2VydCA9IChSZXZva2VkQ2VydGlmaWNhdGUpIHJjOworICAgICAgICAgICAgcmV0dXJuIHVzZXJDZXJ0aWZpY2F0ZS5lcXVhbHMocmNlcnQudXNlckNlcnRpZmljYXRlKQorICAgICAgICAgICAgICAgICYmICgocmV2b2NhdGlvbkRhdGUuZ2V0VGltZSgpIC8gMTAwMCkKKyAgICAgICAgICAgICAgICAgICAgICAgID09IChyY2VydC5yZXZvY2F0aW9uRGF0ZS5nZXRUaW1lKCkgLyAxMDAwKSkKKyAgICAgICAgICAgICAgICAmJiAoKGNybEVudHJ5RXh0ZW5zaW9ucyA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICA/IHJjZXJ0LmNybEVudHJ5RXh0ZW5zaW9ucyA9PSBudWxsCisgICAgICAgICAgICAgICAgICAgIDogY3JsRW50cnlFeHRlbnNpb25zLmVxdWFscyhyY2VydC5jcmxFbnRyeUV4dGVuc2lvbnMpKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICByZXR1cm4gdXNlckNlcnRpZmljYXRlLmhhc2hDb2RlKCkgKiAzNyArIChpbnQpcmV2b2NhdGlvbkRhdGUuZ2V0VGltZSgpIC8gMTAwMAorICAgICAgICAgICAgICAgICAgICArIChjcmxFbnRyeUV4dGVuc2lvbnMgPT0gbnVsbCA/IDAgOiBjcmxFbnRyeUV4dGVuc2lvbnMuaGFzaENvZGUoKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBkdW1wVmFsdWUoU3RyaW5nQnVpbGRlciBzYiwgU3RyaW5nIHByZWZpeCkgeworICAgICAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCJDZXJ0aWZpY2F0ZSBTZXJpYWwgTnVtYmVyOiAiKS5hcHBlbmQodXNlckNlcnRpZmljYXRlKS5hcHBlbmQoJ1xuJyk7CisgICAgICAgICAgICBzYi5hcHBlbmQocHJlZml4KS5hcHBlbmQoIlJldm9jYXRpb24gRGF0ZTogIikuYXBwZW5kKHJldm9jYXRpb25EYXRlKTsKKyAgICAgICAgICAgIGlmIChjcmxFbnRyeUV4dGVuc2lvbnMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgnXG4nKS5hcHBlbmQocHJlZml4KS5hcHBlbmQoIkNSTCBFbnRyeSBFeHRlbnNpb25zOiBbIik7CisgICAgICAgICAgICAgICAgY3JsRW50cnlFeHRlbnNpb25zLmR1bXBWYWx1ZShzYiwgcHJlZml4ICsgIiAgIik7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCddJyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZSgKKyAgICAgICAgICAgICAgICBuZXcgQVNOMVR5cGVbXSB7QVNOMUludGVnZXIuZ2V0SW5zdGFuY2UoKSwgVGltZS5BU04xLAorICAgICAgICAgICAgICAgIEV4dGVuc2lvbnMuQVNOMX0pIHsKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBzZXRPcHRpb25hbCgyKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgICAgIE9iamVjdFtdIHZhbHVlcyA9IChPYmplY3RbXSkgaW4uY29udGVudDsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJldm9rZWRDZXJ0aWZpY2F0ZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigoYnl0ZVtdKSB2YWx1ZXNbMF0pLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChEYXRlKSB2YWx1ZXNbMV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEV4dGVuc2lvbnMpIHZhbHVlc1syXQorICAgICAgICAgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKyAgICAgICAgICAgICAgICBSZXZva2VkQ2VydGlmaWNhdGUgcmNlcnQgPSAoUmV2b2tlZENlcnRpZmljYXRlKSBvYmplY3Q7CisgICAgICAgICAgICAgICAgdmFsdWVzWzBdID0gcmNlcnQudXNlckNlcnRpZmljYXRlLnRvQnl0ZUFycmF5KCk7CisgICAgICAgICAgICAgICAgdmFsdWVzWzFdID0gcmNlcnQucmV2b2NhdGlvbkRhdGU7CisgICAgICAgICAgICAgICAgdmFsdWVzWzJdID0gcmNlcnQuY3JsRW50cnlFeHRlbnNpb25zOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIC8qKiBDb25zdHJ1Y3RzIHRoZSBvYmplY3Qgd2l0aCBhc3NvY2lhdGVkIEFTTi4xIGVuY29kaW5nICovCisgICAgcHJpdmF0ZSBUQlNDZXJ0TGlzdChpbnQgdmVyc2lvbiwgQWxnb3JpdGhtSWRlbnRpZmllciBzaWduYXR1cmUsCisgICAgICAgICAgICBOYW1lIGlzc3VlciwgRGF0ZSB0aGlzVXBkYXRlLCBEYXRlIG5leHRVcGRhdGUsCisgICAgICAgICAgICBMaXN0PFJldm9rZWRDZXJ0aWZpY2F0ZT4gcmV2b2tlZENlcnRpZmljYXRlcywgRXh0ZW5zaW9ucyBjcmxFeHRlbnNpb25zLAorICAgICAgICAgICAgYnl0ZVtdIGVuY29kaW5nKSB7CisgICAgICAgIHRoaXMudmVyc2lvbiA9IHZlcnNpb247CisgICAgICAgIHRoaXMuc2lnbmF0dXJlID0gc2lnbmF0dXJlOworICAgICAgICB0aGlzLmlzc3VlciA9IGlzc3VlcjsKKyAgICAgICAgdGhpcy50aGlzVXBkYXRlID0gdGhpc1VwZGF0ZTsKKyAgICAgICAgdGhpcy5uZXh0VXBkYXRlID0gbmV4dFVwZGF0ZTsKKyAgICAgICAgdGhpcy5yZXZva2VkQ2VydGlmaWNhdGVzID0gcmV2b2tlZENlcnRpZmljYXRlczsKKyAgICAgICAgdGhpcy5jcmxFeHRlbnNpb25zID0gY3JsRXh0ZW5zaW9uczsKKyAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHZlcnNpb24gZmllbGQgb2YgdGhlIHN0cnVjdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFZlcnNpb24oKSB7CisgICAgICAgIHJldHVybiB2ZXJzaW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHNpZ25hdHVyZSBmaWVsZCBvZiB0aGUgc3RydWN0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBBbGdvcml0aG1JZGVudGlmaWVyIGdldFNpZ25hdHVyZSgpIHsKKyAgICAgICAgcmV0dXJuIHNpZ25hdHVyZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBpc3N1ZXIgZmllbGQgb2YgdGhlIHN0cnVjdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTmFtZSBnZXRJc3N1ZXIoKSB7CisgICAgICAgIHJldHVybiBpc3N1ZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhpc1VwZGF0ZSBmaWVsZCBvZiB0aGUgc3RydWN0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBEYXRlIGdldFRoaXNVcGRhdGUoKSB7CisgICAgICAgIHJldHVybiB0aGlzVXBkYXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIG5leHRVcGRhdGUgZmllbGQgb2YgdGhlIHN0cnVjdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0ZSBnZXROZXh0VXBkYXRlKCkgeworICAgICAgICByZXR1cm4gbmV4dFVwZGF0ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiByZXZva2VkQ2VydGlmaWNhdGVzIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUuCisgICAgICovCisgICAgcHVibGljIExpc3Q8UmV2b2tlZENlcnRpZmljYXRlPiBnZXRSZXZva2VkQ2VydGlmaWNhdGVzKCkgeworICAgICAgICByZXR1cm4gcmV2b2tlZENlcnRpZmljYXRlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBjcmxFeHRlbnNpb25zIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUuCisgICAgICovCisgICAgcHVibGljIEV4dGVuc2lvbnMgZ2V0Q3JsRXh0ZW5zaW9ucygpIHsKKyAgICAgICAgcmV0dXJuIGNybEV4dGVuc2lvbnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBlbmNvZGVkIGZvcm0gb2YgdGhpcyBYLjUwOSBUQlNDZXJ0TGlzdCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgeworICAgICAgICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFRCU0NlcnRMaXN0KSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIFRCU0NlcnRMaXN0IHRoYXQgPSAoVEJTQ2VydExpc3QpIG90aGVyOworICAgICAgICByZXR1cm4gdmVyc2lvbiA9PSB0aGF0LnZlcnNpb24KKyAgICAgICAgICAgICYmIHNpZ25hdHVyZS5lcXVhbHModGhhdC5zaWduYXR1cmUpCisgICAgICAgICAgICAmJiBBcnJheXMuZXF1YWxzKGlzc3Vlci5nZXRFbmNvZGVkKCksIHRoYXQuaXNzdWVyLmdldEVuY29kZWQoKSkKKyAgICAgICAgICAgICYmIHRoaXNVcGRhdGUuZ2V0VGltZSgpIC8gMTAwMAorICAgICAgICAgICAgICAgICAgICA9PSB0aGF0LnRoaXNVcGRhdGUuZ2V0VGltZSgpIC8gMTAwMAorICAgICAgICAgICAgJiYgKG5leHRVcGRhdGUgPT0gbnVsbAorICAgICAgICAgICAgICAgICAgICA/IHRoYXQubmV4dFVwZGF0ZSA9PSBudWxsCisgICAgICAgICAgICAgICAgICAgIDogbmV4dFVwZGF0ZS5nZXRUaW1lKCkgLyAxMDAwCisgICAgICAgICAgICAgICAgICAgICAgICA9PSB0aGF0Lm5leHRVcGRhdGUuZ2V0VGltZSgpIC8gMTAwMCkKKyAgICAgICAgICAgICYmICgocmV2b2tlZENlcnRpZmljYXRlcyA9PSBudWxsIHx8IHRoYXQucmV2b2tlZENlcnRpZmljYXRlcyA9PSBudWxsKQorICAgICAgICAgICAgICAgICYmIHJldm9rZWRDZXJ0aWZpY2F0ZXMgPT0gdGhhdC5yZXZva2VkQ2VydGlmaWNhdGVzCisgICAgICAgICAgICAgICAgfHwgcmV2b2tlZENlcnRpZmljYXRlcy5lcXVhbHModGhhdC5yZXZva2VkQ2VydGlmaWNhdGVzKSkKKyAgICAgICAgICAgICYmIChjcmxFeHRlbnNpb25zID09IG51bGwKKyAgICAgICAgICAgICAgICAgICAgPyB0aGF0LmNybEV4dGVuc2lvbnMgPT0gbnVsbAorICAgICAgICAgICAgICAgICAgICA6IGNybEV4dGVuc2lvbnMuZXF1YWxzKHRoYXQuY3JsRXh0ZW5zaW9ucykpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICByZXR1cm4gKCh2ZXJzaW9uICogMzcgKyBzaWduYXR1cmUuaGFzaENvZGUoKSkgKiAzNworICAgICAgICAgICAgICAgICsgQXJyYXlzLmhhc2hDb2RlKGlzc3Vlci5nZXRFbmNvZGVkKCkpKSAqIDM3CisgICAgICAgICAgICAgICAgKyAoaW50KXRoaXNVcGRhdGUuZ2V0VGltZSgpIC8gMTAwMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBkdW1wVmFsdWUoU3RyaW5nQnVpbGRlciBzYikgeworICAgICAgICBzYi5hcHBlbmQoIlguNTA5IENSTCB2IikuYXBwZW5kKHZlcnNpb24pOworICAgICAgICBzYi5hcHBlbmQoIlxuU2lnbmF0dXJlIEFsZ29yaXRobTogWyIpOworICAgICAgICBzaWduYXR1cmUuZHVtcFZhbHVlKHNiKTsKKyAgICAgICAgc2IuYXBwZW5kKCddJyk7CisgICAgICAgIHNiLmFwcGVuZCgiXG5Jc3N1ZXI6ICIpLmFwcGVuZChpc3N1ZXIuZ2V0TmFtZShYNTAwUHJpbmNpcGFsLlJGQzIyNTMpKTsKKyAgICAgICAgc2IuYXBwZW5kKCJcblxuVGhpcyBVcGRhdGU6ICIpLmFwcGVuZCh0aGlzVXBkYXRlKTsKKyAgICAgICAgc2IuYXBwZW5kKCJcbk5leHQgVXBkYXRlOiAiKS5hcHBlbmQobmV4dFVwZGF0ZSkuYXBwZW5kKCdcbicpOworICAgICAgICBpZiAocmV2b2tlZENlcnRpZmljYXRlcyAhPSBudWxsKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIlxuUmV2b2tlZCBDZXJ0aWZpY2F0ZXM6ICIpLmFwcGVuZChyZXZva2VkQ2VydGlmaWNhdGVzLnNpemUoKSkuYXBwZW5kKCIgWyIpOworICAgICAgICAgICAgaW50IG51bWJlciA9IDE7CisgICAgICAgICAgICBmb3IgKFJldm9rZWRDZXJ0aWZpY2F0ZSByZXZva2VkQ2VydGlmaWNhdGUgOiByZXZva2VkQ2VydGlmaWNhdGVzKSB7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCJcbiAgWyIpLmFwcGVuZChudW1iZXIrKykuYXBwZW5kKCddJyk7CisgICAgICAgICAgICAgICAgcmV2b2tlZENlcnRpZmljYXRlLmR1bXBWYWx1ZShzYiwgIiAgIik7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCdcbicpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2IuYXBwZW5kKCJdXG4iKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY3JsRXh0ZW5zaW9ucyAhPSBudWxsKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIlxuQ1JMIEV4dGVuc2lvbnM6ICIpLmFwcGVuZChjcmxFeHRlbnNpb25zLnNpemUoKSkuYXBwZW5kKCIgWyIpOworICAgICAgICAgICAgY3JsRXh0ZW5zaW9ucy5kdW1wVmFsdWUoc2IsICIgICIpOworICAgICAgICAgICAgc2IuYXBwZW5kKCJdXG4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFguNTA5IFRCU0NlcnRMaXN0IGVuY29kZXIvZGVjb2Rlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZShuZXcgQVNOMVR5cGVbXSB7CisgICAgICAgICAgICBBU04xSW50ZWdlci5nZXRJbnN0YW5jZSgpLCAvLyB2ZXJzaW9uCisgICAgICAgICAgICBBbGdvcml0aG1JZGVudGlmaWVyLkFTTjEsICAvLyBzaWduYXR1cmUKKyAgICAgICAgICAgIE5hbWUuQVNOMSwgLy8gaXNzdWVyCisgICAgICAgICAgICBUaW1lLkFTTjEsIC8vIHRoaXNVcGRhdGUKKyAgICAgICAgICAgIFRpbWUuQVNOMSwgLy8gbmV4dFVwZGF0ZQorICAgICAgICAgICAgbmV3IEFTTjFTZXF1ZW5jZU9mKFJldm9rZWRDZXJ0aWZpY2F0ZS5BU04xKSwgLy8gcmV2b2tlZENlcnRpZmljYXRlcworICAgICAgICAgICAgbmV3IEFTTjFFeHBsaWNpdCgwLCBFeHRlbnNpb25zLkFTTjEpIC8vIGNybEV4dGVuc2lvbnMKKyAgICAgICAgICAgICAgICB9KSB7CisgICAgICAgIHsKKyAgICAgICAgICAgIHNldE9wdGlvbmFsKDApOworICAgICAgICAgICAgc2V0T3B0aW9uYWwoNCk7CisgICAgICAgICAgICBzZXRPcHRpb25hbCg1KTsKKyAgICAgICAgICAgIHNldE9wdGlvbmFsKDYpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIE9iamVjdFtdIHZhbHVlcyA9IChPYmplY3RbXSkgaW4uY29udGVudDsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVEJTQ2VydExpc3QoCisgICAgICAgICAgICAgICAgICAgICAgICAodmFsdWVzWzBdID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAxCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBBU04xSW50ZWdlci50b0ludFZhbHVlKHZhbHVlc1swXSkrMSwKKyAgICAgICAgICAgICAgICAgICAgICAgIChBbGdvcml0aG1JZGVudGlmaWVyKSB2YWx1ZXNbMV0sCisgICAgICAgICAgICAgICAgICAgICAgICAoTmFtZSkgdmFsdWVzWzJdLAorICAgICAgICAgICAgICAgICAgICAgICAgKERhdGUpIHZhbHVlc1szXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIChEYXRlKSB2YWx1ZXNbNF0sCisgICAgICAgICAgICAgICAgICAgICAgICAoTGlzdDxSZXZva2VkQ2VydGlmaWNhdGU+KSB2YWx1ZXNbNV0sCisgICAgICAgICAgICAgICAgICAgICAgICAoRXh0ZW5zaW9ucykgdmFsdWVzWzZdLAorICAgICAgICAgICAgICAgICAgICAgICAgaW4uZ2V0RW5jb2RlZCgpCisgICAgICAgICAgICAgICAgICAgICk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZ2V0VmFsdWVzKE9iamVjdCBvYmplY3QsIE9iamVjdFtdIHZhbHVlcykgeworICAgICAgICAgICAgVEJTQ2VydExpc3QgdGJzID0gKFRCU0NlcnRMaXN0KSBvYmplY3Q7CisgICAgICAgICAgICB2YWx1ZXNbMF0gPSAodGJzLnZlcnNpb24gPiAxKQorICAgICAgICAgICAgICAgID8gQVNOMUludGVnZXIuZnJvbUludFZhbHVlKHRicy52ZXJzaW9uIC0gMSkgOiBudWxsOworICAgICAgICAgICAgdmFsdWVzWzFdID0gdGJzLnNpZ25hdHVyZTsKKyAgICAgICAgICAgIHZhbHVlc1syXSA9IHRicy5pc3N1ZXI7CisgICAgICAgICAgICB2YWx1ZXNbM10gPSB0YnMudGhpc1VwZGF0ZTsKKyAgICAgICAgICAgIHZhbHVlc1s0XSA9IHRicy5uZXh0VXBkYXRlOworICAgICAgICAgICAgdmFsdWVzWzVdID0gdGJzLnJldm9rZWRDZXJ0aWZpY2F0ZXM7CisgICAgICAgICAgICB2YWx1ZXNbNl0gPSB0YnMuY3JsRXh0ZW5zaW9uczsKKyAgICAgICAgfQorICAgIH07Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvVEJTQ2VydGlmaWNhdGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9UQlNDZXJ0aWZpY2F0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlkNjIyYzkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvVEJTQ2VydGlmaWNhdGUuamF2YQpAQCAtMCwwICsxLDI4NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5OworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUJpdFN0cmluZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xRXhwbGljaXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUltcGxpY2l0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFJbnRlZ2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXF1ZW5jZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CaXRTdHJpbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDEuTmFtZTsKKworLyoqCisgKiBUaGUgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBBU04uMSBERVIgZW5jb2RpbmcvZGVjb2Rpbmcgd29yaworICogd2l0aCBUQlNDZXJ0aWZpY2F0ZSBzdHJ1Y3R1cmUgd2hpY2ggaXMgdGhlIHBhcnQgb2YgWC41MDkgY2VydGlmaWNhdGUKKyAqIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODAgLQorICogIEludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUuCisgKiAgQ2VydGlmaWNhdGUgYW5kIENlcnRpZmljYXRlIFJldm9jYXRpb24gTGlzdCAoQ1JMKSBQcm9maWxlLgorICogIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KToKKyAqCisgKiA8cHJlPgorICogIFRCU0NlcnRpZmljYXRlICA6Oj0gIFNFUVVFTkNFICB7CisgKiAgICAgICB2ZXJzaW9uICAgICAgICAgWzBdICBFWFBMSUNJVCBWZXJzaW9uIERFRkFVTFQgdjEsCisgKiAgICAgICBzZXJpYWxOdW1iZXIgICAgICAgICBDZXJ0aWZpY2F0ZVNlcmlhbE51bWJlciwKKyAqICAgICAgIHNpZ25hdHVyZSAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIsCisgKiAgICAgICBpc3N1ZXIgICAgICAgICAgICAgICBOYW1lLAorICogICAgICAgdmFsaWRpdHkgICAgICAgICAgICAgVmFsaWRpdHksCisgKiAgICAgICBzdWJqZWN0ICAgICAgICAgICAgICBOYW1lLAorICogICAgICAgc3ViamVjdFB1YmxpY0tleUluZm8gU3ViamVjdFB1YmxpY0tleUluZm8sCisgKiAgICAgICBpc3N1ZXJVbmlxdWVJRCAgWzFdICBJTVBMSUNJVCBVbmlxdWVJZGVudGlmaWVyIE9QVElPTkFMLAorICogICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0gSWYgcHJlc2VudCwgdmVyc2lvbiBNVVNUIGJlIHYyIG9yIHYzCisgKiAgICAgICBzdWJqZWN0VW5pcXVlSUQgWzJdICBJTVBMSUNJVCBVbmlxdWVJZGVudGlmaWVyIE9QVElPTkFMLAorICogICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0gSWYgcHJlc2VudCwgdmVyc2lvbiBNVVNUIGJlIHYyIG9yIHYzCisgKiAgICAgICBleHRlbnNpb25zICAgICAgWzNdICBFWFBMSUNJVCBFeHRlbnNpb25zIE9QVElPTkFMCisgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLSBJZiBwcmVzZW50LCB2ZXJzaW9uIE1VU1QgYmUgdjMKKyAqICB9CisgKiA8L3ByZT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFRCU0NlcnRpZmljYXRlIHsKKworICAgIC8qKiB0aGUgdmFsdWUgb2YgdmVyc2lvbiBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmVyc2lvbjsKKyAgICAvKiogdGhlIHZhbHVlIG9mIHNlcmlhbE51bWJlciBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIHNlcmlhbE51bWJlcjsKKyAgICAvKiogdGhlIHZhbHVlIG9mIHNpZ25hdHVyZSBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBmaW5hbCBBbGdvcml0aG1JZGVudGlmaWVyIHNpZ25hdHVyZTsKKyAgICAvKiogdGhlIHZhbHVlIG9mIGlzc3VlciBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBmaW5hbCBOYW1lIGlzc3VlcjsKKyAgICAvKiogdGhlIHZhbHVlIG9mIHZhbGlkaXR5IGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIFZhbGlkaXR5IHZhbGlkaXR5OworICAgIC8qKiB0aGUgdmFsdWUgb2Ygc3ViamVjdCBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBmaW5hbCBOYW1lIHN1YmplY3Q7CisgICAgLyoqIHRoZSB2YWx1ZSBvZiBzdWJqZWN0UHVibGljS2V5SW5mbyBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBmaW5hbCBTdWJqZWN0UHVibGljS2V5SW5mbyBzdWJqZWN0UHVibGljS2V5SW5mbzsKKyAgICAvKiogdGhlIHZhbHVlIG9mIGlzc3VlclVuaXF1ZUlEIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW5bXSBpc3N1ZXJVbmlxdWVJRDsKKyAgICAvKiogdGhlIHZhbHVlIG9mIHN1YmplY3RVbmlxdWVJRCBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuW10gc3ViamVjdFVuaXF1ZUlEOworICAgIC8qKiB0aGUgdmFsdWUgb2YgZXh0ZW5zaW9ucyBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBmaW5hbCBFeHRlbnNpb25zIGV4dGVuc2lvbnM7CisgICAgLyoqIHRoZSBBU04uMSBlbmNvZGVkIGZvcm0gb2YgVEJTQ2VydGlmaWNhdGUgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGluZzsKKworICAgIHB1YmxpYyBUQlNDZXJ0aWZpY2F0ZShpbnQgdmVyc2lvbiwgQmlnSW50ZWdlciBzZXJpYWxOdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIgc2lnbmF0dXJlLCBOYW1lIGlzc3VlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsaWRpdHkgdmFsaWRpdHksIE5hbWUgc3ViamVjdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgU3ViamVjdFB1YmxpY0tleUluZm8gc3ViamVjdFB1YmxpY0tleUluZm8sCisgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW5bXSBpc3N1ZXJVbmlxdWVJRCwgYm9vbGVhbltdIHN1YmplY3RVbmlxdWVJRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9ucyBleHRlbnNpb25zKSB7CisgICAgICAgIHRoaXMudmVyc2lvbiA9IHZlcnNpb247CisgICAgICAgIHRoaXMuc2VyaWFsTnVtYmVyID0gc2VyaWFsTnVtYmVyOworICAgICAgICB0aGlzLnNpZ25hdHVyZSA9IHNpZ25hdHVyZTsKKyAgICAgICAgdGhpcy5pc3N1ZXIgPSBpc3N1ZXI7CisgICAgICAgIHRoaXMudmFsaWRpdHkgPSB2YWxpZGl0eTsKKyAgICAgICAgdGhpcy5zdWJqZWN0ID0gc3ViamVjdDsKKyAgICAgICAgdGhpcy5zdWJqZWN0UHVibGljS2V5SW5mbyA9IHN1YmplY3RQdWJsaWNLZXlJbmZvOworICAgICAgICB0aGlzLmlzc3VlclVuaXF1ZUlEID0gaXNzdWVyVW5pcXVlSUQ7CisgICAgICAgIHRoaXMuc3ViamVjdFVuaXF1ZUlEID0gc3ViamVjdFVuaXF1ZUlEOworICAgICAgICB0aGlzLmV4dGVuc2lvbnMgPSBleHRlbnNpb25zOworICAgIH0KKworICAgIHByaXZhdGUgVEJTQ2VydGlmaWNhdGUoaW50IHZlcnNpb24sIEJpZ0ludGVnZXIgc2VyaWFsTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICBBbGdvcml0aG1JZGVudGlmaWVyIHNpZ25hdHVyZSwgTmFtZSBpc3N1ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbGlkaXR5IHZhbGlkaXR5LCBOYW1lIHN1YmplY3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgIFN1YmplY3RQdWJsaWNLZXlJbmZvIHN1YmplY3RQdWJsaWNLZXlJbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuW10gaXNzdWVyVW5pcXVlSUQsIGJvb2xlYW5bXSBzdWJqZWN0VW5pcXVlSUQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvbnMgZXh0ZW5zaW9ucywgYnl0ZVtdIGVuY29kaW5nKSB7CisgICAgICAgIHRoaXModmVyc2lvbiwgc2VyaWFsTnVtYmVyLCBzaWduYXR1cmUsIGlzc3VlciwgdmFsaWRpdHksIHN1YmplY3QsCisgICAgICAgICAgICAgc3ViamVjdFB1YmxpY0tleUluZm8sIGlzc3VlclVuaXF1ZUlELCBzdWJqZWN0VW5pcXVlSUQsIGV4dGVuc2lvbnMpOworICAgICAgICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdmVyc2lvbiBmaWVsZCBvZiB0aGUgc3RydWN0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VmVyc2lvbigpIHsKKyAgICAgICAgcmV0dXJuIHZlcnNpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2Ygc2VyaWFsTnVtYmVyIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUuCisgICAgICovCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0U2VyaWFsTnVtYmVyKCkgeworICAgICAgICByZXR1cm4gc2VyaWFsTnVtYmVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHNpZ25hdHVyZSBmaWVsZCBvZiB0aGUgc3RydWN0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBBbGdvcml0aG1JZGVudGlmaWVyIGdldFNpZ25hdHVyZSgpIHsKKyAgICAgICAgcmV0dXJuIHNpZ25hdHVyZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBpc3N1ZXIgZmllbGQgb2YgdGhlIHN0cnVjdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTmFtZSBnZXRJc3N1ZXIoKSB7CisgICAgICAgIHJldHVybiBpc3N1ZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdmFsaWRpdHkgZmllbGQgb2YgdGhlIHN0cnVjdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVmFsaWRpdHkgZ2V0VmFsaWRpdHkoKSB7CisgICAgICAgIHJldHVybiB2YWxpZGl0eTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBzdWJqZWN0IGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUuCisgICAgICovCisgICAgcHVibGljIE5hbWUgZ2V0U3ViamVjdCgpIHsKKyAgICAgICAgcmV0dXJuIHN1YmplY3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2Ygc3ViamVjdFB1YmxpY0tleUluZm8gZmllbGQgb2YgdGhlIHN0cnVjdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3ViamVjdFB1YmxpY0tleUluZm8gZ2V0U3ViamVjdFB1YmxpY0tleUluZm8oKSB7CisgICAgICAgIHJldHVybiBzdWJqZWN0UHVibGljS2V5SW5mbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBpc3N1ZXJVbmlxdWVJRCBmaWVsZCBvZiB0aGUgc3RydWN0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuW10gZ2V0SXNzdWVyVW5pcXVlSUQoKSB7CisgICAgICAgIHJldHVybiBpc3N1ZXJVbmlxdWVJRDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBzdWJqZWN0VW5pcXVlSUQgZmllbGQgb2YgdGhlIHN0cnVjdHVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbltdIGdldFN1YmplY3RVbmlxdWVJRCgpIHsKKyAgICAgICAgcmV0dXJuIHN1YmplY3RVbmlxdWVJRDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBleHRlbnNpb25zIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUuCisgICAgICovCisgICAgcHVibGljIEV4dGVuc2lvbnMgZ2V0RXh0ZW5zaW9ucygpIHsKKyAgICAgICAgcmV0dXJuIGV4dGVuc2lvbnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBlbmNvZGVkIGZvcm0gb2YgdGhpcyBYLjUwOSBUQlNDZXJ0aWZpY2F0ZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBkdW1wVmFsdWUoU3RyaW5nQnVpbGRlciBzYikgeworICAgICAgICBzYi5hcHBlbmQoJ1snKTsKKyAgICAgICAgc2IuYXBwZW5kKCJcbiAgVmVyc2lvbjogViIpLmFwcGVuZCh2ZXJzaW9uKzEpOworICAgICAgICBzYi5hcHBlbmQoIlxuICBTdWJqZWN0OiAiKS5hcHBlbmQoc3ViamVjdC5nZXROYW1lKFg1MDBQcmluY2lwYWwuUkZDMjI1MykpOworICAgICAgICBzYi5hcHBlbmQoIlxuICBTaWduYXR1cmUgQWxnb3JpdGhtOiAiKTsKKyAgICAgICAgc2lnbmF0dXJlLmR1bXBWYWx1ZShzYik7CisgICAgICAgIHNiLmFwcGVuZCgiXG4gIEtleTogIikuYXBwZW5kKHN1YmplY3RQdWJsaWNLZXlJbmZvLmdldFB1YmxpY0tleSgpLnRvU3RyaW5nKCkpOworICAgICAgICBzYi5hcHBlbmQoIlxuICBWYWxpZGl0eTogW0Zyb206ICIpLmFwcGVuZCh2YWxpZGl0eS5nZXROb3RCZWZvcmUoKSk7CisgICAgICAgIHNiLmFwcGVuZCgiXG4gICAgICAgICAgICAgICBUbzogIikuYXBwZW5kKHZhbGlkaXR5LmdldE5vdEFmdGVyKCkpLmFwcGVuZCgnXScpOworICAgICAgICBzYi5hcHBlbmQoIlxuICBJc3N1ZXI6ICIpLmFwcGVuZChpc3N1ZXIuZ2V0TmFtZShYNTAwUHJpbmNpcGFsLlJGQzIyNTMpKTsKKyAgICAgICAgc2IuYXBwZW5kKCJcbiAgU2VyaWFsIE51bWJlcjogIikuYXBwZW5kKHNlcmlhbE51bWJlcik7CisgICAgICAgIGlmIChpc3N1ZXJVbmlxdWVJRCAhPSBudWxsKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIlxuICBJc3N1ZXIgSWQ6ICIpOworICAgICAgICAgICAgZm9yIChib29sZWFuIGIgOiBpc3N1ZXJVbmlxdWVJRCkgeworICAgICAgICAgICAgICAgIHNiLmFwcGVuZChiID8gJzEnIDogJzAnKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoc3ViamVjdFVuaXF1ZUlEICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiXG4gIFN1YmplY3QgSWQ6ICIpOworICAgICAgICAgICAgZm9yIChib29sZWFuIGIgOiBzdWJqZWN0VW5pcXVlSUQpIHsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoYiA/ICcxJyA6ICcwJyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGV4dGVuc2lvbnMgIT0gbnVsbCkgeworICAgICAgICAgICAgc2IuYXBwZW5kKCJcblxuICBFeHRlbnNpb25zOiAiKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiW1xuIik7CisgICAgICAgICAgICBleHRlbnNpb25zLmR1bXBWYWx1ZShzYiwgIiAgICAiKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgiICBdIik7CisgICAgICAgIH0KKyAgICAgICAgc2IuYXBwZW5kKCJcbl0iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBYLjUwOSBUQlNDZXJ0aWZpY2F0ZSBlbmNvZGVyL2RlY29kZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xU2VxdWVuY2UgQVNOMSA9IG5ldyBBU04xU2VxdWVuY2UobmV3IEFTTjFUeXBlW10geworICAgICAgICAgICAgbmV3IEFTTjFFeHBsaWNpdCgwLCBBU04xSW50ZWdlci5nZXRJbnN0YW5jZSgpKSwgQVNOMUludGVnZXIuZ2V0SW5zdGFuY2UoKSwKKyAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIuQVNOMSwgTmFtZS5BU04xLAorICAgICAgICAgICAgVmFsaWRpdHkuQVNOMSwgTmFtZS5BU04xLCBTdWJqZWN0UHVibGljS2V5SW5mby5BU04xLAorICAgICAgICAgICAgbmV3IEFTTjFJbXBsaWNpdCgxLCBBU04xQml0U3RyaW5nLmdldEluc3RhbmNlKCkpLAorICAgICAgICAgICAgbmV3IEFTTjFJbXBsaWNpdCgyLCBBU04xQml0U3RyaW5nLmdldEluc3RhbmNlKCkpLAorICAgICAgICAgICAgbmV3IEFTTjFFeHBsaWNpdCgzLCBFeHRlbnNpb25zLkFTTjEpfSkgeworICAgICAgICB7CisgICAgICAgICAgICBzZXREZWZhdWx0KG5ldyBieXRlW10gezB9LCAwKTsKKyAgICAgICAgICAgIHNldE9wdGlvbmFsKDcpOworICAgICAgICAgICAgc2V0T3B0aW9uYWwoOCk7CisgICAgICAgICAgICBzZXRPcHRpb25hbCg5KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgICAgIE9iamVjdFtdIHZhbHVlcyA9IChPYmplY3RbXSkgaW4uY29udGVudDsKKworICAgICAgICAgICAgYm9vbGVhbltdIGlzc3VlclVuaXF1ZUlEID0gKHZhbHVlc1s3XSA9PSBudWxsKQorICAgICAgICAgICAgICAgID8gbnVsbCA6ICgoQml0U3RyaW5nKSB2YWx1ZXNbN10pLnRvQm9vbGVhbkFycmF5KCk7CisgICAgICAgICAgICBib29sZWFuW10gc3ViamVjdFVuaXF1ZUlEID0gKHZhbHVlc1s4XSA9PSBudWxsKQorICAgICAgICAgICAgICAgID8gbnVsbCA6ICgoQml0U3RyaW5nKSB2YWx1ZXNbOF0pLnRvQm9vbGVhbkFycmF5KCk7CisgICAgICAgICAgICByZXR1cm4gbmV3IFRCU0NlcnRpZmljYXRlKAorICAgICAgICAgICAgICAgICAgICAgICAgQVNOMUludGVnZXIudG9JbnRWYWx1ZSh2YWx1ZXNbMF0pLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoKGJ5dGVbXSkgdmFsdWVzWzFdKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIChBbGdvcml0aG1JZGVudGlmaWVyKSB2YWx1ZXNbMl0sCisgICAgICAgICAgICAgICAgICAgICAgICAoTmFtZSkgdmFsdWVzWzNdLAorICAgICAgICAgICAgICAgICAgICAgICAgKFZhbGlkaXR5KSB2YWx1ZXNbNF0sCisgICAgICAgICAgICAgICAgICAgICAgICAoTmFtZSkgdmFsdWVzWzVdLAorICAgICAgICAgICAgICAgICAgICAgICAgKFN1YmplY3RQdWJsaWNLZXlJbmZvKSB2YWx1ZXNbNl0sCisgICAgICAgICAgICAgICAgICAgICAgICBpc3N1ZXJVbmlxdWVJRCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHN1YmplY3RVbmlxdWVJRCwKKyAgICAgICAgICAgICAgICAgICAgICAgIChFeHRlbnNpb25zKSB2YWx1ZXNbOV0sCisgICAgICAgICAgICAgICAgICAgICAgICBpbi5nZXRFbmNvZGVkKCkKKyAgICAgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCwgT2JqZWN0W10gdmFsdWVzKSB7CisgICAgICAgICAgICBUQlNDZXJ0aWZpY2F0ZSB0YnMgPSAoVEJTQ2VydGlmaWNhdGUpIG9iamVjdDsKKyAgICAgICAgICAgIHZhbHVlc1swXSA9IEFTTjFJbnRlZ2VyLmZyb21JbnRWYWx1ZSh0YnMudmVyc2lvbik7CisgICAgICAgICAgICB2YWx1ZXNbMV0gPSB0YnMuc2VyaWFsTnVtYmVyLnRvQnl0ZUFycmF5KCk7CisgICAgICAgICAgICB2YWx1ZXNbMl0gPSB0YnMuc2lnbmF0dXJlOworICAgICAgICAgICAgdmFsdWVzWzNdID0gdGJzLmlzc3VlcjsKKyAgICAgICAgICAgIHZhbHVlc1s0XSA9IHRicy52YWxpZGl0eTsKKyAgICAgICAgICAgIHZhbHVlc1s1XSA9IHRicy5zdWJqZWN0OworICAgICAgICAgICAgdmFsdWVzWzZdID0gdGJzLnN1YmplY3RQdWJsaWNLZXlJbmZvOworICAgICAgICAgICAgaWYgKHRicy5pc3N1ZXJVbmlxdWVJRCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdmFsdWVzWzddID0gbmV3IEJpdFN0cmluZyh0YnMuaXNzdWVyVW5pcXVlSUQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHRicy5zdWJqZWN0VW5pcXVlSUQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHZhbHVlc1s4XSA9IG5ldyBCaXRTdHJpbmcodGJzLnN1YmplY3RVbmlxdWVJRCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB2YWx1ZXNbOV0gPSB0YnMuZXh0ZW5zaW9uczsKKyAgICAgICAgfQorICAgIH07Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvVGltZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L1RpbWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NTc2YWMzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L1RpbWUuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xQ2hvaWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFHZW5lcmFsaXplZFRpbWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVR5cGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVVUQ1RpbWU7CisKKy8qKgorICogQ2xhc3MgcmVwcmVzZW50cyB0aGUgd29yayB3aXRoIHRoZSBmb2xsb3dpbmcgWC41MDkgc3RydWN0dXJlOgorICogKGFzIHNwZWNpZmllZCBpbiBSRkMgMzI4MCAtCisgKiAgSW50ZXJuZXQgWC41MDkgUHVibGljIEtleSBJbmZyYXN0cnVjdHVyZS4KKyAqICBDZXJ0aWZpY2F0ZSBhbmQgQ2VydGlmaWNhdGUgUmV2b2NhdGlvbiBMaXN0IChDUkwpIFByb2ZpbGUuCisgKiAgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI4MC50eHQpOgorICoKKyAqIDxwcmU+CisgKiBUaW1lIDo6PSBDSE9JQ0UgeworICogICAgICAgdXRjVGltZSAgICAgICAgVVRDVGltZSwKKyAqICAgICAgIGdlbmVyYWxUaW1lICAgIEdlbmVyYWxpemVkVGltZQorICogfQorICogPC9wcmU+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBUaW1lIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIEpBTl8wMV8yMDUwID0gMjUyNDYwODAwMDAwMEw7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFDaG9pY2UgQVNOMSA9IG5ldyBBU04xQ2hvaWNlKG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgIEFTTjFHZW5lcmFsaXplZFRpbWUuZ2V0SW5zdGFuY2UoKSwgQVNOMVVUQ1RpbWUuZ2V0SW5zdGFuY2UoKSB9KSB7CisKKyAgICAgICAgcHVibGljIGludCBnZXRJbmRleChqYXZhLmxhbmcuT2JqZWN0IG9iamVjdCkgeworICAgICAgICAgICAgLy8gY2hvb3NlIGVuY29kaW5nIG1ldGhvZCAoc2VlIFJGQyAzMjgwIHAuIDIyKQorICAgICAgICAgICAgaWYgKCgoamF2YS51dGlsLkRhdGUpIG9iamVjdCkuZ2V0VGltZSgpIDwgSkFOXzAxXzIwNTApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMTsgLy8gaXQgaXMgYmVmb3JlIDIwNTAsIHNvIGVuY29kZSBhcyBVVENUaW1lCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiAwOyAvLyBpdCBpcyBhZnRlciAyMDUwLCBlbmNvZGUgYXMgR2VuZXJhbGl6ZWRUaW1lCisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IGdldE9iamVjdFRvRW5jb2RlKE9iamVjdCBvYmplY3QpIHsKKyAgICAgICAgICAgIHJldHVybiBvYmplY3Q7CisgICAgICAgIH0KKyAgICB9OworfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvVmFsaWRpdHkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9WYWxpZGl0eS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcwODk3OWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvVmFsaWRpdHkuamF2YQpAQCAtMCwwICsxLDk5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDk7CisKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xU2VxdWVuY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVR5cGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQmVySW5wdXRTdHJlYW07CisKKy8qKgorICogVGhlIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgQVNOLjEgREVSIGVuY29kaW5nL2RlY29kaW5nIHdvcmsKKyAqIHdpdGggVmFsaWRpdHkgc3RydWN0dXJlIHdoaWNoIGlzIHRoZSBwYXJ0IG9mIFguNTA5IGNlcnRpZmljYXRlCisgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIC0KKyAqICBJbnRlcm5ldCBYLjUwOSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgorICogIENlcnRpZmljYXRlIGFuZCBDZXJ0aWZpY2F0ZSBSZXZvY2F0aW9uIExpc3QgKENSTCkgUHJvZmlsZS4KKyAqICBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCk6CisgKgorICogPHByZT4KKyAqICBWYWxpZGl0eSA6Oj0gU0VRVUVOQ0UgeworICogICAgICAgbm90QmVmb3JlICAgICAgVGltZSwKKyAqICAgICAgIG5vdEFmdGVyICAgICAgIFRpbWUKKyAqICB9CisgKiA8L3ByZT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFZhbGlkaXR5IHsKKyAgICAvKiogdGhlIHZhbHVlIG9mIG5vdEJlZm9yZSBmaWVsZCBvZiB0aGUgc3RydWN0dXJlICovCisgICAgcHJpdmF0ZSBmaW5hbCBEYXRlIG5vdEJlZm9yZTsKKyAgICAvKiogdGhlIHZhbHVlIG9mIG5vdEFmdGVyIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICBwcml2YXRlIGZpbmFsIERhdGUgbm90QWZ0ZXI7CisgICAgLyoqIHRoZSBBU04uMSBlbmNvZGVkIGZvcm0gb2YgVmFsaWRpdHkgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGluZzsKKworICAgIHB1YmxpYyBWYWxpZGl0eShEYXRlIG5vdEJlZm9yZSwgRGF0ZSBub3RBZnRlcikgeworICAgICAgICB0aGlzLm5vdEJlZm9yZSA9IG5vdEJlZm9yZTsKKyAgICAgICAgdGhpcy5ub3RBZnRlciA9IG5vdEFmdGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIG5vdEJlZm9yZSBmaWVsZCBvZiB0aGUgc3RydWN0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBEYXRlIGdldE5vdEJlZm9yZSgpIHsKKyAgICAgICAgcmV0dXJuIG5vdEJlZm9yZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBub3RBZnRlciBmaWVsZCBvZiB0aGUgc3RydWN0dXJlLgorICAgICAqLworICAgIHB1YmxpYyBEYXRlIGdldE5vdEFmdGVyKCkgeworICAgICAgICByZXR1cm4gbm90QWZ0ZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBBU04uMSBlbmNvZGVkIGZvcm0gb2YgdGhpcyBYLjUwOSBWYWxpZGl0eSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBU04uMSBERVIgWC41MDkgVmFsaWRpdHkgZW5jb2Rlci9kZWNvZGVyIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVNlcXVlbmNlIEFTTjEKKyAgICAgICAgPSBuZXcgQVNOMVNlcXVlbmNlKG5ldyBBU04xVHlwZVtdIHtUaW1lLkFTTjEsIFRpbWUuQVNOMSB9KSB7CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgT2JqZWN0W10gdmFsdWVzID0gKE9iamVjdFtdKSBpbi5jb250ZW50OworICAgICAgICAgICAgcmV0dXJuIG5ldyBWYWxpZGl0eSgoRGF0ZSkgdmFsdWVzWzBdLCAoRGF0ZSkgdmFsdWVzWzFdKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCwgT2JqZWN0W10gdmFsdWVzKSB7CisgICAgICAgICAgICBWYWxpZGl0eSB2YWxpZGl0eSA9IChWYWxpZGl0eSkgb2JqZWN0OworICAgICAgICAgICAgdmFsdWVzWzBdID0gdmFsaWRpdHkubm90QmVmb3JlOworICAgICAgICAgICAgdmFsdWVzWzFdID0gdmFsaWRpdHkubm90QWZ0ZXI7CisgICAgICAgIH0KKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L1g1MDlQdWJsaWNLZXkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9YNTA5UHVibGljS2V5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjA4YmQ4YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS9YNTA5UHVibGljS2V5LmphdmEKQEAgLTAsMCArMSw1NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworCitwdWJsaWMgZmluYWwgY2xhc3MgWDUwOVB1YmxpY0tleSBpbXBsZW1lbnRzIFB1YmxpY0tleSB7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgYWxnb3JpdGhtOworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGVuY29kZWQ7CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10ga2V5Qnl0ZXM7CisKKyAgICBwdWJsaWMgWDUwOVB1YmxpY0tleShTdHJpbmcgYWxnb3JpdGhtLCBieXRlW10gZW5jb2RlZCwgYnl0ZVtdIGtleUJ5dGVzKSB7CisgICAgICAgIHRoaXMuYWxnb3JpdGhtID0gYWxnb3JpdGhtOworICAgICAgICB0aGlzLmVuY29kZWQgPSBlbmNvZGVkOworICAgICAgICB0aGlzLmtleUJ5dGVzID0ga2V5Qnl0ZXM7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiBhbGdvcml0aG07CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRGb3JtYXQoKSB7CisgICAgICAgIHJldHVybiAiWC41MDkiOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgcmV0dXJuIGVuY29kZWQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigiYWxnb3JpdGhtID0gIik7CisgICAgICAgIGJ1Zi5hcHBlbmQoYWxnb3JpdGhtKTsKKyAgICAgICAgYnVmLmFwcGVuZCgiLCBwYXJhbXMgdW5wYXJzZWQsIHVucGFyc2VkIGtleWJpdHMgPSBcbiIpOworICAgICAgICAvLyBUT0RPOiBpbXBsZW1lbnQgY29tcGF0aWJsZSB0b1N0cmluZyBtZXRob2QoKQorICAgICAgICAvLyBidWYuYXBwZW5kKEFycmF5cy50b1N0cmluZyhrZXlCeXRlcykpOworICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L3RzcC9NZXNzYWdlSW1wcmludC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L3RzcC9NZXNzYWdlSW1wcmludC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc4OWZkY2YKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvdHNwL01lc3NhZ2VJbXByaW50LmphdmEKQEAgLTAsMCArMSw2NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS50c3A7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xT2N0ZXRTdHJpbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LkFsZ29yaXRobUlkZW50aWZpZXI7CisKKy8qKgorICogQXMgZGVmaW5lZCBpbiBUaW1lLVN0YW1wIFByb3RvY29sIChUU1ApCisgKiAoaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzE2MS50eHQpCisgKgorICogTWVzc2FnZUltcHJpbnQgOjo9IFNFUVVFTkNFICB7CisgKiAgICAgIGhhc2hBbGdvcml0aG0gICAgICAgICAgICAgICAgQWxnb3JpdGhtSWRlbnRpZmllciwKKyAqICAgICAgaGFzaGVkTWVzc2FnZSAgICAgICAgICAgICAgICBPQ1RFVCBTVFJJTkcKKyAqIH0KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBNZXNzYWdlSW1wcmludCB7CisgICAgcHJpdmF0ZSBmaW5hbCBBbGdvcml0aG1JZGVudGlmaWVyIGFsZ0lkOworICAgIHByaXZhdGUgZmluYWwgYnl0ZSBbXSBoYXNoZWRNZXNzYWdlOworCisgICAgcHVibGljIE1lc3NhZ2VJbXByaW50KEFsZ29yaXRobUlkZW50aWZpZXIgYWxnSWQsIGJ5dGUgW10gaGFzaGVkTWVzc2FnZSl7CisgICAgICAgIHRoaXMuYWxnSWQgPSBhbGdJZDsKKyAgICAgICAgdGhpcy5oYXNoZWRNZXNzYWdlID0gaGFzaGVkTWVzc2FnZTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZShuZXcgQVNOMVR5cGVbXSB7CisgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIuQVNOMSwKKyAgICAgICAgQVNOMU9jdGV0U3RyaW5nLmdldEluc3RhbmNlKCl9KSB7CisKKyAgICAgICAgcHJvdGVjdGVkIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB7CisgICAgICAgICAgICBPYmplY3RbXSB2YWx1ZXMgPSAoT2JqZWN0W10pIGluLmNvbnRlbnQ7CisgICAgICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VJbXByaW50KAorICAgICAgICAgICAgICAgICAgICAoQWxnb3JpdGhtSWRlbnRpZmllcil2YWx1ZXNbMF0sCisgICAgICAgICAgICAgICAgICAgIChieXRlW10pdmFsdWVzWzFdKTsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKyAgICAgICAgICAgIE1lc3NhZ2VJbXByaW50IG1pID0gKE1lc3NhZ2VJbXByaW50KSBvYmplY3Q7CisgICAgICAgICAgICB2YWx1ZXNbMF0gPSBtaS5hbGdJZDsKKyAgICAgICAgICAgIHZhbHVlc1sxXSA9IG1pLmhhc2hlZE1lc3NhZ2U7CisgICAgICAgIH0KKyAgICB9OworfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvdHNwL1BLSUZhaWx1cmVJbmZvLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvdHNwL1BLSUZhaWx1cmVJbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2E0NDg5YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS90c3AvUEtJRmFpbHVyZUluZm8uamF2YQpAQCAtMCwwICsxLDEzNiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS50c3A7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247CisKKy8qKgorICAgQ29ycmVzcG9uZHMgdG8gUEtJRmFpbHVyZUluZm8gc3RydWN0dXJlLgorICAgU2VlIFJGQyAzMTYxIC0KKyAgIEludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUKKyAgIFRpbWUtU3RhbXAgUHJvdG9jb2wgKFRTUCkKKyAgIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMxNjEudHh0KQorCisgICBQS0lGYWlsdXJlSW5mbyA6Oj0gQklUIFNUUklORyB7CisgICBiYWRBbGcgICAgICAgICAgICAgICAoMCksCisgICAgIC0tIHVucmVjb2duaXplZCBvciB1bnN1cHBvcnRlZCBBbGdvcml0aG0gSWRlbnRpZmllcgorICAgYmFkUmVxdWVzdCAgICAgICAgICAgKDIpLAorICAgICAtLSB0cmFuc2FjdGlvbiBub3QgcGVybWl0dGVkIG9yIHN1cHBvcnRlZAorICAgYmFkRGF0YUZvcm1hdCAgICAgICAgKDUpLAorICAgICAtLSB0aGUgZGF0YSBzdWJtaXR0ZWQgaGFzIHRoZSB3cm9uZyBmb3JtYXQKKyAgIHRpbWVOb3RBdmFpbGFibGUgICAgKDE0KSwKKyAgICAgLS0gdGhlIFRTQSdzIHRpbWUgc291cmNlIGlzIG5vdCBhdmFpbGFibGUKKyAgIHVuYWNjZXB0ZWRQb2xpY3kgICAgKDE1KSwKKyAgICAgLS0gdGhlIHJlcXVlc3RlZCBUU0EgcG9saWN5IGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIFRTQQorICAgdW5hY2NlcHRlZEV4dGVuc2lvbiAoMTYpLAorICAgICAtLSB0aGUgcmVxdWVzdGVkIGV4dGVuc2lvbiBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBUU0EKKyAgICBhZGRJbmZvTm90QXZhaWxhYmxlICgxNykKKyAgICAgIC0tIHRoZSBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlcXVlc3RlZCBjb3VsZCBub3QgYmUgdW5kZXJzdG9vZAorICAgICAgLS0gb3IgaXMgbm90IGF2YWlsYWJsZQorICAgIHN5c3RlbUZhaWx1cmUgICAgICAgKDI1KQorICAgICAgLS0gdGhlIHJlcXVlc3QgY2Fubm90IGJlIGhhbmRsZWQgZHVlIHRvIHN5c3RlbSBmYWlsdXJlICB9CisKKyAgICBUaGUgdmFsdWUgb2YgUEtJRmFpbHVyZUluZm8gY2FuIHRha2Ugb25seSBvbmUgb2YgdGhlIHZhbHVlcywKKyAgICBzbyBpdCBpcyByZXByZXNlbnRlZCBieSBhbiBpbnRlZ2VyIGhlcmUuCisgKi8KK3B1YmxpYyBlbnVtIFBLSUZhaWx1cmVJbmZvIHsKKyAgICAvKioKKyAgICAgKiAgVW5yZWNvZ25pemVkIGFsZ29yaXRobSBJRAorICAgICAqLworICAgIEJBRF9BTEcoMCksCisKKyAgICAvKioKKyAgICAgKiAgVHJhbnNhY3Rpb24gaXMgbm90IHN1cHBvcnRlZAorICAgICAqLworICAgIEJBRF9SRVFVRVNUKDIpLAorCisgICAgLyoqCisgICAgICogIERhdGEgZm9ybWF0IGlzIHdyb25nCisgICAgICovCisgICAgQkFEX0RBVEFfRk9STUFUKDUpLAorCisgICAgLyoqCisgICAgICogIFRTQSBjYW5ub3QgdXNlIHRoZSB0aW1lIHNvdXJjZQorICAgICAqLworICAgIFRJTUVfTk9UX0FWQUlMQUJMRSgxNCksCisKKyAgICAvKioKKyAgICAgKiAgVGhlIHBvbGljeSBpcyBub3Qgc3VwcG9ydGVkCisgICAgICovCisgICAgVU5BQ0NFUFRFRF9QT0xJQ1koMTUpLAorCisgICAgLyoqCisgICAgICogIFRoZSBleHRlbnNpb24gaXMgbm90IHN1cHBvcnRlZAorICAgICAqLworICAgIFVOQUNDRVBURURfRVhURU5TSU9OKDE2KSwKKworICAgIC8qKgorICAgICAqICBUaGUgcmVxdWVzdGVkIGFkZGl0aW9uYWwgaW5mbyBpcyBub3QgYXZhaWxhYmxlCisgICAgICovCisgICAgQUREX0lORk9fTk9UX0FWQUlMQUJMRSgxNyksCisKKyAgICAvKioKKyAgICAgKiAgU3lzdGVtIGZhaWx1cmUgaGFzIG9jY3VyZWQKKyAgICAgKi8KKyAgICBTWVNURU1fRkFJTFVSRSgyNSk7CisKKworICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOworCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IG1heFZhbHVlOworCisgICAgUEtJRmFpbHVyZUluZm8oaW50IHZhbHVlKSB7CisgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIGludCB2YWx1ZSBvZiB0aGUgZmFpbHVyZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VmFsdWUoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIG1heGltdW0gb2YgdmFsdWVzIGluIHRoZSBlbnVtCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZ2V0TWF4VmFsdWUoKSB7CisgICAgICAgIGlmIChtYXhWYWx1ZSA9PSAwKSB7CisgICAgICAgICAgICBmb3IgKFBLSUZhaWx1cmVJbmZvIGN1ciA6IHZhbHVlcygpKQorICAgICAgICAgICAgICAgIGlmIChjdXIudmFsdWUgPiBtYXhWYWx1ZSkgeworICAgICAgICAgICAgICAgICAgICBtYXhWYWx1ZSA9IGN1ci52YWx1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG1heFZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFBLSUZhaWx1cmVJbmZvIGdldEluc3RhbmNlKGludCB2YWx1ZSkgeworICAgICAgICBmb3IgKFBLSUZhaWx1cmVJbmZvIGluZm8gOiB2YWx1ZXMoKSl7CisgICAgICAgICAgICBpZiAodmFsdWUgPT0gaW5mby52YWx1ZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBpbmZvOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKCJVbmtub3duIFBLSUZhaWx1cmVJbmZvIHZhbHVlIik7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3g1MDkvdHNwL1BLSVN0YXR1cy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L3RzcC9QS0lTdGF0dXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOTdiM2EzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L3RzcC9QS0lTdGF0dXMuamF2YQpAQCAtMCwwICsxLDkzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LnRzcDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbjsKKworLyoqCisgICBDb3JyZXNwb25kcyB0byBQS0lTdGF0dXMgc3RydWN0dXJlLgorICAgU2VlIFJGQyAzMTYxIC0KKyAgIEludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUKKyAgIFRpbWUtU3RhbXAgUHJvdG9jb2wgKFRTUCkKKyAgIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMxNjEudHh0KQorCisgICBQS0lTdGF0dXMgOjo9IElOVEVHRVIgeworICAgICAgZ3JhbnRlZCAgICAgICAgICAgICAgICAoMCksCisgICAgICAtLSB3aGVuIHRoZSBQS0lTdGF0dXMgY29udGFpbnMgdGhlIHZhbHVlIHplcm8gYSBUaW1lU3RhbXBUb2tlbiwgYXMKKyAgICAgICAgIHJlcXVlc3RlZCwgaXMgcHJlc2VudC4KKyAgICAgIGdyYW50ZWRXaXRoTW9kcyAgICAgICAgKDEpLAorICAgICAgIC0tIHdoZW4gdGhlIFBLSVN0YXR1cyBjb250YWlucyB0aGUgdmFsdWUgb25lIGEgVGltZVN0YW1wVG9rZW4sCisgICAgICAgICB3aXRoIG1vZGlmaWNhdGlvbnMsIGlzIHByZXNlbnQuCisgICAgICByZWplY3Rpb24gICAgICAgICAgICAgICgyKSwKKyAgICAgIHdhaXRpbmcgICAgICAgICAgICAgICAgKDMpLAorICAgICAgcmV2b2NhdGlvbldhcm5pbmcgICAgICAoNCksCisgICAgICAgLS0gdGhpcyBtZXNzYWdlIGNvbnRhaW5zIGEgd2FybmluZyB0aGF0IGEgcmV2b2NhdGlvbiBpcworICAgICAgIC0tIGltbWluZW50CisgICAgICByZXZvY2F0aW9uTm90aWZpY2F0aW9uICg1KQorICAgICAgIC0tIG5vdGlmaWNhdGlvbiB0aGF0IGEgcmV2b2NhdGlvbiBoYXMgb2NjdXJyZWQgIH0KKyAqLworcHVibGljIGVudW0gUEtJU3RhdHVzIHsKKyAgICAvKioKKyAgICAgKiBUaW1lU3RhbXBUb2tlbiBpcyBwcmVzZW50IGFzIHJlcXVlc3RlZAorICAgICAqLworICAgIEdSQU5URUQoMCksCisgICAgLyoqCisgICAgICogVGltZVN0YW1wVG9rZW4gaXMgcHJlc2VudCB3aXRoIG1vZGlmaWNhdGlvbnMKKyAgICAgKi8KKyAgICBHUkFOVEVEX1dJVEhfTU9EUygxKSwKKyAgICAvKioKKyAgICAgKiByZWplY3RlZAorICAgICAqLworICAgIFJFSkVDVElPTigyKSwKKyAgICAvKioKKyAgICAgKiB3YWl0aW5nCisgICAgICovCisgICAgV0FJVElORygzKSwKKyAgICAvKioKKyAgICAgKiByZXZvY2F0aW9uIHRpbWUgY29tZXMgc29vbgorICAgICAqLworICAgIFJFVk9DQVRJT05fV0FSTklORyg0KSwKKyAgICAvKioKKyAgICAgKiByZXZva2VkCisgICAgICovCisgICAgUkVWT0NBVElPTl9OT1RJRklDQVRJT04oNSk7CisKKyAgICBwcml2YXRlIGZpbmFsIGludCBzdGF0dXM7CisgICAgUEtJU3RhdHVzKGludCBzdGF0dXMpIHsKKyAgICAgICAgdGhpcy5zdGF0dXMgPSBzdGF0dXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiBpbnQgdmFsdWUgb2YgdGhlIHN0YXR1cworICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U3RhdHVzKCl7CisgICAgICAgIHJldHVybiBzdGF0dXM7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBQS0lTdGF0dXMgZ2V0SW5zdGFuY2UoaW50IHN0YXR1cykgeworICAgICAgICBmb3IgKFBLSVN0YXR1cyBjdXJTdGF0dXMgOiB2YWx1ZXMoKSkgeworICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSBjdXJTdGF0dXMuc3RhdHVzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGN1clN0YXR1czsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbigiVW5rbm93biBQS0lTdGF0dXMgdmFsdWUiKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS90c3AvUEtJU3RhdHVzSW5mby5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L3RzcC9QS0lTdGF0dXNJbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmM3MDE0MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS90c3AvUEtJU3RhdHVzSW5mby5qYXZhCkBAIC0wLDAgKzEsMTM5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LnRzcDsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFCaXRTdHJpbmc7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUludGVnZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXF1ZW5jZU9mOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTdHJpbmdUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJpdFN0cmluZzsKKworCisvKioKKyAqIEFzIGRlZmluZWQgaW4gVGltZS1TdGFtcCBQcm90b2NvbCAoVFNQKQorICogKGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMxNjEudHh0KQorICoKKyAqIFBLSVN0YXR1c0luZm8gOjo9IFNFUVVFTkNFIHsKKyAqICAgIHN0YXR1cyBQS0lTdGF0dXMsCisgKiAgICBzdGF0dXNTdHJpbmcgUEtJRnJlZVRleHQgT1BUSU9OQUwsCisgKiAgICBmYWlsSW5mbyBQS0lGYWlsdXJlSW5mbyBPUFRJT05BTAorICogfQorICoKKyAqLworcHVibGljIGNsYXNzIFBLSVN0YXR1c0luZm8geworCisgICAgcHJpdmF0ZSBmaW5hbCBQS0lTdGF0dXMgc3RhdHVzOworCisgICAgcHJpdmF0ZSBmaW5hbCBMaXN0IHN0YXR1c1N0cmluZzsKKworICAgIHByaXZhdGUgZmluYWwgUEtJRmFpbHVyZUluZm8gZmFpbEluZm87CisKKyAgICBwdWJsaWMgUEtJU3RhdHVzSW5mbyhQS0lTdGF0dXMgcEtJU3RhdHVzLCBMaXN0IHN0YXR1c1N0cmluZywKKyAgICAgICAgICAgIFBLSUZhaWx1cmVJbmZvIGZhaWxJbmZvKSB7CisgICAgICAgIHRoaXMuc3RhdHVzID0gcEtJU3RhdHVzOworICAgICAgICB0aGlzLnN0YXR1c1N0cmluZyA9IHN0YXR1c1N0cmluZzsKKyAgICAgICAgdGhpcy5mYWlsSW5mbyA9IGZhaWxJbmZvOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKXsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXMgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICByZXMuYXBwZW5kKCItLSBQS0lTdGF0dXNJbmZvOiIpOworICAgICAgICByZXMuYXBwZW5kKCJcblBLSVN0YXR1cyA6ICIpOworICAgICAgICByZXMuYXBwZW5kKHN0YXR1cyk7CisgICAgICAgIHJlcy5hcHBlbmQoIlxuc3RhdHVzU3RyaW5nOiAgIik7CisgICAgICAgIHJlcy5hcHBlbmQoc3RhdHVzU3RyaW5nKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG5mYWlsSW5mbzogICIpOworICAgICAgICByZXMuYXBwZW5kKGZhaWxJbmZvKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG4tLSBQS0lTdGF0dXNJbmZvIEVuZFxuIik7CisgICAgICAgIHJldHVybiByZXMudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGZhaWxJbmZvLgorICAgICAqLworICAgIHB1YmxpYyBQS0lGYWlsdXJlSW5mbyBnZXRGYWlsSW5mbygpIHsKKyAgICAgICAgcmV0dXJuIGZhaWxJbmZvOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgcEtJU3RhdHVzLgorICAgICAqLworICAgIHB1YmxpYyBQS0lTdGF0dXMgZ2V0U3RhdHVzKCkgeworICAgICAgICByZXR1cm4gc3RhdHVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgc3RhdHVzU3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBMaXN0IGdldFN0YXR1c1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIHN0YXR1c1N0cmluZzsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEFTTjFTZXF1ZW5jZSBBU04xID0gbmV3IEFTTjFTZXF1ZW5jZShuZXcgQVNOMVR5cGVbXSB7CisgICAgICAgIEFTTjFJbnRlZ2VyLmdldEluc3RhbmNlKCksICAgICAgICAgICAgICAgICAgICAgIC8vIHN0YXR1cworICAgICAgICBuZXcgQVNOMVNlcXVlbmNlT2YoQVNOMVN0cmluZ1R5cGUuVVRGOFNUUklORyksICAvLyBzdGF0dXNTdHJpbmcKKyAgICAgICAgQVNOMUJpdFN0cmluZy5nZXRJbnN0YW5jZSgpIH0pIHsgICAgICAgICAgICAgICAgLy8gZmFpbEluZm8KKyAgICAgICAgeworICAgICAgICAgICAgc2V0T3B0aW9uYWwoMSk7CisgICAgICAgICAgICBzZXRPcHRpb25hbCgyKTsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKyAgICAgICAgICAgIFBLSVN0YXR1c0luZm8gcHNpID0gKFBLSVN0YXR1c0luZm8pIG9iamVjdDsKKyAgICAgICAgICAgIHZhbHVlc1swXSA9IEJpZ0ludGVnZXIudmFsdWVPZihwc2kuc3RhdHVzLmdldFN0YXR1cygpKQorICAgICAgICAgICAgICAgICAgICAudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgICAgIHZhbHVlc1sxXSA9IHBzaS5zdGF0dXNTdHJpbmc7CisgICAgICAgICAgICBpZiAocHNpLmZhaWxJbmZvICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyBzZXQgdGhlIG5lZWRlZCBiaXQgaW4gdGhlIGJpdCBzdHJpbmcKKyAgICAgICAgICAgICAgICBib29sZWFuW10gZmFpbEluZm9Cb29sQXJyYXkgPSBuZXcgYm9vbGVhbltQS0lGYWlsdXJlSW5mbworICAgICAgICAgICAgICAgICAgICAgICAgLmdldE1heFZhbHVlKCldOworICAgICAgICAgICAgICAgIGZhaWxJbmZvQm9vbEFycmF5W3BzaS5mYWlsSW5mby5nZXRWYWx1ZSgpXSA9IHRydWU7CisgICAgICAgICAgICAgICAgdmFsdWVzWzJdID0gbmV3IEJpdFN0cmluZyhmYWlsSW5mb0Jvb2xBcnJheSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHZhbHVlc1syXSA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgT2JqZWN0IGdldERlY29kZWRPYmplY3QoQmVySW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgICAgIE9iamVjdFtdIHZhbHVlcyA9IChPYmplY3RbXSkgaW4uY29udGVudDsKKworICAgICAgICAgICAgaW50IGZhaWxJbmZvVmFsdWUgPSAtMTsKKyAgICAgICAgICAgIGlmICh2YWx1ZXNbMl0gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGJvb2xlYW5bXSBmYWlsSW5mb0Jvb2xBcnJheSA9ICgoQml0U3RyaW5nKSB2YWx1ZXNbMl0pLnRvQm9vbGVhbkFycmF5KCk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmYWlsSW5mb0Jvb2xBcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBpZiAoZmFpbEluZm9Cb29sQXJyYXlbaV0pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWxJbmZvVmFsdWUgPSBpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IFBLSVN0YXR1c0luZm8oCisgICAgICAgICAgICAgICAgICAgIFBLSVN0YXR1cy5nZXRJbnN0YW5jZShBU04xSW50ZWdlci50b0ludFZhbHVlKHZhbHVlc1swXSkpLAorICAgICAgICAgICAgICAgICAgICAoTGlzdCl2YWx1ZXNbMV0sCisgICAgICAgICAgICAgICAgICAgIFBLSUZhaWx1cmVJbmZvLmdldEluc3RhbmNlKGZhaWxJbmZvVmFsdWUpKTsKKyAgICAgICAgfQorICAgIH07Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS90c3AvVFNUSW5mby5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L3RzcC9UU1RJbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTE2ODE0NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS90c3AvVFNUSW5mby5qYXZhCkBAIC0wLDAgKzEsMjk5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LnRzcDsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFCb29sZWFuOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFFeHBsaWNpdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xR2VuZXJhbGl6ZWRUaW1lOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFJbXBsaWNpdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xSW50ZWdlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xT2lkOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFTZXF1ZW5jZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5BU04xVHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5CZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkuYXNuMS5PYmplY3RJZGVudGlmaWVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5LkV4dGVuc2lvbnM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuR2VuZXJhbE5hbWU7CisKKy8qKgorICogQXMgZGVmaW5lZCBpbiBUaW1lLVN0YW1wIFByb3RvY29sIChUU1ApCisgKiAoaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzE2MS50eHQpCisgKgorICogVFNUSW5mbyA6Oj0gU0VRVUVOQ0UgIHsKKyAqICAgIHZlcnNpb24gICAgICAgICAgICAgICAgICAgICAgSU5URUdFUiAgeyB2MSgxKSB9LAorICogICAgcG9saWN5ICAgICAgICAgICAgICAgICAgICAgICBUU0FQb2xpY3lJZCwKKyAqICAgIG1lc3NhZ2VJbXByaW50ICAgICAgICAgICAgICAgTWVzc2FnZUltcHJpbnQsCisgKiAgICAgIC0tIE1VU1QgaGF2ZSB0aGUgc2FtZSB2YWx1ZSBhcyB0aGUgc2ltaWxhciBmaWVsZCBpbgorICogICAgICAtLSBUaW1lU3RhbXBSZXEKKyAqICAgIHNlcmlhbE51bWJlciAgICAgICAgICAgICAgICAgSU5URUdFUiwKKyAqICAgICAtLSBUaW1lLVN0YW1waW5nIHVzZXJzIE1VU1QgYmUgcmVhZHkgdG8gYWNjb21tb2RhdGUgaW50ZWdlcnMKKyAqICAgICAtLSB1cCB0byAxNjAgYml0cy4KKyAqICAgIGdlblRpbWUgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhbGl6ZWRUaW1lLAorICogICAgYWNjdXJhY3kgICAgICAgICAgICAgICAgICAgICBBY2N1cmFjeSAgICAgICAgICAgICAgICAgT1BUSU9OQUwsCisgKiAgICBvcmRlcmluZyAgICAgICAgICAgICAgICAgICAgIEJPT0xFQU4gICAgICAgICAgICAgREVGQVVMVCBGQUxTRSwKKyAqICAgIG5vbmNlICAgICAgICAgICAgICAgICAgICAgICAgSU5URUdFUiAgICAgICAgICAgICAgICAgIE9QVElPTkFMLAorICogICAgICAtLSBNVVNUIGJlIHByZXNlbnQgaWYgdGhlIHNpbWlsYXIgZmllbGQgd2FzIHByZXNlbnQKKyAqICAgICAgLS0gaW4gVGltZVN0YW1wUmVxLiAgSW4gdGhhdCBjYXNlIGl0IE1VU1QgaGF2ZSB0aGUgc2FtZSB2YWx1ZS4KKyAqICAgIHRzYSAgICAgICAgICAgICAgICAgICAgICAgICAgWzBdIEdlbmVyYWxOYW1lICAgICAgICAgIE9QVElPTkFMLAorICogICAgZXh0ZW5zaW9ucyAgICAgICAgICAgICAgICAgICBbMV0gSU1QTElDSVQgRXh0ZW5zaW9ucyAgIE9QVElPTkFMCisgKiB9CisgKgorICogVFNBUG9saWN5SWQgOjo9IE9CSkVDVCBJREVOVElGSUVSCisgKgorICogInRzYSBbMF0gR2VuZXJhbE5hbWUgT1BUSU9OQUwiIGlzIEVYUExJQ0lUIGFuZCB0aGUgd29yZCBFWFBMSUNJVCBpcyBvbWl0dGVkLgorICovCitwdWJsaWMgY2xhc3MgVFNUSW5mbyB7CisKKyAgICBwcml2YXRlIGZpbmFsIGludCB2ZXJzaW9uOworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcG9saWN5OworCisgICAgcHJpdmF0ZSBmaW5hbCBNZXNzYWdlSW1wcmludCBtZXNzYWdlSW1wcmludDsKKworICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBzZXJpYWxOdW1iZXI7CisKKyAgICBwcml2YXRlIGZpbmFsIERhdGUgZ2VuVGltZTsKKworICAgIHByaXZhdGUgZmluYWwgaW50IFtdIGFjY3VyYWN5OworCisgICAgcHJpdmF0ZSBmaW5hbCBCb29sZWFuIG9yZGVyaW5nOworCisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIG5vbmNlOworCisgICAgcHJpdmF0ZSBmaW5hbCBHZW5lcmFsTmFtZSB0c2E7CisKKyAgICBwcml2YXRlIGZpbmFsIEV4dGVuc2lvbnMgZXh0ZW5zaW9uczsKKworICAgIHB1YmxpYyBUU1RJbmZvKGludCB2ZXJzaW9uLCBTdHJpbmcgcG9saWN5LCBNZXNzYWdlSW1wcmludCBtZXNzYWdlSW1wcmludCwKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgc2VyaWFsTnVtYmVyLCBEYXRlIGdlblRpbWUsIGludFtdIGFjY3VyYWN5LAorICAgICAgICAgICAgQm9vbGVhbiBvcmRlcmluZywgQmlnSW50ZWdlciBub25jZSwgR2VuZXJhbE5hbWUgdHNhLAorICAgICAgICAgICAgRXh0ZW5zaW9ucyBleHRlbnNpb25zKSB7CisgICAgICAgIHRoaXMudmVyc2lvbiA9IHZlcnNpb247CisgICAgICAgIHRoaXMucG9saWN5ID0gcG9saWN5OworICAgICAgICB0aGlzLm1lc3NhZ2VJbXByaW50ID0gbWVzc2FnZUltcHJpbnQ7CisgICAgICAgIHRoaXMuc2VyaWFsTnVtYmVyID0gc2VyaWFsTnVtYmVyOworICAgICAgICB0aGlzLmdlblRpbWUgPSBnZW5UaW1lOworICAgICAgICB0aGlzLmFjY3VyYWN5ID0gYWNjdXJhY3k7CisgICAgICAgIHRoaXMub3JkZXJpbmcgPSBvcmRlcmluZzsKKyAgICAgICAgdGhpcy5ub25jZSA9IG5vbmNlOworICAgICAgICB0aGlzLnRzYSA9IHRzYTsKKyAgICAgICAgdGhpcy5leHRlbnNpb25zID0gZXh0ZW5zaW9uczsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlcyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIHJlcy5hcHBlbmQoIi0tIFRTVEluZm86Iik7CisgICAgICAgIHJlcy5hcHBlbmQoIlxudmVyc2lvbjogICIpOworICAgICAgICByZXMuYXBwZW5kKHZlcnNpb24pOworICAgICAgICByZXMuYXBwZW5kKCJcbnBvbGljeTogICIpOworICAgICAgICByZXMuYXBwZW5kKHBvbGljeSk7CisgICAgICAgIHJlcy5hcHBlbmQoIlxubWVzc2FnZUltcHJpbnQ6ICAiKTsKKyAgICAgICAgcmVzLmFwcGVuZChtZXNzYWdlSW1wcmludCk7CisgICAgICAgIHJlcy5hcHBlbmQoIlxuc2VyaWFsTnVtYmVyOiAgIik7CisgICAgICAgIHJlcy5hcHBlbmQoc2VyaWFsTnVtYmVyKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG5nZW5UaW1lOiAgIik7CisgICAgICAgIHJlcy5hcHBlbmQoZ2VuVGltZSk7CisgICAgICAgIHJlcy5hcHBlbmQoIlxuYWNjdXJhY3k6ICAiKTsKKyAgICAgICAgaWYgKGFjY3VyYWN5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlcy5hcHBlbmQoYWNjdXJhY3lbMF0gKyAiIHNlYywgIiArIGFjY3VyYWN5WzFdICsgIiBtaWxsaXMsICIKKyAgICAgICAgICAgICAgICAgICAgKyBhY2N1cmFjeVsyXSArICIgbWljcm9zIik7CisgICAgICAgIH0KKyAgICAgICAgcmVzLmFwcGVuZCgiXG5vcmRlcmluZzogICIpOworICAgICAgICByZXMuYXBwZW5kKG9yZGVyaW5nKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG5ub25jZTogICIpOworICAgICAgICByZXMuYXBwZW5kKG5vbmNlKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG50c2E6ICAiKTsKKyAgICAgICAgcmVzLmFwcGVuZCh0c2EpOworICAgICAgICByZXMuYXBwZW5kKCJcbmV4dGVuc2lvbnM6ICAiKTsKKyAgICAgICAgcmVzLmFwcGVuZChleHRlbnNpb25zKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG4tLSBUU1RJbmZvIEVuZFxuIik7CisgICAgICAgIHJldHVybiByZXMudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGFjY3VyYWN5LgorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSBnZXRBY2N1cmFjeSgpIHsKKyAgICAgICAgcmV0dXJuIGFjY3VyYWN5OworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgZXh0ZW5zaW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRXh0ZW5zaW9ucyBnZXRFeHRlbnNpb25zKCkgeworICAgICAgICByZXR1cm4gZXh0ZW5zaW9uczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGdlblRpbWUuCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0R2VuVGltZSgpIHsKKyAgICAgICAgcmV0dXJuIGdlblRpbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBtZXNzYWdlSW1wcmludC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWVzc2FnZUltcHJpbnQgZ2V0TWVzc2FnZUltcHJpbnQoKSB7CisgICAgICAgIHJldHVybiBtZXNzYWdlSW1wcmludDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIG5vbmNlLgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldE5vbmNlKCkgeworICAgICAgICByZXR1cm4gbm9uY2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBvcmRlcmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQm9vbGVhbiBnZXRPcmRlcmluZygpIHsKKyAgICAgICAgcmV0dXJuIG9yZGVyaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgcG9saWN5LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UG9saWN5KCkgeworICAgICAgICByZXR1cm4gcG9saWN5OworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgc2VyaWFsTnVtYmVyLgorICAgICAqLworICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFNlcmlhbE51bWJlcigpIHsKKyAgICAgICAgcmV0dXJuIHNlcmlhbE51bWJlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIHRzYS4KKyAgICAgKi8KKyAgICBwdWJsaWMgR2VuZXJhbE5hbWUgZ2V0VHNhKCkgeworICAgICAgICByZXR1cm4gdHNhOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgdmVyc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFZlcnNpb24oKSB7CisgICAgICAgIHJldHVybiB2ZXJzaW9uOworICAgIH0KKworICAgIC8qKgorICAgICAgICAgQWNjdXJhY3kgOjo9IFNFUVVFTkNFIHsKKyAgICAgICAgICAgICAgICBzZWNvbmRzICAgICAgICBJTlRFR0VSICAgICAgICAgICBPUFRJT05BTCwKKyAgICAgICAgICAgICAgICBtaWxsaXMgICAgIFswXSBJTlRFR0VSICAoMS4uOTk5KSBPUFRJT05BTCwKKyAgICAgICAgICAgICAgICBtaWNyb3MgICAgIFsxXSBJTlRFR0VSICAoMS4uOTk5KSBPUFRJT05BTCAgfQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVNlcXVlbmNlIEFDQ1VSQUNZCisgICAgICAgICAgICA9IG5ldyBBU04xU2VxdWVuY2UobmV3IEFTTjFUeXBlW10geworICAgICAgICAgICAgICAgICAgICBBU04xSW50ZWdlci5nZXRJbnN0YW5jZSgpLAorICAgICAgICAgICAgICAgICAgICBBU04xSW50ZWdlci5nZXRJbnN0YW5jZSgpLAorICAgICAgICAgICAgICAgICAgICBBU04xSW50ZWdlci5nZXRJbnN0YW5jZSgpCisgICAgICAgICAgICB9KSB7CisgICAgICAgIHsKKyAgICAgICAgICAgIHNldE9wdGlvbmFsKDApOworICAgICAgICAgICAgc2V0T3B0aW9uYWwoMSk7CisgICAgICAgICAgICBzZXRPcHRpb25hbCgyKTsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgT2JqZWN0W10gdmFsdWVzID0gKE9iamVjdFtdKSBpbi5jb250ZW50OworCisgICAgICAgICAgICBpbnQgW10gYWNjdXJhY3kgPSBuZXcgaW50IFszXTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKHZhbHVlc1tpXSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGFjY3VyYWN5W2ldID0gQVNOMUludGVnZXIudG9JbnRWYWx1ZSh2YWx1ZXNbaV0pOworICAgICAgICAgICAgICAgICAgICBpZiAoaSA+IDAgJiYgKGFjY3VyYWN5W2ldIDwgMCB8fCBhY2N1cmFjeVtpXSA+IDk5OSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJUaW1lLXN0YW1wIGFjY3VyYWN5IHZhbHVlIGlzIGluY29ycmVjdDogIiArIGFjY3VyYWN5W2ldKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBhY2N1cmFjeTsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKyAgICAgICAgICAgIGludCBbXSBhY2N1cmFjeSA9IChpbnQgW10pIG9iamVjdDsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGkgPiAwICYmIChhY2N1cmFjeVtpXSA8IDAgfHwgYWNjdXJhY3lbaV0gPiA5OTkpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJUaW1lLXN0YW1wIGFjY3VyYWN5IHZhbHVlIGlzIGluY29ycmVjdDogIiArIGFjY3VyYWN5W2ldKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdmFsdWVzW2ldID0gQmlnSW50ZWdlci52YWx1ZU9mKGFjY3VyYWN5W2ldKS50b0J5dGVBcnJheSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVNlcXVlbmNlIEFTTjEgPSBuZXcgQVNOMVNlcXVlbmNlKG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgIEFTTjFJbnRlZ2VyLmdldEluc3RhbmNlKCksICAgICAgICAgICAgICAvLyB2ZXJzaW9uCisgICAgICAgICAgICBBU04xT2lkLmdldEluc3RhbmNlKCksICAgICAgICAgICAgICAgICAgLy8gcG9saWN5CisgICAgICAgICAgICBNZXNzYWdlSW1wcmludC5BU04xLCAgICAgICAgICAgICAgICAgICAgLy8gbWVzc2FnZUltcHJpbnQKKyAgICAgICAgICAgIEFTTjFJbnRlZ2VyLmdldEluc3RhbmNlKCksICAgICAgICAgICAgICAvLyBzZXJpYWxOdW1iZXIKKyAgICAgICAgICAgIEFTTjFHZW5lcmFsaXplZFRpbWUuZ2V0SW5zdGFuY2UoKSwgICAgICAvLyBnZW5UaW1lCisgICAgICAgICAgICBBQ0NVUkFDWSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWNjdXJhY3kKKyAgICAgICAgICAgIEFTTjFCb29sZWFuLmdldEluc3RhbmNlKCksICAgICAgICAgICAgICAvLyBvcmRlcmluZworICAgICAgICAgICAgQVNOMUludGVnZXIuZ2V0SW5zdGFuY2UoKSwgICAgICAgICAgICAgIC8vIG5vbmNlCisgICAgICAgICAgICBuZXcgQVNOMUV4cGxpY2l0KDAsIEdlbmVyYWxOYW1lLkFTTjEpLCAgLy8gdHNhCisgICAgICAgICAgICBuZXcgQVNOMUltcGxpY2l0KDEsIEV4dGVuc2lvbnMuQVNOMSkgfSkgey8vIGV4dGVuc2lvbnMKKyAgICAgICAgeworICAgICAgICAgICAgc2V0T3B0aW9uYWwoNSk7CisgICAgICAgICAgICBzZXREZWZhdWx0KEJvb2xlYW4uRkFMU0UsIDYpOworICAgICAgICAgICAgc2V0T3B0aW9uYWwoNyk7CisgICAgICAgICAgICBzZXRPcHRpb25hbCg4KTsKKyAgICAgICAgICAgIHNldE9wdGlvbmFsKDkpOworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB7CisgICAgICAgICAgICBPYmplY3RbXSB2YWx1ZXMgPSAoT2JqZWN0W10pIGluLmNvbnRlbnQ7CisKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgbm9uY2UgPSAodmFsdWVzWzddID09IG51bGwpID8gbnVsbCA6IG5ldyBCaWdJbnRlZ2VyKAorICAgICAgICAgICAgICAgICAgICAoYnl0ZVtdKSB2YWx1ZXNbN10pOworCisgICAgICAgICAgICByZXR1cm4gbmV3IFRTVEluZm8oCisgICAgICAgICAgICAgICAgICAgIEFTTjFJbnRlZ2VyLnRvSW50VmFsdWUodmFsdWVzWzBdKSwKKyAgICAgICAgICAgICAgICAgICAgT2JqZWN0SWRlbnRpZmllci50b1N0cmluZygoaW50W10pIHZhbHVlc1sxXSksCisgICAgICAgICAgICAgICAgICAgIChNZXNzYWdlSW1wcmludCkgdmFsdWVzWzJdLAorICAgICAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigoYnl0ZVtdKSB2YWx1ZXNbM10pLAorICAgICAgICAgICAgICAgICAgICAoRGF0ZSkgdmFsdWVzWzRdLAorICAgICAgICAgICAgICAgICAgICAoaW50IFtdKSB2YWx1ZXNbNV0sCisgICAgICAgICAgICAgICAgICAgIChCb29sZWFuKSB2YWx1ZXNbNl0sCisgICAgICAgICAgICAgICAgICAgIG5vbmNlLAorICAgICAgICAgICAgICAgICAgICAoR2VuZXJhbE5hbWUpIHZhbHVlc1s4XSwKKyAgICAgICAgICAgICAgICAgICAgKEV4dGVuc2lvbnMpIHZhbHVlc1s5XSk7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgdm9pZCBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCwgT2JqZWN0W10gdmFsdWVzKSB7CisgICAgICAgICAgICBUU1RJbmZvIGluZm8gPSAoVFNUSW5mbykgb2JqZWN0OworCisgICAgICAgICAgICB2YWx1ZXNbMF0gPSBBU04xSW50ZWdlci5mcm9tSW50VmFsdWUoaW5mby52ZXJzaW9uKTsKKyAgICAgICAgICAgIHZhbHVlc1sxXSA9IE9iamVjdElkZW50aWZpZXIudG9JbnRBcnJheShpbmZvLnBvbGljeSk7CisgICAgICAgICAgICB2YWx1ZXNbMl0gPSBpbmZvLm1lc3NhZ2VJbXByaW50OworICAgICAgICAgICAgdmFsdWVzWzNdID0gaW5mby5zZXJpYWxOdW1iZXIudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgICAgIHZhbHVlc1s0XSA9IGluZm8uZ2VuVGltZTsKKyAgICAgICAgICAgIHZhbHVlc1s1XSA9IGluZm8uYWNjdXJhY3k7CisgICAgICAgICAgICB2YWx1ZXNbNl0gPSBpbmZvLm9yZGVyaW5nOworICAgICAgICAgICAgdmFsdWVzWzddID0gKGluZm8ubm9uY2UgPT0gbnVsbCkgPyBudWxsIDogaW5mby5ub25jZS50b0J5dGVBcnJheSgpOworICAgICAgICAgICAgdmFsdWVzWzhdID0gaW5mby50c2E7CisgICAgICAgICAgICB2YWx1ZXNbOV0gPSBpbmZvLmV4dGVuc2lvbnM7CisgICAgICAgIH0KKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L3RzcC9UaW1lU3RhbXBSZXEuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS90c3AvVGltZVN0YW1wUmVxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWQ3ODg2MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS90c3AvVGltZVN0YW1wUmVxLmphdmEKQEAgLTAsMCArMSwyMTQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkudHNwOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUJvb2xlYW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUltcGxpY2l0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFJbnRlZ2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFPaWQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLk9iamVjdElkZW50aWZpZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuRXh0ZW5zaW9uczsKKworLyoqCisgKiBBcyBkZWZpbmVkIGluIFRpbWUtU3RhbXAgUHJvdG9jb2wgKFRTUCkKKyAqIChodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMTYxLnR4dCkKKyAqCisgKiBUaW1lU3RhbXBSZXEgOjo9IFNFUVVFTkNFICB7CisgKiAgICB2ZXJzaW9uICAgICAgICAgICAgICAgICAgICAgIElOVEVHRVIgIHsgdjEoMSkgfSwKKyAqICAgIG1lc3NhZ2VJbXByaW50ICAgICAgICAgICAgICAgTWVzc2FnZUltcHJpbnQsCisgKiAgICAgIC0tYSBoYXNoIGFsZ29yaXRobSBPSUQgYW5kIHRoZSBoYXNoIHZhbHVlIG9mIHRoZSBkYXRhIHRvIGJlCisgKiAgICAgIC0tdGltZS1zdGFtcGVkCisgKiAgICByZXFQb2xpY3kgICAgICAgICAgICAgVFNBUG9saWN5SWQgICAgICAgICAgICAgIE9QVElPTkFMLAorICogICAgbm9uY2UgICAgICAgICAgICAgICAgIElOVEVHRVIgICAgICAgICAgICAgICAgICBPUFRJT05BTCwKKyAqICAgIGNlcnRSZXEgICAgICAgICAgICAgICBCT09MRUFOICAgICAgICAgICAgICAgICAgREVGQVVMVCBGQUxTRSwKKyAqICAgIGV4dGVuc2lvbnMgICAgICAgICAgICBbMF0gSU1QTElDSVQgRXh0ZW5zaW9ucyAgT1BUSU9OQUwKKyAqICB9CisgKgorICogIFRTQVBvbGljeUlkIDo6PSBPQkpFQ1QgSURFTlRJRklFUgorICovCitwdWJsaWMgY2xhc3MgVGltZVN0YW1wUmVxIHsKKyAgICBwcml2YXRlIGZpbmFsIGludCB2ZXJzaW9uOworCisgICAgcHJpdmF0ZSBmaW5hbCBNZXNzYWdlSW1wcmludCBtZXNzYWdlSW1wcmludDsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHJlcVBvbGljeTsKKworICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBub25jZTsKKworICAgIHByaXZhdGUgZmluYWwgQm9vbGVhbiBjZXJ0UmVxOworCisgICAgcHJpdmF0ZSBmaW5hbCBFeHRlbnNpb25zIGV4dGVuc2lvbnM7CisKKyAgICBwcml2YXRlIGJ5dGUgW10gZW5jb2Rpbmc7CisKKyAgICBwdWJsaWMgVGltZVN0YW1wUmVxKGludCB2ZXJzaW9uLCBNZXNzYWdlSW1wcmludCBtZXNzYWdlSW1wcmludCwKKyAgICAgICAgICAgIFN0cmluZyByZXFQb2xpY3ksIEJpZ0ludGVnZXIgbm9uY2UsIEJvb2xlYW4gY2VydFJlcSwKKyAgICAgICAgICAgIEV4dGVuc2lvbnMgZXh0ZW5zaW9ucykgeworICAgICAgICB0aGlzLnZlcnNpb24gPSB2ZXJzaW9uOworICAgICAgICB0aGlzLm1lc3NhZ2VJbXByaW50ID0gbWVzc2FnZUltcHJpbnQ7CisgICAgICAgIHRoaXMucmVxUG9saWN5ID0gcmVxUG9saWN5OworICAgICAgICB0aGlzLm5vbmNlID0gbm9uY2U7CisgICAgICAgIHRoaXMuY2VydFJlcSA9IGNlcnRSZXE7CisgICAgICAgIHRoaXMuZXh0ZW5zaW9ucyA9IGV4dGVuc2lvbnM7CisgICAgfQorCisgICAgcHJpdmF0ZSBUaW1lU3RhbXBSZXEoaW50IHZlcnNpb24sIE1lc3NhZ2VJbXByaW50IG1lc3NhZ2VJbXByaW50LAorICAgICAgICAgICAgU3RyaW5nIHJlcVBvbGljeSwgQmlnSW50ZWdlciBub25jZSwgQm9vbGVhbiBjZXJ0UmVxLAorICAgICAgICAgICAgRXh0ZW5zaW9ucyBleHRlbnNpb25zLCBieXRlIFtdIGVuY29kaW5nKSB7CisgICAgICAgIHRoaXMgKHZlcnNpb24sIG1lc3NhZ2VJbXByaW50LCByZXFQb2xpY3ksIG5vbmNlLCBjZXJ0UmVxLCBleHRlbnNpb25zKTsKKyAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiLS0gVGltZVN0YW1wUmVxOiIpOworICAgICAgICByZXMuYXBwZW5kKCJcbnZlcnNpb24gOiAiKTsKKyAgICAgICAgcmVzLmFwcGVuZCh2ZXJzaW9uKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG5tZXNzYWdlSW1wcmludDogICIpOworICAgICAgICByZXMuYXBwZW5kKG1lc3NhZ2VJbXByaW50KTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG5yZXFQb2xpY3k6ICAiKTsKKyAgICAgICAgcmVzLmFwcGVuZChyZXFQb2xpY3kpOworICAgICAgICByZXMuYXBwZW5kKCJcbm5vbmNlOiAgIik7CisgICAgICAgIHJlcy5hcHBlbmQobm9uY2UpOworICAgICAgICByZXMuYXBwZW5kKCJcbmNlcnRSZXE6ICAiKTsKKyAgICAgICAgcmVzLmFwcGVuZChjZXJ0UmVxKTsKKyAgICAgICAgcmVzLmFwcGVuZCgiXG5leHRlbnNpb25zOiAgIik7CisgICAgICAgIHJlcy5hcHBlbmQoZXh0ZW5zaW9ucyk7CisgICAgICAgIHJlcy5hcHBlbmQoIlxuLS0gVGltZVN0YW1wUmVxIEVuZFxuIik7CisgICAgICAgIHJldHVybiByZXMudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIEFTTi4xIGVuY29kZWQgZm9ybSBvZiB0aGlzIFRpbWVTdGFtcFJlcS4KKyAgICAgKiBAcmV0dXJuIGEgYnl0ZSBhcnJheSBjb250YWluaW5nIEFTTi4xIGVuY29kZWQgZm9ybS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZSBbXSBnZXRFbmNvZGVkKCl7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmNvZGluZyA9IEFTTjEuZW5jb2RlKHRoaXMpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGNlcnRSZXEuCisgICAgICovCisgICAgcHVibGljIEJvb2xlYW4gZ2V0Q2VydFJlcSgpIHsKKyAgICAgICAgcmV0dXJuIGNlcnRSZXE7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBleHRlbnNpb25zLgorICAgICAqLworICAgIHB1YmxpYyBFeHRlbnNpb25zIGdldEV4dGVuc2lvbnMoKSB7CisgICAgICAgIHJldHVybiBleHRlbnNpb25zOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgbWVzc2FnZUltcHJpbnQuCisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2VJbXByaW50IGdldE1lc3NhZ2VJbXByaW50KCkgeworICAgICAgICByZXR1cm4gbWVzc2FnZUltcHJpbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBub25jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXROb25jZSgpIHsKKyAgICAgICAgcmV0dXJuIG5vbmNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgcmVxUG9saWN5LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UmVxUG9saWN5KCkgeworICAgICAgICByZXR1cm4gcmVxUG9saWN5OworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgdmVyc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFZlcnNpb24oKSB7CisgICAgICAgIHJldHVybiB2ZXJzaW9uOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQVNOMVNlcXVlbmNlIEFTTjEgPSBuZXcgQVNOMVNlcXVlbmNlKG5ldyBBU04xVHlwZVtdIHsKKyAgICAgICAgICAgIEFTTjFJbnRlZ2VyLmdldEluc3RhbmNlKCksICAgICAgICAgICAgICAvLyB2ZXJzaW9uCisgICAgICAgICAgICBNZXNzYWdlSW1wcmludC5BU04xLCAgICAgICAgICAgICAgICAgICAgLy8gbWVzc2FnZUltcHJpbnQKKyAgICAgICAgICAgIEFTTjFPaWQuZ2V0SW5zdGFuY2UoKSwgICAgICAgICAgICAgICAgICAvLyByZXFQb2xpY3kKKyAgICAgICAgICAgIEFTTjFJbnRlZ2VyLmdldEluc3RhbmNlKCksICAgICAgICAgICAgICAvLyBub25jZQorICAgICAgICAgICAgQVNOMUJvb2xlYW4uZ2V0SW5zdGFuY2UoKSwgICAgICAgICAgICAgIC8vIGNlcnRSZXEKKyAgICAgICAgICAgIG5ldyBBU04xSW1wbGljaXQoMCwgRXh0ZW5zaW9ucy5BU04xKX0pIHsvLyBleHRlbnNpb25zCisKKyAgICAgICAgeworICAgICAgICAgICAgc2V0RGVmYXVsdChCb29sZWFuLkZBTFNFLCA0KTsKKyAgICAgICAgICAgIHNldE9wdGlvbmFsKDIpOworICAgICAgICAgICAgc2V0T3B0aW9uYWwoMyk7CisgICAgICAgICAgICBzZXRPcHRpb25hbCg1KTsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCBPYmplY3QgZ2V0RGVjb2RlZE9iamVjdChCZXJJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgT2JqZWN0W10gdmFsdWVzID0gKE9iamVjdFtdKSBpbi5jb250ZW50OworCisgICAgICAgICAgICBTdHJpbmcgb2JqSUQgPSAodmFsdWVzWzJdID09IG51bGwpID8gbnVsbCA6IE9iamVjdElkZW50aWZpZXIKKyAgICAgICAgICAgICAgICAgICAgLnRvU3RyaW5nKChpbnRbXSkgdmFsdWVzWzJdKTsKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgbm9uY2UgPSAodmFsdWVzWzNdID09IG51bGwpID8gbnVsbCA6IG5ldyBCaWdJbnRlZ2VyKAorICAgICAgICAgICAgICAgICAgICAoYnl0ZVtdKSB2YWx1ZXNbM10pOworCisgICAgICAgICAgICBpZiAodmFsdWVzWzVdID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFRpbWVTdGFtcFJlcSgKKyAgICAgICAgICAgICAgICAgICAgICAgIEFTTjFJbnRlZ2VyLnRvSW50VmFsdWUodmFsdWVzWzBdKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIChNZXNzYWdlSW1wcmludCkgdmFsdWVzWzFdLAorICAgICAgICAgICAgICAgICAgICAgICAgb2JqSUQsCisgICAgICAgICAgICAgICAgICAgICAgICBub25jZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIChCb29sZWFuKSB2YWx1ZXNbNF0sCisgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgaW4uZ2V0RW5jb2RlZCgpCisgICAgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUaW1lU3RhbXBSZXEoCisgICAgICAgICAgICAgICAgICAgICAgICBBU04xSW50ZWdlci50b0ludFZhbHVlKHZhbHVlc1swXSksCisgICAgICAgICAgICAgICAgICAgICAgICAoTWVzc2FnZUltcHJpbnQpIHZhbHVlc1sxXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG9iaklELAorICAgICAgICAgICAgICAgICAgICAgICAgbm9uY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAoQm9vbGVhbikgdmFsdWVzWzRdLAorICAgICAgICAgICAgICAgICAgICAgICAgKEV4dGVuc2lvbnMpIHZhbHVlc1s1XSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGluLmdldEVuY29kZWQoKQorICAgICAgICAgICAgICAgICAgICk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgdm9pZCBnZXRWYWx1ZXMoT2JqZWN0IG9iamVjdCwgT2JqZWN0W10gdmFsdWVzKSB7CisgICAgICAgICAgICBUaW1lU3RhbXBSZXEgcmVxID0gKFRpbWVTdGFtcFJlcSkgb2JqZWN0OworICAgICAgICAgICAgdmFsdWVzWzBdID0gQVNOMUludGVnZXIuZnJvbUludFZhbHVlKHJlcS52ZXJzaW9uKTsKKyAgICAgICAgICAgIHZhbHVlc1sxXSA9IHJlcS5tZXNzYWdlSW1wcmludDsKKyAgICAgICAgICAgIHZhbHVlc1syXSA9IChyZXEucmVxUG9saWN5ID09IG51bGwpID8gbnVsbCA6IE9iamVjdElkZW50aWZpZXIKKyAgICAgICAgICAgICAgICAgICAgLnRvSW50QXJyYXkocmVxLnJlcVBvbGljeSk7CisgICAgICAgICAgICB2YWx1ZXNbM10gPSAocmVxLm5vbmNlID09IG51bGwpID8gbnVsbCA6IHJlcS5ub25jZS50b0J5dGVBcnJheSgpOworICAgICAgICAgICAgdmFsdWVzWzRdID0gKHJlcS5jZXJ0UmVxID09IG51bGwpID8gQm9vbGVhbi5GQUxTRSA6IHJlcS5jZXJ0UmVxOworICAgICAgICAgICAgdmFsdWVzWzVdID0gcmVxLmV4dGVuc2lvbnM7CisgICAgICAgIH0KKyAgICB9OworCit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS90c3AvVGltZVN0YW1wUmVzcC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS94NTA5L3RzcC9UaW1lU3RhbXBSZXNwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjMyNzBmZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkveDUwOS90c3AvVGltZVN0YW1wUmVzcC5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkudHNwOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkJlcklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wa2NzNy5Db250ZW50SW5mbzsKKworLyoqCisgKiBBcyBkZWZpbmVkIGluIFRpbWUtU3RhbXAgUHJvdG9jb2wgKFRTUCkKKyAqIChodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMTYxLnR4dCkKKyAqCisgKiBUaW1lU3RhbXBSZXNwIDo6PSBTRVFVRU5DRSB7CisgKiAgICBzdGF0dXMgUEtJU3RhdHVzSW5mbywKKyAqICAgIHRpbWVTdGFtcFRva2VuIFRpbWVTdGFtcFRva2VuIE9QVElPTkFMCisgKiB9CisgKgorICovCitwdWJsaWMgY2xhc3MgVGltZVN0YW1wUmVzcCB7CisKKyAgICBwcml2YXRlIGZpbmFsIFBLSVN0YXR1c0luZm8gc3RhdHVzOworCisgICAgcHJpdmF0ZSBmaW5hbCBDb250ZW50SW5mbyB0aW1lU3RhbXBUb2tlbjsKKworICAgIHB1YmxpYyBUaW1lU3RhbXBSZXNwKFBLSVN0YXR1c0luZm8gc3RhdHVzLCBDb250ZW50SW5mbyB0aW1lU3RhbXBUb2tlbikgeworICAgICAgICB0aGlzLnN0YXR1cyA9IHN0YXR1czsKKyAgICAgICAgdGhpcy50aW1lU3RhbXBUb2tlbiA9IHRpbWVTdGFtcFRva2VuOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKXsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXMgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICByZXMuYXBwZW5kKCItLSBUaW1lU3RhbXBSZXNwOiIpOworICAgICAgICByZXMuYXBwZW5kKCJcbnN0YXR1czogICIpOworICAgICAgICByZXMuYXBwZW5kKHN0YXR1cyk7CisgICAgICAgIHJlcy5hcHBlbmQoIlxudGltZVN0YW1wVG9rZW46ICAiKTsKKyAgICAgICAgcmVzLmFwcGVuZCh0aW1lU3RhbXBUb2tlbik7CisgICAgICAgIHJlcy5hcHBlbmQoIlxuLS0gVGltZVN0YW1wUmVzcCBFbmRcbiIpOworICAgICAgICByZXR1cm4gcmVzLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBzdGF0dXMuCisgICAgICovCisgICAgcHVibGljIFBLSVN0YXR1c0luZm8gZ2V0U3RhdHVzKCkgeworICAgICAgICByZXR1cm4gc3RhdHVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgdGltZVN0YW1wVG9rZW4uCisgICAgICovCisgICAgcHVibGljIENvbnRlbnRJbmZvIGdldFRpbWVTdGFtcFRva2VuKCkgeworICAgICAgICByZXR1cm4gdGltZVN0YW1wVG9rZW47CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBBU04xU2VxdWVuY2UgQVNOMSA9IG5ldyBBU04xU2VxdWVuY2UobmV3IEFTTjFUeXBlW10geworICAgICAgICAgICAgUEtJU3RhdHVzSW5mby5BU04xLCAgICAgLy8gc3RhdHVzCisgICAgICAgICAgICBDb250ZW50SW5mby5BU04xfSkgeyAgICAvLyB0aW1lU3RhbXBUb2tlbgorCisgICAgICAgIHsKKyAgICAgICAgICAgIHNldE9wdGlvbmFsKDEpOworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIE9iamVjdCBnZXREZWNvZGVkT2JqZWN0KEJlcklucHV0U3RyZWFtIGluKSB7CisgICAgICAgICAgICBPYmplY3RbXSB2YWx1ZXMgPSAoT2JqZWN0W10pIGluLmNvbnRlbnQ7CisgICAgICAgICAgICByZXR1cm4gbmV3IFRpbWVTdGFtcFJlc3AoCisgICAgICAgICAgICAgICAgICAgIChQS0lTdGF0dXNJbmZvKSB2YWx1ZXNbMF0sCisgICAgICAgICAgICAgICAgICAgIChDb250ZW50SW5mbykgdmFsdWVzWzFdKTsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGdldFZhbHVlcyhPYmplY3Qgb2JqZWN0LCBPYmplY3RbXSB2YWx1ZXMpIHsKKyAgICAgICAgICAgIFRpbWVTdGFtcFJlc3AgcmVzcCA9IChUaW1lU3RhbXBSZXNwKSBvYmplY3Q7CisKKyAgICAgICAgICAgIHZhbHVlc1swXSA9IHJlc3Auc3RhdHVzOworICAgICAgICAgICAgdmFsdWVzWzFdID0gcmVzcC50aW1lU3RhbXBUb2tlbjsKKyAgICAgICAgfQorICAgIH07Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL0V4cGF0QXR0cmlidXRlcy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvRXhwYXRBdHRyaWJ1dGVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjkyZmM1MAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL0V4cGF0QXR0cmlidXRlcy5qYXZhCkBAIC0wLDAgKzEsMTUwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG1sOworCitpbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKKworLyoqCisgKiBXcmFwcyBuYXRpdmUgYXR0cmlidXRlIGFycmF5LgorICovCithYnN0cmFjdCBjbGFzcyBFeHBhdEF0dHJpYnV0ZXMgaW1wbGVtZW50cyBBdHRyaWJ1dGVzIHsKKworICAgIC8qKgorICAgICAqIFNpbmNlIHdlIGRvbid0IGRvIHZhbGlkYXRpb24sIHByZXR0eSBtdWNoIGV2ZXJ5dGhpbmcgaXMgQ0RBVEEgdHlwZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0RBVEEgPSAiQ0RBVEEiOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRMZW5ndGgoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHBvaW50ZXIgdG8gdGhlIHBhcnNlci4gV2UgbmVlZCB0aGlzIHNvIHdlIGNhbiBnZXQgdG8gdGhlCisgICAgICogaW50ZXJuZWQgc3RyaW5nIHBvb2wuCisgICAgICovCisgICAgYWJzdHJhY3QgaW50IGdldFBhcnNlclBvaW50ZXIoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHBvaW50ZXIgdG8gdGhlIHVuZGVybHlpbmcgYXR0cmlidXRlIGFycmF5LiBDYW4gYmUgMCBpZiB0aGUKKyAgICAgKiBsZW5ndGggaXMgMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldFBvaW50ZXIoKTsKKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VVJJKGludCBpbmRleCkgeworICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGdldExlbmd0aCgpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0VVJJKGdldFBhcnNlclBvaW50ZXIoKSwgZ2V0UG9pbnRlcigpLCBpbmRleCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGdldExlbmd0aCgpKQorICAgICAgICAgICAgICAgID8gbnVsbAorICAgICAgICAgICAgICAgIDogZ2V0TG9jYWxOYW1lKGdldFBhcnNlclBvaW50ZXIoKSwgZ2V0UG9pbnRlcigpLCBpbmRleCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRRTmFtZShpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIChpbmRleCA8IDAgfHwgaW5kZXggPj0gZ2V0TGVuZ3RoKCkpCisgICAgICAgICAgICAgICAgPyBudWxsCisgICAgICAgICAgICAgICAgOiBnZXRRTmFtZShnZXRQYXJzZXJQb2ludGVyKCksIGdldFBvaW50ZXIoKSwgaW5kZXgpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZShpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIChpbmRleCA8IDAgfHwgaW5kZXggPj0gZ2V0TGVuZ3RoKCkpID8gbnVsbCA6IENEQVRBOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGdldExlbmd0aCgpKQorICAgICAgICAgICAgICAgID8gbnVsbAorICAgICAgICAgICAgICAgIDogZ2V0VmFsdWVCeUluZGV4KGdldFBvaW50ZXIoKSwgaW5kZXgpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXgoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkgeworICAgICAgICBpZiAodXJpID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidXJpIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxvY2FsTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImxvY2FsIG5hbWUiKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgcG9pbnRlciA9IGdldFBvaW50ZXIoKTsKKyAgICAgICAgaWYgKHBvaW50ZXIgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRJbmRleChwb2ludGVyLCB1cmksIGxvY2FsTmFtZSk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRJbmRleChTdHJpbmcgcU5hbWUpIHsKKyAgICAgICAgaWYgKHFOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidXJpIik7CisgICAgICAgIH0KKyAgICAgICAgaW50IHBvaW50ZXIgPSBnZXRQb2ludGVyKCk7CisgICAgICAgIGlmIChwb2ludGVyID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0SW5kZXhGb3JRTmFtZShwb2ludGVyLCBxTmFtZSk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRUeXBlKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpIHsKKyAgICAgICAgaWYgKHVyaSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInVyaSIpOworICAgICAgICB9CisgICAgICAgIGlmIChsb2NhbE5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJsb2NhbCBuYW1lIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldEluZGV4KHVyaSwgbG9jYWxOYW1lKSA9PSAtMSA/IG51bGwgOiBDREFUQTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoU3RyaW5nIHFOYW1lKSB7CisgICAgICAgIHJldHVybiBnZXRJbmRleChxTmFtZSkgPT0gLTEgPyBudWxsIDogQ0RBVEE7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZShTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKSB7CisgICAgICAgIGlmICh1cmkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ1cmkiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobG9jYWxOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibG9jYWwgbmFtZSIpOworICAgICAgICB9CisgICAgICAgIGludCBwb2ludGVyID0gZ2V0UG9pbnRlcigpOworICAgICAgICBpZiAocG9pbnRlciA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZ2V0VmFsdWUocG9pbnRlciwgdXJpLCBsb2NhbE5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoU3RyaW5nIHFOYW1lKSB7CisgICAgICAgIGlmIChxTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInFOYW1lIik7CisgICAgICAgIH0KKyAgICAgICAgaW50IHBvaW50ZXIgPSBnZXRQb2ludGVyKCk7CisgICAgICAgIGlmIChwb2ludGVyID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBnZXRWYWx1ZUZvclFOYW1lKHBvaW50ZXIsIHFOYW1lKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgU3RyaW5nIGdldFVSSShpbnQgcG9pbnRlciwgaW50IGF0dHJpYnV0ZVBvaW50ZXIsIGludCBpbmRleCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIFN0cmluZyBnZXRMb2NhbE5hbWUoaW50IHBvaW50ZXIsIGludCBhdHRyaWJ1dGVQb2ludGVyLCBpbnQgaW5kZXgpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBTdHJpbmcgZ2V0UU5hbWUoaW50IHBvaW50ZXIsIGludCBhdHRyaWJ1dGVQb2ludGVyLCBpbnQgaW5kZXgpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBTdHJpbmcgZ2V0VmFsdWVCeUluZGV4KGludCBhdHRyaWJ1dGVQb2ludGVyLCBpbnQgaW5kZXgpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgZ2V0SW5kZXgoaW50IGF0dHJpYnV0ZVBvaW50ZXIsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpOworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgZ2V0SW5kZXhGb3JRTmFtZShpbnQgYXR0cmlidXRlUG9pbnRlciwgU3RyaW5nIHFOYW1lKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgU3RyaW5nIGdldFZhbHVlKGludCBhdHRyaWJ1dGVQb2ludGVyLCBTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKTsKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgU3RyaW5nIGdldFZhbHVlRm9yUU5hbWUoaW50IGF0dHJpYnV0ZVBvaW50ZXIsIFN0cmluZyBxTmFtZSk7CisgICAgcHJvdGVjdGVkIG5hdGl2ZSB2b2lkIGZyZWVBdHRyaWJ1dGVzKGludCBwb2ludGVyKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL0V4cGF0RXhjZXB0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9FeHBhdEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhM2RiOWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9FeHBhdEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bWw7CisKKy8qKgorICogVXNlZCBpbnRlcm5hbGx5IHRvIHByb3BvZ2F0ZSBFeHBhdCBlcnJvcnMuIFdlIGNvbnZlcnQgdGhlc2UgZXhjZXB0aW9ucyBpbnRvCisgKiBTQVhQYXJzZUV4Y2VwdGlvbnMgYmVmb3JlIHByb3BvZ2F0aW5nIHRoZW0gdG8gdGhlIGNsaWVudC4KKyAqLworY2xhc3MgRXhwYXRFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworCisgICAgcHVibGljIEV4cGF0RXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7CisgICAgICAgIHN1cGVyKG1lc3NhZ2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL0V4cGF0UGFyc2VyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9FeHBhdFBhcnNlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyYzhlMmEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9FeHBhdFBhcnNlci5qYXZhCkBAIC0wLDAgKzEsODA0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG1sOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUmVhZGVyOworaW1wb3J0IGphdmEubmV0LlVSSTsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5uZXQuVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBsaWJjb3JlLmlvLklvVXRpbHM7CitpbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKK2ltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOworaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOworaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKKworLyoqCisgKiBBZGFwdHMgU0FYIEFQSSB0byB0aGUgRXhwYXQgbmF0aXZlIFhNTCBwYXJzZXIuIE5vdCBpbnRlbmRlZCBmb3IgcmV1c2UKKyAqIGFjcm9zcyBkb2N1bWVudHMuCisgKgorICogQHNlZSBvcmcuYXBhY2hlLmhhcm1vbnkueG1sLkV4cGF0UmVhZGVyCisgKi8KK2NsYXNzIEV4cGF0UGFyc2VyIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCVUZGRVJfU0laRSA9IDgwOTY7IC8vIGluIGJ5dGVzCisKKyAgICAvKiogUG9pbnRlciB0byBYTUxfUGFyc2VyIGluc3RhbmNlLiAqLworICAgIHByaXZhdGUgaW50IHBvaW50ZXI7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaW5TdGFydEVsZW1lbnQgPSBmYWxzZTsKKyAgICBwcml2YXRlIGludCBhdHRyaWJ1dGVDb3VudCA9IC0xOworICAgIHByaXZhdGUgaW50IGF0dHJpYnV0ZVBvaW50ZXIgPSAwOworCisgICAgcHJpdmF0ZSBmaW5hbCBMb2NhdG9yIGxvY2F0b3IgPSBuZXcgRXhwYXRMb2NhdG9yKCk7CisKKyAgICBwcml2YXRlIGZpbmFsIEV4cGF0UmVhZGVyIHhtbFJlYWRlcjsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHB1YmxpY0lkOworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHN5c3RlbUlkOworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZW5jb2Rpbmc7CisKKyAgICBwcml2YXRlIGZpbmFsIEV4cGF0QXR0cmlidXRlcyBhdHRyaWJ1dGVzID0gbmV3IEN1cnJlbnRBdHRyaWJ1dGVzKCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgT1VUU0lERV9TVEFSVF9FTEVNRU5UCisgICAgICAgICAgICA9ICJBdHRyaWJ1dGVzIGNhbiBvbmx5IGJlIHVzZWQgd2l0aGluIHRoZSBzY29wZSBvZiBzdGFydEVsZW1lbnQoKS4iOworCisgICAgLyoqIFdlIGRlZmF1bHQgdG8gVVRGLTggd2hlbiB0aGUgdXNlciBkb2Vzbid0IHNwZWNpZnkgYW4gZW5jb2RpbmcuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfRU5DT0RJTkcgPSAiVVRGLTgiOworCisgICAgLyoqIEVuY29kaW5nIHVzZWQgZm9yIEphdmEgY2hhcnMsIHVzZWQgdG8gcGFyc2UgUmVhZGVycyBhbmQgU3RyaW5ncyAqLworICAgIC8qcGFja2FnZSovIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0hBUkFDVEVSX0VOQ09ESU5HID0gIlVURi0xNiI7CisKKyAgICAvKiogVGltZW91dCBmb3IgSFRUUCBjb25uZWN0aW9ucyAoaW4gbXMpICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRJTUVPVVQgPSAyMCAqIDEwMDA7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHBhcnNlciB3aXRoIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmcuCisgICAgICovCisgICAgLypwYWNrYWdlKi8gRXhwYXRQYXJzZXIoU3RyaW5nIGVuY29kaW5nLCBFeHBhdFJlYWRlciB4bWxSZWFkZXIsCisgICAgICAgICAgICBib29sZWFuIHByb2Nlc3NOYW1lc3BhY2VzLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkgeworICAgICAgICB0aGlzLnB1YmxpY0lkID0gcHVibGljSWQ7CisgICAgICAgIHRoaXMuc3lzdGVtSWQgPSBzeXN0ZW1JZDsKKworICAgICAgICB0aGlzLnhtbFJlYWRlciA9IHhtbFJlYWRlcjsKKworICAgICAgICAvKgorICAgICAgICAgKiBUT0RPOiBMZXQgRXhwYXQgdHJ5IHRvIGd1ZXNzIHRoZSBlbmNvZGluZyBpbnN0ZWFkIG9mIGRlZmF1bHRpbmcuCisgICAgICAgICAqIFVuZm9ydHVuYXRlbHksIEkgZG9uJ3Qga25vdyBob3cgdG8gdGVsbCB3aGljaCBlbmNvZGluZyBFeHBhdCBwaWNrZWQsCisgICAgICAgICAqIHNvIEkgd29uJ3Qga25vdyBob3cgdG8gZW5jb2RlICI8ZXh0ZXJuYWxFbnRpdHk+IiBiZWxvdy4gVGhlIHNvbHV0aW9uCisgICAgICAgICAqIEkgdGhpbmsgaXMgdG8gZml4IEV4cGF0IHRvIG5vdCByZXF1aXJlIHRoZSAiPGV4dGVybmFsRW50aXR5PiIKKyAgICAgICAgICogd29ya2Fyb3VuZC4KKyAgICAgICAgICovCisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZyA9PSBudWxsID8gREVGQVVMVF9FTkNPRElORyA6IGVuY29kaW5nOworICAgICAgICB0aGlzLnBvaW50ZXIgPSBpbml0aWFsaXplKAorICAgICAgICAgICAgdGhpcy5lbmNvZGluZywKKyAgICAgICAgICAgIHByb2Nlc3NOYW1lc3BhY2VzCisgICAgICAgICk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlZCBieSB7QGxpbmsgRW50aXR5UGFyc2VyfS4KKyAgICAgKi8KKyAgICBwcml2YXRlIEV4cGF0UGFyc2VyKFN0cmluZyBlbmNvZGluZywgRXhwYXRSZWFkZXIgeG1sUmVhZGVyLCBpbnQgcG9pbnRlciwKKyAgICAgICAgICAgIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKSB7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICAgICAgdGhpcy54bWxSZWFkZXIgPSB4bWxSZWFkZXI7CisgICAgICAgIHRoaXMucG9pbnRlciA9IHBvaW50ZXI7CisgICAgICAgIHRoaXMuc3lzdGVtSWQgPSBzeXN0ZW1JZDsKKyAgICAgICAgdGhpcy5wdWJsaWNJZCA9IHB1YmxpY0lkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIG5hdGl2ZSByZXNvdXJjZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwb2ludGVyIHRvIHRoZSBuYXRpdmUgcGFyc2VyCisgICAgICovCisgICAgcHJpdmF0ZSBuYXRpdmUgaW50IGluaXRpYWxpemUoU3RyaW5nIGVuY29kaW5nLCBib29sZWFuIG5hbWVzcGFjZXNFbmFibGVkKTsKKworICAgIC8qKgorICAgICAqIENhbGxlZCBhdCB0aGUgc3RhcnQgb2YgYW4gZWxlbWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmkgbmFtZXNwYWNlIFVSSSBvZiBlbGVtZW50IG9yICIiIGlmIG5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzCisgICAgICogIGRpc2FibGVkCisgICAgICogQHBhcmFtIGxvY2FsTmFtZSBsb2NhbCBuYW1lIG9mIGVsZW1lbnQgb3IgIiIgaWYgbmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMKKyAgICAgKiAgZGlzYWJsZWQKKyAgICAgKiBAcGFyYW0gcU5hbWUgcXVhbGlmaWVkIG5hbWUgb3IgIiIgaWYgbmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgZW5hYmxlZAorICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVQb2ludGVyIHBvaW50ZXIgdG8gbmF0aXZlIGF0dHJpYnV0ZSBjaGFyKi0td2Uga2VlcAorICAgICAqICBhIHNlcGFyYXRlIHBvaW50ZXIgc28gd2UgY2FuIGRldGFjaCBpdCBmcm9tIHRoZSBwYXJzZXIgaW5zdGFuY2UKKyAgICAgKiBAcGFyYW0gYXR0cmlidXRlQ291bnQgbnVtYmVyIG9mIGF0dHJpYnV0ZXMKKyAgICAgKi8KKyAgICAvKnBhY2thZ2UqLyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUsCisgICAgICAgICAgICBpbnQgYXR0cmlidXRlUG9pbnRlciwgaW50IGF0dHJpYnV0ZUNvdW50KSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgQ29udGVudEhhbmRsZXIgY29udGVudEhhbmRsZXIgPSB4bWxSZWFkZXIuY29udGVudEhhbmRsZXI7CisgICAgICAgIGlmIChjb250ZW50SGFuZGxlciA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5TdGFydEVsZW1lbnQgPSB0cnVlOworICAgICAgICAgICAgdGhpcy5hdHRyaWJ1dGVQb2ludGVyID0gYXR0cmlidXRlUG9pbnRlcjsKKyAgICAgICAgICAgIHRoaXMuYXR0cmlidXRlQ291bnQgPSBhdHRyaWJ1dGVDb3VudDsKKworICAgICAgICAgICAgY29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KAorICAgICAgICAgICAgICAgICAgICB1cmksIGxvY2FsTmFtZSwgcU5hbWUsIHRoaXMuYXR0cmlidXRlcyk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpblN0YXJ0RWxlbWVudCA9IGZhbHNlOworICAgICAgICAgICAgdGhpcy5hdHRyaWJ1dGVDb3VudCA9IC0xOworICAgICAgICAgICAgdGhpcy5hdHRyaWJ1dGVQb2ludGVyID0gMDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qcGFja2FnZSovIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUpCisgICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgQ29udGVudEhhbmRsZXIgY29udGVudEhhbmRsZXIgPSB4bWxSZWFkZXIuY29udGVudEhhbmRsZXI7CisgICAgICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgICAgICBjb250ZW50SGFuZGxlci5lbmRFbGVtZW50KHVyaSwgbG9jYWxOYW1lLCBxTmFtZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKnBhY2thZ2UqLyB2b2lkIHRleHQoY2hhcltdIHRleHQsIGludCBsZW5ndGgpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICBDb250ZW50SGFuZGxlciBjb250ZW50SGFuZGxlciA9IHhtbFJlYWRlci5jb250ZW50SGFuZGxlcjsKKyAgICAgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLmNoYXJhY3RlcnModGV4dCwgMCwgbGVuZ3RoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qcGFja2FnZSovIHZvaWQgY29tbWVudChjaGFyW10gdGV4dCwgaW50IGxlbmd0aCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIExleGljYWxIYW5kbGVyIGxleGljYWxIYW5kbGVyID0geG1sUmVhZGVyLmxleGljYWxIYW5kbGVyOworICAgICAgICBpZiAobGV4aWNhbEhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgbGV4aWNhbEhhbmRsZXIuY29tbWVudCh0ZXh0LCAwLCBsZW5ndGgpOworICAgICAgICB9CisgICAgfQorCisgICAgLypwYWNrYWdlKi8gdm9pZCBzdGFydENkYXRhKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIExleGljYWxIYW5kbGVyIGxleGljYWxIYW5kbGVyID0geG1sUmVhZGVyLmxleGljYWxIYW5kbGVyOworICAgICAgICBpZiAobGV4aWNhbEhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgbGV4aWNhbEhhbmRsZXIuc3RhcnRDREFUQSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLypwYWNrYWdlKi8gdm9pZCBlbmRDZGF0YSgpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICBMZXhpY2FsSGFuZGxlciBsZXhpY2FsSGFuZGxlciA9IHhtbFJlYWRlci5sZXhpY2FsSGFuZGxlcjsKKyAgICAgICAgaWYgKGxleGljYWxIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxleGljYWxIYW5kbGVyLmVuZENEQVRBKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKnBhY2thZ2UqLyB2b2lkIHN0YXJ0TmFtZXNwYWNlKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCisgICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgQ29udGVudEhhbmRsZXIgY29udGVudEhhbmRsZXIgPSB4bWxSZWFkZXIuY29udGVudEhhbmRsZXI7CisgICAgICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgICAgICBjb250ZW50SGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcocHJlZml4LCB1cmkpOworICAgICAgICB9CisgICAgfQorCisgICAgLypwYWNrYWdlKi8gdm9pZCBlbmROYW1lc3BhY2UoU3RyaW5nIHByZWZpeCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIENvbnRlbnRIYW5kbGVyIGNvbnRlbnRIYW5kbGVyID0geG1sUmVhZGVyLmNvbnRlbnRIYW5kbGVyOworICAgICAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgY29udGVudEhhbmRsZXIuZW5kUHJlZml4TWFwcGluZyhwcmVmaXgpOworICAgICAgICB9CisgICAgfQorCisgICAgLypwYWNrYWdlKi8gdm9pZCBzdGFydER0ZChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCisgICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgTGV4aWNhbEhhbmRsZXIgbGV4aWNhbEhhbmRsZXIgPSB4bWxSZWFkZXIubGV4aWNhbEhhbmRsZXI7CisgICAgICAgIGlmIChsZXhpY2FsSGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgICAgICBsZXhpY2FsSGFuZGxlci5zdGFydERURChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOworICAgICAgICB9CisgICAgfQorCisgICAgLypwYWNrYWdlKi8gdm9pZCBlbmREdGQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgTGV4aWNhbEhhbmRsZXIgbGV4aWNhbEhhbmRsZXIgPSB4bWxSZWFkZXIubGV4aWNhbEhhbmRsZXI7CisgICAgICAgIGlmIChsZXhpY2FsSGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgICAgICBsZXhpY2FsSGFuZGxlci5lbmREVEQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qcGFja2FnZSovIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQorICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIENvbnRlbnRIYW5kbGVyIGNvbnRlbnRIYW5kbGVyID0geG1sUmVhZGVyLmNvbnRlbnRIYW5kbGVyOworICAgICAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgY29udGVudEhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKnBhY2thZ2UqLyB2b2lkIG5vdGF0aW9uRGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICBEVERIYW5kbGVyIGR0ZEhhbmRsZXIgPSB4bWxSZWFkZXIuZHRkSGFuZGxlcjsKKyAgICAgICAgaWYgKGR0ZEhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgZHRkSGFuZGxlci5ub3RhdGlvbkRlY2wobmFtZSwgcHVibGljSWQsIHN5c3RlbUlkKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qcGFja2FnZSovIHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIG5vdGF0aW9uTmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIERUREhhbmRsZXIgZHRkSGFuZGxlciA9IHhtbFJlYWRlci5kdGRIYW5kbGVyOworICAgICAgICBpZiAoZHRkSGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgICAgICBkdGRIYW5kbGVyLnVucGFyc2VkRW50aXR5RGVjbChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQsIG5vdGF0aW9uTmFtZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBIYW5kbGVzIGFuIGV4dGVybmFsIGVudGl0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb250ZXh0IHRvIGJlIHBhc3NlZCBiYWNrIHRvIEV4cGF0IHdoZW4gd2UgcGFyc2UgdGhlIGVudGl0eQorICAgICAqIEBwYXJhbSBwdWJsaWNJZCB0aGUgcHVibGljSWQgb2YgdGhlIGVudGl0eQorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCB0aGUgc3lzdGVtSWQgb2YgdGhlIGVudGl0eQorICAgICAqLworICAgIC8qcGFja2FnZSovIHZvaWQgaGFuZGxlRXh0ZXJuYWxFbnRpdHkoU3RyaW5nIGNvbnRleHQsIFN0cmluZyBwdWJsaWNJZCwKKyAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBFbnRpdHlSZXNvbHZlciBlbnRpdHlSZXNvbHZlciA9IHhtbFJlYWRlci5lbnRpdHlSZXNvbHZlcjsKKyAgICAgICAgaWYgKGVudGl0eVJlc29sdmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIFRoZSBzcGVjLiBpcyB0ZXJyaWJseSB1bmRlci1zcGVjaWZpZWQgaGVyZS4gSXQgc2F5cyB0aGF0IGlmIHRoZQorICAgICAgICAgKiBzeXN0ZW1JZCBpcyBhIFVSTCwgd2Ugc2hvdWxkIHRyeSB0byByZXNvbHZlIGl0LCBidXQgaXQgZG9lc24ndAorICAgICAgICAgKiBzcGVjaWZ5IGhvdyB0byB0ZWxsIHdoZXRoZXIgb3Igbm90IHRoZSBzeXN0ZW1JZCBpcyBhIFVSTCBsZXQgYWxvbmUKKyAgICAgICAgICogaG93IHRvIHJlc29sdmUgaXQuCisgICAgICAgICAqCisgICAgICAgICAqIE90aGVyIGltcGxlbWVudGF0aW9ucyBkbyB2YXJpb3VzIGluc2FuZSB0aGluZ3MuIFdlIHRyeSB0byBrZWVwIGl0CisgICAgICAgICAqIHNpbXBsZTogaWYgdGhlIHN5c3RlbUlkIHBhcnNlcyBhcyBhIFVSSSBhbmQgaXQncyByZWxhdGl2ZSwgd2UgdHJ5IHRvCisgICAgICAgICAqIHJlc29sdmUgaXQgYWdhaW5zdCB0aGUgcGFyZW50IGRvY3VtZW50J3Mgc3lzdGVtSWQuIElmIGFueXRoaW5nIGdvZXMKKyAgICAgICAgICogd3JvbmcsIHdlIGdvIHdpdGggdGhlIG9yaWdpbmFsIHN5c3RlbUlkLiBJZiBjcmF6eWJvYiBoYWQgZGVzaWduZWQKKyAgICAgICAgICogdGhlIEFQSSwgaGUgd291bGQgaGF2ZSBsZWZ0IGFsbCByZXNvbHZpbmcgdG8gdGhlIEVudGl0eVJlc29sdmVyLgorICAgICAgICAgKi8KKyAgICAgICAgaWYgKHRoaXMuc3lzdGVtSWQgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBVUkkgc3lzdGVtVXJpID0gbmV3IFVSSShzeXN0ZW1JZCk7CisgICAgICAgICAgICAgICAgaWYgKCFzeXN0ZW1VcmkuaXNBYnNvbHV0ZSgpICYmICFzeXN0ZW1VcmkuaXNPcGFxdWUoKSkgeworICAgICAgICAgICAgICAgICAgICAvLyBJdCBjb3VsZCBiZSByZWxhdGl2ZSAob3IgaXQgbWF5IG5vdCBiZSBhIFVSSSBhdCBhbGwhKQorICAgICAgICAgICAgICAgICAgICBVUkkgYmFzZVVyaSA9IG5ldyBVUkkodGhpcy5zeXN0ZW1JZCk7CisgICAgICAgICAgICAgICAgICAgIHN5c3RlbVVyaSA9IGJhc2VVcmkucmVzb2x2ZShzeXN0ZW1VcmkpOworCisgICAgICAgICAgICAgICAgICAgIC8vIFJlcGxhY2Ugc3lzdGVtSWQgdy8gcmVzb2x2ZWQgVVJJCisgICAgICAgICAgICAgICAgICAgIHN5c3RlbUlkID0gc3lzdGVtVXJpLnRvU3RyaW5nKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ubG9nSSgiQ291bGQgbm90IHJlc29sdmUgJyIgKyBzeXN0ZW1JZCArICInIHJlbGF0aXZlIHRvIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAiICciICsgdGhpcy5zeXN0ZW1JZCArICInIGF0ICIgKyBsb2NhdG9yLCBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIElucHV0U291cmNlIGlucHV0U291cmNlID0gZW50aXR5UmVzb2x2ZXIucmVzb2x2ZUVudGl0eSgKKyAgICAgICAgICAgICAgICBwdWJsaWNJZCwgc3lzdGVtSWQpOworICAgICAgICBpZiAoaW5wdXRTb3VyY2UgPT0gbnVsbCkgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFRoZSBzcGVjLiBhY3R1YWxseSBzYXlzIHRoYXQgd2Ugc2hvdWxkIHRyeSB0byB0cmVhdCBzeXN0ZW1JZAorICAgICAgICAgICAgICogYXMgYSBVUkwgYW5kIGRvd25sb2FkIGFuZCBwYXJzZSBpdHMgY29udGVudHMgaGVyZSwgYnV0IGFuCisgICAgICAgICAgICAgKiBlbnRpdHkgcmVzb2x2ZXIgY2FuIGVhc2lseSBhY2NvbXBsaXNoIHRoZSBzYW1lIGJ5IHJldHVybmluZworICAgICAgICAgICAgICogbmV3IElucHV0U291cmNlKHN5c3RlbUlkKS4KKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBEb3dubG9hZGluZyBleHRlcm5hbCBlbnRpdGllcyBieSBkZWZhdWx0IHdvdWxkIHJlc3VsdCBpbiBzZXZlcmFsCisgICAgICAgICAgICAgKiB1bndhbnRlZCBEVEQgZG93bmxvYWRzLCBub3QgdG8gbWVudGlvbiBwb3NlIGEgc2VjdXJpdHkgcmlzaworICAgICAgICAgICAgICogd2hlbiBwYXJzaW5nIHVudHJ1c3RlZCBYTUwgLS0gc2VlIGZvciBleGFtcGxlCisgICAgICAgICAgICAgKiBodHRwOi8vYXJjaGl2ZS5jZXJ0LnVuaS1zdHV0dGdhcnQuZGUvYnVndHJhcS8yMDAyLzEwL21zZzAwNDIxLmh0bWwgLS0KKyAgICAgICAgICAgICAqIHNvIHdlIGp1c3QgZG8gbm90aGluZyBpbnN0ZWFkLiBUaGlzIGFsc28gZW5hYmxlcyB0aGUgdXNlciB0bworICAgICAgICAgICAgICogb3B0IG91dCBvZiBlbnRpdHkgcGFyc2luZyB3aGVuIHVzaW5nCisgICAgICAgICAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcn0sIHNvbWV0aGluZyB0aGF0CisgICAgICAgICAgICAgKiB3b3VsZG4ndCBiZSBwb3NzaWJsZSBvdGhlcndpc2UuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBlbmNvZGluZyA9IHBpY2tFbmNvZGluZyhpbnB1dFNvdXJjZSk7CisgICAgICAgIGludCBwb2ludGVyID0gY3JlYXRlRW50aXR5UGFyc2VyKHRoaXMucG9pbnRlciwgY29udGV4dCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnRpdHlQYXJzZXIgZW50aXR5UGFyc2VyID0gbmV3IEVudGl0eVBhcnNlcihlbmNvZGluZywgeG1sUmVhZGVyLAorICAgICAgICAgICAgICAgICAgICBwb2ludGVyLCBpbnB1dFNvdXJjZS5nZXRQdWJsaWNJZCgpLAorICAgICAgICAgICAgICAgICAgICBpbnB1dFNvdXJjZS5nZXRTeXN0ZW1JZCgpKTsKKworICAgICAgICAgICAgcGFyc2VFeHRlcm5hbEVudGl0eShlbnRpdHlQYXJzZXIsIGlucHV0U291cmNlKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHJlbGVhc2VQYXJzZXIocG9pbnRlcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQaWNrcyBhbiBlbmNvZGluZyBmb3IgYW4gZXh0ZXJuYWwgZW50aXR5LiBEZWZhdWx0cyB0byBVVEYtOC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBwaWNrRW5jb2RpbmcoSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UpIHsKKyAgICAgICAgUmVhZGVyIHJlYWRlciA9IGlucHV0U291cmNlLmdldENoYXJhY3RlclN0cmVhbSgpOworICAgICAgICBpZiAocmVhZGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBDSEFSQUNURVJfRU5DT0RJTkc7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgZW5jb2RpbmcgPSBpbnB1dFNvdXJjZS5nZXRFbmNvZGluZygpOworICAgICAgICByZXR1cm4gZW5jb2RpbmcgPT0gbnVsbCA/IERFRkFVTFRfRU5DT0RJTkcgOiBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgdGhlIHRoZSBleHRlcm5hbCBlbnRpdHkgcHJvdmlkZWQgYnkgdGhlIGlucHV0IHNvdXJjZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcGFyc2VFeHRlcm5hbEVudGl0eShFeHBhdFBhcnNlciBlbnRpdHlQYXJzZXIsCisgICAgICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSkgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24geworICAgICAgICAvKgorICAgICAgICAgKiBFeHBhdCBjb21wbGFpbnMgaWYgdGhlIGV4dGVybmFsIGVudGl0eSBpc24ndCB3cmFwcGVkIHdpdGggYSByb290CisgICAgICAgICAqIGVsZW1lbnQgc28gd2UgYWRkIG9uZSBhbmQgaWdub3JlIGl0IGxhdGVyIG9uIGR1cmluZyBwYXJzaW5nLgorICAgICAgICAgKi8KKworICAgICAgICAvLyBUcnkgdGhlIGNoYXJhY3RlciBzdHJlYW0uCisgICAgICAgIFJlYWRlciByZWFkZXIgPSBpbnB1dFNvdXJjZS5nZXRDaGFyYWN0ZXJTdHJlYW0oKTsKKyAgICAgICAgaWYgKHJlYWRlciAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGVudGl0eVBhcnNlci5hcHBlbmQoIjxleHRlcm5hbEVudGl0eT4iKTsKKyAgICAgICAgICAgICAgICBlbnRpdHlQYXJzZXIucGFyc2VGcmFnbWVudChyZWFkZXIpOworICAgICAgICAgICAgICAgIGVudGl0eVBhcnNlci5hcHBlbmQoIjwvZXh0ZXJuYWxFbnRpdHk+Iik7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIElvVXRpbHMuY2xvc2VRdWlldGx5KHJlYWRlcik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICAvLyBUcnkgdGhlIGJ5dGUgc3RyZWFtLgorICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IGlucHV0U291cmNlLmdldEJ5dGVTdHJlYW0oKTsKKyAgICAgICAgaWYgKGluICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZW50aXR5UGFyc2VyLmFwcGVuZCgiPGV4dGVybmFsRW50aXR5PiIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRCeXRlcyhlbnRpdHlQYXJzZXIuZW5jb2RpbmcpKTsKKyAgICAgICAgICAgICAgICBlbnRpdHlQYXJzZXIucGFyc2VGcmFnbWVudChpbik7CisgICAgICAgICAgICAgICAgZW50aXR5UGFyc2VyLmFwcGVuZCgiPC9leHRlcm5hbEVudGl0eT4iCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0Qnl0ZXMoZW50aXR5UGFyc2VyLmVuY29kaW5nKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIElvVXRpbHMuY2xvc2VRdWlldGx5KGluKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIE1ha2Ugc3VyZSB3ZSB1c2UgdGhlIHVzZXItcHJvdmlkZWQgc3lzdGVtSWQuCisgICAgICAgIFN0cmluZyBzeXN0ZW1JZCA9IGlucHV0U291cmNlLmdldFN5c3RlbUlkKCk7CisgICAgICAgIGlmIChzeXN0ZW1JZCA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBUT0RPOiBXZSBjb3VsZCBqdXN0IHRyeSBvdXIgc3lzdGVtSWQgaGVyZS4KKyAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiTm8gaW5wdXQgc3BlY2lmaWVkLiIsIGxvY2F0b3IpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVHJ5IHRoZSBzeXN0ZW0gaWQuCisgICAgICAgIGluID0gb3BlblVybChzeXN0ZW1JZCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbnRpdHlQYXJzZXIuYXBwZW5kKCI8ZXh0ZXJuYWxFbnRpdHk+IgorICAgICAgICAgICAgICAgICAgICAuZ2V0Qnl0ZXMoZW50aXR5UGFyc2VyLmVuY29kaW5nKSk7CisgICAgICAgICAgICBlbnRpdHlQYXJzZXIucGFyc2VGcmFnbWVudChpbik7CisgICAgICAgICAgICBlbnRpdHlQYXJzZXIuYXBwZW5kKCI8L2V4dGVybmFsRW50aXR5PiIKKyAgICAgICAgICAgICAgICAgICAgLmdldEJ5dGVzKGVudGl0eVBhcnNlci5lbmNvZGluZykpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkoaW4pOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5hdGl2ZSBlbnRpdHkgcGFyc2VyLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmVudFBvaW50ZXIgcG9pbnRlciB0byBwYXJlbnQgRXhwYXQgcGFyc2VyCisgICAgICogQHBhcmFtIGNvbnRleHQgcGFzc2VkIHRvIHtAbGluayAjaGFuZGxlRXh0ZXJuYWxFbnRpdHl9CisgICAgICogQHJldHVybiBwb2ludGVyIHRvIG5hdGl2ZSBwYXJzZXIKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IGNyZWF0ZUVudGl0eVBhcnNlcihpbnQgcGFyZW50UG9pbnRlciwgU3RyaW5nIGNvbnRleHQpOworCisgICAgLyoqCisgICAgICogQXBwZW5kcyBwYXJ0IG9mIGFuIFhNTCBkb2N1bWVudC4gVGhpcyBwYXJzZXIgd2lsbCBwYXJzZSB0aGUgZ2l2ZW4gWE1MIHRvCisgICAgICogdGhlIGV4dGVudCBwb3NzaWJsZSBhbmQgZGlzcGF0Y2ggdG8gdGhlIGFwcHJvcHJpYXRlIG1ldGhvZHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0geG1sIGEgd2hvbGUgb3IgcGFydGlhbCBzbmlwcGV0IG9mIFhNTAorICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycyBkdXJpbmcgcGFyc2luZworICAgICAqLworICAgIC8qcGFja2FnZSovIHZvaWQgYXBwZW5kKFN0cmluZyB4bWwpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXBwZW5kU3RyaW5nKHRoaXMucG9pbnRlciwgeG1sLCBmYWxzZSk7CisgICAgICAgIH0gY2F0Y2ggKEV4cGF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSwgdGhpcy5sb2NhdG9yKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgbmF0aXZlIHZvaWQgYXBwZW5kU3RyaW5nKGludCBwb2ludGVyLCBTdHJpbmcgeG1sLCBib29sZWFuIGlzRmluYWwpCisgICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBFeHBhdEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgcGFydCBvZiBhbiBYTUwgZG9jdW1lbnQuIFRoaXMgcGFyc2VyIHdpbGwgcGFyc2UgdGhlIGdpdmVuIFhNTCB0bworICAgICAqIHRoZSBleHRlbnQgcG9zc2libGUgYW5kIGRpc3BhdGNoIHRvIHRoZSBhcHByb3ByaWF0ZSBtZXRob2RzLgorICAgICAqCisgICAgICogQHBhcmFtIHhtbCBhIHdob2xlIG9yIHBhcnRpYWwgc25pcHBldCBvZiBYTUwKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IGludG8gdGhlIGNoYXJbXQorICAgICAqIEBwYXJhbSBsZW5ndGggb2YgY2hhcmFjdGVycyB0byB1c2UKKyAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIHBhcnNpbmcKKyAgICAgKi8KKyAgICAvKnBhY2thZ2UqLyB2b2lkIGFwcGVuZChjaGFyW10geG1sLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcHBlbmRDaGFycyh0aGlzLnBvaW50ZXIsIHhtbCwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgICB9IGNhdGNoIChFeHBhdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCksIHRoaXMubG9jYXRvcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIG5hdGl2ZSB2b2lkIGFwcGVuZENoYXJzKGludCBwb2ludGVyLCBjaGFyW10geG1sLCBpbnQgb2Zmc2V0LAorICAgICAgICAgICAgaW50IGxlbmd0aCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgRXhwYXRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmRzIHBhcnQgb2YgYW4gWE1MIGRvY3VtZW50LiBUaGlzIHBhcnNlciB3aWxsIHBhcnNlIHRoZSBnaXZlbiBYTUwgdG8KKyAgICAgKiB0aGUgZXh0ZW50IHBvc3NpYmxlIGFuZCBkaXNwYXRjaCB0byB0aGUgYXBwcm9wcmlhdGUgbWV0aG9kcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB4bWwgYSB3aG9sZSBvciBwYXJ0aWFsIHNuaXBwZXQgb2YgWE1MCisgICAgICogQHRocm93cyBTQVhFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyBwYXJzaW5nCisgICAgICovCisgICAgLypwYWNrYWdlKi8gdm9pZCBhcHBlbmQoYnl0ZVtdIHhtbCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIGFwcGVuZCh4bWwsIDAsIHhtbC5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgcGFydCBvZiBhbiBYTUwgZG9jdW1lbnQuIFRoaXMgcGFyc2VyIHdpbGwgcGFyc2UgdGhlIGdpdmVuIFhNTCB0bworICAgICAqIHRoZSBleHRlbnQgcG9zc2libGUgYW5kIGRpc3BhdGNoIHRvIHRoZSBhcHByb3ByaWF0ZSBtZXRob2RzLgorICAgICAqCisgICAgICogQHBhcmFtIHhtbCBhIHdob2xlIG9yIHBhcnRpYWwgc25pcHBldCBvZiBYTUwKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IGludG8gdGhlIGJ5dGVbXQorICAgICAqIEBwYXJhbSBsZW5ndGggb2YgYnl0ZXMgdG8gdXNlCisgICAgICogQHRocm93cyBTQVhFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyBwYXJzaW5nCisgICAgICovCisgICAgLypwYWNrYWdlKi8gdm9pZCBhcHBlbmQoYnl0ZVtdIHhtbCwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXBwZW5kQnl0ZXModGhpcy5wb2ludGVyLCB4bWwsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhwYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpLCB0aGlzLmxvY2F0b3IpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBuYXRpdmUgdm9pZCBhcHBlbmRCeXRlcyhpbnQgcG9pbnRlciwgYnl0ZVtdIHhtbCwgaW50IG9mZnNldCwKKyAgICAgICAgICAgIGludCBsZW5ndGgpIHRocm93cyBTQVhFeGNlcHRpb24sIEV4cGF0RXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUGFyc2VzIGFuIFhNTCBkb2N1bWVudCBmcm9tIHRoZSBnaXZlbiBpbnB1dCBzdHJlYW0uCisgICAgICovCisgICAgLypwYWNrYWdlKi8gdm9pZCBwYXJzZURvY3VtZW50KElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgICAgICBTQVhFeGNlcHRpb24geworICAgICAgICBzdGFydERvY3VtZW50KCk7CisgICAgICAgIHBhcnNlRnJhZ21lbnQoaW4pOworICAgICAgICBmaW5pc2goKTsKKyAgICAgICAgZW5kRG9jdW1lbnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgYW4gWE1MIERvY3VtZW50IGZyb20gdGhlIGdpdmVuIHJlYWRlci4KKyAgICAgKi8KKyAgICAvKnBhY2thZ2UqLyB2b2lkIHBhcnNlRG9jdW1lbnQoUmVhZGVyIGluKSB0aHJvd3MgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIHN0YXJ0RG9jdW1lbnQoKTsKKyAgICAgICAgcGFyc2VGcmFnbWVudChpbik7CisgICAgICAgIGZpbmlzaCgpOworICAgICAgICBlbmREb2N1bWVudCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyBYTUwgZnJvbSB0aGUgZ2l2ZW4gUmVhZGVyLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwYXJzZUZyYWdtZW50KFJlYWRlciBpbikgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24geworICAgICAgICBjaGFyW10gYnVmZmVyID0gbmV3IGNoYXJbQlVGRkVSX1NJWkUgLyAyXTsKKyAgICAgICAgaW50IGxlbmd0aDsKKyAgICAgICAgd2hpbGUgKChsZW5ndGggPSBpbi5yZWFkKGJ1ZmZlcikpICE9IC0xKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGFwcGVuZENoYXJzKHRoaXMucG9pbnRlciwgYnVmZmVyLCAwLCBsZW5ndGgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhwYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSwgbG9jYXRvcik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgWE1MIGZyb20gdGhlIGdpdmVuIGlucHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcGFyc2VGcmFnbWVudChJbnB1dFN0cmVhbSBpbikKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlW0JVRkZFUl9TSVpFXTsKKyAgICAgICAgaW50IGxlbmd0aDsKKyAgICAgICAgd2hpbGUgKChsZW5ndGggPSBpbi5yZWFkKGJ1ZmZlcikpICE9IC0xKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGFwcGVuZEJ5dGVzKHRoaXMucG9pbnRlciwgYnVmZmVyLCAwLCBsZW5ndGgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhwYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSwgdGhpcy5sb2NhdG9yKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzdGFydERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIENvbnRlbnRIYW5kbGVyIGNvbnRlbnRIYW5kbGVyID0geG1sUmVhZGVyLmNvbnRlbnRIYW5kbGVyOworICAgICAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgY29udGVudEhhbmRsZXIuc2V0RG9jdW1lbnRMb2NhdG9yKHRoaXMubG9jYXRvcik7CisgICAgICAgICAgICBjb250ZW50SGFuZGxlci5zdGFydERvY3VtZW50KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZW5kRG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgQ29udGVudEhhbmRsZXIgY29udGVudEhhbmRsZXI7CisgICAgICAgIGNvbnRlbnRIYW5kbGVyID0geG1sUmVhZGVyLmNvbnRlbnRIYW5kbGVyOworICAgICAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgY29udGVudEhhbmRsZXIuZW5kRG9jdW1lbnQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlIHRoYXQgd2UncmUgZmluaXNoZWQgcGFyc2luZy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIGlmIHRoZSB4bWwgaXMgaW5jb21wbGV0ZQorICAgICAqLworICAgIC8qcGFja2FnZSovIHZvaWQgZmluaXNoKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcHBlbmRTdHJpbmcodGhpcy5wb2ludGVyLCAiIiwgdHJ1ZSk7CisgICAgICAgIH0gY2F0Y2ggKEV4cGF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSwgdGhpcy5sb2NhdG9yKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICh0aGlzLnBvaW50ZXIgIT0gMCkgeworICAgICAgICAgICAgICAgIHJlbGVhc2UodGhpcy5wb2ludGVyKTsKKyAgICAgICAgICAgICAgICB0aGlzLnBvaW50ZXIgPSAwOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc3VwZXIuZmluYWxpemUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbGVhc2VzIGFsbCBuYXRpdmUgb2JqZWN0cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIG5hdGl2ZSB2b2lkIHJlbGVhc2UoaW50IHBvaW50ZXIpOworCisgICAgLyoqCisgICAgICogUmVsZWFzZXMgbmF0aXZlIHBhcnNlciBvbmx5LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIHJlbGVhc2VQYXJzZXIoaW50IHBvaW50ZXIpOworCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZSBzdGF0aWMgcmVzb3VyY2VzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSB2b2lkIHN0YXRpY0luaXRpYWxpemUoU3RyaW5nIGVtcHR5U3RyaW5nKTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIHN0YXRpY0luaXRpYWxpemUoIiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGN1cnJlbnQgbGluZSBudW1iZXIgd2l0aGluIHRoZSBYTUwgZmlsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBsaW5lKCkgeworICAgICAgICByZXR1cm4gbGluZSh0aGlzLnBvaW50ZXIpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBpbnQgbGluZShpbnQgcG9pbnRlcik7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjdXJyZW50IGNvbHVtbiBudW1iZXIgd2l0aGluIHRoZSBYTUwgZmlsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBjb2x1bW4oKSB7CisgICAgICAgIHJldHVybiBjb2x1bW4odGhpcy5wb2ludGVyKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IGNvbHVtbihpbnQgcG9pbnRlcik7CisKKyAgICAvKioKKyAgICAgKiBDbG9uZXMgdGhlIGN1cnJlbnQgYXR0cmlidXRlcyBzbyB0aGV5IGNhbiBiZSB1c2VkIG91dHNpZGUgb2YKKyAgICAgKiBzdGFydEVsZW1lbnQoKS4KKyAgICAgKi8KKyAgICAvKnBhY2thZ2UqLyBBdHRyaWJ1dGVzIGNsb25lQXR0cmlidXRlcygpIHsKKyAgICAgICAgaWYgKCFpblN0YXJ0RWxlbWVudCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihPVVRTSURFX1NUQVJUX0VMRU1FTlQpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGF0dHJpYnV0ZUNvdW50ID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBDbG9uZWRBdHRyaWJ1dGVzLkVNUFRZOworICAgICAgICB9CisKKyAgICAgICAgaW50IGNsb25lUG9pbnRlcgorICAgICAgICAgICAgICAgID0gY2xvbmVBdHRyaWJ1dGVzKHRoaXMuYXR0cmlidXRlUG9pbnRlciwgdGhpcy5hdHRyaWJ1dGVDb3VudCk7CisgICAgICAgIHJldHVybiBuZXcgQ2xvbmVkQXR0cmlidXRlcyhwb2ludGVyLCBjbG9uZVBvaW50ZXIsIGF0dHJpYnV0ZUNvdW50KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IGNsb25lQXR0cmlidXRlcyhpbnQgcG9pbnRlciwgaW50IGF0dHJpYnV0ZUNvdW50KTsKKworICAgIC8qKgorICAgICAqIFVzZWQgZm9yIGNsb25lZCBhdHRyaWJ1dGVzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIENsb25lZEF0dHJpYnV0ZXMgZXh0ZW5kcyBFeHBhdEF0dHJpYnV0ZXMgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEF0dHJpYnV0ZXMgRU1QVFkgPSBuZXcgQ2xvbmVkQXR0cmlidXRlcygwLCAwLCAwKTsKKworICAgICAgICBwcml2YXRlIGZpbmFsIGludCBwYXJzZXJQb2ludGVyOworICAgICAgICBwcml2YXRlIGludCBwb2ludGVyOworICAgICAgICBwcml2YXRlIGZpbmFsIGludCBsZW5ndGg7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbnN0cnVjdHMgYSBKYXZhIHdyYXBwZXIgZm9yIG5hdGl2ZSBhdHRyaWJ1dGVzLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gcGFyc2VyUG9pbnRlciBwb2ludGVyIHRvIHRoZSBwYXJzZSwgY2FuIGJlIDAgaWYgbGVuZ3RoIGlzIDAuCisgICAgICAgICAqIEBwYXJhbSBwb2ludGVyIHBvaW50ZXIgdG8gdGhlIGF0dHJpYnV0ZXMgYXJyYXksIGNhbiBiZSAwIGlmIHRoZQorICAgICAgICAgKiAgbGVuZ3RoIGlzIDAuCisgICAgICAgICAqIEBwYXJhbSBsZW5ndGggbnVtYmVyIG9mIGF0dHJpYnV0ZXMKKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgQ2xvbmVkQXR0cmlidXRlcyhpbnQgcGFyc2VyUG9pbnRlciwgaW50IHBvaW50ZXIsIGludCBsZW5ndGgpIHsKKyAgICAgICAgICAgIHRoaXMucGFyc2VyUG9pbnRlciA9IHBhcnNlclBvaW50ZXI7CisgICAgICAgICAgICB0aGlzLnBvaW50ZXIgPSBwb2ludGVyOworICAgICAgICAgICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBnZXRQYXJzZXJQb2ludGVyKCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VyUG9pbnRlcjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IGdldFBvaW50ZXIoKSB7CisgICAgICAgICAgICByZXR1cm4gcG9pbnRlcjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKKyAgICAgICAgICAgIHJldHVybiBsZW5ndGg7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmIChwb2ludGVyICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgZnJlZUF0dHJpYnV0ZXMocG9pbnRlcik7CisgICAgICAgICAgICAgICAgICAgIHBvaW50ZXIgPSAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgc3VwZXIuZmluYWxpemUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgRXhwYXRMb2NhdG9yIGltcGxlbWVudHMgTG9jYXRvciB7CisKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBwdWJsaWNJZDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7CisgICAgICAgICAgICByZXR1cm4gc3lzdGVtSWQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKSB7CisgICAgICAgICAgICByZXR1cm4gbGluZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIoKSB7CisgICAgICAgICAgICByZXR1cm4gY29sdW1uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiAiTG9jYXRvcltwdWJsaWNJZDogIiArIHB1YmxpY0lkICsgIiwgc3lzdGVtSWQ6ICIgKyBzeXN0ZW1JZAorICAgICAgICAgICAgICAgICsgIiwgbGluZTogIiArIGdldExpbmVOdW1iZXIoKQorICAgICAgICAgICAgICAgICsgIiwgY29sdW1uOiAiICsgZ2V0Q29sdW1uTnVtYmVyKCkgKyAiXSI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdHRyaWJ1dGVzIHRoYXQgYXJlIG9ubHkgdmFsaWQgZHVyaW5nIHN0YXJ0RWxlbWVudCgpLgorICAgICAqLworICAgIHByaXZhdGUgY2xhc3MgQ3VycmVudEF0dHJpYnV0ZXMgZXh0ZW5kcyBFeHBhdEF0dHJpYnV0ZXMgeworCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IGdldFBhcnNlclBvaW50ZXIoKSB7CisgICAgICAgICAgICByZXR1cm4gcG9pbnRlcjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IGdldFBvaW50ZXIoKSB7CisgICAgICAgICAgICBpZiAoIWluU3RhcnRFbGVtZW50KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihPVVRTSURFX1NUQVJUX0VMRU1FTlQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZVBvaW50ZXI7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7CisgICAgICAgICAgICBpZiAoIWluU3RhcnRFbGVtZW50KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihPVVRTSURFX1NUQVJUX0VMRU1FTlQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZUNvdW50OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5jbHVkZXMgbGluZSBhbmQgY29sdW1uIGluIHRoZSBtZXNzYWdlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFBhcnNlRXhjZXB0aW9uIGV4dGVuZHMgU0FYUGFyc2VFeGNlcHRpb24geworCisgICAgICAgIHByaXZhdGUgUGFyc2VFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIExvY2F0b3IgbG9jYXRvcikgeworICAgICAgICAgICAgc3VwZXIobWFrZU1lc3NhZ2UobWVzc2FnZSwgbG9jYXRvciksIGxvY2F0b3IpOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIG1ha2VNZXNzYWdlKFN0cmluZyBtZXNzYWdlLCBMb2NhdG9yIGxvY2F0b3IpIHsKKyAgICAgICAgICAgIHJldHVybiBtYWtlTWVzc2FnZShtZXNzYWdlLCBsb2NhdG9yLmdldExpbmVOdW1iZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgbG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKSk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgbWFrZU1lc3NhZ2UoCisgICAgICAgICAgICAgICAgU3RyaW5nIG1lc3NhZ2UsIGludCBsaW5lLCBpbnQgY29sdW1uKSB7CisgICAgICAgICAgICByZXR1cm4gIkF0IGxpbmUgIiArIGxpbmUgKyAiLCBjb2x1bW4gIgorICAgICAgICAgICAgICAgICAgICArIGNvbHVtbiArICI6ICIgKyBtZXNzYWdlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogT3BlbnMgYW4gSW5wdXRTdHJlYW0gZm9yIHRoZSBnaXZlbiBVUkwuCisgICAgICovCisgICAgLypwYWNrYWdlKi8gc3RhdGljIElucHV0U3RyZWFtIG9wZW5VcmwoU3RyaW5nIHVybCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFVSTENvbm5lY3Rpb24gdXJsQ29ubmVjdGlvbiA9IG5ldyBVUkwodXJsKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICAgICAgdXJsQ29ubmVjdGlvbi5zZXRDb25uZWN0VGltZW91dChUSU1FT1VUKTsKKyAgICAgICAgICAgIHVybENvbm5lY3Rpb24uc2V0UmVhZFRpbWVvdXQoVElNRU9VVCk7CisgICAgICAgICAgICB1cmxDb25uZWN0aW9uLnNldERvSW5wdXQodHJ1ZSk7CisgICAgICAgICAgICB1cmxDb25uZWN0aW9uLnNldERvT3V0cHV0KGZhbHNlKTsKKyAgICAgICAgICAgIHJldHVybiB1cmxDb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBJT0V4Y2VwdGlvbiBpb2UgPSBuZXcgSU9FeGNlcHRpb24oIkNvdWxkbid0IG9wZW4gIiArIHVybCk7CisgICAgICAgICAgICBpb2UuaW5pdENhdXNlKGUpOworICAgICAgICAgICAgdGhyb3cgaW9lOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIGFuIGV4dGVybmFsIGVudGl0eS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBFbnRpdHlQYXJzZXIgZXh0ZW5kcyBFeHBhdFBhcnNlciB7CisKKyAgICAgICAgcHJpdmF0ZSBpbnQgZGVwdGggPSAwOworCisgICAgICAgIHByaXZhdGUgRW50aXR5UGFyc2VyKFN0cmluZyBlbmNvZGluZywgRXhwYXRSZWFkZXIgeG1sUmVhZGVyLAorICAgICAgICAgICAgICAgIGludCBwb2ludGVyLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkgeworICAgICAgICAgICAgc3VwZXIoZW5jb2RpbmcsIHhtbFJlYWRlciwgcG9pbnRlciwgcHVibGljSWQsIHN5c3RlbUlkKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUsCisgICAgICAgICAgICAgICAgaW50IGF0dHJpYnV0ZVBvaW50ZXIsIGludCBhdHRyaWJ1dGVDb3VudCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogU2tpcCB0b3Btb3N0IGVsZW1lbnQgZ2VuZXJhdGVkIGJ5IG91ciB3b3JrYXJvdW5kIGluCisgICAgICAgICAgICAgKiB7QGxpbmsgI2hhbmRsZUV4dGVybmFsRW50aXR5fS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaWYgKGRlcHRoKysgPiAwKSB7CisgICAgICAgICAgICAgICAgc3VwZXIuc3RhcnRFbGVtZW50KHVyaSwgbG9jYWxOYW1lLCBxTmFtZSwgYXR0cmlidXRlUG9pbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZUNvdW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lKQorICAgICAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKC0tZGVwdGggPiAwKSB7CisgICAgICAgICAgICAgICAgc3VwZXIuZW5kRWxlbWVudCh1cmksIGxvY2FsTmFtZSwgcU5hbWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJGaW5hbGl6ZURvZXNudENhbGxTdXBlckZpbmFsaXplIikKKyAgICAgICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogRG9uJ3QgcmVsZWFzZSBvdXIgbmF0aXZlIHJlc291cmNlcy4gV2UgZG8gc28gZXhwbGljaXRseSBpbgorICAgICAgICAgICAgICoge0BsaW5rICNoYW5kbGVFeHRlcm5hbEVudGl0eX0gYW5kIHdlIGRvbid0IHdhbnQgdG8gcmVsZWFzZSB0aGUKKyAgICAgICAgICAgICAqIHBhcnNpbmcgY29udGV4dC0tb3VyIHBhcmVudCBpcyB1c2luZyBpdC4KKyAgICAgICAgICAgICAqLworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvRXhwYXRSZWFkZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL0V4cGF0UmVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTBmYTE4MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL0V4cGF0UmVhZGVyLmphdmEKQEAgLTAsMCArMSwzMjcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bWw7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CitpbXBvcnQgbGliY29yZS5pby5Jb1V0aWxzOworaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkRUREhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOworCisvKioKKyAqIFNBWCB3cmFwcGVyIGFyb3VuZCBFeHBhdC4gSW50ZXJucyBzdHJpbmdzLiBEb2VzIG5vdCBzdXBwb3J0IHZhbGlkYXRpb24uCisgKiBEb2VzIG5vdCBzdXBwb3J0IHtAbGluayBEVERIYW5kbGVyfS4KKyAqLworcHVibGljIGNsYXNzIEV4cGF0UmVhZGVyIGltcGxlbWVudHMgWE1MUmVhZGVyIHsKKyAgICAvKgorICAgICAqIEV4cGF0UGFyc2VyIGFjY2Vzc2VzIHRoZXNlIGZpZWxkcyBkaXJlY3RseSBkdXJpbmcgcGFyc2luZy4gVGhlIHVzZXIKKyAgICAgKiBzaG91bGQgYmUgYWJsZSB0byBzYWZlbHkgY2hhbmdlIHRoZW0gZHVyaW5nIHBhcnNpbmcuCisgICAgICovCisgICAgLypwYWNrYWdlKi8gQ29udGVudEhhbmRsZXIgY29udGVudEhhbmRsZXI7CisgICAgLypwYWNrYWdlKi8gRFRESGFuZGxlciBkdGRIYW5kbGVyOworICAgIC8qcGFja2FnZSovIEVudGl0eVJlc29sdmVyIGVudGl0eVJlc29sdmVyOworICAgIC8qcGFja2FnZSovIEVycm9ySGFuZGxlciBlcnJvckhhbmRsZXI7CisgICAgLypwYWNrYWdlKi8gTGV4aWNhbEhhbmRsZXIgbGV4aWNhbEhhbmRsZXI7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gcHJvY2Vzc05hbWVzcGFjZXMgPSB0cnVlOworICAgIHByaXZhdGUgYm9vbGVhbiBwcm9jZXNzTmFtZXNwYWNlUHJlZml4ZXMgPSBmYWxzZTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBMRVhJQ0FMX0hBTkRMRVJfUFJPUEVSVFkKKyAgICAgICAgICAgID0gImh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2xleGljYWwtaGFuZGxlciI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBGZWF0dXJlIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEJBU0VfVVJJID0gImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy8iOworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURBVElPTiA9IEJBU0VfVVJJICsgInZhbGlkYXRpb24iOworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFUyA9IEJBU0VfVVJJICsgIm5hbWVzcGFjZXMiOworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX1BSRUZJWEVTID0gQkFTRV9VUkkgKyAibmFtZXNwYWNlLXByZWZpeGVzIjsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNUUklOR19JTlRFUk5JTkcgPSBCQVNFX1VSSSArICJzdHJpbmctaW50ZXJuaW5nIjsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVYVEVSTkFMX0dFTkVSQUxfRU5USVRJRVMKKyAgICAgICAgICAgICAgICA9IEJBU0VfVVJJICsgImV4dGVybmFsLWdlbmVyYWwtZW50aXRpZXMiOworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVhURVJOQUxfUEFSQU1FVEVSX0VOVElUSUVTCisgICAgICAgICAgICAgICAgPSBCQVNFX1VSSSArICJleHRlcm5hbC1wYXJhbWV0ZXItZW50aXRpZXMiOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpCisgICAgICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJuYW1lID09IG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChuYW1lLmVxdWFscyhGZWF0dXJlLlZBTElEQVRJT04pCisgICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHMoRmVhdHVyZS5FWFRFUk5BTF9HRU5FUkFMX0VOVElUSUVTKQorICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzKEZlYXR1cmUuRVhURVJOQUxfUEFSQU1FVEVSX0VOVElUSUVTKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG5hbWUuZXF1YWxzKEZlYXR1cmUuTkFNRVNQQUNFUykpIHsKKyAgICAgICAgICAgIHJldHVybiBwcm9jZXNzTmFtZXNwYWNlczsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChuYW1lLmVxdWFscyhGZWF0dXJlLk5BTUVTUEFDRV9QUkVGSVhFUykpIHsKKyAgICAgICAgICAgIHJldHVybiBwcm9jZXNzTmFtZXNwYWNlUHJlZml4ZXM7CisgICAgICAgIH0KKworICAgICAgICBpZiAobmFtZS5lcXVhbHMoRmVhdHVyZS5TVFJJTkdfSU5URVJOSU5HKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKQorICAgICAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAobmFtZS5lcXVhbHMoRmVhdHVyZS5WQUxJREFUSU9OKQorICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzKEZlYXR1cmUuRVhURVJOQUxfR0VORVJBTF9FTlRJVElFUykKKyAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFscyhGZWF0dXJlLkVYVEVSTkFMX1BBUkFNRVRFUl9FTlRJVElFUykpIHsKKyAgICAgICAgICAgIGlmICh2YWx1ZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIkNhbm5vdCBlbmFibGUgIiArIG5hbWUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBEZWZhdWx0LgorICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChuYW1lLmVxdWFscyhGZWF0dXJlLk5BTUVTUEFDRVMpKSB7CisgICAgICAgICAgICBwcm9jZXNzTmFtZXNwYWNlcyA9IHZhbHVlOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG5hbWUuZXF1YWxzKEZlYXR1cmUuTkFNRVNQQUNFX1BSRUZJWEVTKSkgeworICAgICAgICAgICAgcHJvY2Vzc05hbWVzcGFjZVByZWZpeGVzID0gdmFsdWU7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAobmFtZS5lcXVhbHMoRmVhdHVyZS5TVFJJTkdfSU5URVJOSU5HKSkgeworICAgICAgICAgICAgaWYgKHZhbHVlKSB7CisgICAgICAgICAgICAgICAgLy8gRGVmYXVsdC4KKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIkNhbm5vdCBkaXNhYmxlICIgKyBuYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKG5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpCisgICAgICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJuYW1lID09IG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChuYW1lLmVxdWFscyhMRVhJQ0FMX0hBTkRMRVJfUFJPUEVSVFkpKSB7CisgICAgICAgICAgICByZXR1cm4gbGV4aWNhbEhhbmRsZXI7CisgICAgICAgIH0KKworICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKQorICAgICAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAobmFtZS5lcXVhbHMoTEVYSUNBTF9IQU5ETEVSX1BST1BFUlRZKSkgeworICAgICAgICAgICAgLy8gVGhlIG9iamVjdCBtdXN0IGltcGxlbWVudCBMZXhpY2FsSGFuZGxlcgorICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTGV4aWNhbEhhbmRsZXIgfHwgdmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRoaXMubGV4aWNhbEhhbmRsZXIgPSAoTGV4aWNhbEhhbmRsZXIpIHZhbHVlOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oInZhbHVlIGRvZXNuJ3QgaW1wbGVtZW50ICIgKworICAgICAgICAgICAgICAgICAgICAib3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyIik7CisgICAgICAgIH0KKworICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRFbnRpdHlSZXNvbHZlcihFbnRpdHlSZXNvbHZlciByZXNvbHZlcikgeworICAgICAgICB0aGlzLmVudGl0eVJlc29sdmVyID0gcmVzb2x2ZXI7CisgICAgfQorCisgICAgcHVibGljIEVudGl0eVJlc29sdmVyIGdldEVudGl0eVJlc29sdmVyKCkgeworICAgICAgICByZXR1cm4gZW50aXR5UmVzb2x2ZXI7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlcihEVERIYW5kbGVyIGR0ZEhhbmRsZXIpIHsKKyAgICAgICAgdGhpcy5kdGRIYW5kbGVyID0gZHRkSGFuZGxlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgRFRESGFuZGxlciBnZXREVERIYW5kbGVyKCkgeworICAgICAgICByZXR1cm4gZHRkSGFuZGxlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlciBoYW5kbGVyKSB7CisgICAgICAgIHRoaXMuY29udGVudEhhbmRsZXIgPSBoYW5kbGVyOworICAgIH0KKworICAgIHB1YmxpYyBDb250ZW50SGFuZGxlciBnZXRDb250ZW50SGFuZGxlcigpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuY29udGVudEhhbmRsZXI7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlciBoYW5kbGVyKSB7CisgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gaGFuZGxlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpIHsKKyAgICAgICAgcmV0dXJuIGVycm9ySGFuZGxlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGxleGljYWwgaGFuZGxlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgbGV4aWNhbCBoYW5kbGVyLCBvciBudWxsIGlmIG5vbmUgaGFzIGJlZW4gcmVnaXN0ZXJlZAorICAgICAqIEBzZWUgI3NldExleGljYWxIYW5kbGVyCisgICAgICovCisgICAgcHVibGljIExleGljYWxIYW5kbGVyIGdldExleGljYWxIYW5kbGVyKCkgeworICAgICAgICByZXR1cm4gbGV4aWNhbEhhbmRsZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVnaXN0ZXJzIGEgbGV4aWNhbCBldmVudCBoYW5kbGVyLiBTdXBwb3J0cyBuZWl0aGVyCisgICAgICoge0BsaW5rIExleGljYWxIYW5kbGVyI3N0YXJ0RW50aXR5KFN0cmluZyl9IG5vcgorICAgICAqIHtAbGluayBMZXhpY2FsSGFuZGxlciNlbmRFbnRpdHkoU3RyaW5nKX0uCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgYXBwbGljYXRpb24gZG9lcyBub3QgcmVnaXN0ZXIgYSBsZXhpY2FsIGhhbmRsZXIsIGFsbAorICAgICAqIGxleGljYWwgZXZlbnRzIHJlcG9ydGVkIGJ5IHRoZSBTQVggcGFyc2VyIHdpbGwgYmUgc2lsZW50bHkKKyAgICAgKiBpZ25vcmVkLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkFwcGxpY2F0aW9ucyBtYXkgcmVnaXN0ZXIgYSBuZXcgb3IgZGlmZmVyZW50IGhhbmRsZXIgaW4gdGhlCisgICAgICogbWlkZGxlIG9mIGEgcGFyc2UsIGFuZCB0aGUgU0FYIHBhcnNlciBtdXN0IGJlZ2luIHVzaW5nIHRoZSBuZXcKKyAgICAgKiBoYW5kbGVyIGltbWVkaWF0ZWx5LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsZXhpY2FsSGFuZGxlciBsaXN0ZW5zIGZvciBsZXhpY2FsIGV2ZW50cworICAgICAqIEBzZWUgI2dldExleGljYWxIYW5kbGVyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMZXhpY2FsSGFuZGxlcihMZXhpY2FsSGFuZGxlciBsZXhpY2FsSGFuZGxlcikgeworICAgICAgICB0aGlzLmxleGljYWxIYW5kbGVyID0gbGV4aWNhbEhhbmRsZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgU0FYIHBhcnNlciBwcm9jZXNzZXMgbmFtZXNwYWNlcy4KKyAgICAgKgorICAgICAqIEBzZWUgI3NldE5hbWVzcGFjZVByb2Nlc3NpbmdFbmFibGVkKGJvb2xlYW4pCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNOYW1lc3BhY2VQcm9jZXNzaW5nRW5hYmxlZCgpIHsKKyAgICAgICAgcmV0dXJuIHByb2Nlc3NOYW1lc3BhY2VzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuYWJsZXMgb3IgZGlzYWJsZXMgbmFtZXNwYWNlIHByb2Nlc3NpbmcuIFNldCB0byB0cnVlIGJ5IGRlZmF1bHQuIElmIHlvdQorICAgICAqIGVuYWJsZSBuYW1lc3BhY2UgcHJvY2Vzc2luZywgdGhlIHBhcnNlciB3aWxsIGludm9rZQorICAgICAqIHtAbGluayBDb250ZW50SGFuZGxlciNzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nLCBTdHJpbmcpfSBhbmQKKyAgICAgKiB7QGxpbmsgQ29udGVudEhhbmRsZXIjZW5kUHJlZml4TWFwcGluZyhTdHJpbmcpfSwgYW5kIGl0IHdpbGwgZmlsdGVyCisgICAgICogb3V0IG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgZnJvbSBlbGVtZW50IGF0dHJpYnV0ZXMuCisgICAgICoKKyAgICAgKiBAc2VlICNpc05hbWVzcGFjZVByb2Nlc3NpbmdFbmFibGVkKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2VQcm9jZXNzaW5nRW5hYmxlZChib29sZWFuIHByb2Nlc3NOYW1lc3BhY2VzKSB7CisgICAgICAgIHRoaXMucHJvY2Vzc05hbWVzcGFjZXMgPSBwcm9jZXNzTmFtZXNwYWNlczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBwYXJzZShJbnB1dFNvdXJjZSBpbnB1dCkgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24geworICAgICAgICBpZiAocHJvY2Vzc05hbWVzcGFjZVByZWZpeGVzICYmIHByb2Nlc3NOYW1lc3BhY2VzKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogRXhwYXQgaGFzIFhNTF9TZXRSZXR1cm5OU1RyaXBsZXQsIGJ1dCB0aGF0IHN0aWxsIGRvZXNuJ3QKKyAgICAgICAgICAgICAqIGluY2x1ZGUgeG1sbnMgYXR0cmlidXRlcyBsaWtlIHRoaXMgZmVhdHVyZSByZXF1aXJlcy4gV2UgbWF5CisgICAgICAgICAgICAgKiBoYXZlIHRvIGltcGxlbWVudCBuYW1lc3BhY2UgcHJvY2Vzc2luZyBvdXJzZWx2ZXMgaWYgd2Ugd2FudAorICAgICAgICAgICAgICogdGhpcyAobm90IHRvbyBkaWZmaWN1bHQpLiBXZSBvYnZpb3VzbHkgInN1cHBvcnQiIG5hbWVzcGFjZQorICAgICAgICAgICAgICogcHJlZml4ZXMgaWYgbmFtZXNwYWNlcyBhcmUgZGlzYWJsZWQuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIlRoZSAnbmFtZXNwYWNlLXByZWZpeCcgIiArCisgICAgICAgICAgICAgICAgICAgICJmZWF0dXJlIGlzIG5vdCBzdXBwb3J0ZWQgd2hpbGUgdGhlICduYW1lc3BhY2VzJyAiICsKKyAgICAgICAgICAgICAgICAgICAgImZlYXR1cmUgaXMgZW5hYmxlZC4iKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRyeSB0aGUgY2hhcmFjdGVyIHN0cmVhbS4KKyAgICAgICAgUmVhZGVyIHJlYWRlciA9IGlucHV0LmdldENoYXJhY3RlclN0cmVhbSgpOworICAgICAgICBpZiAocmVhZGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcGFyc2UocmVhZGVyLCBpbnB1dC5nZXRQdWJsaWNJZCgpLCBpbnB1dC5nZXRTeXN0ZW1JZCgpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkocmVhZGVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRyeSB0aGUgYnl0ZSBzdHJlYW0uCisgICAgICAgIElucHV0U3RyZWFtIGluID0gaW5wdXQuZ2V0Qnl0ZVN0cmVhbSgpOworICAgICAgICBTdHJpbmcgZW5jb2RpbmcgPSBpbnB1dC5nZXRFbmNvZGluZygpOworICAgICAgICBpZiAoaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwYXJzZShpbiwgZW5jb2RpbmcsIGlucHV0LmdldFB1YmxpY0lkKCksIGlucHV0LmdldFN5c3RlbUlkKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBJb1V0aWxzLmNsb3NlUXVpZXRseShpbik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgc3lzdGVtSWQgPSBpbnB1dC5nZXRTeXN0ZW1JZCgpOworICAgICAgICBpZiAoc3lzdGVtSWQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbigiTm8gaW5wdXQgc3BlY2lmaWVkLiIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVHJ5IHRoZSBzeXN0ZW0gaWQuCisgICAgICAgIGluID0gRXhwYXRQYXJzZXIub3BlblVybChzeXN0ZW1JZCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJzZShpbiwgZW5jb2RpbmcsIGlucHV0LmdldFB1YmxpY0lkKCksIHN5c3RlbUlkKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIElvVXRpbHMuY2xvc2VRdWlldGx5KGluKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwYXJzZShSZWFkZXIgaW4sIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24geworICAgICAgICBFeHBhdFBhcnNlciBwYXJzZXIgPSBuZXcgRXhwYXRQYXJzZXIoCisgICAgICAgICAgICAgICAgRXhwYXRQYXJzZXIuQ0hBUkFDVEVSX0VOQ09ESU5HLAorICAgICAgICAgICAgICAgIHRoaXMsCisgICAgICAgICAgICAgICAgcHJvY2Vzc05hbWVzcGFjZXMsCisgICAgICAgICAgICAgICAgcHVibGljSWQsCisgICAgICAgICAgICAgICAgc3lzdGVtSWQKKyAgICAgICAgKTsKKyAgICAgICAgcGFyc2VyLnBhcnNlRG9jdW1lbnQoaW4pOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwYXJzZShJbnB1dFN0cmVhbSBpbiwgU3RyaW5nIGVuY29kaW5nLCBTdHJpbmcgcHVibGljSWQsCisgICAgICAgICAgICBTdHJpbmcgc3lzdGVtSWQpIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgRXhwYXRQYXJzZXIgcGFyc2VyID0gbmV3IEV4cGF0UGFyc2VyKAorICAgICAgICAgICAgICAgIGVuY29kaW5nLAorICAgICAgICAgICAgICAgIHRoaXMsCisgICAgICAgICAgICAgICAgcHJvY2Vzc05hbWVzcGFjZXMsCisgICAgICAgICAgICAgICAgcHVibGljSWQsCisgICAgICAgICAgICAgICAgc3lzdGVtSWQKKyAgICAgICAgKTsKKyAgICAgICAgcGFyc2VyLnBhcnNlRG9jdW1lbnQoaW4pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHBhcnNlKFN0cmluZyBzeXN0ZW1JZCkgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24geworICAgICAgICBwYXJzZShuZXcgSW5wdXRTb3VyY2Uoc3lzdGVtSWQpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vQXR0ckltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9BdHRySW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRjNjgyNDkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vQXR0ckltcGwuamF2YQpAQCAtMCwwICsxLDEyMiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhtbC5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5BdHRyOworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uVHlwZUluZm87CisKKy8qKgorICogUHJvdmlkZXMgYSBzdHJhaWdodGZvcndhcmQgaW1wbGVtZW50YXRpb24gb2YgdGhlIGNvcnJlc3BvbmRpbmcgVzNDIERPTQorICogaW50ZXJmYWNlLiBUaGUgY2xhc3MgaXMgdXNlZCBpbnRlcm5hbGx5IG9ubHksIHRodXMgb25seSBub3RhYmxlIG1lbWJlcnMgdGhhdAorICogYXJlIG5vdCBpbiB0aGUgb3JpZ2luYWwgaW50ZXJmYWNlIGFyZSBkb2N1bWVudGVkICh0aGUgVzNDIGRvY3MgYXJlIHF1aXRlCisgKiBleHRlbnNpdmUpLiBIb3BlIHRoYXQncyBvay4KKyAqIDxwPgorICogU29tZSBvZiB0aGUgZmllbGRzIG1heSBoYXZlIHBhY2thZ2UgdmlzaWJpbGl0eSwgc28gb3RoZXIgY2xhc3NlcyBiZWxvbmdpbmcgdG8KKyAqIHRoZSBET00gaW1wbGVtZW50YXRpb24gY2FuIGVhc2lseSBhY2Nlc3MgdGhlbSB3aGlsZSBtYWludGFpbmluZyB0aGUgRE9NIHRyZWUKKyAqIHN0cnVjdHVyZS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEF0dHJJbXBsIGV4dGVuZHMgTm9kZUltcGwgaW1wbGVtZW50cyBBdHRyIHsKKworICAgIC8vIE1haW50YWluZWQgYnkgRWxlbWVudEltcGwuCisgICAgRWxlbWVudEltcGwgb3duZXJFbGVtZW50OworICAgIGJvb2xlYW4gaXNJZDsKKworICAgIGJvb2xlYW4gbmFtZXNwYWNlQXdhcmU7CisgICAgU3RyaW5nIG5hbWVzcGFjZVVSSTsKKyAgICBTdHJpbmcgcHJlZml4OworICAgIFN0cmluZyBsb2NhbE5hbWU7CisKKyAgICBwcml2YXRlIFN0cmluZyB2YWx1ZSA9ICIiOworCisgICAgQXR0ckltcGwoRG9jdW1lbnRJbXBsIGRvY3VtZW50LCBTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgcXVhbGlmaWVkTmFtZSkgeworICAgICAgICBzdXBlcihkb2N1bWVudCk7CisgICAgICAgIHNldE5hbWVOUyh0aGlzLCBuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgIH0KKworICAgIEF0dHJJbXBsKERvY3VtZW50SW1wbCBkb2N1bWVudCwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgc3VwZXIoZG9jdW1lbnQpOworICAgICAgICBzZXROYW1lKHRoaXMsIG5hbWUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKCkgeworICAgICAgICByZXR1cm4gbmFtZXNwYWNlQXdhcmUgPyBsb2NhbE5hbWUgOiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIHByZWZpeCAhPSBudWxsCisgICAgICAgICAgICAgICAgPyBwcmVmaXggKyAiOiIgKyBsb2NhbE5hbWUKKyAgICAgICAgICAgICAgICA6IGxvY2FsTmFtZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWVzcGFjZVVSSTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkgeworICAgICAgICByZXR1cm4gZ2V0TmFtZSgpOworICAgIH0KKworICAgIHB1YmxpYyBzaG9ydCBnZXROb2RlVHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIE5vZGUuQVRUUklCVVRFX05PREU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXROb2RlVmFsdWUoKSB7CisgICAgICAgIHJldHVybiBnZXRWYWx1ZSgpOworICAgIH0KKworICAgIHB1YmxpYyBFbGVtZW50IGdldE93bmVyRWxlbWVudCgpIHsKKyAgICAgICAgcmV0dXJuIG93bmVyRWxlbWVudDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeCgpIHsKKyAgICAgICAgcmV0dXJuIHByZWZpeDsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRTcGVjaWZpZWQoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRQcmVmaXgoU3RyaW5nIHByZWZpeCkgeworICAgICAgICB0aGlzLnByZWZpeCA9IHZhbGlkYXRlUHJlZml4KHByZWZpeCwgbmFtZXNwYWNlQXdhcmUsIG5hbWVzcGFjZVVSSSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VmFsdWUoU3RyaW5nIHZhbHVlKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyBUeXBlSW5mbyBnZXRTY2hlbWFUeXBlSW5mbygpIHsKKyAgICAgICAgLy8gVE9ETzogcG9wdWxhdGUgdGhpcyB3aGVuIHdlIHN1cHBvcnQgWE1MIFNjaGVtYQorICAgICAgICByZXR1cm4gTlVMTF9UWVBFX0lORk87CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNJZCgpIHsKKyAgICAgICAgcmV0dXJuIGlzSWQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL0NEQVRBU2VjdGlvbkltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9DREFUQVNlY3Rpb25JbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzdjZDhhOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9DREFUQVNlY3Rpb25JbXBsLmphdmEKQEAgLTAsMCArMSw4NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhtbC5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5DREFUQVNlY3Rpb247CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKKworLyoqCisgKiBQcm92aWRlcyBhIHN0cmFpZ2h0Zm9yd2FyZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgY29ycmVzcG9uZGluZyBXM0MgRE9NCisgKiBpbnRlcmZhY2UuIFRoZSBjbGFzcyBpcyB1c2VkIGludGVybmFsbHkgb25seSwgdGh1cyBvbmx5IG5vdGFibGUgbWVtYmVycyB0aGF0CisgKiBhcmUgbm90IGluIHRoZSBvcmlnaW5hbCBpbnRlcmZhY2UgYXJlIGRvY3VtZW50ZWQgKHRoZSBXM0MgZG9jcyBhcmUgcXVpdGUKKyAqIGV4dGVuc2l2ZSkuIEhvcGUgdGhhdCdzIG9rLgorICogPHA+CisgKiBTb21lIG9mIHRoZSBmaWVsZHMgbWF5IGhhdmUgcGFja2FnZSB2aXNpYmlsaXR5LCBzbyBvdGhlciBjbGFzc2VzIGJlbG9uZ2luZyB0bworICogdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBjYW4gZWFzaWx5IGFjY2VzcyB0aGVtIHdoaWxlIG1haW50YWluaW5nIHRoZSBET00gdHJlZQorICogc3RydWN0dXJlLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQ0RBVEFTZWN0aW9uSW1wbCBleHRlbmRzIFRleHRJbXBsIGltcGxlbWVudHMgQ0RBVEFTZWN0aW9uIHsKKworICAgIHB1YmxpYyBDREFUQVNlY3Rpb25JbXBsKERvY3VtZW50SW1wbCBkb2N1bWVudCwgU3RyaW5nIGRhdGEpIHsKKyAgICAgICAgc3VwZXIoZG9jdW1lbnQsIGRhdGEpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKSB7CisgICAgICAgIHJldHVybiAiI2NkYXRhLXNlY3Rpb24iOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzaG9ydCBnZXROb2RlVHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNwbGl0cyB0aGlzIENEQVRBIG5vZGUgaW50byBwYXJ0cyB0aGF0IGRvIG5vdCBjb250YWluIGEgIl1dPiIgc2VxdWVuY2UuCisgICAgICogQW55IG5ld2x5IGNyZWF0ZWQgbm9kZXMgd2lsbCBiZSBpbnNlcnRlZCBiZWZvcmUgdGhpcyBub2RlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNwbGl0KCkgeworICAgICAgICBpZiAoIW5lZWRzU3BsaXR0aW5nKCkpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIE5vZGUgcGFyZW50ID0gZ2V0UGFyZW50Tm9kZSgpOworICAgICAgICBTdHJpbmdbXSBwYXJ0cyA9IGdldERhdGEoKS5zcGxpdCgiXFxdXFxdPiIpOworICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKG5ldyBDREFUQVNlY3Rpb25JbXBsKGRvY3VtZW50LCBwYXJ0c1swXSArICJdXSIpLCB0aGlzKTsKKyAgICAgICAgZm9yIChpbnQgcCA9IDE7IHAgPCBwYXJ0cy5sZW5ndGggLSAxOyBwKyspIHsKKyAgICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUobmV3IENEQVRBU2VjdGlvbkltcGwoZG9jdW1lbnQsICI+IiArIHBhcnRzW3BdICsgIl1dIiksIHRoaXMpOworICAgICAgICB9CisgICAgICAgIHNldERhdGEoIj4iICsgcGFydHNbcGFydHMubGVuZ3RoIC0gMV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIENEQVRBIHNlY3Rpb24gY29udGFpbnMgdGhlIGlsbGVnYWwgY2hhcmFjdGVyCisgICAgICogc2VxdWVuY2UgIl1dPiIuIFN1Y2ggbm9kZXMgbXVzdCBiZSB7QGxpbmsgI3NwbGl0fSBiZWZvcmUgdGhleSBhcmUKKyAgICAgKiBzZXJpYWxpemVkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG5lZWRzU3BsaXR0aW5nKCkgeworICAgICAgICByZXR1cm4gYnVmZmVyLmluZGV4T2YoIl1dPiIpICE9IC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2VzIHRoaXMgbm9kZSB3aXRoIGEgc2VtYW50aWNhbGx5IGVxdWl2YWxlbnQgdGV4dCBub2RlLiBUaGlzIG5vZGUKKyAgICAgKiB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgRE9NIHRyZWUgYW5kIHRoZSBuZXcgbm9kZSBpbnNlcnRlZCBpbiBpdHMgcGxhY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZXBsYWNlbWVudCBub2RlLgorICAgICAqLworICAgIHB1YmxpYyBUZXh0SW1wbCByZXBsYWNlV2l0aFRleHQoKSB7CisgICAgICAgIFRleHRJbXBsIHJlcGxhY2VtZW50ID0gbmV3IFRleHRJbXBsKGRvY3VtZW50LCBnZXREYXRhKCkpOworICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKHJlcGxhY2VtZW50LCB0aGlzKTsKKyAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKHRoaXMpOworICAgICAgICByZXR1cm4gcmVwbGFjZW1lbnQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL0NoYXJhY3RlckRhdGFJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vQ2hhcmFjdGVyRGF0YUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZDRjM2I0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL0NoYXJhY3RlckRhdGFJbXBsLmphdmEKQEAgLTAsMCArMSw5OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhtbC5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5DaGFyYWN0ZXJEYXRhOworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKKworLyoqCisgKiBQcm92aWRlcyBhIHN0cmFpZ2h0Zm9yd2FyZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgY29ycmVzcG9uZGluZyBXM0MgRE9NCisgKiBpbnRlcmZhY2UuIFRoZSBjbGFzcyBpcyB1c2VkIGludGVybmFsbHkgb25seSwgdGh1cyBvbmx5IG5vdGFibGUgbWVtYmVycyB0aGF0CisgKiBhcmUgbm90IGluIHRoZSBvcmlnaW5hbCBpbnRlcmZhY2UgYXJlIGRvY3VtZW50ZWQgKHRoZSBXM0MgZG9jcyBhcmUgcXVpdGUKKyAqIGV4dGVuc2l2ZSkuIEhvcGUgdGhhdCdzIG9rLgorICogPHA+CisgKiBTb21lIG9mIHRoZSBmaWVsZHMgbWF5IGhhdmUgcGFja2FnZSB2aXNpYmlsaXR5LCBzbyBvdGhlciBjbGFzc2VzIGJlbG9uZ2luZyB0bworICogdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBjYW4gZWFzaWx5IGFjY2VzcyB0aGVtIHdoaWxlIG1haW50YWluaW5nIHRoZSBET00gdHJlZQorICogc3RydWN0dXJlLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ2hhcmFjdGVyRGF0YUltcGwgZXh0ZW5kcyBMZWFmTm9kZUltcGwgaW1wbGVtZW50cworICAgICAgICBDaGFyYWN0ZXJEYXRhIHsKKworICAgIHByb3RlY3RlZCBTdHJpbmdCdWZmZXIgYnVmZmVyOworCisgICAgQ2hhcmFjdGVyRGF0YUltcGwoRG9jdW1lbnRJbXBsIGRvY3VtZW50LCBTdHJpbmcgZGF0YSkgeworICAgICAgICBzdXBlcihkb2N1bWVudCk7CisgICAgICAgIHNldERhdGEoZGF0YSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYXBwZW5kRGF0YShTdHJpbmcgYXJnKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgYnVmZmVyLmFwcGVuZChhcmcpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGRlbGV0ZURhdGEoaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgYnVmZmVyLmRlbGV0ZShvZmZzZXQsIG9mZnNldCArIGNvdW50KTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldERhdGEoKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhpcyBub2RlJ3MgdGV4dCBjb250ZW50IHRvIHRoZSBnaXZlbiBidWlsZGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFwcGVuZERhdGFUbyhTdHJpbmdCdWlsZGVyIHN0cmluZ0J1aWxkZXIpIHsKKyAgICAgICAgc3RyaW5nQnVpbGRlci5hcHBlbmQoYnVmZmVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIGJ1ZmZlci5sZW5ndGgoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIGdldERhdGEoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBpbnNlcnREYXRhKGludCBvZmZzZXQsIFN0cmluZyBhcmcpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnVmZmVyLmluc2VydChvZmZzZXQsIGFyZyk7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIsIG51bGwpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVwbGFjZURhdGEoaW50IG9mZnNldCwgaW50IGNvdW50LCBTdHJpbmcgYXJnKQorICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidWZmZXIucmVwbGFjZShvZmZzZXQsIG9mZnNldCArIGNvdW50LCBhcmcpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLklOREVYX1NJWkVfRVJSLCBudWxsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldERhdGEoU3RyaW5nIGRhdGEpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKGRhdGEpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgc3Vic3RyaW5nRGF0YShpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlci5zdWJzdHJpbmcob2Zmc2V0LCBvZmZzZXQgKyBjb3VudCk7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIsIG51bGwpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vQ29tbWVudEltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9Db21tZW50SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVmOGE0ZTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vQ29tbWVudEltcGwuamF2YQpAQCAtMCwwICsxLDU1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG1sLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLkNvbW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKKworLyoqCisgKiBQcm92aWRlcyBhIHN0cmFpZ2h0Zm9yd2FyZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgY29ycmVzcG9uZGluZyBXM0MgRE9NCisgKiBpbnRlcmZhY2UuIFRoZSBjbGFzcyBpcyB1c2VkIGludGVybmFsbHkgb25seSwgdGh1cyBvbmx5IG5vdGFibGUgbWVtYmVycyB0aGF0CisgKiBhcmUgbm90IGluIHRoZSBvcmlnaW5hbCBpbnRlcmZhY2UgYXJlIGRvY3VtZW50ZWQgKHRoZSBXM0MgZG9jcyBhcmUgcXVpdGUKKyAqIGV4dGVuc2l2ZSkuIEhvcGUgdGhhdCdzIG9rLgorICogPHA+CisgKiBTb21lIG9mIHRoZSBmaWVsZHMgbWF5IGhhdmUgcGFja2FnZSB2aXNpYmlsaXR5LCBzbyBvdGhlciBjbGFzc2VzIGJlbG9uZ2luZyB0bworICogdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBjYW4gZWFzaWx5IGFjY2VzcyB0aGVtIHdoaWxlIG1haW50YWluaW5nIHRoZSBET00gdHJlZQorICogc3RydWN0dXJlLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQ29tbWVudEltcGwgZXh0ZW5kcyBDaGFyYWN0ZXJEYXRhSW1wbCBpbXBsZW1lbnRzIENvbW1lbnQgeworCisgICAgQ29tbWVudEltcGwoRG9jdW1lbnRJbXBsIGRvY3VtZW50LCBTdHJpbmcgZGF0YSkgeworICAgICAgICBzdXBlcihkb2N1bWVudCwgZGF0YSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuICIjY29tbWVudCI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKCkgeworICAgICAgICByZXR1cm4gTm9kZS5DT01NRU5UX05PREU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgY29tbWVudCBjb250YWlucyB0aGUgaWxsZWdhbCBjaGFyYWN0ZXIgc2VxdWVuY2UKKyAgICAgKiAiLS0iLiBTdWNoIG5vZGVzIG1heSBub3QgYmUgc2VyaWFsaXplZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0Rhc2hEYXNoKCkgeworICAgICAgICByZXR1cm4gYnVmZmVyLmluZGV4T2YoIi0tIikgIT0gLTE7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL0RPTUNvbmZpZ3VyYXRpb25JbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vRE9NQ29uZmlndXJhdGlvbkltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NzI0Nzc2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL0RPTUNvbmZpZ3VyYXRpb25JbXBsLmphdmEKQEAgLTAsMCArMSw0ODkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bWwuZG9tOworCitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01Db25maWd1cmF0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUVycm9yOworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUVycm9ySGFuZGxlcjsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRE9NU3RyaW5nTGlzdDsKK2ltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKKworLyoqCisgKiBBIG1pbmltYWwgaW1wbGVtZW50YXRpb24gb2YgRE9NQ29uZmlndXJhdGlvbi4gVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIGlubmVyCisgKiBwYXJhbWV0ZXIgaW5zdGFuY2VzIHRvIGNlbnRyYWxpemUgZWFjaCBwYXJhbWV0ZXIncyBiZWhhdmlvci4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIERPTUNvbmZpZ3VyYXRpb25JbXBsIGltcGxlbWVudHMgRE9NQ29uZmlndXJhdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8U3RyaW5nLCBQYXJhbWV0ZXI+IFBBUkFNRVRFUlMKKyAgICAgICAgICAgID0gbmV3IFRyZWVNYXA8U3RyaW5nLCBQYXJhbWV0ZXI+KFN0cmluZy5DQVNFX0lOU0VOU0lUSVZFX09SREVSKTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIC8qCisgICAgICAgICAqIFRydWUgdG8gY2Fub25pY2FsaXplIHRoZSBkb2N1bWVudCAodW5zdXBwb3J0ZWQpLiBUaGlzIGluY2x1ZGVzCisgICAgICAgICAqIHJlbW92aW5nIERvY3VtZW50VHlwZSBub2RlcyBmcm9tIHRoZSB0cmVlIGFuZCByZW1vdmluZyB1bnVzZWQKKyAgICAgICAgICogbmFtZXNwYWNlIGRlY2xhcmF0aW9ucy4gU2V0dGluZyB0aGlzIHRvIHRydWUgYWxzbyBzZXRzIHRoZXNlCisgICAgICAgICAqIHBhcmFtZXRlcnM6CisgICAgICAgICAqICAgZW50aXRpZXMgPSBmYWxzZQorICAgICAgICAgKiAgIG5vcm1hbGl6ZS1jaGFyYWN0ZXJzID0gZmFsc2UKKyAgICAgICAgICogICBjZGF0YS1zZWN0aW9ucyA9IGZhbHNlCisgICAgICAgICAqICAgbmFtZXNwYWNlcyA9IHRydWUKKyAgICAgICAgICogICBuYW1lc3BhY2UtZGVjbGFyYXRpb25zID0gdHJ1ZQorICAgICAgICAgKiAgIHdlbGwtZm9ybWVkID0gdHJ1ZQorICAgICAgICAgKiAgIGVsZW1lbnQtY29udGVudC13aGl0ZXNwYWNlID0gdHJ1ZQorICAgICAgICAgKiBTZXR0aW5nIHRoZXNlIHBhcmFtZXRlcnMgdG8gYW5vdGhlciB2YWx1ZSBzaGFsbCByZXZlcnQgdGhlIGNhbm9uaWNhbAorICAgICAgICAgKiBmb3JtIHRvIGZhbHNlLgorICAgICAgICAgKi8KKyAgICAgICAgUEFSQU1FVEVSUy5wdXQoImNhbm9uaWNhbC1mb3JtIiwgbmV3IEZpeGVkUGFyYW1ldGVyKGZhbHNlKSk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVHJ1ZSB0byBrZWVwIGV4aXN0aW5nIENEQVRBIG5vZGVzOyBmYWxzZSB0byByZXBsYWNlIHRoZW0vbWVyZ2UgdGhlbQorICAgICAgICAgKiBpbnRvIGFkamFjZW50IHRleHQgbm9kZXMuCisgICAgICAgICAqLworICAgICAgICBQQVJBTUVURVJTLnB1dCgiY2RhdGEtc2VjdGlvbnMiLCBuZXcgQm9vbGVhblBhcmFtZXRlcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0KERPTUNvbmZpZ3VyYXRpb25JbXBsIGNvbmZpZykgeworICAgICAgICAgICAgICAgIHJldHVybiBjb25maWcuY2RhdGFTZWN0aW9uczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHNldChET01Db25maWd1cmF0aW9uSW1wbCBjb25maWcsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGNvbmZpZy5jZGF0YVNlY3Rpb25zID0gKEJvb2xlYW4pIHZhbHVlOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKworICAgICAgICAvKgorICAgICAgICAgKiBUcnVlIHRvIGNoZWNrIGNoYXJhY3RlciBub3JtYWxpemF0aW9uICh1bnN1cHBvcnRlZCkuCisgICAgICAgICAqLworICAgICAgICBQQVJBTUVURVJTLnB1dCgiY2hlY2stY2hhcmFjdGVyLW5vcm1hbGl6YXRpb24iLCBuZXcgRml4ZWRQYXJhbWV0ZXIoZmFsc2UpKTsKKworICAgICAgICAvKgorICAgICAgICAgKiBUcnVlIHRvIGtlZXAgY29tbWVudHMgaW4gdGhlIGRvY3VtZW50OyBmYWxzZSB0byBkaXNjYXJkIHRoZW0uCisgICAgICAgICAqLworICAgICAgICBQQVJBTUVURVJTLnB1dCgiY29tbWVudHMiLCBuZXcgQm9vbGVhblBhcmFtZXRlcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0KERPTUNvbmZpZ3VyYXRpb25JbXBsIGNvbmZpZykgeworICAgICAgICAgICAgICAgIHJldHVybiBjb25maWcuY29tbWVudHM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBzZXQoRE9NQ29uZmlndXJhdGlvbkltcGwgY29uZmlnLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgICAgICAgICBjb25maWcuY29tbWVudHMgPSAoQm9vbGVhbikgdmFsdWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworCisgICAgICAgIC8qCisgICAgICAgICAqIFRydWUgdG8gZXhwb3NlIHNjaGVtYSBub3JtYWxpemVkIHZhbHVlcy4gU2V0dGluZyB0aGlzIHRvIHRydWUgc2V0cworICAgICAgICAgKiB0aGUgdmFsaWRhdGUgcGFyYW1ldGVyIHRvIHRydWUuIEhhcyBubyBlZmZlY3Qgd2hlbiB2YWxpZGF0ZSBpcyBmYWxzZS4KKyAgICAgICAgICovCisgICAgICAgIFBBUkFNRVRFUlMucHV0KCJkYXRhdHlwZS1ub3JtYWxpemF0aW9uIiwgbmV3IEJvb2xlYW5QYXJhbWV0ZXIoKSB7CisgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IGdldChET01Db25maWd1cmF0aW9uSW1wbCBjb25maWcpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY29uZmlnLmRhdGF0eXBlTm9ybWFsaXphdGlvbjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHNldChET01Db25maWd1cmF0aW9uSW1wbCBjb25maWcsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGlmICgoQm9vbGVhbikgdmFsdWUpIHsKKyAgICAgICAgICAgICAgICAgICAgY29uZmlnLmRhdGF0eXBlTm9ybWFsaXphdGlvbiA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIGNvbmZpZy52YWxpZGF0ZSA9IHRydWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgY29uZmlnLmRhdGF0eXBlTm9ybWFsaXphdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVHJ1ZSB0byBrZWVwIHdoaXRlc3BhY2UgZWxlbWVudHMgaW4gdGhlIGRvY3VtZW50OyBmYWxzZSB0byBkaXNjYXJkCisgICAgICAgICAqIHRoZW0gKHVuc3VwcG9ydGVkKS4KKyAgICAgICAgICovCisgICAgICAgIFBBUkFNRVRFUlMucHV0KCJlbGVtZW50LWNvbnRlbnQtd2hpdGVzcGFjZSIsIG5ldyBGaXhlZFBhcmFtZXRlcih0cnVlKSk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVHJ1ZSB0byBrZWVwIGVudGl0eSByZWZlcmVuY2VzIGluIHRoZSBkb2N1bWVudDsgZmFsc2UgdG8gZXhwYW5kIHRoZW0uCisgICAgICAgICAqLworICAgICAgICBQQVJBTUVURVJTLnB1dCgiZW50aXRpZXMiLCBuZXcgQm9vbGVhblBhcmFtZXRlcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0KERPTUNvbmZpZ3VyYXRpb25JbXBsIGNvbmZpZykgeworICAgICAgICAgICAgICAgIHJldHVybiBjb25maWcuZW50aXRpZXM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBzZXQoRE9NQ29uZmlndXJhdGlvbkltcGwgY29uZmlnLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgICAgICAgICBjb25maWcuZW50aXRpZXMgPSAoQm9vbGVhbikgdmFsdWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworCisgICAgICAgIC8qCisgICAgICAgICAqIEhhbmRsZXIgdG8gYmUgaW52b2tlZCB3aGVuIGVycm9ycyBhcmUgZW5jb3VudGVyZWQuCisgICAgICAgICAqLworICAgICAgICBQQVJBTUVURVJTLnB1dCgiZXJyb3ItaGFuZGxlciIsIG5ldyBQYXJhbWV0ZXIoKSB7CisgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IGdldChET01Db25maWd1cmF0aW9uSW1wbCBjb25maWcpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY29uZmlnLmVycm9ySGFuZGxlcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHNldChET01Db25maWd1cmF0aW9uSW1wbCBjb25maWcsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGNvbmZpZy5lcnJvckhhbmRsZXIgPSAoRE9NRXJyb3JIYW5kbGVyKSB2YWx1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGNhblNldChET01Db25maWd1cmF0aW9uSW1wbCBjb25maWcsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZSA9PSBudWxsIHx8IHZhbHVlIGluc3RhbmNlb2YgRE9NRXJyb3JIYW5kbGVyOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKworICAgICAgICAvKgorICAgICAgICAgKiBCdWxrIGFsaWFzIHRvIHNldCB0aGUgZm9sbG93aW5nIHBhcmFtZXRlciB2YWx1ZXM6CisgICAgICAgICAqICAgdmFsaWRhdGUtaWYtc2NoZW1hID0gZmFsc2UKKyAgICAgICAgICogICBlbnRpdGllcyA9IGZhbHNlCisgICAgICAgICAqICAgZGF0YXR5cGUtbm9ybWFsaXphdGlvbiA9IGZhbHNlCisgICAgICAgICAqICAgY2RhdGEtc2VjdGlvbnMgPSBmYWxzZQorICAgICAgICAgKiAgIG5hbWVzcGFjZS1kZWNsYXJhdGlvbnMgPSB0cnVlCisgICAgICAgICAqICAgd2VsbC1mb3JtZWQgPSB0cnVlCisgICAgICAgICAqICAgZWxlbWVudC1jb250ZW50LXdoaXRlc3BhY2UgPSB0cnVlCisgICAgICAgICAqICAgY29tbWVudHMgPSB0cnVlCisgICAgICAgICAqICAgbmFtZXNwYWNlcyA9IHRydWUuCisgICAgICAgICAqIFF1ZXJ5aW5nIHRoaXMgcmV0dXJucyB0cnVlIGlmIGFsbCBvZiB0aGUgYWJvdmUgcGFyYW1ldGVycyBoYXZlIHRoZQorICAgICAgICAgKiBsaXN0ZWQgdmFsdWVzOyBmYWxzZSBvdGhlcndpc2UuCisgICAgICAgICAqLworICAgICAgICBQQVJBTUVURVJTLnB1dCgiaW5mb3NldCIsIG5ldyBCb29sZWFuUGFyYW1ldGVyKCkgeworICAgICAgICAgICAgcHVibGljIE9iamVjdCBnZXQoRE9NQ29uZmlndXJhdGlvbkltcGwgY29uZmlnKSB7CisgICAgICAgICAgICAgICAgLy8gdmFsaWRhdGUtaWYtc2NoZW1hIGlzIGFsd2F5cyBmYWxzZQorICAgICAgICAgICAgICAgIC8vIGVsZW1lbnQtY29udGVudC13aGl0ZXNwYWNlIGlzIGFsd2F5cyB0cnVlCisgICAgICAgICAgICAgICAgLy8gbmFtZXNwYWNlLWRlY2xhcmF0aW9ucyBpcyBhbHdheXMgdHJ1ZQorICAgICAgICAgICAgICAgIHJldHVybiAhY29uZmlnLmVudGl0aWVzCisgICAgICAgICAgICAgICAgICAgICAgICAmJiAhY29uZmlnLmRhdGF0eXBlTm9ybWFsaXphdGlvbgorICAgICAgICAgICAgICAgICAgICAgICAgJiYgIWNvbmZpZy5jZGF0YVNlY3Rpb25zCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBjb25maWcud2VsbEZvcm1lZAorICAgICAgICAgICAgICAgICAgICAgICAgJiYgY29uZmlnLmNvbW1lbnRzCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBjb25maWcubmFtZXNwYWNlczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHNldChET01Db25maWd1cmF0aW9uSW1wbCBjb25maWcsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGlmICgoQm9vbGVhbikgdmFsdWUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gdmFsaWRhdGUtaWYtc2NoZW1hIGlzIGFsd2F5cyBmYWxzZQorICAgICAgICAgICAgICAgICAgICAvLyBlbGVtZW50LWNvbnRlbnQtd2hpdGVzcGFjZSBpcyBhbHdheXMgdHJ1ZQorICAgICAgICAgICAgICAgICAgICAvLyBuYW1lc3BhY2UtZGVjbGFyYXRpb25zIGlzIGFsd2F5cyB0cnVlCisgICAgICAgICAgICAgICAgICAgIGNvbmZpZy5lbnRpdGllcyA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICBjb25maWcuZGF0YXR5cGVOb3JtYWxpemF0aW9uID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIGNvbmZpZy5jZGF0YVNlY3Rpb25zID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIGNvbmZpZy53ZWxsRm9ybWVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgY29uZmlnLmNvbW1lbnRzID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgY29uZmlnLm5hbWVzcGFjZXMgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVHJ1ZSB0byBwZXJmb3JtIG5hbWVzcGFjZSBwcm9jZXNzaW5nOyBmYWxzZSBmb3Igbm9uZS4KKyAgICAgICAgICovCisgICAgICAgIFBBUkFNRVRFUlMucHV0KCJuYW1lc3BhY2VzIiwgbmV3IEJvb2xlYW5QYXJhbWV0ZXIoKSB7CisgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IGdldChET01Db25maWd1cmF0aW9uSW1wbCBjb25maWcpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY29uZmlnLm5hbWVzcGFjZXM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBzZXQoRE9NQ29uZmlndXJhdGlvbkltcGwgY29uZmlnLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgICAgICAgICBjb25maWcubmFtZXNwYWNlcyA9IChCb29sZWFuKSB2YWx1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRydWUgdG8gaW5jbHVkZSBuYW1lc3BhY2UgZGVjbGFyYXRpb25zOyBmYWxzZSB0byBkaXNjYXJkIHRoZW0KKyAgICAgICAgICogKHVuc3VwcG9ydGVkKS4gRXZlbiB3aGVuIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgYXJlIGRpc2NhcmRlZCwKKyAgICAgICAgICogcHJlZml4ZXMgYXJlIHJldGFpbmVkLgorICAgICAgICAgKgorICAgICAgICAgKiBIYXMgbm8gZWZmZWN0IGlmIG5hbWVzcGFjZXMgaXMgZmFsc2UuCisgICAgICAgICAqLworICAgICAgICBQQVJBTUVURVJTLnB1dCgibmFtZXNwYWNlLWRlY2xhcmF0aW9ucyIsIG5ldyBGaXhlZFBhcmFtZXRlcih0cnVlKSk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVHJ1ZSB0byBmdWxseSBub3JtYWxpemUgY2hhcmFjdGVycyAodW5zdXBwb3J0ZWQpLgorICAgICAgICAgKi8KKyAgICAgICAgUEFSQU1FVEVSUy5wdXQoIm5vcm1hbGl6ZS1jaGFyYWN0ZXJzIiwgbmV3IEZpeGVkUGFyYW1ldGVyKGZhbHNlKSk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogQSBsaXN0IG9mIHdoaXRlc3BhY2Utc2VwYXJhdGVkIFVSSXMgcmVwcmVzZW50aW5nIHRoZSBzY2hlbWFzIHRvIHZhbGlkYXRlCisgICAgICAgICAqIGFnYWluc3QuIEhhcyBubyBlZmZlY3QgaWYgc2NoZW1hLXR5cGUgaXMgbnVsbC4KKyAgICAgICAgICovCisgICAgICAgIFBBUkFNRVRFUlMucHV0KCJzY2hlbWEtbG9jYXRpb24iLCBuZXcgUGFyYW1ldGVyKCkgeworICAgICAgICAgICAgcHVibGljIE9iamVjdCBnZXQoRE9NQ29uZmlndXJhdGlvbkltcGwgY29uZmlnKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNvbmZpZy5zY2hlbWFMb2NhdGlvbjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHNldChET01Db25maWd1cmF0aW9uSW1wbCBjb25maWcsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGNvbmZpZy5zY2hlbWFMb2NhdGlvbiA9IChTdHJpbmcpIHZhbHVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gY2FuU2V0KERPTUNvbmZpZ3VyYXRpb25JbXBsIGNvbmZpZywgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlID09IG51bGwgfHwgdmFsdWUgaW5zdGFuY2VvZiBTdHJpbmc7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworCisgICAgICAgIC8qCisgICAgICAgICAqIFVSSSByZXByZXNlbnRpbmcgdGhlIHR5cGUgb2Ygc2NoZW1hIGxhbmd1YWdlLCBzdWNoIGFzCisgICAgICAgICAqICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgb3IgImh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwiLgorICAgICAgICAgKi8KKyAgICAgICAgUEFSQU1FVEVSUy5wdXQoInNjaGVtYS10eXBlIiwgbmV3IFBhcmFtZXRlcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0KERPTUNvbmZpZ3VyYXRpb25JbXBsIGNvbmZpZykgeworICAgICAgICAgICAgICAgIHJldHVybiBjb25maWcuc2NoZW1hVHlwZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHNldChET01Db25maWd1cmF0aW9uSW1wbCBjb25maWcsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGNvbmZpZy5zY2hlbWFUeXBlID0gKFN0cmluZykgdmFsdWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBjYW5TZXQoRE9NQ29uZmlndXJhdGlvbkltcGwgY29uZmlnLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVHJ1ZSB0byBzcGxpdCBDREFUQSBzZWN0aW9ucyBjb250YWluaW5nICJdXT4iOyBmYWxzZSB0byBzaWduYWwgYW4KKyAgICAgICAgICogZXJyb3IgaW5zdGVhZC4KKyAgICAgICAgICovCisgICAgICAgIFBBUkFNRVRFUlMucHV0KCJzcGxpdC1jZGF0YS1zZWN0aW9ucyIsIG5ldyBCb29sZWFuUGFyYW1ldGVyKCkgeworICAgICAgICAgICAgcHVibGljIE9iamVjdCBnZXQoRE9NQ29uZmlndXJhdGlvbkltcGwgY29uZmlnKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNvbmZpZy5zcGxpdENkYXRhU2VjdGlvbnM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBzZXQoRE9NQ29uZmlndXJhdGlvbkltcGwgY29uZmlnLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgICAgICAgICBjb25maWcuc3BsaXRDZGF0YVNlY3Rpb25zID0gKEJvb2xlYW4pIHZhbHVlOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKworICAgICAgICAvKgorICAgICAgICAgKiBUcnVlIHRvIHJlcXVpcmUgdmFsaWRhdGlvbiBhZ2FpbnN0IGEgc2NoZW1hIG9yIERURC4gVmFsaWRhdGlvbiB3aWxsCisgICAgICAgICAqIHJlY29tcHV0ZSBlbGVtZW50IGNvbnRlbnQgd2hpdGVzcGFjZSwgSUQgYW5kIHNjaGVtYSB0eXBlIGRhdGEuCisgICAgICAgICAqCisgICAgICAgICAqIFNldHRpbmcgdGhpcyB1bnNldHMgdmFsaWRhdGUtaWYtc2NoZW1hLgorICAgICAgICAgKi8KKyAgICAgICAgUEFSQU1FVEVSUy5wdXQoInZhbGlkYXRlIiwgbmV3IEJvb2xlYW5QYXJhbWV0ZXIoKSB7CisgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IGdldChET01Db25maWd1cmF0aW9uSW1wbCBjb25maWcpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY29uZmlnLnZhbGlkYXRlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIHZvaWQgc2V0KERPTUNvbmZpZ3VyYXRpb25JbXBsIGNvbmZpZywgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgICAgICAgICAgLy8gdmFsaWRhdGUtaWYtc2NoZW1hIGlzIGFsd2F5cyBmYWxzZQorICAgICAgICAgICAgICAgIGNvbmZpZy52YWxpZGF0ZSA9IChCb29sZWFuKSB2YWx1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVHJ1ZSB0byB2YWxpZGF0ZSBpZiBhIHNjaGVtYSB3YXMgZGVjbGFyZWQgKHVuc3VwcG9ydGVkKS4gU2V0dGluZyB0aGlzCisgICAgICAgICAqIHVuc2V0cyB2YWxpZGF0ZS4KKyAgICAgICAgICovCisgICAgICAgIFBBUkFNRVRFUlMucHV0KCJ2YWxpZGF0ZS1pZi1zY2hlbWEiLCBuZXcgRml4ZWRQYXJhbWV0ZXIoZmFsc2UpKTsKKworICAgICAgICAvKgorICAgICAgICAgKiBUcnVlIHRvIHJlcG9ydCBpbnZhbGlkIGNoYXJhY3RlcnMgaW4gbm9kZSBuYW1lcywgYXR0cmlidXRlcywgZWxlbWVudHMsCisgICAgICAgICAqIGNvbW1lbnRzLCB0ZXh0LCBDREFUQSBzZWN0aW9ucyBhbmQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMuCisgICAgICAgICAqLworICAgICAgICBQQVJBTUVURVJTLnB1dCgid2VsbC1mb3JtZWQiLCBuZXcgQm9vbGVhblBhcmFtZXRlcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0KERPTUNvbmZpZ3VyYXRpb25JbXBsIGNvbmZpZykgeworICAgICAgICAgICAgICAgIHJldHVybiBjb25maWcud2VsbEZvcm1lZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHNldChET01Db25maWd1cmF0aW9uSW1wbCBjb25maWcsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGNvbmZpZy53ZWxsRm9ybWVkID0gKEJvb2xlYW4pIHZhbHVlOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKworICAgICAgICAvLyBUT0RPIGFkZCAicmVzb3VyY2UtcmVzb2x2ZXIiIHByb3BlcnR5IGZvciB1c2Ugd2l0aCBMUyBmZWF0dXJlLi4uCisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGNkYXRhU2VjdGlvbnMgPSB0cnVlOworICAgIHByaXZhdGUgYm9vbGVhbiBjb21tZW50cyA9IHRydWU7CisgICAgcHJpdmF0ZSBib29sZWFuIGRhdGF0eXBlTm9ybWFsaXphdGlvbiA9IGZhbHNlOworICAgIHByaXZhdGUgYm9vbGVhbiBlbnRpdGllcyA9IHRydWU7CisgICAgcHJpdmF0ZSBET01FcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyOworICAgIHByaXZhdGUgYm9vbGVhbiBuYW1lc3BhY2VzID0gdHJ1ZTsKKyAgICBwcml2YXRlIFN0cmluZyBzY2hlbWFMb2NhdGlvbjsKKyAgICBwcml2YXRlIFN0cmluZyBzY2hlbWFUeXBlOworICAgIHByaXZhdGUgYm9vbGVhbiBzcGxpdENkYXRhU2VjdGlvbnMgPSB0cnVlOworICAgIHByaXZhdGUgYm9vbGVhbiB2YWxpZGF0ZSA9IGZhbHNlOworICAgIHByaXZhdGUgYm9vbGVhbiB3ZWxsRm9ybWVkID0gdHJ1ZTsKKworICAgIGludGVyZmFjZSBQYXJhbWV0ZXIgeworICAgICAgICBPYmplY3QgZ2V0KERPTUNvbmZpZ3VyYXRpb25JbXBsIGNvbmZpZyk7CisgICAgICAgIHZvaWQgc2V0KERPTUNvbmZpZ3VyYXRpb25JbXBsIGNvbmZpZywgT2JqZWN0IHZhbHVlKTsKKyAgICAgICAgYm9vbGVhbiBjYW5TZXQoRE9NQ29uZmlndXJhdGlvbkltcGwgY29uZmlnLCBPYmplY3QgdmFsdWUpOworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBGaXhlZFBhcmFtZXRlciBpbXBsZW1lbnRzIFBhcmFtZXRlciB7CisgICAgICAgIGZpbmFsIE9iamVjdCBvbmx5VmFsdWU7CisgICAgICAgIEZpeGVkUGFyYW1ldGVyKE9iamVjdCBvbmx5VmFsdWUpIHsKKyAgICAgICAgICAgIHRoaXMub25seVZhbHVlID0gb25seVZhbHVlOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0KERPTUNvbmZpZ3VyYXRpb25JbXBsIGNvbmZpZykgeworICAgICAgICAgICAgcmV0dXJuIG9ubHlWYWx1ZTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgdm9pZCBzZXQoRE9NQ29uZmlndXJhdGlvbkltcGwgY29uZmlnLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgICAgIGlmICghb25seVZhbHVlLmVxdWFscyh2YWx1ZSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJVbnN1cHBvcnRlZCB2YWx1ZTogIiArIHZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBjYW5TZXQoRE9NQ29uZmlndXJhdGlvbkltcGwgY29uZmlnLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgICAgIHJldHVybiBvbmx5VmFsdWUuZXF1YWxzKHZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBCb29sZWFuUGFyYW1ldGVyIGltcGxlbWVudHMgUGFyYW1ldGVyIHsKKyAgICAgICAgcHVibGljIGJvb2xlYW4gY2FuU2V0KERPTUNvbmZpZ3VyYXRpb25JbXBsIGNvbmZpZywgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgICAgICByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBCb29sZWFuOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gY2FuU2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgUGFyYW1ldGVyIHBhcmFtZXRlciA9IFBBUkFNRVRFUlMuZ2V0KG5hbWUpOworICAgICAgICByZXR1cm4gcGFyYW1ldGVyICE9IG51bGwgJiYgcGFyYW1ldGVyLmNhblNldCh0aGlzLCB2YWx1ZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICBQYXJhbWV0ZXIgcGFyYW1ldGVyID0gUEFSQU1FVEVSUy5nZXQobmFtZSk7CisgICAgICAgIGlmIChwYXJhbWV0ZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUiwgIk5vIHN1Y2ggcGFyYW1ldGVyOiAiICsgbmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmFtZXRlci5zZXQodGhpcywgdmFsdWUpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5UWVBFX01JU01BVENIX0VSUiwKKyAgICAgICAgICAgICAgICAgICAgIk51bGwgbm90IGFsbG93ZWQgZm9yICIgKyBuYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLlRZUEVfTUlTTUFUQ0hfRVJSLAorICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCB0eXBlIGZvciAiICsgbmFtZSArICI6ICIgKyB2YWx1ZS5nZXRDbGFzcygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgUGFyYW1ldGVyIHBhcmFtZXRlciA9IFBBUkFNRVRFUlMuZ2V0KG5hbWUpOworICAgICAgICBpZiAocGFyYW1ldGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIsICJObyBzdWNoIHBhcmFtZXRlcjogIiArIG5hbWUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBwYXJhbWV0ZXIuZ2V0KHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBET01TdHJpbmdMaXN0IGdldFBhcmFtZXRlck5hbWVzKCkgeworICAgICAgICBmaW5hbCBTdHJpbmdbXSByZXN1bHQgPSBQQVJBTUVURVJTLmtleVNldCgpLnRvQXJyYXkobmV3IFN0cmluZ1tQQVJBTUVURVJTLnNpemUoKV0pOworICAgICAgICByZXR1cm4gbmV3IERPTVN0cmluZ0xpc3QoKSB7CisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGl0ZW0oaW50IGluZGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4IDwgcmVzdWx0Lmxlbmd0aCA/IHJlc3VsdFtpbmRleF0gOiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5sZW5ndGg7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhTdHJpbmcgc3RyKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIFBBUkFNRVRFUlMuY29udGFpbnNLZXkoc3RyKTsgLy8gY2FzZS1pbnNlbnNpdGl2ZS4KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBub3JtYWxpemUoTm9kZSBub2RlKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFNpbmNlIHdlIGRvbid0IHZhbGlkYXRlLCB0aGlzIGNvZGUgZG9lc24ndCB0YWtlIGludG8gYWNjb3VudCB0aGUKKyAgICAgICAgICogZm9sbG93aW5nICJzdXBwb3J0ZWQiIHBhcmFtZXRlcnM6IGRhdGF0eXBlLW5vcm1hbGl6YXRpb24sIGVudGl0aWVzLAorICAgICAgICAgKiBzY2hlbWEtbG9jYXRpb24sIHNjaGVtYS10eXBlLCBvciB2YWxpZGF0ZS4KKyAgICAgICAgICoKKyAgICAgICAgICogVE9ETzogbm9ybWFsaXplIG5hbWVzcGFjZXMKKyAgICAgICAgICovCisKKyAgICAgICAgc3dpdGNoIChub2RlLmdldE5vZGVUeXBlKCkpIHsKKyAgICAgICAgICAgIGNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREU6CisgICAgICAgICAgICAgICAgQ0RBVEFTZWN0aW9uSW1wbCBjZGF0YSA9IChDREFUQVNlY3Rpb25JbXBsKSBub2RlOworICAgICAgICAgICAgICAgIGlmIChjZGF0YVNlY3Rpb25zKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChjZGF0YS5uZWVkc1NwbGl0dGluZygpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3BsaXRDZGF0YVNlY3Rpb25zKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2RhdGEuc3BsaXQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnQoRE9NRXJyb3IuU0VWRVJJVFlfV0FSTklORywgImNkYXRhLXNlY3Rpb25zLXNwbGl0dGVkIik7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydChET01FcnJvci5TRVZFUklUWV9FUlJPUiwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgY2hlY2tUZXh0VmFsaWRpdHkoY2RhdGEuYnVmZmVyKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG5vZGUgPSBjZGF0YS5yZXBsYWNlV2l0aFRleHQoKTsKKyAgICAgICAgICAgICAgICAvLyBmYWxsIHRocm91Z2gKKworICAgICAgICAgICAgY2FzZSBOb2RlLlRFWFRfTk9ERToKKyAgICAgICAgICAgICAgICBUZXh0SW1wbCB0ZXh0ID0gKFRleHRJbXBsKSBub2RlOworICAgICAgICAgICAgICAgIHRleHQgPSB0ZXh0Lm1pbmltaXplKCk7CisgICAgICAgICAgICAgICAgaWYgKHRleHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBjaGVja1RleHRWYWxpZGl0eSh0ZXh0LmJ1ZmZlcik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIE5vZGUuQ09NTUVOVF9OT0RFOgorICAgICAgICAgICAgICAgIENvbW1lbnRJbXBsIGNvbW1lbnQgPSAoQ29tbWVudEltcGwpIG5vZGU7CisgICAgICAgICAgICAgICAgaWYgKCFjb21tZW50cykgeworICAgICAgICAgICAgICAgICAgICBjb21tZW50LmdldFBhcmVudE5vZGUoKS5yZW1vdmVDaGlsZChjb21tZW50KTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChjb21tZW50LmNvbnRhaW5zRGFzaERhc2goKSkgeworICAgICAgICAgICAgICAgICAgICByZXBvcnQoRE9NRXJyb3IuU0VWRVJJVFlfRVJST1IsICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjaGVja1RleHRWYWxpZGl0eShjb21tZW50LmJ1ZmZlcik7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU6CisgICAgICAgICAgICAgICAgY2hlY2tUZXh0VmFsaWRpdHkoKChQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25JbXBsKSBub2RlKS5nZXREYXRhKCkpOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIE5vZGUuQVRUUklCVVRFX05PREU6CisgICAgICAgICAgICAgICAgY2hlY2tUZXh0VmFsaWRpdHkoKChBdHRySW1wbCkgbm9kZSkuZ2V0VmFsdWUoKSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6CisgICAgICAgICAgICAgICAgRWxlbWVudEltcGwgZWxlbWVudCA9IChFbGVtZW50SW1wbCkgbm9kZTsKKyAgICAgICAgICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIG5vcm1hbGl6ZShhdHRyaWJ1dGVzLml0ZW0oaSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBmYWxsIHRocm91Z2gKKworICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREU6CisgICAgICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERToKKyAgICAgICAgICAgICAgICBOb2RlIG5leHQ7CisgICAgICAgICAgICAgICAgZm9yIChOb2RlIGNoaWxkID0gbm9kZS5nZXRGaXJzdENoaWxkKCk7IGNoaWxkICE9IG51bGw7IGNoaWxkID0gbmV4dCkgeworICAgICAgICAgICAgICAgICAgICAvLyBsb29rdXAgbmV4dCBlYWdlcmx5IGJlY2F1c2Ugbm9ybWFsaXplKCkgbWF5IHJlbW92ZSBpdHMgc3ViamVjdAorICAgICAgICAgICAgICAgICAgICBuZXh0ID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKTsKKyAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplKGNoaWxkKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgTm9kZS5OT1RBVElPTl9OT0RFOgorICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX1RZUEVfTk9ERToKKyAgICAgICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfTk9ERToKKyAgICAgICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREU6CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsCisgICAgICAgICAgICAgICAgICAgICAgICAiVW5zdXBwb3J0ZWQgbm9kZSB0eXBlICIgKyBub2RlLmdldE5vZGVUeXBlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrVGV4dFZhbGlkaXR5KENoYXJTZXF1ZW5jZSBzKSB7CisgICAgICAgIGlmICh3ZWxsRm9ybWVkICYmICFpc1ZhbGlkKHMpKSB7CisgICAgICAgICAgICByZXBvcnQoRE9NRXJyb3IuU0VWRVJJVFlfRVJST1IsICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIGFsbCBvZiB0aGUgY2hhcmFjdGVycyBpbiB0aGUgdGV4dCBhcmUgcGVybWl0dGVkIGZvciB1c2UKKyAgICAgKiBpbiBYTUwgZG9jdW1lbnRzLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpc1ZhbGlkKENoYXJTZXF1ZW5jZSB0ZXh0KSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGV4dC5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBjaGFyIGMgPSB0ZXh0LmNoYXJBdChpKTsKKyAgICAgICAgICAgIC8vIGFzIGRlZmluZWQgYnkgaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC8jY2hhcnNldHMuCisgICAgICAgICAgICBib29sZWFuIHZhbGlkID0gYyA9PSAweDkgfHwgYyA9PSAweEEgfHwgYyA9PSAweEQKKyAgICAgICAgICAgICAgICAgICAgfHwgKGMgPj0gMHgyMCAmJiBjIDw9IDB4ZDdmZikKKyAgICAgICAgICAgICAgICAgICAgfHwgKGMgPj0gMHhlMDAwICYmIGMgPD0gMHhmZmZkKTsKKyAgICAgICAgICAgIGlmICghdmFsaWQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlcG9ydChzaG9ydCBzZXZlcml0eSwgU3RyaW5nIHR5cGUpIHsKKyAgICAgICAgaWYgKGVycm9ySGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgICAgICAvLyBUT0RPOiBhYm9ydCBpZiBoYW5kbGVFcnJvciByZXR1cm5zIGZhbHNlCisgICAgICAgICAgICBlcnJvckhhbmRsZXIuaGFuZGxlRXJyb3IobmV3IERPTUVycm9ySW1wbChzZXZlcml0eSwgdHlwZSkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL0RPTUVycm9ySW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL0RPTUVycm9ySW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA2ZTY2OWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vRE9NRXJyb3JJbXBsLmphdmEKQEAgLTAsMCArMSw3NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhtbC5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01FcnJvcjsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01Mb2NhdG9yOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBET01FcnJvckltcGwgaW1wbGVtZW50cyBET01FcnJvciB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRE9NTG9jYXRvciBOVUxMX0RPTV9MT0NBVE9SID0gbmV3IERPTUxvY2F0b3IoKSB7CisgICAgICAgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgaW50IGdldEJ5dGVPZmZzZXQoKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGludCBnZXRVdGYxNk9mZnNldCgpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgTm9kZSBnZXRSZWxhdGVkTm9kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VXJpKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9OworCisgICAgcHJpdmF0ZSBmaW5hbCBzaG9ydCBzZXZlcml0eTsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyB0eXBlOworCisgICAgcHVibGljIERPTUVycm9ySW1wbChzaG9ydCBzZXZlcml0eSwgU3RyaW5nIHR5cGUpIHsKKyAgICAgICAgdGhpcy5zZXZlcml0eSA9IHNldmVyaXR5OworICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgIH0KKworICAgIHB1YmxpYyBzaG9ydCBnZXRTZXZlcml0eSgpIHsKKyAgICAgICAgcmV0dXJuIHNldmVyaXR5OworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKyAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRUeXBlKCkgeworICAgICAgICByZXR1cm4gdHlwZTsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldFJlbGF0ZWRFeGNlcHRpb24oKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0UmVsYXRlZERhdGEoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBET01Mb2NhdG9yIGdldExvY2F0aW9uKCkgeworICAgICAgICByZXR1cm4gTlVMTF9ET01fTE9DQVRPUjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vRE9NSW1wbGVtZW50YXRpb25JbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vRE9NSW1wbGVtZW50YXRpb25JbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTg1MmU2YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9ET01JbXBsZW1lbnRhdGlvbkltcGwuamF2YQpAQCAtMCwwICsxLDkwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG1sLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7CisKKy8qKgorICogUHJvdmlkZXMgYSBzdHJhaWdodGZvcndhcmQgaW1wbGVtZW50YXRpb24gb2YgdGhlIGNvcnJlc3BvbmRpbmcgVzNDIERPTQorICogaW50ZXJmYWNlLiBUaGUgY2xhc3MgaXMgdXNlZCBpbnRlcm5hbGx5IG9ubHksIHRodXMgb25seSBub3RhYmxlIG1lbWJlcnMgdGhhdAorICogYXJlIG5vdCBpbiB0aGUgb3JpZ2luYWwgaW50ZXJmYWNlIGFyZSBkb2N1bWVudGVkICh0aGUgVzNDIGRvY3MgYXJlIHF1aXRlCisgKiBleHRlbnNpdmUpLiBIb3BlIHRoYXQncyBvay4KKyAqIDxwPgorICogU29tZSBvZiB0aGUgZmllbGRzIG1heSBoYXZlIHBhY2thZ2UgdmlzaWJpbGl0eSwgc28gb3RoZXIgY2xhc3NlcyBiZWxvbmdpbmcgdG8KKyAqIHRoZSBET00gaW1wbGVtZW50YXRpb24gY2FuIGVhc2lseSBhY2Nlc3MgdGhlbSB3aGlsZSBtYWludGFpbmluZyB0aGUgRE9NIHRyZWUKKyAqIHN0cnVjdHVyZS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIERPTUltcGxlbWVudGF0aW9uSW1wbCBpbXBsZW1lbnRzIERPTUltcGxlbWVudGF0aW9uIHsKKworICAgIC8vIFNpbmdsZXRvbiBpbnN0YW5jZS4KKyAgICBwcml2YXRlIHN0YXRpYyBET01JbXBsZW1lbnRhdGlvbkltcGwgaW5zdGFuY2U7CisKKyAgICBET01JbXBsZW1lbnRhdGlvbkltcGwoKSB7CisgICAgfQorCisgICAgcHVibGljIERvY3VtZW50IGNyZWF0ZURvY3VtZW50KFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBxdWFsaWZpZWROYW1lLAorICAgICAgICAgICAgRG9jdW1lbnRUeXBlIGRvY3R5cGUpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3IERvY3VtZW50SW1wbCh0aGlzLCBuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsIGRvY3R5cGUsIG51bGwpOworICAgIH0KKworICAgIHB1YmxpYyBEb2N1bWVudFR5cGUgY3JlYXRlRG9jdW1lbnRUeXBlKFN0cmluZyBxdWFsaWZpZWROYW1lLAorICAgICAgICAgICAgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3IERvY3VtZW50VHlwZUltcGwobnVsbCwgcXVhbGlmaWVkTmFtZSwgcHVibGljSWQsIHN5c3RlbUlkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNGZWF0dXJlKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikgeworICAgICAgICBib29sZWFuIGFueVZlcnNpb24gPSB2ZXJzaW9uID09IG51bGwgfHwgdmVyc2lvbi5sZW5ndGgoKSA9PSAwOworICAgICAgICBpZiAoZmVhdHVyZS5zdGFydHNXaXRoKCIrIikpIHsKKyAgICAgICAgICAgIGZlYXR1cmUgPSBmZWF0dXJlLnN1YnN0cmluZygxKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRPRE86IGZ1bGx5IGltcGxlbWVudCB0aGVzZSBBUElzOgorICAgICAgICAvLyAiTFMiIChvcmcudzNjLmRvbS5scykgdmVyc2lvbnMgIjMuMCIKKyAgICAgICAgLy8gIkVsZW1lbnRUcmF2ZXJzYWwiIChvcmcudzNjLmRvbS50cmF2ZXJzYWwpIHZlcnNpb25zICIxLjAiCisKKyAgICAgICAgaWYgKGZlYXR1cmUuZXF1YWxzSWdub3JlQ2FzZSgiQ29yZSIpKSB7CisgICAgICAgICAgICByZXR1cm4gYW55VmVyc2lvbiB8fCB2ZXJzaW9uLmVxdWFscygiMS4wIikgfHwgdmVyc2lvbi5lcXVhbHMoIjIuMCIpIHx8IHZlcnNpb24uZXF1YWxzKCIzLjAiKTsKKyAgICAgICAgfSBlbHNlIGlmIChmZWF0dXJlLmVxdWFsc0lnbm9yZUNhc2UoIlhNTCIpKSB7CisgICAgICAgICAgICByZXR1cm4gYW55VmVyc2lvbiB8fCB2ZXJzaW9uLmVxdWFscygiMS4wIikgfHwgdmVyc2lvbi5lcXVhbHMoIjIuMCIpIHx8IHZlcnNpb24uZXF1YWxzKCIzLjAiKTsKKyAgICAgICAgfSBlbHNlIGlmIChmZWF0dXJlLmVxdWFsc0lnbm9yZUNhc2UoIlhNTFZlcnNpb24iKSkgeworICAgICAgICAgICAgcmV0dXJuIGFueVZlcnNpb24gfHwgdmVyc2lvbi5lcXVhbHMoIjEuMCIpIHx8IHZlcnNpb24uZXF1YWxzKCIxLjEiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcXVlc3RzIHRoZSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgdGhlIGNsYXNzLiBDcmVhdGVzIGl0IGZpcnN0LCBpZgorICAgICAqIG5lY2Vzc2FyeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIHNpbmdsZXRvbiBBbmRyb2lkIERPTUltcGxlbWVudGF0aW9uSW1wbCBpbnN0YW5jZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIERPTUltcGxlbWVudGF0aW9uSW1wbCBnZXRJbnN0YW5jZSgpIHsKKyAgICAgICAgaWYgKGluc3RhbmNlID09IG51bGwpIHsKKyAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IERPTUltcGxlbWVudGF0aW9uSW1wbCgpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGluc3RhbmNlOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pIHsKKyAgICAgICAgcmV0dXJuIGhhc0ZlYXR1cmUoZmVhdHVyZSwgdmVyc2lvbikgPyB0aGlzIDogbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vRG9jdW1lbnRGcmFnbWVudEltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9Eb2N1bWVudEZyYWdtZW50SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFhMzM2MzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vRG9jdW1lbnRGcmFnbWVudEltcGwuamF2YQpAQCAtMCwwICsxLDQ5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG1sLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKKworLyoqCisgKiBQcm92aWRlcyBhIHN0cmFpZ2h0Zm9yd2FyZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgY29ycmVzcG9uZGluZyBXM0MgRE9NCisgKiBpbnRlcmZhY2UuIFRoZSBjbGFzcyBpcyB1c2VkIGludGVybmFsbHkgb25seSwgdGh1cyBvbmx5IG5vdGFibGUgbWVtYmVycyB0aGF0CisgKiBhcmUgbm90IGluIHRoZSBvcmlnaW5hbCBpbnRlcmZhY2UgYXJlIGRvY3VtZW50ZWQgKHRoZSBXM0MgZG9jcyBhcmUgcXVpdGUKKyAqIGV4dGVuc2l2ZSkuIEhvcGUgdGhhdCdzIG9rLgorICogPHA+CisgKiBTb21lIG9mIHRoZSBmaWVsZHMgbWF5IGhhdmUgcGFja2FnZSB2aXNpYmlsaXR5LCBzbyBvdGhlciBjbGFzc2VzIGJlbG9uZ2luZyB0bworICogdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBjYW4gZWFzaWx5IGFjY2VzcyB0aGVtIHdoaWxlIG1haW50YWluaW5nIHRoZSBET00gdHJlZQorICogc3RydWN0dXJlLgorICovCitwdWJsaWMgY2xhc3MgRG9jdW1lbnRGcmFnbWVudEltcGwgZXh0ZW5kcyBJbm5lck5vZGVJbXBsIGltcGxlbWVudHMKKyAgICAgICAgRG9jdW1lbnRGcmFnbWVudCB7CisKKyAgICBEb2N1bWVudEZyYWdtZW50SW1wbChEb2N1bWVudEltcGwgZG9jdW1lbnQpIHsKKyAgICAgICAgc3VwZXIoZG9jdW1lbnQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKSB7CisgICAgICAgIHJldHVybiAiI2RvY3VtZW50LWZyYWdtZW50IjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc2hvcnQgZ2V0Tm9kZVR5cGUoKSB7CisgICAgICAgIHJldHVybiBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREU7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vRG9jdW1lbnRJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vRG9jdW1lbnRJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTFiNjJmYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9Eb2N1bWVudEltcGwuamF2YQpAQCAtMCwwICsxLDU0OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhtbC5kb207CisKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuV2Vha0hhc2hNYXA7CitpbXBvcnQgb3JnLnczYy5kb20uQ2hhcmFjdGVyRGF0YTsKK2ltcG9ydCBvcmcudzNjLmRvbS5Db21tZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworaW1wb3J0IG9yZy53M2MuZG9tLlByb2Nlc3NpbmdJbnN0cnVjdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5UZXh0OworaW1wb3J0IG9yZy53M2MuZG9tLlVzZXJEYXRhSGFuZGxlcjsKKworLyoqCisgKiBQcm92aWRlcyBhIHN0cmFpZ2h0Zm9yd2FyZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgY29ycmVzcG9uZGluZyBXM0MgRE9NCisgKiBpbnRlcmZhY2UuIFRoZSBjbGFzcyBpcyB1c2VkIGludGVybmFsbHkgb25seSwgdGh1cyBvbmx5IG5vdGFibGUgbWVtYmVycyB0aGF0CisgKiBhcmUgbm90IGluIHRoZSBvcmlnaW5hbCBpbnRlcmZhY2UgYXJlIGRvY3VtZW50ZWQgKHRoZSBXM0MgZG9jcyBhcmUgcXVpdGUKKyAqIGV4dGVuc2l2ZSkuIEhvcGUgdGhhdCdzIG9rLgorICogPHA+CisgKiBTb21lIG9mIHRoZSBmaWVsZHMgbWF5IGhhdmUgcGFja2FnZSB2aXNpYmlsaXR5LCBzbyBvdGhlciBjbGFzc2VzIGJlbG9uZ2luZyB0bworICogdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBjYW4gZWFzaWx5IGFjY2VzcyB0aGVtIHdoaWxlIG1haW50YWluaW5nIHRoZSBET00gdHJlZQorICogc3RydWN0dXJlLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRG9jdW1lbnRJbXBsIGV4dGVuZHMgSW5uZXJOb2RlSW1wbCBpbXBsZW1lbnRzIERvY3VtZW50IHsKKworICAgIHByaXZhdGUgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbGVtZW50YXRpb247CisgICAgcHJpdmF0ZSBET01Db25maWd1cmF0aW9uSW1wbCBkb21Db25maWd1cmF0aW9uOworCisgICAgLyoKKyAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZXMgb2YgdGhlc2UgZmllbGRzIGFyZSBzcGVjaWZpZWQgYnkgdGhlIERvY3VtZW50CisgICAgICogaW50ZXJmYWNlLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGRvY3VtZW50VXJpOworICAgIHByaXZhdGUgU3RyaW5nIGlucHV0RW5jb2Rpbmc7CisgICAgcHJpdmF0ZSBTdHJpbmcgeG1sRW5jb2Rpbmc7CisgICAgcHJpdmF0ZSBTdHJpbmcgeG1sVmVyc2lvbiA9ICIxLjAiOworICAgIHByaXZhdGUgYm9vbGVhbiB4bWxTdGFuZGFsb25lID0gZmFsc2U7CisgICAgcHJpdmF0ZSBib29sZWFuIHN0cmljdEVycm9yQ2hlY2tpbmcgPSB0cnVlOworCisgICAgLyoqCisgICAgICogQSBsYXppbHkgaW5pdGlhbGl6ZWQgbWFwIG9mIHVzZXIgZGF0YSB2YWx1ZXMgZm9yIHRoaXMgZG9jdW1lbnQncyBvd24KKyAgICAgKiBub2Rlcy4gVGhlIG1hcCBpcyB3ZWFrIGJlY2F1c2UgdGhlIGRvY3VtZW50IG1heSBsaXZlIGxvbmdlciB0aGFuIGl0cworICAgICAqIG5vZGVzLgorICAgICAqCisgICAgICogPHA+QXR0YWNoaW5nIHVzZXIgZGF0YSBkaXJlY3RseSB0byB0aGUgY29ycmVzcG9uZGluZyBub2RlIHdvdWxkIGNvc3QgYQorICAgICAqIGZpZWxkIHBlciBub2RlLiBVbmRlciB0aGUgYXNzdW1wdGlvbiB0aGF0IHVzZXIgZGF0YSBpcyByYXJlbHkgbmVlZGVkLCB3ZQorICAgICAqIGF0dGFjaCB1c2VyIGRhdGEgdG8gdGhlIGRvY3VtZW50IHRvIHNhdmUgdGhvc2UgZmllbGRzLiBYZXJjZXMgYWxzbyB0YWtlcworICAgICAqIHRoaXMgYXBwcm9hY2guCisgICAgICovCisgICAgcHJpdmF0ZSBXZWFrSGFzaE1hcDxOb2RlSW1wbCwgTWFwPFN0cmluZywgVXNlckRhdGE+PiBub2RlVG9Vc2VyRGF0YTsKKworICAgIHB1YmxpYyBEb2N1bWVudEltcGwoRE9NSW1wbGVtZW50YXRpb25JbXBsIGltcGwsIFN0cmluZyBuYW1lc3BhY2VVUkksCisgICAgICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSwgRG9jdW1lbnRUeXBlIGRvY3R5cGUsIFN0cmluZyBpbnB1dEVuY29kaW5nKSB7CisgICAgICAgIHN1cGVyKG51bGwpOworICAgICAgICB0aGlzLmRvY3VtZW50ID0gdGhpczsKKyAgICAgICAgdGhpcy5kb21JbXBsZW1lbnRhdGlvbiA9IGltcGw7CisgICAgICAgIHRoaXMuaW5wdXRFbmNvZGluZyA9IGlucHV0RW5jb2Rpbmc7CisKKyAgICAgICAgaWYgKGRvY3R5cGUgIT0gbnVsbCkgeworICAgICAgICAgICAgYXBwZW5kQ2hpbGQoZG9jdHlwZSk7CisgICAgICAgIH0KKworICAgICAgICBpZiAocXVhbGlmaWVkTmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICBhcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzWE1MSWRlbnRpZmllclN0YXJ0KGNoYXIgYykgeworICAgICAgICByZXR1cm4gKGMgPj0gJ0EnICYmIGMgPD0gJ1onKSB8fCAoYyA+PSAnYScgJiYgYyA8PSAneicpIHx8IChjID09ICdfJyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1hNTElkZW50aWZpZXJQYXJ0KGNoYXIgYykgeworICAgICAgICByZXR1cm4gaXNYTUxJZGVudGlmaWVyU3RhcnQoYykgfHwgKGMgPj0gJzAnICYmIGMgPD0gJzknKSB8fCAoYyA9PSAnLScpIHx8IChjID09ICcuJyk7CisgICAgfQorCisgICAgc3RhdGljIGJvb2xlYW4gaXNYTUxJZGVudGlmaWVyKFN0cmluZyBzKSB7CisgICAgICAgIGlmIChzLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghaXNYTUxJZGVudGlmaWVyU3RhcnQocy5jaGFyQXQoMCkpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IHMubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgaWYgKCFpc1hNTElkZW50aWZpZXJQYXJ0KHMuY2hhckF0KGkpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzaGFsbG93IGNvcHkgb2YgdGhlIGdpdmVuIG5vZGUuIElmIHRoZSBub2RlIGlzIGFuIGVsZW1lbnQgbm9kZSwKKyAgICAgKiBpdHMgYXR0cmlidXRlcyBhcmUgYWx3YXlzIGNvcGllZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBub2RlIGEgbm9kZSBiZWxvbmdpbmcgdG8gYW55IGRvY3VtZW50IG9yIERPTSBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKiBAcGFyYW0gb3BlcmF0aW9uIHRoZSBvcGVyYXRpb24gdHlwZSB0byB1c2Ugd2hlbiBub3RpZnlpbmcgdXNlciBkYXRhCisgICAgICogICAgIGhhbmRsZXJzIG9mIGNvcGllZCBlbGVtZW50IGF0dHJpYnV0ZXMuIEl0IGlzIHRoZSBjYWxsZXIncworICAgICAqICAgICByZXNwb25zaWJpbGl0eSB0byBub3RpZnkgdXNlciBkYXRhIGhhbmRsZXJzIG9mIHRoZSByZXR1cm5lZCBub2RlLgorICAgICAqIEByZXR1cm4gYSBuZXcgbm9kZSB3aG9zZSBkb2N1bWVudCBpcyB0aGlzIGRvY3VtZW50IGFuZCB3aG9zZSBET00KKyAgICAgKiAgICAgaW1wbGVtZW50YXRpb24gaXMgdGhpcyBET00gaW1wbGVtZW50YXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBOb2RlSW1wbCBzaGFsbG93Q29weShzaG9ydCBvcGVyYXRpb24sIE5vZGUgbm9kZSkgeworICAgICAgICBzd2l0Y2ggKG5vZGUuZ2V0Tm9kZVR5cGUoKSkgeworICAgICAgICBjYXNlIE5vZGUuQVRUUklCVVRFX05PREU6CisgICAgICAgICAgICBBdHRySW1wbCBhdHRyID0gKEF0dHJJbXBsKSBub2RlOworICAgICAgICAgICAgQXR0ckltcGwgYXR0ckNvcHk7CisgICAgICAgICAgICBpZiAoYXR0ci5uYW1lc3BhY2VBd2FyZSkgeworICAgICAgICAgICAgICAgIGF0dHJDb3B5ID0gY3JlYXRlQXR0cmlidXRlTlMoYXR0ci5nZXROYW1lc3BhY2VVUkkoKSwgYXR0ci5nZXRMb2NhbE5hbWUoKSk7CisgICAgICAgICAgICAgICAgYXR0ckNvcHkuc2V0UHJlZml4KGF0dHIuZ2V0UHJlZml4KCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhdHRyQ29weSA9IGNyZWF0ZUF0dHJpYnV0ZShhdHRyLmdldE5hbWUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhdHRyQ29weS5zZXROb2RlVmFsdWUoYXR0ci5nZXRWYWx1ZSgpKTsKKyAgICAgICAgICAgIHJldHVybiBhdHRyQ29weTsKKworICAgICAgICBjYXNlIE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFOgorICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUNEQVRBU2VjdGlvbigoKENoYXJhY3RlckRhdGEpIG5vZGUpLmdldERhdGEoKSk7CisKKyAgICAgICAgY2FzZSBOb2RlLkNPTU1FTlRfTk9ERToKKyAgICAgICAgICAgIHJldHVybiBjcmVhdGVDb21tZW50KCgoQ29tbWVudCkgbm9kZSkuZ2V0RGF0YSgpKTsKKworICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERToKKyAgICAgICAgICAgIHJldHVybiBjcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CisKKyAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREU6CisgICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9UWVBFX05PREU6CisgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwKKyAgICAgICAgICAgICAgICAgICAgIkNhbm5vdCBjb3B5IG5vZGUgb2YgdHlwZSAiICsgbm9kZS5nZXROb2RlVHlwZSgpKTsKKworICAgICAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFOgorICAgICAgICAgICAgRWxlbWVudEltcGwgZWxlbWVudCA9IChFbGVtZW50SW1wbCkgbm9kZTsKKyAgICAgICAgICAgIEVsZW1lbnRJbXBsIGVsZW1lbnRDb3B5OworICAgICAgICAgICAgaWYgKGVsZW1lbnQubmFtZXNwYWNlQXdhcmUpIHsKKyAgICAgICAgICAgICAgICBlbGVtZW50Q29weSA9IGNyZWF0ZUVsZW1lbnROUyhlbGVtZW50LmdldE5hbWVzcGFjZVVSSSgpLCBlbGVtZW50LmdldExvY2FsTmFtZSgpKTsKKyAgICAgICAgICAgICAgICBlbGVtZW50Q29weS5zZXRQcmVmaXgoZWxlbWVudC5nZXRQcmVmaXgoKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGVsZW1lbnRDb3B5ID0gY3JlYXRlRWxlbWVudChlbGVtZW50LmdldFRhZ05hbWUoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgICAgIEF0dHJJbXBsIGVsZW1lbnRBdHRyID0gKEF0dHJJbXBsKSBhdHRyaWJ1dGVzLml0ZW0oaSk7CisgICAgICAgICAgICAgICAgQXR0ckltcGwgZWxlbWVudEF0dHJDb3B5ID0gKEF0dHJJbXBsKSBzaGFsbG93Q29weShvcGVyYXRpb24sIGVsZW1lbnRBdHRyKTsKKyAgICAgICAgICAgICAgICBub3RpZnlVc2VyRGF0YUhhbmRsZXJzKG9wZXJhdGlvbiwgZWxlbWVudEF0dHIsIGVsZW1lbnRBdHRyQ29weSk7CisgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRBdHRyLm5hbWVzcGFjZUF3YXJlKSB7CisgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRDb3B5LnNldEF0dHJpYnV0ZU5vZGVOUyhlbGVtZW50QXR0ckNvcHkpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRDb3B5LnNldEF0dHJpYnV0ZU5vZGUoZWxlbWVudEF0dHJDb3B5KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZWxlbWVudENvcHk7CisKKyAgICAgICAgY2FzZSBOb2RlLkVOVElUWV9OT0RFOgorICAgICAgICBjYXNlIE5vZGUuTk9UQVRJT05fTk9ERToKKyAgICAgICAgICAgIC8vIFRPRE86IGltcGxlbWVudCB0aGlzIHdoZW4gd2Ugc3VwcG9ydCB0aGVzZSBub2RlIHR5cGVzCisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKworICAgICAgICBjYXNlIE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFOgorICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFdoZW4gd2Ugc3VwcG9ydCBlbnRpdGllcyBpbiB0aGUgZG9jdHlwZSwgdGhpcyB3aWxsIG5lZWQgdG8KKyAgICAgICAgICAgICAqIGJlaGF2ZSBkaWZmZXJlbnRseSBmb3IgY2xvbmVzIHZzLiBpbXBvcnRzLiBDbG9uZXMgY29weQorICAgICAgICAgICAgICogZW50aXRpZXMgYnkgdmFsdWUsIGNvcHlpbmcgdGhlIHJlZmVyZW5jZWQgc3VidHJlZSBmcm9tIHRoZQorICAgICAgICAgICAgICogb3JpZ2luYWwgZG9jdW1lbnQuIEltcG9ydHMgY29weSBlbnRpdGllcyBieSByZWZlcmVuY2UsCisgICAgICAgICAgICAgKiBwb3NzaWJseSByZWZlcnJpbmcgdG8gYSBkaWZmZXJlbnQgc3VidHJlZSBpbiB0aGUgbmV3CisgICAgICAgICAgICAgKiBkb2N1bWVudC4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUVudGl0eVJlZmVyZW5jZShub2RlLmdldE5vZGVOYW1lKCkpOworCisgICAgICAgIGNhc2UgTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU6CisgICAgICAgICAgICBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gcGkgPSAoUHJvY2Vzc2luZ0luc3RydWN0aW9uKSBub2RlOworICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbihwaS5nZXRUYXJnZXQoKSwgcGkuZ2V0RGF0YSgpKTsKKworICAgICAgICBjYXNlIE5vZGUuVEVYVF9OT0RFOgorICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVRleHROb2RlKCgoVGV4dCkgbm9kZSkuZ2V0RGF0YSgpKTsKKworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsCisgICAgICAgICAgICAgICAgICAgICJVbnN1cHBvcnRlZCBub2RlIHR5cGUgIiArIG5vZGUuZ2V0Tm9kZVR5cGUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29weSBvZiB0aGUgZ2l2ZW4gbm9kZSBvciBzdWJ0cmVlIHdpdGggdGhpcyBkb2N1bWVudCBhcyBpdHMKKyAgICAgKiBvd25lci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcGVyYXRpb24gZWl0aGVyIHtAbGluayBVc2VyRGF0YUhhbmRsZXIjTk9ERV9DTE9ORUR9IG9yCisgICAgICogICAgICB7QGxpbmsgVXNlckRhdGFIYW5kbGVyI05PREVfSU1QT1JURUR9LgorICAgICAqIEBwYXJhbSBub2RlIGEgbm9kZSBiZWxvbmdpbmcgdG8gYW55IGRvY3VtZW50IG9yIERPTSBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKiBAcGFyYW0gZGVlcCB0cnVlIHRvIHJlY3Vyc2l2ZWx5IGNvcHkgYW55IGNoaWxkIG5vZGVzOyBmYWxzZSB0byBkbyBubyBzdWNoCisgICAgICogICAgICBjb3B5aW5nIGFuZCByZXR1cm4gYSBub2RlIHdpdGggbm8gY2hpbGRyZW4uCisgICAgICovCisgICAgTm9kZSBjbG9uZU9ySW1wb3J0Tm9kZShzaG9ydCBvcGVyYXRpb24sIE5vZGUgbm9kZSwgYm9vbGVhbiBkZWVwKSB7CisgICAgICAgIE5vZGVJbXBsIGNvcHkgPSBzaGFsbG93Q29weShvcGVyYXRpb24sIG5vZGUpOworCisgICAgICAgIGlmIChkZWVwKSB7CisgICAgICAgICAgICBOb2RlTGlzdCBsaXN0ID0gbm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxpc3QuZ2V0TGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgICAgIGNvcHkuYXBwZW5kQ2hpbGQoY2xvbmVPckltcG9ydE5vZGUob3BlcmF0aW9uLCBsaXN0Lml0ZW0oaSksIGRlZXApKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIG5vdGlmeVVzZXJEYXRhSGFuZGxlcnMob3BlcmF0aW9uLCBub2RlLCBjb3B5KTsKKyAgICAgICAgcmV0dXJuIGNvcHk7CisgICAgfQorCisgICAgcHVibGljIE5vZGUgaW1wb3J0Tm9kZShOb2RlIGltcG9ydGVkTm9kZSwgYm9vbGVhbiBkZWVwKSB7CisgICAgICAgIHJldHVybiBjbG9uZU9ySW1wb3J0Tm9kZShVc2VyRGF0YUhhbmRsZXIuTk9ERV9JTVBPUlRFRCwgaW1wb3J0ZWROb2RlLCBkZWVwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRhY2hlcyB0aGUgbm9kZSBmcm9tIGl0cyBwYXJlbnQgKGlmIGFueSkgYW5kIGNoYW5nZXMgaXRzIGRvY3VtZW50IHRvCisgICAgICogdGhpcyBkb2N1bWVudC4gVGhlIG5vZGUncyBzdWJ0cmVlIGFuZCBhdHRyaWJ1dGVzIHdpbGwgcmVtYWluIGF0dGFjaGVkLAorICAgICAqIGJ1dCB0aGVpciBkb2N1bWVudCB3aWxsIGJlIGNoYW5nZWQgdG8gdGhpcyBkb2N1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9kZSBhZG9wdE5vZGUoTm9kZSBub2RlKSB7CisgICAgICAgIGlmICghKG5vZGUgaW5zdGFuY2VvZiBOb2RlSW1wbCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOyAvLyB0aGUgQVBJIHNwZWNpZmllcyB0aGlzIHF1aWV0IGZhaWx1cmUKKyAgICAgICAgfQorICAgICAgICBOb2RlSW1wbCBub2RlSW1wbCA9IChOb2RlSW1wbCkgbm9kZTsKKyAgICAgICAgc3dpdGNoIChub2RlSW1wbC5nZXROb2RlVHlwZSgpKSB7CisgICAgICAgICAgICBjYXNlIE5vZGUuQVRUUklCVVRFX05PREU6CisgICAgICAgICAgICAgICAgQXR0ckltcGwgYXR0ciA9IChBdHRySW1wbCkgbm9kZTsKKyAgICAgICAgICAgICAgICBpZiAoYXR0ci5vd25lckVsZW1lbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBhdHRyLm93bmVyRWxlbWVudC5yZW1vdmVBdHRyaWJ1dGVOb2RlKGF0dHIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREU6CisgICAgICAgICAgICBjYXNlIE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFOgorICAgICAgICAgICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERToKKyAgICAgICAgICAgIGNhc2UgTm9kZS5URVhUX05PREU6CisgICAgICAgICAgICBjYXNlIE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFOgorICAgICAgICAgICAgY2FzZSBOb2RlLkNPTU1FTlRfTk9ERToKKyAgICAgICAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFOgorICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX1RZUEVfTk9ERToKKyAgICAgICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfTk9ERToKKyAgICAgICAgICAgIGNhc2UgTm9kZS5OT1RBVElPTl9OT0RFOgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLAorICAgICAgICAgICAgICAgICAgICAgICAgIkNhbm5vdCBhZG9wdCBub2RlcyBvZiB0eXBlICIgKyBub2RlSW1wbC5nZXROb2RlVHlwZSgpKTsKKworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJVbnN1cHBvcnRlZCBub2RlIHR5cGUgIiArIG5vZGUuZ2V0Tm9kZVR5cGUoKSk7CisgICAgICAgIH0KKworICAgICAgICBOb2RlIHBhcmVudCA9IG5vZGVJbXBsLmdldFBhcmVudE5vZGUoKTsKKyAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsKSB7CisgICAgICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQobm9kZUltcGwpOworICAgICAgICB9CisKKyAgICAgICAgY2hhbmdlRG9jdW1lbnRUb1RoaXMobm9kZUltcGwpOworICAgICAgICBub3RpZnlVc2VyRGF0YUhhbmRsZXJzKFVzZXJEYXRhSGFuZGxlci5OT0RFX0FET1BURUQsIG5vZGUsIG51bGwpOworICAgICAgICByZXR1cm4gbm9kZUltcGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVjdXJzaXZlbHkgY2hhbmdlIHRoZSBkb2N1bWVudCBvZiB7QGNvZGUgbm9kZX0gd2l0aG91dCBhbHNvIGNoYW5naW5nIGl0cworICAgICAqIHBhcmVudCBub2RlLiBPbmx5IGFkb3B0Tm9kZSgpIHNob3VsZCBpbnZva2UgdGhpcyBtZXRob2QsIG90aGVyd2lzZSBub2RlcworICAgICAqIHdpbGwgYmUgbGVmdCBpbiBhbiBpbmNvbnNpc3RlbnQgc3RhdGUuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoYW5nZURvY3VtZW50VG9UaGlzKE5vZGVJbXBsIG5vZGUpIHsKKyAgICAgICAgTWFwPFN0cmluZywgVXNlckRhdGE+IHVzZXJEYXRhID0gbm9kZS5kb2N1bWVudC5nZXRVc2VyRGF0YU1hcEZvclJlYWQobm9kZSk7CisgICAgICAgIGlmICghdXNlckRhdGEuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBnZXRVc2VyRGF0YU1hcChub2RlKS5wdXRBbGwodXNlckRhdGEpOworICAgICAgICB9CisgICAgICAgIG5vZGUuZG9jdW1lbnQgPSB0aGlzOworCisgICAgICAgIC8vIGNoYW5nZSB0aGUgZG9jdW1lbnQgb24gYWxsIGNoaWxkIG5vZGVzCisgICAgICAgIE5vZGVMaXN0IGxpc3QgPSBub2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsaXN0LmdldExlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgICAgIGNoYW5nZURvY3VtZW50VG9UaGlzKChOb2RlSW1wbCkgbGlzdC5pdGVtKGkpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNoYW5nZSB0aGUgZG9jdW1lbnQgb24gYWxsIGF0dHJpYnV0ZSBub2RlcworICAgICAgICBpZiAobm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7CisgICAgICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlcyA9IG5vZGUuZ2V0QXR0cmlidXRlcygpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICBjaGFuZ2VEb2N1bWVudFRvVGhpcygoQXR0ckltcGwpIGF0dHJpYnV0ZXMuaXRlbShpKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgTm9kZSByZW5hbWVOb2RlKE5vZGUgbm9kZSwgU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIHF1YWxpZmllZE5hbWUpIHsKKyAgICAgICAgaWYgKG5vZGUuZ2V0T3duZXJEb2N1bWVudCgpICE9IHRoaXMpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUiwgbnVsbCk7CisgICAgICAgIH0KKworICAgICAgICBzZXROYW1lTlMoKE5vZGVJbXBsKSBub2RlLCBuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgICBub3RpZnlVc2VyRGF0YUhhbmRsZXJzKFVzZXJEYXRhSGFuZGxlci5OT0RFX1JFTkFNRUQsIG5vZGUsIG51bGwpOworICAgICAgICByZXR1cm4gbm9kZTsKKyAgICB9CisKKyAgICBwdWJsaWMgQXR0ckltcGwgY3JlYXRlQXR0cmlidXRlKFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiBuZXcgQXR0ckltcGwodGhpcywgbmFtZSk7CisgICAgfQorCisgICAgcHVibGljIEF0dHJJbXBsIGNyZWF0ZUF0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBxdWFsaWZpZWROYW1lKSB7CisgICAgICAgIHJldHVybiBuZXcgQXR0ckltcGwodGhpcywgbmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQ0RBVEFTZWN0aW9uSW1wbCBjcmVhdGVDREFUQVNlY3Rpb24oU3RyaW5nIGRhdGEpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBDREFUQVNlY3Rpb25JbXBsKHRoaXMsIGRhdGEpOworICAgIH0KKworICAgIHB1YmxpYyBDb21tZW50SW1wbCBjcmVhdGVDb21tZW50KFN0cmluZyBkYXRhKSB7CisgICAgICAgIHJldHVybiBuZXcgQ29tbWVudEltcGwodGhpcywgZGF0YSk7CisgICAgfQorCisgICAgcHVibGljIERvY3VtZW50RnJhZ21lbnRJbXBsIGNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSB7CisgICAgICAgIHJldHVybiBuZXcgRG9jdW1lbnRGcmFnbWVudEltcGwodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIEVsZW1lbnRJbXBsIGNyZWF0ZUVsZW1lbnQoU3RyaW5nIHRhZ05hbWUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBFbGVtZW50SW1wbCh0aGlzLCB0YWdOYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRWxlbWVudEltcGwgY3JlYXRlRWxlbWVudE5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBxdWFsaWZpZWROYW1lKSB7CisgICAgICAgIHJldHVybiBuZXcgRWxlbWVudEltcGwodGhpcywgbmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRW50aXR5UmVmZXJlbmNlSW1wbCBjcmVhdGVFbnRpdHlSZWZlcmVuY2UoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBFbnRpdHlSZWZlcmVuY2VJbXBsKHRoaXMsIG5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25JbXBsIGNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkgeworICAgICAgICByZXR1cm4gbmV3IFByb2Nlc3NpbmdJbnN0cnVjdGlvbkltcGwodGhpcywgdGFyZ2V0LCBkYXRhKTsKKyAgICB9CisKKyAgICBwdWJsaWMgVGV4dEltcGwgY3JlYXRlVGV4dE5vZGUoU3RyaW5nIGRhdGEpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBUZXh0SW1wbCh0aGlzLCBkYXRhKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRG9jdW1lbnRUeXBlIGdldERvY3R5cGUoKSB7CisgICAgICAgIGZvciAoTGVhZk5vZGVJbXBsIGNoaWxkIDogY2hpbGRyZW4pIHsKKyAgICAgICAgICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIERvY3VtZW50VHlwZSkgeworICAgICAgICAgICAgICAgIHJldHVybiAoRG9jdW1lbnRUeXBlKSBjaGlsZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBFbGVtZW50IGdldERvY3VtZW50RWxlbWVudCgpIHsKKyAgICAgICAgZm9yIChMZWFmTm9kZUltcGwgY2hpbGQgOiBjaGlsZHJlbikgeworICAgICAgICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgRWxlbWVudCkgeworICAgICAgICAgICAgICAgIHJldHVybiAoRWxlbWVudCkgY2hpbGQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgRWxlbWVudCBnZXRFbGVtZW50QnlJZChTdHJpbmcgZWxlbWVudElkKSB7CisgICAgICAgIEVsZW1lbnRJbXBsIHJvb3QgPSAoRWxlbWVudEltcGwpIGdldERvY3VtZW50RWxlbWVudCgpOworCisgICAgICAgIHJldHVybiAocm9vdCA9PSBudWxsID8gbnVsbCA6IHJvb3QuZ2V0RWxlbWVudEJ5SWQoZWxlbWVudElkKSk7CisgICAgfQorCisgICAgcHVibGljIE5vZGVMaXN0IGdldEVsZW1lbnRzQnlUYWdOYW1lKFN0cmluZyBuYW1lKSB7CisgICAgICAgIE5vZGVMaXN0SW1wbCByZXN1bHQgPSBuZXcgTm9kZUxpc3RJbXBsKCk7CisgICAgICAgIGdldEVsZW1lbnRzQnlUYWdOYW1lKHJlc3VsdCwgbmFtZSk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIE5vZGVMaXN0IGdldEVsZW1lbnRzQnlUYWdOYW1lTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkgeworICAgICAgICBOb2RlTGlzdEltcGwgcmVzdWx0ID0gbmV3IE5vZGVMaXN0SW1wbCgpOworICAgICAgICBnZXRFbGVtZW50c0J5VGFnTmFtZU5TKHJlc3VsdCwgbmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBET01JbXBsZW1lbnRhdGlvbiBnZXRJbXBsZW1lbnRhdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIGRvbUltcGxlbWVudGF0aW9uOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKSB7CisgICAgICAgIHJldHVybiAiI2RvY3VtZW50IjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc2hvcnQgZ2V0Tm9kZVR5cGUoKSB7CisgICAgICAgIHJldHVybiBOb2RlLkRPQ1VNRU5UX05PREU7CisgICAgfQorCisgICAgLyoqCisgICAgICogRG9jdW1lbnQgZWxlbWVudHMgbWF5IGhhdmUgYXQgbW9zdCBvbmUgcm9vdCBlbGVtZW50IGFuZCBhdCBtb3N0IG9uZSBEVEQKKyAgICAgKiBlbGVtZW50LgorICAgICAqLworICAgIEBPdmVycmlkZSBwdWJsaWMgTm9kZSBpbnNlcnRDaGlsZEF0KE5vZGUgdG9JbnNlcnQsIGludCBpbmRleCkgeworICAgICAgICBpZiAodG9JbnNlcnQgaW5zdGFuY2VvZiBFbGVtZW50ICYmIGdldERvY3VtZW50RWxlbWVudCgpICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUiwKKyAgICAgICAgICAgICAgICAgICAgIk9ubHkgb25lIHJvb3QgZWxlbWVudCBhbGxvd2VkIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRvSW5zZXJ0IGluc3RhbmNlb2YgRG9jdW1lbnRUeXBlICYmIGdldERvY3R5cGUoKSAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5ISUVSQVJDSFlfUkVRVUVTVF9FUlIsCisgICAgICAgICAgICAgICAgICAgICJPbmx5IG9uZSBET0NUWVBFIGVsZW1lbnQgYWxsb3dlZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzdXBlci5pbnNlcnRDaGlsZEF0KHRvSW5zZXJ0LCBpbmRleCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgZ2V0VGV4dENvbnRlbnQoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0SW5wdXRFbmNvZGluZygpIHsKKyAgICAgICAgcmV0dXJuIGlucHV0RW5jb2Rpbmc7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRYbWxFbmNvZGluZygpIHsKKyAgICAgICAgcmV0dXJuIHhtbEVuY29kaW5nOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGdldFhtbFN0YW5kYWxvbmUoKSB7CisgICAgICAgIHJldHVybiB4bWxTdGFuZGFsb25lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFhtbFN0YW5kYWxvbmUoYm9vbGVhbiB4bWxTdGFuZGFsb25lKSB7CisgICAgICAgIHRoaXMueG1sU3RhbmRhbG9uZSA9IHhtbFN0YW5kYWxvbmU7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRYbWxWZXJzaW9uKCkgeworICAgICAgICByZXR1cm4geG1sVmVyc2lvbjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRYbWxWZXJzaW9uKFN0cmluZyB4bWxWZXJzaW9uKSB7CisgICAgICAgIHRoaXMueG1sVmVyc2lvbiA9IHhtbFZlcnNpb247CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZ2V0U3RyaWN0RXJyb3JDaGVja2luZygpIHsKKyAgICAgICAgcmV0dXJuIHN0cmljdEVycm9yQ2hlY2tpbmc7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3RyaWN0RXJyb3JDaGVja2luZyhib29sZWFuIHN0cmljdEVycm9yQ2hlY2tpbmcpIHsKKyAgICAgICAgdGhpcy5zdHJpY3RFcnJvckNoZWNraW5nID0gc3RyaWN0RXJyb3JDaGVja2luZzsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VVJJKCkgeworICAgICAgICByZXR1cm4gZG9jdW1lbnRVcmk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRVUkkoU3RyaW5nIGRvY3VtZW50VXJpKSB7CisgICAgICAgIHRoaXMuZG9jdW1lbnRVcmkgPSBkb2N1bWVudFVyaTsKKyAgICB9CisKKyAgICBwdWJsaWMgRE9NQ29uZmlndXJhdGlvbiBnZXREb21Db25maWcoKSB7CisgICAgICAgIGlmIChkb21Db25maWd1cmF0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24gPSBuZXcgRE9NQ29uZmlndXJhdGlvbkltcGwoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZG9tQ29uZmlndXJhdGlvbjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBub3JtYWxpemVEb2N1bWVudCgpIHsKKyAgICAgICAgRWxlbWVudCByb290ID0gZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIGlmIChyb290ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgICgoRE9NQ29uZmlndXJhdGlvbkltcGwpIGdldERvbUNvbmZpZygpKS5ub3JtYWxpemUocm9vdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG1hcCB3aXRoIHRoZSB1c2VyIGRhdGEgb2JqZWN0cyBhdHRhY2hlZCB0byB0aGUgc3BlY2lmaWVkIG5vZGUuCisgICAgICogVGhpcyBtYXAgaXMgcmVhZGFibGUgYW5kIHdyaXRhYmxlLgorICAgICAqLworICAgIE1hcDxTdHJpbmcsIFVzZXJEYXRhPiBnZXRVc2VyRGF0YU1hcChOb2RlSW1wbCBub2RlKSB7CisgICAgICAgIGlmIChub2RlVG9Vc2VyRGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICBub2RlVG9Vc2VyRGF0YSA9IG5ldyBXZWFrSGFzaE1hcDxOb2RlSW1wbCwgTWFwPFN0cmluZywgVXNlckRhdGE+PigpOworICAgICAgICB9CisgICAgICAgIE1hcDxTdHJpbmcsIFVzZXJEYXRhPiB1c2VyRGF0YU1hcCA9IG5vZGVUb1VzZXJEYXRhLmdldChub2RlKTsKKyAgICAgICAgaWYgKHVzZXJEYXRhTWFwID09IG51bGwpIHsKKyAgICAgICAgICAgIHVzZXJEYXRhTWFwID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBVc2VyRGF0YT4oKTsKKyAgICAgICAgICAgIG5vZGVUb1VzZXJEYXRhLnB1dChub2RlLCB1c2VyRGF0YU1hcCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHVzZXJEYXRhTWFwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBtYXAgd2l0aCB0aGUgdXNlciBkYXRhIG9iamVjdHMgYXR0YWNoZWQgdG8gdGhlIHNwZWNpZmllZCBub2RlLgorICAgICAqIFRoZSByZXR1cm5lZCBtYXAgbWF5IGJlIHJlYWQtb25seS4KKyAgICAgKi8KKyAgICBNYXA8U3RyaW5nLCBVc2VyRGF0YT4gZ2V0VXNlckRhdGFNYXBGb3JSZWFkKE5vZGVJbXBsIG5vZGUpIHsKKyAgICAgICAgaWYgKG5vZGVUb1VzZXJEYXRhID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbXB0eU1hcCgpOworICAgICAgICB9CisgICAgICAgIE1hcDxTdHJpbmcsIFVzZXJEYXRhPiB1c2VyRGF0YU1hcCA9IG5vZGVUb1VzZXJEYXRhLmdldChub2RlKTsKKyAgICAgICAgcmV0dXJuIHVzZXJEYXRhTWFwID09IG51bGwKKyAgICAgICAgICAgICAgICA/IENvbGxlY3Rpb25zLjxTdHJpbmcsIFVzZXJEYXRhPmVtcHR5TWFwKCkKKyAgICAgICAgICAgICAgICA6IHVzZXJEYXRhTWFwOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGxzIHtAbGluayBVc2VyRGF0YUhhbmRsZXIjaGFuZGxlfSBvbiBlYWNoIG9mIHRoZSBzb3VyY2Ugbm9kZSdzCisgICAgICogdmFsdWUvaGFuZGxlciBwYWlycy4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBzb3VyY2Ugbm9kZSBjb21lcyBmcm9tIGFub3RoZXIgRE9NIGltcGxlbWVudGF0aW9uLCB1c2VyIGRhdGEKKyAgICAgKiBoYW5kbGVycyB3aWxsIDxzdHJvbmc+bm90PC9zdHJvbmc+IGJlIG5vdGlmaWVkLiBUaGUgRE9NIEFQSSBwcm92aWRlcyBubworICAgICAqIG1lY2hhbmlzbSB0byBpbnNwZWN0IGEgZm9yZWlnbiBub2RlJ3MgdXNlciBkYXRhLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgbm90aWZ5VXNlckRhdGFIYW5kbGVycygKKyAgICAgICAgICAgIHNob3J0IG9wZXJhdGlvbiwgTm9kZSBzb3VyY2UsIE5vZGVJbXBsIGRlc3RpbmF0aW9uKSB7CisgICAgICAgIGlmICghKHNvdXJjZSBpbnN0YW5jZW9mIE5vZGVJbXBsKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgTm9kZUltcGwgc3JjSW1wbCA9IChOb2RlSW1wbCkgc291cmNlOworICAgICAgICBpZiAoc3JjSW1wbC5kb2N1bWVudCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBmb3IgKE1hcC5FbnRyeTxTdHJpbmcsIFVzZXJEYXRhPiBlbnRyeQorICAgICAgICAgICAgICAgIDogc3JjSW1wbC5kb2N1bWVudC5nZXRVc2VyRGF0YU1hcEZvclJlYWQoc3JjSW1wbCkuZW50cnlTZXQoKSkgeworICAgICAgICAgICAgVXNlckRhdGEgdXNlckRhdGEgPSBlbnRyeS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgaWYgKHVzZXJEYXRhLmhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHVzZXJEYXRhLmhhbmRsZXIuaGFuZGxlKAorICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uLCBlbnRyeS5nZXRLZXkoKSwgdXNlckRhdGEudmFsdWUsIHNvdXJjZSwgZGVzdGluYXRpb24pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL0RvY3VtZW50VHlwZUltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9Eb2N1bWVudFR5cGVJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDliOTAzZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9Eb2N1bWVudFR5cGVJbXBsLmphdmEKQEAgLTAsMCArMSwxMTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bWwuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKKworLyoqCisgKiBQcm92aWRlcyBhIHN0cmFpZ2h0Zm9yd2FyZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgY29ycmVzcG9uZGluZyBXM0MgRE9NCisgKiBpbnRlcmZhY2UuIFRoZSBjbGFzcyBpcyB1c2VkIGludGVybmFsbHkgb25seSwgdGh1cyBvbmx5IG5vdGFibGUgbWVtYmVycyB0aGF0CisgKiBhcmUgbm90IGluIHRoZSBvcmlnaW5hbCBpbnRlcmZhY2UgYXJlIGRvY3VtZW50ZWQgKHRoZSBXM0MgZG9jcyBhcmUgcXVpdGUKKyAqIGV4dGVuc2l2ZSkuIEhvcGUgdGhhdCdzIG9rLgorICogPHA+CisgKiBTb21lIG9mIHRoZSBmaWVsZHMgbWF5IGhhdmUgcGFja2FnZSB2aXNpYmlsaXR5LCBzbyBvdGhlciBjbGFzc2VzIGJlbG9uZ2luZyB0bworICogdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBjYW4gZWFzaWx5IGFjY2VzcyB0aGVtIHdoaWxlIG1haW50YWluaW5nIHRoZSBET00gdHJlZQorICogc3RydWN0dXJlLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRG9jdW1lbnRUeXBlSW1wbCBleHRlbmRzIExlYWZOb2RlSW1wbCBpbXBsZW1lbnRzIERvY3VtZW50VHlwZSB7CisKKyAgICBwcml2YXRlIFN0cmluZyBxdWFsaWZpZWROYW1lOworCisgICAgcHJpdmF0ZSBTdHJpbmcgcHVibGljSWQ7CisKKyAgICBwcml2YXRlIFN0cmluZyBzeXN0ZW1JZDsKKworICAgIHB1YmxpYyBEb2N1bWVudFR5cGVJbXBsKERvY3VtZW50SW1wbCBkb2N1bWVudCwgU3RyaW5nIHF1YWxpZmllZE5hbWUsCisgICAgICAgICAgICBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkgeworICAgICAgICBzdXBlcihkb2N1bWVudCk7CisKKyAgICAgICAgaWYgKHF1YWxpZmllZE5hbWUgPT0gbnVsbCB8fCAiIi5lcXVhbHMocXVhbGlmaWVkTmFtZSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIsIHF1YWxpZmllZE5hbWUpOworICAgICAgICB9CisKKyAgICAgICAgaW50IHByZWZpeFNlcGFyYXRvciA9IHF1YWxpZmllZE5hbWUubGFzdEluZGV4T2YoIjoiKTsKKyAgICAgICAgaWYgKHByZWZpeFNlcGFyYXRvciAhPSAtMSkgeworICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IHF1YWxpZmllZE5hbWUuc3Vic3RyaW5nKDAsIHByZWZpeFNlcGFyYXRvcik7CisgICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gcXVhbGlmaWVkTmFtZS5zdWJzdHJpbmcocHJlZml4U2VwYXJhdG9yICsgMSk7CisKKyAgICAgICAgICAgIGlmICghRG9jdW1lbnRJbXBsLmlzWE1MSWRlbnRpZmllcihwcmVmaXgpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUiwgcXVhbGlmaWVkTmFtZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICghRG9jdW1lbnRJbXBsLmlzWE1MSWRlbnRpZmllcihsb2NhbE5hbWUpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmICghRG9jdW1lbnRJbXBsLmlzWE1MSWRlbnRpZmllcihxdWFsaWZpZWROYW1lKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUiwgcXVhbGlmaWVkTmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0aGlzLnF1YWxpZmllZE5hbWUgPSBxdWFsaWZpZWROYW1lOworICAgICAgICB0aGlzLnB1YmxpY0lkID0gcHVibGljSWQ7CisgICAgICAgIHRoaXMuc3lzdGVtSWQgPSBzeXN0ZW1JZDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkgeworICAgICAgICByZXR1cm4gcXVhbGlmaWVkTmFtZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc2hvcnQgZ2V0Tm9kZVR5cGUoKSB7CisgICAgICAgIHJldHVybiBOb2RlLkRPQ1VNRU5UX1RZUEVfTk9ERTsKKyAgICB9CisKKyAgICBwdWJsaWMgTmFtZWROb2RlTWFwIGdldEVudGl0aWVzKCkgeworICAgICAgICAvLyBUT0RPIER1bW15LiBJbXBsZW1lbnQgdGhpcyBsYXRlciwgaWYgYXQgYWxsICh3ZSdyZSBET00gbGV2ZWwgMiBvbmx5KS4KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRJbnRlcm5hbFN1YnNldCgpIHsKKyAgICAgICAgLy8gVE9ETyBEdW1teS4gSW1wbGVtZW50IHRoaXMgbGF0ZXIsIGlmIGF0IGFsbCAod2UncmUgRE9NIGxldmVsIDIgb25seSkuCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIHF1YWxpZmllZE5hbWU7CisgICAgfQorCisgICAgcHVibGljIE5hbWVkTm9kZU1hcCBnZXROb3RhdGlvbnMoKSB7CisgICAgICAgIC8vIFRPRE8gRHVtbXkuIEltcGxlbWVudCB0aGlzIGxhdGVyLCBpZiBhdCBhbGwgKHdlJ3JlIERPTSBsZXZlbCAyIG9ubHkpLgorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCkgeworICAgICAgICByZXR1cm4gcHVibGljSWQ7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKKyAgICAgICAgcmV0dXJuIHN5c3RlbUlkOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIGdldFRleHRDb250ZW50KCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9FbGVtZW50SW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL0VsZW1lbnRJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjg5YWVmNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9FbGVtZW50SW1wbC5qYXZhCkBAIC0wLDAgKzEsNDE1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG1sLmRvbTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgbGliY29yZS51dGlsLk9iamVjdHM7CitpbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKK2ltcG9ydCBvcmcudzNjLmRvbS5UeXBlSW5mbzsKKworLyoqCisgKiBQcm92aWRlcyBhIHN0cmFpZ2h0Zm9yd2FyZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgY29ycmVzcG9uZGluZyBXM0MgRE9NCisgKiBpbnRlcmZhY2UuIFRoZSBjbGFzcyBpcyB1c2VkIGludGVybmFsbHkgb25seSwgdGh1cyBvbmx5IG5vdGFibGUgbWVtYmVycyB0aGF0CisgKiBhcmUgbm90IGluIHRoZSBvcmlnaW5hbCBpbnRlcmZhY2UgYXJlIGRvY3VtZW50ZWQgKHRoZSBXM0MgZG9jcyBhcmUgcXVpdGUKKyAqIGV4dGVuc2l2ZSkuIEhvcGUgdGhhdCdzIG9rLgorICogPHA+CisgKiBTb21lIG9mIHRoZSBmaWVsZHMgbWF5IGhhdmUgcGFja2FnZSB2aXNpYmlsaXR5LCBzbyBvdGhlciBjbGFzc2VzIGJlbG9uZ2luZyB0bworICogdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBjYW4gZWFzaWx5IGFjY2VzcyB0aGVtIHdoaWxlIG1haW50YWluaW5nIHRoZSBET00gdHJlZQorICogc3RydWN0dXJlLgorICovCitwdWJsaWMgY2xhc3MgRWxlbWVudEltcGwgZXh0ZW5kcyBJbm5lck5vZGVJbXBsIGltcGxlbWVudHMgRWxlbWVudCB7CisKKyAgICBib29sZWFuIG5hbWVzcGFjZUF3YXJlOworICAgIFN0cmluZyBuYW1lc3BhY2VVUkk7CisgICAgU3RyaW5nIHByZWZpeDsKKyAgICBTdHJpbmcgbG9jYWxOYW1lOworCisgICAgcHJpdmF0ZSBMaXN0PEF0dHJJbXBsPiBhdHRyaWJ1dGVzID0gbmV3IEFycmF5TGlzdDxBdHRySW1wbD4oKTsKKworICAgIEVsZW1lbnRJbXBsKERvY3VtZW50SW1wbCBkb2N1bWVudCwgU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIHF1YWxpZmllZE5hbWUpIHsKKyAgICAgICAgc3VwZXIoZG9jdW1lbnQpOworICAgICAgICBzZXROYW1lTlModGhpcywgbmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICB9CisKKyAgICBFbGVtZW50SW1wbChEb2N1bWVudEltcGwgZG9jdW1lbnQsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIHN1cGVyKGRvY3VtZW50KTsKKyAgICAgICAgc2V0TmFtZSh0aGlzLCBuYW1lKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBpbmRleE9mQXR0cmlidXRlKFN0cmluZyBuYW1lKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXR0cmlidXRlcy5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgQXR0ckltcGwgYXR0ciA9IGF0dHJpYnV0ZXMuZ2V0KGkpOworICAgICAgICAgICAgaWYgKE9iamVjdHMuZXF1YWwobmFtZSwgYXR0ci5nZXROb2RlTmFtZSgpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIHByaXZhdGUgaW50IGluZGV4T2ZBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXR0cmlidXRlcy5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgQXR0ckltcGwgYXR0ciA9IGF0dHJpYnV0ZXMuZ2V0KGkpOworICAgICAgICAgICAgaWYgKE9iamVjdHMuZXF1YWwobmFtZXNwYWNlVVJJLCBhdHRyLmdldE5hbWVzcGFjZVVSSSgpKQorICAgICAgICAgICAgICAgICAgICAmJiBPYmplY3RzLmVxdWFsKGxvY2FsTmFtZSwgYXR0ci5nZXRMb2NhbE5hbWUoKSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSkgeworICAgICAgICBBdHRyIGF0dHIgPSBnZXRBdHRyaWJ1dGVOb2RlKG5hbWUpOworCisgICAgICAgIGlmIChhdHRyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBhdHRyLmdldFZhbHVlKCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKSB7CisgICAgICAgIEF0dHIgYXR0ciA9IGdldEF0dHJpYnV0ZU5vZGVOUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7CisKKyAgICAgICAgaWYgKGF0dHIgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuICIiOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGF0dHIuZ2V0VmFsdWUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQXR0ckltcGwgZ2V0QXR0cmlidXRlTm9kZShTdHJpbmcgbmFtZSkgeworICAgICAgICBpbnQgaSA9IGluZGV4T2ZBdHRyaWJ1dGUobmFtZSk7CisKKyAgICAgICAgaWYgKGkgPT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXMuZ2V0KGkpOworICAgIH0KKworICAgIHB1YmxpYyBBdHRySW1wbCBnZXRBdHRyaWJ1dGVOb2RlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkgeworICAgICAgICBpbnQgaSA9IGluZGV4T2ZBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7CisKKyAgICAgICAgaWYgKGkgPT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXMuZ2V0KGkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBOYW1lZE5vZGVNYXAgZ2V0QXR0cmlidXRlcygpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBFbGVtZW50QXR0ck5hbWVkTm9kZU1hcEltcGwoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHdhbGtzIHRoZSBlbnRpcmUgZG9jdW1lbnQgbG9va2luZyBmb3IgYW4gZWxlbWVudAorICAgICAqIHdpdGggdGhlIGdpdmVuIElEIGF0dHJpYnV0ZS4gV2Ugc2hvdWxkIGNvbnNpZGVyIGFkZGluZyBhbiBpbmRleCB0byBzcGVlZAorICAgICAqIG5hdmlnYXRpb24gb2YgbGFyZ2UgZG9jdW1lbnRzLgorICAgICAqLworICAgIEVsZW1lbnQgZ2V0RWxlbWVudEJ5SWQoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgZm9yIChBdHRyIGF0dHIgOiBhdHRyaWJ1dGVzKSB7CisgICAgICAgICAgICBpZiAoYXR0ci5pc0lkKCkgJiYgbmFtZS5lcXVhbHMoYXR0ci5nZXRWYWx1ZSgpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVE9ETzogUmVtb3ZlIHRoaXMgYmVoYXZpb3IuCisgICAgICAgICAqIFRoZSBzcGVjIGV4cGxpY2l0bHkgc2F5cyB0aGF0IHRoaXMgaXMgYSBiYWQgaWRlYS4gRnJvbQorICAgICAgICAgKiBEb2N1bWVudC5nZXRFbGVtZW50QnlJZCgpOiAiQXR0cmlidXRlcyB3aXRoIHRoZSBuYW1lICJJRCIKKyAgICAgICAgICogb3IgImlkIiBhcmUgbm90IG9mIHR5cGUgSUQgdW5sZXNzIHNvIGRlZmluZWQuCisgICAgICAgICAqLworICAgICAgICBpZiAobmFtZS5lcXVhbHMoZ2V0QXR0cmlidXRlKCJpZCIpKSkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKE5vZGVJbXBsIG5vZGUgOiBjaGlsZHJlbikgeworICAgICAgICAgICAgaWYgKG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkgeworICAgICAgICAgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9ICgoRWxlbWVudEltcGwpIG5vZGUpLmdldEVsZW1lbnRCeUlkKG5hbWUpOworICAgICAgICAgICAgICAgIGlmIChlbGVtZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIE5vZGVMaXN0IGdldEVsZW1lbnRzQnlUYWdOYW1lKFN0cmluZyBuYW1lKSB7CisgICAgICAgIE5vZGVMaXN0SW1wbCByZXN1bHQgPSBuZXcgTm9kZUxpc3RJbXBsKCk7CisgICAgICAgIGdldEVsZW1lbnRzQnlUYWdOYW1lKHJlc3VsdCwgbmFtZSk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIE5vZGVMaXN0IGdldEVsZW1lbnRzQnlUYWdOYW1lTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkgeworICAgICAgICBOb2RlTGlzdEltcGwgcmVzdWx0ID0gbmV3IE5vZGVMaXN0SW1wbCgpOworICAgICAgICBnZXRFbGVtZW50c0J5VGFnTmFtZU5TKHJlc3VsdCwgbmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKCkgeworICAgICAgICByZXR1cm4gbmFtZXNwYWNlQXdhcmUgPyBsb2NhbE5hbWUgOiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKCkgeworICAgICAgICByZXR1cm4gbmFtZXNwYWNlVVJJOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKSB7CisgICAgICAgIHJldHVybiBnZXRUYWdOYW1lKCk7CisgICAgfQorCisgICAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKCkgeworICAgICAgICByZXR1cm4gTm9kZS5FTEVNRU5UX05PREU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoKSB7CisgICAgICAgIHJldHVybiBwcmVmaXg7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRUYWdOYW1lKCkgeworICAgICAgICByZXR1cm4gcHJlZml4ICE9IG51bGwKKyAgICAgICAgICAgICAgICA/IHByZWZpeCArICI6IiArIGxvY2FsTmFtZQorICAgICAgICAgICAgICAgIDogbG9jYWxOYW1lOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZShTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gaW5kZXhPZkF0dHJpYnV0ZShuYW1lKSAhPSAtMTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKSB7CisgICAgICAgIHJldHVybiBpbmRleE9mQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpICE9IC0xOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZXMoKSB7CisgICAgICAgIHJldHVybiAhYXR0cmlidXRlcy5pc0VtcHR5KCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVtb3ZlQXR0cmlidXRlKFN0cmluZyBuYW1lKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGkgPSBpbmRleE9mQXR0cmlidXRlKG5hbWUpOworCisgICAgICAgIGlmIChpICE9IC0xKSB7CisgICAgICAgICAgICBhdHRyaWJ1dGVzLnJlbW92ZShpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlbW92ZUF0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpCisgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGkgPSBpbmRleE9mQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworCisgICAgICAgIGlmIChpICE9IC0xKSB7CisgICAgICAgICAgICBhdHRyaWJ1dGVzLnJlbW92ZShpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBBdHRyIHJlbW92ZUF0dHJpYnV0ZU5vZGUoQXR0ciBvbGRBdHRyKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgQXR0ckltcGwgb2xkQXR0ckltcGwgPSAoQXR0ckltcGwpIG9sZEF0dHI7CisKKyAgICAgICAgaWYgKG9sZEF0dHJJbXBsLmdldE93bmVyRWxlbWVudCgpICE9IHRoaXMpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIsIG51bGwpOworICAgICAgICB9CisKKyAgICAgICAgYXR0cmlidXRlcy5yZW1vdmUob2xkQXR0ckltcGwpOworICAgICAgICBvbGRBdHRySW1wbC5vd25lckVsZW1lbnQgPSBudWxsOworCisgICAgICAgIHJldHVybiBvbGRBdHRySW1wbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIEF0dHIgYXR0ciA9IGdldEF0dHJpYnV0ZU5vZGUobmFtZSk7CisKKyAgICAgICAgaWYgKGF0dHIgPT0gbnVsbCkgeworICAgICAgICAgICAgYXR0ciA9IGRvY3VtZW50LmNyZWF0ZUF0dHJpYnV0ZShuYW1lKTsKKyAgICAgICAgICAgIHNldEF0dHJpYnV0ZU5vZGUoYXR0cik7CisgICAgICAgIH0KKworICAgICAgICBhdHRyLnNldFZhbHVlKHZhbHVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgcXVhbGlmaWVkTmFtZSwKKyAgICAgICAgICAgIFN0cmluZyB2YWx1ZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIEF0dHIgYXR0ciA9IGdldEF0dHJpYnV0ZU5vZGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworCisgICAgICAgIGlmIChhdHRyID09IG51bGwpIHsKKyAgICAgICAgICAgIGF0dHIgPSBkb2N1bWVudC5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgICAgICAgc2V0QXR0cmlidXRlTm9kZU5TKGF0dHIpOworICAgICAgICB9CisKKyAgICAgICAgYXR0ci5zZXRWYWx1ZSh2YWx1ZSk7CisgICAgfQorCisgICAgcHVibGljIEF0dHIgc2V0QXR0cmlidXRlTm9kZShBdHRyIG5ld0F0dHIpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICBBdHRySW1wbCBuZXdBdHRySW1wbCA9IChBdHRySW1wbCkgbmV3QXR0cjsKKworICAgICAgICBpZiAobmV3QXR0ckltcGwuZG9jdW1lbnQgIT0gdGhpcy5kb2N1bWVudCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSLCBudWxsKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChuZXdBdHRySW1wbC5nZXRPd25lckVsZW1lbnQoKSAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5JTlVTRV9BVFRSSUJVVEVfRVJSLCBudWxsKTsKKyAgICAgICAgfQorCisgICAgICAgIEF0dHJJbXBsIG9sZEF0dHJJbXBsID0gbnVsbDsKKworICAgICAgICBpbnQgaSA9IGluZGV4T2ZBdHRyaWJ1dGUobmV3QXR0ci5nZXROYW1lKCkpOworICAgICAgICBpZiAoaSAhPSAtMSkgeworICAgICAgICAgICAgb2xkQXR0ckltcGwgPSBhdHRyaWJ1dGVzLmdldChpKTsKKyAgICAgICAgICAgIGF0dHJpYnV0ZXMucmVtb3ZlKGkpOworICAgICAgICB9CisKKyAgICAgICAgYXR0cmlidXRlcy5hZGQobmV3QXR0ckltcGwpOworICAgICAgICBuZXdBdHRySW1wbC5vd25lckVsZW1lbnQgPSB0aGlzOworCisgICAgICAgIHJldHVybiBvbGRBdHRySW1wbDsKKyAgICB9CisKKyAgICBwdWJsaWMgQXR0ciBzZXRBdHRyaWJ1dGVOb2RlTlMoQXR0ciBuZXdBdHRyKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgQXR0ckltcGwgbmV3QXR0ckltcGwgPSAoQXR0ckltcGwpIG5ld0F0dHI7CisKKyAgICAgICAgaWYgKG5ld0F0dHJJbXBsLmRvY3VtZW50ICE9IHRoaXMuZG9jdW1lbnQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUiwgbnVsbCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAobmV3QXR0ckltcGwuZ2V0T3duZXJFbGVtZW50KCkgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5VU0VfQVRUUklCVVRFX0VSUiwgbnVsbCk7CisgICAgICAgIH0KKworICAgICAgICBBdHRySW1wbCBvbGRBdHRySW1wbCA9IG51bGw7CisKKyAgICAgICAgaW50IGkgPSBpbmRleE9mQXR0cmlidXRlTlMobmV3QXR0ci5nZXROYW1lc3BhY2VVUkkoKSwgbmV3QXR0ci5nZXRMb2NhbE5hbWUoKSk7CisgICAgICAgIGlmIChpICE9IC0xKSB7CisgICAgICAgICAgICBvbGRBdHRySW1wbCA9IGF0dHJpYnV0ZXMuZ2V0KGkpOworICAgICAgICAgICAgYXR0cmlidXRlcy5yZW1vdmUoaSk7CisgICAgICAgIH0KKworICAgICAgICBhdHRyaWJ1dGVzLmFkZChuZXdBdHRySW1wbCk7CisgICAgICAgIG5ld0F0dHJJbXBsLm93bmVyRWxlbWVudCA9IHRoaXM7CisKKyAgICAgICAgcmV0dXJuIG9sZEF0dHJJbXBsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFByZWZpeChTdHJpbmcgcHJlZml4KSB7CisgICAgICAgIHRoaXMucHJlZml4ID0gdmFsaWRhdGVQcmVmaXgocHJlZml4LCBuYW1lc3BhY2VBd2FyZSwgbmFtZXNwYWNlVVJJKTsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgRWxlbWVudEF0dHJOYW1lZE5vZGVNYXBJbXBsIGltcGxlbWVudHMgTmFtZWROb2RlTWFwIHsKKworICAgICAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKKyAgICAgICAgICAgIHJldHVybiBFbGVtZW50SW1wbC50aGlzLmF0dHJpYnV0ZXMuc2l6ZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBpbnQgaW5kZXhPZkl0ZW0oU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgIHJldHVybiBFbGVtZW50SW1wbC50aGlzLmluZGV4T2ZBdHRyaWJ1dGUobmFtZSk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIGludCBpbmRleE9mSXRlbU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpIHsKKyAgICAgICAgICAgIHJldHVybiBFbGVtZW50SW1wbC50aGlzLmluZGV4T2ZBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTm9kZSBnZXROYW1lZEl0ZW0oU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgIHJldHVybiBFbGVtZW50SW1wbC50aGlzLmdldEF0dHJpYnV0ZU5vZGUobmFtZSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTm9kZSBnZXROYW1lZEl0ZW1OUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKSB7CisgICAgICAgICAgICByZXR1cm4gRWxlbWVudEltcGwudGhpcy5nZXRBdHRyaWJ1dGVOb2RlTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE5vZGUgaXRlbShpbnQgaW5kZXgpIHsKKyAgICAgICAgICAgIHJldHVybiBFbGVtZW50SW1wbC50aGlzLmF0dHJpYnV0ZXMuZ2V0KGluZGV4KTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBOb2RlIHJlbW92ZU5hbWVkSXRlbShTdHJpbmcgbmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpbnQgaSA9IGluZGV4T2ZJdGVtKG5hbWUpOworCisgICAgICAgICAgICBpZiAoaSA9PSAtMSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIsIG51bGwpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gRWxlbWVudEltcGwudGhpcy5hdHRyaWJ1dGVzLnJlbW92ZShpKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBOb2RlIHJlbW92ZU5hbWVkSXRlbU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpCisgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpbnQgaSA9IGluZGV4T2ZJdGVtTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworCisgICAgICAgICAgICBpZiAoaSA9PSAtMSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIsIG51bGwpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gRWxlbWVudEltcGwudGhpcy5hdHRyaWJ1dGVzLnJlbW92ZShpKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBOb2RlIHNldE5hbWVkSXRlbShOb2RlIGFyZykgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoIShhcmcgaW5zdGFuY2VvZiBBdHRyKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUiwgbnVsbCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBFbGVtZW50SW1wbC50aGlzLnNldEF0dHJpYnV0ZU5vZGUoKEF0dHIpYXJnKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBOb2RlIHNldE5hbWVkSXRlbU5TKE5vZGUgYXJnKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmICghKGFyZyBpbnN0YW5jZW9mIEF0dHIpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSLCBudWxsKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIEVsZW1lbnRJbXBsLnRoaXMuc2V0QXR0cmlidXRlTm9kZU5TKChBdHRyKWFyZyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgVHlwZUluZm8gZ2V0U2NoZW1hVHlwZUluZm8oKSB7CisgICAgICAgIC8vIFRPRE86IHBvcHVsYXRlIHRoaXMgd2hlbiB3ZSBzdXBwb3J0IFhNTCBTY2hlbWEKKyAgICAgICAgcmV0dXJuIE5VTExfVFlQRV9JTkZPOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElkQXR0cmlidXRlKFN0cmluZyBuYW1lLCBib29sZWFuIGlzSWQpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICBBdHRySW1wbCBhdHRyID0gZ2V0QXR0cmlidXRlTm9kZShuYW1lKTsKKyAgICAgICAgaWYgKGF0dHIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUiwKKyAgICAgICAgICAgICAgICAgICAgIk5vIHN1Y2ggYXR0cmlidXRlOiAiICsgbmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgYXR0ci5pc0lkID0gaXNJZDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJZEF0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUsCisgICAgICAgICAgICBib29sZWFuIGlzSWQpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICBBdHRySW1wbCBhdHRyID0gZ2V0QXR0cmlidXRlTm9kZU5TKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKKyAgICAgICAgaWYgKGF0dHIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUiwKKyAgICAgICAgICAgICAgICAgICAgIk5vIHN1Y2ggYXR0cmlidXRlOiAiICsgbmFtZXNwYWNlVVJJICsgICIgIiArIGxvY2FsTmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgYXR0ci5pc0lkID0gaXNJZDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJZEF0dHJpYnV0ZU5vZGUoQXR0ciBpZEF0dHIsIGJvb2xlYW4gaXNJZCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgICgoQXR0ckltcGwpIGlkQXR0cikuaXNJZCA9IGlzSWQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL0VudGl0eUltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9FbnRpdHlJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmI0YWZjMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9FbnRpdHlJbXBsLmphdmEKQEAgLTAsMCArMSw4MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhtbC5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5FbnRpdHk7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKKworLyoqCisgKiBQcm92aWRlcyBhIHN0cmFpZ2h0Zm9yd2FyZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgY29ycmVzcG9uZGluZyBXM0MgRE9NCisgKiBpbnRlcmZhY2UuIFRoZSBjbGFzcyBpcyB1c2VkIGludGVybmFsbHkgb25seSwgdGh1cyBvbmx5IG5vdGFibGUgbWVtYmVycyB0aGF0CisgKiBhcmUgbm90IGluIHRoZSBvcmlnaW5hbCBpbnRlcmZhY2UgYXJlIGRvY3VtZW50ZWQgKHRoZSBXM0MgZG9jcyBhcmUgcXVpdGUKKyAqIGV4dGVuc2l2ZSkuIEhvcGUgdGhhdCdzIG9rLgorICogPHA+CisgKiBTb21lIG9mIHRoZSBmaWVsZHMgbWF5IGhhdmUgcGFja2FnZSB2aXNpYmlsaXR5LCBzbyBvdGhlciBjbGFzc2VzIGJlbG9uZ2luZyB0bworICogdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBjYW4gZWFzaWx5IGFjY2VzcyB0aGVtIHdoaWxlIG1haW50YWluaW5nIHRoZSBET00gdHJlZQorICogc3RydWN0dXJlLgorICovCitwdWJsaWMgY2xhc3MgRW50aXR5SW1wbCBleHRlbmRzIE5vZGVJbXBsIGltcGxlbWVudHMgRW50aXR5IHsKKworICAgIHByaXZhdGUgU3RyaW5nIG5vdGF0aW9uTmFtZTsKKworICAgIHByaXZhdGUgU3RyaW5nIHB1YmxpY0lEOworCisgICAgcHJpdmF0ZSBTdHJpbmcgc3lzdGVtSUQ7CisKKyAgICBFbnRpdHlJbXBsKERvY3VtZW50SW1wbCBkb2N1bWVudCwgU3RyaW5nIG5vdGF0aW9uTmFtZSwgU3RyaW5nIHB1YmxpY0lELAorICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlEKSB7CisgICAgICAgIHN1cGVyKGRvY3VtZW50KTsKKyAgICAgICAgdGhpcy5ub3RhdGlvbk5hbWUgPSBub3RhdGlvbk5hbWU7CisgICAgICAgIHRoaXMucHVibGljSUQgPSBwdWJsaWNJRDsKKyAgICAgICAgdGhpcy5zeXN0ZW1JRCA9IHN5c3RlbUlEOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKSB7CisgICAgICAgIHJldHVybiBnZXROb3RhdGlvbk5hbWUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc2hvcnQgZ2V0Tm9kZVR5cGUoKSB7CisgICAgICAgIHJldHVybiBOb2RlLkVOVElUWV9OT0RFOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm90YXRpb25OYW1lKCkgeworICAgICAgICByZXR1cm4gbm90YXRpb25OYW1lOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKSB7CisgICAgICAgIHJldHVybiBwdWJsaWNJRDsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkgeworICAgICAgICByZXR1cm4gc3lzdGVtSUQ7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRJbnB1dEVuY29kaW5nKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsgLy8gVE9ETworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0WG1sRW5jb2RpbmcoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOyAvLyBUT0RPCisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRYbWxWZXJzaW9uKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsgLy8gVE9ETworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9FbnRpdHlSZWZlcmVuY2VJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vRW50aXR5UmVmZXJlbmNlSW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ0YjYyYjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vRW50aXR5UmVmZXJlbmNlSW1wbC5qYXZhCkBAIC0wLDAgKzEsNTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bWwuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRW50aXR5UmVmZXJlbmNlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CisKKy8qKgorICogUHJvdmlkZXMgYSBzdHJhaWdodGZvcndhcmQgaW1wbGVtZW50YXRpb24gb2YgdGhlIGNvcnJlc3BvbmRpbmcgVzNDIERPTQorICogaW50ZXJmYWNlLiBUaGUgY2xhc3MgaXMgdXNlZCBpbnRlcm5hbGx5IG9ubHksIHRodXMgb25seSBub3RhYmxlIG1lbWJlcnMgdGhhdAorICogYXJlIG5vdCBpbiB0aGUgb3JpZ2luYWwgaW50ZXJmYWNlIGFyZSBkb2N1bWVudGVkICh0aGUgVzNDIGRvY3MgYXJlIHF1aXRlCisgKiBleHRlbnNpdmUpLiBIb3BlIHRoYXQncyBvay4KKyAqIDxwPgorICogU29tZSBvZiB0aGUgZmllbGRzIG1heSBoYXZlIHBhY2thZ2UgdmlzaWJpbGl0eSwgc28gb3RoZXIgY2xhc3NlcyBiZWxvbmdpbmcgdG8KKyAqIHRoZSBET00gaW1wbGVtZW50YXRpb24gY2FuIGVhc2lseSBhY2Nlc3MgdGhlbSB3aGlsZSBtYWludGFpbmluZyB0aGUgRE9NIHRyZWUKKyAqIHN0cnVjdHVyZS4KKyAqLworcHVibGljIGNsYXNzIEVudGl0eVJlZmVyZW5jZUltcGwgZXh0ZW5kcyBMZWFmTm9kZUltcGwgaW1wbGVtZW50cyBFbnRpdHlSZWZlcmVuY2UgeworCisgICAgcHJpdmF0ZSBTdHJpbmcgbmFtZTsKKworICAgIEVudGl0eVJlZmVyZW5jZUltcGwoRG9jdW1lbnRJbXBsIGRvY3VtZW50LCBTdHJpbmcgbmFtZSkgeworICAgICAgICBzdXBlcihkb2N1bWVudCk7CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKCkgeworICAgICAgICByZXR1cm4gTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREU7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vSW5uZXJOb2RlSW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL0lubmVyTm9kZUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MTg3ODlkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL0lubmVyTm9kZUltcGwuamF2YQpAQCAtMCwwICsxLDI2MyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhtbC5kb207CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGxpYmNvcmUudXRpbC5PYmplY3RzOworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CisKKy8qKgorICogUHJvdmlkZXMgYSBzdHJhaWdodGZvcndhcmQgaW1wbGVtZW50YXRpb24gb2YgdGhlIGNvcnJlc3BvbmRpbmcgVzNDIERPTQorICogaW50ZXJmYWNlLiBUaGUgY2xhc3MgaXMgdXNlZCBpbnRlcm5hbGx5IG9ubHksIHRodXMgb25seSBub3RhYmxlIG1lbWJlcnMgdGhhdAorICogYXJlIG5vdCBpbiB0aGUgb3JpZ2luYWwgaW50ZXJmYWNlIGFyZSBkb2N1bWVudGVkICh0aGUgVzNDIGRvY3MgYXJlIHF1aXRlCisgKiBleHRlbnNpdmUpLgorICoKKyAqIDxwPlNvbWUgb2YgdGhlIGZpZWxkcyBtYXkgaGF2ZSBwYWNrYWdlIHZpc2liaWxpdHksIHNvIG90aGVyIGNsYXNzZXMgYmVsb25naW5nCisgKiB0byB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGNhbiBlYXNpbHkgYWNjZXNzIHRoZW0gd2hpbGUgbWFpbnRhaW5pbmcgdGhlIERPTQorICogdHJlZSBzdHJ1Y3R1cmUuCisgKgorICogPHA+VGhpcyBjbGFzcyByZXByZXNlbnRzIGEgTm9kZSB0aGF0IGhhcyBhIHBhcmVudCBOb2RlIGFzIHdlbGwgYXMKKyAqIChwb3RlbnRpYWxseSkgYSBudW1iZXIgb2YgY2hpbGRyZW4uCisgKgorICogPHA+U29tZSBjb2RlIHdhcyBhZGFwdGVkIGZyb20gQXBhY2hlIFhlcmNlcy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIElubmVyTm9kZUltcGwgZXh0ZW5kcyBMZWFmTm9kZUltcGwgeworCisgICAgLy8gTWFpbnRhaW5lZCBieSBMZWFmTm9kZUltcGwgYW5kIEVsZW1lbnRJbXBsLgorICAgIExpc3Q8TGVhZk5vZGVJbXBsPiBjaGlsZHJlbiA9IG5ldyBBcnJheUxpc3Q8TGVhZk5vZGVJbXBsPigpOworCisgICAgcHJvdGVjdGVkIElubmVyTm9kZUltcGwoRG9jdW1lbnRJbXBsIGRvY3VtZW50KSB7CisgICAgICAgIHN1cGVyKGRvY3VtZW50KTsKKyAgICB9CisKKyAgICBwdWJsaWMgTm9kZSBhcHBlbmRDaGlsZChOb2RlIG5ld0NoaWxkKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGluc2VydENoaWxkQXQobmV3Q2hpbGQsIGNoaWxkcmVuLnNpemUoKSk7CisgICAgfQorCisgICAgcHVibGljIE5vZGVMaXN0IGdldENoaWxkTm9kZXMoKSB7CisgICAgICAgIE5vZGVMaXN0SW1wbCBsaXN0ID0gbmV3IE5vZGVMaXN0SW1wbCgpOworCisgICAgICAgIGZvciAoTm9kZUltcGwgbm9kZSA6IGNoaWxkcmVuKSB7CisgICAgICAgICAgICBsaXN0LmFkZChub2RlKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBsaXN0OworICAgIH0KKworICAgIHB1YmxpYyBOb2RlIGdldEZpcnN0Q2hpbGQoKSB7CisgICAgICAgIHJldHVybiAoIWNoaWxkcmVuLmlzRW1wdHkoKSA/IGNoaWxkcmVuLmdldCgwKSA6IG51bGwpOworICAgIH0KKworICAgIHB1YmxpYyBOb2RlIGdldExhc3RDaGlsZCgpIHsKKyAgICAgICAgcmV0dXJuICghY2hpbGRyZW4uaXNFbXB0eSgpID8gY2hpbGRyZW4uZ2V0KGNoaWxkcmVuLnNpemUoKSAtIDEpIDogbnVsbCk7CisgICAgfQorCisgICAgcHVibGljIE5vZGUgZ2V0TmV4dFNpYmxpbmcoKSB7CisgICAgICAgIGlmIChwYXJlbnQgPT0gbnVsbCB8fCBpbmRleCArIDEgPj0gcGFyZW50LmNoaWxkcmVuLnNpemUoKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcGFyZW50LmNoaWxkcmVuLmdldChpbmRleCArIDEpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGhhc0NoaWxkTm9kZXMoKSB7CisgICAgICAgIHJldHVybiBjaGlsZHJlbi5zaXplKCkgIT0gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgTm9kZSBpbnNlcnRCZWZvcmUoTm9kZSBuZXdDaGlsZCwgTm9kZSByZWZDaGlsZCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIExlYWZOb2RlSW1wbCByZWZDaGlsZEltcGwgPSAoTGVhZk5vZGVJbXBsKSByZWZDaGlsZDsKKworICAgICAgICBpZiAocmVmQ2hpbGRJbXBsLmRvY3VtZW50ICE9IGRvY3VtZW50KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIsIG51bGwpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHJlZkNoaWxkSW1wbC5wYXJlbnQgIT0gdGhpcykgeworICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSLCBudWxsKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBpbnNlcnRDaGlsZEF0KG5ld0NoaWxkLCByZWZDaGlsZEltcGwuaW5kZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydHMge0Bjb2RlIG5ld0NoaWxkfSBhdCB7QGNvZGUgaW5kZXh9LiBJZiBpdCBpcyBhbHJlYWR5IGNoaWxkIG9mCisgICAgICogYW5vdGhlciBub2RlLCBpdCBpcyByZW1vdmVkIGZyb20gdGhlcmUuCisgICAgICovCisgICAgTm9kZSBpbnNlcnRDaGlsZEF0KE5vZGUgbmV3Q2hpbGQsIGludCBpbmRleCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChuZXdDaGlsZCBpbnN0YW5jZW9mIERvY3VtZW50RnJhZ21lbnQpIHsKKyAgICAgICAgICAgIE5vZGVMaXN0IHRvQWRkID0gbmV3Q2hpbGQuZ2V0Q2hpbGROb2RlcygpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0b0FkZC5nZXRMZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgaW5zZXJ0Q2hpbGRBdCh0b0FkZC5pdGVtKGkpLCBpbmRleCArIGkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ld0NoaWxkOworICAgICAgICB9CisKKyAgICAgICAgTGVhZk5vZGVJbXBsIHRvSW5zZXJ0ID0gKExlYWZOb2RlSW1wbCkgbmV3Q2hpbGQ7CisgICAgICAgIGlmICh0b0luc2VydC5kb2N1bWVudCAhPSBudWxsICYmIGRvY3VtZW50ICE9IG51bGwgJiYgdG9JbnNlcnQuZG9jdW1lbnQgIT0gZG9jdW1lbnQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUiwgbnVsbCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRvSW5zZXJ0LmlzUGFyZW50T2YodGhpcykpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUiwgbnVsbCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAodG9JbnNlcnQucGFyZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGludCBvbGRJbmRleCA9IHRvSW5zZXJ0LmluZGV4OworICAgICAgICAgICAgdG9JbnNlcnQucGFyZW50LmNoaWxkcmVuLnJlbW92ZShvbGRJbmRleCk7CisgICAgICAgICAgICB0b0luc2VydC5wYXJlbnQucmVmcmVzaEluZGljZXMob2xkSW5kZXgpOworICAgICAgICB9CisKKyAgICAgICAgY2hpbGRyZW4uYWRkKGluZGV4LCB0b0luc2VydCk7CisgICAgICAgIHRvSW5zZXJ0LnBhcmVudCA9IHRoaXM7CisgICAgICAgIHJlZnJlc2hJbmRpY2VzKGluZGV4KTsKKworICAgICAgICByZXR1cm4gbmV3Q2hpbGQ7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNQYXJlbnRPZihOb2RlIG5vZGUpIHsKKyAgICAgICAgTGVhZk5vZGVJbXBsIG5vZGVJbXBsID0gKExlYWZOb2RlSW1wbCkgbm9kZTsKKworICAgICAgICB3aGlsZSAobm9kZUltcGwgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKG5vZGVJbXBsID09IHRoaXMpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgbm9kZUltcGwgPSBub2RlSW1wbC5wYXJlbnQ7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogTm9ybWFsaXplIHRoZSB0ZXh0IG5vZGVzIHdpdGhpbiB0aGlzIHN1YnRyZWUuIEFsdGhvdWdoIG5hbWVkIHNpbWlsYXJseSwKKyAgICAgKiB0aGlzIG1ldGhvZCBpcyB1bnJlbGF0ZWQgdG8gRG9jdW1lbnQubm9ybWFsaXplLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBmaW5hbCB2b2lkIG5vcm1hbGl6ZSgpIHsKKyAgICAgICAgTm9kZSBuZXh0OworICAgICAgICBmb3IgKE5vZGUgbm9kZSA9IGdldEZpcnN0Q2hpbGQoKTsgbm9kZSAhPSBudWxsOyBub2RlID0gbmV4dCkgeworICAgICAgICAgICAgbmV4dCA9IG5vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKKyAgICAgICAgICAgIG5vZGUubm9ybWFsaXplKCk7CisKKyAgICAgICAgICAgIGlmIChub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpIHsKKyAgICAgICAgICAgICAgICAoKFRleHRJbXBsKSBub2RlKS5taW5pbWl6ZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlZnJlc2hJbmRpY2VzKGludCBmcm9tSW5kZXgpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IGZyb21JbmRleDsgaSA8IGNoaWxkcmVuLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICBjaGlsZHJlbi5nZXQoaSkuaW5kZXggPSBpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE5vZGUgcmVtb3ZlQ2hpbGQoTm9kZSBvbGRDaGlsZCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIExlYWZOb2RlSW1wbCBvbGRDaGlsZEltcGwgPSAoTGVhZk5vZGVJbXBsKSBvbGRDaGlsZDsKKworICAgICAgICBpZiAob2xkQ2hpbGRJbXBsLmRvY3VtZW50ICE9IGRvY3VtZW50KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIsIG51bGwpOworICAgICAgICB9CisgICAgICAgIGlmIChvbGRDaGlsZEltcGwucGFyZW50ICE9IHRoaXMpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUiwgbnVsbCk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgaW5kZXggPSBvbGRDaGlsZEltcGwuaW5kZXg7CisgICAgICAgIGNoaWxkcmVuLnJlbW92ZShpbmRleCk7CisgICAgICAgIG9sZENoaWxkSW1wbC5wYXJlbnQgPSBudWxsOworICAgICAgICByZWZyZXNoSW5kaWNlcyhpbmRleCk7CisKKyAgICAgICAgcmV0dXJuIG9sZENoaWxkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMge0Bjb2RlIG9sZENoaWxkfSBhbmQgYWRkcyB7QGNvZGUgbmV3Q2hpbGR9IGluIGl0cyBwbGFjZS4gVGhpcworICAgICAqIGlzIG5vdCBhdG9taWMuCisgICAgICovCisgICAgcHVibGljIE5vZGUgcmVwbGFjZUNoaWxkKE5vZGUgbmV3Q2hpbGQsIE5vZGUgb2xkQ2hpbGQpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICBpbnQgaW5kZXggPSAoKExlYWZOb2RlSW1wbCkgb2xkQ2hpbGQpLmluZGV4OworICAgICAgICByZW1vdmVDaGlsZChvbGRDaGlsZCk7CisgICAgICAgIGluc2VydENoaWxkQXQobmV3Q2hpbGQsIGluZGV4KTsKKyAgICAgICAgcmV0dXJuIG9sZENoaWxkOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGV4dENvbnRlbnQoKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgTm9kZSBjaGlsZCA9IGdldEZpcnN0Q2hpbGQoKTsKKyAgICAgICAgaWYgKGNoaWxkID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorCisgICAgICAgIE5vZGUgbmV4dCA9IGNoaWxkLmdldE5leHRTaWJsaW5nKCk7CisgICAgICAgIGlmIChuZXh0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBoYXNUZXh0Q29udGVudChjaGlsZCkgPyBjaGlsZC5nZXRUZXh0Q29udGVudCgpIDogIiI7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGdldFRleHRDb250ZW50KGJ1Zik7CisgICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICB2b2lkIGdldFRleHRDb250ZW50KFN0cmluZ0J1aWxkZXIgYnVmKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgTm9kZSBjaGlsZCA9IGdldEZpcnN0Q2hpbGQoKTsKKyAgICAgICAgd2hpbGUgKGNoaWxkICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChoYXNUZXh0Q29udGVudChjaGlsZCkpIHsKKyAgICAgICAgICAgICAgICAoKE5vZGVJbXBsKSBjaGlsZCkuZ2V0VGV4dENvbnRlbnQoYnVmKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGZpbmFsIGJvb2xlYW4gaGFzVGV4dENvbnRlbnQoTm9kZSBjaGlsZCkgeworICAgICAgICAvLyBUT0RPOiBza2lwIHRleHQgbm9kZXMgd2l0aCBpZ25vcmFibGUgd2hpdGVzcGFjZT8KKyAgICAgICAgcmV0dXJuIGNoaWxkLmdldE5vZGVUeXBlKCkgIT0gTm9kZS5DT01NRU5UX05PREUKKyAgICAgICAgICAgICAgICAmJiBjaGlsZC5nZXROb2RlVHlwZSgpICE9IE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFOworICAgIH0KKworICAgIHZvaWQgZ2V0RWxlbWVudHNCeVRhZ05hbWUoTm9kZUxpc3RJbXBsIG91dCwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgZm9yIChOb2RlSW1wbCBub2RlIDogY2hpbGRyZW4pIHsKKyAgICAgICAgICAgIGlmIChub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKKyAgICAgICAgICAgICAgICBFbGVtZW50SW1wbCBlbGVtZW50ID0gKEVsZW1lbnRJbXBsKSBub2RlOworICAgICAgICAgICAgICAgIGlmIChtYXRjaGVzTmFtZU9yV2lsZGNhcmQobmFtZSwgZWxlbWVudC5nZXROb2RlTmFtZSgpKSkgeworICAgICAgICAgICAgICAgICAgICBvdXQuYWRkKGVsZW1lbnQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKG91dCwgbmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICB2b2lkIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMoTm9kZUxpc3RJbXBsIG91dCwgU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkgeworICAgICAgICBmb3IgKE5vZGVJbXBsIG5vZGUgOiBjaGlsZHJlbikgeworICAgICAgICAgICAgaWYgKG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkgeworICAgICAgICAgICAgICAgIEVsZW1lbnRJbXBsIGVsZW1lbnQgPSAoRWxlbWVudEltcGwpIG5vZGU7CisgICAgICAgICAgICAgICAgaWYgKG1hdGNoZXNOYW1lT3JXaWxkY2FyZChuYW1lc3BhY2VVUkksIGVsZW1lbnQuZ2V0TmFtZXNwYWNlVVJJKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBtYXRjaGVzTmFtZU9yV2lsZGNhcmQobG9jYWxOYW1lLCBlbGVtZW50LmdldExvY2FsTmFtZSgpKSkgeworICAgICAgICAgICAgICAgICAgICBvdXQuYWRkKGVsZW1lbnQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lTlMob3V0LCBuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYge0Bjb2RlIHBhdHRlcm59IGVxdWFscyBlaXRoZXIgIioiIG9yIHtAY29kZSBzfS4gUGF0dGVybgorICAgICAqIG1heSBiZSB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBtYXRjaGVzTmFtZU9yV2lsZGNhcmQoU3RyaW5nIHBhdHRlcm4sIFN0cmluZyBzKSB7CisgICAgICAgIHJldHVybiAiKiIuZXF1YWxzKHBhdHRlcm4pIHx8IE9iamVjdHMuZXF1YWwocGF0dGVybiwgcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL0xlYWZOb2RlSW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL0xlYWZOb2RlSW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmViYjNmYzUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vTGVhZk5vZGVJbXBsLmphdmEKQEAgLTAsMCArMSw2OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhtbC5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworCisvKioKKyAqIFByb3ZpZGVzIGEgc3RyYWlnaHRmb3J3YXJkIGltcGxlbWVudGF0aW9uIG9mIHRoZSBjb3JyZXNwb25kaW5nIFczQyBET00KKyAqIGludGVyZmFjZS4gVGhlIGNsYXNzIGlzIHVzZWQgaW50ZXJuYWxseSBvbmx5LCB0aHVzIG9ubHkgbm90YWJsZSBtZW1iZXJzIHRoYXQKKyAqIGFyZSBub3QgaW4gdGhlIG9yaWdpbmFsIGludGVyZmFjZSBhcmUgZG9jdW1lbnRlZCAodGhlIFczQyBkb2NzIGFyZSBxdWl0ZQorICogZXh0ZW5zaXZlKS4gSG9wZSB0aGF0J3Mgb2suCisgKiA8cD4KKyAqIFNvbWUgb2YgdGhlIGZpZWxkcyBtYXkgaGF2ZSBwYWNrYWdlIHZpc2liaWxpdHksIHNvIG90aGVyIGNsYXNzZXMgYmVsb25naW5nIHRvCisgKiB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGNhbiBlYXNpbHkgYWNjZXNzIHRoZW0gd2hpbGUgbWFpbnRhaW5pbmcgdGhlIERPTSB0cmVlCisgKiBzdHJ1Y3R1cmUuCisgKiA8cD4KKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIE5vZGUgdGhhdCBoYXMgYSBwYXJlbnQgTm9kZSwgYnV0IG5vIGNoaWxkcmVuLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTGVhZk5vZGVJbXBsIGV4dGVuZHMgTm9kZUltcGwgeworCisgICAgLy8gTWFpbnRhaW5lZCBieSBJbm5lck5vZGVJbXBsLgorICAgIElubmVyTm9kZUltcGwgcGFyZW50OworCisgICAgLy8gTWFpbnRhaW5lZCBieSBJbm5lck5vZGVJbXBsLgorICAgIGludCBpbmRleDsKKworICAgIExlYWZOb2RlSW1wbChEb2N1bWVudEltcGwgZG9jdW1lbnQpIHsKKyAgICAgICAgc3VwZXIoZG9jdW1lbnQpOworICAgIH0KKworICAgIHB1YmxpYyBOb2RlIGdldE5leHRTaWJsaW5nKCkgeworICAgICAgICBpZiAocGFyZW50ID09IG51bGwgfHwgaW5kZXggKyAxID49IHBhcmVudC5jaGlsZHJlbi5zaXplKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHBhcmVudC5jaGlsZHJlbi5nZXQoaW5kZXggKyAxKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTm9kZSBnZXRQYXJlbnROb2RlKCkgeworICAgICAgICByZXR1cm4gcGFyZW50OworICAgIH0KKworICAgIHB1YmxpYyBOb2RlIGdldFByZXZpb3VzU2libGluZygpIHsKKyAgICAgICAgaWYgKHBhcmVudCA9PSBudWxsIHx8IGluZGV4ID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHBhcmVudC5jaGlsZHJlbi5nZXQoaW5kZXggLSAxKTsKKyAgICB9CisKKyAgICBib29sZWFuIGlzUGFyZW50T2YoTm9kZSBub2RlKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9Ob2RlSW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL05vZGVJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWYxMjkzYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9Ob2RlSW1wbC5qYXZhCkBAIC0wLDAgKzEsNzI2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG1sLmRvbTsKKworaW1wb3J0IGphdmEubmV0LlVSSTsKK2ltcG9ydCBqYXZhLm5ldC5VUklTeW50YXhFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IG9yZy53M2MuZG9tLkF0dHI7CitpbXBvcnQgb3JnLnczYy5kb20uQ2hhcmFjdGVyRGF0YTsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb247CitpbXBvcnQgb3JnLnczYy5kb20uVHlwZUluZm87CitpbXBvcnQgb3JnLnczYy5kb20uVXNlckRhdGFIYW5kbGVyOworCisvKioKKyAqIEEgc3RyYWlnaHRmb3J3YXJkIGltcGxlbWVudGF0aW9uIG9mIHRoZSBjb3JyZXNwb25kaW5nIFczQyBET00gbm9kZS4KKyAqCisgKiA8cD5Tb21lIGZpZWxkcyBoYXZlIHBhY2thZ2UgdmlzaWJpbGl0eSBzbyBvdGhlciBjbGFzc2VzIGNhbiBhY2Nlc3MgdGhlbSB3aGlsZQorICogbWFpbnRhaW5pbmcgdGhlIERPTSBzdHJ1Y3R1cmUuCisgKgorICogPHA+VGhpcyBjbGFzcyByZXByZXNlbnRzIGEgTm9kZSB0aGF0IGhhcyBuZWl0aGVyIGEgcGFyZW50IG5vciBjaGlsZHJlbi4KKyAqIFN1YmNsYXNzZXMgbWF5IGhhdmUgZWl0aGVyLgorICoKKyAqIDxwPlNvbWUgY29kZSB3YXMgYWRhcHRlZCBmcm9tIEFwYWNoZSBYZXJjZXMuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBOb2RlSW1wbCBpbXBsZW1lbnRzIE5vZGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTm9kZUxpc3QgRU1QVFlfTElTVCA9IG5ldyBOb2RlTGlzdEltcGwoKTsKKworICAgIHN0YXRpYyBmaW5hbCBUeXBlSW5mbyBOVUxMX1RZUEVfSU5GTyA9IG5ldyBUeXBlSW5mbygpIHsKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRUeXBlTmFtZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZU5hbWVzcGFjZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRGVyaXZlZEZyb20oCisgICAgICAgICAgICAgICAgU3RyaW5nIHR5cGVOYW1lc3BhY2VBcmcsIFN0cmluZyB0eXBlTmFtZUFyZywgaW50IGRlcml2YXRpb25NZXRob2QpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29udGFpbmluZyBkb2N1bWVudC4gVGhpcyBpcyBub24tbnVsbCBleGNlcHQgZm9yIERvY3VtZW50VHlwZUltcGwKKyAgICAgKiBub2RlcyBjcmVhdGVkIGJ5IHRoZSBET01JbXBsZW1lbnRhdGlvbi4KKyAgICAgKi8KKyAgICBEb2N1bWVudEltcGwgZG9jdW1lbnQ7CisKKyAgICBOb2RlSW1wbChEb2N1bWVudEltcGwgZG9jdW1lbnQpIHsKKyAgICAgICAgdGhpcy5kb2N1bWVudCA9IGRvY3VtZW50OworICAgIH0KKworICAgIHB1YmxpYyBOb2RlIGFwcGVuZENoaWxkKE5vZGUgbmV3Q2hpbGQpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5ISUVSQVJDSFlfUkVRVUVTVF9FUlIsIG51bGwpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBOb2RlIGNsb25lTm9kZShib29sZWFuIGRlZXApIHsKKyAgICAgICAgcmV0dXJuIGRvY3VtZW50LmNsb25lT3JJbXBvcnROb2RlKFVzZXJEYXRhSGFuZGxlci5OT0RFX0NMT05FRCwgdGhpcywgZGVlcCk7CisgICAgfQorCisgICAgcHVibGljIE5hbWVkTm9kZU1hcCBnZXRBdHRyaWJ1dGVzKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgTm9kZUxpc3QgZ2V0Q2hpbGROb2RlcygpIHsKKyAgICAgICAgcmV0dXJuIEVNUFRZX0xJU1Q7CisgICAgfQorCisgICAgcHVibGljIE5vZGUgZ2V0Rmlyc3RDaGlsZCgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIE5vZGUgZ2V0TGFzdENoaWxkKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBOb2RlIGdldE5leHRTaWJsaW5nKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgYWJzdHJhY3Qgc2hvcnQgZ2V0Tm9kZVR5cGUoKTsKKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZVZhbHVlKCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBEb2N1bWVudCBnZXRPd25lckRvY3VtZW50KCkgeworICAgICAgICByZXR1cm4gZG9jdW1lbnQgPT0gdGhpcyA/IG51bGwgOiBkb2N1bWVudDsKKyAgICB9CisKKyAgICBwdWJsaWMgTm9kZSBnZXRQYXJlbnROb2RlKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeCgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIE5vZGUgZ2V0UHJldmlvdXNTaWJsaW5nKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNBdHRyaWJ1dGVzKCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaGFzQ2hpbGROb2RlcygpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBOb2RlIGluc2VydEJlZm9yZShOb2RlIG5ld0NoaWxkLCBOb2RlIHJlZkNoaWxkKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSLCBudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1N1cHBvcnRlZChTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pIHsKKyAgICAgICAgcmV0dXJuIERPTUltcGxlbWVudGF0aW9uSW1wbC5nZXRJbnN0YW5jZSgpLmhhc0ZlYXR1cmUoZmVhdHVyZSwgdmVyc2lvbik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgbm9ybWFsaXplKCkgeworICAgIH0KKworICAgIHB1YmxpYyBOb2RlIHJlbW92ZUNoaWxkKE5vZGUgb2xkQ2hpbGQpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5ISUVSQVJDSFlfUkVRVUVTVF9FUlIsIG51bGwpOworICAgIH0KKworICAgIHB1YmxpYyBOb2RlIHJlcGxhY2VDaGlsZChOb2RlIG5ld0NoaWxkLCBOb2RlIG9sZENoaWxkKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSLCBudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXROb2RlVmFsdWUoU3RyaW5nIG5vZGVWYWx1ZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIHN3aXRjaCAoZ2V0Tm9kZVR5cGUoKSkgeworICAgICAgICAgICAgY2FzZSBDREFUQV9TRUNUSU9OX05PREU6CisgICAgICAgICAgICBjYXNlIENPTU1FTlRfTk9ERToKKyAgICAgICAgICAgIGNhc2UgVEVYVF9OT0RFOgorICAgICAgICAgICAgICAgICgoQ2hhcmFjdGVyRGF0YSkgdGhpcykuc2V0RGF0YShub2RlVmFsdWUpOworICAgICAgICAgICAgICAgIHJldHVybjsKKworICAgICAgICAgICAgY2FzZSBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU6CisgICAgICAgICAgICAgICAgKChQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24pIHRoaXMpLnNldERhdGEobm9kZVZhbHVlKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisKKyAgICAgICAgICAgIGNhc2UgQVRUUklCVVRFX05PREU6CisgICAgICAgICAgICAgICAgKChBdHRyKSB0aGlzKS5zZXRWYWx1ZShub2RlVmFsdWUpOworICAgICAgICAgICAgICAgIHJldHVybjsKKworICAgICAgICAgICAgY2FzZSBFTEVNRU5UX05PREU6CisgICAgICAgICAgICBjYXNlIEVOVElUWV9SRUZFUkVOQ0VfTk9ERToKKyAgICAgICAgICAgIGNhc2UgRU5USVRZX05PREU6CisgICAgICAgICAgICBjYXNlIERPQ1VNRU5UX05PREU6CisgICAgICAgICAgICBjYXNlIERPQ1VNRU5UX1RZUEVfTk9ERToKKyAgICAgICAgICAgIGNhc2UgRE9DVU1FTlRfRlJBR01FTlRfTk9ERToKKyAgICAgICAgICAgIGNhc2UgTk9UQVRJT05fTk9ERToKKyAgICAgICAgICAgICAgICByZXR1cm47IC8vIGRvIG5vdGhpbmchCisKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsCisgICAgICAgICAgICAgICAgICAgICAgICAiVW5zdXBwb3J0ZWQgbm9kZSB0eXBlICIgKyBnZXROb2RlVHlwZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFByZWZpeChTdHJpbmcgcHJlZml4KSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWYWxpZGF0ZXMgdGhlIGVsZW1lbnQgb3IgYXR0cmlidXRlIG5hbWVzcGFjZSBwcmVmaXggb24gdGhpcyBub2RlLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWVzcGFjZUF3YXJlIHdoZXRoZXIgdGhpcyBub2RlIGlzIG5hbWVzcGFjZSBhd2FyZQorICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgdGhpcyBub2RlJ3MgbmFtZXNwYWNlIFVSSQorICAgICAqLworICAgIHN0YXRpYyBTdHJpbmcgdmFsaWRhdGVQcmVmaXgoU3RyaW5nIHByZWZpeCwgYm9vbGVhbiBuYW1lc3BhY2VBd2FyZSwgU3RyaW5nIG5hbWVzcGFjZVVSSSkgeworICAgICAgICBpZiAoIW5hbWVzcGFjZUF3YXJlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSLCBwcmVmaXgpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHByZWZpeCAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAobmFtZXNwYWNlVVJJID09IG51bGwKKyAgICAgICAgICAgICAgICAgICAgfHwgIURvY3VtZW50SW1wbC5pc1hNTElkZW50aWZpZXIocHJlZml4KQorICAgICAgICAgICAgICAgICAgICB8fCAieG1sIi5lcXVhbHMocHJlZml4KSAmJiAhImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIuZXF1YWxzKG5hbWVzcGFjZVVSSSkKKyAgICAgICAgICAgICAgICAgICAgfHwgInhtbG5zIi5lcXVhbHMocHJlZml4KSAmJiAhImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIi5lcXVhbHMobmFtZXNwYWNlVVJJKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIsIHByZWZpeCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcHJlZml4OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMge0Bjb2RlIG5vZGV9IHRvIGJlIG5hbWVzcGFjZS1hd2FyZSBhbmQgYXNzaWducyBpdHMgbmFtZXNwYWNlIFVSSQorICAgICAqIGFuZCBxdWFsaWZpZWQgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBub2RlIGFuIGVsZW1lbnQgb3IgYXR0cmlidXRlIG5vZGUuCisgICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSB0aGlzIG5vZGUncyBuYW1lc3BhY2UgVVJJLiBNYXkgYmUgbnVsbC4KKyAgICAgKiBAcGFyYW0gcXVhbGlmaWVkTmFtZSBhIHBvc3NpYmx5LXByZWZpeGVkIG5hbWUgbGlrZSAiaW1nIiBvciAiaHRtbDppbWciLgorICAgICAqLworICAgIHN0YXRpYyB2b2lkIHNldE5hbWVOUyhOb2RlSW1wbCBub2RlLCBTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgcXVhbGlmaWVkTmFtZSkgeworICAgICAgICBpZiAocXVhbGlmaWVkTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBwcmVmaXggPSBudWxsOworICAgICAgICBpbnQgcCA9IHF1YWxpZmllZE5hbWUubGFzdEluZGV4T2YoIjoiKTsKKyAgICAgICAgaWYgKHAgIT0gLTEpIHsKKyAgICAgICAgICAgIHByZWZpeCA9IHZhbGlkYXRlUHJlZml4KHF1YWxpZmllZE5hbWUuc3Vic3RyaW5nKDAsIHApLCB0cnVlLCBuYW1lc3BhY2VVUkkpOworICAgICAgICAgICAgcXVhbGlmaWVkTmFtZSA9IHF1YWxpZmllZE5hbWUuc3Vic3RyaW5nKHAgKyAxKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghRG9jdW1lbnRJbXBsLmlzWE1MSWRlbnRpZmllcihxdWFsaWZpZWROYW1lKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIHN3aXRjaCAobm9kZS5nZXROb2RlVHlwZSgpKSB7CisgICAgICAgIGNhc2UgQVRUUklCVVRFX05PREU6CisgICAgICAgICAgICBpZiAoInhtbG5zIi5lcXVhbHMocXVhbGlmaWVkTmFtZSkKKyAgICAgICAgICAgICAgICAgICAgJiYgISJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIuZXF1YWxzKG5hbWVzcGFjZVVSSSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQXR0ckltcGwgYXR0ciA9IChBdHRySW1wbCkgbm9kZTsKKyAgICAgICAgICAgIGF0dHIubmFtZXNwYWNlQXdhcmUgPSB0cnVlOworICAgICAgICAgICAgYXR0ci5uYW1lc3BhY2VVUkkgPSBuYW1lc3BhY2VVUkk7CisgICAgICAgICAgICBhdHRyLnByZWZpeCA9IHByZWZpeDsKKyAgICAgICAgICAgIGF0dHIubG9jYWxOYW1lID0gcXVhbGlmaWVkTmFtZTsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgRUxFTUVOVF9OT0RFOgorICAgICAgICAgICAgRWxlbWVudEltcGwgZWxlbWVudCA9IChFbGVtZW50SW1wbCkgbm9kZTsKKyAgICAgICAgICAgIGVsZW1lbnQubmFtZXNwYWNlQXdhcmUgPSB0cnVlOworICAgICAgICAgICAgZWxlbWVudC5uYW1lc3BhY2VVUkkgPSBuYW1lc3BhY2VVUkk7CisgICAgICAgICAgICBlbGVtZW50LnByZWZpeCA9IHByZWZpeDsKKyAgICAgICAgICAgIGVsZW1lbnQubG9jYWxOYW1lID0gcXVhbGlmaWVkTmFtZTsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwKKyAgICAgICAgICAgICAgICAgICAgIkNhbm5vdCByZW5hbWUgbm9kZXMgb2YgdHlwZSAiICsgbm9kZS5nZXROb2RlVHlwZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMge0Bjb2RlIG5vZGV9IHRvIGJlIG5vdCBuYW1lc3BhY2UtYXdhcmUgYW5kIGFzc2lnbnMgaXRzIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbm9kZSBhbiBlbGVtZW50IG9yIGF0dHJpYnV0ZSBub2RlLgorICAgICAqLworICAgIHN0YXRpYyB2b2lkIHNldE5hbWUoTm9kZUltcGwgbm9kZSwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgaW50IHByZWZpeFNlcGFyYXRvciA9IG5hbWUubGFzdEluZGV4T2YoIjoiKTsKKyAgICAgICAgaWYgKHByZWZpeFNlcGFyYXRvciAhPSAtMSkgeworICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IG5hbWUuc3Vic3RyaW5nKDAsIHByZWZpeFNlcGFyYXRvcik7CisgICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gbmFtZS5zdWJzdHJpbmcocHJlZml4U2VwYXJhdG9yICsgMSk7CisgICAgICAgICAgICBpZiAoIURvY3VtZW50SW1wbC5pc1hNTElkZW50aWZpZXIocHJlZml4KSB8fCAhRG9jdW1lbnRJbXBsLmlzWE1MSWRlbnRpZmllcihsb2NhbE5hbWUpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSLCBuYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmICghRG9jdW1lbnRJbXBsLmlzWE1MSWRlbnRpZmllcihuYW1lKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSLCBuYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIHN3aXRjaCAobm9kZS5nZXROb2RlVHlwZSgpKSB7CisgICAgICAgIGNhc2UgQVRUUklCVVRFX05PREU6CisgICAgICAgICAgICBBdHRySW1wbCBhdHRyID0gKEF0dHJJbXBsKSBub2RlOworICAgICAgICAgICAgYXR0ci5uYW1lc3BhY2VBd2FyZSA9IGZhbHNlOworICAgICAgICAgICAgYXR0ci5sb2NhbE5hbWUgPSBuYW1lOworICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgY2FzZSBFTEVNRU5UX05PREU6CisgICAgICAgICAgICBFbGVtZW50SW1wbCBlbGVtZW50ID0gKEVsZW1lbnRJbXBsKSBub2RlOworICAgICAgICAgICAgZWxlbWVudC5uYW1lc3BhY2VBd2FyZSA9IGZhbHNlOworICAgICAgICAgICAgZWxlbWVudC5sb2NhbE5hbWUgPSBuYW1lOworICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLAorICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IHJlbmFtZSBub2RlcyBvZiB0eXBlICIgKyBub2RlLmdldE5vZGVUeXBlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRCYXNlVVJJKCkgeworICAgICAgICBzd2l0Y2ggKGdldE5vZGVUeXBlKCkpIHsKKyAgICAgICAgICAgIGNhc2UgRE9DVU1FTlRfTk9ERToKKyAgICAgICAgICAgICAgICByZXR1cm4gc2FuaXRpemVVcmkoKChEb2N1bWVudCkgdGhpcykuZ2V0RG9jdW1lbnRVUkkoKSk7CisKKyAgICAgICAgICAgIGNhc2UgRUxFTUVOVF9OT0RFOgorICAgICAgICAgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IChFbGVtZW50KSB0aGlzOworICAgICAgICAgICAgICAgIFN0cmluZyB1cmkgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5TKAorICAgICAgICAgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIsICJiYXNlIik7IC8vIG9yICJ4bWw6YmFzZSIKKworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoaXMgbm9kZSBoYXMgbm8gYmFzZSBVUkksIHJldHVybiB0aGUgcGFyZW50J3MuCisgICAgICAgICAgICAgICAgICAgIGlmICh1cmkgPT0gbnVsbCB8fCB1cmkuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0UGFyZW50QmFzZVVyaSgpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgLy8gaWYgdGhpcyBub2RlJ3MgVVJJIGlzIGFic29sdXRlLCByZXR1cm4gaXQKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5ldyBVUkkodXJpKS5pc0Fic29sdXRlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB1cmk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIG5vZGUgaGFzIGEgcmVsYXRpdmUgVVJJLiBUcnkgdG8gcmVzb2x2ZSBpdCBhZ2FpbnN0IHRoZQorICAgICAgICAgICAgICAgICAgICAvLyBwYXJlbnQsIGJ1dCBpZiB0aGF0IGRvZXNuJ3Qgd29yayBqdXN0IGdpdmUgdXAgYW5kIHJldHVybiBudWxsLgorICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcGFyZW50VXJpID0gZ2V0UGFyZW50QmFzZVVyaSgpOworICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50VXJpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVUkkocGFyZW50VXJpKS5yZXNvbHZlKHVyaSkudG9TdHJpbmcoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChVUklTeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNhc2UgUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFOgorICAgICAgICAgICAgICAgIHJldHVybiBnZXRQYXJlbnRCYXNlVXJpKCk7CisKKyAgICAgICAgICAgIGNhc2UgTk9UQVRJT05fTk9ERToKKyAgICAgICAgICAgIGNhc2UgRU5USVRZX05PREU6CisgICAgICAgICAgICAgICAgLy8gV2hlbiB3ZSBzdXBwb3J0IHRoZXNlIG5vZGUgdHlwZXMsIHRoZSBwYXJzZXIgc2hvdWxkCisgICAgICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZSBhIGJhc2UgVVJJIGZpZWxkIG9uIHRoZXNlIG5vZGVzLgorICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworCisgICAgICAgICAgICBjYXNlIEVOVElUWV9SRUZFUkVOQ0VfTk9ERToKKyAgICAgICAgICAgICAgICAvLyBUT0RPOiBnZXQgdGhpcyB2YWx1ZSBmcm9tIHRoZSBwYXJzZXIsIGZhbGxpbmcgYmFjayB0byB0aGUKKyAgICAgICAgICAgICAgICAvLyByZWZlcmVuY2VkIGVudGl0eSdzIGJhc2VVUkkgaWYgdGhhdCBkb2Vzbid0IGV4aXN0CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisKKyAgICAgICAgICAgIGNhc2UgRE9DVU1FTlRfVFlQRV9OT0RFOgorICAgICAgICAgICAgY2FzZSBET0NVTUVOVF9GUkFHTUVOVF9OT0RFOgorICAgICAgICAgICAgY2FzZSBBVFRSSUJVVEVfTk9ERToKKyAgICAgICAgICAgIGNhc2UgVEVYVF9OT0RFOgorICAgICAgICAgICAgY2FzZSBDREFUQV9TRUNUSU9OX05PREU6CisgICAgICAgICAgICBjYXNlIENPTU1FTlRfTk9ERToKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJVbnN1cHBvcnRlZCBub2RlIHR5cGUgIiArIGdldE5vZGVUeXBlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0UGFyZW50QmFzZVVyaSgpIHsKKyAgICAgICAgTm9kZSBwYXJlbnROb2RlID0gZ2V0UGFyZW50Tm9kZSgpOworICAgICAgICByZXR1cm4gcGFyZW50Tm9kZSAhPSBudWxsID8gcGFyZW50Tm9kZS5nZXRCYXNlVVJJKCkgOiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNhbml0aXplZCBpbnB1dCBpZiBpdCBpcyBhIFVSSSwgb3Ige0Bjb2RlIG51bGx9IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBzYW5pdGl6ZVVyaShTdHJpbmcgdXJpKSB7CisgICAgICAgIGlmICh1cmkgPT0gbnVsbCB8fCB1cmkubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVVJJKHVyaSkudG9TdHJpbmcoKTsKKyAgICAgICAgfSBjYXRjaCAoVVJJU3ludGF4RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHNob3J0IGNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKE5vZGUgb3RoZXIpCisgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7IC8vIFRPRE8KKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFRleHRDb250ZW50KCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXROb2RlVmFsdWUoKTsKKyAgICB9CisKKyAgICB2b2lkIGdldFRleHRDb250ZW50KFN0cmluZ0J1aWxkZXIgYnVmKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGNvbnRlbnQgPSBnZXROb2RlVmFsdWUoKTsKKyAgICAgICAgaWYgKGNvbnRlbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgYnVmLmFwcGVuZChjb250ZW50KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldFRleHRDb250ZW50KFN0cmluZyB0ZXh0Q29udGVudCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7CisgICAgICAgIHN3aXRjaCAoZ2V0Tm9kZVR5cGUoKSkgeworICAgICAgICAgICAgY2FzZSBET0NVTUVOVF9UWVBFX05PREU6CisgICAgICAgICAgICBjYXNlIERPQ1VNRU5UX05PREU6CisgICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBkbyBub3RoaW5nIQorCisgICAgICAgICAgICBjYXNlIEVMRU1FTlRfTk9ERToKKyAgICAgICAgICAgIGNhc2UgRU5USVRZX05PREU6CisgICAgICAgICAgICBjYXNlIEVOVElUWV9SRUZFUkVOQ0VfTk9ERToKKyAgICAgICAgICAgIGNhc2UgRE9DVU1FTlRfRlJBR01FTlRfTk9ERToKKyAgICAgICAgICAgICAgICAvLyByZW1vdmUgYWxsIGV4aXN0aW5nIGNoaWxkcmVuCisgICAgICAgICAgICAgICAgTm9kZSBjaGlsZDsKKyAgICAgICAgICAgICAgICB3aGlsZSAoKGNoaWxkID0gZ2V0Rmlyc3RDaGlsZCgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNoaWxkKGNoaWxkKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gY3JlYXRlIGEgdGV4dCBub2RlIHRvIGhvbGQgdGhlIGdpdmVuIGNvbnRlbnQKKyAgICAgICAgICAgICAgICBpZiAodGV4dENvbnRlbnQgIT0gbnVsbCAmJiB0ZXh0Q29udGVudC5sZW5ndGgoKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRleHRDb250ZW50KSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybjsKKworICAgICAgICAgICAgY2FzZSBBVFRSSUJVVEVfTk9ERToKKyAgICAgICAgICAgIGNhc2UgVEVYVF9OT0RFOgorICAgICAgICAgICAgY2FzZSBDREFUQV9TRUNUSU9OX05PREU6CisgICAgICAgICAgICBjYXNlIFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERToKKyAgICAgICAgICAgIGNhc2UgQ09NTUVOVF9OT0RFOgorICAgICAgICAgICAgY2FzZSBOT1RBVElPTl9OT0RFOgorICAgICAgICAgICAgICAgIHNldE5vZGVWYWx1ZSh0ZXh0Q29udGVudCk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworCisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLAorICAgICAgICAgICAgICAgICAgICAgICAgIlVuc3VwcG9ydGVkIG5vZGUgdHlwZSAiICsgZ2V0Tm9kZVR5cGUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NhbWVOb2RlKE5vZGUgb3RoZXIpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMgPT0gb3RoZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZWxlbWVudCB3aG9zZSBuYW1lc3BhY2UgZGVmaW5pdGlvbnMgYXBwbHkgdG8gdGhpcyBub2RlLiBVc2UKKyAgICAgKiB0aGlzIGVsZW1lbnQgd2hlbiBtYXBwaW5nIHByZWZpeGVzIHRvIFVSSXMgYW5kIHZpY2UgdmVyc2EuCisgICAgICovCisgICAgcHJpdmF0ZSBOb2RlSW1wbCBnZXROYW1lc3BhY2luZ0VsZW1lbnQoKSB7CisgICAgICAgIHN3aXRjaCAodGhpcy5nZXROb2RlVHlwZSgpKSB7CisgICAgICAgICAgICBjYXNlIEVMRU1FTlRfTk9ERToKKyAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKKworICAgICAgICAgICAgY2FzZSBET0NVTUVOVF9OT0RFOgorICAgICAgICAgICAgICAgIHJldHVybiAoTm9kZUltcGwpICgoRG9jdW1lbnQpIHRoaXMpLmdldERvY3VtZW50RWxlbWVudCgpOworCisgICAgICAgICAgICBjYXNlIEVOVElUWV9OT0RFOgorICAgICAgICAgICAgY2FzZSBOT1RBVElPTl9OT0RFOgorICAgICAgICAgICAgY2FzZSBET0NVTUVOVF9GUkFHTUVOVF9OT0RFOgorICAgICAgICAgICAgY2FzZSBET0NVTUVOVF9UWVBFX05PREU6CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisKKyAgICAgICAgICAgIGNhc2UgQVRUUklCVVRFX05PREU6CisgICAgICAgICAgICAgICAgcmV0dXJuIChOb2RlSW1wbCkgKChBdHRyKSB0aGlzKS5nZXRPd25lckVsZW1lbnQoKTsKKworICAgICAgICAgICAgY2FzZSBURVhUX05PREU6CisgICAgICAgICAgICBjYXNlIENEQVRBX1NFQ1RJT05fTk9ERToKKyAgICAgICAgICAgIGNhc2UgRU5USVRZX1JFRkVSRU5DRV9OT0RFOgorICAgICAgICAgICAgY2FzZSBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU6CisgICAgICAgICAgICBjYXNlIENPTU1FTlRfTk9ERToKKyAgICAgICAgICAgICAgICByZXR1cm4gZ2V0Q29udGFpbmluZ0VsZW1lbnQoKTsKKworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJVbnN1cHBvcnRlZCBub2RlIHR5cGUgIiArIGdldE5vZGVUeXBlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmVhcmVzdCBhbmNlc3RvciBlbGVtZW50IHRoYXQgY29udGFpbnMgdGhpcyBub2RlLgorICAgICAqLworICAgIHByaXZhdGUgTm9kZUltcGwgZ2V0Q29udGFpbmluZ0VsZW1lbnQoKSB7CisgICAgICAgIGZvciAoTm9kZSBwID0gZ2V0UGFyZW50Tm9kZSgpOyBwICE9IG51bGw7IHAgPSBwLmdldFBhcmVudE5vZGUoKSkgeworICAgICAgICAgICAgaWYgKHAuZ2V0Tm9kZVR5cGUoKSA9PSBFTEVNRU5UX05PREUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gKE5vZGVJbXBsKSBwOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgbG9va3VwUHJlZml4KFN0cmluZyBuYW1lc3BhY2VVUkkpIHsKKyAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRoZSBYTUwgc3BlY3MgZGVmaW5lIHNvbWUgcHJlZml4ZXMgKGxpa2UgInhtbCIgYW5kICJ4bWxucyIpIGJ1dCB0aGlzCisgICAgICAgIC8vIEFQSSBpcyBleHBsaWNpdGx5IGRlZmluZWQgdG8gaWdub3JlIHRob3NlLgorCisgICAgICAgIE5vZGVJbXBsIHRhcmdldCA9IGdldE5hbWVzcGFjaW5nRWxlbWVudCgpOworICAgICAgICBmb3IgKE5vZGVJbXBsIG5vZGUgPSB0YXJnZXQ7IG5vZGUgIT0gbnVsbDsgbm9kZSA9IG5vZGUuZ2V0Q29udGFpbmluZ0VsZW1lbnQoKSkgeworICAgICAgICAgICAgLy8gY2hlY2sgdGhpcyBlbGVtZW50J3MgbmFtZXNwYWNlIGZpcnN0CisgICAgICAgICAgICBpZiAobmFtZXNwYWNlVVJJLmVxdWFscyhub2RlLmdldE5hbWVzcGFjZVVSSSgpKQorICAgICAgICAgICAgICAgICAgICAmJiB0YXJnZXQuaXNQcmVmaXhNYXBwZWRUb1VyaShub2RlLmdldFByZWZpeCgpLCBuYW1lc3BhY2VVUkkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGUuZ2V0UHJlZml4KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIHNlYXJjaCB0aGlzIGVsZW1lbnQgZm9yIGFuIGF0dHJpYnV0ZSBvZiB0aGlzIGZvcm06CisgICAgICAgICAgICAvLyAgIHhtbG5zOmZvbz0iaHR0cDovL25hbWVzcGFjZVVSSSIKKyAgICAgICAgICAgIGlmICghbm9kZS5oYXNBdHRyaWJ1dGVzKCkpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzID0gbm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMCwgbGVuZ3RoID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgTm9kZSBhdHRyID0gYXR0cmlidXRlcy5pdGVtKGkpOworICAgICAgICAgICAgICAgIGlmICghImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIi5lcXVhbHMoYXR0ci5nZXROYW1lc3BhY2VVUkkoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgIHx8ICEieG1sbnMiLmVxdWFscyhhdHRyLmdldFByZWZpeCgpKQorICAgICAgICAgICAgICAgICAgICAgICAgfHwgIW5hbWVzcGFjZVVSSS5lcXVhbHMoYXR0ci5nZXROb2RlVmFsdWUoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICh0YXJnZXQuaXNQcmVmaXhNYXBwZWRUb1VyaShhdHRyLmdldExvY2FsTmFtZSgpLCBuYW1lc3BhY2VVUkkpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBhdHRyLmdldExvY2FsTmFtZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gcHJlZml4IGlzIG1hcHBlZCB0byB0aGUgZ2l2ZW4gVVJJIG9uIHRoaXMKKyAgICAgKiBlbGVtZW50LiBTaW5jZSBjaGlsZCBlbGVtZW50cyBjYW4gcmVkZWZpbmUgcHJlZml4ZXMsIHRoaXMgY2hlY2sgaXMKKyAgICAgKiBuZWNlc3Nhcnk6IHtAY29kZQorICAgICAqIDxmb28geG1sbnM6YT0iaHR0cDovL2dvb2QiPgorICAgICAqICAgPGJhciB4bWxuczphPSJodHRwOi8vZXZpbCI+CisgICAgICogICAgIDxhOmJheiAvPgorICAgICAqICAgPC9iYXI+CisgICAgICogPC9mb28+fQorICAgICAqCisgICAgICogQHBhcmFtIHByZWZpeCB0aGUgcHJlZml4IHRvIGZpbmQuIE51bGxhYmxlLgorICAgICAqIEBwYXJhbSB1cmkgdGhlIFVSSSB0byBtYXRjaC4gTm9uLW51bGwuCisgICAgICovCisgICAgYm9vbGVhbiBpc1ByZWZpeE1hcHBlZFRvVXJpKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpIHsKKyAgICAgICAgaWYgKHByZWZpeCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgYWN0dWFsID0gbG9va3VwTmFtZXNwYWNlVVJJKHByZWZpeCk7CisgICAgICAgIHJldHVybiB1cmkuZXF1YWxzKGFjdHVhbCk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNEZWZhdWx0TmFtZXNwYWNlKFN0cmluZyBuYW1lc3BhY2VVUkkpIHsKKyAgICAgICAgU3RyaW5nIGFjdHVhbCA9IGxvb2t1cE5hbWVzcGFjZVVSSShudWxsKTsgLy8gbnVsbCB5aWVsZHMgdGhlIGRlZmF1bHQgbmFtZXNwYWNlCisgICAgICAgIHJldHVybiBuYW1lc3BhY2VVUkkgPT0gbnVsbAorICAgICAgICAgICAgICAgID8gYWN0dWFsID09IG51bGwKKyAgICAgICAgICAgICAgICA6IG5hbWVzcGFjZVVSSS5lcXVhbHMoYWN0dWFsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGxvb2t1cE5hbWVzcGFjZVVSSShTdHJpbmcgcHJlZml4KSB7CisgICAgICAgIE5vZGVJbXBsIHRhcmdldCA9IGdldE5hbWVzcGFjaW5nRWxlbWVudCgpOworICAgICAgICBmb3IgKE5vZGVJbXBsIG5vZGUgPSB0YXJnZXQ7IG5vZGUgIT0gbnVsbDsgbm9kZSA9IG5vZGUuZ2V0Q29udGFpbmluZ0VsZW1lbnQoKSkgeworICAgICAgICAgICAgLy8gY2hlY2sgdGhpcyBlbGVtZW50J3MgbmFtZXNwYWNlIGZpcnN0CisgICAgICAgICAgICBTdHJpbmcgbm9kZVByZWZpeCA9IG5vZGUuZ2V0UHJlZml4KCk7CisgICAgICAgICAgICBpZiAobm9kZS5nZXROYW1lc3BhY2VVUkkoKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaWYgKHByZWZpeCA9PSBudWxsIC8vIG51bGwgPT4gZGVmYXVsdCBwcmVmaXgKKyAgICAgICAgICAgICAgICAgICAgICAgID8gbm9kZVByZWZpeCA9PSBudWxsCisgICAgICAgICAgICAgICAgICAgICAgICA6IHByZWZpeC5lcXVhbHMobm9kZVByZWZpeCkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGUuZ2V0TmFtZXNwYWNlVVJJKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBzZWFyY2ggdGhpcyBlbGVtZW50IGZvciBhbiBhdHRyaWJ1dGUgb2YgdGhlIGFwcHJvcHJpYXRlIGZvcm0uCisgICAgICAgICAgICAvLyAgICBkZWZhdWx0IG5hbWVzcGFjZTogeG1sbnM9Imh0dHA6Ly9yZXN1bHRVcmkiCisgICAgICAgICAgICAvLyAgICAgICAgICBub24gZGVmYXVsdDogeG1sbnM6c3BlY2lmaWVkUHJlZml4PSJodHRwOi8vcmVzdWx0VXJpIgorICAgICAgICAgICAgaWYgKCFub2RlLmhhc0F0dHJpYnV0ZXMoKSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXMgPSBub2RlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwLCBsZW5ndGggPSBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBOb2RlIGF0dHIgPSBhdHRyaWJ1dGVzLml0ZW0oaSk7CisgICAgICAgICAgICAgICAgaWYgKCEiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iLmVxdWFscyhhdHRyLmdldE5hbWVzcGFjZVVSSSgpKSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHByZWZpeCA9PSBudWxsIC8vIG51bGwgPT4gZGVmYXVsdCBwcmVmaXgKKyAgICAgICAgICAgICAgICAgICAgICAgID8gInhtbG5zIi5lcXVhbHMoYXR0ci5nZXROb2RlTmFtZSgpKQorICAgICAgICAgICAgICAgICAgICAgICAgOiAieG1sbnMiLmVxdWFscyhhdHRyLmdldFByZWZpeCgpKSAmJiBwcmVmaXguZXF1YWxzKGF0dHIuZ2V0TG9jYWxOYW1lKCkpKSB7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IGF0dHIuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5sZW5ndGgoKSA+IDAgPyB2YWx1ZSA6IG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGxpc3Qgb2Ygb2JqZWN0cyBzdWNoIHRoYXQgdHdvIG5vZGVzIGFyZSBlcXVhbCBpZiB0aGVpciBsaXN0cworICAgICAqIGFyZSBlcXVhbC4gQmUgY2FyZWZ1bDogdGhlIGxpc3RzIG1heSBjb250YWluIE5hbWVkTm9kZU1hcHMgYW5kIE5vZGVzLAorICAgICAqIG5laXRoZXIgb2Ygd2hpY2ggb3ZlcnJpZGUgT2JqZWN0LmVxdWFscygpLiBTdWNoIHZhbHVlcyBtdXN0IGJlIGNvbXBhcmVkCisgICAgICogbWFudWFsbHkuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgTGlzdDxPYmplY3Q+IGNyZWF0ZUVxdWFsaXR5S2V5KE5vZGUgbm9kZSkgeworICAgICAgICBMaXN0PE9iamVjdD4gdmFsdWVzID0gbmV3IEFycmF5TGlzdDxPYmplY3Q+KCk7CisgICAgICAgIHZhbHVlcy5hZGQobm9kZS5nZXROb2RlVHlwZSgpKTsKKyAgICAgICAgdmFsdWVzLmFkZChub2RlLmdldE5vZGVOYW1lKCkpOworICAgICAgICB2YWx1ZXMuYWRkKG5vZGUuZ2V0TG9jYWxOYW1lKCkpOworICAgICAgICB2YWx1ZXMuYWRkKG5vZGUuZ2V0TmFtZXNwYWNlVVJJKCkpOworICAgICAgICB2YWx1ZXMuYWRkKG5vZGUuZ2V0UHJlZml4KCkpOworICAgICAgICB2YWx1ZXMuYWRkKG5vZGUuZ2V0Tm9kZVZhbHVlKCkpOworICAgICAgICBmb3IgKE5vZGUgY2hpbGQgPSBub2RlLmdldEZpcnN0Q2hpbGQoKTsgY2hpbGQgIT0gbnVsbDsgY2hpbGQgPSBjaGlsZC5nZXROZXh0U2libGluZygpKSB7CisgICAgICAgICAgICB2YWx1ZXMuYWRkKGNoaWxkKTsKKyAgICAgICAgfQorCisgICAgICAgIHN3aXRjaCAobm9kZS5nZXROb2RlVHlwZSgpKSB7CisgICAgICAgICAgICBjYXNlIERPQ1VNRU5UX1RZUEVfTk9ERToKKyAgICAgICAgICAgICAgICBEb2N1bWVudFR5cGVJbXBsIGRvY3R5cGUgPSAoRG9jdW1lbnRUeXBlSW1wbCkgbm9kZTsKKyAgICAgICAgICAgICAgICB2YWx1ZXMuYWRkKGRvY3R5cGUuZ2V0UHVibGljSWQoKSk7CisgICAgICAgICAgICAgICAgdmFsdWVzLmFkZChkb2N0eXBlLmdldFN5c3RlbUlkKCkpOworICAgICAgICAgICAgICAgIHZhbHVlcy5hZGQoZG9jdHlwZS5nZXRJbnRlcm5hbFN1YnNldCgpKTsKKyAgICAgICAgICAgICAgICB2YWx1ZXMuYWRkKGRvY3R5cGUuZ2V0RW50aXRpZXMoKSk7CisgICAgICAgICAgICAgICAgdmFsdWVzLmFkZChkb2N0eXBlLmdldE5vdGF0aW9ucygpKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBFTEVNRU5UX05PREU6CisgICAgICAgICAgICAgICAgRWxlbWVudCBlbGVtZW50ID0gKEVsZW1lbnQpIG5vZGU7CisgICAgICAgICAgICAgICAgdmFsdWVzLmFkZChlbGVtZW50LmdldEF0dHJpYnV0ZXMoKSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gdmFsdWVzOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzRXF1YWxOb2RlKE5vZGUgYXJnKSB7CisgICAgICAgIGlmIChhcmcgPT0gdGhpcykgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBMaXN0PE9iamVjdD4gbGlzdEEgPSBjcmVhdGVFcXVhbGl0eUtleSh0aGlzKTsKKyAgICAgICAgTGlzdDxPYmplY3Q+IGxpc3RCID0gY3JlYXRlRXF1YWxpdHlLZXkoYXJnKTsKKworICAgICAgICBpZiAobGlzdEEuc2l6ZSgpICE9IGxpc3RCLnNpemUoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsaXN0QS5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgT2JqZWN0IGEgPSBsaXN0QS5nZXQoaSk7CisgICAgICAgICAgICBPYmplY3QgYiA9IGxpc3RCLmdldChpKTsKKworICAgICAgICAgICAgaWYgKGEgPT0gYikgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworCisgICAgICAgICAgICB9IGVsc2UgaWYgKGEgPT0gbnVsbCB8fCBiID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoYSBpbnN0YW5jZW9mIFN0cmluZyB8fCBhIGluc3RhbmNlb2YgU2hvcnQpIHsKKyAgICAgICAgICAgICAgICBpZiAoIWEuZXF1YWxzKGIpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoYSBpbnN0YW5jZW9mIE5hbWVkTm9kZU1hcCkgeworICAgICAgICAgICAgICAgIGlmICghKGIgaW5zdGFuY2VvZiBOYW1lZE5vZGVNYXApCisgICAgICAgICAgICAgICAgICAgICAgICB8fCAhbmFtZWROb2RlTWFwc0VxdWFsKChOYW1lZE5vZGVNYXApIGEsIChOYW1lZE5vZGVNYXApIGIpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoYSBpbnN0YW5jZW9mIE5vZGUpIHsKKyAgICAgICAgICAgICAgICBpZiAoIShiIGluc3RhbmNlb2YgTm9kZSkKKyAgICAgICAgICAgICAgICAgICAgICAgIHx8ICEoKE5vZGUpIGEpLmlzRXF1YWxOb2RlKChOb2RlKSBiKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOyAvLyB1bmV4cGVjdGVkIHR5cGUKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBuYW1lZE5vZGVNYXBzRXF1YWwoTmFtZWROb2RlTWFwIGEsIE5hbWVkTm9kZU1hcCBiKSB7CisgICAgICAgIGlmIChhLmdldExlbmd0aCgpICE9IGIuZ2V0TGVuZ3RoKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGEuZ2V0TGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgTm9kZSBhTm9kZSA9IGEuaXRlbShpKTsKKyAgICAgICAgICAgIE5vZGUgYk5vZGUgPSBhTm9kZS5nZXRMb2NhbE5hbWUoKSA9PSBudWxsCisgICAgICAgICAgICAgICAgICAgID8gYi5nZXROYW1lZEl0ZW0oYU5vZGUuZ2V0Tm9kZU5hbWUoKSkKKyAgICAgICAgICAgICAgICAgICAgOiBiLmdldE5hbWVkSXRlbU5TKGFOb2RlLmdldE5hbWVzcGFjZVVSSSgpLCBhTm9kZS5nZXRMb2NhbE5hbWUoKSk7CisgICAgICAgICAgICBpZiAoYk5vZGUgPT0gbnVsbCB8fCAhYU5vZGUuaXNFcXVhbE5vZGUoYk5vZGUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBPYmplY3QgZ2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pIHsKKyAgICAgICAgcmV0dXJuIGlzU3VwcG9ydGVkKGZlYXR1cmUsIHZlcnNpb24pID8gdGhpcyA6IG51bGw7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIE9iamVjdCBzZXRVc2VyRGF0YShTdHJpbmcga2V5LCBPYmplY3QgZGF0YSwgVXNlckRhdGFIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBNYXA8U3RyaW5nLCBVc2VyRGF0YT4gbWFwID0gZG9jdW1lbnQuZ2V0VXNlckRhdGFNYXAodGhpcyk7CisgICAgICAgIFVzZXJEYXRhIHByZXZpb3VzID0gZGF0YSA9PSBudWxsCisgICAgICAgICAgICAgICAgPyBtYXAucmVtb3ZlKGtleSkKKyAgICAgICAgICAgICAgICA6IG1hcC5wdXQoa2V5LCBuZXcgVXNlckRhdGEoZGF0YSwgaGFuZGxlcikpOworICAgICAgICByZXR1cm4gcHJldmlvdXMgIT0gbnVsbCA/IHByZXZpb3VzLnZhbHVlIDogbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgT2JqZWN0IGdldFVzZXJEYXRhKFN0cmluZyBrZXkpIHsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBNYXA8U3RyaW5nLCBVc2VyRGF0YT4gbWFwID0gZG9jdW1lbnQuZ2V0VXNlckRhdGFNYXBGb3JSZWFkKHRoaXMpOworICAgICAgICBVc2VyRGF0YSB1c2VyRGF0YSA9IG1hcC5nZXQoa2V5KTsKKyAgICAgICAgcmV0dXJuIHVzZXJEYXRhICE9IG51bGwgPyB1c2VyRGF0YS52YWx1ZSA6IG51bGw7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFVzZXJEYXRhIHsKKyAgICAgICAgZmluYWwgT2JqZWN0IHZhbHVlOworICAgICAgICBmaW5hbCBVc2VyRGF0YUhhbmRsZXIgaGFuZGxlcjsKKyAgICAgICAgVXNlckRhdGEoT2JqZWN0IHZhbHVlLCBVc2VyRGF0YUhhbmRsZXIgaGFuZGxlcikgeworICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgICAgICAgICAgdGhpcy5oYW5kbGVyID0gaGFuZGxlcjsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9Ob2RlTGlzdEltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9Ob2RlTGlzdEltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMjgxYzgxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL05vZGVMaXN0SW1wbC5qYXZhCkBAIC0wLDAgKzEsNjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bWwuZG9tOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworCisvKioKKyAqIFByb3ZpZGVzIGEgc3RyYWlnaHRmb3J3YXJkIGltcGxlbWVudGF0aW9uIG9mIHRoZSBjb3JyZXNwb25kaW5nIFczQyBET00KKyAqIGludGVyZmFjZS4gVGhlIGNsYXNzIGlzIHVzZWQgaW50ZXJuYWxseSBvbmx5LCB0aHVzIG9ubHkgbm90YWJsZSBtZW1iZXJzIHRoYXQKKyAqIGFyZSBub3QgaW4gdGhlIG9yaWdpbmFsIGludGVyZmFjZSBhcmUgZG9jdW1lbnRlZCAodGhlIFczQyBkb2NzIGFyZSBxdWl0ZQorICogZXh0ZW5zaXZlKS4gSG9wZSB0aGF0J3Mgb2suCisgKiA8cD4KKyAqIFNvbWUgb2YgdGhlIGZpZWxkcyBtYXkgaGF2ZSBwYWNrYWdlIHZpc2liaWxpdHksIHNvIG90aGVyIGNsYXNzZXMgYmVsb25naW5nIHRvCisgKiB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGNhbiBlYXNpbHkgYWNjZXNzIHRoZW0gd2hpbGUgbWFpbnRhaW5pbmcgdGhlIERPTSB0cmVlCisgKiBzdHJ1Y3R1cmUuCisgKi8KK3B1YmxpYyBjbGFzcyBOb2RlTGlzdEltcGwgaW1wbGVtZW50cyBOb2RlTGlzdCB7CisKKyAgICBwcml2YXRlIExpc3Q8Tm9kZUltcGw+IGNoaWxkcmVuOworCisgICAgTm9kZUxpc3RJbXBsKCkgeworICAgICAgICBjaGlsZHJlbiA9IG5ldyBBcnJheUxpc3Q8Tm9kZUltcGw+KCk7CisgICAgfQorCisgICAgTm9kZUxpc3RJbXBsKExpc3Q8Tm9kZUltcGw+IGxpc3QpIHsKKyAgICAgICAgY2hpbGRyZW4gPSBsaXN0OworICAgIH0KKworICAgIHZvaWQgYWRkKE5vZGVJbXBsIG5vZGUpIHsKKyAgICAgICAgY2hpbGRyZW4uYWRkKG5vZGUpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gY2hpbGRyZW4uc2l6ZSgpOworICAgIH0KKworICAgIHB1YmxpYyBOb2RlIGl0ZW0oaW50IGluZGV4KSB7CisgICAgICAgIGlmIChpbmRleCA+PSBjaGlsZHJlbi5zaXplKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIGNoaWxkcmVuLmdldChpbmRleCk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9Ob3RhdGlvbkltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9Ob3RhdGlvbkltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YmM2Nzg5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL05vdGF0aW9uSW1wbC5qYXZhCkBAIC0wLDAgKzEsNjMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bWwuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob3RhdGlvbjsKKworLyoqCisgKiBQcm92aWRlcyBhIHN0cmFpZ2h0Zm9yd2FyZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgY29ycmVzcG9uZGluZyBXM0MgRE9NCisgKiBpbnRlcmZhY2UuIFRoZSBjbGFzcyBpcyB1c2VkIGludGVybmFsbHkgb25seSwgdGh1cyBvbmx5IG5vdGFibGUgbWVtYmVycyB0aGF0CisgKiBhcmUgbm90IGluIHRoZSBvcmlnaW5hbCBpbnRlcmZhY2UgYXJlIGRvY3VtZW50ZWQgKHRoZSBXM0MgZG9jcyBhcmUgcXVpdGUKKyAqIGV4dGVuc2l2ZSkuIEhvcGUgdGhhdCdzIG9rLgorICogPHA+CisgKiBTb21lIG9mIHRoZSBmaWVsZHMgbWF5IGhhdmUgcGFja2FnZSB2aXNpYmlsaXR5LCBzbyBvdGhlciBjbGFzc2VzIGJlbG9uZ2luZyB0bworICogdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBjYW4gZWFzaWx5IGFjY2VzcyB0aGVtIHdoaWxlIG1haW50YWluaW5nIHRoZSBET00gdHJlZQorICogc3RydWN0dXJlLgorICovCitwdWJsaWMgY2xhc3MgTm90YXRpb25JbXBsIGV4dGVuZHMgTGVhZk5vZGVJbXBsIGltcGxlbWVudHMgTm90YXRpb24geworCisgICAgcHJpdmF0ZSBTdHJpbmcgbm90YXRpb25OYW1lOworCisgICAgcHJpdmF0ZSBTdHJpbmcgcHVibGljSUQ7CisKKyAgICBwcml2YXRlIFN0cmluZyBzeXN0ZW1JRDsKKworICAgIE5vdGF0aW9uSW1wbChEb2N1bWVudEltcGwgZG9jdW1lbnQsIFN0cmluZyBub3RhdGlvbk5hbWUsIFN0cmluZyBwdWJsaWNJRCwKKyAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JRCkgeworICAgICAgICBzdXBlcihkb2N1bWVudCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG5vdGF0aW9uTmFtZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc2hvcnQgZ2V0Tm9kZVR5cGUoKSB7CisgICAgICAgIHJldHVybiBOb2RlLk5PVEFUSU9OX05PREU7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpIHsKKyAgICAgICAgcmV0dXJuIHB1YmxpY0lEOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7CisgICAgICAgIHJldHVybiBzeXN0ZW1JRDsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL2RvbS9Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb25JbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vUHJvY2Vzc2luZ0luc3RydWN0aW9uSW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExNTI0NWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vUHJvY2Vzc2luZ0luc3RydWN0aW9uSW1wbC5qYXZhCkBAIC0wLDAgKzEsNzMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bWwuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uUHJvY2Vzc2luZ0luc3RydWN0aW9uOworCisvKioKKyAqIFByb3ZpZGVzIGEgc3RyYWlnaHRmb3J3YXJkIGltcGxlbWVudGF0aW9uIG9mIHRoZSBjb3JyZXNwb25kaW5nIFczQyBET00KKyAqIGludGVyZmFjZS4gVGhlIGNsYXNzIGlzIHVzZWQgaW50ZXJuYWxseSBvbmx5LCB0aHVzIG9ubHkgbm90YWJsZSBtZW1iZXJzIHRoYXQKKyAqIGFyZSBub3QgaW4gdGhlIG9yaWdpbmFsIGludGVyZmFjZSBhcmUgZG9jdW1lbnRlZCAodGhlIFczQyBkb2NzIGFyZSBxdWl0ZQorICogZXh0ZW5zaXZlKS4gSG9wZSB0aGF0J3Mgb2suCisgKiA8cD4KKyAqIFNvbWUgb2YgdGhlIGZpZWxkcyBtYXkgaGF2ZSBwYWNrYWdlIHZpc2liaWxpdHksIHNvIG90aGVyIGNsYXNzZXMgYmVsb25naW5nIHRvCisgKiB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGNhbiBlYXNpbHkgYWNjZXNzIHRoZW0gd2hpbGUgbWFpbnRhaW5pbmcgdGhlIERPTSB0cmVlCisgKiBzdHJ1Y3R1cmUuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25JbXBsIGV4dGVuZHMgTGVhZk5vZGVJbXBsIGltcGxlbWVudHMKKyAgICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uIHsKKworICAgIHByaXZhdGUgU3RyaW5nIHRhcmdldDsKKworICAgIHByaXZhdGUgU3RyaW5nIGRhdGE7CisKKyAgICBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25JbXBsKERvY3VtZW50SW1wbCBkb2N1bWVudCwgU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpIHsKKyAgICAgICAgc3VwZXIoZG9jdW1lbnQpOworICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDsgLy8gVE9ETzogdmFsaWRhdGUgdGhhdCB0YXJnZXQgaXMgd2VsbC1mb3JtZWQKKyAgICAgICAgdGhpcy5kYXRhID0gZGF0YTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldERhdGEoKSB7CisgICAgICAgIHJldHVybiBkYXRhOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKSB7CisgICAgICAgIHJldHVybiB0YXJnZXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKCkgeworICAgICAgICByZXR1cm4gTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXROb2RlVmFsdWUoKSB7CisgICAgICAgIHJldHVybiBkYXRhOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0KCkgeworICAgICAgICByZXR1cm4gdGFyZ2V0OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldERhdGEoU3RyaW5nIGRhdGEpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICB0aGlzLmRhdGEgPSBkYXRhOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL1RleHRJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9kb20vVGV4dEltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YjYxYjAyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvZG9tL1RleHRJbXBsLmphdmEKQEAgLTAsMCArMSwxNzIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bWwuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uVGV4dDsKKworLyoqCisgKiBQcm92aWRlcyBhIHN0cmFpZ2h0Zm9yd2FyZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgY29ycmVzcG9uZGluZyBXM0MgRE9NCisgKiBpbnRlcmZhY2UuIFRoZSBjbGFzcyBpcyB1c2VkIGludGVybmFsbHkgb25seSwgdGh1cyBvbmx5IG5vdGFibGUgbWVtYmVycyB0aGF0CisgKiBhcmUgbm90IGluIHRoZSBvcmlnaW5hbCBpbnRlcmZhY2UgYXJlIGRvY3VtZW50ZWQgKHRoZSBXM0MgZG9jcyBhcmUgcXVpdGUKKyAqIGV4dGVuc2l2ZSkuIEhvcGUgdGhhdCdzIG9rLgorICogPHA+CisgKiBTb21lIG9mIHRoZSBmaWVsZHMgbWF5IGhhdmUgcGFja2FnZSB2aXNpYmlsaXR5LCBzbyBvdGhlciBjbGFzc2VzIGJlbG9uZ2luZyB0bworICogdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBjYW4gZWFzaWx5IGFjY2VzcyB0aGVtIHdoaWxlIG1haW50YWluaW5nIHRoZSBET00gdHJlZQorICogc3RydWN0dXJlLgorICovCitwdWJsaWMgY2xhc3MgVGV4dEltcGwgZXh0ZW5kcyBDaGFyYWN0ZXJEYXRhSW1wbCBpbXBsZW1lbnRzIFRleHQgeworCisgICAgcHVibGljIFRleHRJbXBsKERvY3VtZW50SW1wbCBkb2N1bWVudCwgU3RyaW5nIGRhdGEpIHsKKyAgICAgICAgc3VwZXIoZG9jdW1lbnQsIGRhdGEpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKSB7CisgICAgICAgIHJldHVybiAiI3RleHQiOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzaG9ydCBnZXROb2RlVHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIE5vZGUuVEVYVF9OT0RFOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBUZXh0IHNwbGl0VGV4dChpbnQgb2Zmc2V0KSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKKyAgICAgICAgVGV4dCBuZXdUZXh0ID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoCisgICAgICAgICAgICAgICAgc3Vic3RyaW5nRGF0YShvZmZzZXQsIGdldExlbmd0aCgpIC0gb2Zmc2V0KSk7CisgICAgICAgIGRlbGV0ZURhdGEoMCwgb2Zmc2V0KTsKKworICAgICAgICBOb2RlIHJlZk5vZGUgPSBnZXROZXh0U2libGluZygpOworICAgICAgICBpZiAocmVmTm9kZSA9PSBudWxsKSB7CisgICAgICAgICAgICBnZXRQYXJlbnROb2RlKCkuYXBwZW5kQ2hpbGQobmV3VGV4dCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBnZXRQYXJlbnROb2RlKCkuaW5zZXJ0QmVmb3JlKG5ld1RleHQsIHJlZk5vZGUpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoKSB7CisgICAgICAgIC8vIFVuZGVmaW5lZCBiZWNhdXNlIHdlIGRvbid0IHZhbGlkYXRlLiBXaGV0aGVyIHdoaXRlc3BhY2UgY2hhcmFjdGVycworICAgICAgICAvLyBjb25zdGl0dXRlICJlbGVtZW50IGNvbnRlbnQgd2hpdGVzcGFjZSIgaXMgZGVmaW5lZCBieSB0aGUgY29udGFpbmluZworICAgICAgICAvLyBlbGVtZW50J3MgZGVjbGFyYXRpb24gKERURCkgYW5kIHdlIGRvbid0IHBhcnNlIHRoYXQuCisgICAgICAgIC8vIFRPRE86IHdpcmUgdGhpcyB1cCB3aGVuIHdlIHN1cHBvcnQgZG9jdW1lbnQgdmFsaWRhdGlvbgorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRXaG9sZVRleHQoKSB7CisgICAgICAgIC8vIFRPRE86IHN1cHBvcnQgZW50aXR5IHJlZmVyZW5jZXMuIFRoaXMgY29kZSBzaG91bGQgZXhwYW5kIHRocm91Z2gKKyAgICAgICAgLy8gdGhlIGNoaWxkIGVsZW1lbnRzIG9mIGVudGl0eSByZWZlcmVuY2VzLgorICAgICAgICAvLyAgICAgaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD02ODA3CisKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBmb3IgKFRleHRJbXBsIG4gPSBmaXJzdFRleHROb2RlSW5DdXJyZW50UnVuKCk7IG4gIT0gbnVsbDsgbiA9IG4ubmV4dFRleHROb2RlKCkpIHsKKyAgICAgICAgICAgIG4uYXBwZW5kRGF0YVRvKHJlc3VsdCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBUZXh0IHJlcGxhY2VXaG9sZVRleHQoU3RyaW5nIGNvbnRlbnQpIHRocm93cyBET01FeGNlcHRpb24geworICAgICAgICAvLyBUT0RPOiBzdXBwb3J0IGVudGl0eSByZWZlcmVuY2VzLiBUaGlzIGNvZGUgc2hvdWxkIGV4cGFuZCBhbmQgcmVwbGFjZQorICAgICAgICAvLyB0aGUgY2hpbGQgZWxlbWVudHMgb2YgZW50aXR5IHJlZmVyZW5jZXMuCisgICAgICAgIC8vICAgICBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTY4MDcKKworICAgICAgICBOb2RlIHBhcmVudCA9IGdldFBhcmVudE5vZGUoKTsKKyAgICAgICAgVGV4dCByZXN1bHQgPSBudWxsOworCisgICAgICAgIC8vIGRlbGV0ZSBhbGwgbm9kZXMgaW4gdGhlIGN1cnJlbnQgcnVuIG9mIHRleHQuLi4KKyAgICAgICAgZm9yIChUZXh0SW1wbCBuID0gZmlyc3RUZXh0Tm9kZUluQ3VycmVudFJ1bigpOyBuICE9IG51bGw7ICkgeworCisgICAgICAgICAgICAvLyAuLi5leGNlcHQgdGhlIGN1cnJlbnQgbm9kZSBpZiB3ZSBoYXZlIGNvbnRlbnQgZm9yIGl0CisgICAgICAgICAgICBpZiAobiA9PSB0aGlzICYmIGNvbnRlbnQgIT0gbnVsbCAmJiBjb250ZW50Lmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgICAgIHNldERhdGEoY29udGVudCk7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gdGhpczsKKyAgICAgICAgICAgICAgICBuID0gbi5uZXh0VGV4dE5vZGUoKTsKKworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBOb2RlIHRvUmVtb3ZlID0gbjsgLy8gYmVjYXVzZSByZW1vdmVDaGlsZCgpIGRldGFjaGVzIHNpYmxpbmdzCisgICAgICAgICAgICAgICAgbiA9IG4ubmV4dFRleHROb2RlKCk7CisgICAgICAgICAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKHRvUmVtb3ZlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZmlyc3QgdGV4dCBvciBDREFUQSBub2RlIGluIHRoZSBjdXJyZW50IHNlcXVlbmNlIG9mIHRleHQgYW5kCisgICAgICogQ0RBVEEgbm9kZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBUZXh0SW1wbCBmaXJzdFRleHROb2RlSW5DdXJyZW50UnVuKCkgeworICAgICAgICBUZXh0SW1wbCBmaXJzdFRleHRJbkN1cnJlbnRSdW4gPSB0aGlzOworICAgICAgICBmb3IgKE5vZGUgcCA9IGdldFByZXZpb3VzU2libGluZygpOyBwICE9IG51bGw7IHAgPSBwLmdldFByZXZpb3VzU2libGluZygpKSB7CisgICAgICAgICAgICBzaG9ydCBub2RlVHlwZSA9IHAuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgICAgICAgIGlmIChub2RlVHlwZSA9PSBOb2RlLlRFWFRfTk9ERSB8fCBub2RlVHlwZSA9PSBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERSkgeworICAgICAgICAgICAgICAgIGZpcnN0VGV4dEluQ3VycmVudFJ1biA9IChUZXh0SW1wbCkgcDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZpcnN0VGV4dEluQ3VycmVudFJ1bjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IHNpYmxpbmcgbm9kZSBpZiBpdCBleGlzdHMgYW5kIGl0IGlzIHRleHQgb3IgQ0RBVEEuCisgICAgICogT3RoZXJ3aXNlIHJldHVybnMgbnVsbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFRleHRJbXBsIG5leHRUZXh0Tm9kZSgpIHsKKyAgICAgICAgTm9kZSBuZXh0U2libGluZyA9IGdldE5leHRTaWJsaW5nKCk7CisgICAgICAgIGlmIChuZXh0U2libGluZyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHNob3J0IG5vZGVUeXBlID0gbmV4dFNpYmxpbmcuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgICAgcmV0dXJuIG5vZGVUeXBlID09IE5vZGUuVEVYVF9OT0RFIHx8IG5vZGVUeXBlID09IE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFCisgICAgICAgICAgICAgICAgPyAoVGV4dEltcGwpIG5leHRTaWJsaW5nCisgICAgICAgICAgICAgICAgOiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyaWVzIHRvIHJlbW92ZSB0aGlzIG5vZGUgdXNpbmcgaXRzZWxmIGFuZCB0aGUgcHJldmlvdXMgbm9kZSBhcyBjb250ZXh0LgorICAgICAqIElmIHRoaXMgbm9kZSdzIHRleHQgaXMgZW1wdHksIHRoaXMgbm9kZSBpcyByZW1vdmVkIGFuZCBudWxsIGlzIHJldHVybmVkLgorICAgICAqIElmIHRoZSBwcmV2aW91cyBub2RlIGV4aXN0cyBhbmQgaXMgYSB0ZXh0IG5vZGUsIHRoaXMgbm9kZSdzIHRleHQgd2lsbCBiZQorICAgICAqIGFwcGVuZGVkIHRvIHRoYXQgbm9kZSdzIHRleHQgYW5kIHRoaXMgbm9kZSB3aWxsIGJlIHJlbW92ZWQuCisgICAgICoKKyAgICAgKiA8cD5BbHRob3VnaCB0aGlzIG1ldGhvZCBhbHRlcnMgdGhlIHN0cnVjdHVyZSBvZiB0aGUgRE9NIHRyZWUsIGl0IGRvZXMKKyAgICAgKiBub3QgYWx0ZXIgdGhlIGRvY3VtZW50J3Mgc2VtYW50aWNzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbm9kZSBob2xkaW5nIHRoaXMgbm9kZSdzIHRleHQgYW5kIHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvbi4KKyAgICAgKiAgICAgQ2FuIGJlIG51bGwgaWYgdGhpcyBub2RlIGNvbnRhaW5lZCB0aGUgZW1wdHkgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBUZXh0SW1wbCBtaW5pbWl6ZSgpIHsKKyAgICAgICAgaWYgKGdldExlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZCh0aGlzKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgTm9kZSBwcmV2aW91cyA9IGdldFByZXZpb3VzU2libGluZygpOworICAgICAgICBpZiAocHJldmlvdXMgPT0gbnVsbCB8fCBwcmV2aW91cy5nZXROb2RlVHlwZSgpICE9IE5vZGUuVEVYVF9OT0RFKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgfQorCisgICAgICAgIFRleHRJbXBsIHByZXZpb3VzVGV4dCA9IChUZXh0SW1wbCkgcHJldmlvdXM7CisgICAgICAgIHByZXZpb3VzVGV4dC5idWZmZXIuYXBwZW5kKGJ1ZmZlcik7CisgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZCh0aGlzKTsKKyAgICAgICAgcmV0dXJuIHByZXZpb3VzVGV4dDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9wYXJzZXJzL0RvY3VtZW50QnVpbGRlckZhY3RvcnlJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9wYXJzZXJzL0RvY3VtZW50QnVpbGRlckZhY3RvcnlJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGVmYWEzMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL3BhcnNlcnMvRG9jdW1lbnRCdWlsZGVyRmFjdG9yeUltcGwuamF2YQpAQCAtMCwwICsxLDEwNSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhtbC5wYXJzZXJzOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKKworLyoqCisgKiBQcm92aWRlcyBhIHN0cmFpZ2h0Zm9yd2FyZCBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGltcGxlbWVudGF0aW9uIGJhc2VkIG9uCisgKiBYTUxQdWxsL0tYTUwuIFRoZSBjbGFzcyBpcyB1c2VkIGludGVybmFsbHkgb25seSwgdGh1cyBvbmx5IG5vdGFibGUgbWVtYmVycworICogdGhhdCBhcmUgbm90IGFscmVhZHkgaW4gdGhlIGFic3RyYWN0IHN1cGVyY2xhc3MgYXJlIGRvY3VtZW50ZWQuIEhvcGUgdGhhdCdzCisgKiBvay4KKyAqLworcHVibGljIGNsYXNzIERvY3VtZW50QnVpbGRlckZhY3RvcnlJbXBsIGV4dGVuZHMgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFUyA9CisgICAgICAgICAgICAiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXMiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT04gPQorICAgICAgICAgICAgImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy92YWxpZGF0aW9uIjsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0QXR0cmlidXRlKFN0cmluZyBuYW1lKSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihuYW1lKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKSB0aHJvd3MgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKE5BTUVTUEFDRVMuZXF1YWxzKG5hbWUpKSB7CisgICAgICAgICAgICByZXR1cm4gaXNOYW1lc3BhY2VBd2FyZSgpOworICAgICAgICB9IGVsc2UgaWYgKFZBTElEQVRJT04uZXF1YWxzKG5hbWUpKSB7CisgICAgICAgICAgICByZXR1cm4gaXNWYWxpZGF0aW5nKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihuYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEb2N1bWVudEJ1aWxkZXIgbmV3RG9jdW1lbnRCdWlsZGVyKCkKKyAgICAgICAgICAgIHRocm93cyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzVmFsaWRhdGluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgIk5vIHZhbGlkYXRpbmcgRG9jdW1lbnRCdWlsZGVyIGltcGxlbWVudGF0aW9uIGF2YWlsYWJsZSIpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRPRE8gSWYgQW5kcm9pZCBpcyBnb2luZyB0byBzdXBwb3J0IGEgZGlmZmVyZW50IERvY3VtZW50QnVpbGRlcgorICAgICAgICAgKiBpbXBsZW1lbnRhdGlvbnMsIHRoaXMgc2hvdWxkIGJlIHdpcmVkIGhlcmUuIElmIHdlIHdhbnRlZCB0bworICAgICAgICAgKiBhbGxvdyBkaWZmZXJlbnQgaW1wbGVtZW50YXRpb25zLCB0aGVzZSBjb3VsZCBiZSBkaXN0aW5ndWlzaGVkIGJ5CisgICAgICAgICAqIGEgc3BlY2lhbCBmZWF0dXJlIChsaWtlIGh0dHA6Ly93d3cub3JnLmFwYWNoZS5oYXJtb255LmNvbS94bWwvZXhwYXQpCisgICAgICAgICAqIG9yIGJ5IHRocm93aW5nIHRoZSBmdWxsIFNQSSBtb250eSBhdCBpdC4KKyAgICAgICAgICovCisgICAgICAgIERvY3VtZW50QnVpbGRlckltcGwgYnVpbGRlciA9IG5ldyBEb2N1bWVudEJ1aWxkZXJJbXBsKCk7CisgICAgICAgIGJ1aWxkZXIuc2V0Q29hbGVzY2luZyhpc0NvYWxlc2NpbmcoKSk7CisgICAgICAgIGJ1aWxkZXIuc2V0SWdub3JlQ29tbWVudHMoaXNJZ25vcmluZ0NvbW1lbnRzKCkpOworICAgICAgICBidWlsZGVyLnNldElnbm9yZUVsZW1lbnRDb250ZW50V2hpdGVzcGFjZShpc0lnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKCkpOworICAgICAgICBidWlsZGVyLnNldE5hbWVzcGFjZUF3YXJlKGlzTmFtZXNwYWNlQXdhcmUoKSk7CisKKyAgICAgICAgLy8gVE9ETyBXaGF0IGFib3V0IGV4cGFuZEVudGl0eVJlZmVyZW5jZXM/CisKKyAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0QXR0cmlidXRlKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihuYW1lKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKQorICAgICAgICAgICAgdGhyb3dzIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24geworICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChOQU1FU1BBQ0VTLmVxdWFscyhuYW1lKSkgeworICAgICAgICAgICAgc2V0TmFtZXNwYWNlQXdhcmUodmFsdWUpOworICAgICAgICB9IGVsc2UgaWYgKFZBTElEQVRJT04uZXF1YWxzKG5hbWUpKSB7CisgICAgICAgICAgICBzZXRWYWxpZGF0aW5nKHZhbHVlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKG5hbWUpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9wYXJzZXJzL0RvY3VtZW50QnVpbGRlckltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL3BhcnNlcnMvRG9jdW1lbnRCdWlsZGVySW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQxMDc5YzgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9wYXJzZXJzL0RvY3VtZW50QnVpbGRlckltcGwuamF2YQpAQCAtMCwwICsxLDQyOCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhtbC5wYXJzZXJzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5uZXQuVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CitpbXBvcnQgbGliY29yZS5pby5Jb1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54bWwuZG9tLkNEQVRBU2VjdGlvbkltcGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnhtbC5kb20uRE9NSW1wbGVtZW50YXRpb25JbXBsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54bWwuZG9tLkRvY3VtZW50SW1wbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkueG1sLmRvbS5Eb2N1bWVudFR5cGVJbXBsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54bWwuZG9tLlRleHRJbXBsOworaW1wb3J0IG9yZy5reG1sMi5pby5LWG1sUGFyc2VyOworaW1wb3J0IG9yZy53M2MuZG9tLkF0dHI7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRUeXBlOworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5UZXh0OworaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5Mb2NhdG9ySW1wbDsKK2ltcG9ydCBvcmcueG1scHVsbC52MS5YbWxQdWxsUGFyc2VyOworaW1wb3J0IG9yZy54bWxwdWxsLnYxLlhtbFB1bGxQYXJzZXJFeGNlcHRpb247CisKKy8qKgorICogQnVpbGRzIGEgRE9NIHVzaW5nIEtYbWxQYXJzZXIuCisgKi8KK2NsYXNzIERvY3VtZW50QnVpbGRlckltcGwgZXh0ZW5kcyBEb2N1bWVudEJ1aWxkZXIgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgRE9NSW1wbGVtZW50YXRpb25JbXBsIGRvbSA9IERPTUltcGxlbWVudGF0aW9uSW1wbC5nZXRJbnN0YW5jZSgpOworCisgICAgcHJpdmF0ZSBib29sZWFuIGNvYWxlc2Npbmc7CisgICAgcHJpdmF0ZSBFbnRpdHlSZXNvbHZlciBlbnRpdHlSZXNvbHZlcjsKKyAgICBwcml2YXRlIEVycm9ySGFuZGxlciBlcnJvckhhbmRsZXI7CisgICAgcHJpdmF0ZSBib29sZWFuIGlnbm9yZUNvbW1lbnRzOworICAgIHByaXZhdGUgYm9vbGVhbiBpZ25vcmVFbGVtZW50Q29udGVudFdoaXRlc3BhY2U7CisgICAgcHJpdmF0ZSBib29sZWFuIG5hbWVzcGFjZUF3YXJlOworICAgIC8vIGFkZGluZyBhIG5ldyBmaWVsZD8gZG9uJ3QgZm9yZ2V0IHRvIHVwZGF0ZSByZXNldCgpLgorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgICAgICBjb2FsZXNjaW5nID0gZmFsc2U7CisgICAgICAgIGVudGl0eVJlc29sdmVyID0gbnVsbDsKKyAgICAgICAgZXJyb3JIYW5kbGVyID0gbnVsbDsKKyAgICAgICAgaWdub3JlQ29tbWVudHMgPSBmYWxzZTsKKyAgICAgICAgaWdub3JlRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlID0gZmFsc2U7CisgICAgICAgIG5hbWVzcGFjZUF3YXJlID0gZmFsc2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERPTUltcGxlbWVudGF0aW9uIGdldERPTUltcGxlbWVudGF0aW9uKCkgeworICAgICAgICByZXR1cm4gZG9tOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzTmFtZXNwYWNlQXdhcmUoKSB7CisgICAgICAgIHJldHVybiBuYW1lc3BhY2VBd2FyZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1ZhbGlkYXRpbmcoKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRG9jdW1lbnQgbmV3RG9jdW1lbnQoKSB7CisgICAgICAgIHJldHVybiBkb20uY3JlYXRlRG9jdW1lbnQobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERvY3VtZW50IHBhcnNlKElucHV0U291cmNlIHNvdXJjZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoc291cmNlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInNvdXJjZSA9PSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gbnVsbDsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSBudWxsOworICAgICAgICBEb2N1bWVudFR5cGUgZG9jdHlwZSA9IG51bGw7CisgICAgICAgIFN0cmluZyBpbnB1dEVuY29kaW5nID0gc291cmNlLmdldEVuY29kaW5nKCk7CisgICAgICAgIFN0cmluZyBzeXN0ZW1JZCA9IHNvdXJjZS5nZXRTeXN0ZW1JZCgpOworICAgICAgICBEb2N1bWVudEltcGwgZG9jdW1lbnQgPSBuZXcgRG9jdW1lbnRJbXBsKAorICAgICAgICAgICAgICAgIGRvbSwgbmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lLCBkb2N0eXBlLCBpbnB1dEVuY29kaW5nKTsKKyAgICAgICAgZG9jdW1lbnQuc2V0RG9jdW1lbnRVUkkoc3lzdGVtSWQpOworCisgICAgICAgIEtYbWxQYXJzZXIgcGFyc2VyID0gbmV3IEtYbWxQYXJzZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcnNlci5rZWVwTmFtZXNwYWNlQXR0cmlidXRlcygpOworICAgICAgICAgICAgcGFyc2VyLnNldEZlYXR1cmUoWG1sUHVsbFBhcnNlci5GRUFUVVJFX1BST0NFU1NfTkFNRVNQQUNFUywgbmFtZXNwYWNlQXdhcmUpOworCisgICAgICAgICAgICBpZiAoc291cmNlLmdldEJ5dGVTdHJlYW0oKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcGFyc2VyLnNldElucHV0KHNvdXJjZS5nZXRCeXRlU3RyZWFtKCksIGlucHV0RW5jb2RpbmcpOworICAgICAgICAgICAgfSBlbHNlIGlmIChzb3VyY2UuZ2V0Q2hhcmFjdGVyU3RyZWFtKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHBhcnNlci5zZXRJbnB1dChzb3VyY2UuZ2V0Q2hhcmFjdGVyU3RyZWFtKCkpOworICAgICAgICAgICAgfSBlbHNlIGlmIChzeXN0ZW1JZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoc3lzdGVtSWQpOworICAgICAgICAgICAgICAgIFVSTENvbm5lY3Rpb24gdXJsQ29ubmVjdGlvbiA9IHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICAgICAgICAgIHVybENvbm5lY3Rpb24uY29ubmVjdCgpOworICAgICAgICAgICAgICAgIC8vIFRPRE86IGlmIG51bGwsIGV4dHJhY3QgdGhlIGlucHV0RW5jb2RpbmcgZnJvbSB0aGUgQ29udGVudC1UeXBlIGhlYWRlcj8KKyAgICAgICAgICAgICAgICBwYXJzZXIuc2V0SW5wdXQodXJsQ29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpLCBpbnB1dEVuY29kaW5nKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWFBhcnNlRXhjZXB0aW9uKCJJbnB1dFNvdXJjZSBuZWVkcyBhIHN0cmVhbSwgcmVhZGVyIG9yIFVSSSIsIG51bGwpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAocGFyc2VyLm5leHRUb2tlbigpID09IFhtbFB1bGxQYXJzZXIuRU5EX0RPQ1VNRU5UKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWFBhcnNlRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGVuZCBvZiBkb2N1bWVudCIsIG51bGwpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwYXJzZShwYXJzZXIsIGRvY3VtZW50LCBkb2N1bWVudCwgWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQpOworCisgICAgICAgICAgICBwYXJzZXIucmVxdWlyZShYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgbnVsbCwgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKFhtbFB1bGxQYXJzZXJFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGlmIChleC5nZXREZXRhaWwoKSBpbnN0YW5jZW9mIElPRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgKElPRXhjZXB0aW9uKSBleC5nZXREZXRhaWwoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChleC5nZXREZXRhaWwoKSBpbnN0YW5jZW9mIFJ1bnRpbWVFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikgZXguZ2V0RGV0YWlsKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIExvY2F0b3JJbXBsIGxvY2F0b3IgPSBuZXcgTG9jYXRvckltcGwoKTsKKworICAgICAgICAgICAgbG9jYXRvci5zZXRQdWJsaWNJZChzb3VyY2UuZ2V0UHVibGljSWQoKSk7CisgICAgICAgICAgICBsb2NhdG9yLnNldFN5c3RlbUlkKHN5c3RlbUlkKTsKKyAgICAgICAgICAgIGxvY2F0b3Iuc2V0TGluZU51bWJlcihleC5nZXRMaW5lTnVtYmVyKCkpOworICAgICAgICAgICAgbG9jYXRvci5zZXRDb2x1bW5OdW1iZXIoZXguZ2V0Q29sdW1uTnVtYmVyKCkpOworCisgICAgICAgICAgICBTQVhQYXJzZUV4Y2VwdGlvbiBuZXdFeCA9IG5ldyBTQVhQYXJzZUV4Y2VwdGlvbihleC5nZXRNZXNzYWdlKCksIGxvY2F0b3IpOworCisgICAgICAgICAgICBpZiAoZXJyb3JIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuZXJyb3IobmV3RXgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0aHJvdyBuZXdFeDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIElvVXRpbHMuY2xvc2VRdWlldGx5KHBhcnNlcik7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZG9jdW1lbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW1wbGVtZW50cyB0aGUgd2hvbGUgcGFyc2luZyBvZiB0aGUgWE1MIGRvY3VtZW50LiBUaGUgWE1MIHB1bGwgcGFyc2VyIGlzCisgICAgICogYWN0dWFsbHkgbW9yZSBvZiBhIHRva2VuaXplciwgYW5kIHdlIGFyZSBkb2luZyBhIGNsYXNzaWNhbCByZWN1cnNpdmUKKyAgICAgKiBkZXNjZW50IHBhcnNpbmcgKHRoZSBtZXRob2QgaW52b2tlcyBpdHNlbGYgZm9yIFhNTCBlbGVtZW50cykuIE91cgorICAgICAqIGFwcHJvYWNoIHRvIHBhcnNpbmcgZG9lcyBhY2NlcHQgc29tZSBpbGxlZ2FsIGRvY3VtZW50cyAobW9yZSB0aGFuIG9uZQorICAgICAqIHJvb3QgZWxlbWVudCwgZm9yIGV4YW1wbGUpLiBUaGUgYXNzdW1wdGlvbiBpcyB0aGF0IHRoZSBET00gaW1wbGVtZW50YXRpb24KKyAgICAgKiB0aHJvd3MgdGhlIHByb3BlciBleGNlcHRpb25zIGluIHRoZXNlIGNhc2VzLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcnNlciBUaGUgWE1MIHB1bGwgcGFyc2VyIHdlJ3JlIHJlYWRpbmcgZnJvbS4KKyAgICAgKiBAcGFyYW0gZG9jdW1lbnQgVGhlIGRvY3VtZW50IHdlJ3JlIGJ1aWxkaW5nLgorICAgICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIHdlJ3JlIGN1cnJlbnRseSBvbiAoaW5pdGlhbGx5IHRoZSBkb2N1bWVudCBpdHNlbGYpLgorICAgICAqIEBwYXJhbSBlbmRUb2tlbiBUaGUgdG9rZW4gdGhhdCB3aWxsIGVuZCB0aGlzIHJlY3Vyc2l2ZSBjYWxsLiBFaXRoZXIKKyAgICAgKiAgICAgICAgWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQgb3IgWG1sUHVsbFBhcnNlci5FTkRfVEFHLgorICAgICAqCisgICAgICogQHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIElmIGEgcGFyc2luZyBlcnJvciBvY2N1cnMuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhIGdlbmVyYWwgSU8gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwYXJzZShLWG1sUGFyc2VyIHBhcnNlciwgRG9jdW1lbnRJbXBsIGRvY3VtZW50LCBOb2RlIG5vZGUsCisgICAgICAgICAgICBpbnQgZW5kVG9rZW4pIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgaW50IHRva2VuID0gcGFyc2VyLmdldEV2ZW50VHlwZSgpOworCisgICAgICAgIC8qCisgICAgICAgICAqIFRoZSBtYWluIHBhcnNpbmcgbG9vcC4gVGhlIHByZWNvbmRpdGlvbiBpcyB0aGF0IHdlIGFyZSBhbHJlYWR5IG9uIHRoZQorICAgICAgICAgKiB0b2tlbiB0byBiZSBwcm9jZXNzZWQuIFRoaXMgaG9sZHMgZm9yIGVhY2ggaXRlcmF0aW9uIG9mIHRoZSBsb29wLCBzbworICAgICAgICAgKiB0aGUgaW5uZXIgc3RhdGVtZW50cyBoYXZlIHRvIGVuc3VyZSB0aGF0IChpbiBwYXJ0aWN1bGFyIHRoZSByZWN1cnNpdmUKKyAgICAgICAgICogY2FsbCkuCisgICAgICAgICAqLworICAgICAgICB3aGlsZSAodG9rZW4gIT0gZW5kVG9rZW4gJiYgdG9rZW4gIT0gWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQpIHsKKyAgICAgICAgICAgIGlmICh0b2tlbiA9PSBYbWxQdWxsUGFyc2VyLlBST0NFU1NJTkdfSU5TVFJVQ1RJT04pIHsKKyAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAqIEZvdW5kIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMuIFdlIG5lZWQgdG8gc3BsaXQgdGhlIHRva2VuCisgICAgICAgICAgICAgICAgICogdGV4dCBhdCB0aGUgZmlyc3Qgd2hpdGVzcGFjZSBjaGFyYWN0ZXIuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBwYXJzZXIuZ2V0VGV4dCgpOworCisgICAgICAgICAgICAgICAgaW50IGRvdCA9IHRleHQuaW5kZXhPZignICcpOworCisgICAgICAgICAgICAgICAgU3RyaW5nIHRhcmdldCA9IChkb3QgIT0gLTEgPyB0ZXh0LnN1YnN0cmluZygwLCBkb3QpIDogdGV4dCk7CisgICAgICAgICAgICAgICAgU3RyaW5nIGRhdGEgPSAoZG90ICE9IC0xID8gdGV4dC5zdWJzdHJpbmcoZG90ICsgMSkgOiAiIik7CisKKyAgICAgICAgICAgICAgICBub2RlLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsCisgICAgICAgICAgICAgICAgICAgICAgICBkYXRhKSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHRva2VuID09IFhtbFB1bGxQYXJzZXIuRE9DREVDTCkgeworICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gcGFyc2VyLmdldFJvb3RFbGVtZW50TmFtZSgpOworICAgICAgICAgICAgICAgIFN0cmluZyBwdWJsaWNJZCA9IHBhcnNlci5nZXRQdWJsaWNJZCgpOworICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCA9IHBhcnNlci5nZXRTeXN0ZW1JZCgpOworICAgICAgICAgICAgICAgIGRvY3VtZW50LmFwcGVuZENoaWxkKG5ldyBEb2N1bWVudFR5cGVJbXBsKGRvY3VtZW50LCBuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpKTsKKworICAgICAgICAgICAgfSBlbHNlIGlmICh0b2tlbiA9PSBYbWxQdWxsUGFyc2VyLkNPTU1FTlQpIHsKKyAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAqIEZvdW5kIGEgY29tbWVudC4gV2Ugc2ltcGx5IHRha2UgdGhlIHRva2VuIHRleHQsIGJ1dCB3ZSBvbmx5CisgICAgICAgICAgICAgICAgICogY3JlYXRlIGEgbm9kZSBpZiB0aGUgY2xpZW50IHdhbnRzIHRvIHNlZSBjb21tZW50cyBhdCBhbGwuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgaWYgKCFpZ25vcmVDb21tZW50cykgeworICAgICAgICAgICAgICAgICAgICBub2RlLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUNvbW1lbnQocGFyc2VyLmdldFRleHQoKSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAodG9rZW4gPT0gWG1sUHVsbFBhcnNlci5JR05PUkFCTEVfV0hJVEVTUEFDRSkgeworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogRm91bmQgc29tZSBpZ25vcmFibGUgd2hpdGVzcGFjZS4gV2Ugb25seSBhZGQgaXQgaWYgdGhlIGNsaWVudAorICAgICAgICAgICAgICAgICAqIHdhbnRzIHRvIHNlZSB3aGl0ZXNwYWNlLiBXaGl0ZXNwYWNlIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlCisgICAgICAgICAgICAgICAgICogZG9jdW1lbnQgZWxlbWVudCBpcyBhbHdheXMgaWdub3JlZC4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBpZiAoIWlnbm9yZUVsZW1lbnRDb250ZW50V2hpdGVzcGFjZSAmJiBkb2N1bWVudCAhPSBub2RlKSB7CisgICAgICAgICAgICAgICAgICAgIGFwcGVuZFRleHQoZG9jdW1lbnQsIG5vZGUsIHRva2VuLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKHRva2VuID09IFhtbFB1bGxQYXJzZXIuVEVYVCB8fCB0b2tlbiA9PSBYbWxQdWxsUGFyc2VyLkNEU0VDVCkgeworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogRm91bmQgYSBwaWVjZSBvZiB0ZXh0IChwb3NzaWJseSBlbmNvZGVkIGFzIGEgQ0RBVEEgc2VjdGlvbikuCisgICAgICAgICAgICAgICAgICogVGhhdCdzIHRoZSBlYXNpZXN0IGNhc2UuIFdlIHNpbXBseSB0YWtlIGl0IGFuZCBjcmVhdGUgYSBuZXcgdGV4dCBub2RlLAorICAgICAgICAgICAgICAgICAqIG9yIG1lcmdlIHdpdGggYW4gYWRqYWNlbnQgdGV4dCBub2RlLgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIGFwcGVuZFRleHQoZG9jdW1lbnQsIG5vZGUsIHRva2VuLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodG9rZW4gPT0gWG1sUHVsbFBhcnNlci5FTlRJVFlfUkVGKSB7CisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgKiBGb3VuZCBhbiBlbnRpdHkgcmVmZXJlbmNlLiBJZiBhbiBlbnRpdHkgcmVzb2x2ZXIgaXMKKyAgICAgICAgICAgICAgICAgKiBpbnN0YWxsZWQsIHdlIHJlcGxhY2UgaXQgYnkgdGV4dCAoaWYgcG9zc2libGUpLiBPdGhlcndpc2Ugd2UKKyAgICAgICAgICAgICAgICAgKiBhZGQgYW4gZW50aXR5IHJlZmVyZW5jZSBub2RlLgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIFN0cmluZyBlbnRpdHkgPSBwYXJzZXIuZ2V0TmFtZSgpOworCisgICAgICAgICAgICAgICAgaWYgKGVudGl0eVJlc29sdmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyBJbXBsZW1lbnQgdGhpcy4uLgorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIFN0cmluZyByZXNvbHZlZCA9IHJlc29sdmVQcmVkZWZpbmVkT3JDaGFyYWN0ZXJFbnRpdHkoZW50aXR5KTsKKyAgICAgICAgICAgICAgICBpZiAocmVzb2x2ZWQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBhcHBlbmRUZXh0KGRvY3VtZW50LCBub2RlLCB0b2tlbiwgcmVzb2x2ZWQpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIG5vZGUuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRW50aXR5UmVmZXJlbmNlKGVudGl0eSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAodG9rZW4gPT0gWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcpIHsKKyAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAqIEZvdW5kIGFuIGVsZW1lbnQgc3RhcnQgdGFnLiBXZSBjcmVhdGUgYW4gZWxlbWVudCBub2RlIHdpdGgKKyAgICAgICAgICAgICAgICAgKiB0aGUgcHJvcGVyIGluZm8gYW5kIGF0dHJpYnV0ZXMuIFdlIHRoZW4gaW52b2tlIHBhcnNlKCkKKyAgICAgICAgICAgICAgICAgKiByZWN1cnNpdmVseSB0byBoYW5kbGUgdGhlIG5leHQgbGV2ZWwgb2YgbmVzdGluZy4gV2hlbiB3ZQorICAgICAgICAgICAgICAgICAqIHJldHVybiBmcm9tIHRoaXMgY2FsbCwgd2UgY2hlY2sgdGhhdCB3ZSBhcmUgb24gdGhlIHByb3BlcgorICAgICAgICAgICAgICAgICAqIGVsZW1lbnQgZW5kIHRhZy4gVGhlIHdob2xlIGhhbmRsaW5nIGRpZmZlcnMgc29tZXdoYXQKKyAgICAgICAgICAgICAgICAgKiBkZXBlbmRpbmcgb24gd2hldGhlciB0aGUgcGFyc2VyIGlzIG5hbWVzcGFjZS1hd2FyZSBvciBub3QuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZUF3YXJlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIENvbGxlY3QgaW5mbyBmb3IgZWxlbWVudCBub2RlCisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UgPSBwYXJzZXIuZ2V0TmFtZXNwYWNlKCk7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gcGFyc2VyLmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IHBhcnNlci5nZXRQcmVmaXgoKTsKKworICAgICAgICAgICAgICAgICAgICBpZiAoIiIuZXF1YWxzKG5hbWVzcGFjZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAvLyBDcmVhdGUgZWxlbWVudCBub2RlIGFuZCB3aXJlIGl0IGNvcnJlY3RseQorICAgICAgICAgICAgICAgICAgICBFbGVtZW50IGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlLCBuYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRQcmVmaXgocHJlZml4KTsKKyAgICAgICAgICAgICAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChlbGVtZW50KTsKKworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcnNlci5nZXRBdHRyaWJ1dGVDb3VudCgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbGxlY3QgaW5mbyBmb3IgYSBzaW5nbGUgYXR0cmlidXRlIG5vZGUKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyTmFtZXNwYWNlID0gcGFyc2VyLmdldEF0dHJpYnV0ZU5hbWVzcGFjZShpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyUHJlZml4ID0gcGFyc2VyLmdldEF0dHJpYnV0ZVByZWZpeChpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyTmFtZSA9IHBhcnNlci5nZXRBdHRyaWJ1dGVOYW1lKGkpOworICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF0dHJWYWx1ZSA9IHBhcnNlci5nZXRBdHRyaWJ1dGVWYWx1ZShpKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCIiLmVxdWFscyhhdHRyTmFtZXNwYWNlKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJOYW1lc3BhY2UgPSBudWxsOworICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYXR0cmlidXRlIG5vZGUgYW5kIHdpcmUgaXQgY29ycmVjdGx5CisgICAgICAgICAgICAgICAgICAgICAgICBBdHRyIGF0dHIgPSBkb2N1bWVudC5jcmVhdGVBdHRyaWJ1dGVOUyhhdHRyTmFtZXNwYWNlLCBhdHRyTmFtZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBhdHRyLnNldFByZWZpeChhdHRyUHJlZml4KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIuc2V0VmFsdWUoYXR0clZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZU5TKGF0dHIpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgLy8gUmVjdXJzaXZlIGRlc2NlbnQKKyAgICAgICAgICAgICAgICAgICAgdG9rZW4gPSBwYXJzZXIubmV4dFRva2VuKCk7CisgICAgICAgICAgICAgICAgICAgIHBhcnNlKHBhcnNlciwgZG9jdW1lbnQsIGVsZW1lbnQsIFhtbFB1bGxQYXJzZXIuRU5EX1RBRyk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gRXhwZWN0IHRoZSBlbGVtZW50J3MgZW5kIHRhZyBoZXJlCisgICAgICAgICAgICAgICAgICAgIHBhcnNlci5yZXF1aXJlKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgbmFtZXNwYWNlLCBuYW1lKTsKKworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIC8vIENvbGxlY3QgaW5mbyBmb3IgZWxlbWVudCBub2RlCisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gcGFyc2VyLmdldE5hbWUoKTsKKworICAgICAgICAgICAgICAgICAgICAvLyBDcmVhdGUgZWxlbWVudCBub2RlIGFuZCB3aXJlIGl0IGNvcnJlY3RseQorICAgICAgICAgICAgICAgICAgICBFbGVtZW50IGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KG5hbWUpOworICAgICAgICAgICAgICAgICAgICBub2RlLmFwcGVuZENoaWxkKGVsZW1lbnQpOworCisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyc2VyLmdldEF0dHJpYnV0ZUNvdW50KCk7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29sbGVjdCBpbmZvIGZvciBhIHNpbmdsZSBhdHRyaWJ1dGUgbm9kZQorICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF0dHJOYW1lID0gcGFyc2VyLmdldEF0dHJpYnV0ZU5hbWUoaSk7CisgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXR0clZhbHVlID0gcGFyc2VyLmdldEF0dHJpYnV0ZVZhbHVlKGkpOworCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYXR0cmlidXRlIG5vZGUgYW5kIHdpcmUgaXQgY29ycmVjdGx5CisgICAgICAgICAgICAgICAgICAgICAgICBBdHRyIGF0dHIgPSBkb2N1bWVudC5jcmVhdGVBdHRyaWJ1dGUoYXR0ck5hbWUpOworICAgICAgICAgICAgICAgICAgICAgICAgYXR0ci5zZXRWYWx1ZShhdHRyVmFsdWUpOworICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlKGF0dHIpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgLy8gUmVjdXJzaXZlIGRlc2NlbnQKKyAgICAgICAgICAgICAgICAgICAgdG9rZW4gPSBwYXJzZXIubmV4dFRva2VuKCk7CisgICAgICAgICAgICAgICAgICAgIHBhcnNlKHBhcnNlciwgZG9jdW1lbnQsIGVsZW1lbnQsIFhtbFB1bGxQYXJzZXIuRU5EX1RBRyk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gRXhwZWN0IHRoZSBlbGVtZW50J3MgZW5kIHRhZyBoZXJlCisgICAgICAgICAgICAgICAgICAgIHBhcnNlci5yZXF1aXJlKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgIiIsIG5hbWUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdG9rZW4gPSBwYXJzZXIubmV4dFRva2VuKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gdG9rZW4gdGhlIFhNTCBwdWxsIHBhcnNlciB0b2tlbiB0eXBlLCBzdWNoIGFzIFhtbFB1bGxQYXJzZXIuQ0RTRUNUCisgICAgICogICAgICBvciBYbWxQdWxsUGFyc2VyLkVOVElUWV9SRUYuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGFwcGVuZFRleHQoRG9jdW1lbnRJbXBsIGRvY3VtZW50LCBOb2RlIHBhcmVudCwgaW50IHRva2VuLCBTdHJpbmcgdGV4dCkgeworICAgICAgICAvLyBJZ25vcmUgZW1wdHkgcnVucy4KKyAgICAgICAgaWYgKHRleHQuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgLy8gTWVyZ2Ugd2l0aCBhbnkgcHJldmlvdXMgdGV4dCBub2RlIGlmIHBvc3NpYmxlLgorICAgICAgICBpZiAoY29hbGVzY2luZyB8fCB0b2tlbiAhPSBYbWxQdWxsUGFyc2VyLkNEU0VDVCkgeworICAgICAgICAgICAgTm9kZSBsYXN0Q2hpbGQgPSBwYXJlbnQuZ2V0TGFzdENoaWxkKCk7CisgICAgICAgICAgICBpZiAobGFzdENoaWxkICE9IG51bGwgJiYgbGFzdENoaWxkLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpIHsKKyAgICAgICAgICAgICAgICBUZXh0IHRleHROb2RlID0gKFRleHQpIGxhc3RDaGlsZDsKKyAgICAgICAgICAgICAgICB0ZXh0Tm9kZS5hcHBlbmREYXRhKHRleHQpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBPa2F5LCB3ZSByZWFsbHkgZG8gbmVlZCBhIG5ldyB0ZXh0IG5vZGUKKyAgICAgICAgcGFyZW50LmFwcGVuZENoaWxkKHRva2VuID09IFhtbFB1bGxQYXJzZXIuQ0RTRUNUCisgICAgICAgICAgICAgICAgPyBuZXcgQ0RBVEFTZWN0aW9uSW1wbChkb2N1bWVudCwgdGV4dCkKKyAgICAgICAgICAgICAgICA6IG5ldyBUZXh0SW1wbChkb2N1bWVudCwgdGV4dCkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyKEVudGl0eVJlc29sdmVyIHJlc29sdmVyKSB7CisgICAgICAgIGVudGl0eVJlc29sdmVyID0gcmVzb2x2ZXI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlciBoYW5kbGVyKSB7CisgICAgICAgIGVycm9ySGFuZGxlciA9IGhhbmRsZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udHJvbHMgd2hldGhlciB0aGlzIERvY3VtZW50QnVpbGRlciBpZ25vcmVzIGNvbW1lbnRzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldElnbm9yZUNvbW1lbnRzKGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgICAgaWdub3JlQ29tbWVudHMgPSB2YWx1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRDb2FsZXNjaW5nKGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgICAgY29hbGVzY2luZyA9IHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnRyb2xzIHdoZXRoZXIgdGhpcyBEb2N1bWVudEJ1aWxkZXIgaWdub3JlcyBlbGVtZW50IGNvbnRlbnQgd2hpdGVzcGFjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRJZ25vcmVFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICBpZ25vcmVFbGVtZW50Q29udGVudFdoaXRlc3BhY2UgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb250cm9scyB3aGV0aGVyIHRoaXMgRG9jdW1lbnRCdWlsZGVyIGlzIG5hbWVzcGFjZS1hd2FyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2VBd2FyZShib29sZWFuIHZhbHVlKSB7CisgICAgICAgIG5hbWVzcGFjZUF3YXJlID0gdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmVwbGFjZW1lbnQgdGV4dCBvciBudWxsIGlmIHtAY29kZSBlbnRpdHl9IGlzbid0IHByZWRlZmluZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgcmVzb2x2ZVByZWRlZmluZWRPckNoYXJhY3RlckVudGl0eShTdHJpbmcgZW50aXR5TmFtZSkgeworICAgICAgICAvLyBDaGFyYWN0ZXIgcmVmZXJlbmNlcywgc2VjdGlvbiA0LjEgb2YgdGhlIFhNTCBzcGVjaWZpY2F0aW9uLgorICAgICAgICBpZiAoZW50aXR5TmFtZS5zdGFydHNXaXRoKCIjeCIpKSB7CisgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZUNoYXJhY3RlclJlZmVyZW5jZShlbnRpdHlOYW1lLnN1YnN0cmluZygyKSwgMTYpOworICAgICAgICB9IGVsc2UgaWYgKGVudGl0eU5hbWUuc3RhcnRzV2l0aCgiIyIpKSB7CisgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZUNoYXJhY3RlclJlZmVyZW5jZShlbnRpdHlOYW1lLnN1YnN0cmluZygxKSwgMTApOworICAgICAgICB9CisgICAgICAgIC8vIFByZWRlZmluZWQgZW50aXRpZXMsIHNlY3Rpb24gNC42IG9mIHRoZSBYTUwgc3BlY2lmaWNhdGlvbi4KKyAgICAgICAgaWYgKCJsdCIuZXF1YWxzKGVudGl0eU5hbWUpKSB7CisgICAgICAgICAgICByZXR1cm4gIjwiOworICAgICAgICB9IGVsc2UgaWYgKCJndCIuZXF1YWxzKGVudGl0eU5hbWUpKSB7CisgICAgICAgICAgICByZXR1cm4gIj4iOworICAgICAgICB9IGVsc2UgaWYgKCJhbXAiLmVxdWFscyhlbnRpdHlOYW1lKSkgeworICAgICAgICAgICAgcmV0dXJuICImIjsKKyAgICAgICAgfSBlbHNlIGlmICgiYXBvcyIuZXF1YWxzKGVudGl0eU5hbWUpKSB7CisgICAgICAgICAgICByZXR1cm4gIiciOworICAgICAgICB9IGVsc2UgaWYgKCJxdW90Ii5lcXVhbHMoZW50aXR5TmFtZSkpIHsKKyAgICAgICAgICAgIHJldHVybiAiXCIiOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyByZXNvbHZlQ2hhcmFjdGVyUmVmZXJlbmNlKFN0cmluZyB2YWx1ZSwgaW50IGJhc2UpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBjaCA9IEludGVnZXIucGFyc2VJbnQodmFsdWUsIGJhc2UpOworICAgICAgICAgICAgaWYgKGNoIDwgMCB8fCBjaCA+IENoYXJhY3Rlci5NQVhfVkFMVUUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBTdHJpbmcudmFsdWVPZigoY2hhcikgY2gpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvcGFyc2Vycy9TQVhQYXJzZXJGYWN0b3J5SW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bWwvcGFyc2Vycy9TQVhQYXJzZXJGYWN0b3J5SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA4NjU3YjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9wYXJzZXJzL1NBWFBhcnNlckZhY3RvcnlJbXBsLmphdmEKQEAgLTAsMCArMSwxMjEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bWwucGFyc2VyczsKKworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXI7CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeTsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOworCisvKioKKyAqIFByb3ZpZGVzIGEgc3RyYWlnaHRmb3J3YXJkIFNBWFBhcnNlckZhY3RvcnkgaW1wbGVtZW50YXRpb24gYmFzZWQgb24KKyAqIEV4cGF0LiBUaGUgY2xhc3MgaXMgdXNlZCBpbnRlcm5hbGx5IG9ubHksIHRodXMgb25seSBub3RhYmxlIG1lbWJlcnMKKyAqIHRoYXQgYXJlIG5vdCBhbHJlYWR5IGluIHRoZSBhYnN0cmFjdCBzdXBlcmNsYXNzIGFyZSBkb2N1bWVudGVkLgorICovCitwdWJsaWMgY2xhc3MgU0FYUGFyc2VyRmFjdG9yeUltcGwgZXh0ZW5kcyBTQVhQYXJzZXJGYWN0b3J5IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VTCisgICAgICAgICAgICA9ICJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlcyI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURBVElPTgorICAgICAgICAgICAgPSAiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb24iOworCisgICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBCb29sZWFuPiBmZWF0dXJlcyA9IG5ldyBIYXNoTWFwPFN0cmluZywgQm9vbGVhbj4oKTsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIW5hbWUuc3RhcnRzV2l0aCgiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzLyIpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBCb29sZWFuLlRSVUUuZXF1YWxzKGZlYXR1cmVzLmdldChuYW1lKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNOYW1lc3BhY2VBd2FyZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBnZXRGZWF0dXJlKE5BTUVTUEFDRVMpOworICAgICAgICB9IGNhdGNoIChTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNWYWxpZGF0aW5nKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGdldEZlYXR1cmUoVkFMSURBVElPTik7CisgICAgICAgIH0gY2F0Y2ggKFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU0FYUGFyc2VyIG5ld1NBWFBhcnNlcigpIHRocm93cyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzVmFsaWRhdGluZygpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgIk5vIHZhbGlkYXRpbmcgU0FYUGFyc2VyIGltcGxlbWVudGF0aW9uIGF2YWlsYWJsZSIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgU0FYUGFyc2VySW1wbChmZWF0dXJlcyk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oZXgudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKSB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFuYW1lLnN0YXJ0c1dpdGgoImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy8iKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24obmFtZSk7CisgICAgICAgIH0KKworICAgICAgICBpZiAodmFsdWUpIHsKKyAgICAgICAgICAgIGZlYXR1cmVzLnB1dChuYW1lLCBCb29sZWFuLlRSVUUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gVGhpcyBpcyBuZWVkZWQgdG8gZGlzYWJsZSBmZWF0dXJlcyB0aGF0IGFyZSBlbmFibGVkIGJ5IGRlZmF1bHQuCisgICAgICAgICAgICBmZWF0dXJlcy5wdXQobmFtZSwgQm9vbGVhbi5GQUxTRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2VBd2FyZShib29sZWFuIHZhbHVlKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXRGZWF0dXJlKE5BTUVTUEFDRVMsIHZhbHVlKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFZhbGlkYXRpbmcoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2V0RmVhdHVyZShWQUxJREFUSU9OLCB2YWx1ZSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihleCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9wYXJzZXJzL1NBWFBhcnNlckltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG1sL3BhcnNlcnMvU0FYUGFyc2VySW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFlYzY2MmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3htbC9wYXJzZXJzL1NBWFBhcnNlckltcGwuamF2YQpAQCAtMCwwICsxLDEwOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhtbC5wYXJzZXJzOworCitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54bWwuRXhwYXRSZWFkZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguUGFyc2VyOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5YTUxSZWFkZXJBZGFwdGVyOworCisvKioKKyAqIEEgU0FYIHBhcnNlciBiYXNlZCBvbiBFeHBhdC4KKyAqLworZmluYWwgY2xhc3MgU0FYUGFyc2VySW1wbCBleHRlbmRzIFNBWFBhcnNlciB7CisKKyAgICBwcml2YXRlIE1hcDxTdHJpbmcsIEJvb2xlYW4+IGluaXRpYWxGZWF0dXJlczsKKyAgICBwcml2YXRlIFhNTFJlYWRlciByZWFkZXI7CisgICAgcHJpdmF0ZSBQYXJzZXIgcGFyc2VyOworCisgICAgU0FYUGFyc2VySW1wbChNYXA8U3RyaW5nLCBCb29sZWFuPiBpbml0aWFsRmVhdHVyZXMpCisgICAgICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5pbml0aWFsRmVhdHVyZXMgPSBpbml0aWFsRmVhdHVyZXMuaXNFbXB0eSgpCisgICAgICAgICAgICAgICAgPyBDb2xsZWN0aW9ucy48U3RyaW5nLCBCb29sZWFuPmVtcHR5TWFwKCkKKyAgICAgICAgICAgICAgICA6IG5ldyBIYXNoTWFwPFN0cmluZywgQm9vbGVhbj4oaW5pdGlhbEZlYXR1cmVzKTsKKyAgICAgICAgcmVzZXRJbnRlcm5hbCgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZXNldEludGVybmFsKCkKKyAgICAgICAgICAgIHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24sIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24geworICAgICAgICByZWFkZXIgPSBuZXcgRXhwYXRSZWFkZXIoKTsKKyAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLEJvb2xlYW4+IGVudHJ5IDogaW5pdGlhbEZlYXR1cmVzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIHJlYWRlci5zZXRGZWF0dXJlKGVudHJ5LmdldEtleSgpLCBlbnRyeS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCByZXNldCgpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogVGhlIGV4Y2VwdGlvbnMgYXJlIGltcG9zc2libGUuIElmIGFueSBmZWF0dXJlcyBhcmUgdW5yZWNvZ25pemVkIG9yCisgICAgICAgICAqIHVuc3VwcG9ydGVkLCBjb25zdHJ1Y3Rpb24gb2YgdGhpcyBpbnN0YW5jZSB3b3VsZCBoYXZlIGZhaWxlZC4KKyAgICAgICAgICovCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXNldEludGVybmFsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CisgICAgICAgIH0gY2F0Y2ggKFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBQYXJzZXIgZ2V0UGFyc2VyKCkgeworICAgICAgICBpZiAocGFyc2VyID09IG51bGwpIHsKKyAgICAgICAgICAgIHBhcnNlciA9IG5ldyBYTUxSZWFkZXJBZGFwdGVyKHJlYWRlcik7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcGFyc2VyOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLAorICAgICAgICAgICAgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHJlYWRlci5nZXRQcm9wZXJ0eShuYW1lKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgWE1MUmVhZGVyIGdldFhNTFJlYWRlcigpIHsKKyAgICAgICAgcmV0dXJuIHJlYWRlcjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc05hbWVzcGFjZUF3YXJlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIHJlYWRlci5nZXRGZWF0dXJlKCJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlcyIpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzVmFsaWRhdGluZygpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpCisgICAgICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgcmVhZGVyLnNldFByb3BlcnR5KG5hbWUsIHZhbHVlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9BYnN0cmFjdFNlc3Npb25Db250ZXh0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9BYnN0cmFjdFNlc3Npb25Db250ZXh0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjQ5NmE5MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0Fic3RyYWN0U2Vzc2lvbkNvbnRleHQuamF2YQpAQCAtMCwwICsxLDI5MyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5EYXRhT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb25Db250ZXh0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5wcm92aWRlci5jZXJ0Llg1MDlDZXJ0SW1wbDsKKworLyoqCisgKiBTdXBwb3J0cyBTU0wgc2Vzc2lvbiBjYWNoZXMuCisgKi8KK2Fic3RyYWN0IGNsYXNzIEFic3RyYWN0U2Vzc2lvbkNvbnRleHQgaW1wbGVtZW50cyBTU0xTZXNzaW9uQ29udGV4dCB7CisKKyAgICB2b2xhdGlsZSBpbnQgbWF4aW11bVNpemU7CisgICAgdm9sYXRpbGUgaW50IHRpbWVvdXQ7CisKKyAgICBmaW5hbCBpbnQgc3NsQ3R4TmF0aXZlUG9pbnRlciA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworCisgICAgLyoqIElkZW50aWZpZXMgT3BlblNTTCBzZXNzaW9ucy4gKi8KKyAgICBzdGF0aWMgZmluYWwgaW50IE9QRU5fU1NMID0gMTsKKworICAgIHByaXZhdGUgZmluYWwgTWFwPEJ5dGVBcnJheSwgU1NMU2Vzc2lvbj4gc2Vzc2lvbnMKKyAgICAgICAgICAgID0gbmV3IExpbmtlZEhhc2hNYXA8Qnl0ZUFycmF5LCBTU0xTZXNzaW9uPigpIHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBib29sZWFuIHJlbW92ZUVsZGVzdEVudHJ5KAorICAgICAgICAgICAgICAgIE1hcC5FbnRyeTxCeXRlQXJyYXksIFNTTFNlc3Npb24+IGVsZGVzdCkgeworICAgICAgICAgICAgcmV0dXJuIG1heGltdW1TaXplID4gMCAmJiBzaXplKCkgPiBtYXhpbXVtU2l6ZTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHNlc3Npb24gY29udGV4dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtYXhpbXVtU2l6ZSBvZiBjYWNoZQorICAgICAqIEBwYXJhbSB0aW1lb3V0IGZvciBjYWNoZSBlbnRyaWVzCisgICAgICovCisgICAgQWJzdHJhY3RTZXNzaW9uQ29udGV4dChpbnQgbWF4aW11bVNpemUsIGludCB0aW1lb3V0KSB7CisgICAgICAgIHRoaXMubWF4aW11bVNpemUgPSBtYXhpbXVtU2l6ZTsKKyAgICAgICAgdGhpcy50aW1lb3V0ID0gdGltZW91dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb2xsZWN0aW9uIG9mIHNlc3Npb25zIG9yZGVyZWQgZnJvbSBvbGRlc3QgdG8gbmV3ZXN0CisgICAgICovCisgICAgcHJpdmF0ZSBJdGVyYXRvcjxTU0xTZXNzaW9uPiBzZXNzaW9uSXRlcmF0b3IoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoc2Vzc2lvbnMpIHsKKyAgICAgICAgICAgIFNTTFNlc3Npb25bXSBhcnJheSA9IHNlc3Npb25zLnZhbHVlcygpLnRvQXJyYXkoCisgICAgICAgICAgICAgICAgICAgIG5ldyBTU0xTZXNzaW9uW3Nlc3Npb25zLnNpemUoKV0pOworICAgICAgICAgICAgcmV0dXJuIEFycmF5cy5hc0xpc3QoYXJyYXkpLml0ZXJhdG9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgRW51bWVyYXRpb24gZ2V0SWRzKCkgeworICAgICAgICBmaW5hbCBJdGVyYXRvcjxTU0xTZXNzaW9uPiBpID0gc2Vzc2lvbkl0ZXJhdG9yKCk7CisgICAgICAgIHJldHVybiBuZXcgRW51bWVyYXRpb248Ynl0ZVtdPigpIHsKKyAgICAgICAgICAgIHByaXZhdGUgU1NMU2Vzc2lvbiBuZXh0OworICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTW9yZUVsZW1lbnRzKCkgeworICAgICAgICAgICAgICAgIGlmIChuZXh0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHdoaWxlIChpLmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgICAgICBTU0xTZXNzaW9uIHNlc3Npb24gPSBpLm5leHQoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNlc3Npb24uaXNWYWxpZCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBuZXh0ID0gc2Vzc2lvbjsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG5leHQgPSBudWxsOworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gbmV4dEVsZW1lbnQoKSB7CisgICAgICAgICAgICAgICAgaWYgKGhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBpZCA9IG5leHQuZ2V0SWQoKTsKKyAgICAgICAgICAgICAgICAgICAgbmV4dCA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpZDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgaW50IGdldFNlc3Npb25DYWNoZVNpemUoKSB7CisgICAgICAgIHJldHVybiBtYXhpbXVtU2l6ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgaW50IGdldFNlc3Npb25UaW1lb3V0KCkgeworICAgICAgICByZXR1cm4gdGltZW91dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYWtlcyBzdXJlIGNhY2hlIHNpemUgaXMgPCBtYXhpbXVtU2l6ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0cmltVG9TaXplKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKHNlc3Npb25zKSB7CisgICAgICAgICAgICBpbnQgc2l6ZSA9IHNlc3Npb25zLnNpemUoKTsKKyAgICAgICAgICAgIGlmIChzaXplID4gbWF4aW11bVNpemUpIHsKKyAgICAgICAgICAgICAgICBpbnQgcmVtb3ZhbHMgPSBzaXplIC0gbWF4aW11bVNpemU7CisgICAgICAgICAgICAgICAgSXRlcmF0b3I8U1NMU2Vzc2lvbj4gaSA9IHNlc3Npb25zLnZhbHVlcygpLml0ZXJhdG9yKCk7CisgICAgICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgICAgICBTU0xTZXNzaW9uIHNlc3Npb24gPSBpLm5leHQoKTsKKyAgICAgICAgICAgICAgICAgICAgaS5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICAgICAgc2Vzc2lvblJlbW92ZWQoc2Vzc2lvbik7CisgICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1yZW1vdmFscyA+IDApOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U2Vzc2lvblRpbWVvdXQoaW50IHNlY29uZHMpCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNlY29uZHMgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzZWNvbmRzIDwgMCIpOworICAgICAgICB9CisgICAgICAgIHRpbWVvdXQgPSBzZWNvbmRzOworCisgICAgICAgIHN5bmNocm9uaXplZCAoc2Vzc2lvbnMpIHsKKyAgICAgICAgICAgIEl0ZXJhdG9yPFNTTFNlc3Npb24+IGkgPSBzZXNzaW9ucy52YWx1ZXMoKS5pdGVyYXRvcigpOworICAgICAgICAgICAgd2hpbGUgKGkuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgU1NMU2Vzc2lvbiBzZXNzaW9uID0gaS5uZXh0KCk7CisgICAgICAgICAgICAgICAgLy8gU1NMU2Vzc2lvbidzIGtub3cgdGhlaXIgY29udGV4dCBhbmQgY29uc3VsdCB0aGUKKyAgICAgICAgICAgICAgICAvLyB0aW1lb3V0IGFzIHBhcnQgb2YgdGhlaXIgdmFsaWRpdHkgY29uZGl0aW9uLgorICAgICAgICAgICAgICAgIGlmICghc2Vzc2lvbi5pc1ZhbGlkKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaS5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICAgICAgc2Vzc2lvblJlbW92ZWQoc2Vzc2lvbik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbGVkIHdoZW4gYSBzZXNzaW9uIGlzIHJlbW92ZWQuIFVzZWQgYnkgQ2xpZW50U2Vzc2lvbkNvbnRleHQKKyAgICAgKiB0byB1cGRhdGUgaXRzIGhvc3QtYW5kLXBvcnQgYmFzZWQgY2FjaGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgc2Vzc2lvblJlbW92ZWQoU1NMU2Vzc2lvbiBzZXNzaW9uKTsKKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldFNlc3Npb25DYWNoZVNpemUoaW50IHNpemUpCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNpemUgPCAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzaXplIDwgMCIpOworICAgICAgICB9CisKKyAgICAgICAgaW50IG9sZE1heGltdW0gPSBtYXhpbXVtU2l6ZTsKKyAgICAgICAgbWF4aW11bVNpemUgPSBzaXplOworCisgICAgICAgIC8vIFRyaW0gY2FjaGUgdG8gc2l6ZSBpZiBuZWNlc3NhcnkuCisgICAgICAgIGlmIChzaXplIDwgb2xkTWF4aW11bSkgeworICAgICAgICAgICAgdHJpbVRvU2l6ZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgdGhlIGdpdmVuIHNlc3Npb24gdG8gYnl0ZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHNlc3Npb24gZGF0YSBhcyBieXRlcyBvciBudWxsIGlmIHRoZSBzZXNzaW9uIGNhbid0IGJlIGNvbnZlcnRlZAorICAgICAqLworICAgIGJ5dGVbXSB0b0J5dGVzKFNTTFNlc3Npb24gc2Vzc2lvbikgeworICAgICAgICAvLyBUT0RPOiBTdXBwb3J0IFNTTFNlc3Npb25JbXBsLCB0b28uCisgICAgICAgIGlmICghKHNlc3Npb24gaW5zdGFuY2VvZiBPcGVuU1NMU2Vzc2lvbkltcGwpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIE9wZW5TU0xTZXNzaW9uSW1wbCBzc2xTZXNzaW9uID0gKE9wZW5TU0xTZXNzaW9uSW1wbCkgc2Vzc2lvbjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgRGF0YU91dHB1dFN0cmVhbSBkYW9zID0gbmV3IERhdGFPdXRwdXRTdHJlYW0oYmFvcyk7CisKKyAgICAgICAgICAgIGRhb3Mud3JpdGVJbnQoT1BFTl9TU0wpOyAvLyBzZXNzaW9uIHR5cGUgSUQKKworICAgICAgICAgICAgLy8gU2Vzc2lvbiBkYXRhLgorICAgICAgICAgICAgYnl0ZVtdIGRhdGEgPSBzc2xTZXNzaW9uLmdldEVuY29kZWQoKTsKKyAgICAgICAgICAgIGRhb3Mud3JpdGVJbnQoZGF0YS5sZW5ndGgpOworICAgICAgICAgICAgZGFvcy53cml0ZShkYXRhKTsKKworICAgICAgICAgICAgLy8gQ2VydGlmaWNhdGVzLgorICAgICAgICAgICAgQ2VydGlmaWNhdGVbXSBjZXJ0cyA9IHNlc3Npb24uZ2V0UGVlckNlcnRpZmljYXRlcygpOworICAgICAgICAgICAgZGFvcy53cml0ZUludChjZXJ0cy5sZW5ndGgpOworCisgICAgICAgICAgICBmb3IgKENlcnRpZmljYXRlIGNlcnQgOiBjZXJ0cykgeworICAgICAgICAgICAgICAgIGRhdGEgPSBjZXJ0LmdldEVuY29kZWQoKTsKKyAgICAgICAgICAgICAgICBkYW9zLndyaXRlSW50KGRhdGEubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBkYW9zLndyaXRlKGRhdGEpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gVE9ETzogbG9jYWwgY2VydGlmaWNhdGVzPworCisgICAgICAgICAgICByZXR1cm4gYmFvcy50b0J5dGVBcnJheSgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBsb2coZSk7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBsb2coZSk7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBzZXNzaW9uIGZyb20gdGhlIGdpdmVuIGJ5dGVzLgorICAgICAqCisgICAgICogQHJldHVybiBhIHNlc3Npb24gb3IgbnVsbCBpZiB0aGUgc2Vzc2lvbiBjYW4ndCBiZSBjb252ZXJ0ZWQKKyAgICAgKi8KKyAgICBTU0xTZXNzaW9uIHRvU2Vzc2lvbihieXRlW10gZGF0YSwgU3RyaW5nIGhvc3QsIGludCBwb3J0KSB7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJhaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSk7CisgICAgICAgIERhdGFJbnB1dFN0cmVhbSBkYWlzID0gbmV3IERhdGFJbnB1dFN0cmVhbShiYWlzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCB0eXBlID0gZGFpcy5yZWFkSW50KCk7CisgICAgICAgICAgICBpZiAodHlwZSAhPSBPUEVOX1NTTCkgeworICAgICAgICAgICAgICAgIGxvZyhuZXcgQXNzZXJ0aW9uRXJyb3IoIlVuZXhwZWN0ZWQgdHlwZSBJRDogIiArIHR5cGUpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IGxlbmd0aCA9IGRhaXMucmVhZEludCgpOworICAgICAgICAgICAgYnl0ZVtdIHNlc3Npb25EYXRhID0gbmV3IGJ5dGVbbGVuZ3RoXTsKKyAgICAgICAgICAgIGRhaXMucmVhZEZ1bGx5KHNlc3Npb25EYXRhKTsKKworICAgICAgICAgICAgaW50IGNvdW50ID0gZGFpcy5yZWFkSW50KCk7CisgICAgICAgICAgICBYNTA5Q2VydEltcGxbXSBjZXJ0cyA9IG5ldyBYNTA5Q2VydEltcGxbY291bnRdOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CisgICAgICAgICAgICAgICAgbGVuZ3RoID0gZGFpcy5yZWFkSW50KCk7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGNlcnREYXRhID0gbmV3IGJ5dGVbbGVuZ3RoXTsKKyAgICAgICAgICAgICAgICBkYWlzLnJlYWRGdWxseShjZXJ0RGF0YSk7CisgICAgICAgICAgICAgICAgY2VydHNbaV0gPSBuZXcgWDUwOUNlcnRJbXBsKGNlcnREYXRhKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIG5ldyBPcGVuU1NMU2Vzc2lvbkltcGwoc2Vzc2lvbkRhdGEsIGhvc3QsIHBvcnQsIGNlcnRzLCB0aGlzKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgbG9nKGUpOworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgU1NMU2Vzc2lvbiBnZXRTZXNzaW9uKGJ5dGVbXSBzZXNzaW9uSWQpIHsKKyAgICAgICAgaWYgKHNlc3Npb25JZCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInNlc3Npb25JZCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgQnl0ZUFycmF5IGtleSA9IG5ldyBCeXRlQXJyYXkoc2Vzc2lvbklkKTsKKyAgICAgICAgU1NMU2Vzc2lvbiBzZXNzaW9uOworICAgICAgICBzeW5jaHJvbml6ZWQgKHNlc3Npb25zKSB7CisgICAgICAgICAgICBzZXNzaW9uID0gc2Vzc2lvbnMuZ2V0KGtleSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNlc3Npb24gIT0gbnVsbCAmJiBzZXNzaW9uLmlzVmFsaWQoKSkgeworICAgICAgICAgICAgcmV0dXJuIHNlc3Npb247CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgdm9pZCBwdXRTZXNzaW9uKFNTTFNlc3Npb24gc2Vzc2lvbikgeworICAgICAgICBieXRlW10gaWQgPSBzZXNzaW9uLmdldElkKCk7CisgICAgICAgIGlmIChpZC5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIEJ5dGVBcnJheSBrZXkgPSBuZXcgQnl0ZUFycmF5KGlkKTsKKyAgICAgICAgc3luY2hyb25pemVkIChzZXNzaW9ucykgeworICAgICAgICAgICAgc2Vzc2lvbnMucHV0KGtleSwgc2Vzc2lvbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBsb2coVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgU3lzdGVtLmxvZ1coIkVycm9yIGNvbnZlcnRpbmcgc2Vzc2lvbi4iLCB0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoc3NsQ3R4TmF0aXZlUG9pbnRlcik7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzdXBlci5maW5hbGl6ZSgpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQWxlcnRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0FsZXJ0RXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmRjMWNkOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0FsZXJ0RXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw2NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFeGNlcHRpb247CisKKy8qKgorICogVGhpcyBleGNlcHRpb24gaXMgdXNlZCB0byBzaWduYWwgdGhhdCBhIGZhdGFsIGFsZXJ0IGhhcyBvY2N1cnJlZCB3aGlsZSB3b3JraW5nIHRocm91Z2ggdGhlCisgKiBwcm90b2NvbC4KKyAqLworcHVibGljIGNsYXNzIEFsZXJ0RXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDQ0ODMyNzE3NzE2NTY4NzU4MUw7CisgICAgLy8gU1NMRXhjZXB0aW9uIHRvIGJlIHRocm93biB0byBhcHBsaWNhdGlvbiBzaWRlCisgICAgcHJpdmF0ZSBmaW5hbCBTU0xFeGNlcHRpb24gcmVhc29uOworICAgIC8vIGFsZXJ0IGRlc2NyaXB0aW9uIGNvZGUKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGUgZGVzY3JpcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIHRoZSBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXNjcmlwdGlvbiBUaGUgYWxlcnQgZGVzY3JpcHRpb24gY29kZSBmcm9tIHtAbGluayBBbGVydFByb3RvY29sfQorICAgICAqIEBwYXJhbSByZWFzb24gVGhlIFNTTEV4Y2VwdGlvbiB0byBiZSB0aHJvd24gdG8gYXBwbGljYXRpb24gc2lkZSBhZnRlciBhbGVydCBwcm9jZXNzaW5nCisgICAgICogICAgICAgICAgICAoc2VuZGluZyB0aGUgcmVjb3JkIHdpdGggYWxlcnQsIHNodXRkb3duIHdvcmssIGV0YykuCisgICAgICogQHNlZSBBbGVydFByb3RvY29sCisgICAgICovCisgICAgcHJvdGVjdGVkIEFsZXJ0RXhjZXB0aW9uKGJ5dGUgZGVzY3JpcHRpb24sIFNTTEV4Y2VwdGlvbiByZWFzb24pIHsKKyAgICAgICAgc3VwZXIocmVhc29uKTsKKyAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247CisgICAgICAgIHRoaXMuZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByZWFzb24gb2YgYWxlcnQuIFRoaXMgcmVhc29uIHNob3VsZCBiZSByZXRocm93biBhZnRlciBhbGVydCBwcm9jZXNzaW5nLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcmVhc29uIG9mIGFsZXJ0LgorICAgICAqLworICAgIHByb3RlY3RlZCBTU0xFeGNlcHRpb24gZ2V0UmVhc29uKCkgeworICAgICAgICByZXR1cm4gcmVhc29uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYWxlcnQncyBkZXNjcmlwdGlvbiBjb2RlLgorICAgICAqCisgICAgICogQHJldHVybiBhbGVydCBkZXNjcmlwdGlvbiBjb2RlIGZyb20ge0BsaW5rIEFsZXJ0UHJvdG9jb2x9CisgICAgICogQHNlZSBBbGVydFByb3RvY29sIGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHBvc3NpYmxlIHJlYXNvbiBjb2Rlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYnl0ZSBnZXREZXNjcmlwdGlvbkNvZGUoKSB7CisgICAgICAgIHJldHVybiBkZXNjcmlwdGlvbjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9BbGVydFByb3RvY29sLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9BbGVydFByb3RvY29sLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjA5N2JiMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0FsZXJ0UHJvdG9jb2wuamF2YQpAQCAtMCwwICsxLDI4MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCisvKioKKyAqIFRoaXMgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBmdW5jdGlvbmFsaXR5IG9mIEFsZXJ0IFByb3RvY29sLgorICogQ29uc3RhbnQgdmFsdWVzIGFyZSB0YWtlbiBhY2NvcmRpbmcgdG8gdGhlIFRMUyB2MSBzcGVjaWZpY2F0aW9uCisgKiAoaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI0Ni50eHQpLCBwIDcuMi4KKyAqLworcHVibGljIGNsYXNzIEFsZXJ0UHJvdG9jb2wgeworCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEFsZXJ0TGV2ZWwgY29kZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAvKioKKyAgICAgKiBEZWZpbmVzIHRoZSBzZXZlcml0eSBvZiBhbGVydCBhcyB3YXJuaW5nCisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIFdBUk5JTkcgPSAxOworICAgIC8qKgorICAgICAqIERlZmluZXMgdGhlIHNldmVyaXR5IG9mIGFsZXJ0IGFzIGZhdGFsCisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIEZBVEFMID0gMjsKKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLSBBbGVydERlc2NyaXB0aW9uIGNvZGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUgZGVzY3JpcHRpb24gY29kZSBvZiB0aGUgY2xvc2Vfbm90aWZ5IGFsZXJ0CisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIENMT1NFX05PVElGWSA9IDA7CisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUgZGVzY3JpcHRpb24gY29kZSBvZiB0aGUgdW5leHBlY3RlZF9tZXNzYWdlIGFsZXJ0CisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIFVORVhQRUNURURfTUVTU0FHRSA9IDEwOworICAgIC8qKgorICAgICAqIERlZmluZXMgdGhlIGRlc2NyaXB0aW9uIGNvZGUgb2YgdGhlIGJhZF9yZWNvcmRfbWFjIGFsZXJ0CisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIEJBRF9SRUNPUkRfTUFDID0gMjA7CisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUgZGVzY3JpcHRpb24gY29kZSBvZiB0aGUgZGVjcnlwdGlvbl9mYWlsZWQgYWxlcnQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJ5dGUgREVDUllQVElPTl9GQUlMRUQgPSAyMTsKKyAgICAvKioKKyAgICAgKiBEZWZpbmVzIHRoZSBkZXNjcmlwdGlvbiBjb2RlIG9mIHRoZSByZWNvcmRfb3ZlcmZsb3cgYWxlcnQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJ5dGUgUkVDT1JEX09WRVJGTE9XID0gMjI7CisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUgZGVzY3JpcHRpb24gY29kZSBvZiB0aGUgZGVjb21wcmVzc2lvbl9mYWlsdXJlIGFsZXJ0CisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIERFQ09NUFJFU1NJT05fRkFJTFVSRSA9IDMwOworICAgIC8qKgorICAgICAqIERlZmluZXMgdGhlIGRlc2NyaXB0aW9uIGNvZGUgb2YgdGhlIGhhbmRzaGFrZV9mYWlsdXJlIGFsZXJ0CisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIEhBTkRTSEFLRV9GQUlMVVJFID0gNDA7CisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUgZGVzY3JpcHRpb24gY29kZSBvZiB0aGUgYmFkX2NlcnRpZmljYXRlIGFsZXJ0CisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIEJBRF9DRVJUSUZJQ0FURSA9IDQyOworICAgIC8qKgorICAgICAqIERlZmluZXMgdGhlIGRlc2NyaXB0aW9uIGNvZGUgb2YgdGhlIHVuc3VwcG9ydGVkX2NlcnRpZmljYXRlIGFsZXJ0CisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIFVOU1VQUE9SVEVEX0NFUlRJRklDQVRFID0gNDM7CisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUgZGVzY3JpcHRpb24gY29kZSBvZiB0aGUgY2VydGlmaWNhdGVfcmV2b2tlZCBhbGVydAorICAgICAqLworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgYnl0ZSBDRVJUSUZJQ0FURV9SRVZPS0VEID0gNDQ7CisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUgZGVzY3JpcHRpb24gY29kZSBvZiB0aGUgY2VydGlmaWNhdGVfZXhwaXJlZCBhbGVydAorICAgICAqLworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgYnl0ZSBDRVJUSUZJQ0FURV9FWFBJUkVEID0gNDU7CisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUgZGVzY3JpcHRpb24gY29kZSBvZiB0aGUgY2VydGlmaWNhdGVfdW5rbm93biBhbGVydAorICAgICAqLworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgYnl0ZSBDRVJUSUZJQ0FURV9VTktOT1dOID0gNDY7CisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUgZGVzY3JpcHRpb24gY29kZSBvZiB0aGUgaWxsZWdhbF9wYXJhbWV0ZXIgYWxlcnQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJ5dGUgSUxMRUdBTF9QQVJBTUVURVIgPSA0NzsKKyAgICAvKioKKyAgICAgKiBEZWZpbmVzIHRoZSBkZXNjcmlwdGlvbiBjb2RlIG9mIHRoZSB1bmtub3duX2NhIGFsZXJ0CisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIFVOS05PV05fQ0EgPSA0ODsKKyAgICAvKioKKyAgICAgKiBEZWZpbmVzIHRoZSBkZXNjcmlwdGlvbiBjb2RlIG9mIHRoZSBhY2Nlc3NfZGVuaWVkIGFsZXJ0CisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIEFDQ0VTU19ERU5JRUQgPSA0OTsKKyAgICAvKioKKyAgICAgKiBEZWZpbmVzIHRoZSBkZXNjcmlwdGlvbiBjb2RlIG9mIHRoZSBkZWNvZGVfZXJyb3IgYWxlcnQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJ5dGUgREVDT0RFX0VSUk9SID0gNTA7CisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUgZGVzY3JpcHRpb24gY29kZSBvZiB0aGUgZGVjcnlwdF9lcnJvciBhbGVydAorICAgICAqLworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgYnl0ZSBERUNSWVBUX0VSUk9SID0gNTE7CisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUgZGVzY3JpcHRpb24gY29kZSBvZiB0aGUgZXhwb3J0X3Jlc3RyaWN0aW9uIGFsZXJ0CisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIEVYUE9SVF9SRVNUUklDVElPTiA9IDYwOworICAgIC8qKgorICAgICAqIERlZmluZXMgdGhlIGRlc2NyaXB0aW9uIGNvZGUgb2YgdGhlIHByb3RvY29sX3ZlcnNpb24gYWxlcnQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJ5dGUgUFJPVE9DT0xfVkVSU0lPTiA9IDcwOworICAgIC8qKgorICAgICAqIERlZmluZXMgdGhlIGRlc2NyaXB0aW9uIGNvZGUgb2YgdGhlIGluc3VmZmljaWVudF9zZWN1cml0eSBhbGVydAorICAgICAqLworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgYnl0ZSBJTlNVRkZJQ0lFTlRfU0VDVVJJVFkgPSA3MTsKKyAgICAvKioKKyAgICAgKiBEZWZpbmVzIHRoZSBkZXNjcmlwdGlvbiBjb2RlIG9mIHRoZSBpbnRlcm5hbF9lcnJvciBhbGVydAorICAgICAqLworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgYnl0ZSBJTlRFUk5BTF9FUlJPUiA9IDgwOworICAgIC8qKgorICAgICAqIERlZmluZXMgdGhlIGRlc2NyaXB0aW9uIGNvZGUgb2YgdGhlIHVzZXJfY2FuY2VsZWQgYWxlcnQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJ5dGUgVVNFUl9DQU5DRUxFRCA9IDkwOworICAgIC8qKgorICAgICAqIERlZmluZXMgdGhlIGRlc2NyaXB0aW9uIGNvZGUgb2YgdGhlIG5vX3JlbmVnb3RpYXRpb24gYWxlcnQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJ5dGUgTk9fUkVORUdPVElBVElPTiA9IDEwMDsKKyAgICAvLyBob2xkcyBsZXZlbCBhbmQgZGVzY3JpcHRpb24gY29kZXMKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBhbGVydCA9IG5ldyBieXRlWzJdOworICAgIC8vIHJlY29yZCBwcm90b2NvbCB0byBiZSB1c2VkIHRvIHdyYXAgdGhlIGFsZXJ0cworICAgIHByaXZhdGUgU1NMUmVjb3JkUHJvdG9jb2wgcmVjb3JkUHJvdG9jb2w7CisKKyAgICBwcml2YXRlIExvZ2dlci5TdHJlYW0gbG9nZ2VyID0gTG9nZ2VyLmdldFN0cmVhbSgiYWxlcnQiKTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIGluc3RhbmNlIG9mIEFsZXJ0UHJvdG9jb2wuCisgICAgICogTm90ZSB0aGF0IGNsYXNzIGlzIG5vdCByZWFkeSB0byB3b3JrIHdpdGhvdXQgcHJvdmlkaW5nIG9mCisgICAgICogcmVjb3JkIHByb3RvY29sCisgICAgICogQHNlZSAjc2V0UmVjb3JkUHJvdG9jb2wKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQWxlcnRQcm90b2NvbCgpIHt9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSByZWNvcmQgcHJvdG9jb2wgdG8gYmUgdXNlZCBieSB0aGlzIGFsbGVydCBwcm90b2NvbC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRSZWNvcmRQcm90b2NvbChTU0xSZWNvcmRQcm90b2NvbCByZWNvcmRQcm90b2NvbCkgeworICAgICAgICB0aGlzLnJlY29yZFByb3RvY29sID0gcmVjb3JkUHJvdG9jb2w7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwb3J0cyBhbiBhbGVydCB0byBiZSBzZW50L3JlY2VpdmVkIGJ5IHRyYW5zcG9ydC4KKyAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c3VhbGx5IGNhbGxlZCBkdXJpbmcgcHJvY2Vzc2luZworICAgICAqIG9mIHRoZSBpbmNvbWUgVFNMIHJlY29yZDogaWYgaXQgY29udGFpbnMgYWxlcnQgbWVzc2FnZSBmcm9tIGFub3RoZXIKKyAgICAgKiBwZWVyLCBvciBpZiB3YXJuaW5nIGFsZXJ0IG9jY3VyZWQgZHVyaW5nIHRoZSBwcm9jZXNzaW5nIG9mIHRoZQorICAgICAqIG1lc3NhZ2UgYW5kIHRoaXMgd2FybmluZyBzaG91bGQgYmUgc2VudCB0byBhbm90aGVyIHBlZXIuCisgICAgICogQHBhcmFtICAgbGV2ZWw6ICBhbGVydCBsZXZlbCBjb2RlCisgICAgICogQHBhcmFtICAgZGVzY3JpcHRpb246IGFsZXJ0IGRlc2NyaXB0aW9uIGNvZGUKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgYWxlcnQoYnl0ZSBsZXZlbCwgYnl0ZSBkZXNjcmlwdGlvbikgeworICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJBbGVydC5hbGVydDogIitsZXZlbCsiICIrZGVzY3JpcHRpb24pOworICAgICAgICB9CisgICAgICAgIHRoaXMuYWxlcnRbMF0gPSBsZXZlbDsKKyAgICAgICAgdGhpcy5hbGVydFsxXSA9IGRlc2NyaXB0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRlc2NyaXB0aW9uIGNvZGUgb2YgYWxlcnQgb3IgLTEwMCBpZiB0aGVyZQorICAgICAqIGlzIG5vIGFsZXJ0LgorICAgICAqLworICAgIHByb3RlY3RlZCBieXRlIGdldERlc2NyaXB0aW9uQ29kZSgpIHsKKyAgICAgICAgcmV0dXJuIChhbGVydFswXSAhPSAwKSA/IGFsZXJ0WzFdIDogLTEwMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldHMgdGhlIHByb3RvY29sIHRvIGJlIGluICJubyBhbGVydCIgc3RhdGUuCisgICAgICogVGhpcyBtZXRob2Qgc2hvdWQgYmUgY2FsbGVkIGFmdGVyIHByb2Nlc3Npbmcgb2YgdGhlIHJlcG9ydGVkIGFsZXJ0LgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFByb2Nlc3NlZCgpIHsKKyAgICAgICAgLy8gZnJlZSB0aGUgaW5mbyBhYm91dCBhbGVydAorICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJBbGVydC5zZXRQcm9jZXNzZWQiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmFsZXJ0WzBdID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgYW55IGFsZXJ0IGhhcyBvY2N1cmVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGhhc0FsZXJ0KCkgeworICAgICAgICByZXR1cm4gKGFsZXJ0WzBdICE9IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiBvY2N1cmVkIGFsZXJ0IGlzIGZhdGFsIGFsZXJ0LgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGlzRmF0YWxBbGVydCgpIHsKKyAgICAgICAgcmV0dXJuIChhbGVydFswXSA9PSAyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2Ygb2NjdXJlZCBhbGVydC4KKyAgICAgKiBJZiBubyBhbGVydCBoYXMgb2NjdXJlZCBudWxsIGlzIHJldHVybmVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgZ2V0QWxlcnREZXNjcmlwdGlvbigpIHsKKyAgICAgICAgc3dpdGNoIChhbGVydFsxXSkgeworICAgICAgICBjYXNlIENMT1NFX05PVElGWToKKyAgICAgICAgICAgIHJldHVybiAiY2xvc2Vfbm90aWZ5IjsKKyAgICAgICAgY2FzZSBVTkVYUEVDVEVEX01FU1NBR0U6CisgICAgICAgICAgICByZXR1cm4gInVuZXhwZWN0ZWRfbWVzc2FnZSI7CisgICAgICAgIGNhc2UgQkFEX1JFQ09SRF9NQUM6CisgICAgICAgICAgICByZXR1cm4gImJhZF9yZWNvcmRfbWFjIjsKKyAgICAgICAgY2FzZSBERUNSWVBUSU9OX0ZBSUxFRDoKKyAgICAgICAgICAgIHJldHVybiAiZGVjcnlwdGlvbl9mYWlsZWQiOworICAgICAgICBjYXNlIFJFQ09SRF9PVkVSRkxPVzoKKyAgICAgICAgICAgIHJldHVybiAicmVjb3JkX292ZXJmbG93IjsKKyAgICAgICAgY2FzZSBERUNPTVBSRVNTSU9OX0ZBSUxVUkU6CisgICAgICAgICAgICByZXR1cm4gImRlY29tcHJlc3Npb25fZmFpbHVyZSI7CisgICAgICAgIGNhc2UgSEFORFNIQUtFX0ZBSUxVUkU6CisgICAgICAgICAgICByZXR1cm4gImhhbmRzaGFrZV9mYWlsdXJlIjsKKyAgICAgICAgY2FzZSBCQURfQ0VSVElGSUNBVEU6CisgICAgICAgICAgICByZXR1cm4gImJhZF9jZXJ0aWZpY2F0ZSI7CisgICAgICAgIGNhc2UgVU5TVVBQT1JURURfQ0VSVElGSUNBVEU6CisgICAgICAgICAgICByZXR1cm4gInVuc3VwcG9ydGVkX2NlcnRpZmljYXRlIjsKKyAgICAgICAgY2FzZSBDRVJUSUZJQ0FURV9SRVZPS0VEOgorICAgICAgICAgICAgcmV0dXJuICJjZXJ0aWZpY2F0ZV9yZXZva2VkIjsKKyAgICAgICAgY2FzZSBDRVJUSUZJQ0FURV9FWFBJUkVEOgorICAgICAgICAgICAgcmV0dXJuICJjZXJ0aWZpY2F0ZV9leHBpcmVkIjsKKyAgICAgICAgY2FzZSBDRVJUSUZJQ0FURV9VTktOT1dOOgorICAgICAgICAgICAgcmV0dXJuICJjZXJ0aWZpY2F0ZV91bmtub3duIjsKKyAgICAgICAgY2FzZSBJTExFR0FMX1BBUkFNRVRFUjoKKyAgICAgICAgICAgIHJldHVybiAiaWxsZWdhbF9wYXJhbWV0ZXIiOworICAgICAgICBjYXNlIFVOS05PV05fQ0E6CisgICAgICAgICAgICByZXR1cm4gInVua25vd25fY2EiOworICAgICAgICBjYXNlIEFDQ0VTU19ERU5JRUQ6CisgICAgICAgICAgICByZXR1cm4gImFjY2Vzc19kZW5pZWQiOworICAgICAgICBjYXNlIERFQ09ERV9FUlJPUjoKKyAgICAgICAgICAgIHJldHVybiAiZGVjb2RlX2Vycm9yIjsKKyAgICAgICAgY2FzZSBERUNSWVBUX0VSUk9SOgorICAgICAgICAgICAgcmV0dXJuICJkZWNyeXB0X2Vycm9yIjsKKyAgICAgICAgY2FzZSBFWFBPUlRfUkVTVFJJQ1RJT046CisgICAgICAgICAgICByZXR1cm4gImV4cG9ydF9yZXN0cmljdGlvbiI7CisgICAgICAgIGNhc2UgUFJPVE9DT0xfVkVSU0lPTjoKKyAgICAgICAgICAgIHJldHVybiAicHJvdG9jb2xfdmVyc2lvbiI7CisgICAgICAgIGNhc2UgSU5TVUZGSUNJRU5UX1NFQ1VSSVRZOgorICAgICAgICAgICAgcmV0dXJuICJpbnN1ZmZpY2llbnRfc2VjdXJpdHkiOworICAgICAgICBjYXNlIElOVEVSTkFMX0VSUk9SOgorICAgICAgICAgICAgcmV0dXJuICJpbnRlcm5hbF9lcnJvciI7CisgICAgICAgIGNhc2UgVVNFUl9DQU5DRUxFRDoKKyAgICAgICAgICAgIHJldHVybiAidXNlcl9jYW5jZWxlZCI7CisgICAgICAgIGNhc2UgTk9fUkVORUdPVElBVElPTjoKKyAgICAgICAgICAgIHJldHVybiAibm9fcmVuZWdvdGlhdGlvbiI7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcmVjb3JkIHdpdGggcmVwb3J0ZWQgYWxlcnQgbWVzc2FnZS4KKyAgICAgKiBUaGUgcmV0dXJuZWQgYXJyYXkgb2YgYnl0ZXMgaXMgcmVhZHkgdG8gYmUgc2VudCB0byBhbm90aGVyIHBlZXIuCisgICAgICogTm90ZSwgdGhhdCB0aGlzIG1ldGhvZCBkb2VzIG5vdCBhdXRvbWF0aWNhbGx5IHNldCB0aGUgc3RhdGUgb2YgYWxlcnQKKyAgICAgKiBwcm90b2NvbCBpbiAibm8gYWxlcnQiIHN0YXRlLCBzbyBhZnRlciB3cmFwcGluZyB0aGUgbWV0aG9kIHNldFByb2Nlc3NlZAorICAgICAqIHNob3VsZCBiZSBjYWxsZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJ5dGVbXSB3cmFwKCkgeworICAgICAgICBieXRlW10gcmVzID0gcmVjb3JkUHJvdG9jb2wud3JhcChDb250ZW50VHlwZS5BTEVSVCwgYWxlcnQsIDAsIDIpOworICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNodXRkb3duIHRoZSBwcm90b2NvbC4gSXQgd2lsbCBiZSBpbXBvc3NpYmxlIHRvIHVzZSB0aGUgaW5zdGFuY2UKKyAgICAgKiBhZnRlciB0aGUgY2FsbGluZyBvZiB0aGlzIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzaHV0ZG93bigpIHsKKyAgICAgICAgYWxlcnRbMF0gPSAwOworICAgICAgICBhbGVydFsxXSA9IDA7CisgICAgICAgIHJlY29yZFByb3RvY29sID0gbnVsbDsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0FwcGVuZGFibGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0FwcGVuZGFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wOThiNjBjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQXBwZW5kYWJsZS5qYXZhCkBAIC0wLDAgKzEsMzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworLyoqCisgKiBUaGlzIGludGVyZmFjZSByZXByZXNlbnRzIHRoZSBhYmlsaXR5IG9mIHRoZSBpbnB1dCBzdHJlYW0gcmVsYXRlZCBjbGFzc2VzIHRvIHByb3ZpZGUgYWRkaXRpb25hbAorICogZGF0YSB0byBiZSByZWFkLgorICovCitwdWJsaWMgaW50ZXJmYWNlIEFwcGVuZGFibGUgeworCisgICAgLyoqCisgICAgICogUHJvdmlkZXMgdGhlIGFkZGl0aW9uYWwgZGF0YSB0byBiZSByZWFkLgorICAgICAqCisgICAgICogQHBhcmFtIHNyYyB0aGUgc291cmNlIGRhdGEgdG8gYmUgYXBwZW5kZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYXBwZW5kKGJ5dGVbXSBzcmMpOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9CeXRlQXJyYXkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0J5dGVBcnJheS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhMDAwYzUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9CeXRlQXJyYXkuamF2YQpAQCAtMCwwICsxLDQ0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBCeXRlIGFycmF5IHdyYXBwZXIgZm9yIGhhc2h0YWJsZSB1c2UuIEltcGxlbWVudHMgZXF1YWxzKCkgYW5kIGhhc2hDb2RlKCkuCisgKi8KK2ZpbmFsIGNsYXNzIEJ5dGVBcnJheSB7CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gYnl0ZXM7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgaGFzaENvZGU7CisKKyAgICBCeXRlQXJyYXkoYnl0ZVtdIGJ5dGVzKSB7CisgICAgICAgIHRoaXMuYnl0ZXMgPSBieXRlczsKKyAgICAgICAgdGhpcy5oYXNoQ29kZSA9IEFycmF5cy5oYXNoQ29kZShieXRlcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiBoYXNoQ29kZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBCeXRlQXJyYXkpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgQnl0ZUFycmF5IGxocyA9IChCeXRlQXJyYXkpIG87CisgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKGJ5dGVzLCBsaHMuYnl0ZXMpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0NlcnRpZmljYXRlTWVzc2FnZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQ2VydGlmaWNhdGVNZXNzYWdlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWJjMjhhMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0NlcnRpZmljYXRlTWVzc2FnZS5qYXZhCkBAIC0wLDAgKzEsMTY5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CisKKy8qKgorICogUmVwcmVzZW50cyBzZXJ2ZXIvY2xpZW50IGNlcnRpZmljYXRlIG1lc3NhZ2UKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI0Ni50eHQiPlRMUworICogMS4wIHNwZWMuLCA3LjQuMi4gU2VydmVyIGNlcnRpZmljYXRlOyA3LjQuNi4gQ2xpZW50IGNlcnRpZmljYXRlPC9hPgorICoKKyAqLworcHVibGljIGNsYXNzIENlcnRpZmljYXRlTWVzc2FnZSBleHRlbmRzIE1lc3NhZ2UgeworCisgICAgLyoqCisgICAgICogQ2VydGlmaWNhdGVzCisgICAgICovCisgICAgWDUwOUNlcnRpZmljYXRlW10gY2VydHM7CisKKyAgICAvKioKKyAgICAgKiBDZXJ0aWZpY2F0ZXMgaW4gZW5jb2RlZCBmb3JtCisgICAgICovCisgICAgYnl0ZVtdW10gZW5jb2RlZF9jZXJ0czsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgaW5ib3VuZCBtZXNzYWdlCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZU1lc3NhZ2UoSGFuZHNoYWtlSU9EYXRhU3RyZWFtIGluLCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgbCA9IGluLnJlYWRVaW50MjQoKTsgLy8gdG90YWxfbGVuZ3RoCisgICAgICAgIGlmIChsID09IDApIHsgIC8vIG1lc3NhZ2UgY29udGFpcyBubyBjZXJ0aWZpY2F0ZXMKKyAgICAgICAgICAgIGlmIChsZW5ndGggIT0gMykgeyAvLyBubyBtb3JlIGJ5dGVzIGFmdGVyIHRvdGFsX2xlbmd0aAorICAgICAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5ERUNPREVfRVJST1IsCisgICAgICAgICAgICAgICAgICAgICAgICAiREVDT0RFIEVSUk9SOiBpbmNvcnJlY3QgQ2VydGlmaWNhdGVNZXNzYWdlIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjZXJ0cyA9IG5ldyBYNTA5Q2VydGlmaWNhdGVbMF07CisgICAgICAgICAgICBlbmNvZGVkX2NlcnRzID0gbmV3IGJ5dGVbMF1bMF07CisgICAgICAgICAgICB0aGlzLmxlbmd0aCA9IDM7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlg1MDkiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLklOVEVSTkFMX0VSUk9SLCAiSU5URVJOQUwgRVJST1IiLCBlKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBBcnJheUxpc3Q8WDUwOUNlcnRpZmljYXRlPiBjZXJ0c0xpc3QgPSBuZXcgQXJyYXlMaXN0PFg1MDlDZXJ0aWZpY2F0ZT4oKTsKKyAgICAgICAgaW50IHNpemUgPSAwOworICAgICAgICBpbnQgZW5jX3NpemUgPSAwOworICAgICAgICB3aGlsZSAobCA+IDApIHsKKyAgICAgICAgICAgIHNpemUgPSBpbi5yZWFkVWludDI0KCk7CisgICAgICAgICAgICBsIC09IDM7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNlcnRzTGlzdC5hZGQoKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShpbikpOworICAgICAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5ERUNPREVfRVJST1IsICJERUNPREUgRVJST1IiLCBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGwgLT0gc2l6ZTsKKyAgICAgICAgICAgIGVuY19zaXplICs9IHNpemU7CisgICAgICAgIH0KKyAgICAgICAgY2VydHMgPSBjZXJ0c0xpc3QudG9BcnJheShuZXcgWDUwOUNlcnRpZmljYXRlW2NlcnRzTGlzdC5zaXplKCldKTsKKyAgICAgICAgdGhpcy5sZW5ndGggPSAzICsgMyAqIGNlcnRzLmxlbmd0aCArIGVuY19zaXplOworICAgICAgICBpZiAodGhpcy5sZW5ndGggIT0gbGVuZ3RoKSB7CisgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuREVDT0RFX0VSUk9SLCAiREVDT0RFIEVSUk9SOiBpbmNvcnJlY3QgQ2VydGlmaWNhdGVNZXNzYWdlIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIG91dGJvdW5kIG1lc3NhZ2UKKyAgICAgKgorICAgICAqIEBwYXJhbSBjZXJ0cworICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZU1lc3NhZ2UoWDUwOUNlcnRpZmljYXRlW10gY2VydHMpIHsKKyAgICAgICAgaWYgKGNlcnRzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMuY2VydHMgPSBuZXcgWDUwOUNlcnRpZmljYXRlWzBdOworICAgICAgICAgICAgZW5jb2RlZF9jZXJ0cyA9IG5ldyBieXRlWzBdWzBdOworICAgICAgICAgICAgbGVuZ3RoID0gMzsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmNlcnRzID0gY2VydHM7CisgICAgICAgIGlmIChlbmNvZGVkX2NlcnRzID09IG51bGwpIHsKKyAgICAgICAgICAgIGVuY29kZWRfY2VydHMgPSBuZXcgYnl0ZVtjZXJ0cy5sZW5ndGhdW107CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNlcnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZW5jb2RlZF9jZXJ0c1tpXSA9IGNlcnRzW2ldLmdldEVuY29kZWQoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLklOVEVSTkFMX0VSUk9SLCAiSU5URVJOQUwgRVJST1IiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBsZW5ndGggPSAzICsgMyAqIGVuY29kZWRfY2VydHMubGVuZ3RoOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVuY29kZWRfY2VydHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGxlbmd0aCArPSBlbmNvZGVkX2NlcnRzW2ldLmxlbmd0aDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmRzIG1lc3NhZ2UKKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZW5kKEhhbmRzaGFrZUlPRGF0YVN0cmVhbSBvdXQpIHsKKworICAgICAgICBpbnQgdG90YWxfbGVuZ3RoID0gMDsKKyAgICAgICAgaWYgKGVuY29kZWRfY2VydHMgPT0gbnVsbCkgeworICAgICAgICAgICAgZW5jb2RlZF9jZXJ0cyA9IG5ldyBieXRlW2NlcnRzLmxlbmd0aF1bXTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2VydHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBlbmNvZGVkX2NlcnRzW2ldID0gY2VydHNbaV0uZ2V0RW5jb2RlZCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuSU5URVJOQUxfRVJST1IsICJJTlRFUk5BTCBFUlJPUiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRvdGFsX2xlbmd0aCA9IDMgKiBlbmNvZGVkX2NlcnRzLmxlbmd0aDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbmNvZGVkX2NlcnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0b3RhbF9sZW5ndGggKz0gZW5jb2RlZF9jZXJ0c1tpXS5sZW5ndGg7CisgICAgICAgIH0KKyAgICAgICAgb3V0LndyaXRlVWludDI0KHRvdGFsX2xlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZW5jb2RlZF9jZXJ0cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgb3V0LndyaXRlVWludDI0KGVuY29kZWRfY2VydHNbaV0ubGVuZ3RoKTsKKyAgICAgICAgICAgIG91dC53cml0ZShlbmNvZGVkX2NlcnRzW2ldKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRBdXRoVHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIGNlcnRzWzBdLmdldFB1YmxpY0tleSgpLmdldEFsZ29yaXRobSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgbWVzc2FnZSB0eXBlCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRUeXBlKCkgeworICAgICAgICByZXR1cm4gSGFuZHNoYWtlLkNFUlRJRklDQVRFOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQ2VydGlmaWNhdGVSZXF1ZXN0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9DZXJ0aWZpY2F0ZVJlcXVlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mM2JlNDRjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQ2VydGlmaWNhdGVSZXF1ZXN0LmphdmEKQEAgLTAsMCArMSwxNjEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsOworaW1wb3J0IGxpYmNvcmUuaW8uU3RyZWFtczsKKworLyoqCisgKgorICogUmVwcmVzZW50cyBjZXJ0aWZpY2F0ZSByZXF1ZXN0IG1lc3NhZ2UKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI0Ni50eHQiPlRMUyAxLjAgc3BlYy4sIDcuNC40LgorICogQ2VydGlmaWNhdGUgcmVxdWVzdDwvYT4KKyAqLworcHVibGljIGNsYXNzIENlcnRpZmljYXRlUmVxdWVzdCBleHRlbmRzIE1lc3NhZ2UgeworCisgICAgLyoqCisgICAgICogUmVxdWVzdGVkIGNlcnRpZmljYXRlIHR5cGVzCisgICAgICovCisgICAgZmluYWwgYnl0ZVtdIGNlcnRpZmljYXRlX3R5cGVzOworCisgICAgLyoqCisgICAgICogQ2VydGlmaWNhdGUgYXV0aG9yaXRpZXMKKyAgICAgKi8KKyAgICBmaW5hbCBYNTAwUHJpbmNpcGFsW10gY2VydGlmaWNhdGVfYXV0aG9yaXRpZXM7CisKKyAgICAvKioKKyAgICAgKiBSZXF1ZXN0ZWQgY2VydGlmaWNhdGUgdHlwZXMgYXMgU3RyaW5ncworICAgICAqICgiUlNBIiwgIkRTQSIsICJESF9SU0EiIG9yICJESF9EU0EiKQorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nW10gdHlwZXM7CisKKyAgICAvKioKKyAgICAgKiBFbmNvZGVkIGZvcm0gb2YgY2VydGlmaWNhdGUgYXV0aG9yaXRpZXMKKyAgICAgKi8KKyAgICBwcml2YXRlIGJ5dGVbXVtdIGVuY29kZWRfcHJpbmNpcGFsczsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgb3V0Ym91bmQgbWVzc2FnZQorICAgICAqCisgICAgICogQHBhcmFtIGNlcnRpZmljYXRlX3R5cGVzCisgICAgICogQHBhcmFtIGFjY2VwdGVkIC0gYXJyYXkgb2YgY2VydGlmaWNhdGUgYXV0aG9yaXR5IGNlcnRpZmljYXRlcworICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZVJlcXVlc3QoYnl0ZVtdIGNlcnRpZmljYXRlX3R5cGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlW10gYWNjZXB0ZWQpIHsKKworICAgICAgICBpZiAoYWNjZXB0ZWQgPT0gbnVsbCkgeworICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLklOVEVSTkFMX0VSUk9SLAorICAgICAgICAgICAgICAgICAgICAiQ2VydGlmaWNhdGVSZXF1ZXN0OiBhcnJheSBvZiBjZXJ0aWZpY2F0ZSBhdXRob3JpdHkgY2VydGlmaWNhdGVzIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmNlcnRpZmljYXRlX3R5cGVzID0gY2VydGlmaWNhdGVfdHlwZXM7CisKKyAgICAgICAgaW50IHRvdGFsUHJpbmNpcGFsc0xlbmd0aCA9IDA7CisgICAgICAgIGNlcnRpZmljYXRlX2F1dGhvcml0aWVzID0gbmV3IFg1MDBQcmluY2lwYWxbYWNjZXB0ZWQubGVuZ3RoXTsKKyAgICAgICAgZW5jb2RlZF9wcmluY2lwYWxzID0gbmV3IGJ5dGVbYWNjZXB0ZWQubGVuZ3RoXVtdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFjY2VwdGVkLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjZXJ0aWZpY2F0ZV9hdXRob3JpdGllc1tpXSA9IGFjY2VwdGVkW2ldLmdldElzc3Vlclg1MDBQcmluY2lwYWwoKTsKKyAgICAgICAgICAgIGVuY29kZWRfcHJpbmNpcGFsc1tpXSA9IGNlcnRpZmljYXRlX2F1dGhvcml0aWVzW2ldLmdldEVuY29kZWQoKTsKKyAgICAgICAgICAgIHRvdGFsUHJpbmNpcGFsc0xlbmd0aCArPSBlbmNvZGVkX3ByaW5jaXBhbHNbaV0ubGVuZ3RoICsgMjsKKyAgICAgICAgfQorCisgICAgICAgIGxlbmd0aCA9IDMgKyBjZXJ0aWZpY2F0ZV90eXBlcy5sZW5ndGggKyB0b3RhbFByaW5jaXBhbHNMZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBpbmJvdW5kIG1lc3NhZ2UKKyAgICAgKgorICAgICAqIEBwYXJhbSBpbgorICAgICAqIEBwYXJhbSBsZW5ndGgKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlUmVxdWVzdChIYW5kc2hha2VJT0RhdGFTdHJlYW0gaW4sIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBzaXplID0gaW4ucmVhZFVpbnQ4KCk7CisgICAgICAgIGNlcnRpZmljYXRlX3R5cGVzID0gbmV3IGJ5dGVbc2l6ZV07CisgICAgICAgIFN0cmVhbXMucmVhZEZ1bGx5KGluLCBjZXJ0aWZpY2F0ZV90eXBlcyk7CisgICAgICAgIHNpemUgPSBpbi5yZWFkVWludDE2KCk7CisgICAgICAgIGludCB0b3RhbFByaW5jaXBhbHNMZW5ndGggPSAwOworICAgICAgICBpbnQgcHJpbmNpcGFsTGVuZ3RoID0gMDsKKyAgICAgICAgQXJyYXlMaXN0PFg1MDBQcmluY2lwYWw+IHByaW5jaXBhbHMgPSBuZXcgQXJyYXlMaXN0PFg1MDBQcmluY2lwYWw+KCk7CisgICAgICAgIHdoaWxlICh0b3RhbFByaW5jaXBhbHNMZW5ndGggPCBzaXplKSB7CisgICAgICAgICAgICBwcmluY2lwYWxMZW5ndGggPSBpbi5yZWFkVWludDE2KCk7IC8vIGVuY29kZWQgWDUwMFByaW5jaXBhbCBzaXplCisgICAgICAgICAgICBwcmluY2lwYWxzLmFkZChuZXcgWDUwMFByaW5jaXBhbChpbikpOworICAgICAgICAgICAgdG90YWxQcmluY2lwYWxzTGVuZ3RoICs9IDI7CisgICAgICAgICAgICB0b3RhbFByaW5jaXBhbHNMZW5ndGggKz0gcHJpbmNpcGFsTGVuZ3RoOworICAgICAgICB9CisgICAgICAgIGNlcnRpZmljYXRlX2F1dGhvcml0aWVzID0gcHJpbmNpcGFscy50b0FycmF5KG5ldyBYNTAwUHJpbmNpcGFsW3ByaW5jaXBhbHMuc2l6ZSgpXSk7CisgICAgICAgIHRoaXMubGVuZ3RoID0gMyArIGNlcnRpZmljYXRlX3R5cGVzLmxlbmd0aCArIHRvdGFsUHJpbmNpcGFsc0xlbmd0aDsKKyAgICAgICAgaWYgKHRoaXMubGVuZ3RoICE9IGxlbmd0aCkgeworICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLkRFQ09ERV9FUlJPUiwgIkRFQ09ERSBFUlJPUjogaW5jb3JyZWN0IENlcnRpZmljYXRlUmVxdWVzdCIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZHMgbWVzc2FnZQorICAgICAqCisgICAgICogQHBhcmFtIG91dAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNlbmQoSGFuZHNoYWtlSU9EYXRhU3RyZWFtIG91dCkgeworCisgICAgICAgIG91dC53cml0ZVVpbnQ4KGNlcnRpZmljYXRlX3R5cGVzLmxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2VydGlmaWNhdGVfdHlwZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG91dC53cml0ZShjZXJ0aWZpY2F0ZV90eXBlc1tpXSk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGF1dGhvcml0aWVzTGVuZ3RoID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjZXJ0aWZpY2F0ZV9hdXRob3JpdGllcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXV0aG9yaXRpZXNMZW5ndGggKz0gZW5jb2RlZF9wcmluY2lwYWxzW2ldLmxlbmd0aCArMjsKKyAgICAgICAgfQorICAgICAgICBvdXQud3JpdGVVaW50MTYoYXV0aG9yaXRpZXNMZW5ndGgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNlcnRpZmljYXRlX2F1dGhvcml0aWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBvdXQud3JpdGVVaW50MTYoZW5jb2RlZF9wcmluY2lwYWxzW2ldLmxlbmd0aCk7CisgICAgICAgICAgICBvdXQud3JpdGUoZW5jb2RlZF9wcmluY2lwYWxzW2ldKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgbWVzc2FnZSB0eXBlCisgICAgICoKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRUeXBlKCkgeworICAgICAgICByZXR1cm4gSGFuZHNoYWtlLkNFUlRJRklDQVRFX1JFUVVFU1Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyByZXF1ZXN0ZWQgY2VydGlmaWNhdGUgdHlwZXMgYXMgYXJyYXkgb2Ygc3RyaW5ncworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRUeXBlc0FzU3RyaW5nKCkgeworICAgICAgICBpZiAodHlwZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgdHlwZXMgPSBuZXcgU3RyaW5nW2NlcnRpZmljYXRlX3R5cGVzLmxlbmd0aF07CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHR5cGUgPSBDaXBoZXJTdWl0ZS5nZXRDbGllbnRLZXlUeXBlKGNlcnRpZmljYXRlX3R5cGVzW2ldKTsKKyAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5ERUNPREVfRVJST1IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRFQ09ERSBFUlJPUjogaW5jb3JyZWN0IENlcnRpZmljYXRlUmVxdWVzdCIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0eXBlc1tpXSA9IHR5cGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHR5cGVzOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQ2VydGlmaWNhdGVWZXJpZnkuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0NlcnRpZmljYXRlVmVyaWZ5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWE0NDAyZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0NlcnRpZmljYXRlVmVyaWZ5LmphdmEKQEAgLTAsMCArMSw5MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBSZXByZXNlbnRzIGNlcnRpZmljYXRlIHZlcmlmeSBtZXNzYWdlCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyNDYudHh0Ij5UTFMgMS4wIHNwZWMuLCA3LjQuOC4KKyAqIENlcnRpZmljYXRlIHZlcmlmeTwvYT4KKyAqLworcHVibGljIGNsYXNzIENlcnRpZmljYXRlVmVyaWZ5IGV4dGVuZHMgTWVzc2FnZSB7CisKKyAgICAvKioKKyAgICAgKiBTaWduYXR1cmUKKyAgICAgKi8KKyAgICBieXRlW10gc2lnbmVkSGFzaDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgb3V0Ym91bmQgbWVzc2FnZQorICAgICAqCisgICAgICogQHBhcmFtIGhhc2gKKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVWZXJpZnkoYnl0ZVtdIGhhc2gpIHsKKyAgICAgICAgaWYgKGhhc2ggPT0gbnVsbCB8fCBoYXNoLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuSU5URVJOQUxfRVJST1IsCisgICAgICAgICAgICAgICAgICAgICJJTlRFUk5BTCBFUlJPUjogaW5jb3JyZWN0IGNlcnRpZmljYXRlIHZlcmlmeSBoYXNoIik7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zaWduZWRIYXNoID0gaGFzaDsKKyAgICAgICAgbGVuZ3RoID0gaGFzaC5sZW5ndGggKyAyOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgaW5ib3VuZCBtZXNzYWdlCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZVZlcmlmeShIYW5kc2hha2VJT0RhdGFTdHJlYW0gaW4sIGludCBsZW5ndGgpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAobGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5ERUNPREVfRVJST1IsCisgICAgICAgICAgICAgICAgICAgICJERUNPREUgRVJST1I6IGluY29ycmVjdCBDZXJ0aWZpY2F0ZVZlcmlmeSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKGluLnJlYWRVaW50MTYoKSAhPSBsZW5ndGggLSAyKSB7CisgICAgICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLkRFQ09ERV9FUlJPUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJERUNPREUgRVJST1I6IGluY29ycmVjdCBDZXJ0aWZpY2F0ZVZlcmlmeSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2lnbmVkSGFzaCA9IGluLnJlYWQobGVuZ3RoIC0yKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kcyBtZXNzYWdlCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2VuZChIYW5kc2hha2VJT0RhdGFTdHJlYW0gb3V0KSB7CisgICAgICAgIGlmIChzaWduZWRIYXNoLmxlbmd0aCAhPSAwKSB7CisgICAgICAgICAgICBvdXQud3JpdGVVaW50MTYoc2lnbmVkSGFzaC5sZW5ndGgpOworICAgICAgICAgICAgb3V0LndyaXRlKHNpZ25lZEhhc2gpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBtZXNzYWdlIHR5cGUKKyAgICAgKgorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFR5cGUoKSB7CisgICAgICAgIHJldHVybiBIYW5kc2hha2UuQ0VSVElGSUNBVEVfVkVSSUZZOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0NpcGhlclN1aXRlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9DaXBoZXJTdWl0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyMGEwYjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9DaXBoZXJTdWl0ZS5qYXZhCkBAIC0wLDAgKzEsMTE5NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uQ2lwaGVyOworCisvKioKKyAqIFJlcHJlc2VudHMgQ2lwaGVyIFN1aXRlIGFzIGRlZmluZWQgaW4gVExTIDEuMCBzcGVjLiwKKyAqIEEuNS4gVGhlIENpcGhlclN1aXRlOworICogQy4gQ2lwaGVyU3VpdGUgZGVmaW5pdGlvbnMuCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyNDYudHh0Ij5UTFMgMS4wIHNwZWMuPC9hPgorICoKKyAqLworcHVibGljIGNsYXNzIENpcGhlclN1aXRlIHsKKworICAgIC8qKgorICAgICAqIHRydWUgaWYgdGhpcyBjaXBoZXIgc3VpdGUgaXMgc3VwcG9ydGVkCisgICAgICovCisgICAgYm9vbGVhbiBzdXBwb3J0ZWQgPSB0cnVlOworCisgICAgLyoqCisgICAgICogY2lwaGVyIHN1aXRlIGtleSBleGNoYW5nZQorICAgICAqLworICAgIGZpbmFsIGludCBrZXlFeGNoYW5nZTsKKworICAgIC8qKgorICAgICAqIGFsZ29yaXRobSB1c2VkIGZvciBhdXRoZW50aWNhdGlvbiAoIlJTQSIsICJEU0EiLCAiREgiLCBudWxsIGZvciBhbm9ueW1vdXMpCisgICAgICovCisgICAgZmluYWwgU3RyaW5nIGF1dGhUeXBlOworCisgICAgLyoqCisgICAgICogY2lwaGVyCisgICAgICovCisgICAgZmluYWwgU3RyaW5nIGNpcGhlck5hbWU7CisKKyAgICAvKioKKyAgICAgKiBDaXBoZXIgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBmaW5hbCBpbnQga2V5TWF0ZXJpYWw7CisgICAgZmluYWwgaW50IGV4cGFuZGVkS2V5TWF0ZXJpYWw7CisgICAgZmluYWwgaW50IGVmZmVjdGl2ZUtleUJ5dGVzOworICAgIGZpbmFsIGludCBpdlNpemU7CisgICAgZmluYWwgcHJpdmF0ZSBpbnQgYmxvY2tTaXplOworCisgICAgLy8gY2lwaGVyIHN1aXRlIGNvZGUKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBjaXBoZXJTdWl0ZUNvZGU7CisKKyAgICAvLyBjaXBoZXIgc3VpdGUgbmFtZQorICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG5hbWU7CisKKyAgICAvLyB0cnVlIGlmIGNpcGhlciBzdWl0ZSBpcyBleHBvcnRhYmxlCisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGlzRXhwb3J0YWJsZTsKKworICAgIC8vIEhhc2ggYWxnb3JpdGhtCisgICAgZmluYWwgcHJpdmF0ZSBTdHJpbmcgaGFzaE5hbWU7CisKKyAgICAvLyBNQUMgYWxnb3JpdGhtCisgICAgZmluYWwgcHJpdmF0ZSBTdHJpbmcgaG1hY05hbWU7CisKKyAgICAvLyBIYXNoIHNpemUKKyAgICBmaW5hbCBwcml2YXRlIGludCBoYXNoU2l6ZTsKKworICAgIC8qKgorICAgICAqIGtleSBleGNoYW5nZSB2YWx1ZXMKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgaW50IEtFWV9FWENIQU5HRV9SU0EgPSAxOworICAgIHN0YXRpYyBmaW5hbCBpbnQgS0VZX0VYQ0hBTkdFX1JTQV9FWFBPUlQgPSAyOworICAgIHN0YXRpYyBmaW5hbCBpbnQgS0VZX0VYQ0hBTkdFX0RIRV9EU1MgPSAzOworICAgIHN0YXRpYyBmaW5hbCBpbnQgS0VZX0VYQ0hBTkdFX0RIRV9EU1NfRVhQT1JUID0gNDsKKyAgICBzdGF0aWMgZmluYWwgaW50IEtFWV9FWENIQU5HRV9ESEVfUlNBID0gNTsKKyAgICBzdGF0aWMgZmluYWwgaW50IEtFWV9FWENIQU5HRV9ESEVfUlNBX0VYUE9SVCA9IDY7CisgICAgLy8gQkVHSU4gYW5kcm9pZC1yZW1vdmVkCisgICAgLy8gc3RhdGljIGZpbmFsIGludCBLRVlfRVhDSEFOR0VfREhfRFNTID0gNzsKKyAgICAvLyBzdGF0aWMgZmluYWwgaW50IEtFWV9FWENIQU5HRV9ESF9SU0EgPSA4OworICAgIC8vIEVORCBhbmRyb2lkLXJlbW92ZWQKKyAgICBzdGF0aWMgZmluYWwgaW50IEtFWV9FWENIQU5HRV9ESF9hbm9uID0gOTsKKyAgICBzdGF0aWMgZmluYWwgaW50IEtFWV9FWENIQU5HRV9ESF9hbm9uX0VYUE9SVCA9IDEwOworICAgIC8vIEJFR0lOIGFuZHJvaWQtcmVtb3ZlZAorICAgIC8vIHN0YXRpYyBmaW5hbCBpbnQgS0VZX0VYQ0hBTkdFX0RIX0RTU19FWFBPUlQgPSAxMTsKKyAgICAvLyBzdGF0aWMgZmluYWwgaW50IEtFWV9FWENIQU5HRV9ESF9SU0FfRVhQT1JUID0gMTI7CisgICAgLy8gRU5EIGFuZHJvaWQtcmVtb3ZlZAorICAgIHN0YXRpYyBmaW5hbCBpbnQgS0VZX0VYQ0hBTkdFX0VDREhfRUNEU0EgPSAxMzsKKyAgICBzdGF0aWMgZmluYWwgaW50IEtFWV9FWENIQU5HRV9FQ0RIRV9FQ0RTQSA9IDE0OworICAgIHN0YXRpYyBmaW5hbCBpbnQgS0VZX0VYQ0hBTkdFX0VDREhfUlNBID0gMTU7CisgICAgc3RhdGljIGZpbmFsIGludCBLRVlfRVhDSEFOR0VfRUNESEVfUlNBID0gMTY7CisgICAgc3RhdGljIGZpbmFsIGludCBLRVlfRVhDSEFOR0VfRUNESF9hbm9uID0gMTc7CisKKyAgICAvKioKKyAgICAgKiBUTFMgY2lwaGVyIHN1aXRlIGNvZGVzCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1NTTF9OVUxMX1dJVEhfTlVMTF9OVUxMID0geyAweDAwLCAweDAwIH07CisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1NTTF9SU0FfV0lUSF9OVUxMX01ENSA9IHsgMHgwMCwgMHgwMSB9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9TU0xfUlNBX1dJVEhfTlVMTF9TSEEgPSB7IDB4MDAsIDB4MDIgfTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfU1NMX1JTQV9FWFBPUlRfV0lUSF9SQzRfNDBfTUQ1ID0geyAweDAwLCAweDAzIH07CisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1NTTF9SU0FfV0lUSF9SQzRfMTI4X01ENSA9IHsgMHgwMCwgMHgwNCB9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9TU0xfUlNBX1dJVEhfUkM0XzEyOF9TSEEgPSB7IDB4MDAsIDB4MDUgfTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfU1NMX1JTQV9FWFBPUlRfV0lUSF9SQzJfQ0JDXzQwX01ENSA9IHsgMHgwMCwgMHgwNiB9OworICAgIC8vIEJFR0lOIGFuZHJvaWQtcmVtb3ZlZAorICAgIC8vIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfUlNBX1dJVEhfSURFQV9DQkNfU0hBID0geyAweDAwLCAweDA3IH07CisgICAgLy8gRU5EIGFuZHJvaWQtcmVtb3ZlZAorICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9TU0xfUlNBX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEgPSB7IDB4MDAsIDB4MDggfTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfU1NMX1JTQV9XSVRIX0RFU19DQkNfU0hBID0geyAweDAwLCAweDA5IH07CisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1NTTF9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBID0geyAweDAwLCAweDBBIH07CisgICAgLy8gQkVHSU4gYW5kcm9pZC1yZW1vdmVkCisgICAgLy8gc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1NTTF9ESF9EU1NfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSA9IHsgMHgwMCwgMHgwQiB9OworICAgIC8vIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9TU0xfREhfRFNTX1dJVEhfREVTX0NCQ19TSEEgPSB7IDB4MDAsIDB4MEMgfTsKKyAgICAvLyBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfU1NMX0RIX0RTU19XSVRIXzNERVNfRURFX0NCQ19TSEEgPSB7IDB4MDAsIDB4MEQgfTsKKyAgICAvLyBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfU1NMX0RIX1JTQV9FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBID0geyAweDAwLCAweDBFIH07CisgICAgLy8gc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1NTTF9ESF9SU0FfV0lUSF9ERVNfQ0JDX1NIQSA9IHsgMHgwMCwgMHgwRiB9OworICAgIC8vIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9TU0xfREhfUlNBX1dJVEhfM0RFU19FREVfQ0JDX1NIQSA9IHsgMHgwMCwgMHgxMCB9OworICAgIC8vIEVORCBhbmRyb2lkLXJlbW92ZWQKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfU1NMX0RIRV9EU1NfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSA9IHsgMHgwMCwgMHgxMSB9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9TU0xfREhFX0RTU19XSVRIX0RFU19DQkNfU0hBID0geyAweDAwLCAweDEyIH07CisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1NTTF9ESEVfRFNTX1dJVEhfM0RFU19FREVfQ0JDX1NIQSA9IHsgMHgwMCwgMHgxMyB9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9TU0xfREhFX1JTQV9FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBID0geyAweDAwLCAweDE0IH07CisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1NTTF9ESEVfUlNBX1dJVEhfREVTX0NCQ19TSEEgPSB7IDB4MDAsIDB4MTUgfTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfU1NMX0RIRV9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBID0geyAweDAwLCAweDE2IH07CisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1NTTF9ESF9hbm9uX0VYUE9SVF9XSVRIX1JDNF80MF9NRDUgPSB7IDB4MDAsIDB4MTcgfTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfU1NMX0RIX2Fub25fV0lUSF9SQzRfMTI4X01ENSA9IHsgMHgwMCwgMHgxOCB9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9TU0xfREhfYW5vbl9FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBID0geyAweDAwLCAweDE5IH07CisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1NTTF9ESF9hbm9uX1dJVEhfREVTX0NCQ19TSEEgPSB7IDB4MDAsIDB4MUEgfTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfU1NMX0RIX2Fub25fV0lUSF8zREVTX0VERV9DQkNfU0hBID0geyAweDAwLCAweDFCIH07CisKKyAgICAvLyBBRVMgQ2lwaGVyIFN1aXRlcyBmcm9tIFJGQyAzMjY4IC0gaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzI2OC50eHQKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfVExTX1JTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSA9IHsgMHgwMCwgMHgyRiB9OworICAgIC8vc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1RMU19ESF9EU1NfV0lUSF9BRVNfMTI4X0NCQ19TSEEgPSB7IDB4MDAsIDB4MzAgfTsKKyAgICAvL3N0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfREhfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBID0geyAweDAwLCAweDMxIH07CisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1RMU19ESEVfRFNTX1dJVEhfQUVTXzEyOF9DQkNfU0hBID0geyAweDAwLCAweDMyIH07CisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1RMU19ESEVfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBID0geyAweDAwLCAweDMzIH07CisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1RMU19ESF9hbm9uX1dJVEhfQUVTXzEyOF9DQkNfU0hBID0geyAweDAwLCAweDM0IH07CisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1RMU19SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEgPSB7IDB4MDAsIDB4MzUgfTsKKyAgICAvL3N0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfREhfRFNTX1dJVEhfQUVTXzI1Nl9DQkNfU0hBID0geyAweDAwLCAweDM2IH07CisgICAgLy9zdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfVExTX0RIX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSA9IHsgMHgwMCwgMHgzNyB9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfREhFX0RTU19XSVRIX0FFU18yNTZfQ0JDX1NIQSA9IHsgMHgwMCwgMHgzOCB9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfREhFX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSA9IHsgMHgwMCwgMHgzOSB9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfREhfYW5vbl9XSVRIX0FFU18yNTZfQ0JDX1NIQSA9IHsgMHgwMCwgMHgzQSB9OworCisgICAgLy8gRUMgQ2lwaGVyIFN1aXRlcyBmcm9tIFJGQyA0NDkyIC0gaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjNDQ5Mi50eHQKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfVExTX0VDREhfRUNEU0FfV0lUSF9OVUxMX1NIQSA9IHsgKGJ5dGUpIDB4YzAsIDB4MDF9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfRUNESF9FQ0RTQV9XSVRIX1JDNF8xMjhfU0hBID0geyAoYnl0ZSkgMHhjMCwgMHgwMn07CisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1RMU19FQ0RIX0VDRFNBX1dJVEhfM0RFU19FREVfQ0JDX1NIQSA9IHsgKGJ5dGUpIDB4YzAsIDB4MDN9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfRUNESF9FQ0RTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSA9IHsgKGJ5dGUpIDB4YzAsIDB4MDR9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfRUNESF9FQ0RTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSA9IHsgKGJ5dGUpIDB4YzAsIDB4MDV9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfRUNESEVfRUNEU0FfV0lUSF9OVUxMX1NIQSA9IHsgKGJ5dGUpIDB4YzAsIDB4MDZ9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfRUNESEVfRUNEU0FfV0lUSF9SQzRfMTI4X1NIQSA9IHsgKGJ5dGUpIDB4YzAsIDB4MDd9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfRUNESEVfRUNEU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBID0geyAoYnl0ZSkgMHhjMCwgMHgwOH07CisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1RMU19FQ0RIRV9FQ0RTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSA9IHsgKGJ5dGUpIDB4YzAsIDB4MDl9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfRUNESEVfRUNEU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEgPSB7IChieXRlKSAweGMwLCAweDBBfTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfVExTX0VDREhfUlNBX1dJVEhfTlVMTF9TSEEgPSB7IChieXRlKSAweGMwLCAweDBCfTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfVExTX0VDREhfUlNBX1dJVEhfUkM0XzEyOF9TSEEgPSB7IChieXRlKSAweGMwLCAweDBDfTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfVExTX0VDREhfUlNBX1dJVEhfM0RFU19FREVfQ0JDX1NIQSA9IHsgKGJ5dGUpIDB4YzAsIDB4MER9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfRUNESF9SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEgPSB7IChieXRlKSAweGMwLCAweDBFfTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfVExTX0VDREhfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBID0geyAoYnl0ZSkgMHhjMCwgMHgwRn07CisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1RMU19FQ0RIRV9SU0FfV0lUSF9OVUxMX1NIQSA9IHsgKGJ5dGUpIDB4YzAsIDB4MTB9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfRUNESEVfUlNBX1dJVEhfUkM0XzEyOF9TSEEgPSB7IChieXRlKSAweGMwLCAweDExfTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfVExTX0VDREhFX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEgPSB7IChieXRlKSAweGMwLCAweDEyfTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfVExTX0VDREhFX1JTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSA9IHsgKGJ5dGUpIDB4YzAsIDB4MTN9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfRUNESEVfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBID0geyAoYnl0ZSkgMHhjMCwgMHgxNH07CisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0RFX1RMU19FQ0RIX2Fub25fV0lUSF9OVUxMX1NIQSA9IHsgKGJ5dGUpIDB4YzAsIDB4MTV9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfRUNESF9hbm9uX1dJVEhfUkM0XzEyOF9TSEEgPSB7IChieXRlKSAweGMwLCAweDE2fTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfVExTX0VDREhfYW5vbl9XSVRIXzNERVNfRURFX0NCQ19TSEEgPSB7IChieXRlKSAweGMwLCAweDE3fTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPREVfVExTX0VDREhfYW5vbl9XSVRIX0FFU18xMjhfQ0JDX1NIQSA9IHsgKGJ5dGUpIDB4YzAsIDB4MTh9OworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09ERV9UTFNfRUNESF9hbm9uX1dJVEhfQUVTXzI1Nl9DQkNfU0hBID0geyAoYnl0ZSkgMHhjMCwgMHgxOX07CisKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgU1NMX05VTExfV0lUSF9OVUxMX05VTEwgPSBuZXcgQ2lwaGVyU3VpdGUoCisgICAgICAgICAgICAiU1NMX05VTExfV0lUSF9OVUxMX05VTEwiLCB0cnVlLCAwLCBudWxsLCBudWxsLCBudWxsLAorICAgICAgICAgICAgQ09ERV9TU0xfTlVMTF9XSVRIX05VTExfTlVMTCk7CisKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgU1NMX1JTQV9XSVRIX05VTExfTUQ1ID0gbmV3IENpcGhlclN1aXRlKAorICAgICAgICAgICAgIlNTTF9SU0FfV0lUSF9OVUxMX01ENSIsIHRydWUsIEtFWV9FWENIQU5HRV9SU0EsICJSU0EiLCBudWxsLCAiTUQ1IiwKKyAgICAgICAgICAgIENPREVfU1NMX1JTQV9XSVRIX05VTExfTUQ1KTsKKworICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBTU0xfUlNBX1dJVEhfTlVMTF9TSEEgPSBuZXcgQ2lwaGVyU3VpdGUoCisgICAgICAgICAgICAiU1NMX1JTQV9XSVRIX05VTExfU0hBIiwgdHJ1ZSwgS0VZX0VYQ0hBTkdFX1JTQSwgIlJTQSIsIG51bGwsICJTSEEiLAorICAgICAgICAgICAgQ09ERV9TU0xfUlNBX1dJVEhfTlVMTF9TSEEpOworCisgICAgc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFNTTF9SU0FfRVhQT1JUX1dJVEhfUkM0XzQwX01ENSA9IG5ldyBDaXBoZXJTdWl0ZSgKKyAgICAgICAgICAgICJTU0xfUlNBX0VYUE9SVF9XSVRIX1JDNF80MF9NRDUiLCB0cnVlLCBLRVlfRVhDSEFOR0VfUlNBX0VYUE9SVCwKKyAgICAgICAgICAgICJSU0EiLCAiUkM0XzQwIiwgIk1ENSIsIENPREVfU1NMX1JTQV9FWFBPUlRfV0lUSF9SQzRfNDBfTUQ1KTsKKworICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBTU0xfUlNBX1dJVEhfUkM0XzEyOF9NRDUgPSBuZXcgQ2lwaGVyU3VpdGUoCisgICAgICAgICAgICAiU1NMX1JTQV9XSVRIX1JDNF8xMjhfTUQ1IiwgZmFsc2UsIEtFWV9FWENIQU5HRV9SU0EsICJSU0EiLCAiUkM0XzEyOCIsCisgICAgICAgICAgICAiTUQ1IiwgQ09ERV9TU0xfUlNBX1dJVEhfUkM0XzEyOF9NRDUpOworCisgICAgc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFNTTF9SU0FfV0lUSF9SQzRfMTI4X1NIQSA9IG5ldyBDaXBoZXJTdWl0ZSgKKyAgICAgICAgICAgICJTU0xfUlNBX1dJVEhfUkM0XzEyOF9TSEEiLCBmYWxzZSwgS0VZX0VYQ0hBTkdFX1JTQSwgIlJTQSIsICJSQzRfMTI4IiwKKyAgICAgICAgICAgICJTSEEiLCBDT0RFX1NTTF9SU0FfV0lUSF9SQzRfMTI4X1NIQSk7CisKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgU1NMX1JTQV9FWFBPUlRfV0lUSF9SQzJfQ0JDXzQwX01ENSA9IG5ldyBDaXBoZXJTdWl0ZSgKKyAgICAgICAgICAgICJTU0xfUlNBX0VYUE9SVF9XSVRIX1JDMl9DQkNfNDBfTUQ1IiwgdHJ1ZSwgS0VZX0VYQ0hBTkdFX1JTQV9FWFBPUlQsCisgICAgICAgICAgICAiUlNBIiwgIlJDMl9DQkNfNDAiLCAiTUQ1IiwgQ09ERV9TU0xfUlNBX0VYUE9SVF9XSVRIX1JDMl9DQkNfNDBfTUQ1KTsKKworICAgIC8vIEJFR0lOIGFuZHJvaWQtcmVtb3ZlZAorICAgIC8vIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBUTFNfUlNBX1dJVEhfSURFQV9DQkNfU0hBID0gbmV3IENpcGhlclN1aXRlKAorICAgIC8vICAgICAgICAgIlRMU19SU0FfV0lUSF9JREVBX0NCQ19TSEEiLCBmYWxzZSwgS0VZX0VYQ0hBTkdFX1JTQSwgIlJTQSIsICJJREVBX0NCQyIsCisgICAgLy8gICAgICAgICAiU0hBIiwgQ09ERV9UTFNfUlNBX1dJVEhfSURFQV9DQkNfU0hBKTsKKyAgICAvLyBFTkQgYW5kcm9pZC1yZW1vdmVkCisKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgU1NMX1JTQV9FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBID0gbmV3IENpcGhlclN1aXRlKAorICAgICAgICAgICAgIlNTTF9SU0FfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSIsIHRydWUsIEtFWV9FWENIQU5HRV9SU0FfRVhQT1JULAorICAgICAgICAgICAgIlJTQSIsICJERVM0MF9DQkMiLCAiU0hBIiwgQ09ERV9TU0xfUlNBX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEpOworCisgICAgc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFNTTF9SU0FfV0lUSF9ERVNfQ0JDX1NIQSA9IG5ldyBDaXBoZXJTdWl0ZSgKKyAgICAgICAgICAgICJTU0xfUlNBX1dJVEhfREVTX0NCQ19TSEEiLCBmYWxzZSwgS0VZX0VYQ0hBTkdFX1JTQSwgIlJTQSIsICJERVNfQ0JDIiwKKyAgICAgICAgICAgICJTSEEiLCBDT0RFX1NTTF9SU0FfV0lUSF9ERVNfQ0JDX1NIQSk7CisKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgU1NMX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEgPSBuZXcgQ2lwaGVyU3VpdGUoCisgICAgICAgICAgICAiU1NMX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiLCBmYWxzZSwgS0VZX0VYQ0hBTkdFX1JTQSwKKyAgICAgICAgICAgICJSU0EiLCAiM0RFU19FREVfQ0JDIiwgIlNIQSIsIENPREVfU1NMX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEpOworCisgICAgLy8gQkVHSU4gYW5kcm9pZC1yZW1vdmVkCisgICAgLy8gc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFNTTF9ESF9EU1NfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSA9IG5ldyBDaXBoZXJTdWl0ZSgKKyAgICAvLyAgICAgICAgICJTU0xfREhfRFNTX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEiLCB0cnVlLAorICAgIC8vICAgICAgICAgS0VZX0VYQ0hBTkdFX0RIX0RTU19FWFBPUlQsICJESCIsICJERVM0MF9DQkMiLCAiU0hBIiwKKyAgICAvLyAgICAgICAgIENPREVfU1NMX0RIX0RTU19FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBKTsKKyAgICAvLworICAgIC8vIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBTU0xfREhfRFNTX1dJVEhfREVTX0NCQ19TSEEgPSBuZXcgQ2lwaGVyU3VpdGUoCisgICAgLy8gICAgICAgICAiU1NMX0RIX0RTU19XSVRIX0RFU19DQkNfU0hBIiwgZmFsc2UsIEtFWV9FWENIQU5HRV9ESF9EU1MsCisgICAgLy8gICAgICAgICAiREgiLCAiREVTX0NCQyIsICJTSEEiLCBDT0RFX1NTTF9ESF9EU1NfV0lUSF9ERVNfQ0JDX1NIQSk7CisgICAgLy8KKyAgICAvLyBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgU1NMX0RIX0RTU19XSVRIXzNERVNfRURFX0NCQ19TSEEgPSBuZXcgQ2lwaGVyU3VpdGUoCisgICAgLy8gICAgICAgICAiU1NMX0RIX0RTU19XSVRIXzNERVNfRURFX0NCQ19TSEEiLCBmYWxzZSwgS0VZX0VYQ0hBTkdFX0RIX0RTUywKKyAgICAvLyAgICAgICAgICJESCIsICIzREVTX0VERV9DQkMiLCAiU0hBIiwgQ09ERV9TU0xfREhfRFNTX1dJVEhfM0RFU19FREVfQ0JDX1NIQSk7CisgICAgLy8KKyAgICAvLyBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgU1NMX0RIX1JTQV9FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBID0gbmV3IENpcGhlclN1aXRlKAorICAgIC8vICAgICAgICAgIlNTTF9ESF9SU0FfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSIsIHRydWUsCisgICAgLy8gICAgICAgICBLRVlfRVhDSEFOR0VfREhfUlNBX0VYUE9SVCwgIkRIIiwgIkRFUzQwX0NCQyIsICJTSEEiLAorICAgIC8vICAgICAgICAgQ09ERV9TU0xfREhfUlNBX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEpOworICAgIC8vCisgICAgLy8gc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFNTTF9ESF9SU0FfV0lUSF9ERVNfQ0JDX1NIQSA9IG5ldyBDaXBoZXJTdWl0ZSgKKyAgICAvLyAgICAgICAgICJTU0xfREhfUlNBX1dJVEhfREVTX0NCQ19TSEEiLCBmYWxzZSwgS0VZX0VYQ0hBTkdFX0RIX1JTQSwKKyAgICAvLyAgICAgICAgICJESCIsICJERVNfQ0JDIiwgIlNIQSIsIENPREVfU1NMX0RIX1JTQV9XSVRIX0RFU19DQkNfU0hBKTsKKyAgICAvLworICAgIC8vIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBTU0xfREhfUlNBX1dJVEhfM0RFU19FREVfQ0JDX1NIQSA9IG5ldyBDaXBoZXJTdWl0ZSgKKyAgICAvLyAgICAgICAgICJTU0xfREhfUlNBX1dJVEhfM0RFU19FREVfQ0JDX1NIQSIsIGZhbHNlLCBLRVlfRVhDSEFOR0VfREhfUlNBLAorICAgIC8vICAgICAgICAgIkRIIiwgIjNERVNfRURFX0NCQyIsICJTSEEiLCBDT0RFX1NTTF9ESF9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBKTsKKyAgICAvLyBFTkQgYW5kcm9pZC1yZW1vdmVkCisKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgU1NMX0RIRV9EU1NfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSA9IG5ldyBDaXBoZXJTdWl0ZSgKKyAgICAgICAgICAgICJTU0xfREhFX0RTU19FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBIiwgdHJ1ZSwKKyAgICAgICAgICAgIEtFWV9FWENIQU5HRV9ESEVfRFNTX0VYUE9SVCwgIkRTQSIsICJERVM0MF9DQkMiLCAiU0hBIiwKKyAgICAgICAgICAgIENPREVfU1NMX0RIRV9EU1NfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSk7CisKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgU1NMX0RIRV9EU1NfV0lUSF9ERVNfQ0JDX1NIQSA9IG5ldyBDaXBoZXJTdWl0ZSgKKyAgICAgICAgICAgICJTU0xfREhFX0RTU19XSVRIX0RFU19DQkNfU0hBIiwgZmFsc2UsIEtFWV9FWENIQU5HRV9ESEVfRFNTLAorICAgICAgICAgICAgIkRTQSIsICJERVNfQ0JDIiwgIlNIQSIsIENPREVfU1NMX0RIRV9EU1NfV0lUSF9ERVNfQ0JDX1NIQSk7CisKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgU1NMX0RIRV9EU1NfV0lUSF8zREVTX0VERV9DQkNfU0hBID0gbmV3IENpcGhlclN1aXRlKAorICAgICAgICAgICAgIlNTTF9ESEVfRFNTX1dJVEhfM0RFU19FREVfQ0JDX1NIQSIsIGZhbHNlLCBLRVlfRVhDSEFOR0VfREhFX0RTUywKKyAgICAgICAgICAgICJEU0EiLCAiM0RFU19FREVfQ0JDIiwgIlNIQSIsIENPREVfU1NMX0RIRV9EU1NfV0lUSF8zREVTX0VERV9DQkNfU0hBKTsKKworICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBTU0xfREhFX1JTQV9FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBID0gbmV3IENpcGhlclN1aXRlKAorICAgICAgICAgICAgIlNTTF9ESEVfUlNBX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEiLCB0cnVlLAorICAgICAgICAgICAgS0VZX0VYQ0hBTkdFX0RIRV9SU0FfRVhQT1JULCAiUlNBIiwgIkRFUzQwX0NCQyIsICJTSEEiLAorICAgICAgICAgICAgQ09ERV9TU0xfREhFX1JTQV9FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBKTsKKworICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBTU0xfREhFX1JTQV9XSVRIX0RFU19DQkNfU0hBID0gbmV3IENpcGhlclN1aXRlKAorICAgICAgICAgICAgIlNTTF9ESEVfUlNBX1dJVEhfREVTX0NCQ19TSEEiLCBmYWxzZSwgS0VZX0VYQ0hBTkdFX0RIRV9SU0EsCisgICAgICAgICAgICAiUlNBIiwgIkRFU19DQkMiLCAiU0hBIiwgQ09ERV9TU0xfREhFX1JTQV9XSVRIX0RFU19DQkNfU0hBKTsKKworICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBTU0xfREhFX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEgPSBuZXcgQ2lwaGVyU3VpdGUoCisgICAgICAgICAgICAiU1NMX0RIRV9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBIiwgZmFsc2UsIEtFWV9FWENIQU5HRV9ESEVfUlNBLAorICAgICAgICAgICAgIlJTQSIsICIzREVTX0VERV9DQkMiLCAiU0hBIiwgQ09ERV9TU0xfREhFX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEpOworCisgICAgc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFNTTF9ESF9hbm9uX0VYUE9SVF9XSVRIX1JDNF80MF9NRDUgPSBuZXcgQ2lwaGVyU3VpdGUoCisgICAgICAgICAgICAiU1NMX0RIX2Fub25fRVhQT1JUX1dJVEhfUkM0XzQwX01ENSIsIHRydWUsCisgICAgICAgICAgICBLRVlfRVhDSEFOR0VfREhfYW5vbl9FWFBPUlQsICJESCIsICJSQzRfNDAiLCAiTUQ1IiwKKyAgICAgICAgICAgIENPREVfU1NMX0RIX2Fub25fRVhQT1JUX1dJVEhfUkM0XzQwX01ENSk7CisKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgU1NMX0RIX2Fub25fV0lUSF9SQzRfMTI4X01ENSA9IG5ldyBDaXBoZXJTdWl0ZSgKKyAgICAgICAgICAgICJTU0xfREhfYW5vbl9XSVRIX1JDNF8xMjhfTUQ1IiwgZmFsc2UsIEtFWV9FWENIQU5HRV9ESF9hbm9uLAorICAgICAgICAgICAgIkRIIiwgIlJDNF8xMjgiLCAiTUQ1IiwgQ09ERV9TU0xfREhfYW5vbl9XSVRIX1JDNF8xMjhfTUQ1KTsKKworICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBTU0xfREhfYW5vbl9FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBID0gbmV3IENpcGhlclN1aXRlKAorICAgICAgICAgICAgIlNTTF9ESF9hbm9uX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEiLCB0cnVlLAorICAgICAgICAgICAgS0VZX0VYQ0hBTkdFX0RIX2Fub25fRVhQT1JULCAiREgiLCAiREVTNDBfQ0JDIiwgIlNIQSIsCisgICAgICAgICAgICBDT0RFX1NTTF9ESF9hbm9uX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEpOworCisgICAgc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFNTTF9ESF9hbm9uX1dJVEhfREVTX0NCQ19TSEEgPSBuZXcgQ2lwaGVyU3VpdGUoCisgICAgICAgICAgICAiU1NMX0RIX2Fub25fV0lUSF9ERVNfQ0JDX1NIQSIsIGZhbHNlLCBLRVlfRVhDSEFOR0VfREhfYW5vbiwKKyAgICAgICAgICAgICJESCIsICJERVNfQ0JDIiwgIlNIQSIsIENPREVfU1NMX0RIX2Fub25fV0lUSF9ERVNfQ0JDX1NIQSk7CisKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgU1NMX0RIX2Fub25fV0lUSF8zREVTX0VERV9DQkNfU0hBID0gbmV3IENpcGhlclN1aXRlKAorICAgICAgICAgICAgIlNTTF9ESF9hbm9uX1dJVEhfM0RFU19FREVfQ0JDX1NIQSIsIGZhbHNlLCBLRVlfRVhDSEFOR0VfREhfYW5vbiwKKyAgICAgICAgICAgICJESCIsICIzREVTX0VERV9DQkMiLCAiU0hBIiwgQ09ERV9TU0xfREhfYW5vbl9XSVRIXzNERVNfRURFX0NCQ19TSEEpOworCisgICAgc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFRMU19SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEKKyAgICAgICAgICAgID0gbmV3IENpcGhlclN1aXRlKCJUTFNfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX0VYQ0hBTkdFX1JTQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSU0EiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFFU18xMjhfQ0JDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09ERV9UTFNfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0RIRV9EU1NfV0lUSF9BRVNfMTI4X0NCQ19TSEEKKyAgICAgICAgICAgID0gbmV3IENpcGhlclN1aXRlKCJUTFNfREhFX0RTU19XSVRIX0FFU18xMjhfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9FWENIQU5HRV9ESEVfRFNTLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRTQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQUVTXzEyOF9DQkMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT0RFX1RMU19ESEVfRFNTX1dJVEhfQUVTXzEyOF9DQkNfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0RIRV9SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEKKyAgICAgICAgICAgID0gbmV3IENpcGhlclN1aXRlKCJUTFNfREhFX1JTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9FWENIQU5HRV9ESEVfUlNBLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJTQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQUVTXzEyOF9DQkMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT0RFX1RMU19ESEVfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0RIX2Fub25fV0lUSF9BRVNfMTI4X0NCQ19TSEEKKyAgICAgICAgICAgID0gbmV3IENpcGhlclN1aXRlKCJUTFNfREhfYW5vbl9XSVRIX0FFU18xMjhfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9FWENIQU5HRV9ESF9hbm9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRIIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBRVNfMTI4X0NCQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPREVfVExTX0RIX2Fub25fV0lUSF9BRVNfMTI4X0NCQ19TSEEpOworICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBUTFNfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9FWENIQU5HRV9SU0EsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUlNBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBRVNfMjU2X0NCQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPREVfVExTX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSk7CisgICAgc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFRMU19ESEVfRFNTX1dJVEhfQUVTXzI1Nl9DQkNfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX0RIRV9EU1NfV0lUSF9BRVNfMjU2X0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfRVhDSEFOR0VfREhFX0RTUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEU0EiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFFU18yNTZfQ0JDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09ERV9UTFNfREhFX0RTU19XSVRIX0FFU18yNTZfQ0JDX1NIQSk7CisgICAgc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFRMU19ESEVfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX0RIRV9SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfRVhDSEFOR0VfREhFX1JTQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSU0EiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFFU18yNTZfQ0JDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09ERV9UTFNfREhFX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSk7CisgICAgc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFRMU19ESF9hbm9uX1dJVEhfQUVTXzI1Nl9DQkNfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX0RIX2Fub25fV0lUSF9BRVNfMjU2X0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfRVhDSEFOR0VfREhfYW5vbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJESCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQUVTXzI1Nl9DQkMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT0RFX1RMU19ESF9hbm9uX1dJVEhfQUVTXzI1Nl9DQkNfU0hBKTsKKworICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBUTFNfRUNESF9FQ0RTQV9XSVRIX05VTExfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX0VDREhfRUNEU0FfV0lUSF9OVUxMX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9FWENIQU5HRV9FQ0RIX0VDRFNBLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPREVfVExTX0VDREhfRUNEU0FfV0lUSF9OVUxMX1NIQSk7CisgICAgc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFRMU19FQ0RIX0VDRFNBX1dJVEhfUkM0XzEyOF9TSEEKKyAgICAgICAgICAgID0gbmV3IENpcGhlclN1aXRlKCJUTFNfRUNESF9FQ0RTQV9XSVRIX1JDNF8xMjhfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX0VYQ0hBTkdFX0VDREhfRUNEU0EsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRUMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJDNF8xMjgiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT0RFX1RMU19FQ0RIX0VDRFNBX1dJVEhfUkM0XzEyOF9TSEEpOworICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBUTFNfRUNESF9FQ0RTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEKKyAgICAgICAgICAgID0gbmV3IENpcGhlclN1aXRlKCJUTFNfRUNESF9FQ0RTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfRVhDSEFOR0VfRUNESF9FQ0RTQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiM0RFU19FREVfQ0JDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09ERV9UTFNfRUNESF9FQ0RTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEpOworICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBUTFNfRUNESF9FQ0RTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQQorICAgICAgICAgICAgPSBuZXcgQ2lwaGVyU3VpdGUoIlRMU19FQ0RIX0VDRFNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX0VYQ0hBTkdFX0VDREhfRUNEU0EsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRUMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFFU18xMjhfQ0JDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09ERV9UTFNfRUNESF9FQ0RTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSk7CisgICAgc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFRMU19FQ0RIX0VDRFNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX0VDREhfRUNEU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfRVhDSEFOR0VfRUNESF9FQ0RTQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQUVTXzI1Nl9DQkMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT0RFX1RMU19FQ0RIX0VDRFNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0VDREhFX0VDRFNBX1dJVEhfTlVMTF9TSEEKKyAgICAgICAgICAgID0gbmV3IENpcGhlclN1aXRlKCJUTFNfRUNESEVfRUNEU0FfV0lUSF9OVUxMX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9FWENIQU5HRV9FQ0RIRV9FQ0RTQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT0RFX1RMU19FQ0RIRV9FQ0RTQV9XSVRIX05VTExfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0VDREhFX0VDRFNBX1dJVEhfUkM0XzEyOF9TSEEKKyAgICAgICAgICAgID0gbmV3IENpcGhlclN1aXRlKCJUTFNfRUNESEVfRUNEU0FfV0lUSF9SQzRfMTI4X1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9FWENIQU5HRV9FQ0RIRV9FQ0RTQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUkM0XzEyOCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPREVfVExTX0VDREhFX0VDRFNBX1dJVEhfUkM0XzEyOF9TSEEpOworICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBUTFNfRUNESEVfRUNEU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX0VDREhFX0VDRFNBX1dJVEhfM0RFU19FREVfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9FWENIQU5HRV9FQ0RIRV9FQ0RTQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiM0RFU19FREVfQ0JDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09ERV9UTFNfRUNESEVfRUNEU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX0VYQ0hBTkdFX0VDREhFX0VDRFNBLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBRVNfMTI4X0NCQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPREVfVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX0VYQ0hBTkdFX0VDREhFX0VDRFNBLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBRVNfMjU2X0NCQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPREVfVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0VDREhfUlNBX1dJVEhfTlVMTF9TSEEKKyAgICAgICAgICAgID0gbmV3IENpcGhlclN1aXRlKCJUTFNfRUNESF9SU0FfV0lUSF9OVUxMX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9FWENIQU5HRV9FQ0RIX1JTQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT0RFX1RMU19FQ0RIX1JTQV9XSVRIX05VTExfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0VDREhfUlNBX1dJVEhfUkM0XzEyOF9TSEEKKyAgICAgICAgICAgID0gbmV3IENpcGhlclN1aXRlKCJUTFNfRUNESF9SU0FfV0lUSF9SQzRfMTI4X1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9FWENIQU5HRV9FQ0RIX1JTQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUkM0XzEyOCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPREVfVExTX0VDREhfUlNBX1dJVEhfUkM0XzEyOF9TSEEpOworICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBUTFNfRUNESF9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX0VDREhfUlNBX1dJVEhfM0RFU19FREVfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9FWENIQU5HRV9FQ0RIX1JTQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiM0RFU19FREVfQ0JDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09ERV9UTFNfRUNESF9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0VDREhfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX0VDREhfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX0VYQ0hBTkdFX0VDREhfUlNBLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBRVNfMTI4X0NCQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPREVfVExTX0VDREhfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0VDREhfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX0VDREhfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX0VYQ0hBTkdFX0VDREhfUlNBLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBRVNfMjU2X0NCQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPREVfVExTX0VDREhfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0VDREhFX1JTQV9XSVRIX05VTExfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX0VDREhFX1JTQV9XSVRIX05VTExfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX0VYQ0hBTkdFX0VDREhFX1JTQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT0RFX1RMU19FQ0RIRV9SU0FfV0lUSF9OVUxMX1NIQSk7CisgICAgc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFRMU19FQ0RIRV9SU0FfV0lUSF9SQzRfMTI4X1NIQQorICAgICAgICAgICAgPSBuZXcgQ2lwaGVyU3VpdGUoIlRMU19FQ0RIRV9SU0FfV0lUSF9SQzRfMTI4X1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9FWENIQU5HRV9FQ0RIRV9SU0EsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRUMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJDNF8xMjgiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT0RFX1RMU19FQ0RIRV9SU0FfV0lUSF9SQzRfMTI4X1NIQSk7CisgICAgc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFRMU19FQ0RIRV9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX0VDREhFX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfRVhDSEFOR0VfRUNESEVfUlNBLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIzREVTX0VERV9DQkMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT0RFX1RMU19FQ0RIRV9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0VDREhFX1JTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQQorICAgICAgICAgICAgPSBuZXcgQ2lwaGVyU3VpdGUoIlRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfRVhDSEFOR0VfRUNESEVfUlNBLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBRVNfMTI4X0NCQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPREVfVExTX0VDREhFX1JTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSk7CisgICAgc3RhdGljIGZpbmFsIENpcGhlclN1aXRlIFRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEKKyAgICAgICAgICAgID0gbmV3IENpcGhlclN1aXRlKCJUTFNfRUNESEVfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX0VYQ0hBTkdFX0VDREhFX1JTQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQUVTXzI1Nl9DQkMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT0RFX1RMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEpOworICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBUTFNfRUNESF9hbm9uX1dJVEhfTlVMTF9TSEEKKyAgICAgICAgICAgID0gbmV3IENpcGhlclN1aXRlKCJUTFNfRUNESF9hbm9uX1dJVEhfTlVMTF9TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfRVhDSEFOR0VfRUNESF9hbm9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPREVfVExTX0VDREhfYW5vbl9XSVRIX05VTExfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0VDREhfYW5vbl9XSVRIX1JDNF8xMjhfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX0VDREhfYW5vbl9XSVRIX1JDNF8xMjhfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX0VYQ0hBTkdFX0VDREhfYW5vbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUkM0XzEyOCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPREVfVExTX0VDREhfYW5vbl9XSVRIX1JDNF8xMjhfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0VDREhfYW5vbl9XSVRIXzNERVNfRURFX0NCQ19TSEEKKyAgICAgICAgICAgID0gbmV3IENpcGhlclN1aXRlKCJUTFNfRUNESF9hbm9uX1dJVEhfM0RFU19FREVfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9FWENIQU5HRV9FQ0RIX2Fub24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRUMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjNERVNfRURFX0NCQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPREVfVExTX0VDREhfYW5vbl9XSVRIXzNERVNfRURFX0NCQ19TSEEpOworICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZSBUTFNfRUNESF9hbm9uX1dJVEhfQUVTXzEyOF9DQkNfU0hBCisgICAgICAgICAgICA9IG5ldyBDaXBoZXJTdWl0ZSgiVExTX0VDREhfYW5vbl9XSVRIX0FFU18xMjhfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9FWENIQU5HRV9FQ0RIX2Fub24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRUMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFFU18xMjhfQ0JDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09ERV9UTFNfRUNESF9hbm9uX1dJVEhfQUVTXzEyOF9DQkNfU0hBKTsKKyAgICBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGUgVExTX0VDREhfYW5vbl9XSVRIX0FFU18yNTZfQ0JDX1NIQQorICAgICAgICAgICAgPSBuZXcgQ2lwaGVyU3VpdGUoIlRMU19FQ0RIX2Fub25fV0lUSF9BRVNfMjU2X0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfRVhDSEFOR0VfRUNESF9hbm9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVDIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBRVNfMjU2X0NCQyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPREVfVExTX0VDREhfYW5vbl9XSVRIX0FFU18yNTZfQ0JDX1NIQSk7CisKKyAgICAvLyBhcnJheXMgZm9yIHF1aWNrIGFjY2VzcyB0byBjaXBoZXIgc3VpdGUgYnkgY29kZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENpcGhlclN1aXRlW10gU1VJVEVTX0JZX0NPREVfMHgwMCA9IHsKKyAgICAgICAgLy8gaHR0cDovL3d3dy5pYW5hLm9yZy9hc3NpZ25tZW50cy90bHMtcGFyYW1ldGVycy90bHMtcGFyYW1ldGVycy54bWwKKyAgICAgICAgU1NMX05VTExfV0lUSF9OVUxMX05VTEwsICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MDAgfTsKKyAgICAgICAgU1NMX1JTQV9XSVRIX05VTExfTUQ1LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MDEgfTsKKyAgICAgICAgU1NMX1JTQV9XSVRIX05VTExfU0hBLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MDIgfTsKKyAgICAgICAgU1NMX1JTQV9FWFBPUlRfV0lUSF9SQzRfNDBfTUQ1LCAgICAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MDMgfTsKKyAgICAgICAgU1NMX1JTQV9XSVRIX1JDNF8xMjhfTUQ1LCAgICAgICAgICAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MDQgfTsKKyAgICAgICAgU1NMX1JTQV9XSVRIX1JDNF8xMjhfU0hBLCAgICAgICAgICAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MDUgfTsKKyAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIG51bGwsIC8vIFNTTF9SU0FfRVhQT1JUX1dJVEhfUkMyX0NCQ180MF9NRDUsICAgICAgLy8geyAweDAwLCAweDA2IH07CisgICAgICAgIG51bGwsIC8vIFRMU19SU0FfV0lUSF9JREVBX0NCQ19TSEEsICAgICAgICAgICAgICAgLy8geyAweDAwLCAweDA3IH07CisgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgU1NMX1JTQV9FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBLCAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MDggfTsKKyAgICAgICAgU1NMX1JTQV9XSVRIX0RFU19DQkNfU0hBLCAgICAgICAgICAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MDkgfTsKKyAgICAgICAgU1NMX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEsICAgICAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MGEgfTsKKyAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIG51bGwsIC8vIFNTTF9ESF9EU1NfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSAgICAgLy8geyAweDAwLCAweDBiIH07CisgICAgICAgIG51bGwsIC8vIFNTTF9ESF9EU1NfV0lUSF9ERVNfQ0JDX1NIQSwgICAgICAgICAgICAgLy8geyAweDAwLCAweDBjIH07CisgICAgICAgIG51bGwsIC8vIFNTTF9ESF9EU1NfV0lUSF8zREVTX0VERV9DQkNfU0hBLCAgICAgICAgLy8geyAweDAwLCAweDBkIH07CisgICAgICAgIG51bGwsIC8vIFNTTF9ESF9SU0FfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSwgICAgLy8geyAweDAwLCAweDBlIH07CisgICAgICAgIG51bGwsIC8vIFNTTF9ESF9SU0FfV0lUSF9ERVNfQ0JDX1NIQSwgICAgICAgICAgICAgLy8geyAweDAwLCAweDBmIH07CisgICAgICAgIG51bGwsIC8vIFNTTF9ESF9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBLCAgICAgICAgLy8geyAweDAwLCAweDEwIH07CisgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgU1NMX0RIRV9EU1NfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSwgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MTEgfTsKKyAgICAgICAgU1NMX0RIRV9EU1NfV0lUSF9ERVNfQ0JDX1NIQSwgICAgICAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MTIgfTsKKyAgICAgICAgU1NMX0RIRV9EU1NfV0lUSF8zREVTX0VERV9DQkNfU0hBLCAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MTMgfTsKKyAgICAgICAgU1NMX0RIRV9SU0FfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSwgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MTQgfTsKKyAgICAgICAgU1NMX0RIRV9SU0FfV0lUSF9ERVNfQ0JDX1NIQSwgICAgICAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MTUgfTsKKyAgICAgICAgU1NMX0RIRV9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBLCAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MTYgfTsKKyAgICAgICAgU1NMX0RIX2Fub25fRVhQT1JUX1dJVEhfUkM0XzQwX01ENSwgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MTcgfTsKKyAgICAgICAgU1NMX0RIX2Fub25fV0lUSF9SQzRfMTI4X01ENSwgICAgICAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MTggfTsKKyAgICAgICAgU1NMX0RIX2Fub25fRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSwgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MTkgfTsKKyAgICAgICAgU1NMX0RIX2Fub25fV0lUSF9ERVNfQ0JDX1NIQSwgICAgICAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MUEgfTsKKyAgICAgICAgU1NMX0RIX2Fub25fV0lUSF8zREVTX0VERV9DQkNfU0hBLCAgICAgICAgICAgICAgICAvLyB7IDB4MDAsIDB4MUIgfTsKKyAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1hZGRlZAorICAgICAgICBudWxsLCAvLyBTU0xfRk9SVEVaWkFfS0VBX1dJVEhfTlVMTF9TSEEgICAgICAgICAgIC8vIHsgMHgwMCwgMHgxQyB9OworICAgICAgICBudWxsLCAvLyBTU0xfRk9SVEVaWkFfS0VBX1dJVEhfRk9SVEVaWkFfQ0JDX1NIQSAgIC8vIHsgMHgwMCwgMHgxRCB9OworICAgICAgICBudWxsLCAvLyBUTFNfS1JCNV9XSVRIX0RFU19DQkNfU0hBICAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgxRSB9OworICAgICAgICBudWxsLCAvLyBUTFNfS1JCNV9XSVRIXzNERVNfRURFX0NCQ19TSEEgICAgICAgICAgIC8vIHsgMHgwMCwgMHgxRiB9OworICAgICAgICBudWxsLCAvLyBUTFNfS1JCNV9XSVRIX1JDNF8xMjhfU0hBICAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgyMCB9OworICAgICAgICBudWxsLCAvLyBUTFNfS1JCNV9XSVRIX0lERUFfQ0JDX1NIQSAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgyMSB9OworICAgICAgICBudWxsLCAvLyBUTFNfS1JCNV9XSVRIX0RFU19DQkNfTUQ1ICAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgyMiB9OworICAgICAgICBudWxsLCAvLyBUTFNfS1JCNV9XSVRIXzNERVNfRURFX0NCQ19NRDUgICAgICAgICAgIC8vIHsgMHgwMCwgMHgyMyB9OworICAgICAgICBudWxsLCAvLyBUTFNfS1JCNV9XSVRIX1JDNF8xMjhfTUQ1ICAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgyNCB9OworICAgICAgICBudWxsLCAvLyBUTFNfS1JCNV9XSVRIX0lERUFfQ0JDX01ENSAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgyNSB9OworICAgICAgICBudWxsLCAvLyBUTFNfS1JCNV9FWFBPUlRfV0lUSF9ERVNfQ0JDXzQwX1NIQSAgICAgIC8vIHsgMHgwMCwgMHgyNiB9OworICAgICAgICBudWxsLCAvLyBUTFNfS1JCNV9FWFBPUlRfV0lUSF9SQzJfQ0JDXzQwX1NIQSAgICAgIC8vIHsgMHgwMCwgMHgyNyB9OworICAgICAgICBudWxsLCAvLyBUTFNfS1JCNV9FWFBPUlRfV0lUSF9SQzRfNDBfU0hBICAgICAgICAgIC8vIHsgMHgwMCwgMHgyOCB9OworICAgICAgICBudWxsLCAvLyBUTFNfS1JCNV9FWFBPUlRfV0lUSF9ERVNfQ0JDXzQwX01ENSAgICAgIC8vIHsgMHgwMCwgMHgyOSB9OworICAgICAgICBudWxsLCAvLyBUTFNfS1JCNV9FWFBPUlRfV0lUSF9SQzJfQ0JDXzQwX01ENSAgICAgIC8vIHsgMHgwMCwgMHgyQSB9OworICAgICAgICBudWxsLCAvLyBUTFNfS1JCNV9FWFBPUlRfV0lUSF9SQzRfNDBfTUQ1ICAgICAgICAgIC8vIHsgMHgwMCwgMHgyQiB9OworICAgICAgICBudWxsLCAvLyBUTFNfUFNLX1dJVEhfTlVMTF9TSEEgICAgICAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgyQyB9OworICAgICAgICBudWxsLCAvLyBUTFNfREhFX1BTS19XSVRIX05VTExfU0hBICAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgyRCB9OworICAgICAgICBudWxsLCAvLyBUTFNfUlNBX1BTS19XSVRIX05VTExfU0hBICAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgyRSB9OworICAgICAgICBUTFNfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBLCAgICAgICAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgyRiB9OworICAgICAgICBudWxsLCAvLyBUTFNfREhfRFNTX1dJVEhfQUVTXzEyOF9DQkNfU0hBICAgICAgICAgIC8vIHsgMHgwMCwgMHgzMCB9OworICAgICAgICBudWxsLCAvLyBUTFNfREhfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBICAgICAgICAgIC8vIHsgMHgwMCwgMHgzMSB9OworICAgICAgICBUTFNfREhFX0RTU19XSVRIX0FFU18xMjhfQ0JDX1NIQSwgICAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgzMiB9OworICAgICAgICBUTFNfREhFX1JTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSwgICAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgzMyB9OworICAgICAgICBUTFNfREhfYW5vbl9XSVRIX0FFU18xMjhfQ0JDX1NIQSwgICAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgzNCB9OworICAgICAgICBUTFNfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBLCAgICAgICAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgzNSB9OworICAgICAgICBudWxsLCAvLyBUTFNfREhfRFNTX1dJVEhfQUVTXzI1Nl9DQkNfU0hBLCAgICAgICAgIC8vIHsgMHgwMCwgMHgzNiB9OworICAgICAgICBudWxsLCAvLyBUTFNfREhfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBLCAgICAgICAgIC8vIHsgMHgwMCwgMHgzNyB9OworICAgICAgICBUTFNfREhFX0RTU19XSVRIX0FFU18yNTZfQ0JDX1NIQSwgICAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgzOCB9OworICAgICAgICBUTFNfREhFX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSwgICAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgzOSB9OworICAgICAgICBUTFNfREhfYW5vbl9XSVRIX0FFU18yNTZfQ0JDX1NIQSwgICAgICAgICAgICAgICAgIC8vIHsgMHgwMCwgMHgzQSB9OworICAgICAgICAvLyBFTkQgYW5kcm9pZC1hZGRlZAorICAgIH07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ2lwaGVyU3VpdGVbXSBTVUlURVNfQllfQ09ERV8weGMwID0geworICAgICAgICBudWxsLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHsgMHhjMCwgMHgwMH07CisgICAgICAgIFRMU19FQ0RIX0VDRFNBX1dJVEhfTlVMTF9TSEEsICAgICAgICAgICAgICAgICAgICAgLy8geyAweGMwLCAweDAxfTsKKyAgICAgICAgVExTX0VDREhfRUNEU0FfV0lUSF9SQzRfMTI4X1NIQSwgICAgICAgICAgICAgICAgICAvLyB7IDB4YzAsIDB4MDJ9OworICAgICAgICBUTFNfRUNESF9FQ0RTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEsICAgICAgICAgICAgIC8vIHsgMHhjMCwgMHgwM307CisgICAgICAgIFRMU19FQ0RIX0VDRFNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBLCAgICAgICAgICAgICAgLy8geyAweGMwLCAweDA0fTsKKyAgICAgICAgVExTX0VDREhfRUNEU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEsICAgICAgICAgICAgICAvLyB7IDB4YzAsIDB4MDV9OworICAgICAgICBUTFNfRUNESEVfRUNEU0FfV0lUSF9OVUxMX1NIQSwgICAgICAgICAgICAgICAgICAgIC8vIHsgMHhjMCwgMHgwNn07CisgICAgICAgIFRMU19FQ0RIRV9FQ0RTQV9XSVRIX1JDNF8xMjhfU0hBLCAgICAgICAgICAgICAgICAgLy8geyAweGMwLCAweDA3fTsKKyAgICAgICAgVExTX0VDREhFX0VDRFNBX1dJVEhfM0RFU19FREVfQ0JDX1NIQSwgICAgICAgICAgICAvLyB7IDB4YzAsIDB4MDh9OworICAgICAgICBUTFNfRUNESEVfRUNEU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEsICAgICAgICAgICAgIC8vIHsgMHhjMCwgMHgwOX07CisgICAgICAgIFRMU19FQ0RIRV9FQ0RTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSwgICAgICAgICAgICAgLy8geyAweGMwLCAweDBBfTsKKyAgICAgICAgVExTX0VDREhfUlNBX1dJVEhfTlVMTF9TSEEsICAgICAgICAgICAgICAgICAgICAgICAvLyB7IDB4YzAsIDB4MEJ9OworICAgICAgICBUTFNfRUNESF9SU0FfV0lUSF9SQzRfMTI4X1NIQSwgICAgICAgICAgICAgICAgICAgIC8vIHsgMHhjMCwgMHgwQ307CisgICAgICAgIFRMU19FQ0RIX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEsICAgICAgICAgICAgICAgLy8geyAweGMwLCAweDBEfTsKKyAgICAgICAgVExTX0VDREhfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBLCAgICAgICAgICAgICAgICAvLyB7IDB4YzAsIDB4MEV9OworICAgICAgICBUTFNfRUNESF9SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEsICAgICAgICAgICAgICAgIC8vIHsgMHhjMCwgMHgwRn07CisgICAgICAgIFRMU19FQ0RIRV9SU0FfV0lUSF9OVUxMX1NIQSwgICAgICAgICAgICAgICAgICAgICAgLy8geyAweGMwLCAweDEwfTsKKyAgICAgICAgVExTX0VDREhFX1JTQV9XSVRIX1JDNF8xMjhfU0hBLCAgICAgICAgICAgICAgICAgICAvLyB7IDB4YzAsIDB4MTF9OworICAgICAgICBUTFNfRUNESEVfUlNBX1dJVEhfM0RFU19FREVfQ0JDX1NIQSwgICAgICAgICAgICAgIC8vIHsgMHhjMCwgMHgxMn07CisgICAgICAgIFRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEsICAgICAgICAgICAgICAgLy8geyAweGMwLCAweDEzfTsKKyAgICAgICAgVExTX0VDREhFX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSwgICAgICAgICAgICAgICAvLyB7IDB4YzAsIDB4MTR9OworICAgICAgICBUTFNfRUNESF9hbm9uX1dJVEhfTlVMTF9TSEEsICAgICAgICAgICAgICAgICAgICAgIC8vIHsgMHhjMCwgMHgxNX07CisgICAgICAgIFRMU19FQ0RIX2Fub25fV0lUSF9SQzRfMTI4X1NIQSwgICAgICAgICAgICAgICAgICAgLy8geyAweGMwLCAweDE2fTsKKyAgICAgICAgVExTX0VDREhfYW5vbl9XSVRIXzNERVNfRURFX0NCQ19TSEEsICAgICAgICAgICAgICAvLyB7IDB4YzAsIDB4MTd9OworICAgICAgICBUTFNfRUNESF9hbm9uX1dJVEhfQUVTXzEyOF9DQkNfU0hBLCAgICAgICAgICAgICAgIC8vIHsgMHhjMCwgMHgxOH07CisgICAgICAgIFRMU19FQ0RIX2Fub25fV0lUSF9BRVNfMjU2X0NCQ19TSEEsICAgICAgICAgICAgICAgLy8geyAweGMwLCAweDE5fTsKKyAgICAgICAgLy8gVExTX1NSUF9TSEFfV0lUSF8zREVTX0VERV9DQkNfU0hBLCAgICAgICAgICAgICAvLyB7IDB4YzAsIDB4MUF9OworICAgICAgICAvLyBUTFNfU1JQX1NIQV9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBLCAgICAgICAgIC8vIHsgMHhjMCwgMHgxQn07CisgICAgICAgIC8vIFRMU19TUlBfU0hBX0RTU19XSVRIXzNERVNfRURFX0NCQ19TSEEsICAgICAgICAgLy8geyAweGMwLCAweDFDfTsKKyAgICAgICAgLy8gVExTX1NSUF9TSEFfV0lUSF9BRVNfMTI4X0NCQ19TSEEsICAgICAgICAgICAgICAvLyB7IDB4YzAsIDB4MUR9OworICAgICAgICAvLyBUTFNfU1JQX1NIQV9SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEsICAgICAgICAgIC8vIHsgMHhjMCwgMHgxRX07CisgICAgICAgIC8vIFRMU19TUlBfU0hBX0RTU19XSVRIX0FFU18xMjhfQ0JDX1NIQSwgICAgICAgICAgLy8geyAweGMwLCAweDFGfTsKKyAgICAgICAgLy8gVExTX1NSUF9TSEFfV0lUSF9BRVNfMjU2X0NCQ19TSEEsICAgICAgICAgICAgICAvLyB7IDB4YzAsIDB4MjB9OworICAgICAgICAvLyBUTFNfU1JQX1NIQV9SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEsICAgICAgICAgIC8vIHsgMHhjMCwgMHgyMX07CisgICAgICAgIC8vIFRMU19TUlBfU0hBX0RTU19XSVRIX0FFU18yNTZfQ0JDX1NIQSwgICAgICAgICAgLy8geyAweGMwLCAweDIyfTsKKyAgICAgICAgLy8gVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBMjU2LCAgICAgICAvLyB7IDB4YzAsIDB4MjN9OworICAgICAgICAvLyBUTFNfRUNESEVfRUNEU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEzODQsICAgICAgIC8vIHsgMHhjMCwgMHgyNH07CisgICAgICAgIC8vIFRMU19FQ0RIX0VDRFNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBMjU2LCAgICAgICAgLy8geyAweGMwLCAweDI1fTsKKyAgICAgICAgLy8gVExTX0VDREhfRUNEU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEzODQsICAgICAgICAvLyB7IDB4YzAsIDB4MjZ9OworICAgICAgICAvLyBUTFNfRUNESEVfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBMjU2LCAgICAgICAgIC8vIHsgMHhjMCwgMHgyN307CisgICAgICAgIC8vIFRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEzODQsICAgICAgICAgLy8geyAweGMwLCAweDI4fTsKKyAgICAgICAgLy8gVExTX0VDREhfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBMjU2LCAgICAgICAgICAvLyB7IDB4YzAsIDB4Mjl9OworICAgICAgICAvLyBUTFNfRUNESF9SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEzODQsICAgICAgICAgIC8vIHsgMHhjMCwgMHgyQX07CisgICAgICAgIC8vIFRMU19FQ0RIRV9FQ0RTQV9XSVRIX0FFU18xMjhfR0NNX1NIQTI1NiwgICAgICAgLy8geyAweGMwLCAweDJCfTsKKyAgICAgICAgLy8gVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzI1Nl9HQ01fU0hBMzg0LCAgICAgICAvLyB7IDB4YzAsIDB4MkN9OworICAgICAgICAvLyBUTFNfRUNESF9FQ0RTQV9XSVRIX0FFU18xMjhfR0NNX1NIQTI1NiwgICAgICAgIC8vIHsgMHhjMCwgMHgyRH07CisgICAgICAgIC8vIFRMU19FQ0RIX0VDRFNBX1dJVEhfQUVTXzI1Nl9HQ01fU0hBMzg0LCAgICAgICAgLy8geyAweGMwLCAweDJFfTsKKyAgICAgICAgLy8gVExTX0VDREhFX1JTQV9XSVRIX0FFU18xMjhfR0NNX1NIQTI1NiwgICAgICAgICAvLyB7IDB4YzAsIDB4MkZ9OworICAgICAgICAvLyBUTFNfRUNESEVfUlNBX1dJVEhfQUVTXzI1Nl9HQ01fU0hBMzg0LCAgICAgICAgIC8vIHsgMHhjMCwgMHgzMH07CisgICAgICAgIC8vIFRMU19FQ0RIX1JTQV9XSVRIX0FFU18xMjhfR0NNX1NIQTI1NiwgICAgICAgICAgLy8geyAweGMwLCAweDMxfTsKKyAgICAgICAgLy8gVExTX0VDREhfUlNBX1dJVEhfQUVTXzI1Nl9HQ01fU0hBMzg0LCAgICAgICAgICAvLyB7IDB4YzAsIDB4MzJ9OworICAgICAgICAvLyBUTFNfRUNESEVfUFNLX1dJVEhfUkM0XzEyOF9TSEEsICAgICAgICAgICAgICAgIC8vIHsgMHhjMCwgMHgzM307CisgICAgICAgIC8vIFRMU19FQ0RIRV9QU0tfV0lUSF8zREVTX0VERV9DQkNfU0hBLCAgICAgICAgICAgLy8geyAweGMwLCAweDM0fTsKKyAgICAgICAgLy8gVExTX0VDREhFX1BTS19XSVRIX0FFU18xMjhfQ0JDX1NIQSwgICAgICAgICAgICAvLyB7IDB4YzAsIDB4MzV9OworICAgICAgICAvLyBUTFNfRUNESEVfUFNLX1dJVEhfQUVTXzI1Nl9DQkNfU0hBLCAgICAgICAgICAgIC8vIHsgMHhjMCwgMHgzNn07CisgICAgICAgIC8vIFRMU19FQ0RIRV9QU0tfV0lUSF9BRVNfMTI4X0NCQ19TSEEyNTYsICAgICAgICAgLy8geyAweGMwLCAweDM3fTsKKyAgICAgICAgLy8gVExTX0VDREhFX1BTS19XSVRIX0FFU18yNTZfQ0JDX1NIQTM4NCwgICAgICAgICAvLyB7IDB4YzAsIDB4Mzh9OworICAgICAgICAvLyBUTFNfRUNESEVfUFNLX1dJVEhfTlVMTF9TSEEsICAgICAgICAgICAgICAgICAgIC8vIHsgMHhjMCwgMHgzOX07CisgICAgICAgIC8vIFRMU19FQ0RIRV9QU0tfV0lUSF9OVUxMX1NIQTI1NiwgICAgICAgICAgICAgICAgLy8geyAweGMwLCAweDNBfTsKKyAgICAgICAgLy8gVExTX0VDREhFX1BTS19XSVRIX05VTExfU0hBMzg0LCAgICAgICAgICAgICAgICAvLyB7IDB4YzAsIDB4M0J9OworICAgIH07CisKKyAgICAvLyBoYXNoIGZvciBxdWljayBhY2Nlc3MgdG8gY2lwaGVyIHN1aXRlIGJ5IG5hbWUKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBIYXNodGFibGU8U3RyaW5nLCBDaXBoZXJTdWl0ZT4gU1VJVEVTX0JZX05BTUU7CisKKyAgICAvKioKKyAgICAgKiBhcnJheSBvZiBzdXBwb3J0ZWQgY2lwaGVyIHN1aXRlcy4KKyAgICAgKiBTZXQgb2Ygc3VwcG9ydGVkIHN1aXRlcyBpcyBkZWZpbmVkIGF0IHRoZSBtb21lbnQgcHJvdmlkZXIncyBzdGFydAorICAgICAqLworICAgIC8vICBUT0RPIER5bmFtaWNhbGx5IHN1cHBvcnRlZCBzdWl0ZXM6IG5ldyBwcm92aWRlcnMgbWF5IGJlIGR5bmFtaWNhbGx5CisgICAgLy8gIGFkZGVkL3JlbW92ZWQgYW5kIHRoZSBzZXQgb2Ygc3VwcG9ydGVkIHN1aXRlcyBtYXkgYmUgY2hhbmdlZAorICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZVtdIFNVUFBPUlRFRF9DSVBIRVJfU1VJVEVTOworCisgICAgLyoqCisgICAgICogYXJyYXkgb2Ygc3VwcG9ydGVkIGNpcGhlciBzdWl0ZXMgbmFtZXMKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nW10gU1VQUE9SVEVEX0NJUEhFUl9TVUlURV9OQU1FUzsKKworICAgIC8qKgorICAgICAqIGRlZmF1bHQgY2lwaGVyIHN1aXRlcworICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBDaXBoZXJTdWl0ZVtdIERFRkFVTFRfQ0lQSEVSX1NVSVRFUzsKKworICAgIHN0YXRpYyB7CisgICAgICAgIFNVSVRFU19CWV9OQU1FID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIENpcGhlclN1aXRlPigpOworICAgICAgICBpbnQgY291bnRfMHgwMCA9IHJlZ2lzdGVyQ2lwaGVyU3VpdGVzQnlDb2RlKFNVSVRFU19CWV9DT0RFXzB4MDApOworICAgICAgICBpbnQgY291bnRfMHhjMCA9IHJlZ2lzdGVyQ2lwaGVyU3VpdGVzQnlDb2RlKFNVSVRFU19CWV9DT0RFXzB4YzApOworICAgICAgICBpbnQgY291bnQgPSBjb3VudF8weDAwICsgY291bnRfMHhjMDsKKyAgICAgICAgU1VQUE9SVEVEX0NJUEhFUl9TVUlURVMgPSBuZXcgQ2lwaGVyU3VpdGVbY291bnRdOworICAgICAgICBTVVBQT1JURURfQ0lQSEVSX1NVSVRFX05BTUVTID0gbmV3IFN0cmluZ1tjb3VudF07CisgICAgICAgIHJlZ2lzdGVyU3VwcG9ydGVkQ2lwaGVyU3VpdGVzKDAsIFNVSVRFU19CWV9DT0RFXzB4MDApOworICAgICAgICByZWdpc3RlclN1cHBvcnRlZENpcGhlclN1aXRlcyhjb3VudF8weDAwLCBTVUlURVNfQllfQ09ERV8weGMwKTsKKworICAgICAgICBDaXBoZXJTdWl0ZVtdIGRlZmF1bHRDaXBoZXJTdWl0ZXMgPSB7CisgICAgICAgICAgICAgICAgU1NMX1JTQV9XSVRIX1JDNF8xMjhfTUQ1LAorICAgICAgICAgICAgICAgIFNTTF9SU0FfV0lUSF9SQzRfMTI4X1NIQSwKKyAgICAgICAgICAgICAgICBUTFNfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBLAorICAgICAgICAgICAgICAgIFRMU19ESEVfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBLAorICAgICAgICAgICAgICAgIFRMU19ESEVfRFNTX1dJVEhfQUVTXzEyOF9DQkNfU0hBLAorICAgICAgICAgICAgICAgIFNTTF9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBLAorICAgICAgICAgICAgICAgIFNTTF9ESEVfUlNBX1dJVEhfM0RFU19FREVfQ0JDX1NIQSwKKyAgICAgICAgICAgICAgICBTU0xfREhFX0RTU19XSVRIXzNERVNfRURFX0NCQ19TSEEsCisgICAgICAgICAgICAgICAgU1NMX1JTQV9XSVRIX0RFU19DQkNfU0hBLAorICAgICAgICAgICAgICAgIFNTTF9ESEVfUlNBX1dJVEhfREVTX0NCQ19TSEEsCisgICAgICAgICAgICAgICAgU1NMX0RIRV9EU1NfV0lUSF9ERVNfQ0JDX1NIQSwKKyAgICAgICAgICAgICAgICBTU0xfUlNBX0VYUE9SVF9XSVRIX1JDNF80MF9NRDUsCisgICAgICAgICAgICAgICAgU1NMX1JTQV9FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBLAorICAgICAgICAgICAgICAgIFNTTF9ESEVfUlNBX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEsCisgICAgICAgICAgICAgICAgU1NMX0RIRV9EU1NfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQQorICAgICAgICAgICAgICAgIH07CisgICAgICAgIGNvdW50ID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZWZhdWx0Q2lwaGVyU3VpdGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoZGVmYXVsdENpcGhlclN1aXRlc1tpXS5zdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgICAgICBjb3VudCsrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIERFRkFVTFRfQ0lQSEVSX1NVSVRFUyA9IG5ldyBDaXBoZXJTdWl0ZVtjb3VudF07CisgICAgICAgIGNvdW50ID0gMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZWZhdWx0Q2lwaGVyU3VpdGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoZGVmYXVsdENpcGhlclN1aXRlc1tpXS5zdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgICAgICBERUZBVUxUX0NJUEhFUl9TVUlURVNbY291bnQrK10gPSBkZWZhdWx0Q2lwaGVyU3VpdGVzW2ldOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIGludCByZWdpc3RlckNpcGhlclN1aXRlc0J5Q29kZShDaXBoZXJTdWl0ZVtdIGNpcGhlclN1aXRlcykgeworICAgICAgICBpbnQgY291bnQgPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNpcGhlclN1aXRlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKGNpcGhlclN1aXRlc1tpXSA9PSBTU0xfTlVMTF9XSVRIX05VTExfTlVMTCkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGNpcGhlclN1aXRlc1tpXSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTVUlURVNfQllfTkFNRS5wdXQoY2lwaGVyU3VpdGVzW2ldLmdldE5hbWUoKSwgY2lwaGVyU3VpdGVzW2ldKTsKKyAgICAgICAgICAgIGlmIChjaXBoZXJTdWl0ZXNbaV0uc3VwcG9ydGVkKSB7CisgICAgICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY291bnQ7CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcmVnaXN0ZXJTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoaW50IG9mZnNldCwgQ2lwaGVyU3VpdGVbXSBjaXBoZXJTdWl0ZXMpIHsKKyAgICAgICAgaW50IGNvdW50ID0gb2Zmc2V0OworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNpcGhlclN1aXRlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKGNpcGhlclN1aXRlc1tpXSA9PSBTU0xfTlVMTF9XSVRIX05VTExfTlVMTCkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGNpcGhlclN1aXRlc1tpXSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY2lwaGVyU3VpdGVzW2ldLnN1cHBvcnRlZCkgeworICAgICAgICAgICAgICAgIFNVUFBPUlRFRF9DSVBIRVJfU1VJVEVTW2NvdW50XSA9IGNpcGhlclN1aXRlc1tpXTsKKyAgICAgICAgICAgICAgICBTVVBQT1JURURfQ0lQSEVSX1NVSVRFX05BTUVTW2NvdW50XSA9IFNVUFBPUlRFRF9DSVBIRVJfU1VJVEVTW2NvdW50XS5nZXROYW1lKCk7CisgICAgICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgQ2lwaGVyU3VpdGUgYnkgbmFtZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ2lwaGVyU3VpdGUgZ2V0QnlOYW1lKFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiBTVUlURVNfQllfTkFNRS5nZXQobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBDaXBoZXJTdWl0ZSBiYXNlZCBvbiBUTFMgQ2lwaGVyU3VpdGUgY29kZQorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI0Ni50eHQiPlRMUyAxLjAgc3BlYy4sIEEuNS4gVGhlIENpcGhlclN1aXRlPC9hPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ2lwaGVyU3VpdGUgZ2V0QnlDb2RlKGJ5dGUgYjEsIGJ5dGUgYjIpIHsKKyAgICAgICAgaW50IGkxID0gYjEgJiAweGZmOworICAgICAgICBpbnQgaTIgPSBiMiAmIDB4ZmY7CisgICAgICAgIENpcGhlclN1aXRlIGNzID0gZ2V0Q2lwaGVyU3VpdGVCeUNvZGUoMCwgaTEsIGkyKTsKKyAgICAgICAgaWYgKGNzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBjczsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IENpcGhlclN1aXRlKCJVTktOT1dOXyIgKyBpMSArICJfIiArIGkyLCBmYWxzZSwgMCwgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsLCBuZXcgYnl0ZVtdIHsgYjEsIGIyIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgQ2lwaGVyU3VpdGUgYmFzZWQgb24gVjJDaXBoZXJTcGVjIGNvZGUKKyAgICAgKiBhcyBkZXNjcmliZWQgaW4gVExTIDEuMCBzcGVjLiwgRS4gQmFja3dhcmQgQ29tcGF0aWJpbGl0eSBXaXRoIFNTTAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ2lwaGVyU3VpdGUgZ2V0QnlDb2RlKGJ5dGUgYjEsIGJ5dGUgYjIsIGJ5dGUgYjMpIHsKKyAgICAgICAgaW50IGkxID0gYjEgJiAweGZmOworICAgICAgICBpbnQgaTIgPSBiMiAmIDB4ZmY7CisgICAgICAgIGludCBpMyA9IGIzICYgMHhmZjsKKyAgICAgICAgQ2lwaGVyU3VpdGUgY3MgPSBnZXRDaXBoZXJTdWl0ZUJ5Q29kZShpMSwgaTIsIGkzKTsKKyAgICAgICAgaWYgKGNzICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBjczsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IENpcGhlclN1aXRlKCJVTktOT1dOXyIgKyBpMSArICJfIiArIGkyICsgIl8iICsgaTMsIGZhbHNlLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwsIG51bGwsIG5ldyBieXRlW10geyBiMSwgYjIsIGIzIH0pOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIENpcGhlclN1aXRlIGdldENpcGhlclN1aXRlQnlDb2RlKGludCBpMSwgaW50IGkyLCBpbnQgaTMpIHsKKyAgICAgICAgQ2lwaGVyU3VpdGVbXSBjaXBoZXJTdWl0ZXM7CisgICAgICAgIGlmIChpMSA9PSAweDAwICYmIGkyID09IDB4MDApIHsKKyAgICAgICAgICAgIGNpcGhlclN1aXRlcyA9IFNVSVRFU19CWV9DT0RFXzB4MDA7CisgICAgICAgIH0gZWxzZSBpZiAoaTEgPT0gMHgwMCAmJiBpMiA9PSAweGMwKSB7CisgICAgICAgICAgICBjaXBoZXJTdWl0ZXMgPSBTVUlURVNfQllfQ09ERV8weGMwOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGkzID49IGNpcGhlclN1aXRlcy5sZW5ndGgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjaXBoZXJTdWl0ZXNbaTNdOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgQ2lwaGVyU3VpdGUKKyAgICAgKi8KKyAgICBwcml2YXRlIENpcGhlclN1aXRlKFN0cmluZyBuYW1lLCBib29sZWFuIGlzRXhwb3J0YWJsZSwgaW50IGtleUV4Y2hhbmdlLAorICAgICAgICAgICAgU3RyaW5nIGF1dGhUeXBlLCBTdHJpbmcgY2lwaGVyTmFtZSwgU3RyaW5nIGhhc2gsIGJ5dGVbXSBjb2RlKSB7CisgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgIHRoaXMua2V5RXhjaGFuZ2UgPSBrZXlFeGNoYW5nZTsKKyAgICAgICAgdGhpcy5hdXRoVHlwZSA9IGF1dGhUeXBlOworICAgICAgICB0aGlzLmlzRXhwb3J0YWJsZSA9IGlzRXhwb3J0YWJsZTsKKyAgICAgICAgaWYgKGNpcGhlck5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhpcy5jaXBoZXJOYW1lID0gbnVsbDsKKyAgICAgICAgICAgIGtleU1hdGVyaWFsID0gMDsKKyAgICAgICAgICAgIGV4cGFuZGVkS2V5TWF0ZXJpYWwgPSAwOworICAgICAgICAgICAgZWZmZWN0aXZlS2V5Qnl0ZXMgPSAwOworICAgICAgICAgICAgaXZTaXplID0gMDsKKyAgICAgICAgICAgIGJsb2NrU2l6ZSA9IDA7CisgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtcmVtb3ZlZAorICAgICAgICAvLyB9IGVsc2UgaWYgKCJJREVBX0NCQyIuZXF1YWxzKGNpcGhlck5hbWUpKSB7CisgICAgICAgIC8vICAgICB0aGlzLmNpcGhlck5hbWUgPSAiSURFQS9DQkMvTm9QYWRkaW5nIjsKKyAgICAgICAgLy8gICAgIGtleU1hdGVyaWFsID0gMTY7CisgICAgICAgIC8vICAgICBleHBhbmRlZEtleU1hdGVyaWFsID0gMTY7CisgICAgICAgIC8vICAgICBlZmZlY3RpdmVLZXlCeXRlcyA9IDE2OworICAgICAgICAvLyAgICAgaXZTaXplID0gODsKKyAgICAgICAgLy8gICAgIGJsb2NrU2l6ZSA9IDg7CisgICAgICAgIC8vIH0gZWxzZSBpZiAoIlJDMl9DQkNfNDAiLmVxdWFscyhjaXBoZXJOYW1lKSkgeworICAgICAgICAvLyAgICAgdGhpcy5jaXBoZXJOYW1lID0gIlJDMi9DQkMvTm9QYWRkaW5nIjsKKyAgICAgICAgLy8gICAgIGtleU1hdGVyaWFsID0gNTsKKyAgICAgICAgLy8gICAgIGV4cGFuZGVkS2V5TWF0ZXJpYWwgPSAxNjsKKyAgICAgICAgLy8gICAgIGVmZmVjdGl2ZUtleUJ5dGVzID0gNTsKKyAgICAgICAgLy8gICAgIGl2U2l6ZSA9IDg7CisgICAgICAgIC8vICAgICBibG9ja1NpemUgPSA4OworICAgICAgICAvLyBFTkQgYW5kcm9pZC1yZW1vdmVkCisgICAgICAgIH0gZWxzZSBpZiAoIlJDNF80MCIuZXF1YWxzKGNpcGhlck5hbWUpKSB7CisgICAgICAgICAgICB0aGlzLmNpcGhlck5hbWUgPSAiUkM0IjsKKyAgICAgICAgICAgIGtleU1hdGVyaWFsID0gNTsKKyAgICAgICAgICAgIGV4cGFuZGVkS2V5TWF0ZXJpYWwgPSAxNjsKKyAgICAgICAgICAgIGVmZmVjdGl2ZUtleUJ5dGVzID0gNTsKKyAgICAgICAgICAgIGl2U2l6ZSA9IDA7CisgICAgICAgICAgICBibG9ja1NpemUgPSAwOworICAgICAgICB9IGVsc2UgaWYgKCJSQzRfMTI4Ii5lcXVhbHMoY2lwaGVyTmFtZSkpIHsKKyAgICAgICAgICAgIHRoaXMuY2lwaGVyTmFtZSA9ICJSQzQiOworICAgICAgICAgICAga2V5TWF0ZXJpYWwgPSAxNjsKKyAgICAgICAgICAgIGV4cGFuZGVkS2V5TWF0ZXJpYWwgPSAxNjsKKyAgICAgICAgICAgIGVmZmVjdGl2ZUtleUJ5dGVzID0gMTY7CisgICAgICAgICAgICBpdlNpemUgPSAwOworICAgICAgICAgICAgYmxvY2tTaXplID0gMDsKKyAgICAgICAgfSBlbHNlIGlmICgiREVTNDBfQ0JDIi5lcXVhbHMoY2lwaGVyTmFtZSkpIHsKKyAgICAgICAgICAgIHRoaXMuY2lwaGVyTmFtZSA9ICJERVMvQ0JDL05vUGFkZGluZyI7CisgICAgICAgICAgICBrZXlNYXRlcmlhbCA9IDU7CisgICAgICAgICAgICBleHBhbmRlZEtleU1hdGVyaWFsID0gODsKKyAgICAgICAgICAgIGVmZmVjdGl2ZUtleUJ5dGVzID0gNTsKKyAgICAgICAgICAgIGl2U2l6ZSA9IDg7CisgICAgICAgICAgICBibG9ja1NpemUgPSA4OworICAgICAgICB9IGVsc2UgaWYgKCJERVNfQ0JDIi5lcXVhbHMoY2lwaGVyTmFtZSkpIHsKKyAgICAgICAgICAgIHRoaXMuY2lwaGVyTmFtZSA9ICJERVMvQ0JDL05vUGFkZGluZyI7CisgICAgICAgICAgICBrZXlNYXRlcmlhbCA9IDg7CisgICAgICAgICAgICBleHBhbmRlZEtleU1hdGVyaWFsID0gODsKKyAgICAgICAgICAgIGVmZmVjdGl2ZUtleUJ5dGVzID0gNzsKKyAgICAgICAgICAgIGl2U2l6ZSA9IDg7CisgICAgICAgICAgICBibG9ja1NpemUgPSA4OworICAgICAgICB9IGVsc2UgaWYgKCIzREVTX0VERV9DQkMiLmVxdWFscyhjaXBoZXJOYW1lKSkgeworICAgICAgICAgICAgdGhpcy5jaXBoZXJOYW1lID0gIkRFU2VkZS9DQkMvTm9QYWRkaW5nIjsKKyAgICAgICAgICAgIGtleU1hdGVyaWFsID0gMjQ7CisgICAgICAgICAgICBleHBhbmRlZEtleU1hdGVyaWFsID0gMjQ7CisgICAgICAgICAgICBlZmZlY3RpdmVLZXlCeXRlcyA9IDI0OworICAgICAgICAgICAgaXZTaXplID0gODsKKyAgICAgICAgICAgIGJsb2NrU2l6ZSA9IDg7CisgICAgICAgIH0gZWxzZSBpZiAoIkFFU18xMjhfQ0JDIi5lcXVhbHMoY2lwaGVyTmFtZSkpIHsKKyAgICAgICAgICAgIHRoaXMuY2lwaGVyTmFtZSA9ICJBRVMvQ0JDL05vUGFkZGluZyI7CisgICAgICAgICAgICBrZXlNYXRlcmlhbCA9IDE2OworICAgICAgICAgICAgZXhwYW5kZWRLZXlNYXRlcmlhbCA9IDE2OworICAgICAgICAgICAgZWZmZWN0aXZlS2V5Qnl0ZXMgPSAxNjsKKyAgICAgICAgICAgIGl2U2l6ZSA9IDE2OworICAgICAgICAgICAgYmxvY2tTaXplID0gMTY7CisgICAgICAgIH0gZWxzZSBpZiAoIkFFU18yNTZfQ0JDIi5lcXVhbHMoY2lwaGVyTmFtZSkpIHsKKyAgICAgICAgICAgIHRoaXMuY2lwaGVyTmFtZSA9ICJBRVMvQ0JDL05vUGFkZGluZyI7CisgICAgICAgICAgICBrZXlNYXRlcmlhbCA9IDMyOworICAgICAgICAgICAgZXhwYW5kZWRLZXlNYXRlcmlhbCA9IDMyOworICAgICAgICAgICAgZWZmZWN0aXZlS2V5Qnl0ZXMgPSAzMjsKKyAgICAgICAgICAgIGl2U2l6ZSA9IDE2OworICAgICAgICAgICAgYmxvY2tTaXplID0gMTY7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aGlzLmNpcGhlck5hbWUgPSBjaXBoZXJOYW1lOworICAgICAgICAgICAga2V5TWF0ZXJpYWwgPSAwOworICAgICAgICAgICAgZXhwYW5kZWRLZXlNYXRlcmlhbCA9IDA7CisgICAgICAgICAgICBlZmZlY3RpdmVLZXlCeXRlcyA9IDA7CisgICAgICAgICAgICBpdlNpemUgPSAwOworICAgICAgICAgICAgYmxvY2tTaXplID0gMDsKKyAgICAgICAgfQorCisgICAgICAgIGlmICgiTUQ1Ii5lcXVhbHMoaGFzaCkpIHsKKyAgICAgICAgICAgIHRoaXMuaG1hY05hbWUgPSAiSG1hY01ENSI7CisgICAgICAgICAgICB0aGlzLmhhc2hOYW1lID0gIk1ENSI7CisgICAgICAgICAgICBoYXNoU2l6ZSA9IDE2OworICAgICAgICB9IGVsc2UgaWYgKCJTSEEiLmVxdWFscyhoYXNoKSkgeworICAgICAgICAgICAgdGhpcy5obWFjTmFtZSA9ICJIbWFjU0hBMSI7CisgICAgICAgICAgICB0aGlzLmhhc2hOYW1lID0gIlNIQS0xIjsKKyAgICAgICAgICAgIGhhc2hTaXplID0gMjA7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aGlzLmhtYWNOYW1lID0gbnVsbDsKKyAgICAgICAgICAgIHRoaXMuaGFzaE5hbWUgPSBudWxsOworICAgICAgICAgICAgaGFzaFNpemUgPSAwOworICAgICAgICB9CisKKyAgICAgICAgY2lwaGVyU3VpdGVDb2RlID0gY29kZTsKKworICAgICAgICBpZiAodGhpcy5jaXBoZXJOYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2lwaGVyLmdldEluc3RhbmNlKHRoaXMuY2lwaGVyTmFtZSk7CisgICAgICAgICAgICB9IGNhdGNoIChHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHN1cHBvcnRlZCA9IGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gV2UgZGVmaW5lIHRoZSBFbGxpcHRpYyBDdXJ2ZSBjaXBoZXIgc3VpdGVzIGZvciB1c2Ugd2l0aAorICAgICAgICAvLyBjb2RlIHNoYXJlZCBieSBPcGVuU1NMLCBidXQgdGhleSBhcmUgbm90IHN1cHBvcnRlZCBieQorICAgICAgICAvLyBTU0xFbmdpbmUgb3IgU1NMU29ja2V0J3MgYnVpbHQgd2l0aCBTU0xFbmdpbmUuCisgICAgICAgIGlmICh0aGlzLm5hbWUuc3RhcnRzV2l0aCgiVExTX0VDIikpIHsKKyAgICAgICAgICAgIHN1cHBvcnRlZCA9IGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIGNpcGhlciBzdWl0ZSBpcyBhbm9ueW1vdXMKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNBbm9ueW1vdXMoKSB7CisgICAgICAgIGlmIChrZXlFeGNoYW5nZSA9PSBLRVlfRVhDSEFOR0VfREhfYW5vbgorICAgICAgICAgICAgICAgIHx8IGtleUV4Y2hhbmdlID09IEtFWV9FWENIQU5HRV9ESF9hbm9uX0VYUE9SVAorICAgICAgICAgICAgICAgIHx8IGtleUV4Y2hhbmdlID09IEtFWV9FWENIQU5HRV9FQ0RIX2Fub24pIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFycmF5IG9mIHN1cHBvcnRlZCBDaXBoZXJTdWl0ZXMKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDaXBoZXJTdWl0ZVtdIGdldFN1cHBvcnRlZCgpIHsKKyAgICAgICAgcmV0dXJuIFNVUFBPUlRFRF9DSVBIRVJfU1VJVEVTOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYXJyYXkgb2Ygc3VwcG9ydGVkIGNpcGhlciBzdWl0ZXMgbmFtZXMKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmdbXSBnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZU5hbWVzKCkgeworICAgICAgICByZXR1cm4gU1VQUE9SVEVEX0NJUEhFUl9TVUlURV9OQU1FUy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgY2lwaGVyIHN1aXRlIG5hbWUKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGNpcGhlciBzdWl0ZSBjb2RlIGFzIGJ5dGUgYXJyYXkKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSB0b0J5dGVzKCkgeworICAgICAgICByZXR1cm4gY2lwaGVyU3VpdGVDb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgY2lwaGVyIHN1aXRlIGRlc2NyaXB0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIG5hbWUgKyAiOiAiICsgY2lwaGVyU3VpdGVDb2RlWzBdICsgIiAiICsgY2lwaGVyU3VpdGVDb2RlWzFdOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgY2lwaGVyIGFsZ29yaXRobSBuYW1lCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QnVsa0VuY3J5cHRpb25BbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiBjaXBoZXJOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgY2lwaGVyIGJsb2NrIHNpemUKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRCbG9ja1NpemUoKSB7CisgICAgICAgIHJldHVybiBibG9ja1NpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBNQUMgYWxnb3JpdGhtIG5hbWUKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRIbWFjTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIGhtYWNOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgaGFzaCBhbGdvcml0aG0gbmFtZQorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEhhc2hOYW1lKCkgeworICAgICAgICByZXR1cm4gaGFzaE5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBoYXNoIHNpemUKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNQUNMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBoYXNoU2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIGNpcGhlciBzdWl0ZSBpcyBleHBvcnRhYmxlCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRXhwb3J0YWJsZSgpIHsKKyAgICAgICAgcmV0dXJuIGlzRXhwb3J0YWJsZTsKKyAgICB9CisKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIEtFWV9UWVBFX1JTQSA9ICJSU0EiOworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgS0VZX1RZUEVfRFNBID0gIkRTQSI7CisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBLRVlfVFlQRV9ESF9SU0EgPSAiREhfUlNBIjsKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIEtFWV9UWVBFX0RIX0RTQSA9ICJESF9EU0EiOworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgS0VZX1RZUEVfRUMgPSAiRUMiOworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgS0VZX1RZUEVfRUNfRUMgPSAiRUNfRUMiOworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgS0VZX1RZUEVfRUNfUlNBID0gIkVDX1JTQSI7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGtleSB0eXBlIGNvbnN0YW50IHN1aXRhYmxlIGZvciBjYWxsaW5nCisgICAgICogWDUwOUtleU1hbmFnZXIuY2hvb3NlU2VydmVyQWxpYXMgb3IKKyAgICAgKiBYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyLmNob29zZUVuZ2luZVNlcnZlckFsaWFzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2VydmVyS2V5VHlwZSgpIHsKKyAgICAgICAgc3dpdGNoIChrZXlFeGNoYW5nZSkgeworICAgICAgICAgICAgY2FzZSBLRVlfRVhDSEFOR0VfREhFX1JTQToKKyAgICAgICAgICAgIGNhc2UgS0VZX0VYQ0hBTkdFX0RIRV9SU0FfRVhQT1JUOgorICAgICAgICAgICAgY2FzZSBLRVlfRVhDSEFOR0VfRUNESEVfUlNBOgorICAgICAgICAgICAgY2FzZSBLRVlfRVhDSEFOR0VfUlNBOgorICAgICAgICAgICAgY2FzZSBLRVlfRVhDSEFOR0VfUlNBX0VYUE9SVDoKKyAgICAgICAgICAgICAgICByZXR1cm4gS0VZX1RZUEVfUlNBOworICAgICAgICAgICAgY2FzZSBLRVlfRVhDSEFOR0VfREhFX0RTUzoKKyAgICAgICAgICAgIGNhc2UgS0VZX0VYQ0hBTkdFX0RIRV9EU1NfRVhQT1JUOgorICAgICAgICAgICAgICAgIHJldHVybiBLRVlfVFlQRV9EU0E7CisgICAgICAgICAgICBjYXNlIEtFWV9FWENIQU5HRV9FQ0RIX0VDRFNBOgorICAgICAgICAgICAgY2FzZSBLRVlfRVhDSEFOR0VfRUNESEVfRUNEU0E6CisgICAgICAgICAgICAgICAgcmV0dXJuIEtFWV9UWVBFX0VDX0VDOworICAgICAgICAgICAgY2FzZSBLRVlfRVhDSEFOR0VfRUNESF9SU0E6CisgICAgICAgICAgICAgICAgcmV0dXJuIEtFWV9UWVBFX0VDX1JTQTsKKyAgICAgICAgICAgIGNhc2UgS0VZX0VYQ0hBTkdFX0RIX2Fub246CisgICAgICAgICAgICBjYXNlIEtFWV9FWENIQU5HRV9ESF9hbm9uX0VYUE9SVDoKKyAgICAgICAgICAgIGNhc2UgS0VZX0VYQ0hBTkdFX0VDREhfYW5vbjoKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVW5rbm93biBrZXkgdHlwZSBmb3Iga2V5IGV4Y2hhbmdlICIgKyBrZXlFeGNoYW5nZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbGllbnQgY2VydGlmaWNhdGUgdHlwZXMgYXMgZGVmaW5lZCBpbgorICAgICAqIFRMUyAxLjAgc3BlYy4sIDcuNC40LiBDZXJ0aWZpY2F0ZSByZXF1ZXN0LgorICAgICAqIEVDIGNvbnN0YW50cyBmcm9tIFJGQyA0NDkyLgorICAgICAqIE5hbWVzIG1hdGNoIG9wZW5zc2wgY29uc3RhbnRzLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBieXRlIFRMU19DVF9SU0FfU0lHTiA9IDE7CisgICAgc3RhdGljIGZpbmFsIGJ5dGUgVExTX0NUX0RTU19TSUdOID0gMjsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZSBUTFNfQ1RfUlNBX0ZJWEVEX0RIID0gMzsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZSBUTFNfQ1RfRFNTX0ZJWEVEX0RIID0gNDsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZSBUTFNfQ1RfRUNEU0FfU0lHTiA9IDY0OworICAgIHN0YXRpYyBmaW5hbCBieXRlIFRMU19DVF9SU0FfRklYRURfRUNESCA9IDY1OworICAgIHN0YXRpYyBmaW5hbCBieXRlIFRMU19DVF9FQ0RTQV9GSVhFRF9FQ0RIID0gNjY7CisKKyAgICAvKioKKyAgICAgKiBTaW1pbGFyIHRvIGdldFNlcnZlcktleVR5cGUsIGJ1dCByZXR1cm5zIHZhbHVlIGdpdmVuIFRMUworICAgICAqIENsaWVudENlcnRpZmljYXRlVHlwZSBieXRlIHZhbHVlcyBmcm9tIGEgQ2VydGlmaWNhdGVSZXF1ZXN0CisgICAgICogbWVzc2FnZSBmb3IgdXNlIHdpdGggWDUwOUtleU1hbmFnZXIuY2hvb3NlQ2xpZW50QWxpYXMgb3IKKyAgICAgKiBYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyLmNob29zZUVuZ2luZUNsaWVudEFsaWFzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldENsaWVudEtleVR5cGUoYnl0ZSBrZXlUeXBlKSB7CisgICAgICAgIC8vIFNlZSBhbHNvIGh0dHA6Ly93d3cuaWV0Zi5vcmcvYXNzaWdubWVudHMvdGxzLXBhcmFtZXRlcnMvdGxzLXBhcmFtZXRlcnMueG1sCisgICAgICAgIHN3aXRjaCAoa2V5VHlwZSkgeworICAgICAgICAgICAgY2FzZSBUTFNfQ1RfUlNBX1NJR046CisgICAgICAgICAgICAgICAgcmV0dXJuIEtFWV9UWVBFX1JTQTsgLy8gUkZDIHJzYV9zaWduCisgICAgICAgICAgICBjYXNlIFRMU19DVF9EU1NfU0lHTjoKKyAgICAgICAgICAgICAgICByZXR1cm4gS0VZX1RZUEVfRFNBOyAvLyBSRkMgZHNzX3NpZ24KKyAgICAgICAgICAgIGNhc2UgVExTX0NUX1JTQV9GSVhFRF9ESDoKKyAgICAgICAgICAgICAgICByZXR1cm4gS0VZX1RZUEVfREhfUlNBOyAvLyBSRkMgcnNhX2ZpeGVkX2RoCisgICAgICAgICAgICBjYXNlIFRMU19DVF9EU1NfRklYRURfREg6CisgICAgICAgICAgICAgICAgcmV0dXJuIEtFWV9UWVBFX0RIX0RTQTsgLy8gUkZDIGRzc19maXhlZF9kaAorICAgICAgICAgICAgY2FzZSBUTFNfQ1RfRUNEU0FfU0lHTjoKKyAgICAgICAgICAgICAgICByZXR1cm4gS0VZX1RZUEVfRUM7IC8vIFJGQyBlY2RzYV9zaWduCisgICAgICAgICAgICBjYXNlIFRMU19DVF9SU0FfRklYRURfRUNESDoKKyAgICAgICAgICAgICAgICByZXR1cm4gS0VZX1RZUEVfRUNfUlNBOyAvLyBSRkMgcnNhX2ZpeGVkX2VjZGgKKyAgICAgICAgICAgIGNhc2UgVExTX0NUX0VDRFNBX0ZJWEVEX0VDREg6CisgICAgICAgICAgICAgICAgcmV0dXJuIEtFWV9UWVBFX0VDX0VDOyAvLyBSRkMgZWNkc2FfZml4ZWRfZWNkaAorICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBVVRIX1RZUEVfUlNBID0gIlJTQSI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFVVEhfVFlQRV9SU0FfRVhQT1JUID0gIlJTQV9FWFBPUlQiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBVVRIX1RZUEVfREhFX0RTUyA9ICJESEVfRFNTIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVVUSF9UWVBFX0RIRV9SU0EgPSAiREhFX1JTQSI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFVVEhfVFlQRV9ESF9EU1MgPSAiREhfRFNTIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVVUSF9UWVBFX0RIX1JTQSA9ICJESF9SU0EiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBVVRIX1RZUEVfRUNESF9FQ0RTQSA9ICJFQ0RIX0VDRFNBIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVVUSF9UWVBFX0VDREhfUlNBID0gIkVDREhfUlNBIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVVUSF9UWVBFX0VDREhFX0VDRFNBID0gIkVDREhFX0VDRFNBIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVVUSF9UWVBFX0VDREhFX1JTQSA9ICJFQ0RIRV9SU0EiOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhdXRoIHR5cGUgY29uc3RhbnQgc3VpdGFibGUgZm9yIGNhbGxpbmcgWDUwOVRydXN0TWFuYWdlci5jaGVja1NlcnZlclRydXN0ZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRBdXRoVHlwZShib29sZWFuIGVtcGhlbWVyYWwpIHsKKyAgICAgICAgc3dpdGNoIChrZXlFeGNoYW5nZSkgeworICAgICAgICAgICAgY2FzZSBLRVlfRVhDSEFOR0VfUlNBOgorICAgICAgICAgICAgICAgIHJldHVybiBBVVRIX1RZUEVfUlNBOworICAgICAgICAgICAgY2FzZSBLRVlfRVhDSEFOR0VfUlNBX0VYUE9SVDoKKyAgICAgICAgICAgICAgICByZXR1cm4gZW1waGVtZXJhbCA/IEFVVEhfVFlQRV9SU0FfRVhQT1JUIDogQVVUSF9UWVBFX1JTQTsKKyAgICAgICAgICAgIGNhc2UgS0VZX0VYQ0hBTkdFX0RIRV9EU1M6CisgICAgICAgICAgICBjYXNlIEtFWV9FWENIQU5HRV9ESEVfRFNTX0VYUE9SVDoKKyAgICAgICAgICAgICAgICByZXR1cm4gQVVUSF9UWVBFX0RIRV9EU1M7CisgICAgICAgICAgICBjYXNlIEtFWV9FWENIQU5HRV9ESEVfUlNBOgorICAgICAgICAgICAgY2FzZSBLRVlfRVhDSEFOR0VfREhFX1JTQV9FWFBPUlQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIEFVVEhfVFlQRV9ESEVfUlNBOworICAgICAgICAgICAgY2FzZSBLRVlfRVhDSEFOR0VfRUNESF9FQ0RTQToKKyAgICAgICAgICAgICAgICByZXR1cm4gQVVUSF9UWVBFX0VDREhfRUNEU0E7CisgICAgICAgICAgICBjYXNlIEtFWV9FWENIQU5HRV9FQ0RIRV9FQ0RTQToKKyAgICAgICAgICAgICAgICByZXR1cm4gQVVUSF9UWVBFX0VDREhFX0VDRFNBOworICAgICAgICAgICAgY2FzZSBLRVlfRVhDSEFOR0VfRUNESF9SU0E6CisgICAgICAgICAgICAgICAgcmV0dXJuIEFVVEhfVFlQRV9FQ0RIX1JTQTsKKyAgICAgICAgICAgIGNhc2UgS0VZX0VYQ0hBTkdFX0VDREhFX1JTQToKKyAgICAgICAgICAgICAgICByZXR1cm4gQVVUSF9UWVBFX0VDREhFX1JTQTsKKyAgICAgICAgICAgIGNhc2UgS0VZX0VYQ0hBTkdFX0RIX2Fub246CisgICAgICAgICAgICBjYXNlIEtFWV9FWENIQU5HRV9ESF9hbm9uX0VYUE9SVDoKKyAgICAgICAgICAgIGNhc2UgS0VZX0VYQ0hBTkdFX0VDREhfYW5vbjoKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVW5rbm93biBhdXRoIHR5cGUgZm9yIGtleSBleGNoYW5nZSAiICsga2V5RXhjaGFuZ2UpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQ2xpZW50SGFuZHNoYWtlSW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQ2xpZW50SGFuZHNoYWtlSW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyMWFhMmMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9DbGllbnRIYW5kc2hha2VJbXBsLmphdmEKQEAgLTAsMCArMSw1NzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5RmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZheC5jcnlwdG8uQ2lwaGVyOworaW1wb3J0IGphdmF4LmNyeXB0by5LZXlBZ3JlZW1lbnQ7CitpbXBvcnQgamF2YXguY3J5cHRvLmludGVyZmFjZXMuREhLZXk7CitpbXBvcnQgamF2YXguY3J5cHRvLmludGVyZmFjZXMuREhQdWJsaWNLZXk7CitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuREhQYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLkRIUHVibGljS2V5U3BlYzsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlg1MDlFeHRlbmRlZEtleU1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5YNTA5S2V5TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbDsKKworLyoqCisgKiBDbGllbnQgc2lkZSBoYW5kc2hha2UgcHJvdG9jb2wgaW1wbGVtZW50YXRpb24uCisgKiBIYW5kc2hha2UgcHJvdG9jb2wgb3BlcmF0ZXMgb24gdG9wIG9mIHRoZSBSZWNvcmQgUHJvdG9jb2wuCisgKiBJdCBpcyByZXNwb25zaWJsZSBmb3Igc2Vzc2lvbiBuZWdvdGlhdGluZy4KKyAqCisgKiBUaGUgaW1wbGVtZW50YXRpb24gcHJvY2Vzc2VzIGluYm91bmQgc2VydmVyIGhhbmRzaGFrZSBtZXNzYWdlcywKKyAqIGNyZWF0ZXMgYW5kIHNlbmRzIHJlc3BvbmQgbWVzc2FnZXMuIE91dGJvdW5kIG1lc3NhZ2VzIGFyZSBzdXBwbGllZAorICogdG8gUmVjb3JkIFByb3RvY29sLiBEZXRlY3RlZCBlcnJvcnMgYXJlIHJlcG9ydGVkIHRvIHRoZSBBbGVydCBwcm90b2NvbC4KKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyNDYudHh0Ij5UTFMgMS4wIHNwZWMuLCA3LiBUaGUKKyAqIFRMUyBIYW5kc2hha2UgUHJvdG9jb2w8L2E+CisgKgorICovCitwdWJsaWMgY2xhc3MgQ2xpZW50SGFuZHNoYWtlSW1wbCBleHRlbmRzIEhhbmRzaGFrZVByb3RvY29sIHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgQ2xpZW50IEhhbmRzaGFrZSBJbXBsZW1lbnRhdGlvbgorICAgICAqCisgICAgICogQHBhcmFtIG93bmVyCisgICAgICovCisgICAgQ2xpZW50SGFuZHNoYWtlSW1wbChPYmplY3Qgb3duZXIpIHsKKyAgICAgICAgc3VwZXIob3duZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0YXJ0cyBoYW5kc2hha2UKKyAgICAgKgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHN0YXJ0KCkgeworICAgICAgICBpZiAoc2Vzc2lvbiA9PSBudWxsKSB7IC8vIGluaXRpYWwgaGFuZHNoYWtlCisgICAgICAgICAgICBzZXNzaW9uID0gZmluZFNlc3Npb25Ub1Jlc3VtZSgpOworICAgICAgICB9IGVsc2UgeyAvLyBzdGFydCBzZXNzaW9uIHJlbmVnb3RpYXRpb24KKyAgICAgICAgICAgIGlmIChjbGllbnRIZWxsbyAhPSBudWxsICYmIHRoaXMuc3RhdHVzICE9IEZJTklTSEVEKSB7CisgICAgICAgICAgICAgICAgLy8gY3VycmVudCBuZWdvdGlhdGlvbiBoYXMgbm90IGNvbXBsZXRlZAorICAgICAgICAgICAgICAgIHJldHVybjsgLy8gaWdub3JlCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIXNlc3Npb24uaXNWYWxpZCgpKSB7CisgICAgICAgICAgICAgICAgc2Vzc2lvbiA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNlc3Npb24gIT0gbnVsbCkgeworICAgICAgICAgICAgaXNSZXN1bWluZyA9IHRydWU7CisgICAgICAgIH0gZWxzZSBpZiAocGFyYW1ldGVycy5nZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oKSl7CisgICAgICAgICAgICBpc1Jlc3VtaW5nID0gZmFsc2U7CisgICAgICAgICAgICBzZXNzaW9uID0gbmV3IFNTTFNlc3Npb25JbXBsKHBhcmFtZXRlcnMuZ2V0U2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAgaWYgKGVuZ2luZU93bmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXNzaW9uLnNldFBlZXIoZW5naW5lT3duZXIuZ2V0UGVlckhvc3QoKSwgZW5naW5lT3duZXIuZ2V0UGVlclBvcnQoKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHNlc3Npb24uc2V0UGVlcihzb2NrZXRPd25lci5nZXRJbmV0QWRkcmVzcygpLmdldEhvc3ROYW1lKCksIHNvY2tldE93bmVyLmdldFBvcnQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzZXNzaW9uLnByb3RvY29sID0gUHJvdG9jb2xWZXJzaW9uLmdldExhdGVzdFZlcnNpb24ocGFyYW1ldGVycy5nZXRFbmFibGVkUHJvdG9jb2xzKCkpOworICAgICAgICAgICAgcmVjb3JkUHJvdG9jb2wuc2V0VmVyc2lvbihzZXNzaW9uLnByb3RvY29sLnZlcnNpb24pOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLkhBTkRTSEFLRV9GQUlMVVJFLCAiU1NMIFNlc3Npb24gbWF5IG5vdCBiZSBjcmVhdGVkICIpOworICAgICAgICB9CisgICAgICAgIHN0YXJ0U2Vzc2lvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0YXJ0cyByZW5lZ290aWF0aW9uIG9uIGEgbmV3IHNlc3Npb24KKyAgICAgKgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZW5lZ290aWF0ZU5ld1Nlc3Npb24oKSB7CisgICAgICAgIGlmIChwYXJhbWV0ZXJzLmdldEVuYWJsZVNlc3Npb25DcmVhdGlvbigpKXsKKyAgICAgICAgICAgIGlzUmVzdW1pbmcgPSBmYWxzZTsKKyAgICAgICAgICAgIHNlc3Npb24gPSBuZXcgU1NMU2Vzc2lvbkltcGwocGFyYW1ldGVycy5nZXRTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICBpZiAoZW5naW5lT3duZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlc3Npb24uc2V0UGVlcihlbmdpbmVPd25lci5nZXRQZWVySG9zdCgpLCBlbmdpbmVPd25lci5nZXRQZWVyUG9ydCgpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc2Vzc2lvbi5zZXRQZWVyKHNvY2tldE93bmVyLmdldEluZXRBZGRyZXNzKCkuZ2V0SG9zdE5hbWUoKSwgc29ja2V0T3duZXIuZ2V0UG9ydCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNlc3Npb24ucHJvdG9jb2wgPSBQcm90b2NvbFZlcnNpb24uZ2V0TGF0ZXN0VmVyc2lvbihwYXJhbWV0ZXJzLmdldEVuYWJsZWRQcm90b2NvbHMoKSk7CisgICAgICAgICAgICByZWNvcmRQcm90b2NvbC5zZXRWZXJzaW9uKHNlc3Npb24ucHJvdG9jb2wudmVyc2lvbik7CisgICAgICAgICAgICBzdGFydFNlc3Npb24oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHN0YXR1cyA9IE5PVF9IQU5EU0hBS0lORzsKKyAgICAgICAgICAgIHNlbmRXYXJuaW5nQWxlcnQoQWxlcnRQcm90b2NvbC5OT19SRU5FR09USUFUSU9OKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogU3RhcnRzL3Jlc3VtZXMgc2Vzc2lvbgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzdGFydFNlc3Npb24oKSB7CisgICAgICAgIENpcGhlclN1aXRlW10gY2lwaGVyX3N1aXRlczsKKyAgICAgICAgaWYgKGlzUmVzdW1pbmcpIHsKKyAgICAgICAgICAgIGNpcGhlcl9zdWl0ZXMgPSBuZXcgQ2lwaGVyU3VpdGVbXSB7IHNlc3Npb24uY2lwaGVyU3VpdGUgfTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNpcGhlcl9zdWl0ZXMgPSBwYXJhbWV0ZXJzLmdldEVuYWJsZWRDaXBoZXJTdWl0ZXNNZW1iZXIoKTsKKyAgICAgICAgfQorICAgICAgICBjbGllbnRIZWxsbyA9IG5ldyBDbGllbnRIZWxsbyhwYXJhbWV0ZXJzLmdldFNlY3VyZVJhbmRvbSgpLAorICAgICAgICAgICAgICAgIHNlc3Npb24ucHJvdG9jb2wudmVyc2lvbiwgc2Vzc2lvbi5pZCwgY2lwaGVyX3N1aXRlcyk7CisgICAgICAgIHNlc3Npb24uY2xpZW50UmFuZG9tID0gY2xpZW50SGVsbG8ucmFuZG9tOworICAgICAgICBzZW5kKGNsaWVudEhlbGxvKTsKKyAgICAgICAgc3RhdHVzID0gTkVFRF9VTldSQVA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2Vzc2VzIGluYm91bmQgaGFuZHNoYWtlIG1lc3NhZ2VzCisgICAgICogQHBhcmFtIGJ5dGVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgdW53cmFwKGJ5dGVbXSBieXRlcykgeworICAgICAgICBpZiAodGhpcy5kZWxlZ2F0ZWRUYXNrRXJyICE9IG51bGwpIHsKKyAgICAgICAgICAgIEV4Y2VwdGlvbiBlID0gdGhpcy5kZWxlZ2F0ZWRUYXNrRXJyOworICAgICAgICAgICAgdGhpcy5kZWxlZ2F0ZWRUYXNrRXJyID0gbnVsbDsKKyAgICAgICAgICAgIHRoaXMuZmF0YWxBbGVydChBbGVydFByb3RvY29sLkhBTkRTSEFLRV9GQUlMVVJFLCAiRXJyb3IgaW4gZGVsZWdhdGVkIHRhc2siLCBlKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgaGFuZHNoYWtlVHlwZTsKKyAgICAgICAgaW9fc3RyZWFtLmFwcGVuZChieXRlcyk7CisgICAgICAgIHdoaWxlIChpb19zdHJlYW0uYXZhaWxhYmxlKCkgPiAwKSB7CisgICAgICAgICAgICBpb19zdHJlYW0ubWFyaygpOworICAgICAgICAgICAgaW50IGxlbmd0aDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaGFuZHNoYWtlVHlwZSA9IGlvX3N0cmVhbS5yZWFkKCk7CisgICAgICAgICAgICAgICAgbGVuZ3RoID0gaW9fc3RyZWFtLnJlYWRVaW50MjQoKTsKKyAgICAgICAgICAgICAgICBpZiAoaW9fc3RyZWFtLmF2YWlsYWJsZSgpIDwgbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIGlvX3N0cmVhbS5yZXNldCgpOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHN3aXRjaCAoaGFuZHNoYWtlVHlwZSkgeworICAgICAgICAgICAgICAgIGNhc2UgMDogLy8gSEVMTE9fUkVRVUVTVAorICAgICAgICAgICAgICAgICAgICAvLyB3ZSBkb24ndCBuZWVkIHRvIHRha2UgdGhpcyBtZXNzYWdlIGludG8gYWNjb3VudAorICAgICAgICAgICAgICAgICAgICAvLyBkdXJpbmcgRklOSVNIIG1lc3NhZ2UgdmVyaWZpY2F0aW9uLCBzbyByZW1vdmUgaXQKKyAgICAgICAgICAgICAgICAgICAgaW9fc3RyZWFtLnJlbW92ZUZyb21NYXJrZWRQb3NpdGlvbigpOworICAgICAgICAgICAgICAgICAgICBpZiAoY2xpZW50SGVsbG8gIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIChjbGllbnRGaW5pc2hlZCA9PSBudWxsIHx8IHNlcnZlckZpbmlzaGVkID09IG51bGwpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvL2N1cnJlbnRseSBuZWdvdGlhdGluZyAtIGlnbm9yZQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgLy8gcmVuZWdvdGlhdGUKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNlc3Npb24uaXNWYWxpZCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uID0gKFNTTFNlc3Npb25JbXBsKSBzZXNzaW9uLmNsb25lKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpc1Jlc3VtaW5nID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0U2Vzc2lvbigpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgU1NMU2Vzc2lvbiBpcyBpbnZhbGlkYXRlZCAoZS5nLiB0aW1lb3V0IGxpbWl0IGlzCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBleGNlZWRlZCkgY29ubmVjdGlvbiBjYW4ndCByZXN1bWUgdGhlIHNlc3Npb24uCisgICAgICAgICAgICAgICAgICAgICAgICByZW5lZ290aWF0ZU5ld1Nlc3Npb24oKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIDI6IC8vIFNFUlZFUl9IRUxMTworICAgICAgICAgICAgICAgICAgICBpZiAoY2xpZW50SGVsbG8gPT0gbnVsbCB8fCBzZXJ2ZXJIZWxsbyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB1bmV4cGVjdGVkTWVzc2FnZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHNlcnZlckhlbGxvID0gbmV3IFNlcnZlckhlbGxvKGlvX3N0cmVhbSwgbGVuZ3RoKTsKKworICAgICAgICAgICAgICAgICAgICAvL2NoZWNrIHByb3RvY29sIHZlcnNpb24KKyAgICAgICAgICAgICAgICAgICAgUHJvdG9jb2xWZXJzaW9uIHNlcnZQcm90ID0gUHJvdG9jb2xWZXJzaW9uLmdldEJ5VmVyc2lvbihzZXJ2ZXJIZWxsby5zZXJ2ZXJfdmVyc2lvbik7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZ1tdIGVuYWJsZWQgPSBwYXJhbWV0ZXJzLmdldEVuYWJsZWRQcm90b2NvbHMoKTsKKyAgICAgICAgICAgICAgICAgICAgZmluZDogeworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbmFibGVkLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlcnZQcm90LmVxdWFscyhQcm90b2NvbFZlcnNpb24uZ2V0QnlOYW1lKGVuYWJsZWRbaV0pKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBmaW5kOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5IQU5EU0hBS0VfRkFJTFVSRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJhZCBzZXJ2ZXIgaGVsbG8gcHJvdG9jb2wgdmVyc2lvbiIpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgY29tcHJlc3Npb24gbWV0aG9kCisgICAgICAgICAgICAgICAgICAgIGlmIChzZXJ2ZXJIZWxsby5jb21wcmVzc2lvbl9tZXRob2QgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLkhBTkRTSEFLRV9GQUlMVVJFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQmFkIHNlcnZlciBoZWxsbyBjb21wcmVzc2lvbiBtZXRob2QiKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vY2hlY2sgY2lwaGVyX3N1aXRlCisgICAgICAgICAgICAgICAgICAgIENpcGhlclN1aXRlW10gZW5hYmxlZFN1aXRlcyA9IHBhcmFtZXRlcnMuZ2V0RW5hYmxlZENpcGhlclN1aXRlc01lbWJlcigpOworICAgICAgICAgICAgICAgICAgICBmaW5kOiB7CisgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVuYWJsZWRTdWl0ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VydmVySGVsbG8uY2lwaGVyX3N1aXRlLmVxdWFscyhlbmFibGVkU3VpdGVzW2ldKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBmaW5kOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5IQU5EU0hBS0VfRkFJTFVSRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJhZCBzZXJ2ZXIgaGVsbG8gY2lwaGVyIHN1aXRlIik7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBpZiAoaXNSZXN1bWluZykgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlcnZlckhlbGxvLnNlc3Npb25faWQubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzZXJ2ZXIgaXMgbm90IHdpbGxpbmcgdG8gZXN0YWJsaXNoIHRoZSBuZXcgY29ubmVjdGlvbgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVzaW5nIHNwZWNpZmllZCBzZXNzaW9uCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNSZXN1bWluZyA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghQXJyYXlzLmVxdWFscyhzZXJ2ZXJIZWxsby5zZXNzaW9uX2lkLCBjbGllbnRIZWxsby5zZXNzaW9uX2lkKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzUmVzdW1pbmcgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXNlc3Npb24ucHJvdG9jb2wuZXF1YWxzKHNlcnZQcm90KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5IQU5EU0hBS0VfRkFJTFVSRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJCYWQgc2VydmVyIGhlbGxvIHByb3RvY29sIHZlcnNpb24iKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXNlc3Npb24uY2lwaGVyU3VpdGUuZXF1YWxzKHNlcnZlckhlbGxvLmNpcGhlcl9zdWl0ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuSEFORFNIQUtFX0ZBSUxVUkUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQmFkIHNlcnZlciBoZWxsbyBjaXBoZXIgc3VpdGUiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZXJ2ZXJIZWxsby5zZXJ2ZXJfdmVyc2lvblsxXSA9PSAxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcHV0ZXJSZWZlcmVuY2VWZXJpZnlEYXRhVExTKCJzZXJ2ZXIgZmluaXNoZWQiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcHV0ZXJSZWZlcmVuY2VWZXJpZnlEYXRhU1NMdjMoU1NMdjNDb25zdGFudHMuc2VydmVyKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLnByb3RvY29sID0gc2VydlByb3Q7CisgICAgICAgICAgICAgICAgICAgIHJlY29yZFByb3RvY29sLnNldFZlcnNpb24oc2Vzc2lvbi5wcm90b2NvbC52ZXJzaW9uKTsKKyAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5jaXBoZXJTdWl0ZSA9IHNlcnZlckhlbGxvLmNpcGhlcl9zdWl0ZTsKKyAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5pZCA9IHNlcnZlckhlbGxvLnNlc3Npb25faWQuY2xvbmUoKTsKKyAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5zZXJ2ZXJSYW5kb20gPSBzZXJ2ZXJIZWxsby5yYW5kb207CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgMTE6IC8vIENFUlRJRklDQVRFCisgICAgICAgICAgICAgICAgICAgIGlmIChzZXJ2ZXJIZWxsbyA9PSBudWxsIHx8IHNlcnZlcktleUV4Y2hhbmdlICE9IG51bGwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBzZXJ2ZXJDZXJ0ICE9IG51bGwgfHwgaXNSZXN1bWluZykgeworICAgICAgICAgICAgICAgICAgICAgICAgdW5leHBlY3RlZE1lc3NhZ2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJDZXJ0ID0gbmV3IENlcnRpZmljYXRlTWVzc2FnZShpb19zdHJlYW0sIGxlbmd0aCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgMTI6IC8vIFNFUlZFUl9LRVlfRVhDSEFOR0UKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNlcnZlckhlbGxvID09IG51bGwgfHwgc2VydmVyS2V5RXhjaGFuZ2UgIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGlzUmVzdW1pbmcpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHVuZXhwZWN0ZWRNZXNzYWdlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgc2VydmVyS2V5RXhjaGFuZ2UgPSBuZXcgU2VydmVyS2V5RXhjaGFuZ2UoaW9fc3RyZWFtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCwgc2Vzc2lvbi5jaXBoZXJTdWl0ZS5rZXlFeGNoYW5nZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgMTM6IC8vIENFUlRJRklDQVRFX1JFUVVFU1QKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNlcnZlckNlcnQgPT0gbnVsbCB8fCBjZXJ0aWZpY2F0ZVJlcXVlc3QgIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHNlc3Npb24uY2lwaGVyU3VpdGUuaXNBbm9ueW1vdXMoKSB8fCBpc1Jlc3VtaW5nKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB1bmV4cGVjdGVkTWVzc2FnZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGNlcnRpZmljYXRlUmVxdWVzdCA9IG5ldyBDZXJ0aWZpY2F0ZVJlcXVlc3QoaW9fc3RyZWFtLCBsZW5ndGgpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIDE0OiAvLyBTRVJWRVJfSEVMTE9fRE9ORQorICAgICAgICAgICAgICAgICAgICBpZiAoc2VydmVySGVsbG8gPT0gbnVsbCB8fCBzZXJ2ZXJIZWxsb0RvbmUgIT0gbnVsbCB8fCBpc1Jlc3VtaW5nKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB1bmV4cGVjdGVkTWVzc2FnZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHNlcnZlckhlbGxvRG9uZSA9IG5ldyBTZXJ2ZXJIZWxsb0RvbmUoaW9fc3RyZWFtLCBsZW5ndGgpOworICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5ub25CbG9ja2luZykgeworICAgICAgICAgICAgICAgICAgICAgICAgZGVsZWdhdGVkVGFza3MuYWRkKG5ldyBEZWxlZ2F0ZWRUYXNrKG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NTZXJ2ZXJIZWxsb0RvbmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9LCB0aGlzKSk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc1NlcnZlckhlbGxvRG9uZSgpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIDIwOiAvLyBGSU5JU0hFRAorICAgICAgICAgICAgICAgICAgICBpZiAoIWNoYW5nZUNpcGhlclNwZWNSZWNlaXZlZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgdW5leHBlY3RlZE1lc3NhZ2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJGaW5pc2hlZCA9IG5ldyBGaW5pc2hlZChpb19zdHJlYW0sIGxlbmd0aCk7CisgICAgICAgICAgICAgICAgICAgIHZlcmlmeUZpbmlzaGVkKHNlcnZlckZpbmlzaGVkLmdldERhdGEoKSk7CisgICAgICAgICAgICAgICAgICAgIHNlc3Npb24ubGFzdEFjY2Vzc2VkVGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmNvbnRleHQgPSBwYXJhbWV0ZXJzLmdldENsaWVudFNlc3Npb25Db250ZXh0KCk7CisgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuZ2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKS5wdXRTZXNzaW9uKHNlc3Npb24pOworICAgICAgICAgICAgICAgICAgICBpZiAoaXNSZXN1bWluZykgeworICAgICAgICAgICAgICAgICAgICAgICAgc2VuZENoYW5nZUNpcGhlclNwZWMoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24ubGFzdEFjY2Vzc2VkVGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gRklOSVNIRUQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgLy8gWFhYIHRoZXJlIGlzIG5vIGNsZWFudXAgd29yaworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICB1bmV4cGVjdGVkTWVzc2FnZSgpOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGlvIHN0cmVhbSBkb3NuJ3QgY29udGFpbiBjb21wbGV0ZSBoYW5kc2hha2UgbWVzc2FnZQorICAgICAgICAgICAgICAgIGlvX3N0cmVhbS5yZXNldCgpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2Vzc2VzIFNTTHYyIEhlbGxvIG1lc3NhZ2UuCisgICAgICogU1NMdjIgY2xpZW50IGhlbGxvIG1lc3NhZ2UgbWVzc2FnZSBpcyBhbiB1bmV4cGVjdGVkIG1lc3NhZ2UKKyAgICAgKiBmb3IgY2xpZW50IHNpZGUgb2YgaGFuZHNoYWtlIHByb3RvY29sLgorICAgICAqIEAgc2VlIFRMUyAxLjAgc3BlYy4sIEUuMS4gVmVyc2lvbiAyIGNsaWVudCBoZWxsbworICAgICAqIEBwYXJhbSBieXRlcworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHVud3JhcFNTTHYyKGJ5dGVbXSBieXRlcykgeworICAgICAgICB1bmV4cGVjdGVkTWVzc2FnZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW5kIHNlbmRzIEZpbmlzaGVkIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBtYWtlRmluaXNoZWQoKSB7CisgICAgICAgIGJ5dGVbXSB2ZXJpZnlfZGF0YTsKKyAgICAgICAgaWYgKHNlcnZlckhlbGxvLnNlcnZlcl92ZXJzaW9uWzFdID09IDEpIHsKKyAgICAgICAgICAgIHZlcmlmeV9kYXRhID0gbmV3IGJ5dGVbMTJdOworICAgICAgICAgICAgY29tcHV0ZXJWZXJpZnlEYXRhVExTKCJjbGllbnQgZmluaXNoZWQiLCB2ZXJpZnlfZGF0YSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB2ZXJpZnlfZGF0YSA9IG5ldyBieXRlWzM2XTsKKyAgICAgICAgICAgIGNvbXB1dGVyVmVyaWZ5RGF0YVNTTHYzKFNTTHYzQ29uc3RhbnRzLmNsaWVudCwgdmVyaWZ5X2RhdGEpOworICAgICAgICB9CisgICAgICAgIGNsaWVudEZpbmlzaGVkID0gbmV3IEZpbmlzaGVkKHZlcmlmeV9kYXRhKTsKKyAgICAgICAgc2VuZChjbGllbnRGaW5pc2hlZCk7CisgICAgICAgIGlmIChpc1Jlc3VtaW5nKSB7CisgICAgICAgICAgICBzZXNzaW9uLmxhc3RBY2Nlc3NlZFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgICAgIHN0YXR1cyA9IEZJTklTSEVEOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKHNlcnZlckhlbGxvLnNlcnZlcl92ZXJzaW9uWzFdID09IDEpIHsKKyAgICAgICAgICAgICAgICBjb21wdXRlclJlZmVyZW5jZVZlcmlmeURhdGFUTFMoInNlcnZlciBmaW5pc2hlZCIpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBjb21wdXRlclJlZmVyZW5jZVZlcmlmeURhdGFTU0x2MyhTU0x2M0NvbnN0YW50cy5zZXJ2ZXIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3RhdHVzID0gTkVFRF9VTldSQVA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgU2VydmVySGVsbG9Eb25lOiBtYWtlcyB2ZXJpZmljYXRpb24gb2YgdGhlIHNlcnZlciBtZXNzYWdlczsgc2VuZHMKKyAgICAgKiBjbGllbnQgbWVzc2FnZXMsIGNvbXB1dGVycyBtYXN0ZXJTZWNyZXQsIHNlbmRzIENoYW5nZUNpcGhlclNwZWMKKyAgICAgKi8KKyAgICB2b2lkIHByb2Nlc3NTZXJ2ZXJIZWxsb0RvbmUoKSB7CisgICAgICAgIFByaXZhdGVLZXkgY2xpZW50S2V5ID0gbnVsbDsKKworICAgICAgICBpZiAoc2VydmVyQ2VydCAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoc2Vzc2lvbi5jaXBoZXJTdWl0ZS5pc0Fub255bW91cygpKSB7CisgICAgICAgICAgICAgICAgdW5leHBlY3RlZE1lc3NhZ2UoKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICB2ZXJpZnlTZXJ2ZXJDZXJ0KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpZiAoIXNlc3Npb24uY2lwaGVyU3VpdGUuaXNBbm9ueW1vdXMoKSkgeworICAgICAgICAgICAgICAgIHVuZXhwZWN0ZWRNZXNzYWdlKCk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gQ2xpZW50IGNlcnRpZmljYXRlCisgICAgICAgIGlmIChjZXJ0aWZpY2F0ZVJlcXVlc3QgIT0gbnVsbCkgeworICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlW10gY2VydHMgPSBudWxsOworICAgICAgICAgICAgLy8gb2J0YWluIGNlcnRpZmljYXRlcyBmcm9tIGtleSBtYW5hZ2VyCisgICAgICAgICAgICBTdHJpbmcgYWxpYXMgPSBudWxsOworICAgICAgICAgICAgU3RyaW5nW10gY2VydFR5cGVzID0gY2VydGlmaWNhdGVSZXF1ZXN0LmdldFR5cGVzQXNTdHJpbmcoKTsKKyAgICAgICAgICAgIFg1MDBQcmluY2lwYWxbXSBpc3N1ZXJzID0gY2VydGlmaWNhdGVSZXF1ZXN0LmNlcnRpZmljYXRlX2F1dGhvcml0aWVzOworICAgICAgICAgICAgWDUwOUtleU1hbmFnZXIga20gPSBwYXJhbWV0ZXJzLmdldEtleU1hbmFnZXIoKTsKKyAgICAgICAgICAgIGlmIChrbSBpbnN0YW5jZW9mIFg1MDlFeHRlbmRlZEtleU1hbmFnZXIpIHsKKyAgICAgICAgICAgICAgICBYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyIGVrbSA9IChYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyKWttOworICAgICAgICAgICAgICAgIGlmICh0aGlzLnNvY2tldE93bmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYWxpYXMgPSBla20uY2hvb3NlQ2xpZW50QWxpYXMoY2VydFR5cGVzLCBpc3N1ZXJzLCB0aGlzLnNvY2tldE93bmVyKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBhbGlhcyA9IGVrbS5jaG9vc2VFbmdpbmVDbGllbnRBbGlhcyhjZXJ0VHlwZXMsIGlzc3VlcnMsIHRoaXMuZW5naW5lT3duZXIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoYWxpYXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBjZXJ0cyA9IGVrbS5nZXRDZXJ0aWZpY2F0ZUNoYWluKGFsaWFzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFsaWFzID0ga20uY2hvb3NlQ2xpZW50QWxpYXMoY2VydFR5cGVzLCBpc3N1ZXJzLCB0aGlzLnNvY2tldE93bmVyKTsKKyAgICAgICAgICAgICAgICBpZiAoYWxpYXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBjZXJ0cyA9IGttLmdldENlcnRpZmljYXRlQ2hhaW4oYWxpYXMpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc2Vzc2lvbi5sb2NhbENlcnRpZmljYXRlcyA9IGNlcnRzOworICAgICAgICAgICAgY2xpZW50Q2VydCA9IG5ldyBDZXJ0aWZpY2F0ZU1lc3NhZ2UoY2VydHMpOworICAgICAgICAgICAgY2xpZW50S2V5ID0ga20uZ2V0UHJpdmF0ZUtleShhbGlhcyk7CisgICAgICAgICAgICBzZW5kKGNsaWVudENlcnQpOworICAgICAgICB9CisgICAgICAgIC8vIENsaWVudCBrZXkgZXhjaGFuZ2UKKyAgICAgICAgaWYgKHNlc3Npb24uY2lwaGVyU3VpdGUua2V5RXhjaGFuZ2UgPT0gQ2lwaGVyU3VpdGUuS0VZX0VYQ0hBTkdFX1JTQQorICAgICAgICAgICAgICAgIHx8IHNlc3Npb24uY2lwaGVyU3VpdGUua2V5RXhjaGFuZ2UgPT0gQ2lwaGVyU3VpdGUuS0VZX0VYQ0hBTkdFX1JTQV9FWFBPUlQpIHsKKyAgICAgICAgICAgIC8vIFJTQSBlbmNyeXB0ZWQgcHJlbWFzdGVyIHNlY3JldCBtZXNzYWdlCisgICAgICAgICAgICBDaXBoZXIgYzsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiUlNBL0VDQi9QS0NTMVBhZGRpbmciKTsKKyAgICAgICAgICAgICAgICBpZiAoc2VydmVyS2V5RXhjaGFuZ2UgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgc2VydmVyS2V5RXhjaGFuZ2UKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0UlNBUHVibGljS2V5KCkpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGMuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBzZXJ2ZXJDZXJ0LmNlcnRzWzBdKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5JTlRFUk5BTF9FUlJPUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHByZU1hc3RlclNlY3JldCA9IG5ldyBieXRlWzQ4XTsKKyAgICAgICAgICAgIHBhcmFtZXRlcnMuZ2V0U2VjdXJlUmFuZG9tKCkubmV4dEJ5dGVzKHByZU1hc3RlclNlY3JldCk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNsaWVudEhlbGxvLmNsaWVudF92ZXJzaW9uLCAwLCBwcmVNYXN0ZXJTZWNyZXQsIDAsIDIpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjbGllbnRLZXlFeGNoYW5nZSA9IG5ldyBDbGllbnRLZXlFeGNoYW5nZShjCisgICAgICAgICAgICAgICAgICAgICAgICAuZG9GaW5hbChwcmVNYXN0ZXJTZWNyZXQpLAorICAgICAgICAgICAgICAgICAgICAgICAgc2VydmVySGVsbG8uc2VydmVyX3ZlcnNpb25bMV0gPT0gMSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5JTlRFUk5BTF9FUlJPUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5RmFjdG9yeSBrZiA9IEtleUZhY3RvcnkuZ2V0SW5zdGFuY2UoIkRIIik7CisgICAgICAgICAgICAgICAgS2V5QWdyZWVtZW50IGFncmVlbWVudCA9IEtleUFncmVlbWVudC5nZXRJbnN0YW5jZSgiREgiKTsKKyAgICAgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGtwZyA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRIIik7CisgICAgICAgICAgICAgICAgUHVibGljS2V5IHNlcnZlclB1YmxpYzsKKyAgICAgICAgICAgICAgICBESFBhcmFtZXRlclNwZWMgc3BlYzsKKyAgICAgICAgICAgICAgICBpZiAoc2VydmVyS2V5RXhjaGFuZ2UgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJQdWJsaWMgPSBrZi5nZW5lcmF0ZVB1YmxpYyhuZXcgREhQdWJsaWNLZXlTcGVjKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZlcktleUV4Y2hhbmdlLnBhcjMsIHNlcnZlcktleUV4Y2hhbmdlLnBhcjEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VydmVyS2V5RXhjaGFuZ2UucGFyMikpOworICAgICAgICAgICAgICAgICAgICBzcGVjID0gbmV3IERIUGFyYW1ldGVyU3BlYyhzZXJ2ZXJLZXlFeGNoYW5nZS5wYXIxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZlcktleUV4Y2hhbmdlLnBhcjIpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHNlcnZlclB1YmxpYyA9IHNlcnZlckNlcnQuY2VydHNbMF0uZ2V0UHVibGljS2V5KCk7CisgICAgICAgICAgICAgICAgICAgIHNwZWMgPSAoKERIUHVibGljS2V5KSBzZXJ2ZXJQdWJsaWMpLmdldFBhcmFtcygpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBrcGcuaW5pdGlhbGl6ZShzcGVjKTsKKworICAgICAgICAgICAgICAgIEtleVBhaXIga3AgPSBrcGcuZ2VuZXJhdGVLZXlQYWlyKCk7CisgICAgICAgICAgICAgICAgS2V5IGtleSA9IGtwLmdldFB1YmxpYygpOworICAgICAgICAgICAgICAgIGlmIChjbGllbnRDZXJ0ICE9IG51bGwKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIHNlcnZlckNlcnQgIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgJiYgKHNlc3Npb24uY2lwaGVyU3VpdGUua2V5RXhjaGFuZ2UgPT0gQ2lwaGVyU3VpdGUuS0VZX0VYQ0hBTkdFX0RIRV9SU0EKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgc2Vzc2lvbi5jaXBoZXJTdWl0ZS5rZXlFeGNoYW5nZSA9PSBDaXBoZXJTdWl0ZS5LRVlfRVhDSEFOR0VfREhFX0RTUykpIHsKKyAgICAgICAgICAgICAgICAgICAgUHVibGljS2V5IGNsaWVudF9wayA9IGNsaWVudENlcnQuY2VydHNbMF0uZ2V0UHVibGljS2V5KCk7CisgICAgICAgICAgICAgICAgICAgIFB1YmxpY0tleSBzZXJ2ZXJfcGsgPSBzZXJ2ZXJDZXJ0LmNlcnRzWzBdLmdldFB1YmxpY0tleSgpOworICAgICAgICAgICAgICAgICAgICBpZiAoY2xpZW50X3BrIGluc3RhbmNlb2YgREhLZXkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBzZXJ2ZXJfcGsgaW5zdGFuY2VvZiBESEtleSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoREhLZXkpIGNsaWVudF9waykuZ2V0UGFyYW1zKCkuZ2V0RygpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChESEtleSkgc2VydmVyX3BrKS5nZXRQYXJhbXMoKS5nZXRHKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmICgoREhLZXkpIGNsaWVudF9waykuZ2V0UGFyYW1zKCkuZ2V0UCgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKCgoREhLZXkpIHNlcnZlcl9waykuZ2V0UGFyYW1zKCkuZ2V0RygpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsaWVudCBjZXJ0IG1lc3NhZ2UgREggcHVibGljIGtleSBwYXJhbWV0ZXJzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWF0Y2hlZCB0aG9zZSBzcGVjaWZpZWQgYnkgdGhlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICBzZXJ2ZXIgaW4gaXRzIGNlcnRpZmljYXRlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudEtleUV4Y2hhbmdlID0gbmV3IENsaWVudEtleUV4Y2hhbmdlKCk7IC8vIGVtcHR5CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBjbGllbnRLZXlFeGNoYW5nZSA9IG5ldyBDbGllbnRLZXlFeGNoYW5nZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKERIUHVibGljS2V5KSBrZXkpLmdldFkoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGtleSA9IGtwLmdldFByaXZhdGUoKTsKKyAgICAgICAgICAgICAgICBhZ3JlZW1lbnQuaW5pdChrZXkpOworICAgICAgICAgICAgICAgIGFncmVlbWVudC5kb1BoYXNlKHNlcnZlclB1YmxpYywgdHJ1ZSk7CisgICAgICAgICAgICAgICAgcHJlTWFzdGVyU2VjcmV0ID0gYWdyZWVtZW50LmdlbmVyYXRlU2VjcmV0KCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5JTlRFUk5BTF9FUlJPUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoY2xpZW50S2V5RXhjaGFuZ2UgIT0gbnVsbCkgeworICAgICAgICAgICAgc2VuZChjbGllbnRLZXlFeGNoYW5nZSk7CisgICAgICAgIH0KKworICAgICAgICBjb21wdXRlck1hc3RlclNlY3JldCgpOworCisgICAgICAgIC8vIHNlbmQgY2VydGlmaWNhdGUgdmVyaWZ5IGZvciBhbGwgY2VydGlmaWNhdGVzIGV4Y2VwdCB0aG9zZSBjb250YWluaW5nCisgICAgICAgIC8vIGZpeGVkIERIIHBhcmFtZXRlcnMKKyAgICAgICAgaWYgKGNsaWVudENlcnQgIT0gbnVsbCAmJiAhY2xpZW50S2V5RXhjaGFuZ2UuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAvLyBDZXJ0aWZpY2F0ZSB2ZXJpZnkKKyAgICAgICAgICAgIFN0cmluZyBhdXRoVHlwZSA9IGNsaWVudEtleS5nZXRBbGdvcml0aG0oKTsKKyAgICAgICAgICAgIERpZ2l0YWxTaWduYXR1cmUgZHMgPSBuZXcgRGlnaXRhbFNpZ25hdHVyZShhdXRoVHlwZSk7CisgICAgICAgICAgICBkcy5pbml0KGNsaWVudEtleSk7CisKKyAgICAgICAgICAgIGlmICgiUlNBIi5lcXVhbHMoYXV0aFR5cGUpKSB7CisgICAgICAgICAgICAgICAgZHMuc2V0TUQ1KGlvX3N0cmVhbS5nZXREaWdlc3RNRDUoKSk7CisgICAgICAgICAgICAgICAgZHMuc2V0U0hBKGlvX3N0cmVhbS5nZXREaWdlc3RTSEEoKSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKCJEU0EiLmVxdWFscyhhdXRoVHlwZSkpIHsKKyAgICAgICAgICAgICAgICBkcy5zZXRTSEEoaW9fc3RyZWFtLmdldERpZ2VzdFNIQSgpKTsKKyAgICAgICAgICAgIC8vIFRoZSBTaWduYXR1cmUgc2hvdWxkIGJlIGVtcHR5IGluIGNhc2Ugb2YgYW5vbnltb3VzIHNpZ25hdHVyZSBhbGdvcml0aG06CisgICAgICAgICAgICAvLyB9IGVsc2UgaWYgKCJESCIuZXF1YWxzKGF1dGhUeXBlKSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2VydGlmaWNhdGVWZXJpZnkgPSBuZXcgQ2VydGlmaWNhdGVWZXJpZnkoZHMuc2lnbigpKTsKKyAgICAgICAgICAgIHNlbmQoY2VydGlmaWNhdGVWZXJpZnkpOworICAgICAgICB9CisKKyAgICAgICAgc2VuZENoYW5nZUNpcGhlclNwZWMoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFZlcmlmaWVzIGNlcnRpZmljYXRlIHBhdGgKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgdmVyaWZ5U2VydmVyQ2VydCgpIHsKKyAgICAgICAgU3RyaW5nIGF1dGhUeXBlID0gc2Vzc2lvbi5jaXBoZXJTdWl0ZS5nZXRBdXRoVHlwZShzZXJ2ZXJLZXlFeGNoYW5nZSAhPSBudWxsKTsKKyAgICAgICAgaWYgKGF1dGhUeXBlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFyYW1ldGVycy5nZXRUcnVzdE1hbmFnZXIoKS5jaGVja1NlcnZlclRydXN0ZWQoc2VydmVyQ2VydC5jZXJ0cywgYXV0aFR5cGUpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuQkFEX0NFUlRJRklDQVRFLCAiTm90IHRydXN0ZWQgc2VydmVyIGNlcnRpZmljYXRlIiwgZSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgc2Vzc2lvbi5wZWVyQ2VydGlmaWNhdGVzID0gc2VydmVyQ2VydC5jZXJ0czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgQ2hhbmdlQ2lwaGVyU3BlYyBtZXNzYWdlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVjZWl2ZUNoYW5nZUNpcGhlclNwZWMoKSB7CisgICAgICAgIGlmIChpc1Jlc3VtaW5nKSB7CisgICAgICAgICAgICBpZiAoc2VydmVySGVsbG8gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHVuZXhwZWN0ZWRNZXNzYWdlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAoY2xpZW50RmluaXNoZWQgPT0gbnVsbCkgeworICAgICAgICAgICAgdW5leHBlY3RlZE1lc3NhZ2UoKTsKKyAgICAgICAgfQorICAgICAgICBjaGFuZ2VDaXBoZXJTcGVjUmVjZWl2ZWQgPSB0cnVlOworICAgIH0KKworICAgIC8vIEZpbmQgc2Vzc2lvbiB0byByZXN1bWUgaW4gY2xpZW50IHNlc3Npb24gY29udGV4dAorICAgIHByaXZhdGUgU1NMU2Vzc2lvbkltcGwgZmluZFNlc3Npb25Ub1Jlc3VtZSgpIHsKKyAgICAgICAgU3RyaW5nIGhvc3QgPSBudWxsOworICAgICAgICBpbnQgcG9ydCA9IC0xOworICAgICAgICBpZiAoZW5naW5lT3duZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgaG9zdCA9IGVuZ2luZU93bmVyLmdldFBlZXJIb3N0KCk7CisgICAgICAgICAgICBwb3J0ID0gZW5naW5lT3duZXIuZ2V0UGVlclBvcnQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGhvc3QgPSBzb2NrZXRPd25lci5nZXRJbmV0QWRkcmVzcygpLmdldEhvc3ROYW1lKCk7CisgICAgICAgICAgICBwb3J0ID0gc29ja2V0T3duZXIuZ2V0UG9ydCgpOworICAgICAgICB9CisgICAgICAgIGlmIChob3N0ID09IG51bGwgfHwgcG9ydCA9PSAtMSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7IC8vIHN0YXJ0cyBuZXcgc2Vzc2lvbgorICAgICAgICB9CisKKyAgICAgICAgQ2xpZW50U2Vzc2lvbkNvbnRleHQgY29udGV4dCA9IHBhcmFtZXRlcnMuZ2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKTsKKyAgICAgICAgU1NMU2Vzc2lvbkltcGwgc2Vzc2lvbgorICAgICAgICAgICAgICAgID0gKFNTTFNlc3Npb25JbXBsKSBjb250ZXh0LmdldFNlc3Npb24oaG9zdCwgcG9ydCk7CisgICAgICAgIGlmIChzZXNzaW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNlc3Npb24gPSAoU1NMU2Vzc2lvbkltcGwpIHNlc3Npb24uY2xvbmUoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2Vzc2lvbjsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0NsaWVudEhlbGxvLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9DbGllbnRIZWxsby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFiZGVkNWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9DbGllbnRIZWxsby5qYXZhCkBAIC0wLDAgKzEsMjA4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworaW1wb3J0IGxpYmNvcmUudXRpbC5FbXB0eUFycmF5OworCisvKioKKyAqIFJlcHJlc2VudHMgQ2xpZW50IEhlbGxvIG1lc3NhZ2UKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI0Ni50eHQiPlRMUyAxLjAgc3BlYy4sIDcuNC4xLjIuCisgKiBDbGllbnQgaGVsbG88L2E+CisgKgorICovCitwdWJsaWMgY2xhc3MgQ2xpZW50SGVsbG8gZXh0ZW5kcyBNZXNzYWdlIHsKKworICAgIC8qKgorICAgICAqIENsaWVudCB2ZXJzaW9uCisgICAgICovCisgICAgZmluYWwgYnl0ZVtdIGNsaWVudF92ZXJzaW9uOworCisgICAgLyoqCisgICAgICogUmFuZG9tIGJ5dGVzCisgICAgICovCisgICAgZmluYWwgYnl0ZVtdIHJhbmRvbSA9IG5ldyBieXRlWzMyXTsKKworICAgIC8qKgorICAgICAqIFNlc3Npb24gaWQKKyAgICAgKi8KKyAgICBmaW5hbCBieXRlW10gc2Vzc2lvbl9pZDsKKworICAgIC8qKgorICAgICAqIENpcGhlciBzdWl0ZXMgc3VwcG9ydGVkIGJ5IHRoZSBjbGllbnQKKyAgICAgKi8KKyAgICBmaW5hbCBDaXBoZXJTdWl0ZVtdIGNpcGhlcl9zdWl0ZXM7CisKKyAgICAvKioKKyAgICAgKiBDb21wcmVzc2lvbiBtZXRob2RzIHN1cHBvcnRlZCBieSB0aGUgY2xpZW50CisgICAgICovCisgICAgZmluYWwgYnl0ZVtdIGNvbXByZXNzaW9uX21ldGhvZHM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIG91dGJvdW5kIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gc3IKKyAgICAgKiBAcGFyYW0gdmVyc2lvbgorICAgICAqIEBwYXJhbSBzZXNfaWQKKyAgICAgKiBAcGFyYW0gY2lwaGVyX3N1aXRlCisgICAgICovCisgICAgcHVibGljIENsaWVudEhlbGxvKFNlY3VyZVJhbmRvbSBzciwgYnl0ZVtdIHZlcnNpb24sIGJ5dGVbXSBzZXNfaWQsCisgICAgICAgICAgICBDaXBoZXJTdWl0ZVtdIGNpcGhlcl9zdWl0ZSkgeworICAgICAgICBjbGllbnRfdmVyc2lvbiA9IHZlcnNpb247CisgICAgICAgIGxvbmcgZ210X3VuaXhfdGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpLzEwMDA7CisgICAgICAgIHNyLm5leHRCeXRlcyhyYW5kb20pOworICAgICAgICByYW5kb21bMF0gPSAoYnl0ZSkgKGdtdF91bml4X3RpbWUgJiAweEZGMDAwMDAwID4+PiAyNCk7CisgICAgICAgIHJhbmRvbVsxXSA9IChieXRlKSAoZ210X3VuaXhfdGltZSAmIDB4RkYwMDAwID4+PiAxNik7CisgICAgICAgIHJhbmRvbVsyXSA9IChieXRlKSAoZ210X3VuaXhfdGltZSAmIDB4RkYwMCA+Pj4gOCk7CisgICAgICAgIHJhbmRvbVszXSA9IChieXRlKSAoZ210X3VuaXhfdGltZSAmIDB4RkYpOworICAgICAgICBzZXNzaW9uX2lkID0gc2VzX2lkOworICAgICAgICB0aGlzLmNpcGhlcl9zdWl0ZXMgPSBjaXBoZXJfc3VpdGU7CisgICAgICAgIGNvbXByZXNzaW9uX21ldGhvZHMgPSBuZXcgYnl0ZVtdIHsgMCB9OyAvLyBDb21wcmVzc2lvbk1ldGhvZC5udWxsCisgICAgICAgIGxlbmd0aCA9IDM4ICsgc2Vzc2lvbl9pZC5sZW5ndGggKyAodGhpcy5jaXBoZXJfc3VpdGVzLmxlbmd0aCA8PCAxKQorICAgICAgICAgICAgICAgICsgY29tcHJlc3Npb25fbWV0aG9kcy5sZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBpbmJvdW5kIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBDbGllbnRIZWxsbyhIYW5kc2hha2VJT0RhdGFTdHJlYW0gaW4sIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNsaWVudF92ZXJzaW9uID0gbmV3IGJ5dGVbMl07CisgICAgICAgIGNsaWVudF92ZXJzaW9uWzBdID0gKGJ5dGUpIGluLnJlYWRVaW50OCgpOworICAgICAgICBjbGllbnRfdmVyc2lvblsxXSA9IChieXRlKSBpbi5yZWFkVWludDgoKTsKKyAgICAgICAgU3RyZWFtcy5yZWFkRnVsbHkoaW4sIHJhbmRvbSk7CisgICAgICAgIGludCBzaXplID0gaW4ucmVhZCgpOworICAgICAgICBzZXNzaW9uX2lkID0gbmV3IGJ5dGVbc2l6ZV07CisgICAgICAgIGluLnJlYWQoc2Vzc2lvbl9pZCwgMCwgc2l6ZSk7CisgICAgICAgIGludCBsID0gaW4ucmVhZFVpbnQxNigpOworICAgICAgICBpZiAoKGwgJiAweDAxKSA9PSAweDAxKSB7IC8vIGNpcGhlciBzdWl0ZXMgbGVuZ3RoIG11c3QgYmUgYW4gZXZlbiBudW1iZXIKKyAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5ERUNPREVfRVJST1IsCisgICAgICAgICAgICAgICAgICAgICJERUNPREUgRVJST1I6IGluY29ycmVjdCBDbGllbnRIZWxsbyIpOworICAgICAgICB9CisgICAgICAgIHNpemUgPSBsID4+IDE7CisgICAgICAgIGNpcGhlcl9zdWl0ZXMgPSBuZXcgQ2lwaGVyU3VpdGVbc2l6ZV07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBieXRlIGIwID0gKGJ5dGUpIGluLnJlYWQoKTsKKyAgICAgICAgICAgIGJ5dGUgYjEgPSAoYnl0ZSkgaW4ucmVhZCgpOworICAgICAgICAgICAgY2lwaGVyX3N1aXRlc1tpXSA9IENpcGhlclN1aXRlLmdldEJ5Q29kZShiMCwgYjEpOworICAgICAgICB9CisgICAgICAgIHNpemUgPSBpbi5yZWFkKCk7CisgICAgICAgIGNvbXByZXNzaW9uX21ldGhvZHMgPSBuZXcgYnl0ZVtzaXplXTsKKyAgICAgICAgaW4ucmVhZChjb21wcmVzc2lvbl9tZXRob2RzLCAwLCBzaXplKTsKKyAgICAgICAgdGhpcy5sZW5ndGggPSAzOCArIHNlc3Npb25faWQubGVuZ3RoICsgKGNpcGhlcl9zdWl0ZXMubGVuZ3RoIDw8IDEpCisgICAgICAgICAgICAgICAgKyBjb21wcmVzc2lvbl9tZXRob2RzLmxlbmd0aDsKKyAgICAgICAgaWYgKHRoaXMubGVuZ3RoID4gbGVuZ3RoKSB7CisgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuREVDT0RFX0VSUk9SLCAiREVDT0RFIEVSUk9SOiBpbmNvcnJlY3QgQ2xpZW50SGVsbG8iKTsKKyAgICAgICAgfQorICAgICAgICAvLyBmb3IgZm9yd2FyZCBjb21wYXRpYmlsaXR5LCBleHRyYSBkYXRhIGlzIHBlcm1pdHRlZDsKKyAgICAgICAgLy8gbXVzdCBiZSBpZ25vcmVkCisgICAgICAgIGlmICh0aGlzLmxlbmd0aCA8IGxlbmd0aCkgeworICAgICAgICAgICAgaW4uc2tpcChsZW5ndGggLSB0aGlzLmxlbmd0aCk7CisgICAgICAgICAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDsKKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBQYXJzZSBWMkNsaWVudEhlbGxvCisgICAgICogQHBhcmFtIGluCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBDbGllbnRIZWxsbyhIYW5kc2hha2VJT0RhdGFTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpbi5yZWFkVWludDgoKSAhPSAxKSB7CisgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuREVDT0RFX0VSUk9SLCAiREVDT0RFIEVSUk9SOiBpbmNvcnJlY3QgVjJDbGllbnRIZWxsbyIpOworICAgICAgICB9CisgICAgICAgIGNsaWVudF92ZXJzaW9uID0gbmV3IGJ5dGVbMl07CisgICAgICAgIGNsaWVudF92ZXJzaW9uWzBdID0gKGJ5dGUpIGluLnJlYWRVaW50OCgpOworICAgICAgICBjbGllbnRfdmVyc2lvblsxXSA9IChieXRlKSBpbi5yZWFkVWludDgoKTsKKyAgICAgICAgaW50IGNpcGhlcl9zcGVjX2xlbmd0aCA9IGluLnJlYWRVaW50MTYoKTsKKyAgICAgICAgaWYgKGluLnJlYWRVaW50MTYoKSAhPSAwKSB7IC8vIHNlc3Npb25faWRfbGVuZ3RoCisgICAgICAgICAgICAvLyBhcyBjbGllbnQgYWxyZWFkeSBrbm93cyB0aGUgcHJvdG9jb2wga25vd24gdG8gYSBzZXJ2ZXIgaXQgc2hvdWxkCisgICAgICAgICAgICAvLyBpbml0aWF0ZSB0aGUgY29ubmVjdGlvbiBpbiB0aGF0IG5hdGl2ZSBwcm90b2NvbAorICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLkRFQ09ERV9FUlJPUiwKKyAgICAgICAgICAgICAgICAgICAgIkRFQ09ERSBFUlJPUjogaW5jb3JyZWN0IFYyQ2xpZW50SGVsbG8sIGNhbm5vdCBiZSB1c2VkIGZvciByZXN1bWluZyIpOworICAgICAgICB9CisgICAgICAgIGludCBjaGFsbGVuZ2VfbGVuZ3RoID0gaW4ucmVhZFVpbnQxNigpOworICAgICAgICBpZiAoY2hhbGxlbmdlX2xlbmd0aCA8IDE2KSB7CisgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuREVDT0RFX0VSUk9SLCAiREVDT0RFIEVSUk9SOiBpbmNvcnJlY3QgVjJDbGllbnRIZWxsbywgc2hvcnQgY2hhbGxlbmdlIGRhdGEiKTsKKyAgICAgICAgfQorICAgICAgICBzZXNzaW9uX2lkID0gRW1wdHlBcnJheS5CWVRFOworICAgICAgICBjaXBoZXJfc3VpdGVzID0gbmV3IENpcGhlclN1aXRlW2NpcGhlcl9zcGVjX2xlbmd0aC8zXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaXBoZXJfc3VpdGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBieXRlIGIwID0gKGJ5dGUpIGluLnJlYWQoKTsKKyAgICAgICAgICAgIGJ5dGUgYjEgPSAoYnl0ZSkgaW4ucmVhZCgpOworICAgICAgICAgICAgYnl0ZSBiMiA9IChieXRlKSBpbi5yZWFkKCk7CisgICAgICAgICAgICBjaXBoZXJfc3VpdGVzW2ldID0gQ2lwaGVyU3VpdGUuZ2V0QnlDb2RlKGIwLCBiMSwgYjIpOworICAgICAgICB9CisgICAgICAgIGNvbXByZXNzaW9uX21ldGhvZHMgPSBuZXcgYnl0ZVtdIHsgMCB9OyAvLyBDb21wcmVzc2lvbk1ldGhvZC5udWxsCisKKyAgICAgICAgaWYgKGNoYWxsZW5nZV9sZW5ndGggPCAzMikgeworICAgICAgICAgICAgQXJyYXlzLmZpbGwocmFuZG9tLCAwLCAzMiAtIGNoYWxsZW5nZV9sZW5ndGgsIChieXRlKTApOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShpbi5yZWFkKGNoYWxsZW5nZV9sZW5ndGgpLCAwLCByYW5kb20sIDMyIC0gY2hhbGxlbmdlX2xlbmd0aCwgY2hhbGxlbmdlX2xlbmd0aCk7CisgICAgICAgIH0gZWxzZSBpZiAoY2hhbGxlbmdlX2xlbmd0aCA9PSAzMikgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShpbi5yZWFkKDMyKSwgMCwgcmFuZG9tLCAwLCAzMik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGluLnJlYWQoY2hhbGxlbmdlX2xlbmd0aCksIGNoYWxsZW5nZV9sZW5ndGggLSAzMiwgcmFuZG9tLCAwLCAzMik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGluLmF2YWlsYWJsZSgpID4gMCkgeworICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLkRFQ09ERV9FUlJPUiwgIkRFQ09ERSBFUlJPUjogaW5jb3JyZWN0IFYyQ2xpZW50SGVsbG8sIGV4dHJhIGRhdGEiKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmxlbmd0aCA9IDM4ICsgc2Vzc2lvbl9pZC5sZW5ndGggKyAoY2lwaGVyX3N1aXRlcy5sZW5ndGggPDwgMSkKKyAgICAgICAgICAgICAgICArIGNvbXByZXNzaW9uX21ldGhvZHMubGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmRzIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2VuZChIYW5kc2hha2VJT0RhdGFTdHJlYW0gb3V0KSB7CisgICAgICAgIG91dC53cml0ZShjbGllbnRfdmVyc2lvbik7CisgICAgICAgIG91dC53cml0ZShyYW5kb20pOworICAgICAgICBvdXQud3JpdGVVaW50OChzZXNzaW9uX2lkLmxlbmd0aCk7CisgICAgICAgIG91dC53cml0ZShzZXNzaW9uX2lkKTsKKyAgICAgICAgaW50IHNpemUgPSBjaXBoZXJfc3VpdGVzLmxlbmd0aCA8PCAxOworICAgICAgICBvdXQud3JpdGVVaW50MTYoc2l6ZSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2lwaGVyX3N1aXRlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgb3V0LndyaXRlKGNpcGhlcl9zdWl0ZXNbaV0udG9CeXRlcygpKTsKKyAgICAgICAgfQorICAgICAgICBvdXQud3JpdGVVaW50OChjb21wcmVzc2lvbl9tZXRob2RzLmxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY29tcHJlc3Npb25fbWV0aG9kcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgb3V0LndyaXRlKGNvbXByZXNzaW9uX21ldGhvZHNbaV0pOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBjbGllbnQgcmFuZG9tCisgICAgICogQHJldHVybiBjbGllbnQgcmFuZG9tCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRSYW5kb20oKSB7CisgICAgICAgIHJldHVybiByYW5kb207CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBtZXNzYWdlIHR5cGUKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRUeXBlKCkgeworICAgICAgICByZXR1cm4gSGFuZHNoYWtlLkNMSUVOVF9IRUxMTzsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9DbGllbnRLZXlFeGNoYW5nZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQ2xpZW50S2V5RXhjaGFuZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYmFlOGQwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQ2xpZW50S2V5RXhjaGFuZ2UuamF2YQpAQCAtMCwwICsxLDE1MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBsaWJjb3JlLmlvLlN0cmVhbXM7CitpbXBvcnQgbGliY29yZS51dGlsLkVtcHR5QXJyYXk7CisKKy8qKgorICogUmVwcmVzZW50cyBjbGllbnQga2V5IGV4Y2hhbmdlIG1lc3NhZ2UKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI0Ni50eHQiPlRMUyAxLjAgc3BlYy4sIDcuNC43LgorICogQ2xpZW50IGtleSBleGNoYW5nZSBtZXNzYWdlPC9hPgorICoKKyAqLworcHVibGljIGNsYXNzIENsaWVudEtleUV4Y2hhbmdlIGV4dGVuZHMgTWVzc2FnZSB7CisKKyAgICAvKioKKyAgICAgKiBFeGNoYW5nZSBrZXlzCisgICAgICovCisgICAgZmluYWwgYnl0ZVtdIGV4Y2hhbmdlX2tleXM7CisKKyAgICAvKioKKyAgICAgKiBFcXVhbHMgdHJ1ZSBpZiBUTFMxLjAgcHJvdG9jb2wgaXMgdXNlZAorICAgICAqLworICAgIGJvb2xlYW4gaXNUTFM7CisKKyAgICAvKioKKyAgICAgKiBFcXVhbHMgdHJ1ZSBpZiBrZXkgZXhjaGFuZ2UgYWxnb3JpdGhtIGlzIFJTQQorICAgICAqLworICAgIGZpbmFsIGJvb2xlYW4gaXNSU0E7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIG91dGJvdW5kIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gZW5jcnlwdGVkX3ByZV9tYXN0ZXJfc2VjcmV0CisgICAgICogQHBhcmFtIGlzVExTCisgICAgICovCisgICAgcHVibGljIENsaWVudEtleUV4Y2hhbmdlKGJ5dGVbXSBlbmNyeXB0ZWRfcHJlX21hc3Rlcl9zZWNyZXQsIGJvb2xlYW4gaXNUTFMpIHsKKyAgICAgICAgdGhpcy5leGNoYW5nZV9rZXlzID0gZW5jcnlwdGVkX3ByZV9tYXN0ZXJfc2VjcmV0OworICAgICAgICBsZW5ndGggPSB0aGlzLmV4Y2hhbmdlX2tleXMubGVuZ3RoOworICAgICAgICBpZiAoaXNUTFMpIHsKKyAgICAgICAgICAgIGxlbmd0aCArPSAyOworICAgICAgICB9CisgICAgICAgIHRoaXMuaXNUTFMgPSBpc1RMUzsKKyAgICAgICAgaXNSU0EgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgb3V0Ym91bmQgbWVzc2FnZQorICAgICAqIEBwYXJhbSBkaF9ZYworICAgICAqLworICAgIHB1YmxpYyBDbGllbnRLZXlFeGNoYW5nZShCaWdJbnRlZ2VyIGRoX1ljKSB7CisgICAgICAgIGJ5dGVbXSBiYiA9IGRoX1ljLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIGlmIChiYlswXSA9PSAwKSB7CisgICAgICAgICAgICBleGNoYW5nZV9rZXlzID0gbmV3IGJ5dGVbYmIubGVuZ3RoLTFdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShiYiwgMSwgZXhjaGFuZ2Vfa2V5cywgMCwgZXhjaGFuZ2Vfa2V5cy5sZW5ndGgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZXhjaGFuZ2Vfa2V5cyA9IGJiOworICAgICAgICB9CisgICAgICAgIGxlbmd0aCA9IGV4Y2hhbmdlX2tleXMubGVuZ3RoICsyOworICAgICAgICBpc1JTQSA9IGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgZW1wdHkgbWVzc2FnZQorICAgICAqCisgICAgICovCisgICAgcHVibGljIENsaWVudEtleUV4Y2hhbmdlKCkgeworICAgICAgICBleGNoYW5nZV9rZXlzID0gRW1wdHlBcnJheS5CWVRFOworICAgICAgICBsZW5ndGggPSAwOworICAgICAgICBpc1JTQSA9IGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgaW5ib3VuZCBtZXNzYWdlCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqIEBwYXJhbSBpc1RMUworICAgICAqIEBwYXJhbSBpc1JTQQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xpZW50S2V5RXhjaGFuZ2UoSGFuZHNoYWtlSU9EYXRhU3RyZWFtIGluLCBpbnQgbGVuZ3RoLCBib29sZWFuIGlzVExTLCBib29sZWFuIGlzUlNBKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5pc1RMUyA9IGlzVExTOworICAgICAgICB0aGlzLmlzUlNBID0gaXNSU0E7CisgICAgICAgIGlmIChsZW5ndGggPT0gMCkgeworICAgICAgICAgICAgdGhpcy5sZW5ndGggPSAwOworICAgICAgICAgICAgZXhjaGFuZ2Vfa2V5cyA9IEVtcHR5QXJyYXkuQllURTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGludCBzaXplOworICAgICAgICAgICAgaWYgKGlzUlNBICYmICFpc1RMUykgey8vIFNTTDMuMCBSU0EKKyAgICAgICAgICAgICAgICBzaXplID0gbGVuZ3RoOworICAgICAgICAgICAgICAgIHRoaXMubGVuZ3RoID0gc2l6ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7IC8vIERIIG9yIFRMU3YxIFJTQQorICAgICAgICAgICAgICAgIHNpemUgPSBpbi5yZWFkVWludDE2KCk7CisgICAgICAgICAgICAgICAgdGhpcy5sZW5ndGggPSAyICsgc2l6ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGV4Y2hhbmdlX2tleXMgPSBuZXcgYnl0ZVtzaXplXTsKKyAgICAgICAgICAgIFN0cmVhbXMucmVhZEZ1bGx5KGluLCBleGNoYW5nZV9rZXlzKTsKKyAgICAgICAgICAgIGlmICh0aGlzLmxlbmd0aCAhPSBsZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuREVDT0RFX0VSUk9SLCAiREVDT0RFIEVSUk9SOiBpbmNvcnJlY3QgQ2xpZW50S2V5RXhjaGFuZ2UiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmRzIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2VuZChIYW5kc2hha2VJT0RhdGFTdHJlYW0gb3V0KSB7CisgICAgICAgIGlmIChleGNoYW5nZV9rZXlzLmxlbmd0aCAhPSAwKSB7CisgICAgICAgICAgICBpZiAoIWlzUlNBIHx8IGlzVExTKSB7Ly8gREggb3IgVExTdjEgUlNBCisgICAgICAgICAgICAgICAgb3V0LndyaXRlVWludDE2KGV4Y2hhbmdlX2tleXMubGVuZ3RoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG91dC53cml0ZShleGNoYW5nZV9rZXlzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgbWVzc2FnZSB0eXBlCisgICAgICogQHJldHVybgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0VHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIEhhbmRzaGFrZS5DTElFTlRfS0VZX0VYQ0hBTkdFOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgbWVzc2FnZSBpcyBlbXB0eSAoaW4gY2FzZSBvZiBpbXBsaWNpdCBESCBZYykKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgcmV0dXJuIChleGNoYW5nZV9rZXlzLmxlbmd0aCA9PSAwKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9DbGllbnRTZXNzaW9uQ29udGV4dC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQ2xpZW50U2Vzc2lvbkNvbnRleHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYjM1OGFhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQ2xpZW50U2Vzc2lvbkNvbnRleHQuamF2YQpAQCAtMCwwICsxLDE0NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uOworCisvKioKKyAqIENhY2hlcyBjbGllbnQgc2Vzc2lvbnMuIEluZGV4ZXMgYnkgaG9zdCBhbmQgcG9ydC4gVXNlcnMgYXJlIHR5cGljYWxseQorICogbG9va2luZyB0byByZXVzZSBhbnkgc2Vzc2lvbiBmb3IgYSBnaXZlbiBob3N0IGFuZCBwb3J0LgorICovCitwdWJsaWMgY2xhc3MgQ2xpZW50U2Vzc2lvbkNvbnRleHQgZXh0ZW5kcyBBYnN0cmFjdFNlc3Npb25Db250ZXh0IHsKKworICAgIC8qKgorICAgICAqIFNlc3Npb25zIGluZGV4ZWQgYnkgaG9zdCBhbmQgcG9ydC4gUHJvdGVjdCBmcm9tIGNvbmN1cnJlbnQKKyAgICAgKiBhY2Nlc3MgYnkgaG9sZGluZyBhIGxvY2sgb24gc2Vzc2lvbnNCeUhvc3RBbmRQb3J0LgorICAgICAqLworICAgIGZpbmFsIE1hcDxIb3N0QW5kUG9ydCwgU1NMU2Vzc2lvbj4gc2Vzc2lvbnNCeUhvc3RBbmRQb3J0CisgICAgICAgID0gbmV3IEhhc2hNYXA8SG9zdEFuZFBvcnQsIFNTTFNlc3Npb24+KCk7CisKKyAgICBwcml2YXRlIFNTTENsaWVudFNlc3Npb25DYWNoZSBwZXJzaXN0ZW50Q2FjaGU7CisKKyAgICBwdWJsaWMgQ2xpZW50U2Vzc2lvbkNvbnRleHQoKSB7CisgICAgICAgIHN1cGVyKDEwLCAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgIHJldHVybiBzZXNzaW9uc0J5SG9zdEFuZFBvcnQuc2l6ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFBlcnNpc3RlbnRDYWNoZShTU0xDbGllbnRTZXNzaW9uQ2FjaGUgcGVyc2lzdGVudENhY2hlKSB7CisgICAgICAgIHRoaXMucGVyc2lzdGVudENhY2hlID0gcGVyc2lzdGVudENhY2hlOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNlc3Npb25SZW1vdmVkKFNTTFNlc3Npb24gc2Vzc2lvbikgeworICAgICAgICBTdHJpbmcgaG9zdCA9IHNlc3Npb24uZ2V0UGVlckhvc3QoKTsKKyAgICAgICAgaW50IHBvcnQgPSBzZXNzaW9uLmdldFBlZXJQb3J0KCk7CisgICAgICAgIGlmIChob3N0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBIb3N0QW5kUG9ydCBob3N0QW5kUG9ydEtleSA9IG5ldyBIb3N0QW5kUG9ydChob3N0LCBwb3J0KTsKKyAgICAgICAgc3luY2hyb25pemVkIChzZXNzaW9uc0J5SG9zdEFuZFBvcnQpIHsKKyAgICAgICAgICAgIHNlc3Npb25zQnlIb3N0QW5kUG9ydC5yZW1vdmUoaG9zdEFuZFBvcnRLZXkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluZHMgYSBjYWNoZWQgc2Vzc2lvbiBmb3IgdGhlIGdpdmVuIGhvc3QgbmFtZSBhbmQgcG9ydC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3N0IG9mIHNlcnZlcgorICAgICAqIEBwYXJhbSBwb3J0IG9mIHNlcnZlcgorICAgICAqIEByZXR1cm4gY2FjaGVkIHNlc3Npb24gb3IgbnVsbCBpZiBub25lIGZvdW5kCisgICAgICovCisgICAgcHVibGljIFNTTFNlc3Npb24gZ2V0U2Vzc2lvbihTdHJpbmcgaG9zdCwgaW50IHBvcnQpIHsKKyAgICAgICAgaWYgKGhvc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgU1NMU2Vzc2lvbiBzZXNzaW9uOworICAgICAgICBIb3N0QW5kUG9ydCBob3N0QW5kUG9ydEtleSA9IG5ldyBIb3N0QW5kUG9ydChob3N0LCBwb3J0KTsKKyAgICAgICAgc3luY2hyb25pemVkIChzZXNzaW9uc0J5SG9zdEFuZFBvcnQpIHsKKyAgICAgICAgICAgIHNlc3Npb24gPSBzZXNzaW9uc0J5SG9zdEFuZFBvcnQuZ2V0KGhvc3RBbmRQb3J0S2V5KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc2Vzc2lvbiAhPSBudWxsICYmIHNlc3Npb24uaXNWYWxpZCgpKSB7CisgICAgICAgICAgICByZXR1cm4gc2Vzc2lvbjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIExvb2sgaW4gcGVyc2lzdGVudCBjYWNoZS4KKyAgICAgICAgaWYgKHBlcnNpc3RlbnRDYWNoZSAhPSBudWxsKSB7CisgICAgICAgICAgICBieXRlW10gZGF0YSA9IHBlcnNpc3RlbnRDYWNoZS5nZXRTZXNzaW9uRGF0YShob3N0LCBwb3J0KTsKKyAgICAgICAgICAgIGlmIChkYXRhICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXNzaW9uID0gdG9TZXNzaW9uKGRhdGEsIGhvc3QsIHBvcnQpOworICAgICAgICAgICAgICAgIGlmIChzZXNzaW9uICE9IG51bGwgJiYgc2Vzc2lvbi5pc1ZhbGlkKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgc3VwZXIucHV0U2Vzc2lvbihzZXNzaW9uKTsKKyAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVkIChzZXNzaW9uc0J5SG9zdEFuZFBvcnQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25zQnlIb3N0QW5kUG9ydC5wdXQoaG9zdEFuZFBvcnRLZXksIHNlc3Npb24pOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBzZXNzaW9uOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHB1dFNlc3Npb24oU1NMU2Vzc2lvbiBzZXNzaW9uKSB7CisgICAgICAgIHN1cGVyLnB1dFNlc3Npb24oc2Vzc2lvbik7CisKKyAgICAgICAgU3RyaW5nIGhvc3QgPSBzZXNzaW9uLmdldFBlZXJIb3N0KCk7CisgICAgICAgIGludCBwb3J0ID0gc2Vzc2lvbi5nZXRQZWVyUG9ydCgpOworICAgICAgICBpZiAoaG9zdCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBIb3N0QW5kUG9ydCBob3N0QW5kUG9ydEtleSA9IG5ldyBIb3N0QW5kUG9ydChob3N0LCBwb3J0KTsKKyAgICAgICAgc3luY2hyb25pemVkIChzZXNzaW9uc0J5SG9zdEFuZFBvcnQpIHsKKyAgICAgICAgICAgIHNlc3Npb25zQnlIb3N0QW5kUG9ydC5wdXQoaG9zdEFuZFBvcnRLZXksIHNlc3Npb24pOworICAgICAgICB9CisKKyAgICAgICAgLy8gVE9ETzogVGhpcyBpbiBhIGJhY2tncm91bmQgdGhyZWFkLgorICAgICAgICBpZiAocGVyc2lzdGVudENhY2hlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBkYXRhID0gdG9CeXRlcyhzZXNzaW9uKTsKKyAgICAgICAgICAgIGlmIChkYXRhICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBwZXJzaXN0ZW50Q2FjaGUucHV0U2Vzc2lvbkRhdGEoc2Vzc2lvbiwgZGF0YSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgSG9zdEFuZFBvcnQgeworICAgICAgICBmaW5hbCBTdHJpbmcgaG9zdDsKKyAgICAgICAgZmluYWwgaW50IHBvcnQ7CisKKyAgICAgICAgSG9zdEFuZFBvcnQoU3RyaW5nIGhvc3QsIGludCBwb3J0KSB7CisgICAgICAgICAgICB0aGlzLmhvc3QgPSBob3N0OworICAgICAgICAgICAgdGhpcy5wb3J0ID0gcG9ydDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgcmV0dXJuIGhvc3QuaGFzaENvZGUoKSAqIDMxICsgcG9ydDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBIb3N0QW5kUG9ydCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBIb3N0QW5kUG9ydCBsaHMgPSAoSG9zdEFuZFBvcnQpIG87CisgICAgICAgICAgICByZXR1cm4gaG9zdC5lcXVhbHMobGhzLmhvc3QpICYmIHBvcnQgPT0gbGhzLnBvcnQ7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9Db25uZWN0aW9uU3RhdGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0Nvbm5lY3Rpb25TdGF0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA2OWQ1ZGIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9Db25uZWN0aW9uU3RhdGUuamF2YQpAQCAtMCwwICsxLDE3NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YXguY3J5cHRvLkNpcGhlcjsKKworLyoqCisgKiBUaGlzIGFic3RyYWN0IGNsYXNzIGlzIGEgYmFzZSBmb3IgUmVjb3JkIFByb3RvY29sIG9wZXJhdGluZyBlbnZpcm9ubWV0CisgKiBvZiBkaWZmZXJlbnQgU1NMIHByb3RvY29sIHZlcnNpb25zLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ29ubmVjdGlvblN0YXRlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBjaXBoZXIgdXNlZCBmb3IgZW5jb2RlIG9wZXJhdGlvbnMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ2lwaGVyIGVuY0NpcGhlcjsKKworICAgIC8qKgorICAgICAqIFRoZSBjaXBoZXIgdXNlZCBmb3IgZGVjb2RlIG9wZXJhdGlvbnMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQ2lwaGVyIGRlY0NpcGhlcjsKKworICAgIC8qKgorICAgICAqIFRoZSBibG9jayBzaXplLCBvciB6ZXJvIGlmIG5vdCBhIGJsb2NrIGNpcGhlcgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgYmxvY2tfc2l6ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBzaXplIG9mIE1BQyB1c2VkIHVuZGVyIHRoaXMgY29ubmVjdGlvbiBzdGF0ZQorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgaGFzaF9zaXplOworCisgICAgLyoqCisgICAgICogV3JpdGUgc2VxdWVuY2UgbnVtYmVyIHdoaWNoIGlzIGluY3JlbWVudGVkIGFmdGVyIGVhY2gKKyAgICAgKiBlbmNyeXB0IGNhbGwKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgYnl0ZVtdIHdyaXRlX3NlcV9udW0gPSB7MCwgMCwgMCwgMCwgMCwgMCwgMCwgMH07CisKKyAgICAvKioKKyAgICAgKiBSZWFkIHNlcXVlbmNlIG51bWJlciB3aGljaCBpcyBpbmNyZW1lbnRlZCBhZnRlciBlYWNoCisgICAgICogZGVjcnlwdCBjYWxsCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIGJ5dGVbXSByZWFkX3NlcV9udW0gPSB7MCwgMCwgMCwgMCwgMCwgMCwgMCwgMH07CisKKyAgICBwcm90ZWN0ZWQgTG9nZ2VyLlN0cmVhbSBsb2dnZXIgPSBMb2dnZXIuZ2V0U3RyZWFtKCJjb25uX3N0YXRlIik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtaW5pbWFsIHBvc3NpYmxlIHNpemUgb2YgdGhlCisgICAgICogR2VuZXJpY1tTdHJlYW18R2VuZXJpY11DaXBoZXIgc3RydWN0dXJlIHVuZGVyIHRoaXMKKyAgICAgKiBjb25uZWN0aW9uIHN0YXRlLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgZ2V0TWluRnJhZ21lbnRTaXplKCkgeworICAgICAgICAvLyBibG9jayBjaXBoZXJzIHJldHVybiB2YWx1ZSB3aXRoIHBhZGRpbmcgaW5jbHVkZWQKKyAgICAgICAgcmV0dXJuIGVuY0NpcGhlci5nZXRPdXRwdXRTaXplKDEraGFzaF9zaXplKTsgLy8gMSBieXRlIGZvciBkYXRhCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2l6ZSBvZiB0aGUgR2VuZXJpY1tTdHJlYW18R2VuZXJpY11DaXBoZXIgc3RydWN0dXJlCisgICAgICogY29ycmVzcG9uZGluZyB0byB0aGUgY29udGVudCBkYXRhIG9mIHNwZWNpZmllZCBzaXplLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgZ2V0RnJhZ21lbnRTaXplKGludCBjb250ZW50X3NpemUpIHsKKyAgICAgICAgcmV0dXJuIGVuY0NpcGhlci5nZXRPdXRwdXRTaXplKGNvbnRlbnRfc2l6ZStoYXNoX3NpemUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1pbmltYWwgdXBwZXIgYm91bmQgb2YgdGhlIGNvbnRlbnQgc2l6ZSBlbmNsb3NlZAorICAgICAqIGludG8gdGhlIEdlbmVyaWNbU3RyZWFtfEdlbmVyaWNdQ2lwaGVyIHN0cnVjdHVyZSBvZiBzcGVjaWZpZWQgc2l6ZS4KKyAgICAgKiBGb3Igc3RyZWFtIGNpcGhlcnMgdGhlIHJldHVybmVkIHZhbHVlIHdpbGwgYmUgZXhhY3QgdmFsdWUuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBnZXRDb250ZW50U2l6ZShpbnQgZ2VuZXJpY19jaXBoZXJfc2l6ZSkgeworICAgICAgICAvL2l0IGRvZXMgbm90IHRha2UgdGhlIHBhZGRpbmcgb2YgYmxvY2sgY2lwaGVyZWQgc3RydWN0dXJlcworICAgICAgICAvL2ludG8gYWNjb3VudCAoc28gcmV0dXJuZWQgdmFsdWUgY2FuIGJlIGdyZWF0ZXIgdGhhbiBhY3R1YWwpCisgICAgICAgIHJldHVybiBkZWNDaXBoZXIuZ2V0T3V0cHV0U2l6ZShnZW5lcmljX2NpcGhlcl9zaXplKS1oYXNoX3NpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIG9mIHBhZGRpbmcgcmVxdWlyZWQgdG8gcm91bmQgdGhlCisgICAgICogY29udGVudCB1cCB0byB0aGUgcmVxdWlyZWQgYmxvY2sgc2l6ZS4gQXNzdW1lcyBwb3dlciBvZiB0d28KKyAgICAgKiBibG9jayBzaXplLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgZ2V0UGFkZGluZ1NpemUoaW50IGNvbnRlbnRfc2l6ZSkgeworICAgICAgICBpbnQgbWFzayA9IGJsb2NrX3NpemUgLSAxOworICAgICAgICByZXR1cm4gKGJsb2NrX3NpemUgLSAoY29udGVudF9zaXplICYgbWFzaykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIEdlbmVyaWNTdHJlYW1DaXBoZXIgb3IgR2VuZXJpY0Jsb2NrQ2lwaGVyCisgICAgICogZGF0YSBzdHJ1Y3R1cmUgZm9yIHNwZWNpZmllZCBkYXRhIG9mIHNwZWNpZmllZCB0eXBlLgorICAgICAqIEBwYXJhbSB0eXBlIC0gdGhlIENvbnRlbnRUeXBlIG9mIHRoZSBwcm92aWRlZCBkYXRhCisgICAgICogQHBhcmFtIGZyYWdtZW50IC0gdGhlIGJ5dGUgYXJyYXkgY29udGFpbmluZyB0aGUKKyAgICAgKiBkYXRhIHRvIGJlIGVuY3J5cHRlZCB1bmRlciB0aGUgY3VycmVudCBjb25uZWN0aW9uIHN0YXRlLgorICAgICAqLworICAgIHByb3RlY3RlZCBieXRlW10gZW5jcnlwdChieXRlIHR5cGUsIGJ5dGVbXSBmcmFnbWVudCkgeworICAgICAgICByZXR1cm4gZW5jcnlwdCh0eXBlLCBmcmFnbWVudCwgMCwgZnJhZ21lbnQubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBHZW5lcmljU3RyZWFtQ2lwaGVyIG9yIEdlbmVyaWNCbG9ja0NpcGhlcgorICAgICAqIGRhdGEgc3RydWN0dXJlIGZvciBzcGVjaWZpZWQgZGF0YSBvZiBzcGVjaWZpZWQgdHlwZS4KKyAgICAgKiBAcGFyYW0gdHlwZSAtIHRoZSBDb250ZW50VHlwZSBvZiB0aGUgcHJvdmlkZWQgZGF0YQorICAgICAqIEBwYXJhbSBmcmFnbWVudCAtIHRoZSBieXRlIGFycmF5IGNvbnRhaW5pbmcgdGhlCisgICAgICogZGF0YSB0byBiZSBlbmNyeXB0ZWQgdW5kZXIgdGhlIGN1cnJlbnQgY29ubmVjdGlvbiBzdGF0ZS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0IC0gdGhlIG9mZnNldCBmcm9tIHdoaWNoIHRoZSBkYXRhIGJlZ2lucyB3aXRoLgorICAgICAqIEBwYXJhbSBsZW4gLSB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBieXRlW10gZW5jcnlwdAorICAgICAgICAoYnl0ZSB0eXBlLCBieXRlW10gZnJhZ21lbnQsIGludCBvZmZzZXQsIGludCBsZW4pOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIHRoZSBmcmFnbWVudCBvZiB0aGUgUGxhaW50ZXh0IHN0cnVjdHVyZSBvZgorICAgICAqIHRoZSBzcGVjaWZpZWQgdHlwZSBmcm9tIHRoZSBwcm92aWRlZCBkYXRhLgorICAgICAqIEBwYXJhbSB0eXBlIC0gdGhlIENvbnRlbnRUeXBlIG9mIHRoZSBkYXRhIHRvIGJlIGRlY3J5cHRlZC4KKyAgICAgKiBAcGFyYW0gZnJhZ21lbnQgLSB0aGUgYnl0ZSBhcnJheSBjb250YWluaW5nIHRoZQorICAgICAqIGRhdGEgdG8gYmUgZW5jcnlwdGVkIHVuZGVyIHRoZSBjdXJyZW50IGNvbm5lY3Rpb24gc3RhdGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBkZWNyeXB0KGJ5dGUgdHlwZSwgYnl0ZVtdIGZyYWdtZW50KSB7CisgICAgICAgIHJldHVybiBkZWNyeXB0KHR5cGUsIGZyYWdtZW50LCAwLCBmcmFnbWVudC5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyB0aGUgZnJhZ21lbnQgb2YgdGhlIFBsYWludGV4dCBzdHJ1Y3R1cmUgb2YKKyAgICAgKiB0aGUgc3BlY2lmaWVkIHR5cGUgZnJvbSB0aGUgcHJvdmlkZWQgZGF0YS4KKyAgICAgKiBAcGFyYW0gdHlwZSAtIHRoZSBDb250ZW50VHlwZSBvZiB0aGUgZGF0YSB0byBiZSBkZWNyeXB0ZWQuCisgICAgICogQHBhcmFtIGZyYWdtZW50IC0gdGhlIGJ5dGUgYXJyYXkgY29udGFpbmluZyB0aGUKKyAgICAgKiBkYXRhIHRvIGJlIGVuY3J5cHRlZCB1bmRlciB0aGUgY3VycmVudCBjb25uZWN0aW9uIHN0YXRlLgorICAgICAqIEBwYXJhbSBvZmZzZXQgLSB0aGUgb2Zmc2V0IGZyb20gd2hpY2ggdGhlIGRhdGEgYmVnaW5zIHdpdGguCisgICAgICogQHBhcmFtIGxlbiAtIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IGJ5dGVbXSBkZWNyeXB0CisgICAgICAgIChieXRlIHR5cGUsIGJ5dGVbXSBmcmFnbWVudCwgaW50IG9mZnNldCwgaW50IGxlbik7CisKKyAgICAvKioKKyAgICAgKiBJbmNyZW1lbnRzIHRoZSBzZXF1ZW5jZSBudW1iZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyB2b2lkIGluY1NlcXVlbmNlTnVtYmVyKGJ5dGVbXSBzZXFfbnVtKSB7CisgICAgICAgIGludCBvY3RldCA9IDc7CisgICAgICAgIHdoaWxlIChvY3RldCA+PSAwKSB7CisgICAgICAgICAgICBzZXFfbnVtW29jdGV0XSArKzsKKyAgICAgICAgICAgIGlmIChzZXFfbnVtW29jdGV0XSA9PSAwKSB7CisgICAgICAgICAgICAgICAgLy8gY2hhcmFjdGVyaXN0aWMgb3ZlcmZsb3csIHNvCisgICAgICAgICAgICAgICAgLy8gY2FycnlpbmcgYSBudW1iZXIgaW4gYWRkaW5nCisgICAgICAgICAgICAgICAgb2N0ZXQgLS07CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNodXRkb3duZXMgdGhlIHByb3RvY29sLiBJdCB3aWxsIGJlIGltcG9zc2libGtlIHRvIHVzZSB0aGUgaW5zdGFuY2UKKyAgICAgKiBhZnRlciB0aGUgY2FsbGluZyBvZiB0aGlzIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzaHV0ZG93bigpIHsKKyAgICAgICAgZW5jQ2lwaGVyID0gbnVsbDsKKyAgICAgICAgZGVjQ2lwaGVyID0gbnVsbDsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPHdyaXRlX3NlcV9udW0ubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHdyaXRlX3NlcV9udW1baV0gPSAwOworICAgICAgICAgICAgcmVhZF9zZXFfbnVtW2ldID0gMDsKKyAgICAgICAgfQorICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQ29ubmVjdGlvblN0YXRlU1NMdjMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0Nvbm5lY3Rpb25TdGF0ZVNTTHYzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDA3MDVjYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0Nvbm5lY3Rpb25TdGF0ZVNTTHYzLmphdmEKQEAgLTAsMCArMSwzNjEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXI7CitpbXBvcnQgamF2YXguY3J5cHRvLk51bGxDaXBoZXI7CitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuSXZQYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLlNlY3JldEtleVNwZWM7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xQcm90b2NvbEV4Y2VwdGlvbjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgb3BlcmF0aW5nIGVudmlyb25tZW50IG9mIHRoZSBTU0wgdjMKKyAqIChodHRwOi8vd3AubmV0c2NhcGUuY29tL2VuZy9zc2wzKSBSZWNvcmQgUHJvdG9jb2wgYW5kIHByb3ZpZGVzCisgKiByZWxhdGluZyBlbmNyeXB0aW9uL2RlY3J5cHRpb24gZnVuY3Rpb25hbGl0eS4KKyAqIFRoZSB3b3JrIGZ1bmN0aW9uYWxpdHkgaXMgYmFzZWQgb24gdGhlIHNlY3VyaXR5CisgKiBwYXJhbWV0ZXJzIG5lZ290aWF0ZWQgZHVyaW5nIHRoZSBoYW5kc2hha2UuCisgKi8KK3B1YmxpYyBjbGFzcyBDb25uZWN0aW9uU3RhdGVTU0x2MyBleHRlbmRzIENvbm5lY3Rpb25TdGF0ZSB7CisKKyAgICAvLyBkaWdlc3QgdG8gY3JlYXRlIGFuZCBjaGVjayB0aGUgbWVzc2FnZSBpbnRlZ3JpdHkgaW5mbworICAgIHByaXZhdGUgZmluYWwgTWVzc2FnZURpZ2VzdCBtZXNzYWdlRGlnZXN0OworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIG1hY193cml0ZV9zZWNyZXQ7CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gbWFjX3JlYWRfc2VjcmV0OworCisgICAgLy8gcGFkZGluZ3MKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBwYWRfMTsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBwYWRfMjsKKyAgICAvLyBhcnJheSB3aWxsIGhvbGQgdGhlIHBhcnQgb2YgdGhlIE1BQyBtYXRlcmlhbDoKKyAgICAvLyBsZW5ndGggb2YgMyA9PSAxKFNTTENvbXByZXNzZWQudHlwZSkgKyAyKFNTTENvbXByZXNzZWQubGVuZ3RoKQorICAgIC8vIChtb3JlIG9uIFNTTHYzIE1BQyBjb21wdXRhdGlvbiBhbmQgcGF5bG9hZCBwcm90ZWN0aW9uIHNlZQorICAgIC8vIFNTTCB2MyBzcGVjaWZpY2F0aW9uLCBwLiA1LjIuMykKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBtYWNfbWF0ZXJpYWxfcGFydCA9IG5ldyBieXRlWzNdOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgaW5zdGFuY2Ugb2YgU1NMIHYzIENvbm5lY3Rpb24gU3RhdGUuIEFsbCBvZiB0aGUKKyAgICAgKiBzZWN1cml0eSBwYXJhbWV0ZXJzIGFyZSBwcm92aWRlZCBieSBzZXNzaW9uIG9iamVjdC4KKyAgICAgKiBAcGFyYW0gICBzZXNzaW9uOiB0aGUgc2Vzc2luIG9iamVjdCB3aGljaCBpbmNhcHN1bGF0ZXMKKyAgICAgKiBhbGwgb2YgdGhlIHNlY3VyaXR5IHBhcmFtZXRlcnMgZXN0YWJsaXNoZWQgYnkgaGFuZHNoYWtlIHByb3RvY29sLgorICAgICAqIFRoZSBrZXkgY2FsY3VsYXRpb24gZm9yIHRoZSBzdGF0ZSBpcyBkb25lIGFjY29yZGluZworICAgICAqIHRvIHRoZSBTU0wgdjMgUHJvdG9jb2wgc3BlY2lmaWNhdGlvbi4KKyAgICAgKiAoaHR0cDovL3d3dy5tb3ppbGxhLm9yZy9wcm9qZWN0cy9zZWN1cml0eS9wa2kvbnNzL3NzbC9kcmFmdDMwMi50eHQpCisgICAgICovCisgICAgcHJvdGVjdGVkIENvbm5lY3Rpb25TdGF0ZVNTTHYzKFNTTFNlc3Npb25JbXBsIHNlc3Npb24pIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENpcGhlclN1aXRlIGNpcGhlclN1aXRlID0gc2Vzc2lvbi5jaXBoZXJTdWl0ZTsKKworICAgICAgICAgICAgYm9vbGVhbiBpc19leHBvcnRhYmUgPSAgY2lwaGVyU3VpdGUuaXNFeHBvcnRhYmxlKCk7CisgICAgICAgICAgICBoYXNoX3NpemUgPSBjaXBoZXJTdWl0ZS5nZXRNQUNMZW5ndGgoKTsKKyAgICAgICAgICAgIGludCBrZXlfc2l6ZSA9IChpc19leHBvcnRhYmUpCisgICAgICAgICAgICAgICAgPyBjaXBoZXJTdWl0ZS5rZXlNYXRlcmlhbAorICAgICAgICAgICAgICAgIDogY2lwaGVyU3VpdGUuZXhwYW5kZWRLZXlNYXRlcmlhbDsKKyAgICAgICAgICAgIGludCBpdl9zaXplID0gY2lwaGVyU3VpdGUuaXZTaXplOworICAgICAgICAgICAgYmxvY2tfc2l6ZSA9IGNpcGhlclN1aXRlLmdldEJsb2NrU2l6ZSgpOworCisgICAgICAgICAgICBTdHJpbmcgYWxnTmFtZSA9IGNpcGhlclN1aXRlLmdldEJ1bGtFbmNyeXB0aW9uQWxnb3JpdGhtKCk7CisgICAgICAgICAgICBTdHJpbmcgaGFzaE5hbWUgPSBjaXBoZXJTdWl0ZS5nZXRIYXNoTmFtZSgpOworICAgICAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIkNvbm5lY3Rpb25TdGF0ZVNTTHYzLmNyZWF0ZToiKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiICBjaXBoZXIgc3VpdGUgbmFtZTogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgc2Vzc2lvbi5nZXRDaXBoZXJTdWl0ZSgpKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiICBlbmNyeXB0aW9uIGFsZyBuYW1lOiAiICsgYWxnTmFtZSk7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIiAgaGFzaCBhbGcgbmFtZTogIiArIGhhc2hOYW1lKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiICBoYXNoIHNpemU6ICIgKyBoYXNoX3NpemUpOworICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCIgIGJsb2NrIHNpemU6ICIgKyBibG9ja19zaXplKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiICBJViBzaXplOiIgKyBpdl9zaXplKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiICBrZXkgc2l6ZTogIiArIGtleV9zaXplKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYnl0ZVtdIGNsaWVudFJhbmRvbSA9IHNlc3Npb24uY2xpZW50UmFuZG9tOworICAgICAgICAgICAgYnl0ZVtdIHNlcnZlclJhbmRvbSA9IHNlc3Npb24uc2VydmVyUmFuZG9tOworICAgICAgICAgICAgLy8gc28gd2UgbmVlZCBQUkYgdmFsdWUgb2Ygc2l6ZSBvZgorICAgICAgICAgICAgLy8gMipoYXNoX3NpemUgKyAyKmtleV9zaXplICsgMippdl9zaXplCisgICAgICAgICAgICBieXRlW10ga2V5X2Jsb2NrID0gbmV3IGJ5dGVbMipoYXNoX3NpemUgKyAyKmtleV9zaXplICsgMippdl9zaXplXTsKKyAgICAgICAgICAgIGJ5dGVbXSBzZWVkID0gbmV3IGJ5dGVbY2xpZW50UmFuZG9tLmxlbmd0aCArIHNlcnZlclJhbmRvbS5sZW5ndGhdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzZXJ2ZXJSYW5kb20sIDAsIHNlZWQsIDAsIHNlcnZlclJhbmRvbS5sZW5ndGgpOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShjbGllbnRSYW5kb20sIDAsIHNlZWQsIHNlcnZlclJhbmRvbS5sZW5ndGgsCisgICAgICAgICAgICAgICAgICAgIGNsaWVudFJhbmRvbS5sZW5ndGgpOworCisgICAgICAgICAgICBQUkYuY29tcHV0ZVBSRl9TU0x2MyhrZXlfYmxvY2ssIHNlc3Npb24ubWFzdGVyX3NlY3JldCwgc2VlZCk7CisKKyAgICAgICAgICAgIGJ5dGVbXSBjbGllbnRfbWFjX3NlY3JldCA9IG5ldyBieXRlW2hhc2hfc2l6ZV07CisgICAgICAgICAgICBieXRlW10gc2VydmVyX21hY19zZWNyZXQgPSBuZXcgYnl0ZVtoYXNoX3NpemVdOworICAgICAgICAgICAgYnl0ZVtdIGNsaWVudF9rZXkgPSBuZXcgYnl0ZVtrZXlfc2l6ZV07CisgICAgICAgICAgICBieXRlW10gc2VydmVyX2tleSA9IG5ldyBieXRlW2tleV9zaXplXTsKKworICAgICAgICAgICAgYm9vbGVhbiBpc19jbGllbnQgPSAhc2Vzc2lvbi5pc1NlcnZlcjsKKworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShrZXlfYmxvY2ssIDAsIGNsaWVudF9tYWNfc2VjcmV0LCAwLCBoYXNoX3NpemUpOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShrZXlfYmxvY2ssIGhhc2hfc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgc2VydmVyX21hY19zZWNyZXQsIDAsIGhhc2hfc2l6ZSk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGtleV9ibG9jaywgMipoYXNoX3NpemUsIGNsaWVudF9rZXksIDAsIGtleV9zaXplKTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoa2V5X2Jsb2NrLCAyKmhhc2hfc2l6ZStrZXlfc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgc2VydmVyX2tleSwgMCwga2V5X3NpemUpOworCisgICAgICAgICAgICBJdlBhcmFtZXRlclNwZWMgY2xpZW50SVYgPSBudWxsOworICAgICAgICAgICAgSXZQYXJhbWV0ZXJTcGVjIHNlcnZlcklWID0gbnVsbDsKKworICAgICAgICAgICAgaWYgKGlzX2V4cG9ydGFiZSkgeworICAgICAgICAgICAgICAgIGlmIChsb2dnZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiQ29ubmVjdGlvblN0YXRlU1NMdjM6IGlzX2V4cG9ydGFibGUiKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kNSA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoIk1ENSIpOworICAgICAgICAgICAgICAgIG1kNS51cGRhdGUoY2xpZW50X2tleSk7CisgICAgICAgICAgICAgICAgbWQ1LnVwZGF0ZShjbGllbnRSYW5kb20pOworICAgICAgICAgICAgICAgIG1kNS51cGRhdGUoc2VydmVyUmFuZG9tKTsKKyAgICAgICAgICAgICAgICBjbGllbnRfa2V5ID0gbWQ1LmRpZ2VzdCgpOworCisgICAgICAgICAgICAgICAgbWQ1LnVwZGF0ZShzZXJ2ZXJfa2V5KTsKKyAgICAgICAgICAgICAgICBtZDUudXBkYXRlKHNlcnZlclJhbmRvbSk7CisgICAgICAgICAgICAgICAgbWQ1LnVwZGF0ZShjbGllbnRSYW5kb20pOworICAgICAgICAgICAgICAgIHNlcnZlcl9rZXkgPSBtZDUuZGlnZXN0KCk7CisKKyAgICAgICAgICAgICAgICBrZXlfc2l6ZSA9IGNpcGhlclN1aXRlLmV4cGFuZGVkS2V5TWF0ZXJpYWw7CisKKyAgICAgICAgICAgICAgICBpZiAoYmxvY2tfc2l6ZSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIG1kNS51cGRhdGUoY2xpZW50UmFuZG9tKTsKKyAgICAgICAgICAgICAgICAgICAgbWQ1LnVwZGF0ZShzZXJ2ZXJSYW5kb20pOworICAgICAgICAgICAgICAgICAgICBjbGllbnRJViA9IG5ldyBJdlBhcmFtZXRlclNwZWMobWQ1LmRpZ2VzdCgpLCAwLCBpdl9zaXplKTsKKyAgICAgICAgICAgICAgICAgICAgbWQ1LnVwZGF0ZShzZXJ2ZXJSYW5kb20pOworICAgICAgICAgICAgICAgICAgICBtZDUudXBkYXRlKGNsaWVudFJhbmRvbSk7CisgICAgICAgICAgICAgICAgICAgIHNlcnZlcklWID0gbmV3IEl2UGFyYW1ldGVyU3BlYyhtZDUuZGlnZXN0KCksIDAsIGl2X3NpemUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoYmxvY2tfc2l6ZSAhPSAwKSB7CisgICAgICAgICAgICAgICAgY2xpZW50SVYgPSBuZXcgSXZQYXJhbWV0ZXJTcGVjKGtleV9ibG9jaywKKyAgICAgICAgICAgICAgICAgICAgICAgIDIqaGFzaF9zaXplKzIqa2V5X3NpemUsIGl2X3NpemUpOworICAgICAgICAgICAgICAgIHNlcnZlcklWID0gbmV3IEl2UGFyYW1ldGVyU3BlYyhrZXlfYmxvY2ssCisgICAgICAgICAgICAgICAgICAgICAgICAyKmhhc2hfc2l6ZSsyKmtleV9zaXplK2l2X3NpemUsIGl2X3NpemUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiaXMgZXhwb3J0YWJsZTogIitpc19leHBvcnRhYmUpOworICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJtYXN0ZXJfc2VjcmV0Iik7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50KHNlc3Npb24ubWFzdGVyX3NlY3JldCk7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oImNsaWVudF9yYW5kb20iKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnQoY2xpZW50UmFuZG9tKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigic2VydmVyX3JhbmRvbSIpOworICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludChzZXJ2ZXJSYW5kb20pOworICAgICAgICAgICAgICAgIC8vbG9nZ2VyLnByaW50bG4oImtleV9ibG9jayIpOworICAgICAgICAgICAgICAgIC8vbG9nZ2VyLnByaW50KGtleV9ibG9jayk7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oImNsaWVudF9tYWNfc2VjcmV0Iik7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50KGNsaWVudF9tYWNfc2VjcmV0KTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigic2VydmVyX21hY19zZWNyZXQiKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnQoc2VydmVyX21hY19zZWNyZXQpOworICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJjbGllbnRfa2V5Iik7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50KGNsaWVudF9rZXksIDAsIGtleV9zaXplKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigic2VydmVyX2tleSIpOworICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludChzZXJ2ZXJfa2V5LCAwLCBrZXlfc2l6ZSk7CisgICAgICAgICAgICAgICAgaWYgKGNsaWVudElWICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oImNsaWVudF9pdiIpOworICAgICAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnQoY2xpZW50SVYuZ2V0SVYoKSk7CisgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJzZXJ2ZXJfaXYiKTsKKyAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50KHNlcnZlcklWLmdldElWKCkpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJubyBJVi4iKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChhbGdOYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBlbmNDaXBoZXIgPSBuZXcgTnVsbENpcGhlcigpOworICAgICAgICAgICAgICAgIGRlY0NpcGhlciA9IG5ldyBOdWxsQ2lwaGVyKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGVuY0NpcGhlciA9IENpcGhlci5nZXRJbnN0YW5jZShhbGdOYW1lKTsKKyAgICAgICAgICAgICAgICBkZWNDaXBoZXIgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoYWxnTmFtZSk7CisgICAgICAgICAgICAgICAgaWYgKGlzX2NsaWVudCkgeyAvLyBjbGllbnQgc2lkZQorICAgICAgICAgICAgICAgICAgICBlbmNDaXBoZXIuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU2VjcmV0S2V5U3BlYyhjbGllbnRfa2V5LCAwLCBrZXlfc2l6ZSwgYWxnTmFtZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudElWKTsKKyAgICAgICAgICAgICAgICAgICAgZGVjQ2lwaGVyLmluaXQoQ2lwaGVyLkRFQ1JZUFRfTU9ERSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFNlY3JldEtleVNwZWMoc2VydmVyX2tleSwgMCwga2V5X3NpemUsIGFsZ05hbWUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJJVik7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gc2VydmVyIHNpZGUKKyAgICAgICAgICAgICAgICAgICAgZW5jQ2lwaGVyLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFNlY3JldEtleVNwZWMoc2VydmVyX2tleSwgMCwga2V5X3NpemUsIGFsZ05hbWUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJJVik7CisgICAgICAgICAgICAgICAgICAgIGRlY0NpcGhlci5pbml0KENpcGhlci5ERUNSWVBUX01PREUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTZWNyZXRLZXlTcGVjKGNsaWVudF9rZXksIDAsIGtleV9zaXplLCBhbGdOYW1lKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50SVYpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgbWVzc2FnZURpZ2VzdCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoaGFzaE5hbWUpOworICAgICAgICAgICAgaWYgKGlzX2NsaWVudCkgeyAvLyBjbGllbnQgc2lkZQorICAgICAgICAgICAgICAgIG1hY193cml0ZV9zZWNyZXQgPSBjbGllbnRfbWFjX3NlY3JldDsKKyAgICAgICAgICAgICAgICBtYWNfcmVhZF9zZWNyZXQgPSBzZXJ2ZXJfbWFjX3NlY3JldDsKKyAgICAgICAgICAgIH0gZWxzZSB7IC8vIHNlcnZlciBzaWRlCisgICAgICAgICAgICAgICAgbWFjX3dyaXRlX3NlY3JldCA9IHNlcnZlcl9tYWNfc2VjcmV0OworICAgICAgICAgICAgICAgIG1hY19yZWFkX3NlY3JldCA9IGNsaWVudF9tYWNfc2VjcmV0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGhhc2hOYW1lLmVxdWFscygiTUQ1IikpIHsKKyAgICAgICAgICAgICAgICBwYWRfMSA9IFNTTHYzQ29uc3RhbnRzLk1ENXBhZDE7CisgICAgICAgICAgICAgICAgcGFkXzIgPSBTU0x2M0NvbnN0YW50cy5NRDVwYWQyOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBwYWRfMSA9IFNTTHYzQ29uc3RhbnRzLlNIQXBhZDE7CisgICAgICAgICAgICAgICAgcGFkXzIgPSBTU0x2M0NvbnN0YW50cy5TSEFwYWQyOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbihBbGVydFByb3RvY29sLklOVEVSTkFMX0VSUk9SLAorICAgICAgICAgICAgICAgICAgICBuZXcgU1NMUHJvdG9jb2xFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAiRXJyb3IgZHVyaW5nIGNvbXB1dGF0aW9uIG9mIHNlY3VyaXR5IHBhcmFtZXRlcnMiKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBHZW5lcmljU3RyZWFtQ2lwaGVyIG9yIEdlbmVyaWNCbG9ja0NpcGhlcgorICAgICAqIGRhdGEgc3RydWN0dXJlIGZvciBzcGVjaWZpZWQgZGF0YSBvZiBzcGVjaWZpZWQgdHlwZS4KKyAgICAgKiBAdGhyb3dzIEFsZXJ0RXhjZXB0aW9uIGlmIGFsZXJ0IHdhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuY3J5cHQoYnl0ZSB0eXBlLCBieXRlW10gZnJhZ21lbnQsIGludCBvZmZzZXQsIGludCBsZW4pIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBjb250ZW50X21hY19sZW5ndGggPSBsZW4gKyBoYXNoX3NpemU7CisgICAgICAgICAgICBpbnQgcGFkZGluZ19sZW5ndGggPSAoYmxvY2tfc2l6ZSA9PSAwKSA/IDAgOiBnZXRQYWRkaW5nU2l6ZSgrK2NvbnRlbnRfbWFjX2xlbmd0aCk7CisgICAgICAgICAgICBieXRlW10gcmVzID0gbmV3IGJ5dGVbY29udGVudF9tYWNfbGVuZ3RoICsgcGFkZGluZ19sZW5ndGhdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmcmFnbWVudCwgb2Zmc2V0LCByZXMsIDAsIGxlbik7CisKKyAgICAgICAgICAgIG1hY19tYXRlcmlhbF9wYXJ0WzBdID0gdHlwZTsKKyAgICAgICAgICAgIG1hY19tYXRlcmlhbF9wYXJ0WzFdID0gKGJ5dGUpICgoMHgwMEZGMDAgJiBsZW4pID4+IDgpOworICAgICAgICAgICAgbWFjX21hdGVyaWFsX3BhcnRbMl0gPSAoYnl0ZSkgKDB4MDAwMEZGICYgbGVuKTsKKworICAgICAgICAgICAgbWVzc2FnZURpZ2VzdC51cGRhdGUobWFjX3dyaXRlX3NlY3JldCk7CisgICAgICAgICAgICBtZXNzYWdlRGlnZXN0LnVwZGF0ZShwYWRfMSk7CisgICAgICAgICAgICBtZXNzYWdlRGlnZXN0LnVwZGF0ZSh3cml0ZV9zZXFfbnVtKTsKKyAgICAgICAgICAgIG1lc3NhZ2VEaWdlc3QudXBkYXRlKG1hY19tYXRlcmlhbF9wYXJ0KTsKKyAgICAgICAgICAgIG1lc3NhZ2VEaWdlc3QudXBkYXRlKGZyYWdtZW50LCBvZmZzZXQsIGxlbik7CisgICAgICAgICAgICBieXRlW10gZGlnZXN0ID0gbWVzc2FnZURpZ2VzdC5kaWdlc3QoKTsKKyAgICAgICAgICAgIG1lc3NhZ2VEaWdlc3QudXBkYXRlKG1hY193cml0ZV9zZWNyZXQpOworICAgICAgICAgICAgbWVzc2FnZURpZ2VzdC51cGRhdGUocGFkXzIpOworICAgICAgICAgICAgbWVzc2FnZURpZ2VzdC51cGRhdGUoZGlnZXN0KTsKKyAgICAgICAgICAgIGRpZ2VzdCA9IG1lc3NhZ2VEaWdlc3QuZGlnZXN0KCk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRpZ2VzdCwgMCwgcmVzLCBsZW4sIGhhc2hfc2l6ZSk7CisKKyAgICAgICAgICAgIC8vaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICAvLyAgICBsb2dnZXIucHJpbnRsbigiTUFDIE1hdGVyaWFsOiIpOworICAgICAgICAgICAgLy8gICAgbG9nZ2VyLnByaW50KHdyaXRlX3NlcV9udW0pOworICAgICAgICAgICAgLy8gICAgbG9nZ2VyLnByaW50KG1hY19tYXRlcmlhbF9oZWFkZXIpOworICAgICAgICAgICAgLy8gICAgbG9nZ2VyLnByaW50KGZyYWdtZW50LCBvZmZzZXQsIGxlbik7CisgICAgICAgICAgICAvL30KKworICAgICAgICAgICAgaWYgKGJsb2NrX3NpemUgIT0gMCkgeworICAgICAgICAgICAgICAgIC8vIGRvIHBhZGRpbmc6CisgICAgICAgICAgICAgICAgQXJyYXlzLmZpbGwocmVzLCBjb250ZW50X21hY19sZW5ndGgtMSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcy5sZW5ndGgsIChieXRlKSAocGFkZGluZ19sZW5ndGgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChsb2dnZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJTU0xSZWNvcmRQcm90b2NvbC5lbmNyeXB0OiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIChibG9ja19zaXplICE9IDAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICJHZW5lcmljQmxvY2tDaXBoZXIgd2l0aCBwYWRkaW5nWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgK3BhZGRpbmdfbGVuZ3RoKyJdOiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICJHZW5lcmljU3RyZWFtQ2lwaGVyOiIpKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnQocmVzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ5dGVbXSByZXogPSBuZXcgYnl0ZVtlbmNDaXBoZXIuZ2V0T3V0cHV0U2l6ZShyZXMubGVuZ3RoKV07CisgICAgICAgICAgICBlbmNDaXBoZXIudXBkYXRlKHJlcywgMCwgcmVzLmxlbmd0aCwgcmV6KTsKKyAgICAgICAgICAgIGluY1NlcXVlbmNlTnVtYmVyKHdyaXRlX3NlcV9udW0pOworICAgICAgICAgICAgcmV0dXJuIHJlejsKKyAgICAgICAgfSBjYXRjaCAoR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICB0aHJvdyBuZXcgQWxlcnRFeGNlcHRpb24oQWxlcnRQcm90b2NvbC5JTlRFUk5BTF9FUlJPUiwKKyAgICAgICAgICAgICAgICAgICAgbmV3IFNTTFByb3RvY29sRXhjZXB0aW9uKCJFcnJvciBkdXJpbmcgdGhlIGVuY3J5cHRpb24iKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgdGhlIGZyYWdtZW50IG9mIHRoZSBQbGFpbnRleHQgc3RydWN0dXJlIG9mCisgICAgICogdGhlIHNwZWNpZmllZCB0eXBlIGZyb20gdGhlIHByb3ZpZGVkIGRhdGEuCisgICAgICogQHRocm93cyBBbGVydEV4Y2VwdGlvbiBpZiBhbGVydCB3YXMgb2NjdXJlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIGRlY3J5cHQoYnl0ZSB0eXBlLCBieXRlW10gZnJhZ21lbnQsCisgICAgICAgICAgICBpbnQgb2Zmc2V0LCBpbnQgbGVuKSB7CisgICAgICAgIC8vIHBsYWluIGRhdGEgb2YgdGhlIEdlbmVyaWNbU3RyZWFtfEJsb2NrXUNpcGhlciBzdHJ1Y3R1cmUKKyAgICAgICAgYnl0ZVtdIGRhdGEgPSBkZWNDaXBoZXIudXBkYXRlKGZyYWdtZW50LCBvZmZzZXQsIGxlbik7CisgICAgICAgIC8vIHRoZSAnY29udGVudCcgcGFydCBvZiB0aGUgc3RydWN0dXJlCisgICAgICAgIGJ5dGVbXSBjb250ZW50OworICAgICAgICBpZiAoYmxvY2tfc2l6ZSAhPSAwKSB7CisgICAgICAgICAgICAvLyBjaGVjayBwYWRkaW5nCisgICAgICAgICAgICBpbnQgcGFkZGluZ19sZW5ndGggPSBkYXRhW2RhdGEubGVuZ3RoLTFdOworICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPHBhZGRpbmdfbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoZGF0YVtkYXRhLmxlbmd0aC0yLWldICE9IHBhZGRpbmdfbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbGVydFByb3RvY29sLkRFQ1JZUFRJT05fRkFJTEVELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTU0xQcm90b2NvbEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlY2VpdmVkIG1lc3NhZ2UgaGFzIGJhZCBwYWRkaW5nIikpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvbnRlbnQgPSBuZXcgYnl0ZVtkYXRhLmxlbmd0aCAtIGhhc2hfc2l6ZSAtIHBhZGRpbmdfbGVuZ3RoIC0gMV07CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjb250ZW50ID0gbmV3IGJ5dGVbZGF0YS5sZW5ndGggLSBoYXNoX3NpemVdOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZVtdIG1hY192YWx1ZTsKKworICAgICAgICBtYWNfbWF0ZXJpYWxfcGFydFswXSA9IHR5cGU7CisgICAgICAgIG1hY19tYXRlcmlhbF9wYXJ0WzFdID0gKGJ5dGUpICgoMHgwMEZGMDAgJiBjb250ZW50Lmxlbmd0aCkgPj4gOCk7CisgICAgICAgIG1hY19tYXRlcmlhbF9wYXJ0WzJdID0gKGJ5dGUpICgweDAwMDBGRiAmIGNvbnRlbnQubGVuZ3RoKTsKKworICAgICAgICBtZXNzYWdlRGlnZXN0LnVwZGF0ZShtYWNfcmVhZF9zZWNyZXQpOworICAgICAgICBtZXNzYWdlRGlnZXN0LnVwZGF0ZShwYWRfMSk7CisgICAgICAgIG1lc3NhZ2VEaWdlc3QudXBkYXRlKHJlYWRfc2VxX251bSk7CisgICAgICAgIG1lc3NhZ2VEaWdlc3QudXBkYXRlKG1hY19tYXRlcmlhbF9wYXJ0KTsKKyAgICAgICAgbWVzc2FnZURpZ2VzdC51cGRhdGUoZGF0YSwgMCwgY29udGVudC5sZW5ndGgpOworICAgICAgICBtYWNfdmFsdWUgPSBtZXNzYWdlRGlnZXN0LmRpZ2VzdCgpOworICAgICAgICBtZXNzYWdlRGlnZXN0LnVwZGF0ZShtYWNfcmVhZF9zZWNyZXQpOworICAgICAgICBtZXNzYWdlRGlnZXN0LnVwZGF0ZShwYWRfMik7CisgICAgICAgIG1lc3NhZ2VEaWdlc3QudXBkYXRlKG1hY192YWx1ZSk7CisgICAgICAgIG1hY192YWx1ZSA9IG1lc3NhZ2VEaWdlc3QuZGlnZXN0KCk7CisKKyAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiRGVjcnlwdGVkOiIpOworICAgICAgICAgICAgbG9nZ2VyLnByaW50KGRhdGEpOworICAgICAgICAgICAgLy9sb2dnZXIucHJpbnRsbigiTUFDIE1hdGVyaWFsOiIpOworICAgICAgICAgICAgLy9sb2dnZXIucHJpbnQocmVhZF9zZXFfbnVtKTsKKyAgICAgICAgICAgIC8vbG9nZ2VyLnByaW50KG1hY19tYXRlcmlhbF9oZWFkZXIpOworICAgICAgICAgICAgLy9sb2dnZXIucHJpbnQoZGF0YSwgMCwgY29udGVudC5sZW5ndGgpOworICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIkV4cGVjdGVkIG1hYyB2YWx1ZToiKTsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludChtYWNfdmFsdWUpOworICAgICAgICB9CisgICAgICAgIC8vIGNoZWNraW5nIHRoZSBtYWMgdmFsdWUKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPGhhc2hfc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBpZiAobWFjX3ZhbHVlW2ldICE9IGRhdGFbaStjb250ZW50Lmxlbmd0aF0pIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWxlcnRFeGNlcHRpb24oQWxlcnRQcm90b2NvbC5CQURfUkVDT1JEX01BQywKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTU0xQcm90b2NvbEV4Y2VwdGlvbigiQmFkIHJlY29yZCBNQUMiKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCAwLCBjb250ZW50LCAwLCBjb250ZW50Lmxlbmd0aCk7CisgICAgICAgIGluY1NlcXVlbmNlTnVtYmVyKHJlYWRfc2VxX251bSk7CisgICAgICAgIHJldHVybiBjb250ZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNodXRkb3duIHRoZSBwcm90b2NvbC4gSXQgd2lsbCBiZSBpbXBvc3NpYmxlIHRvIHVzZSB0aGUgaW5zdGFuY2UKKyAgICAgKiBhZnRlciB0aGUgY2FsbGluZyBvZiB0aGlzIG1ldGhvZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzaHV0ZG93bigpIHsKKyAgICAgICAgQXJyYXlzLmZpbGwobWFjX3dyaXRlX3NlY3JldCwgKGJ5dGUpIDApOworICAgICAgICBBcnJheXMuZmlsbChtYWNfcmVhZF9zZWNyZXQsIChieXRlKSAwKTsKKyAgICAgICAgc3VwZXIuc2h1dGRvd24oKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0Nvbm5lY3Rpb25TdGF0ZVRMUy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQ29ubmVjdGlvblN0YXRlVExTLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGUwNTE5MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0Nvbm5lY3Rpb25TdGF0ZVRMUy5qYXZhCkBAIC0wLDAgKzEsMzUxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXI7CitpbXBvcnQgamF2YXguY3J5cHRvLk1hYzsKK2ltcG9ydCBqYXZheC5jcnlwdG8uTnVsbENpcGhlcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5JdlBhcmFtZXRlclNwZWM7CitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuU2VjcmV0S2V5U3BlYzsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFByb3RvY29sRXhjZXB0aW9uOworCisvKioKKyAqIFRoaXMgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBvcGVyYXRpbmcgZW52aXJvbm1lbnQgb2YgdGhlIFRMUyB2MQorICogKGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyNDYudHh0KSBSZWNvcmQgUHJvdG9jb2wgYW5kIHByb3ZpZGVzCisgKiByZWxhdGluZyBlbmNyeXB0aW9uL2RlY3J5cHRpb24gZnVuY3Rpb25hbGl0eS4KKyAqIFRoZSB3b3JrIGZ1bmN0aW9uYWxpdHkgaXMgYmFzZWQgb24gdGhlIHNlY3VyaXR5CisgKiBwYXJhbWV0ZXJzIG5lZ290aWF0ZWQgZHVyaW5nIHRoZSBoYW5kc2hha2UuCisgKi8KK3B1YmxpYyBjbGFzcyBDb25uZWN0aW9uU3RhdGVUTFMgZXh0ZW5kcyBDb25uZWN0aW9uU3RhdGUgeworCisgICAgLy8gUHJlLWNhbGN1bGF0ZWQgcHJmIGxhYmVsIHZhbHVlczoKKyAgICAvLyAia2V5IGV4cGFuc2lvbiIuZ2V0Qnl0ZXMoKQorICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBLRVlfRVhQQU5TSU9OX0xBQkVMID0geworICAgICAgICAoYnl0ZSkgMHg2QiwgKGJ5dGUpIDB4NjUsIChieXRlKSAweDc5LCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4NjUsCisgICAgICAgIChieXRlKSAweDc4LCAoYnl0ZSkgMHg3MCwgKGJ5dGUpIDB4NjEsIChieXRlKSAweDZFLCAoYnl0ZSkgMHg3MywKKyAgICAgICAgKGJ5dGUpIDB4NjksIChieXRlKSAweDZGLCAoYnl0ZSkgMHg2RSB9OworCisgICAgLy8gImNsaWVudCB3cml0ZSBrZXkiLmdldEJ5dGVzKCkKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlW10gQ0xJRU5UX1dSSVRFX0tFWV9MQUJFTCA9IHsKKyAgICAgICAgKGJ5dGUpIDB4NjMsIChieXRlKSAweDZDLCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4NjUsIChieXRlKSAweDZFLAorICAgICAgICAoYnl0ZSkgMHg3NCwgKGJ5dGUpIDB4MjAsIChieXRlKSAweDc3LCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4NjksCisgICAgICAgIChieXRlKSAweDc0LCAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4MjAsIChieXRlKSAweDZCLCAoYnl0ZSkgMHg2NSwKKyAgICAgICAgKGJ5dGUpIDB4NzkgfTsKKworICAgIC8vICJzZXJ2ZXIgd3JpdGUga2V5Ii5nZXRCeXRlcygpCisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdIFNFUlZFUl9XUklURV9LRVlfTEFCRUwgPSB7CisgICAgICAgIChieXRlKSAweDczLCAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4NzIsIChieXRlKSAweDc2LCAoYnl0ZSkgMHg2NSwKKyAgICAgICAgKGJ5dGUpIDB4NzIsIChieXRlKSAweDIwLCAoYnl0ZSkgMHg3NywgKGJ5dGUpIDB4NzIsIChieXRlKSAweDY5LAorICAgICAgICAoYnl0ZSkgMHg3NCwgKGJ5dGUpIDB4NjUsIChieXRlKSAweDIwLCAoYnl0ZSkgMHg2QiwgKGJ5dGUpIDB4NjUsCisgICAgICAgIChieXRlKSAweDc5IH07CisKKyAgICAvLyAiSVYgYmxvY2siLmdldEJ5dGVzKCkKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlW10gSVZfQkxPQ0tfTEFCRUwgPSB7CisgICAgICAgIChieXRlKSAweDQ5LCAoYnl0ZSkgMHg1NiwgKGJ5dGUpIDB4MjAsIChieXRlKSAweDYyLCAoYnl0ZSkgMHg2QywKKyAgICAgICAgKGJ5dGUpIDB4NkYsIChieXRlKSAweDYzLCAoYnl0ZSkgMHg2QiB9OworCisgICAgLy8gTUFDcyB0byBjcmVhdGUgYW5kIGNoZWNrIHRoZSBtZXNzYWdlIGludGVncml0eSBpbmZvCisgICAgcHJpdmF0ZSBmaW5hbCBNYWMgZW5jTWFjOworICAgIHByaXZhdGUgZmluYWwgTWFjIGRlY01hYzsKKworICAgIC8vIE9uY2UgY3JlYXRlZCBwZXJtYW5lbnRseSB1c2VkIGFycmF5OgorICAgIC8vIGlzIHVzZWQgdG8gY3JlYXRlIHRoZSBoZWFkZXIgb2YgdGhlIE1BQyBtYXRlcmlhbCB2YWx1ZToKKyAgICAvLyA1ID09IDEoVExTQ29tcHJlc3NlZC50eXBlKSArIDIoVExTQ29tcHJlc3NlZC52ZXJzaW9uKSArCisgICAgLy8gICAgICAyKFRMU0NvbXByZXNzZWQubGVuZ3RoKQorICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIG1hY19tYXRlcmlhbF9oZWFkZXIgPSBuZXcgYnl0ZVtdIHswLCAzLCAxLCAwLCAwfTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGhlIGluc3RhbmNlIG9mIFRMUyB2MSBDb25uZWN0aW9uIFN0YXRlLiBBbGwgb2YgdGhlCisgICAgICogc2VjdXJpdHkgcGFyYW1ldGVycyBhcmUgcHJvdmlkZWQgYnkgc2Vzc2lvbiBvYmplY3QuCisgICAgICogQHBhcmFtICAgc2Vzc2lvbjogdGhlIHNlc3NpbiBvYmplY3Qgd2hpY2ggaW5jYXBzdWxhdGVzCisgICAgICogYWxsIG9mIHRoZSBzZWN1cml0eSBwYXJhbWV0ZXJzIGVzdGFibGlzaGVkIGJ5IGhhbmRzaGFrZSBwcm90b2NvbC4KKyAgICAgKiBUaGUga2V5IGNhbGN1bGF0aW9uIGZvciB0aGUgc3RhdGUgaXMgZG9uZSBhY2NvcmRpbmcKKyAgICAgKiB0byB0aGUgVExTIHYgMS4wIFByb3RvY29sIHNwZWNpZmljYXRpb24uCisgICAgICogKGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyNDYudHh0KQorICAgICAqLworICAgIHByb3RlY3RlZCBDb25uZWN0aW9uU3RhdGVUTFMoU1NMU2Vzc2lvbkltcGwgc2Vzc2lvbikgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2lwaGVyU3VpdGUgY2lwaGVyU3VpdGUgPSBzZXNzaW9uLmNpcGhlclN1aXRlOworCisgICAgICAgICAgICBoYXNoX3NpemUgPSBjaXBoZXJTdWl0ZS5nZXRNQUNMZW5ndGgoKTsKKyAgICAgICAgICAgIGJvb2xlYW4gaXNfZXhwb3J0YWJlID0gIGNpcGhlclN1aXRlLmlzRXhwb3J0YWJsZSgpOworICAgICAgICAgICAgaW50IGtleV9zaXplID0gKGlzX2V4cG9ydGFiZSkKKyAgICAgICAgICAgICAgICA/IGNpcGhlclN1aXRlLmtleU1hdGVyaWFsCisgICAgICAgICAgICAgICAgOiBjaXBoZXJTdWl0ZS5leHBhbmRlZEtleU1hdGVyaWFsOworICAgICAgICAgICAgaW50IGl2X3NpemUgPSBjaXBoZXJTdWl0ZS5pdlNpemU7CisgICAgICAgICAgICBibG9ja19zaXplID0gY2lwaGVyU3VpdGUuZ2V0QmxvY2tTaXplKCk7CisKKyAgICAgICAgICAgIFN0cmluZyBhbGdOYW1lID0gY2lwaGVyU3VpdGUuZ2V0QnVsa0VuY3J5cHRpb25BbGdvcml0aG0oKTsKKyAgICAgICAgICAgIFN0cmluZyBtYWNOYW1lID0gY2lwaGVyU3VpdGUuZ2V0SG1hY05hbWUoKTsKKyAgICAgICAgICAgIGlmIChsb2dnZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJDb25uZWN0aW9uU3RhdGVUTFMuY3JlYXRlOiIpOworICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCIgIGNpcGhlciBzdWl0ZSBuYW1lOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgY2lwaGVyU3VpdGUuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiICBlbmNyeXB0aW9uIGFsZyBuYW1lOiAiICsgYWxnTmFtZSk7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIiAgbWFjIGFsZyBuYW1lOiAiICsgbWFjTmFtZSk7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIiAgaGFzaCBzaXplOiAiICsgaGFzaF9zaXplKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiICBibG9jayBzaXplOiAiICsgYmxvY2tfc2l6ZSk7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIiAgSVYgc2l6ZToiICsgaXZfc2l6ZSk7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIiAga2V5IHNpemU6ICIgKyBrZXlfc2l6ZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGJ5dGVbXSBjbGllbnRSYW5kb20gPSBzZXNzaW9uLmNsaWVudFJhbmRvbTsKKyAgICAgICAgICAgIGJ5dGVbXSBzZXJ2ZXJSYW5kb20gPSBzZXNzaW9uLnNlcnZlclJhbmRvbTsKKyAgICAgICAgICAgIC8vIHNvIHdlIG5lZWQgUFJGIHZhbHVlIG9mIHNpemUgb2YKKyAgICAgICAgICAgIC8vIDIqaGFzaF9zaXplICsgMiprZXlfc2l6ZSArIDIqaXZfc2l6ZQorICAgICAgICAgICAgYnl0ZVtdIGtleV9ibG9jayA9IG5ldyBieXRlWzIqaGFzaF9zaXplICsgMiprZXlfc2l6ZSArIDIqaXZfc2l6ZV07CisgICAgICAgICAgICBieXRlW10gc2VlZCA9IG5ldyBieXRlW2NsaWVudFJhbmRvbS5sZW5ndGggKyBzZXJ2ZXJSYW5kb20ubGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2VydmVyUmFuZG9tLCAwLCBzZWVkLCAwLCBzZXJ2ZXJSYW5kb20ubGVuZ3RoKTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY2xpZW50UmFuZG9tLCAwLCBzZWVkLCBzZXJ2ZXJSYW5kb20ubGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICBjbGllbnRSYW5kb20ubGVuZ3RoKTsKKworICAgICAgICAgICAgUFJGLmNvbXB1dGVQUkYoa2V5X2Jsb2NrLCBzZXNzaW9uLm1hc3Rlcl9zZWNyZXQsCisgICAgICAgICAgICAgICAgICAgIEtFWV9FWFBBTlNJT05fTEFCRUwsIHNlZWQpOworCisgICAgICAgICAgICBieXRlW10gY2xpZW50X21hY19zZWNyZXQgPSBuZXcgYnl0ZVtoYXNoX3NpemVdOworICAgICAgICAgICAgYnl0ZVtdIHNlcnZlcl9tYWNfc2VjcmV0ID0gbmV3IGJ5dGVbaGFzaF9zaXplXTsKKyAgICAgICAgICAgIGJ5dGVbXSBjbGllbnRfa2V5ID0gbmV3IGJ5dGVba2V5X3NpemVdOworICAgICAgICAgICAgYnl0ZVtdIHNlcnZlcl9rZXkgPSBuZXcgYnl0ZVtrZXlfc2l6ZV07CisKKyAgICAgICAgICAgIGJvb2xlYW4gaXNfY2xpZW50ID0gIXNlc3Npb24uaXNTZXJ2ZXI7CisKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoa2V5X2Jsb2NrLCAwLCBjbGllbnRfbWFjX3NlY3JldCwgMCwgaGFzaF9zaXplKTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoa2V5X2Jsb2NrLCBoYXNoX3NpemUsCisgICAgICAgICAgICAgICAgICAgIHNlcnZlcl9tYWNfc2VjcmV0LCAwLCBoYXNoX3NpemUpOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShrZXlfYmxvY2ssIDIqaGFzaF9zaXplLCBjbGllbnRfa2V5LCAwLCBrZXlfc2l6ZSk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGtleV9ibG9jaywgMipoYXNoX3NpemUra2V5X3NpemUsCisgICAgICAgICAgICAgICAgICAgIHNlcnZlcl9rZXksIDAsIGtleV9zaXplKTsKKworICAgICAgICAgICAgSXZQYXJhbWV0ZXJTcGVjIGNsaWVudElWID0gbnVsbDsKKyAgICAgICAgICAgIEl2UGFyYW1ldGVyU3BlYyBzZXJ2ZXJJViA9IG51bGw7CisKKyAgICAgICAgICAgIGlmIChpc19leHBvcnRhYmUpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNsaWVudFJhbmRvbSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQsIDAsIGNsaWVudFJhbmRvbS5sZW5ndGgpOworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2VydmVyUmFuZG9tLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgc2VlZCwgY2xpZW50UmFuZG9tLmxlbmd0aCwgc2VydmVyUmFuZG9tLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGZpbmFsX2NsaWVudF9rZXkgPQorICAgICAgICAgICAgICAgICAgICBuZXcgYnl0ZVtjaXBoZXJTdWl0ZS5leHBhbmRlZEtleU1hdGVyaWFsXTsKKyAgICAgICAgICAgICAgICBieXRlW10gZmluYWxfc2VydmVyX2tleSA9CisgICAgICAgICAgICAgICAgICAgIG5ldyBieXRlW2NpcGhlclN1aXRlLmV4cGFuZGVkS2V5TWF0ZXJpYWxdOworICAgICAgICAgICAgICAgIFBSRi5jb21wdXRlUFJGKGZpbmFsX2NsaWVudF9rZXksIGNsaWVudF9rZXksCisgICAgICAgICAgICAgICAgICAgICAgICBDTElFTlRfV1JJVEVfS0VZX0xBQkVMLCBzZWVkKTsKKyAgICAgICAgICAgICAgICBQUkYuY29tcHV0ZVBSRihmaW5hbF9zZXJ2ZXJfa2V5LCBzZXJ2ZXJfa2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgU0VSVkVSX1dSSVRFX0tFWV9MQUJFTCwgc2VlZCk7CisgICAgICAgICAgICAgICAgY2xpZW50X2tleSA9IGZpbmFsX2NsaWVudF9rZXk7CisgICAgICAgICAgICAgICAgc2VydmVyX2tleSA9IGZpbmFsX3NlcnZlcl9rZXk7CisgICAgICAgICAgICAgICAgaWYgKGJsb2NrX3NpemUgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICBieXRlW10gaXZfYmxvY2sgPSBuZXcgYnl0ZVsyKml2X3NpemVdOworICAgICAgICAgICAgICAgICAgICBQUkYuY29tcHV0ZVBSRihpdl9ibG9jaywgbnVsbCwgSVZfQkxPQ0tfTEFCRUwsIHNlZWQpOworICAgICAgICAgICAgICAgICAgICBjbGllbnRJViA9IG5ldyBJdlBhcmFtZXRlclNwZWMoaXZfYmxvY2ssIDAsIGl2X3NpemUpOworICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJJViA9IG5ldyBJdlBhcmFtZXRlclNwZWMoaXZfYmxvY2ssIGl2X3NpemUsIGl2X3NpemUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoYmxvY2tfc2l6ZSAhPSAwKSB7CisgICAgICAgICAgICAgICAgY2xpZW50SVYgPSBuZXcgSXZQYXJhbWV0ZXJTcGVjKGtleV9ibG9jaywKKyAgICAgICAgICAgICAgICAgICAgICAgIDIqKGhhc2hfc2l6ZStrZXlfc2l6ZSksIGl2X3NpemUpOworICAgICAgICAgICAgICAgIHNlcnZlcklWID0gbmV3IEl2UGFyYW1ldGVyU3BlYyhrZXlfYmxvY2ssCisgICAgICAgICAgICAgICAgICAgICAgICAyKihoYXNoX3NpemUra2V5X3NpemUpK2l2X3NpemUsIGl2X3NpemUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiaXMgZXhwb3J0YWJsZTogIitpc19leHBvcnRhYmUpOworICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJtYXN0ZXJfc2VjcmV0Iik7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50KHNlc3Npb24ubWFzdGVyX3NlY3JldCk7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oImNsaWVudF9yYW5kb20iKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnQoY2xpZW50UmFuZG9tKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigic2VydmVyX3JhbmRvbSIpOworICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludChzZXJ2ZXJSYW5kb20pOworICAgICAgICAgICAgICAgIC8vbG9nZ2VyLnByaW50bG4oImtleV9ibG9jayIpOworICAgICAgICAgICAgICAgIC8vbG9nZ2VyLnByaW50KGtleV9ibG9jayk7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oImNsaWVudF9tYWNfc2VjcmV0Iik7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50KGNsaWVudF9tYWNfc2VjcmV0KTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigic2VydmVyX21hY19zZWNyZXQiKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnQoc2VydmVyX21hY19zZWNyZXQpOworICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJjbGllbnRfa2V5Iik7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50KGNsaWVudF9rZXkpOworICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJzZXJ2ZXJfa2V5Iik7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50KHNlcnZlcl9rZXkpOworICAgICAgICAgICAgICAgIGlmIChjbGllbnRJViA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJubyBJVi4iKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiY2xpZW50X2l2Iik7CisgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludChjbGllbnRJVi5nZXRJVigpKTsKKyAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oInNlcnZlcl9pdiIpOworICAgICAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnQoc2VydmVySVYuZ2V0SVYoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoYWxnTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgZW5jQ2lwaGVyID0gbmV3IE51bGxDaXBoZXIoKTsKKyAgICAgICAgICAgICAgICBkZWNDaXBoZXIgPSBuZXcgTnVsbENpcGhlcigpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBlbmNDaXBoZXIgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoYWxnTmFtZSk7CisgICAgICAgICAgICAgICAgZGVjQ2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKGFsZ05hbWUpOworICAgICAgICAgICAgICAgIGlmIChpc19jbGllbnQpIHsgLy8gY2xpZW50IHNpZGUKKyAgICAgICAgICAgICAgICAgICAgZW5jQ2lwaGVyLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFNlY3JldEtleVNwZWMoY2xpZW50X2tleSwgYWxnTmFtZSksIGNsaWVudElWKTsKKyAgICAgICAgICAgICAgICAgICAgZGVjQ2lwaGVyLmluaXQoQ2lwaGVyLkRFQ1JZUFRfTU9ERSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFNlY3JldEtleVNwZWMoc2VydmVyX2tleSwgYWxnTmFtZSksIHNlcnZlcklWKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBzZXJ2ZXIgc2lkZQorICAgICAgICAgICAgICAgICAgICBlbmNDaXBoZXIuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU2VjcmV0S2V5U3BlYyhzZXJ2ZXJfa2V5LCBhbGdOYW1lKSwgc2VydmVySVYpOworICAgICAgICAgICAgICAgICAgICBkZWNDaXBoZXIuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU2VjcmV0S2V5U3BlYyhjbGllbnRfa2V5LCBhbGdOYW1lKSwgY2xpZW50SVYpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZW5jTWFjID0gTWFjLmdldEluc3RhbmNlKG1hY05hbWUpOworICAgICAgICAgICAgZGVjTWFjID0gTWFjLmdldEluc3RhbmNlKG1hY05hbWUpOworICAgICAgICAgICAgaWYgKGlzX2NsaWVudCkgeyAvLyBjbGllbnQgc2lkZQorICAgICAgICAgICAgICAgIGVuY01hYy5pbml0KG5ldyBTZWNyZXRLZXlTcGVjKGNsaWVudF9tYWNfc2VjcmV0LCBtYWNOYW1lKSk7CisgICAgICAgICAgICAgICAgZGVjTWFjLmluaXQobmV3IFNlY3JldEtleVNwZWMoc2VydmVyX21hY19zZWNyZXQsIG1hY05hbWUpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IC8vIHNlcnZlciBzaWRlCisgICAgICAgICAgICAgICAgZW5jTWFjLmluaXQobmV3IFNlY3JldEtleVNwZWMoc2VydmVyX21hY19zZWNyZXQsIG1hY05hbWUpKTsKKyAgICAgICAgICAgICAgICBkZWNNYWMuaW5pdChuZXcgU2VjcmV0S2V5U3BlYyhjbGllbnRfbWFjX3NlY3JldCwgbWFjTmFtZSkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbihBbGVydFByb3RvY29sLklOVEVSTkFMX0VSUk9SLAorICAgICAgICAgICAgICAgICAgICBuZXcgU1NMUHJvdG9jb2xFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAiRXJyb3IgZHVyaW5nIGNvbXB1dGF0aW9uIG9mIHNlY3VyaXR5IHBhcmFtZXRlcnMiKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBHZW5lcmljU3RyZWFtQ2lwaGVyIG9yIEdlbmVyaWNCbG9ja0NpcGhlcgorICAgICAqIGRhdGEgc3RydWN0dXJlIGZvciBzcGVjaWZpZWQgZGF0YSBvZiBzcGVjaWZpZWQgdHlwZS4KKyAgICAgKiBAdGhyb3dzIEFsZXJ0RXhjZXB0aW9uIGlmIGFsZXJ0IHdhcyBvY2N1cnJlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuY3J5cHQoYnl0ZSB0eXBlLCBieXRlW10gZnJhZ21lbnQsIGludCBvZmZzZXQsIGludCBsZW4pIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBjb250ZW50X21hY19sZW5ndGggPSBsZW4gKyBoYXNoX3NpemU7CisgICAgICAgICAgICBpbnQgcGFkZGluZ19sZW5ndGggPSAoYmxvY2tfc2l6ZSA9PSAwKSA/IDAgOiBnZXRQYWRkaW5nU2l6ZSgrK2NvbnRlbnRfbWFjX2xlbmd0aCk7CisgICAgICAgICAgICBieXRlW10gcmVzID0gbmV3IGJ5dGVbY29udGVudF9tYWNfbGVuZ3RoICsgcGFkZGluZ19sZW5ndGhdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmcmFnbWVudCwgb2Zmc2V0LCByZXMsIDAsIGxlbik7CisKKyAgICAgICAgICAgIG1hY19tYXRlcmlhbF9oZWFkZXJbMF0gPSB0eXBlOworICAgICAgICAgICAgbWFjX21hdGVyaWFsX2hlYWRlclszXSA9IChieXRlKSAoKDB4MDBGRjAwICYgbGVuKSA+PiA4KTsKKyAgICAgICAgICAgIG1hY19tYXRlcmlhbF9oZWFkZXJbNF0gPSAoYnl0ZSkgKDB4MDAwMEZGICYgbGVuKTsKKworICAgICAgICAgICAgZW5jTWFjLnVwZGF0ZSh3cml0ZV9zZXFfbnVtKTsKKyAgICAgICAgICAgIGVuY01hYy51cGRhdGUobWFjX21hdGVyaWFsX2hlYWRlcik7CisgICAgICAgICAgICBlbmNNYWMudXBkYXRlKGZyYWdtZW50LCBvZmZzZXQsIGxlbik7CisgICAgICAgICAgICBlbmNNYWMuZG9GaW5hbChyZXMsIGxlbik7CisKKyAgICAgICAgICAgIC8vaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICAvLyAgICBsb2dnZXIucHJpbnRsbigiTUFDIE1hdGVyaWFsOiIpOworICAgICAgICAgICAgLy8gICAgbG9nZ2VyLnByaW50KHdyaXRlX3NlcV9udW0pOworICAgICAgICAgICAgLy8gICAgbG9nZ2VyLnByaW50KG1hY19tYXRlcmlhbF9oZWFkZXIpOworICAgICAgICAgICAgLy8gICAgbG9nZ2VyLnByaW50KGZyYWdtZW50LCBvZmZzZXQsIGxlbik7CisgICAgICAgICAgICAvL30KKworICAgICAgICAgICAgaWYgKGJsb2NrX3NpemUgIT0gMCkgeworICAgICAgICAgICAgICAgIC8vIGRvIHBhZGRpbmc6CisgICAgICAgICAgICAgICAgQXJyYXlzLmZpbGwocmVzLCBjb250ZW50X21hY19sZW5ndGgtMSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcy5sZW5ndGgsIChieXRlKSAocGFkZGluZ19sZW5ndGgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChsb2dnZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJTU0xSZWNvcmRQcm90b2NvbC5kb19lbmNyeXB0aW9uOiBHZW5lcmljIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAoYmxvY2tfc2l6ZSAhPSAwCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAiQmxvY2tDaXBoZXIgd2l0aCBwYWRkaW5nWyIrcGFkZGluZ19sZW5ndGgrIl06IgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogIlN0cmVhbUNpcGhlcjoiKSk7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50KHJlcyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBieXRlW10gcmV6ID0gbmV3IGJ5dGVbZW5jQ2lwaGVyLmdldE91dHB1dFNpemUocmVzLmxlbmd0aCldOworICAgICAgICAgICAgLy8gV2Ugc2hvdWxkIG5vdCBjYWxsIGp1c3QgZG9GaW5hbCBiZWNhdXNlIGl0IHJlaW5pdGlhbGl6ZQorICAgICAgICAgICAgLy8gdGhlIGNpcGhlciwgYnV0IGFzIHNheXMgcmZjIDIyNDY6CisgICAgICAgICAgICAvLyAiRm9yIHN0cmVhbSBjaXBoZXJzIHRoYXQgZG8gbm90IHVzZSBhIHN5bmNocm9uaXphdGlvbgorICAgICAgICAgICAgLy8gdmVjdG9yIChzdWNoIGFzIFJDNCksIHRoZSBzdHJlYW0gY2lwaGVyIHN0YXRlIGZyb20gdGhlIGVuZAorICAgICAgICAgICAgLy8gb2Ygb25lIHJlY29yZCBpcyBzaW1wbHkgdXNlZCBvbiB0aGUgc3Vic2VxdWVudCBwYWNrZXQuIgorICAgICAgICAgICAgLy8gYW5kIGZvciBibG9jayBjaXBoZXJzOgorICAgICAgICAgICAgLy8gIlRoZSBJViBmb3Igc3Vic2VxdWVudCByZWNvcmRzIGlzIHRoZSBsYXN0IGNpcGhlcnRleHQgYmxvY2sgZnJvbQorICAgICAgICAgICAgLy8gdGhlIHByZXZpb3VzIHJlY29yZC4iCisgICAgICAgICAgICAvLyBpLmUuIHdlIHNob3VsZCBrZWVwIHRoZSBjaXBoZXIgc3RhdGUuCisgICAgICAgICAgICBlbmNDaXBoZXIudXBkYXRlKHJlcywgMCwgcmVzLmxlbmd0aCwgcmV6KTsKKyAgICAgICAgICAgIGluY1NlcXVlbmNlTnVtYmVyKHdyaXRlX3NlcV9udW0pOworICAgICAgICAgICAgcmV0dXJuIHJlejsKKyAgICAgICAgfSBjYXRjaCAoR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICB0aHJvdyBuZXcgQWxlcnRFeGNlcHRpb24oQWxlcnRQcm90b2NvbC5JTlRFUk5BTF9FUlJPUiwKKyAgICAgICAgICAgICAgICAgICAgbmV3IFNTTFByb3RvY29sRXhjZXB0aW9uKCJFcnJvciBkdXJpbmcgdGhlIGVuY3J5cHRpb24iKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgdGhlIGZyYWdtZW50IG9mIHRoZSBQbGFpbnRleHQgc3RydWN0dXJlIG9mCisgICAgICogdGhlIHNwZWNpZmllZCB0eXBlIGZyb20gdGhlIHByb3ZpZGVkIGRhdGEgcmVwcmVzZW50aW5nCisgICAgICogdGhlIEdlbmVyaWNbU3RyZWFtfEJsb2NrXUNpcGhlciBzdHJ1Y3R1cmUuCisgICAgICogQHRocm93cyBBbGVydEV4Y2VwdGlvbiBpZiBhbGVydCB3YXMgb2NjdXJyZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBkZWNyeXB0KGJ5dGUgdHlwZSwgYnl0ZVtdIGZyYWdtZW50LAorICAgICAgICAgICAgaW50IG9mZnNldCwgaW50IGxlbikgeworICAgICAgICAvLyBwbGFpbiBkYXRhIG9mIHRoZSBHZW5lcmljW1N0cmVhbXxCbG9ja11DaXBoZXIgc3RydWN0dXJlCisgICAgICAgIGJ5dGVbXSBkYXRhID0gZGVjQ2lwaGVyLnVwZGF0ZShmcmFnbWVudCwgb2Zmc2V0LCBsZW4pOworICAgICAgICAvLyB0aGUgJ2NvbnRlbnQnIHBhcnQgb2YgdGhlIHN0cnVjdHVyZQorICAgICAgICBieXRlW10gY29udGVudDsKKyAgICAgICAgaWYgKGJsb2NrX3NpemUgIT0gMCkgeworICAgICAgICAgICAgLy8gY2hlY2sgcGFkZGluZworICAgICAgICAgICAgaW50IHBhZGRpbmdfbGVuZ3RoID0gZGF0YVtkYXRhLmxlbmd0aC0xXTsKKyAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxwYWRkaW5nX2xlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGRhdGFbZGF0YS5sZW5ndGgtMi1pXSAhPSBwYWRkaW5nX2xlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWxlcnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWxlcnRQcm90b2NvbC5ERUNSWVBUSU9OX0ZBSUxFRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU1NMUHJvdG9jb2xFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWNlaXZlZCBtZXNzYWdlIGhhcyBiYWQgcGFkZGluZyIpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb250ZW50ID0gbmV3IGJ5dGVbZGF0YS5sZW5ndGggLSBoYXNoX3NpemUgLSBwYWRkaW5nX2xlbmd0aCAtIDFdOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY29udGVudCA9IG5ldyBieXRlW2RhdGEubGVuZ3RoIC0gaGFzaF9zaXplXTsKKyAgICAgICAgfQorCisgICAgICAgIG1hY19tYXRlcmlhbF9oZWFkZXJbMF0gPSB0eXBlOworICAgICAgICBtYWNfbWF0ZXJpYWxfaGVhZGVyWzNdID0gKGJ5dGUpICgoMHgwMEZGMDAgJiBjb250ZW50Lmxlbmd0aCkgPj4gOCk7CisgICAgICAgIG1hY19tYXRlcmlhbF9oZWFkZXJbNF0gPSAoYnl0ZSkgKDB4MDAwMEZGICYgY29udGVudC5sZW5ndGgpOworCisgICAgICAgIGRlY01hYy51cGRhdGUocmVhZF9zZXFfbnVtKTsKKyAgICAgICAgZGVjTWFjLnVwZGF0ZShtYWNfbWF0ZXJpYWxfaGVhZGVyKTsKKyAgICAgICAgZGVjTWFjLnVwZGF0ZShkYXRhLCAwLCBjb250ZW50Lmxlbmd0aCk7IC8vIG1hYy51cGRhdGUoZnJhZ21lbnQpOworICAgICAgICBieXRlW10gbWFjX3ZhbHVlID0gZGVjTWFjLmRvRmluYWwoKTsKKyAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiRGVjcnlwdGVkOiIpOworICAgICAgICAgICAgbG9nZ2VyLnByaW50KGRhdGEpOworICAgICAgICAgICAgLy9sb2dnZXIucHJpbnRsbigiTUFDIE1hdGVyaWFsOiIpOworICAgICAgICAgICAgLy9sb2dnZXIucHJpbnQocmVhZF9zZXFfbnVtKTsKKyAgICAgICAgICAgIC8vbG9nZ2VyLnByaW50KG1hY19tYXRlcmlhbF9oZWFkZXIpOworICAgICAgICAgICAgLy9sb2dnZXIucHJpbnQoZGF0YSwgMCwgY29udGVudC5sZW5ndGgpOworICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIkV4cGVjdGVkIG1hYyB2YWx1ZToiKTsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludChtYWNfdmFsdWUpOworICAgICAgICB9CisgICAgICAgIC8vIGNoZWNraW5nIHRoZSBtYWMgdmFsdWUKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPGhhc2hfc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBpZiAobWFjX3ZhbHVlW2ldICE9IGRhdGFbaStjb250ZW50Lmxlbmd0aF0pIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWxlcnRFeGNlcHRpb24oQWxlcnRQcm90b2NvbC5CQURfUkVDT1JEX01BQywKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTU0xQcm90b2NvbEV4Y2VwdGlvbigiQmFkIHJlY29yZCBNQUMiKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCAwLCBjb250ZW50LCAwLCBjb250ZW50Lmxlbmd0aCk7CisgICAgICAgIGluY1NlcXVlbmNlTnVtYmVyKHJlYWRfc2VxX251bSk7CisgICAgICAgIHJldHVybiBjb250ZW50OworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQ29udGVudFR5cGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0NvbnRlbnRUeXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjk3MDRmNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0NvbnRlbnRUeXBlLmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW5jYXBzdWxhdGVzIHRoZSBjb25zdGFudHMgZGV0ZXJtaW5pbmcgdGhlCisgKiB0eXBlcyBvZiBTU0wvVExTIHJlY29yZCdzIGNvbnRlbnQgZGF0YS4KKyAqIENvbnN0YW50IHZhbHVlcyBhcmUgdGFrZW4gYWNjb3JkaW5nIHRvIHRoZSBUTFMgdjEgc3BlY2lmaWNhdGlvbgorICogKGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyNDYudHh0KS4KKyAqLworcHVibGljIGNsYXNzIENvbnRlbnRUeXBlIHsKKworICAgIC8qKgorICAgICAqIElkZW50aWZpZXMgY2hhbmdlIGNpcGhlciBzcGVjIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJ5dGUgQ0hBTkdFX0NJUEhFUl9TUEVDID0gMjA7CisKKyAgICAvKioKKyAgICAgKiBJZGVudGlmaWVzIGFsZXJ0IG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJ5dGUgQUxFUlQgPSAyMTsKKworICAgIC8qKgorICAgICAqIElkZW50aWZpZXMgaGFuZHNoYWtlIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJ5dGUgSEFORFNIQUtFID0gMjI7CisKKyAgICAvKioKKyAgICAgKiBJZGVudGlmaWVzIGFwcGxpY2F0aW9uIGRhdGEgbWVzc2FnZQorICAgICAqLworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgYnl0ZSBBUFBMSUNBVElPTl9EQVRBID0gMjM7CisKK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvREhQYXJhbWV0ZXJzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9ESFBhcmFtZXRlcnMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40OTg4ZDVlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvREhQYXJhbWV0ZXJzLmphdmEKQEAgLTAsMCArMSwxMDggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKKy8qKgorICogVGhpcyBjbGFzcyBjb250YWlucyB3ZWxsLWtub3duIHByaW1lcworICovCitwdWJsaWMgY2xhc3MgREhQYXJhbWV0ZXJzIHsKKworICAgIC8vIFdlbGwta25vd24gNTEyIGJpdCBwcmltZQorICAgIC8vIGh0dHA6Ly9uZXdzLmhwaW5nLm9yZy9zY2kuY3J5cHQuYXJjaGl2ZS8yMzcwLmh0bWwKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlW10gcHJpbWU1MTIgPSBuZXcgYnl0ZVtdIHsgKGJ5dGUpIDB4RjUsIChieXRlKSAweDJBLCAoYnl0ZSkgMHhGRiwKKyAgICAgICAgICAgIChieXRlKSAweDNDLCAoYnl0ZSkgMHhFMSwgKGJ5dGUpIDB4QjEsIChieXRlKSAweDI5LCAoYnl0ZSkgMHg0MCwKKyAgICAgICAgICAgIChieXRlKSAweDE4LCAoYnl0ZSkgMHgxMSwgKGJ5dGUpIDB4OEQsIChieXRlKSAweDdDLCAoYnl0ZSkgMHg4NCwKKyAgICAgICAgICAgIChieXRlKSAweEE3LCAoYnl0ZSkgMHgwQSwgKGJ5dGUpIDB4NzIsIChieXRlKSAweEQ2LCAoYnl0ZSkgMHg4NiwKKyAgICAgICAgICAgIChieXRlKSAweEM0LCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MTksIChieXRlKSAweEM4LCAoYnl0ZSkgMHgwNywKKyAgICAgICAgICAgIChieXRlKSAweDI5LCAoYnl0ZSkgMHg3QSwgKGJ5dGUpIDB4Q0EsIChieXRlKSAweDk1LCAoYnl0ZSkgMHgwQywKKyAgICAgICAgICAgIChieXRlKSAweEQ5LCAoYnl0ZSkgMHg5NiwgKGJ5dGUpIDB4OUYsIChieXRlKSAweEFCLCAoYnl0ZSkgMHhEMCwKKyAgICAgICAgICAgIChieXRlKSAweDBBLCAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4OUIsIChieXRlKSAweDAyLCAoYnl0ZSkgMHg0NiwKKyAgICAgICAgICAgIChieXRlKSAweEQzLCAoYnl0ZSkgMHgwOCwgKGJ5dGUpIDB4M0QsIChieXRlKSAweDY2LCAoYnl0ZSkgMHhBNCwKKyAgICAgICAgICAgIChieXRlKSAweDVELCAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4OUYsIChieXRlKSAweDlDLCAoYnl0ZSkgMHg3QywKKyAgICAgICAgICAgIChieXRlKSAweEJELCAoYnl0ZSkgMHg4OSwgKGJ5dGUpIDB4NEIsIChieXRlKSAweDIyLCAoYnl0ZSkgMHgxOSwKKyAgICAgICAgICAgIChieXRlKSAweDI2LCAoYnl0ZSkgMHhCQSwgKGJ5dGUpIDB4QUIsIChieXRlKSAweEEyLCAoYnl0ZSkgMHg1RSwKKyAgICAgICAgICAgIChieXRlKSAweEMzLCAoYnl0ZSkgMHg1NSwgKGJ5dGUpIDB4RTksIChieXRlKSAweDJBLCAoYnl0ZSkgMHgwNSwKKyAgICAgICAgICAgIChieXRlKSAweDVGIH07CisKKyAgICAvLyBXZWxsLUtub3duIEdyb3VwIDE6IEEgNzY4IGJpdCBwcmltZSByZmMgMjUzOQorICAgIC8vIChodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyNTM5LnR4dD9udW1iZXI9MjUzOSkKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlW10gcHJpbWVHcm91cDEgPSB7IChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLAorICAgICAgICAgICAgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEM5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MEYsIChieXRlKSAweERBLCAoYnl0ZSkgMHhBMiwgKGJ5dGUpIDB4MjEsIChieXRlKSAweDY4LAorICAgICAgICAgICAgKGJ5dGUpIDB4QzIsIChieXRlKSAweDM0LCAoYnl0ZSkgMHhDNCwgKGJ5dGUpIDB4QzYsIChieXRlKSAweDYyLAorICAgICAgICAgICAgKGJ5dGUpIDB4OEIsIChieXRlKSAweDgwLCAoYnl0ZSkgMHhEQywgKGJ5dGUpIDB4MUMsIChieXRlKSAweEQxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjksIChieXRlKSAweDAyLCAoYnl0ZSkgMHg0RSwgKGJ5dGUpIDB4MDgsIChieXRlKSAweDhBLAorICAgICAgICAgICAgKGJ5dGUpIDB4NjcsIChieXRlKSAweENDLCAoYnl0ZSkgMHg3NCwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDBCLAorICAgICAgICAgICAgKGJ5dGUpIDB4QkUsIChieXRlKSAweEE2LCAoYnl0ZSkgMHgzQiwgKGJ5dGUpIDB4MTMsIChieXRlKSAweDlCLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjIsIChieXRlKSAweDUxLCAoYnl0ZSkgMHg0QSwgKGJ5dGUpIDB4MDgsIChieXRlKSAweDc5LAorICAgICAgICAgICAgKGJ5dGUpIDB4OEUsIChieXRlKSAweDM0LCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4REQsIChieXRlKSAweEVGLAorICAgICAgICAgICAgKGJ5dGUpIDB4OTUsIChieXRlKSAweDE5LCAoYnl0ZSkgMHhCMywgKGJ5dGUpIDB4Q0QsIChieXRlKSAweDNBLAorICAgICAgICAgICAgKGJ5dGUpIDB4NDMsIChieXRlKSAweDFCLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4MkIsIChieXRlKSAweDBBLAorICAgICAgICAgICAgKGJ5dGUpIDB4NkQsIChieXRlKSAweEYyLCAoYnl0ZSkgMHg1RiwgKGJ5dGUpIDB4MTQsIChieXRlKSAweDM3LAorICAgICAgICAgICAgKGJ5dGUpIDB4NEYsIChieXRlKSAweEUxLCAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4NkQsIChieXRlKSAweDZELAorICAgICAgICAgICAgKGJ5dGUpIDB4NTEsIChieXRlKSAweEMyLCAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4RTQsIChieXRlKSAweDg1LAorICAgICAgICAgICAgKGJ5dGUpIDB4QjUsIChieXRlKSAweDc2LCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4NUUsIChieXRlKSAweDdFLAorICAgICAgICAgICAgKGJ5dGUpIDB4QzYsIChieXRlKSAweEY0LCAoYnl0ZSkgMHg0QywgKGJ5dGUpIDB4NDIsIChieXRlKSAweEU5LAorICAgICAgICAgICAgKGJ5dGUpIDB4QTYsIChieXRlKSAweDNBLCAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4MjAsIChieXRlKSAweEZGLAorICAgICAgICAgICAgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLAorICAgICAgICAgICAgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGIH07CisKKyAgICAvLyBXZWxsLUtub3duIEdyb3VwIDI6IEEgMTAyNCBiaXQgcHJpbWUgcmZjIDI1MzkKKyAgICAvLyAoaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjUzOS50eHQ/bnVtYmVyPTI1MzkpCisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdIHByaW1lR3JvdXAyID0geyAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwKKyAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhDOSwKKyAgICAgICAgICAgIChieXRlKSAweDBGLCAoYnl0ZSkgMHhEQSwgKGJ5dGUpIDB4QTIsIChieXRlKSAweDIxLCAoYnl0ZSkgMHg2OCwKKyAgICAgICAgICAgIChieXRlKSAweEMyLCAoYnl0ZSkgMHgzNCwgKGJ5dGUpIDB4QzQsIChieXRlKSAweEM2LCAoYnl0ZSkgMHg2MiwKKyAgICAgICAgICAgIChieXRlKSAweDhCLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4REMsIChieXRlKSAweDFDLCAoYnl0ZSkgMHhEMSwKKyAgICAgICAgICAgIChieXRlKSAweDI5LCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4NEUsIChieXRlKSAweDA4LCAoYnl0ZSkgMHg4QSwKKyAgICAgICAgICAgIChieXRlKSAweDY3LCAoYnl0ZSkgMHhDQywgKGJ5dGUpIDB4NzQsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwQiwKKyAgICAgICAgICAgIChieXRlKSAweEJFLCAoYnl0ZSkgMHhBNiwgKGJ5dGUpIDB4M0IsIChieXRlKSAweDEzLCAoYnl0ZSkgMHg5QiwKKyAgICAgICAgICAgIChieXRlKSAweDIyLCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4NEEsIChieXRlKSAweDA4LCAoYnl0ZSkgMHg3OSwKKyAgICAgICAgICAgIChieXRlKSAweDhFLCAoYnl0ZSkgMHgzNCwgKGJ5dGUpIDB4MDQsIChieXRlKSAweERELCAoYnl0ZSkgMHhFRiwKKyAgICAgICAgICAgIChieXRlKSAweDk1LCAoYnl0ZSkgMHgxOSwgKGJ5dGUpIDB4QjMsIChieXRlKSAweENELCAoYnl0ZSkgMHgzQSwKKyAgICAgICAgICAgIChieXRlKSAweDQzLCAoYnl0ZSkgMHgxQiwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDJCLCAoYnl0ZSkgMHgwQSwKKyAgICAgICAgICAgIChieXRlKSAweDZELCAoYnl0ZSkgMHhGMiwgKGJ5dGUpIDB4NUYsIChieXRlKSAweDE0LCAoYnl0ZSkgMHgzNywKKyAgICAgICAgICAgIChieXRlKSAweDRGLCAoYnl0ZSkgMHhFMSwgKGJ5dGUpIDB4MzUsIChieXRlKSAweDZELCAoYnl0ZSkgMHg2RCwKKyAgICAgICAgICAgIChieXRlKSAweDUxLCAoYnl0ZSkgMHhDMiwgKGJ5dGUpIDB4NDUsIChieXRlKSAweEU0LCAoYnl0ZSkgMHg4NSwKKyAgICAgICAgICAgIChieXRlKSAweEI1LCAoYnl0ZSkgMHg3NiwgKGJ5dGUpIDB4NjIsIChieXRlKSAweDVFLCAoYnl0ZSkgMHg3RSwKKyAgICAgICAgICAgIChieXRlKSAweEM2LCAoYnl0ZSkgMHhGNCwgKGJ5dGUpIDB4NEMsIChieXRlKSAweDQyLCAoYnl0ZSkgMHhFOSwKKyAgICAgICAgICAgIChieXRlKSAweEE2LCAoYnl0ZSkgMHgzNywgKGJ5dGUpIDB4RUQsIChieXRlKSAweDZCLCAoYnl0ZSkgMHgwQiwKKyAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHg1QywgKGJ5dGUpIDB4QjYsIChieXRlKSAweEY0LCAoYnl0ZSkgMHgwNiwKKyAgICAgICAgICAgIChieXRlKSAweEI3LCAoYnl0ZSkgMHhFRCwgKGJ5dGUpIDB4RUUsIChieXRlKSAweDM4LCAoYnl0ZSkgMHg2QiwKKyAgICAgICAgICAgIChieXRlKSAweEZCLCAoYnl0ZSkgMHg1QSwgKGJ5dGUpIDB4ODksIChieXRlKSAweDlGLCAoYnl0ZSkgMHhBNSwKKyAgICAgICAgICAgIChieXRlKSAweEFFLCAoYnl0ZSkgMHg5RiwgKGJ5dGUpIDB4MjQsIChieXRlKSAweDExLCAoYnl0ZSkgMHg3QywKKyAgICAgICAgICAgIChieXRlKSAweDRCLCAoYnl0ZSkgMHgxRiwgKGJ5dGUpIDB4RTYsIChieXRlKSAweDQ5LCAoYnl0ZSkgMHgyOCwKKyAgICAgICAgICAgIChieXRlKSAweDY2LCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4RUMsIChieXRlKSAweEU2LCAoYnl0ZSkgMHg1MywKKyAgICAgICAgICAgIChieXRlKSAweDgxLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwKKyAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGCisgICAgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBwcmltZTsKKworICAgIHN0YXRpYyB7CisvL1RPRE8gc2V0IHByaW1lIGRlcGFuZCBvbiBzb21lIHN5c3RlbSBvciBzZWN1cml0eSBwcm9wZXJ0eQorICAgICAgICBwcmltZSA9IHByaW1lNTEyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgcHJpbWUgYnl0ZXMKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gZ2V0UHJpbWUoKSB7CisgICAgICAgIHJldHVybiBwcmltZTsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvRGF0YVN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvRGF0YVN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZmYzg2MTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9EYXRhU3RyZWFtLmphdmEKQEAgLTAsMCArMSw0MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCisvKioKKyAqIFRoaXMgaW50ZXJmYWNlIHJlcHJlc2VudHMgdGhlIGFiaWxpdHkgb2YgdGhlCisgKiBjbGFzc2VzIHRvIHByb3ZpZGUgdGhlIGNodW5rcyBvZiBkYXRhLgorICovCitwdWJsaWMgaW50ZXJmYWNlIERhdGFTdHJlYW0geworCisgICAgLyoqCisgICAgICogQ2hlY2tzIGlmIHRoZXJlIGlzIGRhdGEgdG8gYmUgcmVhZC4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlcmUgaXMgdGhlIGlucHV0IGRhdGEgaW4gdGhlIHN0cmVhbSwKKyAgICAgKiBmYWxzZSBvdGhlcndpc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNEYXRhKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgdGhlIGRhdGEgb2Ygc3BlY2lmaWVkIGxlbmd0aCBmcm9tIHRoZSBzdHJlYW0uCisgICAgICogSWYgdGhlIGRhdGEgc2l6ZSBpbiB0aGUgc3RyZWFtIGlzIGxlc3MgdGhhbiBzcGVjaWZpZWQgbGVuZ3RoLAorICAgICAqIG1ldGhvZCByZXR1cm5zIGFsbCB0aGUgZGF0YSBjb250YWluZWQgaW4gdGhlIHN0cmVhbS4KKyAgICAgKiBAcmV0dXJuIGJ5dGUgYXJyYXkgY29udGFpbmluZyB0aGUgZGVtYW5kZWQgZGF0YS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldERhdGEoaW50IGxlbmd0aCk7CisKK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvRGVmYXVsdFNTTENvbnRleHRJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9EZWZhdWx0U1NMQ29udGV4dEltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MDU3NTE4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvRGVmYXVsdFNTTENvbnRleHRJbXBsLmphdmEKQEAgLTAsMCArMSwxMzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlNYW5hZ2VtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleU1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyRmFjdG9yeTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlckZhY3Rvcnk7CisKKy8qKgorICogU3VwcG9ydCBjbGFzcyBmb3IgdGhpcyBwYWNrYWdlLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRGVmYXVsdFNTTENvbnRleHRJbXBsIGV4dGVuZHMgT3BlblNTTENvbnRleHRJbXBsIHsKKworICAgIC8qKgorICAgICAqIEFjY2Vzc2VkIGJ5IFNTTENvbnRleHRJbXBsKERlZmF1bHRTU0xDb250ZXh0SW1wbCkgaG9sZGluZyB0aGUKKyAgICAgKiBEZWZhdWx0U1NMQ29udGV4dEltcGwuY2xhc3MgbW9uaXRvcgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIEtleU1hbmFnZXJbXSBLRVlfTUFOQUdFUlM7CisKKyAgICAvKioKKyAgICAgKiBBY2Nlc3NlZCBieSBTU0xDb250ZXh0SW1wbChEZWZhdWx0U1NMQ29udGV4dEltcGwpIGhvbGRpbmcgdGhlCisgICAgICogRGVmYXVsdFNTTENvbnRleHRJbXBsLmNsYXNzIG1vbml0b3IKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBUcnVzdE1hbmFnZXJbXSBUUlVTVF9NQU5BR0VSUzsKKworICAgIC8qKgorICAgICAqIERlZmF1bHRTU0xDb250ZXh0SW1wbCBkZWxlZ2F0ZXMgdGhlIHdvcmsgdG8gdGhlIHN1cGVyIGNsYXNzCisgICAgICogc2luY2UgdGhlcmUgaXMgbm8gd2F5IHRvIHB1dCBhIHN5bmNocm9uaXplZCBhcm91bmQgYm90aCB0aGUKKyAgICAgKiBjYWxsIHRvIHN1cGVyIGFuZCB0aGUgcmVzdCBvZiB0aGlzIGNvbnN0cnVjdG9yIHRvIGd1YXJhbnRlZQorICAgICAqIHRoYXQgd2UgZG9uJ3QgaGF2ZSByYWNlcyBpbiBjcmVhdGluZyB0aGUgc3RhdGUgc2hhcmVkIGJldHdlZW4KKyAgICAgKiBhbGwgZGVmYXVsdCBTU0xDb250ZXh0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGVmYXVsdFNTTENvbnRleHRJbXBsKCkgdGhyb3dzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihudWxsKTsKKyAgICB9CisKKyAgICAvLyBUT0RPIGphdmF4Lm5ldC5zc2wua2V5U3RvcmVQcm92aWRlciBzeXN0ZW0gcHJvcGVydHkKKyAgICBLZXlNYW5hZ2VyW10gZ2V0S2V5TWFuYWdlcnMgKCkgdGhyb3dzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoS0VZX01BTkFHRVJTICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBLRVlfTUFOQUdFUlM7CisgICAgICAgIH0KKyAgICAgICAgLy8gZmluZCBLZXlTdG9yZSwgS2V5TWFuYWdlcnMKKyAgICAgICAgU3RyaW5nIGtleXN0b3JlID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZheC5uZXQuc3NsLmtleVN0b3JlIik7CisgICAgICAgIGlmIChrZXlzdG9yZSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcga2V5c3RvcmVwd2QgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmF4Lm5ldC5zc2wua2V5U3RvcmVQYXNzd29yZCIpOworICAgICAgICBjaGFyW10gcHdkID0gKGtleXN0b3JlcHdkID09IG51bGwpID8gbnVsbCA6IGtleXN0b3JlcHdkLnRvQ2hhckFycmF5KCk7CisKKyAgICAgICAgS2V5U3RvcmUga3MgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGtleXN0b3JlKSk7CisgICAgICAgICAgICBrcy5sb2FkKGlzLCBwd2QpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGttZkFsZyA9IFNlY3VyaXR5LmdldFByb3BlcnR5KCJzc2wuS2V5TWFuYWdlckZhY3RvcnkuYWxnb3JpdGhtIik7CisgICAgICAgIGlmIChrbWZBbGcgPT0gbnVsbCkgeworICAgICAgICAgICAga21mQWxnID0gIlN1blg1MDkiOworICAgICAgICB9CisKKyAgICAgICAgS2V5TWFuYWdlckZhY3Rvcnkga21mID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2Uoa21mQWxnKTsKKyAgICAgICAga21mLmluaXQoa3MsIHB3ZCk7CisgICAgICAgIEtFWV9NQU5BR0VSUyA9IGttZi5nZXRLZXlNYW5hZ2VycygpOworICAgICAgICByZXR1cm4gS0VZX01BTkFHRVJTOworICAgIH0KKworICAgIC8vIFRPRE8gamF2YXgubmV0LnNzbC50cnVzdFN0b3JlUHJvdmlkZXIgc3lzdGVtIHByb3BlcnR5CisgICAgVHJ1c3RNYW5hZ2VyW10gZ2V0VHJ1c3RNYW5hZ2VycygpIHRocm93cyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKFRSVVNUX01BTkFHRVJTICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBUUlVTVF9NQU5BR0VSUzsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGZpbmQgVHJ1c3RTdG9yZSwgVHJ1c3RNYW5hZ2VycworICAgICAgICBTdHJpbmcga2V5c3RvcmUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmF4Lm5ldC5zc2wudHJ1c3RTdG9yZSIpOworICAgICAgICBpZiAoa2V5c3RvcmUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIGtleXN0b3JlcHdkID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZheC5uZXQuc3NsLnRydXN0U3RvcmVQYXNzd29yZCIpOworICAgICAgICBjaGFyW10gcHdkID0gKGtleXN0b3JlcHdkID09IG51bGwpID8gbnVsbCA6IGtleXN0b3JlcHdkLnRvQ2hhckFycmF5KCk7CisKKyAgICAgICAgLy8gVE9ETyBEZWZhdWx0czoganNzZWNhY2VydHM7IGNhY2VydHMKKyAgICAgICAgS2V5U3RvcmUga3MgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGtleXN0b3JlKSk7CisgICAgICAgICAgICBrcy5sb2FkKGlzLCBwd2QpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFN0cmluZyB0bWZBbGcgPSBTZWN1cml0eS5nZXRQcm9wZXJ0eSgic3NsLlRydXN0TWFuYWdlckZhY3RvcnkuYWxnb3JpdGhtIik7CisgICAgICAgIGlmICh0bWZBbGcgPT0gbnVsbCkgeworICAgICAgICAgICAgdG1mQWxnID0gIlBLSVgiOworICAgICAgICB9CisKKyAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeSB0bWYgPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKHRtZkFsZyk7CisgICAgICAgIHRtZi5pbml0KGtzKTsKKyAgICAgICAgVFJVU1RfTUFOQUdFUlMgPSB0bWYuZ2V0VHJ1c3RNYW5hZ2VycygpOworICAgICAgICByZXR1cm4gVFJVU1RfTUFOQUdFUlM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZW5naW5lSW5pdChLZXlNYW5hZ2VyW10ga21zLCBUcnVzdE1hbmFnZXJbXSB0bXMsCisgICAgICAgICAgICBTZWN1cmVSYW5kb20gc3IpIHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IEtleU1hbmFnZW1lbnRFeGNlcHRpb24oIkRvIG5vdCBpbml0KCkgdGhlIGRlZmF1bHQgU1NMQ29udGV4dCAiKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9EZWxlZ2F0ZWRUYXNrLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9EZWxlZ2F0ZWRUYXNrLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGUxM2JjMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0RlbGVnYXRlZFRhc2suamF2YQpAQCAtMCwwICsxLDQzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKKy8qKgorICogRGVsZWdhdGVkIFJ1bm5hYmxlIHRhc2sgZm9yIFNTTEVuZ2luZQorICovCitwdWJsaWMgY2xhc3MgRGVsZWdhdGVkVGFzayBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKworICAgIHByaXZhdGUgZmluYWwgSGFuZHNoYWtlUHJvdG9jb2wgaGFuZHNoYWtlcjsKKyAgICBwcml2YXRlIGZpbmFsIFJ1bm5hYmxlIGFjdGlvbjsKKworICAgIHB1YmxpYyBEZWxlZ2F0ZWRUYXNrKFJ1bm5hYmxlIGFjdGlvbiwgSGFuZHNoYWtlUHJvdG9jb2wgaGFuZHNoYWtlcikgeworICAgICAgICB0aGlzLmFjdGlvbiA9IGFjdGlvbjsKKyAgICAgICAgdGhpcy5oYW5kc2hha2VyID0gaGFuZHNoYWtlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoaGFuZHNoYWtlcikgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhY3Rpb24ucnVuKCk7CisgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBwYXNzIGV4Y2VwdGlvbiB0byBIYW5kc2hha2VQcm90b2NvbAorICAgICAgICAgICAgICAgIGhhbmRzaGFrZXIuZGVsZWdhdGVkVGFza0VyciA9IGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9EaWdpdGFsU2lnbmF0dXJlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9EaWdpdGFsU2lnbmF0dXJlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWYxMmJiMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0RpZ2l0YWxTaWduYXR1cmUuamF2YQpAQCAtMCwwICsxLDI1MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuRGlnZXN0RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmF4LmNyeXB0by5CYWRQYWRkaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXI7CitpbXBvcnQgamF2YXguY3J5cHRvLklsbGVnYWxCbG9ja1NpemVFeGNlcHRpb247CitpbXBvcnQgamF2YXguY3J5cHRvLk5vU3VjaFBhZGRpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFeGNlcHRpb247CitpbXBvcnQgbGliY29yZS51dGlsLkVtcHR5QXJyYXk7CisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIFNpZ25hdHVyZSB0eXBlLCBhcyBkZXNjcmliZWQgaW4gVExTIHYgMS4wIFByb3RvY29sCisgKiBzcGVjaWZpY2F0aW9uLCA3LjQuMy4gSXQgYWxsb3cgdG8gaW5pdCwgdXBkYXRlIGFuZCBzaWduIGhhc2guIEhhc2ggYWxnb3JpdGhtCisgKiBkZXBlbmRzIG9uIFNpZ25hdHVyZUFsZ29yaXRobS4KKyAqCisgKiBzZWxlY3QgKFNpZ25hdHVyZUFsZ29yaXRobSkKKyAqICAgICAgIHsgICBjYXNlIGFub255bW91czogc3RydWN0IHsgfTsKKyAqICAgICAgICAgICBjYXNlIHJzYToKKyAqICAgICAgICAgICAgICAgZGlnaXRhbGx5LXNpZ25lZCBzdHJ1Y3QgeworICogICAgICAgICAgICAgICAgICAgb3BhcXVlIG1kNV9oYXNoWzE2XTsKKyAqICAgICAgICAgICAgICAgICAgIG9wYXF1ZSBzaGFfaGFzaFsyMF07CisgKiAgICAgICAgICAgICAgIH07CisgKiAgICAgICAgICAgY2FzZSBkc2E6CisgKiAgICAgICAgICAgICAgIGRpZ2l0YWxseS1zaWduZWQgc3RydWN0IHsKKyAqICAgICAgICAgICAgICAgICAgIG9wYXF1ZSBzaGFfaGFzaFsyMF07CisgKiAgICAgICAgICAgICAgIH07CisgKiAgICAgICB9IFNpZ25hdHVyZTsKKyAqCisgKiBEaWdpdGFsIHNpZ25pbmcgZGVzY3JpcHRpb24gc2VlIGluIFRMUyBzcGVjLiwgNC43LgorICogKGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyNDYudHh0KQorICoKKyAqLworcHVibGljIGNsYXNzIERpZ2l0YWxTaWduYXR1cmUgeworCisgICAgcHJpdmF0ZSBmaW5hbCBNZXNzYWdlRGlnZXN0IG1kNTsKKyAgICBwcml2YXRlIGZpbmFsIE1lc3NhZ2VEaWdlc3Qgc2hhOworICAgIHByaXZhdGUgZmluYWwgU2lnbmF0dXJlIHNpZ25hdHVyZTsKKyAgICBwcml2YXRlIGZpbmFsIENpcGhlciBjaXBoZXI7CisKKyAgICBwcml2YXRlIGJ5dGVbXSBtZDVfaGFzaDsKKyAgICBwcml2YXRlIGJ5dGVbXSBzaGFfaGFzaDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBTaWduYXR1cmUgdHlwZQorICAgICAqIEBwYXJhbSBrZXlFeGNoYW5nZQorICAgICAqLworICAgIHB1YmxpYyBEaWdpdGFsU2lnbmF0dXJlKFN0cmluZyBhdXRoVHlwZSkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2hhID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZSgiU0hBLTEiKTsKKworICAgICAgICAgICAgaWYgKCJSU0EiLmVxdWFscyhhdXRoVHlwZSkpIHsKKyAgICAgICAgICAgICAgICBtZDUgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJNRDUiKTsKKyAgICAgICAgICAgICAgICBjaXBoZXIgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIlJTQS9FQ0IvUEtDUzFQYWRkaW5nIik7CisgICAgICAgICAgICAgICAgc2lnbmF0dXJlID0gbnVsbDsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIkRTQSIuZXF1YWxzKGF1dGhUeXBlKSkgeworICAgICAgICAgICAgICAgIC8vIFNpZ25hdHVyZUFsZ29yaXRobSBpcyBkc2EKKyAgICAgICAgICAgICAgICBzaWduYXR1cmUgPSBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIk5PTkV3aXRoRFNBIik7CisgICAgICAgICAgICAgICAgY2lwaGVyID0gbnVsbDsKKyAgICAgICAgICAgICAgICBtZDUgPSBudWxsOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBjaXBoZXIgPSBudWxsOworICAgICAgICAgICAgICAgIHNpZ25hdHVyZSA9IG51bGw7CisgICAgICAgICAgICAgICAgbWQ1ID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbgorICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hQYWRkaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbgorICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhdGUgU2lnbmF0dXJlIHR5cGUgYnkgcHJpdmF0ZSBrZXkKKyAgICAgKiBAcGFyYW0ga2V5CisgICAgICovCisgICAgcHVibGljIHZvaWQgaW5pdChQcml2YXRlS2V5IGtleSkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKHNpZ25hdHVyZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2lnbmF0dXJlLmluaXRTaWduKGtleSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGNpcGhlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgY2lwaGVyLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwga2V5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKXsKKyAgICAgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbihBbGVydFByb3RvY29sLkJBRF9DRVJUSUZJQ0FURSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IFNTTEV4Y2VwdGlvbigiaW5pdCAtIGludmFsaWQgcHJpdmF0ZSBrZXkiLCBlKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWF0ZSBTaWduYXR1cmUgdHlwZSBieSBjZXJ0aWZpY2F0ZQorICAgICAqIEBwYXJhbSBjZXJ0CisgICAgICovCisgICAgcHVibGljIHZvaWQgaW5pdChDZXJ0aWZpY2F0ZSBjZXJ0KSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoc2lnbmF0dXJlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzaWduYXR1cmUuaW5pdFZlcmlmeShjZXJ0KTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY2lwaGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjaXBoZXIuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLCBjZXJ0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKXsKKyAgICAgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbihBbGVydFByb3RvY29sLkJBRF9DRVJUSUZJQ0FURSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IFNTTEV4Y2VwdGlvbigiaW5pdCAtIGludmFsaWQgY2VydGlmaWNhdGUiLCBlKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGUgU2lnbmF0dXJlIGhhc2gKKyAgICAgKiBAcGFyYW0gZGF0YQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZShieXRlW10gZGF0YSkgeworICAgICAgICBpZiAoc2hhICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNoYS51cGRhdGUoZGF0YSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG1kNSAhPSBudWxsKSB7CisgICAgICAgICAgICBtZDUudXBkYXRlKGRhdGEpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBNRDUgaGFzaAorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TUQ1KGJ5dGVbXSBkYXRhKSB7CisgICAgICAgIG1kNV9oYXNoID0gZGF0YTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIFNIQSBoYXNoCisgICAgICogQHBhcmFtIGRhdGEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTSEEoYnl0ZVtdIGRhdGEpIHsKKyAgICAgICAgc2hhX2hhc2ggPSBkYXRhOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNpZ24gaGFzaAorICAgICAqIEByZXR1cm4gU2lnbmF0dXJlIGJ5dGVzCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBzaWduKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKG1kNSAhPSBudWxsICYmIG1kNV9oYXNoID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBtZDVfaGFzaCA9IG5ldyBieXRlWzE2XTsKKyAgICAgICAgICAgICAgICBtZDUuZGlnZXN0KG1kNV9oYXNoLCAwLCBtZDVfaGFzaC5sZW5ndGgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG1kNV9oYXNoICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZiAoc2lnbmF0dXJlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgc2lnbmF0dXJlLnVwZGF0ZShtZDVfaGFzaCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaXBoZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBjaXBoZXIudXBkYXRlKG1kNV9oYXNoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc2hhICE9IG51bGwgJiYgc2hhX2hhc2ggPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNoYV9oYXNoID0gbmV3IGJ5dGVbMjBdOworICAgICAgICAgICAgICAgIHNoYS5kaWdlc3Qoc2hhX2hhc2gsIDAsIHNoYV9oYXNoLmxlbmd0aCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc2hhX2hhc2ggIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmIChzaWduYXR1cmUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBzaWduYXR1cmUudXBkYXRlKHNoYV9oYXNoKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNpcGhlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGNpcGhlci51cGRhdGUoc2hhX2hhc2gpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzaWduYXR1cmUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBzaWduYXR1cmUuc2lnbigpOworICAgICAgICAgICAgfSBlbHNlIGlmIChjaXBoZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBjaXBoZXIuZG9GaW5hbCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIEVtcHR5QXJyYXkuQllURTsKKyAgICAgICAgfSBjYXRjaCAoRGlnZXN0RXhjZXB0aW9uIGUpeworICAgICAgICAgICAgcmV0dXJuIEVtcHR5QXJyYXkuQllURTsKKyAgICAgICAgfSBjYXRjaCAoU2lnbmF0dXJlRXhjZXB0aW9uIGUpeworICAgICAgICAgICAgcmV0dXJuIEVtcHR5QXJyYXkuQllURTsKKyAgICAgICAgfSBjYXRjaCAoQmFkUGFkZGluZ0V4Y2VwdGlvbiBlKXsKKyAgICAgICAgICAgIHJldHVybiBFbXB0eUFycmF5LkJZVEU7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24gZSl7CisgICAgICAgICAgICByZXR1cm4gRW1wdHlBcnJheS5CWVRFOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVmVyaWZpZXMgdGhlIHNpZ25hdHVyZSBkYXRhLgorICAgICAqIEBwYXJhbSBkYXRhIC0gdGhlIHNpZ25hdHVyZSBieXRlcworICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB2ZXJpZmllZAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHZlcmlmeVNpZ25hdHVyZShieXRlW10gZGF0YSkgeworICAgICAgICBpZiAoc2lnbmF0dXJlICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2lnbmF0dXJlLnVwZGF0ZShzaGFfaGFzaCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHNpZ25hdHVyZS52ZXJpZnkoZGF0YSk7CisgICAgICAgICAgICB9IGNhdGNoIChTaWduYXR1cmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChjaXBoZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGRlY3J5cHQ7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGRlY3J5cHQgPSBjaXBoZXIuZG9GaW5hbChkYXRhKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEJhZFBhZGRpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZmluYWwgYnl0ZVtdIG1kNV9zaGE7CisgICAgICAgICAgICBpZiAobWQ1X2hhc2ggIT0gbnVsbCAmJiBzaGFfaGFzaCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgbWQ1X3NoYSA9IG5ldyBieXRlW21kNV9oYXNoLmxlbmd0aCArIHNoYV9oYXNoLmxlbmd0aF07CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShtZDVfaGFzaCwgMCwgbWQ1X3NoYSwgMCwgbWQ1X2hhc2gubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHNoYV9oYXNoLCAwLCBtZDVfc2hhLCBtZDVfaGFzaC5sZW5ndGgsIHNoYV9oYXNoLmxlbmd0aCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKG1kNV9oYXNoICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBtZDVfc2hhID0gbWQ1X2hhc2g7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG1kNV9zaGEgPSBzaGFfaGFzaDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIEFycmF5cy5lcXVhbHMoZGVjcnlwdCwgbWQ1X3NoYSk7CisgICAgICAgIH0gZWxzZSBpZiAoZGF0YSA9PSBudWxsIHx8IGRhdGEubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9FbmRPZkJ1ZmZlckV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvRW5kT2ZCdWZmZXJFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZmUyZDdmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvRW5kT2ZCdWZmZXJFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDMzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFRoaXMgZXhjZXB0aW9uIGluZGljYXRlcyB0aGF0IGRhdGEgY291bGQgbm90IGJlIHJlYWQgZnJvbSB0aGUgc3RyZWFtIGJlY2F1c2UgdGhlIHVuZGVybHlpbmcgaW5wdXQKKyAqIHN0cmVhbSByZWFjaGVkIGl0cyBlbmQuCisgKi8KK3B1YmxpYyBjbGFzcyBFbmRPZkJ1ZmZlckV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDE4Mzg2MzY2MzEyNTUzNjk1MTlMOworCisgICAgcHVibGljIEVuZE9mQnVmZmVyRXhjZXB0aW9uKCkgeworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvRW5kT2ZTb3VyY2VFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0VuZE9mU291cmNlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzg3NDcwOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0VuZE9mU291cmNlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBUaGlzIGV4Y2VwdGlvbiBpbmRpY2F0ZXMgdGhhdCBkYXRhIGNvdWxkIG5vdCBiZSByZWFkIGZyb20gdGhlIGJ1ZmZlcmVkIHN0cmVhbSBiZWNhdXNlIHVuZGVybHlpbmcKKyAqIGRhdGEgYnVmZmVyIHdhcyBleGhhdXN0ZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBFbmRPZlNvdXJjZUV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00NjczNjExNDM1OTc0MDU0NDEzTDsKKworICAgIHB1YmxpYyBFbmRPZlNvdXJjZUV4Y2VwdGlvbigpIHsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0ZpbGVDbGllbnRTZXNzaW9uQ2FjaGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0ZpbGVDbGllbnRTZXNzaW9uQ2FjaGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NjE5ZDFkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvRmlsZUNsaWVudFNlc3Npb25DYWNoZS5qYXZhCkBAIC0wLDAgKzEsMzY1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZVNldDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb247CitpbXBvcnQgbGliY29yZS5pby5Jb1V0aWxzOworCisvKioKKyAqIEZpbGUtYmFzZWQgY2FjaGUgaW1wbGVtZW50YXRpb24uIE9ubHkgb25lIHByb2Nlc3Mgc2hvdWxkIGFjY2VzcyB0aGUKKyAqIHVuZGVybHlpbmcgZGlyZWN0b3J5IGF0IGEgdGltZS4KKyAqLworcHVibGljIGNsYXNzIEZpbGVDbGllbnRTZXNzaW9uQ2FjaGUgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1NJWkUgPSAxMjsgLy8gfjcyaworCisgICAgcHJpdmF0ZSBGaWxlQ2xpZW50U2Vzc2lvbkNhY2hlKCkge30KKworICAgIC8qKgorICAgICAqIFRoaXMgY2FjaGUgY3JlYXRlcyBvbmUgZmlsZSBwZXIgU1NMIHNlc3Npb24gdXNpbmcgImhvc3QucG9ydCIgZm9yCisgICAgICogdGhlIGZpbGUgbmFtZS4gRmlsZXMgYXJlIGNyZWF0ZWQgb3IgcmVwbGFjZWQgd2hlbiBzZXNzaW9uIGRhdGEgaXMgcHV0CisgICAgICogaW4gdGhlIGNhY2hlIChzZWUge0BsaW5rICNwdXRTZXNzaW9uRGF0YX0pLiBGaWxlcyBhcmUgcmVhZCBvbgorICAgICAqIGNhY2hlIGhpdHMsIGJ1dCBub3Qgb24gY2FjaGUgbWlzc2VzLgorICAgICAqCisgICAgICogPHA+V2hlbiB0aGUgbnVtYmVyIG9mIHNlc3Npb24gZmlsZXMgZXhjZWVkcyBNQVhfU0laRSwgd2UgZGVsZXRlIHRoZQorICAgICAqIGxlYXN0LXJlY2VudGx5LXVzZWQgZmlsZS4gV2UgZG9uJ3QgY3VycmVudCBwZXJzaXN0IHRoZSBsYXN0IGFjY2VzcyB0aW1lLAorICAgICAqIHNvIHRoZSBvcmRlcmluZyBhY3R1YWxseSBlbmRzIHVwIGJlaW5nIGxlYXN0LXJlY2VudGx5LW1vZGlmaWVkIGluIHNvbWUKKyAgICAgKiBjYXNlcyBhbmQgZXZlbiBqdXN0ICJub3QgYWNjZXNzZWQgaW4gdGhpcyBwcm9jZXNzIiBpZiB0aGUgZmlsZXN5c3RlbQorICAgICAqIGRvZXNuJ3QgdHJhY2sgbGFzdCBtb2RpZmllZCB0aW1lcy4KKyAgICAgKi8KKyAgICBzdGF0aWMgY2xhc3MgSW1wbCBpbXBsZW1lbnRzIFNTTENsaWVudFNlc3Npb25DYWNoZSB7CisKKyAgICAgICAgLyoqIERpcmVjdG9yeSB0byBzdG9yZSBzZXNzaW9uIGZpbGVzIGluLiAqLworICAgICAgICBmaW5hbCBGaWxlIGRpcmVjdG9yeTsKKworICAgICAgICAvKioKKyAgICAgICAgICogTWFwIG9mIG5hbWUgLT4gRmlsZS4gS2VlcHMgdHJhY2sgb2YgdGhlIG9yZGVyIGZpbGVzIHdlcmUgYWNjZXNzZWQgaW4uCisgICAgICAgICAqLworICAgICAgICBNYXA8U3RyaW5nLCBGaWxlPiBhY2Nlc3NPcmRlciA9IG5ld0FjY2Vzc09yZGVyKCk7CisKKyAgICAgICAgLyoqIFRoZSBudW1iZXIgb2YgZmlsZXMgb24gZGlzay4gKi8KKyAgICAgICAgaW50IHNpemU7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBpbml0aWFsIHNldCBvZiBmaWxlcy4gV2UgdXNlIHRoaXMgdG8gZGVmZXIgYWRkaW5nIGluZm9ybWF0aW9uCisgICAgICAgICAqIGFib3V0IGFsbCBmaWxlcyB0byBhY2Nlc3NPcmRlciB1bnRpbCBuZWNlc3NhcnkuCisgICAgICAgICAqLworICAgICAgICBTdHJpbmdbXSBpbml0aWFsRmlsZXM7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgY2FjaGUgYmFja2VkIGJ5IHRoZSBnaXZlbiBkaXJlY3RvcnkuCisgICAgICAgICAqLworICAgICAgICBJbXBsKEZpbGUgZGlyZWN0b3J5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgYm9vbGVhbiBleGlzdHMgPSBkaXJlY3RvcnkuZXhpc3RzKCk7CisgICAgICAgICAgICBpZiAoZXhpc3RzICYmICFkaXJlY3RvcnkuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihkaXJlY3RvcnkgKyAiIGV4aXN0cyBidXQgaXMgbm90IGEgZGlyZWN0b3J5LiIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZXhpc3RzKSB7CisgICAgICAgICAgICAgICAgLy8gUmVhZCBhbmQgc29ydCBpbml0aWFsIGxpc3Qgb2YgZmlsZXMuIFdlIGRlZmVyIGFkZGluZworICAgICAgICAgICAgICAgIC8vIGluZm9ybWF0aW9uIGFib3V0IHRoZXNlIGZpbGVzIHRvIGFjY2Vzc09yZGVyIHVudGlsIG5lY2Vzc2FyeQorICAgICAgICAgICAgICAgIC8vIChzZWUgaW5kZXhGaWxlcygpKS4gU29ydGluZyB0aGUgbGlzdCBlbmFibGVzIHVzIHRvIGRldGVjdAorICAgICAgICAgICAgICAgIC8vIGNhY2hlIG1pc3NlcyBpbiBnZXRTZXNzaW9uRGF0YSgpLgorICAgICAgICAgICAgICAgIC8vIE5vdGU6IFNvcnRpbmcgYW4gYXJyYXkgaGVyZSB3YXMgZmFzdGVyIHRoYW4gY3JlYXRpbmcgYQorICAgICAgICAgICAgICAgIC8vIEhhc2hTZXQgb24gRGFsdmlrLgorICAgICAgICAgICAgICAgIGluaXRpYWxGaWxlcyA9IGRpcmVjdG9yeS5saXN0KCk7CisgICAgICAgICAgICAgICAgaWYgKGluaXRpYWxGaWxlcyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIEZpbGUubGlzdCgpIHdpbGwgcmV0dXJuIG51bGwgaW4gZXJyb3IgY2FzZXMgd2l0aG91dCB0aHJvd2luZyBJT0V4Y2VwdGlvbgorICAgICAgICAgICAgICAgICAgICAvLyBodHRwOi8vYi8zMzYzNTYxCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihkaXJlY3RvcnkgKyAiIGV4aXN0cyBidXQgY2Fubm90IGxpc3QgY29udGVudHMuIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIEFycmF5cy5zb3J0KGluaXRpYWxGaWxlcyk7CisgICAgICAgICAgICAgICAgc2l6ZSA9IGluaXRpYWxGaWxlcy5sZW5ndGg7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBkaXJlY3RvcnkuCisgICAgICAgICAgICAgICAgaWYgKCFkaXJlY3RvcnkubWtkaXJzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDcmVhdGlvbiBvZiAiICsgZGlyZWN0b3J5ICsgIiBkaXJlY3RvcnkgZmFpbGVkLiIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzaXplID0gMDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdGhpcy5kaXJlY3RvcnkgPSBkaXJlY3Rvcnk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBhY2Nlc3Mtb3JkZXJlZCBsaW5rZWQgaGFzaCBtYXAuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIHN0YXRpYyBNYXA8U3RyaW5nLCBGaWxlPiBuZXdBY2Nlc3NPcmRlcigpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgTGlua2VkSGFzaE1hcDxTdHJpbmcsIEZpbGU+KAorICAgICAgICAgICAgICAgICAgICBNQVhfU0laRSwgMC43NWYsIHRydWUgLyogYWNjZXNzIG9yZGVyICovKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBHZXRzIHRoZSBmaWxlIG5hbWUgZm9yIHRoZSBnaXZlbiBob3N0IGFuZCBwb3J0LgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGZpbGVOYW1lKFN0cmluZyBob3N0LCBpbnQgcG9ydCkgeworICAgICAgICAgICAgaWYgKGhvc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiaG9zdCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGhvc3QgKyAiLiIgKyBwb3J0OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCBieXRlW10gZ2V0U2Vzc2lvbkRhdGEoU3RyaW5nIGhvc3QsIGludCBwb3J0KSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogTm90ZTogVGhpcyBtZXRob2QgaXMgb25seSBjYWxsZWQgd2hlbiB0aGUgaW4tbWVtb3J5IGNhY2hlCisgICAgICAgICAgICAgKiBpbiBTU0xTZXNzaW9uQ29udGV4dCBtaXNzZXMsIHNvIGl0IHdvdWxkIGJlIHVubmVjZXNzYXJpbHkKKyAgICAgICAgICAgICAqIHJlZHVuZGFudCBmb3IgdGhpcyBjYWNoZSB0byBzdG9yZSBkYXRhIGluIG1lbW9yeS4KKyAgICAgICAgICAgICAqLworCisgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGZpbGVOYW1lKGhvc3QsIHBvcnQpOworICAgICAgICAgICAgRmlsZSBmaWxlID0gYWNjZXNzT3JkZXIuZ2V0KG5hbWUpOworCisgICAgICAgICAgICBpZiAoZmlsZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgLy8gRmlsZSB3YXNuJ3QgaW4gYWNjZXNzIG9yZGVyLiBDaGVjayBpbml0aWFsRmlsZXMuLi4KKyAgICAgICAgICAgICAgICBpZiAoaW5pdGlhbEZpbGVzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gQWxsIGZpbGVzIGFyZSBpbiBhY2Nlc3NPcmRlciwgc28gaXQgZG9lc24ndCBleGlzdC4KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gTG9vayBpbiBpbml0aWFsRmlsZXMuCisgICAgICAgICAgICAgICAgaWYgKEFycmF5cy5iaW5hcnlTZWFyY2goaW5pdGlhbEZpbGVzLCBuYW1lKSA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gTm90IGZvdW5kLgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBUaGUgZmlsZSBpcyBvbiBkaXNrIGJ1dCBub3QgaW4gYWNjZXNzT3JkZXIgeWV0LgorICAgICAgICAgICAgICAgIGZpbGUgPSBuZXcgRmlsZShkaXJlY3RvcnksIG5hbWUpOworICAgICAgICAgICAgICAgIGFjY2Vzc09yZGVyLnB1dChuYW1lLCBmaWxlKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgRmlsZUlucHV0U3RyZWFtIGluOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSk7CisgICAgICAgICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGxvZ1JlYWRFcnJvcihob3N0LCBmaWxlLCBlKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaW50IHNpemUgPSAoaW50KSBmaWxlLmxlbmd0aCgpOworICAgICAgICAgICAgICAgIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbc2l6ZV07CisgICAgICAgICAgICAgICAgbmV3IERhdGFJbnB1dFN0cmVhbShpbikucmVhZEZ1bGx5KGRhdGEpOworICAgICAgICAgICAgICAgIHJldHVybiBkYXRhOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGxvZ1JlYWRFcnJvcihob3N0LCBmaWxlLCBlKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkoaW4pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgc3RhdGljIHZvaWQgbG9nUmVhZEVycm9yKFN0cmluZyBob3N0LCBGaWxlIGZpbGUsIFRocm93YWJsZSB0KSB7CisgICAgICAgICAgICBTeXN0ZW0ubG9nVygiRXJyb3IgcmVhZGluZyBzZXNzaW9uIGRhdGEgZm9yICIgKyBob3N0ICsgIiBmcm9tICIgKyBmaWxlICsgIi4iLCB0KTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBwdXRTZXNzaW9uRGF0YShTU0xTZXNzaW9uIHNlc3Npb24sCisgICAgICAgICAgICAgICAgYnl0ZVtdIHNlc3Npb25EYXRhKSB7CisgICAgICAgICAgICBTdHJpbmcgaG9zdCA9IHNlc3Npb24uZ2V0UGVlckhvc3QoKTsKKyAgICAgICAgICAgIGlmIChzZXNzaW9uRGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJzZXNzaW9uRGF0YSIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGZpbGVOYW1lKGhvc3QsIHNlc3Npb24uZ2V0UGVlclBvcnQoKSk7CisgICAgICAgICAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShkaXJlY3RvcnksIG5hbWUpOworCisgICAgICAgICAgICAvLyBVc2VkIHRvIGtlZXAgdHJhY2sgb2Ygd2hldGhlciBvciBub3Qgd2UncmUgZXhwYW5kaW5nIHRoZSBjYWNoZS4KKyAgICAgICAgICAgIGJvb2xlYW4gZXhpc3RlZEJlZm9yZSA9IGZpbGUuZXhpc3RzKCk7CisKKyAgICAgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gb3V0OworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gV2UgY2FuJ3Qgd3JpdGUgdG8gdGhlIGZpbGUuCisgICAgICAgICAgICAgICAgbG9nV3JpdGVFcnJvcihob3N0LCBmaWxlLCBlKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIElmIHdlIGV4cGFuZGVkIHRoZSBjYWNoZSAoYnkgY3JlYXRpbmcgYSBuZXcgZmlsZSkuLi4KKyAgICAgICAgICAgIGlmICghZXhpc3RlZEJlZm9yZSkgeworICAgICAgICAgICAgICAgIHNpemUrKzsKKworICAgICAgICAgICAgICAgIC8vIERlbGV0ZSBhbiBvbGQgZmlsZSBpZiBuZWNlc3NhcnkuCisgICAgICAgICAgICAgICAgbWFrZVJvb20oKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYm9vbGVhbiB3cml0ZVN1Y2Nlc3NmdWwgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlKHNlc3Npb25EYXRhKTsKKyAgICAgICAgICAgICAgICB3cml0ZVN1Y2Nlc3NmdWwgPSB0cnVlOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGxvZ1dyaXRlRXJyb3IoaG9zdCwgZmlsZSwgZSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGJvb2xlYW4gY2xvc2VTdWNjZXNzZnVsID0gZmFsc2U7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIGNsb3NlU3VjY2Vzc2Z1bCA9IHRydWU7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBsb2dXcml0ZUVycm9yKGhvc3QsIGZpbGUsIGUpOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIGlmICghd3JpdGVTdWNjZXNzZnVsIHx8ICFjbG9zZVN1Y2Nlc3NmdWwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN0b3JhZ2UgZmFpbGVkLiBDbGVhbiB1cC4KKyAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZShmaWxlKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN1Y2Nlc3MhCisgICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3NPcmRlci5wdXQobmFtZSwgZmlsZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogRGVsZXRlcyBvbGQgZmlsZXMgaWYgbmVjZXNzYXJ5LgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSB2b2lkIG1ha2VSb29tKCkgeworICAgICAgICAgICAgaWYgKHNpemUgPD0gTUFYX1NJWkUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGluZGV4RmlsZXMoKTsKKworICAgICAgICAgICAgLy8gRGVsZXRlIExSVWVkIGZpbGVzLgorICAgICAgICAgICAgaW50IHJlbW92YWxzID0gc2l6ZSAtIE1BWF9TSVpFOworICAgICAgICAgICAgSXRlcmF0b3I8RmlsZT4gaSA9IGFjY2Vzc09yZGVyLnZhbHVlcygpLml0ZXJhdG9yKCk7CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgZGVsZXRlKGkubmV4dCgpKTsKKyAgICAgICAgICAgICAgICBpLnJlbW92ZSgpOworICAgICAgICAgICAgfSB3aGlsZSAoLS1yZW1vdmFscyA+IDApOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIExhemlseSB1cGRhdGVzIGFjY2Vzc09yZGVyIHRvIGtub3cgYWJvdXQgYWxsIGZpbGVzIGFzIG9wcG9zZWQgdG8KKyAgICAgICAgICoganVzdCB0aGUgZmlsZXMgYWNjZXNzZWQgc2luY2UgdGhpcyBwcm9jZXNzIHN0YXJ0ZWQuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIHZvaWQgaW5kZXhGaWxlcygpIHsKKyAgICAgICAgICAgIFN0cmluZ1tdIGluaXRpYWxGaWxlcyA9IHRoaXMuaW5pdGlhbEZpbGVzOworICAgICAgICAgICAgaWYgKGluaXRpYWxGaWxlcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhpcy5pbml0aWFsRmlsZXMgPSBudWxsOworCisgICAgICAgICAgICAgICAgLy8gRmlsZXMgb24gZGlzayBvbmx5LCBzb3J0ZWQgYnkgbGFzdCBtb2RpZmllZCB0aW1lLgorICAgICAgICAgICAgICAgIC8vIFRPRE86IFVzZSBsYXN0IGFjY2VzcyB0aW1lLgorICAgICAgICAgICAgICAgIFNldDxDYWNoZUZpbGU+IGRpc2tPbmx5ID0gbmV3IFRyZWVTZXQ8Q2FjaGVGaWxlPigpOworICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIG5hbWUgOiBpbml0aWFsRmlsZXMpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGZpbGUgaGFzbid0IGJlZW4gYWNjZXNzZWQgaW4gdGhpcyBwcm9jZXNzLi4uCisgICAgICAgICAgICAgICAgICAgIGlmICghYWNjZXNzT3JkZXIuY29udGFpbnNLZXkobmFtZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRpc2tPbmx5LmFkZChuZXcgQ2FjaGVGaWxlKGRpcmVjdG9yeSwgbmFtZSkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKCFkaXNrT25seS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gQWRkIGZpbGVzIG5vdCBhY2Nlc3NlZCBpbiB0aGlzIHByb2Nlc3MgdG8gdGhlIGJlZ2lubmluZworICAgICAgICAgICAgICAgICAgICAvLyBvZiBhY2Nlc3NPcmRlci4KKyAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZywgRmlsZT4gbmV3T3JkZXIgPSBuZXdBY2Nlc3NPcmRlcigpOworICAgICAgICAgICAgICAgICAgICBmb3IgKENhY2hlRmlsZSBjYWNoZUZpbGUgOiBkaXNrT25seSkgeworICAgICAgICAgICAgICAgICAgICAgICAgbmV3T3JkZXIucHV0KGNhY2hlRmlsZS5uYW1lLCBjYWNoZUZpbGUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIG5ld09yZGVyLnB1dEFsbChhY2Nlc3NPcmRlcik7CisKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NPcmRlciA9IG5ld09yZGVyOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJUaHJvd2FibGVJbnN0YW5jZU5ldmVyVGhyb3duIikKKyAgICAgICAgcHJpdmF0ZSB2b2lkIGRlbGV0ZShGaWxlIGZpbGUpIHsKKyAgICAgICAgICAgIGlmICghZmlsZS5kZWxldGUoKSkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5sb2dXKCJGYWlsZWQgdG8gZGVsZXRlICIgKyBmaWxlICsgIi4iLCBuZXcgSU9FeGNlcHRpb24oKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzaXplLS07CisgICAgICAgIH0KKworICAgICAgICBzdGF0aWMgdm9pZCBsb2dXcml0ZUVycm9yKFN0cmluZyBob3N0LCBGaWxlIGZpbGUsIFRocm93YWJsZSB0KSB7CisgICAgICAgICAgICBTeXN0ZW0ubG9nVygiRXJyb3Igd3JpdGluZyBzZXNzaW9uIGRhdGEgZm9yICIgKyBob3N0ICsgIiB0byAiICsgZmlsZSArICIuIiwgdCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXBzIGRpcmVjdG9yaWVzIHRvIHRoZSBjYWNoZSBpbnN0YW5jZXMgdGhhdCBhcmUgYmFja2VkIGJ5IHRob3NlCisgICAgICogZGlyZWN0b3JpZXMuIFdlIHN5bmNocm9uaXplIGFjY2VzcyB1c2luZyB0aGUgY2FjaGUgaW5zdGFuY2UsIHNvIGl0J3MKKyAgICAgKiBpbXBvcnRhbnQgdGhhdCBldmVyeW9uZSBzaGFyZXMgdGhlIHNhbWUgaW5zdGFuY2UuCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIE1hcDxGaWxlLCBGaWxlQ2xpZW50U2Vzc2lvbkNhY2hlLkltcGw+IGNhY2hlcworICAgICAgICAgICAgPSBuZXcgSGFzaE1hcDxGaWxlLCBGaWxlQ2xpZW50U2Vzc2lvbkNhY2hlLkltcGw+KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY2FjaGUgYmFja2VkIGJ5IHRoZSBnaXZlbiBkaXJlY3RvcnkuIENyZWF0ZXMgdGhlIGRpcmVjdG9yeQorICAgICAqIChpbmNsdWRpbmcgcGFyZW50IGRpcmVjdG9yaWVzKSBpZiBuZWNlc3NhcnkuIFRoaXMgY2FjaGUgc2hvdWxkIGhhdmUKKyAgICAgKiBleGNsdXNpdmUgYWNjZXNzIHRvIHRoZSBnaXZlbiBkaXJlY3RvcnkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGlyZWN0b3J5IHRvIHN0b3JlIGZpbGVzIGluCisgICAgICogQHJldHVybiBhIGNhY2hlIGJhY2tlZCBieSB0aGUgZ2l2ZW4gZGlyZWN0b3J5CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgZmlsZSBleGlzdHMgYW5kIGlzIG5vdCBhIGRpcmVjdG9yeSBvciBpZgorICAgICAqICBjcmVhdGluZyB0aGUgZGlyZWN0b3JpZXMgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBTU0xDbGllbnRTZXNzaW9uQ2FjaGUgdXNpbmdEaXJlY3RvcnkoCisgICAgICAgICAgICBGaWxlIGRpcmVjdG9yeSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZUNsaWVudFNlc3Npb25DYWNoZS5JbXBsIGNhY2hlID0gY2FjaGVzLmdldChkaXJlY3RvcnkpOworICAgICAgICBpZiAoY2FjaGUgPT0gbnVsbCkgeworICAgICAgICAgICAgY2FjaGUgPSBuZXcgRmlsZUNsaWVudFNlc3Npb25DYWNoZS5JbXBsKGRpcmVjdG9yeSk7CisgICAgICAgICAgICBjYWNoZXMucHV0KGRpcmVjdG9yeSwgY2FjaGUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjYWNoZTsKKyAgICB9CisKKyAgICAvKiogRm9yIHRlc3RpbmcuICovCisgICAgc3RhdGljIHN5bmNocm9uaXplZCB2b2lkIHJlc2V0KCkgeworICAgICAgICBjYWNoZXMuY2xlYXIoKTsKKyAgICB9CisKKyAgICAvKiogQSBmaWxlIGNvbnRhaW5pbmcgYSBwaWVjZSBvZiBjYWNoZWQgZGF0YS4gKi8KKyAgICBzdGF0aWMgY2xhc3MgQ2FjaGVGaWxlIGV4dGVuZHMgRmlsZSB7CisKKyAgICAgICAgZmluYWwgU3RyaW5nIG5hbWU7CisKKyAgICAgICAgQ2FjaGVGaWxlKEZpbGUgZGlyLCBTdHJpbmcgbmFtZSkgeworICAgICAgICAgICAgc3VwZXIoZGlyLCBuYW1lKTsKKyAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgIH0KKworICAgICAgICBsb25nIGxhc3RNb2RpZmllZCA9IC0xOworCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgbG9uZyBsYXN0TW9kaWZpZWQoKSB7CisgICAgICAgICAgICBsb25nIGxhc3RNb2RpZmllZCA9IHRoaXMubGFzdE1vZGlmaWVkOworICAgICAgICAgICAgaWYgKGxhc3RNb2RpZmllZCA9PSAtMSkgeworICAgICAgICAgICAgICAgIGxhc3RNb2RpZmllZCA9IHRoaXMubGFzdE1vZGlmaWVkID0gc3VwZXIubGFzdE1vZGlmaWVkKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbGFzdE1vZGlmaWVkOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKEZpbGUgYW5vdGhlcikgeworICAgICAgICAgICAgLy8gU29ydCBieSBsYXN0IG1vZGlmaWVkIHRpbWUuCisgICAgICAgICAgICBsb25nIHJlc3VsdCA9IGxhc3RNb2RpZmllZCgpIC0gYW5vdGhlci5sYXN0TW9kaWZpZWQoKTsKKyAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5jb21wYXJlVG8oYW5vdGhlcik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0IDwgMCA/IC0xIDogMTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0ZpbmlzaGVkLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9GaW5pc2hlZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZjODlkNDgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9GaW5pc2hlZC5qYXZhCkBAIC0wLDAgKzEsODAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICoKKyAqIFJlcHJlc2VudHMgRmluaXNoZWQgbWVzc2FnZQorICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMjQ2LnR4dCI+VExTIDEuMCBzcGVjLiwgNy40LjkuCisgKiBGaW5pc2hlZDwvYT4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBGaW5pc2hlZCBleHRlbmRzIE1lc3NhZ2UgeworCisgICAgLy8gdmVyaWZ5IGRhdGEKKyAgICBwcml2YXRlIGJ5dGVbXSBkYXRhOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBvdXRib3VuZCBtZXNzYWdlCisgICAgICogQHBhcmFtIGJ5dGVzCisgICAgICovCisgICAgcHVibGljIEZpbmlzaGVkKGJ5dGVbXSBieXRlcykgeworICAgICAgICBkYXRhID0gYnl0ZXM7CisgICAgICAgIGxlbmd0aCA9IGRhdGEubGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgaW5ib3VuZCBtZXNzYWdlCisgICAgICogQHBhcmFtIGluCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgRmluaXNoZWQoSGFuZHNoYWtlSU9EYXRhU3RyZWFtIGluLCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGxlbmd0aCA9PSAxMiB8fCBsZW5ndGggPT0gMzYpIHsKKyAgICAgICAgICAgIGRhdGEgPSBpbi5yZWFkKGxlbmd0aCk7CisgICAgICAgICAgICB0aGlzLmxlbmd0aCA9IGRhdGEubGVuZ3RoOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLkRFQ09ERV9FUlJPUiwgIkRFQ09ERSBFUlJPUjogaW5jb3JyZWN0IEZpbmlzaGVkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZW5kKEhhbmRzaGFrZUlPRGF0YVN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LndyaXRlKGRhdGEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgbWVzc2FnZSB0eXBlCisgICAgICogQHJldHVybgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0VHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIEhhbmRzaGFrZS5GSU5JU0hFRDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHZlcmlmeSBkYXRhCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RGF0YSgpIHsKKyAgICAgICAgcmV0dXJuIGRhdGE7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvSGFuZHNoYWtlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9IYW5kc2hha2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNjFhOTZjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvSGFuZHNoYWtlLmphdmEKQEAgLTAsMCArMSw4OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCisvKioKKyAqCisgKiBUaGlzIGNsYXNzIGluY2Fwc3VsYXRlcyB0aGUgY29uc3RhbnRzIGRldGVybWluaW5nIHRoZSB0eXBlcyBvZiBoYW5kc2hha2UKKyAqIG1lc3NhZ2VzIGFzIGRlZmluZWQgaW4gVExTIDEuMCBzcGVjLiwgNy40LiBIYW5kc2hha2UgcHJvdG9jb2wuCisgKiAoaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI0Ni50eHQpCisgKgorICovCitwdWJsaWMgY2xhc3MgSGFuZHNoYWtlIHsKKworICAgIC8qKgorICAgICAqCisgICAgICogaGVsbG9fcmVxdWVzdCBoYW5kc2hha2UgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBIRUxMT19SRVFVRVNUID0gMDsKKworICAgIC8qKgorICAgICAqCisgICAgICogY2xpZW50X2hlbGxvIGhhbmRzaGFrZSB0eXBlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIENMSUVOVF9IRUxMTyA9IDE7CisKKyAgICAvKioKKyAgICAgKgorICAgICAqIHNlcnZlcl9oZWxsbyBoYW5kc2hha2UgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBTRVJWRVJfSEVMTE8gPSAyOworCisgICAgLyoqCisgICAgICoKKyAgICAgKiBjZXJ0aWZpY2F0ZSBoYW5kc2hha2UgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBDRVJUSUZJQ0FURSA9IDExOworCisgICAgLyoqCisgICAgICoKKyAgICAgKiBzZXJ2ZXJfa2V5X2V4Y2hhbmdlICBoYW5kc2hha2UgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBTRVJWRVJfS0VZX0VYQ0hBTkdFID0gMTI7CisKKyAgICAvKioKKyAgICAgKgorICAgICAqIGNlcnRpZmljYXRlX3JlcXVlc3QgaGFuZHNoYWtlIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQ0VSVElGSUNBVEVfUkVRVUVTVCA9IDEzOworCisgICAgLyoqCisgICAgICoKKyAgICAgKiBzZXJ2ZXJfaGVsbG9fZG9uZSBoYW5kc2hha2UgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBTRVJWRVJfSEVMTE9fRE9ORSA9IDE0OworCisgICAgLyoqCisgICAgICoKKyAgICAgKiBjZXJ0aWZpY2F0ZV92ZXJpZnkgaGFuZHNoYWtlIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQ0VSVElGSUNBVEVfVkVSSUZZID0gMTU7CisKKyAgICAvKioKKyAgICAgKgorICAgICAqIGNsaWVudF9rZXlfZXhjaGFuZ2UgaGFuZHNoYWtlIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQ0xJRU5UX0tFWV9FWENIQU5HRSA9IDE2OworCisgICAgLyoqCisgICAgICoKKyAgICAgKiBmaW5pc2hlZCBoYW5kc2hha2UgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBGSU5JU0hFRCA9IDIwOworCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvSGFuZHNoYWtlSU9EYXRhU3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9IYW5kc2hha2VJT0RhdGFTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZTlmNjY3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvSGFuZHNoYWtlSU9EYXRhU3RyZWFtLmphdmEKQEAgLTAsMCArMSw0MzUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5QcmludFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMSGFuZHNoYWtlRXhjZXB0aW9uOworCisvKioKKyAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgSW5wdXQvT3V0cHV0IGRhdGEgZnVuY3Rpb25hbGl0eQorICogZm9yIGhhbmRzaGFrZSBsYXllci4gSXQgcHJvdmlkZXMgcmVhZCBhbmQgd3JpdGUgb3BlcmF0aW9ucworICogYW5kIGFjY3VtdWxhdGVzIGFsbCBzZW50L3JlY2VpdmVkIGhhbmRzaGFrZSdzIGRhdGEuCisgKiBUaGlzIGNsYXNzIGNhbiBiZSBwcmVzZW50ZWQgYXMgYSBjb21iaW5hdGlvbiBvZiAyIGRhdGEgcGlwZXMuCisgKiBUaGUgZmlyc3QgZGF0YSBwaXBlIGlzIGEgcGlwZSBvZiBpbmNvbWUgZGF0YTogYXBwZW5kIG1ldGhvZAorICogcGxhY2VzIHRoZSBkYXRhIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHBpcGUsIGFuZCByZWFkIG1ldGhvZHMKKyAqIGNvbnN1bWUgdGhlIGRhdGEgZnJvbSB0aGUgcGlwZS4gVGhlIHNlY29uZCBwaXBlIGlzIGFuIG91dGNvbWluZworICogZGF0YSBwaXBlOiB3cml0ZSBvcGVyYXRpb25zIHBsYXNlcyB0aGUgZGF0YSBpbnRvIHRoZSBwaXBlLAorICogYW5kIGdldERhdGEgbWV0aG9kcyBjb25zdW1lIHRoZSBkYXRhLgorICogSXQgaXMgaW1wb3J0YW50IHRvIG5vdGUgdGhhdCB3b3JrIHdpdGggcGlwZSBjb3VuZCBub3QgYmUKKyAqIHN0YXJ0ZWQgaWYgdGhlcmUgaXMgdW5jb25zdW1lZCBkYXRhIGluIGFub3RoZXIgcGlwZS4gSXQgaXMKKyAqIHJlYXNvbmVkIGJ5IHRoZSBmb2xsb3dpbmc6IGhhbmRzaGFrZSBwcm90b2NvbCBwZXJmb3JtcyByZWFkCisgKiBhbmQgd3JpdGUgb3BlcmF0aW9ucyBjb25zZWN1ZW50bHkuIEkuZS4gaXQgZmlyc3QgcmVhZHMgYWxsCisgKiBpbmNvbWUgZGF0YSBhbmQgb25seSB0aGFuIHByb2R1Y2VzIHRoZSByZXNwb25jZSBhbmQgcGxhY2VzIGl0CisgKiBpbnRvIHRoZSBzdHJlYW0uCisgKiBUaGUgcmVhZCBvcGVyYXRpb25zIG9mIHRoZSBzdHJlYW0gcHJlc2VudGVkIGJ5IHRoZSBtZXRob2RzCisgKiBvZiBTU0xJbnB1dFN0cmVhbSB3aGljaCBpbiBpdHMgdHVybiBpcyBhbiBleHRlbnNpb24gb2YgSW5wdXRTdHJlYW0uCisgKiBTbyB0aGlzIHN0cmVhbSBjYW4gYmUgdXNlZCBhcyBhbiBJbnB1dFN0cmVhbSBwYXJhbWV0ZXIgZm9yCisgKiBjZXJ0aWZpY2F0ZSBnZW5lcmF0aW9uLgorICogQWxzbyBpbnB1dCBzdHJlYW0gZnVuY3Rpb25hbGl0eSBzdXBwb3J0cyBtYXJrcy4gVGhlIG1hcmtzCisgKiBoZWxwIHRvIHJlc2V0IHRoZSBwb3NpdGlvbiBvZiB0aGUgc3RyZWFtIGluIGNhc2Ugb2YgaW5jb21wbGVhdGUKKyAqIGhhbmRzaGFrZSByZWNvcmRzLiBOb3RlIHRoYXQgaW4gY2FzZSBvZiBleGhhdXN0aW5nCisgKiBvZiBpbmNvbWUgZGF0YSB0aGUgRW5kT2ZCdWZmZXJFeGNlcHRpb24gaXMgdGhvd24gd2hpY2ggaW1wbGllcworICogdGhlIGZvbGxvd2luZzoKKyAqICAxLiB0aGUgc3RyZWFtIGNvbnRhaW5zIHNjcmFwcHkgaGFuZHNoYWtlIHJlY29yZCwKKyAqICAyLiB0aGUgcmVhZCBwb3NpdGlvbiBzaG91bGQgYmUgcmVzZXRlZCB0byBtYXJrZWQsCisgKiAgMy4gYW5kIG1vcmUgaW5jb21lIGRhdGEgaXMgZXhwZWN0ZWQuCisgKiBUaGUgdGhyb3dpbmcgb2YgdGhlIGV4Y2VwdGlvbiAoaW5zdGVhZCBvZiByZXR1cm5pbmcgb2YgLTEgdmFsdWUKKyAqIG9yIGluY29tcGxlYXRlIGZpbGxpbmcgb2YgZGVzdGluYXRpb24gYnVmZmVyKQorICogaGVscHMgdG8gc3BlZWQgdXAgdGhlIHByb2Nlc3Mgb2Ygc2NyYXBweSBkYXRhIHJlY29nbml0aW9uIGFuZAorICogcHJvY2Vzc2luZy4KKyAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IFRMUyBoYW5kc2hha2UgcHJvY2VzcyBzZWUKKyAqIFRMUyB2IDEgc3BlY2lmaWNhdGlvbiBhdCBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMjQ2LnR4dC4KKyAqLworcHVibGljIGNsYXNzIEhhbmRzaGFrZUlPRGF0YVN0cmVhbQorICAgICAgICBleHRlbmRzIFNTTElucHV0U3RyZWFtIGltcGxlbWVudHMgb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZS5BcHBlbmRhYmxlLCBEYXRhU3RyZWFtIHsKKworICAgIC8vIE9iamVjdHMgYXJlIHVzZWQgdG8gY29tcHV0ZSBkaWdlc3RzIG9mIGRhdGEgcGFzc2VkCisgICAgLy8gZHVyaW5nIHRoZSBoYW5kc2hha2UgcGhhc2UKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNZXNzYWdlRGlnZXN0IG1kNTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNZXNzYWdlRGlnZXN0IHNoYTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtZDUgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJNRDUiKTsKKyAgICAgICAgICAgIHNoYSA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoIlNIQS0xIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJDb3VsZCBub3QgaW5pdGlhbGl6ZSB0aGUgRGlnZXN0IEFsZ29yaXRobXMuIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgSGFuZHNoYWtlSU9EYXRhU3RyZWFtKCkge30KKworICAgIC8vIGJ1ZmZlciBpcyB1c2VkIHRvIGtlZXAgdGhlIGhhbmRzaGFraW5nIGRhdGE7CisgICAgcHJpdmF0ZSBpbnQgYnVmZl9zaXplID0gMTAyNDsKKyAgICBwcml2YXRlIGludCBpbmNfYnVmZl9zaXplID0gMTAyNDsKKyAgICBwcml2YXRlIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtidWZmX3NpemVdOworCisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tIElucHV0IHJlbGF0ZWQgZnVuY3Rpb25hbGl0eSAtLS0tLS0tLS0tLS0tLS0tLQorCisgICAgLy8gcG9zaXRpb24gb2YgdGhlIG5leHQgYnl0ZSB0byByZWFkCisgICAgcHJpdmF0ZSBpbnQgcmVhZF9wb3M7CisgICAgcHJpdmF0ZSBpbnQgbWFya2VkX3BvczsKKyAgICAvLyBwb3NpdGlvbiBvZiB0aGUgbGFzdCBieXRlIHRvIHJlYWQgKyAxCisgICAgcHJpdmF0ZSBpbnQgcmVhZF9wb3NfZW5kOworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB7CisgICAgICAgIHJldHVybiByZWFkX3Bvc19lbmQgLSByZWFkX3BvczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXJrU3VwcG9ydGVkKCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBtYXJrKGludCBsaW1pdCkgeworICAgICAgICBtYXJrZWRfcG9zID0gcmVhZF9wb3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgbWFyaygpIHsKKyAgICAgICAgbWFya2VkX3BvcyA9IHJlYWRfcG9zOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgICAgICByZWFkX3BvcyA9IG1hcmtlZF9wb3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgZGF0YSBmcm9tIHRoZSBtYXJrZWQgcG9zaXRpb24gdG8KKyAgICAgKiB0aGUgY3VycmVudCByZWFkIHBvc2l0aW9uLiBUaGUgbWV0aG9kIGlzIHVzZWZ1bGwgd2hlbiBpdCBpcyBuZWVkZWQKKyAgICAgKiB0byBkZWxldGUgb25lIG1lc3NhZ2UgZnJvbSB0aGUgaW50ZXJuYWwgYnVmZmVyLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHJlbW92ZUZyb21NYXJrZWRQb3NpdGlvbigpIHsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWZmZXIsIHJlYWRfcG9zLAorICAgICAgICAgICAgICAgIGJ1ZmZlciwgbWFya2VkX3BvcywgcmVhZF9wb3NfZW5kIC0gcmVhZF9wb3MpOworICAgICAgICByZWFkX3Bvc19lbmQgLT0gKHJlYWRfcG9zIC0gbWFya2VkX3Bvcyk7CisgICAgICAgIHJlYWRfcG9zID0gbWFya2VkX3BvczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiByZWFkIGFuIG9wYXF1ZSB2YWx1ZTsKKyAgICAgKiBAcGFyYW0gICBieXRlOiAgIGJ5dGUKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHJlYWRfcG9zID09IHJlYWRfcG9zX2VuZCkgeworICAgICAgICAgICAgLy9yZXR1cm4gLTE7CisgICAgICAgICAgICB0aHJvdyBuZXcgRW5kT2ZCdWZmZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnVmZmVyW3JlYWRfcG9zKytdICYgMHhGRjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiByZWFkcyB2ZWN0b3Igb2Ygb3BhcXVlIHZhbHVlcworICAgICAqIEBwYXJhbSAgIG5ldzogICAgbG9uZworICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZVtdIHJlYWQoaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGxlbmd0aCA+IGF2YWlsYWJsZSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRW5kT2ZCdWZmZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gcmVzID0gbmV3IGJ5dGVbbGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWZmZXIsIHJlYWRfcG9zLCByZXMsIDAsIGxlbmd0aCk7CisgICAgICAgIHJlYWRfcG9zID0gcmVhZF9wb3MgKyBsZW5ndGg7CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGJ5dGVbXSBkc3QsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChsZW5ndGggPiBhdmFpbGFibGUoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVuZE9mQnVmZmVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWZmZXIsIHJlYWRfcG9zLCBkc3QsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgcmVhZF9wb3MgPSByZWFkX3BvcyArIGxlbmd0aDsKKyAgICAgICAgcmV0dXJuIGxlbmd0aDsKKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tIEV4dGVuZGluZyBvZiB0aGUgaW5wdXQgZGF0YSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIC8qKgorICAgICAqIEFwcGVuZHMgdGhlIGluY29tZSBkYXRhIHRvIGJlIHJlYWQgYnkgaGFuZHNoYWtlIHByb3RvY29sLgorICAgICAqIFRoZSBhdHRlbXB0cyB0byBvdmVyZmxvdyB0aGUgYnVmZmVyIGJ5IG1lYW5zIG9mIHRoaXMgbWV0aG9kcworICAgICAqIHNlZW0gdG8gYmUgZnV0aWxlIGJlY2F1c2Ugb2Y6CisgICAgICogMS4gVGhlIFNTTCBwcm90b2NvbCBzcGVjaWZpZXMgdGhlIG1heGltdW0gc2l6ZSBvZiB0aGUgcmVjb3JkCisgICAgICogYW5kIHJlY29yZCBwcm90b2NvbCBkb2VzIG5vdCBwYXNzIGh1Z2UgbWVzc2FnZXMuCisgICAgICogKHNlZSBUTFMgdjEgc3BlY2lmaWNhdGlvbiBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMjQ2LnR4dCAsCisgICAgICogcCA2LjIpCisgICAgICogMi4gQWZ0ZXIgZWFjaCBjYWxsIG9mIHRoaXMgbWV0aG9kLCBoYW5kc2hha2UgcHJvdG9jb2wgc2hvdWxkCisgICAgICogc3RhcnQgKGFuZCBzdGFydHMpIHRoZSBvcGVyYXRpb25zIG9uIHJlY2VpdmVkIGRhdGEgYW5kIHJlY29nbml6ZQorICAgICAqIHRoZSBmYWtlIGRhdGEgaWYgc3VjaCB3YXMgcHJvdmlkZWQgKHRvIGNoZWNrIHRoZSBzaXplIG9mIGNlcnRpZmljYXRlCisgICAgICogZm9yIGV4YW1wbGUpLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFwcGVuZChieXRlW10gc3JjKSB7CisgICAgICAgIGFwcGVuZChzcmMsIDAsIHNyYy5sZW5ndGgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhcHBlbmQoYnl0ZVtdIHNyYywgaW50IGZyb20sIGludCBsZW5ndGgpIHsKKyAgICAgICAgaWYgKHJlYWRfcG9zID09IHJlYWRfcG9zX2VuZCkgeworICAgICAgICAgICAgLy8gc3RhcnQgcmVhZGluZyBzdGF0ZSBhZnRlciB3cml0aW5nCisgICAgICAgICAgICBpZiAod3JpdGVfcG9zX2JlZyAhPSB3cml0ZV9wb3MpIHsKKyAgICAgICAgICAgICAgICAvLyBlcnJvcjogb3V0Ym91ZCBoYW5kc2hha2UgZGF0YSB3YXMgbm90IHNlbnQsCisgICAgICAgICAgICAgICAgLy8gYnV0IGluYm91bmQgaGFuZHNoYWtlIGRhdGEgaGFzIGJlZW4gcmVjZWl2ZWQuCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFsZXJ0RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICBBbGVydFByb3RvY29sLlVORVhQRUNURURfTUVTU0FHRSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IFNTTEhhbmRzaGFrZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICJIYW5kc2hha2UgbWVzc2FnZSBoYXMgYmVlbiByZWNlaXZlZCBiZWZvcmUgIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAidGhlIGxhc3Qgb3Vib3VuZCBtZXNzYWdlIGhhZCBiZWVuIHNlbnQuIikpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHJlYWRfcG9zIDwgd3JpdGVfcG9zKSB7CisgICAgICAgICAgICAgICAgcmVhZF9wb3MgPSB3cml0ZV9wb3M7CisgICAgICAgICAgICAgICAgcmVhZF9wb3NfZW5kID0gcmVhZF9wb3M7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJlYWRfcG9zX2VuZCArIGxlbmd0aCA+IGJ1ZmZfc2l6ZSkgeworICAgICAgICAgICAgZW5sYXJnZUJ1ZmZlcihyZWFkX3Bvc19lbmQrbGVuZ3RoLWJ1ZmZfc2l6ZSk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzcmMsIGZyb20sIGJ1ZmZlciwgcmVhZF9wb3NfZW5kLCBsZW5ndGgpOworICAgICAgICByZWFkX3Bvc19lbmQgKz0gbGVuZ3RoOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBlbmxhcmdlQnVmZmVyKGludCBzaXplKSB7CisgICAgICAgIGJ1ZmZfc2l6ZSA9IChzaXplIDwgaW5jX2J1ZmZfc2l6ZSkKKyAgICAgICAgICAgID8gYnVmZl9zaXplICsgaW5jX2J1ZmZfc2l6ZQorICAgICAgICAgICAgOiBidWZmX3NpemUgKyBzaXplOworICAgICAgICBieXRlW10gbmV3X2J1ZmYgPSBuZXcgYnl0ZVtidWZmX3NpemVdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZmZlciwgMCwgbmV3X2J1ZmYsIDAsIGJ1ZmZlci5sZW5ndGgpOworICAgICAgICBidWZmZXIgPSBuZXdfYnVmZjsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBjbGVhckJ1ZmZlcigpIHsKKyAgICAgICAgcmVhZF9wb3MgPSAwOworICAgICAgICBtYXJrZWRfcG9zID0gMDsKKyAgICAgICAgcmVhZF9wb3NfZW5kID0gMDsKKyAgICAgICAgd3JpdGVfcG9zID0gMDsKKyAgICAgICAgd3JpdGVfcG9zX2JlZyA9IDA7CisgICAgICAgIEFycmF5cy5maWxsKGJ1ZmZlciwgKGJ5dGUpIDApOworICAgIH0KKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0gT3V0cHV0IHJlbGF0ZWQgZnVuY3Rpb25hbGl0eSAtLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgLy8gcG9zaXRpb24gaW4gdGhlIGJ1ZmZlciBhdmFpbGFibGUgZm9yIHdyaXRlCisgICAgcHJpdmF0ZSBpbnQgd3JpdGVfcG9zOworICAgIC8vIHBvc2l0aW9uIGluIHRoZSBidWZmZXIgd2hlcmUgdGhlIGxhc3Qgd3JpdGUgc2Vzc2lvbiBoYXMgYmVndW4KKyAgICBwcml2YXRlIGludCB3cml0ZV9wb3NfYmVnOworCisgICAgLy8gY2hlY2tzIGlmIHRoZSBkYXRhIGNhbiBiZSB3cml0dGVuIGluIHRoZSBidWZmZXIKKyAgICBwcml2YXRlIHZvaWQgY2hlY2soaW50IGxlbmd0aCkgeworICAgICAgICAvLyAod3JpdGVfcG9zID09IHdyaXRlX3Bvc19iZWcpIGlmZjoKKyAgICAgICAgLy8gMS4gdGhlcmUgd2VyZSBub3Qgd3JpdGUgb3BlcmF0aW9ucyB5ZXQKKyAgICAgICAgLy8gMi4gYWxsIHdyaXR0ZW4gZGF0YSB3YXMgZGVtYW5kZWQgYnkgZ2V0RGF0YSBtZXRob2RzCisgICAgICAgIGlmICh3cml0ZV9wb3MgPT0gd3JpdGVfcG9zX2JlZykgeworICAgICAgICAgICAgLy8ganVzdCBzdGFydGVkIHRvIHdyaXRlIGFmdGVyIHRoZSByZWFkaW5nCisgICAgICAgICAgICBpZiAocmVhZF9wb3MgIT0gcmVhZF9wb3NfZW5kKSB7CisgICAgICAgICAgICAgICAgLy8gZXJyb3I6IGF0dGVtcHQgdG8gd3JpdGUgb3V0Ym91bmQgZGF0YSBpbnRvIHRoZSBzdHJlYW0gYmVmb3JlCisgICAgICAgICAgICAgICAgLy8gYWxsIHRoZSBpbmJvdW5kIGhhbmRzaGFrZSBkYXRhIGhhZCBiZWVuIHJlYWQKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWxlcnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICBBbGVydFByb3RvY29sLklOVEVSTkFMX0VSUk9SLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFNTTEhhbmRzaGFrZUV4Y2VwdGlvbigiRGF0YSB3YXMgbm90IGZ1bGx5IHJlYWQ6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgcmVhZF9wb3MgKyAiICIgKyByZWFkX3Bvc19lbmQpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIHNldCB1cCB0aGUgd3JpdGUgcG9zaXRpb25zCisgICAgICAgICAgICBpZiAod3JpdGVfcG9zX2JlZyA8IHJlYWRfcG9zX2VuZCkgeworICAgICAgICAgICAgICAgIHdyaXRlX3Bvc19iZWcgPSByZWFkX3Bvc19lbmQ7CisgICAgICAgICAgICAgICAgd3JpdGVfcG9zID0gd3JpdGVfcG9zX2JlZzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBpZiB0aGVyZSBpcyBub3QgZW5vdWdodCBmcmVlIHNwYWNlIGluIHRoZSBidWZmZXIgLSBlbmxhcmdlIGl0OgorICAgICAgICBpZiAod3JpdGVfcG9zICsgbGVuZ3RoID49IGJ1ZmZfc2l6ZSkgeworICAgICAgICAgICAgZW5sYXJnZUJ1ZmZlcihsZW5ndGgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIGFuIG9wYXF1ZSB2YWx1ZQorICAgICAqIEBwYXJhbSAgIGJ5dGU6ICAgYnl0ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGUgYikgeworICAgICAgICBjaGVjaygxKTsKKyAgICAgICAgYnVmZmVyW3dyaXRlX3BvcysrXSA9IGI7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIFVpbnQ4IHZhbHVlCisgICAgICogQHBhcmFtIGxvbmc6IHRoZSB2YWx1ZSB0byBiZSB3cml0dGVuIChsYXN0IGJ5dGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVVaW50OChsb25nIG4pIHsKKyAgICAgICAgY2hlY2soMSk7CisgICAgICAgIGJ1ZmZlclt3cml0ZV9wb3MrK10gPSAoYnl0ZSkgKG4gJiAweDAwZmYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBVaW50MTYgdmFsdWUKKyAgICAgKiBAcGFyYW0gbG9uZzogdGhlIHZhbHVlIHRvIGJlIHdyaXR0ZW4gKGxhc3QgMiBieXRlcykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVVpbnQxNihsb25nIG4pIHsKKyAgICAgICAgY2hlY2soMik7CisgICAgICAgIGJ1ZmZlclt3cml0ZV9wb3MrK10gPSAoYnl0ZSkgKChuICYgMHgwMGZmMDApID4+IDgpOworICAgICAgICBidWZmZXJbd3JpdGVfcG9zKytdID0gKGJ5dGUpIChuICYgMHgwMGZmKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgVWludDI0IHZhbHVlCisgICAgICogQHBhcmFtIGxvbmc6IHRoZSB2YWx1ZSB0byBiZSB3cml0dGVuIChsYXN0IDMgYnl0ZXMpCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVVaW50MjQobG9uZyBuKSB7CisgICAgICAgIGNoZWNrKDMpOworICAgICAgICBidWZmZXJbd3JpdGVfcG9zKytdID0gKGJ5dGUpICgobiAmIDB4MDBmZjAwMDApID4+IDE2KTsKKyAgICAgICAgYnVmZmVyW3dyaXRlX3BvcysrXSA9IChieXRlKSAoKG4gJiAweDAwZmYwMCkgPj4gOCk7CisgICAgICAgIGJ1ZmZlclt3cml0ZV9wb3MrK10gPSAoYnl0ZSkgKG4gJiAweDAwZmYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBVaW50MzIgdmFsdWUKKyAgICAgKiBAcGFyYW0gbG9uZzogdGhlIHZhbHVlIHRvIGJlIHdyaXR0ZW4gKGxhc3QgNCBieXRlcykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVVpbnQzMihsb25nIG4pIHsKKyAgICAgICAgY2hlY2soNCk7CisgICAgICAgIGJ1ZmZlclt3cml0ZV9wb3MrK10gPSAoYnl0ZSkgKChuICYgMHgwMGZmMDAwMDAwKSA+PiAyNCk7CisgICAgICAgIGJ1ZmZlclt3cml0ZV9wb3MrK10gPSAoYnl0ZSkgKChuICYgMHgwMGZmMDAwMCkgPj4gMTYpOworICAgICAgICBidWZmZXJbd3JpdGVfcG9zKytdID0gKGJ5dGUpICgobiAmIDB4MDBmZjAwKSA+PiA4KTsKKyAgICAgICAgYnVmZmVyW3dyaXRlX3BvcysrXSA9IChieXRlKSAobiAmIDB4MDBmZik7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIFVpbnQ2NCB2YWx1ZQorICAgICAqIEBwYXJhbSBsb25nOiB0aGUgdmFsdWUgdG8gYmUgd3JpdHRlbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlVWludDY0KGxvbmcgbikgeworICAgICAgICBjaGVjayg4KTsKKyAgICAgICAgYnVmZmVyW3dyaXRlX3BvcysrXSA9IChieXRlKSAoKG4gJiAweDAwZmYwMDAwMDAwMDAwMDAwMEwpID4+IDU2KTsKKyAgICAgICAgYnVmZmVyW3dyaXRlX3BvcysrXSA9IChieXRlKSAoKG4gJiAweDAwZmYwMDAwMDAwMDAwMDBMKSA+PiA0OCk7CisgICAgICAgIGJ1ZmZlclt3cml0ZV9wb3MrK10gPSAoYnl0ZSkgKChuICYgMHgwMGZmMDAwMDAwMDAwMEwpID4+IDQwKTsKKyAgICAgICAgYnVmZmVyW3dyaXRlX3BvcysrXSA9IChieXRlKSAoKG4gJiAweDAwZmYwMDAwMDAwMEwpID4+IDMyKTsKKyAgICAgICAgYnVmZmVyW3dyaXRlX3BvcysrXSA9IChieXRlKSAoKG4gJiAweDAwZmYwMDAwMDApID4+IDI0KTsKKyAgICAgICAgYnVmZmVyW3dyaXRlX3BvcysrXSA9IChieXRlKSAoKG4gJiAweDAwZmYwMDAwKSA+PiAxNik7CisgICAgICAgIGJ1ZmZlclt3cml0ZV9wb3MrK10gPSAoYnl0ZSkgKChuICYgMHgwMGZmMDApID4+IDgpOworICAgICAgICBidWZmZXJbd3JpdGVfcG9zKytdID0gKGJ5dGUpIChuICYgMHgwMGZmKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB3cml0ZXMgdmVjdG9yIG9mIG9wYXF1ZSB2YWx1ZXMKKyAgICAgKiBAcGFyYW0gIHZlY3RvciB0aGUgdmVjdG9yIHRvIGJlIHdyaXR0ZW4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gdmVjdG9yKSB7CisgICAgICAgIGNoZWNrKHZlY3Rvci5sZW5ndGgpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHZlY3RvciwgMCwgYnVmZmVyLCB3cml0ZV9wb3MsIHZlY3Rvci5sZW5ndGgpOworICAgICAgICB3cml0ZV9wb3MgKz0gdmVjdG9yLmxlbmd0aDsKKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tIFJldHJpZXZlIHRoZSB3cml0dGVuIGJ5dGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIHB1YmxpYyBib29sZWFuIGhhc0RhdGEoKSB7CisgICAgICAgIHJldHVybiAod3JpdGVfcG9zID4gd3JpdGVfcG9zX2JlZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogcmV0dXJucyB0aGUgY2h1bmsgb2Ygc3RvcmVkIGRhdGEgd2l0aCB0aGUgbGVuZ3RoIG5vIG1vcmUgdGhhbiBzcGVjaWZpZWQuCisgICAgICogQHBhcmFtICAgbGVuZ3RoOiBpbnQKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXREYXRhKGludCBsZW5ndGgpIHsKKyAgICAgICAgYnl0ZVtdIHJlczsKKyAgICAgICAgaWYgKHdyaXRlX3BvcyAtIHdyaXRlX3Bvc19iZWcgPCBsZW5ndGgpIHsKKyAgICAgICAgICAgIHJlcyA9IG5ldyBieXRlW3dyaXRlX3BvcyAtIHdyaXRlX3Bvc19iZWddOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWZmZXIsIHdyaXRlX3Bvc19iZWcsCisgICAgICAgICAgICAgICAgICAgIHJlcywgMCwgd3JpdGVfcG9zLXdyaXRlX3Bvc19iZWcpOworICAgICAgICAgICAgd3JpdGVfcG9zX2JlZyA9IHdyaXRlX3BvczsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlcyA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZmZlciwgd3JpdGVfcG9zX2JlZywgcmVzLCAwLCBsZW5ndGgpOworICAgICAgICAgICAgd3JpdGVfcG9zX2JlZyArPSBsZW5ndGg7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tIE1lc3NhZ2UgRGlnZXN0IEZ1bmN0aW9uYWxpdHkgLS0tLS0tLS0tLS0tLS0tLQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgTUQ1IGRpZ2VzdCBvZiB0aGUgZGF0YSBwYXNzZWQgdGhyb3VnaHQgdGhlIHN0cmVhbQorICAgICAqIEByZXR1cm4gTUQ1IGRpZ2VzdAorICAgICAqLworICAgIHByb3RlY3RlZCBieXRlW10gZ2V0RGlnZXN0TUQ1KCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKG1kNSkgeworICAgICAgICAgICAgaW50IGxlbiA9IChyZWFkX3Bvc19lbmQgPiB3cml0ZV9wb3MpCisgICAgICAgICAgICAgICAgPyByZWFkX3Bvc19lbmQKKyAgICAgICAgICAgICAgICA6IHdyaXRlX3BvczsKKyAgICAgICAgICAgIG1kNS51cGRhdGUoYnVmZmVyLCAwLCBsZW4pOworICAgICAgICAgICAgcmV0dXJuIG1kNS5kaWdlc3QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIFNIQS0xIGRpZ2VzdCBvZiB0aGUgZGF0YSBwYXNzZWQgdGhyb3VnaHQgdGhlIHN0cmVhbQorICAgICAqIEByZXR1cm4gU0hBLTEgZGlnZXN0CisgICAgICovCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBnZXREaWdlc3RTSEEoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoc2hhKSB7CisgICAgICAgICAgICBpbnQgbGVuID0gKHJlYWRfcG9zX2VuZCA+IHdyaXRlX3BvcykKKyAgICAgICAgICAgICAgICA/IHJlYWRfcG9zX2VuZAorICAgICAgICAgICAgICAgIDogd3JpdGVfcG9zOworICAgICAgICAgICAgc2hhLnVwZGF0ZShidWZmZXIsIDAsIGxlbik7CisgICAgICAgICAgICByZXR1cm4gc2hhLmRpZ2VzdCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgTUQ1IGRpZ2VzdCBvZiB0aGUgZGF0YSBwYXNzZWQgdGhyb3VnaHQgdGhlIHN0cmVhbQorICAgICAqIGV4Y2VwdCBsYXN0IG1lc3NhZ2UKKyAgICAgKiBAcmV0dXJuIE1ENSBkaWdlc3QKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIGdldERpZ2VzdE1ENXdpdGhvdXRMYXN0KCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKG1kNSkgeworICAgICAgICAgICAgbWQ1LnVwZGF0ZShidWZmZXIsIDAsIG1hcmtlZF9wb3MpOworICAgICAgICAgICAgcmV0dXJuIG1kNS5kaWdlc3QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIFNIQS0xIGRpZ2VzdCBvZiB0aGUgZGF0YSBwYXNzZWQgdGhyb3VnaHQgdGhlIHN0cmVhbQorICAgICAqIGV4Y2VwdCBsYXN0IG1lc3NhZ2UKKyAgICAgKiBAcmV0dXJuIFNIQS0xIGRpZ2VzdAorICAgICAqLworICAgIHByb3RlY3RlZCBieXRlW10gZ2V0RGlnZXN0U0hBd2l0aG91dExhc3QoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAoc2hhKSB7CisgICAgICAgICAgICBzaGEudXBkYXRlKGJ1ZmZlciwgMCwgbWFya2VkX3Bvcyk7CisgICAgICAgICAgICByZXR1cm4gc2hhLmRpZ2VzdCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbGwgdGhlIGRhdGEgcGFzc2VkIHRocm91Z2h0IHRoZSBzdHJlYW0KKyAgICAgKiBAcmV0dXJuIGFsbCB0aGUgZGF0YSBwYXNzZWQgdGhyb3VnaHQgdGhlIHN0cmVhbSBhdCB0aGUgbW9tZW50CisgICAgICovCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBnZXRNZXNzYWdlcygpIHsKKyAgICAgICAgaW50IGxlbiA9IChyZWFkX3Bvc19lbmQgPiB3cml0ZV9wb3MpID8gcmVhZF9wb3NfZW5kIDogd3JpdGVfcG9zOworICAgICAgICBieXRlW10gcmVzID0gbmV3IGJ5dGVbbGVuXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWZmZXIsIDAsIHJlcywgMCwgbGVuKTsKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9IYW5kc2hha2VQcm90b2NvbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvSGFuZHNoYWtlUHJvdG9jb2wuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mODAxNmYxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvSGFuZHNoYWtlUHJvdG9jb2wuamF2YQpAQCAtMCwwICsxLDUzMCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlGYWN0b3J5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuUlNBS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5JbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuUlNBUHVibGljS2V5U3BlYzsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFbmdpbmVSZXN1bHQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xIYW5kc2hha2VFeGNlcHRpb247CisKKy8qKgorICogQmFzZSBjbGFzcyBmb3IgQ2xpZW50SGFuZHNoYWtlSW1wbCBhbmQgU2VydmVySGFuZHNoYWtlSW1wbCBjbGFzc2VzLgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMjQ2LnR4dCI+VExTIDEuMCBzcGVjLiwgNy40LgorICogSGFuZHNoYWtlIHByb3RvY29sPC9hPgorICoKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEhhbmRzaGFrZVByb3RvY29sIHsKKworICAgIC8qKgorICAgICAqIEhhbmRzaGFrZSBzdGF0dXMgTkVFRF9VTldSQVAgLSBIYW5kc2hha2VQcm90b2NvbCBuZWVkcyB0byByZWNlaXZlIGRhdGEKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBORUVEX1VOV1JBUCA9IDE7CisKKyAgICAvKioKKyAgICAgKiBIYW5kc2hha2Ugc3RhdHVzIE5PVF9IQU5EU0hBS0lORyAtIGlzIG5vdCBjdXJyZW50bHkgaGFuZHNoYWtpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT1RfSEFORFNIQUtJTkcgPSAyOworCisgICAgLyoqCisgICAgICogSGFuZHNoYWtlIHN0YXR1cyBGSU5JU0hFRCAtIEhhbmRzaGFrZVByb3RvY29sIGhhcyBqdXN0IGZpbmlzaGVkCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklOSVNIRUQgPSAzOworCisgICAgLyoqCisgICAgICogSGFuZHNoYWtlIHN0YXR1cyBORUVEX1RBU0sgLSBIYW5kc2hha2VQcm90b2NvbCBuZWVkcyB0aGUgcmVzdWx0cyBvZiBkZWxlZ2F0ZWQgdGFzaworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5FRURfVEFTSyA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBDdXJyZW50IGhhbmRzaGFrZSBzdGF0dXMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHN0YXR1cyA9IE5PVF9IQU5EU0hBS0lORzsKKworICAgIC8qKgorICAgICAqIElPIHN0cmVhbSBmb3IgaW5jb21lL291dGNvbWUgaGFuZHNoYWtlIGRhdGEKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSGFuZHNoYWtlSU9EYXRhU3RyZWFtIGlvX3N0cmVhbSA9IG5ldyBIYW5kc2hha2VJT0RhdGFTdHJlYW0oKTsKKworICAgIC8qKgorICAgICAqIFNTTCBSZWNvcmQgUHJvdG9jb2wgaW1wbGVtZW50YXRpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIFNTTFJlY29yZFByb3RvY29sIHJlY29yZFByb3RvY29sOworCisgICAgLyoqCisgICAgICogU1NMUGFyYW1ldGVyc0ltcGwgc3VwbGllZCBieSBTU0xTb2NrZXQgb3IgU1NMRW5naW5lCisgICAgICovCisgICAgcHJvdGVjdGVkIFNTTFBhcmFtZXRlcnNJbXBsIHBhcmFtZXRlcnM7CisKKyAgICAvKioKKyAgICAgKiBEZWxlZ2F0ZWQgdGFza3MgZm9yIHRoaXMgaGFuZHNoYWtlIGltcGxlbWVudGF0aW9uCisgICAgICovCisgICAgcHJvdGVjdGVkIFZlY3RvcjxEZWxlZ2F0ZWRUYXNrPiBkZWxlZ2F0ZWRUYXNrcyA9IG5ldyBWZWN0b3I8RGVsZWdhdGVkVGFzaz4oKTsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyBub24tYmxvY2tpbmcgaGFuZHNoYWtlCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gbm9uQmxvY2tpbmc7CisKKyAgICAvKioKKyAgICAgKiBQZW5kaW5nIHNlc3Npb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU1NMU2Vzc2lvbkltcGwgc2Vzc2lvbjsKKworICAgIC8qKgorICAgICAqIFNlbnQgYW5kIHJlY2VpdmVkIGhhbmRzaGFrZSBtZXNzYWdlcworICAgICAqLworICAgIHByb3RlY3RlZCBDbGllbnRIZWxsbyBjbGllbnRIZWxsbzsKKyAgICBwcm90ZWN0ZWQgU2VydmVySGVsbG8gc2VydmVySGVsbG87CisgICAgcHJvdGVjdGVkIENlcnRpZmljYXRlTWVzc2FnZSBzZXJ2ZXJDZXJ0OworICAgIHByb3RlY3RlZCBTZXJ2ZXJLZXlFeGNoYW5nZSBzZXJ2ZXJLZXlFeGNoYW5nZTsKKyAgICBwcm90ZWN0ZWQgQ2VydGlmaWNhdGVSZXF1ZXN0IGNlcnRpZmljYXRlUmVxdWVzdDsKKyAgICBwcm90ZWN0ZWQgU2VydmVySGVsbG9Eb25lIHNlcnZlckhlbGxvRG9uZTsKKyAgICBwcm90ZWN0ZWQgQ2VydGlmaWNhdGVNZXNzYWdlIGNsaWVudENlcnQ7CisgICAgcHJvdGVjdGVkIENsaWVudEtleUV4Y2hhbmdlIGNsaWVudEtleUV4Y2hhbmdlOworICAgIHByb3RlY3RlZCBDZXJ0aWZpY2F0ZVZlcmlmeSBjZXJ0aWZpY2F0ZVZlcmlmeTsKKyAgICBwcm90ZWN0ZWQgRmluaXNoZWQgY2xpZW50RmluaXNoZWQ7CisgICAgcHJvdGVjdGVkIEZpbmlzaGVkIHNlcnZlckZpbmlzaGVkOworCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHRoYXQgY2hhbmdlIGNpcGhlciBzcGVjIG1lc3NhZ2UgaGFzIGJlZW4gcmVjZWl2ZWQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBjaGFuZ2VDaXBoZXJTcGVjUmVjZWl2ZWQgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyBwcmV2aW91cyBzZXNzaW9uIHJlc3VtaW5nCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNSZXN1bWluZyA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogIFByZW1hc3RlciBzZWNyZXQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIHByZU1hc3RlclNlY3JldDsKKworICAgIC8qKgorICAgICAqIEV4Y2VwdGlvbiBvY2N1cmVkIGluIGRlbGVnYXRlZCB0YXNrCisgICAgICovCisgICAgcHJvdGVjdGVkIEV4Y2VwdGlvbiBkZWxlZ2F0ZWRUYXNrRXJyOworCisgICAgLy8gcmVmZXJlbmNlIHZlcmlmeV9kYXRhIHVzZWQgdG8gdmVyaWZ5IGZpbmlzaGVkIG1lc3NhZ2UKKyAgICBwcml2YXRlIGJ5dGVbXSB2ZXJpZnlfZGF0YSA9IG5ldyBieXRlWzEyXTsKKworICAgIC8vIEVuY29kaW5nIG9mICJtYXN0ZXIgc2VjcmV0IiBzdHJpbmc6ICJtYXN0ZXIgc2VjcmV0Ii5nZXRCeXRlcygpCisgICAgcHJpdmF0ZSBieXRlW10gbWFzdGVyX3NlY3JldF9ieXRlcyA9CisgICAgICAgICAgICB7MTA5LCA5NywgMTE1LCAxMTYsIDEwMSwgMTE0LCAzMiwgMTE1LCAxMDEsIDk5LCAxMTQsIDEwMSwgMTE2IH07CisKKyAgICAvLyBpbmRpY2F0ZXMgd2hldGhlciBwcm90b2NvbCBuZWVkcyB0byBzZW5kIGNoYW5nZSBjaXBoZXIgc3BlYyBtZXNzYWdlCisgICAgcHJpdmF0ZSBib29sZWFuIG5lZWRTZW5kQ0NTcGVjID0gZmFsc2U7CisKKyAgICAvLyBpbmRpY2F0ZXMgd2hldGhlciBwcm90b2NvbCBuZWVkcyB0byBzZW5kIGNoYW5nZSBjaXBoZXIgc3BlYyBtZXNzYWdlCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gbmVlZFNlbmRIZWxsb1JlcXVlc3QgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIFNTTEVuZ2luZSBvd25pbmcgdGhpcyBIYW5kc2hha2VQcm90b2NvbAorICAgICAqLworICAgIHB1YmxpYyBTU0xFbmdpbmVJbXBsIGVuZ2luZU93bmVyOworCisgICAgLyoqCisgICAgICogU1NMU29ja2V0IG93bmluZyB0aGlzIEhhbmRzaGFrZVByb3RvY29sCisgICAgICovCisgICAgcHVibGljIFNTTFNvY2tldEltcGwgc29ja2V0T3duZXI7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIEhhbmRzaGFrZVByb3RvY29sIGluc3RhbmNlCisgICAgICogQHBhcmFtIG93bmVyCisgICAgICovCisgICAgcHJvdGVjdGVkIEhhbmRzaGFrZVByb3RvY29sKE9iamVjdCBvd25lcikgeworICAgICAgICBpZiAob3duZXIgaW5zdGFuY2VvZiBTU0xFbmdpbmVJbXBsKSB7CisgICAgICAgICAgICBlbmdpbmVPd25lciA9IChTU0xFbmdpbmVJbXBsKSBvd25lcjsKKyAgICAgICAgICAgIG5vbkJsb2NraW5nID0gdHJ1ZTsKKyAgICAgICAgICAgIHRoaXMucGFyYW1ldGVycyA9IGVuZ2luZU93bmVyLnNzbFBhcmFtZXRlcnM7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAob3duZXIgaW5zdGFuY2VvZiBTU0xTb2NrZXRJbXBsKSB7CisgICAgICAgICAgICBzb2NrZXRPd25lciA9IChTU0xTb2NrZXRJbXBsKSBvd25lcjsKKyAgICAgICAgICAgIG5vbkJsb2NraW5nID0gZmFsc2U7CisgICAgICAgICAgICB0aGlzLnBhcmFtZXRlcnMgPSBzb2NrZXRPd25lci5zc2xQYXJhbWV0ZXJzOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBTU0wgUmVjb3JkIFByb3RvY29sCisgICAgICogQHBhcmFtIHJlY29yZFByb3RvY29sCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmVjb3JkUHJvdG9jb2woU1NMUmVjb3JkUHJvdG9jb2wgcmVjb3JkUHJvdG9jb2wpIHsKKyAgICAgICAgdGhpcy5yZWNvcmRQcm90b2NvbCA9IHJlY29yZFByb3RvY29sOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0YXJ0IHNlc3Npb24gbmVnb3RpYXRpb24KKyAgICAgKiBAcGFyYW0gc2Vzc2lvbgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHN0YXJ0KCk7CisKKyAgICAvKioKKyAgICAgKiBTdG9wcyB0aGUgY3VycmVudCBzZXNzaW9uIHJlbmVnb3RpYXRpb24gcHJvY2Vzcy4KKyAgICAgKiBTdWNoIGZ1bmN0aW9uYWxpdHkgaXMgbmVlZGVkIHdoZW4gaXQgaXMgc2Vzc2lvbiByZW5lZ290aWF0aW9uCisgICAgICogcHJvY2VzcyBhbmQgbm9fcmVuZWdvdGlhdGlvbiBhbGVydCBtZXNzYWdlIGlzIHJlY2VpdmVkCisgICAgICogZnJvbSBhbm90aGVyIHBlZXIuCisgICAgICogQHBhcmFtIHNlc3Npb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzdG9wKCkgeworICAgICAgICBjbGVhck1lc3NhZ2VzKCk7CisgICAgICAgIHN0YXR1cyA9IE5PVF9IQU5EU0hBS0lORzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGhhbmRzaGFrZSBzdGF0dXMKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMgZ2V0U3RhdHVzKCkgeworICAgICAgICBpZiAoaW9fc3RyZWFtLmhhc0RhdGEoKSB8fCBuZWVkU2VuZENDU3BlYyB8fAorICAgICAgICAgICAgICAgIG5lZWRTZW5kSGVsbG9SZXF1ZXN0IHx8IGRlbGVnYXRlZFRhc2tFcnIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMuTkVFRF9XUkFQOworICAgICAgICB9CisgICAgICAgIGlmICghZGVsZWdhdGVkVGFza3MuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICByZXR1cm4gU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cy5ORUVEX1RBU0s7CisgICAgICAgIH0KKworICAgICAgICBzd2l0Y2ggKHN0YXR1cykgeworICAgICAgICBjYXNlIEhhbmRzaGFrZVByb3RvY29sLk5FRURfVU5XUkFQOgorICAgICAgICAgICAgcmV0dXJuIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMuTkVFRF9VTldSQVA7CisgICAgICAgIGNhc2UgSGFuZHNoYWtlUHJvdG9jb2wuRklOSVNIRUQ6CisgICAgICAgICAgICBzdGF0dXMgPSBOT1RfSEFORFNIQUtJTkc7CisgICAgICAgICAgICBjbGVhck1lc3NhZ2VzKCk7CisgICAgICAgICAgICByZXR1cm4gU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cy5GSU5JU0hFRDsKKyAgICAgICAgZGVmYXVsdDogLy8gSGFuZHNoYWtlUHJvdG9jb2wuTk9UX0hBTkRTSEFLSU5HOgorICAgICAgICAgICAgcmV0dXJuIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMuTk9UX0hBTkRTSEFLSU5HOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBwZW5kaW5nIHNlc3Npb24KKyAgICAgKiBAcmV0dXJuIHNlc3Npb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU1NMU2Vzc2lvbkltcGwgZ2V0U2Vzc2lvbigpIHsKKyAgICAgICAgcmV0dXJuIHNlc3Npb247CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2VuZENoYW5nZUNpcGhlclNwZWMoKSB7CisgICAgICAgIG5lZWRTZW5kQ0NTcGVjID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZW5kSGVsbG9SZXF1ZXN0KCkgeworICAgICAgICBuZWVkU2VuZEhlbGxvUmVxdWVzdCA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2VzZXMgaW5ib3VuZCBDaGFuZ2VDaXBoZXJTcGVjIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBhYnN0cmFjdCB2b2lkIHJlY2VpdmVDaGFuZ2VDaXBoZXJTcGVjKCk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuZCBzZW5kcyBmaW5pc2hlZCBtZXNzYWdlCisgICAgICovCisgICAgYWJzdHJhY3Qgdm9pZCBtYWtlRmluaXNoZWQoKTsKKworICAgIC8qKgorICAgICAqIFByb2Nlc2VzIGluYm91bmQgaGFuZHNoYWtlIG1lc3NhZ2VzCisgICAgICogQHBhcmFtIGJ5dGVzCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgdW53cmFwKGJ5dGVbXSBieXRlcyk7CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgU1NMdjIgSGVsbG8gbWVzc2FnZQorICAgICAqIEBwYXJhbSBieXRlcworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHVud3JhcFNTTHYyKGJ5dGVbXSBieXRlcyk7CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNlcyBvdXRib3VuZCBoYW5kc2hha2UgbWVzc2FnZXMKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSB3cmFwKCkgeworICAgICAgICBpZiAoZGVsZWdhdGVkVGFza0VyciAhPSBudWxsKSB7CisgICAgICAgICAgICAvLyBwcm9jZXNzIGVycm9yIG9jY3VyZWQgaW4gZGVsZWdhdGVkIHRhc2sKKyAgICAgICAgICAgIEV4Y2VwdGlvbiBlID0gZGVsZWdhdGVkVGFza0VycjsKKyAgICAgICAgICAgIGRlbGVnYXRlZFRhc2tFcnIgPSBudWxsOworICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLkhBTkRTSEFLRV9GQUlMVVJFLAorICAgICAgICAgICAgICAgICAgICAiRXJyb3Igb2NjdXJlZCBpbiBkZWxlZ2F0ZWQgdGFzazoiICsgZS5nZXRNZXNzYWdlKCksIGUpOworICAgICAgICB9CisgICAgICAgIGlmIChpb19zdHJlYW0uaGFzRGF0YSgpKSB7CisgICAgICAgICAgICByZXR1cm4gcmVjb3JkUHJvdG9jb2wud3JhcChDb250ZW50VHlwZS5IQU5EU0hBS0UsIGlvX3N0cmVhbSk7CisgICAgICAgIH0gZWxzZSBpZiAobmVlZFNlbmRDQ1NwZWMpIHsKKyAgICAgICAgICAgIG1ha2VGaW5pc2hlZCgpOworICAgICAgICAgICAgbmVlZFNlbmRDQ1NwZWMgPSBmYWxzZTsKKyAgICAgICAgICAgIHJldHVybiByZWNvcmRQcm90b2NvbC5nZXRDaGFuZ2VDaXBoZXJTcGVjTWVzYWdlKGdldFNlc3Npb24oKSk7CisgICAgICAgIH0gZWxzZSBpZiAobmVlZFNlbmRIZWxsb1JlcXVlc3QpIHsKKyAgICAgICAgICAgIG5lZWRTZW5kSGVsbG9SZXF1ZXN0ID0gZmFsc2U7CisgICAgICAgICAgICByZXR1cm4gcmVjb3JkUHJvdG9jb2wud3JhcChDb250ZW50VHlwZS5IQU5EU0hBS0UsCisgICAgICAgICAgICAgICAgICAgIC8vIGhlbGxvIHJlcXVlc3QgbWVzc2FnZQorICAgICAgICAgICAgICAgICAgICAvLyAoc2VlIFRMUyB2IDEgc3BlY2lmaWNhdGlvbjoKKyAgICAgICAgICAgICAgICAgICAgLy8gaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI0Ni50eHQpCisgICAgICAgICAgICAgICAgICAgIG5ldyBieXRlW10gezAsIDAsIDAsIDB9LCAwLCA0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOyAvLyBub3RoaW5nIHRvIHNlbmQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kcyBmYXRhbCBhbGVydCwgYnJlYWtzIGV4ZWN1dGlvbgorICAgICAqCisgICAgICogQHBhcmFtIGRlc2NyaXB0aW9uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2VuZFdhcm5pbmdBbGVydChieXRlIGRlc2NyaXB0aW9uKSB7CisgICAgICAgIHJlY29yZFByb3RvY29sLmFsZXJ0KEFsZXJ0UHJvdG9jb2wuV0FSTklORywgZGVzY3JpcHRpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmRzIGZhdGFsIGFsZXJ0LCBicmVha3MgZXhlY3V0aW9uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGVzY3JpcHRpb24KKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgZmF0YWxBbGVydChieXRlIGRlc2NyaXB0aW9uLCBTdHJpbmcgcmVhc29uKSB7CisgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbihkZXNjcmlwdGlvbiwgbmV3IFNTTEhhbmRzaGFrZUV4Y2VwdGlvbihyZWFzb24pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kcyBmYXRhbCBhbGVydCwgYnJlYWtzIGV4ZWN1dGlvbgorICAgICAqCisgICAgICogQHBhcmFtIGRlc2NyaXB0aW9uCisgICAgICogQHBhcmFtIHJlYXNvbgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGZhdGFsQWxlcnQoYnl0ZSBkZXNjcmlwdGlvbiwgU3RyaW5nIHJlYXNvbiwgRXhjZXB0aW9uIGNhdXNlKSB7CisgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbihkZXNjcmlwdGlvbiwgbmV3IFNTTEV4Y2VwdGlvbihyZWFzb24sIGNhdXNlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZHMgZmF0YWwgYWxlcnQsIGJyZWFrcyBleGVjdXRpb24KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZXNjcmlwdGlvbgorICAgICAqIEBwYXJhbSBjYXVzZQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGZhdGFsQWxlcnQoYnl0ZSBkZXNjcmlwdGlvbiwgU1NMRXhjZXB0aW9uIGNhdXNlKSB7CisgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbihkZXNjcmlwdGlvbiwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGVycyByZWZlcmVuY2UgVExTIHZlcmlmeV9kYXRhIHRoYXQgaXMgdXNlZCB0byB2ZXJpZnkgZmluaXNoZWQgbWVzc2FnZQorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI0Ni50eHQiPlRMUyBzcGVjLiA3LjQuOS4gRmluaXNoZWQ8L2E+CisgICAgICogQHBhcmFtIGxhYmVsCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgY29tcHV0ZXJSZWZlcmVuY2VWZXJpZnlEYXRhVExTKFN0cmluZyBsYWJlbCkgeworICAgICAgICBjb21wdXRlclZlcmlmeURhdGFUTFMobGFiZWwsIHZlcmlmeV9kYXRhKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlciBUTFMgdmVyaWZ5X2RhdGEKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyNDYudHh0Ij5UTFMgc3BlYy4gNy40LjkuIEZpbmlzaGVkPC9hPgorICAgICAqIEBwYXJhbSBsYWJlbAorICAgICAqIEBwYXJhbSBidWYKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBjb21wdXRlclZlcmlmeURhdGFUTFMoU3RyaW5nIGxhYmVsLCBieXRlW10gYnVmKSB7CisgICAgICAgIGJ5dGVbXSBtZDVfZGlnZXN0ID0gaW9fc3RyZWFtLmdldERpZ2VzdE1ENSgpOworICAgICAgICBieXRlW10gc2hhX2RpZ2VzdCA9IGlvX3N0cmVhbS5nZXREaWdlc3RTSEEoKTsKKworICAgICAgICBieXRlW10gZGlnZXN0ID0gbmV3IGJ5dGVbbWQ1X2RpZ2VzdC5sZW5ndGggKyBzaGFfZGlnZXN0Lmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobWQ1X2RpZ2VzdCwgMCwgZGlnZXN0LCAwLCBtZDVfZGlnZXN0Lmxlbmd0aCk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2hhX2RpZ2VzdCwgMCwgZGlnZXN0LCBtZDVfZGlnZXN0Lmxlbmd0aCwKKyAgICAgICAgICAgICAgICBzaGFfZGlnZXN0Lmxlbmd0aCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQUkYuY29tcHV0ZVBSRihidWYsIHNlc3Npb24ubWFzdGVyX3NlY3JldCwKKyAgICAgICAgICAgICAgICAgICAgbGFiZWwuZ2V0Qnl0ZXMoKSwgZGlnZXN0KTsKKyAgICAgICAgfSBjYXRjaCAoR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5JTlRFUk5BTF9FUlJPUiwgIlBSRiBlcnJvciIsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZXIgcmVmZXJlbmNlIFNTTHYzIHZlcmlmeV9kYXRhIHRoYXQgaXMgdXNlZCB0byB2ZXJpZnkgZmluaXNoZWQgbWVzc2FnZQorICAgICAqIEBzZWUgIlNTTHYzIHNwZWMuIDcuNi45LiBGaW5pc2hlZCIKKyAgICAgKiBAcGFyYW0gbGFiZWwKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBjb21wdXRlclJlZmVyZW5jZVZlcmlmeURhdGFTU0x2MyhieXRlW10gc2VuZGVyKSB7CisgICAgICAgIHZlcmlmeV9kYXRhID0gbmV3IGJ5dGVbMzZdOworICAgICAgICBjb21wdXRlclZlcmlmeURhdGFTU0x2MyhzZW5kZXIsIHZlcmlmeV9kYXRhKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlciBTU0x2MyB2ZXJpZnlfZGF0YQorICAgICAqIEBzZWUgIlNTTHYzIHNwZWMuIDcuNi45LiBGaW5pc2hlZCIKKyAgICAgKiBAcGFyYW0gbGFiZWwKKyAgICAgKiBAcGFyYW0gYnVmCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgY29tcHV0ZXJWZXJpZnlEYXRhU1NMdjMoYnl0ZVtdIHNlbmRlciwgYnl0ZVtdIGJ1ZikgeworICAgICAgICBNZXNzYWdlRGlnZXN0IG1kNTsKKyAgICAgICAgTWVzc2FnZURpZ2VzdCBzaGE7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtZDUgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJNRDUiKTsKKyAgICAgICAgICAgIHNoYSA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoIlNIQS0xIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuSU5URVJOQUxfRVJST1IsCisgICAgICAgICAgICAgICAgICAgICAgICJDb3VsZCBub3QgaW5pdGlhbGl6ZSB0aGUgRGlnZXN0IEFsZ29yaXRobXMuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgZSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ5dGVbXSBoYW5kc2hha2VfbWVzc2FnZXMgPSBpb19zdHJlYW0uZ2V0TWVzc2FnZXMoKTsKKyAgICAgICAgICAgIG1kNS51cGRhdGUoaGFuZHNoYWtlX21lc3NhZ2VzKTsKKyAgICAgICAgICAgIG1kNS51cGRhdGUoc2VuZGVyKTsKKyAgICAgICAgICAgIG1kNS51cGRhdGUoc2Vzc2lvbi5tYXN0ZXJfc2VjcmV0KTsKKyAgICAgICAgICAgIGJ5dGVbXSBiID0gbWQ1LmRpZ2VzdChTU0x2M0NvbnN0YW50cy5NRDVwYWQxKTsKKyAgICAgICAgICAgIG1kNS51cGRhdGUoc2Vzc2lvbi5tYXN0ZXJfc2VjcmV0KTsKKyAgICAgICAgICAgIG1kNS51cGRhdGUoU1NMdjNDb25zdGFudHMuTUQ1cGFkMik7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1kNS5kaWdlc3QoYiksIDAsIGJ1ZiwgMCwgMTYpOworCisgICAgICAgICAgICBzaGEudXBkYXRlKGhhbmRzaGFrZV9tZXNzYWdlcyk7CisgICAgICAgICAgICBzaGEudXBkYXRlKHNlbmRlcik7CisgICAgICAgICAgICBzaGEudXBkYXRlKHNlc3Npb24ubWFzdGVyX3NlY3JldCk7CisgICAgICAgICAgICBiID0gc2hhLmRpZ2VzdChTU0x2M0NvbnN0YW50cy5TSEFwYWQxKTsKKyAgICAgICAgICAgIHNoYS51cGRhdGUoc2Vzc2lvbi5tYXN0ZXJfc2VjcmV0KTsKKyAgICAgICAgICAgIHNoYS51cGRhdGUoU1NMdjNDb25zdGFudHMuU0hBcGFkMik7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHNoYS5kaWdlc3QoYiksIDAsIGJ1ZiwgMTYsIDIwKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5JTlRFUk5BTF9FUlJPUiwgIklOVEVSTkFMIEVSUk9SIiwgZSk7CisKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFZlcmlmaWVzIGZpbmlzaGVkIGRhdGEKKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXRhCisgICAgICogQHBhcmFtIGlzU2VydmVyCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdmVyaWZ5RmluaXNoZWQoYnl0ZVtdIGRhdGEpIHsKKyAgICAgICAgaWYgKCFBcnJheXMuZXF1YWxzKHZlcmlmeV9kYXRhLCBkYXRhKSkgeworICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLkhBTkRTSEFLRV9GQUlMVVJFLCAiSW5jb3JyZWN0IEZJTklTRUQiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmRzIGZhdGFsIGFsZXJ0ICJVTkVYUEVDVEVEIE1FU1NBR0UiCisgICAgICoKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB1bmV4cGVjdGVkTWVzc2FnZSgpIHsKKyAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLlVORVhQRUNURURfTUVTU0FHRSwgIlVORVhQRUNURUQgTUVTU0FHRSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyBtZXNzYWdlIHRvIEhhbmRzaGFrZUlPRGF0YVN0cmVhbQorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZW5kKE1lc3NhZ2UgbWVzc2FnZSkgeworICAgICAgICBpb19zdHJlYW0ud3JpdGVVaW50OChtZXNzYWdlLmdldFR5cGUoKSk7CisgICAgICAgIGlvX3N0cmVhbS53cml0ZVVpbnQyNChtZXNzYWdlLmxlbmd0aCgpKTsKKyAgICAgICAgbWVzc2FnZS5zZW5kKGlvX3N0cmVhbSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZXJzIG1hc3RlciBzZWNyZXQKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNvbXB1dGVyTWFzdGVyU2VjcmV0KCkgeworICAgICAgICBieXRlW10gc2VlZCA9IG5ldyBieXRlWzY0XTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShjbGllbnRIZWxsby5nZXRSYW5kb20oKSwgMCwgc2VlZCwgMCwgMzIpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHNlcnZlckhlbGxvLmdldFJhbmRvbSgpLCAwLCBzZWVkLCAzMiwgMzIpOworICAgICAgICBzZXNzaW9uLm1hc3Rlcl9zZWNyZXQgPSBuZXcgYnl0ZVs0OF07CisgICAgICAgIGlmIChzZXJ2ZXJIZWxsby5zZXJ2ZXJfdmVyc2lvblsxXSA9PSAxKSB7IC8vIFRMU3YxCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFBSRi5jb21wdXRlUFJGKHNlc3Npb24ubWFzdGVyX3NlY3JldCwgcHJlTWFzdGVyU2VjcmV0LAorICAgICAgICAgICAgICAgICAgICAgICAgbWFzdGVyX3NlY3JldF9ieXRlcywgc2VlZCk7CisgICAgICAgICAgICB9IGNhdGNoIChHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5JTlRFUk5BTF9FUlJPUiwgIlBSRiBlcnJvciIsIGUpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeyAvLyBTU0wzLjAKKyAgICAgICAgICAgIFBSRi5jb21wdXRlUFJGX1NTTHYzKHNlc3Npb24ubWFzdGVyX3NlY3JldCwgcHJlTWFzdGVyU2VjcmV0LCBzZWVkKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vZGVsZXRlIHByZU1hc3RlclNlY3JldCBmcm9tIG1lbW9yeQorICAgICAgICBBcnJheXMuZmlsbChwcmVNYXN0ZXJTZWNyZXQsIChieXRlKTApOworICAgICAgICBwcmVNYXN0ZXJTZWNyZXQgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBkZWxlZ2F0ZWQgdGFzay4KKyAgICAgKiBAcmV0dXJuIERlbGVnYXRlZCB0YXNrIG9yIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgUnVubmFibGUgZ2V0VGFzaygpIHsKKyAgICAgICAgaWYgKGRlbGVnYXRlZFRhc2tzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlZFRhc2tzLnJlbW92ZSgwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbGVhcnMgcHJldmlvdXNseSBzZW50IGFuZCByZWNlaXZlZCBoYW5kc2hha2UgbWVzc2FnZXMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBjbGVhck1lc3NhZ2VzKCkgeworICAgICAgICBpb19zdHJlYW0uY2xlYXJCdWZmZXIoKTsKKyAgICAgICAgY2xpZW50SGVsbG8gPSBudWxsOworICAgICAgICBzZXJ2ZXJIZWxsbyA9IG51bGw7CisgICAgICAgIHNlcnZlckNlcnQgPSBudWxsOworICAgICAgICBzZXJ2ZXJLZXlFeGNoYW5nZSA9IG51bGw7CisgICAgICAgIGNlcnRpZmljYXRlUmVxdWVzdCA9IG51bGw7CisgICAgICAgIHNlcnZlckhlbGxvRG9uZSA9IG51bGw7CisgICAgICAgIGNsaWVudENlcnQgPSBudWxsOworICAgICAgICBjbGllbnRLZXlFeGNoYW5nZSA9IG51bGw7CisgICAgICAgIGNlcnRpZmljYXRlVmVyaWZ5ID0gbnVsbDsKKyAgICAgICAgY2xpZW50RmluaXNoZWQgPSBudWxsOworICAgICAgICBzZXJ2ZXJGaW5pc2hlZCA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBSU0Ega2V5IGxlbmd0aAorICAgICAqIEBwYXJhbSBwaworICAgICAqIEByZXR1cm4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGludCBnZXRSU0FLZXlMZW5ndGgoUHVibGljS2V5IHBrKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgSW52YWxpZEtleVNwZWNFeGNlcHRpb24geworCisgICAgICAgIEJpZ0ludGVnZXIgbW9kOworICAgICAgICBpZiAocGsgaW5zdGFuY2VvZiBSU0FLZXkpIHsKKyAgICAgICAgICAgIG1vZCA9ICgoUlNBS2V5KSBwaykuZ2V0TW9kdWx1cygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgS2V5RmFjdG9yeSBrZiA9IEtleUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlJTQSIpOworICAgICAgICAgICAgbW9kID0ga2YuZ2V0S2V5U3BlYyhwaywgUlNBUHVibGljS2V5U3BlYy5jbGFzcykKKyAgICAgICAgICAgICAgICAgICAgLmdldE1vZHVsdXMoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbW9kLmJpdExlbmd0aCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNodXRzIGRvd24gdGhlIHByb3RvY29sLiBJdCB3aWxsIGJlIGltcG9zc2libGUgdG8gdXNlIHRoZSBpbnN0YW5jZQorICAgICAqIGFmdGVyIGNhbGxpbmcgdGhpcyBtZXRob2QuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2h1dGRvd24oKSB7CisgICAgICAgIGNsZWFyTWVzc2FnZXMoKTsKKyAgICAgICAgc2Vzc2lvbiA9IG51bGw7CisgICAgICAgIHByZU1hc3RlclNlY3JldCA9IG51bGw7CisgICAgICAgIGRlbGVnYXRlZFRhc2tzLmNsZWFyKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvSGVsbG9SZXF1ZXN0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9IZWxsb1JlcXVlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42OWMxNDZjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvSGVsbG9SZXF1ZXN0LmphdmEKQEAgLTAsMCArMSw3MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKgorICogUmVwcmVzZW50cyBIZWxsbyBSZXF1ZXN0IG1lc3NhZ2UKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI0Ni50eHQiPlRMUyAxLjAgc3BlYy4sIDcuNC4xLjEuCisgKiBIZWxsbyByZXF1ZXN0PC9hPgorICoKKyAqLworcHVibGljIGNsYXNzIEhlbGxvUmVxdWVzdCBleHRlbmRzIE1lc3NhZ2UgeworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBvdXRib3VuZCBtZXNzYWdlCisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgSGVsbG9SZXF1ZXN0KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgaW5ib3VuZCBtZXNzYWdlCisgICAgICogQHBhcmFtIGluCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgSGVsbG9SZXF1ZXN0KEhhbmRzaGFrZUlPRGF0YVN0cmVhbSBpbiwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChsZW5ndGggIT0gMCkgeworICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLkRFQ09ERV9FUlJPUiwgIkRFQ09ERSBFUlJPUjogaW5jb3JyZWN0IEhlbGxvUmVxdWVzdCIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZHMgbWVzc2FnZQorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZW5kKEhhbmRzaGFrZUlPRGF0YVN0cmVhbSBvdXQpIHsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGxlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBtZXNzYWdlIHR5cGUKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRUeXBlKCkgeworICAgICAgICByZXR1cm4gSGFuZHNoYWtlLkhFTExPX1JFUVVFU1Q7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9KU1NFUHJvdmlkZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0pTU0VQcm92aWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ5Yjc2NTkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9KU1NFUHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDExOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKKworLyoqCisgKiBKU1NFIFByb3ZpZGVyIGltcGxlbWVudGF0aW9uLgorICoKKyAqIFRoaXMgaW1wbGVtZW50YXRpb24gaXMgYmFzZWQgb24gVExTIHYgMS4wIGFuZCBTU0wgdjMgcHJvdG9jb2wgc3BlY2lmaWNhdGlvbnMuCisgKgorICogPHVsPgorICogPGxpPjxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyNDYudHh0Ij5UTFMgdiAxLjAgUHJvdG9jb2wKKyAqIHNwZWNpZmljYXRpb248L2E+PC9saT4KKyAqIDxsaT48YSBocmVmPSJodHRwOi8vd3AubmV0c2NhcGUuY29tL2VuZy9zc2wzIj5TU0wgdjMgUHJvdG9jb2wKKyAqIHNwZWNpZmljYXRpb248L2E+PC9saT4KKyAqIDwvdWw+CisgKgorICogUHJvdmlkZXIgaW1wbGVtZW50YXRpb24gc3VwcG9ydHMgdGhlIGZvbGxvd2luZyAgY2lwaGVyIHN1aXRlczoKKyAqICAgICBUTFNfTlVMTF9XSVRIX05VTExfTlVMTAorICogICAgIFRMU19SU0FfV0lUSF9OVUxMX01ENQorICogICAgIFRMU19SU0FfV0lUSF9OVUxMX1NIQQorICogICAgIFRMU19SU0FfRVhQT1JUX1dJVEhfUkM0XzQwX01ENQorICogICAgIFRMU19SU0FfV0lUSF9SQzRfMTI4X01ENQorICogICAgIFRMU19SU0FfV0lUSF9SQzRfMTI4X1NIQQorICogICAgIFRMU19SU0FfRVhQT1JUX1dJVEhfUkMyX0NCQ180MF9NRDUKKyAqICAgICBUTFNfUlNBX1dJVEhfSURFQV9DQkNfU0hBCisgKiAgICAgVExTX1JTQV9FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBCisgKiAgICAgVExTX1JTQV9XSVRIX0RFU19DQkNfU0hBCisgKiAgICAgVExTX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEKKyAqICAgICBUTFNfREhfRFNTX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEKKyAqICAgICBUTFNfREhfRFNTX1dJVEhfREVTX0NCQ19TSEEKKyAqICAgICBUTFNfREhfRFNTX1dJVEhfM0RFU19FREVfQ0JDX1NIQQorICogICAgIFRMU19ESF9SU0FfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQQorICogICAgIFRMU19ESF9SU0FfV0lUSF9ERVNfQ0JDX1NIQQorICogICAgIFRMU19ESF9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBCisgKiAgICAgVExTX0RIRV9EU1NfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQQorICogICAgIFRMU19ESEVfRFNTX1dJVEhfREVTX0NCQ19TSEEKKyAqICAgICBUTFNfREhFX0RTU19XSVRIXzNERVNfRURFX0NCQ19TSEEKKyAqICAgICBUTFNfREhFX1JTQV9FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBCisgKiAgICAgVExTX0RIRV9SU0FfV0lUSF9ERVNfQ0JDX1NIQQorICogICAgIFRMU19ESEVfUlNBX1dJVEhfM0RFU19FREVfQ0JDX1NIQQorICogICAgIFRMU19ESF9hbm9uX0VYUE9SVF9XSVRIX1JDNF80MF9NRDUKKyAqICAgICBUTFNfREhfYW5vbl9XSVRIX1JDNF8xMjhfTUQ1CisgKiAgICAgVExTX0RIX2Fub25fRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQQorICogICAgIFRMU19ESF9hbm9uX1dJVEhfREVTX0NCQ19TSEEKKyAqICAgICBUTFNfREhfYW5vbl9XSVRIXzNERVNfRURFX0NCQ19TSEEKKyAqCisgKiBUaGUgcmVhbCBzZXQgb2YgYXZhaWxhYmxlIGNpcGhlciBzdWl0ZXMgZGVwZW5kcyBvbiBzZXQgb2YgYXZhaWxhYmxlCisgKiBjcnlwdG8gYWxnb3JpdGhtcy4gVGhlc2UgYWxnb3JpdGhtcyBtdXN0IGJlIHByb3ZpZGVkIGJ5IHNvbWUgY3J5cHRvCisgKiBwcm92aWRlci4KKyAqCisgKiBUaGUgZm9sbG93aW5nIGNpcGhlciBhbGdvcml0aG1zIGFyZSB1c2VkIGJ5IGRpZmZlcmVudCBjaXBoZXIgc3VpdGVzOgorICogICAgIElERUEvQ0JDL05vUGFkZGluZworICogICAgIFJDMi9DQkMvTm9QYWRkaW5nCisgKiAgICAgUkM0CisgKiAgICAgREVTL0NCQy9Ob1BhZGRpbmcKKyAqICAgICBERVMvQ0JDL05vUGFkZGluZworICogICAgIERFU2VkZS9DQkMvTm9QYWRkaW5nCisgKgorICogQWxzbyB0aGUgY3VycmVudCBKU1NFIHByb3ZpZGVyIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlIGZvbGxvd2luZworICogY3J5cHRvIGFsZ29yaXRobXM6CisgKgorICogQWxnb3JpdGhtcyB0aGF0IE1VU1QgYmUgcHJvdmlkZWQgYnkgY3J5cHRvIHByb3ZpZGVyOgorICogICAgIE1hYyAgICBIbWFjTUQ1CisgKiAgICAgTWFjICAgIEhtYWNTSEExCisgKiAgICAgTWVzc2FnZURpZ2VzdCAgICBNRDUKKyAqICAgICBNZXNzYWdlRGlnZXN0ICAgIFNIQS0xCisgKiAgICAgQ2VydGlmaWNhdGVGYWN0b3J5ICAgIFg1MDkKKyAqCisgKiBUaGUgY2lwaGVyIHN1aXRlcyB3aXRoIFJTQSBrZXkgZXhjaGFuZ2UgbWF5IGFsc28gcmVxdWlyZToKKyAqICAgICBDaXBoZXIgICAgUlNBCisgKiAgICAgS2V5UGFpckdlbmVyYXRvciAgICBSU0EKKyAqICAgICBLZXlGYWN0b3J5ICAgIFJTQQorICoKKyAqIFRoZSBjaXBoZXIgc3VpdGVzIHdpdGggREgga2V5IGV4Y2hhbmdlIG1heSBhbHNvIHJlcXVpcmU6CisgKiAgICAgU2lnbmF0dXJlICAgIE5PTkV3aXRoRFNBCisgKiAgICAgS2V5UGFpckdlbmVyYXRvciAgICBEaWZmaWVIZWxsbWFuIG9yIERICisgKiAgICAgS2V5RmFjdG9yeSAgICBEaWZmaWVIZWxsbWFuIG9yIERICisgKiAgICAgS2V5QWdyZWVtZW50ICAgIERpZmZpZUhlbGxtYW4gb3IgREgKKyAqICAgICBLZXlQYWlyR2VuZXJhdG9yICAgIERpZmZpZUhlbGxtYW4gb3IgREgKKyAqCisgKiBUcnVzdCBtYW5hZ2VyIGltcGxlbWVudGF0aW9uIHJlcXVpcmVzOgorICogICAgIENlcnRQYXRoVmFsaWRhdG9yICAgIFBLSVgKKyAqICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgICAgWDUwOQorICoKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEpTU0VQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDMwNzU2ODYwOTIyNjA2Njk2NzVMOworCisgICAgcHVibGljIEpTU0VQcm92aWRlcigpIHsKKyAgICAgICAgc3VwZXIoIkhhcm1vbnlKU1NFIiwgMS4wLCAiSGFybW9ueSBKU1NFIFByb3ZpZGVyIik7CisKKyAgICAgICAgcHV0KCJTU0xDb250ZXh0LlNTTCIsIFNTTENvbnRleHRJbXBsLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIHB1dCgiU1NMQ29udGV4dC5TU0x2MyIsIFNTTENvbnRleHRJbXBsLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIHB1dCgiU1NMQ29udGV4dC5UTFMiLCBTU0xDb250ZXh0SW1wbC5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwdXQoIlNTTENvbnRleHQuVExTdjEiLCBTU0xDb250ZXh0SW1wbC5jbGFzcy5nZXROYW1lKCkpOworCisgICAgICAgIHB1dCgiS2V5TWFuYWdlckZhY3RvcnkuWDUwOSIsIEtleU1hbmFnZXJGYWN0b3J5SW1wbC5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwdXQoIlRydXN0TWFuYWdlckZhY3RvcnkuWDUwOSIsIFRydXN0TWFuYWdlckZhY3RvcnlJbXBsLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIHB1dCgiS2V5U3RvcmUuQW5kcm9pZENBU3RvcmUiLCBUcnVzdGVkQ2VydGlmaWNhdGVLZXlTdG9yZVNwaS5jbGFzcy5nZXROYW1lKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0tleU1hbmFnZXJGYWN0b3J5SW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvS2V5TWFuYWdlckZhY3RvcnlJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjYxZjNjNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0tleU1hbmFnZXJGYWN0b3J5SW1wbC5qYXZhCkBAIC0wLDAgKzEsMTE4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleU1hbmFnZXJGYWN0b3J5U3BpOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzOworaW1wb3J0IGxpYmNvcmUudXRpbC5FbXB0eUFycmF5OworCisvKioKKyAqIEtleU1hbmFnZXJGYWN0b3J5IGltcGxlbWVudGF0aW9uLgorICogQHNlZSBqYXZheC5uZXQuc3NsLktleU1hbmFnZXJGYWN0b3J5U3BpCisgKi8KK3B1YmxpYyBjbGFzcyBLZXlNYW5hZ2VyRmFjdG9yeUltcGwgZXh0ZW5kcyBLZXlNYW5hZ2VyRmFjdG9yeVNwaSB7CisKKyAgICAvLyBzb3VyY2Ugb2Yga2V5IG1hdGVyaWFsCisgICAgcHJpdmF0ZSBLZXlTdG9yZSBrZXlTdG9yZTsKKworICAgIC8vcGFzc3dvcmQKKyAgICBwcml2YXRlIGNoYXJbXSBwd2Q7CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlckZhY3RvcnlTcGkjZW5naW5lSW5pdChLZXlTdG9yZSBrcywgY2hhcltdCisgICAgICogICAgICBwYXNzd29yZCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVJbml0KEtleVN0b3JlIGtzLCBjaGFyW10gcGFzc3dvcmQpCisgICAgICAgICAgICB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24geworICAgICAgICBpZiAoa3MgIT0gbnVsbCkgeworICAgICAgICAgICAga2V5U3RvcmUgPSBrczsKKyAgICAgICAgICAgIGlmIChwYXNzd29yZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcHdkID0gcGFzc3dvcmQuY2xvbmUoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcHdkID0gRW1wdHlBcnJheS5DSEFSOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAga2V5U3RvcmUgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAgICAgIFN0cmluZyBrZXlTdG9yZU5hbWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmF4Lm5ldC5zc2wua2V5U3RvcmUiKTsKKyAgICAgICAgICAgIFN0cmluZyBrZXlTdG9yZVB3ZCA9IG51bGw7CisgICAgICAgICAgICBpZiAoa2V5U3RvcmVOYW1lID09IG51bGwgfHwga2V5U3RvcmVOYW1lLmVxdWFsc0lnbm9yZUNhc2UoIk5PTkUiKSB8fCBrZXlTdG9yZU5hbWUuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBLZXlTdG9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBLZXlTdG9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGtleVN0b3JlUHdkID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZheC5uZXQuc3NsLmtleVN0b3JlUGFzc3dvcmQiKTsKKyAgICAgICAgICAgICAgICBpZiAoa2V5U3RvcmVQd2QgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBwd2QgPSBFbXB0eUFycmF5LkNIQVI7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcHdkID0ga2V5U3RvcmVQd2QudG9DaGFyQXJyYXkoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUubG9hZChuZXcgRmlsZUlucHV0U3RyZWFtKG5ldyBGaWxlKGtleVN0b3JlTmFtZSkpLCBwd2QpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBLZXlTdG9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBLZXlTdG9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBLZXlTdG9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLktleU1hbmFnZXJGYWN0b3J5U3BpI2VuZ2luZUluaXQoTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzCisgICAgICogICAgICBzcGVjKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGVuZ2luZUluaXQoTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzIHNwZWMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMgbm90IHN1cHBvcnRlZCIpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLktleU1hbmFnZXJGYWN0b3J5U3BpI2VuZ2luZUdldEtleU1hbmFnZXJzKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgS2V5TWFuYWdlcltdIGVuZ2luZUdldEtleU1hbmFnZXJzKCkgeworICAgICAgICBpZiAoa2V5U3RvcmUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiS2V5TWFuYWdlckZhY3RvcnkgaXMgbm90IGluaXRpYWxpemVkIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBLZXlNYW5hZ2VyW10geyBuZXcgS2V5TWFuYWdlckltcGwoa2V5U3RvcmUsIHB3ZCkgfTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0tleU1hbmFnZXJJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9LZXlNYW5hZ2VySW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjY2Y2ODcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9LZXlNYW5hZ2VySW1wbC5qYXZhCkBAIC0wLDAgKzEsMjE5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5uZXQuU29ja2V0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZS5Qcml2YXRlS2V5RW50cnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5VbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFbmdpbmU7CitpbXBvcnQgamF2YXgubmV0LnNzbC5YNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsOworCisvKioKKyAqIEtleU1hbmFnZXIgaW1wbGVtZW50YXRpb24uCisgKgorICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIGhhc2hlZCBrZXkgc3RvcmUgaW5mb3JtYXRpb24uIEl0IHdvcmtzIGZhc3RlciB0aGFuIHJldHJpZXZpbmcgYWxsIG9mIHRoZQorICogZGF0YSBmcm9tIHRoZSBrZXkgc3RvcmUuIEFueSBrZXkgc3RvcmUgY2hhbmdlcywgdGhhdCBoYXBwZW4gYWZ0ZXIga2V5IG1hbmFnZXIgd2FzIGNyZWF0ZWQsIGhhdmUKKyAqIG5vIGVmZmVjdC4gVGhlIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHVzZSBwZWVyIGluZm9ybWF0aW9uIChob3N0LCBwb3J0KSB0aGF0IG1heSBiZSBvYnRhaW5lZAorICogZnJvbSBzb2NrZXQgb3IgZW5naW5lLgorICoKKyAqIEBzZWUgamF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyCisgKgorICovCitwdWJsaWMgY2xhc3MgS2V5TWFuYWdlckltcGwgZXh0ZW5kcyBYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyIHsKKworICAgIC8vIGhhc2hlZCBrZXkgc3RvcmUgaW5mb3JtYXRpb24KKyAgICBwcml2YXRlIGZpbmFsIEhhc2h0YWJsZTxTdHJpbmcsIFByaXZhdGVLZXlFbnRyeT4gaGFzaDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgS2V5IG1hbmFnZXIKKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXlTdG9yZQorICAgICAqIEBwYXJhbSBwd2QKKyAgICAgKi8KKyAgICBwdWJsaWMgS2V5TWFuYWdlckltcGwoS2V5U3RvcmUga2V5U3RvcmUsIGNoYXJbXSBwd2QpIHsKKyAgICAgICAgdGhpcy5oYXNoID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIFByaXZhdGVLZXlFbnRyeT4oKTsKKyAgICAgICAgZmluYWwgRW51bWVyYXRpb248U3RyaW5nPiBhbGlhc2VzOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWxpYXNlcyA9IGtleVN0b3JlLmFsaWFzZXMoKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGZvciAoOyBhbGlhc2VzLmhhc01vcmVFbGVtZW50cygpOykgeworICAgICAgICAgICAgZmluYWwgU3RyaW5nIGFsaWFzID0gYWxpYXNlcy5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKGFsaWFzLCBLZXlTdG9yZS5Qcml2YXRlS2V5RW50cnkuY2xhc3MpKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSBlbnRyeSA9IChLZXlTdG9yZS5Qcml2YXRlS2V5RW50cnkpIGtleVN0b3JlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEVudHJ5KGFsaWFzLCBuZXcgS2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uKHB3ZCkpOworICAgICAgICAgICAgICAgICAgICBoYXNoLnB1dChhbGlhcywgZW50cnkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBjaG9vc2VDbGllbnRBbGlhcyhTdHJpbmdbXSBrZXlUeXBlcywgUHJpbmNpcGFsW10gaXNzdWVycywgU29ja2V0IHNvY2tldCkgeworICAgICAgICBmaW5hbCBTdHJpbmdbXSBhbCA9IGNob29zZUFsaWFzKGtleVR5cGVzLCBpc3N1ZXJzKTsKKyAgICAgICAgcmV0dXJuIChhbCA9PSBudWxsID8gbnVsbCA6IGFsWzBdKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGNob29zZVNlcnZlckFsaWFzKFN0cmluZyBrZXlUeXBlLCBQcmluY2lwYWxbXSBpc3N1ZXJzLCBTb2NrZXQgc29ja2V0KSB7CisgICAgICAgIGZpbmFsIFN0cmluZ1tdIGFsID0gY2hvb3NlQWxpYXMobmV3IFN0cmluZ1tdIHsga2V5VHlwZSB9LCBpc3N1ZXJzKTsKKyAgICAgICAgcmV0dXJuIChhbCA9PSBudWxsID8gbnVsbCA6IGFsWzBdKTsKKyAgICB9CisKKyAgICBwdWJsaWMgWDUwOUNlcnRpZmljYXRlW10gZ2V0Q2VydGlmaWNhdGVDaGFpbihTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgaWYgKGFsaWFzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGlmIChoYXNoLmNvbnRhaW5zS2V5KGFsaWFzKSkgeworICAgICAgICAgICAgQ2VydGlmaWNhdGVbXSBjZXJ0cyA9IGhhc2guZ2V0KGFsaWFzKS5nZXRDZXJ0aWZpY2F0ZUNoYWluKCk7CisgICAgICAgICAgICBpZiAoY2VydHNbMF0gaW5zdGFuY2VvZiBYNTA5Q2VydGlmaWNhdGUpIHsKKyAgICAgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGVbXSB4Y2VydHMgPSBuZXcgWDUwOUNlcnRpZmljYXRlW2NlcnRzLmxlbmd0aF07CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjZXJ0cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICB4Y2VydHNbaV0gPSAoWDUwOUNlcnRpZmljYXRlKSBjZXJ0c1tpXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHhjZXJ0czsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRDbGllbnRBbGlhc2VzKFN0cmluZyBrZXlUeXBlLCBQcmluY2lwYWxbXSBpc3N1ZXJzKSB7CisgICAgICAgIHJldHVybiBjaG9vc2VBbGlhcyhuZXcgU3RyaW5nW10geyBrZXlUeXBlIH0sIGlzc3VlcnMpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRTZXJ2ZXJBbGlhc2VzKFN0cmluZyBrZXlUeXBlLCBQcmluY2lwYWxbXSBpc3N1ZXJzKSB7CisgICAgICAgIHJldHVybiBjaG9vc2VBbGlhcyhuZXcgU3RyaW5nW10geyBrZXlUeXBlIH0sIGlzc3VlcnMpOworICAgIH0KKworICAgIHB1YmxpYyBQcml2YXRlS2V5IGdldFByaXZhdGVLZXkoU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIGlmIChhbGlhcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaGFzaC5jb250YWluc0tleShhbGlhcykpIHsKKyAgICAgICAgICAgIHJldHVybiBoYXNoLmdldChhbGlhcykuZ2V0UHJpdmF0ZUtleSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgY2hvb3NlRW5naW5lQ2xpZW50QWxpYXMoU3RyaW5nW10ga2V5VHlwZXMsIFByaW5jaXBhbFtdIGlzc3VlcnMsIFNTTEVuZ2luZSBlbmdpbmUpIHsKKyAgICAgICAgZmluYWwgU3RyaW5nW10gYWwgPSBjaG9vc2VBbGlhcyhrZXlUeXBlcywgaXNzdWVycyk7CisgICAgICAgIHJldHVybiAoYWwgPT0gbnVsbCA/IG51bGwgOiBhbFswXSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBjaG9vc2VFbmdpbmVTZXJ2ZXJBbGlhcyhTdHJpbmcga2V5VHlwZSwgUHJpbmNpcGFsW10gaXNzdWVycywgU1NMRW5naW5lIGVuZ2luZSkgeworICAgICAgICBmaW5hbCBTdHJpbmdbXSBhbCA9IGNob29zZUFsaWFzKG5ldyBTdHJpbmdbXSB7IGtleVR5cGUgfSwgaXNzdWVycyk7CisgICAgICAgIHJldHVybiAoYWwgPT0gbnVsbCA/IG51bGwgOiBhbFswXSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmdbXSBjaG9vc2VBbGlhcyhTdHJpbmdbXSBrZXlUeXBlcywgUHJpbmNpcGFsW10gaXNzdWVycykgeworICAgICAgICBpZiAoa2V5VHlwZXMgPT0gbnVsbCB8fCBrZXlUeXBlcy5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgTGlzdDxQcmluY2lwYWw+IGlzc3VlcnNMaXN0ID0gKGlzc3VlcnMgPT0gbnVsbCkgPyBudWxsIDogQXJyYXlzLmFzTGlzdChpc3N1ZXJzKTsKKyAgICAgICAgQXJyYXlMaXN0PFN0cmluZz4gZm91bmQgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgZm9yIChFbnVtZXJhdGlvbjxTdHJpbmc+IGFsaWFzZXMgPSBoYXNoLmtleXMoKTsgYWxpYXNlcy5oYXNNb3JlRWxlbWVudHMoKTspIHsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBhbGlhcyA9IGFsaWFzZXMubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGZpbmFsIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSBlbnRyeSA9IGhhc2guZ2V0KGFsaWFzKTsKKyAgICAgICAgICAgIGZpbmFsIENlcnRpZmljYXRlW10gY2hhaW4gPSBlbnRyeS5nZXRDZXJ0aWZpY2F0ZUNoYWluKCk7CisgICAgICAgICAgICBmaW5hbCBDZXJ0aWZpY2F0ZSBjZXJ0ID0gY2hhaW5bMF07CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgY2VydEtleUFsZyA9IGNlcnQuZ2V0UHVibGljS2V5KCkuZ2V0QWxnb3JpdGhtKCk7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgY2VydFNpZ0FsZyA9IChjZXJ0IGluc3RhbmNlb2YgWDUwOUNlcnRpZmljYXRlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICgoWDUwOUNlcnRpZmljYXRlKSBjZXJ0KS5nZXRTaWdBbGdOYW1lKCkudG9VcHBlckNhc2UoTG9jYWxlLlVTKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBudWxsKTsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIGtleUFsZ29yaXRobSA6IGtleVR5cGVzKSB7CisgICAgICAgICAgICAgICAgaWYgKGtleUFsZ29yaXRobSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBTdHJpbmcgc2lnQWxnb3JpdGhtOworICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBjYXNlcyBsaWtlIEVDX0VDIGFuZCBFQ19SU0EKKyAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSBrZXlBbGdvcml0aG0uaW5kZXhPZignXycpOworICAgICAgICAgICAgICAgIGlmIChpbmRleCA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICBzaWdBbGdvcml0aG0gPSBrZXlBbGdvcml0aG07CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgc2lnQWxnb3JpdGhtID0ga2V5QWxnb3JpdGhtLnN1YnN0cmluZyhpbmRleCArIDEpOworICAgICAgICAgICAgICAgICAgICBrZXlBbGdvcml0aG0gPSBrZXlBbGdvcml0aG0uc3Vic3RyaW5nKDAsIGluZGV4KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8ga2V5IGFsZ29yaXRobSBkb2VzIG5vdCBtYXRjaAorICAgICAgICAgICAgICAgIGlmICghY2VydEtleUFsZy5lcXVhbHMoa2V5QWxnb3JpdGhtKSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgKiBUT0RPIGZpbmQgYSBtb3JlIHJlbGlhYmxlIHRlc3QgZm9yIHNpZ25hdHVyZQorICAgICAgICAgICAgICAgICAqIGFsZ29yaXRobS4gVW5mb3J0dW5hdGVseSB2YWx1ZSB2YXJpZXMgd2l0aAorICAgICAgICAgICAgICAgICAqIHByb3ZpZGVyLiBGb3IgZXhhbXBsZSBmb3IgIkVDIiBpdCBjb3VsZCBiZQorICAgICAgICAgICAgICAgICAqICJTSEExV2l0aEVDRFNBIiBvciBzaW1wbHkgIkVDRFNBIi4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICAvLyBzaWcgYWxnb3JpdGhtIGRvZXMgbm90IG1hdGNoCisgICAgICAgICAgICAgICAgaWYgKGNlcnRTaWdBbGcgIT0gbnVsbCAmJiAhY2VydFNpZ0FsZy5jb250YWlucyhzaWdBbGdvcml0aG0pKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBubyBpc3N1ZXJzIHRvIG1hdGNoLCBqdXN0IGFkZCB0byByZXR1cm4gbGlzdCBhbmQgY29udGludWUKKyAgICAgICAgICAgICAgICBpZiAoaXNzdWVycyA9PSBudWxsIHx8IGlzc3VlcnMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgZm91bmQuYWRkKGFsaWFzKTsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgYSBjZXJ0aWZpY2F0ZSBpbiB0aGUgY2hhaW4gd2FzIGlzc3VlZCBieSBvbmUgb2YgdGhlIHNwZWNpZmllZCBpc3N1ZXJzCisgICAgICAgICAgICAgICAgbG9vcDogZm9yIChDZXJ0aWZpY2F0ZSBjZXJ0RnJvbUNoYWluIDogY2hhaW4pIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCEoY2VydEZyb21DaGFpbiBpbnN0YW5jZW9mIFg1MDlDZXJ0aWZpY2F0ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNraXAgbm9uLVg1MDlDZXJ0aWZpY2F0ZXMKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSB4Y2VydEZyb21DaGFpbiA9IChYNTA5Q2VydGlmaWNhdGUpIGNlcnRGcm9tQ2hhaW47CisgICAgICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICAgICAqIE5vdGUgdXNlIG9mIFg1MDBQcmluY2lwYWwgZnJvbQorICAgICAgICAgICAgICAgICAgICAgKiBnZXRJc3N1ZXJYNTAwUHJpbmNpcGFsIGFzIG9wcG9zZWQgdG8gUHJpbmNpcGFsCisgICAgICAgICAgICAgICAgICAgICAqIGZyb20gZ2V0SXNzdWVyRE4uIFByaW5jaXBhbC5lcXVhbHMgdGVzdCBkb2VzCisgICAgICAgICAgICAgICAgICAgICAqIG5vdCB3b3JrIGluIHRoZSBjYXNlIHdoZXJlCisgICAgICAgICAgICAgICAgICAgICAqIHhjZXJ0RnJvbUNoYWluLmdldElzc3VlckROIGlzIGEgYm91bmN5Y2FzdGxlCisgICAgICAgICAgICAgICAgICAgICAqIG9yZy5ib3VuY3ljYXN0bGUuamNlLlg1MDlQcmluY2lwYWwuCisgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICBYNTAwUHJpbmNpcGFsIGlzc3VlckZyb21DaGFpbiA9IHhjZXJ0RnJvbUNoYWluLmdldElzc3Vlclg1MDBQcmluY2lwYWwoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGlzc3VlcnNMaXN0LmNvbnRhaW5zKGlzc3VlckZyb21DaGFpbikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kLmFkZChhbGlhcyk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFmb3VuZC5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmb3VuZC50b0FycmF5KG5ldyBTdHJpbmdbZm91bmQuc2l6ZSgpXSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvTG9nZ2VyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9Mb2dnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMjY4OGUyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvTG9nZ2VyLmphdmEKQEAgLTAsMCArMSwxMTAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOworaW1wb3J0IGxpYmNvcmUudXRpbC5FbXB0eUFycmF5OworCisvKioKKyAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgZGVidWcgbG9nZ2luZyBmb3IgSlNTRSBwcm92aWRlciBpbXBsZW1lbnRhdGlvbgorICogVE9ETzogVXNlIGphdmEudXRpbC5sb2dnaW5nCisgKi8KK3B1YmxpYyBjbGFzcyBMb2dnZXIgeworCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBTdHJlYW0gZXh0ZW5kcyBQcmludFN0cmVhbSB7CisgICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHByZWZpeDsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGluZGVudCA9IDA7CisKKyAgICAgICAgcHVibGljIFN0cmVhbShTdHJpbmcgbmFtZSkgeworICAgICAgICAgICAgc3VwZXIoU3lzdGVtLmVycik7CisgICAgICAgICAgICBwcmVmaXggPSBuYW1lICsgIlsiK1RocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0TmFtZSgpKyJdICI7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcHJpbnQoU3RyaW5nIG1zZykgeworICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGluZGVudDsgaSsrKSB7CisgICAgICAgICAgICAgICAgc3VwZXIucHJpbnQoIiAgIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzdXBlci5wcmludChtc2cpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgbmV3SW5kZW50KCkgeworICAgICAgICAgICAgaW5kZW50ICsrOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgZW5kSW5kZW50KCkgeworICAgICAgICAgICAgaW5kZW50IC0tOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHByaW50bG4oU3RyaW5nIG1zZykgeworICAgICAgICAgICAgcHJpbnQocHJlZml4KTsKKyAgICAgICAgICAgIHN1cGVyLnByaW50bG4obXNnKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHByaW50KGJ5dGVbXSBkYXRhKSB7CisgICAgICAgICAgICBwcmludEFzSGV4KDE2LCAiICIsICIiLCBkYXRhLCAwLCBkYXRhLmxlbmd0aCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBwcmludChieXRlW10gZGF0YSwgaW50IG9mZnNldCwgaW50IGxlbikgeworICAgICAgICAgICAgcHJpbnRBc0hleCgxNiwgIiAiLCAiIiwgZGF0YSwgb2Zmc2V0LCBsZW4pOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcHJpbnRBc0hleChpbnQgcGVyTGluZSwgU3RyaW5nIHByZWZpeCwgU3RyaW5nIGRlbGltaXRlciwgYnl0ZVtdIGRhdGEpIHsKKyAgICAgICAgICAgIHByaW50QXNIZXgocGVyTGluZSwgcHJlZml4LCBkZWxpbWl0ZXIsIGRhdGEsIDAsIGRhdGEubGVuZ3RoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHByaW50QXNIZXgoaW50IHBlckxpbmUsIFN0cmluZyBwcmVmaXgsIFN0cmluZyBkZWxpbWl0ZXIsCisgICAgICAgICAgICAgICAgYnl0ZVtdIGRhdGEsIGludCBvZmZzZXQsIGludCBsZW4pIHsKKyAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgbGluZSA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisgICAgICAgICAgICAgICAgbGluZS5hcHBlbmQocHJlZml4KTsKKyAgICAgICAgICAgICAgICBsaW5lLmFwcGVuZChCeXRlLnRvSGV4U3RyaW5nKGRhdGFbaStvZmZzZXRdLCBmYWxzZSkpOworICAgICAgICAgICAgICAgIGxpbmUuYXBwZW5kKGRlbGltaXRlcik7CisKKyAgICAgICAgICAgICAgICBpZiAoKChpKzEpJXBlckxpbmUpID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgc3VwZXIucHJpbnRsbihsaW5lLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgICAgICBsaW5lID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzdXBlci5wcmludGxuKGxpbmUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBuYW1lczsKKworICAgIHN0YXRpYyB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuYW1lcyA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgianNzZSIsICIiKS5zcGxpdCgiLCIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgbmFtZXMgPSBFbXB0eUFycmF5LlNUUklORzsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyZWFtIGdldFN0cmVhbShTdHJpbmcgbmFtZSkgeworICAgICAgICBmb3IgKGludCBpPTA7IGk8bmFtZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChuYW1lc1tpXS5lcXVhbHMobmFtZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmVhbShuYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9NZXNzYWdlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9NZXNzYWdlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmQ5NzEzNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL01lc3NhZ2UuamF2YQpAQCAtMCwwICsxLDcyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEhhbmRzaGFrZUV4Y2VwdGlvbjsKKworLyoqCisgKgorICogQmFzZSBjbGFzcyBmb3IgaGFuZHNoYWtlIG1lc3NhZ2VzCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBNZXNzYWdlIHsKKworICAgIC8qCisgICAgICogTWVzc2FnZSBsZW5ndGgKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGxlbmd0aDsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgbWVzc2FnZSB0eXBlCisgICAgICogQHJldHVybgorICAgICAqLworICAgIGFic3RyYWN0IGludCBnZXRUeXBlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIG1lc3NhZ2UgbGVuZ3RoCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHB1YmxpYyBpbnQgbGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gbGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmRzIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICovCisgICAgYWJzdHJhY3Qgdm9pZCBzZW5kKEhhbmRzaGFrZUlPRGF0YVN0cmVhbSBvdXQpOworCisgICAgLyoqCisgICAgICogU2VuZHMgZmF0YWwgYWxlcnQKKyAgICAgKiBAcGFyYW0gZGVzY3JpcHRpb24KKyAgICAgKiBAcGFyYW0gcmVhc29uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgZmF0YWxBbGVydChieXRlIGRlc2NyaXB0aW9uLCBTdHJpbmcgcmVhc29uKSB7CisgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbihkZXNjcmlwdGlvbiwgbmV3IFNTTEhhbmRzaGFrZUV4Y2VwdGlvbihyZWFzb24pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kcyBmYXRhbCBhbGVydAorICAgICAqIEBwYXJhbSBkZXNjcmlwdGlvbgorICAgICAqIEBwYXJhbSByZWFzb24KKyAgICAgKiBAcGFyYW0gY2F1c2UKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBmYXRhbEFsZXJ0KGJ5dGUgZGVzY3JpcHRpb24sIFN0cmluZyByZWFzb24sIFRocm93YWJsZSBjYXVzZSkgeworICAgICAgICB0aHJvdyBuZXcgQWxlcnRFeGNlcHRpb24oZGVzY3JpcHRpb24sIG5ldyBTU0xFeGNlcHRpb24ocmVhc29uLCBjYXVzZSkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL05hdGl2ZUNyeXB0by5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvTmF0aXZlQ3J5cHRvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWU3NTljMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL05hdGl2ZUNyeXB0by5qYXZhCkBAIC0wLDAgKzEsNjI1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlNvY2tldFRpbWVvdXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZU9yZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLlJTQVB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFeGNlcHRpb247CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CitpbXBvcnQgbGliY29yZS5pby5NZW1vcnk7CisKKy8qKgorICogUHJvdmlkZXMgdGhlIEphdmEgc2lkZSBvZiBvdXIgSk5JIGdsdWUgZm9yIE9wZW5TU0wuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBOYXRpdmVDcnlwdG8geworCisgICAgLy8gLS0tIE9wZW5TU0wgbGlicmFyeSBpbml0aWFsaXphdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIHN0YXRpYyB7CisgICAgICAgIGNsaW5pdCgpOworICAgIH0KKworICAgIHByaXZhdGUgbmF0aXZlIHN0YXRpYyB2b2lkIGNsaW5pdCgpOworCisgICAgLy8gLS0tIERTQS9SU0EgcHVibGljL3ByaXZhdGUga2V5IGhhbmRsaW5nIGZ1bmN0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEVWUF9QS0VZX25ld19EU0EoYnl0ZVtdIHAsIGJ5dGVbXSBxLCBieXRlW10gZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlW10gcHJpdl9rZXksIGJ5dGVbXSBwdWJfa2V5KTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBFVlBfUEtFWV9uZXdfUlNBKGJ5dGVbXSBuLCBieXRlW10gZSwgYnl0ZVtdIGQsIGJ5dGVbXSBwLCBieXRlW10gcSk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEVWUF9QS0VZX2ZyZWUoaW50IHBrZXkpOworCisgICAgLy8gLS0tIE1lc3NhZ2UgZGlnZXN0IGZ1bmN0aW9ucyAtLS0tLS0tLS0tLS0tLQorCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEVWUF9nZXRfZGlnZXN0YnluYW1lKFN0cmluZyBuYW1lKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBFVlBfTURfc2l6ZShpbnQgZXZwX21kKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBFVlBfTURfYmxvY2tfc2l6ZShpbnQgZXZwX21kKTsKKworICAgIC8vIC0tLSBNZXNzYWdlIGRpZ2VzdCBjb250ZXh0IGZ1bmN0aW9ucyAtLS0tLS0tLS0tLS0tLQorCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBFVlBfTURfQ1RYX2Rlc3Ryb3koaW50IGN0eCk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgRVZQX01EX0NUWF9jb3B5KGludCBjdHgpOworCisgICAgLy8gLS0tIERpZ2VzdCBoYW5kbGluZyBmdW5jdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEVWUF9EaWdlc3RJbml0KGludCBldnBfbWQpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBFVlBfRGlnZXN0VXBkYXRlKGludCBjdHgsIGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBsZW5ndGgpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEVWUF9EaWdlc3RGaW5hbChpbnQgY3R4LCBieXRlW10gaGFzaCwgaW50IG9mZnNldCk7CisKKyAgICAvLyAtLS0gU2lnbmF0dXJlIGhhbmRsaW5nIGZ1bmN0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgRVZQX1ZlcmlmeUluaXQoU3RyaW5nIGFsZ29yaXRobSk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEVWUF9WZXJpZnlVcGRhdGUoaW50IGN0eCwgYnl0ZVtdIGJ1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9mZnNldCwgaW50IGxlbmd0aCk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgRVZQX1ZlcmlmeUZpbmFsKGludCBjdHgsIGJ5dGVbXSBzaWduYXR1cmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoLCBpbnQga2V5KTsKKworICAgIC8vIC0tLSBSQU5EIHNlZWRpbmcgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJBTkRfU0VFRF9MRU5HVEhfSU5fQllURVMgPSAxMDI0OworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBSQU5EX3NlZWQoYnl0ZVtdIHNlZWQpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFJBTkRfbG9hZF9maWxlKFN0cmluZyBmaWxlbmFtZSwgbG9uZyBtYXhfYnl0ZXMpOworCisgICAgLy8gLS0tIFg1MDlfTkFNRSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgcHVibGljIHN0YXRpYyBpbnQgWDUwOV9OQU1FX2hhc2goWDUwMFByaW5jaXBhbCBwcmluY2lwYWwpIHsKKyAgICAgICAgcmV0dXJuIFg1MDlfTkFNRV9oYXNoKHByaW5jaXBhbCwgIlNIQTEiKTsKKyAgICB9CisgICAgcHVibGljIHN0YXRpYyBpbnQgWDUwOV9OQU1FX2hhc2hfb2xkKFg1MDBQcmluY2lwYWwgcHJpbmNpcGFsKSB7CisgICAgICAgIHJldHVybiBYNTA5X05BTUVfaGFzaChwcmluY2lwYWwsICJNRDUiKTsKKyAgICB9CisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IFg1MDlfTkFNRV9oYXNoKFg1MDBQcmluY2lwYWwgcHJpbmNpcGFsLCBTdHJpbmcgYWxnb3JpdGhtKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBieXRlW10gZGlnZXN0ID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShhbGdvcml0aG0pLmRpZ2VzdChwcmluY2lwYWwuZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgICAgIHJldHVybiBNZW1vcnkucGVla0ludChkaWdlc3QsIDAsIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIC0tLSBTU0wgaGFuZGxpbmcgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTVVBQT1JURURfUFJPVE9DT0xfU1NMVjMgPSAiU1NMdjMiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTVVBQT1JURURfUFJPVE9DT0xfVExTVjEgPSAiVExTdjEiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IE9QRU5TU0xfVE9fU1RBTkRBUkRfQ0lQSEVSX1NVSVRFUworICAgICAgICAgICAgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gU1RBTkRBUkRfVE9fT1BFTlNTTF9DSVBIRVJfU1VJVEVTCisgICAgICAgICAgICA9IG5ldyBMaW5rZWRIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhZGQoU3RyaW5nIHN0YW5kYXJkLCBTdHJpbmcgb3BlbnNzbCkgeworICAgICAgICBPUEVOU1NMX1RPX1NUQU5EQVJEX0NJUEhFUl9TVUlURVMucHV0KG9wZW5zc2wsIHN0YW5kYXJkKTsKKyAgICAgICAgU1RBTkRBUkRfVE9fT1BFTlNTTF9DSVBIRVJfU1VJVEVTLnB1dChzdGFuZGFyZCwgb3BlbnNzbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVExTX0VNUFRZX1JFTkVHT1RJQVRJT05fSU5GT19TQ1NWIGlzIFJGQyA1NzQ2J3MgcmVuZWdvdGlhdGlvbgorICAgICAqIGluZGljYXRpb24gc2lnbmFsaW5nIGNpcGhlciBzdWl0ZSB2YWx1ZS4gSXQgaXMgbm90IGEgcmVhbAorICAgICAqIGNpcGhlciBzdWl0ZS4gSXQgaXMganVzdCBhbiBpbmRpY2F0aW9uIGluIHRoZSBkZWZhdWx0IGFuZAorICAgICAqIHN1cHBvcnRlZCBjaXBoZXIgc3VpdGUgbGlzdHMgaW5kaWNhdGVzIHRoYXQgdGhlIGltcGxlbWVudGF0aW9uCisgICAgICogc3VwcG9ydHMgc2VjdXJlIHJlbmVnb3RpYXRpb24uCisgICAgICoKKyAgICAgKiBJbiB0aGUgUkksIGl0cyBwcmVzZW5jZSBtZWFucyB0aGF0IHRoZSBTQ1NWIGlzIHNlbnQgaW4gdGhlCisgICAgICogY2lwaGVyIHN1aXRlIGxpc3QgdG8gaW5kaWNhdGUgc2VjdXJlIHJlbmVnb3RpYXRpb24gc3VwcG9ydCBhbmQKKyAgICAgKiBpdHMgYWJzZW5zZSBtZWFucyB0byBzZW5kIGFuIGVtcHR5IFRMUyByZW5lZ290aWF0aW9uIGluZm8KKyAgICAgKiBleHRlbnNpb24gaW5zdGVhZC4KKyAgICAgKgorICAgICAqIEhvd2V2ZXIsIE9wZW5TU0wgZG9lc24ndCBwcm92aWRlIGFuIEFQSSB0byBnaXZlIHRoaXMgbGV2ZWwgb2YKKyAgICAgKiBjb250cm9sLCBpbnN0ZWFkIGFsd2F5cyBzZW5kaW5nIHRoZSBTQ1NWIGFuZCBhbHdheXMgaW5jbHVkaW5nCisgICAgICogdGhlIGVtcHR5IHJlbmVnb3RpYXRpb24gaW5mbyBpZiBUTFMgaXMgdXNlZCAoYXMgb3Bwb3NlZCB0bworICAgICAqIFNTTCkuIFNvIHdlIHNpbXBseSBhbGxvdyBUTFNfRU1QVFlfUkVORUdPVElBVElPTl9JTkZPX1NDU1YgdG8KKyAgICAgKiBiZSBwYXNzZWQgZm9yIGNvbXBhdGliaWxpdHkgYXMgdG8gcHJvdmlkZSB0aGUgaGludCB0aGF0IHdlCisgICAgICogc3VwcG9ydCBzZWN1cmUgcmVuZWdvdGlhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUTFNfRU1QVFlfUkVORUdPVElBVElPTl9JTkZPX1NDU1YKKyAgICAgICAgICAgID0gIlRMU19FTVBUWV9SRU5FR09USUFUSU9OX0lORk9fU0NTViI7CisKKyAgICBzdGF0aWMgeworICAgICAgICAvLyBOb3RlIHRoZXNlIGFyZSBhZGRlZCBpbiBwcmlvcml0eSBvcmRlcgorICAgICAgICBhZGQoIlNTTF9SU0FfV0lUSF9SQzRfMTI4X01ENSIsICAgICAgICAgICAgICAiUkM0LU1ENSIpOworICAgICAgICBhZGQoIlNTTF9SU0FfV0lUSF9SQzRfMTI4X1NIQSIsICAgICAgICAgICAgICAiUkM0LVNIQSIpOworICAgICAgICBhZGQoIlRMU19SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEiLCAgICAgICAgICAiQUVTMTI4LVNIQSIpOworICAgICAgICBhZGQoIlRMU19SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEiLCAgICAgICAgICAiQUVTMjU2LVNIQSIpOworICAgICAgICBhZGQoIlRMU19FQ0RIX0VDRFNBX1dJVEhfUkM0XzEyOF9TSEEiLCAgICAgICAiRUNESC1FQ0RTQS1SQzQtU0hBIik7CisgICAgICAgIGFkZCgiVExTX0VDREhfRUNEU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEiLCAgICJFQ0RILUVDRFNBLUFFUzEyOC1TSEEiKTsKKyAgICAgICAgYWRkKCJUTFNfRUNESF9FQ0RTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSIsICAgIkVDREgtRUNEU0EtQUVTMjU2LVNIQSIpOworICAgICAgICBhZGQoIlRMU19FQ0RIX1JTQV9XSVRIX1JDNF8xMjhfU0hBIiwgICAgICAgICAiRUNESC1SU0EtUkM0LVNIQSIpOworICAgICAgICBhZGQoIlRMU19FQ0RIX1JTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSIsICAgICAiRUNESC1SU0EtQUVTMTI4LVNIQSIpOworICAgICAgICBhZGQoIlRMU19FQ0RIX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSIsICAgICAiRUNESC1SU0EtQUVTMjU2LVNIQSIpOworICAgICAgICBhZGQoIlRMU19FQ0RIRV9FQ0RTQV9XSVRIX1JDNF8xMjhfU0hBIiwgICAgICAiRUNESEUtRUNEU0EtUkM0LVNIQSIpOworICAgICAgICBhZGQoIlRMU19FQ0RIRV9FQ0RTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSIsICAiRUNESEUtRUNEU0EtQUVTMTI4LVNIQSIpOworICAgICAgICBhZGQoIlRMU19FQ0RIRV9FQ0RTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSIsICAiRUNESEUtRUNEU0EtQUVTMjU2LVNIQSIpOworICAgICAgICBhZGQoIlRMU19FQ0RIRV9SU0FfV0lUSF9SQzRfMTI4X1NIQSIsICAgICAgICAiRUNESEUtUlNBLVJDNC1TSEEiKTsKKyAgICAgICAgYWRkKCJUTFNfRUNESEVfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBIiwgICAgIkVDREhFLVJTQS1BRVMxMjgtU0hBIik7CisgICAgICAgIGFkZCgiVExTX0VDREhFX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSIsICAgICJFQ0RIRS1SU0EtQUVTMjU2LVNIQSIpOworICAgICAgICBhZGQoIlRMU19ESEVfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBIiwgICAgICAiREhFLVJTQS1BRVMxMjgtU0hBIik7CisgICAgICAgIGFkZCgiVExTX0RIRV9SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEiLCAgICAgICJESEUtUlNBLUFFUzI1Ni1TSEEiKTsKKyAgICAgICAgYWRkKCJUTFNfREhFX0RTU19XSVRIX0FFU18xMjhfQ0JDX1NIQSIsICAgICAgIkRIRS1EU1MtQUVTMTI4LVNIQSIpOworICAgICAgICBhZGQoIlRMU19ESEVfRFNTX1dJVEhfQUVTXzI1Nl9DQkNfU0hBIiwgICAgICAiREhFLURTUy1BRVMyNTYtU0hBIik7CisgICAgICAgIGFkZCgiU1NMX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiLCAgICAgICAgICJERVMtQ0JDMy1TSEEiKTsKKyAgICAgICAgYWRkKCJUTFNfRUNESF9FQ0RTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiLCAgIkVDREgtRUNEU0EtREVTLUNCQzMtU0hBIik7CisgICAgICAgIGFkZCgiVExTX0VDREhfUlNBX1dJVEhfM0RFU19FREVfQ0JDX1NIQSIsICAgICJFQ0RILVJTQS1ERVMtQ0JDMy1TSEEiKTsKKyAgICAgICAgYWRkKCJUTFNfRUNESEVfRUNEU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBIiwgIkVDREhFLUVDRFNBLURFUy1DQkMzLVNIQSIpOworICAgICAgICBhZGQoIlRMU19FQ0RIRV9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBIiwgICAiRUNESEUtUlNBLURFUy1DQkMzLVNIQSIpOworICAgICAgICBhZGQoIlNTTF9ESEVfUlNBX1dJVEhfM0RFU19FREVfQ0JDX1NIQSIsICAgICAiRURILVJTQS1ERVMtQ0JDMy1TSEEiKTsKKyAgICAgICAgYWRkKCJTU0xfREhFX0RTU19XSVRIXzNERVNfRURFX0NCQ19TSEEiLCAgICAgIkVESC1EU1MtREVTLUNCQzMtU0hBIik7CisgICAgICAgIGFkZCgiU1NMX1JTQV9XSVRIX0RFU19DQkNfU0hBIiwgICAgICAgICAgICAgICJERVMtQ0JDLVNIQSIpOworICAgICAgICBhZGQoIlNTTF9ESEVfUlNBX1dJVEhfREVTX0NCQ19TSEEiLCAgICAgICAgICAiRURILVJTQS1ERVMtQ0JDLVNIQSIpOworICAgICAgICBhZGQoIlNTTF9ESEVfRFNTX1dJVEhfREVTX0NCQ19TSEEiLCAgICAgICAgICAiRURILURTUy1ERVMtQ0JDLVNIQSIpOworICAgICAgICBhZGQoIlNTTF9SU0FfRVhQT1JUX1dJVEhfUkM0XzQwX01ENSIsICAgICAgICAiRVhQLVJDNC1NRDUiKTsKKyAgICAgICAgYWRkKCJTU0xfUlNBX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEiLCAgICAgIkVYUC1ERVMtQ0JDLVNIQSIpOworICAgICAgICBhZGQoIlNTTF9ESEVfUlNBX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEiLCAiRVhQLUVESC1SU0EtREVTLUNCQy1TSEEiKTsKKyAgICAgICAgYWRkKCJTU0xfREhFX0RTU19FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBIiwgIkVYUC1FREgtRFNTLURFUy1DQkMtU0hBIik7CisgICAgICAgIGFkZCgiU1NMX1JTQV9XSVRIX05VTExfTUQ1IiwgICAgICAgICAgICAgICAgICJOVUxMLU1ENSIpOworICAgICAgICBhZGQoIlNTTF9SU0FfV0lUSF9OVUxMX1NIQSIsICAgICAgICAgICAgICAgICAiTlVMTC1TSEEiKTsKKyAgICAgICAgYWRkKCJUTFNfRUNESF9FQ0RTQV9XSVRIX05VTExfU0hBIiwgICAgICAgICAgIkVDREgtRUNEU0EtTlVMTC1TSEEiKTsKKyAgICAgICAgYWRkKCJUTFNfRUNESF9SU0FfV0lUSF9OVUxMX1NIQSIsICAgICAgICAgICAgIkVDREgtUlNBLU5VTEwtU0hBIik7CisgICAgICAgIGFkZCgiVExTX0VDREhFX0VDRFNBX1dJVEhfTlVMTF9TSEEiLCAgICAgICAgICJFQ0RIRS1FQ0RTQS1OVUxMLVNIQSIpOworICAgICAgICBhZGQoIlRMU19FQ0RIRV9SU0FfV0lUSF9OVUxMX1NIQSIsICAgICAgICAgICAiRUNESEUtUlNBLU5VTEwtU0hBIik7CisgICAgICAgIGFkZCgiU1NMX0RIX2Fub25fV0lUSF9SQzRfMTI4X01ENSIsICAgICAgICAgICJBREgtUkM0LU1ENSIpOworICAgICAgICBhZGQoIlRMU19ESF9hbm9uX1dJVEhfQUVTXzEyOF9DQkNfU0hBIiwgICAgICAiQURILUFFUzEyOC1TSEEiKTsKKyAgICAgICAgYWRkKCJUTFNfREhfYW5vbl9XSVRIX0FFU18yNTZfQ0JDX1NIQSIsICAgICAgIkFESC1BRVMyNTYtU0hBIik7CisgICAgICAgIGFkZCgiU1NMX0RIX2Fub25fV0lUSF8zREVTX0VERV9DQkNfU0hBIiwgICAgICJBREgtREVTLUNCQzMtU0hBIik7CisgICAgICAgIGFkZCgiU1NMX0RIX2Fub25fV0lUSF9ERVNfQ0JDX1NIQSIsICAgICAgICAgICJBREgtREVTLUNCQy1TSEEiKTsKKyAgICAgICAgYWRkKCJUTFNfRUNESF9hbm9uX1dJVEhfUkM0XzEyOF9TSEEiLCAgICAgICAgIkFFQ0RILVJDNC1TSEEiKTsKKyAgICAgICAgYWRkKCJUTFNfRUNESF9hbm9uX1dJVEhfQUVTXzEyOF9DQkNfU0hBIiwgICAgIkFFQ0RILUFFUzEyOC1TSEEiKTsKKyAgICAgICAgYWRkKCJUTFNfRUNESF9hbm9uX1dJVEhfQUVTXzI1Nl9DQkNfU0hBIiwgICAgIkFFQ0RILUFFUzI1Ni1TSEEiKTsKKyAgICAgICAgYWRkKCJUTFNfRUNESF9hbm9uX1dJVEhfM0RFU19FREVfQ0JDX1NIQSIsICAgIkFFQ0RILURFUy1DQkMzLVNIQSIpOworICAgICAgICBhZGQoIlNTTF9ESF9hbm9uX0VYUE9SVF9XSVRIX1JDNF80MF9NRDUiLCAgICAiRVhQLUFESC1SQzQtTUQ1Iik7CisgICAgICAgIGFkZCgiU1NMX0RIX2Fub25fRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSIsICJFWFAtQURILURFUy1DQkMtU0hBIik7CisgICAgICAgIGFkZCgiVExTX0VDREhfYW5vbl9XSVRIX05VTExfU0hBIiwgICAgICAgICAgICJBRUNESC1OVUxMLVNIQSIpOworCisgICAgICAgIC8vIE5vIEtlcmJlcm9zIGluIEFuZHJvaWQKKyAgICAgICAgLy8gYWRkKCJUTFNfS1JCNV9XSVRIX1JDNF8xMjhfU0hBIiwgICAgICAgICAgICJLUkI1LVJDNC1TSEEiKTsKKyAgICAgICAgLy8gYWRkKCJUTFNfS1JCNV9XSVRIX1JDNF8xMjhfTUQ1IiwgICAgICAgICAgICJLUkI1LVJDNC1NRDUiKTsKKyAgICAgICAgLy8gYWRkKCJUTFNfS1JCNV9XSVRIXzNERVNfRURFX0NCQ19TSEEiLCAgICAgICJLUkI1LURFUy1DQkMzLVNIQSIpOworICAgICAgICAvLyBhZGQoIlRMU19LUkI1X1dJVEhfM0RFU19FREVfQ0JDX01ENSIsICAgICAgIktSQjUtREVTLUNCQzMtTUQ1Iik7CisgICAgICAgIC8vIGFkZCgiVExTX0tSQjVfV0lUSF9ERVNfQ0JDX1NIQSIsICAgICAgICAgICAiS1JCNS1ERVMtQ0JDLVNIQSIpOworICAgICAgICAvLyBhZGQoIlRMU19LUkI1X1dJVEhfREVTX0NCQ19NRDUiLCAgICAgICAgICAgIktSQjUtREVTLUNCQy1NRDUiKTsKKyAgICAgICAgLy8gYWRkKCJUTFNfS1JCNV9FWFBPUlRfV0lUSF9SQzRfNDBfU0hBIiwgICAgICJFWFAtS1JCNS1SQzQtU0hBIik7CisgICAgICAgIC8vIGFkZCgiVExTX0tSQjVfRVhQT1JUX1dJVEhfUkM0XzQwX01ENSIsICAgICAiRVhQLUtSQjUtUkM0LU1ENSIpOworICAgICAgICAvLyBhZGQoIlRMU19LUkI1X0VYUE9SVF9XSVRIX0RFU19DQkNfNDBfU0hBIiwgIkVYUC1LUkI1LURFUy1DQkMtU0hBIik7CisgICAgICAgIC8vIGFkZCgiVExTX0tSQjVfRVhQT1JUX1dJVEhfREVTX0NCQ180MF9NRDUiLCAiRVhQLUtSQjUtREVTLUNCQy1NRDUiKTsKKworICAgICAgICAvLyBub3QgaW1wbGVtZW50ZWQgYnkgZWl0aGVyIFJJIG9yIE9wZW5TU0wKKyAgICAgICAgLy8gYWRkKCJTU0xfREhfRFNTX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEiLCBudWxsKTsKKyAgICAgICAgLy8gYWRkKCJTU0xfREhfUlNBX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEiLCBudWxsKTsKKworICAgICAgICAvLyBFWFBPUlQxMDI0IHN1aXRlcyB3ZXJlIG5ldmVyIHN0YW5kYXJkaXplZCBidXQgd2VyZSB3aWRlbHkgaW1wbGVtZW50ZWQuCisgICAgICAgIC8vIE9wZW5TU0wgMC45LjhjIGFuZCBsYXRlciBoYXZlIGRpc2FibGVkIFRMUzFfQUxMT1dfRVhQRVJJTUVOVEFMX0NJUEhFUlNVSVRFUworICAgICAgICAvLyBhZGQoIlNTTF9SU0FfRVhQT1JUMTAyNF9XSVRIX0RFU19DQkNfU0hBIiwgIkVYUDEwMjQtREVTLUNCQy1TSEEiKTsKKyAgICAgICAgLy8gYWRkKCJTU0xfUlNBX0VYUE9SVDEwMjRfV0lUSF9SQzRfNTZfU0hBIiwgICJFWFAxMDI0LVJDNC1TSEEiKTsKKworICAgICAgICAvLyBObyBSQzIKKyAgICAgICAgLy8gYWRkKCJTU0xfUlNBX0VYUE9SVF9XSVRIX1JDMl9DQkNfNDBfTUQ1IiwgICJFWFAtUkMyLUNCQy1NRDUiKTsKKyAgICAgICAgLy8gYWRkKCJUTFNfS1JCNV9FWFBPUlRfV0lUSF9SQzJfQ0JDXzQwX1NIQSIsICJFWFAtS1JCNS1SQzItQ0JDLVNIQSIpOworICAgICAgICAvLyBhZGQoIlRMU19LUkI1X0VYUE9SVF9XSVRIX1JDMl9DQkNfNDBfTUQ1IiwgIkVYUC1LUkI1LVJDMi1DQkMtTUQ1Iik7CisKKyAgICAgICAgLy8gUFNLIGlzIFByaXZhdGUgU2hhcmVkIEtleSAtIGRpZG4ndCBleGlzdCBpbiBGcm95bydzIG9wZW5zc2wgLSBubyBKU1NFIGVxdWl2YWxlbnQKKyAgICAgICAgLy8gYWRkKG51bGwsICJQU0stM0RFUy1FREUtQ0JDLVNIQSIpOworICAgICAgICAvLyBhZGQobnVsbCwgIlBTSy1BRVMxMjgtQ0JDLVNIQSIpOworICAgICAgICAvLyBhZGQobnVsbCwgIlBTSy1BRVMyNTYtQ0JDLVNIQSIpOworICAgICAgICAvLyBhZGQobnVsbCwgIlBTSy1SQzQtU0hBIik7CisKKyAgICAgICAgLy8gU2lnbmFsaW5nIENpcGhlciBTdWl0ZSBWYWx1ZSBmb3Igc2VjdXJlIHJlbmVnb3RpYXRpb24gaGFuZGxlZCBhcyBzcGVjaWFsIGNhc2UuCisgICAgICAgIC8vIGFkZCgiVExTX0VNUFRZX1JFTkVHT1RJQVRJT05fSU5GT19TQ1NWIiwgbnVsbCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gU1VQUE9SVEVEX0NJUEhFUl9TVUlURVM7CisgICAgc3RhdGljIHsKKyAgICAgICAgaW50IHNpemUgPSBTVEFOREFSRF9UT19PUEVOU1NMX0NJUEhFUl9TVUlURVMuc2l6ZSgpOworICAgICAgICBTVVBQT1JURURfQ0lQSEVSX1NVSVRFUyA9IG5ldyBTdHJpbmdbc2l6ZSArIDFdOworICAgICAgICBTVEFOREFSRF9UT19PUEVOU1NMX0NJUEhFUl9TVUlURVMua2V5U2V0KCkudG9BcnJheShTVVBQT1JURURfQ0lQSEVSX1NVSVRFUyk7CisgICAgICAgIFNVUFBPUlRFRF9DSVBIRVJfU1VJVEVTW3NpemVdID0gVExTX0VNUFRZX1JFTkVHT1RJQVRJT05fSU5GT19TQ1NWOworICAgIH0KKworICAgIC8vIFNTTCBtb2RlIGZyb20gc3NsLmgKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgU1NMX01PREVfSEFORFNIQUtFX0NVVFRIUk9VR0ggPSAweDAwMDAwMDQwTDsKKworICAgIC8vIFNTTCBvcHRpb25zIGZyb20gc3NsLmgKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgU1NMX09QX05PX1RJQ0tFVCAgICAgID0gMHgwMDAwNDAwMEw7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIFNTTF9PUF9OT19DT01QUkVTU0lPTiA9IDB4MDAwMjAwMDBMOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBTU0xfT1BfTk9fU1NMdjMgICAgICAgPSAweDAyMDAwMDAwTDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgU1NMX09QX05PX1RMU3YxICAgICAgID0gMHgwNDAwMDAwMEw7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgU1NMX0NUWF9uZXcoKTsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdbXSB7CisgICAgICAgICAgICAiU1NMX1JTQV9XSVRIX1JDNF8xMjhfTUQ1IiwKKyAgICAgICAgICAgICJTU0xfUlNBX1dJVEhfUkM0XzEyOF9TSEEiLAorICAgICAgICAgICAgIlRMU19SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEiLAorICAgICAgICAgICAgIlRMU19SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEiLAorICAgICAgICAgICAgIlRMU19FQ0RIX0VDRFNBX1dJVEhfUkM0XzEyOF9TSEEiLAorICAgICAgICAgICAgIlRMU19FQ0RIX0VDRFNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBIiwKKyAgICAgICAgICAgICJUTFNfRUNESF9FQ0RTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSIsCisgICAgICAgICAgICAiVExTX0VDREhfUlNBX1dJVEhfUkM0XzEyOF9TSEEiLAorICAgICAgICAgICAgIlRMU19FQ0RIX1JTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSIsCisgICAgICAgICAgICAiVExTX0VDREhfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBIiwKKyAgICAgICAgICAgICJUTFNfRUNESEVfRUNEU0FfV0lUSF9SQzRfMTI4X1NIQSIsCisgICAgICAgICAgICAiVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBIiwKKyAgICAgICAgICAgICJUTFNfRUNESEVfRUNEU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEiLAorICAgICAgICAgICAgIlRMU19FQ0RIRV9SU0FfV0lUSF9SQzRfMTI4X1NIQSIsCisgICAgICAgICAgICAiVExTX0VDREhFX1JTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSIsCisgICAgICAgICAgICAiVExTX0VDREhFX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSIsCisgICAgICAgICAgICAiVExTX0RIRV9SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEiLAorICAgICAgICAgICAgIlRMU19ESEVfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBIiwKKyAgICAgICAgICAgICJUTFNfREhFX0RTU19XSVRIX0FFU18xMjhfQ0JDX1NIQSIsCisgICAgICAgICAgICAiVExTX0RIRV9EU1NfV0lUSF9BRVNfMjU2X0NCQ19TSEEiLAorICAgICAgICAgICAgIlNTTF9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBIiwKKyAgICAgICAgICAgICJUTFNfRUNESF9FQ0RTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiLAorICAgICAgICAgICAgIlRMU19FQ0RIX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiLAorICAgICAgICAgICAgIlRMU19FQ0RIRV9FQ0RTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiLAorICAgICAgICAgICAgIlRMU19FQ0RIRV9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBIiwKKyAgICAgICAgICAgICJTU0xfREhFX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiLAorICAgICAgICAgICAgIlNTTF9ESEVfRFNTX1dJVEhfM0RFU19FREVfQ0JDX1NIQSIsCisgICAgICAgICAgICAiU1NMX1JTQV9XSVRIX0RFU19DQkNfU0hBIiwKKyAgICAgICAgICAgICJTU0xfREhFX1JTQV9XSVRIX0RFU19DQkNfU0hBIiwKKyAgICAgICAgICAgICJTU0xfREhFX0RTU19XSVRIX0RFU19DQkNfU0hBIiwKKyAgICAgICAgICAgICJTU0xfUlNBX0VYUE9SVF9XSVRIX1JDNF80MF9NRDUiLAorICAgICAgICAgICAgIlNTTF9SU0FfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSIsCisgICAgICAgICAgICAiU1NMX0RIRV9SU0FfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSIsCisgICAgICAgICAgICAiU1NMX0RIRV9EU1NfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSIsCisgICAgICAgICAgICBUTFNfRU1QVFlfUkVORUdPVElBVElPTl9JTkZPX1NDU1YKKyAgICAgICAgfTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZ1tdIGdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgcmV0dXJuIFNVUFBPUlRFRF9DSVBIRVJfU1VJVEVTLmNsb25lKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTU0xfQ1RYX2ZyZWUoaW50IHNzbF9jdHgpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNTTF9uZXcoaW50IHNzbF9jdHgpIHRocm93cyBTU0xFeGNlcHRpb247CisKKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXVtdIGVuY29kZUNlcnRpZmljYXRlcyhDZXJ0aWZpY2F0ZVtdIGNlcnRpZmljYXRlcykKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdW10gY2VydGlmaWNhdGVCeXRlcyA9IG5ldyBieXRlW2NlcnRpZmljYXRlcy5sZW5ndGhdW107CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2VydGlmaWNhdGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjZXJ0aWZpY2F0ZUJ5dGVzW2ldID0gY2VydGlmaWNhdGVzW2ldLmdldEVuY29kZWQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2VydGlmaWNhdGVCeXRlczsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFNTTF91c2VfY2VydGlmaWNhdGUoaW50IHNzbCwgYnl0ZVtdW10gYXNuMURlckVuY29kZWRDZXJ0aWZpY2F0ZUNoYWluKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU1NMX3VzZV9Qcml2YXRlS2V5KGludCBzc2wsIGJ5dGVbXSBwa2NzOEVuY29kZWRQcml2YXRlS2V5KTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU1NMX2NoZWNrX3ByaXZhdGVfa2V5KGludCBzc2wpIHRocm93cyBTU0xFeGNlcHRpb247CisKKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXVtdIGVuY29kZUlzc3Vlclg1MDlQcmluY2lwYWxzKFg1MDlDZXJ0aWZpY2F0ZVtdIGNlcnRpZmljYXRlcykKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdW10gcHJpbmNpcGFsQnl0ZXMgPSBuZXcgYnl0ZVtjZXJ0aWZpY2F0ZXMubGVuZ3RoXVtdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNlcnRpZmljYXRlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgcHJpbmNpcGFsQnl0ZXNbaV0gPSBjZXJ0aWZpY2F0ZXNbaV0uZ2V0SXNzdWVyWDUwMFByaW5jaXBhbCgpLmdldEVuY29kZWQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcHJpbmNpcGFsQnl0ZXM7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTU0xfc2V0X2NsaWVudF9DQV9saXN0KGludCBzc2wsIGJ5dGVbXVtdIGFzbjFEZXJFbmNvZGVkWDUwMFByaW5jaXBhbHMpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgbG9uZyBTU0xfZ2V0X21vZGUoaW50IHNzbCk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBsb25nIFNTTF9zZXRfbW9kZShpbnQgc3NsLCBsb25nIG1vZGUpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgbG9uZyBTU0xfY2xlYXJfbW9kZShpbnQgc3NsLCBsb25nIG1vZGUpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgbG9uZyBTU0xfZ2V0X29wdGlvbnMoaW50IHNzbCk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBsb25nIFNTTF9zZXRfb3B0aW9ucyhpbnQgc3NsLCBsb25nIG9wdGlvbnMpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgbG9uZyBTU0xfY2xlYXJfb3B0aW9ucyhpbnQgc3NsLCBsb25nIG9wdGlvbnMpOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmdbXSBnZXRTdXBwb3J0ZWRQcm90b2NvbHMoKSB7CisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nW10geyBTVVBQT1JURURfUFJPVE9DT0xfU1NMVjMsIFNVUFBPUlRFRF9QUk9UT0NPTF9UTFNWMSB9OworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRFbmFibGVkUHJvdG9jb2xzKGludCBzc2wsIFN0cmluZ1tdIHByb3RvY29scykgeworICAgICAgICBjaGVja0VuYWJsZWRQcm90b2NvbHMocHJvdG9jb2xzKTsKKyAgICAgICAgLy8gb3BlbnNzbCB1c2VzIG5lZ2F0aXZlIGxvZ2ljIGxldHRpbmcgeW91IGRpc2FibGUgcHJvdG9jb2xzLgorICAgICAgICAvLyBzbyBmaXJzdCwgYXNzdW1lIHdlIG5lZWQgdG8gc2V0IGFsbCAoZGlzYWJsZSBhbGwpIGFuZCBjbGVhciBub25lIChlbmFibGUgbm9uZSkuCisgICAgICAgIC8vIGluIHRoZSBsb29wLCBzZWxlY3RpdmVseSBtb3ZlIGJpdHMgZnJvbSBzZXQgdG8gY2xlYXIgKGZyb20gZGlzYWJsZSB0byBlbmFibGUpCisgICAgICAgIGxvbmcgb3B0aW9uc1RvU2V0ID0gKFNTTF9PUF9OT19TU0x2MyB8IFNTTF9PUF9OT19UTFN2MSk7CisgICAgICAgIGxvbmcgb3B0aW9uc1RvQ2xlYXIgPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHByb3RvY29scy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIHByb3RvY29sID0gcHJvdG9jb2xzW2ldOworICAgICAgICAgICAgaWYgKHByb3RvY29sLmVxdWFscyhTVVBQT1JURURfUFJPVE9DT0xfU1NMVjMpKSB7CisgICAgICAgICAgICAgICAgb3B0aW9uc1RvU2V0ICY9IH5TU0xfT1BfTk9fU1NMdjM7CisgICAgICAgICAgICAgICAgb3B0aW9uc1RvQ2xlYXIgfD0gU1NMX09QX05PX1NTTHYzOworICAgICAgICAgICAgfSBlbHNlIGlmIChwcm90b2NvbC5lcXVhbHMoU1VQUE9SVEVEX1BST1RPQ09MX1RMU1YxKSkgeworICAgICAgICAgICAgICAgIG9wdGlvbnNUb1NldCAmPSB+U1NMX09QX05PX1RMU3YxOworICAgICAgICAgICAgICAgIG9wdGlvbnNUb0NsZWFyIHw9IFNTTF9PUF9OT19UTFN2MTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gZXJyb3IgY2hlY2tlZCBieSBjaGVja0VuYWJsZWRQcm90b2NvbHMKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBTU0xfc2V0X29wdGlvbnMoc3NsLCBvcHRpb25zVG9TZXQpOworICAgICAgICBTU0xfY2xlYXJfb3B0aW9ucyhzc2wsIG9wdGlvbnNUb0NsZWFyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZ1tdIGNoZWNrRW5hYmxlZFByb3RvY29scyhTdHJpbmdbXSBwcm90b2NvbHMpIHsKKyAgICAgICAgaWYgKHByb3RvY29scyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJwcm90b2NvbHMgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG9jb2xzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBTdHJpbmcgcHJvdG9jb2wgPSBwcm90b2NvbHNbaV07CisgICAgICAgICAgICBpZiAocHJvdG9jb2wgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInByb3RvY29sc1siICsgaSArICJdID09IG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICgoIXByb3RvY29sLmVxdWFscyhTVVBQT1JURURfUFJPVE9DT0xfU1NMVjMpKQorICAgICAgICAgICAgICAgICAgICAmJiAoIXByb3RvY29sLmVxdWFscyhTVVBQT1JURURfUFJPVE9DT0xfVExTVjEpKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInByb3RvY29sICIgKyBwcm90b2NvbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGlzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcHJvdG9jb2xzOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU1NMX3NldF9jaXBoZXJfbGlzdHMoaW50IHNzbCwgU3RyaW5nW10gY2lwaGVycyk7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0RW5hYmxlZENpcGhlclN1aXRlcyhpbnQgc3NsLCBTdHJpbmdbXSBjaXBoZXJTdWl0ZXMpIHsKKyAgICAgICAgY2hlY2tFbmFibGVkQ2lwaGVyU3VpdGVzKGNpcGhlclN1aXRlcyk7CisgICAgICAgIExpc3Q8U3RyaW5nPiBvcGVuc3NsU3VpdGVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2lwaGVyU3VpdGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBTdHJpbmcgY2lwaGVyU3VpdGUgPSBjaXBoZXJTdWl0ZXNbaV07CisgICAgICAgICAgICBpZiAoY2lwaGVyU3VpdGUuZXF1YWxzKFRMU19FTVBUWV9SRU5FR09USUFUSU9OX0lORk9fU0NTVikpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN0cmluZyBvcGVuc3NsID0gU1RBTkRBUkRfVE9fT1BFTlNTTF9DSVBIRVJfU1VJVEVTLmdldChjaXBoZXJTdWl0ZSk7CisgICAgICAgICAgICBTdHJpbmcgY3MgPSAob3BlbnNzbCA9PSBudWxsKSA/IGNpcGhlclN1aXRlIDogb3BlbnNzbDsKKyAgICAgICAgICAgIG9wZW5zc2xTdWl0ZXMuYWRkKGNzKTsKKyAgICAgICAgfQorICAgICAgICBTU0xfc2V0X2NpcGhlcl9saXN0cyhzc2wsIG9wZW5zc2xTdWl0ZXMudG9BcnJheShuZXcgU3RyaW5nW29wZW5zc2xTdWl0ZXMuc2l6ZSgpXSkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gY2hlY2tFbmFibGVkQ2lwaGVyU3VpdGVzKFN0cmluZ1tdIGNpcGhlclN1aXRlcykgeworICAgICAgICBpZiAoY2lwaGVyU3VpdGVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImNpcGhlclN1aXRlcyA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgLy8gbWFrZXMgc3VyZSBhbGwgc3VpdGVzIGFyZSB2YWxpZCwgdGhyb3dpbmcgb24gZXJyb3IKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaXBoZXJTdWl0ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFN0cmluZyBjaXBoZXJTdWl0ZSA9IGNpcGhlclN1aXRlc1tpXTsKKyAgICAgICAgICAgIGlmIChjaXBoZXJTdWl0ZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiY2lwaGVyU3VpdGVzWyIgKyBpICsgIl0gPT0gbnVsbCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGNpcGhlclN1aXRlLmVxdWFscyhUTFNfRU1QVFlfUkVORUdPVElBVElPTl9JTkZPX1NDU1YpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoU1RBTkRBUkRfVE9fT1BFTlNTTF9DSVBIRVJfU1VJVEVTLmNvbnRhaW5zS2V5KGNpcGhlclN1aXRlKSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKE9QRU5TU0xfVE9fU1RBTkRBUkRfQ0lQSEVSX1NVSVRFUy5jb250YWluc0tleShjaXBoZXJTdWl0ZSkpIHsKKyAgICAgICAgICAgICAgICAvLyBUT0RPIGxvZyB3YXJuaW5nIGFib3V0IHVzaW5nIGJhY2t3YXJkIGNvbXBhdGFiaWxpdHkKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImNpcGhlclN1aXRlICIgKyBjaXBoZXJTdWl0ZSArICIgaXMgbm90IHN1cHBvcnRlZC4iKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2lwaGVyU3VpdGVzOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTVVBQT1JURURfQ09NUFJFU1NJT05fTUVUSE9EX1pMSUIgPSAiWkxJQiI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNVUFBPUlRFRF9DT01QUkVTU0lPTl9NRVRIT0RfTlVMTCA9ICJOVUxMIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIFNVUFBPUlRFRF9DT01QUkVTU0lPTl9NRVRIT0RTCisgICAgICAgICAgICA9IHsgU1VQUE9SVEVEX0NPTVBSRVNTSU9OX01FVEhPRF9aTElCLCBTVVBQT1JURURfQ09NUFJFU1NJT05fTUVUSE9EX05VTEwgfTsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gZ2V0U3VwcG9ydGVkQ29tcHJlc3Npb25NZXRob2RzKCkgeworICAgICAgICByZXR1cm4gU1VQUE9SVEVEX0NPTVBSRVNTSU9OX01FVEhPRFMuY2xvbmUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGdldERlZmF1bHRDb21wcmVzc2lvbk1ldGhvZHMoKSB7CisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nW10geyBTVVBQT1JURURfQ09NUFJFU1NJT05fTUVUSE9EX05VTEwgfTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZ1tdIGNoZWNrRW5hYmxlZENvbXByZXNzaW9uTWV0aG9kcyhTdHJpbmdbXSBtZXRob2RzKSB7CisgICAgICAgIGlmIChtZXRob2RzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm1ldGhvZHMgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChtZXRob2RzLmxlbmd0aCA8IDEKKyAgICAgICAgICAgICAgICAmJiAhbWV0aG9kc1ttZXRob2RzLmxlbmd0aC0xXS5lcXVhbHMoU1VQUE9SVEVEX0NPTVBSRVNTSU9OX01FVEhPRF9OVUxMKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibGFzdCBtZXRob2QgbXVzdCBiZSBOVUxMIik7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXRob2RzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBTdHJpbmcgbWV0aG9kID0gbWV0aG9kc1tpXTsKKyAgICAgICAgICAgIGlmIChtZXRob2QgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm1ldGhvZHNbIiArIGkgKyAiXSA9PSBudWxsIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIW1ldGhvZC5lcXVhbHMoU1VQUE9SVEVEX0NPTVBSRVNTSU9OX01FVEhPRF9aTElCKQorICAgICAgICAgICAgICAgICAgICAmJiAhbWV0aG9kLmVxdWFscyhTVVBQT1JURURfQ09NUFJFU1NJT05fTUVUSE9EX05VTEwpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibWV0aG9kICIgKyBtZXRob2QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG1ldGhvZHM7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldEVuYWJsZWRDb21wcmVzc2lvbk1ldGhvZHMoaW50IHNzbCwgU3RyaW5nW10gbWV0aG9kcykgeworICAgICAgICBjaGVja0VuYWJsZWRDb21wcmVzc2lvbk1ldGhvZHMobWV0aG9kcyk7CisgICAgICAgIC8vIG9wZW5zc2wgdXNlcyBuZWdhdGl2ZSBsb2dpYyBsZXR0aW5nIHlvdSBkaXNhYmxlIGNvbXByZXNzaW9uLgorICAgICAgICAvLyBzbyBmaXJzdCwgYXNzdW1lIHdlIG5lZWQgdG8gc2V0IGFsbCAoZGlzYWJsZSBhbGwpIGFuZCBjbGVhciBub25lIChlbmFibGUgbm9uZSkuCisgICAgICAgIC8vIGluIHRoZSBsb29wLCBzZWxlY3RpdmVseSBtb3ZlIGJpdHMgZnJvbSBzZXQgdG8gY2xlYXIgKGZyb20gZGlzYWJsZSB0byBlbmFibGUpCisgICAgICAgIGxvbmcgb3B0aW9uc1RvU2V0ID0gKFNTTF9PUF9OT19DT01QUkVTU0lPTik7CisgICAgICAgIGxvbmcgb3B0aW9uc1RvQ2xlYXIgPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1ldGhvZHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFN0cmluZyBtZXRob2QgPSBtZXRob2RzW2ldOworICAgICAgICAgICAgaWYgKG1ldGhvZC5lcXVhbHMoU1VQUE9SVEVEX0NPTVBSRVNTSU9OX01FVEhPRF9OVUxMKSkgeworICAgICAgICAgICAgICAgIC8vIG5vdGhpbmcgdG8gZG8gdG8gc3VwcG9ydCBOVUxMCisgICAgICAgICAgICB9IGVsc2UgaWYgKG1ldGhvZC5lcXVhbHMoU1VQUE9SVEVEX0NPTVBSRVNTSU9OX01FVEhPRF9aTElCKSkgeworICAgICAgICAgICAgICAgIG9wdGlvbnNUb1NldCAmPSB+U1NMX09QX05PX0NPTVBSRVNTSU9OOworICAgICAgICAgICAgICAgIG9wdGlvbnNUb0NsZWFyIHw9IFNTTF9PUF9OT19DT01QUkVTU0lPTjsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gZXJyb3IgY2hlY2tlZCBieSBjaGVja0VuYWJsZWRDb21wcmVzc2lvbk1ldGhvZHMKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBTU0xfc2V0X29wdGlvbnMoc3NsLCBvcHRpb25zVG9TZXQpOworICAgICAgICBTU0xfY2xlYXJfb3B0aW9ucyhzc2wsIG9wdGlvbnNUb0NsZWFyKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFNlZSB0aGUgT3BlblNTTCBzc2wuaCBoZWFkZXIgZmlsZSBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTU0xfVkVSSUZZX05PTkUgPSAgICAgICAgICAgICAgICAgMHgwMDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTU0xfVkVSSUZZX1BFRVIgPSAgICAgICAgICAgICAgICAgMHgwMTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTU0xfVkVSSUZZX0ZBSUxfSUZfTk9fUEVFUl9DRVJUID0gMHgwMjsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU1NMX3NldF92ZXJpZnkoaW50IHNzbE5hdGl2ZVBvaW50ZXIsIGludCBtb2RlKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU1NMX3NldF9zZXNzaW9uKGludCBzc2xOYXRpdmVQb2ludGVyLCBpbnQgc3NsU2Vzc2lvbk5hdGl2ZVBvaW50ZXIpCisgICAgICAgIHRocm93cyBTU0xFeGNlcHRpb247CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFNTTF9zZXRfc2Vzc2lvbl9jcmVhdGlvbl9lbmFibGVkKAorICAgICAgICAgICAgaW50IHNzbE5hdGl2ZVBvaW50ZXIsIGJvb2xlYW4gY3JlYXRpb25FbmFibGVkKSB0aHJvd3MgU1NMRXhjZXB0aW9uOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTU0xfc2V0X3Rsc2V4dF9ob3N0X25hbWUoaW50IHNzbE5hdGl2ZVBvaW50ZXIsIFN0cmluZyBob3N0bmFtZSkKKyAgICAgICAgICAgIHRocm93cyBTU0xFeGNlcHRpb247CisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgU3RyaW5nIFNTTF9nZXRfc2VydmVybmFtZShpbnQgc3NsTmF0aXZlUG9pbnRlcik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzc2xTZXNzaW9uTmF0aXZlUG9pbnRlciBvZiB0aGUgbmVnb3RpYXRlZCBzZXNzaW9uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNTTF9kb19oYW5kc2hha2UoaW50IHNzbE5hdGl2ZVBvaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3IgZmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIHNoYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdGltZW91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGNsaWVudF9tb2RlKQorICAgICAgICB0aHJvd3MgU1NMRXhjZXB0aW9uLCBTb2NrZXRUaW1lb3V0RXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEN1cnJlbnRseSBvbmx5IGludGVuZGVkIGZvciBmb3JjaW5nIHJlbmVnb3RpYXRpb24gZm9yIHRlc3RpbmcuCisgICAgICogTm90IHVzZWQgd2l0aGluIE9wZW5TU0xTb2NrZXRJbXBsLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU1NMX3JlbmVnb3RpYXRlKGludCBzc2xOYXRpdmVQb2ludGVyKSB0aHJvd3MgU1NMRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbG9jYWwgQVNOLjEgREVSIGVuY29kZWQgWDUwOSBjZXJ0aWZpY2F0ZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgYnl0ZVtdW10gU1NMX2dldF9jZXJ0aWZpY2F0ZShpbnQgc3NsTmF0aXZlUG9pbnRlcik7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwZWVyIEFTTi4xIERFUiBlbmNvZGVkIFg1MDkgY2VydGlmaWNhdGVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJ5dGVbXVtdIFNTTF9nZXRfcGVlcl9jZXJ0X2NoYWluKGludCBzc2xOYXRpdmVQb2ludGVyKTsKKworICAgIC8qKgorICAgICAqIFJlYWRzIHdpdGggdGhlIG5hdGl2ZSBTU0xfcmVhZCBmdW5jdGlvbiBmcm9tIHRoZSBlbmNyeXB0ZWQgZGF0YSBzdHJlYW0KKyAgICAgKiBAcmV0dXJuIC0xIGlmIGVycm9yIG9yIHRoZSBlbmQgb2YgdGhlIHN0cmVhbSBpcyByZWFjaGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTU0xfcmVhZChpbnQgc3NsTmF0aXZlUG9pbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3IgZmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTEhhbmRzaGFrZUNhbGxiYWNrcyBzaGMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuLCBpbnQgdGltZW91dCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGVzIHdpdGggdGhlIG5hdGl2ZSBTU0xfd3JpdGUgZnVuY3Rpb24gdG8gdGhlIGVuY3J5cHRlZCBkYXRhIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFNTTF93cml0ZShpbnQgc3NsTmF0aXZlUG9pbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvciBmZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xIYW5kc2hha2VDYWxsYmFja3Mgc2hjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFNTTF9pbnRlcnJ1cHQoaW50IHNzbE5hdGl2ZVBvaW50ZXIpOworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU1NMX3NodXRkb3duKGludCBzc2xOYXRpdmVQb2ludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yIGZkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTEhhbmRzaGFrZUNhbGxiYWNrcyBzaGMpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU1NMX2ZyZWUoaW50IHNzbE5hdGl2ZVBvaW50ZXIpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgYnl0ZVtdIFNTTF9TRVNTSU9OX3Nlc3Npb25faWQoaW50IHNzbFNlc3Npb25OYXRpdmVQb2ludGVyKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGxvbmcgU1NMX1NFU1NJT05fZ2V0X3RpbWUoaW50IHNzbFNlc3Npb25OYXRpdmVQb2ludGVyKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIFN0cmluZyBTU0xfU0VTU0lPTl9nZXRfdmVyc2lvbihpbnQgc3NsU2Vzc2lvbk5hdGl2ZVBvaW50ZXIpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgU3RyaW5nIFNTTF9TRVNTSU9OX2NpcGhlcihpbnQgc3NsU2Vzc2lvbk5hdGl2ZVBvaW50ZXIpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgU3RyaW5nIFNTTF9TRVNTSU9OX2NvbXByZXNzX21ldGgoaW50IHNzbEN0eE5hdGl2ZVBvaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNzbFNlc3Npb25OYXRpdmVQb2ludGVyKTsKKworICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU1NMX1NFU1NJT05fZnJlZShpbnQgc3NsU2Vzc2lvbk5hdGl2ZVBvaW50ZXIpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgYnl0ZVtdIGkyZF9TU0xfU0VTU0lPTihpbnQgc3NsU2Vzc2lvbk5hdGl2ZVBvaW50ZXIpOworCisgICAgcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IGQyaV9TU0xfU0VTU0lPTihieXRlW10gZGF0YSk7CisKKyAgICAvKioKKyAgICAgKiBBIGNvbGxlY3Rpb24gb2YgY2FsbGJhY2tzIGZyb20gdGhlIG5hdGl2ZSBPcGVuU1NMIGNvZGUgdGhhdCBhcmUKKyAgICAgKiByZWxhdGVkIHRvIHRoZSBTU0wgaGFuZHNoYWtlIGluaXRpYXRlZCBieSBTU0xfZG9faGFuZHNoYWtlLgorICAgICAqLworICAgIHB1YmxpYyBpbnRlcmZhY2UgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFZlcmlmeSB0aGF0IHdlIHRydXN0IHRoZSBjZXJ0aWZpY2F0ZSBjaGFpbiBpcyB0cnVzdGVkLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gYXNuMURlckVuY29kZWRDZXJ0aWZpY2F0ZUNoYWluIEEgY2hhaW4gb2YgQVNOLjEgREVSIGVuY29kZWQgY2VydGlmaWNhdGVzCisgICAgICAgICAqIEBwYXJhbSBhdXRoTWV0aG9kIGF1dGggYWxnb3JpdGhtIG5hbWUKKyAgICAgICAgICoKKyAgICAgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBpZiB0aGUgY2VydGlmaWNhdGUgaXMgdW50cnVzdGVkCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCB2ZXJpZnlDZXJ0aWZpY2F0ZUNoYWluKGJ5dGVbXVtdIGFzbjFEZXJFbmNvZGVkQ2VydGlmaWNhdGVDaGFpbiwgU3RyaW5nIGF1dGhNZXRob2QpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb247CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENhbGxlZCBvbiBhbiBTU0wgY2xpZW50IHdoZW4gdGhlIHNlcnZlciByZXF1ZXN0cyAob3IKKyAgICAgICAgICogcmVxdWlyZXMgYSBjZXJ0aWZpY2F0ZSkuIFRoZSBjbGllbnQgY2FuIHJlc3BvbmQgYnkgdXNpbmcKKyAgICAgICAgICogU1NMX3VzZV9jZXJ0aWZpY2F0ZSBhbmQgU1NMX3VzZV9Qcml2YXRlS2V5IHRvIHNldCBhCisgICAgICAgICAqIGNlcnRpZmljYXRlIGlmIGhhcyBhbiBhcHByb3ByaWF0ZSBvbmUgYXZhaWxhYmxlLCBzaW1pbGFyIHRvCisgICAgICAgICAqIGhvdyB0aGUgc2VydmVyIHByb3ZpZGVzIGl0cyBjZXJ0aWZpY2F0ZS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIGtleVR5cGVzIGtleSB0eXBlcyBzdXBwb3J0ZWQgYnkgdGhlIHNlcnZlciwKKyAgICAgICAgICogY29udmVydGlibGUgdG8gc3RyaW5ncyB3aXRoICNrZXlUeXBlCisgICAgICAgICAqIEBwYXJhbSBhc24xRGVyRW5jb2RlZFg1MDBQcmluY2lwYWxzIENBcyBrbm93biB0byB0aGUgc2VydmVyCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCBjbGllbnRDZXJ0aWZpY2F0ZVJlcXVlc3RlZChieXRlW10ga2V5VHlwZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVbXVtdIGFzbjFEZXJFbmNvZGVkWDUwMFByaW5jaXBhbHMpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiwgU1NMRXhjZXB0aW9uOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDYWxsZWQgd2hlbiBTU0wgaGFuZHNoYWtlIGlzIGNvbXBsZXRlZC4gTm90ZSB0aGF0IHRoaXMgY2FuCisgICAgICAgICAqIGJlIGFmdGVyIFNTTF9kb19oYW5kc2hha2UgcmV0dXJucyB3aGVuIGhhbmRzaGFrZSBjdXR0aHJvdWdoCisgICAgICAgICAqIGlzIGVuYWJsZWQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCBoYW5kc2hha2VDb21wbGV0ZWQoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9PcGVuU1NMQ29udGV4dEltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL09wZW5TU0xDb250ZXh0SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI0ZTRhNDYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9PcGVuU1NMQ29udGV4dEltcGwuamF2YQpAQCAtMCwwICsxLDUyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldEZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTb2NrZXRGYWN0b3J5OworCisvKioKKyAqIE92ZXJyaWRlcyB0aGUgb3JpZ2luYWwgU1NMQ29udGV4dEltcGwgdG8gcHJvdmlkZSBPcGVuU1NMLWJhc2VkCisgKiBTU0xTb2NrZXRGYWN0b3J5IGFuZCBTU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5IGluc3RhbmNlcy4KKyAqLworcHVibGljIGNsYXNzIE9wZW5TU0xDb250ZXh0SW1wbCBleHRlbmRzIFNTTENvbnRleHRJbXBsIHsKKworICAgIHB1YmxpYyBPcGVuU1NMQ29udGV4dEltcGwoKSB7fQorCisgICAgcHJvdGVjdGVkIE9wZW5TU0xDb250ZXh0SW1wbChEZWZhdWx0U1NMQ29udGV4dEltcGwgZHVtbXkpCisgICAgICAgICAgICB0aHJvd3MgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKGR1bW15KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU1NMU29ja2V0RmFjdG9yeSBlbmdpbmVHZXRTb2NrZXRGYWN0b3J5KCkgeworICAgICAgICBpZiAoc3NsUGFyYW1ldGVycyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJTU0xDb250ZXh0IGlzIG5vdCBpbml0aWFsaXplZC4iKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IE9wZW5TU0xTb2NrZXRGYWN0b3J5SW1wbChzc2xQYXJhbWV0ZXJzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU1NMU2VydmVyU29ja2V0RmFjdG9yeSBlbmdpbmVHZXRTZXJ2ZXJTb2NrZXRGYWN0b3J5KCkgeworICAgICAgICBpZiAoc3NsUGFyYW1ldGVycyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJTU0xDb250ZXh0IGlzIG5vdCBpbml0aWFsaXplZC4iKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IE9wZW5TU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5SW1wbChzc2xQYXJhbWV0ZXJzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9PcGVuU1NMTWVzc2FnZURpZ2VzdEpESy5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvT3BlblNTTE1lc3NhZ2VEaWdlc3RKREsuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYTQzMWJkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvT3BlblNTTE1lc3NhZ2VEaWdlc3RKREsuamF2YQpAQCAtMCwwICsxLDE1NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKKworLyoqCisgKiBJbXBsZW1lbnRzIHRoZSBKREsgTWVzc2FnZURpZ2VzdCBpbnRlcmZhY2UgdXNpbmcgT3BlblNTTCdzIEVWUCBBUEkuCisgKi8KK3B1YmxpYyBjbGFzcyBPcGVuU1NMTWVzc2FnZURpZ2VzdEpESyBleHRlbmRzIE1lc3NhZ2VEaWdlc3QgaW1wbGVtZW50cyBDbG9uZWFibGUgeworCisgICAgLyoqCisgICAgICogSG9sZHMgYSBwb2ludGVyIHRvIHRoZSBuYXRpdmUgbWVzc2FnZSBkaWdlc3QgY29udGV4dC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBjdHg7CisKKyAgICAvKioKKyAgICAgKiBIb2xkcyB0aGUgRVZQX01EIGZvciB0aGUgaGFzaGluZyBhbGdvcml0aG0sIGUuZy4gRVZQX2dldF9kaWdlc3RieW5hbWUoInNoYTEiKTsKKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBldnBfbWQ7CisKKyAgICAvKioKKyAgICAgKiBIb2xkcyB0aGUgb3V0cHV0IHNpemUgb2YgdGhlIG1lc3NhZ2UgZGlnZXN0LgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgaW50IHNpemU7CisKKyAgICAvKioKKyAgICAgKiBIb2xkcyBhIGR1bW15IGJ1ZmZlciBmb3Igd3JpdGluZyBzaW5nbGUgYnl0ZXMgdG8gdGhlIGRpZ2VzdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBzaW5nbGVCeXRlID0gbmV3IGJ5dGVbMV07CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IE9wZW5TU0xNZXNzYWdlRGlnZXN0IGluc3RhbmNlIGZvciB0aGUgZ2l2ZW4gYWxnb3JpdGhtCisgICAgICogbmFtZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIE9wZW5TU0xNZXNzYWdlRGlnZXN0SkRLKFN0cmluZyBhbGdvcml0aG0sIGludCBldnBfbWQsIGludCBzaXplKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKGFsZ29yaXRobSk7CisgICAgICAgIHRoaXMuZXZwX21kID0gZXZwX21kOworICAgICAgICB0aGlzLnNpemUgPSBzaXplOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVJlc2V0KCkgeworICAgICAgICBmcmVlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBlbmdpbmVHZXREaWdlc3RMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBzaXplOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShieXRlIGlucHV0KSB7CisgICAgICAgIHNpbmdsZUJ5dGVbMF0gPSBpbnB1dDsKKyAgICAgICAgZW5naW5lVXBkYXRlKHNpbmdsZUJ5dGUsIDAsIDEpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShieXRlW10gaW5wdXQsIGludCBvZmZzZXQsIGludCBsZW4pIHsKKyAgICAgICAgTmF0aXZlQ3J5cHRvLkVWUF9EaWdlc3RVcGRhdGUoZ2V0Q3R4KCksIGlucHV0LCBvZmZzZXQsIGxlbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVEaWdlc3QoKSB7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtzaXplXTsKKyAgICAgICAgTmF0aXZlQ3J5cHRvLkVWUF9EaWdlc3RGaW5hbChnZXRDdHgoKSwgcmVzdWx0LCAwKTsKKyAgICAgICAgY3R4ID0gMDsgLy8gRVZQX0RpZ2VzdEZpbmFsIGZyZWVzIHRoZSBjb250ZXh0IGFzIGEgc2lkZSBlZmZlY3QKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgT3BlblNTTE1lc3NhZ2VEaWdlc3RKREsgZCA9IChPcGVuU1NMTWVzc2FnZURpZ2VzdEpESykgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgZC5jdHggPSBOYXRpdmVDcnlwdG8uRVZQX01EX0NUWF9jb3B5KGdldEN0eCgpKTsKKyAgICAgICAgcmV0dXJuIGQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgZ2V0Q3R4KCkgeworICAgICAgICBpZiAoY3R4ID09IDApIHsKKyAgICAgICAgICAgIGN0eCA9IE5hdGl2ZUNyeXB0by5FVlBfRGlnZXN0SW5pdChldnBfbWQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjdHg7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGZyZWUoKSB7CisgICAgICAgIGlmIChjdHggIT0gMCkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLkVWUF9NRF9DVFhfZGVzdHJveShjdHgpOworICAgICAgICAgICAgY3R4ID0gMDsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgZnJlZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc3VwZXIuZmluYWxpemUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTUQ1IGV4dGVuZHMgT3BlblNTTE1lc3NhZ2VEaWdlc3RKREsgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRVZQX01EID0gTmF0aXZlQ3J5cHRvLkVWUF9nZXRfZGlnZXN0YnluYW1lKCJtZDUiKTsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNJWkUgPSBOYXRpdmVDcnlwdG8uRVZQX01EX3NpemUoRVZQX01EKTsKKyAgICAgICAgcHVibGljIE1ENSgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIoIk1ENSIsRVZQX01ELCBTSVpFKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgU0hBMSBleHRlbmRzIE9wZW5TU0xNZXNzYWdlRGlnZXN0SkRLIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEVWUF9NRCA9IE5hdGl2ZUNyeXB0by5FVlBfZ2V0X2RpZ2VzdGJ5bmFtZSgic2hhMSIpOworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0laRSA9IE5hdGl2ZUNyeXB0by5FVlBfTURfc2l6ZShFVlBfTUQpOworICAgICAgICBwdWJsaWMgU0hBMSgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIoIlNIQS0xIiwgRVZQX01ELCBTSVpFKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgU0hBMjU2IGV4dGVuZHMgT3BlblNTTE1lc3NhZ2VEaWdlc3RKREsgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRVZQX01EID0gTmF0aXZlQ3J5cHRvLkVWUF9nZXRfZGlnZXN0YnluYW1lKCJzaGEyNTYiKTsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNJWkUgPSBOYXRpdmVDcnlwdG8uRVZQX01EX3NpemUoRVZQX01EKTsKKyAgICAgICAgcHVibGljIFNIQTI1NigpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIoIlNIQS0yNTYiLCBFVlBfTUQsIFNJWkUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBTSEEzODQgZXh0ZW5kcyBPcGVuU1NMTWVzc2FnZURpZ2VzdEpESyB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBFVlBfTUQgPSBOYXRpdmVDcnlwdG8uRVZQX2dldF9kaWdlc3RieW5hbWUoInNoYTM4NCIpOworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0laRSA9IE5hdGl2ZUNyeXB0by5FVlBfTURfc2l6ZShFVlBfTUQpOworICAgICAgICBwdWJsaWMgU0hBMzg0KCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcigiU0hBLTM4NCIsIEVWUF9NRCwgU0laRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFNIQTUxMiBleHRlbmRzIE9wZW5TU0xNZXNzYWdlRGlnZXN0SkRLIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEVWUF9NRCA9IE5hdGl2ZUNyeXB0by5FVlBfZ2V0X2RpZ2VzdGJ5bmFtZSgic2hhNTEyIik7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTSVpFID0gTmF0aXZlQ3J5cHRvLkVWUF9NRF9zaXplKEVWUF9NRCk7CisgICAgICAgIHB1YmxpYyBTSEE1MTIoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyKCJTSEEtNTEyIiwgRVZQX01ELCBTSVpFKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL09wZW5TU0xQcm92aWRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvT3BlblNTTFByb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGM4YWQzYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL09wZW5TU0xQcm92aWRlci5qYXZhCkBAIC0wLDAgKzEsNTkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworCitwdWJsaWMgZmluYWwgY2xhc3MgT3BlblNTTFByb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXIgeworCisgICAgcHVibGljIE9wZW5TU0xQcm92aWRlcigpIHsKKyAgICAgICAgc3VwZXIoIkFuZHJvaWRPcGVuU1NMIiwgMS4wLCAiQW5kcm9pZCdzIE9wZW5TU0wtYmFja2VkIHNlY3VyaXR5IHByb3ZpZGVyIik7CisKKyAgICAgICAgcHV0KCJTU0xDb250ZXh0LlNTTCIsIE9wZW5TU0xDb250ZXh0SW1wbC5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwdXQoIlNTTENvbnRleHQuU1NMdjMiLCBPcGVuU1NMQ29udGV4dEltcGwuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgcHV0KCJTU0xDb250ZXh0LlRMUyIsIE9wZW5TU0xDb250ZXh0SW1wbC5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwdXQoIlNTTENvbnRleHQuVExTdjEiLCBPcGVuU1NMQ29udGV4dEltcGwuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgcHV0KCJTU0xDb250ZXh0LkRlZmF1bHQiLCBEZWZhdWx0U1NMQ29udGV4dEltcGwuY2xhc3MuZ2V0TmFtZSgpKTsKKworICAgICAgICBwdXQoIk1lc3NhZ2VEaWdlc3QuU0hBLTEiLAorICAgICAgICAgICAgIm9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2UuT3BlblNTTE1lc3NhZ2VEaWdlc3RKREskU0hBMSIpOworICAgICAgICBwdXQoIkFsZy5BbGlhcy5NZXNzYWdlRGlnZXN0LlNIQTEiLCAiU0hBLTEiKTsKKyAgICAgICAgcHV0KCJBbGcuQWxpYXMuTWVzc2FnZURpZ2VzdC5TSEEiLCAiU0hBLTEiKTsKKyAgICAgICAgcHV0KCJBbGcuQWxpYXMuTWVzc2FnZURpZ2VzdC4xLjMuMTQuMy4yLjI2IiwgIlNIQS0xIik7CisKKyAgICAgICAgcHV0KCJNZXNzYWdlRGlnZXN0LlNIQS0yNTYiLAorICAgICAgICAgICAgIm9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2UuT3BlblNTTE1lc3NhZ2VEaWdlc3RKREskU0hBMjU2Iik7CisgICAgICAgIHB1dCgiQWxnLkFsaWFzLk1lc3NhZ2VEaWdlc3QuU0hBMjU2IiwgIlNIQS0yNTYiKTsKKyAgICAgICAgcHV0KCJBbGcuQWxpYXMuTWVzc2FnZURpZ2VzdC4yLjE2Ljg0MC4xLjEwMS4zLjQuMi4xIiwgIlNIQS0yNTYiKTsKKworICAgICAgICBwdXQoIk1lc3NhZ2VEaWdlc3QuU0hBLTM4NCIsCisgICAgICAgICAgICAib3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZS5PcGVuU1NMTWVzc2FnZURpZ2VzdEpESyRTSEEzODQiKTsKKyAgICAgICAgcHV0KCJBbGcuQWxpYXMuTWVzc2FnZURpZ2VzdC5TSEEzODQiLCAiU0hBLTM4NCIpOworICAgICAgICBwdXQoIkFsZy5BbGlhcy5NZXNzYWdlRGlnZXN0LjIuMTYuODQwLjEuMTAxLjMuNC4yLjIiLCAiU0hBLTM4NCIpOworCisgICAgICAgIHB1dCgiTWVzc2FnZURpZ2VzdC5TSEEtNTEyIiwKKyAgICAgICAgICAgICJvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlLk9wZW5TU0xNZXNzYWdlRGlnZXN0SkRLJFNIQTUxMiIpOworICAgICAgICBwdXQoIkFsZy5BbGlhcy5NZXNzYWdlRGlnZXN0LlNIQTUxMiIsICJTSEEtNTEyIik7CisgICAgICAgIHB1dCgiQWxnLkFsaWFzLk1lc3NhZ2VEaWdlc3QuMi4xNi44NDAuMS4xMDEuMy40LjIuMyIsICJTSEEtNTEyIik7CisKKyAgICAgICAgcHV0KCJNZXNzYWdlRGlnZXN0Lk1ENSIsCisgICAgICAgICAgICAib3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZS5PcGVuU1NMTWVzc2FnZURpZ2VzdEpESyRNRDUiKTsKKyAgICAgICAgcHV0KCJBbGcuQWxpYXMuTWVzc2FnZURpZ2VzdC4xLjIuODQwLjExMzU0OS4yLjUiLCAiTUQ1Iik7CisKKyAgICAgICAgLy8gVE9ETyBGbHVzaCBvdXQgaW1wbGVtZW50YXRpb24gb2YgT3BlblNTTFNpZ25hdHVyZSBzbyBpdCBjYW4gYmUgcmVnaXN0ZXJlZCBoZXJlCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvT3BlblNTTFNlcnZlclNvY2tldEZhY3RvcnlJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9PcGVuU1NMU2VydmVyU29ja2V0RmFjdG9yeUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jM2NkYWFkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvT3BlblNTTFNlcnZlclNvY2tldEZhY3RvcnlJbXBsLmphdmEKQEAgLTAsMCArMSw3NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU2VydmVyU29ja2V0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5TWFuYWdlbWVudEV4Y2VwdGlvbjsKKworcHVibGljIGNsYXNzIE9wZW5TU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5SW1wbCBleHRlbmRzIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0RmFjdG9yeSB7CisKKyAgICBwcml2YXRlIFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnM7CisgICAgcHJpdmF0ZSBJT0V4Y2VwdGlvbiBpbnN0YW50aWF0aW9uRXhjZXB0aW9uOworCisgICAgcHVibGljIE9wZW5TU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5SW1wbCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoaXMuc3NsUGFyYW1ldGVycyA9IFNTTFBhcmFtZXRlcnNJbXBsLmdldERlZmF1bHQoKTsKKyAgICAgICAgICAgIHRoaXMuc3NsUGFyYW1ldGVycy5zZXRVc2VDbGllbnRNb2RlKGZhbHNlKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpbnN0YW50aWF0aW9uRXhjZXB0aW9uID0KKyAgICAgICAgICAgICAgICBuZXcgSU9FeGNlcHRpb24oIkRlbGF5ZWQgaW5zdGFudGlhdGlvbiBleGNlcHRpb246Iik7CisgICAgICAgICAgICBpbnN0YW50aWF0aW9uRXhjZXB0aW9uLmluaXRDYXVzZShlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPcGVuU1NMU2VydmVyU29ja2V0RmFjdG9yeUltcGwoU1NMUGFyYW1ldGVyc0ltcGwgc3NsUGFyYW1ldGVycykgeworICAgICAgICB0aGlzLnNzbFBhcmFtZXRlcnMgPSAoU1NMUGFyYW1ldGVyc0ltcGwpIHNzbFBhcmFtZXRlcnMuY2xvbmUoKTsKKyAgICAgICAgdGhpcy5zc2xQYXJhbWV0ZXJzLnNldFVzZUNsaWVudE1vZGUoZmFsc2UpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXREZWZhdWx0Q2lwaGVyU3VpdGVzKCkgeworICAgICAgICByZXR1cm4gTmF0aXZlQ3J5cHRvLmdldERlZmF1bHRDaXBoZXJTdWl0ZXMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkgeworICAgICAgICByZXR1cm4gTmF0aXZlQ3J5cHRvLmdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpOworICAgIH0KKworICAgIHB1YmxpYyBTZXJ2ZXJTb2NrZXQgY3JlYXRlU2VydmVyU29ja2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBPcGVuU1NMU2VydmVyU29ja2V0SW1wbCgoU1NMUGFyYW1ldGVyc0ltcGwpIHNzbFBhcmFtZXRlcnMuY2xvbmUoKSk7CisgICAgfQorCisgICAgcHVibGljIFNlcnZlclNvY2tldCBjcmVhdGVTZXJ2ZXJTb2NrZXQoaW50IHBvcnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgT3BlblNTTFNlcnZlclNvY2tldEltcGwocG9ydCwgKFNTTFBhcmFtZXRlcnNJbXBsKSBzc2xQYXJhbWV0ZXJzLmNsb25lKCkpOworICAgIH0KKworICAgIHB1YmxpYyBTZXJ2ZXJTb2NrZXQgY3JlYXRlU2VydmVyU29ja2V0KGludCBwb3J0LCBpbnQgYmFja2xvZykKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgT3BlblNTTFNlcnZlclNvY2tldEltcGwocG9ydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWNrbG9nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChTU0xQYXJhbWV0ZXJzSW1wbCkgc3NsUGFyYW1ldGVycy5jbG9uZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU2VydmVyU29ja2V0IGNyZWF0ZVNlcnZlclNvY2tldChpbnQgcG9ydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYmFja2xvZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcyBpQWRkcmVzcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBPcGVuU1NMU2VydmVyU29ja2V0SW1wbChwb3J0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tsb2csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaUFkZHJlc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFNTTFBhcmFtZXRlcnNJbXBsKSBzc2xQYXJhbWV0ZXJzLmNsb25lKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL09wZW5TU0xTZXJ2ZXJTb2NrZXRJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9PcGVuU1NMU2VydmVyU29ja2V0SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIwMjE5ZTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9PcGVuU1NMU2VydmVyU29ja2V0SW1wbC5qYXZhCkBAIC0wLDAgKzEsMjUzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5FQ1ByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLkRTQVByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLlJTQVByaXZhdGVLZXk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFeGNlcHRpb247CisKKy8qKgorICogT3BlblNTTC1iYXNlZCBpbXBsZW1lbnRhdGlvbiBvZiBzZXJ2ZXIgc29ja2V0cy4KKyAqCisgKiBUaGlzIGNsYXNzIG9ubHkgc3VwcG9ydHMgU1NMdjMgYW5kIFRMU3YxLiBUaGlzIHNob3VsZCBiZSBkb2N1bWVudGVkIGVsc2V3aGVyZQorICogbGF0ZXIsIGZvciBleGFtcGxlIGluIHRoZSBwYWNrYWdlLmh0bWwgb3IgYSBzZXBhcmF0ZSByZWZlcmVuY2UgZG9jdW1lbnQuCisgKi8KK3B1YmxpYyBjbGFzcyBPcGVuU1NMU2VydmVyU29ja2V0SW1wbCBleHRlbmRzIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0IHsKKyAgICBwcml2YXRlIGZpbmFsIFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnM7CisgICAgcHJpdmF0ZSBTdHJpbmdbXSBlbmFibGVkUHJvdG9jb2xzID0gTmF0aXZlQ3J5cHRvLmdldFN1cHBvcnRlZFByb3RvY29scygpOworICAgIHByaXZhdGUgU3RyaW5nW10gZW5hYmxlZENpcGhlclN1aXRlcyA9IE5hdGl2ZUNyeXB0by5nZXREZWZhdWx0Q2lwaGVyU3VpdGVzKCk7CisgICAgcHJpdmF0ZSBTdHJpbmdbXSBlbmFibGVkQ29tcHJlc3Npb25NZXRob2RzID0gTmF0aXZlQ3J5cHRvLmdldERlZmF1bHRDb21wcmVzc2lvbk1ldGhvZHMoKTsKKworICAgIHByb3RlY3RlZCBPcGVuU1NMU2VydmVyU29ja2V0SW1wbChTU0xQYXJhbWV0ZXJzSW1wbCBzc2xQYXJhbWV0ZXJzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLnNzbFBhcmFtZXRlcnMgPSBzc2xQYXJhbWV0ZXJzOworICAgIH0KKworICAgIHByb3RlY3RlZCBPcGVuU1NMU2VydmVyU29ja2V0SW1wbChpbnQgcG9ydCwgU1NMUGFyYW1ldGVyc0ltcGwgc3NsUGFyYW1ldGVycykKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIocG9ydCk7CisgICAgICAgIHRoaXMuc3NsUGFyYW1ldGVycyA9IHNzbFBhcmFtZXRlcnM7CisgICAgfQorCisgICAgcHJvdGVjdGVkIE9wZW5TU0xTZXJ2ZXJTb2NrZXRJbXBsKGludCBwb3J0LCBpbnQgYmFja2xvZywgU1NMUGFyYW1ldGVyc0ltcGwgc3NsUGFyYW1ldGVycykKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIocG9ydCwgYmFja2xvZyk7CisgICAgICAgIHRoaXMuc3NsUGFyYW1ldGVycyA9IHNzbFBhcmFtZXRlcnM7CisgICAgfQorCisgICAgcHJvdGVjdGVkIE9wZW5TU0xTZXJ2ZXJTb2NrZXRJbXBsKGludCBwb3J0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYmFja2xvZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MgaUFkZHJlc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnMpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKHBvcnQsIGJhY2tsb2csIGlBZGRyZXNzKTsKKyAgICAgICAgdGhpcy5zc2xQYXJhbWV0ZXJzID0gc3NsUGFyYW1ldGVyczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oKSB7CisgICAgICAgIHJldHVybiBzc2xQYXJhbWV0ZXJzLmdldEVuYWJsZVNlc3Npb25DcmVhdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEVuYWJsZVNlc3Npb25DcmVhdGlvbihib29sZWFuIGZsYWcpIHsKKyAgICAgICAgc3NsUGFyYW1ldGVycy5zZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oZmxhZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIG5hbWVzIG9mIHRoZSBwcm90b2NvbHMnIHZlcnNpb25zIHRoYXQgbWF5IGJlIHVzZWQgb24gdGhpcyBTU0wKKyAgICAgKiBjb25uZWN0aW9uLgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgcHJvdG9jb2xzIG5hbWVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ1tdIGdldFN1cHBvcnRlZFByb3RvY29scygpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUNyeXB0by5nZXRTdXBwb3J0ZWRQcm90b2NvbHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgbmFtZXMgb2YgdGhlIHByb3RvY29scycgdmVyc2lvbnMgdGhhdCBpbiB1c2Ugb24gdGhpcyBTU0wgY29ubmVjdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgcHJvdG9jb2xzIG5hbWVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ1tdIGdldEVuYWJsZWRQcm90b2NvbHMoKSB7CisgICAgICAgIHJldHVybiBlbmFibGVkUHJvdG9jb2xzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgZW5hYmxlcyB0aGUgcHJvdG9jb2xzJyB2ZXJzaW9ucyBsaXN0ZWQgYnkKKyAgICAgKiBnZXRTdXBwb3J0ZWRQcm90b2NvbHMoKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcm90b2NvbHMgbmFtZXMgb2YgYWxsIHRoZSBwcm90b2NvbHMgdG8gZW5hYmxlLgorICAgICAqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2hlbiBvbmUgb3IgbW9yZSBvZiB0aGUgbmFtZXMgaW4gdGhlCisgICAgICogICAgICAgICAgICAgYXJyYXkgYXJlIG5vdCBzdXBwb3J0ZWQsIG9yIHdoZW4gdGhlIGFycmF5IGlzIG51bGwuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RW5hYmxlZFByb3RvY29scyhTdHJpbmdbXSBwcm90b2NvbHMpIHsKKyAgICAgICAgZW5hYmxlZFByb3RvY29scyA9IE5hdGl2ZUNyeXB0by5jaGVja0VuYWJsZWRQcm90b2NvbHMocHJvdG9jb2xzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkgeworICAgICAgICByZXR1cm4gTmF0aXZlQ3J5cHRvLmdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCkgeworICAgICAgICByZXR1cm4gZW5hYmxlZENpcGhlclN1aXRlcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGVuYWJsZXMgdGhlIGNpcGhlciBzdWl0ZXMgbGlzdGVkIGJ5CisgICAgICogZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3VpdGVzIHRoZSBuYW1lcyBvZiBhbGwgdGhlIGNpcGhlciBzdWl0ZXMgdG8gZW5hYmxlCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2hlbiBvbmUgb3IgbW9yZSBvZiB0aGUgY2lwaGVycyBpbiBhcnJheQorICAgICAqICAgICAgICAgc3VpdGVzIGFyZSBub3Qgc3VwcG9ydGVkLCBvciB3aGVuIHRoZSBhcnJheSBpcyBudWxsLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoU3RyaW5nW10gc3VpdGVzKSB7CisgICAgICAgIGVuYWJsZWRDaXBoZXJTdWl0ZXMgPSBOYXRpdmVDcnlwdG8uY2hlY2tFbmFibGVkQ2lwaGVyU3VpdGVzKHN1aXRlcyk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZ1tdIGdldFN1cHBvcnRlZENvbXByZXNzaW9uTWV0aG9kcygpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUNyeXB0by5nZXRTdXBwb3J0ZWRDb21wcmVzc2lvbk1ldGhvZHMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RW5hYmxlZENvbXByZXNzaW9uTWV0aG9kcygpIHsKKyAgICAgICAgcmV0dXJuIGVuYWJsZWRDb21wcmVzc2lvbk1ldGhvZHMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBlbmFibGVzIHRoZSBjb21wcmVzc2lvbiBtZXRob2RzIGxpc3RlZCBieQorICAgICAqIGdldFN1cHBvcnRlZENvbXByZXNzaW9uTWV0aG9kcygpLgorICAgICAqCisgICAgICogQHBhcmFtIHN1aXRlcyB0aGUgbmFtZXMgb2YgYWxsIHRoZSBjb21wcmVzc2lvbiBtZXRob2RzIHRvIGVuYWJsZQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gb25lIG9yIG1vcmUgb2YgdGhlIGNpcGhlcnMgaW4gYXJyYXkKKyAgICAgKiAgICAgICAgIHN1aXRlcyBhcmUgbm90IHN1cHBvcnRlZCwgb3Igd2hlbiB0aGUgYXJyYXkgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRFbmFibGVkQ29tcHJlc3Npb25NZXRob2RzKFN0cmluZ1tdIG1ldGhvZHMpIHsKKyAgICAgICAgZW5hYmxlZENvbXByZXNzaW9uTWV0aG9kcyA9IE5hdGl2ZUNyeXB0by5jaGVja0VuYWJsZWRDb21wcmVzc2lvbk1ldGhvZHMobWV0aG9kcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0V2FudENsaWVudEF1dGgoKSB7CisgICAgICAgIHJldHVybiBzc2xQYXJhbWV0ZXJzLmdldFdhbnRDbGllbnRBdXRoKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0V2FudENsaWVudEF1dGgoYm9vbGVhbiB3YW50KSB7CisgICAgICAgIHNzbFBhcmFtZXRlcnMuc2V0V2FudENsaWVudEF1dGgod2FudCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0TmVlZENsaWVudEF1dGgoKSB7CisgICAgICAgIHJldHVybiBzc2xQYXJhbWV0ZXJzLmdldE5lZWRDbGllbnRBdXRoKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0TmVlZENsaWVudEF1dGgoYm9vbGVhbiBuZWVkKSB7CisgICAgICAgIHNzbFBhcmFtZXRlcnMuc2V0TmVlZENsaWVudEF1dGgobmVlZCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0VXNlQ2xpZW50TW9kZShib29sZWFuIG1vZGUpIHsKKyAgICAgICAgc3NsUGFyYW1ldGVycy5zZXRVc2VDbGllbnRNb2RlKG1vZGUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGdldFVzZUNsaWVudE1vZGUoKSB7CisgICAgICAgIHJldHVybiBzc2xQYXJhbWV0ZXJzLmdldFVzZUNsaWVudE1vZGUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU29ja2V0IGFjY2VwdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgaWYgKCFzc2xQYXJhbWV0ZXJzLmdldFVzZUNsaWVudE1vZGUoKSkgeworICAgICAgICAgICAgY2hlY2tFbmFibGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgICAgIH0KKworICAgICAgICBPcGVuU1NMU29ja2V0SW1wbCBzb2NrZXQgPSBuZXcgT3BlblNTTFNvY2tldEltcGwoc3NsUGFyYW1ldGVycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWRQcm90b2NvbHMuY2xvbmUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWRDaXBoZXJTdWl0ZXMuY2xvbmUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWRDb21wcmVzc2lvbk1ldGhvZHMuY2xvbmUoKSk7CisgICAgICAgIGltcGxBY2NlcHQoc29ja2V0KTsKKyAgICAgICAgcmV0dXJuIHNvY2tldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayBpZiBhbnkgb2YgdGhlIGVuYWJsZWQgY2lwaGVyIHN1aXRlcyBoYXMgYSBjaGFuY2UgdG8gd29yay4KKyAgICAgKiBOb3QgMTAwJSBhY2N1cmF0ZSwganVzdCBhIHVzZWZ1bCBkaWFnbm9zdGljIHRoYXQgdGhlIFJJIGRvZXMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrRW5hYmxlZENpcGhlclN1aXRlcygpIHRocm93cyBTU0xFeGNlcHRpb24geworICAgICAgICAvKiBMb29wIG92ZXIgYWxsIGVuYWJsZWQgY2lwaGVyIHN1aXRlcy4gSWYgd2UgZmluZCBhIHByb2JsZW0sCisgICAgICAgICAqIHdlIGp1c3QgY29udGludWUgdG8gdGhlIG5leHQgb25lLiBJZiB3ZSBmaW5kIG9uZSB0aGF0IGNvdWxkCisgICAgICAgICAqIHdvcmssIHdlIHJldHVybi4gVGhpcyBiYXNpY2FsbHkgbWFrZXMgc3VyZSB0aGUgY2FsbGVyIGhhcworICAgICAgICAgKiBjb25maWd1cmVkIHNvbWUgYXBwcm9wcmlhdGUgY2VydGlmaWNhdGUva2V5IHVubGVzcworICAgICAgICAgKiBhbiBhbm9ueW1vdXMgY2lwaGVyIGlzIHBpY2tlZC4KKyAgICAgICAgICovCisgICAgICAgIGZvciAoU3RyaW5nIGVuYWJsZWRDaXBoZXJTdWl0ZSA6IGVuYWJsZWRDaXBoZXJTdWl0ZXMpIHsKKyAgICAgICAgICAgIGlmIChlbmFibGVkQ2lwaGVyU3VpdGUuZXF1YWxzKE5hdGl2ZUNyeXB0by5UTFNfRU1QVFlfUkVORUdPVElBVElPTl9JTkZPX1NDU1YpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTdHJpbmcga2V5VHlwZSA9IENpcGhlclN1aXRlLmdldEJ5TmFtZShlbmFibGVkQ2lwaGVyU3VpdGUpLmdldFNlcnZlcktleVR5cGUoKTsKKyAgICAgICAgICAgIGlmIChrZXlUeXBlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyBhbm9ueW1vdXMgYWx3YXlzIHdvcmsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoa2V5VHlwZS5lcXVhbHMoQ2lwaGVyU3VpdGUuS0VZX1RZUEVfUlNBKQorICAgICAgICAgICAgICAgICAgICB8fCBrZXlUeXBlLmVxdWFscyhDaXBoZXJTdWl0ZS5LRVlfVFlQRV9ESF9SU0EpKSB7CisgICAgICAgICAgICAgICAgaWYgKGNoZWNrRm9yUHJpdmF0ZUtleShrZXlUeXBlLCBSU0FQcml2YXRlS2V5LmNsYXNzKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGtleVR5cGUuZXF1YWxzKENpcGhlclN1aXRlLktFWV9UWVBFX0RTQSkKKyAgICAgICAgICAgICAgICAgICAgfHwga2V5VHlwZS5lcXVhbHMoQ2lwaGVyU3VpdGUuS0VZX1RZUEVfREhfRFNBKSkgeworICAgICAgICAgICAgICAgIGlmIChjaGVja0ZvclByaXZhdGVLZXkoa2V5VHlwZSwgRFNBUHJpdmF0ZUtleS5jbGFzcykpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChrZXlUeXBlLmVxdWFscyhDaXBoZXJTdWl0ZS5LRVlfVFlQRV9FQykKKyAgICAgICAgICAgICAgICAgICAgfHwga2V5VHlwZS5lcXVhbHMoQ2lwaGVyU3VpdGUuS0VZX1RZUEVfRUNfUlNBKQorICAgICAgICAgICAgICAgICAgICB8fCBrZXlUeXBlLmVxdWFscyhDaXBoZXJTdWl0ZS5LRVlfVFlQRV9FQ19FQykpIHsKKyAgICAgICAgICAgICAgICBpZiAoY2hlY2tGb3JQcml2YXRlS2V5KGtleVR5cGUsIEVDUHJpdmF0ZUtleS5jbGFzcykpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIlVua25vd24ga2V5IHR5cGUgIiArIGtleVR5cGUpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBTU0xFeGNlcHRpb24oIkNvdWxkIG5vdCBmaW5kIGFueSBrZXkgc3RvcmUgZW50cmllcyAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAidG8gc3VwcG9ydCB0aGUgZW5hYmxlZCBjaXBoZXIgc3VpdGVzLiIpOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBjaGVja0ZvclByaXZhdGVLZXkoU3RyaW5nIGtleVR5cGUsIENsYXNzIGtleUNsYXNzKSB7CisgICAgICAgIFN0cmluZyBhbGlhcyA9IHNzbFBhcmFtZXRlcnMuZ2V0S2V5TWFuYWdlcigpLmNob29zZVNlcnZlckFsaWFzKGtleVR5cGUsIG51bGwsIG51bGwpOworICAgICAgICBpZiAoYWxpYXMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIFByaXZhdGVLZXkga2V5ID0gc3NsUGFyYW1ldGVycy5nZXRLZXlNYW5hZ2VyKCkuZ2V0UHJpdmF0ZUtleShhbGlhcyk7CisgICAgICAgIHJldHVybiAoa2V5ICE9IG51bGwgJiYga2V5Q2xhc3MuaXNBc3NpZ25hYmxlRnJvbShrZXkuZ2V0Q2xhc3MoKSkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL09wZW5TU0xTZXNzaW9uSW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvT3BlblNTTFNlc3Npb25JbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTE5NGEzOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL09wZW5TU0xTZXNzaW9uSW1wbC5qYXZhCkBAIC0wLDAgKzEsNDc1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbkJpbmRpbmdFdmVudDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uQ29udGV4dDsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworCisvKioKKyAqIEltcGxlbWVudGF0aW9uIG9mIHRoZSBjbGFzcyBPcGVuU1NMU2Vzc2lvbkltcGwKKyAqIGJhc2VkIG9uIE9wZW5TU0wuCisgKi8KK3B1YmxpYyBjbGFzcyBPcGVuU1NMU2Vzc2lvbkltcGwgaW1wbGVtZW50cyBTU0xTZXNzaW9uIHsKKworICAgIHByaXZhdGUgbG9uZyBjcmVhdGlvblRpbWUgPSAwOworICAgIGxvbmcgbGFzdEFjY2Vzc2VkVGltZSA9IDA7CisgICAgZmluYWwgWDUwOUNlcnRpZmljYXRlW10gbG9jYWxDZXJ0aWZpY2F0ZXM7CisgICAgZmluYWwgWDUwOUNlcnRpZmljYXRlW10gcGVlckNlcnRpZmljYXRlczsKKworICAgIHByaXZhdGUgYm9vbGVhbiBpc1ZhbGlkID0gdHJ1ZTsKKyAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIE9iamVjdD4gdmFsdWVzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBPYmplY3Q+KCk7CisgICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZheC5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZVtdIHBlZXJDZXJ0aWZpY2F0ZUNoYWluOworICAgIHByb3RlY3RlZCBpbnQgc3NsU2Vzc2lvbk5hdGl2ZVBvaW50ZXI7CisgICAgcHJpdmF0ZSBTdHJpbmcgcGVlckhvc3Q7CisgICAgcHJpdmF0ZSBpbnQgcGVlclBvcnQgPSAtMTsKKyAgICBwcml2YXRlIFN0cmluZyBjaXBoZXJTdWl0ZTsKKyAgICBwcml2YXRlIFN0cmluZyBwcm90b2NvbDsKKyAgICBwcml2YXRlIFN0cmluZyBjb21wcmVzc2lvbk1ldGhvZDsKKyAgICBwcml2YXRlIEFic3RyYWN0U2Vzc2lvbkNvbnRleHQgc2Vzc2lvbkNvbnRleHQ7CisgICAgcHJpdmF0ZSBieXRlW10gaWQ7CisKKyAgICAvKioKKyAgICAgKiBDbGFzcyBjb25zdHJ1Y3RvciBjcmVhdGVzIGFuIFNTTCBzZXNzaW9uIGNvbnRleHQgZ2l2ZW4gdGhlIGFwcHJvcHJpYXRlCisgICAgICogU1NMIHBhcmFtZXRlcnMuCisgICAgICovCisgICAgcHJvdGVjdGVkIE9wZW5TU0xTZXNzaW9uSW1wbChpbnQgc3NsU2Vzc2lvbk5hdGl2ZVBvaW50ZXIsIFg1MDlDZXJ0aWZpY2F0ZVtdIGxvY2FsQ2VydGlmaWNhdGVzLAorICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlW10gcGVlckNlcnRpZmljYXRlcywgU3RyaW5nIHBlZXJIb3N0LCBpbnQgcGVlclBvcnQsCisgICAgICAgICAgICBBYnN0cmFjdFNlc3Npb25Db250ZXh0IHNlc3Npb25Db250ZXh0KSB7CisgICAgICAgIHRoaXMuc3NsU2Vzc2lvbk5hdGl2ZVBvaW50ZXIgPSBzc2xTZXNzaW9uTmF0aXZlUG9pbnRlcjsKKyAgICAgICAgdGhpcy5sb2NhbENlcnRpZmljYXRlcyA9IGxvY2FsQ2VydGlmaWNhdGVzOworICAgICAgICB0aGlzLnBlZXJDZXJ0aWZpY2F0ZXMgPSBwZWVyQ2VydGlmaWNhdGVzOworICAgICAgICB0aGlzLnBlZXJIb3N0ID0gcGVlckhvc3Q7CisgICAgICAgIHRoaXMucGVlclBvcnQgPSBwZWVyUG9ydDsKKyAgICAgICAgdGhpcy5zZXNzaW9uQ29udGV4dCA9IHNlc3Npb25Db250ZXh0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBzZXNzaW9uIGZyb20gYSBieXRlW10gY29udGFpbmluZyBERVIgZGF0YS4gVGhpcworICAgICAqIGFsbG93cyBsb2FkaW5nIHRoZSBzYXZlZCBzZXNzaW9uLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBPcGVuU1NMU2Vzc2lvbkltcGwoYnl0ZVtdIGRlckRhdGEsCisgICAgICAgICAgICBTdHJpbmcgcGVlckhvc3QsIGludCBwZWVyUG9ydCwKKyAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIHBlZXJDZXJ0aWZpY2F0ZXMsCisgICAgICAgICAgICBBYnN0cmFjdFNlc3Npb25Db250ZXh0IHNlc3Npb25Db250ZXh0KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcyhOYXRpdmVDcnlwdG8uZDJpX1NTTF9TRVNTSU9OKGRlckRhdGEpLAorICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgcGVlckNlcnRpZmljYXRlcywKKyAgICAgICAgICAgICBwZWVySG9zdCwKKyAgICAgICAgICAgICBwZWVyUG9ydCwKKyAgICAgICAgICAgICBzZXNzaW9uQ29udGV4dCk7CisgICAgICAgIC8vIFRPRE8gbW92ZSB0aGlzIGNoZWNrIGludG8gbmF0aXZlIGNvZGUgc28gd2UgY2FuIHRocm93IGFuIGVycm9yIHdpdGggbW9yZSBpbmZvcm1hdGlvbgorICAgICAgICBpZiAodGhpcy5zc2xTZXNzaW9uTmF0aXZlUG9pbnRlciA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkludmFsaWQgc2Vzc2lvbiBkYXRhIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBpZGVudGlmaWVyIG9mIHRoZSBhY3R1YWwgU1NMIHNlc3Npb24KKyAgICAgKiBAcmV0dXJuIGFycmF5IG9mIHNlc3Npb25zJyBpZGVudGlmaWVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldElkKCkgeworICAgICAgICBpZiAoaWQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmVzZXRJZCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXNldCB0aGUgaWQgZmllbGQgdG8gdGhlIGN1cnJlbnQgdmFsdWUgZm91bmQgaW4gdGhlIG5hdGl2ZQorICAgICAqIFNTTF9TRVNTSU9OLiBJdCBjYW4gY2hhbmdlIGR1cmluZyB0aGUgbGlmZXRpbWUgb2YgdGhlIHNlc3Npb24KKyAgICAgKiBiZWNhdXNlIHdoaWxlIGEgc2Vzc2lvbiBpcyBjcmVhdGVkIGR1cmluZyBpbml0aWFsIGhhbmRzaGFrZSwKKyAgICAgKiB3aXRoIGhhbmRzaGFrZV9jdXR0aHJvdWdoLCB0aGUgU1NMX2RvX2hhbmRzaGFrZSBtYXkgcmV0dXJuCisgICAgICogYmVmb3JlIHdlIGhhdmUgcmVhZCB0aGUgc2Vzc2lvbiB0aWNrZXQgZnJvbSB0aGUgc2VydmVyIHNpZGUgYW5kCisgICAgICogdGhlcmVmb3JlIGhhdmUgY29tcHV0ZWQgbm8gaWQgYmFzZWQgb24gdGhlIFNIQSBvZiB0aGUgdGlja2V0LgorICAgICAqLworICAgIHZvaWQgcmVzZXRJZCgpIHsKKyAgICAgICAgaWQgPSBOYXRpdmVDcnlwdG8uU1NMX1NFU1NJT05fc2Vzc2lvbl9pZChzc2xTZXNzaW9uTmF0aXZlUG9pbnRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBzZXNzaW9uIG9iamVjdCBpbiBERVIgZm9ybWF0LiBUaGlzIGFsbG93cyBzYXZpbmcgdGhlIHNlc3Npb24KKyAgICAgKiBkYXRhIG9yIHNoYXJpbmcgaXQgd2l0aCBvdGhlciBwcm9jZXNzZXMuCisgICAgICovCisgICAgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIHJldHVybiBOYXRpdmVDcnlwdG8uaTJkX1NTTF9TRVNTSU9OKHNzbFNlc3Npb25OYXRpdmVQb2ludGVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjcmVhdGlvbiB0aW1lIG9mIHRoZSBTU0wgc2Vzc2lvbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBzZXNzaW9uJ3MgY3JlYXRpb24gdGltZSBpbiBtaWxsaXNlY29uZHMgc2luY2UgdGhlIGVwb2NoCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0Q3JlYXRpb25UaW1lKCkgeworICAgICAgICBpZiAoY3JlYXRpb25UaW1lID09IDApIHsKKyAgICAgICAgICAgIGNyZWF0aW9uVGltZSA9IE5hdGl2ZUNyeXB0by5TU0xfU0VTU0lPTl9nZXRfdGltZShzc2xTZXNzaW9uTmF0aXZlUG9pbnRlcik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNyZWF0aW9uVGltZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsYXN0IHRpbWUgdGhpcyBjb25jcmV0ZSBTU0wgc2Vzc2lvbiB3YXMgYWNjZXNzZWQuIEFjY2Vzc2luZworICAgICAqIGhlcmUgaXMgdG8gbWVhbiB0aGF0IGEgbmV3IGNvbm5lY3Rpb24gd2l0aCB0aGUgc2FtZSBTU0wgY29udGV4dCBkYXRhIHdhcworICAgICAqIGVzdGFibGlzaGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc2Vzc2lvbidzIGxhc3QgYWNjZXNzIHRpbWUgaW4gbWlsbGlzZWNvbmRzIHNpbmNlIHRoZSBlcG9jaAorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldExhc3RBY2Nlc3NlZFRpbWUoKSB7CisgICAgICAgIHJldHVybiAobGFzdEFjY2Vzc2VkVGltZSA9PSAwKSA/IGdldENyZWF0aW9uVGltZSgpIDogbGFzdEFjY2Vzc2VkVGltZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsYXJnZXN0IGJ1ZmZlciBzaXplIGZvciB0aGUgYXBwbGljYXRpb24ncyBkYXRhIGJvdW5kIHRvIHRoaXMKKyAgICAgKiBjb25jcmV0ZSBTU0wgc2Vzc2lvbi4KKyAgICAgKiBAcmV0dXJuIHRoZSBsYXJnZXN0IGJ1ZmZlciBzaXplCisgICAgICovCisgICAgcHVibGljIGludCBnZXRBcHBsaWNhdGlvbkJ1ZmZlclNpemUoKSB7CisgICAgICAgIHJldHVybiBTU0xSZWNvcmRQcm90b2NvbC5NQVhfREFUQV9MRU5HVEg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbGFyZ2VzdCBTU0wvVExTIHBhY2tldCBzaXplIG9uZSBjYW4gZXhwZWN0IGZvciB0aGlzIGNvbmNyZXRlCisgICAgICogU1NMIHNlc3Npb24uCisgICAgICogQHJldHVybiB0aGUgbGFyZ2VzdCBwYWNrZXQgc2l6ZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UGFja2V0QnVmZmVyU2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIFNTTFJlY29yZFByb3RvY29sLk1BWF9TU0xfUEFDS0VUX1NJWkU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJpbmNpcGFsIChzdWJqZWN0KSBvZiB0aGlzIGNvbmNyZXRlIFNTTCBzZXNzaW9uIHVzZWQgaW4gdGhlCisgICAgICogaGFuZHNoYWtpbmcgcGhhc2Ugb2YgdGhlIGNvbm5lY3Rpb24uCisgICAgICogQHJldHVybiBhIFg1MDkgY2VydGlmaWNhdGUgb3IgbnVsbCBpZiBubyBwcmluY2lwYWwgd2FzIGRlZmluZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpbmNpcGFsIGdldExvY2FsUHJpbmNpcGFsKCkgeworICAgICAgICBpZiAobG9jYWxDZXJ0aWZpY2F0ZXMgIT0gbnVsbCAmJiBsb2NhbENlcnRpZmljYXRlcy5sZW5ndGggPiAwKSB7CisgICAgICAgICAgICByZXR1cm4gbG9jYWxDZXJ0aWZpY2F0ZXNbMF0uZ2V0U3ViamVjdFg1MDBQcmluY2lwYWwoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2VydGlmaWNhdGUocykgb2YgdGhlIHByaW5jaXBhbCAoc3ViamVjdCkgb2YgdGhpcyBjb25jcmV0ZSBTU0wKKyAgICAgKiBzZXNzaW9uIHVzZWQgaW4gdGhlIGhhbmRzaGFraW5nIHBoYXNlIG9mIHRoZSBjb25uZWN0aW9uLiBUaGUgT3BlblNTTAorICAgICAqIG5hdGl2ZSBtZXRob2Qgc3VwcG9ydHMgb25seSBSU0EgY2VydGlmaWNhdGVzLgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgY2VydGlmaWNhdGVzICh0aGUgbG9jYWwgb25lIGZpcnN0IGFuZCB0aGVuIGV2ZW50dWFsbHkKKyAgICAgKiAgICAgICAgIHRoYXQgb2YgdGhlIGNlcnRpZmljYXRpb24gYXV0aG9yaXR5KSBvciBudWxsIGlmIG5vIGNlcnRpZmljYXRlCisgICAgICogICAgICAgICB3ZXJlIHVzZWQgZHVyaW5nIHRoZSBoYW5kc2hha2luZyBwaGFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVbXSBnZXRMb2NhbENlcnRpZmljYXRlcygpIHsKKyAgICAgICAgcmV0dXJuIGxvY2FsQ2VydGlmaWNhdGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNlcnRpZmljYXRlKHMpIG9mIHRoZSBwZWVyIGluIHRoaXMgU1NMIHNlc3Npb24KKyAgICAgKiB1c2VkIGluIHRoZSBoYW5kc2hha2luZyBwaGFzZSBvZiB0aGUgY29ubmVjdGlvbi4KKyAgICAgKiBQbGVhc2Ugbm90aWNlIGhhdCB0aGlzIG1ldGhvZCBpcyBzdXBlcnNlZGVkIGJ5CisgICAgICogPGNvZGU+Z2V0UGVlckNlcnRpZmljYXRlcygpPC9jb2RlPi4KKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIFg1MDkgY2VydGlmaWNhdGVzICh0aGUgcGVlcidzIG9uZSBmaXJzdCBhbmQgdGhlbgorICAgICAqICAgICAgICAgZXZlbnR1YWxseSB0aGF0IG9mIHRoZSBjZXJ0aWZpY2F0aW9uIGF1dGhvcml0eSkgb3IgbnVsbCBpZiBubworICAgICAqICAgICAgICAgY2VydGlmaWNhdGUgd2VyZSB1c2VkIGR1cmluZyB0aGUgU1NMIGNvbm5lY3Rpb24uCisgICAgICogQHRocm93cyA8Y29kZT5TU0xQZWVyVW52ZXJpZmllZENlcnRpZmljYXRlRXhjZXB0aW9uPC9jb2RlPiBpZiBlaXRoZXIgYQorICAgICAqICAgICAgICAgbm90IFg1MDkgY2VydGlmaWNhdGUgd2FzIHVzZWQgKGkuZS4gS2VyYmVyb3MgY2VydGlmaWNhdGVzKSBvciB0aGUKKyAgICAgKiAgICAgICAgIHBlZXIgY291bGQgbm90IGJlIHZlcmlmaWVkLgorICAgICAqLworICAgIHB1YmxpYyBqYXZheC5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZVtdIGdldFBlZXJDZXJ0aWZpY2F0ZUNoYWluKCkKKyAgICAgICAgICAgIHRocm93cyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrUGVlckNlcnRpZmljYXRlc1ByZXNlbnQoKTsKKyAgICAgICAgamF2YXguc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGVbXSByZXN1bHQgPSBwZWVyQ2VydGlmaWNhdGVDaGFpbjsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBzaW5nbGUtY2hlY2sgaWRpb20KKyAgICAgICAgICAgIHBlZXJDZXJ0aWZpY2F0ZUNoYWluID0gcmVzdWx0ID0gY3JlYXRlUGVlckNlcnRpZmljYXRlQ2hhaW4oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb3ZpZGUgYSB2YWx1ZSB0byBpbml0aWFsaXplIHRoZSB2b2xhdGlsZSBwZWVyQ2VydGlmaWNhdGVDaGFpbgorICAgICAqIGZpZWxkIGJhc2VkIG9uIHRoZSBuYXRpdmUgU1NMX1NFU1NJT04KKyAgICAgKi8KKyAgICBwcml2YXRlIGphdmF4LnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlW10gY3JlYXRlUGVlckNlcnRpZmljYXRlQ2hhaW4oKQorICAgICAgICAgICAgdGhyb3dzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGphdmF4LnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlW10gY2hhaW4KKyAgICAgICAgICAgICAgICAgICAgPSBuZXcgamF2YXguc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGVbcGVlckNlcnRpZmljYXRlcy5sZW5ndGhdOworCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBlZXJDZXJ0aWZpY2F0ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBieXRlW10gZW5jb2RlZCA9IHBlZXJDZXJ0aWZpY2F0ZXNbaV0uZ2V0RW5jb2RlZCgpOworICAgICAgICAgICAgICAgIGNoYWluW2ldID0gamF2YXguc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGUuZ2V0SW5zdGFuY2UoZW5jb2RlZCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gY2hhaW47CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24gZXhjZXB0aW9uID0gbmV3IFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvbi5pbml0Q2F1c2UoZXhjZXB0aW9uKTsKKyAgICAgICAgICAgIHRocm93IGV4Y2VwdGlvbjsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24gZXhjZXB0aW9uID0gbmV3IFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvbi5pbml0Q2F1c2UoZXhjZXB0aW9uKTsKKyAgICAgICAgICAgIHRocm93IGV4Y2VwdGlvbjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgaWRlbnRpdHkgb2YgdGhlIHBlZXIgaW4gdGhpcyBTU0wgc2Vzc2lvbgorICAgICAqIGRldGVybWluZWQgdmlhIGNlcnRpZmljYXRlKHMpLgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgWDUwOSBjZXJ0aWZpY2F0ZXMgKHRoZSBwZWVyJ3Mgb25lIGZpcnN0IGFuZCB0aGVuCisgICAgICogICAgICAgICBldmVudHVhbGx5IHRoYXQgb2YgdGhlIGNlcnRpZmljYXRpb24gYXV0aG9yaXR5KSBvciBudWxsIGlmIG5vCisgICAgICogICAgICAgICBjZXJ0aWZpY2F0ZSB3ZXJlIHVzZWQgZHVyaW5nIHRoZSBTU0wgY29ubmVjdGlvbi4KKyAgICAgKiBAdGhyb3dzIDxjb2RlPlNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uPC9jb2RlPiBpZiBlaXRoZXIgYSBub3QgWDUwOQorICAgICAqICAgICAgICAgY2VydGlmaWNhdGUgd2FzIHVzZWQgKGkuZS4gS2VyYmVyb3MgY2VydGlmaWNhdGVzKSBvciB0aGUgcGVlcgorICAgICAqICAgICAgICAgY291bGQgbm90IGJlIHZlcmlmaWVkLgorICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZVtdIGdldFBlZXJDZXJ0aWZpY2F0ZXMoKSB0aHJvd3MgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24geworICAgICAgICBjaGVja1BlZXJDZXJ0aWZpY2F0ZXNQcmVzZW50KCk7CisgICAgICAgIHJldHVybiBwZWVyQ2VydGlmaWNhdGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRocm93IFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIG9uIG51bGwgb3IgZW1wdHkgcGVlckNlcnRpZmljYXRlcyBhcnJheQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjaGVja1BlZXJDZXJ0aWZpY2F0ZXNQcmVzZW50KCkgdGhyb3dzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBlZXJDZXJ0aWZpY2F0ZXMgPT0gbnVsbCB8fCBwZWVyQ2VydGlmaWNhdGVzLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24oIk5vIHBlZXIgY2VydGlmaWNhdGVzIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgaWRlbnRpdHkgb2YgdGhlIHByaW5jaXBhbCB0aGF0IHdhcyB1c2VkIGJ5IHRoZSBwZWVyIGR1cmluZyB0aGUgU1NMCisgICAgICogaGFuZHNoYWtlIHBoYXNlIGlzIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kLgorICAgICAqIEByZXR1cm4gYSBYNTAwUHJpbmNpcGFsIG9mIHRoZSBsYXN0IGNlcnRpZmljYXRlIGZvciBYNTA5LWJhc2VkCisgICAgICogICAgICAgICBjaXBoZXIgc3VpdGVzLgorICAgICAqIEB0aHJvd3MgPGNvZGU+U1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb248L2NvZGU+IGlmIGVpdGhlciBhIG5vdCBYNTA5CisgICAgICogICAgICAgICBjZXJ0aWZpY2F0ZSB3YXMgdXNlZCAoaS5lLiBLZXJiZXJvcyBjZXJ0aWZpY2F0ZXMpIG9yIHRoZQorICAgICAqICAgICAgICAgcGVlciBkb2VzIG5vdCBleGlzdC4KKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0UGVlclByaW5jaXBhbCgpIHRocm93cyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrUGVlckNlcnRpZmljYXRlc1ByZXNlbnQoKTsKKyAgICAgICAgcmV0dXJuIHBlZXJDZXJ0aWZpY2F0ZXNbMF0uZ2V0U3ViamVjdFg1MDBQcmluY2lwYWwoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgcGVlcidzIGhvc3QgbmFtZSB1c2VkIGluIHRoaXMgU1NMIHNlc3Npb24gaXMgcmV0dXJuZWQuIEl0IGlzIHRoZSBob3N0CisgICAgICogbmFtZSBvZiB0aGUgY2xpZW50IGZvciB0aGUgc2VydmVyOyBhbmQgdGhhdCBvZiB0aGUgc2VydmVyIGZvciB0aGUgY2xpZW50LgorICAgICAqIEl0IGlzIG5vdCBhIHJlbGlhYmxlIHdheSB0byBnZXQgYSBmdWxseSBxdWFsaWZpZWQgaG9zdCBuYW1lOiBpdCBpcyBtYWlubHkKKyAgICAgKiB1c2VkIGludGVybmFsbHkgdG8gaW1wbGVtZW50IGxpbmtzIGZvciBhIHRlbXBvcmFyeSBjYWNoZSBvZiBTU0wgc2Vzc2lvbnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBob3N0IG5hbWUgb2YgdGhlIHBlZXIsIG9yIG51bGwgaWYgbm8gaW5mb3JtYXRpb24gaXMKKyAgICAgKiAgICAgICAgIGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGVlckhvc3QoKSB7CisgICAgICAgIHJldHVybiBwZWVySG9zdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwZWVyJ3MgcG9ydCBudW1iZXIgZm9yIHRoZSBhY3R1YWwgU1NMIHNlc3Npb24uIEl0IGlzIHRoZSBwb3J0CisgICAgICogbnVtYmVyIG9mIHRoZSBjbGllbnQgZm9yIHRoZSBzZXJ2ZXI7IGFuZCB0aGF0IG9mIHRoZSBzZXJ2ZXIgZm9yIHRoZQorICAgICAqIGNsaWVudC4gSXQgaXMgbm90IGEgcmVsaWFibGUgd2F5IHRvIGdldCBhIHBlZXIncyBwb3J0IG51bWJlcjogaXQgaXMKKyAgICAgKiBtYWlubHkgdXNlZCBpbnRlcm5hbGx5IHRvIGltcGxlbWVudCBsaW5rcyBmb3IgYSB0ZW1wb3JhcnkgY2FjaGUgb2YgU1NMCisgICAgICogc2Vzc2lvbnMuCisgICAgICogQHJldHVybiB0aGUgcGVlcidzIHBvcnQgbnVtYmVyLCBvciAtMSBpZiBubyBvbmUgaXMgYXZhaWxhYmxlLgorICAgICAqCisgICAgICovCisgICAgcHVibGljIGludCBnZXRQZWVyUG9ydCgpIHsKKyAgICAgICAgcmV0dXJuIHBlZXJQb3J0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgaWRlbnRpZmllciBvZiB0aGUgY3J5cHRvIHRvb2xzIHVzZWQgaW4gdGhlIGFjdHVhbCBTU0wKKyAgICAgKiBzZXNzaW9uLiBGb3IgZXhhbXBsZSBBRVNfMjU2X1dJVEhfTUQ1LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2lwaGVyU3VpdGUoKSB7CisgICAgICAgIGlmIChjaXBoZXJTdWl0ZSA9PSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IE5hdGl2ZUNyeXB0by5TU0xfU0VTU0lPTl9jaXBoZXIoc3NsU2Vzc2lvbk5hdGl2ZVBvaW50ZXIpOworICAgICAgICAgICAgY2lwaGVyU3VpdGUgPSBOYXRpdmVDcnlwdG8uT1BFTlNTTF9UT19TVEFOREFSRF9DSVBIRVJfU1VJVEVTLmdldChuYW1lKTsKKyAgICAgICAgICAgIGlmIChjaXBoZXJTdWl0ZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY2lwaGVyU3VpdGUgPSBuYW1lOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBjaXBoZXJTdWl0ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdGFuZGFyZCB2ZXJzaW9uIG5hbWUgb2YgdGhlIFNTTCBwcm90b2NvbCB1c2VkIGluIGFsbAorICAgICAqIGNvbm5lY3Rpb25zIHBlcnRhaW5pbmcgdG8gdGhpcyBTU0wgc2Vzc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFByb3RvY29sKCkgeworICAgICAgICBpZiAocHJvdG9jb2wgPT0gbnVsbCkgeworICAgICAgICAgICAgcHJvdG9jb2wgPSBOYXRpdmVDcnlwdG8uU1NMX1NFU1NJT05fZ2V0X3ZlcnNpb24oc3NsU2Vzc2lvbk5hdGl2ZVBvaW50ZXIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBwcm90b2NvbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb21wcmVzc2lvbiBtZXRob2QgbmFtZSB1c2VkIGluIGFsbCBjb25uZWN0aW9ucworICAgICAqIHBlcnRhaW5pbmcgdG8gdGhpcyBTU0wgc2Vzc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbXByZXNzaW9uTWV0aG9kKCkgeworICAgICAgICBpZiAoY29tcHJlc3Npb25NZXRob2QgPT0gbnVsbCkgeworICAgICAgICAgICAgY29tcHJlc3Npb25NZXRob2QKKyAgICAgICAgICAgICAgICAgICAgPSBOYXRpdmVDcnlwdG8uU1NMX1NFU1NJT05fY29tcHJlc3NfbWV0aChzZXNzaW9uQ29udGV4dC5zc2xDdHhOYXRpdmVQb2ludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNzbFNlc3Npb25OYXRpdmVQb2ludGVyKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29tcHJlc3Npb25NZXRob2Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29udGV4dCB0byB3aGljaCB0aGUgYWN0dWFsIFNTTCBzZXNzaW9uIGlzIGJvdW5kLiBBIFNTTAorICAgICAqIGNvbnRleHQgY29uc2lzdHMgb2YgKDEpIGEgcG9zc2libGUgZGVsZWdhdGUsICgyKSBhIHByb3ZpZGVyIGFuZCAoMykgYQorICAgICAqIHByb3RvY29sLgorICAgICAqIEByZXR1cm4gdGhlIFNTTCBjb250ZXh0IHVzZWQgZm9yIHRoaXMgc2Vzc2lvbiwgb3IgbnVsbCBpZiBpdCBpcworICAgICAqIHVuYXZhaWxhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBTU0xTZXNzaW9uQ29udGV4dCBnZXRTZXNzaW9uQ29udGV4dCgpIHsKKyAgICAgICAgcmV0dXJuIHNlc3Npb25Db250ZXh0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBib29sZWFuIGZsYWcgc2lnbmFsaW5nIHdoZXRoZXIgYSBTU0wgc2Vzc2lvbiBpcyB2YWxpZAorICAgICAqIGFuZCBhdmFpbGFibGUgZm9yIHJlc3VtaW5nIG9yIGpvaW5pbmcgb3Igbm90LgorICAgICAqCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgc2Vzc2lvbiBtYXkgYmUgcmVzdW1lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1ZhbGlkKCkgeworICAgICAgICBTU0xTZXNzaW9uQ29udGV4dCBjb250ZXh0ID0gc2Vzc2lvbkNvbnRleHQ7CisgICAgICAgIGlmIChpc1ZhbGlkCisgICAgICAgICAgICAgICAgJiYgY29udGV4dCAhPSBudWxsCisgICAgICAgICAgICAgICAgJiYgY29udGV4dC5nZXRTZXNzaW9uVGltZW91dCgpICE9IDAKKyAgICAgICAgICAgICAgICAmJiBnZXRDcmVhdGlvblRpbWUoKSArIChjb250ZXh0LmdldFNlc3Npb25UaW1lb3V0KCkgKiAxMDAwKQorICAgICAgICAgICAgICAgICAgICA8IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKSB7CisgICAgICAgICAgICBpc1ZhbGlkID0gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlzVmFsaWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXQgaW52YWxpZGF0ZXMgYSBTU0wgc2Vzc2lvbiBmb3JiaWRkaW5nIGFueSByZXN1bXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGludmFsaWRhdGUoKSB7CisgICAgICAgIGlzVmFsaWQgPSBmYWxzZTsKKyAgICAgICAgc2Vzc2lvbkNvbnRleHQgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG9iamVjdCB3aGljaCBpcyBib3VuZCB0byB0aGUgdGhlIGlucHV0IHBhcmFtZXRlciBuYW1lLgorICAgICAqIFRoaXMgbmFtZSBpcyBhIHNvcnQgb2YgbGluayB0byB0aGUgZGF0YSBvZiB0aGUgU1NMIHNlc3Npb24ncyBhcHBsaWNhdGlvbgorICAgICAqIGxheWVyLCBpZiBhbnkgZXhpc3RzLiBUaGUgc2VhcmNoIGZvciB0aGlzIGxpbmsgaXMgbW9uaXRvcmVkLCBhcyBhIG1hdHRlcgorICAgICAqIG9mIHNlY3VyaXR5LCBieSB0aGUgZnVsbCBtYWNoaW5lcnkgb2YgdGhlIDxjb2RlPkFjY2Vzc0NvbnRyb2xsZXI8L2NvZGU+CisgICAgICogY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgYmluZGluZyB0byBmaW5kLgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIGJvdW5kIHRvIHRoYXQgbmFtZSwgb3IgbnVsbCBpZiB0aGUgYmluZGluZyBkb2VzIG5vdAorICAgICAqICAgICAgICAgZXhpc3QuCisgICAgICogQHRocm93cyA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlmIHRoZSBhcmd1bWVudCBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0VmFsdWUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHZhbHVlcy5nZXQobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBhcnJheSB3aXRoIHRoZSBuYW1lcyAoc29ydCBvZiBsaW5rcykgb2YgYWxsIHRoZSBkYXRhCisgICAgICogb2JqZWN0cyBvZiB0aGUgYXBwbGljYXRpb24gbGF5ZXIgYm91bmQgaW50byB0aGUgU1NMIHNlc3Npb24uIFRoZSBzZWFyY2gKKyAgICAgKiBmb3IgdGhpcyBsaW5rIGlzIG1vbml0b3JlZCwgYXMgYSBtYXR0ZXIgb2Ygc2VjdXJpdHksIGJ5IHRoZSBmdWxsCisgICAgICogbWFjaGluZXJ5IG9mIHRoZSA8Y29kZT5BY2Nlc3NDb250cm9sbGVyPC9jb2RlPiBjbGFzcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBub24tbnVsbCAocG9zc2libHkgZW1wdHkpIGFycmF5IG9mIG5hbWVzIG9mIHRoZSBkYXRhIG9iamVjdHMKKyAgICAgKiAgICAgICAgIGJvdW5kIHRvIHRoaXMgU1NMIHNlc3Npb24uCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIGdldFZhbHVlTmFtZXMoKSB7CisgICAgICAgIHJldHVybiB2YWx1ZXMua2V5U2V0KCkudG9BcnJheShuZXcgU3RyaW5nW3ZhbHVlcy5zaXplKCldKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBIGxpbmsgKG5hbWUpIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZSBvYmplY3Qgb2YgdGhlIFNTTCBzZXNzaW9uJ3MKKyAgICAgKiBhcHBsaWNhdGlvbiBsYXllciBkYXRhIGlzIGNyZWF0ZWQgb3IgcmVwbGFjZWQuIElmIHRoZSBuZXcgKG9yIGV4aXN0aW5nKQorICAgICAqIHZhbHVlIG9iamVjdCBpbXBsZW1lbnRzIHRoZSA8Y29kZT5TU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyPC9jb2RlPgorICAgICAqIGludGVyZmFjZSwgdGhhdCBvYmplY3Qgd2lsbCBiZSBub3RpZmllZCBpbiBkdWUgY291cnNlLiBUaGVzZSBsaW5rcy10bworICAgICAqIC1kYXRhIGJvdW5kcyBhcmUgbW9uaXRvcmVkLCBhcyBhIG1hdHRlciBvZiBzZWN1cml0eSwgYnkgdGhlIGZ1bGwKKyAgICAgKiBtYWNoaW5lcnkgb2YgdGhlIDxjb2RlPkFjY2Vzc0NvbnRyb2xsZXI8L2NvZGU+IGNsYXNzLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhlIGxpbmsgKG5vIG51bGwgYXJlCisgICAgICogICAgICAgICAgICBhY2NlcHRlZCEpCisgICAgICogQHBhcmFtIHZhbHVlIGRhdGEgb2JqZWN0IHRoYXQgc2hhbGwgYmUgYm91bmQgdG8KKyAgICAgKiAgICAgICAgICAgIG5hbWUuCisgICAgICogQHRocm93cyA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlmIG9uZSBvciBib3RoCisgICAgICogICAgICAgICAgICAgYXJndW1lbnQocykgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXRWYWx1ZShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIGlmIChuYW1lID09IG51bGwgfHwgdmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibmFtZSA9PSBudWxsIHx8IHZhbHVlID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBPYmplY3Qgb2xkID0gdmFsdWVzLnB1dChuYW1lLCB2YWx1ZSk7CisgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXIpIHsKKyAgICAgICAgICAgICgoU1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lcikgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgIC52YWx1ZUJvdW5kKG5ldyBTU0xTZXNzaW9uQmluZGluZ0V2ZW50KHRoaXMsIG5hbWUpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2xkIGluc3RhbmNlb2YgU1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lcikgeworICAgICAgICAgICAgKChTU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyKSBvbGQpCisgICAgICAgICAgICAgICAgICAgIC52YWx1ZVVuYm91bmQobmV3IFNTTFNlc3Npb25CaW5kaW5nRXZlbnQodGhpcywgbmFtZSkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlcyBhIGxpbmsgKG5hbWUpIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZSBvYmplY3Qgb2YgdGhlIFNTTAorICAgICAqIHNlc3Npb24ncyBhcHBsaWNhdGlvbiBsYXllciBkYXRhLgorICAgICAqCisgICAgICogPHA+SWYgdGhlIHZhbHVlIG9iamVjdCBpbXBsZW1lbnRzIHRoZSA8Y29kZT5TU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyPC9jb2RlPgorICAgICAqIGludGVyZmFjZSwgdGhlIG9iamVjdCB3aWxsIHJlY2VpdmUgYSA8Y29kZT52YWx1ZVVuYm91bmQ8L2NvZGU+IG5vdGlmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIDxwPlRoZXNlIGxpbmtzLXRvIC1kYXRhIGJvdW5kcyBhcmUKKyAgICAgKiBtb25pdG9yZWQsIGFzIGEgbWF0dGVyIG9mIHNlY3VyaXR5LCBieSB0aGUgZnVsbCBtYWNoaW5lcnkgb2YgdGhlCisgICAgICogPGNvZGU+QWNjZXNzQ29udHJvbGxlcjwvY29kZT4gY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgbGluayAobm8gbnVsbCBhcmUKKyAgICAgKiAgICAgICAgICAgIGFjY2VwdGVkISkKKyAgICAgKiBAdGhyb3dzIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaWYgdGhlIGFyZ3VtZW50IGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlVmFsdWUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibmFtZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgT2JqZWN0IG9sZCA9IHZhbHVlcy5yZW1vdmUobmFtZSk7CisgICAgICAgIGlmIChvbGQgaW5zdGFuY2VvZiBTU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyKSB7CisgICAgICAgICAgICBTU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyIGxpc3RlbmVyID0gKFNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXIpIG9sZDsKKyAgICAgICAgICAgIGxpc3RlbmVyLnZhbHVlVW5ib3VuZChuZXcgU1NMU2Vzc2lvbkJpbmRpbmdFdmVudCh0aGlzLCBuYW1lKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfU0VTU0lPTl9mcmVlKHNzbFNlc3Npb25OYXRpdmVQb2ludGVyKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHN1cGVyLmZpbmFsaXplKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9PcGVuU1NMU2lnbmF0dXJlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9PcGVuU1NMU2lnbmF0dXJlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmNjY2RhNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL09wZW5TU0xTaWduYXR1cmUuamF2YQpAQCAtMCwwICsxLDI5MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5EU0FQYXJhbXM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLkRTQVB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuUlNBUHVibGljS2V5OworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBJbXBsZW1lbnRzIHRoZSBzdWJzZXQgb2YgdGhlIEpESyBTaWduYXR1cmUgaW50ZXJmYWNlIG5lZWRlZCBmb3IKKyAqIHNpZ25hdHVyZSB2ZXJpZmljYXRpb24gdXNpbmcgT3BlblNTTC4KKyAqLworcHVibGljIGNsYXNzIE9wZW5TU0xTaWduYXR1cmUgZXh0ZW5kcyBTaWduYXR1cmUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgTWFwPFN0cmluZyxDbGFzczw/IGV4dGVuZHMgT3BlblNTTFNpZ25hdHVyZT4+IGpka1RvT3BlblNzbAorICAgICAgICAgICAgPSBuZXcgSGFzaE1hcDxTdHJpbmcsQ2xhc3M8PyBleHRlbmRzIE9wZW5TU0xTaWduYXR1cmU+PigpOworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcmVnaXN0ZXIoU3RyaW5nIGFsZ29yaXRobSwgQ2xhc3MgaW1wbGVtZW50YXRpb24pIHsKKyAgICAgICAgamRrVG9PcGVuU3NsLnB1dChhbGdvcml0aG0udG9VcHBlckNhc2UoTG9jYWxlLlVTKSwgaW1wbGVtZW50YXRpb24pOworICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBDbGFzcyBsb29rdXAoU3RyaW5nIGFsZ29yaXRobSkgeworICAgICAgICByZXR1cm4gamRrVG9PcGVuU3NsLmdldChhbGdvcml0aG0udG9VcHBlckNhc2UoTG9jYWxlLlVTKSk7CisgICAgfQorCisgICAgc3RhdGljIHsKKyAgICAgICAgLy8gVE9ETyBGaW5pc2ggT3BlblNTTFNpZ25hdHVyZSBpbXBsZW1lbnRhdGlvbiBhbmQgbW92ZQorICAgICAgICAvLyByZWdpc3RyYXRpb24gaW5mb3JtYXRpb24gdG8gdGhlIE9wZW5TU0xQcm92aWRlcgorICAgICAgICByZWdpc3RlcigiTUQ1V2l0aFJTQUVuY3J5cHRpb24iLCBNRDVSU0EuY2xhc3MpOworICAgICAgICByZWdpc3RlcigiTUQ1V2l0aFJTQSIsIE1ENVJTQS5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKCJNRDUvUlNBIiwgTUQ1UlNBLmNsYXNzKTsKKyAgICAgICAgcmVnaXN0ZXIoIjEuMi44NDAuMTEzNTQ5LjEuMS40IiwgTUQ1UlNBLmNsYXNzKTsKKyAgICAgICAgcmVnaXN0ZXIoIjEuMi44NDAuMTEzNTQ5LjIuNXdpdGgxLjIuODQwLjExMzU0OS4xLjEuMSIsIE1ENVJTQS5jbGFzcyk7CisKKyAgICAgICAgcmVnaXN0ZXIoIlNIQTFXaXRoUlNBRW5jcnlwdGlvbiIsIFNIQTFSU0EuY2xhc3MpOworICAgICAgICByZWdpc3RlcigiU0hBMVdpdGhSU0EiLCBTSEExUlNBLmNsYXNzKTsKKyAgICAgICAgcmVnaXN0ZXIoIlNIQTEvUlNBIiwgU0hBMVJTQS5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKCJTSEEtMS9SU0EiLCBTSEExUlNBLmNsYXNzKTsKKyAgICAgICAgcmVnaXN0ZXIoIjEuMi44NDAuMTEzNTQ5LjEuMS41IiwgU0hBMVJTQS5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKCIxLjMuMTQuMy4yLjI2d2l0aDEuMi44NDAuMTEzNTQ5LjEuMS4xIiwgU0hBMVJTQS5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKCIxLjMuMTQuMy4yLjI2d2l0aDEuMi44NDAuMTEzNTQ5LjEuMS41IiwgU0hBMVJTQS5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKCIxLjMuMTQuMy4yLjI5IiwgU0hBMVJTQS5jbGFzcyk7CisKKyAgICAgICAgcmVnaXN0ZXIoIlNIQTI1NldpdGhSU0FFbmNyeXB0aW9uIiwgU0hBMjU2UlNBLmNsYXNzKTsKKyAgICAgICAgcmVnaXN0ZXIoIlNIQTI1NldpdGhSU0EiLCBTSEEyNTZSU0EuY2xhc3MpOworICAgICAgICByZWdpc3RlcigiMS4yLjg0MC4xMTM1NDkuMS4xLjExIiwgU0hBMjU2UlNBLmNsYXNzKTsKKworICAgICAgICByZWdpc3RlcigiU0hBMzg0V2l0aFJTQUVuY3J5cHRpb24iLCBTSEEzODRSU0EuY2xhc3MpOworICAgICAgICByZWdpc3RlcigiU0hBMzg0V2l0aFJTQSIsIFNIQTM4NFJTQS5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKCIxLjIuODQwLjExMzU0OS4xLjEuMTIiLCBTSEEzODRSU0EuY2xhc3MpOworCisgICAgICAgIHJlZ2lzdGVyKCJTSEE1MTJXaXRoUlNBRW5jcnlwdGlvbiIsIFNIQTUxMlJTQS5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKCJTSEE1MTJXaXRoUlNBIiwgU0hBNTEyUlNBLmNsYXNzKTsKKyAgICAgICAgcmVnaXN0ZXIoIjEuMi44NDAuMTEzNTQ5LjEuMS4xMyIsIFNIQTUxMlJTQS5jbGFzcyk7CisKKyAgICAgICAgcmVnaXN0ZXIoIlNIQTF3aXRoRFNBIiwgU0hBMURTQS5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKCJTSEEvRFNBIiwgU0hBMURTQS5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKCJEU0EiLCBTSEExRFNBLmNsYXNzKTsKKyAgICAgICAgcmVnaXN0ZXIoIjEuMy4xNC4zLjIuMjZ3aXRoMS4yLjg0MC4xMDA0MC40LjEiLCBTSEExRFNBLmNsYXNzKTsKKyAgICAgICAgcmVnaXN0ZXIoIjEuMy4xNC4zLjIuMjZ3aXRoMS4yLjg0MC4xMDA0MC40LjMiLCBTSEExRFNBLmNsYXNzKTsKKyAgICAgICAgcmVnaXN0ZXIoIkRTQVdpdGhTSEExIiwgU0hBMURTQS5jbGFzcyk7CisgICAgICAgIHJlZ2lzdGVyKCIxLjIuODQwLjEwMDQwLjQuMyIsIFNIQTFEU0EuY2xhc3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhvbGRzIGEgcG9pbnRlciB0byB0aGUgbmF0aXZlIG1lc3NhZ2UgZGlnZXN0IGNvbnRleHQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgY3R4OworCisgICAgLyoqCisgICAgICogSG9sZHMgYSBwb2ludGVyIHRvIHRoZSBuYXRpdmUgRFNBIGtleS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBkc2E7CisKKyAgICAvKioKKyAgICAgKiBIb2xkcyBhIHBvaW50ZXIgdG8gdGhlIG5hdGl2ZSBSU0Ega2V5LgorICAgICAqLworICAgIHByaXZhdGUgaW50IHJzYTsKKworICAgIC8qKgorICAgICAqIEhvbGRzIHRoZSBPcGVuU1NMIG5hbWUgb2YgdGhlIGFsZ29yaXRobSAobG93ZXIgY2FzZSwgbm8gZGFzaGVzKS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBldnBBbGdvcml0aG07CisKKyAgICAvKioKKyAgICAgKiBIb2xkcyBhIGR1bW15IGJ1ZmZlciBmb3Igd3JpdGluZyBzaW5nbGUgYnl0ZXMgdG8gdGhlIGRpZ2VzdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBzaW5nbGVCeXRlID0gbmV3IGJ5dGVbMV07CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IE9wZW5TU0xTaWduYXR1cmUgaW5zdGFuY2UgZm9yIHRoZSBnaXZlbiBhbGdvcml0aG0gbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0gVGhlIG5hbWUgb2YgdGhlIGFsZ29yaXRobSwgZS5nLiAiU0hBMVdpdGhSU0EiLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgbmV3IE9wZW5TU0xTaWduYXR1cmUgaW5zdGFuY2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gSW4gY2FzZSBvZiBwcm9ibGVtcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIE9wZW5TU0xTaWduYXR1cmUgZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0SW5zdGFuY2UoKSBpbnZva2VkIHdpdGggIiArIGFsZ29yaXRobSk7CisKKyAgICAgICAgQ2xhc3MgPD8gZXh0ZW5kcyBPcGVuU1NMU2lnbmF0dXJlPiBjbGF6eiA9IGxvb2t1cChhbGdvcml0aG0pOworICAgICAgICBpZiAoY2xhenogPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbihhbGdvcml0aG0pOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gY2xhenoubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKGFsZ29yaXRobSwgZSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbihhbGdvcml0aG0sIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBPcGVuU1NMU2lnbmF0dXJlIGluc3RhbmNlIGZvciB0aGUgZ2l2ZW4gYWxnb3JpdGhtIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtIE9wZW5TU0wgbmFtZSBvZiB0aGUgYWxnb3JpdGhtLCBlLmcuICJSU0EtU0hBMSIuCisgICAgICovCisgICAgcHJpdmF0ZSBPcGVuU1NMU2lnbmF0dXJlKFN0cmluZyBhbGdvcml0aG0pIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBzdXBlcihhbGdvcml0aG0pOworCisgICAgICAgIC8vIFdlIGRvbid0IHN1cHBvcnQgTUQyCisgICAgICAgIGlmICgiUlNBLU1EMiIuZXF1YWxzKGFsZ29yaXRobSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oYWxnb3JpdGhtKTsKKyAgICAgICAgfQorCisgICAgICAgIHRoaXMuZXZwQWxnb3JpdGhtID0gYWxnb3JpdGhtOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShieXRlIGlucHV0KSB7CisgICAgICAgIHNpbmdsZUJ5dGVbMF0gPSBpbnB1dDsKKyAgICAgICAgZW5naW5lVXBkYXRlKHNpbmdsZUJ5dGUsIDAsIDEpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShieXRlW10gaW5wdXQsIGludCBvZmZzZXQsIGludCBsZW4pIHsKKyAgICAgICAgaWYgKHN0YXRlID09IFNJR04pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLkVWUF9WZXJpZnlVcGRhdGUoY3R4LCBpbnB1dCwgb2Zmc2V0LCBsZW4pOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIE9iamVjdCBlbmdpbmVHZXRQYXJhbWV0ZXIoU3RyaW5nIHBhcmFtKSB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXRTaWduKFByaXZhdGVLZXkgcHJpdmF0ZUtleSkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0VmVyaWZ5KFB1YmxpY0tleSBwdWJsaWNLZXkpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJlbmdpbmVJbml0VmVyaWZ5KCkgaW52b2tlZCB3aXRoICIKKyAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICsgcHVibGljS2V5LmdldENsYXNzKCkuZ2V0Q2Fub25pY2FsTmFtZSgpKTsKKworICAgICAgICBpZiAocHVibGljS2V5IGluc3RhbmNlb2YgRFNBUHVibGljS2V5KSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIERTQVB1YmxpY0tleSBkc2FQdWJsaWNLZXkgPSAoRFNBUHVibGljS2V5KXB1YmxpY0tleTsKKyAgICAgICAgICAgICAgICBEU0FQYXJhbXMgZHNhUGFyYW1zID0gZHNhUHVibGljS2V5LmdldFBhcmFtcygpOworICAgICAgICAgICAgICAgIGRzYSA9IE5hdGl2ZUNyeXB0by5FVlBfUEtFWV9uZXdfRFNBKGRzYVBhcmFtcy5nZXRQKCkudG9CeXRlQXJyYXkoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRzYVBhcmFtcy5nZXRRKCkudG9CeXRlQXJyYXkoKSwgZHNhUGFyYW1zLmdldEcoKS50b0J5dGVBcnJheSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgZHNhUHVibGljS2V5LmdldFkoKS50b0J5dGVBcnJheSgpLCBudWxsKTsKKworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChwdWJsaWNLZXkgaW5zdGFuY2VvZiBSU0FQdWJsaWNLZXkpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgUlNBUHVibGljS2V5IHJzYVB1YmxpY0tleSA9IChSU0FQdWJsaWNLZXkpcHVibGljS2V5OworICAgICAgICAgICAgICAgIHJzYSA9IE5hdGl2ZUNyeXB0by5FVlBfUEtFWV9uZXdfUlNBKHJzYVB1YmxpY0tleS5nZXRNb2R1bHVzKCkudG9CeXRlQXJyYXkoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHJzYVB1YmxpY0tleS5nZXRQdWJsaWNFeHBvbmVudCgpLnRvQnl0ZUFycmF5KCksIG51bGwsIG51bGwsIG51bGwpOworCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5RXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oIk5lZWQgRFNBIG9yIFJTQSBwdWJsaWMga2V5Iik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY3R4ID0gTmF0aXZlQ3J5cHRvLkVWUF9WZXJpZnlJbml0KGV2cEFsZ29yaXRobSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lU2V0UGFyYW1ldGVyKFN0cmluZyBwYXJhbSwgT2JqZWN0IHZhbHVlKSB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVTaWduKCkgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBib29sZWFuIGVuZ2luZVZlcmlmeShieXRlW10gc2lnQnl0ZXMpIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICBpbnQgaGFuZGxlID0gKHJzYSAhPSAwKSA/IHJzYSA6IGRzYTsKKworICAgICAgICBpZiAoaGFuZGxlID09IDApIHsKKyAgICAgICAgICAgIC8vIFRoaXMgY2FuJ3QgYWN0dWFsbHkgaGFwcGVuLCBidXQgeW91IG5ldmVyIGtub3cuLi4KKyAgICAgICAgICAgIHRocm93IG5ldyBTaWduYXR1cmVFeGNlcHRpb24oIk5lZWQgRFNBIG9yIFJTQSBwdWJsaWMga2V5Iik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IHJlc3VsdCA9IE5hdGl2ZUNyeXB0by5FVlBfVmVyaWZ5RmluYWwoY3R4LCBzaWdCeXRlcywgMCwgc2lnQnl0ZXMubGVuZ3RoLCBoYW5kbGUpOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSAxOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTaWduYXR1cmVFeGNlcHRpb24oZXgpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChkc2EgIT0gMCkgeworICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5FVlBfUEtFWV9mcmVlKGRzYSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChyc2EgIT0gMCkgeworICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5FVlBfUEtFWV9mcmVlKHJzYSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChjdHggIT0gMCkgeworICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5FVlBfTURfQ1RYX2Rlc3Ryb3koY3R4KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHN1cGVyLmZpbmFsaXplKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE1ENVJTQSBleHRlbmRzIE9wZW5TU0xTaWduYXR1cmUgeworICAgICAgICBwdWJsaWMgTUQ1UlNBKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcigiUlNBLU1ENSIpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgU0hBMVJTQSBleHRlbmRzIE9wZW5TU0xTaWduYXR1cmUgeworICAgICAgICBwdWJsaWMgU0hBMVJTQSgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIoIlJTQS1TSEExIik7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBTSEEyNTZSU0EgZXh0ZW5kcyBPcGVuU1NMU2lnbmF0dXJlIHsKKyAgICAgICAgcHVibGljIFNIQTI1NlJTQSgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIoIlJTQS1TSEEyNTYiKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFNIQTM4NFJTQSBleHRlbmRzIE9wZW5TU0xTaWduYXR1cmUgeworICAgICAgICBwdWJsaWMgU0hBMzg0UlNBKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcigiUlNBLVNIQTM4NCIpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgU0hBNTEyUlNBIGV4dGVuZHMgT3BlblNTTFNpZ25hdHVyZSB7CisgICAgICAgIHB1YmxpYyBTSEE1MTJSU0EoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyKCJSU0EtU0hBNTEyIik7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBTSEExRFNBIGV4dGVuZHMgT3BlblNTTFNpZ25hdHVyZSB7CisgICAgICAgIHB1YmxpYyBTSEExRFNBKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcigiRFNBLVNIQTEiKTsKKyAgICAgICAgfQorICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvT3BlblNTTFNvY2tldEZhY3RvcnlJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9PcGVuU1NMU29ja2V0RmFjdG9yeUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MWM1OGI2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvT3BlblNTTFNvY2tldEZhY3RvcnlJbXBsLmphdmEKQEAgLTAsMCArMSwxMDAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleU1hbmFnZW1lbnRFeGNlcHRpb247CisKK3B1YmxpYyBjbGFzcyBPcGVuU1NMU29ja2V0RmFjdG9yeUltcGwgZXh0ZW5kcyBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3RvcnkgeworCisgICAgcHJpdmF0ZSBmaW5hbCBTU0xQYXJhbWV0ZXJzSW1wbCBzc2xQYXJhbWV0ZXJzOworICAgIHByaXZhdGUgZmluYWwgSU9FeGNlcHRpb24gaW5zdGFudGlhdGlvbkV4Y2VwdGlvbjsKKworICAgIHB1YmxpYyBPcGVuU1NMU29ja2V0RmFjdG9yeUltcGwoKSB7CisgICAgICAgIFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnNMb2NhbCA9IG51bGw7CisgICAgICAgIElPRXhjZXB0aW9uIGluc3RhbnRpYXRpb25FeGNlcHRpb25Mb2NhbCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2xQYXJhbWV0ZXJzTG9jYWwgPSBTU0xQYXJhbWV0ZXJzSW1wbC5nZXREZWZhdWx0KCk7CisgICAgICAgIH0gY2F0Y2ggKEtleU1hbmFnZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaW5zdGFudGlhdGlvbkV4Y2VwdGlvbkxvY2FsID0gbmV3IElPRXhjZXB0aW9uKCJEZWxheWVkIGluc3RhbnRpYXRpb24gZXhjZXB0aW9uOiIpOworICAgICAgICAgICAgaW5zdGFudGlhdGlvbkV4Y2VwdGlvbkxvY2FsLmluaXRDYXVzZShlKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnNzbFBhcmFtZXRlcnMgPSBzc2xQYXJhbWV0ZXJzTG9jYWw7CisgICAgICAgIHRoaXMuaW5zdGFudGlhdGlvbkV4Y2VwdGlvbiA9IGluc3RhbnRpYXRpb25FeGNlcHRpb25Mb2NhbDsKKyAgICB9CisKKyAgICBwdWJsaWMgT3BlblNTTFNvY2tldEZhY3RvcnlJbXBsKFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnMpIHsKKyAgICAgICAgdGhpcy5zc2xQYXJhbWV0ZXJzID0gc3NsUGFyYW1ldGVyczsKKyAgICAgICAgdGhpcy5pbnN0YW50aWF0aW9uRXhjZXB0aW9uID0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUNyeXB0by5nZXREZWZhdWx0Q2lwaGVyU3VpdGVzKCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZ1tdIGdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUNyeXB0by5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpbnN0YW50aWF0aW9uRXhjZXB0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IGluc3RhbnRpYXRpb25FeGNlcHRpb247CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBPcGVuU1NMU29ja2V0SW1wbCgoU1NMUGFyYW1ldGVyc0ltcGwpIHNzbFBhcmFtZXRlcnMuY2xvbmUoKSk7CisgICAgfQorCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoU3RyaW5nIGhvc3QsIGludCBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24sIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBPcGVuU1NMU29ja2V0SW1wbChob3N0LCBwb3J0LCAoU1NMUGFyYW1ldGVyc0ltcGwpIHNzbFBhcmFtZXRlcnMuY2xvbmUoKSk7CisgICAgfQorCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoU3RyaW5nIGhvc3QsIGludCBwb3J0LCBJbmV0QWRkcmVzcyBsb2NhbEhvc3QsIGludCBsb2NhbFBvcnQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBPcGVuU1NMU29ja2V0SW1wbChob3N0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxIb3N0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsUG9ydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoU1NMUGFyYW1ldGVyc0ltcGwpIHNzbFBhcmFtZXRlcnMuY2xvbmUoKSk7CisgICAgfQorCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MgaG9zdCwgaW50IHBvcnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgT3BlblNTTFNvY2tldEltcGwoaG9zdCwgcG9ydCwgKFNTTFBhcmFtZXRlcnNJbXBsKSBzc2xQYXJhbWV0ZXJzLmNsb25lKCkpOworICAgIH0KKworICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzIGFkZHJlc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBvcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MgbG9jYWxBZGRyZXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsb2NhbFBvcnQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3IE9wZW5TU0xTb2NrZXRJbXBsKGFkZHJlc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9ydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbEFkZHJlc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxQb3J0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChTU0xQYXJhbWV0ZXJzSW1wbCkgc3NsUGFyYW1ldGVycy5jbG9uZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldChTb2NrZXQgcywgU3RyaW5nIGhvc3QsIGludCBwb3J0LCBib29sZWFuIGF1dG9DbG9zZSkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgT3BlblNTTFNvY2tldEltcGxXcmFwcGVyKHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9DbG9zZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFNTTFBhcmFtZXRlcnNJbXBsKSBzc2xQYXJhbWV0ZXJzLmNsb25lKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL09wZW5TU0xTb2NrZXRJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9PcGVuU1NMU29ja2V0SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ0NjgxYWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9PcGVuU1NMU29ja2V0SW1wbC5qYXZhCkBAIC0wLDAgKzEsMTAwMCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGRhbHZpay5zeXN0ZW0uQmxvY2tHdWFyZDsKK2ltcG9ydCBkYWx2aWsuc3lzdGVtLkNsb3NlR3VhcmQ7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLkhhbmRzaGFrZUNvbXBsZXRlZEV2ZW50OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xIYW5kc2hha2VFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xQcm90b2NvbEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5YNTA5VHJ1c3RNYW5hZ2VyOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsOworaW1wb3J0IGxpYmNvcmUuaW8uU3RyZWFtczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkucHJvdmlkZXIuY2VydC5YNTA5Q2VydEltcGw7CisKKy8qKgorICogSW1wbGVtZW50YXRpb24gb2YgdGhlIGNsYXNzIE9wZW5TU0xTb2NrZXRJbXBsIGJhc2VkIG9uIE9wZW5TU0wuCisgKiA8cD4KKyAqIFRoaXMgY2xhc3Mgb25seSBzdXBwb3J0cyBTU0x2MyBhbmQgVExTdjEuIFRoaXMgc2hvdWxkIGJlIGRvY3VtZW50ZWQgZWxzZXdoZXJlCisgKiBsYXRlciwgZm9yIGV4YW1wbGUgaW4gdGhlIHBhY2thZ2UuaHRtbCBvciBhIHNlcGFyYXRlIHJlZmVyZW5jZSBkb2N1bWVudC4KKyAqIDxwPgorICogRXh0ZW5zaW9ucyB0byBTU0xTb2NrZXQgaW5jbHVkZToKKyAqIDx1bD4KKyAqIDxsaT5oYW5kc2hha2UgdGltZW91dAorICogPGxpPmNvbXByZXNzaW9uIG1ldGhvZHMKKyAqIDxsaT5zZXNzaW9uIHRpY2tldHMKKyAqIDxsaT5TZXJ2ZXIgTmFtZSBJbmRpY2F0aW9uCisgKiA8L3VsPgorICovCitwdWJsaWMgY2xhc3MgT3BlblNTTFNvY2tldEltcGwKKyAgICAgICAgZXh0ZW5kcyBqYXZheC5uZXQuc3NsLlNTTFNvY2tldAorICAgICAgICBpbXBsZW1lbnRzIE5hdGl2ZUNyeXB0by5TU0xIYW5kc2hha2VDYWxsYmFja3MgeworCisgICAgcHJpdmF0ZSBpbnQgc3NsTmF0aXZlUG9pbnRlcjsKKyAgICBwcml2YXRlIElucHV0U3RyZWFtIGlzOworICAgIHByaXZhdGUgT3V0cHV0U3RyZWFtIG9zOworICAgIHByaXZhdGUgZmluYWwgT2JqZWN0IGhhbmRzaGFrZUxvY2sgPSBuZXcgT2JqZWN0KCk7CisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgcmVhZExvY2sgPSBuZXcgT2JqZWN0KCk7CisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3Qgd3JpdGVMb2NrID0gbmV3IE9iamVjdCgpOworICAgIHByaXZhdGUgU1NMUGFyYW1ldGVyc0ltcGwgc3NsUGFyYW1ldGVyczsKKyAgICBwcml2YXRlIFN0cmluZ1tdIGVuYWJsZWRQcm90b2NvbHM7CisgICAgcHJpdmF0ZSBTdHJpbmdbXSBlbmFibGVkQ2lwaGVyU3VpdGVzOworICAgIHByaXZhdGUgU3RyaW5nW10gZW5hYmxlZENvbXByZXNzaW9uTWV0aG9kczsKKyAgICBwcml2YXRlIGJvb2xlYW4gdXNlU2Vzc2lvblRpY2tldHM7CisgICAgcHJpdmF0ZSBTdHJpbmcgaG9zdG5hbWU7CisgICAgcHJpdmF0ZSBPcGVuU1NMU2Vzc2lvbkltcGwgc3NsU2Vzc2lvbjsKKyAgICBwcml2YXRlIGZpbmFsIFNvY2tldCBzb2NrZXQ7CisgICAgcHJpdmF0ZSBib29sZWFuIGF1dG9DbG9zZTsKKyAgICBwcml2YXRlIGJvb2xlYW4gaGFuZHNoYWtlU3RhcnRlZCA9IGZhbHNlOworICAgIHByaXZhdGUgZmluYWwgQ2xvc2VHdWFyZCBndWFyZCA9IENsb3NlR3VhcmQuZ2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBOb3Qgc2V0IHRvIHRydWUgdW50aWwgdGhlIHVwZGF0ZSBmcm9tIG5hdGl2ZSB0aGF0IHRlbGxzIHVzIHRoZQorICAgICAqIGZ1bGwgaGFuZHNoYWtlIGlzIGNvbXBsZXRlLCBzaW5jZSBTU0xfZG9faGFuZHNoYWtlIGNhbiByZXR1cm4KKyAgICAgKiBiZWZvcmUgdGhlIGhhbmRzaGFrZSBpcyBjb21wbGV0ZWx5IGRvbmUgZHVlIHRvCisgICAgICogaGFuZHNoYWtlX2N1dHRocm91Z2ggc3VwcG9ydC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaGFuZHNoYWtlQ29tcGxldGVkID0gZmFsc2U7CisKKyAgICBwcml2YXRlIEFycmF5TGlzdDxIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lcj4gbGlzdGVuZXJzOworCisgICAgLyoqCisgICAgICogTG9jYWwgY2FjaGUgb2YgdGltZW91dCB0byBhdm9pZCBnZXRzb2Nrb3B0IG9uIGV2ZXJ5IHJlYWQgYW5kCisgICAgICogd3JpdGUgZm9yIG5vbi13cmFwcGVkIHNvY2tldHMuIE5vdGUgdGhhdAorICAgICAqIE9wZW5TU0xTb2NrZXRJbXBsV3JhcHBlciBvdmVycmlkZXMgc2V0U29UaW1lb3V0IGFuZAorICAgICAqIGdldFNvVGltZW91dCB0byBkZWxlZ2F0ZSB0byB0aGUgd3JhcHBlZCBzb2NrZXQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgdGltZW91dE1pbGxpc2Vjb25kcyA9IDA7CisKKyAgICBwcml2YXRlIGludCBoYW5kc2hha2VUaW1lb3V0TWlsbGlzZWNvbmRzID0gLTE7ICAvLyAtMSA9IHNhbWUgYXMgdGltZW91dDsgMCA9IGluZmluaXRlCisgICAgcHJpdmF0ZSBTdHJpbmcgd3JhcHBlZEhvc3Q7CisgICAgcHJpdmF0ZSBpbnQgd3JhcHBlZFBvcnQ7CisKKyAgICBwcm90ZWN0ZWQgT3BlblNTTFNvY2tldEltcGwoU1NMUGFyYW1ldGVyc0ltcGwgc3NsUGFyYW1ldGVycykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5zb2NrZXQgPSB0aGlzOworICAgICAgICBpbml0KHNzbFBhcmFtZXRlcnMpOworICAgIH0KKworICAgIHByb3RlY3RlZCBPcGVuU1NMU29ja2V0SW1wbChTU0xQYXJhbWV0ZXJzSW1wbCBzc2xQYXJhbWV0ZXJzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdbXSBlbmFibGVkUHJvdG9jb2xzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdbXSBlbmFibGVkQ2lwaGVyU3VpdGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdbXSBlbmFibGVkQ29tcHJlc3Npb25NZXRob2RzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLnNvY2tldCA9IHRoaXM7CisgICAgICAgIGluaXQoc3NsUGFyYW1ldGVycywgZW5hYmxlZFByb3RvY29scywgZW5hYmxlZENpcGhlclN1aXRlcywgZW5hYmxlZENvbXByZXNzaW9uTWV0aG9kcyk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIE9wZW5TU0xTb2NrZXRJbXBsKFN0cmluZyBob3N0LCBpbnQgcG9ydCwgU1NMUGFyYW1ldGVyc0ltcGwgc3NsUGFyYW1ldGVycykKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKGhvc3QsIHBvcnQpOworICAgICAgICB0aGlzLnNvY2tldCA9IHRoaXM7CisgICAgICAgIGluaXQoc3NsUGFyYW1ldGVycyk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIE9wZW5TU0xTb2NrZXRJbXBsKEluZXRBZGRyZXNzIGFkZHJlc3MsIGludCBwb3J0LCBTU0xQYXJhbWV0ZXJzSW1wbCBzc2xQYXJhbWV0ZXJzKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoYWRkcmVzcywgcG9ydCk7CisgICAgICAgIHRoaXMuc29ja2V0ID0gdGhpczsKKyAgICAgICAgaW5pdChzc2xQYXJhbWV0ZXJzKTsKKyAgICB9CisKKworICAgIHByb3RlY3RlZCBPcGVuU1NMU29ja2V0SW1wbChTdHJpbmcgaG9zdCwgaW50IHBvcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZXRBZGRyZXNzIGNsaWVudEFkZHJlc3MsIGludCBjbGllbnRQb3J0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xQYXJhbWV0ZXJzSW1wbCBzc2xQYXJhbWV0ZXJzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdXBlcihob3N0LCBwb3J0LCBjbGllbnRBZGRyZXNzLCBjbGllbnRQb3J0KTsKKyAgICAgICAgdGhpcy5zb2NrZXQgPSB0aGlzOworICAgICAgICBpbml0KHNzbFBhcmFtZXRlcnMpOworICAgIH0KKworICAgIHByb3RlY3RlZCBPcGVuU1NMU29ja2V0SW1wbChJbmV0QWRkcmVzcyBhZGRyZXNzLCBpbnQgcG9ydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MgY2xpZW50QWRkcmVzcywgaW50IGNsaWVudFBvcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKGFkZHJlc3MsIHBvcnQsIGNsaWVudEFkZHJlc3MsIGNsaWVudFBvcnQpOworICAgICAgICB0aGlzLnNvY2tldCA9IHRoaXM7CisgICAgICAgIGluaXQoc3NsUGFyYW1ldGVycyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuIFNTTCBzb2NrZXQgdGhhdCB3cmFwcyBhbm90aGVyIHNvY2tldC4gSW52b2tlZCBieQorICAgICAqIE9wZW5TU0xTb2NrZXRJbXBsV3JhcHBlciBjb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgT3BlblNTTFNvY2tldEltcGwoU29ja2V0IHNvY2tldCwgU3RyaW5nIGhvc3QsIGludCBwb3J0LAorICAgICAgICAgICAgYm9vbGVhbiBhdXRvQ2xvc2UsIFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMuc29ja2V0ID0gc29ja2V0OworICAgICAgICB0aGlzLndyYXBwZWRIb3N0ID0gaG9zdDsKKyAgICAgICAgdGhpcy53cmFwcGVkUG9ydCA9IHBvcnQ7CisgICAgICAgIHRoaXMuYXV0b0Nsb3NlID0gYXV0b0Nsb3NlOworICAgICAgICBpbml0KHNzbFBhcmFtZXRlcnMpOworCisgICAgICAgIC8vIHRoaXMudGltZW91dCBpcyBub3Qgc2V0IGludGVudGlvbmFsbHkuCisgICAgICAgIC8vIE9wZW5TU0xTb2NrZXRJbXBsV3JhcHBlci5nZXRTb1RpbWVvdXQgd2lsbCBkZWxlZ2F0ZSB0aW1lb3V0CisgICAgICAgIC8vIHRvIHdyYXBwZWQgc29ja2V0CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZSB0aGUgU1NMIHNvY2tldCBhbmQgc2V0IHRoZSBjZXJ0aWZpY2F0ZXMgZm9yIHRoZQorICAgICAqIGZ1dHVyZSBoYW5kc2hha2luZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdChTU0xQYXJhbWV0ZXJzSW1wbCBzc2xQYXJhbWV0ZXJzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbml0KHNzbFBhcmFtZXRlcnMsCisgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLmdldFN1cHBvcnRlZFByb3RvY29scygpLAorICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5nZXREZWZhdWx0Q2lwaGVyU3VpdGVzKCksCisgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLmdldERlZmF1bHRDb21wcmVzc2lvbk1ldGhvZHMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZSB0aGUgU1NMIHNvY2tldCBhbmQgc2V0IHRoZSBjZXJ0aWZpY2F0ZXMgZm9yIHRoZQorICAgICAqIGZ1dHVyZSBoYW5kc2hha2luZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdChTU0xQYXJhbWV0ZXJzSW1wbCBzc2xQYXJhbWV0ZXJzLAorICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1tdIGVuYWJsZWRQcm90b2NvbHMsCisgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nW10gZW5hYmxlZENpcGhlclN1aXRlcywKKyAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdbXSBlbmFibGVkQ29tcHJlc3Npb25NZXRob2RzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLnNzbFBhcmFtZXRlcnMgPSBzc2xQYXJhbWV0ZXJzOworICAgICAgICB0aGlzLmVuYWJsZWRQcm90b2NvbHMgPSBlbmFibGVkUHJvdG9jb2xzOworICAgICAgICB0aGlzLmVuYWJsZWRDaXBoZXJTdWl0ZXMgPSBlbmFibGVkQ2lwaGVyU3VpdGVzOworICAgICAgICB0aGlzLmVuYWJsZWRDb21wcmVzc2lvbk1ldGhvZHMgPSBlbmFibGVkQ29tcHJlc3Npb25NZXRob2RzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHN1aXRhYmxlIHNlc3Npb24gcmVmZXJlbmNlIGZyb20gdGhlIHNlc3Npb24gY2FjaGUgY29udGFpbmVyLgorICAgICAqLworICAgIHByaXZhdGUgT3BlblNTTFNlc3Npb25JbXBsIGdldENhY2hlZENsaWVudFNlc3Npb24oQ2xpZW50U2Vzc2lvbkNvbnRleHQgc2Vzc2lvbkNvbnRleHQpIHsKKyAgICAgICAgaWYgKHN1cGVyLmdldEluZXRBZGRyZXNzKCkgPT0gbnVsbCB8fAorICAgICAgICAgICAgICAgIHN1cGVyLmdldEluZXRBZGRyZXNzKCkuZ2V0SG9zdEFkZHJlc3MoKSA9PSBudWxsIHx8CisgICAgICAgICAgICAgICAgc3VwZXIuZ2V0SW5ldEFkZHJlc3MoKS5nZXRIb3N0TmFtZSgpID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIE9wZW5TU0xTZXNzaW9uSW1wbCBzZXNzaW9uID0gKE9wZW5TU0xTZXNzaW9uSW1wbCkgc2Vzc2lvbkNvbnRleHQuZ2V0U2Vzc2lvbigKKyAgICAgICAgICAgICAgICBzdXBlci5nZXRJbmV0QWRkcmVzcygpLmdldEhvc3ROYW1lKCksCisgICAgICAgICAgICAgICAgc3VwZXIuZ2V0UG9ydCgpKTsKKyAgICAgICAgaWYgKHNlc3Npb24gPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgcHJvdG9jb2wgPSBzZXNzaW9uLmdldFByb3RvY29sKCk7CisgICAgICAgIGJvb2xlYW4gcHJvdG9jb2xGb3VuZCA9IGZhbHNlOworICAgICAgICBmb3IgKFN0cmluZyBlbmFibGVkUHJvdG9jb2wgOiBlbmFibGVkUHJvdG9jb2xzKSB7CisgICAgICAgICAgICBpZiAocHJvdG9jb2wuZXF1YWxzKGVuYWJsZWRQcm90b2NvbCkpIHsKKyAgICAgICAgICAgICAgICBwcm90b2NvbEZvdW5kID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoIXByb3RvY29sRm91bmQpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGNpcGhlclN1aXRlID0gc2Vzc2lvbi5nZXRDaXBoZXJTdWl0ZSgpOworICAgICAgICBib29sZWFuIGNpcGhlclN1aXRlRm91bmQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChTdHJpbmcgZW5hYmxlZENpcGhlclN1aXRlIDogZW5hYmxlZENpcGhlclN1aXRlcykgeworICAgICAgICAgICAgaWYgKGNpcGhlclN1aXRlLmVxdWFscyhlbmFibGVkQ2lwaGVyU3VpdGUpKSB7CisgICAgICAgICAgICAgICAgY2lwaGVyU3VpdGVGb3VuZCA9IHRydWU7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFjaXBoZXJTdWl0ZUZvdW5kKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBjb21wcmVzc2lvbk1ldGhvZCA9IHNlc3Npb24uZ2V0Q29tcHJlc3Npb25NZXRob2QoKTsKKyAgICAgICAgYm9vbGVhbiBjb21wcmVzc2lvbk1ldGhvZEZvdW5kID0gZmFsc2U7CisgICAgICAgIGZvciAoU3RyaW5nIGVuYWJsZWRDb21wcmVzc2lvbk1ldGhvZCA6IGVuYWJsZWRDb21wcmVzc2lvbk1ldGhvZHMpIHsKKyAgICAgICAgICAgIGlmIChjb21wcmVzc2lvbk1ldGhvZC5lcXVhbHMoZW5hYmxlZENvbXByZXNzaW9uTWV0aG9kKSkgeworICAgICAgICAgICAgICAgIGNvbXByZXNzaW9uTWV0aG9kRm91bmQgPSB0cnVlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmICghY29tcHJlc3Npb25NZXRob2RGb3VuZCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gc2Vzc2lvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdGFydHMgYSBUTFMvU1NMIGhhbmRzaGFrZSBvbiB0aGlzIGNvbm5lY3Rpb24gdXNpbmcgc29tZSBuYXRpdmUgbWV0aG9kcworICAgICAqIGZyb20gdGhlIE9wZW5TU0wgbGlicmFyeS4gSXQgY2FuIG5lZ290aWF0ZSBuZXcgZW5jcnlwdGlvbiBrZXlzLCBjaGFuZ2UKKyAgICAgKiBjaXBoZXIgc3VpdGVzLCBvciBpbml0aWF0ZSBhIG5ldyBzZXNzaW9uLiBUaGUgY2VydGlmaWNhdGUgY2hhaW4gaXMKKyAgICAgKiB2ZXJpZmllZCBpZiB0aGUgY29ycmVzcG9uZGVudCBwcm9wZXJ0eSBpbiBqYXZhLlNlY3VyaXR5IGlzIHNldC4gQWxsCisgICAgICogbGlzdGVuZXJzIGFyZSBub3RpZmllZCBhdCB0aGUgZW5kIG9mIHRoZSBUTFMvU1NMIGhhbmRzaGFrZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzdGFydEhhbmRzaGFrZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN0YXJ0SGFuZHNoYWtlKHRydWUpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja09wZW4oKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzQ2xvc2VkKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oIlNvY2tldCBpcyBjbG9zZWQiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm0gdGhlIGhhbmRzaGFrZQorICAgICAqCisgICAgICogQHBhcmFtIGZ1bGwgSWYgdHJ1ZSwgZGlzYWJsZSBoYW5kc2hha2UgY3V0dGhyb3VnaCBmb3IgYSBmdWxseSBzeW5jaHJvbm91cyBoYW5kc2hha2UKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc3RhcnRIYW5kc2hha2UoYm9vbGVhbiBmdWxsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKGhhbmRzaGFrZUxvY2spIHsKKyAgICAgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICAgICAgaWYgKCFoYW5kc2hha2VTdGFydGVkKSB7CisgICAgICAgICAgICAgICAgaGFuZHNoYWtlU3RhcnRlZCA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIG5vdGUgdGhhdCB0aGlzIG1vZGlmaWVzIHRoZSBnbG9iYWwgc2VlZCwgbm90IHNvbWV0aGluZyBzcGVjaWZpYyB0byB0aGUgY29ubmVjdGlvbgorICAgICAgICBmaW5hbCBpbnQgc2VlZExlbmd0aEluQnl0ZXMgPSBOYXRpdmVDcnlwdG8uUkFORF9TRUVEX0xFTkdUSF9JTl9CWVRFUzsKKyAgICAgICAgZmluYWwgU2VjdXJlUmFuZG9tIHNlY3VyZVJhbmRvbSA9IHNzbFBhcmFtZXRlcnMuZ2V0U2VjdXJlUmFuZG9tTWVtYmVyKCk7CisgICAgICAgIGlmIChzZWN1cmVSYW5kb20gPT0gbnVsbCkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlJBTkRfbG9hZF9maWxlKCIvZGV2L3VyYW5kb20iLCBzZWVkTGVuZ3RoSW5CeXRlcyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uUkFORF9zZWVkKHNlY3VyZVJhbmRvbS5nZW5lcmF0ZVNlZWQoc2VlZExlbmd0aEluQnl0ZXMpKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGJvb2xlYW4gY2xpZW50ID0gc3NsUGFyYW1ldGVycy5nZXRVc2VDbGllbnRNb2RlKCk7CisKKyAgICAgICAgZmluYWwgaW50IHNzbEN0eE5hdGl2ZVBvaW50ZXIgPSAoY2xpZW50KSA/CisgICAgICAgICAgICBzc2xQYXJhbWV0ZXJzLmdldENsaWVudFNlc3Npb25Db250ZXh0KCkuc3NsQ3R4TmF0aXZlUG9pbnRlciA6CisgICAgICAgICAgICBzc2xQYXJhbWV0ZXJzLmdldFNlcnZlclNlc3Npb25Db250ZXh0KCkuc3NsQ3R4TmF0aXZlUG9pbnRlcjsKKworICAgICAgICB0aGlzLnNzbE5hdGl2ZVBvaW50ZXIgPSAwOworICAgICAgICBib29sZWFuIGV4Y2VwdGlvbiA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2xOYXRpdmVQb2ludGVyID0gTmF0aXZlQ3J5cHRvLlNTTF9uZXcoc3NsQ3R4TmF0aXZlUG9pbnRlcik7CisgICAgICAgICAgICBndWFyZC5vcGVuKCJjbG9zZSIpOworCisgICAgICAgICAgICAvLyBzZXR1cCBzZXJ2ZXIgY2VydGlmaWNhdGVzIGFuZCBwcml2YXRlIGtleXMuCisgICAgICAgICAgICAvLyBjbGllbnRzIHdpbGwgcmVjZWl2ZSBhIGNhbGwgYmFjayB0byByZXF1ZXN0IGNlcnRpZmljYXRlcy4KKyAgICAgICAgICAgIGlmICghY2xpZW50KSB7CisgICAgICAgICAgICAgICAgU2V0PFN0cmluZz4ga2V5VHlwZXMgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7CisgICAgICAgICAgICAgICAgZm9yIChTdHJpbmcgZW5hYmxlZENpcGhlclN1aXRlIDogZW5hYmxlZENpcGhlclN1aXRlcykgeworICAgICAgICAgICAgICAgICAgICBpZiAoZW5hYmxlZENpcGhlclN1aXRlLmVxdWFscyhOYXRpdmVDcnlwdG8uVExTX0VNUFRZX1JFTkVHT1RJQVRJT05fSU5GT19TQ1NWKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGtleVR5cGUgPSBDaXBoZXJTdWl0ZS5nZXRCeU5hbWUoZW5hYmxlZENpcGhlclN1aXRlKS5nZXRTZXJ2ZXJLZXlUeXBlKCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChrZXlUeXBlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGtleVR5cGVzLmFkZChrZXlUeXBlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmb3IgKFN0cmluZyBrZXlUeXBlIDoga2V5VHlwZXMpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNldENlcnRpZmljYXRlKHNzbFBhcmFtZXRlcnMuZ2V0S2V5TWFuYWdlcigpLmNob29zZVNlcnZlckFsaWFzKGtleVR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcykpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLnNldEVuYWJsZWRQcm90b2NvbHMoc3NsTmF0aXZlUG9pbnRlciwgZW5hYmxlZFByb3RvY29scyk7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uc2V0RW5hYmxlZENpcGhlclN1aXRlcyhzc2xOYXRpdmVQb2ludGVyLCBlbmFibGVkQ2lwaGVyU3VpdGVzKTsKKyAgICAgICAgICAgIGlmIChlbmFibGVkQ29tcHJlc3Npb25NZXRob2RzLmxlbmd0aCAhPSAwKSB7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLnNldEVuYWJsZWRDb21wcmVzc2lvbk1ldGhvZHMoc3NsTmF0aXZlUG9pbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkQ29tcHJlc3Npb25NZXRob2RzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh1c2VTZXNzaW9uVGlja2V0cykgeworICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfY2xlYXJfb3B0aW9ucyhzc2xOYXRpdmVQb2ludGVyLCBOYXRpdmVDcnlwdG8uU1NMX09QX05PX1RJQ0tFVCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaG9zdG5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfc2V0X3Rsc2V4dF9ob3N0X25hbWUoc3NsTmF0aXZlUG9pbnRlciwgaG9zdG5hbWUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBib29sZWFuIGVuYWJsZVNlc3Npb25DcmVhdGlvbiA9IHNzbFBhcmFtZXRlcnMuZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCk7CisgICAgICAgICAgICBpZiAoIWVuYWJsZVNlc3Npb25DcmVhdGlvbikgeworICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfc2V0X3Nlc3Npb25fY3JlYXRpb25fZW5hYmxlZChzc2xOYXRpdmVQb2ludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVTZXNzaW9uQ3JlYXRpb24pOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBBYnN0cmFjdFNlc3Npb25Db250ZXh0IHNlc3Npb25Db250ZXh0OworICAgICAgICAgICAgaWYgKGNsaWVudCkgeworICAgICAgICAgICAgICAgIC8vIGxvb2sgZm9yIGNsaWVudCBzZXNzaW9uIHRvIHJldXNlCisgICAgICAgICAgICAgICAgQ2xpZW50U2Vzc2lvbkNvbnRleHQgY2xpZW50U2Vzc2lvbkNvbnRleHQgPSBzc2xQYXJhbWV0ZXJzLmdldENsaWVudFNlc3Npb25Db250ZXh0KCk7CisgICAgICAgICAgICAgICAgc2Vzc2lvbkNvbnRleHQgPSBjbGllbnRTZXNzaW9uQ29udGV4dDsKKyAgICAgICAgICAgICAgICBPcGVuU1NMU2Vzc2lvbkltcGwgc2Vzc2lvbiA9IGdldENhY2hlZENsaWVudFNlc3Npb24oY2xpZW50U2Vzc2lvbkNvbnRleHQpOworICAgICAgICAgICAgICAgIGlmIChzZXNzaW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfc2Vzc2lvbihzc2xOYXRpdmVQb2ludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uc3NsU2Vzc2lvbk5hdGl2ZVBvaW50ZXIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc2Vzc2lvbkNvbnRleHQgPSBzc2xQYXJhbWV0ZXJzLmdldFNlcnZlclNlc3Npb25Db250ZXh0KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIHNldHVwIHBlZXIgY2VydGlmaWNhdGUgdmVyaWZpY2F0aW9uCisgICAgICAgICAgICBpZiAoY2xpZW50KSB7CisgICAgICAgICAgICAgICAgLy8gVE9ETyBzdXBwb3J0IGZvciBhbm9ueW1vdXMgY2lwaGVyIHdvdWxkIHJlcXVpcmUgdXMgdG8KKyAgICAgICAgICAgICAgICAvLyBjb25kaXRpb25hbGx5IHVzZSBTU0xfVkVSSUZZX05PTkUKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gbmVlZGluZyBjbGllbnQgYXV0aCB0YWtlcyBwcmlvcml0eS4uLgorICAgICAgICAgICAgICAgIGJvb2xlYW4gY2VydFJlcXVlc3RlZDsKKyAgICAgICAgICAgICAgICBpZiAoc3NsUGFyYW1ldGVycy5nZXROZWVkQ2xpZW50QXV0aCgpKSB7CisgICAgICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfc2V0X3ZlcmlmeShzc2xOYXRpdmVQb2ludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9WRVJJRllfUEVFUgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBOYXRpdmVDcnlwdG8uU1NMX1ZFUklGWV9GQUlMX0lGX05PX1BFRVJfQ0VSVCk7CisgICAgICAgICAgICAgICAgICAgIGNlcnRSZXF1ZXN0ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIC8vIC4uLiBvdmVyIGp1c3Qgd2FudGluZyBpdC4uLgorICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3NsUGFyYW1ldGVycy5nZXRXYW50Q2xpZW50QXV0aCgpKSB7CisgICAgICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfc2V0X3ZlcmlmeShzc2xOYXRpdmVQb2ludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9WRVJJRllfUEVFUik7CisgICAgICAgICAgICAgICAgICAgIGNlcnRSZXF1ZXN0ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIC8vIC4uLiBhbmQgaXQgZGVmYXVsdHMgcHJvcGVybHkgc28gZG9uJ3QgY2FsbCBTU0xfc2V0X3ZlcmlmeSBpbiB0aGUgY29tbW9uIGNhc2UuCisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgY2VydFJlcXVlc3RlZCA9IGZhbHNlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChjZXJ0UmVxdWVzdGVkKSB7CisgICAgICAgICAgICAgICAgICAgIFg1MDlUcnVzdE1hbmFnZXIgdHJ1c3RNYW5hZ2VyID0gc3NsUGFyYW1ldGVycy5nZXRUcnVzdE1hbmFnZXIoKTsKKyAgICAgICAgICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlW10gaXNzdWVycyA9IHRydXN0TWFuYWdlci5nZXRBY2NlcHRlZElzc3VlcnMoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGlzc3VlcnMgIT0gbnVsbCAmJiBpc3N1ZXJzLmxlbmd0aCAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBieXRlW11bXSBpc3N1ZXJzQnl0ZXM7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzc3VlcnNCeXRlcyA9IE5hdGl2ZUNyeXB0by5lbmNvZGVJc3N1ZXJYNTA5UHJpbmNpcGFscyhpc3N1ZXJzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUHJvYmxlbSBlbmNvZGluZyBwcmluY2lwYWxzIiwgZSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3NldF9jbGllbnRfQ0FfbGlzdChzc2xOYXRpdmVQb2ludGVyLCBpc3N1ZXJzQnl0ZXMpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoY2xpZW50ICYmIGZ1bGwpIHsKKyAgICAgICAgICAgICAgICAvLyB3ZSB3YW50IHRvIGRvIGEgZnVsbCBzeW5jaHJvbm91cyBoYW5kc2hha2UsIHNvIHR1cm4gb2ZmIGN1dHRocm91Z2gKKyAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2NsZWFyX21vZGUoc3NsTmF0aXZlUG9pbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9NT0RFX0hBTkRTSEFLRV9DVVRUSFJPVUdIKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gVGVtcG9yYXJpbHkgdXNlIGEgZGlmZmVyZW50IHRpbWVvdXQgZm9yIHRoZSBoYW5kc2hha2UgcHJvY2VzcworICAgICAgICAgICAgaW50IHNhdmVkVGltZW91dE1pbGxpc2Vjb25kcyA9IGdldFNvVGltZW91dCgpOworICAgICAgICAgICAgaWYgKGhhbmRzaGFrZVRpbWVvdXRNaWxsaXNlY29uZHMgPj0gMCkgeworICAgICAgICAgICAgICAgIHNldFNvVGltZW91dChoYW5kc2hha2VUaW1lb3V0TWlsbGlzZWNvbmRzKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IHNzbFNlc3Npb25OYXRpdmVQb2ludGVyOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzc2xTZXNzaW9uTmF0aXZlUG9pbnRlciA9IE5hdGl2ZUNyeXB0by5TU0xfZG9faGFuZHNoYWtlKHNzbE5hdGl2ZVBvaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICBzb2NrZXQuZ2V0RmlsZURlc2NyaXB0b3IkKCksIHRoaXMsIGdldFNvVGltZW91dCgpLCBjbGllbnQpOworICAgICAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIFNTTEhhbmRzaGFrZUV4Y2VwdGlvbiB3cmFwcGVyID0gbmV3IFNTTEhhbmRzaGFrZUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICAgICAgd3JhcHBlci5pbml0Q2F1c2UoZSk7CisgICAgICAgICAgICAgICAgdGhyb3cgd3JhcHBlcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ5dGVbXSBzZXNzaW9uSWQgPSBOYXRpdmVDcnlwdG8uU1NMX1NFU1NJT05fc2Vzc2lvbl9pZChzc2xTZXNzaW9uTmF0aXZlUG9pbnRlcik7CisgICAgICAgICAgICBzc2xTZXNzaW9uID0gKE9wZW5TU0xTZXNzaW9uSW1wbCkgc2Vzc2lvbkNvbnRleHQuZ2V0U2Vzc2lvbihzZXNzaW9uSWQpOworICAgICAgICAgICAgaWYgKHNzbFNlc3Npb24gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNzbFNlc3Npb24ubGFzdEFjY2Vzc2VkVGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfU0VTU0lPTl9mcmVlKHNzbFNlc3Npb25OYXRpdmVQb2ludGVyKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKCFlbmFibGVTZXNzaW9uQ3JlYXRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gU2hvdWxkIGhhdmUgYmVlbiBwcmV2ZW50ZWQgYnkgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfc2Vzc2lvbl9jcmVhdGlvbl9lbmFibGVkCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIlNTTCBTZXNzaW9uIG1heSBub3QgYmUgY3JlYXRlZCIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGVbXSBsb2NhbENlcnRpZmljYXRlcworICAgICAgICAgICAgICAgICAgICAgICAgPSBjcmVhdGVDZXJ0Q2hhaW4oTmF0aXZlQ3J5cHRvLlNTTF9nZXRfY2VydGlmaWNhdGUoc3NsTmF0aXZlUG9pbnRlcikpOworICAgICAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIHBlZXJDZXJ0aWZpY2F0ZXMKKyAgICAgICAgICAgICAgICAgICAgICAgID0gY3JlYXRlQ2VydENoYWluKE5hdGl2ZUNyeXB0by5TU0xfZ2V0X3BlZXJfY2VydF9jaGFpbihzc2xOYXRpdmVQb2ludGVyKSk7CisgICAgICAgICAgICAgICAgaWYgKHdyYXBwZWRIb3N0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgc3NsU2Vzc2lvbiA9IG5ldyBPcGVuU1NMU2Vzc2lvbkltcGwoc3NsU2Vzc2lvbk5hdGl2ZVBvaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsQ2VydGlmaWNhdGVzLCBwZWVyQ2VydGlmaWNhdGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBlci5nZXRJbmV0QWRkcmVzcygpLmdldEhvc3ROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cGVyLmdldFBvcnQoKSwgc2Vzc2lvbkNvbnRleHQpOworICAgICAgICAgICAgICAgIH0gZWxzZSAgeworICAgICAgICAgICAgICAgICAgICBzc2xTZXNzaW9uID0gbmV3IE9wZW5TU0xTZXNzaW9uSW1wbChzc2xTZXNzaW9uTmF0aXZlUG9pbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDZXJ0aWZpY2F0ZXMsIHBlZXJDZXJ0aWZpY2F0ZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyYXBwZWRIb3N0LCB3cmFwcGVkUG9ydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbkNvbnRleHQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBpZiBub3QsIHB1dFNlc3Npb24gbGF0ZXIgaW4gaGFuZHNoYWtlQ29tcGxldGVkKCkgY2FsbGJhY2sKKyAgICAgICAgICAgICAgICBpZiAoaGFuZHNoYWtlQ29tcGxldGVkKSB7CisgICAgICAgICAgICAgICAgICAgIHNlc3Npb25Db250ZXh0LnB1dFNlc3Npb24oc3NsU2Vzc2lvbik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBSZXN0b3JlIHRoZSBvcmlnaW5hbCB0aW1lb3V0IG5vdyB0aGF0IHRoZSBoYW5kc2hha2UgaXMgY29tcGxldGUKKyAgICAgICAgICAgIGlmIChoYW5kc2hha2VUaW1lb3V0TWlsbGlzZWNvbmRzID49IDApIHsKKyAgICAgICAgICAgICAgICBzZXRTb1RpbWVvdXQoc2F2ZWRUaW1lb3V0TWlsbGlzZWNvbmRzKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gaWYgbm90LCBub3RpZnlIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lcnMgbGF0ZXIgaW4gaGFuZHNoYWtlQ29tcGxldGVkKCkgY2FsbGJhY2sKKyAgICAgICAgICAgIGlmIChoYW5kc2hha2VDb21wbGV0ZWQpIHsKKyAgICAgICAgICAgICAgICBub3RpZnlIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lcnMoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZXhjZXB0aW9uID0gZmFsc2U7CisgICAgICAgIH0gY2F0Y2ggKFNTTFByb3RvY29sRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTU0xIYW5kc2hha2VFeGNlcHRpb24oZSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAvLyBvbiBleGNlcHRpb25hbCBleGl0LCB0cmVhdCB0aGUgc29ja2V0IGFzIGNsb3NlZAorICAgICAgICAgICAgaWYgKGV4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgIGNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBwb3NzaWJseSBudWxsIGFycmF5IG9mIFg1MDlDZXJ0aWZpY2F0ZXMgZ2l2ZW4gdGhlCisgICAgICogcG9zc2libHkgbnVsbCBhcnJheSBvZiBERVIgZW5jb2RlZCBieXRlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBYNTA5Q2VydGlmaWNhdGVbXSBjcmVhdGVDZXJ0Q2hhaW4oYnl0ZVtdW10gY2VydGlmaWNhdGVzQnl0ZXMpIHsKKyAgICAgICAgaWYgKGNlcnRpZmljYXRlc0J5dGVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIGNlcnRpZmljYXRlcyA9IG5ldyBYNTA5Q2VydGlmaWNhdGVbY2VydGlmaWNhdGVzQnl0ZXMubGVuZ3RoXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjZXJ0aWZpY2F0ZXNCeXRlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjZXJ0aWZpY2F0ZXNbaV0gPSBuZXcgWDUwOUNlcnRJbXBsKGNlcnRpZmljYXRlc0J5dGVzW2ldKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2VydGlmaWNhdGVzOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzZXRDZXJ0aWZpY2F0ZShTdHJpbmcgYWxpYXMpIHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uLCBTU0xFeGNlcHRpb24geworICAgICAgICBpZiAoYWxpYXMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFByaXZhdGVLZXkgcHJpdmF0ZUtleSA9IHNzbFBhcmFtZXRlcnMuZ2V0S2V5TWFuYWdlcigpLmdldFByaXZhdGVLZXkoYWxpYXMpOworICAgICAgICBpZiAocHJpdmF0ZUtleSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgWDUwOUNlcnRpZmljYXRlW10gY2VydGlmaWNhdGVzID0gc3NsUGFyYW1ldGVycy5nZXRLZXlNYW5hZ2VyKCkuZ2V0Q2VydGlmaWNhdGVDaGFpbihhbGlhcyk7CisgICAgICAgIGlmIChjZXJ0aWZpY2F0ZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZVtdIHByaXZhdGVLZXlCeXRlcyA9IHByaXZhdGVLZXkuZ2V0RW5jb2RlZCgpOworICAgICAgICBieXRlW11bXSBjZXJ0aWZpY2F0ZUJ5dGVzID0gTmF0aXZlQ3J5cHRvLmVuY29kZUNlcnRpZmljYXRlcyhjZXJ0aWZpY2F0ZXMpOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3VzZV9Qcml2YXRlS2V5KHNzbE5hdGl2ZVBvaW50ZXIsIHByaXZhdGVLZXlCeXRlcyk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfdXNlX2NlcnRpZmljYXRlKHNzbE5hdGl2ZVBvaW50ZXIsIGNlcnRpZmljYXRlQnl0ZXMpOworCisgICAgICAgIC8vIGNoZWNrcyB0aGUgbGFzdCBpbnN0YWxsZWQgcHJpdmF0ZSBrZXkgYW5kIGNlcnRpZmljYXRlLAorICAgICAgICAvLyBzbyBuZWVkIHRvIGRvIHRoaXMgb25jZSBwZXIgbG9vcCBpdGVyYXRpb24KKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9jaGVja19wcml2YXRlX2tleShzc2xOYXRpdmVQb2ludGVyKTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikgLy8gdXNlZCBieSBOYXRpdmVDcnlwdG8uU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIC8gY2xpZW50X2NlcnRfY2IKKyAgICBwdWJsaWMgdm9pZCBjbGllbnRDZXJ0aWZpY2F0ZVJlcXVlc3RlZChieXRlW10ga2V5VHlwZUJ5dGVzLCBieXRlW11bXSBhc24xRGVyRW5jb2RlZFByaW5jaXBhbHMpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiwgU1NMRXhjZXB0aW9uIHsKKworICAgICAgICBTdHJpbmdbXSBrZXlUeXBlcyA9IG5ldyBTdHJpbmdba2V5VHlwZUJ5dGVzLmxlbmd0aF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga2V5VHlwZUJ5dGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBrZXlUeXBlc1tpXSA9IENpcGhlclN1aXRlLmdldENsaWVudEtleVR5cGUoa2V5VHlwZUJ5dGVzW2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIFg1MDBQcmluY2lwYWxbXSBpc3N1ZXJzOworICAgICAgICBpZiAoYXNuMURlckVuY29kZWRQcmluY2lwYWxzID09IG51bGwpIHsKKyAgICAgICAgICAgIGlzc3VlcnMgPSBudWxsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaXNzdWVycyA9IG5ldyBYNTAwUHJpbmNpcGFsW2FzbjFEZXJFbmNvZGVkUHJpbmNpcGFscy5sZW5ndGhdOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhc24xRGVyRW5jb2RlZFByaW5jaXBhbHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpc3N1ZXJzW2ldID0gbmV3IFg1MDBQcmluY2lwYWwoYXNuMURlckVuY29kZWRQcmluY2lwYWxzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzZXRDZXJ0aWZpY2F0ZShzc2xQYXJhbWV0ZXJzLmdldEtleU1hbmFnZXIoKS5jaG9vc2VDbGllbnRBbGlhcyhrZXlUeXBlcywgaXNzdWVycywgdGhpcykpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKSAvLyB1c2VkIGJ5IE5hdGl2ZUNyeXB0by5TU0xIYW5kc2hha2VDYWxsYmFja3MgLyBpbmZvX2NhbGxiYWNrCisgICAgcHVibGljIHZvaWQgaGFuZHNoYWtlQ29tcGxldGVkKCkgeworICAgICAgICBoYW5kc2hha2VDb21wbGV0ZWQgPSB0cnVlOworCisgICAgICAgIC8vIElmIHNzbFNlc3Npb24gaXMgbnVsbCwgdGhlIGhhbmRzaGFrZSB3YXMgY29tcGxldGVkIGR1cmluZworICAgICAgICAvLyB0aGUgY2FsbCB0byBOYXRpdmVDcnlwdG8uU1NMX2RvX2hhbmRzaGFrZSBhbmQgbm90IGR1cmluZyBhCisgICAgICAgIC8vIGxhdGVyIHJlYWQgb3BlcmF0aW9uLiBUaGF0IG1lYW5zIHdlIGRvIG5vdCBuZWVkIHRvIGZpeCB1cAorICAgICAgICAvLyB0aGUgU1NMU2Vzc2lvbiBhbmQgc2Vzc2lvbiBjYWNoZSBvciBub3RpZnkKKyAgICAgICAgLy8gSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXJzLCBpdCB3aWxsIGJlIGRvbmUgaW4KKyAgICAgICAgLy8gc3RhcnRIYW5kc2hha2UuCisgICAgICAgIGlmIChzc2xTZXNzaW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHJlc2V0IHNlc3Npb24gaWQgZnJvbSB0aGUgbmF0aXZlIHBvaW50ZXIgYW5kIHVwZGF0ZSB0aGUKKyAgICAgICAgLy8gYXBwcm9wcmlhdGUgY2FjaGUuCisgICAgICAgIHNzbFNlc3Npb24ucmVzZXRJZCgpOworICAgICAgICBBYnN0cmFjdFNlc3Npb25Db250ZXh0IHNlc3Npb25Db250ZXh0ID0KKyAgICAgICAgICAgIChzc2xQYXJhbWV0ZXJzLmdldFVzZUNsaWVudE1vZGUoKSkKKyAgICAgICAgICAgID8gc3NsUGFyYW1ldGVycy5nZXRDbGllbnRTZXNzaW9uQ29udGV4dCgpCisgICAgICAgICAgICAgICAgOiBzc2xQYXJhbWV0ZXJzLmdldFNlcnZlclNlc3Npb25Db250ZXh0KCk7CisgICAgICAgIHNlc3Npb25Db250ZXh0LnB1dFNlc3Npb24oc3NsU2Vzc2lvbik7CisKKyAgICAgICAgLy8gbGV0IGxpc3RlbmVycyBrbm93IHdlIGFyZSBmaW5hbGx5IGRvbmUKKyAgICAgICAgbm90aWZ5SGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXJzKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG5vdGlmeUhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVycygpIHsKKyAgICAgICAgaWYgKGxpc3RlbmVycyAhPSBudWxsICYmICFsaXN0ZW5lcnMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAvLyBub3RpZnkgdGhlIGxpc3RlbmVycworICAgICAgICAgICAgSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQgZXZlbnQgPQorICAgICAgICAgICAgICAgIG5ldyBIYW5kc2hha2VDb21wbGV0ZWRFdmVudCh0aGlzLCBzc2xTZXNzaW9uKTsKKyAgICAgICAgICAgIGZvciAoSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXIgbGlzdGVuZXIgOiBsaXN0ZW5lcnMpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lci5oYW5kc2hha2VDb21wbGV0ZWQoZXZlbnQpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAvLyBUaGUgUkkgcnVucyB0aGUgaGFuZGxlcnMgaW4gYSBzZXBhcmF0ZSB0aHJlYWQsCisgICAgICAgICAgICAgICAgICAgIC8vIHdoaWNoIHdlIGRvIG5vdC4gQnV0IHdlIHRyeSB0byBwcmVzZXJ2ZSB0aGVpcgorICAgICAgICAgICAgICAgICAgICAvLyBiZWhhdmlvciBvZiBsb2dnaW5nIGEgcHJvYmxlbSBhbmQgbm90IGtpbGxpbmcKKyAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGhhbmRzaGFraW5nIHRocmVhZCBqdXN0IGJlY2F1c2UgYSBsaXN0ZW5lcgorICAgICAgICAgICAgICAgICAgICAvLyBoYXMgYSBwcm9ibGVtLgorICAgICAgICAgICAgICAgICAgICBUaHJlYWQgdGhyZWFkID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKyAgICAgICAgICAgICAgICAgICAgdGhyZWFkLmdldFVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlcigpLnVuY2F1Z2h0RXhjZXB0aW9uKHRocmVhZCwgZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpIC8vIHVzZWQgYnkgTmF0aXZlQ3J5cHRvLlNTTEhhbmRzaGFrZUNhbGxiYWNrcworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCB2ZXJpZnlDZXJ0aWZpY2F0ZUNoYWluKGJ5dGVbXVtdIGJ5dGVzLCBTdHJpbmcgYXV0aE1ldGhvZCkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoYnl0ZXMgPT0gbnVsbCB8fCBieXRlcy5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTU0xFeGNlcHRpb24oIlBlZXIgc2VudCBubyBjZXJ0aWZpY2F0ZSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlW10gcGVlckNlcnRpZmljYXRlQ2hhaW4gPSBuZXcgWDUwOUNlcnRpZmljYXRlW2J5dGVzLmxlbmd0aF07CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgcGVlckNlcnRpZmljYXRlQ2hhaW5baV0gPSBuZXcgWDUwOUNlcnRJbXBsKGJ5dGVzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJvb2xlYW4gY2xpZW50ID0gc3NsUGFyYW1ldGVycy5nZXRVc2VDbGllbnRNb2RlKCk7CisgICAgICAgICAgICBpZiAoY2xpZW50KSB7CisgICAgICAgICAgICAgICAgc3NsUGFyYW1ldGVycy5nZXRUcnVzdE1hbmFnZXIoKS5jaGVja1NlcnZlclRydXN0ZWQocGVlckNlcnRpZmljYXRlQ2hhaW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0aE1ldGhvZCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIFN0cmluZyBhdXRoVHlwZSA9IHBlZXJDZXJ0aWZpY2F0ZUNoYWluWzBdLmdldFB1YmxpY0tleSgpLmdldEFsZ29yaXRobSgpOworICAgICAgICAgICAgICAgIHNzbFBhcmFtZXRlcnMuZ2V0VHJ1c3RNYW5hZ2VyKCkuY2hlY2tDbGllbnRUcnVzdGVkKHBlZXJDZXJ0aWZpY2F0ZUNoYWluLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dGhUeXBlKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICBpZiAoaXMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlzID0gbmV3IFNTTElucHV0U3RyZWFtKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBpczsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgT3V0cHV0U3RyZWFtIGdldE91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrT3BlbigpOworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGlmIChvcyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgb3MgPSBuZXcgU1NMT3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBvczsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgaW5uZXIgY2xhc3MgcHJvdmlkZXMgaW5wdXQgZGF0YSBzdHJlYW0gZnVuY3Rpb25hbGl0eQorICAgICAqIGZvciB0aGUgT3BlblNTTCBuYXRpdmUgaW1wbGVtZW50YXRpb24uIEl0IGlzIHVzZWQgdG8KKyAgICAgKiByZWFkIGRhdGEgcmVjZWl2ZWQgdmlhIFNTTCBwcm90b2NvbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGNsYXNzIFNTTElucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworICAgICAgICBTU0xJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgIC8qIE5vdGU6IFdoZW4gc3RhcnRIYW5kc2hha2UoKSB0aHJvd3MgYW4gZXhjZXB0aW9uLCBubworICAgICAgICAgICAgICogU1NMSW5wdXRTdHJlYW0gb2JqZWN0IHdpbGwgYmUgY3JlYXRlZC4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgT3BlblNTTFNvY2tldEltcGwudGhpcy5zdGFydEhhbmRzaGFrZShmYWxzZSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmVhZHMgb25lIGJ5dGUuIElmIHRoZXJlIGlzIG5vIGRhdGEgaW4gdGhlIHVuZGVybHlpbmcgYnVmZmVyLAorICAgICAgICAgKiB0aGlzIG9wZXJhdGlvbiBjYW4gYmxvY2sgdW50aWwgdGhlIGRhdGEgd2lsbCBiZQorICAgICAgICAgKiBhdmFpbGFibGUuCisgICAgICAgICAqIEByZXR1cm4gcmVhZCB2YWx1ZS4KKyAgICAgICAgICogQHRocm93cyA8Y29kZT5JT0V4Y2VwdGlvbjwvY29kZT4KKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIFN0cmVhbXMucmVhZFNpbmdsZUJ5dGUodGhpcyk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogTWV0aG9kIGFjdHMgYXMgZGVzY3JpYmVkIGluIHNwZWMgZm9yIHN1cGVyY2xhc3MuCisgICAgICAgICAqIEBzZWUgamF2YS5pby5JbnB1dFN0cmVhbSNyZWFkKGJ5dGVbXSxpbnQsaW50KQorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmLCBpbnQgb2Zmc2V0LCBpbnQgYnl0ZUNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgQmxvY2tHdWFyZC5nZXRUaHJlYWRQb2xpY3koKS5vbk5ldHdvcmsoKTsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAocmVhZExvY2spIHsKKyAgICAgICAgICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWYubGVuZ3RoLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgICAgICAgICAgaWYgKGJ5dGVDb3VudCA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gTmF0aXZlQ3J5cHRvLlNTTF9yZWFkKHNzbE5hdGl2ZVBvaW50ZXIsIHNvY2tldC5nZXRGaWxlRGVzY3JpcHRvciQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5TU0xTb2NrZXRJbXBsLnRoaXMsIGJ1Ziwgb2Zmc2V0LCBieXRlQ291bnQsIGdldFNvVGltZW91dCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgaW5uZXIgY2xhc3MgcHJvdmlkZXMgb3V0cHV0IGRhdGEgc3RyZWFtIGZ1bmN0aW9uYWxpdHkKKyAgICAgKiBmb3IgdGhlIE9wZW5TU0wgbmF0aXZlIGltcGxlbWVudGF0aW9uLiBJdCBpcyB1c2VkIHRvCisgICAgICogd3JpdGUgZGF0YSBhY2NvcmRpbmcgdG8gdGhlIGVuY3J5cHRpb24gcGFyYW1ldGVycyBnaXZlbiBpbiBTU0wgY29udGV4dC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGNsYXNzIFNTTE91dHB1dFN0cmVhbSBleHRlbmRzIE91dHB1dFN0cmVhbSB7CisgICAgICAgIFNTTE91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgIC8qIE5vdGU6IFdoZW4gc3RhcnRIYW5kc2hha2UoKSB0aHJvd3MgYW4gZXhjZXB0aW9uLCBubworICAgICAgICAgICAgICogU1NMT3V0cHV0U3RyZWFtIG9iamVjdCB3aWxsIGJlIGNyZWF0ZWQuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIE9wZW5TU0xTb2NrZXRJbXBsLnRoaXMuc3RhcnRIYW5kc2hha2UoZmFsc2UpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE1ldGhvZCBhY3RzIGFzIGRlc2NyaWJlZCBpbiBzcGVjIGZvciBzdXBlcmNsYXNzLgorICAgICAgICAgKiBAc2VlIGphdmEuaW8uT3V0cHV0U3RyZWFtI3dyaXRlKGludCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgb25lQnl0ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIFN0cmVhbXMud3JpdGVTaW5nbGVCeXRlKHRoaXMsIG9uZUJ5dGUpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE1ldGhvZCBhY3RzIGFzIGRlc2NyaWJlZCBpbiBzcGVjIGZvciBzdXBlcmNsYXNzLgorICAgICAgICAgKiBAc2VlIGphdmEuaW8uT3V0cHV0U3RyZWFtI3dyaXRlKGJ5dGVbXSxpbnQsaW50KQorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBidWYsIGludCBvZmZzZXQsIGludCBieXRlQ291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBCbG9ja0d1YXJkLmdldFRocmVhZFBvbGljeSgpLm9uTmV0d29yaygpOworICAgICAgICAgICAgc3luY2hyb25pemVkICh3cml0ZUxvY2spIHsKKyAgICAgICAgICAgICAgICBjaGVja09wZW4oKTsKKyAgICAgICAgICAgICAgICBBcnJheXMuY2hlY2tPZmZzZXRBbmRDb3VudChidWYubGVuZ3RoLCBvZmZzZXQsIGJ5dGVDb3VudCk7CisgICAgICAgICAgICAgICAgaWYgKGJ5dGVDb3VudCA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF93cml0ZShzc2xOYXRpdmVQb2ludGVyLCBzb2NrZXQuZ2V0RmlsZURlc2NyaXB0b3IkKCksCisgICAgICAgICAgICAgICAgICAgICAgICBPcGVuU1NMU29ja2V0SW1wbC50aGlzLCBidWYsIG9mZnNldCwgYnl0ZUNvdW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTU0xTZXNzaW9uIGdldFNlc3Npb24oKSB7CisgICAgICAgIGlmIChzc2xTZXNzaW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3RhcnRIYW5kc2hha2UodHJ1ZSk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gcmV0dXJuIGFuIGludmFsaWQgc2Vzc2lvbiB3aXRoCisgICAgICAgICAgICAgICAgLy8gaW52YWxpZCBjaXBoZXIgc3VpdGUgb2YgIlNTTF9OVUxMX1dJVEhfTlVMTF9OVUxMIgorICAgICAgICAgICAgICAgIHJldHVybiBTU0xTZXNzaW9uSW1wbC5OVUxMX1NFU1NJT047CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNzbFNlc3Npb247CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGFkZEhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyKAorICAgICAgICAgICAgSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXIgbGlzdGVuZXIpIHsKKyAgICAgICAgaWYgKGxpc3RlbmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlByb3ZpZGVkIGxpc3RlbmVyIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobGlzdGVuZXJzID09IG51bGwpIHsKKyAgICAgICAgICAgIGxpc3RlbmVycyA9IG5ldyBBcnJheUxpc3Q8SGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXI+KCk7CisgICAgICAgIH0KKyAgICAgICAgbGlzdGVuZXJzLmFkZChsaXN0ZW5lcik7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHJlbW92ZUhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyKAorICAgICAgICAgICAgSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXIgbGlzdGVuZXIpIHsKKyAgICAgICAgaWYgKGxpc3RlbmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlByb3ZpZGVkIGxpc3RlbmVyIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobGlzdGVuZXJzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJQcm92aWRlZCBsaXN0ZW5lciBpcyBub3QgcmVnaXN0ZXJlZCIpOworICAgICAgICB9CisgICAgICAgIGlmICghbGlzdGVuZXJzLnJlbW92ZShsaXN0ZW5lcikpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJQcm92aWRlZCBsaXN0ZW5lciBpcyBub3QgcmVnaXN0ZXJlZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGdldEVuYWJsZVNlc3Npb25DcmVhdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIHNzbFBhcmFtZXRlcnMuZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHNldEVuYWJsZVNlc3Npb25DcmVhdGlvbihib29sZWFuIGZsYWcpIHsKKyAgICAgICAgc3NsUGFyYW1ldGVycy5zZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oZmxhZyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmdbXSBnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSB7CisgICAgICAgIHJldHVybiBOYXRpdmVDcnlwdG8uZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmdbXSBnZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCkgeworICAgICAgICByZXR1cm4gZW5hYmxlZENpcGhlclN1aXRlcy5jbG9uZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBzZXRFbmFibGVkQ2lwaGVyU3VpdGVzKFN0cmluZ1tdIHN1aXRlcykgeworICAgICAgICBlbmFibGVkQ2lwaGVyU3VpdGVzID0gTmF0aXZlQ3J5cHRvLmNoZWNrRW5hYmxlZENpcGhlclN1aXRlcyhzdWl0ZXMpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nW10gZ2V0U3VwcG9ydGVkUHJvdG9jb2xzKCkgeworICAgICAgICByZXR1cm4gTmF0aXZlQ3J5cHRvLmdldFN1cHBvcnRlZFByb3RvY29scygpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nW10gZ2V0RW5hYmxlZFByb3RvY29scygpIHsKKyAgICAgICAgcmV0dXJuIGVuYWJsZWRQcm90b2NvbHMuY2xvbmUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2V0RW5hYmxlZFByb3RvY29scyhTdHJpbmdbXSBwcm90b2NvbHMpIHsKKyAgICAgICAgZW5hYmxlZFByb3RvY29scyA9IE5hdGl2ZUNyeXB0by5jaGVja0VuYWJsZWRQcm90b2NvbHMocHJvdG9jb2xzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgbmFtZXMgb2YgdGhlIGNvbXByZXNzaW9uIG1ldGhvZHMgdGhhdCBtYXkgYmUgdXNlZCBvbiB0aGlzIFNTTAorICAgICAqIGNvbm5lY3Rpb24uCisgICAgICogQHJldHVybiBhbiBhcnJheSBvZiBjb21wcmVzc2lvbiBtZXRob2RzCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIGdldFN1cHBvcnRlZENvbXByZXNzaW9uTWV0aG9kcygpIHsKKyAgICAgICAgcmV0dXJuIE5hdGl2ZUNyeXB0by5nZXRTdXBwb3J0ZWRDb21wcmVzc2lvbk1ldGhvZHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgbmFtZXMgb2YgdGhlIGNvbXByZXNzaW9uIG1ldGhvZHMgdmVyc2lvbnMgdGhhdCBhcmUgaW4gdXNlCisgICAgICogb24gdGhpcyBTU0wgY29ubmVjdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgY29tcHJlc3Npb24gbWV0aG9kcworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRFbmFibGVkQ29tcHJlc3Npb25NZXRob2RzKCkgeworICAgICAgICByZXR1cm4gZW5hYmxlZENvbXByZXNzaW9uTWV0aG9kcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuYWJsZXMgY29tcHJlc3Npb24gbWV0aG9kcyBsaXN0ZWQgYnkgZ2V0U3VwcG9ydGVkQ29tcHJlc3Npb25NZXRob2RzKCkuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aGVuIG9uZSBvciBtb3JlIG9mIHRoZSBuYW1lcyBpbiB0aGUKKyAgICAgKiAgICAgICAgICAgICBhcnJheSBhcmUgbm90IHN1cHBvcnRlZCwgb3Igd2hlbiB0aGUgYXJyYXkgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRFbmFibGVkQ29tcHJlc3Npb25NZXRob2RzKFN0cmluZ1tdIG1ldGhvZHMpIHsKKyAgICAgICAgZW5hYmxlZENvbXByZXNzaW9uTWV0aG9kcyA9IE5hdGl2ZUNyeXB0by5jaGVja0VuYWJsZWRDb21wcmVzc2lvbk1ldGhvZHMobWV0aG9kcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgZW5hYmxlcyBzZXNzaW9uIHRpY2tldCBzdXBwb3J0LgorICAgICAqCisgICAgICogQHBhcmFtIHVzZVNlc3Npb25UaWNrZXRzIFRydWUgdG8gZW5hYmxlIHNlc3Npb24gdGlja2V0cworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFVzZVNlc3Npb25UaWNrZXRzKGJvb2xlYW4gdXNlU2Vzc2lvblRpY2tldHMpIHsKKyAgICAgICAgdGhpcy51c2VTZXNzaW9uVGlja2V0cyA9IHVzZVNlc3Npb25UaWNrZXRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGVuYWJsZXMgU2VydmVyIE5hbWUgSW5kaWNhdGlvbgorICAgICAqCisgICAgICogQHBhcmFtIGhvc3RuYW1lIHRoZSBkZXNpcmVkIFNOSSBob3N0bmFtZSwgb3IgbnVsbCB0byBkaXNhYmxlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SG9zdG5hbWUoU3RyaW5nIGhvc3RuYW1lKSB7CisgICAgICAgIHRoaXMuaG9zdG5hbWUgPSBob3N0bmFtZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZ2V0VXNlQ2xpZW50TW9kZSgpIHsKKyAgICAgICAgcmV0dXJuIHNzbFBhcmFtZXRlcnMuZ2V0VXNlQ2xpZW50TW9kZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBzZXRVc2VDbGllbnRNb2RlKGJvb2xlYW4gbW9kZSkgeworICAgICAgICBpZiAoaGFuZHNoYWtlU3RhcnRlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgIkNvdWxkIG5vdCBjaGFuZ2UgdGhlIG1vZGUgYWZ0ZXIgdGhlIGluaXRpYWwgaGFuZHNoYWtlIGhhcyBiZWd1bi4iKTsKKyAgICAgICAgfQorICAgICAgICBzc2xQYXJhbWV0ZXJzLnNldFVzZUNsaWVudE1vZGUobW9kZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGdldFdhbnRDbGllbnRBdXRoKCkgeworICAgICAgICByZXR1cm4gc3NsUGFyYW1ldGVycy5nZXRXYW50Q2xpZW50QXV0aCgpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBnZXROZWVkQ2xpZW50QXV0aCgpIHsKKyAgICAgICAgcmV0dXJuIHNzbFBhcmFtZXRlcnMuZ2V0TmVlZENsaWVudEF1dGgoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2V0TmVlZENsaWVudEF1dGgoYm9vbGVhbiBuZWVkKSB7CisgICAgICAgIHNzbFBhcmFtZXRlcnMuc2V0TmVlZENsaWVudEF1dGgobmVlZCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHNldFdhbnRDbGllbnRBdXRoKGJvb2xlYW4gd2FudCkgeworICAgICAgICBzc2xQYXJhbWV0ZXJzLnNldFdhbnRDbGllbnRBdXRoKHdhbnQpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBzZW5kVXJnZW50RGF0YShpbnQgZGF0YSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbigiTWV0aG9kIHNlbmRVcmdlbnREYXRhKCkgaXMgbm90IHN1cHBvcnRlZC4iKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2V0T09CSW5saW5lKGJvb2xlYW4gb24pIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKCJNZXRob2RzIHNlbmRVcmdlbnREYXRhLCBzZXRPT0JJbmxpbmUgYXJlIG5vdCBzdXBwb3J0ZWQuIik7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHNldFNvVGltZW91dChpbnQgdGltZW91dE1pbGxpc2Vjb25kcykgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFNvVGltZW91dCh0aW1lb3V0TWlsbGlzZWNvbmRzKTsKKyAgICAgICAgdGhpcy50aW1lb3V0TWlsbGlzZWNvbmRzID0gdGltZW91dE1pbGxpc2Vjb25kczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCBnZXRTb1RpbWVvdXQoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHRpbWVvdXRNaWxsaXNlY29uZHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBoYW5kc2hha2UgdGltZW91dCBvbiB0aGlzIHNvY2tldC4gIFRoaXMgdGltZW91dCBpcyBzcGVjaWZpZWQgaW4KKyAgICAgKiBtaWxsaXNlY29uZHMgYW5kIHdpbGwgYmUgdXNlZCBvbmx5IGR1cmluZyB0aGUgaGFuZHNoYWtlIHByb2Nlc3MuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SGFuZHNoYWtlVGltZW91dChpbnQgdGltZW91dE1pbGxpc2Vjb25kcykgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMuaGFuZHNoYWtlVGltZW91dE1pbGxpc2Vjb25kcyA9IHRpbWVvdXRNaWxsaXNlY29uZHM7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVE9ETzogQ2xvc2UgU1NMIHNvY2tldHMgdXNpbmcgYSBiYWNrZ3JvdW5kIHRocmVhZCBzbyB0aGV5IGNsb3NlIGdyYWNlZnVsbHkuCisKKyAgICAgICAgc3luY2hyb25pemVkIChoYW5kc2hha2VMb2NrKSB7CisgICAgICAgICAgICBpZiAoIWhhbmRzaGFrZVN0YXJ0ZWQpIHsKKyAgICAgICAgICAgICAgICAvLyBwcmV2ZW50IGZ1cnRoZXIgYXR0ZW1wdHMgdG8gc3RhcnQgaGFuZHNoYWtlCisgICAgICAgICAgICAgICAgaGFuZHNoYWtlU3RhcnRlZCA9IHRydWU7CisKKyAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgICAgICAgICAgZnJlZSgpOworCisgICAgICAgICAgICAgICAgICAgIGlmIChzb2NrZXQgIT0gdGhpcykgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGF1dG9DbG9zZSAmJiAhc29ja2V0LmlzQ2xvc2VkKCkpIHNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5pc0Nsb3NlZCgpKSBzdXBlci5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9pbnRlcnJ1cHQoc3NsTmF0aXZlUG9pbnRlcik7CisKKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHdyaXRlTG9jaykgeworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAocmVhZExvY2spIHsKKworICAgICAgICAgICAgICAgICAgICAvLyBTaHV0IGRvd24gdGhlIFNTTCBjb25uZWN0aW9uLCBwZXIgc2UuCisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFuZHNoYWtlU3RhcnRlZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJsb2NrR3VhcmQuZ2V0VGhyZWFkUG9saWN5KCkub25OZXR3b3JrKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zaHV0ZG93bihzc2xOYXRpdmVQb2ludGVyLCBzb2NrZXQuZ2V0RmlsZURlc2NyaXB0b3IkKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgICAgICAgICAqIE5vdGUgdGhhdCBhbHRob3VnaCBjbG9zZSgpIGNhbiB0aHJvdworICAgICAgICAgICAgICAgICAgICAgICAgICogSU9FeGNlcHRpb24sIHRoZSBSSSBkb2VzIG5vdCB0aHJvdyBpZiB0aGVyZQorICAgICAgICAgICAgICAgICAgICAgICAgICogaXMgcHJvYmxlbSBzZW5kaW5nIGEgImNsb3NlIG5vdGlmeSIgd2hpY2gKKyAgICAgICAgICAgICAgICAgICAgICAgICAqIGNhbiBoYXBwZW4gaWYgdGhlIHVuZGVybHlpbmcgc29ja2V0IGlzIGNsb3NlZC4KKyAgICAgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgICAgICAgICAqIEV2ZW4gaWYgdGhlIGFib3ZlIGNhbGwgZmFpbGVkLCBpdCBpcyBzdGlsbCBzYWZlIHRvIGZyZWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAqIHRoZSBuYXRpdmUgc3RydWN0cywgYW5kIHdlIG5lZWQgdG8gZG8gc28gbGVzdCB3ZSBsZWFrCisgICAgICAgICAgICAgICAgICAgICAgICAgKiBtZW1vcnkuCisgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgIGZyZWUoKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNvY2tldCAhPSB0aGlzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGF1dG9DbG9zZSAmJiAhc29ja2V0LmlzQ2xvc2VkKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLmlzQ2xvc2VkKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VwZXIuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZnJlZSgpIHsKKyAgICAgICAgaWYgKHNzbE5hdGl2ZVBvaW50ZXIgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfZnJlZShzc2xOYXRpdmVQb2ludGVyKTsKKyAgICAgICAgc3NsTmF0aXZlUG9pbnRlciA9IDA7CisgICAgICAgIGd1YXJkLmNsb3NlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogSnVzdCB3b3JyeSBhYm91dCBvdXIgb3duIHN0YXRlLiBOb3RhYmx5IHdlIGRvIG5vdCB0cnkgYW5kCisgICAgICAgICAgICAgKiBjbG9zZSBhbnl0aGluZy4gVGhlIFNvY2tldEltcGwsIGVpdGhlciBvdXIgb3duCisgICAgICAgICAgICAgKiBQbGFpblNvY2tldEltcGwsIG9yIHRoZSBTb2NrZXQgd2UgYXJlIHdyYXBwaW5nLCB3aWxsIGRvCisgICAgICAgICAgICAgKiB0aGF0LiBUaGlzIG1pZ2h0IG1lYW4gd2UgZG8gbm90IHByb3Blcmx5IFNTTF9zaHV0ZG93biwgYnV0CisgICAgICAgICAgICAgKiBpZiB5b3Ugd2FudCB0byBkbyB0aGF0LCBwcm9wZXJseSBjbG9zZSB0aGUgc29ja2V0IHlvdXJzZWxmLgorICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAqIFRoZSByZWFzb24gd2h5IHdlIGRvbid0IHRyeSB0byBTU0xfc2h1dGRvd24sIGlzIHRoYXQgdGhlcmUKKyAgICAgICAgICAgICAqIGNhbiBiZSBhIHJhY2UgYmV0d2VlbiBmaW5hbGl6ZXJzIHdoZXJlIHRoZSBQbGFpblNvY2tldEltcGwKKyAgICAgICAgICAgICAqIGZpbmFsaXplciBydW5zIGZpcnN0IGFuZCBjbG9zZXMgdGhlIHNvY2tldC4gSG93ZXZlciwgaW4gdGhlCisgICAgICAgICAgICAgKiBtZWFud2hpbGUsIHRoZSB1bmRlcmx5aW5nIGZpbGUgZGVzY3JpcHRvciBjb3VsZCBiZSByZXVzZWQKKyAgICAgICAgICAgICAqIGZvciBhbm90aGVyIHB1cnBvc2UuIElmIHdlIGNhbGwgU1NMX3NodXRkb3duLCB0aGUKKyAgICAgICAgICAgICAqIHVuZGVybHlpbmcgc29ja2V0IEJJT3Mgc3RpbGwgaGF2ZSB0aGUgb2xkIGZpbGUgZGVzY3JpcHRvcgorICAgICAgICAgICAgICogYW5kIHdpbGwgd3JpdGUgdGhlIGNsb3NlIG5vdGlmeSB0byBzb21lIHVuc3VzcGVjdGluZworICAgICAgICAgICAgICogcmVhZGVyLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAoZ3VhcmQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGd1YXJkLndhcm5JZk9wZW4oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZyZWUoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHN1cGVyLmZpbmFsaXplKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3IgZ2V0RmlsZURlc2NyaXB0b3IkKCkgeworICAgICAgICBpZiAoc29ja2V0ID09IHRoaXMpIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRGaWxlRGVzY3JpcHRvciQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBzb2NrZXQuZ2V0RmlsZURlc2NyaXB0b3IkKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9PcGVuU1NMU29ja2V0SW1wbFdyYXBwZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL09wZW5TU0xTb2NrZXRJbXBsV3JhcHBlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmNjVkMTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9PcGVuU1NMU29ja2V0SW1wbFdyYXBwZXIuamF2YQpAQCAtMCwwICsxLDIwMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRFeGNlcHRpb247CisKKy8qKgorICogVGhpcyBjbGFzcyB3cmFwcyB0aGUgU1NMIGZ1bmN0aW9uYWxpdHkgb3ZlciBhbiBleGlzdGluZyBjb25uZWN0ZWQgc29ja2V0LgorICovCitwdWJsaWMgY2xhc3MgT3BlblNTTFNvY2tldEltcGxXcmFwcGVyIGV4dGVuZHMgT3BlblNTTFNvY2tldEltcGwgeworCisgICAgcHJpdmF0ZSBTb2NrZXQgc29ja2V0OworCisgICAgcHJvdGVjdGVkIE9wZW5TU0xTb2NrZXRJbXBsV3JhcHBlcihTb2NrZXQgc29ja2V0LCBTdHJpbmcgaG9zdCwgaW50IHBvcnQsCisgICAgICAgICAgICBib29sZWFuIGF1dG9DbG9zZSwgU1NMUGFyYW1ldGVyc0ltcGwgc3NsUGFyYW1ldGVycykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoc29ja2V0LCBob3N0LCBwb3J0LCBhdXRvQ2xvc2UsIHNzbFBhcmFtZXRlcnMpOworICAgICAgICBpZiAoIXNvY2tldC5pc0Nvbm5lY3RlZCgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKCJTb2NrZXQgaXMgbm90IGNvbm5lY3RlZC4iKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnNvY2tldCA9IHNvY2tldDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjb25uZWN0KFNvY2tldEFkZHJlc3Mgc29ja2FkZHIsIGludCB0aW1lb3V0KQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlVuZGVybHlpbmcgc29ja2V0IGlzIGFscmVhZHkgY29ubmVjdGVkLiIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNvbm5lY3QoU29ja2V0QWRkcmVzcyBzb2NrYWRkcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJVbmRlcmx5aW5nIHNvY2tldCBpcyBhbHJlYWR5IGNvbm5lY3RlZC4iKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBiaW5kKFNvY2tldEFkZHJlc3Mgc29ja2FkZHIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5kZXJseWluZyBzb2NrZXQgaXMgYWxyZWFkeSBjb25uZWN0ZWQuIik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNvY2tldEFkZHJlc3MgZ2V0UmVtb3RlU29ja2V0QWRkcmVzcygpIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5nZXRSZW1vdGVTb2NrZXRBZGRyZXNzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNvY2tldEFkZHJlc3MgZ2V0TG9jYWxTb2NrZXRBZGRyZXNzKCkgeworICAgICAgICByZXR1cm4gc29ja2V0LmdldExvY2FsU29ja2V0QWRkcmVzcygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbmV0QWRkcmVzcyBnZXRMb2NhbEFkZHJlc3MoKSB7CisgICAgICAgIHJldHVybiBzb2NrZXQuZ2V0TG9jYWxBZGRyZXNzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEluZXRBZGRyZXNzIGdldEluZXRBZGRyZXNzKCkgeworICAgICAgICByZXR1cm4gc29ja2V0LmdldEluZXRBZGRyZXNzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuICJTU0wgc29ja2V0IG92ZXIgIiArIHNvY2tldC50b1N0cmluZygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFNvTGluZ2VyKGJvb2xlYW4gb24sIGludCBsaW5nZXIpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBzb2NrZXQuc2V0U29MaW5nZXIob24sIGxpbmdlcik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0VGNwTm9EZWxheShib29sZWFuIG9uKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgc29ja2V0LnNldFRjcE5vRGVsYXkob24pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFJldXNlQWRkcmVzcyhib29sZWFuIG9uKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgc29ja2V0LnNldFJldXNlQWRkcmVzcyhvbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0S2VlcEFsaXZlKGJvb2xlYW4gb24pIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBzb2NrZXQuc2V0S2VlcEFsaXZlKG9uKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRUcmFmZmljQ2xhc3MoaW50IHRvcykgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHNvY2tldC5zZXRUcmFmZmljQ2xhc3ModG9zKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRTb1RpbWVvdXQoaW50IHRvKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgc29ja2V0LnNldFNvVGltZW91dCh0byk7CisgICAgICAgIHN1cGVyLnNldFNvVGltZW91dCh0byk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0U2VuZEJ1ZmZlclNpemUoaW50IHNpemUpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBzb2NrZXQuc2V0U2VuZEJ1ZmZlclNpemUoc2l6ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UmVjZWl2ZUJ1ZmZlclNpemUoaW50IHNpemUpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBzb2NrZXQuc2V0UmVjZWl2ZUJ1ZmZlclNpemUoc2l6ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0VGNwTm9EZWxheSgpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc29ja2V0LmdldFRjcE5vRGVsYXkoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRSZXVzZUFkZHJlc3MoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5nZXRSZXVzZUFkZHJlc3MoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRPT0JJbmxpbmUoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5nZXRPT0JJbmxpbmUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRLZWVwQWxpdmUoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5nZXRLZWVwQWxpdmUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFRyYWZmaWNDbGFzcygpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc29ja2V0LmdldFRyYWZmaWNDbGFzcygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0U29UaW1lb3V0KCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzb2NrZXQuZ2V0U29UaW1lb3V0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRTb0xpbmdlcigpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc29ja2V0LmdldFNvTGluZ2VyKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRTZW5kQnVmZmVyU2l6ZSgpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc29ja2V0LmdldFNlbmRCdWZmZXJTaXplKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRSZWNlaXZlQnVmZmVyU2l6ZSgpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc29ja2V0LmdldFJlY2VpdmVCdWZmZXJTaXplKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNDb25uZWN0ZWQoKSB7CisgICAgICAgIHJldHVybiBzb2NrZXQuaXNDb25uZWN0ZWQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0Nsb3NlZCgpIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5pc0Nsb3NlZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzQm91bmQoKSB7CisgICAgICAgIHJldHVybiBzb2NrZXQuaXNCb3VuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzT3V0cHV0U2h1dGRvd24oKSB7CisgICAgICAgIHJldHVybiBzb2NrZXQuaXNPdXRwdXRTaHV0ZG93bigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzSW5wdXRTaHV0ZG93bigpIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5pc0lucHV0U2h1dGRvd24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFBvcnQoKSB7CisgICAgICAgIHJldHVybiBzb2NrZXQuZ2V0UG9ydCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0TG9jYWxQb3J0KCkgeworICAgICAgICByZXR1cm4gc29ja2V0LmdldExvY2FsUG9ydCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1BSRi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvUFJGLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjAxM2QzOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1BSRi5qYXZhCkBAIC0wLDAgKzEsMTk4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZheC5jcnlwdG8uTWFjOworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLlNlY3JldEtleVNwZWM7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFeGNlcHRpb247CisKKy8qKgorICogVGhpcyBjbGFzcyBwcm92aWRlcyBmdW5jdGlvbmFsaXR5IGZvciBjb21wdXRhdGlvbgorICogb2YgUFJGIHZhbHVlcyBmb3IgVExTIChodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMjQ2LnR4dCkKKyAqIGFuZCBTU0wgdjMgKGh0dHA6Ly93cC5uZXRzY2FwZS5jb20vZW5nL3NzbDMpIHByb3RvY29scy4KKyAqLworcHVibGljIGNsYXNzIFBSRiB7CisgICAgcHJpdmF0ZSBzdGF0aWMgTG9nZ2VyLlN0cmVhbSBsb2dnZXIgPSBMb2dnZXIuZ2V0U3RyZWFtKCJwcmYiKTsKKworICAgIHByaXZhdGUgc3RhdGljIE1hYyBtZDVfbWFjOworICAgIHByaXZhdGUgc3RhdGljIE1hYyBzaGFfbWFjOworICAgIHByb3RlY3RlZCBzdGF0aWMgTWVzc2FnZURpZ2VzdCBtZDU7CisgICAgcHJvdGVjdGVkIHN0YXRpYyBNZXNzYWdlRGlnZXN0IHNoYTsKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgbWQ1X21hY19sZW5ndGg7CisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHNoYV9tYWNfbGVuZ3RoOworCisgICAgc3RhdGljIHByaXZhdGUgdm9pZCBpbml0KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWQ1X21hYyA9IE1hYy5nZXRJbnN0YW5jZSgiSG1hY01ENSIpOworICAgICAgICAgICAgc2hhX21hYyA9IE1hYy5nZXRJbnN0YW5jZSgiSG1hY1NIQTEiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbihBbGVydFByb3RvY29sLklOVEVSTkFMX0VSUk9SLAorICAgICAgICAgICAgICAgICAgICBuZXcgU1NMRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJUaGVyZSBpcyBubyBwcm92aWRlciBvZiBIbWFjU0hBMSBvciBIbWFjTUQ1ICIKKyAgICAgICAgICAgICAgICArICJhbGdvcml0aG1zIGluc3RhbGxlZCBpbiB0aGUgc3lzdGVtIikpOworICAgICAgICB9CisgICAgICAgIG1kNV9tYWNfbGVuZ3RoID0gbWQ1X21hYy5nZXRNYWNMZW5ndGgoKTsKKyAgICAgICAgc2hhX21hY19sZW5ndGggPSBzaGFfbWFjLmdldE1hY0xlbmd0aCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWQ1ID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZSgiTUQ1Iik7CisgICAgICAgICAgICBzaGEgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJTSEEtMSIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFsZXJ0RXhjZXB0aW9uKEFsZXJ0UHJvdG9jb2wuSU5URVJOQUxfRVJST1IsCisgICAgICAgICAgICAgICAgICAgIG5ldyBTU0xFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJDb3VsZCBub3QgaW5pdGlhbGl6ZSB0aGUgRGlnZXN0IEFsZ29yaXRobXMuIikpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZXMgdGhlIHZhbHVlIG9mIFNTTHYzIHBzZXVkbyByYW5kb20gZnVuY3Rpb24uCisgICAgICogQHBhcmFtICAgb3V0OiAgICB0aGUgYnVmZmVyIHRvIGZpbGwgdXAgd2l0aCB0aGUgdmFsdWUgb2YgdGhlIGZ1bmN0aW9uLgorICAgICAqIEBwYXJhbSAgIHNlY3JldDogdGhlIGJ1ZmZlciBjb250YWluaW5nIHRoZSBzZWNyZXQgdmFsdWUgdG8gZ2VuZXJhdGUgcHJmLgorICAgICAqIEBwYXJhbSAgIHNlZWQ6ICAgdGhlIHNlZWQgdG8gYmUgdXNlZC4KKyAgICAgKi8KKyAgICBzdGF0aWMgc3luY2hyb25pemVkIHZvaWQgY29tcHV0ZVBSRl9TU0x2MyhieXRlW10gb3V0LCBieXRlW10gc2VjcmV0LCBieXRlW10gc2VlZCkgeworICAgICAgICBpZiAoc2hhID09IG51bGwpIHsKKyAgICAgICAgICAgIGluaXQoKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgcG9zID0gMDsKKyAgICAgICAgaW50IGl0ZXJhdGlvbiA9IDE7CisgICAgICAgIGJ5dGVbXSBkaWdlc3Q7CisgICAgICAgIHdoaWxlIChwb3MgPCBvdXQubGVuZ3RoKSB7CisgICAgICAgICAgICBieXRlW10gcHJlZiA9IG5ldyBieXRlW2l0ZXJhdGlvbl07CisgICAgICAgICAgICBBcnJheXMuZmlsbChwcmVmLCAoYnl0ZSkgKDY0ICsgaXRlcmF0aW9uKyspKTsKKyAgICAgICAgICAgIHNoYS51cGRhdGUocHJlZik7CisgICAgICAgICAgICBzaGEudXBkYXRlKHNlY3JldCk7CisgICAgICAgICAgICBzaGEudXBkYXRlKHNlZWQpOworICAgICAgICAgICAgbWQ1LnVwZGF0ZShzZWNyZXQpOworICAgICAgICAgICAgbWQ1LnVwZGF0ZShzaGEuZGlnZXN0KCkpOworICAgICAgICAgICAgZGlnZXN0ID0gbWQ1LmRpZ2VzdCgpOyAvLyBsZW5ndGggPT0gMTYKKyAgICAgICAgICAgIGlmIChwb3MgKyAxNiA+IG91dC5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRpZ2VzdCwgMCwgb3V0LCBwb3MsIG91dC5sZW5ndGggLSBwb3MpOworICAgICAgICAgICAgICAgIHBvcyA9IG91dC5sZW5ndGg7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGlnZXN0LCAwLCBvdXQsIHBvcywgMTYpOworICAgICAgICAgICAgICAgIHBvcyArPSAxNjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGVzIHRoZSB2YWx1ZSBvZiBUTFMgcHNldWRvIHJhbmRvbSBmdW5jdGlvbi4KKyAgICAgKiBAcGFyYW0gICBvdXQ6ICAgIHRoZSBidWZmZXIgdG8gZmlsbCB1cCB3aXRoIHRoZSB2YWx1ZSBvZiB0aGUgZnVuY3Rpb24uCisgICAgICogQHBhcmFtICAgc2VjcmV0OiB0aGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIHNlY3JldCB2YWx1ZSB0byBnZW5lcmF0ZSBwcmYuCisgICAgICogQHBhcmFtICAgc3RyX2J5dGVzOiAgdGhlIGxhYmVsIGJ5dGVzIHRvIGJlIHVzZWQuCisgICAgICogQHBhcmFtICAgc2VlZDogICB0aGUgc2VlZCB0byBiZSB1c2VkLgorICAgICAqLworICAgIHN5bmNocm9uaXplZCBzdGF0aWMgdm9pZCBjb21wdXRlUFJGKGJ5dGVbXSBvdXQsIGJ5dGVbXSBzZWNyZXQsCisgICAgICAgICAgICBieXRlW10gc3RyX2J5dHMsIGJ5dGVbXSBzZWVkKSB0aHJvd3MgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNoYV9tYWMgPT0gbnVsbCkgeworICAgICAgICAgICAgaW5pdCgpOworICAgICAgICB9CisgICAgICAgIC8vIERvIGNvbmNhdGVuYXRpb24gb2YgdGhlIGxhYmVsIHdpdGggdGhlIHNlZWQ6CisgICAgICAgIC8vIChtZXR0ZXJpbmdzIHNob3cgdGhhdCBpcyBpcyBmYXN0ZXIgdG8gY29uY2F0ZW5hdGUgdGhlIGFycmF5cworICAgICAgICAvLyBhbmQgdG8gY2FsbCBITUFDLnVwZGF0ZSBvbiBjYW5jYXRlbmF0aW9uLCB0aGFuIHR3aWNlIGNhbGwgZm9yCisgICAgICAgIC8vIGVhY2ggb2YgdGhlIHBhcnQsIGkuZS46CisgICAgICAgIC8vIHRpbWUoSE1BQy51cGRhdGUobGFiZWwrc2VlZCkpCisgICAgICAgIC8vICAgICAgICAgIDwgdGltZShITUFDLnVwZGF0ZShsYWJlbCkpICsgdGltZShITUFDLnVwZGF0ZShzZWVkKSkKKyAgICAgICAgLy8gYnV0IGl0IHRha2VzIG1vcmUgbWVtbW9yeSAoYXBwcm94aW1hdHkgb24gNCUpCisgICAgICAgIC8qCisgICAgICAgIGJ5dGVbXSB0bXBfc2VlZCA9IG5ldyBieXRlW3NlZWQubGVuZ3RoICsgc3RyX2J5dHMubGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShzdHJfYnl0cywgMCwgdG1wX3NlZWQsIDAsIHN0cl9ieXRzLmxlbmd0aCk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2VlZCwgMCwgdG1wX3NlZWQsIHN0cl9ieXRzLmxlbmd0aCwgc2VlZC5sZW5ndGgpOworICAgICAgICBzZWVkID0gdG1wX3NlZWQ7CisgICAgICAgICovCisgICAgICAgIFNlY3JldEtleVNwZWMga2V5TWQ1OworICAgICAgICBTZWNyZXRLZXlTcGVjIGtleVNoYTE7CisgICAgICAgIGlmICgoc2VjcmV0ID09IG51bGwpIHx8IChzZWNyZXQubGVuZ3RoID09IDApKSB7CisgICAgICAgICAgICBzZWNyZXQgPSBuZXcgYnl0ZVs4XTsKKyAgICAgICAgICAgIGtleU1kNSA9IG5ldyBTZWNyZXRLZXlTcGVjKHNlY3JldCwgIkhtYWNNRDUiKTsKKyAgICAgICAgICAgIGtleVNoYTEgPSBuZXcgU2VjcmV0S2V5U3BlYyhzZWNyZXQsICJIbWFjU0hBMSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaW50IGxlbmd0aCA9IHNlY3JldC5sZW5ndGggPj4gMTsgLy8gZGl2aXNpb24gYnkgMgorICAgICAgICAgICAgaW50IG9mZnNldCA9IHNlY3JldC5sZW5ndGggJiAxOyAgLy8gcmVtYWluZGVyCisgICAgICAgICAgICBrZXlNZDUgPSBuZXcgU2VjcmV0S2V5U3BlYyhzZWNyZXQsIDAsIGxlbmd0aCArIG9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgIkhtYWNNRDUiKTsKKyAgICAgICAgICAgIGtleVNoYTEgPSBuZXcgU2VjcmV0S2V5U3BlYyhzZWNyZXQsIGxlbmd0aCwgbGVuZ3RoCisgICAgICAgICAgICAgICAgICAgICsgb2Zmc2V0LCAiSG1hY1NIQTEiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vYnl0ZVtdIHN0cl9ieXRzID0gbGFiZWwuZ2V0Qnl0ZXMoKTsKKworICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJzZWNyZXRbIitzZWNyZXQubGVuZ3RoKyJdOiAiKTsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludEFzSGV4KDE2LCAiIiwgIiAiLCBzZWNyZXQpOworICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oImxhYmVsWyIrc3RyX2J5dHMubGVuZ3RoKyJdOiAiKTsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludEFzSGV4KDE2LCAiIiwgIiAiLCBzdHJfYnl0cyk7CisgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigic2VlZFsiK3NlZWQubGVuZ3RoKyJdOiAiKTsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludEFzSGV4KDE2LCAiIiwgIiAiLCBzZWVkKTsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJNRDUga2V5OiIpOworICAgICAgICAgICAgbG9nZ2VyLnByaW50QXNIZXgoMTYsICIiLCAiICIsIGtleU1kNS5nZXRFbmNvZGVkKCkpOworICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIlNIQTEga2V5OiIpOworICAgICAgICAgICAgbG9nZ2VyLnByaW50QXNIZXgoMTYsICIiLCAiICIsIGtleVNoYTEuZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIG1kNV9tYWMuaW5pdChrZXlNZDUpOworICAgICAgICBzaGFfbWFjLmluaXQoa2V5U2hhMSk7CisKKyAgICAgICAgaW50IHBvcyA9IDA7CisgICAgICAgIG1kNV9tYWMudXBkYXRlKHN0cl9ieXRzKTsKKyAgICAgICAgYnl0ZVtdIGhhc2ggPSBtZDVfbWFjLmRvRmluYWwoc2VlZCk7IC8vIEEoMSkKKyAgICAgICAgd2hpbGUgKHBvcyA8IG91dC5sZW5ndGgpIHsKKyAgICAgICAgICAgIG1kNV9tYWMudXBkYXRlKGhhc2gpOworICAgICAgICAgICAgbWQ1X21hYy51cGRhdGUoc3RyX2J5dHMpOworICAgICAgICAgICAgbWQ1X21hYy51cGRhdGUoc2VlZCk7CisgICAgICAgICAgICBpZiAocG9zICsgbWQ1X21hY19sZW5ndGggPCBvdXQubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgbWQ1X21hYy5kb0ZpbmFsKG91dCwgcG9zKTsKKyAgICAgICAgICAgICAgICBwb3MgKz0gbWQ1X21hY19sZW5ndGg7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobWQ1X21hYy5kb0ZpbmFsKCksIDAsIG91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHBvcywgb3V0Lmxlbmd0aCAtIHBvcyk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBtYWtlIEEoaSkKKyAgICAgICAgICAgIGhhc2ggPSBtZDVfbWFjLmRvRmluYWwoaGFzaCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiUF9NRDU6Iik7CisgICAgICAgICAgICBsb2dnZXIucHJpbnRBc0hleChtZDVfbWFjX2xlbmd0aCwgIiIsICIgIiwgb3V0KTsKKyAgICAgICAgfQorCisgICAgICAgIHBvcyA9IDA7CisgICAgICAgIHNoYV9tYWMudXBkYXRlKHN0cl9ieXRzKTsKKyAgICAgICAgaGFzaCA9IHNoYV9tYWMuZG9GaW5hbChzZWVkKTsgLy8gQSgxKQorICAgICAgICBieXRlW10gc2hhMWhhc2g7CisgICAgICAgIHdoaWxlIChwb3MgPCBvdXQubGVuZ3RoKSB7CisgICAgICAgICAgICBzaGFfbWFjLnVwZGF0ZShoYXNoKTsKKyAgICAgICAgICAgIHNoYV9tYWMudXBkYXRlKHN0cl9ieXRzKTsKKyAgICAgICAgICAgIHNoYTFoYXNoID0gc2hhX21hYy5kb0ZpbmFsKHNlZWQpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IChpIDwgc2hhX21hY19sZW5ndGgpICYgKHBvcyA8IG91dC5sZW5ndGgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICBvdXRbcG9zKytdIF49IHNoYTFoYXNoW2ldOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gbWFrZSBBKGkpCisgICAgICAgICAgICBoYXNoID0gc2hhX21hYy5kb0ZpbmFsKGhhc2gpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiUFJGOiIpOworICAgICAgICAgICAgbG9nZ2VyLnByaW50QXNIZXgoc2hhX21hY19sZW5ndGgsICIiLCAiICIsIG91dCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9Qcm90b2NvbFZlcnNpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1Byb3RvY29sVmVyc2lvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzMGY5ZmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9Qcm90b2NvbFZlcnNpb24uamF2YQpAQCAtMCwwICsxLDE0NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CisKKy8qKgorICoKKyAqIFJlcHJlc2VudHMgUHJvdG9jb2wgVmVyc2lvbgorICovCitwdWJsaWMgY2xhc3MgUHJvdG9jb2xWZXJzaW9uIHsKKyAgICAvKioKKyAgICAgKiBQcm90b2NvbHMgc3VwcG9ydGVkIGJ5IHRoaXMgcHJvdmlkZXIgaW1wbGVtZW50YXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZ1tdIHN1cHBvcnRlZFByb3RvY29scyA9IG5ldyBTdHJpbmdbXSB7ICJUTFN2MSIsCisgICAgICAgICAgICAiU1NMdjMiIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBIYXNodGFibGU8U3RyaW5nLCBQcm90b2NvbFZlcnNpb24+IHByb3RvY29sc0J5TmFtZSA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBQcm90b2NvbFZlcnNpb24+KDQpOworCisgICAgLyoqCisgICAgICoKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgcHJvdG9jb2wgdmVyc2lvbiBpcyBzdXBwb3J0ZWQKKyAgICAgKgorICAgICAqIEBwYXJhbSB2ZXJzaW9uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzU3VwcG9ydGVkKGJ5dGVbXSB2ZXJzaW9uKSB7CisgICAgICAgIGlmICh2ZXJzaW9uWzBdICE9IDMgfHwgKHZlcnNpb25bMV0gIT0gMCAmJiB2ZXJzaW9uWzFdICE9IDEpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBQcm90b2NvbFZlcnNpb24KKyAgICAgKgorICAgICAqIEBwYXJhbSB2ZXJzaW9uCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUHJvdG9jb2xWZXJzaW9uIGdldEJ5VmVyc2lvbihieXRlW10gdmVyc2lvbikgeworICAgICAgICBpZiAodmVyc2lvblswXSA9PSAzKSB7CisgICAgICAgICAgICBpZiAodmVyc2lvblsxXSA9PSAxKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIFRMU3YxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHZlcnNpb25bMV0gPT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBTU0x2MzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgcHJvdmlkZXIgc3VwcG9ydHMgcHJvdG9jb2wgdmVyc2lvbgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzU3VwcG9ydGVkKFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiBwcm90b2NvbHNCeU5hbWUuY29udGFpbnNLZXkobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBQcm90b2NvbFZlcnNpb24KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUHJvdG9jb2xWZXJzaW9uIGdldEJ5TmFtZShTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gcHJvdG9jb2xzQnlOYW1lLmdldChuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBIaWdoZXN0IHByb3RvY29sIHZlcnNpb24gc3VwcG9ydGVkIGJ5IHByb3ZpZGVyIGltcGxlbWVudGF0aW9uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJvdG9jb2xzCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUHJvdG9jb2xWZXJzaW9uIGdldExhdGVzdFZlcnNpb24oU3RyaW5nW10gcHJvdG9jb2xzKSB7CisgICAgICAgIGlmIChwcm90b2NvbHMgPT0gbnVsbCB8fCBwcm90b2NvbHMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIFByb3RvY29sVmVyc2lvbiBsYXRlc3QgPSBnZXRCeU5hbWUocHJvdG9jb2xzWzBdKTsKKyAgICAgICAgUHJvdG9jb2xWZXJzaW9uIGN1cnJlbnQ7CisgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgcHJvdG9jb2xzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjdXJyZW50ID0gZ2V0QnlOYW1lKHByb3RvY29sc1tpXSk7CisgICAgICAgICAgICBpZiAoY3VycmVudCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoKGxhdGVzdCA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICB8fCAobGF0ZXN0LnZlcnNpb25bMF0gPCBjdXJyZW50LnZlcnNpb25bMF0pCisgICAgICAgICAgICAgICAgICAgIHx8IChsYXRlc3QudmVyc2lvblswXSA9PSBjdXJyZW50LnZlcnNpb25bMF0gJiYgbGF0ZXN0LnZlcnNpb25bMV0gPCBjdXJyZW50LnZlcnNpb25bMV0pKSB7CisgICAgICAgICAgICAgICAgbGF0ZXN0ID0gY3VycmVudDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbGF0ZXN0OworCisgICAgfQorCisgICAgLyoqCisgICAgICogU1NMIDMuMCBwcm90b2NvbCB2ZXJzaW9uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBQcm90b2NvbFZlcnNpb24gU1NMdjMgPSBuZXcgUHJvdG9jb2xWZXJzaW9uKCJTU0x2MyIsCisgICAgICAgICAgICBuZXcgYnl0ZVtdIHsgMywgMCB9KTsKKworICAgIC8qKgorICAgICAqIFRMUyAxLjAgcHJvdG9jb2wgdmVyc2lvbgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUHJvdG9jb2xWZXJzaW9uIFRMU3YxID0gbmV3IFByb3RvY29sVmVyc2lvbigiVExTdjEiLAorICAgICAgICAgICAgbmV3IGJ5dGVbXSB7IDMsIDEgfSk7CisKKyAgICBzdGF0aWMgeworICAgICAgICBwcm90b2NvbHNCeU5hbWUucHV0KFNTTHYzLm5hbWUsIFNTTHYzKTsKKyAgICAgICAgcHJvdG9jb2xzQnlOYW1lLnB1dChUTFN2MS5uYW1lLCBUTFN2MSk7CisgICAgICAgIHByb3RvY29sc0J5TmFtZS5wdXQoIlNTTCIsIFNTTHYzKTsKKyAgICAgICAgcHJvdG9jb2xzQnlOYW1lLnB1dCgiVExTIiwgVExTdjEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb3RvY29sIG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU3RyaW5nIG5hbWU7CisKKyAgICAvKioKKyAgICAgKiBQcm90b2NvbCB2ZXJzaW9uIGFzIGJ5dGUgYXJyYXkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgYnl0ZVtdIHZlcnNpb247CisKKyAgICBwcml2YXRlIFByb3RvY29sVmVyc2lvbihTdHJpbmcgbmFtZSwgYnl0ZVtdIHZlcnNpb24pIHsKKyAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMQnVmZmVyZWRJbnB1dC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMQnVmZmVyZWRJbnB1dC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM5NDVkYmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xCdWZmZXJlZElucHV0LmphdmEKQEAgLTAsMCArMSw3NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworCisvKioKKyAqIFRoaXMgaXMgYSB3cmFwcGVyIGlucHV0IHN0cmVhbSBmb3IgQnl0ZUJ1ZmZlciBkYXRhIHNvdXJjZS4KKyAqIEFtb25nIHdpdGggdGhlIHJlYWQgZnVuY3Rpb25hbGl0eSBpdCBwcm92aWRlcyBpbmZvCisgKiBhYm91dCBudW1iZXIgb2YgY3Vuc3VtZWQgYnl0ZXMgZnJvbSB0aGUgc291cmNlIEJ5dGVCdWZmZXIuCisgKiBUaGUgc291cmNlIEJ5dGVCdWZmZXIgb2JqZWN0IGNhbiBiZSByZXNldGVkLgorICogU28gb25lIGluc3RhbmNlIG9mIHRoaXMgd3JhcHBlciBjYW4gYmUgcmV1c2VkIGZvciBzZXZlcmFsCisgKiBCeXRlQnVmZmVyIGRhdGEgc291cmNlcy4KKyAqLworcHVibGljIGNsYXNzIFNTTEJ1ZmZlcmVkSW5wdXQgZXh0ZW5kcyBTU0xJbnB1dFN0cmVhbSB7CisKKyAgICBwcml2YXRlIEJ5dGVCdWZmZXIgaW47CisgICAgcHJpdmF0ZSBpbnQgYnl0aWs7CisgICAgcHJpdmF0ZSBpbnQgY29uc3VtZWQgPSAwOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU1NMQnVmZmVyZWRJbnB1dCgpIHt9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBidWZmZXIgYXMgYSBkYXRhIHNvdXJjZQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFNvdXJjZUJ1ZmZlcihCeXRlQnVmZmVyIGluKSB7CisgICAgICAgIGNvbnN1bWVkID0gMDsKKyAgICAgICAgdGhpcy5pbiA9IGluOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gaW4gYXNzdW1wdGlvbiB0aGF0IHRoZSBidWZmZXIgaGFzIGJlZW4gc2V0CisgICAgICAgIHJldHVybiBpbi5yZW1haW5pbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgY29uc3VtZWQgYnl0ZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBjb25zdW1lZCgpIHsKKyAgICAgICAgcmV0dXJuIGNvbnN1bWVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSBmb2xsb3dpbmcgYnl0ZSB2YWx1ZS4gSWYgdGhlcmUgYXJlIG5vIGJ5dGVzIGluIHRoZSBzb3VyY2UKKyAgICAgKiBidWZmZXIsIG1ldGhvZCB0aHJvd3MgamF2YS5uaW8uQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRPRE86IGltcGxlbWVudCBvcHRpbWl6ZWQgcmVhZChpbnQpCisgICAgICAgIC8vIGFuZCByZWFkKGJ5dGVbXSwgaW50LCBpbnQpIG1ldGhvZHMKKyAgICAgICAgYnl0aWsgPSBpbi5nZXQoKSAmIDB4MDBGRjsKKyAgICAgICAgY29uc3VtZWQgKys7CisgICAgICAgIHJldHVybiBieXRpazsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xDbGllbnRTZXNzaW9uQ2FjaGUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTENsaWVudFNlc3Npb25DYWNoZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhNzNmYTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xDbGllbnRTZXNzaW9uQ2FjaGUuamF2YQpAQCAtMCwwICsxLDUzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uOworCisvKioKKyAqIEEgcGVyc2lzdGVudCB7QGxpbmsgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9ufSBjYWNoZSB1c2VkIGJ5CisgKiB7QGxpbmsgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uQ29udGV4dH0gdG8gc2hhcmUgY2xpZW50LXNpZGUgU1NMIHNlc3Npb25zCisgKiBhY3Jvc3MgcHJvY2Vzc2VzLiBGb3IgZXhhbXBsZSwgdGhpcyBjYWNoZSBlbmFibGVzIGFwcGxpY2F0aW9ucyB0bworICogcGVyc2lzdCBhbmQgcmV1c2Ugc2Vzc2lvbnMgYWNyb3NzIHJlc3RhcnRzLgorICoKKyAqIDxwPlRoZSB7QGNvZGUgU1NMU2Vzc2lvbkNvbnRleHR9IGltcGxlbWVudGF0aW9uIGNvbnZlcnRzCisgKiB7QGNvZGUgU1NMU2Vzc2lvbn1zIGludG8gcmF3IGJ5dGVzIGFuZCB2aWNlIHZlcnNhLiBUaGUgZXhhY3QgbWFrZXVwIG9mIHRoZQorICogc2Vzc2lvbiBkYXRhIGlzIGRlcGVuZGVudCB1cG9uIHRoZSBjYWxsZXIncyBpbXBsZW1lbnRhdGlvbiBhbmQgaXMgb3BhcXVlIHRvCisgKiB0aGUge0Bjb2RlIFNTTENsaWVudFNlc3Npb25DYWNoZX0gaW1wbGVtZW50YXRpb24uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgU1NMQ2xpZW50U2Vzc2lvbkNhY2hlIHsKKworICAvKioKKyAgICogR2V0cyBkYXRhIGZyb20gYSBwcmUtZXhpc3Rpbmcgc2Vzc2lvbiBmb3IgYSBnaXZlbiBzZXJ2ZXIgaG9zdCBhbmQgcG9ydC4KKyAgICoKKyAgICogQHBhcmFtIGhvc3QgZnJvbSB7QGxpbmsgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uI2dldFBlZXJIb3N0KCl9CisgICAqIEBwYXJhbSBwb3J0IGZyb20ge0BsaW5rIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNnZXRQZWVyUG9ydCgpfQorICAgKiBAcmV0dXJuIHRoZSBzZXNzaW9uIGRhdGEgb3IgbnVsbCBpZiBub25lIGlzIGNhY2hlZAorICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGhvc3QgaXMgbnVsbAorICAgKi8KKyAgcHVibGljIGJ5dGVbXSBnZXRTZXNzaW9uRGF0YShTdHJpbmcgaG9zdCwgaW50IHBvcnQpOworCisgIC8qKgorICAgKiBTdG9yZXMgc2Vzc2lvbiBkYXRhIGZvciB0aGUgZ2l2ZW4gc2Vzc2lvbi4KKyAgICoKKyAgICogQHBhcmFtIHNlc3Npb24gdG8gY2FjaGUgZGF0YSBmb3IKKyAgICogQHBhcmFtIHNlc3Npb25EYXRhIHRvIGNhY2hlCisgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgc2Vzc2lvbiwgcmVzdWx0IG9mCisgICAqICB7QGNvZGUgc2Vzc2lvbi5nZXRQZWVySG9zdCgpfSBvciBkYXRhIGlzIG51bGwKKyAgICovCisgIHB1YmxpYyB2b2lkIHB1dFNlc3Npb25EYXRhKFNTTFNlc3Npb24gc2Vzc2lvbiwgYnl0ZVtdIHNlc3Npb25EYXRhKTsKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xDb250ZXh0SW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMQ29udGV4dEltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZTFlMTMwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMQ29udGV4dEltcGwuamF2YQpAQCAtMCwwICsxLDE0MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleU1hbmFnZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMQ29udGV4dFNwaTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldEZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTb2NrZXRGYWN0b3J5OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuVHJ1c3RNYW5hZ2VyOworCisvKioKKyAqIEltcGxlbWVudGF0aW9uIG9mIFNTTENvbnRleHQgc2VydmljZSBwcm92aWRlciBpbnRlcmZhY2UuCisgKi8KK3B1YmxpYyBjbGFzcyBTU0xDb250ZXh0SW1wbCBleHRlbmRzIFNTTENvbnRleHRTcGkgeworCisgICAgLyoqCisgICAgICogVGhlIGRlZmF1bHQgU1NMQ29udGV4dEltcGwgZm9yIHVzZSB3aXRoIFNTTENvbnRleHQuZ2V0SW5zdGFuY2UoIkRlZmF1bHQiKS4KKyAgICAgKiBQcm90ZWN0ZWQgYnkgdGhlIERlZmF1bHRTU0xDb250ZXh0SW1wbC5jbGFzcyBtb25pdG9yLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIERlZmF1bHRTU0xDb250ZXh0SW1wbCBERUZBVUxUX1NTTF9DT05URVhUX0lNUEw7CisKKyAgICAvKiogQ2xpZW50IHNlc3Npb24gY2FjaGUuICovCisgICAgcHJpdmF0ZSBmaW5hbCBDbGllbnRTZXNzaW9uQ29udGV4dCBjbGllbnRTZXNzaW9uQ29udGV4dDsKKworICAgIC8qKiBTZXJ2ZXIgc2Vzc2lvbiBjYWNoZS4gKi8KKyAgICBwcml2YXRlIGZpbmFsIFNlcnZlclNlc3Npb25Db250ZXh0IHNlcnZlclNlc3Npb25Db250ZXh0OworCisgICAgcHJvdGVjdGVkIFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnM7CisKKyAgICBwdWJsaWMgU1NMQ29udGV4dEltcGwoKSB7CisgICAgICAgIGNsaWVudFNlc3Npb25Db250ZXh0ID0gbmV3IENsaWVudFNlc3Npb25Db250ZXh0KCk7CisgICAgICAgIHNlcnZlclNlc3Npb25Db250ZXh0ID0gbmV3IFNlcnZlclNlc3Npb25Db250ZXh0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3R1Y3RvciBmb3IgdGhlIERlZmF1bHRTU0xDb250ZXh0SW1wbC4KKyAgICAgKiBAcGFyYW0gZHVtbXkgaXMgbnVsbCwgdXNlZCB0byBkaXN0aW5ndWlzaCB0aGlzIGNhc2UgZnJvbSB0aGUKKyAgICAgKiBwdWJsaWMgU1NMQ29udGV4dEltcGwoKSBjb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU1NMQ29udGV4dEltcGwoRGVmYXVsdFNTTENvbnRleHRJbXBsIGR1bW15KQorICAgICAgICAgICAgdGhyb3dzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBzeW5jaHJvbml6ZWQgKERlZmF1bHRTU0xDb250ZXh0SW1wbC5jbGFzcykgeworICAgICAgICAgICAgaWYgKERFRkFVTFRfU1NMX0NPTlRFWFRfSU1QTCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY2xpZW50U2Vzc2lvbkNvbnRleHQgPSBuZXcgQ2xpZW50U2Vzc2lvbkNvbnRleHQoKTsKKyAgICAgICAgICAgICAgICBzZXJ2ZXJTZXNzaW9uQ29udGV4dCA9IG5ldyBTZXJ2ZXJTZXNzaW9uQ29udGV4dCgpOworICAgICAgICAgICAgICAgIERFRkFVTFRfU1NMX0NPTlRFWFRfSU1QTCA9IChEZWZhdWx0U1NMQ29udGV4dEltcGwpdGhpczsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgY2xpZW50U2Vzc2lvbkNvbnRleHQgPSBERUZBVUxUX1NTTF9DT05URVhUX0lNUEwuZW5naW5lR2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKTsKKyAgICAgICAgICAgICAgICBzZXJ2ZXJTZXNzaW9uQ29udGV4dCA9IERFRkFVTFRfU1NMX0NPTlRFWFRfSU1QTC5lbmdpbmVHZXRTZXJ2ZXJTZXNzaW9uQ29udGV4dCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3NsUGFyYW1ldGVycyA9IG5ldyBTU0xQYXJhbWV0ZXJzSW1wbChERUZBVUxUX1NTTF9DT05URVhUX0lNUEwuZ2V0S2V5TWFuYWdlcnMoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgREVGQVVMVF9TU0xfQ09OVEVYVF9JTVBMLmdldFRydXN0TWFuYWdlcnMoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50U2Vzc2lvbkNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZlclNlc3Npb25Db250ZXh0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRoaXMge0Bjb2RlIFNTTENvbnRleHR9IGluc3RhbmNlLiBBbGwgb2YgdGhlIGFyZ3VtZW50cyBhcmUKKyAgICAgKiBvcHRpb25hbCwgYW5kIHRoZSBzZWN1cml0eSBwcm92aWRlcnMgd2lsbCBiZSBzZWFyY2hlZCBmb3IgdGhlIHJlcXVpcmVkCisgICAgICogaW1wbGVtZW50YXRpb25zIG9mIHRoZSBuZWVkZWQgYWxnb3JpdGhtcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrbXMgdGhlIGtleSBzb3VyY2VzIG9yIHtAY29kZSBudWxsfQorICAgICAqIEBwYXJhbSB0bXMgdGhlIHRydXN0IGRlY2lzaW9uIHNvdXJjZXMgb3Ige0Bjb2RlIG51bGx9CisgICAgICogQHBhcmFtIHNyIHRoZSByYW5kb21uZXNzIHNvdXJjZSBvciB7QGNvZGUgbnVsbH0KKyAgICAgKiBAdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24gaWYgaW5pdGlhbGl6aW5nIHRoaXMgaW5zdGFuY2UgZmFpbHMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVJbml0KEtleU1hbmFnZXJbXSBrbXMsIFRydXN0TWFuYWdlcltdIHRtcywKKyAgICAgICAgICAgIFNlY3VyZVJhbmRvbSBzcikgdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24geworICAgICAgICBzc2xQYXJhbWV0ZXJzID0gbmV3IFNTTFBhcmFtZXRlcnNJbXBsKGttcywgdG1zLCBzciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRTZXNzaW9uQ29udGV4dCwgc2VydmVyU2Vzc2lvbkNvbnRleHQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTU0xTb2NrZXRGYWN0b3J5IGVuZ2luZUdldFNvY2tldEZhY3RvcnkoKSB7CisgICAgICAgIGlmIChzc2xQYXJhbWV0ZXJzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIlNTTENvbnRleHQgaXMgbm90IGluaXRpYWxpemVkLiIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU1NMU29ja2V0RmFjdG9yeUltcGwoc3NsUGFyYW1ldGVycyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNTTFNlcnZlclNvY2tldEZhY3RvcnkgZW5naW5lR2V0U2VydmVyU29ja2V0RmFjdG9yeSgpIHsKKyAgICAgICAgaWYgKHNzbFBhcmFtZXRlcnMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiU1NMQ29udGV4dCBpcyBub3QgaW5pdGlhbGl6ZWQuIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBTU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5SW1wbChzc2xQYXJhbWV0ZXJzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU1NMRW5naW5lIGVuZ2luZUNyZWF0ZVNTTEVuZ2luZShTdHJpbmcgaG9zdCwgaW50IHBvcnQpIHsKKyAgICAgICAgaWYgKHNzbFBhcmFtZXRlcnMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiU1NMQ29udGV4dCBpcyBub3QgaW5pdGlhbGl6ZWQuIik7CisgICAgICAgIH0KKyAgICAgICAgU1NMUGFyYW1ldGVyc0ltcGwgcCA9IChTU0xQYXJhbWV0ZXJzSW1wbCkgc3NsUGFyYW1ldGVycy5jbG9uZSgpOworICAgICAgICBwLnNldFVzZUNsaWVudE1vZGUoZmFsc2UpOworICAgICAgICByZXR1cm4gbmV3IFNTTEVuZ2luZUltcGwoaG9zdCwgcG9ydCwgcCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNTTEVuZ2luZSBlbmdpbmVDcmVhdGVTU0xFbmdpbmUoKSB7CisgICAgICAgIGlmIChzc2xQYXJhbWV0ZXJzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIlNTTENvbnRleHQgaXMgbm90IGluaXRpYWxpemVkLiIpOworICAgICAgICB9CisgICAgICAgIFNTTFBhcmFtZXRlcnNJbXBsIHAgPSAoU1NMUGFyYW1ldGVyc0ltcGwpIHNzbFBhcmFtZXRlcnMuY2xvbmUoKTsKKyAgICAgICAgcC5zZXRVc2VDbGllbnRNb2RlKGZhbHNlKTsKKyAgICAgICAgcmV0dXJuIG5ldyBTU0xFbmdpbmVJbXBsKHApOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTZXJ2ZXJTZXNzaW9uQ29udGV4dCBlbmdpbmVHZXRTZXJ2ZXJTZXNzaW9uQ29udGV4dCgpIHsKKyAgICAgICAgcmV0dXJuIHNlcnZlclNlc3Npb25Db250ZXh0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDbGllbnRTZXNzaW9uQ29udGV4dCBlbmdpbmVHZXRDbGllbnRTZXNzaW9uQ29udGV4dCgpIHsKKyAgICAgICAgcmV0dXJuIGNsaWVudFNlc3Npb25Db250ZXh0OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTEVuZ2luZUFwcERhdGEuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTEVuZ2luZUFwcERhdGEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iODI3MDE2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMRW5naW5lQXBwRGF0YS5qYXZhCkBAIC0wLDAgKzEsOTMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFeGNlcHRpb247CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyB1c2VkIHRvIHJldHJpZXZlIHRoZSBhcHBsaWNhdGlvbiBkYXRhCisgKiBhcnJpdmVkIGZvciB0aGUgU1NMRW5naW5lLgorICovCitwdWJsaWMgY2xhc3MgU1NMRW5naW5lQXBwRGF0YSBpbXBsZW1lbnRzIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2UuQXBwZW5kYWJsZSB7CisKKyAgICAvKioKKyAgICAgKiBCdWZmZXIgY29udGFpbmluZyByZWNlaXZlZCBhcHBsaWNhdGlvbiBkYXRhLgorICAgICAqLworICAgIGJ5dGVbXSBidWZmZXI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvcgorICAgICAqLworICAgIHByb3RlY3RlZCBTU0xFbmdpbmVBcHBEYXRhKCkge30KKworICAgIC8qKgorICAgICAqIFN0b3JlcyByZWNlaXZlZCBkYXRhLiBUaGUgc291cmNlIGRhdGEgaXMgbm90IGNsb25lZCwKKyAgICAgKiBqdXN0IHRoZSBhcnJheSByZWZlcmVuY2UgaXMgcmVtZW1iZXJlZCBpbnRvIHRoZSBidWZmZXIgZmllbGQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYXBwZW5kKGJ5dGVbXSBzcmMpIHsKKyAgICAgICAgaWYgKGJ1ZmZlciAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQWxlcnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgQWxlcnRQcm90b2NvbC5JTlRFUk5BTF9FUlJPUiwKKyAgICAgICAgICAgICAgICBuZXcgU1NMRXhjZXB0aW9uKCJBdHRlbXB0IHRvIG92ZXJyaWRlIHRoZSBkYXRhIikpOworICAgICAgICB9CisgICAgICAgIGJ1ZmZlciA9IHNyYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQbGFjZXMgdGhlIGRhdGEgZnJvbSB0aGUgYnVmZmVyIGludG8gdGhlIGFycmF5IG9mIGRlc3RpbmF0aW9uCisgICAgICogQnl0ZUJ1ZmZlciBvYmplY3RzLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgcGxhY2VUbyhCeXRlQnVmZmVyW10gZHN0cywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgICAgICBpZiAoYnVmZmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGludCBwb3MgPSAwOworICAgICAgICBpbnQgbGVuID0gYnVmZmVyLmxlbmd0aDsKKyAgICAgICAgaW50IHJlbTsKKyAgICAgICAgLy8gd3JpdGUgZGF0YSB0byB0aGUgYnVmZmVycworICAgICAgICBmb3IgKGludCBpPW9mZnNldDsgaTxvZmZzZXQrbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHJlbSA9IGRzdHNbaV0ucmVtYWluaW5nKCk7CisgICAgICAgICAgICAvLyBUT0RPOiBvcHRpbWl6YXRpb24gd29yayAtIHVzZSBoYXNBcnJheSwgYXJyYXkoKSwgYXJyYXljb3B5CisgICAgICAgICAgICBpZiAobGVuIC0gcG9zIDwgcmVtKSB7CisgICAgICAgICAgICAgICAgLy8gY2FuIGZ1bGx5IHdyaXRlIHJlbWFpbmluZyBkYXRhIGludG8gYnVmZmVyCisgICAgICAgICAgICAgICAgZHN0c1tpXS5wdXQoYnVmZmVyLCBwb3MsIGxlbiAtIHBvcyk7CisgICAgICAgICAgICAgICAgcG9zID0gbGVuOworICAgICAgICAgICAgICAgIC8vIGRhdGEgd2FzIHdyaXR0ZW4sIGV4aXQKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIHdyaXRlIGNodW5rIG9mIGRhdGEKKyAgICAgICAgICAgIGRzdHNbaV0ucHV0KGJ1ZmZlciwgcG9zLCByZW0pOworICAgICAgICAgICAgcG9zICs9IHJlbTsKKyAgICAgICAgfQorICAgICAgICBpZiAocG9zICE9IGxlbikgeworICAgICAgICAgICAgLy8gVGhlIGRhdGEgZGlkIG5vdCBmZWV0IGludG8gdGhlIGJ1ZmZlcnMsCisgICAgICAgICAgICAvLyBpdCBzaG91bGQgbm90IGhhcHBlbiwgYmVjYXVzZSB0aGUgZGVzdGluYXRpb24gYnVmZmVycworICAgICAgICAgICAgLy8gaGFkIGJlZW4gY2hlY2tlZCBmb3IgdGhlIHNwYWNlIGJlZm9yZSByZWNvcmQgdW53cmFwcGluZy4KKyAgICAgICAgICAgIC8vIEJ1dCBpZiBpdCBzbywgd2Ugc2hvdWxkIGFsbGVydCBhYm91dCBpbnRlcm5hbCBlcnJvci4KKyAgICAgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICBBbGVydFByb3RvY29sLklOVEVSTkFMX0VSUk9SLAorICAgICAgICAgICAgICAgIG5ldyBTU0xFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJUaGUgcmVjZWl2ZWQgYXBwbGljYXRpb24gZGF0YSBjb3VsZCBub3QgYmUgZnVsbHkgd3JpdHRlbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW50byB0aGUgZGVzdGluYXRpb24gYnVmZmVycyIpKTsKKyAgICAgICAgfQorICAgICAgICBidWZmZXIgPSBudWxsOworICAgICAgICByZXR1cm4gbGVuOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMRW5naW5lRGF0YVN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMRW5naW5lRGF0YVN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUyMDlkZDEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xFbmdpbmVEYXRhU3RyZWFtLmphdmEKQEAgLTAsMCArMSw5MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKKworLyoqCisgKiBUaGlzIGNsYXNzIHByb3ZpZGVzIHRoZSBEYXRhU3RyZWFtIGZ1bmN0aW9uYWxpdHkKKyAqIGltcGxlbWVudGVkIG92ZXIgdGhlIGFycmF5IG9mIEJ5dGVCdWZmZXIgaW5zdGFuY2VzLgorICogQW1vbmcgd2l0aCB0aGUgZGF0YSBjaHVua3MgcmVhZCBmdW5jdGlvbmFsaXR5CisgKiBpdCBwcm92aWRlcyB0aGUgaW5mbyBhYm91dCBhbW91bnQgb2YgY29uc3VtZWQgZGF0YS4KKyAqIFRoZSBzb3VyY2UgQnl0ZUJ1ZmZlciBvYmplY3RzIGNhbiBiZSByZXBsYWNlZCBieSBvdGhlci4KKyAqIFNvIG9uZSBpbnN0YW5jZSBvZiB0aGlzIHdyYXBwZXIgY2FuIGJlIHJldXNlZCBmb3Igc2V2ZXJhbAorICogZGF0YSBzb3VyY2VzLgorICovCitwdWJsaWMgY2xhc3MgU1NMRW5naW5lRGF0YVN0cmVhbSBpbXBsZW1lbnRzIERhdGFTdHJlYW0geworCisgICAgcHJpdmF0ZSBCeXRlQnVmZmVyW10gc3JjczsKKyAgICBwcml2YXRlIGludCBvZmZzZXQ7CisgICAgcHJpdmF0ZSBpbnQgbGltaXQ7CisKKyAgICBwcml2YXRlIGludCBhdmFpbGFibGU7CisgICAgcHJpdmF0ZSBpbnQgY29uc3VtZWQ7CisKKyAgICBwcm90ZWN0ZWQgU1NMRW5naW5lRGF0YVN0cmVhbSgpIHt9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRTb3VyY2VCdWZmZXJzKEJ5dGVCdWZmZXJbXSBzcmNzLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIHRoaXMuc3JjcyA9IHNyY3M7CisgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0OworICAgICAgICB0aGlzLmxpbWl0ID0gb2Zmc2V0K2xlbmd0aDsKKyAgICAgICAgdGhpcy5jb25zdW1lZCA9IDA7CisgICAgICAgIHRoaXMuYXZhaWxhYmxlID0gMDsKKyAgICAgICAgZm9yIChpbnQgaT1vZmZzZXQ7IGk8bGltaXQ7IGkrKykgeworICAgICAgICAgICAgaWYgKHNyY3NbaV0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAiU29tZSBvZiB0aGUgaW5wdXQgcGFyYW1ldGVycyBhcmUgbnVsbCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXZhaWxhYmxlICs9IHNyY3NbaV0ucmVtYWluaW5nKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHsKKyAgICAgICAgcmV0dXJuIGF2YWlsYWJsZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNEYXRhKCkgeworICAgICAgICByZXR1cm4gYXZhaWxhYmxlID4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldERhdGEoaW50IGxlbmd0aCkgeworICAgICAgICAvLyBUT0RPOiBvcHRpbWl6YXRpb24gd29yazoKKyAgICAgICAgLy8gdXNlIEJ5dGVCdWZmZXIuZ2V0KGJ5dGVbXSxpbnQsaW50KQorICAgICAgICAvLyBhbmQgQnl0ZUJ1ZmZlci5oYXNBcnJheSgpIG1ldGhvZHMKKyAgICAgICAgaW50IGxlbiA9IChsZW5ndGggPCBhdmFpbGFibGUpID8gbGVuZ3RoIDogYXZhaWxhYmxlOworICAgICAgICBhdmFpbGFibGUgLT0gbGVuOworICAgICAgICBjb25zdW1lZCArPSBsZW47CisgICAgICAgIGJ5dGVbXSByZXMgPSBuZXcgYnl0ZVtsZW5dOworICAgICAgICBpbnQgcG9zID0gMDsKKyAgICAgICAgbG9vcDoKKyAgICAgICAgZm9yICg7IG9mZnNldDxsaW1pdDsgb2Zmc2V0KyspIHsKKyAgICAgICAgICAgIHdoaWxlIChzcmNzW29mZnNldF0uaGFzUmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgICAgICByZXNbcG9zKytdID0gc3Jjc1tvZmZzZXRdLmdldCgpOworICAgICAgICAgICAgICAgIGxlbiAtLTsKKyAgICAgICAgICAgICAgICBpZiAobGVuID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWsgbG9vcDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgaW50IGNvbnN1bWVkKCkgeworICAgICAgICByZXR1cm4gY29uc3VtZWQ7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xFbmdpbmVJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xFbmdpbmVJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWYwMzMyNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTEVuZ2luZUltcGwuamF2YQpAQCAtMCwwICsxLDc1NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLlJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lUmVzdWx0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMSGFuZHNoYWtlRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbjsKKworLyoqCisgKiBJbXBsZW1lbnRhdGlvbiBvZiBTU0xFbmdpbmUuCisgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lIGNsYXNzIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24uCisgKi8KK3B1YmxpYyBjbGFzcyBTU0xFbmdpbmVJbXBsIGV4dGVuZHMgU1NMRW5naW5lIHsKKworICAgIC8vIGluZGljYXRlcyBpZiBwZWVyIG1vZGUgd2FzIHNldAorICAgIHByaXZhdGUgYm9vbGVhbiBwZWVyX21vZGVfd2FzX3NldCA9IGZhbHNlOworICAgIC8vIGluZGljYXRlcyBpZiBoYW5kc2hha2UgaGFzIGJlZW4gc3RhcnRlZAorICAgIHByaXZhdGUgYm9vbGVhbiBoYW5kc2hha2Vfc3RhcnRlZCA9IGZhbHNlOworICAgIC8vIGluZGljYXRlcyBpZiBpbmJvdW5kIG9wZXJhdGlvbnMgZmluaXNoZWQKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNJbmJvdW5kRG9uZSA9IGZhbHNlOworICAgIC8vIGluZGljYXRlcyBpZiBvdXRib3VuZCBvcGVyYXRpb25zIGZpbmlzaGVkCisgICAgcHJpdmF0ZSBib29sZWFuIGlzT3V0Ym91bmREb25lID0gZmFsc2U7CisgICAgLy8gaW5kaWNhdGVzIGlmIGNsb3NlX25vdGlmeSBhbGVydCBoYWQgYmVlbiBzZW50IHRvIGFub3RoZXIgcGVlcgorICAgIHByaXZhdGUgYm9vbGVhbiBjbG9zZV9ub3RpZnlfd2FzX3NlbnQgPSBmYWxzZTsKKyAgICAvLyBpbmRpY2F0ZXMgaWYgY2xvc2Vfbm90aWZ5IGFsZXJ0IGhhZCBiZWVuIHJlY2VpdmVkIGZyb20gYW5vdGhlciBwZWVyCisgICAgcHJpdmF0ZSBib29sZWFuIGNsb3NlX25vdGlmeV93YXNfcmVjZWl2ZWQgPSBmYWxzZTsKKyAgICAvLyBpbmRpY2F0ZXMgaWYgZW5naW5lIHdhcyBjbG9zZWQgKGl0IG1lYW5zIHRoYXQKKyAgICAvLyBhbGwgdGhlIHdvcmtzIG9uIGl0IGFyZSBkb25lLCBleGNlcHQgKHByb2JhYmx5KSBzb21lIGZpbmFsaXppbmcgd29yaykKKyAgICBwcml2YXRlIGJvb2xlYW4gZW5naW5lX3dhc19jbG9zZWQgPSBmYWxzZTsKKyAgICAvLyBpbmRpY2F0ZXMgaWYgZW5naW5lIHdhcyBzaHV0dGVkIGRvd24gKGl0IG1lYW5zIHRoYXQKKyAgICAvLyBhbGwgY2xlYW5pbmcgd29yayBoYWQgYmVlbiBkb25lIGFuZCB0aGUgZW5naW5lIGlzIG5vdCBvcGVyYWJsZSkKKyAgICBwcml2YXRlIGJvb2xlYW4gZW5naW5lX3dhc19zaHV0dGVkZG93biA9IGZhbHNlOworCisgICAgLy8gcmVjb3JkIHByb3RvY29sIHRvIGJlIHVzZWQKKyAgICBwcm90ZWN0ZWQgU1NMUmVjb3JkUHJvdG9jb2wgcmVjb3JkUHJvdG9jb2w7CisgICAgLy8gaW5wdXQgc3RyZWFtIGZvciByZWNvcmQgcHJvdG9jb2wKKyAgICBwcml2YXRlIFNTTEJ1ZmZlcmVkSW5wdXQgcmVjUHJvdElTOworICAgIC8vIGhhbmRzaGFrZSBwcm90b2NvbCB0byBiZSB1c2VkCisgICAgcHJpdmF0ZSBIYW5kc2hha2VQcm90b2NvbCBoYW5kc2hha2VQcm90b2NvbDsKKyAgICAvLyBhbGVydCBwcm90b2NvbCB0byBiZSB1c2VkCisgICAgcHJpdmF0ZSBBbGVydFByb3RvY29sIGFsZXJ0UHJvdG9jb2w7CisgICAgLy8gcGxhY2Ugd2hlcmUgYXBwbGljYXRpb24gZGF0YSB3aWxsIGJlIHN0b3JlZAorICAgIHByaXZhdGUgU1NMRW5naW5lQXBwRGF0YSBhcHBEYXRhOworICAgIC8vIG91dGNvbWluZyBhcHBsaWNhdGlvbiBkYXRhIHN0cmVhbQorICAgIHByaXZhdGUgU1NMRW5naW5lRGF0YVN0cmVhbSBkYXRhU3RyZWFtID0gbmV3IFNTTEVuZ2luZURhdGFTdHJlYW0oKTsKKyAgICAvLyBhY3RpdmUgc2Vzc2lvbiBvYmplY3QKKyAgICBwcml2YXRlIFNTTFNlc3Npb25JbXBsIHNlc3Npb247CisKKyAgICAvLyBwZWVyIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVycworICAgIHByb3RlY3RlZCBTU0xQYXJhbWV0ZXJzSW1wbCBzc2xQYXJhbWV0ZXJzOworCisgICAgLy8gaW4gY2FzZSBvZiBlbWVyZ2VuY3kgc2l0dWF0aW9ucyB3aGVuIGRhdGEgY291bGQgbm90IGJlCisgICAgLy8gcGxhY2VkIGluIGRlc3RpbmF0aW9uIGJ1ZmZlcnMgaXQgd2lsbCBiZSBzdG9yZWQgaW4gdGhpcworICAgIC8vIGZpZWxkcworICAgIHByaXZhdGUgYnl0ZVtdIHJlbWFpbmluZ193cmFwcGVkX2RhdGEgPSBudWxsOworICAgIHByaXZhdGUgYnl0ZVtdIHJlbWFpbmluZ19oc2hfZGF0YSA9IG51bGw7CisKKyAgICAvLyBsb2dnZXIKKyAgICBwcml2YXRlIExvZ2dlci5TdHJlYW0gbG9nZ2VyID0gTG9nZ2VyLmdldFN0cmVhbSgiZW5naW5lIik7CisKKyAgICBwcm90ZWN0ZWQgU1NMRW5naW5lSW1wbChTU0xQYXJhbWV0ZXJzSW1wbCBzc2xQYXJhbWV0ZXJzKSB7CisgICAgICAgIHRoaXMuc3NsUGFyYW1ldGVycyA9IHNzbFBhcmFtZXRlcnM7CisgICAgfQorCisgICAgcHJvdGVjdGVkIFNTTEVuZ2luZUltcGwoU3RyaW5nIGhvc3QsIGludCBwb3J0LCBTU0xQYXJhbWV0ZXJzSW1wbCBzc2xQYXJhbWV0ZXJzKSB7CisgICAgICAgIHN1cGVyKGhvc3QsIHBvcnQpOworICAgICAgICB0aGlzLnNzbFBhcmFtZXRlcnMgPSBzc2xQYXJhbWV0ZXJzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0YXJ0cyB0aGUgaGFuZHNoYWtlLgorICAgICAqIEB0aHJvd3MgIFNTTEV4Y2VwdGlvbgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjYmVnaW5IYW5kc2hha2UoKSBtZXRob2QgZG9jdW1lbnRhdGlvbgorICAgICAqIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYmVnaW5IYW5kc2hha2UoKSB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGVuZ2luZV93YXNfY2xvc2VkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU1NMRXhjZXB0aW9uKCJFbmdpbmUgaGFzIGFscmVhZHkgYmVlbiBjbG9zZWQuIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFwZWVyX21vZGVfd2FzX3NldCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiQ2xpZW50L1NlcnZlciBtb2RlIHdhcyBub3Qgc2V0Iik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFoYW5kc2hha2Vfc3RhcnRlZCkgeworICAgICAgICAgICAgaGFuZHNoYWtlX3N0YXJ0ZWQgPSB0cnVlOworICAgICAgICAgICAgaWYgKGdldFVzZUNsaWVudE1vZGUoKSkgeworICAgICAgICAgICAgICAgIGhhbmRzaGFrZVByb3RvY29sID0gbmV3IENsaWVudEhhbmRzaGFrZUltcGwodGhpcyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGhhbmRzaGFrZVByb3RvY29sID0gbmV3IFNlcnZlckhhbmRzaGFrZUltcGwodGhpcyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhcHBEYXRhID0gbmV3IFNTTEVuZ2luZUFwcERhdGEoKTsKKyAgICAgICAgICAgIGFsZXJ0UHJvdG9jb2wgPSBuZXcgQWxlcnRQcm90b2NvbCgpOworICAgICAgICAgICAgcmVjUHJvdElTID0gbmV3IFNTTEJ1ZmZlcmVkSW5wdXQoKTsKKyAgICAgICAgICAgIHJlY29yZFByb3RvY29sID0gbmV3IFNTTFJlY29yZFByb3RvY29sKGhhbmRzaGFrZVByb3RvY29sLAorICAgICAgICAgICAgICAgICAgICBhbGVydFByb3RvY29sLCByZWNQcm90SVMsIGFwcERhdGEpOworICAgICAgICB9CisgICAgICAgIGhhbmRzaGFrZVByb3RvY29sLnN0YXJ0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIGluYm91bmQgb3BlcmF0aW9ucyBvZiB0aGlzIGVuZ2luZQorICAgICAqIEB0aHJvd3MgIFNTTEV4Y2VwdGlvbgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjY2xvc2VJbmJvdW5kKCkgbWV0aG9kIGRvY3VtZW50YXRpb24KKyAgICAgKiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlSW5ib3VuZCgpIHRocm93cyBTU0xFeGNlcHRpb24geworICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJjbG9zZUluYm91bmQoKSAiK2lzSW5ib3VuZERvbmUpOworICAgICAgICB9CisgICAgICAgIGlmIChpc0luYm91bmREb25lKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaXNJbmJvdW5kRG9uZSA9IHRydWU7CisgICAgICAgIGVuZ2luZV93YXNfY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgaWYgKGhhbmRzaGFrZV9zdGFydGVkKSB7CisgICAgICAgICAgICBpZiAoIWNsb3NlX25vdGlmeV93YXNfcmVjZWl2ZWQpIHsKKyAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uaW52YWxpZGF0ZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhbGVydFByb3RvY29sLmFsZXJ0KEFsZXJ0UHJvdG9jb2wuRkFUQUwsCisgICAgICAgICAgICAgICAgICAgICAgICBBbGVydFByb3RvY29sLklOVEVSTkFMX0VSUk9SKTsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU1NMRXhjZXB0aW9uKCJJbmJvdW5kIGlzIGNsb3NlZCBiZWZvcmUgY2xvc2Vfbm90aWZ5ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgImFsZXJ0IGhhcyBiZWVuIHJlY2VpdmVkLiIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gZW5naW5lIGlzIGNsb3NpbmcgYmVmb3JlIGluaXRpYWwgaGFuZHNoYWtlIGhhcyBiZWVuIG1hZGUKKyAgICAgICAgICAgIHNodXRkb3duKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgb3V0Ym91bmQgb3BlcmF0aW9ucyBvZiB0aGlzIGVuZ2luZQorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjY2xvc2VPdXRib3VuZCgpIG1ldGhvZCBkb2N1bWVudGF0aW9uCisgICAgICogZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZU91dGJvdW5kKCkgeworICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJjbG9zZU91dGJvdW5kKCkgIitpc091dGJvdW5kRG9uZSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlzT3V0Ym91bmREb25lKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaXNPdXRib3VuZERvbmUgPSB0cnVlOworICAgICAgICBpZiAoaGFuZHNoYWtlX3N0YXJ0ZWQpIHsKKyAgICAgICAgICAgIC8vIGluaXRpYWwgaGFuZHNoYWtlIGhhZCBiZWVuIHN0YXJ0ZWQKKyAgICAgICAgICAgIGFsZXJ0UHJvdG9jb2wuYWxlcnQoQWxlcnRQcm90b2NvbC5XQVJOSU5HLAorICAgICAgICAgICAgICAgICAgICBBbGVydFByb3RvY29sLkNMT1NFX05PVElGWSk7CisgICAgICAgICAgICBjbG9zZV9ub3RpZnlfd2FzX3NlbnQgPSB0cnVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gZW5naW5lIGlzIGNsb3NpbmcgYmVmb3JlIGluaXRpYWwgaGFuZHNoYWtlIGhhcyBiZWVuIG1hZGUKKyAgICAgICAgICAgIHNodXRkb3duKCk7CisgICAgICAgIH0KKyAgICAgICAgZW5naW5lX3dhc19jbG9zZWQgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgaGFuZHNoYWtlJ3MgZGVsZWdhdGVkIHRhc2tzIHRvIGJlIHJ1bgorICAgICAqIEByZXR1cm4gdGhlIGRlbGVnYXRlZCB0YXNrIHRvIGJlIGV4ZWN1dGVkLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjZ2V0RGVsZWdhdGVkVGFzaygpIG1ldGhvZCBkb2N1bWVudGF0aW9uCisgICAgICogZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgUnVubmFibGUgZ2V0RGVsZWdhdGVkVGFzaygpIHsKKyAgICAgICAgcmV0dXJuIGhhbmRzaGFrZVByb3RvY29sLmdldFRhc2soKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIG5hbWVzIG9mIHN1cHBvcnRlZCBjaXBoZXIgc3VpdGVzLgorICAgICAqIEByZXR1cm4gYXJyYXkgb2Ygc3RyaW5ncyBjb250YWluaW5nIHRoZSBuYW1lcyBvZiBzdXBwb3J0ZWQgY2lwaGVyIHN1aXRlcworICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkgbWV0aG9kCisgICAgICogZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSB7CisgICAgICAgIHJldHVybiBDaXBoZXJTdWl0ZS5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZU5hbWVzKCk7CisgICAgfQorCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tIFNTTFBhcmFtZXRlcnMgYmFzZWQgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI2dldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKSBtZXRob2QKKyAgICAgKiBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ1tdIGdldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKSB7CisgICAgICAgIHJldHVybiBzc2xQYXJhbWV0ZXJzLmdldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSNzZXRFbmFibGVkQ2lwaGVyU3VpdGVzKFN0cmluZ1tdKSBtZXRob2QKKyAgICAgKiBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RW5hYmxlZENpcGhlclN1aXRlcyhTdHJpbmdbXSBzdWl0ZXMpIHsKKyAgICAgICAgc3NsUGFyYW1ldGVycy5zZXRFbmFibGVkQ2lwaGVyU3VpdGVzKHN1aXRlcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjZ2V0U3VwcG9ydGVkUHJvdG9jb2xzKCkgbWV0aG9kCisgICAgICogZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRTdXBwb3J0ZWRQcm90b2NvbHMoKSB7CisgICAgICAgIHJldHVybiBQcm90b2NvbFZlcnNpb24uc3VwcG9ydGVkUHJvdG9jb2xzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjZ2V0RW5hYmxlZFByb3RvY29scygpIG1ldGhvZAorICAgICAqIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RW5hYmxlZFByb3RvY29scygpIHsKKyAgICAgICAgcmV0dXJuIHNzbFBhcmFtZXRlcnMuZ2V0RW5hYmxlZFByb3RvY29scygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3NldEVuYWJsZWRQcm90b2NvbHMoU3RyaW5nW10pIG1ldGhvZAorICAgICAqIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRFbmFibGVkUHJvdG9jb2xzKFN0cmluZ1tdIHByb3RvY29scykgeworICAgICAgICBzc2xQYXJhbWV0ZXJzLnNldEVuYWJsZWRQcm90b2NvbHMocHJvdG9jb2xzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSNzZXRVc2VDbGllbnRNb2RlKGJvb2xlYW4pIG1ldGhvZAorICAgICAqIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRVc2VDbGllbnRNb2RlKGJvb2xlYW4gbW9kZSkgeworICAgICAgICBpZiAoaGFuZHNoYWtlX3N0YXJ0ZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAiQ291bGQgbm90IGNoYW5nZSB0aGUgbW9kZSBhZnRlciB0aGUgaW5pdGlhbCBoYW5kc2hha2UgaGFzIGJlZ3VuLiIpOworICAgICAgICB9CisgICAgICAgIHNzbFBhcmFtZXRlcnMuc2V0VXNlQ2xpZW50TW9kZShtb2RlKTsKKyAgICAgICAgcGVlcl9tb2RlX3dhc19zZXQgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI2dldFVzZUNsaWVudE1vZGUoKSBtZXRob2QKKyAgICAgKiBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0VXNlQ2xpZW50TW9kZSgpIHsKKyAgICAgICAgcmV0dXJuIHNzbFBhcmFtZXRlcnMuZ2V0VXNlQ2xpZW50TW9kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3NldE5lZWRDbGllbnRBdXRoKGJvb2xlYW4pIG1ldGhvZAorICAgICAqIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXROZWVkQ2xpZW50QXV0aChib29sZWFuIG5lZWQpIHsKKyAgICAgICAgc3NsUGFyYW1ldGVycy5zZXROZWVkQ2xpZW50QXV0aChuZWVkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSNnZXROZWVkQ2xpZW50QXV0aCgpIG1ldGhvZAorICAgICAqIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXROZWVkQ2xpZW50QXV0aCgpIHsKKyAgICAgICAgcmV0dXJuIHNzbFBhcmFtZXRlcnMuZ2V0TmVlZENsaWVudEF1dGgoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSNzZXRXYW50Q2xpZW50QXV0aChib29sZWFuKSBtZXRob2QKKyAgICAgKiBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0V2FudENsaWVudEF1dGgoYm9vbGVhbiB3YW50KSB7CisgICAgICAgIHNzbFBhcmFtZXRlcnMuc2V0V2FudENsaWVudEF1dGgod2FudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjZ2V0V2FudENsaWVudEF1dGgoKSBtZXRob2QKKyAgICAgKiBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0V2FudENsaWVudEF1dGgoKSB7CisgICAgICAgIHJldHVybiBzc2xQYXJhbWV0ZXJzLmdldFdhbnRDbGllbnRBdXRoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjc2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKGJvb2xlYW4pIG1ldGhvZAorICAgICAqIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oYm9vbGVhbiBmbGFnKSB7CisgICAgICAgIHNzbFBhcmFtZXRlcnMuc2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKGZsYWcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI2dldEVuYWJsZVNlc3Npb25DcmVhdGlvbigpIG1ldGhvZAorICAgICAqIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oKSB7CisgICAgICAgIHJldHVybiBzc2xQYXJhbWV0ZXJzLmdldEVuYWJsZVNlc3Npb25DcmVhdGlvbigpOworICAgIH0KKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSNnZXRIYW5kc2hha2VTdGF0dXMoKSBtZXRob2QKKyAgICAgKiBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMgZ2V0SGFuZHNoYWtlU3RhdHVzKCkgeworICAgICAgICBpZiAoIWhhbmRzaGFrZV9zdGFydGVkIHx8IGVuZ2luZV93YXNfc2h1dHRlZGRvd24pIHsKKyAgICAgICAgICAgIC8vIGluaXRpYWwgaGFuZHNoYWtlIGhhcyBub3QgYmVlbiBzdGFydGVkIHlldAorICAgICAgICAgICAgcmV0dXJuIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMuTk9UX0hBTkRTSEFLSU5HOworICAgICAgICB9CisgICAgICAgIGlmIChhbGVydFByb3RvY29sLmhhc0FsZXJ0KCkpIHsKKyAgICAgICAgICAgIC8vIG5lZWQgdG8gc2VuZCBhbiBhbGVydAorICAgICAgICAgICAgcmV0dXJuIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMuTkVFRF9XUkFQOworICAgICAgICB9CisgICAgICAgIGlmIChjbG9zZV9ub3RpZnlfd2FzX3NlbnQgJiYgIWNsb3NlX25vdGlmeV93YXNfcmVjZWl2ZWQpIHsKKyAgICAgICAgICAgIC8vIHdhaXRpbmcgZm9yICJjbG9zZV9ub3RpZnkiIHJlc3BvbnNlCisgICAgICAgICAgICByZXR1cm4gU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cy5ORUVEX1VOV1JBUDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaGFuZHNoYWtlUHJvdG9jb2wuZ2V0U3RhdHVzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjZ2V0U2Vzc2lvbigpIG1ldGhvZAorICAgICAqIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU1NMU2Vzc2lvbiBnZXRTZXNzaW9uKCkgeworICAgICAgICBpZiAoc2Vzc2lvbiAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gc2Vzc2lvbjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gU1NMU2Vzc2lvbkltcGwuTlVMTF9TRVNTSU9OOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI2lzSW5ib3VuZERvbmUoKSBtZXRob2QKKyAgICAgKiBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNJbmJvdW5kRG9uZSgpIHsKKyAgICAgICAgcmV0dXJuIGlzSW5ib3VuZERvbmUgfHwgZW5naW5lX3dhc19jbG9zZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjaXNPdXRib3VuZERvbmUoKSBtZXRob2QKKyAgICAgKiBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNPdXRib3VuZERvbmUoKSB7CisgICAgICAgIHJldHVybiBpc091dGJvdW5kRG9uZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvZGVzIG9uZSBjb21wbGV0ZSBTU0wvVExTIHJlY29yZCBwcm92aWRlZCBpbiB0aGUgc291cmNlIGJ1ZmZlci4KKyAgICAgKiBJZiBkZWNvZGVkIHJlY29yZCBjb250YWluZWQgYXBwbGljYXRpb24gZGF0YSwgdGhpcyBkYXRhIHdpbGwKKyAgICAgKiBiZSBwbGFjZWQgaW4gdGhlIGRlc3RpbmF0aW9uIGJ1ZmZlcnMuCisgICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgVExTIHJlY29yZCBmcmFnbWVudGF0aW9uIHNlZQorICAgICAqIFRMUyB2IDEgc3BlY2lmaWNhdGlvbiAoaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI0Ni50eHQpIHAgNi4yLgorICAgICAqIEBwYXJhbSBzcmMgc291cmNlIGJ1ZmZlciBjb250YWluaW5nIFNTTC9UTFMgcmVjb3JkLgorICAgICAqIEBwYXJhbSBkc3RzIGRlc3RpbmF0aW9uIGJ1ZmZlcnMgdG8gcGxhY2UgcmVjZWl2ZWQgYXBwbGljYXRpb24gZGF0YS4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3Vud3JhcChCeXRlQnVmZmVyLEJ5dGVCdWZmZXJbXSxpbnQsaW50KQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNTTEVuZ2luZVJlc3VsdCB1bndyYXAoQnl0ZUJ1ZmZlciBzcmMsIEJ5dGVCdWZmZXJbXSBkc3RzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGVuZ2luZV93YXNfc2h1dHRlZGRvd24pIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgU1NMRW5naW5lUmVzdWx0KFNTTEVuZ2luZVJlc3VsdC5TdGF0dXMuQ0xPU0VELAorICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzLk5PVF9IQU5EU0hBS0lORywgMCwgMCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChzcmMgPT0gbnVsbCkgfHwgKGRzdHMgPT0gbnVsbCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJTb21lIG9mIHRoZSBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBudWxsIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWhhbmRzaGFrZV9zdGFydGVkKSB7CisgICAgICAgICAgICBiZWdpbkhhbmRzaGFrZSgpOworICAgICAgICB9CisKKyAgICAgICAgU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cyBoYW5kc2hha2VTdGF0dXMgPSBnZXRIYW5kc2hha2VTdGF0dXMoKTsKKyAgICAgICAgLy8gSWYgaXMgaXMgaW5pdGlhbCBoYW5kc2hha2Ugb3IgY29ubmVjdGlvbiBjbG9zdXJlIHN0YWdlLAorICAgICAgICAvLyBjaGVjayBpZiB0aGlzIGNhbGwgd2FzIG1hZGUgaW4gc3BpdGUgb2YgaGFuZHNoYWtlIHN0YXR1cworICAgICAgICBpZiAoKHNlc3Npb24gPT0gbnVsbCB8fCBlbmdpbmVfd2FzX2Nsb3NlZCkgJiYgKAorICAgICAgICAgICAgICAgICAgICBoYW5kc2hha2VTdGF0dXMuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cy5ORUVEX1dSQVApIHx8CisgICAgICAgICAgICAgICAgICAgIGhhbmRzaGFrZVN0YXR1cy5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzLk5FRURfVEFTSykpKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFNTTEVuZ2luZVJlc3VsdCgKKyAgICAgICAgICAgICAgICAgICAgZ2V0RW5naW5lU3RhdHVzKCksIGhhbmRzaGFrZVN0YXR1cywgMCwgMCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc3JjLnJlbWFpbmluZygpIDwgcmVjb3JkUHJvdG9jb2wuZ2V0TWluUmVjb3JkU2l6ZSgpKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFNTTEVuZ2luZVJlc3VsdCgKKyAgICAgICAgICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LlN0YXR1cy5CVUZGRVJfVU5ERVJGTE9XLAorICAgICAgICAgICAgICAgICAgICBnZXRIYW5kc2hha2VTdGF0dXMoKSwgMCwgMCk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3JjLm1hcmsoKTsKKyAgICAgICAgICAgIC8vIGNoZWNrIHRoZSBkZXN0aW5hdGlvbiBidWZmZXJzIGFuZCBjb3VudCB0aGVpciBjYXBhY2l0eQorICAgICAgICAgICAgaW50IGNhcGFjaXR5ID0gMDsKKyAgICAgICAgICAgIGZvciAoaW50IGk9b2Zmc2V0OyBpPG9mZnNldCtsZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChkc3RzW2ldID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU29tZSBvZiB0aGUgaW5wdXQgcGFyYW1ldGVycyBhcmUgbnVsbCIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoZHN0c1tpXS5pc1JlYWRPbmx5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNhcGFjaXR5ICs9IGRzdHNbaV0ucmVtYWluaW5nKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY2FwYWNpdHkgPCByZWNvcmRQcm90b2NvbC5nZXREYXRhU2l6ZShzcmMucmVtYWluaW5nKCkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTU0xFbmdpbmVSZXN1bHQoCisgICAgICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuU3RhdHVzLkJVRkZFUl9PVkVSRkxPVywKKyAgICAgICAgICAgICAgICAgICAgICAgIGdldEhhbmRzaGFrZVN0YXR1cygpLCAwLCAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlY1Byb3RJUy5zZXRTb3VyY2VCdWZmZXIoc3JjKTsKKyAgICAgICAgICAgIC8vIHVud3JhcCB0aGUgcmVjb3JkIGNvbnRhaW5lZCBpbiBzb3VyY2UgYnVmZmVyLCBwYXNzIGl0CisgICAgICAgICAgICAvLyB0byBhcHByb3ByaWF0ZSBjbGllbnQgcHJvdG9jb2wgKGFsZXJ0LCBoYW5kc2hha2UsIG9yIGFwcCkKKyAgICAgICAgICAgIC8vIGFuZCByZXRyaWV2ZSB0aGUgdHlwZSBvZiB1bndyYXBwZWQgZGF0YQorICAgICAgICAgICAgaW50IHR5cGUgPSByZWNvcmRQcm90b2NvbC51bndyYXAoKTsKKyAgICAgICAgICAgIC8vIHByb2Nlc3MgdGhlIGRhdGEgYW5kIHJldHVybiB0aGUgcmVzdWx0CisgICAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgICAgICAgICAgICBjYXNlIENvbnRlbnRUeXBlLkhBTkRTSEFLRToKKyAgICAgICAgICAgICAgICBjYXNlIENvbnRlbnRUeXBlLkNIQU5HRV9DSVBIRVJfU1BFQzoKKyAgICAgICAgICAgICAgICAgICAgaWYgKGhhbmRzaGFrZVByb3RvY29sLmdldFN0YXR1cygpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzLkZJTklTSEVEKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbiA9IHJlY29yZFByb3RvY29sLmdldFNlc3Npb24oKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIENvbnRlbnRUeXBlLkFQUExJQ0FUSU9OX0RBVEE6CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgQ29udGVudFR5cGUuQUxFUlQ6CisgICAgICAgICAgICAgICAgICAgIGlmIChhbGVydFByb3RvY29sLmlzRmF0YWxBbGVydCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhbGVydFByb3RvY29sLnNldFByb2Nlc3NlZCgpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlc3Npb24gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uaW52YWxpZGF0ZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGRlc2NyaXB0aW9uID0gIkZhdGFsIGFsZXJ0IHJlY2VpdmVkICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGFsZXJ0UHJvdG9jb2wuZ2V0QWxlcnREZXNjcmlwdGlvbigpOworICAgICAgICAgICAgICAgICAgICAgICAgc2h1dGRvd24oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTU0xFeGNlcHRpb24oZGVzY3JpcHRpb24pOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIldhcm5pbmcgYWxsZXJ0IGhhcyBiZWVuIHJlY2VpdmVkOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgYWxlcnRQcm90b2NvbC5nZXRBbGVydERlc2NyaXB0aW9uKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGFsZXJ0UHJvdG9jb2wuZ2V0RGVzY3JpcHRpb25Db2RlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEFsZXJ0UHJvdG9jb2wuQ0xPU0VfTk9USUZZOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGVydFByb3RvY29sLnNldFByb2Nlc3NlZCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9zZV9ub3RpZnlfd2FzX3JlY2VpdmVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjbG9zZV9ub3RpZnlfd2FzX3NlbnQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlT3V0Ym91bmQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlSW5ib3VuZCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvc2VJbmJvdW5kKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaHV0ZG93bigpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQWxlcnRQcm90b2NvbC5OT19SRU5FR09USUFUSU9OOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGVydFByb3RvY29sLnNldFByb2Nlc3NlZCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtZXNzYWdlIHJlY2VpdmVkIGR1cmluZyB0aGUgaW5pdGlhbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZHNoYWtlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWxlcnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWxlcnRQcm90b2NvbC5IQU5EU0hBS0VfRkFJTFVSRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU1NMSGFuZHNoYWtlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVjZWl2ZWQgbm9fcmVuZWdvdGlhdGlvbiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgImR1cmluZyB0aGUgaW5pdGlhbCBoYW5kc2hha2UiKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBqdXN0IHN0b3AgdGhlIGhhbmRzaGFrZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZHNoYWtlUHJvdG9jb2wuc3RvcCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsZXJ0UHJvdG9jb2wuc2V0UHJvY2Vzc2VkKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmV3IFNTTEVuZ2luZVJlc3VsdChnZXRFbmdpbmVTdGF0dXMoKSwgZ2V0SGFuZHNoYWtlU3RhdHVzKCksCisgICAgICAgICAgICAgICAgICAgIHJlY1Byb3RJUy5jb25zdW1lZCgpLAorICAgICAgICAgICAgICAgICAgICAvLyBwbGFjZSB0aGUgYXBwLiBkYXRhIChpZiBhbnkpIGludG8gdGhlIGRlc3QuIGJ1ZmZlcnMKKyAgICAgICAgICAgICAgICAgICAgLy8gYW5kIGdldCB0aGUgbnVtYmVyIG9mIHByb2R1Y2VkIGJ5dGVzOgorICAgICAgICAgICAgICAgICAgICBhcHBEYXRhLnBsYWNlVG8oZHN0cywgb2Zmc2V0LCBsZW5ndGgpKTsKKyAgICAgICAgfSBjYXRjaCAoQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIHRoZXJlIHdhcyBub3QgZW5vdWdodCBkYXRhIG91cmNlIGJ1ZmZlciB0byBtYWtlIGNvbXBsZXRlIHBhY2tldAorICAgICAgICAgICAgc3JjLnJlc2V0KCk7CisgICAgICAgICAgICByZXR1cm4gbmV3IFNTTEVuZ2luZVJlc3VsdChTU0xFbmdpbmVSZXN1bHQuU3RhdHVzLkJVRkZFUl9VTkRFUkZMT1csCisgICAgICAgICAgICAgICAgICAgIGdldEhhbmRzaGFrZVN0YXR1cygpLCAwLCAwKTsKKyAgICAgICAgfSBjYXRjaCAoQWxlcnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZmF0YWwgYWxlcnQgb2NjdXJlZAorICAgICAgICAgICAgYWxlcnRQcm90b2NvbC5hbGVydChBbGVydFByb3RvY29sLkZBVEFMLCBlLmdldERlc2NyaXB0aW9uQ29kZSgpKTsKKyAgICAgICAgICAgIGVuZ2luZV93YXNfY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgICAgIHNyYy5yZXNldCgpOworICAgICAgICAgICAgaWYgKHNlc3Npb24gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlc3Npb24uaW52YWxpZGF0ZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gc2h1dGRvd24gd29yayB3aWxsIGJlIG1hZGUgYWZ0ZXIgdGhlIGFsZXJ0IHdpbGwgYmUgc2VudAorICAgICAgICAgICAgLy8gdG8gYW5vdGhlciBwZWVyIChieSB3cmFwIG1ldGhvZCkKKyAgICAgICAgICAgIHRocm93IGUuZ2V0UmVhc29uKCk7CisgICAgICAgIH0gY2F0Y2ggKFNTTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhbGVydFByb3RvY29sLmFsZXJ0KEFsZXJ0UHJvdG9jb2wuRkFUQUwsCisgICAgICAgICAgICAgICAgICAgIEFsZXJ0UHJvdG9jb2wuSU5URVJOQUxfRVJST1IpOworICAgICAgICAgICAgZW5naW5lX3dhc19jbG9zZWQgPSB0cnVlOworICAgICAgICAgICAgLy8gc2h1dGRvd24gd29yayB3aWxsIGJlIG1hZGUgYWZ0ZXIgdGhlIGFsZXJ0IHdpbGwgYmUgc2VudAorICAgICAgICAgICAgLy8gdG8gYW5vdGhlciBwZWVyIChieSB3cmFwIG1ldGhvZCkKKyAgICAgICAgICAgIHRocm93IG5ldyBTU0xFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlcyB0aGUgYXBwbGljYXRpb24gZGF0YSBpbnRvIFNTTC9UTFMgcmVjb3JkLiBJZiBoYW5kc2hha2Ugc3RhdHVzCisgICAgICogb2YgdGhlIGVuZ2luZSBkaWZmZXJzIGZyb20gTk9UX0hBTkRTSEFLSU5HIHRoZSBvcGVyYXRpb24gY2FuIHdvcmsKKyAgICAgKiB3aXRob3V0IGNvbnN1bWluZyBvZiB0aGUgc291cmNlIGRhdGEuCisgICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgVExTIHJlY29yZCBmcmFnbWVudGF0aW9uIHNlZQorICAgICAqIFRMUyB2IDEgc3BlY2lmaWNhdGlvbiAoaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI0Ni50eHQpIHAgNi4yLgorICAgICAqIEBwYXJhbSBzcmNzIHRoZSBzb3VyY2UgYnVmZmVycyB3aXRoIGFwcGxpY2F0aW9uIGRhdGEgdG8gYmUgZW5jb2RlZAorICAgICAqIGludG8gU1NML1RMUyByZWNvcmQuCisgICAgICogQHBhcmFtIG9mZnNldCB0aGUgb2Zmc2V0IGluIHRoZSBkZXN0aW5hdGlvbiBidWZmZXJzIGFycmF5IHBvaW50aW5nIHRvCisgICAgICogdGhlIGZpcnN0IGJ1ZmZlciB3aXRoIHRoZSBzb3VyY2UgZGF0YS4KKyAgICAgKiBAcGFyYW0gbGVuIHNwZWNpZmllcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnVmZmVycyB0byBiZSBwcm9jZXNlZC4KKyAgICAgKiBAcGFyYW0gZHN0IHRoZSBkZXN0aW5hdGlvbiBidWZmZXIgd2hlcmUgZW5jb2RlZCBkYXRhIHdpbGwgYmUgcGxhY2VkLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjd3JhcChCeXRlQnVmZmVyW10saW50LGludCxCeXRlQnVmZmVyKSBtZXRob2QKKyAgICAgKiBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNTTEVuZ2luZVJlc3VsdCB3cmFwKEJ5dGVCdWZmZXJbXSBzcmNzLCBpbnQgb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsZW4sIEJ5dGVCdWZmZXIgZHN0KSB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGVuZ2luZV93YXNfc2h1dHRlZGRvd24pIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgU1NMRW5naW5lUmVzdWx0KFNTTEVuZ2luZVJlc3VsdC5TdGF0dXMuQ0xPU0VELAorICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzLk5PVF9IQU5EU0hBS0lORywgMCwgMCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChzcmNzID09IG51bGwpIHx8IChkc3QgPT0gbnVsbCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJTb21lIG9mIHRoZSBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRzdC5pc1JlYWRPbmx5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFoYW5kc2hha2Vfc3RhcnRlZCkgeworICAgICAgICAgICAgYmVnaW5IYW5kc2hha2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMgaGFuZHNoYWtlU3RhdHVzID0gZ2V0SGFuZHNoYWtlU3RhdHVzKCk7CisgICAgICAgIC8vIElmIGl0IGlzIGFuIGluaXRpYWwgaGFuZHNoYWtlIG9yIGNvbm5lY3Rpb24gY2xvc3VyZSBzdGFnZSwKKyAgICAgICAgLy8gY2hlY2sgaWYgdGhpcyBjYWxsIHdhcyBtYWRlIGluIHNwaXRlIG9mIGhhbmRzaGFrZSBzdGF0dXMKKyAgICAgICAgaWYgKChzZXNzaW9uID09IG51bGwgfHwgZW5naW5lX3dhc19jbG9zZWQpICYmICgKKyAgICAgICAgICAgICAgICBoYW5kc2hha2VTdGF0dXMuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cy5ORUVEX1VOV1JBUCkgfHwKKyAgICAgICAgICAgICAgICBoYW5kc2hha2VTdGF0dXMuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cy5ORUVEX1RBU0spKSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBTU0xFbmdpbmVSZXN1bHQoCisgICAgICAgICAgICAgICAgICAgIGdldEVuZ2luZVN0YXR1cygpLCBoYW5kc2hha2VTdGF0dXMsIDAsIDApOworICAgICAgICB9CisKKyAgICAgICAgaW50IGNhcGFjaXR5ID0gZHN0LnJlbWFpbmluZygpOworICAgICAgICBpbnQgcHJvZHVjZWQgPSAwOworCisgICAgICAgIGlmIChhbGVydFByb3RvY29sLmhhc0FsZXJ0KCkpIHsKKyAgICAgICAgICAgIC8vIHdlIGhhdmUgYW4gYWxlcnQgdG8gYmUgc2VudAorICAgICAgICAgICAgaWYgKGNhcGFjaXR5IDwgcmVjb3JkUHJvdG9jb2wuZ2V0UmVjb3JkU2l6ZSgyKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU1NMRW5naW5lUmVzdWx0KAorICAgICAgICAgICAgICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LlN0YXR1cy5CVUZGRVJfT1ZFUkZMT1csCisgICAgICAgICAgICAgICAgICAgICAgICBoYW5kc2hha2VTdGF0dXMsIDAsIDApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnl0ZVtdIGFsZXJ0X2RhdGEgPSBhbGVydFByb3RvY29sLndyYXAoKTsKKyAgICAgICAgICAgIC8vIHBsYWNlIHRoZSBhbGVydCByZWNvcmQgaW50byBkZXN0aW5hdGlvbgorICAgICAgICAgICAgZHN0LnB1dChhbGVydF9kYXRhKTsKKyAgICAgICAgICAgIGlmIChhbGVydFByb3RvY29sLmlzRmF0YWxBbGVydCgpKSB7CisgICAgICAgICAgICAgICAgYWxlcnRQcm90b2NvbC5zZXRQcm9jZXNzZWQoKTsKKyAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uaW52YWxpZGF0ZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBmYXRhbCBhbGVydCBoYXMgYmVlbiBzZW50LCBzbyBzaHV0IGRvd24gdGhlIGVuZ2luZQorICAgICAgICAgICAgICAgIHNodXRkb3duKCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTU0xFbmdpbmVSZXN1bHQoCisgICAgICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuU3RhdHVzLkNMT1NFRCwKKyAgICAgICAgICAgICAgICAgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMuTk9UX0hBTkRTSEFLSU5HLAorICAgICAgICAgICAgICAgICAgICAgICAgMCwgYWxlcnRfZGF0YS5sZW5ndGgpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhbGVydFByb3RvY29sLnNldFByb2Nlc3NlZCgpOworICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIHRoZSB3b3JrcyBvbiB0aGlzIGVuZ2luZSBoYXZlIGJlZW4gZG9uZQorICAgICAgICAgICAgICAgIGlmIChjbG9zZV9ub3RpZnlfd2FzX3NlbnQgJiYgY2xvc2Vfbm90aWZ5X3dhc19yZWNlaXZlZCkgeworICAgICAgICAgICAgICAgICAgICBzaHV0ZG93bigpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNTTEVuZ2luZVJlc3VsdChTU0xFbmdpbmVSZXN1bHQuU3RhdHVzLkNMT1NFRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzLk5PVF9IQU5EU0hBS0lORywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBhbGVydF9kYXRhLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU1NMRW5naW5lUmVzdWx0KAorICAgICAgICAgICAgICAgICAgICAgICAgZ2V0RW5naW5lU3RhdHVzKCksCisgICAgICAgICAgICAgICAgICAgICAgICBnZXRIYW5kc2hha2VTdGF0dXMoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIDAsIGFsZXJ0X2RhdGEubGVuZ3RoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChjYXBhY2l0eSA8IHJlY29yZFByb3RvY29sLmdldE1pblJlY29yZFNpemUoKSkgeworICAgICAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIkNhcGFjaXR5IG9mIHRoZSBkZXN0aW5hdGlvbigiCisgICAgICAgICAgICAgICAgICAgICAgICArY2FwYWNpdHkrIikgPCBNSU5fUEFDS0VUX1NJWkUoIgorICAgICAgICAgICAgICAgICAgICAgICAgK3JlY29yZFByb3RvY29sLmdldE1pblJlY29yZFNpemUoKSsiKSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBTU0xFbmdpbmVSZXN1bHQoU1NMRW5naW5lUmVzdWx0LlN0YXR1cy5CVUZGRVJfT1ZFUkZMT1csCisgICAgICAgICAgICAgICAgICAgICAgICBoYW5kc2hha2VTdGF0dXMsIDAsIDApOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICghaGFuZHNoYWtlU3RhdHVzLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMuTkVFRF9XUkFQKSkgeworICAgICAgICAgICAgICAgIC8vIHNvIHdlIHdyYXBzIGFwcGxpY2F0aW9uIGRhdGEKKyAgICAgICAgICAgICAgICBkYXRhU3RyZWFtLnNldFNvdXJjZUJ1ZmZlcnMoc3Jjcywgb2Zmc2V0LCBsZW4pOworICAgICAgICAgICAgICAgIGlmICgoY2FwYWNpdHkgPCBTU0xSZWNvcmRQcm90b2NvbC5NQVhfU1NMX1BBQ0tFVF9TSVpFKSAmJgorICAgICAgICAgICAgICAgICAgICAoY2FwYWNpdHkgPCByZWNvcmRQcm90b2NvbC5nZXRSZWNvcmRTaXplKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFTdHJlYW0uYXZhaWxhYmxlKCkpKSkgeworICAgICAgICAgICAgICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJUaGUgZGVzdGluYXRpb24gYnVmZmVyKCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgK2NhcGFjaXR5KyIpIGNhbiBub3QgdGFrZSB0aGUgcmVzdWx0aW5nIHBhY2tldCgiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgcmVjb3JkUHJvdG9jb2wuZ2V0UmVjb3JkU2l6ZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFTdHJlYW0uYXZhaWxhYmxlKCkpKyIpIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTU0xFbmdpbmVSZXN1bHQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LlN0YXR1cy5CVUZGRVJfT1ZFUkZMT1csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZHNoYWtlU3RhdHVzLCAwLCAwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHJlbWFpbmluZ193cmFwcGVkX2RhdGEgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZW1haW5pbmdfd3JhcHBlZF9kYXRhID0KKyAgICAgICAgICAgICAgICAgICAgICAgIHJlY29yZFByb3RvY29sLndyYXAoQ29udGVudFR5cGUuQVBQTElDQVRJT05fREFUQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVN0cmVhbSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChjYXBhY2l0eSA8IHJlbWFpbmluZ193cmFwcGVkX2RhdGEubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIEl0IHNob3VsZCBuZXdlciBoYXBwZW4gYmVjYXVzZSB3ZSBjaGVja2VkIHRoZSBkZXN0aW5hdGlvbgorICAgICAgICAgICAgICAgICAgICAvLyBidWZmZXIgc2l6ZSwgYnV0IHRoZXJlIGlzIGEgcG9zc2liaWxpdHkKKyAgICAgICAgICAgICAgICAgICAgLy8gKGlmIGRlc3QgYnVmZmVyIHdhcyBmaWxsZWQgb3V0c2lkZSkKKyAgICAgICAgICAgICAgICAgICAgLy8gc28gd2UganVzdCByZW1lbWJlciB0aGUgZGF0YSBpbnRvIHJlbWFpbmluZ193cmFwcGVkX2RhdGEKKyAgICAgICAgICAgICAgICAgICAgLy8gYW5kIHdpbGwgZW5jbG9zZSBpdCBkdXJpbmcgdGhlIHRoZSBuZXh0IGNhbGwKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTU0xFbmdpbmVSZXN1bHQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LlN0YXR1cy5CVUZGRVJfT1ZFUkZMT1csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZHNoYWtlU3RhdHVzLCBkYXRhU3RyZWFtLmNvbnN1bWVkKCksIDApOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGRzdC5wdXQocmVtYWluaW5nX3dyYXBwZWRfZGF0YSk7CisgICAgICAgICAgICAgICAgICAgIHByb2R1Y2VkID0gcmVtYWluaW5nX3dyYXBwZWRfZGF0YS5sZW5ndGg7CisgICAgICAgICAgICAgICAgICAgIHJlbWFpbmluZ193cmFwcGVkX2RhdGEgPSBudWxsOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNTTEVuZ2luZVJlc3VsdChnZXRFbmdpbmVTdGF0dXMoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kc2hha2VTdGF0dXMsIGRhdGFTdHJlYW0uY29uc3VtZWQoKSwgcHJvZHVjZWQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKHJlbWFpbmluZ19oc2hfZGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJlbWFpbmluZ19oc2hfZGF0YSA9IGhhbmRzaGFrZVByb3RvY29sLndyYXAoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGNhcGFjaXR5IDwgcmVtYWluaW5nX2hzaF9kYXRhLmxlbmd0aCkgeworICAgICAgICAgICAgICAgICAgICAvLyBJdCBzaG91bGQgbmV3ZXIgaGFwcGVuIGJlY2F1c2Ugd2UgY2hlY2tlZCB0aGUgZGVzdGluYXRpb24KKyAgICAgICAgICAgICAgICAgICAgLy8gYnVmZmVyIHNpemUsIGJ1dCB0aGVyZSBpcyBhIHBvc3NpYmlsaXR5CisgICAgICAgICAgICAgICAgICAgIC8vIChpZiBkZXN0IGJ1ZmZlciB3YXMgZmlsbGVkIG91dHNpZGUpCisgICAgICAgICAgICAgICAgICAgIC8vIHNvIHdlIGp1c3QgcmVtZW1iZXIgdGhlIGRhdGEgaW50byByZW1haW5pbmdfaHNoX2RhdGEKKyAgICAgICAgICAgICAgICAgICAgLy8gYW5kIHdpbGwgZW5jbG9zZSBpdCBkdXJpbmcgdGhlIHRoZSBuZXh0IGNhbGwKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTU0xFbmdpbmVSZXN1bHQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LlN0YXR1cy5CVUZGRVJfT1ZFUkZMT1csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZHNoYWtlU3RhdHVzLCAwLCAwKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBkc3QucHV0KHJlbWFpbmluZ19oc2hfZGF0YSk7CisgICAgICAgICAgICAgICAgICAgIHByb2R1Y2VkID0gcmVtYWluaW5nX2hzaF9kYXRhLmxlbmd0aDsKKyAgICAgICAgICAgICAgICAgICAgcmVtYWluaW5nX2hzaF9kYXRhID0gbnVsbDsKKworICAgICAgICAgICAgICAgICAgICBoYW5kc2hha2VTdGF0dXMgPSBoYW5kc2hha2VQcm90b2NvbC5nZXRTdGF0dXMoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGhhbmRzaGFrZVN0YXR1cy5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cy5GSU5JU0hFRCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24gPSByZWNvcmRQcm90b2NvbC5nZXRTZXNzaW9uKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTU0xFbmdpbmVSZXN1bHQoCisgICAgICAgICAgICAgICAgICAgICAgICBnZXRFbmdpbmVTdGF0dXMoKSwgZ2V0SGFuZHNoYWtlU3RhdHVzKCksIDAsIHByb2R1Y2VkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoQWxlcnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZmF0YWwgYWxlcnQgb2NjdXJlZAorICAgICAgICAgICAgYWxlcnRQcm90b2NvbC5hbGVydChBbGVydFByb3RvY29sLkZBVEFMLCBlLmdldERlc2NyaXB0aW9uQ29kZSgpKTsKKyAgICAgICAgICAgIGVuZ2luZV93YXNfY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgICAgIGlmIChzZXNzaW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXNzaW9uLmludmFsaWRhdGUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIHNodXRkb3duIHdvcmsgd2lsbCBiZSBtYWRlIGFmdGVyIHRoZSBhbGVydCB3aWxsIGJlIHNlbnQKKyAgICAgICAgICAgIC8vIHRvIGFub3RoZXIgcGVlciAoYnkgd3JhcCBtZXRob2QpCisgICAgICAgICAgICB0aHJvdyBlLmdldFJlYXNvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gU2h1dGRvd25lcyB0aGUgZW5naW5lIGFuZCBtYWtlcyBhbGwgY2xlYW51cCB3b3JrLgorICAgIHByaXZhdGUgdm9pZCBzaHV0ZG93bigpIHsKKyAgICAgICAgZW5naW5lX3dhc19jbG9zZWQgPSB0cnVlOworICAgICAgICBlbmdpbmVfd2FzX3NodXR0ZWRkb3duID0gdHJ1ZTsKKyAgICAgICAgaXNPdXRib3VuZERvbmUgPSB0cnVlOworICAgICAgICBpc0luYm91bmREb25lID0gdHJ1ZTsKKyAgICAgICAgaWYgKGhhbmRzaGFrZV9zdGFydGVkKSB7CisgICAgICAgICAgICBhbGVydFByb3RvY29sLnNodXRkb3duKCk7CisgICAgICAgICAgICBhbGVydFByb3RvY29sID0gbnVsbDsKKyAgICAgICAgICAgIGhhbmRzaGFrZVByb3RvY29sLnNodXRkb3duKCk7CisgICAgICAgICAgICBoYW5kc2hha2VQcm90b2NvbCA9IG51bGw7CisgICAgICAgICAgICByZWNvcmRQcm90b2NvbC5zaHV0ZG93bigpOworICAgICAgICAgICAgcmVjb3JkUHJvdG9jb2wgPSBudWxsOworICAgICAgICB9CisgICAgfQorCisKKyAgICBwcml2YXRlIFNTTEVuZ2luZVJlc3VsdC5TdGF0dXMgZ2V0RW5naW5lU3RhdHVzKCkgeworICAgICAgICByZXR1cm4gKGVuZ2luZV93YXNfY2xvc2VkKQorICAgICAgICAgICAgPyBTU0xFbmdpbmVSZXN1bHQuU3RhdHVzLkNMT1NFRAorICAgICAgICAgICAgOiBTU0xFbmdpbmVSZXN1bHQuU3RhdHVzLk9LOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTElucHV0U3RyZWFtLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJhNmM1ZDYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMTEzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyBhIGJhc2UgZm9yIGFsbCBpbnB1dCBzdHJlYW0gY2xhc3NlcyB1c2VkCisgKiBpbiBwcm90b2NvbCBpbXBsZW1lbnRhdGlvbi4gSXQgZXh0ZW5kcyBhbiBJbnB1dFN0cmVhbSB3aXRoCisgKiBzb21lIGFkZGl0aW9uYWwgcmVhZCBtZXRob2RzIGFsbG93aW5nIHRvIHJlYWQgVExTIHNwZWNpZmljCisgKiBkYXRhIHR5cGVzIHN1Y2ggYXMgdWludDgsIHVpbnQzMiBldGMgKHNlZSBUTFMgdiAxIHNwZWNpZmljYXRpb24KKyAqIGF0IGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyNDYudHh0KS4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFNTTElucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGFic3RyYWN0IGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB0aGUgZm9sbG93aW5nIGJ5dGUgdmFsdWUuIE5vdGUgdGhhdCBpbiB0aGUgY2FzZSBvZgorICAgICAqIHJlYWNoaW5nIG9mIHRoZSBlbmQgb2YgdGhlIGRhdGEgdGhpcyBtZXRob2RzIHRocm93cyB0aGUKKyAgICAgKiBleGNlcHRpb24sIG5vdCByZXR1cm4gLTEuIFRoZSB0eXBlIG9mIGV4Y2VwdGlvbiBkZXBlbmRzCisgICAgICogb24gaW1wbGVtZW50YXRpb24uIEl0IHdhcyBkb25lIGZvciBzaW1wbGlmeWluZyBhbmQgc3BlZWRpbmcKKyAgICAgKiB1cCBvZiBwcm9jZXNzaW5nIG9mIHN1Y2ggY2FzZXMuCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlLlNTTFN0cmVhbWVkSW5wdXQjcmVhZCgpCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlLlNTTEJ1ZmZlcmVkSW5wdXQjcmVhZCgpCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlLkhhbmRzaGFrZUlPRGF0YVN0cmVhbSNyZWFkKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhbmQgcmV0dXJucyB1aW50OCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHJlYWRVaW50OCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByZWFkKCkgJiAweDAwRkY7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYW5kIHJldHVybnMgdWludDE2IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgcmVhZFVpbnQxNigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiAocmVhZCgpIDw8IDgpIHwgKHJlYWQoKSAmIDB4MDBGRik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgYW5kIHJldHVybnMgdWludDI0IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgcmVhZFVpbnQyNCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiAocmVhZCgpIDw8IDE2KSB8IChyZWFkKCkgPDwgOCkgfCAocmVhZCgpICYgMHgwMEZGKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhbmQgcmV0dXJucyB1aW50MzIgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIGxvbmcgcmVhZFVpbnQzMigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiAocmVhZCgpIDw8IDI0KSB8IChyZWFkKCkgPDwgMTYpCisgICAgICAgICAgICAgIHwgKHJlYWQoKSA8PCA4KSB8IChyZWFkKCkgJiAweDAwRkYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGFuZCByZXR1cm5zIHVpbnQ2NCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyByZWFkVWludDY0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgbG9uZyBoaSA9IHJlYWRVaW50MzIoKTsKKyAgICAgICAgbG9uZyBsbyA9IHJlYWRVaW50MzIoKTsKKyAgICAgICAgcmV0dXJuIChoaSA8PCAzMikgfCBsbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2ZWN0b3Igb2Ygb3BhcXVlIHZhbHVlcyBvZiBzcGVjaWZpZWQgbGVuZ3RoOworICAgICAqIEBwYXJhbSBsZW5ndGggLSB0aGUgbGVuZ3RoIG9mIHRoZSB2ZWN0b3IgdG8gYmUgcmVhZC4KKyAgICAgKiBAcmV0dXJuIHRoZSByZWFkIGRhdGEKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHJlYWQgb3BlcmF0aW9uIGNvdWxkIG5vdCBiZSBmaW5pc2hlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIHJlYWQoaW50IGxlbmd0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIHJlcyA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgICAgIGZvciAoaW50IGk9MDsgaTxsZW5ndGg7IGkrKykgeworICAgICAgICAgICAgcmVzW2ldID0gKGJ5dGUpIHJlYWQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHJlYWRfYjsKKyAgICAgICAgaW50IGkgPSAwOworICAgICAgICBkbyB7CisgICAgICAgICAgICBpZiAoKHJlYWRfYiA9IHJlYWQoKSkgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gKGkgPT0gMCkgPyAtMSA6IGk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBiW29mZitpXSA9IChieXRlKSByZWFkX2I7CisgICAgICAgICAgICBpKys7CisgICAgICAgIH0gd2hpbGUgKChhdmFpbGFibGUoKSAhPSAwKSAmJiAoaTxsZW4pKTsKKyAgICAgICAgcmV0dXJuIGk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMUGFyYW1ldGVyc0ltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTFBhcmFtZXRlcnNJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTE3NDkyZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTFBhcmFtZXRlcnNJbXBsLmphdmEKQEAgLTAsMCArMSw0MjQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2UuVHJ1c3RNYW5hZ2VySW1wbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleU1hbmFnZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEuc2VjdXJpdHkuVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleU1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyRmFjdG9yeTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlckZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5YNTA5S2V5TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlg1MDlUcnVzdE1hbmFnZXI7CisKKy8qKgorICogVGhlIGluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIGVuY2Fwc3VsYXRlIGFsbCB0aGUgaW5mbworICogYWJvdXQgZW5hYmxlZCBjaXBoZXIgc3VpdGVzIGFuZCBwcm90b2NvbHMsCisgKiBhcyB3ZWxsIGFzIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBjbGllbnQvc2VydmVyIG1vZGUgb2YKKyAqIHNzbCBzb2NrZXQsIHdoZXRoZXIgaXQgcmVxdWlyZS93YW50IGNsaWVudCBhdXRoZW50aWNhdGlvbiBvciBub3QsCisgKiBhbmQgY29udHJvbHMgd2hldGhlciBuZXcgU1NMIHNlc3Npb25zIG1heSBiZSBlc3RhYmxpc2hlZCBieSB0aGlzCisgKiBzb2NrZXQgb3Igbm90LgorICovCitwdWJsaWMgY2xhc3MgU1NMUGFyYW1ldGVyc0ltcGwgaW1wbGVtZW50cyBDbG9uZWFibGUgeworCisgICAgLy8gZGVmYXVsdCBzb3VyY2Ugb2YgYXV0aGVudGljYXRpb24ga2V5cworICAgIHByaXZhdGUgc3RhdGljIHZvbGF0aWxlIFg1MDlLZXlNYW5hZ2VyIGRlZmF1bHRLZXlNYW5hZ2VyOworICAgIC8vIGRlZmF1bHQgc291cmNlIG9mIGF1dGhlbnRpY2F0aW9uIHRydXN0IGRlY2lzaW9ucworICAgIHByaXZhdGUgc3RhdGljIHZvbGF0aWxlIFg1MDlUcnVzdE1hbmFnZXIgZGVmYXVsdFRydXN0TWFuYWdlcjsKKyAgICAvLyBkZWZhdWx0IHNvdXJjZSBvZiByYW5kb20gbnVtYmVycworICAgIHByaXZhdGUgc3RhdGljIHZvbGF0aWxlIFNlY3VyZVJhbmRvbSBkZWZhdWx0U2VjdXJlUmFuZG9tOworICAgIC8vIGRlZmF1bHQgU1NMIHBhcmFtZXRlcnMKKyAgICBwcml2YXRlIHN0YXRpYyB2b2xhdGlsZSBTU0xQYXJhbWV0ZXJzSW1wbCBkZWZhdWx0UGFyYW1ldGVyczsKKworICAgIC8vIGNsaWVudCBzZXNzaW9uIGNvbnRleHQgY29udGFpbnMgdGhlIHNldCBvZiByZXVzYWJsZQorICAgIC8vIGNsaWVudC1zaWRlIFNTTCBzZXNzaW9ucworICAgIHByaXZhdGUgZmluYWwgQ2xpZW50U2Vzc2lvbkNvbnRleHQgY2xpZW50U2Vzc2lvbkNvbnRleHQ7CisgICAgLy8gc2VydmVyIHNlc3Npb24gY29udGV4dCBjb250YWlucyB0aGUgc2V0IG9mIHJldXNhYmxlCisgICAgLy8gc2VydmVyLXNpZGUgU1NMIHNlc3Npb25zCisgICAgcHJpdmF0ZSBmaW5hbCBTZXJ2ZXJTZXNzaW9uQ29udGV4dCBzZXJ2ZXJTZXNzaW9uQ29udGV4dDsKKyAgICAvLyBzb3VyY2Ugb2YgYXV0aGVudGljYXRpb24ga2V5cworICAgIHByaXZhdGUgWDUwOUtleU1hbmFnZXIga2V5TWFuYWdlcjsKKyAgICAvLyBzb3VyY2Ugb2YgYXV0aGVudGljYXRpb24gdHJ1c3QgZGVjaXNpb25zCisgICAgcHJpdmF0ZSBYNTA5VHJ1c3RNYW5hZ2VyIHRydXN0TWFuYWdlcjsKKyAgICAvLyBzb3VyY2Ugb2YgcmFuZG9tIG51bWJlcnMKKyAgICBwcml2YXRlIFNlY3VyZVJhbmRvbSBzZWN1cmVSYW5kb207CisKKyAgICAvLyBjaXBoZXIgc3VpdGVzIGF2YWlsYWJsZSBmb3IgU1NMIGNvbm5lY3Rpb24KKyAgICBwcml2YXRlIENpcGhlclN1aXRlW10gZW5hYmxlZENpcGhlclN1aXRlczsKKyAgICAvLyBzdHJpbmcgcmVwcmVzZW50YXRpb25zIG9mIGF2YWlsYWJsZSBjaXBoZXIgc3VpdGVzCisgICAgcHJpdmF0ZSBTdHJpbmdbXSBlbmFibGVkQ2lwaGVyU3VpdGVOYW1lcyA9IG51bGw7CisKKyAgICAvLyBwcm90b2NvbHMgYXZhaWxhYmxlIGZvciBTU0wgY29ubmVjdGlvbgorICAgIHByaXZhdGUgU3RyaW5nW10gZW5hYmxlZFByb3RvY29scyA9IFByb3RvY29sVmVyc2lvbi5zdXBwb3J0ZWRQcm90b2NvbHM7CisKKyAgICAvLyBpZiB0aGUgcGVlciB3aXRoIHRoaXMgcGFyYW1ldGVycyB0dW5lZCB0byB3b3JrIGluIGNsaWVudCBtb2RlCisgICAgcHJpdmF0ZSBib29sZWFuIGNsaWVudF9tb2RlID0gdHJ1ZTsKKyAgICAvLyBpZiB0aGUgcGVlciB3aXRoIHRoaXMgcGFyYW1ldGVycyB0dW5lZCB0byByZXF1aXJlIGNsaWVudCBhdXRoZW50aWNhdGlvbgorICAgIHByaXZhdGUgYm9vbGVhbiBuZWVkX2NsaWVudF9hdXRoID0gZmFsc2U7CisgICAgLy8gaWYgdGhlIHBlZXIgd2l0aCB0aGlzIHBhcmFtZXRlcnMgdHVuZWQgdG8gcmVxdWVzdCBjbGllbnQgYXV0aGVudGljYXRpb24KKyAgICBwcml2YXRlIGJvb2xlYW4gd2FudF9jbGllbnRfYXV0aCA9IGZhbHNlOworICAgIC8vIGlmIHRoZSBwZWVyIHdpdGggdGhpcyBwYXJhbWV0ZXJzIGFsbG93ZWQgdG8gY3RlYXRlIG5ldyBTU0wgc2Vzc2lvbgorICAgIHByaXZhdGUgYm9vbGVhbiBlbmFibGVfc2Vzc2lvbl9jcmVhdGlvbiA9IHRydWU7CisKKyAgICBwcm90ZWN0ZWQgQ2lwaGVyU3VpdGVbXSBnZXRFbmFibGVkQ2lwaGVyU3VpdGVzTWVtYmVyKCkgeworICAgICAgICBpZiAoZW5hYmxlZENpcGhlclN1aXRlcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aGlzLmVuYWJsZWRDaXBoZXJTdWl0ZXMgPSBDaXBoZXJTdWl0ZS5ERUZBVUxUX0NJUEhFUl9TVUlURVM7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVuYWJsZWRDaXBoZXJTdWl0ZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgdGhlIHBhcmFtZXRlcnMuIE5hdHVyYWxseSB0aGlzIGNvbnN0cnVjdG9yIGlzIHVzZWQKKyAgICAgKiBpbiBTU0xDb250ZXh0SW1wbC5lbmdpbmVJbml0IG1ldGhvZCB3aGljaCBkaXJlY3RseSBwYXNzZXMgaXRzCisgICAgICogcGFyYW1ldGVycy4gSW4gb3RoZXIgd29yZHMgdGhpcyBjb25zdHJ1Y3RvciBob2xkcyBhbGwKKyAgICAgKiB0aGUgZnVuY3Rpb25hbGl0eSBwcm92aWRlZCBieSBTU0xDb250ZXh0LmluaXQgbWV0aG9kLgorICAgICAqIFNlZSB7QGxpbmsgamF2YXgubmV0LnNzbC5TU0xDb250ZXh0I2luaXQoS2V5TWFuYWdlcltdLFRydXN0TWFuYWdlcltdLAorICAgICAqIFNlY3VyZVJhbmRvbSl9IGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgcHJvdGVjdGVkIFNTTFBhcmFtZXRlcnNJbXBsKEtleU1hbmFnZXJbXSBrbXMsIFRydXN0TWFuYWdlcltdIHRtcywKKyAgICAgICAgICAgIFNlY3VyZVJhbmRvbSBzciwgQ2xpZW50U2Vzc2lvbkNvbnRleHQgY2xpZW50U2Vzc2lvbkNvbnRleHQsCisgICAgICAgICAgICBTZXJ2ZXJTZXNzaW9uQ29udGV4dCBzZXJ2ZXJTZXNzaW9uQ29udGV4dCkKKyAgICAgICAgICAgIHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5zZXJ2ZXJTZXNzaW9uQ29udGV4dCA9IHNlcnZlclNlc3Npb25Db250ZXh0OworICAgICAgICB0aGlzLmNsaWVudFNlc3Npb25Db250ZXh0ID0gY2xpZW50U2Vzc2lvbkNvbnRleHQ7CisKKyAgICAgICAgLy8gSXQncyBub3QgZGVzY3JpYmVkIGJ5IHRoZSBzcGVjIG9mIFNTTENvbnRleHQgd2hhdCBzaG91bGQgaGFwcGVuCisgICAgICAgIC8vIGlmIHRoZSBhcnJheXMgb2YgbGVuZ3RoIDAgYXJlIHNwZWNpZmllZC4gVGhpcyBpbXBsZW1lbnRhdGlvbgorICAgICAgICAvLyBiZWhhdmUgYXMgZm9yIG51bGwgYXJyYXlzIChpLmUuIHVzZSBpbnN0YWxsZWQgc2VjdXJpdHkgcHJvdmlkZXJzKQorCisgICAgICAgIC8vIGluaXRpYWxpemUga2V5TWFuYWdlcgorICAgICAgICBpZiAoKGttcyA9PSBudWxsKSB8fCAoa21zLmxlbmd0aCA9PSAwKSkgeworICAgICAgICAgICAga2V5TWFuYWdlciA9IGdldERlZmF1bHRLZXlNYW5hZ2VyKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBrZXlNYW5hZ2VyID0gZmluZFg1MDlLZXlNYW5hZ2VyKGttcyk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGtleU1hbmFnZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEtleU1hbmFnZW1lbnRFeGNlcHRpb24oIk5vIFg1MDlLZXlNYW5hZ2VyIGZvdW5kIik7CisgICAgICAgIH0KKworICAgICAgICAvLyBpbml0aWFsaXplIHRydXN0TWFuYWdlcgorICAgICAgICBpZiAoKHRtcyA9PSBudWxsKSB8fCAodG1zLmxlbmd0aCA9PSAwKSkgeworICAgICAgICAgICAgdHJ1c3RNYW5hZ2VyID0gZ2V0RGVmYXVsdFRydXN0TWFuYWdlcigpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdHJ1c3RNYW5hZ2VyID0gZmluZFg1MDlUcnVzdE1hbmFnZXIodG1zKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodHJ1c3RNYW5hZ2VyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uKCJObyBYNTA5VHJ1c3RNYW5hZ2VyIGZvdW5kIik7CisgICAgICAgIH0KKyAgICAgICAgLy8gaW5pdGlhbGl6ZSBzZWN1cmUgcmFuZG9tCisgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtcmVtb3ZlZAorICAgICAgICAvLyBpZiAoc3IgPT0gbnVsbCkgeworICAgICAgICAvLyAgICAgaWYgKGRlZmF1bHRTZWN1cmVSYW5kb20gPT0gbnVsbCkgeworICAgICAgICAvLyAgICAgICAgIGRlZmF1bHRTZWN1cmVSYW5kb20gPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIC8vICAgICB9CisgICAgICAgIC8vICAgICBzZWN1cmVSYW5kb20gPSBkZWZhdWx0U2VjdXJlUmFuZG9tOworICAgICAgICAvLyB9IGVsc2UgeworICAgICAgICAvLyAgICAgc2VjdXJlUmFuZG9tID0gc3I7CisgICAgICAgIC8vIH0KKyAgICAgICAgLy8gRU5EIGFuZHJvaWQtcmVtb3ZlZAorICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLWFkZGVkCisgICAgICAgIC8vIFdlIHNpbXBseSB1c2UgdGhlIFNlY3VyZVJhbmRvbSBwYXNzZWQgaW4gYnkgdGhlIGNhbGxlci4gSWYgaXQncworICAgICAgICAvLyBudWxsLCB3ZSBkb24ndCByZXBsYWNlIGl0IGJ5IGEgbmV3IGluc3RhbmNlLiBUaGUgbmF0aXZlIGNvZGUgYmVsb3cKKyAgICAgICAgLy8gdGhlbiBkaXJlY3RseSBhY2Nlc3NlcyAvZGV2L3VyYW5kb20uIE5vdCB0aGUgbW9zdCBlbGVnYW50IHNvbHV0aW9uLAorICAgICAgICAvLyBidXQgZmFzdGVyIHRoYW4gZ29pbmcgdGhyb3VnaCB0aGUgU2VjdXJlUmFuZG9tIG9iamVjdC4KKyAgICAgICAgc2VjdXJlUmFuZG9tID0gc3I7CisgICAgICAgIC8vIEVORCBhbmRyb2lkLWFkZGVkCisgICAgfQorCisgICAgcHJvdGVjdGVkIHN0YXRpYyBTU0xQYXJhbWV0ZXJzSW1wbCBnZXREZWZhdWx0KCkgdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24geworICAgICAgICBTU0xQYXJhbWV0ZXJzSW1wbCByZXN1bHQgPSBkZWZhdWx0UGFyYW1ldGVyczsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBzaW5nbGUtY2hlY2sgaWRpb20KKyAgICAgICAgICAgIGRlZmF1bHRQYXJhbWV0ZXJzID0gcmVzdWx0ID0gbmV3IFNTTFBhcmFtZXRlcnNJbXBsKG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDbGllbnRTZXNzaW9uQ29udGV4dCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFNlcnZlclNlc3Npb25Db250ZXh0KCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoU1NMUGFyYW1ldGVyc0ltcGwpIHJlc3VsdC5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gc2VydmVyIHNlc3Npb24gY29udGV4dAorICAgICAqLworICAgIHByb3RlY3RlZCBTZXJ2ZXJTZXNzaW9uQ29udGV4dCBnZXRTZXJ2ZXJTZXNzaW9uQ29udGV4dCgpIHsKKyAgICAgICAgcmV0dXJuIHNlcnZlclNlc3Npb25Db250ZXh0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gY2xpZW50IHNlc3Npb24gY29udGV4dAorICAgICAqLworICAgIHByb3RlY3RlZCBDbGllbnRTZXNzaW9uQ29udGV4dCBnZXRDbGllbnRTZXNzaW9uQ29udGV4dCgpIHsKKyAgICAgICAgcmV0dXJuIGNsaWVudFNlc3Npb25Db250ZXh0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4ga2V5IG1hbmFnZXIKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgWDUwOUtleU1hbmFnZXIgZ2V0S2V5TWFuYWdlcigpIHsKKyAgICAgICAgcmV0dXJuIGtleU1hbmFnZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiB0cnVzdCBtYW5hZ2VyCisgICAgICovCisgICAgcHJvdGVjdGVkIFg1MDlUcnVzdE1hbmFnZXIgZ2V0VHJ1c3RNYW5hZ2VyKCkgeworICAgICAgICByZXR1cm4gdHJ1c3RNYW5hZ2VyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gc2VjdXJlIHJhbmRvbQorICAgICAqLworICAgIHByb3RlY3RlZCBTZWN1cmVSYW5kb20gZ2V0U2VjdXJlUmFuZG9tKCkgeworICAgICAgICBpZiAoc2VjdXJlUmFuZG9tICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBzZWN1cmVSYW5kb207CisgICAgICAgIH0KKyAgICAgICAgU2VjdXJlUmFuZG9tIHJlc3VsdCA9IGRlZmF1bHRTZWN1cmVSYW5kb207CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gc2luZ2xlLWNoZWNrIGlkaW9tCisgICAgICAgICAgICBkZWZhdWx0U2VjdXJlUmFuZG9tID0gcmVzdWx0ID0gbmV3IFNlY3VyZVJhbmRvbSgpOworICAgICAgICB9CisgICAgICAgIHNlY3VyZVJhbmRvbSA9IHJlc3VsdDsKKyAgICAgICAgcmV0dXJuIHNlY3VyZVJhbmRvbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIHRoZSBzZWN1cmUgcmFuZG9tIG1lbWJlciByZWZlcmVuY2UsIGV2ZW4gaXQgaXMgbnVsbAorICAgICAqLworICAgIHByb3RlY3RlZCBTZWN1cmVSYW5kb20gZ2V0U2VjdXJlUmFuZG9tTWVtYmVyKCkgeworICAgICAgICByZXR1cm4gc2VjdXJlUmFuZG9tOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWVzIG9mIGVuYWJsZWQgY2lwaGVyIHN1aXRlcworICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmdbXSBnZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCkgeworICAgICAgICBpZiAoZW5hYmxlZENpcGhlclN1aXRlTmFtZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgQ2lwaGVyU3VpdGVbXSBlbmFibGVkQ2lwaGVyU3VpdGVzID0gZ2V0RW5hYmxlZENpcGhlclN1aXRlc01lbWJlcigpOworICAgICAgICAgICAgZW5hYmxlZENpcGhlclN1aXRlTmFtZXMgPSBuZXcgU3RyaW5nW2VuYWJsZWRDaXBoZXJTdWl0ZXMubGVuZ3RoXTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpPCBlbmFibGVkQ2lwaGVyU3VpdGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgZW5hYmxlZENpcGhlclN1aXRlTmFtZXNbaV0gPSBlbmFibGVkQ2lwaGVyU3VpdGVzW2ldLmdldE5hbWUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW5hYmxlZENpcGhlclN1aXRlTmFtZXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzZXQgb2YgYXZhaWxhYmxlIGNpcGhlciBzdWl0ZXMgZm9yIHVzZSBpbiBTU0wgY29ubmVjdGlvbi4KKyAgICAgKiBAcGFyYW0gICBzdWl0ZXM6IFN0cmluZ1tdCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoU3RyaW5nW10gc3VpdGVzKSB7CisgICAgICAgIGlmIChzdWl0ZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigic3VpdGVzID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBDaXBoZXJTdWl0ZVtdIGNpcGhlclN1aXRlcyA9IG5ldyBDaXBoZXJTdWl0ZVtzdWl0ZXMubGVuZ3RoXTsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPHN1aXRlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIHN1aXRlID0gc3VpdGVzW2ldOworICAgICAgICAgICAgaWYgKHN1aXRlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzdWl0ZXNbIiArIGkgKyAiXSA9PSBudWxsIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjaXBoZXJTdWl0ZXNbaV0gPSBDaXBoZXJTdWl0ZS5nZXRCeU5hbWUoc3VpdGUpOworICAgICAgICAgICAgaWYgKGNpcGhlclN1aXRlc1tpXSA9PSBudWxsIHx8ICFjaXBoZXJTdWl0ZXNbaV0uc3VwcG9ydGVkKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihzdWl0ZSArICIgaXMgbm90IHN1cHBvcnRlZC4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBlbmFibGVkQ2lwaGVyU3VpdGVzID0gY2lwaGVyU3VpdGVzOworICAgICAgICBlbmFibGVkQ2lwaGVyU3VpdGVOYW1lcyA9IHN1aXRlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIHRoZSBzZXQgb2YgZW5hYmxlZCBwcm90b2NvbHMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nW10gZ2V0RW5hYmxlZFByb3RvY29scygpIHsKKyAgICAgICAgcmV0dXJuIGVuYWJsZWRQcm90b2NvbHMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzZXQgb2YgYXZhaWxhYmxlIHByb3RvY29scyBmb3IgdXNlIGluIFNTTCBjb25uZWN0aW9uLgorICAgICAqIEBwYXJhbSBwcm90b2NvbHMgU3RyaW5nW10KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRFbmFibGVkUHJvdG9jb2xzKFN0cmluZ1tdIHByb3RvY29scykgeworICAgICAgICBpZiAocHJvdG9jb2xzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInByb3RvY29scyA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPHByb3RvY29scy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIHByb3RvY29sID0gcHJvdG9jb2xzW2ldOworICAgICAgICAgICAgaWYgKHByb3RvY29sID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJwcm90b2NvbHNbIiArIGkgKyAiXSA9PSBudWxsIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIVByb3RvY29sVmVyc2lvbi5pc1N1cHBvcnRlZChwcm90b2NvbCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQcm90b2NvbCAiICsgcHJvdG9jb2wgKyAiIGlzIG5vdCBzdXBwb3J0ZWQuIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZW5hYmxlZFByb3RvY29scyA9IHByb3RvY29sczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUdW5lcyB0aGUgcGVlciBob2xkaW5nIHRoaXMgcGFyYW1ldGVycyB0byB3b3JrIGluIGNsaWVudCBtb2RlLgorICAgICAqIEBwYXJhbSAgIG1vZGUgaWYgdGhlIHBlZXIgaXMgY29uZmlndXJlZCB0byB3b3JrIGluIGNsaWVudCBtb2RlCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXNlQ2xpZW50TW9kZShib29sZWFuIG1vZGUpIHsKKyAgICAgICAgY2xpZW50X21vZGUgPSBtb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIGluZGljYXRpbmcgaWYgdGhlIHBhcmFtZXRlcnMgY29uZmlndXJlZCB0byB3b3JrCisgICAgICogaW4gY2xpZW50IG1vZGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gZ2V0VXNlQ2xpZW50TW9kZSgpIHsKKyAgICAgICAgcmV0dXJuIGNsaWVudF9tb2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFR1bmVzIHRoZSBwZWVyIGhvbGRpbmcgdGhpcyBwYXJhbWV0ZXJzIHRvIHJlcXVpcmUgY2xpZW50IGF1dGhlbnRpY2F0aW9uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0TmVlZENsaWVudEF1dGgoYm9vbGVhbiBuZWVkKSB7CisgICAgICAgIG5lZWRfY2xpZW50X2F1dGggPSBuZWVkOworICAgICAgICAvLyByZXNldCB0aGUgd2FudF9jbGllbnRfYXV0aCBzZXR0aW5nCisgICAgICAgIHdhbnRfY2xpZW50X2F1dGggPSBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBpbmRpY2F0aW5nIGlmIHRoZSBwZWVyIHdpdGggdGhpcyBwYXJhbWV0ZXJzIHR1bmVkCisgICAgICogdG8gcmVxdWlyZSBjbGllbnQgYXV0aGVudGljYXRpb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBnZXROZWVkQ2xpZW50QXV0aCgpIHsKKyAgICAgICAgcmV0dXJuIG5lZWRfY2xpZW50X2F1dGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHVuZXMgdGhlIHBlZXIgaG9sZGluZyB0aGlzIHBhcmFtZXRlcnMgdG8gcmVxdWVzdCBjbGllbnQgYXV0aGVudGljYXRpb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRXYW50Q2xpZW50QXV0aChib29sZWFuIHdhbnQpIHsKKyAgICAgICAgd2FudF9jbGllbnRfYXV0aCA9IHdhbnQ7CisgICAgICAgIC8vIHJlc2V0IHRoZSBuZWVkX2NsaWVudF9hdXRoIHNldHRpbmcKKyAgICAgICAgbmVlZF9jbGllbnRfYXV0aCA9IGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIGluZGljYXRpbmcgaWYgdGhlIHBlZXIgd2l0aCB0aGlzIHBhcmFtZXRlcnMKKyAgICAgKiB0dW5lZCB0byByZXF1ZXN0IGNsaWVudCBhdXRoZW50aWNhdGlvbgorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBnZXRXYW50Q2xpZW50QXV0aCgpIHsKKyAgICAgICAgcmV0dXJuIHdhbnRfY2xpZW50X2F1dGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWxsb3dzL2Rpc2FsbG93cyB0aGUgcGVlciBob2xkaW5nIHRoaXMgcGFyYW1ldGVycyB0bworICAgICAqIGNyZWF0ZSBuZXcgU1NMIHNlc3Npb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oYm9vbGVhbiBmbGFnKSB7CisgICAgICAgIGVuYWJsZV9zZXNzaW9uX2NyZWF0aW9uID0gZmxhZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBpbmRpY2F0aW5nIGlmIHRoZSBwZWVyIHdpdGggdGhpcyBwYXJhbWV0ZXJzCisgICAgICogYWxsb3dlZCB0byBjdGVhdGUgbmV3IFNTTCBzZXNzaW9uCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCkgeworICAgICAgICByZXR1cm4gZW5hYmxlX3Nlc3Npb25fY3JlYXRpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2xvbmUgb2YgdGhpcyBvYmplY3QuCisgICAgICogQHJldHVybiB0aGUgY2xvbmUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBYNTA5S2V5TWFuYWdlciBnZXREZWZhdWx0S2V5TWFuYWdlcigpIHsKKyAgICAgICAgWDUwOUtleU1hbmFnZXIgcmVzdWx0ID0gZGVmYXVsdEtleU1hbmFnZXI7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gc2luZ2xlLWNoZWNrIGlkaW9tCisgICAgICAgICAgICBkZWZhdWx0S2V5TWFuYWdlciA9IHJlc3VsdCA9IGNyZWF0ZURlZmF1bHRLZXlNYW5hZ2VyKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisgICAgcHJpdmF0ZSBzdGF0aWMgWDUwOUtleU1hbmFnZXIgY3JlYXRlRGVmYXVsdEtleU1hbmFnZXIoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgYWxnb3JpdGhtID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0RGVmYXVsdEFsZ29yaXRobSgpOworICAgICAgICAgICAgS2V5TWFuYWdlckZhY3Rvcnkga21mID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtKTsKKyAgICAgICAgICAgIGttZi5pbml0KG51bGwsIG51bGwpOworICAgICAgICAgICAgS2V5TWFuYWdlcltdIGttcyA9IGttZi5nZXRLZXlNYW5hZ2VycygpOworICAgICAgICAgICAgcmV0dXJuIGZpbmRYNTA5S2V5TWFuYWdlcihrbXMpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGNhdGNoIChVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIFg1MDlLZXlNYW5hZ2VyIGZpbmRYNTA5S2V5TWFuYWdlcihLZXlNYW5hZ2VyW10ga21zKSB7CisgICAgICAgIGZvciAoS2V5TWFuYWdlciBrbSA6IGttcykgeworICAgICAgICAgICAgaWYgKGttIGluc3RhbmNlb2YgWDUwOUtleU1hbmFnZXIpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gKFg1MDlLZXlNYW5hZ2VyKWttOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHJ1c3QgbWFuYWdlci4KKyAgICAgKgorICAgICAqIFRPRE86IE1vdmUgdGhpcyB0byBhIHB1Ymxpc2hlZCBBUEkgdW5kZXIgZGFsdmlrLnN5c3RlbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFg1MDlUcnVzdE1hbmFnZXIgZ2V0RGVmYXVsdFRydXN0TWFuYWdlcigpIHsKKyAgICAgICAgWDUwOVRydXN0TWFuYWdlciByZXN1bHQgPSBkZWZhdWx0VHJ1c3RNYW5hZ2VyOworICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIHNpbmdsZS1jaGVjayBpZGlvbQorICAgICAgICAgICAgZGVmYXVsdFRydXN0TWFuYWdlciA9IHJlc3VsdCA9IGNyZWF0ZURlZmF1bHRUcnVzdE1hbmFnZXIoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBYNTA5VHJ1c3RNYW5hZ2VyIGNyZWF0ZURlZmF1bHRUcnVzdE1hbmFnZXIoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgYWxnb3JpdGhtID0gVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXREZWZhdWx0QWxnb3JpdGhtKCk7CisgICAgICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5IHRtZiA9IFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtKTsKKyAgICAgICAgICAgIHRtZi5pbml0KChLZXlTdG9yZSkgbnVsbCk7CisgICAgICAgICAgICBUcnVzdE1hbmFnZXJbXSB0bXMgPSB0bWYuZ2V0VHJ1c3RNYW5hZ2VycygpOworICAgICAgICAgICAgWDUwOVRydXN0TWFuYWdlciB0cnVzdE1hbmFnZXIgPSBmaW5kWDUwOVRydXN0TWFuYWdlcih0bXMpOworICAgICAgICAgICAgcmV0dXJuIHRydXN0TWFuYWdlcjsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBYNTA5VHJ1c3RNYW5hZ2VyIGZpbmRYNTA5VHJ1c3RNYW5hZ2VyKFRydXN0TWFuYWdlcltdIHRtcykgeworICAgICAgICBmb3IgKFRydXN0TWFuYWdlciB0bSA6IHRtcykgeworICAgICAgICAgICAgaWYgKHRtIGluc3RhbmNlb2YgWDUwOVRydXN0TWFuYWdlcikgeworICAgICAgICAgICAgICAgIHJldHVybiAoWDUwOVRydXN0TWFuYWdlcil0bTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xSZWNvcmRQcm90b2NvbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMUmVjb3JkUHJvdG9jb2wuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYmVjN2QxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMUmVjb3JkUHJvdG9jb2wuamF2YQpAQCAtMCwwICsxLDQ3NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFByb3RvY29sRXhjZXB0aW9uOworCisvKioKKyAqIFRoaXMgY2xhc3MgcGVyZm9ybXMgZnVuY3Rpb25hbGl0eSBkZWRpY2F0ZWQgdG8gU1NMIHJlY29yZCBsYXllci4KKyAqIEl0IHVucGFja3MgYW5kIHJvdXRlcyBpbmNvbWUgZGF0YSB0byB0aGUgYXBwcm9wcmlhdGUKKyAqIGNsaWVudCBwcm90b2NvbCAoaGFuZHNoYWtlLCBhbGVydCwgYXBwbGljYXRpb24gZGF0YSBwcm90b2NvbHMpCisgKiBhbmQgcGFja2FnZXMgb3V0Y29tZSBkYXRhIGludG8gU1NML1RMUyByZWNvcmRzLgorICogSW5pdGlhbGx5IGNyZWF0ZWQgb2JqZWN0IGhhcyBudWxsIGNvbm5lY3Rpb24gc3RhdGUgYW5kIGRvZXMgbm90CisgKiBwZXJmb3JtIGFueSBjcnlwdG9ncmFwaHkgY29tcHV0YXRpb25zIG92ZXIgdGhlIGluY29tZS9vdXRjb21lIGRhdGEuCisgKiBBZnRlciBoYW5kc2hha2UgcHJvdG9jb2wgYWdyZWVkIHVwb24gc2VjdXJpdHkgcGFyYW1ldGVycyB0aGV5IGFyZSBwbGFjZWQKKyAqIGludG8gU1NMU2Vzc2lvbkltcGwgb2JqZWN0IGFuZCBhdmFpbGFibGUgZm9yIHJlY29yZCBwcm90b2NvbCBhcworICogcGVuZGluZyBzZXNzaW9uLiBUaGUgb3JkZXIgb2Ygc2V0dGluZyB1cCBvZiB0aGUgcGVuZGluZyBzZXNzaW9uCisgKiBhcyBhbiBhY3RpdmUgc2Vzc2lvbiBkaWZmZXJzIGZvciBjbGllbnQgYW5kIHNlcnZlciBtb2Rlcy4KKyAqIFNvIGZvciBjbGllbnQgbW9kZSB0aGUgcGFyYW1ldGVycyBhcmUgcHJvdmlkZWQgYnkgaGFuZHNoYWtlIHByb3RvY29sCisgKiBkdXJpbmcgcmV0cmlldmluZyBvZiBjaGFuZ2VfY2lwaGVyX3NwZWMgbWVzc2FnZSB0byBiZSBzZW50IChieSBjYWxsaW5nIG9mCisgKiBnZXRDaGFuZ2VDaXBoZXJTcGVjTWVzYWdlIG1ldGhvZCkuCisgKiBGb3Igc2VydmVyIHNpZGUgbW9kZSByZWNvcmQgcHJvdG9jb2wgcmV0cmlldmVzIHRoZSBwYXJhbWV0ZXJzIGZyb20KKyAqIGhhbmRzaGFrZSBwcm90b2NvbCBhZnRlciByZWNlaXZpbmcgb2YgY2xpZW50J3MgY2hhbmdlX2NpcGhlcl9zcGVjIG1lc3NhZ2UuCisgKiBBZnRlciB0aGUgcGVuZGluZyBzZXNzaW9uIGhhcyBiZWVuIHNldCB1cCBhcyBhIGN1cnJlbnQgc2Vzc2lvbiwKKyAqIG5ldyBjb25uZWN0aW9uIHN0YXRlIG9iamVjdCBpcyBjcmVhdGVkIGFuZCB1c2VkIGZvciBlbmNyeXB0aW9uL2RlY3J5cHRpb24KKyAqIG9mIHRoZSBtZXNzYWdlcy4KKyAqIEFtb25nIHdpdGggYmFzZSBmdW5jdGlvbmFsaXR5IHRoaXMgY2xhc3MgcHJvdmlkZXMgdGhlIGluZm9ybWF0aW9uIGFib3V0CisgKiBjb25zdHJhaW5zIG9uIHRoZSBkYXRhIGxlbmd0aCwgYW5kIGluZm9ybWF0aW9uIGFib3V0IGNvcnJlc3BvbmRlbmNlCisgKiBvZiBwbGFpbiBhbmQgZW5jcnlwdGVkIGRhdGEgbGVuZ3Rocy4KKyAqIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIFRMUyB2MSBzZWUgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI0Ni50eHQsCisgKiBvbiBTU0wgdjMgc2VlIGh0dHA6Ly93cC5uZXRzY2FwZS5jb20vZW5nL3NzbDMsCisgKiBvbiBTU0wgdjIgc2VlIGh0dHA6Ly93cC5uZXRzY2FwZS5jb20vZW5nL3NlY3VyaXR5L1NTTF8yLmh0bWwuCisgKi8KK3B1YmxpYyBjbGFzcyBTU0xSZWNvcmRQcm90b2NvbCB7CisKKyAgICAvKioKKyAgICAgKiBNYXhpbXVtIGxlbmd0aCBvZiBhbGxvd2VkIHBsYWluIGRhdGEgZnJhZ21lbnQKKyAgICAgKiBhcyBzcGVjaWZpZWQgYnkgVExTIHNwZWNpZmljYXRpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0RBVEFfTEVOR1RIID0gMTYzODQ7IC8vIDJeMTQKKyAgICAvKioKKyAgICAgKiBNYXhpbXVtIGxlbmd0aCBvZiBhbGxvd2VkIGNvbXByZXNzZWQgZGF0YSBmcmFnbWVudAorICAgICAqIGFzIHNwZWNpZmllZCBieSBUTFMgc3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBNQVhfQ09NUFJFU1NFRF9EQVRBX0xFTkdUSAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBNQVhfREFUQV9MRU5HVEggKyAxMDI0OworICAgIC8qKgorICAgICAqIE1heGltdW0gbGVuZ3RoIG9mIGFsbG93ZWQgY2lwaGVyZWQgZGF0YSBmcmFnbWVudAorICAgICAqIGFzIHNwZWNpZmllZCBieSBUTFMgc3BlY2lmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBNQVhfQ0lQSEVSRURfREFUQV9MRU5HVEgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gTUFYX0NPTVBSRVNTRURfREFUQV9MRU5HVEggKyAxMDI0OworICAgIC8qKgorICAgICAqIE1heGltdW0gbGVuZ3RoIG9mIHNzbCByZWNvcmQuIEl0IGlzIGNvdW50ZWQgYXM6CisgICAgICogdHlwZSgxKSArIHZlcnNpb24oMikgKyBsZW5ndGgoMikgKyBNQVhfQ0lQSEVSRURfREFUQV9MRU5HVEgKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBNQVhfU1NMX1BBQ0tFVF9TSVpFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IE1BWF9DSVBIRVJFRF9EQVRBX0xFTkdUSCArIDU7CisgICAgLy8gdGhlIFNTTCBzZXNzaW9uIHVzZWQgZm9yIGNvbm5lY3Rpb24KKyAgICBwcml2YXRlIFNTTFNlc3Npb25JbXBsIHNlc3Npb247CisgICAgLy8gcHJvdG9jb2wgdmVyc2lvbiBvZiB0aGUgY29ubmVjdGlvbgorICAgIHByaXZhdGUgYnl0ZVtdIHZlcnNpb247CisgICAgLy8gaW5wdXQgc3RyZWFtIG9mIHJlY29yZCBwcm90b2NvbAorICAgIHByaXZhdGUgU1NMSW5wdXRTdHJlYW0gaW47CisgICAgLy8gaGFuZHNoYWtlIHByb3RvY29sIG9iamVjdCB0byB3aGljaCBoYW5kc2hha2luZyBkYXRhIHdpbGwgYmUgdHJhbnNtaXR0ZWQKKyAgICBwcml2YXRlIEhhbmRzaGFrZVByb3RvY29sIGhhbmRzaGFrZVByb3RvY29sOworICAgIC8vIGFsZXJ0IHByb3RvY29sIHRvIGluZGljYXRlIGFsZXJ0cyBvY2N1cnJlZC9yZWNlaXZlZAorICAgIHByaXZhdGUgQWxlcnRQcm90b2NvbCBhbGVydFByb3RvY29sOworICAgIC8vIGFwcGxpY2F0aW9uIGRhdGEgb2JqZWN0IHRvIHdoaWNoIGFwcGxpY2F0aW9uIGRhdGEgd2lsbCBiZSB0cmFuc21pdHRlZAorICAgIHByaXZhdGUgb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZS5BcHBlbmRhYmxlIGFwcERhdGE7CisgICAgLy8gY29ubmVjdGlvbiBzdGF0ZSBob2xkaW5nIG9iamVjdAorICAgIHByaXZhdGUgQ29ubmVjdGlvblN0YXRlCisgICAgICAgIGFjdGl2ZVJlYWRTdGF0ZSwgYWN0aXZlV3JpdGVTdGF0ZSwgcGVuZGluZ0Nvbm5lY3Rpb25TdGF0ZTsKKworICAgIC8vIGxvZ2dlcgorICAgIHByaXZhdGUgTG9nZ2VyLlN0cmVhbSBsb2dnZXIgPSBMb2dnZXIuZ2V0U3RyZWFtKCJyZWNvcmQiKTsKKworICAgIC8vIGZsYWcgaW5kaWNhdGluZyBpZiBzZXNzaW9uIG9iamVjdCBoYXMgYmVlbiBjaGFuZ2VkIGFmdGVyCisgICAgLy8gaGFuZHNoYWtlIHBoYXNlICh0byBkaXN0aW5ndWlzaCBzZXNzaW9uIHBlbmRpbmcgc3RhdGUpCisgICAgcHJpdmF0ZSBib29sZWFuIHNlc3Npb25XYXNDaGFuZ2VkID0gZmFsc2U7CisKKyAgICAvLyBjaGFuZ2UgY2lwaGVyIHNwZWMgbWVzc2FnZSBjb250ZW50CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIGNoYW5nZV9jaXBoZXJfc3BlY19ieXRlID0gbmV3IGJ5dGVbXSB7MX07CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIHJlY29yZCBwcm90b2NvbCBhbmQgdHVuZXMKKyAgICAgKiB1cCB0aGUgY2xpZW50IHByb3RvY29scyB0byB1c2UgdXQuCisgICAgICogQHBhcmFtICAgaGFuZHNoYWtlUHJvdG9jb2w6ICBIYW5kc2hha2VQcm90b2NvbAorICAgICAqIEBwYXJhbSAgIGFsZXJ0UHJvdG9jb2w6ICBBbGVydFByb3RvY29sCisgICAgICogQHBhcmFtICAgaW46IFNTTElucHV0U3RyZWFtCisgICAgICogQHBhcmFtICAgYXBwRGF0YTogICAgQXBwZW5kYWJsZQorICAgICAqLworICAgIHByb3RlY3RlZCBTU0xSZWNvcmRQcm90b2NvbChIYW5kc2hha2VQcm90b2NvbCBoYW5kc2hha2VQcm90b2NvbCwKKyAgICAgICAgICAgIEFsZXJ0UHJvdG9jb2wgYWxlcnRQcm90b2NvbCwKKyAgICAgICAgICAgIFNTTElucHV0U3RyZWFtIGluLAorICAgICAgICAgICAgQXBwZW5kYWJsZSBhcHBEYXRhKSB7CisgICAgICAgIHRoaXMuaGFuZHNoYWtlUHJvdG9jb2wgPSBoYW5kc2hha2VQcm90b2NvbDsKKyAgICAgICAgdGhpcy5oYW5kc2hha2VQcm90b2NvbC5zZXRSZWNvcmRQcm90b2NvbCh0aGlzKTsKKyAgICAgICAgdGhpcy5hbGVydFByb3RvY29sID0gYWxlcnRQcm90b2NvbDsKKyAgICAgICAgdGhpcy5hbGVydFByb3RvY29sLnNldFJlY29yZFByb3RvY29sKHRoaXMpOworICAgICAgICB0aGlzLmluID0gaW47CisgICAgICAgIHRoaXMuYXBwRGF0YSA9IGFwcERhdGE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc2Vzc2lvbiBvYnRhaW5lZCBkdXJpbmcgdGhlIGhhbmRzaGFrZSBuZWdvdGlhdGlvbi4KKyAgICAgKiBJZiB0aGUgaGFuZHNoYWtlIHByb2Nlc3Mgd2FzIG5vdCBjb21wbGV0ZWQsIG1ldGhvZCByZXR1cm5zIG51bGwuCisgICAgICogQHJldHVybiB0aGUgc2Vzc2lvbiBpbiBlZmZlY3QuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNTTFNlc3Npb25JbXBsIGdldFNlc3Npb24oKSB7CisgICAgICAgIHJldHVybiBzZXNzaW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1pbmltdW0gcG9zc2libGUgbGVuZ3RoIG9mIHRoZSBTU0wgcmVjb3JkLgorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGdldE1pblJlY29yZFNpemUoKSB7CisgICAgICAgIHJldHVybiAoYWN0aXZlUmVhZFN0YXRlID09IG51bGwpCisgICAgICAgICAgICA/IDYgLy8gdHlwZSArIHZlcnNpb24gKyBsZW5ndGggKyAxIGJ5dGUgb2YgZGF0YQorICAgICAgICAgICAgOiA1ICsgYWN0aXZlUmVhZFN0YXRlLmdldE1pbkZyYWdtZW50U2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHJlY29yZCBsZW5ndGggZm9yIHRoZSBzcGVjaWZpZWQgaW5jb21pbmcgZGF0YSBsZW5ndGguCisgICAgICogSWYgYWN0dWFsIHJlc3VsdGluZyByZWNvcmQgbGVuZ3RoIGlzIGdyZWF0ZXIgdGhhbgorICAgICAqIE1BWF9DSVBIRVJFRF9EQVRBX0xFTkdUSCwgTUFYX0NJUEhFUkVEX0RBVEFfTEVOR1RIIGlzIHJldHVybmVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgZ2V0UmVjb3JkU2l6ZShpbnQgZGF0YV9zaXplKSB7CisgICAgICAgIGlmIChhY3RpdmVXcml0ZVN0YXRlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiA1K2RhdGFfc2l6ZTsgLy8gdHlwZSArIHZlcnNpb24gKyBsZW5ndGggKyBkYXRhX3NpemUKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGludCByZXMgPSA1ICsgYWN0aXZlV3JpdGVTdGF0ZS5nZXRGcmFnbWVudFNpemUoZGF0YV9zaXplKTsKKyAgICAgICAgICAgIHJldHVybiAocmVzID4gTUFYX0NJUEhFUkVEX0RBVEFfTEVOR1RIKQorICAgICAgICAgICAgICAgID8gTUFYX0NJUEhFUkVEX0RBVEFfTEVOR1RIIC8vIHNvIHRoZSBzb3VyY2UgZGF0YSBzaG91bGQgYmUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzcGxpdCBpbnRvIHNldmVyYWwgcGFja2V0cworICAgICAgICAgICAgICAgIDogcmVzOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdXBwZXIgYm91bmQgb2YgbGVuZ3RoIG9mIGRhdGEgY29udGFpbmluZyBpbiB0aGUgcmVjb3JkIHdpdGgKKyAgICAgKiBzcGVjaWZpZWQgbGVuZ3RoLgorICAgICAqIElmIHRoZSBwcm92aWRlZCByZWNvcmRfc2l6ZSBpcyBncmVhdGVyIG9yIGVxdWFsIHRvCisgICAgICogTUFYX0NJUEhFUkVEX0RBVEFfTEVOR1RIIHRoZSByZXR1cm5lZCB2YWx1ZSB3aWxsIGJlCisgICAgICogTUFYX0RBVEFfTEVOR1RICisgICAgICogY291bnRlZCBhcyBmb3IgZGF0YSB3aXRoCisgICAgICogTUFYX0NJUEhFUkVEX0RBVEFfTEVOR1RIIGxlbmd0aC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGdldERhdGFTaXplKGludCByZWNvcmRfc2l6ZSkgeworICAgICAgICByZWNvcmRfc2l6ZSAtPSA1OyAvLyAtICh0eXBlICsgdmVyc2lvbiArIGxlbmd0aCArIGRhdGFfc2l6ZSkKKyAgICAgICAgaWYgKHJlY29yZF9zaXplID4gTUFYX0NJUEhFUkVEX0RBVEFfTEVOR1RIKSB7CisgICAgICAgICAgICAvLyB0aGUgZGF0YSBvZiBzdWNoIHNpemUgY29uc2lzdHMgb2YgdGhlIHNldmVyYWwgcGFja2V0cworICAgICAgICAgICAgcmV0dXJuIE1BWF9EQVRBX0xFTkdUSDsKKyAgICAgICAgfQorICAgICAgICBpZiAoYWN0aXZlUmVhZFN0YXRlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiByZWNvcmRfc2l6ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYWN0aXZlUmVhZFN0YXRlLmdldENvbnRlbnRTaXplKHJlY29yZF9zaXplKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXBlbmRpbmcgb24gdGhlIENvbm5lY3Rpb24gU3RhdGUgKFNlc3Npb24pIGVuY3J5cHRzIGFuZCBjb21wcmVzcworICAgICAqIHRoZSBwcm92aWRlZCBkYXRhLCBhbmQgcGFja3MgaXQgaW50byBUTFNDaXBoZXJ0ZXh0IHN0cnVjdHVyZS4KKyAgICAgKiBAcGFyYW0gICBjb250ZW50X3R5cGU6IGludAorICAgICAqIEByZXR1cm4gIHNzbCBwYWNrZXQgY3JlYXRlZCBvdmVyIHRoZSBjdXJyZW50IGNvbm5lY3Rpb24gc3RhdGUKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIHdyYXAoYnl0ZSBjb250ZW50X3R5cGUsIERhdGFTdHJlYW0gZGF0YVN0cmVhbSkgeworICAgICAgICBieXRlW10gZnJhZ21lbnQgPSBkYXRhU3RyZWFtLmdldERhdGEoTUFYX0RBVEFfTEVOR1RIKTsKKyAgICAgICAgcmV0dXJuIHdyYXAoY29udGVudF90eXBlLCBmcmFnbWVudCwgMCwgZnJhZ21lbnQubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXBlbmRpbmcgb24gdGhlIENvbm5lY3Rpb24gU3RhdGUgKFNlc3Npb24pIGVuY3J5cHRzIGFuZCBjb21wcmVzcworICAgICAqIHRoZSBwcm92aWRlZCBkYXRhLCBhbmQgcGFja3MgaXQgaW50byBUTFNDaXBoZXJ0ZXh0IHN0cnVjdHVyZS4KKyAgICAgKiBAcGFyYW0gICBjb250ZW50X3R5cGU6IGludAorICAgICAqIEBwYXJhbSAgIGZyYWdtZW50OiBieXRlW10KKyAgICAgKiBAcmV0dXJuICBzc2wgcGFja2V0IGNyZWF0ZWQgb3ZlciB0aGUgY3VycmVudCBjb25uZWN0aW9uIHN0YXRlCisgICAgICovCisgICAgcHJvdGVjdGVkIGJ5dGVbXSB3cmFwKGJ5dGUgY29udGVudF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICBieXRlW10gZnJhZ21lbnQsIGludCBvZmZzZXQsIGludCBsZW4pIHsKKyAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiU1NMUmVjb3JkUHJvdG9jb2wud3JhcDogVExTUGxhaW50ZXh0LmZyYWdtZW50WyIKKyAgICAgICAgICAgICAgICAgICAgK2xlbisiXToiKTsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludChmcmFnbWVudCwgb2Zmc2V0LCBsZW4pOworICAgICAgICB9CisgICAgICAgIGlmIChsZW4gPiBNQVhfREFUQV9MRU5HVEgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICBBbGVydFByb3RvY29sLklOVEVSTkFMX0VSUk9SLAorICAgICAgICAgICAgICAgIG5ldyBTU0xQcm90b2NvbEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgIlRoZSBwcm92aWRlZCBjaHVuayBvZiBkYXRhIGlzIHRvbyBiaWc6ICIgKyBsZW4KKyAgICAgICAgICAgICAgICAgICAgKyAiID4gTUFYX0RBVEFfTEVOR1RIID09ICIrTUFYX0RBVEFfTEVOR1RIKSk7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIGNpcGhlcmVkX2ZyYWdtZW50ID0gZnJhZ21lbnQ7CisgICAgICAgIGlmIChhY3RpdmVXcml0ZVN0YXRlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGNpcGhlcmVkX2ZyYWdtZW50ID0KKyAgICAgICAgICAgICAgICBhY3RpdmVXcml0ZVN0YXRlLmVuY3J5cHQoY29udGVudF90eXBlLCBmcmFnbWVudCwgb2Zmc2V0LCBsZW4pOworICAgICAgICAgICAgaWYgKGNpcGhlcmVkX2ZyYWdtZW50Lmxlbmd0aCA+IE1BWF9DSVBIRVJFRF9EQVRBX0xFTkdUSCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgQWxlcnRQcm90b2NvbC5JTlRFUk5BTF9FUlJPUiwKKyAgICAgICAgICAgICAgICAgICAgbmV3IFNTTFByb3RvY29sRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgIlRoZSBjaXBoZXJlZCBkYXRhIGluY3JlYXNlZCBtb3JlIHRoYW4gb24gMTAyNCBieXRlcyIpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChsb2dnZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJTU0xSZWNvcmRQcm90b2NvbC53cmFwOiBUTFNDaXBoZXJ0ZXh0LmZyYWdtZW50WyIKKyAgICAgICAgICAgICAgICAgICAgICAgICtjaXBoZXJlZF9mcmFnbWVudC5sZW5ndGgrIl06Iik7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50KGNpcGhlcmVkX2ZyYWdtZW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcGFja2V0aXplKGNvbnRlbnRfdHlwZSwgdmVyc2lvbiwgY2lwaGVyZWRfZnJhZ21lbnQpOworICAgIH0KKworICAgIHByaXZhdGUgYnl0ZVtdIHBhY2tldGl6ZShieXRlIHR5cGUsIGJ5dGVbXSB2ZXJzaW9uLCBieXRlW10gZnJhZ21lbnQpIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZmYgPSBuZXcgYnl0ZVs1K2ZyYWdtZW50Lmxlbmd0aF07CisgICAgICAgIGJ1ZmZbMF0gPSB0eXBlOworICAgICAgICBpZiAodmVyc2lvbiAhPSBudWxsKSB7CisgICAgICAgICAgICBidWZmWzFdID0gdmVyc2lvblswXTsKKyAgICAgICAgICAgIGJ1ZmZbMl0gPSB2ZXJzaW9uWzFdOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYnVmZlsxXSA9IDM7CisgICAgICAgICAgICBidWZmWzJdID0gMTsKKyAgICAgICAgfQorICAgICAgICBidWZmWzNdID0gKGJ5dGUpICgoMHgwMEZGMDAgJiBmcmFnbWVudC5sZW5ndGgpID4+IDgpOworICAgICAgICBidWZmWzRdID0gKGJ5dGUpICgweDAwMDBGRiAmIGZyYWdtZW50Lmxlbmd0aCk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZnJhZ21lbnQsIDAsIGJ1ZmYsIDUsIGZyYWdtZW50Lmxlbmd0aCk7CisgICAgICAgIHJldHVybiBidWZmOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgc3NsIHNlc3Npb24gdG8gYmUgdXNlZCBhZnRlciBzZW5kaW5nIHRoZSBjaGFuZ2VDaXBoZXJTcGVjIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gICBzZXNzaW9uOiAgICBTU0xTZXNzaW9uSW1wbAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRTZXNzaW9uKFNTTFNlc3Npb25JbXBsIHNlc3Npb24pIHsKKyAgICAgICAgaWYgKCFzZXNzaW9uV2FzQ2hhbmdlZCkgeworICAgICAgICAgICAgLy8gc2Vzc2lvbiB3YXMgbm90IGNoYW5nZWQgZm9yIGN1cnJlbnQgaGFuZHNoYWtlIHByb2Nlc3MKKyAgICAgICAgICAgIGlmIChsb2dnZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJTU0xSZWNvcmRQcm90b2NvbC5zZXRTZXNzaW9uOiBTZXQgcGVuZGluZyBzZXNzaW9uIik7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIiAgY2lwaGVyIG5hbWU6ICIgKyBzZXNzaW9uLmdldENpcGhlclN1aXRlKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy5zZXNzaW9uID0gc2Vzc2lvbjsKKyAgICAgICAgICAgIC8vIGNyZWF0ZSBuZXcgY29ubmVjdGlvbiBzdGF0ZQorICAgICAgICAgICAgcGVuZGluZ0Nvbm5lY3Rpb25TdGF0ZSA9ICgodmVyc2lvbiA9PSBudWxsKSB8fCAodmVyc2lvblsxXSA9PSAxKSkKKyAgICAgICAgICAgICAgICA/IChDb25uZWN0aW9uU3RhdGUpIG5ldyBDb25uZWN0aW9uU3RhdGVUTFMoZ2V0U2Vzc2lvbigpKQorICAgICAgICAgICAgICAgIDogKENvbm5lY3Rpb25TdGF0ZSkgbmV3IENvbm5lY3Rpb25TdGF0ZVNTTHYzKGdldFNlc3Npb24oKSk7CisgICAgICAgICAgICBzZXNzaW9uV2FzQ2hhbmdlZCA9IHRydWU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyB3YWl0IGZvciByZWhhbmRzaGFraW5nJ3Mgc2Vzc2lvbgorICAgICAgICAgICAgc2Vzc2lvbldhc0NoYW5nZWQgPSBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGNoYW5nZSBjaXBoZXIgc3BlYyBtZXNzYWdlIHRvIGJlIHNlbnQgdG8gYW5vdGhlciBwZWVyLgorICAgICAqIFRoZSBwZW5kaW5nIGNvbm5lY3Rpb24gc3RhdGUgd2lsbCBiZSBidWlsdCBvbiB0aGUgYmFzZSBvZiBwcm92aWRlZAorICAgICAqIHNlc3Npb24gb2JqZWN0CisgICAgICogVGhlIGNhbGxpbmcgb2YgdGhpcyBtZXRob2QgdHJpZ2dlcnMgcGVuZGluZyB3cml0ZSBjb25uZWN0aW9uIHN0YXRlIHRvCisgICAgICogYmUgYWN0aXZlLgorICAgICAqIEByZXR1cm4gc3NsIHJlY29yZCBjb250YWluaW5nIHRoZSAiY2hhbmdlIGNpcGhlciBzcGVjIiBtZXNzYWdlLgorICAgICAqLworICAgIHByb3RlY3RlZCBieXRlW10gZ2V0Q2hhbmdlQ2lwaGVyU3BlY01lc2FnZShTU0xTZXNzaW9uSW1wbCBzZXNzaW9uKSB7CisgICAgICAgIC8vIG1ha2UgY2hhbmdlX2NpcGhlcl9zcGVjX21lc3NhZ2U6CisgICAgICAgIGJ5dGVbXSBjaGFuZ2VfY2lwaGVyX3NwZWNfbWVzc2FnZTsKKyAgICAgICAgaWYgKGFjdGl2ZVdyaXRlU3RhdGUgPT0gbnVsbCkgeworICAgICAgICAgICAgY2hhbmdlX2NpcGhlcl9zcGVjX21lc3NhZ2UgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgQ29udGVudFR5cGUuQ0hBTkdFX0NJUEhFUl9TUEVDLCB2ZXJzaW9uWzBdLAorICAgICAgICAgICAgICAgICAgICAgICAgdmVyc2lvblsxXSwgMCwgMSwgMQorICAgICAgICAgICAgICAgIH07CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjaGFuZ2VfY2lwaGVyX3NwZWNfbWVzc2FnZSA9CisgICAgICAgICAgICAgICAgcGFja2V0aXplKENvbnRlbnRUeXBlLkNIQU5HRV9DSVBIRVJfU1BFQywgdmVyc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZVdyaXRlU3RhdGUuZW5jcnlwdChDb250ZW50VHlwZS5DSEFOR0VfQ0lQSEVSX1NQRUMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlX2NpcGhlcl9zcGVjX2J5dGUsIDAsIDEpKTsKKyAgICAgICAgfQorICAgICAgICBzZXRTZXNzaW9uKHNlc3Npb24pOworICAgICAgICBhY3RpdmVXcml0ZVN0YXRlID0gcGVuZGluZ0Nvbm5lY3Rpb25TdGF0ZTsKKyAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiU1NMUmVjb3JkUHJvdG9jb2wuZ2V0Q2hhbmdlQ2lwaGVyU3BlY01lc2FnZSIpOworICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oImFjdGl2ZVdyaXRlU3RhdGUgPSBwZW5kaW5nQ29ubmVjdGlvblN0YXRlIik7CisgICAgICAgICAgICBsb2dnZXIucHJpbnQoY2hhbmdlX2NpcGhlcl9zcGVjX21lc3NhZ2UpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjaGFuZ2VfY2lwaGVyX3NwZWNfbWVzc2FnZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgdGhlIGZyYWdtZW50IGZpZWxkIG9mIFRMU0NpcGhlcnRleHQsIGFuZCB0aGFuCisgICAgICogZGVwZW5kaW5nIG9uIHRoZSBlc3RhYmxpc2hlZCBDb25uZWN0aW9uIFN0YXRlCisgICAgICogZGVjcnlwdHMgYW5kIGRlY29tcHJlc3NlcyBpdC4gVGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmUgaXMgZXhwZWN0ZWQKKyAgICAgKiBvbiB0aGUgaW5wdXQgYXQgdGhlIG1vbWVudCBvZiB0aGUgY2FsbDoKKyAgICAgKgorICAgICAqICBzdHJ1Y3QgeworICAgICAqICAgICAgQ29udGVudFR5cGUgdHlwZTsKKyAgICAgKiAgICAgIFByb3RvY29sVmVyc2lvbiB2ZXJzaW9uOworICAgICAqICAgICAgdWludDE2IGxlbmd0aDsKKyAgICAgKiAgICAgIHNlbGVjdCAoQ2lwaGVyU3BlYy5jaXBoZXJfdHlwZSkgeworICAgICAqICAgICAgICAgIGNhc2Ugc3RyZWFtOiBHZW5lcmljU3RyZWFtQ2lwaGVyOworICAgICAqICAgICAgICAgIGNhc2UgYmxvY2s6IEdlbmVyaWNCbG9ja0NpcGhlcjsKKyAgICAgKiAgICAgIH0gZnJhZ21lbnQ7CisgICAgICogIH0gVExTQ2lwaGVydGV4dDsKKyAgICAgKgorICAgICAqIChhcyBzcGVjaWZpZWQgYnkgUkZDIDIyNDYsIFRMUyB2MSBQcm90b2NvbCBzcGVjaWZpY2F0aW9uKQorICAgICAqCisgICAgICogSW4gYWRkaXRpb24gdGhpcyBtZXRob2QgY2FuIHJlY29nbml6ZSBTU0x2MiBoZWxsbyBtZXNzYWdlIHdoaWNoCisgICAgICogYXJlIG9mdGVuIHVzZWQgdG8gZXN0YWJsaXNoIHRoZSBTU0wvVExTIHNlc3Npb24uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHNvbWUgaW8gZXJyb3JzIGhhdmUgYmVlbiBvY2N1cnJlZAorICAgICAqIEB0aHJvd3MgRW5kT2ZTb3VyY2VFeGNlcHRpb24gaWYgdW5kZXJseWluZyBpbnB1dCBzdHJlYW0KKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhcyByYW4gb3V0IG9mIGRhdGEuCisgICAgICogQHRocm93cyBFbmRPZkJ1ZmZlckV4Y2VwdGlvbiBpZiB0aGVyZSB3YXMgbm90IGVub3VnaCBkYXRhCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0byBidWlsZCBjb21wbGV0ZSBzc2wgcGFja2V0LgorICAgICAqIEByZXR1cm4gdGhlIHR5cGUgb2YgdW53cmFwcGVkIG1lc3NhZ2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCB1bndyYXAoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJTU0xSZWNvcmRQcm90b2NvbC51bndyYXA6IEJFR0lOIFsiKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgdHlwZSA9IGluLnJlYWRVaW50OCgpOworICAgICAgICBpZiAoKHR5cGUgPCBDb250ZW50VHlwZS5DSEFOR0VfQ0lQSEVSX1NQRUMpCisgICAgICAgICAgICAgICAgfHwgKHR5cGUgPiBDb250ZW50VHlwZS5BUFBMSUNBVElPTl9EQVRBKSkgeworICAgICAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIk5vbiB2My4xIG1lc3NhZ2UgdHlwZToiICsgdHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodHlwZSA+PSAweDgwKSB7CisgICAgICAgICAgICAgICAgLy8gaXQgaXMgcHJvYmFibHkgU1NMIHYyIGNsaWVudF9oZWxsbyBtZXNzYWdlCisgICAgICAgICAgICAgICAgLy8gKHNlZSBTU0wgdjIgc3BlYyBhdDoKKyAgICAgICAgICAgICAgICAvLyBodHRwOi8vd3AubmV0c2NhcGUuY29tL2VuZy9zZWN1cml0eS9TU0xfMi5odG1sKQorICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSAodHlwZSAmIDB4N2YpIDw8IDggfCBpbi5yZWFkKCk7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGZyYWdtZW50ID0gaW4ucmVhZChsZW5ndGgpOworICAgICAgICAgICAgICAgIGhhbmRzaGFrZVByb3RvY29sLnVud3JhcFNTTHYyKGZyYWdtZW50KTsKKyAgICAgICAgICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNTTFJlY29yZFByb3RvY29sOnVud3JhcCBdIEVORCwgU1NMdjIgdHlwZSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gQ29udGVudFR5cGUuSEFORFNIQUtFOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IEFsZXJ0RXhjZXB0aW9uKEFsZXJ0UHJvdG9jb2wuVU5FWFBFQ1RFRF9NRVNTQUdFLAorICAgICAgICAgICAgICAgICAgICBuZXcgU1NMUHJvdG9jb2xFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAiVW5leHBlY3RlZCBtZXNzYWdlIHR5cGUgaGFzIGJlZW4gcmVjZWl2ZWQ6ICIrdHlwZSkpOworICAgICAgICB9CisgICAgICAgIGlmIChsb2dnZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIkdvdCB0aGUgbWVzc2FnZSBvZiB0eXBlOiAiICsgdHlwZSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHZlcnNpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKChpbi5yZWFkKCkgIT0gdmVyc2lvblswXSkKKyAgICAgICAgICAgICAgICAgICAgfHwgKGluLnJlYWQoKSAhPSB2ZXJzaW9uWzFdKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbihBbGVydFByb3RvY29sLlVORVhQRUNURURfTUVTU0FHRSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTU0xQcm90b2NvbEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5leHBlY3RlZCBtZXNzYWdlIHR5cGUgaGFzIGJlZW4gcmVjZWl2ZWQ6ICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGluLnNraXAoMik7IC8vIGp1c3Qgc2tpcCB0aGUgdmVyc2lvbiBudW1iZXIKKyAgICAgICAgfQorICAgICAgICBpbnQgbGVuZ3RoID0gaW4ucmVhZFVpbnQxNigpOworICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJUTFNDaXBoZXJ0ZXh0LmZyYWdtZW50WyIrbGVuZ3RoKyJdOiAuLi4iKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobGVuZ3RoID4gTUFYX0NJUEhFUkVEX0RBVEFfTEVOR1RIKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQWxlcnRFeGNlcHRpb24oQWxlcnRQcm90b2NvbC5SRUNPUkRfT1ZFUkZMT1csCisgICAgICAgICAgICAgICAgICAgIG5ldyBTU0xQcm90b2NvbEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICJSZWNlaXZlZCBtZXNzYWdlIGlzIHRvbyBiaWcuIikpOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSBmcmFnbWVudCA9IGluLnJlYWQobGVuZ3RoKTsKKyAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICBsb2dnZXIucHJpbnQoZnJhZ21lbnQpOworICAgICAgICB9CisgICAgICAgIGlmIChhY3RpdmVSZWFkU3RhdGUgIT0gbnVsbCkgeworICAgICAgICAgICAgZnJhZ21lbnQgPSBhY3RpdmVSZWFkU3RhdGUuZGVjcnlwdCgoYnl0ZSkgdHlwZSwgZnJhZ21lbnQpOworICAgICAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIlRMU1BsYWludGV4dC5mcmFnbWVudDoiKTsKKyAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnQoZnJhZ21lbnQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChmcmFnbWVudC5sZW5ndGggPiBNQVhfREFUQV9MRU5HVEgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbihBbGVydFByb3RvY29sLkRFQ09NUFJFU1NJT05fRkFJTFVSRSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IFNTTFByb3RvY29sRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgIkRlY29tcHJlc3NlZCBwbGFpbiBkYXRhIGlzIHRvbyBiaWcuIikpOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAodHlwZSkgeworICAgICAgICAgICAgY2FzZSBDb250ZW50VHlwZS5DSEFOR0VfQ0lQSEVSX1NQRUM6CisgICAgICAgICAgICAgICAgLy8gbm90aWZ5IGhhbmRzaGFrZSBwcm90b2NvbDoKKyAgICAgICAgICAgICAgICBoYW5kc2hha2VQcm90b2NvbC5yZWNlaXZlQ2hhbmdlQ2lwaGVyU3BlYygpOworICAgICAgICAgICAgICAgIHNldFNlc3Npb24oaGFuZHNoYWtlUHJvdG9jb2wuZ2V0U2Vzc2lvbigpKTsKKyAgICAgICAgICAgICAgICAvLyBjaGFuZ2UgY2lwaGVyIHNwZWMgbWVzc2FnZSBoYXMgYmVlbiByZWNlaXZlZCwgc286CisgICAgICAgICAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJhY3RpdmVSZWFkU3RhdGUgPSBwZW5kaW5nQ29ubmVjdGlvblN0YXRlIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFjdGl2ZVJlYWRTdGF0ZSA9IHBlbmRpbmdDb25uZWN0aW9uU3RhdGU7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIENvbnRlbnRUeXBlLkFMRVJUOgorICAgICAgICAgICAgICAgIGFsZXJ0KGZyYWdtZW50WzBdLCBmcmFnbWVudFsxXSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIENvbnRlbnRUeXBlLkhBTkRTSEFLRToKKyAgICAgICAgICAgICAgICBoYW5kc2hha2VQcm90b2NvbC51bndyYXAoZnJhZ21lbnQpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBDb250ZW50VHlwZS5BUFBMSUNBVElPTl9EQVRBOgorICAgICAgICAgICAgICAgIGlmIChsb2dnZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVExTQ2lwaGVydGV4dC51bndyYXA6IEFQUCBEQVRBWyIrbGVuZ3RoKyJdOiIpOworICAgICAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbihuZXcgU3RyaW5nKGZyYWdtZW50KSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFwcERhdGEuYXBwZW5kKGZyYWdtZW50KTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFsZXJ0RXhjZXB0aW9uKEFsZXJ0UHJvdG9jb2wuVU5FWFBFQ1RFRF9NRVNTQUdFLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFNTTFByb3RvY29sRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVbmV4cGVjdGVkIG1lc3NhZ2UgdHlwZSBoYXMgYmVlbiByZWNlaXZlZDogIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSkpOworICAgICAgICB9CisgICAgICAgIGlmIChsb2dnZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIlNTTFJlY29yZFByb3RvY29sOnVud3JhcCBdIEVORCwgdHlwZTogIiArIHR5cGUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhc3NlcyB0aGUgYWxlcnQgaW5mb3JtYXRpb24gdG8gdGhlIGFsZXJ0IHByb3RvY29sLgorICAgICAqIEBwYXJhbSAgIGxldmVsOiAgYnl0ZQorICAgICAqIEBwYXJhbSAgIGRlc2NyaXB0aW9uOiAgICBieXRlCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgYWxlcnQoYnl0ZSBsZXZlbCwgYnl0ZSBkZXNjcmlwdGlvbikgeworICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJTU0xSZWNvcmRQcm90b2NvbC5hbGxlcnQ6ICIrbGV2ZWwrIiAiK2Rlc2NyaXB0aW9uKTsKKyAgICAgICAgfQorICAgICAgICBhbGVydFByb3RvY29sLmFsZXJ0KGxldmVsLCBkZXNjcmlwdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgU1NMIHZlcnNpb24gdXNlZCBpbiB0aGlzIGNvbm5lY3Rpb24uCisgICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGluZyBmcm9tIHRoZSBoYW5kc2hha2UgcHJvdG9jb2wgYWZ0ZXIKKyAgICAgKiBpdCBiZWNvbWVzIGtub3duIHdpdGNoIHByb3RvY29sIHZlcnNpb24gd2lsbCBiZSB1c2VkLgorICAgICAqIEBwYXJhbSAgIHZlcjogICAgYnl0ZVtdCisgICAgICogQHJldHVybgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFZlcnNpb24oYnl0ZVtdIHZlcikgeworICAgICAgICB0aGlzLnZlcnNpb24gPSB2ZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2h1dHMgZG93biB0aGUgcHJvdG9jb2wuIEl0IHdpbGwgYmUgaW1wb3NzaWJsZSB0byB1c2UgdGhlIGluc3RhbmNlCisgICAgICogYWZ0ZXIgdGhlIGNhbGxpbmcgb2YgdGhpcyBtZXRob2QuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2h1dGRvd24oKSB7CisgICAgICAgIHNlc3Npb24gPSBudWxsOworICAgICAgICB2ZXJzaW9uID0gbnVsbDsKKyAgICAgICAgaW4gPSBudWxsOworICAgICAgICBoYW5kc2hha2VQcm90b2NvbCA9IG51bGw7CisgICAgICAgIGFsZXJ0UHJvdG9jb2wgPSBudWxsOworICAgICAgICBhcHBEYXRhID0gbnVsbDsKKyAgICAgICAgaWYgKHBlbmRpbmdDb25uZWN0aW9uU3RhdGUgIT0gbnVsbCkgeworICAgICAgICAgICAgcGVuZGluZ0Nvbm5lY3Rpb25TdGF0ZS5zaHV0ZG93bigpOworICAgICAgICB9CisgICAgICAgIHBlbmRpbmdDb25uZWN0aW9uU3RhdGUgPSBudWxsOworICAgICAgICBpZiAoYWN0aXZlUmVhZFN0YXRlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFjdGl2ZVJlYWRTdGF0ZS5zaHV0ZG93bigpOworICAgICAgICB9CisgICAgICAgIGFjdGl2ZVJlYWRTdGF0ZSA9IG51bGw7CisgICAgICAgIGlmIChhY3RpdmVSZWFkU3RhdGUgIT0gbnVsbCkgeworICAgICAgICAgICAgYWN0aXZlUmVhZFN0YXRlLnNodXRkb3duKCk7CisgICAgICAgIH0KKyAgICAgICAgYWN0aXZlV3JpdGVTdGF0ZSA9IG51bGw7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMU2VydmVyU2Vzc2lvbkNhY2hlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xTZXJ2ZXJTZXNzaW9uQ2FjaGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMmEwZTcyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMU2VydmVyU2Vzc2lvbkNhY2hlLmphdmEKQEAgLTAsMCArMSw1MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbjsKKworLyoqCisgKiBBIHBlcnNpc3RlbnQge0BsaW5rIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbn0gY2FjaGUgdXNlZCBieQorICoge0BsaW5rIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbkNvbnRleHR9IHRvIHNoYXJlIHNlcnZlci1zaWRlIFNTTCBzZXNzaW9ucworICogYWNyb3NzIHByb2Nlc3Nlcy4gRm9yIGV4YW1wbGUsIHRoaXMgY2FjaGUgZW5hYmxlcyBvbmUgc2VydmVyIHRvIHJlc3VtZQorICogYSBzZXNzaW9uIHN0YXJ0ZWQgYnkgYSBkaWZmZXJlbnQgc2VydmVyIGJhc2VkIG9uIGEgc2Vzc2lvbiBJRCBwcm92aWRlZAorICogYnkgdGhlIGNsaWVudC4KKyAqCisgKiA8cD5UaGUge0Bjb2RlIFNTTFNlc3Npb25Db250ZXh0fSBpbXBsZW1lbnRhdGlvbiBjb252ZXJ0cworICoge0Bjb2RlIFNTTFNlc3Npb259cyBpbnRvIHJhdyBieXRlcyBhbmQgdmljZSB2ZXJzYS4gVGhlIGV4YWN0IG1ha2V1cCBvZiB0aGUKKyAqIHNlc3Npb24gZGF0YSBpcyBkZXBlbmRlbnQgdXBvbiB0aGUgY2FsbGVyJ3MgaW1wbGVtZW50YXRpb24gYW5kIGlzIG9wYXF1ZSB0bworICogdGhlIHtAY29kZSBTU0xTZXJ2ZXJTZXNzaW9uQ2FjaGV9IGltcGxlbWVudGF0aW9uLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFNTTFNlcnZlclNlc3Npb25DYWNoZSB7CisKKyAgLyoqCisgICAqIEdldHMgdGhlIHNlc3Npb24gZGF0YSBmb3IgZ2l2ZW4gc2Vzc2lvbiBJRC4KKyAgICoKKyAgICogQHBhcmFtIGlkIGZyb20ge0BsaW5rIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNnZXRJZCgpfQorICAgKiBAcmV0dXJuIHRoZSBzZXNzaW9uIGRhdGEgb3IgbnVsbCBpZiBub25lIGlzIGNhY2hlZAorICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGlkIGlzIG51bGwKKyAgICovCisgIHB1YmxpYyBieXRlW10gZ2V0U2Vzc2lvbkRhdGEoYnl0ZVtdIGlkKTsKKworICAvKioKKyAgICogU3RvcmVzIHNlc3Npb24gZGF0YSBmb3IgdGhlIGdpdmVuIHNlc3Npb24uCisgICAqCisgICAqIEBwYXJhbSBzZXNzaW9uIHRvIGNhY2hlIGRhdGEgZm9yCisgICAqIEBwYXJhbSBzZXNzaW9uRGF0YSB0byBjYWNoZQorICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHNlc3Npb24gb3IgZGF0YSBpcyBudWxsCisgICAqLworICBwdWJsaWMgdm9pZCBwdXRTZXNzaW9uRGF0YShTU0xTZXNzaW9uIHNlc3Npb24sIGJ5dGVbXSBzZXNzaW9uRGF0YSk7Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMU2VydmVyU29ja2V0RmFjdG9yeUltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTFNlcnZlclNvY2tldEZhY3RvcnlJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjI4NzJmOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTFNlcnZlclNvY2tldEZhY3RvcnlJbXBsLmphdmEKQEAgLTAsMCArMSwxMjggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU2VydmVyU29ja2V0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5TWFuYWdlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldEZhY3Rvcnk7CitpbXBvcnQgbGliY29yZS51dGlsLkVtcHR5QXJyYXk7CisKKy8qKgorICogSW1wbGVtZW50YXRpb24gb2YgU1NMU2VydmVyU29ja2V0RmFjdG9yeS4KKyAqLworcHVibGljIGNsYXNzIFNTTFNlcnZlclNvY2tldEZhY3RvcnlJbXBsIGV4dGVuZHMgU1NMU2VydmVyU29ja2V0RmFjdG9yeSB7CisKKyAgICBwcml2YXRlIFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnM7CisgICAgcHJpdmF0ZSBJT0V4Y2VwdGlvbiBpbnN0YW50aWF0aW9uRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICovCisgICAgcHVibGljIFNTTFNlcnZlclNvY2tldEZhY3RvcnlJbXBsKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhpcy5zc2xQYXJhbWV0ZXJzID0gU1NMUGFyYW1ldGVyc0ltcGwuZ2V0RGVmYXVsdCgpOworICAgICAgICAgICAgdGhpcy5zc2xQYXJhbWV0ZXJzLnNldFVzZUNsaWVudE1vZGUoZmFsc2UpOworICAgICAgICB9IGNhdGNoIChLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGluc3RhbnRpYXRpb25FeGNlcHRpb24gPQorICAgICAgICAgICAgICAgIG5ldyBJT0V4Y2VwdGlvbigiRGVsYXllZCBpbnN0YW50aWF0aW9uIGV4Y2VwdGlvbjoiKTsKKyAgICAgICAgICAgIGluc3RhbnRpYXRpb25FeGNlcHRpb24uaW5pdENhdXNlKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNTTFNlcnZlclNvY2tldEZhY3RvcnlJbXBsKFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnMpIHsKKyAgICAgICAgdGhpcy5zc2xQYXJhbWV0ZXJzID0gKFNTTFBhcmFtZXRlcnNJbXBsKSBzc2xQYXJhbWV0ZXJzLmNsb25lKCk7CisgICAgICAgIHRoaXMuc3NsUGFyYW1ldGVycy5zZXRVc2VDbGllbnRNb2RlKGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0RmFjdG9yeSNnZXREZWZhdWx0Q2lwaGVyU3VpdGVzKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgaWYgKGluc3RhbnRpYXRpb25FeGNlcHRpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIEVtcHR5QXJyYXkuU1RSSU5HOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzc2xQYXJhbWV0ZXJzLmdldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0RmFjdG9yeSNnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSB7CisgICAgICAgIGlmIChpbnN0YW50aWF0aW9uRXhjZXB0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBFbXB0eUFycmF5LlNUUklORzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gQ2lwaGVyU3VpdGUuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVOYW1lcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YXgubmV0LlNlcnZlclNvY2tldEZhY3RvcnkjY3JlYXRlU2VydmVyU29ja2V0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2VydmVyU29ja2V0IGNyZWF0ZVNlcnZlclNvY2tldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpbnN0YW50aWF0aW9uRXhjZXB0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IGluc3RhbnRpYXRpb25FeGNlcHRpb247CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBTU0xTZXJ2ZXJTb2NrZXRJbXBsKChTU0xQYXJhbWV0ZXJzSW1wbCkgc3NsUGFyYW1ldGVycy5jbG9uZSgpKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YXgubmV0LlNlcnZlclNvY2tldEZhY3RvcnkjY3JlYXRlU2VydmVyU29ja2V0KGludCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2VydmVyU29ja2V0IGNyZWF0ZVNlcnZlclNvY2tldChpbnQgcG9ydCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluc3RhbnRpYXRpb25FeGNlcHRpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgaW5zdGFudGlhdGlvbkV4Y2VwdGlvbjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFNTTFNlcnZlclNvY2tldEltcGwocG9ydCwKKyAgICAgICAgICAgICAgICAoU1NMUGFyYW1ldGVyc0ltcGwpIHNzbFBhcmFtZXRlcnMuY2xvbmUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZheC5uZXQuU2VydmVyU29ja2V0RmFjdG9yeSNjcmVhdGVTZXJ2ZXJTb2NrZXQoaW50LGludCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2VydmVyU29ja2V0IGNyZWF0ZVNlcnZlclNvY2tldChpbnQgcG9ydCwgaW50IGJhY2tsb2cpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaW5zdGFudGlhdGlvbkV4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBpbnN0YW50aWF0aW9uRXhjZXB0aW9uOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU1NMU2VydmVyU29ja2V0SW1wbChwb3J0LCBiYWNrbG9nLAorICAgICAgICAgICAgICAgIChTU0xQYXJhbWV0ZXJzSW1wbCkgc3NsUGFyYW1ldGVycy5jbG9uZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5TZXJ2ZXJTb2NrZXRGYWN0b3J5I2NyZWF0ZVNlcnZlclNvY2tldChpbnQsaW50LEluZXRBZGRyZXNzKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTZXJ2ZXJTb2NrZXQgY3JlYXRlU2VydmVyU29ja2V0KGludCBwb3J0LCBpbnQgYmFja2xvZywKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIGlBZGRyZXNzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaW5zdGFudGlhdGlvbkV4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBpbnN0YW50aWF0aW9uRXhjZXB0aW9uOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU1NMU2VydmVyU29ja2V0SW1wbChwb3J0LCBiYWNrbG9nLCBpQWRkcmVzcywKKyAgICAgICAgICAgICAgICAoU1NMUGFyYW1ldGVyc0ltcGwpIHNzbFBhcmFtZXRlcnMuY2xvbmUoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMU2VydmVyU29ja2V0SW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMU2VydmVyU29ja2V0SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ3N2QwM2QKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xTZXJ2ZXJTb2NrZXRJbXBsLmphdmEKQEAgLTAsMCArMSwyNjYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0OworCisvKioKKyAqIFNTTFNlcnZlclNvY2tldCBpbXBsZW1lbnRhdGlvbgorICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldCBjbGFzcyBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uLgorICovCitwdWJsaWMgY2xhc3MgU1NMU2VydmVyU29ja2V0SW1wbCBleHRlbmRzIFNTTFNlcnZlclNvY2tldCB7CisKKyAgICAvLyB0aGUgc3NsUGFyYW1ldGVycyBvYmplY3QgZW5jYXBzdWxhdGVzIGFsbCB0aGUgaW5mbworICAgIC8vIGFib3V0IHN1cHBvcnRlZCBhbmQgZW5hYmxlZCBjaXBoZXIgc3VpdGVzIGFuZCBwcm90b2NvbHMsCisgICAgLy8gYXMgd2VsbCBhcyB0aGUgaW5mb3JtYXRpb24gYWJvdXQgY2xpZW50L3NlcnZlciBtb2RlIG9mCisgICAgLy8gc3NsIHNvY2tldCwgd2hldGhlciBpdCByZXF1aXJlL3dhbnQgY2xpZW50IGF1dGhlbnRpY2F0aW9uIG9yIG5vdCwKKyAgICAvLyBhbmQgY29udHJvbHMgd2hldGhlciBuZXcgU1NMIHNlc3Npb25zIG1heSBiZSBlc3RhYmxpc2hlZCBieSB0aGlzCisgICAgLy8gc29ja2V0IG9yIG5vdC4KKyAgICBwcml2YXRlIGZpbmFsIFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnM7CisKKyAgICAvLyBsb2dnZXIKKyAgICBwcml2YXRlIExvZ2dlci5TdHJlYW0gbG9nZ2VyID0gTG9nZ2VyLmdldFN0cmVhbSgic3NvY2tldCIpOworCisgICAgLyoqCisgICAgICogQ3RvcgorICAgICAqIEBwYXJhbSAgIHNzbFBhcmFtZXRlcnM6ICBTU0xQYXJhbWV0ZXJzCisgICAgICogQHRocm93cyAgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU1NMU2VydmVyU29ja2V0SW1wbChTU0xQYXJhbWV0ZXJzSW1wbCBzc2xQYXJhbWV0ZXJzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLnNzbFBhcmFtZXRlcnMgPSBzc2xQYXJhbWV0ZXJzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEN0b3IKKyAgICAgKiBAcGFyYW0gICBwb3J0OiAgIGludAorICAgICAqIEBwYXJhbSAgIHNzbFBhcmFtZXRlcnM6ICBTU0xQYXJhbWV0ZXJzCisgICAgICogQHRocm93cyAgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU1NMU2VydmVyU29ja2V0SW1wbChpbnQgcG9ydCwgU1NMUGFyYW1ldGVyc0ltcGwgc3NsUGFyYW1ldGVycykKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIocG9ydCk7CisgICAgICAgIHRoaXMuc3NsUGFyYW1ldGVycyA9IHNzbFBhcmFtZXRlcnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3RvcgorICAgICAqIEBwYXJhbSAgIHBvcnQ6ICAgaW50CisgICAgICogQHBhcmFtICAgYmFja2xvZzogICAgaW50CisgICAgICogQHBhcmFtICAgc3NsUGFyYW1ldGVyczogIFNTTFBhcmFtZXRlcnMKKyAgICAgKiBAdGhyb3dzICBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHByb3RlY3RlZCBTU0xTZXJ2ZXJTb2NrZXRJbXBsKGludCBwb3J0LCBpbnQgYmFja2xvZywKKyAgICAgICAgICAgIFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKHBvcnQsIGJhY2tsb2cpOworICAgICAgICB0aGlzLnNzbFBhcmFtZXRlcnMgPSBzc2xQYXJhbWV0ZXJzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEN0b3IKKyAgICAgKiBAcGFyYW0gICBwb3J0OiAgIGludAorICAgICAqIEBwYXJhbSAgIGJhY2tsb2c6ICAgIGludAorICAgICAqIEBwYXJhbSAgIGlBZGRyZXNzOiAgIEluZXRBZGRyZXNzCisgICAgICogQHBhcmFtICAgc3NsUGFyYW1ldGVyczogIFNTTFBhcmFtZXRlcnMKKyAgICAgKiBAdGhyb3dzICBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHByb3RlY3RlZCBTU0xTZXJ2ZXJTb2NrZXRJbXBsKGludCBwb3J0LCBpbnQgYmFja2xvZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MgaUFkZHJlc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnMpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKHBvcnQsIGJhY2tsb2csIGlBZGRyZXNzKTsKKyAgICAgICAgdGhpcy5zc2xQYXJhbWV0ZXJzID0gc3NsUGFyYW1ldGVyczsKKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0gU1NMUGFyYW1ldGVycyBiYXNlZCBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXQjZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSB7CisgICAgICAgIHJldHVybiBDaXBoZXJTdWl0ZS5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZU5hbWVzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXQjZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgcmV0dXJuIHNzbFBhcmFtZXRlcnMuZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0I3NldEVuYWJsZWRDaXBoZXJTdWl0ZXMoU3RyaW5nW10pCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRFbmFibGVkQ2lwaGVyU3VpdGVzKFN0cmluZ1tdIHN1aXRlcykgeworICAgICAgICBzc2xQYXJhbWV0ZXJzLnNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoc3VpdGVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldCNnZXRTdXBwb3J0ZWRQcm90b2NvbHMoKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ1tdIGdldFN1cHBvcnRlZFByb3RvY29scygpIHsKKyAgICAgICAgcmV0dXJuIFByb3RvY29sVmVyc2lvbi5zdXBwb3J0ZWRQcm90b2NvbHMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldCNnZXRFbmFibGVkUHJvdG9jb2xzKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRFbmFibGVkUHJvdG9jb2xzKCkgeworICAgICAgICByZXR1cm4gc3NsUGFyYW1ldGVycy5nZXRFbmFibGVkUHJvdG9jb2xzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXQjc2V0RW5hYmxlZFByb3RvY29scyhTdHJpbmdbXSkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEVuYWJsZWRQcm90b2NvbHMoU3RyaW5nW10gcHJvdG9jb2xzKSB7CisgICAgICAgIHNzbFBhcmFtZXRlcnMuc2V0RW5hYmxlZFByb3RvY29scyhwcm90b2NvbHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0I3NldFVzZUNsaWVudE1vZGUoYm9vbGVhbikKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFVzZUNsaWVudE1vZGUoYm9vbGVhbiBtb2RlKSB7CisgICAgICAgIHNzbFBhcmFtZXRlcnMuc2V0VXNlQ2xpZW50TW9kZShtb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldCNnZXRVc2VDbGllbnRNb2RlKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGdldFVzZUNsaWVudE1vZGUoKSB7CisgICAgICAgIHJldHVybiBzc2xQYXJhbWV0ZXJzLmdldFVzZUNsaWVudE1vZGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldCNzZXROZWVkQ2xpZW50QXV0aChib29sZWFuKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0TmVlZENsaWVudEF1dGgoYm9vbGVhbiBuZWVkKSB7CisgICAgICAgIHNzbFBhcmFtZXRlcnMuc2V0TmVlZENsaWVudEF1dGgobmVlZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXQjZ2V0TmVlZENsaWVudEF1dGgoKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0TmVlZENsaWVudEF1dGgoKSB7CisgICAgICAgIHJldHVybiBzc2xQYXJhbWV0ZXJzLmdldE5lZWRDbGllbnRBdXRoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXQjc2V0V2FudENsaWVudEF1dGgoYm9vbGVhbikKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFdhbnRDbGllbnRBdXRoKGJvb2xlYW4gd2FudCkgeworICAgICAgICBzc2xQYXJhbWV0ZXJzLnNldFdhbnRDbGllbnRBdXRoKHdhbnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0I2dldFdhbnRDbGllbnRBdXRoKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGdldFdhbnRDbGllbnRBdXRoKCkgeworICAgICAgICByZXR1cm4gc3NsUGFyYW1ldGVycy5nZXRXYW50Q2xpZW50QXV0aCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0I3NldEVuYWJsZVNlc3Npb25DcmVhdGlvbihib29sZWFuKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKGJvb2xlYW4gZmxhZykgeworICAgICAgICBzc2xQYXJhbWV0ZXJzLnNldEVuYWJsZVNlc3Npb25DcmVhdGlvbihmbGFnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldCNnZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCkgeworICAgICAgICByZXR1cm4gc3NsUGFyYW1ldGVycy5nZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oKTsKKyAgICB9CisKKworICAgIC8vIC0tLS0tLS0tLS0tLS0gU2VydmVyU29ja2V0J3MgbWV0aG9kcyBvdmVycmlkaW5ncyAtLS0tLS0tLS0tLS0tLS0tCisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZhLm5ldC5TZXJ2ZXJTb2NrZXQjYWNjZXB0KCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTb2NrZXQgYWNjZXB0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiU1NMU2VydmVyU29ja2V0SW1wbC5hY2NlcHQgLi4iKTsKKyAgICAgICAgfQorICAgICAgICBTU0xTb2NrZXRJbXBsIHMgPSBuZXcgU1NMU29ja2V0SW1wbCgKKyAgICAgICAgICAgICAgICAoU1NMUGFyYW1ldGVyc0ltcGwpIHNzbFBhcmFtZXRlcnMuY2xvbmUoKSk7CisgICAgICAgIGltcGxBY2NlcHQocyk7CisgICAgICAgIHMuaW5pdCgpOworICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJTU0xTZXJ2ZXJTb2NrZXRJbXBsOiBhY2NlcHRlZCwgaW5pdGlhbGl6ZWQiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gIltTU0xTZXJ2ZXJTb2NrZXRJbXBsXSI7CisgICAgfQorCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTFNlc3Npb25JbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xTZXNzaW9uSW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI0N2M2ZWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xTZXNzaW9uSW1wbC5qYXZhCkBAIC0wLDAgKzEsMjI3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbkJpbmRpbmdFdmVudDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uQ29udGV4dDsKK2ltcG9ydCBsaWJjb3JlLnV0aWwuRW1wdHlBcnJheTsKKworcHVibGljIGZpbmFsIGNsYXNzIFNTTFNlc3Npb25JbXBsIGltcGxlbWVudHMgU1NMU2Vzc2lvbiwgQ2xvbmVhYmxlICB7CisKKyAgICAvKiogU2Vzc2lvbiBvYmplY3QgcmVwb3J0aW5nIGFuIGludmFsaWQgY2lwaGVyIHN1aXRlIG9mICJTU0xfTlVMTF9XSVRIX05VTExfTlVMTCIgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFNTTFNlc3Npb25JbXBsIE5VTExfU0VTU0lPTiA9IG5ldyBTU0xTZXNzaW9uSW1wbChudWxsKTsKKworICAgIHByaXZhdGUgbG9uZyBjcmVhdGlvblRpbWU7CisgICAgcHJpdmF0ZSBib29sZWFuIGlzVmFsaWQgPSB0cnVlOworICAgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgT2JqZWN0PiB2YWx1ZXMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIE9iamVjdD4oKTsKKworICAgIGJ5dGVbXSBpZDsKKyAgICBsb25nIGxhc3RBY2Nlc3NlZFRpbWU7CisgICAgUHJvdG9jb2xWZXJzaW9uIHByb3RvY29sOworICAgIENpcGhlclN1aXRlIGNpcGhlclN1aXRlOworICAgIFNTTFNlc3Npb25Db250ZXh0IGNvbnRleHQ7CisgICAgWDUwOUNlcnRpZmljYXRlW10gbG9jYWxDZXJ0aWZpY2F0ZXM7CisgICAgWDUwOUNlcnRpZmljYXRlW10gcGVlckNlcnRpZmljYXRlczsKKyAgICBwcml2YXRlIFN0cmluZyBwZWVySG9zdDsKKyAgICBwcml2YXRlIGludCBwZWVyUG9ydCA9IC0xOworICAgIGJ5dGVbXSBtYXN0ZXJfc2VjcmV0OworICAgIGJ5dGVbXSBjbGllbnRSYW5kb207CisgICAgYnl0ZVtdIHNlcnZlclJhbmRvbTsKKyAgICBmaW5hbCBib29sZWFuIGlzU2VydmVyOworCisgICAgcHVibGljIFNTTFNlc3Npb25JbXBsKENpcGhlclN1aXRlIGNpcGhlcl9zdWl0ZSwgU2VjdXJlUmFuZG9tIHNlY3VyZVJhbmRvbSkgeworICAgICAgICBjcmVhdGlvblRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgbGFzdEFjY2Vzc2VkVGltZSA9IGNyZWF0aW9uVGltZTsKKyAgICAgICAgaWYgKGNpcGhlcl9zdWl0ZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aGlzLmNpcGhlclN1aXRlID0gQ2lwaGVyU3VpdGUuU1NMX05VTExfV0lUSF9OVUxMX05VTEw7CisgICAgICAgICAgICBpZCA9IEVtcHR5QXJyYXkuQllURTsKKyAgICAgICAgICAgIGlzU2VydmVyID0gZmFsc2U7CisgICAgICAgICAgICBpc1ZhbGlkID0gZmFsc2U7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aGlzLmNpcGhlclN1aXRlID0gY2lwaGVyX3N1aXRlOworICAgICAgICAgICAgaWQgPSBuZXcgYnl0ZVszMl07CisgICAgICAgICAgICBzZWN1cmVSYW5kb20ubmV4dEJ5dGVzKGlkKTsKKyAgICAgICAgICAgIGxvbmcgdGltZSA9IGNyZWF0aW9uVGltZSAvIDEwMDA7CisgICAgICAgICAgICBpZFsyOF0gPSAoYnl0ZSkgKCh0aW1lICYgMHhGRjAwMDAwMCkgPj4+IDI0KTsKKyAgICAgICAgICAgIGlkWzI5XSA9IChieXRlKSAoKHRpbWUgJiAweDAwRkYwMDAwKSA+Pj4gMTYpOworICAgICAgICAgICAgaWRbMzBdID0gKGJ5dGUpICgodGltZSAmIDB4MDAwMEZGMDApID4+PiA4KTsKKyAgICAgICAgICAgIGlkWzMxXSA9IChieXRlKSAoKHRpbWUgJiAweDAwMDAwMEZGKSk7CisgICAgICAgICAgICBpc1NlcnZlciA9IHRydWU7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHB1YmxpYyBTU0xTZXNzaW9uSW1wbChTZWN1cmVSYW5kb20gc2VjdXJlUmFuZG9tKSB7CisgICAgICAgIHRoaXMobnVsbCwgc2VjdXJlUmFuZG9tKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldEFwcGxpY2F0aW9uQnVmZmVyU2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIFNTTFJlY29yZFByb3RvY29sLk1BWF9EQVRBX0xFTkdUSDsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldENpcGhlclN1aXRlKCkgeworICAgICAgICByZXR1cm4gY2lwaGVyU3VpdGUuZ2V0TmFtZSgpOworICAgIH0KKworICAgIHB1YmxpYyBsb25nIGdldENyZWF0aW9uVGltZSgpIHsKKyAgICAgICAgcmV0dXJuIGNyZWF0aW9uVGltZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldElkKCkgeworICAgICAgICByZXR1cm4gaWQ7CisgICAgfQorCisgICAgcHVibGljIGxvbmcgZ2V0TGFzdEFjY2Vzc2VkVGltZSgpIHsKKyAgICAgICAgcmV0dXJuIGxhc3RBY2Nlc3NlZFRpbWU7CisgICAgfQorCisgICAgcHVibGljIENlcnRpZmljYXRlW10gZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKSB7CisgICAgICAgIHJldHVybiBsb2NhbENlcnRpZmljYXRlczsKKyAgICB9CisKKyAgICBwdWJsaWMgUHJpbmNpcGFsIGdldExvY2FsUHJpbmNpcGFsKCkgeworICAgICAgICBpZiAobG9jYWxDZXJ0aWZpY2F0ZXMgIT0gbnVsbCAmJiBsb2NhbENlcnRpZmljYXRlcy5sZW5ndGggPiAwKSB7CisgICAgICAgICAgICByZXR1cm4gbG9jYWxDZXJ0aWZpY2F0ZXNbMF0uZ2V0U3ViamVjdFg1MDBQcmluY2lwYWwoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFBhY2tldEJ1ZmZlclNpemUoKSB7CisgICAgICAgIHJldHVybiBTU0xSZWNvcmRQcm90b2NvbC5NQVhfU1NMX1BBQ0tFVF9TSVpFOworICAgIH0KKworICAgIHB1YmxpYyBqYXZheC5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZVtdIGdldFBlZXJDZXJ0aWZpY2F0ZUNoYWluKCkKKyAgICAgICAgICAgIHRocm93cyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwZWVyQ2VydGlmaWNhdGVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbigiTm8gcGVlciBjZXJ0aWZpY2F0ZSIpOworICAgICAgICB9CisgICAgICAgIGphdmF4LnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlW10gY2VydHMgPSBuZXcgamF2YXguc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGVbcGVlckNlcnRpZmljYXRlcy5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNlcnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNlcnRzW2ldID0gamF2YXguc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGUuZ2V0SW5zdGFuY2UocGVlckNlcnRpZmljYXRlc1tpXQorICAgICAgICAgICAgICAgICAgICAgICAgLmdldEVuY29kZWQoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChqYXZheC5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBjZXJ0czsKKyAgICB9CisKKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVbXSBnZXRQZWVyQ2VydGlmaWNhdGVzKCkgdGhyb3dzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBlZXJDZXJ0aWZpY2F0ZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uKCJObyBwZWVyIGNlcnRpZmljYXRlIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHBlZXJDZXJ0aWZpY2F0ZXM7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRQZWVySG9zdCgpIHsKKyAgICAgICAgcmV0dXJuIHBlZXJIb3N0OworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0UGVlclBvcnQoKSB7CisgICAgICAgIHJldHVybiBwZWVyUG9ydDsKKyAgICB9CisKKyAgICBwdWJsaWMgUHJpbmNpcGFsIGdldFBlZXJQcmluY2lwYWwoKSB0aHJvd3MgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24geworICAgICAgICBpZiAocGVlckNlcnRpZmljYXRlcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24oIk5vIHBlZXIgY2VydGlmaWNhdGUiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcGVlckNlcnRpZmljYXRlc1swXS5nZXRTdWJqZWN0WDUwMFByaW5jaXBhbCgpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJvdG9jb2woKSB7CisgICAgICAgIHJldHVybiAocHJvdG9jb2wgPT0gbnVsbCkgPyAiTk9ORSIgOiBwcm90b2NvbC5uYW1lOworICAgIH0KKworICAgIHB1YmxpYyBTU0xTZXNzaW9uQ29udGV4dCBnZXRTZXNzaW9uQ29udGV4dCgpIHsKKyAgICAgICAgcmV0dXJuIGNvbnRleHQ7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRWYWx1ZShTdHJpbmcgbmFtZSkgeworICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJuYW1lID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdmFsdWVzLmdldChuYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0VmFsdWVOYW1lcygpIHsKKyAgICAgICAgcmV0dXJuIHZhbHVlcy5rZXlTZXQoKS50b0FycmF5KG5ldyBTdHJpbmdbdmFsdWVzLnNpemUoKV0pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGludmFsaWRhdGUoKSB7CisgICAgICAgIGlzVmFsaWQgPSBmYWxzZTsKKyAgICAgICAgY29udGV4dCA9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNWYWxpZCgpIHsKKyAgICAgICAgaWYgKGlzVmFsaWQgJiYgY29udGV4dCAhPSBudWxsICYmIGNvbnRleHQuZ2V0U2Vzc2lvblRpbWVvdXQoKSAhPSAwCisgICAgICAgICAgICAgICAgJiYgbGFzdEFjY2Vzc2VkVGltZSArIGNvbnRleHQuZ2V0U2Vzc2lvblRpbWVvdXQoKSA+IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKSB7CisgICAgICAgICAgICBpc1ZhbGlkID0gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGlzVmFsaWQ7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcHV0VmFsdWUoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICBpZiAobmFtZSA9PSBudWxsIHx8IHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm5hbWUgPT0gbnVsbCB8fCB2YWx1ZSA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgT2JqZWN0IG9sZCA9IHZhbHVlcy5wdXQobmFtZSwgdmFsdWUpOworICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBTU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyKSB7CisgICAgICAgICAgICAoKFNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXIpIHZhbHVlKS52YWx1ZUJvdW5kKG5ldyBTU0xTZXNzaW9uQmluZGluZ0V2ZW50KHRoaXMsIG5hbWUpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2xkIGluc3RhbmNlb2YgU1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lcikgeworICAgICAgICAgICAgKChTU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyKSBvbGQpLnZhbHVlVW5ib3VuZChuZXcgU1NMU2Vzc2lvbkJpbmRpbmdFdmVudCh0aGlzLCBuYW1lKSk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlbW92ZVZhbHVlKFN0cmluZyBuYW1lKSB7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm5hbWUgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIE9iamVjdCBvbGQgPSB2YWx1ZXMucmVtb3ZlKG5hbWUpOworICAgICAgICBpZiAob2xkIGluc3RhbmNlb2YgU1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lcikgeworICAgICAgICAgICAgU1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lciBsaXN0ZW5lciA9IChTU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyKSBvbGQ7CisgICAgICAgICAgICBsaXN0ZW5lci52YWx1ZVVuYm91bmQobmV3IFNTTFNlc3Npb25CaW5kaW5nRXZlbnQodGhpcywgbmFtZSkpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICB2b2lkIHNldFBlZXIoU3RyaW5nIHBlZXJIb3N0LCBpbnQgcGVlclBvcnQpIHsKKyAgICAgICAgdGhpcy5wZWVySG9zdCA9IHBlZXJIb3N0OworICAgICAgICB0aGlzLnBlZXJQb3J0ID0gcGVlclBvcnQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMU29ja2V0RmFjdG9yeUltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTFNvY2tldEZhY3RvcnlJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmU5YTdmYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTFNvY2tldEZhY3RvcnlJbXBsLmphdmEKQEAgLTAsMCArMSwxNjIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0OworaW1wb3J0IGphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5TWFuYWdlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3Rvcnk7CitpbXBvcnQgbGliY29yZS51dGlsLkVtcHR5QXJyYXk7CisKKy8qKgorICogSW1wbGVtZW50YXRpb24gb2YgU1NMU29ja2V0RmFjdG9yeS4KKyAqLworcHVibGljIGNsYXNzIFNTTFNvY2tldEZhY3RvcnlJbXBsIGV4dGVuZHMgU1NMU29ja2V0RmFjdG9yeSB7CisKKyAgICBwcml2YXRlIGZpbmFsIFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnM7CisgICAgcHJpdmF0ZSBmaW5hbCBJT0V4Y2VwdGlvbiBpbnN0YW50aWF0aW9uRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICovCisgICAgcHVibGljIFNTTFNvY2tldEZhY3RvcnlJbXBsKCkgeworICAgICAgICBTU0xQYXJhbWV0ZXJzSW1wbCBzc2xQYXJhbWV0ZXJzTG9jYWwgPSBudWxsOworICAgICAgICBJT0V4Y2VwdGlvbiBpbnN0YW50aWF0aW9uRXhjZXB0aW9uTG9jYWwgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NsUGFyYW1ldGVyc0xvY2FsID0gU1NMUGFyYW1ldGVyc0ltcGwuZ2V0RGVmYXVsdCgpOworICAgICAgICB9IGNhdGNoIChLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGluc3RhbnRpYXRpb25FeGNlcHRpb25Mb2NhbCA9IG5ldyBJT0V4Y2VwdGlvbigiRGVsYXllZCBpbnN0YW50aWF0aW9uIGV4Y2VwdGlvbjoiKTsKKyAgICAgICAgICAgIGluc3RhbnRpYXRpb25FeGNlcHRpb25Mb2NhbC5pbml0Q2F1c2UoZSk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zc2xQYXJhbWV0ZXJzID0gc3NsUGFyYW1ldGVyc0xvY2FsOworICAgICAgICB0aGlzLmluc3RhbnRpYXRpb25FeGNlcHRpb24gPSBpbnN0YW50aWF0aW9uRXhjZXB0aW9uTG9jYWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNTTFNvY2tldEZhY3RvcnlJbXBsKFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnMpIHsKKyAgICAgICAgdGhpcy5zc2xQYXJhbWV0ZXJzID0gc3NsUGFyYW1ldGVyczsKKyAgICAgICAgdGhpcy5pbnN0YW50aWF0aW9uRXhjZXB0aW9uID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0RmFjdG9yeSNnZXREZWZhdWx0Q2lwaGVyU3VpdGVzKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgaWYgKGluc3RhbnRpYXRpb25FeGNlcHRpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIEVtcHR5QXJyYXkuU1RSSU5HOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzc2xQYXJhbWV0ZXJzLmdldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0RmFjdG9yeSNnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSB7CisgICAgICAgIGlmIChpbnN0YW50aWF0aW9uRXhjZXB0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBFbXB0eUFycmF5LlNUUklORzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gQ2lwaGVyU3VpdGUuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVOYW1lcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTb2NrZXRGYWN0b3J5I2NyZWF0ZVNvY2tldChTb2NrZXQsU3RyaW5nLGludCxib29sZWFuKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KFNvY2tldCBzLCBTdHJpbmcgaG9zdCwgaW50IHBvcnQsCisgICAgICAgICAgICBib29sZWFuIGF1dG9DbG9zZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluc3RhbnRpYXRpb25FeGNlcHRpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgaW5zdGFudGlhdGlvbkV4Y2VwdGlvbjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFNTTFNvY2tldFdyYXBwZXIocywgYXV0b0Nsb3NlLCAoU1NMUGFyYW1ldGVyc0ltcGwpIHNzbFBhcmFtZXRlcnMKKyAgICAgICAgICAgICAgICAuY2xvbmUoKSk7CisgICAgfQorCisgICAgLy8gLS0tLS0tLS0tLS0tLS0gTWV0aG9kcyBpbmhlcmlkZWQgZnJvbSBTb2NrZXRGYWN0b3J5IC0tLS0tLS0tLS0tLS0tCisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5I2NyZWF0ZVNvY2tldCgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaW5zdGFudGlhdGlvbkV4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBpbnN0YW50aWF0aW9uRXhjZXB0aW9uOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU1NMU29ja2V0SW1wbCgoU1NMUGFyYW1ldGVyc0ltcGwpIHNzbFBhcmFtZXRlcnMuY2xvbmUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZheC5uZXQuU29ja2V0RmFjdG9yeSNjcmVhdGVTb2NrZXQoU3RyaW5nLGludCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldChTdHJpbmcgaG9zdCwgaW50IHBvcnQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluc3RhbnRpYXRpb25FeGNlcHRpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgaW5zdGFudGlhdGlvbkV4Y2VwdGlvbjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFNTTFNvY2tldEltcGwoaG9zdCwgcG9ydCwKKyAgICAgICAgICAgICAgICAoU1NMUGFyYW1ldGVyc0ltcGwpIHNzbFBhcmFtZXRlcnMuY2xvbmUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZheC5uZXQuU29ja2V0RmFjdG9yeSNjcmVhdGVTb2NrZXQoU3RyaW5nLGludCxJbmV0QWRkcmVzcyxpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoU3RyaW5nIGhvc3QsIGludCBwb3J0LAorICAgICAgICAgICAgSW5ldEFkZHJlc3MgbG9jYWxIb3N0LCBpbnQgbG9jYWxQb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgICAgICBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpbnN0YW50aWF0aW9uRXhjZXB0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IGluc3RhbnRpYXRpb25FeGNlcHRpb247CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBTU0xTb2NrZXRJbXBsKGhvc3QsIHBvcnQsIGxvY2FsSG9zdCwgbG9jYWxQb3J0LAorICAgICAgICAgICAgICAgIChTU0xQYXJhbWV0ZXJzSW1wbCkgc3NsUGFyYW1ldGVycy5jbG9uZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5I2NyZWF0ZVNvY2tldChJbmV0QWRkcmVzcyxpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MgaG9zdCwgaW50IHBvcnQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaW5zdGFudGlhdGlvbkV4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBpbnN0YW50aWF0aW9uRXhjZXB0aW9uOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU1NMU29ja2V0SW1wbChob3N0LCBwb3J0LAorICAgICAgICAgICAgICAgIChTU0xQYXJhbWV0ZXJzSW1wbCkgc3NsUGFyYW1ldGVycy5jbG9uZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5I2NyZWF0ZVNvY2tldChJbmV0QWRkcmVzcyxpbnQsSW5ldEFkZHJlc3MsaW50KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzIGFkZHJlc3MsIGludCBwb3J0LAorICAgICAgICAgICAgSW5ldEFkZHJlc3MgbG9jYWxBZGRyZXNzLCBpbnQgbG9jYWxQb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaW5zdGFudGlhdGlvbkV4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBpbnN0YW50aWF0aW9uRXhjZXB0aW9uOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU1NMU29ja2V0SW1wbChhZGRyZXNzLCBwb3J0LCBsb2NhbEFkZHJlc3MsIGxvY2FsUG9ydCwKKyAgICAgICAgICAgICAgICAoU1NMUGFyYW1ldGVyc0ltcGwpIHNzbFBhcmFtZXRlcnMuY2xvbmUoKSk7CisgICAgfQorCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xTb2NrZXRJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xTb2NrZXRJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmU1ZmRkZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTFNvY2tldEltcGwuamF2YQpAQCAtMCwwICsxLDgxMCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YXgubmV0LnNzbC5IYW5kc2hha2VDb21wbGV0ZWRFdmVudDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLkhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lUmVzdWx0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldDsKKworLyoqCisgKiBTU0xTb2NrZXQgaW1wbGVtZW50YXRpb24uCisgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0IGNsYXNzIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24uCisgKi8KK3B1YmxpYyBjbGFzcyBTU0xTb2NrZXRJbXBsIGV4dGVuZHMgU1NMU29ja2V0IHsKKworICAgIC8vIGluZGljYXRlcyBpZiBoYW5kc2hha2UgaGFzIGJlZW4gc3RhcnRlZAorICAgIHByaXZhdGUgYm9vbGVhbiBoYW5kc2hha2Vfc3RhcnRlZCA9IGZhbHNlOworCisgICAgLy8gcmVjb3JkIHByb3RvY29sIHRvIGJlIHVzZWQKKyAgICBwcm90ZWN0ZWQgU1NMUmVjb3JkUHJvdG9jb2wgcmVjb3JkUHJvdG9jb2w7CisgICAgLy8gaGFuZHNoYWtlIHByb3RvY29sIHRvIGJlIHVzZWQKKyAgICBwcml2YXRlIEhhbmRzaGFrZVByb3RvY29sIGhhbmRzaGFrZVByb3RvY29sOworICAgIC8vIGFsZXJ0IHByb3RvY29sIHRvIGJlIHVzZWQKKyAgICBwcml2YXRlIEFsZXJ0UHJvdG9jb2wgYWxlcnRQcm90b2NvbDsKKyAgICAvLyBhcHBsaWNhdGlvbiBkYXRhIGlucHV0IHN0cmVhbSwgdGhpcyBzdHJlYW0gaXMgcHJlc2VudGVkIGJ5CisgICAgLy8gc3NsIHNvY2tldCBhcyBhbiBpbnB1dCBzdHJlYW0uIEFkZGl0aW9uYWxseSB0aGlzIG9iamVjdCBpcyBhCisgICAgLy8gcGxhY2Ugd2hlcmUgYXBwbGljYXRpb24gZGF0YSB3aWxsIGJlIHN0b3JlZCBieSByZWNvcmQgcHJvdG9jb2wKKyAgICBwcml2YXRlIFNTTFNvY2tldElucHV0U3RyZWFtIGFwcERhdGFJUzsKKyAgICAvLyBvdXRnb2luZyBhcHBsaWNhdGlvbiBkYXRhIHN0cmVhbQorICAgIHByaXZhdGUgU1NMU29ja2V0T3V0cHV0U3RyZWFtIGFwcERhdGFPUzsKKyAgICAvLyBhY3RpdmUgc2Vzc2lvbiBvYmplY3QKKyAgICBwcml2YXRlIFNTTFNlc3Npb25JbXBsIHNlc3Npb247CisKKyAgICBwcml2YXRlIGJvb2xlYW4gc29ja2V0X3dhc19jbG9zZWQgPSBmYWxzZTsKKworICAgIC8vIHRoZSBzc2xQYXJhbWV0ZXJzIG9iamVjdCBlbmNhcHN1bGF0ZXMgYWxsIHRoZSBpbmZvCisgICAgLy8gYWJvdXQgc3VwcG9ydGVkIGFuZCBlbmFibGVkIGNpcGhlciBzdWl0ZXMgYW5kIHByb3RvY29scywKKyAgICAvLyBhcyB3ZWxsIGFzIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBjbGllbnQvc2VydmVyIG1vZGUgb2YKKyAgICAvLyBzc2wgc29ja2V0LCB3aGV0aGVyIGl0IHJlcXVpcmUvd2FudCBjbGllbnQgYXV0aGVudGljYXRpb24gb3Igbm90LAorICAgIC8vIGFuZCBjb250cm9scyB3aGV0aGVyIG5ldyBTU0wgc2Vzc2lvbnMgbWF5IGJlIGVzdGFibGlzaGVkIGJ5IHRoaXMKKyAgICAvLyBzb2NrZXQgb3Igbm90LgorICAgIHByb3RlY3RlZCBTU0xQYXJhbWV0ZXJzSW1wbCBzc2xQYXJhbWV0ZXJzOworICAgIC8vIHN1cGVyJ3Mgc3RyZWFtcyB0byBiZSB3cmFwcGVkOgorICAgIHByb3RlY3RlZCBJbnB1dFN0cmVhbSBpbnB1dDsKKyAgICBwcm90ZWN0ZWQgT3V0cHV0U3RyZWFtIG91dHB1dDsKKyAgICAvLyBoYW5kc2hha2UgY29tcGxldGUgbGlzdGVuZXJzCisgICAgcHJpdmF0ZSBBcnJheUxpc3Q8SGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXI+IGxpc3RlbmVyczsKKyAgICAvLyBsb2dnZXIKKyAgICBwcml2YXRlIExvZ2dlci5TdHJlYW0gbG9nZ2VyID0gTG9nZ2VyLmdldFN0cmVhbSgic29ja2V0Iik7CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLSBDb25zdHJ1Y3RvcnMgYW5kIGluaXRpYWxpemVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IKKyAgICAgKiBAcGFyYW0gICBzc2xQYXJhbWV0ZXJzOiAgU1NMUGFyYW1ldGVyc0ltcGwKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0I1NTTFNvY2tldCgpIG1ldGhvZCBkb2N1bWVudGF0aW9uCisgICAgICogZm9yIG1vcmUgaW5mb3JtYXRpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIFNTTFNvY2tldEltcGwoU1NMUGFyYW1ldGVyc0ltcGwgc3NsUGFyYW1ldGVycykgeworICAgICAgICB0aGlzLnNzbFBhcmFtZXRlcnMgPSBzc2xQYXJhbWV0ZXJzOworICAgICAgICAvLyBpbml0IHNob3VsZCBiZSBjYWxsZWQgYWZ0ZXIgY3JlYXRpb24hCisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IKKyAgICAgKiBAcGFyYW0gICBob3N0OiAgIFN0cmluZworICAgICAqIEBwYXJhbSAgIHBvcnQ6ICAgaW50CisgICAgICogQHBhcmFtICAgc3NsUGFyYW1ldGVyczogIFNTTFBhcmFtZXRlcnNJbXBsCisgICAgICogQHRocm93cyAgSU9FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzICBVbmtub3duSG9zdEV4Y2VwdGlvbgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjU1NMU29ja2V0KFN0cmluZyxpbnQpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIFNTTFNvY2tldEltcGwoU3RyaW5nIGhvc3QsIGludCBwb3J0LCBTU0xQYXJhbWV0ZXJzSW1wbCBzc2xQYXJhbWV0ZXJzKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKGhvc3QsIHBvcnQpOworICAgICAgICB0aGlzLnNzbFBhcmFtZXRlcnMgPSBzc2xQYXJhbWV0ZXJzOworICAgICAgICBpbml0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IKKyAgICAgKiBAcGFyYW0gICBob3N0OiAgIFN0cmluZworICAgICAqIEBwYXJhbSAgIHBvcnQ6ICAgaW50CisgICAgICogQHBhcmFtICAgbG9jYWxIb3N0OiAgSW5ldEFkZHJlc3MKKyAgICAgKiBAcGFyYW0gICBsb2NhbFBvcnQ6ICBpbnQKKyAgICAgKiBAcGFyYW0gICBzc2xQYXJhbWV0ZXJzOiAgU1NMUGFyYW1ldGVyc0ltcGwKKyAgICAgKiBAdGhyb3dzICBJT0V4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgIFVua25vd25Ib3N0RXhjZXB0aW9uCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNTU0xTb2NrZXQoU3RyaW5nLGludCxJbmV0QWRkcmVzcyxpbnQpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIFNTTFNvY2tldEltcGwoU3RyaW5nIGhvc3QsIGludCBwb3J0LAorICAgICAgICAgICAgSW5ldEFkZHJlc3MgbG9jYWxIb3N0LCBpbnQgbG9jYWxQb3J0LAorICAgICAgICAgICAgU1NMUGFyYW1ldGVyc0ltcGwgc3NsUGFyYW1ldGVycykgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgVW5rbm93bkhvc3RFeGNlcHRpb24geworICAgICAgICBzdXBlcihob3N0LCBwb3J0LCBsb2NhbEhvc3QsIGxvY2FsUG9ydCk7CisgICAgICAgIHRoaXMuc3NsUGFyYW1ldGVycyA9IHNzbFBhcmFtZXRlcnM7CisgICAgICAgIGluaXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvcgorICAgICAqIEBwYXJhbSAgIGhvc3Q6ICAgSW5ldEFkZHJlc3MKKyAgICAgKiBAcGFyYW0gICBwb3J0OiAgIGludAorICAgICAqIEBwYXJhbSAgIHNzbFBhcmFtZXRlcnM6ICBTU0xQYXJhbWV0ZXJzSW1wbAorICAgICAqIEByZXR1cm4KKyAgICAgKiBAdGhyb3dzICBJT0V4Y2VwdGlvbgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjU1NMU29ja2V0KEluZXRBZGRyZXNzLGludCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU1NMU29ja2V0SW1wbChJbmV0QWRkcmVzcyBob3N0LCBpbnQgcG9ydCwKKyAgICAgICAgICAgIFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKGhvc3QsIHBvcnQpOworICAgICAgICB0aGlzLnNzbFBhcmFtZXRlcnMgPSBzc2xQYXJhbWV0ZXJzOworICAgICAgICBpbml0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IKKyAgICAgKiBAcGFyYW0gICBhZGRyZXNzOiAgICBJbmV0QWRkcmVzcworICAgICAqIEBwYXJhbSAgIHBvcnQ6ICAgaW50CisgICAgICogQHBhcmFtICAgbG9jYWxBZGRyZXNzOiAgIEluZXRBZGRyZXNzCisgICAgICogQHBhcmFtICAgbG9jYWxQb3J0OiAgaW50CisgICAgICogQHBhcmFtICAgc3NsUGFyYW1ldGVyczogIFNTTFBhcmFtZXRlcnNJbXBsCisgICAgICogQHJldHVybgorICAgICAqIEB0aHJvd3MgIElPRXhjZXB0aW9uCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNTU0xTb2NrZXQoSW5ldEFkZHJlc3MsaW50LEluZXRBZGRyZXNzLGludCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU1NMU29ja2V0SW1wbChJbmV0QWRkcmVzcyBhZGRyZXNzLCBpbnQgcG9ydCwKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIGxvY2FsQWRkcmVzcywgaW50IGxvY2FsUG9ydCwKKyAgICAgICAgICAgIFNTTFBhcmFtZXRlcnNJbXBsIHNzbFBhcmFtZXRlcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKGFkZHJlc3MsIHBvcnQsIGxvY2FsQWRkcmVzcywgbG9jYWxQb3J0KTsKKyAgICAgICAgdGhpcy5zc2xQYXJhbWV0ZXJzID0gc3NsUGFyYW1ldGVyczsKKyAgICAgICAgaW5pdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemUgdGhlIFNTTCBzb2NrZXQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgaW5pdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhcHBEYXRhSVMgIT0gbnVsbCkgeworICAgICAgICAgICAgLy8gYWxyZWFkeSBpbml0aWFsaXplZAorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGluaXRUcmFuc3BvcnRMYXllcigpOworICAgICAgICBhcHBEYXRhSVMgPSBuZXcgU1NMU29ja2V0SW5wdXRTdHJlYW0odGhpcyk7CisgICAgICAgIGFwcERhdGFPUyA9IG5ldyBTU0xTb2NrZXRPdXRwdXRTdHJlYW0odGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZSB0aGUgdHJhbnNwb3J0IGRhdGEgc3RyZWFtcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBpbml0VHJhbnNwb3J0TGF5ZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnB1dCA9IHN1cGVyLmdldElucHV0U3RyZWFtKCk7CisgICAgICAgIG91dHB1dCA9IHN1cGVyLmdldE91dHB1dFN0cmVhbSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlcyB0aGUgdHJhbnNwb3J0IGRhdGEgc3RyZWFtcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBjbG9zZVRyYW5zcG9ydExheWVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuY2xvc2UoKTsKKyAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlucHV0LmNsb3NlKCk7CisgICAgICAgICAgICBvdXRwdXQuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLSBTU0xQYXJhbWV0ZXJzIGJhc2VkIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ1tdIGdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgcmV0dXJuIENpcGhlclN1aXRlLmdldFN1cHBvcnRlZENpcGhlclN1aXRlTmFtZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNnZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCkgeworICAgICAgICByZXR1cm4gc3NsUGFyYW1ldGVycy5nZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjc2V0RW5hYmxlZENpcGhlclN1aXRlcyhTdHJpbmdbXSkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoU3RyaW5nW10gc3VpdGVzKSB7CisgICAgICAgIHNzbFBhcmFtZXRlcnMuc2V0RW5hYmxlZENpcGhlclN1aXRlcyhzdWl0ZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0I2dldFN1cHBvcnRlZFByb3RvY29scygpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0U3VwcG9ydGVkUHJvdG9jb2xzKCkgeworICAgICAgICByZXR1cm4gUHJvdG9jb2xWZXJzaW9uLnN1cHBvcnRlZFByb3RvY29scy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0I2dldEVuYWJsZWRQcm90b2NvbHMoKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ1tdIGdldEVuYWJsZWRQcm90b2NvbHMoKSB7CisgICAgICAgIHJldHVybiBzc2xQYXJhbWV0ZXJzLmdldEVuYWJsZWRQcm90b2NvbHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNzZXRFbmFibGVkUHJvdG9jb2xzKFN0cmluZ1tdKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RW5hYmxlZFByb3RvY29scyhTdHJpbmdbXSBwcm90b2NvbHMpIHsKKyAgICAgICAgc3NsUGFyYW1ldGVycy5zZXRFbmFibGVkUHJvdG9jb2xzKHByb3RvY29scyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjc2V0VXNlQ2xpZW50TW9kZShib29sZWFuKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0VXNlQ2xpZW50TW9kZShib29sZWFuIG1vZGUpIHsKKyAgICAgICAgaWYgKGhhbmRzaGFrZV9zdGFydGVkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgIkNvdWxkIG5vdCBjaGFuZ2UgdGhlIG1vZGUgYWZ0ZXIgdGhlIGluaXRpYWwgaGFuZHNoYWtlIGhhcyBiZWd1bi4iKTsKKyAgICAgICAgfQorICAgICAgICBzc2xQYXJhbWV0ZXJzLnNldFVzZUNsaWVudE1vZGUobW9kZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjZ2V0VXNlQ2xpZW50TW9kZSgpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRVc2VDbGllbnRNb2RlKCkgeworICAgICAgICByZXR1cm4gc3NsUGFyYW1ldGVycy5nZXRVc2VDbGllbnRNb2RlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjc2V0TmVlZENsaWVudEF1dGgoYm9vbGVhbikKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldE5lZWRDbGllbnRBdXRoKGJvb2xlYW4gbmVlZCkgeworICAgICAgICBzc2xQYXJhbWV0ZXJzLnNldE5lZWRDbGllbnRBdXRoKG5lZWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0I2dldE5lZWRDbGllbnRBdXRoKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGdldE5lZWRDbGllbnRBdXRoKCkgeworICAgICAgICByZXR1cm4gc3NsUGFyYW1ldGVycy5nZXROZWVkQ2xpZW50QXV0aCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0I3NldFdhbnRDbGllbnRBdXRoKGJvb2xlYW4pCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRXYW50Q2xpZW50QXV0aChib29sZWFuIHdhbnQpIHsKKyAgICAgICAgc3NsUGFyYW1ldGVycy5zZXRXYW50Q2xpZW50QXV0aCh3YW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNnZXRXYW50Q2xpZW50QXV0aCgpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRXYW50Q2xpZW50QXV0aCgpIHsKKyAgICAgICAgcmV0dXJuIHNzbFBhcmFtZXRlcnMuZ2V0V2FudENsaWVudEF1dGgoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNzZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oYm9vbGVhbikKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEVuYWJsZVNlc3Npb25DcmVhdGlvbihib29sZWFuIGZsYWcpIHsKKyAgICAgICAgc3NsUGFyYW1ldGVycy5zZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oZmxhZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGdldEVuYWJsZVNlc3Npb25DcmVhdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIHNzbFBhcmFtZXRlcnMuZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCk7CisgICAgfQorCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0I2dldFNlc3Npb24oKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNTTFNlc3Npb24gZ2V0U2Vzc2lvbigpIHsKKyAgICAgICAgaWYgKCFoYW5kc2hha2Vfc3RhcnRlZCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdGFydEhhbmRzaGFrZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIHJldHVybiBhbiBpbnZhbGlkIHNlc3Npb24gd2l0aAorICAgICAgICAgICAgICAgIC8vIGludmFsaWQgY2lwaGVyIHN1aXRlIG9mICJTU0xfTlVMTF9XSVRIX05VTExfTlVMTCIKKyAgICAgICAgICAgICAgICByZXR1cm4gU1NMU2Vzc2lvbkltcGwuTlVMTF9TRVNTSU9OOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBzZXNzaW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0I2FkZEhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyKEhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYWRkSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXIoCisgICAgICAgICAgICBIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lciBsaXN0ZW5lcikgeworICAgICAgICBpZiAobGlzdGVuZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiUHJvdmlkZWQgbGlzdGVuZXIgaXMgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChsaXN0ZW5lcnMgPT0gbnVsbCkgeworICAgICAgICAgICAgbGlzdGVuZXJzID0gbmV3IEFycmF5TGlzdDxIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lcj4oKTsKKyAgICAgICAgfQorICAgICAgICBsaXN0ZW5lcnMuYWRkKGxpc3RlbmVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNyZW1vdmVIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lcihIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lcikKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJlbW92ZUhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyKAorICAgICAgICAgICAgSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXIgbGlzdGVuZXIpIHsKKyAgICAgICAgaWYgKGxpc3RlbmVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlByb3ZpZGVkIGxpc3RlbmVyIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobGlzdGVuZXJzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJQcm92aWRlZCBsaXN0ZW5lciBpcyBub3QgcmVnaXN0ZXJlZCIpOworICAgICAgICB9CisgICAgICAgIGlmICghbGlzdGVuZXJzLnJlbW92ZShsaXN0ZW5lcikpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJQcm92aWRlZCBsaXN0ZW5lciBpcyBub3QgcmVnaXN0ZXJlZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgdGhlIGhhbmRzaGFrZSBwcm9jZXNzIG92ZXIgdGhlIFNTTC9UTFMgY29ubmVjdGlvbgorICAgICAqIGFzIGRlc2NyaWJlZCBpbiByZmMgMjI0NiwgVExTIHYxIHNwZWNpZmljYXRpb24KKyAgICAgKiBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMjQ2LnR4dC4gSWYgdGhlIGluaXRpYWwgaGFuZHNoYWtlCisgICAgICogaGFzIGJlZW4gYWxyZWFkeSBkb25lLCB0aGlzIG1ldGhvZCBpbml0aWF0ZXMgcmVoYW5kc2hha2UuCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjc3RhcnRIYW5kc2hha2UoKQorICAgICAqIG1ldGhvZCBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc3RhcnRIYW5kc2hha2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoYXBwRGF0YUlTID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU29ja2V0IGlzIG5vdCBjb25uZWN0ZWQuIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNvY2tldF93YXNfY2xvc2VkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlNvY2tldCBoYXMgYWxyZWFkeSBiZWVuIGNsb3NlZC4iKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghaGFuZHNoYWtlX3N0YXJ0ZWQpIHsKKyAgICAgICAgICAgIGhhbmRzaGFrZV9zdGFydGVkID0gdHJ1ZTsKKyAgICAgICAgICAgIGlmIChzc2xQYXJhbWV0ZXJzLmdldFVzZUNsaWVudE1vZGUoKSkgeworICAgICAgICAgICAgICAgIGlmIChsb2dnZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiU1NMU29ja2V0SW1wbDogQ0xJRU5UIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGhhbmRzaGFrZVByb3RvY29sID0gbmV3IENsaWVudEhhbmRzaGFrZUltcGwodGhpcyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmIChsb2dnZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiU1NMU29ja2V0SW1wbDogU0VSVkVSIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGhhbmRzaGFrZVByb3RvY29sID0gbmV3IFNlcnZlckhhbmRzaGFrZUltcGwodGhpcyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGFsZXJ0UHJvdG9jb2wgPSBuZXcgQWxlcnRQcm90b2NvbCgpOworICAgICAgICAgICAgcmVjb3JkUHJvdG9jb2wgPSBuZXcgU1NMUmVjb3JkUHJvdG9jb2woaGFuZHNoYWtlUHJvdG9jb2wsCisgICAgICAgICAgICAgICAgICAgIGFsZXJ0UHJvdG9jb2wsIG5ldyBTU0xTdHJlYW1lZElucHV0KGlucHV0KSwKKyAgICAgICAgICAgICAgICAgICAgYXBwRGF0YUlTLmRhdGFQb2ludCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJTU0xTb2NrZXRJbXBsLnN0YXJ0SGFuZHNoYWtlIik7CisgICAgICAgIH0KKworICAgICAgICBoYW5kc2hha2VQcm90b2NvbC5zdGFydCgpOworCisgICAgICAgIGRvSGFuZHNoYWtlKCk7CisKKyAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiU1NMU29ja2V0SW1wbC5zdGFydEhhbmRzaGFrZTogRU5EIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNnZXRJbnB1dFN0cmVhbSgpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoc29ja2V0X3dhc19jbG9zZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU29ja2V0IGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkLiIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBhcHBEYXRhSVM7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjZ2V0T3V0cHV0U3RyZWFtKCkKKyAgICAgKiBtZXRob2QgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNvY2tldF93YXNfY2xvc2VkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlNvY2tldCBoYXMgYWxyZWFkeSBiZWVuIGNsb3NlZC4iKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYXBwRGF0YU9TOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBvZiBpbXBsZW1lbnRlZCBjbGFzcy4KKyAgICAgKiBAc2VlIGphdmEubmV0LlNvY2tldCNjb25uZWN0KFNvY2tldEFkZHJlc3MpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjb25uZWN0KFNvY2tldEFkZHJlc3MgZW5kcG9pbnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLmNvbm5lY3QoZW5kcG9pbnQpOworICAgICAgICBpbml0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3MgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGltcGxlbWVudGVkIGNsYXNzLgorICAgICAqIEBzZWUgamF2YS5uZXQuU29ja2V0I2Nvbm5lY3QoU29ja2V0QWRkcmVzcyxpbnQpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjb25uZWN0KFNvY2tldEFkZHJlc3MgZW5kcG9pbnQsIGludCB0aW1lb3V0KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuY29ubmVjdChlbmRwb2ludCwgdGltZW91dCk7CisgICAgICAgIGluaXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YgaW1wbGVtZW50ZWQgY2xhc3MuCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNjbG9zZSgpCisgICAgICogbWV0aG9kIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChsb2dnZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oIlNTTFNvY2tldC5jbG9zZSAiK3NvY2tldF93YXNfY2xvc2VkKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXNvY2tldF93YXNfY2xvc2VkKSB7CisgICAgICAgICAgICBpZiAoaGFuZHNoYWtlX3N0YXJ0ZWQpIHsKKyAgICAgICAgICAgICAgICBhbGVydFByb3RvY29sLmFsZXJ0KEFsZXJ0UHJvdG9jb2wuV0FSTklORywKKyAgICAgICAgICAgICAgICAgICAgICAgIEFsZXJ0UHJvdG9jb2wuQ0xPU0VfTk9USUZZKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGUoYWxlcnRQcm90b2NvbC53cmFwKCkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7IH0KKyAgICAgICAgICAgICAgICBhbGVydFByb3RvY29sLnNldFByb2Nlc3NlZCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2h1dGRvd24oKTsKKyAgICAgICAgICAgIGNsb3NlVHJhbnNwb3J0TGF5ZXIoKTsKKyAgICAgICAgICAgIHNvY2tldF93YXNfY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIFNTTFNvY2tldCBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZW5kVXJnZW50RGF0YShpbnQgZGF0YSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFNvY2tldEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiTWV0aG9kIHNlbmRVcmdlbnREYXRhKCkgaXMgbm90IHN1cHBvcnRlZC4iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBub3Qgc3VwcG9ydGVkIGZvciBTU0xTb2NrZXQgaW1wbGVtZW50YXRpb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0T09CSW5saW5lKGJvb2xlYW4gb24pIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgU29ja2V0RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJNZXRob2RzIHNlbmRVcmdlbnREYXRhLCBzZXRPT0JJbmxpbmUgYXJlIG5vdCBzdXBwb3J0ZWQuIik7CisgICAgfQorCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIHByaXZhdGUgdm9pZCBzaHV0ZG93bigpIHsKKyAgICAgICAgaWYgKGhhbmRzaGFrZV9zdGFydGVkKSB7CisgICAgICAgICAgICBhbGVydFByb3RvY29sLnNodXRkb3duKCk7CisgICAgICAgICAgICBhbGVydFByb3RvY29sID0gbnVsbDsKKyAgICAgICAgICAgIGhhbmRzaGFrZVByb3RvY29sLnNodXRkb3duKCk7CisgICAgICAgICAgICBoYW5kc2hha2VQcm90b2NvbCA9IG51bGw7CisgICAgICAgICAgICByZWNvcmRQcm90b2NvbC5zaHV0ZG93bigpOworICAgICAgICAgICAgcmVjb3JkUHJvdG9jb2wgPSBudWxsOworICAgICAgICB9CisgICAgICAgIHNvY2tldF93YXNfY2xvc2VkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgU1NMU29ja2V0SW5wdXRTdHJlYW0gY2xhc3MKKyAgICAgKiB3aGVuIGNsaWVudCBhcHBsaWNhdGlvbiB0cmllcyB0byByZWFkIGFwcGxpY2F0aW9uIGRhdGEgZnJvbQorICAgICAqIHRoZSBzdHJlYW0sIGJ1dCB0aGVyZSBpcyBubyBkYXRhIGluIGl0cyB1bmRlcmx5aW5nIGJ1ZmZlci4KKyAgICAgKiBAdGhyb3dzICBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIG5lZWRBcHBEYXRhKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFoYW5kc2hha2Vfc3RhcnRlZCkgeworICAgICAgICAgICAgc3RhcnRIYW5kc2hha2UoKTsKKyAgICAgICAgfQorICAgICAgICBpbnQgdHlwZTsKKyAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiU1NMU29ja2V0Lm5lZWRBcHBEYXRhLi4iKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgd2hpbGUoYXBwRGF0YUlTLmF2YWlsYWJsZSgpID09IDApIHsKKyAgICAgICAgICAgICAgICAvLyByZWFkIGFuZCB1bndyYXAgdGhlIHJlY29yZCBjb250YWluZWQgaW4gdGhlIHRyYW5zcG9ydAorICAgICAgICAgICAgICAgIC8vIGlucHV0IHN0cmVhbSAoU1NMU3RyZWFtZWRJbnB1dCksIHBhc3MgaXQKKyAgICAgICAgICAgICAgICAvLyB0byBhcHByb3ByaWF0ZSBjbGllbnQgcHJvdG9jb2wgKGFsZXJ0LCBoYW5kc2hha2UsIG9yIGFwcCkKKyAgICAgICAgICAgICAgICAvLyBhbmQgcmV0cmlldmUgdGhlIHR5cGUgb2YgdW53cmFwcGVkIGRhdGEKKyAgICAgICAgICAgICAgICBzd2l0Y2ggKHR5cGUgPSByZWNvcmRQcm90b2NvbC51bndyYXAoKSkgeworICAgICAgICAgICAgICAgICAgICBjYXNlIENvbnRlbnRUeXBlLkhBTkRTSEFLRToKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaGFuZHNoYWtlUHJvdG9jb2wuZ2V0U3RhdHVzKCkuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5OT1RfSEFORFNIQUtJTkcpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZHNoYWtlIHByb3RvY29sIGdvdCBhZGRyZXNzZWQgdG8gaXQgbWVzc2FnZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBkaWQgbm90IGlnbm9yZSBpdCwgc28gaXQncyBhIHJlaGFuZHNoYWtlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9IYW5kc2hha2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIENvbnRlbnRUeXBlLkFMRVJUOgorICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0FsZXJ0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc29ja2V0X3dhc19jbG9zZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBDb250ZW50VHlwZS5BUFBMSUNBVElPTl9EQVRBOgorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLnByaW50bG4oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1NMU29ja2V0Lm5lZWRBcHBEYXRhOiBnb3QgdGhlIGRhdGEiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2lsbCB0aHJvdyBleGNlcHRpb24KKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5VTkVYUEVDVEVEX01FU1NBR0UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTU0xFeGNlcHRpb24oIlVuZXhwZWN0ZWQgbWVzc2FnZSBvZiB0eXBlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdHlwZSArICIgaGFzIGJlZW4gZ290IikpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoYWxlcnRQcm90b2NvbC5oYXNBbGVydCgpKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIHdhcm5pbmcgYWxlcnQgb2NjdXJyZWQgZHVyaW5nIHdyYXAgb3IgdW53cmFwCisgICAgICAgICAgICAgICAgICAgIC8vIChub3RlOiBmYXRhbCBhbGVydCBjYXVzZXMgQWxlcnRFeGNlcHRpb24KKyAgICAgICAgICAgICAgICAgICAgLy8gdG8gYmUgdGhyb3duKQorICAgICAgICAgICAgICAgICAgICBvdXRwdXQud3JpdGUoYWxlcnRQcm90b2NvbC53cmFwKCkpOworICAgICAgICAgICAgICAgICAgICBhbGVydFByb3RvY29sLnNldFByb2Nlc3NlZCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoc29ja2V0X3dhc19jbG9zZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgYXBwRGF0YUlTLnNldEVuZCgpOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChBbGVydEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyB3aWxsIHRocm93IGV4Y2VwdGlvbgorICAgICAgICAgICAgcmVwb3J0RmF0YWxBbGVydChlLmdldERlc2NyaXB0aW9uQ29kZSgpLCBlLmdldFJlYXNvbigpKTsKKyAgICAgICAgfSBjYXRjaCAoRW5kT2ZTb3VyY2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZW5kIG9mIHNvY2tldCdzIGlucHV0IHN0cmVhbSBoYXMgYmVlbiByZWFjaGVkCisgICAgICAgICAgICBhcHBEYXRhSVMuc2V0RW5kKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiU1NMU29ja2V0Lm5lZWRBcHBEYXRhOiBhcHAgZGF0YSBsZW46ICIKKyAgICAgICAgICAgICAgICAgICAgKyBhcHBEYXRhSVMuYXZhaWxhYmxlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IFNTTFNvY2tldE91dHB1dFN0cmVhbSB3aGVuIGEgY2xpZW50IGFwcGxpY2F0aW9uCisgICAgICogdHJpZXMgdG8gc2VuZCB0aGUgZGF0YSBvdmVyIHNzbCBwcm90b2NvbC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB3cml0ZUFwcERhdGEoYnl0ZVtdIGRhdGEsIGludCBvZmZzZXQsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaGFuZHNoYWtlX3N0YXJ0ZWQpIHsKKyAgICAgICAgICAgIHN0YXJ0SGFuZHNoYWtlKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxvZ2dlciAhPSBudWxsKSB7CisgICAgICAgICAgICBsb2dnZXIucHJpbnRsbigiU1NMU29ja2V0LndyaXRlQXBwRGF0YTogIiArCisgICAgICAgICAgICAgICAgICAgIGxlbiArICIgIiArIFNTTFJlY29yZFByb3RvY29sLk1BWF9EQVRBX0xFTkdUSCk7CisgICAgICAgICAgICAvL2xvZ2dlci5wcmludGxuKG5ldyBTdHJpbmcoZGF0YSwgb2Zmc2V0LCBsZW4pKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGxlbiA8IFNTTFJlY29yZFByb3RvY29sLk1BWF9EQVRBX0xFTkdUSCkgeworICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZShyZWNvcmRQcm90b2NvbC53cmFwKENvbnRlbnRUeXBlLkFQUExJQ0FUSU9OX0RBVEEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSwgb2Zmc2V0LCBsZW4pKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgd2hpbGUgKGxlbiA+PSBTU0xSZWNvcmRQcm90b2NvbC5NQVhfREFUQV9MRU5HVEgpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0LndyaXRlKHJlY29yZFByb3RvY29sLndyYXAoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRlbnRUeXBlLkFQUExJQ0FUSU9OX0RBVEEsIGRhdGEsIG9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMUmVjb3JkUHJvdG9jb2wuTUFYX0RBVEFfTEVOR1RIKSk7CisgICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSBTU0xSZWNvcmRQcm90b2NvbC5NQVhfREFUQV9MRU5HVEg7CisgICAgICAgICAgICAgICAgICAgIGxlbiAtPSBTU0xSZWNvcmRQcm90b2NvbC5NQVhfREFUQV9MRU5HVEg7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChsZW4gPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZSgKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlY29yZFByb3RvY29sLndyYXAoQ29udGVudFR5cGUuQVBQTElDQVRJT05fREFUQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSwgb2Zmc2V0LCBsZW4pKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEFsZXJ0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIHdpbGwgdGhyb3cgZXhjZXB0aW9uCisgICAgICAgICAgICByZXBvcnRGYXRhbEFsZXJ0KGUuZ2V0RGVzY3JpcHRpb25Db2RlKCksIGUuZ2V0UmVhc29uKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBQZXJmb3JtcyBoYW5kc2hha2UgcHJvY2VzcyBvdmVyIHRoaXMgY29ubmVjdGlvbi4gVGhlIGhhbmRzaGFrZQorICAgICAqIHByb2Nlc3MgaXMgZGlyZWN0ZWQgYnkgdGhlIGhhbmRzaGFrZSBzdGF0dXMgY29kZSBwcm92aWRlZCBieQorICAgICAqIGhhbmRzaGFrZSBwcm90b2NvbC4gSWYgdGhpcyBzdGF0dXMgaXMgTkVFRF9XUkFQLCBtZXRob2QgcmV0cmlldmVzCisgICAgICogaGFuZHNoYWtlIG1lc3NhZ2UgZnJvbSBoYW5kc2hha2UgcHJvdG9jb2wgYW5kIHNlbmRzIGl0IHRvIGFub3RoZXIgcGVlci4KKyAgICAgKiBJZiB0aGlzIHN0YXR1cyBpcyBORUVEX1VOV1JBUCwgbWV0aG9kIHJlY2VpdmVzIGFuZCBwcm9jZXNzZXMgaGFuZHNoYWtlCisgICAgICogbWVzc2FnZSBmcm9tIGFub3RoZXIgcGVlci4gRWFjaCBvZiB0aGlzIHN0YWdlcyAod3JhcC91bndyYXApIGNoYW5nZQorICAgICAqIHRoZSBzdGF0ZSBvZiBoYW5kc2hha2UgcHJvdG9jb2wgYW5kIHRoaXMgcHJvY2VzcyBpcyBwZXJmb3JtZWQKKyAgICAgKiB1bnRpbCBoYW5kc2hha2Ugc3RhdHVzIGlzIEZJTklTSEVELiBBZnRlciBoYW5kc2hha2UgcHJvY2VzcyBpcyBmaW5pc2hlZAorICAgICAqIGhhbmRzaGFrZSBjb21wbGV0ZWQgZXZlbnQgYXJlIHNlbnQgdG8gdGhlIHJlZ2lzdGVyZWQgbGlzdGVuZXJzLgorICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBoYW5kc2hha2UgcHJvY2VzcyBzZWUKKyAgICAgKiBUTFMgdjEgc3BlY2lmaWNhdGlvbiAoaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI0Ni50eHQpIHAgNy4zLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBkb0hhbmRzaGFrZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMgc3RhdHVzOworICAgICAgICBpbnQgdHlwZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdoaWxlICghKHN0YXR1cyA9IGhhbmRzaGFrZVByb3RvY29sLmdldFN0YXR1cygpKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzLkZJTklTSEVEKSkgeworICAgICAgICAgICAgICAgIGlmIChsb2dnZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcyA9IChzdGF0dXMuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzLk5FRURfV1JBUCkpCisgICAgICAgICAgICAgICAgICAgICAgICA/ICJORUVEX1dSQVAiCisgICAgICAgICAgICAgICAgICAgICAgICA6IChzdGF0dXMuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzLk5FRURfVU5XUkFQKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICJORUVEX1VOV1JBUCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICJTVEFUVVM6IE9USEVSISI7CisgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJTU0xTb2NrZXRJbXBsOiBIUyBzdGF0dXM6ICIrcysiICIrc3RhdHVzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHN0YXR1cy5lcXVhbHMoU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cy5ORUVEX1dSQVApKSB7CisgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZShoYW5kc2hha2VQcm90b2NvbC53cmFwKCkpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdHVzLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzLk5FRURfVU5XUkFQKSkgeworICAgICAgICAgICAgICAgICAgICAvLyByZWFkIGFuZCB1bndyYXAgdGhlIHJlY29yZCBjb250YWluZWQgaW4gdGhlIHRyYW5zcG9ydAorICAgICAgICAgICAgICAgICAgICAvLyBpbnB1dCBzdHJlYW0gKFNTTFN0cmVhbWVkSW5wdXQpLCBwYXNzIGl0CisgICAgICAgICAgICAgICAgICAgIC8vIHRvIGFwcHJvcHJpYXRlIGNsaWVudCBwcm90b2NvbCAoYWxlcnQsIGhhbmRzaGFrZSwgb3IgYXBwKQorICAgICAgICAgICAgICAgICAgICAvLyBhbmQgcmV0cmlldmUgdGhlIHR5cGUgb2YgdW53cmFwcGVkIGRhdGEKKyAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0eXBlID0gcmVjb3JkUHJvdG9jb2wudW53cmFwKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ29udGVudFR5cGUuSEFORFNIQUtFOgorICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBDb250ZW50VHlwZS5DSEFOR0VfQ0lQSEVSX1NQRUM6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIENvbnRlbnRUeXBlLkFQUExJQ0FUSU9OX0RBVEE6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU28gaXQncyByZWhhbmRzaGFrZSBhbmQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBhcHAgZGF0YSBidWZmZXIgd2lsbCBiZSBvdmVybG9hZGVkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXQgd2lsbCB0aHJvdyBhbGVydCBleGNlcHRpb24uCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUHJvYmFibHkgd2Ugc2hvdWxkIGNvdW50IHRoZSBudW1iZXIgb2YKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBub3QgaGFuZHNoYWtpbmcgZGF0YSBhbmQgbWFrZSBhZGRpdGlvbmFsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc3RyYWludHMgKGRvIG5vdCBleHBlY3QgYnVmZmVyIG92ZXJmbG93KS4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ29udGVudFR5cGUuQUxFUlQ6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0FsZXJ0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNvY2tldF93YXNfY2xvc2VkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdpbGwgdGhyb3cgZXhjZXB0aW9uCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxBbGVydChBbGVydFByb3RvY29sLlVORVhQRUNURURfTUVTU0FHRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTU0xFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuZXhwZWN0ZWQgbWVzc2FnZSBvZiB0eXBlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHR5cGUgKyAiIGhhcyBiZWVuIGdvdCIpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIC8vIHdpbGwgdGhyb3cgZXhjZXB0aW9uCisgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5JTlRFUk5BTF9FUlJPUiwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTU0xFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkhhbmRzaGFrZSBwYXNzZWQgdW5leHBlY3RlZCBzdGF0dXM6ICIrc3RhdHVzKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChhbGVydFByb3RvY29sLmhhc0FsZXJ0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gd2FybmluZyBhbGVydCBvY2N1cnJlZCBkdXJpbmcgd3JhcCBvciB1bndyYXAKKyAgICAgICAgICAgICAgICAgICAgLy8gKG5vdGU6IGZhdGFsIGFsZXJ0IGNhdXNlcyBBbGVydEV4Y2VwdGlvbgorICAgICAgICAgICAgICAgICAgICAvLyB0byBiZSB0aHJvd24pCisgICAgICAgICAgICAgICAgICAgIG91dHB1dC53cml0ZShhbGVydFByb3RvY29sLndyYXAoKSk7CisgICAgICAgICAgICAgICAgICAgIGFsZXJ0UHJvdG9jb2wuc2V0UHJvY2Vzc2VkKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFbmRPZlNvdXJjZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhcHBEYXRhSVMuc2V0RW5kKCk7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNvbm5lY3Rpb24gd2FzIGNsb3NlZCIpOworICAgICAgICB9IGNhdGNoIChBbGVydEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyB3aWxsIHRocm93IGV4Y2VwdGlvbgorICAgICAgICAgICAgcmVwb3J0RmF0YWxBbGVydChlLmdldERlc2NyaXB0aW9uQ29kZSgpLCBlLmdldFJlYXNvbigpKTsKKyAgICAgICAgfQorCisgICAgICAgIHNlc3Npb24gPSByZWNvcmRQcm90b2NvbC5nZXRTZXNzaW9uKCk7CisgICAgICAgIGlmIChsaXN0ZW5lcnMgIT0gbnVsbCkgeworICAgICAgICAgICAgLy8gbm90aWZ5IHRoZSBsaXN0ZW5lcnMKKyAgICAgICAgICAgIEhhbmRzaGFrZUNvbXBsZXRlZEV2ZW50IGV2ZW50ID0KKyAgICAgICAgICAgICAgICBuZXcgSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQodGhpcywgc2Vzc2lvbik7CisgICAgICAgICAgICBpbnQgc2l6ZSA9IGxpc3RlbmVycy5zaXplKCk7CisgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8c2l6ZTsgaSsrKSB7CisgICAgICAgICAgICAgICAgbGlzdGVuZXJzLmdldChpKQorICAgICAgICAgICAgICAgICAgICAuaGFuZHNoYWtlQ29tcGxldGVkKGV2ZW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogUHJvY2VzcyByZWNlaXZlZCBhbGVydCBtZXNzYWdlCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHByb2Nlc3NBbGVydCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghYWxlcnRQcm90b2NvbC5oYXNBbGVydCgpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFsZXJ0UHJvdG9jb2wuaXNGYXRhbEFsZXJ0KCkpIHsKKyAgICAgICAgICAgIGFsZXJ0UHJvdG9jb2wuc2V0UHJvY2Vzc2VkKCk7CisgICAgICAgICAgICBTdHJpbmcgZGVzY3JpcHRpb24gPSAiRmF0YWwgYWxlcnQgcmVjZWl2ZWQgIgorICAgICAgICAgICAgICAgICsgYWxlcnRQcm90b2NvbC5nZXRBbGVydERlc2NyaXB0aW9uKCk7CisgICAgICAgICAgICBzaHV0ZG93bigpOworICAgICAgICAgICAgdGhyb3cgbmV3IFNTTEV4Y2VwdGlvbihkZXNjcmlwdGlvbik7CisgICAgICAgIH0KKworICAgICAgICBpZiAobG9nZ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxvZ2dlci5wcmludGxuKCJXYXJuaW5nIGFsZXJ0IHJlY2VpdmVkOiAiCisgICAgICAgICAgICAgICAgKyBhbGVydFByb3RvY29sLmdldEFsZXJ0RGVzY3JpcHRpb24oKSk7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoKGFsZXJ0UHJvdG9jb2wuZ2V0RGVzY3JpcHRpb25Db2RlKCkpIHsKKyAgICAgICAgICAgIGNhc2UgQWxlcnRQcm90b2NvbC5DTE9TRV9OT1RJRlk6CisgICAgICAgICAgICAgICAgYWxlcnRQcm90b2NvbC5zZXRQcm9jZXNzZWQoKTsKKyAgICAgICAgICAgICAgICBhcHBEYXRhSVMuc2V0RW5kKCk7CisgICAgICAgICAgICAgICAgY2xvc2UoKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIGFsZXJ0UHJvdG9jb2wuc2V0UHJvY2Vzc2VkKCk7CisgICAgICAgICAgICAvLyBUT0RPOiBwcm9jZXNzIG90aGVyIHdhcm5pbmcgbWVzc2FnZXMKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogU2VuZHMgZmF0YWwgYWxlcnQgbWVzc2FnZSBhbmQgdGhyb3dzIGV4Y2VwdGlvbgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZXBvcnRGYXRhbEFsZXJ0KGJ5dGUgZGVzY3JpcHRpb25fY29kZSwKKyAgICAgICAgICAgIFNTTEV4Y2VwdGlvbiByZWFzb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGFsZXJ0UHJvdG9jb2wuYWxlcnQoQWxlcnRQcm90b2NvbC5GQVRBTCwgZGVzY3JpcHRpb25fY29kZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyB0aGUgb3V0cHV0IHN0cmVhbSBjYW4gYmUgY2xvc2VkCisgICAgICAgICAgICBvdXRwdXQud3JpdGUoYWxlcnRQcm90b2NvbC53cmFwKCkpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeyB9CisgICAgICAgIGFsZXJ0UHJvdG9jb2wuc2V0UHJvY2Vzc2VkKCk7CisgICAgICAgIHNodXRkb3duKCk7CisgICAgICAgIHRocm93IHJlYXNvbjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xTb2NrZXRJbnB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMU29ja2V0SW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MDE2NTc5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMU29ja2V0SW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDE2NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMRXhjZXB0aW9uOworCisvKioKKyAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgaW5wdXQgZGF0YSBzdHJlYW0gZnVuY3Rpb25hbGl0eQorICogZm9yIFNTTFNvY2tldC4gSXQgYWNjdW11bGF0ZXMgdGhlIGFwcGxpY2F0aW9uIGRhdGEKKyAqIHJlY2VpdmVkIGJ5IFNTTCBwcm90b2NvbC4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFNTTFNvY2tldElucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworCisgICAgLy8gVGhlIHNpemUgb2YgdGhlIGludGVybmFsIGRhdGEgYnVmZmVyLgorICAgIC8vIEl0IHNob3VsZCBub3QgYmUgbGVzcyB0aGFuIG1heGltdW0gZGF0YSBjaHVuayBlbmNsb3NlZAorICAgIC8vIGluIG9uZSBzc2wgcGFja2V0LgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCVUZGRVJfU0laRSA9IFNTTFJlY29yZFByb3RvY29sLk1BWF9EQVRBX0xFTkdUSDsKKworICAgIC8vIEludGVybmFsIGJ1ZmZlciBhY2N1bXVsYXRpbmcgdGhlIHJlY2VpdmVkIGFwcGxpY2F0aW9uIGRhdGEKKyAgICBwcml2YXRlIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtCVUZGRVJfU0laRV07CisKKyAgICAvLyBwb3NpdGlvbiBvZiB0aGUgbmV4dCBieXRlIHRvIHJlYWQgZnJvbSB0aGUgYnVmZmVyCisgICAgcHJpdmF0ZSBpbnQgcG9zOworCisgICAgLy8gcG9zaXRpb24gb2YgdGhlIGxhc3QgYnl0ZSB0byByZWFkICsgMQorICAgIHByaXZhdGUgaW50IGVuZDsKKworICAgIC8vIHRoZSBzc2wgc29ja2V0IG93bmluZyB0aGUgc3RyZWFtCisgICAgcHJpdmF0ZSBmaW5hbCBTU0xTb2NrZXRJbXBsIG93bmVyOworCisgICAgLy8gdGhlIGZsYWcgaW5kaWNhdGluZyB0aGF0IHRoZSBlbmQgb2YgdGhlIChvd25lcidzKSBpbnB1dCBzdHJlYW0KKyAgICAvLyBoYXMgYmVlbiByZWFjaGVkCisgICAgcHJpdmF0ZSBib29sZWFuIGVuZF9yZWFjaGVkID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBhcHBsaWNhdGlvbiBkYXRhIGlucHV0IHN0cmVhbSBmb3Igc3BlY2lmaWVkIHNvY2tldC4KKyAgICAgKiBAcGFyYW0gICBvd25lciB0aGUgc29ja2V0IHdoaWNoIHdpbGwgcHJvdmlkZSB0aGlzIGlucHV0IHN0cmVhbQorICAgICAqIHRvIGNsaWVudCBhcHBsaWNhdGlvbnMuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNTTFNvY2tldElucHV0U3RyZWFtKFNTTFNvY2tldEltcGwgb3duZXIpIHsKKyAgICAgICAgdGhpcy5vd25lciA9IG93bmVyOworICAgIH0KKworICAgIC8vIFRoZSBoZWxwZXIgZGVsaXZlcmluZyB0aGUgYXBwbGljYXRpb24gZGF0YSBmcm9tIHRoZSByZWNvcmQgbGF5ZXIKKyAgICBwcm90ZWN0ZWQgQWRhcHRlciBkYXRhUG9pbnQgPSBuZXcgQWRhcHRlcigpOworCisgICAgLyoqCisgICAgICogVGVsbHMgdG8gdGhlIHN0cmVhbSB0aGF0IHRoZSBlbmQgb2YgdGhlIGluY29tZSBkYXRhIGhhcworICAgICAqIGJlZW4gcmVhY2hlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRFbmQoKSB7CisgICAgICAgIGVuZF9yZWFjaGVkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0gSW5wdXRTdHJlYW0gaW1wbGVtZW50YXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIGF2YWlsYWJsZSBmb3IgcmVhZGluZyB3aXRob3V0IGJsb2NraW5nLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBhdmFpbGFibGUgYnl0ZXMuCisgICAgICogQHRocm93cyAgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBlbmQgLSBwb3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoZSBzdHJlYW0KKyAgICAgKiBAdGhyb3dzICBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnVmZmVyID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBvbmUgYnl0ZS4gSWYgdGhlcmUgaXMgbm8gZGF0YSBpbiB0aGUgdW5kZXJseWluZyBidWZmZXIsCisgICAgICogdGhpcyBvcGVyYXRpb24gY2FuIGJsb2NrIHVudGlsIHRoZSBkYXRhIHdpbGwgYmUKKyAgICAgKiBhdmFpbGFibGUuCisgICAgICogQHJldHVybiByZWFkIHZhbHVlLgorICAgICAqIEB0aHJvd3MgIElPRXhjZXB0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGJ1ZmZlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlN0cmVhbSB3YXMgY2xvc2VkLiIpOworICAgICAgICB9CisgICAgICAgIHdoaWxlIChwb3MgPT0gZW5kKSB7CisgICAgICAgICAgICBpZiAoZW5kX3JlYWNoZWQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBkYXRhIGluIHRoZSBidWZmZXIKKyAgICAgICAgICAgIC8vIC0gd2lsbCBibG9jayB1bnRpbCB0aGUgZGF0YSB3aWxsIGJlIHByb3ZpZGVkIGJ5CisgICAgICAgICAgICAvLyByZWNvcmQgbGF5ZXIKKyAgICAgICAgICAgIG93bmVyLm5lZWRBcHBEYXRhKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJ1ZmZlcltwb3MrK10gJiAweEZGOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByZWFkX2I7CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgZG8geworICAgICAgICAgICAgaWYgKChyZWFkX2IgPSByZWFkKCkpID09IC0xKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChpID09IDApID8gLTEgOiBpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYltvZmYraV0gPSAoYnl0ZSkgcmVhZF9iOworICAgICAgICAgICAgaSsrOworICAgICAgICB9IHdoaWxlICgoYXZhaWxhYmxlKCkgIT0gMCkgJiYgKGk8bGVuKSk7CisgICAgICAgIHJldHVybiBpOworICAgIH0KKworICAgIC8vIFRoZSBoZWxwZXIgY2xhc3MgZGVsaXZlcmluZyB0aGUgYXBwbGljYXRpb24gZGF0YSBmcm9tIHRoZSByZWNvcmQgbGF5ZXIKKyAgICAvLyB0byB0aGlzIGlucHV0IHN0cmVhbS4KKyAgICAvLyBJdCAnYWRhcHRzJyB0aGUgSW5wdXRTdHJlYW0gaW50ZXJmYWNlIHRvIEFwcGVuZGFibGUsIHdoaWNoIGlzIHVzZWQgZm9yCisgICAgLy8gdHJhbnNtaXNzaW9uIG9mIGluY29tZSBkYXRhIGZyb20gdGhlIHJlY29yZCBwcm90b2NvbCB0byBpdHMgY2xpZW50cy4KKyAgICBwcml2YXRlIGNsYXNzIEFkYXB0ZXIgaW1wbGVtZW50cyBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlLkFwcGVuZGFibGUgeworICAgICAgICAvKioKKyAgICAgICAgICogQXBwZW5kcyB0aGUgZGF0YSB0byB0aGUgc3RyZWFtLgorICAgICAgICAgKiBUaGlzIG1ldGhvZCBjb3VsZCBiZSBpbXBsZW1lbnRlZCBpbiB0aGUgb3V0ZXIgY2xhc3MKKyAgICAgICAgICogaXRzZWxmLCBidXQgaXQgY291bGQgYmUgaW5zZWN1cmUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCBhcHBlbmQoYnl0ZVtdIHNyYykgeworICAgICAgICAgICAgaW50IGxlbmd0aCA9IHNyYy5sZW5ndGg7CisgICAgICAgICAgICBpZiAoQlVGRkVSX1NJWkUgLSAoZW5kIC0gcG9zKSA8IGxlbmd0aCkgeworICAgICAgICAgICAgICAgIC8vIElmIHRoZSBzaXplIG9mIHRoZSBidWZmZXIgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFscyB0bworICAgICAgICAgICAgICAgIC8vIFNTTFJlY29yZFByb3RvY29sLk1BWF9EQVRBX0xFTkdUSCB0aGlzIHNpdHVhdGlvbiB3aWxsCisgICAgICAgICAgICAgICAgLy8gaGFwcGVuIGlmZjoKKyAgICAgICAgICAgICAgICAvLyAxLiB0aGUgbGVuZ3RoIG9mIHJlY2VpdmVkIGRhdGEgZnJhZ21lbnQgaXMgZ3JlYXRlcgorICAgICAgICAgICAgICAgIC8vIHRoYW4gYWxsb3dlZCBieSB0aGUgc3BlYworICAgICAgICAgICAgICAgIC8vIDIuIGl0IGlzIHJlaGFuZHNoYWtpbmcgc3RhZ2UgYW5kIHdlIGhhdmUgZ290IHNldmVyYWwKKyAgICAgICAgICAgICAgICAvLyBleHRyYSBhcHAgZGF0YSBtZXNzYWdlcy4KKyAgICAgICAgICAgICAgICAvLyBJbiBhbnkgY2FzZSBpdCBpcyBiZXR0ZXIgdG8gdGhyb3cgYWxlcnQgZXhjZXB0aW9uLgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBBbGVydEV4Y2VwdGlvbihBbGVydFByb3RvY29sLklOVEVSTkFMX0VSUk9SLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFNTTEV4Y2VwdGlvbigiQ291bGQgbm90IGFjY2VwdCBpbmNvbWUgYXBwIGRhdGEuIikpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGVuZCArIGxlbmd0aCA+IEJVRkZFUl9TSVpFKSB7CisgICAgICAgICAgICAgICAgLy8gbW92ZSB0aGUgY29udGVudCBvZiB0aGUgYnVmZmVyIHRvIHRoZSBiZWdpbm5pbmcKKyAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZmZlciwgcG9zLCBidWZmZXIsIDAsIGVuZC1wb3MpOworICAgICAgICAgICAgICAgIGVuZCAtPSBwb3M7CisgICAgICAgICAgICAgICAgcG9zID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc3JjLCAwLCBidWZmZXIsIGVuZCwgbGVuZ3RoKTsKKyAgICAgICAgICAgIGVuZCA9IGVuZCArIGxlbmd0aDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTFNvY2tldE91dHB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU1NMU29ja2V0T3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjY2NmVlZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTFNvY2tldE91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworCisvKioKKyAqIFRoaXMgaXMgYSBhcHBsaWNhdGlvbiBkYXRhIG91dHB1dCBzdHJlYW0gdXNlZCBpbiBTU0xTb2NrZXQKKyAqIGltcGxlbWVudGF0aW9uLgorICogVGhlIHdyaXR0ZW4gYnl0ZXMgYXJlIGVuY3J5cHRlZCwgcGFja2VkIGludG8gdGhlIHJlY29yZHMsCisgKiBhbmQgdGhlbiBzZW50IHRvIHRoZSBwZWVyIGhvc3QuCisgKi8KK3B1YmxpYyBjbGFzcyBTU0xTb2NrZXRPdXRwdXRTdHJlYW0gZXh0ZW5kcyBPdXRwdXRTdHJlYW0geworICAgIHByaXZhdGUgZmluYWwgU1NMU29ja2V0SW1wbCBvd25lcjsKKworICAgIHByb3RlY3RlZCBTU0xTb2NrZXRPdXRwdXRTdHJlYW0oU1NMU29ja2V0SW1wbCBvd25lcikgeworICAgICAgICB0aGlzLm93bmVyID0gb3duZXI7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHdyaXRlKGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJlYW1zLndyaXRlU2luZ2xlQnl0ZSh0aGlzLCBiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3duZXIud3JpdGVBcHBEYXRhKGIsIG9mZiwgbGVuKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xTb2NrZXRXcmFwcGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xTb2NrZXRXcmFwcGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjdiYmVhZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTFNvY2tldFdyYXBwZXIuamF2YQpAQCAtMCwwICsxLDIzMSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNvY2tldEV4Y2VwdGlvbjsKKworLyoqCisgKiBUaGlzIGNsYXNzIHdyYXBzIHRoZSBTU0wgZnVjdGlvbmFsaXR5IG92ZXIgZXhpc3RpbmcgY29ubmV0ZWQgc29ja2V0LgorICovCitwdWJsaWMgY2xhc3MgU1NMU29ja2V0V3JhcHBlciBleHRlbmRzIFNTTFNvY2tldEltcGwgeworCisgICAgcHJpdmF0ZSBmaW5hbCBTb2NrZXQgc29ja2V0OworICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBhdXRvQ2xvc2U7CisKKyAgICBwcm90ZWN0ZWQgU1NMU29ja2V0V3JhcHBlcihTb2NrZXQgc29ja2V0LCBib29sZWFuIGF1dG9DbG9zZSwgU1NMUGFyYW1ldGVyc0ltcGwgc3NsUGFyYW1ldGVycykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIoc3NsUGFyYW1ldGVycyk7CisgICAgICAgIGlmICghc29ja2V0LmlzQ29ubmVjdGVkKCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTb2NrZXRFeGNlcHRpb24oIlNvY2tldCBpcyBub3QgY29ubmVjdGVkLiIpOworICAgICAgICB9CisgICAgICAgIHRoaXMuc29ja2V0ID0gc29ja2V0OworICAgICAgICB0aGlzLmF1dG9DbG9zZSA9IGF1dG9DbG9zZTsKKyAgICAgICAgaW5pdCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGluaXRUcmFuc3BvcnRMYXllcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlucHV0ID0gc29ja2V0LmdldElucHV0U3RyZWFtKCk7CisgICAgICAgIG91dHB1dCA9IHNvY2tldC5nZXRPdXRwdXRTdHJlYW0oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBjbG9zZVRyYW5zcG9ydExheWVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGF1dG9DbG9zZSAmJiAoaW5wdXQgIT0gbnVsbCkpIHsKKyAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgaW5wdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIG91dHB1dC5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLSBXcmFwcGluZyBtZXRob2QgaW1wbGVtZW50YXRpb25zIC0tLS0tLS0tLS0tLS0tLQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY29ubmVjdChTb2NrZXRBZGRyZXNzIHNvY2thZGRyLCBpbnQgdGltZW91dCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJVbmRlcmx5aW5nIHNvY2tldCBpcyBhbHJlYWR5IGNvbm5lY3RlZC4iKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjb25uZWN0KFNvY2tldEFkZHJlc3Mgc29ja2FkZHIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5kZXJseWluZyBzb2NrZXQgaXMgYWxyZWFkeSBjb25uZWN0ZWQuIik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYmluZChTb2NrZXRBZGRyZXNzIHNvY2thZGRyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlVuZGVybHlpbmcgc29ja2V0IGlzIGFscmVhZHkgY29ubmVjdGVkLiIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTb2NrZXRBZGRyZXNzIGdldFJlbW90ZVNvY2tldEFkZHJlc3MoKSB7CisgICAgICAgIHJldHVybiBzb2NrZXQuZ2V0UmVtb3RlU29ja2V0QWRkcmVzcygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTb2NrZXRBZGRyZXNzIGdldExvY2FsU29ja2V0QWRkcmVzcygpIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5nZXRMb2NhbFNvY2tldEFkZHJlc3MoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW5ldEFkZHJlc3MgZ2V0TG9jYWxBZGRyZXNzKCkgeworICAgICAgICByZXR1cm4gc29ja2V0LmdldExvY2FsQWRkcmVzcygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbmV0QWRkcmVzcyBnZXRJbmV0QWRkcmVzcygpIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5nZXRJbmV0QWRkcmVzcygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiAiU1NMIHNvY2tldCBvdmVyICIgKyBzb2NrZXQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRTb0xpbmdlcihib29sZWFuIG9uLCBpbnQgbGluZ2VyKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgc29ja2V0LnNldFNvTGluZ2VyKG9uLCBsaW5nZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFRjcE5vRGVsYXkoYm9vbGVhbiBvbikgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHNvY2tldC5zZXRUY3BOb0RlbGF5KG9uKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRSZXVzZUFkZHJlc3MoYm9vbGVhbiBvbikgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHNvY2tldC5zZXRSZXVzZUFkZHJlc3Mob24pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEtlZXBBbGl2ZShib29sZWFuIG9uKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgc29ja2V0LnNldEtlZXBBbGl2ZShvbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0VHJhZmZpY0NsYXNzKGludCB0b3MpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBzb2NrZXQuc2V0VHJhZmZpY0NsYXNzKHRvcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0U29UaW1lb3V0KGludCB0bykgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHNvY2tldC5zZXRTb1RpbWVvdXQodG8pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFNlbmRCdWZmZXJTaXplKGludCBzaXplKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgc29ja2V0LnNldFNlbmRCdWZmZXJTaXplKHNpemUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFJlY2VpdmVCdWZmZXJTaXplKGludCBzaXplKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgc29ja2V0LnNldFJlY2VpdmVCdWZmZXJTaXplKHNpemUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGdldFRjcE5vRGVsYXkoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5nZXRUY3BOb0RlbGF5KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0UmV1c2VBZGRyZXNzKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzb2NrZXQuZ2V0UmV1c2VBZGRyZXNzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0T09CSW5saW5lKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzb2NrZXQuZ2V0T09CSW5saW5lKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0S2VlcEFsaXZlKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzb2NrZXQuZ2V0S2VlcEFsaXZlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRUcmFmZmljQ2xhc3MoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5nZXRUcmFmZmljQ2xhc3MoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFNvVGltZW91dCgpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc29ja2V0LmdldFNvVGltZW91dCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0U29MaW5nZXIoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5nZXRTb0xpbmdlcigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0U2VuZEJ1ZmZlclNpemUoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5nZXRTZW5kQnVmZmVyU2l6ZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0UmVjZWl2ZUJ1ZmZlclNpemUoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5nZXRSZWNlaXZlQnVmZmVyU2l6ZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzQ29ubmVjdGVkKCkgeworICAgICAgICByZXR1cm4gc29ja2V0LmlzQ29ubmVjdGVkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNDbG9zZWQoKSB7CisgICAgICAgIHJldHVybiBzb2NrZXQuaXNDbG9zZWQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0JvdW5kKCkgeworICAgICAgICByZXR1cm4gc29ja2V0LmlzQm91bmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc091dHB1dFNodXRkb3duKCkgeworICAgICAgICByZXR1cm4gc29ja2V0LmlzT3V0cHV0U2h1dGRvd24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0lucHV0U2h1dGRvd24oKSB7CisgICAgICAgIHJldHVybiBzb2NrZXQuaXNJbnB1dFNodXRkb3duKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRQb3J0KCkgeworICAgICAgICByZXR1cm4gc29ja2V0LmdldFBvcnQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldExvY2FsUG9ydCgpIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5nZXRMb2NhbFBvcnQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3IgZ2V0RmlsZURlc2NyaXB0b3IkKCkgeworICAgICAgICByZXR1cm4gc29ja2V0LmdldEZpbGVEZXNjcmlwdG9yJCgpOworICAgIH0KKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xTdHJlYW1lZElucHV0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0xTdHJlYW1lZElucHV0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzA0MDY1MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTFN0cmVhbWVkSW5wdXQuamF2YQpAQCAtMCwwICsxLDU3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKKy8qKgorICogVGhpcyBjbGFzcyBhY3RzIGxpa2UgYSBmaWx0ZXJlZCBpbnB1dCBzdHJlYW06IGl0IHRha2VzCisgKiB0aGUgYnl0ZXMgZnJvbSBhbm90aGVyIElucHV0U3RyZWFtLgorICovCitwdWJsaWMgY2xhc3MgU1NMU3RyZWFtZWRJbnB1dCBleHRlbmRzIFNTTElucHV0U3RyZWFtIHsKKworICAgIHByaXZhdGUgSW5wdXRTdHJlYW0gaW47CisKKyAgICBwdWJsaWMgU1NMU3RyZWFtZWRJbnB1dChJbnB1dFN0cmVhbSBpbikgeworICAgICAgICB0aGlzLmluID0gaW47CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gaW4uYXZhaWxhYmxlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCBhbiBvcGFxdWUgdmFsdWUgZnJvbSB0aGUgc3RyZWFtLgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIHJlYWQgZnJvbSB0aGUgdW5kZXJseWluZyBzdHJlYW0uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgZGF0YSBjb3VsZCBub3QgYmUgcmVhZCBmcm9tCisgICAgICogdGhlIHVuZGVybHlpbmcgc3RyZWFtCisgICAgICogQHRocm93cyBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlLkVuZE9mU291cmNlRXhjZXB0aW9uIGlmIHRoZSBlbmQgb2YgdGhlIHVuZGVybHlpbmcKKyAgICAgKiBzdHJlYW0gaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgcmVzID0gaW4ucmVhZCgpOworICAgICAgICBpZiAocmVzIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVuZE9mU291cmNlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NTTHYzQ29uc3RhbnRzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0x2M0NvbnN0YW50cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQzZGMxNzgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TU0x2M0NvbnN0YW50cy5qYXZhCkBAIC0wLDAgKzEsODQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworLyoqCisgKgorICogQ29udGFpbnMgU1NMIDMuMCBjb25zdGFudHMKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3dwLm5ldHNjYXBlLmNvbS9lbmcvc3NsMyI+U1NMIDMuMCBTcGVjLjwvYT4KKyAqLworcHVibGljIGNsYXNzIFNTTHYzQ29uc3RhbnRzIHsKKworICAgIC8qKgorICAgICAqIENsaWVudCBpcyBhIHNlbmRlci4gVXNlZCBpbiBoYXNoIGNhbGN1bGF0aW5nIGZvciBmaW5pc2hlZCBtZXNzYWdlLgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3dwLm5ldHNjYXBlLmNvbS9lbmcvc3NsMyI+U1NMIDMuMCBTcGVjLiwgNS42LjkKKyAgICAgKiBGaW5pc2hlZDwvYT4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIGNsaWVudCA9IG5ldyBieXRlW10geyAweDQzLCAweDRDLCAweDRFLCAweDU0IH07CisKKyAgICAvKioKKyAgICAgKiBTZXJ2ZXIgaXMgYSBzZW5kZXIuIFVzZWQgaW4gaGFzaCBjYWxjdWxhdGluZyBmb3IgZmluaXNoZWQgbWVzc2FnZS4KKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93cC5uZXRzY2FwZS5jb20vZW5nL3NzbDMiPlNTTCAzLjAgU3BlYy4sIDUuNi45CisgICAgICogRmluaXNoZWQ8L2E+CisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBzZXJ2ZXIgPSBuZXcgYnl0ZVtdIHsgMHg1MywgMHg1MiwgMHg1NiwgMHg1MiB9OworCisgICAgLyoqCisgICAgICogcGFkXzEgZm9yIE1ENQorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3dwLm5ldHNjYXBlLmNvbS9lbmcvc3NsMyI+U1NMIDMuMCBTcGVjLiwgNS4yLjMuMQorICAgICAqIE51bGwgb3Igc3RhbmRhcmQgc3RyZWFtIGNpcGhlcjwvYT4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIE1ENXBhZDEgPSBuZXcgYnl0ZVtdIHsgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwKKyAgICAgICAgICAgIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsCisgICAgICAgICAgICAweDM2LCAweDM2LCAweDM2LCAweDM2LCAweDM2LCAweDM2LCAweDM2LCAweDM2LCAweDM2LCAweDM2LCAweDM2LAorICAgICAgICAgICAgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwKKyAgICAgICAgICAgIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYgfTsKKworICAgIC8qKgorICAgICAqIHBhZF8xIGZvciBTSEEKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93cC5uZXRzY2FwZS5jb20vZW5nL3NzbDMiPlNTTCAzLjAgU3BlYy4sIDUuMi4zLjEKKyAgICAgKiBOdWxsIG9yIHN0YW5kYXJkIHN0cmVhbSBjaXBoZXI8L2E+CisgICAgICovCisgICAgc3RhdGljIGZpbmFsIGJ5dGVbXSBTSEFwYWQxID0gbmV3IGJ5dGVbXSB7IDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsCisgICAgICAgICAgICAweDM2LCAweDM2LCAweDM2LCAweDM2LCAweDM2LCAweDM2LCAweDM2LCAweDM2LCAweDM2LCAweDM2LCAweDM2LAorICAgICAgICAgICAgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwgMHgzNiwKKyAgICAgICAgICAgIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsIDB4MzYsCisgICAgICAgICAgICAweDM2LCAweDM2LCAweDM2IH07CisKKyAgICAvKioKKyAgICAgKiBwYWRfMiBmb3IgTUQ1CisgICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3AubmV0c2NhcGUuY29tL2VuZy9zc2wzIj5TU0wgMy4wIFNwZWMuLCA1LjIuMy4xCisgICAgICogTnVsbCBvciBzdGFuZGFyZCBzdHJlYW0gY2lwaGVyPC9hPgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gTUQ1cGFkMiA9IG5ldyBieXRlW10geyAweDVDLCAweDVDLCAweDVDLCAweDVDLAorICAgICAgICAgICAgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywKKyAgICAgICAgICAgIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsCisgICAgICAgICAgICAweDVDLCAweDVDLCAweDVDLCAweDVDLCAweDVDLCAweDVDLCAweDVDLCAweDVDLCAweDVDLCAweDVDLCAweDVDLAorICAgICAgICAgICAgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QyB9OworCisgICAgLyoqCisgICAgICogcGFkXzIgZm9yIFNIQQorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3dwLm5ldHNjYXBlLmNvbS9lbmcvc3NsMyI+U1NMIDMuMCBTcGVjLiwgNS4yLjMuMQorICAgICAqIE51bGwgb3Igc3RhbmRhcmQgc3RyZWFtIGNpcGhlcjwvYT4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIFNIQXBhZDIgPSBuZXcgYnl0ZVtdIHsgMHg1QywgMHg1QywgMHg1QywgMHg1QywKKyAgICAgICAgICAgIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsIDB4NUMsCisgICAgICAgICAgICAweDVDLCAweDVDLCAweDVDLCAweDVDLCAweDVDLCAweDVDLCAweDVDLCAweDVDLCAweDVDLCAweDVDLCAweDVDLAorICAgICAgICAgICAgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywgMHg1QywKKyAgICAgICAgICAgIDB4NUMsIDB4NUMsIDB4NUMgfTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NlcnZlckhhbmRzaGFrZUltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NlcnZlckhhbmRzaGFrZUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNmE2NWI0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU2VydmVySGFuZHNoYWtlSW1wbC5qYXZhCkBAIC0wLDAgKzEsNjY5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5SU0FQdWJsaWNLZXk7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZheC5jcnlwdG8uQ2lwaGVyOworaW1wb3J0IGphdmF4LmNyeXB0by5LZXlBZ3JlZW1lbnQ7CitpbXBvcnQgamF2YXguY3J5cHRvLmludGVyZmFjZXMuREhQdWJsaWNLZXk7CitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuREhQYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLkRIUHVibGljS2V5U3BlYzsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlg1MDlFeHRlbmRlZEtleU1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5YNTA5S2V5TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlg1MDlUcnVzdE1hbmFnZXI7CisKKy8qKgorICogU2VydmVyIHNpZGUgaGFuZHNoYWtlIHByb3RvY29sIGltcGxlbWVudGF0aW9uLgorICogSGFuZHNoYWtlIHByb3RvY29sIG9wZXJhdGVzIG9uIHRvcCBvZiB0aGUgUmVjb3JkIFByb3RvY29sLgorICogSXQgcmVzcG9uc2libGUgZm9yIG5lZ290aWF0aW5nIGEgc2Vzc2lvbi4KKyAqCisgKiBUaGUgaW1wbGVtZW50YXRpb24gcHJvY2Vzc2VzIGluYm91bmQgY2xpZW50IGhhbmRzaGFrZSBtZXNzYWdlcywKKyAqIGNyZWF0ZXMgYW5kIHNlbmRzIHJlc3BvbmQgbWVzc2FnZXMuIE91dGJvdW5kIG1lc3NhZ2VzIGFyZSBzdXBwbGllZAorICogdG8gUmVjb3JkIFByb3RvY29sLiBEZXRlY3RlZCBlcnJvcnMgYXJlIHJlcG9ydGVkIHRvIHRoZSBBbGVydCBwcm90b2NvbC4KKyAqCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyNDYudHh0Ij5UTFMgMS4wIHNwZWMuLCA3LjQuCisgKiBIYW5kc2hha2UgcHJvdG9jb2wuPC9hPgorICoKKyAqLworcHVibGljIGNsYXNzIFNlcnZlckhhbmRzaGFrZUltcGwgZXh0ZW5kcyBIYW5kc2hha2VQcm90b2NvbCB7CisKKyAgICAvLyBwcml2YXRlIGtleSB1c2VkIGluIGtleSBleGNoYW5nZQorICAgIHByaXZhdGUgUHJpdmF0ZUtleSBwcml2S2V5OworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBTZXJ2ZXIgSGFuZHNoYWtlIEltcGxlbWVudGF0aW9uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3duZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgU2VydmVySGFuZHNoYWtlSW1wbChPYmplY3Qgb3duZXIpIHsKKyAgICAgICAgc3VwZXIob3duZXIpOworICAgICAgICBzdGF0dXMgPSBORUVEX1VOV1JBUDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdGFydCBzZXNzaW9uIG5lZ290aWF0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc3RhcnQoKSB7CisgICAgICAgIGlmIChzZXNzaW9uID09IG51bGwpIHsgLy8gaW5pdGlhbCBoYW5kc2hha2UKKyAgICAgICAgICAgIHN0YXR1cyA9IE5FRURfVU5XUkFQOworICAgICAgICAgICAgcmV0dXJuOyAvLyB3YWl0IGNsaWVudCBoZWxsbworICAgICAgICB9CisgICAgICAgIGlmIChjbGllbnRIZWxsbyAhPSBudWxsICYmIHRoaXMuc3RhdHVzICE9IEZJTklTSEVEKSB7CisgICAgICAgICAgICAvLyBjdXJyZW50IG5lZ290aWF0aW9uIGhhcyBub3QgY29tcGxldGVkCisgICAgICAgICAgICByZXR1cm47IC8vIGlnbm9yZQorICAgICAgICB9CisKKyAgICAgICAgLy8gcmVuZWdvdGlhdGlvbgorICAgICAgICBzZW5kSGVsbG9SZXF1ZXN0KCk7CisgICAgICAgIHN0YXR1cyA9IE5FRURfVU5XUkFQOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc2VzIGluYm91bmQgaGFuZHNoYWtlIG1lc3NhZ2VzCisgICAgICogQHBhcmFtIGJ5dGVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgdW53cmFwKGJ5dGVbXSBieXRlcykgeworCisgICAgICAgIGlvX3N0cmVhbS5hcHBlbmQoYnl0ZXMpOworICAgICAgICB3aGlsZSAoaW9fc3RyZWFtLmF2YWlsYWJsZSgpID4gMCkgeworICAgICAgICAgICAgaW50IGhhbmRzaGFrZVR5cGU7CisgICAgICAgICAgICBpbnQgbGVuZ3RoOworICAgICAgICAgICAgaW9fc3RyZWFtLm1hcmsoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaGFuZHNoYWtlVHlwZSA9IGlvX3N0cmVhbS5yZWFkKCk7CisgICAgICAgICAgICAgICAgbGVuZ3RoID0gaW9fc3RyZWFtLnJlYWRVaW50MjQoKTsKKyAgICAgICAgICAgICAgICBpZiAoaW9fc3RyZWFtLmF2YWlsYWJsZSgpIDwgbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIGlvX3N0cmVhbS5yZXNldCgpOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgc3dpdGNoIChoYW5kc2hha2VUeXBlKSB7CisgICAgICAgICAgICAgICAgY2FzZSAxOiAvLyBDTElFTlRfSEVMTE8KKyAgICAgICAgICAgICAgICAgICAgaWYgKGNsaWVudEhlbGxvICE9IG51bGwgJiYgdGhpcy5zdGF0dXMgIT0gRklOSVNIRUQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDbGllbnQgaGVsbG8gaGFzIGJlZW4gcmVjZWl2ZWQgZHVyaW5nIGhhbmRzaGFrZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuZXhwZWN0ZWRNZXNzYWdlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8vIGlmIHByb3RvY29sIHBsYW5lZCB0byBzZW5kIEhlbGxvIFJlcXVlc3QgbWVzc2FnZQorICAgICAgICAgICAgICAgICAgICAvLyAtIGNhbmNlbCB0aGlzIGRlbWFuZC4KKyAgICAgICAgICAgICAgICAgICAgbmVlZFNlbmRIZWxsb1JlcXVlc3QgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgY2xpZW50SGVsbG8gPSBuZXcgQ2xpZW50SGVsbG8oaW9fc3RyZWFtLCBsZW5ndGgpOworICAgICAgICAgICAgICAgICAgICBpZiAobm9uQmxvY2tpbmcpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlbGVnYXRlZFRhc2tzLmFkZChuZXcgRGVsZWdhdGVkVGFzayhuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzQ2xpZW50SGVsbG8oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9LCB0aGlzKSk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0NsaWVudEhlbGxvKCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICAgICAgY2FzZSAxMTogLy8gICAgQ0xJRU5UIENFUlRJRklDQVRFCisgICAgICAgICAgICAgICAgICAgIGlmIChpc1Jlc3VtaW5nIHx8IGNlcnRpZmljYXRlUmVxdWVzdCA9PSBudWxsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgc2VydmVySGVsbG9Eb25lID09IG51bGwgfHwgY2xpZW50Q2VydCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB1bmV4cGVjdGVkTWVzc2FnZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGNsaWVudENlcnQgPSBuZXcgQ2VydGlmaWNhdGVNZXNzYWdlKGlvX3N0cmVhbSwgbGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNsaWVudENlcnQuY2VydHMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJhbWV0ZXJzLmdldE5lZWRDbGllbnRBdXRoKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuSEFORFNIQUtFX0ZBSUxVUkUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSEFORFNIQUtFIEZBSUxVUkU6IG5vIGNsaWVudCBjZXJ0aWZpY2F0ZSByZWNlaXZlZCIpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF1dGhUeXBlID0gY2xpZW50Q2VydC5nZXRBdXRoVHlwZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmdldFRydXN0TWFuYWdlcigpLmNoZWNrQ2xpZW50VHJ1c3RlZCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudENlcnQuY2VydHMsIGF1dGhUeXBlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuQkFEX0NFUlRJRklDQVRFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVudHJ1c3RlZCBDbGllbnQgQ2VydGlmaWNhdGUgIiwgZSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLnBlZXJDZXJ0aWZpY2F0ZXMgPSBjbGllbnRDZXJ0LmNlcnRzOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICAgICAgY2FzZSAxNTogLy8gQ0VSVElGSUNBVEVfVkVSSUZZCisgICAgICAgICAgICAgICAgICAgIGlmIChpc1Jlc3VtaW5nCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgY2xpZW50S2V5RXhjaGFuZ2UgPT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGNsaWVudENlcnQgPT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGNsaWVudEtleUV4Y2hhbmdlLmlzRW1wdHkoKSAvL2NsaWVudCBjZXJ0aWZpY2F0ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb250YWlucyBmaXhlZCBESAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwYXJhbWV0ZXJzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgY2VydGlmaWNhdGVWZXJpZnkgIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGNoYW5nZUNpcGhlclNwZWNSZWNlaXZlZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgdW5leHBlY3RlZE1lc3NhZ2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBjZXJ0aWZpY2F0ZVZlcmlmeSA9IG5ldyBDZXJ0aWZpY2F0ZVZlcmlmeShpb19zdHJlYW0sIGxlbmd0aCk7CisKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF1dGhUeXBlID0gY2xpZW50Q2VydC5nZXRBdXRoVHlwZSgpOworICAgICAgICAgICAgICAgICAgICBEaWdpdGFsU2lnbmF0dXJlIGRzID0gbmV3IERpZ2l0YWxTaWduYXR1cmUoYXV0aFR5cGUpOworICAgICAgICAgICAgICAgICAgICBkcy5pbml0KGNsaWVudENlcnQuY2VydHNbMF0pOworICAgICAgICAgICAgICAgICAgICBieXRlW10gbWQ1X2hhc2ggPSBudWxsOworICAgICAgICAgICAgICAgICAgICBieXRlW10gc2hhX2hhc2ggPSBudWxsOworCisgICAgICAgICAgICAgICAgICAgIGlmICgiUlNBIi5lcXVhbHMoYXV0aFR5cGUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBtZDVfaGFzaCA9IGlvX3N0cmVhbS5nZXREaWdlc3RNRDV3aXRob3V0TGFzdCgpOworICAgICAgICAgICAgICAgICAgICAgICAgc2hhX2hhc2ggPSBpb19zdHJlYW0uZ2V0RGlnZXN0U0hBd2l0aG91dExhc3QoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgiRFNBIi5lcXVhbHMoYXV0aFR5cGUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzaGFfaGFzaCA9IGlvX3N0cmVhbS5nZXREaWdlc3RTSEF3aXRob3V0TGFzdCgpOworICAgICAgICAgICAgICAgICAgICAvLyBUaGUgU2lnbmF0dXJlIHNob3VsZCBiZSBlbXB0eSBpbiBjYXNlIG9mIGFub255bW91cyBzaWduYXR1cmUgYWxnb3JpdGhtOgorICAgICAgICAgICAgICAgICAgICAvLyB9IGVsc2UgaWYgKCJESCIuZXF1YWxzKGF1dGhUeXBlKSkgeworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGRzLnNldE1ENShtZDVfaGFzaCk7CisgICAgICAgICAgICAgICAgICAgIGRzLnNldFNIQShzaGFfaGFzaCk7CisgICAgICAgICAgICAgICAgICAgIGlmICghZHMudmVyaWZ5U2lnbmF0dXJlKGNlcnRpZmljYXRlVmVyaWZ5LnNpZ25lZEhhc2gpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuREVDUllQVF9FUlJPUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRFQ1JZUFQgRVJST1I6IENFUlRJRklDQVRFX1ZFUklGWSBpbmNvcnJlY3Qgc2lnbmF0dXJlIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAxNjogLy8gQ0xJRU5UX0tFWV9FWENIQU5HRQorICAgICAgICAgICAgICAgICAgICBpZiAoaXNSZXN1bWluZworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHNlcnZlckhlbGxvRG9uZSA9PSBudWxsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgY2xpZW50S2V5RXhjaGFuZ2UgIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IChjbGllbnRDZXJ0ID09IG51bGwgJiYgcGFyYW1ldGVycy5nZXROZWVkQ2xpZW50QXV0aCgpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdW5leHBlY3RlZE1lc3NhZ2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5jaXBoZXJTdWl0ZS5rZXlFeGNoYW5nZSA9PSBDaXBoZXJTdWl0ZS5LRVlfRVhDSEFOR0VfUlNBCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgc2Vzc2lvbi5jaXBoZXJTdWl0ZS5rZXlFeGNoYW5nZSA9PSBDaXBoZXJTdWl0ZS5LRVlfRVhDSEFOR0VfUlNBX0VYUE9SVCkgeworICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50S2V5RXhjaGFuZ2UgPSBuZXcgQ2xpZW50S2V5RXhjaGFuZ2UoaW9fc3RyZWFtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGgsIHNlcnZlckhlbGxvLnNlcnZlcl92ZXJzaW9uWzFdID09IDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgICAgICAgICAgICAgICAgICAgICAgQ2lwaGVyIGMgPSBudWxsOworICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJSU0EvRUNCL1BLQ1MxUGFkZGluZyIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLCBwcml2S2V5KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVNYXN0ZXJTZWNyZXQgPSBjLmRvRmluYWwoY2xpZW50S2V5RXhjaGFuZ2UuZXhjaGFuZ2Vfa2V5cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgcHJlTWFzdGVyU2VjcmV0OgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmVNYXN0ZXJTZWNyZXQubGVuZ3RoICE9IDQ4CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBwcmVNYXN0ZXJTZWNyZXRbMF0gIT0gY2xpZW50SGVsbG8uY2xpZW50X3ZlcnNpb25bMF0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHByZU1hc3RlclNlY3JldFsxXSAhPSBjbGllbnRIZWxsby5jbGllbnRfdmVyc2lvblsxXSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmNvcnJlY3QgcHJlTWFzdGVyU2VjcmV0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByZXZlbnQgYW4gYXR0YWNrIChzZWUgVExTIDEuMCBzcGVjLiwgNy40LjcuMS4pCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZU1hc3RlclNlY3JldCA9IG5ldyBieXRlWzQ4XTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycy5nZXRTZWN1cmVSYW5kb20oKS5uZXh0Qnl0ZXMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlTWFzdGVyU2VjcmV0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5JTlRFUk5BTF9FUlJPUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJTlRFUk5BTCBFUlJPUiIsIGUpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBkaWZmaWUgaGVsbG1hbiBrZXkgZXhjaGFuZ2UKKyAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudEtleUV4Y2hhbmdlID0gbmV3IENsaWVudEtleUV4Y2hhbmdlKGlvX3N0cmVhbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoLCBzZXJ2ZXJIZWxsby5zZXJ2ZXJfdmVyc2lvblsxXSA9PSAxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2xpZW50S2V5RXhjaGFuZ2UuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyBjaGVjayB0aGF0IGNsaWVudCBjZXJ0LiBESCBwYXJhbXMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYXRjaGVkIHNlcnZlciBjZXJ0LiBESCBwYXJhbXMKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsaWVudCBjZXJ0LiBjb250YWlucyBmaXhlZCBESCBwYXJhbWV0ZXJzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlTWFzdGVyU2VjcmV0ID0gKChESFB1YmxpY0tleSkgY2xpZW50Q2VydC5jZXJ0c1swXS5nZXRQdWJsaWNLZXkoKSkuZ2V0WSgpLnRvQnl0ZUFycmF5KCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtleUZhY3Rvcnkga2YgPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKCJESCIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLZXlBZ3JlZW1lbnQgYWdyZWVtZW50ID0gS2V5QWdyZWVtZW50LmdldEluc3RhbmNlKCJESCIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQdWJsaWNLZXkgY2xpZW50UHVibGljID0ga2YuZ2VuZXJhdGVQdWJsaWMobmV3IERIUHVibGljS2V5U3BlYygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRLZXlFeGNoYW5nZS5leGNoYW5nZV9rZXlzKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZlcktleUV4Y2hhbmdlLnBhcjEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJLZXlFeGNoYW5nZS5wYXIyKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFncmVlbWVudC5pbml0KHByaXZLZXkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZ3JlZW1lbnQuZG9QaGFzZShjbGllbnRQdWJsaWMsIHRydWUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVNYXN0ZXJTZWNyZXQgPSBhZ3JlZW1lbnQuZ2VuZXJhdGVTZWNyZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuSU5URVJOQUxfRVJST1IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIklOVEVSTkFMIEVSUk9SIiwgZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBjb21wdXRlck1hc3RlclNlY3JldCgpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICAgIGNhc2UgMjA6IC8vIEZJTklTSEVECisgICAgICAgICAgICAgICAgICAgIGlmICghaXNSZXN1bWluZyAmJiAhY2hhbmdlQ2lwaGVyU3BlY1JlY2VpdmVkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB1bmV4cGVjdGVkTWVzc2FnZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgY2xpZW50RmluaXNoZWQgPSBuZXcgRmluaXNoZWQoaW9fc3RyZWFtLCBsZW5ndGgpOworICAgICAgICAgICAgICAgICAgICB2ZXJpZnlGaW5pc2hlZChjbGllbnRGaW5pc2hlZC5nZXREYXRhKCkpOworICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmNvbnRleHQgPSBwYXJhbWV0ZXJzLmdldFNlcnZlclNlc3Npb25Db250ZXh0KCk7CisgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuZ2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKS5wdXRTZXNzaW9uKHNlc3Npb24pOworICAgICAgICAgICAgICAgICAgICBpZiAoIWlzUmVzdW1pbmcpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRDaGFuZ2VDaXBoZXJTcGVjKCk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmxhc3RBY2Nlc3NlZFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IEZJTklTSEVEOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgIHVuZXhwZWN0ZWRNZXNzYWdlKCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gaW8gc3RyZWFtIGRvc24ndCBjb250YWluIGNvbXBsZXRlIGhhbmRzaGFrZSBtZXNzYWdlCisgICAgICAgICAgICAgICAgaW9fc3RyZWFtLnJlc2V0KCk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIC8qKgorICAgICAqIFByb2Nlc3NlcyBTU0x2MiBIZWxsbyBtZXNzYWdlCisgICAgICogQCBzZWUgVExTIDEuMCBzcGVjLiwgRS4xLiBWZXJzaW9uIDIgY2xpZW50IGhlbGxvCisgICAgICogQHBhcmFtIGJ5dGVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgdW53cmFwU1NMdjIoYnl0ZVtdIGJ5dGVzKSB7CisgICAgICAgIGlvX3N0cmVhbS5hcHBlbmQoYnl0ZXMpOworICAgICAgICBpb19zdHJlYW0ubWFyaygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2xpZW50SGVsbG8gPSBuZXcgQ2xpZW50SGVsbG8oaW9fc3RyZWFtKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaW9fc3RyZWFtLnJlc2V0KCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKG5vbkJsb2NraW5nKSB7CisgICAgICAgICAgICBkZWxlZ2F0ZWRUYXNrcy5hZGQobmV3IERlbGVnYXRlZFRhc2sobmV3IFJ1bm5hYmxlKCkgeworICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0NsaWVudEhlbGxvKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSwgdGhpcykpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHByb2Nlc3NDbGllbnRIZWxsbygpOworICAgIH0KKworICAgIC8qKgorICAgICAqCisgICAgICogUHJvY2Vzc2VzIENsaWVudCBIZWxsbyBtZXNzYWdlLgorICAgICAqIFNlcnZlciByZXNwb25kcyB0byBjbGllbnQgaGVsbG8gbWVzc2FnZSB3aXRoIHNlcnZlciBoZWxsbworICAgICAqIGFuZCAoaWYgbmVjZXNzYXJ5KSBzZXJ2ZXIgY2VydGlmaWNhdGUsIHNlcnZlciBrZXkgZXhjaGFuZ2UsCisgICAgICogY2VydGlmaWNhdGUgcmVxdWVzdCwgYW5kIHNlcnZlciBoZWxsbyBkb25lIG1lc3NhZ2VzLgorICAgICAqLworICAgIHZvaWQgcHJvY2Vzc0NsaWVudEhlbGxvKCkgeworICAgICAgICBDaXBoZXJTdWl0ZSBjaXBoZXJfc3VpdGU7CisKKyAgICAgICAgLy8gY2hlY2sgdGhhdCBjbGllbnRIZWxsbyBjb250YWlucyBDb21wcmVzc2lvbk1ldGhvZC5udWxsCisgICAgICAgIGNoZWNrQ29tcHJlc3Npb246IHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2xpZW50SGVsbG8uY29tcHJlc3Npb25fbWV0aG9kcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChjbGllbnRIZWxsby5jb21wcmVzc2lvbl9tZXRob2RzW2ldID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWsgY2hlY2tDb21wcmVzc2lvbjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuSEFORFNIQUtFX0ZBSUxVUkUsCisgICAgICAgICAgICAgICAgICAgICAgICJIQU5EU0hBS0UgRkFJTFVSRS4gSW5jb3JyZWN0IGNsaWVudCBoZWxsbyBtZXNzYWdlIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIVByb3RvY29sVmVyc2lvbi5pc1N1cHBvcnRlZChjbGllbnRIZWxsby5jbGllbnRfdmVyc2lvbikpIHsKKyAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5QUk9UT0NPTF9WRVJTSU9OLAorICAgICAgICAgICAgICAgICAgICAgICAiUFJPVE9DT0wgVkVSU0lPTi4gVW5zdXBwb3J0ZWQgY2xpZW50IHZlcnNpb24gIgorICAgICAgICAgICAgICAgICAgICAgICArIGNsaWVudEhlbGxvLmNsaWVudF92ZXJzaW9uWzBdCisgICAgICAgICAgICAgICAgICAgICAgICsgY2xpZW50SGVsbG8uY2xpZW50X3ZlcnNpb25bMV0pOworICAgICAgICB9CisKKyAgICAgICAgaXNSZXN1bWluZyA9IGZhbHNlOworICAgICAgICBGSU5EOiBpZiAoY2xpZW50SGVsbG8uc2Vzc2lvbl9pZC5sZW5ndGggIT0gMCkgeworICAgICAgICAgICAgLy8gY2xpZW50IHdpc2hlcyB0byByZXVzZSBzZXNzaW9uCisKKyAgICAgICAgICAgIFNTTFNlc3Npb25JbXBsIHNlc3Npb25Ub1Jlc3VtZTsKKyAgICAgICAgICAgIGJvb2xlYW4gcmV1c2VDdXJyZW50ID0gZmFsc2U7CisKKyAgICAgICAgICAgIC8vIHJldXNlIGN1cnJlbnQgc2Vzc2lvbgorICAgICAgICAgICAgaWYgKHNlc3Npb24gIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAmJiBBcnJheXMuZXF1YWxzKHNlc3Npb24uaWQsIGNsaWVudEhlbGxvLnNlc3Npb25faWQpKSB7CisgICAgICAgICAgICAgICAgaWYgKHNlc3Npb24uaXNWYWxpZCgpKSB7CisgICAgICAgICAgICAgICAgICAgIGlzUmVzdW1pbmcgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICBicmVhayBGSU5EOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXVzZUN1cnJlbnQgPSB0cnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBmaW5kIHNlc3Npb24gaW4gY2FzaAorICAgICAgICAgICAgc2Vzc2lvblRvUmVzdW1lID0gZmluZFNlc3Npb25Ub1Jlc3VtZShjbGllbnRIZWxsby5zZXNzaW9uX2lkKTsKKyAgICAgICAgICAgIGlmIChzZXNzaW9uVG9SZXN1bWUgPT0gbnVsbCB8fCAhc2Vzc2lvblRvUmVzdW1lLmlzVmFsaWQoKSkgeworICAgICAgICAgICAgICAgIGlmICghcGFyYW1ldGVycy5nZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oKSkgeworICAgICAgICAgICAgICAgICAgICBpZiAocmV1c2VDdXJyZW50KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBjYW4gY29udGludWUgY3VycmVudCBzZXNzaW9uCisgICAgICAgICAgICAgICAgICAgICAgICBzZW5kV2FybmluZ0FsZXJ0KEFsZXJ0UHJvdG9jb2wuTk9fUkVORUdPVElBVElPTik7CisgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBOT1RfSEFORFNIQUtJTkc7CisgICAgICAgICAgICAgICAgICAgICAgICBjbGVhck1lc3NhZ2VzKCk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgLy8gdGhyb3cgQWxlcnRFeGNlcHRpb24KKyAgICAgICAgICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLkhBTkRTSEFLRV9GQUlMVVJFLCAiU1NMIFNlc3Npb24gbWF5IG5vdCBiZSBjcmVhdGVkIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHNlc3Npb24gPSBudWxsOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzZXNzaW9uID0gKFNTTFNlc3Npb25JbXBsKXNlc3Npb25Ub1Jlc3VtZS5jbG9uZSgpOworICAgICAgICAgICAgICAgIGlzUmVzdW1pbmcgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKGlzUmVzdW1pbmcpIHsKKyAgICAgICAgICAgIGNpcGhlcl9zdWl0ZSA9IHNlc3Npb24uY2lwaGVyU3VpdGU7CisgICAgICAgICAgICAvLyBjbGllbnRIZWxsby5jaXBoZXJfc3VpdGVzIG11c3QgaW5jbHVkZSBhdCBsZWFzdCBjaXBoZXJfc3VpdGUgZnJvbSB0aGUgc2Vzc2lvbgorICAgICAgICAgICAgY2hlY2tDaXBoZXJTdWl0ZTogeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2xpZW50SGVsbG8uY2lwaGVyX3N1aXRlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBpZiAoY2lwaGVyX3N1aXRlLmVxdWFscyhjbGllbnRIZWxsby5jaXBoZXJfc3VpdGVzW2ldKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgY2hlY2tDaXBoZXJTdWl0ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuSEFORFNIQUtFX0ZBSUxVUkUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAiSEFORFNIQUtFIEZBSUxVUkUuIEluY29ycmVjdCBjbGllbnQgaGVsbG8gbWVzc2FnZSIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY2lwaGVyX3N1aXRlID0gc2VsZWN0U3VpdGUoY2xpZW50SGVsbG8uY2lwaGVyX3N1aXRlcyk7CisgICAgICAgICAgICBpZiAoY2lwaGVyX3N1aXRlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuSEFORFNIQUtFX0ZBSUxVUkUsICJIQU5EU0hBS0UgRkFJTFVSRS4gTk8gQ09NTU9OIFNVSVRFIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIXBhcmFtZXRlcnMuZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCkpIHsKKyAgICAgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuSEFORFNIQUtFX0ZBSUxVUkUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1NMIFNlc3Npb24gbWF5IG5vdCBiZSBjcmVhdGVkIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzZXNzaW9uID0gbmV3IFNTTFNlc3Npb25JbXBsKGNpcGhlcl9zdWl0ZSwgcGFyYW1ldGVycy5nZXRTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICBpZiAoZW5naW5lT3duZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlc3Npb24uc2V0UGVlcihlbmdpbmVPd25lci5nZXRQZWVySG9zdCgpLCBlbmdpbmVPd25lci5nZXRQZWVyUG9ydCgpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc2Vzc2lvbi5zZXRQZWVyKHNvY2tldE93bmVyLmdldEluZXRBZGRyZXNzKCkuZ2V0SG9zdE5hbWUoKSwgc29ja2V0T3duZXIuZ2V0UG9ydCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJlY29yZFByb3RvY29sLnNldFZlcnNpb24oY2xpZW50SGVsbG8uY2xpZW50X3ZlcnNpb24pOworICAgICAgICBzZXNzaW9uLnByb3RvY29sID0gUHJvdG9jb2xWZXJzaW9uLmdldEJ5VmVyc2lvbihjbGllbnRIZWxsby5jbGllbnRfdmVyc2lvbik7CisgICAgICAgIHNlc3Npb24uY2xpZW50UmFuZG9tID0gY2xpZW50SGVsbG8ucmFuZG9tOworCisgICAgICAgIC8vIGNyZWF0ZSBzZXJ2ZXIgaGVsbG8gbWVzc2FnZQorICAgICAgICBzZXJ2ZXJIZWxsbyA9IG5ldyBTZXJ2ZXJIZWxsbyhwYXJhbWV0ZXJzLmdldFNlY3VyZVJhbmRvbSgpLAorICAgICAgICAgICAgICAgIGNsaWVudEhlbGxvLmNsaWVudF92ZXJzaW9uLAorICAgICAgICAgICAgICAgIHNlc3Npb24uZ2V0SWQoKSwgY2lwaGVyX3N1aXRlLCAoYnl0ZSkgMCk7IC8vQ29tcHJlc3Npb25NZXRob2QubnVsbAorICAgICAgICBzZXNzaW9uLnNlcnZlclJhbmRvbSA9IHNlcnZlckhlbGxvLnJhbmRvbTsKKyAgICAgICAgc2VuZChzZXJ2ZXJIZWxsbyk7CisgICAgICAgIGlmIChpc1Jlc3VtaW5nKSB7CisgICAgICAgICAgICBzZW5kQ2hhbmdlQ2lwaGVyU3BlYygpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLy8gICAgY3JlYXRlIGFuZCBzZW5kIHNlcnZlciBjZXJ0aWZpY2F0ZSBtZXNzYWdlIGlmIG5lZWRlZAorICAgICAgICBpZiAoIWNpcGhlcl9zdWl0ZS5pc0Fub255bW91cygpKSB7IC8vIG5lZWQgdG8gc2VuZCBzZXJ2ZXIgY2VydGlmaWNhdGUKKyAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIGNlcnRzID0gbnVsbDsKKyAgICAgICAgICAgIFN0cmluZyBjZXJ0VHlwZSA9IGNpcGhlcl9zdWl0ZS5nZXRTZXJ2ZXJLZXlUeXBlKCk7CisgICAgICAgICAgICBpZiAoY2VydFR5cGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5IQU5EU0hBS0VfRkFJTFVSRSwgIk5PIENFUlQgVFlQRSBGT1IgIiArIGNpcGhlcl9zdWl0ZS5nZXROYW1lKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gb2J0YWluIGNlcnRpZmljYXRlcyBmcm9tIGtleSBtYW5hZ2VyCisgICAgICAgICAgICBTdHJpbmcgYWxpYXMgPSBudWxsOworICAgICAgICAgICAgWDUwOUtleU1hbmFnZXIga20gPSBwYXJhbWV0ZXJzLmdldEtleU1hbmFnZXIoKTsKKyAgICAgICAgICAgIGlmIChrbSBpbnN0YW5jZW9mIFg1MDlFeHRlbmRlZEtleU1hbmFnZXIpIHsKKyAgICAgICAgICAgICAgICBYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyIGVrbSA9IChYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyKWttOworICAgICAgICAgICAgICAgIGlmICh0aGlzLnNvY2tldE93bmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYWxpYXMgPSBla20uY2hvb3NlU2VydmVyQWxpYXMoY2VydFR5cGUsIG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zb2NrZXRPd25lcik7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYWxpYXMgPSBla20uY2hvb3NlRW5naW5lU2VydmVyQWxpYXMoY2VydFR5cGUsIG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbmdpbmVPd25lcik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChhbGlhcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGNlcnRzID0gZWttLmdldENlcnRpZmljYXRlQ2hhaW4oYWxpYXMpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYWxpYXMgPSBrbS5jaG9vc2VTZXJ2ZXJBbGlhcyhjZXJ0VHlwZSwgbnVsbCwgdGhpcy5zb2NrZXRPd25lcik7CisgICAgICAgICAgICAgICAgaWYgKGFsaWFzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgY2VydHMgPSBrbS5nZXRDZXJ0aWZpY2F0ZUNoYWluKGFsaWFzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChjZXJ0cyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLkhBTkRTSEFLRV9GQUlMVVJFLCAiTk8gU0VSVkVSIENFUlRJRklDQVRFIEZPVU5EIik7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2Vzc2lvbi5sb2NhbENlcnRpZmljYXRlcyA9IGNlcnRzOworICAgICAgICAgICAgc2VydmVyQ2VydCA9IG5ldyBDZXJ0aWZpY2F0ZU1lc3NhZ2UoY2VydHMpOworICAgICAgICAgICAgcHJpdktleSA9IGttLmdldFByaXZhdGVLZXkoYWxpYXMpOworICAgICAgICAgICAgc2VuZChzZXJ2ZXJDZXJ0KTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNyZWF0ZSBhbmQgc2VuZCBzZXJ2ZXIga2V5IGV4Y2hhbmdlIG1lc3NhZ2UgaWYgbmVlZGVkCisgICAgICAgIFJTQVB1YmxpY0tleSByc2FrZXkgPSBudWxsOworICAgICAgICBESFB1YmxpY0tleVNwZWMgZGhrZXlTcGVjID0gbnVsbDsKKyAgICAgICAgYnl0ZVtdIGhhc2ggPSBudWxsOworICAgICAgICBCaWdJbnRlZ2VyIHAgPSBudWxsOworICAgICAgICBCaWdJbnRlZ2VyIGcgPSBudWxsOworCisgICAgICAgIEtleVBhaXJHZW5lcmF0b3Iga3BnID0gbnVsbDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGNpcGhlcl9zdWl0ZS5rZXlFeGNoYW5nZSA9PSBDaXBoZXJTdWl0ZS5LRVlfRVhDSEFOR0VfUlNBX0VYUE9SVCkgeworICAgICAgICAgICAgICAgIFB1YmxpY0tleSBwayA9IHNlcnZlckNlcnQuY2VydHNbMF0uZ2V0UHVibGljS2V5KCk7CisgICAgICAgICAgICAgICAgaWYgKGdldFJTQUtleUxlbmd0aChwaykgPiA1MTIpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8ga2V5IGlzIGxvbmdlciB0aGFuIDUxMiBiaXRzCisgICAgICAgICAgICAgICAgICAgIGtwZyA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIlJTQSIpOworICAgICAgICAgICAgICAgICAgICBrcGcuaW5pdGlhbGl6ZSg1MTIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY2lwaGVyX3N1aXRlLmtleUV4Y2hhbmdlID09IENpcGhlclN1aXRlLktFWV9FWENIQU5HRV9ESEVfRFNTCisgICAgICAgICAgICAgICAgICAgIHx8IGNpcGhlcl9zdWl0ZS5rZXlFeGNoYW5nZSA9PSBDaXBoZXJTdWl0ZS5LRVlfRVhDSEFOR0VfREhFX0RTU19FWFBPUlQKKyAgICAgICAgICAgICAgICAgICAgfHwgY2lwaGVyX3N1aXRlLmtleUV4Y2hhbmdlID09IENpcGhlclN1aXRlLktFWV9FWENIQU5HRV9ESEVfUlNBCisgICAgICAgICAgICAgICAgICAgIHx8IGNpcGhlcl9zdWl0ZS5rZXlFeGNoYW5nZSA9PSBDaXBoZXJTdWl0ZS5LRVlfRVhDSEFOR0VfREhFX1JTQV9FWFBPUlQKKyAgICAgICAgICAgICAgICAgICAgfHwgY2lwaGVyX3N1aXRlLmtleUV4Y2hhbmdlID09IENpcGhlclN1aXRlLktFWV9FWENIQU5HRV9ESF9hbm9uCisgICAgICAgICAgICAgICAgICAgIHx8IGNpcGhlcl9zdWl0ZS5rZXlFeGNoYW5nZSA9PSBDaXBoZXJTdWl0ZS5LRVlfRVhDSEFOR0VfREhfYW5vbl9FWFBPUlQpIHsKKyAgICAgICAgICAgICAgICBrcGcgPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKCJESCIpOworICAgICAgICAgICAgICAgIHAgPSBuZXcgQmlnSW50ZWdlcigxLCBESFBhcmFtZXRlcnMuZ2V0UHJpbWUoKSk7CisgICAgICAgICAgICAgICAgZyA9IG5ldyBCaWdJbnRlZ2VyKCIyIik7CisgICAgICAgICAgICAgICAgREhQYXJhbWV0ZXJTcGVjIHNwZWMgPSBuZXcgREhQYXJhbWV0ZXJTcGVjKHAsIGcpOworICAgICAgICAgICAgICAgIGtwZy5pbml0aWFsaXplKHNwZWMpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLklOVEVSTkFMX0VSUk9SLCAiSU5URVJOQUwgRVJST1IiLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChrcGcgIT0gbnVsbCkgeworICAgICAgICAgICAgLy8gbmVlZCB0byBzZW5kIHNlcnZlciBrZXkgZXhjaGFuZ2UgbWVzc2FnZQorICAgICAgICAgICAgRGlnaXRhbFNpZ25hdHVyZSBkcyA9IG5ldyBEaWdpdGFsU2lnbmF0dXJlKGNpcGhlcl9zdWl0ZS5hdXRoVHlwZSk7CisgICAgICAgICAgICBLZXlQYWlyIGtwID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga3AgPSBrcGcuZ2VuS2V5UGFpcigpOworICAgICAgICAgICAgICAgIGlmIChjaXBoZXJfc3VpdGUua2V5RXhjaGFuZ2UgPT0gQ2lwaGVyU3VpdGUuS0VZX0VYQ0hBTkdFX1JTQV9FWFBPUlQpIHsKKyAgICAgICAgICAgICAgICAgICAgcnNha2V5ID0gKFJTQVB1YmxpY0tleSkga3AuZ2V0UHVibGljKCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgREhQdWJsaWNLZXkgZGhrZXkgPSAoREhQdWJsaWNLZXkpIGtwLmdldFB1YmxpYygpOworICAgICAgICAgICAgICAgICAgICBLZXlGYWN0b3J5IGtmID0gS2V5RmFjdG9yeS5nZXRJbnN0YW5jZSgiREgiKTsKKyAgICAgICAgICAgICAgICAgICAgZGhrZXlTcGVjID0ga2YuZ2V0S2V5U3BlYyhkaGtleSwgREhQdWJsaWNLZXlTcGVjLmNsYXNzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKCFjaXBoZXJfc3VpdGUuaXNBbm9ueW1vdXMoKSkgeyAvLyBjYWxjdWxhdGUgc2lnbmVkX3BhcmFtcworCisgICAgICAgICAgICAgICAgICAgIC8vIGluaXQgYnkgcHJpdmF0ZSBrZXkgd2hpY2ggY29ycmVzcG9uZCB0bworICAgICAgICAgICAgICAgICAgICAvLyBzZXJ2ZXIgY2VydGlmaWNhdGUKKyAgICAgICAgICAgICAgICAgICAgZHMuaW5pdChwcml2S2V5KTsKKworICAgICAgICAgICAgICAgICAgICAvLyB1c2UgZW1waGVtZXJhbCBrZXkgZm9yIGtleSBleGNoYW5nZQorICAgICAgICAgICAgICAgICAgICBwcml2S2V5ID0ga3AuZ2V0UHJpdmF0ZSgpOworICAgICAgICAgICAgICAgICAgICBkcy51cGRhdGUoY2xpZW50SGVsbG8uZ2V0UmFuZG9tKCkpOworICAgICAgICAgICAgICAgICAgICBkcy51cGRhdGUoc2VydmVySGVsbG8uZ2V0UmFuZG9tKCkpOworCisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSB0bXA7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSB0bXBMZW5ndGggPSBuZXcgYnl0ZVsyXTsKKy8vRklYTUUgMV9ieXRlPT0weDAwCisgICAgICAgICAgICAgICAgICAgIGlmIChjaXBoZXJfc3VpdGUua2V5RXhjaGFuZ2UgPT0gQ2lwaGVyU3VpdGUuS0VZX0VYQ0hBTkdFX1JTQV9FWFBPUlQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IFNlcnZlcktleUV4Y2hhbmdlLnRvVW5zaWduZWRCeXRlQXJyYXkocnNha2V5LmdldE1vZHVsdXMoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB0bXBMZW5ndGhbMF0gPSAoYnl0ZSkgKCh0bXAubGVuZ3RoICYgMHhGRjAwKSA+Pj4gOCk7CisgICAgICAgICAgICAgICAgICAgICAgICB0bXBMZW5ndGhbMV0gPSAoYnl0ZSkgKHRtcC5sZW5ndGggJiAweEZGKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRzLnVwZGF0ZSh0bXBMZW5ndGgpOworICAgICAgICAgICAgICAgICAgICAgICAgZHMudXBkYXRlKHRtcCk7CisgICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSBTZXJ2ZXJLZXlFeGNoYW5nZS50b1Vuc2lnbmVkQnl0ZUFycmF5KHJzYWtleS5nZXRQdWJsaWNFeHBvbmVudCgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRtcExlbmd0aFswXSA9IChieXRlKSAoKHRtcC5sZW5ndGggJiAweEZGMDApID4+PiA4KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRtcExlbmd0aFsxXSA9IChieXRlKSAodG1wLmxlbmd0aCAmIDB4RkYpOworICAgICAgICAgICAgICAgICAgICAgICAgZHMudXBkYXRlKHRtcExlbmd0aCk7CisgICAgICAgICAgICAgICAgICAgICAgICBkcy51cGRhdGUodG1wKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IFNlcnZlcktleUV4Y2hhbmdlLnRvVW5zaWduZWRCeXRlQXJyYXkoZGhrZXlTcGVjLmdldFAoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB0bXBMZW5ndGhbMF0gPSAoYnl0ZSkgKCh0bXAubGVuZ3RoICYgMHhGRjAwKSA+Pj4gOCk7CisgICAgICAgICAgICAgICAgICAgICAgICB0bXBMZW5ndGhbMV0gPSAoYnl0ZSkgKHRtcC5sZW5ndGggJiAweEZGKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRzLnVwZGF0ZSh0bXBMZW5ndGgpOworICAgICAgICAgICAgICAgICAgICAgICAgZHMudXBkYXRlKHRtcCk7CisgICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSBTZXJ2ZXJLZXlFeGNoYW5nZS50b1Vuc2lnbmVkQnl0ZUFycmF5KGRoa2V5U3BlYy5nZXRHKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgdG1wTGVuZ3RoWzBdID0gKGJ5dGUpICgodG1wLmxlbmd0aCAmIDB4RkYwMCkgPj4+IDgpOworICAgICAgICAgICAgICAgICAgICAgICAgdG1wTGVuZ3RoWzFdID0gKGJ5dGUpICh0bXAubGVuZ3RoICYgMHhGRik7CisgICAgICAgICAgICAgICAgICAgICAgICBkcy51cGRhdGUodG1wTGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRzLnVwZGF0ZSh0bXApOworICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gU2VydmVyS2V5RXhjaGFuZ2UudG9VbnNpZ25lZEJ5dGVBcnJheShkaGtleVNwZWMuZ2V0WSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRtcExlbmd0aFswXSA9IChieXRlKSAoKHRtcC5sZW5ndGggJiAweEZGMDApID4+PiA4KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRtcExlbmd0aFsxXSA9IChieXRlKSAodG1wLmxlbmd0aCAmIDB4RkYpOworICAgICAgICAgICAgICAgICAgICAgICAgZHMudXBkYXRlKHRtcExlbmd0aCk7CisgICAgICAgICAgICAgICAgICAgICAgICBkcy51cGRhdGUodG1wKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBoYXNoID0gZHMuc2lnbigpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHByaXZLZXkgPSBrcC5nZXRQcml2YXRlKCk7IC8vIHVzZSBlbXBoZW1lcmFsIGtleSBmb3Iga2V5IGV4Y2hhbmdlCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuSU5URVJOQUxfRVJST1IsICJJTlRFUk5BTCBFUlJPUiIsIGUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoY2lwaGVyX3N1aXRlLmtleUV4Y2hhbmdlID09IENpcGhlclN1aXRlLktFWV9FWENIQU5HRV9SU0FfRVhQT1JUKSB7CisgICAgICAgICAgICAgICAgc2VydmVyS2V5RXhjaGFuZ2UgPSBuZXcgU2VydmVyS2V5RXhjaGFuZ2UocnNha2V5LmdldE1vZHVsdXMoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHJzYWtleS5nZXRQdWJsaWNFeHBvbmVudCgpLCBudWxsLCBoYXNoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc2VydmVyS2V5RXhjaGFuZ2UgPSBuZXcgU2VydmVyS2V5RXhjaGFuZ2UocCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGcsIGRoa2V5U3BlYy5nZXRZKCksIGhhc2gpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2VuZChzZXJ2ZXJLZXlFeGNoYW5nZSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBDRVJUSUZJQ0FURV9SRVFVRVNUCisgICAgICAgIGNlcnRSZXF1ZXN0OiBpZiAocGFyYW1ldGVycy5nZXRXYW50Q2xpZW50QXV0aCgpCisgICAgICAgICAgICAgICAgfHwgcGFyYW1ldGVycy5nZXROZWVkQ2xpZW50QXV0aCgpKSB7CisgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGVbXSBhY2NlcHRlZDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgWDUwOVRydXN0TWFuYWdlciB0bSA9IHBhcmFtZXRlcnMuZ2V0VHJ1c3RNYW5hZ2VyKCk7CisgICAgICAgICAgICAgICAgYWNjZXB0ZWQgPSB0bS5nZXRBY2NlcHRlZElzc3VlcnMoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gZG9uJ3Qgc2VuZCBjZXJ0aWZpY2F0ZVJlcXVlc3QKKyAgICAgICAgICAgICAgICBicmVhayBjZXJ0UmVxdWVzdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ5dGVbXSByZXF1ZXN0ZWRDbGllbnRDZXJ0VHlwZXMgPSB7IENpcGhlclN1aXRlLlRMU19DVF9SU0FfU0lHTiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENpcGhlclN1aXRlLlRMU19DVF9EU1NfU0lHTiB9OworICAgICAgICAgICAgY2VydGlmaWNhdGVSZXF1ZXN0ID0gbmV3IENlcnRpZmljYXRlUmVxdWVzdCgKKyAgICAgICAgICAgICAgICAgICAgcmVxdWVzdGVkQ2xpZW50Q2VydFR5cGVzLCBhY2NlcHRlZCk7CisgICAgICAgICAgICBzZW5kKGNlcnRpZmljYXRlUmVxdWVzdCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBTRVJWRVJfSEVMTE9fRE9ORQorICAgICAgICBzZXJ2ZXJIZWxsb0RvbmUgPSBuZXcgU2VydmVySGVsbG9Eb25lKCk7CisgICAgICAgIHNlbmQoc2VydmVySGVsbG9Eb25lKTsKKyAgICAgICAgc3RhdHVzID0gTkVFRF9VTldSQVA7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbmQgc2VuZHMgZmluaXNoZWQgbWVzc2FnZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIG1ha2VGaW5pc2hlZCgpIHsKKyAgICAgICAgYnl0ZVtdIHZlcmlmeV9kYXRhOworICAgICAgICBib29sZWFuIGlzVExTID0gKHNlcnZlckhlbGxvLnNlcnZlcl92ZXJzaW9uWzFdID09IDEpOyAvLyBUTFMgMS4wIHByb3RvY29sCisgICAgICAgIGlmIChpc1RMUykgeworICAgICAgICAgICAgdmVyaWZ5X2RhdGEgPSBuZXcgYnl0ZVsxMl07CisgICAgICAgICAgICBjb21wdXRlclZlcmlmeURhdGFUTFMoInNlcnZlciBmaW5pc2hlZCIsIHZlcmlmeV9kYXRhKTsKKyAgICAgICAgfSBlbHNlIHsgLy8gU1NMIDMuMCBwcm90b2NvbCAoaHR0cDovL3dwLm5ldHNjYXBlLmNvbS9lbmcvc3NsMykKKyAgICAgICAgICAgIHZlcmlmeV9kYXRhID0gbmV3IGJ5dGVbMzZdOworICAgICAgICAgICAgY29tcHV0ZXJWZXJpZnlEYXRhU1NMdjMoU1NMdjNDb25zdGFudHMuc2VydmVyLCB2ZXJpZnlfZGF0YSk7CisgICAgICAgIH0KKyAgICAgICAgc2VydmVyRmluaXNoZWQgPSBuZXcgRmluaXNoZWQodmVyaWZ5X2RhdGEpOworICAgICAgICBzZW5kKHNlcnZlckZpbmlzaGVkKTsKKyAgICAgICAgaWYgKGlzUmVzdW1pbmcpIHsKKyAgICAgICAgICAgIGlmIChpc1RMUykgeworICAgICAgICAgICAgICAgIGNvbXB1dGVyUmVmZXJlbmNlVmVyaWZ5RGF0YVRMUygiY2xpZW50IGZpbmlzaGVkIik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGNvbXB1dGVyUmVmZXJlbmNlVmVyaWZ5RGF0YVNTTHYzKFNTTHYzQ29uc3RhbnRzLmNsaWVudCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzdGF0dXMgPSBORUVEX1VOV1JBUDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHNlc3Npb24ubGFzdEFjY2Vzc2VkVGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICAgICAgc3RhdHVzID0gRklOSVNIRUQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBmaW5kIHNlc3NzaW9uIGluIHRoZSBzZXNzaW9uIGhhc2gKKyAgICBwcml2YXRlIFNTTFNlc3Npb25JbXBsIGZpbmRTZXNzaW9uVG9SZXN1bWUoYnl0ZVtdIHNlc3Npb25faWQpIHsKKyAgICAgICAgcmV0dXJuIChTU0xTZXNzaW9uSW1wbClwYXJhbWV0ZXJzLmdldFNlcnZlclNlc3Npb25Db250ZXh0KCkuZ2V0U2Vzc2lvbihzZXNzaW9uX2lkKTsKKyAgICB9CisKKyAgICAvLyBmaW5kIGFwcHJvcHJpYXRlIGNpcGhlcl9zdWl0ZSBpbiB0aGUgY2xpZW50IHN1aXRlcworICAgIHByaXZhdGUgQ2lwaGVyU3VpdGUgc2VsZWN0U3VpdGUoQ2lwaGVyU3VpdGVbXSBjbGllbnRTdWl0ZXMpIHsKKyAgICAgICAgZm9yIChDaXBoZXJTdWl0ZSBjbGllbnRTdWl0ZSA6IGNsaWVudFN1aXRlcykgeworICAgICAgICAgICAgaWYgKCFjbGllbnRTdWl0ZS5zdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZvciAoQ2lwaGVyU3VpdGUgZW5hYmxlZENpcGhlclN1aXRlIDogcGFyYW1ldGVycy5nZXRFbmFibGVkQ2lwaGVyU3VpdGVzTWVtYmVyKCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoY2xpZW50U3VpdGUuZXF1YWxzKGVuYWJsZWRDaXBoZXJTdWl0ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNsaWVudFN1aXRlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgaW5ib3VuZCBDaGFuZ2VDaXBoZXJTcGVjIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCByZWNlaXZlQ2hhbmdlQ2lwaGVyU3BlYygpIHsKKyAgICAgICAgaWYgKGlzUmVzdW1pbmcpIHsKKyAgICAgICAgICAgIGlmIChzZXJ2ZXJGaW5pc2hlZCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdW5leHBlY3RlZE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgY2hhbmdlQ2lwaGVyU3BlY1JlY2VpdmVkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmICgocGFyYW1ldGVycy5nZXROZWVkQ2xpZW50QXV0aCgpICYmIGNsaWVudENlcnQgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgfHwgY2xpZW50S2V5RXhjaGFuZ2UgPT0gbnVsbAorICAgICAgICAgICAgICAgICAgICB8fCAoY2xpZW50Q2VydCAhPSBudWxsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgIWNsaWVudEtleUV4Y2hhbmdlLmlzRW1wdHkoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGNlcnRpZmljYXRlVmVyaWZ5ID09IG51bGwpKSB7CisgICAgICAgICAgICAgICAgdW5leHBlY3RlZE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgY2hhbmdlQ2lwaGVyU3BlY1JlY2VpdmVkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzZXJ2ZXJIZWxsby5zZXJ2ZXJfdmVyc2lvblsxXSA9PSAxKSB7CisgICAgICAgICAgICAgICAgY29tcHV0ZXJSZWZlcmVuY2VWZXJpZnlEYXRhVExTKCJjbGllbnQgZmluaXNoZWQiKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgY29tcHV0ZXJSZWZlcmVuY2VWZXJpZnlEYXRhU1NMdjMoU1NMdjNDb25zdGFudHMuY2xpZW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU2VydmVySGVsbG8uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NlcnZlckhlbGxvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDBhMjVmOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NlcnZlckhlbGxvLmphdmEKQEAgLTAsMCArMSwxMzYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgbGliY29yZS5pby5TdHJlYW1zOworCisvKioKKyAqCisgKiBSZXByZXNlbnRzIHNlcnZlciBoZWxsbyBtZXNzYWdlLgorICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMjQ2LnR4dCI+VExTIDEuMCBzcGVjLiwgNy40LjEuMy4KKyAqIFNlcnZlciBoZWxsby48L2E+CisgKi8KK3B1YmxpYyBjbGFzcyBTZXJ2ZXJIZWxsbyBleHRlbmRzIE1lc3NhZ2UgeworCisgICAgLyoqCisgICAgICogU2VydmVyIHZlcnNpb24KKyAgICAgKi8KKyAgICBieXRlW10gc2VydmVyX3ZlcnNpb24gPSBuZXcgYnl0ZVsyXTsKKworICAgIC8qKgorICAgICAqIFJhbmRvbSBieXRlcworICAgICAqLworICAgIGJ5dGVbXSByYW5kb20gPSBuZXcgYnl0ZVszMl07CisKKyAgICAvKioKKyAgICAgKiBTZXNzaW9uIGlkCisgICAgICovCisgICAgYnl0ZVtdIHNlc3Npb25faWQ7CisKKyAgICAvKioKKyAgICAgKiBTZWxlY3RlZCBjaXBoZXIgc3VpdGUKKyAgICAgKi8KKyAgICBDaXBoZXJTdWl0ZSBjaXBoZXJfc3VpdGU7CisKKyAgICAvKioKKyAgICAgKiBTZWxlY3RlZCBjb21wcmVzc2lvbiBtZXRob2QKKyAgICAgKi8KKyAgICBieXRlIGNvbXByZXNzaW9uX21ldGhvZDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgb3V0Ym91bmQgbWVzc2FnZQorICAgICAqIEBwYXJhbSBzcgorICAgICAqIEBwYXJhbSBzZXJ2ZXJfdmVyc2lvbgorICAgICAqIEBwYXJhbSBzZXNzaW9uX2lkCisgICAgICogQHBhcmFtIGNpcGhlcl9zdWl0ZQorICAgICAqIEBwYXJhbSBjb21wcmVzc2lvbl9tZXRob2QKKyAgICAgKi8KKyAgICBwdWJsaWMgU2VydmVySGVsbG8oU2VjdXJlUmFuZG9tIHNyLCBieXRlW10gc2VydmVyX3ZlcnNpb24sCisgICAgICAgICAgICBieXRlW10gc2Vzc2lvbl9pZCwgQ2lwaGVyU3VpdGUgY2lwaGVyX3N1aXRlLCBieXRlIGNvbXByZXNzaW9uX21ldGhvZCkgeworICAgICAgICBsb25nIGdtdF91bml4X3RpbWUgPSBuZXcgamF2YS51dGlsLkRhdGUoKS5nZXRUaW1lKCkgLyAxMDAwOworICAgICAgICBzci5uZXh0Qnl0ZXMocmFuZG9tKTsKKyAgICAgICAgcmFuZG9tWzBdID0gKGJ5dGUpICgoZ210X3VuaXhfdGltZSAmIDB4RkYwMDAwMDApID4+PiAyNCk7CisgICAgICAgIHJhbmRvbVsxXSA9IChieXRlKSAoKGdtdF91bml4X3RpbWUgJiAweEZGMDAwMCkgPj4+IDE2KTsKKyAgICAgICAgcmFuZG9tWzJdID0gKGJ5dGUpICgoZ210X3VuaXhfdGltZSAmIDB4RkYwMCkgPj4+IDgpOworICAgICAgICByYW5kb21bM10gPSAoYnl0ZSkgKGdtdF91bml4X3RpbWUgJiAweEZGKTsKKyAgICAgICAgdGhpcy5zZXNzaW9uX2lkID0gc2Vzc2lvbl9pZDsKKyAgICAgICAgdGhpcy5jaXBoZXJfc3VpdGUgPSBjaXBoZXJfc3VpdGU7CisgICAgICAgIHRoaXMuY29tcHJlc3Npb25fbWV0aG9kID0gY29tcHJlc3Npb25fbWV0aG9kOworICAgICAgICB0aGlzLnNlcnZlcl92ZXJzaW9uID0gc2VydmVyX3ZlcnNpb247CisgICAgICAgIGxlbmd0aCA9IDM4ICsgc2Vzc2lvbl9pZC5sZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBpbmJvdW5kIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTZXJ2ZXJIZWxsbyhIYW5kc2hha2VJT0RhdGFTdHJlYW0gaW4sIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgc2VydmVyX3ZlcnNpb25bMF0gPSAoYnl0ZSkgaW4ucmVhZCgpOworICAgICAgICBzZXJ2ZXJfdmVyc2lvblsxXSA9IChieXRlKSBpbi5yZWFkKCk7CisgICAgICAgIFN0cmVhbXMucmVhZEZ1bGx5KGluLCByYW5kb20pOworICAgICAgICBpbnQgc2l6ZSA9IGluLnJlYWRVaW50OCgpOworICAgICAgICBzZXNzaW9uX2lkID0gbmV3IGJ5dGVbc2l6ZV07CisgICAgICAgIGluLnJlYWQoc2Vzc2lvbl9pZCwgMCwgc2l6ZSk7CisgICAgICAgIGJ5dGUgYjAgPSAoYnl0ZSkgaW4ucmVhZCgpOworICAgICAgICBieXRlIGIxID0gKGJ5dGUpIGluLnJlYWQoKTsKKyAgICAgICAgY2lwaGVyX3N1aXRlID0gQ2lwaGVyU3VpdGUuZ2V0QnlDb2RlKGIwLCBiMSk7CisgICAgICAgIGNvbXByZXNzaW9uX21ldGhvZCA9IChieXRlKSBpbi5yZWFkKCk7CisgICAgICAgIHRoaXMubGVuZ3RoID0gMzggKyBzZXNzaW9uX2lkLmxlbmd0aDsKKyAgICAgICAgaWYgKHRoaXMubGVuZ3RoICE9IGxlbmd0aCkgeworICAgICAgICAgICAgZmF0YWxBbGVydChBbGVydFByb3RvY29sLkRFQ09ERV9FUlJPUiwgIkRFQ09ERSBFUlJPUjogaW5jb3JyZWN0IFNlcnZlckhlbGxvIik7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmRzIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gb3V0CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2VuZChIYW5kc2hha2VJT0RhdGFTdHJlYW0gb3V0KSB7CisgICAgICAgIG91dC53cml0ZShzZXJ2ZXJfdmVyc2lvbik7CisgICAgICAgIG91dC53cml0ZShyYW5kb20pOworICAgICAgICBvdXQud3JpdGVVaW50OChzZXNzaW9uX2lkLmxlbmd0aCk7CisgICAgICAgIG91dC53cml0ZShzZXNzaW9uX2lkKTsKKyAgICAgICAgb3V0LndyaXRlKGNpcGhlcl9zdWl0ZS50b0J5dGVzKCkpOworICAgICAgICBvdXQud3JpdGUoY29tcHJlc3Npb25fbWV0aG9kKTsKKyAgICAgICAgbGVuZ3RoID0gMzggKyBzZXNzaW9uX2lkLmxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHNlcnZlciByYW5kb20KKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRSYW5kb20oKSB7CisgICAgICAgIHJldHVybiByYW5kb207CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBtZXNzYWdlIHR5cGUKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRUeXBlKCkgeworICAgICAgICByZXR1cm4gSGFuZHNoYWtlLlNFUlZFUl9IRUxMTzsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TZXJ2ZXJIZWxsb0RvbmUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NlcnZlckhlbGxvRG9uZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZkNzhiMWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TZXJ2ZXJIZWxsb0RvbmUuamF2YQpAQCAtMCwwICsxLDc2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqCisgKiBSZXByZXNlbnRzIHNlcnZlciBoZWxsbyBkb25lIG1lc3NhZ2UKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI0Ni50eHQiPlRMUyAxLjAgc3BlYy4sIDcuNC41LgorICogU2VydmVyIGhlbGxvIGRvbmU8L2E+CisgKgorICovCitwdWJsaWMgY2xhc3MgU2VydmVySGVsbG9Eb25lIGV4dGVuZHMgTWVzc2FnZSB7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIG91dGJvdW5kIG1lc3NhZ2UKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBTZXJ2ZXJIZWxsb0RvbmUoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBpbmJvdW5kIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gaW4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBTZXJ2ZXJIZWxsb0RvbmUoSGFuZHNoYWtlSU9EYXRhU3RyZWFtIGluLCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGxlbmd0aCAhPSAwKSB7CisgICAgICAgICAgICBmYXRhbEFsZXJ0KEFsZXJ0UHJvdG9jb2wuREVDT0RFX0VSUk9SLCAiREVDT0RFIEVSUk9SOiBpbmNvcnJlY3QgU2VydmVySGVsbG9Eb25lIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kcyBtZXNzYWdlCisgICAgICogQHBhcmFtIG91dAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNlbmQoSGFuZHNoYWtlSU9EYXRhU3RyZWFtIG91dCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgbWVzc2FnZSBsZW5ndGgKKyAgICAgKiBAcmV0dXJuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBsZW5ndGgoKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgbWVzc2FnZSB0eXBlCisgICAgICogQHJldHVybgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0VHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIEhhbmRzaGFrZS5TRVJWRVJfSEVMTE9fRE9ORTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9TZXJ2ZXJLZXlFeGNoYW5nZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU2VydmVyS2V5RXhjaGFuZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZWE4MDc2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU2VydmVyS2V5RXhjaGFuZ2UuamF2YQpAQCAtMCwwICsxLDE5MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLlJTQVB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuUlNBUHVibGljS2V5U3BlYzsKKworLyoqCisgKgorICogUmVwcmVzZW50cyBzZXJ2ZXIga2V5IGV4Y2hhbmdlIG1lc3NhZ2UuCisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyNDYudHh0Ij5UTFMgMS4wIHNwZWMuLCA3LjQuMy4KKyAqIFNlcnZlciBrZXkgZXhjaGFuZ2UgbWVzc2FnZS48L2E+CisgKgorICovCitwdWJsaWMgY2xhc3MgU2VydmVyS2V5RXhjaGFuZ2UgZXh0ZW5kcyBNZXNzYWdlIHsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgU2VydmVyUlNBUGFyYW1zICAgICAgICBTZXJ2ZXJESFBhcmFtcworICAgIGZpbmFsIEJpZ0ludGVnZXIgcGFyMTsgLy8gICAgICAgICAgICByc2FfbW9kdWx1cyAgICAgICAgICAgICAgIGRoX3AKKyAgICBmaW5hbCBieXRlW10gYnl0ZXMxOworCisgICAgZmluYWwgQmlnSW50ZWdlciBwYXIyOyAvLyAgICAgICAgICAgIHJzYV9leHBvbmVudCAgICAgICAgICAgICAgZGhfZworICAgIGZpbmFsIGJ5dGVbXSBieXRlczI7CisKKyAgICBmaW5hbCBCaWdJbnRlZ2VyIHBhcjM7IC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaF9ZcworICAgIGZpbmFsIGJ5dGVbXSBieXRlczM7CisKKyAgICAvKioKKyAgICAgKiBTaWduYXR1cmUKKyAgICAgKi8KKyAgICBmaW5hbCBieXRlW10gaGFzaDsKKworICAgIHByaXZhdGUgUlNBUHVibGljS2V5IGtleTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgb3V0Ym91bmQgbWVzc2FnZQorICAgICAqIEBwYXJhbSBwYXIxIHJzYV9tb2R1bHVzIG9yIGRoX3AKKyAgICAgKiBAcGFyYW0gcGFyMiByc2FfZXhwb25lbnQgb3IgZGhfZworICAgICAqIEBwYXJhbSBwYXIzIGRoX1lzIGZvciBTZXJ2ZXJESFBhcmFtczsgc2hvdWxkIGJlIG51bGwgZm9yIFNlcnZlclJTQVBhcmFtcworICAgICAqIEBwYXJhbSBoYXNoIHNob3VsZCBiZSBudWxsIGZvciBhbm9ueW1vdXMgU2lnbmF0dXJlQWxnb3JpdGhtCisgICAgICovCisgICAgcHVibGljIFNlcnZlcktleUV4Y2hhbmdlKEJpZ0ludGVnZXIgcGFyMSwgQmlnSW50ZWdlciBwYXIyLCBCaWdJbnRlZ2VyIHBhcjMsCisgICAgICAgICAgICBieXRlW10gaGFzaCkgeworICAgICAgICB0aGlzLnBhcjEgPSBwYXIxOworICAgICAgICB0aGlzLnBhcjIgPSBwYXIyOworICAgICAgICB0aGlzLnBhcjMgPSBwYXIzOworICAgICAgICB0aGlzLmhhc2ggPSBoYXNoOworCisgICAgICAgIGJ5dGVzMSA9IHRvVW5zaWduZWRCeXRlQXJyYXkodGhpcy5wYXIxKTsKKworICAgICAgICBieXRlczIgPSB0b1Vuc2lnbmVkQnl0ZUFycmF5KHRoaXMucGFyMik7CisKKyAgICAgICAgbGVuZ3RoID0gNCArIGJ5dGVzMS5sZW5ndGggKyBieXRlczIubGVuZ3RoOworICAgICAgICBpZiAoaGFzaCAhPSBudWxsKSB7CisgICAgICAgICAgICBsZW5ndGggKz0gMiArIGhhc2gubGVuZ3RoOworICAgICAgICB9CisgICAgICAgIGlmIChwYXIzID09IG51bGwpIHsKKyAgICAgICAgICAgIGJ5dGVzMyA9IG51bGw7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgYnl0ZXMzID0gdG9VbnNpZ25lZEJ5dGVBcnJheSh0aGlzLnBhcjMpOworICAgICAgICBsZW5ndGggKz0gMiArIGJ5dGVzMy5sZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlIGZpcnN0IGJ5dGUgaWYgMC4gTmVlZGVkIGJlY2F1c2UgQmlnSW50ZWdlci50b0J5dGVBcnJheSgpIHNvbWV0aW1lcworICAgICAqIHJldHVybnMgYSB6ZXJvIHByZWZpeC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSB0b1Vuc2lnbmVkQnl0ZUFycmF5KEJpZ0ludGVnZXIgYmkpIHsKKyAgICAgICAgaWYgKGJpID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSBiYiA9IGJpLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIC8vIGJiIGlzIG5vdCBudWxsLCBhbmQgaGFzIGF0IGxlYXN0IDEgYnl0ZSAtIFpFUk8gaXMgcmVwcmVzZW50ZWQgYXMgWzBdCisgICAgICAgIGlmIChiYlswXSA9PSAwKSB7CisgICAgICAgICAgICBieXRlW10gbm9aZXJvID0gbmV3IGJ5dGVbYmIubGVuZ3RoIC0gMV07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJiLCAxLCBub1plcm8sIDAsIG5vWmVyby5sZW5ndGgpOworICAgICAgICAgICAgcmV0dXJuIG5vWmVybzsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBiYjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgaW5ib3VuZCBtZXNzYWdlCisgICAgICogQHBhcmFtIGluCisgICAgICogQHBhcmFtIGxlbmd0aAorICAgICAqIEBwYXJhbSBrZXlFeGNoYW5nZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU2VydmVyS2V5RXhjaGFuZ2UoSGFuZHNoYWtlSU9EYXRhU3RyZWFtIGluLCBpbnQgbGVuZ3RoLAorICAgICAgICAgICAgaW50IGtleUV4Y2hhbmdlKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIGludCBzaXplID0gaW4ucmVhZFVpbnQxNigpOworICAgICAgICBieXRlczEgPSBpbi5yZWFkKHNpemUpOworICAgICAgICBwYXIxID0gbmV3IEJpZ0ludGVnZXIoMSwgYnl0ZXMxKTsKKyAgICAgICAgdGhpcy5sZW5ndGggPSAyICsgYnl0ZXMxLmxlbmd0aDsKKyAgICAgICAgc2l6ZSA9IGluLnJlYWRVaW50MTYoKTsKKyAgICAgICAgYnl0ZXMyID0gaW4ucmVhZChzaXplKTsKKyAgICAgICAgcGFyMiA9IG5ldyBCaWdJbnRlZ2VyKDEsIGJ5dGVzMik7CisgICAgICAgIHRoaXMubGVuZ3RoICs9IDIgKyBieXRlczIubGVuZ3RoOworICAgICAgICBpZiAoa2V5RXhjaGFuZ2UgIT0gQ2lwaGVyU3VpdGUuS0VZX0VYQ0hBTkdFX1JTQV9FWFBPUlQpIHsKKyAgICAgICAgICAgIHNpemUgPSBpbi5yZWFkVWludDE2KCk7CisgICAgICAgICAgICBieXRlczMgPSBpbi5yZWFkKHNpemUpOworICAgICAgICAgICAgcGFyMyA9IG5ldyBCaWdJbnRlZ2VyKDEsIGJ5dGVzMyk7CisgICAgICAgICAgICB0aGlzLmxlbmd0aCArPSAyICsgYnl0ZXMzLmxlbmd0aDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHBhcjMgPSBudWxsOworICAgICAgICAgICAgYnl0ZXMzID0gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoa2V5RXhjaGFuZ2UgIT0gQ2lwaGVyU3VpdGUuS0VZX0VYQ0hBTkdFX0RIX2Fub25fRVhQT1JUCisgICAgICAgICAgICAgICAgJiYga2V5RXhjaGFuZ2UgIT0gQ2lwaGVyU3VpdGUuS0VZX0VYQ0hBTkdFX0RIX2Fub24pIHsKKyAgICAgICAgICAgIHNpemUgPSBpbi5yZWFkVWludDE2KCk7CisgICAgICAgICAgICBoYXNoID0gaW4ucmVhZChzaXplKTsKKyAgICAgICAgICAgIHRoaXMubGVuZ3RoICs9IDIgKyBoYXNoLmxlbmd0aDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGhhc2ggPSBudWxsOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLmxlbmd0aCAhPSBsZW5ndGgpIHsKKyAgICAgICAgICAgIGZhdGFsQWxlcnQoQWxlcnRQcm90b2NvbC5ERUNPREVfRVJST1IsCisgICAgICAgICAgICAgICAgICAgICJERUNPREUgRVJST1I6IGluY29ycmVjdCBTZXJ2ZXJLZXlFeGNoYW5nZSIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZHMgbWVzc2FnZQorICAgICAqIEBwYXJhbSBvdXQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZW5kKEhhbmRzaGFrZUlPRGF0YVN0cmVhbSBvdXQpIHsKKyAgICAgICAgb3V0LndyaXRlVWludDE2KGJ5dGVzMS5sZW5ndGgpOworICAgICAgICBvdXQud3JpdGUoYnl0ZXMxKTsKKyAgICAgICAgb3V0LndyaXRlVWludDE2KGJ5dGVzMi5sZW5ndGgpOworICAgICAgICBvdXQud3JpdGUoYnl0ZXMyKTsKKyAgICAgICAgaWYgKGJ5dGVzMyAhPSBudWxsKSB7CisgICAgICAgICAgICBvdXQud3JpdGVVaW50MTYoYnl0ZXMzLmxlbmd0aCk7CisgICAgICAgICAgICBvdXQud3JpdGUoYnl0ZXMzKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaGFzaCAhPSBudWxsKSB7CisgICAgICAgICAgICBvdXQud3JpdGVVaW50MTYoaGFzaC5sZW5ndGgpOworICAgICAgICAgICAgb3V0LndyaXRlKGhhc2gpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBSU0FQdWJsaWNLZXkgZ2VuZXJhdGVkIHVzaW5nIFNlcnZlclJTQVBhcmFtcworICAgICAqIChyc2FfbW9kdWx1cyBhbmQgcnNhX2V4cG9uZW50KS4KKyAgICAgKgorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwdWJsaWMgUlNBUHVibGljS2V5IGdldFJTQVB1YmxpY0tleSgpIHsKKyAgICAgICAgaWYgKGtleSAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4ga2V5OworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlGYWN0b3J5IGtmID0gS2V5RmFjdG9yeS5nZXRJbnN0YW5jZSgiUlNBIik7CisgICAgICAgICAgICBrZXkgPSAoUlNBUHVibGljS2V5KSBrZi5nZW5lcmF0ZVB1YmxpYyhuZXcgUlNBUHVibGljS2V5U3BlYyhwYXIxLAorICAgICAgICAgICAgICAgICAgICBwYXIyKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4ga2V5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgbWVzc2FnZSB0eXBlCisgICAgICogQHJldHVybgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0VHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIEhhbmRzaGFrZS5TRVJWRVJfS0VZX0VYQ0hBTkdFOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvU2VydmVyU2Vzc2lvbkNvbnRleHQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NlcnZlclNlc3Npb25Db250ZXh0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2IyMWJlNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1NlcnZlclNlc3Npb25Db250ZXh0LmphdmEKQEAgLTAsMCArMSw4MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbjsKKworLyoqCisgKiBDYWNoZXMgc2VydmVyIHNlc3Npb25zLiBJbmRleGVzIGJ5IHNlc3Npb24gSUQuIFVzZXJzIHR5cGljYWxseSBsb29rIHVwCisgKiBzZXNzaW9ucyB1c2luZyB0aGUgSUQgcHJvdmlkZWQgYnkgYW4gU1NMIGNsaWVudC4KKyAqLworcHVibGljIGNsYXNzIFNlcnZlclNlc3Npb25Db250ZXh0IGV4dGVuZHMgQWJzdHJhY3RTZXNzaW9uQ29udGV4dCB7CisKKyAgICBwcml2YXRlIFNTTFNlcnZlclNlc3Npb25DYWNoZSBwZXJzaXN0ZW50Q2FjaGU7CisKKyAgICBwdWJsaWMgU2VydmVyU2Vzc2lvbkNvbnRleHQoKSB7CisgICAgICAgIHN1cGVyKDEwMCwgMCk7CisKKyAgICAgICAgLy8gVE9ETyBtYWtlIHN1cmUgU1NMX0NUWCBkb2VzIG5vdCBhdXRvbWF0aWNhbHkgY2xlYXIgc2Vzc2lvbnMgd2Ugd2FudCBpdCB0byBjYWNoZQorICAgICAgICAvLyBTU0xfQ1RYX3NldF9zZXNzaW9uX2NhY2hlX21vZGUoc3NsQ3R4TmF0aXZlUG9pbnRlciwgU1NMX1NFU1NfQ0FDSEVfTk9fQVVUT19DTEVBUik7CisKKyAgICAgICAgLy8gVE9ETyByZW1vdmUgU1NMX0NUWCBzZXNzaW9uIGNhY2hlIGxpbWl0IHNvIHdlIGNhbiBtYW5hZ2UgaXQKKyAgICAgICAgLy8gU1NMX0NUWF9zZXNzX3NldF9jYWNoZV9zaXplKHNzbEN0eE5hdGl2ZVBvaW50ZXIsIDApOworCisgICAgICAgIC8vIFRPRE8gb3ZlcnJpZGUgdHJpbVRvU2l6ZSBhbmQgcmVtb3ZlRWxkZXN0RW50cnkgdG8gdXNlCisgICAgICAgIC8vIFNTTF9DVFhfc2Vzc2lvbnMgdG8gcmVtb3ZlIGZyb20gbmF0aXZlIGNhY2hlCisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0UGVyc2lzdGVudENhY2hlKFNTTFNlcnZlclNlc3Npb25DYWNoZSBwZXJzaXN0ZW50Q2FjaGUpIHsKKyAgICAgICAgdGhpcy5wZXJzaXN0ZW50Q2FjaGUgPSBwZXJzaXN0ZW50Q2FjaGU7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2Vzc2lvblJlbW92ZWQoU1NMU2Vzc2lvbiBzZXNzaW9uKSB7fQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNTTFNlc3Npb24gZ2V0U2Vzc2lvbihieXRlW10gc2Vzc2lvbklkKSB7CisgICAgICAgIFNTTFNlc3Npb24gc2Vzc2lvbiA9IHN1cGVyLmdldFNlc3Npb24oc2Vzc2lvbklkKTsKKyAgICAgICAgaWYgKHNlc3Npb24gIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHNlc3Npb247CisgICAgICAgIH0KKworICAgICAgICAvLyBDaGVjayBwZXJzaXN0ZW50IGNhY2hlLgorICAgICAgICBpZiAocGVyc2lzdGVudENhY2hlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGJ5dGVbXSBkYXRhID0gcGVyc2lzdGVudENhY2hlLmdldFNlc3Npb25EYXRhKHNlc3Npb25JZCk7CisgICAgICAgICAgICBpZiAoZGF0YSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2Vzc2lvbiA9IHRvU2Vzc2lvbihkYXRhLCBudWxsLCAtMSk7CisgICAgICAgICAgICAgICAgaWYgKHNlc3Npb24gIT0gbnVsbCAmJiBzZXNzaW9uLmlzVmFsaWQoKSkgeworICAgICAgICAgICAgICAgICAgICBzdXBlci5wdXRTZXNzaW9uKHNlc3Npb24pOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2Vzc2lvbjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICB2b2lkIHB1dFNlc3Npb24oU1NMU2Vzc2lvbiBzZXNzaW9uKSB7CisgICAgICAgIHN1cGVyLnB1dFNlc3Npb24oc2Vzc2lvbik7CisKKyAgICAgICAgLy8gVE9ETzogSW4gYmFja2dyb3VuZCB0aHJlYWQuCisgICAgICAgIGlmIChwZXJzaXN0ZW50Q2FjaGUgIT0gbnVsbCkgeworICAgICAgICAgICAgYnl0ZVtdIGRhdGEgPSB0b0J5dGVzKHNlc3Npb24pOworICAgICAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHBlcnNpc3RlbnRDYWNoZS5wdXRTZXNzaW9uRGF0YShzZXNzaW9uLCBkYXRhKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1RydXN0TWFuYWdlckZhY3RvcnlJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9UcnVzdE1hbmFnZXJGYWN0b3J5SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE1OWUzNjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9UcnVzdE1hbmFnZXJGYWN0b3J5SW1wbC5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5NYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXJGYWN0b3J5U3BpOworCisvKioKKyAqCisgKiBUcnVzdE1hbmFnZXJGYWN0b3J5IHNlcnZpY2UgcHJvdmlkZXIgaW50ZXJmYWNlIGltcGxlbWVudGF0aW9uLgorICoKKyAqIEBzZWUgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXJGYWN0b3J5U3BpCisgKi8KK3B1YmxpYyBjbGFzcyBUcnVzdE1hbmFnZXJGYWN0b3J5SW1wbCBleHRlbmRzIFRydXN0TWFuYWdlckZhY3RvcnlTcGkgeworCisgICAgcHJpdmF0ZSBLZXlTdG9yZSBrZXlTdG9yZTsKKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXJGYWN0b3J5U3BpI2VuZ2luZUluaXQoS2V5U3RvcmUpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZW5naW5lSW5pdChLZXlTdG9yZSBrcykgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGtzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGtleVN0b3JlID0ga3M7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBrZXlTdG9yZSA9IEtleVN0b3JlLmdldEluc3RhbmNlKCJBbmRyb2lkQ0FTdG9yZSIpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5sb2FkKG51bGwsIG51bGwpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBLZXlTdG9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgS2V5U3RvcmVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBLZXlTdG9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbCNlbmdpbmVJbml0KE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycykKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVJbml0KE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyBzcGVjKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wjZW5naW5lR2V0VHJ1c3RNYW5hZ2VycygpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFRydXN0TWFuYWdlcltdIGVuZ2luZUdldFRydXN0TWFuYWdlcnMoKSB7CisgICAgICAgIGlmIChrZXlTdG9yZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAiVHJ1c3RNYW5hZ2VyRmFjdG9yeSBpcyBub3QgaW5pdGlhbGl6ZWQiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFRydXN0TWFuYWdlcltdIHsgbmV3IFRydXN0TWFuYWdlckltcGwoa2V5U3RvcmUpIH07CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvVHJ1c3RNYW5hZ2VySW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvVHJ1c3RNYW5hZ2VySW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY1M2RjYTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9UcnVzdE1hbmFnZXJJbXBsLmphdmEKQEAgLTAsMCArMSwzMjggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aFZhbGlkYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LlBLSVhQYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5UcnVzdEFuY2hvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlg1MDlUcnVzdE1hbmFnZXI7CisKKy8qKgorICoKKyAqIFRydXN0TWFuYWdlciBpbXBsZW1lbnRhdGlvbi4gVGhlIGltcGxlbWVudGF0aW9uIGlzIGJhc2VkIG9uIENlcnRQYXRoVmFsaWRhdG9yCisgKiBQS0lYIGFuZCBDZXJ0aWZpY2F0ZUZhY3RvcnkgWDUwOSBpbXBsZW1lbnRhdGlvbnMuIFRoaXMgaW1wbGVtZW50YXRpb25zIHNob3VsZAorICogYmUgcHJvdmlkZWQgYnkgc29tZSBjZXJ0aWZpY2F0aW9uIHByb3ZpZGVyLgorICoKKyAqIEBzZWUgamF2YXgubmV0LnNzbC5YNTA5VHJ1c3RNYW5hZ2VyCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBUcnVzdE1hbmFnZXJJbXBsIGltcGxlbWVudHMgWDUwOVRydXN0TWFuYWdlciB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgQW5kcm9pZENBU3RvcmUgaWYgbm9uLW51bGwsIG51bGwgb3RoZXJ3aXNlLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgS2V5U3RvcmUgcm9vdEtleVN0b3JlOworCisgICAgLyoqCisgICAgICogVGhlIGJhY2tpbmcgc3RvcmUgZm9yIHRoZSBBbmRyb2lkQ0FTdG9yZSBpZiBub24tbnVsbC4gVGhpcyB3aWxsCisgICAgICogYmUgbnVsbCB3aGVuIHRoZSByb290S2V5U3RvcmUgaXMgbnVsbCwgaW1wbHlpbmcgd2UgYXJlIG5vdAorICAgICAqIHVzaW5nIHRoZSBBbmRyb2lkQ0FTdG9yZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFRydXN0ZWRDZXJ0aWZpY2F0ZVN0b3JlIHRydXN0ZWRDZXJ0aWZpY2F0ZVN0b3JlOworCisgICAgcHJpdmF0ZSBmaW5hbCBDZXJ0UGF0aFZhbGlkYXRvciB2YWxpZGF0b3I7CisKKyAgICAvKioKKyAgICAgKiBBbiBpbmRleCBvZiBUcnVzdEFuY2hvciBpbnN0YW5jZXMgdGhhdCB3ZSd2ZSBzZWVuLiBVbmxpa2UgdGhlCisgICAgICogVHJ1c3RlZENlcnRpZmljYXRlU3RvcmUsIHRoaXMgbWF5IGNvbnRhaW4gaW50ZXJtZWRpYXRlIENBcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFRydXN0ZWRDZXJ0aWZpY2F0ZUluZGV4IHRydXN0ZWRDZXJ0aWZpY2F0ZUluZGV4OworCisgICAgLyoqCisgICAgICogVGhpcyBpcyBsYXppbHkgaW5pdGlhbGl6ZWQgaW4gdGhlIEFuZHJvaWRDQVN0b3JlIGNhc2Ugc2luY2UgaXQKKyAgICAgKiBmb3JjZXMgdXMgdG8gYnJpbmcgYWxsIHRoZSBDQXMgaW50byBtZW1vcnkuIEluIHRoZQorICAgICAqIG5vbi1BbmRyb2lkQ0FTdG9yZSwgd2UgaW5pdGlhbGl6ZSB0aGlzIGFzIHBhcnQgb2YgdGhlCisgICAgICogY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBYNTA5Q2VydGlmaWNhdGVbXSBhY2NlcHRlZElzc3VlcnM7CisKKyAgICBwcml2YXRlIGZpbmFsIEV4Y2VwdGlvbiBlcnI7CisgICAgcHJpdmF0ZSBmaW5hbCBDZXJ0aWZpY2F0ZUZhY3RvcnkgZmFjdG9yeTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgWDUwOVRydXN0TWFuYWdlciBiYXNlZCBvbiBhIGtleXN0b3JlCisgICAgICoKKyAgICAgKiBAcGFyYW0ga3MKKyAgICAgKi8KKyAgICBwdWJsaWMgVHJ1c3RNYW5hZ2VySW1wbChLZXlTdG9yZSBrZXlTdG9yZSkgeworICAgICAgICBDZXJ0UGF0aFZhbGlkYXRvciB2YWxpZGF0b3JMb2NhbCA9IG51bGw7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBmYWN0b3J5TG9jYWwgPSBudWxsOworICAgICAgICBLZXlTdG9yZSByb290S2V5U3RvcmVMb2NhbCA9IG51bGw7CisgICAgICAgIFRydXN0ZWRDZXJ0aWZpY2F0ZVN0b3JlIHRydXN0ZWRDZXJ0aWZpY2F0ZVN0b3JlTG9jYWwgPSBudWxsOworICAgICAgICBUcnVzdGVkQ2VydGlmaWNhdGVJbmRleCB0cnVzdGVkQ2VydGlmaWNhdGVJbmRleExvY2FsID0gbnVsbDsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlW10gYWNjZXB0ZWRJc3N1ZXJzTG9jYWwgPSBudWxsOworICAgICAgICBFeGNlcHRpb24gZXJyTG9jYWwgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdmFsaWRhdG9yTG9jYWwgPSBDZXJ0UGF0aFZhbGlkYXRvci5nZXRJbnN0YW5jZSgiUEtJWCIpOworICAgICAgICAgICAgZmFjdG9yeUxvY2FsID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYNTA5Iik7CisKKyAgICAgICAgICAgIC8vIGlmIHdlIGhhdmUgYW4gQW5kcm9pZENBU3RvcmUsIHdlIHdpbGwgbGF6aWx5IGxvYWQgQ0FzCisgICAgICAgICAgICBpZiAoIkFuZHJvaWRDQVN0b3JlIi5lcXVhbHMoa2V5U3RvcmUuZ2V0VHlwZSgpKSkgeworICAgICAgICAgICAgICAgIHJvb3RLZXlTdG9yZUxvY2FsID0ga2V5U3RvcmU7CisgICAgICAgICAgICAgICAgdHJ1c3RlZENlcnRpZmljYXRlU3RvcmVMb2NhbCA9IG5ldyBUcnVzdGVkQ2VydGlmaWNhdGVTdG9yZSgpOworICAgICAgICAgICAgICAgIGFjY2VwdGVkSXNzdWVyc0xvY2FsID0gbnVsbDsKKyAgICAgICAgICAgICAgICB0cnVzdGVkQ2VydGlmaWNhdGVJbmRleExvY2FsID0gbmV3IFRydXN0ZWRDZXJ0aWZpY2F0ZUluZGV4KCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJvb3RLZXlTdG9yZUxvY2FsID0gbnVsbDsKKyAgICAgICAgICAgICAgICB0cnVzdGVkQ2VydGlmaWNhdGVTdG9yZUxvY2FsID0gbnVsbDsKKyAgICAgICAgICAgICAgICBhY2NlcHRlZElzc3VlcnNMb2NhbCA9IGFjY2VwdGVkSXNzdWVycyhrZXlTdG9yZSk7CisgICAgICAgICAgICAgICAgdHJ1c3RlZENlcnRpZmljYXRlSW5kZXhMb2NhbAorICAgICAgICAgICAgICAgICAgICAgICAgPSBuZXcgVHJ1c3RlZENlcnRpZmljYXRlSW5kZXgodHJ1c3RBbmNob3JzKGFjY2VwdGVkSXNzdWVyc0xvY2FsKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGVyckxvY2FsID0gZTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnJvb3RLZXlTdG9yZSA9IHJvb3RLZXlTdG9yZUxvY2FsOworICAgICAgICB0aGlzLnRydXN0ZWRDZXJ0aWZpY2F0ZVN0b3JlID0gdHJ1c3RlZENlcnRpZmljYXRlU3RvcmVMb2NhbDsKKyAgICAgICAgdGhpcy52YWxpZGF0b3IgPSB2YWxpZGF0b3JMb2NhbDsKKyAgICAgICAgdGhpcy5mYWN0b3J5ID0gZmFjdG9yeUxvY2FsOworICAgICAgICB0aGlzLnRydXN0ZWRDZXJ0aWZpY2F0ZUluZGV4ID0gdHJ1c3RlZENlcnRpZmljYXRlSW5kZXhMb2NhbDsKKyAgICAgICAgdGhpcy5hY2NlcHRlZElzc3VlcnMgPSBhY2NlcHRlZElzc3VlcnNMb2NhbDsKKyAgICAgICAgdGhpcy5lcnIgPSBlcnJMb2NhbDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBYNTA5Q2VydGlmaWNhdGVbXSBhY2NlcHRlZElzc3VlcnMoS2V5U3RvcmUga3MpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIE5vdGUgdGhhdCB1bmxpa2UgdGhlIFBLSVhQYXJhbWV0ZXJzIGNvZGUgdG8gY3JlYXRlIGEgU2V0IG9mCisgICAgICAgICAgICAvLyBUcnVzdEFuY2hvcnMgZnJvbSBhIEtleVN0b3JlLCB0aGlzIHZlcnNpb24gdGFrZXMgZnJvbSBib3RoCisgICAgICAgICAgICAvLyBUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeSBhbmQgUHJpdmF0ZUtleUVudHJ5LCBub3QganVzdAorICAgICAgICAgICAgLy8gVHJ1c3RlZENlcnRpZmljYXRlRW50cnksIHdoaWNoIGlzIHdoeSBUcnVzdE1hbmFnZXJJbXBsCisgICAgICAgICAgICAvLyBjYW5ub3QganVzdCB1c2UgYW4gUEtJWFBhcmFtZXRlcnMoS2V5U3RvcmUpCisgICAgICAgICAgICAvLyBjb25zdHJ1Y3Rvci4KKworICAgICAgICAgICAgLy8gVE9ETyByZW1vdmUgZHVwbGljYXRlcyBpZiBzYW1lIGNlcnQgaXMgZm91bmQgaW4gYm90aCBhCisgICAgICAgICAgICAvLyBQcml2YXRlS2V5RW50cnkgYW5kIFRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5CisgICAgICAgICAgICBMaXN0PFg1MDlDZXJ0aWZpY2F0ZT4gdHJ1c3RlZCA9IG5ldyBBcnJheUxpc3Q8WDUwOUNlcnRpZmljYXRlPigpOworICAgICAgICAgICAgZm9yIChFbnVtZXJhdGlvbjxTdHJpbmc+IGVuID0ga3MuYWxpYXNlcygpOyBlbi5oYXNNb3JlRWxlbWVudHMoKTspIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgYWxpYXMgPSBlbi5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgICAgIGZpbmFsIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0ID0gKFg1MDlDZXJ0aWZpY2F0ZSkga3MuZ2V0Q2VydGlmaWNhdGUoYWxpYXMpOworICAgICAgICAgICAgICAgIGlmIChjZXJ0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ1c3RlZC5hZGQoY2VydCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHRydXN0ZWQudG9BcnJheShuZXcgWDUwOUNlcnRpZmljYXRlW3RydXN0ZWQuc2l6ZSgpXSk7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgWDUwOUNlcnRpZmljYXRlWzBdOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU2V0PFRydXN0QW5jaG9yPiB0cnVzdEFuY2hvcnMoWDUwOUNlcnRpZmljYXRlW10gY2VydHMpIHsKKyAgICAgICAgU2V0PFRydXN0QW5jaG9yPiB0cnVzdEFuY2hvcnMgPSBuZXcgSGFzaFNldDxUcnVzdEFuY2hvcj4oY2VydHMubGVuZ3RoKTsKKyAgICAgICAgZm9yIChYNTA5Q2VydGlmaWNhdGUgY2VydCA6IGNlcnRzKSB7CisgICAgICAgICAgICB0cnVzdEFuY2hvcnMuYWRkKG5ldyBUcnVzdEFuY2hvcihjZXJ0LCBudWxsKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydXN0QW5jaG9yczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgY2hlY2tDbGllbnRUcnVzdGVkKFg1MDlDZXJ0aWZpY2F0ZVtdIGNoYWluLCBTdHJpbmcgYXV0aFR5cGUpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBjaGVja1RydXN0ZWQoY2hhaW4sIGF1dGhUeXBlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgY2hlY2tTZXJ2ZXJUcnVzdGVkKFg1MDlDZXJ0aWZpY2F0ZVtdIGNoYWluLCBTdHJpbmcgYXV0aFR5cGUpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBjaGVja1RydXN0ZWQoY2hhaW4sIGF1dGhUeXBlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tUcnVzdGVkKFg1MDlDZXJ0aWZpY2F0ZVtdIGNoYWluLCBTdHJpbmcgYXV0aFR5cGUpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBpZiAoY2hhaW4gPT0gbnVsbCB8fCBjaGFpbi5sZW5ndGggPT0gMCB8fCBhdXRoVHlwZSA9PSBudWxsIHx8IGF1dGhUeXBlLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm51bGwgb3IgemVyby1sZW5ndGggcGFyYW1ldGVyIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVyciAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oZXJyKTsKKyAgICAgICAgfQorCisgICAgICAgIFNldDxUcnVzdEFuY2hvcj4gdHJ1c3RBbmNob3JzID0gbmV3IEhhc2hTZXQ8VHJ1c3RBbmNob3I+KCk7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIG5ld0NoYWluID0gY2xlYW51cENlcnRDaGFpbkFuZEZpbmRUcnVzdEFuY2hvcnMoY2hhaW4sIHRydXN0QW5jaG9ycyk7CisgICAgICAgIGlmIChuZXdDaGFpbi5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgLy8gY2hhaW4gd2FzIGVudGlyZWx5IHRydXN0ZWQsIHNraXAgdGhlIHZhbGlkYXRvcgorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgQ2VydFBhdGggY2VydFBhdGggPSBmYWN0b3J5LmdlbmVyYXRlQ2VydFBhdGgoQXJyYXlzLmFzTGlzdChuZXdDaGFpbikpOworICAgICAgICBpZiAodHJ1c3RBbmNob3JzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKG5ldyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgIlRydXN0IGFuY2hvciBmb3IgY2VydGlmaWNhdGlvbiBwYXRoIG5vdCBmb3VuZC4iLCBudWxsLCBjZXJ0UGF0aCwgLTEpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQS0lYUGFyYW1ldGVycyBwYXJhbXMgPSBuZXcgUEtJWFBhcmFtZXRlcnModHJ1c3RBbmNob3JzKTsKKyAgICAgICAgICAgIHBhcmFtcy5zZXRSZXZvY2F0aW9uRW5hYmxlZChmYWxzZSk7CisgICAgICAgICAgICB2YWxpZGF0b3IudmFsaWRhdGUoY2VydFBhdGgsIHBhcmFtcyk7CisgICAgICAgICAgICAvLyBBZGQgaW50ZXJtZWRpYXRlIENBcyB0byB0aGUgaW5kZXggdG8gdG9sZXJhdGUgc2l0ZXMKKyAgICAgICAgICAgIC8vIHRoYXQgYXNzdW1lIHRoYXQgdGhlIGJyb3dzZXIgd2lsbCBoYXZlIGNhY2hlZCB0aGVzZS4KKyAgICAgICAgICAgIC8vIFRoZSBzZXJ2ZXIgY2VydGlmaWNhdGUgaXMgc2tpcHBlZCBieSBza2lwcGluZyB0aGUKKyAgICAgICAgICAgIC8vIHplcm90aCBlbGVtZW50IG9mIG5ldyBjaGFpbiBhbmQgbm90ZSB0aGF0IHRoZSByb290IENBCisgICAgICAgICAgICAvLyB3aWxsIGhhdmUgYmVlbiByZW1vdmVkIGluCisgICAgICAgICAgICAvLyBjbGVhbnVwQ2VydENoYWluQW5kRmluZFRydXN0QW5jaG9ycy4gIGh0dHA6Ly9iLzM0MDQ5MDIKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgbmV3Q2hhaW4ubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICB0cnVzdGVkQ2VydGlmaWNhdGVJbmRleC5pbmRleChuZXdDaGFpbltpXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKGUpOworICAgICAgICB9IGNhdGNoIChDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbGVhbiB1cCB0aGUgY2VydGlmaWNhdGUgY2hhaW4sIHJldHVybmluZyBhIGNsZWFuZWQgdXAgY2hhaW4sCisgICAgICogd2hpY2ggbWF5IGJlIGEgbmV3IGFycmF5IGluc3RhbmNlIGlmIGVsZW1lbnRzIHdlcmUgcmVtb3ZlZC4KKyAgICAgKiBUaGVvcmV0aWNhbGx5LCB3ZSBzaG91bGRuJ3QgaGF2ZSB0byBkbyB0aGlzLCBidXQgdmFyaW91cyB3ZWIKKyAgICAgKiBzZXJ2ZXJzIGluIHByYWN0aWNlIGFyZSBtaXMtY29uZmlndXJlZCB0byBoYXZlIG91dC1vZi1vcmRlcgorICAgICAqIGNlcnRpZmljYXRlcywgZXhwaXJlZCBzZWxmLWlzc3VlZCByb290IGNlcnRpZmljYXRlLCBvciBDQXMgd2l0aAorICAgICAqIHVuc3VwcG9ydGVkIHNpZ25hdHVyZSBhbGdvcml0aG1zIHN1Y2ggYXMKKyAgICAgKiBtZDJXaXRoUlNBRW5jcnlwdGlvbi4gVGhpcyBhbHNvIGhhbmRsZXMgcmVtb3Zpbmcgb2xkIGNlcnRzCisgICAgICogYWZ0ZXIgYnJpZGdlIENBIGNlcnRzLgorICAgICAqLworICAgIHByaXZhdGUgWDUwOUNlcnRpZmljYXRlW10gY2xlYW51cENlcnRDaGFpbkFuZEZpbmRUcnVzdEFuY2hvcnMoWDUwOUNlcnRpZmljYXRlW10gY2hhaW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXQ8VHJ1c3RBbmNob3I+IHRydXN0QW5jaG9ycykgeworICAgICAgICBYNTA5Q2VydGlmaWNhdGVbXSBvcmlnaW5hbCA9IGNoYWluOworCisgICAgICAgIC8vIDEuIENsZWFuIHRoZSByZWNlaXZlZCBjZXJ0aWZpY2F0ZXMgY2hhaW4uCisgICAgICAgIGludCBjdXJySW5kZXg7CisgICAgICAgIC8vIFN0YXJ0IHdpdGggdGhlIGZpcnN0IGNlcnRpZmljYXRlIGluIHRoZSBjaGFpbiwgYXNzdW1pbmcgaXQKKyAgICAgICAgLy8gaXMgdGhlIGxlYWYgY2VydGlmaWNhdGUgKHNlcnZlciBvciBjbGllbnQgY2VydCkuCisgICAgICAgIGZvciAoY3VyckluZGV4ID0gMDsgY3VyckluZGV4IDwgY2hhaW4ubGVuZ3RoOyBjdXJySW5kZXgrKykgeworICAgICAgICAgICAgLy8gSWYgdGhlIGN1cnJlbnQgY2VydCBpcyBhIFRydXN0QW5jaG9yLCB3ZSBjYW4gaWdub3JlIHRoZSByZXN0IG9mIHRoZSBjaGFpbi4KKyAgICAgICAgICAgIC8vIFRoaXMgYXZvaWRzIGluY2x1ZGluZyAiYnJpZGdlIiBDQSBjZXJ0cyB0aGF0IGFkZGVkIGZvciBsZWdhY3kgY29tcGF0YWJpbGl0eS4KKyAgICAgICAgICAgIFRydXN0QW5jaG9yIHRydXN0QW5jaG9yID0gZmluZFRydXN0QW5jaG9yQnlTdWJqZWN0QW5kUHVibGljS2V5KGNoYWluW2N1cnJJbmRleF0pOworICAgICAgICAgICAgaWYgKHRydXN0QW5jaG9yICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0cnVzdEFuY2hvcnMuYWRkKHRydXN0QW5jaG9yKTsKKyAgICAgICAgICAgICAgICBjdXJySW5kZXgtLTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIFdhbGsgdGhlIHJlc3Qgb2YgdGhlIGNoYWluIHRvIGZpbmQgYSAic3ViamVjdCIgbWF0Y2hpbmcKKyAgICAgICAgICAgIC8vIHRoZSAiaXNzdWVyIiBvZiB0aGUgY3VycmVudCBjZXJ0aWZpY2F0ZS4gSW4gYSBwcm9wZXJseQorICAgICAgICAgICAgLy8gb3JkZXIgY2hhaW4gdGhpcyBzaG91bGQgYmUgdGhlIG5leHQgY2VydCBhbmQgYmUgZmFzdC4KKyAgICAgICAgICAgIC8vIElmIG5vdCwgd2UgcmVvcmRlciB0aGluZ3MgdG8gYmUgYXMgdGhlIHZhbGlkYXRvciB3aWxsCisgICAgICAgICAgICAvLyBleHBlY3QuCisgICAgICAgICAgICBib29sZWFuIGZvdW5kTmV4dCA9IGZhbHNlOworICAgICAgICAgICAgZm9yIChpbnQgbmV4dEluZGV4ID0gY3VyckluZGV4ICsgMTsgbmV4dEluZGV4IDwgY2hhaW4ubGVuZ3RoOyBuZXh0SW5kZXgrKykgeworICAgICAgICAgICAgICAgIGlmIChjaGFpbltjdXJySW5kZXhdLmdldElzc3VlckROKCkuZXF1YWxzKGNoYWluW25leHRJbmRleF0uZ2V0U3ViamVjdEROKCkpKSB7CisgICAgICAgICAgICAgICAgICAgIGZvdW5kTmV4dCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIC8vIEV4Y2hhbmdlIGNlcnRpZmljYXRlcyBzbyB0aGF0IDAgdGhyb3VnaCBjdXJySW5kZXggKyAxIGFyZSBpbiBwcm9wZXIgb3JkZXIKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRJbmRleCAhPSBjdXJySW5kZXggKyAxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBkb24ndCBtdXR1YXRlIG9yaWdpbmFsIGNoYWluLCB3aGljaCBtYXkgYmUgZGlyZWN0bHkgZnJvbSBhbiBTU0xTZXNzaW9uCisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hhaW4gPT0gb3JpZ2luYWwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFpbiA9IG9yaWdpbmFsLmNsb25lKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGUgdGVtcENlcnRpZmljYXRlID0gY2hhaW5bbmV4dEluZGV4XTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNoYWluW25leHRJbmRleF0gPSBjaGFpbltjdXJySW5kZXggKyAxXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNoYWluW2N1cnJJbmRleCArIDFdID0gdGVtcENlcnRpZmljYXRlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIElmIHdlIGNhbid0IGZpbmQgdGhlIG5leHQgaW4gdGhlIGNoYWluLCBqdXN0IGdpdmUgdXAKKyAgICAgICAgICAgIC8vIGFuZCB1c2Ugd2hhdCB3ZSBmb3VuZCBzbyBmYXIuIFRoaXMgZHJvcHMgdW5yZWxhdGVkCisgICAgICAgICAgICAvLyBjZXJ0aWZpY2F0ZXMgdGhhdCBoYXZlIG5vdGhpbmcgdG8gZG8gd2l0aCB0aGUgY2VydAorICAgICAgICAgICAgLy8gY2hhaW4uCisgICAgICAgICAgICBpZiAoIWZvdW5kTmV4dCkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gMi4gSWYgdGhlIGNoYWluIGlzIG5vdyBzaG9ydGVyLCBjb3B5IHRvIGFuIGFwcHJvcHJpYXRlbHkgc2l6ZWQgYXJyYXkuCisgICAgICAgIGludCBjaGFpbkxlbmd0aCA9IGN1cnJJbmRleCArIDE7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIG5ld0NoYWluID0gKChjaGFpbkxlbmd0aCA9PSBjaGFpbi5sZW5ndGgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gY2hhaW4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBBcnJheXMuY29weU9mKGNoYWluLCBjaGFpbkxlbmd0aCkpOworCisgICAgICAgIC8vIDMuIElmIG5vIFRydXN0QW5jaG9yIHdhcyBmb3VuZCBpbiBjbGVhbnVwLCBsb29rIGZvciBvbmUgbm93CisgICAgICAgIGlmICh0cnVzdEFuY2hvcnMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBUcnVzdEFuY2hvciB0cnVzdEFuY2hvciA9IGZpbmRUcnVzdEFuY2hvckJ5SXNzdWVyQW5kU2lnbmF0dXJlKG5ld0NoYWluW2NoYWluTGVuZ3RoLTFdKTsKKyAgICAgICAgICAgIGlmICh0cnVzdEFuY2hvciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdHJ1c3RBbmNob3JzLmFkZCh0cnVzdEFuY2hvcik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ld0NoYWluOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIHRoZSB0cnVzdGVkQ2VydGlmaWNhdGVJbmRleCBmb3IgdGhlIGNlcnQgdG8gc2VlIGlmIGl0IGlzCisgICAgICogYWxyZWFkeSB0cnVzdGVkIGFuZCBmYWlsaW5nIHRoYXQgY2hlY2sgdGhlIEtleVN0b3JlIGlmIGl0IGlzCisgICAgICogYXZhaWxhYmxlLgorICAgICAqLworICAgIHByaXZhdGUgVHJ1c3RBbmNob3IgZmluZFRydXN0QW5jaG9yQnlTdWJqZWN0QW5kUHVibGljS2V5KFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0KSB7CisgICAgICAgIFRydXN0QW5jaG9yIHRydXN0QW5jaG9yID0gdHJ1c3RlZENlcnRpZmljYXRlSW5kZXguZmluZEJ5U3ViamVjdEFuZFB1YmxpY0tleShjZXJ0KTsKKyAgICAgICAgaWYgKHRydXN0QW5jaG9yICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVzdEFuY2hvcjsKKyAgICAgICAgfQorICAgICAgICBpZiAodHJ1c3RlZENlcnRpZmljYXRlU3RvcmUgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gbm90IHRydXN0ZWQgYW5kIG5vIFRydXN0ZWRDZXJ0aWZpY2F0ZVN0b3JlIHRvIGNoZWNrCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICAvLyBwcm9iZSBLZXlTdG9yZSBmb3IgYSBjZXJ0LiBBbmRyb2lkQ0FTdG9yZSBzdG9yZXMgaXRzCisgICAgICAgIC8vIGNvbnRlbnRzIGhhc2hlZCBieSBjZXJ0IHN1YmplY3Qgb24gdGhlIGZpbGVzeXN0ZW0gdG8gbWFrZQorICAgICAgICAvLyB0aGlzIGZhc3RlciB0aGFuIHNjYW5uaW5nIGFsbCBrZXkgc3RvcmUgZW50cmllcy4KKyAgICAgICAgaWYgKHRydXN0ZWRDZXJ0aWZpY2F0ZVN0b3JlLmlzVHJ1c3RBbmNob3IoY2VydCkpIHsKKyAgICAgICAgICAgIC8vIGFkZCBuZXcgVHJ1c3RBbmNob3IgdG8gcGFyYW1zIGluZGV4IHRvIGF2b2lkCisgICAgICAgICAgICAvLyBjaGVja2luZyBmaWxlc3lzdGVtIG5leHQgdGltZSBhcm91bmQuCisgICAgICAgICAgICByZXR1cm4gdHJ1c3RlZENlcnRpZmljYXRlSW5kZXguaW5kZXgoY2VydCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBUcnVzdEFuY2hvciBmaW5kVHJ1c3RBbmNob3JCeUlzc3VlckFuZFNpZ25hdHVyZShYNTA5Q2VydGlmaWNhdGUgbGFzdENlcnQpIHsKKyAgICAgICAgVHJ1c3RBbmNob3IgdHJ1c3RBbmNob3IgPSB0cnVzdGVkQ2VydGlmaWNhdGVJbmRleC5maW5kQnlJc3N1ZXJBbmRTaWduYXR1cmUobGFzdENlcnQpOworICAgICAgICBpZiAodHJ1c3RBbmNob3IgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHRydXN0QW5jaG9yOworICAgICAgICB9CisgICAgICAgIGlmICh0cnVzdGVkQ2VydGlmaWNhdGVTdG9yZSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICAvLyB3ZSBoYXZlIGEgS2V5U3RvcmUgYW5kIHRoZSBpc3N1ZXIgb2YgdGhlIGxhc3QgY2VydCBpbgorICAgICAgICAvLyB0aGUgY2hhaW4gc2VlbXMgdG8gYmUgbWlzc2luZyBmcm9tIHRoZQorICAgICAgICAvLyBUcnVzdGVkQ2VydGlmaWNhdGVJbmRleCwgY2hlY2sgdGhlIEtleVN0b3JlIGZvciBhIGhpdAorICAgICAgICBYNTA5Q2VydGlmaWNhdGUgaXNzdWVyID0gdHJ1c3RlZENlcnRpZmljYXRlU3RvcmUuZmluZElzc3VlcihsYXN0Q2VydCk7CisgICAgICAgIGlmIChpc3N1ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHRydXN0ZWRDZXJ0aWZpY2F0ZUluZGV4LmluZGV4KGlzc3Vlcik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBYNTA5Q2VydGlmaWNhdGVbXSBnZXRBY2NlcHRlZElzc3VlcnMoKSB7CisgICAgICAgIHJldHVybiAoYWNjZXB0ZWRJc3N1ZXJzICE9IG51bGwpID8gYWNjZXB0ZWRJc3N1ZXJzLmNsb25lKCkgOiBhY2NlcHRlZElzc3VlcnMocm9vdEtleVN0b3JlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9UcnVzdGVkQ2VydGlmaWNhdGVJbmRleC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvVHJ1c3RlZENlcnRpZmljYXRlSW5kZXguamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MTM4YjE5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvVHJ1c3RlZENlcnRpZmljYXRlSW5kZXguamF2YQpAQCAtMCwwICsxLDEzNSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuVHJ1c3RBbmNob3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbDsKKworLyoqCisgKiBJbmRleGVzIHtAY29kZSBUcnVzdEFuY2hvcn0gaW5zdGFuY2VzIHNvIHRoZXkgY2FuIGJlIGZvdW5kIGluIE8oMSkKKyAqIHRpbWUgaW5zdGVhZCBvZiBPKE4pLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgVHJ1c3RlZENlcnRpZmljYXRlSW5kZXggeworCisgICAgcHJpdmF0ZSBmaW5hbCBNYXA8WDUwMFByaW5jaXBhbCwgTGlzdDxUcnVzdEFuY2hvcj4+IHN1YmplY3RUb1RydXN0QW5jaG9ycworICAgICAgICAgICAgPSBuZXcgSGFzaE1hcDxYNTAwUHJpbmNpcGFsLCBMaXN0PFRydXN0QW5jaG9yPj4oKTsKKworICAgIHB1YmxpYyBUcnVzdGVkQ2VydGlmaWNhdGVJbmRleCgpIHt9CisKKyAgICBwdWJsaWMgVHJ1c3RlZENlcnRpZmljYXRlSW5kZXgoU2V0PFRydXN0QW5jaG9yPiBhbmNob3JzKSB7CisgICAgICAgIGluZGV4KGFuY2hvcnMpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBpbmRleChTZXQ8VHJ1c3RBbmNob3I+IGFuY2hvcnMpIHsKKyAgICAgICAgZm9yIChUcnVzdEFuY2hvciBhbmNob3IgOiBhbmNob3JzKSB7CisgICAgICAgICAgICBpbmRleChhbmNob3IpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFRydXN0QW5jaG9yIGluZGV4KFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0KSB7CisgICAgICAgIFRydXN0QW5jaG9yIGFuY2hvciA9IG5ldyBUcnVzdEFuY2hvcihjZXJ0LCBudWxsKTsKKyAgICAgICAgaW5kZXgoYW5jaG9yKTsKKyAgICAgICAgcmV0dXJuIGFuY2hvcjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBpbmRleChUcnVzdEFuY2hvciBhbmNob3IpIHsKKyAgICAgICAgWDUwMFByaW5jaXBhbCBzdWJqZWN0OworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydCA9IGFuY2hvci5nZXRUcnVzdGVkQ2VydCgpOworICAgICAgICBpZiAoY2VydCAhPSBudWxsKSB7CisgICAgICAgICAgICBzdWJqZWN0ID0gY2VydC5nZXRTdWJqZWN0WDUwMFByaW5jaXBhbCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc3ViamVjdCA9IGFuY2hvci5nZXRDQSgpOworICAgICAgICB9CisKKyAgICAgICAgc3luY2hyb25pemVkIChzdWJqZWN0VG9UcnVzdEFuY2hvcnMpIHsKKyAgICAgICAgICAgIExpc3Q8VHJ1c3RBbmNob3I+IGFuY2hvcnMgPSBzdWJqZWN0VG9UcnVzdEFuY2hvcnMuZ2V0KHN1YmplY3QpOworICAgICAgICAgICAgaWYgKGFuY2hvcnMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFuY2hvcnMgPSBuZXcgQXJyYXlMaXN0PFRydXN0QW5jaG9yPigxKTsKKyAgICAgICAgICAgICAgICBzdWJqZWN0VG9UcnVzdEFuY2hvcnMucHV0KHN1YmplY3QsIGFuY2hvcnMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYW5jaG9ycy5hZGQoYW5jaG9yKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBUcnVzdEFuY2hvciBmaW5kQnlJc3N1ZXJBbmRTaWduYXR1cmUoWDUwOUNlcnRpZmljYXRlIGNlcnQpIHsKKyAgICAgICAgWDUwMFByaW5jaXBhbCBpc3N1ZXIgPSBjZXJ0LmdldElzc3Vlclg1MDBQcmluY2lwYWwoKTsKKyAgICAgICAgc3luY2hyb25pemVkIChzdWJqZWN0VG9UcnVzdEFuY2hvcnMpIHsKKyAgICAgICAgICAgIExpc3Q8VHJ1c3RBbmNob3I+IGFuY2hvcnMgPSBzdWJqZWN0VG9UcnVzdEFuY2hvcnMuZ2V0KGlzc3Vlcik7CisgICAgICAgICAgICBpZiAoYW5jaG9ycyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGZvciAoVHJ1c3RBbmNob3IgYW5jaG9yIDogYW5jaG9ycykgeworICAgICAgICAgICAgICAgIFB1YmxpY0tleSBwdWJsaWNLZXk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlIGNhQ2VydCA9IGFuY2hvci5nZXRUcnVzdGVkQ2VydCgpOworICAgICAgICAgICAgICAgICAgICBpZiAoY2FDZXJ0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpY0tleSA9IGNhQ2VydC5nZXRQdWJsaWNLZXkoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpY0tleSA9IGFuY2hvci5nZXRDQVB1YmxpY0tleSgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGNlcnQudmVyaWZ5KHB1YmxpY0tleSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBhbmNob3I7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIFRydXN0QW5jaG9yIGZpbmRCeVN1YmplY3RBbmRQdWJsaWNLZXkoWDUwOUNlcnRpZmljYXRlIGNlcnQpIHsKKyAgICAgICAgWDUwMFByaW5jaXBhbCBzdWJqZWN0ID0gY2VydC5nZXRTdWJqZWN0WDUwMFByaW5jaXBhbCgpOworICAgICAgICBzeW5jaHJvbml6ZWQgKHN1YmplY3RUb1RydXN0QW5jaG9ycykgeworICAgICAgICAgICAgTGlzdDxUcnVzdEFuY2hvcj4gYW5jaG9ycyA9IHN1YmplY3RUb1RydXN0QW5jaG9ycy5nZXQoc3ViamVjdCk7CisgICAgICAgICAgICBpZiAoYW5jaG9ycyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZmluZEJ5U3ViamVjdEFuZFB1YmxpY0tleShjZXJ0LCBhbmNob3JzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFRydXN0QW5jaG9yIGZpbmRCeVN1YmplY3RBbmRQdWJsaWNLZXkoWDUwOUNlcnRpZmljYXRlIGNlcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsZWN0aW9uPFRydXN0QW5jaG9yPiBhbmNob3JzKSB7CisgICAgICAgIFB1YmxpY0tleSBjZXJ0UHVibGljS2V5ID0gY2VydC5nZXRQdWJsaWNLZXkoKTsKKyAgICAgICAgZm9yIChUcnVzdEFuY2hvciBhbmNob3IgOiBhbmNob3JzKSB7CisgICAgICAgICAgICBQdWJsaWNLZXkgY2FQdWJsaWNLZXk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjYUNlcnQgPSBhbmNob3IuZ2V0VHJ1c3RlZENlcnQoKTsKKyAgICAgICAgICAgICAgICBpZiAoY2FDZXJ0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgY2FQdWJsaWNLZXkgPSBjYUNlcnQuZ2V0UHVibGljS2V5KCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgY2FQdWJsaWNLZXkgPSBhbmNob3IuZ2V0Q0FQdWJsaWNLZXkoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGNhUHVibGljS2V5LmVxdWFscyhjZXJ0UHVibGljS2V5KSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gYW5jaG9yOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gY2FuIGhhcHBlbiB3aXRoIHVuc3VwcG9ydGVkIHB1YmxpYyBrZXkgdHlwZXMKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9UcnVzdGVkQ2VydGlmaWNhdGVLZXlTdG9yZVNwaS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvVHJ1c3RlZENlcnRpZmljYXRlS2V5U3RvcmVTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MmE2NjQ3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvVHJ1c3RlZENlcnRpZmljYXRlS2V5U3RvcmVTcGkuamF2YQpAQCAtMCwwICsxLDExMyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZVNwaTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKKworLyoqCisgKiBBIEtleVN0b3JlU3BpIHdyYXBwZXIgZm9yIHRoZSBUcnVzdGVkQ2VydGlmaWNhdGVTdG9yZS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFRydXN0ZWRDZXJ0aWZpY2F0ZUtleVN0b3JlU3BpIGV4dGVuZHMgS2V5U3RvcmVTcGkgeworCisgICAgcHJpdmF0ZSBmaW5hbCBUcnVzdGVkQ2VydGlmaWNhdGVTdG9yZSBzdG9yZSA9IG5ldyBUcnVzdGVkQ2VydGlmaWNhdGVTdG9yZSgpOworCisgICAgQE92ZXJyaWRlIHB1YmxpYyBLZXkgZW5naW5lR2V0S2V5KFN0cmluZyBhbGlhcywgY2hhcltdIHBhc3N3b3JkKSB7CisgICAgICAgIGlmIChhbGlhcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImFsaWFzID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIENlcnRpZmljYXRlW10gZW5naW5lR2V0Q2VydGlmaWNhdGVDaGFpbihTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgaWYgKGFsaWFzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiYWxpYXMgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgQ2VydGlmaWNhdGUgZW5naW5lR2V0Q2VydGlmaWNhdGUoU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIHJldHVybiBzdG9yZS5nZXRDZXJ0aWZpY2F0ZShhbGlhcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBEYXRlIGVuZ2luZUdldENyZWF0aW9uRGF0ZShTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgcmV0dXJuIHN0b3JlLmdldENyZWF0aW9uRGF0ZShhbGlhcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGVuZ2luZVNldEtleUVudHJ5KAorICAgICAgICAgICAgU3RyaW5nIGFsaWFzLCBLZXkga2V5LCBjaGFyW10gcGFzc3dvcmQsIENlcnRpZmljYXRlW10gY2hhaW4pIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGVuZ2luZVNldEtleUVudHJ5KFN0cmluZyBhbGlhcywgYnl0ZVtdIGtleSwgQ2VydGlmaWNhdGVbXSBjaGFpbikgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZW5naW5lU2V0Q2VydGlmaWNhdGVFbnRyeShTdHJpbmcgYWxpYXMsIENlcnRpZmljYXRlIGNlcnQpIHsKKyAgICAgICAgaWYgKGFsaWFzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiYWxpYXMgPT0gbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBlbmdpbmVEZWxldGVFbnRyeShTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGVuZ2luZUFsaWFzZXMoKSB7CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbnVtZXJhdGlvbihzdG9yZS5hbGlhc2VzKCkpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBlbmdpbmVDb250YWluc0FsaWFzKFN0cmluZyBhbGlhcykgeworICAgICAgICByZXR1cm4gc3RvcmUuY29udGFpbnNBbGlhcyhhbGlhcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgZW5naW5lU2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIHN0b3JlLmFsaWFzZXMoKS5zaXplKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVuZ2luZUlzS2V5RW50cnkoU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIGlmIChhbGlhcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImFsaWFzID09IG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGVuZ2luZUlzQ2VydGlmaWNhdGVFbnRyeShTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgcmV0dXJuIGVuZ2luZUNvbnRhaW5zQWxpYXMoYWxpYXMpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIGVuZ2luZUdldENlcnRpZmljYXRlQWxpYXMoQ2VydGlmaWNhdGUgYykgeworICAgICAgICByZXR1cm4gc3RvcmUuZ2V0Q2VydGlmaWNhdGVBbGlhcyhjKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZW5naW5lU3RvcmUoT3V0cHV0U3RyZWFtIHN0cmVhbSwgY2hhcltdIHBhc3N3b3JkKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBlbmdpbmVMb2FkKElucHV0U3RyZWFtIHN0cmVhbSwgY2hhcltdIHBhc3N3b3JkKSB7CisgICAgICAgIGlmIChzdHJlYW0gIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9UcnVzdGVkQ2VydGlmaWNhdGVTdG9yZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvVHJ1c3RlZENlcnRpZmljYXRlU3RvcmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NDExNmE3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvVHJ1c3RlZENlcnRpZmljYXRlU3RvcmUuamF2YQpAQCAtMCwwICsxLDUyNSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlU3BpOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0U2VsZWN0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CitpbXBvcnQgbGliY29yZS5pby5Jb1V0aWxzOworCisvKioKKyAqIEEgc291cmNlIGZvciB0cnVzdGVkIHJvb3QgY2VydGlmaWNhdGUgYXV0aG9yaXR5IChDQSkgY2VydGlmaWNhdGVzCisgKiBzdXBwb3J0aW5nIGFuIGltbXV0YWJsZSBzeXN0ZW0gQ0EgZGlyZWN0b3J5IGFsb25nIHdpdGggbXV0YWJsZQorICogZGlyZWN0b3JpZXMgYWxsb3dpbmcgdGhlIHVzZXIgYWRkaXRpb24gb2YgY3VzdG9tIENBcyBhbmQgdXNlcgorICogcmVtb3ZhbCBvZiBzeXN0ZW0gQ0FzLiBUaGlzIHN0b3JlIHN1cHBvcnRzIHRoZSB7QGNvZGUKKyAqIFRydXN0ZWRDZXJ0aWZpY2F0ZUtleVN0b3JlU3BpfSB3cmFwcGVyIHRvIGFsbG93IGEgdHJhZGl0aW9uYWwKKyAqIEtleVN0b3JlIGludGVyZmFjZSBmb3IgdXNlIHdpdGgge0BsaW5rCisgKiBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlckZhY3RvcnkuaW5pdH0uCisgKgorICogPHA+VGhlIENBcyBhcmUgYWNjZXNzZWQgdmlhIHtAY29kZSBLZXlTdG9yZX0gc3R5bGUgYWxpYXNlcy4gQWxpYXNlcworICogYXJlIG1hZGUgdXAgb2YgYSBwcmVmaXggaWRlbnRpZnlpbmcgdGhlIHNvdXJjZSAoInN5c3RlbToiIHZzCisgKiAidXNlcjoiKSBhbmQgYSBzdWZmaXggYmFzZWQgb24gdGhlIE9wZW5TU0wgWDUwOV9OQU1FX2hhc2hfb2xkCisgKiBmdW5jdGlvbiBvZiB0aGUgQ0EncyBzdWJqZWN0IG5hbWUuIEZvciBleGFtcGxlLCB0aGUgc3lzdGVtIENBIGZvcgorICogIkM9VVMsIE89VmVyaVNpZ24sIEluYy4sIE9VPUNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbgorICogQXV0aG9yaXR5IiBjb3VsZCBiZSByZXByZXNlbnRlZCBhcyAic3lzdGVtOjc2NTFiMzI3LjAiLiBCeSB1c2luZworICogdGhlIHN1YmplY3QgaGFzaCwgb3BlcmF0aW9ucyBzdWNoIGFzIHtAbGluayAjZ2V0Q2VydGlmaWNhdGVBbGlhcworICogZ2V0Q2VydGlmaWNhdGVBbGlhc30gY2FuIGJlIGltcGxlbWVudGVkIGVmZmljaWVudGx5IHdpdGhvdXQKKyAqIHNjYW5uaW5nIHRoZSBlbnRpcmUgc3RvcmUuCisgKgorICogPHA+SW4gYWRkaXRpb24gdG8gc3VwcG9ydGluZyB0aGUge0Bjb2RlCisgKiBUcnVzdGVkQ2VydGlmaWNhdGVLZXlTdG9yZVNwaX0gaW1wbGVtZW50YXRpb24sIHtAY29kZQorICogVHJ1c3RlZENlcnRpZmljYXRlU3RvcmV9IGFsc28gcHJvdmlkZXMgdGhlIGFkZGl0aW9uYWwgcHVibGljCisgKiBtZXRob2RzIHtAbGluayAjaXNUcnVzdEFuY2hvcn0gYW5kIHtAbGluayAjZmluZElzc3Vlcn0gdG8gYWxsb3cKKyAqIGVmZmljaWVudCBsb29rdXAgb3BlcmF0aW9ucyBmb3IgQ0FzIGFnYWluIGJhc2VkIG9uIHRoZSBmaWxlIG5hbWluZworICogY29udmVudGlvbi4KKyAqCisgKiA8cD5UaGUgS2V5Q2hhaW5TZXJ2aWNlIHVzZXJzIHRoZSB7QGxpbmsgaW5zdGFsbENlcnRpZmljYXRlfSBhbmQKKyAqIHtAbGluayAjZGVsZXRlQ2VydGlmaWNhdGVFbnRyeX0gdG8gaW5zdGFsbCB1c2VyIENBcyBhcyB3ZWxsIGFzCisgKiBkZWxldGUgdGhvc2UgdXNlciBDQXMgYXMgd2VsbCBhcyBzeXN0ZW0gQ0FzLiBUaGUgZGVsZXRpb24gb2Ygc3lzdGVtCisgKiBDQXMgaXMgcGVyZm9ybWVkIGJ5IHBsYWNpbmcgYW4gZXhhY3QgY29weSBvZiB0aGF0IENBIGluIHRoZSBkZWxldGVkCisgKiBkaXJlY3RvcnkuIFN1Y2ggZGVsZXRpb25zIGFyZSBpbnRlbmRlZCB0byBwZXJzaXN0IGFjcm9zcyB1cGdyYWRlcworICogYnV0IG5vdCBpbnRlbmRlZCB0byBtYXNrIGEgQ0Egd2l0aCBhIG1hdGNoaW5nIG5hbWUgb3IgcHVibGljIGtleQorICogYnV0IGlzIG90aGVyd2lzZSByZWlzc3VlZCBpbiBhIHN5c3RlbSB1cGRhdGUuIFJlaW5zdGFsbGluZyBhCisgKiBkZWxldGVkIHN5c3RlbSBjZXJ0aWZpY2F0ZSBzaW1wbHkgcmVtb3ZlcyB0aGUgY29weSBmcm9tIHRoZSBkZWxldGVkCisgKiBkaXJlY3RvcnksIHJlZW5hYmxpbmcgdGhlIG9yaWdpbmFsIGluIHRoZSBzeXN0ZW0gZGlyZWN0b3J5LgorICoKKyAqIDxwPk5vdGUgdGhhdCB0aGUgZGVmYXVsdCBtdXRhYmxlIGRpcmVjdG9yeSBpcyBjcmVhdGVkIGJ5IGluaXQgdmlhCisgKiBjb25maWd1cmF0aW9uIGluIHRoZSBzeXN0ZW0vY29yZS9yb290ZGlyL2luaXQucmMgZmlsZS4gVGhlCisgKiBkaXJlY3RpdmUgIm1rZGlyIC9kYXRhL21pc2Mva2V5Y2hhaW4gMDc3NSBzeXN0ZW0gc3lzdGVtIgorICogZW5zdXJlcyB0aGF0IGl0cyBvd25lciBhbmQgZ3JvdXAgYXJlIHRoZSBzeXN0ZW0gdWlkIGFuZCBzeXN0ZW0KKyAqIGdpZCBhbmQgdGhhdCBpdCBpcyB3b3JsZCByZWFkYWJsZSBidXQgb25seSB3cml0YWJsZSBieSB0aGUgc3lzdGVtCisgKiB1c2VyLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgVHJ1c3RlZENlcnRpZmljYXRlU3RvcmUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBSRUZJWF9TWVNURU0gPSAic3lzdGVtOiI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBSRUZJWF9VU0VSID0gInVzZXI6IjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYm9vbGVhbiBpc1N5c3RlbShTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgcmV0dXJuIGFsaWFzLnN0YXJ0c1dpdGgoUFJFRklYX1NZU1RFTSk7CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYm9vbGVhbiBpc1VzZXIoU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIHJldHVybiBhbGlhcy5zdGFydHNXaXRoKFBSRUZJWF9VU0VSKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWxlIENBX0NFUlRTX0RJUl9TWVNURU07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmlsZSBDQV9DRVJUU19ESVJfQURERUQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmlsZSBDQV9DRVJUU19ESVJfREVMRVRFRDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDZXJ0aWZpY2F0ZUZhY3RvcnkgQ0VSVF9GQUNUT1JZOworICAgIHN0YXRpYyB7CisgICAgICAgIFN0cmluZyBBTkRST0lEX1JPT1QgPSBTeXN0ZW0uZ2V0ZW52KCJBTkRST0lEX1JPT1QiKTsKKyAgICAgICAgU3RyaW5nIEFORFJPSURfREFUQSA9IFN5c3RlbS5nZXRlbnYoIkFORFJPSURfREFUQSIpOworICAgICAgICBDQV9DRVJUU19ESVJfU1lTVEVNID0gbmV3IEZpbGUoQU5EUk9JRF9ST09UICsgIi9ldGMvc2VjdXJpdHkvY2FjZXJ0cyIpOworICAgICAgICBDQV9DRVJUU19ESVJfQURERUQgPSBuZXcgRmlsZShBTkRST0lEX0RBVEEgKyAiL21pc2Mva2V5Y2hhaW4vY2FjZXJ0cy1hZGRlZCIpOworICAgICAgICBDQV9DRVJUU19ESVJfREVMRVRFRCA9IG5ldyBGaWxlKEFORFJPSURfREFUQSArICIvbWlzYy9rZXljaGFpbi9jYWNlcnRzLXJlbW92ZWQiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ0VSVF9GQUNUT1JZID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYNTA5Iik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgRmlsZSBzeXN0ZW1EaXI7CisgICAgcHJpdmF0ZSBmaW5hbCBGaWxlIGFkZGVkRGlyOworICAgIHByaXZhdGUgZmluYWwgRmlsZSBkZWxldGVkRGlyOworCisgICAgcHVibGljIFRydXN0ZWRDZXJ0aWZpY2F0ZVN0b3JlKCkgeworICAgICAgICB0aGlzKENBX0NFUlRTX0RJUl9TWVNURU0sIENBX0NFUlRTX0RJUl9BRERFRCwgQ0FfQ0VSVFNfRElSX0RFTEVURUQpOworICAgIH0KKworICAgIHB1YmxpYyBUcnVzdGVkQ2VydGlmaWNhdGVTdG9yZShGaWxlIHN5c3RlbURpciwgRmlsZSBhZGRlZERpciwgRmlsZSBkZWxldGVkRGlyKSB7CisgICAgICAgIHRoaXMuc3lzdGVtRGlyID0gc3lzdGVtRGlyOworICAgICAgICB0aGlzLmFkZGVkRGlyID0gYWRkZWREaXI7CisgICAgICAgIHRoaXMuZGVsZXRlZERpciA9IGRlbGV0ZWREaXI7CisgICAgfQorCisgICAgcHVibGljIENlcnRpZmljYXRlIGdldENlcnRpZmljYXRlKFN0cmluZyBhbGlhcykgeworICAgICAgICByZXR1cm4gZ2V0Q2VydGlmaWNhdGUoYWxpYXMsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQ2VydGlmaWNhdGUgZ2V0Q2VydGlmaWNhdGUoU3RyaW5nIGFsaWFzLCBib29sZWFuIGluY2x1ZGVEZWxldGVkU3lzdGVtKSB7CisKKyAgICAgICAgRmlsZSBmaWxlID0gZmlsZUZvckFsaWFzKGFsaWFzKTsKKyAgICAgICAgaWYgKGZpbGUgPT0gbnVsbCB8fCAoaXNVc2VyKGFsaWFzKSAmJiBpc1RvbWJzdG9uZShmaWxlKSkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0ID0gcmVhZENlcnRpZmljYXRlKGZpbGUpOworICAgICAgICBpZiAoY2VydCA9PSBudWxsIHx8IChpc1N5c3RlbShhbGlhcykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgIWluY2x1ZGVEZWxldGVkU3lzdGVtCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGlzRGVsZXRlZFN5c3RlbUNlcnRpZmljYXRlKGNlcnQpKSkgeworICAgICAgICAgICAgLy8gc2tpcCBtYWxmb3JtZWQgY2VydHMgYXMgd2VsbCBhcyBkZWxldGVkIHN5c3RlbSBvbmVzCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2VydDsKKyAgICB9CisKKyAgICBwcml2YXRlIEZpbGUgZmlsZUZvckFsaWFzKFN0cmluZyBhbGlhcykgeworICAgICAgICBpZiAoYWxpYXMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJhbGlhcyA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgRmlsZSBmaWxlOworICAgICAgICBpZiAoaXNTeXN0ZW0oYWxpYXMpKSB7CisgICAgICAgICAgICBmaWxlID0gbmV3IEZpbGUoc3lzdGVtRGlyLCBhbGlhcy5zdWJzdHJpbmcoUFJFRklYX1NZU1RFTS5sZW5ndGgoKSkpOworICAgICAgICB9IGVsc2UgaWYgKGlzVXNlcihhbGlhcykpIHsKKyAgICAgICAgICAgIGZpbGUgPSBuZXcgRmlsZShhZGRlZERpciwgYWxpYXMuc3Vic3RyaW5nKFBSRUZJWF9VU0VSLmxlbmd0aCgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoIWZpbGUuZXhpc3RzKCkgfHwgaXNUb21ic3RvbmUoZmlsZSkpIHsKKyAgICAgICAgICAgIC8vIHNpbGVudGx5IGVsaWRlIHRvbWJzdG9uZXMKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmaWxlOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBpc1RvbWJzdG9uZShGaWxlIGZpbGUpIHsKKyAgICAgICAgcmV0dXJuIGZpbGUubGVuZ3RoKCkgPT0gMDsKKyAgICB9CisKKyAgICBwcml2YXRlIFg1MDlDZXJ0aWZpY2F0ZSByZWFkQ2VydGlmaWNhdGUoRmlsZSBmaWxlKSB7CisgICAgICAgIGlmICghZmlsZS5pc0ZpbGUoKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpKTsKKyAgICAgICAgICAgIHJldHVybiAoWDUwOUNlcnRpZmljYXRlKSBDRVJUX0ZBQ1RPUlkuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShpcyk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyByZWFkaW5nIGEgY2VydCB3aGlsZSBpdHMgYmVpbmcgaW5zdGFsbGVkIGNhbiBsZWFkIHRvIHRoaXMuCisgICAgICAgICAgICAvLyBqdXN0IHByZXRlbmQgbGlrZSBpdHMgbm90IGF2YWlsYWJsZSB5ZXQuCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIElvVXRpbHMuY2xvc2VRdWlldGx5KGlzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZUNlcnRpZmljYXRlKEZpbGUgZmlsZSwgWDUwOUNlcnRpZmljYXRlIGNlcnQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZSBkaXIgPSBmaWxlLmdldFBhcmVudEZpbGUoKTsKKyAgICAgICAgZGlyLm1rZGlycygpOworICAgICAgICBkaXIuc2V0UmVhZGFibGUodHJ1ZSwgZmFsc2UpOworICAgICAgICBkaXIuc2V0RXhlY3V0YWJsZSh0cnVlLCBmYWxzZSk7CisgICAgICAgIE91dHB1dFN0cmVhbSBvcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZpbGUpOworICAgICAgICAgICAgb3Mud3JpdGUoY2VydC5nZXRFbmNvZGVkKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgSW9VdGlscy5jbG9zZVF1aWV0bHkob3MpOworICAgICAgICB9CisgICAgICAgIGZpbGUuc2V0UmVhZGFibGUodHJ1ZSwgZmFsc2UpOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBpc0RlbGV0ZWRTeXN0ZW1DZXJ0aWZpY2F0ZShYNTA5Q2VydGlmaWNhdGUgeCkgeworICAgICAgICByZXR1cm4gZ2V0Q2VydGlmaWNhdGVGaWxlKGRlbGV0ZWREaXIsIHgpLmV4aXN0cygpOworICAgIH0KKworICAgIHB1YmxpYyBEYXRlIGdldENyZWF0aW9uRGF0ZShTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgLy8gY29udGFpbnNBbGlhcyBjaGVjayBlbnN1cmVzIHRoZSBsYXRlciBmaWxlRm9yQWxpYXMgcmVzdWx0CisgICAgICAgIC8vIHdhcyBub3QgYSBkZWxldGVkIHN5c3RlbSBjZXJ0LgorICAgICAgICBpZiAoIWNvbnRhaW5zQWxpYXMoYWxpYXMpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBGaWxlIGZpbGUgPSBmaWxlRm9yQWxpYXMoYWxpYXMpOworICAgICAgICBpZiAoZmlsZSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBsb25nIHRpbWUgPSBmaWxlLmxhc3RNb2RpZmllZCgpOworICAgICAgICBpZiAodGltZSA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IERhdGUodGltZSk7CisgICAgfQorCisgICAgcHVibGljIFNldDxTdHJpbmc+IGFsaWFzZXMoKSB7CisgICAgICAgIFNldDxTdHJpbmc+IHJlc3VsdCA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKyAgICAgICAgYWRkQWxpYXNlcyhyZXN1bHQsIFBSRUZJWF9VU0VSLCBhZGRlZERpcik7CisgICAgICAgIGFkZEFsaWFzZXMocmVzdWx0LCBQUkVGSVhfU1lTVEVNLCBzeXN0ZW1EaXIpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBTZXQ8U3RyaW5nPiB1c2VyQWxpYXNlcygpIHsKKyAgICAgICAgU2V0PFN0cmluZz4gcmVzdWx0ID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgICBhZGRBbGlhc2VzKHJlc3VsdCwgUFJFRklYX1VTRVIsIGFkZGVkRGlyKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYWRkQWxpYXNlcyhTZXQ8U3RyaW5nPiByZXN1bHQsIFN0cmluZyBwcmVmaXgsIEZpbGUgZGlyKSB7CisgICAgICAgIFN0cmluZ1tdIGZpbGVzID0gZGlyLmxpc3QoKTsKKyAgICAgICAgaWYgKGZpbGVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmb3IgKFN0cmluZyBmaWxlbmFtZSA6IGZpbGVzKSB7CisgICAgICAgICAgICBTdHJpbmcgYWxpYXMgPSBwcmVmaXggKyBmaWxlbmFtZTsKKyAgICAgICAgICAgIGlmIChjb250YWluc0FsaWFzKGFsaWFzKSkgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQoYWxpYXMpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFNldDxTdHJpbmc+IGFsbFN5c3RlbUFsaWFzZXMoKSB7CisgICAgICAgIFNldDxTdHJpbmc+IHJlc3VsdCA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKyAgICAgICAgU3RyaW5nW10gZmlsZXMgPSBzeXN0ZW1EaXIubGlzdCgpOworICAgICAgICBpZiAoZmlsZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgICAgICBmb3IgKFN0cmluZyBmaWxlbmFtZSA6IGZpbGVzKSB7CisgICAgICAgICAgICBTdHJpbmcgYWxpYXMgPSBQUkVGSVhfU1lTVEVNICsgZmlsZW5hbWU7CisgICAgICAgICAgICBpZiAoY29udGFpbnNBbGlhcyhhbGlhcywgdHJ1ZSkpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYWRkKGFsaWFzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQWxpYXMoU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIHJldHVybiBjb250YWluc0FsaWFzKGFsaWFzLCBmYWxzZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGNvbnRhaW5zQWxpYXMoU3RyaW5nIGFsaWFzLCBib29sZWFuIGluY2x1ZGVEZWxldGVkU3lzdGVtKSB7CisgICAgICAgIHJldHVybiBnZXRDZXJ0aWZpY2F0ZShhbGlhcywgaW5jbHVkZURlbGV0ZWRTeXN0ZW0pICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRDZXJ0aWZpY2F0ZUFsaWFzKENlcnRpZmljYXRlIGMpIHsKKyAgICAgICAgaWYgKGMgPT0gbnVsbCB8fCAhKGMgaW5zdGFuY2VvZiBYNTA5Q2VydGlmaWNhdGUpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBYNTA5Q2VydGlmaWNhdGUgeCA9IChYNTA5Q2VydGlmaWNhdGUpIGM7CisgICAgICAgIEZpbGUgdXNlciA9IGdldENlcnRpZmljYXRlRmlsZShhZGRlZERpciwgeCk7CisgICAgICAgIGlmICh1c2VyLmV4aXN0cygpKSB7CisgICAgICAgICAgICByZXR1cm4gUFJFRklYX1VTRVIgKyB1c2VyLmdldE5hbWUoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaXNEZWxldGVkU3lzdGVtQ2VydGlmaWNhdGUoeCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIEZpbGUgc3lzdGVtID0gZ2V0Q2VydGlmaWNhdGVGaWxlKHN5c3RlbURpciwgeCk7CisgICAgICAgIGlmIChzeXN0ZW0uZXhpc3RzKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBQUkVGSVhfU1lTVEVNICsgc3lzdGVtLmdldE5hbWUoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgRmlsZSBmb3Igd2hlcmUgdGhlIGNlcnRpZmljYXRlIGlzIGZvdW5kIGlmIGl0IGV4aXN0cworICAgICAqIG9yIHdoZXJlIGl0IHNob3VsZCBiZSBpbnN0YWxsZWQgaWYgaXQgZG9lcyBub3QgZXhpc3QuIFRoZQorICAgICAqIGNhbGxlciBjYW4gZGlzYW1iaWd1YXRlIHRoZXNlIGNhc2VzIGJ5IGNhbGxpbmcge0Bjb2RlCisgICAgICogRmlsZS5leGlzdHMoKX0gb24gdGhlIHJlc3VsdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIEZpbGUgZ2V0Q2VydGlmaWNhdGVGaWxlKEZpbGUgZGlyLCBmaW5hbCBYNTA5Q2VydGlmaWNhdGUgeCkgeworICAgICAgICAvLyBjb21wYXJlIFg1MDlDZXJ0aWZpY2F0ZS5nZXRFbmNvZGVkIHZhbHVlcworICAgICAgICBDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgQ2VydFNlbGVjdG9yKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIG1hdGNoKFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNlcnQuZXF1YWxzKHgpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICByZXR1cm4gZmluZENlcnQoZGlyLCB4LmdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCksIHNlbGVjdG9yLCBGaWxlLmNsYXNzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG5vbi17QGNvZGUgS2V5U3RvcmVTcGl9IHB1YmxpYyBpbnRlcmZhY2UgaXMgdXNlZCBieSB7QGNvZGUKKyAgICAgKiBUcnVzdE1hbmFnZXJJbXBsfSB0byBsb2NhdGUgYSBDQSBjZXJ0aWZpY2F0ZSB3aXRoIHRoZSBzYW1lIG5hbWUKKyAgICAgKiBhbmQgcHVibGljIGtleSBhcyB0aGUgcHJvdmlkZWQge0Bjb2RlIFg1MDlDZXJ0aWZpY2F0ZX0uIFdlCisgICAgICogbWF0Y2ggb24gdGhlIG5hbWUgYW5kIHB1YmxpYyBrZXkgYW5kIG5vdCB0aGUgZW50aXJlIGNlcnRpZmljYXRlCisgICAgICogc2luY2UgYSBDQSBtYXkgYmUgcmVpc3N1ZWQgd2l0aCB0aGUgc2FtZSBuYW1lIGFuZCBQdWJsaWNLZXkgYnV0CisgICAgICogd2l0aCBvdGhlciBkaWZmZXJlbmNlcyAoZm9yIGV4YW1wbGUgd2hlbiBzd2l0Y2hpbmcgc2lnbmF0dXJlCisgICAgICogZnJvbSBtZDJXaXRoUlNBRW5jcnlwdGlvbiB0byBTSEExd2l0aFJTQSkKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1RydXN0QW5jaG9yKGZpbmFsIFg1MDlDZXJ0aWZpY2F0ZSBjKSB7CisgICAgICAgIC8vIGNvbXBhcmUgWDUwOUNlcnRpZmljYXRlLmdldFB1YmxpY0tleSB2YWx1ZXMKKyAgICAgICAgQ2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IENlcnRTZWxlY3RvcigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBtYXRjaChYNTA5Q2VydGlmaWNhdGUgY2EpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY2EuZ2V0UHVibGljS2V5KCkuZXF1YWxzKGMuZ2V0UHVibGljS2V5KCkpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBib29sZWFuIHVzZXIgPSBmaW5kQ2VydChhZGRlZERpciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5nZXRTdWJqZWN0WDUwMFByaW5jaXBhbCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQm9vbGVhbi5jbGFzcyk7CisgICAgICAgIGlmICh1c2VyKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBYNTA5Q2VydGlmaWNhdGUgc3lzdGVtID0gZmluZENlcnQoc3lzdGVtRGlyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5nZXRTdWJqZWN0WDUwMFByaW5jaXBhbCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGUuY2xhc3MpOworICAgICAgICByZXR1cm4gc3lzdGVtICE9IG51bGwgJiYgIWlzRGVsZXRlZFN5c3RlbUNlcnRpZmljYXRlKHN5c3RlbSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBub24te0Bjb2RlIEtleVN0b3JlU3BpfSBwdWJsaWMgaW50ZXJmYWNlIGlzIHVzZWQgYnkge0Bjb2RlCisgICAgICogVHJ1c3RNYW5hZ2VySW1wbH0gdG8gbG9jYXRlIHRoZSBDQSBjZXJ0aWZpY2F0ZSB0aGF0IHNpZ25lZCB0aGUKKyAgICAgKiBwcm92aWRlZCB7QGNvZGUgWDUwOUNlcnRpZmljYXRlfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgWDUwOUNlcnRpZmljYXRlIGZpbmRJc3N1ZXIoZmluYWwgWDUwOUNlcnRpZmljYXRlIGMpIHsKKyAgICAgICAgLy8gbWF0Y2ggb24gdmVyaWZpZWQgaXNzdWVyIG9mIENlcnRpZmljYXRlCisgICAgICAgIENlcnRTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBDZXJ0U2VsZWN0b3IoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gbWF0Y2goWDUwOUNlcnRpZmljYXRlIGNhKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgYy52ZXJpZnkoY2EuZ2V0UHVibGljS2V5KCkpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBYNTAwUHJpbmNpcGFsIGlzc3VlciA9IGMuZ2V0SXNzdWVyWDUwMFByaW5jaXBhbCgpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgdXNlciA9IGZpbmRDZXJ0KGFkZGVkRGlyLCBpc3N1ZXIsIHNlbGVjdG9yLCBYNTA5Q2VydGlmaWNhdGUuY2xhc3MpOworICAgICAgICBpZiAodXNlciAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gdXNlcjsKKyAgICAgICAgfQorICAgICAgICBYNTA5Q2VydGlmaWNhdGUgc3lzdGVtID0gZmluZENlcnQoc3lzdGVtRGlyLCBpc3N1ZXIsIHNlbGVjdG9yLCBYNTA5Q2VydGlmaWNhdGUuY2xhc3MpOworICAgICAgICBpZiAoc3lzdGVtICE9IG51bGwgJiYgIWlzRGVsZXRlZFN5c3RlbUNlcnRpZmljYXRlKHN5c3RlbSkpIHsKKyAgICAgICAgICAgIHJldHVybiBzeXN0ZW07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLy8gbGlrZSBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFNlbGVjdG9yIGJ1dCB3aXRoIFg1MDlDZXJ0aWZpY2F0ZSBhbmQgd2l0aG91dCBjbG9uaW5nCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50ZXJmYWNlIENlcnRTZWxlY3RvciB7CisgICAgICAgIHB1YmxpYyBib29sZWFuIG1hdGNoKFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0KTsKKyAgICB9CisKKyAgICBwcml2YXRlIDxUPiBUIGZpbmRDZXJ0KAorICAgICAgICAgICAgRmlsZSBkaXIsIFg1MDBQcmluY2lwYWwgc3ViamVjdCwgQ2VydFNlbGVjdG9yIHNlbGVjdG9yLCBDbGFzczxUPiBkZXNpcmVkUmV0dXJuVHlwZSkgeworCisgICAgICAgIFN0cmluZyBoYXNoID0gaGFzaChzdWJqZWN0KTsKKyAgICAgICAgZm9yIChpbnQgaW5kZXggPSAwOyB0cnVlOyBpbmRleCsrKSB7CisgICAgICAgICAgICBGaWxlIGZpbGUgPSBmaWxlKGRpciwgaGFzaCwgaW5kZXgpOworICAgICAgICAgICAgaWYgKCFmaWxlLmlzRmlsZSgpKSB7CisgICAgICAgICAgICAgICAgLy8gY291bGQgbm90IGZpbmQgYSBtYXRjaCwgbm8gZmlsZSBleGlzdHMsIGJhaWwKKyAgICAgICAgICAgICAgICBpZiAoZGVzaXJlZFJldHVyblR5cGUgPT0gQm9vbGVhbi5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpIEJvb2xlYW4uRkFMU0U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChkZXNpcmVkUmV0dXJuVHlwZSA9PSBGaWxlLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIHdlIHJldHVybiBmaWxlIHNvIHRoYXQgY2FsbGVyIHRoYXQgd2FudHMgdG8KKyAgICAgICAgICAgICAgICAgICAgLy8gd3JpdGUga25vd3Mgd2hhdCB0aGUgbmV4dCBhdmFpbGFibGUgaGFzCisgICAgICAgICAgICAgICAgICAgIC8vIGxvY2F0aW9uIGlzCisgICAgICAgICAgICAgICAgICAgIHJldHVybiAoVCkgZmlsZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaXNUb21ic3RvbmUoZmlsZSkpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0ID0gcmVhZENlcnRpZmljYXRlKGZpbGUpOworICAgICAgICAgICAgaWYgKGNlcnQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIHNraXAgcHJvYmxlbSBjZXJ0aWZpY2F0ZXMKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzZWxlY3Rvci5tYXRjaChjZXJ0KSkgeworICAgICAgICAgICAgICAgIGlmIChkZXNpcmVkUmV0dXJuVHlwZSA9PSBYNTA5Q2VydGlmaWNhdGUuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChUKSBjZXJ0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoZGVzaXJlZFJldHVyblR5cGUgPT0gQm9vbGVhbi5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpIEJvb2xlYW4uVFJVRTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGRlc2lyZWRSZXR1cm5UeXBlID09IEZpbGUuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChUKSBmaWxlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGhhc2goWDUwMFByaW5jaXBhbCBuYW1lKSB7CisgICAgICAgIGludCBoYXNoID0gTmF0aXZlQ3J5cHRvLlg1MDlfTkFNRV9oYXNoX29sZChuYW1lKTsKKyAgICAgICAgcmV0dXJuIEludGVncmFsVG9TdHJpbmcuaW50VG9IZXhTdHJpbmcoaGFzaCwgZmFsc2UsIDgpOworICAgIH0KKworICAgIHByaXZhdGUgRmlsZSBmaWxlKEZpbGUgZGlyLCBTdHJpbmcgaGFzaCwgaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiBuZXcgRmlsZShkaXIsIGhhc2ggKyAnLicgKyBpbmRleCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBub24te0Bjb2RlIEtleVN0b3JlU3BpfSBwdWJsaWMgaW50ZXJmYWNlIGlzIHVzZWQgYnkgdGhlCisgICAgICoge0Bjb2RlIEtleUNoYWluU2VydmljZX0gdG8gaW5zdGFsbCBuZXcgQ0EgY2VydGlmaWNhdGVzLiBJdAorICAgICAqIHNpbGVudGx5IGlnbm9yZXMgdGhlIGNlcnRpZmljYXRlIGlmIGl0IGFscmVhZHkgZXhpc3RzIGluIHRoZQorICAgICAqIHN0b3JlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGluc3RhbGxDZXJ0aWZpY2F0ZShYNTA5Q2VydGlmaWNhdGUgY2VydCkgdGhyb3dzIElPRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjZXJ0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiY2VydCA9PSBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgRmlsZSBzeXN0ZW0gPSBnZXRDZXJ0aWZpY2F0ZUZpbGUoc3lzdGVtRGlyLCBjZXJ0KTsKKyAgICAgICAgaWYgKHN5c3RlbS5leGlzdHMoKSkgeworICAgICAgICAgICAgRmlsZSBkZWxldGVkID0gZ2V0Q2VydGlmaWNhdGVGaWxlKGRlbGV0ZWREaXIsIGNlcnQpOworICAgICAgICAgICAgaWYgKGRlbGV0ZWQuZXhpc3RzKCkpIHsKKyAgICAgICAgICAgICAgICAvLyB3ZSBoYXZlIGEgc3lzdGVtIGNlcnQgdGhhdCB3YXMgbWFya2VkIGRlbGV0ZWQuCisgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBkZWxldGVkIG1hcmtlciB0byBleHBvc2UgdGhlIG9yaWdpbmFsCisgICAgICAgICAgICAgICAgaWYgKCFkZWxldGVkLmRlbGV0ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ291bGQgbm90IHJlbW92ZSAiICsgZGVsZXRlZCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIG90aGVyd2lzZSB3ZSBqdXN0IGhhdmUgYSBkdXAgb2YgYW4gZXhpc3Rpbmcgc3lzdGVtIGNlcnQuCisgICAgICAgICAgICAvLyByZXR1cm4gdGFraW5nIG5vIGZ1cnRoZXIgYWN0aW9uLgorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIEZpbGUgdXNlciA9IGdldENlcnRpZmljYXRlRmlsZShhZGRlZERpciwgY2VydCk7CisgICAgICAgIGlmICh1c2VyLmV4aXN0cygpKSB7CisgICAgICAgICAgICAvLyB3ZSBoYXZlIGFuIGFscmVhZHkgaW5zdGFsbGVkIHVzZXIgY2VydCwgYmFpbC4KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICAvLyBpbnN0YWxsIHRoZSB1c2VyIGNlcnQKKyAgICAgICAgd3JpdGVDZXJ0aWZpY2F0ZSh1c2VyLCBjZXJ0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNvdWxkIGJlIGNvbnNpZGVyZWQgdGhlIGltcGxlbWVudGF0aW9uIG9mIHtAY29kZQorICAgICAqIFRydXN0ZWRDZXJ0aWZpY2F0ZUtleVN0b3JlU3BpLmVuZ2luZURlbGV0ZUVudHJ5fSBidXQgd2UKKyAgICAgKiBjb25zaWRlciB7QGNvZGUgVHJ1c3RlZENlcnRpZmljYXRlS2V5U3RvcmVTcGl9IHRvIGJlIHJlYWQKKyAgICAgKiBvbmx5LiBJbnN0ZWFkLCB0aGlzIGlzIHVzZWQgYnkgdGhlIHtAY29kZSBLZXlDaGFpblNlcnZpY2V9IHRvCisgICAgICogZGVsZXRlIENBIGNlcnRpZmljYXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkZWxldGVDZXJ0aWZpY2F0ZUVudHJ5KFN0cmluZyBhbGlhcykgdGhyb3dzIElPRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhbGlhcyA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgRmlsZSBmaWxlID0gZmlsZUZvckFsaWFzKGFsaWFzKTsKKyAgICAgICAgaWYgKGZpbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGlmIChpc1N5c3RlbShhbGlhcykpIHsKKyAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0ID0gcmVhZENlcnRpZmljYXRlKGZpbGUpOworICAgICAgICAgICAgaWYgKGNlcnQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIHNraXAgcHJvYmxlbSBjZXJ0aWZpY2F0ZXMKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICBGaWxlIGRlbGV0ZWQgPSBnZXRDZXJ0aWZpY2F0ZUZpbGUoZGVsZXRlZERpciwgY2VydCk7CisgICAgICAgICAgICBpZiAoZGVsZXRlZC5leGlzdHMoKSkgeworICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgZGVsZXRlZCBzeXN0ZW0gY2VydGlmaWNhdGUKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyB3cml0ZSBjb3B5IG9mIHN5c3RlbSBjZXJ0IHRvIG1hcmtlZCBhcyBkZWxldGVkCisgICAgICAgICAgICB3cml0ZUNlcnRpZmljYXRlKGRlbGV0ZWQsIGNlcnQpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGlmIChpc1VzZXIoYWxpYXMpKSB7CisgICAgICAgICAgICAvLyB0cnVuY2F0ZSB0aGUgZmlsZSB0byBtYWtlIGEgdG9tYnN0b25lIGJ5IG9wZW5pbmcgYW5kIGNsb3NpbmcuCisgICAgICAgICAgICAvLyB3ZSBuZWVkIGVuc3VyZSB0aGF0IHdlIGRvbid0IGxlYXZlIGEgZ2FwIGJlZm9yZSBhIHZhbGlkIGNlcnQuCisgICAgICAgICAgICBuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlKS5jbG9zZSgpOworICAgICAgICAgICAgcmVtb3ZlVW5uZWNlc3NhcnlUb21ic3RvbmVzKGFsaWFzKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICAvLyBub24tZXhpc3RhbnQgdXNlciBjZXJ0LCBub3RoaW5nIHRvIGRlbGV0ZQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZW1vdmVVbm5lY2Vzc2FyeVRvbWJzdG9uZXMoU3RyaW5nIGFsaWFzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIWlzVXNlcihhbGlhcykpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihhbGlhcyk7CisgICAgICAgIH0KKyAgICAgICAgaW50IGRvdEluZGV4ID0gYWxpYXMubGFzdEluZGV4T2YoJy4nKTsKKyAgICAgICAgaWYgKGRvdEluZGV4ID09IC0xKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoYWxpYXMpOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGhhc2ggPSBhbGlhcy5zdWJzdHJpbmcoUFJFRklYX1VTRVIubGVuZ3RoKCksIGRvdEluZGV4KTsKKyAgICAgICAgaW50IGxhc3RUb21ic3RvbmVJbmRleCA9IEludGVnZXIucGFyc2VJbnQoYWxpYXMuc3Vic3RyaW5nKGRvdEluZGV4ICsgMSkpOworCisgICAgICAgIGlmIChmaWxlKGFkZGVkRGlyLCBoYXNoLCBsYXN0VG9tYnN0b25lSW5kZXggKyAxKS5leGlzdHMoKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHdoaWxlIChsYXN0VG9tYnN0b25lSW5kZXggPj0gMCkgeworICAgICAgICAgICAgRmlsZSBmaWxlID0gZmlsZShhZGRlZERpciwgaGFzaCwgbGFzdFRvbWJzdG9uZUluZGV4KTsKKyAgICAgICAgICAgIGlmICghaXNUb21ic3RvbmUoZmlsZSkpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghZmlsZS5kZWxldGUoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ291bGQgbm90IHJlbW92ZSAiICsgZmlsZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsYXN0VG9tYnN0b25lSW5kZXgtLTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9BdHRyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vQXR0ci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk0NDA0NTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vQXR0ci5qYXZhCkBAIC0wLDAgKzEsMjc1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKgorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCisgKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKKyAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0CisgKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKKyAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KKyAqCisgKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb207CisKKy8qKgorICogVGhlIDxjb2RlPkF0dHI8L2NvZGU+IGludGVyZmFjZSByZXByZXNlbnRzIGFuIGF0dHJpYnV0ZSBpbiBhbgorICogPGNvZGU+RWxlbWVudDwvY29kZT4gb2JqZWN0LiBUeXBpY2FsbHkgdGhlIGFsbG93YWJsZSB2YWx1ZXMgZm9yIHRoZQorICogYXR0cmlidXRlIGFyZSBkZWZpbmVkIGluIGEgc2NoZW1hIGFzc29jaWF0ZWQgd2l0aCB0aGUgZG9jdW1lbnQuCisgKiA8cD48Y29kZT5BdHRyPC9jb2RlPiBvYmplY3RzIGluaGVyaXQgdGhlIDxjb2RlPk5vZGU8L2NvZGU+IGludGVyZmFjZSwgYnV0CisgKiBzaW5jZSB0aGV5IGFyZSBub3QgYWN0dWFsbHkgY2hpbGQgbm9kZXMgb2YgdGhlIGVsZW1lbnQgdGhleSBkZXNjcmliZSwgdGhlCisgKiBET00gZG9lcyBub3QgY29uc2lkZXIgdGhlbSBwYXJ0IG9mIHRoZSBkb2N1bWVudCB0cmVlLiBUaHVzLCB0aGUKKyAqIDxjb2RlPk5vZGU8L2NvZGU+IGF0dHJpYnV0ZXMgPGNvZGU+cGFyZW50Tm9kZTwvY29kZT4sCisgKiA8Y29kZT5wcmV2aW91c1NpYmxpbmc8L2NvZGU+LCBhbmQgPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IGhhdmUgYQorICogPGNvZGU+bnVsbDwvY29kZT4gdmFsdWUgZm9yIDxjb2RlPkF0dHI8L2NvZGU+IG9iamVjdHMuIFRoZSBET00gdGFrZXMgdGhlCisgKiB2aWV3IHRoYXQgYXR0cmlidXRlcyBhcmUgcHJvcGVydGllcyBvZiBlbGVtZW50cyByYXRoZXIgdGhhbiBoYXZpbmcgYQorICogc2VwYXJhdGUgaWRlbnRpdHkgZnJvbSB0aGUgZWxlbWVudHMgdGhleSBhcmUgYXNzb2NpYXRlZCB3aXRoOyB0aGlzIHNob3VsZAorICogbWFrZSBpdCBtb3JlIGVmZmljaWVudCB0byBpbXBsZW1lbnQgc3VjaCBmZWF0dXJlcyBhcyBkZWZhdWx0IGF0dHJpYnV0ZXMKKyAqIGFzc29jaWF0ZWQgd2l0aCBhbGwgZWxlbWVudHMgb2YgYSBnaXZlbiB0eXBlLiBGdXJ0aGVybW9yZSwKKyAqIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzIG1heSBub3QgYmUgaW1tZWRpYXRlIGNoaWxkcmVuIG9mIGEKKyAqIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+LiBIb3dldmVyLCB0aGV5IGNhbiBiZSBhc3NvY2lhdGVkIHdpdGgKKyAqIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG5vZGVzIGNvbnRhaW5lZCB3aXRoaW4gYQorICogPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4uIEluIHNob3J0LCB1c2VycyBhbmQgaW1wbGVtZW50b3JzIG9mIHRoZQorICogRE9NIG5lZWQgdG8gYmUgYXdhcmUgdGhhdCA8Y29kZT5BdHRyPC9jb2RlPiBub2RlcyBoYXZlIHNvbWUgdGhpbmdzIGluCisgKiBjb21tb24gd2l0aCBvdGhlciBvYmplY3RzIGluaGVyaXRpbmcgdGhlIDxjb2RlPk5vZGU8L2NvZGU+IGludGVyZmFjZSwgYnV0CisgKiB0aGV5IGFsc28gYXJlIHF1aXRlIGRpc3RpbmN0LgorICogPHA+VGhlIGF0dHJpYnV0ZSdzIGVmZmVjdGl2ZSB2YWx1ZSBpcyBkZXRlcm1pbmVkIGFzIGZvbGxvd3M6IGlmIHRoaXMKKyAqIGF0dHJpYnV0ZSBoYXMgYmVlbiBleHBsaWNpdGx5IGFzc2lnbmVkIGFueSB2YWx1ZSwgdGhhdCB2YWx1ZSBpcyB0aGUKKyAqIGF0dHJpYnV0ZSdzIGVmZmVjdGl2ZSB2YWx1ZTsgb3RoZXJ3aXNlLCBpZiB0aGVyZSBpcyBhIGRlY2xhcmF0aW9uIGZvcgorICogdGhpcyBhdHRyaWJ1dGUsIGFuZCB0aGF0IGRlY2xhcmF0aW9uIGluY2x1ZGVzIGEgZGVmYXVsdCB2YWx1ZSwgdGhlbiB0aGF0CisgKiBkZWZhdWx0IHZhbHVlIGlzIHRoZSBhdHRyaWJ1dGUncyBlZmZlY3RpdmUgdmFsdWU7IG90aGVyd2lzZSwgdGhlCisgKiBhdHRyaWJ1dGUgZG9lcyBub3QgZXhpc3Qgb24gdGhpcyBlbGVtZW50IGluIHRoZSBzdHJ1Y3R1cmUgbW9kZWwgdW50aWwgaXQKKyAqIGhhcyBiZWVuIGV4cGxpY2l0bHkgYWRkZWQuIE5vdGUgdGhhdCB0aGUgPGNvZGU+Tm9kZS5ub2RlVmFsdWU8L2NvZGU+CisgKiBhdHRyaWJ1dGUgb24gdGhlIDxjb2RlPkF0dHI8L2NvZGU+IGluc3RhbmNlIGNhbiBhbHNvIGJlIHVzZWQgdG8gcmV0cmlldmUKKyAqIHRoZSBzdHJpbmcgdmVyc2lvbiBvZiB0aGUgYXR0cmlidXRlJ3MgdmFsdWUocykuCisgKiA8cD4gSWYgdGhlIGF0dHJpYnV0ZSB3YXMgbm90IGV4cGxpY2l0bHkgZ2l2ZW4gYSB2YWx1ZSBpbiB0aGUgaW5zdGFuY2UKKyAqIGRvY3VtZW50IGJ1dCBoYXMgYSBkZWZhdWx0IHZhbHVlIHByb3ZpZGVkIGJ5IHRoZSBzY2hlbWEgYXNzb2NpYXRlZCB3aXRoCisgKiB0aGUgZG9jdW1lbnQsIGFuIGF0dHJpYnV0ZSBub2RlIHdpbGwgYmUgY3JlYXRlZCB3aXRoCisgKiA8Y29kZT5zcGVjaWZpZWQ8L2NvZGU+IHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4uIFJlbW92aW5nIGF0dHJpYnV0ZQorICogbm9kZXMgZm9yIHdoaWNoIGEgZGVmYXVsdCB2YWx1ZSBpcyBkZWZpbmVkIGluIHRoZSBzY2hlbWEgZ2VuZXJhdGVzIGEgbmV3CisgKiBhdHRyaWJ1dGUgbm9kZSB3aXRoIHRoZSBkZWZhdWx0IHZhbHVlIGFuZCA8Y29kZT5zcGVjaWZpZWQ8L2NvZGU+IHNldCB0bworICogPGNvZGU+ZmFsc2U8L2NvZGU+LiBJZiB2YWxpZGF0aW9uIG9jY3VycmVkIHdoaWxlIGludm9raW5nCisgKiA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPiwgYXR0cmlidXRlIG5vZGVzIHdpdGgKKyAqIDxjb2RlPnNwZWNpZmllZDwvY29kZT4gZXF1YWxzIHRvIDxjb2RlPmZhbHNlPC9jb2RlPiBhcmUgcmVjb21wdXRlZAorICogYWNjb3JkaW5nIHRvIHRoZSBkZWZhdWx0IGF0dHJpYnV0ZSB2YWx1ZXMgcHJvdmlkZWQgYnkgdGhlIHNjaGVtYS4gSWYgbm8KKyAqIGRlZmF1bHQgdmFsdWUgaXMgYXNzb2NpYXRlIHdpdGggdGhpcyBhdHRyaWJ1dGUgaW4gdGhlIHNjaGVtYSwgdGhlCisgKiBhdHRyaWJ1dGUgbm9kZSBpcyBkaXNjYXJkZWQuCisgKiA8cD5JbiBYTUwsIHdoZXJlIHRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUgY2FuIGNvbnRhaW4gZW50aXR5IHJlZmVyZW5jZXMsCisgKiB0aGUgY2hpbGQgbm9kZXMgb2YgdGhlIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGUgbWF5IGJlIGVpdGhlcgorICogPGNvZGU+VGV4dDwvY29kZT4gb3IgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlcyAod2hlbiB0aGVzZSBhcmUKKyAqIGluIHVzZTsgc2VlIHRoZSBkZXNjcmlwdGlvbiBvZiA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IGZvcgorICogZGlzY3Vzc2lvbikuCisgKiA8cD5UaGUgRE9NIENvcmUgcmVwcmVzZW50cyBhbGwgYXR0cmlidXRlIHZhbHVlcyBhcyBzaW1wbGUgc3RyaW5ncywgZXZlbiBpZgorICogdGhlIERURCBvciBzY2hlbWEgYXNzb2NpYXRlZCB3aXRoIHRoZSBkb2N1bWVudCBkZWNsYXJlcyB0aGVtIG9mIHNvbWUKKyAqIHNwZWNpZmljIHR5cGUgc3VjaCBhcyB0b2tlbml6ZWQuCisgKiA8cD5UaGUgd2F5IGF0dHJpYnV0ZSB2YWx1ZSBub3JtYWxpemF0aW9uIGlzIHBlcmZvcm1lZCBieSB0aGUgRE9NCisgKiBpbXBsZW1lbnRhdGlvbiBkZXBlbmRzIG9uIGhvdyBtdWNoIHRoZSBpbXBsZW1lbnRhdGlvbiBrbm93cyBhYm91dCB0aGUKKyAqIHNjaGVtYSBpbiB1c2UuIFR5cGljYWxseSwgdGhlIDxjb2RlPnZhbHVlPC9jb2RlPiBhbmQKKyAqIDxjb2RlPm5vZGVWYWx1ZTwvY29kZT4gYXR0cmlidXRlcyBvZiBhbiA8Y29kZT5BdHRyPC9jb2RlPiBub2RlIGluaXRpYWxseQorICogcmV0dXJucyB0aGUgbm9ybWFsaXplZCB2YWx1ZSBnaXZlbiBieSB0aGUgcGFyc2VyLiBJdCBpcyBhbHNvIHRoZSBjYXNlCisgKiBhZnRlciA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPiBpcyBjYWxsZWQgKGFzc3VtaW5nIHRoZQorICogcmlnaHQgb3B0aW9ucyBoYXZlIGJlZW4gc2V0KS4gQnV0IHRoaXMgbWF5IG5vdCBiZSB0aGUgY2FzZSBhZnRlcgorICogbXV0YXRpb24sIGluZGVwZW5kZW50bHkgb2Ygd2hldGhlciB0aGUgbXV0YXRpb24gaXMgcGVyZm9ybWVkIGJ5IHNldHRpbmcKKyAqIHRoZSBzdHJpbmcgdmFsdWUgZGlyZWN0bHkgb3IgYnkgY2hhbmdpbmcgdGhlIDxjb2RlPkF0dHI8L2NvZGU+IGNoaWxkCisgKiBub2Rlcy4gSW4gcGFydGljdWxhciwgdGhpcyBpcyB0cnVlIHdoZW4gPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0I2R0LWNoYXJyZWYnPmNoYXJhY3RlcgorICogcmVmZXJlbmNlczwvYT4gYXJlIGludm9sdmVkLCBnaXZlbiB0aGF0IHRoZXkgYXJlIG5vdCByZXByZXNlbnRlZCBpbiB0aGUgRE9NIGFuZCB0aGV5CisgKiBpbXBhY3QgYXR0cmlidXRlIHZhbHVlIG5vcm1hbGl6YXRpb24uIE9uIHRoZSBvdGhlciBoYW5kLCBpZiB0aGUKKyAqIGltcGxlbWVudGF0aW9uIGtub3dzIGFib3V0IHRoZSBzY2hlbWEgaW4gdXNlIHdoZW4gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBpcworICogY2hhbmdlZCwgYW5kIGl0IGlzIG9mIGEgZGlmZmVyZW50IHR5cGUgdGhhbiBDREFUQSwgaXQgbWF5IG5vcm1hbGl6ZSBpdAorICogYWdhaW4gYXQgdGhhdCB0aW1lLiBUaGlzIGlzIGVzcGVjaWFsbHkgdHJ1ZSBvZiBzcGVjaWFsaXplZCBET00KKyAqIGltcGxlbWVudGF0aW9ucywgc3VjaCBhcyBTVkcgRE9NIGltcGxlbWVudGF0aW9ucywgd2hpY2ggc3RvcmUgYXR0cmlidXRlCisgKiB2YWx1ZXMgaW4gYW4gaW50ZXJuYWwgZm9ybSBkaWZmZXJlbnQgZnJvbSBhIHN0cmluZy4KKyAqIDxwPlRoZSBmb2xsb3dpbmcgdGFibGUgZ2l2ZXMgc29tZSBleGFtcGxlcyBvZiB0aGUgcmVsYXRpb25zIGJldHdlZW4gdGhlCisgKiBhdHRyaWJ1dGUgdmFsdWUgaW4gdGhlIG9yaWdpbmFsIGRvY3VtZW50IChwYXJzZWQgYXR0cmlidXRlKSwgdGhlIHZhbHVlIGFzCisgKiBleHBvc2VkIGluIHRoZSBET00sIGFuZCB0aGUgc2VyaWFsaXphdGlvbiBvZiB0aGUgdmFsdWU6CisgKiA8dGFibGUgYm9yZGVyPScxJyBjZWxscGFkZGluZz0nMyc+CisgKiA8dHI+CisgKiA8dGg+RXhhbXBsZXM8L3RoPgorICogPHRoPlBhcnNlZAorICogYXR0cmlidXRlIHZhbHVlPC90aD4KKyAqIDx0aD5Jbml0aWFsIDxjb2RlPkF0dHIudmFsdWU8L2NvZGU+PC90aD4KKyAqIDx0aD5TZXJpYWxpemVkIGF0dHJpYnV0ZSB2YWx1ZTwvdGg+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KKyAqIENoYXJhY3RlciByZWZlcmVuY2U8L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KKyAqIDxwcmU+IngmYW1wOyMxNzg7PTUiPC9wcmU+CisgKiA8L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KKyAqIDxwcmU+InhcdTAwYjI9NSI8L3ByZT4KKyAqIDwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICogPHByZT4ieCZhbXA7IzE3ODs9NSI8L3ByZT4KKyAqIDwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5CdWlsdC1pbgorICogY2hhcmFjdGVyIGVudGl0eTwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICogPHByZT4ieSZhbXA7bHQ7NiI8L3ByZT4KKyAqIDwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICogPHByZT4ieSZsdDs2IjwvcHJlPgorICogPC90ZD4KKyAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+CisgKiA8cHJlPiJ5JmFtcDtsdDs2IjwvcHJlPgorICogPC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPkxpdGVyYWwgbmV3bGluZSBiZXR3ZWVuPC90ZD4KKyAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+CisgKiA8cHJlPgorICogIng9NSZhbXA7IzEwO3k9NiI8L3ByZT4KKyAqIDwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICogPHByZT4ieD01IHk9NiI8L3ByZT4KKyAqIDwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICogPHByZT4ieD01JmFtcDsjMTA7eT02IjwvcHJlPgorICogPC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPk5vcm1hbGl6ZWQgbmV3bGluZSBiZXR3ZWVuPC90ZD4KKyAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+CisgKiA8cHJlPiJ4PTUKKyAqIHk9NiI8L3ByZT4KKyAqIDwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICogPHByZT4ieD01IHk9NiI8L3ByZT4KKyAqIDwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICogPHByZT4ieD01IHk9NiI8L3ByZT4KKyAqIDwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5FbnRpdHkgPGNvZGU+ZTwvY29kZT4gd2l0aCBsaXRlcmFsIG5ld2xpbmU8L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KKyAqIDxwcmU+CisgKiAmbHQ7IUVOVElUWSBlICcuLi4mYW1wOyMxMDsuLi4nJmd0OyBbLi4uXSZndDsgIng9NSZhbXA7ZTt5PTYiPC9wcmU+CisgKiA8L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48ZW0+RGVwZW5kZW50IG9uIEltcGxlbWVudGF0aW9uIGFuZCBMb2FkIE9wdGlvbnM8L2VtPjwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxlbT5EZXBlbmRlbnQgb24gSW1wbGVtZW50YXRpb24gYW5kIExvYWQvU2F2ZSBPcHRpb25zPC9lbT48L3RkPgorICogPC90cj4KKyAqIDwvdGFibGU+CisgKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBTcGVjaWZpY2F0aW9uPC9hPi4KKyAqLworcHVibGljIGludGVyZmFjZSBBdHRyIGV4dGVuZHMgTm9kZSB7CisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGlzIGF0dHJpYnV0ZS4gSWYgPGNvZGU+Tm9kZS5sb2NhbE5hbWU8L2NvZGU+IGlzCisgICAgICogZGlmZmVyZW50IGZyb20gPGNvZGU+bnVsbDwvY29kZT4sIHRoaXMgYXR0cmlidXRlIGlzIGEgcXVhbGlmaWVkIG5hbWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCk7CisKKyAgICAvKioKKyAgICAgKiAgPGNvZGU+VHJ1ZTwvY29kZT4gaWYgdGhpcyBhdHRyaWJ1dGUgd2FzIGV4cGxpY2l0bHkgZ2l2ZW4gYSB2YWx1ZSBpbgorICAgICAqIHRoZSBpbnN0YW5jZSBkb2N1bWVudCwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4gSWYgdGhlCisgICAgICogYXBwbGljYXRpb24gY2hhbmdlZCB0aGUgdmFsdWUgb2YgdGhpcyBhdHRyaWJ1dGUgbm9kZSAoZXZlbiBpZiBpdCBlbmRzCisgICAgICogdXAgaGF2aW5nIHRoZSBzYW1lIHZhbHVlIGFzIHRoZSBkZWZhdWx0IHZhbHVlKSB0aGVuIGl0IGlzIHNldCB0bworICAgICAqIDxjb2RlPnRydWU8L2NvZGU+LiBUaGUgaW1wbGVtZW50YXRpb24gbWF5IGhhbmRsZSBhdHRyaWJ1dGVzIHdpdGgKKyAgICAgKiBkZWZhdWx0IHZhbHVlcyBmcm9tIG90aGVyIHNjaGVtYXMgc2ltaWxhcmx5IGJ1dCBhcHBsaWNhdGlvbnMgc2hvdWxkCisgICAgICogdXNlIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk8L2NvZGU+IHRvIGd1YXJhbnRlZSB0aGlzCisgICAgICogaW5mb3JtYXRpb24gaXMgdXAtdG8tZGF0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRTcGVjaWZpZWQoKTsKKworICAgIC8qKgorICAgICAqIE9uIHJldHJpZXZhbCwgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgaXMgcmV0dXJuZWQgYXMgYSBzdHJpbmcuCisgICAgICogQ2hhcmFjdGVyIGFuZCBnZW5lcmFsIGVudGl0eSByZWZlcmVuY2VzIGFyZSByZXBsYWNlZCB3aXRoIHRoZWlyCisgICAgICogdmFsdWVzLiBTZWUgYWxzbyB0aGUgbWV0aG9kIDxjb2RlPmdldEF0dHJpYnV0ZTwvY29kZT4gb24gdGhlCisgICAgICogPGNvZGU+RWxlbWVudDwvY29kZT4gaW50ZXJmYWNlLgorICAgICAqIDxicj5PbiBzZXR0aW5nLCB0aGlzIGNyZWF0ZXMgYSA8Y29kZT5UZXh0PC9jb2RlPiBub2RlIHdpdGggdGhlIHVucGFyc2VkCisgICAgICogY29udGVudHMgb2YgdGhlIHN0cmluZywgaS5lLiBhbnkgY2hhcmFjdGVycyB0aGF0IGFuIFhNTCBwcm9jZXNzb3IKKyAgICAgKiB3b3VsZCByZWNvZ25pemUgYXMgbWFya3VwIGFyZSBpbnN0ZWFkIHRyZWF0ZWQgYXMgbGl0ZXJhbCB0ZXh0LiBTZWUKKyAgICAgKiBhbHNvIHRoZSBtZXRob2QgPGNvZGU+RWxlbWVudC5zZXRBdHRyaWJ1dGUoKTwvY29kZT4uCisgICAgICogPGJyPiBTb21lIHNwZWNpYWxpemVkIGltcGxlbWVudGF0aW9ucywgc3VjaCBhcyBzb21lIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAzL1JFQy1TVkcxMS0yMDAzMDExNC8nPlNWRyAxLjE8L2E+XQorICAgICAqIGltcGxlbWVudGF0aW9ucywgbWF5IGRvIG5vcm1hbGl6YXRpb24gYXV0b21hdGljYWxseSwgZXZlbiBhZnRlcgorICAgICAqIG11dGF0aW9uOyBpbiBzdWNoIGNhc2UsIHRoZSB2YWx1ZSBvbiByZXRyaWV2YWwgbWF5IGRpZmZlciBmcm9tIHRoZQorICAgICAqIHZhbHVlIG9uIHNldHRpbmcuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZSgpOworICAgIC8qKgorICAgICAqIE9uIHJldHJpZXZhbCwgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgaXMgcmV0dXJuZWQgYXMgYSBzdHJpbmcuCisgICAgICogQ2hhcmFjdGVyIGFuZCBnZW5lcmFsIGVudGl0eSByZWZlcmVuY2VzIGFyZSByZXBsYWNlZCB3aXRoIHRoZWlyCisgICAgICogdmFsdWVzLiBTZWUgYWxzbyB0aGUgbWV0aG9kIDxjb2RlPmdldEF0dHJpYnV0ZTwvY29kZT4gb24gdGhlCisgICAgICogPGNvZGU+RWxlbWVudDwvY29kZT4gaW50ZXJmYWNlLgorICAgICAqIDxicj5PbiBzZXR0aW5nLCB0aGlzIGNyZWF0ZXMgYSA8Y29kZT5UZXh0PC9jb2RlPiBub2RlIHdpdGggdGhlIHVucGFyc2VkCisgICAgICogY29udGVudHMgb2YgdGhlIHN0cmluZywgaS5lLiBhbnkgY2hhcmFjdGVycyB0aGF0IGFuIFhNTCBwcm9jZXNzb3IKKyAgICAgKiB3b3VsZCByZWNvZ25pemUgYXMgbWFya3VwIGFyZSBpbnN0ZWFkIHRyZWF0ZWQgYXMgbGl0ZXJhbCB0ZXh0LiBTZWUKKyAgICAgKiBhbHNvIHRoZSBtZXRob2QgPGNvZGU+RWxlbWVudC5zZXRBdHRyaWJ1dGUoKTwvY29kZT4uCisgICAgICogPGJyPiBTb21lIHNwZWNpYWxpemVkIGltcGxlbWVudGF0aW9ucywgc3VjaCBhcyBzb21lIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAzL1JFQy1TVkcxMS0yMDAzMDExNC8nPlNWRyAxLjE8L2E+XQorICAgICAqIGltcGxlbWVudGF0aW9ucywgbWF5IGRvIG5vcm1hbGl6YXRpb24gYXV0b21hdGljYWxseSwgZXZlbiBhZnRlcgorICAgICAqIG11dGF0aW9uOyBpbiBzdWNoIGNhc2UsIHRoZSB2YWx1ZSBvbiByZXRyaWV2YWwgbWF5IGRpZmZlciBmcm9tIHRoZQorICAgICAqIHZhbHVlIG9uIHNldHRpbmcuCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIHdoZW4gdGhlIG5vZGUgaXMgcmVhZG9ubHkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VmFsdWUoU3RyaW5nIHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBUaGUgPGNvZGU+RWxlbWVudDwvY29kZT4gbm9kZSB0aGlzIGF0dHJpYnV0ZSBpcyBhdHRhY2hlZCB0byBvcgorICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgYXR0cmlidXRlIGlzIG5vdCBpbiB1c2UuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAyCisgICAgICovCisgICAgcHVibGljIEVsZW1lbnQgZ2V0T3duZXJFbGVtZW50KCk7CisKKyAgICAvKioKKyAgICAgKiAgVGhlIHR5cGUgaW5mb3JtYXRpb24gYXNzb2NpYXRlZCB3aXRoIHRoaXMgYXR0cmlidXRlLiBXaGlsZSB0aGUgdHlwZQorICAgICAqIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBpbiB0aGlzIGF0dHJpYnV0ZSBpcyBndWFyYW50ZWUgdG8gYmUgY29ycmVjdAorICAgICAqIGFmdGVyIGxvYWRpbmcgdGhlIGRvY3VtZW50IG9yIGludm9raW5nCisgICAgICogPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4sIDxjb2RlPnNjaGVtYVR5cGVJbmZvPC9jb2RlPgorICAgICAqICBtYXkgbm90IGJlIHJlbGlhYmxlIGlmIHRoZSBub2RlIHdhcyBtb3ZlZC4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgVHlwZUluZm8gZ2V0U2NoZW1hVHlwZUluZm8oKTsKKworICAgIC8qKgorICAgICAqICBSZXR1cm5zIHdoZXRoZXIgdGhpcyBhdHRyaWJ1dGUgaXMga25vd24gdG8gYmUgb2YgdHlwZSBJRCAoaS5lLiB0bworICAgICAqIGNvbnRhaW4gYW4gaWRlbnRpZmllciBmb3IgaXRzIG93bmVyIGVsZW1lbnQpIG9yIG5vdC4gV2hlbiBpdCBpcyBhbmQKKyAgICAgKiBpdHMgdmFsdWUgaXMgdW5pcXVlLCB0aGUgPGNvZGU+b3duZXJFbGVtZW50PC9jb2RlPiBvZiB0aGlzIGF0dHJpYnV0ZQorICAgICAqIGNhbiBiZSByZXRyaWV2ZWQgdXNpbmcgdGhlIG1ldGhvZCA8Y29kZT5Eb2N1bWVudC5nZXRFbGVtZW50QnlJZDwvY29kZT4KKyAgICAgKiAuIFRoZSBpbXBsZW1lbnRhdGlvbiBjb3VsZCB1c2Ugc2V2ZXJhbCB3YXlzIHRvIGRldGVybWluZSBpZiBhbgorICAgICAqIGF0dHJpYnV0ZSBub2RlIGlzIGtub3duIHRvIGNvbnRhaW4gYW4gaWRlbnRpZmllcjoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPiBJZiB2YWxpZGF0aW9uCisgICAgICogb2NjdXJyZWQgdXNpbmcgYW4gWE1MIFNjaGVtYSBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvJz5YTUwgU2NoZW1hIFBhcnQgMTwvYT5dCisgICAgICogIHdoaWxlIGxvYWRpbmcgdGhlIGRvY3VtZW50IG9yIHdoaWxlIGludm9raW5nCisgICAgICogPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4sIHRoZSBwb3N0LXNjaGVtYS12YWxpZGF0aW9uCisgICAgICogaW5mb3NldCBjb250cmlidXRpb25zIChQU1ZJIGNvbnRyaWJ1dGlvbnMpIHZhbHVlcyBhcmUgdXNlZCB0bworICAgICAqIGRldGVybWluZSBpZiB0aGlzIGF0dHJpYnV0ZSBpcyBhIHNjaGVtYS1kZXRlcm1pbmVkIElEIGF0dHJpYnV0ZSB1c2luZworICAgICAqIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAzL1JFQy14cHRyLWZyYW1ld29yay0yMDAzMDMyNS8jdGVybS1zZGknPgorICAgICAqIHNjaGVtYS1kZXRlcm1pbmVkIElEPC9hPiBkZWZpbml0aW9uIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAzL1JFQy14cHRyLWZyYW1ld29yay0yMDAzMDMyNS8nPlhQb2ludGVyPC9hPl0KKyAgICAgKiAuCisgICAgICogPC9saT4KKyAgICAgKiA8bGk+IElmIHZhbGlkYXRpb24gb2NjdXJyZWQgdXNpbmcgYSBEVEQgd2hpbGUgbG9hZGluZyB0aGUgZG9jdW1lbnQgb3IKKyAgICAgKiB3aGlsZSBpbnZva2luZyA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPiwgdGhlIGluZm9zZXQgPGI+W3R5cGUgZGVmaW5pdGlvbl08L2I+IHZhbHVlIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIGlmIHRoaXMgYXR0cmlidXRlIGlzIGEgRFRELWRldGVybWluZWQgSUQKKyAgICAgKiBhdHRyaWJ1dGUgdXNpbmcgdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvUkVDLXhwdHItZnJhbWV3b3JrLTIwMDMwMzI1LyN0ZXJtLWRkaSc+CisgICAgICogRFRELWRldGVybWluZWQgSUQ8L2E+IGRlZmluaXRpb24gaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvUkVDLXhwdHItZnJhbWV3b3JrLTIwMDMwMzI1Lyc+WFBvaW50ZXI8L2E+XQorICAgICAqIC4KKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT4gZnJvbSB0aGUgdXNlIG9mIHRoZSBtZXRob2RzIDxjb2RlPkVsZW1lbnQuc2V0SWRBdHRyaWJ1dGUoKTwvY29kZT4sCisgICAgICogPGNvZGU+RWxlbWVudC5zZXRJZEF0dHJpYnV0ZU5TKCk8L2NvZGU+LCBvcgorICAgICAqIDxjb2RlPkVsZW1lbnQuc2V0SWRBdHRyaWJ1dGVOb2RlKCk8L2NvZGU+LCBpLmUuIGl0IGlzIGFuCisgICAgICogdXNlci1kZXRlcm1pbmVkIElEIGF0dHJpYnV0ZTsKKyAgICAgKiA8cCA+PGI+Tm90ZTo8L2I+ICBYUG9pbnRlciBmcmFtZXdvcmsgKHNlZSBzZWN0aW9uIDMuMiBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9SRUMteHB0ci1mcmFtZXdvcmstMjAwMzAzMjUvJz5YUG9pbnRlcjwvYT5dCisgICAgICogKSBjb25zaWRlciB0aGUgRE9NIHVzZXItZGV0ZXJtaW5lZCBJRCBhdHRyaWJ1dGUgYXMgYmVpbmcgcGFydCBvZiB0aGUKKyAgICAgKiBYUG9pbnRlciBleHRlcm5hbGx5LWRldGVybWluZWQgSUQgZGVmaW5pdGlvbi4KKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT4gdXNpbmcgbWVjaGFuaXNtcyB0aGF0CisgICAgICogYXJlIG91dHNpZGUgdGhlIHNjb3BlIG9mIHRoaXMgc3BlY2lmaWNhdGlvbiwgaXQgaXMgdGhlbiBhbgorICAgICAqIGV4dGVybmFsbHktZGV0ZXJtaW5lZCBJRCBhdHRyaWJ1dGUuIFRoaXMgaW5jbHVkZXMgdXNpbmcgc2NoZW1hCisgICAgICogbGFuZ3VhZ2VzIGRpZmZlcmVudCBmcm9tIFhNTCBzY2hlbWEgYW5kIERURC4KKyAgICAgKiA8L2xpPgorICAgICAqIDwvdWw+CisgICAgICogPGJyPiBJZiB2YWxpZGF0aW9uIG9jY3VycmVkIHdoaWxlIGludm9raW5nCisgICAgICogPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4sIGFsbCB1c2VyLWRldGVybWluZWQgSUQKKyAgICAgKiBhdHRyaWJ1dGVzIGFyZSByZXNldCBhbmQgYWxsIGF0dHJpYnV0ZSBub2RlcyBJRCBpbmZvcm1hdGlvbiBhcmUgdGhlbgorICAgICAqIHJlZXZhbHVhdGVkIGluIGFjY29yZGFuY2UgdG8gdGhlIHNjaGVtYSB1c2VkLiBBcyBhIGNvbnNlcXVlbmNlLCBpZgorICAgICAqIHRoZSA8Y29kZT5BdHRyLnNjaGVtYVR5cGVJbmZvPC9jb2RlPiBhdHRyaWJ1dGUgY29udGFpbnMgYW4gSUQgdHlwZSwKKyAgICAgKiA8Y29kZT5pc0lkPC9jb2RlPiB3aWxsIGFsd2F5cyByZXR1cm4gdHJ1ZS4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0lkKCk7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9DREFUQVNlY3Rpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9DREFUQVNlY3Rpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZTRiMzQ2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0NEQVRBU2VjdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKKyAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcworICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKKyAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAorICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgorICoKKyAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbTsKKworLyoqCisgKiBDREFUQSBzZWN0aW9ucyBhcmUgdXNlZCB0byBlc2NhcGUgYmxvY2tzIG9mIHRleHQgY29udGFpbmluZyBjaGFyYWN0ZXJzIHRoYXQKKyAqIHdvdWxkIG90aGVyd2lzZSBiZSByZWdhcmRlZCBhcyBtYXJrdXAuIFRoZSBvbmx5IGRlbGltaXRlciB0aGF0IGlzCisgKiByZWNvZ25pemVkIGluIGEgQ0RBVEEgc2VjdGlvbiBpcyB0aGUgIl1dJmd0OyIgc3RyaW5nIHRoYXQgZW5kcyB0aGUgQ0RBVEEKKyAqIHNlY3Rpb24uIENEQVRBIHNlY3Rpb25zIGNhbm5vdCBiZSBuZXN0ZWQuIFRoZWlyIHByaW1hcnkgcHVycG9zZSBpcyBmb3IKKyAqIGluY2x1ZGluZyBtYXRlcmlhbCBzdWNoIGFzIFhNTCBmcmFnbWVudHMsIHdpdGhvdXQgbmVlZGluZyB0byBlc2NhcGUgYWxsCisgKiB0aGUgZGVsaW1pdGVycy4KKyAqIDxwPlRoZSA8Y29kZT5DaGFyYWN0ZXJEYXRhLmRhdGE8L2NvZGU+IGF0dHJpYnV0ZSBob2xkcyB0aGUgdGV4dCB0aGF0IGlzCisgKiBjb250YWluZWQgYnkgdGhlIENEQVRBIHNlY3Rpb24uIE5vdGUgdGhhdCB0aGlzIDxlbT5tYXk8L2VtPiBjb250YWluIGNoYXJhY3RlcnMgdGhhdCBuZWVkIHRvIGJlIGVzY2FwZWQgb3V0c2lkZSBvZiBDREFUQSBzZWN0aW9ucyBhbmQKKyAqIHRoYXQsIGRlcGVuZGluZyBvbiB0aGUgY2hhcmFjdGVyIGVuY29kaW5nICgiY2hhcnNldCIpIGNob3NlbiBmb3IKKyAqIHNlcmlhbGl6YXRpb24sIGl0IG1heSBiZSBpbXBvc3NpYmxlIHRvIHdyaXRlIG91dCBzb21lIGNoYXJhY3RlcnMgYXMgcGFydAorICogb2YgYSBDREFUQSBzZWN0aW9uLgorICogPHA+VGhlIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gaW50ZXJmYWNlIGluaGVyaXRzIGZyb20gdGhlCisgKiA8Y29kZT5DaGFyYWN0ZXJEYXRhPC9jb2RlPiBpbnRlcmZhY2UgdGhyb3VnaCB0aGUgPGNvZGU+VGV4dDwvY29kZT4KKyAqIGludGVyZmFjZS4gQWRqYWNlbnQgPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPiBub2RlcyBhcmUgbm90IG1lcmdlZCBieSB1c2UKKyAqIG9mIHRoZSA8Y29kZT5ub3JtYWxpemU8L2NvZGU+IG1ldGhvZCBvZiB0aGUgPGNvZGU+Tm9kZTwvY29kZT4gaW50ZXJmYWNlLgorICogPHA+IE5vIGxleGljYWwgY2hlY2sgaXMgZG9uZSBvbiB0aGUgY29udGVudCBvZiBhIENEQVRBIHNlY3Rpb24gYW5kIGl0IGlzCisgKiB0aGVyZWZvcmUgcG9zc2libGUgdG8gaGF2ZSB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIDxjb2RlPiJdXSZndDsiPC9jb2RlPgorICogaW4gdGhlIGNvbnRlbnQsIHdoaWNoIGlzIGlsbGVnYWwgaW4gYSBDREFUQSBzZWN0aW9uIHBlciBzZWN0aW9uIDIuNyBvZiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0uIFRoZQorICogcHJlc2VuY2Ugb2YgdGhpcyBjaGFyYWN0ZXIgc2VxdWVuY2UgbXVzdCBnZW5lcmF0ZSBhIGZhdGFsIGVycm9yIGR1cmluZworICogc2VyaWFsaXphdGlvbiBvciB0aGUgY2RhdGEgc2VjdGlvbiBtdXN0IGJlIHNwbGl0dGVkIGJlZm9yZSB0aGUKKyAqIHNlcmlhbGl6YXRpb24gKHNlZSBhbHNvIHRoZSBwYXJhbWV0ZXIgPGNvZGU+InNwbGl0LWNkYXRhLXNlY3Rpb25zIjwvY29kZT4KKyAqIGluIHRoZSA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBpbnRlcmZhY2UpLgorICogPHAgPjxiPk5vdGU6PC9iPiBCZWNhdXNlIG5vIG1hcmt1cCBpcyByZWNvZ25pemVkIHdpdGhpbiBhCisgKiA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+LCBjaGFyYWN0ZXIgbnVtZXJpYyByZWZlcmVuY2VzIGNhbm5vdCBiZSB1c2VkIGFzCisgKiBhbiBlc2NhcGUgbWVjaGFuaXNtIHdoZW4gc2VyaWFsaXppbmcuIFRoZXJlZm9yZSwgYWN0aW9uIG5lZWRzIHRvIGJlIHRha2VuCisgKiB3aGVuIHNlcmlhbGl6aW5nIGEgPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPiB3aXRoIGEgY2hhcmFjdGVyIGVuY29kaW5nCisgKiB3aGVyZSBzb21lIG9mIHRoZSBjb250YWluZWQgY2hhcmFjdGVycyBjYW5ub3QgYmUgcmVwcmVzZW50ZWQuIEZhaWx1cmUgdG8KKyAqIGRvIHNvIHdvdWxkIG5vdCBwcm9kdWNlIHdlbGwtZm9ybWVkIFhNTC4KKyAqIDxwID48Yj5Ob3RlOjwvYj4gT25lIHBvdGVudGlhbCBzb2x1dGlvbiBpbiB0aGUgc2VyaWFsaXphdGlvbiBwcm9jZXNzIGlzIHRvCisgKiBlbmQgdGhlIENEQVRBIHNlY3Rpb24gYmVmb3JlIHRoZSBjaGFyYWN0ZXIsIG91dHB1dCB0aGUgY2hhcmFjdGVyIHVzaW5nIGEKKyAqIGNoYXJhY3RlciByZWZlcmVuY2Ugb3IgZW50aXR5IHJlZmVyZW5jZSwgYW5kIG9wZW4gYSBuZXcgQ0RBVEEgc2VjdGlvbiBmb3IKKyAqIGFueSBmdXJ0aGVyIGNoYXJhY3RlcnMgaW4gdGhlIHRleHQgbm9kZS4gTm90ZSwgaG93ZXZlciwgdGhhdCBzb21lIGNvZGUKKyAqIGNvbnZlcnNpb24gbGlicmFyaWVzIGF0IHRoZSB0aW1lIG9mIHdyaXRpbmcgZG8gbm90IHJldHVybiBhbiBlcnJvciBvcgorICogZXhjZXB0aW9uIHdoZW4gYSBjaGFyYWN0ZXIgaXMgbWlzc2luZyBmcm9tIHRoZSBlbmNvZGluZywgbWFraW5nIHRoZSB0YXNrCisgKiBvZiBlbnN1cmluZyB0aGF0IGRhdGEgaXMgbm90IGNvcnJ1cHRlZCBvbiBzZXJpYWxpemF0aW9uIG1vcmUgZGlmZmljdWx0LgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQ0RBVEFTZWN0aW9uIGV4dGVuZHMgVGV4dCB7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vQ2hhcmFjdGVyRGF0YS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0NoYXJhY3RlckRhdGEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zN2FhOGRmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0NoYXJhY3RlckRhdGEuamF2YQpAQCAtMCwwICsxLDE1MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICoKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgorICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCisgKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAorICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCisgKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisgKgorICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tOworCisvKioKKyAqIFRoZSA8Y29kZT5DaGFyYWN0ZXJEYXRhPC9jb2RlPiBpbnRlcmZhY2UgZXh0ZW5kcyBOb2RlIHdpdGggYSBzZXQgb2YKKyAqIGF0dHJpYnV0ZXMgYW5kIG1ldGhvZHMgZm9yIGFjY2Vzc2luZyBjaGFyYWN0ZXIgZGF0YSBpbiB0aGUgRE9NLiBGb3IKKyAqIGNsYXJpdHkgdGhpcyBzZXQgaXMgZGVmaW5lZCBoZXJlIHJhdGhlciB0aGFuIG9uIGVhY2ggb2JqZWN0IHRoYXQgdXNlcworICogdGhlc2UgYXR0cmlidXRlcyBhbmQgbWV0aG9kcy4gTm8gRE9NIG9iamVjdHMgY29ycmVzcG9uZCBkaXJlY3RseSB0bworICogPGNvZGU+Q2hhcmFjdGVyRGF0YTwvY29kZT4sIHRob3VnaCA8Y29kZT5UZXh0PC9jb2RlPiBhbmQgb3RoZXJzIGRvCisgKiBpbmhlcml0IHRoZSBpbnRlcmZhY2UgZnJvbSBpdC4gQWxsIDxjb2RlPm9mZnNldHM8L2NvZGU+IGluIHRoaXMgaW50ZXJmYWNlCisgKiBzdGFydCBmcm9tIDxjb2RlPjA8L2NvZGU+LgorICogPHA+QXMgZXhwbGFpbmVkIGluIHRoZSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IGludGVyZmFjZSwgdGV4dCBzdHJpbmdzIGluCisgKiB0aGUgRE9NIGFyZSByZXByZXNlbnRlZCBpbiBVVEYtMTYsIGkuZS4gYXMgYSBzZXF1ZW5jZSBvZiAxNi1iaXQgdW5pdHMuIEluCisgKiB0aGUgZm9sbG93aW5nLCB0aGUgdGVybSAxNi1iaXQgdW5pdHMgaXMgdXNlZCB3aGVuZXZlciBuZWNlc3NhcnkgdG8KKyAqIGluZGljYXRlIHRoYXQgaW5kZXhpbmcgb24gQ2hhcmFjdGVyRGF0YSBpcyBkb25lIGluIDE2LWJpdCB1bml0cy4KKyAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgorICovCitwdWJsaWMgaW50ZXJmYWNlIENoYXJhY3RlckRhdGEgZXh0ZW5kcyBOb2RlIHsKKyAgICAvKioKKyAgICAgKiBUaGUgY2hhcmFjdGVyIGRhdGEgb2YgdGhlIG5vZGUgdGhhdCBpbXBsZW1lbnRzIHRoaXMgaW50ZXJmYWNlLiBUaGUgRE9NCisgICAgICogaW1wbGVtZW50YXRpb24gbWF5IG5vdCBwdXQgYXJiaXRyYXJ5IGxpbWl0cyBvbiB0aGUgYW1vdW50IG9mIGRhdGEKKyAgICAgKiB0aGF0IG1heSBiZSBzdG9yZWQgaW4gYSA8Y29kZT5DaGFyYWN0ZXJEYXRhPC9jb2RlPiBub2RlLiBIb3dldmVyLAorICAgICAqIGltcGxlbWVudGF0aW9uIGxpbWl0cyBtYXkgbWVhbiB0aGF0IHRoZSBlbnRpcmV0eSBvZiBhIG5vZGUncyBkYXRhIG1heQorICAgICAqIG5vdCBmaXQgaW50byBhIHNpbmdsZSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+LiBJbiBzdWNoIGNhc2VzLCB0aGUgdXNlcgorICAgICAqIG1heSBjYWxsIDxjb2RlPnN1YnN0cmluZ0RhdGE8L2NvZGU+IHRvIHJldHJpZXZlIHRoZSBkYXRhIGluCisgICAgICogYXBwcm9wcmlhdGVseSBzaXplZCBwaWVjZXMuCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIERPTVNUUklOR19TSVpFX0VSUjogUmFpc2VkIHdoZW4gaXQgd291bGQgcmV0dXJuIG1vcmUgY2hhcmFjdGVycyB0aGFuCisgICAgICogICBmaXQgaW4gYSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IHZhcmlhYmxlIG9uIHRoZSBpbXBsZW1lbnRhdGlvbgorICAgICAqICAgcGxhdGZvcm0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXREYXRhKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworICAgIC8qKgorICAgICAqIFRoZSBjaGFyYWN0ZXIgZGF0YSBvZiB0aGUgbm9kZSB0aGF0IGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UuIFRoZSBET00KKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBtYXkgbm90IHB1dCBhcmJpdHJhcnkgbGltaXRzIG9uIHRoZSBhbW91bnQgb2YgZGF0YQorICAgICAqIHRoYXQgbWF5IGJlIHN0b3JlZCBpbiBhIDxjb2RlPkNoYXJhY3RlckRhdGE8L2NvZGU+IG5vZGUuIEhvd2V2ZXIsCisgICAgICogaW1wbGVtZW50YXRpb24gbGltaXRzIG1heSBtZWFuIHRoYXQgdGhlIGVudGlyZXR5IG9mIGEgbm9kZSdzIGRhdGEgbWF5CisgICAgICogbm90IGZpdCBpbnRvIGEgc2luZ2xlIDxjb2RlPkRPTVN0cmluZzwvY29kZT4uIEluIHN1Y2ggY2FzZXMsIHRoZSB1c2VyCisgICAgICogbWF5IGNhbGwgPGNvZGU+c3Vic3RyaW5nRGF0YTwvY29kZT4gdG8gcmV0cmlldmUgdGhlIGRhdGEgaW4KKyAgICAgKiBhcHByb3ByaWF0ZWx5IHNpemVkIHBpZWNlcy4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgd2hlbiB0aGUgbm9kZSBpcyByZWFkb25seS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREYXRhKFN0cmluZyBkYXRhKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtYmVyIG9mIDE2LWJpdCB1bml0cyB0aGF0IGFyZSBhdmFpbGFibGUgdGhyb3VnaCA8Y29kZT5kYXRhPC9jb2RlPgorICAgICAqIGFuZCB0aGUgPGNvZGU+c3Vic3RyaW5nRGF0YTwvY29kZT4gbWV0aG9kIGJlbG93LiBUaGlzIG1heSBoYXZlIHRoZQorICAgICAqIHZhbHVlIHplcm8sIGkuZS4sIDxjb2RlPkNoYXJhY3RlckRhdGE8L2NvZGU+IG5vZGVzIG1heSBiZSBlbXB0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOworCisgICAgLyoqCisgICAgICogRXh0cmFjdHMgYSByYW5nZSBvZiBkYXRhIGZyb20gdGhlIG5vZGUuCisgICAgICogQHBhcmFtIG9mZnNldCBTdGFydCBvZmZzZXQgb2Ygc3Vic3RyaW5nIHRvIGV4dHJhY3QuCisgICAgICogQHBhcmFtIGNvdW50IFRoZSBudW1iZXIgb2YgMTYtYml0IHVuaXRzIHRvIGV4dHJhY3QuCisgICAgICogQHJldHVybiBUaGUgc3BlY2lmaWVkIHN1YnN0cmluZy4gSWYgdGhlIHN1bSBvZiA8Y29kZT5vZmZzZXQ8L2NvZGU+IGFuZAorICAgICAqICAgPGNvZGU+Y291bnQ8L2NvZGU+IGV4Y2VlZHMgdGhlIDxjb2RlPmxlbmd0aDwvY29kZT4sIHRoZW4gYWxsIDE2LWJpdAorICAgICAqICAgdW5pdHMgdG8gdGhlIGVuZCBvZiB0aGUgZGF0YSBhcmUgcmV0dXJuZWQuCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCA8Y29kZT5vZmZzZXQ8L2NvZGU+IGlzCisgICAgICogICBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiAxNi1iaXQgdW5pdHMgaW4KKyAgICAgKiAgIDxjb2RlPmRhdGE8L2NvZGU+LCBvciBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPmNvdW50PC9jb2RlPiBpcworICAgICAqICAgbmVnYXRpdmUuCisgICAgICogICA8YnI+RE9NU1RSSU5HX1NJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCByYW5nZSBvZiB0ZXh0IGRvZXMKKyAgICAgKiAgIG5vdCBmaXQgaW50byBhIDxjb2RlPkRPTVN0cmluZzwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBzdWJzdHJpbmdEYXRhKGludCBvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb3VudCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEFwcGVuZCB0aGUgc3RyaW5nIHRvIHRoZSBlbmQgb2YgdGhlIGNoYXJhY3RlciBkYXRhIG9mIHRoZSBub2RlLiBVcG9uCisgICAgICogc3VjY2VzcywgPGNvZGU+ZGF0YTwvY29kZT4gcHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBjb25jYXRlbmF0aW9uIG9mCisgICAgICogPGNvZGU+ZGF0YTwvY29kZT4gYW5kIHRoZSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IHNwZWNpZmllZC4KKyAgICAgKiBAcGFyYW0gYXJnIFRoZSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IHRvIGFwcGVuZC4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFwcGVuZERhdGEoU3RyaW5nIGFyZykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnQgYSBzdHJpbmcgYXQgdGhlIHNwZWNpZmllZCAxNi1iaXQgdW5pdCBvZmZzZXQuCisgICAgICogQHBhcmFtIG9mZnNldCBUaGUgY2hhcmFjdGVyIG9mZnNldCBhdCB3aGljaCB0byBpbnNlcnQuCisgICAgICogQHBhcmFtIGFyZyBUaGUgPGNvZGU+RE9NU3RyaW5nPC9jb2RlPiB0byBpbnNlcnQuCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCA8Y29kZT5vZmZzZXQ8L2NvZGU+IGlzCisgICAgICogICBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiAxNi1iaXQgdW5pdHMgaW4KKyAgICAgKiAgIDxjb2RlPmRhdGE8L2NvZGU+LgorICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBpbnNlcnREYXRhKGludCBvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXJnKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlbW92ZSBhIHJhbmdlIG9mIDE2LWJpdCB1bml0cyBmcm9tIHRoZSBub2RlLiBVcG9uIHN1Y2Nlc3MsCisgICAgICogPGNvZGU+ZGF0YTwvY29kZT4gYW5kIDxjb2RlPmxlbmd0aDwvY29kZT4gcmVmbGVjdCB0aGUgY2hhbmdlLgorICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIG9mZnNldCBmcm9tIHdoaWNoIHRvIHN0YXJ0IHJlbW92aW5nLgorICAgICAqIEBwYXJhbSBjb3VudCBUaGUgbnVtYmVyIG9mIDE2LWJpdCB1bml0cyB0byBkZWxldGUuIElmIHRoZSBzdW0gb2YKKyAgICAgKiAgIDxjb2RlPm9mZnNldDwvY29kZT4gYW5kIDxjb2RlPmNvdW50PC9jb2RlPiBleGNlZWRzCisgICAgICogICA8Y29kZT5sZW5ndGg8L2NvZGU+IHRoZW4gYWxsIDE2LWJpdCB1bml0cyBmcm9tIDxjb2RlPm9mZnNldDwvY29kZT4KKyAgICAgKiAgIHRvIHRoZSBlbmQgb2YgdGhlIGRhdGEgYXJlIGRlbGV0ZWQuCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCA8Y29kZT5vZmZzZXQ8L2NvZGU+IGlzCisgICAgICogICBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiAxNi1iaXQgdW5pdHMgaW4KKyAgICAgKiAgIDxjb2RlPmRhdGE8L2NvZGU+LCBvciBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPmNvdW50PC9jb2RlPiBpcworICAgICAqICAgbmVnYXRpdmUuCisgICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRlbGV0ZURhdGEoaW50IG9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb3VudCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlIHRoZSBjaGFyYWN0ZXJzIHN0YXJ0aW5nIGF0IHRoZSBzcGVjaWZpZWQgMTYtYml0IHVuaXQgb2Zmc2V0CisgICAgICogd2l0aCB0aGUgc3BlY2lmaWVkIHN0cmluZy4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBvZmZzZXQgZnJvbSB3aGljaCB0byBzdGFydCByZXBsYWNpbmcuCisgICAgICogQHBhcmFtIGNvdW50IFRoZSBudW1iZXIgb2YgMTYtYml0IHVuaXRzIHRvIHJlcGxhY2UuIElmIHRoZSBzdW0gb2YKKyAgICAgKiAgIDxjb2RlPm9mZnNldDwvY29kZT4gYW5kIDxjb2RlPmNvdW50PC9jb2RlPiBleGNlZWRzCisgICAgICogICA8Y29kZT5sZW5ndGg8L2NvZGU+LCB0aGVuIGFsbCAxNi1iaXQgdW5pdHMgdG8gdGhlIGVuZCBvZiB0aGUgZGF0YQorICAgICAqICAgYXJlIHJlcGxhY2VkOyAoaS5lLiwgdGhlIGVmZmVjdCBpcyB0aGUgc2FtZSBhcyBhIDxjb2RlPnJlbW92ZTwvY29kZT4KKyAgICAgKiAgICBtZXRob2QgY2FsbCB3aXRoIHRoZSBzYW1lIHJhbmdlLCBmb2xsb3dlZCBieSBhbiA8Y29kZT5hcHBlbmQ8L2NvZGU+CisgICAgICogICAgbWV0aG9kIGludm9jYXRpb24pLgorICAgICAqIEBwYXJhbSBhcmcgVGhlIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gd2l0aCB3aGljaCB0aGUgcmFuZ2UgbXVzdCBiZQorICAgICAqICAgcmVwbGFjZWQuCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCA8Y29kZT5vZmZzZXQ8L2NvZGU+IGlzCisgICAgICogICBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiAxNi1iaXQgdW5pdHMgaW4KKyAgICAgKiAgIDxjb2RlPmRhdGE8L2NvZGU+LCBvciBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPmNvdW50PC9jb2RlPiBpcworICAgICAqICAgbmVnYXRpdmUuCisgICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlcGxhY2VEYXRhKGludCBvZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhcmcpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0NvbW1lbnQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9Db21tZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDBiNzUyNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9Db21tZW50LmphdmEKQEAgLTAsMCArMSwzMCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICoKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgorICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCisgKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAorICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCisgKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisgKgorICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tOworCisvKioKKyAqIFRoaXMgaW50ZXJmYWNlIGluaGVyaXRzIGZyb20gPGNvZGU+Q2hhcmFjdGVyRGF0YTwvY29kZT4gYW5kIHJlcHJlc2VudHMgdGhlCisgKiBjb250ZW50IG9mIGEgY29tbWVudCwgaS5lLiwgYWxsIHRoZSBjaGFyYWN0ZXJzIGJldHdlZW4gdGhlIHN0YXJ0aW5nICcKKyAqIDxjb2RlPiZsdDshLS08L2NvZGU+JyBhbmQgZW5kaW5nICc8Y29kZT4tLSZndDs8L2NvZGU+Jy4gTm90ZSB0aGF0IHRoaXMgaXMKKyAqIHRoZSBkZWZpbml0aW9uIG9mIGEgY29tbWVudCBpbiBYTUwsIGFuZCwgaW4gcHJhY3RpY2UsIEhUTUwsIGFsdGhvdWdoIHNvbWUKKyAqIEhUTUwgdG9vbHMgbWF5IGltcGxlbWVudCB0aGUgZnVsbCBTR01MIGNvbW1lbnQgc3RydWN0dXJlLgorICogPHA+IE5vIGxleGljYWwgY2hlY2sgaXMgZG9uZSBvbiB0aGUgY29udGVudCBvZiBhIGNvbW1lbnQgYW5kIGl0IGlzCisgKiB0aGVyZWZvcmUgcG9zc2libGUgdG8gaGF2ZSB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIDxjb2RlPiItLSI8L2NvZGU+CisgKiAoZG91YmxlLWh5cGhlbikgaW4gdGhlIGNvbnRlbnQsIHdoaWNoIGlzIGlsbGVnYWwgaW4gYSBjb21tZW50IHBlciBzZWN0aW9uCisgKiAyLjUgb2YgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dLiBUaGUKKyAqIHByZXNlbmNlIG9mIHRoaXMgY2hhcmFjdGVyIHNlcXVlbmNlIG11c3QgZ2VuZXJhdGUgYSBmYXRhbCBlcnJvciBkdXJpbmcKKyAqIHNlcmlhbGl6YXRpb24uCisgKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBTcGVjaWZpY2F0aW9uPC9hPi4KKyAqLworcHVibGljIGludGVyZmFjZSBDb21tZW50IGV4dGVuZHMgQ2hhcmFjdGVyRGF0YSB7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vRE9NQ29uZmlndXJhdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0RPTUNvbmZpZ3VyYXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMDUyNTc4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0RPTUNvbmZpZ3VyYXRpb24uamF2YQpAQCAtMCwwICsxLDQxMyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICoKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgorICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCisgKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAorICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCisgKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisgKgorICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tOworCisvKioKKyAqICBUaGUgPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gaW50ZXJmYWNlIHJlcHJlc2VudHMgdGhlIGNvbmZpZ3VyYXRpb24KKyAqIG9mIGEgZG9jdW1lbnQgYW5kIG1haW50YWlucyBhIHRhYmxlIG9mIHJlY29nbml6ZWQgcGFyYW1ldGVycy4gVXNpbmcgdGhlCisgKiBjb25maWd1cmF0aW9uLCBpdCBpcyBwb3NzaWJsZSB0byBjaGFuZ2UKKyAqIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk8L2NvZGU+IGJlaGF2aW9yLCBzdWNoIGFzIHJlcGxhY2luZyB0aGUKKyAqIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gbm9kZXMgd2l0aCA8Y29kZT5UZXh0PC9jb2RlPiBub2RlcyBvcgorICogc3BlY2lmeWluZyB0aGUgdHlwZSBvZiB0aGUgc2NoZW1hIHRoYXQgbXVzdCBiZSB1c2VkIHdoZW4gdGhlIHZhbGlkYXRpb24KKyAqIG9mIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gaXMgcmVxdWVzdGVkLiA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPgorICogb2JqZWN0cyBhcmUgYWxzbyB1c2VkIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1MUy0yMDA0MDQwNyc+RE9NIExldmVsIDMgTG9hZCBhbmQgU2F2ZTwvYT5dCisgKiAgaW4gdGhlIDxjb2RlPkRPTVBhcnNlcjwvY29kZT4gYW5kIDxjb2RlPkRPTVNlcmlhbGl6ZXI8L2NvZGU+IGludGVyZmFjZXMuCisgKiA8cD4gVGhlIHBhcmFtZXRlciBuYW1lcyB1c2VkIGJ5IHRoZSA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBvYmplY3QKKyAqIGFyZSBkZWZpbmVkIHRocm91Z2hvdXQgdGhlIERPTSBMZXZlbCAzIHNwZWNpZmljYXRpb25zLiBOYW1lcyBhcmUKKyAqIGNhc2UtaW5zZW5zaXRpdmUuIFRvIGF2b2lkIHBvc3NpYmxlIGNvbmZsaWN0cywgYXMgYSBjb252ZW50aW9uLCBuYW1lcworICogcmVmZXJyaW5nIHRvIHBhcmFtZXRlcnMgZGVmaW5lZCBvdXRzaWRlIHRoZSBET00gc3BlY2lmaWNhdGlvbiBzaG91bGQgYmUKKyAqIG1hZGUgdW5pcXVlLiBCZWNhdXNlIHBhcmFtZXRlcnMgYXJlIGV4cG9zZWQgYXMgcHJvcGVydGllcyBpbiB0aGUgLCBuYW1lcworICogYXJlIHJlY29tbWVuZGVkIHRvIGZvbGxvdyB0aGUgc2VjdGlvbiA1LjE2IElkZW50aWZpZXJzIG9mIFtVbmljb2RlXSB3aXRoIHRoZSBhZGRpdGlvbiBvZiB0aGUgY2hhcmFjdGVyICctJyAoSFlQSEVOLU1JTlVTKSBidXQgaXQgaXMgbm90CisgKiBlbmZvcmNlZCBieSB0aGUgRE9NIGltcGxlbWVudGF0aW9uLiBET00gTGV2ZWwgMyBDb3JlIEltcGxlbWVudGF0aW9ucyBhcmUKKyAqIHJlcXVpcmVkIHRvIHJlY29nbml6ZSBhbGwgcGFyYW1ldGVycyBkZWZpbmVkIGluIHRoaXMgc3BlY2lmaWNhdGlvbi4gU29tZQorICogcGFyYW1ldGVyIHZhbHVlcyBtYXkgYWxzbyBiZSByZXF1aXJlZCB0byBiZSBzdXBwb3J0ZWQgYnkgdGhlCisgKiBpbXBsZW1lbnRhdGlvbi4gUmVmZXIgdG8gdGhlIGRlZmluaXRpb24gb2YgdGhlIHBhcmFtZXRlciB0byBrbm93IGlmIGEKKyAqIHZhbHVlIG11c3QgYmUgc3VwcG9ydGVkIG9yIG5vdC4KKyAqIDxwID48Yj5Ob3RlOjwvYj4gIFBhcmFtZXRlcnMgYXJlIHNpbWlsYXIgdG8gZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgdXNlZCBpbgorICogU0FYMiBbPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZy8nPlNBWDwvYT5dLgorICogPHA+IFRoZSBmb2xsb3dpbmcgbGlzdCBvZiBwYXJhbWV0ZXJzIGRlZmluZWQgaW4gdGhlIERPTToKKyAqIDxkbD4KKyAqIDxkdD4KKyAqIDxjb2RlPiJjYW5vbmljYWwtZm9ybSI8L2NvZGU+PC9kdD4KKyAqIDxkZD4KKyAqIDxkbD4KKyAqIDxkdD48Y29kZT50cnVlPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+WzxlbT5vcHRpb25hbDwvZW0+XSBDYW5vbmljYWxpemUgdGhlIGRvY3VtZW50IGFjY29yZGluZyB0byB0aGUgcnVsZXMgc3BlY2lmaWVkIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy14bWwtYzE0bi0yMDAxMDMxNSc+Q2Fub25pY2FsIFhNTDwvYT5dLAorICogc3VjaCBhcyByZW1vdmluZyB0aGUgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBub2RlIChpZiBhbnkpIGZyb20gdGhlCisgKiB0cmVlLCBvciByZW1vdmluZyBzdXBlcmZsdW91cyBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIGZyb20gZWFjaCBlbGVtZW50LgorICogTm90ZSB0aGF0IHRoaXMgaXMgbGltaXRlZCB0byB3aGF0IGNhbiBiZSByZXByZXNlbnRlZCBpbiB0aGUgRE9NOyBpbgorICogcGFydGljdWxhciwgdGhlcmUgaXMgbm8gd2F5IHRvIHNwZWNpZnkgdGhlIG9yZGVyIG9mIHRoZSBhdHRyaWJ1dGVzIGluIHRoZQorICogRE9NLiBJbiBhZGRpdGlvbiwgIFNldHRpbmcgdGhpcyBwYXJhbWV0ZXIgdG8gPGNvZGU+dHJ1ZTwvY29kZT4gd2lsbCBhbHNvCisgKiBzZXQgdGhlIHN0YXRlIG9mIHRoZSBwYXJhbWV0ZXJzIGxpc3RlZCBiZWxvdy4gTGF0ZXIgY2hhbmdlcyB0byB0aGUgc3RhdGUKKyAqIG9mIG9uZSBvZiB0aG9zZSBwYXJhbWV0ZXJzIHdpbGwgcmV2ZXJ0ICJjYW5vbmljYWwtZm9ybSIgYmFjayB0bworICogPGNvZGU+ZmFsc2U8L2NvZGU+LiBQYXJhbWV0ZXJzIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT46ICJlbnRpdGllcyIsICIKKyAqIG5vcm1hbGl6ZS1jaGFyYWN0ZXJzIiwgImNkYXRhLXNlY3Rpb25zIi4gUGFyYW1ldGVycyBzZXQgdG8KKyAqIDxjb2RlPnRydWU8L2NvZGU+OiAibmFtZXNwYWNlcyIsICJuYW1lc3BhY2UtZGVjbGFyYXRpb25zIiwgIndlbGwtZm9ybWVkIiwKKyAqICJlbGVtZW50LWNvbnRlbnQtd2hpdGVzcGFjZSIuIE90aGVyIHBhcmFtZXRlcnMgYXJlIG5vdCBjaGFuZ2VkIHVubGVzcworICogZXhwbGljaXRseSBzcGVjaWZpZWQgaW4gdGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBwYXJhbWV0ZXJzLjwvZGQ+CisgKiA8ZHQ+CisgKiA8Y29kZT5mYWxzZTwvY29kZT48L2R0PgorICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pRG8gbm90IGNhbm9uaWNhbGl6ZSB0aGUgZG9jdW1lbnQuPC9kZD4KKyAqIDwvZGw+PC9kZD4KKyAqIDxkdD48Y29kZT4iY2RhdGEtc2VjdGlvbnMiPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+CisgKiA8ZGw+CisgKiA8ZHQ+CisgKiA8Y29kZT50cnVlPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPilLZWVwIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gbm9kZXMgaW4gdGhlIGRvY3VtZW50LjwvZGQ+CisgKiA8ZHQ+PGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KKyAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dVHJhbnNmb3JtIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gbm9kZXMgaW4gdGhlIGRvY3VtZW50IGludG8KKyAqIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGVzLiBUaGUgbmV3IDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUgaXMgdGhlbiBjb21iaW5lZAorICogd2l0aCBhbnkgYWRqYWNlbnQgPGNvZGU+VGV4dDwvY29kZT4gbm9kZS48L2RkPgorICogPC9kbD48L2RkPgorICogPGR0PgorICogPGNvZGU+ImNoZWNrLWNoYXJhY3Rlci1ub3JtYWxpemF0aW9uIjwvY29kZT48L2R0PgorICogPGRkPgorICogPGRsPgorICogPGR0Pjxjb2RlPnRydWU8L2NvZGU+PC9kdD4KKyAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dIENoZWNrIGlmIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBkb2N1bWVudCBhcmUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sMTEtMjAwNDAyMDQvI2R0LWZ1bGxub3JtJz5mdWxseQorICogbm9ybWFsaXplZDwvYT4sIGFzIGRlZmluZWQgaW4gYXBwZW5kaXggQiBvZiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sMTEtMjAwNDAyMDQvJz5YTUwgMS4xPC9hPl0uIFdoZW4gYQorICogc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyBpcyBlbmNvdW50ZXJlZCB0aGF0IGZhaWxzIG5vcm1hbGl6YXRpb24gY2hlY2tpbmcsCisgKiBhbiBlcnJvciB3aXRoIHRoZSA8Y29kZT5ET01FcnJvci50eXBlPC9jb2RlPiBlcXVhbHMgdG8KKyAqICJjaGVjay1jaGFyYWN0ZXItbm9ybWFsaXphdGlvbi1mYWlsdXJlIiBpcyBpc3N1ZWQuIDwvZGQ+CisgKiA8ZHQ+PGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KKyAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dICg8ZW0+ZGVmYXVsdDwvZW0+KURvIG5vdCBjaGVjayBpZiBjaGFyYWN0ZXJzIGFyZSBub3JtYWxpemVkLjwvZGQ+CisgKiA8L2RsPjwvZGQ+CisgKiA8ZHQ+PGNvZGU+ImNvbW1lbnRzIjwvY29kZT48L2R0PgorICogPGRkPgorICogPGRsPgorICogPGR0PgorICogPGNvZGU+dHJ1ZTwvY29kZT48L2R0PgorICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pS2VlcCA8Y29kZT5Db21tZW50PC9jb2RlPiBub2RlcyBpbiB0aGUgZG9jdW1lbnQuPC9kZD4KKyAqIDxkdD48Y29kZT5mYWxzZTwvY29kZT48L2R0PgorICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl1EaXNjYXJkIDxjb2RlPkNvbW1lbnQ8L2NvZGU+IG5vZGVzIGluIHRoZSBkb2N1bWVudC48L2RkPgorICogPC9kbD48L2RkPgorICogPGR0PgorICogPGNvZGU+ImRhdGF0eXBlLW5vcm1hbGl6YXRpb24iPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+CisgKiA8ZGw+CisgKiA8ZHQ+PGNvZGU+dHJ1ZTwvY29kZT48L2R0PgorICogPGRkPls8ZW0+b3B0aW9uYWw8L2VtPl0gRXhwb3NlIHNjaGVtYSBub3JtYWxpemVkIHZhbHVlcyBpbiB0aGUgdHJlZSwgc3VjaCBhcyA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy14bWxzY2hlbWEtMS0yMDAxMDUwMi8ja2V5LW52Jz5YTUwKKyAqIFNjaGVtYSBub3JtYWxpemVkIHZhbHVlczwvYT4gaW4gdGhlIGNhc2Ugb2YgWE1MIFNjaGVtYS4gU2luY2UgdGhpcyBwYXJhbWV0ZXIgcmVxdWlyZXMgdG8gaGF2ZSBzY2hlbWEKKyAqIGluZm9ybWF0aW9uLCB0aGUgInZhbGlkYXRlIiBwYXJhbWV0ZXIgd2lsbCBhbHNvIGJlIHNldCB0bworICogPGNvZGU+dHJ1ZTwvY29kZT4uIEhhdmluZyB0aGlzIHBhcmFtZXRlciBhY3RpdmF0ZWQgd2hlbiAidmFsaWRhdGUiIGlzCisgKiA8Y29kZT5mYWxzZTwvY29kZT4gaGFzIG5vIGVmZmVjdCBhbmQgbm8gc2NoZW1hLW5vcm1hbGl6YXRpb24gd2lsbCBoYXBwZW4uCisgKiA8cCA+PGI+Tm90ZTo8L2I+ICBTaW5jZSB0aGUgZG9jdW1lbnQgY29udGFpbnMgdGhlIHJlc3VsdCBvZiB0aGUgWE1MIDEuMAorICogcHJvY2Vzc2luZywgdGhpcyBwYXJhbWV0ZXIgZG9lcyBub3QgYXBwbHkgdG8gYXR0cmlidXRlIHZhbHVlCisgKiBub3JtYWxpemF0aW9uIGFzIGRlZmluZWQgaW4gc2VjdGlvbiAzLjMuMyBvZiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0gYW5kIGlzIG9ubHkKKyAqIG1lYW50IGZvciBzY2hlbWEgbGFuZ3VhZ2VzIG90aGVyIHRoYW4gRG9jdW1lbnQgVHlwZSBEZWZpbml0aW9uIChEVEQpLiA8L2RkPgorICogPGR0PgorICogPGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KKyAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dICg8ZW0+ZGVmYXVsdDwvZW0+KSBEbyBub3QgcGVyZm9ybSBzY2hlbWEgbm9ybWFsaXphdGlvbiBvbiB0aGUgdHJlZS4gPC9kZD4KKyAqIDwvZGw+PC9kZD4KKyAqIDxkdD4KKyAqIDxjb2RlPiJlbGVtZW50LWNvbnRlbnQtd2hpdGVzcGFjZSI8L2NvZGU+PC9kdD4KKyAqIDxkZD4KKyAqIDxkbD4KKyAqIDxkdD48Y29kZT50cnVlPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPilLZWVwIGFsbCB3aGl0ZXNwYWNlcyBpbiB0aGUgZG9jdW1lbnQuPC9kZD4KKyAqIDxkdD48Y29kZT5mYWxzZTwvY29kZT48L2R0PgorICogPGRkPls8ZW0+b3B0aW9uYWw8L2VtPl0gRGlzY2FyZCBhbGwgPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMgdGhhdCBjb250YWluIHdoaXRlc3BhY2VzIGluIGVsZW1lbnQKKyAqIGNvbnRlbnQsIGFzIGRlc2NyaWJlZCBpbiA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtaW5mb3NldC0yMDA0MDIwNCNpbmZvaXRlbS5jaGFyYWN0ZXInPgorICogW2VsZW1lbnQgY29udGVudCB3aGl0ZXNwYWNlXTwvYT4uIFRoZSBpbXBsZW1lbnRhdGlvbiBpcyBleHBlY3RlZCB0byB1c2UgdGhlIGF0dHJpYnV0ZQorICogPGNvZGU+VGV4dC5pc0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZTwvY29kZT4gdG8gZGV0ZXJtaW5lIGlmIGEKKyAqIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUgc2hvdWxkIGJlIGRpc2NhcmRlZCBvciBub3QuPC9kZD4KKyAqIDwvZGw+PC9kZD4KKyAqIDxkdD48Y29kZT4iZW50aXRpZXMiPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+CisgKiA8ZGw+CisgKiA8ZHQ+CisgKiA8Y29kZT50cnVlPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPilLZWVwIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZXMgaW4gdGhlIGRvY3VtZW50LjwvZGQ+CisgKiA8ZHQ+CisgKiA8Y29kZT5mYWxzZTwvY29kZT48L2R0PgorICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gUmVtb3ZlIGFsbCA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IG5vZGVzIGZyb20gdGhlIGRvY3VtZW50LAorICogcHV0dGluZyB0aGUgZW50aXR5IGV4cGFuc2lvbnMgZGlyZWN0bHkgaW4gdGhlaXIgcGxhY2UuIDxjb2RlPlRleHQ8L2NvZGU+CisgKiBub2RlcyBhcmUgbm9ybWFsaXplZCwgYXMgZGVmaW5lZCBpbiA8Y29kZT5Ob2RlLm5vcm1hbGl6ZTwvY29kZT4uIE9ubHkgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLWluZm9zZXQtMjAwNDAyMDQvI2luZm9pdGVtLnJzZSc+CisgKiB1bmV4cGFuZGVkIGVudGl0eSByZWZlcmVuY2VzPC9hPiBhcmUga2VwdCBpbiB0aGUgZG9jdW1lbnQuIDwvZGQ+CisgKiA8L2RsPgorICogPHAgPjxiPk5vdGU6PC9iPiAgVGhpcyBwYXJhbWV0ZXIgZG9lcyBub3QgYWZmZWN0IDxjb2RlPkVudGl0eTwvY29kZT4gbm9kZXMuIDwvZGQ+CisgKiA8ZHQ+CisgKiA8Y29kZT4iZXJyb3ItaGFuZGxlciI8L2NvZGU+PC9kdD4KKyAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dIENvbnRhaW5zIGEgPGNvZGU+RE9NRXJyb3JIYW5kbGVyPC9jb2RlPiBvYmplY3QuIElmIGFuIGVycm9yIGlzCisgKiBlbmNvdW50ZXJlZCBpbiB0aGUgZG9jdW1lbnQsIHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsIGNhbGwgYmFjayB0aGUKKyAqIDxjb2RlPkRPTUVycm9ySGFuZGxlcjwvY29kZT4gcmVnaXN0ZXJlZCB1c2luZyB0aGlzIHBhcmFtZXRlci4gVGhlCisgKiBpbXBsZW1lbnRhdGlvbiBtYXkgcHJvdmlkZSBhIGRlZmF1bHQgPGNvZGU+RE9NRXJyb3JIYW5kbGVyPC9jb2RlPiBvYmplY3QuCisgKiAgV2hlbiBjYWxsZWQsIDxjb2RlPkRPTUVycm9yLnJlbGF0ZWREYXRhPC9jb2RlPiB3aWxsIGNvbnRhaW4gdGhlIGNsb3Nlc3QKKyAqIG5vZGUgdG8gd2hlcmUgdGhlIGVycm9yIG9jY3VycmVkLiBJZiB0aGUgaW1wbGVtZW50YXRpb24gaXMgdW5hYmxlIHRvCisgKiBkZXRlcm1pbmUgdGhlIG5vZGUgd2hlcmUgdGhlIGVycm9yIG9jY3VycywKKyAqIDxjb2RlPkRPTUVycm9yLnJlbGF0ZWREYXRhPC9jb2RlPiB3aWxsIGNvbnRhaW4gdGhlIDxjb2RlPkRvY3VtZW50PC9jb2RlPgorICogbm9kZS4gTXV0YXRpb25zIHRvIHRoZSBkb2N1bWVudCBmcm9tIHdpdGhpbiBhbiBlcnJvciBoYW5kbGVyIHdpbGwgcmVzdWx0CisgKiBpbiBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQgYmVoYXZpb3IuIDwvZGQ+CisgKiA8ZHQ+PGNvZGU+ImluZm9zZXQiPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+CisgKiA8ZGw+CisgKiA8ZHQ+CisgKiA8Y29kZT50cnVlPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XUtlZXAgaW4gdGhlIGRvY3VtZW50IHRoZSBpbmZvcm1hdGlvbiBkZWZpbmVkIGluIHRoZSBYTUwgSW5mb3JtYXRpb24gU2V0IFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtaW5mb3NldC0yMDA0MDIwNC8nPlhNTCBJbmZvcm1hdGlvbiBTZXQ8L2E+XQorICogLlRoaXMgZm9yY2VzIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVycyB0byA8Y29kZT5mYWxzZTwvY29kZT46ICIKKyAqIHZhbGlkYXRlLWlmLXNjaGVtYSIsICJlbnRpdGllcyIsICJkYXRhdHlwZS1ub3JtYWxpemF0aW9uIiwgImNkYXRhLXNlY3Rpb25zCisgKiAiLlRoaXMgZm9yY2VzIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVycyB0byA8Y29kZT50cnVlPC9jb2RlPjogIgorICogbmFtZXNwYWNlLWRlY2xhcmF0aW9ucyIsICJ3ZWxsLWZvcm1lZCIsICJlbGVtZW50LWNvbnRlbnQtd2hpdGVzcGFjZSIsICIKKyAqIGNvbW1lbnRzIiwgIm5hbWVzcGFjZXMiLk90aGVyIHBhcmFtZXRlcnMgYXJlIG5vdCBjaGFuZ2VkIHVubGVzcworICogZXhwbGljaXRseSBzcGVjaWZpZWQgaW4gdGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBwYXJhbWV0ZXJzLiBOb3RlIHRoYXQKKyAqIHF1ZXJ5aW5nIHRoaXMgcGFyYW1ldGVyIHdpdGggPGNvZGU+Z2V0UGFyYW1ldGVyPC9jb2RlPiByZXR1cm5zCisgKiA8Y29kZT50cnVlPC9jb2RlPiBvbmx5IGlmIHRoZSBpbmRpdmlkdWFsIHBhcmFtZXRlcnMgc3BlY2lmaWVkIGFib3ZlIGFyZQorICogYXBwcm9wcmlhdGVseSBzZXQuPC9kZD4KKyAqIDxkdD48Y29kZT5mYWxzZTwvY29kZT48L2R0PgorICogPGRkPlNldHRpbmcgPGNvZGU+aW5mb3NldDwvY29kZT4gdG8KKyAqIDxjb2RlPmZhbHNlPC9jb2RlPiBoYXMgbm8gZWZmZWN0LjwvZGQ+CisgKiA8L2RsPjwvZGQ+CisgKiA8ZHQ+PGNvZGU+Im5hbWVzcGFjZXMiPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+CisgKiA8ZGw+CisgKiA8ZHQ+CisgKiA8Y29kZT50cnVlPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPikgUGVyZm9ybSB0aGUgbmFtZXNwYWNlIHByb2Nlc3NpbmcgYXMgZGVmaW5lZCBpbiAuIDwvZGQ+CisgKiA8ZHQ+PGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KKyAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dIERvIG5vdCBwZXJmb3JtIHRoZSBuYW1lc3BhY2UgcHJvY2Vzc2luZy4gPC9kZD4KKyAqIDwvZGw+PC9kZD4KKyAqIDxkdD4KKyAqIDxjb2RlPiJuYW1lc3BhY2UtZGVjbGFyYXRpb25zIjwvY29kZT48L2R0PgorICogPGRkPiBUaGlzIHBhcmFtZXRlciBoYXMgbm8gZWZmZWN0IGlmIHRoZQorICogcGFyYW1ldGVyICJuYW1lc3BhY2VzIiBpcyBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LgorICogPGRsPgorICogPGR0Pjxjb2RlPnRydWU8L2NvZGU+PC9kdD4KKyAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dICg8ZW0+ZGVmYXVsdDwvZW0+KSBJbmNsdWRlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBhdHRyaWJ1dGVzLCBzcGVjaWZpZWQgb3IgZGVmYXVsdGVkIGZyb20KKyAqIHRoZSBzY2hlbWEsIGluIHRoZSBkb2N1bWVudC4gU2VlIGFsc28gdGhlIHNlY3Rpb25zICJEZWNsYXJpbmcgTmFtZXNwYWNlcyIKKyAqIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14bWwtbmFtZXMtMTk5OTAxMTQvJz5YTUwgTmFtZXNwYWNlczwvYT5dCisgKiAgYW5kIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtbmFtZXMxMS0yMDA0MDIwNC8nPlhNTCBOYW1lc3BhY2VzIDEuMTwvYT5dCisgKiAuPC9kZD4KKyAqIDxkdD48Y29kZT5mYWxzZTwvY29kZT48L2R0PgorICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl1EaXNjYXJkIGFsbCBuYW1lc3BhY2UgZGVjbGFyYXRpb24gYXR0cmlidXRlcy4gVGhlIG5hbWVzcGFjZSBwcmVmaXhlcyAoCisgKiA8Y29kZT5Ob2RlLnByZWZpeDwvY29kZT4pIGFyZSByZXRhaW5lZCBldmVuIGlmIHRoaXMgcGFyYW1ldGVyIGlzIHNldCB0bworICogPGNvZGU+ZmFsc2U8L2NvZGU+LjwvZGQ+CisgKiA8L2RsPjwvZGQ+CisgKiA8ZHQ+PGNvZGU+Im5vcm1hbGl6ZS1jaGFyYWN0ZXJzIjwvY29kZT48L2R0PgorICogPGRkPgorICogPGRsPgorICogPGR0Pjxjb2RlPnRydWU8L2NvZGU+PC9kdD4KKyAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0LyNkdC1mdWxsbm9ybSc+RnVsbHkKKyAqIG5vcm1hbGl6ZWQ8L2E+IHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBkb2N1bWVudCBhcyBkZWZpbmVkIGluIGFwcGVuZGl4IEIgb2YgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0Lyc+WE1MIDEuMTwvYT5dLiA8L2RkPgorICogPGR0PgorICogPGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KKyAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dICg8ZW0+ZGVmYXVsdDwvZW0+KURvIG5vdCBwZXJmb3JtIGNoYXJhY3RlciBub3JtYWxpemF0aW9uLjwvZGQ+CisgKiA8L2RsPjwvZGQ+CisgKiA8ZHQ+PGNvZGU+InNjaGVtYS1sb2NhdGlvbiI8L2NvZGU+PC9kdD4KKyAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dIFJlcHJlc2VudCBhIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gb2JqZWN0IGNvbnRhaW5pbmcgYSBsaXN0IG9mIFVSSXMsCisgKiBzZXBhcmF0ZWQgYnkgd2hpdGVzcGFjZXMgKGNoYXJhY3RlcnMgbWF0Y2hpbmcgdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCNOVC1TJz5ub250ZXJtaW5hbAorICogcHJvZHVjdGlvbiBTPC9hPiBkZWZpbmVkIGluIHNlY3Rpb24gMi4zIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XSksIHRoYXQKKyAqIHJlcHJlc2VudHMgdGhlIHNjaGVtYXMgYWdhaW5zdCB3aGljaCB2YWxpZGF0aW9uIHNob3VsZCBvY2N1ciwgaS5lLiB0aGUKKyAqIGN1cnJlbnQgc2NoZW1hLiBUaGUgdHlwZXMgb2Ygc2NoZW1hcyByZWZlcmVuY2VkIGluIHRoaXMgbGlzdCBtdXN0IG1hdGNoCisgKiB0aGUgdHlwZSBzcGVjaWZpZWQgd2l0aCA8Y29kZT5zY2hlbWEtdHlwZTwvY29kZT4sIG90aGVyd2lzZSB0aGUgYmVoYXZpb3IKKyAqIG9mIGFuIGltcGxlbWVudGF0aW9uIGlzIHVuZGVmaW5lZC4gIFRoZSBzY2hlbWFzIHNwZWNpZmllZCB1c2luZyB0aGlzCisgKiBwcm9wZXJ0eSB0YWtlIHByZWNlZGVuY2UgdG8gdGhlIHNjaGVtYSBpbmZvcm1hdGlvbiBzcGVjaWZpZWQgaW4gdGhlCisgKiBkb2N1bWVudCBpdHNlbGYuIEZvciBuYW1lc3BhY2UgYXdhcmUgc2NoZW1hLCBpZiBhIHNjaGVtYSBzcGVjaWZpZWQgdXNpbmcKKyAqIHRoaXMgcHJvcGVydHkgYW5kIGEgc2NoZW1hIHNwZWNpZmllZCBpbiB0aGUgZG9jdW1lbnQgaW5zdGFuY2UgKGkuZS4gdXNpbmcKKyAqIHRoZSA8Y29kZT5zY2hlbWFMb2NhdGlvbjwvY29kZT4gYXR0cmlidXRlKSBpbiBhIHNjaGVtYSBkb2N1bWVudCAoaS5lLgorICogdXNpbmcgc2NoZW1hIDxjb2RlPmltcG9ydDwvY29kZT4gbWVjaGFuaXNtcykgc2hhcmUgdGhlIHNhbWUKKyAqIDxjb2RlPnRhcmdldE5hbWVzcGFjZTwvY29kZT4sIHRoZSBzY2hlbWEgc3BlY2lmaWVkIGJ5IHRoZSB1c2VyIHVzaW5nIHRoaXMKKyAqIHByb3BlcnR5IHdpbGwgYmUgdXNlZC4gSWYgdHdvIHNjaGVtYXMgc3BlY2lmaWVkIHVzaW5nIHRoaXMgcHJvcGVydHkgc2hhcmUKKyAqIHRoZSBzYW1lIDxjb2RlPnRhcmdldE5hbWVzcGFjZTwvY29kZT4gb3IgaGF2ZSBubyBuYW1lc3BhY2UsIHRoZSBiZWhhdmlvcgorICogaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LiAgSWYgbm8gbG9jYXRpb24gaGFzIGJlZW4gcHJvdmlkZWQsIHRoaXMKKyAqIHBhcmFtZXRlciBpcyA8Y29kZT5udWxsPC9jb2RlPi4KKyAqIDxwID48Yj5Ob3RlOjwvYj4gIFRoZSA8Y29kZT4ic2NoZW1hLWxvY2F0aW9uIjwvY29kZT4gcGFyYW1ldGVyIGlzIGlnbm9yZWQKKyAqIHVubGVzcyB0aGUgInNjaGVtYS10eXBlIiBwYXJhbWV0ZXIgdmFsdWUgaXMgc2V0LiBJdCBpcyBzdHJvbmdseQorICogcmVjb21tZW5kZWQgdGhhdCA8Y29kZT5Eb2N1bWVudC5kb2N1bWVudFVSSTwvY29kZT4gd2lsbCBiZSBzZXQgc28gdGhhdCBhbgorICogaW1wbGVtZW50YXRpb24gY2FuIHN1Y2Nlc3NmdWxseSByZXNvbHZlIGFueSBleHRlcm5hbCBlbnRpdGllcyByZWZlcmVuY2VkLiA8L2RkPgorICogPGR0PgorICogPGNvZGU+InNjaGVtYS10eXBlIjwvY29kZT48L2R0PgorICogPGRkPls8ZW0+b3B0aW9uYWw8L2VtPl0gUmVwcmVzZW50IGEgPGNvZGU+RE9NU3RyaW5nPC9jb2RlPiBvYmplY3QgY29udGFpbmluZyBhbiBhYnNvbHV0ZSBVUkkKKyAqIGFuZCByZXByZXNlbnRpbmcgdGhlIHR5cGUgb2YgdGhlIHNjaGVtYSBsYW5ndWFnZSB1c2VkIHRvIHZhbGlkYXRlIGEKKyAqIGRvY3VtZW50IGFnYWluc3QuIE5vdGUgdGhhdCBubyBsZXhpY2FsIGNoZWNraW5nIGlzIGRvbmUgb24gdGhlIGFic29sdXRlCisgKiBVUkkuICBJZiB0aGlzIHBhcmFtZXRlciBpcyBub3Qgc2V0LCBhIGRlZmF1bHQgdmFsdWUgbWF5IGJlIHByb3ZpZGVkIGJ5CisgKiB0aGUgaW1wbGVtZW50YXRpb24sIGJhc2VkIG9uIHRoZSBzY2hlbWEgbGFuZ3VhZ2VzIHN1cHBvcnRlZCBhbmQgb24gdGhlCisgKiBzY2hlbWEgbGFuZ3VhZ2UgdXNlZCBhdCBsb2FkIHRpbWUuIElmIG5vIHZhbHVlIGlzIHByb3ZpZGVkLCB0aGlzCisgKiBwYXJhbWV0ZXIgaXMgPGNvZGU+bnVsbDwvY29kZT4uCisgKiA8cCA+PGI+Tm90ZTo8L2I+ICBGb3IgWE1MIFNjaGVtYSBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvJz5YTUwgU2NoZW1hIFBhcnQgMTwvYT5dCisgKiAsIGFwcGxpY2F0aW9ucyBtdXN0IHVzZSB0aGUgdmFsdWUKKyAqIDxjb2RlPiJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSI8L2NvZGU+LiBGb3IgWE1MIERURCBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0sCisgKiBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlCisgKiA8Y29kZT4iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCI8L2NvZGU+LiBPdGhlciBzY2hlbWEgbGFuZ3VhZ2VzIGFyZQorICogb3V0c2lkZSB0aGUgc2NvcGUgb2YgdGhlIFczQyBhbmQgdGhlcmVmb3JlIHNob3VsZCByZWNvbW1lbmQgYW4gYWJzb2x1dGUKKyAqIFVSSSBpbiBvcmRlciB0byB1c2UgdGhpcyBtZXRob2QuIDwvZGQ+CisgKiA8ZHQ+PGNvZGU+InNwbGl0LWNkYXRhLXNlY3Rpb25zIjwvY29kZT48L2R0PgorICogPGRkPgorICogPGRsPgorICogPGR0PgorICogPGNvZGU+dHJ1ZTwvY29kZT48L2R0PgorICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pU3BsaXQgQ0RBVEEgc2VjdGlvbnMgY29udGFpbmluZyB0aGUgQ0RBVEEgc2VjdGlvbiB0ZXJtaW5hdGlvbiBtYXJrZXIKKyAqICddXSZndDsnLiBXaGVuIGEgQ0RBVEEgc2VjdGlvbiBpcyBzcGxpdCBhIHdhcm5pbmcgaXMgaXNzdWVkIHdpdGggYQorICogPGNvZGU+RE9NRXJyb3IudHlwZTwvY29kZT4gZXF1YWxzIHRvCisgKiA8Y29kZT4iY2RhdGEtc2VjdGlvbnMtc3BsaXR0ZWQiPC9jb2RlPiBhbmQKKyAqIDxjb2RlPkRPTUVycm9yLnJlbGF0ZWREYXRhPC9jb2RlPiBlcXVhbHMgdG8gdGhlIGZpcnN0CisgKiA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+IG5vZGUgaW4gZG9jdW1lbnQgb3JkZXIgcmVzdWx0aW5nIGZyb20gdGhlIHNwbGl0LjwvZGQ+CisgKiA8ZHQ+CisgKiA8Y29kZT5mYWxzZTwvY29kZT48L2R0PgorICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl1TaWduYWwgYW4gZXJyb3IgaWYgYSA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+IGNvbnRhaW5zIGFuCisgKiB1bnJlcHJlc2VudGFibGUgY2hhcmFjdGVyLjwvZGQ+CisgKiA8L2RsPjwvZGQ+CisgKiA8ZHQ+PGNvZGU+InZhbGlkYXRlIjwvY29kZT48L2R0PgorICogPGRkPgorICogPGRsPgorICogPGR0Pjxjb2RlPnRydWU8L2NvZGU+PC9kdD4KKyAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dIFJlcXVpcmUgdGhlIHZhbGlkYXRpb24gYWdhaW5zdCBhIHNjaGVtYSAoaS5lLiBYTUwgc2NoZW1hLCBEVEQsIGFueQorICogb3RoZXIgdHlwZSBvciByZXByZXNlbnRhdGlvbiBvZiBzY2hlbWEpIG9mIHRoZSBkb2N1bWVudCBhcyBpdCBpcyBiZWluZworICogbm9ybWFsaXplZCBhcyBkZWZpbmVkIGJ5IFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XS4gSWYKKyAqIHZhbGlkYXRpb24gZXJyb3JzIGFyZSBmb3VuZCwgb3Igbm8gc2NoZW1hIHdhcyBmb3VuZCwgdGhlIGVycm9yIGhhbmRsZXIgaXMKKyAqIG5vdGlmaWVkLiBTY2hlbWEtbm9ybWFsaXplZCB2YWx1ZXMgd2lsbCBub3QgYmUgZXhwb3NlZCBhY2NvcmRpbmcgdG8gdGhlCisgKiBzY2hlbWEgaW4gdXNlZCB1bmxlc3MgdGhlIHBhcmFtZXRlciAiZGF0YXR5cGUtbm9ybWFsaXphdGlvbiIgaXMKKyAqIDxjb2RlPnRydWU8L2NvZGU+LiAgVGhpcyBwYXJhbWV0ZXIgd2lsbCByZWV2YWx1YXRlOgorICogPHVsPgorICogPGxpPiBBdHRyaWJ1dGUgbm9kZXMgd2l0aAorICogPGNvZGU+QXR0ci5zcGVjaWZpZWQ8L2NvZGU+IGVxdWFscyB0byA8Y29kZT5mYWxzZTwvY29kZT4sIGFzIHNwZWNpZmllZCBpbgorICogdGhlIGRlc2NyaXB0aW9uIG9mIHRoZSA8Y29kZT5BdHRyPC9jb2RlPiBpbnRlcmZhY2U7CisgKiA8L2xpPgorICogPGxpPiBUaGUgdmFsdWUgb2YgdGhlCisgKiBhdHRyaWJ1dGUgPGNvZGU+VGV4dC5pc0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZTwvY29kZT4gZm9yIGFsbAorICogPGNvZGU+VGV4dDwvY29kZT4gbm9kZXM7CisgKiA8L2xpPgorICogPGxpPiBUaGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZQorICogPGNvZGU+QXR0ci5pc0lkPC9jb2RlPiBmb3IgYWxsIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzOworICogPC9saT4KKyAqIDxsaT4gVGhlIGF0dHJpYnV0ZXMKKyAqIDxjb2RlPkVsZW1lbnQuc2NoZW1hVHlwZUluZm88L2NvZGU+IGFuZCA8Y29kZT5BdHRyLnNjaGVtYVR5cGVJbmZvPC9jb2RlPi4KKyAqIDwvbGk+CisgKiA8L3VsPgorICogPHAgPjxiPk5vdGU6PC9iPiAgInZhbGlkYXRlLWlmLXNjaGVtYSIgYW5kICJ2YWxpZGF0ZSIgYXJlIG11dHVhbGx5CisgKiBleGNsdXNpdmUsIHNldHRpbmcgb25lIG9mIHRoZW0gdG8gPGNvZGU+dHJ1ZTwvY29kZT4gd2lsbCBzZXQgdGhlIG90aGVyCisgKiBvbmUgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LiBBcHBsaWNhdGlvbnMgc2hvdWxkIGFsc28gY29uc2lkZXIgc2V0dGluZyB0aGUKKyAqIHBhcmFtZXRlciAid2VsbC1mb3JtZWQiIHRvIDxjb2RlPnRydWU8L2NvZGU+LCB3aGljaCBpcyB0aGUgZGVmYXVsdCBmb3IKKyAqIHRoYXQgb3B0aW9uLCB3aGVuIHZhbGlkYXRpbmcgdGhlIGRvY3VtZW50LiA8L2RkPgorICogPGR0Pjxjb2RlPmZhbHNlPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPikgRG8gbm90IGFjY29tcGxpc2ggc2NoZW1hIHByb2Nlc3NpbmcsIGluY2x1ZGluZyB0aGUgaW50ZXJuYWwgc3Vic2V0CisgKiBwcm9jZXNzaW5nLiBEZWZhdWx0IGF0dHJpYnV0ZSB2YWx1ZXMgaW5mb3JtYXRpb24gYXJlIGtlcHQuIE5vdGUgdGhhdAorICogdmFsaWRhdGlvbiBtaWdodCBzdGlsbCBoYXBwZW4gaWYgInZhbGlkYXRlLWlmLXNjaGVtYSIgaXMgPGNvZGU+dHJ1ZTwvY29kZT4KKyAqIC4gPC9kZD4KKyAqIDwvZGw+PC9kZD4KKyAqIDxkdD48Y29kZT4idmFsaWRhdGUtaWYtc2NoZW1hIjwvY29kZT48L2R0PgorICogPGRkPgorICogPGRsPgorICogPGR0Pjxjb2RlPnRydWU8L2NvZGU+PC9kdD4KKyAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dRW5hYmxlIHZhbGlkYXRpb24gb25seSBpZiBhIGRlY2xhcmF0aW9uIGZvciB0aGUgZG9jdW1lbnQgZWxlbWVudCBjYW4gYmUKKyAqIGZvdW5kIGluIGEgc2NoZW1hIChpbmRlcGVuZGVudGx5IG9mIHdoZXJlIGl0IGlzIGZvdW5kLCBpLmUuIFhNTCBzY2hlbWEsCisgKiBEVEQsIG9yIGFueSBvdGhlciB0eXBlIG9yIHJlcHJlc2VudGF0aW9uIG9mIHNjaGVtYSkuIElmIHZhbGlkYXRpb24gaXMKKyAqIGVuYWJsZWQsIHRoaXMgcGFyYW1ldGVyIGhhcyB0aGUgc2FtZSBiZWhhdmlvciBhcyB0aGUgcGFyYW1ldGVyICJ2YWxpZGF0ZSIKKyAqIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPi4KKyAqIDxwID48Yj5Ob3RlOjwvYj4gICJ2YWxpZGF0ZS1pZi1zY2hlbWEiIGFuZCAidmFsaWRhdGUiIGFyZSBtdXR1YWxseQorICogZXhjbHVzaXZlLCBzZXR0aW5nIG9uZSBvZiB0aGVtIHRvIDxjb2RlPnRydWU8L2NvZGU+IHdpbGwgc2V0IHRoZSBvdGhlcgorICogb25lIHRvIDxjb2RlPmZhbHNlPC9jb2RlPi4gPC9kZD4KKyAqIDxkdD48Y29kZT5mYWxzZTwvY29kZT48L2R0PgorICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pIE5vIHNjaGVtYSBwcm9jZXNzaW5nIHNob3VsZCBiZSBwZXJmb3JtZWQgaWYgdGhlIGRvY3VtZW50IGhhcyBhIHNjaGVtYSwKKyAqIGluY2x1ZGluZyBpbnRlcm5hbCBzdWJzZXQgcHJvY2Vzc2luZy4gRGVmYXVsdCBhdHRyaWJ1dGUgdmFsdWVzCisgKiBpbmZvcm1hdGlvbiBhcmUga2VwdC4gTm90ZSB0aGF0IHZhbGlkYXRpb24gbXVzdCBzdGlsbCBoYXBwZW4gaWYgInZhbGlkYXRlCisgKiAiIGlzIDxjb2RlPnRydWU8L2NvZGU+LiA8L2RkPgorICogPC9kbD48L2RkPgorICogPGR0Pjxjb2RlPiJ3ZWxsLWZvcm1lZCI8L2NvZGU+PC9kdD4KKyAqIDxkZD4KKyAqIDxkbD4KKyAqIDxkdD48Y29kZT50cnVlPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPikgQ2hlY2sgaWYgYWxsIG5vZGVzIGFyZSBYTUwgd2VsbCBmb3JtZWQgYWNjb3JkaW5nIHRvIHRoZSBYTUwgdmVyc2lvbiBpbgorICogdXNlIGluIDxjb2RlPkRvY3VtZW50LnhtbFZlcnNpb248L2NvZGU+OgorICogPHVsPgorICogPGxpPiBjaGVjayBpZiB0aGUgYXR0cmlidXRlCisgKiA8Y29kZT5Ob2RlLm5vZGVOYW1lPC9jb2RlPiBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnMgYWNjb3JkaW5nIHRvIGl0cworICogbm9kZSB0eXBlIGFuZCBnZW5lcmF0ZSBhIDxjb2RlPkRPTUVycm9yPC9jb2RlPiBvZiB0eXBlCisgKiA8Y29kZT4id2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lIjwvY29kZT4sIHdpdGggYQorICogPGNvZGU+RE9NRXJyb3IuU0VWRVJJVFlfRVJST1I8L2NvZGU+IHNldmVyaXR5LCBpZiBuZWNlc3Nhcnk7CisgKiA8L2xpPgorICogPGxpPiBjaGVjayBpZgorICogdGhlIHRleHQgY29udGVudCBpbnNpZGUgPGNvZGU+QXR0cjwvY29kZT4sIDxjb2RlPkVsZW1lbnQ8L2NvZGU+LAorICogPGNvZGU+Q29tbWVudDwvY29kZT4sIDxjb2RlPlRleHQ8L2NvZGU+LCA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+IG5vZGVzCisgKiBmb3IgaW52YWxpZCBjaGFyYWN0ZXJzIGFuZCBnZW5lcmF0ZSBhIDxjb2RlPkRPTUVycm9yPC9jb2RlPiBvZiB0eXBlCisgKiA8Y29kZT4id2YtaW52YWxpZC1jaGFyYWN0ZXIiPC9jb2RlPiwgd2l0aCBhCisgKiA8Y29kZT5ET01FcnJvci5TRVZFUklUWV9FUlJPUjwvY29kZT4gc2V2ZXJpdHksIGlmIG5lY2Vzc2FyeTsKKyAqIDwvbGk+CisgKiA8bGk+IGNoZWNrIGlmCisgKiB0aGUgZGF0YSBpbnNpZGUgPGNvZGU+UHJvY2Vzc2luZ0luc3RydWN0aW9uPC9jb2RlPiBub2RlcyBmb3IgaW52YWxpZAorICogY2hhcmFjdGVycyBhbmQgZ2VuZXJhdGUgYSA8Y29kZT5ET01FcnJvcjwvY29kZT4gb2YgdHlwZQorICogPGNvZGU+IndmLWludmFsaWQtY2hhcmFjdGVyIjwvY29kZT4sIHdpdGggYQorICogPGNvZGU+RE9NRXJyb3IuU0VWRVJJVFlfRVJST1I8L2NvZGU+IHNldmVyaXR5LCBpZiBuZWNlc3Nhcnk7CisgKiA8L2xpPgorICogPC91bD48L2RkPgorICogPGR0PgorICogPGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KKyAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dIERvIG5vdCBjaGVjayBmb3IgWE1MIHdlbGwtZm9ybWVkbmVzcy4gPC9kZD4KKyAqIDwvZGw+PC9kZD4KKyAqIDwvZGw+CisgKiA8cD4gVGhlIHJlc29sdXRpb24gb2YgdGhlIHN5c3RlbSBpZGVudGlmaWVycyBhc3NvY2lhdGVkIHdpdGggZW50aXRpZXMgaXMKKyAqIGRvbmUgdXNpbmcgPGNvZGU+RG9jdW1lbnQuZG9jdW1lbnRVUkk8L2NvZGU+LiBIb3dldmVyLCB3aGVuIHRoZSBmZWF0dXJlCisgKiAiTFMiIGRlZmluZWQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUxTLTIwMDQwNDA3Jz5ET00gTGV2ZWwgMyBMb2FkIGFuZCBTYXZlPC9hPl0KKyAqICBpcyBzdXBwb3J0ZWQgYnkgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiwgdGhlIHBhcmFtZXRlcgorICogInJlc291cmNlLXJlc29sdmVyIiBjYW4gYWxzbyBiZSB1c2VkIG9uIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+CisgKiBvYmplY3RzIGF0dGFjaGVkIHRvIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBub2Rlcy4gSWYgdGhpcyBwYXJhbWV0ZXIgaXMKKyAqIHNldCwgPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4gd2lsbCBpbnZva2UgdGhlIHJlc291cmNlCisgKiByZXNvbHZlciBpbnN0ZWFkIG9mIHVzaW5nIDxjb2RlPkRvY3VtZW50LmRvY3VtZW50VVJJPC9jb2RlPi4KKyAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgorICogQHNpbmNlIERPTSBMZXZlbCAzCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRE9NQ29uZmlndXJhdGlvbiB7CisgICAgLyoqCisgICAgICogU2V0IHRoZSB2YWx1ZSBvZiBhIHBhcmFtZXRlci4KKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyIHRvIHNldC4KKyAgICAgKiBAcGFyYW0gdmFsdWUgIFRoZSBuZXcgdmFsdWUgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIHVzZXIgd2lzaGVzIHRvCisgICAgICogICB1bnNldCB0aGUgcGFyYW1ldGVyLiBXaGlsZSB0aGUgdHlwZSBvZiB0aGUgdmFsdWUgcGFyYW1ldGVyIGlzCisgICAgICogICBkZWZpbmVkIGFzIDxjb2RlPkRPTVVzZXJEYXRhPC9jb2RlPiwgdGhlIG9iamVjdCB0eXBlIG11c3QgbWF0Y2ggdGhlCisgICAgICogICB0eXBlIGRlZmluZWQgYnkgdGhlIGRlZmluaXRpb24gb2YgdGhlIHBhcmFtZXRlci4gRm9yIGV4YW1wbGUsIGlmCisgICAgICogICB0aGUgcGFyYW1ldGVyIGlzICJlcnJvci1oYW5kbGVyIiwgdGhlIHZhbHVlIG11c3QgYmUgb2YgdHlwZQorICAgICAqICAgPGNvZGU+RE9NRXJyb3JIYW5kbGVyPC9jb2RlPi4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgIE5PVF9GT1VORF9FUlI6IFJhaXNlZCB3aGVuIHRoZSBwYXJhbWV0ZXIgbmFtZSBpcyBub3QgcmVjb2duaXplZC4KKyAgICAgKiAgIDxicj4gTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCB3aGVuIHRoZSBwYXJhbWV0ZXIgbmFtZSBpcyByZWNvZ25pemVkCisgICAgICogICBidXQgdGhlIHJlcXVlc3RlZCB2YWx1ZSBjYW5ub3QgYmUgc2V0LgorICAgICAqICAgPGJyPiBUWVBFX01JU01BVENIX0VSUjogUmFpc2VkIGlmIHRoZSB2YWx1ZSB0eXBlIGZvciB0aGlzIHBhcmFtZXRlcgorICAgICAqICAgbmFtZSBpcyBpbmNvbXBhdGlibGUgd2l0aCB0aGUgZXhwZWN0ZWQgdmFsdWUgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdCB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqICBSZXR1cm4gdGhlIHZhbHVlIG9mIGEgcGFyYW1ldGVyIGlmIGtub3duLgorICAgICAqIEBwYXJhbSBuYW1lICBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqIEByZXR1cm4gIFRoZSBjdXJyZW50IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgb3IKKyAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vIG9iamVjdCBoYXMgYmVlbiBhc3NvY2lhdGVkIG9yIGlmIHRoZQorICAgICAqICAgcGFyYW1ldGVyIGlzIG5vdCBzdXBwb3J0ZWQuCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgICBOT1RfRk9VTkRfRVJSOiBSYWlzZWQgd2hlbiB0aGUgcGFyYW1ldGVyIG5hbWUgaXMgbm90IHJlY29nbml6ZWQuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENoZWNrIGlmIHNldHRpbmcgYSBwYXJhbWV0ZXIgdG8gYSBzcGVjaWZpYyB2YWx1ZSBpcyBzdXBwb3J0ZWQuCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlciB0byBjaGVjay4KKyAgICAgKiBAcGFyYW0gdmFsdWUgIEFuIG9iamVjdC4gaWYgPGNvZGU+bnVsbDwvY29kZT4sIHRoZSByZXR1cm5lZCB2YWx1ZSBpcworICAgICAqICAgPGNvZGU+dHJ1ZTwvY29kZT4uCisgICAgICogQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHBhcmFtZXRlciBjb3VsZCBiZSBzdWNjZXNzZnVsbHkgc2V0CisgICAgICogICB0byB0aGUgc3BlY2lmaWVkIHZhbHVlLCBvciA8Y29kZT5mYWxzZTwvY29kZT4gaWYgdGhlIHBhcmFtZXRlciBpcworICAgICAqICAgbm90IHJlY29nbml6ZWQgb3IgdGhlIHJlcXVlc3RlZCB2YWx1ZSBpcyBub3Qgc3VwcG9ydGVkLiBUaGlzIGRvZXMKKyAgICAgKiAgIG5vdCBjaGFuZ2UgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHBhcmFtZXRlciBpdHNlbGYuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY2FuU2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgdmFsdWUpOworCisgICAgLyoqCisgICAgICogIFRoZSBsaXN0IG9mIHRoZSBwYXJhbWV0ZXJzIHN1cHBvcnRlZCBieSB0aGlzCisgICAgICogPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gb2JqZWN0IGFuZCBmb3Igd2hpY2ggYXQgbGVhc3Qgb25lIHZhbHVlCisgICAgICogY2FuIGJlIHNldCBieSB0aGUgYXBwbGljYXRpb24uIE5vdGUgdGhhdCB0aGlzIGxpc3QgY2FuIGFsc28gY29udGFpbgorICAgICAqIHBhcmFtZXRlciBuYW1lcyBkZWZpbmVkIG91dHNpZGUgdGhpcyBzcGVjaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBET01TdHJpbmdMaXN0IGdldFBhcmFtZXRlck5hbWVzKCk7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9ET01FcnJvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0RPTUVycm9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjYzNGRmMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9ET01FcnJvci5qYXZhCkBAIC0wLDAgKzEsODcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKKyAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcworICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKKyAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAorICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgorICoKKyAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbTsKKworLyoqCisgKiA8Y29kZT5ET01FcnJvcjwvY29kZT4gaXMgYW4gaW50ZXJmYWNlIHRoYXQgZGVzY3JpYmVzIGFuIGVycm9yLgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCisgKiBAc2luY2UgRE9NIExldmVsIDMKKyAqLworcHVibGljIGludGVyZmFjZSBET01FcnJvciB7CisgICAgLy8gRXJyb3JTZXZlcml0eQorICAgIC8qKgorICAgICAqIFRoZSBzZXZlcml0eSBvZiB0aGUgZXJyb3IgZGVzY3JpYmVkIGJ5IHRoZSA8Y29kZT5ET01FcnJvcjwvY29kZT4gaXMKKyAgICAgKiB3YXJuaW5nLiBBIDxjb2RlPlNFVkVSSVRZX1dBUk5JTkc8L2NvZGU+IHdpbGwgbm90IGNhdXNlIHRoZQorICAgICAqIHByb2Nlc3NpbmcgdG8gc3RvcCwgdW5sZXNzIDxjb2RlPkRPTUVycm9ySGFuZGxlci5oYW5kbGVFcnJvcigpPC9jb2RlPgorICAgICAqIHJldHVybnMgPGNvZGU+ZmFsc2U8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgU0VWRVJJVFlfV0FSTklORyAgICAgICAgICA9IDE7CisgICAgLyoqCisgICAgICogVGhlIHNldmVyaXR5IG9mIHRoZSBlcnJvciBkZXNjcmliZWQgYnkgdGhlIDxjb2RlPkRPTUVycm9yPC9jb2RlPiBpcworICAgICAqIGVycm9yLiBBIDxjb2RlPlNFVkVSSVRZX0VSUk9SPC9jb2RlPiBtYXkgbm90IGNhdXNlIHRoZSBwcm9jZXNzaW5nIHRvCisgICAgICogc3RvcCBpZiB0aGUgZXJyb3IgY2FuIGJlIHJlY292ZXJlZCwgdW5sZXNzCisgICAgICogPGNvZGU+RE9NRXJyb3JIYW5kbGVyLmhhbmRsZUVycm9yKCk8L2NvZGU+IHJldHVybnMgPGNvZGU+ZmFsc2U8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgU0VWRVJJVFlfRVJST1IgICAgICAgICAgICA9IDI7CisgICAgLyoqCisgICAgICogVGhlIHNldmVyaXR5IG9mIHRoZSBlcnJvciBkZXNjcmliZWQgYnkgdGhlIDxjb2RlPkRPTUVycm9yPC9jb2RlPiBpcworICAgICAqIGZhdGFsIGVycm9yLiBBIDxjb2RlPlNFVkVSSVRZX0ZBVEFMX0VSUk9SPC9jb2RlPiB3aWxsIGNhdXNlIHRoZQorICAgICAqIG5vcm1hbCBwcm9jZXNzaW5nIHRvIHN0b3AuIFRoZSByZXR1cm4gdmFsdWUgb2YKKyAgICAgKiA8Y29kZT5ET01FcnJvckhhbmRsZXIuaGFuZGxlRXJyb3IoKTwvY29kZT4gaXMgaWdub3JlZCB1bmxlc3MgdGhlCisgICAgICogaW1wbGVtZW50YXRpb24gY2hvb3NlcyB0byBjb250aW51ZSwgaW4gd2hpY2ggY2FzZSB0aGUgYmVoYXZpb3IKKyAgICAgKiBiZWNvbWVzIHVuZGVmaW5lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNFVkVSSVRZX0ZBVEFMX0VSUk9SICAgICAgPSAzOworCisgICAgLyoqCisgICAgICogVGhlIHNldmVyaXR5IG9mIHRoZSBlcnJvciwgZWl0aGVyIDxjb2RlPlNFVkVSSVRZX1dBUk5JTkc8L2NvZGU+LAorICAgICAqIDxjb2RlPlNFVkVSSVRZX0VSUk9SPC9jb2RlPiwgb3IgPGNvZGU+U0VWRVJJVFlfRkFUQUxfRVJST1I8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzaG9ydCBnZXRTZXZlcml0eSgpOworCisgICAgLyoqCisgICAgICogQW4gaW1wbGVtZW50YXRpb24gc3BlY2lmaWMgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIGVycm9yIHRoYXQgb2NjdXJyZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCk7CisKKyAgICAvKioKKyAgICAgKiAgQSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IGluZGljYXRpbmcgd2hpY2ggcmVsYXRlZCBkYXRhIGlzIGV4cGVjdGVkIGluCisgICAgICogPGNvZGU+cmVsYXRlZERhdGE8L2NvZGU+LiBVc2VycyBzaG91bGQgcmVmZXIgdG8gdGhlIHNwZWNpZmljYXRpb24gb2YKKyAgICAgKiB0aGUgZXJyb3IgaW4gb3JkZXIgdG8gZmluZCBpdHMgPGNvZGU+RE9NU3RyaW5nPC9jb2RlPiB0eXBlIGFuZAorICAgICAqIDxjb2RlPnJlbGF0ZWREYXRhPC9jb2RlPiBkZWZpbml0aW9ucyBpZiBhbnkuCisgICAgICogPHAgPjxiPk5vdGU6PC9iPiAgQXMgYW4gZXhhbXBsZSwKKyAgICAgKiA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPiBkb2VzIGdlbmVyYXRlIHdhcm5pbmdzIHdoZW4KKyAgICAgKiB0aGUgInNwbGl0LWNkYXRhLXNlY3Rpb25zIiBwYXJhbWV0ZXIgaXMgaW4gdXNlLiBUaGVyZWZvcmUsIHRoZSBtZXRob2QKKyAgICAgKiBnZW5lcmF0ZXMgYSA8Y29kZT5TRVZFUklUWV9XQVJOSU5HPC9jb2RlPiB3aXRoIDxjb2RlPnR5cGU8L2NvZGU+CisgICAgICogPGNvZGU+ImNkYXRhLXNlY3Rpb25zLXNwbGl0dGVkIjwvY29kZT4gYW5kIHRoZSBmaXJzdAorICAgICAqIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gbm9kZSBpbiBkb2N1bWVudCBvcmRlciByZXN1bHRpbmcgZnJvbSB0aGUKKyAgICAgKiBzcGxpdCBpcyByZXR1cm5lZCBieSB0aGUgPGNvZGU+cmVsYXRlZERhdGE8L2NvZGU+IGF0dHJpYnV0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoKTsKKworICAgIC8qKgorICAgICAqIFRoZSByZWxhdGVkIHBsYXRmb3JtIGRlcGVuZGVudCBleGNlcHRpb24gaWYgYW55LgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0UmVsYXRlZEV4Y2VwdGlvbigpOworCisgICAgLyoqCisgICAgICogIFRoZSByZWxhdGVkIDxjb2RlPkRPTUVycm9yLnR5cGU8L2NvZGU+IGRlcGVuZGVudCBkYXRhIGlmIGFueS4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldFJlbGF0ZWREYXRhKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbG9jYXRpb24gb2YgdGhlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBET01Mb2NhdG9yIGdldExvY2F0aW9uKCk7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9ET01FcnJvckhhbmRsZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9ET01FcnJvckhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZGNjOTAxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0RPTUVycm9ySGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKKyAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcworICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKKyAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAorICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgorICoKKyAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbTsKKworLyoqCisgKiAgPGNvZGU+RE9NRXJyb3JIYW5kbGVyPC9jb2RlPiBpcyBhIGNhbGxiYWNrIGludGVyZmFjZSB0aGF0IHRoZSBET00KKyAqIGltcGxlbWVudGF0aW9uIGNhbiBjYWxsIHdoZW4gcmVwb3J0aW5nIGVycm9ycyB0aGF0IGhhcHBlbnMgd2hpbGUKKyAqIHByb2Nlc3NpbmcgWE1MIGRhdGEsIG9yIHdoZW4gZG9pbmcgc29tZSBvdGhlciBwcm9jZXNzaW5nIChlLmcuIHZhbGlkYXRpbmcKKyAqIGEgZG9jdW1lbnQpLiBBIDxjb2RlPkRPTUVycm9ySGFuZGxlcjwvY29kZT4gb2JqZWN0IGNhbiBiZSBhdHRhY2hlZCB0byBhCisgKiA8Y29kZT5Eb2N1bWVudDwvY29kZT4gdXNpbmcgdGhlICJlcnJvci1oYW5kbGVyIiBvbiB0aGUKKyAqIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IGludGVyZmFjZS4gSWYgbW9yZSB0aGFuIG9uZSBlcnJvciBuZWVkcyB0bworICogYmUgcmVwb3J0ZWQgZHVyaW5nIGFuIG9wZXJhdGlvbiwgdGhlIHNlcXVlbmNlIGFuZCBudW1iZXJzIG9mIHRoZSBlcnJvcnMKKyAqIHBhc3NlZCB0byB0aGUgZXJyb3IgaGFuZGxlciBhcmUgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgorICogPHA+IFRoZSBhcHBsaWNhdGlvbiB0aGF0IGlzIHVzaW5nIHRoZSBET00gaW1wbGVtZW50YXRpb24gaXMgZXhwZWN0ZWQgdG8KKyAqIGltcGxlbWVudCB0aGlzIGludGVyZmFjZS4KKyAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgorICogQHNpbmNlIERPTSBMZXZlbCAzCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRE9NRXJyb3JIYW5kbGVyIHsKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgb24gdGhlIGVycm9yIGhhbmRsZXIgd2hlbiBhbiBlcnJvciBvY2N1cnMuCisgICAgICogPGJyPiBJZiBhbiBleGNlcHRpb24gaXMgdGhyb3duIGZyb20gdGhpcyBtZXRob2QsIGl0IGlzIGNvbnNpZGVyZWQgdG8gYmUKKyAgICAgKiBlcXVpdmFsZW50IG9mIHJldHVybmluZyA8Y29kZT50cnVlPC9jb2RlPi4KKyAgICAgKiBAcGFyYW0gZXJyb3IgIFRoZSBlcnJvciBvYmplY3QgdGhhdCBkZXNjcmliZXMgdGhlIGVycm9yLiBUaGlzIG9iamVjdAorICAgICAqICAgbWF5IGJlIHJldXNlZCBieSB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGFjcm9zcyBtdWx0aXBsZSBjYWxscyB0bworICAgICAqICAgdGhlIDxjb2RlPmhhbmRsZUVycm9yPC9jb2RlPiBtZXRob2QuCisgICAgICogQHJldHVybiAgSWYgdGhlIDxjb2RlPmhhbmRsZUVycm9yPC9jb2RlPiBtZXRob2QgcmV0dXJucworICAgICAqICAgPGNvZGU+ZmFsc2U8L2NvZGU+LCB0aGUgRE9NIGltcGxlbWVudGF0aW9uIHNob3VsZCBzdG9wIHRoZSBjdXJyZW50CisgICAgICogICBwcm9jZXNzaW5nIHdoZW4gcG9zc2libGUuIElmIHRoZSBtZXRob2QgcmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiwKKyAgICAgKiAgIHRoZSBwcm9jZXNzaW5nIG1heSBjb250aW51ZSBkZXBlbmRpbmcgb24KKyAgICAgKiAgIDxjb2RlPkRPTUVycm9yLnNldmVyaXR5PC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYW5kbGVFcnJvcihET01FcnJvciBlcnJvcik7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9ET01FeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9ET01FeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yM2M3MGM0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0RPTUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTMxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKgorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCisgKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKKyAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0CisgKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKKyAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KKyAqCisgKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb207CisKKy8qKgorICogRE9NIG9wZXJhdGlvbnMgb25seSByYWlzZSBleGNlcHRpb25zIGluICJleGNlcHRpb25hbCIgY2lyY3Vtc3RhbmNlcywgaS5lLiwKKyAqIHdoZW4gYW4gb3BlcmF0aW9uIGlzIGltcG9zc2libGUgdG8gcGVyZm9ybSAoZWl0aGVyIGZvciBsb2dpY2FsIHJlYXNvbnMsCisgKiBiZWNhdXNlIGRhdGEgaXMgbG9zdCwgb3IgYmVjYXVzZSB0aGUgaW1wbGVtZW50YXRpb24gaGFzIGJlY29tZSB1bnN0YWJsZSkuCisgKiBJbiBnZW5lcmFsLCBET00gbWV0aG9kcyByZXR1cm4gc3BlY2lmaWMgZXJyb3IgdmFsdWVzIGluIG9yZGluYXJ5CisgKiBwcm9jZXNzaW5nIHNpdHVhdGlvbnMsIHN1Y2ggYXMgb3V0LW9mLWJvdW5kIGVycm9ycyB3aGVuIHVzaW5nCisgKiA8Y29kZT5Ob2RlTGlzdDwvY29kZT4uCisgKiA8cD5JbXBsZW1lbnRhdGlvbnMgc2hvdWxkIHJhaXNlIG90aGVyIGV4Y2VwdGlvbnMgdW5kZXIgb3RoZXIgY2lyY3Vtc3RhbmNlcy4KKyAqIEZvciBleGFtcGxlLCBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIHJhaXNlIGFuIGltcGxlbWVudGF0aW9uLWRlcGVuZGVudAorICogZXhjZXB0aW9uIGlmIGEgPGNvZGU+bnVsbDwvY29kZT4gYXJndW1lbnQgaXMgcGFzc2VkIHdoZW4gPGNvZGU+bnVsbDwvY29kZT4KKyAqICB3YXMgbm90IGV4cGVjdGVkLgorICogPHA+U29tZSBsYW5ndWFnZXMgYW5kIG9iamVjdCBzeXN0ZW1zIGRvIG5vdCBzdXBwb3J0IHRoZSBjb25jZXB0IG9mCisgKiBleGNlcHRpb25zLiBGb3Igc3VjaCBzeXN0ZW1zLCBlcnJvciBjb25kaXRpb25zIG1heSBiZSBpbmRpY2F0ZWQgdXNpbmcKKyAqIG5hdGl2ZSBlcnJvciByZXBvcnRpbmcgbWVjaGFuaXNtcy4gRm9yIHNvbWUgYmluZGluZ3MsIGZvciBleGFtcGxlLAorICogbWV0aG9kcyBtYXkgcmV0dXJuIGVycm9yIGNvZGVzIHNpbWlsYXIgdG8gdGhvc2UgbGlzdGVkIGluIHRoZQorICogY29ycmVzcG9uZGluZyBtZXRob2QgZGVzY3JpcHRpb25zLgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCisgKi8KK3B1YmxpYyBjbGFzcyBET01FeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKKyAgICBwdWJsaWMgRE9NRXhjZXB0aW9uKHNob3J0IGNvZGUsIFN0cmluZyBtZXNzYWdlKSB7CisgICAgICAgc3VwZXIobWVzc2FnZSk7CisgICAgICAgdGhpcy5jb2RlID0gY29kZTsKKyAgICB9CisgICAgcHVibGljIHNob3J0ICAgY29kZTsKKyAgICAvLyBFeGNlcHRpb25Db2RlCisgICAgLyoqCisgICAgICogSWYgaW5kZXggb3Igc2l6ZSBpcyBuZWdhdGl2ZSwgb3IgZ3JlYXRlciB0aGFuIHRoZSBhbGxvd2VkIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5ERVhfU0laRV9FUlIgICAgICAgICAgICA9IDE7CisgICAgLyoqCisgICAgICogSWYgdGhlIHNwZWNpZmllZCByYW5nZSBvZiB0ZXh0IGRvZXMgbm90IGZpdCBpbnRvIGEKKyAgICAgKiA8Y29kZT5ET01TdHJpbmc8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRE9NU1RSSU5HX1NJWkVfRVJSICAgICAgICA9IDI7CisgICAgLyoqCisgICAgICogSWYgYW55IDxjb2RlPk5vZGU8L2NvZGU+IGlzIGluc2VydGVkIHNvbWV3aGVyZSBpdCBkb2Vzbid0IGJlbG9uZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEhJRVJBUkNIWV9SRVFVRVNUX0VSUiAgICAgPSAzOworICAgIC8qKgorICAgICAqIElmIGEgPGNvZGU+Tm9kZTwvY29kZT4gaXMgdXNlZCBpbiBhIGRpZmZlcmVudCBkb2N1bWVudCB0aGFuIHRoZSBvbmUKKyAgICAgKiB0aGF0IGNyZWF0ZWQgaXQgKHRoYXQgZG9lc24ndCBzdXBwb3J0IGl0KS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFdST05HX0RPQ1VNRU5UX0VSUiAgICAgICAgPSA0OworICAgIC8qKgorICAgICAqIElmIGFuIGludmFsaWQgb3IgaWxsZWdhbCBjaGFyYWN0ZXIgaXMgc3BlY2lmaWVkLCBzdWNoIGFzIGluIGFuIFhNTCBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5WQUxJRF9DSEFSQUNURVJfRVJSICAgICA9IDU7CisgICAgLyoqCisgICAgICogSWYgZGF0YSBpcyBzcGVjaWZpZWQgZm9yIGEgPGNvZGU+Tm9kZTwvY29kZT4gd2hpY2ggZG9lcyBub3Qgc3VwcG9ydAorICAgICAqIGRhdGEuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBOT19EQVRBX0FMTE9XRURfRVJSICAgICAgID0gNjsKKyAgICAvKioKKyAgICAgKiBJZiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gbW9kaWZ5IGFuIG9iamVjdCB3aGVyZSBtb2RpZmljYXRpb25zIGFyZSBub3QKKyAgICAgKiBhbGxvd2VkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSID0gNzsKKyAgICAvKioKKyAgICAgKiBJZiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gcmVmZXJlbmNlIGEgPGNvZGU+Tm9kZTwvY29kZT4gaW4gYSBjb250ZXh0CisgICAgICogd2hlcmUgaXQgZG9lcyBub3QgZXhpc3QuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBOT1RfRk9VTkRfRVJSICAgICAgICAgICAgID0gODsKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCB0aGUgcmVxdWVzdGVkIHR5cGUgb2Ygb2JqZWN0IG9yCisgICAgICogb3BlcmF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTk9UX1NVUFBPUlRFRF9FUlIgICAgICAgICA9IDk7CisgICAgLyoqCisgICAgICogSWYgYW4gYXR0ZW1wdCBpcyBtYWRlIHRvIGFkZCBhbiBhdHRyaWJ1dGUgdGhhdCBpcyBhbHJlYWR5IGluIHVzZQorICAgICAqIGVsc2V3aGVyZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElOVVNFX0FUVFJJQlVURV9FUlIgICAgICAgPSAxMDsKKyAgICAvKioKKyAgICAgKiBJZiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gdXNlIGFuIG9iamVjdCB0aGF0IGlzIG5vdCwgb3IgaXMgbm8gbG9uZ2VyLAorICAgICAqIHVzYWJsZS4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElOVkFMSURfU1RBVEVfRVJSICAgICAgICAgPSAxMTsKKyAgICAvKioKKyAgICAgKiBJZiBhbiBpbnZhbGlkIG9yIGlsbGVnYWwgc3RyaW5nIGlzIHNwZWNpZmllZC4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNZTlRBWF9FUlIgICAgICAgICAgICAgICAgPSAxMjsKKyAgICAvKioKKyAgICAgKiBJZiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gbW9kaWZ5IHRoZSB0eXBlIG9mIHRoZSB1bmRlcmx5aW5nIG9iamVjdC4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElOVkFMSURfTU9ESUZJQ0FUSU9OX0VSUiAgPSAxMzsKKyAgICAvKioKKyAgICAgKiBJZiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gY3JlYXRlIG9yIGNoYW5nZSBhbiBvYmplY3QgaW4gYSB3YXkgd2hpY2ggaXMKKyAgICAgKiBpbmNvcnJlY3Qgd2l0aCByZWdhcmQgdG8gbmFtZXNwYWNlcy4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5BTUVTUEFDRV9FUlIgICAgICAgICAgICAgPSAxNDsKKyAgICAvKioKKyAgICAgKiBJZiBhIHBhcmFtZXRlciBvciBhbiBvcGVyYXRpb24gaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgdW5kZXJseWluZworICAgICAqIG9iamVjdC4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElOVkFMSURfQUNDRVNTX0VSUiAgICAgICAgPSAxNTsKKyAgICAvKioKKyAgICAgKiBJZiBhIGNhbGwgdG8gYSBtZXRob2Qgc3VjaCBhcyA8Y29kZT5pbnNlcnRCZWZvcmU8L2NvZGU+IG9yCisgICAgICogPGNvZGU+cmVtb3ZlQ2hpbGQ8L2NvZGU+IHdvdWxkIG1ha2UgdGhlIDxjb2RlPk5vZGU8L2NvZGU+IGludmFsaWQKKyAgICAgKiB3aXRoIHJlc3BlY3QgdG8gInBhcnRpYWwgdmFsaWRpdHkiLCB0aGlzIGV4Y2VwdGlvbiB3b3VsZCBiZSByYWlzZWQKKyAgICAgKiBhbmQgdGhlIG9wZXJhdGlvbiB3b3VsZCBub3QgYmUgZG9uZS4gVGhpcyBjb2RlIGlzIHVzZWQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLVZhbC0yMDA0MDEyNy8nPkRPTSBMZXZlbCAzIFZhbGlkYXRpb248L2E+XQorICAgICAqIC4gUmVmZXIgdG8gdGhpcyBzcGVjaWZpY2F0aW9uIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVkFMSURBVElPTl9FUlIgICAgICAgICAgICA9IDE2OworICAgIC8qKgorICAgICAqICBJZiB0aGUgdHlwZSBvZiBhbiBvYmplY3QgaXMgaW5jb21wYXRpYmxlIHdpdGggdGhlIGV4cGVjdGVkIHR5cGUgb2YgdGhlCisgICAgICogcGFyYW1ldGVyIGFzc29jaWF0ZWQgdG8gdGhlIG9iamVjdC4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFRZUEVfTUlTTUFUQ0hfRVJSICAgICAgICAgPSAxNzsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0RPTUltcGxlbWVudGF0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vRE9NSW1wbGVtZW50YXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YjA3NTc0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0RPTUltcGxlbWVudGF0aW9uLmphdmEKQEAgLTAsMCArMSwxMzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKKyAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcworICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKKyAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAorICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgorICoKKyAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbTsKKworLyoqCisgKiBUaGUgPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+IGludGVyZmFjZSBwcm92aWRlcyBhIG51bWJlciBvZiBtZXRob2RzCisgKiBmb3IgcGVyZm9ybWluZyBvcGVyYXRpb25zIHRoYXQgYXJlIGluZGVwZW5kZW50IG9mIGFueSBwYXJ0aWN1bGFyIGluc3RhbmNlCisgKiBvZiB0aGUgZG9jdW1lbnQgb2JqZWN0IG1vZGVsLgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRE9NSW1wbGVtZW50YXRpb24geworICAgIC8qKgorICAgICAqIFRlc3QgaWYgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBpbXBsZW1lbnRzIGEgc3BlY2lmaWMgZmVhdHVyZSBhbmQKKyAgICAgKiB2ZXJzaW9uLCBhcyBzcGVjaWZpZWQgaW4gLgorICAgICAqIEBwYXJhbSBmZWF0dXJlICBUaGUgbmFtZSBvZiB0aGUgZmVhdHVyZSB0byB0ZXN0LgorICAgICAqIEBwYXJhbSB2ZXJzaW9uICBUaGlzIGlzIHRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGUgZmVhdHVyZSB0byB0ZXN0LgorICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGZlYXR1cmUgaXMgaW1wbGVtZW50ZWQgaW4gdGhlCisgICAgICogICBzcGVjaWZpZWQgdmVyc2lvbiwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNGZWF0dXJlKFN0cmluZyBmZWF0dXJlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZlcnNpb24pOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBlbXB0eSA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IG5vZGUuIEVudGl0eSBkZWNsYXJhdGlvbnMKKyAgICAgKiBhbmQgbm90YXRpb25zIGFyZSBub3QgbWFkZSBhdmFpbGFibGUuIEVudGl0eSByZWZlcmVuY2UgZXhwYW5zaW9ucyBhbmQKKyAgICAgKiBkZWZhdWx0IGF0dHJpYnV0ZSBhZGRpdGlvbnMgZG8gbm90IG9jY3VyLi4KKyAgICAgKiBAcGFyYW0gcXVhbGlmaWVkTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGRvY3VtZW50IHR5cGUgdG8gYmUKKyAgICAgKiAgIGNyZWF0ZWQuCisgICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBleHRlcm5hbCBzdWJzZXQgcHVibGljIGlkZW50aWZpZXIuCisgICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBleHRlcm5hbCBzdWJzZXQgc3lzdGVtIGlkZW50aWZpZXIuCisgICAgICogQHJldHVybiBBIG5ldyA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IG5vZGUgd2l0aAorICAgICAqICAgPGNvZGU+Tm9kZS5vd25lckRvY3VtZW50PC9jb2RlPiBzZXQgdG8gPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIElOVkFMSURfQ0hBUkFDVEVSX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgcXVhbGlmaWVkIG5hbWUgaXMgbm90CisgICAgICogICBhbiBYTUwgbmFtZSBhY2NvcmRpbmcgdG8gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dLgorICAgICAqICAgPGJyPk5BTUVTUEFDRV9FUlI6IFJhaXNlZCBpZiB0aGUgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gaXMKKyAgICAgKiAgIG1hbGZvcm1lZC4KKyAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogTWF5IGJlIHJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3QKKyAgICAgKiAgIHN1cHBvcnQgdGhlIGZlYXR1cmUgIlhNTCIgYW5kIHRoZSBsYW5ndWFnZSBleHBvc2VkIHRocm91Z2ggdGhlCisgICAgICogICBEb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IFhNTCBOYW1lc3BhY2VzIChzdWNoIGFzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy1odG1sNDAxLTE5OTkxMjI0Lyc+SFRNTCA0LjAxPC9hPl0pLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgorICAgICAqLworICAgIHB1YmxpYyBEb2N1bWVudFR5cGUgY3JlYXRlRG9jdW1lbnRUeXBlKFN0cmluZyBxdWFsaWZpZWROYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwdWJsaWNJZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc3lzdGVtSWQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBET00gRG9jdW1lbnQgb2JqZWN0IG9mIHRoZSBzcGVjaWZpZWQgdHlwZSB3aXRoIGl0cyBkb2N1bWVudAorICAgICAqIGVsZW1lbnQuCisgICAgICogPGJyPk5vdGUgdGhhdCBiYXNlZCBvbiB0aGUgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBnaXZlbiB0byBjcmVhdGUKKyAgICAgKiB0aGUgZG9jdW1lbnQsIHRoZSBpbXBsZW1lbnRhdGlvbiBtYXkgaW5zdGFudGlhdGUgc3BlY2lhbGl6ZWQKKyAgICAgKiA8Y29kZT5Eb2N1bWVudDwvY29kZT4gb2JqZWN0cyB0aGF0IHN1cHBvcnQgYWRkaXRpb25hbCBmZWF0dXJlcyB0aGFuCisgICAgICogdGhlICJDb3JlIiwgc3VjaCBhcyAiSFRNTCIgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvUkVDLURPTS1MZXZlbC0yLUhUTUwtMjAwMzAxMDknPkRPTSBMZXZlbCAyIEhUTUw8L2E+XQorICAgICAqIC4gT24gdGhlIG90aGVyIGhhbmQsIHNldHRpbmcgdGhlIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gYWZ0ZXIgdGhlCisgICAgICogZG9jdW1lbnQgd2FzIGNyZWF0ZWQgbWFrZXMgdGhpcyB2ZXJ5IHVubGlrZWx5IHRvIGhhcHBlbi4KKyAgICAgKiBBbHRlcm5hdGl2ZWx5LCBzcGVjaWFsaXplZCA8Y29kZT5Eb2N1bWVudDwvY29kZT4gY3JlYXRpb24gbWV0aG9kcywKKyAgICAgKiBzdWNoIGFzIDxjb2RlPmNyZWF0ZUhUTUxEb2N1bWVudDwvY29kZT4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvUkVDLURPTS1MZXZlbC0yLUhUTUwtMjAwMzAxMDknPkRPTSBMZXZlbCAyIEhUTUw8L2E+XQorICAgICAqICwgY2FuIGJlIHVzZWQgdG8gb2J0YWluIHNwZWNpZmljIHR5cGVzIG9mIDxjb2RlPkRvY3VtZW50PC9jb2RlPgorICAgICAqIG9iamVjdHMuCisgICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgZG9jdW1lbnQgZWxlbWVudCB0bworICAgICAqICAgY3JlYXRlIG9yIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqIEBwYXJhbSBxdWFsaWZpZWROYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgZG9jdW1lbnQgZWxlbWVudCB0byBiZQorICAgICAqICAgY3JlYXRlZCBvciA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKiBAcGFyYW0gZG9jdHlwZSBUaGUgdHlwZSBvZiBkb2N1bWVudCB0byBiZSBjcmVhdGVkIG9yIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqICAgV2hlbiA8Y29kZT5kb2N0eXBlPC9jb2RlPiBpcyBub3QgPGNvZGU+bnVsbDwvY29kZT4sIGl0cworICAgICAqICAgPGNvZGU+Tm9kZS5vd25lckRvY3VtZW50PC9jb2RlPiBhdHRyaWJ1dGUgaXMgc2V0IHRvIHRoZSBkb2N1bWVudAorICAgICAqICAgYmVpbmcgY3JlYXRlZC4KKyAgICAgKiBAcmV0dXJuIEEgbmV3IDxjb2RlPkRvY3VtZW50PC9jb2RlPiBvYmplY3Qgd2l0aCBpdHMgZG9jdW1lbnQgZWxlbWVudC4KKyAgICAgKiAgIElmIHRoZSA8Y29kZT5OYW1lc3BhY2VVUkk8L2NvZGU+LCA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiwgYW5kCisgICAgICogICA8Y29kZT5kb2N0eXBlPC9jb2RlPiBhcmUgPGNvZGU+bnVsbDwvY29kZT4sIHRoZSByZXR1cm5lZAorICAgICAqICAgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IGlzIGVtcHR5IHdpdGggbm8gZG9jdW1lbnQgZWxlbWVudC4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgSU5WQUxJRF9DSEFSQUNURVJfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBxdWFsaWZpZWQgbmFtZSBpcyBub3QKKyAgICAgKiAgIGFuIFhNTCBuYW1lIGFjY29yZGluZyB0byBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0uCisgICAgICogICA8YnI+TkFNRVNQQUNFX0VSUjogUmFpc2VkIGlmIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBpcworICAgICAqICAgbWFsZm9ybWVkLCBpZiB0aGUgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gaGFzIGEgcHJlZml4IGFuZCB0aGUKKyAgICAgKiAgIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIG9yIGlmIHRoZQorICAgICAqICAgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4gYW5kIHRoZQorICAgICAqICAgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyBkaWZmZXJlbnQgZnJvbSA8Y29kZT5udWxsPC9jb2RlPiwgb3IKKyAgICAgKiAgIGlmIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBoYXMgYSBwcmVmaXggdGhhdCBpcyAieG1sIiBhbmQKKyAgICAgKiAgIHRoZSA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzIGRpZmZlcmVudCBmcm9tICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UnPgorICAgICAqICAgaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlPC9hPiIgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNC8nPlhNTCBOYW1lc3BhY2VzPC9hPl0KKyAgICAgKiAgICwgb3IgaWYgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IHRoZQorICAgICAqICAgPGNvZGU+IlhNTCI8L2NvZGU+IGZlYXR1cmUgYnV0IGEgbm9uLW51bGwgbmFtZXNwYWNlIFVSSSB3YXMKKyAgICAgKiAgIHByb3ZpZGVkLCBzaW5jZSBuYW1lc3BhY2VzIHdlcmUgZGVmaW5lZCBieSBYTUwuCisgICAgICogICA8YnI+V1JPTkdfRE9DVU1FTlRfRVJSOiBSYWlzZWQgaWYgPGNvZGU+ZG9jdHlwZTwvY29kZT4gaGFzIGFscmVhZHkKKyAgICAgKiAgIGJlZW4gdXNlZCB3aXRoIGEgZGlmZmVyZW50IGRvY3VtZW50IG9yIHdhcyBjcmVhdGVkIGZyb20gYSBkaWZmZXJlbnQKKyAgICAgKiAgIGltcGxlbWVudGF0aW9uLgorICAgICAqICAgPGJyPk5PVF9TVVBQT1JURURfRVJSOiBNYXkgYmUgcmFpc2VkIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdAorICAgICAqICAgc3VwcG9ydCB0aGUgZmVhdHVyZSAiWE1MIiBhbmQgdGhlIGxhbmd1YWdlIGV4cG9zZWQgdGhyb3VnaCB0aGUKKyAgICAgKiAgIERvY3VtZW50IGRvZXMgbm90IHN1cHBvcnQgWE1MIE5hbWVzcGFjZXMgKHN1Y2ggYXMgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLWh0bWw0MDEtMTk5OTEyMjQvJz5IVE1MIDQuMDE8L2E+XSkuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAyCisgICAgICovCisgICAgcHVibGljIERvY3VtZW50IGNyZWF0ZURvY3VtZW50KFN0cmluZyBuYW1lc3BhY2VVUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEb2N1bWVudFR5cGUgZG9jdHlwZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqICBUaGlzIG1ldGhvZCByZXR1cm5zIGEgc3BlY2lhbGl6ZWQgb2JqZWN0IHdoaWNoIGltcGxlbWVudHMgdGhlCisgICAgICogc3BlY2lhbGl6ZWQgQVBJcyBvZiB0aGUgc3BlY2lmaWVkIGZlYXR1cmUgYW5kIHZlcnNpb24sIGFzIHNwZWNpZmllZAorICAgICAqIGluIC4gVGhlIHNwZWNpYWxpemVkIG9iamVjdCBtYXkgYWxzbyBiZSBvYnRhaW5lZCBieSB1c2luZworICAgICAqIGJpbmRpbmctc3BlY2lmaWMgY2FzdGluZyBtZXRob2RzIGJ1dCBpcyBub3QgbmVjZXNzYXJpbHkgZXhwZWN0ZWQgdG8sCisgICAgICogYXMgZGlzY3Vzc2VkIGluIC4gVGhpcyBtZXRob2QgYWxzbyBhbGxvdyB0aGUgaW1wbGVtZW50YXRpb24gdG8KKyAgICAgKiBwcm92aWRlIHNwZWNpYWxpemVkIG9iamVjdHMgd2hpY2ggZG8gbm90IHN1cHBvcnQgdGhlCisgICAgICogPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+IGludGVyZmFjZS4KKyAgICAgKiBAcGFyYW0gZmVhdHVyZSAgVGhlIG5hbWUgb2YgdGhlIGZlYXR1cmUgcmVxdWVzdGVkLiBOb3RlIHRoYXQgYW55IHBsdXMKKyAgICAgKiAgIHNpZ24gIisiIHByZXBlbmRlZCB0byB0aGUgbmFtZSBvZiB0aGUgZmVhdHVyZSB3aWxsIGJlIGlnbm9yZWQgc2luY2UKKyAgICAgKiAgIGl0IGlzIG5vdCBzaWduaWZpY2FudCBpbiB0aGUgY29udGV4dCBvZiB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gdmVyc2lvbiAgVGhpcyBpcyB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4KKyAgICAgKiBAcmV0dXJuICBSZXR1cm5zIGFuIG9iamVjdCB3aGljaCBpbXBsZW1lbnRzIHRoZSBzcGVjaWFsaXplZCBBUElzIG9mCisgICAgICogICB0aGUgc3BlY2lmaWVkIGZlYXR1cmUgYW5kIHZlcnNpb24sIGlmIGFueSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYKKyAgICAgKiAgIHRoZXJlIGlzIG5vIG9iamVjdCB3aGljaCBpbXBsZW1lbnRzIGludGVyZmFjZXMgYXNzb2NpYXRlZCB3aXRoIHRoYXQKKyAgICAgKiAgIGZlYXR1cmUuIElmIHRoZSA8Y29kZT5ET01PYmplY3Q8L2NvZGU+IHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kCisgICAgICogICBpbXBsZW1lbnRzIHRoZSA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbjwvY29kZT4gaW50ZXJmYWNlLCBpdCBtdXN0CisgICAgICogICBkZWxlZ2F0ZSB0byB0aGUgcHJpbWFyeSBjb3JlIDxjb2RlPkRPTUltcGxlbWVudGF0aW9uPC9jb2RlPiBhbmQgbm90CisgICAgICogICByZXR1cm4gcmVzdWx0cyBpbmNvbnNpc3RlbnQgd2l0aCB0aGUgcHJpbWFyeSBjb3JlCisgICAgICogICA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbjwvY29kZT4gc3VjaCBhcyA8Y29kZT5oYXNGZWF0dXJlPC9jb2RlPiwKKyAgICAgKiAgIDxjb2RlPmdldEZlYXR1cmU8L2NvZGU+LCBldGMuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAzCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmVyc2lvbik7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9ET01JbXBsZW1lbnRhdGlvbkxpc3QuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9ET01JbXBsZW1lbnRhdGlvbkxpc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NzdkZTZlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0RPTUltcGxlbWVudGF0aW9uTGlzdC5qYXZhCkBAIC0wLDAgKzEsNDMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKKyAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcworICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKKyAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAorICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgorICoKKyAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbTsKKworLyoqCisgKiAgVGhlIDxjb2RlPkRPTUltcGxlbWVudGF0aW9uTGlzdDwvY29kZT4gaW50ZXJmYWNlIHByb3ZpZGVzIHRoZSBhYnN0cmFjdGlvbgorICogb2YgYW4gb3JkZXJlZCBjb2xsZWN0aW9uIG9mIERPTSBpbXBsZW1lbnRhdGlvbnMsIHdpdGhvdXQgZGVmaW5pbmcgb3IKKyAqIGNvbnN0cmFpbmluZyBob3cgdGhpcyBjb2xsZWN0aW9uIGlzIGltcGxlbWVudGVkLiBUaGUgaXRlbXMgaW4gdGhlCisgKiA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbkxpc3Q8L2NvZGU+IGFyZSBhY2Nlc3NpYmxlIHZpYSBhbiBpbnRlZ3JhbCBpbmRleCwKKyAqIHN0YXJ0aW5nIGZyb20gMC4KKyAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgorICogQHNpbmNlIERPTSBMZXZlbCAzCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRE9NSW1wbGVtZW50YXRpb25MaXN0IHsKKyAgICAvKioKKyAgICAgKiAgUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggaXRlbSBpbiB0aGUgY29sbGVjdGlvbi4gSWYKKyAgICAgKiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YKKyAgICAgKiA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbjwvY29kZT5zIGluIHRoZSBsaXN0LCB0aGlzIHJldHVybnMKKyAgICAgKiA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKiBAcGFyYW0gaW5kZXggSW5kZXggaW50byB0aGUgY29sbGVjdGlvbi4KKyAgICAgKiBAcmV0dXJuICBUaGUgPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+IGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT4KKyAgICAgKiAgIHRoIHBvc2l0aW9uIGluIHRoZSA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbkxpc3Q8L2NvZGU+LCBvcgorICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhhdCBpcyBub3QgYSB2YWxpZCBpbmRleC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb24gaXRlbShpbnQgaW5kZXgpOworCisgICAgLyoqCisgICAgICogIFRoZSBudW1iZXIgb2YgPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+cyBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlCisgICAgICogb2YgdmFsaWQgY2hpbGQgbm9kZSBpbmRpY2VzIGlzIDAgdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vRE9NSW1wbGVtZW50YXRpb25Tb3VyY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9ET01JbXBsZW1lbnRhdGlvblNvdXJjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjNWMwYjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vRE9NSW1wbGVtZW50YXRpb25Tb3VyY2UuamF2YQpAQCAtMCwwICsxLDU4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKgorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCisgKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKKyAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0CisgKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKKyAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KKyAqCisgKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb207CisKKy8qKgorICogVGhpcyBpbnRlcmZhY2UgcGVybWl0cyBhIERPTSBpbXBsZW1lbnRlciB0byBzdXBwbHkgb25lIG9yIG1vcmUKKyAqIGltcGxlbWVudGF0aW9ucywgYmFzZWQgdXBvbiByZXF1ZXN0ZWQgZmVhdHVyZXMgYW5kIHZlcnNpb25zLCBhcyBzcGVjaWZpZWQKKyAqIGluIC4gRWFjaCBpbXBsZW1lbnRlZCA8Y29kZT5ET01JbXBsZW1lbnRhdGlvblNvdXJjZTwvY29kZT4gb2JqZWN0IGlzCisgKiBsaXN0ZWQgaW4gdGhlIGJpbmRpbmctc3BlY2lmaWMgbGlzdCBvZiBhdmFpbGFibGUgc291cmNlcyBzbyB0aGF0IGl0cworICogPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+IG9iamVjdHMgYXJlIG1hZGUgYXZhaWxhYmxlLgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCisgKiBAc2luY2UgRE9NIExldmVsIDMKKyAqLworcHVibGljIGludGVyZmFjZSBET01JbXBsZW1lbnRhdGlvblNvdXJjZSB7CisgICAgLyoqCisgICAgICogIEEgbWV0aG9kIHRvIHJlcXVlc3QgdGhlIGZpcnN0IERPTSBpbXBsZW1lbnRhdGlvbiB0aGF0IHN1cHBvcnRzIHRoZQorICAgICAqIHNwZWNpZmllZCBmZWF0dXJlcy4KKyAgICAgKiBAcGFyYW0gZmVhdHVyZXMgIEEgc3RyaW5nIHRoYXQgc3BlY2lmaWVzIHdoaWNoIGZlYXR1cmVzIGFuZCB2ZXJzaW9ucworICAgICAqICAgYXJlIHJlcXVpcmVkLiBUaGlzIGlzIGEgc3BhY2Ugc2VwYXJhdGVkIGxpc3QgaW4gd2hpY2ggZWFjaCBmZWF0dXJlCisgICAgICogICBpcyBzcGVjaWZpZWQgYnkgaXRzIG5hbWUgb3B0aW9uYWxseSBmb2xsb3dlZCBieSBhIHNwYWNlIGFuZCBhCisgICAgICogICB2ZXJzaW9uIG51bWJlci4gIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIGZpcnN0IGl0ZW0gb2YgdGhlIGxpc3QKKyAgICAgKiAgIHJldHVybmVkIGJ5IDxjb2RlPmdldERPTUltcGxlbWVudGF0aW9uTGlzdDwvY29kZT4uICBBcyBhbiBleGFtcGxlLAorICAgICAqICAgdGhlIHN0cmluZyA8Y29kZT4iWE1MIDMuMCBUcmF2ZXJzYWwgK0V2ZW50cyAyLjAiPC9jb2RlPiB3aWxsCisgICAgICogICByZXF1ZXN0IGEgRE9NIGltcGxlbWVudGF0aW9uIHRoYXQgc3VwcG9ydHMgdGhlIG1vZHVsZSAiWE1MIiBmb3IgaXRzCisgICAgICogICAzLjAgdmVyc2lvbiwgYSBtb2R1bGUgdGhhdCBzdXBwb3J0IG9mIHRoZSAiVHJhdmVyc2FsIiBtb2R1bGUgZm9yCisgICAgICogICBhbnkgdmVyc2lvbiwgYW5kIHRoZSBtb2R1bGUgIkV2ZW50cyIgZm9yIGl0cyAyLjAgdmVyc2lvbi4gVGhlCisgICAgICogICBtb2R1bGUgIkV2ZW50cyIgbXVzdCBiZSBhY2Nlc3NpYmxlIHVzaW5nIHRoZSBtZXRob2QKKyAgICAgKiAgIDxjb2RlPk5vZGUuZ2V0RmVhdHVyZSgpPC9jb2RlPiBhbmQKKyAgICAgKiAgIDxjb2RlPkRPTUltcGxlbWVudGF0aW9uLmdldEZlYXR1cmUoKTwvY29kZT4uCisgICAgICogQHJldHVybiBUaGUgZmlyc3QgRE9NIGltcGxlbWVudGF0aW9uIHRoYXQgc3VwcG9ydCB0aGUgZGVzaXJlZAorICAgICAqICAgZmVhdHVyZXMsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgc291cmNlIGhhcyBub25lLgorICAgICAqLworICAgIHB1YmxpYyBET01JbXBsZW1lbnRhdGlvbiBnZXRET01JbXBsZW1lbnRhdGlvbihTdHJpbmcgZmVhdHVyZXMpOworCisgICAgLyoqCisgICAgICogQSBtZXRob2QgdG8gcmVxdWVzdCBhIGxpc3Qgb2YgRE9NIGltcGxlbWVudGF0aW9ucyB0aGF0IHN1cHBvcnQgdGhlCisgICAgICogc3BlY2lmaWVkIGZlYXR1cmVzIGFuZCB2ZXJzaW9ucywgYXMgc3BlY2lmaWVkIGluIC4KKyAgICAgKiBAcGFyYW0gZmVhdHVyZXMgQSBzdHJpbmcgdGhhdCBzcGVjaWZpZXMgd2hpY2ggZmVhdHVyZXMgYW5kIHZlcnNpb25zCisgICAgICogICBhcmUgcmVxdWlyZWQuIFRoaXMgaXMgYSBzcGFjZSBzZXBhcmF0ZWQgbGlzdCBpbiB3aGljaCBlYWNoIGZlYXR1cmUKKyAgICAgKiAgIGlzIHNwZWNpZmllZCBieSBpdHMgbmFtZSBvcHRpb25hbGx5IGZvbGxvd2VkIGJ5IGEgc3BhY2UgYW5kIGEKKyAgICAgKiAgIHZlcnNpb24gbnVtYmVyLiBUaGlzIGlzIHNvbWV0aGluZyBsaWtlOiAiWE1MIDMuMCBUcmF2ZXJzYWwgK0V2ZW50cworICAgICAqICAgMi4wIgorICAgICAqIEByZXR1cm4gQSBsaXN0IG9mIERPTSBpbXBsZW1lbnRhdGlvbnMgdGhhdCBzdXBwb3J0IHRoZSBkZXNpcmVkCisgICAgICogICBmZWF0dXJlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb25MaXN0IGdldERPTUltcGxlbWVudGF0aW9uTGlzdChTdHJpbmcgZmVhdHVyZXMpOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vRE9NTG9jYXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0RPTUxvY2F0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MGNkN2QyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0RPTUxvY2F0b3IuamF2YQpAQCAtMCwwICsxLDU4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKgorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCisgKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKKyAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0CisgKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKKyAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KKyAqCisgKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb207CisKKy8qKgorICogPGNvZGU+RE9NTG9jYXRvcjwvY29kZT4gaXMgYW4gaW50ZXJmYWNlIHRoYXQgZGVzY3JpYmVzIGEgbG9jYXRpb24gKGUuZy4KKyAqIHdoZXJlIGFuIGVycm9yIG9jY3VycmVkKS4KKyAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgorICogQHNpbmNlIERPTSBMZXZlbCAzCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRE9NTG9jYXRvciB7CisgICAgLyoqCisgICAgICogVGhlIGxpbmUgbnVtYmVyIHRoaXMgbG9jYXRvciBpcyBwb2ludGluZyB0bywgb3IgPGNvZGU+LTE8L2NvZGU+IGlmCisgICAgICogdGhlcmUgaXMgbm8gY29sdW1uIG51bWJlciBhdmFpbGFibGUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29sdW1uIG51bWJlciB0aGlzIGxvY2F0b3IgaXMgcG9pbnRpbmcgdG8sIG9yIDxjb2RlPi0xPC9jb2RlPiBpZgorICAgICAqIHRoZXJlIGlzIG5vIGNvbHVtbiBudW1iZXIgYXZhaWxhYmxlLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uTnVtYmVyKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYnl0ZSBvZmZzZXQgaW50byB0aGUgaW5wdXQgc291cmNlIHRoaXMgbG9jYXRvciBpcyBwb2ludGluZyB0byBvcgorICAgICAqIDxjb2RlPi0xPC9jb2RlPiBpZiB0aGVyZSBpcyBubyBieXRlIG9mZnNldCBhdmFpbGFibGUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRCeXRlT2Zmc2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgVVRGLTE2LCBhcyBkZWZpbmVkIGluIFtVbmljb2RlXSBhbmQgQW1lbmRtZW50IDEgb2YgW0lTTy9JRUMgMTA2NDZdLCBvZmZzZXQgaW50byB0aGUgaW5wdXQgc291cmNlIHRoaXMgbG9jYXRvciBpcyBwb2ludGluZyB0byBvcgorICAgICAqIDxjb2RlPi0xPC9jb2RlPiBpZiB0aGVyZSBpcyBubyBVVEYtMTYgb2Zmc2V0IGF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFV0ZjE2T2Zmc2V0KCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbm9kZSB0aGlzIGxvY2F0b3IgaXMgcG9pbnRpbmcgdG8sIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vIG5vZGUKKyAgICAgKiBpcyBhdmFpbGFibGUuCisgICAgICovCisgICAgcHVibGljIE5vZGUgZ2V0UmVsYXRlZE5vZGUoKTsKKworICAgIC8qKgorICAgICAqIFRoZSBVUkkgdGhpcyBsb2NhdG9yIGlzIHBvaW50aW5nIHRvLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBubyBVUkkgaXMKKyAgICAgKiBhdmFpbGFibGUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRVcmkoKTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0RPTVN0cmluZ0xpc3QuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9ET01TdHJpbmdMaXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTNhNDA5NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9ET01TdHJpbmdMaXN0LmphdmEKQEAgLTAsMCArMSw1MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICoKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgorICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCisgKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAorICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCisgKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisgKgorICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tOworCisvKioKKyAqICBUaGUgPGNvZGU+RE9NU3RyaW5nTGlzdDwvY29kZT4gaW50ZXJmYWNlIHByb3ZpZGVzIHRoZSBhYnN0cmFjdGlvbiBvZiBhbgorICogb3JkZXJlZCBjb2xsZWN0aW9uIG9mIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gdmFsdWVzLCB3aXRob3V0IGRlZmluaW5nIG9yCisgKiBjb25zdHJhaW5pbmcgaG93IHRoaXMgY29sbGVjdGlvbiBpcyBpbXBsZW1lbnRlZC4gVGhlIGl0ZW1zIGluIHRoZQorICogPGNvZGU+RE9NU3RyaW5nTGlzdDwvY29kZT4gYXJlIGFjY2Vzc2libGUgdmlhIGFuIGludGVncmFsIGluZGV4LCBzdGFydGluZworICogZnJvbSAwLgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCisgKiBAc2luY2UgRE9NIExldmVsIDMKKyAqLworcHVibGljIGludGVyZmFjZSBET01TdHJpbmdMaXN0IHsKKyAgICAvKioKKyAgICAgKiAgUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggaXRlbSBpbiB0aGUgY29sbGVjdGlvbi4gSWYKKyAgICAgKiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YKKyAgICAgKiA8Y29kZT5ET01TdHJpbmc8L2NvZGU+cyBpbiB0aGUgbGlzdCwgdGhpcyByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqIEBwYXJhbSBpbmRleCBJbmRleCBpbnRvIHRoZSBjb2xsZWN0aW9uLgorICAgICAqIEByZXR1cm4gIFRoZSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT50aAorICAgICAqICAgcG9zaXRpb24gaW4gdGhlIDxjb2RlPkRPTVN0cmluZ0xpc3Q8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZgorICAgICAqICAgdGhhdCBpcyBub3QgYSB2YWxpZCBpbmRleC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGl0ZW0oaW50IGluZGV4KTsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgPGNvZGU+RE9NU3RyaW5nPC9jb2RlPnMgaW4gdGhlIGxpc3QuIFRoZSByYW5nZSBvZiB2YWxpZAorICAgICAqIGNoaWxkIG5vZGUgaW5kaWNlcyBpcyAwIHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPiBpbmNsdXNpdmUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRMZW5ndGgoKTsKKworICAgIC8qKgorICAgICAqICBUZXN0IGlmIGEgc3RyaW5nIGlzIHBhcnQgb2YgdGhpcyA8Y29kZT5ET01TdHJpbmdMaXN0PC9jb2RlPi4KKyAgICAgKiBAcGFyYW0gc3RyICBUaGUgc3RyaW5nIHRvIGxvb2sgZm9yLgorICAgICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBzdHJpbmcgaGFzIGJlZW4gZm91bmQsCisgICAgICogICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFN0cmluZyBzdHIpOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vRG9jdW1lbnQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9Eb2N1bWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMxOTNmYTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vRG9jdW1lbnQuamF2YQpAQCAtMCwwICsxLDgxNCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICoKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgorICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCisgKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAorICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCisgKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisgKgorICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tOworCisvKioKKyAqIFRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gaW50ZXJmYWNlIHJlcHJlc2VudHMgdGhlIGVudGlyZSBIVE1MIG9yIFhNTAorICogZG9jdW1lbnQuIENvbmNlcHR1YWxseSwgaXQgaXMgdGhlIHJvb3Qgb2YgdGhlIGRvY3VtZW50IHRyZWUsIGFuZCBwcm92aWRlcworICogdGhlIHByaW1hcnkgYWNjZXNzIHRvIHRoZSBkb2N1bWVudCdzIGRhdGEuCisgKiA8cD5TaW5jZSBlbGVtZW50cywgdGV4dCBub2RlcywgY29tbWVudHMsIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zLCBldGMuCisgKiBjYW5ub3QgZXhpc3Qgb3V0c2lkZSB0aGUgY29udGV4dCBvZiBhIDxjb2RlPkRvY3VtZW50PC9jb2RlPiwgdGhlCisgKiA8Y29kZT5Eb2N1bWVudDwvY29kZT4gaW50ZXJmYWNlIGFsc28gY29udGFpbnMgdGhlIGZhY3RvcnkgbWV0aG9kcyBuZWVkZWQKKyAqIHRvIGNyZWF0ZSB0aGVzZSBvYmplY3RzLiBUaGUgPGNvZGU+Tm9kZTwvY29kZT4gb2JqZWN0cyBjcmVhdGVkIGhhdmUgYQorICogPGNvZGU+b3duZXJEb2N1bWVudDwvY29kZT4gYXR0cmlidXRlIHdoaWNoIGFzc29jaWF0ZXMgdGhlbSB3aXRoIHRoZQorICogPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IHdpdGhpbiB3aG9zZSBjb250ZXh0IHRoZXkgd2VyZSBjcmVhdGVkLgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRG9jdW1lbnQgZXh0ZW5kcyBOb2RlIHsKKyAgICAvKioKKyAgICAgKiBUaGUgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbiAoc2VlIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4pCisgICAgICogYXNzb2NpYXRlZCB3aXRoIHRoaXMgZG9jdW1lbnQuIEZvciBYTUwgZG9jdW1lbnRzIHdpdGhvdXQgYSBkb2N1bWVudAorICAgICAqIHR5cGUgZGVjbGFyYXRpb24gdGhpcyByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+LiBGb3IgSFRNTCBkb2N1bWVudHMsCisgICAgICogYSA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IG9iamVjdCBtYXkgYmUgcmV0dXJuZWQsIGluZGVwZW5kZW50bHkgb2YKKyAgICAgKiB0aGUgcHJlc2VuY2Ugb3IgYWJzZW5jZSBvZiBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uIGluIHRoZSBIVE1MCisgICAgICogZG9jdW1lbnQuCisgICAgICogPGJyPlRoaXMgcHJvdmlkZXMgZGlyZWN0IGFjY2VzcyB0byB0aGUgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBub2RlLAorICAgICAqIGNoaWxkIG5vZGUgb2YgdGhpcyA8Y29kZT5Eb2N1bWVudDwvY29kZT4uIFRoaXMgbm9kZSBjYW4gYmUgc2V0IGF0CisgICAgICogZG9jdW1lbnQgY3JlYXRpb24gdGltZSBhbmQgbGF0ZXIgY2hhbmdlZCB0aHJvdWdoIHRoZSB1c2Ugb2YgY2hpbGQKKyAgICAgKiBub2RlcyBtYW5pcHVsYXRpb24gbWV0aG9kcywgc3VjaCBhcyA8Y29kZT5Ob2RlLmluc2VydEJlZm9yZTwvY29kZT4sCisgICAgICogb3IgPGNvZGU+Tm9kZS5yZXBsYWNlQ2hpbGQ8L2NvZGU+LiBOb3RlLCBob3dldmVyLCB0aGF0IHdoaWxlIHNvbWUKKyAgICAgKiBpbXBsZW1lbnRhdGlvbnMgbWF5IGluc3RhbnRpYXRlIGRpZmZlcmVudCB0eXBlcyBvZgorICAgICAqIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBvYmplY3RzIHN1cHBvcnRpbmcgYWRkaXRpb25hbCBmZWF0dXJlcyB0aGFuIHRoZQorICAgICAqICJDb3JlIiwgc3VjaCBhcyAiSFRNTCIgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvUkVDLURPTS1MZXZlbC0yLUhUTUwtMjAwMzAxMDknPkRPTSBMZXZlbCAyIEhUTUw8L2E+XQorICAgICAqICwgYmFzZWQgb24gdGhlIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gc3BlY2lmaWVkIGF0IGNyZWF0aW9uIHRpbWUsCisgICAgICogY2hhbmdpbmcgaXQgYWZ0ZXJ3YXJkcyBpcyB2ZXJ5IHVubGlrZWx5IHRvIHJlc3VsdCBpbiBhIGNoYW5nZSBvZiB0aGUKKyAgICAgKiBmZWF0dXJlcyBzdXBwb3J0ZWQuCisgICAgICogQHZlcnNpb24gRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgRG9jdW1lbnRUeXBlIGdldERvY3R5cGUoKTsKKworICAgIC8qKgorICAgICAqIFRoZSA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbjwvY29kZT4gb2JqZWN0IHRoYXQgaGFuZGxlcyB0aGlzIGRvY3VtZW50LiBBCisgICAgICogRE9NIGFwcGxpY2F0aW9uIG1heSB1c2Ugb2JqZWN0cyBmcm9tIG11bHRpcGxlIGltcGxlbWVudGF0aW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb24gZ2V0SW1wbGVtZW50YXRpb24oKTsKKworICAgIC8qKgorICAgICAqIFRoaXMgaXMgYSBjb252ZW5pZW5jZSBhdHRyaWJ1dGUgdGhhdCBhbGxvd3MgZGlyZWN0IGFjY2VzcyB0byB0aGUgY2hpbGQKKyAgICAgKiBub2RlIHRoYXQgaXMgdGhlIGRvY3VtZW50IGVsZW1lbnQgb2YgdGhlIGRvY3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBFbGVtZW50IGdldERvY3VtZW50RWxlbWVudCgpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBlbGVtZW50IG9mIHRoZSB0eXBlIHNwZWNpZmllZC4gTm90ZSB0aGF0IHRoZSBpbnN0YW5jZQorICAgICAqIHJldHVybmVkIGltcGxlbWVudHMgdGhlIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IGludGVyZmFjZSwgc28gYXR0cmlidXRlcworICAgICAqIGNhbiBiZSBzcGVjaWZpZWQgZGlyZWN0bHkgb24gdGhlIHJldHVybmVkIG9iamVjdC4KKyAgICAgKiA8YnI+SW4gYWRkaXRpb24sIGlmIHRoZXJlIGFyZSBrbm93biBhdHRyaWJ1dGVzIHdpdGggZGVmYXVsdCB2YWx1ZXMsCisgICAgICogPGNvZGU+QXR0cjwvY29kZT4gbm9kZXMgcmVwcmVzZW50aW5nIHRoZW0gYXJlIGF1dG9tYXRpY2FsbHkgY3JlYXRlZAorICAgICAqIGFuZCBhdHRhY2hlZCB0byB0aGUgZWxlbWVudC4KKyAgICAgKiA8YnI+VG8gY3JlYXRlIGFuIGVsZW1lbnQgd2l0aCBhIHF1YWxpZmllZCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLCB1c2UKKyAgICAgKiB0aGUgPGNvZGU+Y3JlYXRlRWxlbWVudE5TPC9jb2RlPiBtZXRob2QuCisgICAgICogQHBhcmFtIHRhZ05hbWUgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQgdHlwZSB0byBpbnN0YW50aWF0ZS4gRm9yIFhNTCwKKyAgICAgKiAgIHRoaXMgaXMgY2FzZS1zZW5zaXRpdmUsIG90aGVyd2lzZSBpdCBkZXBlbmRzIG9uIHRoZQorICAgICAqICAgY2FzZS1zZW5zaXRpdml0eSBvZiB0aGUgbWFya3VwIGxhbmd1YWdlIGluIHVzZS4gSW4gdGhhdCBjYXNlLCB0aGUKKyAgICAgKiAgIG5hbWUgaXMgbWFwcGVkIHRvIHRoZSBjYW5vbmljYWwgZm9ybSBvZiB0aGF0IG1hcmt1cCBieSB0aGUgRE9NCisgICAgICogICBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKiBAcmV0dXJuIEEgbmV3IDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG9iamVjdCB3aXRoIHRoZQorICAgICAqICAgPGNvZGU+bm9kZU5hbWU8L2NvZGU+IGF0dHJpYnV0ZSBzZXQgdG8gPGNvZGU+dGFnTmFtZTwvY29kZT4sIGFuZAorICAgICAqICAgPGNvZGU+bG9jYWxOYW1lPC9jb2RlPiwgPGNvZGU+cHJlZml4PC9jb2RlPiwgYW5kCisgICAgICogICA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IHNldCB0byA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgSU5WQUxJRF9DSEFSQUNURVJfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBuYW1lIGlzIG5vdCBhbiBYTUwKKyAgICAgKiAgIG5hbWUgYWNjb3JkaW5nIHRvIHRoZSBYTUwgdmVyc2lvbiBpbiB1c2Ugc3BlY2lmaWVkIGluIHRoZQorICAgICAqICAgPGNvZGU+RG9jdW1lbnQueG1sVmVyc2lvbjwvY29kZT4gYXR0cmlidXRlLgorICAgICAqLworICAgIHB1YmxpYyBFbGVtZW50IGNyZWF0ZUVsZW1lbnQoU3RyaW5nIHRhZ05hbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBlbXB0eSA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBvYmplY3QuCisgICAgICogQHJldHVybiBBIG5ldyA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgRG9jdW1lbnRGcmFnbWVudCBjcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgPGNvZGU+VGV4dDwvY29kZT4gbm9kZSBnaXZlbiB0aGUgc3BlY2lmaWVkIHN0cmluZy4KKyAgICAgKiBAcGFyYW0gZGF0YSBUaGUgZGF0YSBmb3IgdGhlIG5vZGUuCisgICAgICogQHJldHVybiBUaGUgbmV3IDxjb2RlPlRleHQ8L2NvZGU+IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGV4dCBjcmVhdGVUZXh0Tm9kZShTdHJpbmcgZGF0YSk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgPGNvZGU+Q29tbWVudDwvY29kZT4gbm9kZSBnaXZlbiB0aGUgc3BlY2lmaWVkIHN0cmluZy4KKyAgICAgKiBAcGFyYW0gZGF0YSBUaGUgZGF0YSBmb3IgdGhlIG5vZGUuCisgICAgICogQHJldHVybiBUaGUgbmV3IDxjb2RlPkNvbW1lbnQ8L2NvZGU+IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29tbWVudCBjcmVhdGVDb21tZW50KFN0cmluZyBkYXRhKTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+IG5vZGUgd2hvc2UgdmFsdWUgaXMgdGhlIHNwZWNpZmllZAorICAgICAqIHN0cmluZy4KKyAgICAgKiBAcGFyYW0gZGF0YSBUaGUgZGF0YSBmb3IgdGhlIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gY29udGVudHMuCisgICAgICogQHJldHVybiBUaGUgbmV3IDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gb2JqZWN0LgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBOT1RfU1VQUE9SVEVEX0VSUjogUmFpc2VkIGlmIHRoaXMgZG9jdW1lbnQgaXMgYW4gSFRNTCBkb2N1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ0RBVEFTZWN0aW9uIGNyZWF0ZUNEQVRBU2VjdGlvbihTdHJpbmcgZGF0YSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIDxjb2RlPlByb2Nlc3NpbmdJbnN0cnVjdGlvbjwvY29kZT4gbm9kZSBnaXZlbiB0aGUgc3BlY2lmaWVkCisgICAgICogbmFtZSBhbmQgZGF0YSBzdHJpbmdzLgorICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCBwYXJ0IG9mIHRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLlVubGlrZQorICAgICAqICAgPGNvZGU+RG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TPC9jb2RlPiBvcgorICAgICAqICAgPGNvZGU+RG9jdW1lbnQuY3JlYXRlQXR0cmlidXRlTlM8L2NvZGU+LCBubyBuYW1lc3BhY2Ugd2VsbC1mb3JtZWQKKyAgICAgKiAgIGNoZWNraW5nIGlzIGRvbmUgb24gdGhlIHRhcmdldCBuYW1lLiBBcHBsaWNhdGlvbnMgc2hvdWxkIGludm9rZQorICAgICAqICAgPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4gd2l0aCB0aGUgcGFyYW1ldGVyICIKKyAgICAgKiAgIG5hbWVzcGFjZXMiIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiBpbiBvcmRlciB0byBlbnN1cmUgdGhhdCB0aGUKKyAgICAgKiAgIHRhcmdldCBuYW1lIGlzIG5hbWVzcGFjZSB3ZWxsLWZvcm1lZC4KKyAgICAgKiBAcGFyYW0gZGF0YSBUaGUgZGF0YSBmb3IgdGhlIG5vZGUuCisgICAgICogQHJldHVybiBUaGUgbmV3IDxjb2RlPlByb2Nlc3NpbmdJbnN0cnVjdGlvbjwvY29kZT4gb2JqZWN0LgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBJTlZBTElEX0NIQVJBQ1RFUl9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIHRhcmdldCBpcyBub3QgYW4gWE1MCisgICAgICogICBuYW1lIGFjY29yZGluZyB0byB0aGUgWE1MIHZlcnNpb24gaW4gdXNlIHNwZWNpZmllZCBpbiB0aGUKKyAgICAgKiAgIDxjb2RlPkRvY3VtZW50LnhtbFZlcnNpb248L2NvZGU+IGF0dHJpYnV0ZS4KKyAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogUmFpc2VkIGlmIHRoaXMgZG9jdW1lbnQgaXMgYW4gSFRNTCBkb2N1bWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvY2Vzc2luZ0luc3RydWN0aW9uIGNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBkYXRhKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIDxjb2RlPkF0dHI8L2NvZGU+IG9mIHRoZSBnaXZlbiBuYW1lLiBOb3RlIHRoYXQgdGhlCisgICAgICogPGNvZGU+QXR0cjwvY29kZT4gaW5zdGFuY2UgY2FuIHRoZW4gYmUgc2V0IG9uIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+CisgICAgICogdXNpbmcgdGhlIDxjb2RlPnNldEF0dHJpYnV0ZU5vZGU8L2NvZGU+IG1ldGhvZC4KKyAgICAgKiA8YnI+VG8gY3JlYXRlIGFuIGF0dHJpYnV0ZSB3aXRoIGEgcXVhbGlmaWVkIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkksIHVzZQorICAgICAqIHRoZSA8Y29kZT5jcmVhdGVBdHRyaWJ1dGVOUzwvY29kZT4gbWV0aG9kLgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCisgICAgICogQHJldHVybiBBIG5ldyA8Y29kZT5BdHRyPC9jb2RlPiBvYmplY3Qgd2l0aCB0aGUgPGNvZGU+bm9kZU5hbWU8L2NvZGU+CisgICAgICogICBhdHRyaWJ1dGUgc2V0IHRvIDxjb2RlPm5hbWU8L2NvZGU+LCBhbmQgPGNvZGU+bG9jYWxOYW1lPC9jb2RlPiwKKyAgICAgKiAgIDxjb2RlPnByZWZpeDwvY29kZT4sIGFuZCA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IHNldCB0bworICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4uIFRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlIGlzIHRoZSBlbXB0eSBzdHJpbmcuCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIElOVkFMSURfQ0hBUkFDVEVSX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgbmFtZSBpcyBub3QgYW4gWE1MCisgICAgICogICBuYW1lIGFjY29yZGluZyB0byB0aGUgWE1MIHZlcnNpb24gaW4gdXNlIHNwZWNpZmllZCBpbiB0aGUKKyAgICAgKiAgIDxjb2RlPkRvY3VtZW50LnhtbFZlcnNpb248L2NvZGU+IGF0dHJpYnV0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXR0ciBjcmVhdGVBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gb2JqZWN0LiBJbiBhZGRpdGlvbiwgaWYgdGhlCisgICAgICogcmVmZXJlbmNlZCBlbnRpdHkgaXMga25vd24sIHRoZSBjaGlsZCBsaXN0IG9mIHRoZQorICAgICAqIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZSBpcyBtYWRlIHRoZSBzYW1lIGFzIHRoYXQgb2YgdGhlCisgICAgICogY29ycmVzcG9uZGluZyA8Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGUuCisgICAgICogPHAgPjxiPk5vdGU6PC9iPiBJZiBhbnkgZGVzY2VuZGFudCBvZiB0aGUgPGNvZGU+RW50aXR5PC9jb2RlPiBub2RlIGhhcworICAgICAqIGFuIHVuYm91bmQgbmFtZXNwYWNlIHByZWZpeCwgdGhlIGNvcnJlc3BvbmRpbmcgZGVzY2VuZGFudCBvZiB0aGUKKyAgICAgKiBjcmVhdGVkIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZSBpcyBhbHNvIHVuYm91bmQ7IChpdHMKKyAgICAgKiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+KS4gVGhlIERPTSBMZXZlbCAyIGFuZAorICAgICAqIDMgZG8gbm90IHN1cHBvcnQgYW55IG1lY2hhbmlzbSB0byByZXNvbHZlIG5hbWVzcGFjZSBwcmVmaXhlcyBpbiB0aGlzCisgICAgICogY2FzZS4KKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5IHRvIHJlZmVyZW5jZS5Vbmxpa2UKKyAgICAgKiAgIDxjb2RlPkRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUzwvY29kZT4gb3IKKyAgICAgKiAgIDxjb2RlPkRvY3VtZW50LmNyZWF0ZUF0dHJpYnV0ZU5TPC9jb2RlPiwgbm8gbmFtZXNwYWNlIHdlbGwtZm9ybWVkCisgICAgICogICBjaGVja2luZyBpcyBkb25lIG9uIHRoZSBlbnRpdHkgbmFtZS4gQXBwbGljYXRpb25zIHNob3VsZCBpbnZva2UKKyAgICAgKiAgIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk8L2NvZGU+IHdpdGggdGhlIHBhcmFtZXRlciAiCisgICAgICogICBuYW1lc3BhY2VzIiBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4gaW4gb3JkZXIgdG8gZW5zdXJlIHRoYXQgdGhlCisgICAgICogICBlbnRpdHkgbmFtZSBpcyBuYW1lc3BhY2Ugd2VsbC1mb3JtZWQuCisgICAgICogQHJldHVybiBUaGUgbmV3IDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gb2JqZWN0LgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBJTlZBTElEX0NIQVJBQ1RFUl9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIG5hbWUgaXMgbm90IGFuIFhNTAorICAgICAqICAgbmFtZSBhY2NvcmRpbmcgdG8gdGhlIFhNTCB2ZXJzaW9uIGluIHVzZSBzcGVjaWZpZWQgaW4gdGhlCisgICAgICogICA8Y29kZT5Eb2N1bWVudC54bWxWZXJzaW9uPC9jb2RlPiBhdHRyaWJ1dGUuCisgICAgICogICA8YnI+Tk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIGRvY3VtZW50IGlzIGFuIEhUTUwgZG9jdW1lbnQuCisgICAgICovCisgICAgcHVibGljIEVudGl0eVJlZmVyZW5jZSBjcmVhdGVFbnRpdHlSZWZlcmVuY2UoU3RyaW5nIG5hbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSA8Y29kZT5Ob2RlTGlzdDwvY29kZT4gb2YgYWxsIHRoZSA8Y29kZT5FbGVtZW50czwvY29kZT4gaW4KKyAgICAgKiBkb2N1bWVudCBvcmRlciB3aXRoIGEgZ2l2ZW4gdGFnIG5hbWUgYW5kIGFyZSBjb250YWluZWQgaW4gdGhlCisgICAgICogZG9jdW1lbnQuCisgICAgICogQHBhcmFtIHRhZ25hbWUgIFRoZSBuYW1lIG9mIHRoZSB0YWcgdG8gbWF0Y2ggb24uIFRoZSBzcGVjaWFsIHZhbHVlICIqIgorICAgICAqICAgbWF0Y2hlcyBhbGwgdGFncy4gRm9yIFhNTCwgdGhlIDxjb2RlPnRhZ25hbWU8L2NvZGU+IHBhcmFtZXRlciBpcworICAgICAqICAgY2FzZS1zZW5zaXRpdmUsIG90aGVyd2lzZSBpdCBkZXBlbmRzIG9uIHRoZSBjYXNlLXNlbnNpdGl2aXR5IG9mIHRoZQorICAgICAqICAgbWFya3VwIGxhbmd1YWdlIGluIHVzZS4KKyAgICAgKiBAcmV0dXJuIEEgbmV3IDxjb2RlPk5vZGVMaXN0PC9jb2RlPiBvYmplY3QgY29udGFpbmluZyBhbGwgdGhlIG1hdGNoZWQKKyAgICAgKiAgIDxjb2RlPkVsZW1lbnRzPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9kZUxpc3QgZ2V0RWxlbWVudHNCeVRhZ05hbWUoU3RyaW5nIHRhZ25hbWUpOworCisgICAgLyoqCisgICAgICogSW1wb3J0cyBhIG5vZGUgZnJvbSBhbm90aGVyIGRvY3VtZW50IHRvIHRoaXMgZG9jdW1lbnQsIHdpdGhvdXQgYWx0ZXJpbmcKKyAgICAgKiBvciByZW1vdmluZyB0aGUgc291cmNlIG5vZGUgZnJvbSB0aGUgb3JpZ2luYWwgZG9jdW1lbnQ7IHRoaXMgbWV0aG9kCisgICAgICogY3JlYXRlcyBhIG5ldyBjb3B5IG9mIHRoZSBzb3VyY2Ugbm9kZS4gVGhlIHJldHVybmVkIG5vZGUgaGFzIG5vCisgICAgICogcGFyZW50OyAoPGNvZGU+cGFyZW50Tm9kZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4pLgorICAgICAqIDxicj5Gb3IgYWxsIG5vZGVzLCBpbXBvcnRpbmcgYSBub2RlIGNyZWF0ZXMgYSBub2RlIG9iamVjdCBvd25lZCBieSB0aGUKKyAgICAgKiBpbXBvcnRpbmcgZG9jdW1lbnQsIHdpdGggYXR0cmlidXRlIHZhbHVlcyBpZGVudGljYWwgdG8gdGhlIHNvdXJjZQorICAgICAqIG5vZGUncyA8Y29kZT5ub2RlTmFtZTwvY29kZT4gYW5kIDxjb2RlPm5vZGVUeXBlPC9jb2RlPiwgcGx1cyB0aGUKKyAgICAgKiBhdHRyaWJ1dGVzIHJlbGF0ZWQgdG8gbmFtZXNwYWNlcyAoPGNvZGU+cHJlZml4PC9jb2RlPiwKKyAgICAgKiA8Y29kZT5sb2NhbE5hbWU8L2NvZGU+LCBhbmQgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPikuIEFzIGluIHRoZQorICAgICAqIDxjb2RlPmNsb25lTm9kZTwvY29kZT4gb3BlcmF0aW9uLCB0aGUgc291cmNlIG5vZGUgaXMgbm90IGFsdGVyZWQuCisgICAgICogVXNlciBkYXRhIGFzc29jaWF0ZWQgdG8gdGhlIGltcG9ydGVkIG5vZGUgaXMgbm90IGNhcnJpZWQgb3Zlci4KKyAgICAgKiBIb3dldmVyLCBpZiBhbnkgPGNvZGU+VXNlckRhdGFIYW5kbGVyczwvY29kZT4gaGFzIGJlZW4gc3BlY2lmaWVkCisgICAgICogYWxvbmcgd2l0aCB0aGUgYXNzb2NpYXRlZCBkYXRhIHRoZXNlIGhhbmRsZXJzIHdpbGwgYmUgY2FsbGVkIHdpdGggdGhlCisgICAgICogYXBwcm9wcmlhdGUgcGFyYW1ldGVycyBiZWZvcmUgdGhpcyBtZXRob2QgcmV0dXJucy4KKyAgICAgKiA8YnI+QWRkaXRpb25hbCBpbmZvcm1hdGlvbiBpcyBjb3BpZWQgYXMgYXBwcm9wcmlhdGUgdG8gdGhlCisgICAgICogPGNvZGU+bm9kZVR5cGU8L2NvZGU+LCBhdHRlbXB0aW5nIHRvIG1pcnJvciB0aGUgYmVoYXZpb3IgZXhwZWN0ZWQgaWYKKyAgICAgKiBhIGZyYWdtZW50IG9mIFhNTCBvciBIVE1MIHNvdXJjZSB3YXMgY29waWVkIGZyb20gb25lIGRvY3VtZW50IHRvCisgICAgICogYW5vdGhlciwgcmVjb2duaXppbmcgdGhhdCB0aGUgdHdvIGRvY3VtZW50cyBtYXkgaGF2ZSBkaWZmZXJlbnQgRFREcworICAgICAqIGluIHRoZSBYTUwgY2FzZS4gVGhlIGZvbGxvd2luZyBsaXN0IGRlc2NyaWJlcyB0aGUgc3BlY2lmaWNzIGZvciBlYWNoCisgICAgICogdHlwZSBvZiBub2RlLgorICAgICAqIDxkbD4KKyAgICAgKiA8ZHQ+QVRUUklCVVRFX05PREU8L2R0PgorICAgICAqIDxkZD5UaGUgPGNvZGU+b3duZXJFbGVtZW50PC9jb2RlPiBhdHRyaWJ1dGUKKyAgICAgKiBpcyBzZXQgdG8gPGNvZGU+bnVsbDwvY29kZT4gYW5kIHRoZSA8Y29kZT5zcGVjaWZpZWQ8L2NvZGU+IGZsYWcgaXMKKyAgICAgKiBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4gb24gdGhlIGdlbmVyYXRlZCA8Y29kZT5BdHRyPC9jb2RlPi4gVGhlCisgICAgICogZGVzY2VuZGFudHMgb2YgdGhlIHNvdXJjZSA8Y29kZT5BdHRyPC9jb2RlPiBhcmUgcmVjdXJzaXZlbHkgaW1wb3J0ZWQKKyAgICAgKiBhbmQgdGhlIHJlc3VsdGluZyBub2RlcyByZWFzc2VtYmxlZCB0byBmb3JtIHRoZSBjb3JyZXNwb25kaW5nIHN1YnRyZWUuCisgICAgICogTm90ZSB0aGF0IHRoZSA8Y29kZT5kZWVwPC9jb2RlPiBwYXJhbWV0ZXIgaGFzIG5vIGVmZmVjdCBvbgorICAgICAqIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzOyB0aGV5IGFsd2F5cyBjYXJyeSB0aGVpciBjaGlsZHJlbiB3aXRoIHRoZW0KKyAgICAgKiB3aGVuIGltcG9ydGVkLjwvZGQ+CisgICAgICogPGR0PkRPQ1VNRU5UX0ZSQUdNRU5UX05PREU8L2R0PgorICAgICAqIDxkZD5JZiB0aGUgPGNvZGU+ZGVlcDwvY29kZT4gb3B0aW9uCisgICAgICogd2FzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiwgdGhlIGRlc2NlbmRhbnRzIG9mIHRoZSBzb3VyY2UKKyAgICAgKiA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBhcmUgcmVjdXJzaXZlbHkgaW1wb3J0ZWQgYW5kIHRoZQorICAgICAqIHJlc3VsdGluZyBub2RlcyByZWFzc2VtYmxlZCB1bmRlciB0aGUgaW1wb3J0ZWQKKyAgICAgKiA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiB0byBmb3JtIHRoZSBjb3JyZXNwb25kaW5nIHN1YnRyZWUuCisgICAgICogT3RoZXJ3aXNlLCB0aGlzIHNpbXBseSBnZW5lcmF0ZXMgYW4gZW1wdHkKKyAgICAgKiA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPi48L2RkPgorICAgICAqIDxkdD5ET0NVTUVOVF9OT0RFPC9kdD4KKyAgICAgKiA8ZGQ+PGNvZGU+RG9jdW1lbnQ8L2NvZGU+CisgICAgICogbm9kZXMgY2Fubm90IGJlIGltcG9ydGVkLjwvZGQ+CisgICAgICogPGR0PkRPQ1VNRU5UX1RZUEVfTk9ERTwvZHQ+CisgICAgICogPGRkPjxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4KKyAgICAgKiBub2RlcyBjYW5ub3QgYmUgaW1wb3J0ZWQuPC9kZD4KKyAgICAgKiA8ZHQ+RUxFTUVOVF9OT0RFPC9kdD4KKyAgICAgKiA8ZGQ+PGVtPlNwZWNpZmllZDwvZW0+IGF0dHJpYnV0ZSBub2RlcyBvZiB0aGUgc291cmNlIGVsZW1lbnQgYXJlIGltcG9ydGVkLCBhbmQgdGhlIGdlbmVyYXRlZAorICAgICAqIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzIGFyZSBhdHRhY2hlZCB0byB0aGUgZ2VuZXJhdGVkCisgICAgICogPGNvZGU+RWxlbWVudDwvY29kZT4uIERlZmF1bHQgYXR0cmlidXRlcyBhcmUgPGVtPm5vdDwvZW0+IGNvcGllZCwgdGhvdWdoIGlmIHRoZSBkb2N1bWVudCBiZWluZyBpbXBvcnRlZCBpbnRvIGRlZmluZXMgZGVmYXVsdAorICAgICAqIGF0dHJpYnV0ZXMgZm9yIHRoaXMgZWxlbWVudCBuYW1lLCB0aG9zZSBhcmUgYXNzaWduZWQuIElmIHRoZQorICAgICAqIDxjb2RlPmltcG9ydE5vZGU8L2NvZGU+IDxjb2RlPmRlZXA8L2NvZGU+IHBhcmFtZXRlciB3YXMgc2V0IHRvCisgICAgICogPGNvZGU+dHJ1ZTwvY29kZT4sIHRoZSBkZXNjZW5kYW50cyBvZiB0aGUgc291cmNlIGVsZW1lbnQgYXJlCisgICAgICogcmVjdXJzaXZlbHkgaW1wb3J0ZWQgYW5kIHRoZSByZXN1bHRpbmcgbm9kZXMgcmVhc3NlbWJsZWQgdG8gZm9ybSB0aGUKKyAgICAgKiBjb3JyZXNwb25kaW5nIHN1YnRyZWUuPC9kZD4KKyAgICAgKiA8ZHQ+RU5USVRZX05PREU8L2R0PgorICAgICAqIDxkZD48Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGVzIGNhbiBiZQorICAgICAqIGltcG9ydGVkLCBob3dldmVyIGluIHRoZSBjdXJyZW50IHJlbGVhc2Ugb2YgdGhlIERPTSB0aGUKKyAgICAgKiA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IGlzIHJlYWRvbmx5LiBBYmlsaXR5IHRvIGFkZCB0aGVzZSBpbXBvcnRlZAorICAgICAqIG5vZGVzIHRvIGEgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiB3aWxsIGJlIGNvbnNpZGVyZWQgZm9yIGFkZGl0aW9uCisgICAgICogdG8gYSBmdXR1cmUgcmVsZWFzZSBvZiB0aGUgRE9NLk9uIGltcG9ydCwgdGhlIDxjb2RlPnB1YmxpY0lkPC9jb2RlPiwKKyAgICAgKiA8Y29kZT5zeXN0ZW1JZDwvY29kZT4sIGFuZCA8Y29kZT5ub3RhdGlvbk5hbWU8L2NvZGU+IGF0dHJpYnV0ZXMgYXJlCisgICAgICogY29waWVkLiBJZiBhIDxjb2RlPmRlZXA8L2NvZGU+IGltcG9ydCBpcyByZXF1ZXN0ZWQsIHRoZSBkZXNjZW5kYW50cworICAgICAqIG9mIHRoZSB0aGUgc291cmNlIDxjb2RlPkVudGl0eTwvY29kZT4gYXJlIHJlY3Vyc2l2ZWx5IGltcG9ydGVkIGFuZAorICAgICAqIHRoZSByZXN1bHRpbmcgbm9kZXMgcmVhc3NlbWJsZWQgdG8gZm9ybSB0aGUgY29ycmVzcG9uZGluZyBzdWJ0cmVlLjwvZGQ+CisgICAgICogPGR0PgorICAgICAqIEVOVElUWV9SRUZFUkVOQ0VfTk9ERTwvZHQ+CisgICAgICogPGRkPk9ubHkgdGhlIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gaXRzZWxmIGlzCisgICAgICogY29waWVkLCBldmVuIGlmIGEgPGNvZGU+ZGVlcDwvY29kZT4gaW1wb3J0IGlzIHJlcXVlc3RlZCwgc2luY2UgdGhlCisgICAgICogc291cmNlIGFuZCBkZXN0aW5hdGlvbiBkb2N1bWVudHMgbWlnaHQgaGF2ZSBkZWZpbmVkIHRoZSBlbnRpdHkKKyAgICAgKiBkaWZmZXJlbnRseS4gSWYgdGhlIGRvY3VtZW50IGJlaW5nIGltcG9ydGVkIGludG8gcHJvdmlkZXMgYQorICAgICAqIGRlZmluaXRpb24gZm9yIHRoaXMgZW50aXR5IG5hbWUsIGl0cyB2YWx1ZSBpcyBhc3NpZ25lZC48L2RkPgorICAgICAqIDxkdD5OT1RBVElPTl9OT0RFPC9kdD4KKyAgICAgKiA8ZGQ+CisgICAgICogPGNvZGU+Tm90YXRpb248L2NvZGU+IG5vZGVzIGNhbiBiZSBpbXBvcnRlZCwgaG93ZXZlciBpbiB0aGUgY3VycmVudAorICAgICAqIHJlbGVhc2Ugb2YgdGhlIERPTSB0aGUgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBpcyByZWFkb25seS4gQWJpbGl0eQorICAgICAqIHRvIGFkZCB0aGVzZSBpbXBvcnRlZCBub2RlcyB0byBhIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gd2lsbCBiZQorICAgICAqIGNvbnNpZGVyZWQgZm9yIGFkZGl0aW9uIHRvIGEgZnV0dXJlIHJlbGVhc2Ugb2YgdGhlIERPTS5PbiBpbXBvcnQsIHRoZQorICAgICAqIDxjb2RlPnB1YmxpY0lkPC9jb2RlPiBhbmQgPGNvZGU+c3lzdGVtSWQ8L2NvZGU+IGF0dHJpYnV0ZXMgYXJlIGNvcGllZC4KKyAgICAgKiBOb3RlIHRoYXQgdGhlIDxjb2RlPmRlZXA8L2NvZGU+IHBhcmFtZXRlciBoYXMgbm8gZWZmZWN0IG9uIHRoaXMgdHlwZQorICAgICAqIG9mIG5vZGVzIHNpbmNlIHRoZXkgY2Fubm90IGhhdmUgYW55IGNoaWxkcmVuLjwvZGQ+CisgICAgICogPGR0PgorICAgICAqIFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTwvZHQ+CisgICAgICogPGRkPlRoZSBpbXBvcnRlZCBub2RlIGNvcGllcyBpdHMKKyAgICAgKiA8Y29kZT50YXJnZXQ8L2NvZGU+IGFuZCA8Y29kZT5kYXRhPC9jb2RlPiB2YWx1ZXMgZnJvbSB0aG9zZSBvZiB0aGUKKyAgICAgKiBzb3VyY2Ugbm9kZS5Ob3RlIHRoYXQgdGhlIDxjb2RlPmRlZXA8L2NvZGU+IHBhcmFtZXRlciBoYXMgbm8gZWZmZWN0CisgICAgICogb24gdGhpcyB0eXBlIG9mIG5vZGVzIHNpbmNlIHRoZXkgY2Fubm90IGhhdmUgYW55IGNoaWxkcmVuLjwvZGQ+CisgICAgICogPGR0PlRFWFRfTk9ERSwKKyAgICAgKiBDREFUQV9TRUNUSU9OX05PREUsIENPTU1FTlRfTk9ERTwvZHQ+CisgICAgICogPGRkPlRoZXNlIHRocmVlIHR5cGVzIG9mIG5vZGVzIGluaGVyaXRpbmcKKyAgICAgKiBmcm9tIDxjb2RlPkNoYXJhY3RlckRhdGE8L2NvZGU+IGNvcHkgdGhlaXIgPGNvZGU+ZGF0YTwvY29kZT4gYW5kCisgICAgICogPGNvZGU+bGVuZ3RoPC9jb2RlPiBhdHRyaWJ1dGVzIGZyb20gdGhvc2Ugb2YgdGhlIHNvdXJjZSBub2RlLk5vdGUKKyAgICAgKiB0aGF0IHRoZSA8Y29kZT5kZWVwPC9jb2RlPiBwYXJhbWV0ZXIgaGFzIG5vIGVmZmVjdCBvbiB0aGVzZSB0eXBlcyBvZgorICAgICAqIG5vZGVzIHNpbmNlIHRoZXkgY2Fubm90IGhhdmUgYW55IGNoaWxkcmVuLjwvZGQ+CisgICAgICogPC9kbD4KKyAgICAgKiBAcGFyYW0gaW1wb3J0ZWROb2RlIFRoZSBub2RlIHRvIGltcG9ydC4KKyAgICAgKiBAcGFyYW0gZGVlcCBJZiA8Y29kZT50cnVlPC9jb2RlPiwgcmVjdXJzaXZlbHkgaW1wb3J0IHRoZSBzdWJ0cmVlIHVuZGVyCisgICAgICogICB0aGUgc3BlY2lmaWVkIG5vZGU7IGlmIDxjb2RlPmZhbHNlPC9jb2RlPiwgaW1wb3J0IG9ubHkgdGhlIG5vZGUKKyAgICAgKiAgIGl0c2VsZiwgYXMgZXhwbGFpbmVkIGFib3ZlLiBUaGlzIGhhcyBubyBlZmZlY3Qgb24gbm9kZXMgdGhhdCBjYW5ub3QKKyAgICAgKiAgIGhhdmUgYW55IGNoaWxkcmVuLCBhbmQgb24gPGNvZGU+QXR0cjwvY29kZT4sIGFuZAorICAgICAqICAgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2Rlcy4KKyAgICAgKiBAcmV0dXJuIFRoZSBpbXBvcnRlZCBub2RlIHRoYXQgYmVsb25ncyB0byB0aGlzIDxjb2RlPkRvY3VtZW50PC9jb2RlPi4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGUgdHlwZSBvZiBub2RlIGJlaW5nIGltcG9ydGVkIGlzIG5vdAorICAgICAqICAgc3VwcG9ydGVkLgorICAgICAqICAgPGJyPklOVkFMSURfQ0hBUkFDVEVSX0VSUjogUmFpc2VkIGlmIG9uZSBvZiB0aGUgaW1wb3J0ZWQgbmFtZXMgaXMgbm90CisgICAgICogICBhbiBYTUwgbmFtZSBhY2NvcmRpbmcgdG8gdGhlIFhNTCB2ZXJzaW9uIGluIHVzZSBzcGVjaWZpZWQgaW4gdGhlCisgICAgICogICA8Y29kZT5Eb2N1bWVudC54bWxWZXJzaW9uPC9jb2RlPiBhdHRyaWJ1dGUuIFRoaXMgbWF5IGhhcHBlbiB3aGVuCisgICAgICogICBpbXBvcnRpbmcgYW4gWE1MIDEuMSBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sMTEtMjAwNDAyMDQvJz5YTUwgMS4xPC9hPl0gZWxlbWVudAorICAgICAqICAgaW50byBhbiBYTUwgMS4wIGRvY3VtZW50LCBmb3IgaW5zdGFuY2UuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAyCisgICAgICovCisgICAgcHVibGljIE5vZGUgaW1wb3J0Tm9kZShOb2RlIGltcG9ydGVkTm9kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZGVlcCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGVsZW1lbnQgb2YgdGhlIGdpdmVuIHF1YWxpZmllZCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLgorICAgICAqIDxicj5QZXIgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNC8nPlhNTCBOYW1lc3BhY2VzPC9hPl0KKyAgICAgKiAsIGFwcGxpY2F0aW9ucyBtdXN0IHVzZSB0aGUgdmFsdWUgPGNvZGU+bnVsbDwvY29kZT4gYXMgdGhlCisgICAgICogbmFtZXNwYWNlVVJJIHBhcmFtZXRlciBmb3IgbWV0aG9kcyBpZiB0aGV5IHdpc2ggdG8gaGF2ZSBubyBuYW1lc3BhY2UuCisgICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgZWxlbWVudCB0byBjcmVhdGUuCisgICAgICogQHBhcmFtIHF1YWxpZmllZE5hbWUgVGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBlbGVtZW50IHR5cGUgdG8KKyAgICAgKiAgIGluc3RhbnRpYXRlLgorICAgICAqIEByZXR1cm4gQSBuZXcgPGNvZGU+RWxlbWVudDwvY29kZT4gb2JqZWN0IHdpdGggdGhlIGZvbGxvd2luZworICAgICAqICAgYXR0cmlidXRlczoKKyAgICAgKiA8dGFibGUgYm9yZGVyPScxJyBjZWxscGFkZGluZz0nMyc+CisgICAgICogPHRyPgorICAgICAqIDx0aD5BdHRyaWJ1dGU8L3RoPgorICAgICAqIDx0aD5WYWx1ZTwvdGg+CisgICAgICogPC90cj4KKyAgICAgKiA8dHI+CisgICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5Ob2RlLm5vZGVOYW1lPC9jb2RlPjwvdGQ+CisgICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KKyAgICAgKiAgIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+PC90ZD4KKyAgICAgKiA8L3RyPgorICAgICAqIDx0cj4KKyAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPk5vZGUubmFtZXNwYWNlVVJJPC9jb2RlPjwvdGQ+CisgICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KKyAgICAgKiAgIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT48L3RkPgorICAgICAqIDwvdHI+CisgICAgICogPHRyPgorICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+Tm9kZS5wcmVmaXg8L2NvZGU+PC90ZD4KKyAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPnByZWZpeCwgZXh0cmFjdGVkCisgICAgICogICBmcm9tIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBpcworICAgICAqICAgbm8gcHJlZml4PC90ZD4KKyAgICAgKiA8L3RyPgorICAgICAqIDx0cj4KKyAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPk5vZGUubG9jYWxOYW1lPC9jb2RlPjwvdGQ+CisgICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5sb2NhbCBuYW1lLCBleHRyYWN0ZWQgZnJvbQorICAgICAqICAgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT48L3RkPgorICAgICAqIDwvdHI+CisgICAgICogPHRyPgorICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+RWxlbWVudC50YWdOYW1lPC9jb2RlPjwvdGQ+CisgICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KKyAgICAgKiAgIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+PC90ZD4KKyAgICAgKiA8L3RyPgorICAgICAqIDwvdGFibGU+CisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIElOVkFMSURfQ0hBUkFDVEVSX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IGlzIG5vdCBhbiBYTUwgbmFtZSBhY2NvcmRpbmcgdG8gdGhlIFhNTAorICAgICAqICAgdmVyc2lvbiBpbiB1c2Ugc3BlY2lmaWVkIGluIHRoZSA8Y29kZT5Eb2N1bWVudC54bWxWZXJzaW9uPC9jb2RlPgorICAgICAqICAgYXR0cmlidXRlLgorICAgICAqICAgPGJyPk5BTUVTUEFDRV9FUlI6IFJhaXNlZCBpZiB0aGUgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gaXMgYQorICAgICAqICAgbWFsZm9ybWVkIHF1YWxpZmllZCBuYW1lLCBpZiB0aGUgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gaGFzIGEKKyAgICAgKiAgIHByZWZpeCBhbmQgdGhlIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIG9yCisgICAgICogICBpZiB0aGUgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gaGFzIGEgcHJlZml4IHRoYXQgaXMgInhtbCIgYW5kCisgICAgICogICB0aGUgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyBkaWZmZXJlbnQgZnJvbSAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlJz4KKyAgICAgKiAgIGh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZTwvYT4iIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14bWwtbmFtZXMtMTk5OTAxMTQvJz5YTUwgTmFtZXNwYWNlczwvYT5dCisgICAgICogICAsIG9yIGlmIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBvciBpdHMgcHJlZml4IGlzICJ4bWxucyIgYW5kCisgICAgICogICB0aGUgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyBkaWZmZXJlbnQgZnJvbSAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8nPmh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvPC9hPiIsIG9yIGlmIHRoZSA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyc+aHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy88L2E+IiBhbmQgbmVpdGhlciB0aGUgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gbm9yIGl0cyBwcmVmaXggaXMgInhtbG5zIi4KKyAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogQWx3YXlzIHRocm93biBpZiB0aGUgY3VycmVudCBkb2N1bWVudCBkb2VzIG5vdAorICAgICAqICAgc3VwcG9ydCB0aGUgPGNvZGU+IlhNTCI8L2NvZGU+IGZlYXR1cmUsIHNpbmNlIG5hbWVzcGFjZXMgd2VyZQorICAgICAqICAgZGVmaW5lZCBieSBYTUwuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAyCisgICAgICovCisgICAgcHVibGljIEVsZW1lbnQgY3JlYXRlRWxlbWVudE5TKFN0cmluZyBuYW1lc3BhY2VVUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBhdHRyaWJ1dGUgb2YgdGhlIGdpdmVuIHF1YWxpZmllZCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLgorICAgICAqIDxicj5QZXIgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNC8nPlhNTCBOYW1lc3BhY2VzPC9hPl0KKyAgICAgKiAsIGFwcGxpY2F0aW9ucyBtdXN0IHVzZSB0aGUgdmFsdWUgPGNvZGU+bnVsbDwvY29kZT4gYXMgdGhlCisgICAgICogPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBwYXJhbWV0ZXIgZm9yIG1ldGhvZHMgaWYgdGhleSB3aXNoIHRvIGhhdmUKKyAgICAgKiBubyBuYW1lc3BhY2UuCisgICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgYXR0cmlidXRlIHRvIGNyZWF0ZS4KKyAgICAgKiBAcGFyYW0gcXVhbGlmaWVkTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0bworICAgICAqICAgaW5zdGFudGlhdGUuCisgICAgICogQHJldHVybiBBIG5ldyA8Y29kZT5BdHRyPC9jb2RlPiBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nIGF0dHJpYnV0ZXM6CisgICAgICogPHRhYmxlIGJvcmRlcj0nMScgY2VsbHBhZGRpbmc9JzMnPgorICAgICAqIDx0cj4KKyAgICAgKiA8dGg+CisgICAgICogICBBdHRyaWJ1dGU8L3RoPgorICAgICAqIDx0aD5WYWx1ZTwvdGg+CisgICAgICogPC90cj4KKyAgICAgKiA8dHI+CisgICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5Ob2RlLm5vZGVOYW1lPC9jb2RlPjwvdGQ+CisgICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5xdWFsaWZpZWROYW1lPC90ZD4KKyAgICAgKiA8L3RyPgorICAgICAqIDx0cj4KKyAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICAgICAqICAgPGNvZGU+Tm9kZS5uYW1lc3BhY2VVUkk8L2NvZGU+PC90ZD4KKyAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT48L3RkPgorICAgICAqIDwvdHI+CisgICAgICogPHRyPgorICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+CisgICAgICogICA8Y29kZT5Ob2RlLnByZWZpeDwvY29kZT48L3RkPgorICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+cHJlZml4LCBleHRyYWN0ZWQgZnJvbQorICAgICAqICAgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4sIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGlzIG5vCisgICAgICogICBwcmVmaXg8L3RkPgorICAgICAqIDwvdHI+CisgICAgICogPHRyPgorICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+Tm9kZS5sb2NhbE5hbWU8L2NvZGU+PC90ZD4KKyAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPmxvY2FsIG5hbWUsIGV4dHJhY3RlZCBmcm9tCisgICAgICogICA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPjwvdGQ+CisgICAgICogPC90cj4KKyAgICAgKiA8dHI+CisgICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5BdHRyLm5hbWU8L2NvZGU+PC90ZD4KKyAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICAgICAqICAgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT48L3RkPgorICAgICAqIDwvdHI+CisgICAgICogPHRyPgorICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+Tm9kZS5ub2RlVmFsdWU8L2NvZGU+PC90ZD4KKyAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPnRoZSBlbXB0eQorICAgICAqICAgc3RyaW5nPC90ZD4KKyAgICAgKiA8L3RyPgorICAgICAqIDwvdGFibGU+CisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIElOVkFMSURfQ0hBUkFDVEVSX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQKKyAgICAgKiAgIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IGlzIG5vdCBhbiBYTUwgbmFtZSBhY2NvcmRpbmcgdG8gdGhlIFhNTAorICAgICAqICAgdmVyc2lvbiBpbiB1c2Ugc3BlY2lmaWVkIGluIHRoZSA8Y29kZT5Eb2N1bWVudC54bWxWZXJzaW9uPC9jb2RlPgorICAgICAqICAgYXR0cmlidXRlLgorICAgICAqICAgPGJyPk5BTUVTUEFDRV9FUlI6IFJhaXNlZCBpZiB0aGUgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gaXMgYQorICAgICAqICAgbWFsZm9ybWVkIHF1YWxpZmllZCBuYW1lLCBpZiB0aGUgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gaGFzIGEKKyAgICAgKiAgIHByZWZpeCBhbmQgdGhlIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIGlmCisgICAgICogICB0aGUgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gaGFzIGEgcHJlZml4IHRoYXQgaXMgInhtbCIgYW5kIHRoZQorICAgICAqICAgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyBkaWZmZXJlbnQgZnJvbSAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlJz4KKyAgICAgKiAgIGh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZTwvYT4iLCBpZiB0aGUgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gb3IgaXRzIHByZWZpeCBpcyAieG1sbnMiIGFuZCB0aGUKKyAgICAgKiAgIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgZGlmZmVyZW50IGZyb20gIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvJz5odHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLzwvYT4iLCBvciBpZiB0aGUgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8nPmh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvPC9hPiIgYW5kIG5laXRoZXIgdGhlIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IG5vciBpdHMgcHJlZml4IGlzICJ4bWxucyIuCisgICAgICogICA8YnI+Tk9UX1NVUFBPUlRFRF9FUlI6IEFsd2F5cyB0aHJvd24gaWYgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZG9lcyBub3QKKyAgICAgKiAgIHN1cHBvcnQgdGhlIDxjb2RlPiJYTUwiPC9jb2RlPiBmZWF0dXJlLCBzaW5jZSBuYW1lc3BhY2VzIHdlcmUKKyAgICAgKiAgIGRlZmluZWQgYnkgWE1MLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgorICAgICAqLworICAgIHB1YmxpYyBBdHRyIGNyZWF0ZUF0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSA8Y29kZT5Ob2RlTGlzdDwvY29kZT4gb2YgYWxsIHRoZSA8Y29kZT5FbGVtZW50czwvY29kZT4gd2l0aCBhCisgICAgICogZ2l2ZW4gbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSBpbiBkb2N1bWVudCBvcmRlci4KKyAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBlbGVtZW50cyB0byBtYXRjaCBvbi4gVGhlCisgICAgICogICBzcGVjaWFsIHZhbHVlIDxjb2RlPiIqIjwvY29kZT4gbWF0Y2hlcyBhbGwgbmFtZXNwYWNlcy4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBlbGVtZW50cyB0byBtYXRjaCBvbi4gVGhlCisgICAgICogICBzcGVjaWFsIHZhbHVlICIqIiBtYXRjaGVzIGFsbCBsb2NhbCBuYW1lcy4KKyAgICAgKiBAcmV0dXJuIEEgbmV3IDxjb2RlPk5vZGVMaXN0PC9jb2RlPiBvYmplY3QgY29udGFpbmluZyBhbGwgdGhlIG1hdGNoZWQKKyAgICAgKiAgIDxjb2RlPkVsZW1lbnRzPC9jb2RlPi4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgTm9kZUxpc3QgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgPGNvZGU+RWxlbWVudDwvY29kZT4gdGhhdCBoYXMgYW4gSUQgYXR0cmlidXRlIHdpdGggdGhlCisgICAgICogZ2l2ZW4gdmFsdWUuIElmIG5vIHN1Y2ggZWxlbWVudCBleGlzdHMsIHRoaXMgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPgorICAgICAqIC4gSWYgbW9yZSB0aGFuIG9uZSBlbGVtZW50IGhhcyBhbiBJRCBhdHRyaWJ1dGUgd2l0aCB0aGF0IHZhbHVlLCB3aGF0CisgICAgICogaXMgcmV0dXJuZWQgaXMgdW5kZWZpbmVkLgorICAgICAqIDxicj4gVGhlIERPTSBpbXBsZW1lbnRhdGlvbiBpcyBleHBlY3RlZCB0byB1c2UgdGhlIGF0dHJpYnV0ZQorICAgICAqIDxjb2RlPkF0dHIuaXNJZDwvY29kZT4gdG8gZGV0ZXJtaW5lIGlmIGFuIGF0dHJpYnV0ZSBpcyBvZiB0eXBlIElELgorICAgICAqIDxwID48Yj5Ob3RlOjwvYj4gQXR0cmlidXRlcyB3aXRoIHRoZSBuYW1lICJJRCIgb3IgImlkIiBhcmUgbm90IG9mIHR5cGUKKyAgICAgKiBJRCB1bmxlc3Mgc28gZGVmaW5lZC4KKyAgICAgKiBAcGFyYW0gZWxlbWVudElkIFRoZSB1bmlxdWUgPGNvZGU+aWQ8L2NvZGU+IHZhbHVlIGZvciBhbiBlbGVtZW50LgorICAgICAqIEByZXR1cm4gVGhlIG1hdGNoaW5nIGVsZW1lbnQgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgaXMgbm9uZS4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgRWxlbWVudCBnZXRFbGVtZW50QnlJZChTdHJpbmcgZWxlbWVudElkKTsKKworICAgIC8qKgorICAgICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nIHRoZSBlbmNvZGluZyB1c2VkIGZvciB0aGlzIGRvY3VtZW50IGF0IHRoZSB0aW1lCisgICAgICogb2YgdGhlIHBhcnNpbmcuIFRoaXMgaXMgPGNvZGU+bnVsbDwvY29kZT4gd2hlbiBpdCBpcyBub3Qga25vd24sIHN1Y2gKKyAgICAgKiBhcyB3aGVuIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gd2FzIGNyZWF0ZWQgaW4gbWVtb3J5LgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0SW5wdXRFbmNvZGluZygpOworCisgICAgLyoqCisgICAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCNOVC1YTUxEZWNsJz5YTUwgZGVjbGFyYXRpb248L2E+LCB0aGUgZW5jb2Rpbmcgb2YgdGhpcyBkb2N1bWVudC4gVGhpcyBpcyA8Y29kZT5udWxsPC9jb2RlPiB3aGVuCisgICAgICogdW5zcGVjaWZpZWQgb3Igd2hlbiBpdCBpcyBub3Qga25vd24sIHN1Y2ggYXMgd2hlbiB0aGUKKyAgICAgKiA8Y29kZT5Eb2N1bWVudDwvY29kZT4gd2FzIGNyZWF0ZWQgaW4gbWVtb3J5LgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0WG1sRW5jb2RpbmcoKTsKKworICAgIC8qKgorICAgICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQjTlQtWE1MRGVjbCc+WE1MIGRlY2xhcmF0aW9uPC9hPiwgd2hldGhlciB0aGlzIGRvY3VtZW50IGlzIHN0YW5kYWxvbmUuIFRoaXMgaXMgPGNvZGU+ZmFsc2U8L2NvZGU+IHdoZW4KKyAgICAgKiB1bnNwZWNpZmllZC4KKyAgICAgKiA8cCA+PGI+Tm90ZTo8L2I+ICBObyB2ZXJpZmljYXRpb24gaXMgZG9uZSBvbiB0aGUgdmFsdWUgd2hlbiBzZXR0aW5nCisgICAgICogdGhpcyBhdHRyaWJ1dGUuIEFwcGxpY2F0aW9ucyBzaG91bGQgdXNlCisgICAgICogPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4gd2l0aCB0aGUgInZhbGlkYXRlIgorICAgICAqIHBhcmFtZXRlciB0byB2ZXJpZnkgaWYgdGhlIHZhbHVlIG1hdGNoZXMgdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCNzZWMtcm1kJz52YWxpZGl0eQorICAgICAqIGNvbnN0cmFpbnQgZm9yIHN0YW5kYWxvbmUgZG9jdW1lbnQgZGVjbGFyYXRpb248L2E+IGFzIGRlZmluZWQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldFhtbFN0YW5kYWxvbmUoKTsKKyAgICAvKioKKyAgICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZywgYXMgcGFydCBvZiB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0I05ULVhNTERlY2wnPlhNTCBkZWNsYXJhdGlvbjwvYT4sIHdoZXRoZXIgdGhpcyBkb2N1bWVudCBpcyBzdGFuZGFsb25lLiBUaGlzIGlzIDxjb2RlPmZhbHNlPC9jb2RlPiB3aGVuCisgICAgICogdW5zcGVjaWZpZWQuCisgICAgICogPHAgPjxiPk5vdGU6PC9iPiAgTm8gdmVyaWZpY2F0aW9uIGlzIGRvbmUgb24gdGhlIHZhbHVlIHdoZW4gc2V0dGluZworICAgICAqIHRoaXMgYXR0cmlidXRlLiBBcHBsaWNhdGlvbnMgc2hvdWxkIHVzZQorICAgICAqIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk8L2NvZGU+IHdpdGggdGhlICJ2YWxpZGF0ZSIKKyAgICAgKiBwYXJhbWV0ZXIgdG8gdmVyaWZ5IGlmIHRoZSB2YWx1ZSBtYXRjaGVzIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQjc2VjLXJtZCc+dmFsaWRpdHkKKyAgICAgKiBjb25zdHJhaW50IGZvciBzdGFuZGFsb25lIGRvY3VtZW50IGRlY2xhcmF0aW9uPC9hPiBhcyBkZWZpbmVkIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XS4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgIE5PVF9TVVBQT1JURURfRVJSOiBSYWlzZWQgaWYgdGhpcyBkb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IHRoZQorICAgICAqICAgIlhNTCIgZmVhdHVyZS4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRYbWxTdGFuZGFsb25lKGJvb2xlYW4geG1sU3RhbmRhbG9uZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQjTlQtWE1MRGVjbCc+WE1MIGRlY2xhcmF0aW9uPC9hPiwgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoaXMgZG9jdW1lbnQuIElmIHRoZXJlIGlzIG5vIGRlY2xhcmF0aW9uIGFuZCBpZgorICAgICAqIHRoaXMgZG9jdW1lbnQgc3VwcG9ydHMgdGhlICJYTUwiIGZlYXR1cmUsIHRoZSB2YWx1ZSBpcworICAgICAqIDxjb2RlPiIxLjAiPC9jb2RlPi4gSWYgdGhpcyBkb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IHRoZSAiWE1MIgorICAgICAqIGZlYXR1cmUsIHRoZSB2YWx1ZSBpcyBhbHdheXMgPGNvZGU+bnVsbDwvY29kZT4uIENoYW5naW5nIHRoaXMKKyAgICAgKiBhdHRyaWJ1dGUgd2lsbCBhZmZlY3QgbWV0aG9kcyB0aGF0IGNoZWNrIGZvciBpbnZhbGlkIGNoYXJhY3RlcnMgaW4KKyAgICAgKiBYTUwgbmFtZXMuIEFwcGxpY2F0aW9uIHNob3VsZCBpbnZva2UKKyAgICAgKiA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPiBpbiBvcmRlciB0byBjaGVjayBmb3IKKyAgICAgKiBpbnZhbGlkIGNoYXJhY3RlcnMgaW4gdGhlIDxjb2RlPk5vZGU8L2NvZGU+cyB0aGF0IGFyZSBhbHJlYWR5IHBhcnQgb2YKKyAgICAgKiB0aGlzIDxjb2RlPkRvY3VtZW50PC9jb2RlPi4KKyAgICAgKiA8YnI+IERPTSBhcHBsaWNhdGlvbnMgbWF5IHVzZSB0aGUKKyAgICAgKiA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbi5oYXNGZWF0dXJlKGZlYXR1cmUsIHZlcnNpb24pPC9jb2RlPiBtZXRob2QKKyAgICAgKiB3aXRoIHBhcmFtZXRlciB2YWx1ZXMgIlhNTFZlcnNpb24iIGFuZCAiMS4wIiAocmVzcGVjdGl2ZWx5KSB0bworICAgICAqIGRldGVybWluZSBpZiBhbiBpbXBsZW1lbnRhdGlvbiBzdXBwb3J0cyBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0uIERPTQorICAgICAqIGFwcGxpY2F0aW9ucyBtYXkgdXNlIHRoZSBzYW1lIG1ldGhvZCB3aXRoIHBhcmFtZXRlciB2YWx1ZXMKKyAgICAgKiAiWE1MVmVyc2lvbiIgYW5kICIxLjEiIChyZXNwZWN0aXZlbHkpIHRvIGRldGVybWluZSBpZiBhbgorICAgICAqIGltcGxlbWVudGF0aW9uIHN1cHBvcnRzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwxMS0yMDA0MDIwNC8nPlhNTCAxLjE8L2E+XS4gSW4gYm90aAorICAgICAqIGNhc2VzLCBpbiBvcmRlciB0byBzdXBwb3J0IFhNTCwgYW4gaW1wbGVtZW50YXRpb24gbXVzdCBhbHNvIHN1cHBvcnQKKyAgICAgKiB0aGUgIlhNTCIgZmVhdHVyZSBkZWZpbmVkIGluIHRoaXMgc3BlY2lmaWNhdGlvbi4gPGNvZGU+RG9jdW1lbnQ8L2NvZGU+CisgICAgICogIG9iamVjdHMgc3VwcG9ydGluZyBhIHZlcnNpb24gb2YgdGhlICJYTUxWZXJzaW9uIiBmZWF0dXJlIG11c3Qgbm90CisgICAgICogcmFpc2UgYSA8Y29kZT5OT1RfU1VQUE9SVEVEX0VSUjwvY29kZT4gZXhjZXB0aW9uIGZvciB0aGUgc2FtZSB2ZXJzaW9uCisgICAgICogbnVtYmVyIHdoZW4gdXNpbmcgPGNvZGU+RG9jdW1lbnQueG1sVmVyc2lvbjwvY29kZT4uCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAzCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRYbWxWZXJzaW9uKCk7CisgICAgLyoqCisgICAgICogIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQjTlQtWE1MRGVjbCc+WE1MIGRlY2xhcmF0aW9uPC9hPiwgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoaXMgZG9jdW1lbnQuIElmIHRoZXJlIGlzIG5vIGRlY2xhcmF0aW9uIGFuZCBpZgorICAgICAqIHRoaXMgZG9jdW1lbnQgc3VwcG9ydHMgdGhlICJYTUwiIGZlYXR1cmUsIHRoZSB2YWx1ZSBpcworICAgICAqIDxjb2RlPiIxLjAiPC9jb2RlPi4gSWYgdGhpcyBkb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IHRoZSAiWE1MIgorICAgICAqIGZlYXR1cmUsIHRoZSB2YWx1ZSBpcyBhbHdheXMgPGNvZGU+bnVsbDwvY29kZT4uIENoYW5naW5nIHRoaXMKKyAgICAgKiBhdHRyaWJ1dGUgd2lsbCBhZmZlY3QgbWV0aG9kcyB0aGF0IGNoZWNrIGZvciBpbnZhbGlkIGNoYXJhY3RlcnMgaW4KKyAgICAgKiBYTUwgbmFtZXMuIEFwcGxpY2F0aW9uIHNob3VsZCBpbnZva2UKKyAgICAgKiA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPiBpbiBvcmRlciB0byBjaGVjayBmb3IKKyAgICAgKiBpbnZhbGlkIGNoYXJhY3RlcnMgaW4gdGhlIDxjb2RlPk5vZGU8L2NvZGU+cyB0aGF0IGFyZSBhbHJlYWR5IHBhcnQgb2YKKyAgICAgKiB0aGlzIDxjb2RlPkRvY3VtZW50PC9jb2RlPi4KKyAgICAgKiA8YnI+IERPTSBhcHBsaWNhdGlvbnMgbWF5IHVzZSB0aGUKKyAgICAgKiA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbi5oYXNGZWF0dXJlKGZlYXR1cmUsIHZlcnNpb24pPC9jb2RlPiBtZXRob2QKKyAgICAgKiB3aXRoIHBhcmFtZXRlciB2YWx1ZXMgIlhNTFZlcnNpb24iIGFuZCAiMS4wIiAocmVzcGVjdGl2ZWx5KSB0bworICAgICAqIGRldGVybWluZSBpZiBhbiBpbXBsZW1lbnRhdGlvbiBzdXBwb3J0cyBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0uIERPTQorICAgICAqIGFwcGxpY2F0aW9ucyBtYXkgdXNlIHRoZSBzYW1lIG1ldGhvZCB3aXRoIHBhcmFtZXRlciB2YWx1ZXMKKyAgICAgKiAiWE1MVmVyc2lvbiIgYW5kICIxLjEiIChyZXNwZWN0aXZlbHkpIHRvIGRldGVybWluZSBpZiBhbgorICAgICAqIGltcGxlbWVudGF0aW9uIHN1cHBvcnRzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwxMS0yMDA0MDIwNC8nPlhNTCAxLjE8L2E+XS4gSW4gYm90aAorICAgICAqIGNhc2VzLCBpbiBvcmRlciB0byBzdXBwb3J0IFhNTCwgYW4gaW1wbGVtZW50YXRpb24gbXVzdCBhbHNvIHN1cHBvcnQKKyAgICAgKiB0aGUgIlhNTCIgZmVhdHVyZSBkZWZpbmVkIGluIHRoaXMgc3BlY2lmaWNhdGlvbi4gPGNvZGU+RG9jdW1lbnQ8L2NvZGU+CisgICAgICogIG9iamVjdHMgc3VwcG9ydGluZyBhIHZlcnNpb24gb2YgdGhlICJYTUxWZXJzaW9uIiBmZWF0dXJlIG11c3Qgbm90CisgICAgICogcmFpc2UgYSA8Y29kZT5OT1RfU1VQUE9SVEVEX0VSUjwvY29kZT4gZXhjZXB0aW9uIGZvciB0aGUgc2FtZSB2ZXJzaW9uCisgICAgICogbnVtYmVyIHdoZW4gdXNpbmcgPGNvZGU+RG9jdW1lbnQueG1sVmVyc2lvbjwvY29kZT4uCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgICBOT1RfU1VQUE9SVEVEX0VSUjogUmFpc2VkIGlmIHRoZSB2ZXJzaW9uIGlzIHNldCB0byBhIHZhbHVlIHRoYXQgaXMKKyAgICAgKiAgIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyA8Y29kZT5Eb2N1bWVudDwvY29kZT4gb3IgaWYgdGhpcyBkb2N1bWVudAorICAgICAqICAgZG9lcyBub3Qgc3VwcG9ydCB0aGUgIlhNTCIgZmVhdHVyZS4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRYbWxWZXJzaW9uKFN0cmluZyB4bWxWZXJzaW9uKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZyB3aGV0aGVyIGVycm9yIGNoZWNraW5nIGlzIGVuZm9yY2VkIG9yIG5vdC4gV2hlbgorICAgICAqIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4sIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBmcmVlIHRvIG5vdCB0ZXN0CisgICAgICogZXZlcnkgcG9zc2libGUgZXJyb3IgY2FzZSBub3JtYWxseSBkZWZpbmVkIG9uIERPTSBvcGVyYXRpb25zLCBhbmQgbm90CisgICAgICogcmFpc2UgYW55IDxjb2RlPkRPTUV4Y2VwdGlvbjwvY29kZT4gb24gRE9NIG9wZXJhdGlvbnMgb3IgcmVwb3J0CisgICAgICogZXJyb3JzIHdoaWxlIHVzaW5nIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk8L2NvZGU+LiBJbiBjYXNlCisgICAgICogb2YgZXJyb3IsIHRoZSBiZWhhdmlvciBpcyB1bmRlZmluZWQuIFRoaXMgYXR0cmlidXRlIGlzCisgICAgICogPGNvZGU+dHJ1ZTwvY29kZT4gYnkgZGVmYXVsdC4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRTdHJpY3RFcnJvckNoZWNraW5nKCk7CisgICAgLyoqCisgICAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcgd2hldGhlciBlcnJvciBjaGVja2luZyBpcyBlbmZvcmNlZCBvciBub3QuIFdoZW4KKyAgICAgKiBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LCB0aGUgaW1wbGVtZW50YXRpb24gaXMgZnJlZSB0byBub3QgdGVzdAorICAgICAqIGV2ZXJ5IHBvc3NpYmxlIGVycm9yIGNhc2Ugbm9ybWFsbHkgZGVmaW5lZCBvbiBET00gb3BlcmF0aW9ucywgYW5kIG5vdAorICAgICAqIHJhaXNlIGFueSA8Y29kZT5ET01FeGNlcHRpb248L2NvZGU+IG9uIERPTSBvcGVyYXRpb25zIG9yIHJlcG9ydAorICAgICAqIGVycm9ycyB3aGlsZSB1c2luZyA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPi4gSW4gY2FzZQorICAgICAqIG9mIGVycm9yLCB0aGUgYmVoYXZpb3IgaXMgdW5kZWZpbmVkLiBUaGlzIGF0dHJpYnV0ZSBpcworICAgICAqIDxjb2RlPnRydWU8L2NvZGU+IGJ5IGRlZmF1bHQuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3RyaWN0RXJyb3JDaGVja2luZyhib29sZWFuIHN0cmljdEVycm9yQ2hlY2tpbmcpOworCisgICAgLyoqCisgICAgICogIFRoZSBsb2NhdGlvbiBvZiB0aGUgZG9jdW1lbnQgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdW5kZWZpbmVkIG9yIGlmCisgICAgICogdGhlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiB3YXMgY3JlYXRlZCB1c2luZworICAgICAqIDxjb2RlPkRPTUltcGxlbWVudGF0aW9uLmNyZWF0ZURvY3VtZW50PC9jb2RlPi4gTm8gbGV4aWNhbCBjaGVja2luZyBpcworICAgICAqIHBlcmZvcm1lZCB3aGVuIHNldHRpbmcgdGhpcyBhdHRyaWJ1dGU7IHRoaXMgY291bGQgcmVzdWx0IGluIGEKKyAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiB2YWx1ZSByZXR1cm5lZCB3aGVuIHVzaW5nIDxjb2RlPk5vZGUuYmFzZVVSSTwvY29kZT4KKyAgICAgKiAuCisgICAgICogPGJyPiBCZXdhcmUgdGhhdCB3aGVuIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gc3VwcG9ydHMgdGhlIGZlYXR1cmUKKyAgICAgKiAiSFRNTCIgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvUkVDLURPTS1MZXZlbC0yLUhUTUwtMjAwMzAxMDknPkRPTSBMZXZlbCAyIEhUTUw8L2E+XQorICAgICAqICwgdGhlIGhyZWYgYXR0cmlidXRlIG9mIHRoZSBIVE1MIEJBU0UgZWxlbWVudCB0YWtlcyBwcmVjZWRlbmNlIG92ZXIKKyAgICAgKiB0aGlzIGF0dHJpYnV0ZSB3aGVuIGNvbXB1dGluZyA8Y29kZT5Ob2RlLmJhc2VVUkk8L2NvZGU+LgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRVUkkoKTsKKyAgICAvKioKKyAgICAgKiAgVGhlIGxvY2F0aW9uIG9mIHRoZSBkb2N1bWVudCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB1bmRlZmluZWQgb3IgaWYKKyAgICAgKiB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IHdhcyBjcmVhdGVkIHVzaW5nCisgICAgICogPGNvZGU+RE9NSW1wbGVtZW50YXRpb24uY3JlYXRlRG9jdW1lbnQ8L2NvZGU+LiBObyBsZXhpY2FsIGNoZWNraW5nIGlzCisgICAgICogcGVyZm9ybWVkIHdoZW4gc2V0dGluZyB0aGlzIGF0dHJpYnV0ZTsgdGhpcyBjb3VsZCByZXN1bHQgaW4gYQorICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIHJldHVybmVkIHdoZW4gdXNpbmcgPGNvZGU+Tm9kZS5iYXNlVVJJPC9jb2RlPgorICAgICAqIC4KKyAgICAgKiA8YnI+IEJld2FyZSB0aGF0IHdoZW4gdGhlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBzdXBwb3J0cyB0aGUgZmVhdHVyZQorICAgICAqICJIVE1MIiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9SRUMtRE9NLUxldmVsLTItSFRNTC0yMDAzMDEwOSc+RE9NIExldmVsIDIgSFRNTDwvYT5dCisgICAgICogLCB0aGUgaHJlZiBhdHRyaWJ1dGUgb2YgdGhlIEhUTUwgQkFTRSBlbGVtZW50IHRha2VzIHByZWNlZGVuY2Ugb3ZlcgorICAgICAqIHRoaXMgYXR0cmlidXRlIHdoZW4gY29tcHV0aW5nIDxjb2RlPk5vZGUuYmFzZVVSSTwvY29kZT4uCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRVUkkoU3RyaW5nIGRvY3VtZW50VVJJKTsKKworICAgIC8qKgorICAgICAqICBBdHRlbXB0cyB0byBhZG9wdCBhIG5vZGUgZnJvbSBhbm90aGVyIGRvY3VtZW50IHRvIHRoaXMgZG9jdW1lbnQuIElmCisgICAgICogc3VwcG9ydGVkLCBpdCBjaGFuZ2VzIHRoZSA8Y29kZT5vd25lckRvY3VtZW50PC9jb2RlPiBvZiB0aGUgc291cmNlCisgICAgICogbm9kZSwgaXRzIGNoaWxkcmVuLCBhcyB3ZWxsIGFzIHRoZSBhdHRhY2hlZCBhdHRyaWJ1dGUgbm9kZXMgaWYgdGhlcmUKKyAgICAgKiBhcmUgYW55LiBJZiB0aGUgc291cmNlIG5vZGUgaGFzIGEgcGFyZW50IGl0IGlzIGZpcnN0IHJlbW92ZWQgZnJvbSB0aGUKKyAgICAgKiBjaGlsZCBsaXN0IG9mIGl0cyBwYXJlbnQuIFRoaXMgZWZmZWN0aXZlbHkgYWxsb3dzIG1vdmluZyBhIHN1YnRyZWUKKyAgICAgKiBmcm9tIG9uZSBkb2N1bWVudCB0byBhbm90aGVyICh1bmxpa2UgPGNvZGU+aW1wb3J0Tm9kZSgpPC9jb2RlPiB3aGljaAorICAgICAqIGNyZWF0ZSBhIGNvcHkgb2YgdGhlIHNvdXJjZSBub2RlIGluc3RlYWQgb2YgbW92aW5nIGl0KS4gV2hlbiBpdAorICAgICAqIGZhaWxzLCBhcHBsaWNhdGlvbnMgc2hvdWxkIHVzZSA8Y29kZT5Eb2N1bWVudC5pbXBvcnROb2RlKCk8L2NvZGU+CisgICAgICogaW5zdGVhZC4gTm90ZSB0aGF0IGlmIHRoZSBhZG9wdGVkIG5vZGUgaXMgYWxyZWFkeSBwYXJ0IG9mIHRoaXMKKyAgICAgKiBkb2N1bWVudCAoaS5lLiB0aGUgc291cmNlIGFuZCB0YXJnZXQgZG9jdW1lbnQgYXJlIHRoZSBzYW1lKSwgdGhpcworICAgICAqIG1ldGhvZCBzdGlsbCBoYXMgdGhlIGVmZmVjdCBvZiByZW1vdmluZyB0aGUgc291cmNlIG5vZGUgZnJvbSB0aGUKKyAgICAgKiBjaGlsZCBsaXN0IG9mIGl0cyBwYXJlbnQsIGlmIGFueS4gVGhlIGZvbGxvd2luZyBsaXN0IGRlc2NyaWJlcyB0aGUKKyAgICAgKiBzcGVjaWZpY3MgZm9yIGVhY2ggdHlwZSBvZiBub2RlLgorICAgICAqIDxkbD4KKyAgICAgKiA8ZHQ+QVRUUklCVVRFX05PREU8L2R0PgorICAgICAqIDxkZD5UaGUKKyAgICAgKiA8Y29kZT5vd25lckVsZW1lbnQ8L2NvZGU+IGF0dHJpYnV0ZSBpcyBzZXQgdG8gPGNvZGU+bnVsbDwvY29kZT4gYW5kCisgICAgICogdGhlIDxjb2RlPnNwZWNpZmllZDwvY29kZT4gZmxhZyBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4gb24gdGhlCisgICAgICogYWRvcHRlZCA8Y29kZT5BdHRyPC9jb2RlPi4gVGhlIGRlc2NlbmRhbnRzIG9mIHRoZSBzb3VyY2UKKyAgICAgKiA8Y29kZT5BdHRyPC9jb2RlPiBhcmUgcmVjdXJzaXZlbHkgYWRvcHRlZC48L2RkPgorICAgICAqIDxkdD5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFPC9kdD4KKyAgICAgKiA8ZGQ+VGhlCisgICAgICogZGVzY2VuZGFudHMgb2YgdGhlIHNvdXJjZSBub2RlIGFyZSByZWN1cnNpdmVseSBhZG9wdGVkLjwvZGQ+CisgICAgICogPGR0PkRPQ1VNRU5UX05PREU8L2R0PgorICAgICAqIDxkZD4KKyAgICAgKiA8Y29kZT5Eb2N1bWVudDwvY29kZT4gbm9kZXMgY2Fubm90IGJlIGFkb3B0ZWQuPC9kZD4KKyAgICAgKiA8ZHQ+RE9DVU1FTlRfVFlQRV9OT0RFPC9kdD4KKyAgICAgKiA8ZGQ+CisgICAgICogPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBub2RlcyBjYW5ub3QgYmUgYWRvcHRlZC48L2RkPgorICAgICAqIDxkdD5FTEVNRU5UX05PREU8L2R0PgorICAgICAqIDxkZD48ZW0+U3BlY2lmaWVkPC9lbT4gYXR0cmlidXRlIG5vZGVzIG9mIHRoZSBzb3VyY2UgZWxlbWVudCBhcmUgYWRvcHRlZC4gRGVmYXVsdCBhdHRyaWJ1dGVzCisgICAgICogYXJlIGRpc2NhcmRlZCwgdGhvdWdoIGlmIHRoZSBkb2N1bWVudCBiZWluZyBhZG9wdGVkIGludG8gZGVmaW5lcworICAgICAqIGRlZmF1bHQgYXR0cmlidXRlcyBmb3IgdGhpcyBlbGVtZW50IG5hbWUsIHRob3NlIGFyZSBhc3NpZ25lZC4gVGhlCisgICAgICogZGVzY2VuZGFudHMgb2YgdGhlIHNvdXJjZSBlbGVtZW50IGFyZSByZWN1cnNpdmVseSBhZG9wdGVkLjwvZGQ+CisgICAgICogPGR0PkVOVElUWV9OT0RFPC9kdD4KKyAgICAgKiA8ZGQ+CisgICAgICogPGNvZGU+RW50aXR5PC9jb2RlPiBub2RlcyBjYW5ub3QgYmUgYWRvcHRlZC48L2RkPgorICAgICAqIDxkdD5FTlRJVFlfUkVGRVJFTkNFX05PREU8L2R0PgorICAgICAqIDxkZD5Pbmx5CisgICAgICogdGhlIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZSBpdHNlbGYgaXMgYWRvcHRlZCwgdGhlCisgICAgICogZGVzY2VuZGFudHMgYXJlIGRpc2NhcmRlZCwgc2luY2UgdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gZG9jdW1lbnRzCisgICAgICogbWlnaHQgaGF2ZSBkZWZpbmVkIHRoZSBlbnRpdHkgZGlmZmVyZW50bHkuIElmIHRoZSBkb2N1bWVudCBiZWluZworICAgICAqIGltcG9ydGVkIGludG8gcHJvdmlkZXMgYSBkZWZpbml0aW9uIGZvciB0aGlzIGVudGl0eSBuYW1lLCBpdHMgdmFsdWUKKyAgICAgKiBpcyBhc3NpZ25lZC48L2RkPgorICAgICAqIDxkdD5OT1RBVElPTl9OT0RFPC9kdD4KKyAgICAgKiA8ZGQ+PGNvZGU+Tm90YXRpb248L2NvZGU+IG5vZGVzIGNhbm5vdCBiZQorICAgICAqIGFkb3B0ZWQuPC9kZD4KKyAgICAgKiA8ZHQ+UFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFLCBURVhUX05PREUsIENEQVRBX1NFQ1RJT05fTk9ERSwKKyAgICAgKiBDT01NRU5UX05PREU8L2R0PgorICAgICAqIDxkZD5UaGVzZSBub2RlcyBjYW4gYWxsIGJlIGFkb3B0ZWQuIE5vIHNwZWNpZmljcy48L2RkPgorICAgICAqIDwvZGw+CisgICAgICogPHAgPjxiPk5vdGU6PC9iPiAgU2luY2UgaXQgZG9lcyBub3QgY3JlYXRlIG5ldyBub2RlcyB1bmxpa2UgdGhlCisgICAgICogPGNvZGU+RG9jdW1lbnQuaW1wb3J0Tm9kZSgpPC9jb2RlPiBtZXRob2QsIHRoaXMgbWV0aG9kIGRvZXMgbm90IHJhaXNlCisgICAgICogYW4gPGNvZGU+SU5WQUxJRF9DSEFSQUNURVJfRVJSPC9jb2RlPiBleGNlcHRpb24sIGFuZCBhcHBsaWNhdGlvbnMKKyAgICAgKiBzaG91bGQgdXNlIHRoZSA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPiBtZXRob2QgdG8KKyAgICAgKiBjaGVjayBpZiBhbiBpbXBvcnRlZCBuYW1lIGlzIG5vdCBhbiBYTUwgbmFtZSBhY2NvcmRpbmcgdG8gdGhlIFhNTAorICAgICAqIHZlcnNpb24gaW4gdXNlLgorICAgICAqIEBwYXJhbSBzb3VyY2UgVGhlIG5vZGUgdG8gbW92ZSBpbnRvIHRoaXMgZG9jdW1lbnQuCisgICAgICogQHJldHVybiBUaGUgYWRvcHRlZCBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGlzIG9wZXJhdGlvbgorICAgICAqICAgZmFpbHMsIHN1Y2ggYXMgd2hlbiB0aGUgc291cmNlIG5vZGUgY29tZXMgZnJvbSBhIGRpZmZlcmVudAorICAgICAqICAgaW1wbGVtZW50YXRpb24uCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIE5PVF9TVVBQT1JURURfRVJSOiBSYWlzZWQgaWYgdGhlIHNvdXJjZSBub2RlIGlzIG9mIHR5cGUKKyAgICAgKiAgIDxjb2RlPkRPQ1VNRU5UPC9jb2RlPiwgPGNvZGU+RE9DVU1FTlRfVFlQRTwvY29kZT4uCisgICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgd2hlbiB0aGUgc291cmNlIG5vZGUgaXMKKyAgICAgKiAgIHJlYWRvbmx5LgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyBOb2RlIGFkb3B0Tm9kZShOb2RlIHNvdXJjZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqICBUaGUgY29uZmlndXJhdGlvbiB1c2VkIHdoZW4gPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4KKyAgICAgKiBpcyBpbnZva2VkLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyBET01Db25maWd1cmF0aW9uIGdldERvbUNvbmZpZygpOworCisgICAgLyoqCisgICAgICogIFRoaXMgbWV0aG9kIGFjdHMgYXMgaWYgdGhlIGRvY3VtZW50IHdhcyBnb2luZyB0aHJvdWdoIGEgc2F2ZSBhbmQgbG9hZAorICAgICAqIGN5Y2xlLCBwdXR0aW5nIHRoZSBkb2N1bWVudCBpbiBhICJub3JtYWwiIGZvcm0uIEFzIGEgY29uc2VxdWVuY2UsCisgICAgICogdGhpcyBtZXRob2QgdXBkYXRlcyB0aGUgcmVwbGFjZW1lbnQgdHJlZSBvZgorICAgICAqIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZXMgYW5kIG5vcm1hbGl6ZXMgPGNvZGU+VGV4dDwvY29kZT4KKyAgICAgKiBub2RlcywgYXMgZGVmaW5lZCBpbiB0aGUgbWV0aG9kIDxjb2RlPk5vZGUubm9ybWFsaXplKCk8L2NvZGU+LgorICAgICAqIDxicj4gT3RoZXJ3aXNlLCB0aGUgYWN0dWFsIHJlc3VsdCBkZXBlbmRzIG9uIHRoZSBmZWF0dXJlcyBiZWluZyBzZXQgb24KKyAgICAgKiB0aGUgPGNvZGU+RG9jdW1lbnQuZG9tQ29uZmlnPC9jb2RlPiBvYmplY3QgYW5kIGdvdmVybmluZyB3aGF0CisgICAgICogb3BlcmF0aW9ucyBhY3R1YWxseSB0YWtlIHBsYWNlLiBOb3RpY2VhYmx5IHRoaXMgbWV0aG9kIGNvdWxkIGFsc28KKyAgICAgKiBtYWtlIHRoZSBkb2N1bWVudCBuYW1lc3BhY2Ugd2VsbC1mb3JtZWQgYWNjb3JkaW5nIHRvIHRoZSBhbGdvcml0aG0KKyAgICAgKiBkZXNjcmliZWQgaW4gLCBjaGVjayB0aGUgY2hhcmFjdGVyIG5vcm1hbGl6YXRpb24sIHJlbW92ZSB0aGUKKyAgICAgKiA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+IG5vZGVzLCBldGMuIFNlZQorICAgICAqIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IGZvciBkZXRhaWxzLgorICAgICAqIDxwcmU+Ly8gS2VlcCBpbiB0aGUgZG9jdW1lbnQKKyAgICAgKiB0aGUgaW5mb3JtYXRpb24gZGVmaW5lZCAvLyBpbiB0aGUgWE1MIEluZm9ybWF0aW9uIFNldCAoSmF2YSBleGFtcGxlKQorICAgICAqIERPTUNvbmZpZ3VyYXRpb24gZG9jQ29uZmlnID0gbXlEb2N1bWVudC5nZXREb21Db25maWcoKTsKKyAgICAgKiBkb2NDb25maWcuc2V0UGFyYW1ldGVyKCJpbmZvc2V0IiwgQm9vbGVhbi5UUlVFKTsKKyAgICAgKiBteURvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk7PC9wcmU+CisgICAgICoKKyAgICAgKiA8YnI+TXV0YXRpb24gZXZlbnRzLCB3aGVuIHN1cHBvcnRlZCwgYXJlIGdlbmVyYXRlZCB0byByZWZsZWN0IHRoZQorICAgICAqIGNoYW5nZXMgb2NjdXJyaW5nIG9uIHRoZSBkb2N1bWVudC4KKyAgICAgKiA8YnI+IElmIGVycm9ycyBvY2N1ciBkdXJpbmcgdGhlIGludm9jYXRpb24gb2YgdGhpcyBtZXRob2QsIHN1Y2ggYXMgYW4KKyAgICAgKiBhdHRlbXB0IHRvIHVwZGF0ZSBhIHJlYWQtb25seSBub2RlIG9yIGEgPGNvZGU+Tm9kZS5ub2RlTmFtZTwvY29kZT4KKyAgICAgKiBjb250YWlucyBhbiBpbnZhbGlkIGNoYXJhY3RlciBhY2NvcmRpbmcgdG8gdGhlIFhNTCB2ZXJzaW9uIGluIHVzZSwKKyAgICAgKiBlcnJvcnMgb3Igd2FybmluZ3MgKDxjb2RlPkRPTUVycm9yLlNFVkVSSVRZX0VSUk9SPC9jb2RlPiBvcgorICAgICAqIDxjb2RlPkRPTUVycm9yLlNFVkVSSVRZX1dBUk5JTkc8L2NvZGU+KSB3aWxsIGJlIHJlcG9ydGVkIHVzaW5nIHRoZQorICAgICAqIDxjb2RlPkRPTUVycm9ySGFuZGxlcjwvY29kZT4gb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGUgImVycm9yLWhhbmRsZXIKKyAgICAgKiAiIHBhcmFtZXRlci4gTm90ZSB0aGlzIG1ldGhvZCBtaWdodCBhbHNvIHJlcG9ydCBmYXRhbCBlcnJvcnMgKAorICAgICAqIDxjb2RlPkRPTUVycm9yLlNFVkVSSVRZX0ZBVEFMX0VSUk9SPC9jb2RlPikgaWYgYW4gaW1wbGVtZW50YXRpb24KKyAgICAgKiBjYW5ub3QgcmVjb3ZlciBmcm9tIGFuIGVycm9yLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyB2b2lkIG5vcm1hbGl6ZURvY3VtZW50KCk7CisKKyAgICAvKioKKyAgICAgKiBSZW5hbWUgYW4gZXhpc3Rpbmcgbm9kZSBvZiB0eXBlIDxjb2RlPkVMRU1FTlRfTk9ERTwvY29kZT4gb3IKKyAgICAgKiA8Y29kZT5BVFRSSUJVVEVfTk9ERTwvY29kZT4uCisgICAgICogPGJyPldoZW4gcG9zc2libGUgdGhpcyBzaW1wbHkgY2hhbmdlcyB0aGUgbmFtZSBvZiB0aGUgZ2l2ZW4gbm9kZSwKKyAgICAgKiBvdGhlcndpc2UgdGhpcyBjcmVhdGVzIGEgbmV3IG5vZGUgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgYW5kCisgICAgICogcmVwbGFjZXMgdGhlIGV4aXN0aW5nIG5vZGUgd2l0aCB0aGUgbmV3IG5vZGUgYXMgZGVzY3JpYmVkIGJlbG93LgorICAgICAqIDxicj5JZiBzaW1wbHkgY2hhbmdpbmcgdGhlIG5hbWUgb2YgdGhlIGdpdmVuIG5vZGUgaXMgbm90IHBvc3NpYmxlLCB0aGUKKyAgICAgKiBmb2xsb3dpbmcgb3BlcmF0aW9ucyBhcmUgcGVyZm9ybWVkOiBhIG5ldyBub2RlIGlzIGNyZWF0ZWQsIGFueQorICAgICAqIHJlZ2lzdGVyZWQgZXZlbnQgbGlzdGVuZXIgaXMgcmVnaXN0ZXJlZCBvbiB0aGUgbmV3IG5vZGUsIGFueSB1c2VyCisgICAgICogZGF0YSBhdHRhY2hlZCB0byB0aGUgb2xkIG5vZGUgaXMgcmVtb3ZlZCBmcm9tIHRoYXQgbm9kZSwgdGhlIG9sZCBub2RlCisgICAgICogaXMgcmVtb3ZlZCBmcm9tIGl0cyBwYXJlbnQgaWYgaXQgaGFzIG9uZSwgdGhlIGNoaWxkcmVuIGFyZSBtb3ZlZCB0bworICAgICAqIHRoZSBuZXcgbm9kZSwgaWYgdGhlIHJlbmFtZWQgbm9kZSBpcyBhbiA8Y29kZT5FbGVtZW50PC9jb2RlPiBpdHMKKyAgICAgKiBhdHRyaWJ1dGVzIGFyZSBtb3ZlZCB0byB0aGUgbmV3IG5vZGUsIHRoZSBuZXcgbm9kZSBpcyBpbnNlcnRlZCBhdCB0aGUKKyAgICAgKiBwb3NpdGlvbiB0aGUgb2xkIG5vZGUgdXNlZCB0byBoYXZlIGluIGl0cyBwYXJlbnQncyBjaGlsZCBub2RlcyBsaXN0CisgICAgICogaWYgaXQgaGFzIG9uZSwgdGhlIHVzZXIgZGF0YSB0aGF0IHdhcyBhdHRhY2hlZCB0byB0aGUgb2xkIG5vZGUgaXMKKyAgICAgKiBhdHRhY2hlZCB0byB0aGUgbmV3IG5vZGUuCisgICAgICogPGJyPldoZW4gdGhlIG5vZGUgYmVpbmcgcmVuYW1lZCBpcyBhbiA8Y29kZT5FbGVtZW50PC9jb2RlPiBvbmx5IHRoZQorICAgICAqIHNwZWNpZmllZCBhdHRyaWJ1dGVzIGFyZSBtb3ZlZCwgZGVmYXVsdCBhdHRyaWJ1dGVzIG9yaWdpbmF0ZWQgZnJvbQorICAgICAqIHRoZSBEVEQgYXJlIHVwZGF0ZWQgYWNjb3JkaW5nIHRvIHRoZSBuZXcgZWxlbWVudCBuYW1lLiBJbiBhZGRpdGlvbiwKKyAgICAgKiB0aGUgaW1wbGVtZW50YXRpb24gbWF5IHVwZGF0ZSBkZWZhdWx0IGF0dHJpYnV0ZXMgZnJvbSBvdGhlciBzY2hlbWFzLgorICAgICAqIEFwcGxpY2F0aW9ucyBzaG91bGQgdXNlIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk8L2NvZGU+IHRvCisgICAgICogZ3VhcmFudGVlIHRoZXNlIGF0dHJpYnV0ZXMgYXJlIHVwLXRvLWRhdGUuCisgICAgICogPGJyPldoZW4gdGhlIG5vZGUgYmVpbmcgcmVuYW1lZCBpcyBhbiA8Y29kZT5BdHRyPC9jb2RlPiB0aGF0IGlzCisgICAgICogYXR0YWNoZWQgdG8gYW4gPGNvZGU+RWxlbWVudDwvY29kZT4sIHRoZSBub2RlIGlzIGZpcnN0IHJlbW92ZWQgZnJvbQorICAgICAqIHRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiBhdHRyaWJ1dGVzIG1hcC4gVGhlbiwgb25jZSByZW5hbWVkLCBlaXRoZXIKKyAgICAgKiBieSBtb2RpZnlpbmcgdGhlIGV4aXN0aW5nIG5vZGUgb3IgY3JlYXRpbmcgYSBuZXcgb25lIGFzIGRlc2NyaWJlZAorICAgICAqIGFib3ZlLCBpdCBpcyBwdXQgYmFjay4KKyAgICAgKiA8YnI+SW4gYWRkaXRpb24sCisgICAgICogPHVsPgorICAgICAqIDxsaT4gYSB1c2VyIGRhdGEgZXZlbnQgPGNvZGU+Tk9ERV9SRU5BTUVEPC9jb2RlPiBpcyBmaXJlZCwKKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT4KKyAgICAgKiB3aGVuIHRoZSBpbXBsZW1lbnRhdGlvbiBzdXBwb3J0cyB0aGUgZmVhdHVyZSAiTXV0YXRpb25OYW1lRXZlbnRzIiwKKyAgICAgKiBlYWNoIG11dGF0aW9uIG9wZXJhdGlvbiBpbnZvbHZlZCBpbiB0aGlzIG1ldGhvZCBmaXJlcyB0aGUgYXBwcm9wcmlhdGUKKyAgICAgKiBldmVudCwgYW5kIGluIHRoZSBlbmQgdGhlIGV2ZW50IHsKKyAgICAgKiA8Y29kZT5odHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHM8L2NvZGU+LAorICAgICAqIDxjb2RlPkRPTUVsZW1lbnROYW1lQ2hhbmdlZDwvY29kZT59IG9yIHsKKyAgICAgKiA8Y29kZT5odHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHM8L2NvZGU+LAorICAgICAqIDxjb2RlPkRPTUF0dHJpYnV0ZU5hbWVDaGFuZ2VkPC9jb2RlPn0gaXMgZmlyZWQuCisgICAgICogPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqIEBwYXJhbSBuIFRoZSBub2RlIHRvIHJlbmFtZS4KKyAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuZXcgbmFtZXNwYWNlIFVSSS4KKyAgICAgKiBAcGFyYW0gcXVhbGlmaWVkTmFtZSBUaGUgbmV3IHF1YWxpZmllZCBuYW1lLgorICAgICAqIEByZXR1cm4gVGhlIHJlbmFtZWQgbm9kZS4gVGhpcyBpcyBlaXRoZXIgdGhlIHNwZWNpZmllZCBub2RlIG9yIHRoZSBuZXcKKyAgICAgKiAgIG5vZGUgdGhhdCB3YXMgY3JlYXRlZCB0byByZXBsYWNlIHRoZSBzcGVjaWZpZWQgbm9kZS4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCB3aGVuIHRoZSB0eXBlIG9mIHRoZSBzcGVjaWZpZWQgbm9kZSBpcworICAgICAqICAgbmVpdGhlciA8Y29kZT5FTEVNRU5UX05PREU8L2NvZGU+IG5vciA8Y29kZT5BVFRSSUJVVEVfTk9ERTwvY29kZT4sCisgICAgICogICBvciBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCB0aGUgcmVuYW1pbmcgb2YgdGhlCisgICAgICogICBkb2N1bWVudCBlbGVtZW50LgorICAgICAqICAgPGJyPklOVkFMSURfQ0hBUkFDVEVSX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgcXVhbGlmaWVkIG5hbWUgaXMgbm90IGFuCisgICAgICogICBYTUwgbmFtZSBhY2NvcmRpbmcgdG8gdGhlIFhNTCB2ZXJzaW9uIGluIHVzZSBzcGVjaWZpZWQgaW4gdGhlCisgICAgICogICA8Y29kZT5Eb2N1bWVudC54bWxWZXJzaW9uPC9jb2RlPiBhdHRyaWJ1dGUuCisgICAgICogICA8YnI+V1JPTkdfRE9DVU1FTlRfRVJSOiBSYWlzZWQgd2hlbiB0aGUgc3BlY2lmaWVkIG5vZGUgd2FzIGNyZWF0ZWQKKyAgICAgKiAgIGZyb20gYSBkaWZmZXJlbnQgZG9jdW1lbnQgdGhhbiB0aGlzIGRvY3VtZW50LgorICAgICAqICAgPGJyPk5BTUVTUEFDRV9FUlI6IFJhaXNlZCBpZiB0aGUgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gaXMgYQorICAgICAqICAgbWFsZm9ybWVkIHF1YWxpZmllZCBuYW1lLCBpZiB0aGUgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gaGFzIGEKKyAgICAgKiAgIHByZWZpeCBhbmQgdGhlIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIG9yCisgICAgICogICBpZiB0aGUgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gaGFzIGEgcHJlZml4IHRoYXQgaXMgInhtbCIgYW5kCisgICAgICogICB0aGUgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyBkaWZmZXJlbnQgZnJvbSAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlJz4KKyAgICAgKiAgIGh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZTwvYT4iIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14bWwtbmFtZXMtMTk5OTAxMTQvJz5YTUwgTmFtZXNwYWNlczwvYT5dCisgICAgICogICAuIEFsc28gcmFpc2VkLCB3aGVuIHRoZSBub2RlIGJlaW5nIHJlbmFtZWQgaXMgYW4gYXR0cmlidXRlLCBpZiB0aGUKKyAgICAgKiAgIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+LCBvciBpdHMgcHJlZml4LCBpcyAieG1sbnMiIGFuZCB0aGUKKyAgICAgKiAgIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgZGlmZmVyZW50IGZyb20gIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvJz5odHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLzwvYT4iLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyBOb2RlIHJlbmFtZU5vZGUoTm9kZSBuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0RvY3VtZW50RnJhZ21lbnQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9Eb2N1bWVudEZyYWdtZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjg3MzkxNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9Eb2N1bWVudEZyYWdtZW50LmphdmEKQEAgLTAsMCArMSw1MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICoKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgorICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCisgKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAorICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCisgKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisgKgorICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tOworCisvKioKKyAqIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IGlzIGEgImxpZ2h0d2VpZ2h0IiBvciAibWluaW1hbCIKKyAqIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBvYmplY3QuIEl0IGlzIHZlcnkgY29tbW9uIHRvIHdhbnQgdG8gYmUgYWJsZSB0bworICogZXh0cmFjdCBhIHBvcnRpb24gb2YgYSBkb2N1bWVudCdzIHRyZWUgb3IgdG8gY3JlYXRlIGEgbmV3IGZyYWdtZW50IG9mIGEKKyAqIGRvY3VtZW50LiBJbWFnaW5lIGltcGxlbWVudGluZyBhIHVzZXIgY29tbWFuZCBsaWtlIGN1dCBvciByZWFycmFuZ2luZyBhCisgKiBkb2N1bWVudCBieSBtb3ZpbmcgZnJhZ21lbnRzIGFyb3VuZC4gSXQgaXMgZGVzaXJhYmxlIHRvIGhhdmUgYW4gb2JqZWN0CisgKiB3aGljaCBjYW4gaG9sZCBzdWNoIGZyYWdtZW50cyBhbmQgaXQgaXMgcXVpdGUgbmF0dXJhbCB0byB1c2UgYSBOb2RlIGZvcgorICogdGhpcyBwdXJwb3NlLiBXaGlsZSBpdCBpcyB0cnVlIHRoYXQgYSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gb2JqZWN0IGNvdWxkCisgKiBmdWxmaWxsIHRoaXMgcm9sZSwgYSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gb2JqZWN0IGNhbiBwb3RlbnRpYWxseSBiZSBhCisgKiBoZWF2eXdlaWdodCBvYmplY3QsIGRlcGVuZGluZyBvbiB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbi4gV2hhdCBpcworICogcmVhbGx5IG5lZWRlZCBmb3IgdGhpcyBpcyBhIHZlcnkgbGlnaHR3ZWlnaHQgb2JqZWN0LgorICogPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4gaXMgc3VjaCBhbiBvYmplY3QuCisgKiA8cD5GdXJ0aGVybW9yZSwgdmFyaW91cyBvcGVyYXRpb25zIC0tIHN1Y2ggYXMgaW5zZXJ0aW5nIG5vZGVzIGFzIGNoaWxkcmVuCisgKiBvZiBhbm90aGVyIDxjb2RlPk5vZGU8L2NvZGU+IC0tIG1heSB0YWtlIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+CisgKiBvYmplY3RzIGFzIGFyZ3VtZW50czsgdGhpcyByZXN1bHRzIGluIGFsbCB0aGUgY2hpbGQgbm9kZXMgb2YgdGhlCisgKiA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBiZWluZyBtb3ZlZCB0byB0aGUgY2hpbGQgbGlzdCBvZiB0aGlzIG5vZGUuCisgKiA8cD5UaGUgY2hpbGRyZW4gb2YgYSA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBub2RlIGFyZSB6ZXJvIG9yIG1vcmUKKyAqIG5vZGVzIHJlcHJlc2VudGluZyB0aGUgdG9wcyBvZiBhbnkgc3ViLXRyZWVzIGRlZmluaW5nIHRoZSBzdHJ1Y3R1cmUgb2YKKyAqIHRoZSBkb2N1bWVudC4gPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4gbm9kZXMgZG8gbm90IG5lZWQgdG8gYmUKKyAqIHdlbGwtZm9ybWVkIFhNTCBkb2N1bWVudHMgKGFsdGhvdWdoIHRoZXkgZG8gbmVlZCB0byBmb2xsb3cgdGhlIHJ1bGVzCisgKiBpbXBvc2VkIHVwb24gd2VsbC1mb3JtZWQgWE1MIHBhcnNlZCBlbnRpdGllcywgd2hpY2ggY2FuIGhhdmUgbXVsdGlwbGUgdG9wCisgKiBub2RlcykuIEZvciBleGFtcGxlLCBhIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IG1pZ2h0IGhhdmUgb25seSBvbmUKKyAqIGNoaWxkIGFuZCB0aGF0IGNoaWxkIG5vZGUgY291bGQgYmUgYSA8Y29kZT5UZXh0PC9jb2RlPiBub2RlLiBTdWNoIGEKKyAqIHN0cnVjdHVyZSBtb2RlbCByZXByZXNlbnRzIG5laXRoZXIgYW4gSFRNTCBkb2N1bWVudCBub3IgYSB3ZWxsLWZvcm1lZCBYTUwKKyAqIGRvY3VtZW50LgorICogPHA+V2hlbiBhIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IGlzIGluc2VydGVkIGludG8gYQorICogPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IChvciBpbmRlZWQgYW55IG90aGVyIDxjb2RlPk5vZGU8L2NvZGU+IHRoYXQgbWF5CisgKiB0YWtlIGNoaWxkcmVuKSB0aGUgY2hpbGRyZW4gb2YgdGhlIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IGFuZCBub3QKKyAqIHRoZSA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBpdHNlbGYgYXJlIGluc2VydGVkIGludG8gdGhlCisgKiA8Y29kZT5Ob2RlPC9jb2RlPi4gVGhpcyBtYWtlcyB0aGUgPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4gdmVyeQorICogdXNlZnVsIHdoZW4gdGhlIHVzZXIgd2lzaGVzIHRvIGNyZWF0ZSBub2RlcyB0aGF0IGFyZSBzaWJsaW5nczsgdGhlCisgKiA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBhY3RzIGFzIHRoZSBwYXJlbnQgb2YgdGhlc2Ugbm9kZXMgc28gdGhhdAorICogdGhlIHVzZXIgY2FuIHVzZSB0aGUgc3RhbmRhcmQgbWV0aG9kcyBmcm9tIHRoZSA8Y29kZT5Ob2RlPC9jb2RlPgorICogaW50ZXJmYWNlLCBzdWNoIGFzIDxjb2RlPk5vZGUuaW5zZXJ0QmVmb3JlPC9jb2RlPiBhbmQKKyAqIDxjb2RlPk5vZGUuYXBwZW5kQ2hpbGQ8L2NvZGU+LgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRG9jdW1lbnRGcmFnbWVudCBleHRlbmRzIE5vZGUgeworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0RvY3VtZW50VHlwZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0RvY3VtZW50VHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc4NTU3ODEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vRG9jdW1lbnRUeXBlLmphdmEKQEAgLTAsMCArMSw4MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICoKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgorICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCisgKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAorICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCisgKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisgKgorICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tOworCisvKioKKyAqIEVhY2ggPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IGhhcyBhIDxjb2RlPmRvY3R5cGU8L2NvZGU+IGF0dHJpYnV0ZSB3aG9zZSB2YWx1ZQorICogaXMgZWl0aGVyIDxjb2RlPm51bGw8L2NvZGU+IG9yIGEgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBvYmplY3QuIFRoZQorICogPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBpbnRlcmZhY2UgaW4gdGhlIERPTSBDb3JlIHByb3ZpZGVzIGFuIGludGVyZmFjZQorICogdG8gdGhlIGxpc3Qgb2YgZW50aXRpZXMgdGhhdCBhcmUgZGVmaW5lZCBmb3IgdGhlIGRvY3VtZW50LCBhbmQgbGl0dGxlCisgKiBlbHNlIGJlY2F1c2UgdGhlIGVmZmVjdCBvZiBuYW1lc3BhY2VzIGFuZCB0aGUgdmFyaW91cyBYTUwgc2NoZW1hIGVmZm9ydHMKKyAqIG9uIERURCByZXByZXNlbnRhdGlvbiBhcmUgbm90IGNsZWFybHkgdW5kZXJzdG9vZCBhcyBvZiB0aGlzIHdyaXRpbmcuCisgKiA8cD5ET00gTGV2ZWwgMyBkb2Vzbid0IHN1cHBvcnQgZWRpdGluZyA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IG5vZGVzLgorICogPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBub2RlcyBhcmUgcmVhZC1vbmx5LgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRG9jdW1lbnRUeXBlIGV4dGVuZHMgTm9kZSB7CisgICAgLyoqCisgICAgICogVGhlIG5hbWUgb2YgRFREOyBpLmUuLCB0aGUgbmFtZSBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlCisgICAgICogPGNvZGU+RE9DVFlQRTwvY29kZT4ga2V5d29yZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKTsKKworICAgIC8qKgorICAgICAqIEEgPGNvZGU+TmFtZWROb2RlTWFwPC9jb2RlPiBjb250YWluaW5nIHRoZSBnZW5lcmFsIGVudGl0aWVzLCBib3RoCisgICAgICogZXh0ZXJuYWwgYW5kIGludGVybmFsLCBkZWNsYXJlZCBpbiB0aGUgRFRELiBQYXJhbWV0ZXIgZW50aXRpZXMgYXJlCisgICAgICogbm90IGNvbnRhaW5lZC4gRHVwbGljYXRlcyBhcmUgZGlzY2FyZGVkLiBGb3IgZXhhbXBsZSBpbjoKKyAgICAgKiA8cHJlPiZsdDshRE9DVFlQRQorICAgICAqIGV4IFNZU1RFTSAiZXguZHRkIiBbICZsdDshRU5USVRZIGZvbyAiZm9vIiZndDsgJmx0OyFFTlRJVFkgYmFyCisgICAgICogImJhciImZ3Q7ICZsdDshRU5USVRZIGJhciAiYmFyMiImZ3Q7ICZsdDshRU5USVRZICUgYmF6ICJiYXoiJmd0OworICAgICAqIF0mZ3Q7ICZsdDtleC8mZ3Q7PC9wcmU+CisgICAgICogIHRoZSBpbnRlcmZhY2UgcHJvdmlkZXMgYWNjZXNzIHRvIDxjb2RlPmZvbzwvY29kZT4KKyAgICAgKiBhbmQgdGhlIGZpcnN0IGRlY2xhcmF0aW9uIG9mIDxjb2RlPmJhcjwvY29kZT4gYnV0IG5vdCB0aGUgc2Vjb25kCisgICAgICogZGVjbGFyYXRpb24gb2YgPGNvZGU+YmFyPC9jb2RlPiBvciA8Y29kZT5iYXo8L2NvZGU+LiBFdmVyeSBub2RlIGluCisgICAgICogdGhpcyBtYXAgYWxzbyBpbXBsZW1lbnRzIHRoZSA8Y29kZT5FbnRpdHk8L2NvZGU+IGludGVyZmFjZS4KKyAgICAgKiA8YnI+VGhlIERPTSBMZXZlbCAyIGRvZXMgbm90IHN1cHBvcnQgZWRpdGluZyBlbnRpdGllcywgdGhlcmVmb3JlCisgICAgICogPGNvZGU+ZW50aXRpZXM8L2NvZGU+IGNhbm5vdCBiZSBhbHRlcmVkIGluIGFueSB3YXkuCisgICAgICovCisgICAgcHVibGljIE5hbWVkTm9kZU1hcCBnZXRFbnRpdGllcygpOworCisgICAgLyoqCisgICAgICogQSA8Y29kZT5OYW1lZE5vZGVNYXA8L2NvZGU+IGNvbnRhaW5pbmcgdGhlIG5vdGF0aW9ucyBkZWNsYXJlZCBpbiB0aGUKKyAgICAgKiBEVEQuIER1cGxpY2F0ZXMgYXJlIGRpc2NhcmRlZC4gRXZlcnkgbm9kZSBpbiB0aGlzIG1hcCBhbHNvIGltcGxlbWVudHMKKyAgICAgKiB0aGUgPGNvZGU+Tm90YXRpb248L2NvZGU+IGludGVyZmFjZS4KKyAgICAgKiA8YnI+VGhlIERPTSBMZXZlbCAyIGRvZXMgbm90IHN1cHBvcnQgZWRpdGluZyBub3RhdGlvbnMsIHRoZXJlZm9yZQorICAgICAqIDxjb2RlPm5vdGF0aW9uczwvY29kZT4gY2Fubm90IGJlIGFsdGVyZWQgaW4gYW55IHdheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTmFtZWROb2RlTWFwIGdldE5vdGF0aW9ucygpOworCisgICAgLyoqCisgICAgICogVGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBleHRlcm5hbCBzdWJzZXQuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAyCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpOworCisgICAgLyoqCisgICAgICogVGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBleHRlcm5hbCBzdWJzZXQuIFRoaXMgbWF5IGJlIGFuIGFic29sdXRlCisgICAgICogVVJJIG9yIG5vdC4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW50ZXJuYWwgc3Vic2V0IGFzIGEgc3RyaW5nLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBpcyBub25lLgorICAgICAqIFRoaXMgaXMgZG9lcyBub3QgY29udGFpbiB0aGUgZGVsaW1pdGluZyBzcXVhcmUgYnJhY2tldHMuCisgICAgICogPHAgPjxiPk5vdGU6PC9iPiBUaGUgYWN0dWFsIGNvbnRlbnQgcmV0dXJuZWQgZGVwZW5kcyBvbiBob3cgbXVjaAorICAgICAqIGluZm9ybWF0aW9uIGlzIGF2YWlsYWJsZSB0byB0aGUgaW1wbGVtZW50YXRpb24uIFRoaXMgbWF5IHZhcnkKKyAgICAgKiBkZXBlbmRpbmcgb24gdmFyaW91cyBwYXJhbWV0ZXJzLCBpbmNsdWRpbmcgdGhlIFhNTCBwcm9jZXNzb3IgdXNlZCB0bworICAgICAqIGJ1aWxkIHRoZSBkb2N1bWVudC4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEludGVybmFsU3Vic2V0KCk7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9FbGVtZW50LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vRWxlbWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJlY2E3ZmMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vRWxlbWVudC5qYXZhCkBAIC0wLDAgKzEsNDM5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKgorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCisgKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKKyAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0CisgKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKKyAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KKyAqCisgKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb207CisKKy8qKgorICogVGhlIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IGludGVyZmFjZSByZXByZXNlbnRzIGFuIGVsZW1lbnQgaW4gYW4gSFRNTCBvciBYTUwKKyAqIGRvY3VtZW50LiBFbGVtZW50cyBtYXkgaGF2ZSBhdHRyaWJ1dGVzIGFzc29jaWF0ZWQgd2l0aCB0aGVtOyBzaW5jZSB0aGUKKyAqIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IGludGVyZmFjZSBpbmhlcml0cyBmcm9tIDxjb2RlPk5vZGU8L2NvZGU+LCB0aGUKKyAqIGdlbmVyaWMgPGNvZGU+Tm9kZTwvY29kZT4gaW50ZXJmYWNlIGF0dHJpYnV0ZSA8Y29kZT5hdHRyaWJ1dGVzPC9jb2RlPiBtYXkKKyAqIGJlIHVzZWQgdG8gcmV0cmlldmUgdGhlIHNldCBvZiBhbGwgYXR0cmlidXRlcyBmb3IgYW4gZWxlbWVudC4gVGhlcmUgYXJlCisgKiBtZXRob2RzIG9uIHRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiBpbnRlcmZhY2UgdG8gcmV0cmlldmUgZWl0aGVyIGFuCisgKiA8Y29kZT5BdHRyPC9jb2RlPiBvYmplY3QgYnkgbmFtZSBvciBhbiBhdHRyaWJ1dGUgdmFsdWUgYnkgbmFtZS4gSW4gWE1MLAorICogd2hlcmUgYW4gYXR0cmlidXRlIHZhbHVlIG1heSBjb250YWluIGVudGl0eSByZWZlcmVuY2VzLCBhbgorICogPGNvZGU+QXR0cjwvY29kZT4gb2JqZWN0IHNob3VsZCBiZSByZXRyaWV2ZWQgdG8gZXhhbWluZSB0aGUgcG9zc2libHkKKyAqIGZhaXJseSBjb21wbGV4IHN1Yi10cmVlIHJlcHJlc2VudGluZyB0aGUgYXR0cmlidXRlIHZhbHVlLiBPbiB0aGUgb3RoZXIKKyAqIGhhbmQsIGluIEhUTUwsIHdoZXJlIGFsbCBhdHRyaWJ1dGVzIGhhdmUgc2ltcGxlIHN0cmluZyB2YWx1ZXMsIG1ldGhvZHMgdG8KKyAqIGRpcmVjdGx5IGFjY2VzcyBhbiBhdHRyaWJ1dGUgdmFsdWUgY2FuIHNhZmVseSBiZSB1c2VkIGFzIGEgY29udmVuaWVuY2UuCisgKiA8cCA+PGI+Tm90ZTo8L2I+IEluIERPTSBMZXZlbCAyLCB0aGUgbWV0aG9kIDxjb2RlPm5vcm1hbGl6ZTwvY29kZT4gaXMKKyAqIGluaGVyaXRlZCBmcm9tIHRoZSA8Y29kZT5Ob2RlPC9jb2RlPiBpbnRlcmZhY2Ugd2hlcmUgaXQgd2FzIG1vdmVkLgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRWxlbWVudCBleHRlbmRzIE5vZGUgeworICAgIC8qKgorICAgICAqIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LiBJZiA8Y29kZT5Ob2RlLmxvY2FsTmFtZTwvY29kZT4gaXMgZGlmZmVyZW50CisgICAgICogZnJvbSA8Y29kZT5udWxsPC9jb2RlPiwgdGhpcyBhdHRyaWJ1dGUgaXMgYSBxdWFsaWZpZWQgbmFtZS4gRm9yCisgICAgICogZXhhbXBsZSwgaW46CisgICAgICogPHByZT4gJmx0O2VsZW1lbnRFeGFtcGxlIGlkPSJkZW1vIiZndDsgLi4uCisgICAgICogJmx0Oy9lbGVtZW50RXhhbXBsZSZndDsgLCA8L3ByZT4KKyAgICAgKiAgPGNvZGU+dGFnTmFtZTwvY29kZT4gaGFzIHRoZSB2YWx1ZQorICAgICAqIDxjb2RlPiJlbGVtZW50RXhhbXBsZSI8L2NvZGU+LiBOb3RlIHRoYXQgdGhpcyBpcyBjYXNlLXByZXNlcnZpbmcgaW4KKyAgICAgKiBYTUwsIGFzIGFyZSBhbGwgb2YgdGhlIG9wZXJhdGlvbnMgb2YgdGhlIERPTS4gVGhlIEhUTUwgRE9NIHJldHVybnMKKyAgICAgKiB0aGUgPGNvZGU+dGFnTmFtZTwvY29kZT4gb2YgYW4gSFRNTCBlbGVtZW50IGluIHRoZSBjYW5vbmljYWwKKyAgICAgKiB1cHBlcmNhc2UgZm9ybSwgcmVnYXJkbGVzcyBvZiB0aGUgY2FzZSBpbiB0aGUgc291cmNlIEhUTUwgZG9jdW1lbnQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRUYWdOYW1lKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYW4gYXR0cmlidXRlIHZhbHVlIGJ5IG5hbWUuCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byByZXRyaWV2ZS4KKyAgICAgKiBAcmV0dXJuIFRoZSA8Y29kZT5BdHRyPC9jb2RlPiB2YWx1ZSBhcyBhIHN0cmluZywgb3IgdGhlIGVtcHR5IHN0cmluZworICAgICAqICAgaWYgdGhhdCBhdHRyaWJ1dGUgZG9lcyBub3QgaGF2ZSBhIHNwZWNpZmllZCBvciBkZWZhdWx0IHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlKFN0cmluZyBuYW1lKTsKKworICAgIC8qKgorICAgICAqIEFkZHMgYSBuZXcgYXR0cmlidXRlLiBJZiBhbiBhdHRyaWJ1dGUgd2l0aCB0aGF0IG5hbWUgaXMgYWxyZWFkeSBwcmVzZW50CisgICAgICogaW4gdGhlIGVsZW1lbnQsIGl0cyB2YWx1ZSBpcyBjaGFuZ2VkIHRvIGJlIHRoYXQgb2YgdGhlIHZhbHVlCisgICAgICogcGFyYW1ldGVyLiBUaGlzIHZhbHVlIGlzIGEgc2ltcGxlIHN0cmluZzsgaXQgaXMgbm90IHBhcnNlZCBhcyBpdCBpcworICAgICAqIGJlaW5nIHNldC4gU28gYW55IG1hcmt1cCAoc3VjaCBhcyBzeW50YXggdG8gYmUgcmVjb2duaXplZCBhcyBhbgorICAgICAqIGVudGl0eSByZWZlcmVuY2UpIGlzIHRyZWF0ZWQgYXMgbGl0ZXJhbCB0ZXh0LCBhbmQgbmVlZHMgdG8gYmUKKyAgICAgKiBhcHByb3ByaWF0ZWx5IGVzY2FwZWQgYnkgdGhlIGltcGxlbWVudGF0aW9uIHdoZW4gaXQgaXMgd3JpdHRlbiBvdXQuCisgICAgICogSW4gb3JkZXIgdG8gYXNzaWduIGFuIGF0dHJpYnV0ZSB2YWx1ZSB0aGF0IGNvbnRhaW5zIGVudGl0eQorICAgICAqIHJlZmVyZW5jZXMsIHRoZSB1c2VyIG11c3QgY3JlYXRlIGFuIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGUgcGx1cyBhbnkKKyAgICAgKiA8Y29kZT5UZXh0PC9jb2RlPiBhbmQgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlcywgYnVpbGQgdGhlCisgICAgICogYXBwcm9wcmlhdGUgc3VidHJlZSwgYW5kIHVzZSA8Y29kZT5zZXRBdHRyaWJ1dGVOb2RlPC9jb2RlPiB0byBhc3NpZ24KKyAgICAgKiBpdCBhcyB0aGUgdmFsdWUgb2YgYW4gYXR0cmlidXRlLgorICAgICAqIDxicj5UbyBzZXQgYW4gYXR0cmlidXRlIHdpdGggYSBxdWFsaWZpZWQgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSwgdXNlCisgICAgICogdGhlIDxjb2RlPnNldEF0dHJpYnV0ZU5TPC9jb2RlPiBtZXRob2QuCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byBjcmVhdGUgb3IgYWx0ZXIuCisgICAgICogQHBhcmFtIHZhbHVlIFZhbHVlIHRvIHNldCBpbiBzdHJpbmcgZm9ybS4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgSU5WQUxJRF9DSEFSQUNURVJfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBuYW1lIGlzIG5vdCBhbiBYTUwKKyAgICAgKiAgIG5hbWUgYWNjb3JkaW5nIHRvIHRoZSBYTUwgdmVyc2lvbiBpbiB1c2Ugc3BlY2lmaWVkIGluIHRoZQorICAgICAqICAgPGNvZGU+RG9jdW1lbnQueG1sVmVyc2lvbjwvY29kZT4gYXR0cmlidXRlLgorICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgYW4gYXR0cmlidXRlIGJ5IG5hbWUuIElmIGEgZGVmYXVsdCB2YWx1ZSBmb3IgdGhlIHJlbW92ZWQKKyAgICAgKiBhdHRyaWJ1dGUgaXMgZGVmaW5lZCBpbiB0aGUgRFRELCBhIG5ldyBhdHRyaWJ1dGUgaW1tZWRpYXRlbHkgYXBwZWFycworICAgICAqIHdpdGggdGhlIGRlZmF1bHQgdmFsdWUgYXMgd2VsbCBhcyB0aGUgY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgVVJJLAorICAgICAqIGxvY2FsIG5hbWUsIGFuZCBwcmVmaXggd2hlbiBhcHBsaWNhYmxlLiBUaGUgaW1wbGVtZW50YXRpb24gbWF5IGhhbmRsZQorICAgICAqIGRlZmF1bHQgdmFsdWVzIGZyb20gb3RoZXIgc2NoZW1hcyBzaW1pbGFybHkgYnV0IGFwcGxpY2F0aW9ucyBzaG91bGQKKyAgICAgKiB1c2UgPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4gdG8gZ3VhcmFudGVlIHRoaXMKKyAgICAgKiBpbmZvcm1hdGlvbiBpcyB1cC10by1kYXRlLgorICAgICAqIDxicj5JZiBubyBhdHRyaWJ1dGUgd2l0aCB0aGlzIG5hbWUgaXMgZm91bmQsIHRoaXMgbWV0aG9kIGhhcyBubyBlZmZlY3QuCisgICAgICogPGJyPlRvIHJlbW92ZSBhbiBhdHRyaWJ1dGUgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSwgdXNlIHRoZQorICAgICAqIDxjb2RlPnJlbW92ZUF0dHJpYnV0ZU5TPC9jb2RlPiBtZXRob2QuCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byByZW1vdmUuCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYW4gYXR0cmlidXRlIG5vZGUgYnkgbmFtZS4KKyAgICAgKiA8YnI+VG8gcmV0cmlldmUgYW4gYXR0cmlidXRlIG5vZGUgYnkgcXVhbGlmaWVkIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkksCisgICAgICogdXNlIHRoZSA8Y29kZT5nZXRBdHRyaWJ1dGVOb2RlTlM8L2NvZGU+IG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSAoPGNvZGU+bm9kZU5hbWU8L2NvZGU+KSBvZiB0aGUgYXR0cmlidXRlIHRvCisgICAgICogICByZXRyaWV2ZS4KKyAgICAgKiBAcmV0dXJuIFRoZSA8Y29kZT5BdHRyPC9jb2RlPiBub2RlIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lICgKKyAgICAgKiAgIDxjb2RlPm5vZGVOYW1lPC9jb2RlPikgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gc3VjaAorICAgICAqICAgYXR0cmlidXRlLgorICAgICAqLworICAgIHB1YmxpYyBBdHRyIGdldEF0dHJpYnV0ZU5vZGUoU3RyaW5nIG5hbWUpOworCisgICAgLyoqCisgICAgICogQWRkcyBhIG5ldyBhdHRyaWJ1dGUgbm9kZS4gSWYgYW4gYXR0cmlidXRlIHdpdGggdGhhdCBuYW1lICgKKyAgICAgKiA8Y29kZT5ub2RlTmFtZTwvY29kZT4pIGlzIGFscmVhZHkgcHJlc2VudCBpbiB0aGUgZWxlbWVudCwgaXQgaXMKKyAgICAgKiByZXBsYWNlZCBieSB0aGUgbmV3IG9uZS4gUmVwbGFjaW5nIGFuIGF0dHJpYnV0ZSBub2RlIGJ5IGl0c2VsZiBoYXMgbm8KKyAgICAgKiBlZmZlY3QuCisgICAgICogPGJyPlRvIGFkZCBhIG5ldyBhdHRyaWJ1dGUgbm9kZSB3aXRoIGEgcXVhbGlmaWVkIG5hbWUgYW5kIG5hbWVzcGFjZQorICAgICAqIFVSSSwgdXNlIHRoZSA8Y29kZT5zZXRBdHRyaWJ1dGVOb2RlTlM8L2NvZGU+IG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gbmV3QXR0ciBUaGUgPGNvZGU+QXR0cjwvY29kZT4gbm9kZSB0byBhZGQgdG8gdGhlIGF0dHJpYnV0ZSBsaXN0LgorICAgICAqIEByZXR1cm4gSWYgdGhlIDxjb2RlPm5ld0F0dHI8L2NvZGU+IGF0dHJpYnV0ZSByZXBsYWNlcyBhbiBleGlzdGluZworICAgICAqICAgYXR0cmlidXRlLCB0aGUgcmVwbGFjZWQgPGNvZGU+QXR0cjwvY29kZT4gbm9kZSBpcyByZXR1cm5lZCwKKyAgICAgKiAgIG90aGVyd2lzZSA8Y29kZT5udWxsPC9jb2RlPiBpcyByZXR1cm5lZC4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgV1JPTkdfRE9DVU1FTlRfRVJSOiBSYWlzZWQgaWYgPGNvZGU+bmV3QXR0cjwvY29kZT4gd2FzIGNyZWF0ZWQgZnJvbSBhCisgICAgICogICBkaWZmZXJlbnQgZG9jdW1lbnQgdGhhbiB0aGUgb25lIHRoYXQgY3JlYXRlZCB0aGUgZWxlbWVudC4KKyAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG5vZGUgaXMgcmVhZG9ubHkuCisgICAgICogICA8YnI+SU5VU0VfQVRUUklCVVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPm5ld0F0dHI8L2NvZGU+IGlzIGFscmVhZHkgYW4KKyAgICAgKiAgIGF0dHJpYnV0ZSBvZiBhbm90aGVyIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG9iamVjdC4gVGhlIERPTSB1c2VyIG11c3QKKyAgICAgKiAgIGV4cGxpY2l0bHkgY2xvbmUgPGNvZGU+QXR0cjwvY29kZT4gbm9kZXMgdG8gcmUtdXNlIHRoZW0gaW4gb3RoZXIKKyAgICAgKiAgIGVsZW1lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBBdHRyIHNldEF0dHJpYnV0ZU5vZGUoQXR0ciBuZXdBdHRyKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUgbm9kZS4gSWYgYSBkZWZhdWx0IHZhbHVlIGZvciB0aGUKKyAgICAgKiByZW1vdmVkIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGUgaXMgZGVmaW5lZCBpbiB0aGUgRFRELCBhIG5ldyBub2RlCisgICAgICogaW1tZWRpYXRlbHkgYXBwZWFycyB3aXRoIHRoZSBkZWZhdWx0IHZhbHVlIGFzIHdlbGwgYXMgdGhlCisgICAgICogY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgVVJJLCBsb2NhbCBuYW1lLCBhbmQgcHJlZml4IHdoZW4gYXBwbGljYWJsZS4KKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gbWF5IGhhbmRsZSBkZWZhdWx0IHZhbHVlcyBmcm9tIG90aGVyIHNjaGVtYXMKKyAgICAgKiBzaW1pbGFybHkgYnV0IGFwcGxpY2F0aW9ucyBzaG91bGQgdXNlCisgICAgICogPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4gdG8gZ3VhcmFudGVlIHRoaXMKKyAgICAgKiBpbmZvcm1hdGlvbiBpcyB1cC10by1kYXRlLgorICAgICAqIEBwYXJhbSBvbGRBdHRyIFRoZSA8Y29kZT5BdHRyPC9jb2RlPiBub2RlIHRvIHJlbW92ZSBmcm9tIHRoZSBhdHRyaWJ1dGUKKyAgICAgKiAgIGxpc3QuCisgICAgICogQHJldHVybiBUaGUgPGNvZGU+QXR0cjwvY29kZT4gbm9kZSB0aGF0IHdhcyByZW1vdmVkLgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG5vZGUgaXMgcmVhZG9ubHkuCisgICAgICogICA8YnI+Tk9UX0ZPVU5EX0VSUjogUmFpc2VkIGlmIDxjb2RlPm9sZEF0dHI8L2NvZGU+IGlzIG5vdCBhbiBhdHRyaWJ1dGUKKyAgICAgKiAgIG9mIHRoZSBlbGVtZW50LgorICAgICAqLworICAgIHB1YmxpYyBBdHRyIHJlbW92ZUF0dHJpYnV0ZU5vZGUoQXR0ciBvbGRBdHRyKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSA8Y29kZT5Ob2RlTGlzdDwvY29kZT4gb2YgYWxsIGRlc2NlbmRhbnQgPGNvZGU+RWxlbWVudHM8L2NvZGU+CisgICAgICogd2l0aCBhIGdpdmVuIHRhZyBuYW1lLCBpbiBkb2N1bWVudCBvcmRlci4KKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdGFnIHRvIG1hdGNoIG9uLiBUaGUgc3BlY2lhbCB2YWx1ZSAiKiIKKyAgICAgKiAgIG1hdGNoZXMgYWxsIHRhZ3MuCisgICAgICogQHJldHVybiBBIGxpc3Qgb2YgbWF0Y2hpbmcgPGNvZGU+RWxlbWVudDwvY29kZT4gbm9kZXMuCisgICAgICovCisgICAgcHVibGljIE5vZGVMaXN0IGdldEVsZW1lbnRzQnlUYWdOYW1lKFN0cmluZyBuYW1lKTsKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyBhbiBhdHRyaWJ1dGUgdmFsdWUgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4KKyAgICAgKiA8YnI+UGVyIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14bWwtbmFtZXMtMTk5OTAxMTQvJz5YTUwgTmFtZXNwYWNlczwvYT5dCisgICAgICogLCBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlIDxjb2RlPm51bGw8L2NvZGU+IGFzIHRoZQorICAgICAqIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gcGFyYW1ldGVyIGZvciBtZXRob2RzIGlmIHRoZXkgd2lzaCB0byBoYXZlCisgICAgICogbm8gbmFtZXNwYWNlLgorICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGF0dHJpYnV0ZSB0byByZXRyaWV2ZS4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgdG8gcmV0cmlldmUuCisgICAgICogQHJldHVybiBUaGUgPGNvZGU+QXR0cjwvY29kZT4gdmFsdWUgYXMgYSBzdHJpbmcsIG9yIHRoZSBlbXB0eSBzdHJpbmcKKyAgICAgKiAgIGlmIHRoYXQgYXR0cmlidXRlIGRvZXMgbm90IGhhdmUgYSBzcGVjaWZpZWQgb3IgZGVmYXVsdCB2YWx1ZS4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IE1heSBiZSByYWlzZWQgaWYgdGhlIGltcGxlbWVudGF0aW9uIGRvZXMgbm90CisgICAgICogICBzdXBwb3J0IHRoZSBmZWF0dXJlIDxjb2RlPiJYTUwiPC9jb2RlPiBhbmQgdGhlIGxhbmd1YWdlIGV4cG9zZWQKKyAgICAgKiAgIHRocm91Z2ggdGhlIERvY3VtZW50IGRvZXMgbm90IHN1cHBvcnQgWE1MIE5hbWVzcGFjZXMgKHN1Y2ggYXMgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLWh0bWw0MDEtMTk5OTEyMjQvJz5IVE1MIDQuMDE8L2E+XSkuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAyCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGEgbmV3IGF0dHJpYnV0ZS4gSWYgYW4gYXR0cmlidXRlIHdpdGggdGhlIHNhbWUgbG9jYWwgbmFtZSBhbmQKKyAgICAgKiBuYW1lc3BhY2UgVVJJIGlzIGFscmVhZHkgcHJlc2VudCBvbiB0aGUgZWxlbWVudCwgaXRzIHByZWZpeCBpcworICAgICAqIGNoYW5nZWQgdG8gYmUgdGhlIHByZWZpeCBwYXJ0IG9mIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiwgYW5kCisgICAgICogaXRzIHZhbHVlIGlzIGNoYW5nZWQgdG8gYmUgdGhlIDxjb2RlPnZhbHVlPC9jb2RlPiBwYXJhbWV0ZXIuIFRoaXMKKyAgICAgKiB2YWx1ZSBpcyBhIHNpbXBsZSBzdHJpbmc7IGl0IGlzIG5vdCBwYXJzZWQgYXMgaXQgaXMgYmVpbmcgc2V0LiBTbyBhbnkKKyAgICAgKiBtYXJrdXAgKHN1Y2ggYXMgc3ludGF4IHRvIGJlIHJlY29nbml6ZWQgYXMgYW4gZW50aXR5IHJlZmVyZW5jZSkgaXMKKyAgICAgKiB0cmVhdGVkIGFzIGxpdGVyYWwgdGV4dCwgYW5kIG5lZWRzIHRvIGJlIGFwcHJvcHJpYXRlbHkgZXNjYXBlZCBieSB0aGUKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiB3aGVuIGl0IGlzIHdyaXR0ZW4gb3V0LiBJbiBvcmRlciB0byBhc3NpZ24gYW4KKyAgICAgKiBhdHRyaWJ1dGUgdmFsdWUgdGhhdCBjb250YWlucyBlbnRpdHkgcmVmZXJlbmNlcywgdGhlIHVzZXIgbXVzdCBjcmVhdGUKKyAgICAgKiBhbiA8Y29kZT5BdHRyPC9jb2RlPiBub2RlIHBsdXMgYW55IDxjb2RlPlRleHQ8L2NvZGU+IGFuZAorICAgICAqIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZXMsIGJ1aWxkIHRoZSBhcHByb3ByaWF0ZSBzdWJ0cmVlLAorICAgICAqIGFuZCB1c2UgPGNvZGU+c2V0QXR0cmlidXRlTm9kZU5TPC9jb2RlPiBvcgorICAgICAqIDxjb2RlPnNldEF0dHJpYnV0ZU5vZGU8L2NvZGU+IHRvIGFzc2lnbiBpdCBhcyB0aGUgdmFsdWUgb2YgYW4KKyAgICAgKiBhdHRyaWJ1dGUuCisgICAgICogPGJyPlBlciBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0Lyc+WE1MIE5hbWVzcGFjZXM8L2E+XQorICAgICAqICwgYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZSA8Y29kZT5udWxsPC9jb2RlPiBhcyB0aGUKKyAgICAgKiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IHBhcmFtZXRlciBmb3IgbWV0aG9kcyBpZiB0aGV5IHdpc2ggdG8gaGF2ZQorICAgICAqIG5vIG5hbWVzcGFjZS4KKyAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBhdHRyaWJ1dGUgdG8gY3JlYXRlIG9yCisgICAgICogICBhbHRlci4KKyAgICAgKiBAcGFyYW0gcXVhbGlmaWVkTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byBjcmVhdGUgb3IKKyAgICAgKiAgIGFsdGVyLgorICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0IGluIHN0cmluZyBmb3JtLgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBJTlZBTElEX0NIQVJBQ1RFUl9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIHF1YWxpZmllZCBuYW1lIGlzIG5vdAorICAgICAqICAgYW4gWE1MIG5hbWUgYWNjb3JkaW5nIHRvIHRoZSBYTUwgdmVyc2lvbiBpbiB1c2Ugc3BlY2lmaWVkIGluIHRoZQorICAgICAqICAgPGNvZGU+RG9jdW1lbnQueG1sVmVyc2lvbjwvY29kZT4gYXR0cmlidXRlLgorICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seS4KKyAgICAgKiAgIDxicj5OQU1FU1BBQ0VfRVJSOiBSYWlzZWQgaWYgdGhlIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IGlzCisgICAgICogICBtYWxmb3JtZWQgcGVyIHRoZSBOYW1lc3BhY2VzIGluIFhNTCBzcGVjaWZpY2F0aW9uLCBpZiB0aGUKKyAgICAgKiAgIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IGhhcyBhIHByZWZpeCBhbmQgdGhlCisgICAgICogICA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LCBpZiB0aGUKKyAgICAgKiAgIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IGhhcyBhIHByZWZpeCB0aGF0IGlzICJ4bWwiIGFuZCB0aGUKKyAgICAgKiAgIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgZGlmZmVyZW50IGZyb20gIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSc+CisgICAgICogICBodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2U8L2E+IiwgaWYgdGhlIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IG9yIGl0cyBwcmVmaXggaXMgInhtbG5zIiBhbmQgdGhlCisgICAgICogICA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzIGRpZmZlcmVudCBmcm9tICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyc+aHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy88L2E+Iiwgb3IgaWYgdGhlIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvJz5odHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLzwvYT4iIGFuZCBuZWl0aGVyIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBub3IgaXRzIHByZWZpeCBpcyAieG1sbnMiLgorICAgICAqICAgPGJyPk5PVF9TVVBQT1JURURfRVJSOiBNYXkgYmUgcmFpc2VkIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdAorICAgICAqICAgc3VwcG9ydCB0aGUgZmVhdHVyZSA8Y29kZT4iWE1MIjwvY29kZT4gYW5kIHRoZSBsYW5ndWFnZSBleHBvc2VkCisgICAgICogICB0aHJvdWdoIHRoZSBEb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IFhNTCBOYW1lc3BhY2VzIChzdWNoIGFzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy1odG1sNDAxLTE5OTkxMjI0Lyc+SFRNTCA0LjAxPC9hPl0pLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGFuIGF0dHJpYnV0ZSBieSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLiBJZiBhIGRlZmF1bHQKKyAgICAgKiB2YWx1ZSBmb3IgdGhlIHJlbW92ZWQgYXR0cmlidXRlIGlzIGRlZmluZWQgaW4gdGhlIERURCwgYSBuZXcKKyAgICAgKiBhdHRyaWJ1dGUgaW1tZWRpYXRlbHkgYXBwZWFycyB3aXRoIHRoZSBkZWZhdWx0IHZhbHVlIGFzIHdlbGwgYXMgdGhlCisgICAgICogY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgVVJJLCBsb2NhbCBuYW1lLCBhbmQgcHJlZml4IHdoZW4gYXBwbGljYWJsZS4KKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gbWF5IGhhbmRsZSBkZWZhdWx0IHZhbHVlcyBmcm9tIG90aGVyIHNjaGVtYXMKKyAgICAgKiBzaW1pbGFybHkgYnV0IGFwcGxpY2F0aW9ucyBzaG91bGQgdXNlCisgICAgICogPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4gdG8gZ3VhcmFudGVlIHRoaXMKKyAgICAgKiBpbmZvcm1hdGlvbiBpcyB1cC10by1kYXRlLgorICAgICAqIDxicj5JZiBubyBhdHRyaWJ1dGUgd2l0aCB0aGlzIGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkgaXMgZm91bmQsCisgICAgICogdGhpcyBtZXRob2QgaGFzIG5vIGVmZmVjdC4KKyAgICAgKiA8YnI+UGVyIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14bWwtbmFtZXMtMTk5OTAxMTQvJz5YTUwgTmFtZXNwYWNlczwvYT5dCisgICAgICogLCBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlIDxjb2RlPm51bGw8L2NvZGU+IGFzIHRoZQorICAgICAqIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gcGFyYW1ldGVyIGZvciBtZXRob2RzIGlmIHRoZXkgd2lzaCB0byBoYXZlCisgICAgICogbm8gbmFtZXNwYWNlLgorICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGF0dHJpYnV0ZSB0byByZW1vdmUuCisgICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIHJlbW92ZS4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgorICAgICAqICAgPGJyPk5PVF9TVVBQT1JURURfRVJSOiBNYXkgYmUgcmFpc2VkIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdAorICAgICAqICAgc3VwcG9ydCB0aGUgZmVhdHVyZSA8Y29kZT4iWE1MIjwvY29kZT4gYW5kIHRoZSBsYW5ndWFnZSBleHBvc2VkCisgICAgICogICB0aHJvdWdoIHRoZSBEb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IFhNTCBOYW1lc3BhY2VzIChzdWNoIGFzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy1odG1sNDAxLTE5OTkxMjI0Lyc+SFRNTCA0LjAxPC9hPl0pLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZUF0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGFuIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGUgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4KKyAgICAgKiA8YnI+UGVyIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14bWwtbmFtZXMtMTk5OTAxMTQvJz5YTUwgTmFtZXNwYWNlczwvYT5dCisgICAgICogLCBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlIDxjb2RlPm51bGw8L2NvZGU+IGFzIHRoZQorICAgICAqIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gcGFyYW1ldGVyIGZvciBtZXRob2RzIGlmIHRoZXkgd2lzaCB0byBoYXZlCisgICAgICogbm8gbmFtZXNwYWNlLgorICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGF0dHJpYnV0ZSB0byByZXRyaWV2ZS4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgdG8gcmV0cmlldmUuCisgICAgICogQHJldHVybiBUaGUgPGNvZGU+QXR0cjwvY29kZT4gbm9kZSB3aXRoIHRoZSBzcGVjaWZpZWQgYXR0cmlidXRlIGxvY2FsCisgICAgICogICBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGlzIG5vIHN1Y2gKKyAgICAgKiAgIGF0dHJpYnV0ZS4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IE1heSBiZSByYWlzZWQgaWYgdGhlIGltcGxlbWVudGF0aW9uIGRvZXMgbm90CisgICAgICogICBzdXBwb3J0IHRoZSBmZWF0dXJlIDxjb2RlPiJYTUwiPC9jb2RlPiBhbmQgdGhlIGxhbmd1YWdlIGV4cG9zZWQKKyAgICAgKiAgIHRocm91Z2ggdGhlIERvY3VtZW50IGRvZXMgbm90IHN1cHBvcnQgWE1MIE5hbWVzcGFjZXMgKHN1Y2ggYXMgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLWh0bWw0MDEtMTk5OTEyMjQvJz5IVE1MIDQuMDE8L2E+XSkuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAyCisgICAgICovCisgICAgcHVibGljIEF0dHIgZ2V0QXR0cmlidXRlTm9kZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGEgbmV3IGF0dHJpYnV0ZS4gSWYgYW4gYXR0cmlidXRlIHdpdGggdGhhdCBsb2NhbCBuYW1lIGFuZCB0aGF0CisgICAgICogbmFtZXNwYWNlIFVSSSBpcyBhbHJlYWR5IHByZXNlbnQgaW4gdGhlIGVsZW1lbnQsIGl0IGlzIHJlcGxhY2VkIGJ5CisgICAgICogdGhlIG5ldyBvbmUuIFJlcGxhY2luZyBhbiBhdHRyaWJ1dGUgbm9kZSBieSBpdHNlbGYgaGFzIG5vIGVmZmVjdC4KKyAgICAgKiA8YnI+UGVyIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14bWwtbmFtZXMtMTk5OTAxMTQvJz5YTUwgTmFtZXNwYWNlczwvYT5dCisgICAgICogLCBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlIDxjb2RlPm51bGw8L2NvZGU+IGFzIHRoZQorICAgICAqIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gcGFyYW1ldGVyIGZvciBtZXRob2RzIGlmIHRoZXkgd2lzaCB0byBoYXZlCisgICAgICogbm8gbmFtZXNwYWNlLgorICAgICAqIEBwYXJhbSBuZXdBdHRyIFRoZSA8Y29kZT5BdHRyPC9jb2RlPiBub2RlIHRvIGFkZCB0byB0aGUgYXR0cmlidXRlIGxpc3QuCisgICAgICogQHJldHVybiBJZiB0aGUgPGNvZGU+bmV3QXR0cjwvY29kZT4gYXR0cmlidXRlIHJlcGxhY2VzIGFuIGV4aXN0aW5nCisgICAgICogICBhdHRyaWJ1dGUgd2l0aCB0aGUgc2FtZSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLCB0aGUgcmVwbGFjZWQKKyAgICAgKiAgIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGUgaXMgcmV0dXJuZWQsIG90aGVyd2lzZSA8Y29kZT5udWxsPC9jb2RlPiBpcworICAgICAqICAgcmV0dXJuZWQuCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIFdST05HX0RPQ1VNRU5UX0VSUjogUmFpc2VkIGlmIDxjb2RlPm5ld0F0dHI8L2NvZGU+IHdhcyBjcmVhdGVkIGZyb20gYQorICAgICAqICAgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhlIGVsZW1lbnQuCisgICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgorICAgICAqICAgPGJyPklOVVNFX0FUVFJJQlVURV9FUlI6IFJhaXNlZCBpZiA8Y29kZT5uZXdBdHRyPC9jb2RlPiBpcyBhbHJlYWR5IGFuCisgICAgICogICBhdHRyaWJ1dGUgb2YgYW5vdGhlciA8Y29kZT5FbGVtZW50PC9jb2RlPiBvYmplY3QuIFRoZSBET00gdXNlciBtdXN0CisgICAgICogICBleHBsaWNpdGx5IGNsb25lIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzIHRvIHJlLXVzZSB0aGVtIGluIG90aGVyCisgICAgICogICBlbGVtZW50cy4KKyAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogTWF5IGJlIHJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3QKKyAgICAgKiAgIHN1cHBvcnQgdGhlIGZlYXR1cmUgPGNvZGU+IlhNTCI8L2NvZGU+IGFuZCB0aGUgbGFuZ3VhZ2UgZXhwb3NlZAorICAgICAqICAgdGhyb3VnaCB0aGUgRG9jdW1lbnQgZG9lcyBub3Qgc3VwcG9ydCBYTUwgTmFtZXNwYWNlcyAoc3VjaCBhcyBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMtaHRtbDQwMS0xOTk5MTIyNC8nPkhUTUwgNC4wMTwvYT5dKS4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgQXR0ciBzZXRBdHRyaWJ1dGVOb2RlTlMoQXR0ciBuZXdBdHRyKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiBvZiBhbGwgdGhlIGRlc2NlbmRhbnQKKyAgICAgKiA8Y29kZT5FbGVtZW50czwvY29kZT4gd2l0aCBhIGdpdmVuIGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkgaW4KKyAgICAgKiBkb2N1bWVudCBvcmRlci4KKyAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBlbGVtZW50cyB0byBtYXRjaCBvbi4gVGhlCisgICAgICogICBzcGVjaWFsIHZhbHVlICIqIiBtYXRjaGVzIGFsbCBuYW1lc3BhY2VzLgorICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGVsZW1lbnRzIHRvIG1hdGNoIG9uLiBUaGUKKyAgICAgKiAgIHNwZWNpYWwgdmFsdWUgIioiIG1hdGNoZXMgYWxsIGxvY2FsIG5hbWVzLgorICAgICAqIEByZXR1cm4gQSBuZXcgPGNvZGU+Tm9kZUxpc3Q8L2NvZGU+IG9iamVjdCBjb250YWluaW5nIGFsbCB0aGUgbWF0Y2hlZAorICAgICAqICAgPGNvZGU+RWxlbWVudHM8L2NvZGU+LgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBOT1RfU1VQUE9SVEVEX0VSUjogTWF5IGJlIHJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3QKKyAgICAgKiAgIHN1cHBvcnQgdGhlIGZlYXR1cmUgPGNvZGU+IlhNTCI8L2NvZGU+IGFuZCB0aGUgbGFuZ3VhZ2UgZXhwb3NlZAorICAgICAqICAgdGhyb3VnaCB0aGUgRG9jdW1lbnQgZG9lcyBub3Qgc3VwcG9ydCBYTUwgTmFtZXNwYWNlcyAoc3VjaCBhcyBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMtaHRtbDQwMS0xOTk5MTIyNC8nPkhUTUwgNC4wMTwvYT5dKS4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgTm9kZUxpc3QgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gd2hlbiBhbiBhdHRyaWJ1dGUgd2l0aCBhIGdpdmVuIG5hbWUgaXMKKyAgICAgKiBzcGVjaWZpZWQgb24gdGhpcyBlbGVtZW50IG9yIGhhcyBhIGRlZmF1bHQgdmFsdWUsIDxjb2RlPmZhbHNlPC9jb2RlPgorICAgICAqIG90aGVyd2lzZS4KKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIGxvb2sgZm9yLgorICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgYW4gYXR0cmlidXRlIHdpdGggdGhlIGdpdmVuIG5hbWUgaXMKKyAgICAgKiAgIHNwZWNpZmllZCBvbiB0aGlzIGVsZW1lbnQgb3IgaGFzIGEgZGVmYXVsdCB2YWx1ZSwgPGNvZGU+ZmFsc2U8L2NvZGU+CisgICAgICogICAgb3RoZXJ3aXNlLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZShTdHJpbmcgbmFtZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IHdoZW4gYW4gYXR0cmlidXRlIHdpdGggYSBnaXZlbiBsb2NhbCBuYW1lIGFuZAorICAgICAqIG5hbWVzcGFjZSBVUkkgaXMgc3BlY2lmaWVkIG9uIHRoaXMgZWxlbWVudCBvciBoYXMgYSBkZWZhdWx0IHZhbHVlLAorICAgICAqIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCisgICAgICogPGJyPlBlciBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0Lyc+WE1MIE5hbWVzcGFjZXM8L2E+XQorICAgICAqICwgYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZSA8Y29kZT5udWxsPC9jb2RlPiBhcyB0aGUKKyAgICAgKiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IHBhcmFtZXRlciBmb3IgbWV0aG9kcyBpZiB0aGV5IHdpc2ggdG8gaGF2ZQorICAgICAqIG5vIG5hbWVzcGFjZS4KKyAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBhdHRyaWJ1dGUgdG8gbG9vayBmb3IuCisgICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIGxvb2sgZm9yLgorICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgYW4gYXR0cmlidXRlIHdpdGggdGhlIGdpdmVuIGxvY2FsIG5hbWUKKyAgICAgKiAgIGFuZCBuYW1lc3BhY2UgVVJJIGlzIHNwZWNpZmllZCBvciBoYXMgYSBkZWZhdWx0IHZhbHVlIG9uIHRoaXMKKyAgICAgKiAgIGVsZW1lbnQsIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIE5PVF9TVVBQT1JURURfRVJSOiBNYXkgYmUgcmFpc2VkIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdAorICAgICAqICAgc3VwcG9ydCB0aGUgZmVhdHVyZSA8Y29kZT4iWE1MIjwvY29kZT4gYW5kIHRoZSBsYW5ndWFnZSBleHBvc2VkCisgICAgICogICB0aHJvdWdoIHRoZSBEb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IFhNTCBOYW1lc3BhY2VzIChzdWNoIGFzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy1odG1sNDAxLTE5OTkxMjI0Lyc+SFRNTCA0LjAxPC9hPl0pLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogIFRoZSB0eXBlIGluZm9ybWF0aW9uIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVsZW1lbnQuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAzCisgICAgICovCisgICAgcHVibGljIFR5cGVJbmZvIGdldFNjaGVtYVR5cGVJbmZvKCk7CisKKyAgICAvKioKKyAgICAgKiAgSWYgdGhlIHBhcmFtZXRlciA8Y29kZT5pc0lkPC9jb2RlPiBpcyA8Y29kZT50cnVlPC9jb2RlPiwgdGhpcyBtZXRob2QKKyAgICAgKiBkZWNsYXJlcyB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZSB0byBiZSBhIHVzZXItZGV0ZXJtaW5lZCBJRCBhdHRyaWJ1dGUKKyAgICAgKiAuIFRoaXMgYWZmZWN0cyB0aGUgdmFsdWUgb2YgPGNvZGU+QXR0ci5pc0lkPC9jb2RlPiBhbmQgdGhlIGJlaGF2aW9yCisgICAgICogb2YgPGNvZGU+RG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQ8L2NvZGU+LCBidXQgZG9lcyBub3QgY2hhbmdlIGFueQorICAgICAqIHNjaGVtYSB0aGF0IG1heSBiZSBpbiB1c2UsIGluIHBhcnRpY3VsYXIgdGhpcyBkb2VzIG5vdCBhZmZlY3QgdGhlCisgICAgICogPGNvZGU+QXR0ci5zY2hlbWFUeXBlSW5mbzwvY29kZT4gb2YgdGhlIHNwZWNpZmllZCA8Y29kZT5BdHRyPC9jb2RlPgorICAgICAqIG5vZGUuIFVzZSB0aGUgdmFsdWUgPGNvZGU+ZmFsc2U8L2NvZGU+IGZvciB0aGUgcGFyYW1ldGVyCisgICAgICogPGNvZGU+aXNJZDwvY29kZT4gdG8gdW5kZWNsYXJlIGFuIGF0dHJpYnV0ZSBmb3IgYmVpbmcgYQorICAgICAqIHVzZXItZGV0ZXJtaW5lZCBJRCBhdHRyaWJ1dGUuCisgICAgICogPGJyPiBUbyBzcGVjaWZ5IGFuIGF0dHJpYnV0ZSBieSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLCB1c2UgdGhlCisgICAgICogPGNvZGU+c2V0SWRBdHRyaWJ1dGVOUzwvY29kZT4gbWV0aG9kLgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCisgICAgICogQHBhcmFtIGlzSWQgV2hldGhlciB0aGUgYXR0cmlidXRlIGlzIGEgb2YgdHlwZSBJRC4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgorICAgICAqICAgPGJyPk5PVF9GT1VORF9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIG5vZGUgaXMgbm90IGFuIGF0dHJpYnV0ZQorICAgICAqICAgb2YgdGhpcyBlbGVtZW50LgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldElkQXR0cmlidXRlKFN0cmluZyBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNJZCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogIElmIHRoZSBwYXJhbWV0ZXIgPGNvZGU+aXNJZDwvY29kZT4gaXMgPGNvZGU+dHJ1ZTwvY29kZT4sIHRoaXMgbWV0aG9kCisgICAgICogZGVjbGFyZXMgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUgdG8gYmUgYSB1c2VyLWRldGVybWluZWQgSUQgYXR0cmlidXRlCisgICAgICogLiBUaGlzIGFmZmVjdHMgdGhlIHZhbHVlIG9mIDxjb2RlPkF0dHIuaXNJZDwvY29kZT4gYW5kIHRoZSBiZWhhdmlvcgorICAgICAqIG9mIDxjb2RlPkRvY3VtZW50LmdldEVsZW1lbnRCeUlkPC9jb2RlPiwgYnV0IGRvZXMgbm90IGNoYW5nZSBhbnkKKyAgICAgKiBzY2hlbWEgdGhhdCBtYXkgYmUgaW4gdXNlLCBpbiBwYXJ0aWN1bGFyIHRoaXMgZG9lcyBub3QgYWZmZWN0IHRoZQorICAgICAqIDxjb2RlPkF0dHIuc2NoZW1hVHlwZUluZm88L2NvZGU+IG9mIHRoZSBzcGVjaWZpZWQgPGNvZGU+QXR0cjwvY29kZT4KKyAgICAgKiBub2RlLiBVc2UgdGhlIHZhbHVlIDxjb2RlPmZhbHNlPC9jb2RlPiBmb3IgdGhlIHBhcmFtZXRlcgorICAgICAqIDxjb2RlPmlzSWQ8L2NvZGU+IHRvIHVuZGVjbGFyZSBhbiBhdHRyaWJ1dGUgZm9yIGJlaW5nIGEKKyAgICAgKiB1c2VyLWRldGVybWluZWQgSUQgYXR0cmlidXRlLgorICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGF0dHJpYnV0ZS4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCisgICAgICogQHBhcmFtIGlzSWQgV2hldGhlciB0aGUgYXR0cmlidXRlIGlzIGEgb2YgdHlwZSBJRC4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgorICAgICAqICAgPGJyPk5PVF9GT1VORF9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIG5vZGUgaXMgbm90IGFuIGF0dHJpYnV0ZQorICAgICAqICAgb2YgdGhpcyBlbGVtZW50LgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldElkQXR0cmlidXRlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlzSWQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogIElmIHRoZSBwYXJhbWV0ZXIgPGNvZGU+aXNJZDwvY29kZT4gaXMgPGNvZGU+dHJ1ZTwvY29kZT4sIHRoaXMgbWV0aG9kCisgICAgICogZGVjbGFyZXMgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUgdG8gYmUgYSB1c2VyLWRldGVybWluZWQgSUQgYXR0cmlidXRlCisgICAgICogLiBUaGlzIGFmZmVjdHMgdGhlIHZhbHVlIG9mIDxjb2RlPkF0dHIuaXNJZDwvY29kZT4gYW5kIHRoZSBiZWhhdmlvcgorICAgICAqIG9mIDxjb2RlPkRvY3VtZW50LmdldEVsZW1lbnRCeUlkPC9jb2RlPiwgYnV0IGRvZXMgbm90IGNoYW5nZSBhbnkKKyAgICAgKiBzY2hlbWEgdGhhdCBtYXkgYmUgaW4gdXNlLCBpbiBwYXJ0aWN1bGFyIHRoaXMgZG9lcyBub3QgYWZmZWN0IHRoZQorICAgICAqIDxjb2RlPkF0dHIuc2NoZW1hVHlwZUluZm88L2NvZGU+IG9mIHRoZSBzcGVjaWZpZWQgPGNvZGU+QXR0cjwvY29kZT4KKyAgICAgKiBub2RlLiBVc2UgdGhlIHZhbHVlIDxjb2RlPmZhbHNlPC9jb2RlPiBmb3IgdGhlIHBhcmFtZXRlcgorICAgICAqIDxjb2RlPmlzSWQ8L2NvZGU+IHRvIHVuZGVjbGFyZSBhbiBhdHRyaWJ1dGUgZm9yIGJlaW5nIGEKKyAgICAgKiB1c2VyLWRldGVybWluZWQgSUQgYXR0cmlidXRlLgorICAgICAqIEBwYXJhbSBpZEF0dHIgVGhlIGF0dHJpYnV0ZSBub2RlLgorICAgICAqIEBwYXJhbSBpc0lkIFdoZXRoZXIgdGhlIGF0dHJpYnV0ZSBpcyBhIG9mIHR5cGUgSUQuCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seS4KKyAgICAgKiAgIDxicj5OT1RfRk9VTkRfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBub2RlIGlzIG5vdCBhbiBhdHRyaWJ1dGUKKyAgICAgKiAgIG9mIHRoaXMgZWxlbWVudC4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRJZEF0dHJpYnV0ZU5vZGUoQXR0ciBpZEF0dHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNJZCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0VudGl0eS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0VudGl0eS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZjODkyNDgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vRW50aXR5LmphdmEKQEAgLTAsMCArMSw5MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICoKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgorICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCisgKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAorICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCisgKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisgKgorICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tOworCisvKioKKyAqIFRoaXMgaW50ZXJmYWNlIHJlcHJlc2VudHMgYSBrbm93biBlbnRpdHksIGVpdGhlciBwYXJzZWQgb3IgdW5wYXJzZWQsIGluIGFuCisgKiBYTUwgZG9jdW1lbnQuIE5vdGUgdGhhdCB0aGlzIG1vZGVscyB0aGUgZW50aXR5IGl0c2VsZiA8ZW0+bm90PC9lbT4gdGhlIGVudGl0eSBkZWNsYXJhdGlvbi4KKyAqIDxwPlRoZSA8Y29kZT5ub2RlTmFtZTwvY29kZT4gYXR0cmlidXRlIHRoYXQgaXMgaW5oZXJpdGVkIGZyb20KKyAqIDxjb2RlPk5vZGU8L2NvZGU+IGNvbnRhaW5zIHRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCisgKiA8cD5BbiBYTUwgcHJvY2Vzc29yIG1heSBjaG9vc2UgdG8gY29tcGxldGVseSBleHBhbmQgZW50aXRpZXMgYmVmb3JlIHRoZQorICogc3RydWN0dXJlIG1vZGVsIGlzIHBhc3NlZCB0byB0aGUgRE9NOyBpbiB0aGlzIGNhc2UgdGhlcmUgd2lsbCBiZSBubworICogPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlcyBpbiB0aGUgZG9jdW1lbnQgdHJlZS4KKyAqIDxwPlhNTCBkb2VzIG5vdCBtYW5kYXRlIHRoYXQgYSBub24tdmFsaWRhdGluZyBYTUwgcHJvY2Vzc29yIHJlYWQgYW5kCisgKiBwcm9jZXNzIGVudGl0eSBkZWNsYXJhdGlvbnMgbWFkZSBpbiB0aGUgZXh0ZXJuYWwgc3Vic2V0IG9yIGRlY2xhcmVkIGluCisgKiBwYXJhbWV0ZXIgZW50aXRpZXMuIFRoaXMgbWVhbnMgdGhhdCBwYXJzZWQgZW50aXRpZXMgZGVjbGFyZWQgaW4gdGhlCisgKiBleHRlcm5hbCBzdWJzZXQgbmVlZCBub3QgYmUgZXhwYW5kZWQgYnkgc29tZSBjbGFzc2VzIG9mIGFwcGxpY2F0aW9ucywgYW5kCisgKiB0aGF0IHRoZSByZXBsYWNlbWVudCB0ZXh0IG9mIHRoZSBlbnRpdHkgbWF5IG5vdCBiZSBhdmFpbGFibGUuIFdoZW4gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCNpbnRlcm4tcmVwbGFjZW1lbnQnPgorICogcmVwbGFjZW1lbnQgdGV4dDwvYT4gaXMgYXZhaWxhYmxlLCB0aGUgY29ycmVzcG9uZGluZyA8Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGUncyBjaGlsZCBsaXN0CisgKiByZXByZXNlbnRzIHRoZSBzdHJ1Y3R1cmUgb2YgdGhhdCByZXBsYWNlbWVudCB2YWx1ZS4gT3RoZXJ3aXNlLCB0aGUgY2hpbGQKKyAqIGxpc3QgaXMgZW1wdHkuCisgKiA8cD5ET00gTGV2ZWwgMyBkb2VzIG5vdCBzdXBwb3J0IGVkaXRpbmcgPGNvZGU+RW50aXR5PC9jb2RlPiBub2RlczsgaWYgYQorICogdXNlciB3YW50cyB0byBtYWtlIGNoYW5nZXMgdG8gdGhlIGNvbnRlbnRzIG9mIGFuIDxjb2RlPkVudGl0eTwvY29kZT4sCisgKiBldmVyeSByZWxhdGVkIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZSBoYXMgdG8gYmUgcmVwbGFjZWQgaW4gdGhlCisgKiBzdHJ1Y3R1cmUgbW9kZWwgYnkgYSBjbG9uZSBvZiB0aGUgPGNvZGU+RW50aXR5PC9jb2RlPidzIGNvbnRlbnRzLCBhbmQKKyAqIHRoZW4gdGhlIGRlc2lyZWQgY2hhbmdlcyBtdXN0IGJlIG1hZGUgdG8gZWFjaCBvZiB0aG9zZSBjbG9uZXMgaW5zdGVhZC4KKyAqIDxjb2RlPkVudGl0eTwvY29kZT4gbm9kZXMgYW5kIGFsbCB0aGVpciBkZXNjZW5kYW50cyBhcmUgcmVhZG9ubHkuCisgKiA8cD5BbiA8Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGUgZG9lcyBub3QgaGF2ZSBhbnkgcGFyZW50LgorICogPHAgPjxiPk5vdGU6PC9iPiBJZiB0aGUgZW50aXR5IGNvbnRhaW5zIGFuIHVuYm91bmQgbmFtZXNwYWNlIHByZWZpeCwgdGhlCisgKiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IG9mIHRoZSBjb3JyZXNwb25kaW5nIG5vZGUgaW4gdGhlCisgKiA8Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGUgc3VidHJlZSBpcyA8Y29kZT5udWxsPC9jb2RlPi4gVGhlIHNhbWUgaXMgdHJ1ZQorICogZm9yIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZXMgdGhhdCByZWZlciB0byB0aGlzIGVudGl0eSwgd2hlbgorICogdGhleSBhcmUgY3JlYXRlZCB1c2luZyB0aGUgPGNvZGU+Y3JlYXRlRW50aXR5UmVmZXJlbmNlPC9jb2RlPiBtZXRob2Qgb2YKKyAqIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gaW50ZXJmYWNlLgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRW50aXR5IGV4dGVuZHMgTm9kZSB7CisgICAgLyoqCisgICAgICogVGhlIHB1YmxpYyBpZGVudGlmaWVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgZW50aXR5IGlmIHNwZWNpZmllZCwgYW5kCisgICAgICogPGNvZGU+bnVsbDwvY29kZT4gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKTsKKworICAgIC8qKgorICAgICAqIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBhc3NvY2lhdGVkIHdpdGggdGhlIGVudGl0eSBpZiBzcGVjaWZpZWQsIGFuZAorICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IG90aGVyd2lzZS4gVGhpcyBtYXkgYmUgYW4gYWJzb2x1dGUgVVJJIG9yIG5vdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCk7CisKKyAgICAvKioKKyAgICAgKiBGb3IgdW5wYXJzZWQgZW50aXRpZXMsIHRoZSBuYW1lIG9mIHRoZSBub3RhdGlvbiBmb3IgdGhlIGVudGl0eS4gRm9yCisgICAgICogcGFyc2VkIGVudGl0aWVzLCB0aGlzIGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm90YXRpb25OYW1lKCk7CisKKyAgICAvKioKKyAgICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZyB0aGUgZW5jb2RpbmcgdXNlZCBmb3IgdGhpcyBlbnRpdHkgYXQgdGhlIHRpbWUKKyAgICAgKiBvZiBwYXJzaW5nLCB3aGVuIGl0IGlzIGFuIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkuIFRoaXMgaXMKKyAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiBpdCBhbiBlbnRpdHkgZnJvbSB0aGUgaW50ZXJuYWwgc3Vic2V0IG9yIGlmIGl0CisgICAgICogaXMgbm90IGtub3duLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0SW5wdXRFbmNvZGluZygpOworCisgICAgLyoqCisgICAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIHRleHQgZGVjbGFyYXRpb24sIHRoZSBlbmNvZGluZworICAgICAqIG9mIHRoaXMgZW50aXR5LCB3aGVuIGl0IGlzIGFuIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkuIFRoaXMgaXMKKyAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBvdGhlcndpc2UuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAzCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRYbWxFbmNvZGluZygpOworCisgICAgLyoqCisgICAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIHRleHQgZGVjbGFyYXRpb24sIHRoZSB2ZXJzaW9uCisgICAgICogbnVtYmVyIG9mIHRoaXMgZW50aXR5LCB3aGVuIGl0IGlzIGFuIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkuIFRoaXMgaXMKKyAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBvdGhlcndpc2UuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAzCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRYbWxWZXJzaW9uKCk7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9FbnRpdHlSZWZlcmVuY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9FbnRpdHlSZWZlcmVuY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NmNjNjYxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL0VudGl0eVJlZmVyZW5jZS5qYXZhCkBAIC0wLDAgKzEsNDMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKKyAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcworICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKKyAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAorICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgorICoKKyAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbTsKKworLyoqCisgKiA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IG5vZGVzIG1heSBiZSB1c2VkIHRvIHJlcHJlc2VudCBhbiBlbnRpdHkKKyAqIHJlZmVyZW5jZSBpbiB0aGUgdHJlZS4gTm90ZSB0aGF0IGNoYXJhY3RlciByZWZlcmVuY2VzIGFuZCByZWZlcmVuY2VzIHRvCisgKiBwcmVkZWZpbmVkIGVudGl0aWVzIGFyZSBjb25zaWRlcmVkIHRvIGJlIGV4cGFuZGVkIGJ5IHRoZSBIVE1MIG9yIFhNTAorICogcHJvY2Vzc29yIHNvIHRoYXQgY2hhcmFjdGVycyBhcmUgcmVwcmVzZW50ZWQgYnkgdGhlaXIgVW5pY29kZSBlcXVpdmFsZW50CisgKiByYXRoZXIgdGhhbiBieSBhbiBlbnRpdHkgcmVmZXJlbmNlLiBNb3Jlb3ZlciwgdGhlIFhNTCBwcm9jZXNzb3IgbWF5CisgKiBjb21wbGV0ZWx5IGV4cGFuZCByZWZlcmVuY2VzIHRvIGVudGl0aWVzIHdoaWxlIGJ1aWxkaW5nIHRoZQorICogPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LCBpbnN0ZWFkIG9mIHByb3ZpZGluZyA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+CisgKiBub2Rlcy4gSWYgaXQgZG9lcyBwcm92aWRlIHN1Y2ggbm9kZXMsIHRoZW4gZm9yIGFuCisgKiA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IG5vZGUgdGhhdCByZXByZXNlbnRzIGEgcmVmZXJlbmNlIHRvIGEga25vd24KKyAqIGVudGl0eSBhbiA8Y29kZT5FbnRpdHk8L2NvZGU+IGV4aXN0cywgYW5kIHRoZSBzdWJ0cmVlIG9mIHRoZQorICogPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlIGlzIGEgY29weSBvZiB0aGUgPGNvZGU+RW50aXR5PC9jb2RlPgorICogbm9kZSBzdWJ0cmVlLiBIb3dldmVyLCB0aGUgbGF0dGVyIG1heSBub3QgYmUgdHJ1ZSB3aGVuIGFuIGVudGl0eSBjb250YWlucworICogYW4gdW5ib3VuZCBuYW1lc3BhY2UgcHJlZml4LiBJbiBzdWNoIGEgY2FzZSwgYmVjYXVzZSB0aGUgbmFtZXNwYWNlIHByZWZpeAorICogcmVzb2x1dGlvbiBkZXBlbmRzIG9uIHdoZXJlIHRoZSBlbnRpdHkgcmVmZXJlbmNlIGlzLCB0aGUgZGVzY2VuZGFudHMgb2YKKyAqIHRoZSA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IG5vZGUgbWF5IGJlIGJvdW5kIHRvIGRpZmZlcmVudCBuYW1lc3BhY2UKKyAqIFVSSXMuIFdoZW4gYW4gPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlIHJlcHJlc2VudHMgYSByZWZlcmVuY2UgdG8KKyAqIGFuIHVua25vd24gZW50aXR5LCB0aGUgbm9kZSBoYXMgbm8gY2hpbGRyZW4gYW5kIGl0cyByZXBsYWNlbWVudCB2YWx1ZSwKKyAqIHdoZW4gdXNlZCBieSA8Y29kZT5BdHRyLnZhbHVlPC9jb2RlPiBmb3IgZXhhbXBsZSwgaXMgZW1wdHkuCisgKiA8cD5BcyBmb3IgPGNvZGU+RW50aXR5PC9jb2RlPiBub2RlcywgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlcyBhbmQKKyAqIGFsbCB0aGVpciBkZXNjZW5kYW50cyBhcmUgcmVhZG9ubHkuCisgKiA8cCA+PGI+Tm90ZTo8L2I+IDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZXMgbWF5IGNhdXNlIGVsZW1lbnQKKyAqIGNvbnRlbnQgYW5kIGF0dHJpYnV0ZSB2YWx1ZSBub3JtYWxpemF0aW9uIHByb2JsZW1zIHdoZW4sIHN1Y2ggYXMgaW4gWE1MCisgKiAxLjAgYW5kIFhNTCBTY2hlbWEsIHRoZSBub3JtYWxpemF0aW9uIGlzIHBlcmZvcm1lZCBhZnRlciBlbnRpdHkgcmVmZXJlbmNlCisgKiBhcmUgZXhwYW5kZWQuCisgKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBTcGVjaWZpY2F0aW9uPC9hPi4KKyAqLworcHVibGljIGludGVyZmFjZSBFbnRpdHlSZWZlcmVuY2UgZXh0ZW5kcyBOb2RlIHsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9OYW1lTGlzdC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL05hbWVMaXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTk0NDMzZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9OYW1lTGlzdC5qYXZhCkBAIC0wLDAgKzEsNjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKKyAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcworICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKKyAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAorICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgorICoKKyAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbTsKKworLyoqCisgKiAgVGhlIDxjb2RlPk5hbWVMaXN0PC9jb2RlPiBpbnRlcmZhY2UgcHJvdmlkZXMgdGhlIGFic3RyYWN0aW9uIG9mIGFuIG9yZGVyZWQKKyAqIGNvbGxlY3Rpb24gb2YgcGFyYWxsZWwgcGFpcnMgb2YgbmFtZSBhbmQgbmFtZXNwYWNlIHZhbHVlcyAod2hpY2ggY291bGQgYmUKKyAqIG51bGwgdmFsdWVzKSwgd2l0aG91dCBkZWZpbmluZyBvciBjb25zdHJhaW5pbmcgaG93IHRoaXMgY29sbGVjdGlvbiBpcworICogaW1wbGVtZW50ZWQuIFRoZSBpdGVtcyBpbiB0aGUgPGNvZGU+TmFtZUxpc3Q8L2NvZGU+IGFyZSBhY2Nlc3NpYmxlIHZpYSBhbgorICogaW50ZWdyYWwgaW5kZXgsIHN0YXJ0aW5nIGZyb20gMC4KKyAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgorICogQHNpbmNlIERPTSBMZXZlbCAzCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgTmFtZUxpc3QgeworICAgIC8qKgorICAgICAqICBSZXR1cm5zIHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBuYW1lIGl0ZW0gaW4gdGhlIGNvbGxlY3Rpb24uCisgICAgICogQHBhcmFtIGluZGV4IEluZGV4IGludG8gdGhlIGNvbGxlY3Rpb24uCisgICAgICogQHJldHVybiAgVGhlIG5hbWUgYXQgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIHBvc2l0aW9uIGluIHRoZQorICAgICAqICAgPGNvZGU+TmFtZUxpc3Q8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBpcyBubyBuYW1lIGZvcgorICAgICAqICAgdGhlIHNwZWNpZmllZCBpbmRleCBvciBpZiB0aGUgaW5kZXggaXMgb3V0IG9mIHJhbmdlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZShpbnQgaW5kZXgpOworCisgICAgLyoqCisgICAgICogIFJldHVybnMgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIG5hbWVzcGFjZVVSSSBpdGVtIGluIHRoZSBjb2xsZWN0aW9uLgorICAgICAqIEBwYXJhbSBpbmRleCBJbmRleCBpbnRvIHRoZSBjb2xsZWN0aW9uLgorICAgICAqIEByZXR1cm4gIFRoZSBuYW1lc3BhY2UgVVJJIGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBwb3NpdGlvbiBpbiB0aGUKKyAgICAgKiAgIDxjb2RlPk5hbWVMaXN0PC9jb2RlPiwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gbmFtZSBmb3IKKyAgICAgKiAgIHRoZSBzcGVjaWZpZWQgaW5kZXggb3IgaWYgdGhlIGluZGV4IGlzIG91dCBvZiByYW5nZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSShpbnQgaW5kZXgpOworCisgICAgLyoqCisgICAgICogIFRoZSBudW1iZXIgb2YgcGFpcnMgKG5hbWUgYW5kIG5hbWVzcGFjZVVSSSkgaW4gdGhlIGxpc3QuIFRoZSByYW5nZSBvZgorICAgICAqIHZhbGlkIGNoaWxkIG5vZGUgaW5kaWNlcyBpcyAwIHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPiBpbmNsdXNpdmUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRMZW5ndGgoKTsKKworICAgIC8qKgorICAgICAqICBUZXN0IGlmIGEgbmFtZSBpcyBwYXJ0IG9mIHRoaXMgPGNvZGU+TmFtZUxpc3Q8L2NvZGU+LgorICAgICAqIEBwYXJhbSBzdHIgIFRoZSBuYW1lIHRvIGxvb2sgZm9yLgorICAgICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBuYW1lIGhhcyBiZWVuIGZvdW5kLAorICAgICAqICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhTdHJpbmcgc3RyKTsKKworICAgIC8qKgorICAgICAqICBUZXN0IGlmIHRoZSBwYWlyIG5hbWVzcGFjZVVSSS9uYW1lIGlzIHBhcnQgb2YgdGhpcworICAgICAqIDxjb2RlPk5hbWVMaXN0PC9jb2RlPi4KKyAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJICBUaGUgbmFtZXNwYWNlIFVSSSB0byBsb29rIGZvci4KKyAgICAgKiBAcGFyYW0gbmFtZSAgVGhlIG5hbWUgdG8gbG9vayBmb3IuCisgICAgICogQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHBhaXIgbmFtZXNwYWNlVVJJL25hbWUgaGFzIGJlZW4KKyAgICAgKiAgIGZvdW5kLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lKTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL05hbWVkTm9kZU1hcC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL05hbWVkTm9kZU1hcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3NGFjZTcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vTmFtZWROb2RlTWFwLmphdmEKQEAgLTAsMCArMSwxODMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKKyAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcworICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKKyAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAorICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgorICoKKyAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbTsKKworLyoqCisgKiBPYmplY3RzIGltcGxlbWVudGluZyB0aGUgPGNvZGU+TmFtZWROb2RlTWFwPC9jb2RlPiBpbnRlcmZhY2UgYXJlIHVzZWQgdG8KKyAqIHJlcHJlc2VudCBjb2xsZWN0aW9ucyBvZiBub2RlcyB0aGF0IGNhbiBiZSBhY2Nlc3NlZCBieSBuYW1lLiBOb3RlIHRoYXQKKyAqIDxjb2RlPk5hbWVkTm9kZU1hcDwvY29kZT4gZG9lcyBub3QgaW5oZXJpdCBmcm9tIDxjb2RlPk5vZGVMaXN0PC9jb2RlPjsKKyAqIDxjb2RlPk5hbWVkTm9kZU1hcHM8L2NvZGU+IGFyZSBub3QgbWFpbnRhaW5lZCBpbiBhbnkgcGFydGljdWxhciBvcmRlci4KKyAqIE9iamVjdHMgY29udGFpbmVkIGluIGFuIG9iamVjdCBpbXBsZW1lbnRpbmcgPGNvZGU+TmFtZWROb2RlTWFwPC9jb2RlPiBtYXkKKyAqIGFsc28gYmUgYWNjZXNzZWQgYnkgYW4gb3JkaW5hbCBpbmRleCwgYnV0IHRoaXMgaXMgc2ltcGx5IHRvIGFsbG93CisgKiBjb252ZW5pZW50IGVudW1lcmF0aW9uIG9mIHRoZSBjb250ZW50cyBvZiBhIDxjb2RlPk5hbWVkTm9kZU1hcDwvY29kZT4sCisgKiBhbmQgZG9lcyBub3QgaW1wbHkgdGhhdCB0aGUgRE9NIHNwZWNpZmllcyBhbiBvcmRlciB0byB0aGVzZSBOb2Rlcy4KKyAqIDxwPjxjb2RlPk5hbWVkTm9kZU1hcDwvY29kZT4gb2JqZWN0cyBpbiB0aGUgRE9NIGFyZSBsaXZlLgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgTmFtZWROb2RlTWFwIHsKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgYSBub2RlIHNwZWNpZmllZCBieSBuYW1lLgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSA8Y29kZT5ub2RlTmFtZTwvY29kZT4gb2YgYSBub2RlIHRvIHJldHJpZXZlLgorICAgICAqIEByZXR1cm4gQSA8Y29kZT5Ob2RlPC9jb2RlPiAob2YgYW55IHR5cGUpIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqICAgPGNvZGU+bm9kZU5hbWU8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBpdCBkb2VzIG5vdCBpZGVudGlmeQorICAgICAqICAgYW55IG5vZGUgaW4gdGhpcyBtYXAuCisgICAgICovCisgICAgcHVibGljIE5vZGUgZ2V0TmFtZWRJdGVtKFN0cmluZyBuYW1lKTsKKworICAgIC8qKgorICAgICAqIEFkZHMgYSBub2RlIHVzaW5nIGl0cyA8Y29kZT5ub2RlTmFtZTwvY29kZT4gYXR0cmlidXRlLiBJZiBhIG5vZGUgd2l0aAorICAgICAqIHRoYXQgbmFtZSBpcyBhbHJlYWR5IHByZXNlbnQgaW4gdGhpcyBtYXAsIGl0IGlzIHJlcGxhY2VkIGJ5IHRoZSBuZXcKKyAgICAgKiBvbmUuIFJlcGxhY2luZyBhIG5vZGUgYnkgaXRzZWxmIGhhcyBubyBlZmZlY3QuCisgICAgICogPGJyPkFzIHRoZSA8Y29kZT5ub2RlTmFtZTwvY29kZT4gYXR0cmlidXRlIGlzIHVzZWQgdG8gZGVyaXZlIHRoZSBuYW1lCisgICAgICogd2hpY2ggdGhlIG5vZGUgbXVzdCBiZSBzdG9yZWQgdW5kZXIsIG11bHRpcGxlIG5vZGVzIG9mIGNlcnRhaW4gdHlwZXMKKyAgICAgKiAodGhvc2UgdGhhdCBoYXZlIGEgInNwZWNpYWwiIHN0cmluZyB2YWx1ZSkgY2Fubm90IGJlIHN0b3JlZCBhcyB0aGUKKyAgICAgKiBuYW1lcyB3b3VsZCBjbGFzaC4gVGhpcyBpcyBzZWVuIGFzIHByZWZlcmFibGUgdG8gYWxsb3dpbmcgbm9kZXMgdG8gYmUKKyAgICAgKiBhbGlhc2VkLgorICAgICAqIEBwYXJhbSBhcmcgQSBub2RlIHRvIHN0b3JlIGluIHRoaXMgbWFwLiBUaGUgbm9kZSB3aWxsIGxhdGVyIGJlCisgICAgICogICBhY2Nlc3NpYmxlIHVzaW5nIHRoZSB2YWx1ZSBvZiBpdHMgPGNvZGU+bm9kZU5hbWU8L2NvZGU+IGF0dHJpYnV0ZS4KKyAgICAgKiBAcmV0dXJuIElmIHRoZSBuZXcgPGNvZGU+Tm9kZTwvY29kZT4gcmVwbGFjZXMgYW4gZXhpc3Rpbmcgbm9kZSB0aGUKKyAgICAgKiAgIHJlcGxhY2VkIDxjb2RlPk5vZGU8L2NvZGU+IGlzIHJldHVybmVkLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4KKyAgICAgKiAgIGlzIHJldHVybmVkLgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBXUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiA8Y29kZT5hcmc8L2NvZGU+IHdhcyBjcmVhdGVkIGZyb20gYQorICAgICAqICAgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyBtYXAuCisgICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBtYXAgaXMgcmVhZG9ubHkuCisgICAgICogICA8YnI+SU5VU0VfQVRUUklCVVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPmFyZzwvY29kZT4gaXMgYW4KKyAgICAgKiAgIDxjb2RlPkF0dHI8L2NvZGU+IHRoYXQgaXMgYWxyZWFkeSBhbiBhdHRyaWJ1dGUgb2YgYW5vdGhlcgorICAgICAqICAgPGNvZGU+RWxlbWVudDwvY29kZT4gb2JqZWN0LiBUaGUgRE9NIHVzZXIgbXVzdCBleHBsaWNpdGx5IGNsb25lCisgICAgICogICA8Y29kZT5BdHRyPC9jb2RlPiBub2RlcyB0byByZS11c2UgdGhlbSBpbiBvdGhlciBlbGVtZW50cy4KKyAgICAgKiAgIDxicj5ISUVSQVJDSFlfUkVRVUVTVF9FUlI6IFJhaXNlZCBpZiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gYWRkIGEgbm9kZQorICAgICAqICAgZG9lc24ndCBiZWxvbmcgaW4gdGhpcyBOYW1lZE5vZGVNYXAuIEV4YW1wbGVzIHdvdWxkIGluY2x1ZGUgdHJ5aW5nCisgICAgICogICB0byBpbnNlcnQgc29tZXRoaW5nIG90aGVyIHRoYW4gYW4gQXR0ciBub2RlIGludG8gYW4gRWxlbWVudCdzIG1hcAorICAgICAqICAgb2YgYXR0cmlidXRlcywgb3IgYSBub24tRW50aXR5IG5vZGUgaW50byB0aGUgRG9jdW1lbnRUeXBlJ3MgbWFwIG9mCisgICAgICogICBFbnRpdGllcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9kZSBzZXROYW1lZEl0ZW0oTm9kZSBhcmcpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGEgbm9kZSBzcGVjaWZpZWQgYnkgbmFtZS4gV2hlbiB0aGlzIG1hcCBjb250YWlucyB0aGUgYXR0cmlidXRlcworICAgICAqIGF0dGFjaGVkIHRvIGFuIGVsZW1lbnQsIGlmIHRoZSByZW1vdmVkIGF0dHJpYnV0ZSBpcyBrbm93biB0byBoYXZlIGEKKyAgICAgKiBkZWZhdWx0IHZhbHVlLCBhbiBhdHRyaWJ1dGUgaW1tZWRpYXRlbHkgYXBwZWFycyBjb250YWluaW5nIHRoZQorICAgICAqIGRlZmF1bHQgdmFsdWUgYXMgd2VsbCBhcyB0aGUgY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgVVJJLCBsb2NhbCBuYW1lLAorICAgICAqIGFuZCBwcmVmaXggd2hlbiBhcHBsaWNhYmxlLgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSA8Y29kZT5ub2RlTmFtZTwvY29kZT4gb2YgdGhlIG5vZGUgdG8gcmVtb3ZlLgorICAgICAqIEByZXR1cm4gVGhlIG5vZGUgcmVtb3ZlZCBmcm9tIHRoaXMgbWFwIGlmIGEgbm9kZSB3aXRoIHN1Y2ggYSBuYW1lCisgICAgICogICBleGlzdHMuCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIE5PVF9GT1VORF9FUlI6IFJhaXNlZCBpZiB0aGVyZSBpcyBubyBub2RlIG5hbWVkIDxjb2RlPm5hbWU8L2NvZGU+IGluCisgICAgICogICB0aGlzIG1hcC4KKyAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG1hcCBpcyByZWFkb25seS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9kZSByZW1vdmVOYW1lZEl0ZW0oU3RyaW5nIG5hbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBpdGVtIGluIHRoZSBtYXAuIElmIDxjb2RlPmluZGV4PC9jb2RlPgorICAgICAqIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgbWFwLCB0aGlzCisgICAgICogcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKiBAcGFyYW0gaW5kZXggSW5kZXggaW50byB0aGlzIG1hcC4KKyAgICAgKiBAcmV0dXJuIFRoZSBub2RlIGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBwb3NpdGlvbiBpbiB0aGUgbWFwLCBvcgorICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhhdCBpcyBub3QgYSB2YWxpZCBpbmRleC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9kZSBpdGVtKGludCBpbmRleCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgbWFwLiBUaGUgcmFuZ2Ugb2YgdmFsaWQgY2hpbGQgbm9kZSBpbmRpY2VzCisgICAgICogaXMgPGNvZGU+MDwvY29kZT4gdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOworCisgICAgLyoqCisgICAgICogUmV0cmlldmVzIGEgbm9kZSBzcGVjaWZpZWQgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4KKyAgICAgKiA8YnI+UGVyIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14bWwtbmFtZXMtMTk5OTAxMTQvJz5YTUwgTmFtZXNwYWNlczwvYT5dCisgICAgICogLCBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlIG51bGwgYXMgdGhlIG5hbWVzcGFjZVVSSSBwYXJhbWV0ZXIKKyAgICAgKiBmb3IgbWV0aG9kcyBpZiB0aGV5IHdpc2ggdG8gaGF2ZSBubyBuYW1lc3BhY2UuCisgICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgbm9kZSB0byByZXRyaWV2ZS4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBub2RlIHRvIHJldHJpZXZlLgorICAgICAqIEByZXR1cm4gQSA8Y29kZT5Ob2RlPC9jb2RlPiAob2YgYW55IHR5cGUpIHdpdGggdGhlIHNwZWNpZmllZCBsb2NhbAorICAgICAqICAgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhleSBkbyBub3QKKyAgICAgKiAgIGlkZW50aWZ5IGFueSBub2RlIGluIHRoaXMgbWFwLgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBOT1RfU1VQUE9SVEVEX0VSUjogTWF5IGJlIHJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3QKKyAgICAgKiAgIHN1cHBvcnQgdGhlIGZlYXR1cmUgIlhNTCIgYW5kIHRoZSBsYW5ndWFnZSBleHBvc2VkIHRocm91Z2ggdGhlCisgICAgICogICBEb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IFhNTCBOYW1lc3BhY2VzIChzdWNoIGFzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy1odG1sNDAxLTE5OTkxMjI0Lyc+SFRNTCA0LjAxPC9hPl0pLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgorICAgICAqLworICAgIHB1YmxpYyBOb2RlIGdldE5hbWVkSXRlbU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQWRkcyBhIG5vZGUgdXNpbmcgaXRzIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gYW5kCisgICAgICogPGNvZGU+bG9jYWxOYW1lPC9jb2RlPi4gSWYgYSBub2RlIHdpdGggdGhhdCBuYW1lc3BhY2UgVVJJIGFuZCB0aGF0CisgICAgICogbG9jYWwgbmFtZSBpcyBhbHJlYWR5IHByZXNlbnQgaW4gdGhpcyBtYXAsIGl0IGlzIHJlcGxhY2VkIGJ5IHRoZSBuZXcKKyAgICAgKiBvbmUuIFJlcGxhY2luZyBhIG5vZGUgYnkgaXRzZWxmIGhhcyBubyBlZmZlY3QuCisgICAgICogPGJyPlBlciBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0Lyc+WE1MIE5hbWVzcGFjZXM8L2E+XQorICAgICAqICwgYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZSBudWxsIGFzIHRoZSBuYW1lc3BhY2VVUkkgcGFyYW1ldGVyCisgICAgICogZm9yIG1ldGhvZHMgaWYgdGhleSB3aXNoIHRvIGhhdmUgbm8gbmFtZXNwYWNlLgorICAgICAqIEBwYXJhbSBhcmcgQSBub2RlIHRvIHN0b3JlIGluIHRoaXMgbWFwLiBUaGUgbm9kZSB3aWxsIGxhdGVyIGJlCisgICAgICogICBhY2Nlc3NpYmxlIHVzaW5nIHRoZSB2YWx1ZSBvZiBpdHMgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBhbmQKKyAgICAgKiAgIDxjb2RlPmxvY2FsTmFtZTwvY29kZT4gYXR0cmlidXRlcy4KKyAgICAgKiBAcmV0dXJuIElmIHRoZSBuZXcgPGNvZGU+Tm9kZTwvY29kZT4gcmVwbGFjZXMgYW4gZXhpc3Rpbmcgbm9kZSB0aGUKKyAgICAgKiAgIHJlcGxhY2VkIDxjb2RlPk5vZGU8L2NvZGU+IGlzIHJldHVybmVkLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4KKyAgICAgKiAgIGlzIHJldHVybmVkLgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBXUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiA8Y29kZT5hcmc8L2NvZGU+IHdhcyBjcmVhdGVkIGZyb20gYQorICAgICAqICAgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyBtYXAuCisgICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBtYXAgaXMgcmVhZG9ubHkuCisgICAgICogICA8YnI+SU5VU0VfQVRUUklCVVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPmFyZzwvY29kZT4gaXMgYW4KKyAgICAgKiAgIDxjb2RlPkF0dHI8L2NvZGU+IHRoYXQgaXMgYWxyZWFkeSBhbiBhdHRyaWJ1dGUgb2YgYW5vdGhlcgorICAgICAqICAgPGNvZGU+RWxlbWVudDwvY29kZT4gb2JqZWN0LiBUaGUgRE9NIHVzZXIgbXVzdCBleHBsaWNpdGx5IGNsb25lCisgICAgICogICA8Y29kZT5BdHRyPC9jb2RlPiBub2RlcyB0byByZS11c2UgdGhlbSBpbiBvdGhlciBlbGVtZW50cy4KKyAgICAgKiAgIDxicj5ISUVSQVJDSFlfUkVRVUVTVF9FUlI6IFJhaXNlZCBpZiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gYWRkIGEgbm9kZQorICAgICAqICAgZG9lc24ndCBiZWxvbmcgaW4gdGhpcyBOYW1lZE5vZGVNYXAuIEV4YW1wbGVzIHdvdWxkIGluY2x1ZGUgdHJ5aW5nCisgICAgICogICB0byBpbnNlcnQgc29tZXRoaW5nIG90aGVyIHRoYW4gYW4gQXR0ciBub2RlIGludG8gYW4gRWxlbWVudCdzIG1hcAorICAgICAqICAgb2YgYXR0cmlidXRlcywgb3IgYSBub24tRW50aXR5IG5vZGUgaW50byB0aGUgRG9jdW1lbnRUeXBlJ3MgbWFwIG9mCisgICAgICogICBFbnRpdGllcy4KKyAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogTWF5IGJlIHJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3QKKyAgICAgKiAgIHN1cHBvcnQgdGhlIGZlYXR1cmUgIlhNTCIgYW5kIHRoZSBsYW5ndWFnZSBleHBvc2VkIHRocm91Z2ggdGhlCisgICAgICogICBEb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IFhNTCBOYW1lc3BhY2VzIChzdWNoIGFzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy1odG1sNDAxLTE5OTkxMjI0Lyc+SFRNTCA0LjAxPC9hPl0pLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgorICAgICAqLworICAgIHB1YmxpYyBOb2RlIHNldE5hbWVkSXRlbU5TKE5vZGUgYXJnKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIGEgbm9kZSBzcGVjaWZpZWQgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4gQSByZW1vdmVkCisgICAgICogYXR0cmlidXRlIG1heSBiZSBrbm93biB0byBoYXZlIGEgZGVmYXVsdCB2YWx1ZSB3aGVuIHRoaXMgbWFwIGNvbnRhaW5zCisgICAgICogdGhlIGF0dHJpYnV0ZXMgYXR0YWNoZWQgdG8gYW4gZWxlbWVudCwgYXMgcmV0dXJuZWQgYnkgdGhlIGF0dHJpYnV0ZXMKKyAgICAgKiBhdHRyaWJ1dGUgb2YgdGhlIDxjb2RlPk5vZGU8L2NvZGU+IGludGVyZmFjZS4gSWYgc28sIGFuIGF0dHJpYnV0ZQorICAgICAqIGltbWVkaWF0ZWx5IGFwcGVhcnMgY29udGFpbmluZyB0aGUgZGVmYXVsdCB2YWx1ZSBhcyB3ZWxsIGFzIHRoZQorICAgICAqIGNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlIFVSSSwgbG9jYWwgbmFtZSwgYW5kIHByZWZpeCB3aGVuIGFwcGxpY2FibGUuCisgICAgICogPGJyPlBlciBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0Lyc+WE1MIE5hbWVzcGFjZXM8L2E+XQorICAgICAqICwgYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZSBudWxsIGFzIHRoZSBuYW1lc3BhY2VVUkkgcGFyYW1ldGVyCisgICAgICogZm9yIG1ldGhvZHMgaWYgdGhleSB3aXNoIHRvIGhhdmUgbm8gbmFtZXNwYWNlLgorICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIG5vZGUgdG8gcmVtb3ZlLgorICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIG5vZGUgdG8gcmVtb3ZlLgorICAgICAqIEByZXR1cm4gVGhlIG5vZGUgcmVtb3ZlZCBmcm9tIHRoaXMgbWFwIGlmIGEgbm9kZSB3aXRoIHN1Y2ggYSBsb2NhbAorICAgICAqICAgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSBleGlzdHMuCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIE5PVF9GT1VORF9FUlI6IFJhaXNlZCBpZiB0aGVyZSBpcyBubyBub2RlIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqICAgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBhbmQgPGNvZGU+bG9jYWxOYW1lPC9jb2RlPiBpbiB0aGlzIG1hcC4KKyAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG1hcCBpcyByZWFkb25seS4KKyAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogTWF5IGJlIHJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3QKKyAgICAgKiAgIHN1cHBvcnQgdGhlIGZlYXR1cmUgIlhNTCIgYW5kIHRoZSBsYW5ndWFnZSBleHBvc2VkIHRocm91Z2ggdGhlCisgICAgICogICBEb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IFhNTCBOYW1lc3BhY2VzIChzdWNoIGFzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy1odG1sNDAxLTE5OTkxMjI0Lyc+SFRNTCA0LjAxPC9hPl0pLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgorICAgICAqLworICAgIHB1YmxpYyBOb2RlIHJlbW92ZU5hbWVkSXRlbU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vTm9kZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL05vZGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOWE2ZDAwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL05vZGUuamF2YQpAQCAtMCwwICsxLDkwMCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICoKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgorICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCisgKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAorICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCisgKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisgKgorICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tOworCisvKioKKyAqIFRoZSA8Y29kZT5Ob2RlPC9jb2RlPiBpbnRlcmZhY2UgaXMgdGhlIHByaW1hcnkgZGF0YXR5cGUgZm9yIHRoZSBlbnRpcmUKKyAqIERvY3VtZW50IE9iamVjdCBNb2RlbC4gSXQgcmVwcmVzZW50cyBhIHNpbmdsZSBub2RlIGluIHRoZSBkb2N1bWVudCB0cmVlLgorICogV2hpbGUgYWxsIG9iamVjdHMgaW1wbGVtZW50aW5nIHRoZSA8Y29kZT5Ob2RlPC9jb2RlPiBpbnRlcmZhY2UgZXhwb3NlCisgKiBtZXRob2RzIGZvciBkZWFsaW5nIHdpdGggY2hpbGRyZW4sIG5vdCBhbGwgb2JqZWN0cyBpbXBsZW1lbnRpbmcgdGhlCisgKiA8Y29kZT5Ob2RlPC9jb2RlPiBpbnRlcmZhY2UgbWF5IGhhdmUgY2hpbGRyZW4uIEZvciBleGFtcGxlLAorICogPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMgbWF5IG5vdCBoYXZlIGNoaWxkcmVuLCBhbmQgYWRkaW5nIGNoaWxkcmVuIHRvCisgKiBzdWNoIG5vZGVzIHJlc3VsdHMgaW4gYSA8Y29kZT5ET01FeGNlcHRpb248L2NvZGU+IGJlaW5nIHJhaXNlZC4KKyAqIDxwPlRoZSBhdHRyaWJ1dGVzIDxjb2RlPm5vZGVOYW1lPC9jb2RlPiwgPGNvZGU+bm9kZVZhbHVlPC9jb2RlPiBhbmQKKyAqIDxjb2RlPmF0dHJpYnV0ZXM8L2NvZGU+IGFyZSBpbmNsdWRlZCBhcyBhIG1lY2hhbmlzbSB0byBnZXQgYXQgbm9kZQorICogaW5mb3JtYXRpb24gd2l0aG91dCBjYXN0aW5nIGRvd24gdG8gdGhlIHNwZWNpZmljIGRlcml2ZWQgaW50ZXJmYWNlLiBJbgorICogY2FzZXMgd2hlcmUgdGhlcmUgaXMgbm8gb2J2aW91cyBtYXBwaW5nIG9mIHRoZXNlIGF0dHJpYnV0ZXMgZm9yIGEKKyAqIHNwZWNpZmljIDxjb2RlPm5vZGVUeXBlPC9jb2RlPiAoZS5nLiwgPGNvZGU+bm9kZVZhbHVlPC9jb2RlPiBmb3IgYW4KKyAqIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG9yIDxjb2RlPmF0dHJpYnV0ZXM8L2NvZGU+IGZvciBhIDxjb2RlPkNvbW1lbnQ8L2NvZGU+CisgKiApLCB0aGlzIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uIE5vdGUgdGhhdCB0aGUgc3BlY2lhbGl6ZWQgaW50ZXJmYWNlcworICogbWF5IGNvbnRhaW4gYWRkaXRpb25hbCBhbmQgbW9yZSBjb252ZW5pZW50IG1lY2hhbmlzbXMgdG8gZ2V0IGFuZCBzZXQgdGhlCisgKiByZWxldmFudCBpbmZvcm1hdGlvbi4KKyAqIDxwPlRoZSB2YWx1ZXMgb2YgPGNvZGU+bm9kZU5hbWU8L2NvZGU+LAorICogPGNvZGU+bm9kZVZhbHVlPC9jb2RlPiwgYW5kIDxjb2RlPmF0dHJpYnV0ZXM8L2NvZGU+IHZhcnkgYWNjb3JkaW5nIHRvIHRoZQorICogbm9kZSB0eXBlIGFzIGZvbGxvd3M6CisgKiA8dGFibGUgYm9yZGVyPScxJyBjZWxscGFkZGluZz0nMyc+CisgKiA8dHI+CisgKiA8dGg+SW50ZXJmYWNlPC90aD4KKyAqIDx0aD5ub2RlTmFtZTwvdGg+CisgKiA8dGg+bm9kZVZhbHVlPC90aD4KKyAqIDx0aD5hdHRyaWJ1dGVzPC90aD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICogPGNvZGU+QXR0cjwvY29kZT48L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5zYW1lIGFzIDxjb2RlPkF0dHIubmFtZTwvY29kZT48L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5zYW1lIGFzCisgKiA8Y29kZT5BdHRyLnZhbHVlPC9jb2RlPjwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPm51bGw8L2NvZGU+PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT48L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KKyAqIDxjb2RlPiIjY2RhdGEtc2VjdGlvbiI8L2NvZGU+PC90ZD4KKyAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+c2FtZSBhcyA8Y29kZT5DaGFyYWN0ZXJEYXRhLmRhdGE8L2NvZGU+LCB0aGUKKyAqIGNvbnRlbnQgb2YgdGhlIENEQVRBIFNlY3Rpb248L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5udWxsPC9jb2RlPjwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5Db21tZW50PC9jb2RlPjwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICogPGNvZGU+IiNjb21tZW50IjwvY29kZT48L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5zYW1lIGFzIDxjb2RlPkNoYXJhY3RlckRhdGEuZGF0YTwvY29kZT4sIHRoZQorICogY29udGVudCBvZiB0aGUgY29tbWVudDwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPm51bGw8L2NvZGU+PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPkRvY3VtZW50PC9jb2RlPjwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICogPGNvZGU+IiNkb2N1bWVudCI8L2NvZGU+PC90ZD4KKyAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+bnVsbDwvY29kZT48L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5udWxsPC9jb2RlPjwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KKyAqIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+PC90ZD4KKyAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+IiNkb2N1bWVudC1mcmFnbWVudCI8L2NvZGU+PC90ZD4KKyAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+CisgKiA8Y29kZT5udWxsPC9jb2RlPjwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPm51bGw8L2NvZGU+PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT48L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5zYW1lIGFzCisgKiA8Y29kZT5Eb2N1bWVudFR5cGUubmFtZTwvY29kZT48L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5udWxsPC9jb2RlPjwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPm51bGw8L2NvZGU+PC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICogPGNvZGU+RWxlbWVudDwvY29kZT48L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5zYW1lIGFzIDxjb2RlPkVsZW1lbnQudGFnTmFtZTwvY29kZT48L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5udWxsPC9jb2RlPjwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICogPGNvZGU+TmFtZWROb2RlTWFwPC9jb2RlPjwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5FbnRpdHk8L2NvZGU+PC90ZD4KKyAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+ZW50aXR5IG5hbWU8L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5udWxsPC9jb2RlPjwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICogPGNvZGU+bnVsbDwvY29kZT48L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPjwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPm5hbWUgb2YgZW50aXR5IHJlZmVyZW5jZWQ8L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KKyAqIDxjb2RlPm51bGw8L2NvZGU+PC90ZD4KKyAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+bnVsbDwvY29kZT48L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+Tm90YXRpb248L2NvZGU+PC90ZD4KKyAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+bm90YXRpb24gbmFtZTwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICogPGNvZGU+bnVsbDwvY29kZT48L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5udWxsPC9jb2RlPjwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb248L2NvZGU+PC90ZD4KKyAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+c2FtZQorICogYXMgPGNvZGU+UHJvY2Vzc2luZ0luc3RydWN0aW9uLnRhcmdldDwvY29kZT48L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5zYW1lIGFzCisgKiA8Y29kZT5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb24uZGF0YTwvY29kZT48L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5udWxsPC9jb2RlPjwvdGQ+CisgKiA8L3RyPgorICogPHRyPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5UZXh0PC9jb2RlPjwvdGQ+CisgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgorICogPGNvZGU+IiN0ZXh0IjwvY29kZT48L3RkPgorICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5zYW1lIGFzIDxjb2RlPkNoYXJhY3RlckRhdGEuZGF0YTwvY29kZT4sIHRoZSBjb250ZW50CisgKiBvZiB0aGUgdGV4dCBub2RlPC90ZD4KKyAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+bnVsbDwvY29kZT48L3RkPgorICogPC90cj4KKyAqIDwvdGFibGU+CisgKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBTcGVjaWZpY2F0aW9uPC9hPi4KKyAqLworcHVibGljIGludGVyZmFjZSBOb2RlIHsKKyAgICAvLyBOb2RlVHlwZQorICAgIC8qKgorICAgICAqIFRoZSBub2RlIGlzIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRUxFTUVOVF9OT0RFICAgICAgICAgICAgICA9IDE7CisgICAgLyoqCisgICAgICogVGhlIG5vZGUgaXMgYW4gPGNvZGU+QXR0cjwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBBVFRSSUJVVEVfTk9ERSAgICAgICAgICAgID0gMjsKKyAgICAvKioKKyAgICAgKiBUaGUgbm9kZSBpcyBhIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBURVhUX05PREUgICAgICAgICAgICAgICAgID0gMzsKKyAgICAvKioKKyAgICAgKiBUaGUgbm9kZSBpcyBhIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDREFUQV9TRUNUSU9OX05PREUgICAgICAgID0gNDsKKyAgICAvKioKKyAgICAgKiBUaGUgbm9kZSBpcyBhbiA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRU5USVRZX1JFRkVSRU5DRV9OT0RFICAgICA9IDU7CisgICAgLyoqCisgICAgICogVGhlIG5vZGUgaXMgYW4gPGNvZGU+RW50aXR5PC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEVOVElUWV9OT0RFICAgICAgICAgICAgICAgPSA2OworICAgIC8qKgorICAgICAqIFRoZSBub2RlIGlzIGEgPGNvZGU+UHJvY2Vzc2luZ0luc3RydWN0aW9uPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSA9IDc7CisgICAgLyoqCisgICAgICogVGhlIG5vZGUgaXMgYSA8Y29kZT5Db21tZW50PC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENPTU1FTlRfTk9ERSAgICAgICAgICAgICAgPSA4OworICAgIC8qKgorICAgICAqIFRoZSBub2RlIGlzIGEgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRE9DVU1FTlRfTk9ERSAgICAgICAgICAgICA9IDk7CisgICAgLyoqCisgICAgICogVGhlIG5vZGUgaXMgYSA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRE9DVU1FTlRfVFlQRV9OT0RFICAgICAgICA9IDEwOworICAgIC8qKgorICAgICAqIFRoZSBub2RlIGlzIGEgPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBET0NVTUVOVF9GUkFHTUVOVF9OT0RFICAgID0gMTE7CisgICAgLyoqCisgICAgICogVGhlIG5vZGUgaXMgYSA8Y29kZT5Ob3RhdGlvbjwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBOT1RBVElPTl9OT0RFICAgICAgICAgICAgID0gMTI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIG5vZGUsIGRlcGVuZGluZyBvbiBpdHMgdHlwZTsgc2VlIHRoZSB0YWJsZSBhYm92ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdmFsdWUgb2YgdGhpcyBub2RlLCBkZXBlbmRpbmcgb24gaXRzIHR5cGU7IHNlZSB0aGUgdGFibGUgYWJvdmUuCisgICAgICogV2hlbiBpdCBpcyBkZWZpbmVkIHRvIGJlIDxjb2RlPm51bGw8L2NvZGU+LCBzZXR0aW5nIGl0IGhhcyBubyBlZmZlY3QsCisgICAgICogaW5jbHVkaW5nIGlmIHRoZSBub2RlIGlzIHJlYWQtb25seS4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgRE9NU1RSSU5HX1NJWkVfRVJSOiBSYWlzZWQgd2hlbiBpdCB3b3VsZCByZXR1cm4gbW9yZSBjaGFyYWN0ZXJzIHRoYW4KKyAgICAgKiAgIGZpdCBpbiBhIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gdmFyaWFibGUgb24gdGhlIGltcGxlbWVudGF0aW9uCisgICAgICogICBwbGF0Zm9ybS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVWYWx1ZSgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworICAgIC8qKgorICAgICAqIFRoZSB2YWx1ZSBvZiB0aGlzIG5vZGUsIGRlcGVuZGluZyBvbiBpdHMgdHlwZTsgc2VlIHRoZSB0YWJsZSBhYm92ZS4KKyAgICAgKiBXaGVuIGl0IGlzIGRlZmluZWQgdG8gYmUgPGNvZGU+bnVsbDwvY29kZT4sIHNldHRpbmcgaXQgaGFzIG5vIGVmZmVjdCwKKyAgICAgKiBpbmNsdWRpbmcgaWYgdGhlIG5vZGUgaXMgcmVhZC1vbmx5LgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCB3aGVuIHRoZSBub2RlIGlzIHJlYWRvbmx5IGFuZCBpZgorICAgICAqICAgaXQgaXMgbm90IGRlZmluZWQgdG8gYmUgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Tm9kZVZhbHVlKFN0cmluZyBub2RlVmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQSBjb2RlIHJlcHJlc2VudGluZyB0aGUgdHlwZSBvZiB0aGUgdW5kZXJseWluZyBvYmplY3QsIGFzIGRlZmluZWQgYWJvdmUuCisgICAgICovCisgICAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcGFyZW50IG9mIHRoaXMgbm9kZS4gQWxsIG5vZGVzLCBleGNlcHQgPGNvZGU+QXR0cjwvY29kZT4sCisgICAgICogPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LCA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiwKKyAgICAgKiA8Y29kZT5FbnRpdHk8L2NvZGU+LCBhbmQgPGNvZGU+Tm90YXRpb248L2NvZGU+IG1heSBoYXZlIGEgcGFyZW50LgorICAgICAqIEhvd2V2ZXIsIGlmIGEgbm9kZSBoYXMganVzdCBiZWVuIGNyZWF0ZWQgYW5kIG5vdCB5ZXQgYWRkZWQgdG8gdGhlCisgICAgICogdHJlZSwgb3IgaWYgaXQgaGFzIGJlZW4gcmVtb3ZlZCBmcm9tIHRoZSB0cmVlLCB0aGlzIGlzCisgICAgICogPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIE5vZGUgZ2V0UGFyZW50Tm9kZSgpOworCisgICAgLyoqCisgICAgICogQSA8Y29kZT5Ob2RlTGlzdDwvY29kZT4gdGhhdCBjb250YWlucyBhbGwgY2hpbGRyZW4gb2YgdGhpcyBub2RlLiBJZgorICAgICAqIHRoZXJlIGFyZSBubyBjaGlsZHJlbiwgdGhpcyBpcyBhIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiBjb250YWluaW5nIG5vCisgICAgICogbm9kZXMuCisgICAgICovCisgICAgcHVibGljIE5vZGVMaXN0IGdldENoaWxkTm9kZXMoKTsKKworICAgIC8qKgorICAgICAqIFRoZSBmaXJzdCBjaGlsZCBvZiB0aGlzIG5vZGUuIElmIHRoZXJlIGlzIG5vIHN1Y2ggbm9kZSwgdGhpcyByZXR1cm5zCisgICAgICogPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIE5vZGUgZ2V0Rmlyc3RDaGlsZCgpOworCisgICAgLyoqCisgICAgICogVGhlIGxhc3QgY2hpbGQgb2YgdGhpcyBub2RlLiBJZiB0aGVyZSBpcyBubyBzdWNoIG5vZGUsIHRoaXMgcmV0dXJucworICAgICAqIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBOb2RlIGdldExhc3RDaGlsZCgpOworCisgICAgLyoqCisgICAgICogVGhlIG5vZGUgaW1tZWRpYXRlbHkgcHJlY2VkaW5nIHRoaXMgbm9kZS4gSWYgdGhlcmUgaXMgbm8gc3VjaCBub2RlLAorICAgICAqIHRoaXMgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9kZSBnZXRQcmV2aW91c1NpYmxpbmcoKTsKKworICAgIC8qKgorICAgICAqIFRoZSBub2RlIGltbWVkaWF0ZWx5IGZvbGxvd2luZyB0aGlzIG5vZGUuIElmIHRoZXJlIGlzIG5vIHN1Y2ggbm9kZSwKKyAgICAgKiB0aGlzIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIE5vZGUgZ2V0TmV4dFNpYmxpbmcoKTsKKworICAgIC8qKgorICAgICAqIEEgPGNvZGU+TmFtZWROb2RlTWFwPC9jb2RlPiBjb250YWluaW5nIHRoZSBhdHRyaWJ1dGVzIG9mIHRoaXMgbm9kZSAoaWYKKyAgICAgKiBpdCBpcyBhbiA8Y29kZT5FbGVtZW50PC9jb2RlPikgb3IgPGNvZGU+bnVsbDwvY29kZT4gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBOYW1lZE5vZGVNYXAgZ2V0QXR0cmlidXRlcygpOworCisgICAgLyoqCisgICAgICogVGhlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoaXMgbm9kZS4gVGhpcyBpcworICAgICAqIGFsc28gdGhlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBvYmplY3QgdXNlZCB0byBjcmVhdGUgbmV3IG5vZGVzLiBXaGVuCisgICAgICogdGhpcyBub2RlIGlzIGEgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG9yIGEgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPgorICAgICAqIHdoaWNoIGlzIG5vdCB1c2VkIHdpdGggYW55IDxjb2RlPkRvY3VtZW50PC9jb2RlPiB5ZXQsIHRoaXMgaXMKKyAgICAgKiA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKiBAdmVyc2lvbiBET00gTGV2ZWwgMgorICAgICAqLworICAgIHB1YmxpYyBEb2N1bWVudCBnZXRPd25lckRvY3VtZW50KCk7CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRzIHRoZSBub2RlIDxjb2RlPm5ld0NoaWxkPC9jb2RlPiBiZWZvcmUgdGhlIGV4aXN0aW5nIGNoaWxkIG5vZGUKKyAgICAgKiA8Y29kZT5yZWZDaGlsZDwvY29kZT4uIElmIDxjb2RlPnJlZkNoaWxkPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwKKyAgICAgKiBpbnNlcnQgPGNvZGU+bmV3Q2hpbGQ8L2NvZGU+IGF0IHRoZSBlbmQgb2YgdGhlIGxpc3Qgb2YgY2hpbGRyZW4uCisgICAgICogPGJyPklmIDxjb2RlPm5ld0NoaWxkPC9jb2RlPiBpcyBhIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IG9iamVjdCwKKyAgICAgKiBhbGwgb2YgaXRzIGNoaWxkcmVuIGFyZSBpbnNlcnRlZCwgaW4gdGhlIHNhbWUgb3JkZXIsIGJlZm9yZQorICAgICAqIDxjb2RlPnJlZkNoaWxkPC9jb2RlPi4gSWYgdGhlIDxjb2RlPm5ld0NoaWxkPC9jb2RlPiBpcyBhbHJlYWR5IGluIHRoZQorICAgICAqIHRyZWUsIGl0IGlzIGZpcnN0IHJlbW92ZWQuCisgICAgICogPHAgPjxiPk5vdGU6PC9iPiAgSW5zZXJ0aW5nIGEgbm9kZSBiZWZvcmUgaXRzZWxmIGlzIGltcGxlbWVudGF0aW9uCisgICAgICogZGVwZW5kZW50LgorICAgICAqIEBwYXJhbSBuZXdDaGlsZCBUaGUgbm9kZSB0byBpbnNlcnQuCisgICAgICogQHBhcmFtIHJlZkNoaWxkIFRoZSByZWZlcmVuY2Ugbm9kZSwgaS5lLiwgdGhlIG5vZGUgYmVmb3JlIHdoaWNoIHRoZQorICAgICAqICAgbmV3IG5vZGUgbXVzdCBiZSBpbnNlcnRlZC4KKyAgICAgKiBAcmV0dXJuIFRoZSBub2RlIGJlaW5nIGluc2VydGVkLgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBISUVSQVJDSFlfUkVRVUVTVF9FUlI6IFJhaXNlZCBpZiB0aGlzIG5vZGUgaXMgb2YgYSB0eXBlIHRoYXQgZG9lcyBub3QKKyAgICAgKiAgIGFsbG93IGNoaWxkcmVuIG9mIHRoZSB0eXBlIG9mIHRoZSA8Y29kZT5uZXdDaGlsZDwvY29kZT4gbm9kZSwgb3IgaWYKKyAgICAgKiAgIHRoZSBub2RlIHRvIGluc2VydCBpcyBvbmUgb2YgdGhpcyBub2RlJ3MgYW5jZXN0b3JzIG9yIHRoaXMgbm9kZQorICAgICAqICAgaXRzZWxmLCBvciBpZiB0aGlzIG5vZGUgaXMgb2YgdHlwZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gYW5kIHRoZQorICAgICAqICAgRE9NIGFwcGxpY2F0aW9uIGF0dGVtcHRzIHRvIGluc2VydCBhIHNlY29uZAorICAgICAqICAgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBvciA8Y29kZT5FbGVtZW50PC9jb2RlPiBub2RlLgorICAgICAqICAgPGJyPldST05HX0RPQ1VNRU5UX0VSUjogUmFpc2VkIGlmIDxjb2RlPm5ld0NoaWxkPC9jb2RlPiB3YXMgY3JlYXRlZAorICAgICAqICAgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudCB0aGFuIHRoZSBvbmUgdGhhdCBjcmVhdGVkIHRoaXMgbm9kZS4KKyAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG5vZGUgaXMgcmVhZG9ubHkgb3IKKyAgICAgKiAgIGlmIHRoZSBwYXJlbnQgb2YgdGhlIG5vZGUgYmVpbmcgaW5zZXJ0ZWQgaXMgcmVhZG9ubHkuCisgICAgICogICA8YnI+Tk9UX0ZPVU5EX0VSUjogUmFpc2VkIGlmIDxjb2RlPnJlZkNoaWxkPC9jb2RlPiBpcyBub3QgYSBjaGlsZCBvZgorICAgICAqICAgdGhpcyBub2RlLgorICAgICAqICAgPGJyPk5PVF9TVVBQT1JURURfRVJSOiBpZiB0aGlzIG5vZGUgaXMgb2YgdHlwZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4sCisgICAgICogICB0aGlzIGV4Y2VwdGlvbiBtaWdodCBiZSByYWlzZWQgaWYgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0CisgICAgICogICBzdXBwb3J0IHRoZSBpbnNlcnRpb24gb2YgYSA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IG9yCisgICAgICogICA8Y29kZT5FbGVtZW50PC9jb2RlPiBub2RlLgorICAgICAqIEB2ZXJzaW9uIERPTSBMZXZlbCAzCisgICAgICovCisgICAgcHVibGljIE5vZGUgaW5zZXJ0QmVmb3JlKE5vZGUgbmV3Q2hpbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgcmVmQ2hpbGQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyB0aGUgY2hpbGQgbm9kZSA8Y29kZT5vbGRDaGlsZDwvY29kZT4gd2l0aCA8Y29kZT5uZXdDaGlsZDwvY29kZT4KKyAgICAgKiAgaW4gdGhlIGxpc3Qgb2YgY2hpbGRyZW4sIGFuZCByZXR1cm5zIHRoZSA8Y29kZT5vbGRDaGlsZDwvY29kZT4gbm9kZS4KKyAgICAgKiA8YnI+SWYgPGNvZGU+bmV3Q2hpbGQ8L2NvZGU+IGlzIGEgPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4gb2JqZWN0LAorICAgICAqIDxjb2RlPm9sZENoaWxkPC9jb2RlPiBpcyByZXBsYWNlZCBieSBhbGwgb2YgdGhlCisgICAgICogPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4gY2hpbGRyZW4sIHdoaWNoIGFyZSBpbnNlcnRlZCBpbiB0aGUKKyAgICAgKiBzYW1lIG9yZGVyLiBJZiB0aGUgPGNvZGU+bmV3Q2hpbGQ8L2NvZGU+IGlzIGFscmVhZHkgaW4gdGhlIHRyZWUsIGl0CisgICAgICogaXMgZmlyc3QgcmVtb3ZlZC4KKyAgICAgKiA8cCA+PGI+Tm90ZTo8L2I+ICBSZXBsYWNpbmcgYSBub2RlIHdpdGggaXRzZWxmIGlzIGltcGxlbWVudGF0aW9uCisgICAgICogZGVwZW5kZW50LgorICAgICAqIEBwYXJhbSBuZXdDaGlsZCBUaGUgbmV3IG5vZGUgdG8gcHV0IGluIHRoZSBjaGlsZCBsaXN0LgorICAgICAqIEBwYXJhbSBvbGRDaGlsZCBUaGUgbm9kZSBiZWluZyByZXBsYWNlZCBpbiB0aGUgbGlzdC4KKyAgICAgKiBAcmV0dXJuIFRoZSBub2RlIHJlcGxhY2VkLgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBISUVSQVJDSFlfUkVRVUVTVF9FUlI6IFJhaXNlZCBpZiB0aGlzIG5vZGUgaXMgb2YgYSB0eXBlIHRoYXQgZG9lcyBub3QKKyAgICAgKiAgIGFsbG93IGNoaWxkcmVuIG9mIHRoZSB0eXBlIG9mIHRoZSA8Y29kZT5uZXdDaGlsZDwvY29kZT4gbm9kZSwgb3IgaWYKKyAgICAgKiAgIHRoZSBub2RlIHRvIHB1dCBpbiBpcyBvbmUgb2YgdGhpcyBub2RlJ3MgYW5jZXN0b3JzIG9yIHRoaXMgbm9kZQorICAgICAqICAgaXRzZWxmLCBvciBpZiB0aGlzIG5vZGUgaXMgb2YgdHlwZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gYW5kIHRoZQorICAgICAqICAgcmVzdWx0IG9mIHRoZSByZXBsYWNlbWVudCBvcGVyYXRpb24gd291bGQgYWRkIGEgc2Vjb25kCisgICAgICogICA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IG9yIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG9uIHRoZQorICAgICAqICAgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG5vZGUuCisgICAgICogICA8YnI+V1JPTkdfRE9DVU1FTlRfRVJSOiBSYWlzZWQgaWYgPGNvZGU+bmV3Q2hpbGQ8L2NvZGU+IHdhcyBjcmVhdGVkCisgICAgICogICBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyBub2RlLgorICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBvciB0aGUgcGFyZW50IG9mCisgICAgICogICB0aGUgbmV3IG5vZGUgaXMgcmVhZG9ubHkuCisgICAgICogICA8YnI+Tk9UX0ZPVU5EX0VSUjogUmFpc2VkIGlmIDxjb2RlPm9sZENoaWxkPC9jb2RlPiBpcyBub3QgYSBjaGlsZCBvZgorICAgICAqICAgdGhpcyBub2RlLgorICAgICAqICAgPGJyPk5PVF9TVVBQT1JURURfRVJSOiBpZiB0aGlzIG5vZGUgaXMgb2YgdHlwZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4sCisgICAgICogICB0aGlzIGV4Y2VwdGlvbiBtaWdodCBiZSByYWlzZWQgaWYgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0CisgICAgICogICBzdXBwb3J0IHRoZSByZXBsYWNlbWVudCBvZiB0aGUgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBjaGlsZCBvcgorICAgICAqICAgPGNvZGU+RWxlbWVudDwvY29kZT4gY2hpbGQuCisgICAgICogQHZlcnNpb24gRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgTm9kZSByZXBsYWNlQ2hpbGQoTm9kZSBuZXdDaGlsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSBvbGRDaGlsZCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIGNoaWxkIG5vZGUgaW5kaWNhdGVkIGJ5IDxjb2RlPm9sZENoaWxkPC9jb2RlPiBmcm9tIHRoZSBsaXN0CisgICAgICogb2YgY2hpbGRyZW4sIGFuZCByZXR1cm5zIGl0LgorICAgICAqIEBwYXJhbSBvbGRDaGlsZCBUaGUgbm9kZSBiZWluZyByZW1vdmVkLgorICAgICAqIEByZXR1cm4gVGhlIG5vZGUgcmVtb3ZlZC4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgorICAgICAqICAgPGJyPk5PVF9GT1VORF9FUlI6IFJhaXNlZCBpZiA8Y29kZT5vbGRDaGlsZDwvY29kZT4gaXMgbm90IGEgY2hpbGQgb2YKKyAgICAgKiAgIHRoaXMgbm9kZS4KKyAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogaWYgdGhpcyBub2RlIGlzIG9mIHR5cGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LAorICAgICAqICAgdGhpcyBleGNlcHRpb24gbWlnaHQgYmUgcmFpc2VkIGlmIHRoZSBET00gaW1wbGVtZW50YXRpb24gZG9lc24ndAorICAgICAqICAgc3VwcG9ydCB0aGUgcmVtb3ZhbCBvZiB0aGUgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBjaGlsZCBvciB0aGUKKyAgICAgKiAgIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IGNoaWxkLgorICAgICAqIEB2ZXJzaW9uIERPTSBMZXZlbCAzCisgICAgICovCisgICAgcHVibGljIE5vZGUgcmVtb3ZlQ2hpbGQoTm9kZSBvbGRDaGlsZCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQWRkcyB0aGUgbm9kZSA8Y29kZT5uZXdDaGlsZDwvY29kZT4gdG8gdGhlIGVuZCBvZiB0aGUgbGlzdCBvZiBjaGlsZHJlbgorICAgICAqIG9mIHRoaXMgbm9kZS4gSWYgdGhlIDxjb2RlPm5ld0NoaWxkPC9jb2RlPiBpcyBhbHJlYWR5IGluIHRoZSB0cmVlLCBpdAorICAgICAqIGlzIGZpcnN0IHJlbW92ZWQuCisgICAgICogQHBhcmFtIG5ld0NoaWxkIFRoZSBub2RlIHRvIGFkZC5JZiBpdCBpcyBhCisgICAgICogICA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBvYmplY3QsIHRoZSBlbnRpcmUgY29udGVudHMgb2YgdGhlCisgICAgICogICBkb2N1bWVudCBmcmFnbWVudCBhcmUgbW92ZWQgaW50byB0aGUgY2hpbGQgbGlzdCBvZiB0aGlzIG5vZGUKKyAgICAgKiBAcmV0dXJuIFRoZSBub2RlIGFkZGVkLgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBISUVSQVJDSFlfUkVRVUVTVF9FUlI6IFJhaXNlZCBpZiB0aGlzIG5vZGUgaXMgb2YgYSB0eXBlIHRoYXQgZG9lcyBub3QKKyAgICAgKiAgIGFsbG93IGNoaWxkcmVuIG9mIHRoZSB0eXBlIG9mIHRoZSA8Y29kZT5uZXdDaGlsZDwvY29kZT4gbm9kZSwgb3IgaWYKKyAgICAgKiAgIHRoZSBub2RlIHRvIGFwcGVuZCBpcyBvbmUgb2YgdGhpcyBub2RlJ3MgYW5jZXN0b3JzIG9yIHRoaXMgbm9kZQorICAgICAqICAgaXRzZWxmLCBvciBpZiB0aGlzIG5vZGUgaXMgb2YgdHlwZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gYW5kIHRoZQorICAgICAqICAgRE9NIGFwcGxpY2F0aW9uIGF0dGVtcHRzIHRvIGFwcGVuZCBhIHNlY29uZAorICAgICAqICAgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBvciA8Y29kZT5FbGVtZW50PC9jb2RlPiBub2RlLgorICAgICAqICAgPGJyPldST05HX0RPQ1VNRU5UX0VSUjogUmFpc2VkIGlmIDxjb2RlPm5ld0NoaWxkPC9jb2RlPiB3YXMgY3JlYXRlZAorICAgICAqICAgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudCB0aGFuIHRoZSBvbmUgdGhhdCBjcmVhdGVkIHRoaXMgbm9kZS4KKyAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG5vZGUgaXMgcmVhZG9ubHkgb3IKKyAgICAgKiAgIGlmIHRoZSBwcmV2aW91cyBwYXJlbnQgb2YgdGhlIG5vZGUgYmVpbmcgaW5zZXJ0ZWQgaXMgcmVhZG9ubHkuCisgICAgICogICA8YnI+Tk9UX1NVUFBPUlRFRF9FUlI6IGlmIHRoZSA8Y29kZT5uZXdDaGlsZDwvY29kZT4gbm9kZSBpcyBhIGNoaWxkCisgICAgICogICBvZiB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG5vZGUsIHRoaXMgZXhjZXB0aW9uIG1pZ2h0IGJlIHJhaXNlZAorICAgICAqICAgaWYgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHN1cHBvcnQgdGhlIHJlbW92YWwgb2YgdGhlCisgICAgICogICA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IGNoaWxkIG9yIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IGNoaWxkLgorICAgICAqIEB2ZXJzaW9uIERPTSBMZXZlbCAzCisgICAgICovCisgICAgcHVibGljIE5vZGUgYXBwZW5kQ2hpbGQoTm9kZSBuZXdDaGlsZCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgbm9kZSBoYXMgYW55IGNoaWxkcmVuLgorICAgICAqIEByZXR1cm4gUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGlzIG5vZGUgaGFzIGFueSBjaGlsZHJlbiwKKyAgICAgKiAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzQ2hpbGROb2RlcygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGR1cGxpY2F0ZSBvZiB0aGlzIG5vZGUsIGkuZS4sIHNlcnZlcyBhcyBhIGdlbmVyaWMgY29weQorICAgICAqIGNvbnN0cnVjdG9yIGZvciBub2Rlcy4gVGhlIGR1cGxpY2F0ZSBub2RlIGhhcyBubyBwYXJlbnQgKAorICAgICAqIDxjb2RlPnBhcmVudE5vZGU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+KSBhbmQgbm8gdXNlciBkYXRhLiBVc2VyCisgICAgICogZGF0YSBhc3NvY2lhdGVkIHRvIHRoZSBpbXBvcnRlZCBub2RlIGlzIG5vdCBjYXJyaWVkIG92ZXIuIEhvd2V2ZXIsIGlmCisgICAgICogYW55IDxjb2RlPlVzZXJEYXRhSGFuZGxlcnM8L2NvZGU+IGhhcyBiZWVuIHNwZWNpZmllZCBhbG9uZyB3aXRoIHRoZQorICAgICAqIGFzc29jaWF0ZWQgZGF0YSB0aGVzZSBoYW5kbGVycyB3aWxsIGJlIGNhbGxlZCB3aXRoIHRoZSBhcHByb3ByaWF0ZQorICAgICAqIHBhcmFtZXRlcnMgYmVmb3JlIHRoaXMgbWV0aG9kIHJldHVybnMuCisgICAgICogPGJyPkNsb25pbmcgYW4gPGNvZGU+RWxlbWVudDwvY29kZT4gY29waWVzIGFsbCBhdHRyaWJ1dGVzIGFuZCB0aGVpcgorICAgICAqIHZhbHVlcywgaW5jbHVkaW5nIHRob3NlIGdlbmVyYXRlZCBieSB0aGUgWE1MIHByb2Nlc3NvciB0byByZXByZXNlbnQKKyAgICAgKiBkZWZhdWx0ZWQgYXR0cmlidXRlcywgYnV0IHRoaXMgbWV0aG9kIGRvZXMgbm90IGNvcHkgYW55IGNoaWxkcmVuIGl0CisgICAgICogY29udGFpbnMgdW5sZXNzIGl0IGlzIGEgZGVlcCBjbG9uZS4gVGhpcyBpbmNsdWRlcyB0ZXh0IGNvbnRhaW5lZCBpbgorICAgICAqIGFuIHRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiBzaW5jZSB0aGUgdGV4dCBpcyBjb250YWluZWQgaW4gYSBjaGlsZAorICAgICAqIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUuIENsb25pbmcgYW4gPGNvZGU+QXR0cjwvY29kZT4gZGlyZWN0bHksIGFzCisgICAgICogb3Bwb3NlZCB0byBiZSBjbG9uZWQgYXMgcGFydCBvZiBhbiA8Y29kZT5FbGVtZW50PC9jb2RlPiBjbG9uaW5nCisgICAgICogb3BlcmF0aW9uLCByZXR1cm5zIGEgc3BlY2lmaWVkIGF0dHJpYnV0ZSAoPGNvZGU+c3BlY2lmaWVkPC9jb2RlPiBpcworICAgICAqIDxjb2RlPnRydWU8L2NvZGU+KS4gQ2xvbmluZyBhbiA8Y29kZT5BdHRyPC9jb2RlPiBhbHdheXMgY2xvbmVzIGl0cworICAgICAqIGNoaWxkcmVuLCBzaW5jZSB0aGV5IHJlcHJlc2VudCBpdHMgdmFsdWUsIG5vIG1hdHRlciB3aGV0aGVyIHRoaXMgaXMgYQorICAgICAqIGRlZXAgY2xvbmUgb3Igbm90LiBDbG9uaW5nIGFuIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4KKyAgICAgKiBhdXRvbWF0aWNhbGx5IGNvbnN0cnVjdHMgaXRzIHN1YnRyZWUgaWYgYSBjb3JyZXNwb25kaW5nCisgICAgICogPGNvZGU+RW50aXR5PC9jb2RlPiBpcyBhdmFpbGFibGUsIG5vIG1hdHRlciB3aGV0aGVyIHRoaXMgaXMgYSBkZWVwCisgICAgICogY2xvbmUgb3Igbm90LiBDbG9uaW5nIGFueSBvdGhlciB0eXBlIG9mIG5vZGUgc2ltcGx5IHJldHVybnMgYSBjb3B5IG9mCisgICAgICogdGhpcyBub2RlLgorICAgICAqIDxicj5Ob3RlIHRoYXQgY2xvbmluZyBhbiBpbW11dGFibGUgc3VidHJlZSByZXN1bHRzIGluIGEgbXV0YWJsZSBjb3B5LAorICAgICAqIGJ1dCB0aGUgY2hpbGRyZW4gb2YgYW4gPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBjbG9uZSBhcmUgcmVhZG9ubHkKKyAgICAgKiAuIEluIGFkZGl0aW9uLCBjbG9uZXMgb2YgdW5zcGVjaWZpZWQgPGNvZGU+QXR0cjwvY29kZT4gbm9kZXMgYXJlCisgICAgICogc3BlY2lmaWVkLiBBbmQsIGNsb25pbmcgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LAorICAgICAqIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4sIDxjb2RlPkVudGl0eTwvY29kZT4sIGFuZAorICAgICAqIDxjb2RlPk5vdGF0aW9uPC9jb2RlPiBub2RlcyBpcyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuCisgICAgICogQHBhcmFtIGRlZXAgSWYgPGNvZGU+dHJ1ZTwvY29kZT4sIHJlY3Vyc2l2ZWx5IGNsb25lIHRoZSBzdWJ0cmVlIHVuZGVyCisgICAgICogICB0aGUgc3BlY2lmaWVkIG5vZGU7IGlmIDxjb2RlPmZhbHNlPC9jb2RlPiwgY2xvbmUgb25seSB0aGUgbm9kZQorICAgICAqICAgaXRzZWxmIChhbmQgaXRzIGF0dHJpYnV0ZXMsIGlmIGl0IGlzIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+KS4KKyAgICAgKiBAcmV0dXJuIFRoZSBkdXBsaWNhdGUgbm9kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9kZSBjbG9uZU5vZGUoYm9vbGVhbiBkZWVwKTsKKworICAgIC8qKgorICAgICAqICBQdXRzIGFsbCA8Y29kZT5UZXh0PC9jb2RlPiBub2RlcyBpbiB0aGUgZnVsbCBkZXB0aCBvZiB0aGUgc3ViLXRyZWUKKyAgICAgKiB1bmRlcm5lYXRoIHRoaXMgPGNvZGU+Tm9kZTwvY29kZT4sIGluY2x1ZGluZyBhdHRyaWJ1dGUgbm9kZXMsIGludG8gYQorICAgICAqICJub3JtYWwiIGZvcm0gd2hlcmUgb25seSBzdHJ1Y3R1cmUgKGUuZy4sIGVsZW1lbnRzLCBjb21tZW50cywKKyAgICAgKiBwcm9jZXNzaW5nIGluc3RydWN0aW9ucywgQ0RBVEEgc2VjdGlvbnMsIGFuZCBlbnRpdHkgcmVmZXJlbmNlcykKKyAgICAgKiBzZXBhcmF0ZXMgPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMsIGkuZS4sIHRoZXJlIGFyZSBuZWl0aGVyIGFkamFjZW50CisgICAgICogPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMgbm9yIGVtcHR5IDxjb2RlPlRleHQ8L2NvZGU+IG5vZGVzLiBUaGlzIGNhbgorICAgICAqIGJlIHVzZWQgdG8gZW5zdXJlIHRoYXQgdGhlIERPTSB2aWV3IG9mIGEgZG9jdW1lbnQgaXMgdGhlIHNhbWUgYXMgaWYKKyAgICAgKiBpdCB3ZXJlIHNhdmVkIGFuZCByZS1sb2FkZWQsIGFuZCBpcyB1c2VmdWwgd2hlbiBvcGVyYXRpb25zIChzdWNoIGFzCisgICAgICogWFBvaW50ZXIgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvUkVDLXhwdHItZnJhbWV3b3JrLTIwMDMwMzI1Lyc+WFBvaW50ZXI8L2E+XQorICAgICAqICBsb29rdXBzKSB0aGF0IGRlcGVuZCBvbiBhIHBhcnRpY3VsYXIgZG9jdW1lbnQgdHJlZSBzdHJ1Y3R1cmUgYXJlIHRvCisgICAgICogYmUgdXNlZC4gSWYgdGhlIHBhcmFtZXRlciAibm9ybWFsaXplLWNoYXJhY3RlcnMiIG9mIHRoZQorICAgICAqIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IG9iamVjdCBhdHRhY2hlZCB0byB0aGUKKyAgICAgKiA8Y29kZT5Ob2RlLm93bmVyRG9jdW1lbnQ8L2NvZGU+IGlzIDxjb2RlPnRydWU8L2NvZGU+LCB0aGlzIG1ldGhvZAorICAgICAqIHdpbGwgYWxzbyBmdWxseSBub3JtYWxpemUgdGhlIGNoYXJhY3RlcnMgb2YgdGhlIDxjb2RlPlRleHQ8L2NvZGU+CisgICAgICogbm9kZXMuCisgICAgICogPHAgPjxiPk5vdGU6PC9iPiBJbiBjYXNlcyB3aGVyZSB0aGUgZG9jdW1lbnQgY29udGFpbnMKKyAgICAgKiA8Y29kZT5DREFUQVNlY3Rpb25zPC9jb2RlPiwgdGhlIG5vcm1hbGl6ZSBvcGVyYXRpb24gYWxvbmUgbWF5IG5vdCBiZQorICAgICAqIHN1ZmZpY2llbnQsIHNpbmNlIFhQb2ludGVycyBkbyBub3QgZGlmZmVyZW50aWF0ZSBiZXR3ZWVuCisgICAgICogPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMgYW5kIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gbm9kZXMuCisgICAgICogQHZlcnNpb24gRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBub3JtYWxpemUoKTsKKworICAgIC8qKgorICAgICAqICBUZXN0cyB3aGV0aGVyIHRoZSBET00gaW1wbGVtZW50YXRpb24gaW1wbGVtZW50cyBhIHNwZWNpZmljIGZlYXR1cmUgYW5kCisgICAgICogdGhhdCBmZWF0dXJlIGlzIHN1cHBvcnRlZCBieSB0aGlzIG5vZGUsIGFzIHNwZWNpZmllZCBpbiAuCisgICAgICogQHBhcmFtIGZlYXR1cmUgIFRoZSBuYW1lIG9mIHRoZSBmZWF0dXJlIHRvIHRlc3QuCisgICAgICogQHBhcmFtIHZlcnNpb24gIFRoaXMgaXMgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBmZWF0dXJlIHRvIHRlc3QuCisgICAgICogQHJldHVybiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBzcGVjaWZpZWQgZmVhdHVyZSBpcworICAgICAqICAgc3VwcG9ydGVkIG9uIHRoaXMgbm9kZSwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1N1cHBvcnRlZChTdHJpbmcgZmVhdHVyZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmVyc2lvbik7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGlzIG5vZGUsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIGl0IGlzCisgICAgICogdW5zcGVjaWZpZWQgKHNlZSApLgorICAgICAqIDxicj5UaGlzIGlzIG5vdCBhIGNvbXB1dGVkIHZhbHVlIHRoYXQgaXMgdGhlIHJlc3VsdCBvZiBhIG5hbWVzcGFjZQorICAgICAqIGxvb2t1cCBiYXNlZCBvbiBhbiBleGFtaW5hdGlvbiBvZiB0aGUgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBpbgorICAgICAqIHNjb3BlLiBJdCBpcyBtZXJlbHkgdGhlIG5hbWVzcGFjZSBVUkkgZ2l2ZW4gYXQgY3JlYXRpb24gdGltZS4KKyAgICAgKiA8YnI+Rm9yIG5vZGVzIG9mIGFueSB0eXBlIG90aGVyIHRoYW4gPGNvZGU+RUxFTUVOVF9OT0RFPC9jb2RlPiBhbmQKKyAgICAgKiA8Y29kZT5BVFRSSUJVVEVfTk9ERTwvY29kZT4gYW5kIG5vZGVzIGNyZWF0ZWQgd2l0aCBhIERPTSBMZXZlbCAxCisgICAgICogbWV0aG9kLCBzdWNoIGFzIDxjb2RlPkRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoKTwvY29kZT4sIHRoaXMgaXMgYWx3YXlzCisgICAgICogPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICogPHAgPjxiPk5vdGU6PC9iPiBQZXIgdGhlIDxlbT5OYW1lc3BhY2VzIGluIFhNTDwvZW0+IFNwZWNpZmljYXRpb24gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNC8nPlhNTCBOYW1lc3BhY2VzPC9hPl0KKyAgICAgKiAgYW4gYXR0cmlidXRlIGRvZXMgbm90IGluaGVyaXQgaXRzIG5hbWVzcGFjZSBmcm9tIHRoZSBlbGVtZW50IGl0IGlzCisgICAgICogYXR0YWNoZWQgdG8uIElmIGFuIGF0dHJpYnV0ZSBpcyBub3QgZXhwbGljaXRseSBnaXZlbiBhIG5hbWVzcGFjZSwgaXQKKyAgICAgKiBzaW1wbHkgaGFzIG5vIG5hbWVzcGFjZS4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSSgpOworCisgICAgLyoqCisgICAgICogVGhlIG5hbWVzcGFjZSBwcmVmaXggb2YgdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBpdCBpcworICAgICAqIHVuc3BlY2lmaWVkLiBXaGVuIGl0IGlzIGRlZmluZWQgdG8gYmUgPGNvZGU+bnVsbDwvY29kZT4sIHNldHRpbmcgaXQKKyAgICAgKiBoYXMgbm8gZWZmZWN0LCBpbmNsdWRpbmcgaWYgdGhlIG5vZGUgaXMgcmVhZC1vbmx5LgorICAgICAqIDxicj5Ob3RlIHRoYXQgc2V0dGluZyB0aGlzIGF0dHJpYnV0ZSwgd2hlbiBwZXJtaXR0ZWQsIGNoYW5nZXMgdGhlCisgICAgICogPGNvZGU+bm9kZU5hbWU8L2NvZGU+IGF0dHJpYnV0ZSwgd2hpY2ggaG9sZHMgdGhlIHF1YWxpZmllZCBuYW1lLCBhcworICAgICAqIHdlbGwgYXMgdGhlIDxjb2RlPnRhZ05hbWU8L2NvZGU+IGFuZCA8Y29kZT5uYW1lPC9jb2RlPiBhdHRyaWJ1dGVzIG9mCisgICAgICogdGhlIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IGFuZCA8Y29kZT5BdHRyPC9jb2RlPiBpbnRlcmZhY2VzLCB3aGVuCisgICAgICogYXBwbGljYWJsZS4KKyAgICAgKiA8YnI+U2V0dGluZyB0aGUgcHJlZml4IHRvIDxjb2RlPm51bGw8L2NvZGU+IG1ha2VzIGl0IHVuc3BlY2lmaWVkLAorICAgICAqIHNldHRpbmcgaXQgdG8gYW4gZW1wdHkgc3RyaW5nIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KKyAgICAgKiA8YnI+Tm90ZSBhbHNvIHRoYXQgY2hhbmdpbmcgdGhlIHByZWZpeCBvZiBhbiBhdHRyaWJ1dGUgdGhhdCBpcyBrbm93biB0bworICAgICAqIGhhdmUgYSBkZWZhdWx0IHZhbHVlLCBkb2VzIG5vdCBtYWtlIGEgbmV3IGF0dHJpYnV0ZSB3aXRoIHRoZSBkZWZhdWx0CisgICAgICogdmFsdWUgYW5kIHRoZSBvcmlnaW5hbCBwcmVmaXggYXBwZWFyLCBzaW5jZSB0aGUKKyAgICAgKiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGFuZCA8Y29kZT5sb2NhbE5hbWU8L2NvZGU+IGRvIG5vdCBjaGFuZ2UuCisgICAgICogPGJyPkZvciBub2RlcyBvZiBhbnkgdHlwZSBvdGhlciB0aGFuIDxjb2RlPkVMRU1FTlRfTk9ERTwvY29kZT4gYW5kCisgICAgICogPGNvZGU+QVRUUklCVVRFX05PREU8L2NvZGU+IGFuZCBub2RlcyBjcmVhdGVkIHdpdGggYSBET00gTGV2ZWwgMQorICAgICAqIG1ldGhvZCwgc3VjaCBhcyA8Y29kZT5jcmVhdGVFbGVtZW50PC9jb2RlPiBmcm9tIHRoZQorICAgICAqIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBpbnRlcmZhY2UsIHRoaXMgaXMgYWx3YXlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KCk7CisgICAgLyoqCisgICAgICogVGhlIG5hbWVzcGFjZSBwcmVmaXggb2YgdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBpdCBpcworICAgICAqIHVuc3BlY2lmaWVkLiBXaGVuIGl0IGlzIGRlZmluZWQgdG8gYmUgPGNvZGU+bnVsbDwvY29kZT4sIHNldHRpbmcgaXQKKyAgICAgKiBoYXMgbm8gZWZmZWN0LCBpbmNsdWRpbmcgaWYgdGhlIG5vZGUgaXMgcmVhZC1vbmx5LgorICAgICAqIDxicj5Ob3RlIHRoYXQgc2V0dGluZyB0aGlzIGF0dHJpYnV0ZSwgd2hlbiBwZXJtaXR0ZWQsIGNoYW5nZXMgdGhlCisgICAgICogPGNvZGU+bm9kZU5hbWU8L2NvZGU+IGF0dHJpYnV0ZSwgd2hpY2ggaG9sZHMgdGhlIHF1YWxpZmllZCBuYW1lLCBhcworICAgICAqIHdlbGwgYXMgdGhlIDxjb2RlPnRhZ05hbWU8L2NvZGU+IGFuZCA8Y29kZT5uYW1lPC9jb2RlPiBhdHRyaWJ1dGVzIG9mCisgICAgICogdGhlIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IGFuZCA8Y29kZT5BdHRyPC9jb2RlPiBpbnRlcmZhY2VzLCB3aGVuCisgICAgICogYXBwbGljYWJsZS4KKyAgICAgKiA8YnI+U2V0dGluZyB0aGUgcHJlZml4IHRvIDxjb2RlPm51bGw8L2NvZGU+IG1ha2VzIGl0IHVuc3BlY2lmaWVkLAorICAgICAqIHNldHRpbmcgaXQgdG8gYW4gZW1wdHkgc3RyaW5nIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KKyAgICAgKiA8YnI+Tm90ZSBhbHNvIHRoYXQgY2hhbmdpbmcgdGhlIHByZWZpeCBvZiBhbiBhdHRyaWJ1dGUgdGhhdCBpcyBrbm93biB0bworICAgICAqIGhhdmUgYSBkZWZhdWx0IHZhbHVlLCBkb2VzIG5vdCBtYWtlIGEgbmV3IGF0dHJpYnV0ZSB3aXRoIHRoZSBkZWZhdWx0CisgICAgICogdmFsdWUgYW5kIHRoZSBvcmlnaW5hbCBwcmVmaXggYXBwZWFyLCBzaW5jZSB0aGUKKyAgICAgKiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGFuZCA8Y29kZT5sb2NhbE5hbWU8L2NvZGU+IGRvIG5vdCBjaGFuZ2UuCisgICAgICogPGJyPkZvciBub2RlcyBvZiBhbnkgdHlwZSBvdGhlciB0aGFuIDxjb2RlPkVMRU1FTlRfTk9ERTwvY29kZT4gYW5kCisgICAgICogPGNvZGU+QVRUUklCVVRFX05PREU8L2NvZGU+IGFuZCBub2RlcyBjcmVhdGVkIHdpdGggYSBET00gTGV2ZWwgMQorICAgICAqIG1ldGhvZCwgc3VjaCBhcyA8Y29kZT5jcmVhdGVFbGVtZW50PC9jb2RlPiBmcm9tIHRoZQorICAgICAqIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBpbnRlcmZhY2UsIHRoaXMgaXMgYWx3YXlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBJTlZBTElEX0NIQVJBQ1RFUl9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIHByZWZpeCBjb250YWlucyBhbgorICAgICAqICAgaWxsZWdhbCBjaGFyYWN0ZXIgYWNjb3JkaW5nIHRvIHRoZSBYTUwgdmVyc2lvbiBpbiB1c2Ugc3BlY2lmaWVkIGluCisgICAgICogICB0aGUgPGNvZGU+RG9jdW1lbnQueG1sVmVyc2lvbjwvY29kZT4gYXR0cmlidXRlLgorICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seS4KKyAgICAgKiAgIDxicj5OQU1FU1BBQ0VfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCA8Y29kZT5wcmVmaXg8L2NvZGU+IGlzCisgICAgICogICBtYWxmb3JtZWQgcGVyIHRoZSBOYW1lc3BhY2VzIGluIFhNTCBzcGVjaWZpY2F0aW9uLCBpZiB0aGUKKyAgICAgKiAgIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gb2YgdGhpcyBub2RlIGlzIDxjb2RlPm51bGw8L2NvZGU+LCBpZiB0aGUKKyAgICAgKiAgIHNwZWNpZmllZCBwcmVmaXggaXMgInhtbCIgYW5kIHRoZSA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IG9mIHRoaXMKKyAgICAgKiAgIG5vZGUgaXMgZGlmZmVyZW50IGZyb20gIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSc+CisgICAgICogICBodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2U8L2E+IiwgaWYgdGhpcyBub2RlIGlzIGFuIGF0dHJpYnV0ZSBhbmQgdGhlIHNwZWNpZmllZCBwcmVmaXggaXMgInhtbG5zIiBhbmQKKyAgICAgKiAgIHRoZSA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IG9mIHRoaXMgbm9kZSBpcyBkaWZmZXJlbnQgZnJvbSAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8nPmh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvPC9hPiIsIG9yIGlmIHRoaXMgbm9kZSBpcyBhbiBhdHRyaWJ1dGUgYW5kIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBvZgorICAgICAqICAgdGhpcyBub2RlIGlzICJ4bWxucyIgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNC8nPlhNTCBOYW1lc3BhY2VzPC9hPl0KKyAgICAgKiAgIC4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQcmVmaXgoU3RyaW5nIHByZWZpeCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbG9jYWwgcGFydCBvZiB0aGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhpcyBub2RlLgorICAgICAqIDxicj5Gb3Igbm9kZXMgb2YgYW55IHR5cGUgb3RoZXIgdGhhbiA8Y29kZT5FTEVNRU5UX05PREU8L2NvZGU+IGFuZAorICAgICAqIDxjb2RlPkFUVFJJQlVURV9OT0RFPC9jb2RlPiBhbmQgbm9kZXMgY3JlYXRlZCB3aXRoIGEgRE9NIExldmVsIDEKKyAgICAgKiBtZXRob2QsIHN1Y2ggYXMgPGNvZGU+RG9jdW1lbnQuY3JlYXRlRWxlbWVudCgpPC9jb2RlPiwgdGhpcyBpcyBhbHdheXMKKyAgICAgKiA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgbm9kZSAoaWYgaXQgaXMgYW4gZWxlbWVudCkgaGFzIGFueSBhdHRyaWJ1dGVzLgorICAgICAqIEByZXR1cm4gUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGlzIG5vZGUgaGFzIGFueSBhdHRyaWJ1dGVzLAorICAgICAqICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNBdHRyaWJ1dGVzKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWJzb2x1dGUgYmFzZSBVUkkgb2YgdGhpcyBub2RlIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZQorICAgICAqIGltcGxlbWVudGF0aW9uIHdhc24ndCBhYmxlIHRvIG9idGFpbiBhbiBhYnNvbHV0ZSBVUkkuIFRoaXMgdmFsdWUgaXMKKyAgICAgKiBjb21wdXRlZCBhcyBkZXNjcmliZWQgaW4gLiBIb3dldmVyLCB3aGVuIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4KKyAgICAgKiBzdXBwb3J0cyB0aGUgZmVhdHVyZSAiSFRNTCIgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvUkVDLURPTS1MZXZlbC0yLUhUTUwtMjAwMzAxMDknPkRPTSBMZXZlbCAyIEhUTUw8L2E+XQorICAgICAqICwgdGhlIGJhc2UgVVJJIGlzIGNvbXB1dGVkIHVzaW5nIGZpcnN0IHRoZSB2YWx1ZSBvZiB0aGUgaHJlZgorICAgICAqIGF0dHJpYnV0ZSBvZiB0aGUgSFRNTCBCQVNFIGVsZW1lbnQgaWYgYW55LCBhbmQgdGhlIHZhbHVlIG9mIHRoZQorICAgICAqIDxjb2RlPmRvY3VtZW50VVJJPC9jb2RlPiBhdHRyaWJ1dGUgZnJvbSB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+CisgICAgICogaW50ZXJmYWNlIG90aGVyd2lzZS4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VVUkkoKTsKKworICAgIC8vIERvY3VtZW50UG9zaXRpb24KKyAgICAvKioKKyAgICAgKiBUaGUgdHdvIG5vZGVzIGFyZSBkaXNjb25uZWN0ZWQuIE9yZGVyIGJldHdlZW4gZGlzY29ubmVjdGVkIG5vZGVzIGlzCisgICAgICogYWx3YXlzIGltcGxlbWVudGF0aW9uLXNwZWNpZmljLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRE9DVU1FTlRfUE9TSVRJT05fRElTQ09OTkVDVEVEID0gMHgwMTsKKyAgICAvKioKKyAgICAgKiBUaGUgc2Vjb25kIG5vZGUgcHJlY2VkZXMgdGhlIHJlZmVyZW5jZSBub2RlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRE9DVU1FTlRfUE9TSVRJT05fUFJFQ0VESU5HID0gMHgwMjsKKyAgICAvKioKKyAgICAgKiBUaGUgbm9kZSBmb2xsb3dzIHRoZSByZWZlcmVuY2Ugbm9kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERPQ1VNRU5UX1BPU0lUSU9OX0ZPTExPV0lORyA9IDB4MDQ7CisgICAgLyoqCisgICAgICogVGhlIG5vZGUgY29udGFpbnMgdGhlIHJlZmVyZW5jZSBub2RlLiBBIG5vZGUgd2hpY2ggY29udGFpbnMgaXMgYWx3YXlzCisgICAgICogcHJlY2VkaW5nLCB0b28uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBET0NVTUVOVF9QT1NJVElPTl9DT05UQUlOUyA9IDB4MDg7CisgICAgLyoqCisgICAgICogVGhlIG5vZGUgaXMgY29udGFpbmVkIGJ5IHRoZSByZWZlcmVuY2Ugbm9kZS4gQSBub2RlIHdoaWNoIGlzIGNvbnRhaW5lZAorICAgICAqIGlzIGFsd2F5cyBmb2xsb3dpbmcsIHRvby4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERPQ1VNRU5UX1BPU0lUSU9OX0NPTlRBSU5FRF9CWSA9IDB4MTA7CisgICAgLyoqCisgICAgICogVGhlIGRldGVybWluYXRpb24gb2YgcHJlY2VkaW5nIHZlcnN1cyBmb2xsb3dpbmcgaXMKKyAgICAgKiBpbXBsZW1lbnRhdGlvbi1zcGVjaWZpYy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERPQ1VNRU5UX1BPU0lUSU9OX0lNUExFTUVOVEFUSU9OX1NQRUNJRklDID0gMHgyMDsKKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSByZWZlcmVuY2Ugbm9kZSwgaS5lLiB0aGUgbm9kZSBvbiB3aGljaCB0aGlzIG1ldGhvZCBpcworICAgICAqIGJlaW5nIGNhbGxlZCwgd2l0aCBhIG5vZGUsIGkuZS4gdGhlIG9uZSBwYXNzZWQgYXMgYSBwYXJhbWV0ZXIsIHdpdGgKKyAgICAgKiByZWdhcmQgdG8gdGhlaXIgcG9zaXRpb24gaW4gdGhlIGRvY3VtZW50IGFuZCBhY2NvcmRpbmcgdG8gdGhlCisgICAgICogZG9jdW1lbnQgb3JkZXIuCisgICAgICogQHBhcmFtIG90aGVyIFRoZSBub2RlIHRvIGNvbXBhcmUgYWdhaW5zdCB0aGUgcmVmZXJlbmNlIG5vZGUuCisgICAgICogQHJldHVybiBSZXR1cm5zIGhvdyB0aGUgbm9kZSBpcyBwb3NpdGlvbmVkIHJlbGF0aXZlbHkgdG8gdGhlIHJlZmVyZW5jZQorICAgICAqICAgbm9kZS4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IHdoZW4gdGhlIGNvbXBhcmVkIG5vZGVzIGFyZSBmcm9tIGRpZmZlcmVudCBET00KKyAgICAgKiAgIGltcGxlbWVudGF0aW9ucyB0aGF0IGRvIG5vdCBjb29yZGluYXRlIHRvIHJldHVybiBjb25zaXN0ZW50CisgICAgICogICBpbXBsZW1lbnRhdGlvbi1zcGVjaWZpYyByZXN1bHRzLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyBzaG9ydCBjb21wYXJlRG9jdW1lbnRQb3NpdGlvbihOb2RlIG90aGVyKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVGhpcyBhdHRyaWJ1dGUgcmV0dXJucyB0aGUgdGV4dCBjb250ZW50IG9mIHRoaXMgbm9kZSBhbmQgaXRzCisgICAgICogZGVzY2VuZGFudHMuIFdoZW4gaXQgaXMgZGVmaW5lZCB0byBiZSA8Y29kZT5udWxsPC9jb2RlPiwgc2V0dGluZyBpdAorICAgICAqIGhhcyBubyBlZmZlY3QuIE9uIHNldHRpbmcsIGFueSBwb3NzaWJsZSBjaGlsZHJlbiB0aGlzIG5vZGUgbWF5IGhhdmUKKyAgICAgKiBhcmUgcmVtb3ZlZCBhbmQsIGlmIGl0IHRoZSBuZXcgc3RyaW5nIGlzIG5vdCBlbXB0eSBvcgorICAgICAqIDxjb2RlPm51bGw8L2NvZGU+LCByZXBsYWNlZCBieSBhIHNpbmdsZSA8Y29kZT5UZXh0PC9jb2RlPiBub2RlCisgICAgICogY29udGFpbmluZyB0aGUgc3RyaW5nIHRoaXMgYXR0cmlidXRlIGlzIHNldCB0by4KKyAgICAgKiA8YnI+IE9uIGdldHRpbmcsIG5vIHNlcmlhbGl6YXRpb24gaXMgcGVyZm9ybWVkLCB0aGUgcmV0dXJuZWQgc3RyaW5nCisgICAgICogZG9lcyBub3QgY29udGFpbiBhbnkgbWFya3VwLiBObyB3aGl0ZXNwYWNlIG5vcm1hbGl6YXRpb24gaXMgcGVyZm9ybWVkCisgICAgICogYW5kIHRoZSByZXR1cm5lZCBzdHJpbmcgZG9lcyBub3QgY29udGFpbiB0aGUgd2hpdGUgc3BhY2VzIGluIGVsZW1lbnQKKyAgICAgKiBjb250ZW50IChzZWUgdGhlIGF0dHJpYnV0ZQorICAgICAqIDxjb2RlPlRleHQuaXNFbGVtZW50Q29udGVudFdoaXRlc3BhY2U8L2NvZGU+KS4gU2ltaWxhcmx5LCBvbiBzZXR0aW5nLAorICAgICAqIG5vIHBhcnNpbmcgaXMgcGVyZm9ybWVkIGVpdGhlciwgdGhlIGlucHV0IHN0cmluZyBpcyB0YWtlbiBhcyBwdXJlCisgICAgICogdGV4dHVhbCBjb250ZW50LgorICAgICAqIDxicj5UaGUgc3RyaW5nIHJldHVybmVkIGlzIG1hZGUgb2YgdGhlIHRleHQgY29udGVudCBvZiB0aGlzIG5vZGUKKyAgICAgKiBkZXBlbmRpbmcgb24gaXRzIHR5cGUsIGFzIGRlZmluZWQgYmVsb3c6CisgICAgICogPHRhYmxlIGJvcmRlcj0nMScgY2VsbHBhZGRpbmc9JzMnPgorICAgICAqIDx0cj4KKyAgICAgKiA8dGg+Tm9kZSB0eXBlPC90aD4KKyAgICAgKiA8dGg+Q29udGVudDwvdGg+CisgICAgICogPC90cj4KKyAgICAgKiA8dHI+CisgICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KKyAgICAgKiBFTEVNRU5UX05PREUsIEFUVFJJQlVURV9OT0RFLCBFTlRJVFlfTk9ERSwgRU5USVRZX1JFRkVSRU5DRV9OT0RFLAorICAgICAqIERPQ1VNRU5UX0ZSQUdNRU5UX05PREU8L3RkPgorICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Y29uY2F0ZW5hdGlvbiBvZiB0aGUgPGNvZGU+dGV4dENvbnRlbnQ8L2NvZGU+CisgICAgICogYXR0cmlidXRlIHZhbHVlIG9mIGV2ZXJ5IGNoaWxkIG5vZGUsIGV4Y2x1ZGluZyBDT01NRU5UX05PREUgYW5kCisgICAgICogUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIG5vZGVzLiBUaGlzIGlzIHRoZSBlbXB0eSBzdHJpbmcgaWYgdGhlCisgICAgICogbm9kZSBoYXMgbm8gY2hpbGRyZW4uPC90ZD4KKyAgICAgKiA8L3RyPgorICAgICAqIDx0cj4KKyAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPlRFWFRfTk9ERSwgQ0RBVEFfU0VDVElPTl9OT0RFLCBDT01NRU5UX05PREUsCisgICAgICogUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFPC90ZD4KKyAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPm5vZGVWYWx1ZTwvY29kZT48L3RkPgorICAgICAqIDwvdHI+CisgICAgICogPHRyPgorICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+RE9DVU1FTlRfTk9ERSwKKyAgICAgKiBET0NVTUVOVF9UWVBFX05PREUsIE5PVEFUSU9OX05PREU8L3RkPgorICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGVtPm51bGw8L2VtPjwvdGQ+CisgICAgICogPC90cj4KKyAgICAgKiA8L3RhYmxlPgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBET01TVFJJTkdfU0laRV9FUlI6IFJhaXNlZCB3aGVuIGl0IHdvdWxkIHJldHVybiBtb3JlIGNoYXJhY3RlcnMgdGhhbgorICAgICAqICAgZml0IGluIGEgPGNvZGU+RE9NU3RyaW5nPC9jb2RlPiB2YXJpYWJsZSBvbiB0aGUgaW1wbGVtZW50YXRpb24KKyAgICAgKiAgIHBsYXRmb3JtLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGV4dENvbnRlbnQoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworICAgIC8qKgorICAgICAqIFRoaXMgYXR0cmlidXRlIHJldHVybnMgdGhlIHRleHQgY29udGVudCBvZiB0aGlzIG5vZGUgYW5kIGl0cworICAgICAqIGRlc2NlbmRhbnRzLiBXaGVuIGl0IGlzIGRlZmluZWQgdG8gYmUgPGNvZGU+bnVsbDwvY29kZT4sIHNldHRpbmcgaXQKKyAgICAgKiBoYXMgbm8gZWZmZWN0LiBPbiBzZXR0aW5nLCBhbnkgcG9zc2libGUgY2hpbGRyZW4gdGhpcyBub2RlIG1heSBoYXZlCisgICAgICogYXJlIHJlbW92ZWQgYW5kLCBpZiBpdCB0aGUgbmV3IHN0cmluZyBpcyBub3QgZW1wdHkgb3IKKyAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiwgcmVwbGFjZWQgYnkgYSBzaW5nbGUgPGNvZGU+VGV4dDwvY29kZT4gbm9kZQorICAgICAqIGNvbnRhaW5pbmcgdGhlIHN0cmluZyB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdG8uCisgICAgICogPGJyPiBPbiBnZXR0aW5nLCBubyBzZXJpYWxpemF0aW9uIGlzIHBlcmZvcm1lZCwgdGhlIHJldHVybmVkIHN0cmluZworICAgICAqIGRvZXMgbm90IGNvbnRhaW4gYW55IG1hcmt1cC4gTm8gd2hpdGVzcGFjZSBub3JtYWxpemF0aW9uIGlzIHBlcmZvcm1lZAorICAgICAqIGFuZCB0aGUgcmV0dXJuZWQgc3RyaW5nIGRvZXMgbm90IGNvbnRhaW4gdGhlIHdoaXRlIHNwYWNlcyBpbiBlbGVtZW50CisgICAgICogY29udGVudCAoc2VlIHRoZSBhdHRyaWJ1dGUKKyAgICAgKiA8Y29kZT5UZXh0LmlzRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlPC9jb2RlPikuIFNpbWlsYXJseSwgb24gc2V0dGluZywKKyAgICAgKiBubyBwYXJzaW5nIGlzIHBlcmZvcm1lZCBlaXRoZXIsIHRoZSBpbnB1dCBzdHJpbmcgaXMgdGFrZW4gYXMgcHVyZQorICAgICAqIHRleHR1YWwgY29udGVudC4KKyAgICAgKiA8YnI+VGhlIHN0cmluZyByZXR1cm5lZCBpcyBtYWRlIG9mIHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhpcyBub2RlCisgICAgICogZGVwZW5kaW5nIG9uIGl0cyB0eXBlLCBhcyBkZWZpbmVkIGJlbG93OgorICAgICAqIDx0YWJsZSBib3JkZXI9JzEnIGNlbGxwYWRkaW5nPSczJz4KKyAgICAgKiA8dHI+CisgICAgICogPHRoPk5vZGUgdHlwZTwvdGg+CisgICAgICogPHRoPkNvbnRlbnQ8L3RoPgorICAgICAqIDwvdHI+CisgICAgICogPHRyPgorICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+CisgICAgICogRUxFTUVOVF9OT0RFLCBBVFRSSUJVVEVfTk9ERSwgRU5USVRZX05PREUsIEVOVElUWV9SRUZFUkVOQ0VfTk9ERSwKKyAgICAgKiBET0NVTUVOVF9GUkFHTUVOVF9OT0RFPC90ZD4KKyAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPmNvbmNhdGVuYXRpb24gb2YgdGhlIDxjb2RlPnRleHRDb250ZW50PC9jb2RlPgorICAgICAqIGF0dHJpYnV0ZSB2YWx1ZSBvZiBldmVyeSBjaGlsZCBub2RlLCBleGNsdWRpbmcgQ09NTUVOVF9OT0RFIGFuZAorICAgICAqIFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSBub2Rlcy4gVGhpcyBpcyB0aGUgZW1wdHkgc3RyaW5nIGlmIHRoZQorICAgICAqIG5vZGUgaGFzIG5vIGNoaWxkcmVuLjwvdGQ+CisgICAgICogPC90cj4KKyAgICAgKiA8dHI+CisgICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5URVhUX05PREUsIENEQVRBX1NFQ1RJT05fTk9ERSwgQ09NTUVOVF9OT0RFLAorICAgICAqIFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTwvdGQ+CisgICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5ub2RlVmFsdWU8L2NvZGU+PC90ZD4KKyAgICAgKiA8L3RyPgorICAgICAqIDx0cj4KKyAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPkRPQ1VNRU5UX05PREUsCisgICAgICogRE9DVU1FTlRfVFlQRV9OT0RFLCBOT1RBVElPTl9OT0RFPC90ZD4KKyAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxlbT5udWxsPC9lbT48L3RkPgorICAgICAqIDwvdHI+CisgICAgICogPC90YWJsZT4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgd2hlbiB0aGUgbm9kZSBpcyByZWFkb25seS4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUZXh0Q29udGVudChTdHJpbmcgdGV4dENvbnRlbnQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBub2RlIGlzIHRoZSBzYW1lIG5vZGUgYXMgdGhlIGdpdmVuIG9uZS4KKyAgICAgKiA8YnI+VGhpcyBtZXRob2QgcHJvdmlkZXMgYSB3YXkgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdHdvCisgICAgICogPGNvZGU+Tm9kZTwvY29kZT4gcmVmZXJlbmNlcyByZXR1cm5lZCBieSB0aGUgaW1wbGVtZW50YXRpb24gcmVmZXJlbmNlCisgICAgICogdGhlIHNhbWUgb2JqZWN0LiBXaGVuIHR3byA8Y29kZT5Ob2RlPC9jb2RlPiByZWZlcmVuY2VzIGFyZSByZWZlcmVuY2VzCisgICAgICogdG8gdGhlIHNhbWUgb2JqZWN0LCBldmVuIGlmIHRocm91Z2ggYSBwcm94eSwgdGhlIHJlZmVyZW5jZXMgbWF5IGJlCisgICAgICogdXNlZCBjb21wbGV0ZWx5IGludGVyY2hhbmdlYWJseSwgc3VjaCB0aGF0IGFsbCBhdHRyaWJ1dGVzIGhhdmUgdGhlCisgICAgICogc2FtZSB2YWx1ZXMgYW5kIGNhbGxpbmcgdGhlIHNhbWUgRE9NIG1ldGhvZCBvbiBlaXRoZXIgcmVmZXJlbmNlCisgICAgICogYWx3YXlzIGhhcyBleGFjdGx5IHRoZSBzYW1lIGVmZmVjdC4KKyAgICAgKiBAcGFyYW0gb3RoZXIgVGhlIG5vZGUgdG8gdGVzdCBhZ2FpbnN0LgorICAgICAqIEByZXR1cm4gUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgbm9kZXMgYXJlIHRoZSBzYW1lLAorICAgICAqICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NhbWVOb2RlKE5vZGUgb3RoZXIpOworCisgICAgLyoqCisgICAgICogTG9vayB1cCB0aGUgcHJlZml4IGFzc29jaWF0ZWQgdG8gdGhlIGdpdmVuIG5hbWVzcGFjZSBVUkksIHN0YXJ0aW5nIGZyb20KKyAgICAgKiB0aGlzIG5vZGUuIFRoZSBkZWZhdWx0IG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgYXJlIGlnbm9yZWQgYnkgdGhpcworICAgICAqIG1ldGhvZC4KKyAgICAgKiA8YnI+U2VlICBmb3IgZGV0YWlscyBvbiB0aGUgYWxnb3JpdGhtIHVzZWQgYnkgdGhpcyBtZXRob2QuCisgICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSB0byBsb29rIGZvci4KKyAgICAgKiBAcmV0dXJuIFJldHVybnMgYW4gYXNzb2NpYXRlZCBuYW1lc3BhY2UgcHJlZml4IGlmIGZvdW5kIG9yCisgICAgICogICA8Y29kZT5udWxsPC9jb2RlPiBpZiBub25lIGlzIGZvdW5kLiBJZiBtb3JlIHRoYW4gb25lIHByZWZpeCBhcmUKKyAgICAgKiAgIGFzc29jaWF0ZWQgdG8gdGhlIG5hbWVzcGFjZSBwcmVmaXgsIHRoZSByZXR1cm5lZCBuYW1lc3BhY2UgcHJlZml4CisgICAgICogICBpcyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAzCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBsb29rdXBQcmVmaXgoU3RyaW5nIG5hbWVzcGFjZVVSSSk7CisKKyAgICAvKioKKyAgICAgKiAgVGhpcyBtZXRob2QgY2hlY2tzIGlmIHRoZSBzcGVjaWZpZWQgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyB0aGUKKyAgICAgKiBkZWZhdWx0IG5hbWVzcGFjZSBvciBub3QuCisgICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSB0byBsb29rIGZvci4KKyAgICAgKiBAcmV0dXJuIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHNwZWNpZmllZAorICAgICAqICAgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyB0aGUgZGVmYXVsdCBuYW1lc3BhY2UsCisgICAgICogICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRGVmYXVsdE5hbWVzcGFjZShTdHJpbmcgbmFtZXNwYWNlVVJJKTsKKworICAgIC8qKgorICAgICAqIExvb2sgdXAgdGhlIG5hbWVzcGFjZSBVUkkgYXNzb2NpYXRlZCB0byB0aGUgZ2l2ZW4gcHJlZml4LCBzdGFydGluZyBmcm9tCisgICAgICogdGhpcyBub2RlLgorICAgICAqIDxicj5TZWUgIGZvciBkZXRhaWxzIG9uIHRoZSBhbGdvcml0aG0gdXNlZCBieSB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gcHJlZml4IFRoZSBwcmVmaXggdG8gbG9vayBmb3IuIElmIHRoaXMgcGFyYW1ldGVyIGlzCisgICAgICogICA8Y29kZT5udWxsPC9jb2RlPiwgdGhlIG1ldGhvZCB3aWxsIHJldHVybiB0aGUgZGVmYXVsdCBuYW1lc3BhY2UgVVJJCisgICAgICogICBpZiBhbnkuCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBhc3NvY2lhdGVkIG5hbWVzcGFjZSBVUkkgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYKKyAgICAgKiAgIG5vbmUgaXMgZm91bmQuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAzCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBsb29rdXBOYW1lc3BhY2VVUkkoU3RyaW5nIHByZWZpeCk7CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB3aGV0aGVyIHR3byBub2RlcyBhcmUgZXF1YWwuCisgICAgICogPGJyPlRoaXMgbWV0aG9kIHRlc3RzIGZvciBlcXVhbGl0eSBvZiBub2Rlcywgbm90IHNhbWVuZXNzIChpLmUuLAorICAgICAqIHdoZXRoZXIgdGhlIHR3byBub2RlcyBhcmUgcmVmZXJlbmNlcyB0byB0aGUgc2FtZSBvYmplY3QpIHdoaWNoIGNhbiBiZQorICAgICAqIHRlc3RlZCB3aXRoIDxjb2RlPk5vZGUuaXNTYW1lTm9kZSgpPC9jb2RlPi4gQWxsIG5vZGVzIHRoYXQgYXJlIHRoZQorICAgICAqIHNhbWUgd2lsbCBhbHNvIGJlIGVxdWFsLCB0aG91Z2ggdGhlIHJldmVyc2UgbWF5IG5vdCBiZSB0cnVlLgorICAgICAqIDxicj5Ud28gbm9kZXMgYXJlIGVxdWFsIGlmIGFuZCBvbmx5IGlmIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyAgICAgKiBzYXRpc2ZpZWQ6CisgICAgICogPHVsPgorICAgICAqIDxsaT5UaGUgdHdvIG5vZGVzIGFyZSBvZiB0aGUgc2FtZSB0eXBlLgorICAgICAqIDwvbGk+CisgICAgICogPGxpPlRoZSBmb2xsb3dpbmcgc3RyaW5nCisgICAgICogYXR0cmlidXRlcyBhcmUgZXF1YWw6IDxjb2RlPm5vZGVOYW1lPC9jb2RlPiwgPGNvZGU+bG9jYWxOYW1lPC9jb2RlPiwKKyAgICAgKiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+LCA8Y29kZT5wcmVmaXg8L2NvZGU+LCA8Y29kZT5ub2RlVmFsdWU8L2NvZGU+CisgICAgICogLiBUaGlzIGlzOiB0aGV5IGFyZSBib3RoIDxjb2RlPm51bGw8L2NvZGU+LCBvciB0aGV5IGhhdmUgdGhlIHNhbWUKKyAgICAgKiBsZW5ndGggYW5kIGFyZSBjaGFyYWN0ZXIgZm9yIGNoYXJhY3RlciBpZGVudGljYWwuCisgICAgICogPC9saT4KKyAgICAgKiA8bGk+VGhlCisgICAgICogPGNvZGU+YXR0cmlidXRlczwvY29kZT4gPGNvZGU+TmFtZWROb2RlTWFwczwvY29kZT4gYXJlIGVxdWFsLiBUaGlzCisgICAgICogaXM6IHRoZXkgYXJlIGJvdGggPGNvZGU+bnVsbDwvY29kZT4sIG9yIHRoZXkgaGF2ZSB0aGUgc2FtZSBsZW5ndGggYW5kCisgICAgICogZm9yIGVhY2ggbm9kZSB0aGF0IGV4aXN0cyBpbiBvbmUgbWFwIHRoZXJlIGlzIGEgbm9kZSB0aGF0IGV4aXN0cyBpbgorICAgICAqIHRoZSBvdGhlciBtYXAgYW5kIGlzIGVxdWFsLCBhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgYXQgdGhlIHNhbWUKKyAgICAgKiBpbmRleC4KKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT5UaGUgPGNvZGU+Y2hpbGROb2RlczwvY29kZT4gPGNvZGU+Tm9kZUxpc3RzPC9jb2RlPiBhcmUgZXF1YWwuCisgICAgICogVGhpcyBpczogdGhleSBhcmUgYm90aCA8Y29kZT5udWxsPC9jb2RlPiwgb3IgdGhleSBoYXZlIHRoZSBzYW1lCisgICAgICogbGVuZ3RoIGFuZCBjb250YWluIGVxdWFsIG5vZGVzIGF0IHRoZSBzYW1lIGluZGV4LiBOb3RlIHRoYXQKKyAgICAgKiBub3JtYWxpemF0aW9uIGNhbiBhZmZlY3QgZXF1YWxpdHk7IHRvIGF2b2lkIHRoaXMsIG5vZGVzIHNob3VsZCBiZQorICAgICAqIG5vcm1hbGl6ZWQgYmVmb3JlIGJlaW5nIGNvbXBhcmVkLgorICAgICAqIDwvbGk+CisgICAgICogPC91bD4KKyAgICAgKiA8YnI+Rm9yIHR3byA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IG5vZGVzIHRvIGJlIGVxdWFsLCB0aGUgZm9sbG93aW5nCisgICAgICogY29uZGl0aW9ucyBtdXN0IGFsc28gYmUgc2F0aXNmaWVkOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+VGhlIGZvbGxvd2luZyBzdHJpbmcgYXR0cmlidXRlcworICAgICAqIGFyZSBlcXVhbDogPGNvZGU+cHVibGljSWQ8L2NvZGU+LCA8Y29kZT5zeXN0ZW1JZDwvY29kZT4sCisgICAgICogPGNvZGU+aW50ZXJuYWxTdWJzZXQ8L2NvZGU+LgorICAgICAqIDwvbGk+CisgICAgICogPGxpPlRoZSA8Y29kZT5lbnRpdGllczwvY29kZT4KKyAgICAgKiA8Y29kZT5OYW1lZE5vZGVNYXBzPC9jb2RlPiBhcmUgZXF1YWwuCisgICAgICogPC9saT4KKyAgICAgKiA8bGk+VGhlIDxjb2RlPm5vdGF0aW9uczwvY29kZT4KKyAgICAgKiA8Y29kZT5OYW1lZE5vZGVNYXBzPC9jb2RlPiBhcmUgZXF1YWwuCisgICAgICogPC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqIDxicj5PbiB0aGUgb3RoZXIgaGFuZCwgdGhlIGZvbGxvd2luZyBkbyBub3QgYWZmZWN0IGVxdWFsaXR5OiB0aGUKKyAgICAgKiA8Y29kZT5vd25lckRvY3VtZW50PC9jb2RlPiwgPGNvZGU+YmFzZVVSSTwvY29kZT4sIGFuZAorICAgICAqIDxjb2RlPnBhcmVudE5vZGU8L2NvZGU+IGF0dHJpYnV0ZXMsIHRoZSA8Y29kZT5zcGVjaWZpZWQ8L2NvZGU+CisgICAgICogYXR0cmlidXRlIGZvciA8Y29kZT5BdHRyPC9jb2RlPiBub2RlcywgdGhlIDxjb2RlPnNjaGVtYVR5cGVJbmZvPC9jb2RlPgorICAgICAqICBhdHRyaWJ1dGUgZm9yIDxjb2RlPkF0dHI8L2NvZGU+IGFuZCA8Y29kZT5FbGVtZW50PC9jb2RlPiBub2RlcywgdGhlCisgICAgICogPGNvZGU+VGV4dC5pc0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZTwvY29kZT4gYXR0cmlidXRlIGZvcgorICAgICAqIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGVzLCBhcyB3ZWxsIGFzIGFueSB1c2VyIGRhdGEgb3IgZXZlbnQgbGlzdGVuZXJzCisgICAgICogcmVnaXN0ZXJlZCBvbiB0aGUgbm9kZXMuCisgICAgICogPHAgPjxiPk5vdGU6PC9iPiAgQXMgYSBnZW5lcmFsIHJ1bGUsIGFueXRoaW5nIG5vdCBtZW50aW9uZWQgaW4gdGhlCisgICAgICogZGVzY3JpcHRpb24gYWJvdmUgaXMgbm90IHNpZ25pZmljYW50IGluIGNvbnNpZGVyYXRpb24gb2YgZXF1YWxpdHkKKyAgICAgKiBjaGVja2luZy4gTm90ZSB0aGF0IGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGlzIHNwZWNpZmljYXRpb24gbWF5IHRha2UKKyAgICAgKiBpbnRvIGFjY291bnQgbW9yZSBhdHRyaWJ1dGVzIGFuZCBpbXBsZW1lbnRhdGlvbnMgY29uZm9ybSB0byB0aGlzCisgICAgICogc3BlY2lmaWNhdGlvbiBhcmUgZXhwZWN0ZWQgdG8gYmUgdXBkYXRlZCBhY2NvcmRpbmdseS4KKyAgICAgKiBAcGFyYW0gYXJnIFRoZSBub2RlIHRvIGNvbXBhcmUgZXF1YWxpdHkgd2l0aC4KKyAgICAgKiBAcmV0dXJuIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIG5vZGVzIGFyZSBlcXVhbCwKKyAgICAgKiAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAzCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFcXVhbE5vZGUoTm9kZSBhcmcpOworCisgICAgLyoqCisgICAgICogIFRoaXMgbWV0aG9kIHJldHVybnMgYSBzcGVjaWFsaXplZCBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyB0aGUKKyAgICAgKiBzcGVjaWFsaXplZCBBUElzIG9mIHRoZSBzcGVjaWZpZWQgZmVhdHVyZSBhbmQgdmVyc2lvbiwgYXMgc3BlY2lmaWVkCisgICAgICogaW4gLiBUaGUgc3BlY2lhbGl6ZWQgb2JqZWN0IG1heSBhbHNvIGJlIG9idGFpbmVkIGJ5IHVzaW5nCisgICAgICogYmluZGluZy1zcGVjaWZpYyBjYXN0aW5nIG1ldGhvZHMgYnV0IGlzIG5vdCBuZWNlc3NhcmlseSBleHBlY3RlZCB0bywKKyAgICAgKiBhcyBkaXNjdXNzZWQgaW4gLiBUaGlzIG1ldGhvZCBhbHNvIGFsbG93IHRoZSBpbXBsZW1lbnRhdGlvbiB0bworICAgICAqIHByb3ZpZGUgc3BlY2lhbGl6ZWQgb2JqZWN0cyB3aGljaCBkbyBub3Qgc3VwcG9ydCB0aGUgPGNvZGU+Tm9kZTwvY29kZT4KKyAgICAgKiAgaW50ZXJmYWNlLgorICAgICAqIEBwYXJhbSBmZWF0dXJlICBUaGUgbmFtZSBvZiB0aGUgZmVhdHVyZSByZXF1ZXN0ZWQuIE5vdGUgdGhhdCBhbnkgcGx1cworICAgICAqICAgc2lnbiAiKyIgcHJlcGVuZGVkIHRvIHRoZSBuYW1lIG9mIHRoZSBmZWF0dXJlIHdpbGwgYmUgaWdub3JlZCBzaW5jZQorICAgICAqICAgaXQgaXMgbm90IHNpZ25pZmljYW50IGluIHRoZSBjb250ZXh0IG9mIHRoaXMgbWV0aG9kLgorICAgICAqIEBwYXJhbSB2ZXJzaW9uICBUaGlzIGlzIHRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGUgZmVhdHVyZSB0byB0ZXN0LgorICAgICAqIEByZXR1cm4gIFJldHVybnMgYW4gb2JqZWN0IHdoaWNoIGltcGxlbWVudHMgdGhlIHNwZWNpYWxpemVkIEFQSXMgb2YKKyAgICAgKiAgIHRoZSBzcGVjaWZpZWQgZmVhdHVyZSBhbmQgdmVyc2lvbiwgaWYgYW55LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZgorICAgICAqICAgdGhlcmUgaXMgbm8gb2JqZWN0IHdoaWNoIGltcGxlbWVudHMgaW50ZXJmYWNlcyBhc3NvY2lhdGVkIHdpdGggdGhhdAorICAgICAqICAgZmVhdHVyZS4gSWYgdGhlIDxjb2RlPkRPTU9iamVjdDwvY29kZT4gcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QKKyAgICAgKiAgIGltcGxlbWVudHMgdGhlIDxjb2RlPk5vZGU8L2NvZGU+IGludGVyZmFjZSwgaXQgbXVzdCBkZWxlZ2F0ZSB0byB0aGUKKyAgICAgKiAgIHByaW1hcnkgY29yZSA8Y29kZT5Ob2RlPC9jb2RlPiBhbmQgbm90IHJldHVybiByZXN1bHRzIGluY29uc2lzdGVudAorICAgICAqICAgd2l0aCB0aGUgcHJpbWFyeSBjb3JlIDxjb2RlPk5vZGU8L2NvZGU+IHN1Y2ggYXMgYXR0cmlidXRlcywKKyAgICAgKiAgIGNoaWxkTm9kZXMsIGV0Yy4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2ZXJzaW9uKTsKKworICAgIC8qKgorICAgICAqIEFzc29jaWF0ZSBhbiBvYmplY3QgdG8gYSBrZXkgb24gdGhpcyBub2RlLiBUaGUgb2JqZWN0IGNhbiBsYXRlciBiZQorICAgICAqIHJldHJpZXZlZCBmcm9tIHRoaXMgbm9kZSBieSBjYWxsaW5nIDxjb2RlPmdldFVzZXJEYXRhPC9jb2RlPiB3aXRoIHRoZQorICAgICAqIHNhbWUga2V5LgorICAgICAqIEBwYXJhbSBrZXkgVGhlIGtleSB0byBhc3NvY2lhdGUgdGhlIG9iamVjdCB0by4KKyAgICAgKiBAcGFyYW0gZGF0YSBUaGUgb2JqZWN0IHRvIGFzc29jaWF0ZSB0byB0aGUgZ2l2ZW4ga2V5LCBvcgorICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4gdG8gcmVtb3ZlIGFueSBleGlzdGluZyBhc3NvY2lhdGlvbiB0byB0aGF0IGtleS4KKyAgICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgaGFuZGxlciB0byBhc3NvY2lhdGUgdG8gdGhhdCBrZXksIG9yCisgICAgICogICA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIDxjb2RlPkRPTVVzZXJEYXRhPC9jb2RlPiBwcmV2aW91c2x5IGFzc29jaWF0ZWQgdG8KKyAgICAgKiAgIHRoZSBnaXZlbiBrZXkgb24gdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSB3YXMgbm9uZS4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IHNldFVzZXJEYXRhKFN0cmluZyBrZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzZXJEYXRhSGFuZGxlciBoYW5kbGVyKTsKKworICAgIC8qKgorICAgICAqIFJldHJpZXZlcyB0aGUgb2JqZWN0IGFzc29jaWF0ZWQgdG8gYSBrZXkgb24gYSB0aGlzIG5vZGUuIFRoZSBvYmplY3QKKyAgICAgKiBtdXN0IGZpcnN0IGhhdmUgYmVlbiBzZXQgdG8gdGhpcyBub2RlIGJ5IGNhbGxpbmcKKyAgICAgKiA8Y29kZT5zZXRVc2VyRGF0YTwvY29kZT4gd2l0aCB0aGUgc2FtZSBrZXkuCisgICAgICogQHBhcmFtIGtleSBUaGUga2V5IHRoZSBvYmplY3QgaXMgYXNzb2NpYXRlZCB0by4KKyAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIDxjb2RlPkRPTVVzZXJEYXRhPC9jb2RlPiBhc3NvY2lhdGVkIHRvIHRoZSBnaXZlbgorICAgICAqICAga2V5IG9uIHRoaXMgbm9kZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgd2FzIG5vbmUuCisgICAgICogQHNpbmNlIERPTSBMZXZlbCAzCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRVc2VyRGF0YShTdHJpbmcga2V5KTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL05vZGVMaXN0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vTm9kZUxpc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YTk4YTkwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL05vZGVMaXN0LmphdmEKQEAgLTAsMCArMSw0MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICoKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgorICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCisgKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAorICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCisgKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisgKgorICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tOworCisvKioKKyAqIFRoZSA8Y29kZT5Ob2RlTGlzdDwvY29kZT4gaW50ZXJmYWNlIHByb3ZpZGVzIHRoZSBhYnN0cmFjdGlvbiBvZiBhbiBvcmRlcmVkCisgKiBjb2xsZWN0aW9uIG9mIG5vZGVzLCB3aXRob3V0IGRlZmluaW5nIG9yIGNvbnN0cmFpbmluZyBob3cgdGhpcyBjb2xsZWN0aW9uCisgKiBpcyBpbXBsZW1lbnRlZC4gPGNvZGU+Tm9kZUxpc3Q8L2NvZGU+IG9iamVjdHMgaW4gdGhlIERPTSBhcmUgbGl2ZS4KKyAqIDxwPlRoZSBpdGVtcyBpbiB0aGUgPGNvZGU+Tm9kZUxpc3Q8L2NvZGU+IGFyZSBhY2Nlc3NpYmxlIHZpYSBhbiBpbnRlZ3JhbAorICogaW5kZXgsIHN0YXJ0aW5nIGZyb20gMC4KKyAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgorICovCitwdWJsaWMgaW50ZXJmYWNlIE5vZGVMaXN0IHsKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBpdGVtIGluIHRoZSBjb2xsZWN0aW9uLiBJZgorICAgICAqIDxjb2RlPmluZGV4PC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBub2RlcyBpbgorICAgICAqIHRoZSBsaXN0LCB0aGlzIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICogQHBhcmFtIGluZGV4IEluZGV4IGludG8gdGhlIGNvbGxlY3Rpb24uCisgICAgICogQHJldHVybiBUaGUgbm9kZSBhdCB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggcG9zaXRpb24gaW4gdGhlCisgICAgICogICA8Y29kZT5Ob2RlTGlzdDwvY29kZT4sIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoYXQgaXMgbm90IGEgdmFsaWQKKyAgICAgKiAgIGluZGV4LgorICAgICAqLworICAgIHB1YmxpYyBOb2RlIGl0ZW0oaW50IGluZGV4KTsKKworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhlIGxpc3QuIFRoZSByYW5nZSBvZiB2YWxpZCBjaGlsZCBub2RlIGluZGljZXMKKyAgICAgKiBpcyAwIHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPiBpbmNsdXNpdmUuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRMZW5ndGgoKTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL05vdGF0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vTm90YXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hN2FkNDA5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL05vdGF0aW9uLmphdmEKQEAgLTAsMCArMSw0MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICoKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgorICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCisgKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAorICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCisgKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisgKgorICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tOworCisvKioKKyAqIFRoaXMgaW50ZXJmYWNlIHJlcHJlc2VudHMgYSBub3RhdGlvbiBkZWNsYXJlZCBpbiB0aGUgRFRELiBBIG5vdGF0aW9uIGVpdGhlcgorICogZGVjbGFyZXMsIGJ5IG5hbWUsIHRoZSBmb3JtYXQgb2YgYW4gdW5wYXJzZWQgZW50aXR5IChzZWUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0I05vdGF0aW9ucyc+c2VjdGlvbiA0Ljc8L2E+IG9mIHRoZSBYTUwgMS4wIHNwZWNpZmljYXRpb24gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dKSwgb3IgaXMKKyAqIHVzZWQgZm9yIGZvcm1hbCBkZWNsYXJhdGlvbiBvZiBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRhcmdldHMgKHNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQjc2VjLXBpJz5zZWN0aW9uIDIuNjwvYT4gb2YgdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0pLiBUaGUKKyAqIDxjb2RlPm5vZGVOYW1lPC9jb2RlPiBhdHRyaWJ1dGUgaW5oZXJpdGVkIGZyb20gPGNvZGU+Tm9kZTwvY29kZT4gaXMgc2V0CisgKiB0byB0aGUgZGVjbGFyZWQgbmFtZSBvZiB0aGUgbm90YXRpb24uCisgKiA8cD5UaGUgRE9NIENvcmUgZG9lcyBub3Qgc3VwcG9ydCBlZGl0aW5nIDxjb2RlPk5vdGF0aW9uPC9jb2RlPiBub2RlczsgdGhleQorICogYXJlIHRoZXJlZm9yZSByZWFkb25seS4KKyAqIDxwPkEgPGNvZGU+Tm90YXRpb248L2NvZGU+IG5vZGUgZG9lcyBub3QgaGF2ZSBhbnkgcGFyZW50LgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgTm90YXRpb24gZXh0ZW5kcyBOb2RlIHsKKyAgICAvKioKKyAgICAgKiBUaGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhpcyBub3RhdGlvbi4gSWYgdGhlIHB1YmxpYyBpZGVudGlmaWVyIHdhcworICAgICAqIG5vdCBzcGVjaWZpZWQsIHRoaXMgaXMgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpOworCisgICAgLyoqCisgICAgICogVGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoaXMgbm90YXRpb24uIElmIHRoZSBzeXN0ZW0gaWRlbnRpZmllciB3YXMKKyAgICAgKiBub3Qgc3BlY2lmaWVkLCB0aGlzIGlzIDxjb2RlPm51bGw8L2NvZGU+LiBUaGlzIG1heSBiZSBhbiBhYnNvbHV0ZSBVUkkKKyAgICAgKiBvciBub3QuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vUHJvY2Vzc2luZ0luc3RydWN0aW9uLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vUHJvY2Vzc2luZ0luc3RydWN0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjFiNzg5MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb24uamF2YQpAQCAtMCwwICsxLDUxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKgorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCisgKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKKyAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0CisgKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKKyAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KKyAqCisgKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb207CisKKy8qKgorICogVGhlIDxjb2RlPlByb2Nlc3NpbmdJbnN0cnVjdGlvbjwvY29kZT4gaW50ZXJmYWNlIHJlcHJlc2VudHMgYSAicHJvY2Vzc2luZworICogaW5zdHJ1Y3Rpb24iLCB1c2VkIGluIFhNTCBhcyBhIHdheSB0byBrZWVwIHByb2Nlc3Nvci1zcGVjaWZpYyBpbmZvcm1hdGlvbgorICogaW4gdGhlIHRleHQgb2YgdGhlIGRvY3VtZW50LgorICogPHA+IE5vIGxleGljYWwgY2hlY2sgaXMgZG9uZSBvbiB0aGUgY29udGVudCBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gYW5kCisgKiBpdCBpcyB0aGVyZWZvcmUgcG9zc2libGUgdG8gaGF2ZSB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlCisgKiA8Y29kZT4iPyZndDsiPC9jb2RlPiBpbiB0aGUgY29udGVudCwgd2hpY2ggaXMgaWxsZWdhbCBhIHByb2Nlc3NpbmcKKyAqIGluc3RydWN0aW9uIHBlciBzZWN0aW9uIDIuNiBvZiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0uIFRoZQorICogcHJlc2VuY2Ugb2YgdGhpcyBjaGFyYWN0ZXIgc2VxdWVuY2UgbXVzdCBnZW5lcmF0ZSBhIGZhdGFsIGVycm9yIGR1cmluZworICogc2VyaWFsaXphdGlvbi4KKyAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgorICovCitwdWJsaWMgaW50ZXJmYWNlIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBleHRlbmRzIE5vZGUgeworICAgIC8qKgorICAgICAqIFRoZSB0YXJnZXQgb2YgdGhpcyBwcm9jZXNzaW5nIGluc3RydWN0aW9uLiBYTUwgZGVmaW5lcyB0aGlzIGFzIGJlaW5nCisgICAgICogdGhlIGZpcnN0IHRva2VuIGZvbGxvd2luZyB0aGUgbWFya3VwIHRoYXQgYmVnaW5zIHRoZSBwcm9jZXNzaW5nCisgICAgICogaW5zdHJ1Y3Rpb24uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXQoKTsKKworICAgIC8qKgorICAgICAqIFRoZSBjb250ZW50IG9mIHRoaXMgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4gVGhpcyBpcyBmcm9tIHRoZSBmaXJzdCBub24KKyAgICAgKiB3aGl0ZSBzcGFjZSBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIHRhcmdldCB0byB0aGUgY2hhcmFjdGVyIGltbWVkaWF0ZWx5CisgICAgICogcHJlY2VkaW5nIHRoZSA8Y29kZT4/Jmd0OzwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXREYXRhKCk7CisgICAgLyoqCisgICAgICogVGhlIGNvbnRlbnQgb2YgdGhpcyBwcm9jZXNzaW5nIGluc3RydWN0aW9uLiBUaGlzIGlzIGZyb20gdGhlIGZpcnN0IG5vbgorICAgICAqIHdoaXRlIHNwYWNlIGNoYXJhY3RlciBhZnRlciB0aGUgdGFyZ2V0IHRvIHRoZSBjaGFyYWN0ZXIgaW1tZWRpYXRlbHkKKyAgICAgKiBwcmVjZWRpbmcgdGhlIDxjb2RlPj8mZ3Q7PC9jb2RlPi4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgd2hlbiB0aGUgbm9kZSBpcyByZWFkb25seS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREYXRhKFN0cmluZyBkYXRhKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vVGV4dC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL1RleHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NzJjNTQ5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL1RleHQuamF2YQpAQCAtMCwwICsxLDEyNiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICoKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgorICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCisgKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAorICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCisgKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisgKgorICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tOworCisvKioKKyAqIFRoZSA8Y29kZT5UZXh0PC9jb2RlPiBpbnRlcmZhY2UgaW5oZXJpdHMgZnJvbSA8Y29kZT5DaGFyYWN0ZXJEYXRhPC9jb2RlPgorICogYW5kIHJlcHJlc2VudHMgdGhlIHRleHR1YWwgY29udGVudCAodGVybWVkIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCNzeW50YXgnPmNoYXJhY3RlciBkYXRhPC9hPiBpbiBYTUwpIG9mIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG9yIDxjb2RlPkF0dHI8L2NvZGU+LiBJZiB0aGVyZSBpcyBubworICogbWFya3VwIGluc2lkZSBhbiBlbGVtZW50J3MgY29udGVudCwgdGhlIHRleHQgaXMgY29udGFpbmVkIGluIGEgc2luZ2xlCisgKiBvYmplY3QgaW1wbGVtZW50aW5nIHRoZSA8Y29kZT5UZXh0PC9jb2RlPiBpbnRlcmZhY2UgdGhhdCBpcyB0aGUgb25seQorICogY2hpbGQgb2YgdGhlIGVsZW1lbnQuIElmIHRoZXJlIGlzIG1hcmt1cCwgaXQgaXMgcGFyc2VkIGludG8gdGhlCisgKiBpbmZvcm1hdGlvbiBpdGVtcyAoZWxlbWVudHMsIGNvbW1lbnRzLCBldGMuKSBhbmQgPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMKKyAqIHRoYXQgZm9ybSB0aGUgbGlzdCBvZiBjaGlsZHJlbiBvZiB0aGUgZWxlbWVudC4KKyAqIDxwPldoZW4gYSBkb2N1bWVudCBpcyBmaXJzdCBtYWRlIGF2YWlsYWJsZSB2aWEgdGhlIERPTSwgdGhlcmUgaXMgb25seSBvbmUKKyAqIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUgZm9yIGVhY2ggYmxvY2sgb2YgdGV4dC4gVXNlcnMgbWF5IGNyZWF0ZSBhZGphY2VudAorICogPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMgdGhhdCByZXByZXNlbnQgdGhlIGNvbnRlbnRzIG9mIGEgZ2l2ZW4gZWxlbWVudAorICogd2l0aG91dCBhbnkgaW50ZXJ2ZW5pbmcgbWFya3VwLCBidXQgc2hvdWxkIGJlIGF3YXJlIHRoYXQgdGhlcmUgaXMgbm8gd2F5CisgKiB0byByZXByZXNlbnQgdGhlIHNlcGFyYXRpb25zIGJldHdlZW4gdGhlc2Ugbm9kZXMgaW4gWE1MIG9yIEhUTUwsIHNvIHRoZXkKKyAqIHdpbGwgbm90IChpbiBnZW5lcmFsKSBwZXJzaXN0IGJldHdlZW4gRE9NIGVkaXRpbmcgc2Vzc2lvbnMuIFRoZQorICogPGNvZGU+Tm9kZS5ub3JtYWxpemUoKTwvY29kZT4gbWV0aG9kIG1lcmdlcyBhbnkgc3VjaCBhZGphY2VudAorICogPGNvZGU+VGV4dDwvY29kZT4gb2JqZWN0cyBpbnRvIGEgc2luZ2xlIG5vZGUgZm9yIGVhY2ggYmxvY2sgb2YgdGV4dC4KKyAqIDxwPiBObyBsZXhpY2FsIGNoZWNrIGlzIGRvbmUgb24gdGhlIGNvbnRlbnQgb2YgYSA8Y29kZT5UZXh0PC9jb2RlPiBub2RlCisgKiBhbmQsIGRlcGVuZGluZyBvbiBpdHMgcG9zaXRpb24gaW4gdGhlIGRvY3VtZW50LCBzb21lIGNoYXJhY3RlcnMgbXVzdCBiZQorICogZXNjYXBlZCBkdXJpbmcgc2VyaWFsaXphdGlvbiB1c2luZyBjaGFyYWN0ZXIgcmVmZXJlbmNlczsgZS5nLiB0aGUKKyAqIGNoYXJhY3RlcnMgIiZsdDsmYW1wOyIgaWYgdGhlIHRleHR1YWwgY29udGVudCBpcyBwYXJ0IG9mIGFuIGVsZW1lbnQgb3Igb2YKKyAqIGFuIGF0dHJpYnV0ZSwgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSAiXV0mZ3Q7IiB3aGVuIHBhcnQgb2YgYW4gZWxlbWVudCwKKyAqIHRoZSBxdW90YXRpb24gbWFyayBjaGFyYWN0ZXIgIiBvciB0aGUgYXBvc3Ryb3BoZSBjaGFyYWN0ZXIgJyB3aGVuIHBhcnQgb2YKKyAqIGFuIGF0dHJpYnV0ZS4KKyAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgorICovCitwdWJsaWMgaW50ZXJmYWNlIFRleHQgZXh0ZW5kcyBDaGFyYWN0ZXJEYXRhIHsKKyAgICAvKioKKyAgICAgKiBCcmVha3MgdGhpcyBub2RlIGludG8gdHdvIG5vZGVzIGF0IHRoZSBzcGVjaWZpZWQgPGNvZGU+b2Zmc2V0PC9jb2RlPiwKKyAgICAgKiBrZWVwaW5nIGJvdGggaW4gdGhlIHRyZWUgYXMgc2libGluZ3MuIEFmdGVyIGJlaW5nIHNwbGl0LCB0aGlzIG5vZGUKKyAgICAgKiB3aWxsIGNvbnRhaW4gYWxsIHRoZSBjb250ZW50IHVwIHRvIHRoZSA8Y29kZT5vZmZzZXQ8L2NvZGU+IHBvaW50LiBBCisgICAgICogbmV3IG5vZGUgb2YgdGhlIHNhbWUgdHlwZSwgd2hpY2ggY29udGFpbnMgYWxsIHRoZSBjb250ZW50IGF0IGFuZAorICAgICAqIGFmdGVyIHRoZSA8Y29kZT5vZmZzZXQ8L2NvZGU+IHBvaW50LCBpcyByZXR1cm5lZC4gSWYgdGhlIG9yaWdpbmFsCisgICAgICogbm9kZSBoYWQgYSBwYXJlbnQgbm9kZSwgdGhlIG5ldyBub2RlIGlzIGluc2VydGVkIGFzIHRoZSBuZXh0IHNpYmxpbmcKKyAgICAgKiBvZiB0aGUgb3JpZ2luYWwgbm9kZS4gV2hlbiB0aGUgPGNvZGU+b2Zmc2V0PC9jb2RlPiBpcyBlcXVhbCB0byB0aGUKKyAgICAgKiBsZW5ndGggb2YgdGhpcyBub2RlLCB0aGUgbmV3IG5vZGUgaGFzIG5vIGRhdGEuCisgICAgICogQHBhcmFtIG9mZnNldCBUaGUgMTYtYml0IHVuaXQgb2Zmc2V0IGF0IHdoaWNoIHRvIHNwbGl0LCBzdGFydGluZyBmcm9tCisgICAgICogICA8Y29kZT4wPC9jb2RlPi4KKyAgICAgKiBAcmV0dXJuIFRoZSBuZXcgbm9kZSwgb2YgdGhlIHNhbWUgdHlwZSBhcyB0aGlzIG5vZGUuCisgICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KKyAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBvZmZzZXQgaXMgbmVnYXRpdmUgb3IgZ3JlYXRlcgorICAgICAqICAgdGhhbiB0aGUgbnVtYmVyIG9mIDE2LWJpdCB1bml0cyBpbiA8Y29kZT5kYXRhPC9jb2RlPi4KKyAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG5vZGUgaXMgcmVhZG9ubHkuCisgICAgICovCisgICAgcHVibGljIFRleHQgc3BsaXRUZXh0KGludCBvZmZzZXQpCisgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyB0ZXh0IG5vZGUgY29udGFpbnMgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLWluZm9zZXQtMjAwNDAyMDQjaW5mb2l0ZW0uY2hhcmFjdGVyJz4KKyAgICAgKiBlbGVtZW50IGNvbnRlbnQgd2hpdGVzcGFjZTwvYT4sIG9mdGVuIGFidXNpdmVseSBjYWxsZWQgImlnbm9yYWJsZSB3aGl0ZXNwYWNlIi4gVGhlIHRleHQgbm9kZSBpcworICAgICAqIGRldGVybWluZWQgdG8gY29udGFpbiB3aGl0ZXNwYWNlIGluIGVsZW1lbnQgY29udGVudCBkdXJpbmcgdGhlIGxvYWQKKyAgICAgKiBvZiB0aGUgZG9jdW1lbnQgb3IgaWYgdmFsaWRhdGlvbiBvY2N1cnMgd2hpbGUgdXNpbmcKKyAgICAgKiA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPi4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbGwgdGV4dCBvZiA8Y29kZT5UZXh0PC9jb2RlPiBub2RlcyBsb2dpY2FsbHktYWRqYWNlbnQgdGV4dAorICAgICAqIG5vZGVzIHRvIHRoaXMgbm9kZSwgY29uY2F0ZW5hdGVkIGluIGRvY3VtZW50IG9yZGVyLgorICAgICAqIDxicj5Gb3IgaW5zdGFuY2UsIGluIHRoZSBleGFtcGxlIGJlbG93IDxjb2RlPndob2xlVGV4dDwvY29kZT4gb24gdGhlCisgICAgICogPGNvZGU+VGV4dDwvY29kZT4gbm9kZSB0aGF0IGNvbnRhaW5zICJiYXIiIHJldHVybnMgImJhcmZvbyIsIHdoaWxlIG9uCisgICAgICogdGhlIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUgdGhhdCBjb250YWlucyAiZm9vIiBpdCByZXR1cm5zICJiYXJmb28iLgorICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0V2hvbGVUZXh0KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXBsYWNlcyB0aGUgdGV4dCBvZiB0aGUgY3VycmVudCBub2RlIGFuZCBhbGwgbG9naWNhbGx5LWFkamFjZW50IHRleHQKKyAgICAgKiBub2RlcyB3aXRoIHRoZSBzcGVjaWZpZWQgdGV4dC4gQWxsIGxvZ2ljYWxseS1hZGphY2VudCB0ZXh0IG5vZGVzIGFyZQorICAgICAqIHJlbW92ZWQgaW5jbHVkaW5nIHRoZSBjdXJyZW50IG5vZGUgdW5sZXNzIGl0IHdhcyB0aGUgcmVjaXBpZW50IG9mIHRoZQorICAgICAqIHJlcGxhY2VtZW50IHRleHQuCisgICAgICogPGJyPlRoaXMgbWV0aG9kIHJldHVybnMgdGhlIG5vZGUgd2hpY2ggcmVjZWl2ZWQgdGhlIHJlcGxhY2VtZW50IHRleHQuCisgICAgICogVGhlIHJldHVybmVkIG5vZGUgaXM6CisgICAgICogPHVsPgorICAgICAqIDxsaT48Y29kZT5udWxsPC9jb2RlPiwgd2hlbiB0aGUgcmVwbGFjZW1lbnQgdGV4dCBpcworICAgICAqIHRoZSBlbXB0eSBzdHJpbmc7CisgICAgICogPC9saT4KKyAgICAgKiA8bGk+dGhlIGN1cnJlbnQgbm9kZSwgZXhjZXB0IHdoZW4gdGhlIGN1cnJlbnQgbm9kZSBpcworICAgICAqIHJlYWQtb25seTsKKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT4gYSBuZXcgPGNvZGU+VGV4dDwvY29kZT4gbm9kZSBvZiB0aGUgc2FtZSB0eXBlICgKKyAgICAgKiA8Y29kZT5UZXh0PC9jb2RlPiBvciA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+KSBhcyB0aGUgY3VycmVudCBub2RlCisgICAgICogaW5zZXJ0ZWQgYXQgdGhlIGxvY2F0aW9uIG9mIHRoZSByZXBsYWNlbWVudC4KKyAgICAgKiA8L2xpPgorICAgICAqIDwvdWw+CisgICAgICogPGJyPkZvciBpbnN0YW5jZSwgaW4gdGhlIGFib3ZlIGV4YW1wbGUgY2FsbGluZworICAgICAqIDxjb2RlPnJlcGxhY2VXaG9sZVRleHQ8L2NvZGU+IG9uIHRoZSA8Y29kZT5UZXh0PC9jb2RlPiBub2RlIHRoYXQKKyAgICAgKiBjb250YWlucyAiYmFyIiB3aXRoICJ5byIgaW4gYXJndW1lbnQgcmVzdWx0cyBpbiB0aGUgZm9sbG93aW5nOgorICAgICAqIDxicj5XaGVyZSB0aGUgbm9kZXMgdG8gYmUgcmVtb3ZlZCBhcmUgcmVhZC1vbmx5IGRlc2NlbmRhbnRzIG9mIGFuCisgICAgICogPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiwgdGhlIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbXVzdAorICAgICAqIGJlIHJlbW92ZWQgaW5zdGVhZCBvZiB0aGUgcmVhZC1vbmx5IG5vZGVzLiBJZiBhbnkKKyAgICAgKiA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IHRvIGJlIHJlbW92ZWQgaGFzIGRlc2NlbmRhbnRzIHRoYXQgYXJlCisgICAgICogbm90IDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4sIDxjb2RlPlRleHQ8L2NvZGU+LCBvcgorICAgICAqIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gbm9kZXMsIHRoZSA8Y29kZT5yZXBsYWNlV2hvbGVUZXh0PC9jb2RlPgorICAgICAqIG1ldGhvZCBtdXN0IGZhaWwgYmVmb3JlIHBlcmZvcm1pbmcgYW55IG1vZGlmaWNhdGlvbiBvZiB0aGUgZG9jdW1lbnQsCisgICAgICogcmFpc2luZyBhIDxjb2RlPkRPTUV4Y2VwdGlvbjwvY29kZT4gd2l0aCB0aGUgY29kZQorICAgICAqIDxjb2RlPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjwvY29kZT4uCisgICAgICogPGJyPkZvciBpbnN0YW5jZSwgaW4gdGhlIGV4YW1wbGUgYmVsb3cgY2FsbGluZworICAgICAqIDxjb2RlPnJlcGxhY2VXaG9sZVRleHQ8L2NvZGU+IG9uIHRoZSA8Y29kZT5UZXh0PC9jb2RlPiBub2RlIHRoYXQKKyAgICAgKiBjb250YWlucyAiYmFyIiBmYWlscywgYmVjYXVzZSB0aGUgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlCisgICAgICogImVudCIgY29udGFpbnMgYW4gPGNvZGU+RWxlbWVudDwvY29kZT4gbm9kZSB3aGljaCBjYW5ub3QgYmUgcmVtb3ZlZC4KKyAgICAgKiBAcGFyYW0gY29udGVudCBUaGUgY29udGVudCBvZiB0aGUgcmVwbGFjaW5nIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUuCisgICAgICogQHJldHVybiBUaGUgPGNvZGU+VGV4dDwvY29kZT4gbm9kZSBjcmVhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBjb250ZW50LgorICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCisgICAgICogICBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiBvbmUgb2YgdGhlIDxjb2RlPlRleHQ8L2NvZGU+CisgICAgICogICBub2RlcyBiZWluZyByZXBsYWNlZCBpcyByZWFkb25seS4KKyAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKKyAgICAgKi8KKyAgICBwdWJsaWMgVGV4dCByZXBsYWNlV2hvbGVUZXh0KFN0cmluZyBjb250ZW50KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL1R5cGVJbmZvLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vVHlwZUluZm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMzZmM2NjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL1R5cGVJbmZvLmphdmEKQEAgLTAsMCArMSwxODUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKKyAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcworICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKKyAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAorICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgorICoKKyAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbTsKKworLyoqCisgKiAgVGhlIDxjb2RlPlR5cGVJbmZvPC9jb2RlPiBpbnRlcmZhY2UgcmVwcmVzZW50cyBhIHR5cGUgcmVmZXJlbmNlZCBmcm9tCisgKiA8Y29kZT5FbGVtZW50PC9jb2RlPiBvciA8Y29kZT5BdHRyPC9jb2RlPiBub2Rlcywgc3BlY2lmaWVkIGluIHRoZSBzY2hlbWFzCisgKiBhc3NvY2lhdGVkIHdpdGggdGhlIGRvY3VtZW50LiBUaGUgdHlwZSBpcyBhIHBhaXIgb2YgYSBuYW1lc3BhY2UgVVJJIGFuZAorICogbmFtZSBwcm9wZXJ0aWVzLCBhbmQgZGVwZW5kcyBvbiB0aGUgZG9jdW1lbnQncyBzY2hlbWEuCisgKiA8cD4gSWYgdGhlIGRvY3VtZW50J3Mgc2NoZW1hIGlzIGFuIFhNTCBEVEQgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dLCB0aGUgdmFsdWVzCisgKiBhcmUgY29tcHV0ZWQgYXMgZm9sbG93czoKKyAqIDx1bD4KKyAqIDxsaT4gSWYgdGhpcyB0eXBlIGlzIHJlZmVyZW5jZWQgZnJvbSBhbgorICogPGNvZGU+QXR0cjwvY29kZT4gbm9kZSwgPGNvZGU+dHlwZU5hbWVzcGFjZTwvY29kZT4gaXMKKyAqIDxjb2RlPiJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sIjwvY29kZT4gYW5kIDxjb2RlPnR5cGVOYW1lPC9jb2RlPgorICogcmVwcmVzZW50cyB0aGUgPGI+W2F0dHJpYnV0ZSB0eXBlXTwvYj4gcHJvcGVydHkgaW4gdGhlIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtaW5mb3NldC0yMDA0MDIwNC8nPlhNTCBJbmZvcm1hdGlvbiBTZXQ8L2E+XQorICogLiBJZiB0aGVyZSBpcyBubyBkZWNsYXJhdGlvbiBmb3IgdGhlIGF0dHJpYnV0ZSwgPGNvZGU+dHlwZU5hbWVzcGFjZTwvY29kZT4KKyAqICBhbmQgPGNvZGU+dHlwZU5hbWU8L2NvZGU+IGFyZSA8Y29kZT5udWxsPC9jb2RlPi4KKyAqIDwvbGk+CisgKiA8bGk+IElmIHRoaXMgdHlwZSBpcworICogcmVmZXJlbmNlZCBmcm9tIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG5vZGUsIDxjb2RlPnR5cGVOYW1lc3BhY2U8L2NvZGU+CisgKiBhbmQgPGNvZGU+dHlwZU5hbWU8L2NvZGU+IGFyZSA8Y29kZT5udWxsPC9jb2RlPi4KKyAqIDwvbGk+CisgKiA8L3VsPgorICogPHA+IElmIHRoZSBkb2N1bWVudCdzIHNjaGVtYSBpcyBhbiBYTUwgU2NoZW1hIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy14bWxzY2hlbWEtMS0yMDAxMDUwMi8nPlhNTCBTY2hlbWEgUGFydCAxPC9hPl0KKyAqICwgdGhlIHZhbHVlcyBhcmUgY29tcHV0ZWQgYXMgZm9sbG93cyB1c2luZyB0aGUgcG9zdC1zY2hlbWEtdmFsaWRhdGlvbgorICogaW5mb3NldCBjb250cmlidXRpb25zIChhbHNvIGNhbGxlZCBQU1ZJIGNvbnRyaWJ1dGlvbnMpOgorICogPHVsPgorICogPGxpPiBJZiB0aGUgPGI+W3ZhbGlkaXR5XTwvYj4gcHJvcGVydHkgZXhpc3RzIEFORCBpcyA8ZW0+ImludmFsaWQiPC9lbT4gb3IgPGVtPiJub3RLbm93biI8L2VtPjogdGhlIHt0YXJnZXQgbmFtZXNwYWNlfSBhbmQge25hbWV9IHByb3BlcnRpZXMgb2YgdGhlIGRlY2xhcmVkIHR5cGUgaWYKKyAqIGF2YWlsYWJsZSwgb3RoZXJ3aXNlIDxjb2RlPm51bGw8L2NvZGU+LgorICogPHAgPjxiPk5vdGU6PC9iPiAgQXQgdGhlIHRpbWUgb2Ygd3JpdGluZywgdGhlIFhNTCBTY2hlbWEgc3BlY2lmaWNhdGlvbiBkb2VzCisgKiBub3QgcmVxdWlyZSBleHBvc2luZyB0aGUgZGVjbGFyZWQgdHlwZS4gVGh1cywgRE9NIGltcGxlbWVudGF0aW9ucyBtaWdodAorICogY2hvb3NlIG5vdCB0byBwcm92aWRlIHR5cGUgaW5mb3JtYXRpb24gaWYgdmFsaWRpdHkgaXMgbm90IHZhbGlkLgorICogPC9saT4KKyAqIDxsaT4gSWYgdGhlIDxiPlt2YWxpZGl0eV08L2I+IHByb3BlcnR5IGV4aXN0cyBhbmQgaXMgPGVtPiJ2YWxpZCI8L2VtPjoKKyAqIDxvbD4KKyAqIDxsaT4gSWYgPGI+W21lbWJlciB0eXBlIGRlZmluaXRpb25dPC9iPiBleGlzdHM6CisgKiA8b2w+CisgKiA8bGk+SWYge25hbWV9IGlzIG5vdCBhYnNlbnQsIHRoZW4gZXhwb3NlIHtuYW1lfSBhbmQge3RhcmdldAorICogbmFtZXNwYWNlfSBwcm9wZXJ0aWVzIG9mIHRoZSA8Yj5bbWVtYmVyIHR5cGUgZGVmaW5pdGlvbl08L2I+IHByb3BlcnR5OworICogPC9saT4KKyAqIDxsaT5PdGhlcndpc2UsIGV4cG9zZSB0aGUgbmFtZXNwYWNlIGFuZCBsb2NhbCBuYW1lIG9mIHRoZQorICogY29ycmVzcG9uZGluZyBhbm9ueW1vdXMgdHlwZSBuYW1lLgorICogPC9saT4KKyAqIDwvb2w+CisgKiA8L2xpPgorICogPGxpPiBJZiB0aGUgPGI+W3R5cGUgZGVmaW5pdGlvbl08L2I+IHByb3BlcnR5IGV4aXN0czoKKyAqIDxvbD4KKyAqIDxsaT5JZiB7bmFtZX0gaXMgbm90IGFic2VudCwgdGhlbiBleHBvc2Uge25hbWV9IGFuZCB7dGFyZ2V0CisgKiBuYW1lc3BhY2V9IHByb3BlcnRpZXMgb2YgdGhlIDxiPlt0eXBlIGRlZmluaXRpb25dPC9iPiBwcm9wZXJ0eTsKKyAqIDwvbGk+CisgKiA8bGk+T3RoZXJ3aXNlLCBleHBvc2UgdGhlIG5hbWVzcGFjZSBhbmQgbG9jYWwgbmFtZSBvZiB0aGUKKyAqIGNvcnJlc3BvbmRpbmcgYW5vbnltb3VzIHR5cGUgbmFtZS4KKyAqIDwvbGk+CisgKiA8L29sPgorICogPC9saT4KKyAqIDxsaT4gSWYgdGhlIDxiPlttZW1iZXIgdHlwZSBkZWZpbml0aW9uIGFub255bW91c108L2I+IGV4aXN0czoKKyAqIDxvbD4KKyAqIDxsaT5JZiBpdCBpcyBmYWxzZSwgdGhlbiBleHBvc2UgPGI+W21lbWJlciB0eXBlIGRlZmluaXRpb24gbmFtZV08L2I+IGFuZCA8Yj5bbWVtYmVyIHR5cGUgZGVmaW5pdGlvbiBuYW1lc3BhY2VdPC9iPiBwcm9wZXJ0aWVzOworICogPC9saT4KKyAqIDxsaT5PdGhlcndpc2UsIGV4cG9zZSB0aGUgbmFtZXNwYWNlIGFuZCBsb2NhbCBuYW1lIG9mIHRoZQorICogY29ycmVzcG9uZGluZyBhbm9ueW1vdXMgdHlwZSBuYW1lLgorICogPC9saT4KKyAqIDwvb2w+CisgKiA8L2xpPgorICogPGxpPiBJZiB0aGUgPGI+W3R5cGUgZGVmaW5pdGlvbiBhbm9ueW1vdXNdPC9iPiBleGlzdHM6CisgKiA8b2w+CisgKiA8bGk+SWYgaXQgaXMgZmFsc2UsIHRoZW4gZXhwb3NlIDxiPlt0eXBlIGRlZmluaXRpb24gbmFtZV08L2I+IGFuZCA8Yj5bdHlwZSBkZWZpbml0aW9uIG5hbWVzcGFjZV08L2I+IHByb3BlcnRpZXM7CisgKiA8L2xpPgorICogPGxpPk90aGVyd2lzZSwgZXhwb3NlIHRoZSBuYW1lc3BhY2UgYW5kIGxvY2FsIG5hbWUgb2YgdGhlCisgKiBjb3JyZXNwb25kaW5nIGFub255bW91cyB0eXBlIG5hbWUuCisgKiA8L2xpPgorICogPC9vbD4KKyAqIDwvbGk+CisgKiA8L29sPgorICogPC9saT4KKyAqIDwvdWw+CisgKiA8cCA+PGI+Tm90ZTo8L2I+ICBPdGhlciBzY2hlbWEgbGFuZ3VhZ2VzIGFyZSBvdXRzaWRlIHRoZSBzY29wZSBvZiB0aGUgVzNDCisgKiBhbmQgdGhlcmVmb3JlIHNob3VsZCBkZWZpbmUgaG93IHRvIHJlcHJlc2VudCB0aGVpciB0eXBlIHN5c3RlbXMgdXNpbmcKKyAqIDxjb2RlPlR5cGVJbmZvPC9jb2RlPi4KKyAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgorICogQHNpbmNlIERPTSBMZXZlbCAzCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgVHlwZUluZm8geworICAgIC8qKgorICAgICAqICBUaGUgbmFtZSBvZiBhIHR5cGUgZGVjbGFyZWQgZm9yIHRoZSBhc3NvY2lhdGVkIGVsZW1lbnQgb3IgYXR0cmlidXRlLAorICAgICAqIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHVua25vd24uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRUeXBlTmFtZSgpOworCisgICAgLyoqCisgICAgICogIFRoZSBuYW1lc3BhY2Ugb2YgdGhlIHR5cGUgZGVjbGFyZWQgZm9yIHRoZSBhc3NvY2lhdGVkIGVsZW1lbnQgb3IKKyAgICAgKiBhdHRyaWJ1dGUgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGVsZW1lbnQgZG9lcyBub3QgaGF2ZQorICAgICAqIGRlY2xhcmF0aW9uIG9yIGlmIG5vIG5hbWVzcGFjZSBpbmZvcm1hdGlvbiBpcyBhdmFpbGFibGUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRUeXBlTmFtZXNwYWNlKCk7CisKKyAgICAvLyBEZXJpdmF0aW9uTWV0aG9kcworICAgIC8qKgorICAgICAqICBJZiB0aGUgZG9jdW1lbnQncyBzY2hlbWEgaXMgYW4gWE1MIFNjaGVtYSBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvJz5YTUwgU2NoZW1hIFBhcnQgMTwvYT5dCisgICAgICogLCB0aGlzIGNvbnN0YW50IHJlcHJlc2VudHMgdGhlIGRlcml2YXRpb24gYnkgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvI2tleS10eXBlUmVzdHJpY3Rpb24nPgorICAgICAqIHJlc3RyaWN0aW9uPC9hPiBpZiBjb21wbGV4IHR5cGVzIGFyZSBpbnZvbHZlZCwgb3IgYSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy14bWxzY2hlbWEtMS0yMDAxMDUwMi8jZWxlbWVudC1yZXN0cmljdGlvbic+CisgICAgICogcmVzdHJpY3Rpb248L2E+IGlmIHNpbXBsZSB0eXBlcyBhcmUgaW52b2x2ZWQuCisgICAgICogPGJyPiAgVGhlIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24gaXMgZGVyaXZlZCBieSByZXN0cmljdGlvbiBmcm9tIHRoZQorICAgICAqIG90aGVyIHR5cGUgZGVmaW5pdGlvbiBpZiB0aGUgb3RoZXIgdHlwZSBkZWZpbml0aW9uIGlzIHRoZSBzYW1lIGFzIHRoZQorICAgICAqIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24sIG9yIGlmIHRoZSBvdGhlciB0eXBlIGRlZmluaXRpb24gY2FuIGJlCisgICAgICogcmVhY2hlZCByZWN1cnNpdmVseSBmb2xsb3dpbmcgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gcHJvcGVydHkKKyAgICAgKiBmcm9tIHRoZSByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uLCBhbmQgYWxsIHRoZSA8ZW0+ZGVyaXZhdGlvbiBtZXRob2RzPC9lbT4gaW52b2x2ZWQgYXJlIHJlc3RyaWN0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFUklWQVRJT05fUkVTVFJJQ1RJT04gICAgPSAweDAwMDAwMDAxOworICAgIC8qKgorICAgICAqICBJZiB0aGUgZG9jdW1lbnQncyBzY2hlbWEgaXMgYW4gWE1MIFNjaGVtYSBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvJz5YTUwgU2NoZW1hIFBhcnQgMTwvYT5dCisgICAgICogLCB0aGlzIGNvbnN0YW50IHJlcHJlc2VudHMgdGhlIGRlcml2YXRpb24gYnkgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvI2tleS10eXBlRXh0ZW5zaW9uJz4KKyAgICAgKiBleHRlbnNpb248L2E+LgorICAgICAqIDxicj4gIFRoZSByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uIGlzIGRlcml2ZWQgYnkgZXh0ZW5zaW9uIGZyb20gdGhlCisgICAgICogb3RoZXIgdHlwZSBkZWZpbml0aW9uIGlmIHRoZSBvdGhlciB0eXBlIGRlZmluaXRpb24gY2FuIGJlIHJlYWNoZWQKKyAgICAgKiByZWN1cnNpdmVseSBmb2xsb3dpbmcgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gcHJvcGVydHkgZnJvbSB0aGUKKyAgICAgKiByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uLCBhbmQgYXQgbGVhc3Qgb25lIG9mIHRoZSA8ZW0+ZGVyaXZhdGlvbiBtZXRob2RzPC9lbT4gaW52b2x2ZWQgaXMgYW4gZXh0ZW5zaW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFUklWQVRJT05fRVhURU5TSU9OICAgICAgPSAweDAwMDAwMDAyOworICAgIC8qKgorICAgICAqICBJZiB0aGUgZG9jdW1lbnQncyBzY2hlbWEgaXMgYW4gWE1MIFNjaGVtYSBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvJz5YTUwgU2NoZW1hIFBhcnQgMTwvYT5dCisgICAgICogLCB0aGlzIGNvbnN0YW50IHJlcHJlc2VudHMgdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvUkVDLXhtbHNjaGVtYS0xLTIwMDEwNTAyLyNlbGVtZW50LXVuaW9uJz4KKyAgICAgKiB1bmlvbjwvYT4gaWYgc2ltcGxlIHR5cGVzIGFyZSBpbnZvbHZlZC4KKyAgICAgKiA8YnI+IFRoZSByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uIGlzIGRlcml2ZWQgYnkgdW5pb24gZnJvbSB0aGUgb3RoZXIKKyAgICAgKiB0eXBlIGRlZmluaXRpb24gaWYgdGhlcmUgZXhpc3RzIHR3byB0eXBlIGRlZmluaXRpb25zIFQxIGFuZCBUMiBzdWNoCisgICAgICogYXMgdGhlIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24gaXMgZGVyaXZlZCBmcm9tIFQxIGJ5CisgICAgICogPGNvZGU+REVSSVZBVElPTl9SRVNUUklDVElPTjwvY29kZT4gb3IKKyAgICAgKiA8Y29kZT5ERVJJVkFUSU9OX0VYVEVOU0lPTjwvY29kZT4sIFQyIGlzIGRlcml2ZWQgZnJvbSB0aGUgb3RoZXIgdHlwZQorICAgICAqIGRlZmluaXRpb24gYnkgPGNvZGU+REVSSVZBVElPTl9SRVNUUklDVElPTjwvY29kZT4sIFQxIGhhcyB7dmFyaWV0eX0gPGVtPnVuaW9uPC9lbT4sIGFuZCBvbmUgb2YgdGhlIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gaXMgVDIuIE5vdGUgdGhhdCBUMSBjb3VsZCBiZQorICAgICAqIHRoZSBzYW1lIGFzIHRoZSByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uLCBhbmQgVDIgY291bGQgYmUgdGhlIHNhbWUKKyAgICAgKiBhcyB0aGUgb3RoZXIgdHlwZSBkZWZpbml0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFUklWQVRJT05fVU5JT04gICAgICAgICAgPSAweDAwMDAwMDA0OworICAgIC8qKgorICAgICAqICBJZiB0aGUgZG9jdW1lbnQncyBzY2hlbWEgaXMgYW4gWE1MIFNjaGVtYSBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvJz5YTUwgU2NoZW1hIFBhcnQgMTwvYT5dCisgICAgICogLCB0aGlzIGNvbnN0YW50IHJlcHJlc2VudHMgdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvUkVDLXhtbHNjaGVtYS0xLTIwMDEwNTAyLyNlbGVtZW50LWxpc3QnPmxpc3Q8L2E+LgorICAgICAqIDxicj4gVGhlIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24gaXMgZGVyaXZlZCBieSBsaXN0IGZyb20gdGhlIG90aGVyCisgICAgICogdHlwZSBkZWZpbml0aW9uIGlmIHRoZXJlIGV4aXN0cyB0d28gdHlwZSBkZWZpbml0aW9ucyBUMSBhbmQgVDIgc3VjaAorICAgICAqIGFzIHRoZSByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uIGlzIGRlcml2ZWQgZnJvbSBUMSBieQorICAgICAqIDxjb2RlPkRFUklWQVRJT05fUkVTVFJJQ1RJT048L2NvZGU+IG9yCisgICAgICogPGNvZGU+REVSSVZBVElPTl9FWFRFTlNJT048L2NvZGU+LCBUMiBpcyBkZXJpdmVkIGZyb20gdGhlIG90aGVyIHR5cGUKKyAgICAgKiBkZWZpbml0aW9uIGJ5IDxjb2RlPkRFUklWQVRJT05fUkVTVFJJQ1RJT048L2NvZGU+LCBUMSBoYXMge3ZhcmlldHl9IDxlbT5saXN0PC9lbT4sIGFuZCBUMiBpcyB0aGUge2l0ZW0gdHlwZSBkZWZpbml0aW9ufS4gTm90ZSB0aGF0IFQxIGNvdWxkIGJlIHRoZSBzYW1lIGFzCisgICAgICogdGhlIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24sIGFuZCBUMiBjb3VsZCBiZSB0aGUgc2FtZSBhcyB0aGUgb3RoZXIKKyAgICAgKiB0eXBlIGRlZmluaXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVSSVZBVElPTl9MSVNUICAgICAgICAgICA9IDB4MDAwMDAwMDg7CisKKyAgICAvKioKKyAgICAgKiAgVGhpcyBtZXRob2QgcmV0dXJucyBpZiB0aGVyZSBpcyBhIGRlcml2YXRpb24gYmV0d2VlbiB0aGUgcmVmZXJlbmNlCisgICAgICogdHlwZSBkZWZpbml0aW9uLCBpLmUuIHRoZSA8Y29kZT5UeXBlSW5mbzwvY29kZT4gb24gd2hpY2ggdGhlIG1ldGhvZAorICAgICAqIGlzIGJlaW5nIGNhbGxlZCwgYW5kIHRoZSBvdGhlciB0eXBlIGRlZmluaXRpb24sIGkuZS4gdGhlIG9uZSBwYXNzZWQKKyAgICAgKiBhcyBwYXJhbWV0ZXJzLgorICAgICAqIEBwYXJhbSB0eXBlTmFtZXNwYWNlQXJnICB0aGUgbmFtZXNwYWNlIG9mIHRoZSBvdGhlciB0eXBlIGRlZmluaXRpb24uCisgICAgICogQHBhcmFtIHR5cGVOYW1lQXJnICB0aGUgbmFtZSBvZiB0aGUgb3RoZXIgdHlwZSBkZWZpbml0aW9uLgorICAgICAqIEBwYXJhbSBkZXJpdmF0aW9uTWV0aG9kICB0aGUgdHlwZSBvZiBkZXJpdmF0aW9uIGFuZCBjb25kaXRpb25zIGFwcGxpZWQKKyAgICAgKiAgIGJldHdlZW4gdHdvIHR5cGVzLCBhcyBkZXNjcmliZWQgaW4gdGhlIGxpc3Qgb2YgY29uc3RhbnRzIHByb3ZpZGVkCisgICAgICogICBpbiB0aGlzIGludGVyZmFjZS4KKyAgICAgKiBAcmV0dXJuICBJZiB0aGUgZG9jdW1lbnQncyBzY2hlbWEgaXMgYSBEVEQgb3Igbm8gc2NoZW1hIGlzIGFzc29jaWF0ZWQKKyAgICAgKiAgIHdpdGggdGhlIGRvY3VtZW50LCB0aGlzIG1ldGhvZCB3aWxsIGFsd2F5cyByZXR1cm4gPGNvZGU+ZmFsc2U8L2NvZGU+CisgICAgICogICAuICBJZiB0aGUgZG9jdW1lbnQncyBzY2hlbWEgaXMgYW4gWE1MIFNjaGVtYSwgdGhlIG1ldGhvZCB3aWxsCisgICAgICogICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgcmVmZXJlbmNlIHR5cGUgZGVmaW5pdGlvbiBpcyBkZXJpdmVkIGZyb20KKyAgICAgKiAgIHRoZSBvdGhlciB0eXBlIGRlZmluaXRpb24gYWNjb3JkaW5nIHRvIHRoZSBkZXJpdmF0aW9uIHBhcmFtZXRlci4gSWYKKyAgICAgKiAgIHRoZSB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyIGlzIDxjb2RlPjA8L2NvZGU+IChubyBiaXQgaXMgc2V0IHRvCisgICAgICogICA8Y29kZT4xPC9jb2RlPiBmb3IgdGhlIDxjb2RlPmRlcml2YXRpb25NZXRob2Q8L2NvZGU+IHBhcmFtZXRlciksCisgICAgICogICB0aGUgbWV0aG9kIHdpbGwgcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBvdGhlciB0eXBlCisgICAgICogICBkZWZpbml0aW9uIGNhbiBiZSByZWFjaGVkIGJ5IHJlY3Vyc2luZyBhbnkgY29tYmluYXRpb24gb2Yge2Jhc2UKKyAgICAgKiAgIHR5cGUgZGVmaW5pdGlvbn0sIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0sIG9yIHttZW1iZXIgdHlwZQorICAgICAqICAgZGVmaW5pdGlvbnN9IGZyb20gdGhlIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNEZXJpdmVkRnJvbShTdHJpbmcgdHlwZU5hbWVzcGFjZUFyZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB0eXBlTmFtZUFyZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkZXJpdmF0aW9uTWV0aG9kKTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL1VzZXJEYXRhSGFuZGxlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL1VzZXJEYXRhSGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNmNmVlNTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vVXNlckRhdGFIYW5kbGVyLmphdmEKQEAgLTAsMCArMSw3MiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICoKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgorICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCisgKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAorICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCisgKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisgKgorICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tOworCisvKioKKyAqIFdoZW4gYXNzb2NpYXRpbmcgYW4gb2JqZWN0IHRvIGEga2V5IG9uIGEgbm9kZSB1c2luZworICogPGNvZGU+Tm9kZS5zZXRVc2VyRGF0YSgpPC9jb2RlPiB0aGUgYXBwbGljYXRpb24gY2FuIHByb3ZpZGUgYSBoYW5kbGVyCisgKiB0aGF0IGdldHMgY2FsbGVkIHdoZW4gdGhlIG5vZGUgdGhlIG9iamVjdCBpcyBhc3NvY2lhdGVkIHRvIGlzIGJlaW5nCisgKiBjbG9uZWQsIGltcG9ydGVkLCBvciByZW5hbWVkLiBUaGlzIGNhbiBiZSB1c2VkIGJ5IHRoZSBhcHBsaWNhdGlvbiB0bworICogaW1wbGVtZW50IHZhcmlvdXMgYmVoYXZpb3JzIHJlZ2FyZGluZyB0aGUgZGF0YSBpdCBhc3NvY2lhdGVzIHRvIHRoZSBET00KKyAqIG5vZGVzLiBUaGlzIGludGVyZmFjZSBkZWZpbmVzIHRoYXQgaGFuZGxlci4KKyAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgorICogQHNpbmNlIERPTSBMZXZlbCAzCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgVXNlckRhdGFIYW5kbGVyIHsKKyAgICAvLyBPcGVyYXRpb25UeXBlCisgICAgLyoqCisgICAgICogVGhlIG5vZGUgaXMgY2xvbmVkLCB1c2luZyA8Y29kZT5Ob2RlLmNsb25lTm9kZSgpPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PREVfQ0xPTkVEICAgICAgICAgICAgICAgPSAxOworICAgIC8qKgorICAgICAqIFRoZSBub2RlIGlzIGltcG9ydGVkLCB1c2luZyA8Y29kZT5Eb2N1bWVudC5pbXBvcnROb2RlKCk8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTk9ERV9JTVBPUlRFRCAgICAgICAgICAgICA9IDI7CisgICAgLyoqCisgICAgICogVGhlIG5vZGUgaXMgZGVsZXRlZC4KKyAgICAgKiA8cCA+PGI+Tm90ZTo8L2I+IFRoaXMgbWF5IG5vdCBiZSBzdXBwb3J0ZWQgb3IgbWF5IG5vdCBiZSByZWxpYWJsZSBpbgorICAgICAqIGNlcnRhaW4gZW52aXJvbm1lbnRzLCBzdWNoIGFzIEphdmEsIHdoZXJlIHRoZSBpbXBsZW1lbnRhdGlvbiBoYXMgbm8KKyAgICAgKiByZWFsIGNvbnRyb2wgb3ZlciB3aGVuIG9iamVjdHMgYXJlIGFjdHVhbGx5IGRlbGV0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBOT0RFX0RFTEVURUQgICAgICAgICAgICAgID0gMzsKKyAgICAvKioKKyAgICAgKiBUaGUgbm9kZSBpcyByZW5hbWVkLCB1c2luZyA8Y29kZT5Eb2N1bWVudC5yZW5hbWVOb2RlKCk8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTk9ERV9SRU5BTUVEICAgICAgICAgICAgICA9IDQ7CisgICAgLyoqCisgICAgICogVGhlIG5vZGUgaXMgYWRvcHRlZCwgdXNpbmcgPGNvZGU+RG9jdW1lbnQuYWRvcHROb2RlKCk8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTk9ERV9BRE9QVEVEICAgICAgICAgICAgICA9IDU7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbmV2ZXIgdGhlIG5vZGUgZm9yIHdoaWNoIHRoaXMgaGFuZGxlciBpcworICAgICAqIHJlZ2lzdGVyZWQgaXMgaW1wb3J0ZWQgb3IgY2xvbmVkLgorICAgICAqIDxicj4gRE9NIGFwcGxpY2F0aW9ucyBtdXN0IG5vdCByYWlzZSBleGNlcHRpb25zIGluIGEKKyAgICAgKiA8Y29kZT5Vc2VyRGF0YUhhbmRsZXI8L2NvZGU+LiBUaGUgZWZmZWN0IG9mIHRocm93aW5nIGV4Y2VwdGlvbnMgZnJvbQorICAgICAqIHRoZSBoYW5kbGVyIGlzIERPTSBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuCisgICAgICogQHBhcmFtIG9wZXJhdGlvbiBTcGVjaWZpZXMgdGhlIHR5cGUgb2Ygb3BlcmF0aW9uIHRoYXQgaXMgYmVpbmcKKyAgICAgKiAgIHBlcmZvcm1lZCBvbiB0aGUgbm9kZS4KKyAgICAgKiBAcGFyYW0ga2V5IFNwZWNpZmllcyB0aGUga2V5IGZvciB3aGljaCB0aGlzIGhhbmRsZXIgaXMgYmVpbmcgY2FsbGVkLgorICAgICAqIEBwYXJhbSBkYXRhIFNwZWNpZmllcyB0aGUgZGF0YSBmb3Igd2hpY2ggdGhpcyBoYW5kbGVyIGlzIGJlaW5nIGNhbGxlZC4KKyAgICAgKiBAcGFyYW0gc3JjIFNwZWNpZmllcyB0aGUgbm9kZSBiZWluZyBjbG9uZWQsIGFkb3B0ZWQsIGltcG9ydGVkLCBvcgorICAgICAqICAgcmVuYW1lZC4gVGhpcyBpcyA8Y29kZT5udWxsPC9jb2RlPiB3aGVuIHRoZSBub2RlIGlzIGJlaW5nIGRlbGV0ZWQuCisgICAgICogQHBhcmFtIGRzdCBTcGVjaWZpZXMgdGhlIG5vZGUgbmV3bHkgY3JlYXRlZCBpZiBhbnksIG9yCisgICAgICogICA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBoYW5kbGUoc2hvcnQgb3BlcmF0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcga2V5LAorICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgTm9kZSBzcmMsCisgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgZHN0KTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL2xzL0RPTUltcGxlbWVudGF0aW9uTFMuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9scy9ET01JbXBsZW1lbnRhdGlvbkxTLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGQxYjA5NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9scy9ET01JbXBsZW1lbnRhdGlvbkxTLmphdmEKQEAgLTAsMCArMSwxMjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKKyAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcworICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKKyAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAorICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgorICoKKyAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbS5sczsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKKworLyoqCisgKiAgPGNvZGU+RE9NSW1wbGVtZW50YXRpb25MUzwvY29kZT4gY29udGFpbnMgdGhlIGZhY3RvcnkgbWV0aG9kcyBmb3IgY3JlYXRpbmcKKyAqIExvYWQgYW5kIFNhdmUgb2JqZWN0cy4KKyAqIDxwPiBUaGUgZXhwZWN0YXRpb24gaXMgdGhhdCBhbiBpbnN0YW5jZSBvZiB0aGUKKyAqIDxjb2RlPkRPTUltcGxlbWVudGF0aW9uTFM8L2NvZGU+IGludGVyZmFjZSBjYW4gYmUgb2J0YWluZWQgYnkgdXNpbmcKKyAqIGJpbmRpbmctc3BlY2lmaWMgY2FzdGluZyBtZXRob2RzIG9uIGFuIGluc3RhbmNlIG9mIHRoZQorICogPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+IGludGVyZmFjZSBvciwgaWYgdGhlIDxjb2RlPkRvY3VtZW50PC9jb2RlPgorICogc3VwcG9ydHMgdGhlIGZlYXR1cmUgPGNvZGU+IkNvcmUiPC9jb2RlPiB2ZXJzaW9uIDxjb2RlPiIzLjAiPC9jb2RlPgorICogZGVmaW5lZCBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RE9NIExldmVsIDMgQ29yZTwvYT5dCisgKiAsIGJ5IHVzaW5nIHRoZSBtZXRob2QgPGNvZGU+RE9NSW1wbGVtZW50YXRpb24uZ2V0RmVhdHVyZTwvY29kZT4gd2l0aAorICogcGFyYW1ldGVyIHZhbHVlcyA8Y29kZT4iTFMiPC9jb2RlPiAob3IgPGNvZGU+IkxTLUFzeW5jIjwvY29kZT4pIGFuZAorICogPGNvZGU+IjMuMCI8L2NvZGU+IChyZXNwZWN0aXZlbHkpLgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUxTLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBMb2FkCithbmQgU2F2ZSBTcGVjaWZpY2F0aW9uPC9hPi4KKyAqLworcHVibGljIGludGVyZmFjZSBET01JbXBsZW1lbnRhdGlvbkxTIHsKKyAgICAvLyBET01JbXBsZW1lbnRhdGlvbkxTTW9kZQorICAgIC8qKgorICAgICAqIENyZWF0ZSBhIHN5bmNocm9ub3VzIDxjb2RlPkxTUGFyc2VyPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE1PREVfU1lOQ0hST05PVVMgICAgICAgICAgPSAxOworICAgIC8qKgorICAgICAqIENyZWF0ZSBhbiBhc3luY2hyb25vdXMgPGNvZGU+TFNQYXJzZXI8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTU9ERV9BU1lOQ0hST05PVVMgICAgICAgICA9IDI7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+TFNQYXJzZXI8L2NvZGU+LiBUaGUgbmV3bHkgY29uc3RydWN0ZWQgcGFyc2VyIG1heQorICAgICAqIHRoZW4gYmUgY29uZmlndXJlZCBieSBtZWFucyBvZiBpdHMgPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4KKyAgICAgKiBvYmplY3QsIGFuZCB1c2VkIHRvIHBhcnNlIGRvY3VtZW50cyBieSBtZWFucyBvZiBpdHMgPGNvZGU+cGFyc2U8L2NvZGU+CisgICAgICogIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gbW9kZSAgVGhlIDxjb2RlPm1vZGU8L2NvZGU+IGFyZ3VtZW50IGlzIGVpdGhlcgorICAgICAqICAgPGNvZGU+TU9ERV9TWU5DSFJPTk9VUzwvY29kZT4gb3IgPGNvZGU+TU9ERV9BU1lOQ0hST05PVVM8L2NvZGU+LCBpZgorICAgICAqICAgPGNvZGU+bW9kZTwvY29kZT4gaXMgPGNvZGU+TU9ERV9TWU5DSFJPTk9VUzwvY29kZT4gdGhlbiB0aGUKKyAgICAgKiAgIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiB0aGF0IGlzIGNyZWF0ZWQgd2lsbCBvcGVyYXRlIGluIHN5bmNocm9ub3VzCisgICAgICogICBtb2RlLCBpZiBpdCdzIDxjb2RlPk1PREVfQVNZTkNIUk9OT1VTPC9jb2RlPiB0aGVuIHRoZQorICAgICAqICAgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IHRoYXQgaXMgY3JlYXRlZCB3aWxsIG9wZXJhdGUgaW4gYXN5bmNocm9ub3VzCisgICAgICogICBtb2RlLgorICAgICAqIEBwYXJhbSBzY2hlbWFUeXBlICBBbiBhYnNvbHV0ZSBVUkkgcmVwcmVzZW50aW5nIHRoZSB0eXBlIG9mIHRoZSBzY2hlbWEKKyAgICAgKiAgIGxhbmd1YWdlIHVzZWQgZHVyaW5nIHRoZSBsb2FkIG9mIGEgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IHVzaW5nIHRoZQorICAgICAqICAgbmV3bHkgY3JlYXRlZCA8Y29kZT5MU1BhcnNlcjwvY29kZT4uIE5vdGUgdGhhdCBubyBsZXhpY2FsIGNoZWNraW5nCisgICAgICogICBpcyBkb25lIG9uIHRoZSBhYnNvbHV0ZSBVUkkuIEluIG9yZGVyIHRvIGNyZWF0ZSBhCisgICAgICogICA8Y29kZT5MU1BhcnNlcjwvY29kZT4gZm9yIGFueSBraW5kIG9mIHNjaGVtYSB0eXBlcyAoaS5lLiB0aGUKKyAgICAgKiAgIExTUGFyc2VyIHdpbGwgYmUgZnJlZSB0byB1c2UgYW55IHNjaGVtYSBmb3VuZCksIHVzZSB0aGUgdmFsdWUKKyAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqIDxwID48Yj5Ob3RlOjwvYj4gICAgRm9yIFczQyBYTUwgU2NoZW1hIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy14bWxzY2hlbWEtMS0yMDAxMDUwMi8nPlhNTCBTY2hlbWEgUGFydCAxPC9hPl0KKyAgICAgKiAgICwgYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZQorICAgICAqICAgPGNvZGU+Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIjwvY29kZT4uIEZvciBYTUwgRFREIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XSwKKyAgICAgKiAgIGFwcGxpY2F0aW9ucyBtdXN0IHVzZSB0aGUgdmFsdWUKKyAgICAgKiAgIDxjb2RlPiJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sIjwvY29kZT4uIE90aGVyIFNjaGVtYSBsYW5ndWFnZXMKKyAgICAgKiAgIGFyZSBvdXRzaWRlIHRoZSBzY29wZSBvZiB0aGUgVzNDIGFuZCB0aGVyZWZvcmUgc2hvdWxkIHJlY29tbWVuZCBhbgorICAgICAqICAgYWJzb2x1dGUgVVJJIGluIG9yZGVyIHRvIHVzZSB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcmV0dXJuICBUaGUgbmV3bHkgY3JlYXRlZCA8Y29kZT5MU1BhcnNlcjwvY29kZT4gb2JqZWN0LiBUaGlzCisgICAgICogICA8Y29kZT5MU1BhcnNlcjwvY29kZT4gaXMgZWl0aGVyIHN5bmNocm9ub3VzIG9yIGFzeW5jaHJvbm91cworICAgICAqICAgZGVwZW5kaW5nIG9uIHRoZSB2YWx1ZSBvZiB0aGUgPGNvZGU+bW9kZTwvY29kZT4gYXJndW1lbnQuCisgICAgICogPHAgPjxiPk5vdGU6PC9iPiAgICBCeSBkZWZhdWx0LCB0aGUgbmV3bHkgY3JlYXRlZCA8Y29kZT5MU1BhcnNlcjwvY29kZT4KKyAgICAgKiAgIGRvZXMgbm90IGNvbnRhaW4gYSA8Y29kZT5ET01FcnJvckhhbmRsZXI8L2NvZGU+LCBpLmUuIHRoZSB2YWx1ZSBvZgorICAgICAqICAgdGhlICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItZXJyb3ItaGFuZGxlcic+CisgICAgICogICBlcnJvci1oYW5kbGVyPC9hPiIgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXIgaXMgPGNvZGU+bnVsbDwvY29kZT4uIEhvd2V2ZXIsIGltcGxlbWVudGF0aW9ucworICAgICAqICAgbWF5IHByb3ZpZGUgYSBkZWZhdWx0IGVycm9yIGhhbmRsZXIgYXQgY3JlYXRpb24gdGltZS4gSW4gdGhhdCBjYXNlLAorICAgICAqICAgdGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIDxjb2RlPiJlcnJvci1oYW5kbGVyIjwvY29kZT4gY29uZmlndXJhdGlvbgorICAgICAqICAgcGFyYW1ldGVyIG9uIHRoZSBuZXcgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IG9iamVjdCBjb250YWlucyBhCisgICAgICogICByZWZlcmVuY2UgdG8gdGhlIGRlZmF1bHQgZXJyb3IgaGFuZGxlci4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgIE5PVF9TVVBQT1JURURfRVJSOiBSYWlzZWQgaWYgdGhlIHJlcXVlc3RlZCBtb2RlIG9yIHNjaGVtYSB0eXBlIGlzCisgICAgICogICBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyBMU1BhcnNlciBjcmVhdGVMU1BhcnNlcihzaG9ydCBtb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc2NoZW1hVHlwZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqICBDcmVhdGUgYSBuZXcgPGNvZGU+TFNTZXJpYWxpemVyPC9jb2RlPiBvYmplY3QuCisgICAgICogQHJldHVybiBUaGUgbmV3bHkgY3JlYXRlZCA8Y29kZT5MU1NlcmlhbGl6ZXI8L2NvZGU+IG9iamVjdC4KKyAgICAgKiA8cCA+PGI+Tm90ZTo8L2I+ICAgIEJ5IGRlZmF1bHQsIHRoZSBuZXdseSBjcmVhdGVkCisgICAgICogICA8Y29kZT5MU1NlcmlhbGl6ZXI8L2NvZGU+IGhhcyBubyA8Y29kZT5ET01FcnJvckhhbmRsZXI8L2NvZGU+LCBpLmUuCisgICAgICogICB0aGUgdmFsdWUgb2YgdGhlIDxjb2RlPiJlcnJvci1oYW5kbGVyIjwvY29kZT4gY29uZmlndXJhdGlvbgorICAgICAqICAgcGFyYW1ldGVyIGlzIDxjb2RlPm51bGw8L2NvZGU+LiBIb3dldmVyLCBpbXBsZW1lbnRhdGlvbnMgbWF5CisgICAgICogICBwcm92aWRlIGEgZGVmYXVsdCBlcnJvciBoYW5kbGVyIGF0IGNyZWF0aW9uIHRpbWUuIEluIHRoYXQgY2FzZSwgdGhlCisgICAgICogICBpbml0aWFsIHZhbHVlIG9mIHRoZSA8Y29kZT4iZXJyb3ItaGFuZGxlciI8L2NvZGU+IGNvbmZpZ3VyYXRpb24KKyAgICAgKiAgIHBhcmFtZXRlciBvbiB0aGUgbmV3IDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gb2JqZWN0IGNvbnRhaW5zIGEKKyAgICAgKiAgIHJlZmVyZW5jZSB0byB0aGUgZGVmYXVsdCBlcnJvciBoYW5kbGVyLgorICAgICAqLworICAgIHB1YmxpYyBMU1NlcmlhbGl6ZXIgY3JlYXRlTFNTZXJpYWxpemVyKCk7CisKKyAgICAvKioKKyAgICAgKiAgQ3JlYXRlIGEgbmV3IGVtcHR5IGlucHV0IHNvdXJjZSBvYmplY3Qgd2hlcmUKKyAgICAgKiA8Y29kZT5MU0lucHV0LmNoYXJhY3RlclN0cmVhbTwvY29kZT4sIDxjb2RlPkxTSW5wdXQuYnl0ZVN0cmVhbTwvY29kZT4KKyAgICAgKiAsIDxjb2RlPkxTSW5wdXQuc3RyaW5nRGF0YTwvY29kZT4gPGNvZGU+TFNJbnB1dC5zeXN0ZW1JZDwvY29kZT4sCisgICAgICogPGNvZGU+TFNJbnB1dC5wdWJsaWNJZDwvY29kZT4sIDxjb2RlPkxTSW5wdXQuYmFzZVVSSTwvY29kZT4sIGFuZAorICAgICAqIDxjb2RlPkxTSW5wdXQuZW5jb2Rpbmc8L2NvZGU+IGFyZSBudWxsLCBhbmQKKyAgICAgKiA8Y29kZT5MU0lucHV0LmNlcnRpZmllZFRleHQ8L2NvZGU+IGlzIGZhbHNlLgorICAgICAqIEByZXR1cm4gIFRoZSBuZXdseSBjcmVhdGVkIGlucHV0IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTFNJbnB1dCBjcmVhdGVMU0lucHV0KCk7CisKKyAgICAvKioKKyAgICAgKiAgQ3JlYXRlIGEgbmV3IGVtcHR5IG91dHB1dCBkZXN0aW5hdGlvbiBvYmplY3Qgd2hlcmUKKyAgICAgKiA8Y29kZT5MU091dHB1dC5jaGFyYWN0ZXJTdHJlYW08L2NvZGU+LAorICAgICAqIDxjb2RlPkxTT3V0cHV0LmJ5dGVTdHJlYW08L2NvZGU+LCA8Y29kZT5MU091dHB1dC5zeXN0ZW1JZDwvY29kZT4sCisgICAgICogPGNvZGU+TFNPdXRwdXQuZW5jb2Rpbmc8L2NvZGU+IGFyZSBudWxsLgorICAgICAqIEByZXR1cm4gIFRoZSBuZXdseSBjcmVhdGVkIG91dHB1dCBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIExTT3V0cHV0IGNyZWF0ZUxTT3V0cHV0KCk7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9scy9MU0V4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL2xzL0xTRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjc3YWQzOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9scy9MU0V4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKKyAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcworICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKKyAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAorICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgorICoKKyAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbS5sczsKKworLyoqCisgKiAgUGFyc2VyIG9yIHdyaXRlIG9wZXJhdGlvbnMgbWF5IHRocm93IGFuIDxjb2RlPkxTRXhjZXB0aW9uPC9jb2RlPiBpZiB0aGUKKyAqIHByb2Nlc3NpbmcgaXMgc3RvcHBlZC4gVGhlIHByb2Nlc3NpbmcgY2FuIGJlIHN0b3BwZWQgZHVlIHRvIGEKKyAqIDxjb2RlPkRPTUVycm9yPC9jb2RlPiB3aXRoIGEgc2V2ZXJpdHkgb2YKKyAqIDxjb2RlPkRPTUVycm9yLlNFVkVSSVRZX0ZBVEFMX0VSUk9SPC9jb2RlPiBvciBhIG5vbiByZWNvdmVyZWQKKyAqIDxjb2RlPkRPTUVycm9yLlNFVkVSSVRZX0VSUk9SPC9jb2RlPiwgb3IgaWYKKyAqIDxjb2RlPkRPTUVycm9ySGFuZGxlci5oYW5kbGVFcnJvcigpPC9jb2RlPiByZXR1cm5lZCA8Y29kZT5mYWxzZTwvY29kZT4uCisgKiA8cCA+PGI+Tm90ZTo8L2I+ICBBcyBzdWdnZXN0ZWQgaW4gdGhlIGRlZmluaXRpb24gb2YgdGhlIGNvbnN0YW50cyBpbiB0aGUKKyAqIDxjb2RlPkRPTUVycm9yPC9jb2RlPiBpbnRlcmZhY2UsIGEgRE9NIGltcGxlbWVudGF0aW9uIG1heSBjaG9vc2UgdG8KKyAqIGNvbnRpbnVlIGFmdGVyIGEgZmF0YWwgZXJyb3IsIGJ1dCB0aGUgcmVzdWx0aW5nIERPTSB0cmVlIGlzIHRoZW4KKyAqIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KKyAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1MUy0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgTG9hZAorYW5kIFNhdmUgU3BlY2lmaWNhdGlvbjwvYT4uCisgKi8KK3B1YmxpYyBjbGFzcyBMU0V4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geworICAgIHB1YmxpYyBMU0V4Y2VwdGlvbihzaG9ydCBjb2RlLCBTdHJpbmcgbWVzc2FnZSkgeworICAgICAgIHN1cGVyKG1lc3NhZ2UpOworICAgICAgIHRoaXMuY29kZSA9IGNvZGU7CisgICAgfQorICAgIHB1YmxpYyBzaG9ydCAgIGNvZGU7CisgICAgLy8gTFNFeGNlcHRpb25Db2RlCisgICAgLyoqCisgICAgICogIElmIGFuIGF0dGVtcHQgd2FzIG1hZGUgdG8gbG9hZCBhIGRvY3VtZW50LCBvciBhbiBYTUwgRnJhZ21lbnQsIHVzaW5nCisgICAgICogPGNvZGU+TFNQYXJzZXI8L2NvZGU+IGFuZCB0aGUgcHJvY2Vzc2luZyBoYXMgYmVlbiBzdG9wcGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUEFSU0VfRVJSICAgICAgICAgICAgICAgICA9IDgxOworICAgIC8qKgorICAgICAqICBJZiBhbiBhdHRlbXB0IHdhcyBtYWRlIHRvIHNlcmlhbGl6ZSBhIDxjb2RlPk5vZGU8L2NvZGU+IHVzaW5nCisgICAgICogPGNvZGU+TFNTZXJpYWxpemVyPC9jb2RlPiBhbmQgdGhlIHByb2Nlc3NpbmcgaGFzIGJlZW4gc3RvcHBlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNFUklBTElaRV9FUlIgICAgICAgICAgICAgPSA4MjsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL2xzL0xTSW5wdXQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9scy9MU0lucHV0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmJhMTc5MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9scy9MU0lucHV0LmphdmEKQEAgLTAsMCArMSwyMTggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKKyAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcworICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKKyAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAorICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgorICoKKyAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbS5sczsKKworLyoqCisgKiAgVGhpcyBpbnRlcmZhY2UgcmVwcmVzZW50cyBhbiBpbnB1dCBzb3VyY2UgZm9yIGRhdGEuCisgKiA8cD4gVGhpcyBpbnRlcmZhY2UgYWxsb3dzIGFuIGFwcGxpY2F0aW9uIHRvIGVuY2Fwc3VsYXRlIGluZm9ybWF0aW9uIGFib3V0CisgKiBhbiBpbnB1dCBzb3VyY2UgaW4gYSBzaW5nbGUgb2JqZWN0LCB3aGljaCBtYXkgaW5jbHVkZSBhIHB1YmxpYworICogaWRlbnRpZmllciwgYSBzeXN0ZW0gaWRlbnRpZmllciwgYSBieXRlIHN0cmVhbSAocG9zc2libHkgd2l0aCBhIHNwZWNpZmllZAorICogZW5jb2RpbmcpLCBhIGJhc2UgVVJJLCBhbmQvb3IgYSBjaGFyYWN0ZXIgc3RyZWFtLgorICogPHA+IFRoZSBleGFjdCBkZWZpbml0aW9ucyBvZiBhIGJ5dGUgc3RyZWFtIGFuZCBhIGNoYXJhY3RlciBzdHJlYW0gYXJlCisgKiBiaW5kaW5nIGRlcGVuZGVudC4KKyAqIDxwPiBUaGUgYXBwbGljYXRpb24gaXMgZXhwZWN0ZWQgdG8gcHJvdmlkZSBvYmplY3RzIHRoYXQgaW1wbGVtZW50IHRoaXMKKyAqIGludGVyZmFjZSB3aGVuZXZlciBzdWNoIG9iamVjdHMgYXJlIG5lZWRlZC4gVGhlIGFwcGxpY2F0aW9uIGNhbiBlaXRoZXIKKyAqIHByb3ZpZGUgaXRzIG93biBvYmplY3RzIHRoYXQgaW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlLCBvciBpdCBjYW4gdXNlIHRoZQorICogZ2VuZXJpYyBmYWN0b3J5IG1ldGhvZCA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbkxTLmNyZWF0ZUxTSW5wdXQoKTwvY29kZT4KKyAqIHRvIGNyZWF0ZSBvYmplY3RzIHRoYXQgaW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlLgorICogPHA+IFRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gd2lsbCB1c2UgdGhlIDxjb2RlPkxTSW5wdXQ8L2NvZGU+IG9iamVjdCB0bworICogZGV0ZXJtaW5lIGhvdyB0byByZWFkIGRhdGEuIFRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gd2lsbCBsb29rIGF0IHRoZQorICogZGlmZmVyZW50IGlucHV0cyBzcGVjaWZpZWQgaW4gdGhlIDxjb2RlPkxTSW5wdXQ8L2NvZGU+IGluIHRoZSBmb2xsb3dpbmcKKyAqIG9yZGVyIHRvIGtub3cgd2hpY2ggb25lIHRvIHJlYWQgZnJvbSwgdGhlIGZpcnN0IG9uZSB0aGF0IGlzIG5vdCBudWxsIGFuZAorICogbm90IGFuIGVtcHR5IHN0cmluZyB3aWxsIGJlIHVzZWQ6CisgKiA8b2w+CisgKiA8bGk+IDxjb2RlPkxTSW5wdXQuY2hhcmFjdGVyU3RyZWFtPC9jb2RlPgorICogPC9saT4KKyAqIDxsaT4KKyAqIDxjb2RlPkxTSW5wdXQuYnl0ZVN0cmVhbTwvY29kZT4KKyAqIDwvbGk+CisgKiA8bGk+IDxjb2RlPkxTSW5wdXQuc3RyaW5nRGF0YTwvY29kZT4KKyAqIDwvbGk+CisgKiA8bGk+CisgKiA8Y29kZT5MU0lucHV0LnN5c3RlbUlkPC9jb2RlPgorICogPC9saT4KKyAqIDxsaT4gPGNvZGU+TFNJbnB1dC5wdWJsaWNJZDwvY29kZT4KKyAqIDwvbGk+CisgKiA8L29sPgorICogPHA+IElmIGFsbCBpbnB1dHMgYXJlIG51bGwsIHRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gd2lsbCByZXBvcnQgYQorICogPGNvZGU+RE9NRXJyb3I8L2NvZGU+IHdpdGggaXRzIDxjb2RlPkRPTUVycm9yLnR5cGU8L2NvZGU+IHNldCB0bworICogPGNvZGU+Im5vLWlucHV0LXNwZWNpZmllZCI8L2NvZGU+IGFuZCBpdHMgPGNvZGU+RE9NRXJyb3Iuc2V2ZXJpdHk8L2NvZGU+CisgKiBzZXQgdG8gPGNvZGU+RE9NRXJyb3IuU0VWRVJJVFlfRkFUQUxfRVJST1I8L2NvZGU+LgorICogPHA+IDxjb2RlPkxTSW5wdXQ8L2NvZGU+IG9iamVjdHMgYmVsb25nIHRvIHRoZSBhcHBsaWNhdGlvbi4gVGhlIERPTQorICogaW1wbGVtZW50YXRpb24gd2lsbCBuZXZlciBtb2RpZnkgdGhlbSAodGhvdWdoIGl0IG1heSBtYWtlIGNvcGllcyBhbmQKKyAqIG1vZGlmeSB0aGUgY29waWVzLCBpZiBuZWNlc3NhcnkpLgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUxTLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBMb2FkCithbmQgU2F2ZSBTcGVjaWZpY2F0aW9uPC9hPi4KKyAqLworcHVibGljIGludGVyZmFjZSBMU0lucHV0IHsKKyAgICAvKioKKyAgICAgKiAgQW4gYXR0cmlidXRlIG9mIGEgbGFuZ3VhZ2UgYW5kIGJpbmRpbmcgZGVwZW5kZW50IHR5cGUgdGhhdCByZXByZXNlbnRzCisgICAgICogYSBzdHJlYW0gb2YgMTYtYml0IHVuaXRzLiBUaGUgYXBwbGljYXRpb24gbXVzdCBlbmNvZGUgdGhlIHN0cmVhbQorICAgICAqIHVzaW5nIFVURi0xNiAoZGVmaW5lZCBpbiBbVW5pY29kZV0gYW5kIGluIFtJU08vSUVDIDEwNjQ2XSkuIEl0IGlzIG5vdCBhIHJlcXVpcmVtZW50IHRvIGhhdmUgYW4gWE1MIGRlY2xhcmF0aW9uIHdoZW4KKyAgICAgKiB1c2luZyBjaGFyYWN0ZXIgc3RyZWFtcy4gSWYgYW4gWE1MIGRlY2xhcmF0aW9uIGlzIHByZXNlbnQsIHRoZSB2YWx1ZQorICAgICAqIG9mIHRoZSBlbmNvZGluZyBhdHRyaWJ1dGUgd2lsbCBiZSBpZ25vcmVkLgorICAgICAqLworICAgIHB1YmxpYyBqYXZhLmlvLlJlYWRlciBnZXRDaGFyYWN0ZXJTdHJlYW0oKTsKKyAgICAvKioKKyAgICAgKiAgQW4gYXR0cmlidXRlIG9mIGEgbGFuZ3VhZ2UgYW5kIGJpbmRpbmcgZGVwZW5kZW50IHR5cGUgdGhhdCByZXByZXNlbnRzCisgICAgICogYSBzdHJlYW0gb2YgMTYtYml0IHVuaXRzLiBUaGUgYXBwbGljYXRpb24gbXVzdCBlbmNvZGUgdGhlIHN0cmVhbQorICAgICAqIHVzaW5nIFVURi0xNiAoZGVmaW5lZCBpbiBbVW5pY29kZV0gYW5kIGluIFtJU08vSUVDIDEwNjQ2XSkuIEl0IGlzIG5vdCBhIHJlcXVpcmVtZW50IHRvIGhhdmUgYW4gWE1MIGRlY2xhcmF0aW9uIHdoZW4KKyAgICAgKiB1c2luZyBjaGFyYWN0ZXIgc3RyZWFtcy4gSWYgYW4gWE1MIGRlY2xhcmF0aW9uIGlzIHByZXNlbnQsIHRoZSB2YWx1ZQorICAgICAqIG9mIHRoZSBlbmNvZGluZyBhdHRyaWJ1dGUgd2lsbCBiZSBpZ25vcmVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENoYXJhY3RlclN0cmVhbShqYXZhLmlvLlJlYWRlciBjaGFyYWN0ZXJTdHJlYW0pOworCisgICAgLyoqCisgICAgICogIEFuIGF0dHJpYnV0ZSBvZiBhIGxhbmd1YWdlIGFuZCBiaW5kaW5nIGRlcGVuZGVudCB0eXBlIHRoYXQgcmVwcmVzZW50cworICAgICAqIGEgc3RyZWFtIG9mIGJ5dGVzLgorICAgICAqIDxicj4gSWYgdGhlIGFwcGxpY2F0aW9uIGtub3dzIHRoZSBjaGFyYWN0ZXIgZW5jb2Rpbmcgb2YgdGhlIGJ5dGUKKyAgICAgKiBzdHJlYW0sIGl0IHNob3VsZCBzZXQgdGhlIGVuY29kaW5nIGF0dHJpYnV0ZS4gU2V0dGluZyB0aGUgZW5jb2RpbmcgaW4KKyAgICAgKiB0aGlzIHdheSB3aWxsIG92ZXJyaWRlIGFueSBlbmNvZGluZyBzcGVjaWZpZWQgaW4gYW4gWE1MIGRlY2xhcmF0aW9uCisgICAgICogaW4gdGhlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIGphdmEuaW8uSW5wdXRTdHJlYW0gZ2V0Qnl0ZVN0cmVhbSgpOworICAgIC8qKgorICAgICAqICBBbiBhdHRyaWJ1dGUgb2YgYSBsYW5ndWFnZSBhbmQgYmluZGluZyBkZXBlbmRlbnQgdHlwZSB0aGF0IHJlcHJlc2VudHMKKyAgICAgKiBhIHN0cmVhbSBvZiBieXRlcy4KKyAgICAgKiA8YnI+IElmIHRoZSBhcHBsaWNhdGlvbiBrbm93cyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIG9mIHRoZSBieXRlCisgICAgICogc3RyZWFtLCBpdCBzaG91bGQgc2V0IHRoZSBlbmNvZGluZyBhdHRyaWJ1dGUuIFNldHRpbmcgdGhlIGVuY29kaW5nIGluCisgICAgICogdGhpcyB3YXkgd2lsbCBvdmVycmlkZSBhbnkgZW5jb2Rpbmcgc3BlY2lmaWVkIGluIGFuIFhNTCBkZWNsYXJhdGlvbgorICAgICAqIGluIHRoZSBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJ5dGVTdHJlYW0oamF2YS5pby5JbnB1dFN0cmVhbSBieXRlU3RyZWFtKTsKKworICAgIC8qKgorICAgICAqICBTdHJpbmcgZGF0YSB0byBwYXJzZS4gSWYgcHJvdmlkZWQsIHRoaXMgd2lsbCBhbHdheXMgYmUgdHJlYXRlZCBhcyBhCisgICAgICogc2VxdWVuY2Ugb2YgMTYtYml0IHVuaXRzIChVVEYtMTYgZW5jb2RlZCBjaGFyYWN0ZXJzKS4gSXQgaXMgbm90IGEKKyAgICAgKiByZXF1aXJlbWVudCB0byBoYXZlIGFuIFhNTCBkZWNsYXJhdGlvbiB3aGVuIHVzaW5nCisgICAgICogPGNvZGU+c3RyaW5nRGF0YTwvY29kZT4uIElmIGFuIFhNTCBkZWNsYXJhdGlvbiBpcyBwcmVzZW50LCB0aGUgdmFsdWUKKyAgICAgKiBvZiB0aGUgZW5jb2RpbmcgYXR0cmlidXRlIHdpbGwgYmUgaWdub3JlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFN0cmluZ0RhdGEoKTsKKyAgICAvKioKKyAgICAgKiAgU3RyaW5nIGRhdGEgdG8gcGFyc2UuIElmIHByb3ZpZGVkLCB0aGlzIHdpbGwgYWx3YXlzIGJlIHRyZWF0ZWQgYXMgYQorICAgICAqIHNlcXVlbmNlIG9mIDE2LWJpdCB1bml0cyAoVVRGLTE2IGVuY29kZWQgY2hhcmFjdGVycykuIEl0IGlzIG5vdCBhCisgICAgICogcmVxdWlyZW1lbnQgdG8gaGF2ZSBhbiBYTUwgZGVjbGFyYXRpb24gd2hlbiB1c2luZworICAgICAqIDxjb2RlPnN0cmluZ0RhdGE8L2NvZGU+LiBJZiBhbiBYTUwgZGVjbGFyYXRpb24gaXMgcHJlc2VudCwgdGhlIHZhbHVlCisgICAgICogb2YgdGhlIGVuY29kaW5nIGF0dHJpYnV0ZSB3aWxsIGJlIGlnbm9yZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3RyaW5nRGF0YShTdHJpbmcgc3RyaW5nRGF0YSk7CisKKyAgICAvKioKKyAgICAgKiAgVGhlIHN5c3RlbSBpZGVudGlmaWVyLCBhIFVSSSByZWZlcmVuY2UgWzxhIGhyZWY9J2h0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Jz5JRVRGIFJGQyAyMzk2PC9hPl0sIGZvciB0aGlzCisgICAgICogaW5wdXQgc291cmNlLiBUaGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgb3B0aW9uYWwgaWYgdGhlcmUgaXMgYSBieXRlCisgICAgICogc3RyZWFtLCBhIGNoYXJhY3RlciBzdHJlYW0sIG9yIHN0cmluZyBkYXRhLiBJdCBpcyBzdGlsbCB1c2VmdWwgdG8KKyAgICAgKiBwcm92aWRlIG9uZSwgc2luY2UgdGhlIGFwcGxpY2F0aW9uIHdpbGwgdXNlIGl0IHRvIHJlc29sdmUgYW55CisgICAgICogcmVsYXRpdmUgVVJJcyBhbmQgY2FuIGluY2x1ZGUgaXQgaW4gZXJyb3IgbWVzc2FnZXMgYW5kIHdhcm5pbmdzLiAoVGhlCisgICAgICogTFNQYXJzZXIgd2lsbCBvbmx5IGF0dGVtcHQgdG8gZmV0Y2ggdGhlIHJlc291cmNlIGlkZW50aWZpZWQgYnkgdGhlCisgICAgICogVVJJIHJlZmVyZW5jZSBpZiB0aGVyZSBpcyBubyBvdGhlciBpbnB1dCBhdmFpbGFibGUgaW4gdGhlIGlucHV0CisgICAgICogc291cmNlLikKKyAgICAgKiA8YnI+IElmIHRoZSBhcHBsaWNhdGlvbiBrbm93cyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIG9mIHRoZSBvYmplY3QKKyAgICAgKiBwb2ludGVkIHRvIGJ5IHRoZSBzeXN0ZW0gaWRlbnRpZmllciwgaXQgY2FuIHNldCB0aGUgZW5jb2RpbmcgdXNpbmcKKyAgICAgKiB0aGUgPGNvZGU+ZW5jb2Rpbmc8L2NvZGU+IGF0dHJpYnV0ZS4KKyAgICAgKiA8YnI+IElmIHRoZSBzcGVjaWZpZWQgc3lzdGVtIElEIGlzIGEgcmVsYXRpdmUgVVJJIHJlZmVyZW5jZSAoc2VlCisgICAgICogc2VjdGlvbiA1IGluIFs8YSBocmVmPSdodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dCc+SUVURiBSRkMgMjM5NjwvYT5dKSwgdGhlIERPTQorICAgICAqIGltcGxlbWVudGF0aW9uIHdpbGwgYXR0ZW1wdCB0byByZXNvbHZlIHRoZSByZWxhdGl2ZSBVUkkgd2l0aCB0aGUKKyAgICAgKiA8Y29kZT5iYXNlVVJJPC9jb2RlPiBhcyB0aGUgYmFzZSwgaWYgdGhhdCBmYWlscywgdGhlIGJlaGF2aW9yIGlzCisgICAgICogaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKTsKKyAgICAvKioKKyAgICAgKiAgVGhlIHN5c3RlbSBpZGVudGlmaWVyLCBhIFVSSSByZWZlcmVuY2UgWzxhIGhyZWY9J2h0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Jz5JRVRGIFJGQyAyMzk2PC9hPl0sIGZvciB0aGlzCisgICAgICogaW5wdXQgc291cmNlLiBUaGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgb3B0aW9uYWwgaWYgdGhlcmUgaXMgYSBieXRlCisgICAgICogc3RyZWFtLCBhIGNoYXJhY3RlciBzdHJlYW0sIG9yIHN0cmluZyBkYXRhLiBJdCBpcyBzdGlsbCB1c2VmdWwgdG8KKyAgICAgKiBwcm92aWRlIG9uZSwgc2luY2UgdGhlIGFwcGxpY2F0aW9uIHdpbGwgdXNlIGl0IHRvIHJlc29sdmUgYW55CisgICAgICogcmVsYXRpdmUgVVJJcyBhbmQgY2FuIGluY2x1ZGUgaXQgaW4gZXJyb3IgbWVzc2FnZXMgYW5kIHdhcm5pbmdzLiAoVGhlCisgICAgICogTFNQYXJzZXIgd2lsbCBvbmx5IGF0dGVtcHQgdG8gZmV0Y2ggdGhlIHJlc291cmNlIGlkZW50aWZpZWQgYnkgdGhlCisgICAgICogVVJJIHJlZmVyZW5jZSBpZiB0aGVyZSBpcyBubyBvdGhlciBpbnB1dCBhdmFpbGFibGUgaW4gdGhlIGlucHV0CisgICAgICogc291cmNlLikKKyAgICAgKiA8YnI+IElmIHRoZSBhcHBsaWNhdGlvbiBrbm93cyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIG9mIHRoZSBvYmplY3QKKyAgICAgKiBwb2ludGVkIHRvIGJ5IHRoZSBzeXN0ZW0gaWRlbnRpZmllciwgaXQgY2FuIHNldCB0aGUgZW5jb2RpbmcgdXNpbmcKKyAgICAgKiB0aGUgPGNvZGU+ZW5jb2Rpbmc8L2NvZGU+IGF0dHJpYnV0ZS4KKyAgICAgKiA8YnI+IElmIHRoZSBzcGVjaWZpZWQgc3lzdGVtIElEIGlzIGEgcmVsYXRpdmUgVVJJIHJlZmVyZW5jZSAoc2VlCisgICAgICogc2VjdGlvbiA1IGluIFs8YSBocmVmPSdodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dCc+SUVURiBSRkMgMjM5NjwvYT5dKSwgdGhlIERPTQorICAgICAqIGltcGxlbWVudGF0aW9uIHdpbGwgYXR0ZW1wdCB0byByZXNvbHZlIHRoZSByZWxhdGl2ZSBVUkkgd2l0aCB0aGUKKyAgICAgKiA8Y29kZT5iYXNlVVJJPC9jb2RlPiBhcyB0aGUgYmFzZSwgaWYgdGhhdCBmYWlscywgdGhlIGJlaGF2aW9yIGlzCisgICAgICogaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCk7CisKKyAgICAvKioKKyAgICAgKiAgVGhlIHB1YmxpYyBpZGVudGlmaWVyIGZvciB0aGlzIGlucHV0IHNvdXJjZS4gVGhpcyBtYXkgYmUgbWFwcGVkIHRvIGFuCisgICAgICogaW5wdXQgc291cmNlIHVzaW5nIGFuIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudCBtZWNoYW5pc20gKHN1Y2ggYXMKKyAgICAgKiBjYXRhbG9ndWVzIG9yIG90aGVyIG1hcHBpbmdzKS4gVGhlIHB1YmxpYyBpZGVudGlmaWVyLCBpZiBzcGVjaWZpZWQsCisgICAgICogbWF5IGFsc28gYmUgcmVwb3J0ZWQgYXMgcGFydCBvZiB0aGUgbG9jYXRpb24gaW5mb3JtYXRpb24gd2hlbiBlcnJvcnMKKyAgICAgKiBhcmUgcmVwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpOworICAgIC8qKgorICAgICAqICBUaGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoaXMgaW5wdXQgc291cmNlLiBUaGlzIG1heSBiZSBtYXBwZWQgdG8gYW4KKyAgICAgKiBpbnB1dCBzb3VyY2UgdXNpbmcgYW4gaW1wbGVtZW50YXRpb24gZGVwZW5kZW50IG1lY2hhbmlzbSAoc3VjaCBhcworICAgICAqIGNhdGFsb2d1ZXMgb3Igb3RoZXIgbWFwcGluZ3MpLiBUaGUgcHVibGljIGlkZW50aWZpZXIsIGlmIHNwZWNpZmllZCwKKyAgICAgKiBtYXkgYWxzbyBiZSByZXBvcnRlZCBhcyBwYXJ0IG9mIHRoZSBsb2NhdGlvbiBpbmZvcm1hdGlvbiB3aGVuIGVycm9ycworICAgICAqIGFyZSByZXBvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQdWJsaWNJZChTdHJpbmcgcHVibGljSWQpOworCisgICAgLyoqCisgICAgICogIFRoZSBiYXNlIFVSSSB0byBiZSB1c2VkIChzZWUgc2VjdGlvbiA1LjEuNCBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjM5Ni50eHQnPklFVEYgUkZDIDIzOTY8L2E+XSkgZm9yCisgICAgICogcmVzb2x2aW5nIGEgcmVsYXRpdmUgPGNvZGU+c3lzdGVtSWQ8L2NvZGU+IHRvIGFuIGFic29sdXRlIFVSSS4KKyAgICAgKiA8YnI+IElmLCB3aGVuIHVzZWQsIHRoZSBiYXNlIFVSSSBpcyBpdHNlbGYgYSByZWxhdGl2ZSBVUkksIGFuIGVtcHR5CisgICAgICogc3RyaW5nLCBvciBudWxsLCB0aGUgYmVoYXZpb3IgaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFzZVVSSSgpOworICAgIC8qKgorICAgICAqICBUaGUgYmFzZSBVUkkgdG8gYmUgdXNlZCAoc2VlIHNlY3Rpb24gNS4xLjQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Jz5JRVRGIFJGQyAyMzk2PC9hPl0pIGZvcgorICAgICAqIHJlc29sdmluZyBhIHJlbGF0aXZlIDxjb2RlPnN5c3RlbUlkPC9jb2RlPiB0byBhbiBhYnNvbHV0ZSBVUkkuCisgICAgICogPGJyPiBJZiwgd2hlbiB1c2VkLCB0aGUgYmFzZSBVUkkgaXMgaXRzZWxmIGEgcmVsYXRpdmUgVVJJLCBhbiBlbXB0eQorICAgICAqIHN0cmluZywgb3IgbnVsbCwgdGhlIGJlaGF2aW9yIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCYXNlVVJJKFN0cmluZyBiYXNlVVJJKTsKKworICAgIC8qKgorICAgICAqICBUaGUgY2hhcmFjdGVyIGVuY29kaW5nLCBpZiBrbm93bi4gVGhlIGVuY29kaW5nIG11c3QgYmUgYSBzdHJpbmcKKyAgICAgKiBhY2NlcHRhYmxlIGZvciBhbiBYTUwgZW5jb2RpbmcgZGVjbGFyYXRpb24gKFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XSBzZWN0aW9uCisgICAgICogNC4zLjMgIkNoYXJhY3RlciBFbmNvZGluZyBpbiBFbnRpdGllcyIpLgorICAgICAqIDxicj4gVGhpcyBhdHRyaWJ1dGUgaGFzIG5vIGVmZmVjdCB3aGVuIHRoZSBhcHBsaWNhdGlvbiBwcm92aWRlcyBhCisgICAgICogY2hhcmFjdGVyIHN0cmVhbSBvciBzdHJpbmcgZGF0YS4gRm9yIG90aGVyIHNvdXJjZXMgb2YgaW5wdXQsIGFuCisgICAgICogZW5jb2Rpbmcgc3BlY2lmaWVkIGJ5IG1lYW5zIG9mIHRoaXMgYXR0cmlidXRlIHdpbGwgb3ZlcnJpZGUgYW55CisgICAgICogZW5jb2Rpbmcgc3BlY2lmaWVkIGluIHRoZSBYTUwgZGVjbGFyYXRpb24gb3IgdGhlIFRleHQgZGVjbGFyYXRpb24sIG9yCisgICAgICogYW4gZW5jb2Rpbmcgb2J0YWluZWQgZnJvbSBhIGhpZ2hlciBsZXZlbCBwcm90b2NvbCwgc3VjaCBhcyBIVFRQIFs8YSBocmVmPSdodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyNjE2LnR4dCc+SUVURiBSRkMgMjYxNjwvYT5dLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKTsKKyAgICAvKioKKyAgICAgKiAgVGhlIGNoYXJhY3RlciBlbmNvZGluZywgaWYga25vd24uIFRoZSBlbmNvZGluZyBtdXN0IGJlIGEgc3RyaW5nCisgICAgICogYWNjZXB0YWJsZSBmb3IgYW4gWE1MIGVuY29kaW5nIGRlY2xhcmF0aW9uIChbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0gc2VjdGlvbgorICAgICAqIDQuMy4zICJDaGFyYWN0ZXIgRW5jb2RpbmcgaW4gRW50aXRpZXMiKS4KKyAgICAgKiA8YnI+IFRoaXMgYXR0cmlidXRlIGhhcyBubyBlZmZlY3Qgd2hlbiB0aGUgYXBwbGljYXRpb24gcHJvdmlkZXMgYQorICAgICAqIGNoYXJhY3RlciBzdHJlYW0gb3Igc3RyaW5nIGRhdGEuIEZvciBvdGhlciBzb3VyY2VzIG9mIGlucHV0LCBhbgorICAgICAqIGVuY29kaW5nIHNwZWNpZmllZCBieSBtZWFucyBvZiB0aGlzIGF0dHJpYnV0ZSB3aWxsIG92ZXJyaWRlIGFueQorICAgICAqIGVuY29kaW5nIHNwZWNpZmllZCBpbiB0aGUgWE1MIGRlY2xhcmF0aW9uIG9yIHRoZSBUZXh0IGRlY2xhcmF0aW9uLCBvcgorICAgICAqIGFuIGVuY29kaW5nIG9idGFpbmVkIGZyb20gYSBoaWdoZXIgbGV2ZWwgcHJvdG9jb2wsIHN1Y2ggYXMgSFRUUCBbPGEgaHJlZj0naHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjYxNi50eHQnPklFVEYgUkZDIDI2MTY8L2E+XS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpOworCisgICAgLyoqCisgICAgICogIElmIHNldCB0byB0cnVlLCBhc3N1bWUgdGhhdCB0aGUgaW5wdXQgaXMgY2VydGlmaWVkIChzZWUgc2VjdGlvbiAyLjEzCisgICAgICogaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0Lyc+WE1MIDEuMTwvYT5dKSB3aGVuCisgICAgICogcGFyc2luZyBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sMTEtMjAwNDAyMDQvJz5YTUwgMS4xPC9hPl0uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0Q2VydGlmaWVkVGV4dCgpOworICAgIC8qKgorICAgICAqICBJZiBzZXQgdG8gdHJ1ZSwgYXNzdW1lIHRoYXQgdGhlIGlucHV0IGlzIGNlcnRpZmllZCAoc2VlIHNlY3Rpb24gMi4xMworICAgICAqIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwxMS0yMDA0MDIwNC8nPlhNTCAxLjE8L2E+XSkgd2hlbgorICAgICAqIHBhcnNpbmcgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0Lyc+WE1MIDEuMTwvYT5dLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENlcnRpZmllZFRleHQoYm9vbGVhbiBjZXJ0aWZpZWRUZXh0KTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL2xzL0xTT3V0cHV0LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vbHMvTFNPdXRwdXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ODliOTVhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL2xzL0xTT3V0cHV0LmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKKyAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcworICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKKyAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAorICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgorICoKKyAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbS5sczsKKworLyoqCisgKiAgVGhpcyBpbnRlcmZhY2UgcmVwcmVzZW50cyBhbiBvdXRwdXQgZGVzdGluYXRpb24gZm9yIGRhdGEuCisgKiA8cD4gVGhpcyBpbnRlcmZhY2UgYWxsb3dzIGFuIGFwcGxpY2F0aW9uIHRvIGVuY2Fwc3VsYXRlIGluZm9ybWF0aW9uIGFib3V0CisgKiBhbiBvdXRwdXQgZGVzdGluYXRpb24gaW4gYSBzaW5nbGUgb2JqZWN0LCB3aGljaCBtYXkgaW5jbHVkZSBhIFVSSSwgYSBieXRlCisgKiBzdHJlYW0gKHBvc3NpYmx5IHdpdGggYSBzcGVjaWZpZWQgZW5jb2RpbmcpLCBhIGJhc2UgVVJJLCBhbmQvb3IgYQorICogY2hhcmFjdGVyIHN0cmVhbS4KKyAqIDxwPiBUaGUgZXhhY3QgZGVmaW5pdGlvbnMgb2YgYSBieXRlIHN0cmVhbSBhbmQgYSBjaGFyYWN0ZXIgc3RyZWFtIGFyZQorICogYmluZGluZyBkZXBlbmRlbnQuCisgKiA8cD4gVGhlIGFwcGxpY2F0aW9uIGlzIGV4cGVjdGVkIHRvIHByb3ZpZGUgb2JqZWN0cyB0aGF0IGltcGxlbWVudCB0aGlzCisgKiBpbnRlcmZhY2Ugd2hlbmV2ZXIgc3VjaCBvYmplY3RzIGFyZSBuZWVkZWQuIFRoZSBhcHBsaWNhdGlvbiBjYW4gZWl0aGVyCisgKiBwcm92aWRlIGl0cyBvd24gb2JqZWN0cyB0aGF0IGltcGxlbWVudCB0aGlzIGludGVyZmFjZSwgb3IgaXQgY2FuIHVzZSB0aGUKKyAqIGdlbmVyaWMgZmFjdG9yeSBtZXRob2QgPGNvZGU+RE9NSW1wbGVtZW50YXRpb25MUy5jcmVhdGVMU091dHB1dCgpPC9jb2RlPgorICogdG8gY3JlYXRlIG9iamVjdHMgdGhhdCBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UuCisgKiA8cD4gVGhlIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gd2lsbCB1c2UgdGhlIDxjb2RlPkxTT3V0cHV0PC9jb2RlPiBvYmplY3QKKyAqIHRvIGRldGVybWluZSB3aGVyZSB0byBzZXJpYWxpemUgdGhlIG91dHB1dCB0by4gVGhlCisgKiA8Y29kZT5MU1NlcmlhbGl6ZXI8L2NvZGU+IHdpbGwgbG9vayBhdCB0aGUgZGlmZmVyZW50IG91dHB1dHMgc3BlY2lmaWVkIGluCisgKiB0aGUgPGNvZGU+TFNPdXRwdXQ8L2NvZGU+IGluIHRoZSBmb2xsb3dpbmcgb3JkZXIgdG8ga25vdyB3aGljaCBvbmUgdG8KKyAqIG91dHB1dCB0bywgdGhlIGZpcnN0IG9uZSB0aGF0IGlzIG5vdCBudWxsIGFuZCBub3QgYW4gZW1wdHkgc3RyaW5nIHdpbGwgYmUKKyAqIHVzZWQ6CisgKiA8b2w+CisgKiA8bGk+IDxjb2RlPkxTT3V0cHV0LmNoYXJhY3RlclN0cmVhbTwvY29kZT4KKyAqIDwvbGk+CisgKiA8bGk+CisgKiA8Y29kZT5MU091dHB1dC5ieXRlU3RyZWFtPC9jb2RlPgorICogPC9saT4KKyAqIDxsaT4gPGNvZGU+TFNPdXRwdXQuc3lzdGVtSWQ8L2NvZGU+CisgKiA8L2xpPgorICogPC9vbD4KKyAqIDxwPiA8Y29kZT5MU091dHB1dDwvY29kZT4gb2JqZWN0cyBiZWxvbmcgdG8gdGhlIGFwcGxpY2F0aW9uLiBUaGUgRE9NCisgKiBpbXBsZW1lbnRhdGlvbiB3aWxsIG5ldmVyIG1vZGlmeSB0aGVtICh0aG91Z2ggaXQgbWF5IG1ha2UgY29waWVzIGFuZAorICogbW9kaWZ5IHRoZSBjb3BpZXMsIGlmIG5lY2Vzc2FyeSkuCisgKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtTFMtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIExvYWQKK2FuZCBTYXZlIFNwZWNpZmljYXRpb248L2E+LgorICovCitwdWJsaWMgaW50ZXJmYWNlIExTT3V0cHV0IHsKKyAgICAvKioKKyAgICAgKiAgQW4gYXR0cmlidXRlIG9mIGEgbGFuZ3VhZ2UgYW5kIGJpbmRpbmcgZGVwZW5kZW50IHR5cGUgdGhhdCByZXByZXNlbnRzCisgICAgICogYSB3cml0YWJsZSBzdHJlYW0gdG8gd2hpY2ggMTYtYml0IHVuaXRzIGNhbiBiZSBvdXRwdXQuCisgICAgICovCisgICAgcHVibGljIGphdmEuaW8uV3JpdGVyIGdldENoYXJhY3RlclN0cmVhbSgpOworICAgIC8qKgorICAgICAqICBBbiBhdHRyaWJ1dGUgb2YgYSBsYW5ndWFnZSBhbmQgYmluZGluZyBkZXBlbmRlbnQgdHlwZSB0aGF0IHJlcHJlc2VudHMKKyAgICAgKiBhIHdyaXRhYmxlIHN0cmVhbSB0byB3aGljaCAxNi1iaXQgdW5pdHMgY2FuIGJlIG91dHB1dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDaGFyYWN0ZXJTdHJlYW0oamF2YS5pby5Xcml0ZXIgY2hhcmFjdGVyU3RyZWFtKTsKKworICAgIC8qKgorICAgICAqICBBbiBhdHRyaWJ1dGUgb2YgYSBsYW5ndWFnZSBhbmQgYmluZGluZyBkZXBlbmRlbnQgdHlwZSB0aGF0IHJlcHJlc2VudHMKKyAgICAgKiBhIHdyaXRhYmxlIHN0cmVhbSBvZiBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgamF2YS5pby5PdXRwdXRTdHJlYW0gZ2V0Qnl0ZVN0cmVhbSgpOworICAgIC8qKgorICAgICAqICBBbiBhdHRyaWJ1dGUgb2YgYSBsYW5ndWFnZSBhbmQgYmluZGluZyBkZXBlbmRlbnQgdHlwZSB0aGF0IHJlcHJlc2VudHMKKyAgICAgKiBhIHdyaXRhYmxlIHN0cmVhbSBvZiBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCeXRlU3RyZWFtKGphdmEuaW8uT3V0cHV0U3RyZWFtIGJ5dGVTdHJlYW0pOworCisgICAgLyoqCisgICAgICogIFRoZSBzeXN0ZW0gaWRlbnRpZmllciwgYSBVUkkgcmVmZXJlbmNlIFs8YSBocmVmPSdodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dCc+SUVURiBSRkMgMjM5NjwvYT5dLCBmb3IgdGhpcworICAgICAqIG91dHB1dCBkZXN0aW5hdGlvbi4KKyAgICAgKiA8YnI+IElmIHRoZSBzeXN0ZW0gSUQgaXMgYSByZWxhdGl2ZSBVUkkgcmVmZXJlbmNlIChzZWUgc2VjdGlvbiA1IGluIFs8YSBocmVmPSdodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dCc+SUVURiBSRkMgMjM5NjwvYT5dKSwgdGhlCisgICAgICogYmVoYXZpb3IgaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKTsKKyAgICAvKioKKyAgICAgKiAgVGhlIHN5c3RlbSBpZGVudGlmaWVyLCBhIFVSSSByZWZlcmVuY2UgWzxhIGhyZWY9J2h0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Jz5JRVRGIFJGQyAyMzk2PC9hPl0sIGZvciB0aGlzCisgICAgICogb3V0cHV0IGRlc3RpbmF0aW9uLgorICAgICAqIDxicj4gSWYgdGhlIHN5c3RlbSBJRCBpcyBhIHJlbGF0aXZlIFVSSSByZWZlcmVuY2UgKHNlZSBzZWN0aW9uIDUgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Jz5JRVRGIFJGQyAyMzk2PC9hPl0pLCB0aGUKKyAgICAgKiBiZWhhdmlvciBpcyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3lzdGVtSWQoU3RyaW5nIHN5c3RlbUlkKTsKKworICAgIC8qKgorICAgICAqICBUaGUgY2hhcmFjdGVyIGVuY29kaW5nIHRvIHVzZSBmb3IgdGhlIG91dHB1dC4gVGhlIGVuY29kaW5nIG11c3QgYmUgYQorICAgICAqIHN0cmluZyBhY2NlcHRhYmxlIGZvciBhbiBYTUwgZW5jb2RpbmcgZGVjbGFyYXRpb24gKFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XSBzZWN0aW9uCisgICAgICogNC4zLjMgIkNoYXJhY3RlciBFbmNvZGluZyBpbiBFbnRpdGllcyIpLCBpdCBpcyByZWNvbW1lbmRlZCB0aGF0CisgICAgICogY2hhcmFjdGVyIGVuY29kaW5ncyByZWdpc3RlcmVkIChhcyBjaGFyc2V0cykgd2l0aCB0aGUgSW50ZXJuZXQKKyAgICAgKiBBc3NpZ25lZCBOdW1iZXJzIEF1dGhvcml0eSBbPGEgaHJlZj0nZnRwOi8vZnRwLmlzaS5lZHUvaW4tbm90ZXMvaWFuYS9hc3NpZ25tZW50cy9jaGFyYWN0ZXItc2V0cyc+SUFOQS1DSEFSU0VUUzwvYT5dCisgICAgICogIHNob3VsZCBiZSByZWZlcnJlZCB0byB1c2luZyB0aGVpciByZWdpc3RlcmVkIG5hbWVzLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKTsKKyAgICAvKioKKyAgICAgKiAgVGhlIGNoYXJhY3RlciBlbmNvZGluZyB0byB1c2UgZm9yIHRoZSBvdXRwdXQuIFRoZSBlbmNvZGluZyBtdXN0IGJlIGEKKyAgICAgKiBzdHJpbmcgYWNjZXB0YWJsZSBmb3IgYW4gWE1MIGVuY29kaW5nIGRlY2xhcmF0aW9uIChbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0gc2VjdGlvbgorICAgICAqIDQuMy4zICJDaGFyYWN0ZXIgRW5jb2RpbmcgaW4gRW50aXRpZXMiKSwgaXQgaXMgcmVjb21tZW5kZWQgdGhhdAorICAgICAqIGNoYXJhY3RlciBlbmNvZGluZ3MgcmVnaXN0ZXJlZCAoYXMgY2hhcnNldHMpIHdpdGggdGhlIEludGVybmV0CisgICAgICogQXNzaWduZWQgTnVtYmVycyBBdXRob3JpdHkgWzxhIGhyZWY9J2Z0cDovL2Z0cC5pc2kuZWR1L2luLW5vdGVzL2lhbmEvYXNzaWdubWVudHMvY2hhcmFjdGVyLXNldHMnPklBTkEtQ0hBUlNFVFM8L2E+XQorICAgICAqICBzaG91bGQgYmUgcmVmZXJyZWQgdG8gdXNpbmcgdGhlaXIgcmVnaXN0ZXJlZCBuYW1lcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vbHMvTFNQYXJzZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9scy9MU1BhcnNlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYxMDE0MmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vbHMvTFNQYXJzZXIuamF2YQpAQCAtMCwwICsxLDQ2NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICoKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgorICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCisgKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAorICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCisgKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisgKgorICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tLmxzOworCitpbXBvcnQgb3JnLnczYy5kb20uRE9NQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKKworLyoqCisgKiAgQW4gaW50ZXJmYWNlIHRvIGFuIG9iamVjdCB0aGF0IGlzIGFibGUgdG8gYnVpbGQsIG9yIGF1Z21lbnQsIGEgRE9NIHRyZWUKKyAqIGZyb20gdmFyaW91cyBpbnB1dCBzb3VyY2VzLgorICogPHA+IDxjb2RlPkxTUGFyc2VyPC9jb2RlPiBwcm92aWRlcyBhbiBBUEkgZm9yIHBhcnNpbmcgWE1MIGFuZCBidWlsZGluZyB0aGUKKyAqIGNvcnJlc3BvbmRpbmcgRE9NIGRvY3VtZW50IHN0cnVjdHVyZS4gQSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gaW5zdGFuY2UKKyAqIGNhbiBiZSBvYnRhaW5lZCBieSBpbnZva2luZyB0aGUKKyAqIDxjb2RlPkRPTUltcGxlbWVudGF0aW9uTFMuY3JlYXRlTFNQYXJzZXIoKTwvY29kZT4gbWV0aG9kLgorICogPHA+IEFzIHNwZWNpZmllZCBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RE9NIExldmVsIDMgQ29yZTwvYT5dCisgKiAsIHdoZW4gYSBkb2N1bWVudCBpcyBmaXJzdCBtYWRlIGF2YWlsYWJsZSB2aWEgdGhlIExTUGFyc2VyOgorICogPHVsPgorICogPGxpPiB0aGVyZSB3aWxsCisgKiBuZXZlciBiZSB0d28gYWRqYWNlbnQgbm9kZXMgb2YgdHlwZSBOT0RFX1RFWFQsIGFuZCB0aGVyZSB3aWxsIG5ldmVyIGJlCisgKiBlbXB0eSB0ZXh0IG5vZGVzLgorICogPC9saT4KKyAqIDxsaT4gaXQgaXMgZXhwZWN0ZWQgdGhhdCB0aGUgPGNvZGU+dmFsdWU8L2NvZGU+IGFuZAorICogPGNvZGU+bm9kZVZhbHVlPC9jb2RlPiBhdHRyaWJ1dGVzIG9mIGFuIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGUgaW5pdGlhbGx5CisgKiByZXR1cm4gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCNBVk5vcm1hbGl6ZSc+WE1MIDEuMAorICogbm9ybWFsaXplZCB2YWx1ZTwvYT4uIEhvd2V2ZXIsIGlmIHRoZSBwYXJhbWV0ZXJzICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItdmFsaWRhdGUtaWYtc2NoZW1hJz4KKyAqIHZhbGlkYXRlLWlmLXNjaGVtYTwvYT4iIGFuZCAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLWRhdGF0eXBlLW5vcm1hbGl6YXRpb24nPgorICogZGF0YXR5cGUtbm9ybWFsaXphdGlvbjwvYT4iIGFyZSBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4sIGRlcGVuZGluZyBvbiB0aGUgYXR0cmlidXRlIG5vcm1hbGl6YXRpb24KKyAqIHVzZWQsIHRoZSBhdHRyaWJ1dGUgdmFsdWVzIG1heSBkaWZmZXIgZnJvbSB0aGUgb25lcyBvYnRhaW5lZCBieSB0aGUgWE1MCisgKiAxLjAgYXR0cmlidXRlIG5vcm1hbGl6YXRpb24uIElmIHRoZSBwYXJhbWV0ZXJzICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItZGF0YXR5cGUtbm9ybWFsaXphdGlvbic+CisgKiBkYXRhdHlwZS1ub3JtYWxpemF0aW9uPC9hPiIgaXMgc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiwgdGhlIFhNTCAxLjAgYXR0cmlidXRlIG5vcm1hbGl6YXRpb24gaXMKKyAqIGd1YXJhbnRlZWQgdG8gb2NjdXIsIGFuZCBpZiB0aGUgYXR0cmlidXRlcyBsaXN0IGRvZXMgbm90IGNvbnRhaW4KKyAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMsIHRoZSA8Y29kZT5hdHRyaWJ1dGVzPC9jb2RlPiBhdHRyaWJ1dGUgb24KKyAqIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG5vZGUgcmVwcmVzZW50cyB0aGUgcHJvcGVydHkgPGI+W2F0dHJpYnV0ZXNdPC9iPiBkZWZpbmVkIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtaW5mb3NldC0yMDA0MDIwNC8nPlhNTCBJbmZvcm1hdGlvbiBTZXQ8L2E+XQorICogLgorICogPC9saT4KKyAqIDwvdWw+CisgKiA8cD4gQXN5bmNocm9ub3VzIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiBvYmplY3RzIGFyZSBleHBlY3RlZCB0byBhbHNvCisgKiBpbXBsZW1lbnQgdGhlIDxjb2RlPmV2ZW50czo6RXZlbnRUYXJnZXQ8L2NvZGU+IGludGVyZmFjZSBzbyB0aGF0IGV2ZW50CisgKiBsaXN0ZW5lcnMgY2FuIGJlIHJlZ2lzdGVyZWQgb24gYXN5bmNocm9ub3VzIDxjb2RlPkxTUGFyc2VyPC9jb2RlPgorICogb2JqZWN0cy4KKyAqIDxwPiBFdmVudHMgc3VwcG9ydGVkIGJ5IGFzeW5jaHJvbm91cyA8Y29kZT5MU1BhcnNlcjwvY29kZT4gb2JqZWN0cyBhcmU6CisgKiA8ZGw+CisgKiA8ZHQ+bG9hZDwvZHQ+CisgKiA8ZGQ+CisgKiAgVGhlIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiBmaW5pc2hlcyB0byBsb2FkIHRoZSBkb2N1bWVudC4gU2VlIGFsc28gdGhlCisgKiBkZWZpbml0aW9uIG9mIHRoZSA8Y29kZT5MU0xvYWRFdmVudDwvY29kZT4gaW50ZXJmYWNlLiA8L2RkPgorICogPGR0PnByb2dyZXNzPC9kdD4KKyAqIDxkZD4gVGhlCisgKiA8Y29kZT5MU1BhcnNlcjwvY29kZT4gc2lnbmFscyBwcm9ncmVzcyBhcyBkYXRhIGlzIHBhcnNlZC4gIFRoaXMKKyAqIHNwZWNpZmljYXRpb24gZG9lcyBub3QgYXR0ZW1wdCB0byBkZWZpbmUgZXhhY3RseSB3aGVuIHByb2dyZXNzIGV2ZW50cworICogc2hvdWxkIGJlIGRpc3BhdGNoZWQuIFRoYXQgaXMgaW50ZW50aW9uYWxseSBsZWZ0IGFzCisgKiBpbXBsZW1lbnRhdGlvbi1kZXBlbmRlbnQuIEhlcmUgaXMgb25lIGV4YW1wbGUgb2YgaG93IGFuIGFwcGxpY2F0aW9uIG1pZ2h0CisgKiBkaXNwYXRjaCBwcm9ncmVzcyBldmVudHM6IE9uY2UgdGhlIHBhcnNlciBzdGFydHMgcmVjZWl2aW5nIGRhdGEsIGEKKyAqIHByb2dyZXNzIGV2ZW50IGlzIGRpc3BhdGNoZWQgdG8gaW5kaWNhdGUgdGhhdCB0aGUgcGFyc2luZyBzdGFydHMuIEZyb20KKyAqIHRoZXJlIG9uLCBhIHByb2dyZXNzIGV2ZW50IGlzIGRpc3BhdGNoZWQgZm9yIGV2ZXJ5IDQwOTYgYnl0ZXMgb2YgZGF0YQorICogdGhhdCBpcyByZWNlaXZlZCBhbmQgcHJvY2Vzc2VkLiBUaGlzIGlzIG9ubHkgb25lIGV4YW1wbGUsIHRob3VnaCwgYW5kCisgKiBpbXBsZW1lbnRhdGlvbnMgY2FuIGNob29zZSB0byBkaXNwYXRjaCBwcm9ncmVzcyBldmVudHMgYXQgYW55IHRpbWUgd2hpbGUKKyAqIHBhcnNpbmcsIG9yIG5vdCBkaXNwYXRjaCB0aGVtIGF0IGFsbC4gIFNlZSBhbHNvIHRoZSBkZWZpbml0aW9uIG9mIHRoZQorICogPGNvZGU+TFNQcm9ncmVzc0V2ZW50PC9jb2RlPiBpbnRlcmZhY2UuIDwvZGQ+CisgKiA8L2RsPgorICogPHAgPjxiPk5vdGU6PC9iPiAgQWxsIGV2ZW50cyBkZWZpbmVkIGluIHRoaXMgc3BlY2lmaWNhdGlvbiB1c2UgdGhlCisgKiBuYW1lc3BhY2UgVVJJIDxjb2RlPiJodHRwOi8vd3d3LnczLm9yZy8yMDAyL0RPTUxTIjwvY29kZT4uCisgKiA8cD4gV2hpbGUgcGFyc2luZyBhbiBpbnB1dCBzb3VyY2UsIGVycm9ycyBhcmUgcmVwb3J0ZWQgdG8gdGhlIGFwcGxpY2F0aW9uCisgKiB0aHJvdWdoIHRoZSBlcnJvciBoYW5kbGVyICg8Y29kZT5MU1BhcnNlci5kb21Db25maWc8L2NvZGU+J3MgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lcnJvci1oYW5kbGVyJz4KKyAqIGVycm9yLWhhbmRsZXI8L2E+IiBwYXJhbWV0ZXIpLiBUaGlzIHNwZWNpZmljYXRpb24gZG9lcyBpbiBubyB3YXkgdHJ5IHRvIGRlZmluZSBhbGwgcG9zc2libGUKKyAqIGVycm9ycyB0aGF0IGNhbiBvY2N1ciB3aGlsZSBwYXJzaW5nIFhNTCwgb3IgYW55IG90aGVyIG1hcmt1cCwgYnV0IHNvbWUKKyAqIGNvbW1vbiBlcnJvciBjYXNlcyBhcmUgZGVmaW5lZC4gVGhlIHR5cGVzICg8Y29kZT5ET01FcnJvci50eXBlPC9jb2RlPikgb2YKKyAqIGVycm9ycyBhbmQgd2FybmluZ3MgZGVmaW5lZCBieSB0aGlzIHNwZWNpZmljYXRpb24gYXJlOgorICogPGRsPgorICogPGR0PgorICogPGNvZGU+ImNoZWNrLWNoYXJhY3Rlci1ub3JtYWxpemF0aW9uLWZhaWx1cmUiIFtlcnJvcl08L2NvZGU+IDwvZHQ+CisgKiA8ZGQ+IFJhaXNlZCBpZgorICogdGhlIHBhcmFtZXRlciAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLWNoZWNrLWNoYXJhY3Rlci1ub3JtYWxpemF0aW9uJz4KKyAqIGNoZWNrLWNoYXJhY3Rlci1ub3JtYWxpemF0aW9uPC9hPiIgaXMgc2V0IHRvIHRydWUgYW5kIGEgc3RyaW5nIGlzIGVuY291bnRlcmVkIHRoYXQgZmFpbHMgbm9ybWFsaXphdGlvbgorICogY2hlY2tpbmcuIDwvZGQ+CisgKiA8ZHQ+PGNvZGU+ImRvY3R5cGUtbm90LWFsbG93ZWQiIFtmYXRhbF08L2NvZGU+PC9kdD4KKyAqIDxkZD4gUmFpc2VkIGlmIHRoZQorICogY29uZmlndXJhdGlvbiBwYXJhbWV0ZXIgImRpc2FsbG93LWRvY3R5cGUiIGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPgorICogYW5kIGEgZG9jdHlwZSBpcyBlbmNvdW50ZXJlZC4gPC9kZD4KKyAqIDxkdD48Y29kZT4ibm8taW5wdXQtc3BlY2lmaWVkIiBbZmF0YWxdPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+CisgKiBSYWlzZWQgd2hlbiBsb2FkaW5nIGEgZG9jdW1lbnQgYW5kIG5vIGlucHV0IGlzIHNwZWNpZmllZCBpbiB0aGUKKyAqIDxjb2RlPkxTSW5wdXQ8L2NvZGU+IG9iamVjdC4gPC9kZD4KKyAqIDxkdD4KKyAqIDxjb2RlPiJwaS1iYXNlLXVyaS1ub3QtcHJlc2VydmVkIiBbd2FybmluZ108L2NvZGU+PC9kdD4KKyAqIDxkZD4gUmFpc2VkIGlmIGEgcHJvY2Vzc2luZworICogaW5zdHJ1Y3Rpb24gaXMgZW5jb3VudGVyZWQgaW4gYSBsb2NhdGlvbiB3aGVyZSB0aGUgYmFzZSBVUkkgb2YgdGhlCisgKiBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGNhbiBub3QgYmUgcHJlc2VydmVkLiAgT25lIGV4YW1wbGUgb2YgYSBjYXNlIHdoZXJlCisgKiB0aGlzIHdhcm5pbmcgd2lsbCBiZSByYWlzZWQgaXMgaWYgdGhlIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItZW50aXRpZXMnPgorICogZW50aXRpZXM8L2E+IiBpcyBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+IGFuZCB0aGUgZm9sbG93aW5nIFhNTCBmaWxlIGlzIHBhcnNlZDoKKyAqIDxwcmU+CisgKiAmbHQ7IURPQ1RZUEUgcm9vdCBbICZsdDshRU5USVRZIGUgU1lTVEVNICdzdWJkaXIvbXllbnRpdHkuZW50JyBdJmd0OworICogJmx0O3Jvb3QmZ3Q7ICZhbXA7ZTsgJmx0Oy9yb290Jmd0OzwvcHJlPgorICogIEFuZCA8Y29kZT5zdWJkaXIvbXllbnRpdHkuZW50PC9jb2RlPgorICogY29udGFpbnM6CisgKiA8cHJlPiZsdDtvbmUmZ3Q7ICZsdDt0d28vJmd0OyAmbHQ7L29uZSZndDsgJmx0Oz9waSAzLjE0MTU5PyZndDsKKyAqICZsdDttb3JlLyZndDs8L3ByZT4KKyAqIDwvZGQ+CisgKiA8ZHQ+PGNvZGU+InVuYm91bmQtcHJlZml4LWluLWVudGl0eSIgW3dhcm5pbmddPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+IEFuCisgKiBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQgd2FybmluZyB0aGF0IG1heSBiZSByYWlzZWQgaWYgdGhlIGNvbmZpZ3VyYXRpb24KKyAqIHBhcmFtZXRlciAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLW5hbWVzcGFjZXMnPgorICogbmFtZXNwYWNlczwvYT4iIGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiBhbmQgYW4gdW5ib3VuZCBuYW1lc3BhY2UgcHJlZml4IGlzCisgKiBlbmNvdW50ZXJlZCBpbiBhbiBlbnRpdHkncyByZXBsYWNlbWVudCB0ZXh0LiBSYWlzaW5nIHRoaXMgd2FybmluZyBpcyBub3QKKyAqIGVuZm9yY2VkIHNpbmNlIHNvbWUgZXhpc3RpbmcgcGFyc2VycyBtYXkgbm90IHJlY29nbml6ZSB1bmJvdW5kIG5hbWVzcGFjZQorICogcHJlZml4ZXMgaW4gdGhlIHJlcGxhY2VtZW50IHRleHQgb2YgZW50aXRpZXMuIDwvZGQ+CisgKiA8ZHQ+CisgKiA8Y29kZT4idW5rbm93bi1jaGFyYWN0ZXItZGVub3JtYWxpemF0aW9uIiBbZmF0YWxdPC9jb2RlPjwvZHQ+CisgKiA8ZGQ+IFJhaXNlZCBpZiB0aGUKKyAqIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyICJpZ25vcmUtdW5rbm93bi1jaGFyYWN0ZXItZGVub3JtYWxpemF0aW9ucyIgaXMKKyAqIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4gYW5kIGEgY2hhcmFjdGVyIGlzIGVuY291bnRlcmVkIGZvciB3aGljaCB0aGUKKyAqIHByb2Nlc3NvciBjYW5ub3QgZGV0ZXJtaW5lIHRoZSBub3JtYWxpemF0aW9uIHByb3BlcnRpZXMuIDwvZGQ+CisgKiA8ZHQ+CisgKiA8Y29kZT4idW5zdXBwb3J0ZWQtZW5jb2RpbmciIFtmYXRhbF08L2NvZGU+PC9kdD4KKyAqIDxkZD4gUmFpc2VkIGlmIGFuIHVuc3VwcG9ydGVkCisgKiBlbmNvZGluZyBpcyBlbmNvdW50ZXJlZC4gPC9kZD4KKyAqIDxkdD48Y29kZT4idW5zdXBwb3J0ZWQtbWVkaWEtdHlwZSIgW2ZhdGFsXTwvY29kZT48L2R0PgorICogPGRkPgorICogUmFpc2VkIGlmIHRoZSBjb25maWd1cmF0aW9uIHBhcmFtZXRlciAic3VwcG9ydGVkLW1lZGlhLXR5cGVzLW9ubHkiIGlzIHNldAorICogdG8gPGNvZGU+dHJ1ZTwvY29kZT4gYW5kIGFuIHVuc3VwcG9ydGVkIG1lZGlhIHR5cGUgaXMgZW5jb3VudGVyZWQuIDwvZGQ+CisgKiA8L2RsPgorICogPHA+IEluIGFkZGl0aW9uIHRvIHJhaXNpbmcgdGhlIGRlZmluZWQgZXJyb3JzIGFuZCB3YXJuaW5ncywgaW1wbGVtZW50YXRpb25zCisgKiBhcmUgZXhwZWN0ZWQgdG8gcmFpc2UgaW1wbGVtZW50YXRpb24gc3BlY2lmaWMgZXJyb3JzIGFuZCB3YXJuaW5ncyBmb3IgYW55CisgKiBvdGhlciBlcnJvciBhbmQgd2FybmluZyBjYXNlcyBzdWNoIGFzIElPIGVycm9ycyAoZmlsZSBub3QgZm91bmQsCisgKiBwZXJtaXNzaW9uIGRlbmllZCwuLi4pLCBYTUwgd2VsbC1mb3JtZWRuZXNzIGVycm9ycywgYW5kIHNvIG9uLgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUxTLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBMb2FkCithbmQgU2F2ZSBTcGVjaWZpY2F0aW9uPC9hPi4KKyAqLworcHVibGljIGludGVyZmFjZSBMU1BhcnNlciB7CisgICAgLyoqCisgICAgICogIFRoZSA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBvYmplY3QgdXNlZCB3aGVuIHBhcnNpbmcgYW4gaW5wdXQKKyAgICAgKiBzb3VyY2UuIFRoaXMgPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gaXMgc3BlY2lmaWMgdG8gdGhlIHBhcnNlCisgICAgICogb3BlcmF0aW9uLiBObyBwYXJhbWV0ZXIgdmFsdWVzIGZyb20gdGhpcyA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPgorICAgICAqICBvYmplY3QgYXJlIHBhc3NlZCBhdXRvbWF0aWNhbGx5IHRvIHRoZSA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPgorICAgICAqIG9iamVjdCBvbiB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IHRoYXQgaXMgY3JlYXRlZCwgb3IgdXNlZCwgYnkgdGhlCisgICAgICogcGFyc2Ugb3BlcmF0aW9uLiBUaGUgRE9NIGFwcGxpY2F0aW9uIGlzIHJlc3BvbnNpYmxlIGZvciBwYXNzaW5nIGFueQorICAgICAqIG5lZWRlZCBwYXJhbWV0ZXIgdmFsdWVzIGZyb20gdGhpcyA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPgorICAgICAqIG9iamVjdCB0byB0aGUgPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gb2JqZWN0IHJlZmVyZW5jZWQgYnkgdGhlCisgICAgICogPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG9iamVjdC4KKyAgICAgKiA8YnI+IEluIGFkZGl0aW9uIHRvIHRoZSBwYXJhbWV0ZXJzIHJlY29nbml6ZWQgaW4gb24gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI0RPTUNvbmZpZ3VyYXRpb24nPgorICAgICAqIERPTUNvbmZpZ3VyYXRpb248L2E+IGludGVyZmFjZSBkZWZpbmVkIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5ET00gTGV2ZWwgMyBDb3JlPC9hPl0KKyAgICAgKiAsIHRoZSA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBvYmplY3RzIGZvciA8Y29kZT5MU1BhcnNlcjwvY29kZT4KKyAgICAgKiBhZGQgb3IgbW9kaWZ5IHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVyczoKKyAgICAgKiA8ZGw+CisgICAgICogPGR0PgorICAgICAqIDxjb2RlPiJjaGFyc2V0LW92ZXJyaWRlcy14bWwtZW5jb2RpbmciPC9jb2RlPjwvZHQ+CisgICAgICogPGRkPgorICAgICAqIDxkbD4KKyAgICAgKiA8ZHQ+PGNvZGU+dHJ1ZTwvY29kZT48L2R0PgorICAgICAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dICg8ZW0+ZGVmYXVsdDwvZW0+KSBJZiBhIGhpZ2hlciBsZXZlbCBwcm90b2NvbCBzdWNoIGFzIEhUVFAgWzxhIGhyZWY9J2h0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzI2MTYudHh0Jz5JRVRGIFJGQyAyNjE2PC9hPl0gcHJvdmlkZXMgYW4KKyAgICAgKiBpbmRpY2F0aW9uIG9mIHRoZSBjaGFyYWN0ZXIgZW5jb2Rpbmcgb2YgdGhlIGlucHV0IHN0cmVhbSBiZWluZworICAgICAqIHByb2Nlc3NlZCwgdGhhdCB3aWxsIG92ZXJyaWRlIGFueSBlbmNvZGluZyBzcGVjaWZpZWQgaW4gdGhlIFhNTAorICAgICAqIGRlY2xhcmF0aW9uIG9yIHRoZSBUZXh0IGRlY2xhcmF0aW9uIChzZWUgYWxzbyBzZWN0aW9uIDQuMy4zLAorICAgICAqICJDaGFyYWN0ZXIgRW5jb2RpbmcgaW4gRW50aXRpZXMiLCBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0pLgorICAgICAqIEV4cGxpY2l0bHkgc2V0dGluZyBhbiBlbmNvZGluZyBpbiB0aGUgPGNvZGU+TFNJbnB1dDwvY29kZT4gb3ZlcnJpZGVzCisgICAgICogYW55IGVuY29kaW5nIGZyb20gdGhlIHByb3RvY29sLiA8L2RkPgorICAgICAqIDxkdD48Y29kZT5mYWxzZTwvY29kZT48L2R0PgorICAgICAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dIFRoZSBwYXJzZXIgaWdub3JlcyBhbnkgY2hhcmFjdGVyIHNldCBlbmNvZGluZyBpbmZvcm1hdGlvbiBmcm9tCisgICAgICogaGlnaGVyLWxldmVsIHByb3RvY29scy4gPC9kZD4KKyAgICAgKiA8L2RsPjwvZGQ+CisgICAgICogPGR0Pjxjb2RlPiJkaXNhbGxvdy1kb2N0eXBlIjwvY29kZT48L2R0PgorICAgICAqIDxkZD4KKyAgICAgKiA8ZGw+CisgICAgICogPGR0PgorICAgICAqIDxjb2RlPnRydWU8L2NvZGU+PC9kdD4KKyAgICAgKiA8ZGQ+WzxlbT5vcHRpb25hbDwvZW0+XSBUaHJvdyBhIGZhdGFsIDxiPiJkb2N0eXBlLW5vdC1hbGxvd2VkIjwvYj4gZXJyb3IgaWYgYSBkb2N0eXBlIG5vZGUgaXMgZm91bmQgd2hpbGUgcGFyc2luZyB0aGUgZG9jdW1lbnQuIFRoaXMgaXMKKyAgICAgKiB1c2VmdWwgd2hlbiBkZWFsaW5nIHdpdGggdGhpbmdzIGxpa2UgU09BUCBlbnZlbG9wZXMgd2hlcmUgZG9jdHlwZQorICAgICAqIG5vZGVzIGFyZSBub3QgYWxsb3dlZC4gPC9kZD4KKyAgICAgKiA8ZHQ+PGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KKyAgICAgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPikgQWxsb3cgZG9jdHlwZSBub2RlcyBpbiB0aGUgZG9jdW1lbnQuIDwvZGQ+CisgICAgICogPC9kbD48L2RkPgorICAgICAqIDxkdD4KKyAgICAgKiA8Y29kZT4iaWdub3JlLXVua25vd24tY2hhcmFjdGVyLWRlbm9ybWFsaXphdGlvbnMiPC9jb2RlPjwvZHQ+CisgICAgICogPGRkPgorICAgICAqIDxkbD4KKyAgICAgKiA8ZHQ+CisgICAgICogPGNvZGU+dHJ1ZTwvY29kZT48L2R0PgorICAgICAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dICg8ZW0+ZGVmYXVsdDwvZW0+KSBJZiwgd2hpbGUgdmVyaWZ5aW5nIGZ1bGwgbm9ybWFsaXphdGlvbiB3aGVuIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwxMS0yMDA0MDIwNC8nPlhNTCAxLjE8L2E+XSBpcworICAgICAqIHN1cHBvcnRlZCwgYSBwcm9jZXNzb3IgZW5jb3VudGVycyBjaGFyYWN0ZXJzIGZvciB3aGljaCBpdCBjYW5ub3QKKyAgICAgKiBkZXRlcm1pbmUgdGhlIG5vcm1hbGl6YXRpb24gcHJvcGVydGllcywgdGhlbiB0aGUgcHJvY2Vzc29yIHdpbGwKKyAgICAgKiBpZ25vcmUgYW55IHBvc3NpYmxlIGRlbm9ybWFsaXphdGlvbnMgY2F1c2VkIGJ5IHRoZXNlIGNoYXJhY3RlcnMuCisgICAgICogVGhpcyBwYXJhbWV0ZXIgaXMgaWdub3JlZCBmb3IgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dLiA8L2RkPgorICAgICAqIDxkdD4KKyAgICAgKiA8Y29kZT5mYWxzZTwvY29kZT48L2R0PgorICAgICAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dIFJlcG9ydCBhbiBmYXRhbCA8Yj4idW5rbm93bi1jaGFyYWN0ZXItZGVub3JtYWxpemF0aW9uIjwvYj4gZXJyb3IgaWYgYSBjaGFyYWN0ZXIgaXMgZW5jb3VudGVyZWQgZm9yIHdoaWNoIHRoZSBwcm9jZXNzb3IgY2Fubm90CisgICAgICogZGV0ZXJtaW5lIHRoZSBub3JtYWxpemF0aW9uIHByb3BlcnRpZXMuIDwvZGQ+CisgICAgICogPC9kbD48L2RkPgorICAgICAqIDxkdD48Y29kZT4iaW5mb3NldCI8L2NvZGU+PC9kdD4KKyAgICAgKiA8ZGQ+IFNlZQorICAgICAqIHRoZSBkZWZpbml0aW9uIG9mIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IGZvciBhIGRlc2NyaXB0aW9uIG9mCisgICAgICogdGhpcyBwYXJhbWV0ZXIuIFVubGlrZSBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RE9NIExldmVsIDMgQ29yZTwvYT5dCisgICAgICogLCB0aGlzIHBhcmFtZXRlciB3aWxsIGRlZmF1bHQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4gZm9yCisgICAgICogPGNvZGU+TFNQYXJzZXI8L2NvZGU+LiA8L2RkPgorICAgICAqIDxkdD48Y29kZT4ibmFtZXNwYWNlcyI8L2NvZGU+PC9kdD4KKyAgICAgKiA8ZGQ+CisgICAgICogPGRsPgorICAgICAqIDxkdD48Y29kZT50cnVlPC9jb2RlPjwvZHQ+CisgICAgICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pIFBlcmZvcm0gdGhlIG5hbWVzcGFjZSBwcm9jZXNzaW5nIGFzIGRlZmluZWQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNC8nPlhNTCBOYW1lc3BhY2VzPC9hPl0KKyAgICAgKiAgYW5kIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtbmFtZXMxMS0yMDA0MDIwNC8nPlhNTCBOYW1lc3BhY2VzIDEuMTwvYT5dCisgICAgICogLiA8L2RkPgorICAgICAqIDxkdD48Y29kZT5mYWxzZTwvY29kZT48L2R0PgorICAgICAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dIERvIG5vdCBwZXJmb3JtIHRoZSBuYW1lc3BhY2UgcHJvY2Vzc2luZy4gPC9kZD4KKyAgICAgKiA8L2RsPjwvZGQ+CisgICAgICogPGR0PgorICAgICAqIDxjb2RlPiJyZXNvdXJjZS1yZXNvbHZlciI8L2NvZGU+PC9kdD4KKyAgICAgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSBBIHJlZmVyZW5jZSB0byBhIDxjb2RlPkxTUmVzb3VyY2VSZXNvbHZlcjwvY29kZT4gb2JqZWN0LCBvciBudWxsLiBJZgorICAgICAqIHRoZSB2YWx1ZSBvZiB0aGlzIHBhcmFtZXRlciBpcyBub3QgbnVsbCB3aGVuIGFuIGV4dGVybmFsIHJlc291cmNlCisgICAgICogKHN1Y2ggYXMgYW4gZXh0ZXJuYWwgWE1MIGVudGl0eSBvciBhbiBYTUwgc2NoZW1hIGxvY2F0aW9uKSBpcworICAgICAqIGVuY291bnRlcmVkLCB0aGUgaW1wbGVtZW50YXRpb24gd2lsbCByZXF1ZXN0IHRoYXQgdGhlCisgICAgICogPGNvZGU+TFNSZXNvdXJjZVJlc29sdmVyPC9jb2RlPiByZWZlcmVuY2VkIGluIHRoaXMgcGFyYW1ldGVyIHJlc29sdmVzCisgICAgICogdGhlIHJlc291cmNlLiA8L2RkPgorICAgICAqIDxkdD48Y29kZT4ic3VwcG9ydGVkLW1lZGlhLXR5cGVzLW9ubHkiPC9jb2RlPjwvZHQ+CisgICAgICogPGRkPgorICAgICAqIDxkbD4KKyAgICAgKiA8ZHQ+CisgICAgICogPGNvZGU+dHJ1ZTwvY29kZT48L2R0PgorICAgICAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dIENoZWNrIHRoYXQgdGhlIG1lZGlhIHR5cGUgb2YgdGhlIHBhcnNlZCByZXNvdXJjZSBpcyBhIHN1cHBvcnRlZCBtZWRpYQorICAgICAqIHR5cGUuIElmIGFuIHVuc3VwcG9ydGVkIG1lZGlhIHR5cGUgaXMgZW5jb3VudGVyZWQsIGEgZmF0YWwgZXJyb3Igb2YKKyAgICAgKiB0eXBlIDxiPiJ1bnN1cHBvcnRlZC1tZWRpYS10eXBlIjwvYj4gd2lsbCBiZSByYWlzZWQuIFRoZSBtZWRpYSB0eXBlcyBkZWZpbmVkIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMDIzLnR4dCc+SUVURiBSRkMgMzAyMzwvYT5dIG11c3QgYWx3YXlzCisgICAgICogYmUgYWNjZXB0ZWQuIDwvZGQ+CisgICAgICogPGR0Pjxjb2RlPmZhbHNlPC9jb2RlPjwvZHQ+CisgICAgICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pIEFjY2VwdCBhbnkgbWVkaWEgdHlwZS4gPC9kZD4KKyAgICAgKiA8L2RsPjwvZGQ+CisgICAgICogPGR0Pjxjb2RlPiJ2YWxpZGF0ZSI8L2NvZGU+PC9kdD4KKyAgICAgKiA8ZGQ+IFNlZSB0aGUgZGVmaW5pdGlvbiBvZgorICAgICAqIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IGZvciBhIGRlc2NyaXB0aW9uIG9mIHRoaXMgcGFyYW1ldGVyLgorICAgICAqIFVubGlrZSBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RE9NIExldmVsIDMgQ29yZTwvYT5dCisgICAgICogLCB0aGUgcHJvY2Vzc2luZyBvZiB0aGUgaW50ZXJuYWwgc3Vic2V0IGlzIGFsd2F5cyBhY2NvbXBsaXNoZWQsIGV2ZW4KKyAgICAgKiBpZiB0aGlzIHBhcmFtZXRlciBpcyBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LiA8L2RkPgorICAgICAqIDxkdD4KKyAgICAgKiA8Y29kZT4idmFsaWRhdGUtaWYtc2NoZW1hIjwvY29kZT48L2R0PgorICAgICAqIDxkZD4gU2VlIHRoZSBkZWZpbml0aW9uIG9mCisgICAgICogPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gZm9yIGEgZGVzY3JpcHRpb24gb2YgdGhpcyBwYXJhbWV0ZXIuCisgICAgICogVW5saWtlIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5ET00gTGV2ZWwgMyBDb3JlPC9hPl0KKyAgICAgKiAsIHRoZSBwcm9jZXNzaW5nIG9mIHRoZSBpbnRlcm5hbCBzdWJzZXQgaXMgYWx3YXlzIGFjY29tcGxpc2hlZCwgZXZlbgorICAgICAqIGlmIHRoaXMgcGFyYW1ldGVyIGlzIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4uIDwvZGQ+CisgICAgICogPGR0PgorICAgICAqIDxjb2RlPiJ3ZWxsLWZvcm1lZCI8L2NvZGU+PC9kdD4KKyAgICAgKiA8ZGQ+IFNlZSB0aGUgZGVmaW5pdGlvbiBvZgorICAgICAqIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IGZvciBhIGRlc2NyaXB0aW9uIG9mIHRoaXMgcGFyYW1ldGVyLgorICAgICAqIFVubGlrZSBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RE9NIExldmVsIDMgQ29yZTwvYT5dCisgICAgICogLCB0aGlzIHBhcmFtZXRlciBjYW5ub3QgYmUgc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPi4gPC9kZD4KKyAgICAgKiA8L2RsPgorICAgICAqLworICAgIHB1YmxpYyBET01Db25maWd1cmF0aW9uIGdldERvbUNvbmZpZygpOworCisgICAgLyoqCisgICAgICogIFdoZW4gYSBmaWx0ZXIgaXMgcHJvdmlkZWQsIHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsIGNhbGwgb3V0IHRvIHRoZQorICAgICAqIGZpbHRlciBhcyBpdCBpcyBjb25zdHJ1Y3RpbmcgdGhlIERPTSB0cmVlIHN0cnVjdHVyZS4gVGhlIGZpbHRlciBjYW4KKyAgICAgKiBjaG9vc2UgdG8gcmVtb3ZlIGVsZW1lbnRzIGZyb20gdGhlIGRvY3VtZW50IGJlaW5nIGNvbnN0cnVjdGVkLCBvciB0bworICAgICAqIHRlcm1pbmF0ZSB0aGUgcGFyc2luZyBlYXJseS4KKyAgICAgKiA8YnI+IFRoZSBmaWx0ZXIgaXMgaW52b2tlZCBhZnRlciB0aGUgb3BlcmF0aW9ucyByZXF1ZXN0ZWQgYnkgdGhlCisgICAgICogPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gcGFyYW1ldGVycyBoYXZlIGJlZW4gYXBwbGllZC4gRm9yCisgICAgICogZXhhbXBsZSwgaWYgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci12YWxpZGF0ZSc+CisgICAgICogdmFsaWRhdGU8L2E+IiBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4sIHRoZSB2YWxpZGF0aW9uIGlzIGRvbmUgYmVmb3JlIGludm9raW5nIHRoZQorICAgICAqIGZpbHRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgTFNQYXJzZXJGaWx0ZXIgZ2V0RmlsdGVyKCk7CisgICAgLyoqCisgICAgICogIFdoZW4gYSBmaWx0ZXIgaXMgcHJvdmlkZWQsIHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsIGNhbGwgb3V0IHRvIHRoZQorICAgICAqIGZpbHRlciBhcyBpdCBpcyBjb25zdHJ1Y3RpbmcgdGhlIERPTSB0cmVlIHN0cnVjdHVyZS4gVGhlIGZpbHRlciBjYW4KKyAgICAgKiBjaG9vc2UgdG8gcmVtb3ZlIGVsZW1lbnRzIGZyb20gdGhlIGRvY3VtZW50IGJlaW5nIGNvbnN0cnVjdGVkLCBvciB0bworICAgICAqIHRlcm1pbmF0ZSB0aGUgcGFyc2luZyBlYXJseS4KKyAgICAgKiA8YnI+IFRoZSBmaWx0ZXIgaXMgaW52b2tlZCBhZnRlciB0aGUgb3BlcmF0aW9ucyByZXF1ZXN0ZWQgYnkgdGhlCisgICAgICogPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gcGFyYW1ldGVycyBoYXZlIGJlZW4gYXBwbGllZC4gRm9yCisgICAgICogZXhhbXBsZSwgaWYgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci12YWxpZGF0ZSc+CisgICAgICogdmFsaWRhdGU8L2E+IiBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4sIHRoZSB2YWxpZGF0aW9uIGlzIGRvbmUgYmVmb3JlIGludm9raW5nIHRoZQorICAgICAqIGZpbHRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGaWx0ZXIoTFNQYXJzZXJGaWx0ZXIgZmlsdGVyKTsKKworICAgIC8qKgorICAgICAqICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IGlzIGFzeW5jaHJvbm91cywKKyAgICAgKiA8Y29kZT5mYWxzZTwvY29kZT4gaWYgaXQgaXMgc3luY2hyb25vdXMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0QXN5bmMoKTsKKworICAgIC8qKgorICAgICAqICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IGlzIGN1cnJlbnRseSBidXN5CisgICAgICogbG9hZGluZyBhIGRvY3VtZW50LCBvdGhlcndpc2UgPGNvZGU+ZmFsc2U8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldEJ1c3koKTsKKworICAgIC8qKgorICAgICAqIFBhcnNlIGFuIFhNTCBkb2N1bWVudCBmcm9tIGEgcmVzb3VyY2UgaWRlbnRpZmllZCBieSBhCisgICAgICogPGNvZGU+TFNJbnB1dDwvY29kZT4uCisgICAgICogQHBhcmFtIGlucHV0ICBUaGUgPGNvZGU+TFNJbnB1dDwvY29kZT4gZnJvbSB3aGljaCB0aGUgc291cmNlIG9mIHRoZQorICAgICAqICAgZG9jdW1lbnQgaXMgdG8gYmUgcmVhZC4KKyAgICAgKiBAcmV0dXJuICBJZiB0aGUgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IGlzIGEgc3luY2hyb25vdXMKKyAgICAgKiAgIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiwgdGhlIG5ld2x5IGNyZWF0ZWQgYW5kIHBvcHVsYXRlZAorICAgICAqICAgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IGlzIHJldHVybmVkLiBJZiB0aGUgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IGlzCisgICAgICogICBhc3luY2hyb25vdXMsIDxjb2RlPm51bGw8L2NvZGU+IGlzIHJldHVybmVkIHNpbmNlIHRoZSBkb2N1bWVudAorICAgICAqICAgb2JqZWN0IG1heSBub3QgeWV0IGJlIGNvbnN0cnVjdGVkIHdoZW4gdGhpcyBtZXRob2QgcmV0dXJucy4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgIElOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgdGhlIDxjb2RlPkxTUGFyc2VyPC9jb2RlPidzCisgICAgICogICA8Y29kZT5MU1BhcnNlci5idXN5PC9jb2RlPiBhdHRyaWJ1dGUgaXMgPGNvZGU+dHJ1ZTwvY29kZT4uCisgICAgICogQGV4Y2VwdGlvbiBMU0V4Y2VwdGlvbgorICAgICAqICAgIFBBUlNFX0VSUjogUmFpc2VkIGlmIHRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gd2FzIHVuYWJsZSB0byBsb2FkCisgICAgICogICB0aGUgWE1MIGRvY3VtZW50LiBET00gYXBwbGljYXRpb25zIHNob3VsZCBhdHRhY2ggYQorICAgICAqICAgPGNvZGU+RE9NRXJyb3JIYW5kbGVyPC9jb2RlPiB1c2luZyB0aGUgcGFyYW1ldGVyICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItZXJyb3ItaGFuZGxlcic+CisgICAgICogICBlcnJvci1oYW5kbGVyPC9hPiIgaWYgdGhleSB3aXNoIHRvIGdldCBkZXRhaWxzIG9uIHRoZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgRG9jdW1lbnQgcGFyc2UoTFNJbnB1dCBpbnB1dCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiwgTFNFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiAgUGFyc2UgYW4gWE1MIGRvY3VtZW50IGZyb20gYSBsb2NhdGlvbiBpZGVudGlmaWVkIGJ5IGEgVVJJIHJlZmVyZW5jZSBbPGEgaHJlZj0naHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjM5Ni50eHQnPklFVEYgUkZDIDIzOTY8L2E+XS4gSWYgdGhlIFVSSQorICAgICAqIGNvbnRhaW5zIGEgZnJhZ21lbnQgaWRlbnRpZmllciAoc2VlIHNlY3Rpb24gNC4xIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dCc+SUVURiBSRkMgMjM5NjwvYT5dKSwgdGhlCisgICAgICogYmVoYXZpb3IgaXMgbm90IGRlZmluZWQgYnkgdGhpcyBzcGVjaWZpY2F0aW9uLCBmdXR1cmUgdmVyc2lvbnMgb2YKKyAgICAgKiB0aGlzIHNwZWNpZmljYXRpb24gbWF5IGRlZmluZSB0aGUgYmVoYXZpb3IuCisgICAgICogQHBhcmFtIHVyaSBUaGUgbG9jYXRpb24gb2YgdGhlIFhNTCBkb2N1bWVudCB0byBiZSByZWFkLgorICAgICAqIEByZXR1cm4gIElmIHRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gaXMgYSBzeW5jaHJvbm91cworICAgICAqICAgPGNvZGU+TFNQYXJzZXI8L2NvZGU+LCB0aGUgbmV3bHkgY3JlYXRlZCBhbmQgcG9wdWxhdGVkCisgICAgICogICA8Y29kZT5Eb2N1bWVudDwvY29kZT4gaXMgcmV0dXJuZWQsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIGFuIGVycm9yCisgICAgICogICBvY2N1cmVkLiBJZiB0aGUgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IGlzIGFzeW5jaHJvbm91cywKKyAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlzIHJldHVybmVkIHNpbmNlIHRoZSBkb2N1bWVudCBvYmplY3QgbWF5IG5vdCB5ZXQKKyAgICAgKiAgIGJlIGNvbnN0cnVjdGVkIHdoZW4gdGhpcyBtZXRob2QgcmV0dXJucy4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgIElOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgdGhlIDxjb2RlPkxTUGFyc2VyLmJ1c3k8L2NvZGU+CisgICAgICogICBhdHRyaWJ1dGUgaXMgPGNvZGU+dHJ1ZTwvY29kZT4uCisgICAgICogQGV4Y2VwdGlvbiBMU0V4Y2VwdGlvbgorICAgICAqICAgIFBBUlNFX0VSUjogUmFpc2VkIGlmIHRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gd2FzIHVuYWJsZSB0byBsb2FkCisgICAgICogICB0aGUgWE1MIGRvY3VtZW50LiBET00gYXBwbGljYXRpb25zIHNob3VsZCBhdHRhY2ggYQorICAgICAqICAgPGNvZGU+RE9NRXJyb3JIYW5kbGVyPC9jb2RlPiB1c2luZyB0aGUgcGFyYW1ldGVyICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItZXJyb3ItaGFuZGxlcic+CisgICAgICogICBlcnJvci1oYW5kbGVyPC9hPiIgaWYgdGhleSB3aXNoIHRvIGdldCBkZXRhaWxzIG9uIHRoZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgRG9jdW1lbnQgcGFyc2VVUkkoU3RyaW5nIHVyaSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiwgTFNFeGNlcHRpb247CisKKyAgICAvLyBBQ1RJT05fVFlQRVMKKyAgICAvKioKKyAgICAgKiAgQXBwZW5kIHRoZSByZXN1bHQgb2YgdGhlIHBhcnNlIG9wZXJhdGlvbiBhcyBjaGlsZHJlbiBvZiB0aGUgY29udGV4dAorICAgICAqIG5vZGUuIEZvciB0aGlzIGFjdGlvbiB0byB3b3JrLCB0aGUgY29udGV4dCBub2RlIG11c3QgYmUgYW4KKyAgICAgKiA8Y29kZT5FbGVtZW50PC9jb2RlPiBvciBhIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQUNUSU9OX0FQUEVORF9BU19DSElMRFJFTiA9IDE7CisgICAgLyoqCisgICAgICogIFJlcGxhY2UgYWxsIHRoZSBjaGlsZHJlbiBvZiB0aGUgY29udGV4dCBub2RlIHdpdGggdGhlIHJlc3VsdCBvZiB0aGUKKyAgICAgKiBwYXJzZSBvcGVyYXRpb24uIEZvciB0aGlzIGFjdGlvbiB0byB3b3JrLCB0aGUgY29udGV4dCBub2RlIG11c3QgYmUgYW4KKyAgICAgKiA8Y29kZT5FbGVtZW50PC9jb2RlPiwgYSA8Y29kZT5Eb2N1bWVudDwvY29kZT4sIG9yIGEKKyAgICAgKiA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEFDVElPTl9SRVBMQUNFX0NISUxEUkVOICAgPSAyOworICAgIC8qKgorICAgICAqICBJbnNlcnQgdGhlIHJlc3VsdCBvZiB0aGUgcGFyc2Ugb3BlcmF0aW9uIGFzIHRoZSBpbW1lZGlhdGVseSBwcmVjZWRpbmcKKyAgICAgKiBzaWJsaW5nIG9mIHRoZSBjb250ZXh0IG5vZGUuIEZvciB0aGlzIGFjdGlvbiB0byB3b3JrIHRoZSBjb250ZXh0CisgICAgICogbm9kZSdzIHBhcmVudCBtdXN0IGJlIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG9yIGEKKyAgICAgKiA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEFDVElPTl9JTlNFUlRfQkVGT1JFICAgICAgPSAzOworICAgIC8qKgorICAgICAqICBJbnNlcnQgdGhlIHJlc3VsdCBvZiB0aGUgcGFyc2Ugb3BlcmF0aW9uIGFzIHRoZSBpbW1lZGlhdGVseSBmb2xsb3dpbmcKKyAgICAgKiBzaWJsaW5nIG9mIHRoZSBjb250ZXh0IG5vZGUuIEZvciB0aGlzIGFjdGlvbiB0byB3b3JrIHRoZSBjb250ZXh0CisgICAgICogbm9kZSdzIHBhcmVudCBtdXN0IGJlIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG9yIGEKKyAgICAgKiA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEFDVElPTl9JTlNFUlRfQUZURVIgICAgICAgPSA0OworICAgIC8qKgorICAgICAqICBSZXBsYWNlIHRoZSBjb250ZXh0IG5vZGUgd2l0aCB0aGUgcmVzdWx0IG9mIHRoZSBwYXJzZSBvcGVyYXRpb24uIEZvcgorICAgICAqIHRoaXMgYWN0aW9uIHRvIHdvcmssIHRoZSBjb250ZXh0IG5vZGUgbXVzdCBoYXZlIGEgcGFyZW50LCBhbmQgdGhlCisgICAgICogcGFyZW50IG11c3QgYmUgYW4gPGNvZGU+RWxlbWVudDwvY29kZT4gb3IgYQorICAgICAqIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQUNUSU9OX1JFUExBQ0UgICAgICAgICAgICA9IDU7CisKKyAgICAvKioKKyAgICAgKiAgUGFyc2UgYW4gWE1MIGZyYWdtZW50IGZyb20gYSByZXNvdXJjZSBpZGVudGlmaWVkIGJ5IGEKKyAgICAgKiA8Y29kZT5MU0lucHV0PC9jb2RlPiBhbmQgaW5zZXJ0IHRoZSBjb250ZW50IGludG8gYW4gZXhpc3RpbmcgZG9jdW1lbnQKKyAgICAgKiBhdCB0aGUgcG9zaXRpb24gc3BlY2lmaWVkIHdpdGggdGhlIDxjb2RlPmNvbnRleHQ8L2NvZGU+IGFuZAorICAgICAqIDxjb2RlPmFjdGlvbjwvY29kZT4gYXJndW1lbnRzLiBXaGVuIHBhcnNpbmcgdGhlIGlucHV0IHN0cmVhbSwgdGhlCisgICAgICogY29udGV4dCBub2RlIChvciBpdHMgcGFyZW50LCBkZXBlbmRpbmcgb24gd2hlcmUgdGhlIHJlc3VsdCB3aWxsIGJlCisgICAgICogaW5zZXJ0ZWQpIGlzIHVzZWQgZm9yIHJlc29sdmluZyB1bmJvdW5kIG5hbWVzcGFjZSBwcmVmaXhlcy4gVGhlCisgICAgICogY29udGV4dCBub2RlJ3MgPGNvZGU+b3duZXJEb2N1bWVudDwvY29kZT4gbm9kZSAob3IgdGhlIG5vZGUgaXRzZWxmIGlmCisgICAgICogdGhlIG5vZGUgb2YgdHlwZSA8Y29kZT5ET0NVTUVOVF9OT0RFPC9jb2RlPikgaXMgdXNlZCB0byByZXNvbHZlCisgICAgICogZGVmYXVsdCBhdHRyaWJ1dGVzIGFuZCBlbnRpdHkgcmVmZXJlbmNlcy4KKyAgICAgKiA8YnI+IEFzIHRoZSBuZXcgZGF0YSBpcyBpbnNlcnRlZCBpbnRvIHRoZSBkb2N1bWVudCwgYXQgbGVhc3Qgb25lCisgICAgICogbXV0YXRpb24gZXZlbnQgaXMgZmlyZWQgcGVyIG5ldyBpbW1lZGlhdGUgY2hpbGQgb3Igc2libGluZyBvZiB0aGUKKyAgICAgKiBjb250ZXh0IG5vZGUuCisgICAgICogPGJyPiBJZiB0aGUgY29udGV4dCBub2RlIGlzIGEgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG5vZGUgYW5kIHRoZSBhY3Rpb24KKyAgICAgKiBpcyA8Y29kZT5BQ1RJT05fUkVQTEFDRV9DSElMRFJFTjwvY29kZT4sIHRoZW4gdGhlIGRvY3VtZW50IHRoYXQgaXMKKyAgICAgKiBwYXNzZWQgYXMgdGhlIGNvbnRleHQgbm9kZSB3aWxsIGJlIGNoYW5nZWQgc3VjaCB0aGF0IGl0cworICAgICAqIDxjb2RlPnhtbEVuY29kaW5nPC9jb2RlPiwgPGNvZGU+ZG9jdW1lbnRVUkk8L2NvZGU+LAorICAgICAqIDxjb2RlPnhtbFZlcnNpb248L2NvZGU+LCA8Y29kZT5pbnB1dEVuY29kaW5nPC9jb2RlPiwKKyAgICAgKiA8Y29kZT54bWxTdGFuZGFsb25lPC9jb2RlPiwgYW5kIGFsbCBvdGhlciBzdWNoIGF0dHJpYnV0ZXMgYXJlIHNldCB0bworICAgICAqIHdoYXQgdGhleSB3b3VsZCBiZSBzZXQgdG8gaWYgdGhlIGlucHV0IHNvdXJjZSB3YXMgcGFyc2VkIHVzaW5nCisgICAgICogPGNvZGU+TFNQYXJzZXIucGFyc2UoKTwvY29kZT4uCisgICAgICogPGJyPiBUaGlzIG1ldGhvZCBpcyBhbHdheXMgc3luY2hyb25vdXMsIGV2ZW4gaWYgdGhlCisgICAgICogPGNvZGU+TFNQYXJzZXI8L2NvZGU+IGlzIGFzeW5jaHJvbm91cyAoPGNvZGU+TFNQYXJzZXIuYXN5bmM8L2NvZGU+IGlzCisgICAgICogPGNvZGU+dHJ1ZTwvY29kZT4pLgorICAgICAqIDxicj4gSWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHBhcnNpbmcsIHRoZSBjYWxsZXIgaXMgbm90aWZpZWQgdGhyb3VnaAorICAgICAqIHRoZSA8Y29kZT5FcnJvckhhbmRsZXI8L2NvZGU+IGluc3RhbmNlIGFzc29jaWF0ZWQgd2l0aCB0aGUgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lcnJvci1oYW5kbGVyJz4KKyAgICAgKiBlcnJvci1oYW5kbGVyPC9hPiIgcGFyYW1ldGVyIG9mIHRoZSA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPi4KKyAgICAgKiA8YnI+IFdoZW4gY2FsbGluZyA8Y29kZT5wYXJzZVdpdGhDb250ZXh0PC9jb2RlPiwgdGhlIHZhbHVlcyBvZiB0aGUKKyAgICAgKiBmb2xsb3dpbmcgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXJzIHdpbGwgYmUgaWdub3JlZCBhbmQgdGhlaXIgZGVmYXVsdAorICAgICAqIHZhbHVlcyB3aWxsIGFsd2F5cyBiZSB1c2VkIGluc3RlYWQ6ICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItdmFsaWRhdGUnPgorICAgICAqIHZhbGlkYXRlPC9hPiIsICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItdmFsaWRhdGUtaWYtc2NoZW1hJz4KKyAgICAgKiB2YWxpZGF0ZS1pZi1zY2hlbWE8L2E+IiwgYW5kICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItZWxlbWVudC1jb250ZW50LXdoaXRlc3BhY2UnPgorICAgICAqIGVsZW1lbnQtY29udGVudC13aGl0ZXNwYWNlPC9hPiIuIE90aGVyIHBhcmFtZXRlcnMgd2lsbCBiZSB0cmVhdGVkIG5vcm1hbGx5LCBhbmQgdGhlIHBhcnNlciBpcyBleHBlY3RlZAorICAgICAqIHRvIGNhbGwgdGhlIDxjb2RlPkxTUGFyc2VyRmlsdGVyPC9jb2RlPiBqdXN0IGFzIGlmIGEgd2hvbGUgZG9jdW1lbnQKKyAgICAgKiB3YXMgcGFyc2VkLgorICAgICAqIEBwYXJhbSBpbnB1dCAgVGhlIDxjb2RlPkxTSW5wdXQ8L2NvZGU+IGZyb20gd2hpY2ggdGhlIHNvdXJjZSBkb2N1bWVudAorICAgICAqICAgaXMgdG8gYmUgcmVhZC4gVGhlIHNvdXJjZSBkb2N1bWVudCBtdXN0IGJlIGFuIFhNTCBmcmFnbWVudCwgaS5lLgorICAgICAqICAgYW55dGhpbmcgZXhjZXB0IGEgY29tcGxldGUgWE1MIGRvY3VtZW50IChleGNlcHQgaW4gdGhlIGNhc2Ugd2hlcmUKKyAgICAgKiAgIHRoZSBjb250ZXh0IG5vZGUgb2YgdHlwZSA8Y29kZT5ET0NVTUVOVF9OT0RFPC9jb2RlPiwgYW5kIHRoZSBhY3Rpb24KKyAgICAgKiAgIGlzIDxjb2RlPkFDVElPTl9SRVBMQUNFX0NISUxEUkVOPC9jb2RlPiksIGEgRE9DVFlQRSAoaW50ZXJuYWwKKyAgICAgKiAgIHN1YnNldCksIGVudGl0eSBkZWNsYXJhdGlvbihzKSwgbm90YXRpb24gZGVjbGFyYXRpb24ocyksIG9yIFhNTCBvcgorICAgICAqICAgdGV4dCBkZWNsYXJhdGlvbihzKS4KKyAgICAgKiBAcGFyYW0gY29udGV4dEFyZyAgVGhlIG5vZGUgdGhhdCBpcyB1c2VkIGFzIHRoZSBjb250ZXh0IGZvciB0aGUgZGF0YQorICAgICAqICAgdGhhdCBpcyBiZWluZyBwYXJzZWQuIFRoaXMgbm9kZSBtdXN0IGJlIGEgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+CisgICAgICogICBub2RlLCBhIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IG5vZGUsIG9yIGEgbm9kZSBvZiBhIHR5cGUKKyAgICAgKiAgIHRoYXQgaXMgYWxsb3dlZCBhcyBhIGNoaWxkIG9mIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG5vZGUsIGUuZy4gaXQKKyAgICAgKiAgIGNhbm5vdCBiZSBhbiA8Y29kZT5BdHRyaWJ1dGU8L2NvZGU+IG5vZGUuCisgICAgICogQHBhcmFtIGFjdGlvbiAgVGhpcyBwYXJhbWV0ZXIgZGVzY3JpYmVzIHdoaWNoIGFjdGlvbiBzaG91bGQgYmUgdGFrZW4KKyAgICAgKiAgIGJldHdlZW4gdGhlIG5ldyBzZXQgb2Ygbm9kZXMgYmVpbmcgaW5zZXJ0ZWQgYW5kIHRoZSBleGlzdGluZworICAgICAqICAgY2hpbGRyZW4gb2YgdGhlIGNvbnRleHQgbm9kZS4gVGhlIHNldCBvZiBwb3NzaWJsZSBhY3Rpb25zIGlzCisgICAgICogICBkZWZpbmVkIGluIDxjb2RlPkFDVElPTl9UWVBFUzwvY29kZT4gYWJvdmUuCisgICAgICogQHJldHVybiAgUmV0dXJuIHRoZSBub2RlIHRoYXQgaXMgdGhlIHJlc3VsdCBvZiB0aGUgcGFyc2Ugb3BlcmF0aW9uLiBJZgorICAgICAqICAgdGhlIHJlc3VsdCBpcyBtb3JlIHRoYW4gb25lIHRvcC1sZXZlbCBub2RlLCB0aGUgZmlyc3Qgb25lIGlzCisgICAgICogICByZXR1cm5lZC4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgSElFUkFSQ0hZX1JFUVVFU1RfRVJSOiBSYWlzZWQgaWYgdGhlIGNvbnRlbnQgY2Fubm90IHJlcGxhY2UsIGJlCisgICAgICogICBpbnNlcnRlZCBiZWZvcmUsIGFmdGVyLCBvciBhcyBhIGNoaWxkIG9mIHRoZSBjb250ZXh0IG5vZGUgKHNlZSBhbHNvCisgICAgICogICA8Y29kZT5Ob2RlLmluc2VydEJlZm9yZTwvY29kZT4gb3IgPGNvZGU+Tm9kZS5yZXBsYWNlQ2hpbGQ8L2NvZGU+IGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5ET00gTGV2ZWwgMyBDb3JlPC9hPl0KKyAgICAgKiAgICkuCisgICAgICogICA8YnI+IE5PVF9TVVBQT1JURURfRVJSOiBSYWlzZWQgaWYgdGhlIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiBkb2Vzbid0CisgICAgICogICBzdXBwb3J0IHRoaXMgbWV0aG9kLCBvciBpZiB0aGUgY29udGV4dCBub2RlIGlzIG9mIHR5cGUKKyAgICAgKiAgIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBhbmQgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHN1cHBvcnQKKyAgICAgKiAgIHRoZSByZXBsYWNlbWVudCBvZiB0aGUgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBjaGlsZCBvcgorICAgICAqICAgPGNvZGU+RWxlbWVudDwvY29kZT4gY2hpbGQuCisgICAgICogICA8YnI+IE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoZSBjb250ZXh0IG5vZGUgaXMgYQorICAgICAqICAgcmVhZCBvbmx5IG5vZGUgYW5kIHRoZSBjb250ZW50IGlzIGJlaW5nIGFwcGVuZGVkIHRvIGl0cyBjaGlsZCBsaXN0LAorICAgICAqICAgb3IgaWYgdGhlIHBhcmVudCBub2RlIG9mIHRoZSBjb250ZXh0IG5vZGUgaXMgcmVhZCBvbmx5IG5vZGUgYW5kIHRoZQorICAgICAqICAgY29udGVudCBpcyBiZWluZyBpbnNlcnRlZCBpbiBpdHMgY2hpbGQgbGlzdC4KKyAgICAgKiAgIDxicj4gSU5WQUxJRF9TVEFURV9FUlI6IFJhaXNlZCBpZiB0aGUgPGNvZGU+TFNQYXJzZXIuYnVzeTwvY29kZT4KKyAgICAgKiAgIGF0dHJpYnV0ZSBpcyA8Y29kZT50cnVlPC9jb2RlPi4KKyAgICAgKiBAZXhjZXB0aW9uIExTRXhjZXB0aW9uCisgICAgICogICAgUEFSU0VfRVJSOiBSYWlzZWQgaWYgdGhlIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiB3YXMgdW5hYmxlIHRvIGxvYWQKKyAgICAgKiAgIHRoZSBYTUwgZnJhZ21lbnQuIERPTSBhcHBsaWNhdGlvbnMgc2hvdWxkIGF0dGFjaCBhCisgICAgICogICA8Y29kZT5ET01FcnJvckhhbmRsZXI8L2NvZGU+IHVzaW5nIHRoZSBwYXJhbWV0ZXIgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lcnJvci1oYW5kbGVyJz4KKyAgICAgKiAgIGVycm9yLWhhbmRsZXI8L2E+IiBpZiB0aGV5IHdpc2ggdG8gZ2V0IGRldGFpbHMgb24gdGhlIGVycm9yLgorICAgICAqLworICAgIHB1YmxpYyBOb2RlIHBhcnNlV2l0aENvbnRleHQoTFNJbnB1dCBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgY29udGV4dEFyZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IGFjdGlvbikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24sIExTRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogIEFib3J0IHRoZSBsb2FkaW5nIG9mIHRoZSBkb2N1bWVudCB0aGF0IGlzIGN1cnJlbnRseSBiZWluZyBsb2FkZWQgYnkKKyAgICAgKiB0aGUgPGNvZGU+TFNQYXJzZXI8L2NvZGU+LiBJZiB0aGUgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IGlzIGN1cnJlbnRseQorICAgICAqIG5vdCBidXN5LCBhIGNhbGwgdG8gdGhpcyBtZXRob2QgZG9lcyBub3RoaW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFib3J0KCk7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9scy9MU1BhcnNlckZpbHRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL2xzL0xTUGFyc2VyRmlsdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGJlZTFmZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9scy9MU1BhcnNlckZpbHRlci5qYXZhCkBAIC0wLDAgKzEsMTcyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKgorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCisgKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKKyAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0CisgKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKKyAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KKyAqCisgKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQorICovCisKK3BhY2thZ2Ugb3JnLnczYy5kb20ubHM7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CisKKy8qKgorICogIDxjb2RlPkxTUGFyc2VyRmlsdGVyPC9jb2RlPnMgcHJvdmlkZSBhcHBsaWNhdGlvbnMgdGhlIGFiaWxpdHkgdG8gZXhhbWluZQorICogbm9kZXMgYXMgdGhleSBhcmUgYmVpbmcgY29uc3RydWN0ZWQgd2hpbGUgcGFyc2luZy4gQXMgZWFjaCBub2RlIGlzCisgKiBleGFtaW5lZCwgaXQgbWF5IGJlIG1vZGlmaWVkIG9yIHJlbW92ZWQsIG9yIHRoZSBlbnRpcmUgcGFyc2UgbWF5IGJlCisgKiB0ZXJtaW5hdGVkIGVhcmx5LgorICogPHA+IEF0IHRoZSB0aW1lIGFueSBvZiB0aGUgZmlsdGVyIG1ldGhvZHMgYXJlIGNhbGxlZCBieSB0aGUgcGFyc2VyLCB0aGUKKyAqIG93bmVyIERvY3VtZW50IGFuZCBET01JbXBsZW1lbnRhdGlvbiBvYmplY3RzIGV4aXN0IGFuZCBhcmUgYWNjZXNzaWJsZS4KKyAqIFRoZSBkb2N1bWVudCBlbGVtZW50IGlzIG5ldmVyIHBhc3NlZCB0byB0aGUgPGNvZGU+TFNQYXJzZXJGaWx0ZXI8L2NvZGU+CisgKiBtZXRob2RzLCBpLmUuIGl0IGlzIG5vdCBwb3NzaWJsZSB0byBmaWx0ZXIgb3V0IHRoZSBkb2N1bWVudCBlbGVtZW50LgorICogPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LCA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+LCA8Y29kZT5Ob3RhdGlvbjwvY29kZT4sCisgKiA8Y29kZT5FbnRpdHk8L2NvZGU+LCBhbmQgPGNvZGU+QXR0cjwvY29kZT4gbm9kZXMgYXJlIG5ldmVyIHBhc3NlZCB0byB0aGUKKyAqIDxjb2RlPmFjY2VwdE5vZGU8L2NvZGU+IG1ldGhvZCBvbiB0aGUgZmlsdGVyLiBUaGUgY2hpbGQgbm9kZXMgb2YgYW4KKyAqIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZSBhcmUgcGFzc2VkIHRvIHRoZSBmaWx0ZXIgaWYgdGhlCisgKiBwYXJhbWV0ZXIgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lbnRpdGllcyc+CisgKiBlbnRpdGllczwvYT4iIGlzIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4uIE5vdGUgdGhhdCwgYXMgZGVzY3JpYmVkIGJ5IHRoZSBwYXJhbWV0ZXIgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lbnRpdGllcyc+CisgKiBlbnRpdGllczwvYT4iLCB1bmV4cGFuZGVkIGVudGl0eSByZWZlcmVuY2Ugbm9kZXMgYXJlIG5ldmVyIGRpc2NhcmRlZCBhbmQgYXJlIGFsd2F5cworICogcGFzc2VkIHRvIHRoZSBmaWx0ZXIuCisgKiA8cD4gQWxsIHZhbGlkaXR5IGNoZWNraW5nIHdoaWxlIHBhcnNpbmcgYSBkb2N1bWVudCBvY2N1cnMgb24gdGhlIHNvdXJjZQorICogZG9jdW1lbnQgYXMgaXQgYXBwZWFycyBvbiB0aGUgaW5wdXQgc3RyZWFtLCBub3Qgb24gdGhlIERPTSBkb2N1bWVudCBhcyBpdAorICogaXMgYnVpbHQgaW4gbWVtb3J5LiBXaXRoIGZpbHRlcnMsIHRoZSBkb2N1bWVudCBpbiBtZW1vcnkgbWF5IGJlIGEgc3Vic2V0CisgKiBvZiB0aGUgZG9jdW1lbnQgb24gdGhlIHN0cmVhbSwgYW5kIGl0cyB2YWxpZGl0eSBtYXkgaGF2ZSBiZWVuIGFmZmVjdGVkIGJ5CisgKiB0aGUgZmlsdGVyaW5nLgorICogPHA+IEFsbCBkZWZhdWx0IGF0dHJpYnV0ZXMgbXVzdCBiZSBwcmVzZW50IG9uIGVsZW1lbnRzIHdoZW4gdGhlIGVsZW1lbnRzCisgKiBhcmUgcGFzc2VkIHRvIHRoZSBmaWx0ZXIgbWV0aG9kcy4gQWxsIG90aGVyIGRlZmF1bHQgY29udGVudCBtdXN0IGJlCisgKiBwYXNzZWQgdG8gdGhlIGZpbHRlciBtZXRob2RzLgorICogPHA+IERPTSBhcHBsaWNhdGlvbnMgbXVzdCBub3QgcmFpc2UgZXhjZXB0aW9ucyBpbiBhIGZpbHRlci4gVGhlIGVmZmVjdCBvZgorICogdGhyb3dpbmcgZXhjZXB0aW9ucyBmcm9tIGEgZmlsdGVyIGlzIERPTSBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuCisgKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtTFMtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIExvYWQKK2FuZCBTYXZlIFNwZWNpZmljYXRpb248L2E+LgorICovCitwdWJsaWMgaW50ZXJmYWNlIExTUGFyc2VyRmlsdGVyIHsKKyAgICAvLyBDb25zdGFudHMgcmV0dXJuZWQgYnkgc3RhcnRFbGVtZW50IGFuZCBhY2NlcHROb2RlCisgICAgLyoqCisgICAgICogQWNjZXB0IHRoZSBub2RlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRklMVEVSX0FDQ0VQVCAgICAgICAgICAgICA9IDE7CisgICAgLyoqCisgICAgICogUmVqZWN0IHRoZSBub2RlIGFuZCBpdHMgY2hpbGRyZW4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGSUxURVJfUkVKRUNUICAgICAgICAgICAgID0gMjsKKyAgICAvKioKKyAgICAgKiBTa2lwIHRoaXMgc2luZ2xlIG5vZGUuIFRoZSBjaGlsZHJlbiBvZiB0aGlzIG5vZGUgd2lsbCBzdGlsbCBiZQorICAgICAqIGNvbnNpZGVyZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGSUxURVJfU0tJUCAgICAgICAgICAgICAgID0gMzsKKyAgICAvKioKKyAgICAgKiAgSW50ZXJydXB0IHRoZSBub3JtYWwgcHJvY2Vzc2luZyBvZiB0aGUgZG9jdW1lbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGSUxURVJfSU5URVJSVVBUICAgICAgICAgID0gNDsKKworICAgIC8qKgorICAgICAqICBUaGUgcGFyc2VyIHdpbGwgY2FsbCB0aGlzIG1ldGhvZCBhZnRlciBlYWNoIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IHN0YXJ0CisgICAgICogdGFnIGhhcyBiZWVuIHNjYW5uZWQsIGJ1dCBiZWZvcmUgdGhlIHJlbWFpbmRlciBvZiB0aGUKKyAgICAgKiA8Y29kZT5FbGVtZW50PC9jb2RlPiBpcyBwcm9jZXNzZWQuIFRoZSBpbnRlbnQgaXMgdG8gYWxsb3cgdGhlCisgICAgICogZWxlbWVudCwgaW5jbHVkaW5nIGFueSBjaGlsZHJlbiwgdG8gYmUgZWZmaWNpZW50bHkgc2tpcHBlZC4gTm90ZSB0aGF0CisgICAgICogb25seSBlbGVtZW50IG5vZGVzIGFyZSBwYXNzZWQgdG8gdGhlIDxjb2RlPnN0YXJ0RWxlbWVudDwvY29kZT4KKyAgICAgKiBmdW5jdGlvbi4KKyAgICAgKiA8YnI+VGhlIGVsZW1lbnQgbm9kZSBwYXNzZWQgdG8gPGNvZGU+c3RhcnRFbGVtZW50PC9jb2RlPiBmb3IgZmlsdGVyaW5nCisgICAgICogd2lsbCBpbmNsdWRlIGFsbCBvZiB0aGUgRWxlbWVudCdzIGF0dHJpYnV0ZXMsIGJ1dCBub25lIG9mIHRoZQorICAgICAqIGNoaWxkcmVuIG5vZGVzLiBUaGUgRWxlbWVudCBtYXkgbm90IHlldCBiZSBpbiBwbGFjZSBpbiB0aGUgZG9jdW1lbnQKKyAgICAgKiBiZWluZyBjb25zdHJ1Y3RlZCAoaXQgbWF5IG5vdCBoYXZlIGEgcGFyZW50IG5vZGUuKQorICAgICAqIDxicj5BIDxjb2RlPnN0YXJ0RWxlbWVudDwvY29kZT4gZmlsdGVyIGZ1bmN0aW9uIG1heSBhY2Nlc3Mgb3IgY2hhbmdlCisgICAgICogdGhlIGF0dHJpYnV0ZXMgZm9yIHRoZSBFbGVtZW50LiBDaGFuZ2luZyBOYW1lc3BhY2UgZGVjbGFyYXRpb25zIHdpbGwKKyAgICAgKiBoYXZlIG5vIGVmZmVjdCBvbiBuYW1lc3BhY2UgcmVzb2x1dGlvbiBieSB0aGUgcGFyc2VyLgorICAgICAqIDxicj5Gb3IgZWZmaWNpZW5jeSwgdGhlIEVsZW1lbnQgbm9kZSBwYXNzZWQgdG8gdGhlIGZpbHRlciBtYXkgbm90IGJlCisgICAgICogdGhlIHNhbWUgb25lIGFzIGlzIGFjdHVhbGx5IHBsYWNlZCBpbiB0aGUgdHJlZSBpZiB0aGUgbm9kZSBpcworICAgICAqIGFjY2VwdGVkLiBBbmQgdGhlIGFjdHVhbCBub2RlIChub2RlIG9iamVjdCBpZGVudGl0eSkgbWF5IGJlIHJldXNlZAorICAgICAqIGR1cmluZyB0aGUgcHJvY2VzcyBvZiByZWFkaW5nIGluIGFuZCBmaWx0ZXJpbmcgYSBkb2N1bWVudC4KKyAgICAgKiBAcGFyYW0gZWxlbWVudEFyZyBUaGUgbmV3bHkgZW5jb3VudGVyZWQgZWxlbWVudC4gQXQgdGhlIHRpbWUgdGhpcworICAgICAqICAgbWV0aG9kIGlzIGNhbGxlZCwgdGhlIGVsZW1lbnQgaXMgaW5jb21wbGV0ZSAtIGl0IHdpbGwgaGF2ZSBpdHMKKyAgICAgKiAgIGF0dHJpYnV0ZXMsIGJ1dCBubyBjaGlsZHJlbi4KKyAgICAgKiBAcmV0dXJuCisgICAgICogPHVsPgorICAgICAqIDxsaT4gPGNvZGU+RklMVEVSX0FDQ0VQVDwvY29kZT4gaWYgdGhlIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IHNob3VsZAorICAgICAqICAgYmUgaW5jbHVkZWQgaW4gdGhlIERPTSBkb2N1bWVudCBiZWluZyBidWlsdC4KKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT4KKyAgICAgKiAgIDxjb2RlPkZJTFRFUl9SRUpFQ1Q8L2NvZGU+IGlmIHRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiBhbmQgYWxsIG9mCisgICAgICogICBpdHMgY2hpbGRyZW4gc2hvdWxkIGJlIHJlamVjdGVkLgorICAgICAqIDwvbGk+CisgICAgICogPGxpPiA8Y29kZT5GSUxURVJfU0tJUDwvY29kZT4gaWYgdGhlCisgICAgICogICA8Y29kZT5FbGVtZW50PC9jb2RlPiBzaG91bGQgYmUgc2tpcHBlZC4gQWxsIG9mIGl0cyBjaGlsZHJlbiBhcmUKKyAgICAgKiAgIGluc2VydGVkIGluIHBsYWNlIG9mIHRoZSBza2lwcGVkIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG5vZGUuCisgICAgICogPC9saT4KKyAgICAgKiA8bGk+CisgICAgICogICA8Y29kZT5GSUxURVJfSU5URVJSVVBUPC9jb2RlPiBpZiB0aGUgZmlsdGVyIHdhbnRzIHRvIHN0b3AgdGhlCisgICAgICogICBwcm9jZXNzaW5nIG9mIHRoZSBkb2N1bWVudC4gSW50ZXJydXB0aW5nIHRoZSBwcm9jZXNzaW5nIG9mIHRoZQorICAgICAqICAgZG9jdW1lbnQgZG9lcyBubyBsb25nZXIgZ3VhcmFudGVlIHRoYXQgdGhlIHJlc3VsdGluZyBET00gdHJlZSBpcworICAgICAqICAgWE1MIHdlbGwtZm9ybWVkLiBUaGUgPGNvZGU+RWxlbWVudDwvY29kZT4gaXMgcmVqZWN0ZWQuCisgICAgICogPC9saT4KKyAgICAgKiA8L3VsPiBSZXR1cm5pbmcKKyAgICAgKiAgIGFueSBvdGhlciB2YWx1ZXMgd2lsbCByZXN1bHQgaW4gdW5zcGVjaWZpZWQgYmVoYXZpb3IuCisgICAgICovCisgICAgcHVibGljIHNob3J0IHN0YXJ0RWxlbWVudChFbGVtZW50IGVsZW1lbnRBcmcpOworCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgYnkgdGhlIHBhcnNlciBhdCB0aGUgY29tcGxldGlvbiBvZiB0aGUKKyAgICAgKiBwYXJzaW5nIG9mIGVhY2ggbm9kZS4gVGhlIG5vZGUgYW5kIGFsbCBvZiBpdHMgZGVzY2VuZGFudHMgd2lsbCBleGlzdAorICAgICAqIGFuZCBiZSBjb21wbGV0ZS4gVGhlIHBhcmVudCBub2RlIHdpbGwgYWxzbyBleGlzdCwgYWx0aG91Z2ggaXQgbWF5IGJlCisgICAgICogaW5jb21wbGV0ZSwgaS5lLiBpdCBtYXkgaGF2ZSBhZGRpdGlvbmFsIGNoaWxkcmVuIHRoYXQgaGF2ZSBub3QgeWV0CisgICAgICogYmVlbiBwYXJzZWQuIEF0dHJpYnV0ZSBub2RlcyBhcmUgbmV2ZXIgcGFzc2VkIHRvIHRoaXMgZnVuY3Rpb24uCisgICAgICogPGJyPkZyb20gd2l0aGluIHRoaXMgbWV0aG9kLCB0aGUgbmV3IG5vZGUgbWF5IGJlIGZyZWVseSBtb2RpZmllZCAtCisgICAgICogY2hpbGRyZW4gbWF5IGJlIGFkZGVkIG9yIHJlbW92ZWQsIHRleHQgbm9kZXMgbW9kaWZpZWQsIGV0Yy4gVGhlIHN0YXRlCisgICAgICogb2YgdGhlIHJlc3Qgb2YgdGhlIGRvY3VtZW50IG91dHNpZGUgdGhpcyBub2RlIGlzIG5vdCBkZWZpbmVkLCBhbmQgdGhlCisgICAgICogYWZmZWN0IG9mIGFueSBhdHRlbXB0IHRvIG5hdmlnYXRlIHRvLCBvciB0byBtb2RpZnkgYW55IG90aGVyIHBhcnQgb2YKKyAgICAgKiB0aGUgZG9jdW1lbnQgaXMgdW5kZWZpbmVkLgorICAgICAqIDxicj5Gb3IgdmFsaWRhdGluZyBwYXJzZXJzLCB0aGUgY2hlY2tzIGFyZSBtYWRlIG9uIHRoZSBvcmlnaW5hbAorICAgICAqIGRvY3VtZW50LCBiZWZvcmUgYW55IG1vZGlmaWNhdGlvbiBieSB0aGUgZmlsdGVyLiBObyB2YWxpZGl0eSBjaGVja3MKKyAgICAgKiBhcmUgbWFkZSBvbiBhbnkgZG9jdW1lbnQgbW9kaWZpY2F0aW9ucyBtYWRlIGJ5IHRoZSBmaWx0ZXIuCisgICAgICogPGJyPklmIHRoaXMgbmV3IG5vZGUgaXMgcmVqZWN0ZWQsIHRoZSBwYXJzZXIgbWlnaHQgcmV1c2UgdGhlIG5ldyBub2RlCisgICAgICogYW5kIGFueSBvZiBpdHMgZGVzY2VuZGFudHMuCisgICAgICogQHBhcmFtIG5vZGVBcmcgVGhlIG5ld2x5IGNvbnN0cnVjdGVkIGVsZW1lbnQuIEF0IHRoZSB0aW1lIHRoaXMgbWV0aG9kCisgICAgICogICBpcyBjYWxsZWQsIHRoZSBlbGVtZW50IGlzIGNvbXBsZXRlIC0gaXQgaGFzIGFsbCBvZiBpdHMgY2hpbGRyZW4KKyAgICAgKiAgIChhbmQgdGhlaXIgY2hpbGRyZW4sIHJlY3Vyc2l2ZWx5KSBhbmQgYXR0cmlidXRlcywgYW5kIGlzIGF0dGFjaGVkCisgICAgICogICBhcyBhIGNoaWxkIHRvIGl0cyBwYXJlbnQuCisgICAgICogQHJldHVybgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+IDxjb2RlPkZJTFRFUl9BQ0NFUFQ8L2NvZGU+IGlmIHRoaXMgPGNvZGU+Tm9kZTwvY29kZT4gc2hvdWxkCisgICAgICogICBiZSBpbmNsdWRlZCBpbiB0aGUgRE9NIGRvY3VtZW50IGJlaW5nIGJ1aWx0LgorICAgICAqIDwvbGk+CisgICAgICogPGxpPgorICAgICAqICAgPGNvZGU+RklMVEVSX1JFSkVDVDwvY29kZT4gaWYgdGhlIDxjb2RlPk5vZGU8L2NvZGU+IGFuZCBhbGwgb2YgaXRzCisgICAgICogICBjaGlsZHJlbiBzaG91bGQgYmUgcmVqZWN0ZWQuCisgICAgICogPC9saT4KKyAgICAgKiA8bGk+IDxjb2RlPkZJTFRFUl9TS0lQPC9jb2RlPiBpZiB0aGUKKyAgICAgKiAgIDxjb2RlPk5vZGU8L2NvZGU+IHNob3VsZCBiZSBza2lwcGVkIGFuZCB0aGUgPGNvZGU+Tm9kZTwvY29kZT4KKyAgICAgKiAgIHNob3VsZCBiZSByZXBsYWNlZCBieSBhbGwgdGhlIGNoaWxkcmVuIG9mIHRoZSA8Y29kZT5Ob2RlPC9jb2RlPi4KKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT4KKyAgICAgKiAgIDxjb2RlPkZJTFRFUl9JTlRFUlJVUFQ8L2NvZGU+IGlmIHRoZSBmaWx0ZXIgd2FudHMgdG8gc3RvcCB0aGUKKyAgICAgKiAgIHByb2Nlc3Npbmcgb2YgdGhlIGRvY3VtZW50LiBJbnRlcnJ1cHRpbmcgdGhlIHByb2Nlc3Npbmcgb2YgdGhlCisgICAgICogICBkb2N1bWVudCBkb2VzIG5vIGxvbmdlciBndWFyYW50ZWUgdGhhdCB0aGUgcmVzdWx0aW5nIERPTSB0cmVlIGlzCisgICAgICogICBYTUwgd2VsbC1mb3JtZWQuIFRoZSA8Y29kZT5Ob2RlPC9jb2RlPiBpcyBhY2NlcHRlZCBhbmQgd2lsbCBiZSB0aGUKKyAgICAgKiAgIGxhc3QgY29tcGxldGVseSBwYXJzZWQgbm9kZS4KKyAgICAgKiA8L2xpPgorICAgICAqIDwvdWw+CisgICAgICovCisgICAgcHVibGljIHNob3J0IGFjY2VwdE5vZGUoTm9kZSBub2RlQXJnKTsKKworICAgIC8qKgorICAgICAqICBUZWxscyB0aGUgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IHdoYXQgdHlwZXMgb2Ygbm9kZXMgdG8gc2hvdyB0byB0aGUKKyAgICAgKiBtZXRob2QgPGNvZGU+TFNQYXJzZXJGaWx0ZXIuYWNjZXB0Tm9kZTwvY29kZT4uIElmIGEgbm9kZSBpcyBub3Qgc2hvd24KKyAgICAgKiB0byB0aGUgZmlsdGVyIHVzaW5nIHRoaXMgYXR0cmlidXRlLCBpdCBpcyBhdXRvbWF0aWNhbGx5IGluY2x1ZGVkIGluCisgICAgICogdGhlIERPTSBkb2N1bWVudCBiZWluZyBidWlsdC4gU2VlIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IGZvcgorICAgICAqIGRlZmluaXRpb24gb2YgdGhlIGNvbnN0YW50cy4gVGhlIGNvbnN0YW50cyA8Y29kZT5TSE9XX0FUVFJJQlVURTwvY29kZT4KKyAgICAgKiAsIDxjb2RlPlNIT1dfRE9DVU1FTlQ8L2NvZGU+LCA8Y29kZT5TSE9XX0RPQ1VNRU5UX1RZUEU8L2NvZGU+LAorICAgICAqIDxjb2RlPlNIT1dfTk9UQVRJT048L2NvZGU+LCA8Y29kZT5TSE9XX0VOVElUWTwvY29kZT4sIGFuZAorICAgICAqIDxjb2RlPlNIT1dfRE9DVU1FTlRfRlJBR01FTlQ8L2NvZGU+IGFyZSBtZWFuaW5nbGVzcyBoZXJlLiBUaG9zZSBub2RlcworICAgICAqIHdpbGwgbmV2ZXIgYmUgcGFzc2VkIHRvIDxjb2RlPkxTUGFyc2VyRmlsdGVyLmFjY2VwdE5vZGU8L2NvZGU+LgorICAgICAqIDxicj4gVGhlIGNvbnN0YW50cyB1c2VkIGhlcmUgYXJlIGRlZmluZWQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVRyYXZlcnNhbC1SYW5nZS0yMDAwMTExMyc+RE9NIExldmVsIDIgVHJhdmVyc2FsIGFuZCAgICAgIFJhbmdlPC9hPl0KKyAgICAgKiAuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRXaGF0VG9TaG93KCk7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9scy9MU1Jlc291cmNlUmVzb2x2ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9scy9MU1Jlc291cmNlUmVzb2x2ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MzAxYmViCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL2xzL0xTUmVzb3VyY2VSZXNvbHZlci5qYXZhCkBAIC0wLDAgKzEsODEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKKyAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcworICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKKyAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAorICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgorICoKKyAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbS5sczsKKworLyoqCisgKiAgPGNvZGU+TFNSZXNvdXJjZVJlc29sdmVyPC9jb2RlPiBwcm92aWRlcyBhIHdheSBmb3IgYXBwbGljYXRpb25zIHRvCisgKiByZWRpcmVjdCByZWZlcmVuY2VzIHRvIGV4dGVybmFsIHJlc291cmNlcy4KKyAqIDxwPiBBcHBsaWNhdGlvbnMgbmVlZGluZyB0byBpbXBsZW1lbnQgY3VzdG9tIGhhbmRsaW5nIGZvciBleHRlcm5hbAorICogcmVzb3VyY2VzIGNhbiBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UgYW5kIHJlZ2lzdGVyIHRoZWlyIGltcGxlbWVudGF0aW9uCisgKiBieSBzZXR0aW5nIHRoZSAicmVzb3VyY2UtcmVzb2x2ZXIiIHBhcmFtZXRlciBvZgorICogPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gb2JqZWN0cyBhdHRhY2hlZCB0byA8Y29kZT5MU1BhcnNlcjwvY29kZT4KKyAqIGFuZCA8Y29kZT5MU1NlcmlhbGl6ZXI8L2NvZGU+LiBJdCBjYW4gYWxzbyBiZSByZWdpc3RlciBvbgorICogPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gb2JqZWN0cyBhdHRhY2hlZCB0byA8Y29kZT5Eb2N1bWVudDwvY29kZT4KKyAqIGlmIHRoZSAiTFMiIGZlYXR1cmUgaXMgc3VwcG9ydGVkLgorICogPHA+IFRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gd2lsbCB0aGVuIGFsbG93IHRoZSBhcHBsaWNhdGlvbiB0byBpbnRlcmNlcHQKKyAqIGFueSBleHRlcm5hbCBlbnRpdGllcywgaW5jbHVkaW5nIHRoZSBleHRlcm5hbCBEVEQgc3Vic2V0IGFuZCBleHRlcm5hbAorICogcGFyYW1ldGVyIGVudGl0aWVzLCBiZWZvcmUgaW5jbHVkaW5nIHRoZW0uIFRoZSB0b3AtbGV2ZWwgZG9jdW1lbnQgZW50aXR5CisgKiBpcyBuZXZlciBwYXNzZWQgdG8gdGhlIDxjb2RlPnJlc29sdmVSZXNvdXJjZTwvY29kZT4gbWV0aG9kLgorICogPHA+IE1hbnkgRE9NIGFwcGxpY2F0aW9ucyB3aWxsIG5vdCBuZWVkIHRvIGltcGxlbWVudCB0aGlzIGludGVyZmFjZSwgYnV0IGl0CisgKiB3aWxsIGJlIGVzcGVjaWFsbHkgdXNlZnVsIGZvciBhcHBsaWNhdGlvbnMgdGhhdCBidWlsZCBYTUwgZG9jdW1lbnRzIGZyb20KKyAqIGRhdGFiYXNlcyBvciBvdGhlciBzcGVjaWFsaXplZCBpbnB1dCBzb3VyY2VzLCBvciBmb3IgYXBwbGljYXRpb25zIHRoYXQKKyAqIHVzZSBVUk5zLgorICogPHAgPjxiPk5vdGU6PC9iPiAgPGNvZGU+TFNSZXNvdXJjZVJlc29sdmVyPC9jb2RlPiBpcyBiYXNlZCBvbiB0aGUgU0FYMiBbPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZy8nPlNBWDwvYT5dIDxjb2RlPkVudGl0eVJlc29sdmVyPC9jb2RlPgorICogaW50ZXJmYWNlLgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUxTLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBMb2FkCithbmQgU2F2ZSBTcGVjaWZpY2F0aW9uPC9hPi4KKyAqLworcHVibGljIGludGVyZmFjZSBMU1Jlc291cmNlUmVzb2x2ZXIgeworICAgIC8qKgorICAgICAqICBBbGxvdyB0aGUgYXBwbGljYXRpb24gdG8gcmVzb2x2ZSBleHRlcm5hbCByZXNvdXJjZXMuCisgICAgICogPGJyPiBUaGUgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IHdpbGwgY2FsbCB0aGlzIG1ldGhvZCBiZWZvcmUgb3BlbmluZyBhbnkKKyAgICAgKiBleHRlcm5hbCByZXNvdXJjZSwgaW5jbHVkaW5nIHRoZSBleHRlcm5hbCBEVEQgc3Vic2V0LCBleHRlcm5hbAorICAgICAqIGVudGl0aWVzIHJlZmVyZW5jZWQgd2l0aGluIHRoZSBEVEQsIGFuZCBleHRlcm5hbCBlbnRpdGllcyByZWZlcmVuY2VkCisgICAgICogd2l0aGluIHRoZSBkb2N1bWVudCBlbGVtZW50IChob3dldmVyLCB0aGUgdG9wLWxldmVsIGRvY3VtZW50IGVudGl0eQorICAgICAqIGlzIG5vdCBwYXNzZWQgdG8gdGhpcyBtZXRob2QpLiBUaGUgYXBwbGljYXRpb24gbWF5IHRoZW4gcmVxdWVzdCB0aGF0CisgICAgICogdGhlIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiByZXNvbHZlIHRoZSBleHRlcm5hbCByZXNvdXJjZSBpdHNlbGYsIHRoYXQKKyAgICAgKiBpdCB1c2UgYW4gYWx0ZXJuYXRpdmUgVVJJLCBvciB0aGF0IGl0IHVzZSBhbiBlbnRpcmVseSBkaWZmZXJlbnQgaW5wdXQKKyAgICAgKiBzb3VyY2UuCisgICAgICogPGJyPiBBcHBsaWNhdGlvbiB3cml0ZXJzIGNhbiB1c2UgdGhpcyBtZXRob2QgdG8gcmVkaXJlY3QgZXh0ZXJuYWwKKyAgICAgKiBzeXN0ZW0gaWRlbnRpZmllcnMgdG8gc2VjdXJlIGFuZC9vciBsb2NhbCBVUkksIHRvIGxvb2sgdXAgcHVibGljCisgICAgICogaWRlbnRpZmllcnMgaW4gYSBjYXRhbG9ndWUsIG9yIHRvIHJlYWQgYW4gZW50aXR5IGZyb20gYSBkYXRhYmFzZSBvcgorICAgICAqIG90aGVyIGlucHV0IHNvdXJjZSAoaW5jbHVkaW5nLCBmb3IgZXhhbXBsZSwgYSBkaWFsb2cgYm94KS4KKyAgICAgKiBAcGFyYW0gdHlwZSAgVGhlIHR5cGUgb2YgdGhlIHJlc291cmNlIGJlaW5nIHJlc29sdmVkLiBGb3IgWE1MIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XSByZXNvdXJjZXMKKyAgICAgKiAgIChpLmUuIGVudGl0aWVzKSwgYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZQorICAgICAqICAgPGNvZGU+Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwiPC9jb2RlPi4gRm9yIFhNTCBTY2hlbWEgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvUkVDLXhtbHNjaGVtYS0xLTIwMDEwNTAyLyc+WE1MIFNjaGVtYSBQYXJ0IDE8L2E+XQorICAgICAqICAgLCBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlCisgICAgICogICA8Y29kZT4iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiPC9jb2RlPi4gT3RoZXIgdHlwZXMgb2YKKyAgICAgKiAgIHJlc291cmNlcyBhcmUgb3V0c2lkZSB0aGUgc2NvcGUgb2YgdGhpcyBzcGVjaWZpY2F0aW9uIGFuZCB0aGVyZWZvcmUKKyAgICAgKiAgIHNob3VsZCByZWNvbW1lbmQgYW4gYWJzb2x1dGUgVVJJIGluIG9yZGVyIHRvIHVzZSB0aGlzIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJICBUaGUgbmFtZXNwYWNlIG9mIHRoZSByZXNvdXJjZSBiZWluZyByZXNvbHZlZCwKKyAgICAgKiAgIGUuZy4gdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIFhNTCBTY2hlbWEgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvUkVDLXhtbHNjaGVtYS0xLTIwMDEwNTAyLyc+WE1MIFNjaGVtYSBQYXJ0IDE8L2E+XQorICAgICAqICAgIHdoZW4gcmVzb2x2aW5nIFhNTCBTY2hlbWEgcmVzb3VyY2VzLgorICAgICAqIEBwYXJhbSBwdWJsaWNJZCAgVGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBleHRlcm5hbCBlbnRpdHkgYmVpbmcKKyAgICAgKiAgIHJlZmVyZW5jZWQsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vIHB1YmxpYyBpZGVudGlmaWVyIHdhcworICAgICAqICAgc3VwcGxpZWQgb3IgaWYgdGhlIHJlc291cmNlIGlzIG5vdCBhbiBlbnRpdHkuCisgICAgICogQHBhcmFtIHN5c3RlbUlkICBUaGUgc3lzdGVtIGlkZW50aWZpZXIsIGEgVVJJIHJlZmVyZW5jZSBbPGEgaHJlZj0naHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjM5Ni50eHQnPklFVEYgUkZDIDIzOTY8L2E+XSwgb2YgdGhlCisgICAgICogICBleHRlcm5hbCByZXNvdXJjZSBiZWluZyByZWZlcmVuY2VkLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBubworICAgICAqICAgc3lzdGVtIGlkZW50aWZpZXIgd2FzIHN1cHBsaWVkLgorICAgICAqIEBwYXJhbSBiYXNlVVJJICBUaGUgYWJzb2x1dGUgYmFzZSBVUkkgb2YgdGhlIHJlc291cmNlIGJlaW5nIHBhcnNlZCwgb3IKKyAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGlzIG5vIGJhc2UgVVJJLgorICAgICAqIEByZXR1cm4gIEEgPGNvZGU+TFNJbnB1dDwvY29kZT4gb2JqZWN0IGRlc2NyaWJpbmcgdGhlIG5ldyBpbnB1dAorICAgICAqICAgc291cmNlLCBvciA8Y29kZT5udWxsPC9jb2RlPiB0byByZXF1ZXN0IHRoYXQgdGhlIHBhcnNlciBvcGVuIGEKKyAgICAgKiAgIHJlZ3VsYXIgVVJJIGNvbm5lY3Rpb24gdG8gdGhlIHJlc291cmNlLgorICAgICAqLworICAgIHB1YmxpYyBMU0lucHV0IHJlc29sdmVSZXNvdXJjZShTdHJpbmcgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHB1YmxpY0lkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc3lzdGVtSWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBiYXNlVVJJKTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL2xzL0xTU2VyaWFsaXplci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL2xzL0xTU2VyaWFsaXplci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA3ZTJlMjcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vbHMvTFNTZXJpYWxpemVyLmphdmEKQEAgLTAsMCArMSw0NDAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAqCisgKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKKyAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcworICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKKyAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAorICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgorICoKKyAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCisgKi8KKworcGFja2FnZSBvcmcudzNjLmRvbS5sczsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CisKKy8qKgorICogIEEgPGNvZGU+TFNTZXJpYWxpemVyPC9jb2RlPiBwcm92aWRlcyBhbiBBUEkgZm9yIHNlcmlhbGl6aW5nICh3cml0aW5nKSBhCisgKiBET00gZG9jdW1lbnQgb3V0IGludG8gWE1MLiBUaGUgWE1MIGRhdGEgaXMgd3JpdHRlbiB0byBhIHN0cmluZyBvciBhbgorICogb3V0cHV0IHN0cmVhbS4gQW55IGNoYW5nZXMgb3IgZml4dXBzIG1hZGUgZHVyaW5nIHRoZSBzZXJpYWxpemF0aW9uIGFmZmVjdAorICogb25seSB0aGUgc2VyaWFsaXplZCBkYXRhLiBUaGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG9iamVjdCBhbmQgaXRzCisgKiBjaGlsZHJlbiBhcmUgbmV2ZXIgYWx0ZXJlZCBieSB0aGUgc2VyaWFsaXphdGlvbiBvcGVyYXRpb24uCisgKiA8cD4gRHVyaW5nIHNlcmlhbGl6YXRpb24gb2YgWE1MIGRhdGEsIG5hbWVzcGFjZSBmaXh1cCBpcyBkb25lIGFzIGRlZmluZWQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRPTSBMZXZlbCAzIENvcmU8L2E+XQorICogLCBBcHBlbmRpeCBCLiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItQ29yZS0yMDAwMTExMyc+RE9NIExldmVsIDIgQ29yZTwvYT5dCisgKiAgYWxsb3dzIGVtcHR5IHN0cmluZ3MgYXMgYSByZWFsIG5hbWVzcGFjZSBVUkkuIElmIHRoZQorICogPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBvZiBhIDxjb2RlPk5vZGU8L2NvZGU+IGlzIGVtcHR5IHN0cmluZywgdGhlCisgKiBzZXJpYWxpemF0aW9uIHdpbGwgdHJlYXQgdGhlbSBhcyA8Y29kZT5udWxsPC9jb2RlPiwgaWdub3JpbmcgdGhlIHByZWZpeAorICogaWYgYW55LgorICogPHA+IDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gYWNjZXB0cyBhbnkgbm9kZSB0eXBlIGZvciBzZXJpYWxpemF0aW9uLiBGb3IKKyAqIG5vZGVzIG9mIHR5cGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG9yIDxjb2RlPkVudGl0eTwvY29kZT4sIHdlbGwtZm9ybWVkCisgKiBYTUwgd2lsbCBiZSBjcmVhdGVkIHdoZW4gcG9zc2libGUgKHdlbGwtZm9ybWVkbmVzcyBpcyBndWFyYW50ZWVkIGlmIHRoZQorICogZG9jdW1lbnQgb3IgZW50aXR5IGNvbWVzIGZyb20gYSBwYXJzZSBvcGVyYXRpb24gYW5kIGlzIHVuY2hhbmdlZCBzaW5jZSBpdAorICogd2FzIGNyZWF0ZWQpLiBUaGUgc2VyaWFsaXplZCBvdXRwdXQgZm9yIHRoZXNlIG5vZGUgdHlwZXMgaXMgZWl0aGVyIGFzIGEKKyAqIFhNTCBkb2N1bWVudCBvciBhbiBFeHRlcm5hbCBYTUwgRW50aXR5LCByZXNwZWN0aXZlbHksIGFuZCBpcyBhY2NlcHRhYmxlCisgKiBpbnB1dCBmb3IgYW4gWE1MIHBhcnNlci4gRm9yIGFsbCBvdGhlciB0eXBlcyBvZiBub2RlcyB0aGUgc2VyaWFsaXplZCBmb3JtCisgKiBpcyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuCisgKiA8cD5XaXRoaW4gYSA8Y29kZT5Eb2N1bWVudDwvY29kZT4sIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+LCBvcgorICogPGNvZGU+RW50aXR5PC9jb2RlPiBiZWluZyBzZXJpYWxpemVkLCA8Y29kZT5Ob2RlczwvY29kZT4gYXJlIHByb2Nlc3NlZCBhcworICogZm9sbG93cworICogPHVsPgorICogPGxpPiA8Y29kZT5Eb2N1bWVudDwvY29kZT4gbm9kZXMgYXJlIHdyaXR0ZW4sIGluY2x1ZGluZyB0aGUgWE1MCisgKiBkZWNsYXJhdGlvbiAodW5sZXNzIHRoZSBwYXJhbWV0ZXIgInhtbC1kZWNsYXJhdGlvbiIgaXMgc2V0IHRvCisgKiA8Y29kZT5mYWxzZTwvY29kZT4pIGFuZCBhIERURCBzdWJzZXQsIGlmIG9uZSBleGlzdHMgaW4gdGhlIERPTS4gV3JpdGluZyBhCisgKiA8Y29kZT5Eb2N1bWVudDwvY29kZT4gbm9kZSBzZXJpYWxpemVzIHRoZSBlbnRpcmUgZG9jdW1lbnQuCisgKiA8L2xpPgorICogPGxpPgorICogPGNvZGU+RW50aXR5PC9jb2RlPiBub2Rlcywgd2hlbiB3cml0dGVuIGRpcmVjdGx5IGJ5CisgKiA8Y29kZT5MU1NlcmlhbGl6ZXIud3JpdGU8L2NvZGU+LCBvdXRwdXRzIHRoZSBlbnRpdHkgZXhwYW5zaW9uIGJ1dCBubworICogbmFtZXNwYWNlIGZpeHVwIGlzIGRvbmUuIFRoZSByZXN1bHRpbmcgb3V0cHV0IHdpbGwgYmUgdmFsaWQgYXMgYW4KKyAqIGV4dGVybmFsIGVudGl0eS4KKyAqIDwvbGk+CisgKiA8bGk+IElmIHRoZSBwYXJhbWV0ZXIgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lbnRpdGllcyc+CisgKiBlbnRpdGllczwvYT4iIGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiwgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlcyBhcmUKKyAqIHNlcmlhbGl6ZWQgYXMgYW4gZW50aXR5IHJlZmVyZW5jZSBvZiB0aGUgZm9ybSAiCisgKiA8Y29kZT4mYW1wO2VudGl0eU5hbWU7PC9jb2RlPiIgaW4gdGhlIG91dHB1dC4gQ2hpbGQgbm9kZXMgKHRoZSBleHBhbnNpb24pCisgKiBvZiB0aGUgZW50aXR5IHJlZmVyZW5jZSBhcmUgaWdub3JlZC4gSWYgdGhlIHBhcmFtZXRlciAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLWVudGl0aWVzJz4KKyAqIGVudGl0aWVzPC9hPiIgaXMgc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiwgb25seSB0aGUgY2hpbGRyZW4gb2YgdGhlIGVudGl0eSByZWZlcmVuY2UKKyAqIGFyZSBzZXJpYWxpemVkLiA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IG5vZGVzIHdpdGggbm8gY2hpbGRyZW4gKG5vCisgKiBjb3JyZXNwb25kaW5nIDxjb2RlPkVudGl0eTwvY29kZT4gbm9kZSBvciB0aGUgY29ycmVzcG9uZGluZworICogPGNvZGU+RW50aXR5PC9jb2RlPiBub2RlcyBoYXZlIG5vIGNoaWxkcmVuKSBhcmUgYWx3YXlzIHNlcmlhbGl6ZWQuCisgKiA8L2xpPgorICogPGxpPgorICogPGNvZGU+Q0RBVEFzZWN0aW9uczwvY29kZT4gY29udGFpbmluZyBjb250ZW50IGNoYXJhY3RlcnMgdGhhdCBjYW5ub3QgYmUKKyAqIHJlcHJlc2VudGVkIGluIHRoZSBzcGVjaWZpZWQgb3V0cHV0IGVuY29kaW5nIGFyZSBoYW5kbGVkIGFjY29yZGluZyB0byB0aGUKKyAqICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItc3BsaXQtY2RhdGEtc2VjdGlvbnMnPgorICogc3BsaXQtY2RhdGEtc2VjdGlvbnM8L2E+IiBwYXJhbWV0ZXIuICBJZiB0aGUgcGFyYW1ldGVyIGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiwKKyAqIDxjb2RlPkNEQVRBc2VjdGlvbnM8L2NvZGU+IGFyZSBzcGxpdCwgYW5kIHRoZSB1bnJlcHJlc2VudGFibGUgY2hhcmFjdGVycworICogYXJlIHNlcmlhbGl6ZWQgYXMgbnVtZXJpYyBjaGFyYWN0ZXIgcmVmZXJlbmNlcyBpbiBvcmRpbmFyeSBjb250ZW50LiBUaGUKKyAqIGV4YWN0IHBvc2l0aW9uIGFuZCBudW1iZXIgb2Ygc3BsaXRzIGlzIG5vdCBzcGVjaWZpZWQuICBJZiB0aGUgcGFyYW1ldGVyCisgKiBpcyBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LCB1bnJlcHJlc2VudGFibGUgY2hhcmFjdGVycyBpbiBhCisgKiA8Y29kZT5DREFUQXNlY3Rpb248L2NvZGU+IGFyZSByZXBvcnRlZCBhcworICogPGNvZGU+IndmLWludmFsaWQtY2hhcmFjdGVyIjwvY29kZT4gZXJyb3JzIGlmIHRoZSBwYXJhbWV0ZXIgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci13ZWxsLWZvcm1lZCc+CisgKiB3ZWxsLWZvcm1lZDwvYT4iIGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPi4gVGhlIGVycm9yIGlzIG5vdCByZWNvdmVyYWJsZSAtIHRoZXJlIGlzIG5vCisgKiBtZWNoYW5pc20gZm9yIHN1cHBseWluZyBhbHRlcm5hdGl2ZSBjaGFyYWN0ZXJzIGFuZCBjb250aW51aW5nIHdpdGggdGhlCisgKiBzZXJpYWxpemF0aW9uLgorICogPC9saT4KKyAqIDxsaT4gPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4gbm9kZXMgYXJlIHNlcmlhbGl6ZWQgYnkKKyAqIHNlcmlhbGl6aW5nIHRoZSBjaGlsZHJlbiBvZiB0aGUgZG9jdW1lbnQgZnJhZ21lbnQgaW4gdGhlIG9yZGVyIHRoZXkKKyAqIGFwcGVhciBpbiB0aGUgZG9jdW1lbnQgZnJhZ21lbnQuCisgKiA8L2xpPgorICogPGxpPiBBbGwgb3RoZXIgbm9kZSB0eXBlcyAoRWxlbWVudCwgVGV4dCwKKyAqIGV0Yy4pIGFyZSBzZXJpYWxpemVkIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcgWE1MIHNvdXJjZSBmb3JtLgorICogPC9saT4KKyAqIDwvdWw+CisgKiA8cCA+PGI+Tm90ZTo8L2I+ICBUaGUgc2VyaWFsaXphdGlvbiBvZiBhIDxjb2RlPk5vZGU8L2NvZGU+IGRvZXMgbm90IGFsd2F5cworICogZ2VuZXJhdGUgYSB3ZWxsLWZvcm1lZCBYTUwgZG9jdW1lbnQsIGkuZS4gYSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gbWlnaHQKKyAqIHRocm93IGZhdGFsIGVycm9ycyB3aGVuIHBhcnNpbmcgdGhlIHJlc3VsdGluZyBzZXJpYWxpemF0aW9uLgorICogPHA+IFdpdGhpbiB0aGUgY2hhcmFjdGVyIGRhdGEgb2YgYSBkb2N1bWVudCAob3V0c2lkZSBvZiBtYXJrdXApLCBhbnkKKyAqIGNoYXJhY3RlcnMgdGhhdCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgZGlyZWN0bHkgYXJlIHJlcGxhY2VkIHdpdGgKKyAqIGNoYXJhY3RlciByZWZlcmVuY2VzLiBPY2N1cnJlbmNlcyBvZiAnJmx0OycgYW5kICcmYW1wOycgYXJlIHJlcGxhY2VkIGJ5CisgKiB0aGUgcHJlZGVmaW5lZCBlbnRpdGllcyAmYW1wO2x0OyBhbmQgJmFtcDthbXA7LiBUaGUgb3RoZXIgcHJlZGVmaW5lZAorICogZW50aXRpZXMgKCZhbXA7Z3Q7LCAmYW1wO2Fwb3M7LCBhbmQgJmFtcDtxdW90OykgbWlnaHQgbm90IGJlIHVzZWQsIGV4Y2VwdAorICogd2hlcmUgbmVlZGVkIChlLmcuIHVzaW5nICZhbXA7Z3Q7IGluIGNhc2VzIHN1Y2ggYXMgJ11dJmd0OycpLiBBbnkKKyAqIGNoYXJhY3RlcnMgdGhhdCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgZGlyZWN0bHkgaW4gdGhlIG91dHB1dCBjaGFyYWN0ZXIKKyAqIGVuY29kaW5nIGFyZSBzZXJpYWxpemVkIGFzIG51bWVyaWMgY2hhcmFjdGVyIHJlZmVyZW5jZXMgKGFuZCBzaW5jZQorICogY2hhcmFjdGVyIGVuY29kaW5nIHN0YW5kYXJkcyBjb21tb25seSB1c2UgaGV4YWRlY2ltYWwgcmVwcmVzZW50YXRpb25zIG9mCisgKiBjaGFyYWN0ZXJzLCB1c2luZyB0aGUgaGV4YWRlY2ltYWwgcmVwcmVzZW50YXRpb24gd2hlbiBzZXJpYWxpemluZworICogY2hhcmFjdGVyIHJlZmVyZW5jZXMgaXMgZW5jb3VyYWdlZCkuCisgKiA8cD4gVG8gYWxsb3cgYXR0cmlidXRlIHZhbHVlcyB0byBjb250YWluIGJvdGggc2luZ2xlIGFuZCBkb3VibGUgcXVvdGVzLCB0aGUKKyAqIGFwb3N0cm9waGUgb3Igc2luZ2xlLXF1b3RlIGNoYXJhY3RlciAoJykgbWF5IGJlIHJlcHJlc2VudGVkIGFzCisgKiAiJmFtcDthcG9zOyIsIGFuZCB0aGUgZG91YmxlLXF1b3RlIGNoYXJhY3RlciAoIikgIGFzICImYW1wO3F1b3Q7Ii4gTmV3CisgKiBsaW5lIGNoYXJhY3RlcnMgYW5kIG90aGVyIGNoYXJhY3RlcnMgdGhhdCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgZGlyZWN0bHkKKyAqIGluIGF0dHJpYnV0ZSB2YWx1ZXMgaW4gdGhlIG91dHB1dCBjaGFyYWN0ZXIgZW5jb2RpbmcgYXJlIHNlcmlhbGl6ZWQgYXMgYQorICogbnVtZXJpYyBjaGFyYWN0ZXIgcmVmZXJlbmNlLgorICogPHA+IFdpdGhpbiBtYXJrdXAsIGJ1dCBvdXRzaWRlIG9mIGF0dHJpYnV0ZXMsIGFueSBvY2N1cnJlbmNlIG9mIGEgY2hhcmFjdGVyCisgKiB0aGF0IGNhbm5vdCBiZSByZXByZXNlbnRlZCBpbiB0aGUgb3V0cHV0IGNoYXJhY3RlciBlbmNvZGluZyBpcyByZXBvcnRlZAorICogYXMgYSA8Y29kZT5ET01FcnJvcjwvY29kZT4gZmF0YWwgZXJyb3IuIEFuIGV4YW1wbGUgd291bGQgYmUgc2VyaWFsaXppbmcKKyAqIHRoZSBlbGVtZW50ICZsdDtMYUNhXHUwMGYxYWRhLyZndDsgd2l0aCA8Y29kZT5lbmNvZGluZz0idXMtYXNjaWkiPC9jb2RlPi4KKyAqIFRoaXMgd2lsbCByZXN1bHQgd2l0aCBhIGdlbmVyYXRpb24gb2YgYSA8Y29kZT5ET01FcnJvcjwvY29kZT4KKyAqICJ3Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUiIChhcyBwcm9wb3NlZCBpbiAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLXdlbGwtZm9ybWVkJz4KKyAqIHdlbGwtZm9ybWVkPC9hPiIpLgorICogPHA+IFdoZW4gcmVxdWVzdGVkIGJ5IHNldHRpbmcgdGhlIHBhcmFtZXRlciAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLW5vcm1hbGl6ZS1jaGFyYWN0ZXJzJz4KKyAqIG5vcm1hbGl6ZS1jaGFyYWN0ZXJzPC9hPiIgb24gPGNvZGU+TFNTZXJpYWxpemVyPC9jb2RlPiB0byB0cnVlLCBjaGFyYWN0ZXIgbm9ybWFsaXphdGlvbiBpcworICogcGVyZm9ybWVkIGFjY29yZGluZyB0byB0aGUgZGVmaW5pdGlvbiBvZiA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwxMS0yMDA0MDIwNC8jZHQtZnVsbG5vcm0nPmZ1bGx5CisgKiBub3JtYWxpemVkPC9hPiBjaGFyYWN0ZXJzIGluY2x1ZGVkIGluIGFwcGVuZGl4IEUgb2YgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0Lyc+WE1MIDEuMTwvYT5dIG9uIGFsbAorICogZGF0YSB0byBiZSBzZXJpYWxpemVkLCBib3RoIG1hcmt1cCBhbmQgY2hhcmFjdGVyIGRhdGEuIFRoZSBjaGFyYWN0ZXIKKyAqIG5vcm1hbGl6YXRpb24gcHJvY2VzcyBhZmZlY3RzIG9ubHkgdGhlIGRhdGEgYXMgaXQgaXMgYmVpbmcgd3JpdHRlbjsgaXQKKyAqIGRvZXMgbm90IGFsdGVyIHRoZSBET00ncyB2aWV3IG9mIHRoZSBkb2N1bWVudCBhZnRlciBzZXJpYWxpemF0aW9uIGhhcworICogY29tcGxldGVkLgorICogPHA+IEltcGxlbWVudGF0aW9ucyBhcmUgcmVxdWlyZWQgdG8gc3VwcG9ydCB0aGUgZW5jb2RpbmdzICJVVEYtOCIsCisgKiAiVVRGLTE2IiwgIlVURi0xNkJFIiwgYW5kICJVVEYtMTZMRSIgdG8gZ3VhcmFudGVlIHRoYXQgZGF0YSBpcworICogc2VyaWFsaXphYmxlIGluIGFsbCBlbmNvZGluZ3MgdGhhdCBhcmUgcmVxdWlyZWQgdG8gYmUgc3VwcG9ydGVkIGJ5IGFsbAorICogWE1MIHBhcnNlcnMuIFdoZW4gdGhlIGVuY29kaW5nIGlzIFVURi04LCB3aGV0aGVyIG9yIG5vdCBhIGJ5dGUgb3JkZXIgbWFyaworICogaXMgc2VyaWFsaXplZCwgb3IgaWYgdGhlIG91dHB1dCBpcyBiaWctZW5kaWFuIG9yIGxpdHRsZS1lbmRpYW4sIGlzCisgKiBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuIFdoZW4gdGhlIGVuY29kaW5nIGlzIFVURi0xNiwgd2hldGhlciBvciBub3QgdGhlCisgKiBvdXRwdXQgaXMgYmlnLWVuZGlhbiBvciBsaXR0bGUtZW5kaWFuIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudCwgYnV0IGEKKyAqIEJ5dGUgT3JkZXIgTWFyayBtdXN0IGJlIGdlbmVyYXRlZCBmb3Igbm9uLWNoYXJhY3RlciBvdXRwdXRzLCBzdWNoIGFzCisgKiA8Y29kZT5MU091dHB1dC5ieXRlU3RyZWFtPC9jb2RlPiBvciA8Y29kZT5MU091dHB1dC5zeXN0ZW1JZDwvY29kZT4uIElmCisgKiB0aGUgQnl0ZSBPcmRlciBNYXJrIGlzIG5vdCBnZW5lcmF0ZWQsIGEgImJ5dGUtb3JkZXItbWFyay1uZWVkZWQiIHdhcm5pbmcKKyAqIGlzIHJlcG9ydGVkLiBXaGVuIHRoZSBlbmNvZGluZyBpcyBVVEYtMTZMRSBvciBVVEYtMTZCRSwgdGhlIG91dHB1dCBpcworICogYmlnLWVuZGlhbiAoVVRGLTE2QkUpIG9yIGxpdHRsZS1lbmRpYW4gKFVURi0xNkxFKSBhbmQgdGhlIEJ5dGUgT3JkZXIgTWFyaworICogaXMgbm90IGJlIGdlbmVyYXRlZC4gSW4gYWxsIGNhc2VzLCB0aGUgZW5jb2RpbmcgZGVjbGFyYXRpb24sIGlmCisgKiBnZW5lcmF0ZWQsIHdpbGwgY29ycmVzcG9uZCB0byB0aGUgZW5jb2RpbmcgdXNlZCBkdXJpbmcgdGhlIHNlcmlhbGl6YXRpb24KKyAqIChlLmcuIDxjb2RlPmVuY29kaW5nPSJVVEYtMTYiPC9jb2RlPiB3aWxsIGFwcGVhciBpZiBVVEYtMTYgd2FzCisgKiByZXF1ZXN0ZWQpLgorICogPHA+IE5hbWVzcGFjZXMgYXJlIGZpeGVkIHVwIGR1cmluZyBzZXJpYWxpemF0aW9uLCB0aGUgc2VyaWFsaXphdGlvbiBwcm9jZXNzCisgKiB3aWxsIHZlcmlmeSB0aGF0IG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMsIG5hbWVzcGFjZSBwcmVmaXhlcyBhbmQgdGhlCisgKiBuYW1lc3BhY2UgVVJJIGFzc29jaWF0ZWQgd2l0aCBlbGVtZW50cyBhbmQgYXR0cmlidXRlcyBhcmUgY29uc2lzdGVudC4gSWYKKyAqIGluY29uc2lzdGVuY2llcyBhcmUgZm91bmQsIHRoZSBzZXJpYWxpemVkIGZvcm0gb2YgdGhlIGRvY3VtZW50IHdpbGwgYmUKKyAqIGFsdGVyZWQgdG8gcmVtb3ZlIHRoZW0uIFRoZSBtZXRob2QgdXNlZCBmb3IgZG9pbmcgdGhlIG5hbWVzcGFjZSBmaXh1cAorICogd2hpbGUgc2VyaWFsaXppbmcgYSBkb2N1bWVudCBpcyB0aGUgYWxnb3JpdGhtIGRlZmluZWQgaW4gQXBwZW5kaXggQi4xLAorICogIk5hbWVzcGFjZSBub3JtYWxpemF0aW9uIiwgb2YgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRPTSBMZXZlbCAzIENvcmU8L2E+XQorICogLgorICogPHA+IFdoaWxlIHNlcmlhbGl6aW5nIGEgZG9jdW1lbnQsIHRoZSBwYXJhbWV0ZXIgImRpc2NhcmQtZGVmYXVsdC1jb250ZW50IgorICogY29udHJvbHMgd2hldGhlciBvciBub3Qgbm9uLXNwZWNpZmllZCBkYXRhIGlzIHNlcmlhbGl6ZWQuCisgKiA8cD4gV2hpbGUgc2VyaWFsaXppbmcsIGVycm9ycyBhbmQgd2FybmluZ3MgYXJlIHJlcG9ydGVkIHRvIHRoZSBhcHBsaWNhdGlvbgorICogdGhyb3VnaCB0aGUgZXJyb3IgaGFuZGxlciAoPGNvZGU+TFNTZXJpYWxpemVyLmRvbUNvbmZpZzwvY29kZT4ncyAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLWVycm9yLWhhbmRsZXInPgorICogZXJyb3ItaGFuZGxlcjwvYT4iIHBhcmFtZXRlcikuIFRoaXMgc3BlY2lmaWNhdGlvbiBkb2VzIGluIG5vIHdheSB0cnkgdG8gZGVmaW5lIGFsbCBwb3NzaWJsZQorICogZXJyb3JzIGFuZCB3YXJuaW5ncyB0aGF0IGNhbiBvY2N1ciB3aGlsZSBzZXJpYWxpemluZyBhIERPTSBub2RlLCBidXQgc29tZQorICogY29tbW9uIGVycm9yIGFuZCB3YXJuaW5nIGNhc2VzIGFyZSBkZWZpbmVkLiBUaGUgdHlwZXMgKAorICogPGNvZGU+RE9NRXJyb3IudHlwZTwvY29kZT4pIG9mIGVycm9ycyBhbmQgd2FybmluZ3MgZGVmaW5lZCBieSB0aGlzCisgKiBzcGVjaWZpY2F0aW9uIGFyZToKKyAqIDxkbD4KKyAqIDxkdD48Y29kZT4ibm8tb3V0cHV0LXNwZWNpZmllZCIgW2ZhdGFsXTwvY29kZT48L2R0PgorICogPGRkPiBSYWlzZWQgd2hlbgorICogd3JpdGluZyB0byBhIDxjb2RlPkxTT3V0cHV0PC9jb2RlPiBpZiBubyBvdXRwdXQgaXMgc3BlY2lmaWVkIGluIHRoZQorICogPGNvZGU+TFNPdXRwdXQ8L2NvZGU+LiA8L2RkPgorICogPGR0PgorICogPGNvZGU+InVuYm91bmQtcHJlZml4LWluLWVudGl0eS1yZWZlcmVuY2UiIFtmYXRhbF08L2NvZGU+IDwvZHQ+CisgKiA8ZGQ+IFJhaXNlZCBpZiB0aGUKKyAqIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItbmFtZXNwYWNlcyc+CisgKiBuYW1lc3BhY2VzPC9hPiIgaXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+IGFuZCBhbiBlbnRpdHkgd2hvc2UgcmVwbGFjZW1lbnQgdGV4dAorICogY29udGFpbnMgdW5ib3VuZCBuYW1lc3BhY2UgcHJlZml4ZXMgaXMgcmVmZXJlbmNlZCBpbiBhIGxvY2F0aW9uIHdoZXJlCisgKiB0aGVyZSBhcmUgbm8gYmluZGluZ3MgZm9yIHRoZSBuYW1lc3BhY2UgcHJlZml4ZXMuIDwvZGQ+CisgKiA8ZHQ+CisgKiA8Y29kZT4idW5zdXBwb3J0ZWQtZW5jb2RpbmciIFtmYXRhbF08L2NvZGU+PC9kdD4KKyAqIDxkZD4gUmFpc2VkIGlmIGFuIHVuc3VwcG9ydGVkCisgKiBlbmNvZGluZyBpcyBlbmNvdW50ZXJlZC4gPC9kZD4KKyAqIDwvZGw+CisgKiA8cD4gSW4gYWRkaXRpb24gdG8gcmFpc2luZyB0aGUgZGVmaW5lZCBlcnJvcnMgYW5kIHdhcm5pbmdzLCBpbXBsZW1lbnRhdGlvbnMKKyAqIGFyZSBleHBlY3RlZCB0byByYWlzZSBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYyBlcnJvcnMgYW5kIHdhcm5pbmdzIGZvciBhbnkKKyAqIG90aGVyIGVycm9yIGFuZCB3YXJuaW5nIGNhc2VzIHN1Y2ggYXMgSU8gZXJyb3JzIChmaWxlIG5vdCBmb3VuZCwKKyAqIHBlcm1pc3Npb24gZGVuaWVkLC4uLikgYW5kIHNvIG9uLgorICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUxTLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBMb2FkCithbmQgU2F2ZSBTcGVjaWZpY2F0aW9uPC9hPi4KKyAqLworcHVibGljIGludGVyZmFjZSBMU1NlcmlhbGl6ZXIgeworICAgIC8qKgorICAgICAqICBUaGUgPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gb2JqZWN0IHVzZWQgYnkgdGhlCisgICAgICogPGNvZGU+TFNTZXJpYWxpemVyPC9jb2RlPiB3aGVuIHNlcmlhbGl6aW5nIGEgRE9NIG5vZGUuCisgICAgICogPGJyPiBJbiBhZGRpdGlvbiB0byB0aGUgcGFyYW1ldGVycyByZWNvZ25pemVkIGJ5IHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNET01Db25maWd1cmF0aW9uJz4KKyAgICAgKiBET01Db25maWd1cmF0aW9uPC9hPiBpbnRlcmZhY2UgZGVmaW5lZCBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RE9NIExldmVsIDMgQ29yZTwvYT5dCisgICAgICogLCB0aGUgPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gb2JqZWN0cyBmb3IKKyAgICAgKiA8Y29kZT5MU1NlcmlhbGl6ZXI8L2NvZGU+IGFkZHMsIG9yIG1vZGlmaWVzLCB0aGUgZm9sbG93aW5nCisgICAgICogcGFyYW1ldGVyczoKKyAgICAgKiA8ZGw+CisgICAgICogPGR0Pjxjb2RlPiJjYW5vbmljYWwtZm9ybSI8L2NvZGU+PC9kdD4KKyAgICAgKiA8ZGQ+CisgICAgICogPGRsPgorICAgICAqIDxkdD48Y29kZT50cnVlPC9jb2RlPjwvZHQ+CisgICAgICogPGRkPls8ZW0+b3B0aW9uYWw8L2VtPl0gV3JpdGVzIHRoZSBkb2N1bWVudCBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIHNwZWNpZmllZCBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sLWMxNG4tMjAwMTAzMTUnPkNhbm9uaWNhbCBYTUw8L2E+XS4KKyAgICAgKiBJbiBhZGRpdGlvbiB0byB0aGUgYmVoYXZpb3IgZGVzY3JpYmVkIGluICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItY2Fub25pY2FsLWZvcm0nPgorICAgICAqIGNhbm9uaWNhbC1mb3JtPC9hPiIgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRPTSBMZXZlbCAzIENvcmU8L2E+XQorICAgICAqICwgc2V0dGluZyB0aGlzIHBhcmFtZXRlciB0byA8Y29kZT50cnVlPC9jb2RlPiB3aWxsIHNldCB0aGUgcGFyYW1ldGVycworICAgICAqICJmb3JtYXQtcHJldHR5LXByaW50IiwgImRpc2NhcmQtZGVmYXVsdC1jb250ZW50IiwgYW5kICJ4bWwtZGVjbGFyYXRpb24KKyAgICAgKiAiLCB0byA8Y29kZT5mYWxzZTwvY29kZT4uIFNldHRpbmcgb25lIG9mIHRob3NlIHBhcmFtZXRlcnMgdG8KKyAgICAgKiA8Y29kZT50cnVlPC9jb2RlPiB3aWxsIHNldCB0aGlzIHBhcmFtZXRlciB0byA8Y29kZT5mYWxzZTwvY29kZT4uCisgICAgICogU2VyaWFsaXppbmcgYW4gWE1MIDEuMSBkb2N1bWVudCB3aGVuICJjYW5vbmljYWwtZm9ybSIgaXMKKyAgICAgKiA8Y29kZT50cnVlPC9jb2RlPiB3aWxsIGdlbmVyYXRlIGEgZmF0YWwgZXJyb3IuIDwvZGQ+CisgICAgICogPGR0Pjxjb2RlPmZhbHNlPC9jb2RlPjwvZHQ+CisgICAgICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pIERvIG5vdCBjYW5vbmljYWxpemUgdGhlIG91dHB1dC4gPC9kZD4KKyAgICAgKiA8L2RsPjwvZGQ+CisgICAgICogPGR0Pjxjb2RlPiJkaXNjYXJkLWRlZmF1bHQtY29udGVudCI8L2NvZGU+PC9kdD4KKyAgICAgKiA8ZGQ+CisgICAgICogPGRsPgorICAgICAqIDxkdD4KKyAgICAgKiA8Y29kZT50cnVlPC9jb2RlPjwvZHQ+CisgICAgICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pIFVzZSB0aGUgPGNvZGU+QXR0ci5zcGVjaWZpZWQ8L2NvZGU+IGF0dHJpYnV0ZSB0byBkZWNpZGUgd2hhdCBhdHRyaWJ1dGVzCisgICAgICogc2hvdWxkIGJlIGRpc2NhcmRlZC4gTm90ZSB0aGF0IHNvbWUgaW1wbGVtZW50YXRpb25zIG1pZ2h0IHVzZQorICAgICAqIHdoYXRldmVyIGluZm9ybWF0aW9uIGF2YWlsYWJsZSB0byB0aGUgaW1wbGVtZW50YXRpb24gKGkuZS4gWE1MCisgICAgICogc2NoZW1hLCBEVEQsIHRoZSA8Y29kZT5BdHRyLnNwZWNpZmllZDwvY29kZT4gYXR0cmlidXRlLCBhbmQgc28gb24pIHRvCisgICAgICogZGV0ZXJtaW5lIHdoYXQgYXR0cmlidXRlcyBhbmQgY29udGVudCB0byBkaXNjYXJkIGlmIHRoaXMgcGFyYW1ldGVyIGlzCisgICAgICogc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+LiA8L2RkPgorICAgICAqIDxkdD48Y29kZT5mYWxzZTwvY29kZT48L2R0PgorICAgICAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dS2VlcCBhbGwgYXR0cmlidXRlcyBhbmQgYWxsIGNvbnRlbnQuPC9kZD4KKyAgICAgKiA8L2RsPjwvZGQ+CisgICAgICogPGR0Pjxjb2RlPiJmb3JtYXQtcHJldHR5LXByaW50IjwvY29kZT48L2R0PgorICAgICAqIDxkZD4KKyAgICAgKiA8ZGw+CisgICAgICogPGR0PgorICAgICAqIDxjb2RlPnRydWU8L2NvZGU+PC9kdD4KKyAgICAgKiA8ZGQ+WzxlbT5vcHRpb25hbDwvZW0+XSBGb3JtYXR0aW5nIHRoZSBvdXRwdXQgYnkgYWRkaW5nIHdoaXRlc3BhY2UgdG8gcHJvZHVjZSBhIHByZXR0eS1wcmludGVkLAorICAgICAqIGluZGVudGVkLCBodW1hbi1yZWFkYWJsZSBmb3JtLiBUaGUgZXhhY3QgZm9ybSBvZiB0aGUgdHJhbnNmb3JtYXRpb25zCisgICAgICogaXMgbm90IHNwZWNpZmllZCBieSB0aGlzIHNwZWNpZmljYXRpb24uIFByZXR0eS1wcmludGluZyBjaGFuZ2VzIHRoZQorICAgICAqIGNvbnRlbnQgb2YgdGhlIGRvY3VtZW50IGFuZCBtYXkgYWZmZWN0IHRoZSB2YWxpZGl0eSBvZiB0aGUgZG9jdW1lbnQsCisgICAgICogdmFsaWRhdGluZyBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIHByZXNlcnZlIHZhbGlkaXR5LiA8L2RkPgorICAgICAqIDxkdD4KKyAgICAgKiA8Y29kZT5mYWxzZTwvY29kZT48L2R0PgorICAgICAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dICg8ZW0+ZGVmYXVsdDwvZW0+KSBEb24ndCBwcmV0dHktcHJpbnQgdGhlIHJlc3VsdC4gPC9kZD4KKyAgICAgKiA8L2RsPjwvZGQ+CisgICAgICogPGR0PgorICAgICAqIDxjb2RlPiJpZ25vcmUtdW5rbm93bi1jaGFyYWN0ZXItZGVub3JtYWxpemF0aW9ucyI8L2NvZGU+IDwvZHQ+CisgICAgICogPGRkPgorICAgICAqIDxkbD4KKyAgICAgKiA8ZHQ+CisgICAgICogPGNvZGU+dHJ1ZTwvY29kZT48L2R0PgorICAgICAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dICg8ZW0+ZGVmYXVsdDwvZW0+KSBJZiwgd2hpbGUgdmVyaWZ5aW5nIGZ1bGwgbm9ybWFsaXphdGlvbiB3aGVuIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwxMS0yMDA0MDIwNC8nPlhNTCAxLjE8L2E+XSBpcworICAgICAqIHN1cHBvcnRlZCwgYSBjaGFyYWN0ZXIgaXMgZW5jb3VudGVyZWQgZm9yIHdoaWNoIHRoZSBub3JtYWxpemF0aW9uCisgICAgICogcHJvcGVydGllcyBjYW5ub3QgYmUgZGV0ZXJtaW5lZCwgdGhlbiByYWlzZSBhCisgICAgICogPGNvZGU+InVua25vd24tY2hhcmFjdGVyLWRlbm9ybWFsaXphdGlvbiI8L2NvZGU+IHdhcm5pbmcgKGluc3RlYWQgb2YKKyAgICAgKiByYWlzaW5nIGFuIGVycm9yLCBpZiB0aGlzIHBhcmFtZXRlciBpcyBub3Qgc2V0KSBhbmQgaWdub3JlIGFueQorICAgICAqIHBvc3NpYmxlIGRlbm9ybWFsaXphdGlvbnMgY2F1c2VkIGJ5IHRoZXNlIGNoYXJhY3RlcnMuIDwvZGQ+CisgICAgICogPGR0PgorICAgICAqIDxjb2RlPmZhbHNlPC9jb2RlPjwvZHQ+CisgICAgICogPGRkPls8ZW0+b3B0aW9uYWw8L2VtPl0gUmVwb3J0IGEgZmF0YWwgZXJyb3IgaWYgYSBjaGFyYWN0ZXIgaXMgZW5jb3VudGVyZWQgZm9yIHdoaWNoIHRoZQorICAgICAqIHByb2Nlc3NvciBjYW5ub3QgZGV0ZXJtaW5lIHRoZSBub3JtYWxpemF0aW9uIHByb3BlcnRpZXMuIDwvZGQ+CisgICAgICogPC9kbD48L2RkPgorICAgICAqIDxkdD4KKyAgICAgKiA8Y29kZT4ibm9ybWFsaXplLWNoYXJhY3RlcnMiPC9jb2RlPjwvZHQ+CisgICAgICogPGRkPiBUaGlzIHBhcmFtZXRlciBpcyBlcXVpdmFsZW50IHRvCisgICAgICogdGhlIG9uZSBkZWZpbmVkIGJ5IDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5ET00gTGV2ZWwgMyBDb3JlPC9hPl0KKyAgICAgKiAuIFVubGlrZSBpbiB0aGUgQ29yZSwgdGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRoaXMgcGFyYW1ldGVyIGlzCisgICAgICogPGNvZGU+dHJ1ZTwvY29kZT4uIFdoaWxlIERPTSBpbXBsZW1lbnRhdGlvbnMgYXJlIG5vdCByZXF1aXJlZCB0bworICAgICAqIHN1cHBvcnQgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sMTEtMjAwNDAyMDQvI2R0LWZ1bGxub3JtJz5mdWxseQorICAgICAqIG5vcm1hbGl6aW5nPC9hPiB0aGUgY2hhcmFjdGVycyBpbiB0aGUgZG9jdW1lbnQgYWNjb3JkaW5nIHRvIGFwcGVuZGl4IEUgb2YgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0Lyc+WE1MIDEuMTwvYT5dLCB0aGlzCisgICAgICogcGFyYW1ldGVyIG11c3QgYmUgYWN0aXZhdGVkIGJ5IGRlZmF1bHQgaWYgc3VwcG9ydGVkLiA8L2RkPgorICAgICAqIDxkdD4KKyAgICAgKiA8Y29kZT4ieG1sLWRlY2xhcmF0aW9uIjwvY29kZT48L2R0PgorICAgICAqIDxkZD4KKyAgICAgKiA8ZGw+CisgICAgICogPGR0Pjxjb2RlPnRydWU8L2NvZGU+PC9kdD4KKyAgICAgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPikgSWYgYSA8Y29kZT5Eb2N1bWVudDwvY29kZT4sIDxjb2RlPkVsZW1lbnQ8L2NvZGU+LCBvciA8Y29kZT5FbnRpdHk8L2NvZGU+CisgICAgICogIG5vZGUgaXMgc2VyaWFsaXplZCwgdGhlIFhNTCBkZWNsYXJhdGlvbiwgb3IgdGV4dCBkZWNsYXJhdGlvbiwgc2hvdWxkCisgICAgICogYmUgaW5jbHVkZWQuIFRoZSB2ZXJzaW9uICg8Y29kZT5Eb2N1bWVudC54bWxWZXJzaW9uPC9jb2RlPiBpZiB0aGUKKyAgICAgKiBkb2N1bWVudCBpcyBhIExldmVsIDMgZG9jdW1lbnQgYW5kIHRoZSB2ZXJzaW9uIGlzIG5vbi1udWxsLCBvdGhlcndpc2UKKyAgICAgKiB1c2UgdGhlIHZhbHVlICIxLjAiKSwgYW5kIHRoZSBvdXRwdXQgZW5jb2RpbmcgKHNlZQorICAgICAqIDxjb2RlPkxTU2VyaWFsaXplci53cml0ZTwvY29kZT4gZm9yIGRldGFpbHMgb24gaG93IHRvIGZpbmQgdGhlIG91dHB1dAorICAgICAqIGVuY29kaW5nKSBhcmUgc3BlY2lmaWVkIGluIHRoZSBzZXJpYWxpemVkIFhNTCBkZWNsYXJhdGlvbi4gPC9kZD4KKyAgICAgKiA8ZHQ+CisgICAgICogPGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KKyAgICAgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSBEbyBub3Qgc2VyaWFsaXplIHRoZSBYTUwgYW5kIHRleHQgZGVjbGFyYXRpb25zLiBSZXBvcnQgYQorICAgICAqIDxjb2RlPiJ4bWwtZGVjbGFyYXRpb24tbmVlZGVkIjwvY29kZT4gd2FybmluZyBpZiB0aGlzIHdpbGwgY2F1c2UKKyAgICAgKiBwcm9ibGVtcyAoaS5lLiB0aGUgc2VyaWFsaXplZCBkYXRhIGlzIG9mIGFuIFhNTCB2ZXJzaW9uIG90aGVyIHRoYW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dLCBvciBhbgorICAgICAqIGVuY29kaW5nIHdvdWxkIGJlIG5lZWRlZCB0byBiZSBhYmxlIHRvIHJlLXBhcnNlIHRoZSBzZXJpYWxpemVkIGRhdGEpLiA8L2RkPgorICAgICAqIDwvZGw+PC9kZD4KKyAgICAgKiA8L2RsPgorICAgICAqLworICAgIHB1YmxpYyBET01Db25maWd1cmF0aW9uIGdldERvbUNvbmZpZygpOworCisgICAgLyoqCisgICAgICogIFRoZSBlbmQtb2YtbGluZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIHRvIGJlIHVzZWQgaW4gdGhlIFhNTCBiZWluZworICAgICAqIHdyaXR0ZW4gb3V0LiBBbnkgc3RyaW5nIGlzIHN1cHBvcnRlZCwgYnV0IFhNTCB0cmVhdHMgb25seSBhIGNlcnRhaW4KKyAgICAgKiBzZXQgb2YgY2hhcmFjdGVycyBzZXF1ZW5jZSBhcyBlbmQtb2YtbGluZSAoU2VlIHNlY3Rpb24gMi4xMSwKKyAgICAgKiAiRW5kLW9mLUxpbmUgSGFuZGxpbmciIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XSwgaWYgdGhlCisgICAgICogc2VyaWFsaXplZCBjb250ZW50IGlzIFhNTCAxLjAgb3Igc2VjdGlvbiAyLjExLCAiRW5kLW9mLUxpbmUgSGFuZGxpbmciCisgICAgICogaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0Lyc+WE1MIDEuMTwvYT5dLCBpZiB0aGUKKyAgICAgKiBzZXJpYWxpemVkIGNvbnRlbnQgaXMgWE1MIDEuMSkuIFVzaW5nIG90aGVyIGNoYXJhY3RlciBzZXF1ZW5jZXMgdGhhbgorICAgICAqIHRoZSByZWNvbW1lbmRlZCBvbmVzIGNhbiByZXN1bHQgaW4gYSBkb2N1bWVudCB0aGF0IGlzIGVpdGhlciBub3QKKyAgICAgKiBzZXJpYWxpemFibGUgb3Igbm90IHdlbGwtZm9ybWVkKS4KKyAgICAgKiA8YnI+IE9uIHJldHJpZXZhbCwgdGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhpcyBhdHRyaWJ1dGUgaXMgdGhlCisgICAgICogaW1wbGVtZW50YXRpb24gc3BlY2lmaWMgZGVmYXVsdCBlbmQtb2YtbGluZSBzZXF1ZW5jZS4gRE9NCisgICAgICogaW1wbGVtZW50YXRpb25zIHNob3VsZCBjaG9vc2UgdGhlIGRlZmF1bHQgdG8gbWF0Y2ggdGhlIHVzdWFsCisgICAgICogY29udmVudGlvbiBmb3IgdGV4dCBmaWxlcyBpbiB0aGUgZW52aXJvbm1lbnQgYmVpbmcgdXNlZC4KKyAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbXVzdCBjaG9vc2UgYSBkZWZhdWx0IHNlcXVlbmNlIHRoYXQgbWF0Y2hlcyBvbmUgb2YKKyAgICAgKiB0aG9zZSBhbGxvd2VkIGJ5IFhNTCAxLjAgb3IgWE1MIDEuMSwgZGVwZW5kaW5nIG9uIHRoZSBzZXJpYWxpemVkCisgICAgICogY29udGVudC4gU2V0dGluZyB0aGlzIGF0dHJpYnV0ZSB0byA8Y29kZT5udWxsPC9jb2RlPiB3aWxsIHJlc2V0IGl0cworICAgICAqIHZhbHVlIHRvIHRoZSBkZWZhdWx0IHZhbHVlLgorICAgICAqIDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5ld0xpbmUoKTsKKyAgICAvKioKKyAgICAgKiAgVGhlIGVuZC1vZi1saW5lIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgdG8gYmUgdXNlZCBpbiB0aGUgWE1MIGJlaW5nCisgICAgICogd3JpdHRlbiBvdXQuIEFueSBzdHJpbmcgaXMgc3VwcG9ydGVkLCBidXQgWE1MIHRyZWF0cyBvbmx5IGEgY2VydGFpbgorICAgICAqIHNldCBvZiBjaGFyYWN0ZXJzIHNlcXVlbmNlIGFzIGVuZC1vZi1saW5lIChTZWUgc2VjdGlvbiAyLjExLAorICAgICAqICJFbmQtb2YtTGluZSBIYW5kbGluZyIgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dLCBpZiB0aGUKKyAgICAgKiBzZXJpYWxpemVkIGNvbnRlbnQgaXMgWE1MIDEuMCBvciBzZWN0aW9uIDIuMTEsICJFbmQtb2YtTGluZSBIYW5kbGluZyIKKyAgICAgKiBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sMTEtMjAwNDAyMDQvJz5YTUwgMS4xPC9hPl0sIGlmIHRoZQorICAgICAqIHNlcmlhbGl6ZWQgY29udGVudCBpcyBYTUwgMS4xKS4gVXNpbmcgb3RoZXIgY2hhcmFjdGVyIHNlcXVlbmNlcyB0aGFuCisgICAgICogdGhlIHJlY29tbWVuZGVkIG9uZXMgY2FuIHJlc3VsdCBpbiBhIGRvY3VtZW50IHRoYXQgaXMgZWl0aGVyIG5vdAorICAgICAqIHNlcmlhbGl6YWJsZSBvciBub3Qgd2VsbC1mb3JtZWQpLgorICAgICAqIDxicj4gT24gcmV0cmlldmFsLCB0aGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGlzIGF0dHJpYnV0ZSBpcyB0aGUKKyAgICAgKiBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYyBkZWZhdWx0IGVuZC1vZi1saW5lIHNlcXVlbmNlLiBET00KKyAgICAgKiBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIGNob29zZSB0aGUgZGVmYXVsdCB0byBtYXRjaCB0aGUgdXN1YWwKKyAgICAgKiBjb252ZW50aW9uIGZvciB0ZXh0IGZpbGVzIGluIHRoZSBlbnZpcm9ubWVudCBiZWluZyB1c2VkLgorICAgICAqIEltcGxlbWVudGF0aW9ucyBtdXN0IGNob29zZSBhIGRlZmF1bHQgc2VxdWVuY2UgdGhhdCBtYXRjaGVzIG9uZSBvZgorICAgICAqIHRob3NlIGFsbG93ZWQgYnkgWE1MIDEuMCBvciBYTUwgMS4xLCBkZXBlbmRpbmcgb24gdGhlIHNlcmlhbGl6ZWQKKyAgICAgKiBjb250ZW50LiBTZXR0aW5nIHRoaXMgYXR0cmlidXRlIHRvIDxjb2RlPm51bGw8L2NvZGU+IHdpbGwgcmVzZXQgaXRzCisgICAgICogdmFsdWUgdG8gdGhlIGRlZmF1bHQgdmFsdWUuCisgICAgICogPGJyPgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5ld0xpbmUoU3RyaW5nIG5ld0xpbmUpOworCisgICAgLyoqCisgICAgICogIFdoZW4gdGhlIGFwcGxpY2F0aW9uIHByb3ZpZGVzIGEgZmlsdGVyLCB0aGUgc2VyaWFsaXplciB3aWxsIGNhbGwgb3V0CisgICAgICogdG8gdGhlIGZpbHRlciBiZWZvcmUgc2VyaWFsaXppbmcgZWFjaCBOb2RlLiBUaGUgZmlsdGVyIGltcGxlbWVudGF0aW9uCisgICAgICogY2FuIGNob29zZSB0byByZW1vdmUgdGhlIG5vZGUgZnJvbSB0aGUgc3RyZWFtIG9yIHRvIHRlcm1pbmF0ZSB0aGUKKyAgICAgKiBzZXJpYWxpemF0aW9uIGVhcmx5LgorICAgICAqIDxicj4gVGhlIGZpbHRlciBpcyBpbnZva2VkIGFmdGVyIHRoZSBvcGVyYXRpb25zIHJlcXVlc3RlZCBieSB0aGUKKyAgICAgKiA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBwYXJhbWV0ZXJzIGhhdmUgYmVlbiBhcHBsaWVkLiBGb3IKKyAgICAgKiBleGFtcGxlLCBDREFUQSBzZWN0aW9ucyB3b24ndCBiZSBwYXNzZWQgdG8gdGhlIGZpbHRlciBpZiAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLWNkYXRhLXNlY3Rpb25zJz4KKyAgICAgKiBjZGF0YS1zZWN0aW9uczwvYT4iIGlzIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4uCisgICAgICoKKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIHB1YmxpYyBMU1NlcmlhbGl6ZXJGaWx0ZXIgZ2V0RmlsdGVyKCk7CisgICAgLyoqCisgICAgICogIFdoZW4gdGhlIGFwcGxpY2F0aW9uIHByb3ZpZGVzIGEgZmlsdGVyLCB0aGUgc2VyaWFsaXplciB3aWxsIGNhbGwgb3V0CisgICAgICogdG8gdGhlIGZpbHRlciBiZWZvcmUgc2VyaWFsaXppbmcgZWFjaCBOb2RlLiBUaGUgZmlsdGVyIGltcGxlbWVudGF0aW9uCisgICAgICogY2FuIGNob29zZSB0byByZW1vdmUgdGhlIG5vZGUgZnJvbSB0aGUgc3RyZWFtIG9yIHRvIHRlcm1pbmF0ZSB0aGUKKyAgICAgKiBzZXJpYWxpemF0aW9uIGVhcmx5LgorICAgICAqIDxicj4gVGhlIGZpbHRlciBpcyBpbnZva2VkIGFmdGVyIHRoZSBvcGVyYXRpb25zIHJlcXVlc3RlZCBieSB0aGUKKyAgICAgKiA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBwYXJhbWV0ZXJzIGhhdmUgYmVlbiBhcHBsaWVkLiBGb3IKKyAgICAgKiBleGFtcGxlLCBDREFUQSBzZWN0aW9ucyB3b24ndCBiZSBwYXNzZWQgdG8gdGhlIGZpbHRlciBpZiAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLWNkYXRhLXNlY3Rpb25zJz4KKyAgICAgKiBjZGF0YS1zZWN0aW9uczwvYT4iIGlzIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4uCisgICAgICoKKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZpbHRlcihMU1NlcmlhbGl6ZXJGaWx0ZXIgZmlsdGVyKTsKKworICAgIC8qKgorICAgICAqICBTZXJpYWxpemUgdGhlIHNwZWNpZmllZCBub2RlIGFzIGRlc2NyaWJlZCBhYm92ZSBpbiB0aGUgZ2VuZXJhbAorICAgICAqIGRlc2NyaXB0aW9uIG9mIHRoZSA8Y29kZT5MU1NlcmlhbGl6ZXI8L2NvZGU+IGludGVyZmFjZS4gVGhlIG91dHB1dCBpcworICAgICAqIHdyaXR0ZW4gdG8gdGhlIHN1cHBsaWVkIDxjb2RlPkxTT3V0cHV0PC9jb2RlPi4KKyAgICAgKiA8YnI+IFdoZW4gd3JpdGluZyB0byBhIDxjb2RlPkxTT3V0cHV0PC9jb2RlPiwgdGhlIGVuY29kaW5nIGlzIGZvdW5kIGJ5CisgICAgICogbG9va2luZyBhdCB0aGUgZW5jb2RpbmcgaW5mb3JtYXRpb24gdGhhdCBpcyByZWFjaGFibGUgdGhyb3VnaCB0aGUKKyAgICAgKiA8Y29kZT5MU091dHB1dDwvY29kZT4gYW5kIHRoZSBpdGVtIHRvIGJlIHdyaXR0ZW4gKG9yIGl0cyBvd25lcgorICAgICAqIGRvY3VtZW50KSBpbiB0aGlzIG9yZGVyOgorICAgICAqIDxvbD4KKyAgICAgKiA8bGk+IDxjb2RlPkxTT3V0cHV0LmVuY29kaW5nPC9jb2RlPiwKKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT4KKyAgICAgKiA8Y29kZT5Eb2N1bWVudC5pbnB1dEVuY29kaW5nPC9jb2RlPiwKKyAgICAgKiA8L2xpPgorICAgICAqIDxsaT4KKyAgICAgKiA8Y29kZT5Eb2N1bWVudC54bWxFbmNvZGluZzwvY29kZT4uCisgICAgICogPC9saT4KKyAgICAgKiA8L29sPgorICAgICAqIDxicj4gSWYgbm8gZW5jb2RpbmcgaXMgcmVhY2hhYmxlIHRocm91Z2ggdGhlIGFib3ZlIHByb3BlcnRpZXMsIGEKKyAgICAgKiBkZWZhdWx0IGVuY29kaW5nIG9mICJVVEYtOCIgd2lsbCBiZSB1c2VkLiBJZiB0aGUgc3BlY2lmaWVkIGVuY29kaW5nCisgICAgICogaXMgbm90IHN1cHBvcnRlZCBhbiAidW5zdXBwb3J0ZWQtZW5jb2RpbmciIGZhdGFsIGVycm9yIGlzIHJhaXNlZC4KKyAgICAgKiA8YnI+IElmIG5vIG91dHB1dCBpcyBzcGVjaWZpZWQgaW4gdGhlIDxjb2RlPkxTT3V0cHV0PC9jb2RlPiwgYQorICAgICAqICJuby1vdXRwdXQtc3BlY2lmaWVkIiBmYXRhbCBlcnJvciBpcyByYWlzZWQuCisgICAgICogPGJyPiBUaGUgaW1wbGVtZW50YXRpb24gaXMgcmVzcG9uc2libGUgb2YgYXNzb2NpYXRpbmcgdGhlIGFwcHJvcHJpYXRlCisgICAgICogbWVkaWEgdHlwZSB3aXRoIHRoZSBzZXJpYWxpemVkIGRhdGEuCisgICAgICogPGJyPiBXaGVuIHdyaXRpbmcgdG8gYSBIVFRQIFVSSSwgYSBIVFRQIFBVVCBpcyBwZXJmb3JtZWQuIFdoZW4gd3JpdGluZworICAgICAqIHRvIG90aGVyIHR5cGVzIG9mIFVSSXMsIHRoZSBtZWNoYW5pc20gZm9yIHdyaXRpbmcgdGhlIGRhdGEgdG8gdGhlIFVSSQorICAgICAqIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KKyAgICAgKiBAcGFyYW0gbm9kZUFyZyAgVGhlIG5vZGUgdG8gc2VyaWFsaXplLgorICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbiBUaGUgZGVzdGluYXRpb24gZm9yIHRoZSBzZXJpYWxpemVkIERPTS4KKyAgICAgKiBAcmV0dXJuICBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIDxjb2RlPm5vZGU8L2NvZGU+IHdhcworICAgICAqICAgc3VjY2Vzc2Z1bGx5IHNlcmlhbGl6ZWQuIFJldHVybiA8Y29kZT5mYWxzZTwvY29kZT4gaW4gY2FzZSB0aGUKKyAgICAgKiAgIG5vcm1hbCBwcm9jZXNzaW5nIHN0b3BwZWQgYnV0IHRoZSBpbXBsZW1lbnRhdGlvbiBrZXB0IHNlcmlhbGl6aW5nCisgICAgICogICB0aGUgZG9jdW1lbnQ7IHRoZSByZXN1bHQgb2YgdGhlIHNlcmlhbGl6YXRpb24gYmVpbmcgaW1wbGVtZW50YXRpb24KKyAgICAgKiAgIGRlcGVuZGVudCB0aGVuLgorICAgICAqIEBleGNlcHRpb24gTFNFeGNlcHRpb24KKyAgICAgKiAgICBTRVJJQUxJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gd2FzIHVuYWJsZSB0bworICAgICAqICAgc2VyaWFsaXplIHRoZSBub2RlLiBET00gYXBwbGljYXRpb25zIHNob3VsZCBhdHRhY2ggYQorICAgICAqICAgPGNvZGU+RE9NRXJyb3JIYW5kbGVyPC9jb2RlPiB1c2luZyB0aGUgcGFyYW1ldGVyICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItZXJyb3ItaGFuZGxlcic+CisgICAgICogICBlcnJvci1oYW5kbGVyPC9hPiIgaWYgdGhleSB3aXNoIHRvIGdldCBkZXRhaWxzIG9uIHRoZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB3cml0ZShOb2RlIG5vZGVBcmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgTFNPdXRwdXQgZGVzdGluYXRpb24pCisgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIExTRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogIEEgY29udmVuaWVuY2UgbWV0aG9kIHRoYXQgYWN0cyBhcyBpZiA8Y29kZT5MU1NlcmlhbGl6ZXIud3JpdGU8L2NvZGU+CisgICAgICogd2FzIGNhbGxlZCB3aXRoIGEgPGNvZGU+TFNPdXRwdXQ8L2NvZGU+IHdpdGggbm8gZW5jb2Rpbmcgc3BlY2lmaWVkCisgICAgICogYW5kIDxjb2RlPkxTT3V0cHV0LnN5c3RlbUlkPC9jb2RlPiBzZXQgdG8gdGhlIDxjb2RlPnVyaTwvY29kZT4KKyAgICAgKiBhcmd1bWVudC4KKyAgICAgKiBAcGFyYW0gbm9kZUFyZyAgVGhlIG5vZGUgdG8gc2VyaWFsaXplLgorICAgICAqIEBwYXJhbSB1cmkgVGhlIFVSSSB0byB3cml0ZSB0by4KKyAgICAgKiBAcmV0dXJuICBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIDxjb2RlPm5vZGU8L2NvZGU+IHdhcworICAgICAqICAgc3VjY2Vzc2Z1bGx5IHNlcmlhbGl6ZWQuIFJldHVybiA8Y29kZT5mYWxzZTwvY29kZT4gaW4gY2FzZSB0aGUKKyAgICAgKiAgIG5vcm1hbCBwcm9jZXNzaW5nIHN0b3BwZWQgYnV0IHRoZSBpbXBsZW1lbnRhdGlvbiBrZXB0IHNlcmlhbGl6aW5nCisgICAgICogICB0aGUgZG9jdW1lbnQ7IHRoZSByZXN1bHQgb2YgdGhlIHNlcmlhbGl6YXRpb24gYmVpbmcgaW1wbGVtZW50YXRpb24KKyAgICAgKiAgIGRlcGVuZGVudCB0aGVuLgorICAgICAqIEBleGNlcHRpb24gTFNFeGNlcHRpb24KKyAgICAgKiAgICBTRVJJQUxJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gd2FzIHVuYWJsZSB0bworICAgICAqICAgc2VyaWFsaXplIHRoZSBub2RlLiBET00gYXBwbGljYXRpb25zIHNob3VsZCBhdHRhY2ggYQorICAgICAqICAgPGNvZGU+RE9NRXJyb3JIYW5kbGVyPC9jb2RlPiB1c2luZyB0aGUgcGFyYW1ldGVyICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItZXJyb3ItaGFuZGxlcic+CisgICAgICogICBlcnJvci1oYW5kbGVyPC9hPiIgaWYgdGhleSB3aXNoIHRvIGdldCBkZXRhaWxzIG9uIHRoZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB3cml0ZVRvVVJJKE5vZGUgbm9kZUFyZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB1cmkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTFNFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiAgU2VyaWFsaXplIHRoZSBzcGVjaWZpZWQgbm9kZSBhcyBkZXNjcmliZWQgYWJvdmUgaW4gdGhlIGdlbmVyYWwKKyAgICAgKiBkZXNjcmlwdGlvbiBvZiB0aGUgPGNvZGU+TFNTZXJpYWxpemVyPC9jb2RlPiBpbnRlcmZhY2UuIFRoZSBvdXRwdXQgaXMKKyAgICAgKiB3cml0dGVuIHRvIGEgPGNvZGU+RE9NU3RyaW5nPC9jb2RlPiB0aGF0IGlzIHJldHVybmVkIHRvIHRoZSBjYWxsZXIuCisgICAgICogVGhlIGVuY29kaW5nIHVzZWQgaXMgdGhlIGVuY29kaW5nIG9mIHRoZSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IHR5cGUsCisgICAgICogaS5lLiBVVEYtMTYuIE5vdGUgdGhhdCBubyBCeXRlIE9yZGVyIE1hcmsgaXMgZ2VuZXJhdGVkIGluIGEKKyAgICAgKiA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IG9iamVjdC4KKyAgICAgKiBAcGFyYW0gbm9kZUFyZyAgVGhlIG5vZGUgdG8gc2VyaWFsaXplLgorICAgICAqIEByZXR1cm4gIFJldHVybnMgdGhlIHNlcmlhbGl6ZWQgZGF0YS4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgIERPTVNUUklOR19TSVpFX0VSUjogUmFpc2VkIGlmIHRoZSByZXN1bHRpbmcgc3RyaW5nIGlzIHRvbyBsb25nIHRvCisgICAgICogICBmaXQgaW4gYSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+LgorICAgICAqIEBleGNlcHRpb24gTFNFeGNlcHRpb24KKyAgICAgKiAgICBTRVJJQUxJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gd2FzIHVuYWJsZSB0bworICAgICAqICAgc2VyaWFsaXplIHRoZSBub2RlLiBET00gYXBwbGljYXRpb25zIHNob3VsZCBhdHRhY2ggYQorICAgICAqICAgPGNvZGU+RE9NRXJyb3JIYW5kbGVyPC9jb2RlPiB1c2luZyB0aGUgcGFyYW1ldGVyICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItZXJyb3ItaGFuZGxlcic+CisgICAgICogICBlcnJvci1oYW5kbGVyPC9hPiIgaWYgdGhleSB3aXNoIHRvIGdldCBkZXRhaWxzIG9uIHRoZSBlcnJvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHdyaXRlVG9TdHJpbmcoTm9kZSBub2RlQXJnKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uLCBMU0V4Y2VwdGlvbjsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL2xzL0xTU2VyaWFsaXplckZpbHRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL2xzL0xTU2VyaWFsaXplckZpbHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBhMDM4MTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vbHMvTFNTZXJpYWxpemVyRmlsdGVyLmphdmEKQEAgLTAsMCArMSw2NSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICoKKyAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgorICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCisgKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAorICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCisgKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCisgKgorICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tLmxzOworCitpbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXI7CisKKy8qKgorICogIDxjb2RlPkxTU2VyaWFsaXplckZpbHRlcjwvY29kZT5zIHByb3ZpZGUgYXBwbGljYXRpb25zIHRoZSBhYmlsaXR5IHRvCisgKiBleGFtaW5lIG5vZGVzIGFzIHRoZXkgYXJlIGJlaW5nIHNlcmlhbGl6ZWQgYW5kIGRlY2lkZSB3aGF0IG5vZGVzIHNob3VsZAorICogYmUgc2VyaWFsaXplZCBvciBub3QuIFRoZSA8Y29kZT5MU1NlcmlhbGl6ZXJGaWx0ZXI8L2NvZGU+IGludGVyZmFjZSBpcworICogYmFzZWQgb24gdGhlIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IGludGVyZmFjZSBkZWZpbmVkIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1JFQy1ET00tTGV2ZWwtMi1UcmF2ZXJzYWwtUmFuZ2UtMjAwMDExMTMnPkRPTSBMZXZlbCAyIFRyYXZlcnNhbCBhbmQgICAgICBSYW5nZTwvYT5dCisgKiAuCisgKiA8cD4gPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LCA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+LAorICogPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4sIDxjb2RlPk5vdGF0aW9uPC9jb2RlPiwgPGNvZGU+RW50aXR5PC9jb2RlPgorICogLCBhbmQgY2hpbGRyZW4gb2YgPGNvZGU+QXR0cjwvY29kZT4gbm9kZXMgYXJlIG5vdCBwYXNzZWQgdG8gdGhlIGZpbHRlci4KKyAqIFRoZSBjaGlsZCBub2RlcyBvZiBhbiA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IG5vZGUgYXJlIG9ubHkgcGFzc2VkCisgKiB0byB0aGUgZmlsdGVyIGlmIHRoZSA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IG5vZGUgaXMgc2tpcHBlZCBieSB0aGUKKyAqIG1ldGhvZCA8Y29kZT5MU1BhcnNlckZpbHRlci5hY2NlcHROb2RlKCk8L2NvZGU+LgorICogPHA+IFdoZW4gc2VyaWFsaXppbmcgYW4gPGNvZGU+RWxlbWVudDwvY29kZT4sIHRoZSBlbGVtZW50IGlzIHBhc3NlZCB0byB0aGUKKyAqIGZpbHRlciBiZWZvcmUgYW55IG9mIGl0cyBhdHRyaWJ1dGVzIGFyZSBwYXNzZWQgdG8gdGhlIGZpbHRlci4gTmFtZXNwYWNlCisgKiBkZWNsYXJhdGlvbiBhdHRyaWJ1dGVzLCBhbmQgZGVmYXVsdCBhdHRyaWJ1dGVzIChleGNlcHQgaW4gdGhlIGNhc2Ugd2hlbiAiCisgKiBkaXNjYXJkLWRlZmF1bHQtY29udGVudCIgaXMgc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiksIGFyZSBuZXZlciBwYXNzZWQKKyAqIHRvIHRoZSBmaWx0ZXIuCisgKiA8cD4gVGhlIHJlc3VsdCBvZiBhbnkgYXR0ZW1wdCB0byBtb2RpZnkgYSBub2RlIHBhc3NlZCB0byBhCisgKiA8Y29kZT5MU1NlcmlhbGl6ZXJGaWx0ZXI8L2NvZGU+IGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KKyAqIDxwPiBET00gYXBwbGljYXRpb25zIG11c3Qgbm90IHJhaXNlIGV4Y2VwdGlvbnMgaW4gYSBmaWx0ZXIuIFRoZSBlZmZlY3Qgb2YKKyAqIHRocm93aW5nIGV4Y2VwdGlvbnMgZnJvbSBhIGZpbHRlciBpcyBET00gaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgorICogPHA+IEZvciBlZmZpY2llbmN5LCBhIG5vZGUgcGFzc2VkIHRvIHRoZSBmaWx0ZXIgbWF5IG5vdCBiZSB0aGUgc2FtZSBhcyB0aGUKKyAqIG9uZSB0aGF0IGlzIGFjdHVhbGx5IGluIHRoZSB0cmVlLiBBbmQgdGhlIGFjdHVhbCBub2RlIChub2RlIG9iamVjdAorICogaWRlbnRpdHkpIG1heSBiZSByZXVzZWQgZHVyaW5nIHRoZSBwcm9jZXNzIG9mIGZpbHRlcmluZyBhbmQgc2VyaWFsaXppbmcgYQorICogZG9jdW1lbnQuCisgKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtTFMtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIExvYWQKK2FuZCBTYXZlIFNwZWNpZmljYXRpb248L2E+LgorICoKKyAqIEBoaWRlCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgTFNTZXJpYWxpemVyRmlsdGVyIGV4dGVuZHMgTm9kZUZpbHRlciB7CisgICAgLyoqCisgICAgICogIFRlbGxzIHRoZSA8Y29kZT5MU1NlcmlhbGl6ZXI8L2NvZGU+IHdoYXQgdHlwZXMgb2Ygbm9kZXMgdG8gc2hvdyB0byB0aGUKKyAgICAgKiBmaWx0ZXIuIElmIGEgbm9kZSBpcyBub3Qgc2hvd24gdG8gdGhlIGZpbHRlciB1c2luZyB0aGlzIGF0dHJpYnV0ZSwgaXQKKyAgICAgKiBpcyBhdXRvbWF0aWNhbGx5IHNlcmlhbGl6ZWQuIFNlZSA8Y29kZT5Ob2RlRmlsdGVyPC9jb2RlPiBmb3IKKyAgICAgKiBkZWZpbml0aW9uIG9mIHRoZSBjb25zdGFudHMuIFRoZSBjb25zdGFudHMgPGNvZGU+U0hPV19ET0NVTUVOVDwvY29kZT4KKyAgICAgKiAsIDxjb2RlPlNIT1dfRE9DVU1FTlRfVFlQRTwvY29kZT4sIDxjb2RlPlNIT1dfRE9DVU1FTlRfRlJBR01FTlQ8L2NvZGU+CisgICAgICogLCA8Y29kZT5TSE9XX05PVEFUSU9OPC9jb2RlPiwgYW5kIDxjb2RlPlNIT1dfRU5USVRZPC9jb2RlPiBhcmUKKyAgICAgKiBtZWFuaW5nbGVzcyBoZXJlLCBzdWNoIG5vZGVzIHdpbGwgbmV2ZXIgYmUgcGFzc2VkIHRvIGEKKyAgICAgKiA8Y29kZT5MU1NlcmlhbGl6ZXJGaWx0ZXI8L2NvZGU+LgorICAgICAqIDxicj4gVW5saWtlIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1JFQy1ET00tTGV2ZWwtMi1UcmF2ZXJzYWwtUmFuZ2UtMjAwMDExMTMnPkRPTSBMZXZlbCAyIFRyYXZlcnNhbCBhbmQgICAgICBSYW5nZTwvYT5dCisgICAgICogLCB0aGUgPGNvZGU+U0hPV19BVFRSSUJVVEU8L2NvZGU+IGNvbnN0YW50IGluZGljYXRlcyB0aGF0IHRoZQorICAgICAqIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzIGFyZSBzaG93biBhbmQgcGFzc2VkIHRvIHRoZSBmaWx0ZXIuCisgICAgICogPGJyPiBUaGUgY29uc3RhbnRzIHVzZWQgaGVyZSBhcmUgZGVmaW5lZCBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItVHJhdmVyc2FsLVJhbmdlLTIwMDAxMTEzJz5ET00gTGV2ZWwgMiBUcmF2ZXJzYWwgYW5kICAgICAgUmFuZ2U8L2E+XQorICAgICAqIC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFdoYXRUb1Nob3coKTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL3BhY2thZ2UuaHRtbCBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTVmOGZmNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwxMCBAQAorPGh0bWw+CisgIDxib2R5PgorICAgIDxwPgorICAgICAgUHJvdmlkZXMgdGhlIG9mZmljaWFsIFczQyBKYXZhIGJpbmRpbmdzIGZvciB0aGUgRG9jdW1lbnQgT2JqZWN0IE1vZGVsLAorICAgICAgbGV2ZWwgMiBjb3JlLiBYTUwgZG9jdW1lbnRzIHJldHVybmVkIGJ5CisgICAgICB7QGxpbmsgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyfSBhcmUgYWNjZXNzZWQgYW5kIG1hbmlwdWxhdGVkCisgICAgICB0aHJvdWdoIHRoZXNlIGludGVyZmFjZXMuCisgICAgPC9wPgorICA8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vdHJhdmVyc2FsL05vZGVGaWx0ZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcvdzNjL2RvbS90cmF2ZXJzYWwvTm9kZUZpbHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEyZjYzNzcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vdHJhdmVyc2FsL05vZGVGaWx0ZXIuamF2YQpAQCAtMCwwICsxLDE0NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tLnRyYXZlcnNhbDsKKworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CisKKy8qKgorICogRmlsdGVycyBhcmUgb2JqZWN0cyB0aGF0IGtub3cgaG93IHRvICJmaWx0ZXIgb3V0IiBub2Rlcy4gSWYgYQorICogPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPiBvciA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiBpcyBnaXZlbiBhCisgKiA8Y29kZT5Ob2RlRmlsdGVyPC9jb2RlPiwgaXQgYXBwbGllcyB0aGUgZmlsdGVyIGJlZm9yZSBpdCByZXR1cm5zIHRoZSBuZXh0CisgKiBub2RlLiBJZiB0aGUgZmlsdGVyIHNheXMgdG8gYWNjZXB0IHRoZSBub2RlLCB0aGUgdHJhdmVyc2FsIGxvZ2ljIHJldHVybnMKKyAqIGl0OyBvdGhlcndpc2UsIHRyYXZlcnNhbCBsb29rcyBmb3IgdGhlIG5leHQgbm9kZSBhbmQgcHJldGVuZHMgdGhhdCB0aGUKKyAqIG5vZGUgdGhhdCB3YXMgcmVqZWN0ZWQgd2FzIG5vdCB0aGVyZS4KKyAqIDxwPlRoZSBET00gZG9lcyBub3QgcHJvdmlkZSBhbnkgZmlsdGVycy4gPGNvZGU+Tm9kZUZpbHRlcjwvY29kZT4gaXMganVzdCBhbgorICogaW50ZXJmYWNlIHRoYXQgdXNlcnMgY2FuIGltcGxlbWVudCB0byBwcm92aWRlIHRoZWlyIG93biBmaWx0ZXJzLgorICogPHA+PGNvZGU+Tm9kZUZpbHRlcnM8L2NvZGU+IGRvIG5vdCBuZWVkIHRvIGtub3cgaG93IHRvIHRyYXZlcnNlIGZyb20gbm9kZQorICogdG8gbm9kZSwgbm9yIGRvIHRoZXkgbmVlZCB0byBrbm93IGFueXRoaW5nIGFib3V0IHRoZSBkYXRhIHN0cnVjdHVyZSB0aGF0CisgKiBpcyBiZWluZyB0cmF2ZXJzZWQuIFRoaXMgbWFrZXMgaXQgdmVyeSBlYXN5IHRvIHdyaXRlIGZpbHRlcnMsIHNpbmNlIHRoZQorICogb25seSB0aGluZyB0aGV5IGhhdmUgdG8ga25vdyBob3cgdG8gZG8gaXMgZXZhbHVhdGUgYSBzaW5nbGUgbm9kZS4gT25lCisgKiBmaWx0ZXIgbWF5IGJlIHVzZWQgd2l0aCBhIG51bWJlciBvZiBkaWZmZXJlbnQga2luZHMgb2YgdHJhdmVyc2FscywKKyAqIGVuY291cmFnaW5nIGNvZGUgcmV1c2UuCisgKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItVHJhdmVyc2FsLVJhbmdlLTIwMDAxMTEzJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBUcmF2ZXJzYWwgYW5kIFJhbmdlIFNwZWNpZmljYXRpb248L2E+LgorICogQHNpbmNlIERPTSBMZXZlbCAyCisgKgorICogQGhpZGUKKyAqLworcHVibGljIGludGVyZmFjZSBOb2RlRmlsdGVyIHsKKyAgICAvLyBDb25zdGFudHMgcmV0dXJuZWQgYnkgYWNjZXB0Tm9kZQorICAgIC8qKgorICAgICAqIEFjY2VwdCB0aGUgbm9kZS4gTmF2aWdhdGlvbiBtZXRob2RzIGRlZmluZWQgZm9yCisgICAgICogPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPiBvciA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiB3aWxsIHJldHVybiB0aGlzCisgICAgICogbm9kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZJTFRFUl9BQ0NFUFQgICAgICAgICAgICAgPSAxOworICAgIC8qKgorICAgICAqIFJlamVjdCB0aGUgbm9kZS4gTmF2aWdhdGlvbiBtZXRob2RzIGRlZmluZWQgZm9yCisgICAgICogPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPiBvciA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiB3aWxsIG5vdCByZXR1cm4KKyAgICAgKiB0aGlzIG5vZGUuIEZvciA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiwgdGhlIGNoaWxkcmVuIG9mIHRoaXMgbm9kZQorICAgICAqIHdpbGwgYWxzbyBiZSByZWplY3RlZC4gPGNvZGU+Tm9kZUl0ZXJhdG9yczwvY29kZT4gdHJlYXQgdGhpcyBhcyBhCisgICAgICogc3lub255bSBmb3IgPGNvZGU+RklMVEVSX1NLSVA8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRklMVEVSX1JFSkVDVCAgICAgICAgICAgICA9IDI7CisgICAgLyoqCisgICAgICogU2tpcCB0aGlzIHNpbmdsZSBub2RlLiBOYXZpZ2F0aW9uIG1ldGhvZHMgZGVmaW5lZCBmb3IKKyAgICAgKiA8Y29kZT5Ob2RlSXRlcmF0b3I8L2NvZGU+IG9yIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+IHdpbGwgbm90IHJldHVybgorICAgICAqIHRoaXMgbm9kZS4gRm9yIGJvdGggPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPiBhbmQKKyAgICAgKiA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiwgdGhlIGNoaWxkcmVuIG9mIHRoaXMgbm9kZSB3aWxsIHN0aWxsIGJlCisgICAgICogY29uc2lkZXJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZJTFRFUl9TS0lQICAgICAgICAgICAgICAgPSAzOworCisgICAgLy8gQ29uc3RhbnRzIGZvciB3aGF0VG9TaG93CisgICAgLyoqCisgICAgICogU2hvdyBhbGwgPGNvZGU+Tm9kZXM8L2NvZGU+LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfQUxMICAgICAgICAgICAgICAgICAgPSAweEZGRkZGRkZGOworICAgIC8qKgorICAgICAqIFNob3cgPGNvZGU+RWxlbWVudDwvY29kZT4gbm9kZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19FTEVNRU5UICAgICAgICAgICAgICA9IDB4MDAwMDAwMDE7CisgICAgLyoqCisgICAgICogU2hvdyA8Y29kZT5BdHRyPC9jb2RlPiBub2Rlcy4gVGhpcyBpcyBtZWFuaW5nZnVsIG9ubHkgd2hlbiBjcmVhdGluZyBhbgorICAgICAqIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4gb3IgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4gd2l0aCBhbgorICAgICAqIGF0dHJpYnV0ZSBub2RlIGFzIGl0cyA8Y29kZT5yb290PC9jb2RlPjsgaW4gdGhpcyBjYXNlLCBpdCBtZWFucyB0aGF0CisgICAgICogdGhlIGF0dHJpYnV0ZSBub2RlIHdpbGwgYXBwZWFyIGluIHRoZSBmaXJzdCBwb3NpdGlvbiBvZiB0aGUgaXRlcmF0aW9uCisgICAgICogb3IgdHJhdmVyc2FsLiBTaW5jZSBhdHRyaWJ1dGVzIGFyZSBuZXZlciBjaGlsZHJlbiBvZiBvdGhlciBub2RlcywKKyAgICAgKiB0aGV5IGRvIG5vdCBhcHBlYXIgd2hlbiB0cmF2ZXJzaW5nIG92ZXIgdGhlIGRvY3VtZW50IHRyZWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19BVFRSSUJVVEUgICAgICAgICAgICA9IDB4MDAwMDAwMDI7CisgICAgLyoqCisgICAgICogU2hvdyA8Y29kZT5UZXh0PC9jb2RlPiBub2Rlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX1RFWFQgICAgICAgICAgICAgICAgID0gMHgwMDAwMDAwNDsKKyAgICAvKioKKyAgICAgKiBTaG93IDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gbm9kZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19DREFUQV9TRUNUSU9OICAgICAgICA9IDB4MDAwMDAwMDg7CisgICAgLyoqCisgICAgICogU2hvdyA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IG5vZGVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfRU5USVRZX1JFRkVSRU5DRSAgICAgPSAweDAwMDAwMDEwOworICAgIC8qKgorICAgICAqIFNob3cgPGNvZGU+RW50aXR5PC9jb2RlPiBub2Rlcy4gVGhpcyBpcyBtZWFuaW5nZnVsIG9ubHkgd2hlbiBjcmVhdGluZworICAgICAqIGFuIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4gb3IgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4gd2l0aCBhbgorICAgICAqIDxjb2RlPkVudGl0eTwvY29kZT4gbm9kZSBhcyBpdHMgPGNvZGU+cm9vdDwvY29kZT47IGluIHRoaXMgY2FzZSwgaXQKKyAgICAgKiBtZWFucyB0aGF0IHRoZSA8Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGUgd2lsbCBhcHBlYXIgaW4gdGhlIGZpcnN0CisgICAgICogcG9zaXRpb24gb2YgdGhlIHRyYXZlcnNhbC4gU2luY2UgZW50aXRpZXMgYXJlIG5vdCBwYXJ0IG9mIHRoZQorICAgICAqIGRvY3VtZW50IHRyZWUsIHRoZXkgZG8gbm90IGFwcGVhciB3aGVuIHRyYXZlcnNpbmcgb3ZlciB0aGUgZG9jdW1lbnQKKyAgICAgKiB0cmVlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfRU5USVRZICAgICAgICAgICAgICAgPSAweDAwMDAwMDIwOworICAgIC8qKgorICAgICAqIFNob3cgPGNvZGU+UHJvY2Vzc2luZ0luc3RydWN0aW9uPC9jb2RlPiBub2Rlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04gPSAweDAwMDAwMDQwOworICAgIC8qKgorICAgICAqIFNob3cgPGNvZGU+Q29tbWVudDwvY29kZT4gbm9kZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19DT01NRU5UICAgICAgICAgICAgICA9IDB4MDAwMDAwODA7CisgICAgLyoqCisgICAgICogU2hvdyA8Y29kZT5Eb2N1bWVudDwvY29kZT4gbm9kZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19ET0NVTUVOVCAgICAgICAgICAgICA9IDB4MDAwMDAxMDA7CisgICAgLyoqCisgICAgICogU2hvdyA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IG5vZGVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfRE9DVU1FTlRfVFlQRSAgICAgICAgPSAweDAwMDAwMjAwOworICAgIC8qKgorICAgICAqIFNob3cgPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4gbm9kZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19ET0NVTUVOVF9GUkFHTUVOVCAgICA9IDB4MDAwMDA0MDA7CisgICAgLyoqCisgICAgICogU2hvdyA8Y29kZT5Ob3RhdGlvbjwvY29kZT4gbm9kZXMuIFRoaXMgaXMgbWVhbmluZ2Z1bCBvbmx5IHdoZW4gY3JlYXRpbmcKKyAgICAgKiBhbiA8Y29kZT5Ob2RlSXRlcmF0b3I8L2NvZGU+IG9yIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+IHdpdGggYQorICAgICAqIDxjb2RlPk5vdGF0aW9uPC9jb2RlPiBub2RlIGFzIGl0cyA8Y29kZT5yb290PC9jb2RlPjsgaW4gdGhpcyBjYXNlLCBpdAorICAgICAqIG1lYW5zIHRoYXQgdGhlIDxjb2RlPk5vdGF0aW9uPC9jb2RlPiBub2RlIHdpbGwgYXBwZWFyIGluIHRoZSBmaXJzdAorICAgICAqIHBvc2l0aW9uIG9mIHRoZSB0cmF2ZXJzYWwuIFNpbmNlIG5vdGF0aW9ucyBhcmUgbm90IHBhcnQgb2YgdGhlCisgICAgICogZG9jdW1lbnQgdHJlZSwgdGhleSBkbyBub3QgYXBwZWFyIHdoZW4gdHJhdmVyc2luZyBvdmVyIHRoZSBkb2N1bWVudAorICAgICAqIHRyZWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19OT1RBVElPTiAgICAgICAgICAgICA9IDB4MDAwMDA4MDA7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHdoZXRoZXIgYSBzcGVjaWZpZWQgbm9kZSBpcyB2aXNpYmxlIGluIHRoZSBsb2dpY2FsIHZpZXcgb2YgYQorICAgICAqIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+IG9yIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4uIFRoaXMgZnVuY3Rpb24KKyAgICAgKiB3aWxsIGJlIGNhbGxlZCBieSB0aGUgaW1wbGVtZW50YXRpb24gb2YgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4gYW5kCisgICAgICogPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPjsgaXQgaXMgbm90IG5vcm1hbGx5IGNhbGxlZCBkaXJlY3RseSBmcm9tCisgICAgICogdXNlciBjb2RlLiAoVGhvdWdoIHlvdSBjb3VsZCBkbyBzbyBpZiB5b3Ugd2FudGVkIHRvIHVzZSB0aGUgc2FtZQorICAgICAqIGZpbHRlciB0byBndWlkZSB5b3VyIG93biBhcHBsaWNhdGlvbiBsb2dpYy4pCisgICAgICogQHBhcmFtIG4gVGhlIG5vZGUgdG8gY2hlY2sgdG8gc2VlIGlmIGl0IHBhc3NlcyB0aGUgZmlsdGVyIG9yIG5vdC4KKyAgICAgKiBAcmV0dXJuIEEgY29uc3RhbnQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIG5vZGUgaXMgYWNjZXB0ZWQsCisgICAgICogICByZWplY3RlZCwgb3Igc2tpcHBlZCwgYXMgZGVmaW5lZCBhYm92ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2hvcnQgYWNjZXB0Tm9kZShOb2RlIG4pOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3czYy9kb20vdHJhdmVyc2FsL05vZGVJdGVyYXRvci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL3RyYXZlcnNhbC9Ob2RlSXRlcmF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMWZkNWQwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy93M2MvZG9tL3RyYXZlcnNhbC9Ob2RlSXRlcmF0b3IuamF2YQpAQCAtMCwwICsxLDExMSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAqIFBVUlBPU0UuCisgKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCitwYWNrYWdlIG9yZy53M2MuZG9tLnRyYXZlcnNhbDsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworCisvKioKKyAqIDxjb2RlPk5vZGVJdGVyYXRvcnM8L2NvZGU+IGFyZSB1c2VkIHRvIHN0ZXAgdGhyb3VnaCBhIHNldCBvZiBub2RlcywgZS5nLgorICogdGhlIHNldCBvZiBub2RlcyBpbiBhIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiwgdGhlIGRvY3VtZW50IHN1YnRyZWUKKyAqIGdvdmVybmVkIGJ5IGEgcGFydGljdWxhciA8Y29kZT5Ob2RlPC9jb2RlPiwgdGhlIHJlc3VsdHMgb2YgYSBxdWVyeSwgb3IKKyAqIGFueSBvdGhlciBzZXQgb2Ygbm9kZXMuIFRoZSBzZXQgb2Ygbm9kZXMgdG8gYmUgaXRlcmF0ZWQgaXMgZGV0ZXJtaW5lZCBieQorICogdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZSA8Y29kZT5Ob2RlSXRlcmF0b3I8L2NvZGU+LiBET00gTGV2ZWwgMgorICogc3BlY2lmaWVzIGEgc2luZ2xlIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4gaW1wbGVtZW50YXRpb24gZm9yCisgKiBkb2N1bWVudC1vcmRlciB0cmF2ZXJzYWwgb2YgYSBkb2N1bWVudCBzdWJ0cmVlLiBJbnN0YW5jZXMgb2YgdGhlc2UKKyAqIDxjb2RlPk5vZGVJdGVyYXRvcnM8L2NvZGU+IGFyZSBjcmVhdGVkIGJ5IGNhbGxpbmcKKyAqIDxjb2RlPkRvY3VtZW50VHJhdmVyc2FsPC9jb2RlPjxjb2RlPi5jcmVhdGVOb2RlSXRlcmF0b3IoKTwvY29kZT4uCisgKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItVHJhdmVyc2FsLVJhbmdlLTIwMDAxMTEzJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBUcmF2ZXJzYWwgYW5kIFJhbmdlIFNwZWNpZmljYXRpb248L2E+LgorICogQHNpbmNlIERPTSBMZXZlbCAyCisgKgorICogQGhpZGUKKyAqLworcHVibGljIGludGVyZmFjZSBOb2RlSXRlcmF0b3IgeworICAgIC8qKgorICAgICAqIFRoZSByb290IG5vZGUgb2YgdGhlIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4sIGFzIHNwZWNpZmllZCB3aGVuIGl0CisgICAgICogd2FzIGNyZWF0ZWQuCisgICAgICovCisgICAgcHVibGljIE5vZGUgZ2V0Um9vdCgpOworCisgICAgLyoqCisgICAgICogVGhpcyBhdHRyaWJ1dGUgZGV0ZXJtaW5lcyB3aGljaCBub2RlIHR5cGVzIGFyZSBwcmVzZW50ZWQgdmlhIHRoZQorICAgICAqIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4uIFRoZSBhdmFpbGFibGUgc2V0IG9mIGNvbnN0YW50cyBpcyBkZWZpbmVkCisgICAgICogaW4gdGhlIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IGludGVyZmFjZS4gIE5vZGVzIG5vdCBhY2NlcHRlZCBieQorICAgICAqIDxjb2RlPndoYXRUb1Nob3c8L2NvZGU+IHdpbGwgYmUgc2tpcHBlZCwgYnV0IHRoZWlyIGNoaWxkcmVuIG1heSBzdGlsbAorICAgICAqIGJlIGNvbnNpZGVyZWQuIE5vdGUgdGhhdCB0aGlzIHNraXAgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIHRoZSBmaWx0ZXIsCisgICAgICogaWYgYW55LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0V2hhdFRvU2hvdygpOworCisgICAgLyoqCisgICAgICogVGhlIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IHVzZWQgdG8gc2NyZWVuIG5vZGVzLgorICAgICAqLworICAgIHB1YmxpYyBOb2RlRmlsdGVyIGdldEZpbHRlcigpOworCisgICAgLyoqCisgICAgICogIFRoZSB2YWx1ZSBvZiB0aGlzIGZsYWcgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBjaGlsZHJlbiBvZiBlbnRpdHkKKyAgICAgKiByZWZlcmVuY2Ugbm9kZXMgYXJlIHZpc2libGUgdG8gdGhlIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4uIElmCisgICAgICogZmFsc2UsIHRoZXNlIGNoaWxkcmVuICBhbmQgdGhlaXIgZGVzY2VuZGFudHMgd2lsbCBiZSByZWplY3RlZC4gTm90ZQorICAgICAqIHRoYXQgdGhpcyByZWplY3Rpb24gdGFrZXMgcHJlY2VkZW5jZSBvdmVyIDxjb2RlPndoYXRUb1Nob3c8L2NvZGU+IGFuZAorICAgICAqIHRoZSBmaWx0ZXIuIEFsc28gbm90ZSB0aGF0IHRoaXMgaXMgY3VycmVudGx5IHRoZSBvbmx5IHNpdHVhdGlvbiB3aGVyZQorICAgICAqIDxjb2RlPk5vZGVJdGVyYXRvcnM8L2NvZGU+IG1heSByZWplY3QgYSBjb21wbGV0ZSBzdWJ0cmVlIHJhdGhlciB0aGFuCisgICAgICogc2tpcHBpbmcgaW5kaXZpZHVhbCBub2Rlcy4KKyAgICAgKiA8YnI+CisgICAgICogPGJyPiBUbyBwcm9kdWNlIGEgdmlldyBvZiB0aGUgZG9jdW1lbnQgdGhhdCBoYXMgZW50aXR5IHJlZmVyZW5jZXMKKyAgICAgKiBleHBhbmRlZCBhbmQgZG9lcyBub3QgZXhwb3NlIHRoZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGUgaXRzZWxmLCB1c2UKKyAgICAgKiB0aGUgPGNvZGU+d2hhdFRvU2hvdzwvY29kZT4gZmxhZ3MgdG8gaGlkZSB0aGUgZW50aXR5IHJlZmVyZW5jZSBub2RlCisgICAgICogYW5kIHNldCA8Y29kZT5leHBhbmRFbnRpdHlSZWZlcmVuY2VzPC9jb2RlPiB0byB0cnVlIHdoZW4gY3JlYXRpbmcgdGhlCisgICAgICogPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPi4gVG8gcHJvZHVjZSBhIHZpZXcgb2YgdGhlIGRvY3VtZW50IHRoYXQgaGFzCisgICAgICogZW50aXR5IHJlZmVyZW5jZSBub2RlcyBidXQgbm8gZW50aXR5IGV4cGFuc2lvbiwgdXNlIHRoZQorICAgICAqIDxjb2RlPndoYXRUb1Nob3c8L2NvZGU+IGZsYWdzIHRvIHNob3cgdGhlIGVudGl0eSByZWZlcmVuY2Ugbm9kZSBhbmQKKyAgICAgKiBzZXQgPGNvZGU+ZXhwYW5kRW50aXR5UmVmZXJlbmNlczwvY29kZT4gdG8gZmFsc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0RXhwYW5kRW50aXR5UmVmZXJlbmNlcygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmV4dCBub2RlIGluIHRoZSBzZXQgYW5kIGFkdmFuY2VzIHRoZSBwb3NpdGlvbiBvZiB0aGUKKyAgICAgKiA8Y29kZT5Ob2RlSXRlcmF0b3I8L2NvZGU+IGluIHRoZSBzZXQuIEFmdGVyIGEKKyAgICAgKiA8Y29kZT5Ob2RlSXRlcmF0b3I8L2NvZGU+IGlzIGNyZWF0ZWQsIHRoZSBmaXJzdCBjYWxsIHRvCisgICAgICogPGNvZGU+bmV4dE5vZGUoKTwvY29kZT4gcmV0dXJucyB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgc2V0LgorICAgICAqIEByZXR1cm4gVGhlIG5leHQgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLCBvcgorICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgYXJlIG5vIG1vcmUgbWVtYmVycyBpbiB0aGF0IHNldC4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgSU5WQUxJRF9TVEFURV9FUlI6IFJhaXNlZCBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgdGhlCisgICAgICogICA8Y29kZT5kZXRhY2g8L2NvZGU+IG1ldGhvZCB3YXMgaW52b2tlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9kZSBuZXh0Tm9kZSgpCisgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByZXZpb3VzIG5vZGUgaW4gdGhlIHNldCBhbmQgbW92ZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQorICAgICAqIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4gYmFja3dhcmRzIGluIHRoZSBzZXQuCisgICAgICogQHJldHVybiBUaGUgcHJldmlvdXMgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLAorICAgICAqICAgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgYXJlIG5vIG1vcmUgbWVtYmVycyBpbiB0aGF0IHNldC4KKyAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgorICAgICAqICAgSU5WQUxJRF9TVEFURV9FUlI6IFJhaXNlZCBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgdGhlCisgICAgICogICA8Y29kZT5kZXRhY2g8L2NvZGU+IG1ldGhvZCB3YXMgaW52b2tlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9kZSBwcmV2aW91c05vZGUoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGV0YWNoZXMgdGhlIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4gZnJvbSB0aGUgc2V0IHdoaWNoIGl0IGl0ZXJhdGVkCisgICAgICogb3ZlciwgcmVsZWFzaW5nIGFueSBjb21wdXRhdGlvbmFsIHJlc291cmNlcyBhbmQgcGxhY2luZyB0aGUKKyAgICAgKiA8Y29kZT5Ob2RlSXRlcmF0b3I8L2NvZGU+IGluIHRoZSBJTlZBTElEIHN0YXRlLiBBZnRlcgorICAgICAqIDxjb2RlPmRldGFjaDwvY29kZT4gaGFzIGJlZW4gaW52b2tlZCwgY2FsbHMgdG8gPGNvZGU+bmV4dE5vZGU8L2NvZGU+CisgICAgICogb3IgPGNvZGU+cHJldmlvdXNOb2RlPC9jb2RlPiB3aWxsIHJhaXNlIHRoZSBleGNlcHRpb24KKyAgICAgKiBJTlZBTElEX1NUQVRFX0VSUi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkZXRhY2goKTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L0F0dHJpYnV0ZUxpc3QuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9BdHRyaWJ1dGVMaXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2ZjN2EyZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9BdHRyaWJ1dGVMaXN0LmphdmEKQEAgLTAsMCArMSwxOTQgQEAKKy8vIFNBWCBBdHRyaWJ1dGUgTGlzdCBJbnRlcmZhY2UuCisvLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCisvLyBObyB3YXJyYW50eTsgbm8gY29weXJpZ2h0IC0tIHVzZSB0aGlzIGFzIHlvdSB3aWxsLgorLy8gJElkOiBBdHRyaWJ1dGVMaXN0LmphdmEsdiAxLjcgMjAwNC8wNC8yNiAxNzozNDozNCBkbWVnZ2luc29uIEV4cCAkCisKK3BhY2thZ2Ugb3JnLnhtbC5zYXg7CisKKy8qKgorICogSW50ZXJmYWNlIGZvciBhbiBlbGVtZW50J3MgYXR0cmlidXRlIHNwZWNpZmljYXRpb25zLgorICoKKyAqIDxibG9ja3F1b3RlPgorICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKKyAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KKyAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgorICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+VGhpcyBpcyB0aGUgb3JpZ2luYWwgU0FYMSBpbnRlcmZhY2UgZm9yIHJlcG9ydGluZyBhbiBlbGVtZW50J3MKKyAqIGF0dHJpYnV0ZXMuICBVbmxpa2UgdGhlIG5ldyB7QGxpbmsgb3JnLnhtbC5zYXguQXR0cmlidXRlcyBBdHRyaWJ1dGVzfQorICogaW50ZXJmYWNlLCBpdCBkb2VzIG5vdCBzdXBwb3J0IE5hbWVzcGFjZS1yZWxhdGVkIGluZm9ybWF0aW9uLjwvcD4KKyAqCisgKiA8cD5XaGVuIGFuIGF0dHJpYnV0ZSBsaXN0IGlzIHN1cHBsaWVkIGFzIHBhcnQgb2YgYQorICoge0BsaW5rIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciNzdGFydEVsZW1lbnQgc3RhcnRFbGVtZW50fQorICogZXZlbnQsIHRoZSBsaXN0IHdpbGwgcmV0dXJuIHZhbGlkIHJlc3VsdHMgb25seSBkdXJpbmcgdGhlCisgKiBzY29wZSBvZiB0aGUgZXZlbnQ7IG9uY2UgdGhlIGV2ZW50IGhhbmRsZXIgcmV0dXJucyBjb250cm9sCisgKiB0byB0aGUgcGFyc2VyLCB0aGUgYXR0cmlidXRlIGxpc3QgaXMgaW52YWxpZC4gIFRvIHNhdmUgYQorICogcGVyc2lzdGVudCBjb3B5IG9mIHRoZSBhdHRyaWJ1dGUgbGlzdCwgdXNlIHRoZSBTQVgxCisgKiB7QGxpbmsgb3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVMaXN0SW1wbCBBdHRyaWJ1dGVMaXN0SW1wbH0KKyAqIGhlbHBlciBjbGFzcy48L3A+CisgKgorICogPHA+QW4gYXR0cmlidXRlIGxpc3QgaW5jbHVkZXMgb25seSBhdHRyaWJ1dGVzIHRoYXQgaGF2ZSBiZWVuCisgKiBzcGVjaWZpZWQgb3IgZGVmYXVsdGVkOiAjSU1QTElFRCBhdHRyaWJ1dGVzIHdpbGwgbm90IGJlIGluY2x1ZGVkLjwvcD4KKyAqCisgKiA8cD5UaGVyZSBhcmUgdHdvIHdheXMgZm9yIHRoZSBTQVggYXBwbGljYXRpb24gdG8gb2J0YWluIGluZm9ybWF0aW9uCisgKiBmcm9tIHRoZSBBdHRyaWJ1dGVMaXN0LiAgRmlyc3QsIGl0IGNhbiBpdGVyYXRlIHRocm91Z2ggdGhlIGVudGlyZQorICogbGlzdDo8L3A+CisgKgorICogPHByZT4KKyAqIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCAoU3RyaW5nIG5hbWUsIEF0dHJpYnV0ZUxpc3QgYXR0cykgeworICogICBmb3IgKGludCBpID0gMDsgaSA8IGF0dHMuZ2V0TGVuZ3RoKCk7IGkrKykgeworICogICAgIFN0cmluZyBuYW1lID0gYXR0cy5nZXROYW1lKGkpOworICogICAgIFN0cmluZyB0eXBlID0gYXR0cy5nZXRUeXBlKGkpOworICogICAgIFN0cmluZyB2YWx1ZSA9IGF0dHMuZ2V0VmFsdWUoaSk7CisgKiAgICAgWy4uLl0KKyAqICAgfQorICogfQorICogPC9wcmU+CisgKgorICogPHA+KE5vdGUgdGhhdCB0aGUgcmVzdWx0IG9mIGdldExlbmd0aCgpIHdpbGwgYmUgemVybyBpZiB0aGVyZQorICogYXJlIG5vIGF0dHJpYnV0ZXMuKQorICoKKyAqIDxwPkFzIGFuIGFsdGVybmF0aXZlLCB0aGUgYXBwbGljYXRpb24gY2FuIHJlcXVlc3QgdGhlIHZhbHVlIG9yCisgKiB0eXBlIG9mIHNwZWNpZmljIGF0dHJpYnV0ZXM6PC9wPgorICoKKyAqIDxwcmU+CisgKiBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQgKFN0cmluZyBuYW1lLCBBdHRyaWJ1dGVMaXN0IGF0dHMpIHsKKyAqICAgU3RyaW5nIGlkZW50aWZpZXIgPSBhdHRzLmdldFZhbHVlKCJpZCIpOworICogICBTdHJpbmcgbGFiZWwgPSBhdHRzLmdldFZhbHVlKCJsYWJlbCIpOworICogICBbLi4uXQorICogfQorICogPC9wcmU+CisgKgorICogQGRlcHJlY2F0ZWQgVGhpcyBpbnRlcmZhY2UgaGFzIGJlZW4gcmVwbGFjZWQgYnkgdGhlIFNBWDIKKyAqICAgICAgICAgICAgIHtAbGluayBvcmcueG1sLnNheC5BdHRyaWJ1dGVzIEF0dHJpYnV0ZXN9CisgKiAgICAgICAgICAgICBpbnRlcmZhY2UsIHdoaWNoIGluY2x1ZGVzIE5hbWVzcGFjZSBzdXBwb3J0LgorICogQHNpbmNlIFNBWCAxLjAKKyAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCisgKiBAdmVyc2lvbiAyLjAuMSAoc2F4MnIyKQorICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjc3RhcnRFbGVtZW50IHN0YXJ0RWxlbWVudAorICogQHNlZSBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZUxpc3RJbXBsIEF0dHJpYnV0ZUxpc3RJbXBsCisgKi8KK0BEZXByZWNhdGVkCitwdWJsaWMgaW50ZXJmYWNlIEF0dHJpYnV0ZUxpc3QgeworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBJdGVyYXRpb24gbWV0aG9kcy4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIGluIHRoaXMgbGlzdC4KKyAgICAgKgorICAgICAqIDxwPlRoZSBTQVggcGFyc2VyIG1heSBwcm92aWRlIGF0dHJpYnV0ZXMgaW4gYW55CisgICAgICogYXJiaXRyYXJ5IG9yZGVyLCByZWdhcmRsZXNzIG9mIHRoZSBvcmRlciBpbiB3aGljaCB0aGV5IHdlcmUKKyAgICAgKiBkZWNsYXJlZCBvciBzcGVjaWZpZWQuICBUaGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMgbWF5IGJlCisgICAgICogemVyby48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgYXR0cmlidXRlcyBpbiB0aGUgbGlzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldExlbmd0aCAoKTsKKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBuYW1lIG9mIGFuIGF0dHJpYnV0ZSBpbiB0aGlzIGxpc3QgKGJ5IHBvc2l0aW9uKS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBuYW1lcyBtdXN0IGJlIHVuaXF1ZTogdGhlIFNBWCBwYXJzZXIgc2hhbGwgbm90IGluY2x1ZGUgdGhlCisgICAgICogc2FtZSBhdHRyaWJ1dGUgdHdpY2UuICBBdHRyaWJ1dGVzIHdpdGhvdXQgdmFsdWVzICh0aG9zZSBkZWNsYXJlZAorICAgICAqICNJTVBMSUVEIHdpdGhvdXQgYSB2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIHN0YXJ0IHRhZykgd2lsbCBiZQorICAgICAqIG9taXR0ZWQgZnJvbSB0aGUgbGlzdC48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgYXR0cmlidXRlIG5hbWUgaGFzIGEgbmFtZXNwYWNlIHByZWZpeCwgdGhlIHByZWZpeAorICAgICAqIHdpbGwgc3RpbGwgYmUgYXR0YWNoZWQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGkgVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUgaW4gdGhlIGxpc3QgKHN0YXJ0aW5nIGF0IDApLgorICAgICAqIEByZXR1cm4gVGhlIG5hbWUgb2YgdGhlIGluZGV4ZWQgYXR0cmlidXRlLCBvciBudWxsCisgICAgICogICAgICAgICBpZiB0aGUgaW5kZXggaXMgb3V0IG9mIHJhbmdlLgorICAgICAqIEBzZWUgI2dldExlbmd0aAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0TmFtZSAoaW50IGkpOworCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHR5cGUgb2YgYW4gYXR0cmlidXRlIGluIHRoZSBsaXN0IChieSBwb3NpdGlvbikuCisgICAgICoKKyAgICAgKiA8cD5UaGUgYXR0cmlidXRlIHR5cGUgaXMgb25lIG9mIHRoZSBzdHJpbmdzICJDREFUQSIsICJJRCIsCisgICAgICogIklEUkVGIiwgIklEUkVGUyIsICJOTVRPS0VOIiwgIk5NVE9LRU5TIiwgIkVOVElUWSIsICJFTlRJVElFUyIsCisgICAgICogb3IgIk5PVEFUSU9OIiAoYWx3YXlzIGluIHVwcGVyIGNhc2UpLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBwYXJzZXIgaGFzIG5vdCByZWFkIGEgZGVjbGFyYXRpb24gZm9yIHRoZSBhdHRyaWJ1dGUsCisgICAgICogb3IgaWYgdGhlIHBhcnNlciBkb2VzIG5vdCByZXBvcnQgYXR0cmlidXRlIHR5cGVzLCB0aGVuIGl0IG11c3QKKyAgICAgKiByZXR1cm4gdGhlIHZhbHVlICJDREFUQSIgYXMgc3RhdGVkIGluIHRoZSBYTUwgMS4wIFJlY29tbWVudGF0aW9uCisgICAgICogKGNsYXVzZSAzLjMuMywgIkF0dHJpYnV0ZS1WYWx1ZSBOb3JtYWxpemF0aW9uIikuPC9wPgorICAgICAqCisgICAgICogPHA+Rm9yIGFuIGVudW1lcmF0ZWQgYXR0cmlidXRlIHRoYXQgaXMgbm90IGEgbm90YXRpb24sIHRoZQorICAgICAqIHBhcnNlciB3aWxsIHJlcG9ydCB0aGUgdHlwZSBhcyAiTk1UT0tFTiIuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGkgVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUgaW4gdGhlIGxpc3QgKHN0YXJ0aW5nIGF0IDApLgorICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSB0eXBlIGFzIGEgc3RyaW5nLCBvcgorICAgICAqICAgICAgICAgbnVsbCBpZiB0aGUgaW5kZXggaXMgb3V0IG9mIHJhbmdlLgorICAgICAqIEBzZWUgI2dldExlbmd0aAorICAgICAqIEBzZWUgI2dldFR5cGUoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFR5cGUgKGludCBpKTsKKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUgaW4gdGhlIGxpc3QgKGJ5IHBvc2l0aW9uKS4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBhdHRyaWJ1dGUgdmFsdWUgaXMgYSBsaXN0IG9mIHRva2VucyAoSURSRUZTLAorICAgICAqIEVOVElUSUVTLCBvciBOTVRPS0VOUyksIHRoZSB0b2tlbnMgd2lsbCBiZSBjb25jYXRlbmF0ZWQKKyAgICAgKiBpbnRvIGEgc2luZ2xlIHN0cmluZyBzZXBhcmF0ZWQgYnkgd2hpdGVzcGFjZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaSBUaGUgaW5kZXggb2YgdGhlIGF0dHJpYnV0ZSBpbiB0aGUgbGlzdCAoc3RhcnRpbmcgYXQgMCkuCisgICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIHZhbHVlIGFzIGEgc3RyaW5nLCBvcgorICAgICAqICAgICAgICAgbnVsbCBpZiB0aGUgaW5kZXggaXMgb3V0IG9mIHJhbmdlLgorICAgICAqIEBzZWUgI2dldExlbmd0aAorICAgICAqIEBzZWUgI2dldFZhbHVlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRWYWx1ZSAoaW50IGkpOworCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIExvb2t1cCBtZXRob2RzLgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdHlwZSBvZiBhbiBhdHRyaWJ1dGUgaW4gdGhlIGxpc3QgKGJ5IG5hbWUpLgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgc2FtZSBhcyB0aGUgcmV0dXJuIHZhbHVlIGZvcgorICAgICAqIGdldFR5cGUoaW50KS48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgYXR0cmlidXRlIG5hbWUgaGFzIGEgbmFtZXNwYWNlIHByZWZpeCBpbiB0aGUgZG9jdW1lbnQsCisgICAgICogdGhlIGFwcGxpY2F0aW9uIG11c3QgaW5jbHVkZSB0aGUgcHJlZml4IGhlcmUuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KKyAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgdHlwZSBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiBubworICAgICAqICAgICAgICAgc3VjaCBhdHRyaWJ1dGUgZXhpc3RzLgorICAgICAqIEBzZWUgI2dldFR5cGUoaW50KQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0VHlwZSAoU3RyaW5nIG5hbWUpOworCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSBpbiB0aGUgbGlzdCAoYnkgbmFtZSkuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuIHZhbHVlIGlzIHRoZSBzYW1lIGFzIHRoZSByZXR1cm4gdmFsdWUgZm9yCisgICAgICogZ2V0VmFsdWUoaW50KS48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgYXR0cmlidXRlIG5hbWUgaGFzIGEgbmFtZXNwYWNlIHByZWZpeCBpbiB0aGUgZG9jdW1lbnQsCisgICAgICogdGhlIGFwcGxpY2F0aW9uIG11c3QgaW5jbHVkZSB0aGUgcHJlZml4IGhlcmUuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byByZXR1cm4KKyAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgdmFsdWUgYXMgYSBzdHJpbmcsIG9yIG51bGwgaWYKKyAgICAgKiAgICAgICAgIG5vIHN1Y2ggYXR0cmlidXRlIGV4aXN0cy4KKyAgICAgKiBAc2VlICNnZXRWYWx1ZShpbnQpCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRWYWx1ZSAoU3RyaW5nIG5hbWUpOworCit9CisKKy8vIGVuZCBvZiBBdHRyaWJ1dGVMaXN0LmphdmEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9BdHRyaWJ1dGVzLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvQXR0cmlidXRlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk5OTdkNmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvQXR0cmlidXRlcy5qYXZhCkBAIC0wLDAgKzEsMjU3IEBACisvLyBBdHRyaWJ1dGVzLmphdmEgLSBhdHRyaWJ1dGUgbGlzdCB3aXRoIE5hbWVzcGFjZSBzdXBwb3J0CisvLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCisvLyBXcml0dGVuIGJ5IERhdmlkIE1lZ2dpbnNvbgorLy8gTk8gV0FSUkFOVFkhICBUaGlzIGNsYXNzIGlzIGluIHRoZSBwdWJsaWMgZG9tYWluLgorLy8gJElkOiBBdHRyaWJ1dGVzLmphdmEsdiAxLjEzIDIwMDQvMDMvMTggMTI6Mjg6MDUgZG1lZ2dpbnNvbiBFeHAgJAorCitwYWNrYWdlIG9yZy54bWwuc2F4OworCisKKy8qKgorICogSW50ZXJmYWNlIGZvciBhIGxpc3Qgb2YgWE1MIGF0dHJpYnV0ZXMuCisgKgorICogPGJsb2NrcXVvdGU+CisgKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQorICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgorICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+CisgKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KKyAqIDwvYmxvY2txdW90ZT4KKyAqCisgKiA8cD5UaGlzIGludGVyZmFjZSBhbGxvd3MgYWNjZXNzIHRvIGEgbGlzdCBvZiBhdHRyaWJ1dGVzIGluCisgKiB0aHJlZSBkaWZmZXJlbnQgd2F5czo8L3A+CisgKgorICogPG9sPgorICogPGxpPmJ5IGF0dHJpYnV0ZSBpbmRleDs8L2xpPgorICogPGxpPmJ5IE5hbWVzcGFjZS1xdWFsaWZpZWQgbmFtZTsgb3I8L2xpPgorICogPGxpPmJ5IHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuPC9saT4KKyAqIDwvb2w+CisgKgorICogPHA+VGhlIGxpc3Qgd2lsbCBub3QgY29udGFpbiBhdHRyaWJ1dGVzIHRoYXQgd2VyZSBkZWNsYXJlZAorICogI0lNUExJRUQgYnV0IG5vdCBzcGVjaWZpZWQgaW4gdGhlIHN0YXJ0IHRhZy4gIEl0IHdpbGwgYWxzbyBub3QKKyAqIGNvbnRhaW4gYXR0cmlidXRlcyB1c2VkIGFzIE5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgKHhtbG5zKikgdW5sZXNzCisgKiB0aGUgPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZS1wcmVmaXhlczwvY29kZT4KKyAqIGZlYXR1cmUgaXMgc2V0IHRvIDx2YXI+dHJ1ZTwvdmFyPiAoaXQgaXMgPHZhcj5mYWxzZTwvdmFyPiBieQorICogZGVmYXVsdCkuCisgKiBCZWNhdXNlIFNBWDIgY29uZm9ybXMgdG8gdGhlIG9yaWdpbmFsICJOYW1lc3BhY2VzIGluIFhNTCIKKyAqIHJlY29tbWVuZGF0aW9uLCBpdCBub3JtYWxseSBkb2VzIG5vdAorICogZ2l2ZSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gYXR0cmlidXRlcyBhIG5hbWVzcGFjZSBVUkkuCisgKiA8L3A+CisgKgorICogPHA+U29tZSBTQVgyIHBhcnNlcnMgbWF5IHN1cHBvcnQgdXNpbmcgYW4gb3B0aW9uYWwgZmVhdHVyZSBmbGFnCisgKiAoPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3htbG5zLXVyaXM8L2NvZGU+KSB0byByZXF1ZXN0CisgKiB0aGF0IHRob3NlIGF0dHJpYnV0ZXMgYmUgZ2l2ZW4gVVJJcywgY29uZm9ybWluZyB0byBhIGxhdGVyCisgKiBiYWNrd2FyZHMtaW5jb21wYXRpYmxlIHJldmlzaW9uIG9mIHRoYXQgcmVjb21tZW5kYXRpb24uICAoVGhlCisgKiBhdHRyaWJ1dGUncyAibG9jYWwgbmFtZSIgd2lsbCBiZSB0aGUgcHJlZml4LCBvciAieG1sbnMiIHdoZW4KKyAqIGRlZmluaW5nIGEgZGVmYXVsdCBlbGVtZW50IG5hbWVzcGFjZS4pICBGb3IgcG9ydGFiaWxpdHksIGhhbmRsZXIKKyAqIGNvZGUgc2hvdWxkIGFsd2F5cyByZXNvbHZlIHRoYXQgY29uZmxpY3QsIHJhdGhlciB0aGFuIHJlcXVpcmluZworICogcGFyc2VycyB0aGF0IGNhbiBjaGFuZ2UgdGhlIHNldHRpbmcgb2YgdGhhdCBmZWF0dXJlIGZsYWcuICA8L3A+CisgKgorICogPHA+SWYgdGhlIG5hbWVzcGFjZS1wcmVmaXhlcyBmZWF0dXJlIChzZWUgYWJvdmUpIGlzCisgKiA8dmFyPmZhbHNlPC92YXI+LCBhY2Nlc3MgYnkgcXVhbGlmaWVkIG5hbWUgbWF5IG5vdCBiZSBhdmFpbGFibGU7IGlmCisgKiB0aGUgPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXM8L2NvZGU+IGZlYXR1cmUgaXMKKyAqIDx2YXI+ZmFsc2U8L3Zhcj4sIGFjY2VzcyBieSBOYW1lc3BhY2UtcXVhbGlmaWVkIG5hbWVzIG1heSBub3QgYmUKKyAqIGF2YWlsYWJsZS48L3A+CisgKgorICogPHA+VGhpcyBpbnRlcmZhY2UgcmVwbGFjZXMgdGhlIG5vdy1kZXByZWNhdGVkIFNBWDEge0BsaW5rCisgKiBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0IEF0dHJpYnV0ZUxpc3R9IGludGVyZmFjZSwgd2hpY2ggZG9lcyBub3QKKyAqIGNvbnRhaW4gTmFtZXNwYWNlIHN1cHBvcnQuICBJbiBhZGRpdGlvbiB0byBOYW1lc3BhY2Ugc3VwcG9ydCwgaXQKKyAqIGFkZHMgdGhlIDx2YXI+Z2V0SW5kZXg8L3Zhcj4gbWV0aG9kcyAoYmVsb3cpLjwvcD4KKyAqCisgKiA8cD5UaGUgb3JkZXIgb2YgYXR0cmlidXRlcyBpbiB0aGUgbGlzdCBpcyB1bnNwZWNpZmllZCwgYW5kIHdpbGwKKyAqIHZhcnkgZnJvbSBpbXBsZW1lbnRhdGlvbiB0byBpbXBsZW1lbnRhdGlvbi48L3A+CisgKgorICogQHNpbmNlIFNBWCAyLjAKKyAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCisgKiBAdmVyc2lvbiAyLjAuMSAoc2F4MnIyKQorICogQHNlZSBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZXNJbXBsCisgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciNhdHRyaWJ1dGVEZWNsCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQXR0cmlidXRlcworeworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBJbmRleGVkIGFjY2Vzcy4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIGluIHRoZSBsaXN0LgorICAgICAqCisgICAgICogPHA+T25jZSB5b3Uga25vdyB0aGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMsIHlvdSBjYW4gaXRlcmF0ZQorICAgICAqIHRocm91Z2ggdGhlIGxpc3QuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMgaW4gdGhlIGxpc3QuCisgICAgICogQHNlZSAjZ2V0VVJJKGludCkKKyAgICAgKiBAc2VlICNnZXRMb2NhbE5hbWUoaW50KQorICAgICAqIEBzZWUgI2dldFFOYW1lKGludCkKKyAgICAgKiBAc2VlICNnZXRUeXBlKGludCkKKyAgICAgKiBAc2VlICNnZXRWYWx1ZShpbnQpCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRMZW5ndGggKCk7CisKKworICAgIC8qKgorICAgICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgTmFtZXNwYWNlIFVSSSBieSBpbmRleC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlIGluZGV4ICh6ZXJvLWJhc2VkKS4KKyAgICAgKiBAcmV0dXJuIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIG5vbmUKKyAgICAgKiAgICAgICAgIGlzIGF2YWlsYWJsZSwgb3IgbnVsbCBpZiB0aGUgaW5kZXggaXMgb3V0IG9mCisgICAgICogICAgICAgICByYW5nZS4KKyAgICAgKiBAc2VlICNnZXRMZW5ndGgKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFVSSSAoaW50IGluZGV4KTsKKworCisgICAgLyoqCisgICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyBsb2NhbCBuYW1lIGJ5IGluZGV4LgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXggKHplcm8tYmFzZWQpLgorICAgICAqIEByZXR1cm4gVGhlIGxvY2FsIG5hbWUsIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlCisgICAgICogICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQsIG9yIG51bGwKKyAgICAgKiAgICAgICAgIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuCisgICAgICogQHNlZSAjZ2V0TGVuZ3RoCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRMb2NhbE5hbWUgKGludCBpbmRleCk7CisKKworICAgIC8qKgorICAgICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgWE1MIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUgYnkgaW5kZXguCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleCAoemVyby1iYXNlZCkuCisgICAgICogQHJldHVybiBUaGUgWE1MIHF1YWxpZmllZCBuYW1lLCBvciB0aGUgZW1wdHkgc3RyaW5nCisgICAgICogICAgICAgICBpZiBub25lIGlzIGF2YWlsYWJsZSwgb3IgbnVsbCBpZiB0aGUgaW5kZXgKKyAgICAgKiAgICAgICAgIGlzIG91dCBvZiByYW5nZS4KKyAgICAgKiBAc2VlICNnZXRMZW5ndGgKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFFOYW1lIChpbnQgaW5kZXgpOworCisKKyAgICAvKioKKyAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHR5cGUgYnkgaW5kZXguCisgICAgICoKKyAgICAgKiA8cD5UaGUgYXR0cmlidXRlIHR5cGUgaXMgb25lIG9mIHRoZSBzdHJpbmdzICJDREFUQSIsICJJRCIsCisgICAgICogIklEUkVGIiwgIklEUkVGUyIsICJOTVRPS0VOIiwgIk5NVE9LRU5TIiwgIkVOVElUWSIsICJFTlRJVElFUyIsCisgICAgICogb3IgIk5PVEFUSU9OIiAoYWx3YXlzIGluIHVwcGVyIGNhc2UpLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBwYXJzZXIgaGFzIG5vdCByZWFkIGEgZGVjbGFyYXRpb24gZm9yIHRoZSBhdHRyaWJ1dGUsCisgICAgICogb3IgaWYgdGhlIHBhcnNlciBkb2VzIG5vdCByZXBvcnQgYXR0cmlidXRlIHR5cGVzLCB0aGVuIGl0IG11c3QKKyAgICAgKiByZXR1cm4gdGhlIHZhbHVlICJDREFUQSIgYXMgc3RhdGVkIGluIHRoZSBYTUwgMS4wIFJlY29tbWVuZGF0aW9uCisgICAgICogKGNsYXVzZSAzLjMuMywgIkF0dHJpYnV0ZS1WYWx1ZSBOb3JtYWxpemF0aW9uIikuPC9wPgorICAgICAqCisgICAgICogPHA+Rm9yIGFuIGVudW1lcmF0ZWQgYXR0cmlidXRlIHRoYXQgaXMgbm90IGEgbm90YXRpb24sIHRoZQorICAgICAqIHBhcnNlciB3aWxsIHJlcG9ydCB0aGUgdHlwZSBhcyAiTk1UT0tFTiIuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXggKHplcm8tYmFzZWQpLgorICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIHR5cGUgYXMgYSBzdHJpbmcsIG9yIG51bGwgaWYgdGhlCisgICAgICogICAgICAgICBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuCisgICAgICogQHNlZSAjZ2V0TGVuZ3RoCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRUeXBlIChpbnQgaW5kZXgpOworCisKKyAgICAvKioKKyAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHZhbHVlIGJ5IGluZGV4LgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBpcyBhIGxpc3Qgb2YgdG9rZW5zIChJRFJFRlMsCisgICAgICogRU5USVRJRVMsIG9yIE5NVE9LRU5TKSwgdGhlIHRva2VucyB3aWxsIGJlIGNvbmNhdGVuYXRlZAorICAgICAqIGludG8gYSBzaW5nbGUgc3RyaW5nIHdpdGggZWFjaCB0b2tlbiBzZXBhcmF0ZWQgYnkgYQorICAgICAqIHNpbmdsZSBzcGFjZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleCAoemVyby1iYXNlZCkuCisgICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlJ3MgdmFsdWUgYXMgYSBzdHJpbmcsIG9yIG51bGwgaWYgdGhlCisgICAgICogICAgICAgICBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuCisgICAgICogQHNlZSAjZ2V0TGVuZ3RoCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRWYWx1ZSAoaW50IGluZGV4KTsKKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBOYW1lLWJhc2VkIHF1ZXJ5LgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworICAgIC8qKgorICAgICAqIExvb2sgdXAgdGhlIGluZGV4IG9mIGFuIGF0dHJpYnV0ZSBieSBOYW1lc3BhY2UgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYKKyAgICAgKiAgICAgICAgdGhlIG5hbWUgaGFzIG5vIE5hbWVzcGFjZSBVUkkuCisgICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgYXR0cmlidXRlJ3MgbG9jYWwgbmFtZS4KKyAgICAgKiBAcmV0dXJuIFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlLCBvciAtMSBpZiBpdCBkb2VzIG5vdAorICAgICAqICAgICAgICAgYXBwZWFyIGluIHRoZSBsaXN0LgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXggKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpOworCisKKyAgICAvKioKKyAgICAgKiBMb29rIHVwIHRoZSBpbmRleCBvZiBhbiBhdHRyaWJ1dGUgYnkgWE1MIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCisgICAgICogQHJldHVybiBUaGUgaW5kZXggb2YgdGhlIGF0dHJpYnV0ZSwgb3IgLTEgaWYgaXQgZG9lcyBub3QKKyAgICAgKiAgICAgICAgIGFwcGVhciBpbiB0aGUgbGlzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEluZGV4IChTdHJpbmcgcU5hbWUpOworCisKKyAgICAvKioKKyAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHR5cGUgYnkgTmFtZXNwYWNlIG5hbWUuCisgICAgICoKKyAgICAgKiA8cD5TZWUge0BsaW5rICNnZXRUeXBlKGludCkgZ2V0VHlwZShpbnQpfSBmb3IgYSBkZXNjcmlwdGlvbgorICAgICAqIG9mIHRoZSBwb3NzaWJsZSB0eXBlcy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgU3RyaW5nIGlmIHRoZQorICAgICAqICAgICAgICBuYW1lIGhhcyBubyBOYW1lc3BhY2UgVVJJLgorICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KKyAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgdHlwZSBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiB0aGUKKyAgICAgKiAgICAgICAgIGF0dHJpYnV0ZSBpcyBub3QgaW4gdGhlIGxpc3Qgb3IgaWYgTmFtZXNwYWNlCisgICAgICogICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRUeXBlIChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKTsKKworCisgICAgLyoqCisgICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB0eXBlIGJ5IFhNTCBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLgorICAgICAqCisgICAgICogPHA+U2VlIHtAbGluayAjZ2V0VHlwZShpbnQpIGdldFR5cGUoaW50KX0gZm9yIGEgZGVzY3JpcHRpb24KKyAgICAgKiBvZiB0aGUgcG9zc2libGUgdHlwZXMuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHFOYW1lIFRoZSBYTUwgcXVhbGlmaWVkIG5hbWUuCisgICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIHR5cGUgYXMgYSBzdHJpbmcsIG9yIG51bGwgaWYgdGhlCisgICAgICogICAgICAgICBhdHRyaWJ1dGUgaXMgbm90IGluIHRoZSBsaXN0IG9yIGlmIHF1YWxpZmllZCBuYW1lcworICAgICAqICAgICAgICAgYXJlIG5vdCBhdmFpbGFibGUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRUeXBlIChTdHJpbmcgcU5hbWUpOworCisKKyAgICAvKioKKyAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHZhbHVlIGJ5IE5hbWVzcGFjZSBuYW1lLgorICAgICAqCisgICAgICogPHA+U2VlIHtAbGluayAjZ2V0VmFsdWUoaW50KSBnZXRWYWx1ZShpbnQpfSBmb3IgYSBkZXNjcmlwdGlvbgorICAgICAqIG9mIHRoZSBwb3NzaWJsZSB2YWx1ZXMuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IFN0cmluZyBpZiB0aGUKKyAgICAgKiAgICAgICAgbmFtZSBoYXMgbm8gTmFtZXNwYWNlIFVSSS4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCisgICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIHZhbHVlIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIHRoZQorICAgICAqICAgICAgICAgYXR0cmlidXRlIGlzIG5vdCBpbiB0aGUgbGlzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFZhbHVlIChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKTsKKworCisgICAgLyoqCisgICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB2YWx1ZSBieSBYTUwgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KKyAgICAgKgorICAgICAqIDxwPlNlZSB7QGxpbmsgI2dldFZhbHVlKGludCkgZ2V0VmFsdWUoaW50KX0gZm9yIGEgZGVzY3JpcHRpb24KKyAgICAgKiBvZiB0aGUgcG9zc2libGUgdmFsdWVzLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgWE1MIHF1YWxpZmllZCBuYW1lLgorICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSB2YWx1ZSBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiB0aGUKKyAgICAgKiAgICAgICAgIGF0dHJpYnV0ZSBpcyBub3QgaW4gdGhlIGxpc3Qgb3IgaWYgcXVhbGlmaWVkIG5hbWVzCisgICAgICogICAgICAgICBhcmUgbm90IGF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFZhbHVlIChTdHJpbmcgcU5hbWUpOworCit9CisKKy8vIGVuZCBvZiBBdHRyaWJ1dGVzLmphdmEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9Db250ZW50SGFuZGxlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L0NvbnRlbnRIYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTEzZDE4NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9Db250ZW50SGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsNDE5IEBACisvLyBDb250ZW50SGFuZGxlci5qYXZhIC0gaGFuZGxlIG1haW4gZG9jdW1lbnQgY29udGVudC4KKy8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKKy8vIFdyaXR0ZW4gYnkgRGF2aWQgTWVnZ2luc29uCisvLyBOTyBXQVJSQU5UWSEgIFRoaXMgY2xhc3MgaXMgaW4gdGhlIHB1YmxpYyBkb21haW4uCisvLyAkSWQ6IENvbnRlbnRIYW5kbGVyLmphdmEsdiAxLjEzIDIwMDQvMDQvMjYgMTc6NTA6NDkgZG1lZ2dpbnNvbiBFeHAgJAorCitwYWNrYWdlIG9yZy54bWwuc2F4OworCisKKy8qKgorICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGxvZ2ljYWwgY29udGVudCBvZiBhIGRvY3VtZW50LgorICoKKyAqIDxibG9ja3F1b3RlPgorICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKKyAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KKyAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgorICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+VGhpcyBpcyB0aGUgbWFpbiBpbnRlcmZhY2UgdGhhdCBtb3N0IFNBWCBhcHBsaWNhdGlvbnMKKyAqIGltcGxlbWVudDogaWYgdGhlIGFwcGxpY2F0aW9uIG5lZWRzIHRvIGJlIGluZm9ybWVkIG9mIGJhc2ljIHBhcnNpbmcKKyAqIGV2ZW50cywgaXQgaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSBhbmQgcmVnaXN0ZXJzIGFuIGluc3RhbmNlIHdpdGgKKyAqIHRoZSBTQVggcGFyc2VyIHVzaW5nIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyI3NldENvbnRlbnRIYW5kbGVyCisgKiBzZXRDb250ZW50SGFuZGxlcn0gbWV0aG9kLiAgVGhlIHBhcnNlciB1c2VzIHRoZSBpbnN0YW5jZSB0byByZXBvcnQKKyAqIGJhc2ljIGRvY3VtZW50LXJlbGF0ZWQgZXZlbnRzIGxpa2UgdGhlIHN0YXJ0IGFuZCBlbmQgb2YgZWxlbWVudHMKKyAqIGFuZCBjaGFyYWN0ZXIgZGF0YS48L3A+CisgKgorICogPHA+VGhlIG9yZGVyIG9mIGV2ZW50cyBpbiB0aGlzIGludGVyZmFjZSBpcyB2ZXJ5IGltcG9ydGFudCwgYW5kCisgKiBtaXJyb3JzIHRoZSBvcmRlciBvZiBpbmZvcm1hdGlvbiBpbiB0aGUgZG9jdW1lbnQgaXRzZWxmLiAgRm9yCisgKiBleGFtcGxlLCBhbGwgb2YgYW4gZWxlbWVudCdzIGNvbnRlbnQgKGNoYXJhY3RlciBkYXRhLCBwcm9jZXNzaW5nCisgKiBpbnN0cnVjdGlvbnMsIGFuZC9vciBzdWJlbGVtZW50cykgd2lsbCBhcHBlYXIsIGluIG9yZGVyLCBiZXR3ZWVuCisgKiB0aGUgc3RhcnRFbGVtZW50IGV2ZW50IGFuZCB0aGUgY29ycmVzcG9uZGluZyBlbmRFbGVtZW50IGV2ZW50LjwvcD4KKyAqCisgKiA8cD5UaGlzIGludGVyZmFjZSBpcyBzaW1pbGFyIHRvIHRoZSBub3ctZGVwcmVjYXRlZCBTQVggMS4wCisgKiBEb2N1bWVudEhhbmRsZXIgaW50ZXJmYWNlLCBidXQgaXQgYWRkcyBzdXBwb3J0IGZvciBOYW1lc3BhY2VzCisgKiBhbmQgZm9yIHJlcG9ydGluZyBza2lwcGVkIGVudGl0aWVzIChpbiBub24tdmFsaWRhdGluZyBYTUwKKyAqIHByb2Nlc3NvcnMpLjwvcD4KKyAqCisgKiA8cD5JbXBsZW1lbnRvcnMgc2hvdWxkIG5vdGUgdGhhdCB0aGVyZSBpcyBhbHNvIGEKKyAqIDxjb2RlPkNvbnRlbnRIYW5kbGVyPC9jb2RlPiBjbGFzcyBpbiB0aGUgPGNvZGU+amF2YS5uZXQ8L2NvZGU+CisgKiBwYWNrYWdlOyB0aGF0IG1lYW5zIHRoYXQgaXQncyBwcm9iYWJseSBhIGJhZCBpZGVhIHRvIGRvPC9wPgorICoKKyAqIDxwcmU+aW1wb3J0IGphdmEubmV0Lio7CisgKiBpbXBvcnQgb3JnLnhtbC5zYXguKjsKKyAqIDwvcHJlPgorICoKKyAqIDxwPkluIGZhY3QsICJpbXBvcnQgLi4uKiIgaXMgdXN1YWxseSBhIHNpZ24gb2Ygc2xvcHB5IHByb2dyYW1taW5nCisgKiBhbnl3YXksIHNvIHRoZSB1c2VyIHNob3VsZCBjb25zaWRlciB0aGlzIGEgZmVhdHVyZSByYXRoZXIgdGhhbiBhCisgKiBidWcuPC9wPgorICoKKyAqIEBzaW5jZSBTQVggMi4wCisgKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgorICogQHZlcnNpb24gMi4wLjErIChzYXgycjNwcmUxKQorICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIKKyAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlcgorICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIKKyAqLworcHVibGljIGludGVyZmFjZSBDb250ZW50SGFuZGxlcgoreworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBhbiBvYmplY3QgZm9yIGxvY2F0aW5nIHRoZSBvcmlnaW4gb2YgU0FYIGRvY3VtZW50IGV2ZW50cy4KKyAgICAgKgorICAgICAqIDxwPlNBWCBwYXJzZXJzIGFyZSBzdHJvbmdseSBlbmNvdXJhZ2VkICh0aG91Z2ggbm90IGFic29sdXRlbHkKKyAgICAgKiByZXF1aXJlZCkgdG8gc3VwcGx5IGEgbG9jYXRvcjogaWYgaXQgZG9lcyBzbywgaXQgbXVzdCBzdXBwbHkKKyAgICAgKiB0aGUgbG9jYXRvciB0byB0aGUgYXBwbGljYXRpb24gYnkgaW52b2tpbmcgdGhpcyBtZXRob2QgYmVmb3JlCisgICAgICogaW52b2tpbmcgYW55IG9mIHRoZSBvdGhlciBtZXRob2RzIGluIHRoZSBDb250ZW50SGFuZGxlcgorICAgICAqIGludGVyZmFjZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgbG9jYXRvciBhbGxvd3MgdGhlIGFwcGxpY2F0aW9uIHRvIGRldGVybWluZSB0aGUgZW5kCisgICAgICogcG9zaXRpb24gb2YgYW55IGRvY3VtZW50LXJlbGF0ZWQgZXZlbnQsIGV2ZW4gaWYgdGhlIHBhcnNlciBpcworICAgICAqIG5vdCByZXBvcnRpbmcgYW4gZXJyb3IuICBUeXBpY2FsbHksIHRoZSBhcHBsaWNhdGlvbiB3aWxsCisgICAgICogdXNlIHRoaXMgaW5mb3JtYXRpb24gZm9yIHJlcG9ydGluZyBpdHMgb3duIGVycm9ycyAoc3VjaCBhcworICAgICAqIGNoYXJhY3RlciBjb250ZW50IHRoYXQgZG9lcyBub3QgbWF0Y2ggYW4gYXBwbGljYXRpb24ncworICAgICAqIGJ1c2luZXNzIHJ1bGVzKS4gIFRoZSBpbmZvcm1hdGlvbiByZXR1cm5lZCBieSB0aGUgbG9jYXRvcgorICAgICAqIGlzIHByb2JhYmx5IG5vdCBzdWZmaWNpZW50IGZvciB1c2Ugd2l0aCBhIHNlYXJjaCBlbmdpbmUuPC9wPgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IHRoZSBsb2NhdG9yIHdpbGwgcmV0dXJuIGNvcnJlY3QgaW5mb3JtYXRpb24gb25seQorICAgICAqIGR1cmluZyB0aGUgaW52b2NhdGlvbiBTQVggZXZlbnQgY2FsbGJhY2tzIGFmdGVyCisgICAgICoge0BsaW5rICNzdGFydERvY3VtZW50IHN0YXJ0RG9jdW1lbnR9IHJldHVybnMgYW5kIGJlZm9yZQorICAgICAqIHtAbGluayAjZW5kRG9jdW1lbnQgZW5kRG9jdW1lbnR9IGlzIGNhbGxlZC4gIFRoZQorICAgICAqIGFwcGxpY2F0aW9uIHNob3VsZCBub3QgYXR0ZW1wdCB0byB1c2UgaXQgYXQgYW55IG90aGVyIHRpbWUuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2F0b3IgYW4gb2JqZWN0IHRoYXQgY2FuIHJldHVybiB0aGUgbG9jYXRpb24gb2YKKyAgICAgKiAgICAgICAgICAgICAgICBhbnkgU0FYIGRvY3VtZW50IGV2ZW50CisgICAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yIChMb2NhdG9yIGxvY2F0b3IpOworCisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIGEgZG9jdW1lbnQuCisgICAgICoKKyAgICAgKiA8cD5UaGUgU0FYIHBhcnNlciB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBvbmx5IG9uY2UsIGJlZm9yZSBhbnkKKyAgICAgKiBvdGhlciBldmVudCBjYWxsYmFja3MgKGV4Y2VwdCBmb3Ige0BsaW5rICNzZXREb2N1bWVudExvY2F0b3IKKyAgICAgKiBzZXREb2N1bWVudExvY2F0b3J9KS48L3A+CisgICAgICoKKyAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBhbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKKyAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uCisgICAgICogQHNlZSAjZW5kRG9jdW1lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50ICgpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhIGRvY3VtZW50LgorICAgICAqCisgICAgICogPHA+PHN0cm9uZz5UaGVyZSBpcyBhbiBhcHBhcmVudCBjb250cmFkaWN0aW9uIGJldHdlZW4gdGhlCisgICAgICogZG9jdW1lbnRhdGlvbiBmb3IgdGhpcyBtZXRob2QgYW5kIHRoZSBkb2N1bWVudGF0aW9uIGZvciB7QGxpbmsKKyAgICAgKiBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIjZmF0YWxFcnJvcn0uICBVbnRpbCB0aGlzIGFtYmlndWl0eSBpcworICAgICAqIHJlc29sdmVkIGluIGEgZnV0dXJlIG1ham9yIHJlbGVhc2UsIGNsaWVudHMgc2hvdWxkIG1ha2Ugbm8KKyAgICAgKiBhc3N1bXB0aW9ucyBhYm91dCB3aGV0aGVyIGVuZERvY3VtZW50KCkgd2lsbCBvciB3aWxsIG5vdCBiZQorICAgICAqIGludm9rZWQgd2hlbiB0aGUgcGFyc2VyIGhhcyByZXBvcnRlZCBhIGZhdGFsRXJyb3IoKSBvciB0aHJvd24KKyAgICAgKiBhbiBleGNlcHRpb24uPC9zdHJvbmc+PC9wPgorICAgICAqCisgICAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25seSBvbmNlLCBhbmQgaXQgd2lsbAorICAgICAqIGJlIHRoZSBsYXN0IG1ldGhvZCBpbnZva2VkIGR1cmluZyB0aGUgcGFyc2UuICBUaGUgcGFyc2VyIHNoYWxsCisgICAgICogbm90IGludm9rZSB0aGlzIG1ldGhvZCB1bnRpbCBpdCBoYXMgZWl0aGVyIGFiYW5kb25lZCBwYXJzaW5nCisgICAgICogKGJlY2F1c2Ugb2YgYW4gdW5yZWNvdmVyYWJsZSBlcnJvcikgb3IgcmVhY2hlZCB0aGUgZW5kIG9mCisgICAgICogaW5wdXQuPC9wPgorICAgICAqCisgICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gYW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbgorICAgICAqIEBzZWUgI3N0YXJ0RG9jdW1lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKKworCisgICAgLyoqCisgICAgICogQmVnaW4gdGhlIHNjb3BlIG9mIGEgcHJlZml4LVVSSSBOYW1lc3BhY2UgbWFwcGluZy4KKyAgICAgKgorICAgICAqIDxwPlRoZSBpbmZvcm1hdGlvbiBmcm9tIHRoaXMgZXZlbnQgaXMgbm90IG5lY2Vzc2FyeSBmb3IKKyAgICAgKiBub3JtYWwgTmFtZXNwYWNlIHByb2Nlc3Npbmc6IHRoZSBTQVggWE1MIHJlYWRlciB3aWxsCisgICAgICogYXV0b21hdGljYWxseSByZXBsYWNlIHByZWZpeGVzIGZvciBlbGVtZW50IGFuZCBhdHRyaWJ1dGUKKyAgICAgKiBuYW1lcyB3aGVuIHRoZSA8Y29kZT5odHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlczwvY29kZT4KKyAgICAgKiBmZWF0dXJlIGlzIDx2YXI+dHJ1ZTwvdmFyPiAodGhlIGRlZmF1bHQpLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZXJlIGFyZSBjYXNlcywgaG93ZXZlciwgd2hlbiBhcHBsaWNhdGlvbnMgbmVlZCB0bworICAgICAqIHVzZSBwcmVmaXhlcyBpbiBjaGFyYWN0ZXIgZGF0YSBvciBpbiBhdHRyaWJ1dGUgdmFsdWVzLAorICAgICAqIHdoZXJlIHRoZXkgY2Fubm90IHNhZmVseSBiZSBleHBhbmRlZCBhdXRvbWF0aWNhbGx5OyB0aGUKKyAgICAgKiBzdGFydC9lbmRQcmVmaXhNYXBwaW5nIGV2ZW50IHN1cHBsaWVzIHRoZSBpbmZvcm1hdGlvbgorICAgICAqIHRvIHRoZSBhcHBsaWNhdGlvbiB0byBleHBhbmQgcHJlZml4ZXMgaW4gdGhvc2UgY29udGV4dHMKKyAgICAgKiBpdHNlbGYsIGlmIG5lY2Vzc2FyeS48L3A+CisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoYXQgc3RhcnQvZW5kUHJlZml4TWFwcGluZyBldmVudHMgYXJlIG5vdAorICAgICAqIGd1YXJhbnRlZWQgdG8gYmUgcHJvcGVybHkgbmVzdGVkIHJlbGF0aXZlIHRvIGVhY2ggb3RoZXI6CisgICAgICogYWxsIHN0YXJ0UHJlZml4TWFwcGluZyBldmVudHMgd2lsbCBvY2N1ciBpbW1lZGlhdGVseSBiZWZvcmUgdGhlCisgICAgICogY29ycmVzcG9uZGluZyB7QGxpbmsgI3N0YXJ0RWxlbWVudCBzdGFydEVsZW1lbnR9IGV2ZW50LAorICAgICAqIGFuZCBhbGwge0BsaW5rICNlbmRQcmVmaXhNYXBwaW5nIGVuZFByZWZpeE1hcHBpbmd9CisgICAgICogZXZlbnRzIHdpbGwgb2NjdXIgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIGNvcnJlc3BvbmRpbmcKKyAgICAgKiB7QGxpbmsgI2VuZEVsZW1lbnQgZW5kRWxlbWVudH0gZXZlbnQsCisgICAgICogYnV0IHRoZWlyIG9yZGVyIGlzIG5vdCBvdGhlcndpc2UKKyAgICAgKiBndWFyYW50ZWVkLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZXJlIHNob3VsZCBuZXZlciBiZSBzdGFydC9lbmRQcmVmaXhNYXBwaW5nIGV2ZW50cyBmb3IgdGhlCisgICAgICogInhtbCIgcHJlZml4LCBzaW5jZSBpdCBpcyBwcmVkZWNsYXJlZCBhbmQgaW1tdXRhYmxlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcmVmaXggdGhlIE5hbWVzcGFjZSBwcmVmaXggYmVpbmcgZGVjbGFyZWQuCisgICAgICogICAgQW4gZW1wdHkgc3RyaW5nIGlzIHVzZWQgZm9yIHRoZSBkZWZhdWx0IGVsZW1lbnQgbmFtZXNwYWNlLAorICAgICAqICAgIHdoaWNoIGhhcyBubyBwcmVmaXguCisgICAgICogQHBhcmFtIHVyaSB0aGUgTmFtZXNwYWNlIFVSSSB0aGUgcHJlZml4IGlzIG1hcHBlZCB0bworICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHRoZSBjbGllbnQgbWF5IHRocm93CisgICAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcKKyAgICAgKiBAc2VlICNlbmRQcmVmaXhNYXBwaW5nCisgICAgICogQHNlZSAjc3RhcnRFbGVtZW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nIChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQorICAgIHRocm93cyBTQVhFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIEVuZCB0aGUgc2NvcGUgb2YgYSBwcmVmaXgtVVJJIG1hcHBpbmcuCisgICAgICoKKyAgICAgKiA8cD5TZWUge0BsaW5rICNzdGFydFByZWZpeE1hcHBpbmcgc3RhcnRQcmVmaXhNYXBwaW5nfSBmb3IKKyAgICAgKiBkZXRhaWxzLiAgVGhlc2UgZXZlbnRzIHdpbGwgYWx3YXlzIG9jY3VyIGltbWVkaWF0ZWx5IGFmdGVyIHRoZQorICAgICAqIGNvcnJlc3BvbmRpbmcge0BsaW5rICNlbmRFbGVtZW50IGVuZEVsZW1lbnR9IGV2ZW50LCBidXQgdGhlIG9yZGVyIG9mCisgICAgICoge0BsaW5rICNlbmRQcmVmaXhNYXBwaW5nIGVuZFByZWZpeE1hcHBpbmd9IGV2ZW50cyBpcyBub3Qgb3RoZXJ3aXNlCisgICAgICogZ3VhcmFudGVlZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJlZml4IHRoZSBwcmVmaXggdGhhdCB3YXMgYmVpbmcgbWFwcGVkLgorICAgICAqICAgIFRoaXMgaXMgdGhlIGVtcHR5IHN0cmluZyB3aGVuIGEgZGVmYXVsdCBtYXBwaW5nIHNjb3BlIGVuZHMuCisgICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gdGhlIGNsaWVudCBtYXkgdGhyb3cKKyAgICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZworICAgICAqIEBzZWUgI3N0YXJ0UHJlZml4TWFwcGluZworICAgICAqIEBzZWUgI2VuZEVsZW1lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nIChTdHJpbmcgcHJlZml4KQorICAgIHRocm93cyBTQVhFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYW4gZWxlbWVudC4KKyAgICAgKgorICAgICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2QgYXQgdGhlIGJlZ2lubmluZyBvZiBldmVyeQorICAgICAqIGVsZW1lbnQgaW4gdGhlIFhNTCBkb2N1bWVudDsgdGhlcmUgd2lsbCBiZSBhIGNvcnJlc3BvbmRpbmcKKyAgICAgKiB7QGxpbmsgI2VuZEVsZW1lbnQgZW5kRWxlbWVudH0gZXZlbnQgZm9yIGV2ZXJ5IHN0YXJ0RWxlbWVudCBldmVudAorICAgICAqIChldmVuIHdoZW4gdGhlIGVsZW1lbnQgaXMgZW1wdHkpLiBBbGwgb2YgdGhlIGVsZW1lbnQncyBjb250ZW50IHdpbGwgYmUKKyAgICAgKiByZXBvcnRlZCwgaW4gb3JkZXIsIGJlZm9yZSB0aGUgY29ycmVzcG9uZGluZyBlbmRFbGVtZW50CisgICAgICogZXZlbnQuPC9wPgorICAgICAqCisgICAgICogPHA+VGhpcyBldmVudCBhbGxvd3MgdXAgdG8gdGhyZWUgbmFtZSBjb21wb25lbnRzIGZvciBlYWNoCisgICAgICogZWxlbWVudDo8L3A+CisgICAgICoKKyAgICAgKiA8b2w+CisgICAgICogPGxpPnRoZSBOYW1lc3BhY2UgVVJJOzwvbGk+CisgICAgICogPGxpPnRoZSBsb2NhbCBuYW1lOyBhbmQ8L2xpPgorICAgICAqIDxsaT50aGUgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS48L2xpPgorICAgICAqIDwvb2w+CisgICAgICoKKyAgICAgKiA8cD5Bbnkgb3IgYWxsIG9mIHRoZXNlIG1heSBiZSBwcm92aWRlZCwgZGVwZW5kaW5nIG9uIHRoZQorICAgICAqIHZhbHVlcyBvZiB0aGUgPHZhcj5odHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlczwvdmFyPgorICAgICAqIGFuZCB0aGUgPHZhcj5odHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzPC92YXI+CisgICAgICogcHJvcGVydGllczo8L3A+CisgICAgICoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPnRoZSBOYW1lc3BhY2UgVVJJIGFuZCBsb2NhbCBuYW1lIGFyZSByZXF1aXJlZCB3aGVuCisgICAgICogdGhlIG5hbWVzcGFjZXMgcHJvcGVydHkgaXMgPHZhcj50cnVlPC92YXI+ICh0aGUgZGVmYXVsdCksIGFuZCBhcmUKKyAgICAgKiBvcHRpb25hbCB3aGVuIHRoZSBuYW1lc3BhY2VzIHByb3BlcnR5IGlzIDx2YXI+ZmFsc2U8L3Zhcj4gKGlmIG9uZSBpcworICAgICAqIHNwZWNpZmllZCwgYm90aCBtdXN0IGJlKTs8L2xpPgorICAgICAqIDxsaT50aGUgcXVhbGlmaWVkIG5hbWUgaXMgcmVxdWlyZWQgd2hlbiB0aGUgbmFtZXNwYWNlLXByZWZpeGVzIHByb3BlcnR5CisgICAgICogaXMgPHZhcj50cnVlPC92YXI+LCBhbmQgaXMgb3B0aW9uYWwgd2hlbiB0aGUgbmFtZXNwYWNlLXByZWZpeGVzIHByb3BlcnR5CisgICAgICogaXMgPHZhcj5mYWxzZTwvdmFyPiAodGhlIGRlZmF1bHQpLjwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB0aGUgYXR0cmlidXRlIGxpc3QgcHJvdmlkZWQgd2lsbCBjb250YWluIG9ubHkKKyAgICAgKiBhdHRyaWJ1dGVzIHdpdGggZXhwbGljaXQgdmFsdWVzIChzcGVjaWZpZWQgb3IgZGVmYXVsdGVkKToKKyAgICAgKiAjSU1QTElFRCBhdHRyaWJ1dGVzIHdpbGwgYmUgb21pdHRlZC4gIFRoZSBhdHRyaWJ1dGUgbGlzdAorICAgICAqIHdpbGwgY29udGFpbiBhdHRyaWJ1dGVzIHVzZWQgZm9yIE5hbWVzcGFjZSBkZWNsYXJhdGlvbnMKKyAgICAgKiAoeG1sbnMqIGF0dHJpYnV0ZXMpIG9ubHkgaWYgdGhlCisgICAgICogPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZS1wcmVmaXhlczwvY29kZT4KKyAgICAgKiBwcm9wZXJ0eSBpcyB0cnVlIChpdCBpcyBmYWxzZSBieSBkZWZhdWx0LCBhbmQgc3VwcG9ydCBmb3IgYQorICAgICAqIHRydWUgdmFsdWUgaXMgb3B0aW9uYWwpLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkxpa2Uge0BsaW5rICNjaGFyYWN0ZXJzIGNoYXJhY3RlcnMoKX0sIGF0dHJpYnV0ZSB2YWx1ZXMgbWF5IGhhdmUKKyAgICAgKiBjaGFyYWN0ZXJzIHRoYXQgbmVlZCBtb3JlIHRoYW4gb25lIDxjb2RlPmNoYXI8L2NvZGU+IHZhbHVlLiAgPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHVyaSB0aGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKKyAgICAgKiAgICAgICAgZWxlbWVudCBoYXMgbm8gTmFtZXNwYWNlIFVSSSBvciBpZiBOYW1lc3BhY2UKKyAgICAgKiAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkCisgICAgICogQHBhcmFtIGxvY2FsTmFtZSB0aGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciB0aGUKKyAgICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZworICAgICAqICAgICAgICBwZXJmb3JtZWQKKyAgICAgKiBAcGFyYW0gcU5hbWUgdGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCksIG9yIHRoZQorICAgICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcXVhbGlmaWVkIG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlCisgICAgICogQHBhcmFtIGF0dHMgdGhlIGF0dHJpYnV0ZXMgYXR0YWNoZWQgdG8gdGhlIGVsZW1lbnQuICBJZgorICAgICAqICAgICAgICB0aGVyZSBhcmUgbm8gYXR0cmlidXRlcywgaXQgc2hhbGwgYmUgYW4gZW1wdHkKKyAgICAgKiAgICAgICAgQXR0cmlidXRlcyBvYmplY3QuICBUaGUgdmFsdWUgb2YgdGhpcyBvYmplY3QgYWZ0ZXIKKyAgICAgKiAgICAgICAgc3RhcnRFbGVtZW50IHJldHVybnMgaXMgdW5kZWZpbmVkCisgICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gYW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbgorICAgICAqIEBzZWUgI2VuZEVsZW1lbnQKKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMKKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlc0ltcGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsCisgICAgICAgICAgICAgICAgICBTdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cykKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIGFuIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiA8cD5UaGUgU0FYIHBhcnNlciB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBhdCB0aGUgZW5kIG9mIGV2ZXJ5CisgICAgICogZWxlbWVudCBpbiB0aGUgWE1MIGRvY3VtZW50OyB0aGVyZSB3aWxsIGJlIGEgY29ycmVzcG9uZGluZworICAgICAqIHtAbGluayAjc3RhcnRFbGVtZW50IHN0YXJ0RWxlbWVudH0gZXZlbnQgZm9yIGV2ZXJ5IGVuZEVsZW1lbnQKKyAgICAgKiBldmVudCAoZXZlbiB3aGVuIHRoZSBlbGVtZW50IGlzIGVtcHR5KS48L3A+CisgICAgICoKKyAgICAgKiA8cD5Gb3IgaW5mb3JtYXRpb24gb24gdGhlIG5hbWVzLCBzZWUgc3RhcnRFbGVtZW50LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmkgdGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgdGhlCisgICAgICogICAgICAgIGVsZW1lbnQgaGFzIG5vIE5hbWVzcGFjZSBVUkkgb3IgaWYgTmFtZXNwYWNlCisgICAgICogICAgICAgIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nIHBlcmZvcm1lZAorICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgdGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCisgICAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcKKyAgICAgKiAgICAgICAgcGVyZm9ybWVkCisgICAgICogQHBhcmFtIHFOYW1lIHRoZSBxdWFsaWZpZWQgWE1MIG5hbWUgKHdpdGggcHJlZml4KSwgb3IgdGhlCisgICAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBxdWFsaWZpZWQgbmFtZXMgYXJlIG5vdCBhdmFpbGFibGUKKyAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBhbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKKyAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgZW5kRWxlbWVudCAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwKKyAgICAgICAgICAgICAgICBTdHJpbmcgcU5hbWUpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgY2hhcmFjdGVyIGRhdGEuCisgICAgICoKKyAgICAgKiA8cD5UaGUgUGFyc2VyIHdpbGwgY2FsbCB0aGlzIG1ldGhvZCB0byByZXBvcnQgZWFjaCBjaHVuayBvZgorICAgICAqIGNoYXJhY3RlciBkYXRhLiAgU0FYIHBhcnNlcnMgbWF5IHJldHVybiBhbGwgY29udGlndW91cyBjaGFyYWN0ZXIKKyAgICAgKiBkYXRhIGluIGEgc2luZ2xlIGNodW5rLCBvciB0aGV5IG1heSBzcGxpdCBpdCBpbnRvIHNldmVyYWwKKyAgICAgKiBjaHVua3M7IGhvd2V2ZXIsIGFsbCBvZiB0aGUgY2hhcmFjdGVycyBpbiBhbnkgc2luZ2xlIGV2ZW50CisgICAgICogbXVzdCBjb21lIGZyb20gdGhlIHNhbWUgZXh0ZXJuYWwgZW50aXR5IHNvIHRoYXQgdGhlIExvY2F0b3IKKyAgICAgKiBwcm92aWRlcyB1c2VmdWwgaW5mb3JtYXRpb24uPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3Qgbm90IGF0dGVtcHQgdG8gcmVhZCBmcm9tIHRoZSBhcnJheQorICAgICAqIG91dHNpZGUgb2YgdGhlIHNwZWNpZmllZCByYW5nZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5JbmRpdmlkdWFsIGNoYXJhY3RlcnMgbWF5IGNvbnNpc3Qgb2YgbW9yZSB0aGFuIG9uZSBKYXZhCisgICAgICogPGNvZGU+Y2hhcjwvY29kZT4gdmFsdWUuICBUaGVyZSBhcmUgdHdvIGltcG9ydGFudCBjYXNlcyB3aGVyZSB0aGlzCisgICAgICogaGFwcGVucywgYmVjYXVzZSBjaGFyYWN0ZXJzIGNhbid0IGJlIHJlcHJlc2VudGVkIGluIGp1c3Qgc2l4dGVlbiBiaXRzLgorICAgICAqIEluIG9uZSBjYXNlLCBjaGFyYWN0ZXJzIGFyZSByZXByZXNlbnRlZCBpbiBhIDxlbT5TdXJyb2dhdGUgUGFpcjwvZW0+LAorICAgICAqIHVzaW5nIHR3byBzcGVjaWFsIFVuaWNvZGUgdmFsdWVzLiBTdWNoIGNoYXJhY3RlcnMgYXJlIGluIHRoZSBzby1jYWxsZWQKKyAgICAgKiAiQXN0cmFsIFBsYW5lcyIsIHdpdGggYSBjb2RlIHBvaW50IGFib3ZlIFUrRkZGRi4gIEEgc2Vjb25kIGNhc2UgaW52b2x2ZXMKKyAgICAgKiBjb21wb3NpdGUgY2hhcmFjdGVycywgc3VjaCBhcyBhIGJhc2UgY2hhcmFjdGVyIGNvbWJpbmluZyB3aXRoIG9uZSBvcgorICAgICAqIG1vcmUgYWNjZW50IGNoYXJhY3RlcnMuIDwvcD4KKyAgICAgKgorICAgICAqIDxwPiBZb3VyIGNvZGUgc2hvdWxkIG5vdCBhc3N1bWUgdGhhdCBhbGdvcml0aG1zIHVzaW5nCisgICAgICogPGNvZGU+Y2hhcjwvY29kZT4tYXQtYS10aW1lIGlkaW9tcyB3aWxsIGJlIHdvcmtpbmcgaW4gY2hhcmFjdGVyCisgICAgICogdW5pdHM7IGluIHNvbWUgY2FzZXMgdGhleSB3aWxsIHNwbGl0IGNoYXJhY3RlcnMuICBUaGlzIGlzIHJlbGV2YW50CisgICAgICogd2hlcmV2ZXIgWE1MIHBlcm1pdHMgYXJiaXRyYXJ5IGNoYXJhY3RlcnMsIHN1Y2ggYXMgYXR0cmlidXRlIHZhbHVlcywKKyAgICAgKiBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGRhdGEsIGFuZCBjb21tZW50cyBhcyB3ZWxsIGFzIGluIGRhdGEgcmVwb3J0ZWQKKyAgICAgKiBmcm9tIHRoaXMgbWV0aG9kLiAgSXQncyBhbHNvIGdlbmVyYWxseSByZWxldmFudCB3aGVuZXZlciBKYXZhIGNvZGUKKyAgICAgKiBtYW5pcHVsYXRlcyBpbnRlcm5hdGlvbmFsaXplZCB0ZXh0OyB0aGUgaXNzdWUgaXNuJ3QgdW5pcXVlIHRvIFhNTC48L3A+CisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoYXQgc29tZSBwYXJzZXJzIHdpbGwgcmVwb3J0IHdoaXRlc3BhY2UgaW4gZWxlbWVudAorICAgICAqIGNvbnRlbnQgdXNpbmcgdGhlIHtAbGluayAjaWdub3JhYmxlV2hpdGVzcGFjZSBpZ25vcmFibGVXaGl0ZXNwYWNlfQorICAgICAqIG1ldGhvZCByYXRoZXIgdGhhbiB0aGlzIG9uZSAodmFsaWRhdGluZyBwYXJzZXJzIDxlbT5tdXN0PC9lbT4KKyAgICAgKiBkbyBzbykuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGNoIHRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudAorICAgICAqIEBwYXJhbSBzdGFydCB0aGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5CisgICAgICogQHBhcmFtIGxlbmd0aCB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheQorICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIGFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24KKyAgICAgKiBAc2VlICNpZ25vcmFibGVXaGl0ZXNwYWNlCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyAoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgaWdub3JhYmxlIHdoaXRlc3BhY2UgaW4gZWxlbWVudCBjb250ZW50LgorICAgICAqCisgICAgICogPHA+VmFsaWRhdGluZyBQYXJzZXJzIG11c3QgdXNlIHRoaXMgbWV0aG9kIHRvIHJlcG9ydCBlYWNoIGNodW5rCisgICAgICogb2Ygd2hpdGVzcGFjZSBpbiBlbGVtZW50IGNvbnRlbnQgKHNlZSB0aGUgVzNDIFhNTCAxLjAKKyAgICAgKiByZWNvbW1lbmRhdGlvbiwgc2VjdGlvbiAyLjEwKTogbm9uLXZhbGlkYXRpbmcgcGFyc2VycyBtYXkgYWxzbworICAgICAqIHVzZSB0aGlzIG1ldGhvZCBpZiB0aGV5IGFyZSBjYXBhYmxlIG9mIHBhcnNpbmcgYW5kIHVzaW5nCisgICAgICogY29udGVudCBtb2RlbHMuPC9wPgorICAgICAqCisgICAgICogPHA+U0FYIHBhcnNlcnMgbWF5IHJldHVybiBhbGwgY29udGlndW91cyB3aGl0ZXNwYWNlIGluIGEgc2luZ2xlCisgICAgICogY2h1bmssIG9yIHRoZXkgbWF5IHNwbGl0IGl0IGludG8gc2V2ZXJhbCBjaHVua3M7IGhvd2V2ZXIsIGFsbCBvZgorICAgICAqIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQgbXVzdCBjb21lIGZyb20gdGhlIHNhbWUKKyAgICAgKiBleHRlcm5hbCBlbnRpdHksIHNvIHRoYXQgdGhlIExvY2F0b3IgcHJvdmlkZXMgdXNlZnVsCisgICAgICogaW5mb3JtYXRpb24uPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3Qgbm90IGF0dGVtcHQgdG8gcmVhZCBmcm9tIHRoZSBhcnJheQorICAgICAqIG91dHNpZGUgb2YgdGhlIHNwZWNpZmllZCByYW5nZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2ggdGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50CisgICAgICogQHBhcmFtIHN0YXJ0IHRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkKKyAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5CisgICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gYW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbgorICAgICAqIEBzZWUgI2NoYXJhY3RlcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCisgICAgICoKKyAgICAgKiA8cD5UaGUgUGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIG9uY2UgZm9yIGVhY2ggcHJvY2Vzc2luZworICAgICAqIGluc3RydWN0aW9uIGZvdW5kOiBub3RlIHRoYXQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgbWF5IG9jY3VyCisgICAgICogYmVmb3JlIG9yIGFmdGVyIHRoZSBtYWluIGRvY3VtZW50IGVsZW1lbnQuPC9wPgorICAgICAqCisgICAgICogPHA+QSBTQVggcGFyc2VyIG11c3QgbmV2ZXIgcmVwb3J0IGFuIFhNTCBkZWNsYXJhdGlvbiAoWE1MIDEuMCwKKyAgICAgKiBzZWN0aW9uIDIuOCkgb3IgYSB0ZXh0IGRlY2xhcmF0aW9uIChYTUwgMS4wLCBzZWN0aW9uIDQuMy4xKQorICAgICAqIHVzaW5nIHRoaXMgbWV0aG9kLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkxpa2Uge0BsaW5rICNjaGFyYWN0ZXJzIGNoYXJhY3RlcnMoKX0sIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24KKyAgICAgKiBkYXRhIG1heSBoYXZlIGNoYXJhY3RlcnMgdGhhdCBuZWVkIG1vcmUgdGhhbiBvbmUgPGNvZGU+Y2hhcjwvY29kZT4KKyAgICAgKiB2YWx1ZS4gPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHRhcmdldCB0aGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0YXJnZXQKKyAgICAgKiBAcGFyYW0gZGF0YSB0aGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBkYXRhLCBvciBudWxsIGlmCisgICAgICogICAgICAgIG5vbmUgd2FzIHN1cHBsaWVkLiAgVGhlIGRhdGEgZG9lcyBub3QgaW5jbHVkZSBhbnkKKyAgICAgKiAgICAgICAgd2hpdGVzcGFjZSBzZXBhcmF0aW5nIGl0IGZyb20gdGhlIHRhcmdldAorICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIGFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQorICAgIHRocm93cyBTQVhFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgc2tpcHBlZCBlbnRpdHkuCisgICAgICogVGhpcyBpcyBub3QgY2FsbGVkIGZvciBlbnRpdHkgcmVmZXJlbmNlcyB3aXRoaW4gbWFya3VwIGNvbnN0cnVjdHMKKyAgICAgKiBzdWNoIGFzIGVsZW1lbnQgc3RhcnQgdGFncyBvciBtYXJrdXAgZGVjbGFyYXRpb25zLiAgKFRoZSBYTUwKKyAgICAgKiByZWNvbW1lbmRhdGlvbiByZXF1aXJlcyByZXBvcnRpbmcgc2tpcHBlZCBleHRlcm5hbCBlbnRpdGllcy4KKyAgICAgKiBTQVggYWxzbyByZXBvcnRzIGludGVybmFsIGVudGl0eSBleHBhbnNpb24vbm9uLWV4cGFuc2lvbiwgZXhjZXB0CisgICAgICogd2l0aGluIG1hcmt1cCBjb25zdHJ1Y3RzLikKKyAgICAgKgorICAgICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2QgZWFjaCB0aW1lIHRoZSBlbnRpdHkgaXMKKyAgICAgKiBza2lwcGVkLiAgTm9uLXZhbGlkYXRpbmcgcHJvY2Vzc29ycyBtYXkgc2tpcCBlbnRpdGllcyBpZiB0aGV5CisgICAgICogaGF2ZSBub3Qgc2VlbiB0aGUgZGVjbGFyYXRpb25zIChiZWNhdXNlLCBmb3IgZXhhbXBsZSwgdGhlCisgICAgICogZW50aXR5IHdhcyBkZWNsYXJlZCBpbiBhbiBleHRlcm5hbCBEVEQgc3Vic2V0KS4gIEFsbCBwcm9jZXNzb3JzCisgICAgICogbWF5IHNraXAgZXh0ZXJuYWwgZW50aXRpZXMsIGRlcGVuZGluZyBvbiB0aGUgdmFsdWVzIG9mIHRoZQorICAgICAqIDxjb2RlPmh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9leHRlcm5hbC1nZW5lcmFsLWVudGl0aWVzPC9jb2RlPgorICAgICAqIGFuZCB0aGUKKyAgICAgKiA8Y29kZT5odHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvZXh0ZXJuYWwtcGFyYW1ldGVyLWVudGl0aWVzPC9jb2RlPgorICAgICAqIHByb3BlcnRpZXMuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhlIHNraXBwZWQgZW50aXR5LiAgSWYgaXQgaXMgYQorICAgICAqICAgICAgICBwYXJhbWV0ZXIgZW50aXR5LCB0aGUgbmFtZSB3aWxsIGJlZ2luIHdpdGggJyUnLCBhbmQgaWYKKyAgICAgKiAgICAgICAgaXQgaXMgdGhlIGV4dGVybmFsIERURCBzdWJzZXQsIGl0IHdpbGwgYmUgdGhlIHN0cmluZworICAgICAqICAgICAgICAiW2R0ZF0iCisgICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gYW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkgKFN0cmluZyBuYW1lKQorICAgIHRocm93cyBTQVhFeGNlcHRpb247Cit9CisKKy8vIGVuZCBvZiBDb250ZW50SGFuZGxlci5qYXZhCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvRFRESGFuZGxlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L0RUREhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMTAyNzkyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L0RUREhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDExNyBAQAorLy8gU0FYIERURCBoYW5kbGVyLgorLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZworLy8gTm8gd2FycmFudHk7IG5vIGNvcHlyaWdodCAtLSB1c2UgdGhpcyBhcyB5b3Ugd2lsbC4KKy8vICRJZDogRFRESGFuZGxlci5qYXZhLHYgMS44IDIwMDIvMDEvMzAgMjE6MTM6NDMgZGJyb3duZWxsIEV4cCAkCisKK3BhY2thZ2Ugb3JnLnhtbC5zYXg7CisKKy8qKgorICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYmFzaWMgRFRELXJlbGF0ZWQgZXZlbnRzLgorICoKKyAqIDxibG9ja3F1b3RlPgorICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKKyAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KKyAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgorICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+SWYgYSBTQVggYXBwbGljYXRpb24gbmVlZHMgaW5mb3JtYXRpb24gYWJvdXQgbm90YXRpb25zIGFuZAorICogdW5wYXJzZWQgZW50aXRpZXMsIHRoZW4gdGhlIGFwcGxpY2F0aW9uIGltcGxlbWVudHMgdGhpcworICogaW50ZXJmYWNlIGFuZCByZWdpc3RlcnMgYW4gaW5zdGFuY2Ugd2l0aCB0aGUgU0FYIHBhcnNlciB1c2luZworICogdGhlIHBhcnNlcidzIHNldERUREhhbmRsZXIgbWV0aG9kLiAgVGhlIHBhcnNlciB1c2VzIHRoZQorICogaW5zdGFuY2UgdG8gcmVwb3J0IG5vdGF0aW9uIGFuZCB1bnBhcnNlZCBlbnRpdHkgZGVjbGFyYXRpb25zIHRvCisgKiB0aGUgYXBwbGljYXRpb24uPC9wPgorICoKKyAqIDxwPk5vdGUgdGhhdCB0aGlzIGludGVyZmFjZSBpbmNsdWRlcyBvbmx5IHRob3NlIERURCBldmVudHMgdGhhdAorICogdGhlIFhNTCByZWNvbW1lbmRhdGlvbiA8ZW0+cmVxdWlyZXM8L2VtPiBwcm9jZXNzb3JzIHRvIHJlcG9ydDoKKyAqIG5vdGF0aW9uIGFuZCB1bnBhcnNlZCBlbnRpdHkgZGVjbGFyYXRpb25zLjwvcD4KKyAqCisgKiA8cD5UaGUgU0FYIHBhcnNlciBtYXkgcmVwb3J0IHRoZXNlIGV2ZW50cyBpbiBhbnkgb3JkZXIsIHJlZ2FyZGxlc3MKKyAqIG9mIHRoZSBvcmRlciBpbiB3aGljaCB0aGUgbm90YXRpb25zIGFuZCB1bnBhcnNlZCBlbnRpdGllcyB3ZXJlCisgKiBkZWNsYXJlZDsgaG93ZXZlciwgYWxsIERURCBldmVudHMgbXVzdCBiZSByZXBvcnRlZCBhZnRlciB0aGUKKyAqIGRvY3VtZW50IGhhbmRsZXIncyBzdGFydERvY3VtZW50IGV2ZW50LCBhbmQgYmVmb3JlIHRoZSBmaXJzdAorICogc3RhcnRFbGVtZW50IGV2ZW50LgorICogKElmIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyIExleGljYWxIYW5kbGVyfSBpcworICogdXNlZCwgdGhlc2UgZXZlbnRzIG11c3QgYWxzbyBiZSByZXBvcnRlZCBiZWZvcmUgdGhlIGVuZERURCBldmVudC4pCisgKiA8L3A+CisgKgorICogPHA+SXQgaXMgdXAgdG8gdGhlIGFwcGxpY2F0aW9uIHRvIHN0b3JlIHRoZSBpbmZvcm1hdGlvbiBmb3IKKyAqIGZ1dHVyZSB1c2UgKHBlcmhhcHMgaW4gYSBoYXNoIHRhYmxlIG9yIG9iamVjdCB0cmVlKS4KKyAqIElmIHRoZSBhcHBsaWNhdGlvbiBlbmNvdW50ZXJzIGF0dHJpYnV0ZXMgb2YgdHlwZSAiTk9UQVRJT04iLAorICogIkVOVElUWSIsIG9yICJFTlRJVElFUyIsIGl0IGNhbiB1c2UgdGhlIGluZm9ybWF0aW9uIHRoYXQgaXQKKyAqIG9idGFpbmVkIHRocm91Z2ggdGhpcyBpbnRlcmZhY2UgdG8gZmluZCB0aGUgZW50aXR5IGFuZC9vcgorICogbm90YXRpb24gY29ycmVzcG9uZGluZyB3aXRoIHRoZSBhdHRyaWJ1dGUgdmFsdWUuPC9wPgorICoKKyAqIEBzaW5jZSBTQVggMS4wCisgKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgorICogQHZlcnNpb24gMi4wLjEgKHNheDJyMikKKyAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI3NldERUREhhbmRsZXIKKyAqLworcHVibGljIGludGVyZmFjZSBEVERIYW5kbGVyIHsKKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBub3RhdGlvbiBkZWNsYXJhdGlvbiBldmVudC4KKyAgICAgKgorICAgICAqIDxwPkl0IGlzIHVwIHRvIHRoZSBhcHBsaWNhdGlvbiB0byByZWNvcmQgdGhlIG5vdGF0aW9uIGZvciBsYXRlcgorICAgICAqIHJlZmVyZW5jZSwgaWYgbmVjZXNzYXJ5OworICAgICAqIG5vdGF0aW9ucyBtYXkgYXBwZWFyIGFzIGF0dHJpYnV0ZSB2YWx1ZXMgYW5kIGluIHVucGFyc2VkIGVudGl0eQorICAgICAqIGRlY2xhcmF0aW9ucywgYW5kIGFyZSBzb21ldGltZSB1c2VkIHdpdGggcHJvY2Vzc2luZyBpbnN0cnVjdGlvbgorICAgICAqIHRhcmdldCBuYW1lcy48L3A+CisgICAgICoKKyAgICAgKiA8cD5BdCBsZWFzdCBvbmUgb2YgcHVibGljSWQgYW5kIHN5c3RlbUlkIG11c3QgYmUgbm9uLW51bGwuCisgICAgICogSWYgYSBzeXN0ZW0gaWRlbnRpZmllciBpcyBwcmVzZW50LCBhbmQgaXQgaXMgYSBVUkwsIHRoZSBTQVgKKyAgICAgKiBwYXJzZXIgbXVzdCByZXNvbHZlIGl0IGZ1bGx5IGJlZm9yZSBwYXNzaW5nIGl0IHRvIHRoZQorICAgICAqIGFwcGxpY2F0aW9uIHRocm91Z2ggdGhpcyBldmVudC48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGVyZSBpcyBubyBndWFyYW50ZWUgdGhhdCB0aGUgbm90YXRpb24gZGVjbGFyYXRpb24gd2lsbCBiZQorICAgICAqIHJlcG9ydGVkIGJlZm9yZSBhbnkgdW5wYXJzZWQgZW50aXRpZXMgdGhhdCB1c2UgaXQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5vdGF0aW9uIG5hbWUuCisgICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBub3RhdGlvbidzIHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsIGlmCisgICAgICogICAgICAgIG5vbmUgd2FzIGdpdmVuLgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgbm90YXRpb24ncyBzeXN0ZW0gaWRlbnRpZmllciwgb3IgbnVsbCBpZgorICAgICAqICAgICAgICBub25lIHdhcyBnaXZlbi4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKKyAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgI3VucGFyc2VkRW50aXR5RGVjbAorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIG5vdGF0aW9uRGVjbCAoU3RyaW5nIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwdWJsaWNJZCwKKyAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkKQorICAgIHRocm93cyBTQVhFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGFuIHVucGFyc2VkIGVudGl0eSBkZWNsYXJhdGlvbiBldmVudC4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB0aGUgbm90YXRpb24gbmFtZSBjb3JyZXNwb25kcyB0byBhIG5vdGF0aW9uCisgICAgICogcmVwb3J0ZWQgYnkgdGhlIHtAbGluayAjbm90YXRpb25EZWNsIG5vdGF0aW9uRGVjbH0gZXZlbnQuCisgICAgICogSXQgaXMgdXAgdG8gdGhlIGFwcGxpY2F0aW9uIHRvIHJlY29yZCB0aGUgZW50aXR5IGZvciBsYXRlcgorICAgICAqIHJlZmVyZW5jZSwgaWYgbmVjZXNzYXJ5OworICAgICAqIHVucGFyc2VkIGVudGl0aWVzIG1heSBhcHBlYXIgYXMgYXR0cmlidXRlIHZhbHVlcy4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwsIHRoZSBwYXJzZXIgbXVzdCByZXNvbHZlIGl0CisgICAgICogZnVsbHkgYmVmb3JlIHBhc3NpbmcgaXQgdG8gdGhlIGFwcGxpY2F0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQHBhcmFtIG5hbWUgVGhlIHVucGFyc2VkIGVudGl0eSdzIG5hbWUuCisgICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBlbnRpdHkncyBwdWJsaWMgaWRlbnRpZmllciwgb3IgbnVsbCBpZiBub25lCisgICAgICogICAgICAgIHdhcyBnaXZlbi4KKyAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIGVudGl0eSdzIHN5c3RlbSBpZGVudGlmaWVyLgorICAgICAqIEBwYXJhbSBub3RhdGlvbk5hbWUgVGhlIG5hbWUgb2YgdGhlIGFzc29jaWF0ZWQgbm90YXRpb24uCisgICAgICogQHNlZSAjbm90YXRpb25EZWNsCisgICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVzCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsIChTdHJpbmcgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHVibGljSWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkLAorICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBub3RhdGlvbk5hbWUpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKKworfQorCisvLyBlbmQgb2YgRFRESGFuZGxlci5qYXZhCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvRG9jdW1lbnRIYW5kbGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvRG9jdW1lbnRIYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzFhZDU0NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9Eb2N1bWVudEhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDIzMyBAQAorLy8gU0FYIGRvY3VtZW50IGhhbmRsZXIuCisvLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCisvLyBObyB3YXJyYW50eTsgbm8gY29weXJpZ2h0IC0tIHVzZSB0aGlzIGFzIHlvdSB3aWxsLgorLy8gJElkOiBEb2N1bWVudEhhbmRsZXIuamF2YSx2IDEuNiAyMDAyLzAxLzMwIDIxOjEzOjQzIGRicm93bmVsbCBFeHAgJAorCitwYWNrYWdlIG9yZy54bWwuc2F4OworCisvKioKKyAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGdlbmVyYWwgZG9jdW1lbnQgZXZlbnRzLgorICoKKyAqIDxibG9ja3F1b3RlPgorICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKKyAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KKyAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgorICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+VGhpcyB3YXMgdGhlIG1haW4gZXZlbnQtaGFuZGxpbmcgaW50ZXJmYWNlIGZvciBTQVgxOyBpbgorICogU0FYMiwgaXQgaGFzIGJlZW4gcmVwbGFjZWQgYnkge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyCisgKiBDb250ZW50SGFuZGxlcn0sIHdoaWNoIHByb3ZpZGVzIE5hbWVzcGFjZSBzdXBwb3J0IGFuZCByZXBvcnRpbmcKKyAqIG9mIHNraXBwZWQgZW50aXRpZXMuICBUaGlzIGludGVyZmFjZSBpcyBpbmNsdWRlZCBpbiBTQVgyIG9ubHkKKyAqIHRvIHN1cHBvcnQgbGVnYWN5IFNBWDEgYXBwbGljYXRpb25zLjwvcD4KKyAqCisgKiA8cD5UaGUgb3JkZXIgb2YgZXZlbnRzIGluIHRoaXMgaW50ZXJmYWNlIGlzIHZlcnkgaW1wb3J0YW50LCBhbmQKKyAqIG1pcnJvcnMgdGhlIG9yZGVyIG9mIGluZm9ybWF0aW9uIGluIHRoZSBkb2N1bWVudCBpdHNlbGYuICBGb3IKKyAqIGV4YW1wbGUsIGFsbCBvZiBhbiBlbGVtZW50J3MgY29udGVudCAoY2hhcmFjdGVyIGRhdGEsIHByb2Nlc3NpbmcKKyAqIGluc3RydWN0aW9ucywgYW5kL29yIHN1YmVsZW1lbnRzKSB3aWxsIGFwcGVhciwgaW4gb3JkZXIsIGJldHdlZW4KKyAqIHRoZSBzdGFydEVsZW1lbnQgZXZlbnQgYW5kIHRoZSBjb3JyZXNwb25kaW5nIGVuZEVsZW1lbnQgZXZlbnQuPC9wPgorICoKKyAqIDxwPkFwcGxpY2F0aW9uIHdyaXRlcnMgd2hvIGRvIG5vdCB3YW50IHRvIGltcGxlbWVudCB0aGUgZW50aXJlCisgKiBpbnRlcmZhY2UgY2FuIGRlcml2ZSBhIGNsYXNzIGZyb20gSGFuZGxlckJhc2UsIHdoaWNoIGltcGxlbWVudHMKKyAqIHRoZSBkZWZhdWx0IGZ1bmN0aW9uYWxpdHk7IHBhcnNlciB3cml0ZXJzIGNhbiBpbnN0YW50aWF0ZQorICogSGFuZGxlckJhc2UgdG8gb2J0YWluIGEgZGVmYXVsdCBoYW5kbGVyLiAgVGhlIGFwcGxpY2F0aW9uIGNhbiBmaW5kCisgKiB0aGUgbG9jYXRpb24gb2YgYW55IGRvY3VtZW50IGV2ZW50IHVzaW5nIHRoZSBMb2NhdG9yIGludGVyZmFjZQorICogc3VwcGxpZWQgYnkgdGhlIFBhcnNlciB0aHJvdWdoIHRoZSBzZXREb2N1bWVudExvY2F0b3IgbWV0aG9kLjwvcD4KKyAqCisgKiBAZGVwcmVjYXRlZCBUaGlzIGludGVyZmFjZSBoYXMgYmVlbiByZXBsYWNlZCBieSB0aGUgU0FYMgorICogICAgICAgICAgICAge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIENvbnRlbnRIYW5kbGVyfQorICogICAgICAgICAgICAgaW50ZXJmYWNlLCB3aGljaCBpbmNsdWRlcyBOYW1lc3BhY2Ugc3VwcG9ydC4KKyAqIEBzaW5jZSBTQVggMS4wCisgKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgorICogQHZlcnNpb24gMi4wLjEgKHNheDJyMikKKyAqIEBzZWUgb3JnLnhtbC5zYXguUGFyc2VyI3NldERvY3VtZW50SGFuZGxlcgorICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yCisgKiBAc2VlIG9yZy54bWwuc2F4LkhhbmRsZXJCYXNlCisgKi8KK0BEZXByZWNhdGVkCitwdWJsaWMgaW50ZXJmYWNlIERvY3VtZW50SGFuZGxlciB7CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgYW4gb2JqZWN0IGZvciBsb2NhdGluZyB0aGUgb3JpZ2luIG9mIFNBWCBkb2N1bWVudCBldmVudHMuCisgICAgICoKKyAgICAgKiA8cD5TQVggcGFyc2VycyBhcmUgc3Ryb25nbHkgZW5jb3VyYWdlZCAodGhvdWdoIG5vdCBhYnNvbHV0ZWx5CisgICAgICogcmVxdWlyZWQpIHRvIHN1cHBseSBhIGxvY2F0b3I6IGlmIGl0IGRvZXMgc28sIGl0IG11c3Qgc3VwcGx5CisgICAgICogdGhlIGxvY2F0b3IgdG8gdGhlIGFwcGxpY2F0aW9uIGJ5IGludm9raW5nIHRoaXMgbWV0aG9kIGJlZm9yZQorICAgICAqIGludm9raW5nIGFueSBvZiB0aGUgb3RoZXIgbWV0aG9kcyBpbiB0aGUgRG9jdW1lbnRIYW5kbGVyCisgICAgICogaW50ZXJmYWNlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBsb2NhdG9yIGFsbG93cyB0aGUgYXBwbGljYXRpb24gdG8gZGV0ZXJtaW5lIHRoZSBlbmQKKyAgICAgKiBwb3NpdGlvbiBvZiBhbnkgZG9jdW1lbnQtcmVsYXRlZCBldmVudCwgZXZlbiBpZiB0aGUgcGFyc2VyIGlzCisgICAgICogbm90IHJlcG9ydGluZyBhbiBlcnJvci4gIFR5cGljYWxseSwgdGhlIGFwcGxpY2F0aW9uIHdpbGwKKyAgICAgKiB1c2UgdGhpcyBpbmZvcm1hdGlvbiBmb3IgcmVwb3J0aW5nIGl0cyBvd24gZXJyb3JzIChzdWNoIGFzCisgICAgICogY2hhcmFjdGVyIGNvbnRlbnQgdGhhdCBkb2VzIG5vdCBtYXRjaCBhbiBhcHBsaWNhdGlvbidzCisgICAgICogYnVzaW5lc3MgcnVsZXMpLiAgVGhlIGluZm9ybWF0aW9uIHJldHVybmVkIGJ5IHRoZSBsb2NhdG9yCisgICAgICogaXMgcHJvYmFibHkgbm90IHN1ZmZpY2llbnQgZm9yIHVzZSB3aXRoIGEgc2VhcmNoIGVuZ2luZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoYXQgdGhlIGxvY2F0b3Igd2lsbCByZXR1cm4gY29ycmVjdCBpbmZvcm1hdGlvbiBvbmx5CisgICAgICogZHVyaW5nIHRoZSBpbnZvY2F0aW9uIG9mIHRoZSBldmVudHMgaW4gdGhpcyBpbnRlcmZhY2UuICBUaGUKKyAgICAgKiBhcHBsaWNhdGlvbiBzaG91bGQgbm90IGF0dGVtcHQgdG8gdXNlIGl0IGF0IGFueSBvdGhlciB0aW1lLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhdG9yIEFuIG9iamVjdCB0aGF0IGNhbiByZXR1cm4gdGhlIGxvY2F0aW9uIG9mCisgICAgICogICAgICAgICAgICAgICAgYW55IFNBWCBkb2N1bWVudCBldmVudC4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXREb2N1bWVudExvY2F0b3IgKExvY2F0b3IgbG9jYXRvcik7CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYSBkb2N1bWVudC4KKyAgICAgKgorICAgICAqIDxwPlRoZSBTQVggcGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIG9ubHkgb25jZSwgYmVmb3JlIGFueQorICAgICAqIG90aGVyIG1ldGhvZHMgaW4gdGhpcyBpbnRlcmZhY2Ugb3IgaW4gRFRESGFuZGxlciAoZXhjZXB0IGZvcgorICAgICAqIHNldERvY3VtZW50TG9jYXRvcikuPC9wPgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzdGFydERvY3VtZW50ICgpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhIGRvY3VtZW50LgorICAgICAqCisgICAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25seSBvbmNlLCBhbmQgaXQgd2lsbAorICAgICAqIGJlIHRoZSBsYXN0IG1ldGhvZCBpbnZva2VkIGR1cmluZyB0aGUgcGFyc2UuICBUaGUgcGFyc2VyIHNoYWxsCisgICAgICogbm90IGludm9rZSB0aGlzIG1ldGhvZCB1bnRpbCBpdCBoYXMgZWl0aGVyIGFiYW5kb25lZCBwYXJzaW5nCisgICAgICogKGJlY2F1c2Ugb2YgYW4gdW5yZWNvdmVyYWJsZSBlcnJvcikgb3IgcmVhY2hlZCB0aGUgZW5kIG9mCisgICAgICogaW5wdXQuPC9wPgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBlbmREb2N1bWVudCAoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYW4gZWxlbWVudC4KKyAgICAgKgorICAgICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2QgYXQgdGhlIGJlZ2lubmluZyBvZiBldmVyeQorICAgICAqIGVsZW1lbnQgaW4gdGhlIFhNTCBkb2N1bWVudDsgdGhlcmUgd2lsbCBiZSBhIGNvcnJlc3BvbmRpbmcKKyAgICAgKiBlbmRFbGVtZW50KCkgZXZlbnQgZm9yIGV2ZXJ5IHN0YXJ0RWxlbWVudCgpIGV2ZW50IChldmVuIHdoZW4gdGhlCisgICAgICogZWxlbWVudCBpcyBlbXB0eSkuIEFsbCBvZiB0aGUgZWxlbWVudCdzIGNvbnRlbnQgd2lsbCBiZQorICAgICAqIHJlcG9ydGVkLCBpbiBvcmRlciwgYmVmb3JlIHRoZSBjb3JyZXNwb25kaW5nIGVuZEVsZW1lbnQoKQorICAgICAqIGV2ZW50LjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBlbGVtZW50IG5hbWUgaGFzIGEgbmFtZXNwYWNlIHByZWZpeCwgdGhlIHByZWZpeCB3aWxsCisgICAgICogc3RpbGwgYmUgYXR0YWNoZWQuICBOb3RlIHRoYXQgdGhlIGF0dHJpYnV0ZSBsaXN0IHByb3ZpZGVkIHdpbGwKKyAgICAgKiBjb250YWluIG9ubHkgYXR0cmlidXRlcyB3aXRoIGV4cGxpY2l0IHZhbHVlcyAoc3BlY2lmaWVkIG9yCisgICAgICogZGVmYXVsdGVkKTogI0lNUExJRUQgYXR0cmlidXRlcyB3aWxsIGJlIG9taXR0ZWQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgdHlwZSBuYW1lLgorICAgICAqIEBwYXJhbSBhdHRzIFRoZSBhdHRyaWJ1dGVzIGF0dGFjaGVkIHRvIHRoZSBlbGVtZW50LCBpZiBhbnkuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlICNlbmRFbGVtZW50CisgICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc3RhcnRFbGVtZW50IChTdHJpbmcgbmFtZSwgQXR0cmlidXRlTGlzdCBhdHRzKQorICAgIHRocm93cyBTQVhFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYW4gZWxlbWVudC4KKyAgICAgKgorICAgICAqIDxwPlRoZSBTQVggcGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIGF0IHRoZSBlbmQgb2YgZXZlcnkKKyAgICAgKiBlbGVtZW50IGluIHRoZSBYTUwgZG9jdW1lbnQ7IHRoZXJlIHdpbGwgYmUgYSBjb3JyZXNwb25kaW5nCisgICAgICogc3RhcnRFbGVtZW50KCkgZXZlbnQgZm9yIGV2ZXJ5IGVuZEVsZW1lbnQoKSBldmVudCAoZXZlbiB3aGVuIHRoZQorICAgICAqIGVsZW1lbnQgaXMgZW1wdHkpLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBlbGVtZW50IG5hbWUgaGFzIGEgbmFtZXNwYWNlIHByZWZpeCwgdGhlIHByZWZpeCB3aWxsCisgICAgICogc3RpbGwgYmUgYXR0YWNoZWQgdG8gdGhlIG5hbWUuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgdHlwZSBuYW1lCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBlbmRFbGVtZW50IChTdHJpbmcgbmFtZSkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjaGFyYWN0ZXIgZGF0YS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBjYWxsIHRoaXMgbWV0aG9kIHRvIHJlcG9ydCBlYWNoIGNodW5rIG9mCisgICAgICogY2hhcmFjdGVyIGRhdGEuICBTQVggcGFyc2VycyBtYXkgcmV0dXJuIGFsbCBjb250aWd1b3VzIGNoYXJhY3RlcgorICAgICAqIGRhdGEgaW4gYSBzaW5nbGUgY2h1bmssIG9yIHRoZXkgbWF5IHNwbGl0IGl0IGludG8gc2V2ZXJhbAorICAgICAqIGNodW5rczsgaG93ZXZlciwgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQKKyAgICAgKiBtdXN0IGNvbWUgZnJvbSB0aGUgc2FtZSBleHRlcm5hbCBlbnRpdHksIHNvIHRoYXQgdGhlIExvY2F0b3IKKyAgICAgKiBwcm92aWRlcyB1c2VmdWwgaW5mb3JtYXRpb24uPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3Qgbm90IGF0dGVtcHQgdG8gcmVhZCBmcm9tIHRoZSBhcnJheQorICAgICAqIG91dHNpZGUgb2YgdGhlIHNwZWNpZmllZCByYW5nZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoYXQgc29tZSBwYXJzZXJzIHdpbGwgcmVwb3J0IHdoaXRlc3BhY2UgdXNpbmcgdGhlCisgICAgICogaWdub3JhYmxlV2hpdGVzcGFjZSgpIG1ldGhvZCByYXRoZXIgdGhhbiB0aGlzIG9uZSAodmFsaWRhdGluZworICAgICAqIHBhcnNlcnMgbXVzdCBkbyBzbykuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KKyAgICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQHNlZSAjaWdub3JhYmxlV2hpdGVzcGFjZQorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGNoYXJhY3RlcnMgKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIGluIGVsZW1lbnQgY29udGVudC4KKyAgICAgKgorICAgICAqIDxwPlZhbGlkYXRpbmcgUGFyc2VycyBtdXN0IHVzZSB0aGlzIG1ldGhvZCB0byByZXBvcnQgZWFjaCBjaHVuaworICAgICAqIG9mIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIChzZWUgdGhlIFczQyBYTUwgMS4wIHJlY29tbWVuZGF0aW9uLAorICAgICAqIHNlY3Rpb24gMi4xMCk6IG5vbi12YWxpZGF0aW5nIHBhcnNlcnMgbWF5IGFsc28gdXNlIHRoaXMgbWV0aG9kCisgICAgICogaWYgdGhleSBhcmUgY2FwYWJsZSBvZiBwYXJzaW5nIGFuZCB1c2luZyBjb250ZW50IG1vZGVscy48L3A+CisgICAgICoKKyAgICAgKiA8cD5TQVggcGFyc2VycyBtYXkgcmV0dXJuIGFsbCBjb250aWd1b3VzIHdoaXRlc3BhY2UgaW4gYSBzaW5nbGUKKyAgICAgKiBjaHVuaywgb3IgdGhleSBtYXkgc3BsaXQgaXQgaW50byBzZXZlcmFsIGNodW5rczsgaG93ZXZlciwgYWxsIG9mCisgICAgICogdGhlIGNoYXJhY3RlcnMgaW4gYW55IHNpbmdsZSBldmVudCBtdXN0IGNvbWUgZnJvbSB0aGUgc2FtZQorICAgICAqIGV4dGVybmFsIGVudGl0eSwgc28gdGhhdCB0aGUgTG9jYXRvciBwcm92aWRlcyB1c2VmdWwKKyAgICAgKiBpbmZvcm1hdGlvbi48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgYXBwbGljYXRpb24gbXVzdCBub3QgYXR0ZW1wdCB0byByZWFkIGZyb20gdGhlIGFycmF5CisgICAgICogb3V0c2lkZSBvZiB0aGUgc3BlY2lmaWVkIHJhbmdlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaCBUaGUgY2hhcmFjdGVycyBmcm9tIHRoZSBYTUwgZG9jdW1lbnQuCisgICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCisgICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKKyAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgI2NoYXJhY3RlcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCisgICAgICoKKyAgICAgKiA8cD5UaGUgUGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIG9uY2UgZm9yIGVhY2ggcHJvY2Vzc2luZworICAgICAqIGluc3RydWN0aW9uIGZvdW5kOiBub3RlIHRoYXQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgbWF5IG9jY3VyCisgICAgICogYmVmb3JlIG9yIGFmdGVyIHRoZSBtYWluIGRvY3VtZW50IGVsZW1lbnQuPC9wPgorICAgICAqCisgICAgICogPHA+QSBTQVggcGFyc2VyIHNob3VsZCBuZXZlciByZXBvcnQgYW4gWE1MIGRlY2xhcmF0aW9uIChYTUwgMS4wLAorICAgICAqIHNlY3Rpb24gMi44KSBvciBhIHRleHQgZGVjbGFyYXRpb24gKFhNTCAxLjAsIHNlY3Rpb24gNC4zLjEpCisgICAgICogdXNpbmcgdGhpcyBtZXRob2QuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHRhcmdldCBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0YXJnZXQuCisgICAgICogQHBhcmFtIGRhdGEgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gZGF0YSwgb3IgbnVsbCBpZgorICAgICAqICAgICAgICBub25lIHdhcyBzdXBwbGllZC4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKKyAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbiAoU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKKworfQorCisvLyBlbmQgb2YgRG9jdW1lbnRIYW5kbGVyLmphdmEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9FbnRpdHlSZXNvbHZlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L0VudGl0eVJlc29sdmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDRlZjhiOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9FbnRpdHlSZXNvbHZlci5qYXZhCkBAIC0wLDAgKzEsMTE5IEBACisvLyBTQVggZW50aXR5IHJlc29sdmVyLgorLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZworLy8gTm8gd2FycmFudHk7IG5vIGNvcHlyaWdodCAtLSB1c2UgdGhpcyBhcyB5b3Ugd2lsbC4KKy8vICRJZDogRW50aXR5UmVzb2x2ZXIuamF2YSx2IDEuMTAgMjAwMi8wMS8zMCAyMToxMzo0NCBkYnJvd25lbGwgRXhwICQKKworcGFja2FnZSBvcmcueG1sLnNheDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKworLyoqCisgKiBCYXNpYyBpbnRlcmZhY2UgZm9yIHJlc29sdmluZyBlbnRpdGllcy4KKyAqCisgKiA8YmxvY2txdW90ZT4KKyAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCisgKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+CisgKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KKyAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgorICogPC9ibG9ja3F1b3RlPgorICoKKyAqIDxwPklmIGEgU0FYIGFwcGxpY2F0aW9uIG5lZWRzIHRvIGltcGxlbWVudCBjdXN0b21pemVkIGhhbmRsaW5nCisgKiBmb3IgZXh0ZXJuYWwgZW50aXRpZXMsIGl0IG11c3QgaW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlIGFuZAorICogcmVnaXN0ZXIgYW4gaW5zdGFuY2Ugd2l0aCB0aGUgU0FYIGRyaXZlciB1c2luZyB0aGUKKyAqIHtAbGluayBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0RW50aXR5UmVzb2x2ZXIgc2V0RW50aXR5UmVzb2x2ZXJ9CisgKiBtZXRob2QuPC9wPgorICoKKyAqIDxwPlRoZSBYTUwgcmVhZGVyIHdpbGwgdGhlbiBhbGxvdyB0aGUgYXBwbGljYXRpb24gdG8gaW50ZXJjZXB0IGFueQorICogZXh0ZXJuYWwgZW50aXRpZXMgKGluY2x1ZGluZyB0aGUgZXh0ZXJuYWwgRFREIHN1YnNldCBhbmQgZXh0ZXJuYWwKKyAqIHBhcmFtZXRlciBlbnRpdGllcywgaWYgYW55KSBiZWZvcmUgaW5jbHVkaW5nIHRoZW0uPC9wPgorICoKKyAqIDxwPk1hbnkgU0FYIGFwcGxpY2F0aW9ucyB3aWxsIG5vdCBuZWVkIHRvIGltcGxlbWVudCB0aGlzIGludGVyZmFjZSwKKyAqIGJ1dCBpdCB3aWxsIGJlIGVzcGVjaWFsbHkgdXNlZnVsIGZvciBhcHBsaWNhdGlvbnMgdGhhdCBidWlsZAorICogWE1MIGRvY3VtZW50cyBmcm9tIGRhdGFiYXNlcyBvciBvdGhlciBzcGVjaWFsaXNlZCBpbnB1dCBzb3VyY2VzLAorICogb3IgZm9yIGFwcGxpY2F0aW9ucyB0aGF0IHVzZSBVUkkgdHlwZXMgb3RoZXIgdGhhbiBVUkxzLjwvcD4KKyAqCisgKiA8cD5UaGUgZm9sbG93aW5nIHJlc29sdmVyIHdvdWxkIHByb3ZpZGUgdGhlIGFwcGxpY2F0aW9uCisgKiB3aXRoIGEgc3BlY2lhbCBjaGFyYWN0ZXIgc3RyZWFtIGZvciB0aGUgZW50aXR5IHdpdGggdGhlIHN5c3RlbQorICogaWRlbnRpZmllciAiaHR0cDovL3d3dy5teWhvc3QuY29tL3RvZGF5Ijo8L3A+CisgKgorICogPHByZT4KKyAqIGltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKKyAqIGltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKKyAqCisgKiBwdWJsaWMgY2xhc3MgTXlSZXNvbHZlciBpbXBsZW1lbnRzIEVudGl0eVJlc29sdmVyIHsKKyAqICAgcHVibGljIElucHV0U291cmNlIHJlc29sdmVFbnRpdHkgKFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQorICogICB7CisgKiAgICAgaWYgKHN5c3RlbUlkLmVxdWFscygiaHR0cDovL3d3dy5teWhvc3QuY29tL3RvZGF5IikpIHsKKyAqICAgICAgICAgICAgICAvLyByZXR1cm4gYSBzcGVjaWFsIGlucHV0IHNvdXJjZQorICogICAgICAgTXlSZWFkZXIgcmVhZGVyID0gbmV3IE15UmVhZGVyKCk7CisgKiAgICAgICByZXR1cm4gbmV3IElucHV0U291cmNlKHJlYWRlcik7CisgKiAgICAgfSBlbHNlIHsKKyAqICAgICAgICAgICAgICAvLyB1c2UgdGhlIGRlZmF1bHQgYmVoYXZpb3VyCisgKiAgICAgICByZXR1cm4gbnVsbDsKKyAqICAgICB9CisgKiAgIH0KKyAqIH0KKyAqIDwvcHJlPgorICoKKyAqIDxwPlRoZSBhcHBsaWNhdGlvbiBjYW4gYWxzbyB1c2UgdGhpcyBpbnRlcmZhY2UgdG8gcmVkaXJlY3Qgc3lzdGVtCisgKiBpZGVudGlmaWVycyB0byBsb2NhbCBVUklzIG9yIHRvIGxvb2sgdXAgcmVwbGFjZW1lbnRzIGluIGEgY2F0YWxvZworICogKHBvc3NpYmx5IGJ5IHVzaW5nIHRoZSBwdWJsaWMgaWRlbnRpZmllcikuPC9wPgorICoKKyAqIEBzaW5jZSBTQVggMS4wCisgKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgorICogQHZlcnNpb24gMi4wLjEgKHNheDJyMikKKyAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI3NldEVudGl0eVJlc29sdmVyCisgKiBAc2VlIG9yZy54bWwuc2F4LklucHV0U291cmNlCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRW50aXR5UmVzb2x2ZXIgeworCisKKyAgICAvKioKKyAgICAgKiBBbGxvdyB0aGUgYXBwbGljYXRpb24gdG8gcmVzb2x2ZSBleHRlcm5hbCBlbnRpdGllcy4KKyAgICAgKgorICAgICAqIDxwPlRoZSBwYXJzZXIgd2lsbCBjYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBvcGVuaW5nIGFueSBleHRlcm5hbAorICAgICAqIGVudGl0eSBleGNlcHQgdGhlIHRvcC1sZXZlbCBkb2N1bWVudCBlbnRpdHkuICBTdWNoIGVudGl0aWVzIGluY2x1ZGUKKyAgICAgKiB0aGUgZXh0ZXJuYWwgRFREIHN1YnNldCBhbmQgZXh0ZXJuYWwgcGFyYW1ldGVyIGVudGl0aWVzIHJlZmVyZW5jZWQKKyAgICAgKiB3aXRoaW4gdGhlIERURCAoaW4gZWl0aGVyIGNhc2UsIG9ubHkgaWYgdGhlIHBhcnNlciByZWFkcyBleHRlcm5hbAorICAgICAqIHBhcmFtZXRlciBlbnRpdGllcyksIGFuZCBleHRlcm5hbCBnZW5lcmFsIGVudGl0aWVzIHJlZmVyZW5jZWQKKyAgICAgKiB3aXRoaW4gdGhlIGRvY3VtZW50IGVsZW1lbnQgKGlmIHRoZSBwYXJzZXIgcmVhZHMgZXh0ZXJuYWwgZ2VuZXJhbAorICAgICAqIGVudGl0aWVzKS4gIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmVxdWVzdCB0aGF0IHRoZSBwYXJzZXIgbG9jYXRlCisgICAgICogdGhlIGVudGl0eSBpdHNlbGYsIHRoYXQgaXQgdXNlIGFuIGFsdGVybmF0aXZlIFVSSSwgb3IgdGhhdCBpdAorICAgICAqIHVzZSBkYXRhIHByb3ZpZGVkIGJ5IHRoZSBhcHBsaWNhdGlvbiAoYXMgYSBjaGFyYWN0ZXIgb3IgYnl0ZQorICAgICAqIGlucHV0IHN0cmVhbSkuPC9wPgorICAgICAqCisgICAgICogPHA+QXBwbGljYXRpb24gd3JpdGVycyBjYW4gdXNlIHRoaXMgbWV0aG9kIHRvIHJlZGlyZWN0IGV4dGVybmFsCisgICAgICogc3lzdGVtIGlkZW50aWZpZXJzIHRvIHNlY3VyZSBhbmQvb3IgbG9jYWwgVVJJcywgdG8gbG9vayB1cAorICAgICAqIHB1YmxpYyBpZGVudGlmaWVycyBpbiBhIGNhdGFsb2d1ZSwgb3IgdG8gcmVhZCBhbiBlbnRpdHkgZnJvbSBhCisgICAgICogZGF0YWJhc2Ugb3Igb3RoZXIgaW5wdXQgc291cmNlIChpbmNsdWRpbmcsIGZvciBleGFtcGxlLCBhIGRpYWxvZworICAgICAqIGJveCkuICBOZWl0aGVyIFhNTCBub3IgU0FYIHNwZWNpZmllcyBhIHByZWZlcnJlZCBwb2xpY3kgZm9yIHVzaW5nCisgICAgICogcHVibGljIG9yIHN5c3RlbSBJRHMgdG8gcmVzb2x2ZSByZXNvdXJjZXMuICBIb3dldmVyLCBTQVggc3BlY2lmaWVzCisgICAgICogaG93IHRvIGludGVycHJldCBhbnkgSW5wdXRTb3VyY2UgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QsIGFuZCB0aGF0CisgICAgICogaWYgbm9uZSBpcyByZXR1cm5lZCwgdGhlbiB0aGUgc3lzdGVtIElEIHdpbGwgYmUgZGVyZWZlcmVuY2VkIGFzCisgICAgICogYSBVUkwuICA8L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwsIHRoZSBTQVggcGFyc2VyIG11c3QKKyAgICAgKiByZXNvbHZlIGl0IGZ1bGx5IGJlZm9yZSByZXBvcnRpbmcgaXQgdG8gdGhlIGFwcGxpY2F0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIGVudGl0eQorICAgICAqICAgICAgICBiZWluZyByZWZlcmVuY2VkLCBvciBudWxsIGlmIG5vbmUgd2FzIHN1cHBsaWVkLgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIGVudGl0eQorICAgICAqICAgICAgICBiZWluZyByZWZlcmVuY2VkLgorICAgICAqIEByZXR1cm4gQW4gSW5wdXRTb3VyY2Ugb2JqZWN0IGRlc2NyaWJpbmcgdGhlIG5ldyBpbnB1dCBzb3VyY2UsCisgICAgICogICAgICAgICBvciBudWxsIHRvIHJlcXVlc3QgdGhhdCB0aGUgcGFyc2VyIG9wZW4gYSByZWd1bGFyCisgICAgICogICAgICAgICBVUkkgY29ubmVjdGlvbiB0byB0aGUgc3lzdGVtIGlkZW50aWZpZXIuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24gQSBKYXZhLXNwZWNpZmljIElPIGV4Y2VwdGlvbiwKKyAgICAgKiAgICAgICAgICAgIHBvc3NpYmx5IHRoZSByZXN1bHQgb2YgY3JlYXRpbmcgYSBuZXcgSW5wdXRTdHJlYW0KKyAgICAgKiAgICAgICAgICAgIG9yIFJlYWRlciBmb3IgdGhlIElucHV0U291cmNlLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eSAoU3RyaW5nIHB1YmxpY0lkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uOworCit9CisKKy8vIGVuZCBvZiBFbnRpdHlSZXNvbHZlci5qYXZhCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvRXJyb3JIYW5kbGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvRXJyb3JIYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzg5OGYwMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9FcnJvckhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDEzOSBAQAorLy8gU0FYIGVycm9yIGhhbmRsZXIuCisvLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCisvLyBObyB3YXJyYW50eTsgbm8gY29weXJpZ2h0IC0tIHVzZSB0aGlzIGFzIHlvdSB3aWxsLgorLy8gJElkOiBFcnJvckhhbmRsZXIuamF2YSx2IDEuMTAgMjAwNC8wMy8wOCAxMzowMTowMCBkbWVnZ2luc29uIEV4cCAkCisKK3BhY2thZ2Ugb3JnLnhtbC5zYXg7CisKKworLyoqCisgKiBCYXNpYyBpbnRlcmZhY2UgZm9yIFNBWCBlcnJvciBoYW5kbGVycy4KKyAqCisgKiA8YmxvY2txdW90ZT4KKyAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCisgKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+CisgKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KKyAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgorICogPC9ibG9ja3F1b3RlPgorICoKKyAqIDxwPklmIGEgU0FYIGFwcGxpY2F0aW9uIG5lZWRzIHRvIGltcGxlbWVudCBjdXN0b21pemVkIGVycm9yCisgKiBoYW5kbGluZywgaXQgbXVzdCBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UgYW5kIHRoZW4gcmVnaXN0ZXIgYW4KKyAqIGluc3RhbmNlIHdpdGggdGhlIFhNTCByZWFkZXIgdXNpbmcgdGhlCisgKiB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyI3NldEVycm9ySGFuZGxlciBzZXRFcnJvckhhbmRsZXJ9CisgKiBtZXRob2QuICBUaGUgcGFyc2VyIHdpbGwgdGhlbiByZXBvcnQgYWxsIGVycm9ycyBhbmQgd2FybmluZ3MKKyAqIHRocm91Z2ggdGhpcyBpbnRlcmZhY2UuPC9wPgorICoKKyAqIDxwPjxzdHJvbmc+V0FSTklORzo8L3N0cm9uZz4gSWYgYW4gYXBwbGljYXRpb24gZG9lcyA8ZW0+bm90PC9lbT4KKyAqIHJlZ2lzdGVyIGFuIEVycm9ySGFuZGxlciwgWE1MIHBhcnNpbmcgZXJyb3JzIHdpbGwgZ28gdW5yZXBvcnRlZCwKKyAqIGV4Y2VwdCB0aGF0IDxlbT5TQVhQYXJzZUV4Y2VwdGlvbjwvZW0+cyB3aWxsIGJlIHRocm93biBmb3IgZmF0YWwgZXJyb3JzLgorICogSW4gb3JkZXIgdG8gZGV0ZWN0IHZhbGlkaXR5IGVycm9ycywgYW4gRXJyb3JIYW5kbGVyIHRoYXQgZG9lcyBzb21ldGhpbmcKKyAqIHdpdGgge0BsaW5rICNlcnJvciBlcnJvcigpfSBjYWxscyBtdXN0IGJlIHJlZ2lzdGVyZWQuPC9wPgorICoKKyAqIDxwPkZvciBYTUwgcHJvY2Vzc2luZyBlcnJvcnMsIGEgU0FYIGRyaXZlciBtdXN0IHVzZSB0aGlzIGludGVyZmFjZQorICogaW4gcHJlZmVyZW5jZSB0byB0aHJvd2luZyBhbiBleGNlcHRpb246IGl0IGlzIHVwIHRvIHRoZSBhcHBsaWNhdGlvbgorICogdG8gZGVjaWRlIHdoZXRoZXIgdG8gdGhyb3cgYW4gZXhjZXB0aW9uIGZvciBkaWZmZXJlbnQgdHlwZXMgb2YKKyAqIGVycm9ycyBhbmQgd2FybmluZ3MuICBOb3RlLCBob3dldmVyLCB0aGF0IHRoZXJlIGlzIG5vIHJlcXVpcmVtZW50IHRoYXQKKyAqIHRoZSBwYXJzZXIgY29udGludWUgdG8gcmVwb3J0IGFkZGl0aW9uYWwgZXJyb3JzIGFmdGVyIGEgY2FsbCB0bworICoge0BsaW5rICNmYXRhbEVycm9yIGZhdGFsRXJyb3J9LiAgSW4gb3RoZXIgd29yZHMsIGEgU0FYIGRyaXZlciBjbGFzcworICogbWF5IHRocm93IGFuIGV4Y2VwdGlvbiBhZnRlciByZXBvcnRpbmcgYW55IGZhdGFsRXJyb3IuCisgKiBBbHNvIHBhcnNlcnMgbWF5IHRocm93IGFwcHJvcHJpYXRlIGV4Y2VwdGlvbnMgZm9yIG5vbi1YTUwgZXJyb3JzLgorICogRm9yIGV4YW1wbGUsIHtAbGluayBYTUxSZWFkZXIjcGFyc2UgWE1MUmVhZGVyLnBhcnNlKCl9IHdvdWxkIHRocm93CisgKiBhbiBJT0V4Y2VwdGlvbiBmb3IgZXJyb3JzIGFjY2Vzc2luZyBlbnRpdGllcyBvciB0aGUgZG9jdW1lbnQuPC9wPgorICoKKyAqIEBzaW5jZSBTQVggMS4wCisgKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgorICogQHZlcnNpb24gMi4wLjErIChzYXgycjNwcmUxKQorICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0RXJyb3JIYW5kbGVyCisgKiBAc2VlIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRXJyb3JIYW5kbGVyIHsKKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSB3YXJuaW5nLgorICAgICAqCisgICAgICogPHA+U0FYIHBhcnNlcnMgd2lsbCB1c2UgdGhpcyBtZXRob2QgdG8gcmVwb3J0IGNvbmRpdGlvbnMgdGhhdAorICAgICAqIGFyZSBub3QgZXJyb3JzIG9yIGZhdGFsIGVycm9ycyBhcyBkZWZpbmVkIGJ5IHRoZSBYTUwKKyAgICAgKiByZWNvbW1lbmRhdGlvbi4gIFRoZSBkZWZhdWx0IGJlaGF2aW91ciBpcyB0byB0YWtlIG5vCisgICAgICogYWN0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBTQVggcGFyc2VyIG11c3QgY29udGludWUgdG8gcHJvdmlkZSBub3JtYWwgcGFyc2luZyBldmVudHMKKyAgICAgKiBhZnRlciBpbnZva2luZyB0aGlzIG1ldGhvZDogaXQgc2hvdWxkIHN0aWxsIGJlIHBvc3NpYmxlIGZvciB0aGUKKyAgICAgKiBhcHBsaWNhdGlvbiB0byBwcm9jZXNzIHRoZSBkb2N1bWVudCB0aHJvdWdoIHRvIHRoZSBlbmQuPC9wPgorICAgICAqCisgICAgICogPHA+RmlsdGVycyBtYXkgdXNlIHRoaXMgbWV0aG9kIHRvIHJlcG9ydCBvdGhlciwgbm9uLVhNTCB3YXJuaW5ncworICAgICAqIGFzIHdlbGwuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGV4Y2VwdGlvbiBUaGUgd2FybmluZyBpbmZvcm1hdGlvbiBlbmNhcHN1bGF0ZWQgaW4gYQorICAgICAqICAgICAgICAgICAgICAgICAgU0FYIHBhcnNlIGV4Y2VwdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKKyAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB3YXJuaW5nIChTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSByZWNvdmVyYWJsZSBlcnJvci4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgY29ycmVzcG9uZHMgdG8gdGhlIGRlZmluaXRpb24gb2YgImVycm9yIiBpbiBzZWN0aW9uIDEuMgorICAgICAqIG9mIHRoZSBXM0MgWE1MIDEuMCBSZWNvbW1lbmRhdGlvbi4gIEZvciBleGFtcGxlLCBhIHZhbGlkYXRpbmcKKyAgICAgKiBwYXJzZXIgd291bGQgdXNlIHRoaXMgY2FsbGJhY2sgdG8gcmVwb3J0IHRoZSB2aW9sYXRpb24gb2YgYQorICAgICAqIHZhbGlkaXR5IGNvbnN0cmFpbnQuICBUaGUgZGVmYXVsdCBiZWhhdmlvdXIgaXMgdG8gdGFrZSBubworICAgICAqIGFjdGlvbi48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgU0FYIHBhcnNlciBtdXN0IGNvbnRpbnVlIHRvIHByb3ZpZGUgbm9ybWFsIHBhcnNpbmcKKyAgICAgKiBldmVudHMgYWZ0ZXIgaW52b2tpbmcgdGhpcyBtZXRob2Q6IGl0IHNob3VsZCBzdGlsbCBiZSBwb3NzaWJsZQorICAgICAqIGZvciB0aGUgYXBwbGljYXRpb24gdG8gcHJvY2VzcyB0aGUgZG9jdW1lbnQgdGhyb3VnaCB0byB0aGUgZW5kLgorICAgICAqIElmIHRoZSBhcHBsaWNhdGlvbiBjYW5ub3QgZG8gc28sIHRoZW4gdGhlIHBhcnNlciBzaG91bGQgcmVwb3J0CisgICAgICogYSBmYXRhbCBlcnJvciBldmVuIGlmIHRoZSBYTUwgcmVjb21tZW5kYXRpb24gZG9lcyBub3QgcmVxdWlyZQorICAgICAqIGl0IHRvIGRvIHNvLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkZpbHRlcnMgbWF5IHVzZSB0aGlzIG1ldGhvZCB0byByZXBvcnQgb3RoZXIsIG5vbi1YTUwgZXJyb3JzCisgICAgICogYXMgd2VsbC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSBlcnJvciBpbmZvcm1hdGlvbiBlbmNhcHN1bGF0ZWQgaW4gYQorICAgICAqICAgICAgICAgICAgICAgICAgU0FYIHBhcnNlIGV4Y2VwdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKKyAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBlcnJvciAoU0FYUGFyc2VFeGNlcHRpb24gZXhjZXB0aW9uKQorICAgIHRocm93cyBTQVhFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgbm9uLXJlY292ZXJhYmxlIGVycm9yLgorICAgICAqCisgICAgICogPHA+PHN0cm9uZz5UaGVyZSBpcyBhbiBhcHBhcmVudCBjb250cmFkaWN0aW9uIGJldHdlZW4gdGhlCisgICAgICogZG9jdW1lbnRhdGlvbiBmb3IgdGhpcyBtZXRob2QgYW5kIHRoZSBkb2N1bWVudGF0aW9uIGZvciB7QGxpbmsKKyAgICAgKiBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmREb2N1bWVudH0uICBVbnRpbCB0aGlzIGFtYmlndWl0eQorICAgICAqIGlzIHJlc29sdmVkIGluIGEgZnV0dXJlIG1ham9yIHJlbGVhc2UsIGNsaWVudHMgc2hvdWxkIG1ha2Ugbm8KKyAgICAgKiBhc3N1bXB0aW9ucyBhYm91dCB3aGV0aGVyIGVuZERvY3VtZW50KCkgd2lsbCBvciB3aWxsIG5vdCBiZQorICAgICAqIGludm9rZWQgd2hlbiB0aGUgcGFyc2VyIGhhcyByZXBvcnRlZCBhIGZhdGFsRXJyb3IoKSBvciB0aHJvd24KKyAgICAgKiBhbiBleGNlcHRpb24uPC9zdHJvbmc+PC9wPgorICAgICAqCisgICAgICogPHA+VGhpcyBjb3JyZXNwb25kcyB0byB0aGUgZGVmaW5pdGlvbiBvZiAiZmF0YWwgZXJyb3IiIGluCisgICAgICogc2VjdGlvbiAxLjIgb2YgdGhlIFczQyBYTUwgMS4wIFJlY29tbWVuZGF0aW9uLiAgRm9yIGV4YW1wbGUsIGEKKyAgICAgKiBwYXJzZXIgd291bGQgdXNlIHRoaXMgY2FsbGJhY2sgdG8gcmVwb3J0IHRoZSB2aW9sYXRpb24gb2YgYQorICAgICAqIHdlbGwtZm9ybWVkbmVzcyBjb25zdHJhaW50LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBhcHBsaWNhdGlvbiBtdXN0IGFzc3VtZSB0aGF0IHRoZSBkb2N1bWVudCBpcyB1bnVzYWJsZQorICAgICAqIGFmdGVyIHRoZSBwYXJzZXIgaGFzIGludm9rZWQgdGhpcyBtZXRob2QsIGFuZCBzaG91bGQgY29udGludWUKKyAgICAgKiAoaWYgYXQgYWxsKSBvbmx5IGZvciB0aGUgc2FrZSBvZiBjb2xsZWN0aW5nIGFkZGl0aW9uYWwgZXJyb3IKKyAgICAgKiBtZXNzYWdlczogaW4gZmFjdCwgU0FYIHBhcnNlcnMgYXJlIGZyZWUgdG8gc3RvcCByZXBvcnRpbmcgYW55CisgICAgICogb3RoZXIgZXZlbnRzIG9uY2UgdGhpcyBtZXRob2QgaGFzIGJlZW4gaW52b2tlZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSBlcnJvciBpbmZvcm1hdGlvbiBlbmNhcHN1bGF0ZWQgaW4gYQorICAgICAqICAgICAgICAgICAgICAgICAgU0FYIHBhcnNlIGV4Y2VwdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKKyAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBmYXRhbEVycm9yIChTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKKworfQorCisvLyBlbmQgb2YgRXJyb3JIYW5kbGVyLmphdmEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9IYW5kbGVyQmFzZS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L0hhbmRsZXJCYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTljM2NmZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9IYW5kbGVyQmFzZS5qYXZhCkBAIC0wLDAgKzEsMzcwIEBACisvLyBTQVggZGVmYXVsdCBoYW5kbGVyIGJhc2UgY2xhc3MuCisvLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCisvLyBObyB3YXJyYW50eTsgbm8gY29weXJpZ2h0IC0tIHVzZSB0aGlzIGFzIHlvdSB3aWxsLgorLy8gJElkOiBIYW5kbGVyQmFzZS5qYXZhLHYgMS43IDIwMDQvMDQvMjYgMTc6MzQ6MzQgZG1lZ2dpbnNvbiBFeHAgJAorCitwYWNrYWdlIG9yZy54bWwuc2F4OworCisvKioKKyAqIERlZmF1bHQgYmFzZSBjbGFzcyBmb3IgaGFuZGxlcnMuCisgKgorICogPGJsb2NrcXVvdGU+CisgKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQorICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgorICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+CisgKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KKyAqIDwvYmxvY2txdW90ZT4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGltcGxlbWVudHMgdGhlIGRlZmF1bHQgYmVoYXZpb3VyIGZvciBmb3VyIFNBWDEKKyAqIGludGVyZmFjZXM6IEVudGl0eVJlc29sdmVyLCBEVERIYW5kbGVyLCBEb2N1bWVudEhhbmRsZXIsCisgKiBhbmQgRXJyb3JIYW5kbGVyLiAgSXQgaXMgbm93IG9ic29sZXRlLCBidXQgaXMgaW5jbHVkZWQgaW4gU0FYMiB0bworICogc3VwcG9ydCBsZWdhY3kgU0FYMSBhcHBsaWNhdGlvbnMuICBTQVgyIGFwcGxpY2F0aW9ucyBzaG91bGQgdXNlCisgKiB0aGUge0BsaW5rIG9yZy54bWwuc2F4LmhlbHBlcnMuRGVmYXVsdEhhbmRsZXIgRGVmYXVsdEhhbmRsZXJ9CisgKiBjbGFzcyBpbnN0ZWFkLjwvcD4KKyAqCisgKiA8cD5BcHBsaWNhdGlvbiB3cml0ZXJzIGNhbiBleHRlbmQgdGhpcyBjbGFzcyB3aGVuIHRoZXkgbmVlZCB0bworICogaW1wbGVtZW50IG9ubHkgcGFydCBvZiBhbiBpbnRlcmZhY2U7IHBhcnNlciB3cml0ZXJzIGNhbgorICogaW5zdGFudGlhdGUgdGhpcyBjbGFzcyB0byBwcm92aWRlIGRlZmF1bHQgaGFuZGxlcnMgd2hlbiB0aGUKKyAqIGFwcGxpY2F0aW9uIGhhcyBub3Qgc3VwcGxpZWQgaXRzIG93bi48L3A+CisgKgorICogPHA+Tm90ZSB0aGF0IHRoZSB1c2Ugb2YgdGhpcyBjbGFzcyBpcyBvcHRpb25hbC48L3A+CisgKgorICogQGRlcHJlY2F0ZWQgVGhpcyBjbGFzcyB3b3JrcyB3aXRoIHRoZSBkZXByZWNhdGVkCisgKiAgICAgICAgICAgICB7QGxpbmsgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyIERvY3VtZW50SGFuZGxlcn0KKyAqICAgICAgICAgICAgIGludGVyZmFjZS4gIEl0IGhhcyBiZWVuIHJlcGxhY2VkIGJ5IHRoZSBTQVgyCisgKiAgICAgICAgICAgICB7QGxpbmsgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlciBEZWZhdWx0SGFuZGxlcn0KKyAqICAgICAgICAgICAgIGNsYXNzLgorICogQHNpbmNlIFNBWCAxLjAKKyAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCisgKiBAdmVyc2lvbiAyLjAuMSAoc2F4MnIyKQorICogQHNlZSBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcgorICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyCisgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcgorICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIKKyAqLworQERlcHJlY2F0ZWQKK3B1YmxpYyBjbGFzcyBIYW5kbGVyQmFzZQorICAgIGltcGxlbWVudHMgRW50aXR5UmVzb2x2ZXIsIERUREhhbmRsZXIsIERvY3VtZW50SGFuZGxlciwgRXJyb3JIYW5kbGVyCit7CisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIERlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIEVudGl0eVJlc29sdmVyIGludGVyZmFjZS4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisgICAgLyoqCisgICAgICogUmVzb2x2ZSBhbiBleHRlcm5hbCBlbnRpdHkuCisgICAgICoKKyAgICAgKiA8cD5BbHdheXMgcmV0dXJuIG51bGwsIHNvIHRoYXQgdGhlIHBhcnNlciB3aWxsIHVzZSB0aGUgc3lzdGVtCisgICAgICogaWRlbnRpZmllciBwcm92aWRlZCBpbiB0aGUgWE1MIGRvY3VtZW50LiAgVGhpcyBtZXRob2QgaW1wbGVtZW50cworICAgICAqIHRoZSBTQVggZGVmYXVsdCBiZWhhdmlvdXI6IGFwcGxpY2F0aW9uIHdyaXRlcnMgY2FuIG92ZXJyaWRlIGl0CisgICAgICogaW4gYSBzdWJjbGFzcyB0byBkbyBzcGVjaWFsIHRyYW5zbGF0aW9ucyBzdWNoIGFzIGNhdGFsb2cgbG9va3VwcworICAgICAqIG9yIFVSSSByZWRpcmVjdGlvbi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmZXIsIG9yIG51bGwgaWYgbm9uZSBpcworICAgICAqICAgICAgICAgICAgICAgICBhdmFpbGFibGUuCisgICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBwcm92aWRlZCBpbiB0aGUgWE1MCisgICAgICogICAgICAgICAgICAgICAgIGRvY3VtZW50LgorICAgICAqIEByZXR1cm4gVGhlIG5ldyBpbnB1dCBzb3VyY2UsIG9yIG51bGwgdG8gcmVxdWlyZSB0aGUKKyAgICAgKiAgICAgICAgIGRlZmF1bHQgYmVoYXZpb3VyLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlciNyZXNvbHZlRW50aXR5CisgICAgICovCisgICAgcHVibGljIElucHV0U291cmNlIHJlc29sdmVFbnRpdHkgKFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIERlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgRFRESGFuZGxlciBpbnRlcmZhY2UuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBub3RhdGlvbiBkZWNsYXJhdGlvbi4KKyAgICAgKgorICAgICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCisgICAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgaWYgdGhleSB3aXNoIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG5vdGF0aW9ucworICAgICAqIGRlY2xhcmVkIGluIGEgZG9jdW1lbnQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5vdGF0aW9uIG5hbWUuCisgICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBub3RhdGlvbiBwdWJsaWMgaWRlbnRpZmllciwgb3IgbnVsbCBpZiBub3QKKyAgICAgKiAgICAgICAgICAgICAgICAgYXZhaWxhYmxlLgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgbm90YXRpb24gc3lzdGVtIGlkZW50aWZpZXIuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyI25vdGF0aW9uRGVjbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbCAoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQorICAgIHsKKyAgICAvLyBubyBvcAorICAgIH0KKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYW4gdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uLgorICAgICAqCisgICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKKyAgICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byBrZWVwIHRyYWNrIG9mIHRoZSB1bnBhcnNlZCBlbnRpdGllcworICAgICAqIGRlY2xhcmVkIGluIGEgZG9jdW1lbnQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIGVudGl0eSBuYW1lLgorICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZW50aXR5IHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsIGlmIG5vdAorICAgICAqICAgICAgICAgICAgICAgICBhdmFpbGFibGUuCisgICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBlbnRpdHkgc3lzdGVtIGlkZW50aWZpZXIuCisgICAgICogQHBhcmFtIG5vdGF0aW9uTmFtZSBUaGUgbmFtZSBvZiB0aGUgYXNzb2NpYXRlZCBub3RhdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIjdW5wYXJzZWRFbnRpdHlEZWNsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsIChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLAorICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc3lzdGVtSWQsIFN0cmluZyBub3RhdGlvbk5hbWUpCisgICAgeworICAgIC8vIG5vIG9wCisgICAgfQorCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIERlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgRG9jdW1lbnRIYW5kbGVyIGludGVyZmFjZS4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlIGEgTG9jYXRvciBvYmplY3QgZm9yIGRvY3VtZW50IGV2ZW50cy4KKyAgICAgKgorICAgICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCisgICAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgaWYgdGhleSB3aXNoIHRvIHN0b3JlIHRoZSBsb2NhdG9yIGZvciB1c2UKKyAgICAgKiB3aXRoIG90aGVyIGRvY3VtZW50IGV2ZW50cy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYXRvciBBIGxvY2F0b3IgZm9yIGFsbCBTQVggZG9jdW1lbnQgZXZlbnRzLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyI3NldERvY3VtZW50TG9jYXRvcgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvciAoTG9jYXRvciBsb2NhdG9yKQorICAgIHsKKyAgICAvLyBubyBvcAorICAgIH0KKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiB0aGUgZG9jdW1lbnQuCisgICAgICoKKyAgICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcworICAgICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBhdCB0aGUgYmVnaW5uaW5nCisgICAgICogb2YgYSBkb2N1bWVudCAoc3VjaCBhcyBhbGxvY2F0aW5nIHRoZSByb290IG5vZGUgb2YgYSB0cmVlIG9yCisgICAgICogY3JlYXRpbmcgYW4gb3V0cHV0IGZpbGUpLjwvcD4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjc3RhcnREb2N1bWVudAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQgKCkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIC8vIG5vIG9wCisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIHRoZSBkb2N1bWVudC4KKyAgICAgKgorICAgICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCisgICAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGF0IHRoZSBiZWdpbm5pbmcKKyAgICAgKiBvZiBhIGRvY3VtZW50IChzdWNoIGFzIGZpbmFsaXNpbmcgYSB0cmVlIG9yIGNsb3NpbmcgYW4gb3V0cHV0CisgICAgICogZmlsZSkuPC9wPgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciNlbmREb2N1bWVudAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50ICgpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICAvLyBubyBvcAorICAgIH0KKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIHN0YXJ0IG9mIGFuIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcworICAgICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBhdCB0aGUgc3RhcnQgb2YKKyAgICAgKiBlYWNoIGVsZW1lbnQgKHN1Y2ggYXMgYWxsb2NhdGluZyBhIG5ldyB0cmVlIG5vZGUgb3Igd3JpdGluZworICAgICAqIG91dHB1dCB0byBhIGZpbGUpLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZS4KKyAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgc3BlY2lmaWVkIG9yIGRlZmF1bHRlZCBhdHRyaWJ1dGVzLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjc3RhcnRFbGVtZW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50IChTdHJpbmcgbmFtZSwgQXR0cmlidXRlTGlzdCBhdHRyaWJ1dGVzKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgLy8gbm8gb3AKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYW4gZWxlbWVudC4KKyAgICAgKgorICAgICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCisgICAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGF0IHRoZSBlbmQgb2YKKyAgICAgKiBlYWNoIGVsZW1lbnQgKHN1Y2ggYXMgZmluYWxpc2luZyBhIHRyZWUgbm9kZSBvciB3cml0aW5nCisgICAgICogb3V0cHV0IHRvIGEgZmlsZSkuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgdGhlIGVsZW1lbnQgbmFtZQorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjZW5kRWxlbWVudAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQgKFN0cmluZyBuYW1lKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgLy8gbm8gb3AKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGNoYXJhY3RlciBkYXRhIGluc2lkZSBhbiBlbGVtZW50LgorICAgICAqCisgICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKKyAgICAgKiBtZXRob2QgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGZvciBlYWNoIGNodW5rIG9mIGNoYXJhY3RlciBkYXRhCisgICAgICogKHN1Y2ggYXMgYWRkaW5nIHRoZSBkYXRhIHRvIGEgbm9kZSBvciBidWZmZXIsIG9yIHByaW50aW5nIGl0IHRvCisgICAgICogYSBmaWxlKS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMuCisgICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgY2hhcmFjdGVyIGFycmF5LgorICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZQorICAgICAqICAgICAgICAgICAgICAgY2hhcmFjdGVyIGFycmF5LgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjY2hhcmFjdGVycworICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMgKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgLy8gbm8gb3AKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIGluIGVsZW1lbnQgY29udGVudC4KKyAgICAgKgorICAgICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCisgICAgICogbWV0aG9kIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBmb3IgZWFjaCBjaHVuayBvZiBpZ25vcmFibGUKKyAgICAgKiB3aGl0ZXNwYWNlIChzdWNoIGFzIGFkZGluZyBkYXRhIHRvIGEgbm9kZSBvciBidWZmZXIsIG9yIHByaW50aW5nCisgICAgICogaXQgdG8gYSBmaWxlKS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2ggVGhlIHdoaXRlc3BhY2UgY2hhcmFjdGVycy4KKyAgICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBjaGFyYWN0ZXIgYXJyYXkuCisgICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlIGZyb20gdGhlCisgICAgICogICAgICAgICAgICAgICBjaGFyYWN0ZXIgYXJyYXkuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciNpZ25vcmFibGVXaGl0ZXNwYWNlCisgICAgICovCisgICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZSAoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICAvLyBubyBvcAorICAgIH0KKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgorICAgICAqCisgICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKKyAgICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgZm9yIGVhY2gKKyAgICAgKiBwcm9jZXNzaW5nIGluc3RydWN0aW9uLCBzdWNoIGFzIHNldHRpbmcgc3RhdHVzIHZhcmlhYmxlcyBvcgorICAgICAqIGludm9raW5nIG90aGVyIG1ldGhvZHMuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHRhcmdldCBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0YXJnZXQuCisgICAgICogQHBhcmFtIGRhdGEgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gZGF0YSwgb3IgbnVsbCBpZgorICAgICAqICAgICAgICAgICAgIG5vbmUgaXMgc3VwcGxpZWQuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgLy8gbm8gb3AKKyAgICB9CisKKworDAorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgRXJyb3JIYW5kbGVyIGludGVyZmFjZS4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHBhcnNlciB3YXJuaW5nLgorICAgICAqCisgICAgICogPHA+VGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZG9lcyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycworICAgICAqIG1heSBvdmVycmlkZSB0aGlzIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucworICAgICAqIGZvciBlYWNoIHdhcm5pbmcsIHN1Y2ggYXMgaW5zZXJ0aW5nIHRoZSBtZXNzYWdlIGluIGEgbG9nIGZpbGUgb3IKKyAgICAgKiBwcmludGluZyBpdCB0byB0aGUgY29uc29sZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZSBUaGUgd2FybmluZyBpbmZvcm1hdGlvbiBlbmNvZGVkIGFzIGFuIGV4Y2VwdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKKyAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyI3dhcm5pbmcKKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd2FybmluZyAoU0FYUGFyc2VFeGNlcHRpb24gZSkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIC8vIG5vIG9wCisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHJlY292ZXJhYmxlIHBhcnNlciBlcnJvci4KKyAgICAgKgorICAgICAqIDxwPlRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMKKyAgICAgKiBtYXkgb3ZlcnJpZGUgdGhpcyBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMKKyAgICAgKiBmb3IgZWFjaCBlcnJvciwgc3VjaCBhcyBpbnNlcnRpbmcgdGhlIG1lc3NhZ2UgaW4gYSBsb2cgZmlsZSBvcgorICAgICAqIHByaW50aW5nIGl0IHRvIHRoZSBjb25zb2xlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIFRoZSB3YXJuaW5nIGluZm9ybWF0aW9uIGVuY29kZWQgYXMgYW4gZXhjZXB0aW9uLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIjd2FybmluZworICAgICAqIEBzZWUgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlcnJvciAoU0FYUGFyc2VFeGNlcHRpb24gZSkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIC8vIG5vIG9wCisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXBvcnQgYSBmYXRhbCBYTUwgcGFyc2luZyBlcnJvci4KKyAgICAgKgorICAgICAqIDxwPlRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHRocm93cyBhIFNBWFBhcnNlRXhjZXB0aW9uLgorICAgICAqIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMgbWV0aG9kIGluIGEgc3ViY2xhc3MgaWYKKyAgICAgKiB0aGV5IG5lZWQgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGZvciBlYWNoIGZhdGFsIGVycm9yIChzdWNoIGFzCisgICAgICogY29sbGVjdGluZyBhbGwgb2YgdGhlIGVycm9ycyBpbnRvIGEgc2luZ2xlIHJlcG9ydCk6IGluIGFueSBjYXNlLAorICAgICAqIHRoZSBhcHBsaWNhdGlvbiBtdXN0IHN0b3AgYWxsIHJlZ3VsYXIgcHJvY2Vzc2luZyB3aGVuIHRoaXMKKyAgICAgKiBtZXRob2QgaXMgaW52b2tlZCwgc2luY2UgdGhlIGRvY3VtZW50IGlzIG5vIGxvbmdlciByZWxpYWJsZSwgYW5kCisgICAgICogdGhlIHBhcnNlciBtYXkgbm8gbG9uZ2VyIHJlcG9ydCBwYXJzaW5nIGV2ZW50cy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZSBUaGUgZXJyb3IgaW5mb3JtYXRpb24gZW5jb2RlZCBhcyBhbiBleGNlcHRpb24uCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciNmYXRhbEVycm9yCisgICAgICogQHNlZSBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IgKFNBWFBhcnNlRXhjZXB0aW9uIGUpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICB0aHJvdyBlOworICAgIH0KKworfQorCisvLyBlbmQgb2YgSGFuZGxlckJhc2UuamF2YQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L0lucHV0U291cmNlLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvSW5wdXRTb3VyY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOWIxNDhlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L0lucHV0U291cmNlLmphdmEKQEAgLTAsMCArMSwzMzcgQEAKKy8vIFNBWCBpbnB1dCBzb3VyY2UuCisvLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCisvLyBObyB3YXJyYW50eTsgbm8gY29weXJpZ2h0IC0tIHVzZSB0aGlzIGFzIHlvdSB3aWxsLgorLy8gJElkOiBJbnB1dFNvdXJjZS5qYXZhLHYgMS45IDIwMDIvMDEvMzAgMjE6MTM6NDUgZGJyb3duZWxsIEV4cCAkCisKK3BhY2thZ2Ugb3JnLnhtbC5zYXg7CisKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUmVhZGVyOworCisvKioKKyAqIEEgc2luZ2xlIGlucHV0IHNvdXJjZSBmb3IgYW4gWE1MIGVudGl0eS4KKyAqCisgKiA8YmxvY2txdW90ZT4KKyAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCisgKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+CisgKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KKyAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgorICogPC9ibG9ja3F1b3RlPgorICoKKyAqIDxwPlRoaXMgY2xhc3MgYWxsb3dzIGEgU0FYIGFwcGxpY2F0aW9uIHRvIGVuY2Fwc3VsYXRlIGluZm9ybWF0aW9uCisgKiBhYm91dCBhbiBpbnB1dCBzb3VyY2UgaW4gYSBzaW5nbGUgb2JqZWN0LCB3aGljaCBtYXkgaW5jbHVkZQorICogYSBwdWJsaWMgaWRlbnRpZmllciwgYSBzeXN0ZW0gaWRlbnRpZmllciwgYSBieXRlIHN0cmVhbSAocG9zc2libHkKKyAqIHdpdGggYSBzcGVjaWZpZWQgZW5jb2RpbmcpLCBhbmQvb3IgYSBjaGFyYWN0ZXIgc3RyZWFtLjwvcD4KKyAqCisgKiA8cD5UaGVyZSBhcmUgdHdvIHBsYWNlcyB0aGF0IHRoZSBhcHBsaWNhdGlvbiBjYW4gZGVsaXZlciBhbgorICogaW5wdXQgc291cmNlIHRvIHRoZSBwYXJzZXI6IGFzIHRoZSBhcmd1bWVudCB0byB0aGUgUGFyc2VyLnBhcnNlCisgKiBtZXRob2QsIG9yIGFzIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIEVudGl0eVJlc29sdmVyLnJlc29sdmVFbnRpdHkKKyAqIG1ldGhvZC48L3A+CisgKgorICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCB1c2UgdGhlIElucHV0U291cmNlIG9iamVjdCB0byBkZXRlcm1pbmUgaG93CisgKiB0byByZWFkIFhNTCBpbnB1dC4gIElmIHRoZXJlIGlzIGEgY2hhcmFjdGVyIHN0cmVhbSBhdmFpbGFibGUsIHRoZQorICogcGFyc2VyIHdpbGwgcmVhZCB0aGF0IHN0cmVhbSBkaXJlY3RseSwgZGlzcmVnYXJkaW5nIGFueSB0ZXh0CisgKiBlbmNvZGluZyBkZWNsYXJhdGlvbiBmb3VuZCBpbiB0aGF0IHN0cmVhbS4KKyAqIElmIHRoZXJlIGlzIG5vIGNoYXJhY3RlciBzdHJlYW0sIGJ1dCB0aGVyZSBpcworICogYSBieXRlIHN0cmVhbSwgdGhlIHBhcnNlciB3aWxsIHVzZSB0aGF0IGJ5dGUgc3RyZWFtLCB1c2luZyB0aGUKKyAqIGVuY29kaW5nIHNwZWNpZmllZCBpbiB0aGUgSW5wdXRTb3VyY2Ugb3IgZWxzZSAoaWYgbm8gZW5jb2RpbmcgaXMKKyAqIHNwZWNpZmllZCkgYXV0b2RldGVjdGluZyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIHVzaW5nIGFuIGFsZ29yaXRobQorICogc3VjaCBhcyB0aGUgb25lIGluIHRoZSBYTUwgc3BlY2lmaWNhdGlvbi4gIElmIG5laXRoZXIgYSBjaGFyYWN0ZXIKKyAqIHN0cmVhbSBub3IgYQorICogYnl0ZSBzdHJlYW0gaXMgYXZhaWxhYmxlLCB0aGUgcGFyc2VyIHdpbGwgYXR0ZW1wdCB0byBvcGVuIGEgVVJJCisgKiBjb25uZWN0aW9uIHRvIHRoZSByZXNvdXJjZSBpZGVudGlmaWVkIGJ5IHRoZSBzeXN0ZW0KKyAqIGlkZW50aWZpZXIuPC9wPgorICoKKyAqIDxwPkFuIElucHV0U291cmNlIG9iamVjdCBiZWxvbmdzIHRvIHRoZSBhcHBsaWNhdGlvbjogdGhlIFNBWCBwYXJzZXIKKyAqIHNoYWxsIG5ldmVyIG1vZGlmeSBpdCBpbiBhbnkgd2F5IChpdCBtYXkgbW9kaWZ5IGEgY29weSBpZgorICogbmVjZXNzYXJ5KS4gIEhvd2V2ZXIsIHN0YW5kYXJkIHByb2Nlc3Npbmcgb2YgYm90aCBieXRlIGFuZAorICogY2hhcmFjdGVyIHN0cmVhbXMgaXMgdG8gY2xvc2UgdGhlbSBvbiBhcyBwYXJ0IG9mIGVuZC1vZi1wYXJzZSBjbGVhbnVwLAorICogc28gYXBwbGljYXRpb25zIHNob3VsZCBub3QgYXR0ZW1wdCB0byByZS11c2Ugc3VjaCBzdHJlYW1zIGFmdGVyIHRoZXkKKyAqIGhhdmUgYmVlbiBoYW5kZWQgdG8gYSBwYXJzZXIuICA8L3A+CisgKgorICogQHNpbmNlIFNBWCAxLjAKKyAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCisgKiBAdmVyc2lvbiAyLjAuMSAoc2F4MnIyKQorICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjcGFyc2Uob3JnLnhtbC5zYXguSW5wdXRTb3VyY2UpCisgKiBAc2VlIG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyI3Jlc29sdmVFbnRpdHkKKyAqIEBzZWUgamF2YS5pby5JbnB1dFN0cmVhbQorICogQHNlZSBqYXZhLmlvLlJlYWRlcgorICovCitwdWJsaWMgY2xhc3MgSW5wdXRTb3VyY2UgeworCisgICAgLyoqCisgICAgICogWmVyby1hcmd1bWVudCBkZWZhdWx0IGNvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHNlZSAjc2V0UHVibGljSWQKKyAgICAgKiBAc2VlICNzZXRTeXN0ZW1JZAorICAgICAqIEBzZWUgI3NldEJ5dGVTdHJlYW0KKyAgICAgKiBAc2VlICNzZXRDaGFyYWN0ZXJTdHJlYW0KKyAgICAgKiBAc2VlICNzZXRFbmNvZGluZworICAgICAqLworICAgIHB1YmxpYyBJbnB1dFNvdXJjZSAoKQorICAgIHsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBpbnB1dCBzb3VyY2Ugd2l0aCBhIHN5c3RlbSBpZGVudGlmaWVyLgorICAgICAqCisgICAgICogPHA+QXBwbGljYXRpb25zIG1heSB1c2Ugc2V0UHVibGljSWQgdG8gaW5jbHVkZSBhCisgICAgICogcHVibGljIGlkZW50aWZpZXIgYXMgd2VsbCwgb3Igc2V0RW5jb2RpbmcgdG8gc3BlY2lmeQorICAgICAqIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcsIGlmIGtub3duLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBhIFVSTCwgaXQgbXVzdCBiZSBmdWxseQorICAgICAqIHJlc29sdmVkIChpdCBtYXkgbm90IGJlIGEgcmVsYXRpdmUgVVJMKS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIChVUkkpLgorICAgICAqIEBzZWUgI3NldFB1YmxpY0lkCisgICAgICogQHNlZSAjc2V0U3lzdGVtSWQKKyAgICAgKiBAc2VlICNzZXRCeXRlU3RyZWFtCisgICAgICogQHNlZSAjc2V0RW5jb2RpbmcKKyAgICAgKiBAc2VlICNzZXRDaGFyYWN0ZXJTdHJlYW0KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTb3VyY2UgKFN0cmluZyBzeXN0ZW1JZCkKKyAgICB7CisgICAgc2V0U3lzdGVtSWQoc3lzdGVtSWQpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IGlucHV0IHNvdXJjZSB3aXRoIGEgYnl0ZSBzdHJlYW0uCisgICAgICoKKyAgICAgKiA8cD5BcHBsaWNhdGlvbiB3cml0ZXJzIHNob3VsZCB1c2Ugc2V0U3lzdGVtSWQoKSB0byBwcm92aWRlIGEgYmFzZQorICAgICAqIGZvciByZXNvbHZpbmcgcmVsYXRpdmUgVVJJcywgbWF5IHVzZSBzZXRQdWJsaWNJZCB0byBpbmNsdWRlIGEKKyAgICAgKiBwdWJsaWMgaWRlbnRpZmllciwgYW5kIG1heSB1c2Ugc2V0RW5jb2RpbmcgdG8gc3BlY2lmeSB0aGUgb2JqZWN0J3MKKyAgICAgKiBjaGFyYWN0ZXIgZW5jb2RpbmcuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGJ5dGVTdHJlYW0gVGhlIHJhdyBieXRlIHN0cmVhbSBjb250YWluaW5nIHRoZSBkb2N1bWVudC4KKyAgICAgKiBAc2VlICNzZXRQdWJsaWNJZAorICAgICAqIEBzZWUgI3NldFN5c3RlbUlkCisgICAgICogQHNlZSAjc2V0RW5jb2RpbmcKKyAgICAgKiBAc2VlICNzZXRCeXRlU3RyZWFtCisgICAgICogQHNlZSAjc2V0Q2hhcmFjdGVyU3RyZWFtCisgICAgICovCisgICAgcHVibGljIElucHV0U291cmNlIChJbnB1dFN0cmVhbSBieXRlU3RyZWFtKQorICAgIHsKKyAgICBzZXRCeXRlU3RyZWFtKGJ5dGVTdHJlYW0pOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IGlucHV0IHNvdXJjZSB3aXRoIGEgY2hhcmFjdGVyIHN0cmVhbS4KKyAgICAgKgorICAgICAqIDxwPkFwcGxpY2F0aW9uIHdyaXRlcnMgc2hvdWxkIHVzZSBzZXRTeXN0ZW1JZCgpIHRvIHByb3ZpZGUgYSBiYXNlCisgICAgICogZm9yIHJlc29sdmluZyByZWxhdGl2ZSBVUklzLCBhbmQgbWF5IHVzZSBzZXRQdWJsaWNJZCB0byBpbmNsdWRlIGEKKyAgICAgKiBwdWJsaWMgaWRlbnRpZmllci48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgY2hhcmFjdGVyIHN0cmVhbSBzaGFsbCBub3QgaW5jbHVkZSBhIGJ5dGUgb3JkZXIgbWFyay48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhcmFjdGVyU3RyZWFtIFRoZSByYXcgY2hhcmFjdGVyIHN0cmVhbSBjb250YWluaW5nIHRoZSBkb2N1bWVudC4KKyAgICAgKiBAc2VlICNzZXRQdWJsaWNJZAorICAgICAqIEBzZWUgI3NldFN5c3RlbUlkCisgICAgICogQHNlZSAjc2V0Qnl0ZVN0cmVhbQorICAgICAqIEBzZWUgI3NldENoYXJhY3RlclN0cmVhbQorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFNvdXJjZSAoUmVhZGVyIGNoYXJhY3RlclN0cmVhbSkKKyAgICB7CisgICAgc2V0Q2hhcmFjdGVyU3RyZWFtKGNoYXJhY3RlclN0cmVhbSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHB1YmxpYyBpZGVudGlmaWVyIGZvciB0aGlzIGlucHV0IHNvdXJjZS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBwdWJsaWMgaWRlbnRpZmllciBpcyBhbHdheXMgb3B0aW9uYWw6IGlmIHRoZSBhcHBsaWNhdGlvbgorICAgICAqIHdyaXRlciBpbmNsdWRlcyBvbmUsIGl0IHdpbGwgYmUgcHJvdmlkZWQgYXMgcGFydCBvZiB0aGUKKyAgICAgKiBsb2NhdGlvbiBpbmZvcm1hdGlvbi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmaWVyIGFzIGEgc3RyaW5nLgorICAgICAqIEBzZWUgI2dldFB1YmxpY0lkCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yI2dldFB1YmxpY0lkCisgICAgICogQHNlZSBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbiNnZXRQdWJsaWNJZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFB1YmxpY0lkIChTdHJpbmcgcHVibGljSWQpCisgICAgeworICAgIHRoaXMucHVibGljSWQgPSBwdWJsaWNJZDsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoaXMgaW5wdXQgc291cmNlLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgcHVibGljIGlkZW50aWZpZXIsIG9yIG51bGwgaWYgbm9uZSB3YXMgc3VwcGxpZWQuCisgICAgICogQHNlZSAjc2V0UHVibGljSWQKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkICgpCisgICAgeworICAgIHJldHVybiBwdWJsaWNJZDsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoaXMgaW5wdXQgc291cmNlLgorICAgICAqCisgICAgICogPHA+VGhlIHN5c3RlbSBpZGVudGlmaWVyIGlzIG9wdGlvbmFsIGlmIHRoZXJlIGlzIGEgYnl0ZSBzdHJlYW0KKyAgICAgKiBvciBhIGNoYXJhY3RlciBzdHJlYW0sIGJ1dCBpdCBpcyBzdGlsbCB1c2VmdWwgdG8gcHJvdmlkZSBvbmUsCisgICAgICogc2luY2UgdGhlIGFwcGxpY2F0aW9uIGNhbiB1c2UgaXQgdG8gcmVzb2x2ZSByZWxhdGl2ZSBVUklzCisgICAgICogYW5kIGNhbiBpbmNsdWRlIGl0IGluIGVycm9yIG1lc3NhZ2VzIGFuZCB3YXJuaW5ncyAodGhlIHBhcnNlcgorICAgICAqIHdpbGwgYXR0ZW1wdCB0byBvcGVuIGEgY29ubmVjdGlvbiB0byB0aGUgVVJJIG9ubHkgaWYKKyAgICAgKiB0aGVyZSBpcyBubyBieXRlIHN0cmVhbSBvciBjaGFyYWN0ZXIgc3RyZWFtIHNwZWNpZmllZCkuPC9wPgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIGtub3dzIHRoZSBjaGFyYWN0ZXIgZW5jb2Rpbmcgb2YgdGhlCisgICAgICogb2JqZWN0IHBvaW50ZWQgdG8gYnkgdGhlIHN5c3RlbSBpZGVudGlmaWVyLCBpdCBjYW4gcmVnaXN0ZXIKKyAgICAgKiB0aGUgZW5jb2RpbmcgdXNpbmcgdGhlIHNldEVuY29kaW5nIG1ldGhvZC48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwsIGl0IG11c3QgYmUgZnVsbHkKKyAgICAgKiByZXNvbHZlZCAoaXQgbWF5IG5vdCBiZSBhIHJlbGF0aXZlIFVSTCkuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBhcyBhIHN0cmluZy4KKyAgICAgKiBAc2VlICNzZXRFbmNvZGluZworICAgICAqIEBzZWUgI2dldFN5c3RlbUlkCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yI2dldFN5c3RlbUlkCisgICAgICogQHNlZSBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbiNnZXRTeXN0ZW1JZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkIChTdHJpbmcgc3lzdGVtSWQpCisgICAgeworICAgIHRoaXMuc3lzdGVtSWQgPSBzeXN0ZW1JZDsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoaXMgaW5wdXQgc291cmNlLgorICAgICAqCisgICAgICogPHA+VGhlIGdldEVuY29kaW5nIG1ldGhvZCB3aWxsIHJldHVybiB0aGUgY2hhcmFjdGVyIGVuY29kaW5nCisgICAgICogb2YgdGhlIG9iamVjdCBwb2ludGVkIHRvLCBvciBudWxsIGlmIHVua25vd24uPC9wPgorICAgICAqCisgICAgICogPHA+SWYgdGhlIHN5c3RlbSBJRCBpcyBhIFVSTCwgaXQgd2lsbCBiZSBmdWxseSByZXNvbHZlZC48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllciwgb3IgbnVsbCBpZiBub25lIHdhcyBzdXBwbGllZC4KKyAgICAgKiBAc2VlICNzZXRTeXN0ZW1JZAorICAgICAqIEBzZWUgI2dldEVuY29kaW5nCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCAoKQorICAgIHsKKyAgICByZXR1cm4gc3lzdGVtSWQ7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGJ5dGUgc3RyZWFtIGZvciB0aGlzIGlucHV0IHNvdXJjZS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBTQVggcGFyc2VyIHdpbGwgaWdub3JlIHRoaXMgaWYgdGhlcmUgaXMgYWxzbyBhIGNoYXJhY3RlcgorICAgICAqIHN0cmVhbSBzcGVjaWZpZWQsIGJ1dCBpdCB3aWxsIHVzZSBhIGJ5dGUgc3RyZWFtIGluIHByZWZlcmVuY2UKKyAgICAgKiB0byBvcGVuaW5nIGEgVVJJIGNvbm5lY3Rpb24gaXRzZWxmLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBhcHBsaWNhdGlvbiBrbm93cyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIG9mIHRoZQorICAgICAqIGJ5dGUgc3RyZWFtLCBpdCBzaG91bGQgc2V0IGl0IHdpdGggdGhlIHNldEVuY29kaW5nIG1ldGhvZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gYnl0ZVN0cmVhbSBBIGJ5dGUgc3RyZWFtIGNvbnRhaW5pbmcgYW4gWE1MIGRvY3VtZW50IG9yCisgICAgICogICAgICAgIG90aGVyIGVudGl0eS4KKyAgICAgKiBAc2VlICNzZXRFbmNvZGluZworICAgICAqIEBzZWUgI2dldEJ5dGVTdHJlYW0KKyAgICAgKiBAc2VlICNnZXRFbmNvZGluZworICAgICAqIEBzZWUgamF2YS5pby5JbnB1dFN0cmVhbQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJ5dGVTdHJlYW0gKElucHV0U3RyZWFtIGJ5dGVTdHJlYW0pCisgICAgeworICAgIHRoaXMuYnl0ZVN0cmVhbSA9IGJ5dGVTdHJlYW07CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGJ5dGUgc3RyZWFtIGZvciB0aGlzIGlucHV0IHNvdXJjZS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBnZXRFbmNvZGluZyBtZXRob2Qgd2lsbCByZXR1cm4gdGhlIGNoYXJhY3RlcgorICAgICAqIGVuY29kaW5nIGZvciB0aGlzIGJ5dGUgc3RyZWFtLCBvciBudWxsIGlmIHVua25vd24uPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgYnl0ZSBzdHJlYW0sIG9yIG51bGwgaWYgbm9uZSB3YXMgc3VwcGxpZWQuCisgICAgICogQHNlZSAjZ2V0RW5jb2RpbmcKKyAgICAgKiBAc2VlICNzZXRCeXRlU3RyZWFtCisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldEJ5dGVTdHJlYW0gKCkKKyAgICB7CisgICAgcmV0dXJuIGJ5dGVTdHJlYW07CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGNoYXJhY3RlciBlbmNvZGluZywgaWYga25vd24uCisgICAgICoKKyAgICAgKiA8cD5UaGUgZW5jb2RpbmcgbXVzdCBiZSBhIHN0cmluZyBhY2NlcHRhYmxlIGZvciBhbgorICAgICAqIFhNTCBlbmNvZGluZyBkZWNsYXJhdGlvbiAoc2VlIHNlY3Rpb24gNC4zLjMgb2YgdGhlIFhNTCAxLjAKKyAgICAgKiByZWNvbW1lbmRhdGlvbikuPC9wPgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaGFzIG5vIGVmZmVjdCB3aGVuIHRoZSBhcHBsaWNhdGlvbiBwcm92aWRlcyBhCisgICAgICogY2hhcmFjdGVyIHN0cmVhbS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcgQSBzdHJpbmcgZGVzY3JpYmluZyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nLgorICAgICAqIEBzZWUgI3NldFN5c3RlbUlkCisgICAgICogQHNlZSAjc2V0Qnl0ZVN0cmVhbQorICAgICAqIEBzZWUgI2dldEVuY29kaW5nCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RW5jb2RpbmcgKFN0cmluZyBlbmNvZGluZykKKyAgICB7CisgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgIH0KKworCisgICAgLyoqCisgICAgICogR2V0IHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgZm9yIGEgYnl0ZSBzdHJlYW0gb3IgVVJJLgorICAgICAqIFRoaXMgdmFsdWUgd2lsbCBiZSBpZ25vcmVkIHdoZW4gdGhlIGFwcGxpY2F0aW9uIHByb3ZpZGVzIGEKKyAgICAgKiBjaGFyYWN0ZXIgc3RyZWFtLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgZW5jb2RpbmcsIG9yIG51bGwgaWYgbm9uZSB3YXMgc3VwcGxpZWQuCisgICAgICogQHNlZSAjc2V0Qnl0ZVN0cmVhbQorICAgICAqIEBzZWUgI2dldFN5c3RlbUlkCisgICAgICogQHNlZSAjZ2V0Qnl0ZVN0cmVhbQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcgKCkKKyAgICB7CisgICAgcmV0dXJuIGVuY29kaW5nOworICAgIH0KKworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBjaGFyYWN0ZXIgc3RyZWFtIGZvciB0aGlzIGlucHV0IHNvdXJjZS4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZXJlIGlzIGEgY2hhcmFjdGVyIHN0cmVhbSBzcGVjaWZpZWQsIHRoZSBTQVggcGFyc2VyCisgICAgICogd2lsbCBpZ25vcmUgYW55IGJ5dGUgc3RyZWFtIGFuZCB3aWxsIG5vdCBhdHRlbXB0IHRvIG9wZW4KKyAgICAgKiBhIFVSSSBjb25uZWN0aW9uIHRvIHRoZSBzeXN0ZW0gaWRlbnRpZmllci48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhcmFjdGVyU3RyZWFtIFRoZSBjaGFyYWN0ZXIgc3RyZWFtIGNvbnRhaW5pbmcgdGhlCisgICAgICogICAgICAgIFhNTCBkb2N1bWVudCBvciBvdGhlciBlbnRpdHkuCisgICAgICogQHNlZSAjZ2V0Q2hhcmFjdGVyU3RyZWFtCisgICAgICogQHNlZSBqYXZhLmlvLlJlYWRlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENoYXJhY3RlclN0cmVhbSAoUmVhZGVyIGNoYXJhY3RlclN0cmVhbSkKKyAgICB7CisgICAgdGhpcy5jaGFyYWN0ZXJTdHJlYW0gPSBjaGFyYWN0ZXJTdHJlYW07CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGNoYXJhY3RlciBzdHJlYW0gZm9yIHRoaXMgaW5wdXQgc291cmNlLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgY2hhcmFjdGVyIHN0cmVhbSwgb3IgbnVsbCBpZiBub25lIHdhcyBzdXBwbGllZC4KKyAgICAgKiBAc2VlICNzZXRDaGFyYWN0ZXJTdHJlYW0KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVhZGVyIGdldENoYXJhY3RlclN0cmVhbSAoKQorICAgIHsKKyAgICByZXR1cm4gY2hhcmFjdGVyU3RyZWFtOworICAgIH0KKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBJbnRlcm5hbCBzdGF0ZS4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisgICAgcHJpdmF0ZSBTdHJpbmcgcHVibGljSWQ7CisgICAgcHJpdmF0ZSBTdHJpbmcgc3lzdGVtSWQ7CisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBieXRlU3RyZWFtOworICAgIHByaXZhdGUgU3RyaW5nIGVuY29kaW5nOworICAgIHByaXZhdGUgUmVhZGVyIGNoYXJhY3RlclN0cmVhbTsKKworfQorCisvLyBlbmQgb2YgSW5wdXRTb3VyY2UuamF2YQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L0xvY2F0b3IuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9Mb2NhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWNjZmU1MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9Mb2NhdG9yLmphdmEKQEAgLTAsMCArMSwxMzYgQEAKKy8vIFNBWCBsb2NhdG9yIGludGVyZmFjZSBmb3IgZG9jdW1lbnQgZXZlbnRzLgorLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZworLy8gTm8gd2FycmFudHk7IG5vIGNvcHlyaWdodCAtLSB1c2UgdGhpcyBhcyB5b3Ugd2lsbC4KKy8vICRJZDogTG9jYXRvci5qYXZhLHYgMS44IDIwMDIvMDEvMzAgMjE6MTM6NDcgZGJyb3duZWxsIEV4cCAkCisKK3BhY2thZ2Ugb3JnLnhtbC5zYXg7CisKKworLyoqCisgKiBJbnRlcmZhY2UgZm9yIGFzc29jaWF0aW5nIGEgU0FYIGV2ZW50IHdpdGggYSBkb2N1bWVudCBsb2NhdGlvbi4KKyAqCisgKiA8YmxvY2txdW90ZT4KKyAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCisgKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+CisgKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KKyAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgorICogPC9ibG9ja3F1b3RlPgorICoKKyAqIDxwPklmIGEgU0FYIHBhcnNlciBwcm92aWRlcyBsb2NhdGlvbiBpbmZvcm1hdGlvbiB0byB0aGUgU0FYCisgKiBhcHBsaWNhdGlvbiwgaXQgZG9lcyBzbyBieSBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2UgYW5kIHRoZW4KKyAqIHBhc3NpbmcgYW4gaW5zdGFuY2UgdG8gdGhlIGFwcGxpY2F0aW9uIHVzaW5nIHRoZSBjb250ZW50CisgKiBoYW5kbGVyJ3Mge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3NldERvY3VtZW50TG9jYXRvcgorICogc2V0RG9jdW1lbnRMb2NhdG9yfSBtZXRob2QuICBUaGUgYXBwbGljYXRpb24gY2FuIHVzZSB0aGUKKyAqIG9iamVjdCB0byBvYnRhaW4gdGhlIGxvY2F0aW9uIG9mIGFueSBvdGhlciBTQVggZXZlbnQKKyAqIGluIHRoZSBYTUwgc291cmNlIGRvY3VtZW50LjwvcD4KKyAqCisgKiA8cD5Ob3RlIHRoYXQgdGhlIHJlc3VsdHMgcmV0dXJuZWQgYnkgdGhlIG9iamVjdCB3aWxsIGJlIHZhbGlkIG9ubHkKKyAqIGR1cmluZyB0aGUgc2NvcGUgb2YgZWFjaCBjYWxsYmFjayBtZXRob2Q6IHRoZSBhcHBsaWNhdGlvbgorICogd2lsbCByZWNlaXZlIHVucHJlZGljdGFibGUgcmVzdWx0cyBpZiBpdCBhdHRlbXB0cyB0byB1c2UgdGhlCisgKiBsb2NhdG9yIGF0IGFueSBvdGhlciB0aW1lLCBvciBhZnRlciBwYXJzaW5nIGNvbXBsZXRlcy48L3A+CisgKgorICogPHA+U0FYIHBhcnNlcnMgYXJlIG5vdCByZXF1aXJlZCB0byBzdXBwbHkgYSBsb2NhdG9yLCBidXQgdGhleSBhcmUKKyAqIHZlcnkgc3Ryb25nbHkgZW5jb3VyYWdlZCB0byBkbyBzby4gIElmIHRoZSBwYXJzZXIgc3VwcGxpZXMgYQorICogbG9jYXRvciwgaXQgbXVzdCBkbyBzbyBiZWZvcmUgcmVwb3J0aW5nIGFueSBvdGhlciBkb2N1bWVudCBldmVudHMuCisgKiBJZiBubyBsb2NhdG9yIGhhcyBiZWVuIHNldCBieSB0aGUgdGltZSB0aGUgYXBwbGljYXRpb24gcmVjZWl2ZXMKKyAqIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnREb2N1bWVudCBzdGFydERvY3VtZW50fQorICogZXZlbnQsIHRoZSBhcHBsaWNhdGlvbiBzaG91bGQgYXNzdW1lIHRoYXQgYSBsb2NhdG9yIGlzIG5vdAorICogYXZhaWxhYmxlLjwvcD4KKyAqCisgKiBAc2luY2UgU0FYIDEuMAorICogQGF1dGhvciBEYXZpZCBNZWdnaW5zb24KKyAqIEB2ZXJzaW9uIDIuMC4xIChzYXgycjIpCisgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3NldERvY3VtZW50TG9jYXRvcgorICovCitwdWJsaWMgaW50ZXJmYWNlIExvY2F0b3IgeworCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHB1YmxpYyBpZGVudGlmaWVyIGZvciB0aGUgY3VycmVudCBkb2N1bWVudCBldmVudC4KKyAgICAgKgorICAgICAqIDxwPlRoZSByZXR1cm4gdmFsdWUgaXMgdGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBkb2N1bWVudAorICAgICAqIGVudGl0eSBvciBvZiB0aGUgZXh0ZXJuYWwgcGFyc2VkIGVudGl0eSBpbiB3aGljaCB0aGUgbWFya3VwCisgICAgICogdHJpZ2dlcmluZyB0aGUgZXZlbnQgYXBwZWFycy48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHB1YmxpYyBpZGVudGlmaWVyLCBvcgorICAgICAqICAgICAgICAgbnVsbCBpZiBub25lIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBAc2VlICNnZXRTeXN0ZW1JZAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0UHVibGljSWQgKCk7CisKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50LgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGRvY3VtZW50CisgICAgICogZW50aXR5IG9yIG9mIHRoZSBleHRlcm5hbCBwYXJzZWQgZW50aXR5IGluIHdoaWNoIHRoZSBtYXJrdXAKKyAgICAgKiB0cmlnZ2VyaW5nIHRoZSBldmVudCBhcHBlYXJzLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBhIFVSTCwgdGhlIHBhcnNlciBtdXN0IHJlc29sdmUgaXQKKyAgICAgKiBmdWxseSBiZWZvcmUgcGFzc2luZyBpdCB0byB0aGUgYXBwbGljYXRpb24uICBGb3IgZXhhbXBsZSwgYSBmaWxlCisgICAgICogbmFtZSBtdXN0IGFsd2F5cyBiZSBwcm92aWRlZCBhcyBhIDxlbT5maWxlOi4uLjwvZW0+IFVSTCwgYW5kIG90aGVyCisgICAgICoga2luZHMgb2YgcmVsYXRpdmUgVVJJIGFyZSBhbHNvIHJlc29sdmVkIGFnYWluc3QgdGhlaXIgYmFzZXMuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBBIHN0cmluZyBjb250YWluaW5nIHRoZSBzeXN0ZW0gaWRlbnRpZmllciwgb3IgbnVsbAorICAgICAqICAgICAgICAgaWYgbm9uZSBpcyBhdmFpbGFibGUuCisgICAgICogQHNlZSAjZ2V0UHVibGljSWQKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFN5c3RlbUlkICgpOworCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGxpbmUgbnVtYmVyIHdoZXJlIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50IGVuZHMuCisgICAgICogTGluZXMgYXJlIGRlbGltaXRlZCBieSBsaW5lIGVuZHMsIHdoaWNoIGFyZSBkZWZpbmVkIGluCisgICAgICogdGhlIFhNTCBzcGVjaWZpY2F0aW9uLgorICAgICAqCisgICAgICogPHA+PHN0cm9uZz5XYXJuaW5nOjwvc3Ryb25nPiBUaGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIG1ldGhvZAorICAgICAqIGlzIGludGVuZGVkIG9ubHkgYXMgYW4gYXBwcm94aW1hdGlvbiBmb3IgdGhlIHNha2Ugb2YgZGlhZ25vc3RpY3M7CisgICAgICogaXQgaXMgbm90IGludGVuZGVkIHRvIHByb3ZpZGUgc3VmZmljaWVudCBpbmZvcm1hdGlvbgorICAgICAqIHRvIGVkaXQgdGhlIGNoYXJhY3RlciBjb250ZW50IG9mIHRoZSBvcmlnaW5hbCBYTUwgZG9jdW1lbnQuCisgICAgICogSW4gc29tZSBjYXNlcywgdGhlc2UgImxpbmUiIG51bWJlcnMgbWF0Y2ggd2hhdCB3b3VsZCBiZSBkaXNwbGF5ZWQKKyAgICAgKiBhcyBjb2x1bW5zLCBhbmQgaW4gb3RoZXJzIHRoZXkgbWF5IG5vdCBtYXRjaCB0aGUgc291cmNlIHRleHQKKyAgICAgKiBkdWUgdG8gaW50ZXJuYWwgZW50aXR5IGV4cGFuc2lvbi4gIDwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSByZXR1cm4gdmFsdWUgaXMgYW4gYXBwcm94aW1hdGlvbiBvZiB0aGUgbGluZSBudW1iZXIKKyAgICAgKiBpbiB0aGUgZG9jdW1lbnQgZW50aXR5IG9yIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkgd2hlcmUgdGhlCisgICAgICogbWFya3VwIHRyaWdnZXJpbmcgdGhlIGV2ZW50IGFwcGVhcnMuPC9wPgorICAgICAqCisgICAgICogPHA+SWYgcG9zc2libGUsIHRoZSBTQVggZHJpdmVyIHNob3VsZCBwcm92aWRlIHRoZSBsaW5lIHBvc2l0aW9uCisgICAgICogb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBhZnRlciB0aGUgdGV4dCBhc3NvY2lhdGVkIHdpdGggdGhlIGRvY3VtZW50CisgICAgICogZXZlbnQuICBUaGUgZmlyc3QgbGluZSBpcyBsaW5lIDEuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgbGluZSBudW1iZXIsIG9yIC0xIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgorICAgICAqIEBzZWUgI2dldENvbHVtbk51bWJlcgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0TGluZU51bWJlciAoKTsKKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjb2x1bW4gbnVtYmVyIHdoZXJlIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50IGVuZHMuCisgICAgICogVGhpcyBpcyBvbmUtYmFzZWQgbnVtYmVyIG9mIEphdmEgPGNvZGU+Y2hhcjwvY29kZT4gdmFsdWVzIHNpbmNlCisgICAgICogdGhlIGxhc3QgbGluZSBlbmQuCisgICAgICoKKyAgICAgKiA8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IFRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgbWV0aG9kCisgICAgICogaXMgaW50ZW5kZWQgb25seSBhcyBhbiBhcHByb3hpbWF0aW9uIGZvciB0aGUgc2FrZSBvZiBkaWFnbm9zdGljczsKKyAgICAgKiBpdCBpcyBub3QgaW50ZW5kZWQgdG8gcHJvdmlkZSBzdWZmaWNpZW50IGluZm9ybWF0aW9uCisgICAgICogdG8gZWRpdCB0aGUgY2hhcmFjdGVyIGNvbnRlbnQgb2YgdGhlIG9yaWdpbmFsIFhNTCBkb2N1bWVudC4KKyAgICAgKiBGb3IgZXhhbXBsZSwgd2hlbiBsaW5lcyBjb250YWluIGNvbWJpbmluZyBjaGFyYWN0ZXIgc2VxdWVuY2VzLCB3aWRlCisgICAgICogY2hhcmFjdGVycywgc3Vycm9nYXRlIHBhaXJzLCBvciBiaS1kaXJlY3Rpb25hbCB0ZXh0LCB0aGUgdmFsdWUgbWF5CisgICAgICogbm90IGNvcnJlc3BvbmQgdG8gdGhlIGNvbHVtbiBpbiBhIHRleHQgZWRpdG9yJ3MgZGlzcGxheS4gPC9wPgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybiB2YWx1ZSBpcyBhbiBhcHByb3hpbWF0aW9uIG9mIHRoZSBjb2x1bW4gbnVtYmVyCisgICAgICogaW4gdGhlIGRvY3VtZW50IGVudGl0eSBvciBleHRlcm5hbCBwYXJzZWQgZW50aXR5IHdoZXJlIHRoZQorICAgICAqIG1hcmt1cCB0cmlnZ2VyaW5nIHRoZSBldmVudCBhcHBlYXJzLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHBvc3NpYmxlLCB0aGUgU0FYIGRyaXZlciBzaG91bGQgcHJvdmlkZSB0aGUgbGluZSBwb3NpdGlvbgorICAgICAqIG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIHRleHQgYXNzb2NpYXRlZCB3aXRoIHRoZSBkb2N1bWVudAorICAgICAqIGV2ZW50LiAgVGhlIGZpcnN0IGNvbHVtbiBpbiBlYWNoIGxpbmUgaXMgY29sdW1uIDEuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgY29sdW1uIG51bWJlciwgb3IgLTEgaWYgbm9uZSBpcyBhdmFpbGFibGUuCisgICAgICogQHNlZSAjZ2V0TGluZU51bWJlcgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0Q29sdW1uTnVtYmVyICgpOworCit9CisKKy8vIGVuZCBvZiBMb2NhdG9yLmphdmEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9QYXJzZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9QYXJzZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZTcwMzA1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L1BhcnNlci5qYXZhCkBAIC0wLDAgKzEsMjEwIEBACisvLyBTQVggcGFyc2VyIGludGVyZmFjZS4KKy8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKKy8vIE5vIHdhcnJhbnR5OyBubyBjb3B5cmlnaHQgLS0gdXNlIHRoaXMgYXMgeW91IHdpbGwuCisvLyAkSWQ6IFBhcnNlci5qYXZhLHYgMS42IDIwMDIvMDEvMzAgMjE6MTM6NDcgZGJyb3duZWxsIEV4cCAkCisKK3BhY2thZ2Ugb3JnLnhtbC5zYXg7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CisKKworLyoqCisgKiBCYXNpYyBpbnRlcmZhY2UgZm9yIFNBWCAoU2ltcGxlIEFQSSBmb3IgWE1MKSBwYXJzZXJzLgorICoKKyAqIDxibG9ja3F1b3RlPgorICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKKyAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KKyAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgorICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+VGhpcyB3YXMgdGhlIG1haW4gZXZlbnQgc3VwcGxpZXIgaW50ZXJmYWNlIGZvciBTQVgxOyBpdCBoYXMKKyAqIGJlZW4gcmVwbGFjZWQgaW4gU0FYMiBieSB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyIFhNTFJlYWRlcn0sCisgKiB3aGljaCBpbmNsdWRlcyBOYW1lc3BhY2Ugc3VwcG9ydCBhbmQgc29waGlzdGljYXRlZCBjb25maWd1cmFiaWxpdHkKKyAqIGFuZCBleHRlbnNpYmlsaXR5LjwvcD4KKyAqCisgKiA8cD5BbGwgU0FYMSBwYXJzZXJzIG11c3QgaW1wbGVtZW50IHRoaXMgYmFzaWMgaW50ZXJmYWNlOiBpdCBhbGxvd3MKKyAqIGFwcGxpY2F0aW9ucyB0byByZWdpc3RlciBoYW5kbGVycyBmb3IgZGlmZmVyZW50IHR5cGVzIG9mIGV2ZW50cworICogYW5kIHRvIGluaXRpYXRlIGEgcGFyc2UgZnJvbSBhIFVSSSwgb3IgYSBjaGFyYWN0ZXIgc3RyZWFtLjwvcD4KKyAqCisgKiA8cD5BbGwgU0FYMSBwYXJzZXJzIG11c3QgYWxzbyBpbXBsZW1lbnQgYSB6ZXJvLWFyZ3VtZW50IGNvbnN0cnVjdG9yCisgKiAodGhvdWdoIG90aGVyIGNvbnN0cnVjdG9ycyBhcmUgYWxzbyBhbGxvd2VkKS48L3A+CisgKgorICogPHA+U0FYMSBwYXJzZXJzIGFyZSByZXVzYWJsZSBidXQgbm90IHJlLWVudHJhbnQ6IHRoZSBhcHBsaWNhdGlvbgorICogbWF5IHJldXNlIGEgcGFyc2VyIG9iamVjdCAocG9zc2libHkgd2l0aCBhIGRpZmZlcmVudCBpbnB1dCBzb3VyY2UpCisgKiBvbmNlIHRoZSBmaXJzdCBwYXJzZSBoYXMgY29tcGxldGVkIHN1Y2Nlc3NmdWxseSwgYnV0IGl0IG1heSBub3QKKyAqIGludm9rZSB0aGUgcGFyc2UoKSBtZXRob2RzIHJlY3Vyc2l2ZWx5IHdpdGhpbiBhIHBhcnNlLjwvcD4KKyAqCisgKiBAZGVwcmVjYXRlZCBUaGlzIGludGVyZmFjZSBoYXMgYmVlbiByZXBsYWNlZCBieSB0aGUgU0FYMgorICogICAgICAgICAgICAge0BsaW5rIG9yZy54bWwuc2F4LlhNTFJlYWRlciBYTUxSZWFkZXJ9CisgKiAgICAgICAgICAgICBpbnRlcmZhY2UsIHdoaWNoIGluY2x1ZGVzIE5hbWVzcGFjZSBzdXBwb3J0LgorICogQHNpbmNlIFNBWCAxLjAKKyAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCisgKiBAdmVyc2lvbiAyLjAuMSAoc2F4MnIyKQorICogQHNlZSBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcgorICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyCisgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcgorICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIKKyAqIEBzZWUgb3JnLnhtbC5zYXguSGFuZGxlckJhc2UKKyAqIEBzZWUgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2UKKyAqLworQERlcHJlY2F0ZWQKK3B1YmxpYyBpbnRlcmZhY2UgUGFyc2VyCit7CisKKyAgICAvKioKKyAgICAgKiBBbGxvdyBhbiBhcHBsaWNhdGlvbiB0byByZXF1ZXN0IGEgbG9jYWxlIGZvciBlcnJvcnMgYW5kIHdhcm5pbmdzLgorICAgICAqCisgICAgICogPHA+U0FYIHBhcnNlcnMgYXJlIG5vdCByZXF1aXJlZCB0byBwcm92aWRlIGxvY2FsaXNhdGlvbiBmb3IgZXJyb3JzCisgICAgICogYW5kIHdhcm5pbmdzOyBpZiB0aGV5IGNhbm5vdCBzdXBwb3J0IHRoZSByZXF1ZXN0ZWQgbG9jYWxlLAorICAgICAqIGhvd2V2ZXIsIHRoZXkgbXVzdCB0aHJvdyBhIFNBWCBleGNlcHRpb24uICBBcHBsaWNhdGlvbnMgbWF5CisgICAgICogbm90IHJlcXVlc3QgYSBsb2NhbGUgY2hhbmdlIGluIHRoZSBtaWRkbGUgb2YgYSBwYXJzZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYWxlIEEgSmF2YSBMb2NhbGUgb2JqZWN0LgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRocm93cyBhbiBleGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICh1c2luZyB0aGUgcHJldmlvdXMgb3IgZGVmYXVsdCBsb2NhbGUpIGlmIHRoZQorICAgICAqICAgICAgICAgICAgcmVxdWVzdGVkIGxvY2FsZSBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldExvY2FsZSAoTG9jYWxlIGxvY2FsZSkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBBbGxvdyBhbiBhcHBsaWNhdGlvbiB0byByZWdpc3RlciBhIGN1c3RvbSBlbnRpdHkgcmVzb2x2ZXIuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgYXBwbGljYXRpb24gZG9lcyBub3QgcmVnaXN0ZXIgYW4gZW50aXR5IHJlc29sdmVyLCB0aGUKKyAgICAgKiBTQVggcGFyc2VyIHdpbGwgcmVzb2x2ZSBzeXN0ZW0gaWRlbnRpZmllcnMgYW5kIG9wZW4gY29ubmVjdGlvbnMKKyAgICAgKiB0byBlbnRpdGllcyBpdHNlbGYgKHRoaXMgaXMgdGhlIGRlZmF1bHQgYmVoYXZpb3VyIGltcGxlbWVudGVkIGluCisgICAgICogSGFuZGxlckJhc2UpLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkFwcGxpY2F0aW9ucyBtYXkgcmVnaXN0ZXIgYSBuZXcgb3IgZGlmZmVyZW50IGVudGl0eSByZXNvbHZlcgorICAgICAqIGluIHRoZSBtaWRkbGUgb2YgYSBwYXJzZSwgYW5kIHRoZSBTQVggcGFyc2VyIG11c3QgYmVnaW4gdXNpbmcKKyAgICAgKiB0aGUgbmV3IHJlc29sdmVyIGltbWVkaWF0ZWx5LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZXNvbHZlciBUaGUgb2JqZWN0IGZvciByZXNvbHZpbmcgZW50aXRpZXMuCisgICAgICogQHNlZSBFbnRpdHlSZXNvbHZlcgorICAgICAqIEBzZWUgSGFuZGxlckJhc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRFbnRpdHlSZXNvbHZlciAoRW50aXR5UmVzb2x2ZXIgcmVzb2x2ZXIpOworCisKKyAgICAvKioKKyAgICAgKiBBbGxvdyBhbiBhcHBsaWNhdGlvbiB0byByZWdpc3RlciBhIERURCBldmVudCBoYW5kbGVyLgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIGRvZXMgbm90IHJlZ2lzdGVyIGEgRFREIGhhbmRsZXIsIGFsbCBEVEQKKyAgICAgKiBldmVudHMgcmVwb3J0ZWQgYnkgdGhlIFNBWCBwYXJzZXIgd2lsbCBiZSBzaWxlbnRseQorICAgICAqIGlnbm9yZWQgKHRoaXMgaXMgdGhlIGRlZmF1bHQgYmVoYXZpb3VyIGltcGxlbWVudGVkIGJ5CisgICAgICogSGFuZGxlckJhc2UpLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkFwcGxpY2F0aW9ucyBtYXkgcmVnaXN0ZXIgYSBuZXcgb3IgZGlmZmVyZW50CisgICAgICogaGFuZGxlciBpbiB0aGUgbWlkZGxlIG9mIGEgcGFyc2UsIGFuZCB0aGUgU0FYIHBhcnNlciBtdXN0CisgICAgICogYmVnaW4gdXNpbmcgdGhlIG5ldyBoYW5kbGVyIGltbWVkaWF0ZWx5LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBEVEQgaGFuZGxlci4KKyAgICAgKiBAc2VlIERUREhhbmRsZXIKKyAgICAgKiBAc2VlIEhhbmRsZXJCYXNlCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RFRESGFuZGxlciAoRFRESGFuZGxlciBoYW5kbGVyKTsKKworCisgICAgLyoqCisgICAgICogQWxsb3cgYW4gYXBwbGljYXRpb24gdG8gcmVnaXN0ZXIgYSBkb2N1bWVudCBldmVudCBoYW5kbGVyLgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIGRvZXMgbm90IHJlZ2lzdGVyIGEgZG9jdW1lbnQgaGFuZGxlciwgYWxsCisgICAgICogZG9jdW1lbnQgZXZlbnRzIHJlcG9ydGVkIGJ5IHRoZSBTQVggcGFyc2VyIHdpbGwgYmUgc2lsZW50bHkKKyAgICAgKiBpZ25vcmVkICh0aGlzIGlzIHRoZSBkZWZhdWx0IGJlaGF2aW91ciBpbXBsZW1lbnRlZCBieQorICAgICAqIEhhbmRsZXJCYXNlKS48L3A+CisgICAgICoKKyAgICAgKiA8cD5BcHBsaWNhdGlvbnMgbWF5IHJlZ2lzdGVyIGEgbmV3IG9yIGRpZmZlcmVudCBoYW5kbGVyIGluIHRoZQorICAgICAqIG1pZGRsZSBvZiBhIHBhcnNlLCBhbmQgdGhlIFNBWCBwYXJzZXIgbXVzdCBiZWdpbiB1c2luZyB0aGUgbmV3CisgICAgICogaGFuZGxlciBpbW1lZGlhdGVseS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgZG9jdW1lbnQgaGFuZGxlci4KKyAgICAgKiBAc2VlIERvY3VtZW50SGFuZGxlcgorICAgICAqIEBzZWUgSGFuZGxlckJhc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXREb2N1bWVudEhhbmRsZXIgKERvY3VtZW50SGFuZGxlciBoYW5kbGVyKTsKKworCisgICAgLyoqCisgICAgICogQWxsb3cgYW4gYXBwbGljYXRpb24gdG8gcmVnaXN0ZXIgYW4gZXJyb3IgZXZlbnQgaGFuZGxlci4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBhcHBsaWNhdGlvbiBkb2VzIG5vdCByZWdpc3RlciBhbiBlcnJvciBldmVudCBoYW5kbGVyLAorICAgICAqIGFsbCBlcnJvciBldmVudHMgcmVwb3J0ZWQgYnkgdGhlIFNBWCBwYXJzZXIgd2lsbCBiZSBzaWxlbnRseQorICAgICAqIGlnbm9yZWQsIGV4Y2VwdCBmb3IgZmF0YWxFcnJvciwgd2hpY2ggd2lsbCB0aHJvdyBhIFNBWEV4Y2VwdGlvbgorICAgICAqICh0aGlzIGlzIHRoZSBkZWZhdWx0IGJlaGF2aW91ciBpbXBsZW1lbnRlZCBieSBIYW5kbGVyQmFzZSkuPC9wPgorICAgICAqCisgICAgICogPHA+QXBwbGljYXRpb25zIG1heSByZWdpc3RlciBhIG5ldyBvciBkaWZmZXJlbnQgaGFuZGxlciBpbiB0aGUKKyAgICAgKiBtaWRkbGUgb2YgYSBwYXJzZSwgYW5kIHRoZSBTQVggcGFyc2VyIG11c3QgYmVnaW4gdXNpbmcgdGhlIG5ldworICAgICAqIGhhbmRsZXIgaW1tZWRpYXRlbHkuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGhhbmRsZXIgVGhlIGVycm9yIGhhbmRsZXIuCisgICAgICogQHNlZSBFcnJvckhhbmRsZXIKKyAgICAgKiBAc2VlIFNBWEV4Y2VwdGlvbgorICAgICAqIEBzZWUgSGFuZGxlckJhc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRFcnJvckhhbmRsZXIgKEVycm9ySGFuZGxlciBoYW5kbGVyKTsKKworCisgICAgLyoqCisgICAgICogUGFyc2UgYW4gWE1MIGRvY3VtZW50LgorICAgICAqCisgICAgICogPHA+VGhlIGFwcGxpY2F0aW9uIGNhbiB1c2UgdGhpcyBtZXRob2QgdG8gaW5zdHJ1Y3QgdGhlIFNBWCBwYXJzZXIKKyAgICAgKiB0byBiZWdpbiBwYXJzaW5nIGFuIFhNTCBkb2N1bWVudCBmcm9tIGFueSB2YWxpZCBpbnB1dAorICAgICAqIHNvdXJjZSAoYSBjaGFyYWN0ZXIgc3RyZWFtLCBhIGJ5dGUgc3RyZWFtLCBvciBhIFVSSSkuPC9wPgorICAgICAqCisgICAgICogPHA+QXBwbGljYXRpb25zIG1heSBub3QgaW52b2tlIHRoaXMgbWV0aG9kIHdoaWxlIGEgcGFyc2UgaXMgaW4KKyAgICAgKiBwcm9ncmVzcyAodGhleSBzaG91bGQgY3JlYXRlIGEgbmV3IFBhcnNlciBpbnN0ZWFkIGZvciBlYWNoCisgICAgICogYWRkaXRpb25hbCBYTUwgZG9jdW1lbnQpLiAgT25jZSBhIHBhcnNlIGlzIGNvbXBsZXRlLCBhbgorICAgICAqIGFwcGxpY2F0aW9uIG1heSByZXVzZSB0aGUgc2FtZSBQYXJzZXIgb2JqZWN0LCBwb3NzaWJseSB3aXRoIGEKKyAgICAgKiBkaWZmZXJlbnQgaW5wdXQgc291cmNlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzb3VyY2UgVGhlIGlucHV0IHNvdXJjZSBmb3IgdGhlIHRvcC1sZXZlbCBvZiB0aGUKKyAgICAgKiAgICAgICAgWE1MIGRvY3VtZW50LgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQGV4Y2VwdGlvbiBqYXZhLmlvLklPRXhjZXB0aW9uIEFuIElPIGV4Y2VwdGlvbiBmcm9tIHRoZSBwYXJzZXIsCisgICAgICogICAgICAgICAgICBwb3NzaWJseSBmcm9tIGEgYnl0ZSBzdHJlYW0gb3IgY2hhcmFjdGVyIHN0cmVhbQorICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgYnkgdGhlIGFwcGxpY2F0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2UKKyAgICAgKiBAc2VlICNwYXJzZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqIEBzZWUgI3NldEVudGl0eVJlc29sdmVyCisgICAgICogQHNlZSAjc2V0RFRESGFuZGxlcgorICAgICAqIEBzZWUgI3NldERvY3VtZW50SGFuZGxlcgorICAgICAqIEBzZWUgI3NldEVycm9ySGFuZGxlcgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHBhcnNlIChJbnB1dFNvdXJjZSBzb3VyY2UpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFBhcnNlIGFuIFhNTCBkb2N1bWVudCBmcm9tIGEgc3lzdGVtIGlkZW50aWZpZXIgKFVSSSkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBhIHNob3J0Y3V0IGZvciB0aGUgY29tbW9uIGNhc2Ugb2YgcmVhZGluZyBhCisgICAgICogZG9jdW1lbnQgZnJvbSBhIHN5c3RlbSBpZGVudGlmaWVyLiAgSXQgaXMgdGhlIGV4YWN0CisgICAgICogZXF1aXZhbGVudCBvZiB0aGUgZm9sbG93aW5nOjwvcD4KKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogcGFyc2UobmV3IElucHV0U291cmNlKHN5c3RlbUlkKSk7CisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwsIGl0IG11c3QgYmUgZnVsbHkgcmVzb2x2ZWQKKyAgICAgKiBieSB0aGUgYXBwbGljYXRpb24gYmVmb3JlIGl0IGlzIHBhc3NlZCB0byB0aGUgcGFyc2VyLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgKFVSSSkuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24gQW4gSU8gZXhjZXB0aW9uIGZyb20gdGhlIHBhcnNlciwKKyAgICAgKiAgICAgICAgICAgIHBvc3NpYmx5IGZyb20gYSBieXRlIHN0cmVhbSBvciBjaGFyYWN0ZXIgc3RyZWFtCisgICAgICogICAgICAgICAgICBzdXBwbGllZCBieSB0aGUgYXBwbGljYXRpb24uCisgICAgICogQHNlZSAjcGFyc2Uob3JnLnhtbC5zYXguSW5wdXRTb3VyY2UpCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcGFyc2UgKFN0cmluZyBzeXN0ZW1JZCkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbjsKKworfQorCisvLyBlbmQgb2YgUGFyc2VyLmphdmEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9TQVhFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9TQVhFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOGQwYTliCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L1NBWEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTUxIEBACisvLyBTQVggZXhjZXB0aW9uIGNsYXNzLgorLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZworLy8gTm8gd2FycmFudHk7IG5vIGNvcHlyaWdodCAtLSB1c2UgdGhpcyBhcyB5b3Ugd2lsbC4KKy8vICRJZDogU0FYRXhjZXB0aW9uLmphdmEsdiAxLjcgMjAwMi8wMS8zMCAyMToxMzo0OCBkYnJvd25lbGwgRXhwICQKKworcGFja2FnZSBvcmcueG1sLnNheDsKKworLyoqCisgKiBFbmNhcHN1bGF0ZSBhIGdlbmVyYWwgU0FYIGVycm9yIG9yIHdhcm5pbmcuCisgKgorICogPGJsb2NrcXVvdGU+CisgKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQorICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgorICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+CisgKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KKyAqIDwvYmxvY2txdW90ZT4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGNhbiBjb250YWluIGJhc2ljIGVycm9yIG9yIHdhcm5pbmcgaW5mb3JtYXRpb24gZnJvbQorICogZWl0aGVyIHRoZSBYTUwgcGFyc2VyIG9yIHRoZSBhcHBsaWNhdGlvbjogYSBwYXJzZXIgd3JpdGVyIG9yCisgKiBhcHBsaWNhdGlvbiB3cml0ZXIgY2FuIHN1YmNsYXNzIGl0IHRvIHByb3ZpZGUgYWRkaXRpb25hbAorICogZnVuY3Rpb25hbGl0eS4gIFNBWCBoYW5kbGVycyBtYXkgdGhyb3cgdGhpcyBleGNlcHRpb24gb3IKKyAqIGFueSBleGNlcHRpb24gc3ViY2xhc3NlZCBmcm9tIGl0LjwvcD4KKyAqCisgKiA8cD5JZiB0aGUgYXBwbGljYXRpb24gbmVlZHMgdG8gcGFzcyB0aHJvdWdoIG90aGVyIHR5cGVzIG9mCisgKiBleGNlcHRpb25zLCBpdCBtdXN0IHdyYXAgdGhvc2UgZXhjZXB0aW9ucyBpbiBhIFNBWEV4Y2VwdGlvbgorICogb3IgYW4gZXhjZXB0aW9uIGRlcml2ZWQgZnJvbSBhIFNBWEV4Y2VwdGlvbi48L3A+CisgKgorICogPHA+SWYgdGhlIHBhcnNlciBvciBhcHBsaWNhdGlvbiBuZWVkcyB0byBpbmNsdWRlIGluZm9ybWF0aW9uIGFib3V0IGEKKyAqIHNwZWNpZmljIGxvY2F0aW9uIGluIGFuIFhNTCBkb2N1bWVudCwgaXQgc2hvdWxkIHVzZSB0aGUKKyAqIHtAbGluayBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbiBTQVhQYXJzZUV4Y2VwdGlvbn0gc3ViY2xhc3MuPC9wPgorICoKKyAqIEBzaW5jZSBTQVggMS4wCisgKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgorICogQHZlcnNpb24gMi4wLjEgKHNheDJyMikKKyAqIEBzZWUgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24KKyAqLworcHVibGljIGNsYXNzIFNBWEV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBTQVhFeGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFNBWEV4Y2VwdGlvbiAoKQorICAgIHsKKyAgICB0aGlzLmV4Y2VwdGlvbiA9IG51bGw7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgU0FYRXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG9yIHdhcm5pbmcgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU0FYRXhjZXB0aW9uIChTdHJpbmcgbWVzc2FnZSkgeworICAgIHN1cGVyKG1lc3NhZ2UpOworICAgIHRoaXMuZXhjZXB0aW9uID0gbnVsbDsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBTQVhFeGNlcHRpb24gd3JhcHBpbmcgYW4gZXhpc3RpbmcgZXhjZXB0aW9uLgorICAgICAqCisgICAgICogPHA+VGhlIGV4aXN0aW5nIGV4Y2VwdGlvbiB3aWxsIGJlIGVtYmVkZGVkIGluIHRoZSBuZXcKKyAgICAgKiBvbmUsIGFuZCBpdHMgbWVzc2FnZSB3aWxsIGJlY29tZSB0aGUgZGVmYXVsdCBtZXNzYWdlIGZvcgorICAgICAqIHRoZSBTQVhFeGNlcHRpb24uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGUgVGhlIGV4Y2VwdGlvbiB0byBiZSB3cmFwcGVkIGluIGEgU0FYRXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBTQVhFeGNlcHRpb24gKEV4Y2VwdGlvbiBlKQorICAgIHsKKyAgICB0aGlzLmV4Y2VwdGlvbiA9IGU7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgU0FYRXhjZXB0aW9uIGZyb20gYW4gZXhpc3RpbmcgZXhjZXB0aW9uLgorICAgICAqCisgICAgICogPHA+VGhlIGV4aXN0aW5nIGV4Y2VwdGlvbiB3aWxsIGJlIGVtYmVkZGVkIGluIHRoZSBuZXcKKyAgICAgKiBvbmUsIGJ1dCB0aGUgbmV3IGV4Y2VwdGlvbiB3aWxsIGhhdmUgaXRzIG93biBtZXNzYWdlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKiBAcGFyYW0gZSBUaGUgZXhjZXB0aW9uIHRvIGJlIHdyYXBwZWQgaW4gYSBTQVhFeGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFNBWEV4Y2VwdGlvbiAoU3RyaW5nIG1lc3NhZ2UsIEV4Y2VwdGlvbiBlKQorICAgIHsKKyAgICBzdXBlcihtZXNzYWdlKTsKKyAgICB0aGlzLmV4Y2VwdGlvbiA9IGU7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGVyZSBpcyBhbiBlbWJlZGRlZCBleGNlcHRpb24sIGFuZCBpZiB0aGUgU0FYRXhjZXB0aW9uCisgICAgICogaGFzIG5vIGRldGFpbCBtZXNzYWdlIG9mIGl0cyBvd24sIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuCisgICAgICogdGhlIGRldGFpbCBtZXNzYWdlIGZyb20gdGhlIGVtYmVkZGVkIGV4Y2VwdGlvbi48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBlcnJvciBvciB3YXJuaW5nIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlICgpCisgICAgeworICAgIFN0cmluZyBtZXNzYWdlID0gc3VwZXIuZ2V0TWVzc2FnZSgpOworCisgICAgaWYgKG1lc3NhZ2UgPT0gbnVsbCAmJiBleGNlcHRpb24gIT0gbnVsbCkgeworICAgICAgICByZXR1cm4gZXhjZXB0aW9uLmdldE1lc3NhZ2UoKTsKKyAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gbWVzc2FnZTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGVtYmVkZGVkIGV4Y2VwdGlvbiwgaWYgYW55LgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgZW1iZWRkZWQgZXhjZXB0aW9uLCBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuCisgICAgICovCisgICAgcHVibGljIEV4Y2VwdGlvbiBnZXRFeGNlcHRpb24gKCkKKyAgICB7CisgICAgcmV0dXJuIGV4Y2VwdGlvbjsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIE92ZXJyaWRlIHRvU3RyaW5nIHRvIHBpY2sgdXAgYW55IGVtYmVkZGVkIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZyAoKQorICAgIHsKKyAgICBpZiAoZXhjZXB0aW9uICE9IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIGV4Y2VwdGlvbi50b1N0cmluZygpOworICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBzdXBlci50b1N0cmluZygpOworICAgIH0KKyAgICB9CisKKworICAgIAwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gSW50ZXJuYWwgc3RhdGUuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisKKyAgICAvKioKKyAgICAgKiBAc2VyaWFsIFRoZSBlbWJlZGRlZCBleGNlcHRpb24gaWYgdHVubmVsbGluZywgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIEV4Y2VwdGlvbiBleGNlcHRpb247CisKK30KKworLy8gZW5kIG9mIFNBWEV4Y2VwdGlvbi5qYXZhCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L1NBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNmJiODhkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L1NBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDUyIEBACisvLyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLmphdmEgLSB1bnJlY29nbml6ZWQgZmVhdHVyZSBvciB2YWx1ZS4KKy8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKKy8vIFdyaXR0ZW4gYnkgRGF2aWQgTWVnZ2luc29uCisvLyBOTyBXQVJSQU5UWSEgIFRoaXMgY2xhc3MgaXMgaW4gdGhlIFB1YmxpYyBEb21haW4uCisvLyAkSWQ6IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24uamF2YSx2IDEuNyAyMDAyLzAxLzMwIDIxOjEzOjQ4IGRicm93bmVsbCBFeHAgJAorCitwYWNrYWdlIG9yZy54bWwuc2F4OworCisKKy8qKgorICogRXhjZXB0aW9uIGNsYXNzIGZvciBhbiB1bnJlY29nbml6ZWQgaWRlbnRpZmllci4KKyAqCisgKiA8YmxvY2txdW90ZT4KKyAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCisgKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+CisgKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KKyAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgorICogPC9ibG9ja3F1b3RlPgorICoKKyAqIDxwPkFuIFhNTFJlYWRlciB3aWxsIHRocm93IHRoaXMgZXhjZXB0aW9uIHdoZW4gaXQgZmluZHMgYW4KKyAqIHVucmVjb2duaXplZCBmZWF0dXJlIG9yIHByb3BlcnR5IGlkZW50aWZpZXI7IFNBWCBhcHBsaWNhdGlvbnMgYW5kCisgKiBleHRlbnNpb25zIG1heSB1c2UgdGhpcyBjbGFzcyBmb3Igb3RoZXIsIHNpbWlsYXIgcHVycG9zZXMuPC9wPgorICoKKyAqIEBzaW5jZSBTQVggMi4wCisgKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgorICogQHZlcnNpb24gMi4wLjEgKHNheDJyMikKKyAqIEBzZWUgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uCisgKi8KK3B1YmxpYyBjbGFzcyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIGV4dGVuZHMgU0FYRXhjZXB0aW9uCit7CisKKyAgICAvKioKKyAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uICgpCisgICAgeworICAgIH0KKworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgbmV3IGV4Y2VwdGlvbiB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIHRleHQgbWVzc2FnZSBvZiB0aGUgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIChTdHJpbmcgbWVzc2FnZSkKKyAgICB7CisgICAgc3VwZXIobWVzc2FnZSk7CisgICAgfQorCit9CisKKy8vIGVuZCBvZiBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLmphdmEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24uamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZGE4NWVhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L1NBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTIgQEAKKy8vIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbi5qYXZhIC0gdW5zdXBwb3J0ZWQgZmVhdHVyZSBvciB2YWx1ZS4KKy8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKKy8vIFdyaXR0ZW4gYnkgRGF2aWQgTWVnZ2luc29uCisvLyBOTyBXQVJSQU5UWSEgIFRoaXMgY2xhc3MgaXMgaW4gdGhlIFB1YmxpYyBEb21haW4uCisvLyAkSWQ6IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbi5qYXZhLHYgMS43IDIwMDIvMDEvMzAgMjE6MTM6NDggZGJyb3duZWxsIEV4cCAkCisKK3BhY2thZ2Ugb3JnLnhtbC5zYXg7CisKKy8qKgorICogRXhjZXB0aW9uIGNsYXNzIGZvciBhbiB1bnN1cHBvcnRlZCBvcGVyYXRpb24uCisgKgorICogPGJsb2NrcXVvdGU+CisgKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQorICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgorICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+CisgKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KKyAqIDwvYmxvY2txdW90ZT4KKyAqCisgKiA8cD5BbiBYTUxSZWFkZXIgd2lsbCB0aHJvdyB0aGlzIGV4Y2VwdGlvbiB3aGVuIGl0IHJlY29nbml6ZXMgYQorICogZmVhdHVyZSBvciBwcm9wZXJ0eSBpZGVudGlmaWVyLCBidXQgY2Fubm90IHBlcmZvcm0gdGhlIHJlcXVlc3RlZAorICogb3BlcmF0aW9uIChzZXR0aW5nIGEgc3RhdGUgb3IgdmFsdWUpLiAgT3RoZXIgU0FYMiBhcHBsaWNhdGlvbnMgYW5kCisgKiBleHRlbnNpb25zIG1heSB1c2UgdGhpcyBjbGFzcyBmb3Igc2ltaWxhciBwdXJwb3Nlcy48L3A+CisgKgorICogQHNpbmNlIFNBWCAyLjAKKyAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCisgKiBAdmVyc2lvbiAyLjAuMSAoc2F4MnIyKQorICogQHNlZSBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uCisgKi8KK3B1YmxpYyBjbGFzcyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZXh0ZW5kcyBTQVhFeGNlcHRpb24KK3sKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIG5ldyBleGNlcHRpb24gd2l0aCBubyBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gKCkKKyAgICB7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBuZXcgZXhjZXB0aW9uIHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgdGV4dCBtZXNzYWdlIG9mIHRoZSBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiAoU3RyaW5nIG1lc3NhZ2UpCisgICAgeworICAgIHN1cGVyKG1lc3NhZ2UpOworICAgIH0KKworfQorCisvLyBlbmQgb2YgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uLmphdmEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9TQVhQYXJzZUV4Y2VwdGlvbi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L1NBWFBhcnNlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDI0Zjc3YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9TQVhQYXJzZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMjY5IEBACisvLyBTQVggZXhjZXB0aW9uIGNsYXNzLgorLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZworLy8gTm8gd2FycmFudHk7IG5vIGNvcHlyaWdodCAtLSB1c2UgdGhpcyBhcyB5b3Ugd2lsbC4KKy8vICRJZDogU0FYUGFyc2VFeGNlcHRpb24uamF2YSx2IDEuMTEgMjAwNC8wNC8yMSAxMzowNTowMiBkbWVnZ2luc29uIEV4cCAkCisKK3BhY2thZ2Ugb3JnLnhtbC5zYXg7CisKKy8qKgorICogRW5jYXBzdWxhdGUgYW4gWE1MIHBhcnNlIGVycm9yIG9yIHdhcm5pbmcuCisgKgorICogPGJsb2NrcXVvdGU+CisgKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQorICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgorICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+CisgKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KKyAqIDwvYmxvY2txdW90ZT4KKyAqCisgKiA8cD5UaGlzIGV4Y2VwdGlvbiBtYXkgaW5jbHVkZSBpbmZvcm1hdGlvbiBmb3IgbG9jYXRpbmcgdGhlIGVycm9yCisgKiBpbiB0aGUgb3JpZ2luYWwgWE1MIGRvY3VtZW50LCBhcyBpZiBpdCBjYW1lIGZyb20gYSB7QGxpbmsgTG9jYXRvcn0KKyAqIG9iamVjdC4gIE5vdGUgdGhhdCBhbHRob3VnaCB0aGUgYXBwbGljYXRpb24KKyAqIHdpbGwgcmVjZWl2ZSBhIFNBWFBhcnNlRXhjZXB0aW9uIGFzIHRoZSBhcmd1bWVudCB0byB0aGUgaGFuZGxlcnMKKyAqIGluIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyIEVycm9ySGFuZGxlcn0gaW50ZXJmYWNlLAorICogdGhlIGFwcGxpY2F0aW9uIGlzIG5vdCBhY3R1YWxseSByZXF1aXJlZCB0byB0aHJvdyB0aGUgZXhjZXB0aW9uOworICogaW5zdGVhZCwgaXQgY2FuIHNpbXBseSByZWFkIHRoZSBpbmZvcm1hdGlvbiBpbiBpdCBhbmQgdGFrZSBhCisgKiBkaWZmZXJlbnQgYWN0aW9uLjwvcD4KKyAqCisgKiA8cD5TaW5jZSB0aGlzIGV4Y2VwdGlvbiBpcyBhIHN1YmNsYXNzIG9mIHtAbGluayBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KKyAqIFNBWEV4Y2VwdGlvbn0sIGl0IGluaGVyaXRzIHRoZSBhYmlsaXR5IHRvIHdyYXAgYW5vdGhlciBleGNlcHRpb24uPC9wPgorICoKKyAqIEBzaW5jZSBTQVggMS4wCisgKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgorICogQHZlcnNpb24gMi4wLjEgKHNheDJyMikKKyAqIEBzZWUgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCisgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKKyAqIEBzZWUgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyCisgKi8KK3B1YmxpYyBjbGFzcyBTQVhQYXJzZUV4Y2VwdGlvbiBleHRlbmRzIFNBWEV4Y2VwdGlvbiB7CisKKyAgICAMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIENvbnN0cnVjdG9ycy4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBTQVhQYXJzZUV4Y2VwdGlvbiBmcm9tIGEgbWVzc2FnZSBhbmQgYSBMb2NhdG9yLgorICAgICAqCisgICAgICogPHA+VGhpcyBjb25zdHJ1Y3RvciBpcyBlc3BlY2lhbGx5IHVzZWZ1bCB3aGVuIGFuIGFwcGxpY2F0aW9uIGlzCisgICAgICogY3JlYXRpbmcgaXRzIG93biBleGNlcHRpb24gZnJvbSB3aXRoaW4gYSB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIKKyAgICAgKiBDb250ZW50SGFuZGxlcn0gY2FsbGJhY2suPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG9yIHdhcm5pbmcgbWVzc2FnZS4KKyAgICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRvciBvYmplY3QgZm9yIHRoZSBlcnJvciBvciB3YXJuaW5nIChtYXkgYmUKKyAgICAgKiAgICAgICAgbnVsbCkuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yCisgICAgICovCisgICAgcHVibGljIFNBWFBhcnNlRXhjZXB0aW9uIChTdHJpbmcgbWVzc2FnZSwgTG9jYXRvciBsb2NhdG9yKSB7CisgICAgc3VwZXIobWVzc2FnZSk7CisgICAgaWYgKGxvY2F0b3IgIT0gbnVsbCkgeworICAgICAgICBpbml0KGxvY2F0b3IuZ2V0UHVibGljSWQoKSwgbG9jYXRvci5nZXRTeXN0ZW1JZCgpLAorICAgICAgICAgbG9jYXRvci5nZXRMaW5lTnVtYmVyKCksIGxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCkpOworICAgIH0gZWxzZSB7CisgICAgICAgIGluaXQobnVsbCwgbnVsbCwgLTEsIC0xKTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBXcmFwIGFuIGV4aXN0aW5nIGV4Y2VwdGlvbiBpbiBhIFNBWFBhcnNlRXhjZXB0aW9uLgorICAgICAqCisgICAgICogPHA+VGhpcyBjb25zdHJ1Y3RvciBpcyBlc3BlY2lhbGx5IHVzZWZ1bCB3aGVuIGFuIGFwcGxpY2F0aW9uIGlzCisgICAgICogY3JlYXRpbmcgaXRzIG93biBleGNlcHRpb24gZnJvbSB3aXRoaW4gYSB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIKKyAgICAgKiBDb250ZW50SGFuZGxlcn0gY2FsbGJhY2ssIGFuZCBuZWVkcyB0byB3cmFwIGFuIGV4aXN0aW5nIGV4Y2VwdGlvbiB0aGF0IGlzIG5vdCBhCisgICAgICogc3ViY2xhc3Mgb2Yge0BsaW5rIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBTQVhFeGNlcHRpb259LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBvciB3YXJuaW5nIG1lc3NhZ2UsIG9yIG51bGwgdG8KKyAgICAgKiAgICAgICAgICAgICAgICB1c2UgdGhlIG1lc3NhZ2UgZnJvbSB0aGUgZW1iZWRkZWQgZXhjZXB0aW9uLgorICAgICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBsb2NhdG9yIG9iamVjdCBmb3IgdGhlIGVycm9yIG9yIHdhcm5pbmcgKG1heSBiZQorICAgICAqICAgICAgICBudWxsKS4KKyAgICAgKiBAcGFyYW0gZSBBbnkgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgorICAgICAqLworICAgIHB1YmxpYyBTQVhQYXJzZUV4Y2VwdGlvbiAoU3RyaW5nIG1lc3NhZ2UsIExvY2F0b3IgbG9jYXRvciwKKyAgICAgICAgICAgICAgICAgIEV4Y2VwdGlvbiBlKSB7CisgICAgc3VwZXIobWVzc2FnZSwgZSk7CisgICAgaWYgKGxvY2F0b3IgIT0gbnVsbCkgeworICAgICAgICBpbml0KGxvY2F0b3IuZ2V0UHVibGljSWQoKSwgbG9jYXRvci5nZXRTeXN0ZW1JZCgpLAorICAgICAgICAgbG9jYXRvci5nZXRMaW5lTnVtYmVyKCksIGxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCkpOworICAgIH0gZWxzZSB7CisgICAgICAgIGluaXQobnVsbCwgbnVsbCwgLTEsIC0xKTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgU0FYUGFyc2VFeGNlcHRpb24uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGNvbnN0cnVjdG9yIGlzIG1vc3QgdXNlZnVsIGZvciBwYXJzZXIgd3JpdGVycy48L3A+CisgICAgICoKKyAgICAgKiA8cD5BbGwgcGFyYW1ldGVycyBleGNlcHQgdGhlIG1lc3NhZ2UgYXJlIGFzIGlmCisgICAgICogdGhleSB3ZXJlIHByb3ZpZGVkIGJ5IGEge0BsaW5rIExvY2F0b3J9LiAgRm9yIGV4YW1wbGUsIGlmIHRoZQorICAgICAqIHN5c3RlbSBpZGVudGlmaWVyIGlzIGEgVVJMIChpbmNsdWRpbmcgcmVsYXRpdmUgZmlsZW5hbWUpLCB0aGUKKyAgICAgKiBjYWxsZXIgbXVzdCByZXNvbHZlIGl0IGZ1bGx5IGJlZm9yZSBjcmVhdGluZyB0aGUgZXhjZXB0aW9uLjwvcD4KKyAgICAgKgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG9yIHdhcm5pbmcgbWVzc2FnZS4KKyAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkgdGhhdCBnZW5lcmF0ZWQKKyAgICAgKiAgICAgICAgICAgICAgICAgdGhlIGVycm9yIG9yIHdhcm5pbmcuCisgICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZW50aXR5IHRoYXQgZ2VuZXJhdGVkCisgICAgICogICAgICAgICAgICAgICAgIHRoZSBlcnJvciBvciB3YXJuaW5nLgorICAgICAqIEBwYXJhbSBsaW5lTnVtYmVyIFRoZSBsaW5lIG51bWJlciBvZiB0aGUgZW5kIG9mIHRoZSB0ZXh0IHRoYXQKKyAgICAgKiAgICAgICAgICAgICAgICAgICBjYXVzZWQgdGhlIGVycm9yIG9yIHdhcm5pbmcuCisgICAgICogQHBhcmFtIGNvbHVtbk51bWJlciBUaGUgY29sdW1uIG51bWJlciBvZiB0aGUgZW5kIG9mIHRoZSB0ZXh0IHRoYXQKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGNhdXNlIHRoZSBlcnJvciBvciB3YXJuaW5nLgorICAgICAqLworICAgIHB1YmxpYyBTQVhQYXJzZUV4Y2VwdGlvbiAoU3RyaW5nIG1lc3NhZ2UsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLAorICAgICAgICAgICAgICAgICAgaW50IGxpbmVOdW1iZXIsIGludCBjb2x1bW5OdW1iZXIpCisgICAgeworICAgIHN1cGVyKG1lc3NhZ2UpOworICAgIGluaXQocHVibGljSWQsIHN5c3RlbUlkLCBsaW5lTnVtYmVyLCBjb2x1bW5OdW1iZXIpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IFNBWFBhcnNlRXhjZXB0aW9uIHdpdGggYW4gZW1iZWRkZWQgZXhjZXB0aW9uLgorICAgICAqCisgICAgICogPHA+VGhpcyBjb25zdHJ1Y3RvciBpcyBtb3N0IHVzZWZ1bCBmb3IgcGFyc2VyIHdyaXRlcnMgd2hvCisgICAgICogbmVlZCB0byB3cmFwIGFuIGV4Y2VwdGlvbiB0aGF0IGlzIG5vdCBhIHN1YmNsYXNzIG9mCisgICAgICoge0BsaW5rIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBTQVhFeGNlcHRpb259LjwvcD4KKyAgICAgKgorICAgICAqIDxwPkFsbCBwYXJhbWV0ZXJzIGV4Y2VwdCB0aGUgbWVzc2FnZSBhbmQgZXhjZXB0aW9uIGFyZSBhcyBpZgorICAgICAqIHRoZXkgd2VyZSBwcm92aWRlZCBieSBhIHtAbGluayBMb2NhdG9yfS4gIEZvciBleGFtcGxlLCBpZiB0aGUKKyAgICAgKiBzeXN0ZW0gaWRlbnRpZmllciBpcyBhIFVSTCAoaW5jbHVkaW5nIHJlbGF0aXZlIGZpbGVuYW1lKSwgdGhlCisgICAgICogY2FsbGVyIG11c3QgcmVzb2x2ZSBpdCBmdWxseSBiZWZvcmUgY3JlYXRpbmcgdGhlIGV4Y2VwdGlvbi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3Igb3Igd2FybmluZyBtZXNzYWdlLCBvciBudWxsIHRvIHVzZQorICAgICAqICAgICAgICAgICAgICAgIHRoZSBtZXNzYWdlIGZyb20gdGhlIGVtYmVkZGVkIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkgdGhhdCBnZW5lcmF0ZWQKKyAgICAgKiAgICAgICAgICAgICAgICAgdGhlIGVycm9yIG9yIHdhcm5pbmcuCisgICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZW50aXR5IHRoYXQgZ2VuZXJhdGVkCisgICAgICogICAgICAgICAgICAgICAgIHRoZSBlcnJvciBvciB3YXJuaW5nLgorICAgICAqIEBwYXJhbSBsaW5lTnVtYmVyIFRoZSBsaW5lIG51bWJlciBvZiB0aGUgZW5kIG9mIHRoZSB0ZXh0IHRoYXQKKyAgICAgKiAgICAgICAgICAgICAgICAgICBjYXVzZWQgdGhlIGVycm9yIG9yIHdhcm5pbmcuCisgICAgICogQHBhcmFtIGNvbHVtbk51bWJlciBUaGUgY29sdW1uIG51bWJlciBvZiB0aGUgZW5kIG9mIHRoZSB0ZXh0IHRoYXQKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGNhdXNlIHRoZSBlcnJvciBvciB3YXJuaW5nLgorICAgICAqIEBwYXJhbSBlIEFub3RoZXIgZXhjZXB0aW9uIHRvIGVtYmVkIGluIHRoaXMgb25lLgorICAgICAqLworICAgIHB1YmxpYyBTQVhQYXJzZUV4Y2VwdGlvbiAoU3RyaW5nIG1lc3NhZ2UsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLAorICAgICAgICAgICAgICAgICAgaW50IGxpbmVOdW1iZXIsIGludCBjb2x1bW5OdW1iZXIsIEV4Y2VwdGlvbiBlKQorICAgIHsKKyAgICBzdXBlcihtZXNzYWdlLCBlKTsKKyAgICBpbml0KHB1YmxpY0lkLCBzeXN0ZW1JZCwgbGluZU51bWJlciwgY29sdW1uTnVtYmVyKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEludGVybmFsIGluaXRpYWxpemF0aW9uIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGVudGl0eSB3aGljaCBnZW5lcmF0ZWQgdGhlIGV4Y2VwdGlvbiwKKyAgICAgKiAgICAgICAgb3IgbnVsbC4KKyAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkgd2hpY2ggZ2VuZXJhdGVkIHRoZSBleGNlcHRpb24sCisgICAgICogICAgICAgIG9yIG51bGwuCisgICAgICogQHBhcmFtIGxpbmVOdW1iZXIgVGhlIGxpbmUgbnVtYmVyIG9mIHRoZSBlcnJvciwgb3IgLTEuCisgICAgICogQHBhcmFtIGNvbHVtbk51bWJlciBUaGUgY29sdW1uIG51bWJlciBvZiB0aGUgZXJyb3IsIG9yIC0xLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpbml0IChTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwKKyAgICAgICAgICAgICAgIGludCBsaW5lTnVtYmVyLCBpbnQgY29sdW1uTnVtYmVyKQorICAgIHsKKyAgICB0aGlzLnB1YmxpY0lkID0gcHVibGljSWQ7CisgICAgdGhpcy5zeXN0ZW1JZCA9IHN5c3RlbUlkOworICAgIHRoaXMubGluZU51bWJlciA9IGxpbmVOdW1iZXI7CisgICAgdGhpcy5jb2x1bW5OdW1iZXIgPSBjb2x1bW5OdW1iZXI7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkgd2hlcmUgdGhlIGV4Y2VwdGlvbiBvY2N1cnJlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQSBzdHJpbmcgY29udGFpbmluZyB0aGUgcHVibGljIGlkZW50aWZpZXIsIG9yIG51bGwKKyAgICAgKiAgICAgICAgIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvciNnZXRQdWJsaWNJZAorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQgKCkKKyAgICB7CisgICAgcmV0dXJuIHRoaXMucHVibGljSWQ7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkgd2hlcmUgdGhlIGV4Y2VwdGlvbiBvY2N1cnJlZC4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBhIFVSTCwgaXQgd2lsbCBoYXZlIGJlZW4gcmVzb2x2ZWQKKyAgICAgKiBmdWxseS48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHN5c3RlbSBpZGVudGlmaWVyLCBvciBudWxsCisgICAgICogICAgICAgICBpZiBub25lIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IjZ2V0U3lzdGVtSWQKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkICgpCisgICAgeworICAgIHJldHVybiB0aGlzLnN5c3RlbUlkOworICAgIH0KKworCisgICAgLyoqCisgICAgICogVGhlIGxpbmUgbnVtYmVyIG9mIHRoZSBlbmQgb2YgdGhlIHRleHQgd2hlcmUgdGhlIGV4Y2VwdGlvbiBvY2N1cnJlZC4KKyAgICAgKgorICAgICAqIDxwPlRoZSBmaXJzdCBsaW5lIGlzIGxpbmUgMS48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFuIGludGVnZXIgcmVwcmVzZW50aW5nIHRoZSBsaW5lIG51bWJlciwgb3IgLTEKKyAgICAgKiAgICAgICAgIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvciNnZXRMaW5lTnVtYmVyCisgICAgICovCisgICAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyICgpCisgICAgeworICAgIHJldHVybiB0aGlzLmxpbmVOdW1iZXI7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBUaGUgY29sdW1uIG51bWJlciBvZiB0aGUgZW5kIG9mIHRoZSB0ZXh0IHdoZXJlIHRoZSBleGNlcHRpb24gb2NjdXJyZWQuCisgICAgICoKKyAgICAgKiA8cD5UaGUgZmlyc3QgY29sdW1uIGluIGEgbGluZSBpcyBwb3NpdGlvbiAxLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQW4gaW50ZWdlciByZXByZXNlbnRpbmcgdGhlIGNvbHVtbiBudW1iZXIsIG9yIC0xCisgICAgICogICAgICAgICBpZiBub25lIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IjZ2V0Q29sdW1uTnVtYmVyCisgICAgICovCisgICAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIgKCkKKyAgICB7CisgICAgcmV0dXJuIHRoaXMuY29sdW1uTnVtYmVyOworICAgIH0KKworICAgIAwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gSW50ZXJuYWwgc3RhdGUuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisKKyAgICAvKioKKyAgICAgKiBAc2VyaWFsIFRoZSBwdWJsaWMgaWRlbnRpZmllciwgb3IgbnVsbC4KKyAgICAgKiBAc2VlICNnZXRQdWJsaWNJZAorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHB1YmxpY0lkOworCisKKyAgICAvKioKKyAgICAgKiBAc2VyaWFsIFRoZSBzeXN0ZW0gaWRlbnRpZmllciwgb3IgbnVsbC4KKyAgICAgKiBAc2VlICNnZXRTeXN0ZW1JZAorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHN5c3RlbUlkOworCisKKyAgICAvKioKKyAgICAgKiBAc2VyaWFsIFRoZSBsaW5lIG51bWJlciwgb3IgLTEuCisgICAgICogQHNlZSAjZ2V0TGluZU51bWJlcgorICAgICAqLworICAgIHByaXZhdGUgaW50IGxpbmVOdW1iZXI7CisKKworICAgIC8qKgorICAgICAqIEBzZXJpYWwgVGhlIGNvbHVtbiBudW1iZXIsIG9yIC0xLgorICAgICAqIEBzZWUgI2dldENvbHVtbk51bWJlcgorICAgICAqLworICAgIHByaXZhdGUgaW50IGNvbHVtbk51bWJlcjsKKworfQorCisvLyBlbmQgb2YgU0FYUGFyc2VFeGNlcHRpb24uamF2YQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L1hNTEZpbHRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L1hNTEZpbHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVhMzk5ZmEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvWE1MRmlsdGVyLmphdmEKQEAgLTAsMCArMSw2NSBAQAorLy8gWE1MRmlsdGVyLmphdmEgLSBmaWx0ZXIgU0FYMiBldmVudHMuCisvLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCisvLyBXcml0dGVuIGJ5IERhdmlkIE1lZ2dpbnNvbgorLy8gTk8gV0FSUkFOVFkhICBUaGlzIGNsYXNzIGlzIGluIHRoZSBQdWJsaWMgRG9tYWluLgorLy8gJElkOiBYTUxGaWx0ZXIuamF2YSx2IDEuNiAyMDAyLzAxLzMwIDIxOjEzOjQ4IGRicm93bmVsbCBFeHAgJAorCitwYWNrYWdlIG9yZy54bWwuc2F4OworCisKKy8qKgorICogSW50ZXJmYWNlIGZvciBhbiBYTUwgZmlsdGVyLgorICoKKyAqIDxibG9ja3F1b3RlPgorICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKKyAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KKyAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgorICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+QW4gWE1MIGZpbHRlciBpcyBsaWtlIGFuIFhNTCByZWFkZXIsIGV4Y2VwdCB0aGF0IGl0IG9idGFpbnMgaXRzCisgKiBldmVudHMgZnJvbSBhbm90aGVyIFhNTCByZWFkZXIgcmF0aGVyIHRoYW4gYSBwcmltYXJ5IHNvdXJjZSBsaWtlCisgKiBhbiBYTUwgZG9jdW1lbnQgb3IgZGF0YWJhc2UuICBGaWx0ZXJzIGNhbiBtb2RpZnkgYSBzdHJlYW0gb2YKKyAqIGV2ZW50cyBhcyB0aGV5IHBhc3Mgb24gdG8gdGhlIGZpbmFsIGFwcGxpY2F0aW9uLjwvcD4KKyAqCisgKiA8cD5UaGUgWE1MRmlsdGVySW1wbCBoZWxwZXIgY2xhc3MgcHJvdmlkZXMgYSBjb252ZW5pZW50IGJhc2UKKyAqIGZvciBjcmVhdGluZyBTQVgyIGZpbHRlcnMsIGJ5IHBhc3Npbmcgb24gYWxsIHtAbGluayBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcgorICogRW50aXR5UmVzb2x2ZXJ9LCB7QGxpbmsgb3JnLnhtbC5zYXguRFRESGFuZGxlciBEVERIYW5kbGVyfSwKKyAqIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBDb250ZW50SGFuZGxlcn0gYW5kIHtAbGluayBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIKKyAqIEVycm9ySGFuZGxlcn0gZXZlbnRzIGF1dG9tYXRpY2FsbHkuPC9wPgorICoKKyAqIEBzaW5jZSBTQVggMi4wCisgKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgorICogQHZlcnNpb24gMi4wLjEgKHNheDJyMikKKyAqIEBzZWUgb3JnLnhtbC5zYXguaGVscGVycy5YTUxGaWx0ZXJJbXBsCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgWE1MRmlsdGVyIGV4dGVuZHMgWE1MUmVhZGVyCit7CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHBhcmVudCByZWFkZXIuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBhbGxvd3MgdGhlIGFwcGxpY2F0aW9uIHRvIGxpbmsgdGhlIGZpbHRlciB0bworICAgICAqIGEgcGFyZW50IHJlYWRlciAod2hpY2ggbWF5IGJlIGFub3RoZXIgZmlsdGVyKS4gIFRoZSBhcmd1bWVudAorICAgICAqIG1heSBub3QgYmUgbnVsbC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyZW50IFRoZSBwYXJlbnQgcmVhZGVyLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFBhcmVudCAoWE1MUmVhZGVyIHBhcmVudCk7CisKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgcGFyZW50IHJlYWRlci4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGFsbG93cyB0aGUgYXBwbGljYXRpb24gdG8gcXVlcnkgdGhlIHBhcmVudAorICAgICAqIHJlYWRlciAod2hpY2ggbWF5IGJlIGFub3RoZXIgZmlsdGVyKS4gIEl0IGlzIGdlbmVyYWxseSBhCisgICAgICogYmFkIGlkZWEgdG8gcGVyZm9ybSBhbnkgb3BlcmF0aW9ucyBvbiB0aGUgcGFyZW50IHJlYWRlcgorICAgICAqIGRpcmVjdGx5OiB0aGV5IHNob3VsZCBhbGwgcGFzcyB0aHJvdWdoIHRoaXMgZmlsdGVyLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIHBhcmVudCBmaWx0ZXIsIG9yIG51bGwgaWYgbm9uZSBoYXMgYmVlbiBzZXQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFhNTFJlYWRlciBnZXRQYXJlbnQgKCk7CisKK30KKworLy8gZW5kIG9mIFhNTEZpbHRlci5qYXZhCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvWE1MUmVhZGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvWE1MUmVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmNmZDAyMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9YTUxSZWFkZXIuamF2YQpAQCAtMCwwICsxLDQwNCBAQAorLy8gWE1MUmVhZGVyLmphdmEgLSByZWFkIGFuIFhNTCBkb2N1bWVudC4KKy8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKKy8vIFdyaXR0ZW4gYnkgRGF2aWQgTWVnZ2luc29uCisvLyBOTyBXQVJSQU5UWSEgIFRoaXMgY2xhc3MgaXMgaW4gdGhlIFB1YmxpYyBEb21haW4uCisvLyAkSWQ6IFhNTFJlYWRlci5qYXZhLHYgMS45IDIwMDQvMDQvMjYgMTc6MzQ6MzQgZG1lZ2dpbnNvbiBFeHAgJAorCitwYWNrYWdlIG9yZy54bWwuc2F4OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworCisvKioKKyAqIEludGVyZmFjZSBmb3IgcmVhZGluZyBhbiBYTUwgZG9jdW1lbnQgdXNpbmcgY2FsbGJhY2tzLgorICoKKyAqIDxibG9ja3F1b3RlPgorICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKKyAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KKyAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgorICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+PHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBkZXNwaXRlIGl0cyBuYW1lLCB0aGlzIGludGVyZmFjZSBkb2VzCisgKiA8ZW0+bm90PC9lbT4gZXh0ZW5kIHRoZSBzdGFuZGFyZCBKYXZhIHtAbGluayBqYXZhLmlvLlJlYWRlciBSZWFkZXJ9CisgKiBpbnRlcmZhY2UsIGJlY2F1c2UgcmVhZGluZyBYTUwgaXMgYSBmdW5kYW1lbnRhbGx5IGRpZmZlcmVudCBhY3Rpdml0eQorICogdGhhbiByZWFkaW5nIGNoYXJhY3RlciBkYXRhLjwvcD4KKyAqCisgKiA8cD5YTUxSZWFkZXIgaXMgdGhlIGludGVyZmFjZSB0aGF0IGFuIFhNTCBwYXJzZXIncyBTQVgyIGRyaXZlciBtdXN0CisgKiBpbXBsZW1lbnQuICBUaGlzIGludGVyZmFjZSBhbGxvd3MgYW4gYXBwbGljYXRpb24gdG8gc2V0IGFuZAorICogcXVlcnkgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgaW4gdGhlIHBhcnNlciwgdG8gcmVnaXN0ZXIKKyAqIGV2ZW50IGhhbmRsZXJzIGZvciBkb2N1bWVudCBwcm9jZXNzaW5nLCBhbmQgdG8gaW5pdGlhdGUKKyAqIGEgZG9jdW1lbnQgcGFyc2UuPC9wPgorICoKKyAqIDxwPkFsbCBTQVggaW50ZXJmYWNlcyBhcmUgYXNzdW1lZCB0byBiZSBzeW5jaHJvbm91czogdGhlCisgKiB7QGxpbmsgI3BhcnNlIHBhcnNlfSBtZXRob2RzIG11c3Qgbm90IHJldHVybiB1bnRpbCBwYXJzaW5nCisgKiBpcyBjb21wbGV0ZSwgYW5kIHJlYWRlcnMgbXVzdCB3YWl0IGZvciBhbiBldmVudC1oYW5kbGVyIGNhbGxiYWNrCisgKiB0byByZXR1cm4gYmVmb3JlIHJlcG9ydGluZyB0aGUgbmV4dCBldmVudC48L3A+CisgKgorICogPHA+VGhpcyBpbnRlcmZhY2UgcmVwbGFjZXMgdGhlIChub3cgZGVwcmVjYXRlZCkgU0FYIDEuMCB7QGxpbmsKKyAqIG9yZy54bWwuc2F4LlBhcnNlciBQYXJzZXJ9IGludGVyZmFjZS4gIFRoZSBYTUxSZWFkZXIgaW50ZXJmYWNlCisgKiBjb250YWlucyB0d28gaW1wb3J0YW50IGVuaGFuY2VtZW50cyBvdmVyIHRoZSBvbGQgUGFyc2VyCisgKiBpbnRlcmZhY2UgKGFzIHdlbGwgYXMgc29tZSBtaW5vciBvbmVzKTo8L3A+CisgKgorICogPG9sPgorICogPGxpPml0IGFkZHMgYSBzdGFuZGFyZCB3YXkgdG8gcXVlcnkgYW5kIHNldCBmZWF0dXJlcyBhbmQKKyAqICBwcm9wZXJ0aWVzOyBhbmQ8L2xpPgorICogPGxpPml0IGFkZHMgTmFtZXNwYWNlIHN1cHBvcnQsIHdoaWNoIGlzIHJlcXVpcmVkIGZvciBtYW55CisgKiAgaGlnaGVyLWxldmVsIFhNTCBzdGFuZGFyZHMuPC9saT4KKyAqIDwvb2w+CisgKgorICogPHA+VGhlcmUgYXJlIGFkYXB0ZXJzIGF2YWlsYWJsZSB0byBjb252ZXJ0IGEgU0FYMSBQYXJzZXIgdG8KKyAqIGEgU0FYMiBYTUxSZWFkZXIgYW5kIHZpY2UtdmVyc2EuPC9wPgorICoKKyAqIEBzaW5jZSBTQVggMi4wCisgKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgorICogQHZlcnNpb24gMi4wLjErIChzYXgycjNwcmUxKQorICogQHNlZSBvcmcueG1sLnNheC5YTUxGaWx0ZXIKKyAqIEBzZWUgb3JnLnhtbC5zYXguaGVscGVycy5QYXJzZXJBZGFwdGVyCisgKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuWE1MUmVhZGVyQWRhcHRlcgorICovCitwdWJsaWMgaW50ZXJmYWNlIFhNTFJlYWRlcgoreworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBDb25maWd1cmF0aW9uLgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworICAgIC8qKgorICAgICAqIExvb2sgdXAgdGhlIHZhbHVlIG9mIGEgZmVhdHVyZSBmbGFnLgorICAgICAqCisgICAgICogPHA+VGhlIGZlYXR1cmUgbmFtZSBpcyBhbnkgZnVsbHktcXVhbGlmaWVkIFVSSS4gIEl0IGlzCisgICAgICogcG9zc2libGUgZm9yIGFuIFhNTFJlYWRlciB0byByZWNvZ25pemUgYSBmZWF0dXJlIG5hbWUgYnV0CisgICAgICogdGVtcG9yYXJpbHkgYmUgdW5hYmxlIHRvIHJldHVybiBpdHMgdmFsdWUuCisgICAgICogU29tZSBmZWF0dXJlIHZhbHVlcyBtYXkgYmUgYXZhaWxhYmxlIG9ubHkgaW4gc3BlY2lmaWMKKyAgICAgKiBjb250ZXh0cywgc3VjaCBhcyBiZWZvcmUsIGR1cmluZywgb3IgYWZ0ZXIgYSBwYXJzZS4KKyAgICAgKiBBbHNvLCBzb21lIGZlYXR1cmUgdmFsdWVzIG1heSBub3QgYmUgcHJvZ3JhbW1hdGljYWxseSBhY2Nlc3NpYmxlLgorICAgICAqIChJbiB0aGUgY2FzZSBvZiBhbiBhZGFwdGVyIGZvciBTQVgxIHtAbGluayBQYXJzZXJ9LCB0aGVyZSBpcyBubworICAgICAqIGltcGxlbWVudGF0aW9uLWluZGVwZW5kZW50IHdheSB0byBleHBvc2Ugd2hldGhlciB0aGUgdW5kZXJseWluZworICAgICAqIHBhcnNlciBpcyBwZXJmb3JtaW5nIHZhbGlkYXRpb24sIGV4cGFuZGluZyBleHRlcm5hbCBlbnRpdGllcywKKyAgICAgKiBhbmQgc28gZm9ydGguKSA8L3A+CisgICAgICoKKyAgICAgKiA8cD5BbGwgWE1MUmVhZGVycyBhcmUgcmVxdWlyZWQgdG8gcmVjb2duaXplIHRoZQorICAgICAqIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzIGFuZCB0aGUKKyAgICAgKiBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzIGZlYXR1cmUgbmFtZXMuPC9wPgorICAgICAqCisgICAgICogPHA+VHlwaWNhbCB1c2FnZSBpcyBzb21ldGhpbmcgbGlrZSB0aGlzOjwvcD4KKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogWE1MUmVhZGVyIHIgPSBuZXcgTXlTQVhEcml2ZXIoKTsKKyAgICAgKgorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRyeSB0byBhY3RpdmF0ZSB2YWxpZGF0aW9uCisgICAgICogdHJ5IHsKKyAgICAgKiAgIHIuc2V0RmVhdHVyZSgiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb24iLCB0cnVlKTsKKyAgICAgKiB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAqICAgU3lzdGVtLmVyci5wcmludGxuKCJDYW5ub3QgYWN0aXZhdGUgdmFsaWRhdGlvbi4iKTsKKyAgICAgKiB9CisgICAgICoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZWdpc3RlciBldmVudCBoYW5kbGVycworICAgICAqIHIuc2V0Q29udGVudEhhbmRsZXIobmV3IE15Q29udGVudEhhbmRsZXIoKSk7CisgICAgICogci5zZXRFcnJvckhhbmRsZXIobmV3IE15RXJyb3JIYW5kbGVyKCkpOworICAgICAqCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgLy8gcGFyc2UgdGhlIGZpcnN0IGRvY3VtZW50CisgICAgICogdHJ5IHsKKyAgICAgKiAgIHIucGFyc2UoImh0dHA6Ly93d3cuZm9vLmNvbS9teWRvYy54bWwiKTsKKyAgICAgKiB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICogICBTeXN0ZW0uZXJyLnByaW50bG4oIkkvTyBleGNlcHRpb24gcmVhZGluZyBYTUwgZG9jdW1lbnQiKTsKKyAgICAgKiB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAqICAgU3lzdGVtLmVyci5wcmludGxuKCJYTUwgZXhjZXB0aW9uIHJlYWRpbmcgZG9jdW1lbnQuIik7CisgICAgICogfQorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogPHA+SW1wbGVtZW50b3JzIGFyZSBmcmVlIChhbmQgZW5jb3VyYWdlZCkgdG8gaW52ZW50IHRoZWlyIG93biBmZWF0dXJlcywKKyAgICAgKiB1c2luZyBuYW1lcyBidWlsdCBvbiB0aGVpciBvd24gVVJJcy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZmVhdHVyZSBuYW1lLCB3aGljaCBpcyBhIGZ1bGx5LXF1YWxpZmllZCBVUkkuCisgICAgICogQHJldHVybiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZmVhdHVyZSAodHJ1ZSBvciBmYWxzZSkuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBmZWF0dXJlCisgICAgICogICAgICAgICAgICB2YWx1ZSBjYW4ndCBiZSBhc3NpZ25lZCBvciByZXRyaWV2ZWQuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUKKyAgICAgKiAgICAgICAgICAgIFhNTFJlYWRlciByZWNvZ25pemVzIHRoZSBmZWF0dXJlIG5hbWUgYnV0CisgICAgICogICAgICAgICAgICBjYW5ub3QgZGV0ZXJtaW5lIGl0cyB2YWx1ZSBhdCB0aGlzIHRpbWUuCisgICAgICogQHNlZSAjc2V0RmVhdHVyZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUgKFN0cmluZyBuYW1lKQorICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgZmVhdHVyZSBmbGFnLgorICAgICAqCisgICAgICogPHA+VGhlIGZlYXR1cmUgbmFtZSBpcyBhbnkgZnVsbHktcXVhbGlmaWVkIFVSSS4gIEl0IGlzCisgICAgICogcG9zc2libGUgZm9yIGFuIFhNTFJlYWRlciB0byBleHBvc2UgYSBmZWF0dXJlIHZhbHVlIGJ1dAorICAgICAqIHRvIGJlIHVuYWJsZSB0byBjaGFuZ2UgdGhlIGN1cnJlbnQgdmFsdWUuCisgICAgICogU29tZSBmZWF0dXJlIHZhbHVlcyBtYXkgYmUgaW1tdXRhYmxlIG9yIG11dGFibGUgb25seQorICAgICAqIGluIHNwZWNpZmljIGNvbnRleHRzLCBzdWNoIGFzIGJlZm9yZSwgZHVyaW5nLCBvciBhZnRlcgorICAgICAqIGEgcGFyc2UuPC9wPgorICAgICAqCisgICAgICogPHA+QWxsIFhNTFJlYWRlcnMgYXJlIHJlcXVpcmVkIHRvIHN1cHBvcnQgc2V0dGluZworICAgICAqIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzIHRvIHRydWUgYW5kCisgICAgICogaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZS1wcmVmaXhlcyB0byBmYWxzZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZmVhdHVyZSBuYW1lLCB3aGljaCBpcyBhIGZ1bGx5LXF1YWxpZmllZCBVUkkuCisgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXF1ZXN0ZWQgdmFsdWUgb2YgdGhlIGZlYXR1cmUgKHRydWUgb3IgZmFsc2UpLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBJZiB0aGUgZmVhdHVyZQorICAgICAqICAgICAgICAgICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCisgICAgICogICAgICAgICAgICBYTUxSZWFkZXIgcmVjb2duaXplcyB0aGUgZmVhdHVyZSBuYW1lIGJ1dAorICAgICAqICAgICAgICAgICAgY2Fubm90IHNldCB0aGUgcmVxdWVzdGVkIHZhbHVlLgorICAgICAqIEBzZWUgI2dldEZlYXR1cmUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlIChTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkKKyAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBMb29rIHVwIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LgorICAgICAqCisgICAgICogPHA+VGhlIHByb3BlcnR5IG5hbWUgaXMgYW55IGZ1bGx5LXF1YWxpZmllZCBVUkkuICBJdCBpcworICAgICAqIHBvc3NpYmxlIGZvciBhbiBYTUxSZWFkZXIgdG8gcmVjb2duaXplIGEgcHJvcGVydHkgbmFtZSBidXQKKyAgICAgKiB0ZW1wb3JhcmlseSBiZSB1bmFibGUgdG8gcmV0dXJuIGl0cyB2YWx1ZS4KKyAgICAgKiBTb21lIHByb3BlcnR5IHZhbHVlcyBtYXkgYmUgYXZhaWxhYmxlIG9ubHkgaW4gc3BlY2lmaWMKKyAgICAgKiBjb250ZXh0cywgc3VjaCBhcyBiZWZvcmUsIGR1cmluZywgb3IgYWZ0ZXIgYSBwYXJzZS48L3A+CisgICAgICoKKyAgICAgKiA8cD5YTUxSZWFkZXJzIGFyZSBub3QgcmVxdWlyZWQgdG8gcmVjb2duaXplIGFueSBzcGVjaWZpYworICAgICAqIHByb3BlcnR5IG5hbWVzLCB0aG91Z2ggYW4gaW5pdGlhbCBjb3JlIHNldCBpcyBkb2N1bWVudGVkIGZvcgorICAgICAqIFNBWDIuPC9wPgorICAgICAqCisgICAgICogPHA+SW1wbGVtZW50b3JzIGFyZSBmcmVlIChhbmQgZW5jb3VyYWdlZCkgdG8gaW52ZW50IHRoZWlyIG93biBwcm9wZXJ0aWVzLAorICAgICAqIHVzaW5nIG5hbWVzIGJ1aWx0IG9uIHRoZWlyIG93biBVUklzLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBwcm9wZXJ0eSBuYW1lLCB3aGljaCBpcyBhIGZ1bGx5LXF1YWxpZmllZCBVUkkuCisgICAgICogQHJldHVybiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcHJvcGVydHkuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eQorICAgICAqICAgICAgICAgICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCisgICAgICogICAgICAgICAgICBYTUxSZWFkZXIgcmVjb2duaXplcyB0aGUgcHJvcGVydHkgbmFtZSBidXQKKyAgICAgKiAgICAgICAgICAgIGNhbm5vdCBkZXRlcm1pbmUgaXRzIHZhbHVlIGF0IHRoaXMgdGltZS4KKyAgICAgKiBAc2VlICNzZXRQcm9wZXJ0eQorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkgKFN0cmluZyBuYW1lKQorICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBwcm9wZXJ0eSBuYW1lIGlzIGFueSBmdWxseS1xdWFsaWZpZWQgVVJJLiAgSXQgaXMKKyAgICAgKiBwb3NzaWJsZSBmb3IgYW4gWE1MUmVhZGVyIHRvIHJlY29nbml6ZSBhIHByb3BlcnR5IG5hbWUgYnV0CisgICAgICogdG8gYmUgdW5hYmxlIHRvIGNoYW5nZSB0aGUgY3VycmVudCB2YWx1ZS4KKyAgICAgKiBTb21lIHByb3BlcnR5IHZhbHVlcyBtYXkgYmUgaW1tdXRhYmxlIG9yIG11dGFibGUgb25seQorICAgICAqIGluIHNwZWNpZmljIGNvbnRleHRzLCBzdWNoIGFzIGJlZm9yZSwgZHVyaW5nLCBvciBhZnRlcgorICAgICAqIGEgcGFyc2UuPC9wPgorICAgICAqCisgICAgICogPHA+WE1MUmVhZGVycyBhcmUgbm90IHJlcXVpcmVkIHRvIHJlY29nbml6ZSBzZXR0aW5nCisgICAgICogYW55IHNwZWNpZmljIHByb3BlcnR5IG5hbWVzLCB0aG91Z2ggYSBjb3JlIHNldCBpcyBkZWZpbmVkIGJ5CisgICAgICogU0FYMi48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBhbHNvIHRoZSBzdGFuZGFyZCBtZWNoYW5pc20gZm9yIHNldHRpbmcKKyAgICAgKiBleHRlbmRlZCBoYW5kbGVycy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgcHJvcGVydHkgbmFtZSwgd2hpY2ggaXMgYSBmdWxseS1xdWFsaWZpZWQgVVJJLgorICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVxdWVzdGVkIHZhbHVlIGZvciB0aGUgcHJvcGVydHkuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eQorICAgICAqICAgICAgICAgICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCisgICAgICogICAgICAgICAgICBYTUxSZWFkZXIgcmVjb2duaXplcyB0aGUgcHJvcGVydHkgbmFtZSBidXQKKyAgICAgKiAgICAgICAgICAgIGNhbm5vdCBzZXQgdGhlIHJlcXVlc3RlZCB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eSAoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkKKyAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOworCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIEV2ZW50IGhhbmRsZXJzLgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworICAgIC8qKgorICAgICAqIEFsbG93IGFuIGFwcGxpY2F0aW9uIHRvIHJlZ2lzdGVyIGFuIGVudGl0eSByZXNvbHZlci4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBhcHBsaWNhdGlvbiBkb2VzIG5vdCByZWdpc3RlciBhbiBlbnRpdHkgcmVzb2x2ZXIsCisgICAgICogdGhlIFhNTFJlYWRlciB3aWxsIHBlcmZvcm0gaXRzIG93biBkZWZhdWx0IHJlc29sdXRpb24uPC9wPgorICAgICAqCisgICAgICogPHA+QXBwbGljYXRpb25zIG1heSByZWdpc3RlciBhIG5ldyBvciBkaWZmZXJlbnQgcmVzb2x2ZXIgaW4gdGhlCisgICAgICogbWlkZGxlIG9mIGEgcGFyc2UsIGFuZCB0aGUgU0FYIHBhcnNlciBtdXN0IGJlZ2luIHVzaW5nIHRoZSBuZXcKKyAgICAgKiByZXNvbHZlciBpbW1lZGlhdGVseS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVzb2x2ZXIgVGhlIGVudGl0eSByZXNvbHZlci4KKyAgICAgKiBAc2VlICNnZXRFbnRpdHlSZXNvbHZlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyIChFbnRpdHlSZXNvbHZlciByZXNvbHZlcik7CisKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgY3VycmVudCBlbnRpdHkgcmVzb2x2ZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGVudGl0eSByZXNvbHZlciwgb3IgbnVsbCBpZiBub25lCisgICAgICogICAgICAgICBoYXMgYmVlbiByZWdpc3RlcmVkLgorICAgICAqIEBzZWUgI3NldEVudGl0eVJlc29sdmVyCisgICAgICovCisgICAgcHVibGljIEVudGl0eVJlc29sdmVyIGdldEVudGl0eVJlc29sdmVyICgpOworCisKKyAgICAvKioKKyAgICAgKiBBbGxvdyBhbiBhcHBsaWNhdGlvbiB0byByZWdpc3RlciBhIERURCBldmVudCBoYW5kbGVyLgorICAgICAqCisgICAgICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIGRvZXMgbm90IHJlZ2lzdGVyIGEgRFREIGhhbmRsZXIsIGFsbCBEVEQKKyAgICAgKiBldmVudHMgcmVwb3J0ZWQgYnkgdGhlIFNBWCBwYXJzZXIgd2lsbCBiZSBzaWxlbnRseSBpZ25vcmVkLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkFwcGxpY2F0aW9ucyBtYXkgcmVnaXN0ZXIgYSBuZXcgb3IgZGlmZmVyZW50IGhhbmRsZXIgaW4gdGhlCisgICAgICogbWlkZGxlIG9mIGEgcGFyc2UsIGFuZCB0aGUgU0FYIHBhcnNlciBtdXN0IGJlZ2luIHVzaW5nIHRoZSBuZXcKKyAgICAgKiBoYW5kbGVyIGltbWVkaWF0ZWx5LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBEVEQgaGFuZGxlci4KKyAgICAgKiBAc2VlICNnZXREVERIYW5kbGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlciAoRFRESGFuZGxlciBoYW5kbGVyKTsKKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjdXJyZW50IERURCBoYW5kbGVyLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgY3VycmVudCBEVEQgaGFuZGxlciwgb3IgbnVsbCBpZiBub25lCisgICAgICogICAgICAgICBoYXMgYmVlbiByZWdpc3RlcmVkLgorICAgICAqIEBzZWUgI3NldERUREhhbmRsZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgRFRESGFuZGxlciBnZXREVERIYW5kbGVyICgpOworCisKKyAgICAvKioKKyAgICAgKiBBbGxvdyBhbiBhcHBsaWNhdGlvbiB0byByZWdpc3RlciBhIGNvbnRlbnQgZXZlbnQgaGFuZGxlci4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSBhcHBsaWNhdGlvbiBkb2VzIG5vdCByZWdpc3RlciBhIGNvbnRlbnQgaGFuZGxlciwgYWxsCisgICAgICogY29udGVudCBldmVudHMgcmVwb3J0ZWQgYnkgdGhlIFNBWCBwYXJzZXIgd2lsbCBiZSBzaWxlbnRseQorICAgICAqIGlnbm9yZWQuPC9wPgorICAgICAqCisgICAgICogPHA+QXBwbGljYXRpb25zIG1heSByZWdpc3RlciBhIG5ldyBvciBkaWZmZXJlbnQgaGFuZGxlciBpbiB0aGUKKyAgICAgKiBtaWRkbGUgb2YgYSBwYXJzZSwgYW5kIHRoZSBTQVggcGFyc2VyIG11c3QgYmVnaW4gdXNpbmcgdGhlIG5ldworICAgICAqIGhhbmRsZXIgaW1tZWRpYXRlbHkuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGhhbmRsZXIgVGhlIGNvbnRlbnQgaGFuZGxlci4KKyAgICAgKiBAc2VlICNnZXRDb250ZW50SGFuZGxlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyIChDb250ZW50SGFuZGxlciBoYW5kbGVyKTsKKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjdXJyZW50IGNvbnRlbnQgaGFuZGxlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgY29udGVudCBoYW5kbGVyLCBvciBudWxsIGlmIG5vbmUKKyAgICAgKiAgICAgICAgIGhhcyBiZWVuIHJlZ2lzdGVyZWQuCisgICAgICogQHNlZSAjc2V0Q29udGVudEhhbmRsZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIgKCk7CisKKworICAgIC8qKgorICAgICAqIEFsbG93IGFuIGFwcGxpY2F0aW9uIHRvIHJlZ2lzdGVyIGFuIGVycm9yIGV2ZW50IGhhbmRsZXIuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgYXBwbGljYXRpb24gZG9lcyBub3QgcmVnaXN0ZXIgYW4gZXJyb3IgaGFuZGxlciwgYWxsCisgICAgICogZXJyb3IgZXZlbnRzIHJlcG9ydGVkIGJ5IHRoZSBTQVggcGFyc2VyIHdpbGwgYmUgc2lsZW50bHkKKyAgICAgKiBpZ25vcmVkOyBob3dldmVyLCBub3JtYWwgcHJvY2Vzc2luZyBtYXkgbm90IGNvbnRpbnVlLiAgSXQgaXMKKyAgICAgKiBoaWdobHkgcmVjb21tZW5kZWQgdGhhdCBhbGwgU0FYIGFwcGxpY2F0aW9ucyBpbXBsZW1lbnQgYW4KKyAgICAgKiBlcnJvciBoYW5kbGVyIHRvIGF2b2lkIHVuZXhwZWN0ZWQgYnVncy48L3A+CisgICAgICoKKyAgICAgKiA8cD5BcHBsaWNhdGlvbnMgbWF5IHJlZ2lzdGVyIGEgbmV3IG9yIGRpZmZlcmVudCBoYW5kbGVyIGluIHRoZQorICAgICAqIG1pZGRsZSBvZiBhIHBhcnNlLCBhbmQgdGhlIFNBWCBwYXJzZXIgbXVzdCBiZWdpbiB1c2luZyB0aGUgbmV3CisgICAgICogaGFuZGxlciBpbW1lZGlhdGVseS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgZXJyb3IgaGFuZGxlci4KKyAgICAgKiBAc2VlICNnZXRFcnJvckhhbmRsZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRFcnJvckhhbmRsZXIgKEVycm9ySGFuZGxlciBoYW5kbGVyKTsKKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjdXJyZW50IGVycm9yIGhhbmRsZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGVycm9yIGhhbmRsZXIsIG9yIG51bGwgaWYgbm9uZQorICAgICAqICAgICAgICAgaGFzIGJlZW4gcmVnaXN0ZXJlZC4KKyAgICAgKiBAc2VlICNzZXRFcnJvckhhbmRsZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlciAoKTsKKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBQYXJzaW5nLgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhbiBYTUwgZG9jdW1lbnQuCisgICAgICoKKyAgICAgKiA8cD5UaGUgYXBwbGljYXRpb24gY2FuIHVzZSB0aGlzIG1ldGhvZCB0byBpbnN0cnVjdCB0aGUgWE1MCisgICAgICogcmVhZGVyIHRvIGJlZ2luIHBhcnNpbmcgYW4gWE1MIGRvY3VtZW50IGZyb20gYW55IHZhbGlkIGlucHV0CisgICAgICogc291cmNlIChhIGNoYXJhY3RlciBzdHJlYW0sIGEgYnl0ZSBzdHJlYW0sIG9yIGEgVVJJKS48L3A+CisgICAgICoKKyAgICAgKiA8cD5BcHBsaWNhdGlvbnMgbWF5IG5vdCBpbnZva2UgdGhpcyBtZXRob2Qgd2hpbGUgYSBwYXJzZSBpcyBpbgorICAgICAqIHByb2dyZXNzICh0aGV5IHNob3VsZCBjcmVhdGUgYSBuZXcgWE1MUmVhZGVyIGluc3RlYWQgZm9yIGVhY2gKKyAgICAgKiBuZXN0ZWQgWE1MIGRvY3VtZW50KS4gIE9uY2UgYSBwYXJzZSBpcyBjb21wbGV0ZSwgYW4KKyAgICAgKiBhcHBsaWNhdGlvbiBtYXkgcmV1c2UgdGhlIHNhbWUgWE1MUmVhZGVyIG9iamVjdCwgcG9zc2libHkgd2l0aCBhCisgICAgICogZGlmZmVyZW50IGlucHV0IHNvdXJjZS4KKyAgICAgKiBDb25maWd1cmF0aW9uIG9mIHRoZSBYTUxSZWFkZXIgb2JqZWN0IChzdWNoIGFzIGhhbmRsZXIgYmluZGluZ3MgYW5kCisgICAgICogdmFsdWVzIGVzdGFibGlzaGVkIGZvciBmZWF0dXJlIGZsYWdzIGFuZCBwcm9wZXJ0aWVzKSBpcyB1bmNoYW5nZWQKKyAgICAgKiBieSBjb21wbGV0aW9uIG9mIGEgcGFyc2UsIHVubGVzcyB0aGUgZGVmaW5pdGlvbiBvZiB0aGF0IGFzcGVjdCBvZgorICAgICAqIHRoZSBjb25maWd1cmF0aW9uIGV4cGxpY2l0bHkgc3BlY2lmaWVzIG90aGVyIGJlaGF2aW9yLgorICAgICAqIChGb3IgZXhhbXBsZSwgZmVhdHVyZSBmbGFncyBvciBwcm9wZXJ0aWVzIGV4cG9zaW5nCisgICAgICogY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBkb2N1bWVudCBiZWluZyBwYXJzZWQuKQorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIDxwPkR1cmluZyB0aGUgcGFyc2UsIHRoZSBYTUxSZWFkZXIgd2lsbCBwcm92aWRlIGluZm9ybWF0aW9uCisgICAgICogYWJvdXQgdGhlIFhNTCBkb2N1bWVudCB0aHJvdWdoIHRoZSByZWdpc3RlcmVkIGV2ZW50CisgICAgICogaGFuZGxlcnMuPC9wPgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgc3luY2hyb25vdXM6IGl0IHdpbGwgbm90IHJldHVybiB1bnRpbCBwYXJzaW5nCisgICAgICogaGFzIGVuZGVkLiAgSWYgYSBjbGllbnQgYXBwbGljYXRpb24gd2FudHMgdG8gdGVybWluYXRlCisgICAgICogcGFyc2luZyBlYXJseSwgaXQgc2hvdWxkIHRocm93IGFuIGV4Y2VwdGlvbi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQgVGhlIGlucHV0IHNvdXJjZSBmb3IgdGhlIHRvcC1sZXZlbCBvZiB0aGUKKyAgICAgKiAgICAgICAgWE1MIGRvY3VtZW50LgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQGV4Y2VwdGlvbiBqYXZhLmlvLklPRXhjZXB0aW9uIEFuIElPIGV4Y2VwdGlvbiBmcm9tIHRoZSBwYXJzZXIsCisgICAgICogICAgICAgICAgICBwb3NzaWJseSBmcm9tIGEgYnl0ZSBzdHJlYW0gb3IgY2hhcmFjdGVyIHN0cmVhbQorICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgYnkgdGhlIGFwcGxpY2F0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2UKKyAgICAgKiBAc2VlICNwYXJzZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqIEBzZWUgI3NldEVudGl0eVJlc29sdmVyCisgICAgICogQHNlZSAjc2V0RFRESGFuZGxlcgorICAgICAqIEBzZWUgI3NldENvbnRlbnRIYW5kbGVyCisgICAgICogQHNlZSAjc2V0RXJyb3JIYW5kbGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgcGFyc2UgKElucHV0U291cmNlIGlucHV0KQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhbiBYTUwgZG9jdW1lbnQgZnJvbSBhIHN5c3RlbSBpZGVudGlmaWVyIChVUkkpLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgaXMgYSBzaG9ydGN1dCBmb3IgdGhlIGNvbW1vbiBjYXNlIG9mIHJlYWRpbmcgYQorICAgICAqIGRvY3VtZW50IGZyb20gYSBzeXN0ZW0gaWRlbnRpZmllci4gIEl0IGlzIHRoZSBleGFjdAorICAgICAqIGVxdWl2YWxlbnQgb2YgdGhlIGZvbGxvd2luZzo8L3A+CisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqIHBhcnNlKG5ldyBJbnB1dFNvdXJjZShzeXN0ZW1JZCkpOworICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogPHA+SWYgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGlzIGEgVVJMLCBpdCBtdXN0IGJlIGZ1bGx5IHJlc29sdmVkCisgICAgICogYnkgdGhlIGFwcGxpY2F0aW9uIGJlZm9yZSBpdCBpcyBwYXNzZWQgdG8gdGhlIHBhcnNlci48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIChVUkkpLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQGV4Y2VwdGlvbiBqYXZhLmlvLklPRXhjZXB0aW9uIEFuIElPIGV4Y2VwdGlvbiBmcm9tIHRoZSBwYXJzZXIsCisgICAgICogICAgICAgICAgICBwb3NzaWJseSBmcm9tIGEgYnl0ZSBzdHJlYW0gb3IgY2hhcmFjdGVyIHN0cmVhbQorICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgYnkgdGhlIGFwcGxpY2F0aW9uLgorICAgICAqIEBzZWUgI3BhcnNlKG9yZy54bWwuc2F4LklucHV0U291cmNlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHBhcnNlIChTdHJpbmcgc3lzdGVtSWQpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb247CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9leHQvQXR0cmlidXRlczIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9leHQvQXR0cmlidXRlczIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NWNkNTUxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2V4dC9BdHRyaWJ1dGVzMi5qYXZhCkBAIC0wLDAgKzEsMTMyIEBACisvLyBBdHRyaWJ1dGVzMi5qYXZhIC0gZXh0ZW5kZWQgQXR0cmlidXRlcworLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZworLy8gUHVibGljIERvbWFpbjogbm8gd2FycmFudHkuCisvLyAkSWQ6IEF0dHJpYnV0ZXMyLmphdmEsdiAxLjYgMjAwNC8wMy8wOCAxMzowMTowMCBkbWVnZ2luc29uIEV4cCAkCisKK3BhY2thZ2Ugb3JnLnhtbC5zYXguZXh0OworCitpbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKKworCisvKioKKyAqIFNBWDIgZXh0ZW5zaW9uIHRvIGF1Z21lbnQgdGhlIHBlci1hdHRyaWJ1dGUgaW5mb3JtYXRpb24KKyAqIHByb3ZpZGVkIHRob3VnaCB7QGxpbmsgQXR0cmlidXRlc30uCisgKiBJZiBhbiBpbXBsZW1lbnRhdGlvbiBzdXBwb3J0cyB0aGlzIGV4dGVuc2lvbiwgdGhlIGF0dHJpYnV0ZXMKKyAqIHByb3ZpZGVkIGluIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydEVsZW1lbnQKKyAqIENvbnRlbnRIYW5kbGVyLnN0YXJ0RWxlbWVudCgpIH0gd2lsbCBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UsCisgKiBhbmQgdGhlIDxlbT5odHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvdXNlLWF0dHJpYnV0ZXMyPC9lbT4KKyAqIGZlYXR1cmUgZmxhZyB3aWxsIGhhdmUgdGhlIHZhbHVlIDxlbT50cnVlPC9lbT4uCisgKgorICogPGJsb2NrcXVvdGU+CisgKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQorICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgorICogPC9ibG9ja3F1b3RlPgorICoKKyAqIDxwPiBYTUxSZWFkZXIgaW1wbGVtZW50YXRpb25zIGFyZSBub3QgcmVxdWlyZWQgdG8gc3VwcG9ydCB0aGlzCisgKiBpbmZvcm1hdGlvbiwgYW5kIGl0IGlzIG5vdCBwYXJ0IG9mIGNvcmUtb25seSBTQVgyIGRpc3RyaWJ1dGlvbnMuPC9wPgorICoKKyAqIDxwPk5vdGUgdGhhdCBpZiBhbiBhdHRyaWJ1dGUgd2FzIGRlZmF1bHRlZCAoPGVtPiFpc1NwZWNpZmllZCgpPC9lbT4pCisgKiBpdCB3aWxsIG9mIG5lY2Vzc2l0eSBhbHNvIGhhdmUgYmVlbiBkZWNsYXJlZCAoPGVtPmlzRGVjbGFyZWQoKTwvZW0+KQorICogaW4gdGhlIERURC4KKyAqIFNpbWlsYXJseSBpZiBhbiBhdHRyaWJ1dGUncyB0eXBlIGlzIGFueXRoaW5nIGV4Y2VwdCBDREFUQSwgdGhlbiBpdAorICogbXVzdCBoYXZlIGJlZW4gZGVjbGFyZWQuCisgKiA8L3A+CisgKgorICogQHNpbmNlIFNBWCAyLjAgKGV4dGVuc2lvbnMgMS4xIGFscGhhKQorICogQGF1dGhvciBEYXZpZCBCcm93bmVsbAorICogQHZlcnNpb24gVEJTCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQXR0cmlidXRlczIgZXh0ZW5kcyBBdHRyaWJ1dGVzCit7CisgICAgLyoqCisgICAgICogUmV0dXJucyBmYWxzZSB1bmxlc3MgdGhlIGF0dHJpYnV0ZSB3YXMgZGVjbGFyZWQgaW4gdGhlIERURC4KKyAgICAgKiBUaGlzIGhlbHBzIGRpc3Rpbmd1aXNoIHR3byBraW5kcyBvZiBhdHRyaWJ1dGVzIHRoYXQgU0FYIHJlcG9ydHMKKyAgICAgKiBhcyBDREFUQTogIG9uZXMgdGhhdCB3ZXJlIGRlY2xhcmVkIChhbmQgaGVuY2UgYXJlIHVzdWFsbHkgdmFsaWQpLAorICAgICAqIGFuZCB0aG9zZSB0aGF0IHdlcmUgbm90IChhbmQgd2hpY2ggYXJlIG5ldmVyIHZhbGlkKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlIGluZGV4ICh6ZXJvLWJhc2VkKS4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGF0dHJpYnV0ZSB3YXMgZGVjbGFyZWQgaW4gdGhlIERURCwKKyAgICAgKiAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBXaGVuIHRoZQorICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgaW5kZXggZG9lcyBub3QgaWRlbnRpZnkgYW4gYXR0cmlidXRlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRGVjbGFyZWQgKGludCBpbmRleCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGZhbHNlIHVubGVzcyB0aGUgYXR0cmlidXRlIHdhcyBkZWNsYXJlZCBpbiB0aGUgRFRELgorICAgICAqIFRoaXMgaGVscHMgZGlzdGluZ3Vpc2ggdHdvIGtpbmRzIG9mIGF0dHJpYnV0ZXMgdGhhdCBTQVggcmVwb3J0cworICAgICAqIGFzIENEQVRBOiAgb25lcyB0aGF0IHdlcmUgZGVjbGFyZWQgKGFuZCBoZW5jZSBhcmUgdXN1YWxseSB2YWxpZCksCisgICAgICogYW5kIHRob3NlIHRoYXQgd2VyZSBub3QgKGFuZCB3aGljaCBhcmUgbmV2ZXIgdmFsaWQpLgorICAgICAqCisgICAgICogQHBhcmFtIHFOYW1lIFRoZSBYTUwgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGF0dHJpYnV0ZSB3YXMgZGVjbGFyZWQgaW4gdGhlIERURCwKKyAgICAgKiAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIHRoZQorICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgbmFtZSBkb2VzIG5vdCBpZGVudGlmeSBhbiBhdHRyaWJ1dGUuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNEZWNsYXJlZCAoU3RyaW5nIHFOYW1lKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgZmFsc2UgdW5sZXNzIHRoZSBhdHRyaWJ1dGUgd2FzIGRlY2xhcmVkIGluIHRoZSBEVEQuCisgICAgICogVGhpcyBoZWxwcyBkaXN0aW5ndWlzaCB0d28ga2luZHMgb2YgYXR0cmlidXRlcyB0aGF0IFNBWCByZXBvcnRzCisgICAgICogYXMgQ0RBVEE6ICBvbmVzIHRoYXQgd2VyZSBkZWNsYXJlZCAoYW5kIGhlbmNlIGFyZSB1c3VhbGx5IHZhbGlkKSwKKyAgICAgKiBhbmQgdGhvc2UgdGhhdCB3ZXJlIG5vdCAoYW5kIHdoaWNoIGFyZSBuZXZlciB2YWxpZCkuCisgICAgICoKKyAgICAgKiA8cD5SZW1lbWJlciB0aGF0IHNpbmNlIERURHMgZG8gbm90ICJ1bmRlcnN0YW5kIiBuYW1lc3BhY2VzLCB0aGUKKyAgICAgKiBuYW1lc3BhY2UgVVJJIGFzc29jaWF0ZWQgd2l0aCBhbiBhdHRyaWJ1dGUgbWF5IG5vdCBoYXZlIGNvbWUgZnJvbQorICAgICAqIHRoZSBEVEQuICBUaGUgZGVjbGFyYXRpb24gd2lsbCBoYXZlIGFwcGxpZWQgdG8gdGhlIGF0dHJpYnV0ZSdzCisgICAgICogPGVtPnFOYW1lPC9lbT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmCisgICAgICogICAgICAgIHRoZSBuYW1lIGhhcyBubyBOYW1lc3BhY2UgVVJJLgorICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGF0dHJpYnV0ZSdzIGxvY2FsIG5hbWUuCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBhdHRyaWJ1dGUgd2FzIGRlY2xhcmVkIGluIHRoZSBEVEQsCisgICAgICogICAgICAgIGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gV2hlbiB0aGUKKyAgICAgKiAgICAgICAgICAgIHN1cHBsaWVkIG5hbWVzIGRvIG5vdCBpZGVudGlmeSBhbiBhdHRyaWJ1dGUuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNEZWNsYXJlZCAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgdW5sZXNzIHRoZSBhdHRyaWJ1dGUgdmFsdWUgd2FzIHByb3ZpZGVkCisgICAgICogYnkgRFREIGRlZmF1bHRpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleCAoemVyby1iYXNlZCkuCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSB2YWx1ZSB3YXMgZm91bmQgaW4gdGhlIFhNTCB0ZXh0LAorICAgICAqICAgICAgICBmYWxzZSBpZiB0aGUgdmFsdWUgd2FzIHByb3ZpZGVkIGJ5IERURCBkZWZhdWx0aW5nLgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBXaGVuIHRoZQorICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgaW5kZXggZG9lcyBub3QgaWRlbnRpZnkgYW4gYXR0cmlidXRlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzU3BlY2lmaWVkIChpbnQgaW5kZXgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIHVubGVzcyB0aGUgYXR0cmlidXRlIHZhbHVlIHdhcyBwcm92aWRlZAorICAgICAqIGJ5IERURCBkZWZhdWx0aW5nLgorICAgICAqCisgICAgICogPHA+UmVtZW1iZXIgdGhhdCBzaW5jZSBEVERzIGRvIG5vdCAidW5kZXJzdGFuZCIgbmFtZXNwYWNlcywgdGhlCisgICAgICogbmFtZXNwYWNlIFVSSSBhc3NvY2lhdGVkIHdpdGggYW4gYXR0cmlidXRlIG1heSBub3QgaGF2ZSBjb21lIGZyb20KKyAgICAgKiB0aGUgRFRELiAgVGhlIGRlY2xhcmF0aW9uIHdpbGwgaGF2ZSBhcHBsaWVkIHRvIHRoZSBhdHRyaWJ1dGUncworICAgICAqIDxlbT5xTmFtZTwvZW0+LgorICAgICAqCisgICAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZgorICAgICAqICAgICAgICB0aGUgbmFtZSBoYXMgbm8gTmFtZXNwYWNlIFVSSS4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBhdHRyaWJ1dGUncyBsb2NhbCBuYW1lLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdmFsdWUgd2FzIGZvdW5kIGluIHRoZSBYTUwgdGV4dCwKKyAgICAgKiAgICAgICAgZmFsc2UgaWYgdGhlIHZhbHVlIHdhcyBwcm92aWRlZCBieSBEVEQgZGVmYXVsdGluZy4KKyAgICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gV2hlbiB0aGUKKyAgICAgKiAgICAgICAgICAgIHN1cHBsaWVkIG5hbWVzIGRvIG5vdCBpZGVudGlmeSBhbiBhdHRyaWJ1dGUuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNTcGVjaWZpZWQgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIHVubGVzcyB0aGUgYXR0cmlidXRlIHZhbHVlIHdhcyBwcm92aWRlZAorICAgICAqIGJ5IERURCBkZWZhdWx0aW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHFOYW1lIFRoZSBYTUwgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHZhbHVlIHdhcyBmb3VuZCBpbiB0aGUgWE1MIHRleHQsCisgICAgICogICAgICAgIGZhbHNlIGlmIHRoZSB2YWx1ZSB3YXMgcHJvdmlkZWQgYnkgRFREIGRlZmF1bHRpbmcuCisgICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gdGhlCisgICAgICogICAgICAgICAgICBzdXBwbGllZCBuYW1lIGRvZXMgbm90IGlkZW50aWZ5IGFuIGF0dHJpYnV0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NwZWNpZmllZCAoU3RyaW5nIHFOYW1lKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9leHQvQXR0cmlidXRlczJJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvZXh0L0F0dHJpYnV0ZXMySW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUyZmExZTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvZXh0L0F0dHJpYnV0ZXMySW1wbC5qYXZhCkBAIC0wLDAgKzEsMzE0IEBACisvLyBBdHRyaWJ1dGVzMkltcGwuamF2YSAtIGV4dGVuZGVkIEF0dHJpYnV0ZXNJbXBsCisvLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCisvLyBQdWJsaWMgRG9tYWluOiBubyB3YXJyYW50eS4KKy8vICRJZDogQXR0cmlidXRlczJJbXBsLmphdmEsdiAxLjUgMjAwNC8wMy8wOCAxMzowMTowMSBkbWVnZ2luc29uIEV4cCAkCisKK3BhY2thZ2Ugb3JnLnhtbC5zYXguZXh0OworCitpbXBvcnQgbGliY29yZS51dGlsLkVtcHR5QXJyYXk7CitpbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKK2ltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZXNJbXBsOworCisvKioKKyAqIFNBWDIgZXh0ZW5zaW9uIGhlbHBlciBmb3IgYWRkaXRpb25hbCBBdHRyaWJ1dGVzIGluZm9ybWF0aW9uLAorICogaW1wbGVtZW50aW5nIHRoZSB7QGxpbmsgQXR0cmlidXRlczJ9IGludGVyZmFjZS4KKyAqCisgKiA8YmxvY2txdW90ZT4KKyAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCisgKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+CisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+VGhpcyBpcyBub3QgcGFydCBvZiBjb3JlLW9ubHkgU0FYMiBkaXN0cmlidXRpb25zLjwvcD4KKyAqCisgKiA8cD5UaGUgPGVtPnNwZWNpZmllZDwvZW0+IGZsYWcgZm9yIGVhY2ggYXR0cmlidXRlIHdpbGwgYWx3YXlzCisgKiBiZSB0cnVlLCB1bmxlc3MgaXQgaGFzIGJlZW4gc2V0IHRvIGZhbHNlIGluIHRoZSBjb3B5IGNvbnN0cnVjdG9yCisgKiBvciB1c2luZyB7QGxpbmsgI3NldFNwZWNpZmllZH0uCisgKiBTaW1pbGFybHksIHRoZSA8ZW0+ZGVjbGFyZWQ8L2VtPiBmbGFnIGZvciBlYWNoIGF0dHJpYnV0ZSB3aWxsCisgKiBhbHdheXMgYmUgZmFsc2UsIGV4Y2VwdCBmb3IgZGVmYXVsdGVkIGF0dHJpYnV0ZXMgKDxlbT5zcGVjaWZpZWQ8L2VtPgorICogaXMgZmFsc2UpLCBub24tQ0RBVEEgYXR0cmlidXRlcywgb3Igd2hlbiBpdCBpcyBzZXQgdG8gdHJ1ZSB1c2luZworICoge0BsaW5rICNzZXREZWNsYXJlZH0uCisgKiBJZiB5b3UgY2hhbmdlIGFuIGF0dHJpYnV0ZSdzIHR5cGUgYnkgaGFuZCwgeW91IG1heSBuZWVkIHRvIG1vZGlmeQorICogaXRzIDxlbT5kZWNsYXJlZDwvZW0+IGZsYWcgdG8gbWF0Y2guCisgKiA8L3A+CisgKgorICogQHNpbmNlIFNBWCAyLjAgKGV4dGVuc2lvbnMgMS4xIGFscGhhKQorICogQGF1dGhvciBEYXZpZCBCcm93bmVsbAorICogQHZlcnNpb24gVEJTCisgKi8KK3B1YmxpYyBjbGFzcyBBdHRyaWJ1dGVzMkltcGwgZXh0ZW5kcyBBdHRyaWJ1dGVzSW1wbCBpbXBsZW1lbnRzIEF0dHJpYnV0ZXMyCit7CisgICAgcHJpdmF0ZSBib29sZWFuW10gZGVjbGFyZWQ7CisgICAgcHJpdmF0ZSBib29sZWFuW10gc3BlY2lmaWVkOworCisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBuZXcsIGVtcHR5IEF0dHJpYnV0ZXMySW1wbCBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIEF0dHJpYnV0ZXMySW1wbCAoKSB7CisgICAgICAgIGRlY2xhcmVkID0gRW1wdHlBcnJheS5CT09MRUFOOworICAgICAgICBzcGVjaWZpZWQgPSBFbXB0eUFycmF5LkJPT0xFQU47CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBDb3B5IGFuIGV4aXN0aW5nIEF0dHJpYnV0ZXMgb3IgQXR0cmlidXRlczIgb2JqZWN0LgorICAgICAqIElmIHRoZSBvYmplY3QgaW1wbGVtZW50cyBBdHRyaWJ1dGVzMiwgdmFsdWVzIG9mIHRoZQorICAgICAqIDxlbT5zcGVjaWZpZWQ8L2VtPiBhbmQgPGVtPmRlY2xhcmVkPC9lbT4gZmxhZ3MgZm9yIGVhY2gKKyAgICAgKiBhdHRyaWJ1dGUgYXJlIGNvcGllZC4KKyAgICAgKiBPdGhlcndpc2UgdGhlIGZsYWcgdmFsdWVzIGFyZSBkZWZhdWx0ZWQgdG8gYXNzdW1lIG5vIERURCB3YXMgdXNlZCwKKyAgICAgKiB1bmxlc3MgdGhlcmUgaXMgZXZpZGVuY2UgdG8gdGhlIGNvbnRyYXJ5IChzdWNoIGFzIGF0dHJpYnV0ZXMgd2l0aAorICAgICAqIHR5cGUgb3RoZXIgdGhhbiBDREFUQSwgd2hpY2ggbXVzdCBoYXZlIGJlZW4gPGVtPmRlY2xhcmVkPC9lbT4pLgorICAgICAqCisgICAgICogPHA+VGhpcyBjb25zdHJ1Y3RvciBpcyBlc3BlY2lhbGx5IHVzZWZ1bCBpbnNpZGUgYQorICAgICAqIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydEVsZW1lbnQgc3RhcnRFbGVtZW50fSBldmVudC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gYXR0cyBUaGUgZXhpc3RpbmcgQXR0cmlidXRlcyBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIEF0dHJpYnV0ZXMySW1wbCAoQXR0cmlidXRlcyBhdHRzKQorICAgIHsKKyAgICBzdXBlciAoYXR0cyk7CisgICAgfQorCisKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIEltcGxlbWVudGF0aW9uIG9mIEF0dHJpYnV0ZXMyCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUncyAiZGVjbGFyZWQiIGZsYWcuCisgICAgICovCisgICAgLy8gamF2YWRvYyBtb3N0bHkgZnJvbSBpbnRlcmZhY2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RlY2xhcmVkIChpbnQgaW5kZXgpCisgICAgeworICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gZ2V0TGVuZ3RoICgpKQorICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICgKKyAgICAgICAgIk5vIGF0dHJpYnV0ZSBhdCBpbmRleDogIiArIGluZGV4KTsKKyAgICByZXR1cm4gZGVjbGFyZWQgW2luZGV4XTsKKyAgICB9CisKKworICAgIC8qCisgICAgICogUmV0dXJucyB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlJ3MgImRlY2xhcmVkIiBmbGFnLgorICAgICAqLworICAgIC8vIGphdmFkb2MgbW9zdGx5IGZyb20gaW50ZXJmYWNlCisgICAgcHVibGljIGJvb2xlYW4gaXNEZWNsYXJlZCAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkKKyAgICB7CisgICAgaW50IGluZGV4ID0gZ2V0SW5kZXggKHVyaSwgbG9jYWxOYW1lKTsKKworICAgIGlmIChpbmRleCA8IDApCisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gKAorICAgICAgICAiTm8gc3VjaCBhdHRyaWJ1dGU6IGxvY2FsPSIgKyBsb2NhbE5hbWUKKyAgICAgICAgKyAiLCBuYW1lc3BhY2U9IiArIHVyaSk7CisgICAgcmV0dXJuIGRlY2xhcmVkIFtpbmRleF07CisgICAgfQorCisKKyAgICAvKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSdzICJkZWNsYXJlZCIgZmxhZy4KKyAgICAgKi8KKyAgICAvLyBqYXZhZG9jIG1vc3RseSBmcm9tIGludGVyZmFjZQorICAgIHB1YmxpYyBib29sZWFuIGlzRGVjbGFyZWQgKFN0cmluZyBxTmFtZSkKKyAgICB7CisgICAgaW50IGluZGV4ID0gZ2V0SW5kZXggKHFOYW1lKTsKKworICAgIGlmIChpbmRleCA8IDApCisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gKAorICAgICAgICAiTm8gc3VjaCBhdHRyaWJ1dGU6ICIgKyBxTmFtZSk7CisgICAgcmV0dXJuIGRlY2xhcmVkIFtpbmRleF07CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSdzICJzcGVjaWZpZWQiIGZsYWcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleCAoemVyby1iYXNlZCkuCisgICAgICogQHJldHVybiBjdXJyZW50IGZsYWcgdmFsdWUKKyAgICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gV2hlbiB0aGUKKyAgICAgKiAgICAgICAgICAgIHN1cHBsaWVkIGluZGV4IGRvZXMgbm90IGlkZW50aWZ5IGFuIGF0dHJpYnV0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NwZWNpZmllZCAoaW50IGluZGV4KQorICAgIHsKKyAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGdldExlbmd0aCAoKSkKKyAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiAoCisgICAgICAgICJObyBhdHRyaWJ1dGUgYXQgaW5kZXg6ICIgKyBpbmRleCk7CisgICAgcmV0dXJuIHNwZWNpZmllZCBbaW5kZXhdOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY3VycmVudCB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUncyAic3BlY2lmaWVkIiBmbGFnLgorICAgICAqCisgICAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZgorICAgICAqICAgICAgICB0aGUgbmFtZSBoYXMgbm8gTmFtZXNwYWNlIFVSSS4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBhdHRyaWJ1dGUncyBsb2NhbCBuYW1lLgorICAgICAqIEByZXR1cm4gY3VycmVudCBmbGFnIHZhbHVlCisgICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gdGhlCisgICAgICogICAgICAgICAgICBzdXBwbGllZCBuYW1lcyBkbyBub3QgaWRlbnRpZnkgYW4gYXR0cmlidXRlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzU3BlY2lmaWVkIChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKQorICAgIHsKKyAgICBpbnQgaW5kZXggPSBnZXRJbmRleCAodXJpLCBsb2NhbE5hbWUpOworCisgICAgaWYgKGluZGV4IDwgMCkKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAoCisgICAgICAgICJObyBzdWNoIGF0dHJpYnV0ZTogbG9jYWw9IiArIGxvY2FsTmFtZQorICAgICAgICArICIsIG5hbWVzcGFjZT0iICsgdXJpKTsKKyAgICByZXR1cm4gc3BlY2lmaWVkIFtpbmRleF07CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSdzICJzcGVjaWZpZWQiIGZsYWcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIFhNTCBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLgorICAgICAqIEByZXR1cm4gY3VycmVudCBmbGFnIHZhbHVlCisgICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gdGhlCisgICAgICogICAgICAgICAgICBzdXBwbGllZCBuYW1lIGRvZXMgbm90IGlkZW50aWZ5IGFuIGF0dHJpYnV0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NwZWNpZmllZCAoU3RyaW5nIHFOYW1lKQorICAgIHsKKyAgICBpbnQgaW5kZXggPSBnZXRJbmRleCAocU5hbWUpOworCisgICAgaWYgKGluZGV4IDwgMCkKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAoCisgICAgICAgICJObyBzdWNoIGF0dHJpYnV0ZTogIiArIHFOYW1lKTsKKyAgICByZXR1cm4gc3BlY2lmaWVkIFtpbmRleF07CisgICAgfQorCisKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIE1hbmlwdWxhdG9ycworICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworICAgIC8qKgorICAgICAqIENvcHkgYW4gZW50aXJlIEF0dHJpYnV0ZXMgb2JqZWN0LiAgVGhlICJzcGVjaWZpZWQiIGZsYWdzIGFyZQorICAgICAqIGFzc2lnbmVkIGFzIHRydWUsIGFuZCAiZGVjbGFyZWQiIGZsYWdzIGFzIGZhbHNlIChleGNlcHQgd2hlbgorICAgICAqIGFuIGF0dHJpYnV0ZSdzIHR5cGUgaXMgbm90IENEQVRBKSwKKyAgICAgKiB1bmxlc3MgdGhlIG9iamVjdCBpcyBhbiBBdHRyaWJ1dGVzMiBvYmplY3QuCisgICAgICogSW4gdGhhdCBjYXNlIHRob3NlIGZsYWcgdmFsdWVzIGFyZSBhbGwgY29waWVkLgorICAgICAqCisgICAgICogQHBhcmFtIGF0dHMgVGhlIGF0dHJpYnV0ZXMgdG8gY29weS4KKyAgICAgKgorICAgICAqIEBzZWUgQXR0cmlidXRlc0ltcGwjc2V0QXR0cmlidXRlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZXMgKEF0dHJpYnV0ZXMgYXR0cykKKyAgICB7CisgICAgaW50IGxlbmd0aCA9IGF0dHMuZ2V0TGVuZ3RoICgpOworCisgICAgc3VwZXIuc2V0QXR0cmlidXRlcyAoYXR0cyk7CisgICAgZGVjbGFyZWQgPSBuZXcgYm9vbGVhbiBbbGVuZ3RoXTsKKyAgICBzcGVjaWZpZWQgPSBuZXcgYm9vbGVhbiBbbGVuZ3RoXTsKKworICAgIGlmIChhdHRzIGluc3RhbmNlb2YgQXR0cmlidXRlczIpIHsKKyAgICAgICAgQXR0cmlidXRlczIgICAgYTIgPSAoQXR0cmlidXRlczIpIGF0dHM7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgZGVjbGFyZWQgW2ldID0gYTIuaXNEZWNsYXJlZCAoaSk7CisgICAgICAgIHNwZWNpZmllZCBbaV0gPSBhMi5pc1NwZWNpZmllZCAoaSk7CisgICAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgIGRlY2xhcmVkIFtpXSA9ICEiQ0RBVEEiLmVxdWFscyAoYXR0cy5nZXRUeXBlIChpKSk7CisgICAgICAgIHNwZWNpZmllZCBbaV0gPSB0cnVlOworICAgICAgICB9CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogQWRkIGFuIGF0dHJpYnV0ZSB0byB0aGUgZW5kIG9mIHRoZSBsaXN0LCBzZXR0aW5nIGl0cworICAgICAqICJzcGVjaWZpZWQiIGZsYWcgdG8gdHJ1ZS4gIFRvIHNldCB0aGF0IGZsYWcncyB2YWx1ZQorICAgICAqIHRvIGZhbHNlLCB1c2Uge0BsaW5rICNzZXRTcGVjaWZpZWR9LgorICAgICAqCisgICAgICogPHA+VW5sZXNzIHRoZSBhdHRyaWJ1dGUgPGVtPnR5cGU8L2VtPiBpcyBDREFUQSwgdGhpcyBhdHRyaWJ1dGUKKyAgICAgKiBpcyBtYXJrZWQgYXMgYmVpbmcgZGVjbGFyZWQgaW4gdGhlIERURC4gIFRvIHNldCB0aGF0IGZsYWcncyB2YWx1ZQorICAgICAqIHRvIHRydWUgZm9yIENEQVRBIGF0dHJpYnV0ZXMsIHVzZSB7QGxpbmsgI3NldERlY2xhcmVkfS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYKKyAgICAgKiAgICAgICAgbm9uZSBpcyBhdmFpbGFibGUgb3IgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90CisgICAgICogICAgICAgIGJlaW5nIHBlcmZvcm1lZC4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmCisgICAgICogICAgICAgIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCisgICAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLCBvciB0aGUgZW1wdHkgc3RyaW5nCisgICAgICogICAgICAgIGlmIHF1YWxpZmllZCBuYW1lcyBhcmUgbm90IGF2YWlsYWJsZS4KKyAgICAgKiBAcGFyYW0gdHlwZSBUaGUgYXR0cmlidXRlIHR5cGUgYXMgYSBzdHJpbmcuCisgICAgICogQHBhcmFtIHZhbHVlIFRoZSBhdHRyaWJ1dGUgdmFsdWUuCisgICAgICoKKyAgICAgKiBAc2VlIEF0dHJpYnV0ZXNJbXBsI2FkZEF0dHJpYnV0ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZSAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lLAorICAgICAgICAgICAgICAgICAgU3RyaW5nIHR5cGUsIFN0cmluZyB2YWx1ZSkKKyAgICB7CisgICAgc3VwZXIuYWRkQXR0cmlidXRlICh1cmksIGxvY2FsTmFtZSwgcU5hbWUsIHR5cGUsIHZhbHVlKTsKKworICAgIGludCBsZW5ndGggPSBnZXRMZW5ndGggKCk7CisKKyAgICBpZiAobGVuZ3RoID4gc3BlY2lmaWVkLmxlbmd0aCkgeworICAgICAgICBib29sZWFuW10gbmV3RmxhZ3MgPSBuZXcgYm9vbGVhbiBbbGVuZ3RoXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weSAoZGVjbGFyZWQsIDAsIG5ld0ZsYWdzLCAwLCBkZWNsYXJlZC5sZW5ndGgpOworICAgICAgICBkZWNsYXJlZCA9IG5ld0ZsYWdzOworCisgICAgICAgIG5ld0ZsYWdzID0gbmV3IGJvb2xlYW4gW2xlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkgKHNwZWNpZmllZCwgMCwgbmV3RmxhZ3MsIDAsIHNwZWNpZmllZC5sZW5ndGgpOworICAgICAgICBzcGVjaWZpZWQgPSBuZXdGbGFnczsKKyAgICB9CisKKyAgICBzcGVjaWZpZWQgW2xlbmd0aCAtIDFdID0gdHJ1ZTsKKyAgICBkZWNsYXJlZCBbbGVuZ3RoIC0gMV0gPSAhIkNEQVRBIi5lcXVhbHMgKHR5cGUpOworICAgIH0KKworCisgICAgLy8gamF2YWRvYyBlbnRpcmVseSBmcm9tIHN1cGVyY2xhc3MKKyAgICBwdWJsaWMgdm9pZCByZW1vdmVBdHRyaWJ1dGUgKGludCBpbmRleCkKKyAgICB7CisgICAgaW50IG9yaWdNYXggPSBnZXRMZW5ndGggKCkgLSAxOworCisgICAgc3VwZXIucmVtb3ZlQXR0cmlidXRlIChpbmRleCk7CisgICAgaWYgKGluZGV4ICE9IG9yaWdNYXgpIHsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weSAoZGVjbGFyZWQsIGluZGV4ICsgMSwgZGVjbGFyZWQsIGluZGV4LAorICAgICAgICAgICAgb3JpZ01heCAtIGluZGV4KTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weSAoc3BlY2lmaWVkLCBpbmRleCArIDEsIHNwZWNpZmllZCwgaW5kZXgsCisgICAgICAgICAgICBvcmlnTWF4IC0gaW5kZXgpOworICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEFzc2lnbiBhIHZhbHVlIHRvIHRoZSAiZGVjbGFyZWQiIGZsYWcgb2YgYSBzcGVjaWZpYyBhdHRyaWJ1dGUuCisgICAgICogVGhpcyBpcyBub3JtYWxseSBuZWVkZWQgb25seSBmb3IgYXR0cmlidXRlcyBvZiB0eXBlIENEQVRBLAorICAgICAqIGluY2x1ZGluZyBhdHRyaWJ1dGVzIHdob3NlIHR5cGUgaXMgY2hhbmdlZCB0byBvciBmcm9tIENEQVRBLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlICh6ZXJvLWJhc2VkKS4KKyAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRlc2lyZWQgZmxhZyB2YWx1ZS4KKyAgICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gV2hlbiB0aGUKKyAgICAgKiAgICAgICAgICAgIHN1cHBsaWVkIGluZGV4IGRvZXMgbm90IGlkZW50aWZ5IGFuIGF0dHJpYnV0ZS4KKyAgICAgKiBAc2VlICNzZXRUeXBlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGVjbGFyZWQgKGludCBpbmRleCwgYm9vbGVhbiB2YWx1ZSkKKyAgICB7CisgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBnZXRMZW5ndGggKCkpCisgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gKAorICAgICAgICAiTm8gYXR0cmlidXRlIGF0IGluZGV4OiAiICsgaW5kZXgpOworICAgIGRlY2xhcmVkIFtpbmRleF0gPSB2YWx1ZTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEFzc2lnbiBhIHZhbHVlIHRvIHRoZSAic3BlY2lmaWVkIiBmbGFnIG9mIGEgc3BlY2lmaWMgYXR0cmlidXRlLgorICAgICAqIFRoaXMgaXMgdGhlIG9ubHkgd2F5IHRoaXMgZmxhZyBjYW4gYmUgY2xlYXJlZCwgZXhjZXB0IGNsZWFyaW5nCisgICAgICogYnkgaW5pdGlhbGl6YXRpb24gd2l0aCB0aGUgY29weSBjb25zdHJ1Y3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGF0dHJpYnV0ZSAoemVyby1iYXNlZCkuCisgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkZXNpcmVkIGZsYWcgdmFsdWUuCisgICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIFdoZW4gdGhlCisgICAgICogICAgICAgICAgICBzdXBwbGllZCBpbmRleCBkb2VzIG5vdCBpZGVudGlmeSBhbiBhdHRyaWJ1dGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3BlY2lmaWVkIChpbnQgaW5kZXgsIGJvb2xlYW4gdmFsdWUpCisgICAgeworICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gZ2V0TGVuZ3RoICgpKQorICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICgKKyAgICAgICAgIk5vIGF0dHJpYnV0ZSBhdCBpbmRleDogIiArIGluZGV4KTsKKyAgICBzcGVjaWZpZWQgW2luZGV4XSA9IHZhbHVlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9leHQvRGVjbEhhbmRsZXIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9leHQvRGVjbEhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MWI3MjRiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2V4dC9EZWNsSGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsMTQ2IEBACisvLyBEZWNsSGFuZGxlci5qYXZhIC0gT3B0aW9uYWwgaGFuZGxlciBmb3IgRFREIGRlY2xhcmF0aW9uIGV2ZW50cy4KKy8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKKy8vIFB1YmxpYyBEb21haW46IG5vIHdhcnJhbnR5LgorLy8gJElkOiBEZWNsSGFuZGxlci5qYXZhLHYgMS42IDIwMDQvMDQvMjIgMTM6Mjg6NDkgZG1lZ2dpbnNvbiBFeHAgJAorCitwYWNrYWdlIG9yZy54bWwuc2F4LmV4dDsKKworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKKworCisvKioKKyAqIFNBWDIgZXh0ZW5zaW9uIGhhbmRsZXIgZm9yIERURCBkZWNsYXJhdGlvbiBldmVudHMuCisgKgorICogPGJsb2NrcXVvdGU+CisgKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQorICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgorICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+CisgKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KKyAqIDwvYmxvY2txdW90ZT4KKyAqCisgKiA8cD5UaGlzIGlzIGFuIG9wdGlvbmFsIGV4dGVuc2lvbiBoYW5kbGVyIGZvciBTQVgyIHRvIHByb3ZpZGUgbW9yZQorICogY29tcGxldGUgaW5mb3JtYXRpb24gYWJvdXQgRFREIGRlY2xhcmF0aW9ucyBpbiBhbiBYTUwgZG9jdW1lbnQuCisgKiBYTUwgcmVhZGVycyBhcmUgbm90IHJlcXVpcmVkIHRvIHJlY29nbml6ZSB0aGlzIGhhbmRsZXIsIGFuZCBpdAorICogaXMgbm90IHBhcnQgb2YgY29yZS1vbmx5IFNBWDIgZGlzdHJpYnV0aW9ucy48L3A+CisgKgorICogPHA+Tm90ZSB0aGF0IGRhdGEtcmVsYXRlZCBEVEQgZGVjbGFyYXRpb25zICh1bnBhcnNlZCBlbnRpdGllcyBhbmQKKyAqIG5vdGF0aW9ucykgYXJlIGFscmVhZHkgcmVwb3J0ZWQgdGhyb3VnaCB0aGUge0BsaW5rCisgKiBvcmcueG1sLnNheC5EVERIYW5kbGVyIERUREhhbmRsZXJ9IGludGVyZmFjZS48L3A+CisgKgorICogPHA+SWYgeW91IGFyZSB1c2luZyB0aGUgZGVjbGFyYXRpb24gaGFuZGxlciB0b2dldGhlciB3aXRoIGEgbGV4aWNhbAorICogaGFuZGxlciwgYWxsIG9mIHRoZSBldmVudHMgd2lsbCBvY2N1ciBiZXR3ZWVuIHRoZQorICoge0BsaW5rIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciNzdGFydERURCBzdGFydERURH0gYW5kIHRoZQorICoge0BsaW5rIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciNlbmREVEQgZW5kRFREfSBldmVudHMuPC9wPgorICoKKyAqIDxwPlRvIHNldCB0aGUgRGVjbEhhbmRsZXIgZm9yIGFuIFhNTCByZWFkZXIsIHVzZSB0aGUKKyAqIHtAbGluayBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0UHJvcGVydHkgc2V0UHJvcGVydHl9IG1ldGhvZAorICogd2l0aCB0aGUgcHJvcGVydHkgbmFtZQorICogPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvZGVjbGFyYXRpb24taGFuZGxlcjwvY29kZT4KKyAqIGFuZCBhbiBvYmplY3QgaW1wbGVtZW50aW5nIHRoaXMgaW50ZXJmYWNlIChvciBudWxsKSBhcyB0aGUgdmFsdWUuCisgKiBJZiB0aGUgcmVhZGVyIGRvZXMgbm90IHJlcG9ydCBkZWNsYXJhdGlvbiBldmVudHMsIGl0IHdpbGwgdGhyb3cgYQorICoge0BsaW5rIG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbn0KKyAqIHdoZW4geW91IGF0dGVtcHQgdG8gcmVnaXN0ZXIgdGhlIGhhbmRsZXIuPC9wPgorICoKKyAqIEBzaW5jZSBTQVggMi4wIChleHRlbnNpb25zIDEuMCkKKyAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCisgKiBAdmVyc2lvbiAyLjAuMSAoc2F4MnIyKQorICovCitwdWJsaWMgaW50ZXJmYWNlIERlY2xIYW5kbGVyCit7CisKKyAgICAvKioKKyAgICAgKiBSZXBvcnQgYW4gZWxlbWVudCB0eXBlIGRlY2xhcmF0aW9uLgorICAgICAqCisgICAgICogPHA+VGhlIGNvbnRlbnQgbW9kZWwgd2lsbCBjb25zaXN0IG9mIHRoZSBzdHJpbmcgIkVNUFRZIiwgdGhlCisgICAgICogc3RyaW5nICJBTlkiLCBvciBhIHBhcmVudGhlc2lzZWQgZ3JvdXAsIG9wdGlvbmFsbHkgZm9sbG93ZWQKKyAgICAgKiBieSBhbiBvY2N1cnJlbmNlIGluZGljYXRvci4gIFRoZSBtb2RlbCB3aWxsIGJlIG5vcm1hbGl6ZWQgc28KKyAgICAgKiB0aGF0IGFsbCBwYXJhbWV0ZXIgZW50aXRpZXMgYXJlIGZ1bGx5IHJlc29sdmVkIGFuZCBhbGwgd2hpdGVzcGFjZQorICAgICAqIGlzIHJlbW92ZWQsYW5kIHdpbGwgaW5jbHVkZSB0aGUgZW5jbG9zaW5nIHBhcmVudGhlc2VzLiAgT3RoZXIKKyAgICAgKiBub3JtYWxpemF0aW9uIChzdWNoIGFzIHJlbW92aW5nIHJlZHVuZGFudCBwYXJlbnRoZXNlcyBvcgorICAgICAqIHNpbXBsaWZ5aW5nIG9jY3VycmVuY2UgaW5kaWNhdG9ycykgaXMgYXQgdGhlIGRpc2NyZXRpb24gb2YgdGhlCisgICAgICogcGFyc2VyLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZS4KKyAgICAgKiBAcGFyYW0gbW9kZWwgVGhlIGNvbnRlbnQgbW9kZWwgYXMgYSBub3JtYWxpemVkIHN0cmluZy4KKyAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBlbGVtZW50RGVjbCAoU3RyaW5nIG5hbWUsIFN0cmluZyBtb2RlbCkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBSZXBvcnQgYW4gYXR0cmlidXRlIHR5cGUgZGVjbGFyYXRpb24uCisgICAgICoKKyAgICAgKiA8cD5Pbmx5IHRoZSBlZmZlY3RpdmUgKGZpcnN0KSBkZWNsYXJhdGlvbiBmb3IgYW4gYXR0cmlidXRlIHdpbGwKKyAgICAgKiBiZSByZXBvcnRlZC4gIFRoZSB0eXBlIHdpbGwgYmUgb25lIG9mIHRoZSBzdHJpbmdzICJDREFUQSIsCisgICAgICogIklEIiwgIklEUkVGIiwgIklEUkVGUyIsICJOTVRPS0VOIiwgIk5NVE9LRU5TIiwgIkVOVElUWSIsCisgICAgICogIkVOVElUSUVTIiwgYSBwYXJlbnRoZXNpemVkIHRva2VuIGdyb3VwIHdpdGgKKyAgICAgKiB0aGUgc2VwYXJhdG9yICJ8IiBhbmQgYWxsIHdoaXRlc3BhY2UgcmVtb3ZlZCwgb3IgdGhlIHdvcmQKKyAgICAgKiAiTk9UQVRJT04iIGZvbGxvd2VkIGJ5IGEgc3BhY2UgZm9sbG93ZWQgYnkgYSBwYXJlbnRoZXNpemVkCisgICAgICogdG9rZW4gZ3JvdXAgd2l0aCBhbGwgd2hpdGVzcGFjZSByZW1vdmVkLjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSB2YWx1ZSB3aWxsIGJlIHRoZSB2YWx1ZSBhcyByZXBvcnRlZCB0byBhcHBsaWNhdGlvbnMsCisgICAgICogYXBwcm9wcmlhdGVseSBub3JtYWxpemVkIGFuZCB3aXRoIGVudGl0eSBhbmQgY2hhcmFjdGVyCisgICAgICogcmVmZXJlbmNlcyBleHBhbmRlZC4gIDwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlTmFtZSBUaGUgbmFtZSBvZiB0aGUgYXNzb2NpYXRlZCBlbGVtZW50LgorICAgICAqIEBwYXJhbSBhTmFtZSBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgorICAgICAqIEBwYXJhbSB0eXBlIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgYXR0cmlidXRlIHR5cGUuCisgICAgICogQHBhcmFtIG1vZGUgQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBhdHRyaWJ1dGUgZGVmYXVsdGluZyBtb2RlCisgICAgICogICAgICAgICgiI0lNUExJRUQiLCAiI1JFUVVJUkVEIiwgb3IgIiNGSVhFRCIpIG9yIG51bGwgaWYKKyAgICAgKiAgICAgICAgbm9uZSBvZiB0aGVzZSBhcHBsaWVzLgorICAgICAqIEBwYXJhbSB2YWx1ZSBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGF0dHJpYnV0ZSdzIGRlZmF1bHQgdmFsdWUsCisgICAgICogICAgICAgIG9yIG51bGwgaWYgdGhlcmUgaXMgbm9uZS4KKyAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBhdHRyaWJ1dGVEZWNsIChTdHJpbmcgZU5hbWUsCisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHR5cGUsCisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtb2RlLAorICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKKworCisgICAgLyoqCisgICAgICogUmVwb3J0IGFuIGludGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbi4KKyAgICAgKgorICAgICAqIDxwPk9ubHkgdGhlIGVmZmVjdGl2ZSAoZmlyc3QpIGRlY2xhcmF0aW9uIGZvciBlYWNoIGVudGl0eQorICAgICAqIHdpbGwgYmUgcmVwb3J0ZWQuICBBbGwgcGFyYW1ldGVyIGVudGl0aWVzIGluIHRoZSB2YWx1ZQorICAgICAqIHdpbGwgYmUgZXhwYW5kZWQsIGJ1dCBnZW5lcmFsIGVudGl0aWVzIHdpbGwgbm90LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuICBJZiBpdCBpcyBhIHBhcmFtZXRlcgorICAgICAqICAgICAgICBlbnRpdHksIHRoZSBuYW1lIHdpbGwgYmVnaW4gd2l0aCAnJScuCisgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBsYWNlbWVudCB0ZXh0IG9mIHRoZSBlbnRpdHkuCisgICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCisgICAgICogQHNlZSAjZXh0ZXJuYWxFbnRpdHlEZWNsCisgICAgICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyI3VucGFyc2VkRW50aXR5RGVjbAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGludGVybmFsRW50aXR5RGVjbCAoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBSZXBvcnQgYSBwYXJzZWQgZXh0ZXJuYWwgZW50aXR5IGRlY2xhcmF0aW9uLgorICAgICAqCisgICAgICogPHA+T25seSB0aGUgZWZmZWN0aXZlIChmaXJzdCkgZGVjbGFyYXRpb24gZm9yIGVhY2ggZW50aXR5CisgICAgICogd2lsbCBiZSByZXBvcnRlZC48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwsIHRoZSBwYXJzZXIgbXVzdCByZXNvbHZlIGl0CisgICAgICogZnVsbHkgYmVmb3JlIHBhc3NpbmcgaXQgdG8gdGhlIGFwcGxpY2F0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuICBJZiBpdCBpcyBhIHBhcmFtZXRlcgorICAgICAqICAgICAgICBlbnRpdHksIHRoZSBuYW1lIHdpbGwgYmVnaW4gd2l0aCAnJScuCisgICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBlbnRpdHkncyBwdWJsaWMgaWRlbnRpZmllciwgb3IgbnVsbCBpZiBub25lCisgICAgICogICAgICAgIHdhcyBnaXZlbi4KKyAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIGVudGl0eSdzIHN5c3RlbSBpZGVudGlmaWVyLgorICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgorICAgICAqIEBzZWUgI2ludGVybmFsRW50aXR5RGVjbAorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlciN1bnBhcnNlZEVudGl0eURlY2wKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBleHRlcm5hbEVudGl0eURlY2wgKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkKQorICAgIHRocm93cyBTQVhFeGNlcHRpb247CisKK30KKworLy8gZW5kIG9mIERlY2xIYW5kbGVyLmphdmEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9leHQvRGVmYXVsdEhhbmRsZXIyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvZXh0L0RlZmF1bHRIYW5kbGVyMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVmODAxOTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvZXh0L0RlZmF1bHRIYW5kbGVyMi5qYXZhCkBAIC0wLDAgKzEsMTg1IEBACisvLyBEZWZhdWx0SGFuZGxlcjIuamF2YSAtIGV4dGVuZGVkIERlZmF1bHRIYW5kbGVyCisvLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCisvLyBQdWJsaWMgRG9tYWluOiBubyB3YXJyYW50eS4KKy8vICRJZDogRGVmYXVsdEhhbmRsZXIyLmphdmEsdiAxLjMgMjAwMi8wMS8xMiAxOTowNDoxOSBkYnJvd25lbGwgRXhwICQKKworcGFja2FnZSBvcmcueG1sLnNheC5leHQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyOworCisKKy8qKgorICogVGhpcyBjbGFzcyBleHRlbmRzIHRoZSBTQVgyIGJhc2UgaGFuZGxlciBjbGFzcyB0byBzdXBwb3J0IHRoZQorICogU0FYMiB7QGxpbmsgTGV4aWNhbEhhbmRsZXJ9LCB7QGxpbmsgRGVjbEhhbmRsZXJ9LCBhbmQKKyAqIHtAbGluayBFbnRpdHlSZXNvbHZlcjJ9IGV4dGVuc2lvbnMuICBFeGNlcHQgZm9yIG92ZXJyaWRpbmcgdGhlCisgKiBvcmlnaW5hbCBTQVgxIHtAbGluayBEZWZhdWx0SGFuZGxlciNyZXNvbHZlRW50aXR5IHJlc29sdmVFbnRpdHkoKX0KKyAqIG1ldGhvZCB0aGUgYWRkZWQgaGFuZGxlciBtZXRob2RzIGp1c3QgcmV0dXJuLiAgU3ViY2xhc3NlcnMgbWF5CisgKiBvdmVycmlkZSBldmVyeXRoaW5nIG9uIGEgbWV0aG9kLWJ5LW1ldGhvZCBiYXNpcy4KKyAqCisgKiA8YmxvY2txdW90ZT4KKyAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCisgKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+CisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+IDxlbT5Ob3RlOjwvZW0+IHRoaXMgY2xhc3MgbWlnaHQgeWV0IGxlYXJuIHRoYXQgdGhlCisgKiA8ZW0+Q29udGVudEhhbmRsZXIuc2V0RG9jdW1lbnRMb2NhdG9yKCk8L2VtPiBjYWxsIG1pZ2h0IGJlIHBhc3NlZCBhCisgKiB7QGxpbmsgTG9jYXRvcjJ9IG9iamVjdCwgYW5kIHRoYXQgdGhlCisgKiA8ZW0+Q29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KCk8L2VtPiBjYWxsIG1pZ2h0IGJlIHBhc3NlZCBhCisgKiB7QGxpbmsgQXR0cmlidXRlczJ9IG9iamVjdC4KKyAqCisgKiBAc2luY2UgU0FYIDIuMCAoZXh0ZW5zaW9ucyAxLjEgYWxwaGEpCisgKiBAYXV0aG9yIERhdmlkIEJyb3duZWxsCisgKiBAdmVyc2lvbiBUQlMKKyAqLworcHVibGljIGNsYXNzIERlZmF1bHRIYW5kbGVyMiBleHRlbmRzIERlZmF1bHRIYW5kbGVyCisgICAgaW1wbGVtZW50cyBMZXhpY2FsSGFuZGxlciwgRGVjbEhhbmRsZXIsIEVudGl0eVJlc29sdmVyMgoreworICAgIC8qKiBDb25zdHJ1Y3RzIGEgaGFuZGxlciB3aGljaCBpZ25vcmVzIGFsbCBwYXJzaW5nIGV2ZW50cy4gKi8KKyAgICBwdWJsaWMgRGVmYXVsdEhhbmRsZXIyICgpIHsgfQorCisKKyAgICAvLyBTQVgyIGV4dC0xLjAgTGV4aWNhbEhhbmRsZXIKKworICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEgKCkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAge30KKworICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBICgpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHt9CisKKyAgICBwdWJsaWMgdm9pZCBzdGFydERURCAoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7fQorCisgICAgcHVibGljIHZvaWQgZW5kRFREICgpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHt9CisKKyAgICBwdWJsaWMgdm9pZCBzdGFydEVudGl0eSAoU3RyaW5nIG5hbWUpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHt9CisKKyAgICBwdWJsaWMgdm9pZCBlbmRFbnRpdHkgKFN0cmluZyBuYW1lKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7fQorCisgICAgcHVibGljIHZvaWQgY29tbWVudCAoY2hhciBjaCBbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7IH0KKworCisgICAgLy8gU0FYMiBleHQtMS4wIERlY2xIYW5kbGVyCisKKyAgICBwdWJsaWMgdm9pZCBhdHRyaWJ1dGVEZWNsIChTdHJpbmcgZU5hbWUsIFN0cmluZyBhTmFtZSwKKyAgICAgICAgU3RyaW5nIHR5cGUsIFN0cmluZyBtb2RlLCBTdHJpbmcgdmFsdWUpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHt9CisKKyAgICBwdWJsaWMgdm9pZCBlbGVtZW50RGVjbCAoU3RyaW5nIG5hbWUsIFN0cmluZyBtb2RlbCkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAge30KKworICAgIHB1YmxpYyB2b2lkIGV4dGVybmFsRW50aXR5RGVjbCAoU3RyaW5nIG5hbWUsCisgICAgICAgIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7fQorCisgICAgcHVibGljIHZvaWQgaW50ZXJuYWxFbnRpdHlEZWNsIChTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7fQorCisgICAgLy8gU0FYMiBleHQtMS4xIEVudGl0eVJlc29sdmVyMgorCisgICAgLyoqCisgICAgICogVGVsbHMgdGhlIHBhcnNlciB0aGF0IGlmIG5vIGV4dGVybmFsIHN1YnNldCBoYXMgYmVlbiBkZWNsYXJlZAorICAgICAqIGluIHRoZSBkb2N1bWVudCB0ZXh0LCBub25lIHNob3VsZCBiZSB1c2VkLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgSWRlbnRpZmllcyB0aGUgZG9jdW1lbnQgcm9vdCBlbGVtZW50LiAgVGhpcyBuYW1lIGNvbWVzCisgICAgICogICAgZnJvbSBhIERPQ1RZUEUgZGVjbGFyYXRpb24gKHdoZXJlIGF2YWlsYWJsZSkgb3IgZnJvbSB0aGUgYWN0dWFsCisgICAgICogICAgcm9vdCBlbGVtZW50LiBUaGUgcGFyYW1ldGVyIGlzIGlnbm9yZWQuCisgICAgICogQHBhcmFtIGJhc2VVUkkgVGhlIGRvY3VtZW50J3MgYmFzZSBVUkksIHNlcnZpbmcgYXMgYW4gYWRkaXRpb25hbAorICAgICAqICAgIGhpbnQgZm9yIHNlbGVjdGluZyB0aGUgZXh0ZXJuYWwgc3Vic2V0LiAgVGhpcyBpcyBhbHdheXMgYW4gYWJzb2x1dGUKKyAgICAgKiAgICBVUkksIHVubGVzcyBpdCBpcyBudWxsIGJlY2F1c2UgdGhlIFhNTFJlYWRlciB3YXMgZ2l2ZW4gYW4gSW5wdXRTb3VyY2UKKyAgICAgKiAgICB3aXRob3V0IG9uZS4gVGhlIHBhcmFtZXRlciBpcyBpZ25vcmVkLgorICAgICAqCisgICAgICogQHJldHVybiBudWxsIChhbHdheXMpLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5IHdyYXBwaW5nCisgICAgICogICAgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQGV4Y2VwdGlvbiBJT0V4Y2VwdGlvbiBQcm9iYWJseSBpbmRpY2F0aW5nIGEgZmFpbHVyZSB0byBjcmVhdGUKKyAgICAgKiAgICBhIG5ldyBJbnB1dFN0cmVhbSBvciBSZWFkZXIsIG9yIGFuIGlsbGVnYWwgVVJMLgorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFNvdXJjZSBnZXRFeHRlcm5hbFN1YnNldCAoU3RyaW5nIG5hbWUsIFN0cmluZyBiYXNlVVJJKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uCisgICAgeyByZXR1cm4gbnVsbDsgfQorCisgICAgLyoqCisgICAgICogVGVsbHMgdGhlIHBhcnNlciB0byByZXNvbHZlIHRoZSBzeXN0ZW1JZCBhZ2FpbnN0IHRoZSBiYXNlVVJJCisgICAgICogYW5kIHJlYWQgdGhlIGVudGl0eSB0ZXh0IGZyb20gdGhhdCByZXN1bHRpbmcgYWJzb2x1dGUgVVJJLgorICAgICAqIE5vdGUgdGhhdCBiZWNhdXNlIHRoZSBvbGRlcgorICAgICAqIHtAbGluayBEZWZhdWx0SGFuZGxlciNyZXNvbHZlRW50aXR5IERlZmF1bHRIYW5kbGVyLnJlc29sdmVFbnRpdHkoKX0sCisgICAgICogbWV0aG9kIGlzIG92ZXJyaWRkZW4gdG8gY2FsbCB0aGlzIG9uZSwgdGhpcyBtZXRob2QgbWF5IHNvbWV0aW1lcworICAgICAqIGJlIGludm9rZWQgd2l0aCBudWxsIDxlbT5uYW1lPC9lbT4gYW5kIDxlbT5iYXNlVVJJPC9lbT4sIGFuZAorICAgICAqIHdpdGggdGhlIDxlbT5zeXN0ZW1JZDwvZW0+IGFscmVhZHkgYWJzb2x1dGl6ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBJZGVudGlmaWVzIHRoZSBleHRlcm5hbCBlbnRpdHkgYmVpbmcgcmVzb2x2ZWQuCisgICAgICogICAgRWl0aGVyICJbZHRkXSIgZm9yIHRoZSBleHRlcm5hbCBzdWJzZXQsIG9yIGEgbmFtZSBzdGFydGluZworICAgICAqICAgIHdpdGggIiUiIHRvIGluZGljYXRlIGEgcGFyYW1ldGVyIGVudGl0eSwgb3IgZWxzZSB0aGUgbmFtZSBvZgorICAgICAqICAgIGEgZ2VuZXJhbCBlbnRpdHkuICBUaGlzIGlzIG5ldmVyIG51bGwgd2hlbiBpbnZva2VkIGJ5IGEgU0FYMgorICAgICAqICAgIHBhcnNlci4KKyAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBleHRlcm5hbCBlbnRpdHkgYmVpbmcKKyAgICAgKiAgICByZWZlcmVuY2VkIChub3JtYWxpemVkIGFzIHJlcXVpcmVkIGJ5IHRoZSBYTUwgc3BlY2lmaWNhdGlvbiksIG9yCisgICAgICogICAgbnVsbCBpZiBub25lIHdhcyBzdXBwbGllZC4KKyAgICAgKiBAcGFyYW0gYmFzZVVSSSBUaGUgVVJJIHdpdGggcmVzcGVjdCB0byB3aGljaCByZWxhdGl2ZSBzeXN0ZW1JRHMKKyAgICAgKiAgICBhcmUgaW50ZXJwcmV0ZWQuICBUaGlzIGlzIGFsd2F5cyBhbiBhYnNvbHV0ZSBVUkksIHVubGVzcyBpdCBpcworICAgICAqICAgIG51bGwgKGxpa2VseSBiZWNhdXNlIHRoZSBYTUxSZWFkZXIgd2FzIGdpdmVuIGFuIElucHV0U291cmNlIHdpdGhvdXQKKyAgICAgKiAgb25lKS4gIFRoaXMgVVJJIGlzIGRlZmluZWQgYnkgdGhlIFhNTCBzcGVjaWZpY2F0aW9uIHRvIGJlIHRoZSBvbmUKKyAgICAgKiAgICBhc3NvY2lhdGVkIHdpdGggdGhlICImbHQ7IiBzdGFydGluZyB0aGUgcmVsZXZhbnQgZGVjbGFyYXRpb24uCisgICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgZW50aXR5CisgICAgICogICAgYmVpbmcgcmVmZXJlbmNlZDsgZWl0aGVyIGEgcmVsYXRpdmUgb3IgYWJzb2x1dGUgVVJJLgorICAgICAqICBUaGlzIGlzIG5ldmVyIG51bGwgd2hlbiBpbnZva2VkIGJ5IGEgU0FYMiBwYXJzZXI7IG9ubHkgZGVjbGFyZWQKKyAgICAgKiAgICBlbnRpdGllcywgYW5kIGFueSBleHRlcm5hbCBzdWJzZXQsIGFyZSByZXNvbHZlZCBieSBzdWNoIHBhcnNlcnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFuIElucHV0U291cmNlIG9iamVjdCBkZXNjcmliaW5nIHRoZSBuZXcgaW5wdXQgc291cmNlLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5IHdyYXBwaW5nCisgICAgICogICAgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQGV4Y2VwdGlvbiBJT0V4Y2VwdGlvbiBQcm9iYWJseSBpbmRpY2F0aW5nIGEgZmFpbHVyZSB0byBjcmVhdGUKKyAgICAgKiAgICBhIG5ldyBJbnB1dFN0cmVhbSBvciBSZWFkZXIsIG9yIGFuIGlsbGVnYWwgVVJMLgorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFNvdXJjZSByZXNvbHZlRW50aXR5IChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLAorICAgICAgICBTdHJpbmcgYmFzZVVSSSwgU3RyaW5nIHN5c3RlbUlkKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uCisgICAgeyByZXR1cm4gbnVsbDsgfQorCisgICAgLy8gU0FYMSBFbnRpdHlSZXNvbHZlcgorCisgICAgLyoqCisgICAgICogSW52b2tlcworICAgICAqIHtAbGluayBFbnRpdHlSZXNvbHZlcjIjcmVzb2x2ZUVudGl0eSBFbnRpdHlSZXNvbHZlcjIucmVzb2x2ZUVudGl0eSgpfQorICAgICAqIHdpdGggbnVsbCBlbnRpdHkgbmFtZSBhbmQgYmFzZSBVUkkuCisgICAgICogWW91IG9ubHkgbmVlZCB0byBvdmVycmlkZSB0aGF0IG1ldGhvZCB0byB1c2UgdGhpcyBjbGFzcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIGVudGl0eSBiZWluZworICAgICAqICAgIHJlZmVyZW5jZWQgKG5vcm1hbGl6ZWQgYXMgcmVxdWlyZWQgYnkgdGhlIFhNTCBzcGVjaWZpY2F0aW9uKSwgb3IKKyAgICAgKiAgICBudWxsIGlmIG5vbmUgd2FzIHN1cHBsaWVkLgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIGVudGl0eQorICAgICAqICAgIGJlaW5nIHJlZmVyZW5jZWQ7IGVpdGhlciBhIHJlbGF0aXZlIG9yIGFic29sdXRlIFVSSS4KKyAgICAgKiAgVGhpcyBpcyBuZXZlciBudWxsIHdoZW4gaW52b2tlZCBieSBhIFNBWDIgcGFyc2VyOyBvbmx5IGRlY2xhcmVkCisgICAgICogICAgZW50aXRpZXMsIGFuZCBhbnkgZXh0ZXJuYWwgc3Vic2V0LCBhcmUgcmVzb2x2ZWQgYnkgc3VjaCBwYXJzZXJzLgorICAgICAqCisgICAgICogQHJldHVybiBBbiBJbnB1dFNvdXJjZSBvYmplY3QgZGVzY3JpYmluZyB0aGUgbmV3IGlucHV0IHNvdXJjZS4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseSB3cmFwcGluZworICAgICAqICAgIGFub3RoZXIgZXhjZXB0aW9uLgorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gUHJvYmFibHkgaW5kaWNhdGluZyBhIGZhaWx1cmUgdG8gY3JlYXRlCisgICAgICogICAgYSBuZXcgSW5wdXRTdHJlYW0gb3IgUmVhZGVyLCBvciBhbiBpbGxlZ2FsIFVSTC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eSAoU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24KKyAgICB7IHJldHVybiByZXNvbHZlRW50aXR5IChudWxsLCBwdWJsaWNJZCwgbnVsbCwgc3lzdGVtSWQpOyB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvZXh0L0VudGl0eVJlc29sdmVyMi5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2V4dC9FbnRpdHlSZXNvbHZlcjIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNmIzNTE1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2V4dC9FbnRpdHlSZXNvbHZlcjIuamF2YQpAQCAtMCwwICsxLDE5NiBAQAorLy8gRW50aXR5UmVzb2x2ZXIyLmphdmEgLSBFeHRlbmRlZCBTQVggZW50aXR5IHJlc29sdmVyLgorLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZworLy8gTm8gd2FycmFudHk7IG5vIGNvcHlyaWdodCAtLSB1c2UgdGhpcyBhcyB5b3Ugd2lsbC4KKy8vICRJZDogRW50aXR5UmVzb2x2ZXIyLmphdmEsdiAxLjIgMjAwMi8wMS8xMiAxOToyMDowOCBkYnJvd25lbGwgRXhwICQKKworcGFja2FnZSBvcmcueG1sLnNheC5leHQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOworaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7CisKKworLyoqCisgKiBFeHRlbmRlZCBpbnRlcmZhY2UgZm9yIG1hcHBpbmcgZXh0ZXJuYWwgZW50aXR5IHJlZmVyZW5jZXMgdG8gaW5wdXQKKyAqIHNvdXJjZXMsIG9yIHByb3ZpZGluZyBhIG1pc3NpbmcgZXh0ZXJuYWwgc3Vic2V0LiAgVGhlCisgKiB7QGxpbmsgWE1MUmVhZGVyI3NldEVudGl0eVJlc29sdmVyIFhNTFJlYWRlci5zZXRFbnRpdHlSZXNvbHZlcigpfSBtZXRob2QKKyAqIGlzIHVzZWQgdG8gcHJvdmlkZSBpbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBpbnRlcmZhY2UgdG8gcGFyc2Vycy4KKyAqIFdoZW4gYSBwYXJzZXIgdXNlcyB0aGUgbWV0aG9kcyBpbiB0aGlzIGludGVyZmFjZSwgdGhlCisgKiB7QGxpbmsgRW50aXR5UmVzb2x2ZXIyI3Jlc29sdmVFbnRpdHkgRW50aXR5UmVzb2x2ZXIyLnJlc29sdmVFbnRpdHkoKX0KKyAqIG1ldGhvZCAoaW4gdGhpcyBpbnRlcmZhY2UpIGlzIHVzZWQgPGVtPmluc3RlYWQgb2Y8L2VtPiB0aGUgb2xkZXIgKFNBWCAxLjApCisgKiB7QGxpbmsgRW50aXR5UmVzb2x2ZXIjcmVzb2x2ZUVudGl0eSBFbnRpdHlSZXNvbHZlci5yZXNvbHZlRW50aXR5KCl9IG1ldGhvZC4KKyAqCisgKiA8YmxvY2txdW90ZT4KKyAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCisgKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+CisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+SWYgYSBTQVggYXBwbGljYXRpb24gcmVxdWlyZXMgdGhlIGN1c3RvbWl6ZWQgaGFuZGxpbmcgd2hpY2ggdGhpcworICogaW50ZXJmYWNlIGRlZmluZXMgZm9yIGV4dGVybmFsIGVudGl0aWVzLCBpdCBtdXN0IGVuc3VyZSB0aGF0IGl0IHVzZXMKKyAqIGFuIFhNTFJlYWRlciB3aXRoIHRoZQorICogPGVtPmh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy91c2UtZW50aXR5LXJlc29sdmVyMjwvZW0+IGZlYXR1cmUgZmxhZworICogc2V0IHRvIDxlbT50cnVlPC9lbT4gKHdoaWNoIGlzIGl0cyBkZWZhdWx0IHZhbHVlIHdoZW4gdGhlIGZlYXR1cmUgaXMKKyAqIHJlY29nbml6ZWQpLiAgSWYgdGhhdCBmbGFnIGlzIHVucmVjb2duaXplZCwgb3IgaXRzIHZhbHVlIGlzIGZhbHNlLAorICogb3IgdGhlIHJlc29sdmVyIGRvZXMgbm90IGltcGxlbWVudCB0aGlzIGludGVyZmFjZSwgdGhlbiBvbmx5IHRoZQorICoge0BsaW5rIEVudGl0eVJlc29sdmVyfSBtZXRob2Qgd2lsbCBiZSB1c2VkLgorICogPC9wPgorICoKKyAqIDxwPlRoYXQgc3VwcG9ydHMgdGhyZWUgY2F0ZWdvcmllcyBvZiBhcHBsaWNhdGlvbiB0aGF0IG1vZGlmeSBlbnRpdHkKKyAqIHJlc29sdXRpb24uICA8ZW0+T2xkIFN0eWxlPC9lbT4gYXBwbGljYXRpb25zIHdvbid0IGtub3cgYWJvdXQgdGhpcyBpbnRlcmZhY2U7CisgKiB0aGV5IHdpbGwgcHJvdmlkZSBhbiBFbnRpdHlSZXNvbHZlci4KKyAqIDxlbT5UcmFuc2l0aW9uYWwgTW9kZTwvZW0+IHByb3ZpZGUgYW4gRW50aXR5UmVzb2x2ZXIyIGFuZCBhdXRvbWF0aWNhbGx5CisgKiBnZXQgdGhlIGJlbmVmaXQgb2YgaXRzIG1ldGhvZHMgaW4gYW55IHN5c3RlbXMgKHBhcnNlcnMgb3Igb3RoZXIgdG9vbHMpCisgKiBzdXBwb3J0aW5nIGl0LCBkdWUgdG8gcG9seW1vcnBoaXNtLgorICogQm90aCA8ZW0+T2xkIFN0eWxlPC9lbT4gYW5kIDxlbT5UcmFuc2l0aW9uYWwgTW9kZTwvZW0+IGFwcGxpY2F0aW9ucyB3aWxsCisgKiB3b3JrIHdpdGggYW55IFNBWDIgcGFyc2VyLgorICogPGVtPk5ldyBzdHlsZTwvZW0+IGFwcGxpY2F0aW9ucyB3aWxsIGZhaWwgdG8gcnVuIGV4Y2VwdCBvbiBTQVgyIHBhcnNlcnMKKyAqIHRoYXQgc3VwcG9ydCB0aGlzIHBhcnRpY3VsYXIgZmVhdHVyZS4KKyAqIFRoZXkgd2lsbCBpbnNpc3QgdGhhdCBmZWF0dXJlIGZsYWcgaGF2ZSBhIHZhbHVlIG9mICJ0cnVlIiwgYW5kIHRoZQorICogRW50aXR5UmVzb2x2ZXIyIGltcGxlbWVudGF0aW9uIHRoZXkgcHJvdmlkZSAgbWlnaHQgdGhyb3cgYW4gZXhjZXB0aW9uCisgKiBpZiB0aGUgb3JpZ2luYWwgU0FYIDEuMCBzdHlsZSBlbnRpdHkgcmVzb2x1dGlvbiBtZXRob2QgaXMgaW52b2tlZC4KKyAqIDwvcD4KKyAqCisgKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNzZXRFbnRpdHlSZXNvbHZlcgorICoKKyAqIEBzaW5jZSBTQVggMi4wIChleHRlbnNpb25zIDEuMSBhbHBoYSkKKyAqIEBhdXRob3IgRGF2aWQgQnJvd25lbGwKKyAqIEB2ZXJzaW9uIFRCRAorICovCitwdWJsaWMgaW50ZXJmYWNlIEVudGl0eVJlc29sdmVyMiBleHRlbmRzIEVudGl0eVJlc29sdmVyCit7CisgICAgLyoqCisgICAgICogQWxsb3dzIGFwcGxpY2F0aW9ucyB0byBwcm92aWRlIGFuIGV4dGVybmFsIHN1YnNldCBmb3IgZG9jdW1lbnRzCisgICAgICogdGhhdCBkb24ndCBleHBsaWNpdGx5IGRlZmluZSBvbmUuICBEb2N1bWVudHMgd2l0aCBET0NUWVBFIGRlY2xhcmF0aW9ucworICAgICAqIHRoYXQgb21pdCBhbiBleHRlcm5hbCBzdWJzZXQgY2FuIHRodXMgYXVnbWVudCB0aGUgZGVjbGFyYXRpb25zCisgICAgICogYXZhaWxhYmxlIGZvciB2YWxpZGF0aW9uLCBlbnRpdHkgcHJvY2Vzc2luZywgYW5kIGF0dHJpYnV0ZSBwcm9jZXNzaW5nCisgICAgICogKG5vcm1hbGl6YXRpb24sIGRlZmF1bHRpbmcsIGFuZCByZXBvcnRpbmcgdHlwZXMgaW5jbHVkaW5nIElEKS4KKyAgICAgKiBUaGlzIGF1Z21lbnRhdGlvbiBpcyByZXBvcnRlZAorICAgICAqIHRocm91Z2ggdGhlIHtAbGluayBMZXhpY2FsSGFuZGxlciNzdGFydERURCBzdGFydERURCgpfSBtZXRob2QgYXMgaWYKKyAgICAgKiB0aGUgZG9jdW1lbnQgdGV4dCBoYWQgb3JpZ2luYWxseSBpbmNsdWRlZCB0aGUgZXh0ZXJuYWwgc3Vic2V0OworICAgICAqIHRoaXMgY2FsbGJhY2sgaXMgbWFkZSBiZWZvcmUgYW55IGludGVybmFsIHN1YnNldCBkYXRhIG9yIGVycm9ycworICAgICAqIGFyZSByZXBvcnRlZC48L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBjYW4gYWxzbyBiZSB1c2VkIHdpdGggZG9jdW1lbnRzIHRoYXQgaGF2ZSBubyBET0NUWVBFCisgICAgICogZGVjbGFyYXRpb24uICBXaGVuIHRoZSByb290IGVsZW1lbnQgaXMgZW5jb3VudGVyZWQsCisgICAgICogYnV0IG5vIERPQ1RZUEUgZGVjbGFyYXRpb24gaGFzIGJlZW4gc2VlbiwgdGhpcyBtZXRob2QgaXMKKyAgICAgKiBpbnZva2VkLiAgSWYgaXQgcmV0dXJucyBhIHZhbHVlIGZvciB0aGUgZXh0ZXJuYWwgc3Vic2V0LCB0aGF0IHJvb3QKKyAgICAgKiBlbGVtZW50IGlzIGRlY2xhcmVkIHRvIGJlIHRoZSByb290IGVsZW1lbnQsIGdpdmluZyB0aGUgZWZmZWN0IG9mCisgICAgICogc3BsaWNpbmcgYSBET0NUWVBFIGRlY2xhcmF0aW9uIGF0IHRoZSBlbmQgdGhlIHByb2xvZyBvZiBhIGRvY3VtZW50CisgICAgICogdGhhdCBjb3VsZCBub3Qgb3RoZXJ3aXNlIGJlIHZhbGlkLiAgVGhlIHNlcXVlbmNlIG9mIHBhcnNlciBjYWxsYmFja3MKKyAgICAgKiBpbiB0aGF0IGNhc2UgbG9naWNhbGx5IHJlc2VtYmxlcyB0aGlzOjwvcD4KKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogLi4uIGNvbW1lbnRzIGFuZCBQSXMgZnJvbSB0aGUgcHJvbG9nIChhcyB1c3VhbCkKKyAgICAgKiBzdGFydERURCAoInJvb3ROYW1lIiwgc291cmNlLmdldFB1YmxpY0lkICgpLCBzb3VyY2UuZ2V0U3lzdGVtSWQgKCkpOworICAgICAqIHN0YXJ0RW50aXR5ICgiW2R0ZF0iKTsKKyAgICAgKiAuLi4gZGVjbGFyYXRpb25zLCBjb21tZW50cywgYW5kIFBJcyBmcm9tIHRoZSBleHRlcm5hbCBzdWJzZXQKKyAgICAgKiBlbmRFbnRpdHkgKCJbZHRkXSIpOworICAgICAqIGVuZERURCAoKTsKKyAgICAgKiAuLi4gdGhlbiB0aGUgcmVzdCBvZiB0aGUgZG9jdW1lbnQgKGFzIHVzdWFsKQorICAgICAqIHN0YXJ0RWxlbWVudCAoLi4uLCAicm9vdE5hbWUiLCAuLi4pOworICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IHRoZSBJbnB1dFNvdXJjZSBnZXRzIG5vIGZ1cnRoZXIgcmVzb2x1dGlvbi4KKyAgICAgKiBJbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBtZXRob2QgbWF5IHdpc2ggdG8gaW52b2tlCisgICAgICoge0BsaW5rICNyZXNvbHZlRW50aXR5IHJlc29sdmVFbnRpdHkoKX0gdG8gZ2FpbiBiZW5lZml0cyBzdWNoIGFzIHVzZQorICAgICAqIG9mIGxvY2FsIGNhY2hlcyBvZiBEVEQgZW50aXRpZXMuICBBbHNvLCB0aGlzIG1ldGhvZCB3aWxsIG5ldmVyIGJlCisgICAgICogdXNlZCBieSBhIChub24tdmFsaWRhdGluZykgcHJvY2Vzc29yIHRoYXQgaXMgbm90IGluY2x1ZGluZyBleHRlcm5hbAorICAgICAqIHBhcmFtZXRlciBlbnRpdGllcy4gPC9wPgorICAgICAqCisgICAgICogPHA+VXNlcyBmb3IgdGhpcyBtZXRob2QgaW5jbHVkZSBmYWNpbGl0YXRpbmcgZGF0YSB2YWxpZGF0aW9uIHdoZW4KKyAgICAgKiBpbnRlcm9wZXJhdGluZyB3aXRoIFhNTCBwcm9jZXNzb3JzIHRoYXQgd291bGQgYWx3YXlzIHJlcXVpcmUKKyAgICAgKiB1bmRlc2lyYWJsZSBuZXR3b3JrIGFjY2Vzc2VzIGZvciBleHRlcm5hbCBlbnRpdGllcywgb3Igd2hpY2ggZm9yCisgICAgICogb3RoZXIgcmVhc29ucyBhZG9wdCBhICJubyBEVERzIiBwb2xpY3kuCisgICAgICogTm9uLXZhbGlkYXRpb24gbW90aXZlcyBpbmNsdWRlIGZvcmNpbmcgZG9jdW1lbnRzIHRvIGluY2x1ZGUgRFREcyBzbworICAgICAqIHRoYXQgYXR0cmlidXRlcyBhcmUgaGFuZGxlZCBjb25zaXN0ZW50bHkuCisgICAgICogRm9yIGV4YW1wbGUsIGFuIFhQYXRoIHByb2Nlc3NvciBuZWVkcyB0byBrbm93IHdoaWNoIGF0dGlidXRlcyBoYXZlCisgICAgICogdHlwZSAiSUQiIGJlZm9yZSBpdCBjYW4gcHJvY2VzcyBhIHdpZGVseSB1c2VkIHR5cGUgb2YgcmVmZXJlbmNlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gUmV0dXJuaW5nIGFuIGV4dGVybmFsIHN1YnNldCBtb2RpZmllcworICAgICAqIHRoZSBpbnB1dCBkb2N1bWVudC4gIEJ5IHByb3ZpZGluZyBkZWZpbml0aW9ucyBmb3IgZ2VuZXJhbCBlbnRpdGllcywKKyAgICAgKiBpdCBjYW4gbWFrZSBhIG1hbGZvcm1lZCBkb2N1bWVudCBhcHBlYXIgdG8gYmUgd2VsbCBmb3JtZWQuCisgICAgICogPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgSWRlbnRpZmllcyB0aGUgZG9jdW1lbnQgcm9vdCBlbGVtZW50LiAgVGhpcyBuYW1lIGNvbWVzCisgICAgICogICAgZnJvbSBhIERPQ1RZUEUgZGVjbGFyYXRpb24gKHdoZXJlIGF2YWlsYWJsZSkgb3IgZnJvbSB0aGUgYWN0dWFsCisgICAgICogICAgcm9vdCBlbGVtZW50LgorICAgICAqIEBwYXJhbSBiYXNlVVJJIFRoZSBkb2N1bWVudCdzIGJhc2UgVVJJLCBzZXJ2aW5nIGFzIGFuIGFkZGl0aW9uYWwKKyAgICAgKiAgICBoaW50IGZvciBzZWxlY3RpbmcgdGhlIGV4dGVybmFsIHN1YnNldC4gIFRoaXMgaXMgYWx3YXlzIGFuIGFic29sdXRlCisgICAgICogICAgVVJJLCB1bmxlc3MgaXQgaXMgbnVsbCBiZWNhdXNlIHRoZSBYTUxSZWFkZXIgd2FzIGdpdmVuIGFuIElucHV0U291cmNlCisgICAgICogICAgd2l0aG91dCBvbmUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFuIElucHV0U291cmNlIG9iamVjdCBkZXNjcmliaW5nIHRoZSBuZXcgZXh0ZXJuYWwgc3Vic2V0CisgICAgICogICAgdG8gYmUgdXNlZCBieSB0aGUgcGFyc2VyLCBvciBudWxsIHRvIGluZGljYXRlIHRoYXQgbm8gZXh0ZXJuYWwKKyAgICAgKiAgICBzdWJzZXQgaXMgcHJvdmlkZWQuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkgd3JhcHBpbmcKKyAgICAgKiAgICBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uIFByb2JhYmx5IGluZGljYXRpbmcgYSBmYWlsdXJlIHRvIGNyZWF0ZQorICAgICAqICAgIGEgbmV3IElucHV0U3RyZWFtIG9yIFJlYWRlciwgb3IgYW4gaWxsZWdhbCBVUkwuCisgICAgICovCisgICAgcHVibGljIElucHV0U291cmNlIGdldEV4dGVybmFsU3Vic2V0IChTdHJpbmcgbmFtZSwgU3RyaW5nIGJhc2VVUkkpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBBbGxvd3MgYXBwbGljYXRpb25zIHRvIG1hcCByZWZlcmVuY2VzIHRvIGV4dGVybmFsIGVudGl0aWVzIGludG8gaW5wdXQKKyAgICAgKiBzb3VyY2VzLCBvciB0ZWxsIHRoZSBwYXJzZXIgaXQgc2hvdWxkIHVzZSBjb252ZW50aW9uYWwgVVJJIHJlc29sdXRpb24uCisgICAgICogVGhpcyBtZXRob2QgaXMgb25seSBjYWxsZWQgZm9yIGV4dGVybmFsIGVudGl0aWVzIHdoaWNoIGhhdmUgYmVlbgorICAgICAqIHByb3Blcmx5IGRlY2xhcmVkLgorICAgICAqIFRoaXMgbWV0aG9kIHByb3ZpZGVzIG1vcmUgZmxleGliaWxpdHkgdGhhbiB0aGUge0BsaW5rIEVudGl0eVJlc29sdmVyfQorICAgICAqIGludGVyZmFjZSwgc3VwcG9ydGluZyBpbXBsZW1lbnRhdGlvbnMgb2YgbW9yZSBjb21wbGV4IGNhdGFsb2d1ZQorICAgICAqIHNjaGVtZXMgc3VjaCBhcyB0aGUgb25lIGRlZmluZWQgYnkgdGhlIDxhIGhyZWY9CisgICAgImh0dHA6Ly93d3cub2FzaXMtb3Blbi5vcmcvY29tbWl0dGVlcy9lbnRpdHkvc3BlYy0yMDAxLTA4LTA2Lmh0bWwiCisgICAgPk9BU0lTIFhNTCBDYXRhbG9nczwvYT4gc3BlY2lmaWNhdGlvbi48L3A+CisgICAgICoKKyAgICAgKiA8cD5QYXJzZXJzIGNvbmZpZ3VyZWQgdG8gdXNlIHRoaXMgcmVzb2x2ZXIgbWV0aG9kIHdpbGwgY2FsbCBpdAorICAgICAqIHRvIGRldGVybWluZSB0aGUgaW5wdXQgc291cmNlIHRvIHVzZSBmb3IgYW55IGV4dGVybmFsIGVudGl0eQorICAgICAqIGJlaW5nIGluY2x1ZGVkIGJlY2F1c2Ugb2YgYSByZWZlcmVuY2UgaW4gdGhlIFhNTCB0ZXh0LgorICAgICAqIFRoYXQgZXhjbHVkZXMgdGhlIGRvY3VtZW50IGVudGl0eSwgYW5kIGFueSBleHRlcm5hbCBlbnRpdHkgcmV0dXJuZWQKKyAgICAgKiBieSB7QGxpbmsgI2dldEV4dGVybmFsU3Vic2V0IGdldEV4dGVybmFsU3Vic2V0KCl9LgorICAgICAqIFdoZW4gYSAobm9uLXZhbGlkYXRpbmcpIHByb2Nlc3NvciBpcyBjb25maWd1cmVkIG5vdCB0byBpbmNsdWRlCisgICAgICogYSBjbGFzcyBvZiBlbnRpdGllcyAocGFyYW1ldGVyIG9yIGdlbmVyYWwpIHRocm91Z2ggdXNlIG9mIGZlYXR1cmUKKyAgICAgKiBmbGFncywgdGhpcyBtZXRob2QgaXMgbm90IGludm9rZWQgZm9yIHN1Y2ggZW50aXRpZXMuICA8L3A+CisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoYXQgdGhlIGVudGl0eSBuYW1pbmcgc2NoZW1lIHVzZWQgaGVyZSBpcyB0aGUgc2FtZSBvbmUKKyAgICAgKiB1c2VkIGluIHRoZSB7QGxpbmsgTGV4aWNhbEhhbmRsZXJ9LCBvciBpbiB0aGUge0BsaW5rCisgICAgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2tpcHBlZEVudGl0eQorICAgIENvbnRlbnRIYW5kbGVyLnNraXBwZWRFbnRpdHkoKX0KKyAgICAgKiBtZXRob2QuIDwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIElkZW50aWZpZXMgdGhlIGV4dGVybmFsIGVudGl0eSBiZWluZyByZXNvbHZlZC4KKyAgICAgKiAgICBFaXRoZXIgIltkdGRdIiBmb3IgdGhlIGV4dGVybmFsIHN1YnNldCwgb3IgYSBuYW1lIHN0YXJ0aW5nCisgICAgICogICAgd2l0aCAiJSIgdG8gaW5kaWNhdGUgYSBwYXJhbWV0ZXIgZW50aXR5LCBvciBlbHNlIHRoZSBuYW1lIG9mCisgICAgICogICAgYSBnZW5lcmFsIGVudGl0eS4gIFRoaXMgaXMgbmV2ZXIgbnVsbCB3aGVuIGludm9rZWQgYnkgYSBTQVgyCisgICAgICogICAgcGFyc2VyLgorICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIGVudGl0eSBiZWluZworICAgICAqICAgIHJlZmVyZW5jZWQgKG5vcm1hbGl6ZWQgYXMgcmVxdWlyZWQgYnkgdGhlIFhNTCBzcGVjaWZpY2F0aW9uKSwgb3IKKyAgICAgKiAgICBudWxsIGlmIG5vbmUgd2FzIHN1cHBsaWVkLgorICAgICAqIEBwYXJhbSBiYXNlVVJJIFRoZSBVUkkgd2l0aCByZXNwZWN0IHRvIHdoaWNoIHJlbGF0aXZlIHN5c3RlbUlEcworICAgICAqICAgIGFyZSBpbnRlcnByZXRlZC4gIFRoaXMgaXMgYWx3YXlzIGFuIGFic29sdXRlIFVSSSwgdW5sZXNzIGl0IGlzCisgICAgICogICAgbnVsbCAobGlrZWx5IGJlY2F1c2UgdGhlIFhNTFJlYWRlciB3YXMgZ2l2ZW4gYW4gSW5wdXRTb3VyY2Ugd2l0aG91dAorICAgICAqICBvbmUpLiAgVGhpcyBVUkkgaXMgZGVmaW5lZCBieSB0aGUgWE1MIHNwZWNpZmljYXRpb24gdG8gYmUgdGhlIG9uZQorICAgICAqICAgIGFzc29jaWF0ZWQgd2l0aCB0aGUgIiZsdDsiIHN0YXJ0aW5nIHRoZSByZWxldmFudCBkZWNsYXJhdGlvbi4KKyAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBleHRlcm5hbCBlbnRpdHkKKyAgICAgKiAgICBiZWluZyByZWZlcmVuY2VkOyBlaXRoZXIgYSByZWxhdGl2ZSBvciBhYnNvbHV0ZSBVUkkuCisgICAgICogIFRoaXMgaXMgbmV2ZXIgbnVsbCB3aGVuIGludm9rZWQgYnkgYSBTQVgyIHBhcnNlcjsgb25seSBkZWNsYXJlZAorICAgICAqICAgIGVudGl0aWVzLCBhbmQgYW55IGV4dGVybmFsIHN1YnNldCwgYXJlIHJlc29sdmVkIGJ5IHN1Y2ggcGFyc2Vycy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQW4gSW5wdXRTb3VyY2Ugb2JqZWN0IGRlc2NyaWJpbmcgdGhlIG5ldyBpbnB1dCBzb3VyY2UgdG8KKyAgICAgKiAgICBiZSB1c2VkIGJ5IHRoZSBwYXJzZXIuICBSZXR1cm5pbmcgbnVsbCBkaXJlY3RzIHRoZSBwYXJzZXIgdG8KKyAgICAgKiAgICByZXNvbHZlIHRoZSBzeXN0ZW0gSUQgYWdhaW5zdCB0aGUgYmFzZSBVUkkgYW5kIG9wZW4gYSBjb25uZWN0aW9uCisgICAgICogICAgdG8gcmVzdWx0aW5nIFVSSS4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseSB3cmFwcGluZworICAgICAqICAgIGFub3RoZXIgZXhjZXB0aW9uLgorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gUHJvYmFibHkgaW5kaWNhdGluZyBhIGZhaWx1cmUgdG8gY3JlYXRlCisgICAgICogICAgYSBuZXcgSW5wdXRTdHJlYW0gb3IgUmVhZGVyLCBvciBhbiBpbGxlZ2FsIFVSTC4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eSAoCisgICAgICAgIFN0cmluZyBuYW1lLAorICAgICAgICBTdHJpbmcgcHVibGljSWQsCisgICAgICAgIFN0cmluZyBiYXNlVVJJLAorICAgICAgICBTdHJpbmcgc3lzdGVtSWQKKyAgICApIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2V4dC9MZXhpY2FsSGFuZGxlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2V4dC9MZXhpY2FsSGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgzYWM2ZTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvZXh0L0xleGljYWxIYW5kbGVyLmphdmEKQEAgLTAsMCArMSwyMTIgQEAKKy8vIExleGljYWxIYW5kbGVyLmphdmEgLSBvcHRpb25hbCBoYW5kbGVyIGZvciBsZXhpY2FsIHBhcnNlIGV2ZW50cy4KKy8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKKy8vIFB1YmxpYyBEb21haW46IG5vIHdhcnJhbnR5LgorLy8gJElkOiBMZXhpY2FsSGFuZGxlci5qYXZhLHYgMS41IDIwMDIvMDEvMzAgMjE6MDA6NDQgZGJyb3duZWxsIEV4cCAkCisKK3BhY2thZ2Ugb3JnLnhtbC5zYXguZXh0OworCitpbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOworCisvKioKKyAqIFNBWDIgZXh0ZW5zaW9uIGhhbmRsZXIgZm9yIGxleGljYWwgZXZlbnRzLgorICoKKyAqIDxibG9ja3F1b3RlPgorICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKKyAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KKyAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgorICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+VGhpcyBpcyBhbiBvcHRpb25hbCBleHRlbnNpb24gaGFuZGxlciBmb3IgU0FYMiB0byBwcm92aWRlCisgKiBsZXhpY2FsIGluZm9ybWF0aW9uIGFib3V0IGFuIFhNTCBkb2N1bWVudCwgc3VjaCBhcyBjb21tZW50cworICogYW5kIENEQVRBIHNlY3Rpb24gYm91bmRhcmllcy4KKyAqIFhNTCByZWFkZXJzIGFyZSBub3QgcmVxdWlyZWQgdG8gcmVjb2duaXplIHRoaXMgaGFuZGxlciwgYW5kIGl0CisgKiBpcyBub3QgcGFydCBvZiBjb3JlLW9ubHkgU0FYMiBkaXN0cmlidXRpb25zLjwvcD4KKyAqCisgKiA8cD5UaGUgZXZlbnRzIGluIHRoZSBsZXhpY2FsIGhhbmRsZXIgYXBwbHkgdG8gdGhlIGVudGlyZSBkb2N1bWVudCwKKyAqIG5vdCBqdXN0IHRvIHRoZSBkb2N1bWVudCBlbGVtZW50LCBhbmQgYWxsIGxleGljYWwgaGFuZGxlciBldmVudHMKKyAqIG11c3QgYXBwZWFyIGJldHdlZW4gdGhlIGNvbnRlbnQgaGFuZGxlcidzIHN0YXJ0RG9jdW1lbnQgYW5kCisgKiBlbmREb2N1bWVudCBldmVudHMuPC9wPgorICoKKyAqIDxwPlRvIHNldCB0aGUgTGV4aWNhbEhhbmRsZXIgZm9yIGFuIFhNTCByZWFkZXIsIHVzZSB0aGUKKyAqIHtAbGluayBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0UHJvcGVydHkgc2V0UHJvcGVydHl9IG1ldGhvZAorICogd2l0aCB0aGUgcHJvcGVydHkgbmFtZQorICogPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvbGV4aWNhbC1oYW5kbGVyPC9jb2RlPgorICogYW5kIGFuIG9iamVjdCBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2UgKG9yIG51bGwpIGFzIHRoZSB2YWx1ZS4KKyAqIElmIHRoZSByZWFkZXIgZG9lcyBub3QgcmVwb3J0IGxleGljYWwgZXZlbnRzLCBpdCB3aWxsIHRocm93IGEKKyAqIHtAbGluayBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb259CisgKiB3aGVuIHlvdSBhdHRlbXB0IHRvIHJlZ2lzdGVyIHRoZSBoYW5kbGVyLjwvcD4KKyAqCisgKiBAc2luY2UgU0FYIDIuMCAoZXh0ZW5zaW9ucyAxLjApCisgKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgorICogQHZlcnNpb24gMi4wLjEgKHNheDJyMikKKyAqLworcHVibGljIGludGVyZmFjZSBMZXhpY2FsSGFuZGxlcgoreworCisgICAgLyoqCisgICAgICogUmVwb3J0IHRoZSBzdGFydCBvZiBEVEQgZGVjbGFyYXRpb25zLCBpZiBhbnkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBpbnRlbmRlZCB0byByZXBvcnQgdGhlIGJlZ2lubmluZyBvZiB0aGUKKyAgICAgKiBET0NUWVBFIGRlY2xhcmF0aW9uOyBpZiB0aGUgZG9jdW1lbnQgaGFzIG5vIERPQ1RZUEUgZGVjbGFyYXRpb24sCisgICAgICogdGhpcyBtZXRob2Qgd2lsbCBub3QgYmUgaW52b2tlZC48L3A+CisgICAgICoKKyAgICAgKiA8cD5BbGwgZGVjbGFyYXRpb25zIHJlcG9ydGVkIHRocm91Z2gKKyAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguRFRESGFuZGxlciBEVERIYW5kbGVyfSBvcgorICAgICAqIHtAbGluayBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIgRGVjbEhhbmRsZXJ9IGV2ZW50cyBtdXN0IGFwcGVhcgorICAgICAqIGJldHdlZW4gdGhlIHN0YXJ0RFREIGFuZCB7QGxpbmsgI2VuZERURCBlbmREVER9IGV2ZW50cy4KKyAgICAgKiBEZWNsYXJhdGlvbnMgYXJlIGFzc3VtZWQgdG8gYmVsb25nIHRvIHRoZSBpbnRlcm5hbCBEVEQgc3Vic2V0CisgICAgICogdW5sZXNzIHRoZXkgYXBwZWFyIGJldHdlZW4ge0BsaW5rICNzdGFydEVudGl0eSBzdGFydEVudGl0eX0KKyAgICAgKiBhbmQge0BsaW5rICNlbmRFbnRpdHkgZW5kRW50aXR5fSBldmVudHMuICBDb21tZW50cyBhbmQKKyAgICAgKiBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyBmcm9tIHRoZSBEVEQgc2hvdWxkIGFsc28gYmUgcmVwb3J0ZWQKKyAgICAgKiBiZXR3ZWVuIHRoZSBzdGFydERURCBhbmQgZW5kRFREIGV2ZW50cywgaW4gdGhlaXIgb3JpZ2luYWwKKyAgICAgKiBvcmRlciBvZiAobG9naWNhbCkgb2NjdXJyZW5jZTsgdGhleSBhcmUgbm90IHJlcXVpcmVkIHRvCisgICAgICogYXBwZWFyIGluIHRoZWlyIGNvcnJlY3QgbG9jYXRpb25zIHJlbGF0aXZlIHRvIERUREhhbmRsZXIKKyAgICAgKiBvciBEZWNsSGFuZGxlciBldmVudHMsIGhvd2V2ZXIuPC9wPgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IHRoZSBzdGFydC9lbmREVEQgZXZlbnRzIHdpbGwgYXBwZWFyIHdpdGhpbgorICAgICAqIHRoZSBzdGFydC9lbmREb2N1bWVudCBldmVudHMgZnJvbSBDb250ZW50SGFuZGxlciBhbmQKKyAgICAgKiBiZWZvcmUgdGhlIGZpcnN0CisgICAgICoge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0RWxlbWVudCBzdGFydEVsZW1lbnR9CisgICAgICogZXZlbnQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIGRvY3VtZW50IHR5cGUgbmFtZS4KKyAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIGRlY2xhcmVkIHB1YmxpYyBpZGVudGlmaWVyIGZvciB0aGUKKyAgICAgKiAgICAgICAgZXh0ZXJuYWwgRFREIHN1YnNldCwgb3IgbnVsbCBpZiBub25lIHdhcyBkZWNsYXJlZC4KKyAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIGRlY2xhcmVkIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGUKKyAgICAgKiAgICAgICAgZXh0ZXJuYWwgRFREIHN1YnNldCwgb3IgbnVsbCBpZiBub25lIHdhcyBkZWNsYXJlZC4KKyAgICAgKiAgICAgICAgKE5vdGUgdGhhdCB0aGlzIGlzIG5vdCByZXNvbHZlZCBhZ2FpbnN0IHRoZSBkb2N1bWVudAorICAgICAqICAgICAgICBiYXNlIFVSSS4pCisgICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbgorICAgICAqICAgICAgICAgICAgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgI2VuZERURAorICAgICAqIEBzZWUgI3N0YXJ0RW50aXR5CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc3RhcnREVEQgKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsCisgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkKQorICAgIHRocm93cyBTQVhFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFJlcG9ydCB0aGUgZW5kIG9mIERURCBkZWNsYXJhdGlvbnMuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBpbnRlbmRlZCB0byByZXBvcnQgdGhlIGVuZCBvZiB0aGUKKyAgICAgKiBET0NUWVBFIGRlY2xhcmF0aW9uOyBpZiB0aGUgZG9jdW1lbnQgaGFzIG5vIERPQ1RZUEUgZGVjbGFyYXRpb24sCisgICAgICogdGhpcyBtZXRob2Qgd2lsbCBub3QgYmUgaW52b2tlZC48L3A+CisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlICNzdGFydERURAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGVuZERURCAoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFJlcG9ydCB0aGUgYmVnaW5uaW5nIG9mIHNvbWUgaW50ZXJuYWwgYW5kIGV4dGVybmFsIFhNTCBlbnRpdGllcy4KKyAgICAgKgorICAgICAqIDxwPlRoZSByZXBvcnRpbmcgb2YgcGFyYW1ldGVyIGVudGl0aWVzIChpbmNsdWRpbmcKKyAgICAgKiB0aGUgZXh0ZXJuYWwgRFREIHN1YnNldCkgaXMgb3B0aW9uYWwsIGFuZCBTQVgyIGRyaXZlcnMgdGhhdAorICAgICAqIHJlcG9ydCBMZXhpY2FsSGFuZGxlciBldmVudHMgbWF5IG5vdCBpbXBsZW1lbnQgaXQ7IHlvdSBjYW4gdXNlIHRoZQorICAgICAqIDxjb2RlCisgICAgICogPmh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9sZXhpY2FsLWhhbmRsZXIvcGFyYW1ldGVyLWVudGl0aWVzPC9jb2RlPgorICAgICAqIGZlYXR1cmUgdG8gcXVlcnkgb3IgY29udHJvbCB0aGUgcmVwb3J0aW5nIG9mIHBhcmFtZXRlciBlbnRpdGllcy48L3A+CisgICAgICoKKyAgICAgKiA8cD5HZW5lcmFsIGVudGl0aWVzIGFyZSByZXBvcnRlZCB3aXRoIHRoZWlyIHJlZ3VsYXIgbmFtZXMsCisgICAgICogcGFyYW1ldGVyIGVudGl0aWVzIGhhdmUgJyUnIHByZXBlbmRlZCB0byB0aGVpciBuYW1lcywgYW5kCisgICAgICogdGhlIGV4dGVybmFsIERURCBzdWJzZXQgaGFzIHRoZSBwc2V1ZG8tZW50aXR5IG5hbWUgIltkdGRdIi48L3A+CisgICAgICoKKyAgICAgKiA8cD5XaGVuIGEgU0FYMiBkcml2ZXIgaXMgcHJvdmlkaW5nIHRoZXNlIGV2ZW50cywgYWxsIG90aGVyCisgICAgICogZXZlbnRzIG11c3QgYmUgcHJvcGVybHkgbmVzdGVkIHdpdGhpbiBzdGFydC9lbmQgZW50aXR5CisgICAgICogZXZlbnRzLiAgVGhlcmUgaXMgbm8gYWRkaXRpb25hbCByZXF1aXJlbWVudCB0aGF0IGV2ZW50cyBmcm9tCisgICAgICoge0BsaW5rIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciBEZWNsSGFuZGxlcn0gb3IKKyAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguRFRESGFuZGxlciBEVERIYW5kbGVyfSBiZSBwcm9wZXJseSBvcmRlcmVkLjwvcD4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCBza2lwcGVkIGVudGl0aWVzIHdpbGwgYmUgcmVwb3J0ZWQgdGhyb3VnaCB0aGUKKyAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2tpcHBlZEVudGl0eSBza2lwcGVkRW50aXR5fQorICAgICAqIGV2ZW50LCB3aGljaCBpcyBwYXJ0IG9mIHRoZSBDb250ZW50SGFuZGxlciBpbnRlcmZhY2UuPC9wPgorICAgICAqCisgICAgICogPHA+QmVjYXVzZSBvZiB0aGUgc3RyZWFtaW5nIGV2ZW50IG1vZGVsIHRoYXQgU0FYIHVzZXMsIHNvbWUKKyAgICAgKiBlbnRpdHkgYm91bmRhcmllcyBjYW5ub3QgYmUgcmVwb3J0ZWQgdW5kZXIgYW55CisgICAgICogY2lyY3Vtc3RhbmNlczo8L3A+CisgICAgICoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPmdlbmVyYWwgZW50aXRpZXMgd2l0aGluIGF0dHJpYnV0ZSB2YWx1ZXM8L2xpPgorICAgICAqIDxsaT5wYXJhbWV0ZXIgZW50aXRpZXMgd2l0aGluIGRlY2xhcmF0aW9uczwvbGk+CisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPlRoZXNlIHdpbGwgYmUgc2lsZW50bHkgZXhwYW5kZWQsIHdpdGggbm8gaW5kaWNhdGlvbiBvZiB3aGVyZQorICAgICAqIHRoZSBvcmlnaW5hbCBlbnRpdHkgYm91bmRhcmllcyB3ZXJlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgYWxzbyB0aGF0IHRoZSBib3VuZGFyaWVzIG9mIGNoYXJhY3RlciByZWZlcmVuY2VzICh3aGljaAorICAgICAqIGFyZSBub3QgcmVhbGx5IGVudGl0aWVzIGFueXdheSkgYXJlIG5vdCByZXBvcnRlZC48L3A+CisgICAgICoKKyAgICAgKiA8cD5BbGwgc3RhcnQvZW5kRW50aXR5IGV2ZW50cyBtdXN0IGJlIHByb3Blcmx5IG5lc3RlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuICBJZiBpdCBpcyBhIHBhcmFtZXRlcgorICAgICAqICAgICAgICBlbnRpdHksIHRoZSBuYW1lIHdpbGwgYmVnaW4gd2l0aCAnJScsIGFuZCBpZiBpdCBpcyB0aGUKKyAgICAgKiAgICAgICAgZXh0ZXJuYWwgRFREIHN1YnNldCwgaXQgd2lsbCBiZSAiW2R0ZF0iLgorICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgorICAgICAqIEBzZWUgI2VuZEVudGl0eQorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyI2ludGVybmFsRW50aXR5RGVjbAorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyI2V4dGVybmFsRW50aXR5RGVjbAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHN0YXJ0RW50aXR5IChTdHJpbmcgbmFtZSkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBSZXBvcnQgdGhlIGVuZCBvZiBhbiBlbnRpdHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5IHRoYXQgaXMgZW5kaW5nLgorICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgorICAgICAqIEBzZWUgI3N0YXJ0RW50aXR5CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZW5kRW50aXR5IChTdHJpbmcgbmFtZSkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBSZXBvcnQgdGhlIHN0YXJ0IG9mIGEgQ0RBVEEgc2VjdGlvbi4KKyAgICAgKgorICAgICAqIDxwPlRoZSBjb250ZW50cyBvZiB0aGUgQ0RBVEEgc2VjdGlvbiB3aWxsIGJlIHJlcG9ydGVkIHRocm91Z2gKKyAgICAgKiB0aGUgcmVndWxhciB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjY2hhcmFjdGVycworICAgICAqIGNoYXJhY3RlcnN9IGV2ZW50OyB0aGlzIGV2ZW50IGlzIGludGVuZGVkIG9ubHkgdG8gcmVwb3J0CisgICAgICogdGhlIGJvdW5kYXJ5LjwvcD4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgorICAgICAqIEBzZWUgI2VuZENEQVRBCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc3RhcnRDREFUQSAoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFJlcG9ydCB0aGUgZW5kIG9mIGEgQ0RBVEEgc2VjdGlvbi4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgorICAgICAqIEBzZWUgI3N0YXJ0Q0RBVEEKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBlbmRDREFUQSAoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFJlcG9ydCBhbiBYTUwgY29tbWVudCBhbnl3aGVyZSBpbiB0aGUgZG9jdW1lbnQuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGNhbGxiYWNrIHdpbGwgYmUgdXNlZCBmb3IgY29tbWVudHMgaW5zaWRlIG9yIG91dHNpZGUgdGhlCisgICAgICogZG9jdW1lbnQgZWxlbWVudCwgaW5jbHVkaW5nIGNvbW1lbnRzIGluIHRoZSBleHRlcm5hbCBEVEQKKyAgICAgKiBzdWJzZXQgKGlmIHJlYWQpLiAgQ29tbWVudHMgaW4gdGhlIERURCBtdXN0IGJlIHByb3Blcmx5CisgICAgICogbmVzdGVkIGluc2lkZSBzdGFydC9lbmREVEQgYW5kIHN0YXJ0L2VuZEVudGl0eSBldmVudHMgKGlmCisgICAgICogdXNlZCkuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGNoIEFuIGFycmF5IGhvbGRpbmcgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIGNvbW1lbnQuCisgICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCisgICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlIGZyb20gdGhlIGFycmF5LgorICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGNvbW1lbnQgKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb247CisKK30KKworLy8gZW5kIG9mIExleGljYWxIYW5kbGVyLmphdmEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9leHQvTG9jYXRvcjIuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9leHQvTG9jYXRvcjIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YzIxMmQwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2V4dC9Mb2NhdG9yMi5qYXZhCkBAIC0wLDAgKzEsNzUgQEAKKy8vIExvY2F0b3IyLmphdmEgLSBleHRlbmRlZCBMb2NhdG9yCisvLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCisvLyBQdWJsaWMgRG9tYWluOiBubyB3YXJyYW50eS4KKy8vICRJZDogTG9jYXRvcjIuamF2YSx2IDEuNSAyMDA0LzAzLzE3IDE0OjMwOjEwIGRtZWdnaW5zb24gRXhwICQKKworcGFja2FnZSBvcmcueG1sLnNheC5leHQ7CisKK2ltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOworCisKKy8qKgorICogU0FYMiBleHRlbnNpb24gdG8gYXVnbWVudCB0aGUgZW50aXR5IGluZm9ybWF0aW9uIHByb3ZpZGVkCisgKiB0aG91Z2ggYSB7QGxpbmsgTG9jYXRvcn0uCisgKiBJZiBhbiBpbXBsZW1lbnRhdGlvbiBzdXBwb3J0cyB0aGlzIGV4dGVuc2lvbiwgdGhlIExvY2F0b3IKKyAqIHByb3ZpZGVkIGluIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzZXREb2N1bWVudExvY2F0b3IKKyAqIENvbnRlbnRIYW5kbGVyLnNldERvY3VtZW50TG9jYXRvcigpIH0gd2lsbCBpbXBsZW1lbnQgdGhpcworICogaW50ZXJmYWNlLCBhbmQgdGhlCisgKiA8ZW0+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3VzZS1sb2NhdG9yMjwvZW0+IGZlYXR1cmUKKyAqIGZsYWcgd2lsbCBoYXZlIHRoZSB2YWx1ZSA8ZW0+dHJ1ZTwvZW0+LgorICoKKyAqIDxibG9ja3F1b3RlPgorICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKKyAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KKyAqIDwvYmxvY2txdW90ZT4KKyAqCisgKiA8cD4gWE1MUmVhZGVyIGltcGxlbWVudGF0aW9ucyBhcmUgbm90IHJlcXVpcmVkIHRvIHN1cHBvcnQgdGhpcworICogaW5mb3JtYXRpb24sIGFuZCBpdCBpcyBub3QgcGFydCBvZiBjb3JlLW9ubHkgU0FYMiBkaXN0cmlidXRpb25zLjwvcD4KKyAqCisgKiBAc2luY2UgU0FYIDIuMCAoZXh0ZW5zaW9ucyAxLjEgYWxwaGEpCisgKiBAYXV0aG9yIERhdmlkIEJyb3duZWxsCisgKiBAdmVyc2lvbiBUQlMKKyAqLworcHVibGljIGludGVyZmFjZSBMb2NhdG9yMiBleHRlbmRzIExvY2F0b3IKK3sKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2ZXJzaW9uIG9mIFhNTCB1c2VkIGZvciB0aGUgZW50aXR5LiAgVGhpcyB3aWxsCisgICAgICogbm9ybWFsbHkgYmUgdGhlIGlkZW50aWZpZXIgZnJvbSB0aGUgY3VycmVudCBlbnRpdHkncworICAgICAqIDxlbT4mbHQ7P3htbCZuYnNwO3ZlcnNpb249Jy4uLicmbmJzcDsuLi4/Jmd0OzwvZW0+IGRlY2xhcmF0aW9uLAorICAgICAqIG9yIGJlIGRlZmF1bHRlZCBieSB0aGUgcGFyc2VyLgorICAgICAqCisgICAgICogQHJldHVybiBJZGVudGlmaWVyIGZvciB0aGUgWE1MIHZlcnNpb24gYmVpbmcgdXNlZCB0byBpbnRlcnByZXQKKyAgICAgKiB0aGUgZW50aXR5J3MgdGV4dCwgb3IgbnVsbCBpZiB0aGF0IGluZm9ybWF0aW9uIGlzIG5vdCB5ZXQKKyAgICAgKiBhdmFpbGFibGUgaW4gdGhlIGN1cnJlbnQgcGFyc2luZyBzdGF0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFhNTFZlcnNpb24gKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgZm9yIHRoZSBlbnRpdHkuCisgICAgICogSWYgdGhlIGVuY29kaW5nIHdhcyBkZWNsYXJlZCBleHRlcm5hbGx5IChmb3IgZXhhbXBsZSwgaW4gYSBNSU1FCisgICAgICogQ29udGVudC1UeXBlIGhlYWRlciksIHRoYXQgd2lsbCBiZSB0aGUgbmFtZSByZXR1cm5lZC4gIEVsc2UgaWYgdGhlcmUKKyAgICAgKiB3YXMgYW4gPGVtPiZsdDs/eG1sJm5ic3A7Li4uZW5jb2Rpbmc9Jy4uLic/Jmd0OzwvZW0+IGRlY2xhcmF0aW9uIGF0CisgICAgICogdGhlIHN0YXJ0IG9mIHRoZSBkb2N1bWVudCwgdGhhdCBlbmNvZGluZyBuYW1lIHdpbGwgYmUgcmV0dXJuZWQuCisgICAgICogT3RoZXJ3aXNlIHRoZSBlbmNvZGluZyB3aWxsIGJlZW4gaW5mZXJyZWQgKG5vcm1hbGx5IHRvIGJlIFVURi04LCBvcgorICAgICAqIHNvbWUgVVRGLTE2IHZhcmlhbnQpLCBhbmQgdGhhdCBpbmZlcnJlZCBuYW1lIHdpbGwgYmUgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiA8cD5XaGVuIGFuIHtAbGluayBvcmcueG1sLnNheC5JbnB1dFNvdXJjZSBJbnB1dFNvdXJjZX0gaXMgdXNlZAorICAgICAqIHRvIHByb3ZpZGUgYW4gZW50aXR5J3MgY2hhcmFjdGVyIHN0cmVhbSwgdGhpcyBtZXRob2QgcmV0dXJucyB0aGUKKyAgICAgKiBlbmNvZGluZyBwcm92aWRlZCBpbiB0aGF0IGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIDxwPiBOb3RlIHRoYXQgc29tZSByZWNlbnQgVzNDIHNwZWNpZmljYXRpb25zIHJlcXVpcmUgdGhhdCB0ZXh0CisgICAgICogaW4gc29tZSBlbmNvZGluZ3MgYmUgbm9ybWFsaXplZCwgdXNpbmcgVW5pY29kZSBOb3JtYWxpemF0aW9uCisgICAgICogRm9ybSBDLCBiZWZvcmUgcHJvY2Vzc2luZy4gIFN1Y2ggbm9ybWFsaXphdGlvbiBtdXN0IGJlIHBlcmZvcm1lZAorICAgICAqIGJ5IGFwcGxpY2F0aW9ucywgYW5kIHdvdWxkIG5vcm1hbGx5IGJlIHRyaWdnZXJlZCBiYXNlZCBvbiB0aGUKKyAgICAgKiB2YWx1ZSByZXR1cm5lZCBieSB0aGlzIG1ldGhvZC4KKyAgICAgKgorICAgICAqIDxwPiBFbmNvZGluZyBuYW1lcyBtYXkgYmUgdGhvc2UgdXNlZCBieSB0aGUgdW5kZXJseWluZyBKVk0sCisgICAgICogYW5kIGNvbXBhcmlzb25zIHNob3VsZCBiZSBjYXNlLWluc2Vuc2l0aXZlLgorICAgICAqCisgICAgICogQHJldHVybiBOYW1lIG9mIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgYmVpbmcgdXNlZCB0byBpbnRlcnByZXQKKyAgICAgKiAqIHRoZSBlbnRpdHkncyB0ZXh0LCBvciBudWxsIGlmIHRoaXMgd2FzIG5vdCBwcm92aWRlZCBmb3IgYSAqCisgICAgICogY2hhcmFjdGVyIHN0cmVhbSBwYXNzZWQgdGhyb3VnaCBhbiBJbnB1dFNvdXJjZSBvciBpcyBvdGhlcndpc2UKKyAgICAgKiBub3QgeWV0IGF2YWlsYWJsZSBpbiB0aGUgY3VycmVudCBwYXJzaW5nIHN0YXRlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcgKCk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvZXh0L0xvY2F0b3IySW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2V4dC9Mb2NhdG9yMkltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45Mjc0ZDU4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2V4dC9Mb2NhdG9yMkltcGwuamF2YQpAQCAtMCwwICsxLDEwNSBAQAorLy8gTG9jYXRvcjJJbXBsLmphdmEgLSBleHRlbmRlZCBMb2NhdG9ySW1wbAorLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZworLy8gUHVibGljIERvbWFpbjogbm8gd2FycmFudHkuCisvLyAkSWQ6IExvY2F0b3IySW1wbC5qYXZhLHYgMS4zIDIwMDQvMDQvMjYgMTc6MzQ6MzUgZG1lZ2dpbnNvbiBFeHAgJAorCitwYWNrYWdlIG9yZy54bWwuc2F4LmV4dDsKKworaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7CitpbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5Mb2NhdG9ySW1wbDsKKworCisvKioKKyAqIFNBWDIgZXh0ZW5zaW9uIGhlbHBlciBmb3IgaG9sZGluZyBhZGRpdGlvbmFsIEVudGl0eSBpbmZvcm1hdGlvbiwKKyAqIGltcGxlbWVudGluZyB0aGUge0BsaW5rIExvY2F0b3IyfSBpbnRlcmZhY2UuCisgKgorICogPGJsb2NrcXVvdGU+CisgKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQorICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgorICogPC9ibG9ja3F1b3RlPgorICoKKyAqIDxwPiBUaGlzIGlzIG5vdCBwYXJ0IG9mIGNvcmUtb25seSBTQVgyIGRpc3RyaWJ1dGlvbnMuPC9wPgorICoKKyAqIEBzaW5jZSBTQVggMi4wLjIKKyAqIEBhdXRob3IgRGF2aWQgQnJvd25lbGwKKyAqIEB2ZXJzaW9uIFRCUworICovCitwdWJsaWMgY2xhc3MgTG9jYXRvcjJJbXBsIGV4dGVuZHMgTG9jYXRvckltcGwgaW1wbGVtZW50cyBMb2NhdG9yMgoreworICAgIHByaXZhdGUgU3RyaW5nICAgIGVuY29kaW5nOworICAgIHByaXZhdGUgU3RyaW5nICAgIHZlcnNpb247CisKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIG5ldywgZW1wdHkgTG9jYXRvcjJJbXBsIG9iamVjdC4KKyAgICAgKiBUaGlzIHdpbGwgbm90IG5vcm1hbGx5IGJlIHVzZWZ1bCwgc2luY2UgdGhlIG1haW4gcHVycG9zZQorICAgICAqIG9mIHRoaXMgY2xhc3MgaXMgdG8gbWFrZSBhIHNuYXBzaG90IG9mIGFuIGV4aXN0aW5nIExvY2F0b3IuCisgICAgICovCisgICAgcHVibGljIExvY2F0b3IySW1wbCAoKSB7IH0KKworICAgIC8qKgorICAgICAqIENvcHkgYW4gZXhpc3RpbmcgTG9jYXRvciBvciBMb2NhdG9yMiBvYmplY3QuCisgICAgICogSWYgdGhlIG9iamVjdCBpbXBsZW1lbnRzIExvY2F0b3IyLCB2YWx1ZXMgb2YgdGhlCisgICAgICogPGVtPmVuY29kaW5nPC9lbT4gYW5kIDxlbT52ZXJzaW9uPC9lbT5zdHJpbmdzIGFyZSBjb3BpZWQsCisgICAgICogb3RoZXJ3aXNlIHRoZXkgc2V0IHRvIDxlbT5udWxsPC9lbT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgZXhpc3RpbmcgTG9jYXRvciBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIExvY2F0b3IySW1wbCAoTG9jYXRvciBsb2NhdG9yKQorICAgIHsKKyAgICBzdXBlciAobG9jYXRvcik7CisgICAgaWYgKGxvY2F0b3IgaW5zdGFuY2VvZiBMb2NhdG9yMikgeworICAgICAgICBMb2NhdG9yMiAgICBsMiA9IChMb2NhdG9yMikgbG9jYXRvcjsKKworICAgICAgICB2ZXJzaW9uID0gbDIuZ2V0WE1MVmVyc2lvbiAoKTsKKyAgICAgICAgZW5jb2RpbmcgPSBsMi5nZXRFbmNvZGluZyAoKTsKKyAgICB9CisgICAgfQorCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBMb2NhdG9yMiBtZXRob2QgaW1wbGVtZW50YXRpb25zCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHZlcnNpb24gcHJvcGVydHkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSB2ZXJzaW9uIHByb3BlcnR5LgorICAgICAqCisgICAgICogQHNlZSAjc2V0WE1MVmVyc2lvbgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0WE1MVmVyc2lvbiAoKQorICAgIHsgcmV0dXJuIHZlcnNpb247IH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGVuY29kaW5nIHByb3BlcnR5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZW5jb2RpbmcgcHJvcGVydHkuCisgICAgICoKKyAgICAgKiBAc2VlICNzZXRFbmNvZGluZworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcgKCkKKyAgICB7IHJldHVybiBlbmNvZGluZzsgfQorCisKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIFNldHRlcnMKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisgICAgLyoqCisgICAgICogQXNzaWducyB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgdmVyc2lvbiBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2ZXJzaW9uIHRoZSBuZXcgInZlcnNpb24iIHZhbHVlCisgICAgICogQHNlZSAjZ2V0WE1MVmVyc2lvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFhNTFZlcnNpb24gKFN0cmluZyB2ZXJzaW9uKQorICAgIHsgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjsgfQorCisgICAgLyoqCisgICAgICogQXNzaWducyB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZW5jb2RpbmcgcHJvcGVydHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIG5ldyAiZW5jb2RpbmciIHZhbHVlCisgICAgICogQHNlZSAjZ2V0RW5jb2RpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyAoU3RyaW5nIGVuY29kaW5nKQorICAgIHsgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOyB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvZXh0L3BhY2thZ2UuaHRtbCBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9leHQvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU0NDNkZjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvZXh0L3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDQ2IEBACis8SFRNTD48SEVBRD4KKzwhLS0gJElkOiBwYWNrYWdlLmh0bWwsdiAxLjggMjAwMi8wMS8zMCAyMTowMDo0NCBkYnJvd25lbGwgRXhwICQgLS0+Cis8L0hFQUQ+PEJPRFk+CisKKzxwPgorVGhpcyBwYWNrYWdlIGNvbnRhaW5zIGludGVyZmFjZXMgdG8gU0FYMiBmYWNpbGl0aWVzIHRoYXQKK2NvbmZvcm1hbnQgU0FYIGRyaXZlcnMgd29uJ3QgbmVjZXNzYXJpbHkgc3VwcG9ydC4KKworPHA+U2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+Citmb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBTQVguPC9wPgorCis8cD4gVGhpcyBwYWNrYWdlIGlzIGluZGVwZW5kZW50IG9mIHRoZSBTQVgyIGNvcmUsIHRob3VnaCB0aGUgZnVuY3Rpb25hbGl0eQorZXhwb3NlZCBnZW5lcmFsbHkgbmVlZHMgdG8gYmUgaW1wbGVtZW50ZWQgd2l0aGluIGEgcGFyc2VyIGNvcmUuCitUaGF0IGluZGVwZW5kZW5jZSBoYXMgc2V2ZXJhbCBjb25zZXF1ZW5jZXM6PC9wPgorCis8dWw+CisKKzxsaT5TQVgyIGRyaXZlcnMgYXJlIDxlbT5ub3Q8L2VtPiByZXF1aXJlZCB0byByZWNvZ25pemUgdGhlc2UgaGFuZGxlcnMuCis8L2xpPgorCis8bGk+WW91IGNhbm5vdCBhc3N1bWUgdGhhdCB0aGUgY2xhc3MgZmlsZXMgd2lsbCBiZSBwcmVzZW50IGluIGV2ZXJ5IFNBWDIKK2luc3RhbGxhdGlvbi48L2xpPgorCis8bGk+VGhpcyBwYWNrYWdlIG1heSBiZSB1cGRhdGVkIGluZGVwZW5kZW50bHkgb2YgU0FYMiAoaS5lLiBuZXcKK2hhbmRsZXJzIGFuZCBjbGFzc2VzIG1heSBiZSBhZGRlZCB3aXRob3V0IHVwZGF0aW5nIFNBWDIgaXRzZWxmKS48L2xpPgorCis8bGk+VGhlIG5ldyBoYW5kbGVycyBhcmUgbm90IGltcGxlbWVudGVkIGJ5IHRoZSBTQVgyCis8Y29kZT5vcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyPC9jb2RlPiBvcgorPGNvZGU+b3JnLnhtbC5zYXguaGVscGVycy5YTUxGaWx0ZXJJbXBsPC9jb2RlPiBjbGFzc2VzLgorWW91IGNhbiBzdWJjbGFzcyB0aGVzZSBpZiB5b3UgbmVlZCBzdWNoIGJlaGF2aW9yLCBvcgordXNlIHRoZSBoZWxwZXIgY2xhc3NlcyBmb3VuZCBoZXJlLjwvbGk+CisKKzxsaT5UaGUgaGFuZGxlcnMgbmVlZCB0byBiZSByZWdpc3RlcmVkIGRpZmZlcmVudGx5IHRoYW4gY29yZSBTQVgyCitoYW5kbGVycy48L2xpPgorCis8L3VsPgorCis8cD5UaGlzIHBhY2thZ2UsIFNBWDItZXh0LCBpcyBhIHN0YW5kYXJkaXplZCBleHRlbnNpb24gdG8gU0FYMi4gIEl0IGlzCitkZXNpZ25lZCBib3RoIHRvIGFsbG93IFNBWCBwYXJzZXJzIHRvIHBhc3MgY2VydGFpbiB0eXBlcyBvZiBpbmZvcm1hdGlvbgordG8gYXBwbGljYXRpb25zLCBhbmQgdG8gc2VydmUgYXMgYSBzaW1wbGUgbW9kZWwgZm9yIG90aGVyIFNBWDIgcGFyc2VyCitleHRlbnNpb24gcGFja2FnZXMuICBOb3QgYWxsIHN1Y2ggZXh0ZW5zaW9uIHBhY2thZ2VzIHNob3VsZCBuZWVkIHRvCitiZSByZWNvZ25pemVkIGRpcmVjdGx5IGJ5IHBhcnNlcnMsIGhvd2V2ZXIuCitBcyBhbiBleGFtcGxlLCBtb3N0IHZhbGlkYXRpb24gc3lzdGVtcyBjYW4gYmUgY2xlYW5seSBsYXllcmVkIG9uIHRvcAorb2YgcGFyc2VycyBzdXBwb3J0aW5nIHRoZSBzdGFuZGFyZGl6ZWQgU0FYMiBpbnRlcmZhY2VzLiAgPC9wPgorCis8L0JPRFk+PC9IVE1MPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2hlbHBlcnMvQXR0cmlidXRlTGlzdEltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9oZWxwZXJzL0F0dHJpYnV0ZUxpc3RJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWFlMTlkYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9oZWxwZXJzL0F0dHJpYnV0ZUxpc3RJbXBsLmphdmEKQEAgLTAsMCArMSwyOTIgQEAKKy8vIFNBWCBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGZvciBBdHRyaWJ1dGVMaXN0LgorLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZworLy8gTm8gd2FycmFudHk7IG5vIGNvcHlyaWdodCAtLSB1c2UgdGhpcyBhcyB5b3Ugd2lsbC4KKy8vICRJZDogQXR0cmlidXRlTGlzdEltcGwuamF2YSx2IDEuNiAyMDAyLzAxLzMwIDIwOjUyOjIyIGRicm93bmVsbCBFeHAgJAorCitwYWNrYWdlIG9yZy54bWwuc2F4LmhlbHBlcnM7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3Q7CisKKworLyoqCisgKiBEZWZhdWx0IGltcGxlbWVudGF0aW9uIGZvciBBdHRyaWJ1dGVMaXN0LgorICoKKyAqIDxibG9ja3F1b3RlPgorICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKKyAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KKyAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgorICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+QXR0cmlidXRlTGlzdCBpbXBsZW1lbnRzIHRoZSBkZXByZWNhdGVkIFNBWDEge0BsaW5rCisgKiBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0IEF0dHJpYnV0ZUxpc3R9IGludGVyZmFjZSwgYW5kIGhhcyBiZWVuCisgKiByZXBsYWNlZCBieSB0aGUgbmV3IFNBWDIge0BsaW5rIG9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlc0ltcGwKKyAqIEF0dHJpYnV0ZXNJbXBsfSBpbnRlcmZhY2UuPC9wPgorICoKKyAqIDxwPlRoaXMgY2xhc3MgcHJvdmlkZXMgYSBjb252ZW5pZW5jZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU0FYCisgKiB7QGxpbmsgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdCBBdHRyaWJ1dGVMaXN0fSBpbnRlcmZhY2UuICBUaGlzCisgKiBpbXBsZW1lbnRhdGlvbiBpcyB1c2VmdWwgYm90aCBmb3IgU0FYIHBhcnNlciB3cml0ZXJzLCB3aG8gY2FuIHVzZQorICogaXQgdG8gcHJvdmlkZSBhdHRyaWJ1dGVzIHRvIHRoZSBhcHBsaWNhdGlvbiwgYW5kIGZvciBTQVggYXBwbGljYXRpb24KKyAqIHdyaXRlcnMsIHdobyBjYW4gdXNlIGl0IHRvIGNyZWF0ZSBhIHBlcnNpc3RlbnQgY29weSBvZiBhbiBlbGVtZW50J3MKKyAqIGF0dHJpYnV0ZSBzcGVjaWZpY2F0aW9uczo8L3A+CisgKgorICogPHByZT4KKyAqIHByaXZhdGUgQXR0cmlidXRlTGlzdCBteWF0dHM7CisgKgorICogcHVibGljIHZvaWQgc3RhcnRFbGVtZW50IChTdHJpbmcgbmFtZSwgQXR0cmlidXRlTGlzdCBhdHRzKQorICogeworICogICAgICAgICAgICAgIC8vIGNyZWF0ZSBhIHBlcnNpc3RlbnQgY29weSBvZiB0aGUgYXR0cmlidXRlIGxpc3QKKyAqICAgICAgICAgICAgICAvLyBmb3IgdXNlIG91dHNpZGUgdGhpcyBtZXRob2QKKyAqICAgbXlhdHRzID0gbmV3IEF0dHJpYnV0ZUxpc3RJbXBsKGF0dHMpOworICogICBbLi4uXQorICogfQorICogPC9wcmU+CisgKgorICogPHA+UGxlYXNlIG5vdGUgdGhhdCBTQVggcGFyc2VycyBhcmUgbm90IHJlcXVpcmVkIHRvIHVzZSB0aGlzCisgKiBjbGFzcyB0byBwcm92aWRlIGFuIGltcGxlbWVudGF0aW9uIG9mIEF0dHJpYnV0ZUxpc3Q7IGl0IGlzCisgKiBzdXBwbGllZCBvbmx5IGFzIGFuIG9wdGlvbmFsIGNvbnZlbmllbmNlLiAgSW4gcGFydGljdWxhciwKKyAqIHBhcnNlciB3cml0ZXJzIGFyZSBlbmNvdXJhZ2VkIHRvIGludmVudCBtb3JlIGVmZmljaWVudAorICogaW1wbGVtZW50YXRpb25zLjwvcD4KKyAqCisgKiBAZGVwcmVjYXRlZCBUaGlzIGNsYXNzIGltcGxlbWVudHMgYSBkZXByZWNhdGVkIGludGVyZmFjZSwKKyAqICAgICAgICAgICAgIHtAbGluayBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0IEF0dHJpYnV0ZUxpc3R9OworICogICAgICAgICAgICAgdGhhdCBpbnRlcmZhY2UgaGFzIGJlZW4gcmVwbGFjZWQgYnkKKyAqICAgICAgICAgICAgIHtAbGluayBvcmcueG1sLnNheC5BdHRyaWJ1dGVzIEF0dHJpYnV0ZXN9LAorICogICAgICAgICAgICAgd2hpY2ggaXMgaW1wbGVtZW50ZWQgaW4gdGhlCisgKiAgICAgICAgICAgICB7QGxpbmsgb3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVzSW1wbAorICogICAgICAgICAgICBBdHRyaWJ1dGVzSW1wbH0gaGVscGVyIGNsYXNzLgorICogQHNpbmNlIFNBWCAxLjAKKyAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCisgKiBAdmVyc2lvbiAyLjAuMSAoc2F4MnIyKQorICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0CisgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciNzdGFydEVsZW1lbnQKKyAqLworQERlcHJlY2F0ZWQKK3B1YmxpYyBjbGFzcyBBdHRyaWJ1dGVMaXN0SW1wbCBpbXBsZW1lbnRzIEF0dHJpYnV0ZUxpc3QKK3sKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhbiBlbXB0eSBhdHRyaWJ1dGUgbGlzdC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgY29uc3RydWN0b3IgaXMgbW9zdCB1c2VmdWwgZm9yIHBhcnNlciB3cml0ZXJzLCB3aG8KKyAgICAgKiB3aWxsIHVzZSBpdCB0byBjcmVhdGUgYSBzaW5nbGUsIHJldXNhYmxlIGF0dHJpYnV0ZSBsaXN0IHRoYXQKKyAgICAgKiBjYW4gYmUgcmVzZXQgd2l0aCB0aGUgY2xlYXIgbWV0aG9kIGJldHdlZW4gZWxlbWVudHMuPC9wPgorICAgICAqCisgICAgICogQHNlZSAjYWRkQXR0cmlidXRlCisgICAgICogQHNlZSAjY2xlYXIKKyAgICAgKi8KKyAgICBwdWJsaWMgQXR0cmlidXRlTGlzdEltcGwgKCkKKyAgICB7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBwZXJzaXN0ZW50IGNvcHkgb2YgYW4gZXhpc3RpbmcgYXR0cmlidXRlIGxpc3QuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGNvbnN0cnVjdG9yIGlzIG1vc3QgdXNlZnVsIGZvciBhcHBsaWNhdGlvbiB3cml0ZXJzLAorICAgICAqIHdobyB3aWxsIHVzZSBpdCB0byBjcmVhdGUgYSBwZXJzaXN0ZW50IGNvcHkgb2YgYW4gZXhpc3RpbmcKKyAgICAgKiBhdHRyaWJ1dGUgbGlzdC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gYXR0cyBUaGUgYXR0cmlidXRlIGxpc3QgdG8gY29weQorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyI3N0YXJ0RWxlbWVudAorICAgICAqLworICAgIHB1YmxpYyBBdHRyaWJ1dGVMaXN0SW1wbCAoQXR0cmlidXRlTGlzdCBhdHRzKQorICAgIHsKKyAgICBzZXRBdHRyaWJ1dGVMaXN0KGF0dHMpOworICAgIH0KKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBNZXRob2RzIHNwZWNpZmljIHRvIHRoaXMgY2xhc3MuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBhdHRyaWJ1dGUgbGlzdCwgZGlzY2FyZGluZyBwcmV2aW91cyBjb250ZW50cy4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGFsbG93cyBhbiBhcHBsaWNhdGlvbiB3cml0ZXIgdG8gcmV1c2UgYW4KKyAgICAgKiBhdHRyaWJ1dGUgbGlzdCBlYXNpbHkuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGF0dHMgVGhlIGF0dHJpYnV0ZSBsaXN0IHRvIGNvcHkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QXR0cmlidXRlTGlzdCAoQXR0cmlidXRlTGlzdCBhdHRzKQorICAgIHsKKyAgICBpbnQgY291bnQgPSBhdHRzLmdldExlbmd0aCgpOworCisgICAgY2xlYXIoKTsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgeworICAgICAgICBhZGRBdHRyaWJ1dGUoYXR0cy5nZXROYW1lKGkpLCBhdHRzLmdldFR5cGUoaSksIGF0dHMuZ2V0VmFsdWUoaSkpOworICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEFkZCBhbiBhdHRyaWJ1dGUgdG8gYW4gYXR0cmlidXRlIGxpc3QuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBwcm92aWRlZCBmb3IgU0FYIHBhcnNlciB3cml0ZXJzLCB0byBhbGxvdyB0aGVtCisgICAgICogdG8gYnVpbGQgdXAgYW4gYXR0cmlidXRlIGxpc3QgaW5jcmVtZW50YWxseSBiZWZvcmUgZGVsaXZlcmluZworICAgICAqIGl0IHRvIHRoZSBhcHBsaWNhdGlvbi48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgYXR0cmlidXRlIG5hbWUuCisgICAgICogQHBhcmFtIHR5cGUgVGhlIGF0dHJpYnV0ZSB0eXBlICgiTk1UT0tFTiIgZm9yIGFuIGVudW1lcmF0aW9uKS4KKyAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGF0dHJpYnV0ZSB2YWx1ZSAobXVzdCBub3QgYmUgbnVsbCkuCisgICAgICogQHNlZSAjcmVtb3ZlQXR0cmlidXRlCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjc3RhcnRFbGVtZW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlKFN0cmluZyBuYW1lLCBTdHJpbmcgdHlwZSwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIG5hbWVzLmFkZChuYW1lKTsKKyAgICAgICAgdHlwZXMuYWRkKHR5cGUpOworICAgICAgICB2YWx1ZXMuYWRkKHZhbHVlKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJlbW92ZSBhbiBhdHRyaWJ1dGUgZnJvbSB0aGUgbGlzdC4KKyAgICAgKgorICAgICAqIDxwPlNBWCBhcHBsaWNhdGlvbiB3cml0ZXJzIGNhbiB1c2UgdGhpcyBtZXRob2QgdG8gZmlsdGVyIGFuCisgICAgICogYXR0cmlidXRlIG91dCBvZiBhbiBBdHRyaWJ1dGVMaXN0LiAgTm90ZSB0aGF0IGludm9raW5nIHRoaXMKKyAgICAgKiBtZXRob2Qgd2lsbCBjaGFuZ2UgdGhlIGxlbmd0aCBvZiB0aGUgYXR0cmlidXRlIGxpc3QgYW5kCisgICAgICogc29tZSBvZiB0aGUgYXR0cmlidXRlJ3MgaW5kaWNlcy48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgcmVxdWVzdGVkIGF0dHJpYnV0ZSBpcyBub3QgaW4gdGhlIGxpc3QsIHRoaXMgaXMKKyAgICAgKiBhIG5vLW9wLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBhdHRyaWJ1dGUgbmFtZS4KKyAgICAgKiBAc2VlICNhZGRBdHRyaWJ1dGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgaW50IGkgPSBuYW1lcy5pbmRleE9mKG5hbWUpOworICAgICAgICBpZiAoaSAhPSAtMSkgeworICAgICAgICAgICAgbmFtZXMucmVtb3ZlKGkpOworICAgICAgICAgICAgdHlwZXMucmVtb3ZlKGkpOworICAgICAgICAgICAgdmFsdWVzLnJlbW92ZShpKTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogQ2xlYXIgdGhlIGF0dHJpYnV0ZSBsaXN0LgorICAgICAqCisgICAgICogPHA+U0FYIHBhcnNlciB3cml0ZXJzIGNhbiB1c2UgdGhpcyBtZXRob2QgdG8gcmVzZXQgdGhlIGF0dHJpYnV0ZQorICAgICAqIGxpc3QgYmV0d2VlbiBEb2N1bWVudEhhbmRsZXIuc3RhcnRFbGVtZW50IGV2ZW50cy4gIE5vcm1hbGx5LAorICAgICAqIGl0IHdpbGwgbWFrZSBzZW5zZSB0byByZXVzZSB0aGUgc2FtZSBBdHRyaWJ1dGVMaXN0SW1wbCBvYmplY3QKKyAgICAgKiByYXRoZXIgdGhhbiBhbGxvY2F0aW5nIGEgbmV3IG9uZSBlYWNoIHRpbWUuPC9wPgorICAgICAqCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjc3RhcnRFbGVtZW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgIG5hbWVzLmNsZWFyKCk7CisgICAgICAgIHR5cGVzLmNsZWFyKCk7CisgICAgICAgIHZhbHVlcy5jbGVhcigpOworICAgIH0KKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0CisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgYXR0cmlidXRlcyBpbiB0aGUgbGlzdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIGluIHRoZSBsaXN0LgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdCNnZXRMZW5ndGgKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWVzLnNpemUoKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbmFtZSBvZiBhbiBhdHRyaWJ1dGUgKGJ5IHBvc2l0aW9uKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIFRoZSBwb3NpdGlvbiBvZiB0aGUgYXR0cmlidXRlIGluIHRoZSBsaXN0LgorICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSBuYW1lIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIHRoZXJlCisgICAgICogICAgICAgICBpcyBubyBhdHRyaWJ1dGUgYXQgdGhhdCBwb3NpdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3QjZ2V0TmFtZShpbnQpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKGludCBpKSB7CisgICAgICAgIGlmIChpIDwgMCB8fCBpID49IG5hbWVzLnNpemUoKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5hbWVzLmdldChpKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgdHlwZSBvZiBhbiBhdHRyaWJ1dGUgKGJ5IHBvc2l0aW9uKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpIFRoZSBwb3NpdGlvbiBvZiB0aGUgYXR0cmlidXRlIGluIHRoZSBsaXN0LgorICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSB0eXBlIGFzIGEgc3RyaW5nICgiTk1UT0tFTiIgZm9yIGFuCisgICAgICogICAgICAgICBlbnVtZXJhdGlvbiwgYW5kICJDREFUQSIgaWYgbm8gZGVjbGFyYXRpb24gd2FzCisgICAgICogICAgICAgICByZWFkKSwgb3IgbnVsbCBpZiB0aGVyZSBpcyBubyBhdHRyaWJ1dGUgYXQKKyAgICAgKiAgICAgICAgIHRoYXQgcG9zaXRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0I2dldFR5cGUoaW50KQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZShpbnQgaSkgeworICAgICAgICBpZiAoaSA8IDAgfHwgaSA+PSB0eXBlcy5zaXplKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0eXBlcy5nZXQoaSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSAoYnkgcG9zaXRpb24pLgorICAgICAqCisgICAgICogQHBhcmFtIGkgVGhlIHBvc2l0aW9uIG9mIHRoZSBhdHRyaWJ1dGUgaW4gdGhlIGxpc3QuCisgICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIHZhbHVlIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmCisgICAgICogICAgICAgICB0aGVyZSBpcyBubyBhdHRyaWJ1dGUgYXQgdGhhdCBwb3NpdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3QjZ2V0VmFsdWUoaW50KQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoaW50IGkpIHsKKyAgICAgICAgaWYgKGkgPCAwIHx8IGkgPj0gdmFsdWVzLnNpemUoKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHZhbHVlcy5nZXQoaSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHR5cGUgb2YgYW4gYXR0cmlidXRlIChieSBuYW1lKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBhdHRyaWJ1dGUgbmFtZS4KKyAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgdHlwZSBhcyBhIHN0cmluZyAoIk5NVE9LRU4iIGZvciBhbgorICAgICAqICAgICAgICAgZW51bWVyYXRpb24sIGFuZCAiQ0RBVEEiIGlmIG5vIGRlY2xhcmF0aW9uIHdhcworICAgICAqICAgICAgICAgcmVhZCkuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0I2dldFR5cGUoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIGdldFR5cGUobmFtZXMuaW5kZXhPZihuYW1lKSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSAoYnkgbmFtZSkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgYXR0cmlidXRlIG5hbWUuCisgICAgICogQHJldHVybiB0aGUgbmFtZWQgYXR0cmlidXRlJ3MgdmFsdWUgb3IgbnVsbCwgaWYgdGhlIGF0dHJpYnV0ZSBkb2VzIG5vdAorICAgICAqICAgICAgICAgZXhpc3QuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0I2dldFZhbHVlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZShTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gZ2V0VmFsdWUobmFtZXMuaW5kZXhPZihuYW1lKSk7CisgICAgfQorCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIEludGVybmFsIHN0YXRlLgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKyAgICBwcml2YXRlIEFycmF5TGlzdDxTdHJpbmc+IG5hbWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgcHJpdmF0ZSBBcnJheUxpc3Q8U3RyaW5nPiB0eXBlcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgIHByaXZhdGUgQXJyYXlMaXN0PFN0cmluZz4gdmFsdWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisKK30KKworLy8gZW5kIG9mIEF0dHJpYnV0ZUxpc3RJbXBsLmphdmEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9oZWxwZXJzL0F0dHJpYnV0ZXNJbXBsLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvaGVscGVycy9BdHRyaWJ1dGVzSW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY2ZDVmODUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvaGVscGVycy9BdHRyaWJ1dGVzSW1wbC5qYXZhCkBAIC0wLDAgKzEsNjE4IEBACisvLyBBdHRyaWJ1dGVzSW1wbC5qYXZhIC0gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiBBdHRyaWJ1dGVzLgorLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZworLy8gV3JpdHRlbiBieSBEYXZpZCBNZWdnaW5zb24KKy8vIE5PIFdBUlJBTlRZISAgVGhpcyBjbGFzcyBpcyBpbiB0aGUgcHVibGljIGRvbWFpbi4KKy8vICRJZDogQXR0cmlidXRlc0ltcGwuamF2YSx2IDEuOSAyMDAyLzAxLzMwIDIwOjUyOjI0IGRicm93bmVsbCBFeHAgJAorCitwYWNrYWdlIG9yZy54bWwuc2F4LmhlbHBlcnM7CisKK2ltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOworCisKKy8qKgorICogRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgQXR0cmlidXRlcyBpbnRlcmZhY2UuCisgKgorICogPGJsb2NrcXVvdGU+CisgKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQorICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgorICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+CisgKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KKyAqIDwvYmxvY2txdW90ZT4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIHByb3ZpZGVzIGEgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU0FYMgorICoge0BsaW5rIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMgQXR0cmlidXRlc30gaW50ZXJmYWNlLCB3aXRoIHRoZQorICogYWRkaXRpb24gb2YgbWFuaXB1bGF0b3JzIHNvIHRoYXQgdGhlIGxpc3QgY2FuIGJlIG1vZGlmaWVkIG9yCisgKiByZXVzZWQuPC9wPgorICoKKyAqIDxwPlRoZXJlIGFyZSB0d28gdHlwaWNhbCB1c2VzIG9mIHRoaXMgY2xhc3M6PC9wPgorICoKKyAqIDxvbD4KKyAqIDxsaT50byB0YWtlIGEgcGVyc2lzdGVudCBzbmFwc2hvdCBvZiBhbiBBdHRyaWJ1dGVzIG9iamVjdAorICogIGluIGEge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0RWxlbWVudCBzdGFydEVsZW1lbnR9IGV2ZW50OyBvcjwvbGk+CisgKiA8bGk+dG8gY29uc3RydWN0IG9yIG1vZGlmeSBhbiBBdHRyaWJ1dGVzIG9iamVjdCBpbiBhIFNBWDIgZHJpdmVyIG9yIGZpbHRlci48L2xpPgorICogPC9vbD4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIHJlcGxhY2VzIHRoZSBub3ctZGVwcmVjYXRlZCBTQVgxIHtAbGluaworICogb3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVMaXN0SW1wbCBBdHRyaWJ1dGVMaXN0SW1wbH0KKyAqIGNsYXNzOyBpbiBhZGRpdGlvbiB0byBzdXBwb3J0aW5nIHRoZSB1cGRhdGVkIEF0dHJpYnV0ZXMKKyAqIGludGVyZmFjZSByYXRoZXIgdGhhbiB0aGUgZGVwcmVjYXRlZCB7QGxpbmsgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdAorICogQXR0cmlidXRlTGlzdH0gaW50ZXJmYWNlLCBpdCBhbHNvIGluY2x1ZGVzIGEgbXVjaCBtb3JlIGVmZmljaWVudAorICogaW1wbGVtZW50YXRpb24gdXNpbmcgYSBzaW5nbGUgYXJyYXkgcmF0aGVyIHRoYW4gYSBzZXQgb2YgVmVjdG9ycy48L3A+CisgKgorICogQHNpbmNlIFNBWCAyLjAKKyAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCisgKiBAdmVyc2lvbiAyLjAuMSAoc2F4MnIyKQorICovCitwdWJsaWMgY2xhc3MgQXR0cmlidXRlc0ltcGwgaW1wbGVtZW50cyBBdHRyaWJ1dGVzCit7CisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIENvbnN0cnVjdG9ycy4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBuZXcsIGVtcHR5IEF0dHJpYnV0ZXNJbXBsIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXR0cmlidXRlc0ltcGwgKCkKKyAgICB7CisgICAgbGVuZ3RoID0gMDsKKyAgICBkYXRhID0gbnVsbDsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIENvcHkgYW4gZXhpc3RpbmcgQXR0cmlidXRlcyBvYmplY3QuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGNvbnN0cnVjdG9yIGlzIGVzcGVjaWFsbHkgdXNlZnVsIGluc2lkZSBhCisgICAgICoge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0RWxlbWVudCBzdGFydEVsZW1lbnR9IGV2ZW50LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhdHRzIFRoZSBleGlzdGluZyBBdHRyaWJ1dGVzIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQXR0cmlidXRlc0ltcGwgKEF0dHJpYnV0ZXMgYXR0cykKKyAgICB7CisgICAgc2V0QXR0cmlidXRlcyhhdHRzKTsKKyAgICB9CisKKworDAorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gSW1wbGVtZW50YXRpb24gb2Ygb3JnLnhtbC5zYXguQXR0cmlidXRlcy4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIGluIHRoZSBsaXN0LgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMgaW4gdGhlIGxpc3QuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVzI2dldExlbmd0aAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoICgpCisgICAgeworICAgIHJldHVybiBsZW5ndGg7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYW4gYXR0cmlidXRlJ3MgTmFtZXNwYWNlIFVSSS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlJ3MgaW5kZXggKHplcm8tYmFzZWQpLgorICAgICAqIEByZXR1cm4gVGhlIE5hbWVzcGFjZSBVUkksIHRoZSBlbXB0eSBzdHJpbmcgaWYgbm9uZSBpcworICAgICAqICAgICAgICAgYXZhaWxhYmxlLCBvciBudWxsIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVzI2dldFVSSQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VVJJIChpbnQgaW5kZXgpCisgICAgeworICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgbGVuZ3RoKSB7CisgICAgICAgIHJldHVybiBkYXRhW2luZGV4KjVdOworICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybiBhbiBhdHRyaWJ1dGUncyBsb2NhbCBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IFRoZSBhdHRyaWJ1dGUncyBpbmRleCAoemVyby1iYXNlZCkuCisgICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlJ3MgbG9jYWwgbmFtZSwgdGhlIGVtcHR5IHN0cmluZyBpZgorICAgICAqICAgICAgICAgbm9uZSBpcyBhdmFpbGFibGUsIG9yIG51bGwgaWYgdGhlIGluZGV4IGlmIG91dCBvZiByYW5nZS4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMjZ2V0TG9jYWxOYW1lCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUgKGludCBpbmRleCkKKyAgICB7CisgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBsZW5ndGgpIHsKKyAgICAgICAgcmV0dXJuIGRhdGFbaW5kZXgqNSsxXTsKKyAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYW4gYXR0cmlidXRlJ3MgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlJ3MgaW5kZXggKHplcm8tYmFzZWQpLgorICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIHF1YWxpZmllZCBuYW1lLCB0aGUgZW1wdHkgc3RyaW5nIGlmCisgICAgICogICAgICAgICBub25lIGlzIGF2YWlsYWJsZSwgb3IgbnVsbCBpZiB0aGUgaW5kZXggaXMgb3V0IG9mIGJvdW5kcy4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMjZ2V0UU5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFFOYW1lIChpbnQgaW5kZXgpCisgICAgeworICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgbGVuZ3RoKSB7CisgICAgICAgIHJldHVybiBkYXRhW2luZGV4KjUrMl07CisgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJuIGFuIGF0dHJpYnV0ZSdzIHR5cGUgYnkgaW5kZXguCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGF0dHJpYnV0ZSdzIGluZGV4ICh6ZXJvLWJhc2VkKS4KKyAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyB0eXBlLCAiQ0RBVEEiIGlmIHRoZSB0eXBlIGlzIHVua25vd24sIG9yIG51bGwKKyAgICAgKiAgICAgICAgIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgYm91bmRzLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRUeXBlKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUgKGludCBpbmRleCkKKyAgICB7CisgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBsZW5ndGgpIHsKKyAgICAgICAgcmV0dXJuIGRhdGFbaW5kZXgqNSszXTsKKyAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYW4gYXR0cmlidXRlJ3MgdmFsdWUgYnkgaW5kZXguCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGF0dHJpYnV0ZSdzIGluZGV4ICh6ZXJvLWJhc2VkKS4KKyAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyB2YWx1ZSBvciBudWxsIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgYm91bmRzLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRWYWx1ZShpbnQpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZSAoaW50IGluZGV4KQorICAgIHsKKyAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IGxlbmd0aCkgeworICAgICAgICByZXR1cm4gZGF0YVtpbmRleCo1KzRdOworICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgaW5kZXggYnkgTmFtZXNwYWNlIG5hbWUuCisgICAgICoKKyAgICAgKiA8cD5JbiBtYW55IGNhc2VzLCBpdCB3aWxsIGJlIG1vcmUgZWZmaWNpZW50IHRvIGxvb2sgdXAgdGhlIG5hbWUgb25jZSBhbmQKKyAgICAgKiB1c2UgdGhlIGluZGV4IHF1ZXJ5IG1ldGhvZHMgcmF0aGVyIHRoYW4gdXNpbmcgdGhlIG5hbWUgcXVlcnkgbWV0aG9kcworICAgICAqIHJlcGVhdGVkbHkuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHVyaSBUaGUgYXR0cmlidXRlJ3MgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5CisgICAgICogICAgICAgIHN0cmluZyBpZiBub25lIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBhdHRyaWJ1dGUncyBsb2NhbCBuYW1lLgorICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIGluZGV4LCBvciAtMSBpZiBub25lIG1hdGNoZXMuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVzI2dldEluZGV4KGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEluZGV4IChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKQorICAgIHsKKyAgICBpbnQgbWF4ID0gbGVuZ3RoICogNTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG1heDsgaSArPSA1KSB7CisgICAgICAgIGlmIChkYXRhW2ldLmVxdWFscyh1cmkpICYmIGRhdGFbaSsxXS5lcXVhbHMobG9jYWxOYW1lKSkgeworICAgICAgICByZXR1cm4gaSAvIDU7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIC0xOworICAgIH0KKworCisgICAgLyoqCisgICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyBpbmRleCBieSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZS4KKyAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyBpbmRleCwgb3IgLTEgaWYgbm9uZSBtYXRjaGVzLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRJbmRleChqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXggKFN0cmluZyBxTmFtZSkKKyAgICB7CisgICAgaW50IG1heCA9IGxlbmd0aCAqIDU7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXg7IGkgKz0gNSkgeworICAgICAgICBpZiAoZGF0YVtpKzJdLmVxdWFscyhxTmFtZSkpIHsKKyAgICAgICAgcmV0dXJuIGkgLyA1OworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiAtMTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgdHlwZSBieSBOYW1lc3BhY2UtcXVhbGlmaWVkIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGZvciBhIG5hbWUKKyAgICAgKiAgICAgICAgd2l0aCBubyBleHBsaWNpdCBOYW1lc3BhY2UgVVJJLgorICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUuCisgICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlJ3MgdHlwZSwgb3IgbnVsbCBpZiB0aGVyZSBpcyBubworICAgICAqICAgICAgICAgbWF0Y2hpbmcgYXR0cmlidXRlLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRUeXBlKGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpCisgICAgeworICAgIGludCBtYXggPSBsZW5ndGggKiA1OworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWF4OyBpICs9IDUpIHsKKyAgICAgICAgaWYgKGRhdGFbaV0uZXF1YWxzKHVyaSkgJiYgZGF0YVtpKzFdLmVxdWFscyhsb2NhbE5hbWUpKSB7CisgICAgICAgIHJldHVybiBkYXRhW2krM107CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHR5cGUgYnkgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUuCisgICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlJ3MgdHlwZSwgb3IgbnVsbCBpZiB0aGVyZSBpcyBubworICAgICAqICAgICAgICAgbWF0Y2hpbmcgYXR0cmlidXRlLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRUeXBlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRUeXBlIChTdHJpbmcgcU5hbWUpCisgICAgeworICAgIGludCBtYXggPSBsZW5ndGggKiA1OworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWF4OyBpICs9IDUpIHsKKyAgICAgICAgaWYgKGRhdGFbaSsyXS5lcXVhbHMocU5hbWUpKSB7CisgICAgICAgIHJldHVybiBkYXRhW2krM107CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHZhbHVlIGJ5IE5hbWVzcGFjZS1xdWFsaWZpZWQgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgZm9yIGEgbmFtZQorICAgICAqICAgICAgICB3aXRoIG5vIGV4cGxpY2l0IE5hbWVzcGFjZSBVUkkuCisgICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZS4KKyAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyB2YWx1ZSwgb3IgbnVsbCBpZiB0aGVyZSBpcyBubworICAgICAqICAgICAgICAgbWF0Y2hpbmcgYXR0cmlidXRlLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRWYWx1ZShqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZSAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkKKyAgICB7CisgICAgaW50IG1heCA9IGxlbmd0aCAqIDU7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXg7IGkgKz0gNSkgeworICAgICAgICBpZiAoZGF0YVtpXS5lcXVhbHModXJpKSAmJiBkYXRhW2krMV0uZXF1YWxzKGxvY2FsTmFtZSkpIHsKKyAgICAgICAgcmV0dXJuIGRhdGFbaSs0XTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgdmFsdWUgYnkgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUuCisgICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlJ3MgdmFsdWUsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm8KKyAgICAgKiAgICAgICAgIG1hdGNoaW5nIGF0dHJpYnV0ZS4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMjZ2V0VmFsdWUoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlIChTdHJpbmcgcU5hbWUpCisgICAgeworICAgIGludCBtYXggPSBsZW5ndGggKiA1OworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWF4OyBpICs9IDUpIHsKKyAgICAgICAgaWYgKGRhdGFbaSsyXS5lcXVhbHMocU5hbWUpKSB7CisgICAgICAgIHJldHVybiBkYXRhW2krNF07CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIE1hbmlwdWxhdG9ycy4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisKKyAgICAvKioKKyAgICAgKiBDbGVhciB0aGUgYXR0cmlidXRlIGxpc3QgZm9yIHJldXNlLgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IGxpdHRsZSBtZW1vcnkgaXMgZnJlZWQgYnkgdGhpcyBjYWxsOgorICAgICAqIHRoZSBjdXJyZW50IGFycmF5IGlzIGtlcHQgc28gaXQgY2FuIGJlCisgICAgICogcmV1c2VkLjwvcD4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbGVhciAoKQorICAgIHsKKyAgICBpZiAoZGF0YSAhPSBudWxsKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgKGxlbmd0aCAqIDUpOyBpKyspCisgICAgICAgIGRhdGEgW2ldID0gbnVsbDsKKyAgICB9CisgICAgbGVuZ3RoID0gMDsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIENvcHkgYW4gZW50aXJlIEF0dHJpYnV0ZXMgb2JqZWN0LgorICAgICAqCisgICAgICogPHA+SXQgbWF5IGJlIG1vcmUgZWZmaWNpZW50IHRvIHJldXNlIGFuIGV4aXN0aW5nIG9iamVjdAorICAgICAqIHJhdGhlciB0aGFuIGNvbnN0YW50bHkgYWxsb2NhdGluZyBuZXcgb25lcy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gYXR0cyBUaGUgYXR0cmlidXRlcyB0byBjb3B5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZXMgKEF0dHJpYnV0ZXMgYXR0cykKKyAgICB7CisgICAgICAgIGNsZWFyKCk7CisgICAgICAgIGxlbmd0aCA9IGF0dHMuZ2V0TGVuZ3RoKCk7CisgICAgICAgIGlmIChsZW5ndGggPiAwKSB7CisgICAgICAgICAgICBkYXRhID0gbmV3IFN0cmluZ1tsZW5ndGgqNV07CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgZGF0YVtpKjVdID0gYXR0cy5nZXRVUkkoaSk7CisgICAgICAgICAgICAgICAgZGF0YVtpKjUrMV0gPSBhdHRzLmdldExvY2FsTmFtZShpKTsKKyAgICAgICAgICAgICAgICBkYXRhW2kqNSsyXSA9IGF0dHMuZ2V0UU5hbWUoaSk7CisgICAgICAgICAgICAgICAgZGF0YVtpKjUrM10gPSBhdHRzLmdldFR5cGUoaSk7CisgICAgICAgICAgICAgICAgZGF0YVtpKjUrNF0gPSBhdHRzLmdldFZhbHVlKGkpOworICAgICAgICAgICAgfQorICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEFkZCBhbiBhdHRyaWJ1dGUgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdC4KKyAgICAgKgorICAgICAqIDxwPkZvciB0aGUgc2FrZSBvZiBzcGVlZCwgdGhpcyBtZXRob2QgZG9lcyBubyBjaGVja2luZworICAgICAqIHRvIHNlZSBpZiB0aGUgYXR0cmlidXRlIGlzIGFscmVhZHkgaW4gdGhlIGxpc3Q6IHRoYXQgaXMKKyAgICAgKiB0aGUgcmVzcG9uc2liaWxpdHkgb2YgdGhlIGFwcGxpY2F0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYKKyAgICAgKiAgICAgICAgbm9uZSBpcyBhdmFpbGFibGUgb3IgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90CisgICAgICogICAgICAgIGJlaW5nIHBlcmZvcm1lZC4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmCisgICAgICogICAgICAgIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCisgICAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLCBvciB0aGUgZW1wdHkgc3RyaW5nCisgICAgICogICAgICAgIGlmIHF1YWxpZmllZCBuYW1lcyBhcmUgbm90IGF2YWlsYWJsZS4KKyAgICAgKiBAcGFyYW0gdHlwZSBUaGUgYXR0cmlidXRlIHR5cGUgYXMgYSBzdHJpbmcuCisgICAgICogQHBhcmFtIHZhbHVlIFRoZSBhdHRyaWJ1dGUgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlIChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUsCisgICAgICAgICAgICAgICAgICBTdHJpbmcgdHlwZSwgU3RyaW5nIHZhbHVlKQorICAgIHsKKyAgICBlbnN1cmVDYXBhY2l0eShsZW5ndGgrMSk7CisgICAgZGF0YVtsZW5ndGgqNV0gPSB1cmk7CisgICAgZGF0YVtsZW5ndGgqNSsxXSA9IGxvY2FsTmFtZTsKKyAgICBkYXRhW2xlbmd0aCo1KzJdID0gcU5hbWU7CisgICAgZGF0YVtsZW5ndGgqNSszXSA9IHR5cGU7CisgICAgZGF0YVtsZW5ndGgqNSs0XSA9IHZhbHVlOworICAgIGxlbmd0aCsrOworICAgIH0KKworCisgICAgLyoqCisgICAgICogU2V0IGFuIGF0dHJpYnV0ZSBpbiB0aGUgbGlzdC4KKyAgICAgKgorICAgICAqIDxwPkZvciB0aGUgc2FrZSBvZiBzcGVlZCwgdGhpcyBtZXRob2QgZG9lcyBubyBjaGVja2luZworICAgICAqIGZvciBuYW1lIGNvbmZsaWN0cyBvciB3ZWxsLWZvcm1lZG5lc3M6IHN1Y2ggY2hlY2tzIGFyZSB0aGUKKyAgICAgKiByZXNwb25zaWJpbGl0eSBvZiB0aGUgYXBwbGljYXRpb24uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlICh6ZXJvLWJhc2VkKS4KKyAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmCisgICAgICogICAgICAgIG5vbmUgaXMgYXZhaWxhYmxlIG9yIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdAorICAgICAqICAgICAgICBiZWluZyBwZXJmb3JtZWQuCisgICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZgorICAgICAqICAgICAgICBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgorICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUsIG9yIHRoZSBlbXB0eSBzdHJpbmcKKyAgICAgKiAgICAgICAgaWYgcXVhbGlmaWVkIG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgorICAgICAqIEBwYXJhbSB0eXBlIFRoZSBhdHRyaWJ1dGUgdHlwZSBhcyBhIHN0cmluZy4KKyAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGF0dHJpYnV0ZSB2YWx1ZS4KKyAgICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gV2hlbiB0aGUKKyAgICAgKiAgICAgICAgICAgIHN1cHBsaWVkIGluZGV4IGRvZXMgbm90IHBvaW50IHRvIGFuIGF0dHJpYnV0ZQorICAgICAqICAgICAgICAgICAgaW4gdGhlIGxpc3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QXR0cmlidXRlIChpbnQgaW5kZXgsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsCisgICAgICAgICAgICAgICAgICBTdHJpbmcgcU5hbWUsIFN0cmluZyB0eXBlLCBTdHJpbmcgdmFsdWUpCisgICAgeworICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgbGVuZ3RoKSB7CisgICAgICAgIGRhdGFbaW5kZXgqNV0gPSB1cmk7CisgICAgICAgIGRhdGFbaW5kZXgqNSsxXSA9IGxvY2FsTmFtZTsKKyAgICAgICAgZGF0YVtpbmRleCo1KzJdID0gcU5hbWU7CisgICAgICAgIGRhdGFbaW5kZXgqNSszXSA9IHR5cGU7CisgICAgICAgIGRhdGFbaW5kZXgqNSs0XSA9IHZhbHVlOworICAgIH0gZWxzZSB7CisgICAgICAgIGJhZEluZGV4KGluZGV4KTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZW1vdmUgYW4gYXR0cmlidXRlIGZyb20gdGhlIGxpc3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUgKHplcm8tYmFzZWQpLgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBXaGVuIHRoZQorICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgaW5kZXggZG9lcyBub3QgcG9pbnQgdG8gYW4gYXR0cmlidXRlCisgICAgICogICAgICAgICAgICBpbiB0aGUgbGlzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVBdHRyaWJ1dGUgKGludCBpbmRleCkKKyAgICB7CisgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBsZW5ndGgpIHsKKyAgICAgICAgaWYgKGluZGV4IDwgbGVuZ3RoIC0gMSkgeworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGEsIChpbmRleCsxKSo1LCBkYXRhLCBpbmRleCo1LAorICAgICAgICAgICAgICAgICAobGVuZ3RoLWluZGV4LTEpKjUpOworICAgICAgICB9CisgICAgICAgIGluZGV4ID0gKGxlbmd0aCAtIDEpICogNTsKKyAgICAgICAgZGF0YSBbaW5kZXgrK10gPSBudWxsOworICAgICAgICBkYXRhIFtpbmRleCsrXSA9IG51bGw7CisgICAgICAgIGRhdGEgW2luZGV4KytdID0gbnVsbDsKKyAgICAgICAgZGF0YSBbaW5kZXgrK10gPSBudWxsOworICAgICAgICBkYXRhIFtpbmRleF0gPSBudWxsOworICAgICAgICBsZW5ndGgtLTsKKyAgICB9IGVsc2UgeworICAgICAgICBiYWRJbmRleChpbmRleCk7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBOYW1lc3BhY2UgVVJJIG9mIGEgc3BlY2lmaWMgYXR0cmlidXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlICh6ZXJvLWJhc2VkKS4KKyAgICAgKiBAcGFyYW0gdXJpIFRoZSBhdHRyaWJ1dGUncyBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkKKyAgICAgKiAgICAgICAgc3RyaW5nIGZvciBub25lLgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBXaGVuIHRoZQorICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgaW5kZXggZG9lcyBub3QgcG9pbnQgdG8gYW4gYXR0cmlidXRlCisgICAgICogICAgICAgICAgICBpbiB0aGUgbGlzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRVUkkgKGludCBpbmRleCwgU3RyaW5nIHVyaSkKKyAgICB7CisgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBsZW5ndGgpIHsKKyAgICAgICAgZGF0YVtpbmRleCo1XSA9IHVyaTsKKyAgICB9IGVsc2UgeworICAgICAgICBiYWRJbmRleChpbmRleCk7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBsb2NhbCBuYW1lIG9mIGEgc3BlY2lmaWMgYXR0cmlidXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlICh6ZXJvLWJhc2VkKS4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBhdHRyaWJ1dGUncyBsb2NhbCBuYW1lLCBvciB0aGUgZW1wdHkKKyAgICAgKiAgICAgICAgc3RyaW5nIGZvciBub25lLgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBXaGVuIHRoZQorICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgaW5kZXggZG9lcyBub3QgcG9pbnQgdG8gYW4gYXR0cmlidXRlCisgICAgICogICAgICAgICAgICBpbiB0aGUgbGlzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMb2NhbE5hbWUgKGludCBpbmRleCwgU3RyaW5nIGxvY2FsTmFtZSkKKyAgICB7CisgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBsZW5ndGgpIHsKKyAgICAgICAgZGF0YVtpbmRleCo1KzFdID0gbG9jYWxOYW1lOworICAgIH0gZWxzZSB7CisgICAgICAgIGJhZEluZGV4KGluZGV4KTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHF1YWxpZmllZCBuYW1lIG9mIGEgc3BlY2lmaWMgYXR0cmlidXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlICh6ZXJvLWJhc2VkKS4KKyAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIGF0dHJpYnV0ZSdzIHF1YWxpZmllZCBuYW1lLCBvciB0aGUgZW1wdHkKKyAgICAgKiAgICAgICAgc3RyaW5nIGZvciBub25lLgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBXaGVuIHRoZQorICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgaW5kZXggZG9lcyBub3QgcG9pbnQgdG8gYW4gYXR0cmlidXRlCisgICAgICogICAgICAgICAgICBpbiB0aGUgbGlzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRRTmFtZSAoaW50IGluZGV4LCBTdHJpbmcgcU5hbWUpCisgICAgeworICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgbGVuZ3RoKSB7CisgICAgICAgIGRhdGFbaW5kZXgqNSsyXSA9IHFOYW1lOworICAgIH0gZWxzZSB7CisgICAgICAgIGJhZEluZGV4KGluZGV4KTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHR5cGUgb2YgYSBzcGVjaWZpYyBhdHRyaWJ1dGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUgKHplcm8tYmFzZWQpLgorICAgICAqIEBwYXJhbSB0eXBlIFRoZSBhdHRyaWJ1dGUncyB0eXBlLgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBXaGVuIHRoZQorICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgaW5kZXggZG9lcyBub3QgcG9pbnQgdG8gYW4gYXR0cmlidXRlCisgICAgICogICAgICAgICAgICBpbiB0aGUgbGlzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUeXBlIChpbnQgaW5kZXgsIFN0cmluZyB0eXBlKQorICAgIHsKKyAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IGxlbmd0aCkgeworICAgICAgICBkYXRhW2luZGV4KjUrM10gPSB0eXBlOworICAgIH0gZWxzZSB7CisgICAgICAgIGJhZEluZGV4KGluZGV4KTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWMgYXR0cmlidXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlICh6ZXJvLWJhc2VkKS4KKyAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGF0dHJpYnV0ZSdzIHZhbHVlLgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBXaGVuIHRoZQorICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgaW5kZXggZG9lcyBub3QgcG9pbnQgdG8gYW4gYXR0cmlidXRlCisgICAgICogICAgICAgICAgICBpbiB0aGUgbGlzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZSAoaW50IGluZGV4LCBTdHJpbmcgdmFsdWUpCisgICAgeworICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgbGVuZ3RoKSB7CisgICAgICAgIGRhdGFbaW5kZXgqNSs0XSA9IHZhbHVlOworICAgIH0gZWxzZSB7CisgICAgICAgIGJhZEluZGV4KGluZGV4KTsKKyAgICB9CisgICAgfQorCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIEludGVybmFsIG1ldGhvZHMuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoqCisgICAgICogRW5zdXJlIHRoZSBpbnRlcm5hbCBhcnJheSdzIGNhcGFjaXR5LgorICAgICAqCisgICAgICogQHBhcmFtIG4gVGhlIG1pbmltdW0gbnVtYmVyIG9mIGF0dHJpYnV0ZXMgdGhhdCB0aGUgYXJyYXkgbXVzdAorICAgICAqICAgICAgICBiZSBhYmxlIHRvIGhvbGQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUNhcGFjaXR5IChpbnQgbikgICAgeworICAgICAgICBpZiAobiA8PSAwKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaW50IG1heDsKKyAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCB8fCBkYXRhLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICBtYXggPSAyNTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChkYXRhLmxlbmd0aCA+PSBuICogNSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgbWF4ID0gZGF0YS5sZW5ndGg7CisgICAgICAgIH0KKyAgICAgICAgd2hpbGUgKG1heCA8IG4gKiA1KSB7CisgICAgICAgICAgICBtYXggKj0gMjsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBuZXdEYXRhW10gPSBuZXcgU3RyaW5nW21heF07CisgICAgICAgIGlmIChsZW5ndGggPiAwKSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGEsIDAsIG5ld0RhdGEsIDAsIGxlbmd0aCo1KTsKKyAgICAgICAgfQorICAgICAgICBkYXRhID0gbmV3RGF0YTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJlcG9ydCBhIGJhZCBhcnJheSBpbmRleCBpbiBhIG1hbmlwdWxhdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byByZXBvcnQuCisgICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIEFsd2F5cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYmFkSW5kZXggKGludCBpbmRleCkKKyAgICB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgeworICAgIFN0cmluZyBtc2cgPQorICAgICAgICAiQXR0ZW1wdCB0byBtb2RpZnkgYXR0cmlidXRlIGF0IGlsbGVnYWwgaW5kZXg6ICIgKyBpbmRleDsKKyAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG1zZyk7CisgICAgfQorCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIEludGVybmFsIHN0YXRlLgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKyAgICBpbnQgbGVuZ3RoOworICAgIFN0cmluZyBkYXRhIFtdOworCit9CisKKy8vIGVuZCBvZiBBdHRyaWJ1dGVzSW1wbC5qYXZhCisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9oZWxwZXJzL0RlZmF1bHRIYW5kbGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvaGVscGVycy9EZWZhdWx0SGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk5OTg4NjgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvaGVscGVycy9EZWZhdWx0SGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsNDY2IEBACisvLyBEZWZhdWx0SGFuZGxlci5qYXZhIC0gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgY29yZSBoYW5kbGVycy4KKy8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKKy8vIFdyaXR0ZW4gYnkgRGF2aWQgTWVnZ2luc29uCisvLyBOTyBXQVJSQU5UWSEgIFRoaXMgY2xhc3MgaXMgaW4gdGhlIHB1YmxpYyBkb21haW4uCisvLyAkSWQ6IERlZmF1bHRIYW5kbGVyLmphdmEsdiAxLjkgMjAwNC8wNC8yNiAxNzozNDozNSBkbWVnZ2luc29uIEV4cCAkCisKK3BhY2thZ2Ugb3JnLnhtbC5zYXguaGVscGVyczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKK2ltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKK2ltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbjsKKworCisvKioKKyAqIERlZmF1bHQgYmFzZSBjbGFzcyBmb3IgU0FYMiBldmVudCBoYW5kbGVycy4KKyAqCisgKiA8YmxvY2txdW90ZT4KKyAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCisgKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+CisgKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KKyAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgorICogPC9ibG9ja3F1b3RlPgorICoKKyAqIDxwPlRoaXMgY2xhc3MgaXMgYXZhaWxhYmxlIGFzIGEgY29udmVuaWVuY2UgYmFzZSBjbGFzcyBmb3IgU0FYMgorICogYXBwbGljYXRpb25zOiBpdCBwcm92aWRlcyBkZWZhdWx0IGltcGxlbWVudGF0aW9ucyBmb3IgYWxsIG9mIHRoZQorICogY2FsbGJhY2tzIGluIHRoZSBmb3VyIGNvcmUgU0FYMiBoYW5kbGVyIGNsYXNzZXM6PC9wPgorICoKKyAqIDx1bD4KKyAqIDxsaT57QGxpbmsgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXIgRW50aXR5UmVzb2x2ZXJ9PC9saT4KKyAqIDxsaT57QGxpbmsgb3JnLnhtbC5zYXguRFRESGFuZGxlciBEVERIYW5kbGVyfTwvbGk+CisgKiA8bGk+e0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIENvbnRlbnRIYW5kbGVyfTwvbGk+CisgKiA8bGk+e0BsaW5rIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciBFcnJvckhhbmRsZXJ9PC9saT4KKyAqIDwvdWw+CisgKgorICogPHA+QXBwbGljYXRpb24gd3JpdGVycyBjYW4gZXh0ZW5kIHRoaXMgY2xhc3Mgd2hlbiB0aGV5IG5lZWQgdG8KKyAqIGltcGxlbWVudCBvbmx5IHBhcnQgb2YgYW4gaW50ZXJmYWNlOyBwYXJzZXIgd3JpdGVycyBjYW4KKyAqIGluc3RhbnRpYXRlIHRoaXMgY2xhc3MgdG8gcHJvdmlkZSBkZWZhdWx0IGhhbmRsZXJzIHdoZW4gdGhlCisgKiBhcHBsaWNhdGlvbiBoYXMgbm90IHN1cHBsaWVkIGl0cyBvd24uPC9wPgorICoKKyAqIDxwPlRoaXMgY2xhc3MgcmVwbGFjZXMgdGhlIGRlcHJlY2F0ZWQgU0FYMQorICoge0BsaW5rIG9yZy54bWwuc2F4LkhhbmRsZXJCYXNlIEhhbmRsZXJCYXNlfSBjbGFzcy48L3A+CisgKgorICogQHNpbmNlIFNBWCAyLjAKKyAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uLAorICogQHZlcnNpb24gMi4wLjEgKHNheDJyMikKKyAqIEBzZWUgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXIKKyAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlcgorICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcgorICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIKKyAqLworcHVibGljIGNsYXNzIERlZmF1bHRIYW5kbGVyCisgICAgaW1wbGVtZW50cyBFbnRpdHlSZXNvbHZlciwgRFRESGFuZGxlciwgQ29udGVudEhhbmRsZXIsIEVycm9ySGFuZGxlcgoreworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBEZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBFbnRpdHlSZXNvbHZlciBpbnRlcmZhY2UuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworICAgIC8qKgorICAgICAqIFJlc29sdmUgYW4gZXh0ZXJuYWwgZW50aXR5LgorICAgICAqCisgICAgICogPHA+QWx3YXlzIHJldHVybiBudWxsLCBzbyB0aGF0IHRoZSBwYXJzZXIgd2lsbCB1c2UgdGhlIHN5c3RlbQorICAgICAqIGlkZW50aWZpZXIgcHJvdmlkZWQgaW4gdGhlIFhNTCBkb2N1bWVudC4gIFRoaXMgbWV0aG9kIGltcGxlbWVudHMKKyAgICAgKiB0aGUgU0FYIGRlZmF1bHQgYmVoYXZpb3VyOiBhcHBsaWNhdGlvbiB3cml0ZXJzIGNhbiBvdmVycmlkZSBpdAorICAgICAqIGluIGEgc3ViY2xhc3MgdG8gZG8gc3BlY2lhbCB0cmFuc2xhdGlvbnMgc3VjaCBhcyBjYXRhbG9nIGxvb2t1cHMKKyAgICAgKiBvciBVUkkgcmVkaXJlY3Rpb24uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBwdWJsaWMgaWRlbnRpZmVyLCBvciBudWxsIGlmIG5vbmUgaXMKKyAgICAgKiAgICAgICAgICAgICAgICAgYXZhaWxhYmxlLgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgcHJvdmlkZWQgaW4gdGhlIFhNTAorICAgICAqICAgICAgICAgICAgICAgICBkb2N1bWVudC4KKyAgICAgKiBAcmV0dXJuIFRoZSBuZXcgaW5wdXQgc291cmNlLCBvciBudWxsIHRvIHJlcXVpcmUgdGhlCisgICAgICogICAgICAgICBkZWZhdWx0IGJlaGF2aW91ci4KKyAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24gSWYgdGhlcmUgaXMgYW4gZXJyb3Igc2V0dGluZworICAgICAqICAgICAgICAgICAgdXAgdGhlIG5ldyBpbnB1dCBzb3VyY2UuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyI3Jlc29sdmVFbnRpdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eSAoU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIERlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgRFRESGFuZGxlciBpbnRlcmZhY2UuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBub3RhdGlvbiBkZWNsYXJhdGlvbi4KKyAgICAgKgorICAgICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCisgICAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgaWYgdGhleSB3aXNoIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG5vdGF0aW9ucworICAgICAqIGRlY2xhcmVkIGluIGEgZG9jdW1lbnQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5vdGF0aW9uIG5hbWUuCisgICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBub3RhdGlvbiBwdWJsaWMgaWRlbnRpZmllciwgb3IgbnVsbCBpZiBub3QKKyAgICAgKiAgICAgICAgICAgICAgICAgYXZhaWxhYmxlLgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgbm90YXRpb24gc3lzdGVtIGlkZW50aWZpZXIuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIjbm90YXRpb25EZWNsCisgICAgICovCisgICAgcHVibGljIHZvaWQgbm90YXRpb25EZWNsIChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICAvLyBubyBvcAorICAgIH0KKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYW4gdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uLgorICAgICAqCisgICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKKyAgICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byBrZWVwIHRyYWNrIG9mIHRoZSB1bnBhcnNlZCBlbnRpdGllcworICAgICAqIGRlY2xhcmVkIGluIGEgZG9jdW1lbnQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIGVudGl0eSBuYW1lLgorICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZW50aXR5IHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsIGlmIG5vdAorICAgICAqICAgICAgICAgICAgICAgICBhdmFpbGFibGUuCisgICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBlbnRpdHkgc3lzdGVtIGlkZW50aWZpZXIuCisgICAgICogQHBhcmFtIG5vdGF0aW9uTmFtZSBUaGUgbmFtZSBvZiB0aGUgYXNzb2NpYXRlZCBub3RhdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKKyAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlciN1bnBhcnNlZEVudGl0eURlY2wKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1bnBhcnNlZEVudGl0eURlY2wgKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsCisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIG5vdGF0aW9uTmFtZSkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIC8vIG5vIG9wCisgICAgfQorCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIERlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgQ29udGVudEhhbmRsZXIgaW50ZXJmYWNlLgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgYSBMb2NhdG9yIG9iamVjdCBmb3IgZG9jdW1lbnQgZXZlbnRzLgorICAgICAqCisgICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKKyAgICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyBpZiB0aGV5IHdpc2ggdG8gc3RvcmUgdGhlIGxvY2F0b3IgZm9yIHVzZQorICAgICAqIHdpdGggb3RoZXIgZG9jdW1lbnQgZXZlbnRzLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhdG9yIEEgbG9jYXRvciBmb3IgYWxsIFNBWCBkb2N1bWVudCBldmVudHMuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzZXREb2N1bWVudExvY2F0b3IKKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IgKExvY2F0b3IgbG9jYXRvcikKKyAgICB7CisgICAgLy8gbm8gb3AKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGRvY3VtZW50LgorICAgICAqCisgICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKKyAgICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgYXQgdGhlIGJlZ2lubmluZworICAgICAqIG9mIGEgZG9jdW1lbnQgKHN1Y2ggYXMgYWxsb2NhdGluZyB0aGUgcm9vdCBub2RlIG9mIGEgdHJlZSBvcgorICAgICAqIGNyZWF0aW5nIGFuIG91dHB1dCBmaWxlKS48L3A+CisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKKyAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnREb2N1bWVudAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQgKCkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIC8vIG5vIG9wCisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIHRoZSBkb2N1bWVudC4KKyAgICAgKgorICAgICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCisgICAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGF0IHRoZSBlbmQKKyAgICAgKiBvZiBhIGRvY3VtZW50IChzdWNoIGFzIGZpbmFsaXNpbmcgYSB0cmVlIG9yIGNsb3NpbmcgYW4gb3V0cHV0CisgICAgICogZmlsZSkuPC9wPgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZERvY3VtZW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQgKCkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIC8vIG5vIG9wCisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgc3RhcnQgb2YgYSBOYW1lc3BhY2UgbWFwcGluZy4KKyAgICAgKgorICAgICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCisgICAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGF0IHRoZSBzdGFydCBvZgorICAgICAqIGVhY2ggTmFtZXNwYWNlIHByZWZpeCBzY29wZSAoc3VjaCBhcyBzdG9yaW5nIHRoZSBwcmVmaXggbWFwcGluZykuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHByZWZpeCBUaGUgTmFtZXNwYWNlIHByZWZpeCBiZWluZyBkZWNsYXJlZC4KKyAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJIG1hcHBlZCB0byB0aGUgcHJlZml4LgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydFByZWZpeE1hcHBpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcgKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICAvLyBubyBvcAorICAgIH0KKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhIE5hbWVzcGFjZSBtYXBwaW5nLgorICAgICAqCisgICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKKyAgICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgYXQgdGhlIGVuZCBvZgorICAgICAqIGVhY2ggcHJlZml4IG1hcHBpbmcuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHByZWZpeCBUaGUgTmFtZXNwYWNlIHByZWZpeCBiZWluZyBkZWNsYXJlZC4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKKyAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kUHJlZml4TWFwcGluZworICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcgKFN0cmluZyBwcmVmaXgpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICAvLyBubyBvcAorICAgIH0KKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIHN0YXJ0IG9mIGFuIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcworICAgICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBhdCB0aGUgc3RhcnQgb2YKKyAgICAgKiBlYWNoIGVsZW1lbnQgKHN1Y2ggYXMgYWxsb2NhdGluZyBhIG5ldyB0cmVlIG5vZGUgb3Igd3JpdGluZworICAgICAqIG91dHB1dCB0byBhIGZpbGUpLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgdGhlCisgICAgICogICAgICAgIGVsZW1lbnQgaGFzIG5vIE5hbWVzcGFjZSBVUkkgb3IgaWYgTmFtZXNwYWNlCisgICAgICogICAgICAgIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nIHBlcmZvcm1lZC4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIHRoZQorICAgICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nCisgICAgICogICAgICAgIHBlcmZvcm1lZC4KKyAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCksIG9yIHRoZQorICAgICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcXVhbGlmaWVkIG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgorICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBhdHRyaWJ1dGVzIGF0dGFjaGVkIHRvIHRoZSBlbGVtZW50LiAgSWYKKyAgICAgKiAgICAgICAgdGhlcmUgYXJlIG5vIGF0dHJpYnV0ZXMsIGl0IHNoYWxsIGJlIGFuIGVtcHR5CisgICAgICogICAgICAgIEF0dHJpYnV0ZXMgb2JqZWN0LgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydEVsZW1lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsCisgICAgICAgICAgICAgICAgICBTdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cmlidXRlcykKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIC8vIG5vIG9wCisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIGFuIGVsZW1lbnQuCisgICAgICoKKyAgICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcworICAgICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBhdCB0aGUgZW5kIG9mCisgICAgICogZWFjaCBlbGVtZW50IChzdWNoIGFzIGZpbmFsaXNpbmcgYSB0cmVlIG5vZGUgb3Igd3JpdGluZworICAgICAqIG91dHB1dCB0byBhIGZpbGUpLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgdGhlCisgICAgICogICAgICAgIGVsZW1lbnQgaGFzIG5vIE5hbWVzcGFjZSBVUkkgb3IgaWYgTmFtZXNwYWNlCisgICAgICogICAgICAgIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nIHBlcmZvcm1lZC4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIHRoZQorICAgICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nCisgICAgICogICAgICAgIHBlcmZvcm1lZC4KKyAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCksIG9yIHRoZQorICAgICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcXVhbGlmaWVkIG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmRFbGVtZW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgZW5kRWxlbWVudCAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgLy8gbm8gb3AKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGNoYXJhY3RlciBkYXRhIGluc2lkZSBhbiBlbGVtZW50LgorICAgICAqCisgICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKKyAgICAgKiBtZXRob2QgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGZvciBlYWNoIGNodW5rIG9mIGNoYXJhY3RlciBkYXRhCisgICAgICogKHN1Y2ggYXMgYWRkaW5nIHRoZSBkYXRhIHRvIGEgbm9kZSBvciBidWZmZXIsIG9yIHByaW50aW5nIGl0IHRvCisgICAgICogYSBmaWxlKS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMuCisgICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgY2hhcmFjdGVyIGFycmF5LgorICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZQorICAgICAqICAgICAgICAgICAgICAgY2hhcmFjdGVyIGFycmF5LgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNjaGFyYWN0ZXJzCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyAoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICAvLyBubyBvcAorICAgIH0KKworCisgICAgLyoqCisgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgaWdub3JhYmxlIHdoaXRlc3BhY2UgaW4gZWxlbWVudCBjb250ZW50LgorICAgICAqCisgICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKKyAgICAgKiBtZXRob2QgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGZvciBlYWNoIGNodW5rIG9mIGlnbm9yYWJsZQorICAgICAqIHdoaXRlc3BhY2UgKHN1Y2ggYXMgYWRkaW5nIGRhdGEgdG8gYSBub2RlIG9yIGJ1ZmZlciwgb3IgcHJpbnRpbmcKKyAgICAgKiBpdCB0byBhIGZpbGUpLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaCBUaGUgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzLgorICAgICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGNoYXJhY3RlciBhcnJheS4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB1c2UgZnJvbSB0aGUKKyAgICAgKiAgICAgICAgICAgICAgIGNoYXJhY3RlciBhcnJheS4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKKyAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjaWdub3JhYmxlV2hpdGVzcGFjZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UgKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgLy8gbm8gb3AKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4KKyAgICAgKgorICAgICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCisgICAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGZvciBlYWNoCisgICAgICogcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiwgc3VjaCBhcyBzZXR0aW5nIHN0YXR1cyB2YXJpYWJsZXMgb3IKKyAgICAgKiBpbnZva2luZyBvdGhlciBtZXRob2RzLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdGFyZ2V0LgorICAgICAqIEBwYXJhbSBkYXRhIFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGRhdGEsIG9yIG51bGwgaWYKKyAgICAgKiAgICAgICAgICAgICBub25lIGlzIHN1cHBsaWVkLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgLy8gbm8gb3AKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgc2tpcHBlZCBlbnRpdHkuCisgICAgICoKKyAgICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcworICAgICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBmb3IgZWFjaAorICAgICAqIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24sIHN1Y2ggYXMgc2V0dGluZyBzdGF0dXMgdmFyaWFibGVzIG9yCisgICAgICogaW52b2tpbmcgb3RoZXIgbWV0aG9kcy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgc2tpcHBlZCBlbnRpdHkuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3Byb2Nlc3NpbmdJbnN0cnVjdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkgKFN0cmluZyBuYW1lKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgLy8gbm8gb3AKKyAgICB9CisKKworDAorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgRXJyb3JIYW5kbGVyIGludGVyZmFjZS4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHBhcnNlciB3YXJuaW5nLgorICAgICAqCisgICAgICogPHA+VGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZG9lcyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycworICAgICAqIG1heSBvdmVycmlkZSB0aGlzIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucworICAgICAqIGZvciBlYWNoIHdhcm5pbmcsIHN1Y2ggYXMgaW5zZXJ0aW5nIHRoZSBtZXNzYWdlIGluIGEgbG9nIGZpbGUgb3IKKyAgICAgKiBwcmludGluZyBpdCB0byB0aGUgY29uc29sZS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZSBUaGUgd2FybmluZyBpbmZvcm1hdGlvbiBlbmNvZGVkIGFzIGFuIGV4Y2VwdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKKyAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyI3dhcm5pbmcKKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd2FybmluZyAoU0FYUGFyc2VFeGNlcHRpb24gZSkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIC8vIG5vIG9wCisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHJlY292ZXJhYmxlIHBhcnNlciBlcnJvci4KKyAgICAgKgorICAgICAqIDxwPlRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMKKyAgICAgKiBtYXkgb3ZlcnJpZGUgdGhpcyBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMKKyAgICAgKiBmb3IgZWFjaCBlcnJvciwgc3VjaCBhcyBpbnNlcnRpbmcgdGhlIG1lc3NhZ2UgaW4gYSBsb2cgZmlsZSBvcgorICAgICAqIHByaW50aW5nIGl0IHRvIHRoZSBjb25zb2xlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIFRoZSB3YXJuaW5nIGluZm9ybWF0aW9uIGVuY29kZWQgYXMgYW4gZXhjZXB0aW9uLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIjd2FybmluZworICAgICAqIEBzZWUgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlcnJvciAoU0FYUGFyc2VFeGNlcHRpb24gZSkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIC8vIG5vIG9wCisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXBvcnQgYSBmYXRhbCBYTUwgcGFyc2luZyBlcnJvci4KKyAgICAgKgorICAgICAqIDxwPlRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHRocm93cyBhIFNBWFBhcnNlRXhjZXB0aW9uLgorICAgICAqIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMgbWV0aG9kIGluIGEgc3ViY2xhc3MgaWYKKyAgICAgKiB0aGV5IG5lZWQgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGZvciBlYWNoIGZhdGFsIGVycm9yIChzdWNoIGFzCisgICAgICogY29sbGVjdGluZyBhbGwgb2YgdGhlIGVycm9ycyBpbnRvIGEgc2luZ2xlIHJlcG9ydCk6IGluIGFueSBjYXNlLAorICAgICAqIHRoZSBhcHBsaWNhdGlvbiBtdXN0IHN0b3AgYWxsIHJlZ3VsYXIgcHJvY2Vzc2luZyB3aGVuIHRoaXMKKyAgICAgKiBtZXRob2QgaXMgaW52b2tlZCwgc2luY2UgdGhlIGRvY3VtZW50IGlzIG5vIGxvbmdlciByZWxpYWJsZSwgYW5kCisgICAgICogdGhlIHBhcnNlciBtYXkgbm8gbG9uZ2VyIHJlcG9ydCBwYXJzaW5nIGV2ZW50cy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gZSBUaGUgZXJyb3IgaW5mb3JtYXRpb24gZW5jb2RlZCBhcyBhbiBleGNlcHRpb24uCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5CisgICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciNmYXRhbEVycm9yCisgICAgICogQHNlZSBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IgKFNBWFBhcnNlRXhjZXB0aW9uIGUpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICB0aHJvdyBlOworICAgIH0KKworfQorCisvLyBlbmQgb2YgRGVmYXVsdEhhbmRsZXIuamF2YQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2hlbHBlcnMvTG9jYXRvckltcGwuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9oZWxwZXJzL0xvY2F0b3JJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTdlYzc2YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9oZWxwZXJzL0xvY2F0b3JJbXBsLmphdmEKQEAgLTAsMCArMSwyMTQgQEAKKy8vIFNBWCBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGZvciBMb2NhdG9yLgorLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZworLy8gTm8gd2FycmFudHk7IG5vIGNvcHlyaWdodCAtLSB1c2UgdGhpcyBhcyB5b3Ugd2lsbC4KKy8vICRJZDogTG9jYXRvckltcGwuamF2YSx2IDEuNiAyMDAyLzAxLzMwIDIwOjUyOjI3IGRicm93bmVsbCBFeHAgJAorCitwYWNrYWdlIG9yZy54bWwuc2F4LmhlbHBlcnM7CisKK2ltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOworCisKKy8qKgorICogUHJvdmlkZSBhbiBvcHRpb25hbCBjb252ZW5pZW5jZSBpbXBsZW1lbnRhdGlvbiBvZiBMb2NhdG9yLgorICoKKyAqIDxibG9ja3F1b3RlPgorICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKKyAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KKyAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgorICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+VGhpcyBjbGFzcyBpcyBhdmFpbGFibGUgbWFpbmx5IGZvciBhcHBsaWNhdGlvbiB3cml0ZXJzLCB3aG8KKyAqIGNhbiB1c2UgaXQgdG8gbWFrZSBhIHBlcnNpc3RlbnQgc25hcHNob3Qgb2YgYSBsb2NhdG9yIGF0IGFueQorICogcG9pbnQgZHVyaW5nIGEgZG9jdW1lbnQgcGFyc2U6PC9wPgorICoKKyAqIDxwcmU+CisgKiBMb2NhdG9yIGxvY2F0b3I7CisgKiBMb2NhdG9yIHN0YXJ0bG9jOworICoKKyAqIHB1YmxpYyB2b2lkIHNldExvY2F0b3IgKExvY2F0b3IgbG9jYXRvcikKKyAqIHsKKyAqICAgICAgICAgLy8gbm90ZSB0aGUgbG9jYXRvcgorICogICB0aGlzLmxvY2F0b3IgPSBsb2NhdG9yOworICogfQorICoKKyAqIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQgKCkKKyAqIHsKKyAqICAgICAgICAgLy8gc2F2ZSB0aGUgbG9jYXRpb24gb2YgdGhlIHN0YXJ0IG9mIHRoZSBkb2N1bWVudAorICogICAgICAgICAvLyBmb3IgZnV0dXJlIHVzZS4KKyAqICAgTG9jYXRvciBzdGFydGxvYyA9IG5ldyBMb2NhdG9ySW1wbChsb2NhdG9yKTsKKyAqIH0KKyAqPC9wcmU+CisgKgorICogPHA+Tm9ybWFsbHksIHBhcnNlciB3cml0ZXJzIHdpbGwgbm90IHVzZSB0aGlzIGNsYXNzLCBzaW5jZSBpdAorICogaXMgbW9yZSBlZmZpY2llbnQgdG8gcHJvdmlkZSBsb2NhdGlvbiBpbmZvcm1hdGlvbiBvbmx5IHdoZW4KKyAqIHJlcXVlc3RlZCwgcmF0aGVyIHRoYW4gY29uc3RhbnRseSB1cGRhdGluZyBhIExvY2F0b3Igb2JqZWN0LjwvcD4KKyAqCisgKiBAc2luY2UgU0FYIDEuMAorICogQGF1dGhvciBEYXZpZCBNZWdnaW5zb24KKyAqIEB2ZXJzaW9uIDIuMC4xIChzYXgycjIpCisgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IgTG9jYXRvcgorICovCitwdWJsaWMgY2xhc3MgTG9jYXRvckltcGwgaW1wbGVtZW50cyBMb2NhdG9yCit7CisKKworICAgIC8qKgorICAgICAqIFplcm8tYXJndW1lbnQgY29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIHdpbGwgbm90IG5vcm1hbGx5IGJlIHVzZWZ1bCwgc2luY2UgdGhlIG1haW4gcHVycG9zZQorICAgICAqIG9mIHRoaXMgY2xhc3MgaXMgdG8gbWFrZSBhIHNuYXBzaG90IG9mIGFuIGV4aXN0aW5nIExvY2F0b3IuPC9wPgorICAgICAqLworICAgIHB1YmxpYyBMb2NhdG9ySW1wbCAoKQorICAgIHsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIENvcHkgY29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiA8cD5DcmVhdGUgYSBwZXJzaXN0ZW50IGNvcHkgb2YgdGhlIGN1cnJlbnQgc3RhdGUgb2YgYSBsb2NhdG9yLgorICAgICAqIFdoZW4gdGhlIG9yaWdpbmFsIGxvY2F0b3IgY2hhbmdlcywgdGhpcyBjb3B5IHdpbGwgc3RpbGwga2VlcAorICAgICAqIHRoZSBvcmlnaW5hbCB2YWx1ZXMgKGFuZCBpdCBjYW4gYmUgdXNlZCBvdXRzaWRlIHRoZSBzY29wZSBvZgorICAgICAqIERvY3VtZW50SGFuZGxlciBtZXRob2RzKS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRvciB0byBjb3B5LgorICAgICAqLworICAgIHB1YmxpYyBMb2NhdG9ySW1wbCAoTG9jYXRvciBsb2NhdG9yKQorICAgIHsKKyAgICBzZXRQdWJsaWNJZChsb2NhdG9yLmdldFB1YmxpY0lkKCkpOworICAgIHNldFN5c3RlbUlkKGxvY2F0b3IuZ2V0U3lzdGVtSWQoKSk7CisgICAgc2V0TGluZU51bWJlcihsb2NhdG9yLmdldExpbmVOdW1iZXIoKSk7CisgICAgc2V0Q29sdW1uTnVtYmVyKGxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCkpOworICAgIH0KKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5Mb2NhdG9yCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBzYXZlZCBwdWJsaWMgaWRlbnRpZmllci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIHB1YmxpYyBpZGVudGlmaWVyIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIG5vbmUKKyAgICAgKiAgICAgICAgIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IjZ2V0UHVibGljSWQKKyAgICAgKiBAc2VlICNzZXRQdWJsaWNJZAorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQgKCkKKyAgICB7CisgICAgcmV0dXJuIHB1YmxpY0lkOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBzYXZlZCBzeXN0ZW0gaWRlbnRpZmllci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIHN5c3RlbSBpZGVudGlmaWVyIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIG5vbmUKKyAgICAgKiAgICAgICAgIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IjZ2V0U3lzdGVtSWQKKyAgICAgKiBAc2VlICNzZXRTeXN0ZW1JZAorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQgKCkKKyAgICB7CisgICAgcmV0dXJuIHN5c3RlbUlkOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBzYXZlZCBsaW5lIG51bWJlciAoMS1iYXNlZCkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBsaW5lIG51bWJlciBhcyBhbiBpbnRlZ2VyLCBvciAtMSBpZiBub25lIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IjZ2V0TGluZU51bWJlcgorICAgICAqIEBzZWUgI3NldExpbmVOdW1iZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIgKCkKKyAgICB7CisgICAgcmV0dXJuIGxpbmVOdW1iZXI7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHNhdmVkIGNvbHVtbiBudW1iZXIgKDEtYmFzZWQpLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgY29sdW1uIG51bWJlciBhcyBhbiBpbnRlZ2VyLCBvciAtMSBpZiBub25lIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IjZ2V0Q29sdW1uTnVtYmVyCisgICAgICogQHNlZSAjc2V0Q29sdW1uTnVtYmVyCisgICAgICovCisgICAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIgKCkKKyAgICB7CisgICAgcmV0dXJuIGNvbHVtbk51bWJlcjsKKyAgICB9CisKKworDAorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gU2V0dGVycyBmb3IgdGhlIHByb3BlcnRpZXMgKG5vdCBpbiBvcmcueG1sLnNheC5Mb2NhdG9yKQorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoaXMgbG9jYXRvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgbmV3IHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsCisgICAgICogICAgICAgIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgorICAgICAqIEBzZWUgI2dldFB1YmxpY0lkCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UHVibGljSWQgKFN0cmluZyBwdWJsaWNJZCkKKyAgICB7CisgICAgdGhpcy5wdWJsaWNJZCA9IHB1YmxpY0lkOworICAgIH0KKworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzeXN0ZW0gaWRlbnRpZmllciBmb3IgdGhpcyBsb2NhdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBuZXcgc3lzdGVtIGlkZW50aWZpZXIsIG9yIG51bGwKKyAgICAgKiAgICAgICAgaWYgbm9uZSBpcyBhdmFpbGFibGUuCisgICAgICogQHNlZSAjZ2V0U3lzdGVtSWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZCAoU3RyaW5nIHN5c3RlbUlkKQorICAgIHsKKyAgICB0aGlzLnN5c3RlbUlkID0gc3lzdGVtSWQ7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGxpbmUgbnVtYmVyIGZvciB0aGlzIGxvY2F0b3IgKDEtYmFzZWQpLgorICAgICAqCisgICAgICogQHBhcmFtIGxpbmVOdW1iZXIgVGhlIGxpbmUgbnVtYmVyLCBvciAtMSBpZiBub25lIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBAc2VlICNnZXRMaW5lTnVtYmVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TGluZU51bWJlciAoaW50IGxpbmVOdW1iZXIpCisgICAgeworICAgIHRoaXMubGluZU51bWJlciA9IGxpbmVOdW1iZXI7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGNvbHVtbiBudW1iZXIgZm9yIHRoaXMgbG9jYXRvciAoMS1iYXNlZCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29sdW1uTnVtYmVyIFRoZSBjb2x1bW4gbnVtYmVyLCBvciAtMSBpZiBub25lIGlzIGF2YWlsYWJsZS4KKyAgICAgKiBAc2VlICNnZXRDb2x1bW5OdW1iZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb2x1bW5OdW1iZXIgKGludCBjb2x1bW5OdW1iZXIpCisgICAgeworICAgIHRoaXMuY29sdW1uTnVtYmVyID0gY29sdW1uTnVtYmVyOworICAgIH0KKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBJbnRlcm5hbCBzdGF0ZS4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisgICAgcHJpdmF0ZSBTdHJpbmcgcHVibGljSWQ7CisgICAgcHJpdmF0ZSBTdHJpbmcgc3lzdGVtSWQ7CisgICAgcHJpdmF0ZSBpbnQgbGluZU51bWJlcjsKKyAgICBwcml2YXRlIGludCBjb2x1bW5OdW1iZXI7CisKK30KKworLy8gZW5kIG9mIExvY2F0b3JJbXBsLmphdmEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9oZWxwZXJzL05hbWVzcGFjZVN1cHBvcnQuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9oZWxwZXJzL05hbWVzcGFjZVN1cHBvcnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Zjk2Nzk3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2hlbHBlcnMvTmFtZXNwYWNlU3VwcG9ydC5qYXZhCkBAIC0wLDAgKzEsODMyIEBACisvLyBOYW1lc3BhY2VTdXBwb3J0LmphdmEgLSBnZW5lcmljIE5hbWVzcGFjZSBzdXBwb3J0IGZvciBTQVguCisvLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCisvLyBXcml0dGVuIGJ5IERhdmlkIE1lZ2dpbnNvbgorLy8gVGhpcyBjbGFzcyBpcyBpbiB0aGUgUHVibGljIERvbWFpbi4gIE5PIFdBUlJBTlRZIQorLy8gJElkOiBOYW1lc3BhY2VTdXBwb3J0LmphdmEsdiAxLjE1IDIwMDQvMDQvMjYgMTc6MzQ6MzUgZG1lZ2dpbnNvbiBFeHAgJAorCitwYWNrYWdlIG9yZy54bWwuc2F4LmhlbHBlcnM7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuRW1wdHlTdGFja0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKKworLyoqCisgKiBFbmNhcHN1bGF0ZSBOYW1lc3BhY2UgbG9naWMgZm9yIHVzZSBieSBhcHBsaWNhdGlvbnMgdXNpbmcgU0FYLAorICogb3IgaW50ZXJuYWxseSBieSBTQVggZHJpdmVycy4KKyAqCisgKiA8YmxvY2txdW90ZT4KKyAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCisgKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+CisgKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KKyAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgorICogPC9ibG9ja3F1b3RlPgorICoKKyAqIDxwPlRoaXMgY2xhc3MgZW5jYXBzdWxhdGVzIHRoZSBsb2dpYyBvZiBOYW1lc3BhY2UgcHJvY2Vzc2luZzogaXQKKyAqIHRyYWNrcyB0aGUgZGVjbGFyYXRpb25zIGN1cnJlbnRseSBpbiBmb3JjZSBmb3IgZWFjaCBjb250ZXh0IGFuZAorICogYXV0b21hdGljYWxseSBwcm9jZXNzZXMgcXVhbGlmaWVkIFhNTCBuYW1lcyBpbnRvIHRoZWlyIE5hbWVzcGFjZQorICogcGFydHM7IGl0IGNhbiBhbHNvIGJlIHVzZWQgaW4gcmV2ZXJzZSBmb3IgZ2VuZXJhdGluZyBYTUwgcW5hbWVzCisgKiBmcm9tIE5hbWVzcGFjZXMuPC9wPgorICoKKyAqIDxwPk5hbWVzcGFjZSBzdXBwb3J0IG9iamVjdHMgYXJlIHJldXNhYmxlLCBidXQgdGhlIHJlc2V0IG1ldGhvZAorICogbXVzdCBiZSBpbnZva2VkIGJldHdlZW4gZWFjaCBzZXNzaW9uLjwvcD4KKyAqCisgKiA8cD5IZXJlIGlzIGEgc2ltcGxlIHNlc3Npb246PC9wPgorICoKKyAqIDxwcmU+CisgKiBTdHJpbmcgcGFydHNbXSA9IG5ldyBTdHJpbmdbM107CisgKiBOYW1lc3BhY2VTdXBwb3J0IHN1cHBvcnQgPSBuZXcgTmFtZXNwYWNlU3VwcG9ydCgpOworICoKKyAqIHN1cHBvcnQucHVzaENvbnRleHQoKTsKKyAqIHN1cHBvcnQuZGVjbGFyZVByZWZpeCgiIiwgImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiKTsKKyAqIHN1cHBvcnQuZGVjbGFyZVByZWZpeCgiZGMiLCAiaHR0cDovL3d3dy5wdXJsLm9yZy9kYyMiKTsKKyAqCisgKiBwYXJ0cyA9IHN1cHBvcnQucHJvY2Vzc05hbWUoInAiLCBwYXJ0cywgZmFsc2UpOworICogU3lzdGVtLm91dC5wcmludGxuKCJOYW1lc3BhY2UgVVJJOiAiICsgcGFydHNbMF0pOworICogU3lzdGVtLm91dC5wcmludGxuKCJMb2NhbCBuYW1lOiAiICsgcGFydHNbMV0pOworICogU3lzdGVtLm91dC5wcmludGxuKCJSYXcgbmFtZTogIiArIHBhcnRzWzJdKTsKKyAqCisgKiBwYXJ0cyA9IHN1cHBvcnQucHJvY2Vzc05hbWUoImRjOnRpdGxlIiwgcGFydHMsIGZhbHNlKTsKKyAqIFN5c3RlbS5vdXQucHJpbnRsbigiTmFtZXNwYWNlIFVSSTogIiArIHBhcnRzWzBdKTsKKyAqIFN5c3RlbS5vdXQucHJpbnRsbigiTG9jYWwgbmFtZTogIiArIHBhcnRzWzFdKTsKKyAqIFN5c3RlbS5vdXQucHJpbnRsbigiUmF3IG5hbWU6ICIgKyBwYXJ0c1syXSk7CisgKgorICogc3VwcG9ydC5wb3BDb250ZXh0KCk7CisgKiA8L3ByZT4KKyAqCisgKiA8cD5Ob3RlIHRoYXQgdGhpcyBjbGFzcyBpcyBvcHRpbWl6ZWQgZm9yIHRoZSB1c2UgY2FzZSB3aGVyZSBtb3N0CisgKiBlbGVtZW50cyBkbyBub3QgY29udGFpbiBOYW1lc3BhY2UgZGVjbGFyYXRpb25zOiBpZiB0aGUgc2FtZQorICogcHJlZml4L1VSSSBtYXBwaW5nIGlzIHJlcGVhdGVkIGZvciBlYWNoIGNvbnRleHQgKGZvciBleGFtcGxlKSwgdGhpcworICogY2xhc3Mgd2lsbCBiZSBzb21ld2hhdCBsZXNzIGVmZmljaWVudC48L3A+CisgKgorICogPHA+QWx0aG91Z2ggU0FYIGRyaXZlcnMgKHBhcnNlcnMpIG1heSBjaG9vc2UgdG8gdXNlIHRoaXMgY2xhc3MgdG8KKyAqIGltcGxlbWVudCBuYW1lc3BhY2UgaGFuZGxpbmcsIHRoZXkgYXJlIG5vdCByZXF1aXJlZCB0byBkbyBzby4KKyAqIEFwcGxpY2F0aW9ucyBtdXN0IHRyYWNrIG5hbWVzcGFjZSBpbmZvcm1hdGlvbiB0aGVtc2VsdmVzIGlmIHRoZXkKKyAqIHdhbnQgdG8gdXNlIG5hbWVzcGFjZSBpbmZvcm1hdGlvbi4KKyAqCisgKiBAc2luY2UgU0FYIDIuMAorICogQGF1dGhvciBEYXZpZCBNZWdnaW5zb24KKyAqIEB2ZXJzaW9uIDIuMC4xIChzYXgycjIpCisgKi8KK3B1YmxpYyBjbGFzcyBOYW1lc3BhY2VTdXBwb3J0Cit7CisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIENvbnN0YW50cy4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisKKyAgICAvKioKKyAgICAgKiBUaGUgWE1MIE5hbWVzcGFjZSBVUkkgYXMgYSBjb25zdGFudC4KKyAgICAgKiBUaGUgdmFsdWUgaXMgPGNvZGU+aHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlPC9jb2RlPgorICAgICAqIGFzIGRlZmluZWQgaW4gdGhlICJOYW1lc3BhY2VzIGluIFhNTCIgKiByZWNvbW1lbmRhdGlvbi4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaXMgdGhlIE5hbWVzcGFjZSBVUkkgdGhhdCBpcyBhdXRvbWF0aWNhbGx5IG1hcHBlZAorICAgICAqIHRvIHRoZSAieG1sIiBwcmVmaXguPC9wPgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTE5TID0KKyAgICAiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIjsKKworCisgICAgLyoqCisgICAgICogVGhlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBVUkkgYXMgYSBjb25zdGFudC4KKyAgICAgKiBUaGUgdmFsdWUgaXMgPGNvZGU+aHR0cDovL3d3dy53My5vcmcveG1sbnMvMjAwMC88L2NvZGU+LCBhcyBkZWZpbmVkCisgICAgICogaW4gYSBiYWNrd2FyZHMtaW5jb21wYXRpYmxlIGVycmF0dW0gdG8gdGhlICJOYW1lc3BhY2VzIGluIFhNTCIKKyAgICAgKiByZWNvbW1lbmRhdGlvbi4gIEJlY2F1c2UgdGhhdCBlcnJhdHVtIHBvc3RkYXRlZCBTQVgyLCBTQVgyIGRlZmF1bHRzCisgICAgICogdG8gdGhlIG9yaWdpbmFsIHJlY29tbWVuZGF0aW9uLCBhbmQgZG9lcyBub3Qgbm9ybWFsbHkgdXNlIHRoaXMgVVJJLgorICAgICAqCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGlzIHRoZSBOYW1lc3BhY2UgVVJJIHRoYXQgaXMgb3B0aW9uYWxseSBhcHBsaWVkIHRvCisgICAgICogPGVtPnhtbG5zPC9lbT4gYW5kIDxlbT54bWxuczoqPC9lbT4gYXR0cmlidXRlcywgd2hpY2ggYXJlIHVzZWQgdG8KKyAgICAgKiBkZWNsYXJlIG5hbWVzcGFjZXMuICA8L3A+CisgICAgICoKKyAgICAgKiBAc2luY2UgU0FYIDIuMWFscGhhCisgICAgICogQHNlZSAjc2V0TmFtZXNwYWNlRGVjbFVyaXMKKyAgICAgKiBAc2VlICNpc05hbWVzcGFjZURlY2xVcmlzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTlNERUNMID0KKyAgICAiaHR0cDovL3d3dy53My5vcmcveG1sbnMvMjAwMC8iOworCisKKyAgICAvKioKKyAgICAgKiBBbiBlbXB0eSBlbnVtZXJhdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFbnVtZXJhdGlvbiBFTVBUWV9FTlVNRVJBVElPTiA9IENvbGxlY3Rpb25zLmVudW1lcmF0aW9uKENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpKTsKKworDAorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gQ29uc3RydWN0b3IuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IE5hbWVzcGFjZSBzdXBwb3J0IG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgTmFtZXNwYWNlU3VwcG9ydCAoKQorICAgIHsKKyAgICByZXNldCgpOworICAgIH0KKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBDb250ZXh0IG1hbmFnZW1lbnQuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoqCisgICAgICogUmVzZXQgdGhpcyBOYW1lc3BhY2Ugc3VwcG9ydCBvYmplY3QgZm9yIHJldXNlLgorICAgICAqCisgICAgICogPHA+SXQgaXMgbmVjZXNzYXJ5IHRvIGludm9rZSB0aGlzIG1ldGhvZCBiZWZvcmUgcmV1c2luZyB0aGUKKyAgICAgKiBOYW1lc3BhY2Ugc3VwcG9ydCBvYmplY3QgZm9yIGEgbmV3IHNlc3Npb24uICBJZiBuYW1lc3BhY2UKKyAgICAgKiBkZWNsYXJhdGlvbiBVUklzIGFyZSB0byBiZSBzdXBwb3J0ZWQsIHRoYXQgZmxhZyBtdXN0IGFsc28KKyAgICAgKiBiZSBzZXQgdG8gYSBub24tZGVmYXVsdCB2YWx1ZS4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiBAc2VlICNzZXROYW1lc3BhY2VEZWNsVXJpcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlc2V0ICgpCisgICAgeworICAgIGNvbnRleHRzID0gbmV3IENvbnRleHRbMzJdOworICAgIG5hbWVzcGFjZURlY2xVcmlzID0gZmFsc2U7CisgICAgY29udGV4dFBvcyA9IDA7CisgICAgY29udGV4dHNbY29udGV4dFBvc10gPSBjdXJyZW50Q29udGV4dCA9IG5ldyBDb250ZXh0KCk7CisgICAgY3VycmVudENvbnRleHQuZGVjbGFyZVByZWZpeCgieG1sIiwgWE1MTlMpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogU3RhcnQgYSBuZXcgTmFtZXNwYWNlIGNvbnRleHQuCisgICAgICogVGhlIG5ldyBjb250ZXh0IHdpbGwgYXV0b21hdGljYWxseSBpbmhlcml0CisgICAgICogdGhlIGRlY2xhcmF0aW9ucyBvZiBpdHMgcGFyZW50IGNvbnRleHQsIGJ1dCBpdCB3aWxsIGFsc28ga2VlcAorICAgICAqIHRyYWNrIG9mIHdoaWNoIGRlY2xhcmF0aW9ucyB3ZXJlIG1hZGUgd2l0aGluIHRoaXMgY29udGV4dC4KKyAgICAgKgorICAgICAqIDxwPkV2ZW50IGNhbGxiYWNrIGNvZGUgc2hvdWxkIHN0YXJ0IGEgbmV3IGNvbnRleHQgb25jZSBwZXIgZWxlbWVudC4KKyAgICAgKiBUaGlzIG1lYW5zIGJlaW5nIHJlYWR5IHRvIGNhbGwgdGhpcyBpbiBlaXRoZXIgb2YgdHdvIHBsYWNlcy4KKyAgICAgKiBGb3IgZWxlbWVudHMgdGhhdCBkb24ndCBpbmNsdWRlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMsIHRoZQorICAgICAqIDxlbT5Db250ZW50SGFuZGxlci5zdGFydEVsZW1lbnQoKTwvZW0+IGNhbGxiYWNrIGlzIHRoZSByaWdodCBwbGFjZS4KKyAgICAgKiBGb3IgZWxlbWVudHMgd2l0aCBzdWNoIGEgZGVjbGFyYXRpb24sIGl0J2QgZG9uZSBpbiB0aGUgZmlyc3QKKyAgICAgKiA8ZW0+Q29udGVudEhhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKCk8L2VtPiBjYWxsYmFjay4KKyAgICAgKiBBIGJvb2xlYW4gZmxhZyBjYW4gYmUgdXNlZCB0bworICAgICAqIHRyYWNrIHdoZXRoZXIgYSBjb250ZXh0IGhhcyBiZWVuIHN0YXJ0ZWQgeWV0LiAgV2hlbiBlaXRoZXIgb2YKKyAgICAgKiB0aG9zZSBtZXRob2RzIGlzIGNhbGxlZCwgaXQgY2hlY2tzIHRoZSBmbGFnIHRvIHNlZSBpZiBhIG5ldyBjb250ZXh0CisgICAgICogbmVlZHMgdG8gYmUgc3RhcnRlZC4gIElmIHNvLCBpdCBzdGFydHMgdGhlIGNvbnRleHQgYW5kIHNldHMgdGhlCisgICAgICogZmxhZy4gIEFmdGVyIDxlbT5Db250ZW50SGFuZGxlci5zdGFydEVsZW1lbnQoKTwvZW0+CisgICAgICogZG9lcyB0aGF0LCBpdCBhbHdheXMgY2xlYXJzIHRoZSBmbGFnLgorICAgICAqCisgICAgICogPHA+Tm9ybWFsbHksIFNBWCBkcml2ZXJzIHdvdWxkIHB1c2ggYSBuZXcgY29udGV4dCBhdCB0aGUgYmVnaW5uaW5nCisgICAgICogb2YgZWFjaCBYTUwgZWxlbWVudC4gIFRoZW4gdGhleSBwZXJmb3JtIGEgZmlyc3QgcGFzcyBvdmVyIHRoZQorICAgICAqIGF0dHJpYnV0ZXMgdG8gcHJvY2VzcyBhbGwgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucywgbWFraW5nCisgICAgICogPGVtPkNvbnRlbnRIYW5kbGVyLnN0YXJ0UHJlZml4TWFwcGluZygpPC9lbT4gY2FsbGJhY2tzLgorICAgICAqIFRoZW4gYSBzZWNvbmQgcGFzcyBpcyBtYWRlLCB0byBkZXRlcm1pbmUgdGhlIG5hbWVzcGFjZS1xdWFsaWZpZWQKKyAgICAgKiBuYW1lcyBmb3IgYWxsIGF0dHJpYnV0ZXMgYW5kIGZvciB0aGUgZWxlbWVudCBuYW1lLgorICAgICAqIEZpbmFsbHkgYWxsIHRoZSBpbmZvcm1hdGlvbiBmb3IgdGhlCisgICAgICogPGVtPkNvbnRlbnRIYW5kbGVyLnN0YXJ0RWxlbWVudCgpPC9lbT4gY2FsbGJhY2sgaXMgYXZhaWxhYmxlLAorICAgICAqIHNvIGl0IGNhbiB0aGVuIGJlIG1hZGUuCisgICAgICoKKyAgICAgKiA8cD5UaGUgTmFtZXNwYWNlIHN1cHBvcnQgb2JqZWN0IGFsd2F5cyBzdGFydHMgd2l0aCBhIGJhc2UgY29udGV4dAorICAgICAqIGFscmVhZHkgaW4gZm9yY2U6IGluIHRoaXMgY29udGV4dCwgb25seSB0aGUgInhtbCIgcHJlZml4IGlzCisgICAgICogZGVjbGFyZWQuPC9wPgorICAgICAqCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcgorICAgICAqIEBzZWUgI3BvcENvbnRleHQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXNoQ29udGV4dCAoKQorICAgIHsKKyAgICBpbnQgbWF4ID0gY29udGV4dHMubGVuZ3RoOworCisgICAgY29udGV4dHMgW2NvbnRleHRQb3NdLmRlY2xzT0sgPSBmYWxzZTsKKyAgICBjb250ZXh0UG9zKys7CisKKyAgICAgICAgICAgICAgICAvLyBFeHRlbmQgdGhlIGFycmF5IGlmIG5lY2Vzc2FyeQorICAgIGlmIChjb250ZXh0UG9zID49IG1heCkgeworICAgICAgICBDb250ZXh0IG5ld0NvbnRleHRzW10gPSBuZXcgQ29udGV4dFttYXgqMl07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY29udGV4dHMsIDAsIG5ld0NvbnRleHRzLCAwLCBtYXgpOworICAgICAgICBtYXggKj0gMjsKKyAgICAgICAgY29udGV4dHMgPSBuZXdDb250ZXh0czsKKyAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBBbGxvY2F0ZSB0aGUgY29udGV4dCBpZiBuZWNlc3NhcnkuCisgICAgY3VycmVudENvbnRleHQgPSBjb250ZXh0c1tjb250ZXh0UG9zXTsKKyAgICBpZiAoY3VycmVudENvbnRleHQgPT0gbnVsbCkgeworICAgICAgICBjb250ZXh0c1tjb250ZXh0UG9zXSA9IGN1cnJlbnRDb250ZXh0ID0gbmV3IENvbnRleHQoKTsKKyAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBTZXQgdGhlIHBhcmVudCwgaWYgYW55LgorICAgIGlmIChjb250ZXh0UG9zID4gMCkgeworICAgICAgICBjdXJyZW50Q29udGV4dC5zZXRQYXJlbnQoY29udGV4dHNbY29udGV4dFBvcyAtIDFdKTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXZlcnQgdG8gdGhlIHByZXZpb3VzIE5hbWVzcGFjZSBjb250ZXh0LgorICAgICAqCisgICAgICogPHA+Tm9ybWFsbHksIHlvdSBzaG91bGQgcG9wIHRoZSBjb250ZXh0IGF0IHRoZSBlbmQgb2YgZWFjaAorICAgICAqIFhNTCBlbGVtZW50LiAgQWZ0ZXIgcG9wcGluZyB0aGUgY29udGV4dCwgYWxsIE5hbWVzcGFjZSBwcmVmaXgKKyAgICAgKiBtYXBwaW5ncyB0aGF0IHdlcmUgcHJldmlvdXNseSBpbiBmb3JjZSBhcmUgcmVzdG9yZWQuPC9wPgorICAgICAqCisgICAgICogPHA+WW91IG11c3Qgbm90IGF0dGVtcHQgdG8gZGVjbGFyZSBhZGRpdGlvbmFsIE5hbWVzcGFjZQorICAgICAqIHByZWZpeGVzIGFmdGVyIHBvcHBpbmcgYSBjb250ZXh0LCB1bmxlc3MgeW91IHB1c2ggYW5vdGhlcgorICAgICAqIGNvbnRleHQgZmlyc3QuPC9wPgorICAgICAqCisgICAgICogQHNlZSAjcHVzaENvbnRleHQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwb3BDb250ZXh0ICgpCisgICAgeworICAgIGNvbnRleHRzW2NvbnRleHRQb3NdLmNsZWFyKCk7CisgICAgY29udGV4dFBvcy0tOworICAgIGlmIChjb250ZXh0UG9zIDwgMCkgeworICAgICAgICB0aHJvdyBuZXcgRW1wdHlTdGFja0V4Y2VwdGlvbigpOworICAgIH0KKyAgICBjdXJyZW50Q29udGV4dCA9IGNvbnRleHRzW2NvbnRleHRQb3NdOworICAgIH0KKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBPcGVyYXRpb25zIHdpdGhpbiBhIGNvbnRleHQuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoqCisgICAgICogRGVjbGFyZSBhIE5hbWVzcGFjZSBwcmVmaXguICBBbGwgcHJlZml4ZXMgbXVzdCBiZSBkZWNsYXJlZAorICAgICAqIGJlZm9yZSB0aGV5IGFyZSByZWZlcmVuY2VkLiAgRm9yIGV4YW1wbGUsIGEgU0FYIGRyaXZlciAocGFyc2VyKQorICAgICAqIHdvdWxkIHNjYW4gYW4gZWxlbWVudCdzIGF0dHJpYnV0ZXMKKyAgICAgKiBpbiB0d28gcGFzc2VzOiAgZmlyc3QgZm9yIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMsCisgICAgICogdGhlbiBhIHNlY29uZCBwYXNzIHVzaW5nIHtAbGluayAjcHJvY2Vzc05hbWUgcHJvY2Vzc05hbWUoKX0gdG8KKyAgICAgKiBpbnRlcnByZXQgcHJlZml4ZXMgYWdhaW5zdCAocG90ZW50aWFsbHkgcmVkZWZpbmVkKSBwcmVmaXhlcy4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIGRlY2xhcmVzIGEgcHJlZml4IGluIHRoZSBjdXJyZW50IE5hbWVzcGFjZQorICAgICAqIGNvbnRleHQ7IHRoZSBwcmVmaXggd2lsbCByZW1haW4gaW4gZm9yY2UgdW50aWwgdGhpcyBjb250ZXh0CisgICAgICogaXMgcG9wcGVkLCB1bmxlc3MgaXQgaXMgc2hhZG93ZWQgaW4gYSBkZXNjZW5kYW50IGNvbnRleHQuPC9wPgorICAgICAqCisgICAgICogPHA+VG8gZGVjbGFyZSB0aGUgZGVmYXVsdCBlbGVtZW50IE5hbWVzcGFjZSwgdXNlIHRoZSBlbXB0eSBzdHJpbmcgYXMKKyAgICAgKiB0aGUgcHJlZml4LjwvcD4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB5b3UgbXVzdCA8ZW0+bm90PC9lbT4gZGVjbGFyZSBhIHByZWZpeCBhZnRlcgorICAgICAqIHlvdSd2ZSBwdXNoZWQgYW5kIHBvcHBlZCBhbm90aGVyIE5hbWVzcGFjZSBjb250ZXh0LCBvcgorICAgICAqIHRyZWF0ZWQgdGhlIGRlY2xhcmF0aW9ucyBwaGFzZSBhcyBjb21wbGV0ZSBieSBwcm9jZXNzaW5nCisgICAgICogYSBwcmVmaXhlZCBuYW1lLjwvcD4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCB0aGVyZSBpcyBhbiBhc3ltbWV0cnkgaW4gdGhpcyBsaWJyYXJ5OiB7QGxpbmsKKyAgICAgKiAjZ2V0UHJlZml4IGdldFByZWZpeH0gd2lsbCBub3QgcmV0dXJuIHRoZSAiIiBwcmVmaXgsCisgICAgICogZXZlbiBpZiB5b3UgaGF2ZSBkZWNsYXJlZCBhIGRlZmF1bHQgZWxlbWVudCBuYW1lc3BhY2UuCisgICAgICogVG8gY2hlY2sgZm9yIGEgZGVmYXVsdCBuYW1lc3BhY2UsCisgICAgICogeW91IGhhdmUgdG8gbG9vayBpdCB1cCBleHBsaWNpdGx5IHVzaW5nIHtAbGluayAjZ2V0VVJJIGdldFVSSX0uCisgICAgICogVGhpcyBhc3ltbWV0cnkgZXhpc3RzIHRvIG1ha2UgaXQgZWFzaWVyIHRvIGxvb2sgdXAgcHJlZml4ZXMKKyAgICAgKiBmb3IgYXR0cmlidXRlIG5hbWVzLCB3aGVyZSB0aGUgZGVmYXVsdCBwcmVmaXggaXMgbm90IGFsbG93ZWQuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRvIGRlY2xhcmUsIG9yIHRoZSBlbXB0eSBzdHJpbmcgdG8KKyAgICAgKiAgICBpbmRpY2F0ZSB0aGUgZGVmYXVsdCBlbGVtZW50IG5hbWVzcGFjZS4gIFRoaXMgbWF5IG5ldmVyIGhhdmUKKyAgICAgKiAgICB0aGUgdmFsdWUgInhtbCIgb3IgInhtbG5zIi4KKyAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBwcmVmaXguCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBwcmVmaXggd2FzIGxlZ2FsLCBmYWxzZSBvdGhlcndpc2UKKyAgICAgKgorICAgICAqIEBzZWUgI3Byb2Nlc3NOYW1lCisgICAgICogQHNlZSAjZ2V0VVJJCisgICAgICogQHNlZSAjZ2V0UHJlZml4CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZGVjbGFyZVByZWZpeCAoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKKyAgICB7CisgICAgaWYgKHByZWZpeC5lcXVhbHMoInhtbCIpIHx8IHByZWZpeC5lcXVhbHMoInhtbG5zIikpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0gZWxzZSB7CisgICAgICAgIGN1cnJlbnRDb250ZXh0LmRlY2xhcmVQcmVmaXgocHJlZml4LCB1cmkpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzIGEgcmF3IFhNTCBxdWFsaWZpZWQgbmFtZSwgYWZ0ZXIgYWxsIGRlY2xhcmF0aW9ucyBpbiB0aGUKKyAgICAgKiBjdXJyZW50IGNvbnRleHQgaGF2ZSBiZWVuIGhhbmRsZWQgYnkge0BsaW5rICNkZWNsYXJlUHJlZml4CisgICAgICogZGVjbGFyZVByZWZpeCgpfS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIHByb2Nlc3NlcyBhIHJhdyBYTUwgcXVhbGlmaWVkIG5hbWUgaW4gdGhlCisgICAgICogY3VycmVudCBjb250ZXh0IGJ5IHJlbW92aW5nIHRoZSBwcmVmaXggYW5kIGxvb2tpbmcgaXQgdXAgYW1vbmcKKyAgICAgKiB0aGUgcHJlZml4ZXMgY3VycmVudGx5IGRlY2xhcmVkLiAgVGhlIHJldHVybiB2YWx1ZSB3aWxsIGJlIHRoZQorICAgICAqIGFycmF5IHN1cHBsaWVkIGJ5IHRoZSBjYWxsZXIsIGZpbGxlZCBpbiBhcyBmb2xsb3dzOjwvcD4KKyAgICAgKgorICAgICAqIDxkbD4KKyAgICAgKiA8ZHQ+cGFydHNbMF08L2R0PgorICAgICAqIDxkZD5UaGUgTmFtZXNwYWNlIFVSSSwgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIG5vbmUgaXMKKyAgICAgKiAgaW4gdXNlLjwvZGQ+CisgICAgICogPGR0PnBhcnRzWzFdPC9kdD4KKyAgICAgKiA8ZGQ+VGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KS48L2RkPgorICAgICAqIDxkdD5wYXJ0c1syXTwvZHQ+CisgICAgICogPGRkPlRoZSBvcmlnaW5hbCByYXcgbmFtZS48L2RkPgorICAgICAqIDwvZGw+CisgICAgICoKKyAgICAgKiA8cD5BbGwgb2YgdGhlIHN0cmluZ3MgaW4gdGhlIGFycmF5IHdpbGwgYmUgaW50ZXJuYWxpemVkLiAgSWYKKyAgICAgKiB0aGUgcmF3IG5hbWUgaGFzIGEgcHJlZml4IHRoYXQgaGFzIG5vdCBiZWVuIGRlY2xhcmVkLCB0aGVuCisgICAgICogdGhlIHJldHVybiB2YWx1ZSB3aWxsIGJlIG51bGwuPC9wPgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IGF0dHJpYnV0ZSBuYW1lcyBhcmUgcHJvY2Vzc2VkIGRpZmZlcmVudGx5IHRoYW4KKyAgICAgKiBlbGVtZW50IG5hbWVzOiBhbiB1bnByZWZpeGVkIGVsZW1lbnQgbmFtZSB3aWxsIHJlY2VpdmUgdGhlCisgICAgICogZGVmYXVsdCBOYW1lc3BhY2UgKGlmIGFueSksIHdoaWxlIGFuIHVucHJlZml4ZWQgYXR0cmlidXRlIG5hbWUKKyAgICAgKiB3aWxsIG5vdC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIFhNTCBxdWFsaWZpZWQgbmFtZSB0byBiZSBwcm9jZXNzZWQuCisgICAgICogQHBhcmFtIHBhcnRzIEFuIGFycmF5IHN1cHBsaWVkIGJ5IHRoZSBjYWxsZXIsIGNhcGFibGUgb2YKKyAgICAgKiAgICAgICAgaG9sZGluZyBhdCBsZWFzdCB0aHJlZSBtZW1iZXJzLgorICAgICAqIEBwYXJhbSBpc0F0dHJpYnV0ZSBBIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgaXMgYW4KKyAgICAgKiAgICAgICAgYXR0cmlidXRlIG5hbWUgKHRydWUpIG9yIGFuIGVsZW1lbnQgbmFtZSAoZmFsc2UpLgorICAgICAqIEByZXR1cm4gVGhlIHN1cHBsaWVkIGFycmF5IGhvbGRpbmcgdGhyZWUgaW50ZXJuYWxpemVkIHN0cmluZ3MKKyAgICAgKiAgICAgICAgcmVwcmVzZW50aW5nIHRoZSBOYW1lc3BhY2UgVVJJIChvciBlbXB0eSBzdHJpbmcpLCB0aGUKKyAgICAgKiAgICAgICAgbG9jYWwgbmFtZSwgYW5kIHRoZSBYTUwgcXVhbGlmaWVkIG5hbWU7IG9yIG51bGwgaWYgdGhlcmUKKyAgICAgKiAgICAgICAgaXMgYW4gdW5kZWNsYXJlZCBwcmVmaXguCisgICAgICogQHNlZSAjZGVjbGFyZVByZWZpeAorICAgICAqIEBzZWUgamF2YS5sYW5nLlN0cmluZyNpbnRlcm4gKi8KKyAgICBwdWJsaWMgU3RyaW5nIFtdIHByb2Nlc3NOYW1lIChTdHJpbmcgcU5hbWUsIFN0cmluZyBwYXJ0c1tdLAorICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpc0F0dHJpYnV0ZSkKKyAgICB7CisgICAgU3RyaW5nIG15UGFydHNbXSA9IGN1cnJlbnRDb250ZXh0LnByb2Nlc3NOYW1lKHFOYW1lLCBpc0F0dHJpYnV0ZSk7CisgICAgaWYgKG15UGFydHMgPT0gbnVsbCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9IGVsc2UgeworICAgICAgICBwYXJ0c1swXSA9IG15UGFydHNbMF07CisgICAgICAgIHBhcnRzWzFdID0gbXlQYXJ0c1sxXTsKKyAgICAgICAgcGFydHNbMl0gPSBteVBhcnRzWzJdOworICAgICAgICByZXR1cm4gcGFydHM7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogTG9vayB1cCBhIHByZWZpeCBhbmQgZ2V0IHRoZSBjdXJyZW50bHktbWFwcGVkIE5hbWVzcGFjZSBVUkkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBsb29rcyB1cCB0aGUgcHJlZml4IGluIHRoZSBjdXJyZW50IGNvbnRleHQuCisgICAgICogVXNlIHRoZSBlbXB0eSBzdHJpbmcgKCIiKSBmb3IgdGhlIGRlZmF1bHQgTmFtZXNwYWNlLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCB0byBsb29rIHVwLgorICAgICAqIEByZXR1cm4gVGhlIGFzc29jaWF0ZWQgTmFtZXNwYWNlIFVSSSwgb3IgbnVsbCBpZiB0aGUgcHJlZml4CisgICAgICogICAgICAgICBpcyB1bmRlY2xhcmVkIGluIHRoaXMgY29udGV4dC4KKyAgICAgKiBAc2VlICNnZXRQcmVmaXgKKyAgICAgKiBAc2VlICNnZXRQcmVmaXhlcworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VVJJIChTdHJpbmcgcHJlZml4KQorICAgIHsKKyAgICByZXR1cm4gY3VycmVudENvbnRleHQuZ2V0VVJJKHByZWZpeCk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYW4gZW51bWVyYXRpb24gb2YgYWxsIHByZWZpeGVzIHdob3NlIGRlY2xhcmF0aW9ucyBhcmUKKyAgICAgKiBhY3RpdmUgaW4gdGhlIGN1cnJlbnQgY29udGV4dC4KKyAgICAgKiBUaGlzIGluY2x1ZGVzIGRlY2xhcmF0aW9ucyBmcm9tIHBhcmVudCBjb250ZXh0cyB0aGF0IGhhdmUKKyAgICAgKiBub3QgYmVlbiBvdmVycmlkZGVuLgorICAgICAqCisgICAgICogPHA+PHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBpZiB0aGVyZSBpcyBhIGRlZmF1bHQgcHJlZml4LCBpdCB3aWxsIG5vdCBiZQorICAgICAqIHJldHVybmVkIGluIHRoaXMgZW51bWVyYXRpb247IGNoZWNrIGZvciB0aGUgZGVmYXVsdCBwcmVmaXgKKyAgICAgKiB1c2luZyB0aGUge0BsaW5rICNnZXRVUkkgZ2V0VVJJfSB3aXRoIGFuIGFyZ3VtZW50IG9mICIiLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQW4gZW51bWVyYXRpb24gb2YgcHJlZml4ZXMgKG5ldmVyIGVtcHR5KS4KKyAgICAgKiBAc2VlICNnZXREZWNsYXJlZFByZWZpeGVzCisgICAgICogQHNlZSAjZ2V0VVJJCisgICAgICovCisgICAgcHVibGljIEVudW1lcmF0aW9uIGdldFByZWZpeGVzICgpCisgICAgeworICAgIHJldHVybiBjdXJyZW50Q29udGV4dC5nZXRQcmVmaXhlcygpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJuIG9uZSBvZiB0aGUgcHJlZml4ZXMgbWFwcGVkIHRvIGEgTmFtZXNwYWNlIFVSSS4KKyAgICAgKgorICAgICAqIDxwPklmIG1vcmUgdGhhbiBvbmUgcHJlZml4IGlzIGN1cnJlbnRseSBtYXBwZWQgdG8gdGhlIHNhbWUKKyAgICAgKiBVUkksIHRoaXMgbWV0aG9kIHdpbGwgbWFrZSBhbiBhcmJpdHJhcnkgc2VsZWN0aW9uOyBpZiB5b3UKKyAgICAgKiB3YW50IGFsbCBvZiB0aGUgcHJlZml4ZXMsIHVzZSB0aGUge0BsaW5rICNnZXRQcmVmaXhlc30KKyAgICAgKiBtZXRob2QgaW5zdGVhZC48L3A+CisgICAgICoKKyAgICAgKiA8cD48c3Ryb25nPk5vdGU6PC9zdHJvbmc+IHRoaXMgd2lsbCBuZXZlciByZXR1cm4gdGhlIGVtcHR5IChkZWZhdWx0KSBwcmVmaXg7CisgICAgICogdG8gY2hlY2sgZm9yIGEgZGVmYXVsdCBwcmVmaXgsIHVzZSB0aGUge0BsaW5rICNnZXRVUkkgZ2V0VVJJfQorICAgICAqIG1ldGhvZCB3aXRoIGFuIGFyZ3VtZW50IG9mICIiLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmkgdGhlIG5hbWVzcGFjZSBVUkkKKyAgICAgKiBAcmV0dXJuIG9uZSBvZiB0aGUgcHJlZml4ZXMgY3VycmVudGx5IG1hcHBlZCB0byB0aGUgVVJJIHN1cHBsaWVkLAorICAgICAqICAgICAgICAgb3IgbnVsbCBpZiBub25lIGlzIG1hcHBlZCBvciBpZiB0aGUgVVJJIGlzIGFzc2lnbmVkIHRvCisgICAgICogICAgICAgICB0aGUgZGVmYXVsdCBuYW1lc3BhY2UKKyAgICAgKiBAc2VlICNnZXRQcmVmaXhlcyhqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqIEBzZWUgI2dldFVSSQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4IChTdHJpbmcgdXJpKQorICAgIHsKKyAgICByZXR1cm4gY3VycmVudENvbnRleHQuZ2V0UHJlZml4KHVyaSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYW4gZW51bWVyYXRpb24gb2YgYWxsIHByZWZpeGVzIGZvciBhIGdpdmVuIFVSSSB3aG9zZQorICAgICAqIGRlY2xhcmF0aW9ucyBhcmUgYWN0aXZlIGluIHRoZSBjdXJyZW50IGNvbnRleHQuCisgICAgICogVGhpcyBpbmNsdWRlcyBkZWNsYXJhdGlvbnMgZnJvbSBwYXJlbnQgY29udGV4dHMgdGhhdCBoYXZlCisgICAgICogbm90IGJlZW4gb3ZlcnJpZGRlbi4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIHJldHVybnMgcHJlZml4ZXMgbWFwcGVkIHRvIGEgc3BlY2lmaWMgTmFtZXNwYWNlCisgICAgICogVVJJLiAgVGhlIHhtbDogcHJlZml4IHdpbGwgYmUgaW5jbHVkZWQuICBJZiB5b3Ugd2FudCBvbmx5IG9uZQorICAgICAqIHByZWZpeCB0aGF0J3MgbWFwcGVkIHRvIHRoZSBOYW1lc3BhY2UgVVJJLCBhbmQgeW91IGRvbid0IGNhcmUKKyAgICAgKiB3aGljaCBvbmUgeW91IGdldCwgdXNlIHRoZSB7QGxpbmsgI2dldFByZWZpeCBnZXRQcmVmaXh9CisgICAgICogIG1ldGhvZCBpbnN0ZWFkLjwvcD4KKyAgICAgKgorICAgICAqIDxwPjxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gdGhlIGVtcHR5IChkZWZhdWx0KSBwcmVmaXggaXMgPGVtPm5ldmVyPC9lbT4gaW5jbHVkZWQKKyAgICAgKiBpbiB0aGlzIGVudW1lcmF0aW9uOyB0byBjaGVjayBmb3IgdGhlIHByZXNlbmNlIG9mIGEgZGVmYXVsdAorICAgICAqIE5hbWVzcGFjZSwgdXNlIHRoZSB7QGxpbmsgI2dldFVSSSBnZXRVUkl9IG1ldGhvZCB3aXRoIGFuCisgICAgICogYXJndW1lbnQgb2YgIiIuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSS4KKyAgICAgKiBAcmV0dXJuIEFuIGVudW1lcmF0aW9uIG9mIHByZWZpeGVzIChuZXZlciBlbXB0eSkuCisgICAgICogQHNlZSAjZ2V0UHJlZml4CisgICAgICogQHNlZSAjZ2V0RGVjbGFyZWRQcmVmaXhlcworICAgICAqIEBzZWUgI2dldFVSSQorICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXRQcmVmaXhlcyhTdHJpbmcgdXJpKSB7CisgICAgICAgIEFycmF5TGlzdDxTdHJpbmc+IHByZWZpeGVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIEVudW1lcmF0aW9uIGFsbFByZWZpeGVzID0gZ2V0UHJlZml4ZXMoKTsKKyAgICAgICAgd2hpbGUgKGFsbFByZWZpeGVzLmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gKFN0cmluZykgYWxsUHJlZml4ZXMubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGlmICh1cmkuZXF1YWxzKGdldFVSSShwcmVmaXgpKSkgeworICAgICAgICAgICAgICAgIHByZWZpeGVzLmFkZChwcmVmaXgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbnVtZXJhdGlvbihwcmVmaXhlcyk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYW4gZW51bWVyYXRpb24gb2YgYWxsIHByZWZpeGVzIGRlY2xhcmVkIGluIHRoaXMgY29udGV4dC4KKyAgICAgKgorICAgICAqIDxwPlRoZSBlbXB0eSAoZGVmYXVsdCkgcHJlZml4IHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhpcworICAgICAqIGVudW1lcmF0aW9uOyBub3RlIHRoYXQgdGhpcyBiZWhhdmlvdXIgZGlmZmVycyBmcm9tIHRoYXQgb2YKKyAgICAgKiB7QGxpbmsgI2dldFByZWZpeH0gYW5kIHtAbGluayAjZ2V0UHJlZml4ZXN9LjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQW4gZW51bWVyYXRpb24gb2YgYWxsIHByZWZpeGVzIGRlY2xhcmVkIGluIHRoaXMKKyAgICAgKiAgICAgICAgIGNvbnRleHQuCisgICAgICogQHNlZSAjZ2V0UHJlZml4ZXMKKyAgICAgKiBAc2VlICNnZXRVUkkKKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bWVyYXRpb24gZ2V0RGVjbGFyZWRQcmVmaXhlcyAoKQorICAgIHsKKyAgICByZXR1cm4gY3VycmVudENvbnRleHQuZ2V0RGVjbGFyZWRQcmVmaXhlcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnRyb2xzIHdoZXRoZXIgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGF0dHJpYnV0ZXMgYXJlIHBsYWNlZAorICAgICAqIGludG8gdGhlIHtAbGluayAjTlNERUNMIE5TREVDTH0gbmFtZXNwYWNlCisgICAgICogYnkge0BsaW5rICNwcm9jZXNzTmFtZSBwcm9jZXNzTmFtZSgpfS4gIFRoaXMgbWF5IG9ubHkgYmUKKyAgICAgKiBjaGFuZ2VkIGJlZm9yZSBhbnkgY29udGV4dHMgaGF2ZSBiZWVuIHB1c2hlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGF0dHJpYnV0ZSBzdGF0ZS4gQSB2YWx1ZSBvZiB0cnVlCisgICAgICogICAgICAgICAgICAgIGVuYWJsZXMgdGhpcyBmZWF0dXJlLCBhIHZhbHVlIG9mIGZhbHNlIGRpc2FibGVzIGl0LgorICAgICAqCisgICAgICogQHNpbmNlIFNBWCAyLjFhbHBoYQorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gd2hlbiBhdHRlbXB0aW5nIHRvIHNldCB0aGlzCisgICAgICogICAgYWZ0ZXIgYW55IGNvbnRleHQgaGFzIGJlZW4gcHVzaGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE5hbWVzcGFjZURlY2xVcmlzIChib29sZWFuIHZhbHVlKQorICAgIHsKKyAgICBpZiAoY29udGV4dFBvcyAhPSAwKQorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uICgpOworICAgIGlmICh2YWx1ZSA9PSBuYW1lc3BhY2VEZWNsVXJpcykKKyAgICAgICAgcmV0dXJuOworICAgIG5hbWVzcGFjZURlY2xVcmlzID0gdmFsdWU7CisgICAgaWYgKHZhbHVlKQorICAgICAgICBjdXJyZW50Q29udGV4dC5kZWNsYXJlUHJlZml4ICgieG1sbnMiLCBOU0RFQ0wpOworICAgIGVsc2UgeworICAgICAgICBjb250ZXh0c1tjb250ZXh0UG9zXSA9IGN1cnJlbnRDb250ZXh0ID0gbmV3IENvbnRleHQoKTsKKyAgICAgICAgY3VycmVudENvbnRleHQuZGVjbGFyZVByZWZpeCgieG1sIiwgWE1MTlMpOworICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGF0dHJpYnV0ZXMgYXJlIHBsYWNlZCBpbnRvCisgICAgICogYSBuYW1lc3BhY2UuICBUaGlzIGJlaGF2aW9yIGlzIG5vdCB0aGUgZGVmYXVsdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBuYW1lc3BhY2UgZGVjbGFyYXRpb24gYXR0cmlidXRlcyBhcmUgZW5hYmxlZCwgZmFsc2UKKyAgICAgKiAgICAgICAgIG90aGVyd2lzZS4KKyAgICAgKiBAc2luY2UgU0FYIDIuMWFscGhhCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNOYW1lc3BhY2VEZWNsVXJpcyAoKQorICAgIHsgcmV0dXJuIG5hbWVzcGFjZURlY2xVcmlzOyB9CisKKworDAorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gSW50ZXJuYWwgc3RhdGUuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworICAgIHByaXZhdGUgQ29udGV4dCBjb250ZXh0c1tdOworICAgIHByaXZhdGUgQ29udGV4dCBjdXJyZW50Q29udGV4dDsKKyAgICBwcml2YXRlIGludCBjb250ZXh0UG9zOworICAgIHByaXZhdGUgYm9vbGVhbiBuYW1lc3BhY2VEZWNsVXJpczsKKworDAorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gSW50ZXJuYWwgY2xhc3Nlcy4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisgICAgLyoqCisgICAgICogSW50ZXJuYWwgY2xhc3MgZm9yIGEgc2luZ2xlIE5hbWVzcGFjZSBjb250ZXh0LgorICAgICAqCisgICAgICogPHA+VGhpcyBtb2R1bGUgY2FjaGVzIGFuZCByZXVzZXMgTmFtZXNwYWNlIGNvbnRleHRzLAorICAgICAqIHNvIHRoZSBudW1iZXIgYWxsb2NhdGVkCisgICAgICogd2lsbCBiZSBlcXVhbCB0byB0aGUgZWxlbWVudCBkZXB0aCBvZiB0aGUgZG9jdW1lbnQsIG5vdCB0byB0aGUgdG90YWwKKyAgICAgKiBudW1iZXIgb2YgZWxlbWVudHMgKGkuZS4gNS0xMCByYXRoZXIgdGhhbiB0ZW5zIG9mIHRob3VzYW5kcykuCisgICAgICogQWxzbywgZGF0YSBzdHJ1Y3R1cmVzIHVzZWQgdG8gcmVwcmVzZW50IGNvbnRleHRzIGFyZSBzaGFyZWQgd2hlbgorICAgICAqIHBvc3NpYmxlIChjaGlsZCBjb250ZXh0cyB3aXRob3V0IGRlY2xhcmF0aW9ucykgdG8gZnVydGhlciByZWR1Y2UKKyAgICAgKiB0aGUgYW1vdW50IG9mIG1lbW9yeSB0aGF0J3MgY29uc3VtZWQuCisgICAgICogPC9wPgorICAgICAqLworICAgIGZpbmFsIGNsYXNzIENvbnRleHQgeworCisgICAgLyoqCisgICAgICogQ3JlYXRlIHRoZSByb290LWxldmVsIE5hbWVzcGFjZSBjb250ZXh0LgorICAgICAqLworICAgIENvbnRleHQgKCkKKyAgICB7CisgICAgICAgIGNvcHlUYWJsZXMoKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIChSZSlzZXQgdGhlIHBhcmVudCBvZiB0aGlzIE5hbWVzcGFjZSBjb250ZXh0LgorICAgICAqIFRoZSBjb250ZXh0IG11c3QgZWl0aGVyIGhhdmUgYmVlbiBmcmVzaGx5IGNvbnN0cnVjdGVkLAorICAgICAqIG9yIG11c3QgaGF2ZSBiZWVuIGNsZWFyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgcGFyZW50IE5hbWVzcGFjZSBjb250ZXh0IG9iamVjdC4KKyAgICAgKi8KKyAgICB2b2lkIHNldFBhcmVudCAoQ29udGV4dCBwYXJlbnQpCisgICAgeworICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDsKKyAgICAgICAgZGVjbGFyYXRpb25zID0gbnVsbDsKKyAgICAgICAgcHJlZml4VGFibGUgPSBwYXJlbnQucHJlZml4VGFibGU7CisgICAgICAgIHVyaVRhYmxlID0gcGFyZW50LnVyaVRhYmxlOworICAgICAgICBlbGVtZW50TmFtZVRhYmxlID0gcGFyZW50LmVsZW1lbnROYW1lVGFibGU7CisgICAgICAgIGF0dHJpYnV0ZU5hbWVUYWJsZSA9IHBhcmVudC5hdHRyaWJ1dGVOYW1lVGFibGU7CisgICAgICAgIGRlZmF1bHROUyA9IHBhcmVudC5kZWZhdWx0TlM7CisgICAgICAgIGRlY2xTZWVuID0gZmFsc2U7CisgICAgICAgIGRlY2xzT0sgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1ha2VzIGFzc29jaWF0ZWQgc3RhdGUgYmVjb21lIGNvbGxlY3RpYmxlLAorICAgICAqIGludmFsaWRhdGluZyB0aGlzIGNvbnRleHQuCisgICAgICoge0BsaW5rICNzZXRQYXJlbnR9IG11c3QgYmUgY2FsbGVkIGJlZm9yZQorICAgICAqIHRoaXMgY29udGV4dCBtYXkgYmUgdXNlZCBhZ2Fpbi4KKyAgICAgKi8KKyAgICB2b2lkIGNsZWFyICgpCisgICAgeworICAgICAgICBwYXJlbnQgPSBudWxsOworICAgICAgICBwcmVmaXhUYWJsZSA9IG51bGw7CisgICAgICAgIHVyaVRhYmxlID0gbnVsbDsKKyAgICAgICAgZWxlbWVudE5hbWVUYWJsZSA9IG51bGw7CisgICAgICAgIGF0dHJpYnV0ZU5hbWVUYWJsZSA9IG51bGw7CisgICAgICAgIGRlZmF1bHROUyA9IG51bGw7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBEZWNsYXJlIGEgTmFtZXNwYWNlIHByZWZpeCBmb3IgdGhpcyBjb250ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRvIGRlY2xhcmUuCisgICAgICogQHBhcmFtIHVyaSBUaGUgYXNzb2NpYXRlZCBOYW1lc3BhY2UgVVJJLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguaGVscGVycy5OYW1lc3BhY2VTdXBwb3J0I2RlY2xhcmVQcmVmaXgKKyAgICAgKi8KKyAgICB2b2lkIGRlY2xhcmVQcmVmaXgoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkgeworICAgICAgICAvLyBMYXp5IHByb2Nlc3NpbmcuLi4KKyAgICAgICAgaWYgKCFkZWNsc09LKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uICgiY2FuJ3QgZGVjbGFyZSBhbnkgbW9yZSBwcmVmaXhlcyBpbiB0aGlzIGNvbnRleHQiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIWRlY2xTZWVuKSB7CisgICAgICAgICAgICBjb3B5VGFibGVzKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRlY2xhcmF0aW9ucyA9PSBudWxsKSB7CisgICAgICAgICAgICBkZWNsYXJhdGlvbnMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgfQorCisgICAgICAgIHByZWZpeCA9IHByZWZpeC5pbnRlcm4oKTsKKyAgICAgICAgdXJpID0gdXJpLmludGVybigpOworICAgICAgICBpZiAoIiIuZXF1YWxzKHByZWZpeCkpIHsKKyAgICAgICAgICAgIGlmICgiIi5lcXVhbHModXJpKSkgeworICAgICAgICAgICAgICAgIGRlZmF1bHROUyA9IG51bGw7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGRlZmF1bHROUyA9IHVyaTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHByZWZpeFRhYmxlLnB1dChwcmVmaXgsIHVyaSk7CisgICAgICAgICAgICB1cmlUYWJsZS5wdXQodXJpLCBwcmVmaXgpOyAvLyBtYXkgd2lwZSBvdXQgYW5vdGhlciBwcmVmaXgKKyAgICAgICAgfQorICAgICAgICBkZWNsYXJhdGlvbnMuYWRkKHByZWZpeCk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzIGFuIFhNTCBxdWFsaWZpZWQgbmFtZSBpbiB0aGlzIGNvbnRleHQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIFhNTCBxdWFsaWZpZWQgbmFtZS4KKyAgICAgKiBAcGFyYW0gaXNBdHRyaWJ1dGUgdHJ1ZSBpZiB0aGlzIGlzIGFuIGF0dHJpYnV0ZSBuYW1lLgorICAgICAqIEByZXR1cm4gQW4gYXJyYXkgb2YgdGhyZWUgc3RyaW5ncyBjb250YWluaW5nIHRoZQorICAgICAqICAgICAgICAgVVJJIHBhcnQgKG9yIGVtcHR5IHN0cmluZyksIHRoZSBsb2NhbCBwYXJ0LAorICAgICAqICAgICAgICAgYW5kIHRoZSByYXcgbmFtZSwgYWxsIGludGVybmFsaXplZCwgb3IgbnVsbAorICAgICAqICAgICAgICAgaWYgdGhlcmUgaXMgYW4gdW5kZWNsYXJlZCBwcmVmaXguCisgICAgICogQHNlZSBvcmcueG1sLnNheC5oZWxwZXJzLk5hbWVzcGFjZVN1cHBvcnQjcHJvY2Vzc05hbWUKKyAgICAgKi8KKyAgICBTdHJpbmcgW10gcHJvY2Vzc05hbWUgKFN0cmluZyBxTmFtZSwgYm9vbGVhbiBpc0F0dHJpYnV0ZSkKKyAgICB7CisgICAgICAgIFN0cmluZyBuYW1lW107CisgICAgICAgIEhhc2h0YWJsZSB0YWJsZTsKKworICAgICAgICAgICAgICAgICAgICAvLyBkZXRlY3QgZXJyb3JzIGluIGNhbGwgc2VxdWVuY2UKKyAgICAgICAgZGVjbHNPSyA9IGZhbHNlOworCisgICAgICAgICAgICAgICAgLy8gU2VsZWN0IHRoZSBhcHByb3ByaWF0ZSB0YWJsZS4KKyAgICAgICAgaWYgKGlzQXR0cmlidXRlKSB7CisgICAgICAgIHRhYmxlID0gYXR0cmlidXRlTmFtZVRhYmxlOworICAgICAgICB9IGVsc2UgeworICAgICAgICB0YWJsZSA9IGVsZW1lbnROYW1lVGFibGU7CisgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIFN0YXJ0IGJ5IGxvb2tpbmcgaW4gdGhlIGNhY2hlLCBhbmQKKyAgICAgICAgICAgICAgICAvLyByZXR1cm4gaW1tZWRpYXRlbHkgaWYgdGhlIG5hbWUKKyAgICAgICAgICAgICAgICAvLyBpcyBhbHJlYWR5IGtub3duIGluIHRoaXMgY29udGVudAorICAgICAgICBuYW1lID0gKFN0cmluZ1tdKXRhYmxlLmdldChxTmFtZSk7CisgICAgICAgIGlmIChuYW1lICE9IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIFdlIGhhdmVuJ3Qgc2VlbiB0aGlzIG5hbWUgaW4gdGhpcworICAgICAgICAgICAgICAgIC8vIGNvbnRleHQgYmVmb3JlLiAgTWF5YmUgaW4gdGhlIHBhcmVudAorICAgICAgICAgICAgICAgIC8vIGNvbnRleHQsIGJ1dCB3ZSBjYW4ndCBhc3N1bWUgcHJlZml4CisgICAgICAgICAgICAgICAgLy8gYmluZGluZ3MgYXJlIHRoZSBzYW1lLgorICAgICAgICBuYW1lID0gbmV3IFN0cmluZ1szXTsKKyAgICAgICAgbmFtZVsyXSA9IHFOYW1lLmludGVybigpOworICAgICAgICBpbnQgaW5kZXggPSBxTmFtZS5pbmRleE9mKCc6Jyk7CisKKworICAgICAgICAgICAgICAgIC8vIE5vIHByZWZpeC4KKyAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7CisgICAgICAgIGlmIChpc0F0dHJpYnV0ZSkgeworICAgICAgICAgICAgaWYgKHFOYW1lID09ICJ4bWxucyIgJiYgbmFtZXNwYWNlRGVjbFVyaXMpCisgICAgICAgICAgICBuYW1lWzBdID0gTlNERUNMOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgbmFtZVswXSA9ICIiOworICAgICAgICB9IGVsc2UgaWYgKGRlZmF1bHROUyA9PSBudWxsKSB7CisgICAgICAgICAgICBuYW1lWzBdID0gIiI7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBuYW1lWzBdID0gZGVmYXVsdE5TOworICAgICAgICB9CisgICAgICAgIG5hbWVbMV0gPSBuYW1lWzJdOworICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBQcmVmaXgKKyAgICAgICAgZWxzZSB7CisgICAgICAgIFN0cmluZyBwcmVmaXggPSBxTmFtZS5zdWJzdHJpbmcoMCwgaW5kZXgpOworICAgICAgICBTdHJpbmcgbG9jYWwgPSBxTmFtZS5zdWJzdHJpbmcoaW5kZXgrMSk7CisgICAgICAgIFN0cmluZyB1cmk7CisgICAgICAgIGlmICgiIi5lcXVhbHMocHJlZml4KSkgeworICAgICAgICAgICAgdXJpID0gZGVmYXVsdE5TOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdXJpID0gKFN0cmluZylwcmVmaXhUYWJsZS5nZXQocHJlZml4KTsKKyAgICAgICAgfQorICAgICAgICBpZiAodXJpID09IG51bGwKKyAgICAgICAgICAgIHx8ICghaXNBdHRyaWJ1dGUgJiYgInhtbG5zIi5lcXVhbHMgKHByZWZpeCkpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBuYW1lWzBdID0gdXJpOworICAgICAgICBuYW1lWzFdID0gbG9jYWwuaW50ZXJuKCk7CisgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIFNhdmUgaW4gdGhlIGNhY2hlIGZvciBmdXR1cmUgdXNlLgorICAgICAgICAgICAgICAgIC8vIChDb3VsZCBiZSBzaGFyZWQgd2l0aCBwYXJlbnQgY29udGV4dC4uLikKKyAgICAgICAgdGFibGUucHV0KG5hbWVbMl0sIG5hbWUpOworICAgICAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIExvb2sgdXAgdGhlIFVSSSBhc3NvY2lhdGVkIHdpdGggYSBwcmVmaXggaW4gdGhpcyBjb250ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRvIGxvb2sgdXAuCisgICAgICogQHJldHVybiBUaGUgYXNzb2NpYXRlZCBOYW1lc3BhY2UgVVJJLCBvciBudWxsIGlmIG5vbmUgaXMKKyAgICAgKiAgICAgICAgIGRlY2xhcmVkLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguaGVscGVycy5OYW1lc3BhY2VTdXBwb3J0I2dldFVSSQorICAgICAqLworICAgIFN0cmluZyBnZXRVUkkgKFN0cmluZyBwcmVmaXgpCisgICAgeworICAgICAgICBpZiAoIiIuZXF1YWxzKHByZWZpeCkpIHsKKyAgICAgICAgcmV0dXJuIGRlZmF1bHROUzsKKyAgICAgICAgfSBlbHNlIGlmIChwcmVmaXhUYWJsZSA9PSBudWxsKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gKFN0cmluZylwcmVmaXhUYWJsZS5nZXQocHJlZml4KTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogTG9vayB1cCBvbmUgb2YgdGhlIHByZWZpeGVzIGFzc29jaWF0ZWQgd2l0aCBhIFVSSSBpbiB0aGlzIGNvbnRleHQuCisgICAgICoKKyAgICAgKiA8cD5TaW5jZSBtYW55IHByZWZpeGVzIG1heSBiZSBtYXBwZWQgdG8gdGhlIHNhbWUgVVJJLAorICAgICAqIHRoZSByZXR1cm4gdmFsdWUgbWF5IGJlIHVucmVsaWFibGUuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHVyaSBUaGUgVVJJIHRvIGxvb2sgdXAuCisgICAgICogQHJldHVybiBUaGUgYXNzb2NpYXRlZCBwcmVmaXgsIG9yIG51bGwgaWYgbm9uZSBpcyBkZWNsYXJlZC4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuTmFtZXNwYWNlU3VwcG9ydCNnZXRQcmVmaXgKKyAgICAgKi8KKyAgICBTdHJpbmcgZ2V0UHJlZml4IChTdHJpbmcgdXJpKQorICAgIHsKKyAgICAgICAgaWYgKHVyaVRhYmxlID09IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiAoU3RyaW5nKXVyaVRhYmxlLmdldCh1cmkpOworICAgICAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYW4gZW51bWVyYXRpb24gb2YgcHJlZml4ZXMgZGVjbGFyZWQgaW4gdGhpcyBjb250ZXh0LgorICAgICAqCisgICAgICogQHJldHVybiBBbiBlbnVtZXJhdGlvbiBvZiBwcmVmaXhlcyAocG9zc2libHkgZW1wdHkpLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguaGVscGVycy5OYW1lc3BhY2VTdXBwb3J0I2dldERlY2xhcmVkUHJlZml4ZXMKKyAgICAgKi8KKyAgICBFbnVtZXJhdGlvbiBnZXREZWNsYXJlZFByZWZpeGVzKCkgeworICAgICAgICByZXR1cm4gKGRlY2xhcmF0aW9ucyA9PSBudWxsKSA/IEVNUFRZX0VOVU1FUkFUSU9OIDogQ29sbGVjdGlvbnMuZW51bWVyYXRpb24oZGVjbGFyYXRpb25zKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybiBhbiBlbnVtZXJhdGlvbiBvZiBhbGwgcHJlZml4ZXMgY3VycmVudGx5IGluIGZvcmNlLgorICAgICAqCisgICAgICogPHA+VGhlIGRlZmF1bHQgcHJlZml4LCBpZiBpbiBmb3JjZSwgaXMgPGVtPm5vdDwvZW0+CisgICAgICogcmV0dXJuZWQsIGFuZCB3aWxsIGhhdmUgdG8gYmUgY2hlY2tlZCBmb3Igc2VwYXJhdGVseS48L3A+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFuIGVudW1lcmF0aW9uIG9mIHByZWZpeGVzIChuZXZlciBlbXB0eSkuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5oZWxwZXJzLk5hbWVzcGFjZVN1cHBvcnQjZ2V0UHJlZml4ZXMKKyAgICAgKi8KKyAgICBFbnVtZXJhdGlvbiBnZXRQcmVmaXhlcyAoKQorICAgIHsKKyAgICAgICAgaWYgKHByZWZpeFRhYmxlID09IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIEVNUFRZX0VOVU1FUkFUSU9OOworICAgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gcHJlZml4VGFibGUua2V5cygpOworICAgICAgICB9CisgICAgfQorCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gSW50ZXJuYWwgbWV0aG9kcy4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworICAgIC8qKgorICAgICAqIENvcHkgb24gd3JpdGUgZm9yIHRoZSBpbnRlcm5hbCB0YWJsZXMgaW4gdGhpcyBjb250ZXh0LgorICAgICAqCisgICAgICogPHA+VGhpcyBjbGFzcyBpcyBvcHRpbWl6ZWQgZm9yIHRoZSBub3JtYWwgY2FzZSB3aGVyZSBtb3N0CisgICAgICogZWxlbWVudHMgZG8gbm90IGNvbnRhaW4gTmFtZXNwYWNlIGRlY2xhcmF0aW9ucy48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNvcHlUYWJsZXMgKCkKKyAgICB7CisgICAgICAgIGlmIChwcmVmaXhUYWJsZSAhPSBudWxsKSB7CisgICAgICAgIHByZWZpeFRhYmxlID0gKEhhc2h0YWJsZSlwcmVmaXhUYWJsZS5jbG9uZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICBwcmVmaXhUYWJsZSA9IG5ldyBIYXNodGFibGUoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodXJpVGFibGUgIT0gbnVsbCkgeworICAgICAgICB1cmlUYWJsZSA9IChIYXNodGFibGUpdXJpVGFibGUuY2xvbmUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgdXJpVGFibGUgPSBuZXcgSGFzaHRhYmxlKCk7CisgICAgICAgIH0KKyAgICAgICAgZWxlbWVudE5hbWVUYWJsZSA9IG5ldyBIYXNodGFibGUoKTsKKyAgICAgICAgYXR0cmlidXRlTmFtZVRhYmxlID0gbmV3IEhhc2h0YWJsZSgpOworICAgICAgICBkZWNsU2VlbiA9IHRydWU7CisgICAgfQorCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gUHJvdGVjdGVkIHN0YXRlLgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworICAgIEhhc2h0YWJsZSBwcmVmaXhUYWJsZTsKKyAgICBIYXNodGFibGUgdXJpVGFibGU7CisgICAgSGFzaHRhYmxlIGVsZW1lbnROYW1lVGFibGU7CisgICAgSGFzaHRhYmxlIGF0dHJpYnV0ZU5hbWVUYWJsZTsKKyAgICBTdHJpbmcgZGVmYXVsdE5TID0gbnVsbDsKKyAgICBib29sZWFuIGRlY2xzT0sgPSB0cnVlOworCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gSW50ZXJuYWwgc3RhdGUuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisgICAgcHJpdmF0ZSBBcnJheUxpc3Q8U3RyaW5nPiBkZWNsYXJhdGlvbnMgPSBudWxsOworICAgIHByaXZhdGUgYm9vbGVhbiBkZWNsU2VlbiA9IGZhbHNlOworICAgIHByaXZhdGUgQ29udGV4dCBwYXJlbnQgPSBudWxsOworICAgIH0KK30KKworLy8gZW5kIG9mIE5hbWVzcGFjZVN1cHBvcnQuamF2YQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2hlbHBlcnMvTmV3SW5zdGFuY2UuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9oZWxwZXJzL05ld0luc3RhbmNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGRmZDg3MAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9oZWxwZXJzL05ld0luc3RhbmNlLmphdmEKQEAgLTAsMCArMSw3OSBAQAorLy8gTmV3SW5zdGFuY2UuamF2YSAtIGNyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiBhIGNsYXNzIGJ5IG5hbWUuCisvLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCisvLyBXcml0dGVuIGJ5IEVkd2luIEdvZWksIGVkd2luZ29AYXBhY2hlLm9yZworLy8gYW5kIGJ5IERhdmlkIEJyb3duZWxsLCBkYnJvd25lbGxAdXNlcnMuc291cmNlZm9yZ2UubmV0CisvLyBOTyBXQVJSQU5UWSEgIFRoaXMgY2xhc3MgaXMgaW4gdGhlIFB1YmxpYyBEb21haW4uCisvLyAkSWQ6IE5ld0luc3RhbmNlLmphdmEsdiAxLjQgMjAwMi8wMS8zMCAyMDo1MjoyNyBkYnJvd25lbGwgRXhwICQKKworcGFja2FnZSBvcmcueG1sLnNheC5oZWxwZXJzOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CisKKy8qKgorICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIGEgY2xhc3MgYnkgbmFtZS4KKyAqCisgKiA8YmxvY2txdW90ZT4KKyAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCisgKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+CisgKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KKyAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgorICogPC9ibG9ja3F1b3RlPgorICoKKyAqIDxwPlRoaXMgY2xhc3MgY29udGFpbnMgYSBzdGF0aWMgbWV0aG9kIGZvciBjcmVhdGluZyBhbiBpbnN0YW5jZSBvZiBhCisgKiBjbGFzcyBmcm9tIGFuIGV4cGxpY2l0IGNsYXNzIG5hbWUuICBJdCB0cmllcyB0byB1c2UgdGhlIHRocmVhZCdzIGNvbnRleHQKKyAqIENsYXNzTG9hZGVyIGlmIHBvc3NpYmxlIGFuZCBmYWxscyBiYWNrIHRvIHVzaW5nCisgKiBDbGFzcy5mb3JOYW1lKFN0cmluZykuPC9wPgorICoKKyAqIDxwPlRoaXMgY29kZSBpcyBkZXNpZ25lZCB0byBjb21waWxlIGFuZCBydW4gb24gSkRLIHZlcnNpb24gMS4xIGFuZCBsYXRlcgorICogaW5jbHVkaW5nIHZlcnNpb25zIG9mIEphdmEgMi48L3A+CisgKgorICogQGF1dGhvciBFZHdpbiBHb2VpLCBEYXZpZCBCcm93bmVsbAorICogQHZlcnNpb24gMi4wLjEgKHNheDJyMikKKyAqLworY2xhc3MgTmV3SW5zdGFuY2UgeworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgc3BlY2lmaWVkIGNsYXNzIG5hbWUKKyAgICAgKgorICAgICAqIFBhY2thZ2UgcHJpdmF0ZSBzbyB0aGlzIGNvZGUgaXMgbm90IGV4cG9zZWQgYXQgdGhlIEFQSSBsZXZlbC4KKyAgICAgKi8KKyAgICBzdGF0aWMgT2JqZWN0IG5ld0luc3RhbmNlIChDbGFzc0xvYWRlciBjbGFzc0xvYWRlciwgU3RyaW5nIGNsYXNzTmFtZSkKKyAgICAgICAgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sCisgICAgICAgICAgICBJbnN0YW50aWF0aW9uRXhjZXB0aW9uCisgICAgeworICAgICAgICBDbGFzcyBkcml2ZXJDbGFzczsKKyAgICAgICAgaWYgKGNsYXNzTG9hZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIGRyaXZlckNsYXNzID0gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZHJpdmVyQ2xhc3MgPSBjbGFzc0xvYWRlci5sb2FkQ2xhc3MoY2xhc3NOYW1lKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZHJpdmVyQ2xhc3MubmV3SW5zdGFuY2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaWd1cmUgb3V0IHdoaWNoIENsYXNzTG9hZGVyIHRvIHVzZS4gIEZvciBKREsgMS4yIGFuZCBsYXRlciB1c2UKKyAgICAgKiB0aGUgY29udGV4dCBDbGFzc0xvYWRlci4KKyAgICAgKi8KKyAgICBzdGF0aWMgQ2xhc3NMb2FkZXIgZ2V0Q2xhc3NMb2FkZXIgKCkKKyAgICB7CisgICAgICAgIE1ldGhvZCBtID0gbnVsbDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbSA9IFRocmVhZC5jbGFzcy5nZXRNZXRob2QoImdldENvbnRleHRDbGFzc0xvYWRlciIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQXNzdW1lIHRoYXQgd2UgYXJlIHJ1bm5pbmcgSkRLIDEuMSwgdXNlIHRoZSBjdXJyZW50IENsYXNzTG9hZGVyCisgICAgICAgICAgICByZXR1cm4gTmV3SW5zdGFuY2UuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gKENsYXNzTG9hZGVyKSBtLmludm9rZShUaHJlYWQuY3VycmVudFRocmVhZCgpKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBhc3NlcnQoZmFsc2UpCisgICAgICAgICAgICB0aHJvdyBuZXcgVW5rbm93bkVycm9yKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBhc3NlcnQoZS5nZXRUYXJnZXRFeGNlcHRpb24oKSBpbnN0YW5jZW9mIFNlY3VyaXR5RXhjZXB0aW9uKQorICAgICAgICAgICAgdGhyb3cgbmV3IFVua25vd25FcnJvcihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvaGVscGVycy9QYXJzZXJBZGFwdGVyLmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvaGVscGVycy9QYXJzZXJBZGFwdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWQxYzY4MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9oZWxwZXJzL1BhcnNlckFkYXB0ZXIuamF2YQpAQCAtMCwwICsxLDEwNDEgQEAKKy8vIFBhcnNlckFkYXB0ZXIuamF2YSAtIGFkYXB0IGEgU0FYMSBQYXJzZXIgdG8gYSBTQVgyIFhNTFJlYWRlci4KKy8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKKy8vIFdyaXR0ZW4gYnkgRGF2aWQgTWVnZ2luc29uCisvLyBOTyBXQVJSQU5UWSEgIFRoaXMgY2xhc3MgaXMgaW4gdGhlIHB1YmxpYyBkb21haW4uCisvLyAkSWQ6IFBhcnNlckFkYXB0ZXIuamF2YSx2IDEuMTYgMjAwNC8wNC8yNiAxNzozNDozNSBkbWVnZ2luc29uIEV4cCAkCisKK3BhY2thZ2Ugb3JnLnhtbC5zYXguaGVscGVyczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdDsKK2ltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOworaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkRUREhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKK2ltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOworaW1wb3J0IG9yZy54bWwuc2F4LlBhcnNlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOworCisKKy8qKgorICogQWRhcHQgYSBTQVgxIFBhcnNlciBhcyBhIFNBWDIgWE1MUmVhZGVyLgorICoKKyAqIDxibG9ja3F1b3RlPgorICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKKyAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KKyAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgorICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+VGhpcyBjbGFzcyB3cmFwcyBhIFNBWDEge0BsaW5rIG9yZy54bWwuc2F4LlBhcnNlciBQYXJzZXJ9CisgKiBhbmQgbWFrZXMgaXQgYWN0IGFzIGEgU0FYMiB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyIFhNTFJlYWRlcn0sCisgKiB3aXRoIGZlYXR1cmUsIHByb3BlcnR5LCBhbmQgTmFtZXNwYWNlIHN1cHBvcnQuICBOb3RlCisgKiB0aGF0IGl0IGlzIG5vdCBwb3NzaWJsZSB0byByZXBvcnQge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3NraXBwZWRFbnRpdHkKKyAqIHNraXBwZWRFbnRpdHl9IGV2ZW50cywgc2luY2UgU0FYMSBkb2VzIG5vdCBtYWtlIHRoYXQgaW5mb3JtYXRpb24gYXZhaWxhYmxlLjwvcD4KKyAqCisgKiA8cD5UaGlzIGFkYXB0ZXIgZG9lcyBub3QgdGVzdCBmb3IgZHVwbGljYXRlIE5hbWVzcGFjZS1xdWFsaWZpZWQKKyAqIGF0dHJpYnV0ZSBuYW1lcy48L3A+CisgKgorICogQHNpbmNlIFNBWCAyLjAKKyAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCisgKiBAdmVyc2lvbiAyLjAuMSAoc2F4MnIyKQorICogQHNlZSBvcmcueG1sLnNheC5oZWxwZXJzLlhNTFJlYWRlckFkYXB0ZXIKKyAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyCisgKiBAc2VlIG9yZy54bWwuc2F4LlBhcnNlcgorICovCitwdWJsaWMgY2xhc3MgUGFyc2VyQWRhcHRlciBpbXBsZW1lbnRzIFhNTFJlYWRlciwgRG9jdW1lbnRIYW5kbGVyCit7CisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIENvbnN0cnVjdG9ycy4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBuZXcgcGFyc2VyIGFkYXB0ZXIuCisgICAgICoKKyAgICAgKiA8cD5Vc2UgdGhlICJvcmcueG1sLnNheC5wYXJzZXIiIHByb3BlcnR5IHRvIGxvY2F0ZSB0aGUKKyAgICAgKiBlbWJlZGRlZCBTQVgxIGRyaXZlci48L3A+CisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBJZiB0aGUgZW1iZWRkZWQgZHJpdmVyCisgICAgICogICAgICAgICAgICBjYW5ub3QgYmUgaW5zdGFudGlhdGVkIG9yIGlmIHRoZQorICAgICAqICAgICAgICAgICAgb3JnLnhtbC5zYXgucGFyc2VyIHByb3BlcnR5IGlzIG5vdCBzcGVjaWZpZWQuCisgICAgICovCisgICAgcHVibGljIFBhcnNlckFkYXB0ZXIgKCkKKyAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisKKyAgICBTdHJpbmcgZHJpdmVyID0gU3lzdGVtLmdldFByb3BlcnR5KCJvcmcueG1sLnNheC5wYXJzZXIiKTsKKworICAgIHRyeSB7CisgICAgICAgIHNldHVwKFBhcnNlckZhY3RvcnkubWFrZVBhcnNlcigpKTsKKyAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUxKSB7CisgICAgICAgIHRocm93IG5ldworICAgICAgICBTQVhFeGNlcHRpb24oIkNhbm5vdCBmaW5kIFNBWDEgZHJpdmVyIGNsYXNzICIgKworICAgICAgICAgICAgICAgICBkcml2ZXIsIGUxKTsKKyAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGUyKSB7CisgICAgICAgIHRocm93IG5ldworICAgICAgICBTQVhFeGNlcHRpb24oIlNBWDEgZHJpdmVyIGNsYXNzICIgKworICAgICAgICAgICAgICAgICBkcml2ZXIgKworICAgICAgICAgICAgICAgICAiIGZvdW5kIGJ1dCBjYW5ub3QgYmUgbG9hZGVkIiwgZTIpOworICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gZTMpIHsKKyAgICAgICAgdGhyb3cgbmV3CisgICAgICAgIFNBWEV4Y2VwdGlvbigiU0FYMSBkcml2ZXIgY2xhc3MgIiArCisgICAgICAgICAgICAgICAgIGRyaXZlciArCisgICAgICAgICAgICAgICAgICIgbG9hZGVkIGJ1dCBjYW5ub3QgYmUgaW5zdGFudGlhdGVkIiwgZTMpOworICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlNCkgeworICAgICAgICB0aHJvdyBuZXcKKyAgICAgICAgU0FYRXhjZXB0aW9uKCJTQVgxIGRyaXZlciBjbGFzcyAiICsKKyAgICAgICAgICAgICAgICAgZHJpdmVyICsKKyAgICAgICAgICAgICAgICAgIiBkb2VzIG5vdCBpbXBsZW1lbnQgb3JnLnhtbC5zYXguUGFyc2VyIik7CisgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZTUpIHsKKyAgICAgICAgdGhyb3cgbmV3CisgICAgICAgIFNBWEV4Y2VwdGlvbigiU3lzdGVtIHByb3BlcnR5IG9yZy54bWwuc2F4LnBhcnNlciBub3Qgc3BlY2lmaWVkIik7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgbmV3IHBhcnNlciBhZGFwdGVyLgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IHRoZSBlbWJlZGRlZCBwYXJzZXIgY2Fubm90IGJlIGNoYW5nZWQgb25jZSB0aGUKKyAgICAgKiBhZGFwdGVyIGlzIGNyZWF0ZWQ7IHRvIGVtYmVkIGEgZGlmZmVyZW50IHBhcnNlciwgYWxsb2NhdGUKKyAgICAgKiBhIG5ldyBQYXJzZXJBZGFwdGVyLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJzZXIgVGhlIFNBWDEgcGFyc2VyIHRvIGVtYmVkLgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIElmIHRoZSBwYXJzZXIgcGFyYW1ldGVyCisgICAgICogICAgICAgICAgICBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBQYXJzZXJBZGFwdGVyIChQYXJzZXIgcGFyc2VyKQorICAgIHsKKyAgICBzZXR1cChwYXJzZXIpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogSW50ZXJuYWwgc2V0dXAgbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcnNlciBUaGUgZW1iZWRkZWQgcGFyc2VyLgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIElmIHRoZSBwYXJzZXIgcGFyYW1ldGVyCisgICAgICogICAgICAgICAgICBpcyBudWxsLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXR1cCAoUGFyc2VyIHBhcnNlcikKKyAgICB7CisgICAgaWYgKHBhcnNlciA9PSBudWxsKSB7CisgICAgICAgIHRocm93IG5ldworICAgICAgICBOdWxsUG9pbnRlckV4Y2VwdGlvbigiUGFyc2VyIGFyZ3VtZW50IG11c3Qgbm90IGJlIG51bGwiKTsKKyAgICB9CisgICAgdGhpcy5wYXJzZXIgPSBwYXJzZXI7CisgICAgYXR0cyA9IG5ldyBBdHRyaWJ1dGVzSW1wbCgpOworICAgIG5zU3VwcG9ydCA9IG5ldyBOYW1lc3BhY2VTdXBwb3J0KCk7CisgICAgYXR0QWRhcHRlciA9IG5ldyBBdHRyaWJ1dGVMaXN0QWRhcHRlcigpOworICAgIH0KKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5YTUxSZWFkZXIuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLy8KKyAgICAvLyBJbnRlcm5hbCBjb25zdGFudHMgZm9yIHRoZSBzYWtlIG9mIGNvbnZlbmllbmNlLgorICAgIC8vCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZFQVRVUkVTID0gImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy8iOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VTID0gRkVBVFVSRVMgKyAibmFtZXNwYWNlcyI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9QUkVGSVhFUyA9IEZFQVRVUkVTICsgIm5hbWVzcGFjZS1wcmVmaXhlcyI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTE5TX1VSSXMgPSBGRUFUVVJFUyArICJ4bWxucy11cmlzIjsKKworCisgICAgLyoqCisgICAgICogU2V0IGEgZmVhdHVyZSBmbGFnIGZvciB0aGUgcGFyc2VyLgorICAgICAqCisgICAgICogPHA+VGhlIG9ubHkgZmVhdHVyZXMgcmVjb2duaXplZCBhcmUgbmFtZXNwYWNlcyBhbmQKKyAgICAgKiBuYW1lc3BhY2UtcHJlZml4ZXMuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIGZlYXR1cmUgbmFtZSwgYXMgYSBjb21wbGV0ZSBVUkkuCisgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXF1ZXN0ZWQgZmVhdHVyZSB2YWx1ZS4KKyAgICAgKiBAZXhjZXB0aW9uIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlIGZlYXR1cmUKKyAgICAgKiAgICAgICAgICAgIGNhbid0IGJlIGFzc2lnbmVkIG9yIHJldHJpZXZlZC4KKyAgICAgKiBAZXhjZXB0aW9uIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBJZiB0aGUgZmVhdHVyZQorICAgICAqICAgICAgICAgICAgY2FuJ3QgYmUgYXNzaWduZWQgdGhhdCB2YWx1ZS4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNzZXRGZWF0dXJlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZSAoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpCisgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgorICAgIHsKKyAgICBpZiAobmFtZS5lcXVhbHMoTkFNRVNQQUNFUykpIHsKKyAgICAgICAgY2hlY2tOb3RQYXJzaW5nKCJmZWF0dXJlIiwgbmFtZSk7CisgICAgICAgIG5hbWVzcGFjZXMgPSB2YWx1ZTsKKyAgICAgICAgaWYgKCFuYW1lc3BhY2VzICYmICFwcmVmaXhlcykgeworICAgICAgICBwcmVmaXhlcyA9IHRydWU7CisgICAgICAgIH0KKyAgICB9IGVsc2UgaWYgKG5hbWUuZXF1YWxzKE5BTUVTUEFDRV9QUkVGSVhFUykpIHsKKyAgICAgICAgY2hlY2tOb3RQYXJzaW5nKCJmZWF0dXJlIiwgbmFtZSk7CisgICAgICAgIHByZWZpeGVzID0gdmFsdWU7CisgICAgICAgIGlmICghcHJlZml4ZXMgJiYgIW5hbWVzcGFjZXMpIHsKKyAgICAgICAgbmFtZXNwYWNlcyA9IHRydWU7CisgICAgICAgIH0KKyAgICB9IGVsc2UgaWYgKG5hbWUuZXF1YWxzKFhNTE5TX1VSSXMpKSB7CisgICAgICAgIGNoZWNrTm90UGFyc2luZygiZmVhdHVyZSIsIG5hbWUpOworICAgICAgICB1cmlzID0gdmFsdWU7CisgICAgfSBlbHNlIHsKKyAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oIkZlYXR1cmU6ICIgKyBuYW1lKTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBDaGVjayBhIHBhcnNlciBmZWF0dXJlIGZsYWcuCisgICAgICoKKyAgICAgKiA8cD5UaGUgb25seSBmZWF0dXJlcyByZWNvZ25pemVkIGFyZSBuYW1lc3BhY2VzIGFuZAorICAgICAqIG5hbWVzcGFjZS1wcmVmaXhlcy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZmVhdHVyZSBuYW1lLCBhcyBhIGNvbXBsZXRlIFVSSS4KKyAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGZlYXR1cmUgdmFsdWUuCisgICAgICogQGV4Y2VwdGlvbiBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBmZWF0dXJlCisgICAgICogICAgICAgICAgICB2YWx1ZSBjYW4ndCBiZSBhc3NpZ25lZCBvciByZXRyaWV2ZWQuCisgICAgICogQGV4Y2VwdGlvbiBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gSWYgdGhlCisgICAgICogICAgICAgICAgICBmZWF0dXJlIGlzIG5vdCBjdXJyZW50bHkgcmVhZGFibGUuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0RmVhdHVyZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUgKFN0cmluZyBuYW1lKQorICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKG5hbWUuZXF1YWxzKE5BTUVTUEFDRVMpKSB7CisgICAgICAgIHJldHVybiBuYW1lc3BhY2VzOworICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHMoTkFNRVNQQUNFX1BSRUZJWEVTKSkgeworICAgICAgICByZXR1cm4gcHJlZml4ZXM7CisgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFscyhYTUxOU19VUklzKSkgeworICAgICAgICByZXR1cm4gdXJpczsKKyAgICB9IGVsc2UgeworICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigiRmVhdHVyZTogIiArIG5hbWUpOworICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFNldCBhIHBhcnNlciBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIDxwPk5vIHByb3BlcnRpZXMgYXJlIGN1cnJlbnRseSByZWNvZ25pemVkLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBwcm9wZXJ0eSBuYW1lLgorICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcHJvcGVydHkgdmFsdWUuCisgICAgICogQGV4Y2VwdGlvbiBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eQorICAgICAqICAgICAgICAgICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgorICAgICAqIEBleGNlcHRpb24gU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eQorICAgICAqICAgICAgICAgICAgY2FuJ3QgYmUgYXNzaWduZWQgdGhhdCB2YWx1ZS4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNzZXRQcm9wZXJ0eQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5IChTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKQorICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KKyAgICB7CisgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oIlByb3BlcnR5OiAiICsgbmFtZSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBHZXQgYSBwYXJzZXIgcHJvcGVydHkuCisgICAgICoKKyAgICAgKiA8cD5ObyBwcm9wZXJ0aWVzIGFyZSBjdXJyZW50bHkgcmVjb2duaXplZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgcHJvcGVydHkgbmFtZS4KKyAgICAgKiBAcmV0dXJuIFRoZSBwcm9wZXJ0eSB2YWx1ZS4KKyAgICAgKiBAZXhjZXB0aW9uIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlIHByb3BlcnR5CisgICAgICogICAgICAgICAgICB2YWx1ZSBjYW4ndCBiZSBhc3NpZ25lZCBvciByZXRyaWV2ZWQuCisgICAgICogQGV4Y2VwdGlvbiBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gSWYgdGhlIHByb3BlcnR5CisgICAgICogICAgICAgICAgICB2YWx1ZSBpcyBub3QgY3VycmVudGx5IHJlYWRhYmxlLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI2dldFByb3BlcnR5CisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eSAoU3RyaW5nIG5hbWUpCisgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgorICAgIHsKKyAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigiUHJvcGVydHk6ICIgKyBuYW1lKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZW50aXR5IHJlc29sdmVyLgorICAgICAqCisgICAgICogQHBhcmFtIHJlc29sdmVyIFRoZSBuZXcgZW50aXR5IHJlc29sdmVyLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI3NldEVudGl0eVJlc29sdmVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIgKEVudGl0eVJlc29sdmVyIHJlc29sdmVyKQorICAgIHsKKyAgICBlbnRpdHlSZXNvbHZlciA9IHJlc29sdmVyOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjdXJyZW50IGVudGl0eSByZXNvbHZlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgZW50aXR5IHJlc29sdmVyLCBvciBudWxsIGlmIG5vbmUgd2FzIHN1cHBsaWVkLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI2dldEVudGl0eVJlc29sdmVyCisgICAgICovCisgICAgcHVibGljIEVudGl0eVJlc29sdmVyIGdldEVudGl0eVJlc29sdmVyICgpCisgICAgeworICAgIHJldHVybiBlbnRpdHlSZXNvbHZlcjsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgRFREIGhhbmRsZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaGFuZGxlciB0aGUgbmV3IERURCBoYW5kbGVyCisgICAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0RW50aXR5UmVzb2x2ZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyIChEVERIYW5kbGVyIGhhbmRsZXIpCisgICAgeworICAgIGR0ZEhhbmRsZXIgPSBoYW5kbGVyOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjdXJyZW50IERURCBoYW5kbGVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY3VycmVudCBEVEQgaGFuZGxlciwgb3IgbnVsbCBpZiBub25lIHdhcyBzdXBwbGllZAorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI2dldEVudGl0eVJlc29sdmVyCisgICAgICovCisgICAgcHVibGljIERUREhhbmRsZXIgZ2V0RFRESGFuZGxlciAoKQorICAgIHsKKyAgICByZXR1cm4gZHRkSGFuZGxlcjsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgY29udGVudCBoYW5kbGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGhhbmRsZXIgdGhlIG5ldyBjb250ZW50IGhhbmRsZXIKKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNzZXRFbnRpdHlSZXNvbHZlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyIChDb250ZW50SGFuZGxlciBoYW5kbGVyKQorICAgIHsKKyAgICBjb250ZW50SGFuZGxlciA9IGhhbmRsZXI7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgY29udGVudCBoYW5kbGVyLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgY3VycmVudCBjb250ZW50IGhhbmRsZXIsIG9yIG51bGwgaWYgbm9uZSB3YXMgc3VwcGxpZWQuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjZ2V0RW50aXR5UmVzb2x2ZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIgKCkKKyAgICB7CisgICAgcmV0dXJuIGNvbnRlbnRIYW5kbGVyOworICAgIH0KKworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBlcnJvciBoYW5kbGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGhhbmRsZXIgVGhlIG5ldyBlcnJvciBoYW5kbGVyLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI3NldEVudGl0eVJlc29sdmVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyIChFcnJvckhhbmRsZXIgaGFuZGxlcikKKyAgICB7CisgICAgZXJyb3JIYW5kbGVyID0gaGFuZGxlcjsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgY3VycmVudCBlcnJvciBoYW5kbGVyLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgY3VycmVudCBlcnJvciBoYW5kbGVyLCBvciBudWxsIGlmIG5vbmUgd2FzIHN1cHBsaWVkLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI2dldEVudGl0eVJlc29sdmVyCisgICAgICovCisgICAgcHVibGljIEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIgKCkKKyAgICB7CisgICAgcmV0dXJuIGVycm9ySGFuZGxlcjsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFBhcnNlIGFuIFhNTCBkb2N1bWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgYWJzb2x1dGUgVVJMIG9mIHRoZSBkb2N1bWVudC4KKyAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24gSWYgdGhlcmUgaXMgYSBwcm9ibGVtIHJlYWRpbmcKKyAgICAgKiAgICAgICAgICAgIHRoZSByYXcgY29udGVudCBvZiB0aGUgZG9jdW1lbnQuCisgICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gSWYgdGhlcmUgaXMgYSBwcm9ibGVtCisgICAgICogICAgICAgICAgICBwcm9jZXNzaW5nIHRoZSBkb2N1bWVudC4KKyAgICAgKiBAc2VlICNwYXJzZShvcmcueG1sLnNheC5JbnB1dFNvdXJjZSkKKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlBhcnNlciNwYXJzZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHBhcnNlIChTdHJpbmcgc3lzdGVtSWQpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgcGFyc2UobmV3IElucHV0U291cmNlKHN5c3RlbUlkKSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhbiBYTUwgZG9jdW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQgQW4gaW5wdXQgc291cmNlIGZvciB0aGUgZG9jdW1lbnQuCisgICAgICogQGV4Y2VwdGlvbiBqYXZhLmlvLklPRXhjZXB0aW9uIElmIHRoZXJlIGlzIGEgcHJvYmxlbSByZWFkaW5nCisgICAgICogICAgICAgICAgICB0aGUgcmF3IGNvbnRlbnQgb2YgdGhlIGRvY3VtZW50LgorICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIElmIHRoZXJlIGlzIGEgcHJvYmxlbQorICAgICAqICAgICAgICAgICAgcHJvY2Vzc2luZyB0aGUgZG9jdW1lbnQuCisgICAgICogQHNlZSAjcGFyc2UoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlBhcnNlciNwYXJzZShvcmcueG1sLnNheC5JbnB1dFNvdXJjZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwYXJzZSAoSW5wdXRTb3VyY2UgaW5wdXQpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKHBhcnNpbmcpIHsKKyAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbigiUGFyc2VyIGlzIGFscmVhZHkgaW4gdXNlIik7CisgICAgfQorICAgIHNldHVwUGFyc2VyKCk7CisgICAgcGFyc2luZyA9IHRydWU7CisgICAgdHJ5IHsKKyAgICAgICAgcGFyc2VyLnBhcnNlKGlucHV0KTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgICBwYXJzaW5nID0gZmFsc2U7CisgICAgfQorICAgIHBhcnNpbmcgPSBmYWxzZTsKKyAgICB9CisKKworCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoqCisgICAgICogQWRhcHRlciBpbXBsZW1lbnRhdGlvbiBtZXRob2Q7IGRvIG5vdCBjYWxsLgorICAgICAqIEFkYXB0IGEgU0FYMSBkb2N1bWVudCBsb2NhdG9yIGV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2F0b3IgQSBkb2N1bWVudCBsb2NhdG9yLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2V0RG9jdW1lbnRMb2NhdG9yCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yIChMb2NhdG9yIGxvY2F0b3IpCisgICAgeworICAgIHRoaXMubG9jYXRvciA9IGxvY2F0b3I7CisgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgY29udGVudEhhbmRsZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGxvY2F0b3IpOworICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEFkYXB0ZXIgaW1wbGVtZW50YXRpb24gbWV0aG9kOyBkbyBub3QgY2FsbC4KKyAgICAgKiBBZGFwdCBhIFNBWDEgc3RhcnQgZG9jdW1lbnQgZXZlbnQuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSByYWlzZSBhCisgICAgICogICAgICAgICAgICBwcm9jZXNzaW5nIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciNzdGFydERvY3VtZW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCAoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgY29udGVudEhhbmRsZXIuc3RhcnREb2N1bWVudCgpOworICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEFkYXB0ZXIgaW1wbGVtZW50YXRpb24gbWV0aG9kOyBkbyBub3QgY2FsbC4KKyAgICAgKiBBZGFwdCBhIFNBWDEgZW5kIGRvY3VtZW50IGV2ZW50LgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgcmFpc2UgYQorICAgICAqICAgICAgICAgICAgcHJvY2Vzc2luZyBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjZW5kRG9jdW1lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCAoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgY29udGVudEhhbmRsZXIuZW5kRG9jdW1lbnQoKTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBBZGFwdGVyIGltcGxlbWVudGF0aW9uIG1ldGhvZDsgZG8gbm90IGNhbGwuCisgICAgICogQWRhcHQgYSBTQVgxIHN0YXJ0RWxlbWVudCBldmVudC4KKyAgICAgKgorICAgICAqIDxwPklmIG5lY2Vzc2FyeSwgcGVyZm9ybSBOYW1lc3BhY2UgcHJvY2Vzc2luZy48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCisgICAgICogQHBhcmFtIHFBdHRzIFRoZSBYTUwgYXR0cmlidXRlIGxpc3QgKHdpdGggcW5hbWVzKS4KKyAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSByYWlzZSBhCisgICAgICogICAgICAgICAgICBwcm9jZXNzaW5nIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQgKFN0cmluZyBxTmFtZSwgQXR0cmlidXRlTGlzdCBxQXR0cykgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRoZXNlIGFyZSBleGNlcHRpb25zIGZyb20gdGhlCisgICAgICAgIC8vIGZpcnN0IHBhc3M7IHRoZXkgc2hvdWxkIGJlCisgICAgICAgIC8vIGlnbm9yZWQgaWYgdGhlcmUncyBhIHNlY29uZCBwYXNzLAorICAgICAgICAvLyBidXQgcmVwb3J0ZWQgb3RoZXJ3aXNlLgorICAgICAgICBBcnJheUxpc3Q8U0FYUGFyc2VFeGNlcHRpb24+IGV4Y2VwdGlvbnMgPSBudWxsOworCisgICAgICAgICAgICAgICAgLy8gSWYgd2UncmUgbm90IGRvaW5nIE5hbWVzcGFjZQorICAgICAgICAgICAgICAgIC8vIHByb2Nlc3NpbmcsIGRpc3BhdGNoIHRoaXMgcXVpY2tseS4KKyAgICBpZiAoIW5hbWVzcGFjZXMpIHsKKyAgICAgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgYXR0QWRhcHRlci5zZXRBdHRyaWJ1dGVMaXN0KHFBdHRzKTsKKyAgICAgICAgY29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KCIiLCAiIiwgcU5hbWUuaW50ZXJuKCksCisgICAgICAgICAgICAgICAgICAgICAgICBhdHRBZGFwdGVyKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm47CisgICAgfQorCisKKyAgICAgICAgICAgICAgICAvLyBPSywgd2UncmUgZG9pbmcgTmFtZXNwYWNlIHByb2Nlc3NpbmcuCisgICAgbnNTdXBwb3J0LnB1c2hDb250ZXh0KCk7CisgICAgaW50IGxlbmd0aCA9IHFBdHRzLmdldExlbmd0aCgpOworCisgICAgICAgICAgICAgICAgLy8gRmlyc3QgcGFzczogIGhhbmRsZSBOUyBkZWNscworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgU3RyaW5nIGF0dFFOYW1lID0gcUF0dHMuZ2V0TmFtZShpKTsKKworICAgICAgICBpZiAoIWF0dFFOYW1lLnN0YXJ0c1dpdGgoInhtbG5zIikpCisgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIC8vIENvdWxkIGJlIGEgZGVjbGFyYXRpb24uLi4KKyAgICAgICAgU3RyaW5nIHByZWZpeDsKKyAgICAgICAgaW50IG4gPSBhdHRRTmFtZS5pbmRleE9mKCc6Jyk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8geG1sbnM9Li4uCisgICAgICAgIGlmIChuID09IC0xICYmIGF0dFFOYW1lLmxlbmd0aCAoKSA9PSA1KSB7CisgICAgICAgIHByZWZpeCA9ICIiOworICAgICAgICB9IGVsc2UgaWYgKG4gIT0gNSkgeworICAgICAgICAvLyBYTUwgbmFtZXNwYWNlcyBzcGVjIGRvZXNuJ3QgZGlzY3VzcyAieG1sbnNmOm9vIgorICAgICAgICAvLyAoYW5kIHNpbWlsYXJseSBuYW1lZCkgYXR0cmlidXRlcyAuLi4gYXQgbW9zdCwgd2FybgorICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfSBlbHNlICAgICAgICAgLy8geG1sbnM6Zm9vPS4uLgorICAgICAgICBwcmVmaXggPSBhdHRRTmFtZS5zdWJzdHJpbmcobisxKTsKKworICAgICAgICBTdHJpbmcgdmFsdWUgPSBxQXR0cy5nZXRWYWx1ZShpKTsKKyAgICAgICAgaWYgKCFuc1N1cHBvcnQuZGVjbGFyZVByZWZpeChwcmVmaXgsIHZhbHVlKSkgeworICAgICAgICByZXBvcnRFcnJvcigiSWxsZWdhbCBOYW1lc3BhY2UgcHJlZml4OiAiICsgcHJlZml4KTsKKyAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpCisgICAgICAgIGNvbnRlbnRIYW5kbGVyLnN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsIHZhbHVlKTsKKyAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBTZWNvbmQgcGFzczogY29weSBhbGwgcmVsZXZhbnQKKyAgICAgICAgICAgICAgICAvLyBhdHRyaWJ1dGVzIGludG8gdGhlIFNBWDIgQXR0cmlidXRlTGlzdAorICAgICAgICAgICAgICAgIC8vIHVzaW5nIHVwZGF0ZWQgcHJlZml4IGJpbmRpbmdzCisgICAgYXR0cy5jbGVhcigpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgU3RyaW5nIGF0dFFOYW1lID0gcUF0dHMuZ2V0TmFtZShpKTsKKyAgICAgICAgU3RyaW5nIHR5cGUgPSBxQXR0cy5nZXRUeXBlKGkpOworICAgICAgICBTdHJpbmcgdmFsdWUgPSBxQXR0cy5nZXRWYWx1ZShpKTsKKworICAgICAgICAgICAgICAgIC8vIERlY2xhcmF0aW9uPworICAgICAgICBpZiAoYXR0UU5hbWUuc3RhcnRzV2l0aCgieG1sbnMiKSkgeworICAgICAgICBTdHJpbmcgcHJlZml4OworICAgICAgICBpbnQgbiA9IGF0dFFOYW1lLmluZGV4T2YoJzonKTsKKworICAgICAgICBpZiAobiA9PSAtMSAmJiBhdHRRTmFtZS5sZW5ndGggKCkgPT0gNSkgeworICAgICAgICAgICAgcHJlZml4ID0gIiI7CisgICAgICAgIH0gZWxzZSBpZiAobiAhPSA1KSB7CisgICAgICAgICAgICAvLyBYTUwgbmFtZXNwYWNlcyBzcGVjIGRvZXNuJ3QgZGlzY3VzcyAieG1sbnNmOm9vIgorICAgICAgICAgICAgLy8gKGFuZCBzaW1pbGFybHkgbmFtZWQpIGF0dHJpYnV0ZXMgLi4uIGlnbm9yZQorICAgICAgICAgICAgcHJlZml4ID0gbnVsbDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHByZWZpeCA9IGF0dFFOYW1lLnN1YnN0cmluZyg2KTsKKyAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIFllcywgZGVjbDogIHJlcG9ydCBvciBwcnVuZQorICAgICAgICBpZiAocHJlZml4ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChwcmVmaXhlcykgeworICAgICAgICAgICAgaWYgKHVyaXMpCisgICAgICAgICAgICAgICAgLy8gbm90ZSBmdW5reSBjYXNlOiAgbG9jYWxuYW1lIGNhbiBiZSBudWxsCisgICAgICAgICAgICAgICAgLy8gd2hlbiBkZWNsYXJpbmcgdGhlIGRlZmF1bHQgcHJlZml4LCBhbmQKKyAgICAgICAgICAgICAgICAvLyB5ZXQgdGhlIHVyaSBpc24ndCBudWxsLgorICAgICAgICAgICAgICAgIGF0dHMuYWRkQXR0cmlidXRlIChuc1N1cHBvcnQuWE1MTlMsIHByZWZpeCwKKyAgICAgICAgICAgICAgICAgICAgYXR0UU5hbWUuaW50ZXJuKCksIHR5cGUsIHZhbHVlKTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBhdHRzLmFkZEF0dHJpYnV0ZSAoIiIsICIiLAorICAgICAgICAgICAgICAgICAgICBhdHRRTmFtZS5pbnRlcm4oKSwgdHlwZSwgdmFsdWUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gTm90IGEgZGVjbGFyYXRpb24gLS0gcmVwb3J0CisgICAgICAgIHRyeSB7CisgICAgICAgIFN0cmluZyBhdHROYW1lW10gPSBwcm9jZXNzTmFtZShhdHRRTmFtZSwgdHJ1ZSwgdHJ1ZSk7CisgICAgICAgIGF0dHMuYWRkQXR0cmlidXRlKGF0dE5hbWVbMF0sIGF0dE5hbWVbMV0sIGF0dE5hbWVbMl0sCisgICAgICAgICAgICAgICAgICB0eXBlLCB2YWx1ZSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAoZXhjZXB0aW9ucyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9ucyA9IG5ldyBBcnJheUxpc3Q8U0FYUGFyc2VFeGNlcHRpb24+KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBleGNlcHRpb25zLmFkZCgoU0FYUGFyc2VFeGNlcHRpb24pIGUpOworICAgICAgICAgICAgYXR0cy5hZGRBdHRyaWJ1dGUoIiIsIGF0dFFOYW1lLCBhdHRRTmFtZSwgdHlwZSwgdmFsdWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gbm93IGhhbmRsZSB0aGUgZGVmZXJyZWQgZXhjZXB0aW9uIHJlcG9ydHMKKyAgICBpZiAoZXhjZXB0aW9ucyAhPSBudWxsICYmIGVycm9ySGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgIGZvciAoU0FYUGFyc2VFeGNlcHRpb24gZXggOiBleGNlcHRpb25zKSB7CisgICAgICAgICAgICBlcnJvckhhbmRsZXIuZXJyb3IoZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgICAgICAgICAgICAgLy8gT0ssIGZpbmFsbHkgcmVwb3J0IHRoZSBldmVudC4KKyAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICBTdHJpbmcgbmFtZVtdID0gcHJvY2Vzc05hbWUocU5hbWUsIGZhbHNlLCBmYWxzZSk7CisgICAgICAgIGNvbnRlbnRIYW5kbGVyLnN0YXJ0RWxlbWVudChuYW1lWzBdLCBuYW1lWzFdLCBuYW1lWzJdLCBhdHRzKTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBBZGFwdGVyIGltcGxlbWVudGF0aW9uIG1ldGhvZDsgZG8gbm90IGNhbGwuCisgICAgICogQWRhcHQgYSBTQVgxIGVuZCBlbGVtZW50IGV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLgorICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHJhaXNlIGEKKyAgICAgKiAgICAgICAgICAgIHByb2Nlc3NpbmcgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyI2VuZEVsZW1lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50IChTdHJpbmcgcU5hbWUpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgICAgICAgICAvLyBJZiB3ZSdyZSBub3QgZG9pbmcgTmFtZXNwYWNlCisgICAgICAgICAgICAgICAgLy8gcHJvY2Vzc2luZywgZGlzcGF0Y2ggdGhpcyBxdWlja2x5LgorICAgIGlmICghbmFtZXNwYWNlcykgeworICAgICAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICBjb250ZW50SGFuZGxlci5lbmRFbGVtZW50KCIiLCAiIiwgcU5hbWUuaW50ZXJuKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBTcGxpdCB0aGUgbmFtZS4KKyAgICBTdHJpbmcgbmFtZXNbXSA9IHByb2Nlc3NOYW1lKHFOYW1lLCBmYWxzZSwgZmFsc2UpOworICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgIGNvbnRlbnRIYW5kbGVyLmVuZEVsZW1lbnQobmFtZXNbMF0sIG5hbWVzWzFdLCBuYW1lc1syXSk7CisgICAgICAgIEVudW1lcmF0aW9uIHByZWZpeGVzID0gbnNTdXBwb3J0LmdldERlY2xhcmVkUHJlZml4ZXMoKTsKKyAgICAgICAgd2hpbGUgKHByZWZpeGVzLmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgIFN0cmluZyBwcmVmaXggPSAoU3RyaW5nKXByZWZpeGVzLm5leHRFbGVtZW50KCk7CisgICAgICAgIGNvbnRlbnRIYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKKyAgICAgICAgfQorICAgIH0KKyAgICBuc1N1cHBvcnQucG9wQ29udGV4dCgpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQWRhcHRlciBpbXBsZW1lbnRhdGlvbiBtZXRob2Q7IGRvIG5vdCBjYWxsLgorICAgICAqIEFkYXB0IGEgU0FYMSBjaGFyYWN0ZXJzIGV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGNoIEFuIGFycmF5IG9mIGNoYXJhY3RlcnMuCisgICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCisgICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlLgorICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHJhaXNlIGEKKyAgICAgKiAgICAgICAgICAgIHByb2Nlc3NpbmcgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyI2NoYXJhY3RlcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgIGNvbnRlbnRIYW5kbGVyLmNoYXJhY3RlcnMoY2gsIHN0YXJ0LCBsZW5ndGgpOworICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEFkYXB0ZXIgaW1wbGVtZW50YXRpb24gbWV0aG9kOyBkbyBub3QgY2FsbC4KKyAgICAgKiBBZGFwdCBhIFNBWDEgaWdub3JhYmxlIHdoaXRlc3BhY2UgZXZlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2ggQW4gYXJyYXkgb2YgY2hhcmFjdGVycy4KKyAgICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0aW5nIHBvc2l0aW9uIGluIHRoZSBhcnJheS4KKyAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB1c2UuCisgICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgcmFpc2UgYQorICAgICAqICAgICAgICAgICAgcHJvY2Vzc2luZyBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjaWdub3JhYmxlV2hpdGVzcGFjZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UgKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgY29udGVudEhhbmRsZXIuaWdub3JhYmxlV2hpdGVzcGFjZShjaCwgc3RhcnQsIGxlbmd0aCk7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogQWRhcHRlciBpbXBsZW1lbnRhdGlvbiBtZXRob2Q7IGRvIG5vdCBjYWxsLgorICAgICAqIEFkYXB0IGEgU0FYMSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHRhcmdldCBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0YXJnZXQuCisgICAgICogQHBhcmFtIGRhdGEgVGhlIHJlbWFpbmRlciBvZiB0aGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbgorICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHJhaXNlIGEKKyAgICAgKiAgICAgICAgICAgIHByb2Nlc3NpbmcgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyI3Byb2Nlc3NpbmdJbnN0cnVjdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbiAoU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICBjb250ZW50SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhKTsKKyAgICB9CisgICAgfQorCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIEludGVybmFsIHV0aWxpdHkgbWV0aG9kcy4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplIHRoZSBwYXJzZXIgYmVmb3JlIGVhY2ggcnVuLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXR1cFBhcnNlciAoKQorICAgIHsKKyAgICAvLyBjYXRjaCBhbiBpbGxlZ2FsICJub25zZW5zZSIgc3RhdGUuCisgICAgaWYgKCFwcmVmaXhlcyAmJiAhbmFtZXNwYWNlcykKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiAoKTsKKworICAgIG5zU3VwcG9ydC5yZXNldCgpOworICAgIGlmICh1cmlzKQorICAgICAgICBuc1N1cHBvcnQuc2V0TmFtZXNwYWNlRGVjbFVyaXMgKHRydWUpOworCisgICAgaWYgKGVudGl0eVJlc29sdmVyICE9IG51bGwpIHsKKyAgICAgICAgcGFyc2VyLnNldEVudGl0eVJlc29sdmVyKGVudGl0eVJlc29sdmVyKTsKKyAgICB9CisgICAgaWYgKGR0ZEhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICBwYXJzZXIuc2V0RFRESGFuZGxlcihkdGRIYW5kbGVyKTsKKyAgICB9CisgICAgaWYgKGVycm9ySGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgIHBhcnNlci5zZXRFcnJvckhhbmRsZXIoZXJyb3JIYW5kbGVyKTsKKyAgICB9CisgICAgcGFyc2VyLnNldERvY3VtZW50SGFuZGxlcih0aGlzKTsKKyAgICBsb2NhdG9yID0gbnVsbDsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFByb2Nlc3MgYSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLgorICAgICAqCisgICAgICogPHA+SWYgdGhlIG5hbWUgaGFzIGFuIHVuZGVjbGFyZWQgcHJlZml4LCB1c2Ugb25seSB0aGUgcW5hbWUKKyAgICAgKiBhbmQgbWFrZSBhbiBFcnJvckhhbmRsZXIuZXJyb3IgY2FsbGJhY2sgaW4gY2FzZSB0aGUgYXBwIGlzCisgICAgICogaW50ZXJlc3RlZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCisgICAgICogQHBhcmFtIGlzQXR0cmlidXRlIHRydWUgaWYgdGhpcyBpcyBhbiBhdHRyaWJ1dGUgbmFtZS4KKyAgICAgKiBAcmV0dXJuIFRoZSBuYW1lIHNwbGl0IGludG8gdGhyZWUgcGFydHMuCisgICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKKyAgICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhbiBlcnJvciBjYWxsYmFjay4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBbXSBwcm9jZXNzTmFtZSAoU3RyaW5nIHFOYW1lLCBib29sZWFuIGlzQXR0cmlidXRlLAorICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gdXNlRXhjZXB0aW9uKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgU3RyaW5nIHBhcnRzW10gPSBuc1N1cHBvcnQucHJvY2Vzc05hbWUocU5hbWUsIG5hbWVQYXJ0cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzQXR0cmlidXRlKTsKKyAgICBpZiAocGFydHMgPT0gbnVsbCkgeworICAgICAgICBpZiAodXNlRXhjZXB0aW9uKQorICAgICAgICB0aHJvdyBtYWtlRXhjZXB0aW9uKCJVbmRlY2xhcmVkIHByZWZpeDogIiArIHFOYW1lKTsKKyAgICAgICAgcmVwb3J0RXJyb3IoIlVuZGVjbGFyZWQgcHJlZml4OiAiICsgcU5hbWUpOworICAgICAgICBwYXJ0cyA9IG5ldyBTdHJpbmdbM107CisgICAgICAgIHBhcnRzWzBdID0gcGFydHNbMV0gPSAiIjsKKyAgICAgICAgcGFydHNbMl0gPSBxTmFtZS5pbnRlcm4oKTsKKyAgICB9CisgICAgcmV0dXJuIHBhcnRzOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmVwb3J0IGEgbm9uLWZhdGFsIGVycm9yLgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG1lc3NhZ2UuCisgICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKKyAgICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICB2b2lkIHJlcG9ydEVycm9yIChTdHJpbmcgbWVzc2FnZSkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIGlmIChlcnJvckhhbmRsZXIgIT0gbnVsbCkKKyAgICAgICAgZXJyb3JIYW5kbGVyLmVycm9yKG1ha2VFeGNlcHRpb24obWVzc2FnZSkpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGFuIGV4Y2VwdGlvbiBmb3IgdGhlIGN1cnJlbnQgY29udGV4dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBtZXNzYWdlLgorICAgICAqLworICAgIHByaXZhdGUgU0FYUGFyc2VFeGNlcHRpb24gbWFrZUV4Y2VwdGlvbiAoU3RyaW5nIG1lc3NhZ2UpCisgICAgeworICAgIGlmIChsb2NhdG9yICE9IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTQVhQYXJzZUV4Y2VwdGlvbihtZXNzYWdlLCBsb2NhdG9yKTsKKyAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gbmV3IFNBWFBhcnNlRXhjZXB0aW9uKG1lc3NhZ2UsIG51bGwsIG51bGwsIC0xLCAtMSk7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogVGhyb3cgYW4gZXhjZXB0aW9uIGlmIHdlIGFyZSBwYXJzaW5nLgorICAgICAqCisgICAgICogPHA+VXNlIHRoaXMgbWV0aG9kIHRvIGRldGVjdCBpbGxlZ2FsIGZlYXR1cmUgb3IKKyAgICAgKiBwcm9wZXJ0eSBjaGFuZ2VzLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlIFRoZSB0eXBlIG9mIHRoaW5nIChmZWF0dXJlIG9yIHByb3BlcnR5KS4KKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZmVhdHVyZSBvciBwcm9wZXJ0eSBuYW1lLgorICAgICAqIEBleGNlcHRpb24gU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIElmIGEKKyAgICAgKiAgICAgICAgICAgIGRvY3VtZW50IGlzIGN1cnJlbnRseSBiZWluZyBwYXJzZWQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrTm90UGFyc2luZyAoU3RyaW5nIHR5cGUsIFN0cmluZyBuYW1lKQorICAgIHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKHBhcnNpbmcpIHsKKyAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiQ2Fubm90IGNoYW5nZSAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgKyAnICcgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSArICIgd2hpbGUgcGFyc2luZyIpOworCisgICAgfQorICAgIH0KKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBJbnRlcm5hbCBzdGF0ZS4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisgICAgcHJpdmF0ZSBOYW1lc3BhY2VTdXBwb3J0IG5zU3VwcG9ydDsKKyAgICBwcml2YXRlIEF0dHJpYnV0ZUxpc3RBZGFwdGVyIGF0dEFkYXB0ZXI7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gcGFyc2luZyA9IGZhbHNlOworICAgIHByaXZhdGUgU3RyaW5nIG5hbWVQYXJ0c1tdID0gbmV3IFN0cmluZ1szXTsKKworICAgIHByaXZhdGUgUGFyc2VyIHBhcnNlciA9IG51bGw7CisKKyAgICBwcml2YXRlIEF0dHJpYnV0ZXNJbXBsIGF0dHMgPSBudWxsOworCisgICAgICAgICAgICAgICAgLy8gRmVhdHVyZXMKKyAgICBwcml2YXRlIGJvb2xlYW4gbmFtZXNwYWNlcyA9IHRydWU7CisgICAgcHJpdmF0ZSBib29sZWFuIHByZWZpeGVzID0gZmFsc2U7CisgICAgcHJpdmF0ZSBib29sZWFuIHVyaXMgPSBmYWxzZTsKKworICAgICAgICAgICAgICAgIC8vIFByb3BlcnRpZXMKKworICAgICAgICAgICAgICAgIC8vIEhhbmRsZXJzCisgICAgTG9jYXRvciBsb2NhdG9yOworCisgICAgRW50aXR5UmVzb2x2ZXIgZW50aXR5UmVzb2x2ZXIgPSBudWxsOworICAgIERUREhhbmRsZXIgZHRkSGFuZGxlciA9IG51bGw7CisgICAgQ29udGVudEhhbmRsZXIgY29udGVudEhhbmRsZXIgPSBudWxsOworICAgIEVycm9ySGFuZGxlciBlcnJvckhhbmRsZXIgPSBudWxsOworCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIElubmVyIGNsYXNzIHRvIHdyYXAgYW4gQXR0cmlidXRlTGlzdCB3aGVuIG5vdCBkb2luZyBOUyBwcm9jLgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworICAgIC8qKgorICAgICAqIEFkYXB0IGEgU0FYMSBBdHRyaWJ1dGVMaXN0IGFzIGEgU0FYMiBBdHRyaWJ1dGVzIG9iamVjdC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgY2xhc3MgaXMgaW4gdGhlIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIE5PCisgICAgICogV0FSUkFOVFkgb2YgYW55IGtpbmQuPC9wPgorICAgICAqCisgICAgICogPHA+VGhpcyB3cmFwcGVyIGNsYXNzIGlzIHVzZWQgb25seSB3aGVuIE5hbWVzcGFjZSBzdXBwb3J0CisgICAgICogaXMgZGlzYWJsZWQgLS0gaXQgcHJvdmlkZXMgcHJldHR5IG11Y2ggYSBkaXJlY3QgbWFwcGluZworICAgICAqIGZyb20gU0FYMSB0byBTQVgyLCBleGNlcHQgdGhhdCBuYW1lcyBhbmQgdHlwZXMgYXJlCisgICAgICogaW50ZXJuZWQgd2hlbmV2ZXIgcmVxdWVzdGVkLjwvcD4KKyAgICAgKi8KKyAgICBmaW5hbCBjbGFzcyBBdHRyaWJ1dGVMaXN0QWRhcHRlciBpbXBsZW1lbnRzIEF0dHJpYnV0ZXMKKyAgICB7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBuZXcgYWRhcHRlci4KKyAgICAgKi8KKyAgICBBdHRyaWJ1dGVMaXN0QWRhcHRlciAoKQorICAgIHsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZW1iZWRkZWQgQXR0cmlidXRlTGlzdC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIG11c3QgYmUgaW52b2tlZCBiZWZvcmUgYW55IG9mIHRoZSBvdGhlcnMKKyAgICAgKiBjYW4gYmUgdXNlZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gVGhlIFNBWDEgYXR0cmlidXRlIGxpc3QgKHdpdGggcW5hbWVzKS4KKyAgICAgKi8KKyAgICB2b2lkIHNldEF0dHJpYnV0ZUxpc3QgKEF0dHJpYnV0ZUxpc3QgcUF0dHMpCisgICAgeworICAgICAgICB0aGlzLnFBdHRzID0gcUF0dHM7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgYXR0cmlidXRlIGxpc3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgYXR0cmlidXRlcyBpbiB0aGUgbGlzdC4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMjZ2V0TGVuZ3RoCisgICAgICovCisgICAgcHVibGljIGludCBnZXRMZW5ndGggKCkKKyAgICB7CisgICAgICAgIHJldHVybiBxQXR0cy5nZXRMZW5ndGgoKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgTmFtZXNwYWNlIFVSSSBvZiB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBUaGUgYXR0cmlidXRlJ3MgaW5kZXguCisgICAgICogQHJldHVybiBBbHdheXMgdGhlIGVtcHR5IHN0cmluZy4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMjZ2V0VVJJCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRVUkkgKGludCBpKQorICAgIHsKKyAgICAgICAgcmV0dXJuICIiOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBsb2NhbCBuYW1lIG9mIHRoZSBzcGVjaWZpZWQgYXR0cmlidXRlLgorICAgICAqCisgICAgICogQHBhcmFtIFRoZSBhdHRyaWJ1dGUncyBpbmRleC4KKyAgICAgKiBAcmV0dXJuIEFsd2F5cyB0aGUgZW1wdHkgc3RyaW5nLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRMb2NhbE5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZSAoaW50IGkpCisgICAgeworICAgICAgICByZXR1cm4gIiI7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUgb2YgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gVGhlIGF0dHJpYnV0ZSdzIGluZGV4LgorICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIHF1YWxpZmllZCBuYW1lLCBpbnRlcm5hbGl6ZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRRTmFtZSAoaW50IGkpCisgICAgeworICAgICAgICByZXR1cm4gcUF0dHMuZ2V0TmFtZShpKS5pbnRlcm4oKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdHlwZSBvZiB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBUaGUgYXR0cmlidXRlJ3MgaW5kZXguCisgICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlJ3MgdHlwZSBhcyBhbiBpbnRlcm5hbGl6ZWQgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSAoaW50IGkpCisgICAgeworICAgICAgICByZXR1cm4gcUF0dHMuZ2V0VHlwZShpKS5pbnRlcm4oKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gVGhlIGF0dHJpYnV0ZSdzIGluZGV4LgorICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUgKGludCBpKQorICAgIHsKKyAgICAgICAgcmV0dXJuIHFBdHRzLmdldFZhbHVlKGkpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUgaW5kZXggYnkgTmFtZXNwYWNlIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJIG9yIHRoZSBlbXB0eSBzdHJpbmcuCisgICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZS4KKyAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGVzIGluZGV4LCBvciAtMSBpZiBub25lIHdhcyBmb3VuZC4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMjZ2V0SW5kZXgoamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXggKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpCisgICAgeworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSBpbmRleCBieSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZS4KKyAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGVzIGluZGV4LCBvciAtMSBpZiBub25lIHdhcyBmb3VuZC4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMjZ2V0SW5kZXgoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEluZGV4IChTdHJpbmcgcU5hbWUpCisgICAgeworICAgICAgICBpbnQgbWF4ID0gYXR0cy5nZXRMZW5ndGgoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXg7IGkrKykgeworICAgICAgICBpZiAocUF0dHMuZ2V0TmFtZShpKS5lcXVhbHMocU5hbWUpKSB7CisgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIExvb2sgdXAgdGhlIHR5cGUgb2YgYW4gYXR0cmlidXRlIGJ5IE5hbWVzcGFjZSBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSQorICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUuCisgICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlJ3MgdHlwZSBhcyBhbiBpbnRlcm5hbGl6ZWQgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkKKyAgICB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworCisgICAgLyoqCisgICAgICogTG9vayB1cCB0aGUgdHlwZSBvZiBhbiBhdHRyaWJ1dGUgYnkgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUuCisgICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlJ3MgdHlwZSBhcyBhbiBpbnRlcm5hbGl6ZWQgc3RyaW5nLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSAoU3RyaW5nIHFOYW1lKQorICAgIHsKKyAgICAgICAgcmV0dXJuIHFBdHRzLmdldFR5cGUocU5hbWUpLmludGVybigpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogTG9vayB1cCB0aGUgdmFsdWUgb2YgYW4gYXR0cmlidXRlIGJ5IE5hbWVzcGFjZSBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSQorICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUuCisgICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlJ3MgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZSAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkKKyAgICB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworCisgICAgLyoqCisgICAgICogTG9vayB1cCB0aGUgdmFsdWUgb2YgYW4gYXR0cmlidXRlIGJ5IHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCBuYW1lLgorICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUgKFN0cmluZyBxTmFtZSkKKyAgICB7CisgICAgICAgIHJldHVybiBxQXR0cy5nZXRWYWx1ZShxTmFtZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBBdHRyaWJ1dGVMaXN0IHFBdHRzOworICAgIH0KK30KKworLy8gZW5kIG9mIFBhcnNlckFkYXB0ZXIuamF2YQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2hlbHBlcnMvUGFyc2VyRmFjdG9yeS5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2hlbHBlcnMvUGFyc2VyRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4YjUyODYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvaGVscGVycy9QYXJzZXJGYWN0b3J5LmphdmEKQEAgLTAsMCArMSwxMjggQEAKKy8vIFNBWCBwYXJzZXIgZmFjdG9yeS4KKy8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKKy8vIE5vIHdhcnJhbnR5OyBubyBjb3B5cmlnaHQgLS0gdXNlIHRoaXMgYXMgeW91IHdpbGwuCisvLyAkSWQ6IFBhcnNlckZhY3RvcnkuamF2YSx2IDEuNyAyMDAyLzAxLzMwIDIwOjUyOjM2IGRicm93bmVsbCBFeHAgJAorCitwYWNrYWdlIG9yZy54bWwuc2F4LmhlbHBlcnM7CisKK2ltcG9ydCBvcmcueG1sLnNheC5QYXJzZXI7CisKKworLyoqCisgKiBKYXZhLXNwZWNpZmljIGNsYXNzIGZvciBkeW5hbWljYWxseSBsb2FkaW5nIFNBWCBwYXJzZXJzLgorICoKKyAqIDxibG9ja3F1b3RlPgorICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKKyAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KKyAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgorICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCisgKiA8L2Jsb2NrcXVvdGU+CisgKgorICogPHA+PHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIGNsYXNzIGlzIGRlc2lnbmVkIHRvIHdvcmsgd2l0aCB0aGUgbm93LWRlcHJlY2F0ZWQKKyAqIFNBWDEge0BsaW5rIG9yZy54bWwuc2F4LlBhcnNlciBQYXJzZXJ9IGNsYXNzLiAgU0FYMiBhcHBsaWNhdGlvbnMgc2hvdWxkIHVzZQorICoge0BsaW5rIG9yZy54bWwuc2F4LmhlbHBlcnMuWE1MUmVhZGVyRmFjdG9yeSBYTUxSZWFkZXJGYWN0b3J5fSBpbnN0ZWFkLjwvcD4KKyAqCisgKiA8cD5QYXJzZXJGYWN0b3J5IGlzIG5vdCBwYXJ0IG9mIHRoZSBwbGF0Zm9ybS1pbmRlcGVuZGVudCBkZWZpbml0aW9uCisgKiBvZiBTQVg7IGl0IGlzIGFuIGFkZGl0aW9uYWwgY29udmVuaWVuY2UgY2xhc3MgZGVzaWduZWQKKyAqIHNwZWNpZmljYWxseSBmb3IgSmF2YSBYTUwgYXBwbGljYXRpb24gd3JpdGVycy4gIFNBWCBhcHBsaWNhdGlvbnMKKyAqIGNhbiB1c2UgdGhlIHN0YXRpYyBtZXRob2RzIGluIHRoaXMgY2xhc3MgdG8gYWxsb2NhdGUgYSBTQVggcGFyc2VyCisgKiBkeW5hbWljYWxseSBhdCBydW4tdGltZSBiYXNlZCBlaXRoZXIgb24gdGhlIHZhbHVlIG9mIHRoZQorICogYG9yZy54bWwuc2F4LnBhcnNlcicgc3lzdGVtIHByb3BlcnR5IG9yIG9uIGEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGNsYXNzCisgKiBuYW1lLjwvcD4KKyAqCisgKiA8cD5Ob3RlIHRoYXQgdGhlIGFwcGxpY2F0aW9uIHN0aWxsIHJlcXVpcmVzIGFuIFhNTCBwYXJzZXIgdGhhdAorICogaW1wbGVtZW50cyBTQVgxLjwvcD4KKyAqCisgKiBAZGVwcmVjYXRlZCBUaGlzIGNsYXNzIHdvcmtzIHdpdGggdGhlIGRlcHJlY2F0ZWQKKyAqICAgICAgICAgICAgIHtAbGluayBvcmcueG1sLnNheC5QYXJzZXIgUGFyc2VyfQorICogICAgICAgICAgICAgaW50ZXJmYWNlLgorICogQHNpbmNlIFNBWCAxLjAKKyAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCisgKiBAdmVyc2lvbiAyLjAuMSAoc2F4MnIyKQorICovCitARGVwcmVjYXRlZAorcHVibGljIGNsYXNzIFBhcnNlckZhY3RvcnkgeworCisKKyAgICAvKioKKyAgICAgKiBQcml2YXRlIG51bGwgY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHJpdmF0ZSBQYXJzZXJGYWN0b3J5ICgpCisgICAgeworICAgIH0KKworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IFNBWCBwYXJzZXIgdXNpbmcgdGhlIGBvcmcueG1sLnNheC5wYXJzZXInIHN5c3RlbSBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBuYW1lZCBjbGFzcyBtdXN0IGV4aXN0IGFuZCBtdXN0IGltcGxlbWVudCB0aGUKKyAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguUGFyc2VyIFBhcnNlcn0gaW50ZXJmYWNlLjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5ld2x5IGNyZWF0ZWQgcGFyc2VyLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gVGhlcmUgaXMgbm8gdmFsdWUKKyAgICAgKiAgICAgICAgICAgIGZvciB0aGUgYG9yZy54bWwuc2F4LnBhcnNlcicgc3lzdGVtIHByb3BlcnR5LgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkNsYXNzTm90Rm91bmRFeGNlcHRpb24gVGhlIFNBWCBwYXJzZXIKKyAgICAgKiAgICAgICAgICAgIGNsYXNzIHdhcyBub3QgZm91bmQgKGNoZWNrIHlvdXIgQ0xBU1NQQVRIKS4KKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gVGhlIFNBWCBwYXJzZXIgY2xhc3Mgd2FzCisgICAgICogICAgICAgICAgICBmb3VuZCwgYnV0IHlvdSBkbyBub3QgaGF2ZSBwZXJtaXNzaW9uIHRvIGxvYWQKKyAgICAgKiAgICAgICAgICAgIGl0LgorICAgICAqIEBleGNlcHRpb24gSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBUaGUgU0FYIHBhcnNlciBjbGFzcyB3YXMKKyAgICAgKiAgICAgICAgICAgIGZvdW5kIGJ1dCBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkLgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkNsYXNzQ2FzdEV4Y2VwdGlvbiBUaGUgU0FYIHBhcnNlciBjbGFzcworICAgICAqICAgICAgICAgICAgd2FzIGZvdW5kIGFuZCBpbnN0YW50aWF0ZWQsIGJ1dCBkb2VzIG5vdCBpbXBsZW1lbnQKKyAgICAgKiAgICAgICAgICAgIG9yZy54bWwuc2F4LlBhcnNlci4KKyAgICAgKiBAc2VlICNtYWtlUGFyc2VyKGphdmEubGFuZy5TdHJpbmcpCisgICAgICogQHNlZSBvcmcueG1sLnNheC5QYXJzZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFBhcnNlciBtYWtlUGFyc2VyICgpCisgICAgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24sCisgICAgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwKKyAgICBJbnN0YW50aWF0aW9uRXhjZXB0aW9uLAorICAgIE51bGxQb2ludGVyRXhjZXB0aW9uLAorICAgIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgIHsKKyAgICBTdHJpbmcgY2xhc3NOYW1lID0gU3lzdGVtLmdldFByb3BlcnR5KCJvcmcueG1sLnNheC5wYXJzZXIiKTsKKyAgICBpZiAoY2xhc3NOYW1lID09IG51bGwpIHsKKyAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJObyB2YWx1ZSBmb3Igc2F4LnBhcnNlciBwcm9wZXJ0eSIpOworICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBtYWtlUGFyc2VyKGNsYXNzTmFtZSk7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IFNBWCBwYXJzZXIgb2JqZWN0IHVzaW5nIHRoZSBjbGFzcyBuYW1lIHByb3ZpZGVkLgorICAgICAqCisgICAgICogPHA+VGhlIG5hbWVkIGNsYXNzIG11c3QgZXhpc3QgYW5kIG11c3QgaW1wbGVtZW50IHRoZQorICAgICAqIHtAbGluayBvcmcueG1sLnNheC5QYXJzZXIgUGFyc2VyfSBpbnRlcmZhY2UuPC9wPgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmV3bHkgY3JlYXRlZCBwYXJzZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2xhc3NOYW1lIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIG5hbWUgb2YgdGhlCisgICAgICogICAgICAgICAgICAgICAgICBTQVggcGFyc2VyIGNsYXNzLgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkNsYXNzTm90Rm91bmRFeGNlcHRpb24gVGhlIFNBWCBwYXJzZXIKKyAgICAgKiAgICAgICAgICAgIGNsYXNzIHdhcyBub3QgZm91bmQgKGNoZWNrIHlvdXIgQ0xBU1NQQVRIKS4KKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gVGhlIFNBWCBwYXJzZXIgY2xhc3Mgd2FzCisgICAgICogICAgICAgICAgICBmb3VuZCwgYnV0IHlvdSBkbyBub3QgaGF2ZSBwZXJtaXNzaW9uIHRvIGxvYWQKKyAgICAgKiAgICAgICAgICAgIGl0LgorICAgICAqIEBleGNlcHRpb24gSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBUaGUgU0FYIHBhcnNlciBjbGFzcyB3YXMKKyAgICAgKiAgICAgICAgICAgIGZvdW5kIGJ1dCBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkLgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkNsYXNzQ2FzdEV4Y2VwdGlvbiBUaGUgU0FYIHBhcnNlciBjbGFzcworICAgICAqICAgICAgICAgICAgd2FzIGZvdW5kIGFuZCBpbnN0YW50aWF0ZWQsIGJ1dCBkb2VzIG5vdCBpbXBsZW1lbnQKKyAgICAgKiAgICAgICAgICAgIG9yZy54bWwuc2F4LlBhcnNlci4KKyAgICAgKiBAc2VlICNtYWtlUGFyc2VyKCkKKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlBhcnNlcgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUGFyc2VyIG1ha2VQYXJzZXIgKFN0cmluZyBjbGFzc05hbWUpCisgICAgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24sCisgICAgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwKKyAgICBJbnN0YW50aWF0aW9uRXhjZXB0aW9uLAorICAgIENsYXNzQ2FzdEV4Y2VwdGlvbgorICAgIHsKKyAgICByZXR1cm4gKFBhcnNlcikgTmV3SW5zdGFuY2UubmV3SW5zdGFuY2UgKAorICAgICAgICBOZXdJbnN0YW5jZS5nZXRDbGFzc0xvYWRlciAoKSwgY2xhc3NOYW1lKTsKKyAgICB9CisKK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2hlbHBlcnMvWE1MRmlsdGVySW1wbC5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2hlbHBlcnMvWE1MRmlsdGVySW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRiNGRkNzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvaGVscGVycy9YTUxGaWx0ZXJJbXBsLmphdmEKQEAgLTAsMCArMSw3MTIgQEAKKy8vIFhNTEZpbHRlckltcGwuamF2YSAtIGJhc2UgU0FYMiBmaWx0ZXIgaW1wbGVtZW50YXRpb24uCisvLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCisvLyBXcml0dGVuIGJ5IERhdmlkIE1lZ2dpbnNvbgorLy8gTk8gV0FSUkFOVFkhICBUaGlzIGNsYXNzIGlzIGluIHRoZSBQdWJsaWMgRG9tYWluLgorLy8gJElkOiBYTUxGaWx0ZXJJbXBsLmphdmEsdiAxLjkgMjAwNC8wNC8yNiAxNzozNDozNSBkbWVnZ2luc29uIEV4cCAkCisKK3BhY2thZ2Ugb3JnLnhtbC5zYXguaGVscGVyczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKK2ltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKK2ltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5YTUxGaWx0ZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOworCisKKy8qKgorICogQmFzZSBjbGFzcyBmb3IgZGVyaXZpbmcgYW4gWE1MIGZpbHRlci4KKyAqCisgKiA8YmxvY2txdW90ZT4KKyAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCisgKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+CisgKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KKyAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgorICogPC9ibG9ja3F1b3RlPgorICoKKyAqIDxwPlRoaXMgY2xhc3MgaXMgZGVzaWduZWQgdG8gc2l0IGJldHdlZW4gYW4ge0BsaW5rIG9yZy54bWwuc2F4LlhNTFJlYWRlcgorICogWE1MUmVhZGVyfSBhbmQgdGhlIGNsaWVudCBhcHBsaWNhdGlvbidzIGV2ZW50IGhhbmRsZXJzLiAgQnkgZGVmYXVsdCwgaXQKKyAqIGRvZXMgbm90aGluZyBidXQgcGFzcyByZXF1ZXN0cyB1cCB0byB0aGUgcmVhZGVyIGFuZCBldmVudHMKKyAqIG9uIHRvIHRoZSBoYW5kbGVycyB1bm1vZGlmaWVkLCBidXQgc3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUKKyAqIHNwZWNpZmljIG1ldGhvZHMgdG8gbW9kaWZ5IHRoZSBldmVudCBzdHJlYW0gb3IgdGhlIGNvbmZpZ3VyYXRpb24KKyAqIHJlcXVlc3RzIGFzIHRoZXkgcGFzcyB0aHJvdWdoLjwvcD4KKyAqCisgKiBAc2luY2UgU0FYIDIuMAorICogQGF1dGhvciBEYXZpZCBNZWdnaW5zb24KKyAqIEB2ZXJzaW9uIDIuMC4xIChzYXgycjIpCisgKiBAc2VlIG9yZy54bWwuc2F4LlhNTEZpbHRlcgorICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIKKyAqIEBzZWUgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXIKKyAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlcgorICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcgorICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIKKyAqLworcHVibGljIGNsYXNzIFhNTEZpbHRlckltcGwKKyAgICBpbXBsZW1lbnRzIFhNTEZpbHRlciwgRW50aXR5UmVzb2x2ZXIsIERUREhhbmRsZXIsIENvbnRlbnRIYW5kbGVyLCBFcnJvckhhbmRsZXIKK3sKKworDAorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gQ29uc3RydWN0b3JzLgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhbiBlbXB0eSBYTUwgZmlsdGVyLCB3aXRoIG5vIHBhcmVudC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgZmlsdGVyIHdpbGwgaGF2ZSBubyBwYXJlbnQ6IHlvdSBtdXN0IGFzc2lnbiBhIHBhcmVudAorICAgICAqIGJlZm9yZSB5b3Ugc3RhcnQgYSBwYXJzZSBvciBkbyBhbnkgY29uZmlndXJhdGlvbiB3aXRoCisgICAgICogc2V0RmVhdHVyZSBvciBzZXRQcm9wZXJ0eSwgdW5sZXNzIHlvdSB1c2UgdGhpcyBhcyBhIHB1cmUgZXZlbnQKKyAgICAgKiBjb25zdW1lciByYXRoZXIgdGhhbiBhcyBhbiB7QGxpbmsgWE1MUmVhZGVyfS48L3A+CisgICAgICoKKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNzZXRGZWF0dXJlCisgICAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0UHJvcGVydHkKKyAgICAgKiBAc2VlICNzZXRQYXJlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgWE1MRmlsdGVySW1wbCAoKQorICAgIHsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhbiBYTUwgZmlsdGVyIHdpdGggdGhlIHNwZWNpZmllZCBwYXJlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyZW50IHRoZSBYTUwgcmVhZGVyIGZyb20gd2hpY2ggdGhpcyBmaWx0ZXIgcmVjZWl2ZXMgaXRzIGV2ZW50cy4KKyAgICAgKgorICAgICAqIEBzZWUgI3NldFBhcmVudAorICAgICAqIEBzZWUgI2dldFBhcmVudAorICAgICAqLworICAgIHB1YmxpYyBYTUxGaWx0ZXJJbXBsIChYTUxSZWFkZXIgcGFyZW50KQorICAgIHsKKyAgICBzZXRQYXJlbnQocGFyZW50KTsKKyAgICB9CisKKworDAorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gSW1wbGVtZW50YXRpb24gb2Ygb3JnLnhtbC5zYXguWE1MRmlsdGVyLgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgcGFyZW50IHJlYWRlci4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaXMgdGhlIHtAbGluayBvcmcueG1sLnNheC5YTUxSZWFkZXIgWE1MUmVhZGVyfSBmcm9tIHdoaWNoCisgICAgICogdGhpcyBmaWx0ZXIgd2lsbCBvYnRhaW4gaXRzIGV2ZW50cyBhbmQgdG8gd2hpY2ggaXQgd2lsbCBwYXNzIGl0cworICAgICAqIGNvbmZpZ3VyYXRpb24gcmVxdWVzdHMuICBUaGUgcGFyZW50IG1heSBpdHNlbGYgYmUgYW5vdGhlciBmaWx0ZXIuPC9wPgorICAgICAqCisgICAgICogPHA+SWYgdGhlcmUgaXMgbm8gcGFyZW50IHJlYWRlciBzZXQsIGFueSBhdHRlbXB0IHRvIHBhcnNlCisgICAgICogb3IgdG8gc2V0IG9yIGdldCBhIGZlYXR1cmUgb3IgcHJvcGVydHkgd2lsbCBmYWlsLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJlbnQgVGhlIHBhcmVudCBYTUwgcmVhZGVyLgorICAgICAqIEBzZWUgI2dldFBhcmVudAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBhcmVudCAoWE1MUmVhZGVyIHBhcmVudCkKKyAgICB7CisgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHBhcmVudCByZWFkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBwYXJlbnQgWE1MIHJlYWRlciwgb3IgbnVsbCBpZiBub25lIGlzIHNldC4KKyAgICAgKiBAc2VlICNzZXRQYXJlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgWE1MUmVhZGVyIGdldFBhcmVudCAoKQorICAgIHsKKyAgICByZXR1cm4gcGFyZW50OworICAgIH0KKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5YTUxSZWFkZXIuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoqCisgICAgICogU2V0IHRoZSB2YWx1ZSBvZiBhIGZlYXR1cmUuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIHdpbGwgYWx3YXlzIGZhaWwgaWYgdGhlIHBhcmVudCBpcyBudWxsLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBmZWF0dXJlIG5hbWUuCisgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXF1ZXN0ZWQgZmVhdHVyZSB2YWx1ZS4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlIGZlYXR1cmUKKyAgICAgKiAgICAgICAgICAgIHZhbHVlIGNhbid0IGJlIGFzc2lnbmVkIG9yIHJldHJpZXZlZCBmcm9tIHRoZSBwYXJlbnQuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUKKyAgICAgKiAgICAgICAgICAgIHBhcmVudCByZWNvZ25pemVzIHRoZSBmZWF0dXJlIG5hbWUgYnV0CisgICAgICogICAgICAgICAgICBjYW5ub3Qgc2V0IHRoZSByZXF1ZXN0ZWQgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZSAoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpCisgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgorICAgIHsKKyAgICBpZiAocGFyZW50ICE9IG51bGwpIHsKKyAgICAgICAgcGFyZW50LnNldEZlYXR1cmUobmFtZSwgdmFsdWUpOworICAgIH0gZWxzZSB7CisgICAgICAgIHRocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKCJGZWF0dXJlOiAiICsgbmFtZSk7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogTG9vayB1cCB0aGUgdmFsdWUgb2YgYSBmZWF0dXJlLgorICAgICAqCisgICAgICogPHA+VGhpcyB3aWxsIGFsd2F5cyBmYWlsIGlmIHRoZSBwYXJlbnQgaXMgbnVsbC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZmVhdHVyZSBuYW1lLgorICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGZlYXR1cmUuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBmZWF0dXJlCisgICAgICogICAgICAgICAgICB2YWx1ZSBjYW4ndCBiZSBhc3NpZ25lZCBvciByZXRyaWV2ZWQgZnJvbSB0aGUgcGFyZW50LgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCisgICAgICogICAgICAgICAgICBwYXJlbnQgcmVjb2duaXplcyB0aGUgZmVhdHVyZSBuYW1lIGJ1dAorICAgICAqICAgICAgICAgICAgY2Fubm90IGRldGVybWluZSBpdHMgdmFsdWUgYXQgdGhpcyB0aW1lLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUgKFN0cmluZyBuYW1lKQorICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKHBhcmVudCAhPSBudWxsKSB7CisgICAgICAgIHJldHVybiBwYXJlbnQuZ2V0RmVhdHVyZShuYW1lKTsKKyAgICB9IGVsc2UgeworICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigiRmVhdHVyZTogIiArIG5hbWUpOworICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgd2lsbCBhbHdheXMgZmFpbCBpZiB0aGUgcGFyZW50IGlzIG51bGwuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIHByb3BlcnR5IG5hbWUuCisgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXF1ZXN0ZWQgcHJvcGVydHkgdmFsdWUuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eQorICAgICAqICAgICAgICAgICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkIGZyb20gdGhlIHBhcmVudC4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBXaGVuIHRoZQorICAgICAqICAgICAgICAgICAgcGFyZW50IHJlY29nbml6ZXMgdGhlIHByb3BlcnR5IG5hbWUgYnV0CisgICAgICogICAgICAgICAgICBjYW5ub3Qgc2V0IHRoZSByZXF1ZXN0ZWQgdmFsdWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkgKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpCisgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgorICAgIHsKKyAgICBpZiAocGFyZW50ICE9IG51bGwpIHsKKyAgICAgICAgcGFyZW50LnNldFByb3BlcnR5KG5hbWUsIHZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigiUHJvcGVydHk6ICIgKyBuYW1lKTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBMb29rIHVwIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIHByb3BlcnR5IG5hbWUuCisgICAgICogQHJldHVybiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcHJvcGVydHkuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eQorICAgICAqICAgICAgICAgICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkIGZyb20gdGhlIHBhcmVudC4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBXaGVuIHRoZQorICAgICAqICAgICAgICAgICAgcGFyZW50IHJlY29nbml6ZXMgdGhlIHByb3BlcnR5IG5hbWUgYnV0CisgICAgICogICAgICAgICAgICBjYW5ub3QgZGV0ZXJtaW5lIGl0cyB2YWx1ZSBhdCB0aGlzIHRpbWUuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eSAoU3RyaW5nIG5hbWUpCisgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgorICAgIHsKKyAgICBpZiAocGFyZW50ICE9IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIHBhcmVudC5nZXRQcm9wZXJ0eShuYW1lKTsKKyAgICB9IGVsc2UgeworICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigiUHJvcGVydHk6ICIgKyBuYW1lKTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGVudGl0eSByZXNvbHZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZXNvbHZlciBUaGUgbmV3IGVudGl0eSByZXNvbHZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRFbnRpdHlSZXNvbHZlciAoRW50aXR5UmVzb2x2ZXIgcmVzb2x2ZXIpCisgICAgeworICAgIGVudGl0eVJlc29sdmVyID0gcmVzb2x2ZXI7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGN1cnJlbnQgZW50aXR5IHJlc29sdmVyLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgY3VycmVudCBlbnRpdHkgcmVzb2x2ZXIsIG9yIG51bGwgaWYgbm9uZSB3YXMgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBFbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlciAoKQorICAgIHsKKyAgICByZXR1cm4gZW50aXR5UmVzb2x2ZXI7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIERURCBldmVudCBoYW5kbGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGhhbmRsZXIgdGhlIG5ldyBEVEQgaGFuZGxlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERUREhhbmRsZXIgKERUREhhbmRsZXIgaGFuZGxlcikKKyAgICB7CisgICAgZHRkSGFuZGxlciA9IGhhbmRsZXI7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGN1cnJlbnQgRFREIGV2ZW50IGhhbmRsZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IERURCBoYW5kbGVyLCBvciBudWxsIGlmIG5vbmUgd2FzIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRFRESGFuZGxlciBnZXREVERIYW5kbGVyICgpCisgICAgeworICAgIHJldHVybiBkdGRIYW5kbGVyOworICAgIH0KKworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBjb250ZW50IGV2ZW50IGhhbmRsZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaGFuZGxlciB0aGUgbmV3IGNvbnRlbnQgaGFuZGxlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyIChDb250ZW50SGFuZGxlciBoYW5kbGVyKQorICAgIHsKKyAgICBjb250ZW50SGFuZGxlciA9IGhhbmRsZXI7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGNvbnRlbnQgZXZlbnQgaGFuZGxlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgY29udGVudCBoYW5kbGVyLCBvciBudWxsIGlmIG5vbmUgd2FzIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIgKCkKKyAgICB7CisgICAgcmV0dXJuIGNvbnRlbnRIYW5kbGVyOworICAgIH0KKworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBlcnJvciBldmVudCBoYW5kbGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGhhbmRsZXIgdGhlIG5ldyBlcnJvciBoYW5kbGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyIChFcnJvckhhbmRsZXIgaGFuZGxlcikKKyAgICB7CisgICAgZXJyb3JIYW5kbGVyID0gaGFuZGxlcjsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgY3VycmVudCBlcnJvciBldmVudCBoYW5kbGVyLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgY3VycmVudCBlcnJvciBoYW5kbGVyLCBvciBudWxsIGlmIG5vbmUgd2FzIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlciAoKQorICAgIHsKKyAgICByZXR1cm4gZXJyb3JIYW5kbGVyOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUGFyc2UgYSBkb2N1bWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dCBUaGUgaW5wdXQgc291cmNlIGZvciB0aGUgZG9jdW1lbnQgZW50aXR5LgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQorICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAgICogQGV4Y2VwdGlvbiBqYXZhLmlvLklPRXhjZXB0aW9uIEFuIElPIGV4Y2VwdGlvbiBmcm9tIHRoZSBwYXJzZXIsCisgICAgICogICAgICAgICAgICBwb3NzaWJseSBmcm9tIGEgYnl0ZSBzdHJlYW0gb3IgY2hhcmFjdGVyIHN0cmVhbQorICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgYnkgdGhlIGFwcGxpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHBhcnNlIChJbnB1dFNvdXJjZSBpbnB1dCkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICBzZXR1cFBhcnNlKCk7CisgICAgcGFyZW50LnBhcnNlKGlucHV0KTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFBhcnNlIGEgZG9jdW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIGFzIGEgZnVsbHktcXVhbGlmaWVkIFVSSS4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKKyAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgorICAgICAqIEBleGNlcHRpb24gamF2YS5pby5JT0V4Y2VwdGlvbiBBbiBJTyBleGNlcHRpb24gZnJvbSB0aGUgcGFyc2VyLAorICAgICAqICAgICAgICAgICAgcG9zc2libHkgZnJvbSBhIGJ5dGUgc3RyZWFtIG9yIGNoYXJhY3RlciBzdHJlYW0KKyAgICAgKiAgICAgICAgICAgIHN1cHBsaWVkIGJ5IHRoZSBhcHBsaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwYXJzZSAoU3RyaW5nIHN5c3RlbUlkKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uCisgICAgeworICAgIHBhcnNlKG5ldyBJbnB1dFNvdXJjZShzeXN0ZW1JZCkpOworICAgIH0KKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlci4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisKKyAgICAvKioKKyAgICAgKiBGaWx0ZXIgYW4gZXh0ZXJuYWwgZW50aXR5IHJlc29sdXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIGVudGl0eSdzIHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsLgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgZW50aXR5J3Mgc3lzdGVtIGlkZW50aWZpZXIuCisgICAgICogQHJldHVybiBBIG5ldyBJbnB1dFNvdXJjZSBvciBudWxsIGZvciB0aGUgZGVmYXVsdC4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdworICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgorICAgICAqIEBleGNlcHRpb24gamF2YS5pby5JT0V4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdyBhbgorICAgICAqICAgICAgICAgICAgSS9PLXJlbGF0ZWQgZXhjZXB0aW9uIHdoaWxlIG9idGFpbmluZyB0aGUKKyAgICAgKiAgICAgICAgICAgIG5ldyBJbnB1dFNvdXJjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eSAoU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24KKyAgICB7CisgICAgaWYgKGVudGl0eVJlc29sdmVyICE9IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIGVudGl0eVJlc29sdmVyLnJlc29sdmVFbnRpdHkocHVibGljSWQsIHN5c3RlbUlkKTsKKyAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgICAgfQorCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIEltcGxlbWVudGF0aW9uIG9mIG9yZy54bWwuc2F4LkRUREhhbmRsZXIuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoqCisgICAgICogRmlsdGVyIGEgbm90YXRpb24gZGVjbGFyYXRpb24gZXZlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbm90YXRpb24gbmFtZS4KKyAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIG5vdGF0aW9uJ3MgcHVibGljIGlkZW50aWZpZXIsIG9yIG51bGwuCisgICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBub3RhdGlvbidzIHN5c3RlbSBpZGVudGlmaWVyLCBvciBudWxsLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93CisgICAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgbm90YXRpb25EZWNsIChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICBpZiAoZHRkSGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgIGR0ZEhhbmRsZXIubm90YXRpb25EZWNsKG5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCk7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogRmlsdGVyIGFuIHVucGFyc2VkIGVudGl0eSBkZWNsYXJhdGlvbiBldmVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBlbnRpdHkgbmFtZS4KKyAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIGVudGl0eSdzIHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsLgorICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgZW50aXR5J3Mgc3lzdGVtIGlkZW50aWZpZXIsIG9yIG51bGwuCisgICAgICogQHBhcmFtIG5vdGF0aW9uTmFtZSBUaGUgbmFtZSBvZiB0aGUgYXNzb2NpYXRlZCBub3RhdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdworICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbCAoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgbm90YXRpb25OYW1lKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKGR0ZEhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICBkdGRIYW5kbGVyLnVucGFyc2VkRW50aXR5RGVjbChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQsCisgICAgICAgICAgICAgICAgICAgICAgbm90YXRpb25OYW1lKTsKKyAgICB9CisgICAgfQorCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIEltcGxlbWVudGF0aW9uIG9mIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyLgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworICAgIC8qKgorICAgICAqIEZpbHRlciBhIG5ldyBkb2N1bWVudCBsb2NhdG9yIGV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2F0b3IgVGhlIGRvY3VtZW50IGxvY2F0b3IuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yIChMb2NhdG9yIGxvY2F0b3IpCisgICAgeworICAgIHRoaXMubG9jYXRvciA9IGxvY2F0b3I7CisgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgY29udGVudEhhbmRsZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGxvY2F0b3IpOworICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEZpbHRlciBhIHN0YXJ0IGRvY3VtZW50IGV2ZW50LgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKKyAgICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50ICgpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICBjb250ZW50SGFuZGxlci5zdGFydERvY3VtZW50KCk7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogRmlsdGVyIGFuIGVuZCBkb2N1bWVudCBldmVudC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93CisgICAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQgKCkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgIGNvbnRlbnRIYW5kbGVyLmVuZERvY3VtZW50KCk7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogRmlsdGVyIGEgc3RhcnQgTmFtZXNwYWNlIHByZWZpeCBtYXBwaW5nIGV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHByZWZpeCBUaGUgTmFtZXNwYWNlIHByZWZpeC4KKyAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93CisgICAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nIChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgY29udGVudEhhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgdXJpKTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBGaWx0ZXIgYW4gZW5kIE5hbWVzcGFjZSBwcmVmaXggbWFwcGluZyBldmVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIE5hbWVzcGFjZSBwcmVmaXguCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKKyAgICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nIChTdHJpbmcgcHJlZml4KQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgY29udGVudEhhbmRsZXIuZW5kUHJlZml4TWFwcGluZyhwcmVmaXgpOworICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEZpbHRlciBhIHN0YXJ0IGVsZW1lbnQgZXZlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJpIFRoZSBlbGVtZW50J3MgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZy4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBlbGVtZW50J3MgbG9jYWwgbmFtZSwgb3IgdGhlIGVtcHR5IHN0cmluZy4KKyAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIGVsZW1lbnQncyBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLCBvciB0aGUgZW1wdHkKKyAgICAgKiAgICAgICAgc3RyaW5nLgorICAgICAqIEBwYXJhbSBhdHRzIFRoZSBlbGVtZW50J3MgYXR0cmlidXRlcy4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdworICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lLAorICAgICAgICAgICAgICAgICAgQXR0cmlidXRlcyBhdHRzKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgY29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KHVyaSwgbG9jYWxOYW1lLCBxTmFtZSwgYXR0cyk7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogRmlsdGVyIGFuIGVuZCBlbGVtZW50IGV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHVyaSBUaGUgZWxlbWVudCdzIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcuCisgICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgZWxlbWVudCdzIGxvY2FsIG5hbWUsIG9yIHRoZSBlbXB0eSBzdHJpbmcuCisgICAgICogQHBhcmFtIHFOYW1lIFRoZSBlbGVtZW50J3MgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZSwgb3IgdGhlIGVtcHR5CisgICAgICogICAgICAgIHN0cmluZy4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdworICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgIGNvbnRlbnRIYW5kbGVyLmVuZEVsZW1lbnQodXJpLCBsb2NhbE5hbWUsIHFOYW1lKTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBGaWx0ZXIgYSBjaGFyYWN0ZXIgZGF0YSBldmVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaCBBbiBhcnJheSBvZiBjaGFyYWN0ZXJzLgorICAgICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGFycmF5LgorICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZSBhcnJheS4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdworICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMgKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgY29udGVudEhhbmRsZXIuY2hhcmFjdGVycyhjaCwgc3RhcnQsIGxlbmd0aCk7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogRmlsdGVyIGFuIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIGV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGNoIEFuIGFycmF5IG9mIGNoYXJhY3RlcnMuCisgICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCisgICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlIGZyb20gdGhlIGFycmF5LgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93CisgICAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZSAoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICBjb250ZW50SGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKGNoLCBzdGFydCwgbGVuZ3RoKTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBGaWx0ZXIgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHRhcmdldCBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0YXJnZXQuCisgICAgICogQHBhcmFtIGRhdGEgVGhlIHRleHQgZm9sbG93aW5nIHRoZSB0YXJnZXQuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKKyAgICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgY29udGVudEhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSk7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogRmlsdGVyIGEgc2tpcHBlZCBlbnRpdHkgZXZlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgc2tpcHBlZCBlbnRpdHkuCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKKyAgICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBza2lwcGVkRW50aXR5IChTdHJpbmcgbmFtZSkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgIGNvbnRlbnRIYW5kbGVyLnNraXBwZWRFbnRpdHkobmFtZSk7CisgICAgfQorICAgIH0KKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoqCisgICAgICogRmlsdGVyIGEgd2FybmluZyBldmVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIFRoZSB3YXJuaW5nIGFzIGFuIGV4Y2VwdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdworICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcgKFNBWFBhcnNlRXhjZXB0aW9uIGUpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICBpZiAoZXJyb3JIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgZXJyb3JIYW5kbGVyLndhcm5pbmcoZSk7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogRmlsdGVyIGFuIGVycm9yIGV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGUgVGhlIGVycm9yIGFzIGFuIGV4Y2VwdGlvbi4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdworICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVycm9yIChTQVhQYXJzZUV4Y2VwdGlvbiBlKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKGVycm9ySGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgIGVycm9ySGFuZGxlci5lcnJvcihlKTsKKyAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBGaWx0ZXIgYSBmYXRhbCBlcnJvciBldmVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIFRoZSBlcnJvciBhcyBhbiBleGNlcHRpb24uCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKKyAgICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBmYXRhbEVycm9yIChTQVhQYXJzZUV4Y2VwdGlvbiBlKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKGVycm9ySGFuZGxlciAhPSBudWxsKSB7CisgICAgICAgIGVycm9ySGFuZGxlci5mYXRhbEVycm9yKGUpOworICAgIH0KKyAgICB9CisKKworDAorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gSW50ZXJuYWwgbWV0aG9kcy4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisKKyAgICAvKioKKyAgICAgKiBTZXQgdXAgYmVmb3JlIGEgcGFyc2UuCisgICAgICoKKyAgICAgKiA8cD5CZWZvcmUgZXZlcnkgcGFyc2UsIGNoZWNrIHdoZXRoZXIgdGhlIHBhcmVudCBpcworICAgICAqIG5vbi1udWxsLCBhbmQgcmUtcmVnaXN0ZXIgdGhlIGZpbHRlciBmb3IgYWxsIG9mIHRoZQorICAgICAqIGV2ZW50cy48L3A+CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNldHVwUGFyc2UgKCkKKyAgICB7CisgICAgaWYgKHBhcmVudCA9PSBudWxsKSB7CisgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiTm8gcGFyZW50IGZvciBmaWx0ZXIiKTsKKyAgICB9CisgICAgcGFyZW50LnNldEVudGl0eVJlc29sdmVyKHRoaXMpOworICAgIHBhcmVudC5zZXREVERIYW5kbGVyKHRoaXMpOworICAgIHBhcmVudC5zZXRDb250ZW50SGFuZGxlcih0aGlzKTsKKyAgICBwYXJlbnQuc2V0RXJyb3JIYW5kbGVyKHRoaXMpOworICAgIH0KKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBJbnRlcm5hbCBzdGF0ZS4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisgICAgcHJpdmF0ZSBYTUxSZWFkZXIgcGFyZW50ID0gbnVsbDsKKyAgICBwcml2YXRlIExvY2F0b3IgbG9jYXRvciA9IG51bGw7CisgICAgcHJpdmF0ZSBFbnRpdHlSZXNvbHZlciBlbnRpdHlSZXNvbHZlciA9IG51bGw7CisgICAgcHJpdmF0ZSBEVERIYW5kbGVyIGR0ZEhhbmRsZXIgPSBudWxsOworICAgIHByaXZhdGUgQ29udGVudEhhbmRsZXIgY29udGVudEhhbmRsZXIgPSBudWxsOworICAgIHByaXZhdGUgRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlciA9IG51bGw7CisKK30KKworLy8gZW5kIG9mIFhNTEZpbHRlckltcGwuamF2YQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2hlbHBlcnMvWE1MUmVhZGVyQWRhcHRlci5qYXZhIGIvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L2hlbHBlcnMvWE1MUmVhZGVyQWRhcHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM2ODMyMjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvaGVscGVycy9YTUxSZWFkZXJBZGFwdGVyLmphdmEKQEAgLTAsMCArMSw1MzYgQEAKKy8vIFhNTFJlYWRlckFkYXB0ZXIuamF2YSAtIGFkYXB0IGFuIFNBWDIgWE1MUmVhZGVyIHRvIGEgU0FYMSBQYXJzZXIKKy8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKKy8vIFdyaXR0ZW4gYnkgRGF2aWQgTWVnZ2luc29uCisvLyBOTyBXQVJSQU5UWSEgIFRoaXMgY2xhc3MgaXMgaW4gdGhlIHB1YmxpYyBkb21haW4uCisvLyAkSWQ6IFhNTFJlYWRlckFkYXB0ZXIuamF2YSx2IDEuOSAyMDA0LzA0LzI2IDE3OjM0OjM1IGRtZWdnaW5zb24gRXhwICQKKworcGFja2FnZSBvcmcueG1sLnNheC5oZWxwZXJzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3Q7CitpbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKK2ltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CitpbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKK2ltcG9ydCBvcmcueG1sLnNheC5QYXJzZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7CisKKworLyoqCisgKiBBZGFwdCBhIFNBWDIgWE1MUmVhZGVyIGFzIGEgU0FYMSBQYXJzZXIuCisgKgorICogPGJsb2NrcXVvdGU+CisgKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQorICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgorICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+CisgKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KKyAqIDwvYmxvY2txdW90ZT4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIHdyYXBzIGEgU0FYMiB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyIFhNTFJlYWRlcn0KKyAqIGFuZCBtYWtlcyBpdCBhY3QgYXMgYSBTQVgxIHtAbGluayBvcmcueG1sLnNheC5QYXJzZXIgUGFyc2VyfS4gIFRoZSBYTUxSZWFkZXIKKyAqIG11c3Qgc3VwcG9ydCBhIHRydWUgdmFsdWUgZm9yIHRoZQorICogaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZS1wcmVmaXhlcyBwcm9wZXJ0eSBvciBwYXJzaW5nIHdpbGwgZmFpbAorICogd2l0aCBhIHtAbGluayBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gU0FYRXhjZXB0aW9ufTsgaWYgdGhlIFhNTFJlYWRlcgorICogc3VwcG9ydHMgYSBmYWxzZSB2YWx1ZSBmb3IgdGhlIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzCisgKiBwcm9wZXJ0eSwgdGhhdCB3aWxsIGFsc28gYmUgdXNlZCB0byBpbXByb3ZlIGVmZmljaWVuY3kuPC9wPgorICoKKyAqIEBzaW5jZSBTQVggMi4wCisgKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgorICogQHZlcnNpb24gMi4wLjEgKHNheDJyMikKKyAqIEBzZWUgb3JnLnhtbC5zYXguUGFyc2VyCisgKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlcgorICovCitwdWJsaWMgY2xhc3MgWE1MUmVhZGVyQWRhcHRlciBpbXBsZW1lbnRzIFBhcnNlciwgQ29udGVudEhhbmRsZXIKK3sKKworDAorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gQ29uc3RydWN0b3IuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IGFkYXB0ZXIuCisgICAgICoKKyAgICAgKiA8cD5Vc2UgdGhlICJvcmcueG1sLnNheC5kcml2ZXIiIHByb3BlcnR5IHRvIGxvY2F0ZSB0aGUgU0FYMgorICAgICAqIGRyaXZlciB0byBlbWJlZC48L3A+CisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBJZiB0aGUgZW1iZWRkZWQgZHJpdmVyCisgICAgICogICAgICAgICAgICBjYW5ub3QgYmUgaW5zdGFudGlhdGVkIG9yIGlmIHRoZQorICAgICAqICAgICAgICAgICAgb3JnLnhtbC5zYXguZHJpdmVyIHByb3BlcnR5IGlzIG5vdCBzcGVjaWZpZWQuCisgICAgICovCisgICAgcHVibGljIFhNTFJlYWRlckFkYXB0ZXIgKCkKKyAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgc2V0dXAoWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoKSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgYWRhcHRlci4KKyAgICAgKgorICAgICAqIDxwPkNyZWF0ZSBhIG5ldyBhZGFwdGVyLCB3cmFwcGVkIGFyb3VuZCBhIFNBWDIgWE1MUmVhZGVyLgorICAgICAqIFRoZSBhZGFwdGVyIHdpbGwgbWFrZSB0aGUgWE1MUmVhZGVyIGFjdCBsaWtlIGEgU0FYMQorICAgICAqIFBhcnNlci48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0geG1sUmVhZGVyIFRoZSBTQVgyIFhNTFJlYWRlciB0byB3cmFwLgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIElmIHRoZSBhcmd1bWVudCBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBYTUxSZWFkZXJBZGFwdGVyIChYTUxSZWFkZXIgeG1sUmVhZGVyKQorICAgIHsKKyAgICBzZXR1cCh4bWxSZWFkZXIpOworICAgIH0KKworCisKKyAgICAvKioKKyAgICAgKiBJbnRlcm5hbCBzZXR1cC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB4bWxSZWFkZXIgVGhlIGVtYmVkZGVkIFhNTFJlYWRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0dXAgKFhNTFJlYWRlciB4bWxSZWFkZXIpCisgICAgeworICAgIGlmICh4bWxSZWFkZXIgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIlhNTFJlYWRlciBtdXN0IG5vdCBiZSBudWxsIik7CisgICAgfQorICAgIHRoaXMueG1sUmVhZGVyID0geG1sUmVhZGVyOworICAgIHFBdHRzID0gbmV3IEF0dHJpYnV0ZXNBZGFwdGVyKCk7CisgICAgfQorCisKKworICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gSW1wbGVtZW50YXRpb24gb2Ygb3JnLnhtbC5zYXguUGFyc2VyLgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgbG9jYWxlIGZvciBlcnJvciByZXBvcnRpbmcuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gU0FYMiwgYW5kIHdpbGwgYWx3YXlzIHRocm93CisgICAgICogYW4gZXhjZXB0aW9uLjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZSBmb3IgZXJyb3IgcmVwb3J0aW5nLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguUGFyc2VyI3NldExvY2FsZQorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRocm93biB1bmxlc3Mgb3ZlcnJpZGRlbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRMb2NhbGUgKExvY2FsZSBsb2NhbGUpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICB0aHJvdyBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJzZXRMb2NhbGUgbm90IHN1cHBvcnRlZCIpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmVnaXN0ZXIgdGhlIGVudGl0eSByZXNvbHZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZXNvbHZlciBUaGUgbmV3IHJlc29sdmVyLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguUGFyc2VyI3NldEVudGl0eVJlc29sdmVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIgKEVudGl0eVJlc29sdmVyIHJlc29sdmVyKQorICAgIHsKKyAgICB4bWxSZWFkZXIuc2V0RW50aXR5UmVzb2x2ZXIocmVzb2x2ZXIpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmVnaXN0ZXIgdGhlIERURCBldmVudCBoYW5kbGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGhhbmRsZXIgVGhlIG5ldyBEVEQgZXZlbnQgaGFuZGxlci4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlBhcnNlciNzZXREVERIYW5kbGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlciAoRFRESGFuZGxlciBoYW5kbGVyKQorICAgIHsKKyAgICB4bWxSZWFkZXIuc2V0RFRESGFuZGxlcihoYW5kbGVyKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJlZ2lzdGVyIHRoZSBTQVgxIGRvY3VtZW50IGV2ZW50IGhhbmRsZXIuCisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoYXQgdGhlIFNBWDEgZG9jdW1lbnQgaGFuZGxlciBoYXMgbm8gTmFtZXNwYWNlCisgICAgICogc3VwcG9ydC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgbmV3IFNBWDEgZG9jdW1lbnQgZXZlbnQgaGFuZGxlci4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlBhcnNlciNzZXREb2N1bWVudEhhbmRsZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEhhbmRsZXIgKERvY3VtZW50SGFuZGxlciBoYW5kbGVyKQorICAgIHsKKyAgICBkb2N1bWVudEhhbmRsZXIgPSBoYW5kbGVyOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmVnaXN0ZXIgdGhlIGVycm9yIGV2ZW50IGhhbmRsZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgbmV3IGVycm9yIGV2ZW50IGhhbmRsZXIuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5QYXJzZXIjc2V0RXJyb3JIYW5kbGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyIChFcnJvckhhbmRsZXIgaGFuZGxlcikKKyAgICB7CisgICAgeG1sUmVhZGVyLnNldEVycm9ySGFuZGxlcihoYW5kbGVyKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBkb2N1bWVudC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIHRoZSBlbWJlZGRlZAorICAgICAqIFhNTFJlYWRlciBkb2VzIG5vdCBzdXBwb3J0IHRoZQorICAgICAqIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2UtcHJlZml4ZXMgcHJvcGVydHkuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBhYnNvbHV0ZSBVUkwgb2YgdGhlIGRvY3VtZW50LgorICAgICAqIEBleGNlcHRpb24gamF2YS5pby5JT0V4Y2VwdGlvbiBJZiB0aGVyZSBpcyBhIHByb2JsZW0gcmVhZGluZworICAgICAqICAgICAgICAgICAgdGhlIHJhdyBjb250ZW50IG9mIHRoZSBkb2N1bWVudC4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBJZiB0aGVyZSBpcyBhIHByb2JsZW0KKyAgICAgKiAgICAgICAgICAgIHByb2Nlc3NpbmcgdGhlIGRvY3VtZW50LgorICAgICAqIEBzZWUgI3BhcnNlKG9yZy54bWwuc2F4LklucHV0U291cmNlKQorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguUGFyc2VyI3BhcnNlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgcGFyc2UgKFN0cmluZyBzeXN0ZW1JZCkKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICBwYXJzZShuZXcgSW5wdXRTb3VyY2Uoc3lzdGVtSWQpKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBkb2N1bWVudC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIHRoZSBlbWJlZGRlZAorICAgICAqIFhNTFJlYWRlciBkb2VzIG5vdCBzdXBwb3J0IHRoZQorICAgICAqIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2UtcHJlZml4ZXMgcHJvcGVydHkuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0IEFuIGlucHV0IHNvdXJjZSBmb3IgdGhlIGRvY3VtZW50LgorICAgICAqIEBleGNlcHRpb24gamF2YS5pby5JT0V4Y2VwdGlvbiBJZiB0aGVyZSBpcyBhIHByb2JsZW0gcmVhZGluZworICAgICAqICAgICAgICAgICAgdGhlIHJhdyBjb250ZW50IG9mIHRoZSBkb2N1bWVudC4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBJZiB0aGVyZSBpcyBhIHByb2JsZW0KKyAgICAgKiAgICAgICAgICAgIHByb2Nlc3NpbmcgdGhlIGRvY3VtZW50LgorICAgICAqIEBzZWUgI3BhcnNlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICogQHNlZSBvcmcueG1sLnNheC5QYXJzZXIjcGFyc2Uob3JnLnhtbC5zYXguSW5wdXRTb3VyY2UpCisgICAgICovCisgICAgcHVibGljIHZvaWQgcGFyc2UgKElucHV0U291cmNlIGlucHV0KQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uCisgICAgeworICAgIHNldHVwWE1MUmVhZGVyKCk7CisgICAgeG1sUmVhZGVyLnBhcnNlKGlucHV0KTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFNldCB1cCB0aGUgWE1MIHJlYWRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0dXBYTUxSZWFkZXIgKCkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIHhtbFJlYWRlci5zZXRGZWF0dXJlKCJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzIiwgdHJ1ZSk7CisgICAgdHJ5IHsKKyAgICAgICAgeG1sUmVhZGVyLnNldEZlYXR1cmUoImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOworICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIE5PIE9QOiBpdCdzIGp1c3QgZXh0cmEgaW5mb3JtYXRpb24sIGFuZCB3ZSBjYW4gaWdub3JlIGl0CisgICAgfQorICAgIHhtbFJlYWRlci5zZXRDb250ZW50SGFuZGxlcih0aGlzKTsKKyAgICB9CisKKworDAorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy8gSW1wbGVtZW50YXRpb24gb2Ygb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworCisgICAgLyoqCisgICAgICogU2V0IGEgZG9jdW1lbnQgbG9jYXRvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBkb2N1bWVudCBsb2NhdG9yLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2V0RG9jdW1lbnRMb2NhdG9yCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yIChMb2NhdG9yIGxvY2F0b3IpCisgICAgeworICAgIGlmIChkb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkKKyAgICAgICAgZG9jdW1lbnRIYW5kbGVyLnNldERvY3VtZW50TG9jYXRvcihsb2NhdG9yKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFN0YXJ0IGRvY3VtZW50IGV2ZW50LgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgcmFpc2UgYQorICAgICAqICAgICAgICAgICAgcHJvY2Vzc2luZyBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydERvY3VtZW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCAoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKGRvY3VtZW50SGFuZGxlciAhPSBudWxsKQorICAgICAgICBkb2N1bWVudEhhbmRsZXIuc3RhcnREb2N1bWVudCgpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogRW5kIGRvY3VtZW50IGV2ZW50LgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgcmFpc2UgYQorICAgICAqICAgICAgICAgICAgcHJvY2Vzc2luZyBleGNlcHRpb24uCisgICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmREb2N1bWVudAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50ICgpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICBpZiAoZG9jdW1lbnRIYW5kbGVyICE9IG51bGwpCisgICAgICAgIGRvY3VtZW50SGFuZGxlci5lbmREb2N1bWVudCgpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQWRhcHQgYSBTQVgyIHN0YXJ0IHByZWZpeCBtYXBwaW5nIGV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IGJlaW5nIG1hcHBlZC4KKyAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJIGJlaW5nIG1hcHBlZCB0by4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0UHJlZml4TWFwcGluZworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHN0YXJ0UHJlZml4TWFwcGluZyAoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKKyAgICB7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBBZGFwdCBhIFNBWDIgZW5kIHByZWZpeCBtYXBwaW5nIGV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IGJlaW5nIG1hcHBlZC4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZFByZWZpeE1hcHBpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nIChTdHJpbmcgcHJlZml4KQorICAgIHsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEFkYXB0IGEgU0FYMiBzdGFydCBlbGVtZW50IGV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSS4KKyAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBOYW1lc3BhY2UgbG9jYWwgbmFtZS4KKyAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCisgICAgICogQHBhcmFtIGF0dHMgVGhlIFNBWDIgYXR0cmlidXRlcy4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSByYWlzZSBhCisgICAgICogICAgICAgICAgICBwcm9jZXNzaW5nIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZERvY3VtZW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50IChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLAorICAgICAgICAgICAgICAgICAgU3RyaW5nIHFOYW1lLCBBdHRyaWJ1dGVzIGF0dHMpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICBpZiAoZG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgcUF0dHMuc2V0QXR0cmlidXRlcyhhdHRzKTsKKyAgICAgICAgZG9jdW1lbnRIYW5kbGVyLnN0YXJ0RWxlbWVudChxTmFtZSwgcUF0dHMpOworICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEFkYXB0IGEgU0FYMiBlbmQgZWxlbWVudCBldmVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkkuCisgICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgTmFtZXNwYWNlIGxvY2FsIG5hbWUuCisgICAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHJhaXNlIGEKKyAgICAgKiAgICAgICAgICAgIHByb2Nlc3NpbmcgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kRWxlbWVudAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsCisgICAgICAgICAgICAgICAgU3RyaW5nIHFOYW1lKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKGRvY3VtZW50SGFuZGxlciAhPSBudWxsKQorICAgICAgICBkb2N1bWVudEhhbmRsZXIuZW5kRWxlbWVudChxTmFtZSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBBZGFwdCBhIFNBWDIgY2hhcmFjdGVycyBldmVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjaCBBbiBhcnJheSBvZiBjaGFyYWN0ZXJzLgorICAgICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGFycmF5LgorICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZS4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSByYWlzZSBhCisgICAgICogICAgICAgICAgICBwcm9jZXNzaW5nIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2NoYXJhY3RlcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIGlmIChkb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkKKyAgICAgICAgZG9jdW1lbnRIYW5kbGVyLmNoYXJhY3RlcnMoY2gsIHN0YXJ0LCBsZW5ndGgpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQWRhcHQgYSBTQVgyIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIGV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGNoIEFuIGFycmF5IG9mIGNoYXJhY3RlcnMuCisgICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCisgICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHJhaXNlIGEKKyAgICAgKiAgICAgICAgICAgIHByb2Nlc3NpbmcgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjaWdub3JhYmxlV2hpdGVzcGFjZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UgKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgaWYgKGRvY3VtZW50SGFuZGxlciAhPSBudWxsKQorICAgICAgICBkb2N1bWVudEhhbmRsZXIuaWdub3JhYmxlV2hpdGVzcGFjZShjaCwgc3RhcnQsIGxlbmd0aCk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBBZGFwdCBhIFNBWDIgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBldmVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdGFyZ2V0LgorICAgICAqIEBwYXJhbSBkYXRhIFRoZSByZW1haW5kZXIgb2YgdGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSByYWlzZSBhCisgICAgICogICAgICAgICAgICBwcm9jZXNzaW5nIGV4Y2VwdGlvbi4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3Byb2Nlc3NpbmdJbnN0cnVjdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbiAoU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCisgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgorICAgIHsKKyAgICBpZiAoZG9jdW1lbnRIYW5kbGVyICE9IG51bGwpCisgICAgICAgIGRvY3VtZW50SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEFkYXB0IGEgU0FYMiBza2lwcGVkIGVudGl0eSBldmVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBza2lwcGVkIGVudGl0eS4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3NraXBwZWRFbnRpdHkKKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaHJvd2FibGUgYnkgc3ViY2xhc3Nlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBza2lwcGVkRW50aXR5IChTdHJpbmcgbmFtZSkKKyAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCisgICAgeworICAgIH0KKworCisMCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvLyBJbnRlcm5hbCBzdGF0ZS4KKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisgICAgWE1MUmVhZGVyIHhtbFJlYWRlcjsKKyAgICBEb2N1bWVudEhhbmRsZXIgZG9jdW1lbnRIYW5kbGVyOworICAgIEF0dHJpYnV0ZXNBZGFwdGVyIHFBdHRzOworCisKKwwKKyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIEludGVybmFsIGNsYXNzLgorICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworICAgIC8qKgorICAgICAqIEludGVybmFsIGNsYXNzIHRvIHdyYXAgYSBTQVgyIEF0dHJpYnV0ZXMgb2JqZWN0IGZvciBTQVgxLgorICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBBdHRyaWJ1dGVzQWRhcHRlciBpbXBsZW1lbnRzIEF0dHJpYnV0ZUxpc3QKKyAgICB7CisgICAgQXR0cmlidXRlc0FkYXB0ZXIgKCkKKyAgICB7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGVtYmVkZGVkIEF0dHJpYnV0ZXMgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIFRoZSBlbWJlZGRlZCBTQVgyIEF0dHJpYnV0ZXMuCisgICAgICovCisgICAgdm9pZCBzZXRBdHRyaWJ1dGVzIChBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpCisgICAgeworICAgICAgICB0aGlzLmF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgYXR0cmlidXRlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIGxlbmd0aCBvZiB0aGUgYXR0cmlidXRlIGxpc3QuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0I2dldExlbmd0aAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoICgpCisgICAgeworICAgICAgICByZXR1cm4gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZSBvZiBhbiBhdHRyaWJ1dGUgYnkgcG9zaXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBxdWFsaWZpZWQgbmFtZS4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3QjZ2V0TmFtZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSAoaW50IGkpCisgICAgeworICAgICAgICByZXR1cm4gYXR0cmlidXRlcy5nZXRRTmFtZShpKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdHlwZSBvZiBhbiBhdHRyaWJ1dGUgYnkgcG9zaXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSB0eXBlLgorICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdCNnZXRUeXBlKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUgKGludCBpKQorICAgIHsKKyAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXMuZ2V0VHlwZShpKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgYW4gYXR0cmlidXRlIGJ5IHBvc2l0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgdmFsdWUuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0I2dldFZhbHVlKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlIChpbnQgaSkKKyAgICB7CisgICAgICAgIHJldHVybiBhdHRyaWJ1dGVzLmdldFZhbHVlKGkpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSB0eXBlIG9mIGFuIGF0dHJpYnV0ZSBieSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgdHlwZS4KKyAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3QjZ2V0VHlwZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSAoU3RyaW5nIHFOYW1lKQorICAgIHsKKyAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXMuZ2V0VHlwZShxTmFtZSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSBieSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgdmFsdWUuCisgICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0I2dldFZhbHVlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZSAoU3RyaW5nIHFOYW1lKQorICAgIHsKKyAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXMuZ2V0VmFsdWUocU5hbWUpOworICAgIH0KKworICAgIHByaXZhdGUgQXR0cmlidXRlcyBhdHRyaWJ1dGVzOworICAgIH0KKworfQorCisvLyBlbmQgb2YgWE1MUmVhZGVyQWRhcHRlci5qYXZhCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvaGVscGVycy9YTUxSZWFkZXJGYWN0b3J5LmphdmEgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvaGVscGVycy9YTUxSZWFkZXJGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTQxMTdiYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9oZWxwZXJzL1hNTFJlYWRlckZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDIwNSBAQAorLy8gWE1MUmVhZGVyRmFjdG9yeS5qYXZhIC0gZmFjdG9yeSBmb3IgY3JlYXRpbmcgYSBuZXcgcmVhZGVyLgorLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZworLy8gV3JpdHRlbiBieSBEYXZpZCBNZWdnaW5zb24KKy8vIGFuZCBieSBEYXZpZCBCcm93bmVsbAorLy8gTk8gV0FSUkFOVFkhICBUaGlzIGNsYXNzIGlzIGluIHRoZSBQdWJsaWMgRG9tYWluLgorLy8gJElkOiBYTUxSZWFkZXJGYWN0b3J5LmphdmEsdiAxLjEwIDIwMDIvMDQvMjIgMDE6MDA6MTMgZGJyb3duZWxsIEV4cCAkCisKK3BhY2thZ2Ugb3JnLnhtbC5zYXguaGVscGVyczsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldHM7CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKKworCisvKioKKyAqIEZhY3RvcnkgZm9yIGNyZWF0aW5nIGFuIFhNTCByZWFkZXIuCisgKgorICogPGJsb2NrcXVvdGU+CisgKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQorICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgorICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+CisgKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KKyAqIDwvYmxvY2txdW90ZT4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIGNvbnRhaW5zIHN0YXRpYyBtZXRob2RzIGZvciBjcmVhdGluZyBhbiBYTUwgcmVhZGVyCisgKiBmcm9tIGFuIGV4cGxpY2l0IGNsYXNzIG5hbWUsIG9yIGJhc2VkIG9uIHJ1bnRpbWUgZGVmYXVsdHM6PC9wPgorICoKKyAqIDxwcmU+CisgKiB0cnkgeworICogICBYTUxSZWFkZXIgbXlSZWFkZXIgPSBYTUxSZWFkZXJGYWN0b3J5LmNyZWF0ZVhNTFJlYWRlcigpOworICogfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAqICAgU3lzdGVtLmVyci5wcmludGxuKGUuZ2V0TWVzc2FnZSgpKTsKKyAqIH0KKyAqIDwvcHJlPgorICoKKyAqIDxwPjxzdHJvbmc+Tm90ZSB0byBEaXN0cmlidXRpb25zIGJ1bmRsZWQgd2l0aCBwYXJzZXJzOjwvc3Ryb25nPgorICogWW91IHNob3VsZCBtb2RpZnkgdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBuby1hcmd1bWVudHMKKyAqIDxlbT5jcmVhdGVYTUxSZWFkZXI8L2VtPiB0byBoYW5kbGUgY2FzZXMgd2hlcmUgdGhlIGV4dGVybmFsCisgKiBjb25maWd1cmF0aW9uIG1lY2hhbmlzbXMgYXJlbid0IHNldCB1cC4gIFRoYXQgbWV0aG9kIHNob3VsZCBkbyBpdHMKKyAqIGJlc3QgdG8gcmV0dXJuIGEgcGFyc2VyIHdoZW4gb25lIGlzIGluIHRoZSBjbGFzcyBwYXRoLCBldmVuIHdoZW4KKyAqIG5vdGhpbmcgYm91bmQgaXRzIGNsYXNzIG5hbWUgdG8gPGNvZGU+b3JnLnhtbC5zYXguZHJpdmVyPC9jb2RlPiBzbworICogdGhvc2UgY29uZmlndXJhdGlvbiBtZWNoYW5pc21zIHdvdWxkIHNlZSBpdC48L3A+CisgKgorICogQHNpbmNlIFNBWCAyLjAKKyAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uLCBEYXZpZCBCcm93bmVsbAorICogQHZlcnNpb24gMi4wLjEgKHNheDJyMikKKyAqLworZmluYWwgcHVibGljIGNsYXNzIFhNTFJlYWRlckZhY3RvcnkKK3sKKyAgICAvKioKKyAgICAgKiBQcml2YXRlIGNvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogPHA+VGhpcyBjb25zdHJ1Y3RvciBwcmV2ZW50cyB0aGUgY2xhc3MgZnJvbSBiZWluZyBpbnN0YW50aWF0ZWQuPC9wPgorICAgICAqLworICAgIHByaXZhdGUgWE1MUmVhZGVyRmFjdG9yeSAoKQorICAgIHsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgcHJvcGVydHkgPSAib3JnLnhtbC5zYXguZHJpdmVyIjsKKworICAgIC8qKgorICAgICAqIEF0dGVtcHQgdG8gY3JlYXRlIGFuIFhNTFJlYWRlciBmcm9tIHN5c3RlbSBkZWZhdWx0cy4KKyAgICAgKiBJbiBlbnZpcm9ubWVudHMgd2hpY2ggY2FuIHN1cHBvcnQgaXQsIHRoZSBuYW1lIG9mIHRoZSBYTUxSZWFkZXIKKyAgICAgKiBjbGFzcyBpcyBkZXRlcm1pbmVkIGJ5IHRyeWluZyBlYWNoIHRoZXNlIG9wdGlvbnMgaW4gb3JkZXIsIGFuZAorICAgICAqIHVzaW5nIHRoZSBmaXJzdCBvbmUgd2hpY2ggc3VjY2VlZHM6PC9wPiA8dWw+CisgICAgICoKKyAgICAgKiA8bGk+SWYgdGhlIHN5c3RlbSBwcm9wZXJ0eSA8Y29kZT5vcmcueG1sLnNheC5kcml2ZXI8L2NvZGU+CisgICAgICogaGFzIGEgdmFsdWUsIHRoYXQgaXMgdXNlZCBhcyBhbiBYTUxSZWFkZXIgY2xhc3MgbmFtZS4gPC9saT4KKyAgICAgKgorICAgICAqIDxsaT5UaGUgSkFSICJTZXJ2aWNlcyBBUEkiIGlzIHVzZWQgdG8gbG9vayBmb3IgYSBjbGFzcyBuYW1lCisgICAgICogaW4gdGhlIDxlbT5NRVRBLUlORi9zZXJ2aWNlcy9vcmcueG1sLnNheC5kcml2ZXI8L2VtPiBmaWxlIGluCisgICAgICogamFyZmlsZXMgYXZhaWxhYmxlIHRvIHRoZSBydW50aW1lLjwvbGk+CisgICAgICoKKyAgICAgKiA8bGk+IFNBWCBwYXJzZXIgZGlzdHJpYnV0aW9ucyBhcmUgc3Ryb25nbHkgZW5jb3VyYWdlZCB0byBwcm92aWRlCisgICAgICogYSBkZWZhdWx0IFhNTFJlYWRlciBjbGFzcyBuYW1lIHRoYXQgd2lsbCB0YWtlIGVmZmVjdCBvbmx5IHdoZW4KKyAgICAgKiBwcmV2aW91cyBvcHRpb25zIChvbiB0aGlzIGxpc3QpIGFyZSBub3Qgc3VjY2Vzc2Z1bC48L2xpPgorICAgICAqCisgICAgICogPGxpPkZpbmFsbHksIGlmIHtAbGluayBQYXJzZXJGYWN0b3J5I21ha2VQYXJzZXIoKX0gY2FuCisgICAgICogcmV0dXJuIGEgc3lzdGVtIGRlZmF1bHQgU0FYMSBwYXJzZXIsIHRoYXQgcGFyc2VyIGlzIHdyYXBwZWQgaW4KKyAgICAgKiBhIHtAbGluayBQYXJzZXJBZGFwdGVyfS4gIChUaGlzIGlzIGEgbWlncmF0aW9uIGFpZCBmb3IgU0FYMQorICAgICAqIGVudmlyb25tZW50cywgd2hlcmUgdGhlIDxjb2RlPm9yZy54bWwuc2F4LnBhcnNlcjwvY29kZT4gc3lzdGVtCisgICAgICogcHJvcGVydHkgd2lsbCBvZnRlbiBiZSB1c2FibGUuKSA8L2xpPgorICAgICAqCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIDxwPiBJbiBlbnZpcm9ubWVudHMgc3VjaCBhcyBzbWFsbCBlbWJlZGRlZCBzeXN0ZW1zLCB3aGljaCBjYW4gbm90CisgICAgICogc3VwcG9ydCB0aGF0IGZsZXhpYmlsaXR5LCBvdGhlciBtZWNoYW5pc21zIHRvIGRldGVybWluZSB0aGUgZGVmYXVsdAorICAgICAqIG1heSBiZSB1c2VkLiA8L3A+CisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoYXQgbWFueSBKYXZhIGVudmlyb25tZW50cyBhbGxvdyBzeXN0ZW0gcHJvcGVydGllcyB0byBiZQorICAgICAqIGluaXRpYWxpemVkIG9uIGEgY29tbWFuZCBsaW5lLiAgVGhpcyBtZWFucyB0aGF0IDxlbT5pbiBtb3N0IGNhc2VzPC9lbT4KKyAgICAgKiBzZXR0aW5nIGEgZ29vZCB2YWx1ZSBmb3IgdGhhdCBwcm9wZXJ0eSBlbnN1cmVzIHRoYXQgY2FsbHMgdG8gdGhpcworICAgICAqIG1ldGhvZCB3aWxsIHN1Y2NlZWQsIGV4Y2VwdCB3aGVuIHNlY3VyaXR5IHBvbGljaWVzIGludGVydmVuZS4KKyAgICAgKiBUaGlzIHdpbGwgYWxzbyBtYXhpbWl6ZSBhcHBsaWNhdGlvbiBwb3J0YWJpbGl0eSB0byBvbGRlciBTQVgKKyAgICAgKiBlbnZpcm9ubWVudHMsIHdpdGggbGVzcyByb2J1c3QgaW1wbGVtZW50YXRpb25zIG9mIHRoaXMgbWV0aG9kLgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQSBuZXcgWE1MUmVhZGVyLgorICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIElmIG5vIGRlZmF1bHQgWE1MUmVhZGVyIGNsYXNzCisgICAgICogICAgICAgICAgICBjYW4gYmUgaWRlbnRpZmllZCBhbmQgaW5zdGFudGlhdGVkLgorICAgICAqIEBzZWUgI2NyZWF0ZVhNTFJlYWRlcihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgWE1MUmVhZGVyIGNyZWF0ZVhNTFJlYWRlciAoKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgU3RyaW5nICAgICAgICBjbGFzc05hbWUgPSBudWxsOworICAgIENsYXNzTG9hZGVyICAgIGxvYWRlciA9IE5ld0luc3RhbmNlLmdldENsYXNzTG9hZGVyICgpOworCisgICAgLy8gMS4gdHJ5IHRoZSBKVk0taW5zdGFuY2Utd2lkZSBzeXN0ZW0gcHJvcGVydHkKKyAgICB0cnkgeyBjbGFzc05hbWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkgKHByb3BlcnR5KTsgfQorICAgIGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsgLyogbm9ybWFsbHkgZmFpbHMgZm9yIGFwcGxldHMgKi8gfQorCisgICAgLy8gMi4gaWYgdGhhdCBmYWlscywgdHJ5IE1FVEEtSU5GL3NlcnZpY2VzLworICAgIGlmIChjbGFzc05hbWUgPT0gbnVsbCkgeworICAgICAgICB0cnkgeworICAgICAgICBTdHJpbmcgICAgICAgIHNlcnZpY2UgPSAiTUVUQS1JTkYvc2VydmljZXMvIiArIHByb3BlcnR5OworICAgICAgICBJbnB1dFN0cmVhbSAgICBpbjsKKyAgICAgICAgQnVmZmVyZWRSZWFkZXIgICAgcmVhZGVyOworCisgICAgICAgIGlmIChsb2FkZXIgPT0gbnVsbCkKKyAgICAgICAgICAgIGluID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtUmVzb3VyY2VBc1N0cmVhbSAoc2VydmljZSk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGluID0gbG9hZGVyLmdldFJlc291cmNlQXNTdHJlYW0gKHNlcnZpY2UpOworCisgICAgICAgIGlmIChpbiAhPSBudWxsKSB7CisgICAgICAgICAgICByZWFkZXIgPSBuZXcgQnVmZmVyZWRSZWFkZXIgKG5ldyBJbnB1dFN0cmVhbVJlYWRlciAoaW4sIENoYXJzZXRzLlVURl84KSk7CisgICAgICAgICAgICBjbGFzc05hbWUgPSByZWFkZXIucmVhZExpbmUgKCk7CisgICAgICAgICAgICBpbi5jbG9zZSAoKTsKKyAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLy8gMy4gRGlzdHJvLXNwZWNpZmljIGZhbGxiYWNrCisgICAgaWYgKGNsYXNzTmFtZSA9PSBudWxsKSB7CisvLyBCRUdJTiBESVNUUklCVVRJT04tU1BFQ0lGSUMKKworICAgICAgICAvLyBFWEFNUExFOgorICAgICAgICAvLyBjbGFzc05hbWUgPSAiY29tLmV4YW1wbGUuc2F4LlhtbFJlYWRlciI7CisgICAgICAgIC8vIG9yIGEgJEpBVkFfSE9NRS9qcmUvbGliLypwcm9wZXJ0aWVzIHNldHRpbmcuLi4KKworLy8gRU5EIERJU1RSSUJVVElPTi1TUEVDSUZJQworICAgIH0KKworICAgIC8vIGRvIHdlIGtub3cgdGhlIFhNTFJlYWRlciBpbXBsZW1lbnRhdGlvbiBjbGFzcyB5ZXQ/CisgICAgaWYgKGNsYXNzTmFtZSAhPSBudWxsKQorICAgICAgICByZXR1cm4gbG9hZENsYXNzIChsb2FkZXIsIGNsYXNzTmFtZSk7CisKKyAgICAvLyA0LiBwYW5pYyAtLSBhZGFwdCBhbnkgU0FYMSBwYXJzZXIKKyAgICB0cnkgeworICAgICAgICByZXR1cm4gbmV3IFBhcnNlckFkYXB0ZXIgKFBhcnNlckZhY3RvcnkubWFrZVBhcnNlciAoKSk7CisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbiAoIkNhbid0IGNyZWF0ZSBkZWZhdWx0IFhNTFJlYWRlcjsgIgorICAgICAgICAgICAgKyAiaXMgc3lzdGVtIHByb3BlcnR5IG9yZy54bWwuc2F4LmRyaXZlciBzZXQ/Iik7CisgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogQXR0ZW1wdCB0byBjcmVhdGUgYW4gWE1MIHJlYWRlciBmcm9tIGEgY2xhc3MgbmFtZS4KKyAgICAgKgorICAgICAqIDxwPkdpdmVuIGEgY2xhc3MgbmFtZSwgdGhpcyBtZXRob2QgYXR0ZW1wdHMgdG8gbG9hZAorICAgICAqIGFuZCBpbnN0YW50aWF0ZSB0aGUgY2xhc3MgYXMgYW4gWE1MIHJlYWRlci48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2xhc3NOYW1lIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyB0aGF0IHNob3VsZCBiZSBpbnN0YW50aWF0ZWQuCisgICAgICoKKyAgICAgKiA8cD5Ob3RlIHRoYXQgdGhpcyBtZXRob2Qgd2lsbCBub3QgYmUgdXNhYmxlIGluIGVudmlyb25tZW50cyB3aGVyZQorICAgICAqIHRoZSBjYWxsZXIgKHBlcmhhcHMgYW4gYXBwbGV0KSBpcyBub3QgcGVybWl0dGVkIHRvIGxvYWQgY2xhc3NlcworICAgICAqIGR5bmFtaWNhbGx5LjwvcD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gQSBuZXcgWE1MIHJlYWRlci4KKyAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBJZiB0aGUgY2xhc3MgY2Fubm90IGJlCisgICAgICogICAgICAgICAgICBsb2FkZWQsIGluc3RhbnRpYXRlZCwgYW5kIGNhc3QgdG8gWE1MUmVhZGVyLgorICAgICAqIEBzZWUgI2NyZWF0ZVhNTFJlYWRlcigpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBYTUxSZWFkZXIgY3JlYXRlWE1MUmVhZGVyIChTdHJpbmcgY2xhc3NOYW1lKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgcmV0dXJuIGxvYWRDbGFzcyAoTmV3SW5zdGFuY2UuZ2V0Q2xhc3NMb2FkZXIgKCksIGNsYXNzTmFtZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgWE1MUmVhZGVyIGxvYWRDbGFzcyAoQ2xhc3NMb2FkZXIgbG9hZGVyLCBTdHJpbmcgY2xhc3NOYW1lKQorICAgIHRocm93cyBTQVhFeGNlcHRpb24KKyAgICB7CisgICAgdHJ5IHsKKyAgICAgICAgcmV0dXJuIChYTUxSZWFkZXIpIE5ld0luc3RhbmNlLm5ld0luc3RhbmNlIChsb2FkZXIsIGNsYXNzTmFtZSk7CisgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlMSkgeworICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCJTQVgyIGRyaXZlciBjbGFzcyAiICsgY2xhc3NOYW1lICsKKyAgICAgICAgICAgICAgICAgICAiIG5vdCBmb3VuZCIsIGUxKTsKKyAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGUyKSB7CisgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oIlNBWDIgZHJpdmVyIGNsYXNzICIgKyBjbGFzc05hbWUgKworICAgICAgICAgICAgICAgICAgICIgZm91bmQgYnV0IGNhbm5vdCBiZSBsb2FkZWQiLCBlMik7CisgICAgfSBjYXRjaCAoSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBlMykgeworICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCJTQVgyIGRyaXZlciBjbGFzcyAiICsgY2xhc3NOYW1lICsKKyAgICAgICAiIGxvYWRlZCBidXQgY2Fubm90IGJlIGluc3RhbnRpYXRlZCAobm8gZW1wdHkgcHVibGljIGNvbnN0cnVjdG9yPykiLAorICAgICAgICAgICAgICAgICAgIGUzKTsKKyAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZTQpIHsKKyAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbigiU0FYMiBkcml2ZXIgY2xhc3MgIiArIGNsYXNzTmFtZSArCisgICAgICAgICAgICAgICAgICAgIiBkb2VzIG5vdCBpbXBsZW1lbnQgWE1MUmVhZGVyIiwgZTQpOworICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvaGVscGVycy9wYWNrYWdlLmh0bWwgYi9sdW5pL3NyYy9tYWluL2phdmEvb3JnL3htbC9zYXgvaGVscGVycy9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGYzMjNjMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9oZWxwZXJzL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDExIEBACis8SFRNTD48SEVBRD4KKzwhLS0gJElkOiBwYWNrYWdlLmh0bWwsdiAxLjYgMjAwMi8wMS8zMCAyMDo1MjozOSBkYnJvd25lbGwgRXhwICQgLS0+Cis8L0hFQUQ+PEJPRFk+CisKKzxwPlRoaXMgcGFja2FnZSBjb250YWlucyAiaGVscGVyIiBjbGFzc2VzLCBpbmNsdWRpbmcKK3N1cHBvcnQgZm9yIGJvb3RzdHJhcHBpbmcgU0FYLWJhc2VkIGFwcGxpY2F0aW9ucy4KKworPHA+U2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+Citmb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBTQVguPC9wPgorCis8L0JPRFk+PC9IVE1MPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9qYXZhL29yZy94bWwvc2F4L3BhY2thZ2UuaHRtbCBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2Q3ZjI1NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vamF2YS9vcmcveG1sL3NheC9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwyOTcgQEAKKzxodG1sPjxoZWFkPgorPCEtLSAkSWQ6IHBhY2thZ2UuaHRtbCx2IDEuMTggMjAwNC8wNC8yMSAxMzowNjowMSBkbWVnZ2luc29uIEV4cCAkIC0tPgorPC9oZWFkPjxib2R5PgorCis8cD4gVGhpcyBwYWNrYWdlIHByb3ZpZGVzIHRoZSBjb3JlIFNBWCBBUElzLgorU29tZSBTQVgxIEFQSXMgYXJlIGRlcHJlY2F0ZWQgdG8gZW5jb3VyYWdlIGludGVncmF0aW9uIG9mCituYW1lc3BhY2UtYXdhcmVuZXNzIGludG8gZGVzaWducyBvZiBuZXcgYXBwbGljYXRpb25zCithbmQgaW50byBtYWludGVuYW5jZSBvZiBleGlzdGluZyBpbmZyYXN0cnVjdHVyZS4gPC9wPgorCis8cD5TZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KK2ZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IFNBWC48L3A+CisKKworPGgyPiBTQVgyIFN0YW5kYXJkIEZlYXR1cmUgRmxhZ3MgPC9oMj4KKworPHA+IE9uZSBvZiB0aGUgZXNzZW50aWFsIGNoYXJhY3RlcmlzdGljcyBvZiBTQVgyIGlzIHRoYXQgaXQgYWRkZWQKK2ZlYXR1cmUgZmxhZ3Mgd2hpY2ggY2FuIGJlIHVzZWQgdG8gZXhhbWluZSBhbmQgcGVyaGFwcyBtb2RpZnkKK3BhcnNlciBtb2RlcywgaW4gcGFydGljdWxhciBtb2RlcyBzdWNoIGFzIHZhbGlkYXRpb24uCitTaW5jZSBmZWF0dXJlcyBhcmUgaWRlbnRpZmllZCBieSAoYWJzb2x1dGUpIFVSSXMsIGFueW9uZQorY2FuIGRlZmluZSBzdWNoIGZlYXR1cmVzLiAgIAorQ3VycmVudGx5IGRlZmluZWQgc3RhbmRhcmQgZmVhdHVyZSBVUklzIGhhdmUgdGhlIHByZWZpeAorPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzLzwvY29kZT4gYmVmb3JlIGFuIGlkZW50aWZpZXIgc3VjaCBhcworPGNvZGU+dmFsaWRhdGlvbjwvY29kZT4uICBUdXJuIGZlYXR1cmVzIG9uIG9yIG9mZiB1c2luZworPGVtPnNldEZlYXR1cmU8L2VtPi4gIFRob3NlIHN0YW5kYXJkIGlkZW50aWZpZXJzIGFyZTogPC9wPgorCisKKzx0YWJsZSBib3JkZXI9IjEiIGNlbGxwYWRkaW5nPSIzIiBjZWxsc3BhY2luZz0iMCIgd2lkdGg9IjEwMCUiPgorICAgIDx0ciBhbGlnbj0iY2VudGVyIiBiZ2NvbG9yPSIjY2NjY2ZmIj4KKwk8dGg+RmVhdHVyZSBJRDwvdGg+CisJPHRoPkFjY2VzczwvdGg+CisJPHRoPkRlZmF1bHQ8L3RoPgorCTx0aD5EZXNjcmlwdGlvbjwvdGg+CisJPC90cj4KKworICAgIDx0cj4KKwk8dGQ+ZXh0ZXJuYWwtZ2VuZXJhbC1lbnRpdGllczwvdGQ+CisJPHRkPjxlbT5yZWFkL3dyaXRlPC9lbT48L3RkPgorCTx0ZD48ZW0+dW5zcGVjaWZpZWQ8L2VtPjwvdGQ+CisJPHRkPiBSZXBvcnRzIHdoZXRoZXIgdGhpcyBwYXJzZXIgcHJvY2Vzc2VzIGV4dGVybmFsCisJICAgIGdlbmVyYWwgZW50aXRpZXM7IGFsd2F5cyB0cnVlIGlmIHZhbGlkYXRpbmcuCisJCTwvdGQ+CisJPC90cj4KKworICAgIDx0cj4KKwk8dGQ+ZXh0ZXJuYWwtcGFyYW1ldGVyLWVudGl0aWVzPC90ZD4KKwk8dGQ+PGVtPnJlYWQvd3JpdGU8L2VtPjwvdGQ+CisJPHRkPjxlbT51bnNwZWNpZmllZDwvZW0+PC90ZD4KKwk8dGQ+IFJlcG9ydHMgd2hldGhlciB0aGlzIHBhcnNlciBwcm9jZXNzZXMgZXh0ZXJuYWwKKwkgICAgcGFyYW1ldGVyIGVudGl0aWVzOyBhbHdheXMgdHJ1ZSBpZiB2YWxpZGF0aW5nLgorCQk8L3RkPgorCTwvdHI+CisKKyAgICA8dHI+CisJPHRkPmlzLXN0YW5kYWxvbmU8L3RkPgorCTx0ZD4ocGFyc2luZykgPGVtPnJlYWQtb25seTwvZW0+LCAobm90IHBhcnNpbmcpIDxlbT5ub25lPC9lbT48L3RkPgorCTx0ZD5ub3QgYXBwbGljYWJsZTwvdGQ+CisJPHRkPiBNYXkgYmUgZXhhbWluZWQgb25seSBkdXJpbmcgYSBwYXJzZSwgYWZ0ZXIgdGhlCisJICAgIDxlbT5zdGFydERvY3VtZW50KCk8L2VtPiBjYWxsYmFjayBoYXMgYmVlbiBjb21wbGV0ZWQ7IHJlYWQtb25seS4KKwkgICAgVGhlIHZhbHVlIGlzIHRydWUgaWYgdGhlIGRvY3VtZW50IHNwZWNpZmllZCBzdGFuZGFsb25lPSJ5ZXMiIGluIAorCSAgICBpdHMgWE1MIGRlY2xhcmF0aW9uLCBhbmQgb3RoZXJ3aXNlIGlzIGZhbHNlLgorCQk8L3RkPgorCTwvdHI+CisKKyAgICA8dHI+CisJPHRkPmxleGljYWwtaGFuZGxlci9wYXJhbWV0ZXItZW50aXRpZXM8L3RkPgorCTx0ZD48ZW0+cmVhZC93cml0ZTwvZW0+PC90ZD4KKwk8dGQ+PGVtPnVuc3BlY2lmaWVkPC9lbT48L3RkPgorCTx0ZD4gQSB2YWx1ZSBvZiAidHJ1ZSIgaW5kaWNhdGVzIHRoYXQgdGhlIExleGljYWxIYW5kbGVyIHdpbGwgcmVwb3J0CisJICAgIHRoZSBiZWdpbm5pbmcgYW5kIGVuZCBvZiBwYXJhbWV0ZXIgZW50aXRpZXMuCisJCTwvdGQ+CisJPC90cj4KKworICAgIDx0cj4KKwk8dGQ+bmFtZXNwYWNlczwvdGQ+CisJPHRkPjxlbT5yZWFkL3dyaXRlPC9lbT48L3RkPgorCTx0ZD50cnVlPC90ZD4KKwk8dGQ+IEEgdmFsdWUgb2YgInRydWUiIGluZGljYXRlcyBuYW1lc3BhY2UgVVJJcyBhbmQgdW5wcmVmaXhlZCBsb2NhbCBuYW1lcworCSAgICBmb3IgZWxlbWVudCBhbmQgYXR0cmlidXRlIG5hbWVzIHdpbGwgYmUgYXZhaWxhYmxlLgorCQk8L3RkPgorCTwvdHI+CisKKyAgICA8dHI+CisJPHRkPm5hbWVzcGFjZS1wcmVmaXhlczwvdGQ+CisJPHRkPjxlbT5yZWFkL3dyaXRlPC9lbT48L3RkPgorCTx0ZD5mYWxzZTwvdGQ+CisJPHRkPiBBIHZhbHVlIG9mICJ0cnVlIiBpbmRpY2F0ZXMgdGhhdCBYTUwgcXVhbGlmaWVkIG5hbWVzICh3aXRoIHByZWZpeGVzKSBhbmQKKwkgICAgYXR0cmlidXRlcyAoaW5jbHVkaW5nIDxlbT54bWxucyo8L2VtPiBhdHRyaWJ1dGVzKSB3aWxsIGJlIGF2YWlsYWJsZS4KKwkJPC90ZD4KKwk8L3RyPgorCisgICAgPHRyPgorCTx0ZD5yZXNvbHZlLWR0ZC11cmlzPC90ZD4KKwk8dGQ+PGVtPnJlYWQvd3JpdGU8L2VtPjwvdGQ+CisJPHRkPjxlbT50cnVlPC9lbT48L3RkPgorCTx0ZD4gQSB2YWx1ZSBvZiAidHJ1ZSIgaW5kaWNhdGVzIHRoYXQgc3lzdGVtIElEcyBpbiBkZWNsYXJhdGlvbnMgd2lsbAorCSAgICBiZSBhYnNvbHV0aXplZCAocmVsYXRpdmUgdG8gdGhlaXIgYmFzZSBVUklzKSBiZWZvcmUgcmVwb3J0aW5nLgorCSAgICAoVGhhdCBpcyB0aGUgZGVmYXVsdCBiZWhhdmlvciBmb3IgYWxsIFNBWDIgWE1MIHBhcnNlcnMuKQorCSAgICBBIHZhbHVlIG9mICJmYWxzZSIgaW5kaWNhdGVzIHRob3NlIElEcyB3aWxsIG5vdCBiZSBhYnNvbHV0aXplZDsKKwkgICAgcGFyc2VycyB3aWxsIHByb3ZpZGUgdGhlIGJhc2UgVVJJIGZyb20KKwkgICAgPGVtPkxvY2F0b3IuZ2V0U3lzdGVtSWQoKTwvZW0+LgorCSAgICBUaGlzIGFwcGxpZXMgdG8gc3lzdGVtIElEcyBwYXNzZWQgaW4gPHVsPgorCQk8bGk+PGVtPkRUREhhbmRsZXIubm90YXRpb25EZWNsKCk8L2VtPiwKKwkJPGxpPjxlbT5EVERIYW5kbGVyLnVucGFyc2VkRW50aXR5RGVjbCgpPC9lbT4sIGFuZAorCQk8bGk+PGVtPkRlY2xIYW5kbGVyLmV4dGVybmFsRW50aXR5RGVjbCgpPC9lbT4uCisJICAgIDwvdWw+CisJICAgIEl0IGRvZXMgbm90IGFwcGx5IHRvIDxlbT5FbnRpdHlSZXNvbHZlci5yZXNvbHZlRW50aXR5KCk8L2VtPiwKKwkgICAgd2hpY2ggaXMgbm90IHVzZWQgdG8gcmVwb3J0IGRlY2xhcmF0aW9ucywgb3IgdG8KKwkgICAgPGVtPkxleGljYWxIYW5kbGVyLnN0YXJ0RFREKCk8L2VtPiwgd2hpY2ggYWxyZWFkeSBwcm92aWRlcworCSAgICB0aGUgbm9uLWFic29sdXRpemVkIFVSSS4KKwkgICAgPC90ZD4KKwk8L3RyPgorCisgICAgPHRyPgorCTx0ZD5zdHJpbmctaW50ZXJuaW5nPC90ZD4KKwk8dGQ+PGVtPnJlYWQvd3JpdGU8L2VtPjwvdGQ+CisJPHRkPjxlbT51bnNwZWNpZmllZDwvZW0+PC90ZD4KKwk8dGQ+IEhhcyBhIHZhbHVlIG9mICJ0cnVlIiBpZiBhbGwgWE1MIG5hbWVzIChmb3IgZWxlbWVudHMsIHByZWZpeGVzLAorCSAgICBhdHRyaWJ1dGVzLCBlbnRpdGllcywgbm90YXRpb25zLCBhbmQgbG9jYWwgbmFtZXMpLAorCSAgICBhcyB3ZWxsIGFzIE5hbWVzcGFjZSBVUklzLCB3aWxsIGhhdmUgYmVlbiBpbnRlcm5lZAorCSAgICB1c2luZyA8ZW0+amF2YS5sYW5nLlN0cmluZy5pbnRlcm48L2VtPi4gVGhpcyBzdXBwb3J0cyBmYXN0CisJICAgIHRlc3Rpbmcgb2YgZXF1YWxpdHkvaW5lcXVhbGl0eSBhZ2FpbnN0IHN0cmluZyBjb25zdGFudHMsCisJICAgIHJhdGhlciB0aGFuIGZvcmNpbmcgc2xvd2VyIGNhbGxzIHRvIDxlbT5TdHJpbmcuZXF1YWxzKCk8L2VtPi4KKwkgICAgPC90ZD4KKwk8L3RyPgorCisgICAgPHRyPgorICAgIDx0ZD51bmljb2RlLW5vcm1hbGl6YXRpb24tY2hlY2tpbmc8L3RkPgorICAgIDx0ZD48ZW0+cmVhZC93cml0ZTwvZW0+PC90ZD4KKyAgICA8dGQ+PGVtPmZhbHNlPC9lbT48L3RkPgorICAgIDx0ZD4gQ29udHJvbHMgd2hldGhlciB0aGUgcGFyc2VyIHJlcG9ydHMgVW5pY29kZSBub3JtYWxpemF0aW9uIAorICAgICAgICBlcnJvcnMgYXMgZGVzY3JpYmVkIGluIHNlY3Rpb24gMi4xMyBhbmQgQXBwZW5kaXggQiBvZiB0aGUgCisgICAgICAgIFhNTCAxLjEgUmVjb21tZW5kYXRpb24uIElmIHRydWUsIFVuaWNvZGUgbm9ybWFsaXphdGlvbgorICAgICAgICBlcnJvcnMgYXJlIHJlcG9ydGVkIHVzaW5nIHRoZSBFcnJvckhhbmRsZXIuZXJyb3IoKSBjYWxsYmFjay4KKyAgICAgICAgU3VjaCBlcnJvcnMgYXJlIG5vdCBmYXRhbCBpbiB0aGVtc2VsdmVzICh0aG91Z2gsIG9idmlvdXNseSwKKyAgICAgICAgb3RoZXIgVW5pY29kZS1yZWxhdGVkIGVuY29kaW5nIGVycm9ycyBtYXkgYmUpLgorCQk8L3RkPgorICAgIDwvdHI+CisgICAgCisgICAgPHRyPgorCTx0ZD51c2UtYXR0cmlidXRlczI8L3RkPgorCTx0ZD48ZW0+cmVhZC1vbmx5PC9lbT48L3RkPgorCTx0ZD5ub3QgYXBwbGljYWJsZTwvdGQ+CisJPHRkPiBSZXR1cm5zICJ0cnVlIiBpZiB0aGUgPGVtPkF0dHJpYnV0ZXM8L2VtPiBvYmplY3RzIHBhc3NlZCBieQorCSAgICB0aGlzIHBhcnNlciBpbiA8ZW0+Q29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KCk8L2VtPgorCSAgICBpbXBsZW1lbnQgdGhlIDxhIGhyZWY9ImV4dC9BdHRyaWJ1dGVzMi5odG1sIgorCSAgICA+PGVtPm9yZy54bWwuc2F4LmV4dC5BdHRyaWJ1dGVzMjwvZW0+PC9hPiBpbnRlcmZhY2UuCisJICAgIFRoYXQgaW50ZXJmYWNlIGV4cG9zZXMgYWRkaXRpb25hbCBEVEQtcmVsYXRlZCBpbmZvcm1hdGlvbiwKKwkgICAgc3VjaCBhcyB3aGV0aGVyIHRoZSBhdHRyaWJ1dGUgd2FzIHNwZWNpZmllZCBpbiB0aGUKKwkgICAgc291cmNlIHRleHQgcmF0aGVyIHRoYW4gZGVmYXVsdGVkLgorCQk8L3RkPgorCTwvdHI+CisKKyAgICA8dHI+CisJPHRkPnVzZS1sb2NhdG9yMjwvdGQ+CisJPHRkPjxlbT5yZWFkLW9ubHk8L2VtPjwvdGQ+CisJPHRkPm5vdCBhcHBsaWNhYmxlPC90ZD4KKwk8dGQ+IFJldHVybnMgInRydWUiIGlmIHRoZSA8ZW0+TG9jYXRvcjwvZW0+IG9iamVjdHMgcGFzc2VkIGJ5CisJICAgIHRoaXMgcGFyc2VyIGluIDxlbT5Db250ZW50SGFuZGxlci5zZXREb2N1bWVudExvY2F0b3IoKTwvZW0+CisJICAgIGltcGxlbWVudCB0aGUgPGEgaHJlZj0iZXh0L0xvY2F0b3IyLmh0bWwiCisJICAgID48ZW0+b3JnLnhtbC5zYXguZXh0LkxvY2F0b3IyPC9lbT48L2E+IGludGVyZmFjZS4KKwkgICAgVGhhdCBpbnRlcmZhY2UgZXhwb3NlcyBhZGRpdGlvbmFsIGVudGl0eSBpbmZvcm1hdGlvbiwKKwkgICAgc3VjaCBhcyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIGFuZCBYTUwgdmVyc2lvbiB1c2VkLgorCQk8L3RkPgorCTwvdHI+CisKKyAgICA8dHI+CisJPHRkPnVzZS1lbnRpdHktcmVzb2x2ZXIyPC90ZD4KKwk8dGQ+PGVtPnJlYWQvd3JpdGU8L2VtPjwvdGQ+CisJPHRkPjxlbT50cnVlPC9lbT48L3RkPgorCTx0ZD4gUmV0dXJucyAidHJ1ZSIgaWYsIHdoZW4gPGVtPnNldEVudGl0eVJlc29sdmVyPC9lbT4gaXMgZ2l2ZW4KKwkgICAgYW4gb2JqZWN0IGltcGxlbWVudGluZyB0aGUgPGEgaHJlZj0iZXh0L0VudGl0eVJlc29sdmVyMi5odG1sIgorCSAgICA+PGVtPm9yZy54bWwuc2F4LmV4dC5FbnRpdHlSZXNvbHZlcjI8L2VtPjwvYT4gaW50ZXJmYWNlLAorCSAgICB0aG9zZSBuZXcgbWV0aG9kcyB3aWxsIGJlIHVzZWQuCisJICAgIFJldHVybnMgImZhbHNlIiB0byBpbmRpY2F0ZSB0aGF0IHRob3NlIG1ldGhvZHMgd2lsbCBub3QgYmUgdXNlZC4KKwkJPC90ZD4KKwk8L3RyPgorCisgICAgPHRyPgorCTx0ZD52YWxpZGF0aW9uPC90ZD4KKwk8dGQ+PGVtPnJlYWQvd3JpdGU8L2VtPjwvdGQ+CisJPHRkPjxlbT51bnNwZWNpZmllZDwvZW0+PC90ZD4KKwk8dGQ+IENvbnRyb2xzIHdoZXRoZXIgdGhlIHBhcnNlciBpcyByZXBvcnRpbmcgYWxsIHZhbGlkaXR5CisJICAgIGVycm9yczsgaWYgdHJ1ZSwgYWxsIGV4dGVybmFsIGVudGl0aWVzIHdpbGwgYmUgcmVhZC4KKwkJPC90ZD4KKwk8L3RyPgorCisgICAgPHRyPgorCTx0ZD54bWxucy11cmlzPC90ZD4KKwk8dGQ+PGVtPnJlYWQvd3JpdGU8L2VtPjwvdGQ+CisJPHRkPjxlbT5mYWxzZTwvZW0+PC90ZD4KKwk8dGQ+IENvbnRyb2xzIHdoZXRoZXIsIHdoZW4gdGhlIDxlbT5uYW1lc3BhY2UtcHJlZml4ZXM8L2VtPiBmZWF0dXJlCisJICAgIGlzIHNldCwgdGhlIHBhcnNlciB0cmVhdHMgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGF0dHJpYnV0ZXMgYXMKKwkgICAgYmVpbmcgaW4gdGhlIDxlbT5odHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLzwvZW0+IG5hbWVzcGFjZS4KKwkgICAgQnkgZGVmYXVsdCwgU0FYMiBjb25mb3JtcyB0byB0aGUgb3JpZ2luYWwgIk5hbWVzcGFjZXMgaW4gWE1MIgorCSAgICBSZWNvbW1lbmRhdGlvbiwgd2hpY2ggZXhwbGljaXRseSBzdGF0ZXMgdGhhdCBzdWNoIGF0dHJpYnV0ZXMgYXJlCisJICAgIG5vdCBpbiBhbnkgbmFtZXNwYWNlLgorCSAgICBTZXR0aW5nIHRoaXMgb3B0aW9uYWwgZmxhZyB0byAidHJ1ZSIgbWFrZXMgdGhlIFNBWDIgZXZlbnRzIGNvbmZvcm0gdG8KKwkgICAgYSBsYXRlciBiYWNrd2FyZHMtaW5jb21wYXRpYmxlIHJldmlzaW9uIG9mIHRoYXQgcmVjb21tZW5kYXRpb24sCisJICAgIHBsYWNpbmcgdGhvc2UgYXR0cmlidXRlcyBpbiBhIG5hbWVzcGFjZS4KKwkJPC90ZD4KKwk8L3RyPgorCisgICAgPHRyPgorICAgIDx0ZD54bWwtMS4xPC90ZD4KKyAgICA8dGQ+PGVtPnJlYWQtb25seTwvZW0+PC90ZD4KKyAgICA8dGQ+bm90IGFwcGxpY2FibGU8L3RkPgorICAgIDx0ZD4gUmV0dXJucyAidHJ1ZSIgaWYgdGhlIHBhcnNlciBzdXBwb3J0cyBib3RoIFhNTCAxLjEgYW5kIFhNTCAxLjAuCisgICAgICAgIFJldHVybnMgImZhbHNlIiBpZiB0aGUgcGFyc2VyIHN1cHBvcnRzIG9ubHkgWE1MIDEuMC4KKwkJPC90ZD4KKyAgICA8L3RyPgorCis8L3RhYmxlPgorCis8cD4gU3VwcG9ydCBmb3IgdGhlIGRlZmF1bHQgdmFsdWVzIG9mIHRoZQorPGVtPm5hbWVzcGFjZXM8L2VtPiBhbmQgPGVtPm5hbWVzcGFjZS1wcmVmaXhlczwvZW0+Citwcm9wZXJ0aWVzIGlzIHJlcXVpcmVkLgorU3VwcG9ydCBmb3IgYW55IG90aGVyIGZlYXR1cmUgZmxhZ3MgaXMgZW50aXJlbHkgb3B0aW9uYWwuCis8L3A+CisKKzxwPiBGb3IgZGVmYXVsdCB2YWx1ZXMgbm90IHNwZWNpZmllZCBieSBTQVgyLAorZWFjaCBYTUxSZWFkZXIgaW1wbGVtZW50YXRpb24gc3BlY2lmaWVzIGl0cyBkZWZhdWx0LAorb3IgbWF5IGNob29zZSBub3QgdG8gZXhwb3NlIHRoZSBmZWF0dXJlIGZsYWcuCitVbmxlc3Mgb3RoZXJ3aXNlIHNwZWNpZmllZCBoZXJlLAoraW1wbGVtZW50YXRpb25zIG1heSBzdXBwb3J0IGNoYW5naW5nIGN1cnJlbnQgdmFsdWVzCitvZiB0aGVzZSBzdGFuZGFyZCBmZWF0dXJlIGZsYWdzLCBidXQgbm90IHdoaWxlIHBhcnNpbmcuCis8L3A+CisKKzxoMj4gU0FYMiBTdGFuZGFyZCBIYW5kbGVyIGFuZCBQcm9wZXJ0eSBJRHMgPC9oMj4KKworPHA+IEZvciBwYXJzZXIgaW50ZXJmYWNlIGNoYXJhY3RlcmlzdGljcyB0aGF0IGFyZSBkZXNjcmliZWQKK2FzIG9iamVjdHMsIGEgc2VwYXJhdGUgbmFtZXNwYWNlIGlzIGRlZmluZWQuICBUaGUKK29iamVjdHMgaW4gdGhpcyBuYW1lc3BhY2UgYXJlIGFnYWluIGlkZW50aWZpZWQgYnkgVVJJLCBhbmQKK3RoZSBzdGFuZGFyZCBwcm9wZXJ0eSBVUklzIGhhdmUgdGhlIHByZWZpeAorPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvPC9jb2RlPiBiZWZvcmUgYW4gaWRlbnRpZmllciBzdWNoIGFzCis8Y29kZT5sZXhpY2FsLWhhbmRsZXI8L2NvZGU+IG9yCis8Y29kZT5kb20tbm9kZTwvY29kZT4uICBNYW5hZ2UgdGhvc2UgcHJvcGVydGllcyB1c2luZworPGVtPnNldFByb3BlcnR5KCk8L2VtPi4gIFRob3NlIGlkZW50aWZpZXJzIGFyZTogPC9wPgorCis8dGFibGUgYm9yZGVyPSIxIiBjZWxscGFkZGluZz0iMyIgY2VsbHNwYWNpbmc9IjAiIHdpZHRoPSIxMDAlIj4KKyAgICA8dHIgYWxpZ249ImNlbnRlciIgYmdjb2xvcj0iI2NjY2NmZiI+CisJPHRoPlByb3BlcnR5IElEPC90aD4KKwk8dGg+RGVzY3JpcHRpb248L3RoPgorCTwvdHI+CisKKyAgICA8dHI+CisJPHRkPmRlY2xhcmF0aW9uLWhhbmRsZXI8L3RkPgorCTx0ZD4gVXNlZCB0byBzZWUgbW9zdCBEVEQgZGVjbGFyYXRpb25zIGV4Y2VwdCB0aG9zZSB0cmVhdGVkCisJICAgIGFzIGxleGljYWwgKCJkb2N1bWVudCBlbGVtZW50IG5hbWUgaXMgLi4uIikgb3Igd2hpY2ggYXJlCisJICAgIG1hbmRhdG9yeSBmb3IgYWxsIFNBWCBwYXJzZXJzICg8ZW0+RFRESGFuZGxlcjwvZW0+KS4KKwkgICAgVGhlIE9iamVjdCBtdXN0IGltcGxlbWVudCA8YSBocmVmPSJleHQvRGVjbEhhbmRsZXIuaHRtbCIKKwkgICAgPjxlbT5vcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXI8L2VtPjwvYT4uCisJICAgIDwvdGQ+CisJPC90cj4KKworICAgIDx0cj4KKyAgICAgICAgPHRkPmRvY3VtZW50LXhtbC12ZXJzaW9uPC90ZD4KKyAgICAgICAgPHRkPiBNYXkgYmUgZXhhbWluZWQgb25seSBkdXJpbmcgYSBwYXJzZSwgYWZ0ZXIgdGhlIHN0YXJ0RG9jdW1lbnQoKQorICAgICAgICAgICAgY2FsbGJhY2sgaGFzIGJlZW4gY29tcGxldGVkOyByZWFkLW9ubHkuIFRoaXMgcHJvcGVydHkgaXMgYSAKKyAgICAgICAgICAgIGxpdGVyYWwgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIGFjdHVhbCBYTUwgdmVyc2lvbiBvZiB0aGUgZG9jdW1lbnQsIAorICAgICAgICAgICAgc3VjaCBhcyAiMS4wIiBvciAiMS4xIi4KKyAgICAgICAgICAgIDwvdGQ+CisgICAgICAgIDwvdHI+CisgICAgCisgICAgPHRyPgorCTx0ZD5kb20tbm9kZTwvdGQ+CisJPHRkPiBGb3IgIkRPTSBXYWxrZXIiIHN0eWxlIHBhcnNlcnMsIHdoaWNoIGlnbm9yZSB0aGVpcgorCSAgICA8ZW0+cGFyc2VyLnBhcnNlKCk8L2VtPiBwYXJhbWV0ZXJzLCB0aGlzIGlzIHVzZWQgdG8KKwkgICAgc3BlY2lmeSB0aGUgRE9NIChzdWIpdHJlZSBiZWluZyB3YWxrZWQgYnkgdGhlIHBhcnNlci4KKwkgICAgVGhlIE9iamVjdCBtdXN0IGltcGxlbWVudCB0aGUKKwkgICAgPGVtPm9yZy53M2MuZG9tLk5vZGU8L2VtPiBpbnRlcmZhY2UuCisJICAgIDwvdGQ+CisJPC90cj4KKworICAgIDx0cj4KKwk8dGQ+bGV4aWNhbC1oYW5kbGVyPC90ZD4KKwk8dGQ+IFVzZWQgdG8gc2VlIHNvbWUgc3ludGF4IGV2ZW50cyB0aGF0IGFyZSBlc3NlbnRpYWwgaW4gc29tZQorCSAgICBhcHBsaWNhdGlvbnM6ICBjb21tZW50cywgQ0RBVEEgZGVsaW1pdGVycywgc2VsZWN0ZWQgZ2VuZXJhbAorCSAgICBlbnRpdHkgaW5jbHVzaW9ucywgYW5kIHRoZSBzdGFydCBhbmQgZW5kIG9mIHRoZSBEVEQKKwkgICAgKGFuZCBkZWNsYXJhdGlvbiBvZiBkb2N1bWVudCBlbGVtZW50IG5hbWUpLgorCSAgICBUaGUgT2JqZWN0IG11c3QgaW1wbGVtZW50IDxhIGhyZWY9ImV4dC9MZXhpY2FsSGFuZGxlci5odG1sIgorCSAgICA+PGVtPm9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjwvZW0+PC9hPi4KKwkgICAgPC90ZD4KKwk8L3RyPgorCisgICAgPHRyPgorCTx0ZD54bWwtc3RyaW5nPC90ZD4KKwk8dGQ+IFJlYWRhYmxlIG9ubHkgZHVyaW5nIGEgcGFyc2VyIGNhbGxiYWNrLCB0aGlzIGV4cG9zZXMgYSA8Yj5UQlM8L2I+CisJICAgIGNodW5rIG9mIGNoYXJhY3RlcnMgcmVzcG9uc2libGUgZm9yIHRoZSBjdXJyZW50IGV2ZW50LiA8L3RkPgorCTwvdHI+CisKKzwvdGFibGU+CisKKzxwPiBBbGwgb2YgdGhlc2Ugc3RhbmRhcmQgcHJvcGVydGllcyBhcmUgb3B0aW9uYWw7CitYTUxSZWFkZXIgaW1wbGVtZW50YXRpb25zIG5lZWQgbm90IHN1cHBvcnQgdGhlbS4KKzwvcD4KKworPC9ib2R5PjwvaHRtbD4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vamF2YS9zdW4vbWlzYy9VbnNhZmUuamF2YSBiL2x1bmkvc3JjL21haW4vamF2YS9zdW4vbWlzYy9VbnNhZmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zM2JiOWYxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9qYXZhL3N1bi9taXNjL1Vuc2FmZS5qYXZhCkBAIC0wLDAgKzEsMzQyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBzdW4ubWlzYzsKKworaW1wb3J0IGRhbHZpay5zeXN0ZW0uVk1TdGFjazsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllcjsKKworLyoqCisgKiBUaGUgcGFja2FnZSBuYW1lIG5vdHdpdGhzdGFuZGluZywgdGhpcyBjbGFzcyBpcyB0aGUgcXVhc2ktc3RhbmRhcmQKKyAqIHdheSBmb3IgSmF2YSBjb2RlIHRvIGdhaW4gYWNjZXNzIHRvIGFuZCB1c2UgZnVuY3Rpb25hbGl0eSB3aGljaCwKKyAqIHdoZW4gdW5zdXBlcnZpc2VkLCB3b3VsZCBhbGxvdyBvbmUgdG8gYnJlYWsgdGhlIHBvaW50ZXIvdHlwZSBzYWZldHkKKyAqIG9mIEphdmEuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBVbnNhZmUgeworICAgIC8qKiBub24tbnVsbDsgdW5pcXVlIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBVbnNhZmUgVEhFX09ORSA9IG5ldyBVbnNhZmUoKTsKKworICAgIC8qKgorICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSBwcml2YXRlbHkgaW5zdGFudGlhYmxlLgorICAgICAqLworICAgIHByaXZhdGUgVW5zYWZlKCkge30KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHVuaXF1ZSBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLiBUaGlzIGlzIG9ubHkgYWxsb3dlZCBpbgorICAgICAqIHZlcnkgbGltaXRlZCBzaXR1YXRpb25zLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVW5zYWZlIGdldFVuc2FmZSgpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogT25seSBjb2RlIG9uIHRoZSBib290Y2xhc3NwYXRoIGlzIGFsbG93ZWQgdG8gZ2V0IGF0IHRoZQorICAgICAgICAgKiBVbnNhZmUgaW5zdGFuY2UuCisgICAgICAgICAqLworICAgICAgICBDbGFzc0xvYWRlciBjYWxsaW5nID0gVk1TdGFjay5nZXRDYWxsaW5nQ2xhc3NMb2FkZXIoKTsKKyAgICAgICAgaWYgKChjYWxsaW5nICE9IG51bGwpICYmIChjYWxsaW5nICE9IFVuc2FmZS5jbGFzcy5nZXRDbGFzc0xvYWRlcigpKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCJVbnNhZmUgYWNjZXNzIGRlbmllZCIpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIFRIRV9PTkU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcmF3IGJ5dGUgb2Zmc2V0IGZyb20gdGhlIHN0YXJ0IG9mIGFuIG9iamVjdCdzIG1lbW9yeSB0bworICAgICAqIHRoZSBtZW1vcnkgdXNlZCB0byBzdG9yZSB0aGUgaW5kaWNhdGVkIGluc3RhbmNlIGZpZWxkLgorICAgICAqCisgICAgICogQHBhcmFtIGZpZWxkIG5vbi1udWxsOyB0aGUgZmllbGQgaW4gcXVlc3Rpb24sIHdoaWNoIG11c3QgYmUgYW4KKyAgICAgKiBpbnN0YW5jZSBmaWVsZAorICAgICAqIEByZXR1cm4gdGhlIG9mZnNldCB0byB0aGUgZmllbGQKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBvYmplY3RGaWVsZE9mZnNldChGaWVsZCBmaWVsZCkgeworICAgICAgICBpZiAoTW9kaWZpZXIuaXNTdGF0aWMoZmllbGQuZ2V0TW9kaWZpZXJzKCkpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAidmFsaWQgZm9yIGluc3RhbmNlIGZpZWxkcyBvbmx5Iik7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gb2JqZWN0RmllbGRPZmZzZXQwKGZpZWxkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBIZWxwZXIgZm9yIHtAbGluayAjb2JqZWN0RmllbGRPZmZzZXR9LCB3aGljaCBkb2VzIGFsbCB0aGUgd29yaywKKyAgICAgKiBhc3N1bWluZyB0aGUgcGFyYW1ldGVyIGlzIGRlZW1lZCB2YWxpZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWVsZCBub24tbnVsbDsgdGhlIGluc3RhbmNlIGZpZWxkCisgICAgICogQHJldHVybiB0aGUgb2Zmc2V0IHRvIHRoZSBmaWVsZAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBsb25nIG9iamVjdEZpZWxkT2Zmc2V0MChGaWVsZCBmaWVsZCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YgYW4gYXJyYXkgb2JqZWN0J3MgbWVtb3J5IHRvCisgICAgICogdGhlIG1lbW9yeSB1c2VkIHRvIHN0b3JlIGl0cyBpbml0aWFsICh6ZXJvZXRoKSBlbGVtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIGNsYXp6IG5vbi1udWxsOyBjbGFzcyBpbiBxdWVzdGlvbjsgbXVzdCBiZSBhbiBhcnJheSBjbGFzcworICAgICAqIEByZXR1cm4gdGhlIG9mZnNldCB0byB0aGUgaW5pdGlhbCBlbGVtZW50CisgICAgICovCisgICAgcHVibGljIGludCBhcnJheUJhc2VPZmZzZXQoQ2xhc3MgY2xhenopIHsKKyAgICAgICAgaWYgKCEgY2xhenouaXNBcnJheSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAidmFsaWQgZm9yIGFycmF5IGNsYXNzZXMgb25seSIpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGFycmF5QmFzZU9mZnNldDAoY2xhenopOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhlbHBlciBmb3Ige0BsaW5rICNhcnJheUJhc2VPZmZzZXR9LCB3aGljaCBkb2VzIGFsbCB0aGUgd29yaywKKyAgICAgKiBhc3N1bWluZyB0aGUgcGFyYW1ldGVyIGlzIGRlZW1lZCB2YWxpZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG9mZnNldCB0byB0aGUgZmllbGQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IGFycmF5QmFzZU9mZnNldDAoQ2xhc3MgY2xhenopOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc2l6ZSBvZiBlYWNoIGVsZW1lbnQgb2YgdGhlIGdpdmVuIGFycmF5IGNsYXNzLgorICAgICAqCisgICAgICogQHBhcmFtIGNsYXp6IG5vbi1udWxsOyBjbGFzcyBpbiBxdWVzdGlvbjsgbXVzdCBiZSBhbiBhcnJheSBjbGFzcworICAgICAqIEByZXR1cm4gJmd0OyAwOyB0aGUgc2l6ZSBvZiBlYWNoIGVsZW1lbnQgb2YgdGhlIGFycmF5CisgICAgICovCisgICAgcHVibGljIGludCBhcnJheUluZGV4U2NhbGUoQ2xhc3MgY2xhenopIHsKKyAgICAgICAgaWYgKCEgY2xhenouaXNBcnJheSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAidmFsaWQgZm9yIGFycmF5IGNsYXNzZXMgb25seSIpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGFycmF5SW5kZXhTY2FsZTAoY2xhenopOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhlbHBlciBmb3Ige0BsaW5rICNhcnJheUluZGV4U2NhbGV9LCB3aGljaCBkb2VzIGFsbCB0aGUgd29yaywKKyAgICAgKiBhc3N1bWluZyB0aGUgcGFyYW1ldGVyIGlzIGRlZW1lZCB2YWxpZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG9mZnNldCB0byB0aGUgZmllbGQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IGFycmF5SW5kZXhTY2FsZTAoQ2xhc3MgY2xhenopOworCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBjb21wYXJlLWFuZC1zZXQgb3BlcmF0aW9uIG9uIGFuIDxjb2RlPmludDwvY29kZT4KKyAgICAgKiBmaWVsZCB3aXRoaW4gdGhlIGdpdmVuIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmogbm9uLW51bGw7IG9iamVjdCBjb250YWluaW5nIHRoZSBmaWVsZAorICAgICAqIEBwYXJhbSBvZmZzZXQgb2Zmc2V0IHRvIHRoZSBmaWVsZCB3aXRoaW4gPGNvZGU+b2JqPC9jb2RlPgorICAgICAqIEBwYXJhbSBleHBlY3RlZFZhbHVlIGV4cGVjdGVkIHZhbHVlIG9mIHRoZSBmaWVsZAorICAgICAqIEBwYXJhbSBuZXdWYWx1ZSBuZXcgdmFsdWUgdG8gc3RvcmUgaW4gdGhlIGZpZWxkIGlmIHRoZSBjb250ZW50cyBhcmUKKyAgICAgKiBhcyBleHBlY3RlZAorICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIG5ldyB2YWx1ZSB3YXMgaW4gZmFjdCBzdG9yZWQsIGFuZAorICAgICAqIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiBub3QKKyAgICAgKi8KKyAgICBwdWJsaWMgbmF0aXZlIGJvb2xlYW4gY29tcGFyZUFuZFN3YXBJbnQoT2JqZWN0IG9iaiwgbG9uZyBvZmZzZXQsCisgICAgICAgICAgICBpbnQgZXhwZWN0ZWRWYWx1ZSwgaW50IG5ld1ZhbHVlKTsKKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgY29tcGFyZS1hbmQtc2V0IG9wZXJhdGlvbiBvbiBhIDxjb2RlPmxvbmc8L2NvZGU+CisgICAgICogZmllbGQgd2l0aGluIHRoZSBnaXZlbiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIG5vbi1udWxsOyBvYmplY3QgY29udGFpbmluZyB0aGUgZmllbGQKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IG9mZnNldCB0byB0aGUgZmllbGQgd2l0aGluIDxjb2RlPm9iajwvY29kZT4KKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWRWYWx1ZSBleHBlY3RlZCB2YWx1ZSBvZiB0aGUgZmllbGQKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgbmV3IHZhbHVlIHRvIHN0b3JlIGluIHRoZSBmaWVsZCBpZiB0aGUgY29udGVudHMgYXJlCisgICAgICogYXMgZXhwZWN0ZWQKKyAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBuZXcgdmFsdWUgd2FzIGluIGZhY3Qgc3RvcmVkLCBhbmQKKyAgICAgKiA8Y29kZT5mYWxzZTwvY29kZT4gaWYgbm90CisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSBib29sZWFuIGNvbXBhcmVBbmRTd2FwTG9uZyhPYmplY3Qgb2JqLCBsb25nIG9mZnNldCwKKyAgICAgICAgICAgIGxvbmcgZXhwZWN0ZWRWYWx1ZSwgbG9uZyBuZXdWYWx1ZSk7CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGNvbXBhcmUtYW5kLXNldCBvcGVyYXRpb24gb24gYW4gPGNvZGU+T2JqZWN0PC9jb2RlPgorICAgICAqIGZpZWxkICh0aGF0IGlzLCBhIHJlZmVyZW5jZSBmaWVsZCkgd2l0aGluIHRoZSBnaXZlbiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIG5vbi1udWxsOyBvYmplY3QgY29udGFpbmluZyB0aGUgZmllbGQKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IG9mZnNldCB0byB0aGUgZmllbGQgd2l0aGluIDxjb2RlPm9iajwvY29kZT4KKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWRWYWx1ZSBleHBlY3RlZCB2YWx1ZSBvZiB0aGUgZmllbGQKKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgbmV3IHZhbHVlIHRvIHN0b3JlIGluIHRoZSBmaWVsZCBpZiB0aGUgY29udGVudHMgYXJlCisgICAgICogYXMgZXhwZWN0ZWQKKyAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBuZXcgdmFsdWUgd2FzIGluIGZhY3Qgc3RvcmVkLCBhbmQKKyAgICAgKiA8Y29kZT5mYWxzZTwvY29kZT4gaWYgbm90CisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSBib29sZWFuIGNvbXBhcmVBbmRTd2FwT2JqZWN0KE9iamVjdCBvYmosIGxvbmcgb2Zmc2V0LAorICAgICAgICAgICAgT2JqZWN0IGV4cGVjdGVkVmFsdWUsIE9iamVjdCBuZXdWYWx1ZSk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGFuIDxjb2RlPmludDwvY29kZT4gZmllbGQgZnJvbSB0aGUgZ2l2ZW4gb2JqZWN0LAorICAgICAqIHVzaW5nIDxjb2RlPnZvbGF0aWxlPC9jb2RlPiBzZW1hbnRpY3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIG5vbi1udWxsOyBvYmplY3QgY29udGFpbmluZyB0aGUgZmllbGQKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IG9mZnNldCB0byB0aGUgZmllbGQgd2l0aGluIDxjb2RlPm9iajwvY29kZT4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXRyaWV2ZWQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgbmF0aXZlIGludCBnZXRJbnRWb2xhdGlsZShPYmplY3Qgb2JqLCBsb25nIG9mZnNldCk7CisKKyAgICAvKioKKyAgICAgKiBTdG9yZXMgYW4gPGNvZGU+aW50PC9jb2RlPiBmaWVsZCBpbnRvIHRoZSBnaXZlbiBvYmplY3QsCisgICAgICogdXNpbmcgPGNvZGU+dm9sYXRpbGU8L2NvZGU+IHNlbWFudGljcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmogbm9uLW51bGw7IG9iamVjdCBjb250YWluaW5nIHRoZSBmaWVsZAorICAgICAqIEBwYXJhbSBvZmZzZXQgb2Zmc2V0IHRvIHRoZSBmaWVsZCB3aXRoaW4gPGNvZGU+b2JqPC9jb2RlPgorICAgICAqIEBwYXJhbSBuZXdWYWx1ZSB0aGUgdmFsdWUgdG8gc3RvcmUKKyAgICAgKi8KKyAgICBwdWJsaWMgbmF0aXZlIHZvaWQgcHV0SW50Vm9sYXRpbGUoT2JqZWN0IG9iaiwgbG9uZyBvZmZzZXQsIGludCBuZXdWYWx1ZSk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgPGNvZGU+bG9uZzwvY29kZT4gZmllbGQgZnJvbSB0aGUgZ2l2ZW4gb2JqZWN0LAorICAgICAqIHVzaW5nIDxjb2RlPnZvbGF0aWxlPC9jb2RlPiBzZW1hbnRpY3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIG5vbi1udWxsOyBvYmplY3QgY29udGFpbmluZyB0aGUgZmllbGQKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IG9mZnNldCB0byB0aGUgZmllbGQgd2l0aGluIDxjb2RlPm9iajwvY29kZT4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXRyaWV2ZWQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgbmF0aXZlIGxvbmcgZ2V0TG9uZ1ZvbGF0aWxlKE9iamVjdCBvYmosIGxvbmcgb2Zmc2V0KTsKKworICAgIC8qKgorICAgICAqIFN0b3JlcyBhIDxjb2RlPmxvbmc8L2NvZGU+IGZpZWxkIGludG8gdGhlIGdpdmVuIG9iamVjdCwKKyAgICAgKiB1c2luZyA8Y29kZT52b2xhdGlsZTwvY29kZT4gc2VtYW50aWNzLgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBub24tbnVsbDsgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkCisgICAgICogQHBhcmFtIG9mZnNldCBvZmZzZXQgdG8gdGhlIGZpZWxkIHdpdGhpbiA8Y29kZT5vYmo8L2NvZGU+CisgICAgICogQHBhcmFtIG5ld1ZhbHVlIHRoZSB2YWx1ZSB0byBzdG9yZQorICAgICAqLworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCBwdXRMb25nVm9sYXRpbGUoT2JqZWN0IG9iaiwgbG9uZyBvZmZzZXQsIGxvbmcgbmV3VmFsdWUpOworCisgICAgLyoqCisgICAgICogR2V0cyBhbiA8Y29kZT5PYmplY3Q8L2NvZGU+IGZpZWxkIGZyb20gdGhlIGdpdmVuIG9iamVjdCwKKyAgICAgKiB1c2luZyA8Y29kZT52b2xhdGlsZTwvY29kZT4gc2VtYW50aWNzLgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBub24tbnVsbDsgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkCisgICAgICogQHBhcmFtIG9mZnNldCBvZmZzZXQgdG8gdGhlIGZpZWxkIHdpdGhpbiA8Y29kZT5vYmo8L2NvZGU+CisgICAgICogQHJldHVybiB0aGUgcmV0cmlldmVkIHZhbHVlCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSBPYmplY3QgZ2V0T2JqZWN0Vm9sYXRpbGUoT2JqZWN0IG9iaiwgbG9uZyBvZmZzZXQpOworCisgICAgLyoqCisgICAgICogU3RvcmVzIGFuIDxjb2RlPk9iamVjdDwvY29kZT4gZmllbGQgaW50byB0aGUgZ2l2ZW4gb2JqZWN0LAorICAgICAqIHVzaW5nIDxjb2RlPnZvbGF0aWxlPC9jb2RlPiBzZW1hbnRpY3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIG5vbi1udWxsOyBvYmplY3QgY29udGFpbmluZyB0aGUgZmllbGQKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IG9mZnNldCB0byB0aGUgZmllbGQgd2l0aGluIDxjb2RlPm9iajwvY29kZT4KKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIHZhbHVlIHRvIHN0b3JlCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSB2b2lkIHB1dE9iamVjdFZvbGF0aWxlKE9iamVjdCBvYmosIGxvbmcgb2Zmc2V0LAorICAgICAgICAgICAgT2JqZWN0IG5ld1ZhbHVlKTsKKworICAgIC8qKgorICAgICAqIEdldHMgYW4gPGNvZGU+aW50PC9jb2RlPiBmaWVsZCBmcm9tIHRoZSBnaXZlbiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIG5vbi1udWxsOyBvYmplY3QgY29udGFpbmluZyB0aGUgZmllbGQKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IG9mZnNldCB0byB0aGUgZmllbGQgd2l0aGluIDxjb2RlPm9iajwvY29kZT4KKyAgICAgKiBAcmV0dXJuIHRoZSByZXRyaWV2ZWQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgbmF0aXZlIGludCBnZXRJbnQoT2JqZWN0IG9iaiwgbG9uZyBvZmZzZXQpOworCisgICAgLyoqCisgICAgICogU3RvcmVzIGFuIDxjb2RlPmludDwvY29kZT4gZmllbGQgaW50byB0aGUgZ2l2ZW4gb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBub24tbnVsbDsgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkCisgICAgICogQHBhcmFtIG9mZnNldCBvZmZzZXQgdG8gdGhlIGZpZWxkIHdpdGhpbiA8Y29kZT5vYmo8L2NvZGU+CisgICAgICogQHBhcmFtIG5ld1ZhbHVlIHRoZSB2YWx1ZSB0byBzdG9yZQorICAgICAqLworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCBwdXRJbnQoT2JqZWN0IG9iaiwgbG9uZyBvZmZzZXQsIGludCBuZXdWYWx1ZSk7CisKKyAgICAvKioKKyAgICAgKiBMYXp5IHNldCBhbiBpbnQgZmllbGQuCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSB2b2lkIHB1dE9yZGVyZWRJbnQoT2JqZWN0IG9iaiwgbG9uZyBvZmZzZXQsIGludCBuZXdWYWx1ZSk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIGEgPGNvZGU+bG9uZzwvY29kZT4gZmllbGQgZnJvbSB0aGUgZ2l2ZW4gb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBub24tbnVsbDsgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkCisgICAgICogQHBhcmFtIG9mZnNldCBvZmZzZXQgdG8gdGhlIGZpZWxkIHdpdGhpbiA8Y29kZT5vYmo8L2NvZGU+CisgICAgICogQHJldHVybiB0aGUgcmV0cmlldmVkIHZhbHVlCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSBsb25nIGdldExvbmcoT2JqZWN0IG9iaiwgbG9uZyBvZmZzZXQpOworCisgICAgLyoqCisgICAgICogU3RvcmVzIGEgPGNvZGU+bG9uZzwvY29kZT4gZmllbGQgaW50byB0aGUgZ2l2ZW4gb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiBub24tbnVsbDsgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkCisgICAgICogQHBhcmFtIG9mZnNldCBvZmZzZXQgdG8gdGhlIGZpZWxkIHdpdGhpbiA8Y29kZT5vYmo8L2NvZGU+CisgICAgICogQHBhcmFtIG5ld1ZhbHVlIHRoZSB2YWx1ZSB0byBzdG9yZQorICAgICAqLworICAgIHB1YmxpYyBuYXRpdmUgdm9pZCBwdXRMb25nKE9iamVjdCBvYmosIGxvbmcgb2Zmc2V0LCBsb25nIG5ld1ZhbHVlKTsKKworICAgIC8qKgorICAgICAqIExhenkgc2V0IGEgbG9uZyBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgbmF0aXZlIHZvaWQgcHV0T3JkZXJlZExvbmcoT2JqZWN0IG9iaiwgbG9uZyBvZmZzZXQsIGxvbmcgbmV3VmFsdWUpOworCisgICAgLyoqCisgICAgICogR2V0cyBhbiA8Y29kZT5PYmplY3Q8L2NvZGU+IGZpZWxkIGZyb20gdGhlIGdpdmVuIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmogbm9uLW51bGw7IG9iamVjdCBjb250YWluaW5nIHRoZSBmaWVsZAorICAgICAqIEBwYXJhbSBvZmZzZXQgb2Zmc2V0IHRvIHRoZSBmaWVsZCB3aXRoaW4gPGNvZGU+b2JqPC9jb2RlPgorICAgICAqIEByZXR1cm4gdGhlIHJldHJpZXZlZCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBuYXRpdmUgT2JqZWN0IGdldE9iamVjdChPYmplY3Qgb2JqLCBsb25nIG9mZnNldCk7CisKKyAgICAvKioKKyAgICAgKiBTdG9yZXMgYW4gPGNvZGU+T2JqZWN0PC9jb2RlPiBmaWVsZCBpbnRvIHRoZSBnaXZlbiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIG5vbi1udWxsOyBvYmplY3QgY29udGFpbmluZyB0aGUgZmllbGQKKyAgICAgKiBAcGFyYW0gb2Zmc2V0IG9mZnNldCB0byB0aGUgZmllbGQgd2l0aGluIDxjb2RlPm9iajwvY29kZT4KKyAgICAgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIHZhbHVlIHRvIHN0b3JlCisgICAgICovCisgICAgcHVibGljIG5hdGl2ZSB2b2lkIHB1dE9iamVjdChPYmplY3Qgb2JqLCBsb25nIG9mZnNldCwgT2JqZWN0IG5ld1ZhbHVlKTsKKworICAgIC8qKgorICAgICAqIExhenkgc2V0IGFuIG9iamVjdCBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgbmF0aXZlIHZvaWQgcHV0T3JkZXJlZE9iamVjdChPYmplY3Qgb2JqLCBsb25nIG9mZnNldCwKKyAgICAgICAgICAgIE9iamVjdCBuZXdWYWx1ZSk7CisKKyAgICAvKioKKyAgICAgKiBQYXJrcyB0aGUgY2FsbGluZyB0aHJlYWQgZm9yIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIHRpbWUsCisgICAgICogdW5sZXNzIHRoZSAicGVybWl0IiBmb3IgdGhlIHRocmVhZCBpcyBhbHJlYWR5IGF2YWlsYWJsZSAoZHVlIHRvCisgICAgICogYSBwcmV2aW91cyBjYWxsIHRvIHtAbGluayAjdW5wYXJrfS4gVGhpcyBtZXRob2QgbWF5IGFsc28gcmV0dXJuCisgICAgICogc3B1cmlvdXNseSAodGhhdCBpcywgd2l0aG91dCB0aGUgdGhyZWFkIGJlaW5nIHRvbGQgdG8gdW5wYXJrCisgICAgICogYW5kIHdpdGhvdXQgdGhlIGluZGljYXRlZCBhbW91bnQgb2YgdGltZSBlbGFwc2luZykuCisgICAgICoKKyAgICAgKiA8cD5TZWUge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLkxvY2tTdXBwb3J0fSBmb3IgbW9yZQorICAgICAqIGluLWRlcHRoIGluZm9ybWF0aW9uIG9mIHRoZSBiZWhhdmlvciBvZiB0aGlzIG1ldGhvZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gYWJzb2x1dGUgd2hldGhlciB0aGUgZ2l2ZW4gdGltZSB2YWx1ZSBpcyBhYnNvbHV0ZQorICAgICAqIG1pbGxpc2Vjb25kcy1zaW5jZS10aGUtZXBvY2ggKDxjb2RlPnRydWU8L2NvZGU+KSBvciByZWxhdGl2ZQorICAgICAqIG5hbm9zZWNvbmRzLWZyb20tbm93ICg8Y29kZT5mYWxzZTwvY29kZT4pCisgICAgICogQHBhcmFtIHRpbWUgdGhlIChhYnNvbHV0ZSBtaWxsaXMgb3IgcmVsYXRpdmUgbmFub3MpIHRpbWUgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwYXJrKGJvb2xlYW4gYWJzb2x1dGUsIGxvbmcgdGltZSkgeworICAgICAgICBpZiAoYWJzb2x1dGUpIHsKKyAgICAgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkucGFya1VudGlsKHRpbWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5wYXJrRm9yKHRpbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVW5wYXJrcyB0aGUgZ2l2ZW4gb2JqZWN0LCB3aGljaCBtdXN0IGJlIGEge0BsaW5rIFRocmVhZH0uCisgICAgICoKKyAgICAgKiA8cD5TZWUge0BsaW5rIGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLkxvY2tTdXBwb3J0fSBmb3IgbW9yZQorICAgICAqIGluLWRlcHRoIGluZm9ybWF0aW9uIG9mIHRoZSBiZWhhdmlvciBvZiB0aGlzIG1ldGhvZC48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqIG5vbi1udWxsOyB0aGUgb2JqZWN0IHRvIHVucGFyaworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVucGFyayhPYmplY3Qgb2JqKSB7CisgICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBUaHJlYWQpIHsKKyAgICAgICAgICAgICgoVGhyZWFkKSBvYmopLnVucGFyaygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigidmFsaWQgZm9yIFRocmVhZHMgb25seSIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvQXN5bmNocm9ub3VzU29ja2V0Q2xvc2VNb25pdG9yLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL0FzeW5jaHJvbm91c1NvY2tldENsb3NlTW9uaXRvci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGNmYjhiYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL0FzeW5jaHJvbm91c1NvY2tldENsb3NlTW9uaXRvci5jcHAKQEAgLTAsMCArMSw5NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiQXN5bmNocm9ub3VzU29ja2V0Q2xvc2VNb25pdG9yIgorCisjaW5jbHVkZSAiQXN5bmNocm9ub3VzU29ja2V0Q2xvc2VNb25pdG9yLmgiCisjaW5jbHVkZSAiY3V0aWxzL2xvZy5oIgorCisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxzaWduYWwuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworLyoqCisgKiBXZSB1c2UgYW4gaW50cnVzaXZlIGRvdWJseS1saW5rZWQgbGlzdCB0byBrZWVwIHRyYWNrIG9mIGJsb2NrZWQgdGhyZWFkcy4KKyAqIFRoaXMgZ2l2ZXMgdXMgTygxKSBpbnNlcnRpb24gYW5kIHJlbW92YWwsIGFuZCBtZWFucyB3ZSBkb24ndCBuZWVkIHRvIGRvIGFueSBhbGxvY2F0aW9uLgorICogKFRoZSBvYmplY3RzIHRoZW1zZWx2ZXMgYXJlIHN0YWNrLWFsbG9jYXRlZC4pCisgKiBXYWtpbmcgcG90ZW50aWFsbHktYmxvY2tlZCB0aHJlYWRzIHdoZW4gYSBzb2NrZXQgaXMgY2xvc2VkIGlzIE8obikgaW4gdGhlIHRvdGFsIG51bWJlciBvZgorICogYmxvY2tlZCB0aHJlYWRzIChub3QgdGhlIG51bWJlciBvZiB0aHJlYWRzIGFjdHVhbGx5IGJsb2NrZWQgb24gdGhlIHNvY2tldCBpbiBxdWVzdGlvbikuCisgKiBGb3Igbm93IGF0IGxlYXN0LCB0aGlzIHNlZW1zIGxpa2UgYSBnb29kIGNvbXByb21pc2UgZm9yIEFuZHJvaWQuCisgKi8KK3N0YXRpYyBwdGhyZWFkX211dGV4X3QgYmxvY2tlZFRocmVhZExpc3RNdXRleCA9IFBUSFJFQURfTVVURVhfSU5JVElBTElaRVI7CitzdGF0aWMgQXN5bmNocm9ub3VzU29ja2V0Q2xvc2VNb25pdG9yKiBibG9ja2VkVGhyZWFkTGlzdCA9IE5VTEw7CisKKy8qKgorICogVGhlIHNwZWNpZmljIHNpZ25hbCBjaG9zZW4gaGVyZSBpcyBhcmJpdHJhcnkuCisgKi8KK3N0YXRpYyBjb25zdCBpbnQgQkxPQ0tFRF9USFJFQURfU0lHTkFMID0gU0lHUlRNSU4gKyAyOworCitzdGF0aWMgdm9pZCBibG9ja2VkVGhyZWFkU2lnbmFsSGFuZGxlcihpbnQgLypzaWduYWwqLykgeworICAgIC8vIERvIG5vdGhpbmcuIFdlIG9ubHkgc2VudCB0aGlzIHNpZ25hbCBmb3IgaXRzIHNpZGUtZWZmZWN0IG9mIGludGVycnVwdGluZyBzeXNjYWxscy4KK30KKwordm9pZCBBc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3I6OmluaXQoKSB7CisgICAgLy8gRW5zdXJlIHRoYXQgdGhlIHNpZ25hbCB3ZSBzZW5kIGludGVycnVwdHMgc3lzdGVtIGNhbGxzIGJ1dCBkb2Vzbid0IGtpbGwgdGhyZWFkcy4KKyAgICAvLyBVc2luZyBzaWdhY3Rpb24oMikgbGV0cyB1cyBlbnN1cmUgdGhhdCB0aGUgU0FfUkVTVEFSVCBmbGFnIGlzIG5vdCBzZXQuCisgICAgLy8gKFRoZSB3aG9sZSByZWFzb24gd2UncmUgc2VuZGluZyB0aGlzIHNpZ25hbCBpcyB0byB1bmJsb2NrIHN5c3RlbSBjYWxscyEpCisgICAgc3RydWN0IHNpZ2FjdGlvbiBzYTsKKyAgICBtZW1zZXQoJnNhLCAwLCBzaXplb2Yoc2EpKTsKKyAgICBzYS5zYV9oYW5kbGVyID0gYmxvY2tlZFRocmVhZFNpZ25hbEhhbmRsZXI7CisgICAgc2Euc2FfZmxhZ3MgPSAwOworICAgIGludCByYyA9IHNpZ2FjdGlvbihCTE9DS0VEX1RIUkVBRF9TSUdOQUwsICZzYSwgTlVMTCk7CisgICAgaWYgKHJjID09IC0xKSB7CisgICAgICAgIExPR0UoInNldHRpbmcgYmxvY2tlZCB0aHJlYWQgc2lnbmFsIGhhbmRsZXIgZmFpbGVkOiAlcyIsIHN0cmVycm9yKGVycm5vKSk7CisgICAgfQorfQorCit2b2lkIEFzeW5jaHJvbm91c1NvY2tldENsb3NlTW9uaXRvcjo6c2lnbmFsQmxvY2tlZFRocmVhZHMoaW50IGZkKSB7CisgICAgU2NvcGVkUHRocmVhZE11dGV4TG9jayBsb2NrKCZibG9ja2VkVGhyZWFkTGlzdE11dGV4KTsKKyAgICBmb3IgKEFzeW5jaHJvbm91c1NvY2tldENsb3NlTW9uaXRvciogaXQgPSBibG9ja2VkVGhyZWFkTGlzdDsgaXQgIT0gTlVMTDsgaXQgPSBpdC0+bU5leHQpIHsKKyAgICAgICAgaWYgKGl0LT5tRmQgPT0gZmQpIHsKKyAgICAgICAgICAgIHB0aHJlYWRfa2lsbChpdC0+bVRocmVhZCwgQkxPQ0tFRF9USFJFQURfU0lHTkFMKTsKKyAgICAgICAgICAgIC8vIEtlZXAgZ29pbmcsIGJlY2F1c2UgdGhlcmUgbWF5IGJlIG1vcmUgdGhhbiBvbmUgdGhyZWFkLi4uCisgICAgICAgIH0KKyAgICB9Cit9CisKK0FzeW5jaHJvbm91c1NvY2tldENsb3NlTW9uaXRvcjo6QXN5bmNocm9ub3VzU29ja2V0Q2xvc2VNb25pdG9yKGludCBmZCkgeworICAgIFNjb3BlZFB0aHJlYWRNdXRleExvY2sgbG9jaygmYmxvY2tlZFRocmVhZExpc3RNdXRleCk7CisgICAgLy8gV2hvIGFyZSB3ZSwgYW5kIHdoYXQgYXJlIHdlIHdhaXRpbmcgZm9yPworICAgIG1UaHJlYWQgPSBwdGhyZWFkX3NlbGYoKTsKKyAgICBtRmQgPSBmZDsKKyAgICAvLyBJbnNlcnQgb3Vyc2VsdmVzIGF0IHRoZSBoZWFkIG9mIHRoZSBpbnRydXNpdmUgZG91Ymx5LWxpbmtlZCBsaXN0Li4uCisgICAgbVByZXYgPSBOVUxMOworICAgIG1OZXh0ID0gYmxvY2tlZFRocmVhZExpc3Q7CisgICAgaWYgKG1OZXh0ICE9IE5VTEwpIHsKKyAgICAgICAgbU5leHQtPm1QcmV2ID0gdGhpczsKKyAgICB9CisgICAgYmxvY2tlZFRocmVhZExpc3QgPSB0aGlzOworfQorCitBc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3I6On5Bc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3IoKSB7CisgICAgU2NvcGVkUHRocmVhZE11dGV4TG9jayBsb2NrKCZibG9ja2VkVGhyZWFkTGlzdE11dGV4KTsKKyAgICAvLyBVbmxpbmsgb3Vyc2VsdmVzIGZyb20gdGhlIGludHJ1c2l2ZSBkb3VibHktbGlua2VkIGxpc3QuLi4KKyAgICBpZiAobU5leHQgIT0gTlVMTCkgeworICAgICAgICBtTmV4dC0+bVByZXYgPSBtUHJldjsKKyAgICB9CisgICAgaWYgKG1QcmV2ID09IE5VTEwpIHsKKyAgICAgICAgYmxvY2tlZFRocmVhZExpc3QgPSBtTmV4dDsKKyAgICB9IGVsc2UgeworICAgICAgICBtUHJldi0+bU5leHQgPSBtTmV4dDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS9Bc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3IuaCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL0FzeW5jaHJvbm91c1NvY2tldENsb3NlTW9uaXRvci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMzNzBlMjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9Bc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3IuaApAQCAtMCwwICsxLDYwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBBU1lOQ0hST05PVVNfU09DS0VUX0NMT1NFX01PTklUT1JfSF9pbmNsdWRlZAorI2RlZmluZSBBU1lOQ0hST05PVVNfU09DS0VUX0NMT1NFX01PTklUT1JfSF9pbmNsdWRlZAorCisjaW5jbHVkZSAiU2NvcGVkUHRocmVhZE11dGV4TG9jay5oIgorI2luY2x1ZGUgPHB0aHJlYWQuaD4KKworLyoqCisgKiBBc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3IgaGVscHMgaW1wbGVtZW50IEphdmEncyBhc3luY2hyb25vdXMgU29ja2V0LmNsb3NlIHNlbWFudGljcy4KKyAqCisgKiBBc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3I6OmluaXQgbXVzdCBiZSBjYWxsZWQgYmVmb3JlIGFueXRoaW5nIGVsc2UuCisgKgorICogRXZlcnkgYmxvY2tpbmcgbmV0d29yayBJL08gb3BlcmF0aW9uIG11c3QgYmUgc3Vycm91bmRlZCBieSBhbiBBc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3IKKyAqIGluc3RhbmNlLiBGb3IgZXhhbXBsZToKKyAqCisgKiAgIHsKKyAqICAgICBBc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3IgbW9uaXRvcihmZCk7CisgKiAgICAgYnl0ZUNvdW50ID0gOjpyZWFkKGZkLCBidWYsIHNpemVvZihidWYpKTsKKyAqICAgfQorICoKKyAqIFRvIGludGVycnVwdCBhbGwgdGhyZWFkcyBjdXJyZW50bHkgYmxvY2tlZCBvbiBmaWxlIGRlc2NyaXB0b3IgJ2ZkJywgY2FsbCBzaWduYWxCbG9ja2VkVGhyZWFkczoKKyAqCisgKiAgIEFzeW5jaHJvbm91c1NvY2tldENsb3NlTW9uaXRvcjo6c2lnbmFsQmxvY2tlZFRocmVhZHMoZmQpOworICovCitjbGFzcyBBc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3IgeworcHVibGljOgorICAgIEFzeW5jaHJvbm91c1NvY2tldENsb3NlTW9uaXRvcihpbnQgZmQpOworICAgIH5Bc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3IoKTsKKworICAgIHN0YXRpYyB2b2lkIGluaXQoKTsKKworICAgIHN0YXRpYyB2b2lkIHNpZ25hbEJsb2NrZWRUaHJlYWRzKGludCBmZCk7CisKK3ByaXZhdGU6CisgICAgQXN5bmNocm9ub3VzU29ja2V0Q2xvc2VNb25pdG9yKiBtUHJldjsKKyAgICBBc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3IqIG1OZXh0OworICAgIHB0aHJlYWRfdCBtVGhyZWFkOworICAgIGludCBtRmQ7CisKKyAgICAvLyBEaXNhbGxvdyBjb3B5IGFuZCBhc3NpZ25tZW50LgorICAgIEFzeW5jaHJvbm91c1NvY2tldENsb3NlTW9uaXRvcihjb25zdCBBc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3ImKTsKKyAgICB2b2lkIG9wZXJhdG9yPShjb25zdCBBc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3ImKTsKK307CisKKyNlbmRpZiAgLy8gQVNZTkNIUk9OT1VTX1NPQ0tFVF9DTE9TRV9NT05JVE9SX0hfaW5jbHVkZWQKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL0puaUNvbnN0YW50cy5jcHAgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9KbmlDb25zdGFudHMuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMwOWY1NTkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9KbmlDb25zdGFudHMuY3BwCkBAIC0wLDAgKzEsMTE2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2luY2x1ZGUgIkpuaUNvbnN0YW50cy5oIgorI2luY2x1ZGUgIlNjb3BlZExvY2FsUmVmLmgiCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKworamNsYXNzIEpuaUNvbnN0YW50czo6YmlkaVJ1bkNsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6YmlnRGVjaW1hbENsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6Ym9vbGVhbkNsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6Ynl0ZUFycmF5Q2xhc3M7CitqY2xhc3MgSm5pQ29uc3RhbnRzOjpieXRlQ2xhc3M7CitqY2xhc3MgSm5pQ29uc3RhbnRzOjpjaGFyc2V0SUNVQ2xhc3M7CitqY2xhc3MgSm5pQ29uc3RhbnRzOjpjb25zdHJ1Y3RvckNsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6ZGVmbGF0ZXJDbGFzczsKK2pjbGFzcyBKbmlDb25zdGFudHM6OmRvdWJsZUNsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6ZXJybm9FeGNlcHRpb25DbGFzczsKK2pjbGFzcyBKbmlDb25zdGFudHM6OmZpZWxkQ2xhc3M7CitqY2xhc3MgSm5pQ29uc3RhbnRzOjpmaWVsZFBvc2l0aW9uSXRlcmF0b3JDbGFzczsKK2pjbGFzcyBKbmlDb25zdGFudHM6OmZpbGVEZXNjcmlwdG9yQ2xhc3M7CitqY2xhc3MgSm5pQ29uc3RhbnRzOjpnYWlFeGNlcHRpb25DbGFzczsKK2pjbGFzcyBKbmlDb25zdGFudHM6OmluZXQ2QWRkcmVzc0NsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6aW5ldEFkZHJlc3NDbGFzczsKK2pjbGFzcyBKbmlDb25zdGFudHM6OmluZXRTb2NrZXRBZGRyZXNzQ2xhc3M7CitqY2xhc3MgSm5pQ29uc3RhbnRzOjppbmZsYXRlckNsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6aW50ZWdlckNsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6bG9jYWxlRGF0YUNsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6bG9uZ0NsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6bWV0aG9kQ2xhc3M7CitqY2xhc3MgSm5pQ29uc3RhbnRzOjptdXRhYmxlSW50Q2xhc3M7CitqY2xhc3MgSm5pQ29uc3RhbnRzOjptdXRhYmxlTG9uZ0NsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6cGFyc2VQb3NpdGlvbkNsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6cGF0dGVyblN5bnRheEV4Y2VwdGlvbkNsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6cmVhbFRvU3RyaW5nQ2xhc3M7CitqY2xhc3MgSm5pQ29uc3RhbnRzOjpzb2NrZXRDbGFzczsKK2pjbGFzcyBKbmlDb25zdGFudHM6OnNvY2tldEltcGxDbGFzczsKK2pjbGFzcyBKbmlDb25zdGFudHM6OnN0cmluZ0FycmF5Q2xhc3M7CitqY2xhc3MgSm5pQ29uc3RhbnRzOjpzdHJpbmdDbGFzczsKK2pjbGFzcyBKbmlDb25zdGFudHM6OnN0cnVjdEFkZHJpbmZvQ2xhc3M7CitqY2xhc3MgSm5pQ29uc3RhbnRzOjpzdHJ1Y3RGbG9ja0NsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6c3RydWN0R3JvdXBSZXFDbGFzczsKK2pjbGFzcyBKbmlDb25zdGFudHM6OnN0cnVjdExpbmdlckNsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6c3RydWN0UGFzc3dkQ2xhc3M7CitqY2xhc3MgSm5pQ29uc3RhbnRzOjpzdHJ1Y3RQb2xsZmRDbGFzczsKK2pjbGFzcyBKbmlDb25zdGFudHM6OnN0cnVjdFN0YXRDbGFzczsKK2pjbGFzcyBKbmlDb25zdGFudHM6OnN0cnVjdFN0YXRGc0NsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6c3RydWN0VGltZXZhbENsYXNzOworamNsYXNzIEpuaUNvbnN0YW50czo6c3RydWN0VXRzbmFtZUNsYXNzOworCitzdGF0aWMgamNsYXNzIGZpbmRDbGFzcyhKTklFbnYqIGVudiwgY29uc3QgY2hhciogbmFtZSkgeworICAgIFNjb3BlZExvY2FsUmVmPGpjbGFzcz4gbG9jYWxDbGFzcyhlbnYsIGVudi0+RmluZENsYXNzKG5hbWUpKTsKKyAgICBqY2xhc3MgcmVzdWx0ID0gcmVpbnRlcnByZXRfY2FzdDxqY2xhc3M+KGVudi0+TmV3R2xvYmFsUmVmKGxvY2FsQ2xhc3MuZ2V0KCkpKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKyAgICAgICAgTE9HRSgiZmFpbGVkIHRvIGZpbmQgY2xhc3MgJyVzJyIsIG5hbWUpOworICAgICAgICBhYm9ydCgpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworfQorCit2b2lkIEpuaUNvbnN0YW50czo6aW5pdChKTklFbnYqIGVudikgeworICAgIGJpZGlSdW5DbGFzcyA9IGZpbmRDbGFzcyhlbnYsICJqYXZhL3RleHQvQmlkaSRSdW4iKTsKKyAgICBiaWdEZWNpbWFsQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAiamF2YS9tYXRoL0JpZ0RlY2ltYWwiKTsKKyAgICBib29sZWFuQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAiamF2YS9sYW5nL0Jvb2xlYW4iKTsKKyAgICBieXRlQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAiamF2YS9sYW5nL0J5dGUiKTsKKyAgICBieXRlQXJyYXlDbGFzcyA9IGZpbmRDbGFzcyhlbnYsICJbQiIpOworICAgIGNoYXJzZXRJQ1VDbGFzcyA9IGZpbmRDbGFzcyhlbnYsICJqYXZhL25pby9jaGFyc2V0L0NoYXJzZXRJQ1UiKTsKKyAgICBjb25zdHJ1Y3RvckNsYXNzID0gZmluZENsYXNzKGVudiwgImphdmEvbGFuZy9yZWZsZWN0L0NvbnN0cnVjdG9yIik7CisgICAgZGVmbGF0ZXJDbGFzcyA9IGZpbmRDbGFzcyhlbnYsICJqYXZhL3V0aWwvemlwL0RlZmxhdGVyIik7CisgICAgZG91YmxlQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAiamF2YS9sYW5nL0RvdWJsZSIpOworICAgIGVycm5vRXhjZXB0aW9uQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAibGliY29yZS9pby9FcnJub0V4Y2VwdGlvbiIpOworICAgIGZpZWxkQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAiamF2YS9sYW5nL3JlZmxlY3QvRmllbGQiKTsKKyAgICBmaWVsZFBvc2l0aW9uSXRlcmF0b3JDbGFzcyA9IGZpbmRDbGFzcyhlbnYsICJsaWJjb3JlL2ljdS9OYXRpdmVEZWNpbWFsRm9ybWF0JEZpZWxkUG9zaXRpb25JdGVyYXRvciIpOworICAgIGZpbGVEZXNjcmlwdG9yQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAiamF2YS9pby9GaWxlRGVzY3JpcHRvciIpOworICAgIGdhaUV4Y2VwdGlvbkNsYXNzID0gZmluZENsYXNzKGVudiwgImxpYmNvcmUvaW8vR2FpRXhjZXB0aW9uIik7CisgICAgaW5ldDZBZGRyZXNzQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAiamF2YS9uZXQvSW5ldDZBZGRyZXNzIik7CisgICAgaW5ldEFkZHJlc3NDbGFzcyA9IGZpbmRDbGFzcyhlbnYsICJqYXZhL25ldC9JbmV0QWRkcmVzcyIpOworICAgIGluZXRTb2NrZXRBZGRyZXNzQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAiamF2YS9uZXQvSW5ldFNvY2tldEFkZHJlc3MiKTsKKyAgICBpbmZsYXRlckNsYXNzID0gZmluZENsYXNzKGVudiwgImphdmEvdXRpbC96aXAvSW5mbGF0ZXIiKTsKKyAgICBpbnRlZ2VyQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAiamF2YS9sYW5nL0ludGVnZXIiKTsKKyAgICBsb2NhbGVEYXRhQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAibGliY29yZS9pY3UvTG9jYWxlRGF0YSIpOworICAgIGxvbmdDbGFzcyA9IGZpbmRDbGFzcyhlbnYsICJqYXZhL2xhbmcvTG9uZyIpOworICAgIG1ldGhvZENsYXNzID0gZmluZENsYXNzKGVudiwgImphdmEvbGFuZy9yZWZsZWN0L01ldGhvZCIpOworICAgIG11dGFibGVJbnRDbGFzcyA9IGZpbmRDbGFzcyhlbnYsICJsaWJjb3JlL3V0aWwvTXV0YWJsZUludCIpOworICAgIG11dGFibGVMb25nQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAibGliY29yZS91dGlsL011dGFibGVMb25nIik7CisgICAgcGFyc2VQb3NpdGlvbkNsYXNzID0gZmluZENsYXNzKGVudiwgImphdmEvdGV4dC9QYXJzZVBvc2l0aW9uIik7CisgICAgcGF0dGVyblN5bnRheEV4Y2VwdGlvbkNsYXNzID0gZmluZENsYXNzKGVudiwgImphdmEvdXRpbC9yZWdleC9QYXR0ZXJuU3ludGF4RXhjZXB0aW9uIik7CisgICAgcmVhbFRvU3RyaW5nQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAiamF2YS9sYW5nL1JlYWxUb1N0cmluZyIpOworICAgIHNvY2tldENsYXNzID0gZmluZENsYXNzKGVudiwgImphdmEvbmV0L1NvY2tldCIpOworICAgIHNvY2tldEltcGxDbGFzcyA9IGZpbmRDbGFzcyhlbnYsICJqYXZhL25ldC9Tb2NrZXRJbXBsIik7CisgICAgc3RyaW5nQXJyYXlDbGFzcyA9IGZpbmRDbGFzcyhlbnYsICJbTGphdmEvbGFuZy9TdHJpbmc7Iik7CisgICAgc3RyaW5nQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAiamF2YS9sYW5nL1N0cmluZyIpOworICAgIHN0cnVjdEFkZHJpbmZvQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAibGliY29yZS9pby9TdHJ1Y3RBZGRyaW5mbyIpOworICAgIHN0cnVjdEZsb2NrQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAibGliY29yZS9pby9TdHJ1Y3RGbG9jayIpOworICAgIHN0cnVjdEdyb3VwUmVxQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAibGliY29yZS9pby9TdHJ1Y3RHcm91cFJlcSIpOworICAgIHN0cnVjdExpbmdlckNsYXNzID0gZmluZENsYXNzKGVudiwgImxpYmNvcmUvaW8vU3RydWN0TGluZ2VyIik7CisgICAgc3RydWN0UGFzc3dkQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAibGliY29yZS9pby9TdHJ1Y3RQYXNzd2QiKTsKKyAgICBzdHJ1Y3RQb2xsZmRDbGFzcyA9IGZpbmRDbGFzcyhlbnYsICJsaWJjb3JlL2lvL1N0cnVjdFBvbGxmZCIpOworICAgIHN0cnVjdFN0YXRDbGFzcyA9IGZpbmRDbGFzcyhlbnYsICJsaWJjb3JlL2lvL1N0cnVjdFN0YXQiKTsKKyAgICBzdHJ1Y3RTdGF0RnNDbGFzcyA9IGZpbmRDbGFzcyhlbnYsICJsaWJjb3JlL2lvL1N0cnVjdFN0YXRGcyIpOworICAgIHN0cnVjdFRpbWV2YWxDbGFzcyA9IGZpbmRDbGFzcyhlbnYsICJsaWJjb3JlL2lvL1N0cnVjdFRpbWV2YWwiKTsKKyAgICBzdHJ1Y3RVdHNuYW1lQ2xhc3MgPSBmaW5kQ2xhc3MoZW52LCAibGliY29yZS9pby9TdHJ1Y3RVdHNuYW1lIik7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS9KbmlDb25zdGFudHMuaCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL0puaUNvbnN0YW50cy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiNTI3NzUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9KbmlDb25zdGFudHMuaApAQCAtMCwwICsxLDg5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBKTklfQ09OU1RBTlRTX0hfaW5jbHVkZWQKKyNkZWZpbmUgSk5JX0NPTlNUQU5UU19IX2luY2x1ZGVkCisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisKKy8qKgorICogQSBjYWNoZSB0byBhdm9pZCBjYWxsaW5nIEZpbmRDbGFzcyBhdCBydW50aW1lLgorICoKKyAqIENsYXNzIGxvb2t1cCBpcyByZWxhdGl2ZWx5IGV4cGVuc2l2ZSAoMi41dXMgb24gcGFzc2lvbi1lbmcgYXQgdGhlIHRpbWUgb2Ygd3JpdGluZyksIHNvIHdlIGRvCisgKiBhbGwgc3VjaCBsb29rdXBzIGVhZ2VybHkgYXQgVk0gc3RhcnR1cC4gVGhpcyBtZWFucyB0aGF0IGNvZGUgdGhhdCBuZXZlciB1c2VzLCBzYXksCisgKiBqYXZhLnV0aWwuemlwLkRlZmxhdGVyIHN0aWxsIGhhcyB0byBwYXkgZm9yIHRoZSBsb29rdXAsIGJ1dCBpdCBtZWFucyB0aGF0IG9uIGEgZGV2aWNlIHRoZSBjb3N0CisgKiBpcyBkZWZpbml0ZWx5IHBhaWQgZHVyaW5nIGJvb3QgYW5kIGFtb3J0aXplZC4gQSBjZW50cmFsIGNhY2hlIGFsc28gcmVtb3ZlcyB0aGUgdGVtcHRhdGlvbiB0bworICogZHluYW1pY2FsbHkgY2FsbCBGaW5kQ2xhc3MgcmF0aGVyIHRoYW4gYWRkIGEgc21hbGwgY2FjaGUgdG8gZWFjaCBmaWxlIHRoYXQgbmVlZHMgb25lLiBBbm90aGVyCisgKiBjb3N0IGlzIHRoYXQgZWFjaCBjbGFzcyBjYWNoZWQgaGVyZSByZXF1aXJlcyBhIGdsb2JhbCByZWZlcmVuY2UsIHRob3VnaCBpbiBwcmFjdGljZSB3ZSBzYXZlCisgKiBlbm91Z2ggYnkgbm90IGhhdmluZyBhIGdsb2JhbCByZWZlcmVuY2UgZm9yIGVhY2ggZmlsZSB0aGF0IHVzZXMgYSBjbGFzcyBzdWNoIGFzIGphdmEubGFuZy5TdHJpbmcKKyAqIHdoaWNoIGlzIHVzZWQgaW4gc2V2ZXJhbCBmaWxlcy4KKyAqCisgKiBGaW5kQ2xhc3MgaXMgc3RpbGwgY2FsbGVkIGluIGEgY291cGxlIG9mIHNpdHVhdGlvbnM6IHdoZW4gdGhyb3dpbmcgZXhjZXB0aW9ucywgYW5kIGluIHNvbWUgb2YKKyAqIHRoZSBzZXJpYWxpemF0aW9uIGNvZGUuIFRoZSBmb3JtZXIgaXMgY2xlYXJseSBub3QgYSBwZXJmb3JtYW5jZSBjYXNlLCBhbmQgd2UncmUgY3VycmVudGx5CisgKiBhc3N1bWluZyB0aGF0IG5laXRoZXIgaXMgdGhlIGxhdHRlci4KKyAqCisgKiBUT0RPOiBzaW1pbGFyIGFyZ3VtZW50cyBob2xkIGZvciBmaWVsZCBhbmQgbWV0aG9kIElEczsgd2Ugc2hvdWxkIGNhY2hlIHRoZW0gY2VudHJhbGx5IHRvby4KKyAqLworc3RydWN0IEpuaUNvbnN0YW50cyB7CisgICAgc3RhdGljIHZvaWQgaW5pdChKTklFbnYqIGVudik7CisKKyAgICBzdGF0aWMgamNsYXNzIGJpZGlSdW5DbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIGJpZ0RlY2ltYWxDbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIGJvb2xlYW5DbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIGJ5dGVBcnJheUNsYXNzOworICAgIHN0YXRpYyBqY2xhc3MgYnl0ZUNsYXNzOworICAgIHN0YXRpYyBqY2xhc3MgY2hhcnNldElDVUNsYXNzOworICAgIHN0YXRpYyBqY2xhc3MgY29uc3RydWN0b3JDbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIGRlZmxhdGVyQ2xhc3M7CisgICAgc3RhdGljIGpjbGFzcyBkb3VibGVDbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIGVycm5vRXhjZXB0aW9uQ2xhc3M7CisgICAgc3RhdGljIGpjbGFzcyBmaWVsZENsYXNzOworICAgIHN0YXRpYyBqY2xhc3MgZmllbGRQb3NpdGlvbkl0ZXJhdG9yQ2xhc3M7CisgICAgc3RhdGljIGpjbGFzcyBmaWxlRGVzY3JpcHRvckNsYXNzOworICAgIHN0YXRpYyBqY2xhc3MgZ2FpRXhjZXB0aW9uQ2xhc3M7CisgICAgc3RhdGljIGpjbGFzcyBpbmV0NkFkZHJlc3NDbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIGluZXRBZGRyZXNzQ2xhc3M7CisgICAgc3RhdGljIGpjbGFzcyBpbmV0U29ja2V0QWRkcmVzc0NsYXNzOworICAgIHN0YXRpYyBqY2xhc3MgaW5mbGF0ZXJDbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIGludGVnZXJDbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIGxvY2FsZURhdGFDbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIGxvbmdDbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIG1ldGhvZENsYXNzOworICAgIHN0YXRpYyBqY2xhc3MgbXV0YWJsZUludENsYXNzOworICAgIHN0YXRpYyBqY2xhc3MgbXV0YWJsZUxvbmdDbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIHBhcnNlUG9zaXRpb25DbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIHBhdHRlcm5TeW50YXhFeGNlcHRpb25DbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIHJlYWxUb1N0cmluZ0NsYXNzOworICAgIHN0YXRpYyBqY2xhc3Mgc29ja2V0Q2xhc3M7CisgICAgc3RhdGljIGpjbGFzcyBzb2NrZXRJbXBsQ2xhc3M7CisgICAgc3RhdGljIGpjbGFzcyBzdHJpbmdBcnJheUNsYXNzOworICAgIHN0YXRpYyBqY2xhc3Mgc3RyaW5nQ2xhc3M7CisgICAgc3RhdGljIGpjbGFzcyBzdHJ1Y3RBZGRyaW5mb0NsYXNzOworICAgIHN0YXRpYyBqY2xhc3Mgc3RydWN0RmxvY2tDbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIHN0cnVjdEdyb3VwUmVxQ2xhc3M7CisgICAgc3RhdGljIGpjbGFzcyBzdHJ1Y3RMaW5nZXJDbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIHN0cnVjdFBhc3N3ZENsYXNzOworICAgIHN0YXRpYyBqY2xhc3Mgc3RydWN0UG9sbGZkQ2xhc3M7CisgICAgc3RhdGljIGpjbGFzcyBzdHJ1Y3RTdGF0Q2xhc3M7CisgICAgc3RhdGljIGpjbGFzcyBzdHJ1Y3RTdGF0RnNDbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIHN0cnVjdFRpbWV2YWxDbGFzczsKKyAgICBzdGF0aWMgamNsYXNzIHN0cnVjdFV0c25hbWVDbGFzczsKK307CisKKyNkZWZpbmUgTkFUSVZFX01FVEhPRChjbGFzc05hbWUsIGZ1bmN0aW9uTmFtZSwgc2lnbmF0dXJlKSBcCisgICAgeyAjZnVuY3Rpb25OYW1lLCBzaWduYXR1cmUsIHJlaW50ZXJwcmV0X2Nhc3Q8dm9pZCo+KGNsYXNzTmFtZSAjIyBfICMjIGZ1bmN0aW9uTmFtZSkgfQorCisjZW5kaWYgIC8vIEpOSV9DT05TVEFOVFNfSF9pbmNsdWRlZApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvSm5pRXhjZXB0aW9uLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL0puaUV4Y2VwdGlvbi5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjYyNjQ0OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL0puaUV4Y2VwdGlvbi5jcHAKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpbmNsdWRlICJKbmlFeGNlcHRpb24uaCIKKyNpbmNsdWRlICJKTklIZWxwLmgiCisKK2Jvb2wgbWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihKTklFbnYqIGVudiwgVUVycm9yQ29kZSBlcnJvcikgeworICAgIGlmIChVX1NVQ0NFU1MoZXJyb3IpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgY29uc3QgY2hhciogbWVzc2FnZSA9IHVfZXJyb3JOYW1lKGVycm9yKTsKKyAgICBzd2l0Y2ggKGVycm9yKSB7CisgICAgY2FzZSBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1I6CisgICAgICAgIHJldHVybiBqbmlUaHJvd0V4Y2VwdGlvbihlbnYsICJqYXZhL2xhbmcvSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIiwgbWVzc2FnZSk7CisgICAgY2FzZSBVX0lOREVYX09VVE9GQk9VTkRTX0VSUk9SOgorICAgIGNhc2UgVV9CVUZGRVJfT1ZFUkZMT1dfRVJST1I6CisgICAgICAgIHJldHVybiBqbmlUaHJvd0V4Y2VwdGlvbihlbnYsICJqYXZhL2xhbmcvQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIiwgbWVzc2FnZSk7CisgICAgY2FzZSBVX1VOU1VQUE9SVEVEX0VSUk9SOgorICAgICAgICByZXR1cm4gam5pVGhyb3dFeGNlcHRpb24oZW52LCAiamF2YS9sYW5nL1Vuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIiwgbWVzc2FnZSk7CisgICAgZGVmYXVsdDoKKyAgICAgICAgcmV0dXJuIGpuaVRocm93UnVudGltZUV4Y2VwdGlvbihlbnYsIG1lc3NhZ2UpOworICAgIH0KK30KKwordm9pZCBqbmlUaHJvd0V4Y2VwdGlvbldpdGhFcnJubyhKTklFbnYqIGVudiwgY29uc3QgY2hhciogZXhjZXB0aW9uQ2xhc3NOYW1lLCBpbnQgZXJyb3IpIHsKKyAgICBjaGFyIGJ1ZltCVUZTSVpdOworICAgIGpuaVRocm93RXhjZXB0aW9uKGVudiwgZXhjZXB0aW9uQ2xhc3NOYW1lLCBqbmlTdHJFcnJvcihlcnJvciwgYnVmLCBzaXplb2YoYnVmKSkpOworfQorCit2b2lkIGpuaVRocm93T3V0T2ZNZW1vcnlFcnJvcihKTklFbnYqIGVudiwgY29uc3QgY2hhciogbWVzc2FnZSkgeworICAgIGpuaVRocm93RXhjZXB0aW9uKGVudiwgImphdmEvbGFuZy9PdXRPZk1lbW9yeUVycm9yIiwgbWVzc2FnZSk7Cit9CisKK3ZvaWQgam5pVGhyb3dTb2NrZXRFeGNlcHRpb24oSk5JRW52KiBlbnYsIGludCBlcnJvcikgeworICAgIGpuaVRocm93RXhjZXB0aW9uV2l0aEVycm5vKGVudiwgImphdmEvbmV0L1NvY2tldEV4Y2VwdGlvbiIsIGVycm9yKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL0puaUV4Y2VwdGlvbi5oIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvSm5pRXhjZXB0aW9uLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjM0NDdkMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL0puaUV4Y2VwdGlvbi5oCkBAIC0wLDAgKzEsMzAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaWZuZGVmIEpOSV9FWENFUFRJT05fSF9pbmNsdWRlZAorI2RlZmluZSBKTklfRVhDRVBUSU9OX0hfaW5jbHVkZWQKKworI2luY2x1ZGUgImpuaS5oIgorI2luY2x1ZGUgInVuaWNvZGUvdXR5cGVzLmgiIC8vIEZvciBVRXJyb3JDb2RlLgorCit2b2lkIGpuaVRocm93RXhjZXB0aW9uV2l0aEVycm5vKEpOSUVudiogZW52LCBjb25zdCBjaGFyKiBleGNlcHRpb25DbGFzc05hbWUsIGludCBlcnJvcik7CisKK3ZvaWQgam5pVGhyb3dPdXRPZk1lbW9yeUVycm9yKEpOSUVudiogZW52LCBjb25zdCBjaGFyKiBtZXNzYWdlKTsKK3ZvaWQgam5pVGhyb3dTb2NrZXRFeGNlcHRpb24oSk5JRW52KiBlbnYsIGludCBlcnJvcik7CisKK2Jvb2wgbWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihKTklFbnYqIGVudiwgVUVycm9yQ29kZSBlcnJvcik7CisKKyNlbmRpZiAgLy8gSk5JX0VYQ0VQVElPTl9IX2luY2x1ZGVkCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS9OZXRGZC5oIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvTmV0RmQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMzViMDU3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvTmV0RmQuaApAQCAtMCwwICsxLDcwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2lmbmRlZiBORVRfRkRfSF9pbmNsdWRlZAorI2RlZmluZSBORVRfRkRfSF9pbmNsdWRlZAorCisvKioKKyAqIFdyYXBzIGFjY2VzcyB0byB0aGUgaW50IGluc2lkZSBhIGphdmEuaW8uRmlsZURlc2NyaXB0b3IsIHRha2luZyBjYXJlIG9mIHRocm93aW5nIGV4Y2VwdGlvbnMuCisgKi8KK2NsYXNzIE5ldEZkIHsKK3B1YmxpYzoKKyAgICBOZXRGZChKTklFbnYqIGVudiwgam9iamVjdCBmaWxlRGVzY3JpcHRvcikKKyAgICAgICAgOiBtRW52KGVudiksIG1GaWxlRGVzY3JpcHRvcihmaWxlRGVzY3JpcHRvciksIG1GZCgtMSkKKyAgICB7CisgICAgfQorCisgICAgYm9vbCBpc0Nsb3NlZCgpIHsKKyAgICAgICAgbUZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IobUVudiwgbUZpbGVEZXNjcmlwdG9yKTsKKyAgICAgICAgYm9vbCBjbG9zZWQgPSAobUZkID09IC0xKTsKKyAgICAgICAgaWYgKGNsb3NlZCkgeworICAgICAgICAgICAgam5pVGhyb3dFeGNlcHRpb24obUVudiwgImphdmEvbmV0L1NvY2tldEV4Y2VwdGlvbiIsICJTb2NrZXQgY2xvc2VkIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNsb3NlZDsKKyAgICB9CisKKyAgICBpbnQgZ2V0KCkgY29uc3QgeworICAgICAgICByZXR1cm4gbUZkOworICAgIH0KKworcHJpdmF0ZToKKyAgICBKTklFbnYqIG1FbnY7CisgICAgam9iamVjdCBtRmlsZURlc2NyaXB0b3I7CisgICAgaW50IG1GZDsKKworICAgIC8vIERpc2FsbG93IGNvcHkgYW5kIGFzc2lnbm1lbnQuCisgICAgTmV0RmQoY29uc3QgTmV0RmQmKTsKKyAgICB2b2lkIG9wZXJhdG9yPShjb25zdCBOZXRGZCYpOworfTsKKworLyoqCisgKiBVc2VkIHRvIHJldHJ5IHN5c2NhbGxzIHRoYXQgY2FuIHJldHVybiBFSU5UUi4gVGhpcyBkaWZmZXJzIGZyb20gVEVNUF9GQUlMVVJFX1JFVFJZIGluIHRoYXQKKyAqIGl0IGFsc28gY29uc2lkZXJzIHRoZSBjYXNlIHdoZXJlIHRoZSByZWFzb24gZm9yIGZhaWx1cmUgaXMgdGhhdCBhbm90aGVyIHRocmVhZCBjYWxsZWQKKyAqIFNvY2tldC5jbG9zZS4KKyAqLworI2RlZmluZSBORVRfRkFJTFVSRV9SRVRSWShmZCwgZXhwKSAoeyAgICAgICAgICAgICAgIFwKKyAgICB0eXBlb2YgKGV4cCkgX3JjOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZG8geyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBfcmMgPSAoZXhwKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgaWYgKF9yYyA9PSAtMSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBpZiAoZmQuaXNDbG9zZWQoKSB8fCBlcnJubyAhPSBFSU5UUikgeyAgXAorICAgICAgICAgICAgICAgIGJyZWFrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gd2hpbGUgKF9yYyA9PSAtMSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBfcmM7IH0pCisKKyNlbmRpZiAvLyBORVRfRkRfSF9pbmNsdWRlZApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvTmV0d29ya1V0aWxpdGllcy5jcHAgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9OZXR3b3JrVXRpbGl0aWVzLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYjViODQwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvTmV0d29ya1V0aWxpdGllcy5jcHAKQEAgLTAsMCArMSwxNzggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIk5ldHdvcmtVdGlsaXRpZXMiCisKKyNpbmNsdWRlICJOZXR3b3JrVXRpbGl0aWVzLmgiCisjaW5jbHVkZSAiSk5JSGVscC5oIgorI2luY2x1ZGUgIkpuaUNvbnN0YW50cy5oIgorI2luY2x1ZGUgIlNjb3BlZExvY2FsUmVmLmgiCisKKyNpbmNsdWRlIDxhcnBhL2luZXQuaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8c3lzL3NvY2tldC5oPgorCitqb2JqZWN0IHNvY2thZGRyVG9JbmV0QWRkcmVzcyhKTklFbnYqIGVudiwgY29uc3Qgc29ja2FkZHJfc3RvcmFnZSogc3MsIGppbnQqIHBvcnQpIHsKKyAgICAvLyBDb252ZXJ0IElQdjQtbWFwcGVkIElQdjYgYWRkcmVzc2VzIHRvIElQdjQgYWRkcmVzc2VzLgorICAgIC8vIFRoZSBSSSBzdGF0ZXMgIkphdmEgd2lsbCBuZXZlciByZXR1cm4gYW4gSVB2NC1tYXBwZWQgYWRkcmVzcyIuCisgICAgc29ja2FkZHJfc3RvcmFnZSB0bXA7CisgICAgbWVtc2V0KCZ0bXAsIDAsIHNpemVvZih0bXApKTsKKyAgICBjb25zdCBzb2NrYWRkcl9pbjYqIHNpbjYgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHNvY2thZGRyX2luNio+KHNzKTsKKyAgICBpZiAoc3MtPnNzX2ZhbWlseSA9PSBBRl9JTkVUNiAmJiBJTjZfSVNfQUREUl9WNE1BUFBFRCgmc2luNi0+c2luNl9hZGRyKSkgeworICAgICAgICAvLyBDb3B5IHRoZSBJUHY2IGFkZHJlc3MgaW50byB0aGUgdGVtcG9yYXJ5IHNvY2thZGRyX3N0b3JhZ2UuCisgICAgICAgIG1lbWNweSgmdG1wLCBzcywgc2l6ZW9mKHRtcCkpOworICAgICAgICAvLyBVbm1hcCBpdCBpbnRvIGFuIElQdjQgYWRkcmVzcy4KKyAgICAgICAgc29ja2FkZHJfaW4qIHNpbiA9IHJlaW50ZXJwcmV0X2Nhc3Q8c29ja2FkZHJfaW4qPigmdG1wKTsKKyAgICAgICAgc2luLT5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKKyAgICAgICAgc2luLT5zaW5fcG9ydCA9IHNpbjYtPnNpbjZfcG9ydDsKKyAgICAgICAgbWVtY3B5KCZzaW4tPnNpbl9hZGRyLnNfYWRkciwgJnNpbjYtPnNpbjZfYWRkci5zNl9hZGRyWzEyXSwgNCk7CisgICAgICAgIC8vIEZhbGwgdGhyb3VnaCBpbnRvIHRoZSByZWd1bGFyIGNvbnZlcnNpb24gdXNpbmcgdGhlIHVubWFwcGVkIGFkZHJlc3MuCisgICAgICAgIHNzID0gJnRtcDsKKyAgICB9CisKKyAgICBjb25zdCB2b2lkKiByYXdBZGRyZXNzOworICAgIHNpemVfdCBhZGRyZXNzTGVuZ3RoOworICAgIGludCBzaW5fcG9ydDsKKyAgICBpbnQgc2NvcGVfaWQgPSAwOworICAgIGlmIChzcy0+c3NfZmFtaWx5ID09IEFGX0lORVQpIHsKKyAgICAgICAgY29uc3Qgc29ja2FkZHJfaW4qIHNpbiA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3Qgc29ja2FkZHJfaW4qPihzcyk7CisgICAgICAgIHJhd0FkZHJlc3MgPSAmc2luLT5zaW5fYWRkci5zX2FkZHI7CisgICAgICAgIGFkZHJlc3NMZW5ndGggPSA0OworICAgICAgICBzaW5fcG9ydCA9IG50b2hzKHNpbi0+c2luX3BvcnQpOworICAgIH0gZWxzZSBpZiAoc3MtPnNzX2ZhbWlseSA9PSBBRl9JTkVUNikgeworICAgICAgICBjb25zdCBzb2NrYWRkcl9pbjYqIHNpbjYgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHNvY2thZGRyX2luNio+KHNzKTsKKyAgICAgICAgcmF3QWRkcmVzcyA9ICZzaW42LT5zaW42X2FkZHIuczZfYWRkcjsKKyAgICAgICAgYWRkcmVzc0xlbmd0aCA9IDE2OworICAgICAgICBzaW5fcG9ydCA9IG50b2hzKHNpbjYtPnNpbjZfcG9ydCk7CisgICAgICAgIHNjb3BlX2lkID0gc2luNi0+c2luNl9zY29wZV9pZDsKKyAgICB9IGVsc2UgeworICAgICAgICAvLyBXZSBjYW4ndCB0aHJvdyBTb2NrZXRFeGNlcHRpb24uIFdlIGFyZW4ndCBtZWFudCB0byBzZWUgYmFkIGFkZHJlc3Nlcywgc28gc2VlaW5nIG9uZQorICAgICAgICAvLyByZWFsbHkgZG9lcyBpbXBseSBhbiBpbnRlcm5hbCBlcnJvci4KKyAgICAgICAgam5pVGhyb3dFeGNlcHRpb25GbXQoZW52LCAiamF2YS9sYW5nL0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIsCisgICAgICAgICAgICAgICAgInNvY2thZGRyVG9JbmV0QWRkcmVzcyBiYWQgc3NfZmFtaWx5OiAlaSIsIHNzLT5zc19mYW1pbHkpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKHBvcnQgIT0gTlVMTCkgeworICAgICAgICAqcG9ydCA9IHNpbl9wb3J0OworICAgIH0KKworICAgIFNjb3BlZExvY2FsUmVmPGpieXRlQXJyYXk+IGJ5dGVBcnJheShlbnYsIGVudi0+TmV3Qnl0ZUFycmF5KGFkZHJlc3NMZW5ndGgpKTsKKyAgICBpZiAoYnl0ZUFycmF5LmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGVudi0+U2V0Qnl0ZUFycmF5UmVnaW9uKGJ5dGVBcnJheS5nZXQoKSwgMCwgYWRkcmVzc0xlbmd0aCwKKyAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgamJ5dGUqPihyYXdBZGRyZXNzKSk7CisKKyAgICBzdGF0aWMgam1ldGhvZElEIGdldEJ5QWRkcmVzc01ldGhvZCA9IGVudi0+R2V0U3RhdGljTWV0aG9kSUQoSm5pQ29uc3RhbnRzOjppbmV0QWRkcmVzc0NsYXNzLAorICAgICAgICAgICAgImdldEJ5QWRkcmVzcyIsICIoTGphdmEvbGFuZy9TdHJpbmc7W0JJKUxqYXZhL25ldC9JbmV0QWRkcmVzczsiKTsKKyAgICBpZiAoZ2V0QnlBZGRyZXNzTWV0aG9kID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBlbnYtPkNhbGxTdGF0aWNPYmplY3RNZXRob2QoSm5pQ29uc3RhbnRzOjppbmV0QWRkcmVzc0NsYXNzLCBnZXRCeUFkZHJlc3NNZXRob2QsCisgICAgICAgICAgICBOVUxMLCBieXRlQXJyYXkuZ2V0KCksIHNjb3BlX2lkKTsKK30KKworc3RhdGljIGJvb2wgaW5ldEFkZHJlc3NUb1NvY2thZGRyKEpOSUVudiogZW52LCBqb2JqZWN0IGluZXRBZGRyZXNzLCBpbnQgcG9ydCwgc29ja2FkZHJfc3RvcmFnZSogc3MsIGJvb2wgbWFwKSB7CisgICAgbWVtc2V0KHNzLCAwLCBzaXplb2YoKnNzKSk7CisKKyAgICBpZiAoaW5ldEFkZHJlc3MgPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd051bGxQb2ludGVyRXhjZXB0aW9uKGVudiwgTlVMTCk7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvLyBHZXQgdGhlIGFkZHJlc3MgZmFtaWx5LgorICAgIHN0YXRpYyBqZmllbGRJRCBmYW1pbHlGaWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjppbmV0QWRkcmVzc0NsYXNzLCAiZmFtaWx5IiwgIkkiKTsKKyAgICBzcy0+c3NfZmFtaWx5ID0gZW52LT5HZXRJbnRGaWVsZChpbmV0QWRkcmVzcywgZmFtaWx5RmlkKTsKKyAgICBpZiAoc3MtPnNzX2ZhbWlseSA9PSBBRl9VTlNQRUMpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7IC8vIEpvYiBkb25lIQorICAgIH0KKworICAgIC8vIENoZWNrIHRoaXMgaXMgYW4gYWRkcmVzcyBmYW1pbHkgd2Ugc3VwcG9ydC4KKyAgICBpZiAoc3MtPnNzX2ZhbWlseSAhPSBBRl9JTkVUICYmIHNzLT5zc19mYW1pbHkgIT0gQUZfSU5FVDYpIHsKKyAgICAgICAgam5pVGhyb3dFeGNlcHRpb25GbXQoZW52LCAiamF2YS9sYW5nL0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIsCisgICAgICAgICAgICAgICAgImluZXRBZGRyZXNzVG9Tb2NrYWRkciBiYWQgZmFtaWx5OiAlaSIsIHNzLT5zc19mYW1pbHkpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gR2V0IHRoZSBieXRlIGFycmF5IHRoYXQgc3RvcmVzIHRoZSBJUCBhZGRyZXNzIGJ5dGVzIGluIHRoZSBJbmV0QWRkcmVzcy4KKyAgICBzdGF0aWMgamZpZWxkSUQgYnl0ZXNGaWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjppbmV0QWRkcmVzc0NsYXNzLCAiaXBhZGRyZXNzIiwgIltCIik7CisgICAgU2NvcGVkTG9jYWxSZWY8amJ5dGVBcnJheT4gYWRkcmVzc0J5dGVzKGVudiwgcmVpbnRlcnByZXRfY2FzdDxqYnl0ZUFycmF5PihlbnYtPkdldE9iamVjdEZpZWxkKGluZXRBZGRyZXNzLCBieXRlc0ZpZCkpKTsKKyAgICBpZiAoYWRkcmVzc0J5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsIE5VTEwpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gV2UgdXNlIEFGX0lORVQ2IHNvY2tldHMsIHNvIHdlIHdhbnQgYW4gSVB2NiBhZGRyZXNzICh3aGljaCBtYXkgYmUgYSBJUHY0LW1hcHBlZCBhZGRyZXNzKS4KKyAgICBzb2NrYWRkcl9pbjYqIHNpbjYgPSByZWludGVycHJldF9jYXN0PHNvY2thZGRyX2luNio+KHNzKTsKKyAgICBzaW42LT5zaW42X3BvcnQgPSBodG9ucyhwb3J0KTsKKyAgICBpZiAoc3MtPnNzX2ZhbWlseSA9PSBBRl9JTkVUNikgeworICAgICAgICAvLyBJUHY2IGFkZHJlc3MuIENvcHkgdGhlIGJ5dGVzLi4uCisgICAgICAgIGpieXRlKiBkc3QgPSByZWludGVycHJldF9jYXN0PGpieXRlKj4oJnNpbjYtPnNpbjZfYWRkci5zNl9hZGRyKTsKKyAgICAgICAgZW52LT5HZXRCeXRlQXJyYXlSZWdpb24oYWRkcmVzc0J5dGVzLmdldCgpLCAwLCAxNiwgZHN0KTsKKyAgICAgICAgLy8gLi4uYW5kIHNldCB0aGUgc2NvcGUgaWQuLi4KKyAgICAgICAgc3RhdGljIGpmaWVsZElEIHNjb3BlRmlkID0gZW52LT5HZXRGaWVsZElEKEpuaUNvbnN0YW50czo6aW5ldDZBZGRyZXNzQ2xhc3MsICJzY29wZV9pZCIsICJJIik7CisgICAgICAgIHNpbjYtPnNpbjZfc2NvcGVfaWQgPSBlbnYtPkdldEludEZpZWxkKGluZXRBZGRyZXNzLCBzY29wZUZpZCk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8vIERlYWwgd2l0aCBJbmV0NEFkZHJlc3MgaW5zdGFuY2VzLgorICAgIGlmIChtYXApIHsKKyAgICAgICAgLy8gV2Ugc2hvdWxkIHJlcHJlc2VudCB0aGlzIEluZXQ0QWRkcmVzcyBhcyBhbiBJUHY0LW1hcHBlZCBJUHY2IHNvY2thZGRyX2luNi4KKyAgICAgICAgLy8gQ2hhbmdlIHRoZSBmYW1pbHkuLi4KKyAgICAgICAgc2luNi0+c2luNl9mYW1pbHkgPSBBRl9JTkVUNjsKKyAgICAgICAgLy8gQ29weSB0aGUgYnl0ZXMuLi4KKyAgICAgICAgamJ5dGUqIGRzdCA9IHJlaW50ZXJwcmV0X2Nhc3Q8amJ5dGUqPigmc2luNi0+c2luNl9hZGRyLnM2X2FkZHJbMTJdKTsKKyAgICAgICAgZW52LT5HZXRCeXRlQXJyYXlSZWdpb24oYWRkcmVzc0J5dGVzLmdldCgpLCAwLCA0LCBkc3QpOworICAgICAgICAvLyBJTkFERFJfQU5ZIGFuZCBpbjZhZGRyX2FueSBhcmUgYm90aCBhbGwtemVyb3MuLi4KKyAgICAgICAgaWYgKCFJTjZfSVNfQUREUl9VTlNQRUNJRklFRCgmc2luNi0+c2luNl9hZGRyKSkgeworICAgICAgICAgICAgLy8gLi4uYnV0IGFsbCBvdGhlciBJUHY0LW1hcHBlZCBhZGRyZXNzZXMgYXJlIDo6ZmZmZjphLmIuYy5kLCBzbyBpbnNlcnQgdGhlIGZmZmYuLi4KKyAgICAgICAgICAgIG1lbXNldCgmKHNpbjYtPnNpbjZfYWRkci5zNl9hZGRyWzEwXSksIDB4ZmYsIDIpOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gV2Ugc2hvdWxkIHJlcHJlc2VudCB0aGlzIEluZXQ0QWRkcmVzcyBhcyBhbiBJUHY0IHNvY2thZGRyX2luLgorICAgICAgICBzb2NrYWRkcl9pbiogc2luID0gcmVpbnRlcnByZXRfY2FzdDxzb2NrYWRkcl9pbio+KHNzKTsKKyAgICAgICAgc2luLT5zaW5fcG9ydCA9IGh0b25zKHBvcnQpOworICAgICAgICBqYnl0ZSogZHN0ID0gcmVpbnRlcnByZXRfY2FzdDxqYnl0ZSo+KCZzaW4tPnNpbl9hZGRyLnNfYWRkcik7CisgICAgICAgIGVudi0+R2V0Qnl0ZUFycmF5UmVnaW9uKGFkZHJlc3NCeXRlcy5nZXQoKSwgMCwgNCwgZHN0KTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgaW5ldEFkZHJlc3NUb1NvY2thZGRyVmVyYmF0aW0oSk5JRW52KiBlbnYsIGpvYmplY3QgaW5ldEFkZHJlc3MsIGludCBwb3J0LCBzb2NrYWRkcl9zdG9yYWdlKiBzcykgeworICAgIHJldHVybiBpbmV0QWRkcmVzc1RvU29ja2FkZHIoZW52LCBpbmV0QWRkcmVzcywgcG9ydCwgc3MsIGZhbHNlKTsKK30KKworYm9vbCBpbmV0QWRkcmVzc1RvU29ja2FkZHIoSk5JRW52KiBlbnYsIGpvYmplY3QgaW5ldEFkZHJlc3MsIGludCBwb3J0LCBzb2NrYWRkcl9zdG9yYWdlKiBzcykgeworICAgIHJldHVybiBpbmV0QWRkcmVzc1RvU29ja2FkZHIoZW52LCBpbmV0QWRkcmVzcywgcG9ydCwgc3MsIHRydWUpOworfQorCitib29sIHNldEJsb2NraW5nKGludCBmZCwgYm9vbCBibG9ja2luZykgeworICAgIGludCBmbGFncyA9IGZjbnRsKGZkLCBGX0dFVEZMKTsKKyAgICBpZiAoZmxhZ3MgPT0gLTEpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGlmICghYmxvY2tpbmcpIHsKKyAgICAgICAgZmxhZ3MgfD0gT19OT05CTE9DSzsKKyAgICB9IGVsc2UgeworICAgICAgICBmbGFncyAmPSB+T19OT05CTE9DSzsKKyAgICB9CisKKyAgICBpbnQgcmMgPSBmY250bChmZCwgRl9TRVRGTCwgZmxhZ3MpOworICAgIHJldHVybiAocmMgIT0gLTEpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvTmV0d29ya1V0aWxpdGllcy5oIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvTmV0d29ya1V0aWxpdGllcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFhZTZjNTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9OZXR3b3JrVXRpbGl0aWVzLmgKQEAgLTAsMCArMSwzOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpbmNsdWRlICJqbmkuaCIKKyNpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CisKKy8vIENvbnZlcnQgZnJvbSBzb2NrYWRkcl9zdG9yYWdlIHRvIEluZXRBZGRyZXNzIGFuZCBhbiBvcHRpb25hbCBpbnQgcG9ydC4KK2pvYmplY3Qgc29ja2FkZHJUb0luZXRBZGRyZXNzKEpOSUVudiogZW52LCBjb25zdCBzb2NrYWRkcl9zdG9yYWdlKiBzcywgaW50KiBwb3J0KTsKKworLy8gQ29udmVydCBmcm9tIEluZXRBZGRyZXNzIHRvIHNvY2thZGRyX3N0b3JhZ2UuIEFuIEluZXQ0QWRkcmVzcyB3aWxsIGJlIGNvbnZlcnRlZCB0bworLy8gYW4gSVB2NC1tYXBwZWQgQUZfSU5FVDYgc29ja2FkZHJfaW42LiBUaGlzIGlzIHdoYXQgeW91IHdhbnQgaWYgeW91J3JlIGFib3V0IHRvIHBlcmZvcm0gYW4KKy8vIG9wZXJhdGlvbiBvbiBhIHNvY2tldCwgc2luY2UgYWxsIG91ciBzb2NrZXRzIGFyZSBBRl9JTkVUNi4KK2Jvb2wgaW5ldEFkZHJlc3NUb1NvY2thZGRyKEpOSUVudiogZW52LCBqb2JqZWN0IGluZXRBZGRyZXNzLCBpbnQgcG9ydCwgc29ja2FkZHJfc3RvcmFnZSogc3MpOworCisvLyBDb252ZXJ0IGZyb20gSW5ldEFkZHJlc3MgdG8gc29ja2FkZHJfc3RvcmFnZS4gQW4gSW5ldDZBZGRyZXNzIHdpbGwgYmUgY29udmVydGVkIHRvCisvLyBhIHNvY2thZGRyX2luNiB3aGlsZSBhbiBJbmV0NEFkZHJlc3Mgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gYSBzb2NrYWRkcl9pbi4gVGhpcyBpcworLy8gcHJvYmFibHkgb25seSB1c2VmdWwgZm9yIGdldG5hbWVpbmZvKDIpLCB3aGVyZSB3ZSdsbCBiZSBwcmVzZW50aW5nIHRoZSByZXN1bHQgdG8KKy8vIHRoZSB1c2VyIGFuZCB0aGUgdXNlciBtYXkgYWN0dWFsbHkgY2FyZSB3aGV0aGVyIHRoZSBvcmlnaW5hbCBhZGRyZXNzIHdhcyBwdXJlIElQdjQKKy8vIG9yIGFuIElQdjQtbWFwcGVkIElQdjYgYWRkcmVzcywgYW5kIGZvciB0aGUgTUNBU1RfSk9JTl9HUk9VUCBzb2NrZXQgb3B0aW9uLgorYm9vbCBpbmV0QWRkcmVzc1RvU29ja2FkZHJWZXJiYXRpbShKTklFbnYqIGVudiwgam9iamVjdCBpbmV0QWRkcmVzcywgaW50IHBvcnQsIHNvY2thZGRyX3N0b3JhZ2UqIHNzKTsKKworCisKKy8vIENoYW5nZXMgJ2ZkJyB0byBiZSBibG9ja2luZy9ub24tYmxvY2tpbmcuIFJldHVybnMgZmFsc2UgYW5kIHNldHMgZXJybm8gb24gZmFpbHVyZS4KKy8vIEBEZXByZWNhdGVkIC0gdXNlIElvVXRpbHMuc2V0QmxvY2tpbmcKK2Jvb2wgc2V0QmxvY2tpbmcoaW50IGZkLCBib29sIGJsb2NraW5nKTsKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL1JlZ2lzdGVyLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL1JlZ2lzdGVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNjM3YTczCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvUmVnaXN0ZXIuY3BwCkBAIC0wLDAgKzEsMTEzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJsaWJjb3JlIiAvLyBXZSdsbCBiZSBuZXh0IHRvICJkYWx2aWt2bSIgaW4gdGhlIGxvZzsgbWFrZSB0aGUgZGlzdGluY3Rpb24gY2xlYXIuCisKKyNpbmNsdWRlICJKbmlDb25zdGFudHMuaCIKKyNpbmNsdWRlICJTY29wZWRMb2NhbEZyYW1lLmgiCisKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKworZXh0ZXJuIGludCByZWdpc3Rlcl9qYXZhX2lvX0NvbnNvbGUoSk5JRW52KiBlbnYpOworZXh0ZXJuIGludCByZWdpc3Rlcl9qYXZhX2lvX0ZpbGUoSk5JRW52KiBlbnYpOworZXh0ZXJuIGludCByZWdpc3Rlcl9qYXZhX2lvX09iamVjdFN0cmVhbUNsYXNzKEpOSUVudiogZW52KTsKK2V4dGVybiBpbnQgcmVnaXN0ZXJfamF2YV9sYW5nX0NoYXJhY3RlcihKTklFbnYqIGVudik7CitleHRlcm4gaW50IHJlZ2lzdGVyX2phdmFfbGFuZ19NYXRoKEpOSUVudiogZW52KTsKK2V4dGVybiBpbnQgcmVnaXN0ZXJfamF2YV9sYW5nX1Byb2Nlc3NNYW5hZ2VyKEpOSUVudiogZW52KTsKK2V4dGVybiBpbnQgcmVnaXN0ZXJfamF2YV9sYW5nX1JlYWxUb1N0cmluZyhKTklFbnYqIGVudik7CitleHRlcm4gaW50IHJlZ2lzdGVyX2phdmFfbGFuZ19TdHJpY3RNYXRoKEpOSUVudiogZW52KTsKK2V4dGVybiBpbnQgcmVnaXN0ZXJfamF2YV9sYW5nX1N0cmluZ1RvUmVhbChKTklFbnYqIGVudik7CitleHRlcm4gaW50IHJlZ2lzdGVyX2phdmFfbGFuZ19TeXN0ZW0oSk5JRW52KiBlbnYpOworZXh0ZXJuIGludCByZWdpc3Rlcl9qYXZhX21hdGhfTmF0aXZlQk4oSk5JRW52KiBlbnYpOworZXh0ZXJuIGludCByZWdpc3Rlcl9qYXZhX25pb19CeXRlT3JkZXIoSk5JRW52KiBlbnYpOworZXh0ZXJuIGludCByZWdpc3Rlcl9qYXZhX25pb19jaGFyc2V0X0NoYXJzZXRzKEpOSUVudiogZW52KTsKK2V4dGVybiBpbnQgcmVnaXN0ZXJfamF2YV90ZXh0X0JpZGkoSk5JRW52KiBlbnYpOworZXh0ZXJuIGludCByZWdpc3Rlcl9qYXZhX3V0aWxfcmVnZXhfTWF0Y2hlcihKTklFbnYqIGVudik7CitleHRlcm4gaW50IHJlZ2lzdGVyX2phdmFfdXRpbF9yZWdleF9QYXR0ZXJuKEpOSUVudiogZW52KTsKK2V4dGVybiBpbnQgcmVnaXN0ZXJfamF2YV91dGlsX3ppcF9BZGxlcjMyKEpOSUVudiogZW52KTsKK2V4dGVybiBpbnQgcmVnaXN0ZXJfamF2YV91dGlsX3ppcF9DUkMzMihKTklFbnYqIGVudik7CitleHRlcm4gaW50IHJlZ2lzdGVyX2phdmFfdXRpbF96aXBfRGVmbGF0ZXIoSk5JRW52KiBlbnYpOworZXh0ZXJuIGludCByZWdpc3Rlcl9qYXZhX3V0aWxfemlwX0luZmxhdGVyKEpOSUVudiogZW52KTsKK2V4dGVybiBpbnQgcmVnaXN0ZXJfbGliY29yZV9pY3VfSUNVKEpOSUVudiogZW52KTsKK2V4dGVybiBpbnQgcmVnaXN0ZXJfbGliY29yZV9pY3VfTmF0aXZlQnJlYWtJdGVyYXRvcihKTklFbnYqIGVudik7CitleHRlcm4gaW50IHJlZ2lzdGVyX2xpYmNvcmVfaWN1X05hdGl2ZUNvbGxhdGlvbihKTklFbnYqIGVudik7CitleHRlcm4gaW50IHJlZ2lzdGVyX2xpYmNvcmVfaWN1X05hdGl2ZUNvbnZlcnRlcihKTklFbnYqIGVudik7CitleHRlcm4gaW50IHJlZ2lzdGVyX2xpYmNvcmVfaWN1X05hdGl2ZURlY2ltYWxGb3JtYXQoSk5JRW52KiBlbnYpOworZXh0ZXJuIGludCByZWdpc3Rlcl9saWJjb3JlX2ljdV9OYXRpdmVJRE4oSk5JRW52KiBlbnYpOworZXh0ZXJuIGludCByZWdpc3Rlcl9saWJjb3JlX2ljdV9OYXRpdmVOb3JtYWxpemVyKEpOSUVudiogZW52KTsKK2V4dGVybiBpbnQgcmVnaXN0ZXJfbGliY29yZV9pY3VfTmF0aXZlUGx1cmFsUnVsZXMoSk5JRW52KiBlbnYpOworZXh0ZXJuIGludCByZWdpc3Rlcl9saWJjb3JlX2ljdV9UaW1lWm9uZXMoSk5JRW52KiBlbnYpOworZXh0ZXJuIGludCByZWdpc3Rlcl9saWJjb3JlX2lvX0FzeW5jaHJvbm91c0Nsb3NlTW9uaXRvcihKTklFbnYqIGVudik7CitleHRlcm4gaW50IHJlZ2lzdGVyX2xpYmNvcmVfaW9fTWVtb3J5KEpOSUVudiogZW52KTsKK2V4dGVybiBpbnQgcmVnaXN0ZXJfbGliY29yZV9pb19Pc0NvbnN0YW50cyhKTklFbnYqIGVudik7CitleHRlcm4gaW50IHJlZ2lzdGVyX2xpYmNvcmVfaW9fUG9zaXgoSk5JRW52KiBlbnYpOworZXh0ZXJuIGludCByZWdpc3Rlcl9saWJjb3JlX25ldF9SYXdTb2NrZXQoSk5JRW52KiBlbnYpOworZXh0ZXJuIGludCByZWdpc3Rlcl9vcmdfYXBhY2hlX2hhcm1vbnlfZGFsdmlrX05hdGl2ZVRlc3RUYXJnZXQoSk5JRW52KiBlbnYpOworZXh0ZXJuIGludCByZWdpc3Rlcl9vcmdfYXBhY2hlX2hhcm1vbnlfeG1sX0V4cGF0UGFyc2VyKEpOSUVudiogZW52KTsKK2V4dGVybiBpbnQgcmVnaXN0ZXJfb3JnX2FwYWNoZV9oYXJtb255X3huZXRfcHJvdmlkZXJfanNzZV9OYXRpdmVDcnlwdG8oSk5JRW52KiBlbnYpOworCisvLyBEYWx2aWtWTSBjYWxscyB0aGlzIG9uIHN0YXJ0dXAsIHNvIHdlIGNhbiBzdGF0aWNhbGx5IHJlZ2lzdGVyIGFsbCBvdXIgbmF0aXZlIG1ldGhvZHMuCitpbnQgcmVnaXN0ZXJDb3JlTGlicmFyaWVzSm5pKEpOSUVudiogZW52KSB7CisgICAgU2NvcGVkTG9jYWxGcmFtZSBsb2NhbEZyYW1lKGVudik7CisKKyAgICBKbmlDb25zdGFudHM6OmluaXQoZW52KTsKKworICAgIGJvb2wgcmVzdWx0ID0KKyAgICAgICAgICAgIHJlZ2lzdGVyX2phdmFfaW9fQ29uc29sZShlbnYpICE9IC0xICYmCisgICAgICAgICAgICByZWdpc3Rlcl9qYXZhX2lvX0ZpbGUoZW52KSAhPSAtMSAmJgorICAgICAgICAgICAgcmVnaXN0ZXJfamF2YV9pb19PYmplY3RTdHJlYW1DbGFzcyhlbnYpICE9IC0xICYmCisgICAgICAgICAgICByZWdpc3Rlcl9qYXZhX2xhbmdfQ2hhcmFjdGVyKGVudikgIT0gLTEgJiYKKyAgICAgICAgICAgIHJlZ2lzdGVyX2phdmFfbGFuZ19NYXRoKGVudikgIT0gLTEgJiYKKyAgICAgICAgICAgIHJlZ2lzdGVyX2phdmFfbGFuZ19Qcm9jZXNzTWFuYWdlcihlbnYpICE9IC0xICYmCisgICAgICAgICAgICByZWdpc3Rlcl9qYXZhX2xhbmdfUmVhbFRvU3RyaW5nKGVudikgIT0gLTEgJiYKKyAgICAgICAgICAgIHJlZ2lzdGVyX2phdmFfbGFuZ19TdHJpY3RNYXRoKGVudikgIT0gLTEgJiYKKyAgICAgICAgICAgIHJlZ2lzdGVyX2phdmFfbGFuZ19TdHJpbmdUb1JlYWwoZW52KSAhPSAtMSAmJgorICAgICAgICAgICAgcmVnaXN0ZXJfamF2YV9sYW5nX1N5c3RlbShlbnYpICE9IC0xICYmCisgICAgICAgICAgICByZWdpc3Rlcl9qYXZhX21hdGhfTmF0aXZlQk4oZW52KSAhPSAtMSAmJgorICAgICAgICAgICAgcmVnaXN0ZXJfamF2YV9uaW9fQnl0ZU9yZGVyKGVudikgIT0gLTEgJiYKKyAgICAgICAgICAgIHJlZ2lzdGVyX2phdmFfbmlvX2NoYXJzZXRfQ2hhcnNldHMoZW52KSAhPSAtMSAmJgorICAgICAgICAgICAgcmVnaXN0ZXJfamF2YV90ZXh0X0JpZGkoZW52KSAhPSAtMSAmJgorICAgICAgICAgICAgcmVnaXN0ZXJfamF2YV91dGlsX3JlZ2V4X01hdGNoZXIoZW52KSAhPSAtMSAmJgorICAgICAgICAgICAgcmVnaXN0ZXJfamF2YV91dGlsX3JlZ2V4X1BhdHRlcm4oZW52KSAhPSAtMSAmJgorICAgICAgICAgICAgcmVnaXN0ZXJfamF2YV91dGlsX3ppcF9BZGxlcjMyKGVudikgIT0gLTEgJiYKKyAgICAgICAgICAgIHJlZ2lzdGVyX2phdmFfdXRpbF96aXBfQ1JDMzIoZW52KSAhPSAtMSAmJgorICAgICAgICAgICAgcmVnaXN0ZXJfamF2YV91dGlsX3ppcF9EZWZsYXRlcihlbnYpICE9IC0xICYmCisgICAgICAgICAgICByZWdpc3Rlcl9qYXZhX3V0aWxfemlwX0luZmxhdGVyKGVudikgIT0gLTEgJiYKKyAgICAgICAgICAgIHJlZ2lzdGVyX2xpYmNvcmVfaWN1X0lDVShlbnYpICE9IC0xICYmCisgICAgICAgICAgICByZWdpc3Rlcl9saWJjb3JlX2ljdV9OYXRpdmVCcmVha0l0ZXJhdG9yKGVudikgIT0gLTEgJiYKKyAgICAgICAgICAgIHJlZ2lzdGVyX2xpYmNvcmVfaWN1X05hdGl2ZUNvbGxhdGlvbihlbnYpICE9IC0xICYmCisgICAgICAgICAgICByZWdpc3Rlcl9saWJjb3JlX2ljdV9OYXRpdmVDb252ZXJ0ZXIoZW52KSAhPSAtMSAmJgorICAgICAgICAgICAgcmVnaXN0ZXJfbGliY29yZV9pY3VfTmF0aXZlRGVjaW1hbEZvcm1hdChlbnYpICE9IC0xICYmCisgICAgICAgICAgICByZWdpc3Rlcl9saWJjb3JlX2ljdV9OYXRpdmVJRE4oZW52KSAhPSAtMSAmJgorICAgICAgICAgICAgcmVnaXN0ZXJfbGliY29yZV9pY3VfTmF0aXZlTm9ybWFsaXplcihlbnYpICE9IC0xICYmCisgICAgICAgICAgICByZWdpc3Rlcl9saWJjb3JlX2ljdV9OYXRpdmVQbHVyYWxSdWxlcyhlbnYpICE9IC0xICYmCisgICAgICAgICAgICByZWdpc3Rlcl9saWJjb3JlX2ljdV9UaW1lWm9uZXMoZW52KSAhPSAtMSAmJgorICAgICAgICAgICAgcmVnaXN0ZXJfbGliY29yZV9pb19Bc3luY2hyb25vdXNDbG9zZU1vbml0b3IoZW52KSAhPSAtMSAmJgorICAgICAgICAgICAgcmVnaXN0ZXJfbGliY29yZV9pb19NZW1vcnkoZW52KSAhPSAtMSAmJgorICAgICAgICAgICAgcmVnaXN0ZXJfbGliY29yZV9pb19Pc0NvbnN0YW50cyhlbnYpICE9IC0xICYmCisgICAgICAgICAgICByZWdpc3Rlcl9saWJjb3JlX2lvX1Bvc2l4KGVudikgIT0gLTEgJiYKKyAgICAgICAgICAgIHJlZ2lzdGVyX2xpYmNvcmVfbmV0X1Jhd1NvY2tldChlbnYpICE9IC0xICYmCisgICAgICAgICAgICByZWdpc3Rlcl9vcmdfYXBhY2hlX2hhcm1vbnlfZGFsdmlrX05hdGl2ZVRlc3RUYXJnZXQoZW52KSAhPSAtMSAmJgorICAgICAgICAgICAgcmVnaXN0ZXJfb3JnX2FwYWNoZV9oYXJtb255X3htbF9FeHBhdFBhcnNlcihlbnYpICE9IC0xICYmCisgICAgICAgICAgICByZWdpc3Rlcl9vcmdfYXBhY2hlX2hhcm1vbnlfeG5ldF9wcm92aWRlcl9qc3NlX05hdGl2ZUNyeXB0byhlbnYpICE9IC0xICYmCisgICAgICAgICAgICB0cnVlOworCisgICAgaWYgKCFyZXN1bHQpIHsKKyAgICAgICAgTE9HRSgiRmFpbGVkIHRvIGluaXRpYWxpemUgdGhlIGNvcmUgbGlicmFyaWVzOyBhYm9ydGluZy4uLiIpOworICAgICAgICBhYm9ydCgpOworICAgIH0KKyAgICByZXR1cm4gMDsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL2NiaWdpbnQuY3BwIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvY2JpZ2ludC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGExNWZjYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2NiaWdpbnQuY3BwCkBAIC0wLDAgKzEsODcyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSAiY2JpZ2ludC5oIgorCisjaWYgZGVmaW5lZChfX2xpbnV4X18pIHx8IGRlZmluZWQoRlJFRUJTRCkgfHwgZGVmaW5lZChaT1MpIHx8IGRlZmluZWQoTUFDT1NYKSB8fCBkZWZpbmVkKEFJWCkKKyNkZWZpbmUgVVNFX0xMCisjZW5kaWYKKworI2lmIF9fQllURV9PUkRFUiA9PSBfX0xJVFRMRV9FTkRJQU4KKyNkZWZpbmUgYXQoaSkgKGkpCisjZWxzZQorI2RlZmluZSBhdChpKSAoKGkpXjEpCisvKiB0aGUgc2VxdWVuY2UgZm9yIGhhbGZBdCBpcyAtMSwgMiwgMSwgNCwgMywgNiwgNSwgOC4uLiAqLworLyogYW5kIGl0IHNob3VsZCBjb3JyZXNwb25kIHRvIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcuLi4gKi8KKyNkZWZpbmUgaGFsZkF0KGkpICgtKCgtKGkpKSBeIDEpKQorI2VuZGlmCisKKyNkZWZpbmUgSElHSF9JTl9VNjQodTY0KSAoKHU2NCkgPj4gMzIpCisjaWYgZGVmaW5lZChVU0VfTEwpCisjZGVmaW5lIExPV19JTl9VNjQodTY0KSAoKHU2NCkgJiAweDAwMDAwMDAwRkZGRkZGRkZMTCkKKyNlbHNlCisjaWYgZGVmaW5lZChVU0VfTCkKKyNkZWZpbmUgTE9XX0lOX1U2NCh1NjQpICgodTY0KSAmIDB4MDAwMDAwMDBGRkZGRkZGRkwpCisjZWxzZQorI2RlZmluZSBMT1dfSU5fVTY0KHU2NCkgKCh1NjQpICYgMHgwMDAwMDAwMEZGRkZGRkZGKQorI2VuZGlmIC8qIFVTRV9MICovCisjZW5kaWYgLyogVVNFX0xMICovCisKKyNpZiBkZWZpbmVkKFVTRV9MTCkKKyNkZWZpbmUgVEVOX0UxICgweEFMTCkKKyNkZWZpbmUgVEVOX0UyICgweDY0TEwpCisjZGVmaW5lIFRFTl9FMyAoMHgzRThMTCkKKyNkZWZpbmUgVEVOX0U0ICgweDI3MTBMTCkKKyNkZWZpbmUgVEVOX0U1ICgweDE4NkEwTEwpCisjZGVmaW5lIFRFTl9FNiAoMHhGNDI0MExMKQorI2RlZmluZSBURU5fRTcgKDB4OTg5NjgwTEwpCisjZGVmaW5lIFRFTl9FOCAoMHg1RjVFMTAwTEwpCisjZGVmaW5lIFRFTl9FOSAoMHgzQjlBQ0EwMExMKQorI2RlZmluZSBURU5fRTE5ICgweDhBQzcyMzA0ODlFODAwMDBMTCkKKyNlbHNlCisjaWYgZGVmaW5lZChVU0VfTCkKKyNkZWZpbmUgVEVOX0UxICgweEFMKQorI2RlZmluZSBURU5fRTIgKDB4NjRMKQorI2RlZmluZSBURU5fRTMgKDB4M0U4TCkKKyNkZWZpbmUgVEVOX0U0ICgweDI3MTBMKQorI2RlZmluZSBURU5fRTUgKDB4MTg2QTBMKQorI2RlZmluZSBURU5fRTYgKDB4RjQyNDBMKQorI2RlZmluZSBURU5fRTcgKDB4OTg5NjgwTCkKKyNkZWZpbmUgVEVOX0U4ICgweDVGNUUxMDBMKQorI2RlZmluZSBURU5fRTkgKDB4M0I5QUNBMDBMKQorI2RlZmluZSBURU5fRTE5ICgweDhBQzcyMzA0ODlFODAwMDBMKQorI2Vsc2UKKyNkZWZpbmUgVEVOX0UxICgweEEpCisjZGVmaW5lIFRFTl9FMiAoMHg2NCkKKyNkZWZpbmUgVEVOX0UzICgweDNFOCkKKyNkZWZpbmUgVEVOX0U0ICgweDI3MTApCisjZGVmaW5lIFRFTl9FNSAoMHgxODZBMCkKKyNkZWZpbmUgVEVOX0U2ICgweEY0MjQwKQorI2RlZmluZSBURU5fRTcgKDB4OTg5NjgwKQorI2RlZmluZSBURU5fRTggKDB4NUY1RTEwMCkKKyNkZWZpbmUgVEVOX0U5ICgweDNCOUFDQTAwKQorI2RlZmluZSBURU5fRTE5ICgweDhBQzcyMzA0ODlFODAwMDApCisjZW5kaWYgLyogVVNFX0wgKi8KKyNlbmRpZiAvKiBVU0VfTEwgKi8KKworI2RlZmluZSBUSU1FU19URU4oeCkgKCgoeCkgPDwgMykgKyAoKHgpIDw8IDEpKQorI2RlZmluZSBiaXRTZWN0aW9uKHgsIG1hc2ssIHNoaWZ0KSAoKCh4KSAmIChtYXNrKSkgPj4gKHNoaWZ0KSkKKyNkZWZpbmUgQ1JFQVRFX0RPVUJMRV9CSVRTKG5vcm1hbGl6ZWRNLCBlKSAoKChub3JtYWxpemVkTSkgJiBNQU5USVNTQV9NQVNLKSB8ICgoc3RhdGljX2Nhc3Q8dWludDY0X3Q+KChlKSArIEVfT0ZGU0VUKSkgPDwgNTIpKQorCisjaWYgZGVmaW5lZChVU0VfTEwpCisjZGVmaW5lIE1BTlRJU1NBX01BU0sgKDB4MDAwRkZGRkZGRkZGRkZGRkxMKQorI2RlZmluZSBFWFBPTkVOVF9NQVNLICgweDdGRjAwMDAwMDAwMDAwMDBMTCkKKyNkZWZpbmUgTk9STUFMX01BU0sgKDB4MDAxMDAwMDAwMDAwMDAwMExMKQorI2RlZmluZSBTSUdOX01BU0sgKDB4ODAwMDAwMDAwMDAwMDAwMExMKQorI2Vsc2UKKyNpZiBkZWZpbmVkKFVTRV9MKQorI2RlZmluZSBNQU5USVNTQV9NQVNLICgweDAwMEZGRkZGRkZGRkZGRkZMKQorI2RlZmluZSBFWFBPTkVOVF9NQVNLICgweDdGRjAwMDAwMDAwMDAwMDBMKQorI2RlZmluZSBOT1JNQUxfTUFTSyAoMHgwMDEwMDAwMDAwMDAwMDAwTCkKKyNkZWZpbmUgU0lHTl9NQVNLICgweDgwMDAwMDAwMDAwMDAwMDBMKQorI2Vsc2UKKyNkZWZpbmUgTUFOVElTU0FfTUFTSyAoMHgwMDBGRkZGRkZGRkZGRkZGKQorI2RlZmluZSBFWFBPTkVOVF9NQVNLICgweDdGRjAwMDAwMDAwMDAwMDApCisjZGVmaW5lIE5PUk1BTF9NQVNLICgweDAwMTAwMDAwMDAwMDAwMDApCisjZGVmaW5lIFNJR05fTUFTSyAoMHg4MDAwMDAwMDAwMDAwMDAwKQorI2VuZGlmIC8qIFVTRV9MICovCisjZW5kaWYgLyogVVNFX0xMICovCisKKyNkZWZpbmUgRV9PRkZTRVQgKDEwNzUpCisKKyNkZWZpbmUgRkxPQVRfTUFOVElTU0FfTUFTSyAoMHgwMDdGRkZGRikKKyNkZWZpbmUgRkxPQVRfRVhQT05FTlRfTUFTSyAoMHg3RjgwMDAwMCkKKyNkZWZpbmUgRkxPQVRfTk9STUFMX01BU0sgICAoMHgwMDgwMDAwMCkKKyNkZWZpbmUgRkxPQVRfRV9PRkZTRVQgKDE1MCkKKworaW50MzJfdAorc2ltcGxlQWRkSGlnaFByZWNpc2lvbiAodWludDY0X3QgKiBhcmcxLCBpbnQzMl90IGxlbmd0aCwgdWludDY0X3QgYXJnMikKK3sKKyAgLyogYXNzdW1lcyBsZW5ndGggPiAwICovCisgIGludDMyX3QgaW5kZXggPSAxOworCisgICphcmcxICs9IGFyZzI7CisgIGlmIChhcmcyIDw9ICphcmcxKQorICAgIHJldHVybiAwOworICBlbHNlIGlmIChsZW5ndGggPT0gMSkKKyAgICByZXR1cm4gMTsKKworICB3aGlsZSAoKythcmcxW2luZGV4XSA9PSAwICYmICsraW5kZXggPCBsZW5ndGgpOworCisgIHJldHVybiBpbmRleCA9PSBsZW5ndGg7Cit9CisKK2ludDMyX3QKK2FkZEhpZ2hQcmVjaXNpb24gKHVpbnQ2NF90ICogYXJnMSwgaW50MzJfdCBsZW5ndGgxLCB1aW50NjRfdCAqIGFyZzIsIGludDMyX3QgbGVuZ3RoMikKK3sKKyAgLyogYWRkaXRpb24gaXMgbGltaXRlZCBieSBsZW5ndGggb2YgYXJnMSBhcyBpdCB0aGlzIGZ1bmN0aW9uIGlzCisgICAqIHN0b3JpbmcgdGhlIHJlc3VsdCBpbiBhcmcxICovCisgIC8qIGZpeCBmb3IgY2MgKEdDQykgMy4yIDIwMDIwOTAzIChSZWQgSGF0IExpbnV4IDguMCAzLjItNyk6IGNvZGUgZ2VuZXJhdGVkIGRvZXMgbm90CisgICAqIGRvIHRoZSB0ZW1wMSArIHRlbXAyICsgY2FycnkgYWRkaXRpb24gY29ycmVjdC4gIGNhcnJ5IGlzIDY0IGJpdCBiZWNhdXNlIGdjYyBoYXMKKyAgICogc3VidGxlIGlzc3VlcyB3aGVuIHlvdSBtaXggNjQgLyAzMiBiaXQgbWF0aHMuICovCisgIHVpbnQ2NF90IHRlbXAxLCB0ZW1wMiwgdGVtcDM7ICAgICAvKiB0ZW1wb3JhcnkgdmFyaWFibGVzIHRvIGhlbHAgdGhlIFNILTQsIGFuZCBnY2MgKi8KKyAgdWludDY0X3QgY2Fycnk7CisgIGludDMyX3QgaW5kZXg7CisKKyAgaWYgKGxlbmd0aDEgPT0gMCB8fCBsZW5ndGgyID09IDApCisgICAgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorICBlbHNlIGlmIChsZW5ndGgxIDwgbGVuZ3RoMikKKyAgICB7CisgICAgICBsZW5ndGgyID0gbGVuZ3RoMTsKKyAgICB9CisKKyAgY2FycnkgPSAwOworICBpbmRleCA9IDA7CisgIGRvCisgICAgeworICAgICAgdGVtcDEgPSBhcmcxW2luZGV4XTsKKyAgICAgIHRlbXAyID0gYXJnMltpbmRleF07CisgICAgICB0ZW1wMyA9IHRlbXAxICsgdGVtcDI7CisgICAgICBhcmcxW2luZGV4XSA9IHRlbXAzICsgY2Fycnk7CisgICAgICBpZiAoYXJnMltpbmRleF0gPCBhcmcxW2luZGV4XSkKKyAgICAgICAgY2FycnkgPSAwOworICAgICAgZWxzZSBpZiAoYXJnMltpbmRleF0gIT0gYXJnMVtpbmRleF0pCisgICAgICAgIGNhcnJ5ID0gMTsKKyAgICB9CisgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoMik7CisgIGlmICghY2FycnkpCisgICAgcmV0dXJuIDA7CisgIGVsc2UgaWYgKGluZGV4ID09IGxlbmd0aDEpCisgICAgcmV0dXJuIDE7CisKKyAgd2hpbGUgKCsrYXJnMVtpbmRleF0gPT0gMCAmJiArK2luZGV4IDwgbGVuZ3RoMSk7CisKKyAgcmV0dXJuIGluZGV4ID09IGxlbmd0aDE7Cit9CisKK3ZvaWQKK3N1YnRyYWN0SGlnaFByZWNpc2lvbiAodWludDY0X3QgKiBhcmcxLCBpbnQzMl90IGxlbmd0aDEsIHVpbnQ2NF90ICogYXJnMiwgaW50MzJfdCBsZW5ndGgyKQoreworICAvKiBhc3N1bWVzIGFyZzEgPiBhcmcyICovCisgIGludDMyX3QgaW5kZXg7CisgIGZvciAoaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDE7ICsraW5kZXgpCisgICAgYXJnMVtpbmRleF0gPSB+YXJnMVtpbmRleF07CisgIHNpbXBsZUFkZEhpZ2hQcmVjaXNpb24gKGFyZzEsIGxlbmd0aDEsIDEpOworCisgIHdoaWxlIChsZW5ndGgyID4gMCAmJiBhcmcyW2xlbmd0aDIgLSAxXSA9PSAwKQorICAgIC0tbGVuZ3RoMjsKKworICBhZGRIaWdoUHJlY2lzaW9uIChhcmcxLCBsZW5ndGgxLCBhcmcyLCBsZW5ndGgyKTsKKworICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGgxOyArK2luZGV4KQorICAgIGFyZzFbaW5kZXhdID0gfmFyZzFbaW5kZXhdOworICBzaW1wbGVBZGRIaWdoUHJlY2lzaW9uIChhcmcxLCBsZW5ndGgxLCAxKTsKK30KKworc3RhdGljIHVpbnQzMl90IHNpbXBsZU11bHRpcGx5SGlnaFByZWNpc2lvbih1aW50NjRfdCogYXJnMSwgaW50MzJfdCBsZW5ndGgsIHVpbnQ2NF90IGFyZzIpIHsKKyAgLyogYXNzdW1lcyBhcmcyIG9ubHkgaG9sZHMgMzIgYml0cyBvZiBpbmZvcm1hdGlvbiAqLworICB1aW50NjRfdCBwcm9kdWN0OworICBpbnQzMl90IGluZGV4OworCisgIGluZGV4ID0gMDsKKyAgcHJvZHVjdCA9IDA7CisKKyAgZG8KKyAgICB7CisgICAgICBwcm9kdWN0ID0KKyAgICAgICAgSElHSF9JTl9VNjQgKHByb2R1Y3QpICsgYXJnMiAqIExPV19VMzJfRlJPTV9QVFIgKGFyZzEgKyBpbmRleCk7CisgICAgICBMT1dfVTMyX0ZST01fUFRSIChhcmcxICsgaW5kZXgpID0gTE9XX1UzMl9GUk9NX1ZBUiAocHJvZHVjdCk7CisgICAgICBwcm9kdWN0ID0KKyAgICAgICAgSElHSF9JTl9VNjQgKHByb2R1Y3QpICsgYXJnMiAqIEhJR0hfVTMyX0ZST01fUFRSIChhcmcxICsgaW5kZXgpOworICAgICAgSElHSF9VMzJfRlJPTV9QVFIgKGFyZzEgKyBpbmRleCkgPSBMT1dfVTMyX0ZST01fVkFSIChwcm9kdWN0KTsKKyAgICB9CisgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKTsKKworICByZXR1cm4gSElHSF9VMzJfRlJPTV9WQVIgKHByb2R1Y3QpOworfQorCitzdGF0aWMgdm9pZAorc2ltcGxlTXVsdGlwbHlBZGRIaWdoUHJlY2lzaW9uICh1aW50NjRfdCAqIGFyZzEsIGludDMyX3QgbGVuZ3RoLCB1aW50NjRfdCBhcmcyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCAqIHJlc3VsdCkKK3sKKyAgLyogQXNzdW1lcyByZXN1bHQgY2FuIGhvbGQgdGhlIHByb2R1Y3QgYW5kIGFyZzIgb25seSBob2xkcyAzMiBiaXRzCisgICAgIG9mIGluZm9ybWF0aW9uICovCisgIHVpbnQ2NF90IHByb2R1Y3Q7CisgIGludDMyX3QgaW5kZXgsIHJlc3VsdEluZGV4OworCisgIGluZGV4ID0gcmVzdWx0SW5kZXggPSAwOworICBwcm9kdWN0ID0gMDsKKworICBkbworICAgIHsKKyAgICAgIHByb2R1Y3QgPQorICAgICAgICBISUdIX0lOX1U2NCAocHJvZHVjdCkgKyByZXN1bHRbYXQgKHJlc3VsdEluZGV4KV0gKworICAgICAgICBhcmcyICogTE9XX1UzMl9GUk9NX1BUUiAoYXJnMSArIGluZGV4KTsKKyAgICAgIHJlc3VsdFthdCAocmVzdWx0SW5kZXgpXSA9IExPV19VMzJfRlJPTV9WQVIgKHByb2R1Y3QpOworICAgICAgKytyZXN1bHRJbmRleDsKKyAgICAgIHByb2R1Y3QgPQorICAgICAgICBISUdIX0lOX1U2NCAocHJvZHVjdCkgKyByZXN1bHRbYXQgKHJlc3VsdEluZGV4KV0gKworICAgICAgICBhcmcyICogSElHSF9VMzJfRlJPTV9QVFIgKGFyZzEgKyBpbmRleCk7CisgICAgICByZXN1bHRbYXQgKHJlc3VsdEluZGV4KV0gPSBMT1dfVTMyX0ZST01fVkFSIChwcm9kdWN0KTsKKyAgICAgICsrcmVzdWx0SW5kZXg7CisgICAgfQorICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCk7CisKKyAgcmVzdWx0W2F0IChyZXN1bHRJbmRleCldICs9IEhJR0hfVTMyX0ZST01fVkFSIChwcm9kdWN0KTsKKyAgaWYgKHJlc3VsdFthdCAocmVzdWx0SW5kZXgpXSA8IEhJR0hfVTMyX0ZST01fVkFSIChwcm9kdWN0KSkKKyAgICB7CisgICAgICAvKiBtdXN0IGJlIGNhcmVmdWwgd2l0aCArKyBvcGVyYXRvciBhbmQgbWFjcm8gZXhwYW5zaW9uICovCisgICAgICArK3Jlc3VsdEluZGV4OworICAgICAgd2hpbGUgKCsrcmVzdWx0W2F0IChyZXN1bHRJbmRleCldID09IDApCisgICAgICAgICsrcmVzdWx0SW5kZXg7CisgICAgfQorfQorCisjaWYgX19CWVRFX09SREVSICE9IF9fTElUVExFX0VORElBTgordm9pZCBzaW1wbGVNdWx0aXBseUFkZEhpZ2hQcmVjaXNpb25CaWdFbmRpYW5GaXgodWludDY0X3QqIGFyZzEsIGludDMyX3QgbGVuZ3RoLCB1aW50NjRfdCBhcmcyLCB1aW50MzJfdCogcmVzdWx0KSB7CisgICAgLyogQXNzdW1lcyByZXN1bHQgY2FuIGhvbGQgdGhlIHByb2R1Y3QgYW5kIGFyZzIgb25seSBob2xkcyAzMiBiaXRzIG9mIGluZm9ybWF0aW9uICovCisgICAgaW50MzJfdCBpbmRleCA9IDA7CisgICAgaW50MzJfdCByZXN1bHRJbmRleCA9IDA7CisgICAgdWludDY0X3QgcHJvZHVjdCA9IDA7CisKKyAgICBkbyB7CisgICAgICAgIHByb2R1Y3QgPSBISUdIX0lOX1U2NChwcm9kdWN0KSArIHJlc3VsdFtoYWxmQXQocmVzdWx0SW5kZXgpXSArIGFyZzIgKiBMT1dfVTMyX0ZST01fUFRSKGFyZzEgKyBpbmRleCk7CisgICAgICAgIHJlc3VsdFtoYWxmQXQocmVzdWx0SW5kZXgpXSA9IExPV19VMzJfRlJPTV9WQVIocHJvZHVjdCk7CisgICAgICAgICsrcmVzdWx0SW5kZXg7CisgICAgICAgIHByb2R1Y3QgPSBISUdIX0lOX1U2NChwcm9kdWN0KSArIHJlc3VsdFtoYWxmQXQocmVzdWx0SW5kZXgpXSArIGFyZzIgKiBISUdIX1UzMl9GUk9NX1BUUihhcmcxICsgaW5kZXgpOworICAgICAgICByZXN1bHRbaGFsZkF0KHJlc3VsdEluZGV4KV0gPSBMT1dfVTMyX0ZST01fVkFSKHByb2R1Y3QpOworICAgICAgICArK3Jlc3VsdEluZGV4OworICAgIH0gd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpOworCisgICAgcmVzdWx0W2hhbGZBdChyZXN1bHRJbmRleCldICs9IEhJR0hfVTMyX0ZST01fVkFSKHByb2R1Y3QpOworICAgIGlmIChyZXN1bHRbaGFsZkF0KHJlc3VsdEluZGV4KV0gPCBISUdIX1UzMl9GUk9NX1ZBUihwcm9kdWN0KSkgeworICAgICAgICAvKiBtdXN0IGJlIGNhcmVmdWwgd2l0aCArKyBvcGVyYXRvciBhbmQgbWFjcm8gZXhwYW5zaW9uICovCisgICAgICAgICsrcmVzdWx0SW5kZXg7CisgICAgICAgIHdoaWxlICgrK3Jlc3VsdFtoYWxmQXQocmVzdWx0SW5kZXgpXSA9PSAwKSArK3Jlc3VsdEluZGV4OworICAgIH0KK30KKyNlbmRpZgorCit2b2lkCittdWx0aXBseUhpZ2hQcmVjaXNpb24gKHVpbnQ2NF90ICogYXJnMSwgaW50MzJfdCBsZW5ndGgxLCB1aW50NjRfdCAqIGFyZzIsIGludDMyX3QgbGVuZ3RoMiwKKyAgICAgICAgICAgICAgICAgICAgICAgdWludDY0X3QgKiByZXN1bHQsIGludDMyX3QgbGVuZ3RoKQoreworICAvKiBhc3N1bWVzIHJlc3VsdCBpcyBsYXJnZSBlbm91Z2ggdG8gaG9sZCBwcm9kdWN0ICovCisgIHVpbnQ2NF90KiB0ZW1wOworICB1aW50MzJfdCogcmVzdWx0SW4zMjsKKyAgaW50MzJfdCBjb3VudCwgaW5kZXg7CisKKyAgaWYgKGxlbmd0aDEgPCBsZW5ndGgyKQorICAgIHsKKyAgICAgIHRlbXAgPSBhcmcxOworICAgICAgYXJnMSA9IGFyZzI7CisgICAgICBhcmcyID0gdGVtcDsKKyAgICAgIGNvdW50ID0gbGVuZ3RoMTsKKyAgICAgIGxlbmd0aDEgPSBsZW5ndGgyOworICAgICAgbGVuZ3RoMiA9IGNvdW50OworICAgIH0KKworICBtZW1zZXQgKHJlc3VsdCwgMCwgc2l6ZW9mICh1aW50NjRfdCkgKiBsZW5ndGgpOworCisgIC8qIGxlbmd0aDEgPiBsZW5ndGgyICovCisgIHJlc3VsdEluMzIgPSByZWludGVycHJldF9jYXN0PHVpbnQzMl90Kj4ocmVzdWx0KTsKKyAgaW5kZXggPSAtMTsKKyAgZm9yIChjb3VudCA9IDA7IGNvdW50IDwgbGVuZ3RoMjsgKytjb3VudCkKKyAgICB7CisgICAgICBzaW1wbGVNdWx0aXBseUFkZEhpZ2hQcmVjaXNpb24gKGFyZzEsIGxlbmd0aDEsIExPV19JTl9VNjQgKGFyZzJbY291bnRdKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0SW4zMiArICgrK2luZGV4KSk7CisjaWYgX19CWVRFX09SREVSID09IF9fTElUVExFX0VORElBTgorICAgICAgc2ltcGxlTXVsdGlwbHlBZGRIaWdoUHJlY2lzaW9uKGFyZzEsIGxlbmd0aDEsIEhJR0hfSU5fVTY0KGFyZzJbY291bnRdKSwgcmVzdWx0SW4zMiArICgrK2luZGV4KSk7CisjZWxzZQorICAgICAgc2ltcGxlTXVsdGlwbHlBZGRIaWdoUHJlY2lzaW9uQmlnRW5kaWFuRml4KGFyZzEsIGxlbmd0aDEsIEhJR0hfSU5fVTY0KGFyZzJbY291bnRdKSwgcmVzdWx0SW4zMiArICgrK2luZGV4KSk7CisjZW5kaWYKKyAgICB9Cit9CisKK3VpbnQzMl90CitzaW1wbGVBcHBlbmREZWNpbWFsRGlnaXRIaWdoUHJlY2lzaW9uICh1aW50NjRfdCAqIGFyZzEsIGludDMyX3QgbGVuZ3RoLCB1aW50NjRfdCBkaWdpdCkKK3sKKyAgLyogYXNzdW1lcyBkaWdpdCBpcyBsZXNzIHRoYW4gMzIgYml0cyAqLworICB1aW50NjRfdCBhcmc7CisgIGludDMyX3QgaW5kZXggPSAwOworCisgIGRpZ2l0IDw8PSAzMjsKKyAgZG8KKyAgICB7CisgICAgICBhcmcgPSBMT1dfSU5fVTY0IChhcmcxW2luZGV4XSk7CisgICAgICBkaWdpdCA9IEhJR0hfSU5fVTY0IChkaWdpdCkgKyBUSU1FU19URU4gKGFyZyk7CisgICAgICBMT1dfVTMyX0ZST01fUFRSIChhcmcxICsgaW5kZXgpID0gTE9XX1UzMl9GUk9NX1ZBUiAoZGlnaXQpOworCisgICAgICBhcmcgPSBISUdIX0lOX1U2NCAoYXJnMVtpbmRleF0pOworICAgICAgZGlnaXQgPSBISUdIX0lOX1U2NCAoZGlnaXQpICsgVElNRVNfVEVOIChhcmcpOworICAgICAgSElHSF9VMzJfRlJPTV9QVFIgKGFyZzEgKyBpbmRleCkgPSBMT1dfVTMyX0ZST01fVkFSIChkaWdpdCk7CisgICAgfQorICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCk7CisKKyAgcmV0dXJuIEhJR0hfVTMyX0ZST01fVkFSIChkaWdpdCk7Cit9CisKK3ZvaWQKK3NpbXBsZVNoaWZ0TGVmdEhpZ2hQcmVjaXNpb24gKHVpbnQ2NF90ICogYXJnMSwgaW50MzJfdCBsZW5ndGgsIGludDMyX3QgYXJnMikKK3sKKyAgLyogYXNzdW1lcyBsZW5ndGggPiAwICovCisgIGludDMyX3QgaW5kZXgsIG9mZnNldDsKKyAgaWYgKGFyZzIgPj0gNjQpCisgICAgeworICAgICAgb2Zmc2V0ID0gYXJnMiA+PiA2OworICAgICAgaW5kZXggPSBsZW5ndGg7CisKKyAgICAgIHdoaWxlICgtLWluZGV4IC0gb2Zmc2V0ID49IDApCisgICAgICAgIGFyZzFbaW5kZXhdID0gYXJnMVtpbmRleCAtIG9mZnNldF07CisgICAgICBkbworICAgICAgICB7CisgICAgICAgICAgYXJnMVtpbmRleF0gPSAwOworICAgICAgICB9CisgICAgICB3aGlsZSAoLS1pbmRleCA+PSAwKTsKKworICAgICAgYXJnMiAmPSAweDNGOworICAgIH0KKworICBpZiAoYXJnMiA9PSAwKQorICAgIHJldHVybjsKKyAgd2hpbGUgKC0tbGVuZ3RoID4gMCkKKyAgICB7CisgICAgICBhcmcxW2xlbmd0aF0gPSBhcmcxW2xlbmd0aF0gPDwgYXJnMiB8IGFyZzFbbGVuZ3RoIC0gMV0gPj4gKDY0IC0gYXJnMik7CisgICAgfQorICAqYXJnMSA8PD0gYXJnMjsKK30KKworaW50MzJfdAoraGlnaGVzdFNldEJpdCAodWludDY0X3QgKiB5KQoreworICB1aW50MzJfdCB4OworICBpbnQzMl90IHJlc3VsdDsKKworICBpZiAoKnkgPT0gMCkKKyAgICByZXR1cm4gMDsKKworI2lmIGRlZmluZWQoVVNFX0xMKQorICBpZiAoKnkgJiAweEZGRkZGRkZGMDAwMDAwMDBMTCkKKyAgICB7CisgICAgICB4ID0gSElHSF9VMzJfRlJPTV9QVFIgKHkpOworICAgICAgcmVzdWx0ID0gMzI7CisgICAgfQorICBlbHNlCisgICAgeworICAgICAgeCA9IExPV19VMzJfRlJPTV9QVFIgKHkpOworICAgICAgcmVzdWx0ID0gMDsKKyAgICB9CisjZWxzZQorI2lmIGRlZmluZWQoVVNFX0wpCisgIGlmICgqeSAmIDB4RkZGRkZGRkYwMDAwMDAwMEwpCisgICAgeworICAgICAgeCA9IEhJR0hfVTMyX0ZST01fUFRSICh5KTsKKyAgICAgIHJlc3VsdCA9IDMyOworICAgIH0KKyAgZWxzZQorICAgIHsKKyAgICAgIHggPSBMT1dfVTMyX0ZST01fUFRSICh5KTsKKyAgICAgIHJlc3VsdCA9IDA7CisgICAgfQorI2Vsc2UKKyAgaWYgKCp5ICYgMHhGRkZGRkZGRjAwMDAwMDAwKQorICAgIHsKKyAgICAgIHggPSBISUdIX1UzMl9GUk9NX1BUUiAoeSk7CisgICAgICByZXN1bHQgPSAzMjsKKyAgICB9CisgIGVsc2UKKyAgICB7CisgICAgICB4ID0gTE9XX1UzMl9GUk9NX1BUUiAoeSk7CisgICAgICByZXN1bHQgPSAwOworICAgIH0KKyNlbmRpZiAvKiBVU0VfTCAqLworI2VuZGlmIC8qIFVTRV9MTCAqLworCisgIGlmICh4ICYgMHhGRkZGMDAwMCkKKyAgICB7CisgICAgICB4ID0gYml0U2VjdGlvbiAoeCwgMHhGRkZGMDAwMCwgMTYpOworICAgICAgcmVzdWx0ICs9IDE2OworICAgIH0KKyAgaWYgKHggJiAweEZGMDApCisgICAgeworICAgICAgeCA9IGJpdFNlY3Rpb24gKHgsIDB4RkYwMCwgOCk7CisgICAgICByZXN1bHQgKz0gODsKKyAgICB9CisgIGlmICh4ICYgMHhGMCkKKyAgICB7CisgICAgICB4ID0gYml0U2VjdGlvbiAoeCwgMHhGMCwgNCk7CisgICAgICByZXN1bHQgKz0gNDsKKyAgICB9CisgIGlmICh4ID4gMHg3KQorICAgIHJldHVybiByZXN1bHQgKyA0OworICBlbHNlIGlmICh4ID4gMHgzKQorICAgIHJldHVybiByZXN1bHQgKyAzOworICBlbHNlIGlmICh4ID4gMHgxKQorICAgIHJldHVybiByZXN1bHQgKyAyOworICBlbHNlCisgICAgcmV0dXJuIHJlc3VsdCArIDE7Cit9CisKK2ludDMyX3QKK2xvd2VzdFNldEJpdCAodWludDY0X3QgKiB5KQoreworICB1aW50MzJfdCB4OworICBpbnQzMl90IHJlc3VsdDsKKworICBpZiAoKnkgPT0gMCkKKyAgICByZXR1cm4gMDsKKworI2lmIGRlZmluZWQoVVNFX0xMKQorICBpZiAoKnkgJiAweDAwMDAwMDAwRkZGRkZGRkZMTCkKKyAgICB7CisgICAgICB4ID0gTE9XX1UzMl9GUk9NX1BUUiAoeSk7CisgICAgICByZXN1bHQgPSAwOworICAgIH0KKyAgZWxzZQorICAgIHsKKyAgICAgIHggPSBISUdIX1UzMl9GUk9NX1BUUiAoeSk7CisgICAgICByZXN1bHQgPSAzMjsKKyAgICB9CisjZWxzZQorI2lmIGRlZmluZWQoVVNFX0wpCisgIGlmICgqeSAmIDB4MDAwMDAwMDBGRkZGRkZGRkwpCisgICAgeworICAgICAgeCA9IExPV19VMzJfRlJPTV9QVFIgKHkpOworICAgICAgcmVzdWx0ID0gMDsKKyAgICB9CisgIGVsc2UKKyAgICB7CisgICAgICB4ID0gSElHSF9VMzJfRlJPTV9QVFIgKHkpOworICAgICAgcmVzdWx0ID0gMzI7CisgICAgfQorI2Vsc2UKKyAgaWYgKCp5ICYgMHgwMDAwMDAwMEZGRkZGRkZGKQorICAgIHsKKyAgICAgIHggPSBMT1dfVTMyX0ZST01fUFRSICh5KTsKKyAgICAgIHJlc3VsdCA9IDA7CisgICAgfQorICBlbHNlCisgICAgeworICAgICAgeCA9IEhJR0hfVTMyX0ZST01fUFRSICh5KTsKKyAgICAgIHJlc3VsdCA9IDMyOworICAgIH0KKyNlbmRpZiAvKiBVU0VfTCAqLworI2VuZGlmIC8qIFVTRV9MTCAqLworCisgIGlmICghKHggJiAweEZGRkYpKQorICAgIHsKKyAgICAgIHggPSBiaXRTZWN0aW9uICh4LCAweEZGRkYwMDAwLCAxNik7CisgICAgICByZXN1bHQgKz0gMTY7CisgICAgfQorICBpZiAoISh4ICYgMHhGRikpCisgICAgeworICAgICAgeCA9IGJpdFNlY3Rpb24gKHgsIDB4RkYwMCwgOCk7CisgICAgICByZXN1bHQgKz0gODsKKyAgICB9CisgIGlmICghKHggJiAweEYpKQorICAgIHsKKyAgICAgIHggPSBiaXRTZWN0aW9uICh4LCAweEYwLCA0KTsKKyAgICAgIHJlc3VsdCArPSA0OworICAgIH0KKworICBpZiAoeCAmIDB4MSkKKyAgICByZXR1cm4gcmVzdWx0ICsgMTsKKyAgZWxzZSBpZiAoeCAmIDB4MikKKyAgICByZXR1cm4gcmVzdWx0ICsgMjsKKyAgZWxzZSBpZiAoeCAmIDB4NCkKKyAgICByZXR1cm4gcmVzdWx0ICsgMzsKKyAgZWxzZQorICAgIHJldHVybiByZXN1bHQgKyA0OworfQorCitpbnQzMl90CitoaWdoZXN0U2V0Qml0SGlnaFByZWNpc2lvbiAodWludDY0X3QgKiBhcmcsIGludDMyX3QgbGVuZ3RoKQoreworICBpbnQzMl90IGhpZ2hCaXQ7CisKKyAgd2hpbGUgKC0tbGVuZ3RoID49IDApCisgICAgeworICAgICAgaGlnaEJpdCA9IGhpZ2hlc3RTZXRCaXQgKGFyZyArIGxlbmd0aCk7CisgICAgICBpZiAoaGlnaEJpdCkKKyAgICAgICAgcmV0dXJuIGhpZ2hCaXQgKyA2NCAqIGxlbmd0aDsKKyAgICB9CisKKyAgcmV0dXJuIDA7Cit9CisKK2ludDMyX3QKK2xvd2VzdFNldEJpdEhpZ2hQcmVjaXNpb24gKHVpbnQ2NF90ICogYXJnLCBpbnQzMl90IGxlbmd0aCkKK3sKKyAgaW50MzJfdCBsb3dCaXQsIGluZGV4ID0gLTE7CisKKyAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpCisgICAgeworICAgICAgbG93Qml0ID0gbG93ZXN0U2V0Qml0IChhcmcgKyBpbmRleCk7CisgICAgICBpZiAobG93Qml0KQorICAgICAgICByZXR1cm4gbG93Qml0ICsgNjQgKiBpbmRleDsKKyAgICB9CisKKyAgcmV0dXJuIDA7Cit9CisKK2ludDMyX3QKK2NvbXBhcmVIaWdoUHJlY2lzaW9uICh1aW50NjRfdCAqIGFyZzEsIGludDMyX3QgbGVuZ3RoMSwgdWludDY0X3QgKiBhcmcyLCBpbnQzMl90IGxlbmd0aDIpCit7CisgIHdoaWxlICgtLWxlbmd0aDEgPj0gMCAmJiBhcmcxW2xlbmd0aDFdID09IDApOworICB3aGlsZSAoLS1sZW5ndGgyID49IDAgJiYgYXJnMltsZW5ndGgyXSA9PSAwKTsKKworICBpZiAobGVuZ3RoMSA+IGxlbmd0aDIpCisgICAgcmV0dXJuIDE7CisgIGVsc2UgaWYgKGxlbmd0aDEgPCBsZW5ndGgyKQorICAgIHJldHVybiAtMTsKKyAgZWxzZSBpZiAobGVuZ3RoMSA+IC0xKQorICAgIHsKKyAgICAgIGRvCisgICAgICAgIHsKKyAgICAgICAgICBpZiAoYXJnMVtsZW5ndGgxXSA+IGFyZzJbbGVuZ3RoMV0pCisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICBlbHNlIGlmIChhcmcxW2xlbmd0aDFdIDwgYXJnMltsZW5ndGgxXSkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgd2hpbGUgKC0tbGVuZ3RoMSA+PSAwKTsKKyAgICB9CisKKyAgcmV0dXJuIDA7Cit9CisKK2pkb3VibGUKK3RvRG91YmxlSGlnaFByZWNpc2lvbiAodWludDY0X3QgKiBhcmcsIGludDMyX3QgbGVuZ3RoKQoreworICBpbnQzMl90IGhpZ2hCaXQ7CisgIHVpbnQ2NF90IG1hbnRpc3NhLCB0ZXN0NjQ7CisgIHVpbnQzMl90IHRlc3Q7CisgIGpkb3VibGUgcmVzdWx0OworCisgIHdoaWxlIChsZW5ndGggPiAwICYmIGFyZ1tsZW5ndGggLSAxXSA9PSAwKQorICAgIC0tbGVuZ3RoOworCisgIGlmIChsZW5ndGggPT0gMCkKKyAgICByZXN1bHQgPSAwLjA7CisgIGVsc2UgaWYgKGxlbmd0aCA+IDE2KQorICAgIHsKKyAgICAgIERPVUJMRV9UT19MT05HQklUUyAocmVzdWx0KSA9IEVYUE9ORU5UX01BU0s7CisgICAgfQorICBlbHNlIGlmIChsZW5ndGggPT0gMSkKKyAgICB7CisgICAgICBoaWdoQml0ID0gaGlnaGVzdFNldEJpdCAoYXJnKTsKKyAgICAgIGlmIChoaWdoQml0IDw9IDUzKQorICAgICAgICB7CisgICAgICAgICAgaGlnaEJpdCA9IDUzIC0gaGlnaEJpdDsKKyAgICAgICAgICBtYW50aXNzYSA9ICphcmcgPDwgaGlnaEJpdDsKKyAgICAgICAgICBET1VCTEVfVE9fTE9OR0JJVFMgKHJlc3VsdCkgPQorICAgICAgICAgICAgQ1JFQVRFX0RPVUJMRV9CSVRTIChtYW50aXNzYSwgLWhpZ2hCaXQpOworICAgICAgICB9CisgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICBoaWdoQml0IC09IDUzOworICAgICAgICAgIG1hbnRpc3NhID0gKmFyZyA+PiBoaWdoQml0OworICAgICAgICAgIERPVUJMRV9UT19MT05HQklUUyAocmVzdWx0KSA9CisgICAgICAgICAgICBDUkVBVEVfRE9VQkxFX0JJVFMgKG1hbnRpc3NhLCBoaWdoQml0KTsKKworICAgICAgICAgIC8qIHBlcmZvcm0gcm91bmRpbmcsIHJvdW5kIHRvIGV2ZW4gaW4gY2FzZSBvZiB0aWUgKi8KKyAgICAgICAgICB0ZXN0ID0gKExPV19VMzJfRlJPTV9QVFIgKGFyZykgPDwgKDExIC0gaGlnaEJpdCkpICYgMHg3RkY7CisgICAgICAgICAgaWYgKHRlc3QgPiAweDQwMCB8fCAoKHRlc3QgPT0gMHg0MDApICYmIChtYW50aXNzYSAmIDEpKSkKKyAgICAgICAgICAgIERPVUJMRV9UT19MT05HQklUUyAocmVzdWx0KSA9IERPVUJMRV9UT19MT05HQklUUyAocmVzdWx0KSArIDE7CisgICAgICAgIH0KKyAgICB9CisgIGVsc2UKKyAgICB7CisgICAgICBoaWdoQml0ID0gaGlnaGVzdFNldEJpdCAoYXJnICsgKC0tbGVuZ3RoKSk7CisgICAgICBpZiAoaGlnaEJpdCA8PSA1MykKKyAgICAgICAgeworICAgICAgICAgIGhpZ2hCaXQgPSA1MyAtIGhpZ2hCaXQ7CisgICAgICAgICAgaWYgKGhpZ2hCaXQgPiAwKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICBtYW50aXNzYSA9CisgICAgICAgICAgICAgICAgKGFyZ1tsZW5ndGhdIDw8IGhpZ2hCaXQpIHwgKGFyZ1tsZW5ndGggLSAxXSA+PgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoNjQgLSBoaWdoQml0KSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgZWxzZQorICAgICAgICAgICAgeworICAgICAgICAgICAgICBtYW50aXNzYSA9IGFyZ1tsZW5ndGhdOworICAgICAgICAgICAgfQorICAgICAgICAgIERPVUJMRV9UT19MT05HQklUUyAocmVzdWx0KSA9CisgICAgICAgICAgICBDUkVBVEVfRE9VQkxFX0JJVFMgKG1hbnRpc3NhLCBsZW5ndGggKiA2NCAtIGhpZ2hCaXQpOworCisgICAgICAgICAgLyogcGVyZm9ybSByb3VuZGluZywgcm91bmQgdG8gZXZlbiBpbiBjYXNlIG9mIHRpZSAqLworICAgICAgICAgIHRlc3Q2NCA9IGFyZ1stLWxlbmd0aF0gPDwgaGlnaEJpdDsKKyAgICAgICAgICBpZiAodGVzdDY0ID4gU0lHTl9NQVNLIHx8ICgodGVzdDY0ID09IFNJR05fTUFTSykgJiYgKG1hbnRpc3NhICYgMSkpKQorICAgICAgICAgICAgRE9VQkxFX1RPX0xPTkdCSVRTIChyZXN1bHQpID0gRE9VQkxFX1RPX0xPTkdCSVRTIChyZXN1bHQpICsgMTsKKyAgICAgICAgICBlbHNlIGlmICh0ZXN0NjQgPT0gU0lHTl9NQVNLKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICB3aGlsZSAoLS1sZW5ndGggPj0gMCkKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICBpZiAoYXJnW2xlbmd0aF0gIT0gMCkKKyAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgIERPVUJMRV9UT19MT05HQklUUyAocmVzdWx0KSA9CisgICAgICAgICAgICAgICAgICAgICAgICBET1VCTEVfVE9fTE9OR0JJVFMgKHJlc3VsdCkgKyAxOworICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICBoaWdoQml0IC09IDUzOworICAgICAgICAgIG1hbnRpc3NhID0gYXJnW2xlbmd0aF0gPj4gaGlnaEJpdDsKKyAgICAgICAgICBET1VCTEVfVE9fTE9OR0JJVFMgKHJlc3VsdCkgPQorICAgICAgICAgICAgQ1JFQVRFX0RPVUJMRV9CSVRTIChtYW50aXNzYSwgbGVuZ3RoICogNjQgKyBoaWdoQml0KTsKKworICAgICAgICAgIC8qIHBlcmZvcm0gcm91bmRpbmcsIHJvdW5kIHRvIGV2ZW4gaW4gY2FzZSBvZiB0aWUgKi8KKyAgICAgICAgICB0ZXN0ID0gKExPV19VMzJfRlJPTV9QVFIgKGFyZyArIGxlbmd0aCkgPDwgKDExIC0gaGlnaEJpdCkpICYgMHg3RkY7CisgICAgICAgICAgaWYgKHRlc3QgPiAweDQwMCB8fCAoKHRlc3QgPT0gMHg0MDApICYmIChtYW50aXNzYSAmIDEpKSkKKyAgICAgICAgICAgIERPVUJMRV9UT19MT05HQklUUyAocmVzdWx0KSA9IERPVUJMRV9UT19MT05HQklUUyAocmVzdWx0KSArIDE7CisgICAgICAgICAgZWxzZSBpZiAodGVzdCA9PSAweDQwMCkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgZG8KKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICBpZiAoYXJnWy0tbGVuZ3RoXSAhPSAwKQorICAgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgRE9VQkxFX1RPX0xPTkdCSVRTIChyZXN1bHQpID0KKyAgICAgICAgICAgICAgICAgICAgICAgIERPVUJMRV9UT19MT05HQklUUyAocmVzdWx0KSArIDE7CisgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIHdoaWxlIChsZW5ndGggPiAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgdWludDY0X3Qgc2ltcGxlTXVsdGlwbHlIaWdoUHJlY2lzaW9uNjQodWludDY0X3QqIGFyZzEsIGludDMyX3QgbGVuZ3RoLCB1aW50NjRfdCBhcmcyKTsKKworaW50MzJfdAordGltZXNUZW5Ub1RoZUVIaWdoUHJlY2lzaW9uICh1aW50NjRfdCAqIHJlc3VsdCwgaW50MzJfdCBsZW5ndGgsIGppbnQgZSkKK3sKKyAgLyogYXNzdW1lcyByZXN1bHQgY2FuIGhvbGQgdmFsdWUgKi8KKyAgdWludDY0X3Qgb3ZlcmZsb3c7CisgIGludCBleHAxMCA9IGU7CisKKyAgaWYgKGUgPT0gMCkKKyAgICByZXR1cm4gbGVuZ3RoOworCisgIC8qIGJhZCBPKG4pIHdheSBvZiBkb2luZyBpdCwgYnV0IHNpbXBsZSAqLworICAvKgorICAgICBkbyB7CisgICAgIG92ZXJmbG93ID0gc2ltcGxlQXBwZW5kRGVjaW1hbERpZ2l0SGlnaFByZWNpc2lvbihyZXN1bHQsIGxlbmd0aCwgMCk7CisgICAgIGlmIChvdmVyZmxvdykKKyAgICAgcmVzdWx0W2xlbmd0aCsrXSA9IG92ZXJmbG93OworICAgICB9IHdoaWxlICgtLWUpOworICAgKi8KKyAgLyogUmVwbGFjZSB0aGUgY3VycmVudCBpbXBsZW1lbnRhaW9uIHdoaWNoIHBlcmZvcm1zIGEKKyAgICogIm11bHRpcGxpY2F0aW9uIiBieSAxMCBlIG51bWJlciBvZiB0aW1lcyB3aXRoIGFuIGFjdHVhbAorICAgKiBtdWx0aXBsaWNhdGlvbi4gMTBlMTkgaXMgdGhlIGxhcmdlc3QgZXhwb25lbnQgdG8gdGhlIHBvd2VyIG9mIHRlbgorICAgKiB0aGF0IHdpbGwgZml0IGluIGEgNjQtYml0IGludGVnZXIsIGFuZCAxMGU5IGlzIHRoZSBsYXJnZXN0IGV4cG9uZW50IHRvCisgICAqIHRoZSBwb3dlciBvZiB0ZW4gdGhhdCB3aWxsIGZpdCBpbiBhIDY0LWJpdCBpbnRlZ2VyLiBOb3Qgc3VyZSB3aGVyZSB0aGUKKyAgICogYnJlYWstZXZlbiBwb2ludCBpcyBiZXR3ZWVuIGFuIGFjdHVhbCBtdWx0aXBsaWNhdGlvbiBhbmQgYQorICAgKiBzaW1wbGVBYXBwZW5kRGVjaW1hbERpZ2l0KCkgc28ganVzdCBwaWNrIDEwZTMgYXMgdGhhdCBwb2ludCBmb3IKKyAgICogbm93LgorICAgKi8KKyAgd2hpbGUgKGV4cDEwID49IDE5KQorICAgIHsKKyAgICAgIG92ZXJmbG93ID0gc2ltcGxlTXVsdGlwbHlIaWdoUHJlY2lzaW9uNjQgKHJlc3VsdCwgbGVuZ3RoLCBURU5fRTE5KTsKKyAgICAgIGlmIChvdmVyZmxvdykKKyAgICAgICAgcmVzdWx0W2xlbmd0aCsrXSA9IG92ZXJmbG93OworICAgICAgZXhwMTAgLT0gMTk7CisgICAgfQorICB3aGlsZSAoZXhwMTAgPj0gOSkKKyAgICB7CisgICAgICBvdmVyZmxvdyA9IHNpbXBsZU11bHRpcGx5SGlnaFByZWNpc2lvbiAocmVzdWx0LCBsZW5ndGgsIFRFTl9FOSk7CisgICAgICBpZiAob3ZlcmZsb3cpCisgICAgICAgIHJlc3VsdFtsZW5ndGgrK10gPSBvdmVyZmxvdzsKKyAgICAgIGV4cDEwIC09IDk7CisgICAgfQorICBpZiAoZXhwMTAgPT0gMCkKKyAgICByZXR1cm4gbGVuZ3RoOworICBlbHNlIGlmIChleHAxMCA9PSAxKQorICAgIHsKKyAgICAgIG92ZXJmbG93ID0gc2ltcGxlQXBwZW5kRGVjaW1hbERpZ2l0SGlnaFByZWNpc2lvbiAocmVzdWx0LCBsZW5ndGgsIDApOworICAgICAgaWYgKG92ZXJmbG93KQorICAgICAgICByZXN1bHRbbGVuZ3RoKytdID0gb3ZlcmZsb3c7CisgICAgfQorICBlbHNlIGlmIChleHAxMCA9PSAyKQorICAgIHsKKyAgICAgIG92ZXJmbG93ID0gc2ltcGxlQXBwZW5kRGVjaW1hbERpZ2l0SGlnaFByZWNpc2lvbiAocmVzdWx0LCBsZW5ndGgsIDApOworICAgICAgaWYgKG92ZXJmbG93KQorICAgICAgICByZXN1bHRbbGVuZ3RoKytdID0gb3ZlcmZsb3c7CisgICAgICBvdmVyZmxvdyA9IHNpbXBsZUFwcGVuZERlY2ltYWxEaWdpdEhpZ2hQcmVjaXNpb24gKHJlc3VsdCwgbGVuZ3RoLCAwKTsKKyAgICAgIGlmIChvdmVyZmxvdykKKyAgICAgICAgcmVzdWx0W2xlbmd0aCsrXSA9IG92ZXJmbG93OworICAgIH0KKyAgZWxzZSBpZiAoZXhwMTAgPT0gMykKKyAgICB7CisgICAgICBvdmVyZmxvdyA9IHNpbXBsZU11bHRpcGx5SGlnaFByZWNpc2lvbiAocmVzdWx0LCBsZW5ndGgsIFRFTl9FMyk7CisgICAgICBpZiAob3ZlcmZsb3cpCisgICAgICAgIHJlc3VsdFtsZW5ndGgrK10gPSBvdmVyZmxvdzsKKyAgICB9CisgIGVsc2UgaWYgKGV4cDEwID09IDQpCisgICAgeworICAgICAgb3ZlcmZsb3cgPSBzaW1wbGVNdWx0aXBseUhpZ2hQcmVjaXNpb24gKHJlc3VsdCwgbGVuZ3RoLCBURU5fRTQpOworICAgICAgaWYgKG92ZXJmbG93KQorICAgICAgICByZXN1bHRbbGVuZ3RoKytdID0gb3ZlcmZsb3c7CisgICAgfQorICBlbHNlIGlmIChleHAxMCA9PSA1KQorICAgIHsKKyAgICAgIG92ZXJmbG93ID0gc2ltcGxlTXVsdGlwbHlIaWdoUHJlY2lzaW9uIChyZXN1bHQsIGxlbmd0aCwgVEVOX0U1KTsKKyAgICAgIGlmIChvdmVyZmxvdykKKyAgICAgICAgcmVzdWx0W2xlbmd0aCsrXSA9IG92ZXJmbG93OworICAgIH0KKyAgZWxzZSBpZiAoZXhwMTAgPT0gNikKKyAgICB7CisgICAgICBvdmVyZmxvdyA9IHNpbXBsZU11bHRpcGx5SGlnaFByZWNpc2lvbiAocmVzdWx0LCBsZW5ndGgsIFRFTl9FNik7CisgICAgICBpZiAob3ZlcmZsb3cpCisgICAgICAgIHJlc3VsdFtsZW5ndGgrK10gPSBvdmVyZmxvdzsKKyAgICB9CisgIGVsc2UgaWYgKGV4cDEwID09IDcpCisgICAgeworICAgICAgb3ZlcmZsb3cgPSBzaW1wbGVNdWx0aXBseUhpZ2hQcmVjaXNpb24gKHJlc3VsdCwgbGVuZ3RoLCBURU5fRTcpOworICAgICAgaWYgKG92ZXJmbG93KQorICAgICAgICByZXN1bHRbbGVuZ3RoKytdID0gb3ZlcmZsb3c7CisgICAgfQorICBlbHNlIGlmIChleHAxMCA9PSA4KQorICAgIHsKKyAgICAgIG92ZXJmbG93ID0gc2ltcGxlTXVsdGlwbHlIaWdoUHJlY2lzaW9uIChyZXN1bHQsIGxlbmd0aCwgVEVOX0U4KTsKKyAgICAgIGlmIChvdmVyZmxvdykKKyAgICAgICAgcmVzdWx0W2xlbmd0aCsrXSA9IG92ZXJmbG93OworICAgIH0KKyAgcmV0dXJuIGxlbmd0aDsKK30KKwordWludDY0X3QKK2RvdWJsZU1hbnRpc3NhIChqZG91YmxlIHopCit7CisgIHVpbnQ2NF90IG0gPSBET1VCTEVfVE9fTE9OR0JJVFMgKHopOworCisgIGlmICgobSAmIEVYUE9ORU5UX01BU0spICE9IDApCisgICAgbSA9IChtICYgTUFOVElTU0FfTUFTSykgfCBOT1JNQUxfTUFTSzsKKyAgZWxzZQorICAgIG0gPSAobSAmIE1BTlRJU1NBX01BU0spOworCisgIHJldHVybiBtOworfQorCitpbnQzMl90Citkb3VibGVFeHBvbmVudCAoamRvdWJsZSB6KQoreworICAvKiBhc3N1bWVzIHBvc2l0aXZlIGRvdWJsZSAqLworICBpbnQzMl90IGsgPSBISUdIX1UzMl9GUk9NX1ZBUiAoeikgPj4gMjA7CisKKyAgaWYgKGspCisgICAgayAtPSBFX09GRlNFVDsKKyAgZWxzZQorICAgIGsgPSAxIC0gRV9PRkZTRVQ7CisKKyAgcmV0dXJuIGs7Cit9CisKK3VpbnQzMl90IGZsb2F0TWFudGlzc2EoamZsb2F0IHopIHsKKyAgdWludDMyX3QgbSA9IEZMT0FUX1RPX0lOVEJJVFMgKHopOworCisgIGlmICgobSAmIEZMT0FUX0VYUE9ORU5UX01BU0spICE9IDApCisgICAgbSA9IChtICYgRkxPQVRfTUFOVElTU0FfTUFTSykgfCBGTE9BVF9OT1JNQUxfTUFTSzsKKyAgZWxzZQorICAgIG0gPSAobSAmIEZMT0FUX01BTlRJU1NBX01BU0spOworCisgIHJldHVybiBtOworfQorCitpbnQzMl90CitmbG9hdEV4cG9uZW50IChqZmxvYXQgeikKK3sKKyAgLyogYXNzdW1lcyBwb3NpdGl2ZSBmbG9hdCAqLworICBpbnQzMl90IGsgPSBGTE9BVF9UT19JTlRCSVRTICh6KSA+PiAyMzsKKyAgaWYgKGspCisgICAgayAtPSBGTE9BVF9FX09GRlNFVDsKKyAgZWxzZQorICAgIGsgPSAxIC0gRkxPQVRfRV9PRkZTRVQ7CisKKyAgcmV0dXJuIGs7Cit9CisKKy8qIEFsbG93IGEgNjQtYml0IHZhbHVlIGluIGFyZzIgKi8KK3VpbnQ2NF90CitzaW1wbGVNdWx0aXBseUhpZ2hQcmVjaXNpb242NCAodWludDY0X3QgKiBhcmcxLCBpbnQzMl90IGxlbmd0aCwgdWludDY0X3QgYXJnMikKK3sKKyAgdWludDY0X3QgaW50ZXJtZWRpYXRlLCBjYXJyeTEsIGNhcnJ5MiwgcHJvZDEsIHByb2QyLCBzdW07CisgIHVpbnQ2NF90KiBwQXJnMTsKKyAgaW50MzJfdCBpbmRleDsKKyAgdWludDMyX3QgYnVmMzI7CisKKyAgaW5kZXggPSAwOworICBpbnRlcm1lZGlhdGUgPSAwOworICBwQXJnMSA9IGFyZzEgKyBpbmRleDsKKyAgY2FycnkxID0gY2FycnkyID0gMDsKKworICBkbworICAgIHsKKyAgICAgIGlmICgoKnBBcmcxICE9IDApIHx8IChpbnRlcm1lZGlhdGUgIT0gMCkpCisgICAgICAgIHsKKyAgICAgICAgICBwcm9kMSA9CisgICAgICAgICAgICBzdGF0aWNfY2FzdDx1aW50NjRfdD4oTE9XX1UzMl9GUk9NX1ZBUiAoYXJnMikpICogc3RhdGljX2Nhc3Q8dWludDY0X3Q+KExPV19VMzJfRlJPTV9QVFIgKHBBcmcxKSk7CisgICAgICAgICAgc3VtID0gaW50ZXJtZWRpYXRlICsgcHJvZDE7CisgICAgICAgICAgaWYgKChzdW0gPCBwcm9kMSkgfHwgKHN1bSA8IGludGVybWVkaWF0ZSkpCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgIGNhcnJ5MSA9IDE7CisgICAgICAgICAgICB9CisgICAgICAgICAgZWxzZQorICAgICAgICAgICAgeworICAgICAgICAgICAgICBjYXJyeTEgPSAwOworICAgICAgICAgICAgfQorICAgICAgICAgIHByb2QxID0KKyAgICAgICAgICAgIHN0YXRpY19jYXN0PHVpbnQ2NF90PihMT1dfVTMyX0ZST01fVkFSIChhcmcyKSkgKiBzdGF0aWNfY2FzdDx1aW50NjRfdD4oSElHSF9VMzJfRlJPTV9QVFIgKHBBcmcxKSk7CisgICAgICAgICAgcHJvZDIgPQorICAgICAgICAgICAgc3RhdGljX2Nhc3Q8dWludDY0X3Q+KEhJR0hfVTMyX0ZST01fVkFSIChhcmcyKSkgKiBzdGF0aWNfY2FzdDx1aW50NjRfdD4oTE9XX1UzMl9GUk9NX1BUUiAocEFyZzEpKTsKKyAgICAgICAgICBpbnRlcm1lZGlhdGUgPSBjYXJyeTIgKyBISUdIX0lOX1U2NCAoc3VtKSArIHByb2QxICsgcHJvZDI7CisgICAgICAgICAgaWYgKChpbnRlcm1lZGlhdGUgPCBwcm9kMSkgfHwgKGludGVybWVkaWF0ZSA8IHByb2QyKSkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgY2FycnkyID0gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICBlbHNlCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgIGNhcnJ5MiA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgTE9XX1UzMl9GUk9NX1BUUiAocEFyZzEpID0gTE9XX1UzMl9GUk9NX1ZBUiAoc3VtKTsKKyAgICAgICAgICBidWYzMiA9IEhJR0hfVTMyX0ZST01fUFRSIChwQXJnMSk7CisgICAgICAgICAgSElHSF9VMzJfRlJPTV9QVFIgKHBBcmcxKSA9IExPV19VMzJfRlJPTV9WQVIgKGludGVybWVkaWF0ZSk7CisgICAgICAgICAgaW50ZXJtZWRpYXRlID0gY2FycnkxICsgSElHSF9JTl9VNjQgKGludGVybWVkaWF0ZSkKKyAgICAgICAgICAgICsgc3RhdGljX2Nhc3Q8dWludDY0X3Q+KEhJR0hfVTMyX0ZST01fVkFSIChhcmcyKSkgKiBzdGF0aWNfY2FzdDx1aW50NjRfdD4oYnVmMzIpOworICAgICAgICB9CisgICAgICBwQXJnMSsrOworICAgIH0KKyAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpOworICByZXR1cm4gaW50ZXJtZWRpYXRlOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvY2JpZ2ludC5oIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvY2JpZ2ludC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiZjViMWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9jYmlnaW50LmgKQEAgLTAsMCArMSwxMDcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZiAhZGVmaW5lZChjYmlnaW50X2gpCisjZGVmaW5lIGNiaWdpbnRfaAorCisjaW5jbHVkZSAiSk5JSGVscC5oIgorCisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8c3lzL3BhcmFtLmg+CisjaW5jbHVkZSA8c3RkaW50Lmg+CisKKy8qIElFRUUgZmxvYXRzIGNvbnNpc3Qgb2Y6IHNpZ24gYml0LCBleHBvbmVudCBmaWVsZCwgc2lnbmlmaWNhbmQgZmllbGQKKyAgICBzaW5nbGU6ICAzMSA9IHNpZ24gYml0LCAzMC4uMjMgPSBleHBvbmVudCAoOCBiaXRzKSwgMjIuLjAgPSBzaWduaWZpY2FuZCAoMjMgYml0cykKKyAgICBkb3VibGU6ICA2MyA9IHNpZ24gYml0LCA2Mi4uNTIgPSBleHBvbmVudCAoMTEgYml0cyksIDUxLi4wID0gc2lnbmlmaWNhbmQgKDUyIGJpdHMpCisgICAgaW5mICAgICAgICAgICAgICAgID09ICAgIChhbGwgZXhwb25lbnQgYml0cyBzZXQpIGFuZCAoYWxsIG1hbnRpc3NhIGJpdHMgY2xlYXIpCisgICAgbmFuICAgICAgICAgICAgICAgID09ICAgIChhbGwgZXhwb25lbnQgYml0cyBzZXQpIGFuZCAoYXQgbGVhc3Qgb25lIG1hbnRpc3NhIGJpdCBzZXQpCisgICAgZmluaXRlICAgICAgICAgICAgID09ICAgIChhdCBsZWFzdCBvbmUgZXhwb25lbnQgYml0IGNsZWFyKQorICAgIHplcm8gICAgICAgICAgICAgICA9PSAgICAoYWxsIGV4cG9uZW50IGJpdHMgY2xlYXIpIGFuZCAoYWxsIG1hbnRpc3NhIGJpdHMgY2xlYXIpCisgICAgZGVub3JtYWwgICAgICAgICAgID09ICAgIChhbGwgZXhwb25lbnQgYml0cyBjbGVhcikgYW5kIChhdCBsZWFzdCBvbmUgbWFudGlzc2EgYml0IHNldCkKKyAgICBwb3NpdGl2ZSAgICAgICAgICAgPT0gICAgc2lnbiBiaXQgY2xlYXIKKyAgICBuZWdhdGl2ZSAgICAgICAgICAgPT0gICAgc2lnbiBiaXQgc2V0CisqLworI2lmIF9fQllURV9PUkRFUiA9PSBfX0xJVFRMRV9FTkRJQU4KKyNkZWZpbmUgRE9VQkxFX0xPX09GRlNFVCAgICAgICAgMAorI2RlZmluZSBET1VCTEVfSElfT0ZGU0VUICAgICAgICAxCisjZGVmaW5lIExPTkdfTE9fT0ZGU0VUICAgICAgICAgIDAKKyNkZWZpbmUgTE9OR19ISV9PRkZTRVQgICAgICAgICAgMQorI2Vsc2UKKyNkZWZpbmUgRE9VQkxFX0xPX09GRlNFVCAgICAgICAgMQorI2RlZmluZSBET1VCTEVfSElfT0ZGU0VUICAgICAgICAwCisjZGVmaW5lIExPTkdfTE9fT0ZGU0VUICAgICAgICAgIDEKKyNkZWZpbmUgTE9OR19ISV9PRkZTRVQgICAgICAgICAgMAorI2VuZGlmCisKKyNkZWZpbmUgRE9VQkxFX0VYUE9ORU5UX01BU0tfSEkgMHg3RkYwMDAwMAorI2RlZmluZSBET1VCTEVfTUFOVElTU0FfTUFTS19ISSAweDAwMEZGRkZGCisKK3VuaW9uIFU2NFUzMkRCTCB7CisgICAgdWludDY0X3QgICAgdTY0dmFsOworICAgIHVpbnQzMl90ICAgIHUzMnZhbFsyXTsKKyAgICBpbnQzMl90ICAgIGkzMnZhbFsyXTsKKyAgICBkb3VibGUgIGR2YWw7Cit9OworCisjZGVmaW5lIERPVUJMRV9UT19MT05HQklUUyhkYmwpICgqKHJlaW50ZXJwcmV0X2Nhc3Q8dWludDY0X3QqPigmZGJsKSkpCisjZGVmaW5lIEZMT0FUX1RPX0lOVEJJVFMoZmx0KSAoKihyZWludGVycHJldF9jYXN0PHVpbnQzMl90Kj4oJmZsdCkpKQorI2RlZmluZSBJTlRCSVRTX1RPX0ZMT0FUKGJpdHMpICgqKHJlaW50ZXJwcmV0X2Nhc3Q8ZmxvYXQqPigmYml0cykpKQorCisvKiBSZXBsYWNlIFBfRkxPQVRfSEkgYW5kIFBfRkxPQVRfTE9XICovCisvKiBUaGVzZSBtYWNyb3MgYXJlIHVzZWQgdG8gYWNjZXNzIHRoZSBoaWdoIGFuZCBsb3cgMzItYml0IHBhcnRzIG9mIGEgZG91YmxlICg2NC1iaXQpIHZhbHVlLiAqLworI2RlZmluZSBMT1dfVTMyX0ZST01fREJMX1BUUihkYmxwdHIpICgocmVpbnRlcnByZXRfY2FzdDxVNjRVMzJEQkwqPihkYmxwdHIpKS0+dTMydmFsW0RPVUJMRV9MT19PRkZTRVRdKQorI2RlZmluZSBISUdIX1UzMl9GUk9NX0RCTF9QVFIoZGJscHRyKSAoKHJlaW50ZXJwcmV0X2Nhc3Q8VTY0VTMyREJMKj4oZGJscHRyKSktPnUzMnZhbFtET1VCTEVfSElfT0ZGU0VUXSkKKyNkZWZpbmUgTE9XX0kzMl9GUk9NX0RCTF9QVFIoZGJscHRyKSAoKHJlaW50ZXJwcmV0X2Nhc3Q8VTY0VTMyREJMKj4oZGJscHRyKSktPmkzMnZhbFtET1VCTEVfTE9fT0ZGU0VUXSkKKyNkZWZpbmUgSElHSF9JMzJfRlJPTV9EQkxfUFRSKGRibHB0cikgKChyZWludGVycHJldF9jYXN0PFU2NFUzMkRCTCo+KGRibHB0cikpLT5pMzJ2YWxbRE9VQkxFX0hJX09GRlNFVF0pCisjZGVmaW5lIExPV19VMzJfRlJPTV9EQkwoZGJsKSBMT1dfVTMyX0ZST01fREJMX1BUUigmKGRibCkpCisjZGVmaW5lIEhJR0hfVTMyX0ZST01fREJMKGRibCkgSElHSF9VMzJfRlJPTV9EQkxfUFRSKCYoZGJsKSkKKyNkZWZpbmUgTE9XX1UzMl9GUk9NX0xPTkc2NF9QVFIobG9uZzY0cHRyKSAoKHJlaW50ZXJwcmV0X2Nhc3Q8VTY0VTMyREJMKj4obG9uZzY0cHRyKSktPnUzMnZhbFtMT05HX0xPX09GRlNFVF0pCisjZGVmaW5lIEhJR0hfVTMyX0ZST01fTE9ORzY0X1BUUihsb25nNjRwdHIpICgocmVpbnRlcnByZXRfY2FzdDxVNjRVMzJEQkwqPihsb25nNjRwdHIpKS0+dTMydmFsW0xPTkdfSElfT0ZGU0VUXSkKKyNkZWZpbmUgTE9XX0kzMl9GUk9NX0xPTkc2NF9QVFIobG9uZzY0cHRyKSAoKHJlaW50ZXJwcmV0X2Nhc3Q8VTY0VTMyREJMKj4obG9uZzY0cHRyKSktPmkzMnZhbFtMT05HX0xPX09GRlNFVF0pCisjZGVmaW5lIEhJR0hfSTMyX0ZST01fTE9ORzY0X1BUUihsb25nNjRwdHIpICgocmVpbnRlcnByZXRfY2FzdDxVNjRVMzJEQkwqPihsb25nNjRwdHIpKS0+aTMydmFsW0xPTkdfSElfT0ZGU0VUXSkKKyNkZWZpbmUgTE9XX1UzMl9GUk9NX0xPTkc2NChsb25nNjQpIExPV19VMzJfRlJPTV9MT05HNjRfUFRSKCYobG9uZzY0KSkKKyNkZWZpbmUgSElHSF9VMzJfRlJPTV9MT05HNjQobG9uZzY0KSBISUdIX1UzMl9GUk9NX0xPTkc2NF9QVFIoJihsb25nNjQpKQorI2RlZmluZSBMT1dfSTMyX0ZST01fTE9ORzY0KGxvbmc2NCkgTE9XX0kzMl9GUk9NX0xPTkc2NF9QVFIoJihsb25nNjQpKQorI2RlZmluZSBISUdIX0kzMl9GUk9NX0xPTkc2NChsb25nNjQpIEhJR0hfSTMyX0ZST01fTE9ORzY0X1BUUigmKGxvbmc2NCkpCisjZGVmaW5lIElTX0RFTk9STUFMX0RCTF9QVFIoZGJscHRyKSAoKChISUdIX1UzMl9GUk9NX0RCTF9QVFIoZGJscHRyKSAmIERPVUJMRV9FWFBPTkVOVF9NQVNLX0hJKSA9PSAwKSAmJiAoKEhJR0hfVTMyX0ZST01fREJMX1BUUihkYmxwdHIpICYgRE9VQkxFX01BTlRJU1NBX01BU0tfSEkpICE9IDAgfHwgKExPV19VMzJfRlJPTV9EQkxfUFRSKGRibHB0cikgIT0gMCkpKQorI2RlZmluZSBJU19ERU5PUk1BTF9EQkwoZGJsKSBJU19ERU5PUk1BTF9EQkxfUFRSKCYoZGJsKSkKKworI2RlZmluZSBMT1dfVTMyX0ZST01fVkFSKHU2NCkgICAgIExPV19VMzJfRlJPTV9MT05HNjQodTY0KQorI2RlZmluZSBMT1dfVTMyX0ZST01fUFRSKHU2NHB0cikgIExPV19VMzJfRlJPTV9MT05HNjRfUFRSKHU2NHB0cikKKyNkZWZpbmUgSElHSF9VMzJfRlJPTV9WQVIodTY0KSAgICBISUdIX1UzMl9GUk9NX0xPTkc2NCh1NjQpCisjZGVmaW5lIEhJR0hfVTMyX0ZST01fUFRSKHU2NHB0cikgSElHSF9VMzJfRlJPTV9MT05HNjRfUFRSKHU2NHB0cikKKwordm9pZCBtdWx0aXBseUhpZ2hQcmVjaXNpb24odWludDY0X3QqIGFyZzEsIGludDMyX3QgbGVuZ3RoMSwgdWludDY0X3QqIGFyZzIsIGludDMyX3QgbGVuZ3RoMiwKKyAgICAgICAgdWludDY0X3QqIHJlc3VsdCwgaW50MzJfdCBsZW5ndGgpOwordWludDMyX3Qgc2ltcGxlQXBwZW5kRGVjaW1hbERpZ2l0SGlnaFByZWNpc2lvbih1aW50NjRfdCogYXJnMSwgaW50MzJfdCBsZW5ndGgsIHVpbnQ2NF90IGRpZ2l0KTsKK2pkb3VibGUgdG9Eb3VibGVIaWdoUHJlY2lzaW9uKHVpbnQ2NF90KiBhcmcsIGludDMyX3QgbGVuZ3RoKTsKK3VpbnQ2NF90IGRvdWJsZU1hbnRpc3NhKGpkb3VibGUgeik7CitpbnQzMl90IGNvbXBhcmVIaWdoUHJlY2lzaW9uKHVpbnQ2NF90KiBhcmcxLCBpbnQzMl90IGxlbmd0aDEsIHVpbnQ2NF90KiBhcmcyLCBpbnQzMl90IGxlbmd0aDIpOworaW50MzJfdCBoaWdoZXN0U2V0Qml0SGlnaFByZWNpc2lvbih1aW50NjRfdCogYXJnLCBpbnQzMl90IGxlbmd0aCk7Cit2b2lkIHN1YnRyYWN0SGlnaFByZWNpc2lvbih1aW50NjRfdCogYXJnMSwgaW50MzJfdCBsZW5ndGgxLCB1aW50NjRfdCogYXJnMiwgaW50MzJfdCBsZW5ndGgyKTsKK2ludDMyX3QgZG91YmxlRXhwb25lbnQoamRvdWJsZSB6KTsKK2ludDMyX3QgYWRkSGlnaFByZWNpc2lvbih1aW50NjRfdCogYXJnMSwgaW50MzJfdCBsZW5ndGgxLCB1aW50NjRfdCogYXJnMiwgaW50MzJfdCBsZW5ndGgyKTsKK2ludDMyX3QgbG93ZXN0U2V0Qml0KHVpbnQ2NF90KiB5KTsKK2ludDMyX3QgdGltZXNUZW5Ub1RoZUVIaWdoUHJlY2lzaW9uKHVpbnQ2NF90KiByZXN1bHQsIGludDMyX3QgbGVuZ3RoLCBqaW50IGUpOworaW50MzJfdCBoaWdoZXN0U2V0Qml0KHVpbnQ2NF90KiB5KTsKK2ludDMyX3QgbG93ZXN0U2V0Qml0SGlnaFByZWNpc2lvbih1aW50NjRfdCogYXJnLCBpbnQzMl90IGxlbmd0aCk7Cit2b2lkIHNpbXBsZVNoaWZ0TGVmdEhpZ2hQcmVjaXNpb24odWludDY0X3QqIGFyZzEsIGludDMyX3QgbGVuZ3RoLCBpbnQzMl90IGFyZzIpOwordWludDMyX3QgZmxvYXRNYW50aXNzYShqZmxvYXQgeik7CitpbnQzMl90IHNpbXBsZUFkZEhpZ2hQcmVjaXNpb24odWludDY0X3QqIGFyZzEsIGludDMyX3QgbGVuZ3RoLCB1aW50NjRfdCBhcmcyKTsKK2ludDMyX3QgZmxvYXRFeHBvbmVudChqZmxvYXQgeik7CisKKyNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogY2JpZ2ludF9oICovCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX2lvX0NvbnNvbGUuY3BwIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV9pb19Db25zb2xlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MTUwZmI3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV9pb19Db25zb2xlLmNwcApAQCAtMCwwICsxLDUxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIkNvbnNvbGUiCisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisKKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPHRlcm1pb3MuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKworc3RhdGljIGppbnQgQ29uc29sZV9zZXRFY2hvSW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqYm9vbGVhbiBvbiwgamludCBwcmV2aW91c1N0YXRlKSB7CisgICAgdGVybWlvcyBzdGF0ZTsKKyAgICBpZiAoVEVNUF9GQUlMVVJFX1JFVFJZKHRjZ2V0YXR0cihTVERJTl9GSUxFTk8sICZzdGF0ZSkpID09IC0xKSB7CisgICAgICAgIGpuaVRocm93SU9FeGNlcHRpb24oZW52LCBlcnJubyk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBpZiAob24pIHsKKyAgICAgICAgc3RhdGUuY19sZmxhZyA9IHByZXZpb3VzU3RhdGU7CisgICAgfSBlbHNlIHsKKyAgICAgICAgcHJldmlvdXNTdGF0ZSA9IHN0YXRlLmNfbGZsYWc7CisgICAgICAgIHN0YXRlLmNfbGZsYWcgJj0gfihFQ0hPIHwgRUNIT0UgfCBFQ0hPSyB8IEVDSE9OTCk7CisgICAgfQorICAgIGlmIChURU1QX0ZBSUxVUkVfUkVUUlkodGNzZXRhdHRyKFNURElOX0ZJTEVOTywgVENTQUZMVVNILCAmc3RhdGUpKSA9PSAtMSl7CisgICAgICAgIGpuaVRocm93SU9FeGNlcHRpb24oZW52LCBlcnJubyk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICByZXR1cm4gcHJldmlvdXNTdGF0ZTsKK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBnTWV0aG9kc1tdID0geworICAgIE5BVElWRV9NRVRIT0QoQ29uc29sZSwgc2V0RWNob0ltcGwsICIoWkkpSSIpLAorfTsKK2ludCByZWdpc3Rlcl9qYXZhX2lvX0NvbnNvbGUoSk5JRW52KiBlbnYpIHsKKyAgICByZXR1cm4gam5pUmVnaXN0ZXJOYXRpdmVNZXRob2RzKGVudiwgImphdmEvaW8vQ29uc29sZSIsIGdNZXRob2RzLCBORUxFTShnTWV0aG9kcykpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV9pb19GaWxlLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfaW9fRmlsZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGI4OGExMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfaW9fRmlsZS5jcHAKQEAgLTAsMCArMSwxNzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiRmlsZSIKKworI2luY2x1ZGUgIkpOSUhlbHAuaCIKKyNpbmNsdWRlICJKbmlDb25zdGFudHMuaCIKKyNpbmNsdWRlICJKbmlFeGNlcHRpb24uaCIKKyNpbmNsdWRlICJTY29wZWRQcmltaXRpdmVBcnJheS5oIgorI2luY2x1ZGUgIlNjb3BlZFV0ZkNoYXJzLmgiCisjaW5jbHVkZSAicmVhZGxpbmsuaCIKKyNpbmNsdWRlICJ0b1N0cmluZ0FycmF5LmgiCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8ZGlyZW50Lmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8c3lzL3Zmcy5oPgorI2luY2x1ZGUgPHRpbWUuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNpbmNsdWRlIDx1dGltZS5oPgorCitzdGF0aWMganN0cmluZyBGaWxlX3JlYWRsaW5rKEpOSUVudiogZW52LCBqY2xhc3MsIGpzdHJpbmcgamF2YVBhdGgpIHsKKyAgICBTY29wZWRVdGZDaGFycyBwYXRoKGVudiwgamF2YVBhdGgpOworICAgIGlmIChwYXRoLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBzdGQ6OnN0cmluZyByZXN1bHQ7CisgICAgaWYgKCFyZWFkbGluayhwYXRoLmNfc3RyKCksIHJlc3VsdCkpIHsKKyAgICAgICAgam5pVGhyb3dJT0V4Y2VwdGlvbihlbnYsIGVycm5vKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBlbnYtPk5ld1N0cmluZ1VURihyZXN1bHQuY19zdHIoKSk7Cit9CisKK3N0YXRpYyBqc3RyaW5nIEZpbGVfcmVhbHBhdGgoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBqYXZhUGF0aCkgeworICAgIFNjb3BlZFV0ZkNoYXJzIHBhdGgoZW52LCBqYXZhUGF0aCk7CisgICAgaWYgKHBhdGguY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGV4dGVybiBib29sIHJlYWxwYXRoKGNvbnN0IGNoYXIqIHBhdGgsIHN0ZDo6c3RyaW5nJiByZXNvbHZlZCk7CisgICAgc3RkOjpzdHJpbmcgcmVzdWx0OworICAgIGlmICghcmVhbHBhdGgocGF0aC5jX3N0cigpLCByZXN1bHQpKSB7CisgICAgICAgIGpuaVRocm93SU9FeGNlcHRpb24oZW52LCBlcnJubyk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gZW52LT5OZXdTdHJpbmdVVEYocmVzdWx0LmNfc3RyKCkpOworfQorCitzdGF0aWMgamJvb2xlYW4gRmlsZV9zZXRMYXN0TW9kaWZpZWRJbXBsKEpOSUVudiogZW52LCBqY2xhc3MsIGpzdHJpbmcgamF2YVBhdGgsIGpsb25nIG1zKSB7CisgICAgU2NvcGVkVXRmQ2hhcnMgcGF0aChlbnYsIGphdmFQYXRoKTsKKyAgICBpZiAocGF0aC5jX3N0cigpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICB9CisKKyAgICAvLyBXZSB3YW50IHRvIHByZXNlcnZlIHRoZSBhY2Nlc3MgdGltZS4KKyAgICBzdHJ1Y3Qgc3RhdCBzYjsKKyAgICBpZiAoc3RhdChwYXRoLmNfc3RyKCksICZzYikgPT0gLTEpIHsKKyAgICAgICAgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICB9CisKKyAgICAvLyBUT0RPOiB3ZSBjb3VsZCBnZXQgbWljcm9zZWNvbmQgcmVzb2x1dGlvbiB3aXRoIHV0aW1lcygzKSwgImxlZ2FjeSIgdGhvdWdoIGl0IGlzLgorICAgIHV0aW1idWYgdGltZXM7CisgICAgdGltZXMuYWN0aW1lID0gc2Iuc3RfYXRpbWU7CisgICAgdGltZXMubW9kdGltZSA9IHN0YXRpY19jYXN0PHRpbWVfdD4obXMgLyAxMDAwKTsKKyAgICByZXR1cm4gKHV0aW1lKHBhdGguY19zdHIoKSwgJnRpbWVzKSA9PSAwKTsKK30KKworLy8gSXRlcmF0ZXMgb3ZlciB0aGUgZmlsZW5hbWVzIGluIHRoZSBnaXZlbiBkaXJlY3RvcnkuCitjbGFzcyBTY29wZWRSZWFkZGlyIHsKK3B1YmxpYzoKKyAgICBTY29wZWRSZWFkZGlyKGNvbnN0IGNoYXIqIHBhdGgpIHsKKyAgICAgICAgbURpclN0cmVhbSA9IG9wZW5kaXIocGF0aCk7CisgICAgICAgIG1Jc0JhZCA9IChtRGlyU3RyZWFtID09IE5VTEwpOworICAgIH0KKworICAgIH5TY29wZWRSZWFkZGlyKCkgeworICAgICAgICBpZiAobURpclN0cmVhbSAhPSBOVUxMKSB7CisgICAgICAgICAgICBjbG9zZWRpcihtRGlyU3RyZWFtKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdGhlIG5leHQgZmlsZW5hbWUsIG9yIE5VTEwuCisgICAgY29uc3QgY2hhciogbmV4dCgpIHsKKyAgICAgICAgZGlyZW50KiByZXN1bHQgPSBOVUxMOworICAgICAgICBpbnQgcmMgPSByZWFkZGlyX3IobURpclN0cmVhbSwgJm1FbnRyeSwgJnJlc3VsdCk7CisgICAgICAgIGlmIChyYyAhPSAwKSB7CisgICAgICAgICAgICBtSXNCYWQgPSB0cnVlOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChyZXN1bHQgIT0gTlVMTCkgPyByZXN1bHQtPmRfbmFtZSA6IE5VTEw7CisgICAgfQorCisgICAgLy8gSGFzIGFuIGVycm9yIG9jY3VycmVkIG9uIHRoaXMgc3RyZWFtPworICAgIGJvb2wgaXNCYWQoKSBjb25zdCB7CisgICAgICAgIHJldHVybiBtSXNCYWQ7CisgICAgfQorCitwcml2YXRlOgorICAgIERJUiogbURpclN0cmVhbTsKKyAgICBkaXJlbnQgbUVudHJ5OworICAgIGJvb2wgbUlzQmFkOworCisgICAgLy8gRGlzYWxsb3cgY29weSBhbmQgYXNzaWdubWVudC4KKyAgICBTY29wZWRSZWFkZGlyKGNvbnN0IFNjb3BlZFJlYWRkaXImKTsKKyAgICB2b2lkIG9wZXJhdG9yPShjb25zdCBTY29wZWRSZWFkZGlyJik7Cit9OworCit0eXBlZGVmIHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiBEaXJFbnRyaWVzOworCisvLyBSZWFkcyB0aGUgZGlyZWN0b3J5IHJlZmVycmVkIHRvIGJ5ICdwYXRoQnl0ZXMnLCBhZGRpbmcgZWFjaCBkaXJlY3RvcnkgZW50cnkKKy8vIHRvICdlbnRyaWVzJy4KK3N0YXRpYyBib29sIHJlYWREaXJlY3RvcnkoSk5JRW52KiBlbnYsIGpzdHJpbmcgamF2YVBhdGgsIERpckVudHJpZXMmIGVudHJpZXMpIHsKKyAgICBTY29wZWRVdGZDaGFycyBwYXRoKGVudiwgamF2YVBhdGgpOworICAgIGlmIChwYXRoLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgU2NvcGVkUmVhZGRpciBkaXIocGF0aC5jX3N0cigpKTsKKyAgICBpZiAoZGlyLmlzQmFkKCkpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBjb25zdCBjaGFyKiBmaWxlbmFtZTsKKyAgICB3aGlsZSAoKGZpbGVuYW1lID0gZGlyLm5leHQoKSkgIT0gTlVMTCkgeworICAgICAgICBpZiAoc3RyY21wKGZpbGVuYW1lLCAiLiIpICE9IDAgJiYgc3RyY21wKGZpbGVuYW1lLCAiLi4iKSAhPSAwKSB7CisgICAgICAgICAgICAvLyBUT0RPOiB0aGlzIGhpZGVzIGFsbG9jYXRpb24gZmFpbHVyZXMgZnJvbSB1cy4gUHVzaCBkaXJlY3RvcnkgaXRlcmF0aW9uIHVwIGludG8gSmF2YT8KKyAgICAgICAgICAgIGVudHJpZXMucHVzaF9iYWNrKGZpbGVuYW1lKTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIGpvYmplY3RBcnJheSBGaWxlX2xpc3RJbXBsKEpOSUVudiogZW52LCBqY2xhc3MsIGpzdHJpbmcgamF2YVBhdGgpIHsKKyAgICAvLyBSZWFkIHRoZSBkaXJlY3RvcnkgZW50cmllcyBpbnRvIGFuIGludGVybWVkaWF0ZSBmb3JtLgorICAgIERpckVudHJpZXMgZW50cmllczsKKyAgICBpZiAoIXJlYWREaXJlY3RvcnkoZW52LCBqYXZhUGF0aCwgZW50cmllcykpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIC8vIFRyYW5zbGF0ZSB0aGUgaW50ZXJtZWRpYXRlIGZvcm0gaW50byBhIEphdmEgU3RyaW5nW10uCisgICAgcmV0dXJuIHRvU3RyaW5nQXJyYXkoZW52LCBlbnRyaWVzKTsKK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBnTWV0aG9kc1tdID0geworICAgIE5BVElWRV9NRVRIT0QoRmlsZSwgbGlzdEltcGwsICIoTGphdmEvbGFuZy9TdHJpbmc7KVtMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEZpbGUsIHJlYWRsaW5rLCAiKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEZpbGUsIHJlYWxwYXRoLCAiKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEZpbGUsIHNldExhc3RNb2RpZmllZEltcGwsICIoTGphdmEvbGFuZy9TdHJpbmc7SilaIiksCit9OworaW50IHJlZ2lzdGVyX2phdmFfaW9fRmlsZShKTklFbnYqIGVudikgeworICAgIHJldHVybiBqbmlSZWdpc3Rlck5hdGl2ZU1ldGhvZHMoZW52LCAiamF2YS9pby9GaWxlIiwgZ01ldGhvZHMsIE5FTEVNKGdNZXRob2RzKSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX2lvX09iamVjdFN0cmVhbUNsYXNzLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfaW9fT2JqZWN0U3RyZWFtQ2xhc3MuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcyMTEzNmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX2lvX09iamVjdFN0cmVhbUNsYXNzLmNwcApAQCAtMCwwICsxLDY4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIk9iamVjdFN0cmVhbUNsYXNzIgorCisjaW5jbHVkZSAiSk5JSGVscC5oIgorI2luY2x1ZGUgIkpuaUNvbnN0YW50cy5oIgorCitzdGF0aWMgam9iamVjdCBnZXRTaWduYXR1cmUoSk5JRW52KiBlbnYsIGpjbGFzcyBjLCBqb2JqZWN0IG9iamVjdCkgeworICAgIGptZXRob2RJRCBtaWQgPSBlbnYtPkdldE1ldGhvZElEKGMsICJnZXRTaWduYXR1cmUiLCAiKClMamF2YS9sYW5nL1N0cmluZzsiKTsKKyAgICBpZiAoIW1pZCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgamNsYXNzIG9iamVjdENsYXNzID0gZW52LT5HZXRPYmplY3RDbGFzcyhvYmplY3QpOworICAgIHJldHVybiBlbnYtPkNhbGxOb252aXJ0dWFsT2JqZWN0TWV0aG9kKG9iamVjdCwgb2JqZWN0Q2xhc3MsIG1pZCk7Cit9CisKK3N0YXRpYyBqb2JqZWN0IE9iamVjdFN0cmVhbUNsYXNzX2dldEZpZWxkU2lnbmF0dXJlKEpOSUVudiogZW52LCBqY2xhc3MsIGpvYmplY3QgZmllbGQpIHsKKyAgICByZXR1cm4gZ2V0U2lnbmF0dXJlKGVudiwgSm5pQ29uc3RhbnRzOjpmaWVsZENsYXNzLCBmaWVsZCk7Cit9CisKK3N0YXRpYyBqb2JqZWN0IE9iamVjdFN0cmVhbUNsYXNzX2dldE1ldGhvZFNpZ25hdHVyZShKTklFbnYqIGVudiwgamNsYXNzLCBqb2JqZWN0IG1ldGhvZCkgeworICAgIHJldHVybiBnZXRTaWduYXR1cmUoZW52LCBKbmlDb25zdGFudHM6Om1ldGhvZENsYXNzLCBtZXRob2QpOworfQorCitzdGF0aWMgam9iamVjdCBPYmplY3RTdHJlYW1DbGFzc19nZXRDb25zdHJ1Y3RvclNpZ25hdHVyZShKTklFbnYqIGVudiwgamNsYXNzLCBqb2JqZWN0IGNvbnN0cnVjdG9yKSB7CisgICAgcmV0dXJuIGdldFNpZ25hdHVyZShlbnYsIEpuaUNvbnN0YW50czo6Y29uc3RydWN0b3JDbGFzcywgY29uc3RydWN0b3IpOworfQorCitzdGF0aWMgamJvb2xlYW4gT2JqZWN0U3RyZWFtQ2xhc3NfaGFzQ2xpbml0KEpOSUVudiAqIGVudiwgamNsYXNzLCBqY2xhc3MgdGFyZ2V0Q2xhc3MpIHsKKyAgICBqbWV0aG9kSUQgbWlkID0gZW52LT5HZXRTdGF0aWNNZXRob2RJRCh0YXJnZXRDbGFzcywgIjxjbGluaXQ+IiwgIigpViIpOworICAgIGVudi0+RXhjZXB0aW9uQ2xlYXIoKTsKKyAgICByZXR1cm4gKG1pZCAhPSAwKTsKK30KKworc3RhdGljIGppbnQgT2JqZWN0U3RyZWFtQ2xhc3NfZ2V0Q29uc3RydWN0b3JJZChKTklFbnYqIGVudiwgamNsYXNzLCBqY2xhc3MgY29uc3RydWN0b3JDbGFzcykgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PGppbnQ+KGVudi0+R2V0TWV0aG9kSUQoY29uc3RydWN0b3JDbGFzcywgIjxpbml0PiIsICIoKVYiKSk7Cit9CisKK3N0YXRpYyBqb2JqZWN0IE9iamVjdFN0cmVhbUNsYXNzX25ld0luc3RhbmNlKEpOSUVudiogZW52LCBqY2xhc3MsIGpjbGFzcyBpbnN0YW50aWF0aW9uQ2xhc3MsIGppbnQgbWV0aG9kSWQpIHsKKyAgICByZXR1cm4gZW52LT5OZXdPYmplY3QoaW5zdGFudGlhdGlvbkNsYXNzLCByZWludGVycHJldF9jYXN0PGptZXRob2RJRD4obWV0aG9kSWQpKTsKK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBnTWV0aG9kc1tdID0geworICAgIE5BVElWRV9NRVRIT0QoT2JqZWN0U3RyZWFtQ2xhc3MsIGdldENvbnN0cnVjdG9ySWQsICIoTGphdmEvbGFuZy9DbGFzczspSSIpLAorICAgIE5BVElWRV9NRVRIT0QoT2JqZWN0U3RyZWFtQ2xhc3MsIGdldENvbnN0cnVjdG9yU2lnbmF0dXJlLCAiKExqYXZhL2xhbmcvcmVmbGVjdC9Db25zdHJ1Y3RvcjspTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChPYmplY3RTdHJlYW1DbGFzcywgZ2V0RmllbGRTaWduYXR1cmUsICIoTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOylMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE9iamVjdFN0cmVhbUNsYXNzLCBnZXRNZXRob2RTaWduYXR1cmUsICIoTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDspTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChPYmplY3RTdHJlYW1DbGFzcywgaGFzQ2xpbml0LCAiKExqYXZhL2xhbmcvQ2xhc3M7KVoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE9iamVjdFN0cmVhbUNsYXNzLCBuZXdJbnN0YW5jZSwgIihMamF2YS9sYW5nL0NsYXNzO0kpTGphdmEvbGFuZy9PYmplY3Q7IiksCit9OworaW50IHJlZ2lzdGVyX2phdmFfaW9fT2JqZWN0U3RyZWFtQ2xhc3MoSk5JRW52KiBlbnYpIHsKKyAgICByZXR1cm4gam5pUmVnaXN0ZXJOYXRpdmVNZXRob2RzKGVudiwgImphdmEvaW8vT2JqZWN0U3RyZWFtQ2xhc3MiLCBnTWV0aG9kcywgTkVMRU0oZ01ldGhvZHMpKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfbGFuZ19DaGFyYWN0ZXIuY3BwIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV9sYW5nX0NoYXJhY3Rlci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmVjMDI5ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfbGFuZ19DaGFyYWN0ZXIuY3BwCkBAIC0wLDAgKzEsMTY1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA2IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJDaGFyYWN0ZXIiCisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisjaW5jbHVkZSAiU2NvcGVkVXRmQ2hhcnMuaCIKKyNpbmNsdWRlICJ1bmljb2RlL3VjaGFyLmgiCisjaW5jbHVkZSA8bWF0aC5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorCitzdGF0aWMgamludCBDaGFyYWN0ZXJfZGlnaXRJbXBsKEpOSUVudiosIGpjbGFzcywgamludCBjb2RlUG9pbnQsIGppbnQgcmFkaXgpIHsKKyAgICByZXR1cm4gdV9kaWdpdChjb2RlUG9pbnQsIHJhZGl4KTsKK30KKworc3RhdGljIGppbnQgQ2hhcmFjdGVyX2dldFR5cGVJbXBsKEpOSUVudiosIGpjbGFzcywgamludCBjb2RlUG9pbnQpIHsKKyAgICByZXR1cm4gdV9jaGFyVHlwZShjb2RlUG9pbnQpOworfQorCitzdGF0aWMgamJ5dGUgQ2hhcmFjdGVyX2dldERpcmVjdGlvbmFsaXR5SW1wbChKTklFbnYqLCBqY2xhc3MsIGppbnQgY29kZVBvaW50KSB7CisgICAgcmV0dXJuIHVfY2hhckRpcmVjdGlvbihjb2RlUG9pbnQpOworfQorCitzdGF0aWMgamJvb2xlYW4gQ2hhcmFjdGVyX2lzTWlycm9yZWRJbXBsKEpOSUVudiosIGpjbGFzcywgamludCBjb2RlUG9pbnQpIHsKKyAgICByZXR1cm4gdV9pc01pcnJvcmVkKGNvZGVQb2ludCk7Cit9CisKK3N0YXRpYyBqc3RyaW5nIENoYXJhY3Rlcl9nZXROYW1lSW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGNvZGVQb2ludCkgeworICAgIC8vIFVfVU5JQ09ERV9DSEFSX05BTUUgZ2l2ZXMgdXMgdGhlIG1vZGVybiBuYW1lcyBmb3IgY2hhcmFjdGVycy4gRm9yIGNvbnRyb2wgY2hhcmFjdGVycywKKyAgICAvLyB3ZSBuZWVkIFVfRVhURU5ERURfQ0hBUl9OQU1FIHRvIGdldCAiTlVMTCIgcmF0aGVyIHRoYW4gIkJBU0lDIExBVElOIDAiIGFuZCBzbyBvbi4KKyAgICAvLyBXZSBjb3VsZCBqdXN0IHVzZSBVX0VYVEVOREVEX0NIQVJfTkFNRSBleGNlcHQgdGhhdCBpdCByZXR1cm5zIHN0cmluZ3MgZm9yIGNoYXJhY3RlcnMKKyAgICAvLyB0aGF0IGFyZW4ndCB1bmFzc2lnbmVkIGJ1dCB0aGF0IGRvbid0IGhhdmUgbmFtZXMsIGFuZCB0aG9zZSBzdHJpbmdzIGFyZW4ndCBpbiB0aGUgZm9ybQorICAgIC8vIEphdmEgc3BlY2lmaWVzLgorICAgIGJvb2wgaXNDb250cm9sID0gKGNvZGVQb2ludCA8PSAweDFmIHx8IChjb2RlUG9pbnQgPj0gMHg3ZiAmJiBjb2RlUG9pbnQgPD0gMHg5ZikpOworICAgIFVDaGFyTmFtZUNob2ljZSBuYW1lVHlwZSA9IGlzQ29udHJvbCA/IFVfRVhURU5ERURfQ0hBUl9OQU1FIDogVV9VTklDT0RFX0NIQVJfTkFNRTsKKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBjaGFyIGJ1ZltCVUZTSVpdOyAvLyBUT0RPOiBpcyB0aGVyZSBhIG1vcmUgc2Vuc2libGUgdXBwZXIgYm91bmQ/CisgICAgaW50MzJfdCBieXRlQ291bnQgPSB1X2NoYXJOYW1lKGNvZGVQb2ludCwgbmFtZVR5cGUsICZidWZbMF0sIHNpemVvZihidWYpLCAmc3RhdHVzKTsKKyAgICByZXR1cm4gKFVfRkFJTFVSRShzdGF0dXMpIHx8IGJ5dGVDb3VudCA9PSAwKSA/IE5VTEwgOiBlbnYtPk5ld1N0cmluZ1VURihidWYpOworfQorCitzdGF0aWMgamludCBDaGFyYWN0ZXJfZ2V0TnVtZXJpY1ZhbHVlSW1wbChKTklFbnYqLCBqY2xhc3MsIGppbnQgY29kZVBvaW50KSB7CisgICAgZG91YmxlIHJlc3VsdCA9IHVfZ2V0TnVtZXJpY1ZhbHVlKGNvZGVQb2ludCk7CisgICAgaWYgKHJlc3VsdCA9PSBVX05PX05VTUVSSUNfVkFMVUUpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0gZWxzZSBpZiAocmVzdWx0IDwgMCB8fCBmbG9vcihyZXN1bHQgKyAwLjUpICE9IHJlc3VsdCkgeworICAgICAgICByZXR1cm4gLTI7CisgICAgfQorICAgIHJldHVybiBzdGF0aWNfY2FzdDxqaW50PihyZXN1bHQpOworfQorCitzdGF0aWMgamJvb2xlYW4gQ2hhcmFjdGVyX2lzRGVmaW5lZEltcGwoSk5JRW52KiwgamNsYXNzLCBqaW50IGNvZGVQb2ludCkgeworICAgIHJldHVybiB1X2lzZGVmaW5lZChjb2RlUG9pbnQpOworfQorCitzdGF0aWMgamJvb2xlYW4gQ2hhcmFjdGVyX2lzRGlnaXRJbXBsKEpOSUVudiosIGpjbGFzcywgamludCBjb2RlUG9pbnQpIHsKKyAgICByZXR1cm4gdV9pc2RpZ2l0KGNvZGVQb2ludCk7Cit9CisKK3N0YXRpYyBqYm9vbGVhbiBDaGFyYWN0ZXJfaXNJZGVudGlmaWVySWdub3JhYmxlSW1wbChKTklFbnYqLCBqY2xhc3MsIGppbnQgY29kZVBvaW50KSB7CisgICAgcmV0dXJuIHVfaXNJRElnbm9yYWJsZShjb2RlUG9pbnQpOworfQorCitzdGF0aWMgamJvb2xlYW4gQ2hhcmFjdGVyX2lzTGV0dGVySW1wbChKTklFbnYqLCBqY2xhc3MsIGppbnQgY29kZVBvaW50KSB7CisgICAgcmV0dXJuIHVfaXNhbHBoYShjb2RlUG9pbnQpOworfQorCitzdGF0aWMgamJvb2xlYW4gQ2hhcmFjdGVyX2lzTGV0dGVyT3JEaWdpdEltcGwoSk5JRW52KiwgamNsYXNzLCBqaW50IGNvZGVQb2ludCkgeworICAgIHJldHVybiB1X2lzYWxudW0oY29kZVBvaW50KTsKK30KKworc3RhdGljIGpib29sZWFuIENoYXJhY3Rlcl9pc1NwYWNlQ2hhckltcGwoSk5JRW52KiwgamNsYXNzLCBqaW50IGNvZGVQb2ludCkgeworICAgIHJldHVybiB1X2lzSmF2YVNwYWNlQ2hhcihjb2RlUG9pbnQpOworfQorCitzdGF0aWMgamJvb2xlYW4gQ2hhcmFjdGVyX2lzVGl0bGVDYXNlSW1wbChKTklFbnYqLCBqY2xhc3MsIGppbnQgY29kZVBvaW50KSB7CisgICAgcmV0dXJuIHVfaXN0aXRsZShjb2RlUG9pbnQpOworfQorCitzdGF0aWMgamJvb2xlYW4gQ2hhcmFjdGVyX2lzVW5pY29kZUlkZW50aWZpZXJQYXJ0SW1wbChKTklFbnYqLCBqY2xhc3MsIGppbnQgY29kZVBvaW50KSB7CisgICAgcmV0dXJuIHVfaXNJRFBhcnQoY29kZVBvaW50KTsKK30KKworc3RhdGljIGpib29sZWFuIENoYXJhY3Rlcl9pc1VuaWNvZGVJZGVudGlmaWVyU3RhcnRJbXBsKEpOSUVudiosIGpjbGFzcywgamludCBjb2RlUG9pbnQpIHsKKyAgICByZXR1cm4gdV9pc0lEU3RhcnQoY29kZVBvaW50KTsKK30KKworc3RhdGljIGpib29sZWFuIENoYXJhY3Rlcl9pc1doaXRlc3BhY2VJbXBsKEpOSUVudiosIGpjbGFzcywgamludCBjb2RlUG9pbnQpIHsKKyAgICByZXR1cm4gdV9pc1doaXRlc3BhY2UoY29kZVBvaW50KTsKK30KKworc3RhdGljIGppbnQgQ2hhcmFjdGVyX3RvTG93ZXJDYXNlSW1wbChKTklFbnYqLCBqY2xhc3MsIGppbnQgY29kZVBvaW50KSB7CisgICAgcmV0dXJuIHVfdG9sb3dlcihjb2RlUG9pbnQpOworfQorCitzdGF0aWMgamludCBDaGFyYWN0ZXJfdG9UaXRsZUNhc2VJbXBsKEpOSUVudiosIGpjbGFzcywgamludCBjb2RlUG9pbnQpIHsKKyAgICByZXR1cm4gdV90b3RpdGxlKGNvZGVQb2ludCk7Cit9CisKK3N0YXRpYyBqaW50IENoYXJhY3Rlcl90b1VwcGVyQ2FzZUltcGwoSk5JRW52KiwgamNsYXNzLCBqaW50IGNvZGVQb2ludCkgeworICAgIHJldHVybiB1X3RvdXBwZXIoY29kZVBvaW50KTsKK30KKworc3RhdGljIGpib29sZWFuIENoYXJhY3Rlcl9pc1VwcGVyQ2FzZUltcGwoSk5JRW52KiwgamNsYXNzLCBqaW50IGNvZGVQb2ludCkgeworICAgIHJldHVybiB1X2lzdXBwZXIoY29kZVBvaW50KTsKK30KKworc3RhdGljIGpib29sZWFuIENoYXJhY3Rlcl9pc0xvd2VyQ2FzZUltcGwoSk5JRW52KiwgamNsYXNzLCBqaW50IGNvZGVQb2ludCkgeworICAgIHJldHVybiB1X2lzbG93ZXIoY29kZVBvaW50KTsKK30KKworc3RhdGljIGludCBDaGFyYWN0ZXJfZm9yTmFtZUltcGwoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBqYXZhQmxvY2tOYW1lKSB7CisgICAgU2NvcGVkVXRmQ2hhcnMgYmxvY2tOYW1lKGVudiwgamF2YUJsb2NrTmFtZSk7CisgICAgaWYgKGJsb2NrTmFtZS5jX3N0cigpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIHJldHVybiB1X2dldFByb3BlcnR5VmFsdWVFbnVtKFVDSEFSX0JMT0NLLCBibG9ja05hbWUuY19zdHIoKSk7Cit9CisKK3N0YXRpYyBpbnQgQ2hhcmFjdGVyX29mSW1wbChKTklFbnYqLCBqY2xhc3MsIGppbnQgY29kZVBvaW50KSB7CisgICAgcmV0dXJuIHVibG9ja19nZXRDb2RlKGNvZGVQb2ludCk7Cit9CisKK3N0YXRpYyBKTklOYXRpdmVNZXRob2QgZ01ldGhvZHNbXSA9IHsKKyAgICBOQVRJVkVfTUVUSE9EKENoYXJhY3RlciwgZGlnaXRJbXBsLCAiIShJSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChDaGFyYWN0ZXIsIGZvck5hbWVJbXBsLCAiKExqYXZhL2xhbmcvU3RyaW5nOylJIiksCisgICAgTkFUSVZFX01FVEhPRChDaGFyYWN0ZXIsIGdldERpcmVjdGlvbmFsaXR5SW1wbCwgIiEoSSlCIiksCisgICAgTkFUSVZFX01FVEhPRChDaGFyYWN0ZXIsIGdldE5hbWVJbXBsLCAiKEkpTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChDaGFyYWN0ZXIsIGdldE51bWVyaWNWYWx1ZUltcGwsICIhKEkpSSIpLAorICAgIE5BVElWRV9NRVRIT0QoQ2hhcmFjdGVyLCBnZXRUeXBlSW1wbCwgIiEoSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChDaGFyYWN0ZXIsIGlzRGVmaW5lZEltcGwsICIhKEkpWiIpLAorICAgIE5BVElWRV9NRVRIT0QoQ2hhcmFjdGVyLCBpc0RpZ2l0SW1wbCwgIiEoSSlaIiksCisgICAgTkFUSVZFX01FVEhPRChDaGFyYWN0ZXIsIGlzSWRlbnRpZmllcklnbm9yYWJsZUltcGwsICIhKEkpWiIpLAorICAgIE5BVElWRV9NRVRIT0QoQ2hhcmFjdGVyLCBpc0xldHRlckltcGwsICIhKEkpWiIpLAorICAgIE5BVElWRV9NRVRIT0QoQ2hhcmFjdGVyLCBpc0xldHRlck9yRGlnaXRJbXBsLCAiIShJKVoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKENoYXJhY3RlciwgaXNMb3dlckNhc2VJbXBsLCAiIShJKVoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKENoYXJhY3RlciwgaXNNaXJyb3JlZEltcGwsICIhKEkpWiIpLAorICAgIE5BVElWRV9NRVRIT0QoQ2hhcmFjdGVyLCBpc1NwYWNlQ2hhckltcGwsICIhKEkpWiIpLAorICAgIE5BVElWRV9NRVRIT0QoQ2hhcmFjdGVyLCBpc1RpdGxlQ2FzZUltcGwsICIhKEkpWiIpLAorICAgIE5BVElWRV9NRVRIT0QoQ2hhcmFjdGVyLCBpc1VuaWNvZGVJZGVudGlmaWVyUGFydEltcGwsICIhKEkpWiIpLAorICAgIE5BVElWRV9NRVRIT0QoQ2hhcmFjdGVyLCBpc1VuaWNvZGVJZGVudGlmaWVyU3RhcnRJbXBsLCAiIShJKVoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKENoYXJhY3RlciwgaXNVcHBlckNhc2VJbXBsLCAiIShJKVoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKENoYXJhY3RlciwgaXNXaGl0ZXNwYWNlSW1wbCwgIiEoSSlaIiksCisgICAgTkFUSVZFX01FVEhPRChDaGFyYWN0ZXIsIG9mSW1wbCwgIiEoSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChDaGFyYWN0ZXIsIHRvTG93ZXJDYXNlSW1wbCwgIiEoSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChDaGFyYWN0ZXIsIHRvVGl0bGVDYXNlSW1wbCwgIiEoSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChDaGFyYWN0ZXIsIHRvVXBwZXJDYXNlSW1wbCwgIiEoSSlJIiksCit9OworaW50IHJlZ2lzdGVyX2phdmFfbGFuZ19DaGFyYWN0ZXIoSk5JRW52KiBlbnYpIHsKKyAgICByZXR1cm4gam5pUmVnaXN0ZXJOYXRpdmVNZXRob2RzKGVudiwgImphdmEvbGFuZy9DaGFyYWN0ZXIiLCBnTWV0aG9kcywgTkVMRU0oZ01ldGhvZHMpKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfbGFuZ19NYXRoLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfbGFuZ19NYXRoLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YTQxYWYyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV9sYW5nX01hdGguY3BwCkBAIC0wLDAgKzEsMTM2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA2IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJNYXRoIgorCisjaW5jbHVkZSAiam5pLmgiCisjaW5jbHVkZSAiSk5JSGVscC5oIgorI2luY2x1ZGUgIkpuaUNvbnN0YW50cy5oIgorCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8bWF0aC5oPgorCitzdGF0aWMgamRvdWJsZSBNYXRoX3RhbihKTklFbnYqLCBqY2xhc3MsIGpkb3VibGUgYSkgeworICAgIHJldHVybiB0YW4oYSk7Cit9CisKK3N0YXRpYyBqZG91YmxlIE1hdGhfYXNpbihKTklFbnYqLCBqY2xhc3MsIGpkb3VibGUgYSkgeworICAgIHJldHVybiBhc2luKGEpOworfQorCitzdGF0aWMgamRvdWJsZSBNYXRoX2Fjb3MoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gYWNvcyhhKTsKK30KKworc3RhdGljIGpkb3VibGUgTWF0aF9hdGFuKEpOSUVudiosIGpjbGFzcywgamRvdWJsZSBhKSB7CisgICAgcmV0dXJuIGF0YW4oYSk7Cit9CisKK3N0YXRpYyBqZG91YmxlIE1hdGhfZXhwKEpOSUVudiosIGpjbGFzcywgamRvdWJsZSBhKSB7CisgICAgcmV0dXJuIGV4cChhKTsKK30KKworc3RhdGljIGpkb3VibGUgTWF0aF9sb2coSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gbG9nKGEpOworfQorCitzdGF0aWMgamRvdWJsZSBNYXRoX0lFRUVyZW1haW5kZXIoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEsIGpkb3VibGUgYikgeworICAgIHJldHVybiByZW1haW5kZXIoYSwgYik7Cit9CisKK3N0YXRpYyBqZG91YmxlIE1hdGhfZmxvb3IoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gZmxvb3IoYSk7Cit9CisKK3N0YXRpYyBqZG91YmxlIE1hdGhfY2VpbChKTklFbnYqLCBqY2xhc3MsIGpkb3VibGUgYSkgeworICAgIHJldHVybiBjZWlsKGEpOworfQorCitzdGF0aWMgamRvdWJsZSBNYXRoX3JpbnQoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gcmludChhKTsKK30KKworc3RhdGljIGpkb3VibGUgTWF0aF9hdGFuMihKTklFbnYqLCBqY2xhc3MsIGpkb3VibGUgYSwgamRvdWJsZSBiKSB7CisgICAgcmV0dXJuIGF0YW4yKGEsIGIpOworfQorCitzdGF0aWMgamRvdWJsZSBNYXRoX3BvdyhKTklFbnYqLCBqY2xhc3MsIGpkb3VibGUgYSwgamRvdWJsZSBiKSB7CisgICAgcmV0dXJuIHBvdyhhLCBiKTsKK30KKworc3RhdGljIGpkb3VibGUgTWF0aF9zaW5oKEpOSUVudiosIGpjbGFzcywgamRvdWJsZSBhKSB7CisgICAgcmV0dXJuIHNpbmgoYSk7Cit9CisKK3N0YXRpYyBqZG91YmxlIE1hdGhfdGFuaChKTklFbnYqLCBqY2xhc3MsIGpkb3VibGUgYSkgeworICAgIHJldHVybiB0YW5oKGEpOworfQorCitzdGF0aWMgamRvdWJsZSBNYXRoX2Nvc2goSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gY29zaChhKTsKK30KKworc3RhdGljIGpkb3VibGUgTWF0aF9sb2cxMChKTklFbnYqLCBqY2xhc3MsIGpkb3VibGUgYSkgeworICAgIHJldHVybiBsb2cxMChhKTsKK30KKworc3RhdGljIGpkb3VibGUgTWF0aF9jYnJ0KEpOSUVudiosIGpjbGFzcywgamRvdWJsZSBhKSB7CisgICAgcmV0dXJuIGNicnQoYSk7Cit9CisKK3N0YXRpYyBqZG91YmxlIE1hdGhfZXhwbTEoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gZXhwbTEoYSk7Cit9CisKK3N0YXRpYyBqZG91YmxlIE1hdGhfaHlwb3QoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEsIGpkb3VibGUgYikgeworICAgIHJldHVybiBoeXBvdChhLCBiKTsKK30KKworc3RhdGljIGpkb3VibGUgTWF0aF9sb2cxcChKTklFbnYqLCBqY2xhc3MsIGpkb3VibGUgYSkgeworICAgIHJldHVybiBsb2cxcChhKTsKK30KKworc3RhdGljIGpkb3VibGUgTWF0aF9uZXh0YWZ0ZXIoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEsIGpkb3VibGUgYikgeworICAgIHJldHVybiBuZXh0YWZ0ZXIoYSwgYik7Cit9CisKK3N0YXRpYyBKTklOYXRpdmVNZXRob2QgZ01ldGhvZHNbXSA9IHsKKyAgICBOQVRJVkVfTUVUSE9EKE1hdGgsIElFRUVyZW1haW5kZXIsICIhKEREKUQiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1hdGgsIGFjb3MsICIhKEQpRCIpLAorICAgIE5BVElWRV9NRVRIT0QoTWF0aCwgYXNpbiwgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChNYXRoLCBhdGFuLCAiIShEKUQiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1hdGgsIGF0YW4yLCAiIShERClEIiksCisgICAgTkFUSVZFX01FVEhPRChNYXRoLCBjYnJ0LCAiIShEKUQiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1hdGgsIGNlaWwsICIhKEQpRCIpLAorICAgIE5BVElWRV9NRVRIT0QoTWF0aCwgY29zaCwgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChNYXRoLCBleHAsICIhKEQpRCIpLAorICAgIE5BVElWRV9NRVRIT0QoTWF0aCwgZXhwbTEsICIhKEQpRCIpLAorICAgIE5BVElWRV9NRVRIT0QoTWF0aCwgZmxvb3IsICIhKEQpRCIpLAorICAgIE5BVElWRV9NRVRIT0QoTWF0aCwgaHlwb3QsICIhKEREKUQiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1hdGgsIGxvZywgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChNYXRoLCBsb2cxMCwgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChNYXRoLCBsb2cxcCwgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChNYXRoLCBuZXh0YWZ0ZXIsICIhKEREKUQiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1hdGgsIHBvdywgIiEoREQpRCIpLAorICAgIE5BVElWRV9NRVRIT0QoTWF0aCwgcmludCwgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChNYXRoLCBzaW5oLCAiIShEKUQiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1hdGgsIHRhbiwgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChNYXRoLCB0YW5oLCAiIShEKUQiKSwKK307CisKK2ludCByZWdpc3Rlcl9qYXZhX2xhbmdfTWF0aChKTklFbnYqIGVudikgeworICAgIHJldHVybiBqbmlSZWdpc3Rlck5hdGl2ZU1ldGhvZHMoZW52LCAiamF2YS9sYW5nL01hdGgiLCBnTWV0aG9kcywgTkVMRU0oZ01ldGhvZHMpKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfbGFuZ19Qcm9jZXNzTWFuYWdlci5jcHAgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX2xhbmdfUHJvY2Vzc01hbmFnZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVkNTlmMjcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX2xhbmdfUHJvY2Vzc01hbmFnZXIuY3BwCkBAIC0wLDAgKzEsMjcwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJQcm9jZXNzTWFuYWdlciIKKworI2luY2x1ZGUgPHN5cy9yZXNvdXJjZS5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKworI2luY2x1ZGUgImpuaS5oIgorI2luY2x1ZGUgIkpOSUhlbHAuaCIKKyNpbmNsdWRlICJKbmlDb25zdGFudHMuaCIKKyNpbmNsdWRlICJTY29wZWRMb2NhbFJlZi5oIgorI2luY2x1ZGUgImN1dGlscy9sb2cuaCIKKworLyoqIENsb3NlIGFsbCBvcGVuIGZkcyA+IDIgKGkuZS4gZXZlcnl0aGluZyBidXQgc3RkaW4vb3V0L2VyciksICE9IHNraXBGZC4gKi8KK3N0YXRpYyB2b2lkIGNsb3NlTm9uU3RhbmRhcmRGZHMoaW50IHNraXBGZDEsIGludCBza2lwRmQyKSB7CisgICAgLy8gVE9ETzogcmF0aGVyIHRoYW4gY2xvc2UgYWxsIHRoZXNlIG5vbi1vcGVuIGZpbGVzLCB3ZSBjb3VsZCBsb29rIGluIC9wcm9jL3NlbGYvZmQuCisgICAgcmxpbWl0IHJsaW1pdDsKKyAgICBnZXRybGltaXQoUkxJTUlUX05PRklMRSwgJnJsaW1pdCk7CisgICAgY29uc3QgaW50IG1heF9mZCA9IHJsaW1pdC5ybGltX21heDsKKyAgICBmb3IgKGludCBmZCA9IDM7IGZkIDwgbWF4X2ZkOyArK2ZkKSB7CisgICAgICAgIGlmIChmZCAhPSBza2lwRmQxICYmIGZkICE9IHNraXBGZDIpIHsKKyAgICAgICAgICAgIGNsb3NlKGZkKTsKKyAgICAgICAgfQorICAgIH0KK30KKworI2RlZmluZSBQSVBFX0NPVU5UICg0KSAvLyBudW1iZXIgb2YgcGlwZXMgdXNlZCB0byBjb21tdW5pY2F0ZSB3aXRoIGNoaWxkIHByb2MKKworLyoqIENsb3NlcyBhbGwgcGlwZXMgaW4gdGhlIGdpdmVuIGFycmF5LiAqLworc3RhdGljIHZvaWQgY2xvc2VQaXBlcyhpbnQgcGlwZXNbXSwgaW50IHNraXBGZCkgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUElQRV9DT1VOVCAqIDI7IGkrKykgeworICAgICAgICBpbnQgZmQgPSBwaXBlc1tpXTsKKyAgICAgICAgaWYgKGZkID09IC0xKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZkICE9IHNraXBGZCkgeworICAgICAgICAgICAgY2xvc2UocGlwZXNbaV0pOworICAgICAgICB9CisgICAgfQorfQorCisvKiogRXhlY3V0ZXMgYSBjb21tYW5kIGluIGEgY2hpbGQgcHJvY2Vzcy4gKi8KK3N0YXRpYyBwaWRfdCBleGVjdXRlUHJvY2VzcyhKTklFbnYqIGVudiwgY2hhcioqIGNvbW1hbmRzLCBjaGFyKiogZW52aXJvbm1lbnQsCisgICAgICAgIGNvbnN0IGNoYXIqIHdvcmtpbmdEaXJlY3RvcnksIGpvYmplY3QgaW5EZXNjcmlwdG9yLAorICAgICAgICBqb2JqZWN0IG91dERlc2NyaXB0b3IsIGpvYmplY3QgZXJyRGVzY3JpcHRvciwKKyAgICAgICAgamJvb2xlYW4gcmVkaXJlY3RFcnJvclN0cmVhbSkgeworCisgICAgLy8gS2VlcCB0cmFjayBvZiB0aGUgc3lzdGVtIHByb3BlcnRpZXMgZmQgc28gd2UgZG9uJ3QgY2xvc2UgaXQuCisgICAgaW50IGFuZHJvaWRTeXN0ZW1Qcm9wZXJ0aWVzRmQgPSAtMTsKKyAgICBjaGFyKiBmZFN0cmluZyA9IGdldGVudigiQU5EUk9JRF9QUk9QRVJUWV9XT1JLU1BBQ0UiKTsKKyAgICBpZiAoZmRTdHJpbmcpIHsKKyAgICAgICAgYW5kcm9pZFN5c3RlbVByb3BlcnRpZXNGZCA9IGF0b2koZmRTdHJpbmcpOworICAgIH0KKworICAgIC8vIENyZWF0ZSA0IHBpcGVzOiBzdGRpbiwgc3Rkb3V0LCBzdGRlcnIsIGFuZCBhbiBleGVjKCkgc3RhdHVzIHBpcGUuCisgICAgaW50IHBpcGVzW1BJUEVfQ09VTlQgKiAyXSA9IHsgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xIH07CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBQSVBFX0NPVU5UOyBpKyspIHsKKyAgICAgICAgaWYgKHBpcGUocGlwZXMgKyBpICogMikgPT0gLTEpIHsKKyAgICAgICAgICAgIGpuaVRocm93SU9FeGNlcHRpb24oZW52LCBlcnJubyk7CisgICAgICAgICAgICBjbG9zZVBpcGVzKHBpcGVzLCAtMSk7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICB9CisgICAgaW50IHN0ZGluSW4gPSBwaXBlc1swXTsKKyAgICBpbnQgc3RkaW5PdXQgPSBwaXBlc1sxXTsKKyAgICBpbnQgc3Rkb3V0SW4gPSBwaXBlc1syXTsKKyAgICBpbnQgc3Rkb3V0T3V0ID0gcGlwZXNbM107CisgICAgaW50IHN0ZGVyckluID0gcGlwZXNbNF07CisgICAgaW50IHN0ZGVyck91dCA9IHBpcGVzWzVdOworICAgIGludCBzdGF0dXNJbiA9IHBpcGVzWzZdOworICAgIGludCBzdGF0dXNPdXQgPSBwaXBlc1s3XTsKKworICAgIHBpZF90IGNoaWxkUGlkID0gZm9yaygpOworCisgICAgLy8gSWYgZm9yaygpIGZhaWxlZC4uLgorICAgIGlmIChjaGlsZFBpZCA9PSAtMSkgeworICAgICAgICBqbmlUaHJvd0lPRXhjZXB0aW9uKGVudiwgZXJybm8pOworICAgICAgICBjbG9zZVBpcGVzKHBpcGVzLCAtMSk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvLyBJZiB0aGlzIGlzIHRoZSBjaGlsZCBwcm9jZXNzLi4uCisgICAgaWYgKGNoaWxkUGlkID09IDApIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogTm90ZTogV2UgY2Fubm90IG1hbGxvYygpIG9yIGZyZWUoKSBhZnRlciB0aGlzIHBvaW50IQorICAgICAgICAgKiBBIG5vLWxvbmdlci1ydW5uaW5nIHRocmVhZCBtYXkgYmUgaG9sZGluZyBvbiB0byB0aGUgaGVhcCBsb2NrLCBhbmQKKyAgICAgICAgICogYW4gYXR0ZW1wdCB0byBtYWxsb2MoKSBvciBmcmVlKCkgd291bGQgcmVzdWx0IGluIGRlYWRsb2NrLgorICAgICAgICAgKi8KKworICAgICAgICAvLyBSZXBsYWNlIHN0ZGluLCBvdXQsIGFuZCBlcnIgd2l0aCBwaXBlcy4KKyAgICAgICAgZHVwMihzdGRpbkluLCAwKTsKKyAgICAgICAgZHVwMihzdGRvdXRPdXQsIDEpOworICAgICAgICBpZiAocmVkaXJlY3RFcnJvclN0cmVhbSkgeworICAgICAgICAgICAgZHVwMihzdGRvdXRPdXQsIDIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZHVwMihzdGRlcnJPdXQsIDIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ2xvc2UgYWxsIGJ1dCBzdGF0dXNPdXQuIFRoaXMgc2F2ZXMgc29tZSB3b3JrIGluIHRoZSBuZXh0IHN0ZXAuCisgICAgICAgIGNsb3NlUGlwZXMocGlwZXMsIHN0YXR1c091dCk7CisKKyAgICAgICAgLy8gTWFrZSBzdGF0dXNPdXQgYXV0b21hdGljYWxseSBjbG9zZSBpZiBleGVjdnAoKSBzdWNjZWVkcy4KKyAgICAgICAgZmNudGwoc3RhdHVzT3V0LCBGX1NFVEZELCBGRF9DTE9FWEVDKTsKKworICAgICAgICAvLyBDbG9zZSByZW1haW5pbmcgdW53YW50ZWQgb3BlbiBmZHMuCisgICAgICAgIGNsb3NlTm9uU3RhbmRhcmRGZHMoc3RhdHVzT3V0LCBhbmRyb2lkU3lzdGVtUHJvcGVydGllc0ZkKTsKKworICAgICAgICAvLyBTd2l0Y2ggdG8gd29ya2luZyBkaXJlY3RvcnkuCisgICAgICAgIGlmICh3b3JraW5nRGlyZWN0b3J5ICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGlmIChjaGRpcih3b3JraW5nRGlyZWN0b3J5KSA9PSAtMSkgeworICAgICAgICAgICAgICAgIGdvdG8gZXhlY0ZhaWxlZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFNldCB1cCBlbnZpcm9ubWVudC4KKyAgICAgICAgaWYgKGVudmlyb25tZW50ICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGV4dGVybiBjaGFyKiogZW52aXJvbjsgLy8gU3RhbmRhcmQsIGJ1dCBub3QgaW4gYW55IGhlYWRlciBmaWxlLgorICAgICAgICAgICAgZW52aXJvbiA9IGVudmlyb25tZW50OworICAgICAgICB9CisKKyAgICAgICAgLy8gRXhlY3V0ZSBwcm9jZXNzLiBCeSBjb252ZW50aW9uLCB0aGUgZmlyc3QgYXJndW1lbnQgaW4gdGhlIGFyZyBhcnJheQorICAgICAgICAvLyBzaG91bGQgYmUgdGhlIGNvbW1hbmQgaXRzZWxmLiBJbiBmYWN0LCBJIGdldCBzZWdmYXVsdHMgd2hlbiB0aGlzCisgICAgICAgIC8vIGlzbid0IHRoZSBjYXNlLgorICAgICAgICBleGVjdnAoY29tbWFuZHNbMF0sIGNvbW1hbmRzKTsKKworICAgICAgICAvLyBJZiB3ZSBnb3QgaGVyZSwgZXhlY3ZwKCkgZmFpbGVkIG9yIHRoZSB3b3JraW5nIGRpciB3YXMgaW52YWxpZC4KKyAgICAgICAgZXhlY0ZhaWxlZDoKKyAgICAgICAgICAgIGludCBlcnJvciA9IGVycm5vOworICAgICAgICAgICAgd3JpdGUoc3RhdHVzT3V0LCAmZXJyb3IsIHNpemVvZihpbnQpKTsKKyAgICAgICAgICAgIGNsb3NlKHN0YXR1c091dCk7CisgICAgICAgICAgICBleGl0KGVycm9yKTsKKyAgICB9CisKKyAgICAvLyBUaGlzIGlzIHRoZSBwYXJlbnQgcHJvY2Vzcy4KKworICAgIC8vIENsb3NlIGNoaWxkJ3MgcGlwZSBlbmRzLgorICAgIGNsb3NlKHN0ZGluSW4pOworICAgIGNsb3NlKHN0ZG91dE91dCk7CisgICAgY2xvc2Uoc3RkZXJyT3V0KTsKKyAgICBjbG9zZShzdGF0dXNPdXQpOworCisgICAgLy8gQ2hlY2sgc3RhdHVzIHBpcGUgZm9yIGFuIGVycm9yIGNvZGUuIElmIGV4ZWN2cCgpIHN1Y2NlZWRzLCB0aGUgb3RoZXIKKyAgICAvLyBlbmQgb2YgdGhlIHBpcGUgc2hvdWxkIGF1dG9tYXRpY2FsbHkgY2xvc2UsIGluIHdoaWNoIGNhc2UsIHdlJ2xsIHJlYWQKKyAgICAvLyBub3RoaW5nLgorICAgIGludCByZXN1bHQ7CisgICAgaW50IGNvdW50ID0gcmVhZChzdGF0dXNJbiwgJnJlc3VsdCwgc2l6ZW9mKGludCkpOworICAgIGNsb3NlKHN0YXR1c0luKTsKKyAgICBpZiAoY291bnQgPiAwKSB7CisgICAgICAgIGpuaVRocm93SU9FeGNlcHRpb24oZW52LCByZXN1bHQpOworCisgICAgICAgIGNsb3NlKHN0ZG91dEluKTsKKyAgICAgICAgY2xvc2Uoc3RkaW5PdXQpOworICAgICAgICBjbG9zZShzdGRlcnJJbik7CisKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8vIEZpbGwgaW4gZmlsZSBkZXNjcmlwdG9yIHdyYXBwZXJzLgorICAgIGpuaVNldEZpbGVEZXNjcmlwdG9yT2ZGRChlbnYsIGluRGVzY3JpcHRvciwgc3Rkb3V0SW4pOworICAgIGpuaVNldEZpbGVEZXNjcmlwdG9yT2ZGRChlbnYsIG91dERlc2NyaXB0b3IsIHN0ZGluT3V0KTsKKyAgICBqbmlTZXRGaWxlRGVzY3JpcHRvck9mRkQoZW52LCBlcnJEZXNjcmlwdG9yLCBzdGRlcnJJbik7CisKKyAgICByZXR1cm4gY2hpbGRQaWQ7Cit9CisKKy8qKiBDb252ZXJ0cyBhIEphdmEgU3RyaW5nW10gdG8gYSAwLXRlcm1pbmF0ZWQgY2hhcioqLiAqLworc3RhdGljIGNoYXIqKiBjb252ZXJ0U3RyaW5ncyhKTklFbnYqIGVudiwgam9iamVjdEFycmF5IGphdmFBcnJheSkgeworICAgIGlmIChqYXZhQXJyYXkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBqc2l6ZSBsZW5ndGggPSBlbnYtPkdldEFycmF5TGVuZ3RoKGphdmFBcnJheSk7CisgICAgY2hhcioqIGFycmF5ID0gbmV3IGNoYXIqW2xlbmd0aCArIDFdOworICAgIGFycmF5W2xlbmd0aF0gPSAwOworICAgIGZvciAoanNpemUgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgeworICAgICAgICBTY29wZWRMb2NhbFJlZjxqc3RyaW5nPiBqYXZhRW50cnkoZW52LCByZWludGVycHJldF9jYXN0PGpzdHJpbmc+KGVudi0+R2V0T2JqZWN0QXJyYXlFbGVtZW50KGphdmFBcnJheSwgaSkpKTsKKyAgICAgICAgLy8gV2UgbmVlZCB0byBwYXNzIHRoZXNlIHN0cmluZ3MgdG8gY29uc3QtdW5mcmllbmRseSBjb2RlLgorICAgICAgICBjaGFyKiBlbnRyeSA9IGNvbnN0X2Nhc3Q8Y2hhcio+KGVudi0+R2V0U3RyaW5nVVRGQ2hhcnMoamF2YUVudHJ5LmdldCgpLCBOVUxMKSk7CisgICAgICAgIGFycmF5W2ldID0gZW50cnk7CisgICAgfQorCisgICAgcmV0dXJuIGFycmF5OworfQorCisvKiogRnJlZXMgYSBjaGFyKiogd2hpY2ggd2FzIGNvbnZlcnRlZCBmcm9tIGEgSmF2YSBTdHJpbmdbXS4gKi8KK3N0YXRpYyB2b2lkIGZyZWVTdHJpbmdzKEpOSUVudiogZW52LCBqb2JqZWN0QXJyYXkgamF2YUFycmF5LCBjaGFyKiogYXJyYXkpIHsKKyAgICBpZiAoamF2YUFycmF5ID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGpzaXplIGxlbmd0aCA9IGVudi0+R2V0QXJyYXlMZW5ndGgoamF2YUFycmF5KTsKKyAgICBmb3IgKGpzaXplIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHsKKyAgICAgICAgU2NvcGVkTG9jYWxSZWY8anN0cmluZz4gamF2YUVudHJ5KGVudiwgcmVpbnRlcnByZXRfY2FzdDxqc3RyaW5nPihlbnYtPkdldE9iamVjdEFycmF5RWxlbWVudChqYXZhQXJyYXksIGkpKSk7CisgICAgICAgIGVudi0+UmVsZWFzZVN0cmluZ1VURkNoYXJzKGphdmFFbnRyeS5nZXQoKSwgYXJyYXlbaV0pOworICAgIH0KKworICAgIGRlbGV0ZVtdIGFycmF5OworfQorCisvKioKKyAqIENvbnZlcnRzIEphdmEgU3RyaW5nW10gdG8gY2hhcioqIGFuZCBkZWxlZ2F0ZXMgdG8gZXhlY3V0ZVByb2Nlc3MoKS4KKyAqLworc3RhdGljIHBpZF90IFByb2Nlc3NNYW5hZ2VyX2V4ZWMoSk5JRW52KiBlbnYsIGpjbGFzcywgam9iamVjdEFycmF5IGphdmFDb21tYW5kcywKKyAgICAgICAgam9iamVjdEFycmF5IGphdmFFbnZpcm9ubWVudCwganN0cmluZyBqYXZhV29ya2luZ0RpcmVjdG9yeSwKKyAgICAgICAgam9iamVjdCBpbkRlc2NyaXB0b3IsIGpvYmplY3Qgb3V0RGVzY3JpcHRvciwgam9iamVjdCBlcnJEZXNjcmlwdG9yLAorICAgICAgICBqYm9vbGVhbiByZWRpcmVjdEVycm9yU3RyZWFtKSB7CisKKyAgICAvLyBDb3B5IGNvbW1hbmRzIGludG8gY2hhcipbXS4KKyAgICBjaGFyKiogY29tbWFuZHMgPSBjb252ZXJ0U3RyaW5ncyhlbnYsIGphdmFDb21tYW5kcyk7CisKKyAgICAvLyBFeHRyYWN0IHdvcmtpbmcgZGlyZWN0b3J5IHN0cmluZy4KKyAgICBjb25zdCBjaGFyKiB3b3JraW5nRGlyZWN0b3J5ID0gTlVMTDsKKyAgICBpZiAoamF2YVdvcmtpbmdEaXJlY3RvcnkgIT0gTlVMTCkgeworICAgICAgICB3b3JraW5nRGlyZWN0b3J5ID0gZW52LT5HZXRTdHJpbmdVVEZDaGFycyhqYXZhV29ya2luZ0RpcmVjdG9yeSwgTlVMTCk7CisgICAgfQorCisgICAgLy8gQ29udmVydCBlbnZpcm9ubWVudCBhcnJheS4KKyAgICBjaGFyKiogZW52aXJvbm1lbnQgPSBjb252ZXJ0U3RyaW5ncyhlbnYsIGphdmFFbnZpcm9ubWVudCk7CisKKyAgICBwaWRfdCByZXN1bHQgPSBleGVjdXRlUHJvY2VzcyhlbnYsIGNvbW1hbmRzLCBlbnZpcm9ubWVudCwgd29ya2luZ0RpcmVjdG9yeSwKKyAgICAgICAgICAgIGluRGVzY3JpcHRvciwgb3V0RGVzY3JpcHRvciwgZXJyRGVzY3JpcHRvciwgcmVkaXJlY3RFcnJvclN0cmVhbSk7CisKKyAgICAvLyBUZW1wb3JhcmlseSBjbGVhciBleGNlcHRpb24gc28gd2UgY2FuIGNsZWFuIHVwLgorICAgIGp0aHJvd2FibGUgZXhjZXB0aW9uID0gZW52LT5FeGNlcHRpb25PY2N1cnJlZCgpOworICAgIGVudi0+RXhjZXB0aW9uQ2xlYXIoKTsKKworICAgIGZyZWVTdHJpbmdzKGVudiwgamF2YUVudmlyb25tZW50LCBlbnZpcm9ubWVudCk7CisKKyAgICAvLyBDbGVhbiB1cCB3b3JraW5nIGRpcmVjdG9yeSBzdHJpbmcuCisgICAgaWYgKGphdmFXb3JraW5nRGlyZWN0b3J5ICE9IE5VTEwpIHsKKyAgICAgICAgZW52LT5SZWxlYXNlU3RyaW5nVVRGQ2hhcnMoamF2YVdvcmtpbmdEaXJlY3RvcnksIHdvcmtpbmdEaXJlY3RvcnkpOworICAgIH0KKworICAgIGZyZWVTdHJpbmdzKGVudiwgamF2YUNvbW1hbmRzLCBjb21tYW5kcyk7CisKKyAgICAvLyBSZS10aHJvdyBleGNlcHRpb24gaWYgcHJlc2VudC4KKyAgICBpZiAoZXhjZXB0aW9uICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKGVudi0+VGhyb3coZXhjZXB0aW9uKSA8IDApIHsKKyAgICAgICAgICAgIExPR0UoIkVycm9yIHJldGhyb3dpbmcgZXhjZXB0aW9uISIpOworICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBtZXRob2RzW10gPSB7CisgICAgTkFUSVZFX01FVEhPRChQcm9jZXNzTWFuYWdlciwgZXhlYywgIihbTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yO0xqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yO0xqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yO1opSSIpLAorfTsKK2ludCByZWdpc3Rlcl9qYXZhX2xhbmdfUHJvY2Vzc01hbmFnZXIoSk5JRW52KiBlbnYpIHsKKyAgICByZXR1cm4gam5pUmVnaXN0ZXJOYXRpdmVNZXRob2RzKGVudiwgImphdmEvbGFuZy9Qcm9jZXNzTWFuYWdlciIsIG1ldGhvZHMsIE5FTEVNKG1ldGhvZHMpKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfbGFuZ19SZWFsVG9TdHJpbmcuY3BwIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV9sYW5nX1JlYWxUb1N0cmluZy5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODM1MTUxZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfbGFuZ19SZWFsVG9TdHJpbmcuY3BwCkBAIC0wLDAgKzEsMjQyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIlJlYWxUb1N0cmluZyIKKworI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPG1hdGguaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKworI2luY2x1ZGUgIkpOSUhlbHAuaCIKKyNpbmNsdWRlICJKbmlDb25zdGFudHMuaCIKKyNpbmNsdWRlICJTY29wZWRMb2NhbFJlZi5oIgorI2luY2x1ZGUgIlNjb3BlZFByaW1pdGl2ZUFycmF5LmgiCisjaW5jbHVkZSAiY2JpZ2ludC5oIgorCisjZGVmaW5lIElOVl9MT0dfT0ZfVEVOX0JBU0VfMiAoMC4zMDEwMjk5OTU2NjM5ODExNCkgLyogTG9jYWwgKi8KKworLypOQiB0aGUgTnVtYmVyIGNvbnZlcnRlciBtZXRob2RzIGFyZSBzeW5jaHJvbml6ZWQgc28gaXQgaXMgcG9zc2libGUgdG8KKyAqaGF2ZSBnbG9iYWwgZGF0YSBmb3IgdXNlIGJ5IGJpZ0ludERpZ2l0R2VuZXJhdG9yICovCisjZGVmaW5lIFJNX1NJWkUgMjEgICAgIC8qIExvY2FsLiAqLworI2RlZmluZSBTVGVtcF9TSVpFIDIyICAvKiBMb2NhbC4gKi8KKworLyogVGhlIGFsZ29yaXRobSBmb3IgdGhpcyBwYXJ0aWN1bGFyIGZ1bmN0aW9uIGNhbiBiZSBmb3VuZCBpbjoKKyAqCisgKiAgICAgIFByaW50aW5nIEZsb2F0aW5nLVBvaW50IE51bWJlcnMgUXVpY2tseSBhbmQgQWNjdXJhdGVseSwgUm9iZXJ0CisgKiAgICAgIEcuIEJ1cmdlciwgYW5kIFIuIEtlbnQgRHlidmlnLCBQcm9ncmFtbWluZyBMYW5ndWFnZSBEZXNpZ24gYW5kCisgKiAgICAgIEltcGxlbWVudGF0aW9uIChQTERJKSAxOTk2LCBwcC4xMDgtMTE2LgorICoKKyAqIFRoZSBwcmV2aW91cyBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGZ1bmN0aW9uIGNvbWJpbmVkIG0rIGFuZCBtLSBpbnRvCisgKiBvbmUgc2luZ2xlIE0gd2hpY2ggY2F1c2VkIHNvbWUgaW5hY2N1cmFjeSBvZiB0aGUgbGFzdCBkaWdpdC4gVGhlCisgKiBwYXJ0aWN1bGFyIGNhc2UgYmVsb3cgc2hvd3MgdGhpcyBpbmFjY3VyYWN5OgorICoKKyAqICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihuZXcgRG91YmxlKCgxLjIzNDEyMzQxMjQzMTIzM0UxMDcpKS50b1N0cmluZygpKTsKKyAqICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihuZXcgRG91YmxlKCgxLjIzNDEyMzQxMjQzMTIzMzFFMTA3KSkudG9TdHJpbmcoKSk7CisgKiAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obmV3IERvdWJsZSgoMS4yMzQxMjM0MTI0MzEyMzMyRTEwNykpLnRvU3RyaW5nKCkpOworICoKKyAqICAgICAgIG91dHB1dHMgdGhlIGZvbGxvd2luZzoKKyAqCisgKiAgICAgICAgICAgMS4yMzQxMjM0MTI0MzEyMzNFMTA3CisgKiAgICAgICAgICAgMS4yMzQxMjM0MTI0MzEyMzNFMTA3CisgKiAgICAgICAgICAgMS4yMzQxMjM0MTI0MzEyMzNFMTA3CisgKgorICogICAgICAgaW5zdGVhZCBvZjoKKyAqCisgKiAgICAgICAgICAgMS4yMzQxMjM0MTI0MzEyMzNFMTA3CisgKiAgICAgICAgICAgMS4yMzQxMjM0MTI0MzEyMzMxRTEwNworICogICAgICAgICAgIDEuMjM0MTIzNDEyNDMxMjMzMUUxMDcKKyAqCisgKi8KK3ZvaWQgUmVhbFRvU3RyaW5nX2JpZ0ludERpZ2l0R2VuZXJhdG9yKEpOSUVudiogZW52LCBqb2JqZWN0IG9iaiwgamxvbmcgZiwgamludCBlLAorICAgICAgICBqYm9vbGVhbiBpc0Rlbm9ybWFsaXplZCwgamludCBwKSB7CisgIGludCBSTGVuZ3RoLCBTTGVuZ3RoLCBUZW1wTGVuZ3RoLCBtcGx1c19MZW5ndGgsIG1taW51c19MZW5ndGg7CisgIGludCBoaWdoLCBsb3csIGk7CisgIGppbnQgaywgZmlyc3RLLCBVOworCisgIHVpbnQ2NF90IFJbUk1fU0laRV0sIFNbU1RlbXBfU0laRV0sIG1wbHVzW1JNX1NJWkVdLCBtbWludXNbUk1fU0laRV0sIFRlbXBbU1RlbXBfU0laRV07CisKKyAgbWVtc2V0IChSICAgICAsIDAsIFJNX1NJWkUgICAgKiBzaXplb2YgKHVpbnQ2NF90KSk7CisgIG1lbXNldCAoUyAgICAgLCAwLCBTVGVtcF9TSVpFICogc2l6ZW9mICh1aW50NjRfdCkpOworICBtZW1zZXQgKG1wbHVzICwgMCwgUk1fU0laRSAgICAqIHNpemVvZiAodWludDY0X3QpKTsKKyAgbWVtc2V0IChtbWludXMsIDAsIFJNX1NJWkUgICAgKiBzaXplb2YgKHVpbnQ2NF90KSk7CisgIG1lbXNldCAoVGVtcCAgLCAwLCBTVGVtcF9TSVpFICogc2l6ZW9mICh1aW50NjRfdCkpOworCisgIGlmIChlID49IDApCisgICAgeworICAgICAgKlIgPSBmOworICAgICAgKm1wbHVzID0gKm1taW51cyA9IDE7CisgICAgICBzaW1wbGVTaGlmdExlZnRIaWdoUHJlY2lzaW9uIChtbWludXMsIFJNX1NJWkUsIGUpOworICAgICAgaWYgKGYgIT0gKDIgPDwgKHAgLSAxKSkpCisgICAgICAgIHsKKyAgICAgICAgICBzaW1wbGVTaGlmdExlZnRIaWdoUHJlY2lzaW9uIChSLCBSTV9TSVpFLCBlICsgMSk7CisgICAgICAgICAgKlMgPSAyOworICAgICAgICAgIC8qCisgICAgICAgICAgICogbSsgPSBtKyA8PCBlIHJlc3VsdHMgaW4gMS4wZTIzIHRvIGJlIHByaW50ZWQgYXMKKyAgICAgICAgICAgKiAwLjk5OTk5OTk5OTk5OTk5OTlFMjMKKyAgICAgICAgICAgKiBtKyA9IG0rIDw8IGUrMSByZXN1bHRzIGluIDEuMGUyMyB0byBiZSBwcmludGVkIGFzCisgICAgICAgICAgICogMS4wZTIzIChjYXVzZWQgdG9vIG11Y2ggcm91bmRpbmcpCisgICAgICAgICAgICogICAgICA0NzBmZmZmZmZmZmZmZmZmID0gMi4wNzY5MTg3NDM0MTM5MzA4RTM0CisgICAgICAgICAgICogICAgICA0NzEwMDAwMDAwMDAwMDAwID0gMi4wNzY5MTg3NDM0MTM5MzFFMzQKKyAgICAgICAgICAgKi8KKyAgICAgICAgICBzaW1wbGVTaGlmdExlZnRIaWdoUHJlY2lzaW9uIChtcGx1cywgUk1fU0laRSwgZSk7CisgICAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgIHNpbXBsZVNoaWZ0TGVmdEhpZ2hQcmVjaXNpb24gKFIsIFJNX1NJWkUsIGUgKyAyKTsKKyAgICAgICAgICAqUyA9IDQ7CisgICAgICAgICAgc2ltcGxlU2hpZnRMZWZ0SGlnaFByZWNpc2lvbiAobXBsdXMsIFJNX1NJWkUsIGUgKyAxKTsKKyAgICAgICAgfQorICAgIH0KKyAgZWxzZQorICAgIHsKKyAgICAgIGlmIChpc0Rlbm9ybWFsaXplZCB8fCAoZiAhPSAoMiA8PCAocCAtIDEpKSkpCisgICAgICAgIHsKKyAgICAgICAgICAqUiA9IGYgPDwgMTsKKyAgICAgICAgICAqUyA9IDE7CisgICAgICAgICAgc2ltcGxlU2hpZnRMZWZ0SGlnaFByZWNpc2lvbiAoUywgU1RlbXBfU0laRSwgMSAtIGUpOworICAgICAgICAgICptcGx1cyA9ICptbWludXMgPSAxOworICAgICAgICB9CisgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICAqUiA9IGYgPDwgMjsKKyAgICAgICAgICAqUyA9IDE7CisgICAgICAgICAgc2ltcGxlU2hpZnRMZWZ0SGlnaFByZWNpc2lvbiAoUywgU1RlbXBfU0laRSwgMiAtIGUpOworICAgICAgICAgICptcGx1cyA9IDI7CisgICAgICAgICAgKm1taW51cyA9IDE7CisgICAgICAgIH0KKyAgICB9CisKKyAgayA9IHN0YXRpY19jYXN0PGludD4oY2VpbCAoKGUgKyBwIC0gMSkgKiBJTlZfTE9HX09GX1RFTl9CQVNFXzIgLSAxZS0xMCkpOworCisgIGlmIChrID4gMCkKKyAgICB7CisgICAgICB0aW1lc1RlblRvVGhlRUhpZ2hQcmVjaXNpb24gKFMsIFNUZW1wX1NJWkUsIGspOworICAgIH0KKyAgZWxzZQorICAgIHsKKyAgICAgIHRpbWVzVGVuVG9UaGVFSGlnaFByZWNpc2lvbiAoUiAgICAgLCBSTV9TSVpFLCAtayk7CisgICAgICB0aW1lc1RlblRvVGhlRUhpZ2hQcmVjaXNpb24gKG1wbHVzICwgUk1fU0laRSwgLWspOworICAgICAgdGltZXNUZW5Ub1RoZUVIaWdoUHJlY2lzaW9uIChtbWludXMsIFJNX1NJWkUsIC1rKTsKKyAgICB9CisKKyAgUkxlbmd0aCA9IG1wbHVzX0xlbmd0aCA9IG1taW51c19MZW5ndGggPSBSTV9TSVpFOworICBTTGVuZ3RoID0gVGVtcExlbmd0aCA9IFNUZW1wX1NJWkU7CisKKyAgbWVtc2V0IChUZW1wICsgUk1fU0laRSwgMCwgKFNUZW1wX1NJWkUgLSBSTV9TSVpFKSAqIHNpemVvZiAodWludDY0X3QpKTsKKyAgbWVtY3B5IChUZW1wLCBSLCBSTV9TSVpFICogc2l6ZW9mICh1aW50NjRfdCkpOworCisgIHdoaWxlIChSTGVuZ3RoID4gMSAmJiBSW1JMZW5ndGggLSAxXSA9PSAwKQorICAgIC0tUkxlbmd0aDsKKyAgd2hpbGUgKG1wbHVzX0xlbmd0aCA+IDEgJiYgbXBsdXNbbXBsdXNfTGVuZ3RoIC0gMV0gPT0gMCkKKyAgICAtLW1wbHVzX0xlbmd0aDsKKyAgd2hpbGUgKG1taW51c19MZW5ndGggPiAxICYmIG1taW51c1ttbWludXNfTGVuZ3RoIC0gMV0gPT0gMCkKKyAgICAtLW1taW51c19MZW5ndGg7CisgIHdoaWxlIChTTGVuZ3RoID4gMSAmJiBTW1NMZW5ndGggLSAxXSA9PSAwKQorICAgIC0tU0xlbmd0aDsKKyAgVGVtcExlbmd0aCA9IChSTGVuZ3RoID4gbXBsdXNfTGVuZ3RoID8gUkxlbmd0aCA6IG1wbHVzX0xlbmd0aCkgKyAxOworICBhZGRIaWdoUHJlY2lzaW9uIChUZW1wLCBUZW1wTGVuZ3RoLCBtcGx1cywgbXBsdXNfTGVuZ3RoKTsKKworICBpZiAoY29tcGFyZUhpZ2hQcmVjaXNpb24gKFRlbXAsIFRlbXBMZW5ndGgsIFMsIFNMZW5ndGgpID49IDApCisgICAgeworICAgICAgZmlyc3RLID0gazsKKyAgICB9CisgIGVsc2UKKyAgICB7CisgICAgICBmaXJzdEsgPSBrIC0gMTsKKyAgICAgIHNpbXBsZUFwcGVuZERlY2ltYWxEaWdpdEhpZ2hQcmVjaXNpb24gKFIgICAgICwgKytSTGVuZ3RoICAgICAgLCAwKTsKKyAgICAgIHNpbXBsZUFwcGVuZERlY2ltYWxEaWdpdEhpZ2hQcmVjaXNpb24gKG1wbHVzICwgKyttcGx1c19MZW5ndGggLCAwKTsKKyAgICAgIHNpbXBsZUFwcGVuZERlY2ltYWxEaWdpdEhpZ2hQcmVjaXNpb24gKG1taW51cywgKyttbWludXNfTGVuZ3RoLCAwKTsKKyAgICAgIHdoaWxlIChSTGVuZ3RoID4gMSAmJiBSW1JMZW5ndGggLSAxXSA9PSAwKQorICAgICAgICAtLVJMZW5ndGg7CisgICAgICB3aGlsZSAobXBsdXNfTGVuZ3RoID4gMSAmJiBtcGx1c1ttcGx1c19MZW5ndGggLSAxXSA9PSAwKQorICAgICAgICAtLW1wbHVzX0xlbmd0aDsKKyAgICAgIHdoaWxlIChtbWludXNfTGVuZ3RoID4gMSAmJiBtbWludXNbbW1pbnVzX0xlbmd0aCAtIDFdID09IDApCisgICAgICAgIC0tbW1pbnVzX0xlbmd0aDsKKyAgICB9CisKKyAgc3RhdGljIGpmaWVsZElEIGRpZ2l0c0ZpZCA9IGVudi0+R2V0RmllbGRJRChKbmlDb25zdGFudHM6OnJlYWxUb1N0cmluZ0NsYXNzLCAiZGlnaXRzIiwgIltJIik7CisgIFNjb3BlZExvY2FsUmVmPGppbnRBcnJheT4gamF2YURpZ2l0cyhlbnYsIHJlaW50ZXJwcmV0X2Nhc3Q8amludEFycmF5PihlbnYtPkdldE9iamVjdEZpZWxkKG9iaiwgZGlnaXRzRmlkKSkpOworICBTY29wZWRJbnRBcnJheVJXIGRpZ2l0cyhlbnYsIGphdmFEaWdpdHMuZ2V0KCkpOworICBpZiAoZGlnaXRzLmdldCgpID09IE5VTEwpIHsKKyAgICByZXR1cm47CisgIH0KKworICBqaW50IGRpZ2l0Q291bnQgPSAwOworICBkbworICAgIHsKKyAgICAgIFUgPSAwOworICAgICAgZm9yIChpID0gMzsgaSA+PSAwOyAtLWkpCisgICAgICAgIHsKKyAgICAgICAgICBUZW1wTGVuZ3RoID0gU0xlbmd0aCArIDE7CisgICAgICAgICAgVGVtcFtTTGVuZ3RoXSA9IDA7CisgICAgICAgICAgbWVtY3B5IChUZW1wLCBTLCBTTGVuZ3RoICogc2l6ZW9mICh1aW50NjRfdCkpOworICAgICAgICAgIHNpbXBsZVNoaWZ0TGVmdEhpZ2hQcmVjaXNpb24gKFRlbXAsIFRlbXBMZW5ndGgsIGkpOworICAgICAgICAgIGlmIChjb21wYXJlSGlnaFByZWNpc2lvbiAoUiwgUkxlbmd0aCwgVGVtcCwgVGVtcExlbmd0aCkgPj0gMCkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgc3VidHJhY3RIaWdoUHJlY2lzaW9uIChSLCBSTGVuZ3RoLCBUZW1wLCBUZW1wTGVuZ3RoKTsKKyAgICAgICAgICAgICAgVSArPSAxIDw8IGk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgbG93ID0gY29tcGFyZUhpZ2hQcmVjaXNpb24gKFIsIFJMZW5ndGgsIG1taW51cywgbW1pbnVzX0xlbmd0aCkgPD0gMDsKKworICAgICAgbWVtc2V0IChUZW1wICsgUkxlbmd0aCwgMCwgKFNUZW1wX1NJWkUgLSBSTGVuZ3RoKSAqIHNpemVvZiAodWludDY0X3QpKTsKKyAgICAgIG1lbWNweSAoVGVtcCwgUiwgUkxlbmd0aCAqIHNpemVvZiAodWludDY0X3QpKTsKKyAgICAgIFRlbXBMZW5ndGggPSAoUkxlbmd0aCA+IG1wbHVzX0xlbmd0aCA/IFJMZW5ndGggOiBtcGx1c19MZW5ndGgpICsgMTsKKyAgICAgIGFkZEhpZ2hQcmVjaXNpb24gKFRlbXAsIFRlbXBMZW5ndGgsIG1wbHVzLCBtcGx1c19MZW5ndGgpOworCisgICAgICBoaWdoID0gY29tcGFyZUhpZ2hQcmVjaXNpb24gKFRlbXAsIFRlbXBMZW5ndGgsIFMsIFNMZW5ndGgpID49IDA7CisKKyAgICAgIGlmIChsb3cgfHwgaGlnaCkKKyAgICAgICAgYnJlYWs7CisKKyAgICAgIHNpbXBsZUFwcGVuZERlY2ltYWxEaWdpdEhpZ2hQcmVjaXNpb24gKFIgICAgICwgKytSTGVuZ3RoICAgICAgLCAwKTsKKyAgICAgIHNpbXBsZUFwcGVuZERlY2ltYWxEaWdpdEhpZ2hQcmVjaXNpb24gKG1wbHVzICwgKyttcGx1c19MZW5ndGggLCAwKTsKKyAgICAgIHNpbXBsZUFwcGVuZERlY2ltYWxEaWdpdEhpZ2hQcmVjaXNpb24gKG1taW51cywgKyttbWludXNfTGVuZ3RoLCAwKTsKKyAgICAgIHdoaWxlIChSTGVuZ3RoID4gMSAmJiBSW1JMZW5ndGggLSAxXSA9PSAwKQorICAgICAgICAtLVJMZW5ndGg7CisgICAgICB3aGlsZSAobXBsdXNfTGVuZ3RoID4gMSAmJiBtcGx1c1ttcGx1c19MZW5ndGggLSAxXSA9PSAwKQorICAgICAgICAtLW1wbHVzX0xlbmd0aDsKKyAgICAgIHdoaWxlIChtbWludXNfTGVuZ3RoID4gMSAmJiBtbWludXNbbW1pbnVzX0xlbmd0aCAtIDFdID09IDApCisgICAgICAgIC0tbW1pbnVzX0xlbmd0aDsKKyAgICAgIGRpZ2l0c1tkaWdpdENvdW50KytdID0gVTsKKyAgICB9CisgIHdoaWxlICgxKTsKKworICBzaW1wbGVTaGlmdExlZnRIaWdoUHJlY2lzaW9uIChSLCArK1JMZW5ndGgsIDEpOworICBpZiAobG93ICYmICFoaWdoKQorICAgIGRpZ2l0c1tkaWdpdENvdW50KytdID0gVTsKKyAgZWxzZSBpZiAoaGlnaCAmJiAhbG93KQorICAgIGRpZ2l0c1tkaWdpdENvdW50KytdID0gVSArIDE7CisgIGVsc2UgaWYgKGNvbXBhcmVIaWdoUHJlY2lzaW9uIChSLCBSTGVuZ3RoLCBTLCBTTGVuZ3RoKSA8IDApCisgICAgZGlnaXRzW2RpZ2l0Q291bnQrK10gPSBVOworICBlbHNlCisgICAgZGlnaXRzW2RpZ2l0Q291bnQrK10gPSBVICsgMTsKKworICBzdGF0aWMgamZpZWxkSUQgZGlnaXRDb3VudEZpZCA9IGVudi0+R2V0RmllbGRJRChKbmlDb25zdGFudHM6OnJlYWxUb1N0cmluZ0NsYXNzLCAiZGlnaXRDb3VudCIsICJJIik7CisgIGVudi0+U2V0SW50RmllbGQob2JqLCBkaWdpdENvdW50RmlkLCBkaWdpdENvdW50KTsKKworICBzdGF0aWMgamZpZWxkSUQgZmlyc3RLRmlkID0gZW52LT5HZXRGaWVsZElEKEpuaUNvbnN0YW50czo6cmVhbFRvU3RyaW5nQ2xhc3MsICJmaXJzdEsiLCAiSSIpOworICBlbnYtPlNldEludEZpZWxkKG9iaiwgZmlyc3RLRmlkLCBmaXJzdEspOworfQorCitzdGF0aWMgSk5JTmF0aXZlTWV0aG9kIGdNZXRob2RzW10gPSB7CisgICAgTkFUSVZFX01FVEhPRChSZWFsVG9TdHJpbmcsIGJpZ0ludERpZ2l0R2VuZXJhdG9yLCAiKEpJWkkpViIpLAorfTsKK2ludCByZWdpc3Rlcl9qYXZhX2xhbmdfUmVhbFRvU3RyaW5nKEpOSUVudiogZW52KSB7CisgICAgcmV0dXJuIGpuaVJlZ2lzdGVyTmF0aXZlTWV0aG9kcyhlbnYsICJqYXZhL2xhbmcvUmVhbFRvU3RyaW5nIiwgZ01ldGhvZHMsIE5FTEVNKGdNZXRob2RzKSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX2xhbmdfU3RyaWN0TWF0aC5jcHAgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX2xhbmdfU3RyaWN0TWF0aC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmRmM2YwMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfbGFuZ19TdHJpY3RNYXRoLmNwcApAQCAtMCwwICsxLDE1MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNiBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiU3RyaWN0TWF0aCIKKworI2luY2x1ZGUgIi4uLy4uL2V4dGVybmFsL2ZkbGlibS9mZGxpYm0uaCIKKworI2luY2x1ZGUgImpuaS5oIgorI2luY2x1ZGUgIkpOSUhlbHAuaCIKKyNpbmNsdWRlICJKbmlDb25zdGFudHMuaCIKKworc3RhdGljIGpkb3VibGUgU3RyaWN0TWF0aF9zaW4oSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gaWVlZV9zaW4oYSk7Cit9CisKK3N0YXRpYyBqZG91YmxlIFN0cmljdE1hdGhfY29zKEpOSUVudiosIGpjbGFzcywgamRvdWJsZSBhKSB7CisgICAgcmV0dXJuIGllZWVfY29zKGEpOworfQorCitzdGF0aWMgamRvdWJsZSBTdHJpY3RNYXRoX3RhbihKTklFbnYqLCBqY2xhc3MsIGpkb3VibGUgYSkgeworICAgIHJldHVybiBpZWVlX3RhbihhKTsKK30KKworc3RhdGljIGpkb3VibGUgU3RyaWN0TWF0aF9hc2luKEpOSUVudiosIGpjbGFzcywgamRvdWJsZSBhKSB7CisgICAgcmV0dXJuIGllZWVfYXNpbihhKTsKK30KKworc3RhdGljIGpkb3VibGUgU3RyaWN0TWF0aF9hY29zKEpOSUVudiosIGpjbGFzcywgamRvdWJsZSBhKSB7CisgICAgcmV0dXJuIGllZWVfYWNvcyhhKTsKK30KKworc3RhdGljIGpkb3VibGUgU3RyaWN0TWF0aF9hdGFuKEpOSUVudiosIGpjbGFzcywgamRvdWJsZSBhKSB7CisgICAgcmV0dXJuIGllZWVfYXRhbihhKTsKK30KKworc3RhdGljIGpkb3VibGUgU3RyaWN0TWF0aF9leHAoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gaWVlZV9leHAoYSk7Cit9CisKK3N0YXRpYyBqZG91YmxlIFN0cmljdE1hdGhfbG9nKEpOSUVudiosIGpjbGFzcywgamRvdWJsZSBhKSB7CisgICAgcmV0dXJuIGllZWVfbG9nKGEpOworfQorCitzdGF0aWMgamRvdWJsZSBTdHJpY3RNYXRoX3NxcnQoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gaWVlZV9zcXJ0KGEpOworfQorCitzdGF0aWMgamRvdWJsZSBTdHJpY3RNYXRoX0lFRUVyZW1haW5kZXIoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEsIGpkb3VibGUgYikgeworICAgIHJldHVybiBpZWVlX3JlbWFpbmRlcihhLCBiKTsKK30KKworc3RhdGljIGpkb3VibGUgU3RyaWN0TWF0aF9mbG9vcihKTklFbnYqLCBqY2xhc3MsIGpkb3VibGUgYSkgeworICAgIHJldHVybiBpZWVlX2Zsb29yKGEpOworfQorCitzdGF0aWMgamRvdWJsZSBTdHJpY3RNYXRoX2NlaWwoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gaWVlZV9jZWlsKGEpOworfQorCitzdGF0aWMgamRvdWJsZSBTdHJpY3RNYXRoX3JpbnQoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gaWVlZV9yaW50KGEpOworfQorCitzdGF0aWMgamRvdWJsZSBTdHJpY3RNYXRoX2F0YW4yKEpOSUVudiosIGpjbGFzcywgamRvdWJsZSBhLCBqZG91YmxlIGIpIHsKKyAgICByZXR1cm4gaWVlZV9hdGFuMihhLCBiKTsKK30KKworc3RhdGljIGpkb3VibGUgU3RyaWN0TWF0aF9wb3coSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEsIGpkb3VibGUgYikgeworICAgIHJldHVybiBpZWVlX3BvdyhhLGIpOworfQorCitzdGF0aWMgamRvdWJsZSBTdHJpY3RNYXRoX3NpbmgoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gaWVlZV9zaW5oKGEpOworfQorCitzdGF0aWMgamRvdWJsZSBTdHJpY3RNYXRoX3RhbmgoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gaWVlZV90YW5oKGEpOworfQorCitzdGF0aWMgamRvdWJsZSBTdHJpY3RNYXRoX2Nvc2goSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gaWVlZV9jb3NoKGEpOworfQorCitzdGF0aWMgamRvdWJsZSBTdHJpY3RNYXRoX2xvZzEwKEpOSUVudiosIGpjbGFzcywgamRvdWJsZSBhKSB7CisgICAgcmV0dXJuIGllZWVfbG9nMTAoYSk7Cit9CisKK3N0YXRpYyBqZG91YmxlIFN0cmljdE1hdGhfY2JydChKTklFbnYqLCBqY2xhc3MsIGpkb3VibGUgYSkgeworICAgIHJldHVybiBpZWVlX2NicnQoYSk7Cit9CisKK3N0YXRpYyBqZG91YmxlIFN0cmljdE1hdGhfZXhwbTEoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gaWVlZV9leHBtMShhKTsKK30KKworc3RhdGljIGpkb3VibGUgU3RyaWN0TWF0aF9oeXBvdChKTklFbnYqLCBqY2xhc3MsIGpkb3VibGUgYSwgamRvdWJsZSBiKSB7CisgICAgcmV0dXJuIGllZWVfaHlwb3QoYSwgYik7Cit9CisKK3N0YXRpYyBqZG91YmxlIFN0cmljdE1hdGhfbG9nMXAoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEpIHsKKyAgICByZXR1cm4gaWVlZV9sb2cxcChhKTsKK30KKworc3RhdGljIGpkb3VibGUgU3RyaWN0TWF0aF9uZXh0YWZ0ZXIoSk5JRW52KiwgamNsYXNzLCBqZG91YmxlIGEsIGpkb3VibGUgYikgeworICAgIHJldHVybiBpZWVlX25leHRhZnRlcihhLCBiKTsKK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBnTWV0aG9kc1tdID0geworICAgIE5BVElWRV9NRVRIT0QoU3RyaWN0TWF0aCwgSUVFRXJlbWFpbmRlciwgIiEoREQpRCIpLAorICAgIE5BVElWRV9NRVRIT0QoU3RyaWN0TWF0aCwgYWNvcywgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChTdHJpY3RNYXRoLCBhc2luLCAiIShEKUQiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFN0cmljdE1hdGgsIGF0YW4sICIhKEQpRCIpLAorICAgIE5BVElWRV9NRVRIT0QoU3RyaWN0TWF0aCwgYXRhbjIsICIhKEREKUQiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFN0cmljdE1hdGgsIGNicnQsICIhKEQpRCIpLAorICAgIE5BVElWRV9NRVRIT0QoU3RyaWN0TWF0aCwgY2VpbCwgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChTdHJpY3RNYXRoLCBjb3MsICIhKEQpRCIpLAorICAgIE5BVElWRV9NRVRIT0QoU3RyaWN0TWF0aCwgY29zaCwgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChTdHJpY3RNYXRoLCBleHAsICIhKEQpRCIpLAorICAgIE5BVElWRV9NRVRIT0QoU3RyaWN0TWF0aCwgZXhwbTEsICIhKEQpRCIpLAorICAgIE5BVElWRV9NRVRIT0QoU3RyaWN0TWF0aCwgZmxvb3IsICIhKEQpRCIpLAorICAgIE5BVElWRV9NRVRIT0QoU3RyaWN0TWF0aCwgaHlwb3QsICIhKEREKUQiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFN0cmljdE1hdGgsIGxvZywgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChTdHJpY3RNYXRoLCBsb2cxMCwgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChTdHJpY3RNYXRoLCBsb2cxcCwgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChTdHJpY3RNYXRoLCBuZXh0YWZ0ZXIsICIhKEREKUQiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFN0cmljdE1hdGgsIHBvdywgIiEoREQpRCIpLAorICAgIE5BVElWRV9NRVRIT0QoU3RyaWN0TWF0aCwgcmludCwgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChTdHJpY3RNYXRoLCBzaW4sICIhKEQpRCIpLAorICAgIE5BVElWRV9NRVRIT0QoU3RyaWN0TWF0aCwgc2luaCwgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChTdHJpY3RNYXRoLCBzcXJ0LCAiIShEKUQiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFN0cmljdE1hdGgsIHRhbiwgIiEoRClEIiksCisgICAgTkFUSVZFX01FVEhPRChTdHJpY3RNYXRoLCB0YW5oLCAiIShEKUQiKSwKK307CisKK2ludCByZWdpc3Rlcl9qYXZhX2xhbmdfU3RyaWN0TWF0aChKTklFbnYqIGVudikgeworICAgIHJldHVybiBqbmlSZWdpc3Rlck5hdGl2ZU1ldGhvZHMoZW52LCAiamF2YS9sYW5nL1N0cmljdE1hdGgiLCBnTWV0aG9kcywgTkVMRU0oZ01ldGhvZHMpKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfbGFuZ19TdHJpbmdUb1JlYWwuY3BwIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV9sYW5nX1N0cmluZ1RvUmVhbC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWRjMDk2ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfbGFuZ19TdHJpbmdUb1JlYWwuY3BwCkBAIC0wLDAgKzEsMTAxMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPG1hdGguaD4KKyNpbmNsdWRlICJKTklIZWxwLmgiCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisjaW5jbHVkZSAiSm5pRXhjZXB0aW9uLmgiCisjaW5jbHVkZSAiU2NvcGVkVXRmQ2hhcnMuaCIKKyNpbmNsdWRlICJjYmlnaW50LmgiCisKKy8qICoqKioqKioqKioqKioqKioqKioqKioqKiogRGVmaW5lcyAqKioqKioqKioqKioqKioqKioqKioqKioqICovCisjaWYgZGVmaW5lZChfX2xpbnV4X18pIHx8IGRlZmluZWQoRlJFRUJTRCkKKyNkZWZpbmUgVVNFX0xMCisjZW5kaWYKKworI2RlZmluZSBMT1dfSTMyX0ZST01fVkFSKHU2NCkgICAgIExPV19JMzJfRlJPTV9MT05HNjQodTY0KQorI2RlZmluZSBMT1dfSTMyX0ZST01fUFRSKHU2NHB0cikgIExPV19JMzJfRlJPTV9MT05HNjRfUFRSKHU2NHB0cikKKyNkZWZpbmUgSElHSF9JMzJfRlJPTV9WQVIodTY0KSAgICBISUdIX0kzMl9GUk9NX0xPTkc2NCh1NjQpCisjZGVmaW5lIEhJR0hfSTMyX0ZST01fUFRSKHU2NHB0cikgSElHSF9JMzJfRlJPTV9MT05HNjRfUFRSKHU2NHB0cikKKworI2RlZmluZSBNQVhfRE9VQkxFX0FDQ1VSQUNZX1dJRFRIIDE3CisKKyNkZWZpbmUgREVGQVVMVF9ET1VCTEVfV0lEVEggTUFYX0RPVUJMRV9BQ0NVUkFDWV9XSURUSAorCisjaWYgZGVmaW5lZChVU0VfTEwpCisjZGVmaW5lIERPVUJMRV9JTkZJTklURV9MT05HQklUUyAoMHg3RkYwMDAwMDAwMDAwMDAwTEwpCisjZWxzZQorI2lmIGRlZmluZWQoVVNFX0wpCisjZGVmaW5lIERPVUJMRV9JTkZJTklURV9MT05HQklUUyAoMHg3RkYwMDAwMDAwMDAwMDAwTCkKKyNlbHNlCisjZGVmaW5lIERPVUJMRV9JTkZJTklURV9MT05HQklUUyAoMHg3RkYwMDAwMDAwMDAwMDAwKQorI2VuZGlmIC8qIFVTRV9MICovCisjZW5kaWYgLyogVVNFX0xMICovCisKKyNkZWZpbmUgRE9VQkxFX01JTklNVU1fTE9OR0JJVFMgKDB4MSkKKworI2lmIGRlZmluZWQoVVNFX0xMKQorI2RlZmluZSBET1VCTEVfTUFOVElTU0FfTUFTSyAoMHgwMDBGRkZGRkZGRkZGRkZGTEwpCisjZGVmaW5lIERPVUJMRV9FWFBPTkVOVF9NQVNLICgweDdGRjAwMDAwMDAwMDAwMDBMTCkKKyNkZWZpbmUgRE9VQkxFX05PUk1BTF9NQVNLICAgKDB4MDAxMDAwMDAwMDAwMDAwMExMKQorI2Vsc2UKKyNpZiBkZWZpbmVkKFVTRV9MKQorI2RlZmluZSBET1VCTEVfTUFOVElTU0FfTUFTSyAoMHgwMDBGRkZGRkZGRkZGRkZGTCkKKyNkZWZpbmUgRE9VQkxFX0VYUE9ORU5UX01BU0sgKDB4N0ZGMDAwMDAwMDAwMDAwMEwpCisjZGVmaW5lIERPVUJMRV9OT1JNQUxfTUFTSyAgICgweDAwMTAwMDAwMDAwMDAwMDBMKQorI2Vsc2UKKyNkZWZpbmUgRE9VQkxFX01BTlRJU1NBX01BU0sgKDB4MDAwRkZGRkZGRkZGRkZGRikKKyNkZWZpbmUgRE9VQkxFX0VYUE9ORU5UX01BU0sgKDB4N0ZGMDAwMDAwMDAwMDAwMCkKKyNkZWZpbmUgRE9VQkxFX05PUk1BTF9NQVNLICAgKDB4MDAxMDAwMDAwMDAwMDAwMCkKKyNlbmRpZiAvKiBVU0VfTCAqLworI2VuZGlmIC8qIFVTRV9MTCAqLworCisvKiBLZWVwIGEgY291bnQgb2YgdGhlIG51bWJlciBvZiB0aW1lcyB3ZSBkZWNyZW1lbnQgYW5kIGluY3JlbWVudCB0bworICogYXBwcm94aW1hdGUgdGhlIGRvdWJsZSwgYW5kIGF0dGVtcHQgdG8gZGV0ZWN0IHRoZSBjYXNlIHdoZXJlIHdlCisgKiBjb3VsZCBwb3RlbnRpYWxseSB0b2dnbGUgYmFjayBhbmQgZm9ydGggYmV0d2VlbiBkZWNyZW1lbnRpbmcgYW5kCisgKiBpbmNyZW1lbnRpbmcuIEl0IGlzIHBvc3NpYmxlIGZvciB1cyB0byBiZSBzdHVjayBpbiB0aGUgbG9vcCB3aGVuCisgKiBpbmNyZW1lbnRpbmcgYnkgb25lIG9yIGRlY3JlbWVudGluZyBieSBvbmUgbWF5IGV4Y2VlZCBvciBzdGF5IGJlbG93CisgKiB0aGUgdmFsdWUgdGhhdCB3ZSBhcmUgbG9va2luZyBmb3IuIEluIHRoaXMgY2FzZSwganVzdCBicmVhayBvdXQgb2YKKyAqIHRoZSBsb29wIGlmIHdlIHRvZ2dsZSBiZXR3ZWVuIGluY3JlbWVudGluZyBhbmQgZGVjcmVtZW50aW5nIGZvciBtb3JlCisgKiB0aGFuIHR3aWNlLgorICovCisjZGVmaW5lIElOQ1JFTUVOVF9ET1VCTEUoX3gsIF9kZWNDb3VudCwgX2luY0NvdW50KSBcCisgICAgeyBcCisgICAgICAgICsrRE9VQkxFX1RPX0xPTkdCSVRTKF94KTsgXAorICAgICAgICBfaW5jQ291bnQrKzsgXAorICAgICAgICBpZiggKF9pbmNDb3VudCA+IDIpICYmIChfZGVjQ291bnQgPiAyKSApIHsgXAorICAgICAgICAgICAgaWYoIF9kZWNDb3VudCA+IF9pbmNDb3VudCApIHsgXAorICAgICAgICAgICAgICAgIERPVUJMRV9UT19MT05HQklUUyhfeCkgKz0gX2RlY0NvdW50IC0gX2luY0NvdW50OyBcCisgICAgICAgICAgICB9IGVsc2UgaWYoIF9pbmNDb3VudCA+IF9kZWNDb3VudCApIHsgXAorICAgICAgICAgICAgICAgIERPVUJMRV9UT19MT05HQklUUyhfeCkgLT0gX2luY0NvdW50IC0gX2RlY0NvdW50OyBcCisgICAgICAgICAgICB9IFwKKyAgICAgICAgICAgIGJyZWFrOyBcCisgICAgICAgIH0gXAorICAgIH0KKyNkZWZpbmUgREVDUkVNRU5UX0RPVUJMRShfeCwgX2RlY0NvdW50LCBfaW5jQ291bnQpIFwKKyAgICB7IFwKKyAgICAgICAgLS1ET1VCTEVfVE9fTE9OR0JJVFMoX3gpOyBcCisgICAgICAgIF9kZWNDb3VudCsrOyBcCisgICAgICAgIGlmKCAoX2luY0NvdW50ID4gMikgJiYgKF9kZWNDb3VudCA+IDIpICkgeyBcCisgICAgICAgICAgICBpZiggX2RlY0NvdW50ID4gX2luY0NvdW50ICkgeyBcCisgICAgICAgICAgICAgICAgRE9VQkxFX1RPX0xPTkdCSVRTKF94KSArPSBfZGVjQ291bnQgLSBfaW5jQ291bnQ7IFwKKyAgICAgICAgICAgIH0gZWxzZSBpZiggX2luY0NvdW50ID4gX2RlY0NvdW50ICkgeyBcCisgICAgICAgICAgICAgICAgRE9VQkxFX1RPX0xPTkdCSVRTKF94KSAtPSBfaW5jQ291bnQgLSBfZGVjQ291bnQ7IFwKKyAgICAgICAgICAgIH0gXAorICAgICAgICAgICAgYnJlYWs7IFwKKyAgICAgICAgfSBcCisgICAgfQorCisjZGVmaW5lIGFsbG9jYXRlVTY0KHgsIG4pIGlmICghKCh4KSA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDY0X3QqPihtYWxsb2MoKG4pICogc2l6ZW9mKHVpbnQ2NF90KSkpKSkgZ290byBPdXRPZk1lbW9yeTsKKworLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KKworLyogKioqKioqKioqKioqKioqKioqKioqKioqIGxvY2FsIGRhdGEgKioqKioqKioqKioqKioqKioqKioqKioqICovCitzdGF0aWMgY29uc3QgamRvdWJsZSBkb3VibGVfdGVuc1tdID0geworICAxLjAsCisgIDEuMGUxLAorICAxLjBlMiwKKyAgMS4wZTMsCisgIDEuMGU0LAorICAxLjBlNSwKKyAgMS4wZTYsCisgIDEuMGU3LAorICAxLjBlOCwKKyAgMS4wZTksCisgIDEuMGUxMCwKKyAgMS4wZTExLAorICAxLjBlMTIsCisgIDEuMGUxMywKKyAgMS4wZTE0LAorICAxLjBlMTUsCisgIDEuMGUxNiwKKyAgMS4wZTE3LAorICAxLjBlMTgsCisgIDEuMGUxOSwKKyAgMS4wZTIwLAorICAxLjBlMjEsCisgIDEuMGUyMgorfTsKKy8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCisKKy8qICoqKioqKioqKioqKioqIHByaXZhdGUgZnVuY3Rpb24gZGVjbGFyYXRpb25zICoqKioqKioqKioqKioqICovCitzdGF0aWMgamRvdWJsZSBjcmVhdGVEb3VibGUxICAgKEpOSUVudiogZW52LCB1aW50NjRfdCAqIGYsIGludDMyX3QgbGVuZ3RoLCBqaW50IGUpOworc3RhdGljIGpkb3VibGUgZG91YmxlQWxnb3JpdGhtIChKTklFbnYqIGVudiwgdWludDY0X3QgKiBmLCBpbnQzMl90IGxlbmd0aCwgamludCBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqZG91YmxlIHopOworLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KKworI2RlZmluZSBkb3VibGVUZW5Ub1RoZUUoZSkgKCooZG91YmxlX3RlbnMgKyAoZSkpKQorI2RlZmluZSBET1VCTEVfTE9HNV9PRl9UV09fVE9fVEhFX04gMjMKKworI2RlZmluZSBzaXplT2ZUZW5Ub1RoZUUoZSkgKCgoZSkgLyAxOSkgKyAxKQorCitzdGF0aWMgamRvdWJsZSBjcmVhdGVEb3VibGUoSk5JRW52KiBlbnYsIGNvbnN0IGNoYXIqIHMsIGppbnQgZSkgeworICAvKiBhc3N1bWVzIHMgaXMgYSBudWxsIHRlcm1pbmF0ZWQgc3RyaW5nIHdpdGggYXQgbGVhc3Qgb25lCisgICAqIGNoYXJhY3RlciBpbiBpdCAqLworICB1aW50NjRfdCBkZWZbREVGQVVMVF9ET1VCTEVfV0lEVEhdOworICB1aW50NjRfdCBkZWZCYWNrdXBbREVGQVVMVF9ET1VCTEVfV0lEVEhdOworICB1aW50NjRfdCogZjsKKyAgdWludDY0X3QqIGZOb092ZXJmbG93OworICB1aW50NjRfdCogZzsKKyAgdWludDY0X3QqIHRlbXBCYWNrdXA7CisgIHVpbnQzMl90IG92ZXJmbG93OworICBqZG91YmxlIHJlc3VsdDsKKyAgaW50MzJfdCBpbmRleCA9IDE7CisgIGludCB1bnByb2Nlc3NlZERpZ2l0cyA9IDA7CisKKyAgZiA9IGRlZjsKKyAgZk5vT3ZlcmZsb3cgPSBkZWZCYWNrdXA7CisgICpmID0gMDsKKyAgdGVtcEJhY2t1cCA9IGcgPSAwOworICBkbworICAgIHsKKyAgICAgIGlmICgqcyA+PSAnMCcgJiYgKnMgPD0gJzknKQorICAgICAgICB7CisgICAgICAgICAgLyogTWFrZSBhIGJhY2sgdXAgb2YgZiBiZWZvcmUgYXBwZW5kaW5nLCBzbyB0aGF0IHdlIGNhbgorICAgICAgICAgICAqIGJhY2sgb3V0IG9mIGl0IGlmIHRoZXJlIGlzIG5vIG1vcmUgcm9vbSwgaS5lLiBpbmRleCA+CisgICAgICAgICAgICogTUFYX0RPVUJMRV9BQ0NVUkFDWV9XSURUSC4KKyAgICAgICAgICAgKi8KKyAgICAgICAgICBtZW1jcHkgKGZOb092ZXJmbG93LCBmLCBzaXplb2YgKHVpbnQ2NF90KSAqIGluZGV4KTsKKyAgICAgICAgICBvdmVyZmxvdyA9CisgICAgICAgICAgICBzaW1wbGVBcHBlbmREZWNpbWFsRGlnaXRIaWdoUHJlY2lzaW9uIChmLCBpbmRleCwgKnMgLSAnMCcpOworICAgICAgICAgIGlmIChvdmVyZmxvdykKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgZltpbmRleCsrXSA9IG92ZXJmbG93OworICAgICAgICAgICAgICAvKiBUaGVyZSBpcyBhbiBvdmVyZmxvdywgYnV0IHRoZXJlIGlzIG5vIG1vcmUgcm9vbQorICAgICAgICAgICAgICAgKiB0byBzdG9yZSB0aGUgcmVzdWx0LiBXZSByZWFsbHkgb25seSBuZWVkIHRoZSB0b3AgNTIKKyAgICAgICAgICAgICAgICogYml0cyBhbnl3YXksIHNvIHdlIG11c3QgYmFjayBvdXQgb2YgdGhlIG92ZXJmbG93LAorICAgICAgICAgICAgICAgKiBhbmQgaWdub3JlIHRoZSByZXN0IG9mIHRoZSBzdHJpbmcuCisgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICBpZiAoaW5kZXggPj0gTUFYX0RPVUJMRV9BQ0NVUkFDWV9XSURUSCkKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICBpbmRleC0tOworICAgICAgICAgICAgICAgICAgbWVtY3B5IChmLCBmTm9PdmVyZmxvdywgc2l6ZW9mICh1aW50NjRfdCkgKiBpbmRleCk7CisgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIGlmICh0ZW1wQmFja3VwKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIGZOb092ZXJmbG93ID0gdGVtcEJhY2t1cDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgICAgaW5kZXggPSAtMTsKKyAgICB9CisgIHdoaWxlIChpbmRleCA+IDAgJiYgKigrK3MpICE9ICdcMCcpOworCisgIC8qIFdlJ3ZlIGJyb2tlbiBvdXQgb2YgdGhlIHBhcnNlIGxvb3AgZWl0aGVyIGJlY2F1c2Ugd2UndmUgcmVhY2hlZAorICAgKiB0aGUgZW5kIG9mIHRoZSBzdHJpbmcgb3Igd2UndmUgb3ZlcmZsb3dlZCB0aGUgbWF4aW11bSBhY2N1cmFjeQorICAgKiBsaW1pdCBvZiBhIGRvdWJsZS4gSWYgd2Ugc3RpbGwgaGF2ZSB1bnByb2Nlc3NlZCBkaWdpdHMgaW4gdGhlCisgICAqIGdpdmVuIHN0cmluZywgdGhlbiB0aGVyZSBhcmUgdGhyZWUgcG9zc2libGUgcmVzdWx0czoKKyAgICogICAxLiAodW5wcm9jZXNzZWQgZGlnaXRzICsgZSkgPT0gMCwgaW4gd2hpY2ggY2FzZSB3ZSBzaW1wbHkKKyAgICogICAgICBjb252ZXJ0IHRoZSBleGlzdGluZyBiaXRzIHRoYXQgYXJlIGFscmVhZHkgcGFyc2VkCisgICAqICAgMi4gKHVucHJvY2Vzc2VkIGRpZ2l0cyArIGUpIDwgMCwgaW4gd2hpY2ggY2FzZSB3ZSBzaW1wbHkKKyAgICogICAgICBjb252ZXJ0IHRoZSBleGlzdGluZyBiaXRzIHRoYXQgYXJlIGFscmVhZHkgcGFyc2VkIGFsb25nCisgICAqICAgICAgd2l0aCB0aGUgZ2l2ZW4gZQorICAgKiAgIDMuICh1bnByb2Nlc3NlZCBkaWdpdHMgKyBlKSA+IDAgaW5kaWNhdGVzIHRoYXQgdGhlIHZhbHVlIGlzCisgICAqICAgICAgc2ltcGx5IHRvbyBiaWcgdG8gYmUgc3RvcmVkIGFzIGEgZG91YmxlLCBzbyByZXR1cm4gSW5maW5pdHkKKyAgICovCisgIGlmICgodW5wcm9jZXNzZWREaWdpdHMgPSBzdHJsZW4gKHMpKSA+IDApCisgICAgeworICAgICAgZSArPSB1bnByb2Nlc3NlZERpZ2l0czsKKyAgICAgIGlmIChpbmRleCA+IC0xKQorICAgICAgICB7CisgICAgICAgICAgaWYgKGUgPT0gMCkKKyAgICAgICAgICAgIHJlc3VsdCA9IHRvRG91YmxlSGlnaFByZWNpc2lvbiAoZiwgaW5kZXgpOworICAgICAgICAgIGVsc2UgaWYgKGUgPCAwKQorICAgICAgICAgICAgcmVzdWx0ID0gY3JlYXRlRG91YmxlMSAoZW52LCBmLCBpbmRleCwgZSk7CisgICAgICAgICAgZWxzZQorICAgICAgICAgICAgeworICAgICAgICAgICAgICBET1VCTEVfVE9fTE9OR0JJVFMgKHJlc3VsdCkgPSBET1VCTEVfSU5GSU5JVEVfTE9OR0JJVFM7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgIExPV19JMzJfRlJPTV9WQVIgIChyZXN1bHQpID0gLTE7CisgICAgICAgICAgSElHSF9JMzJfRlJPTV9WQVIgKHJlc3VsdCkgPSAtMTsKKyAgICAgICAgfQorICAgIH0KKyAgZWxzZQorICAgIHsKKyAgICAgIGlmIChpbmRleCA+IC0xKQorICAgICAgICB7CisgICAgICAgICAgaWYgKGUgPT0gMCkKKyAgICAgICAgICAgIHJlc3VsdCA9IHRvRG91YmxlSGlnaFByZWNpc2lvbiAoZiwgaW5kZXgpOworICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJlc3VsdCA9IGNyZWF0ZURvdWJsZTEgKGVudiwgZiwgaW5kZXgsIGUpOworICAgICAgICB9CisgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICBMT1dfSTMyX0ZST01fVkFSICAocmVzdWx0KSA9IC0xOworICAgICAgICAgIEhJR0hfSTMyX0ZST01fVkFSIChyZXN1bHQpID0gLTE7CisgICAgICAgIH0KKyAgICB9CisKKyAgcmV0dXJuIHJlc3VsdDsKKworfQorCitzdGF0aWMgamRvdWJsZSBjcmVhdGVEb3VibGUxKEpOSUVudiogZW52LCB1aW50NjRfdCogZiwgaW50MzJfdCBsZW5ndGgsIGppbnQgZSkgeworICBpbnQzMl90IG51bUJpdHM7CisgIGpkb3VibGUgcmVzdWx0OworCisgIHN0YXRpYyBjb25zdCBqaW50IEFQUFJPWF9NSU5fTUFHTklUVURFID0gLTMwOTsKKyAgc3RhdGljIGNvbnN0IGppbnQgQVBQUk9YX01BWF9NQUdOSVRVREUgPSAzMDk7CisKKyAgbnVtQml0cyA9IGhpZ2hlc3RTZXRCaXRIaWdoUHJlY2lzaW9uIChmLCBsZW5ndGgpICsgMTsKKyAgbnVtQml0cyAtPSBsb3dlc3RTZXRCaXRIaWdoUHJlY2lzaW9uIChmLCBsZW5ndGgpOworICBpZiAobnVtQml0cyA8IDU0ICYmIGUgPj0gMCAmJiBlIDwgRE9VQkxFX0xPRzVfT0ZfVFdPX1RPX1RIRV9OKQorICAgIHsKKyAgICAgIHJldHVybiB0b0RvdWJsZUhpZ2hQcmVjaXNpb24gKGYsIGxlbmd0aCkgKiBkb3VibGVUZW5Ub1RoZUUgKGUpOworICAgIH0KKyAgZWxzZSBpZiAobnVtQml0cyA8IDU0ICYmIGUgPCAwICYmICgtZSkgPCBET1VCTEVfTE9HNV9PRl9UV09fVE9fVEhFX04pCisgICAgeworICAgICAgcmV0dXJuIHRvRG91YmxlSGlnaFByZWNpc2lvbiAoZiwgbGVuZ3RoKSAvIGRvdWJsZVRlblRvVGhlRSAoLWUpOworICAgIH0KKyAgZWxzZSBpZiAoZSA+PSAwICYmIGUgPCBBUFBST1hfTUFYX01BR05JVFVERSkKKyAgICB7CisgICAgICByZXN1bHQgPSB0b0RvdWJsZUhpZ2hQcmVjaXNpb24gKGYsIGxlbmd0aCkgKiBwb3cgKDEwLjAsIGUpOworICAgIH0KKyAgZWxzZSBpZiAoZSA+PSBBUFBST1hfTUFYX01BR05JVFVERSkKKyAgICB7CisgICAgICAvKiBDb252ZXJ0IHRoZSBwYXJ0aWFsIHJlc3VsdCB0byBtYWtlIHN1cmUgdGhhdCB0aGUKKyAgICAgICAqIG5vbi1leHBvbmVudGlhbCBwYXJ0IGlzIG5vdCB6ZXJvLiBUaGlzIGNoZWNrIGZpeGVzIHRoZSBjYXNlCisgICAgICAgKiB3aGVyZSB0aGUgdXNlciBlbnRlcnMgMC4wZTMwOSEgKi8KKyAgICAgIHJlc3VsdCA9IHRvRG91YmxlSGlnaFByZWNpc2lvbiAoZiwgbGVuZ3RoKTsKKyAgICAgIC8qIERvbid0IGdvIHN0cmFpZ2h0IHRvIHplcm8gYXMgdGhlIGZhY3QgdGhhdCB4KjAgPSAwIGluZGVwZW5kZW50IG9mIHggbWlnaHQKKyAgICAgICAgIGNhdXNlIHRoZSBhbGdvcml0aG0gdG8gcHJvZHVjZSBhbiBpbmNvcnJlY3QgcmVzdWx0LiAgSW5zdGVhZCB0cnkgdGhlIG1pbiB2YWx1ZQorICAgICAgICAgZmlyc3QgYW5kIGxldCBpdCBmYWxsIHRvIHplcm8gaWYgbmVlZCBiZS4gKi8KKworICAgICAgaWYgKHJlc3VsdCA9PSAwLjApCisgICAgICAgIHsKKyAgICAgICAgICBET1VCTEVfVE9fTE9OR0JJVFMgKHJlc3VsdCkgPSBET1VCTEVfTUlOSU1VTV9MT05HQklUUzsKKyAgICAgICAgfQorICAgICAgZWxzZQorICAgICAgICB7CisgICAgICAgICAgRE9VQkxFX1RPX0xPTkdCSVRTIChyZXN1bHQpID0gRE9VQkxFX0lORklOSVRFX0xPTkdCSVRTOworICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKyAgICB9CisgIGVsc2UgaWYgKGUgPiBBUFBST1hfTUlOX01BR05JVFVERSkKKyAgICB7CisgICAgICByZXN1bHQgPSB0b0RvdWJsZUhpZ2hQcmVjaXNpb24gKGYsIGxlbmd0aCkgLyBwb3cgKDEwLjAsIC1lKTsKKyAgICB9CisKKyAgaWYgKGUgPD0gQVBQUk9YX01JTl9NQUdOSVRVREUpCisgICAgeworCisgICAgICByZXN1bHQgPSB0b0RvdWJsZUhpZ2hQcmVjaXNpb24gKGYsIGxlbmd0aCkgKiBwb3cgKDEwLjAsIGUgKyA1Mik7CisgICAgICByZXN1bHQgPSByZXN1bHQgKiBwb3cgKDEwLjAsIC01Mik7CisKKyAgICB9CisKKyAgLyogRG9uJ3QgZ28gc3RyYWlnaHQgdG8gemVybyBhcyB0aGUgZmFjdCB0aGF0IHgqMCA9IDAgaW5kZXBlbmRlbnQgb2YgeCBtaWdodAorICAgICBjYXVzZSB0aGUgYWxnb3JpdGhtIHRvIHByb2R1Y2UgYW4gaW5jb3JyZWN0IHJlc3VsdC4gIEluc3RlYWQgdHJ5IHRoZSBtaW4gdmFsdWUKKyAgICAgZmlyc3QgYW5kIGxldCBpdCBmYWxsIHRvIHplcm8gaWYgbmVlZCBiZS4gKi8KKworICBpZiAocmVzdWx0ID09IDAuMCkKKworICAgIERPVUJMRV9UT19MT05HQklUUyAocmVzdWx0KSA9IERPVUJMRV9NSU5JTVVNX0xPTkdCSVRTOworCisgIHJldHVybiBkb3VibGVBbGdvcml0aG0gKGVudiwgZiwgbGVuZ3RoLCBlLCByZXN1bHQpOworfQorCisvKiBUaGUgYWxnb3JpdGhtIGZvciB0aGUgZnVuY3Rpb24gZG91YmxlQWxnb3JpdGhtKCkgYmVsb3cgY2FuIGJlIGZvdW5kCisgKiBpbjoKKyAqCisgKiAgICAgICJIb3cgdG8gUmVhZCBGbG9hdGluZy1Qb2ludCBOdW1iZXJzIEFjY3VyYXRlbHkiLCBXaWxsaWFtIEQuCisgKiAgICAgIENsaW5nZXIsIFByb2NlZWRpbmdzIG9mIHRoZSBBQ00gU0lHUExBTiAnOTAgQ29uZmVyZW5jZSBvbgorICogICAgICBQcm9ncmFtbWluZyBMYW5ndWFnZSBEZXNpZ24gYW5kIEltcGxlbWVudGF0aW9uLCBKdW5lIDIwLTIyLAorICogICAgICAxOTkwLCBwcC4gOTItMTAxLgorICoKKyAqIFRoZXJlIGlzIGEgcG9zc2liaWxpdHkgdGhhdCB0aGUgZnVuY3Rpb24gd2lsbCBlbmQgdXAgaW4gYW4gZW5kbGVzcworICogbG9vcCBpZiB0aGUgZ2l2ZW4gYXBwcm94aW1hdGluZyBmbG9hdGluZy1wb2ludCBudW1iZXIgKGEgdmVyeSBzbWFsbAorICogZmxvYXRpbmctcG9pbnQgd2hvc2UgdmFsdWUgaXMgdmVyeSBjbG9zZSB0byB6ZXJvKSBzdHJhZGRsZXMgYmV0d2VlbgorICogdHdvIGFwcHJveGltYXRpbmcgaW50ZWdlciB2YWx1ZXMuIFdlIG1vZGlmaWVkIHRoZSBhbGdvcml0aG0gc2xpZ2h0bHkKKyAqIHRvIGRldGVjdCB0aGUgY2FzZSB3aGVyZSBpdCBvc2NpbGxhdGVzIGJhY2sgYW5kIGZvcnRoIGJldHdlZW4KKyAqIGluY3JlbWVudGluZyBhbmQgZGVjcmVtZW50aW5nIHRoZSBmbG9hdGluZy1wb2ludCBhcHByb3hpbWF0aW9uLiBJdAorICogaXMgY3VycmVudGx5IHNldCBzdWNoIHRoYXQgaWYgdGhlIG9zY2lsbGF0aW9uIG9jY3VycyBtb3JlIHRoYW4gdHdpY2UKKyAqIHRoZW4gcmV0dXJuIHRoZSBvcmlnaW5hbCBhcHByb3hpbWF0aW9uLgorICovCitzdGF0aWMgamRvdWJsZSBkb3VibGVBbGdvcml0aG0oSk5JRW52KiBlbnYsIHVpbnQ2NF90KiBmLCBpbnQzMl90IGxlbmd0aCwgamludCBlLCBqZG91YmxlIHopIHsKKyAgdWludDY0X3QgbTsKKyAgaW50MzJfdCBrLCBjb21wYXJpc29uLCBjb21wYXJpc29uMjsKKyAgdWludDY0X3QqIHg7CisgIHVpbnQ2NF90KiB5OworICB1aW50NjRfdCogRDsKKyAgdWludDY0X3QqIEQyOworICBpbnQzMl90IHhMZW5ndGgsIHlMZW5ndGgsIERMZW5ndGgsIEQyTGVuZ3RoLCBkZWNBcHByb3hDb3VudCwgaW5jQXBwcm94Q291bnQ7CisKKyAgeCA9IHkgPSBEID0gRDIgPSAwOworICB4TGVuZ3RoID0geUxlbmd0aCA9IERMZW5ndGggPSBEMkxlbmd0aCA9IDA7CisgIGRlY0FwcHJveENvdW50ID0gaW5jQXBwcm94Q291bnQgPSAwOworCisgIGRvCisgICAgeworICAgICAgbSA9IGRvdWJsZU1hbnRpc3NhICh6KTsKKyAgICAgIGsgPSBkb3VibGVFeHBvbmVudCAoeik7CisKKyAgICAgIGlmICh4ICYmIHggIT0gZikKKyAgICAgICAgICBmcmVlKHgpOworCisgICAgICBmcmVlKHkpOworICAgICAgZnJlZShEKTsKKyAgICAgIGZyZWUoRDIpOworCisgICAgICBpZiAoZSA+PSAwICYmIGsgPj0gMCkKKyAgICAgICAgeworICAgICAgICAgIHhMZW5ndGggPSBzaXplT2ZUZW5Ub1RoZUUgKGUpICsgbGVuZ3RoOworICAgICAgICAgIGFsbG9jYXRlVTY0ICh4LCB4TGVuZ3RoKTsKKyAgICAgICAgICBtZW1zZXQgKHggKyBsZW5ndGgsIDAsIHNpemVvZiAodWludDY0X3QpICogKHhMZW5ndGggLSBsZW5ndGgpKTsKKyAgICAgICAgICBtZW1jcHkgKHgsIGYsIHNpemVvZiAodWludDY0X3QpICogbGVuZ3RoKTsKKyAgICAgICAgICB0aW1lc1RlblRvVGhlRUhpZ2hQcmVjaXNpb24gKHgsIHhMZW5ndGgsIGUpOworCisgICAgICAgICAgeUxlbmd0aCA9IChrID4+IDYpICsgMjsKKyAgICAgICAgICBhbGxvY2F0ZVU2NCAoeSwgeUxlbmd0aCk7CisgICAgICAgICAgbWVtc2V0ICh5ICsgMSwgMCwgc2l6ZW9mICh1aW50NjRfdCkgKiAoeUxlbmd0aCAtIDEpKTsKKyAgICAgICAgICAqeSA9IG07CisgICAgICAgICAgc2ltcGxlU2hpZnRMZWZ0SGlnaFByZWNpc2lvbiAoeSwgeUxlbmd0aCwgayk7CisgICAgICAgIH0KKyAgICAgIGVsc2UgaWYgKGUgPj0gMCkKKyAgICAgICAgeworICAgICAgICAgIHhMZW5ndGggPSBzaXplT2ZUZW5Ub1RoZUUgKGUpICsgbGVuZ3RoICsgKCgtaykgPj4gNikgKyAxOworICAgICAgICAgIGFsbG9jYXRlVTY0ICh4LCB4TGVuZ3RoKTsKKyAgICAgICAgICBtZW1zZXQgKHggKyBsZW5ndGgsIDAsIHNpemVvZiAodWludDY0X3QpICogKHhMZW5ndGggLSBsZW5ndGgpKTsKKyAgICAgICAgICBtZW1jcHkgKHgsIGYsIHNpemVvZiAodWludDY0X3QpICogbGVuZ3RoKTsKKyAgICAgICAgICB0aW1lc1RlblRvVGhlRUhpZ2hQcmVjaXNpb24gKHgsIHhMZW5ndGgsIGUpOworICAgICAgICAgIHNpbXBsZVNoaWZ0TGVmdEhpZ2hQcmVjaXNpb24gKHgsIHhMZW5ndGgsIC1rKTsKKworICAgICAgICAgIHlMZW5ndGggPSAxOworICAgICAgICAgIGFsbG9jYXRlVTY0ICh5LCAxKTsKKyAgICAgICAgICAqeSA9IG07CisgICAgICAgIH0KKyAgICAgIGVsc2UgaWYgKGsgPj0gMCkKKyAgICAgICAgeworICAgICAgICAgIHhMZW5ndGggPSBsZW5ndGg7CisgICAgICAgICAgeCA9IGY7CisKKyAgICAgICAgICB5TGVuZ3RoID0gc2l6ZU9mVGVuVG9UaGVFICgtZSkgKyAyICsgKGsgPj4gNik7CisgICAgICAgICAgYWxsb2NhdGVVNjQgKHksIHlMZW5ndGgpOworICAgICAgICAgIG1lbXNldCAoeSArIDEsIDAsIHNpemVvZiAodWludDY0X3QpICogKHlMZW5ndGggLSAxKSk7CisgICAgICAgICAgKnkgPSBtOworICAgICAgICAgIHRpbWVzVGVuVG9UaGVFSGlnaFByZWNpc2lvbiAoeSwgeUxlbmd0aCwgLWUpOworICAgICAgICAgIHNpbXBsZVNoaWZ0TGVmdEhpZ2hQcmVjaXNpb24gKHksIHlMZW5ndGgsIGspOworICAgICAgICB9CisgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICB4TGVuZ3RoID0gbGVuZ3RoICsgKCgtaykgPj4gNikgKyAxOworICAgICAgICAgIGFsbG9jYXRlVTY0ICh4LCB4TGVuZ3RoKTsKKyAgICAgICAgICBtZW1zZXQgKHggKyBsZW5ndGgsIDAsIHNpemVvZiAodWludDY0X3QpICogKHhMZW5ndGggLSBsZW5ndGgpKTsKKyAgICAgICAgICBtZW1jcHkgKHgsIGYsIHNpemVvZiAodWludDY0X3QpICogbGVuZ3RoKTsKKyAgICAgICAgICBzaW1wbGVTaGlmdExlZnRIaWdoUHJlY2lzaW9uICh4LCB4TGVuZ3RoLCAtayk7CisKKyAgICAgICAgICB5TGVuZ3RoID0gc2l6ZU9mVGVuVG9UaGVFICgtZSkgKyAxOworICAgICAgICAgIGFsbG9jYXRlVTY0ICh5LCB5TGVuZ3RoKTsKKyAgICAgICAgICBtZW1zZXQgKHkgKyAxLCAwLCBzaXplb2YgKHVpbnQ2NF90KSAqICh5TGVuZ3RoIC0gMSkpOworICAgICAgICAgICp5ID0gbTsKKyAgICAgICAgICB0aW1lc1RlblRvVGhlRUhpZ2hQcmVjaXNpb24gKHksIHlMZW5ndGgsIC1lKTsKKyAgICAgICAgfQorCisgICAgICBjb21wYXJpc29uID0gY29tcGFyZUhpZ2hQcmVjaXNpb24gKHgsIHhMZW5ndGgsIHksIHlMZW5ndGgpOworICAgICAgaWYgKGNvbXBhcmlzb24gPiAwKQorICAgICAgICB7ICAgICAgICAgICAgICAgICAgICAgICAvKiB4ID4geSAqLworICAgICAgICAgIERMZW5ndGggPSB4TGVuZ3RoOworICAgICAgICAgIGFsbG9jYXRlVTY0IChELCBETGVuZ3RoKTsKKyAgICAgICAgICBtZW1jcHkgKEQsIHgsIERMZW5ndGggKiBzaXplb2YgKHVpbnQ2NF90KSk7CisgICAgICAgICAgc3VidHJhY3RIaWdoUHJlY2lzaW9uIChELCBETGVuZ3RoLCB5LCB5TGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgZWxzZSBpZiAoY29tcGFyaXNvbikKKyAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgLyogeSA+IHggKi8KKyAgICAgICAgICBETGVuZ3RoID0geUxlbmd0aDsKKyAgICAgICAgICBhbGxvY2F0ZVU2NCAoRCwgRExlbmd0aCk7CisgICAgICAgICAgbWVtY3B5IChELCB5LCBETGVuZ3RoICogc2l6ZW9mICh1aW50NjRfdCkpOworICAgICAgICAgIHN1YnRyYWN0SGlnaFByZWNpc2lvbiAoRCwgRExlbmd0aCwgeCwgeExlbmd0aCk7CisgICAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgLyogeSA9PSB4ICovCisgICAgICAgICAgRExlbmd0aCA9IDE7CisgICAgICAgICAgYWxsb2NhdGVVNjQgKEQsIDEpOworICAgICAgICAgICpEID0gMDsKKyAgICAgICAgfQorCisgICAgICBEMkxlbmd0aCA9IERMZW5ndGggKyAxOworICAgICAgYWxsb2NhdGVVNjQgKEQyLCBEMkxlbmd0aCk7CisgICAgICBtIDw8PSAxOworICAgICAgbXVsdGlwbHlIaWdoUHJlY2lzaW9uIChELCBETGVuZ3RoLCAmbSwgMSwgRDIsIEQyTGVuZ3RoKTsKKyAgICAgIG0gPj49IDE7CisKKyAgICAgIGNvbXBhcmlzb24yID0gY29tcGFyZUhpZ2hQcmVjaXNpb24gKEQyLCBEMkxlbmd0aCwgeSwgeUxlbmd0aCk7CisgICAgICBpZiAoY29tcGFyaXNvbjIgPCAwKQorICAgICAgICB7CisgICAgICAgICAgaWYgKGNvbXBhcmlzb24gPCAwICYmIG0gPT0gRE9VQkxFX05PUk1BTF9NQVNLKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICBzaW1wbGVTaGlmdExlZnRIaWdoUHJlY2lzaW9uIChEMiwgRDJMZW5ndGgsIDEpOworICAgICAgICAgICAgICBpZiAoY29tcGFyZUhpZ2hQcmVjaXNpb24gKEQyLCBEMkxlbmd0aCwgeSwgeUxlbmd0aCkgPiAwKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIERFQ1JFTUVOVF9ET1VCTEUgKHosIGRlY0FwcHJveENvdW50LCBpbmNBcHByb3hDb3VudCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIGVsc2UgaWYgKGNvbXBhcmlzb24yID09IDApCisgICAgICAgIHsKKyAgICAgICAgICBpZiAoKExPV19VMzJfRlJPTV9WQVIgKG0pICYgMSkgPT0gMCkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgaWYgKGNvbXBhcmlzb24gPCAwICYmIG0gPT0gRE9VQkxFX05PUk1BTF9NQVNLKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIERFQ1JFTUVOVF9ET1VCTEUgKHosIGRlY0FwcHJveENvdW50LCBpbmNBcHByb3hDb3VudCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgIGVsc2UgaWYgKGNvbXBhcmlzb24gPCAwKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICBERUNSRU1FTlRfRE9VQkxFICh6LCBkZWNBcHByb3hDb3VudCwgaW5jQXBwcm94Q291bnQpOworICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICBlbHNlCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgIElOQ1JFTUVOVF9ET1VCTEUgKHosIGRlY0FwcHJveENvdW50LCBpbmNBcHByb3hDb3VudCk7CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICBlbHNlIGlmIChjb21wYXJpc29uIDwgMCkKKyAgICAgICAgeworICAgICAgICAgIERFQ1JFTUVOVF9ET1VCTEUgKHosIGRlY0FwcHJveENvdW50LCBpbmNBcHByb3hDb3VudCk7CisgICAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgIGlmIChET1VCTEVfVE9fTE9OR0JJVFMgKHopID09IERPVUJMRV9JTkZJTklURV9MT05HQklUUykKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIElOQ1JFTUVOVF9ET1VCTEUgKHosIGRlY0FwcHJveENvdW50LCBpbmNBcHByb3hDb3VudCk7CisgICAgICAgIH0KKyAgICB9CisgIHdoaWxlICgxKTsKKworICBpZiAoeCAmJiB4ICE9IGYpCisgICAgIGZyZWUoeCk7CisgIGZyZWUoeSk7CisgIGZyZWUoRCk7CisgIGZyZWUoRDIpOworICByZXR1cm4gejsKKworT3V0T2ZNZW1vcnk6CisgIGlmICh4ICYmIHggIT0gZikKKyAgICAgIGZyZWUoeCk7CisgIGZyZWUoeSk7CisgIGZyZWUoRCk7CisgIGZyZWUoRDIpOworICBqbmlUaHJvd091dE9mTWVtb3J5RXJyb3IoZW52LCBOVUxMKTsKKyAgcmV0dXJuIHo7Cit9CisKKworCisjZGVmaW5lIE1BWF9GTE9BVF9BQ0NVUkFDWV9XSURUSCA4CisKKyNkZWZpbmUgREVGQVVMVF9GTE9BVF9XSURUSCBNQVhfRkxPQVRfQUNDVVJBQ1lfV0lEVEgKKworc3RhdGljIGpmbG9hdCBjcmVhdGVGbG9hdDEoSk5JRW52KiBlbnYsIHVpbnQ2NF90KiBmLCBpbnQzMl90IGxlbmd0aCwgamludCBlKTsKK3N0YXRpYyBqZmxvYXQgZmxvYXRBbGdvcml0aG0oSk5JRW52KiBlbnYsIHVpbnQ2NF90KiBmLCBpbnQzMl90IGxlbmd0aCwgamludCBlLCBqZmxvYXQgeik7CisKK3N0YXRpYyBjb25zdCB1aW50MzJfdCBmbG9hdF90ZW5zW10gPSB7CisgIDB4M2Y4MDAwMDAsCisgIDB4NDEyMDAwMDAsCisgIDB4NDJjODAwMDAsCisgIDB4NDQ3YTAwMDAsCisgIDB4NDYxYzQwMDAsCisgIDB4NDdjMzUwMDAsCisgIDB4NDk3NDI0MDAsCisgIDB4NGIxODk2ODAsCisgIDB4NGNiZWJjMjAsCisgIDB4NGU2ZTZiMjgsCisgIDB4NTAxNTAyZjkgICAgICAgICAgICAgICAgICAgIC8qIDEwIF4gMTAgaW4gZmxvYXQgKi8KK307CisKKyNkZWZpbmUgZmxvYXRUZW5Ub1RoZUUoZSkgKCpyZWludGVycHJldF9jYXN0PGNvbnN0IGpmbG9hdCo+KGZsb2F0X3RlbnMgKyAoZSkpKQorI2RlZmluZSBGTE9BVF9MT0c1X09GX1RXT19UT19USEVfTiAxMQorCisjZGVmaW5lIEZMT0FUX0lORklOSVRFX0lOVEJJVFMgKDB4N0Y4MDAwMDApCisjZGVmaW5lIEZMT0FUX01JTklNVU1fSU5UQklUUyAoMSkKKworI2RlZmluZSBGTE9BVF9NQU5USVNTQV9NQVNLICgweDAwN0ZGRkZGKQorI2RlZmluZSBGTE9BVF9FWFBPTkVOVF9NQVNLICgweDdGODAwMDAwKQorI2RlZmluZSBGTE9BVF9OT1JNQUxfTUFTSyAgICgweDAwODAwMDAwKQorCisvKiBLZWVwIGEgY291bnQgb2YgdGhlIG51bWJlciBvZiB0aW1lcyB3ZSBkZWNyZW1lbnQgYW5kIGluY3JlbWVudCB0bworICogYXBwcm94aW1hdGUgdGhlIGRvdWJsZSwgYW5kIGF0dGVtcHQgdG8gZGV0ZWN0IHRoZSBjYXNlIHdoZXJlIHdlCisgKiBjb3VsZCBwb3RlbnRpYWxseSB0b2dnbGUgYmFjayBhbmQgZm9ydGggYmV0d2VlbiBkZWNyZW1lbnRpbmcgYW5kCisgKiBpbmNyZW1lbnRpbmcuIEl0IGlzIHBvc3NpYmxlIGZvciB1cyB0byBiZSBzdHVjayBpbiB0aGUgbG9vcCB3aGVuCisgKiBpbmNyZW1lbnRpbmcgYnkgb25lIG9yIGRlY3JlbWVudGluZyBieSBvbmUgbWF5IGV4Y2VlZCBvciBzdGF5IGJlbG93CisgKiB0aGUgdmFsdWUgdGhhdCB3ZSBhcmUgbG9va2luZyBmb3IuIEluIHRoaXMgY2FzZSwganVzdCBicmVhayBvdXQgb2YKKyAqIHRoZSBsb29wIGlmIHdlIHRvZ2dsZSBiZXR3ZWVuIGluY3JlbWVudGluZyBhbmQgZGVjcmVtZW50aW5nIGZvciBtb3JlCisgKiB0aGFuIHR3aWNlLgorICovCisjZGVmaW5lIElOQ1JFTUVOVF9GTE9BVChfeCwgX2RlY0NvdW50LCBfaW5jQ291bnQpIFwKKyAgICB7IFwKKyAgICAgICAgKytGTE9BVF9UT19JTlRCSVRTKF94KTsgXAorICAgICAgICBfaW5jQ291bnQrKzsgXAorICAgICAgICBpZiggKF9pbmNDb3VudCA+IDIpICYmIChfZGVjQ291bnQgPiAyKSApIHsgXAorICAgICAgICAgICAgaWYoIF9kZWNDb3VudCA+IF9pbmNDb3VudCApIHsgXAorICAgICAgICAgICAgICAgIEZMT0FUX1RPX0lOVEJJVFMoX3gpICs9IF9kZWNDb3VudCAtIF9pbmNDb3VudDsgXAorICAgICAgICAgICAgfSBlbHNlIGlmKCBfaW5jQ291bnQgPiBfZGVjQ291bnQgKSB7IFwKKyAgICAgICAgICAgICAgICBGTE9BVF9UT19JTlRCSVRTKF94KSAtPSBfaW5jQ291bnQgLSBfZGVjQ291bnQ7IFwKKyAgICAgICAgICAgIH0gXAorICAgICAgICAgICAgYnJlYWs7IFwKKyAgICAgICAgfSBcCisgICAgfQorI2RlZmluZSBERUNSRU1FTlRfRkxPQVQoX3gsIF9kZWNDb3VudCwgX2luY0NvdW50KSBcCisgICAgeyBcCisgICAgICAgIC0tRkxPQVRfVE9fSU5UQklUUyhfeCk7IFwKKyAgICAgICAgX2RlY0NvdW50Kys7IFwKKyAgICAgICAgaWYoIChfaW5jQ291bnQgPiAyKSAmJiAoX2RlY0NvdW50ID4gMikgKSB7IFwKKyAgICAgICAgICAgIGlmKCBfZGVjQ291bnQgPiBfaW5jQ291bnQgKSB7IFwKKyAgICAgICAgICAgICAgICBGTE9BVF9UT19JTlRCSVRTKF94KSArPSBfZGVjQ291bnQgLSBfaW5jQ291bnQ7IFwKKyAgICAgICAgICAgIH0gZWxzZSBpZiggX2luY0NvdW50ID4gX2RlY0NvdW50ICkgeyBcCisgICAgICAgICAgICAgICAgRkxPQVRfVE9fSU5UQklUUyhfeCkgLT0gX2luY0NvdW50IC0gX2RlY0NvdW50OyBcCisgICAgICAgICAgICB9IFwKKyAgICAgICAgICAgIGJyZWFrOyBcCisgICAgICAgIH0gXAorICAgIH0KKworc3RhdGljIGpmbG9hdCBjcmVhdGVGbG9hdChKTklFbnYqIGVudiwgY29uc3QgY2hhciogcywgamludCBlKSB7CisgIC8qIGFzc3VtZXMgcyBpcyBhIG51bGwgdGVybWluYXRlZCBzdHJpbmcgd2l0aCBhdCBsZWFzdCBvbmUKKyAgICogY2hhcmFjdGVyIGluIGl0ICovCisgIHVpbnQ2NF90IGRlZltERUZBVUxUX0ZMT0FUX1dJRFRIXTsKKyAgdWludDY0X3QgZGVmQmFja3VwW0RFRkFVTFRfRkxPQVRfV0lEVEhdOworICB1aW50NjRfdCogZjsKKyAgdWludDY0X3QqIGZOb092ZXJmbG93OworICB1aW50NjRfdCogZzsKKyAgdWludDY0X3QqIHRlbXBCYWNrdXA7CisgIHVpbnQzMl90IG92ZXJmbG93OworICBqZmxvYXQgcmVzdWx0OworICBpbnQzMl90IGluZGV4ID0gMTsKKyAgaW50IHVucHJvY2Vzc2VkRGlnaXRzID0gMDsKKworICBmID0gZGVmOworICBmTm9PdmVyZmxvdyA9IGRlZkJhY2t1cDsKKyAgKmYgPSAwOworICB0ZW1wQmFja3VwID0gZyA9IDA7CisgIGRvCisgICAgeworICAgICAgaWYgKCpzID49ICcwJyAmJiAqcyA8PSAnOScpCisgICAgICAgIHsKKyAgICAgICAgICAvKiBNYWtlIGEgYmFjayB1cCBvZiBmIGJlZm9yZSBhcHBlbmRpbmcsIHNvIHRoYXQgd2UgY2FuCisgICAgICAgICAgICogYmFjayBvdXQgb2YgaXQgaWYgdGhlcmUgaXMgbm8gbW9yZSByb29tLCBpLmUuIGluZGV4ID4KKyAgICAgICAgICAgKiBNQVhfRkxPQVRfQUNDVVJBQ1lfV0lEVEguCisgICAgICAgICAgICovCisgICAgICAgICAgbWVtY3B5IChmTm9PdmVyZmxvdywgZiwgc2l6ZW9mICh1aW50NjRfdCkgKiBpbmRleCk7CisgICAgICAgICAgb3ZlcmZsb3cgPQorICAgICAgICAgICAgc2ltcGxlQXBwZW5kRGVjaW1hbERpZ2l0SGlnaFByZWNpc2lvbiAoZiwgaW5kZXgsICpzIC0gJzAnKTsKKyAgICAgICAgICBpZiAob3ZlcmZsb3cpCisgICAgICAgICAgICB7CisKKyAgICAgICAgICAgICAgZltpbmRleCsrXSA9IG92ZXJmbG93OworICAgICAgICAgICAgICAvKiBUaGVyZSBpcyBhbiBvdmVyZmxvdywgYnV0IHRoZXJlIGlzIG5vIG1vcmUgcm9vbQorICAgICAgICAgICAgICAgKiB0byBzdG9yZSB0aGUgcmVzdWx0LiBXZSByZWFsbHkgb25seSBuZWVkIHRoZSB0b3AgNTIKKyAgICAgICAgICAgICAgICogYml0cyBhbnl3YXksIHNvIHdlIG11c3QgYmFjayBvdXQgb2YgdGhlIG92ZXJmbG93LAorICAgICAgICAgICAgICAgKiBhbmQgaWdub3JlIHRoZSByZXN0IG9mIHRoZSBzdHJpbmcuCisgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICBpZiAoaW5kZXggPj0gTUFYX0ZMT0FUX0FDQ1VSQUNZX1dJRFRIKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIGluZGV4LS07CisgICAgICAgICAgICAgICAgICBtZW1jcHkgKGYsIGZOb092ZXJmbG93LCBzaXplb2YgKHVpbnQ2NF90KSAqIGluZGV4KTsKKyAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgaWYgKHRlbXBCYWNrdXApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgZk5vT3ZlcmZsb3cgPSB0ZW1wQmFja3VwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgZWxzZQorICAgICAgICBpbmRleCA9IC0xOworICAgIH0KKyAgd2hpbGUgKGluZGV4ID4gMCAmJiAqKCsrcykgIT0gJ1wwJyk7CisKKyAgLyogV2UndmUgYnJva2VuIG91dCBvZiB0aGUgcGFyc2UgbG9vcCBlaXRoZXIgYmVjYXVzZSB3ZSd2ZSByZWFjaGVkCisgICAqIHRoZSBlbmQgb2YgdGhlIHN0cmluZyBvciB3ZSd2ZSBvdmVyZmxvd2VkIHRoZSBtYXhpbXVtIGFjY3VyYWN5CisgICAqIGxpbWl0IG9mIGEgZG91YmxlLiBJZiB3ZSBzdGlsbCBoYXZlIHVucHJvY2Vzc2VkIGRpZ2l0cyBpbiB0aGUKKyAgICogZ2l2ZW4gc3RyaW5nLCB0aGVuIHRoZXJlIGFyZSB0aHJlZSBwb3NzaWJsZSByZXN1bHRzOgorICAgKiAgIDEuICh1bnByb2Nlc3NlZCBkaWdpdHMgKyBlKSA9PSAwLCBpbiB3aGljaCBjYXNlIHdlIHNpbXBseQorICAgKiAgICAgIGNvbnZlcnQgdGhlIGV4aXN0aW5nIGJpdHMgdGhhdCBhcmUgYWxyZWFkeSBwYXJzZWQKKyAgICogICAyLiAodW5wcm9jZXNzZWQgZGlnaXRzICsgZSkgPCAwLCBpbiB3aGljaCBjYXNlIHdlIHNpbXBseQorICAgKiAgICAgIGNvbnZlcnQgdGhlIGV4aXN0aW5nIGJpdHMgdGhhdCBhcmUgYWxyZWFkeSBwYXJzZWQgYWxvbmcKKyAgICogICAgICB3aXRoIHRoZSBnaXZlbiBlCisgICAqICAgMy4gKHVucHJvY2Vzc2VkIGRpZ2l0cyArIGUpID4gMCBpbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgaXMKKyAgICogICAgICBzaW1wbHkgdG9vIGJpZyB0byBiZSBzdG9yZWQgYXMgYSBkb3VibGUsIHNvIHJldHVybiBJbmZpbml0eQorICAgKi8KKyAgaWYgKCh1bnByb2Nlc3NlZERpZ2l0cyA9IHN0cmxlbiAocykpID4gMCkKKyAgICB7CisgICAgICBlICs9IHVucHJvY2Vzc2VkRGlnaXRzOworICAgICAgaWYgKGluZGV4ID4gLTEpCisgICAgICAgIHsKKyAgICAgICAgICBpZiAoZSA8PSAwKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICByZXN1bHQgPSBjcmVhdGVGbG9hdDEgKGVudiwgZiwgaW5kZXgsIGUpOworICAgICAgICAgICAgfQorICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgRkxPQVRfVE9fSU5UQklUUyAocmVzdWx0KSA9IEZMT0FUX0lORklOSVRFX0lOVEJJVFM7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgIHJlc3VsdCA9IElOVEJJVFNfVE9fRkxPQVQoaW5kZXgpOworICAgICAgICB9CisgICAgfQorICBlbHNlCisgICAgeworICAgICAgaWYgKGluZGV4ID4gLTEpCisgICAgICAgIHsKKyAgICAgICAgICByZXN1bHQgPSBjcmVhdGVGbG9hdDEgKGVudiwgZiwgaW5kZXgsIGUpOworICAgICAgICB9CisgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICByZXN1bHQgPSBJTlRCSVRTX1RPX0ZMT0FUKGluZGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICByZXR1cm4gcmVzdWx0OworCit9CisKK3N0YXRpYyBqZmxvYXQgY3JlYXRlRmxvYXQxIChKTklFbnYqIGVudiwgdWludDY0X3QqIGYsIGludDMyX3QgbGVuZ3RoLCBqaW50IGUpIHsKKyAgaW50MzJfdCBudW1CaXRzOworICBqZG91YmxlIGRyZXN1bHQ7CisgIGpmbG9hdCByZXN1bHQ7CisKKyAgbnVtQml0cyA9IGhpZ2hlc3RTZXRCaXRIaWdoUHJlY2lzaW9uIChmLCBsZW5ndGgpICsgMTsKKyAgaWYgKG51bUJpdHMgPCAyNSAmJiBlID49IDAgJiYgZSA8IEZMT0FUX0xPRzVfT0ZfVFdPX1RPX1RIRV9OKQorICAgIHsKKyAgICAgIHJldHVybiAoKGpmbG9hdCkgTE9XX0kzMl9GUk9NX1BUUiAoZikpICogZmxvYXRUZW5Ub1RoZUUgKGUpOworICAgIH0KKyAgZWxzZSBpZiAobnVtQml0cyA8IDI1ICYmIGUgPCAwICYmICgtZSkgPCBGTE9BVF9MT0c1X09GX1RXT19UT19USEVfTikKKyAgICB7CisgICAgICByZXR1cm4gKChqZmxvYXQpIExPV19JMzJfRlJPTV9QVFIgKGYpKSAvIGZsb2F0VGVuVG9UaGVFICgtZSk7CisgICAgfQorICBlbHNlIGlmIChlID49IDAgJiYgZSA8IDM5KQorICAgIHsKKyAgICAgIHJlc3VsdCA9IChqZmxvYXQpICh0b0RvdWJsZUhpZ2hQcmVjaXNpb24gKGYsIGxlbmd0aCkgKiBwb3cgKDEwLjAsIChkb3VibGUpIGUpKTsKKyAgICB9CisgIGVsc2UgaWYgKGUgPj0gMzkpCisgICAgeworICAgICAgLyogQ29udmVydCB0aGUgcGFydGlhbCByZXN1bHQgdG8gbWFrZSBzdXJlIHRoYXQgdGhlCisgICAgICAgKiBub24tZXhwb25lbnRpYWwgcGFydCBpcyBub3QgemVyby4gVGhpcyBjaGVjayBmaXhlcyB0aGUgY2FzZQorICAgICAgICogd2hlcmUgdGhlIHVzZXIgZW50ZXJzIDAuMGUzMDkhICovCisgICAgICByZXN1bHQgPSAoamZsb2F0KSB0b0RvdWJsZUhpZ2hQcmVjaXNpb24gKGYsIGxlbmd0aCk7CisKKyAgICAgIGlmIChyZXN1bHQgPT0gMC4wKQorCisgICAgICAgIEZMT0FUX1RPX0lOVEJJVFMgKHJlc3VsdCkgPSBGTE9BVF9NSU5JTVVNX0lOVEJJVFM7CisgICAgICBlbHNlCisgICAgICAgIEZMT0FUX1RPX0lOVEJJVFMgKHJlc3VsdCkgPSBGTE9BVF9JTkZJTklURV9JTlRCSVRTOworICAgIH0KKyAgZWxzZSBpZiAoZSA+IC0zMDkpCisgICAgeworICAgICAgaW50IGRleHA7CisgICAgICB1aW50MzJfdCBmbWFudCwgZm92Zmw7CisgICAgICB1aW50NjRfdCBkbWFudDsKKyAgICAgIGRyZXN1bHQgPSB0b0RvdWJsZUhpZ2hQcmVjaXNpb24gKGYsIGxlbmd0aCkgLyBwb3cgKDEwLjAsIChkb3VibGUpIC1lKTsKKyAgICAgIGlmIChJU19ERU5PUk1BTF9EQkwgKGRyZXN1bHQpKQorICAgICAgICB7CisgICAgICAgICAgRkxPQVRfVE9fSU5UQklUUyAocmVzdWx0KSA9IDA7CisgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgICAgZGV4cCA9IGRvdWJsZUV4cG9uZW50IChkcmVzdWx0KSArIDUxOworICAgICAgZG1hbnQgPSBkb3VibGVNYW50aXNzYSAoZHJlc3VsdCk7CisgICAgICAvKiBJcyBpdCB0b28gc21hbGwgdG8gYmUgcmVwcmVzZW50ZWQgYnkgYSBzaW5nbGUtcHJlY2lzaW9uCisgICAgICAgKiBmbG9hdD8gKi8KKyAgICAgIGlmIChkZXhwIDw9IC0xNTUpCisgICAgICAgIHsKKyAgICAgICAgICBGTE9BVF9UT19JTlRCSVRTIChyZXN1bHQpID0gMDsKKyAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgICAvKiBJcyBpdCBhIGRlbm9ybWFsaXplZCBzaW5nbGUtcHJlY2lzaW9uIGZsb2F0PyAqLworICAgICAgaWYgKChkZXhwIDw9IC0xMjcpICYmIChkZXhwID4gLTE1NSkpCisgICAgICAgIHsKKyAgICAgICAgICAvKiBPbmx5IGludGVyZXN0ZWQgaW4gMjQgbXNiIGJpdHMgb2YgdGhlIDUzLWJpdCBkb3VibGUgbWFudGlzc2EgKi8KKyAgICAgICAgICBmbWFudCA9ICh1aW50MzJfdCkgKGRtYW50ID4+IDI5KTsKKyAgICAgICAgICBmb3ZmbCA9ICgodWludDMyX3QpIChkbWFudCAmIDB4MUZGRkZGRkYpKSA8PCAzOworICAgICAgICAgIHdoaWxlICgoZGV4cCA8IC0xMjcpICYmICgoZm1hbnQgfCBmb3ZmbCkgIT0gMCkpCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgIGlmICgoZm1hbnQgJiAxKSAhPSAwKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIGZvdmZsIHw9IDB4ODAwMDAwMDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICBmb3ZmbCA+Pj0gMTsKKyAgICAgICAgICAgICAgZm1hbnQgPj49IDE7CisgICAgICAgICAgICAgIGRleHArKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICBpZiAoKGZvdmZsICYgMHg4MDAwMDAwMCkgIT0gMCkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgaWYgKChmb3ZmbCAmIDB4N0ZGRkZGRkMpICE9IDApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgZm1hbnQrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIGVsc2UgaWYgKChmbWFudCAmIDEpICE9IDApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgZm1hbnQrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgZWxzZSBpZiAoKGZvdmZsICYgMHg0MDAwMDAwMCkgIT0gMCkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgaWYgKChmb3ZmbCAmIDB4M0ZGRkZGRkMpICE9IDApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgZm1hbnQrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgRkxPQVRfVE9fSU5UQklUUyAocmVzdWx0KSA9IGZtYW50OworICAgICAgICB9CisgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICByZXN1bHQgPSAoamZsb2F0KSBkcmVzdWx0OworICAgICAgICB9CisgICAgfQorCisgIC8qIERvbid0IGdvIHN0cmFpZ2h0IHRvIHplcm8gYXMgdGhlIGZhY3QgdGhhdCB4KjAgPSAwIGluZGVwZW5kZW50CisgICAqIG9mIHggbWlnaHQgY2F1c2UgdGhlIGFsZ29yaXRobSB0byBwcm9kdWNlIGFuIGluY29ycmVjdCByZXN1bHQuCisgICAqIEluc3RlYWQgdHJ5IHRoZSBtaW4gIHZhbHVlIGZpcnN0IGFuZCBsZXQgaXQgZmFsbCB0byB6ZXJvIGlmIG5lZWQKKyAgICogYmUuCisgICAqLworICBpZiAoZSA8PSAtMzA5IHx8IEZMT0FUX1RPX0lOVEJJVFMgKHJlc3VsdCkgPT0gMCkKKyAgICBGTE9BVF9UT19JTlRCSVRTIChyZXN1bHQpID0gRkxPQVRfTUlOSU1VTV9JTlRCSVRTOworCisgIHJldHVybiBmbG9hdEFsZ29yaXRobSAoZW52LCBmLCBsZW5ndGgsIGUsIChqZmxvYXQpIHJlc3VsdCk7Cit9CisKKy8qIFRoZSBhbGdvcml0aG0gZm9yIHRoZSBmdW5jdGlvbiBmbG9hdEFsZ29yaXRobSgpIGJlbG93IGNhbiBiZSBmb3VuZAorICogaW46CisgKgorICogICAgICAiSG93IHRvIFJlYWQgRmxvYXRpbmctUG9pbnQgTnVtYmVycyBBY2N1cmF0ZWx5IiwgV2lsbGlhbSBELgorICogICAgICBDbGluZ2VyLCBQcm9jZWVkaW5ncyBvZiB0aGUgQUNNIFNJR1BMQU4gJzkwIENvbmZlcmVuY2Ugb24KKyAqICAgICAgUHJvZ3JhbW1pbmcgTGFuZ3VhZ2UgRGVzaWduIGFuZCBJbXBsZW1lbnRhdGlvbiwgSnVuZSAyMC0yMiwKKyAqICAgICAgMTk5MCwgcHAuIDkyLTEwMS4KKyAqCisgKiBUaGVyZSBpcyBhIHBvc3NpYmlsaXR5IHRoYXQgdGhlIGZ1bmN0aW9uIHdpbGwgZW5kIHVwIGluIGFuIGVuZGxlc3MKKyAqIGxvb3AgaWYgdGhlIGdpdmVuIGFwcHJveGltYXRpbmcgZmxvYXRpbmctcG9pbnQgbnVtYmVyIChhIHZlcnkgc21hbGwKKyAqIGZsb2F0aW5nLXBvaW50IHdob3NlIHZhbHVlIGlzIHZlcnkgY2xvc2UgdG8gemVybykgc3RyYWRkbGVzIGJldHdlZW4KKyAqIHR3byBhcHByb3hpbWF0aW5nIGludGVnZXIgdmFsdWVzLiBXZSBtb2RpZmllZCB0aGUgYWxnb3JpdGhtIHNsaWdodGx5CisgKiB0byBkZXRlY3QgdGhlIGNhc2Ugd2hlcmUgaXQgb3NjaWxsYXRlcyBiYWNrIGFuZCBmb3J0aCBiZXR3ZWVuCisgKiBpbmNyZW1lbnRpbmcgYW5kIGRlY3JlbWVudGluZyB0aGUgZmxvYXRpbmctcG9pbnQgYXBwcm94aW1hdGlvbi4gSXQKKyAqIGlzIGN1cnJlbnRseSBzZXQgc3VjaCB0aGF0IGlmIHRoZSBvc2NpbGxhdGlvbiBvY2N1cnMgbW9yZSB0aGFuIHR3aWNlCisgKiB0aGVuIHJldHVybiB0aGUgb3JpZ2luYWwgYXBwcm94aW1hdGlvbi4KKyAqLworc3RhdGljIGpmbG9hdCBmbG9hdEFsZ29yaXRobShKTklFbnYqIGVudiwgdWludDY0X3QqIGYsIGludDMyX3QgbGVuZ3RoLCBqaW50IGUsIGpmbG9hdCB6KSB7CisgIHVpbnQ2NF90IG07CisgIGludDMyX3QgaywgY29tcGFyaXNvbiwgY29tcGFyaXNvbjI7CisgIHVpbnQ2NF90KiB4OworICB1aW50NjRfdCogeTsKKyAgdWludDY0X3QqIEQ7CisgIHVpbnQ2NF90KiBEMjsKKyAgaW50MzJfdCB4TGVuZ3RoLCB5TGVuZ3RoLCBETGVuZ3RoLCBEMkxlbmd0aDsKKyAgaW50MzJfdCBkZWNBcHByb3hDb3VudCwgaW5jQXBwcm94Q291bnQ7CisKKyAgeCA9IHkgPSBEID0gRDIgPSAwOworICB4TGVuZ3RoID0geUxlbmd0aCA9IERMZW5ndGggPSBEMkxlbmd0aCA9IDA7CisgIGRlY0FwcHJveENvdW50ID0gaW5jQXBwcm94Q291bnQgPSAwOworCisgIGRvCisgICAgeworICAgICAgbSA9IGZsb2F0TWFudGlzc2EgKHopOworICAgICAgayA9IGZsb2F0RXhwb25lbnQgKHopOworCisgICAgICBpZiAoeCAmJiB4ICE9IGYpCisgICAgICAgICAgZnJlZSh4KTsKKworICAgICAgZnJlZSh5KTsKKyAgICAgIGZyZWUoRCk7CisgICAgICBmcmVlKEQyKTsKKworICAgICAgaWYgKGUgPj0gMCAmJiBrID49IDApCisgICAgICAgIHsKKyAgICAgICAgICB4TGVuZ3RoID0gc2l6ZU9mVGVuVG9UaGVFIChlKSArIGxlbmd0aDsKKyAgICAgICAgICBhbGxvY2F0ZVU2NCAoeCwgeExlbmd0aCk7CisgICAgICAgICAgbWVtc2V0ICh4ICsgbGVuZ3RoLCAwLCBzaXplb2YgKHVpbnQ2NF90KSAqICh4TGVuZ3RoIC0gbGVuZ3RoKSk7CisgICAgICAgICAgbWVtY3B5ICh4LCBmLCBzaXplb2YgKHVpbnQ2NF90KSAqIGxlbmd0aCk7CisgICAgICAgICAgdGltZXNUZW5Ub1RoZUVIaWdoUHJlY2lzaW9uICh4LCB4TGVuZ3RoLCBlKTsKKworICAgICAgICAgIHlMZW5ndGggPSAoayA+PiA2KSArIDI7CisgICAgICAgICAgYWxsb2NhdGVVNjQgKHksIHlMZW5ndGgpOworICAgICAgICAgIG1lbXNldCAoeSArIDEsIDAsIHNpemVvZiAodWludDY0X3QpICogKHlMZW5ndGggLSAxKSk7CisgICAgICAgICAgKnkgPSBtOworICAgICAgICAgIHNpbXBsZVNoaWZ0TGVmdEhpZ2hQcmVjaXNpb24gKHksIHlMZW5ndGgsIGspOworICAgICAgICB9CisgICAgICBlbHNlIGlmIChlID49IDApCisgICAgICAgIHsKKyAgICAgICAgICB4TGVuZ3RoID0gc2l6ZU9mVGVuVG9UaGVFIChlKSArIGxlbmd0aCArICgoLWspID4+IDYpICsgMTsKKyAgICAgICAgICBhbGxvY2F0ZVU2NCAoeCwgeExlbmd0aCk7CisgICAgICAgICAgbWVtc2V0ICh4ICsgbGVuZ3RoLCAwLCBzaXplb2YgKHVpbnQ2NF90KSAqICh4TGVuZ3RoIC0gbGVuZ3RoKSk7CisgICAgICAgICAgbWVtY3B5ICh4LCBmLCBzaXplb2YgKHVpbnQ2NF90KSAqIGxlbmd0aCk7CisgICAgICAgICAgdGltZXNUZW5Ub1RoZUVIaWdoUHJlY2lzaW9uICh4LCB4TGVuZ3RoLCBlKTsKKyAgICAgICAgICBzaW1wbGVTaGlmdExlZnRIaWdoUHJlY2lzaW9uICh4LCB4TGVuZ3RoLCAtayk7CisKKyAgICAgICAgICB5TGVuZ3RoID0gMTsKKyAgICAgICAgICBhbGxvY2F0ZVU2NCAoeSwgMSk7CisgICAgICAgICAgKnkgPSBtOworICAgICAgICB9CisgICAgICBlbHNlIGlmIChrID49IDApCisgICAgICAgIHsKKyAgICAgICAgICB4TGVuZ3RoID0gbGVuZ3RoOworICAgICAgICAgIHggPSBmOworCisgICAgICAgICAgeUxlbmd0aCA9IHNpemVPZlRlblRvVGhlRSAoLWUpICsgMiArIChrID4+IDYpOworICAgICAgICAgIGFsbG9jYXRlVTY0ICh5LCB5TGVuZ3RoKTsKKyAgICAgICAgICBtZW1zZXQgKHkgKyAxLCAwLCBzaXplb2YgKHVpbnQ2NF90KSAqICh5TGVuZ3RoIC0gMSkpOworICAgICAgICAgICp5ID0gbTsKKyAgICAgICAgICB0aW1lc1RlblRvVGhlRUhpZ2hQcmVjaXNpb24gKHksIHlMZW5ndGgsIC1lKTsKKyAgICAgICAgICBzaW1wbGVTaGlmdExlZnRIaWdoUHJlY2lzaW9uICh5LCB5TGVuZ3RoLCBrKTsKKyAgICAgICAgfQorICAgICAgZWxzZQorICAgICAgICB7CisgICAgICAgICAgeExlbmd0aCA9IGxlbmd0aCArICgoLWspID4+IDYpICsgMTsKKyAgICAgICAgICBhbGxvY2F0ZVU2NCAoeCwgeExlbmd0aCk7CisgICAgICAgICAgbWVtc2V0ICh4ICsgbGVuZ3RoLCAwLCBzaXplb2YgKHVpbnQ2NF90KSAqICh4TGVuZ3RoIC0gbGVuZ3RoKSk7CisgICAgICAgICAgbWVtY3B5ICh4LCBmLCBzaXplb2YgKHVpbnQ2NF90KSAqIGxlbmd0aCk7CisgICAgICAgICAgc2ltcGxlU2hpZnRMZWZ0SGlnaFByZWNpc2lvbiAoeCwgeExlbmd0aCwgLWspOworCisgICAgICAgICAgeUxlbmd0aCA9IHNpemVPZlRlblRvVGhlRSAoLWUpICsgMTsKKyAgICAgICAgICBhbGxvY2F0ZVU2NCAoeSwgeUxlbmd0aCk7CisgICAgICAgICAgbWVtc2V0ICh5ICsgMSwgMCwgc2l6ZW9mICh1aW50NjRfdCkgKiAoeUxlbmd0aCAtIDEpKTsKKyAgICAgICAgICAqeSA9IG07CisgICAgICAgICAgdGltZXNUZW5Ub1RoZUVIaWdoUHJlY2lzaW9uICh5LCB5TGVuZ3RoLCAtZSk7CisgICAgICAgIH0KKworICAgICAgY29tcGFyaXNvbiA9IGNvbXBhcmVIaWdoUHJlY2lzaW9uICh4LCB4TGVuZ3RoLCB5LCB5TGVuZ3RoKTsKKyAgICAgIGlmIChjb21wYXJpc29uID4gMCkKKyAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgLyogeCA+IHkgKi8KKyAgICAgICAgICBETGVuZ3RoID0geExlbmd0aDsKKyAgICAgICAgICBhbGxvY2F0ZVU2NCAoRCwgRExlbmd0aCk7CisgICAgICAgICAgbWVtY3B5IChELCB4LCBETGVuZ3RoICogc2l6ZW9mICh1aW50NjRfdCkpOworICAgICAgICAgIHN1YnRyYWN0SGlnaFByZWNpc2lvbiAoRCwgRExlbmd0aCwgeSwgeUxlbmd0aCk7CisgICAgICAgIH0KKyAgICAgIGVsc2UgaWYgKGNvbXBhcmlzb24pCisgICAgICAgIHsgICAgICAgICAgICAgICAgICAgICAgIC8qIHkgPiB4ICovCisgICAgICAgICAgRExlbmd0aCA9IHlMZW5ndGg7CisgICAgICAgICAgYWxsb2NhdGVVNjQgKEQsIERMZW5ndGgpOworICAgICAgICAgIG1lbWNweSAoRCwgeSwgRExlbmd0aCAqIHNpemVvZiAodWludDY0X3QpKTsKKyAgICAgICAgICBzdWJ0cmFjdEhpZ2hQcmVjaXNpb24gKEQsIERMZW5ndGgsIHgsIHhMZW5ndGgpOworICAgICAgICB9CisgICAgICBlbHNlCisgICAgICAgIHsgICAgICAgICAgICAgICAgICAgICAgIC8qIHkgPT0geCAqLworICAgICAgICAgIERMZW5ndGggPSAxOworICAgICAgICAgIGFsbG9jYXRlVTY0IChELCAxKTsKKyAgICAgICAgICAqRCA9IDA7CisgICAgICAgIH0KKworICAgICAgRDJMZW5ndGggPSBETGVuZ3RoICsgMTsKKyAgICAgIGFsbG9jYXRlVTY0IChEMiwgRDJMZW5ndGgpOworICAgICAgbSA8PD0gMTsKKyAgICAgIG11bHRpcGx5SGlnaFByZWNpc2lvbiAoRCwgRExlbmd0aCwgJm0sIDEsIEQyLCBEMkxlbmd0aCk7CisgICAgICBtID4+PSAxOworCisgICAgICBjb21wYXJpc29uMiA9IGNvbXBhcmVIaWdoUHJlY2lzaW9uIChEMiwgRDJMZW5ndGgsIHksIHlMZW5ndGgpOworICAgICAgaWYgKGNvbXBhcmlzb24yIDwgMCkKKyAgICAgICAgeworICAgICAgICAgIGlmIChjb21wYXJpc29uIDwgMCAmJiBtID09IEZMT0FUX05PUk1BTF9NQVNLKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICBzaW1wbGVTaGlmdExlZnRIaWdoUHJlY2lzaW9uIChEMiwgRDJMZW5ndGgsIDEpOworICAgICAgICAgICAgICBpZiAoY29tcGFyZUhpZ2hQcmVjaXNpb24gKEQyLCBEMkxlbmd0aCwgeSwgeUxlbmd0aCkgPiAwKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIERFQ1JFTUVOVF9GTE9BVCAoeiwgZGVjQXBwcm94Q291bnQsIGluY0FwcHJveENvdW50KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgZWxzZQorICAgICAgICAgICAgeworICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgZWxzZSBpZiAoY29tcGFyaXNvbjIgPT0gMCkKKyAgICAgICAgeworICAgICAgICAgIGlmICgobSAmIDEpID09IDApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgIGlmIChjb21wYXJpc29uIDwgMCAmJiBtID09IEZMT0FUX05PUk1BTF9NQVNLKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIERFQ1JFTUVOVF9GTE9BVCAoeiwgZGVjQXBwcm94Q291bnQsIGluY0FwcHJveENvdW50KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgZWxzZSBpZiAoY29tcGFyaXNvbiA8IDApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgIERFQ1JFTUVOVF9GTE9BVCAoeiwgZGVjQXBwcm94Q291bnQsIGluY0FwcHJveENvdW50KTsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgZWxzZQorICAgICAgICAgICAgeworICAgICAgICAgICAgICBJTkNSRU1FTlRfRkxPQVQgKHosIGRlY0FwcHJveENvdW50LCBpbmNBcHByb3hDb3VudCk7CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICBlbHNlIGlmIChjb21wYXJpc29uIDwgMCkKKyAgICAgICAgeworICAgICAgICAgIERFQ1JFTUVOVF9GTE9BVCAoeiwgZGVjQXBwcm94Q291bnQsIGluY0FwcHJveENvdW50KTsKKyAgICAgICAgfQorICAgICAgZWxzZQorICAgICAgICB7CisgICAgICAgICAgaWYgKEZMT0FUX1RPX0lOVEJJVFMgKHopID09IEZMT0FUX0VYUE9ORU5UX01BU0spCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBJTkNSRU1FTlRfRkxPQVQgKHosIGRlY0FwcHJveENvdW50LCBpbmNBcHByb3hDb3VudCk7CisgICAgICAgIH0KKyAgICB9CisgIHdoaWxlICgxKTsKKworICBpZiAoeCAmJiB4ICE9IGYpCisgICAgICBmcmVlKHgpOworICBmcmVlKHkpOworICBmcmVlKEQpOworICBmcmVlKEQyKTsKKyAgcmV0dXJuIHo7CisKK091dE9mTWVtb3J5OgorICBpZiAoeCAmJiB4ICE9IGYpCisgICAgICBmcmVlKHgpOworICBmcmVlKHkpOworICBmcmVlKEQpOworICBmcmVlKEQyKTsKKyAgam5pVGhyb3dPdXRPZk1lbW9yeUVycm9yKGVudiwgTlVMTCk7CisgIHJldHVybiB6OworfQorCitzdGF0aWMgamZsb2F0IFN0cmluZ1RvUmVhbF9wYXJzZUZsdEltcGwoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBzLCBqaW50IGUpIHsKKyAgICBTY29wZWRVdGZDaGFycyBzdHIoZW52LCBzKTsKKyAgICBpZiAoc3RyLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gMC4wOworICAgIH0KKyAgICByZXR1cm4gY3JlYXRlRmxvYXQoZW52LCBzdHIuY19zdHIoKSwgZSk7Cit9CisKK3N0YXRpYyBqZG91YmxlIFN0cmluZ1RvUmVhbF9wYXJzZURibEltcGwoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBzLCBqaW50IGUpIHsKKyAgICBTY29wZWRVdGZDaGFycyBzdHIoZW52LCBzKTsKKyAgICBpZiAoc3RyLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gMC4wOworICAgIH0KKyAgICByZXR1cm4gY3JlYXRlRG91YmxlKGVudiwgc3RyLmNfc3RyKCksIGUpOworfQorCitzdGF0aWMgSk5JTmF0aXZlTWV0aG9kIGdNZXRob2RzW10gPSB7CisgICAgTkFUSVZFX01FVEhPRChTdHJpbmdUb1JlYWwsIHBhcnNlRmx0SW1wbCwgIihMamF2YS9sYW5nL1N0cmluZztJKUYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFN0cmluZ1RvUmVhbCwgcGFyc2VEYmxJbXBsLCAiKExqYXZhL2xhbmcvU3RyaW5nO0kpRCIpLAorfTsKK2ludCByZWdpc3Rlcl9qYXZhX2xhbmdfU3RyaW5nVG9SZWFsKEpOSUVudiogZW52KSB7CisgICAgcmV0dXJuIGpuaVJlZ2lzdGVyTmF0aXZlTWV0aG9kcyhlbnYsICJqYXZhL2xhbmcvU3RyaW5nVG9SZWFsIiwgZ01ldGhvZHMsIE5FTEVNKGdNZXRob2RzKSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX2xhbmdfU3lzdGVtLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfbGFuZ19TeXN0ZW0uY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjllYmZjMzIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX2xhbmdfU3lzdGVtLmNwcApAQCAtMCwwICsxLDkzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJTeXN0ZW0iCisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisjaW5jbHVkZSAiU2NvcGVkVXRmQ2hhcnMuaCIKKyNpbmNsdWRlICJjdXRpbHMvbG9nLmgiCisjaW5jbHVkZSAib3BlbnNzbC9vcGVuc3Nsdi5oIgorI2luY2x1ZGUgInRvU3RyaW5nQXJyYXkuaCIKKyNpbmNsdWRlICJ6bGliLmgiCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8bGltaXRzLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8dW5pc3RkLmg+CisKK3N0YXRpYyB2b2lkIFN5c3RlbV9sb2coSk5JRW52KiBlbnYsIGpjbGFzcywgamNoYXIgdHlwZSwganN0cmluZyBqYXZhTWVzc2FnZSwganRocm93YWJsZSBleGNlcHRpb24pIHsKKyAgICBTY29wZWRVdGZDaGFycyBtZXNzYWdlKGVudiwgamF2YU1lc3NhZ2UpOworICAgIGlmIChtZXNzYWdlLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICAvLyBTaW5jZSB0aGlzIGZ1bmN0aW9uIGlzIHVzZWQgZm9yIGxhc3QtZ2FzcCBkZWJ1Z2dpbmcgb3V0cHV0LCBiZSBub2lzeSBvbiBmYWlsdXJlLgorICAgICAgICBMT0dFKCJtZXNzYWdlLmNfc3RyKCkgPT0gTlVMTCIpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGludCBwcmlvcml0eTsKKyAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlICdEJzogY2FzZSAnZCc6IHByaW9yaXR5ID0gQU5EUk9JRF9MT0dfREVCVUc7ICAgYnJlYWs7CisgICAgY2FzZSAnRSc6IGNhc2UgJ2UnOiBwcmlvcml0eSA9IEFORFJPSURfTE9HX0VSUk9SOyAgIGJyZWFrOworICAgIGNhc2UgJ0YnOiBjYXNlICdmJzogcHJpb3JpdHkgPSBBTkRST0lEX0xPR19GQVRBTDsgICBicmVhazsKKyAgICBjYXNlICdJJzogY2FzZSAnaSc6IHByaW9yaXR5ID0gQU5EUk9JRF9MT0dfSU5GTzsgICAgYnJlYWs7CisgICAgY2FzZSAnUyc6IGNhc2UgJ3MnOiBwcmlvcml0eSA9IEFORFJPSURfTE9HX1NJTEVOVDsgIGJyZWFrOworICAgIGNhc2UgJ1YnOiBjYXNlICd2JzogcHJpb3JpdHkgPSBBTkRST0lEX0xPR19WRVJCT1NFOyBicmVhazsKKyAgICBjYXNlICdXJzogY2FzZSAndyc6IHByaW9yaXR5ID0gQU5EUk9JRF9MT0dfV0FSTjsgICAgYnJlYWs7CisgICAgZGVmYXVsdDogICAgICAgICAgICBwcmlvcml0eSA9IEFORFJPSURfTE9HX0RFRkFVTFQ7IGJyZWFrOworICAgIH0KKyAgICBMT0dfUFJJKHByaW9yaXR5LCBMT0dfVEFHLCAiJXMiLCBtZXNzYWdlLmNfc3RyKCkpOworICAgIGlmIChleGNlcHRpb24gIT0gTlVMTCkgeworICAgICAgICBqbmlMb2dFeGNlcHRpb24oZW52LCBwcmlvcml0eSwgTE9HX1RBRywgZXhjZXB0aW9uKTsKKyAgICB9Cit9CisKKy8vIFNldHMgYSBmaWVsZCB2aWEgSk5JLiBVc2VkIGZvciB0aGUgc3RhbmRhcmQgc3RyZWFtcywgd2hpY2ggYXJlIHJlYWQtb25seSBvdGhlcndpc2UuCitzdGF0aWMgdm9pZCBTeXN0ZW1fc2V0RmllbGRJbXBsKEpOSUVudiogZW52LCBqY2xhc3MgY2xhenosCisgICAgICAgIGpzdHJpbmcgamF2YU5hbWUsIGpzdHJpbmcgamF2YVNpZ25hdHVyZSwgam9iamVjdCBvYmplY3QpIHsKKyAgICBTY29wZWRVdGZDaGFycyBuYW1lKGVudiwgamF2YU5hbWUpOworICAgIGlmIChuYW1lLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm47CisgICAgfQorICAgIFNjb3BlZFV0ZkNoYXJzIHNpZ25hdHVyZShlbnYsIGphdmFTaWduYXR1cmUpOworICAgIGlmIChzaWduYXR1cmUuY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgamZpZWxkSUQgZmllbGRJRCA9IGVudi0+R2V0U3RhdGljRmllbGRJRChjbGF6eiwgbmFtZS5jX3N0cigpLCBzaWduYXR1cmUuY19zdHIoKSk7CisgICAgZW52LT5TZXRTdGF0aWNPYmplY3RGaWVsZChjbGF6eiwgZmllbGRJRCwgb2JqZWN0KTsKK30KKworc3RhdGljIGpvYmplY3RBcnJheSBTeXN0ZW1fc3BlY2lhbFByb3BlcnRpZXMoSk5JRW52KiBlbnYsIGpjbGFzcykgeworICAgIHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiBwcm9wZXJ0aWVzOworCisgICAgY2hhciBwYXRoW1BBVEhfTUFYXTsKKyAgICBwcm9wZXJ0aWVzLnB1c2hfYmFjayhzdGQ6OnN0cmluZygidXNlci5kaXI9IikgKyBnZXRjd2QocGF0aCwgc2l6ZW9mKHBhdGgpKSk7CisKKyAgICBwcm9wZXJ0aWVzLnB1c2hfYmFjaygiYW5kcm9pZC56bGliLnZlcnNpb249IiBaTElCX1ZFUlNJT04pOworICAgIHByb3BlcnRpZXMucHVzaF9iYWNrKCJhbmRyb2lkLm9wZW5zc2wudmVyc2lvbj0iIE9QRU5TU0xfVkVSU0lPTl9URVhUKTsKKworICAgIHJldHVybiB0b1N0cmluZ0FycmF5KGVudiwgcHJvcGVydGllcyk7Cit9CisKK3N0YXRpYyBKTklOYXRpdmVNZXRob2QgZ01ldGhvZHNbXSA9IHsKKyAgICBOQVRJVkVfTUVUSE9EKFN5c3RlbSwgbG9nLCAiKENMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1Rocm93YWJsZTspViIpLAorICAgIE5BVElWRV9NRVRIT0QoU3lzdGVtLCBzZXRGaWVsZEltcGwsICIoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9PYmplY3Q7KVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFN5c3RlbSwgc3BlY2lhbFByb3BlcnRpZXMsICIoKVtMamF2YS9sYW5nL1N0cmluZzsiKSwKK307CitpbnQgcmVnaXN0ZXJfamF2YV9sYW5nX1N5c3RlbShKTklFbnYqIGVudikgeworICAgIHJldHVybiBqbmlSZWdpc3Rlck5hdGl2ZU1ldGhvZHMoZW52LCAiamF2YS9sYW5nL1N5c3RlbSIsIGdNZXRob2RzLCBORUxFTShnTWV0aG9kcykpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV9tYXRoX05hdGl2ZUJOLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfbWF0aF9OYXRpdmVCTi5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjM1OWUzZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfbWF0aF9OYXRpdmVCTi5jcHAKQEAgLTAsMCArMSw1NTggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKgorICogTmF0aXZlIGdsdWUgZm9yIEphdmEgY2xhc3Mgb3JnLm9wZW5zc2wuTmF0aXZlQk4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIk5hdGl2ZUJOIgorCisjaW5jbHVkZSAiSk5JSGVscC5oIgorI2luY2x1ZGUgIkpuaUNvbnN0YW50cy5oIgorI2luY2x1ZGUgIlNjb3BlZFByaW1pdGl2ZUFycmF5LmgiCisjaW5jbHVkZSAiU2NvcGVkVXRmQ2hhcnMuaCIKKyNpbmNsdWRlICJTdGF0aWNBc3NlcnQuaCIKKyNpbmNsdWRlICJVbmlxdWVQdHIuaCIKKyNpbmNsdWRlICJqbmkuaCIKKyNpbmNsdWRlIDxvcGVuc3NsL2JuLmg+CisjaW5jbHVkZSA8b3BlbnNzbC9jcnlwdG8uaD4KKyNpbmNsdWRlIDxvcGVuc3NsL2Vyci5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisKK3N0cnVjdCBCTl9DVFhfRGVsZXRlciB7CisgICAgdm9pZCBvcGVyYXRvcigpKEJOX0NUWCogcCkgY29uc3QgeworICAgICAgICBCTl9DVFhfZnJlZShwKTsKKyAgICB9Cit9OwordHlwZWRlZiBVbmlxdWVQdHI8Qk5fQ1RYLCBCTl9DVFhfRGVsZXRlcj4gVW5pcXVlX0JOX0NUWDsKKworc3RhdGljIGludCBpc1ZhbGlkSGFuZGxlIChKTklFbnYqIGVudiwgdm9pZCogaGFuZGxlLCBjb25zdCBjaGFyKiBtZXNzYWdlKSB7CisgICAgaWYgKGhhbmRsZSA9PSBOVUxMKSB7CisgICAgICAgIGpuaVRocm93TnVsbFBvaW50ZXJFeGNlcHRpb24oZW52LCBtZXNzYWdlKTsKKyAgICAgICAgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICB9CisgICAgcmV0dXJuIEpOSV9UUlVFOworfQorCitzdGF0aWMgaW50IG9uZVZhbGlkSGFuZGxlIChKTklFbnYqIGVudiwgdm9pZCogYSkKK3sKKyAgICByZXR1cm4gaXNWYWxpZEhhbmRsZShlbnYsIGEsICJNYW5kYXRvcnkgaGFuZGxlIChmaXJzdCkgcGFzc2VkIGFzIG51bGwiKTsKK30KKworc3RhdGljIGludCB0d29WYWxpZEhhbmRsZXMgKEpOSUVudiogZW52LCB2b2lkKiBhLCB2b2lkKiBiKQoreworICAgIGlmICghb25lVmFsaWRIYW5kbGUoZW52LCBhKSkgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICByZXR1cm4gaXNWYWxpZEhhbmRsZShlbnYsIGIsICJNYW5kYXRvcnkgaGFuZGxlIChzZWNvbmQpIHBhc3NlZCBhcyBudWxsIik7Cit9CisKK3N0YXRpYyBpbnQgdGhyZWVWYWxpZEhhbmRsZXMgKEpOSUVudiogZW52LCB2b2lkKiBhLCB2b2lkKiBiLCB2b2lkKiBjKQoreworICAgIGlmICghdHdvVmFsaWRIYW5kbGVzKGVudiwgYSwgYikpIHJldHVybiBKTklfRkFMU0U7CisgICAgcmV0dXJuIGlzVmFsaWRIYW5kbGUoZW52LCBjLCAiTWFuZGF0b3J5IGhhbmRsZSAodGhpcmQpIHBhc3NlZCBhcyBudWxsIik7Cit9CisKK3N0YXRpYyBpbnQgZm91clZhbGlkSGFuZGxlcyAoSk5JRW52KiBlbnYsIHZvaWQqIGEsIHZvaWQqIGIsIHZvaWQqIGMsIHZvaWQqIGQpCit7CisgICAgaWYgKCF0aHJlZVZhbGlkSGFuZGxlcyhlbnYsIGEsIGIsIGMpKSByZXR1cm4gSk5JX0ZBTFNFOworICAgIHJldHVybiBpc1ZhbGlkSGFuZGxlKGVudiwgZCwgIk1hbmRhdG9yeSBoYW5kbGUgKGZvdXJ0aCkgcGFzc2VkIGFzIG51bGwiKTsKK30KKworc3RhdGljIHVuc2lnbmVkIGxvbmcgTmF0aXZlQk5fRVJSX2dldF9lcnJvcihKTklFbnYqLCBqY2xhc3MpIHsKKyAgICByZXR1cm4gRVJSX2dldF9lcnJvcigpOworfQorCitzdGF0aWMganN0cmluZyBOYXRpdmVCTl9FUlJfZXJyb3Jfc3RyaW5nKEpOSUVudiogZW52LCBqY2xhc3MsIHVuc2lnbmVkIGxvbmcgZSkgeworICAgIGNoYXIqIGVyclN0ciA9IEVSUl9lcnJvcl9zdHJpbmcoZSwgTlVMTCk7CisgICAgcmV0dXJuIGVudi0+TmV3U3RyaW5nVVRGKGVyclN0cik7Cit9CisKK3N0YXRpYyBCSUdOVU0qIE5hdGl2ZUJOX0JOX25ldyhKTklFbnYqLCBqY2xhc3MpIHsKKyAgICByZXR1cm4gQk5fbmV3KCk7Cit9CisKK3N0YXRpYyB2b2lkIE5hdGl2ZUJOX0JOX2ZyZWUoSk5JRW52KiBlbnYsIGpjbGFzcywgQklHTlVNKiBhKSB7CisgICAgaWYgKCFvbmVWYWxpZEhhbmRsZShlbnYsIGEpKSByZXR1cm47CisgICAgQk5fZnJlZShhKTsKK30KKworc3RhdGljIGludCBOYXRpdmVCTl9CTl9jbXAoSk5JRW52KiBlbnYsIGpjbGFzcywgQklHTlVNKiBhLCBCSUdOVU0qIGIpIHsKKyAgICBpZiAoIXR3b1ZhbGlkSGFuZGxlcyhlbnYsIGEsIGIpKSByZXR1cm4gMTsKKyAgICByZXR1cm4gQk5fY21wKGEsIGIpOworfQorCitzdGF0aWMgamJvb2xlYW4gTmF0aXZlQk5fQk5fY29weShKTklFbnYqIGVudiwgamNsYXNzLCBCSUdOVU0qIHRvLCBCSUdOVU0qIGZyb20pIHsKKyAgICBpZiAoIXR3b1ZhbGlkSGFuZGxlcyhlbnYsIHRvLCBmcm9tKSkgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICByZXR1cm4gKEJOX2NvcHkodG8sIGZyb20pICE9IE5VTEwpOworfQorCitzdGF0aWMgamJvb2xlYW4gTmF0aXZlQk5fcHV0VUxvbmdJbnQoSk5JRW52KiBlbnYsIGpjbGFzcywgQklHTlVNKiBhLCB1bnNpZ25lZCBsb25nIGxvbmcgZHcsIGpib29sZWFuIG5lZykgeworICAgIGlmICghb25lVmFsaWRIYW5kbGUoZW52LCBhKSkgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICB1bnNpZ25lZCBpbnQgaGkgPSBkdyA+PiAzMjsgLy8gVGhpcyBzaGlmdHMgd2l0aG91dCBzaWduIGV4dGVuc2lvbi4KKyAgICBpbnQgbG8gPSAoaW50KWR3OyAvLyBUaGlzIHRydW5jYXRlcyBpbXBsaWNpdGVseS4KKworICAgIC8vIGNmLiBsaXRFbmRJbnRzMmJuOgorICAgIGJuX2NoZWNrX3RvcChhKTsKKyAgICAgICAgaWYgKGJuX3dleHBhbmQoYSwgMikgIT0gTlVMTCkgeworICAgICAgICAgICAgYS0+ZFswXSA9IGxvOworICAgICAgICAgICAgYS0+ZFsxXSA9IGhpOworICAgICAgICAgICAgYS0+dG9wID0gMjsKKyAgICAgICAgICAgIGEtPm5lZyA9IG5lZzsKKyAgICAgICAgICAgIGJuX2NvcnJlY3RfdG9wKGEpOworICAgICAgICAgICAgcmV0dXJuIEpOSV9UUlVFOworICAgICAgICB9CisgICAgICAgIGVsc2UgcmV0dXJuIEpOSV9GQUxTRTsKK30KKworc3RhdGljIGpib29sZWFuIE5hdGl2ZUJOX3B1dExvbmdJbnQoSk5JRW52KiBlbnYsIGpjbGFzcyBjbHMsIEJJR05VTSogYSwgbG9uZyBsb25nIGR3KSB7CisgICAgaWYgKGR3ID49IDApIHJldHVybiBOYXRpdmVCTl9wdXRVTG9uZ0ludChlbnYsIGNscywgYSwgZHcsIEpOSV9GQUxTRSk7CisgICAgZWxzZSByZXR1cm4gTmF0aXZlQk5fcHV0VUxvbmdJbnQoZW52LCBjbHMsIGEsIC1kdywgSk5JX1RSVUUpOworfQorCitzdGF0aWMgaW50IE5hdGl2ZUJOX0JOX2RlYzJibihKTklFbnYqIGVudiwgamNsYXNzLCBCSUdOVU0qIGEsIGpzdHJpbmcgc3RyKSB7CisgICAgaWYgKCFvbmVWYWxpZEhhbmRsZShlbnYsIGEpKSByZXR1cm4gLTE7CisgICAgU2NvcGVkVXRmQ2hhcnMgY2hhcnMoZW52LCBzdHIpOworICAgIGlmIChjaGFycy5jX3N0cigpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICByZXR1cm4gQk5fZGVjMmJuKCZhLCBjaGFycy5jX3N0cigpKTsKK30KKworc3RhdGljIGludCBOYXRpdmVCTl9CTl9oZXgyYm4oSk5JRW52KiBlbnYsIGpjbGFzcywgQklHTlVNKiBhLCBqc3RyaW5nIHN0cikgeworICAgIGlmICghb25lVmFsaWRIYW5kbGUoZW52LCBhKSkgcmV0dXJuIC0xOworICAgIFNjb3BlZFV0ZkNoYXJzIGNoYXJzKGVudiwgc3RyKTsKKyAgICBpZiAoY2hhcnMuY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmV0dXJuIEJOX2hleDJibigmYSwgY2hhcnMuY19zdHIoKSk7Cit9CisKK3N0YXRpYyBqYm9vbGVhbiBOYXRpdmVCTl9CTl9iaW4yYm4oSk5JRW52KiBlbnYsIGpjbGFzcywgamJ5dGVBcnJheSBhcnIsIGludCBsZW4sIGpib29sZWFuIG5lZywgQklHTlVNKiByZXQpIHsKKyAgICBpZiAoIW9uZVZhbGlkSGFuZGxlKGVudiwgcmV0KSkgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICBTY29wZWRCeXRlQXJyYXlSTyBieXRlcyhlbnYsIGFycik7CisgICAgaWYgKGJ5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBqYm9vbGVhbiBzdWNjZXNzID0gKEJOX2JpbjJibihyZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihieXRlcy5nZXQoKSksIGxlbiwgcmV0KSAhPSBOVUxMKTsKKyAgICBpZiAoc3VjY2VzcyAmJiBuZWcpIHsKKyAgICAgICAgQk5fc2V0X25lZ2F0aXZlKHJldCwgMSk7CisgICAgfQorICAgIHJldHVybiBzdWNjZXNzOworfQorCisvKioKKyAqIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gbGl0RW5kSW50czJibihpbnRbXSwgaW50LCBpbnQsIGludCkKKyAqIE5vdGU6CisgKiBUaGlzIHByb2NlZHVyZSBkaXJlY3RseSB3cml0ZXMgdGhlIGludGVybmFsIHJlcHJlc2VudGF0aW9uIG9mIEJJR05VTXMuCisgKiBXZSBkbyBzbyBhcyB0aGVyZSBpcyBubyBkaXJlY3QgaW50ZXJmYWNlIGJhc2VkIG9uIExpdHRsZSBFbmRpYW4gSW50ZWdlciBBcnJheXMuCisgKiBBbHNvIG5vdGUgdGhhdCB0aGUgc2FtZSByZXByZXNlbnRhdGlvbiBpcyB1c2VkIGluIHRoZSBDb3Jkb2JhIEphdmEgSW1wbGVtZW50YXRpb24gb2YgQmlnSW50ZWdlcnMsCisgKiAgICAgICAgd2hlcmVvZiBjZXJ0YWluIGZ1bmN0aW9uYWxpdHkgaXMgc3RpbGwgYmVpbmcgdXNlZC4KKyAqLworc3RhdGljIGpib29sZWFuIE5hdGl2ZUJOX2xpdEVuZEludHMyYm4oSk5JRW52KiBlbnYsIGpjbGFzcywgamludEFycmF5IGFyciwgaW50IGxlbiwgamJvb2xlYW4gbmVnLCBCSUdOVU0qIHJldCkgeworICAgIGlmICghb25lVmFsaWRIYW5kbGUoZW52LCByZXQpKSByZXR1cm4gSk5JX0ZBTFNFOworICAgIGJuX2NoZWNrX3RvcChyZXQpOworICAgIGlmIChsZW4gPiAwKSB7CisgICAgICAgIFNjb3BlZEludEFycmF5Uk8gc2NvcGVkQXJyYXkoZW52LCBhcnIpOworICAgICAgICBpZiAoc2NvcGVkQXJyYXkuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICAgICAgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICAgICAgfQorCisgICAgICAgIFNUQVRJQ19BU1NFUlQoc2l6ZW9mKEJOX1VMT05HKSA9PSBzaXplb2YoamludCksIEJOX1VMT05HX25vdF8zMl9iaXQpOworICAgICAgICBjb25zdCBCTl9VTE9ORyogdG1wSW50cyA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgQk5fVUxPTkcqPihzY29wZWRBcnJheS5nZXQoKSk7CisgICAgICAgIGlmICgodG1wSW50cyAhPSBOVUxMKSAmJiAoYm5fd2V4cGFuZChyZXQsIGxlbikgIT0gTlVMTCkpIHsKKyAgICAgICAgICAgIGludCBpID0gbGVuOyBkbyB7IGktLTsgcmV0LT5kW2ldID0gdG1wSW50c1tpXTsgfSB3aGlsZSAoaSA+IDApOworICAgICAgICAgICAgcmV0LT50b3AgPSBsZW47CisgICAgICAgICAgICByZXQtPm5lZyA9IG5lZzsKKyAgICAgICAgICAgIC8vIG5lZWQgdG8gY2FsbCB0aGlzIGR1ZSB0byBjbGVhciBieXRlIGF0IHRvcCBpZiBhdm9pZGluZworICAgICAgICAgICAgLy8gaGF2aW5nIHRoZSB0b3AgYml0IHNldCAoLXZlIG51bWJlcikKKyAgICAgICAgICAgIC8vIEJhc2ljYWxseSBnZXQgcmlkIG9mIHRvcCB6ZXJvIGludHM6CisgICAgICAgICAgICBibl9jb3JyZWN0X3RvcChyZXQpOworICAgICAgICAgICAgcmV0dXJuIEpOSV9UUlVFOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICAgICAgfQorICAgIH0gZWxzZSB7IC8vIChsZW4gPSAwKSBtZWFucyB2YWx1ZSA9IDAgYW5kIHNpZ24gd2lsbCBiZSAwLCB0b28uCisgICAgICAgIHJldC0+dG9wID0gMDsKKyAgICAgICAgcmV0dXJuIEpOSV9UUlVFOworICAgIH0KK30KKworCisjZGVmaW5lIEJZVEVTMklOVChieXRlcywgaykgXAorICggIChieXRlc1trICsgM10gJiAweEZGKSBcCisgIHwgKGJ5dGVzW2sgKyAyXSAmIDB4RkYpIDw8IDggXAorICB8IChieXRlc1trICsgMV0gJiAweEZGKSA8PCAxNiBcCisgIHwgKGJ5dGVzW2sgKyAwXSAmIDB4RkYpIDw8IDI0ICkKKworc3RhdGljIGpib29sZWFuIG5lZ0JpZ0VuZGlhbkJ5dGVzMmJuKEpOSUVudiosIGpjbGFzcywgY29uc3QgdW5zaWduZWQgY2hhciogYnl0ZXMsIGludCBieXRlc0xlbiwgQklHTlVNKiByZXQpIHsKKyAgICAvLyBXZSByZWx5IG9uOiAoQk5fQklUUzIgPT0gMzIpLCBpLmUuIEJOX1VMT05HIGlzIHVuc2lnbmVkIGludCBhbmQgaGFzIDQgYnl0ZXM6CisgICAgYm5fY2hlY2tfdG9wKHJldCk7CisgICAgLy8gRklYTUU6IGFzc2VydCBieXRlc0xlbiA+IDAKKyAgICBpbnQgaW50TGVuID0gKGJ5dGVzTGVuICsgMykgLyA0OworICAgIGludCBmaXJzdE5vbnplcm9EaWdpdCA9IC0yOworICAgIGlmIChibl93ZXhwYW5kKHJldCwgaW50TGVuKSAhPSBOVUxMKSB7CisgICAgICAgIEJOX1VMT05HKiBkID0gcmV0LT5kOworICAgICAgICBCTl9VTE9ORyBkaTsKKyAgICAgICAgcmV0LT50b3AgPSBpbnRMZW47CisgICAgICAgIGludCBoaWdoQnl0ZXMgPSBieXRlc0xlbiAlIDQ7CisgICAgICAgIGludCBrID0gYnl0ZXNMZW47CisgICAgICAgIC8vIFB1dCBieXRlcyB0byB0aGUgaW50IGFycmF5IHN0YXJ0aW5nIGZyb20gdGhlIGVuZCBvZiB0aGUgYnl0ZSBhcnJheQorICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgIHdoaWxlIChrID4gaGlnaEJ5dGVzKSB7CisgICAgICAgICAgICBrIC09IDQ7CisgICAgICAgICAgICBkaSA9IEJZVEVTMklOVChieXRlcywgayk7CisgICAgICAgICAgICBpZiAoZGkgIT0gMCkgeworICAgICAgICAgICAgICAgIGRbaV0gPSAtZGk7CisgICAgICAgICAgICAgICAgZmlyc3ROb256ZXJvRGlnaXQgPSBpOworICAgICAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgICAgICB3aGlsZSAoayA+IGhpZ2hCeXRlcykgeworICAgICAgICAgICAgICAgICAgICBrIC09IDQ7CisgICAgICAgICAgICAgICAgICAgIGRbaV0gPSB+QllURVMySU5UKGJ5dGVzLCBrKTsKKyAgICAgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZFtpXSA9IDA7CisgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChoaWdoQnl0ZXMgIT0gMCkgeworICAgICAgICAgICAgZGkgPSAtMTsKKyAgICAgICAgICAgIC8vIFB1dCB0aGUgZmlyc3QgYnl0ZXMgaW4gdGhlIGhpZ2hlc3QgZWxlbWVudCBvZiB0aGUgaW50IGFycmF5CisgICAgICAgICAgICBpZiAoZmlyc3ROb256ZXJvRGlnaXQgIT0gLTIpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGsgPSAwOyBrIDwgaGlnaEJ5dGVzOyBrKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZGkgPSAoZGkgPDwgOCkgfCAoYnl0ZXNba10gJiAweEZGKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZFtpXSA9IH5kaTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZm9yIChrID0gMDsgayA8IGhpZ2hCeXRlczsgaysrKSB7CisgICAgICAgICAgICAgICAgICAgIGRpID0gKGRpIDw8IDgpIHwgKGJ5dGVzW2tdICYgMHhGRik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGRbaV0gPSAtZGk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIEpOSV9UUlVFOworICAgIH0KKyAgICBlbHNlIHJldHVybiBKTklfRkFMU0U7Cit9CisKK3N0YXRpYyBqYm9vbGVhbiBOYXRpdmVCTl90d29zQ29tcDJibihKTklFbnYqIGVudiwgamNsYXNzIGNscywgamJ5dGVBcnJheSBhcnIsIGludCBieXRlc0xlbiwgQklHTlVNKiByZXQpIHsKKyAgICBpZiAoIW9uZVZhbGlkSGFuZGxlKGVudiwgcmV0KSkgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICBTY29wZWRCeXRlQXJyYXlSTyBieXRlcyhlbnYsIGFycik7CisgICAgaWYgKGJ5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBqYm9vbGVhbiBzdWNjZXNzOworICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIqIHMgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihieXRlcy5nZXQoKSk7CisgICAgaWYgKChieXRlc1swXSAmIDBYODApID09IDApIHsgLy8gUG9zaXRpdmUgdmFsdWUhCisgICAgICAgIC8vCisgICAgICAgIC8vIFdlIGNhbiB1c2UgdGhlIGV4aXN0aW5nIEJOIGltcGxlbWVudGF0aW9uIGZvciB1bnNpZ25lZCBiaWcgZW5kaWFuIGJ5dGVzOgorICAgICAgICAvLworICAgICAgICBzdWNjZXNzID0gKEJOX2JpbjJibihzLCBieXRlc0xlbiwgcmV0KSAhPSBOVUxMKTsKKyAgICAgICAgQk5fc2V0X25lZ2F0aXZlKHJldCwgSk5JX0ZBTFNFKTsKKyAgICB9IGVsc2UgeyAvLyBOZWdhdGl2ZSB2YWx1ZSEKKyAgICAgICAgLy8KKyAgICAgICAgLy8gV2UgbmVlZCB0byBhcHBseSB0d28ncyBjb21wbGVtZW50OgorICAgICAgICAvLworICAgICAgICBzdWNjZXNzID0gbmVnQmlnRW5kaWFuQnl0ZXMyYm4oZW52LCBjbHMsIHMsIGJ5dGVzTGVuLCByZXQpOworICAgICAgICBCTl9zZXRfbmVnYXRpdmUocmV0LCBKTklfVFJVRSk7CisgICAgfQorICAgIHJldHVybiBzdWNjZXNzOworfQorCitzdGF0aWMgbG9uZyBsb25nIE5hdGl2ZUJOX2xvbmdJbnQoSk5JRW52KiBlbnYsIGpjbGFzcywgQklHTlVNKiBhKSB7CisgICAgaWYgKCFvbmVWYWxpZEhhbmRsZShlbnYsIGEpKSByZXR1cm4gLTE7CisgICAgYm5fY2hlY2tfdG9wKGEpOworICAgIGludCBpbnRMZW4gPSBhLT50b3A7CisgICAgQk5fVUxPTkcqIGQgPSBhLT5kOworICAgIHN3aXRjaCAoaW50TGVuKSB7CisgICAgY2FzZSAwOgorICAgICAgICByZXR1cm4gMDsKKyAgICBjYXNlIDE6CisgICAgICAgIGlmICghYS0+bmVnKSByZXR1cm4gZFswXSAmIDBYMDAwMDAwMDBGRkZGRkZGRkxMOworICAgICAgICBlbHNlIHJldHVybiAtKGRbMF0gJiAwWDAwMDAwMDAwRkZGRkZGRkZMTCk7CisgICAgZGVmYXVsdDoKKyAgICAgICAgaWYgKCFhLT5uZWcpIHJldHVybiAoKGxvbmcgbG9uZylkWzFdIDw8IDMyKSB8IChkWzBdICYgMFhGRkZGRkZGRkxMKTsKKyAgICAgICAgZWxzZSByZXR1cm4gLSgoKGxvbmcgbG9uZylkWzFdIDw8IDMyKSB8IChkWzBdICYgMFhGRkZGRkZGRkxMKSk7CisgICAgfQorfQorCitzdGF0aWMgY2hhciogbGVhZGluZ1plcm9zVHJpbW1lZChjaGFyKiBzKSB7CisgICAgY2hhciogcCA9IHM7CisgICAgaWYgKCpwID09ICctJykgeworICAgICAgICBwKys7CisgICAgICAgIHdoaWxlICgoKnAgPT0gJzAnKSAmJiAoKihwICsgMSkgIT0gMCkpIHsgcCsrOyB9CisgICAgICAgIHAtLTsKKyAgICAgICAgKnAgPSAnLSc7CisgICAgfSBlbHNlIHsKKyAgICAgICAgd2hpbGUgKCgqcCA9PSAnMCcpICYmICgqKHAgKyAxKSAhPSAwKSkgeyBwKys7IH0KKyAgICB9CisgICAgcmV0dXJuIHA7Cit9CisKK3N0YXRpYyBqc3RyaW5nIE5hdGl2ZUJOX0JOX2JuMmRlYyhKTklFbnYqIGVudiwgamNsYXNzLCBCSUdOVU0qIGEpIHsKKyAgICBpZiAoIW9uZVZhbGlkSGFuZGxlKGVudiwgYSkpIHJldHVybiBOVUxMOworICAgIGNoYXIqIHRtcFN0cjsKKyAgICBjaGFyKiByZXRTdHI7CisgICAgdG1wU3RyID0gQk5fYm4yZGVjKGEpOworICAgIGlmICh0bXBTdHIgIT0gTlVMTCkgeworICAgICAgICByZXRTdHIgPSBsZWFkaW5nWmVyb3NUcmltbWVkKHRtcFN0cik7CisgICAgICAgIGpzdHJpbmcgcmV0dXJuSlN0cmluZyA9IGVudi0+TmV3U3RyaW5nVVRGKHJldFN0cik7CisgICAgICAgIE9QRU5TU0xfZnJlZSh0bXBTdHIpOworICAgICAgICByZXR1cm4gcmV0dXJuSlN0cmluZzsKKyAgICB9CisgICAgZWxzZSByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIGpzdHJpbmcgTmF0aXZlQk5fQk5fYm4yaGV4KEpOSUVudiogZW52LCBqY2xhc3MsIEJJR05VTSogYSkgeworICAgIGlmICghb25lVmFsaWRIYW5kbGUoZW52LCBhKSkgcmV0dXJuIE5VTEw7CisgICAgY2hhciogdG1wU3RyOworICAgIGNoYXIqIHJldFN0cjsKKyAgICB0bXBTdHIgPSBCTl9ibjJoZXgoYSk7CisgICAgaWYgKHRtcFN0ciAhPSBOVUxMKSB7CisgICAgICAgIHJldFN0ciA9IGxlYWRpbmdaZXJvc1RyaW1tZWQodG1wU3RyKTsKKyAgICAgICAganN0cmluZyByZXR1cm5KU3RyaW5nID0gZW52LT5OZXdTdHJpbmdVVEYocmV0U3RyKTsKKyAgICAgICAgT1BFTlNTTF9mcmVlKHRtcFN0cik7CisgICAgICAgIHJldHVybiByZXR1cm5KU3RyaW5nOworICAgIH0KKyAgICBlbHNlIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgamJ5dGVBcnJheSBOYXRpdmVCTl9CTl9ibjJiaW4oSk5JRW52KiBlbnYsIGpjbGFzcywgQklHTlVNKiBhKSB7CisgICAgaWYgKCFvbmVWYWxpZEhhbmRsZShlbnYsIGEpKSByZXR1cm4gTlVMTDsKKyAgICBqYnl0ZUFycmF5IHJlc3VsdCA9IGVudi0+TmV3Qnl0ZUFycmF5KEJOX251bV9ieXRlcyhhKSk7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBTY29wZWRCeXRlQXJyYXlSVyBieXRlcyhlbnYsIHJlc3VsdCk7CisgICAgaWYgKGJ5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIEJOX2JuMmJpbihhLCByZWludGVycHJldF9jYXN0PHVuc2lnbmVkIGNoYXIqPihieXRlcy5nZXQoKSkpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBqaW50QXJyYXkgTmF0aXZlQk5fYm4ybGl0RW5kSW50cyhKTklFbnYqIGVudiwgamNsYXNzLCBCSUdOVU0qIGEpIHsKKyAgICBpZiAoIW9uZVZhbGlkSGFuZGxlKGVudiwgYSkpIHJldHVybiBOVUxMOworICAgIGJuX2NoZWNrX3RvcChhKTsKKyAgICBpbnQgbGVuID0gYS0+dG9wOworICAgIGlmIChsZW4gPT0gMCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgamludEFycmF5IHJlc3VsdCA9IGVudi0+TmV3SW50QXJyYXkobGVuKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFNjb3BlZEludEFycmF5UlcgaW50cyhlbnYsIHJlc3VsdCk7CisgICAgaWYgKGludHMuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgQk5fVUxPTkcqIHVsb25ncyA9IHJlaW50ZXJwcmV0X2Nhc3Q8Qk5fVUxPTkcqPihpbnRzLmdldCgpKTsKKyAgICBpZiAodWxvbmdzID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGludCBpID0gbGVuOyBkbyB7IGktLTsgdWxvbmdzW2ldID0gYS0+ZFtpXTsgfSB3aGlsZSAoaSA+IDApOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBpbnQgTmF0aXZlQk5fc2lnbihKTklFbnYqIGVudiwgamNsYXNzLCBCSUdOVU0qIGEpIHsKKyAgICBpZiAoIW9uZVZhbGlkSGFuZGxlKGVudiwgYSkpIHJldHVybiAtMjsKKyAgICBpZiAoQk5faXNfemVybyhhKSkgcmV0dXJuIDA7CisgICAgZWxzZSBpZiAoQk5faXNfbmVnYXRpdmUoYSkpIHJldHVybiAtMTsKKyAgICBlbHNlIHJldHVybiAxOworfQorCitzdGF0aWMgdm9pZCBOYXRpdmVCTl9CTl9zZXRfbmVnYXRpdmUoSk5JRW52KiBlbnYsIGpjbGFzcywgQklHTlVNKiBiLCBpbnQgbikgeworICAgIGlmICghb25lVmFsaWRIYW5kbGUoZW52LCBiKSkgcmV0dXJuOworICAgIEJOX3NldF9uZWdhdGl2ZShiLCBuKTsKK30KKworc3RhdGljIGludCBOYXRpdmVCTl9iaXRMZW5ndGgoSk5JRW52KiBlbnYsIGpjbGFzcywgQklHTlVNKiBhKSB7CisvLyBXZSByZWx5IG9uOiAoQk5fQklUUzIgPT0gMzIpLCBpLmUuIEJOX1VMT05HIGlzIHVuc2lnbmVkIGludCBhbmQgaGFzIDQgYnl0ZXM6CisvLworICAgIGlmICghb25lVmFsaWRIYW5kbGUoZW52LCBhKSkgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICBibl9jaGVja190b3AoYSk7CisgICAgaW50IGludExlbiA9IGEtPnRvcDsKKyAgICBpZiAoaW50TGVuID09IDApIHJldHVybiAwOworICAgIEJOX1VMT05HKiBkID0gYS0+ZDsKKyAgICBpbnQgaSA9IGludExlbiAtIDE7CisgICAgQk5fVUxPTkcgbXNkID0gZFtpXTsgLy8gbW9zdCBzaWduaWZpY2FudCBkaWdpdAorICAgICAgICBpZiAoYS0+bmVnKSB7CisgICAgICAgICAgICAvLyBIYW5kbGUgbmVnYXRpdmUgdmFsdWVzIGNvcnJlY3RseToKKyAgICAgICAgICAgIC8vIGkuZS4gZGVjcmVtZW50IHRoZSBtc2QgaWYgYWxsIG90aGVyIGRpZ2l0cyBhcmUgMDoKKyAgICAgICAgICAgIC8vIHdoaWxlICgoaSA+IDApICYmIChkW2ldICE9IDApKSB7IGktLTsgfQorICAgICAgICAgICAgZG8geyBpLS07IH0gd2hpbGUgKCEoKGkgPCAwKSB8fCAoZFtpXSAhPSAwKSkpOworICAgICAgICAgICAgaWYgKGkgPCAwKSBtc2QtLTsgLy8gT25seSBpZiBhbGwgbG93ZXIgc2lnbmlmaWNhbnQgZGlnaXRzIGFyZSAwIHdlIGRlY3JlbWVudCB0aGUgbW9zdCBzaWduaWZpY2FudCBvbmUuCisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChpbnRMZW4gLSAxKSAqIDMyICsgQk5fbnVtX2JpdHNfd29yZChtc2QpOworfQorCitzdGF0aWMgamJvb2xlYW4gTmF0aXZlQk5fQk5faXNfYml0X3NldChKTklFbnYqIGVudiwgamNsYXNzLCBCSUdOVU0qIGEsIGludCBuKSB7CisgICAgaWYgKCFvbmVWYWxpZEhhbmRsZShlbnYsIGEpKSByZXR1cm4gSk5JX0ZBTFNFOworICAgIHJldHVybiAoamJvb2xlYW4pQk5faXNfYml0X3NldChhLCBuKTsKK30KKworc3RhdGljIGpib29sZWFuIE5hdGl2ZUJOX21vZGlmeUJpdChKTklFbnYqIGVudiwgamNsYXNzLCBCSUdOVU0qIGEsIGludCBuLCBpbnQgb3ApIHsKKy8vIExPR0QoIk5hdGl2ZUJOX0JOX21vZGlmeUJpdCIpOworICAgIGlmICghb25lVmFsaWRIYW5kbGUoZW52LCBhKSkgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICBzd2l0Y2ggKG9wKSB7CisgICAgY2FzZSAxOiByZXR1cm4gQk5fc2V0X2JpdChhLCBuKTsKKyAgICBjYXNlIDA6IHJldHVybiBCTl9jbGVhcl9iaXQoYSwgbik7CisgICAgY2FzZSAtMToKKyAgICAgICAgaWYgKEJOX2lzX2JpdF9zZXQoYSwgbikpIHJldHVybiBCTl9jbGVhcl9iaXQoYSwgbik7CisgICAgICAgIGVsc2UgcmV0dXJuIEJOX3NldF9iaXQoYSwgbik7CisgICAgfQorICAgIHJldHVybiBKTklfRkFMU0U7Cit9CisKK3N0YXRpYyBqYm9vbGVhbiBOYXRpdmVCTl9CTl9zaGlmdChKTklFbnYqIGVudiwgamNsYXNzLCBCSUdOVU0qIHIsIEJJR05VTSogYSwgaW50IG4pIHsKKyAgICBpZiAoIXR3b1ZhbGlkSGFuZGxlcyhlbnYsIHIsIGEpKSByZXR1cm4gSk5JX0ZBTFNFOworICAgIHJldHVybiAobiA+PSAwKSA/IEJOX2xzaGlmdChyLCBhLCBuKSA6IEJOX3JzaGlmdChyLCBhLCAtbik7Cit9CisKK3N0YXRpYyBqYm9vbGVhbiBOYXRpdmVCTl9CTl9hZGRfd29yZChKTklFbnYqIGVudiwgamNsYXNzLCBCSUdOVU0qIGEsIEJOX1VMT05HIHcpIHsKKyAgICBpZiAoIW9uZVZhbGlkSGFuZGxlKGVudiwgYSkpIHJldHVybiBKTklfRkFMU0U7CisgICAgcmV0dXJuIEJOX2FkZF93b3JkKGEsIHcpOworfQorCitzdGF0aWMgamJvb2xlYW4gTmF0aXZlQk5fQk5fc3ViX3dvcmQoSk5JRW52KiBlbnYsIGpjbGFzcywgQklHTlVNKiBhLCBCTl9VTE9ORyB3KSB7CisgICAgaWYgKCFvbmVWYWxpZEhhbmRsZShlbnYsIGEpKSByZXR1cm4gSk5JX0ZBTFNFOworICAgIHJldHVybiBCTl9zdWJfd29yZChhLCB3KTsKK30KKworc3RhdGljIGpib29sZWFuIE5hdGl2ZUJOX0JOX211bF93b3JkKEpOSUVudiogZW52LCBqY2xhc3MsIEJJR05VTSogYSwgQk5fVUxPTkcgdykgeworICAgIGlmICghb25lVmFsaWRIYW5kbGUoZW52LCBhKSkgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICByZXR1cm4gQk5fbXVsX3dvcmQoYSwgdyk7Cit9CisKK3N0YXRpYyBCTl9VTE9ORyBOYXRpdmVCTl9CTl9kaXZfd29yZChKTklFbnYqIGVudiwgamNsYXNzLCBCSUdOVU0qIGEsIEJOX1VMT05HIHcpIHsKKyAgICBpZiAoIW9uZVZhbGlkSGFuZGxlKGVudiwgYSkpIHJldHVybiBKTklfRkFMU0U7CisgICAgcmV0dXJuIEJOX2Rpdl93b3JkKGEsIHcpOworfQorCitzdGF0aWMgQk5fVUxPTkcgTmF0aXZlQk5fQk5fbW9kX3dvcmQoSk5JRW52KiBlbnYsIGpjbGFzcywgQklHTlVNKiBhLCBCTl9VTE9ORyB3KSB7CisgICAgaWYgKCFvbmVWYWxpZEhhbmRsZShlbnYsIGEpKSByZXR1cm4gSk5JX0ZBTFNFOworICAgIHJldHVybiBCTl9tb2Rfd29yZChhLCB3KTsKK30KKworc3RhdGljIGpib29sZWFuIE5hdGl2ZUJOX0JOX2FkZChKTklFbnYqIGVudiwgamNsYXNzLCBCSUdOVU0qIHIsIEJJR05VTSogYSwgQklHTlVNKiBiKSB7CisgICAgaWYgKCF0aHJlZVZhbGlkSGFuZGxlcyhlbnYsIHIsIGEsIGIpKSByZXR1cm4gSk5JX0ZBTFNFOworICAgIHJldHVybiBCTl9hZGQociwgYSwgYik7Cit9CisKK3N0YXRpYyBqYm9vbGVhbiBOYXRpdmVCTl9CTl9zdWIoSk5JRW52KiBlbnYsIGpjbGFzcywgQklHTlVNKiByLCBCSUdOVU0qIGEsIEJJR05VTSogYikgeworICAgIGlmICghdGhyZWVWYWxpZEhhbmRsZXMoZW52LCByLCBhLCBiKSkgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICByZXR1cm4gQk5fc3ViKHIsIGEsIGIpOworfQorCitzdGF0aWMgamJvb2xlYW4gTmF0aXZlQk5fQk5fZ2NkKEpOSUVudiogZW52LCBqY2xhc3MsIEJJR05VTSogciwgQklHTlVNKiBhLCBCSUdOVU0qIGIpIHsKKyAgICBpZiAoIXRocmVlVmFsaWRIYW5kbGVzKGVudiwgciwgYSwgYikpIHJldHVybiBKTklfRkFMU0U7CisgICAgVW5pcXVlX0JOX0NUWCBjdHgoQk5fQ1RYX25ldygpKTsKKyAgICByZXR1cm4gQk5fZ2NkKHIsIGEsIGIsIGN0eC5nZXQoKSk7Cit9CisKK3N0YXRpYyBqYm9vbGVhbiBOYXRpdmVCTl9CTl9tdWwoSk5JRW52KiBlbnYsIGpjbGFzcywgQklHTlVNKiByLCBCSUdOVU0qIGEsIEJJR05VTSogYikgeworICAgIGlmICghdGhyZWVWYWxpZEhhbmRsZXMoZW52LCByLCBhLCBiKSkgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICBVbmlxdWVfQk5fQ1RYIGN0eChCTl9DVFhfbmV3KCkpOworICAgIHJldHVybiBCTl9tdWwociwgYSwgYiwgY3R4LmdldCgpKTsKK30KKworc3RhdGljIGpib29sZWFuIE5hdGl2ZUJOX0JOX2V4cChKTklFbnYqIGVudiwgamNsYXNzLCBCSUdOVU0qIHIsIEJJR05VTSogYSwgQklHTlVNKiBwKSB7CisgICAgaWYgKCF0aHJlZVZhbGlkSGFuZGxlcyhlbnYsIHIsIGEsIHApKSByZXR1cm4gSk5JX0ZBTFNFOworICAgIFVuaXF1ZV9CTl9DVFggY3R4KEJOX0NUWF9uZXcoKSk7CisgICAgcmV0dXJuIEJOX2V4cChyLCBhLCBwLCBjdHguZ2V0KCkpOworfQorCitzdGF0aWMgamJvb2xlYW4gTmF0aXZlQk5fQk5fZGl2KEpOSUVudiogZW52LCBqY2xhc3MsIEJJR05VTSogZHYsIEJJR05VTSogcmVtLCBCSUdOVU0qIG0sIEJJR05VTSogZCkgeworICAgIGlmICghZm91clZhbGlkSGFuZGxlcyhlbnYsIChyZW0gPyByZW0gOiBkdiksIChkdiA/IGR2IDogcmVtKSwgbSwgZCkpIHJldHVybiBKTklfRkFMU0U7CisgICAgVW5pcXVlX0JOX0NUWCBjdHgoQk5fQ1RYX25ldygpKTsKKyAgICByZXR1cm4gQk5fZGl2KGR2LCByZW0sIG0sIGQsIGN0eC5nZXQoKSk7Cit9CisKK3N0YXRpYyBqYm9vbGVhbiBOYXRpdmVCTl9CTl9ubm1vZChKTklFbnYqIGVudiwgamNsYXNzLCBCSUdOVU0qIHIsIEJJR05VTSogYSwgQklHTlVNKiBtKSB7CisgICAgaWYgKCF0aHJlZVZhbGlkSGFuZGxlcyhlbnYsIHIsIGEsIG0pKSByZXR1cm4gSk5JX0ZBTFNFOworICAgIFVuaXF1ZV9CTl9DVFggY3R4KEJOX0NUWF9uZXcoKSk7CisgICAgcmV0dXJuIEJOX25ubW9kKHIsIGEsIG0sIGN0eC5nZXQoKSk7Cit9CisKK3N0YXRpYyBqYm9vbGVhbiBOYXRpdmVCTl9CTl9tb2RfZXhwKEpOSUVudiogZW52LCBqY2xhc3MsIEJJR05VTSogciwgQklHTlVNKiBhLCBCSUdOVU0qIHAsIEJJR05VTSogbSkgeworICAgIGlmICghZm91clZhbGlkSGFuZGxlcyhlbnYsIHIsIGEsIHAsIG0pKSByZXR1cm4gSk5JX0ZBTFNFOworICAgIFVuaXF1ZV9CTl9DVFggY3R4KEJOX0NUWF9uZXcoKSk7CisgICAgcmV0dXJuIEJOX21vZF9leHAociwgYSwgcCwgbSwgY3R4LmdldCgpKTsKK30KKworc3RhdGljIGpib29sZWFuIE5hdGl2ZUJOX0JOX21vZF9pbnZlcnNlKEpOSUVudiogZW52LCBqY2xhc3MsIEJJR05VTSogcmV0LCBCSUdOVU0qIGEsIEJJR05VTSogbikgeworICAgIGlmICghdGhyZWVWYWxpZEhhbmRsZXMoZW52LCByZXQsIGEsIG4pKSByZXR1cm4gSk5JX0ZBTFNFOworICAgIFVuaXF1ZV9CTl9DVFggY3R4KEJOX0NUWF9uZXcoKSk7CisgICAgcmV0dXJuIChCTl9tb2RfaW52ZXJzZShyZXQsIGEsIG4sIGN0eC5nZXQoKSkgIT0gTlVMTCk7Cit9CisKK3N0YXRpYyBqYm9vbGVhbiBOYXRpdmVCTl9CTl9nZW5lcmF0ZV9wcmltZV9leChKTklFbnYqIGVudiwgamNsYXNzLCBCSUdOVU0qIHJldCwgaW50IGJpdHMsIGpib29sZWFuIHNhZmUsCisgICAgICAgIEJJR05VTSogYWRkLCBCSUdOVU0qIHJlbSwgamludCBjYikgeworICAgIGlmICghb25lVmFsaWRIYW5kbGUoZW52LCByZXQpKSByZXR1cm4gSk5JX0ZBTFNFOworICAgIHJldHVybiBCTl9nZW5lcmF0ZV9wcmltZV9leChyZXQsIGJpdHMsIHNhZmUsIGFkZCwgcmVtLCByZWludGVycHJldF9jYXN0PEJOX0dFTkNCKj4oY2IpKTsKK30KKworc3RhdGljIGpib29sZWFuIE5hdGl2ZUJOX0JOX2lzX3ByaW1lX2V4KEpOSUVudiogZW52LCBqY2xhc3MsIEJJR05VTSogcCwgaW50IG5jaGVja3MsIGppbnQgY2IpIHsKKyAgICBpZiAoIW9uZVZhbGlkSGFuZGxlKGVudiwgcCkpIHJldHVybiBKTklfRkFMU0U7CisgICAgVW5pcXVlX0JOX0NUWCBjdHgoQk5fQ1RYX25ldygpKTsKKyAgICByZXR1cm4gQk5faXNfcHJpbWVfZXgocCwgbmNoZWNrcywgY3R4LmdldCgpLCByZWludGVycHJldF9jYXN0PEJOX0dFTkNCKj4oY2IpKTsKK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBnTWV0aG9kc1tdID0geworICAgTkFUSVZFX01FVEhPRChOYXRpdmVCTiwgQk5fYWRkLCAiKElJSSlaIiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBCTl9hZGRfd29yZCwgIihJSSlaIiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBCTl9iaW4yYm4sICIoW0JJWkkpWiIpLAorICAgTkFUSVZFX01FVEhPRChOYXRpdmVCTiwgQk5fYm4yYmluLCAiKEkpW0IiKSwKKyAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQk4sIEJOX2JuMmRlYywgIihJKUxqYXZhL2xhbmcvU3RyaW5nOyIpLAorICAgTkFUSVZFX01FVEhPRChOYXRpdmVCTiwgQk5fYm4yaGV4LCAiKEkpTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBCTl9jbXAsICIoSUkpSSIpLAorICAgTkFUSVZFX01FVEhPRChOYXRpdmVCTiwgQk5fY29weSwgIihJSSlaIiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBCTl9kZWMyYm4sICIoSUxqYXZhL2xhbmcvU3RyaW5nOylJIiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBCTl9kaXYsICIoSUlJSSlaIiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBCTl9kaXZfd29yZCwgIihJSSlJIiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBCTl9leHAsICIoSUlJKVoiKSwKKyAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQk4sIEJOX2ZyZWUsICIoSSlWIiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBCTl9nY2QsICIoSUlJKVoiKSwKKyAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQk4sIEJOX2dlbmVyYXRlX3ByaW1lX2V4LCAiKElJWklJSSlaIiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBCTl9oZXgyYm4sICIoSUxqYXZhL2xhbmcvU3RyaW5nOylJIiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBCTl9pc19iaXRfc2V0LCAiKElJKVoiKSwKKyAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQk4sIEJOX2lzX3ByaW1lX2V4LCAiKElJSSlaIiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBCTl9tb2RfZXhwLCAiKElJSUkpWiIpLAorICAgTkFUSVZFX01FVEhPRChOYXRpdmVCTiwgQk5fbW9kX2ludmVyc2UsICIoSUlJKVoiKSwKKyAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQk4sIEJOX21vZF93b3JkLCAiKElJKUkiKSwKKyAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQk4sIEJOX211bCwgIihJSUkpWiIpLAorICAgTkFUSVZFX01FVEhPRChOYXRpdmVCTiwgQk5fbXVsX3dvcmQsICIoSUkpWiIpLAorICAgTkFUSVZFX01FVEhPRChOYXRpdmVCTiwgQk5fbmV3LCAiKClJIiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBCTl9ubm1vZCwgIihJSUkpWiIpLAorICAgTkFUSVZFX01FVEhPRChOYXRpdmVCTiwgQk5fc2V0X25lZ2F0aXZlLCAiKElJKVYiKSwKKyAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQk4sIEJOX3NoaWZ0LCAiKElJSSlaIiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBCTl9zdWIsICIoSUlJKVoiKSwKKyAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQk4sIEJOX3N1Yl93b3JkLCAiKElJKVoiKSwKKyAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQk4sIEVSUl9lcnJvcl9zdHJpbmcsICIoSSlMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQk4sIEVSUl9nZXRfZXJyb3IsICIoKUkiKSwKKyAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQk4sIGJpdExlbmd0aCwgIihJKUkiKSwKKyAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQk4sIGJuMmxpdEVuZEludHMsICIoSSlbSSIpLAorICAgTkFUSVZFX01FVEhPRChOYXRpdmVCTiwgbGl0RW5kSW50czJibiwgIihbSUlaSSlaIiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBsb25nSW50LCAiKEkpSiIpLAorICAgTkFUSVZFX01FVEhPRChOYXRpdmVCTiwgbW9kaWZ5Qml0LCAiKElJSSlaIiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBwdXRMb25nSW50LCAiKElKKVoiKSwKKyAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQk4sIHB1dFVMb25nSW50LCAiKElKWilaIiksCisgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJOLCBzaWduLCAiKEkpSSIpLAorICAgTkFUSVZFX01FVEhPRChOYXRpdmVCTiwgdHdvc0NvbXAyYm4sICIoW0JJSSlaIiksCit9OworaW50IHJlZ2lzdGVyX2phdmFfbWF0aF9OYXRpdmVCTihKTklFbnYqIGVudikgeworICAgIHJldHVybiBqbmlSZWdpc3Rlck5hdGl2ZU1ldGhvZHMoZW52LCAiamF2YS9tYXRoL05hdGl2ZUJOIiwgZ01ldGhvZHMsIE5FTEVNKGdNZXRob2RzKSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX25pb19CeXRlT3JkZXIuY3BwIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV9uaW9fQnl0ZU9yZGVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMTY5NWE5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV9uaW9fQnl0ZU9yZGVyLmNwcApAQCAtMCwwICsxLDMyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJCeXRlT3JkZXIiCisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisKK3N0YXRpYyBqYm9vbGVhbiBCeXRlT3JkZXJfaXNMaXR0bGVFbmRpYW4oSk5JRW52KiwgamNsYXNzKSB7CisgICAgaW50IGkgPSAxOworICAgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxqYnl0ZSo+KCZpKSA9PSAxOworfQorCitzdGF0aWMgSk5JTmF0aXZlTWV0aG9kIGdNZXRob2RzW10gPSB7CisgICAgTkFUSVZFX01FVEhPRChCeXRlT3JkZXIsIGlzTGl0dGxlRW5kaWFuLCAiISgpWiIpLAorfTsKK2ludCByZWdpc3Rlcl9qYXZhX25pb19CeXRlT3JkZXIoSk5JRW52KiBlbnYpIHsKKyAgICByZXR1cm4gam5pUmVnaXN0ZXJOYXRpdmVNZXRob2RzKGVudiwgImphdmEvbmlvL0J5dGVPcmRlciIsIGdNZXRob2RzLCBORUxFTShnTWV0aG9kcykpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV9uaW9fY2hhcnNldF9DaGFyc2V0cy5jcHAgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX25pb19jaGFyc2V0X0NoYXJzZXRzLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMjQyMmZlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV9uaW9fY2hhcnNldF9DaGFyc2V0cy5jcHAKQEAgLTAsMCArMSwyNTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIlN0cmluZyIKKworI2luY2x1ZGUgIkpOSUhlbHAuaCIKKyNpbmNsdWRlICJKbmlDb25zdGFudHMuaCIKKyNpbmNsdWRlICJTY29wZWRQcmltaXRpdmVBcnJheS5oIgorI2luY2x1ZGUgImpuaS5oIgorI2luY2x1ZGUgInVuaWNvZGUvdXRmMTYuaCIKKworI2luY2x1ZGUgPHN0cmluZy5oPgorCisvKioKKyAqIEFwcHJveGltYXRlcyBqYXZhLmxhbmcuVW5zYWZlQnl0ZVNlcXVlbmNlIHNvIHdlIGRvbid0IGhhdmUgdG8gcGF5IHRoZSBjb3N0IG9mIGNhbGxpbmcgYmFjayBpbnRvCisgKiBKYXZhIHdoZW4gY29udmVydGluZyBhIGNoYXJbXSB0byBhIFVURi04IGJ5dGVbXS4gVGhpcyBsZXRzIHVzIGhhdmUgVVRGLTggY29udmVyc2lvbnMgc2xpZ2h0bHkKKyAqIGZhc3RlciB0aGFuIElDVSBmb3IgbGFyZ2UgY2hhcltdcyB3aXRob3V0IHBheWluZyBmb3IgdGhlIE5JTyBvdmVyaGVhZCB3aXRoIHNtYWxsIGNoYXJbXXMuCisgKgorICogV2UgY291bGQgYXZvaWQgdGhpcyBieSBrZWVwaW5nIHRoZSBVVEYtOCBieXRlcyBvbiB0aGUgbmF0aXZlIGhlYXAgdW50aWwgd2UncmUgZG9uZSBhbmQgb25seQorICogY3JlYXRpbmcgYSBieXRlW10gb24gdGhlIEphdmEgaGVhcCB3aGVuIHdlIGtub3cgaG93IGJpZyBpdCBuZWVkcyB0byBiZSwgYnV0IG9uZSBzaG91bGRuJ3QgbGllCisgKiB0byB0aGUgZ2FyYmFnZSBjb2xsZWN0b3IgKG5vciBoaWRlIHBvdGVudGlhbGx5IGxhcmdlIGFsbG9jYXRpb25zIGZyb20gaXQpLgorICoKKyAqIEJlY2F1c2UgYSBjYWxsIHRvIGFwcGVuZCBtaWdodCByZXF1aXJlIGFuIGFsbG9jYXRpb24sIGl0IG1pZ2h0IGZhaWwuIENhbGxlcnMgc2hvdWxkIGFsd2F5cworICogY2hlY2sgdGhlIHJldHVybiB2YWx1ZSBvZiBhcHBlbmQuCisgKi8KK2NsYXNzIE5hdGl2ZVVuc2FmZUJ5dGVTZXF1ZW5jZSB7CitwdWJsaWM6CisgICAgTmF0aXZlVW5zYWZlQnl0ZVNlcXVlbmNlKEpOSUVudiogZW52KQorICAgICAgICA6IG1FbnYoZW52KSwgbUphdmFBcnJheShOVUxMKSwgbVJhd0FycmF5KE5VTEwpLCBtU2l6ZSgtMSksIG1PZmZzZXQoMCkKKyAgICB7CisgICAgfQorCisgICAgfk5hdGl2ZVVuc2FmZUJ5dGVTZXF1ZW5jZSgpIHsKKyAgICAgICAgLy8gUmVsZWFzZSBvdXIgcG9pbnRlciB0byB0aGUgcmF3IGFycmF5LCBjb3B5aW5nIGNoYW5nZXMgYmFjayB0byB0aGUgSmF2YSBoZWFwLgorICAgICAgICBpZiAobVJhd0FycmF5ICE9IE5VTEwpIHsKKyAgICAgICAgICAgIG1FbnYtPlJlbGVhc2VCeXRlQXJyYXlFbGVtZW50cyhtSmF2YUFycmF5LCBtUmF3QXJyYXksIDApOworICAgICAgICB9CisgICAgfQorCisgICAgYm9vbCBhcHBlbmQoamJ5dGUgYikgeworICAgICAgICBpZiAobU9mZnNldCA9PSBtU2l6ZSAmJiAhcmVzaXplKG1TaXplICogMikpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBtUmF3QXJyYXlbbU9mZnNldCsrXSA9IGI7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIGJvb2wgcmVzaXplKGludCBuZXdTaXplKSB7CisgICAgICAgIGlmIChuZXdTaXplID09IG1TaXplKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEFsbG9jYXRlIGEgbmV3IGFycmF5LgorICAgICAgICBqYnl0ZUFycmF5IG5ld0phdmFBcnJheSA9IG1FbnYtPk5ld0J5dGVBcnJheShuZXdTaXplKTsKKyAgICAgICAgaWYgKG5ld0phdmFBcnJheSA9PSBOVUxMKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgamJ5dGUqIG5ld1Jhd0FycmF5ID0gbUVudi0+R2V0Qnl0ZUFycmF5RWxlbWVudHMobmV3SmF2YUFycmF5LCBOVUxMKTsKKyAgICAgICAgaWYgKG5ld1Jhd0FycmF5ID09IE5VTEwpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIENvcHkgZGF0YSBvdXQgb2YgdGhlIG9sZCBhcnJheSBhbmQgdGhlbiBsZXQgZ28gb2YgaXQuCisgICAgICAgIC8vIE5vdGUgdGhhdCB3ZSBtYXkgYmUgdHJpbW1pbmcgdGhlIGFycmF5LgorICAgICAgICBpZiAobVJhd0FycmF5ICE9IE5VTEwpIHsKKyAgICAgICAgICAgIG1lbWNweShuZXdSYXdBcnJheSwgbVJhd0FycmF5LCBtT2Zmc2V0KTsKKyAgICAgICAgICAgIG1FbnYtPlJlbGVhc2VCeXRlQXJyYXlFbGVtZW50cyhtSmF2YUFycmF5LCBtUmF3QXJyYXksIEpOSV9BQk9SVCk7CisgICAgICAgICAgICBtRW52LT5EZWxldGVMb2NhbFJlZihtSmF2YUFycmF5KTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFBvaW50IG91cnNlbHZlcyBhdCB0aGUgbmV3IGFycmF5LgorICAgICAgICBtSmF2YUFycmF5ID0gbmV3SmF2YUFycmF5OworICAgICAgICBtUmF3QXJyYXkgPSBuZXdSYXdBcnJheTsKKyAgICAgICAgbVNpemUgPSBuZXdTaXplOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBqYnl0ZUFycmF5IHRvQnl0ZUFycmF5KCkgeworICAgICAgICAvLyBUcmltIGFueSB1bnVzZWQgc3BhY2UsIGlmIG5lY2Vzc2FyeS4KKyAgICAgICAgYm9vbCBva2F5ID0gcmVzaXplKG1PZmZzZXQpOworICAgICAgICByZXR1cm4gb2theSA/IG1KYXZhQXJyYXkgOiBOVUxMOworICAgIH0KKworcHJpdmF0ZToKKyAgICBKTklFbnYqIG1FbnY7CisgICAgamJ5dGVBcnJheSBtSmF2YUFycmF5OworICAgIGpieXRlKiBtUmF3QXJyYXk7CisgICAgamludCBtU2l6ZTsKKyAgICBqaW50IG1PZmZzZXQ7CisKKyAgICAvLyBEaXNhbGxvdyBjb3B5IGFuZCBhc3NpZ25tZW50LgorICAgIE5hdGl2ZVVuc2FmZUJ5dGVTZXF1ZW5jZShjb25zdCBOYXRpdmVVbnNhZmVCeXRlU2VxdWVuY2UmKTsKKyAgICB2b2lkIG9wZXJhdG9yPShjb25zdCBOYXRpdmVVbnNhZmVCeXRlU2VxdWVuY2UmKTsKK307CisKK3N0YXRpYyB2b2lkIENoYXJzZXRzX2FzY2lpQnl0ZXNUb0NoYXJzKEpOSUVudiogZW52LCBqY2xhc3MsIGpieXRlQXJyYXkgamF2YUJ5dGVzLCBqaW50IG9mZnNldCwgamludCBsZW5ndGgsIGpjaGFyQXJyYXkgamF2YUNoYXJzKSB7CisgICAgU2NvcGVkQnl0ZUFycmF5Uk8gYnl0ZXMoZW52LCBqYXZhQnl0ZXMpOworICAgIGlmIChieXRlcy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgU2NvcGVkQ2hhckFycmF5UlcgY2hhcnMoZW52LCBqYXZhQ2hhcnMpOworICAgIGlmIChjaGFycy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBjb25zdCBqYnl0ZSogc3JjID0gJmJ5dGVzW29mZnNldF07CisgICAgamNoYXIqIGRzdCA9ICZjaGFyc1swXTsKKyAgICBzdGF0aWMgY29uc3QgamNoYXIgUkVQTEFDRU1FTlRfQ0hBUiA9IDB4ZmZmZDsKKyAgICBmb3IgKGludCBpID0gbGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHsKKyAgICAgICAgamNoYXIgY2ggPSBzdGF0aWNfY2FzdDxqY2hhcj4oKnNyYysrICYgMHhmZik7CisgICAgICAgICpkc3QrKyA9IChjaCA8PSAweDdmKSA/IGNoIDogUkVQTEFDRU1FTlRfQ0hBUjsKKyAgICB9Cit9CisKK3N0YXRpYyB2b2lkIENoYXJzZXRzX2lzb0xhdGluMUJ5dGVzVG9DaGFycyhKTklFbnYqIGVudiwgamNsYXNzLCBqYnl0ZUFycmF5IGphdmFCeXRlcywgamludCBvZmZzZXQsIGppbnQgbGVuZ3RoLCBqY2hhckFycmF5IGphdmFDaGFycykgeworICAgIFNjb3BlZEJ5dGVBcnJheVJPIGJ5dGVzKGVudiwgamF2YUJ5dGVzKTsKKyAgICBpZiAoYnl0ZXMuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm47CisgICAgfQorICAgIFNjb3BlZENoYXJBcnJheVJXIGNoYXJzKGVudiwgamF2YUNoYXJzKTsKKyAgICBpZiAoY2hhcnMuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgY29uc3QgamJ5dGUqIHNyYyA9ICZieXRlc1tvZmZzZXRdOworICAgIGpjaGFyKiBkc3QgPSAmY2hhcnNbMF07CisgICAgZm9yIChpbnQgaSA9IGxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7CisgICAgICAgICpkc3QrKyA9IHN0YXRpY19jYXN0PGpjaGFyPigqc3JjKysgJiAweGZmKTsKKyAgICB9Cit9CisKKy8qKgorICogVHJhbnNsYXRlcyB0aGUgZ2l2ZW4gY2hhcmFjdGVycyB0byBVUy1BU0NJSSBvciBJU08tODg1OS0xIGJ5dGVzLCB1c2luZyB0aGUgZmFjdCB0aGF0CisgKiBVbmljb2RlIGNvZGUgcG9pbnRzIGJldHdlZW4gVSswMDAwIGFuZCBVKzAwN2YgaW5jbHVzaXZlIGFyZSBpZGVudGljYWwgdG8gVVMtQVNDSUksIHdoaWxlCisgKiBVKzAwMDAgdG8gVSswMGZmIGluY2x1c2l2ZSBhcmUgaWRlbnRpY2FsIHRvIElTTy04ODU5LTEuCisgKi8KK3N0YXRpYyBqYnl0ZUFycmF5IGNoYXJzVG9CeXRlcyhKTklFbnYqIGVudiwgamNoYXJBcnJheSBqYXZhQ2hhcnMsIGppbnQgb2Zmc2V0LCBqaW50IGxlbmd0aCwgamNoYXIgbWF4VmFsaWRDaGFyKSB7CisgICAgU2NvcGVkQ2hhckFycmF5Uk8gY2hhcnMoZW52LCBqYXZhQ2hhcnMpOworICAgIGlmIChjaGFycy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGpieXRlQXJyYXkgamF2YUJ5dGVzID0gZW52LT5OZXdCeXRlQXJyYXkobGVuZ3RoKTsKKyAgICBTY29wZWRCeXRlQXJyYXlSVyBieXRlcyhlbnYsIGphdmFCeXRlcyk7CisgICAgaWYgKGJ5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgY29uc3QgamNoYXIqIHNyYyA9ICZjaGFyc1tvZmZzZXRdOworICAgIGpieXRlKiBkc3QgPSAmYnl0ZXNbMF07CisgICAgZm9yIChpbnQgaSA9IGxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7CisgICAgICAgIGpjaGFyIGNoID0gKnNyYysrOworICAgICAgICBpZiAoY2ggPiBtYXhWYWxpZENoYXIpIHsKKyAgICAgICAgICAgIGNoID0gJz8nOworICAgICAgICB9CisgICAgICAgICpkc3QrKyA9IHN0YXRpY19jYXN0PGpieXRlPihjaCk7CisgICAgfQorCisgICAgcmV0dXJuIGphdmFCeXRlczsKK30KKworc3RhdGljIGpieXRlQXJyYXkgQ2hhcnNldHNfdG9Bc2NpaUJ5dGVzKEpOSUVudiogZW52LCBqY2xhc3MsIGpjaGFyQXJyYXkgamF2YUNoYXJzLCBqaW50IG9mZnNldCwgamludCBsZW5ndGgpIHsKKyAgICByZXR1cm4gY2hhcnNUb0J5dGVzKGVudiwgamF2YUNoYXJzLCBvZmZzZXQsIGxlbmd0aCwgMHg3Zik7Cit9CisKK3N0YXRpYyBqYnl0ZUFycmF5IENoYXJzZXRzX3RvSXNvTGF0aW4xQnl0ZXMoSk5JRW52KiBlbnYsIGpjbGFzcywgamNoYXJBcnJheSBqYXZhQ2hhcnMsIGppbnQgb2Zmc2V0LCBqaW50IGxlbmd0aCkgeworICAgIHJldHVybiBjaGFyc1RvQnl0ZXMoZW52LCBqYXZhQ2hhcnMsIG9mZnNldCwgbGVuZ3RoLCAweGZmKTsKK30KKworc3RhdGljIGpieXRlQXJyYXkgQ2hhcnNldHNfdG9VdGY4Qnl0ZXMoSk5JRW52KiBlbnYsIGpjbGFzcywgamNoYXJBcnJheSBqYXZhQ2hhcnMsIGppbnQgb2Zmc2V0LCBqaW50IGxlbmd0aCkgeworICAgIFNjb3BlZENoYXJBcnJheVJPIGNoYXJzKGVudiwgamF2YUNoYXJzKTsKKyAgICBpZiAoY2hhcnMuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBOYXRpdmVVbnNhZmVCeXRlU2VxdWVuY2Ugb3V0KGVudik7CisgICAgaWYgKCFvdXQucmVzaXplKGxlbmd0aCkpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgY29uc3QgaW50IGVuZCA9IG9mZnNldCArIGxlbmd0aDsKKyAgICBmb3IgKGludCBpID0gb2Zmc2V0OyBpIDwgZW5kOyArK2kpIHsKKyAgICAgICAgamludCBjaCA9IGNoYXJzW2ldOworICAgICAgICBpZiAoY2ggPCAweDgwKSB7CisgICAgICAgICAgICAvLyBPbmUgYnl0ZS4KKyAgICAgICAgICAgIGlmICghb3V0LmFwcGVuZChjaCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChjaCA8IDB4ODAwKSB7CisgICAgICAgICAgICAvLyBUd28gYnl0ZXMuCisgICAgICAgICAgICBpZiAoIW91dC5hcHBlbmQoKGNoID4+IDYpIHwgMHhjMCkgfHwgIW91dC5hcHBlbmQoKGNoICYgMHgzZikgfCAweDgwKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKFUxNl9JU19TVVJST0dBVEUoY2gpKSB7CisgICAgICAgICAgICAvLyBBIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyLgorICAgICAgICAgICAgamNoYXIgaGlnaCA9IChqY2hhcikgY2g7CisgICAgICAgICAgICBqY2hhciBsb3cgPSAoaSArIDEgIT0gZW5kKSA/IGNoYXJzW2kgKyAxXSA6IDA7CisgICAgICAgICAgICBpZiAoIVUxNl9JU19TVVJST0dBVEVfTEVBRChoaWdoKSB8fCAhVTE2X0lTX1NVUlJPR0FURV9UUkFJTChsb3cpKSB7CisgICAgICAgICAgICAgICAgaWYgKCFvdXQuYXBwZW5kKCc/JykpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gTm93IHdlIGtub3cgd2UgaGF2ZSBhICp2YWxpZCogc3Vycm9nYXRlIHBhaXIsIHdlIGNhbiBjb25zdW1lIHRoZSBsb3cgc3Vycm9nYXRlLgorICAgICAgICAgICAgKytpOworICAgICAgICAgICAgY2ggPSBVMTZfR0VUX1NVUFBMRU1FTlRBUlkoaGlnaCwgbG93KTsKKyAgICAgICAgICAgIC8vIEZvdXIgYnl0ZXMuCisgICAgICAgICAgICBqYnl0ZSBiMSA9IChjaCA+PiAxOCkgfCAweGYwOworICAgICAgICAgICAgamJ5dGUgYjIgPSAoKGNoID4+IDEyKSAmIDB4M2YpIHwgMHg4MDsKKyAgICAgICAgICAgIGpieXRlIGIzID0gKChjaCA+PiA2KSAmIDB4M2YpIHwgMHg4MDsKKyAgICAgICAgICAgIGpieXRlIGI0ID0gKGNoICYgMHgzZikgfCAweDgwOworICAgICAgICAgICAgaWYgKCFvdXQuYXBwZW5kKGIxKSB8fCAhb3V0LmFwcGVuZChiMikgfHwgIW91dC5hcHBlbmQoYjMpIHx8ICFvdXQuYXBwZW5kKGI0KSkgeworICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gVGhyZWUgYnl0ZXMuCisgICAgICAgICAgICBqYnl0ZSBiMSA9IChjaCA+PiAxMikgfCAweGUwOworICAgICAgICAgICAgamJ5dGUgYjIgPSAoKGNoID4+IDYpICYgMHgzZikgfCAweDgwOworICAgICAgICAgICAgamJ5dGUgYjMgPSAoY2ggJiAweDNmKSB8IDB4ODA7CisgICAgICAgICAgICBpZiAoIW91dC5hcHBlbmQoYjEpIHx8ICFvdXQuYXBwZW5kKGIyKSB8fCAhb3V0LmFwcGVuZChiMykpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gb3V0LnRvQnl0ZUFycmF5KCk7Cit9CisKK3N0YXRpYyBKTklOYXRpdmVNZXRob2QgZ01ldGhvZHNbXSA9IHsKKyAgICBOQVRJVkVfTUVUSE9EKENoYXJzZXRzLCBhc2NpaUJ5dGVzVG9DaGFycywgIihbQklJW0MpViIpLAorICAgIE5BVElWRV9NRVRIT0QoQ2hhcnNldHMsIGlzb0xhdGluMUJ5dGVzVG9DaGFycywgIihbQklJW0MpViIpLAorICAgIE5BVElWRV9NRVRIT0QoQ2hhcnNldHMsIHRvQXNjaWlCeXRlcywgIihbQ0lJKVtCIiksCisgICAgTkFUSVZFX01FVEhPRChDaGFyc2V0cywgdG9Jc29MYXRpbjFCeXRlcywgIihbQ0lJKVtCIiksCisgICAgTkFUSVZFX01FVEhPRChDaGFyc2V0cywgdG9VdGY4Qnl0ZXMsICIoW0NJSSlbQiIpLAorfTsKK2ludCByZWdpc3Rlcl9qYXZhX25pb19jaGFyc2V0X0NoYXJzZXRzKEpOSUVudiogZW52KSB7CisgICAgcmV0dXJuIGpuaVJlZ2lzdGVyTmF0aXZlTWV0aG9kcyhlbnYsICJqYXZhL25pby9jaGFyc2V0L0NoYXJzZXRzIiwgZ01ldGhvZHMsIE5FTEVNKGdNZXRob2RzKSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX3RleHRfQmlkaS5jcHAgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX3RleHRfQmlkaS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjdkM2RkYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfdGV4dF9CaWRpLmNwcApAQCAtMCwwICsxLDE5MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiQmlkaSIKKworI2luY2x1ZGUgIkpOSUhlbHAuaCIKKyNpbmNsdWRlICJKbmlDb25zdGFudHMuaCIKKyNpbmNsdWRlICJKbmlFeGNlcHRpb24uaCIKKyNpbmNsdWRlICJTY29wZWRQcmltaXRpdmVBcnJheS5oIgorI2luY2x1ZGUgIlVuaXF1ZVB0ci5oIgorI2luY2x1ZGUgInVuaWNvZGUvdWJpZGkuaCIKKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorCitzdHJ1Y3QgQmlEaURhdGEgeworICAgIEJpRGlEYXRhKFVCaURpKiBiaURpKSA6IG1CaURpKGJpRGkpLCBtRW1iZWRkaW5nTGV2ZWxzKE5VTEwpIHsKKyAgICB9CisKKyAgICB+QmlEaURhdGEoKSB7CisgICAgICAgIHViaWRpX2Nsb3NlKG1CaURpKTsKKyAgICB9CisKKyAgICBVQmlEaUxldmVsKiBlbWJlZGRpbmdMZXZlbHMoKSB7CisgICAgICAgIHJldHVybiByZWludGVycHJldF9jYXN0PFVCaURpTGV2ZWwqPigmbUVtYmVkZGluZ0xldmVsc1swXSk7CisgICAgfQorCisgICAgdm9pZCBzZXRFbWJlZGRpbmdMZXZlbHMoamJ5dGUqIG5ld0VtYmVkZGluZ0xldmVscykgeworICAgICAgICBtRW1iZWRkaW5nTGV2ZWxzLnJlc2V0KG5ld0VtYmVkZGluZ0xldmVscyk7CisgICAgfQorCisgICAgVUJpRGkqIHVCaURpKCkgeworICAgICAgICByZXR1cm4gbUJpRGk7CisgICAgfQorCitwcml2YXRlOgorICAgIFVCaURpKiBtQmlEaTsKKyAgICBVbmlxdWVQdHI8amJ5dGVbXT4gbUVtYmVkZGluZ0xldmVsczsKKworICAgIC8vIERpc2FsbG93IGNvcHkgYW5kIGFzc2lnbm1lbnQuCisgICAgQmlEaURhdGEoY29uc3QgQmlEaURhdGEmKTsKKyAgICB2b2lkIG9wZXJhdG9yPShjb25zdCBCaURpRGF0YSYpOworfTsKKworc3RhdGljIEJpRGlEYXRhKiBiaURpRGF0YShqbG9uZyBwdHIpIHsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxCaURpRGF0YSo+KHN0YXRpY19jYXN0PHVpbnRwdHJfdD4ocHRyKSk7Cit9CisKK3N0YXRpYyBVQmlEaSogdUJpRGkoamxvbmcgcHRyKSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8QmlEaURhdGEqPihzdGF0aWNfY2FzdDx1aW50cHRyX3Q+KHB0cikpLT51QmlEaSgpOworfQorCitzdGF0aWMgamxvbmcgQmlkaV91YmlkaV9vcGVuKEpOSUVudiosIGpjbGFzcykgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PHVpbnRwdHJfdD4obmV3IEJpRGlEYXRhKHViaWRpX29wZW4oKSkpOworfQorCitzdGF0aWMgdm9pZCBCaWRpX3ViaWRpX2Nsb3NlKEpOSUVudiosIGpjbGFzcywgamxvbmcgcHRyKSB7CisgICAgZGVsZXRlIGJpRGlEYXRhKHB0cik7Cit9CisKK3N0YXRpYyB2b2lkIEJpZGlfdWJpZGlfc2V0UGFyYShKTklFbnYqIGVudiwgamNsYXNzLCBqbG9uZyBwdHIsIGpjaGFyQXJyYXkgdGV4dCwgamludCBsZW5ndGgsIGppbnQgcGFyYUxldmVsLCBqYnl0ZUFycmF5IG5ld0VtYmVkZGluZ0xldmVscykgeworICAgIEJpRGlEYXRhKiBkYXRhID0gYmlEaURhdGEocHRyKTsKKyAgICAvLyBDb3B5IHRoZSBuZXcgZW1iZWRkaW5nIGxldmVscyBmcm9tIHRoZSBKYXZhIGhlYXAgdG8gdGhlIG5hdGl2ZSBoZWFwLgorICAgIGlmIChuZXdFbWJlZGRpbmdMZXZlbHMgIT0gTlVMTCkgeworICAgICAgICBqYnl0ZSogZHN0OworICAgICAgICBkYXRhLT5zZXRFbWJlZGRpbmdMZXZlbHMoZHN0ID0gbmV3IGpieXRlW2xlbmd0aF0pOworICAgICAgICBlbnYtPkdldEJ5dGVBcnJheVJlZ2lvbihuZXdFbWJlZGRpbmdMZXZlbHMsIDAsIGxlbmd0aCwgZHN0KTsKKyAgICB9IGVsc2UgeworICAgICAgICBkYXRhLT5zZXRFbWJlZGRpbmdMZXZlbHMoTlVMTCk7CisgICAgfQorICAgIFNjb3BlZENoYXJBcnJheVJPIGNoYXJzKGVudiwgdGV4dCk7CisgICAgaWYgKGNoYXJzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBVRXJyb3JDb2RlIGVyciA9IFVfWkVST19FUlJPUjsKKyAgICB1YmlkaV9zZXRQYXJhKGRhdGEtPnVCaURpKCksIGNoYXJzLmdldCgpLCBsZW5ndGgsIHBhcmFMZXZlbCwgZGF0YS0+ZW1iZWRkaW5nTGV2ZWxzKCksICZlcnIpOworICAgIG1heWJlVGhyb3dJY3VFeGNlcHRpb24oZW52LCBlcnIpOworfQorCitzdGF0aWMgamxvbmcgQmlkaV91YmlkaV9zZXRMaW5lKEpOSUVudiogZW52LCBqY2xhc3MsIGpsb25nIHB0ciwgamludCBzdGFydCwgamludCBsaW1pdCkgeworICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworICAgIFVCaURpKiBzaXplZCA9IHViaWRpX29wZW5TaXplZChsaW1pdCAtIHN0YXJ0LCAwLCAmc3RhdHVzKTsKKyAgICBpZiAobWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihlbnYsIHN0YXR1cykpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIFVuaXF1ZVB0cjxCaURpRGF0YT4gbGluZURhdGEobmV3IEJpRGlEYXRhKHNpemVkKSk7CisgICAgdWJpZGlfc2V0TGluZSh1QmlEaShwdHIpLCBzdGFydCwgbGltaXQsIGxpbmVEYXRhLT51QmlEaSgpLCAmc3RhdHVzKTsKKyAgICBtYXliZVRocm93SWN1RXhjZXB0aW9uKGVudiwgc3RhdHVzKTsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDx1aW50cHRyX3Q+KGxpbmVEYXRhLnJlbGVhc2UoKSk7Cit9CisKK3N0YXRpYyBqaW50IEJpZGlfdWJpZGlfZ2V0RGlyZWN0aW9uKEpOSUVudiosIGpjbGFzcywgamxvbmcgcHRyKSB7CisgICAgcmV0dXJuIHViaWRpX2dldERpcmVjdGlvbih1QmlEaShwdHIpKTsKK30KKworc3RhdGljIGppbnQgQmlkaV91YmlkaV9nZXRMZW5ndGgoSk5JRW52KiwgamNsYXNzLCBqbG9uZyBwdHIpIHsKKyAgICByZXR1cm4gdWJpZGlfZ2V0TGVuZ3RoKHVCaURpKHB0cikpOworfQorCitzdGF0aWMgamJ5dGUgQmlkaV91YmlkaV9nZXRQYXJhTGV2ZWwoSk5JRW52KiwgamNsYXNzLCBqbG9uZyBwdHIpIHsKKyAgICByZXR1cm4gdWJpZGlfZ2V0UGFyYUxldmVsKHVCaURpKHB0cikpOworfQorCitzdGF0aWMgamJ5dGVBcnJheSBCaWRpX3ViaWRpX2dldExldmVscyhKTklFbnYqIGVudiwgamNsYXNzLCBqbG9uZyBwdHIpIHsKKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBjb25zdCBVQmlEaUxldmVsKiBsZXZlbHMgPSB1YmlkaV9nZXRMZXZlbHModUJpRGkocHRyKSwgJnN0YXR1cyk7CisgICAgaWYgKG1heWJlVGhyb3dJY3VFeGNlcHRpb24oZW52LCBzdGF0dXMpKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpbnQgbGVuID0gdWJpZGlfZ2V0TGVuZ3RoKHVCaURpKHB0cikpOworICAgIGpieXRlQXJyYXkgcmVzdWx0ID0gZW52LT5OZXdCeXRlQXJyYXkobGVuKTsKKyAgICBlbnYtPlNldEJ5dGVBcnJheVJlZ2lvbihyZXN1bHQsIDAsIGxlbiwgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBqYnl0ZSo+KGxldmVscykpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBqaW50IEJpZGlfdWJpZGlfY291bnRSdW5zKEpOSUVudiogZW52LCBqY2xhc3MsIGpsb25nIHB0cikgeworICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworICAgIGludCBjb3VudCA9IHViaWRpX2NvdW50UnVucyh1QmlEaShwdHIpLCAmc3RhdHVzKTsKKyAgICBtYXliZVRocm93SWN1RXhjZXB0aW9uKGVudiwgc3RhdHVzKTsKKyAgICByZXR1cm4gY291bnQ7Cit9CisKKy8qKgorICogVE9ETzogaWYgd2UgY2FyZSBhYm91dCBwZXJmb3JtYW5jZSwgd2UgbWlnaHQganVzdCB3YW50IHRvIHVzZSBhbiBpbnRbXSBpbnN0ZWFkIG9mIGEgUnVuW10uCisgKi8KK3N0YXRpYyBqb2JqZWN0QXJyYXkgQmlkaV91YmlkaV9nZXRSdW5zKEpOSUVudiogZW52LCBqY2xhc3MsIGpsb25nIHB0cikgeworICAgIFVCaURpKiB1YmlkaSA9IHVCaURpKHB0cik7CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgaW50IHJ1bkNvdW50ID0gdWJpZGlfY291bnRSdW5zKHViaWRpLCAmc3RhdHVzKTsKKyAgICBpZiAobWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihlbnYsIHN0YXR1cykpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGptZXRob2RJRCBiaWRpUnVuQ29uc3RydWN0b3IgPSBlbnYtPkdldE1ldGhvZElEKEpuaUNvbnN0YW50czo6YmlkaVJ1bkNsYXNzLCAiPGluaXQ+IiwgIihJSUkpViIpOworICAgIGpvYmplY3RBcnJheSBydW5zID0gZW52LT5OZXdPYmplY3RBcnJheShydW5Db3VudCwgSm5pQ29uc3RhbnRzOjpiaWRpUnVuQ2xhc3MsIE5VTEwpOworICAgIFVCaURpTGV2ZWwgbGV2ZWwgPSAwOworICAgIGludCBzdGFydCA9IDA7CisgICAgaW50IGxpbWl0ID0gMDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHJ1bkNvdW50OyArK2kpIHsKKyAgICAgICAgdWJpZGlfZ2V0TG9naWNhbFJ1bih1YmlkaSwgc3RhcnQsICZsaW1pdCwgJmxldmVsKTsKKyAgICAgICAgam9iamVjdCBydW4gPSBlbnYtPk5ld09iamVjdChKbmlDb25zdGFudHM6OmJpZGlSdW5DbGFzcywgYmlkaVJ1bkNvbnN0cnVjdG9yLCBzdGFydCwgbGltaXQsIGxldmVsKTsKKyAgICAgICAgZW52LT5TZXRPYmplY3RBcnJheUVsZW1lbnQocnVucywgaSwgcnVuKTsKKyAgICAgICAgc3RhcnQgPSBsaW1pdDsKKyAgICB9CisgICAgcmV0dXJuIHJ1bnM7Cit9CisKK3N0YXRpYyBqaW50QXJyYXkgQmlkaV91YmlkaV9yZW9yZGVyVmlzdWFsKEpOSUVudiogZW52LCBqY2xhc3MsIGpieXRlQXJyYXkgamF2YUxldmVscywgamludCBsZW5ndGgpIHsKKyAgICBTY29wZWRCeXRlQXJyYXlSTyBsZXZlbEJ5dGVzKGVudiwgamF2YUxldmVscyk7CisgICAgaWYgKGxldmVsQnl0ZXMuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBjb25zdCBVQmlEaUxldmVsKiBsZXZlbHMgPSByZWludGVycHJldF9jYXN0PGNvbnN0IFVCaURpTGV2ZWwqPihsZXZlbEJ5dGVzLmdldCgpKTsKKworICAgIFVuaXF1ZVB0cjxpbnRbXT4gaW5kZXhNYXAobmV3IGludFtsZW5ndGhdKTsKKyAgICB1YmlkaV9yZW9yZGVyVmlzdWFsKGxldmVscywgbGVuZ3RoLCAmaW5kZXhNYXBbMF0pOworCisgICAgamludEFycmF5IHJlc3VsdCA9IGVudi0+TmV3SW50QXJyYXkobGVuZ3RoKTsKKyAgICBlbnYtPlNldEludEFycmF5UmVnaW9uKHJlc3VsdCwgMCwgbGVuZ3RoLCAmaW5kZXhNYXBbMF0pOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBKTklOYXRpdmVNZXRob2QgZ01ldGhvZHNbXSA9IHsKKyAgICBOQVRJVkVfTUVUSE9EKEJpZGksIHViaWRpX2Nsb3NlLCAiKEopViIpLAorICAgIE5BVElWRV9NRVRIT0QoQmlkaSwgdWJpZGlfY291bnRSdW5zLCAiKEopSSIpLAorICAgIE5BVElWRV9NRVRIT0QoQmlkaSwgdWJpZGlfZ2V0RGlyZWN0aW9uLCAiKEopSSIpLAorICAgIE5BVElWRV9NRVRIT0QoQmlkaSwgdWJpZGlfZ2V0TGVuZ3RoLCAiKEopSSIpLAorICAgIE5BVElWRV9NRVRIT0QoQmlkaSwgdWJpZGlfZ2V0TGV2ZWxzLCAiKEopW0IiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEJpZGksIHViaWRpX2dldFBhcmFMZXZlbCwgIihKKUIiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEJpZGksIHViaWRpX2dldFJ1bnMsICIoSilbTGphdmEvdGV4dC9CaWRpJFJ1bjsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEJpZGksIHViaWRpX29wZW4sICIoKUoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEJpZGksIHViaWRpX3Jlb3JkZXJWaXN1YWwsICIoW0JJKVtJIiksCisgICAgTkFUSVZFX01FVEhPRChCaWRpLCB1YmlkaV9zZXRMaW5lLCAiKEpJSSlKIiksCisgICAgTkFUSVZFX01FVEhPRChCaWRpLCB1YmlkaV9zZXRQYXJhLCAiKEpbQ0lJW0IpViIpLAorfTsKK2ludCByZWdpc3Rlcl9qYXZhX3RleHRfQmlkaShKTklFbnYqIGVudikgeworICAgIHJldHVybiBqbmlSZWdpc3Rlck5hdGl2ZU1ldGhvZHMoZW52LCAiamF2YS90ZXh0L0JpZGkiLCBnTWV0aG9kcywgTkVMRU0oZ01ldGhvZHMpKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfdXRpbF9yZWdleF9NYXRjaGVyLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfdXRpbF9yZWdleF9NYXRjaGVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMjRhNmYwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV91dGlsX3JlZ2V4X01hdGNoZXIuY3BwCkBAIC0wLDAgKzEsMjE2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJNYXRjaGVyIgorCisjaW5jbHVkZSA8c3RkbGliLmg+CisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisjaW5jbHVkZSAiSm5pRXhjZXB0aW9uLmgiCisjaW5jbHVkZSAiU2NvcGVkUHJpbWl0aXZlQXJyYXkuaCIKKyNpbmNsdWRlICJVbmlxdWVQdHIuaCIKKyNpbmNsdWRlICJqbmkuaCIKKyNpbmNsdWRlICJ1bmljb2RlL3BhcnNlZXJyLmgiCisjaW5jbHVkZSAidW5pY29kZS9yZWdleC5oIgorCisvLyBJQ1UgZG9jdW1lbnRhdGlvbjogaHR0cDovL2ljdS1wcm9qZWN0Lm9yZy9hcGlyZWYvaWN1NGMvY2xhc3NSZWdleE1hdGNoZXIuaHRtbAorCitzdGF0aWMgUmVnZXhNYXRjaGVyKiB0b1JlZ2V4TWF0Y2hlcihqaW50IGFkZHIpIHsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxSZWdleE1hdGNoZXIqPihzdGF0aWNfY2FzdDx1aW50cHRyX3Q+KGFkZHIpKTsKK30KKworLyoqCisgKiBXZSB1c2UgSUNVNEMncyBSZWdleE1hdGNoZXIgY2xhc3MsIGJ1dCBvdXIgaW5wdXQgaXMgb24gdGhlIEphdmEgaGVhcCBhbmQgcG90ZW50aWFsbHkgbW92aW5nCisgKiBhcm91bmQgYmV0d2VlbiBjYWxscy4gVGhpcyB3cmFwcGVyIGNsYXNzIGVuc3VyZXMgdGhhdCBvdXIgUmVnZXhNYXRjaGVyIGlzIGFsd2F5cyBwb2ludGluZyBhdAorICogdGhlIGN1cnJlbnQgbG9jYXRpb24gb2YgdGhlIGNoYXJbXS4gRWFybGllciB2ZXJzaW9ucyBvZiBBbmRyb2lkIHNpbXBseSBjb3BpZWQgdGhlIGRhdGEgdG8gdGhlCisgKiBuYXRpdmUgaGVhcCwgYnV0IHRoYXQncyB3YXN0ZWZ1bCBhbmQgaGlkZXMgYWxsb2NhdGlvbnMgZnJvbSB0aGUgZ2FyYmFnZSBjb2xsZWN0b3IuCisgKi8KK2NsYXNzIE1hdGNoZXJBY2Nlc3NvciB7CitwdWJsaWM6CisgICAgTWF0Y2hlckFjY2Vzc29yKEpOSUVudiogZW52LCBqaW50IGFkZHIsIGpzdHJpbmcgamF2YUlucHV0LCBib29sIHJlc2V0KSB7CisgICAgICAgIGluaXQoZW52LCBhZGRyKTsKKworICAgICAgICBtSmF2YUlucHV0ID0gamF2YUlucHV0OworICAgICAgICBtQ2hhcnMgPSBlbnYtPkdldFN0cmluZ0NoYXJzKG1KYXZhSW5wdXQsIE5VTEwpOworICAgICAgICBpZiAobUNoYXJzID09IE5VTEwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIG1VVGV4dCA9IHV0ZXh0X29wZW5VQ2hhcnMoTlVMTCwgbUNoYXJzLCBlbnYtPkdldFN0cmluZ0xlbmd0aChtSmF2YUlucHV0KSwgJm1TdGF0dXMpOworICAgICAgICBpZiAobVVUZXh0ID09IE5VTEwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChyZXNldCkgeworICAgICAgICAgICAgbU1hdGNoZXItPnJlc2V0KG1VVGV4dCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBtTWF0Y2hlci0+cmVmcmVzaElucHV0VGV4dChtVVRleHQsIG1TdGF0dXMpOworICAgICAgICB9CisgICAgfQorCisgICAgTWF0Y2hlckFjY2Vzc29yKEpOSUVudiogZW52LCBqaW50IGFkZHIpIHsKKyAgICAgICAgaW5pdChlbnYsIGFkZHIpOworICAgIH0KKworICAgIH5NYXRjaGVyQWNjZXNzb3IoKSB7CisgICAgICAgIHV0ZXh0X2Nsb3NlKG1VVGV4dCk7CisgICAgICAgIGlmIChtSmF2YUlucHV0KSB7CisgICAgICAgICAgICBtRW52LT5SZWxlYXNlU3RyaW5nQ2hhcnMobUphdmFJbnB1dCwgbUNoYXJzKTsKKyAgICAgICAgfQorICAgICAgICBtYXliZVRocm93SWN1RXhjZXB0aW9uKG1FbnYsIG1TdGF0dXMpOworICAgIH0KKworICAgIFJlZ2V4TWF0Y2hlciogb3BlcmF0b3ItPigpIHsKKyAgICAgICAgcmV0dXJuIG1NYXRjaGVyOworICAgIH0KKworICAgIFVFcnJvckNvZGUmIHN0YXR1cygpIHsKKyAgICAgICAgcmV0dXJuIG1TdGF0dXM7CisgICAgfQorCisgICAgdm9pZCB1cGRhdGVPZmZzZXRzKGppbnRBcnJheSBqYXZhT2Zmc2V0cykgeworICAgICAgICBTY29wZWRJbnRBcnJheVJXIG9mZnNldHMobUVudiwgamF2YU9mZnNldHMpOworICAgICAgICBpZiAob2Zmc2V0cy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBmb3IgKHNpemVfdCBpID0gMCwgZ3JvdXBDb3VudCA9IG1NYXRjaGVyLT5ncm91cENvdW50KCk7IGkgPD0gZ3JvdXBDb3VudDsgKytpKSB7CisgICAgICAgICAgICBvZmZzZXRzWzIqaSArIDBdID0gbU1hdGNoZXItPnN0YXJ0KGksIG1TdGF0dXMpOworICAgICAgICAgICAgb2Zmc2V0c1syKmkgKyAxXSA9IG1NYXRjaGVyLT5lbmQoaSwgbVN0YXR1cyk7CisgICAgICAgIH0KKyAgICB9CisKK3ByaXZhdGU6CisgICAgdm9pZCBpbml0KEpOSUVudiogZW52LCBqaW50IGFkZHIpIHsKKyAgICAgICAgbUVudiA9IGVudjsKKyAgICAgICAgbUphdmFJbnB1dCA9IE5VTEw7CisgICAgICAgIG1NYXRjaGVyID0gdG9SZWdleE1hdGNoZXIoYWRkcik7CisgICAgICAgIG1DaGFycyA9IE5VTEw7CisgICAgICAgIG1TdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgICAgIG1VVGV4dCA9IE5VTEw7CisgICAgfQorCisgICAgSk5JRW52KiBtRW52OworICAgIGpzdHJpbmcgbUphdmFJbnB1dDsKKyAgICBSZWdleE1hdGNoZXIqIG1NYXRjaGVyOworICAgIGNvbnN0IGpjaGFyKiBtQ2hhcnM7CisgICAgVUVycm9yQ29kZSBtU3RhdHVzOworICAgIFVUZXh0KiBtVVRleHQ7CisKKyAgICAvLyBEaXNhbGxvdyBjb3B5IGFuZCBhc3NpZ25tZW50LgorICAgIE1hdGNoZXJBY2Nlc3Nvcihjb25zdCBNYXRjaGVyQWNjZXNzb3ImKTsKKyAgICB2b2lkIG9wZXJhdG9yPShjb25zdCBNYXRjaGVyQWNjZXNzb3ImKTsKK307CisKK3N0YXRpYyB2b2lkIE1hdGNoZXJfY2xvc2VJbXBsKEpOSUVudiosIGpjbGFzcywgamludCBhZGRyKSB7CisgICAgZGVsZXRlIHRvUmVnZXhNYXRjaGVyKGFkZHIpOworfQorCitzdGF0aWMgamludCBNYXRjaGVyX2ZpbmRJbXBsKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgYWRkciwganN0cmluZyBqYXZhVGV4dCwgamludCBzdGFydEluZGV4LCBqaW50QXJyYXkgb2Zmc2V0cykgeworICAgIE1hdGNoZXJBY2Nlc3NvciBtYXRjaGVyKGVudiwgYWRkciwgamF2YVRleHQsIGZhbHNlKTsKKyAgICBVQm9vbCByZXN1bHQgPSBtYXRjaGVyLT5maW5kKHN0YXJ0SW5kZXgsIG1hdGNoZXIuc3RhdHVzKCkpOworICAgIGlmIChyZXN1bHQpIHsKKyAgICAgICAgbWF0Y2hlci51cGRhdGVPZmZzZXRzKG9mZnNldHMpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgamludCBNYXRjaGVyX2ZpbmROZXh0SW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHIsIGpzdHJpbmcgamF2YVRleHQsIGppbnRBcnJheSBvZmZzZXRzKSB7CisgICAgTWF0Y2hlckFjY2Vzc29yIG1hdGNoZXIoZW52LCBhZGRyLCBqYXZhVGV4dCwgZmFsc2UpOworICAgIGlmIChtYXRjaGVyLnN0YXR1cygpICE9IFVfWkVST19FUlJPUikgeworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIFVCb29sIHJlc3VsdCA9IG1hdGNoZXItPmZpbmQoKTsKKyAgICBpZiAocmVzdWx0KSB7CisgICAgICAgIG1hdGNoZXIudXBkYXRlT2Zmc2V0cyhvZmZzZXRzKTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIGppbnQgTWF0Y2hlcl9ncm91cENvdW50SW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHIpIHsKKyAgICBNYXRjaGVyQWNjZXNzb3IgbWF0Y2hlcihlbnYsIGFkZHIpOworICAgIHJldHVybiBtYXRjaGVyLT5ncm91cENvdW50KCk7Cit9CisKK3N0YXRpYyBqaW50IE1hdGNoZXJfaGl0RW5kSW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHIpIHsKKyAgICBNYXRjaGVyQWNjZXNzb3IgbWF0Y2hlcihlbnYsIGFkZHIpOworICAgIHJldHVybiBtYXRjaGVyLT5oaXRFbmQoKTsKK30KKworc3RhdGljIGppbnQgTWF0Y2hlcl9sb29raW5nQXRJbXBsKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgYWRkciwganN0cmluZyBqYXZhVGV4dCwgamludEFycmF5IG9mZnNldHMpIHsKKyAgICBNYXRjaGVyQWNjZXNzb3IgbWF0Y2hlcihlbnYsIGFkZHIsIGphdmFUZXh0LCBmYWxzZSk7CisgICAgVUJvb2wgcmVzdWx0ID0gbWF0Y2hlci0+bG9va2luZ0F0KG1hdGNoZXIuc3RhdHVzKCkpOworICAgIGlmIChyZXN1bHQpIHsKKyAgICAgICAgbWF0Y2hlci51cGRhdGVPZmZzZXRzKG9mZnNldHMpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgamludCBNYXRjaGVyX21hdGNoZXNJbXBsKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgYWRkciwganN0cmluZyBqYXZhVGV4dCwgamludEFycmF5IG9mZnNldHMpIHsKKyAgICBNYXRjaGVyQWNjZXNzb3IgbWF0Y2hlcihlbnYsIGFkZHIsIGphdmFUZXh0LCBmYWxzZSk7CisgICAgVUJvb2wgcmVzdWx0ID0gbWF0Y2hlci0+bWF0Y2hlcyhtYXRjaGVyLnN0YXR1cygpKTsKKyAgICBpZiAocmVzdWx0KSB7CisgICAgICAgIG1hdGNoZXIudXBkYXRlT2Zmc2V0cyhvZmZzZXRzKTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIGppbnQgTWF0Y2hlcl9vcGVuSW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IHBhdHRlcm5BZGRyKSB7CisgICAgUmVnZXhQYXR0ZXJuKiBwYXR0ZXJuID0gcmVpbnRlcnByZXRfY2FzdDxSZWdleFBhdHRlcm4qPihzdGF0aWNfY2FzdDx1aW50cHRyX3Q+KHBhdHRlcm5BZGRyKSk7CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgUmVnZXhNYXRjaGVyKiByZXN1bHQgPSBwYXR0ZXJuLT5tYXRjaGVyKHN0YXR1cyk7CisgICAgbWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihlbnYsIHN0YXR1cyk7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGppbnQ+KHJlaW50ZXJwcmV0X2Nhc3Q8dWludHB0cl90PihyZXN1bHQpKTsKK30KKworc3RhdGljIGppbnQgTWF0Y2hlcl9yZXF1aXJlRW5kSW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHIpIHsKKyAgICBNYXRjaGVyQWNjZXNzb3IgbWF0Y2hlcihlbnYsIGFkZHIpOworICAgIHJldHVybiBtYXRjaGVyLT5yZXF1aXJlRW5kKCk7Cit9CisKK3N0YXRpYyB2b2lkIE1hdGNoZXJfc2V0SW5wdXRJbXBsKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgYWRkciwganN0cmluZyBqYXZhVGV4dCwgamludCBzdGFydCwgamludCBlbmQpIHsKKyAgICBNYXRjaGVyQWNjZXNzb3IgbWF0Y2hlcihlbnYsIGFkZHIsIGphdmFUZXh0LCB0cnVlKTsKKyAgICBtYXRjaGVyLT5yZWdpb24oc3RhcnQsIGVuZCwgbWF0Y2hlci5zdGF0dXMoKSk7Cit9CisKK3N0YXRpYyB2b2lkIE1hdGNoZXJfdXNlQW5jaG9yaW5nQm91bmRzSW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHIsIGpib29sZWFuIHZhbHVlKSB7CisgICAgTWF0Y2hlckFjY2Vzc29yIG1hdGNoZXIoZW52LCBhZGRyKTsKKyAgICBtYXRjaGVyLT51c2VBbmNob3JpbmdCb3VuZHModmFsdWUpOworfQorCitzdGF0aWMgdm9pZCBNYXRjaGVyX3VzZVRyYW5zcGFyZW50Qm91bmRzSW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHIsIGpib29sZWFuIHZhbHVlKSB7CisgICAgTWF0Y2hlckFjY2Vzc29yIG1hdGNoZXIoZW52LCBhZGRyKTsKKyAgICBtYXRjaGVyLT51c2VUcmFuc3BhcmVudEJvdW5kcyh2YWx1ZSk7Cit9CisKK3N0YXRpYyBKTklOYXRpdmVNZXRob2QgZ01ldGhvZHNbXSA9IHsKKyAgICBOQVRJVkVfTUVUSE9EKE1hdGNoZXIsIGNsb3NlSW1wbCwgIihJKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1hdGNoZXIsIGZpbmRJbXBsLCAiKElMamF2YS9sYW5nL1N0cmluZztJW0kpWiIpLAorICAgIE5BVElWRV9NRVRIT0QoTWF0Y2hlciwgZmluZE5leHRJbXBsLCAiKElMamF2YS9sYW5nL1N0cmluZztbSSlaIiksCisgICAgTkFUSVZFX01FVEhPRChNYXRjaGVyLCBncm91cENvdW50SW1wbCwgIihJKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1hdGNoZXIsIGhpdEVuZEltcGwsICIoSSlaIiksCisgICAgTkFUSVZFX01FVEhPRChNYXRjaGVyLCBsb29raW5nQXRJbXBsLCAiKElMamF2YS9sYW5nL1N0cmluZztbSSlaIiksCisgICAgTkFUSVZFX01FVEhPRChNYXRjaGVyLCBtYXRjaGVzSW1wbCwgIihJTGphdmEvbGFuZy9TdHJpbmc7W0kpWiIpLAorICAgIE5BVElWRV9NRVRIT0QoTWF0Y2hlciwgb3BlbkltcGwsICIoSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChNYXRjaGVyLCByZXF1aXJlRW5kSW1wbCwgIihJKVoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1hdGNoZXIsIHNldElucHV0SW1wbCwgIihJTGphdmEvbGFuZy9TdHJpbmc7SUkpViIpLAorICAgIE5BVElWRV9NRVRIT0QoTWF0Y2hlciwgdXNlQW5jaG9yaW5nQm91bmRzSW1wbCwgIihJWilWIiksCisgICAgTkFUSVZFX01FVEhPRChNYXRjaGVyLCB1c2VUcmFuc3BhcmVudEJvdW5kc0ltcGwsICIoSVopViIpLAorfTsKK2ludCByZWdpc3Rlcl9qYXZhX3V0aWxfcmVnZXhfTWF0Y2hlcihKTklFbnYqIGVudikgeworICAgIHJldHVybiBqbmlSZWdpc3Rlck5hdGl2ZU1ldGhvZHMoZW52LCAiamF2YS91dGlsL3JlZ2V4L01hdGNoZXIiLCBnTWV0aG9kcywgTkVMRU0oZ01ldGhvZHMpKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfdXRpbF9yZWdleF9QYXR0ZXJuLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfdXRpbF9yZWdleF9QYXR0ZXJuLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZTBlMWUzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV91dGlsX3JlZ2V4X1BhdHRlcm4uY3BwCkBAIC0wLDAgKzEsMTAwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJQYXR0ZXJuIgorCisjaW5jbHVkZSA8c3RkbGliLmg+CisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisjaW5jbHVkZSAiU2NvcGVkSmF2YVVuaWNvZGVTdHJpbmcuaCIKKyNpbmNsdWRlICJqbmkuaCIKKyNpbmNsdWRlICJ1bmljb2RlL3BhcnNlZXJyLmgiCisjaW5jbHVkZSAidW5pY29kZS9yZWdleC5oIgorCisvLyBJQ1UgZG9jdW1lbnRhdGlvbjogaHR0cDovL2ljdS1wcm9qZWN0Lm9yZy9hcGlyZWYvaWN1NGMvY2xhc3NSZWdleFBhdHRlcm4uaHRtbAorCitzdGF0aWMgUmVnZXhQYXR0ZXJuKiB0b1JlZ2V4UGF0dGVybihqaW50IGFkZHIpIHsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxSZWdleFBhdHRlcm4qPihzdGF0aWNfY2FzdDx1aW50cHRyX3Q+KGFkZHIpKTsKK30KKworc3RhdGljIGNvbnN0IGNoYXIqIHJlZ2V4RGV0YWlsTWVzc2FnZShVRXJyb3JDb2RlIHN0YXR1cykgeworICAgIC8vIFRoZXNlIGh1bWFuLXJlYWRhYmxlIGVycm9yIG1lc3NhZ2VzIHdlcmUgY3VsbGVkIGZyb20gInV0eXBlcy5oIiwgYW5kIHRoZW4gc2xpZ2h0bHkgdHVuZWQKKyAgICAvLyB0byBtYWtlIG1vcmUgc2Vuc2UgaW4gY29udGV4dC4KKyAgICAvLyBJZiB3ZSBkb24ndCBoYXZlIGEgc3BlY2lhbC1jYXNlLCB3ZSdsbCBqdXN0IHJldHVybiB0aGUgdGV4dHVhbCBuYW1lIG9mCisgICAgLy8gdGhlIGVudW0gdmFsdWUgKHN1Y2ggYXMgVV9SRUdFWF9SVUxFX1NZTlRBWCksIHdoaWNoIGlzIGJldHRlciB0aGFuIG5vdGhpbmcuCisgICAgc3dpdGNoIChzdGF0dXMpIHsKKyAgICBjYXNlIFVfUkVHRVhfSU5URVJOQUxfRVJST1I6IHJldHVybiAiQW4gaW50ZXJuYWwgZXJyb3Igd2FzIGRldGVjdGVkIjsKKyAgICBjYXNlIFVfUkVHRVhfUlVMRV9TWU5UQVg6IHJldHVybiAiU3ludGF4IGVycm9yIGluIHJlZ2V4cCBwYXR0ZXJuIjsKKyAgICBjYXNlIFVfUkVHRVhfSU5WQUxJRF9TVEFURTogcmV0dXJuICJNYXRjaGVyIGluIGludmFsaWQgc3RhdGUgZm9yIHJlcXVlc3RlZCBvcGVyYXRpb24iOworICAgIGNhc2UgVV9SRUdFWF9CQURfRVNDQVBFX1NFUVVFTkNFOiByZXR1cm4gIlVucmVjb2duaXplZCBiYWNrc2xhc2ggZXNjYXBlIHNlcXVlbmNlIGluIHBhdHRlcm4iOworICAgIGNhc2UgVV9SRUdFWF9QUk9QRVJUWV9TWU5UQVg6IHJldHVybiAiSW5jb3JyZWN0IFVuaWNvZGUgcHJvcGVydHkiOworICAgIGNhc2UgVV9SRUdFWF9VTklNUExFTUVOVEVEOiByZXR1cm4gIlVzZSBvZiB1bmltcGxlbWVudGVkIGZlYXR1cmUiOworICAgIGNhc2UgVV9SRUdFWF9NSVNNQVRDSEVEX1BBUkVOOiByZXR1cm4gIkluY29ycmVjdGx5IG5lc3RlZCBwYXJlbnRoZXNlcyBpbiByZWdleHAgcGF0dGVybiI7CisgICAgY2FzZSBVX1JFR0VYX05VTUJFUl9UT09fQklHOiByZXR1cm4gIkRlY2ltYWwgbnVtYmVyIGlzIHRvbyBsYXJnZSI7CisgICAgY2FzZSBVX1JFR0VYX0JBRF9JTlRFUlZBTDogcmV0dXJuICJFcnJvciBpbiB7bWluLG1heH0gaW50ZXJ2YWwiOworICAgIGNhc2UgVV9SRUdFWF9NQVhfTFRfTUlOOiByZXR1cm4gIkluIHttaW4sbWF4fSwgbWF4IGlzIGxlc3MgdGhhbiBtaW4iOworICAgIGNhc2UgVV9SRUdFWF9JTlZBTElEX0JBQ0tfUkVGOiByZXR1cm4gIkJhY2stcmVmZXJlbmNlIHRvIGEgbm9uLWV4aXN0ZW50IGNhcHR1cmUgZ3JvdXAiOworICAgIGNhc2UgVV9SRUdFWF9JTlZBTElEX0ZMQUc6IHJldHVybiAiSW52YWxpZCB2YWx1ZSBmb3IgbWF0Y2ggbW9kZSBmbGFncyI7CisgICAgY2FzZSBVX1JFR0VYX0xPT0tfQkVISU5EX0xJTUlUOiByZXR1cm4gIkxvb2stYmVoaW5kIHBhdHRlcm4gbWF0Y2hlcyBtdXN0IGhhdmUgYSBib3VuZGVkIG1heGltdW0gbGVuZ3RoIjsKKyAgICBjYXNlIFVfUkVHRVhfU0VUX0NPTlRBSU5TX1NUUklORzogcmV0dXJuICJSZWd1bGFyIGV4cHJlc3Npb25zIGNhbm5vdCBoYXZlIFVuaWNvZGVTZXRzIGNvbnRhaW5pbmcgc3RyaW5ncyI7CisgICAgY2FzZSBVX1JFR0VYX09DVEFMX1RPT19CSUc6IHJldHVybiAiT2N0YWwgY2hhcmFjdGVyIGNvbnN0YW50cyBtdXN0IGJlIDw9IDAzNzcuIjsKKyAgICBjYXNlIFVfUkVHRVhfTUlTU0lOR19DTE9TRV9CUkFDS0VUOiByZXR1cm4gIk1pc3NpbmcgY2xvc2luZyBicmFja2V0IGluIGNoYXJhY3RlciBjbGFzcyI7CisgICAgY2FzZSBVX1JFR0VYX0lOVkFMSURfUkFOR0U6IHJldHVybiAiSW4gYSBjaGFyYWN0ZXIgcmFuZ2UgW3gteV0sIHggaXMgZ3JlYXRlciB0aGFuIHkiOworICAgIGNhc2UgVV9SRUdFWF9TVEFDS19PVkVSRkxPVzogcmV0dXJuICJSZWd1bGFyIGV4cHJlc3Npb24gYmFja3RyYWNrIHN0YWNrIG92ZXJmbG93IjsKKyAgICBjYXNlIFVfUkVHRVhfVElNRV9PVVQ6IHJldHVybiAiTWF4aW11bSBhbGxvd2VkIG1hdGNoIHRpbWUgZXhjZWVkZWQiOworICAgIGNhc2UgVV9SRUdFWF9TVE9QUEVEX0JZX0NBTExFUjogcmV0dXJuICJNYXRjaGluZyBvcGVyYXRpb24gYWJvcnRlZCBieSB1c2VyIGNhbGxiYWNrIGZ1bmN0aW9uIjsKKyAgICBkZWZhdWx0OgorICAgICAgICByZXR1cm4gdV9lcnJvck5hbWUoc3RhdHVzKTsKKyAgICB9Cit9CisKK3N0YXRpYyB2b2lkIHRocm93UGF0dGVyblN5bnRheEV4Y2VwdGlvbihKTklFbnYqIGVudiwgVUVycm9yQ29kZSBzdGF0dXMsIGpzdHJpbmcgcGF0dGVybiwgVVBhcnNlRXJyb3IgZXJyb3IpIHsKKyAgICBzdGF0aWMgam1ldGhvZElEIG1ldGhvZCA9IGVudi0+R2V0TWV0aG9kSUQoSm5pQ29uc3RhbnRzOjpwYXR0ZXJuU3ludGF4RXhjZXB0aW9uQ2xhc3MsCisgICAgICAgICAgICAiPGluaXQ+IiwgIihMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZztJKVYiKTsKKyAgICBqc3RyaW5nIG1lc3NhZ2UgPSBlbnYtPk5ld1N0cmluZ1VURihyZWdleERldGFpbE1lc3NhZ2Uoc3RhdHVzKSk7CisgICAgamNsYXNzIGV4Y2VwdGlvbkNsYXNzID0gSm5pQ29uc3RhbnRzOjpwYXR0ZXJuU3ludGF4RXhjZXB0aW9uQ2xhc3M7CisgICAgam9iamVjdCBleGNlcHRpb24gPSBlbnYtPk5ld09iamVjdChleGNlcHRpb25DbGFzcywgbWV0aG9kLCBtZXNzYWdlLCBwYXR0ZXJuLCBlcnJvci5vZmZzZXQpOworICAgIGVudi0+VGhyb3cocmVpbnRlcnByZXRfY2FzdDxqdGhyb3dhYmxlPihleGNlcHRpb24pKTsKK30KKworc3RhdGljIHZvaWQgUGF0dGVybl9jbG9zZUltcGwoSk5JRW52KiwgamNsYXNzLCBqaW50IGFkZHIpIHsKKyAgICBkZWxldGUgdG9SZWdleFBhdHRlcm4oYWRkcik7Cit9CisKK3N0YXRpYyBqaW50IFBhdHRlcm5fY29tcGlsZUltcGwoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBqYXZhUmVnZXgsIGppbnQgZmxhZ3MpIHsKKyAgICBmbGFncyB8PSBVUkVHRVhfRVJST1JfT05fVU5LTk9XTl9FU0NBUEVTOworCisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgVVBhcnNlRXJyb3IgZXJyb3I7CisgICAgZXJyb3Iub2Zmc2V0ID0gLTE7CisKKyAgICBTY29wZWRKYXZhVW5pY29kZVN0cmluZyByZWdleChlbnYsIGphdmFSZWdleCk7CisgICAgVW5pY29kZVN0cmluZyYgcmVnZXhTdHJpbmcocmVnZXgudW5pY29kZVN0cmluZygpKTsKKyAgICBSZWdleFBhdHRlcm4qIHJlc3VsdCA9IFJlZ2V4UGF0dGVybjo6Y29tcGlsZShyZWdleFN0cmluZywgZmxhZ3MsIGVycm9yLCBzdGF0dXMpOworICAgIGlmICghVV9TVUNDRVNTKHN0YXR1cykpIHsKKyAgICAgICAgdGhyb3dQYXR0ZXJuU3ludGF4RXhjZXB0aW9uKGVudiwgc3RhdHVzLCBqYXZhUmVnZXgsIGVycm9yKTsKKyAgICB9CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGppbnQ+KHJlaW50ZXJwcmV0X2Nhc3Q8dWludHB0cl90PihyZXN1bHQpKTsKK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBnTWV0aG9kc1tdID0geworICAgIE5BVElWRV9NRVRIT0QoUGF0dGVybiwgY2xvc2VJbXBsLCAiKEkpViIpLAorICAgIE5BVElWRV9NRVRIT0QoUGF0dGVybiwgY29tcGlsZUltcGwsICIoTGphdmEvbGFuZy9TdHJpbmc7SSlJIiksCit9OworaW50IHJlZ2lzdGVyX2phdmFfdXRpbF9yZWdleF9QYXR0ZXJuKEpOSUVudiogZW52KSB7CisgICAgcmV0dXJuIGpuaVJlZ2lzdGVyTmF0aXZlTWV0aG9kcyhlbnYsICJqYXZhL3V0aWwvcmVnZXgvUGF0dGVybiIsIGdNZXRob2RzLCBORUxFTShnTWV0aG9kcykpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV91dGlsX3ppcF9BZGxlcjMyLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfdXRpbF96aXBfQWRsZXIzMi5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDBjOTZlYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfdXRpbF96aXBfQWRsZXIzMi5jcHAKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiQWRsZXIzMiIKKworI2luY2x1ZGUgIkpOSUhlbHAuaCIKKyNpbmNsdWRlICJKbmlDb25zdGFudHMuaCIKKyNpbmNsdWRlICJTY29wZWRQcmltaXRpdmVBcnJheS5oIgorI2luY2x1ZGUgImpuaS5oIgorI2luY2x1ZGUgInpsaWIuaCIKKworc3RhdGljIGpsb25nIEFkbGVyMzJfdXBkYXRlSW1wbChKTklFbnYqIGVudiwgam9iamVjdCwgamJ5dGVBcnJheSBieXRlQXJyYXksIGludCBvZmYsIGludCBsZW4sIGpsb25nIGNyYykgeworICAgIFNjb3BlZEJ5dGVBcnJheVJPIGJ5dGVzKGVudiwgYnl0ZUFycmF5KTsKKyAgICBpZiAoYnl0ZXMuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgcmV0dXJuIGFkbGVyMzIoY3JjLCByZWludGVycHJldF9jYXN0PGNvbnN0IEJ5dGVmKj4oYnl0ZXMuZ2V0KCkgKyBvZmYpLCBsZW4pOworfQorCitzdGF0aWMgamxvbmcgQWRsZXIzMl91cGRhdGVCeXRlSW1wbChKTklFbnYqLCBqb2JqZWN0LCBqaW50IHZhbCwgamxvbmcgY3JjKSB7CisgICAgQnl0ZWYgYnl0ZWZWYWwgPSB2YWw7CisgICAgcmV0dXJuIGFkbGVyMzIoY3JjLCByZWludGVycHJldF9jYXN0PGNvbnN0IEJ5dGVmKj4oJmJ5dGVmVmFsKSwgMSk7Cit9CisKK3N0YXRpYyBKTklOYXRpdmVNZXRob2QgZ01ldGhvZHNbXSA9IHsKKyAgICBOQVRJVkVfTUVUSE9EKEFkbGVyMzIsIHVwZGF0ZUltcGwsICIoW0JJSUopSiIpLAorICAgIE5BVElWRV9NRVRIT0QoQWRsZXIzMiwgdXBkYXRlQnl0ZUltcGwsICIoSUopSiIpLAorfTsKK2ludCByZWdpc3Rlcl9qYXZhX3V0aWxfemlwX0FkbGVyMzIoSk5JRW52KiBlbnYpIHsKKyAgICByZXR1cm4gam5pUmVnaXN0ZXJOYXRpdmVNZXRob2RzKGVudiwgImphdmEvdXRpbC96aXAvQWRsZXIzMiIsIGdNZXRob2RzLCBORUxFTShnTWV0aG9kcykpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV91dGlsX3ppcF9DUkMzMi5jcHAgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX3V0aWxfemlwX0NSQzMyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lY2ZkZTdmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV91dGlsX3ppcF9DUkMzMi5jcHAKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiQ1JDMzIiCisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisjaW5jbHVkZSAiU2NvcGVkUHJpbWl0aXZlQXJyYXkuaCIKKyNpbmNsdWRlICJqbmkuaCIKKyNpbmNsdWRlICJ6bGliLmgiCisKK3N0YXRpYyBqbG9uZyBDUkMzMl91cGRhdGVJbXBsKEpOSUVudiogZW52LCBqb2JqZWN0LCBqYnl0ZUFycmF5IGJ5dGVBcnJheSwgaW50IG9mZiwgaW50IGxlbiwgamxvbmcgY3JjKSB7CisgICAgU2NvcGVkQnl0ZUFycmF5Uk8gYnl0ZXMoZW52LCBieXRlQXJyYXkpOworICAgIGlmIChieXRlcy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBqbG9uZyByZXN1bHQgPSBjcmMzMihjcmMsIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgQnl0ZWYqPihieXRlcy5nZXQoKSArIG9mZiksIGxlbik7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIGpsb25nIENSQzMyX3VwZGF0ZUJ5dGVJbXBsKEpOSUVudiosIGpvYmplY3QsIGpieXRlIHZhbCwgamxvbmcgY3JjKSB7CisgICAgcmV0dXJuIGNyYzMyKGNyYywgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBCeXRlZio+KCZ2YWwpLCAxKTsKK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBnTWV0aG9kc1tdID0geworICAgIE5BVElWRV9NRVRIT0QoQ1JDMzIsIHVwZGF0ZUltcGwsICIoW0JJSUopSiIpLAorICAgIE5BVElWRV9NRVRIT0QoQ1JDMzIsIHVwZGF0ZUJ5dGVJbXBsLCAiKEJKKUoiKSwKK307CitpbnQgcmVnaXN0ZXJfamF2YV91dGlsX3ppcF9DUkMzMihKTklFbnYqIGVudikgeworICAgIHJldHVybiBqbmlSZWdpc3Rlck5hdGl2ZU1ldGhvZHMoZW52LCAiamF2YS91dGlsL3ppcC9DUkMzMiIsIGdNZXRob2RzLCBORUxFTShnTWV0aG9kcykpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV91dGlsX3ppcF9EZWZsYXRlci5jcHAgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX3V0aWxfemlwX0RlZmxhdGVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MmQwODFiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvamF2YV91dGlsX3ppcF9EZWZsYXRlci5jcHAKQEAgLTAsMCArMSwxNTEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIkRlZmxhdGVyIgorCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisjaW5jbHVkZSAiU2NvcGVkUHJpbWl0aXZlQXJyYXkuaCIKKyNpbmNsdWRlICJ6aXAuaCIKKworc3RhdGljIHZvaWQgRGVmbGF0ZXJfc2V0RGljdGlvbmFyeUltcGwoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpieXRlQXJyYXkgZGljdCwgaW50IG9mZiwgaW50IGxlbiwgamxvbmcgaGFuZGxlKSB7CisgICAgdG9OYXRpdmVaaXBTdHJlYW0oaGFuZGxlKS0+c2V0RGljdGlvbmFyeShlbnYsIGRpY3QsIG9mZiwgbGVuLCBmYWxzZSk7Cit9CisKK3N0YXRpYyBqbG9uZyBEZWZsYXRlcl9nZXRUb3RhbEluSW1wbChKTklFbnYqLCBqb2JqZWN0LCBqbG9uZyBoYW5kbGUpIHsKKyAgICByZXR1cm4gdG9OYXRpdmVaaXBTdHJlYW0oaGFuZGxlKS0+c3RyZWFtLnRvdGFsX2luOworfQorCitzdGF0aWMgamxvbmcgRGVmbGF0ZXJfZ2V0VG90YWxPdXRJbXBsKEpOSUVudiosIGpvYmplY3QsIGpsb25nIGhhbmRsZSkgeworICAgIHJldHVybiB0b05hdGl2ZVppcFN0cmVhbShoYW5kbGUpLT5zdHJlYW0udG90YWxfb3V0OworfQorCitzdGF0aWMgamludCBEZWZsYXRlcl9nZXRBZGxlckltcGwoSk5JRW52Kiwgam9iamVjdCwgamxvbmcgaGFuZGxlKSB7CisgICAgcmV0dXJuIHRvTmF0aXZlWmlwU3RyZWFtKGhhbmRsZSktPnN0cmVhbS5hZGxlcjsKK30KKworc3RhdGljIGpsb25nIERlZmxhdGVyX2NyZWF0ZVN0cmVhbShKTklFbnYgKiBlbnYsIGpvYmplY3QsIGppbnQgbGV2ZWwsIGppbnQgc3RyYXRlZ3ksIGpib29sZWFuIG5vSGVhZGVyKSB7CisgICAgVW5pcXVlUHRyPE5hdGl2ZVppcFN0cmVhbT4ganN0cmVhbShuZXcgTmF0aXZlWmlwU3RyZWFtKTsKKyAgICBpZiAoanN0cmVhbS5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIGpuaVRocm93T3V0T2ZNZW1vcnlFcnJvcihlbnYsIE5VTEwpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBTZWUgemxpYi5oIGZvciBkb2N1bWVudGF0aW9uIG9mIHRoZSBkZWZsYXRlSW5pdDIgd2luZG93Qml0cyBhbmQgbWVtTGV2ZWwgcGFyYW1ldGVycy4KKyAgICAgKgorICAgICAqIHpjb25mLmggc2F5cyB0aGUgInJlcXVpcmVtZW50cyBmb3IgZGVmbGF0ZSBhcmUgKGluIGJ5dGVzKToKKyAgICAgKiAgICAgICAgICgxIDw8ICh3aW5kb3dCaXRzKzIpKSArICAoMSA8PCAobWVtTGV2ZWwrOSkpCisgICAgICogdGhhdCBpczogMTI4SyBmb3Igd2luZG93Qml0cz0xNSAgKyAgMTI4SyBmb3IgbWVtTGV2ZWwgPSA4ICAoZGVmYXVsdCB2YWx1ZXMpCisgICAgICogcGx1cyBhIGZldyBraWxvYnl0ZXMgZm9yIHNtYWxsIG9iamVjdHMuIgorICAgICAqLworICAgIGludCB3aW5kb3dCaXRzID0gbm9IZWFkZXIgPyAtREVGX1dCSVRTIDogREVGX1dCSVRTOworICAgIGludCBtZW1MZXZlbCA9IERFRl9NRU1fTEVWRUw7CisgICAgaW50IGVyciA9IGRlZmxhdGVJbml0MigmanN0cmVhbS0+c3RyZWFtLCBsZXZlbCwgWl9ERUZMQVRFRCwgd2luZG93Qml0cywgbWVtTGV2ZWwsIHN0cmF0ZWd5KTsKKyAgICBpZiAoZXJyICE9IFpfT0spIHsKKyAgICAgICAgdGhyb3dFeGNlcHRpb25Gb3JabGliRXJyb3IoZW52LCAiamF2YS9sYW5nL0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIsIGVycik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8dWludHB0cl90Pihqc3RyZWFtLnJlbGVhc2UoKSk7Cit9CisKK3N0YXRpYyB2b2lkIERlZmxhdGVyX3NldElucHV0SW1wbChKTklFbnYqIGVudiwgam9iamVjdCwgamJ5dGVBcnJheSBidWYsIGppbnQgb2ZmLCBqaW50IGxlbiwgamxvbmcgaGFuZGxlKSB7CisgICAgdG9OYXRpdmVaaXBTdHJlYW0oaGFuZGxlKS0+c2V0SW5wdXQoZW52LCBidWYsIG9mZiwgbGVuKTsKK30KKworc3RhdGljIGppbnQgRGVmbGF0ZXJfZGVmbGF0ZUltcGwoSk5JRW52KiBlbnYsIGpvYmplY3QgcmVjdiwgamJ5dGVBcnJheSBidWYsIGludCBvZmYsIGludCBsZW4sIGpsb25nIGhhbmRsZSwgaW50IGZsdXNoU3R5bGUpIHsKKyAgICBOYXRpdmVaaXBTdHJlYW0qIHN0cmVhbSA9IHRvTmF0aXZlWmlwU3RyZWFtKGhhbmRsZSk7CisgICAgU2NvcGVkQnl0ZUFycmF5Ulcgb3V0KGVudiwgYnVmKTsKKyAgICBpZiAob3V0LmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBzdHJlYW0tPnN0cmVhbS5uZXh0X291dCA9IHJlaW50ZXJwcmV0X2Nhc3Q8Qnl0ZWYqPihvdXQuZ2V0KCkgKyBvZmYpOworICAgIHN0cmVhbS0+c3RyZWFtLmF2YWlsX291dCA9IGxlbjsKKworICAgIEJ5dGVmKiBpbml0aWFsTmV4dEluID0gc3RyZWFtLT5zdHJlYW0ubmV4dF9pbjsKKyAgICBCeXRlZiogaW5pdGlhbE5leHRPdXQgPSBzdHJlYW0tPnN0cmVhbS5uZXh0X291dDsKKworICAgIGludCBlcnIgPSBkZWZsYXRlKCZzdHJlYW0tPnN0cmVhbSwgZmx1c2hTdHlsZSk7CisgICAgc3dpdGNoIChlcnIpIHsKKyAgICBjYXNlIFpfT0s6CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgWl9TVFJFQU1fRU5EOgorICAgICAgICBzdGF0aWMgamZpZWxkSUQgZmluaXNoZWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjpkZWZsYXRlckNsYXNzLCAiZmluaXNoZWQiLCAiWiIpOworICAgICAgICBlbnYtPlNldEJvb2xlYW5GaWVsZChyZWN2LCBmaW5pc2hlZCwgSk5JX1RSVUUpOworICAgICAgICBicmVhazsKKyAgICBjYXNlIFpfQlVGX0VSUk9SOgorICAgICAgICAvLyB6bGliIHJlcG9ydHMgdGhpcyAiaWYgbm8gcHJvZ3Jlc3MgaXMgcG9zc2libGUgKGZvciBleGFtcGxlIGF2YWlsX2luIG9yIGF2YWlsX291dCB3YXMKKyAgICAgICAgLy8gemVybykgLi4uIFpfQlVGX0VSUk9SIGlzIG5vdCBmYXRhbCwgYW5kIGRlZmxhdGUoKSBjYW4gYmUgY2FsbGVkIGFnYWluIHdpdGggbW9yZQorICAgICAgICAvLyBpbnB1dCBhbmQgbW9yZSBvdXRwdXQgc3BhY2UgdG8gY29udGludWUgY29tcHJlc3NpbmciLgorICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICB0aHJvd0V4Y2VwdGlvbkZvclpsaWJFcnJvcihlbnYsICJqYXZhL3V0aWwvemlwL0RhdGFGb3JtYXRFeGNlcHRpb24iLCBlcnIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgamludCBieXRlc1JlYWQgPSBzdHJlYW0tPnN0cmVhbS5uZXh0X2luIC0gaW5pdGlhbE5leHRJbjsKKyAgICBqaW50IGJ5dGVzV3JpdHRlbiA9IHN0cmVhbS0+c3RyZWFtLm5leHRfb3V0IC0gaW5pdGlhbE5leHRPdXQ7CisKKyAgICBzdGF0aWMgamZpZWxkSUQgaW5SZWFkRmllbGQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjpkZWZsYXRlckNsYXNzLCAiaW5SZWFkIiwgIkkiKTsKKyAgICBqaW50IGluUmVhZFZhbHVlID0gZW52LT5HZXRJbnRGaWVsZChyZWN2LCBpblJlYWRGaWVsZCk7CisgICAgaW5SZWFkVmFsdWUgKz0gYnl0ZXNSZWFkOworICAgIGVudi0+U2V0SW50RmllbGQocmVjdiwgaW5SZWFkRmllbGQsIGluUmVhZFZhbHVlKTsKKyAgICByZXR1cm4gYnl0ZXNXcml0dGVuOworfQorCitzdGF0aWMgdm9pZCBEZWZsYXRlcl9lbmRJbXBsKEpOSUVudiosIGpvYmplY3QsIGpsb25nIGhhbmRsZSkgeworICAgIE5hdGl2ZVppcFN0cmVhbSogc3RyZWFtID0gdG9OYXRpdmVaaXBTdHJlYW0oaGFuZGxlKTsKKyAgICBkZWZsYXRlRW5kKCZzdHJlYW0tPnN0cmVhbSk7CisgICAgZGVsZXRlIHN0cmVhbTsKK30KKworc3RhdGljIHZvaWQgRGVmbGF0ZXJfcmVzZXRJbXBsKEpOSUVudiogZW52LCBqb2JqZWN0LCBqbG9uZyBoYW5kbGUpIHsKKyAgICBOYXRpdmVaaXBTdHJlYW0qIHN0cmVhbSA9IHRvTmF0aXZlWmlwU3RyZWFtKGhhbmRsZSk7CisgICAgaW50IGVyciA9IGRlZmxhdGVSZXNldCgmc3RyZWFtLT5zdHJlYW0pOworICAgIGlmIChlcnIgIT0gWl9PSykgeworICAgICAgICB0aHJvd0V4Y2VwdGlvbkZvclpsaWJFcnJvcihlbnYsICJqYXZhL2xhbmcvSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIiwgZXJyKTsKKyAgICB9Cit9CisKK3N0YXRpYyB2b2lkIERlZmxhdGVyX3NldExldmVsc0ltcGwoSk5JRW52KiBlbnYsIGpvYmplY3QsIGludCBsZXZlbCwgaW50IHN0cmF0ZWd5LCBqbG9uZyBoYW5kbGUpIHsKKyAgICBOYXRpdmVaaXBTdHJlYW0qIHN0cmVhbSA9IHRvTmF0aXZlWmlwU3RyZWFtKGhhbmRsZSk7CisgICAgLy8gVGhlIGRlZmxhdGVQYXJhbXMgZG9jdW1lbnRhdGlvbiBzYXlzIHRoYXQgYXZhaWxfb3V0IG11c3QgbmV2ZXIgYmUgMCBiZWNhdXNlIGl0IG1heSBiZQorICAgIC8vIG5lY2Vzc2FyeSB0byBmbHVzaCwgYnV0IHRoZSBKYXZhIEFQSSBlbnN1cmVzIHRoYXQgd2Ugb25seSBnZXQgaGVyZSBpZiB0aGVyZSdzIG5vdGhpbmcKKyAgICAvLyB0byBmbHVzaC4gVG8gYmUgb24gdGhlIHNhZmUgc2lkZSwgbWFrZSBzdXJlIHRoYXQgd2UncmUgbm90IHBvaW50aW5nIHRvIGEgbm8gbG9uZ2VyIHZhbGlkCisgICAgLy8gYnVmZmVyLgorICAgIHN0cmVhbS0+c3RyZWFtLm5leHRfb3V0ID0gcmVpbnRlcnByZXRfY2FzdDxCeXRlZio+KE5VTEwpOworICAgIHN0cmVhbS0+c3RyZWFtLmF2YWlsX291dCA9IDA7CisgICAgaW50IGVyciA9IGRlZmxhdGVQYXJhbXMoJnN0cmVhbS0+c3RyZWFtLCBsZXZlbCwgc3RyYXRlZ3kpOworICAgIGlmIChlcnIgIT0gWl9PSykgeworICAgICAgICB0aHJvd0V4Y2VwdGlvbkZvclpsaWJFcnJvcihlbnYsICJqYXZhL2xhbmcvSWxsZWdhbFN0YXRlRXhjZXB0aW9uIiwgZXJyKTsKKyAgICB9Cit9CisKK3N0YXRpYyBKTklOYXRpdmVNZXRob2QgZ01ldGhvZHNbXSA9IHsKKyAgICBOQVRJVkVfTUVUSE9EKERlZmxhdGVyLCBjcmVhdGVTdHJlYW0sICIoSUlaKUoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKERlZmxhdGVyLCBkZWZsYXRlSW1wbCwgIihbQklJSkkpSSIpLAorICAgIE5BVElWRV9NRVRIT0QoRGVmbGF0ZXIsIGVuZEltcGwsICIoSilWIiksCisgICAgTkFUSVZFX01FVEhPRChEZWZsYXRlciwgZ2V0QWRsZXJJbXBsLCAiKEopSSIpLAorICAgIE5BVElWRV9NRVRIT0QoRGVmbGF0ZXIsIGdldFRvdGFsSW5JbXBsLCAiKEopSiIpLAorICAgIE5BVElWRV9NRVRIT0QoRGVmbGF0ZXIsIGdldFRvdGFsT3V0SW1wbCwgIihKKUoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKERlZmxhdGVyLCByZXNldEltcGwsICIoSilWIiksCisgICAgTkFUSVZFX01FVEhPRChEZWZsYXRlciwgc2V0RGljdGlvbmFyeUltcGwsICIoW0JJSUopViIpLAorICAgIE5BVElWRV9NRVRIT0QoRGVmbGF0ZXIsIHNldElucHV0SW1wbCwgIihbQklJSilWIiksCisgICAgTkFUSVZFX01FVEhPRChEZWZsYXRlciwgc2V0TGV2ZWxzSW1wbCwgIihJSUopViIpLAorfTsKK2ludCByZWdpc3Rlcl9qYXZhX3V0aWxfemlwX0RlZmxhdGVyKEpOSUVudiogZW52KSB7CisgICAgcmV0dXJuIGpuaVJlZ2lzdGVyTmF0aXZlTWV0aG9kcyhlbnYsICJqYXZhL3V0aWwvemlwL0RlZmxhdGVyIiwgZ01ldGhvZHMsIE5FTEVNKGdNZXRob2RzKSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX3V0aWxfemlwX0luZmxhdGVyLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2phdmFfdXRpbF96aXBfSW5mbGF0ZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE5MmQxYjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9qYXZhX3V0aWxfemlwX0luZmxhdGVyLmNwcApAQCAtMCwwICsxLDE3MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiSW5mbGF0ZXIiCisKKyNpbmNsdWRlICJKbmlDb25zdGFudHMuaCIKKyNpbmNsdWRlICJTY29wZWRQcmltaXRpdmVBcnJheS5oIgorI2luY2x1ZGUgInppcC5oIgorI2luY2x1ZGUgPGVycm5vLmg+CisKK3N0YXRpYyBqbG9uZyBJbmZsYXRlcl9jcmVhdGVTdHJlYW0oSk5JRW52KiBlbnYsIGpvYmplY3QsIGpib29sZWFuIG5vSGVhZGVyKSB7CisgICAgVW5pcXVlUHRyPE5hdGl2ZVppcFN0cmVhbT4ganN0cmVhbShuZXcgTmF0aXZlWmlwU3RyZWFtKTsKKyAgICBpZiAoanN0cmVhbS5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIGpuaVRocm93T3V0T2ZNZW1vcnlFcnJvcihlbnYsIE5VTEwpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGpzdHJlYW0tPnN0cmVhbS5hZGxlciA9IDE7CisKKyAgICAvKgorICAgICAqIFNlZSB6bGliLmggZm9yIGRvY3VtZW50YXRpb24gb2YgdGhlIGluZmxhdGVJbml0MiB3aW5kb3dCaXRzIHBhcmFtZXRlci4KKyAgICAgKgorICAgICAqIHpjb25mLmggc2F5cyB0aGUgInJlcXVpcmVtZW50cyBmb3IgaW5mbGF0ZSBhcmUgKGluIGJ5dGVzKSAxIDw8IHdpbmRvd0JpdHMKKyAgICAgKiB0aGF0IGlzLCAzMksgZm9yIHdpbmRvd0JpdHM9MTUgKGRlZmF1bHQgdmFsdWUpIHBsdXMgYSBmZXcga2lsb2J5dGVzCisgICAgICogZm9yIHNtYWxsIG9iamVjdHMuIiBUaGlzIG1lYW5zIHRoYXQgd2UgY2FuIGhhcHBpbHkgdXNlIHRoZSBkZWZhdWx0CisgICAgICogaGVyZSB3aXRob3V0IHdvcnJ5aW5nIGFib3V0IG1lbW9yeSBjb25zdW1wdGlvbi4KKyAgICAgKi8KKyAgICBpbnQgZXJyID0gaW5mbGF0ZUluaXQyKCZqc3RyZWFtLT5zdHJlYW0sIG5vSGVhZGVyID8gLURFRl9XQklUUyA6IERFRl9XQklUUyk7CisgICAgaWYgKGVyciAhPSBaX09LKSB7CisgICAgICAgIHRocm93RXhjZXB0aW9uRm9yWmxpYkVycm9yKGVudiwgImphdmEvbGFuZy9JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iLCBlcnIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHJldHVybiByZWludGVycHJldF9jYXN0PHVpbnRwdHJfdD4oanN0cmVhbS5yZWxlYXNlKCkpOworfQorCitzdGF0aWMgdm9pZCBJbmZsYXRlcl9zZXRJbnB1dEltcGwoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpieXRlQXJyYXkgYnVmLCBqaW50IG9mZiwgamludCBsZW4sIGpsb25nIGhhbmRsZSkgeworICAgIHRvTmF0aXZlWmlwU3RyZWFtKGhhbmRsZSktPnNldElucHV0KGVudiwgYnVmLCBvZmYsIGxlbik7Cit9CisKK3N0YXRpYyBqaW50IEluZmxhdGVyX3NldEZpbGVJbnB1dEltcGwoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpvYmplY3QgamF2YUZpbGVEZXNjcmlwdG9yLCBqbG9uZyBvZmYsIGppbnQgbGVuLCBqbG9uZyBoYW5kbGUpIHsKKyAgICBOYXRpdmVaaXBTdHJlYW0qIHN0cmVhbSA9IHRvTmF0aXZlWmlwU3RyZWFtKGhhbmRsZSk7CisKKyAgICAvLyBXZSByZXVzZSB0aGUgZXhpc3RpbmcgbmF0aXZlIGJ1ZmZlciBpZiBpdCdzIGxhcmdlIGVub3VnaC4KKyAgICAvLyBUT0RPOiBiZW5jaG1hcmsuCisgICAgaWYgKHN0cmVhbS0+aW5DYXAgPCBsZW4pIHsKKyAgICAgICAgc3RyZWFtLT5zZXRJbnB1dChlbnYsIE5VTEwsIDAsIGxlbik7CisgICAgfSBlbHNlIHsKKyAgICAgICAgc3RyZWFtLT5zdHJlYW0ubmV4dF9pbiA9IHJlaW50ZXJwcmV0X2Nhc3Q8Qnl0ZWYqPigmc3RyZWFtLT5pbnB1dFswXSk7CisgICAgICAgIHN0cmVhbS0+c3RyZWFtLmF2YWlsX2luID0gbGVuOworICAgIH0KKworICAgIC8vIEFzIGFuIEFuZHJvaWQtc3BlY2lmaWMgb3B0aW1pemF0aW9uLCB3ZSByZWFkIGRpcmVjdGx5IG9udG8gdGhlIG5hdGl2ZSBoZWFwLgorICAgIC8vIFRoZSBvcmlnaW5hbCBjb2RlIHVzZWQgSmF2YSB0byByZWFkIG9udG8gdGhlIEphdmEgaGVhcCBhbmQgdGhlbiBjYWxsZWQgc2V0SW5wdXQoYnl0ZVtdKS4KKyAgICAvLyBUT0RPOiBiZW5jaG1hcmsuCisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmlsZURlc2NyaXB0b3IpOworICAgIGludCByYyA9IFRFTVBfRkFJTFVSRV9SRVRSWShsc2VlayhmZCwgb2ZmLCBTRUVLX1NFVCkpOworICAgIGlmIChyYyA9PSAtMSkgeworICAgICAgICBqbmlUaHJvd0lPRXhjZXB0aW9uKGVudiwgZXJybm8pOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgamludCB0b3RhbEJ5dGVDb3VudCA9IDA7CisgICAgQnl0ZWYqIGRzdCA9IHJlaW50ZXJwcmV0X2Nhc3Q8Qnl0ZWYqPigmc3RyZWFtLT5pbnB1dFswXSk7CisgICAgc3NpemVfdCBieXRlQ291bnQ7CisgICAgd2hpbGUgKChieXRlQ291bnQgPSBURU1QX0ZBSUxVUkVfUkVUUlkocmVhZChmZCwgZHN0LCBsZW4pKSkgPiAwKSB7CisgICAgICAgIGRzdCArPSBieXRlQ291bnQ7CisgICAgICAgIGxlbiAtPSBieXRlQ291bnQ7CisgICAgICAgIHRvdGFsQnl0ZUNvdW50ICs9IGJ5dGVDb3VudDsKKyAgICB9CisgICAgaWYgKGJ5dGVDb3VudCA9PSAtMSkgeworICAgICAgICBqbmlUaHJvd0lPRXhjZXB0aW9uKGVudiwgZXJybm8pOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgcmV0dXJuIHRvdGFsQnl0ZUNvdW50OworfQorCitzdGF0aWMgamludCBJbmZsYXRlcl9pbmZsYXRlSW1wbChKTklFbnYqIGVudiwgam9iamVjdCByZWN2LCBqYnl0ZUFycmF5IGJ1ZiwgaW50IG9mZiwgaW50IGxlbiwgamxvbmcgaGFuZGxlKSB7CisgICAgTmF0aXZlWmlwU3RyZWFtKiBzdHJlYW0gPSB0b05hdGl2ZVppcFN0cmVhbShoYW5kbGUpOworICAgIFNjb3BlZEJ5dGVBcnJheVJXIG91dChlbnYsIGJ1Zik7CisgICAgaWYgKG91dC5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgc3RyZWFtLT5zdHJlYW0ubmV4dF9vdXQgPSByZWludGVycHJldF9jYXN0PEJ5dGVmKj4ob3V0LmdldCgpICsgb2ZmKTsKKyAgICBzdHJlYW0tPnN0cmVhbS5hdmFpbF9vdXQgPSBsZW47CisKKyAgICBCeXRlZiogaW5pdGlhbE5leHRJbiA9IHN0cmVhbS0+c3RyZWFtLm5leHRfaW47CisgICAgQnl0ZWYqIGluaXRpYWxOZXh0T3V0ID0gc3RyZWFtLT5zdHJlYW0ubmV4dF9vdXQ7CisKKyAgICBpbnQgZXJyID0gaW5mbGF0ZSgmc3RyZWFtLT5zdHJlYW0sIFpfU1lOQ19GTFVTSCk7CisgICAgc3dpdGNoIChlcnIpIHsKKyAgICBjYXNlIFpfT0s6CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgWl9ORUVEX0RJQ1Q6CisgICAgICAgIHN0YXRpYyBqZmllbGRJRCBuZWVkc0RpY3Rpb25hcnkgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjppbmZsYXRlckNsYXNzLCAibmVlZHNEaWN0aW9uYXJ5IiwgIloiKTsKKyAgICAgICAgZW52LT5TZXRCb29sZWFuRmllbGQocmVjdiwgbmVlZHNEaWN0aW9uYXJ5LCBKTklfVFJVRSk7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgWl9TVFJFQU1fRU5EOgorICAgICAgICBzdGF0aWMgamZpZWxkSUQgZmluaXNoZWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjppbmZsYXRlckNsYXNzLCAiZmluaXNoZWQiLCAiWiIpOworICAgICAgICBlbnYtPlNldEJvb2xlYW5GaWVsZChyZWN2LCBmaW5pc2hlZCwgSk5JX1RSVUUpOworICAgICAgICBicmVhazsKKyAgICBjYXNlIFpfU1RSRUFNX0VSUk9SOgorICAgICAgICByZXR1cm4gMDsKKyAgICBkZWZhdWx0OgorICAgICAgICB0aHJvd0V4Y2VwdGlvbkZvclpsaWJFcnJvcihlbnYsICJqYXZhL3V0aWwvemlwL0RhdGFGb3JtYXRFeGNlcHRpb24iLCBlcnIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgamludCBieXRlc1JlYWQgPSBzdHJlYW0tPnN0cmVhbS5uZXh0X2luIC0gaW5pdGlhbE5leHRJbjsKKyAgICBqaW50IGJ5dGVzV3JpdHRlbiA9IHN0cmVhbS0+c3RyZWFtLm5leHRfb3V0IC0gaW5pdGlhbE5leHRPdXQ7CisKKyAgICBzdGF0aWMgamZpZWxkSUQgaW5SZWFkRmllbGQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjppbmZsYXRlckNsYXNzLCAiaW5SZWFkIiwgIkkiKTsKKyAgICBqaW50IGluUmVhZFZhbHVlID0gZW52LT5HZXRJbnRGaWVsZChyZWN2LCBpblJlYWRGaWVsZCk7CisgICAgaW5SZWFkVmFsdWUgKz0gYnl0ZXNSZWFkOworICAgIGVudi0+U2V0SW50RmllbGQocmVjdiwgaW5SZWFkRmllbGQsIGluUmVhZFZhbHVlKTsKKyAgICByZXR1cm4gYnl0ZXNXcml0dGVuOworfQorCitzdGF0aWMgamludCBJbmZsYXRlcl9nZXRBZGxlckltcGwoSk5JRW52Kiwgam9iamVjdCwgamxvbmcgaGFuZGxlKSB7CisgICAgcmV0dXJuIHRvTmF0aXZlWmlwU3RyZWFtKGhhbmRsZSktPnN0cmVhbS5hZGxlcjsKK30KKworc3RhdGljIHZvaWQgSW5mbGF0ZXJfZW5kSW1wbChKTklFbnYqLCBqb2JqZWN0LCBqbG9uZyBoYW5kbGUpIHsKKyAgICBOYXRpdmVaaXBTdHJlYW0qIHN0cmVhbSA9IHRvTmF0aXZlWmlwU3RyZWFtKGhhbmRsZSk7CisgICAgaW5mbGF0ZUVuZCgmc3RyZWFtLT5zdHJlYW0pOworICAgIGRlbGV0ZSBzdHJlYW07Cit9CisKK3N0YXRpYyB2b2lkIEluZmxhdGVyX3NldERpY3Rpb25hcnlJbXBsKEpOSUVudiogZW52LCBqb2JqZWN0LCBqYnl0ZUFycmF5IGRpY3QsIGludCBvZmYsIGludCBsZW4sIGpsb25nIGhhbmRsZSkgeworICAgIHRvTmF0aXZlWmlwU3RyZWFtKGhhbmRsZSktPnNldERpY3Rpb25hcnkoZW52LCBkaWN0LCBvZmYsIGxlbiwgdHJ1ZSk7Cit9CisKK3N0YXRpYyB2b2lkIEluZmxhdGVyX3Jlc2V0SW1wbChKTklFbnYqIGVudiwgam9iamVjdCwgamxvbmcgaGFuZGxlKSB7CisgICAgaW50IGVyciA9IGluZmxhdGVSZXNldCgmdG9OYXRpdmVaaXBTdHJlYW0oaGFuZGxlKS0+c3RyZWFtKTsKKyAgICBpZiAoZXJyICE9IFpfT0spIHsKKyAgICAgICAgdGhyb3dFeGNlcHRpb25Gb3JabGliRXJyb3IoZW52LCAiamF2YS9sYW5nL0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIsIGVycik7CisgICAgfQorfQorCitzdGF0aWMgamxvbmcgSW5mbGF0ZXJfZ2V0VG90YWxPdXRJbXBsKEpOSUVudiosIGpvYmplY3QsIGpsb25nIGhhbmRsZSkgeworICAgIHJldHVybiB0b05hdGl2ZVppcFN0cmVhbShoYW5kbGUpLT5zdHJlYW0udG90YWxfb3V0OworfQorCitzdGF0aWMgamxvbmcgSW5mbGF0ZXJfZ2V0VG90YWxJbkltcGwoSk5JRW52Kiwgam9iamVjdCwgamxvbmcgaGFuZGxlKSB7CisgICAgcmV0dXJuIHRvTmF0aXZlWmlwU3RyZWFtKGhhbmRsZSktPnN0cmVhbS50b3RhbF9pbjsKK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBnTWV0aG9kc1tdID0geworICAgIE5BVElWRV9NRVRIT0QoSW5mbGF0ZXIsIGNyZWF0ZVN0cmVhbSwgIihaKUoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEluZmxhdGVyLCBlbmRJbXBsLCAiKEopViIpLAorICAgIE5BVElWRV9NRVRIT0QoSW5mbGF0ZXIsIGdldEFkbGVySW1wbCwgIihKKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEluZmxhdGVyLCBnZXRUb3RhbEluSW1wbCwgIihKKUoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEluZmxhdGVyLCBnZXRUb3RhbE91dEltcGwsICIoSilKIiksCisgICAgTkFUSVZFX01FVEhPRChJbmZsYXRlciwgaW5mbGF0ZUltcGwsICIoW0JJSUopSSIpLAorICAgIE5BVElWRV9NRVRIT0QoSW5mbGF0ZXIsIHJlc2V0SW1wbCwgIihKKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEluZmxhdGVyLCBzZXREaWN0aW9uYXJ5SW1wbCwgIihbQklJSilWIiksCisgICAgTkFUSVZFX01FVEhPRChJbmZsYXRlciwgc2V0RmlsZUlucHV0SW1wbCwgIihMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtKSUopSSIpLAorICAgIE5BVElWRV9NRVRIT0QoSW5mbGF0ZXIsIHNldElucHV0SW1wbCwgIihbQklJSilWIiksCit9OworaW50IHJlZ2lzdGVyX2phdmFfdXRpbF96aXBfSW5mbGF0ZXIoSk5JRW52KiBlbnYpIHsKKyAgICByZXR1cm4gam5pUmVnaXN0ZXJOYXRpdmVNZXRob2RzKGVudiwgImphdmEvdXRpbC96aXAvSW5mbGF0ZXIiLCBnTWV0aG9kcywgTkVMRU0oZ01ldGhvZHMpKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL2xpYmNvcmVfaWN1X0lDVS5jcHAgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9saWJjb3JlX2ljdV9JQ1UuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmOTZmNDIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9saWJjb3JlX2ljdV9JQ1UuY3BwCkBAIC0wLDAgKzEsODA0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJJQ1UiCisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisjaW5jbHVkZSAiSm5pRXhjZXB0aW9uLmgiCisjaW5jbHVkZSAiU2NvcGVkRmQuaCIKKyNpbmNsdWRlICJTY29wZWRKYXZhVW5pY29kZVN0cmluZy5oIgorI2luY2x1ZGUgIlNjb3BlZExvY2FsUmVmLmgiCisjaW5jbHVkZSAiU2NvcGVkU3RyaW5nQ2hhcnMuaCIKKyNpbmNsdWRlICJTY29wZWRVdGZDaGFycy5oIgorI2luY2x1ZGUgIlVuaXF1ZVB0ci5oIgorI2luY2x1ZGUgImN1dGlscy9sb2cuaCIKKyNpbmNsdWRlICJ0b1N0cmluZ0FycmF5LmgiCisjaW5jbHVkZSAidW5pY29kZS9jYWxlbmRhci5oIgorI2luY2x1ZGUgInVuaWNvZGUvZGF0ZWZtdC5oIgorI2luY2x1ZGUgInVuaWNvZGUvZGNmbXRzeW0uaCIKKyNpbmNsdWRlICJ1bmljb2RlL2RlY2ltZm10LmgiCisjaW5jbHVkZSAidW5pY29kZS9kdGZtdHN5bS5oIgorI2luY2x1ZGUgInVuaWNvZGUvZ3JlZ29jYWwuaCIKKyNpbmNsdWRlICJ1bmljb2RlL2xvY2lkLmgiCisjaW5jbHVkZSAidW5pY29kZS9udW1mbXQuaCIKKyNpbmNsdWRlICJ1bmljb2RlL3N0cmVudW0uaCIKKyNpbmNsdWRlICJ1bmljb2RlL3VicmsuaCIKKyNpbmNsdWRlICJ1bmljb2RlL3VjYWwuaCIKKyNpbmNsdWRlICJ1bmljb2RlL3VjbGVhbi5oIgorI2luY2x1ZGUgInVuaWNvZGUvdWNvbC5oIgorI2luY2x1ZGUgInVuaWNvZGUvdWN1cnIuaCIKKyNpbmNsdWRlICJ1bmljb2RlL3VkYXQuaCIKKyNpbmNsdWRlICJ1bmljb2RlL3Vsb2MuaCIKKyNpbmNsdWRlICJ1bmljb2RlL3VzdHJpbmcuaCIKKyNpbmNsdWRlICJ1cmVzbG9jcy5oIgorI2luY2x1ZGUgInZhbHVlT2YuaCIKKworI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8c3lzL21tYW4uaD4KKyNpbmNsdWRlIDxzeXMvc3RhdC5oPgorI2luY2x1ZGUgPHN5cy90aW1lLmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8dGltZS5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorCitjbGFzcyBTY29wZWRSZXNvdXJjZUJ1bmRsZSB7CitwdWJsaWM6CisgICAgU2NvcGVkUmVzb3VyY2VCdW5kbGUoVVJlc291cmNlQnVuZGxlKiBidW5kbGUpIDogbUJ1bmRsZShidW5kbGUpIHsKKyAgICB9CisKKyAgICB+U2NvcGVkUmVzb3VyY2VCdW5kbGUoKSB7CisgICAgICAgIGlmIChtQnVuZGxlICE9IE5VTEwpIHsKKyAgICAgICAgICAgIHVyZXNfY2xvc2UobUJ1bmRsZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBVUmVzb3VyY2VCdW5kbGUqIGdldCgpIHsKKyAgICAgICAgcmV0dXJuIG1CdW5kbGU7CisgICAgfQorCitwcml2YXRlOgorICAgIFVSZXNvdXJjZUJ1bmRsZSogbUJ1bmRsZTsKKworICAgIC8vIERpc2FsbG93IGNvcHkgYW5kIGFzc2lnbm1lbnQuCisgICAgU2NvcGVkUmVzb3VyY2VCdW5kbGUoY29uc3QgU2NvcGVkUmVzb3VyY2VCdW5kbGUmKTsKKyAgICB2b2lkIG9wZXJhdG9yPShjb25zdCBTY29wZWRSZXNvdXJjZUJ1bmRsZSYpOworfTsKKworTG9jYWxlIGdldExvY2FsZShKTklFbnYqIGVudiwganN0cmluZyBsb2NhbGVOYW1lKSB7CisgICAgcmV0dXJuIExvY2FsZTo6Y3JlYXRlRnJvbU5hbWUoU2NvcGVkVXRmQ2hhcnMoZW52LCBsb2NhbGVOYW1lKS5jX3N0cigpKTsKK30KKworc3RhdGljIGpzdHJpbmcgSUNVX2FkZExpa2VseVN1YnRhZ3MoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBqYXZhTG9jYWxlKSB7CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgU2NvcGVkVXRmQ2hhcnMgbG9jYWxlSUQoZW52LCBqYXZhTG9jYWxlKTsKKyAgICBjaGFyIG1heGltaXplZExvY2FsZUlEW1VMT0NfRlVMTE5BTUVfQ0FQQUNJVFldOworICAgIHVsb2NfYWRkTGlrZWx5U3VidGFncyhsb2NhbGVJRC5jX3N0cigpLCBtYXhpbWl6ZWRMb2NhbGVJRCwgc2l6ZW9mKG1heGltaXplZExvY2FsZUlEKSwgJnN0YXR1cyk7CisgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CisgICAgICAgIHJldHVybiBqYXZhTG9jYWxlOworICAgIH0KKyAgICByZXR1cm4gZW52LT5OZXdTdHJpbmdVVEYobWF4aW1pemVkTG9jYWxlSUQpOworfQorCitzdGF0aWMganN0cmluZyBJQ1VfZ2V0U2NyaXB0KEpOSUVudiogZW52LCBqY2xhc3MsIGpzdHJpbmcgamF2YUxvY2FsZSkgeworICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworICAgIFNjb3BlZFV0ZkNoYXJzIGxvY2FsZUlEKGVudiwgamF2YUxvY2FsZSk7CisgICAgY2hhciBzY3JpcHRbVUxPQ19TQ1JJUFRfQ0FQQUNJVFldOworICAgIHVsb2NfZ2V0U2NyaXB0KGxvY2FsZUlELmNfc3RyKCksIHNjcmlwdCwgc2l6ZW9mKHNjcmlwdCksICZzdGF0dXMpOworICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIGVudi0+TmV3U3RyaW5nVVRGKHNjcmlwdCk7Cit9CisKK3N0YXRpYyBqaW50IElDVV9nZXRDdXJyZW5jeUZyYWN0aW9uRGlnaXRzKEpOSUVudiogZW52LCBqY2xhc3MsIGpzdHJpbmcgamF2YUN1cnJlbmN5Q29kZSkgeworICAgIFNjb3BlZEphdmFVbmljb2RlU3RyaW5nIGN1cnJlbmN5Q29kZShlbnYsIGphdmFDdXJyZW5jeUNvZGUpOworICAgIFVuaWNvZGVTdHJpbmcgaWN1Q3VycmVuY3lDb2RlKGN1cnJlbmN5Q29kZS51bmljb2RlU3RyaW5nKCkpOworICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworICAgIHJldHVybiB1Y3Vycl9nZXREZWZhdWx0RnJhY3Rpb25EaWdpdHMoaWN1Q3VycmVuY3lDb2RlLmdldFRlcm1pbmF0ZWRCdWZmZXIoKSwgJnN0YXR1cyk7Cit9CisKK3N0YXRpYyBqc3RyaW5nIElDVV9nZXRDdXJyZW5jeUNvZGUoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBqYXZhQ291bnRyeUNvZGUpIHsKKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBTY29wZWRSZXNvdXJjZUJ1bmRsZSBzdXBwbERhdGEodXJlc19vcGVuRGlyZWN0KFVfSUNVREFUQV9DVVJSLCAic3VwcGxlbWVudGFsRGF0YSIsICZzdGF0dXMpKTsKKyAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgU2NvcGVkUmVzb3VyY2VCdW5kbGUgY3VycmVuY3lNYXAodXJlc19nZXRCeUtleShzdXBwbERhdGEuZ2V0KCksICJDdXJyZW5jeU1hcCIsIE5VTEwsICZzdGF0dXMpKTsKKyAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgU2NvcGVkVXRmQ2hhcnMgY291bnRyeUNvZGUoZW52LCBqYXZhQ291bnRyeUNvZGUpOworICAgIFNjb3BlZFJlc291cmNlQnVuZGxlIGN1cnJlbmN5KHVyZXNfZ2V0QnlLZXkoY3VycmVuY3lNYXAuZ2V0KCksIGNvdW50cnlDb2RlLmNfc3RyKCksIE5VTEwsICZzdGF0dXMpKTsKKyAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgU2NvcGVkUmVzb3VyY2VCdW5kbGUgY3VycmVuY3lFbGVtKHVyZXNfZ2V0QnlJbmRleChjdXJyZW5jeS5nZXQoKSwgMCwgTlVMTCwgJnN0YXR1cykpOworICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgeworICAgICAgICByZXR1cm4gZW52LT5OZXdTdHJpbmdVVEYoIk5vbmUiKTsKKyAgICB9CisKKyAgICAvLyBDaGVjayBpZiB0aGVyZSdzIGEgJ3RvJyBkYXRlLiBJZiB0aGVyZSBpcywgdGhlIGN1cnJlbmN5IGlzbid0IHVzZWQgYW55bW9yZS4KKyAgICBTY29wZWRSZXNvdXJjZUJ1bmRsZSBjdXJyZW5jeVRvKHVyZXNfZ2V0QnlLZXkoY3VycmVuY3lFbGVtLmdldCgpLCAidG8iLCBOVUxMLCAmc3RhdHVzKSk7CisgICAgaWYgKCFVX0ZBSUxVUkUoc3RhdHVzKSkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgLy8gSWdub3JlIHRoZSBmYWlsdXJlIHRvIGZpbmQgYSAndG8nIGRhdGUuCisgICAgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworCisgICAgU2NvcGVkUmVzb3VyY2VCdW5kbGUgY3VycmVuY3lJZCh1cmVzX2dldEJ5S2V5KGN1cnJlbmN5RWxlbS5nZXQoKSwgImlkIiwgTlVMTCwgJnN0YXR1cykpOworICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgeworICAgICAgICAvLyBObyBpZCBkZWZpbmVkIGZvciB0aGlzIGNvdW50cnkKKyAgICAgICAgcmV0dXJuIGVudi0+TmV3U3RyaW5nVVRGKCJOb25lIik7CisgICAgfQorCisgICAgaW50MzJfdCBjaGFyQ291bnQ7CisgICAgY29uc3QgamNoYXIqIGNoYXJzID0gdXJlc19nZXRTdHJpbmcoY3VycmVuY3lJZC5nZXQoKSwgJmNoYXJDb3VudCwgJnN0YXR1cyk7CisgICAgcmV0dXJuIChjaGFyQ291bnQgPT0gMCkgPyBlbnYtPk5ld1N0cmluZ1VURigiTm9uZSIpIDogZW52LT5OZXdTdHJpbmcoY2hhcnMsIGNoYXJDb3VudCk7Cit9CisKK3N0YXRpYyBqc3RyaW5nIElDVV9nZXRDdXJyZW5jeURpc3BsYXlOYW1lKEpOSUVudiogZW52LCBqY2xhc3MsIGpzdHJpbmcgamF2YUxvY2FsZU5hbWUsIGpzdHJpbmcgamF2YUN1cnJlbmN5Q29kZSkgeworICAgIFNjb3BlZFV0ZkNoYXJzIGxvY2FsZU5hbWUoZW52LCBqYXZhTG9jYWxlTmFtZSk7CisgICAgU2NvcGVkSmF2YVVuaWNvZGVTdHJpbmcgY3VycmVuY3lDb2RlKGVudiwgamF2YUN1cnJlbmN5Q29kZSk7CisgICAgVW5pY29kZVN0cmluZyBpY3VDdXJyZW5jeUNvZGUoY3VycmVuY3lDb2RlLnVuaWNvZGVTdHJpbmcoKSk7CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgVUJvb2wgaXNDaG9pY2VGb3JtYXQ7CisgICAgaW50MzJfdCBjaGFyQ291bnQ7CisgICAgY29uc3QgVUNoYXIqIGNoYXJzID0gdWN1cnJfZ2V0TmFtZShpY3VDdXJyZW5jeUNvZGUuZ2V0VGVybWluYXRlZEJ1ZmZlcigpLCBsb2NhbGVOYW1lLmNfc3RyKCksCisgICAgICAgICAgICBVQ1VSUl9MT05HX05BTUUsICZpc0Nob2ljZUZvcm1hdCwgJmNoYXJDb3VudCwgJnN0YXR1cyk7CisgICAgaWYgKHN0YXR1cyA9PSBVX1VTSU5HX0RFRkFVTFRfV0FSTklORykgeworICAgICAgICAvLyBJQ1UncyBkZWZhdWx0IGlzIEVuZ2xpc2guIFdlIHdhbnQgdGhlIElTTyA0MjE3IGN1cnJlbmN5IGNvZGUgaW5zdGVhZC4KKyAgICAgICAgY2hhcnMgPSBpY3VDdXJyZW5jeUNvZGUuZ2V0QnVmZmVyKCk7CisgICAgICAgIGNoYXJDb3VudCA9IGljdUN1cnJlbmN5Q29kZS5sZW5ndGgoKTsKKyAgICB9CisgICAgcmV0dXJuIChjaGFyQ291bnQgPT0gMCkgPyBOVUxMIDogZW52LT5OZXdTdHJpbmcoY2hhcnMsIGNoYXJDb3VudCk7Cit9CisKK3N0YXRpYyBqc3RyaW5nIElDVV9nZXRDdXJyZW5jeVN5bWJvbChKTklFbnYqIGVudiwgamNsYXNzLCBqc3RyaW5nIGxvY2FsZSwganN0cmluZyBjdXJyZW5jeUNvZGUpIHsKKyAgICAvLyBXZSBjYW4ndCB1c2UgdWN1cnJfZ2V0TmFtZSBiZWNhdXNlIGl0IGRvZXNuJ3QgZGlzdGluZ3Vpc2ggYmV0d2VlbiB1c2luZyBkYXRhIHJvb3QgZnJvbQorICAgIC8vIHRoZSByb290IGxvY2FsZSBhbmQgcGFycm90aW5nIGJhY2sgdGhlIGlucHV0IGJlY2F1c2UgaXQncyBuZXZlciBoZWFyZCBvZiB0aGUgY3VycmVuY3kgY29kZS4KKyAgICBTY29wZWRVdGZDaGFycyBsb2NhbGVOYW1lKGVudiwgbG9jYWxlKTsKKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBTY29wZWRSZXNvdXJjZUJ1bmRsZSBjdXJyTG9jKHVyZXNfb3BlbihVX0lDVURBVEFfQ1VSUiwgbG9jYWxlTmFtZS5jX3N0cigpLCAmc3RhdHVzKSk7CisgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIFNjb3BlZFJlc291cmNlQnVuZGxlIGN1cnJlbmNpZXModXJlc19nZXRCeUtleShjdXJyTG9jLmdldCgpLCAiQ3VycmVuY2llcyIsIE5VTEwsICZzdGF0dXMpKTsKKyAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgU2NvcGVkVXRmQ2hhcnMgY3VycmVuY3koZW52LCBjdXJyZW5jeUNvZGUpOworICAgIFNjb3BlZFJlc291cmNlQnVuZGxlIGN1cnJlbmN5RWxlbXModXJlc19nZXRCeUtleShjdXJyZW5jaWVzLmdldCgpLCBjdXJyZW5jeS5jX3N0cigpLCBOVUxMLCAmc3RhdHVzKSk7CisgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGludDMyX3QgY2hhckNvdW50OworICAgIGNvbnN0IGpjaGFyKiBjaGFycyA9IHVyZXNfZ2V0U3RyaW5nQnlJbmRleChjdXJyZW5jeUVsZW1zLmdldCgpLCAwLCAmY2hhckNvdW50LCAmc3RhdHVzKTsKKyAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiAoY2hhckNvdW50ID09IDApID8gTlVMTCA6IGVudi0+TmV3U3RyaW5nKGNoYXJzLCBjaGFyQ291bnQpOworfQorCitzdGF0aWMganN0cmluZyBJQ1VfZ2V0RGlzcGxheUNvdW50cnlOYXRpdmUoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyB0YXJnZXRMb2NhbGUsIGpzdHJpbmcgbG9jYWxlKSB7CisgICAgTG9jYWxlIGxvYyA9IGdldExvY2FsZShlbnYsIGxvY2FsZSk7CisgICAgTG9jYWxlIHRhcmdldExvYyA9IGdldExvY2FsZShlbnYsIHRhcmdldExvY2FsZSk7CisgICAgVW5pY29kZVN0cmluZyBzdHI7CisgICAgdGFyZ2V0TG9jLmdldERpc3BsYXlDb3VudHJ5KGxvYywgc3RyKTsKKyAgICByZXR1cm4gZW52LT5OZXdTdHJpbmcoc3RyLmdldEJ1ZmZlcigpLCBzdHIubGVuZ3RoKCkpOworfQorCitzdGF0aWMganN0cmluZyBJQ1VfZ2V0RGlzcGxheUxhbmd1YWdlTmF0aXZlKEpOSUVudiogZW52LCBqY2xhc3MsIGpzdHJpbmcgdGFyZ2V0TG9jYWxlLCBqc3RyaW5nIGxvY2FsZSkgeworICAgIExvY2FsZSBsb2MgPSBnZXRMb2NhbGUoZW52LCBsb2NhbGUpOworICAgIExvY2FsZSB0YXJnZXRMb2MgPSBnZXRMb2NhbGUoZW52LCB0YXJnZXRMb2NhbGUpOworICAgIFVuaWNvZGVTdHJpbmcgc3RyOworICAgIHRhcmdldExvYy5nZXREaXNwbGF5TGFuZ3VhZ2UobG9jLCBzdHIpOworICAgIHJldHVybiBlbnYtPk5ld1N0cmluZyhzdHIuZ2V0QnVmZmVyKCksIHN0ci5sZW5ndGgoKSk7Cit9CisKK3N0YXRpYyBqc3RyaW5nIElDVV9nZXREaXNwbGF5VmFyaWFudE5hdGl2ZShKTklFbnYqIGVudiwgamNsYXNzLCBqc3RyaW5nIHRhcmdldExvY2FsZSwganN0cmluZyBsb2NhbGUpIHsKKyAgICBMb2NhbGUgbG9jID0gZ2V0TG9jYWxlKGVudiwgbG9jYWxlKTsKKyAgICBMb2NhbGUgdGFyZ2V0TG9jID0gZ2V0TG9jYWxlKGVudiwgdGFyZ2V0TG9jYWxlKTsKKyAgICBVbmljb2RlU3RyaW5nIHN0cjsKKyAgICB0YXJnZXRMb2MuZ2V0RGlzcGxheVZhcmlhbnQobG9jLCBzdHIpOworICAgIHJldHVybiBlbnYtPk5ld1N0cmluZyhzdHIuZ2V0QnVmZmVyKCksIHN0ci5sZW5ndGgoKSk7Cit9CisKK3N0YXRpYyBqc3RyaW5nIElDVV9nZXRJU08zQ291bnRyeU5hdGl2ZShKTklFbnYqIGVudiwgamNsYXNzLCBqc3RyaW5nIGxvY2FsZSkgeworICAgIExvY2FsZSBsb2MgPSBnZXRMb2NhbGUoZW52LCBsb2NhbGUpOworICAgIHJldHVybiBlbnYtPk5ld1N0cmluZ1VURihsb2MuZ2V0SVNPM0NvdW50cnkoKSk7Cit9CisKK3N0YXRpYyBqc3RyaW5nIElDVV9nZXRJU08zTGFuZ3VhZ2VOYXRpdmUoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBsb2NhbGUpIHsKKyAgICBMb2NhbGUgbG9jID0gZ2V0TG9jYWxlKGVudiwgbG9jYWxlKTsKKyAgICByZXR1cm4gZW52LT5OZXdTdHJpbmdVVEYobG9jLmdldElTTzNMYW5ndWFnZSgpKTsKK30KKworc3RhdGljIGpvYmplY3RBcnJheSBJQ1VfZ2V0SVNPQ291bnRyaWVzTmF0aXZlKEpOSUVudiogZW52LCBqY2xhc3MpIHsKKyAgICByZXR1cm4gdG9TdHJpbmdBcnJheShlbnYsIExvY2FsZTo6Z2V0SVNPQ291bnRyaWVzKCkpOworfQorCitzdGF0aWMgam9iamVjdEFycmF5IElDVV9nZXRJU09MYW5ndWFnZXNOYXRpdmUoSk5JRW52KiBlbnYsIGpjbGFzcykgeworICAgIHJldHVybiB0b1N0cmluZ0FycmF5KGVudiwgTG9jYWxlOjpnZXRJU09MYW5ndWFnZXMoKSk7Cit9CisKK3N0YXRpYyBqb2JqZWN0QXJyYXkgSUNVX2dldEF2YWlsYWJsZUxvY2FsZXNOYXRpdmUoSk5JRW52KiBlbnYsIGpjbGFzcykgeworICAgIHJldHVybiB0b1N0cmluZ0FycmF5KGVudiwgdWxvY19jb3VudEF2YWlsYWJsZSwgdWxvY19nZXRBdmFpbGFibGUpOworfQorCitzdGF0aWMgam9iamVjdEFycmF5IElDVV9nZXRBdmFpbGFibGVCcmVha0l0ZXJhdG9yTG9jYWxlc05hdGl2ZShKTklFbnYqIGVudiwgamNsYXNzKSB7CisgICAgcmV0dXJuIHRvU3RyaW5nQXJyYXkoZW52LCB1YnJrX2NvdW50QXZhaWxhYmxlLCB1YnJrX2dldEF2YWlsYWJsZSk7Cit9CisKK3N0YXRpYyBqb2JqZWN0QXJyYXkgSUNVX2dldEF2YWlsYWJsZUNhbGVuZGFyTG9jYWxlc05hdGl2ZShKTklFbnYqIGVudiwgamNsYXNzKSB7CisgICAgcmV0dXJuIHRvU3RyaW5nQXJyYXkoZW52LCB1Y2FsX2NvdW50QXZhaWxhYmxlLCB1Y2FsX2dldEF2YWlsYWJsZSk7Cit9CisKK3N0YXRpYyBqb2JqZWN0QXJyYXkgSUNVX2dldEF2YWlsYWJsZUNvbGxhdG9yTG9jYWxlc05hdGl2ZShKTklFbnYqIGVudiwgamNsYXNzKSB7CisgICAgcmV0dXJuIHRvU3RyaW5nQXJyYXkoZW52LCB1Y29sX2NvdW50QXZhaWxhYmxlLCB1Y29sX2dldEF2YWlsYWJsZSk7Cit9CisKK3N0YXRpYyBqb2JqZWN0QXJyYXkgSUNVX2dldEF2YWlsYWJsZURhdGVGb3JtYXRMb2NhbGVzTmF0aXZlKEpOSUVudiogZW52LCBqY2xhc3MpIHsKKyAgICByZXR1cm4gdG9TdHJpbmdBcnJheShlbnYsIHVkYXRfY291bnRBdmFpbGFibGUsIHVkYXRfZ2V0QXZhaWxhYmxlKTsKK30KKworc3RhdGljIGpvYmplY3RBcnJheSBJQ1VfZ2V0QXZhaWxhYmxlTnVtYmVyRm9ybWF0TG9jYWxlc05hdGl2ZShKTklFbnYqIGVudiwgamNsYXNzKSB7CisgICAgcmV0dXJuIHRvU3RyaW5nQXJyYXkoZW52LCB1bnVtX2NvdW50QXZhaWxhYmxlLCB1bnVtX2dldEF2YWlsYWJsZSk7Cit9CisKK3N0YXRpYyBib29sIGdldERheUludFZlY3RvcihKTklFbnYqLCBVUmVzb3VyY2VCdW5kbGUqIGdyZWdvcmlhbiwgaW50KiB2YWx1ZXMpIHsKKyAgICAvLyBnZXQgdGhlIEZpcnN0IGRheSBvZiB3ZWVrIGFuZCB0aGUgbWluaW1hbCBkYXlzIGluIGZpcnN0IHdlZWsgbnVtYmVycworICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworICAgIFNjb3BlZFJlc291cmNlQnVuZGxlIGdyZWdvcmlhbkVsZW1zKHVyZXNfZ2V0QnlLZXkoZ3JlZ29yaWFuLCAiRGF0ZVRpbWVFbGVtZW50cyIsIE5VTEwsICZzdGF0dXMpKTsKKyAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGludCBpbnRWZWN0U2l6ZTsKKyAgICBjb25zdCBpbnQqIHJlc3VsdCA9IHVyZXNfZ2V0SW50VmVjdG9yKGdyZWdvcmlhbkVsZW1zLmdldCgpLCAmaW50VmVjdFNpemUsICZzdGF0dXMpOworICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSB8fCBpbnRWZWN0U2l6ZSAhPSAyKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICB2YWx1ZXNbMF0gPSByZXN1bHRbMF07CisgICAgdmFsdWVzWzFdID0gcmVzdWx0WzFdOworICAgIHJldHVybiB0cnVlOworfQorCisvLyBUaGlzIGFsbG93cyB5b3UgdG8gbGVhdmUgZXh0cmEgc3BhY2UgYXQgdGhlIGJlZ2lubmluZyBvciBlbmQgb2YgdGhlIGFycmF5IHRvIHN1cHBvcnQgdGhlCisvLyBtb250aCBuYW1lcyBhbmQgZGF5IG5hbWVzIGFycmF5cy4KK3N0YXRpYyBqb2JqZWN0QXJyYXkgdG9TdHJpbmdBcnJheShKTklFbnYqIGVudiwgVVJlc291cmNlQnVuZGxlKiByYiwgc2l6ZV90IHNpemUsIGludCBjYXBhY2l0eSwgc2l6ZV90IG9mZnNldCkgeworICAgIGlmIChjYXBhY2l0eSA9PSAtMSkgeworICAgICAgICBjYXBhY2l0eSA9IHNpemU7CisgICAgfQorICAgIGpvYmplY3RBcnJheSByZXN1bHQgPSBlbnYtPk5ld09iamVjdEFycmF5KGNhcGFjaXR5LCBKbmlDb25zdGFudHM6OnN0cmluZ0NsYXNzLCBOVUxMKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7CisgICAgICAgIGludCBjaGFyQ291bnQ7CisgICAgICAgIGNvbnN0IGpjaGFyKiBjaGFycyA9IHVyZXNfZ2V0U3RyaW5nQnlJbmRleChyYiwgaSwgJmNoYXJDb3VudCwgJnN0YXR1cyk7CisgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgU2NvcGVkTG9jYWxSZWY8anN0cmluZz4gcyhlbnYsIGVudi0+TmV3U3RyaW5nKGNoYXJzLCBjaGFyQ291bnQpKTsKKyAgICAgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgZW52LT5TZXRPYmplY3RBcnJheUVsZW1lbnQocmVzdWx0LCBvZmZzZXQgKyBpLCBzLmdldCgpKTsKKyAgICAgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIGpvYmplY3RBcnJheSBnZXRBbVBtTWFya2VycyhKTklFbnYqIGVudiwgVVJlc291cmNlQnVuZGxlKiBncmVnb3JpYW4pIHsKKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBTY29wZWRSZXNvdXJjZUJ1bmRsZSBhbVBtTWFya2Vycyh1cmVzX2dldEJ5S2V5KGdyZWdvcmlhbiwgIkFtUG1NYXJrZXJzIiwgTlVMTCwgJnN0YXR1cykpOworICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIHRvU3RyaW5nQXJyYXkoZW52LCBhbVBtTWFya2Vycy5nZXQoKSwgdXJlc19nZXRTaXplKGFtUG1NYXJrZXJzLmdldCgpKSwgLTEsIDApOworfQorCitzdGF0aWMgam9iamVjdEFycmF5IGdldEVyYXMoSk5JRW52KiBlbnYsIFVSZXNvdXJjZUJ1bmRsZSogZ3JlZ29yaWFuKSB7CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgU2NvcGVkUmVzb3VyY2VCdW5kbGUgZXJhcyh1cmVzX2dldEJ5S2V5KGdyZWdvcmlhbiwgImVyYXMiLCBOVUxMLCAmc3RhdHVzKSk7CisgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBTY29wZWRSZXNvdXJjZUJ1bmRsZSBhYmJyZXZpYXRlZEVyYXModXJlc19nZXRCeUtleShlcmFzLmdldCgpLCAiYWJicmV2aWF0ZWQiLCBOVUxMLCAmc3RhdHVzKSk7CisgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gdG9TdHJpbmdBcnJheShlbnYsIGFiYnJldmlhdGVkRXJhcy5nZXQoKSwgdXJlc19nZXRTaXplKGFiYnJldmlhdGVkRXJhcy5nZXQoKSksIC0xLCAwKTsKK30KKworZW51bSBOYW1lVHlwZSB7IFJFR1VMQVIsIFNUQU5EX0FMT05FIH07CitlbnVtIE5hbWVXaWR0aCB7IExPTkcsIFNIT1JUIH07CitzdGF0aWMgam9iamVjdEFycmF5IGdldE5hbWVzKEpOSUVudiogZW52LCBVUmVzb3VyY2VCdW5kbGUqIG5hbWVzQnVuZGxlLCBib29sIG1vbnRocywgTmFtZVR5cGUgdHlwZSwgTmFtZVdpZHRoIHdpZHRoKSB7CisgICAgY29uc3QgY2hhciogdHlwZUtleSA9ICh0eXBlID09IFJFR1VMQVIpID8gImZvcm1hdCIgOiAic3RhbmQtYWxvbmUiOworICAgIGNvbnN0IGNoYXIqIHdpZHRoS2V5ID0gKHdpZHRoID09IExPTkcpID8gIndpZGUiIDogImFiYnJldmlhdGVkIjsKKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBTY29wZWRSZXNvdXJjZUJ1bmRsZSBmb3JtYXRCdW5kbGUodXJlc19nZXRCeUtleShuYW1lc0J1bmRsZSwgdHlwZUtleSwgTlVMTCwgJnN0YXR1cykpOworICAgIFNjb3BlZFJlc291cmNlQnVuZGxlIHZhbHVlc0J1bmRsZSh1cmVzX2dldEJ5S2V5KGZvcm1hdEJ1bmRsZS5nZXQoKSwgd2lkdGhLZXksIE5VTEwsICZzdGF0dXMpKTsKKyAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgLy8gVGhlIG1vbnRocyBhcnJheSBoYXMgYSB0cmFpbGluZyBlbXB0eSBzdHJpbmcuIFRoZSBkYXlzIGFycmF5IGhhcyBhIGxlYWRpbmcgZW1wdHkgc3RyaW5nLgorICAgIGludCBjb3VudCA9IHVyZXNfZ2V0U2l6ZSh2YWx1ZXNCdW5kbGUuZ2V0KCkpOworICAgIGludCBvZmZzZXQgPSBtb250aHMgPyAwIDogMTsKKyAgICBqb2JqZWN0QXJyYXkgcmVzdWx0ID0gdG9TdHJpbmdBcnJheShlbnYsIHZhbHVlc0J1bmRsZS5nZXQoKSwgY291bnQsIGNvdW50ICsgMSwgb2Zmc2V0KTsKKyAgICBTY29wZWRMb2NhbFJlZjxqc3RyaW5nPiBlbXB0eVN0cmluZyhlbnYsIGVudi0+TmV3U3RyaW5nVVRGKCIiKSk7CisgICAgZW52LT5TZXRPYmplY3RBcnJheUVsZW1lbnQocmVzdWx0LCBtb250aHMgPyBjb3VudCA6IDAsIGVtcHR5U3RyaW5nLmdldCgpKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgdm9pZCBzZXRJbnRlZ2VyRmllbGQoSk5JRW52KiBlbnYsIGpvYmplY3Qgb2JqLCBjb25zdCBjaGFyKiBmaWVsZE5hbWUsIGludCB2YWx1ZSkgeworICAgIFNjb3BlZExvY2FsUmVmPGpvYmplY3Q+IGludGVnZXJWYWx1ZShlbnYsIGludGVnZXJWYWx1ZU9mKGVudiwgdmFsdWUpKTsKKyAgICBqZmllbGRJRCBmaWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjpsb2NhbGVEYXRhQ2xhc3MsIGZpZWxkTmFtZSwgIkxqYXZhL2xhbmcvSW50ZWdlcjsiKTsKKyAgICBlbnYtPlNldE9iamVjdEZpZWxkKG9iaiwgZmlkLCBpbnRlZ2VyVmFsdWUuZ2V0KCkpOworfQorCitzdGF0aWMgdm9pZCBzZXRTdHJpbmdGaWVsZChKTklFbnYqIGVudiwgam9iamVjdCBvYmosIGNvbnN0IGNoYXIqIGZpZWxkTmFtZSwganN0cmluZyB2YWx1ZSkgeworICAgIGpmaWVsZElEIGZpZCA9IGVudi0+R2V0RmllbGRJRChKbmlDb25zdGFudHM6OmxvY2FsZURhdGFDbGFzcywgZmllbGROYW1lLCAiTGphdmEvbGFuZy9TdHJpbmc7Iik7CisgICAgZW52LT5TZXRPYmplY3RGaWVsZChvYmosIGZpZCwgdmFsdWUpOworICAgIGVudi0+RGVsZXRlTG9jYWxSZWYodmFsdWUpOworfQorCitzdGF0aWMgdm9pZCBzZXRTdHJpbmdBcnJheUZpZWxkKEpOSUVudiogZW52LCBqb2JqZWN0IG9iaiwgY29uc3QgY2hhciogZmllbGROYW1lLCBqb2JqZWN0QXJyYXkgdmFsdWUpIHsKKyAgICBqZmllbGRJRCBmaWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjpsb2NhbGVEYXRhQ2xhc3MsIGZpZWxkTmFtZSwgIltMamF2YS9sYW5nL1N0cmluZzsiKTsKKyAgICBlbnYtPlNldE9iamVjdEZpZWxkKG9iaiwgZmlkLCB2YWx1ZSk7Cit9CisKK3N0YXRpYyB2b2lkIHNldFN0cmluZ0ZpZWxkKEpOSUVudiogZW52LCBqb2JqZWN0IG9iaiwgY29uc3QgY2hhciogZmllbGROYW1lLCBVUmVzb3VyY2VCdW5kbGUqIGJ1bmRsZSwgaW50IGluZGV4KSB7CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgaW50IGNoYXJDb3VudDsKKyAgICBjb25zdCBVQ2hhciogY2hhcnMgPSB1cmVzX2dldFN0cmluZ0J5SW5kZXgoYnVuZGxlLCBpbmRleCwgJmNoYXJDb3VudCwgJnN0YXR1cyk7CisgICAgaWYgKFVfU1VDQ0VTUyhzdGF0dXMpKSB7CisgICAgICAgIHNldFN0cmluZ0ZpZWxkKGVudiwgb2JqLCBmaWVsZE5hbWUsIGVudi0+TmV3U3RyaW5nKGNoYXJzLCBjaGFyQ291bnQpKTsKKyAgICB9IGVsc2UgeworICAgICAgICBMT0dFKCJFcnJvciBzZXR0aW5nIFN0cmluZyBmaWVsZCAlcyBmcm9tIElDVSByZXNvdXJjZTogJXMiLCBmaWVsZE5hbWUsIHVfZXJyb3JOYW1lKHN0YXR1cykpOworICAgIH0KK30KKworc3RhdGljIGJvb2wgc2V0U3RyaW5nRmllbGQoSk5JRW52KiBlbnYsIGpvYmplY3Qgb2JqLCBjb25zdCBjaGFyKiBrZXksIGNvbnN0IGNoYXIqIGZpZWxkTmFtZSwgVVJlc291cmNlQnVuZGxlKiBidW5kbGUpIHsKKyAgICBpZiAoYnVuZGxlID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBpbnQgY2hhckNvdW50OworICAgIGNvbnN0IFVDaGFyKiBjaGFycyA9IHVyZXNfZ2V0U3RyaW5nQnlLZXkoYnVuZGxlLCBrZXksICZjaGFyQ291bnQsICZzdGF0dXMpOworICAgIGlmIChVX1NVQ0NFU1Moc3RhdHVzKSkgeworICAgICAgICBzZXRTdHJpbmdGaWVsZChlbnYsIG9iaiwgZmllbGROYW1lLCBlbnYtPk5ld1N0cmluZyhjaGFycywgY2hhckNvdW50KSk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICAgIC8vIE1pc3NpbmcgaXRlbSBpbiBjdXJyZW50IHJlc291cmNlIGJ1bmRsZSBidXQgbm90IGFuIGVycm9yLgorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorfQorCitzdGF0aWMgdm9pZCBzZXRTdHJpbmdGaWVsZChKTklFbnYqIGVudiwgam9iamVjdCBvYmosIGNvbnN0IGNoYXIqIGtleSwgY29uc3QgY2hhciogZmllbGROYW1lLAorICAgIFVSZXNvdXJjZUJ1bmRsZSogYnVuZGxlLCBVUmVzb3VyY2VCdW5kbGUqIGZhbGxiYWNrQnVuZGxlKSB7CisgICAgaWYgKCFzZXRTdHJpbmdGaWVsZChlbnYsIG9iaiwga2V5LCBmaWVsZE5hbWUsIGJ1bmRsZSkgJiYgZmFsbGJhY2tCdW5kbGUgIT0gTlVMTCkgeworICAgICAgICBzZXRTdHJpbmdGaWVsZChlbnYsIG9iaiwga2V5LCBmaWVsZE5hbWUsIGZhbGxiYWNrQnVuZGxlKTsKKyAgICB9Cit9CisKK3N0YXRpYyBib29sIHNldENoYXJGaWVsZChKTklFbnYqIGVudiwgam9iamVjdCBvYmosIGNvbnN0IGNoYXIqIGtleSwgY29uc3QgY2hhciogZmllbGROYW1lLAorICAgIFVSZXNvdXJjZUJ1bmRsZSogYnVuZGxlKSB7CisgICAgaWYgKGJ1bmRsZSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgaW50IGNoYXJDb3VudDsKKyAgICBjb25zdCBVQ2hhciogY2hhcnMgPSB1cmVzX2dldFN0cmluZ0J5S2V5KGJ1bmRsZSwga2V5LCAmY2hhckNvdW50LCAmc3RhdHVzKTsKKyAgICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpIHsKKyAgICAgICAgamZpZWxkSUQgZmlkID0gZW52LT5HZXRGaWVsZElEKEpuaUNvbnN0YW50czo6bG9jYWxlRGF0YUNsYXNzLCBmaWVsZE5hbWUsICJDIik7CisgICAgICAgIGVudi0+U2V0Q2hhckZpZWxkKG9iaiwgZmlkLCBjaGFyc1swXSk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICAgIC8vIE1pc3NpbmcgaXRlbSBpbiBjdXJyZW50IHJlc291cmNlIGJ1bmRsZSBidXQgbm90IGFuIGVycm9yLgorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorfQorCitzdGF0aWMgdm9pZCBzZXRDaGFyRmllbGQoSk5JRW52KiBlbnYsIGpvYmplY3Qgb2JqLCBjb25zdCBjaGFyKiBrZXksIGNvbnN0IGNoYXIqIGZpZWxkTmFtZSwKKyAgICBVUmVzb3VyY2VCdW5kbGUqIGJ1bmRsZSwgVVJlc291cmNlQnVuZGxlKiBmYWxsYmFja0J1bmRsZSkgeworICAgIGlmICghc2V0Q2hhckZpZWxkKGVudiwgb2JqLCBrZXksIGZpZWxkTmFtZSwgYnVuZGxlKSAmJiBmYWxsYmFja0J1bmRsZSAhPSBOVUxMKSB7CisgICAgICAgIHNldENoYXJGaWVsZChlbnYsIG9iaiwga2V5LCBmaWVsZE5hbWUsIGZhbGxiYWNrQnVuZGxlKTsKKyAgICB9Cit9CisKK3N0YXRpYyB2b2lkIHNldE51bWJlclN5bWJvbHMoSk5JRW52KiBlbnYsIGpvYmplY3Qgb2JqLCBVUmVzb3VyY2VCdW5kbGUqIG51bWJlclN5bWJvbHMsIFVSZXNvdXJjZUJ1bmRsZSogZmFsbGJhY2tOdW1iZXJTeW1ib2xzKSB7CisgICAgc2V0Q2hhckZpZWxkKGVudiwgb2JqLCAiZGVjaW1hbCIsICJkZWNpbWFsU2VwYXJhdG9yIiwgbnVtYmVyU3ltYm9scywgZmFsbGJhY2tOdW1iZXJTeW1ib2xzKTsKKyAgICBzZXRDaGFyRmllbGQoZW52LCBvYmosICJncm91cCIsICJncm91cGluZ1NlcGFyYXRvciIsIG51bWJlclN5bWJvbHMsIGZhbGxiYWNrTnVtYmVyU3ltYm9scyk7CisgICAgc2V0Q2hhckZpZWxkKGVudiwgb2JqLCAibGlzdCIsICJwYXR0ZXJuU2VwYXJhdG9yIiwgbnVtYmVyU3ltYm9scywgZmFsbGJhY2tOdW1iZXJTeW1ib2xzKTsKKyAgICBzZXRDaGFyRmllbGQoZW52LCBvYmosICJwZXJjZW50U2lnbiIsICJwZXJjZW50IiwgbnVtYmVyU3ltYm9scywgZmFsbGJhY2tOdW1iZXJTeW1ib2xzKTsKKyAgICBzZXRDaGFyRmllbGQoZW52LCBvYmosICJwZXJNaWxsZSIsICJwZXJNaWxsIiwgbnVtYmVyU3ltYm9scywgZmFsbGJhY2tOdW1iZXJTeW1ib2xzKTsKKyAgICBzZXRDaGFyRmllbGQoZW52LCBvYmosICJkZWNpbWFsIiwgIm1vbmV0YXJ5U2VwYXJhdG9yIiwgbnVtYmVyU3ltYm9scywgZmFsbGJhY2tOdW1iZXJTeW1ib2xzKTsKKyAgICBzZXRDaGFyRmllbGQoZW52LCBvYmosICJtaW51c1NpZ24iLCAibWludXNTaWduIiwgbnVtYmVyU3ltYm9scywgZmFsbGJhY2tOdW1iZXJTeW1ib2xzKTsKKyAgICBzZXRTdHJpbmdGaWVsZChlbnYsIG9iaiwgImV4cG9uZW50aWFsIiwgImV4cG9uZW50U2VwYXJhdG9yIiwgbnVtYmVyU3ltYm9scywgZmFsbGJhY2tOdW1iZXJTeW1ib2xzKTsKKyAgICBzZXRTdHJpbmdGaWVsZChlbnYsIG9iaiwgImluZmluaXR5IiwgImluZmluaXR5IiwgbnVtYmVyU3ltYm9scywgZmFsbGJhY2tOdW1iZXJTeW1ib2xzKTsKKyAgICBzZXRTdHJpbmdGaWVsZChlbnYsIG9iaiwgIm5hbiIsICJOYU4iLCBudW1iZXJTeW1ib2xzLCBmYWxsYmFja051bWJlclN5bWJvbHMpOworfQorCitzdGF0aWMgdm9pZCBzZXRaZXJvRGlnaXRUb0RlZmF1bHQoSk5JRW52KiBlbnYsIGpvYmplY3Qgb2JqKSB7CisgICAgc3RhdGljIGpmaWVsZElEIGZpZCA9IGVudi0+R2V0RmllbGRJRChKbmlDb25zdGFudHM6OmxvY2FsZURhdGFDbGFzcywgInplcm9EaWdpdCIsICJDIik7CisgICAgZW52LT5TZXRDaGFyRmllbGQob2JqLCBmaWQsICcwJyk7Cit9CisKK3N0YXRpYyB2b2lkIHNldFplcm9EaWdpdChKTklFbnYqIGVudiwgam9iamVjdCBvYmosIGJvb2wgaXNMYXRuLCBjaGFyKiBidWZmZXIpIHsKKyAgICBpZiAoaXNMYXRuIHx8IGJ1ZmZlciA9PSBOVUxMIHx8IGJ1ZmZlclswXSA9PSAnXDAnKSB7CisgICAgICAgIHJldHVybiBzZXRaZXJvRGlnaXRUb0RlZmF1bHQoZW52LCBvYmopOworICAgIH0KKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBTY29wZWRSZXNvdXJjZUJ1bmRsZSBudW1TeXN0ZW1Sb290KHVyZXNfb3BlbkRpcmVjdChOVUxMLCAibnVtYmVyaW5nU3lzdGVtcyIsICZzdGF0dXMpKTsKKyAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKKyAgICAgICAgcmV0dXJuIHNldFplcm9EaWdpdFRvRGVmYXVsdChlbnYsIG9iaik7CisgICAgfQorICAgIFNjb3BlZFJlc291cmNlQnVuZGxlIG51bVN5c3RlbSh1cmVzX2dldEJ5S2V5KG51bVN5c3RlbVJvb3QuZ2V0KCksICJudW1iZXJpbmdTeXN0ZW1zIiwgTlVMTCwgJnN0YXR1cykpOworICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgeworICAgICAgICByZXR1cm4gc2V0WmVyb0RpZ2l0VG9EZWZhdWx0KGVudiwgb2JqKTsKKyAgICB9CisgICAgU2NvcGVkUmVzb3VyY2VCdW5kbGUgbm9uTGF0blN5c3RlbSh1cmVzX2dldEJ5S2V5KG51bVN5c3RlbS5nZXQoKSwgYnVmZmVyLCBOVUxMLCAmc3RhdHVzKSk7CisgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CisgICAgICAgIHJldHVybiBzZXRaZXJvRGlnaXRUb0RlZmF1bHQoZW52LCBvYmopOworICAgIH0KKyAgICBpbnQzMl90IGNoYXJDb3VudCA9IDA7CisgICAgY29uc3QgVUNoYXIqIGNoYXJzID0gdXJlc19nZXRTdHJpbmdCeUtleShub25MYXRuU3lzdGVtLmdldCgpLCAiZGVzYyIsICZjaGFyQ291bnQsICZzdGF0dXMpOworICAgIGlmIChjaGFyQ291bnQgPT0gMCkgeworICAgICAgICBzZXRaZXJvRGlnaXRUb0RlZmF1bHQoZW52LCBvYmopOworICAgIH0gZWxzZSB7CisgICAgICAgIHN0YXRpYyBqZmllbGRJRCBmaWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjpsb2NhbGVEYXRhQ2xhc3MsICJ6ZXJvRGlnaXQiLCAiQyIpOworICAgICAgICBlbnYtPlNldENoYXJGaWVsZChvYmosIGZpZCwgY2hhcnNbMF0pOworICAgIH0KK30KKworc3RhdGljIHZvaWQgc2V0TnVtYmVyRWxlbWVudHMoSk5JRW52KiBlbnYsIGpvYmplY3Qgb2JqLCBVUmVzb3VyY2VCdW5kbGUqIG51bWJlckVsZW1lbnRzKSB7CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgU2NvcGVkUmVzb3VyY2VCdW5kbGUgbGF0bk51bWJlclJCKHVyZXNfZ2V0QnlLZXkobnVtYmVyRWxlbWVudHMsICJsYXRuIiwgTlVMTCwgJnN0YXR1cykpOworICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgeworICAgICAgICBMT0dXKCJFcnJvciBnZXR0aW5nIElDVSBsYXRuIG51bWJlciBlbGVtZW50cyBzeXN0ZW0gdmFsdWU6ICVzIiwgdV9lcnJvck5hbWUoc3RhdHVzKSk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgU2NvcGVkUmVzb3VyY2VCdW5kbGUgcGF0dGVybnNSQih1cmVzX2dldEJ5S2V5KGxhdG5OdW1iZXJSQi5nZXQoKSwgInBhdHRlcm5zIiwgTlVMTCwgJnN0YXR1cykpOworICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgeworICAgICAgICBMT0dXKCJFcnJvciBnZXR0aW5nIElDVSBsYXRuIG51bWJlciBwYXR0ZXJucyB2YWx1ZTogJXMiLCB1X2Vycm9yTmFtZShzdGF0dXMpKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICAvLyBHZXQgdGhlIHBhdHRlcm5zIGZyb20gdGhlICdsYXRuJyBudW1iZXJFbGVtZW50cworICAgIC8vIFRoaXMgaXMgYSB0ZW1wb3Jhcnkgd29ya2Fyb3VuZCBmb3IgSUNVIHRpY2tldCM4NjExLgorICAgIFVSZXNvdXJjZUJ1bmRsZSogYnVuZGxlID0gcGF0dGVybnNSQi5nZXQoKTsKKyAgICBzZXRTdHJpbmdGaWVsZChlbnYsIG9iaiwgImN1cnJlbmN5Rm9ybWF0IiwgImN1cnJlbmN5UGF0dGVybiIsIGJ1bmRsZSk7CisgICAgc2V0U3RyaW5nRmllbGQoZW52LCBvYmosICJkZWNpbWFsRm9ybWF0IiwgIm51bWJlclBhdHRlcm4iLCBidW5kbGUpOworICAgIHNldFN0cmluZ0ZpZWxkKGVudiwgb2JqLCAicGVyY2VudEZvcm1hdCIsICJwZXJjZW50UGF0dGVybiIsIGJ1bmRsZSk7CisKKyAgICBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgYm9vbCBpc0xhdG4gPSBmYWxzZTsKKyAgICBjaGFyIGJ1ZmZlclsyNTZdOworICAgIGJ1ZmZlclswXSA9ICdcMCc7CisgICAgU2NvcGVkUmVzb3VyY2VCdW5kbGUgZGVmYXVsdE51bWJlckVsZW0odXJlc19nZXRCeUtleShudW1iZXJFbGVtZW50cywgImRlZmF1bHQiLCBOVUxMLCAmc3RhdHVzKSk7CisgICAgaWYgKFVfU1VDQ0VTUyhzdGF0dXMpKSB7CisgICAgICAgIGludDMyX3QgY2hhckNvdW50ID0gMjU2OworICAgICAgICB1cmVzX2dldFVURjhTdHJpbmcoZGVmYXVsdE51bWJlckVsZW0uZ2V0KCksIGJ1ZmZlciwgJmNoYXJDb3VudCwgdHJ1ZSwgJnN0YXR1cyk7CisgICAgICAgIGJ1ZmZlcltjaGFyQ291bnRdID0gJ1wwJzsKKyAgICAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CisgICAgICAgICAgICBMT0dXKCJFcnJvciBnZXR0aW5nIElDVSBkZWZhdWx0IG51bWJlciBlbGVtZW50IHN5c3RlbSB2YWx1ZTogJXMiLCB1X2Vycm9yTmFtZShzdGF0dXMpKTsKKyAgICAgICAgICAgIC8vIFVzZSBsYXRuIG51bWJlciBzeW1ib2xzIGluc3RlYWQuCisgICAgICAgICAgICBpc0xhdG4gPSB0cnVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaXNMYXRuID0gKHN0cmNtcChidWZmZXIsICJsYXRuIikgPT0gMCk7CisgICAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgICAvLyBOb3QgZGVmYXVsdCBkYXRhLCBmYWxsYmFjayB0byBsYXRuIG51bWJlciBlbGVtZW50cy4KKyAgICAgICAgaXNMYXRuID0gdHJ1ZTsKKyAgICB9CisKKyAgICBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgc2V0WmVyb0RpZ2l0KGVudiwgb2JqLCBpc0xhdG4sIGJ1ZmZlcik7CisgICAgaWYgKGlzTGF0bikgeworICAgICAgICBTY29wZWRSZXNvdXJjZUJ1bmRsZSBzeW1ib2xzUkIodXJlc19nZXRCeUtleShsYXRuTnVtYmVyUkIuZ2V0KCksICJzeW1ib2xzIiwgTlVMTCwgJnN0YXR1cykpOworICAgICAgICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpIHsKKyAgICAgICAgICAgIHNldE51bWJlclN5bWJvbHMoZW52LCBvYmosIHN5bWJvbHNSQi5nZXQoKSwgTlVMTCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBMT0dXKCJNaXNzaW5nIElDVSBsYXRuIHN5bWJvbHMgc3lzdGVtIHZhbHVlOiAlcyIsIHVfZXJyb3JOYW1lKHN0YXR1cykpOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gR2V0IGV2ZXJ5IHN5bWJvbCBpdGVtIGZyb20gZGVmYXVsdCBudW1iZXJpbmcgc3lzdGVtIGZpcnN0LiBJZiBpdCBkb2VzIG5vdAorICAgICAgICAvLyBleGlzdCwgZ2V0IHRoZSBzeW1ib2wgZnJvbSBsYXRuIG51bWJlcmluZyBzeXN0ZW0uCisgICAgICAgIFNjb3BlZFJlc291cmNlQnVuZGxlIGRlZmF1bHROdW1iZXJSQih1cmVzX2dldEJ5S2V5KG51bWJlckVsZW1lbnRzLCAoY29uc3QgY2hhciopYnVmZmVyLCBOVUxMLCAmc3RhdHVzKSk7CisgICAgICAgIFNjb3BlZFJlc291cmNlQnVuZGxlIGRlZmF1bHRTeW1ib2xzUkIodXJlc19nZXRCeUtleShkZWZhdWx0TnVtYmVyUkIuZ2V0KCksICJzeW1ib2xzIiwgTlVMTCwgJnN0YXR1cykpOworICAgICAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKKyAgICAgICAgICAgIExPR1coIk1pc3NpbmcgSUNVICVzIHN5bWJvbHMgc3lzdGVtIHZhbHVlOiAlcyIsIGJ1ZmZlciwgdV9lcnJvck5hbWUoc3RhdHVzKSk7CisgICAgICAgICAgICBpc0xhdG4gPSB0cnVlOyAgLy8gRmFsbGJhY2sgdG8gbGF0biBzeW1ib2xzLgorICAgICAgICAgICAgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworICAgICAgICB9CisgICAgICAgIFNjb3BlZFJlc291cmNlQnVuZGxlIGxhdG5TeW1ib2xzUkIodXJlc19nZXRCeUtleShsYXRuTnVtYmVyUkIuZ2V0KCksICJzeW1ib2xzIiwgTlVMTCwgJnN0YXR1cykpOworICAgICAgICBpZiAoaXNMYXRuICYmIFVfRkFJTFVSRShzdGF0dXMpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgc2V0TnVtYmVyU3ltYm9scyhlbnYsIG9iaiwgZGVmYXVsdFN5bWJvbHNSQi5nZXQoKSwgbGF0blN5bWJvbHNSQi5nZXQoKSk7CisgICAgfQorfQorCitzdGF0aWMgamJvb2xlYW4gSUNVX2luaXRMb2NhbGVEYXRhSW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqc3RyaW5nIGxvY2FsZSwgam9iamVjdCBsb2NhbGVEYXRhKSB7CisgICAgU2NvcGVkVXRmQ2hhcnMgbG9jYWxlTmFtZShlbnYsIGxvY2FsZSk7CisgICAgaWYgKGxvY2FsZU5hbWUuY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBKTklfRkFMU0U7CisgICAgfQorCisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgU2NvcGVkUmVzb3VyY2VCdW5kbGUgcm9vdCh1cmVzX29wZW4oTlVMTCwgbG9jYWxlTmFtZS5jX3N0cigpLCAmc3RhdHVzKSk7CisgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CisgICAgICAgIExPR0UoIkVycm9yIGdldHRpbmcgSUNVIHJlc291cmNlIGJ1bmRsZTogJXMiLCB1X2Vycm9yTmFtZShzdGF0dXMpKTsKKyAgICAgICAgcmV0dXJuIEpOSV9GQUxTRTsKKyAgICB9CisKKyAgICBTY29wZWRSZXNvdXJjZUJ1bmRsZSBjYWxlbmRhcih1cmVzX2dldEJ5S2V5KHJvb3QuZ2V0KCksICJjYWxlbmRhciIsIE5VTEwsICZzdGF0dXMpKTsKKyAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKKyAgICAgICAgTE9HRSgiRXJyb3IgZ2V0dGluZyBJQ1UgY2FsZW5kYXIgcmVzb3VyY2UgYnVuZGxlOiAlcyIsIHVfZXJyb3JOYW1lKHN0YXR1cykpOworICAgICAgICByZXR1cm4gSk5JX0ZBTFNFOworICAgIH0KKworICAgIFNjb3BlZFJlc291cmNlQnVuZGxlIGdyZWdvcmlhbih1cmVzX2dldEJ5S2V5KGNhbGVuZGFyLmdldCgpLCAiZ3JlZ29yaWFuIiwgTlVMTCwgJnN0YXR1cykpOworICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgeworICAgICAgICBMT0dFKCJFcnJvciBnZXR0aW5nIElDVSBncmVnb3JpYW4gcmVzb3VyY2UgYnVuZGxlOiAlcyIsIHVfZXJyb3JOYW1lKHN0YXR1cykpOworICAgICAgICByZXR1cm4gSk5JX0ZBTFNFOworICAgIH0KKworICAgIGludCBmaXJzdERheVZhbHNbXSA9IHsgMCwgMCB9OworICAgIGlmIChnZXREYXlJbnRWZWN0b3IoZW52LCBncmVnb3JpYW4uZ2V0KCksIGZpcnN0RGF5VmFscykpIHsKKyAgICAgICAgc2V0SW50ZWdlckZpZWxkKGVudiwgbG9jYWxlRGF0YSwgImZpcnN0RGF5T2ZXZWVrIiwgZmlyc3REYXlWYWxzWzBdKTsKKyAgICAgICAgc2V0SW50ZWdlckZpZWxkKGVudiwgbG9jYWxlRGF0YSwgIm1pbmltYWxEYXlzSW5GaXJzdFdlZWsiLCBmaXJzdERheVZhbHNbMV0pOworICAgIH0KKworICAgIGpvYmplY3RBcnJheSBhbVBtTWFya2VycyA9IGdldEFtUG1NYXJrZXJzKGVudiwgZ3JlZ29yaWFuLmdldCgpKTsKKyAgICBzZXRTdHJpbmdBcnJheUZpZWxkKGVudiwgbG9jYWxlRGF0YSwgImFtUG0iLCBhbVBtTWFya2Vycyk7CisgICAgZW52LT5EZWxldGVMb2NhbFJlZihhbVBtTWFya2Vycyk7CisKKyAgICBqb2JqZWN0QXJyYXkgZXJhcyA9IGdldEVyYXMoZW52LCBncmVnb3JpYW4uZ2V0KCkpOworICAgIHNldFN0cmluZ0FycmF5RmllbGQoZW52LCBsb2NhbGVEYXRhLCAiZXJhcyIsIGVyYXMpOworICAgIGVudi0+RGVsZXRlTG9jYWxSZWYoZXJhcyk7CisKKyAgICBTY29wZWRSZXNvdXJjZUJ1bmRsZSBkYXlOYW1lcyh1cmVzX2dldEJ5S2V5KGdyZWdvcmlhbi5nZXQoKSwgImRheU5hbWVzIiwgTlVMTCwgJnN0YXR1cykpOworICAgIFNjb3BlZFJlc291cmNlQnVuZGxlIG1vbnRoTmFtZXModXJlc19nZXRCeUtleShncmVnb3JpYW4uZ2V0KCksICJtb250aE5hbWVzIiwgTlVMTCwgJnN0YXR1cykpOworCisgICAgLy8gR2V0IHRoZSByZWd1bGFyIG1vbnRoIGFuZCB3ZWVrZGF5IG5hbWVzLgorICAgIGpvYmplY3RBcnJheSBsb25nTW9udGhOYW1lcyA9IGdldE5hbWVzKGVudiwgbW9udGhOYW1lcy5nZXQoKSwgdHJ1ZSwgUkVHVUxBUiwgTE9ORyk7CisgICAgam9iamVjdEFycmF5IHNob3J0TW9udGhOYW1lcyA9IGdldE5hbWVzKGVudiwgbW9udGhOYW1lcy5nZXQoKSwgdHJ1ZSwgUkVHVUxBUiwgU0hPUlQpOworICAgIGpvYmplY3RBcnJheSBsb25nV2Vla2RheU5hbWVzID0gZ2V0TmFtZXMoZW52LCBkYXlOYW1lcy5nZXQoKSwgZmFsc2UsIFJFR1VMQVIsIExPTkcpOworICAgIGpvYmplY3RBcnJheSBzaG9ydFdlZWtkYXlOYW1lcyA9IGdldE5hbWVzKGVudiwgZGF5TmFtZXMuZ2V0KCksIGZhbHNlLCBSRUdVTEFSLCBTSE9SVCk7CisgICAgc2V0U3RyaW5nQXJyYXlGaWVsZChlbnYsIGxvY2FsZURhdGEsICJsb25nTW9udGhOYW1lcyIsIGxvbmdNb250aE5hbWVzKTsKKyAgICBzZXRTdHJpbmdBcnJheUZpZWxkKGVudiwgbG9jYWxlRGF0YSwgInNob3J0TW9udGhOYW1lcyIsIHNob3J0TW9udGhOYW1lcyk7CisgICAgc2V0U3RyaW5nQXJyYXlGaWVsZChlbnYsIGxvY2FsZURhdGEsICJsb25nV2Vla2RheU5hbWVzIiwgbG9uZ1dlZWtkYXlOYW1lcyk7CisgICAgc2V0U3RyaW5nQXJyYXlGaWVsZChlbnYsIGxvY2FsZURhdGEsICJzaG9ydFdlZWtkYXlOYW1lcyIsIHNob3J0V2Vla2RheU5hbWVzKTsKKworICAgIC8vIEdldCB0aGUgc3RhbmQtYWxvbmUgbW9udGggYW5kIHdlZWtkYXkgbmFtZXMuIElmIHRoZXkncmUgbm90IGF2YWlsYWJsZSAoYXMgdGhleSBhcmVuJ3QgZm9yCisgICAgLy8gRW5nbGlzaCksIHdlIHJldXNlIHRoZSByZWd1bGFyIG5hbWVzLiBJZiB3ZSByZXR1cm5lZCBudWxsIHRvIEphdmEsIHRoZSB1c3VhbCBmYWxsYmFjaworICAgIC8vIG1lY2hhbmlzbXMgd291bGQgY29tZSBpbnRvIHBsYXkgYW5kIHdlJ2QgZW5kIHVwIHdpdGggdGhlIGJvZ3VzIHN0YW5kLWFsb25lIG5hbWVzIGZyb20gdGhlCisgICAgLy8gcm9vdCBsb2NhbGUgKCIxIiBmb3IgSmFudWFyeSwgYW5kIHNvIG9uKS4KKyAgICBqb2JqZWN0QXJyYXkgbG9uZ1N0YW5kQWxvbmVNb250aE5hbWVzID0gZ2V0TmFtZXMoZW52LCBtb250aE5hbWVzLmdldCgpLCB0cnVlLCBTVEFORF9BTE9ORSwgTE9ORyk7CisgICAgaWYgKGxvbmdTdGFuZEFsb25lTW9udGhOYW1lcyA9PSBOVUxMKSB7CisgICAgICAgIGxvbmdTdGFuZEFsb25lTW9udGhOYW1lcyA9IGxvbmdNb250aE5hbWVzOworICAgIH0KKyAgICBqb2JqZWN0QXJyYXkgc2hvcnRTdGFuZEFsb25lTW9udGhOYW1lcyA9IGdldE5hbWVzKGVudiwgbW9udGhOYW1lcy5nZXQoKSwgdHJ1ZSwgU1RBTkRfQUxPTkUsIFNIT1JUKTsKKyAgICBpZiAoc2hvcnRTdGFuZEFsb25lTW9udGhOYW1lcyA9PSBOVUxMKSB7CisgICAgICAgIHNob3J0U3RhbmRBbG9uZU1vbnRoTmFtZXMgPSBzaG9ydE1vbnRoTmFtZXM7CisgICAgfQorICAgIGpvYmplY3RBcnJheSBsb25nU3RhbmRBbG9uZVdlZWtkYXlOYW1lcyA9IGdldE5hbWVzKGVudiwgZGF5TmFtZXMuZ2V0KCksIGZhbHNlLCBTVEFORF9BTE9ORSwgTE9ORyk7CisgICAgaWYgKGxvbmdTdGFuZEFsb25lV2Vla2RheU5hbWVzID09IE5VTEwpIHsKKyAgICAgICAgbG9uZ1N0YW5kQWxvbmVXZWVrZGF5TmFtZXMgPSBsb25nV2Vla2RheU5hbWVzOworICAgIH0KKyAgICBqb2JqZWN0QXJyYXkgc2hvcnRTdGFuZEFsb25lV2Vla2RheU5hbWVzID0gZ2V0TmFtZXMoZW52LCBkYXlOYW1lcy5nZXQoKSwgZmFsc2UsIFNUQU5EX0FMT05FLCBTSE9SVCk7CisgICAgaWYgKHNob3J0U3RhbmRBbG9uZVdlZWtkYXlOYW1lcyA9PSBOVUxMKSB7CisgICAgICAgIHNob3J0U3RhbmRBbG9uZVdlZWtkYXlOYW1lcyA9IHNob3J0V2Vla2RheU5hbWVzOworICAgIH0KKyAgICBzZXRTdHJpbmdBcnJheUZpZWxkKGVudiwgbG9jYWxlRGF0YSwgImxvbmdTdGFuZEFsb25lTW9udGhOYW1lcyIsIGxvbmdTdGFuZEFsb25lTW9udGhOYW1lcyk7CisgICAgc2V0U3RyaW5nQXJyYXlGaWVsZChlbnYsIGxvY2FsZURhdGEsICJzaG9ydFN0YW5kQWxvbmVNb250aE5hbWVzIiwgc2hvcnRTdGFuZEFsb25lTW9udGhOYW1lcyk7CisgICAgc2V0U3RyaW5nQXJyYXlGaWVsZChlbnYsIGxvY2FsZURhdGEsICJsb25nU3RhbmRBbG9uZVdlZWtkYXlOYW1lcyIsIGxvbmdTdGFuZEFsb25lV2Vla2RheU5hbWVzKTsKKyAgICBzZXRTdHJpbmdBcnJheUZpZWxkKGVudiwgbG9jYWxlRGF0YSwgInNob3J0U3RhbmRBbG9uZVdlZWtkYXlOYW1lcyIsIHNob3J0U3RhbmRBbG9uZVdlZWtkYXlOYW1lcyk7CisKKyAgICBTY29wZWRSZXNvdXJjZUJ1bmRsZSBkYXRlVGltZVBhdHRlcm5zKHVyZXNfZ2V0QnlLZXkoZ3JlZ29yaWFuLmdldCgpLCAiRGF0ZVRpbWVQYXR0ZXJucyIsIE5VTEwsICZzdGF0dXMpKTsKKyAgICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpIHsKKyAgICAgICAgc2V0U3RyaW5nRmllbGQoZW52LCBsb2NhbGVEYXRhLCAiZnVsbFRpbWVGb3JtYXQiLCBkYXRlVGltZVBhdHRlcm5zLmdldCgpLCAwKTsKKyAgICAgICAgc2V0U3RyaW5nRmllbGQoZW52LCBsb2NhbGVEYXRhLCAibG9uZ1RpbWVGb3JtYXQiLCBkYXRlVGltZVBhdHRlcm5zLmdldCgpLCAxKTsKKyAgICAgICAgc2V0U3RyaW5nRmllbGQoZW52LCBsb2NhbGVEYXRhLCAibWVkaXVtVGltZUZvcm1hdCIsIGRhdGVUaW1lUGF0dGVybnMuZ2V0KCksIDIpOworICAgICAgICBzZXRTdHJpbmdGaWVsZChlbnYsIGxvY2FsZURhdGEsICJzaG9ydFRpbWVGb3JtYXQiLCBkYXRlVGltZVBhdHRlcm5zLmdldCgpLCAzKTsKKyAgICAgICAgc2V0U3RyaW5nRmllbGQoZW52LCBsb2NhbGVEYXRhLCAiZnVsbERhdGVGb3JtYXQiLCBkYXRlVGltZVBhdHRlcm5zLmdldCgpLCA0KTsKKyAgICAgICAgc2V0U3RyaW5nRmllbGQoZW52LCBsb2NhbGVEYXRhLCAibG9uZ0RhdGVGb3JtYXQiLCBkYXRlVGltZVBhdHRlcm5zLmdldCgpLCA1KTsKKyAgICAgICAgc2V0U3RyaW5nRmllbGQoZW52LCBsb2NhbGVEYXRhLCAibWVkaXVtRGF0ZUZvcm1hdCIsIGRhdGVUaW1lUGF0dGVybnMuZ2V0KCksIDYpOworICAgICAgICBzZXRTdHJpbmdGaWVsZChlbnYsIGxvY2FsZURhdGEsICJzaG9ydERhdGVGb3JtYXQiLCBkYXRlVGltZVBhdHRlcm5zLmdldCgpLCA3KTsKKyAgICB9CisgICAgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworCisgICAgLy8gRm9yIG51bWJlclBhdHRlcm5zIGFuZCBzeW1ib2xzLgorICAgIFNjb3BlZFJlc291cmNlQnVuZGxlIG51bWJlckVsZW1lbnRzKHVyZXNfZ2V0QnlLZXkocm9vdC5nZXQoKSwgIk51bWJlckVsZW1lbnRzIiwgTlVMTCwgJnN0YXR1cykpOworICAgIGlmIChVX1NVQ0NFU1Moc3RhdHVzKSkgeworICAgICAgICBzZXROdW1iZXJFbGVtZW50cyhlbnYsIGxvY2FsZURhdGEsIG51bWJlckVsZW1lbnRzLmdldCgpKTsKKyAgICB9CisgICAgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworCisgICAganN0cmluZyBjb3VudHJ5Q29kZSA9IGVudi0+TmV3U3RyaW5nVVRGKExvY2FsZTo6Y3JlYXRlRnJvbU5hbWUobG9jYWxlTmFtZS5jX3N0cigpKS5nZXRDb3VudHJ5KCkpOworICAgIGpzdHJpbmcgaW50ZXJuYXRpb25hbEN1cnJlbmN5U3ltYm9sID0gSUNVX2dldEN1cnJlbmN5Q29kZShlbnYsIE5VTEwsIGNvdW50cnlDb2RlKTsKKyAgICBlbnYtPkRlbGV0ZUxvY2FsUmVmKGNvdW50cnlDb2RlKTsKKyAgICBjb3VudHJ5Q29kZSA9IE5VTEw7CisKKyAgICBqc3RyaW5nIGN1cnJlbmN5U3ltYm9sID0gTlVMTDsKKyAgICBpZiAoaW50ZXJuYXRpb25hbEN1cnJlbmN5U3ltYm9sICE9IE5VTEwpIHsKKyAgICAgICAgY3VycmVuY3lTeW1ib2wgPSBJQ1VfZ2V0Q3VycmVuY3lTeW1ib2woZW52LCBOVUxMLCBsb2NhbGUsIGludGVybmF0aW9uYWxDdXJyZW5jeVN5bWJvbCk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgaW50ZXJuYXRpb25hbEN1cnJlbmN5U3ltYm9sID0gZW52LT5OZXdTdHJpbmdVVEYoIlhYWCIpOworICAgIH0KKyAgICBpZiAoY3VycmVuY3lTeW1ib2wgPT0gTlVMTCkgeworICAgICAgICAvLyBUaGlzIGlzIHRoZSBVVEYtOCBlbmNvZGluZyBvZiBVKzAwQTQgKENVUlJFTkNZIFNJR04pLgorICAgICAgICBjdXJyZW5jeVN5bWJvbCA9IGVudi0+TmV3U3RyaW5nVVRGKCJceGMyXHhhNCIpOworICAgIH0KKyAgICBzZXRTdHJpbmdGaWVsZChlbnYsIGxvY2FsZURhdGEsICJjdXJyZW5jeVN5bWJvbCIsIGN1cnJlbmN5U3ltYm9sKTsKKyAgICBzZXRTdHJpbmdGaWVsZChlbnYsIGxvY2FsZURhdGEsICJpbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2wiLCBpbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2wpOworCisgICAgcmV0dXJuIEpOSV9UUlVFOworfQorCitzdGF0aWMganN0cmluZyBJQ1VfdG9Mb3dlckNhc2UoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBqYXZhU3RyaW5nLCBqc3RyaW5nIGxvY2FsZU5hbWUpIHsKKyAgICBTY29wZWRKYXZhVW5pY29kZVN0cmluZyBzY29wZWRTdHJpbmcoZW52LCBqYXZhU3RyaW5nKTsKKyAgICBVbmljb2RlU3RyaW5nJiBzKHNjb3BlZFN0cmluZy51bmljb2RlU3RyaW5nKCkpOworICAgIFVuaWNvZGVTdHJpbmcgb3JpZ2luYWwocyk7CisgICAgcy50b0xvd2VyKExvY2FsZTo6Y3JlYXRlRnJvbU5hbWUoU2NvcGVkVXRmQ2hhcnMoZW52LCBsb2NhbGVOYW1lKS5jX3N0cigpKSk7CisgICAgcmV0dXJuIHMgPT0gb3JpZ2luYWwgPyBqYXZhU3RyaW5nIDogZW52LT5OZXdTdHJpbmcocy5nZXRCdWZmZXIoKSwgcy5sZW5ndGgoKSk7Cit9CisKK3N0YXRpYyBqc3RyaW5nIElDVV90b1VwcGVyQ2FzZShKTklFbnYqIGVudiwgamNsYXNzLCBqc3RyaW5nIGphdmFTdHJpbmcsIGpzdHJpbmcgbG9jYWxlTmFtZSkgeworICAgIFNjb3BlZEphdmFVbmljb2RlU3RyaW5nIHNjb3BlZFN0cmluZyhlbnYsIGphdmFTdHJpbmcpOworICAgIFVuaWNvZGVTdHJpbmcmIHMoc2NvcGVkU3RyaW5nLnVuaWNvZGVTdHJpbmcoKSk7CisgICAgVW5pY29kZVN0cmluZyBvcmlnaW5hbChzKTsKKyAgICBzLnRvVXBwZXIoTG9jYWxlOjpjcmVhdGVGcm9tTmFtZShTY29wZWRVdGZDaGFycyhlbnYsIGxvY2FsZU5hbWUpLmNfc3RyKCkpKTsKKyAgICByZXR1cm4gcyA9PSBvcmlnaW5hbCA/IGphdmFTdHJpbmcgOiBlbnYtPk5ld1N0cmluZyhzLmdldEJ1ZmZlcigpLCBzLmxlbmd0aCgpKTsKK30KKworc3RhdGljIGpzdHJpbmcgdmVyc2lvblN0cmluZyhKTklFbnYqIGVudiwgY29uc3QgVVZlcnNpb25JbmZvJiB2ZXJzaW9uKSB7CisgICAgY2hhciB2ZXJzaW9uU3RyaW5nW1VfTUFYX1ZFUlNJT05fU1RSSU5HX0xFTkdUSF07CisgICAgdV92ZXJzaW9uVG9TdHJpbmcoY29uc3RfY2FzdDxVVmVyc2lvbkluZm8mPih2ZXJzaW9uKSwgJnZlcnNpb25TdHJpbmdbMF0pOworICAgIHJldHVybiBlbnYtPk5ld1N0cmluZ1VURih2ZXJzaW9uU3RyaW5nKTsKK30KKworc3RhdGljIGpzdHJpbmcgSUNVX2dldEljdVZlcnNpb24oSk5JRW52KiBlbnYsIGpjbGFzcykgeworICAgIFVWZXJzaW9uSW5mbyBpY3VWZXJzaW9uOworICAgIHVfZ2V0VmVyc2lvbihpY3VWZXJzaW9uKTsKKyAgICByZXR1cm4gdmVyc2lvblN0cmluZyhlbnYsIGljdVZlcnNpb24pOworfQorCitzdGF0aWMganN0cmluZyBJQ1VfZ2V0VW5pY29kZVZlcnNpb24oSk5JRW52KiBlbnYsIGpjbGFzcykgeworICAgIFVWZXJzaW9uSW5mbyB1bmljb2RlVmVyc2lvbjsKKyAgICB1X2dldFVuaWNvZGVWZXJzaW9uKHVuaWNvZGVWZXJzaW9uKTsKKyAgICByZXR1cm4gdmVyc2lvblN0cmluZyhlbnYsIHVuaWNvZGVWZXJzaW9uKTsKK30KKworCitzdHJ1Y3QgRW51bWVyYXRpb25Db3VudGVyIHsKKyAgICBjb25zdCBzaXplX3QgY291bnQ7CisgICAgRW51bWVyYXRpb25Db3VudGVyKHNpemVfdCBjb3VudCkgOiBjb3VudChjb3VudCkge30KKyAgICBzaXplX3Qgb3BlcmF0b3IoKSgpIHsgcmV0dXJuIGNvdW50OyB9Cit9Oworc3RydWN0IEVudW1lcmF0aW9uR2V0dGVyIHsKKyAgICBVRW51bWVyYXRpb24qIGU7CisgICAgVUVycm9yQ29kZSogc3RhdHVzOworICAgIEVudW1lcmF0aW9uR2V0dGVyKFVFbnVtZXJhdGlvbiogZSwgVUVycm9yQ29kZSogc3RhdHVzKSA6IGUoZSksIHN0YXR1cyhzdGF0dXMpIHt9CisgICAgY29uc3QgVUNoYXIqIG9wZXJhdG9yKCkoaW50MzJfdCogY2hhckNvdW50KSB7IHJldHVybiB1ZW51bV91bmV4dChlLCBjaGFyQ291bnQsIHN0YXR1cyk7IH0KK307CitzdGF0aWMgam9iamVjdCBJQ1VfZ2V0QXZhaWxhYmxlQ3VycmVuY3lDb2RlcyhKTklFbnYqIGVudiwgamNsYXNzKSB7CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgVUVudW1lcmF0aW9uKiBlKHVjdXJyX29wZW5JU09DdXJyZW5jaWVzKFVDVVJSX0NPTU1PTnxVQ1VSUl9OT05fREVQUkVDQVRFRCwgJnN0YXR1cykpOworICAgIEVudW1lcmF0aW9uQ291bnRlciBjb3VudGVyKHVlbnVtX2NvdW50KGUsICZzdGF0dXMpKTsKKyAgICBFbnVtZXJhdGlvbkdldHRlciBnZXR0ZXIoZSwgJnN0YXR1cyk7CisgICAgam9iamVjdCByZXN1bHQgPSB0b1N0cmluZ0FycmF5MTYoZW52LCAmY291bnRlciwgJmdldHRlcik7CisgICAgbWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihlbnYsIHN0YXR1cyk7CisgICAgdWVudW1fY2xvc2UoZSk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBnTWV0aG9kc1tdID0geworICAgIE5BVElWRV9NRVRIT0QoSUNVLCBhZGRMaWtlbHlTdWJ0YWdzLCAiKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKElDVSwgZ2V0QXZhaWxhYmxlQnJlYWtJdGVyYXRvckxvY2FsZXNOYXRpdmUsICIoKVtMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKElDVSwgZ2V0QXZhaWxhYmxlQ2FsZW5kYXJMb2NhbGVzTmF0aXZlLCAiKClbTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChJQ1UsIGdldEF2YWlsYWJsZUNvbGxhdG9yTG9jYWxlc05hdGl2ZSwgIigpW0xqYXZhL2xhbmcvU3RyaW5nOyIpLAorICAgIE5BVElWRV9NRVRIT0QoSUNVLCBnZXRBdmFpbGFibGVDdXJyZW5jeUNvZGVzLCAiKClbTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChJQ1UsIGdldEF2YWlsYWJsZURhdGVGb3JtYXRMb2NhbGVzTmF0aXZlLCAiKClbTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChJQ1UsIGdldEF2YWlsYWJsZUxvY2FsZXNOYXRpdmUsICIoKVtMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKElDVSwgZ2V0QXZhaWxhYmxlTnVtYmVyRm9ybWF0TG9jYWxlc05hdGl2ZSwgIigpW0xqYXZhL2xhbmcvU3RyaW5nOyIpLAorICAgIE5BVElWRV9NRVRIT0QoSUNVLCBnZXRDdXJyZW5jeUNvZGUsICIoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOyIpLAorICAgIE5BVElWRV9NRVRIT0QoSUNVLCBnZXRDdXJyZW5jeURpc3BsYXlOYW1lLCAiKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKElDVSwgZ2V0Q3VycmVuY3lGcmFjdGlvbkRpZ2l0cywgIihMamF2YS9sYW5nL1N0cmluZzspSSIpLAorICAgIE5BVElWRV9NRVRIT0QoSUNVLCBnZXRDdXJyZW5jeVN5bWJvbCwgIihMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChJQ1UsIGdldERpc3BsYXlDb3VudHJ5TmF0aXZlLCAiKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKElDVSwgZ2V0RGlzcGxheUxhbmd1YWdlTmF0aXZlLCAiKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKElDVSwgZ2V0RGlzcGxheVZhcmlhbnROYXRpdmUsICIoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOyIpLAorICAgIE5BVElWRV9NRVRIT0QoSUNVLCBnZXRJU08zQ291bnRyeU5hdGl2ZSwgIihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChJQ1UsIGdldElTTzNMYW5ndWFnZU5hdGl2ZSwgIihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChJQ1UsIGdldElTT0NvdW50cmllc05hdGl2ZSwgIigpW0xqYXZhL2xhbmcvU3RyaW5nOyIpLAorICAgIE5BVElWRV9NRVRIT0QoSUNVLCBnZXRJU09MYW5ndWFnZXNOYXRpdmUsICIoKVtMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKElDVSwgZ2V0SWN1VmVyc2lvbiwgIigpTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChJQ1UsIGdldFNjcmlwdCwgIihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChJQ1UsIGdldFVuaWNvZGVWZXJzaW9uLCAiKClMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKElDVSwgaW5pdExvY2FsZURhdGFJbXBsLCAiKExqYXZhL2xhbmcvU3RyaW5nO0xsaWJjb3JlL2ljdS9Mb2NhbGVEYXRhOylaIiksCisgICAgTkFUSVZFX01FVEhPRChJQ1UsIHRvTG93ZXJDYXNlLCAiKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKElDVSwgdG9VcHBlckNhc2UsICIoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOyIpLAorfTsKK2ludCByZWdpc3Rlcl9saWJjb3JlX2ljdV9JQ1UoSk5JRW52KiBlbnYpIHsKKyAgICBzdGQ6OnN0cmluZyBwYXRoOworICAgIHBhdGggPSB1X2dldERhdGFEaXJlY3RvcnkoKTsKKyAgICBwYXRoICs9ICIvIjsKKyAgICBwYXRoICs9IFVfSUNVREFUQV9OQU1FOworICAgIHBhdGggKz0gIi5kYXQiOworCisgICAgI2RlZmluZSBGQUlMX1dJVEhfU1RSRVJST1IocykgXAorICAgICAgICBMT0dFKCJDb3VsZG4ndCAiIHMgIiAnJXMnOiAlcyIsIHBhdGguY19zdHIoKSwgc3RyZXJyb3IoZXJybm8pKTsgXAorICAgICAgICByZXR1cm4gLTE7CisgICAgI2RlZmluZSBNQVlCRV9GQUlMX1dJVEhfSUNVX0VSUk9SKHMpIFwKKyAgICAgICAgaWYgKHN0YXR1cyAhPSBVX1pFUk9fRVJST1IpIHtcCisgICAgICAgICAgICBMT0dFKCJDb3VsZG4ndCBpbml0aWFsaXplIElDVSAoIiBzICIpOiAlcyAoJXMpIiwgdV9lcnJvck5hbWUoc3RhdHVzKSwgcGF0aC5jX3N0cigpKTsgXAorICAgICAgICAgICAgcmV0dXJuIC0xOyBcCisgICAgICAgIH0KKworICAgIC8vIE9wZW4gdGhlIGZpbGUgYW5kIGdldCBpdHMgbGVuZ3RoLgorICAgIFNjb3BlZEZkIGZkKG9wZW4ocGF0aC5jX3N0cigpLCBPX1JET05MWSkpOworICAgIGlmIChmZC5nZXQoKSA9PSAtMSkgeworICAgICAgICBGQUlMX1dJVEhfU1RSRVJST1IoIm9wZW4iKTsKKyAgICB9CisgICAgc3RydWN0IHN0YXQgc2I7CisgICAgaWYgKGZzdGF0KGZkLmdldCgpLCAmc2IpID09IC0xKSB7CisgICAgICAgIEZBSUxfV0lUSF9TVFJFUlJPUigic3RhdCIpOworICAgIH0KKworICAgIC8vIE1hcCBpdC4KKyAgICB2b2lkKiBkYXRhID0gbW1hcChOVUxMLCBzYi5zdF9zaXplLCBQUk9UX1JFQUQsIE1BUF9TSEFSRUQsIGZkLmdldCgpLCAwKTsKKyAgICBpZiAoZGF0YSA9PSBNQVBfRkFJTEVEKSB7CisgICAgICAgIEZBSUxfV0lUSF9TVFJFUlJPUigibW1hcCIpOworICAgIH0KKworICAgIC8vIFRlbGwgdGhlIGtlcm5lbCB0aGF0IGFjY2Vzc2VzIGFyZSBsaWtlbHkgdG8gYmUgcmFuZG9tIHJhdGhlciB0aGFuIHNlcXVlbnRpYWwuCisgICAgaWYgKG1hZHZpc2UoZGF0YSwgc2Iuc3Rfc2l6ZSwgTUFEVl9SQU5ET00pID09IC0xKSB7CisgICAgICAgIEZBSUxfV0lUSF9TVFJFUlJPUigibWFkdmlzZShNQURWX1JBTkRPTSkiKTsKKyAgICB9CisKKyAgICAvLyBUZWxsIElDVSB0byB1c2Ugb3VyIG1lbW9yeS1tYXBwZWQgZGF0YS4KKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICB1ZGF0YV9zZXRDb21tb25EYXRhKGRhdGEsICZzdGF0dXMpOworICAgIE1BWUJFX0ZBSUxfV0lUSF9JQ1VfRVJST1IoInVkYXRhX3NldENvbW1vbkRhdGEiKTsKKyAgICAvLyBUZWxsIElDVSBpdCBjYW4gKm9ubHkqIHVzZSBvdXIgbWVtb3J5LW1hcHBlZCBkYXRhLgorICAgIHVkYXRhX3NldEZpbGVBY2Nlc3MoVURBVEFfTk9fRklMRVMsICZzdGF0dXMpOworICAgIE1BWUJFX0ZBSUxfV0lUSF9JQ1VfRVJST1IoInVkYXRhX3NldEZpbGVBY2Nlc3MiKTsKKworICAgIC8vIEZhaWx1cmVzIHRvIGZpbmQgdGhlIElDVSBkYXRhIHRlbmQgdG8gYmUgc29tZXdoYXQgb2JzY3VyZSBiZWNhdXNlIElDVSBsb2FkcyBpdHMgZGF0YSBvbiBmaXJzdAorICAgIC8vIHVzZSwgd2hpY2ggY2FuIGJlIGFueXdoZXJlLiBGb3JjZSBpbml0aWFsaXphdGlvbiB1cCBmcm9udCBzbyB3ZSBjYW4gcmVwb3J0IGEgbmljZSBjbGVhciBlcnJvcgorICAgIC8vIGFuZCBiYWlsLgorICAgIHVfaW5pdCgmc3RhdHVzKTsKKyAgICBNQVlCRV9GQUlMX1dJVEhfSUNVX0VSUk9SKCJ1X2luaXQiKTsKKyAgICByZXR1cm4gam5pUmVnaXN0ZXJOYXRpdmVNZXRob2RzKGVudiwgImxpYmNvcmUvaWN1L0lDVSIsIGdNZXRob2RzLCBORUxFTShnTWV0aG9kcykpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pY3VfTmF0aXZlQnJlYWtJdGVyYXRvci5jcHAgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9saWJjb3JlX2ljdV9OYXRpdmVCcmVha0l0ZXJhdG9yLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNzQ4MjJkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pY3VfTmF0aXZlQnJlYWtJdGVyYXRvci5jcHAKQEAgLTAsMCArMSwyMjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDYgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIk5hdGl2ZUJyZWFrSXRlcmF0b3IiCisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisjaW5jbHVkZSAiSm5pRXhjZXB0aW9uLmgiCisjaW5jbHVkZSAiU2NvcGVkVXRmQ2hhcnMuaCIKKyNpbmNsdWRlICJ1bmljb2RlL3VicmsuaCIKKyNpbmNsdWRlICJ1bmljb2RlL3B1dGlsLmgiCisjaW5jbHVkZSA8c3RkbGliLmg+CisKKy8qKgorICogSUNVNEMgNC42IGRvZXNuJ3QgbGV0IHVzIHVwZGF0ZSB0aGUgcG9pbnRlcnMgaW5zaWRlIGEgVUJyZWFrSXRlcmF0b3IgdG8gdHJhY2sgb3VyIGNoYXJbXSBhcyBpdAorICogbW92ZXMgYXJvdW5kIHRoZSBoZWFwLiBUaGlzIGNsYXNzIHBpbnMgdGhlIGNoYXJbXSBmb3IgdGhlIGxpZmV0aW1lIG9mIHRoZQorICogamF2YS50ZXh0LkJyZWFrSXRlcmF0b3IuIEl0IGFsc28gaG9sZHMgYSBnbG9iYWwgcmVmZXJlbmNlIHRvIHRoZSBqYXZhLmxhbmcuU3RyaW5nIHRoYXQgb3ducyB0aGUKKyAqIGNoYXJbXSBzbyB0aGF0IHRoZSBjaGFyW10gY2FuJ3QgYmUgR0NlZC4KKyAqLworY2xhc3MgQnJlYWtJdGVyYXRvclBlZXIgeworcHVibGljOgorICAgIHN0YXRpYyBCcmVha0l0ZXJhdG9yUGVlciogZnJvbUFkZHJlc3MoamludCBhZGRyZXNzKSB7CisgICAgICAgIHJldHVybiByZWludGVycHJldF9jYXN0PEJyZWFrSXRlcmF0b3JQZWVyKj4oc3RhdGljX2Nhc3Q8dWludHB0cl90PihhZGRyZXNzKSk7CisgICAgfQorCisgICAgdWludHB0cl90IHRvQWRkcmVzcygpIHsKKyAgICAgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8dWludHB0cl90Pih0aGlzKTsKKyAgICB9CisKKyAgICBCcmVha0l0ZXJhdG9yUGVlcihVQnJlYWtJdGVyYXRvciogaXQpIDogbUl0KGl0KSwgbVN0cmluZyhOVUxMKSwgbUNoYXJzKE5VTEwpIHsKKyAgICB9CisKKyAgICB2b2lkIHNldFRleHQoSk5JRW52KiBlbnYsIGpzdHJpbmcgcykgeworICAgICAgICByZWxlYXNlU3RyaW5nKGVudik7CisKKyAgICAgICAgbVN0cmluZyA9IHJlaW50ZXJwcmV0X2Nhc3Q8anN0cmluZz4oZW52LT5OZXdHbG9iYWxSZWYocykpOworICAgICAgICBtQ2hhcnMgPSBlbnYtPkdldFN0cmluZ0NoYXJzKG1TdHJpbmcsIE5VTEwpOworICAgICAgICBpZiAobUNoYXJzID09IE5VTEwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHNpemVfdCBjaGFyQ291bnQgPSBlbnYtPkdldFN0cmluZ0xlbmd0aChtU3RyaW5nKTsKKyAgICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgICAgIHVicmtfc2V0VGV4dChtSXQsIG1DaGFycywgY2hhckNvdW50LCAmc3RhdHVzKTsKKyAgICAgICAgbWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihlbnYsIHN0YXR1cyk7CisgICAgfQorCisgICAgQnJlYWtJdGVyYXRvclBlZXIqIGNsb25lKEpOSUVudiogZW52KSB7CisgICAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworICAgICAgICBqaW50IGJ1ZmZlclNpemUgPSBVX0JSS19TQUZFQ0xPTkVfQlVGRkVSU0laRTsKKyAgICAgICAgVUJyZWFrSXRlcmF0b3IqIGl0ID0gdWJya19zYWZlQ2xvbmUobUl0LCBOVUxMLCAmYnVmZmVyU2l6ZSwgJnN0YXR1cyk7CisgICAgICAgIGlmIChtYXliZVRocm93SWN1RXhjZXB0aW9uKGVudiwgc3RhdHVzKSkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgQnJlYWtJdGVyYXRvclBlZXIqIHJlc3VsdCA9IG5ldyBCcmVha0l0ZXJhdG9yUGVlcihpdCk7CisgICAgICAgIGlmIChtU3RyaW5nICE9IE5VTEwpIHsKKyAgICAgICAgICAgIHJlc3VsdC0+c2V0VGV4dChlbnYsIG1TdHJpbmcpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgdm9pZCBjbG9zZShKTklFbnYqIGVudikgeworICAgICAgICBpZiAobUl0ICE9IE5VTEwpIHsKKyAgICAgICAgICAgIHVicmtfY2xvc2UobUl0KTsKKyAgICAgICAgICAgIG1JdCA9IE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgcmVsZWFzZVN0cmluZyhlbnYpOworICAgIH0KKworICAgIH5CcmVha0l0ZXJhdG9yUGVlcigpIHsKKyAgICAgICAgaWYgKG1JdCAhPSBOVUxMIHx8IG1TdHJpbmcgIT0gTlVMTCkgeworICAgICAgICAgICAgTE9HX0FMV0FZU19GQVRBTCgiQnJlYWtJdGVyYXRvclBlZXIgZGVsZXRlZCBidXQgbm90IGNsb3NlZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgVUJyZWFrSXRlcmF0b3IqIGJyZWFrSXRlcmF0b3IoKSB7CisgICAgICAgIHJldHVybiBtSXQ7CisgICAgfQorCitwcml2YXRlOgorICAgIFVCcmVha0l0ZXJhdG9yKiBtSXQ7CisKKyAgICBqc3RyaW5nIG1TdHJpbmc7CisgICAgY29uc3QgamNoYXIqIG1DaGFyczsKKworICAgIHZvaWQgcmVsZWFzZVN0cmluZyhKTklFbnYqIGVudikgeworICAgICAgICBpZiAobVN0cmluZyAhPSBOVUxMKSB7CisgICAgICAgICAgICBlbnYtPlJlbGVhc2VTdHJpbmdDaGFycyhtU3RyaW5nLCBtQ2hhcnMpOworICAgICAgICAgICAgZW52LT5EZWxldGVHbG9iYWxSZWYobVN0cmluZyk7CisgICAgICAgICAgICBtU3RyaW5nID0gTlVMTDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIERpc2FsbG93IGNvcHkgYW5kIGFzc2lnbm1lbnQuCisgICAgQnJlYWtJdGVyYXRvclBlZXIoY29uc3QgQnJlYWtJdGVyYXRvclBlZXImKTsKKyAgICB2b2lkIG9wZXJhdG9yPShjb25zdCBCcmVha0l0ZXJhdG9yUGVlciYpOworfTsKKworc3RhdGljIFVCcmVha0l0ZXJhdG9yKiBicmVha0l0ZXJhdG9yKGppbnQgYWRkcmVzcykgeworICAgIHJldHVybiBCcmVha0l0ZXJhdG9yUGVlcjo6ZnJvbUFkZHJlc3MoYWRkcmVzcyktPmJyZWFrSXRlcmF0b3IoKTsKK30KKworc3RhdGljIGppbnQgbWFrZUl0ZXJhdG9yKEpOSUVudiogZW52LCBqc3RyaW5nIGxvY2FsZSwgVUJyZWFrSXRlcmF0b3JUeXBlIHR5cGUpIHsKKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBjb25zdCBTY29wZWRVdGZDaGFycyBsb2NhbGVDaGFycyhlbnYsIGxvY2FsZSk7CisgICAgaWYgKGxvY2FsZUNoYXJzLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgVUJyZWFrSXRlcmF0b3IqIGl0ID0gdWJya19vcGVuKHR5cGUsIGxvY2FsZUNoYXJzLmNfc3RyKCksIE5VTEwsIDAsICZzdGF0dXMpOworICAgIGlmIChtYXliZVRocm93SWN1RXhjZXB0aW9uKGVudiwgc3RhdHVzKSkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgcmV0dXJuIChuZXcgQnJlYWtJdGVyYXRvclBlZXIoaXQpKS0+dG9BZGRyZXNzKCk7Cit9CisKK3N0YXRpYyBqaW50IE5hdGl2ZUJyZWFrSXRlcmF0b3JfZ2V0Q2hhcmFjdGVySW5zdGFuY2VJbXBsKEpOSUVudiogZW52LCBqY2xhc3MsIGpzdHJpbmcgbG9jYWxlKSB7CisgICAgcmV0dXJuIG1ha2VJdGVyYXRvcihlbnYsIGxvY2FsZSwgVUJSS19DSEFSQUNURVIpOworfQorCitzdGF0aWMgamludCBOYXRpdmVCcmVha0l0ZXJhdG9yX2dldExpbmVJbnN0YW5jZUltcGwoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBsb2NhbGUpIHsKKyAgICByZXR1cm4gbWFrZUl0ZXJhdG9yKGVudiwgbG9jYWxlLCBVQlJLX0xJTkUpOworfQorCitzdGF0aWMgamludCBOYXRpdmVCcmVha0l0ZXJhdG9yX2dldFNlbnRlbmNlSW5zdGFuY2VJbXBsKEpOSUVudiogZW52LCBqY2xhc3MsIGpzdHJpbmcgbG9jYWxlKSB7CisgICAgcmV0dXJuIG1ha2VJdGVyYXRvcihlbnYsIGxvY2FsZSwgVUJSS19TRU5URU5DRSk7Cit9CisKK3N0YXRpYyBqaW50IE5hdGl2ZUJyZWFrSXRlcmF0b3JfZ2V0V29yZEluc3RhbmNlSW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqc3RyaW5nIGxvY2FsZSkgeworICAgIHJldHVybiBtYWtlSXRlcmF0b3IoZW52LCBsb2NhbGUsIFVCUktfV09SRCk7Cit9CisKK3N0YXRpYyB2b2lkIE5hdGl2ZUJyZWFrSXRlcmF0b3JfY2xvc2VCcmVha0l0ZXJhdG9ySW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHJlc3MpIHsKKyAgICBCcmVha0l0ZXJhdG9yUGVlciogcGVlciA9IEJyZWFrSXRlcmF0b3JQZWVyOjpmcm9tQWRkcmVzcyhhZGRyZXNzKTsKKyAgICBwZWVyLT5jbG9zZShlbnYpOworICAgIGRlbGV0ZSBwZWVyOworfQorCitzdGF0aWMgamludCBOYXRpdmVCcmVha0l0ZXJhdG9yX2Nsb25lSW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHJlc3MpIHsKKyAgICByZXR1cm4gQnJlYWtJdGVyYXRvclBlZXI6OmZyb21BZGRyZXNzKGFkZHJlc3MpLT5jbG9uZShlbnYpLT50b0FkZHJlc3MoKTsKK30KKworc3RhdGljIHZvaWQgTmF0aXZlQnJlYWtJdGVyYXRvcl9zZXRUZXh0SW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHJlc3MsIGpzdHJpbmcgamF2YVRleHQpIHsKKyAgICBCcmVha0l0ZXJhdG9yUGVlciogcGVlciA9IEJyZWFrSXRlcmF0b3JQZWVyOjpmcm9tQWRkcmVzcyhhZGRyZXNzKTsKKyAgICBwZWVyLT5zZXRUZXh0KGVudiwgamF2YVRleHQpOworfQorCitzdGF0aWMgamJvb2xlYW4gTmF0aXZlQnJlYWtJdGVyYXRvcl9pc0JvdW5kYXJ5SW1wbChKTklFbnYqLCBqY2xhc3MsIGppbnQgYWRkcmVzcywgamludCBvZmZzZXQpIHsKKyAgICByZXR1cm4gdWJya19pc0JvdW5kYXJ5KGJyZWFrSXRlcmF0b3IoYWRkcmVzcyksIG9mZnNldCk7Cit9CisKK3N0YXRpYyBqaW50IE5hdGl2ZUJyZWFrSXRlcmF0b3JfbmV4dEltcGwoSk5JRW52KiwgamNsYXNzLCBqaW50IGFkZHJlc3MsIGppbnQgbikgeworICAgIFVCcmVha0l0ZXJhdG9yKiBiaSA9IGJyZWFrSXRlcmF0b3IoYWRkcmVzcyk7CisgICAgaWYgKG4gPCAwKSB7CisgICAgICAgIHdoaWxlIChuKysgPCAtMSkgeworICAgICAgICAgICAgdWJya19wcmV2aW91cyhiaSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHVicmtfcHJldmlvdXMoYmkpOworICAgIH0gZWxzZSBpZiAobiA9PSAwKSB7CisgICAgICAgIHJldHVybiB1YnJrX2N1cnJlbnQoYmkpOworICAgIH0gZWxzZSB7CisgICAgICAgIHdoaWxlIChuLS0gPiAxKSB7CisgICAgICAgICAgICB1YnJrX25leHQoYmkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB1YnJrX25leHQoYmkpOworICAgIH0KKyAgICByZXR1cm4gLTE7Cit9CisKK3N0YXRpYyBqaW50IE5hdGl2ZUJyZWFrSXRlcmF0b3JfcHJlY2VkaW5nSW1wbChKTklFbnYqLCBqY2xhc3MsIGppbnQgYWRkcmVzcywgamludCBvZmZzZXQpIHsKKyAgICByZXR1cm4gdWJya19wcmVjZWRpbmcoYnJlYWtJdGVyYXRvcihhZGRyZXNzKSwgb2Zmc2V0KTsKK30KKworc3RhdGljIGppbnQgTmF0aXZlQnJlYWtJdGVyYXRvcl9maXJzdEltcGwoSk5JRW52KiwgamNsYXNzLCBqaW50IGFkZHJlc3MpIHsKKyAgICByZXR1cm4gdWJya19maXJzdChicmVha0l0ZXJhdG9yKGFkZHJlc3MpKTsKK30KKworc3RhdGljIGppbnQgTmF0aXZlQnJlYWtJdGVyYXRvcl9mb2xsb3dpbmdJbXBsKEpOSUVudiosIGpjbGFzcywgamludCBhZGRyZXNzLCBqaW50IG9mZnNldCkgeworICAgIHJldHVybiB1YnJrX2ZvbGxvd2luZyhicmVha0l0ZXJhdG9yKGFkZHJlc3MpLCBvZmZzZXQpOworfQorCitzdGF0aWMgamludCBOYXRpdmVCcmVha0l0ZXJhdG9yX2N1cnJlbnRJbXBsKEpOSUVudiosIGpjbGFzcywgamludCBhZGRyZXNzKSB7CisgICAgcmV0dXJuIHVicmtfY3VycmVudChicmVha0l0ZXJhdG9yKGFkZHJlc3MpKTsKK30KKworc3RhdGljIGppbnQgTmF0aXZlQnJlYWtJdGVyYXRvcl9wcmV2aW91c0ltcGwoSk5JRW52KiwgamNsYXNzLCBqaW50IGFkZHJlc3MpIHsKKyAgICByZXR1cm4gdWJya19wcmV2aW91cyhicmVha0l0ZXJhdG9yKGFkZHJlc3MpKTsKK30KKworc3RhdGljIGppbnQgTmF0aXZlQnJlYWtJdGVyYXRvcl9sYXN0SW1wbChKTklFbnYqLCBqY2xhc3MsIGppbnQgYWRkcmVzcykgeworICAgIHJldHVybiB1YnJrX2xhc3QoYnJlYWtJdGVyYXRvcihhZGRyZXNzKSk7Cit9CisKK3N0YXRpYyBKTklOYXRpdmVNZXRob2QgZ01ldGhvZHNbXSA9IHsKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJyZWFrSXRlcmF0b3IsIGNsb25lSW1wbCwgIihJKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJyZWFrSXRlcmF0b3IsIGNsb3NlQnJlYWtJdGVyYXRvckltcGwsICIoSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVCcmVha0l0ZXJhdG9yLCBjdXJyZW50SW1wbCwgIihJKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJyZWFrSXRlcmF0b3IsIGZpcnN0SW1wbCwgIihJKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJyZWFrSXRlcmF0b3IsIGZvbGxvd2luZ0ltcGwsICIoSUkpSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQnJlYWtJdGVyYXRvciwgZ2V0Q2hhcmFjdGVySW5zdGFuY2VJbXBsLCAiKExqYXZhL2xhbmcvU3RyaW5nOylJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVCcmVha0l0ZXJhdG9yLCBnZXRMaW5lSW5zdGFuY2VJbXBsLCAiKExqYXZhL2xhbmcvU3RyaW5nOylJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVCcmVha0l0ZXJhdG9yLCBnZXRTZW50ZW5jZUluc3RhbmNlSW1wbCwgIihMamF2YS9sYW5nL1N0cmluZzspSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQnJlYWtJdGVyYXRvciwgZ2V0V29yZEluc3RhbmNlSW1wbCwgIihMamF2YS9sYW5nL1N0cmluZzspSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQnJlYWtJdGVyYXRvciwgaXNCb3VuZGFyeUltcGwsICIoSUkpWiIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQnJlYWtJdGVyYXRvciwgbGFzdEltcGwsICIoSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVCcmVha0l0ZXJhdG9yLCBuZXh0SW1wbCwgIihJSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVCcmVha0l0ZXJhdG9yLCBwcmVjZWRpbmdJbXBsLCAiKElJKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJyZWFrSXRlcmF0b3IsIHByZXZpb3VzSW1wbCwgIihJKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUJyZWFrSXRlcmF0b3IsIHNldFRleHRJbXBsLCAiKElMamF2YS9sYW5nL1N0cmluZzspViIpLAorfTsKK2ludCByZWdpc3Rlcl9saWJjb3JlX2ljdV9OYXRpdmVCcmVha0l0ZXJhdG9yKEpOSUVudiogZW52KSB7CisgICAgcmV0dXJuIGpuaVJlZ2lzdGVyTmF0aXZlTWV0aG9kcyhlbnYsICJsaWJjb3JlL2ljdS9OYXRpdmVCcmVha0l0ZXJhdG9yIiwgZ01ldGhvZHMsIE5FTEVNKGdNZXRob2RzKSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS9saWJjb3JlX2ljdV9OYXRpdmVDb2xsYXRpb24uY3BwIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pY3VfTmF0aXZlQ29sbGF0aW9uLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNmUyNzZlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pY3VfTmF0aXZlQ29sbGF0aW9uLmNwcApAQCAtMCwwICsxLDE5OSBAQAorLyoqCisqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisqIENvcHlyaWdodCAoQykgMTk5Ni0yMDA1LCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZCAgICAqCisqIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCisqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisqCisqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisqLworCisjZGVmaW5lIExPR19UQUcgIk5hdGl2ZUNvbGxhdGlvbiIKKworI2luY2x1ZGUgIkpOSUhlbHAuaCIKKyNpbmNsdWRlICJKbmlDb25zdGFudHMuaCIKKyNpbmNsdWRlICJKbmlFeGNlcHRpb24uaCIKKyNpbmNsdWRlICJTY29wZWRTdHJpbmdDaGFycy5oIgorI2luY2x1ZGUgIlNjb3BlZFV0ZkNoYXJzLmgiCisjaW5jbHVkZSAiVW5pcXVlUHRyLmgiCisjaW5jbHVkZSAidWNvbF9pbXAuaCIKKyNpbmNsdWRlICJ1bmljb2RlL3Vjb2wuaCIKKyNpbmNsdWRlICJ1bmljb2RlL3Vjb2xlaXRyLmgiCisKK3N0YXRpYyBVQ29sbGF0b3IqIHRvQ29sbGF0b3IoamludCBhZGRyZXNzKSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8VUNvbGxhdG9yKj4oc3RhdGljX2Nhc3Q8dWludHB0cl90PihhZGRyZXNzKSk7Cit9CisKK3N0YXRpYyBVQ29sbGF0aW9uRWxlbWVudHMqIHRvQ29sbGF0aW9uRWxlbWVudHMoamludCBhZGRyZXNzKSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8VUNvbGxhdGlvbkVsZW1lbnRzKj4oc3RhdGljX2Nhc3Q8dWludHB0cl90PihhZGRyZXNzKSk7Cit9CisKK3N0YXRpYyB2b2lkIE5hdGl2ZUNvbGxhdGlvbl9jbG9zZUNvbGxhdG9yKEpOSUVudiosIGpjbGFzcywgamludCBhZGRyZXNzKSB7CisgICAgdWNvbF9jbG9zZSh0b0NvbGxhdG9yKGFkZHJlc3MpKTsKK30KKworc3RhdGljIHZvaWQgTmF0aXZlQ29sbGF0aW9uX2Nsb3NlRWxlbWVudHMoSk5JRW52KiwgamNsYXNzLCBqaW50IGFkZHJlc3MpIHsKKyAgICB1Y29sX2Nsb3NlRWxlbWVudHModG9Db2xsYXRpb25FbGVtZW50cyhhZGRyZXNzKSk7Cit9CisKK3N0YXRpYyBqaW50IE5hdGl2ZUNvbGxhdGlvbl9jb21wYXJlKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgYWRkcmVzcywganN0cmluZyBqYXZhTGhzLCBqc3RyaW5nIGphdmFSaHMpIHsKKyAgICBTY29wZWRTdHJpbmdDaGFycyBsaHMoZW52LCBqYXZhTGhzKTsKKyAgICBpZiAobGhzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIFNjb3BlZFN0cmluZ0NoYXJzIHJocyhlbnYsIGphdmFSaHMpOworICAgIGlmIChyaHMuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgcmV0dXJuIHVjb2xfc3RyY29sbCh0b0NvbGxhdG9yKGFkZHJlc3MpLCBsaHMuZ2V0KCksIGxocy5zaXplKCksIHJocy5nZXQoKSwgcmhzLnNpemUoKSk7Cit9CisKK3N0YXRpYyBqaW50IE5hdGl2ZUNvbGxhdGlvbl9nZXRBdHRyaWJ1dGUoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBhZGRyZXNzLCBqaW50IHR5cGUpIHsKKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBqaW50IHJlc3VsdCA9IHVjb2xfZ2V0QXR0cmlidXRlKHRvQ29sbGF0b3IoYWRkcmVzcyksIChVQ29sQXR0cmlidXRlKSB0eXBlLCAmc3RhdHVzKTsKKyAgICBtYXliZVRocm93SWN1RXhjZXB0aW9uKGVudiwgc3RhdHVzKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgamludCBOYXRpdmVDb2xsYXRpb25fZ2V0Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgYWRkcmVzcywganN0cmluZyBqYXZhU291cmNlKSB7CisgICAgU2NvcGVkU3RyaW5nQ2hhcnMgc291cmNlKGVudiwgamF2YVNvdXJjZSk7CisgICAgaWYgKHNvdXJjZS5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgVUNvbGxhdGlvbkVsZW1lbnRzKiByZXN1bHQgPSB1Y29sX29wZW5FbGVtZW50cyh0b0NvbGxhdG9yKGFkZHJlc3MpLCBzb3VyY2UuZ2V0KCksIHNvdXJjZS5zaXplKCksICZzdGF0dXMpOworICAgIG1heWJlVGhyb3dJY3VFeGNlcHRpb24oZW52LCBzdGF0dXMpOworICAgIHJldHVybiBzdGF0aWNfY2FzdDxqaW50PihyZWludGVycHJldF9jYXN0PHVpbnRwdHJfdD4ocmVzdWx0KSk7Cit9CisKK3N0YXRpYyBqaW50IE5hdGl2ZUNvbGxhdGlvbl9nZXRNYXhFeHBhbnNpb24oSk5JRW52KiwgamNsYXNzLCBqaW50IGFkZHJlc3MsIGppbnQgb3JkZXIpIHsKKyAgICByZXR1cm4gdWNvbF9nZXRNYXhFeHBhbnNpb24odG9Db2xsYXRpb25FbGVtZW50cyhhZGRyZXNzKSwgb3JkZXIpOworfQorCitzdGF0aWMgamludCBOYXRpdmVDb2xsYXRpb25fZ2V0T2Zmc2V0KEpOSUVudiosIGpjbGFzcywgamludCBhZGRyZXNzKSB7CisgICAgcmV0dXJuIHVjb2xfZ2V0T2Zmc2V0KHRvQ29sbGF0aW9uRWxlbWVudHMoYWRkcmVzcykpOworfQorCitzdGF0aWMganN0cmluZyBOYXRpdmVDb2xsYXRpb25fZ2V0UnVsZXMoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBhZGRyZXNzKSB7CisgICAgaW50MzJfdCBsZW5ndGggPSAwOworICAgIGNvbnN0IFVDaGFyKiBydWxlcyA9IHVjb2xfZ2V0UnVsZXModG9Db2xsYXRvcihhZGRyZXNzKSwgJmxlbmd0aCk7CisgICAgcmV0dXJuIGVudi0+TmV3U3RyaW5nKHJ1bGVzLCBsZW5ndGgpOworfQorCitzdGF0aWMgamJ5dGVBcnJheSBOYXRpdmVDb2xsYXRpb25fZ2V0U29ydEtleShKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHJlc3MsIGpzdHJpbmcgamF2YVNvdXJjZSkgeworICAgIFNjb3BlZFN0cmluZ0NoYXJzIHNvdXJjZShlbnYsIGphdmFTb3VyY2UpOworICAgIGlmIChzb3VyY2UuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgY29uc3QgVUNvbGxhdG9yKiBjb2xsYXRvciAgPSB0b0NvbGxhdG9yKGFkZHJlc3MpOworICAgIHVpbnQ4X3QgYnl0ZUFycmF5W1VDT0xfTUFYX0JVRkZFUiAqIDJdOworICAgIFVuaXF1ZVB0cjx1aW50OF90W10+IGxhcmdlckJ5dGVBcnJheTsKKyAgICB1aW50OF90KiB1c2VkQnl0ZUFycmF5ID0gYnl0ZUFycmF5OworICAgIHNpemVfdCBieXRlQXJyYXlTaXplID0gdWNvbF9nZXRTb3J0S2V5KGNvbGxhdG9yLCBzb3VyY2UuZ2V0KCksIHNvdXJjZS5zaXplKCksIHVzZWRCeXRlQXJyYXksIHNpemVvZihieXRlQXJyYXkpIC0gMSk7CisgICAgaWYgKGJ5dGVBcnJheVNpemUgPiBzaXplb2YoYnl0ZUFycmF5KSAtIDEpIHsKKyAgICAgICAgLy8gZGlkbid0IGZpdCwgdHJ5IGFnYWluIHdpdGggYSBsYXJnZXIgYnVmZmVyLgorICAgICAgICBsYXJnZXJCeXRlQXJyYXkucmVzZXQobmV3IHVpbnQ4X3RbYnl0ZUFycmF5U2l6ZSArIDFdKTsKKyAgICAgICAgdXNlZEJ5dGVBcnJheSA9IGxhcmdlckJ5dGVBcnJheS5nZXQoKTsKKyAgICAgICAgYnl0ZUFycmF5U2l6ZSA9IHVjb2xfZ2V0U29ydEtleShjb2xsYXRvciwgc291cmNlLmdldCgpLCBzb3VyY2Uuc2l6ZSgpLCB1c2VkQnl0ZUFycmF5LCBieXRlQXJyYXlTaXplKTsKKyAgICB9CisgICAgaWYgKGJ5dGVBcnJheVNpemUgPT0gMCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgamJ5dGVBcnJheSByZXN1bHQgPSBlbnYtPk5ld0J5dGVBcnJheShieXRlQXJyYXlTaXplKTsKKyAgICBlbnYtPlNldEJ5dGVBcnJheVJlZ2lvbihyZXN1bHQsIDAsIGJ5dGVBcnJheVNpemUsIHJlaW50ZXJwcmV0X2Nhc3Q8amJ5dGUqPih1c2VkQnl0ZUFycmF5KSk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIGppbnQgTmF0aXZlQ29sbGF0aW9uX25leHQoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBhZGRyZXNzKSB7CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgamludCByZXN1bHQgPSB1Y29sX25leHQodG9Db2xsYXRpb25FbGVtZW50cyhhZGRyZXNzKSwgJnN0YXR1cyk7CisgICAgbWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihlbnYsIHN0YXR1cyk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIGppbnQgTmF0aXZlQ29sbGF0aW9uX29wZW5Db2xsYXRvcihKTklFbnYqIGVudiwgamNsYXNzLCBqc3RyaW5nIGxvY2FsZU5hbWUpIHsKKyAgICBTY29wZWRVdGZDaGFycyBsb2NhbGVDaGFycyhlbnYsIGxvY2FsZU5hbWUpOworICAgIGlmIChsb2NhbGVDaGFycy5jX3N0cigpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworICAgIFVDb2xsYXRvciogYyA9IHVjb2xfb3Blbihsb2NhbGVDaGFycy5jX3N0cigpLCAmc3RhdHVzKTsKKyAgICBtYXliZVRocm93SWN1RXhjZXB0aW9uKGVudiwgc3RhdHVzKTsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8amludD4ocmVpbnRlcnByZXRfY2FzdDx1aW50cHRyX3Q+KGMpKTsKK30KKworc3RhdGljIGppbnQgTmF0aXZlQ29sbGF0aW9uX29wZW5Db2xsYXRvckZyb21SdWxlcyhKTklFbnYqIGVudiwgamNsYXNzLCBqc3RyaW5nIGphdmFSdWxlcywgamludCBtb2RlLCBqaW50IHN0cmVuZ3RoKSB7CisgICAgU2NvcGVkU3RyaW5nQ2hhcnMgcnVsZXMoZW52LCBqYXZhUnVsZXMpOworICAgIGlmIChydWxlcy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgVUNvbGxhdG9yKiBjID0gdWNvbF9vcGVuUnVsZXMocnVsZXMuZ2V0KCksIHJ1bGVzLnNpemUoKSwKKyAgICAgICAgICAgIFVDb2xBdHRyaWJ1dGVWYWx1ZShtb2RlKSwgVUNvbGxhdGlvblN0cmVuZ3RoKHN0cmVuZ3RoKSwgTlVMTCwgJnN0YXR1cyk7CisgICAgbWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihlbnYsIHN0YXR1cyk7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGppbnQ+KHJlaW50ZXJwcmV0X2Nhc3Q8dWludHB0cl90PihjKSk7Cit9CisKK3N0YXRpYyBqaW50IE5hdGl2ZUNvbGxhdGlvbl9wcmV2aW91cyhKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHJlc3MpIHsKKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBqaW50IHJlc3VsdCA9IHVjb2xfcHJldmlvdXModG9Db2xsYXRpb25FbGVtZW50cyhhZGRyZXNzKSwgJnN0YXR1cyk7CisgICAgbWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihlbnYsIHN0YXR1cyk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIHZvaWQgTmF0aXZlQ29sbGF0aW9uX3Jlc2V0KEpOSUVudiosIGpjbGFzcywgamludCBhZGRyZXNzKSB7CisgICAgdWNvbF9yZXNldCh0b0NvbGxhdGlvbkVsZW1lbnRzKGFkZHJlc3MpKTsKK30KKworc3RhdGljIGppbnQgTmF0aXZlQ29sbGF0aW9uX3NhZmVDbG9uZShKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHJlc3MpIHsKKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBqaW50IGJ1ZmZlclNpemUgPSBVX0NPTF9TQUZFQ0xPTkVfQlVGRkVSU0laRTsKKyAgICBVQ29sbGF0b3IqIGMgPSB1Y29sX3NhZmVDbG9uZSh0b0NvbGxhdG9yKGFkZHJlc3MpLCBOVUxMLCAmYnVmZmVyU2l6ZSwgJnN0YXR1cyk7CisgICAgbWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihlbnYsIHN0YXR1cyk7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGppbnQ+KHJlaW50ZXJwcmV0X2Nhc3Q8dWludHB0cl90PihjKSk7Cit9CisKK3N0YXRpYyB2b2lkIE5hdGl2ZUNvbGxhdGlvbl9zZXRBdHRyaWJ1dGUoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBhZGRyZXNzLCBqaW50IHR5cGUsIGppbnQgdmFsdWUpIHsKKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICB1Y29sX3NldEF0dHJpYnV0ZSh0b0NvbGxhdG9yKGFkZHJlc3MpLCAoVUNvbEF0dHJpYnV0ZSl0eXBlLCAoVUNvbEF0dHJpYnV0ZVZhbHVlKXZhbHVlLCAmc3RhdHVzKTsKKyAgICBtYXliZVRocm93SWN1RXhjZXB0aW9uKGVudiwgc3RhdHVzKTsKK30KKworc3RhdGljIHZvaWQgTmF0aXZlQ29sbGF0aW9uX3NldE9mZnNldChKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHJlc3MsIGppbnQgb2Zmc2V0KSB7CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgdWNvbF9zZXRPZmZzZXQodG9Db2xsYXRpb25FbGVtZW50cyhhZGRyZXNzKSwgb2Zmc2V0LCAmc3RhdHVzKTsKKyAgICBtYXliZVRocm93SWN1RXhjZXB0aW9uKGVudiwgc3RhdHVzKTsKK30KKworc3RhdGljIHZvaWQgTmF0aXZlQ29sbGF0aW9uX3NldFRleHQoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBhZGRyZXNzLCBqc3RyaW5nIGphdmFTb3VyY2UpIHsKKyAgICBTY29wZWRTdHJpbmdDaGFycyBzb3VyY2UoZW52LCBqYXZhU291cmNlKTsKKyAgICBpZiAoc291cmNlLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICB1Y29sX3NldFRleHQodG9Db2xsYXRpb25FbGVtZW50cyhhZGRyZXNzKSwgc291cmNlLmdldCgpLCBzb3VyY2Uuc2l6ZSgpLCAmc3RhdHVzKTsKKyAgICBtYXliZVRocm93SWN1RXhjZXB0aW9uKGVudiwgc3RhdHVzKTsKK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBnTWV0aG9kc1tdID0geworICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ29sbGF0aW9uLCBjbG9zZUNvbGxhdG9yLCAiKEkpViIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ29sbGF0aW9uLCBjbG9zZUVsZW1lbnRzLCAiKEkpViIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ29sbGF0aW9uLCBjb21wYXJlLCAiKElMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZzspSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ29sbGF0aW9uLCBnZXRBdHRyaWJ1dGUsICIoSUkpSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ29sbGF0aW9uLCBnZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IsICIoSUxqYXZhL2xhbmcvU3RyaW5nOylJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDb2xsYXRpb24sIGdldE1heEV4cGFuc2lvbiwgIihJSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDb2xsYXRpb24sIGdldE9mZnNldCwgIihJKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNvbGxhdGlvbiwgZ2V0UnVsZXMsICIoSSlMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNvbGxhdGlvbiwgZ2V0U29ydEtleSwgIihJTGphdmEvbGFuZy9TdHJpbmc7KVtCIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDb2xsYXRpb24sIG5leHQsICIoSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDb2xsYXRpb24sIG9wZW5Db2xsYXRvciwgIihMamF2YS9sYW5nL1N0cmluZzspSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ29sbGF0aW9uLCBvcGVuQ29sbGF0b3JGcm9tUnVsZXMsICIoTGphdmEvbGFuZy9TdHJpbmc7SUkpSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ29sbGF0aW9uLCBwcmV2aW91cywgIihJKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNvbGxhdGlvbiwgcmVzZXQsICIoSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDb2xsYXRpb24sIHNhZmVDbG9uZSwgIihJKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNvbGxhdGlvbiwgc2V0QXR0cmlidXRlLCAiKElJSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDb2xsYXRpb24sIHNldE9mZnNldCwgIihJSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDb2xsYXRpb24sIHNldFRleHQsICIoSUxqYXZhL2xhbmcvU3RyaW5nOylWIiksCit9OworaW50IHJlZ2lzdGVyX2xpYmNvcmVfaWN1X05hdGl2ZUNvbGxhdGlvbihKTklFbnYqIGVudikgeworICAgIHJldHVybiBqbmlSZWdpc3Rlck5hdGl2ZU1ldGhvZHMoZW52LCAibGliY29yZS9pY3UvTmF0aXZlQ29sbGF0aW9uIiwgZ01ldGhvZHMsIE5FTEVNKGdNZXRob2RzKSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS9saWJjb3JlX2ljdV9OYXRpdmVDb252ZXJ0ZXIuY3BwIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pY3VfTmF0aXZlQ29udmVydGVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YTdmYmM1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pY3VfTmF0aXZlQ29udmVydGVyLmNwcApAQCAtMCwwICsxLDYxMyBAQAorLyoqCisqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisqIENvcHlyaWdodCAoQykgMTk5Ni0yMDA2LCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZCAgICAqCisqIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCisqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisqCisqCisqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisqLworLyoKKyAqIChDKSBDb3B5cmlnaHQgSUJNIENvcnAuIDIwMDAgLSBBbGwgUmlnaHRzIFJlc2VydmVkCisgKiAgQSBKTkkgd3JhcHBlciB0byBJQ1UgbmF0aXZlIGNvbnZlcnRlciBJbnRlcmZhY2UKKyAqIEBhdXRob3I6IFJhbSBWaXN3YW5hZGhhCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJOYXRpdmVDb252ZXJ0ZXIiCisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisjaW5jbHVkZSAiSm5pRXhjZXB0aW9uLmgiCisjaW5jbHVkZSAiU2NvcGVkTG9jYWxSZWYuaCIKKyNpbmNsdWRlICJTY29wZWRQcmltaXRpdmVBcnJheS5oIgorI2luY2x1ZGUgIlNjb3BlZFN0cmluZ0NoYXJzLmgiCisjaW5jbHVkZSAiU2NvcGVkVXRmQ2hhcnMuaCIKKyNpbmNsdWRlICJVbmlxdWVQdHIuaCIKKyNpbmNsdWRlICJjdXRpbHMvbG9nLmgiCisjaW5jbHVkZSAidG9TdHJpbmdBcnJheS5oIgorI2luY2x1ZGUgInVuaWNvZGUvdWNudi5oIgorI2luY2x1ZGUgInVuaWNvZGUvdWNudl9jYi5oIgorI2luY2x1ZGUgInVuaWNvZGUvdW5pc2V0LmgiCisjaW5jbHVkZSAidW5pY29kZS91c3RyaW5nLmgiCisjaW5jbHVkZSAidW5pY29kZS91dHlwZXMuaCIKKworI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorCisjZGVmaW5lIE5hdGl2ZUNvbnZlcnRlcl9SRVBPUlQgMAorI2RlZmluZSBOYXRpdmVDb252ZXJ0ZXJfSUdOT1JFIDEKKyNkZWZpbmUgTmF0aXZlQ29udmVydGVyX1JFUExBQ0UgMgorCisjZGVmaW5lIE1BWF9SRVBMQUNFTUVOVF9MRU5HVEggMzIgLy8gZXF1aXZhbGVudCB0byBVQ05WX0VSUk9SX0JVRkZFUl9MRU5HVEgKKworc3RydWN0IERlY29kZXJDYWxsYmFja0NvbnRleHQgeworICAgIFVDaGFyIHJlcGxhY2VtZW50Q2hhcnNbTUFYX1JFUExBQ0VNRU5UX0xFTkdUSF07CisgICAgc2l6ZV90IHJlcGxhY2VtZW50Q2hhckNvdW50OworICAgIFVDb252ZXJ0ZXJUb1VDYWxsYmFjayBvblVubWFwcGFibGVJbnB1dDsKKyAgICBVQ29udmVydGVyVG9VQ2FsbGJhY2sgb25NYWxmb3JtZWRJbnB1dDsKK307CisKK3N0cnVjdCBFbmNvZGVyQ2FsbGJhY2tDb250ZXh0IHsKKyAgICBjaGFyIHJlcGxhY2VtZW50Qnl0ZXNbTUFYX1JFUExBQ0VNRU5UX0xFTkdUSF07CisgICAgc2l6ZV90IHJlcGxhY2VtZW50Qnl0ZUNvdW50OworICAgIFVDb252ZXJ0ZXJGcm9tVUNhbGxiYWNrIG9uVW5tYXBwYWJsZUlucHV0OworICAgIFVDb252ZXJ0ZXJGcm9tVUNhbGxiYWNrIG9uTWFsZm9ybWVkSW5wdXQ7Cit9OworCitzdHJ1Y3QgVUNvbnZlcnRlckRlbGV0ZXIgeworICAgIHZvaWQgb3BlcmF0b3IoKShVQ29udmVydGVyKiBwKSBjb25zdCB7CisgICAgICAgIHVjbnZfY2xvc2UocCk7CisgICAgfQorfTsKK3R5cGVkZWYgVW5pcXVlUHRyPFVDb252ZXJ0ZXIsIFVDb252ZXJ0ZXJEZWxldGVyPiBVbmlxdWVVQ29udmVydGVyOworCitzdGF0aWMgVUNvbnZlcnRlciogdG9VQ29udmVydGVyKGpsb25nIGFkZHJlc3MpIHsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxVQ29udmVydGVyKj4oc3RhdGljX2Nhc3Q8dWludHB0cl90PihhZGRyZXNzKSk7Cit9CisKK3N0YXRpYyBqbG9uZyBOYXRpdmVDb252ZXJ0ZXJfb3BlbkNvbnZlcnRlcihKTklFbnYqIGVudiwgamNsYXNzLCBqc3RyaW5nIGNvbnZlcnRlck5hbWUpIHsKKyAgICBTY29wZWRVdGZDaGFycyBjb252ZXJ0ZXJOYW1lQ2hhcnMoZW52LCBjb252ZXJ0ZXJOYW1lKTsKKyAgICBpZiAoY29udmVydGVyTmFtZUNoYXJzLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgVUNvbnZlcnRlciogY252ID0gdWNudl9vcGVuKGNvbnZlcnRlck5hbWVDaGFycy5jX3N0cigpLCAmc3RhdHVzKTsKKyAgICBtYXliZVRocm93SWN1RXhjZXB0aW9uKGVudiwgc3RhdHVzKTsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDx1aW50cHRyX3Q+KGNudik7Cit9CisKK3N0YXRpYyB2b2lkIE5hdGl2ZUNvbnZlcnRlcl9jbG9zZUNvbnZlcnRlcihKTklFbnYqLCBqY2xhc3MsIGpsb25nIGFkZHJlc3MpIHsKKyAgICB1Y252X2Nsb3NlKHRvVUNvbnZlcnRlcihhZGRyZXNzKSk7Cit9CisKK3N0YXRpYyBqaW50IE5hdGl2ZUNvbnZlcnRlcl9lbmNvZGUoSk5JRW52KiBlbnYsIGpjbGFzcywgamxvbmcgYWRkcmVzcywKKyAgICAgICAgamNoYXJBcnJheSBzb3VyY2UsIGppbnQgc291cmNlRW5kLCBqYnl0ZUFycmF5IHRhcmdldCwgamludCB0YXJnZXRFbmQsCisgICAgICAgIGppbnRBcnJheSBkYXRhLCBqYm9vbGVhbiBmbHVzaCkgeworCisgICAgVUNvbnZlcnRlciogY252ID0gdG9VQ29udmVydGVyKGFkZHJlc3MpOworICAgIGlmIChjbnYgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SOworICAgIH0KKyAgICBTY29wZWRDaGFyQXJyYXlSTyB1U291cmNlKGVudiwgc291cmNlKTsKKyAgICBpZiAodVNvdXJjZS5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1I7CisgICAgfQorICAgIFNjb3BlZEJ5dGVBcnJheVJXIHVUYXJnZXQoZW52LCB0YXJnZXQpOworICAgIGlmICh1VGFyZ2V0LmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUjsKKyAgICB9CisgICAgU2NvcGVkSW50QXJyYXlSVyBteURhdGEoZW52LCBkYXRhKTsKKyAgICBpZiAobXlEYXRhLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUjsKKyAgICB9CisKKyAgICAvLyBEbyB0aGUgY29udmVyc2lvbi4KKyAgICBqaW50KiBzb3VyY2VPZmZzZXQgPSAmbXlEYXRhWzBdOworICAgIGppbnQqIHRhcmdldE9mZnNldCA9ICZteURhdGFbMV07CisgICAgY29uc3QgamNoYXIqIG15U291cmNlID0gdVNvdXJjZS5nZXQoKSArICpzb3VyY2VPZmZzZXQ7CisgICAgY29uc3QgVUNoYXIqIG15U291cmNlTGltaXQ9IHVTb3VyY2UuZ2V0KCkgKyBzb3VyY2VFbmQ7CisgICAgY2hhciogY1RhcmdldCA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KHVUYXJnZXQuZ2V0KCkgKyAqdGFyZ2V0T2Zmc2V0KTsKKyAgICBjb25zdCBjaGFyKiBjVGFyZ2V0TGltaXQgPSByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih1VGFyZ2V0LmdldCgpICsgdGFyZ2V0RW5kKTsKKyAgICBVRXJyb3JDb2RlIGVycm9yQ29kZSA9IFVfWkVST19FUlJPUjsKKyAgICB1Y252X2Zyb21Vbmljb2RlKGNudiAsICZjVGFyZ2V0LCBjVGFyZ2V0TGltaXQsICZteVNvdXJjZSwgbXlTb3VyY2VMaW1pdCwgTlVMTCwgKFVCb29sKSBmbHVzaCwgJmVycm9yQ29kZSk7CisgICAgKnNvdXJjZU9mZnNldCA9IChteVNvdXJjZSAtIHVTb3VyY2UuZ2V0KCkpIC0gKnNvdXJjZU9mZnNldDsKKyAgICAqdGFyZ2V0T2Zmc2V0ID0gKHJlaW50ZXJwcmV0X2Nhc3Q8amJ5dGUqPihjVGFyZ2V0KSAtIHVUYXJnZXQuZ2V0KCkpIC0gKnRhcmdldE9mZnNldDsKKworICAgIC8vIElmIHRoZXJlIHdhcyBhbiBlcnJvciwgY291bnQgdGhlIHByb2JsZW1hdGljIGNoYXJhY3RlcnMuCisgICAgaWYgKGVycm9yQ29kZSA9PSBVX0lMTEVHQUxfQ0hBUl9GT1VORCB8fCBlcnJvckNvZGUgPT0gVV9JTlZBTElEX0NIQVJfRk9VTkQpIHsKKyAgICAgICAgaW50OF90IGludmFsaWRVQ2hhckNvdW50ID0gMzI7CisgICAgICAgIFVDaGFyIGludmFsaWRVQ2hhcnNbMzJdOworICAgICAgICBVRXJyb3JDb2RlIG1pbm9yRXJyb3JDb2RlID0gVV9aRVJPX0VSUk9SOworICAgICAgICB1Y252X2dldEludmFsaWRVQ2hhcnMoY252LCBpbnZhbGlkVUNoYXJzLCAmaW52YWxpZFVDaGFyQ291bnQsICZtaW5vckVycm9yQ29kZSk7CisgICAgICAgIGlmIChVX1NVQ0NFU1MobWlub3JFcnJvckNvZGUpKSB7CisgICAgICAgICAgICBteURhdGFbMl0gPSBpbnZhbGlkVUNoYXJDb3VudDsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZXJyb3JDb2RlOworfQorCitzdGF0aWMgamludCBOYXRpdmVDb252ZXJ0ZXJfZGVjb2RlKEpOSUVudiogZW52LCBqY2xhc3MsIGpsb25nIGFkZHJlc3MsCisgICAgICAgIGpieXRlQXJyYXkgc291cmNlLCBqaW50IHNvdXJjZUVuZCwgamNoYXJBcnJheSB0YXJnZXQsIGppbnQgdGFyZ2V0RW5kLAorICAgICAgICBqaW50QXJyYXkgZGF0YSwgamJvb2xlYW4gZmx1c2gpIHsKKworICAgIFVDb252ZXJ0ZXIqIGNudiA9IHRvVUNvbnZlcnRlcihhZGRyZXNzKTsKKyAgICBpZiAoY252ID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUjsKKyAgICB9CisgICAgU2NvcGVkQnl0ZUFycmF5Uk8gdVNvdXJjZShlbnYsIHNvdXJjZSk7CisgICAgaWYgKHVTb3VyY2UuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SOworICAgIH0KKyAgICBTY29wZWRDaGFyQXJyYXlSVyB1VGFyZ2V0KGVudiwgdGFyZ2V0KTsKKyAgICBpZiAodVRhcmdldC5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1I7CisgICAgfQorICAgIFNjb3BlZEludEFycmF5UlcgbXlEYXRhKGVudiwgZGF0YSk7CisgICAgaWYgKG15RGF0YS5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1I7CisgICAgfQorCisgICAgLy8gRG8gdGhlIGNvbnZlcnNpb24uCisgICAgamludCogc291cmNlT2Zmc2V0ID0gJm15RGF0YVswXTsKKyAgICBqaW50KiB0YXJnZXRPZmZzZXQgPSAmbXlEYXRhWzFdOworICAgIGNvbnN0IGNoYXIqIG15U291cmNlID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odVNvdXJjZS5nZXQoKSArICpzb3VyY2VPZmZzZXQpOworICAgIGNvbnN0IGNoYXIqIG15U291cmNlTGltaXQgPSByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih1U291cmNlLmdldCgpICsgc291cmNlRW5kKTsKKyAgICBVQ2hhciogY1RhcmdldCA9IHVUYXJnZXQuZ2V0KCkgKyAqdGFyZ2V0T2Zmc2V0OworICAgIGNvbnN0IFVDaGFyKiBjVGFyZ2V0TGltaXQgPSB1VGFyZ2V0LmdldCgpICsgdGFyZ2V0RW5kOworICAgIFVFcnJvckNvZGUgZXJyb3JDb2RlID0gVV9aRVJPX0VSUk9SOworICAgIHVjbnZfdG9Vbmljb2RlKGNudiwgJmNUYXJnZXQsIGNUYXJnZXRMaW1pdCwgJm15U291cmNlLCBteVNvdXJjZUxpbWl0LCBOVUxMLCBmbHVzaCwgJmVycm9yQ29kZSk7CisgICAgKnNvdXJjZU9mZnNldCA9IG15U291cmNlIC0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odVNvdXJjZS5nZXQoKSkgLSAqc291cmNlT2Zmc2V0OworICAgICp0YXJnZXRPZmZzZXQgPSBjVGFyZ2V0IC0gdVRhcmdldC5nZXQoKSAtICp0YXJnZXRPZmZzZXQ7CisKKyAgICAvLyBJZiB0aGVyZSB3YXMgYW4gZXJyb3IsIGNvdW50IHRoZSBwcm9ibGVtYXRpYyBieXRlcy4KKyAgICBpZiAoZXJyb3JDb2RlID09IFVfSUxMRUdBTF9DSEFSX0ZPVU5EIHx8IGVycm9yQ29kZSA9PSBVX0lOVkFMSURfQ0hBUl9GT1VORCkgeworICAgICAgICBpbnQ4X3QgaW52YWxpZEJ5dGVDb3VudCA9IDMyOworICAgICAgICBjaGFyIGludmFsaWRCeXRlc1szMl0gPSB7J1wwJ307CisgICAgICAgIFVFcnJvckNvZGUgbWlub3JFcnJvckNvZGUgPSBVX1pFUk9fRVJST1I7CisgICAgICAgIHVjbnZfZ2V0SW52YWxpZENoYXJzKGNudiwgaW52YWxpZEJ5dGVzLCAmaW52YWxpZEJ5dGVDb3VudCwgJm1pbm9yRXJyb3JDb2RlKTsKKyAgICAgICAgaWYgKFVfU1VDQ0VTUyhtaW5vckVycm9yQ29kZSkpIHsKKyAgICAgICAgICAgIG15RGF0YVsyXSA9IGludmFsaWRCeXRlQ291bnQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gZXJyb3JDb2RlOworfQorCitzdGF0aWMgdm9pZCBOYXRpdmVDb252ZXJ0ZXJfcmVzZXRCeXRlVG9DaGFyKEpOSUVudiosIGpjbGFzcywgamxvbmcgYWRkcmVzcykgeworICAgIFVDb252ZXJ0ZXIqIGNudiA9IHRvVUNvbnZlcnRlcihhZGRyZXNzKTsKKyAgICBpZiAoY252KSB7CisgICAgICAgIHVjbnZfcmVzZXRUb1VuaWNvZGUoY252KTsKKyAgICB9Cit9CisKK3N0YXRpYyB2b2lkIE5hdGl2ZUNvbnZlcnRlcl9yZXNldENoYXJUb0J5dGUoSk5JRW52KiwgamNsYXNzLCBqbG9uZyBhZGRyZXNzKSB7CisgICAgVUNvbnZlcnRlciogY252ID0gdG9VQ29udmVydGVyKGFkZHJlc3MpOworICAgIGlmIChjbnYpIHsKKyAgICAgICAgdWNudl9yZXNldEZyb21Vbmljb2RlKGNudik7CisgICAgfQorfQorCitzdGF0aWMgamludCBOYXRpdmVDb252ZXJ0ZXJfZ2V0TWF4Qnl0ZXNQZXJDaGFyKEpOSUVudiosIGpjbGFzcywgamxvbmcgYWRkcmVzcykgeworICAgIFVDb252ZXJ0ZXIqIGNudiA9IHRvVUNvbnZlcnRlcihhZGRyZXNzKTsKKyAgICByZXR1cm4gKGNudiAhPSBOVUxMKSA/IHVjbnZfZ2V0TWF4Q2hhclNpemUoY252KSA6IC0xOworfQorCitzdGF0aWMgamludCBOYXRpdmVDb252ZXJ0ZXJfZ2V0TWluQnl0ZXNQZXJDaGFyKEpOSUVudiosIGpjbGFzcywgamxvbmcgYWRkcmVzcykgeworICAgIFVDb252ZXJ0ZXIqIGNudiA9IHRvVUNvbnZlcnRlcihhZGRyZXNzKTsKKyAgICByZXR1cm4gKGNudiAhPSBOVUxMKSA/IHVjbnZfZ2V0TWluQ2hhclNpemUoY252KSA6IC0xOworfQorCitzdGF0aWMgamZsb2F0IE5hdGl2ZUNvbnZlcnRlcl9nZXRBdmVCeXRlc1BlckNoYXIoSk5JRW52KiwgamNsYXNzLCBqbG9uZyBhZGRyZXNzKSB7CisgICAgVUNvbnZlcnRlciogY252ID0gdG9VQ29udmVydGVyKGFkZHJlc3MpOworICAgIHJldHVybiAoY252ICE9IE5VTEwpID8gKCh1Y252X2dldE1heENoYXJTaXplKGNudikgKyB1Y252X2dldE1pbkNoYXJTaXplKGNudikpIC8gMi4wKSA6IC0xOworfQorCitzdGF0aWMgamJvb2xlYW4gTmF0aXZlQ29udmVydGVyX2NhbkVuY29kZShKTklFbnYqLCBqY2xhc3MsIGpsb25nIGFkZHJlc3MsIGppbnQgY29kZVVuaXQpIHsKKyAgICBVRXJyb3JDb2RlIGVycm9yQ29kZSA9IFVfWkVST19FUlJPUjsKKyAgICBVQ29udmVydGVyKiBjbnYgPSB0b1VDb252ZXJ0ZXIoYWRkcmVzcyk7CisgICAgaWYgKGNudiA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBKTklfRkFMU0U7CisgICAgfQorCisgICAgVUNoYXIgc3JjQnVmZmVyWzNdOworICAgIGNvbnN0IFVDaGFyKiBzcmMgPSAmc3JjQnVmZmVyWzBdOworICAgIGNvbnN0IFVDaGFyKiBzcmNMaW1pdCA9IChjb2RlVW5pdCA8IDB4MTAwMDApID8gJnNyY1sxXSA6ICZzcmNbMl07CisKKyAgICBjaGFyIGRzdEJ1ZmZlcls1XTsKKyAgICBjaGFyKiBkc3QgPSAmZHN0QnVmZmVyWzBdOworICAgIGNvbnN0IGNoYXIqIGRzdExpbWl0ID0gJmRzdEJ1ZmZlcls0XTsKKworICAgIGludCBpID0gMDsKKyAgICBVVEZfQVBQRU5EX0NIQVIoJnNyY0J1ZmZlclswXSwgaSwgMiwgY29kZVVuaXQpOworCisgICAgdWNudl9mcm9tVW5pY29kZShjbnYsICZkc3QsIGRzdExpbWl0LCAmc3JjLCBzcmNMaW1pdCwgTlVMTCwgVFJVRSwgJmVycm9yQ29kZSk7CisgICAgcmV0dXJuIFVfU1VDQ0VTUyhlcnJvckNvZGUpOworfQorCisvKgorICogSWYgYSBjaGFyc2V0IGxpc3RlZCBpbiB0aGUgSUFOQSBDaGFyc2V0IFJlZ2lzdHJ5IGlzIHN1cHBvcnRlZCBieSBhbiBpbXBsZW1lbnRhdGlvbgorICogb2YgdGhlIEphdmEgcGxhdGZvcm0gdGhlbiBpdHMgY2Fub25pY2FsIG5hbWUgbXVzdCBiZSB0aGUgbmFtZSBsaXN0ZWQgaW4gdGhlIHJlZ2lzdHJ5LgorICogTWFueSBjaGFyc2V0cyBhcmUgZ2l2ZW4gbW9yZSB0aGFuIG9uZSBuYW1lIGluIHRoZSByZWdpc3RyeSwgaW4gd2hpY2ggY2FzZSB0aGUgcmVnaXN0cnkKKyAqIGlkZW50aWZpZXMgb25lIG9mIHRoZSBuYW1lcyBhcyBNSU1FLXByZWZlcnJlZC4gSWYgYSBjaGFyc2V0IGhhcyBtb3JlIHRoYW4gb25lIHJlZ2lzdHJ5CisgKiBuYW1lIHRoZW4gaXRzIGNhbm9uaWNhbCBuYW1lIG11c3QgYmUgdGhlIE1JTUUtcHJlZmVycmVkIG5hbWUgYW5kIHRoZSBvdGhlciBuYW1lcyBpbgorICogdGhlIHJlZ2lzdHJ5IG11c3QgYmUgdmFsaWQgYWxpYXNlcy4gSWYgYSBzdXBwb3J0ZWQgY2hhcnNldCBpcyBub3QgbGlzdGVkIGluIHRoZSBJQU5BCisgKiByZWdpc3RyeSB0aGVuIGl0cyBjYW5vbmljYWwgbmFtZSBtdXN0IGJlZ2luIHdpdGggb25lIG9mIHRoZSBzdHJpbmdzICJYLSIgb3IgIngtIi4KKyAqLworc3RhdGljIGpzdHJpbmcgZ2V0SmF2YUNhbm9uaWNhbE5hbWUoSk5JRW52KiBlbnYsIGNvbnN0IGNoYXIqIGljdUNhbm9uaWNhbE5hbWUpIHsKKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKworICAgIC8vIENoZWNrIHRvIHNlZSBpZiB0aGlzIGlzIGEgd2VsbC1rbm93biBNSU1FIG9yIElBTkEgbmFtZS4KKyAgICBjb25zdCBjaGFyKiBjTmFtZSA9IE5VTEw7CisgICAgaWYgKChjTmFtZSA9IHVjbnZfZ2V0U3RhbmRhcmROYW1lKGljdUNhbm9uaWNhbE5hbWUsICJNSU1FIiwgJnN0YXR1cykpICE9IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIGVudi0+TmV3U3RyaW5nVVRGKGNOYW1lKTsKKyAgICB9IGVsc2UgaWYgKChjTmFtZSA9IHVjbnZfZ2V0U3RhbmRhcmROYW1lKGljdUNhbm9uaWNhbE5hbWUsICJJQU5BIiwgJnN0YXR1cykpICE9IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIGVudi0+TmV3U3RyaW5nVVRGKGNOYW1lKTsKKyAgICB9CisKKyAgICAvLyBDaGVjayB0byBzZWUgaWYgYW4gYWxpYXMgYWxyZWFkeSBleGlzdHMgd2l0aCAieC0iIHByZWZpeCwgaWYgeWVzIHRoZW4KKyAgICAvLyBtYWtlIHRoYXQgdGhlIGNhbm9uaWNhbCBuYW1lLgorICAgIGludDMyX3QgYWxpYXNDb3VudCA9IHVjbnZfY291bnRBbGlhc2VzKGljdUNhbm9uaWNhbE5hbWUsICZzdGF0dXMpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxpYXNDb3VudDsgKytpKSB7CisgICAgICAgIGNvbnN0IGNoYXIqIG5hbWUgPSB1Y252X2dldEFsaWFzKGljdUNhbm9uaWNhbE5hbWUsIGksICZzdGF0dXMpOworICAgICAgICBpZiAobmFtZSAhPSBOVUxMICYmIG5hbWVbMF0gPT0gJ3gnICYmIG5hbWVbMV0gPT0gJy0nKSB7CisgICAgICAgICAgICByZXR1cm4gZW52LT5OZXdTdHJpbmdVVEYobmFtZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBBcyBhIGxhc3QgcmVzb3J0LCBwcmVwZW5kICJ4LSIgdG8gYW55IGFsaWFzIGFuZCBtYWtlIHRoYXQgdGhlIGNhbm9uaWNhbCBuYW1lLgorICAgIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBjb25zdCBjaGFyKiBuYW1lID0gdWNudl9nZXRTdGFuZGFyZE5hbWUoaWN1Q2Fub25pY2FsTmFtZSwgIlVUUjIyIiwgJnN0YXR1cyk7CisgICAgaWYgKG5hbWUgPT0gTlVMTCAmJiBzdHJjaHIoaWN1Q2Fub25pY2FsTmFtZSwgJywnKSAhPSBOVUxMKSB7CisgICAgICAgIG5hbWUgPSB1Y252X2dldEFsaWFzKGljdUNhbm9uaWNhbE5hbWUsIDEsICZzdGF0dXMpOworICAgIH0KKyAgICAvLyBJZiB0aGVyZSBpcyBubyBVVFIyMiBjYW5vbmljYWwgbmFtZSB0aGVuIGp1c3QgcmV0dXJuIHRoZSBvcmlnaW5hbCBuYW1lLgorICAgIGlmIChuYW1lID09IE5VTEwpIHsKKyAgICAgICAgbmFtZSA9IGljdUNhbm9uaWNhbE5hbWU7CisgICAgfQorICAgIFVuaXF1ZVB0cjxjaGFyW10+IHJlc3VsdChuZXcgY2hhclsyICsgc3RybGVuKG5hbWUpICsgMV0pOworICAgIHN0cmNweSgmcmVzdWx0WzBdLCAieC0iKTsKKyAgICBzdHJjYXQoJnJlc3VsdFswXSwgbmFtZSk7CisgICAgcmV0dXJuIGVudi0+TmV3U3RyaW5nVVRGKCZyZXN1bHRbMF0pOworfQorCitzdGF0aWMgam9iamVjdEFycmF5IE5hdGl2ZUNvbnZlcnRlcl9nZXRBdmFpbGFibGVDaGFyc2V0TmFtZXMoSk5JRW52KiBlbnYsIGpjbGFzcykgeworICAgIGludDMyX3QgbnVtID0gdWNudl9jb3VudEF2YWlsYWJsZSgpOworICAgIGpvYmplY3RBcnJheSByZXN1bHQgPSBlbnYtPk5ld09iamVjdEFycmF5KG51bSwgSm5pQ29uc3RhbnRzOjpzdHJpbmdDbGFzcywgTlVMTCk7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bTsgKytpKSB7CisgICAgICAgIGNvbnN0IGNoYXIqIG5hbWUgPSB1Y252X2dldEF2YWlsYWJsZU5hbWUoaSk7CisgICAgICAgIFNjb3BlZExvY2FsUmVmPGpzdHJpbmc+IGphdmFDYW5vbmljYWxOYW1lKGVudiwgZ2V0SmF2YUNhbm9uaWNhbE5hbWUoZW52LCBuYW1lKSk7CisgICAgICAgIGlmIChqYXZhQ2Fub25pY2FsTmFtZS5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBlbnYtPlNldE9iamVjdEFycmF5RWxlbWVudChyZXN1bHQsIGksIGphdmFDYW5vbmljYWxOYW1lLmdldCgpKTsKKyAgICAgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIGpvYmplY3RBcnJheSBnZXRBbGlhc2VzKEpOSUVudiogZW52LCBjb25zdCBjaGFyKiBpY3VDYW5vbmljYWxOYW1lKSB7CisgICAgLy8gR2V0IGFuIHVwcGVyIGJvdW5kIG9uIHRoZSBudW1iZXIgb2YgYWxpYXNlcy4uLgorICAgIGNvbnN0IGNoYXIqIG15RW5jTmFtZSA9IGljdUNhbm9uaWNhbE5hbWU7CisgICAgVUVycm9yQ29kZSBlcnJvciA9IFVfWkVST19FUlJPUjsKKyAgICBzaXplX3QgYWxpYXNDb3VudCA9IHVjbnZfY291bnRBbGlhc2VzKG15RW5jTmFtZSwgJmVycm9yKTsKKyAgICBpZiAoYWxpYXNDb3VudCA9PSAwICYmIG15RW5jTmFtZVswXSA9PSAneCcgJiYgbXlFbmNOYW1lWzFdID09ICctJykgeworICAgICAgICBteUVuY05hbWUgPSBteUVuY05hbWUgKyAyOworICAgICAgICBhbGlhc0NvdW50ID0gdWNudl9jb3VudEFsaWFzZXMobXlFbmNOYW1lLCAmZXJyb3IpOworICAgIH0KKyAgICBpZiAoIVVfU1VDQ0VTUyhlcnJvcikpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgLy8gQ29sbGVjdCB0aGUgYWxpYXNlcyB3ZSB3YW50Li4uCisgICAgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IGFsaWFzZXM7CisgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBhbGlhc0NvdW50OyArK2kpIHsKKyAgICAgICAgY29uc3QgY2hhciogbmFtZSA9IHVjbnZfZ2V0QWxpYXMobXlFbmNOYW1lLCBpLCAmZXJyb3IpOworICAgICAgICBpZiAoIVVfU1VDQ0VTUyhlcnJvcikpIHsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIC8vIFRPRE86IHdoeSBkbyB3ZSBpZ25vcmUgdGhlc2Ugb25lcz8KKyAgICAgICAgaWYgKHN0cmNocihuYW1lLCAnKycpID09IDAgJiYgc3RyY2hyKG5hbWUsICcsJykgPT0gMCkgeworICAgICAgICAgICAgYWxpYXNlcy5wdXNoX2JhY2sobmFtZSk7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHRvU3RyaW5nQXJyYXkoZW52LCBhbGlhc2VzKTsKK30KKworc3RhdGljIGNvbnN0IGNoYXIqIGdldElDVUNhbm9uaWNhbE5hbWUoY29uc3QgY2hhciogbmFtZSkgeworICAgIFVFcnJvckNvZGUgZXJyb3IgPSBVX1pFUk9fRVJST1I7CisgICAgY29uc3QgY2hhciogY2Fub25pY2FsTmFtZSA9IE5VTEw7CisgICAgaWYgKChjYW5vbmljYWxOYW1lID0gdWNudl9nZXRDYW5vbmljYWxOYW1lKG5hbWUsICJNSU1FIiwgJmVycm9yKSkgIT0gTlVMTCkgeworICAgICAgICByZXR1cm4gY2Fub25pY2FsTmFtZTsKKyAgICB9IGVsc2UgaWYoKGNhbm9uaWNhbE5hbWUgPSB1Y252X2dldENhbm9uaWNhbE5hbWUobmFtZSwgIklBTkEiLCAmZXJyb3IpKSAhPSBOVUxMKSB7CisgICAgICAgIHJldHVybiBjYW5vbmljYWxOYW1lOworICAgIH0gZWxzZSBpZigoY2Fub25pY2FsTmFtZSA9IHVjbnZfZ2V0Q2Fub25pY2FsTmFtZShuYW1lLCAiIiwgJmVycm9yKSkgIT0gTlVMTCkgeworICAgICAgICByZXR1cm4gY2Fub25pY2FsTmFtZTsKKyAgICB9IGVsc2UgaWYoKGNhbm9uaWNhbE5hbWUgPSAgdWNudl9nZXRBbGlhcyhuYW1lLCAwLCAmZXJyb3IpKSAhPSBOVUxMKSB7CisgICAgICAgIC8qIHdlIGhhdmUgc29tZSBhbGlhc2VzIGluIHRoZSBmb3JtIHgtYmxhaCAuLiBtYXRjaCB0aG9zZSBmaXJzdCAqLworICAgICAgICByZXR1cm4gY2Fub25pY2FsTmFtZTsKKyAgICB9IGVsc2UgaWYgKHN0cnN0cihuYW1lLCAieC0iKSA9PSBuYW1lKSB7CisgICAgICAgIC8qIGNoZWNrIGlmIHRoZSBjb252ZXJ0ZXIgY2FuIGJlIG9wZW5lZCB3aXRoIHRoZSBuYW1lIGdpdmVuICovCisgICAgICAgIGVycm9yID0gVV9aRVJPX0VSUk9SOworICAgICAgICBVbmlxdWVVQ29udmVydGVyIGNudih1Y252X29wZW4obmFtZSArIDIsICZlcnJvcikpOworICAgICAgICBpZiAoY252LmdldCgpICE9IE5VTEwpIHsKKyAgICAgICAgICAgIHJldHVybiBuYW1lICsgMjsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIHZvaWQgQ0hBUlNFVF9FTkNPREVSX0NBTExCQUNLKGNvbnN0IHZvaWQqIHJhd0NvbnRleHQsIFVDb252ZXJ0ZXJGcm9tVW5pY29kZUFyZ3MqIGFyZ3MsCisgICAgICAgIGNvbnN0IFVDaGFyKiBjb2RlVW5pdHMsIGludDMyX3QgbGVuZ3RoLCBVQ2hhcjMyIGNvZGVQb2ludCwgVUNvbnZlcnRlckNhbGxiYWNrUmVhc29uIHJlYXNvbiwKKyAgICAgICAgVUVycm9yQ29kZSogc3RhdHVzKSB7CisgICAgaWYgKCFyYXdDb250ZXh0KSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgY29uc3QgRW5jb2RlckNhbGxiYWNrQ29udGV4dCogY3R4ID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBFbmNvZGVyQ2FsbGJhY2tDb250ZXh0Kj4ocmF3Q29udGV4dCk7CisgICAgc3dpdGNoKHJlYXNvbikgeworICAgIGNhc2UgVUNOVl9VTkFTU0lHTkVEOgorICAgICAgICBjdHgtPm9uVW5tYXBwYWJsZUlucHV0KGN0eCwgYXJncywgY29kZVVuaXRzLCBsZW5ndGgsIGNvZGVQb2ludCwgcmVhc29uLCBzdGF0dXMpOworICAgICAgICByZXR1cm47CisgICAgY2FzZSBVQ05WX0lMTEVHQUw6CisgICAgY2FzZSBVQ05WX0lSUkVHVUxBUjoKKyAgICAgICAgY3R4LT5vbk1hbGZvcm1lZElucHV0KGN0eCwgYXJncywgY29kZVVuaXRzLCBsZW5ndGgsIGNvZGVQb2ludCwgcmVhc29uLCBzdGF0dXMpOworICAgICAgICByZXR1cm47CisgICAgY2FzZSBVQ05WX0NMT1NFOgorICAgICAgICBkZWxldGUgY3R4OworICAgICAgICByZXR1cm47CisgICAgZGVmYXVsdDoKKyAgICAgICAgKnN0YXR1cyA9IFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUjsKKyAgICAgICAgcmV0dXJuOworICAgIH0KK30KKworc3RhdGljIHZvaWQgZW5jb2RlclJlcGxhY2VDYWxsYmFjayhjb25zdCB2b2lkKiByYXdDb250ZXh0LAorICAgICAgICBVQ29udmVydGVyRnJvbVVuaWNvZGVBcmdzKiBmcm9tQXJncywgY29uc3QgVUNoYXIqLCBpbnQzMl90LCBVQ2hhcjMyLAorICAgICAgICBVQ29udmVydGVyQ2FsbGJhY2tSZWFzb24sIFVFcnJvckNvZGUgKiBlcnIpIHsKKyAgICBpZiAocmF3Q29udGV4dCA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgY29uc3QgRW5jb2RlckNhbGxiYWNrQ29udGV4dCogY29udGV4dCA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgRW5jb2RlckNhbGxiYWNrQ29udGV4dCo+KHJhd0NvbnRleHQpOworICAgICplcnIgPSBVX1pFUk9fRVJST1I7CisgICAgdWNudl9jYkZyb21VV3JpdGVCeXRlcyhmcm9tQXJncywgY29udGV4dC0+cmVwbGFjZW1lbnRCeXRlcywgY29udGV4dC0+cmVwbGFjZW1lbnRCeXRlQ291bnQsIDAsIGVycik7Cit9CisKK3N0YXRpYyBVQ29udmVydGVyRnJvbVVDYWxsYmFjayBnZXRGcm9tVUNhbGxiYWNrKGludDMyX3QgbW9kZSkgeworICAgIHN3aXRjaChtb2RlKSB7CisgICAgY2FzZSBOYXRpdmVDb252ZXJ0ZXJfSUdOT1JFOiByZXR1cm4gVUNOVl9GUk9NX1VfQ0FMTEJBQ0tfU0tJUDsKKyAgICBjYXNlIE5hdGl2ZUNvbnZlcnRlcl9SRVBMQUNFOiByZXR1cm4gZW5jb2RlclJlcGxhY2VDYWxsYmFjazsKKyAgICBjYXNlIE5hdGl2ZUNvbnZlcnRlcl9SRVBPUlQ6IHJldHVybiBVQ05WX0ZST01fVV9DQUxMQkFDS19TVE9QOworICAgIH0KKyAgICBhYm9ydCgpOworfQorCitzdGF0aWMgamludCBOYXRpdmVDb252ZXJ0ZXJfc2V0Q2FsbGJhY2tFbmNvZGUoSk5JRW52KiBlbnYsIGpjbGFzcywgamxvbmcgYWRkcmVzcywKKyAgICAgICAgamludCBvbk1hbGZvcm1lZElucHV0LCBqaW50IG9uVW5tYXBwYWJsZUlucHV0LCBqYnl0ZUFycmF5IGphdmFSZXBsYWNlbWVudCkgeworICAgIFVDb252ZXJ0ZXIqIGNudiA9IHRvVUNvbnZlcnRlcihhZGRyZXNzKTsKKyAgICBpZiAoIWNudikgeworICAgICAgICByZXR1cm4gVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SOworICAgIH0KKworICAgIFVDb252ZXJ0ZXJGcm9tVUNhbGxiYWNrIG9sZENhbGxiYWNrID0gTlVMTDsKKyAgICBjb25zdCB2b2lkKiBvbGRDYWxsYmFja0NvbnRleHQgPSBOVUxMOworICAgIHVjbnZfZ2V0RnJvbVVDYWxsQmFjayhjbnYsICZvbGRDYWxsYmFjaywgY29uc3RfY2FzdDxjb25zdCB2b2lkKio+KCZvbGRDYWxsYmFja0NvbnRleHQpKTsKKworICAgIEVuY29kZXJDYWxsYmFja0NvbnRleHQqIGNhbGxiYWNrQ29udGV4dCA9IGNvbnN0X2Nhc3Q8RW5jb2RlckNhbGxiYWNrQ29udGV4dCo+KAorICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBFbmNvZGVyQ2FsbGJhY2tDb250ZXh0Kj4ob2xkQ2FsbGJhY2tDb250ZXh0KSk7CisgICAgaWYgKGNhbGxiYWNrQ29udGV4dCA9PSBOVUxMKSB7CisgICAgICAgIGNhbGxiYWNrQ29udGV4dCA9IG5ldyBFbmNvZGVyQ2FsbGJhY2tDb250ZXh0OworICAgIH0KKworICAgIGNhbGxiYWNrQ29udGV4dC0+b25NYWxmb3JtZWRJbnB1dCA9IGdldEZyb21VQ2FsbGJhY2sob25NYWxmb3JtZWRJbnB1dCk7CisgICAgY2FsbGJhY2tDb250ZXh0LT5vblVubWFwcGFibGVJbnB1dCA9IGdldEZyb21VQ2FsbGJhY2sob25Vbm1hcHBhYmxlSW5wdXQpOworCisgICAgU2NvcGVkQnl0ZUFycmF5Uk8gcmVwbGFjZW1lbnRCeXRlcyhlbnYsIGphdmFSZXBsYWNlbWVudCk7CisgICAgaWYgKHJlcGxhY2VtZW50Qnl0ZXMuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SOworICAgIH0KKyAgICBtZW1jcHkoY2FsbGJhY2tDb250ZXh0LT5yZXBsYWNlbWVudEJ5dGVzLCByZXBsYWNlbWVudEJ5dGVzLmdldCgpLCByZXBsYWNlbWVudEJ5dGVzLnNpemUoKSk7CisgICAgY2FsbGJhY2tDb250ZXh0LT5yZXBsYWNlbWVudEJ5dGVDb3VudCA9IHJlcGxhY2VtZW50Qnl0ZXMuc2l6ZSgpOworCisgICAgVUVycm9yQ29kZSBlcnJvckNvZGUgPSBVX1pFUk9fRVJST1I7CisgICAgdWNudl9zZXRGcm9tVUNhbGxCYWNrKGNudiwgQ0hBUlNFVF9FTkNPREVSX0NBTExCQUNLLCBjYWxsYmFja0NvbnRleHQsIE5VTEwsIE5VTEwsICZlcnJvckNvZGUpOworICAgIHJldHVybiBlcnJvckNvZGU7Cit9CisKK3N0YXRpYyB2b2lkIGRlY29kZXJJZ25vcmVDYWxsYmFjayhjb25zdCB2b2lkKiwgVUNvbnZlcnRlclRvVW5pY29kZUFyZ3MqLCBjb25zdCBjaGFyKiwgaW50MzJfdCwgVUNvbnZlcnRlckNhbGxiYWNrUmVhc29uLCBVRXJyb3JDb2RlKiBlcnIpIHsKKyAgICAvLyBUaGUgaWN1NGMgVUNOVl9GUk9NX1VfQ0FMTEJBQ0tfU0tJUCBjYWxsYmFjayByZXF1aXJlcyB0aGF0IHRoZSBjb250ZXh0IGlzIE5VTEwsIHdoaWNoIGlzCisgICAgLy8gbmV2ZXIgdHJ1ZSBmb3IgdXMuCisgICAgKmVyciA9IFVfWkVST19FUlJPUjsKK30KKworc3RhdGljIHZvaWQgZGVjb2RlclJlcGxhY2VDYWxsYmFjayhjb25zdCB2b2lkKiByYXdDb250ZXh0LAorICAgICAgICBVQ29udmVydGVyVG9Vbmljb2RlQXJncyogdG9BcmdzLCBjb25zdCBjaGFyKiwgaW50MzJfdCwgVUNvbnZlcnRlckNhbGxiYWNrUmVhc29uLAorICAgICAgICBVRXJyb3JDb2RlKiBlcnIpIHsKKyAgICBpZiAoIXJhd0NvbnRleHQpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBjb25zdCBEZWNvZGVyQ2FsbGJhY2tDb250ZXh0KiBjb250ZXh0ID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBEZWNvZGVyQ2FsbGJhY2tDb250ZXh0Kj4ocmF3Q29udGV4dCk7CisgICAgKmVyciA9IFVfWkVST19FUlJPUjsKKyAgICB1Y252X2NiVG9VV3JpdGVVQ2hhcnModG9BcmdzLGNvbnRleHQtPnJlcGxhY2VtZW50Q2hhcnMsIGNvbnRleHQtPnJlcGxhY2VtZW50Q2hhckNvdW50LCAwLCBlcnIpOworfQorCitzdGF0aWMgVUNvbnZlcnRlclRvVUNhbGxiYWNrIGdldFRvVUNhbGxiYWNrKGludDMyX3QgbW9kZSkgeworICAgIHN3aXRjaCAobW9kZSkgeworICAgIGNhc2UgTmF0aXZlQ29udmVydGVyX0lHTk9SRTogcmV0dXJuIGRlY29kZXJJZ25vcmVDYWxsYmFjazsKKyAgICBjYXNlIE5hdGl2ZUNvbnZlcnRlcl9SRVBMQUNFOiByZXR1cm4gZGVjb2RlclJlcGxhY2VDYWxsYmFjazsKKyAgICBjYXNlIE5hdGl2ZUNvbnZlcnRlcl9SRVBPUlQ6IHJldHVybiBVQ05WX1RPX1VfQ0FMTEJBQ0tfU1RPUDsKKyAgICB9CisgICAgYWJvcnQoKTsKK30KKworc3RhdGljIHZvaWQgQ0hBUlNFVF9ERUNPREVSX0NBTExCQUNLKGNvbnN0IHZvaWQqIHJhd0NvbnRleHQsIFVDb252ZXJ0ZXJUb1VuaWNvZGVBcmdzKiBhcmdzLAorICAgICAgICBjb25zdCBjaGFyKiBjb2RlVW5pdHMsIGludDMyX3QgbGVuZ3RoLAorICAgICAgICBVQ29udmVydGVyQ2FsbGJhY2tSZWFzb24gcmVhc29uLCBVRXJyb3JDb2RlKiBzdGF0dXMpIHsKKyAgICBpZiAoIXJhd0NvbnRleHQpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBjb25zdCBEZWNvZGVyQ2FsbGJhY2tDb250ZXh0KiBjdHggPSByZWludGVycHJldF9jYXN0PGNvbnN0IERlY29kZXJDYWxsYmFja0NvbnRleHQqPihyYXdDb250ZXh0KTsKKyAgICBzd2l0Y2gocmVhc29uKSB7CisgICAgY2FzZSBVQ05WX1VOQVNTSUdORUQ6CisgICAgICAgIGN0eC0+b25Vbm1hcHBhYmxlSW5wdXQoY3R4LCBhcmdzLCBjb2RlVW5pdHMsIGxlbmd0aCwgcmVhc29uLCBzdGF0dXMpOworICAgICAgICByZXR1cm47CisgICAgY2FzZSBVQ05WX0lMTEVHQUw6CisgICAgY2FzZSBVQ05WX0lSUkVHVUxBUjoKKyAgICAgICAgY3R4LT5vbk1hbGZvcm1lZElucHV0KGN0eCwgYXJncywgY29kZVVuaXRzLCBsZW5ndGgsIHJlYXNvbiwgc3RhdHVzKTsKKyAgICAgICAgcmV0dXJuOworICAgIGNhc2UgVUNOVl9DTE9TRToKKyAgICAgICAgZGVsZXRlIGN0eDsKKyAgICAgICAgcmV0dXJuOworICAgIGRlZmF1bHQ6CisgICAgICAgICpzdGF0dXMgPSBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1I7CisgICAgICAgIHJldHVybjsKKyAgICB9Cit9CisKK3N0YXRpYyBqaW50IE5hdGl2ZUNvbnZlcnRlcl9zZXRDYWxsYmFja0RlY29kZShKTklFbnYqIGVudiwgamNsYXNzLCBqbG9uZyBhZGRyZXNzLAorICAgICAgICBqaW50IG9uTWFsZm9ybWVkSW5wdXQsIGppbnQgb25Vbm1hcHBhYmxlSW5wdXQsIGpzdHJpbmcgamF2YVJlcGxhY2VtZW50KSB7CisgICAgVUNvbnZlcnRlciogY252ID0gdG9VQ29udmVydGVyKGFkZHJlc3MpOworICAgIGlmIChjbnYgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SOworICAgIH0KKworICAgIFVDb252ZXJ0ZXJUb1VDYWxsYmFjayBvbGRDYWxsYmFjazsKKyAgICBjb25zdCB2b2lkKiBvbGRDYWxsYmFja0NvbnRleHQ7CisgICAgdWNudl9nZXRUb1VDYWxsQmFjayhjbnYsICZvbGRDYWxsYmFjaywgJm9sZENhbGxiYWNrQ29udGV4dCk7CisKKyAgICBEZWNvZGVyQ2FsbGJhY2tDb250ZXh0KiBjYWxsYmFja0NvbnRleHQgPSBjb25zdF9jYXN0PERlY29kZXJDYWxsYmFja0NvbnRleHQqPigKKyAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgRGVjb2RlckNhbGxiYWNrQ29udGV4dCo+KG9sZENhbGxiYWNrQ29udGV4dCkpOworICAgIGlmIChjYWxsYmFja0NvbnRleHQgPT0gTlVMTCkgeworICAgICAgICBjYWxsYmFja0NvbnRleHQgPSBuZXcgRGVjb2RlckNhbGxiYWNrQ29udGV4dDsKKyAgICB9CisKKyAgICBjYWxsYmFja0NvbnRleHQtPm9uTWFsZm9ybWVkSW5wdXQgPSBnZXRUb1VDYWxsYmFjayhvbk1hbGZvcm1lZElucHV0KTsKKyAgICBjYWxsYmFja0NvbnRleHQtPm9uVW5tYXBwYWJsZUlucHV0ID0gZ2V0VG9VQ2FsbGJhY2sob25Vbm1hcHBhYmxlSW5wdXQpOworCisgICAgU2NvcGVkU3RyaW5nQ2hhcnMgcmVwbGFjZW1lbnQoZW52LCBqYXZhUmVwbGFjZW1lbnQpOworICAgIGlmIChyZXBsYWNlbWVudC5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1I7CisgICAgfQorICAgIHVfc3RybmNweShjYWxsYmFja0NvbnRleHQtPnJlcGxhY2VtZW50Q2hhcnMsIHJlcGxhY2VtZW50LmdldCgpLCByZXBsYWNlbWVudC5zaXplKCkpOworICAgIGNhbGxiYWNrQ29udGV4dC0+cmVwbGFjZW1lbnRDaGFyQ291bnQgPSByZXBsYWNlbWVudC5zaXplKCk7CisKKyAgICBVRXJyb3JDb2RlIGVycm9yQ29kZSA9IFVfWkVST19FUlJPUjsKKyAgICB1Y252X3NldFRvVUNhbGxCYWNrKGNudiwgQ0hBUlNFVF9ERUNPREVSX0NBTExCQUNLLCBjYWxsYmFja0NvbnRleHQsIE5VTEwsIE5VTEwsICZlcnJvckNvZGUpOworICAgIHJldHVybiBlcnJvckNvZGU7Cit9CisKK3N0YXRpYyBqZmxvYXQgTmF0aXZlQ29udmVydGVyX2dldEF2ZUNoYXJzUGVyQnl0ZShKTklFbnYqIGVudiwgamNsYXNzLCBqbG9uZyBoYW5kbGUpIHsKKyAgICByZXR1cm4gKDEgLyAoamZsb2F0KSBOYXRpdmVDb252ZXJ0ZXJfZ2V0TWF4Qnl0ZXNQZXJDaGFyKGVudiwgTlVMTCwgaGFuZGxlKSk7Cit9CisKK3N0YXRpYyBqYnl0ZUFycmF5IE5hdGl2ZUNvbnZlcnRlcl9nZXRTdWJzdGl0dXRpb25CeXRlcyhKTklFbnYqIGVudiwgamNsYXNzLCBqbG9uZyBhZGRyZXNzKSB7CisgICAgVUNvbnZlcnRlciogY252ID0gdG9VQ29udmVydGVyKGFkZHJlc3MpOworICAgIGlmIChjbnYgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgY2hhciByZXBsYWNlbWVudEJ5dGVzW01BWF9SRVBMQUNFTUVOVF9MRU5HVEhdOworICAgIGludDhfdCBsZW4gPSBzaXplb2YocmVwbGFjZW1lbnRCeXRlcyk7CisgICAgdWNudl9nZXRTdWJzdENoYXJzKGNudiwgcmVwbGFjZW1lbnRCeXRlcywgJmxlbiwgJnN0YXR1cyk7CisgICAgaWYgKCFVX1NVQ0NFU1Moc3RhdHVzKSkgeworICAgICAgICByZXR1cm4gZW52LT5OZXdCeXRlQXJyYXkoMCk7CisgICAgfQorICAgIGpieXRlQXJyYXkgcmVzdWx0ID0gZW52LT5OZXdCeXRlQXJyYXkobGVuKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGVudi0+U2V0Qnl0ZUFycmF5UmVnaW9uKHJlc3VsdCwgMCwgbGVuLCByZWludGVycHJldF9jYXN0PGpieXRlKj4ocmVwbGFjZW1lbnRCeXRlcykpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBqYm9vbGVhbiBOYXRpdmVDb252ZXJ0ZXJfY29udGFpbnMoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBuYW1lMSwganN0cmluZyBuYW1lMikgeworICAgIFNjb3BlZFV0ZkNoYXJzIG5hbWUxQ2hhcnMoZW52LCBuYW1lMSk7CisgICAgaWYgKG5hbWUxQ2hhcnMuY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBKTklfRkFMU0U7CisgICAgfQorICAgIFNjb3BlZFV0ZkNoYXJzIG5hbWUyQ2hhcnMoZW52LCBuYW1lMik7CisgICAgaWYgKG5hbWUyQ2hhcnMuY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBKTklfRkFMU0U7CisgICAgfQorCisgICAgVUVycm9yQ29kZSBlcnJvckNvZGUgPSBVX1pFUk9fRVJST1I7CisgICAgVW5pcXVlVUNvbnZlcnRlciBjb252ZXJ0ZXIxKHVjbnZfb3BlbihuYW1lMUNoYXJzLmNfc3RyKCksICZlcnJvckNvZGUpKTsKKyAgICBVbmljb2RlU2V0IHNldDE7CisgICAgdWNudl9nZXRVbmljb2RlU2V0KGNvbnZlcnRlcjEuZ2V0KCksIHNldDEudG9VU2V0KCksIFVDTlZfUk9VTkRUUklQX1NFVCwgJmVycm9yQ29kZSk7CisKKyAgICBVbmlxdWVVQ29udmVydGVyIGNvbnZlcnRlcjIodWNudl9vcGVuKG5hbWUyQ2hhcnMuY19zdHIoKSwgJmVycm9yQ29kZSkpOworICAgIFVuaWNvZGVTZXQgc2V0MjsKKyAgICB1Y252X2dldFVuaWNvZGVTZXQoY29udmVydGVyMi5nZXQoKSwgc2V0Mi50b1VTZXQoKSwgVUNOVl9ST1VORFRSSVBfU0VULCAmZXJyb3JDb2RlKTsKKworICAgIHJldHVybiBVX1NVQ0NFU1MoZXJyb3JDb2RlKSAmJiBzZXQxLmNvbnRhaW5zQWxsKHNldDIpOworfQorCitzdGF0aWMgam9iamVjdCBOYXRpdmVDb252ZXJ0ZXJfY2hhcnNldEZvck5hbWUoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBjaGFyc2V0TmFtZSkgeworICAgIFNjb3BlZFV0ZkNoYXJzIGNoYXJzZXROYW1lQ2hhcnMoZW52LCBjaGFyc2V0TmFtZSk7CisgICAgaWYgKGNoYXJzZXROYW1lQ2hhcnMuY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICAvLyBHZXQgSUNVJ3MgY2Fub25pY2FsIG5hbWUgZm9yIHRoaXMgY2hhcnNldC4KKyAgICBjb25zdCBjaGFyKiBpY3VDYW5vbmljYWxOYW1lID0gZ2V0SUNVQ2Fub25pY2FsTmFtZShjaGFyc2V0TmFtZUNoYXJzLmNfc3RyKCkpOworICAgIGlmIChpY3VDYW5vbmljYWxOYW1lID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIC8vIEdldCBKYXZhJ3MgY2Fub25pY2FsIG5hbWUgZm9yIHRoaXMgY2hhcnNldC4KKyAgICBqc3RyaW5nIGphdmFDYW5vbmljYWxOYW1lID0gZ2V0SmF2YUNhbm9uaWNhbE5hbWUoZW52LCBpY3VDYW5vbmljYWxOYW1lKTsKKyAgICBpZiAoZW52LT5FeGNlcHRpb25PY2N1cnJlZCgpKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8vIENoZWNrIHRoYXQgdGhpcyBjaGFyc2V0IGlzIHN1cHBvcnRlZC4KKyAgICAvLyBJQ1UgZG9lc24ndCBvZmZlciBhbnkgImlzU3VwcG9ydGVkIiwgc28gd2UganVzdCBvcGVuIGFuZCBpbW1lZGlhdGVseSBjbG9zZS4KKyAgICAvLyBXZSBpZ25vcmUgdGhlIFVFcnJvckNvZGUgYmVjYXVzZSB1Y252X29wZW4gcmV0dXJuaW5nIE5VTEwgaXMgYWxsIHRoZSBpbmZvcm1hdGlvbiB3ZSBuZWVkLgorICAgIFVFcnJvckNvZGUgZHVtbXkgPSBVX1pFUk9fRVJST1I7CisgICAgVW5pcXVlVUNvbnZlcnRlciBjbnYodWNudl9vcGVuKGljdUNhbm9uaWNhbE5hbWUsICZkdW1teSkpOworICAgIGlmIChjbnYuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgY252LnJlc2V0KCk7CisKKyAgICAvLyBHZXQgdGhlIGFsaWFzZXMgZm9yIHRoaXMgY2hhcnNldC4KKyAgICBqb2JqZWN0QXJyYXkgYWxpYXNlcyA9IGdldEFsaWFzZXMoZW52LCBpY3VDYW5vbmljYWxOYW1lKTsKKyAgICBpZiAoZW52LT5FeGNlcHRpb25PY2N1cnJlZCgpKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8vIENvbnN0cnVjdCB0aGUgQ2hhcnNldElDVSBvYmplY3QuCisgICAgam1ldGhvZElEIGNoYXJzZXRDb25zdHJ1Y3RvciA9IGVudi0+R2V0TWV0aG9kSUQoSm5pQ29uc3RhbnRzOjpjaGFyc2V0SUNVQ2xhc3MsICI8aW5pdD4iLAorICAgICAgICAgICAgIihMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9TdHJpbmc7KVYiKTsKKyAgICBpZiAoZW52LT5FeGNlcHRpb25PY2N1cnJlZCgpKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gZW52LT5OZXdPYmplY3QoSm5pQ29uc3RhbnRzOjpjaGFyc2V0SUNVQ2xhc3MsIGNoYXJzZXRDb25zdHJ1Y3RvciwKKyAgICAgICAgICAgIGphdmFDYW5vbmljYWxOYW1lLCBlbnYtPk5ld1N0cmluZ1VURihpY3VDYW5vbmljYWxOYW1lKSwgYWxpYXNlcyk7Cit9CisKK3N0YXRpYyBKTklOYXRpdmVNZXRob2QgZ01ldGhvZHNbXSA9IHsKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNvbnZlcnRlciwgY2FuRW5jb2RlLCAiKEpJKVoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNvbnZlcnRlciwgY2hhcnNldEZvck5hbWUsICIoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL25pby9jaGFyc2V0L0NoYXJzZXQ7IiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDb252ZXJ0ZXIsIGNsb3NlQ29udmVydGVyLCAiKEopViIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ29udmVydGVyLCBjb250YWlucywgIihMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZzspWiIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ29udmVydGVyLCBkZWNvZGUsICIoSltCSVtDSVtJWilJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDb252ZXJ0ZXIsIGVuY29kZSwgIihKW0NJW0JJW0laKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNvbnZlcnRlciwgZ2V0QXZhaWxhYmxlQ2hhcnNldE5hbWVzLCAiKClbTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDb252ZXJ0ZXIsIGdldEF2ZUJ5dGVzUGVyQ2hhciwgIihKKUYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNvbnZlcnRlciwgZ2V0QXZlQ2hhcnNQZXJCeXRlLCAiKEopRiIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ29udmVydGVyLCBnZXRNYXhCeXRlc1BlckNoYXIsICIoSilJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDb252ZXJ0ZXIsIGdldE1pbkJ5dGVzUGVyQ2hhciwgIihKKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNvbnZlcnRlciwgZ2V0U3Vic3RpdHV0aW9uQnl0ZXMsICIoSilbQiIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ29udmVydGVyLCBvcGVuQ29udmVydGVyLCAiKExqYXZhL2xhbmcvU3RyaW5nOylKIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDb252ZXJ0ZXIsIHJlc2V0Qnl0ZVRvQ2hhciwgIihKKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNvbnZlcnRlciwgcmVzZXRDaGFyVG9CeXRlLCAiKEopViIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ29udmVydGVyLCBzZXRDYWxsYmFja0RlY29kZSwgIihKSUlMamF2YS9sYW5nL1N0cmluZzspSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ29udmVydGVyLCBzZXRDYWxsYmFja0VuY29kZSwgIihKSUlbQilJIiksCit9OworaW50IHJlZ2lzdGVyX2xpYmNvcmVfaWN1X05hdGl2ZUNvbnZlcnRlcihKTklFbnYqIGVudikgeworICAgIHJldHVybiBqbmlSZWdpc3Rlck5hdGl2ZU1ldGhvZHMoZW52LCAibGliY29yZS9pY3UvTmF0aXZlQ29udmVydGVyIiwgZ01ldGhvZHMsIE5FTEVNKGdNZXRob2RzKSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS9saWJjb3JlX2ljdV9OYXRpdmVEZWNpbWFsRm9ybWF0LmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2xpYmNvcmVfaWN1X05hdGl2ZURlY2ltYWxGb3JtYXQuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2OGM4MjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9saWJjb3JlX2ljdV9OYXRpdmVEZWNpbWFsRm9ybWF0LmNwcApAQCAtMCwwICsxLDM3MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNiBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiTmF0aXZlRGVjaW1hbEZvcm1hdCIKKworI2luY2x1ZGUgIkpOSUhlbHAuaCIKKyNpbmNsdWRlICJKbmlDb25zdGFudHMuaCIKKyNpbmNsdWRlICJKbmlFeGNlcHRpb24uaCIKKyNpbmNsdWRlICJTY29wZWRKYXZhVW5pY29kZVN0cmluZy5oIgorI2luY2x1ZGUgIlNjb3BlZFByaW1pdGl2ZUFycmF5LmgiCisjaW5jbHVkZSAiU2NvcGVkU3RyaW5nQ2hhcnMuaCIKKyNpbmNsdWRlICJTY29wZWRVdGZDaGFycy5oIgorI2luY2x1ZGUgIlVuaXF1ZVB0ci5oIgorI2luY2x1ZGUgImN1dGlscy9sb2cuaCIKKyNpbmNsdWRlICJkaWdpdGxzdC5oIgorI2luY2x1ZGUgInVuaWNvZGUvZGVjaW1mbXQuaCIKKyNpbmNsdWRlICJ1bmljb2RlL2ZtdGFibGUuaCIKKyNpbmNsdWRlICJ1bmljb2RlL251bWZtdC5oIgorI2luY2x1ZGUgInVuaWNvZGUvdW51bS5oIgorI2luY2x1ZGUgInVuaWNvZGUvdXN0cmluZy5oIgorI2luY2x1ZGUgInZhbHVlT2YuaCIKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworc3RhdGljIERlY2ltYWxGb3JtYXQqIHRvRGVjaW1hbEZvcm1hdChqaW50IGFkZHIpIHsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxEZWNpbWFsRm9ybWF0Kj4oc3RhdGljX2Nhc3Q8dWludHB0cl90PihhZGRyKSk7Cit9CisKK3N0YXRpYyBVTnVtYmVyRm9ybWF0KiB0b1VOdW1iZXJGb3JtYXQoamludCBhZGRyKSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8VU51bWJlckZvcm1hdCo+KHN0YXRpY19jYXN0PHVpbnRwdHJfdD4oYWRkcikpOworfQorCitzdGF0aWMgRGVjaW1hbEZvcm1hdFN5bWJvbHMqIG1ha2VEZWNpbWFsRm9ybWF0U3ltYm9scyhKTklFbnYqIGVudiwKKyAgICAgICAganN0cmluZyBjdXJyZW5jeVN5bWJvbDAsIGpjaGFyIGRlY2ltYWxTZXBhcmF0b3IsIGpjaGFyIGRpZ2l0LCBqc3RyaW5nIGV4cG9uZW50U2VwYXJhdG9yMCwKKyAgICAgICAgamNoYXIgZ3JvdXBpbmdTZXBhcmF0b3IwLCBqc3RyaW5nIGluZmluaXR5MCwKKyAgICAgICAganN0cmluZyBpbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2wwLCBqY2hhciBtaW51c1NpZ24sCisgICAgICAgIGpjaGFyIG1vbmV0YXJ5RGVjaW1hbFNlcGFyYXRvciwganN0cmluZyBuYW4wLCBqY2hhciBwYXR0ZXJuU2VwYXJhdG9yLAorICAgICAgICBqY2hhciBwZXJjZW50LCBqY2hhciBwZXJNaWxsLCBqY2hhciB6ZXJvRGlnaXQpIHsKKyAgICBTY29wZWRKYXZhVW5pY29kZVN0cmluZyBjdXJyZW5jeVN5bWJvbChlbnYsIGN1cnJlbmN5U3ltYm9sMCk7CisgICAgU2NvcGVkSmF2YVVuaWNvZGVTdHJpbmcgZXhwb25lbnRTZXBhcmF0b3IoZW52LCBleHBvbmVudFNlcGFyYXRvcjApOworICAgIFNjb3BlZEphdmFVbmljb2RlU3RyaW5nIGluZmluaXR5KGVudiwgaW5maW5pdHkwKTsKKyAgICBTY29wZWRKYXZhVW5pY29kZVN0cmluZyBpbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2woZW52LCBpbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2wwKTsKKyAgICBTY29wZWRKYXZhVW5pY29kZVN0cmluZyBuYW4oZW52LCBuYW4wKTsKKyAgICBVbmljb2RlU3RyaW5nIGdyb3VwaW5nU2VwYXJhdG9yKGdyb3VwaW5nU2VwYXJhdG9yMCk7CisKKyAgICBEZWNpbWFsRm9ybWF0U3ltYm9scyogcmVzdWx0ID0gbmV3IERlY2ltYWxGb3JtYXRTeW1ib2xzOworICAgIHJlc3VsdC0+c2V0U3ltYm9sKERlY2ltYWxGb3JtYXRTeW1ib2xzOjprQ3VycmVuY3lTeW1ib2wsIGN1cnJlbmN5U3ltYm9sLnVuaWNvZGVTdHJpbmcoKSk7CisgICAgcmVzdWx0LT5zZXRTeW1ib2woRGVjaW1hbEZvcm1hdFN5bWJvbHM6OmtEZWNpbWFsU2VwYXJhdG9yU3ltYm9sLCBVbmljb2RlU3RyaW5nKGRlY2ltYWxTZXBhcmF0b3IpKTsKKyAgICByZXN1bHQtPnNldFN5bWJvbChEZWNpbWFsRm9ybWF0U3ltYm9sczo6a0RpZ2l0U3ltYm9sLCBVbmljb2RlU3RyaW5nKGRpZ2l0KSk7CisgICAgcmVzdWx0LT5zZXRTeW1ib2woRGVjaW1hbEZvcm1hdFN5bWJvbHM6OmtFeHBvbmVudGlhbFN5bWJvbCwgZXhwb25lbnRTZXBhcmF0b3IudW5pY29kZVN0cmluZygpKTsKKyAgICByZXN1bHQtPnNldFN5bWJvbChEZWNpbWFsRm9ybWF0U3ltYm9sczo6a0dyb3VwaW5nU2VwYXJhdG9yU3ltYm9sLCBncm91cGluZ1NlcGFyYXRvcik7CisgICAgcmVzdWx0LT5zZXRTeW1ib2woRGVjaW1hbEZvcm1hdFN5bWJvbHM6OmtNb25ldGFyeUdyb3VwaW5nU2VwYXJhdG9yU3ltYm9sLCBncm91cGluZ1NlcGFyYXRvcik7CisgICAgcmVzdWx0LT5zZXRTeW1ib2woRGVjaW1hbEZvcm1hdFN5bWJvbHM6OmtJbmZpbml0eVN5bWJvbCwgaW5maW5pdHkudW5pY29kZVN0cmluZygpKTsKKyAgICByZXN1bHQtPnNldFN5bWJvbChEZWNpbWFsRm9ybWF0U3ltYm9sczo6a0ludGxDdXJyZW5jeVN5bWJvbCwgaW50ZXJuYXRpb25hbEN1cnJlbmN5U3ltYm9sLnVuaWNvZGVTdHJpbmcoKSk7CisgICAgcmVzdWx0LT5zZXRTeW1ib2woRGVjaW1hbEZvcm1hdFN5bWJvbHM6OmtNaW51c1NpZ25TeW1ib2wsIFVuaWNvZGVTdHJpbmcobWludXNTaWduKSk7CisgICAgcmVzdWx0LT5zZXRTeW1ib2woRGVjaW1hbEZvcm1hdFN5bWJvbHM6OmtNb25ldGFyeVNlcGFyYXRvclN5bWJvbCwgVW5pY29kZVN0cmluZyhtb25ldGFyeURlY2ltYWxTZXBhcmF0b3IpKTsKKyAgICByZXN1bHQtPnNldFN5bWJvbChEZWNpbWFsRm9ybWF0U3ltYm9sczo6a05hTlN5bWJvbCwgbmFuLnVuaWNvZGVTdHJpbmcoKSk7CisgICAgcmVzdWx0LT5zZXRTeW1ib2woRGVjaW1hbEZvcm1hdFN5bWJvbHM6OmtQYXR0ZXJuU2VwYXJhdG9yU3ltYm9sLCBVbmljb2RlU3RyaW5nKHBhdHRlcm5TZXBhcmF0b3IpKTsKKyAgICByZXN1bHQtPnNldFN5bWJvbChEZWNpbWFsRm9ybWF0U3ltYm9sczo6a1BlcmNlbnRTeW1ib2wsIFVuaWNvZGVTdHJpbmcocGVyY2VudCkpOworICAgIHJlc3VsdC0+c2V0U3ltYm9sKERlY2ltYWxGb3JtYXRTeW1ib2xzOjprUGVyTWlsbFN5bWJvbCwgVW5pY29kZVN0cmluZyhwZXJNaWxsKSk7CisgICAgLy8gamF2YS50ZXh0LkRlY2ltYWxGb3JtYXRTeW1ib2xzIGp1c3QgdXNlcyBhIHplcm8gZGlnaXQsCisgICAgLy8gYnV0IElDVSA+PSA0LjYgaGFzIGEgZmllbGQgZm9yIGVhY2ggZGVjaW1hbCBkaWdpdC4KKyAgICByZXN1bHQtPnNldFN5bWJvbChEZWNpbWFsRm9ybWF0U3ltYm9sczo6a1plcm9EaWdpdFN5bWJvbCwgVW5pY29kZVN0cmluZyh6ZXJvRGlnaXQgKyAwKSk7CisgICAgcmVzdWx0LT5zZXRTeW1ib2woRGVjaW1hbEZvcm1hdFN5bWJvbHM6OmtPbmVEaWdpdFN5bWJvbCwgVW5pY29kZVN0cmluZyh6ZXJvRGlnaXQgKyAxKSk7CisgICAgcmVzdWx0LT5zZXRTeW1ib2woRGVjaW1hbEZvcm1hdFN5bWJvbHM6OmtUd29EaWdpdFN5bWJvbCwgVW5pY29kZVN0cmluZyh6ZXJvRGlnaXQgKyAyKSk7CisgICAgcmVzdWx0LT5zZXRTeW1ib2woRGVjaW1hbEZvcm1hdFN5bWJvbHM6OmtUaHJlZURpZ2l0U3ltYm9sLCBVbmljb2RlU3RyaW5nKHplcm9EaWdpdCArIDMpKTsKKyAgICByZXN1bHQtPnNldFN5bWJvbChEZWNpbWFsRm9ybWF0U3ltYm9sczo6a0ZvdXJEaWdpdFN5bWJvbCwgVW5pY29kZVN0cmluZyh6ZXJvRGlnaXQgKyA0KSk7CisgICAgcmVzdWx0LT5zZXRTeW1ib2woRGVjaW1hbEZvcm1hdFN5bWJvbHM6OmtGaXZlRGlnaXRTeW1ib2wsIFVuaWNvZGVTdHJpbmcoemVyb0RpZ2l0ICsgNSkpOworICAgIHJlc3VsdC0+c2V0U3ltYm9sKERlY2ltYWxGb3JtYXRTeW1ib2xzOjprU2l4RGlnaXRTeW1ib2wsIFVuaWNvZGVTdHJpbmcoemVyb0RpZ2l0ICsgNikpOworICAgIHJlc3VsdC0+c2V0U3ltYm9sKERlY2ltYWxGb3JtYXRTeW1ib2xzOjprU2V2ZW5EaWdpdFN5bWJvbCwgVW5pY29kZVN0cmluZyh6ZXJvRGlnaXQgKyA3KSk7CisgICAgcmVzdWx0LT5zZXRTeW1ib2woRGVjaW1hbEZvcm1hdFN5bWJvbHM6OmtFaWdodERpZ2l0U3ltYm9sLCBVbmljb2RlU3RyaW5nKHplcm9EaWdpdCArIDgpKTsKKyAgICByZXN1bHQtPnNldFN5bWJvbChEZWNpbWFsRm9ybWF0U3ltYm9sczo6a05pbmVEaWdpdFN5bWJvbCwgVW5pY29kZVN0cmluZyh6ZXJvRGlnaXQgKyA5KSk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIHZvaWQgTmF0aXZlRGVjaW1hbEZvcm1hdF9zZXREZWNpbWFsRm9ybWF0U3ltYm9scyhKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHIsCisgICAgICAgIGpzdHJpbmcgY3VycmVuY3lTeW1ib2wsIGpjaGFyIGRlY2ltYWxTZXBhcmF0b3IsIGpjaGFyIGRpZ2l0LCBqc3RyaW5nIGV4cG9uZW50U2VwYXJhdG9yLAorICAgICAgICBqY2hhciBncm91cGluZ1NlcGFyYXRvciwganN0cmluZyBpbmZpbml0eSwKKyAgICAgICAganN0cmluZyBpbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2wsIGpjaGFyIG1pbnVzU2lnbiwKKyAgICAgICAgamNoYXIgbW9uZXRhcnlEZWNpbWFsU2VwYXJhdG9yLCBqc3RyaW5nIG5hbiwgamNoYXIgcGF0dGVyblNlcGFyYXRvciwKKyAgICAgICAgamNoYXIgcGVyY2VudCwgamNoYXIgcGVyTWlsbCwgamNoYXIgemVyb0RpZ2l0KSB7CisgICAgRGVjaW1hbEZvcm1hdFN5bWJvbHMqIHN5bWJvbHMgPSBtYWtlRGVjaW1hbEZvcm1hdFN5bWJvbHMoZW52LAorICAgICAgICAgICAgY3VycmVuY3lTeW1ib2wsIGRlY2ltYWxTZXBhcmF0b3IsIGRpZ2l0LCBleHBvbmVudFNlcGFyYXRvciwgZ3JvdXBpbmdTZXBhcmF0b3IsCisgICAgICAgICAgICBpbmZpbml0eSwgaW50ZXJuYXRpb25hbEN1cnJlbmN5U3ltYm9sLCBtaW51c1NpZ24sCisgICAgICAgICAgICBtb25ldGFyeURlY2ltYWxTZXBhcmF0b3IsIG5hbiwgcGF0dGVyblNlcGFyYXRvciwgcGVyY2VudCwgcGVyTWlsbCwKKyAgICAgICAgICAgIHplcm9EaWdpdCk7CisgICAgdG9EZWNpbWFsRm9ybWF0KGFkZHIpLT5hZG9wdERlY2ltYWxGb3JtYXRTeW1ib2xzKHN5bWJvbHMpOworfQorCitzdGF0aWMgamludCBOYXRpdmVEZWNpbWFsRm9ybWF0X29wZW4oSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBwYXR0ZXJuMCwKKyAgICAgICAganN0cmluZyBjdXJyZW5jeVN5bWJvbCwgamNoYXIgZGVjaW1hbFNlcGFyYXRvciwgamNoYXIgZGlnaXQsIGpzdHJpbmcgZXhwb25lbnRTZXBhcmF0b3IsCisgICAgICAgIGpjaGFyIGdyb3VwaW5nU2VwYXJhdG9yLCBqc3RyaW5nIGluZmluaXR5LAorICAgICAgICBqc3RyaW5nIGludGVybmF0aW9uYWxDdXJyZW5jeVN5bWJvbCwgamNoYXIgbWludXNTaWduLAorICAgICAgICBqY2hhciBtb25ldGFyeURlY2ltYWxTZXBhcmF0b3IsIGpzdHJpbmcgbmFuLCBqY2hhciBwYXR0ZXJuU2VwYXJhdG9yLAorICAgICAgICBqY2hhciBwZXJjZW50LCBqY2hhciBwZXJNaWxsLCBqY2hhciB6ZXJvRGlnaXQpIHsKKyAgICBpZiAocGF0dGVybjAgPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd051bGxQb2ludGVyRXhjZXB0aW9uKGVudiwgTlVMTCk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBVUGFyc2VFcnJvciBwYXJzZUVycm9yOworICAgIFNjb3BlZEphdmFVbmljb2RlU3RyaW5nIHBhdHRlcm4oZW52LCBwYXR0ZXJuMCk7CisgICAgRGVjaW1hbEZvcm1hdFN5bWJvbHMqIHN5bWJvbHMgPSBtYWtlRGVjaW1hbEZvcm1hdFN5bWJvbHMoZW52LAorICAgICAgICAgICAgY3VycmVuY3lTeW1ib2wsIGRlY2ltYWxTZXBhcmF0b3IsIGRpZ2l0LCBleHBvbmVudFNlcGFyYXRvciwgZ3JvdXBpbmdTZXBhcmF0b3IsCisgICAgICAgICAgICBpbmZpbml0eSwgaW50ZXJuYXRpb25hbEN1cnJlbmN5U3ltYm9sLCBtaW51c1NpZ24sCisgICAgICAgICAgICBtb25ldGFyeURlY2ltYWxTZXBhcmF0b3IsIG5hbiwgcGF0dGVyblNlcGFyYXRvciwgcGVyY2VudCwgcGVyTWlsbCwKKyAgICAgICAgICAgIHplcm9EaWdpdCk7CisgICAgRGVjaW1hbEZvcm1hdCogZm10ID0gbmV3IERlY2ltYWxGb3JtYXQocGF0dGVybi51bmljb2RlU3RyaW5nKCksIHN5bWJvbHMsIHBhcnNlRXJyb3IsIHN0YXR1cyk7CisgICAgaWYgKGZtdCA9PSBOVUxMKSB7CisgICAgICAgIGRlbGV0ZSBzeW1ib2xzOworICAgIH0KKyAgICBtYXliZVRocm93SWN1RXhjZXB0aW9uKGVudiwgc3RhdHVzKTsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8amludD4ocmVpbnRlcnByZXRfY2FzdDx1aW50cHRyX3Q+KGZtdCkpOworfQorCitzdGF0aWMgdm9pZCBOYXRpdmVEZWNpbWFsRm9ybWF0X2Nsb3NlKEpOSUVudiosIGpjbGFzcywgamludCBhZGRyKSB7CisgICAgZGVsZXRlIHRvRGVjaW1hbEZvcm1hdChhZGRyKTsKK30KKworc3RhdGljIHZvaWQgTmF0aXZlRGVjaW1hbEZvcm1hdF9zZXRSb3VuZGluZ01vZGUoSk5JRW52KiwgamNsYXNzLCBqaW50IGFkZHIsIGppbnQgbW9kZSwgamRvdWJsZSBpbmNyZW1lbnQpIHsKKyAgICBEZWNpbWFsRm9ybWF0KiBmbXQgPSB0b0RlY2ltYWxGb3JtYXQoYWRkcik7CisgICAgZm10LT5zZXRSb3VuZGluZ01vZGUoc3RhdGljX2Nhc3Q8RGVjaW1hbEZvcm1hdDo6RVJvdW5kaW5nTW9kZT4obW9kZSkpOworICAgIGZtdC0+c2V0Um91bmRpbmdJbmNyZW1lbnQoaW5jcmVtZW50KTsKK30KKworc3RhdGljIHZvaWQgTmF0aXZlRGVjaW1hbEZvcm1hdF9zZXRTeW1ib2woSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBhZGRyLCBqaW50IGphdmFTeW1ib2wsIGpzdHJpbmcgamF2YVZhbHVlKSB7CisgICAgU2NvcGVkU3RyaW5nQ2hhcnMgdmFsdWUoZW52LCBqYXZhVmFsdWUpOworICAgIGlmICh2YWx1ZS5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgVU51bWJlckZvcm1hdFN5bWJvbCBzeW1ib2wgPSBzdGF0aWNfY2FzdDxVTnVtYmVyRm9ybWF0U3ltYm9sPihqYXZhU3ltYm9sKTsKKyAgICB1bnVtX3NldFN5bWJvbCh0b1VOdW1iZXJGb3JtYXQoYWRkciksIHN5bWJvbCwgdmFsdWUuZ2V0KCksIHZhbHVlLnNpemUoKSwgJnN0YXR1cyk7CisgICAgbWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihlbnYsIHN0YXR1cyk7Cit9CisKK3N0YXRpYyB2b2lkIE5hdGl2ZURlY2ltYWxGb3JtYXRfc2V0QXR0cmlidXRlKEpOSUVudiosIGpjbGFzcywgamludCBhZGRyLCBqaW50IGphdmFBdHRyLCBqaW50IHZhbHVlKSB7CisgICAgVU51bWJlckZvcm1hdEF0dHJpYnV0ZSBhdHRyID0gc3RhdGljX2Nhc3Q8VU51bWJlckZvcm1hdEF0dHJpYnV0ZT4oamF2YUF0dHIpOworICAgIHVudW1fc2V0QXR0cmlidXRlKHRvVU51bWJlckZvcm1hdChhZGRyKSwgYXR0ciwgdmFsdWUpOworfQorCitzdGF0aWMgamludCBOYXRpdmVEZWNpbWFsRm9ybWF0X2dldEF0dHJpYnV0ZShKTklFbnYqLCBqY2xhc3MsIGppbnQgYWRkciwgamludCBqYXZhQXR0cikgeworICAgIFVOdW1iZXJGb3JtYXRBdHRyaWJ1dGUgYXR0ciA9IHN0YXRpY19jYXN0PFVOdW1iZXJGb3JtYXRBdHRyaWJ1dGU+KGphdmFBdHRyKTsKKyAgICByZXR1cm4gdW51bV9nZXRBdHRyaWJ1dGUodG9VTnVtYmVyRm9ybWF0KGFkZHIpLCBhdHRyKTsKK30KKworc3RhdGljIHZvaWQgTmF0aXZlRGVjaW1hbEZvcm1hdF9zZXRUZXh0QXR0cmlidXRlKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgYWRkciwgamludCBqYXZhQXR0ciwganN0cmluZyBqYXZhVmFsdWUpIHsKKyAgICBTY29wZWRTdHJpbmdDaGFycyB2YWx1ZShlbnYsIGphdmFWYWx1ZSk7CisgICAgaWYgKHZhbHVlLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBVTnVtYmVyRm9ybWF0VGV4dEF0dHJpYnV0ZSBhdHRyID0gc3RhdGljX2Nhc3Q8VU51bWJlckZvcm1hdFRleHRBdHRyaWJ1dGU+KGphdmFBdHRyKTsKKyAgICB1bnVtX3NldFRleHRBdHRyaWJ1dGUodG9VTnVtYmVyRm9ybWF0KGFkZHIpLCBhdHRyLCB2YWx1ZS5nZXQoKSwgdmFsdWUuc2l6ZSgpLCAmc3RhdHVzKTsKKyAgICBtYXliZVRocm93SWN1RXhjZXB0aW9uKGVudiwgc3RhdHVzKTsKK30KKworc3RhdGljIGpzdHJpbmcgTmF0aXZlRGVjaW1hbEZvcm1hdF9nZXRUZXh0QXR0cmlidXRlKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgYWRkciwgamludCBqYXZhQXR0cikgeworICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworICAgIFVOdW1iZXJGb3JtYXQqIGZtdCA9IHRvVU51bWJlckZvcm1hdChhZGRyKTsKKyAgICBVTnVtYmVyRm9ybWF0VGV4dEF0dHJpYnV0ZSBhdHRyID0gc3RhdGljX2Nhc3Q8VU51bWJlckZvcm1hdFRleHRBdHRyaWJ1dGU+KGphdmFBdHRyKTsKKworICAgIC8vIEZpbmQgb3V0IGhvdyBsb25nIHRoZSByZXN1bHQgd2lsbCBiZS4uLgorICAgIFVuaXF1ZVB0cjxVQ2hhcltdPiBjaGFyczsKKyAgICB1aW50MzJfdCBjaGFyQ291bnQgPSAwOworICAgIHVpbnQzMl90IGRlc2lyZWRDb3VudCA9IHVudW1fZ2V0VGV4dEF0dHJpYnV0ZShmbXQsIGF0dHIsIGNoYXJzLmdldCgpLCBjaGFyQ291bnQsICZzdGF0dXMpOworICAgIGlmIChzdGF0dXMgPT0gVV9CVUZGRVJfT1ZFUkZMT1dfRVJST1IpIHsKKyAgICAgICAgLy8gLi4udGhlbiBnZXQgaXQuCisgICAgICAgIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICAgICAgY2hhckNvdW50ID0gZGVzaXJlZENvdW50ICsgMTsKKyAgICAgICAgY2hhcnMucmVzZXQobmV3IFVDaGFyW2NoYXJDb3VudF0pOworICAgICAgICBjaGFyQ291bnQgPSB1bnVtX2dldFRleHRBdHRyaWJ1dGUoZm10LCBhdHRyLCBjaGFycy5nZXQoKSwgY2hhckNvdW50LCAmc3RhdHVzKTsKKyAgICB9CisgICAgcmV0dXJuIG1heWJlVGhyb3dJY3VFeGNlcHRpb24oZW52LCBzdGF0dXMpID8gTlVMTCA6IGVudi0+TmV3U3RyaW5nKGNoYXJzLmdldCgpLCBjaGFyQ291bnQpOworfQorCitzdGF0aWMgdm9pZCBOYXRpdmVEZWNpbWFsRm9ybWF0X2FwcGx5UGF0dGVybkltcGwoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBhZGRyLCBqYm9vbGVhbiBsb2NhbGl6ZWQsIGpzdHJpbmcgcGF0dGVybjApIHsKKyAgICBpZiAocGF0dGVybjAgPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd051bGxQb2ludGVyRXhjZXB0aW9uKGVudiwgTlVMTCk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgU2NvcGVkSmF2YVVuaWNvZGVTdHJpbmcgcGF0dGVybihlbnYsIHBhdHRlcm4wKTsKKyAgICBEZWNpbWFsRm9ybWF0KiBmbXQgPSB0b0RlY2ltYWxGb3JtYXQoYWRkcik7CisgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CisgICAgaWYgKGxvY2FsaXplZCkgeworICAgICAgICBmbXQtPmFwcGx5TG9jYWxpemVkUGF0dGVybihwYXR0ZXJuLnVuaWNvZGVTdHJpbmcoKSwgc3RhdHVzKTsKKyAgICB9IGVsc2UgeworICAgICAgICBmbXQtPmFwcGx5UGF0dGVybihwYXR0ZXJuLnVuaWNvZGVTdHJpbmcoKSwgc3RhdHVzKTsKKyAgICB9CisgICAgbWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihlbnYsIHN0YXR1cyk7Cit9CisKK3N0YXRpYyBqc3RyaW5nIE5hdGl2ZURlY2ltYWxGb3JtYXRfdG9QYXR0ZXJuSW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHIsIGpib29sZWFuIGxvY2FsaXplZCkgeworICAgIERlY2ltYWxGb3JtYXQqIGZtdCA9IHRvRGVjaW1hbEZvcm1hdChhZGRyKTsKKyAgICBVbmljb2RlU3RyaW5nIHBhdHRlcm47CisgICAgaWYgKGxvY2FsaXplZCkgeworICAgICAgICBmbXQtPnRvTG9jYWxpemVkUGF0dGVybihwYXR0ZXJuKTsKKyAgICB9IGVsc2UgeworICAgICAgICBmbXQtPnRvUGF0dGVybihwYXR0ZXJuKTsKKyAgICB9CisgICAgcmV0dXJuIGVudi0+TmV3U3RyaW5nKHBhdHRlcm4uZ2V0QnVmZmVyKCksIHBhdHRlcm4ubGVuZ3RoKCkpOworfQorCitzdGF0aWMgamNoYXJBcnJheSBmb3JtYXRSZXN1bHQoSk5JRW52KiBlbnYsIGNvbnN0IFVuaWNvZGVTdHJpbmcgJnN0ciwgRmllbGRQb3NpdGlvbkl0ZXJhdG9yKiBmcGksIGpvYmplY3QgZnBJdGVyKSB7CisgICAgc3RhdGljIGptZXRob2RJRCBnRlBJX3NldERhdGEgPSBlbnYtPkdldE1ldGhvZElEKEpuaUNvbnN0YW50czo6ZmllbGRQb3NpdGlvbkl0ZXJhdG9yQ2xhc3MsICJzZXREYXRhIiwgIihbSSlWIik7CisKKyAgICBpZiAoZnBpICE9IE5VTEwpIHsKKyAgICAgICAgaW50IGxlbiA9IGZwaS0+Z2V0RGF0YShOVUxMLCAwKTsKKyAgICAgICAgamludEFycmF5IGRhdGEgPSBOVUxMOworICAgICAgICBpZiAobGVuKSB7CisgICAgICAgICAgICBkYXRhID0gZW52LT5OZXdJbnRBcnJheShsZW4pOworICAgICAgICAgICAgU2NvcGVkSW50QXJyYXlSVyBpbnRzKGVudiwgZGF0YSk7CisgICAgICAgICAgICBpZiAoaW50cy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmcGktPmdldERhdGEoaW50cy5nZXQoKSwgbGVuKTsKKyAgICAgICAgfQorICAgICAgICBlbnYtPkNhbGxWb2lkTWV0aG9kKGZwSXRlciwgZ0ZQSV9zZXREYXRhLCBkYXRhKTsKKyAgICB9CisKKyAgICBqY2hhckFycmF5IHJlc3VsdCA9IGVudi0+TmV3Q2hhckFycmF5KHN0ci5sZW5ndGgoKSk7CisgICAgaWYgKHJlc3VsdCAhPSBOVUxMKSB7CisgICAgICAgIGVudi0+U2V0Q2hhckFycmF5UmVnaW9uKHJlc3VsdCwgMCwgc3RyLmxlbmd0aCgpLCBzdHIuZ2V0QnVmZmVyKCkpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KK3N0YXRpYyBqY2hhckFycmF5IGZvcm1hdChKTklFbnYqIGVudiwgamludCBhZGRyLCBqb2JqZWN0IGZwSXRlciwgVCB2YWwpIHsKKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBVbmljb2RlU3RyaW5nIHN0cjsKKyAgICBEZWNpbWFsRm9ybWF0KiBmbXQgPSB0b0RlY2ltYWxGb3JtYXQoYWRkcik7CisgICAgRmllbGRQb3NpdGlvbkl0ZXJhdG9yIGZwaTsKKyAgICBGaWVsZFBvc2l0aW9uSXRlcmF0b3IqIHBmcGkgPSBmcEl0ZXIgPyAmZnBpIDogTlVMTDsKKyAgICBmbXQtPmZvcm1hdCh2YWwsIHN0ciwgcGZwaSwgc3RhdHVzKTsKKyAgICByZXR1cm4gZm9ybWF0UmVzdWx0KGVudiwgc3RyLCBwZnBpLCBmcEl0ZXIpOworfQorCitzdGF0aWMgamNoYXJBcnJheSBOYXRpdmVEZWNpbWFsRm9ybWF0X2Zvcm1hdExvbmcoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBhZGRyLCBqbG9uZyB2YWx1ZSwgam9iamVjdCBmcEl0ZXIpIHsKKyAgICByZXR1cm4gZm9ybWF0KGVudiwgYWRkciwgZnBJdGVyLCB2YWx1ZSk7Cit9CisKK3N0YXRpYyBqY2hhckFycmF5IE5hdGl2ZURlY2ltYWxGb3JtYXRfZm9ybWF0RG91YmxlKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgYWRkciwgamRvdWJsZSB2YWx1ZSwgam9iamVjdCBmcEl0ZXIpIHsKKyAgICByZXR1cm4gZm9ybWF0KGVudiwgYWRkciwgZnBJdGVyLCB2YWx1ZSk7Cit9CisKK3N0YXRpYyBqY2hhckFycmF5IE5hdGl2ZURlY2ltYWxGb3JtYXRfZm9ybWF0RGlnaXRMaXN0KEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgYWRkciwganN0cmluZyB2YWx1ZSwgam9iamVjdCBmcEl0ZXIpIHsKKyAgICBTY29wZWRVdGZDaGFycyBjaGFycyhlbnYsIHZhbHVlKTsKKyAgICBpZiAoY2hhcnMuY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBTdHJpbmdQaWVjZSBzcChjaGFycy5jX3N0cigpKTsKKyAgICByZXR1cm4gZm9ybWF0KGVudiwgYWRkciwgZnBJdGVyLCBzcCk7Cit9CisKK3N0YXRpYyBqb2JqZWN0IG5ld0JpZ0RlY2ltYWwoSk5JRW52KiBlbnYsIGNvbnN0IGNoYXIqIHZhbHVlLCBqc2l6ZSBsZW4pIHsKKyAgICBzdGF0aWMgam1ldGhvZElEIGdCaWdEZWNpbWFsX2luaXQgPSBlbnYtPkdldE1ldGhvZElEKEpuaUNvbnN0YW50czo6YmlnRGVjaW1hbENsYXNzLCAiPGluaXQ+IiwgIihMamF2YS9sYW5nL1N0cmluZzspViIpOworCisgICAgLy8gdGhpcyBpcyBwYWluZnVsLi4uCisgICAgLy8gdmFsdWUgaXMgYSBVVEYtOCBzdHJpbmcgb2YgaW52YXJpYW50IGNoYXJhY3RlcnMsIGJ1dCBpc24ndCBndWFyYW50ZWVkIHRvIGJlCisgICAgLy8gbnVsbC10ZXJtaW5hdGVkLiAgTmV3U3RyaW5nVVRGIHJlcXVpcmVzIGEgdGVybWluYXRlZCBVVEYtOCBzdHJpbmcuICBTbyB3ZSBjb3B5IHRoZQorICAgIC8vIGRhdGEgdG8gamNoYXJzIHVzaW5nIFVuaWNvZGVTdHJpbmcsIGFuZCBjYWxsIE5ld1N0cmluZyBpbnN0ZWFkLgorICAgIFVuaWNvZGVTdHJpbmcgdG1wKHZhbHVlLCBsZW4sIFVuaWNvZGVTdHJpbmc6OmtJbnZhcmlhbnQpOworICAgIGpvYmplY3Qgc3RyID0gZW52LT5OZXdTdHJpbmcodG1wLmdldEJ1ZmZlcigpLCB0bXAubGVuZ3RoKCkpOworICAgIHJldHVybiBlbnYtPk5ld09iamVjdChKbmlDb25zdGFudHM6OmJpZ0RlY2ltYWxDbGFzcywgZ0JpZ0RlY2ltYWxfaW5pdCwgc3RyKTsKK30KKworc3RhdGljIGpvYmplY3QgTmF0aXZlRGVjaW1hbEZvcm1hdF9wYXJzZShKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGFkZHIsIGpzdHJpbmcgdGV4dCwKKyAgICAgICAgam9iamVjdCBwb3NpdGlvbiwgamJvb2xlYW4gcGFyc2VCaWdEZWNpbWFsKSB7CisKKyAgICBzdGF0aWMgam1ldGhvZElEIGdQUF9nZXRJbmRleCA9IGVudi0+R2V0TWV0aG9kSUQoSm5pQ29uc3RhbnRzOjpwYXJzZVBvc2l0aW9uQ2xhc3MsICJnZXRJbmRleCIsICIoKUkiKTsKKyAgICBzdGF0aWMgam1ldGhvZElEIGdQUF9zZXRJbmRleCA9IGVudi0+R2V0TWV0aG9kSUQoSm5pQ29uc3RhbnRzOjpwYXJzZVBvc2l0aW9uQ2xhc3MsICJzZXRJbmRleCIsICIoSSlWIik7CisgICAgc3RhdGljIGptZXRob2RJRCBnUFBfc2V0RXJyb3JJbmRleCA9IGVudi0+R2V0TWV0aG9kSUQoSm5pQ29uc3RhbnRzOjpwYXJzZVBvc2l0aW9uQ2xhc3MsICJzZXRFcnJvckluZGV4IiwgIihJKVYiKTsKKworICAgIC8vIG1ha2Ugc3VyZSB0aGUgUGFyc2VQb3NpdGlvbiBpcyB2YWxpZC4gQWN0dWFsbHkgaWN1NGMgd291bGQgcGFyc2UgYSBudW1iZXIKKyAgICAvLyBjb3JyZWN0bHkgZXZlbiBpZiB0aGUgcGFyc2VQb3NpdGlvbiBpcyBzZXQgdG8gLTEsIGJ1dCBzaW5jZSB0aGUgUkkgZmFpbHMKKyAgICAvLyBmb3IgdGhhdCBjYXNlIHdlIGhhdmUgdG8gZmFpbCB0b28KKyAgICBpbnQgcGFyc2VQb3MgPSBlbnYtPkNhbGxJbnRNZXRob2QocG9zaXRpb24sIGdQUF9nZXRJbmRleCwgTlVMTCk7CisgICAgaWYgKHBhcnNlUG9zIDwgMCB8fCBwYXJzZVBvcyA+IGVudi0+R2V0U3RyaW5nTGVuZ3RoKHRleHQpKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIEZvcm1hdHRhYmxlIHJlczsKKyAgICBQYXJzZVBvc2l0aW9uIHBwKHBhcnNlUG9zKTsKKyAgICBTY29wZWRKYXZhVW5pY29kZVN0cmluZyBzcmMoZW52LCB0ZXh0KTsKKyAgICBEZWNpbWFsRm9ybWF0KiBmbXQgPSB0b0RlY2ltYWxGb3JtYXQoYWRkcik7CisgICAgZm10LT5wYXJzZShzcmMudW5pY29kZVN0cmluZygpLCByZXMsIHBwKTsKKworICAgIGlmIChwcC5nZXRFcnJvckluZGV4KCkgPT0gLTEpIHsKKyAgICAgICAgZW52LT5DYWxsVm9pZE1ldGhvZChwb3NpdGlvbiwgZ1BQX3NldEluZGV4LCAoamludCkgcHAuZ2V0SW5kZXgoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgZW52LT5DYWxsVm9pZE1ldGhvZChwb3NpdGlvbiwgZ1BQX3NldEVycm9ySW5kZXgsIChqaW50KSBwcC5nZXRFcnJvckluZGV4KCkpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpZiAocGFyc2VCaWdEZWNpbWFsKSB7CisgICAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworICAgICAgICBTdHJpbmdQaWVjZSBzdHIgPSByZXMuZ2V0RGVjaW1hbE51bWJlcihzdGF0dXMpOworICAgICAgICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpIHsKKyAgICAgICAgICAgIGludCBsZW4gPSBzdHIubGVuZ3RoKCk7CisgICAgICAgICAgICBjb25zdCBjaGFyKiBkYXRhID0gc3RyLmRhdGEoKTsKKyAgICAgICAgICAgIGlmIChzdHJuY21wKGRhdGEsICJOYU4iLCAzKSA9PSAwIHx8CisgICAgICAgICAgICAgICAgc3RybmNtcChkYXRhLCAiSW5mIiwgMykgPT0gMCB8fAorICAgICAgICAgICAgICAgIHN0cm5jbXAoZGF0YSwgIi1JbmYiLCA0KSA9PSAwKSB7CisgICAgICAgICAgICAgICAgZG91YmxlIHJlc3VsdERvdWJsZSA9IHJlcy5nZXREb3VibGUoc3RhdHVzKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gZG91YmxlVmFsdWVPZihlbnYsIChqZG91YmxlKSByZXN1bHREb3VibGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ld0JpZ0RlY2ltYWwoZW52LCBkYXRhLCBsZW4pOworICAgICAgICB9CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIEZvcm1hdHRhYmxlOjpUeXBlIG51bVR5cGUgPSByZXMuZ2V0VHlwZSgpOworICAgICAgICBzd2l0Y2gobnVtVHlwZSkgeworICAgICAgICBjYXNlIEZvcm1hdHRhYmxlOjprRG91YmxlOiB7CisgICAgICAgICAgICBkb3VibGUgcmVzdWx0RG91YmxlID0gcmVzLmdldERvdWJsZSgpOworICAgICAgICAgICAgcmV0dXJuIGRvdWJsZVZhbHVlT2YoZW52LCAoamRvdWJsZSkgcmVzdWx0RG91YmxlKTsKKyAgICAgICAgfQorICAgICAgICBjYXNlIEZvcm1hdHRhYmxlOjprTG9uZzogeworICAgICAgICAgICAgbG9uZyByZXN1bHRMb25nID0gcmVzLmdldExvbmcoKTsKKyAgICAgICAgICAgIHJldHVybiBsb25nVmFsdWVPZihlbnYsIChqbG9uZykgcmVzdWx0TG9uZyk7CisgICAgICAgIH0KKyAgICAgICAgY2FzZSBGb3JtYXR0YWJsZTo6a0ludDY0OiB7CisgICAgICAgICAgICBpbnQ2NF90IHJlc3VsdEludDY0ID0gcmVzLmdldEludDY0KCk7CisgICAgICAgICAgICByZXR1cm4gbG9uZ1ZhbHVlT2YoZW52LCAoamxvbmcpIHJlc3VsdEludDY0KTsKKyAgICAgICAgfQorICAgICAgICBkZWZhdWx0OiB7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0KK30KKworc3RhdGljIGppbnQgTmF0aXZlRGVjaW1hbEZvcm1hdF9jbG9uZUltcGwoSk5JRW52KiwgamNsYXNzLCBqaW50IGFkZHIpIHsKKyAgICBEZWNpbWFsRm9ybWF0KiBmbXQgPSB0b0RlY2ltYWxGb3JtYXQoYWRkcik7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGppbnQ+KHJlaW50ZXJwcmV0X2Nhc3Q8dWludHB0cl90PihmbXQtPmNsb25lKCkpKTsKK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBnTWV0aG9kc1tdID0geworICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlRGVjaW1hbEZvcm1hdCwgYXBwbHlQYXR0ZXJuSW1wbCwgIihJWkxqYXZhL2xhbmcvU3RyaW5nOylWIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVEZWNpbWFsRm9ybWF0LCBjbG9uZUltcGwsICIoSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVEZWNpbWFsRm9ybWF0LCBjbG9zZSwgIihJKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZURlY2ltYWxGb3JtYXQsIGZvcm1hdERvdWJsZSwgIihJRExsaWJjb3JlL2ljdS9OYXRpdmVEZWNpbWFsRm9ybWF0JEZpZWxkUG9zaXRpb25JdGVyYXRvcjspW0MiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZURlY2ltYWxGb3JtYXQsIGZvcm1hdExvbmcsICIoSUpMbGliY29yZS9pY3UvTmF0aXZlRGVjaW1hbEZvcm1hdCRGaWVsZFBvc2l0aW9uSXRlcmF0b3I7KVtDIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVEZWNpbWFsRm9ybWF0LCBmb3JtYXREaWdpdExpc3QsICIoSUxqYXZhL2xhbmcvU3RyaW5nO0xsaWJjb3JlL2ljdS9OYXRpdmVEZWNpbWFsRm9ybWF0JEZpZWxkUG9zaXRpb25JdGVyYXRvcjspW0MiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZURlY2ltYWxGb3JtYXQsIGdldEF0dHJpYnV0ZSwgIihJSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVEZWNpbWFsRm9ybWF0LCBnZXRUZXh0QXR0cmlidXRlLCAiKElJKUxqYXZhL2xhbmcvU3RyaW5nOyIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlRGVjaW1hbEZvcm1hdCwgb3BlbiwgIihMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZztDQ0xqYXZhL2xhbmcvU3RyaW5nO0NMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZztDQ0xqYXZhL2xhbmcvU3RyaW5nO0NDQ0MpSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlRGVjaW1hbEZvcm1hdCwgcGFyc2UsICIoSUxqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL3RleHQvUGFyc2VQb3NpdGlvbjtaKUxqYXZhL2xhbmcvTnVtYmVyOyIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlRGVjaW1hbEZvcm1hdCwgc2V0QXR0cmlidXRlLCAiKElJSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVEZWNpbWFsRm9ybWF0LCBzZXREZWNpbWFsRm9ybWF0U3ltYm9scywgIihJTGphdmEvbGFuZy9TdHJpbmc7Q0NMamF2YS9sYW5nL1N0cmluZztDTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7Q0NMamF2YS9sYW5nL1N0cmluZztDQ0NDKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZURlY2ltYWxGb3JtYXQsIHNldFJvdW5kaW5nTW9kZSwgIihJSUQpViIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlRGVjaW1hbEZvcm1hdCwgc2V0U3ltYm9sLCAiKElJTGphdmEvbGFuZy9TdHJpbmc7KVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZURlY2ltYWxGb3JtYXQsIHNldFRleHRBdHRyaWJ1dGUsICIoSUlMamF2YS9sYW5nL1N0cmluZzspViIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlRGVjaW1hbEZvcm1hdCwgdG9QYXR0ZXJuSW1wbCwgIihJWilMamF2YS9sYW5nL1N0cmluZzsiKSwKK307CitpbnQgcmVnaXN0ZXJfbGliY29yZV9pY3VfTmF0aXZlRGVjaW1hbEZvcm1hdChKTklFbnYqIGVudikgeworICAgIHJldHVybiBqbmlSZWdpc3Rlck5hdGl2ZU1ldGhvZHMoZW52LCAibGliY29yZS9pY3UvTmF0aXZlRGVjaW1hbEZvcm1hdCIsIGdNZXRob2RzLCBORUxFTShnTWV0aG9kcykpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pY3VfTmF0aXZlSUROLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2xpYmNvcmVfaWN1X05hdGl2ZUlETi5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2QwY2JhMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2xpYmNvcmVfaWN1X05hdGl2ZUlETi5jcHAKQEAgLTAsMCArMSw2NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiTmF0aXZlSUROIgorCisjaW5jbHVkZSAiSk5JSGVscC5oIgorI2luY2x1ZGUgIkpuaUNvbnN0YW50cy5oIgorI2luY2x1ZGUgIlNjb3BlZFN0cmluZ0NoYXJzLmgiCisjaW5jbHVkZSAidW5pY29kZS91aWRuYS5oIgorCitzdGF0aWMgYm9vbCBpc0xhYmVsU2VwYXJhdG9yKGNvbnN0IFVDaGFyIGNoKSB7CisgICAgc3dpdGNoIChjaCkgeworICAgIGNhc2UgMHgzMDAyOiAvLyBpZGVvZ3JhcGhpYyBmdWxsIHN0b3AKKyAgICBjYXNlIDB4ZmYwZTogLy8gZnVsbHdpZHRoIGZ1bGwgc3RvcAorICAgIGNhc2UgMHhmZjYxOiAvLyBoYWxmd2lkdGggaWRlb2dyYXBoaWMgZnVsbCBzdG9wCisgICAgICAgIHJldHVybiB0cnVlOworICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9Cit9CisKK3N0YXRpYyBqc3RyaW5nIE5hdGl2ZUlETl9jb252ZXJ0SW1wbChKTklFbnYqIGVudiwgamNsYXNzLCBqc3RyaW5nIGphdmFTcmMsIGppbnQgZmxhZ3MsIGpib29sZWFuIHRvQXNjaWkpIHsKKyAgICBTY29wZWRTdHJpbmdDaGFycyBzcmMoZW52LCBqYXZhU3JjKTsKKyAgICBpZiAoc3JjLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFVDaGFyIGRzdFsyNTZdOworICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworICAgIHNpemVfdCByZXN1bHRMZW5ndGggPSB0b0FzY2lpCisgICAgICAgID8gdWlkbmFfSUROVG9BU0NJSShzcmMuZ2V0KCksIHNyYy5zaXplKCksICZkc3RbMF0sIHNpemVvZihkc3QpLCBmbGFncywgTlVMTCwgJnN0YXR1cykKKyAgICAgICAgOiB1aWRuYV9JRE5Ub1VuaWNvZGUoc3JjLmdldCgpLCBzcmMuc2l6ZSgpLCAmZHN0WzBdLCBzaXplb2YoZHN0KSwgZmxhZ3MsIE5VTEwsICZzdGF0dXMpOworICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgeworICAgICAgICBqbmlUaHJvd0V4Y2VwdGlvbihlbnYsICJqYXZhL2xhbmcvSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIiwgdV9lcnJvck5hbWUoc3RhdHVzKSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoIXRvQXNjaWkpIHsKKyAgICAgICAgLy8gSUNVIG9ubHkgdHJhbnNsYXRlcyBzZXBhcmF0b3JzIHRvIEFTQ0lJIGZvciB0b0FTQ0lJLgorICAgICAgICAvLyBKYXZhIGV4cGVjdHMgdGhlIHRyYW5zbGF0aW9uIGZvciB0b1VuaWNvZGUgdG9vLgorICAgICAgICAvLyBXZSBtYXkgYXMgd2VsbCBkbyB0aGlzIGhlcmUsIHdoaWxlIHRoZSBzdHJpbmcgaXMgc3RpbGwgbXV0YWJsZS4KKyAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCByZXN1bHRMZW5ndGg7ICsraSkgeworICAgICAgICAgICAgaWYgKGlzTGFiZWxTZXBhcmF0b3IoZHN0W2ldKSkgeworICAgICAgICAgICAgICAgIGRzdFtpXSA9ICcuJzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZW52LT5OZXdTdHJpbmcoJmRzdFswXSwgcmVzdWx0TGVuZ3RoKTsKK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBnTWV0aG9kc1tdID0geworICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlSUROLCBjb252ZXJ0SW1wbCwgIihMamF2YS9sYW5nL1N0cmluZztJWilMamF2YS9sYW5nL1N0cmluZzsiKSwKK307CitpbnQgcmVnaXN0ZXJfbGliY29yZV9pY3VfTmF0aXZlSUROKEpOSUVudiogZW52KSB7CisgICAgcmV0dXJuIGpuaVJlZ2lzdGVyTmF0aXZlTWV0aG9kcyhlbnYsICJsaWJjb3JlL2ljdS9OYXRpdmVJRE4iLCBnTWV0aG9kcywgTkVMRU0oZ01ldGhvZHMpKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL2xpYmNvcmVfaWN1X05hdGl2ZU5vcm1hbGl6ZXIuY3BwIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pY3VfTmF0aXZlTm9ybWFsaXplci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTdmMzFmNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2xpYmNvcmVfaWN1X05hdGl2ZU5vcm1hbGl6ZXIuY3BwCkBAIC0wLDAgKzEsNTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIk5hdGl2ZU5vcm1hbGl6ZXIiCisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisjaW5jbHVkZSAiSm5pRXhjZXB0aW9uLmgiCisjaW5jbHVkZSAiU2NvcGVkSmF2YVVuaWNvZGVTdHJpbmcuaCIKKyNpbmNsdWRlICJ1bmljb2RlL25vcm1senIuaCIKKworc3RhdGljIGpzdHJpbmcgTmF0aXZlTm9ybWFsaXplcl9ub3JtYWxpemVJbXBsKEpOSUVudiogZW52LCBqY2xhc3MsIGpzdHJpbmcgcywgamludCBpbnRNb2RlKSB7CisgICAgU2NvcGVkSmF2YVVuaWNvZGVTdHJpbmcgc3JjKGVudiwgcyk7CisgICAgVU5vcm1hbGl6YXRpb25Nb2RlIG1vZGUgPSBzdGF0aWNfY2FzdDxVTm9ybWFsaXphdGlvbk1vZGU+KGludE1vZGUpOworICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworICAgIFVuaWNvZGVTdHJpbmcgZHN0OworICAgIE5vcm1hbGl6ZXI6Om5vcm1hbGl6ZShzcmMudW5pY29kZVN0cmluZygpLCBtb2RlLCAwLCBkc3QsIHN0YXR1cyk7CisgICAgbWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihlbnYsIHN0YXR1cyk7CisgICAgcmV0dXJuIGRzdC5pc0JvZ3VzKCkgPyBOVUxMIDogZW52LT5OZXdTdHJpbmcoZHN0LmdldEJ1ZmZlcigpLCBkc3QubGVuZ3RoKCkpOworfQorCitzdGF0aWMgamJvb2xlYW4gTmF0aXZlTm9ybWFsaXplcl9pc05vcm1hbGl6ZWRJbXBsKEpOSUVudiogZW52LCBqY2xhc3MsIGpzdHJpbmcgcywgamludCBpbnRNb2RlKSB7CisgICAgU2NvcGVkSmF2YVVuaWNvZGVTdHJpbmcgc3JjKGVudiwgcyk7CisgICAgVU5vcm1hbGl6YXRpb25Nb2RlIG1vZGUgPSBzdGF0aWNfY2FzdDxVTm9ybWFsaXphdGlvbk1vZGU+KGludE1vZGUpOworICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworICAgIFVCb29sIHJlc3VsdCA9IE5vcm1hbGl6ZXI6OmlzTm9ybWFsaXplZChzcmMudW5pY29kZVN0cmluZygpLCBtb2RlLCBzdGF0dXMpOworICAgIG1heWJlVGhyb3dJY3VFeGNlcHRpb24oZW52LCBzdGF0dXMpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBKTklOYXRpdmVNZXRob2QgZ01ldGhvZHNbXSA9IHsKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZU5vcm1hbGl6ZXIsIG5vcm1hbGl6ZUltcGwsICIoTGphdmEvbGFuZy9TdHJpbmc7SSlMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZU5vcm1hbGl6ZXIsIGlzTm9ybWFsaXplZEltcGwsICIoTGphdmEvbGFuZy9TdHJpbmc7SSlaIiksCit9OworaW50IHJlZ2lzdGVyX2xpYmNvcmVfaWN1X05hdGl2ZU5vcm1hbGl6ZXIoSk5JRW52KiBlbnYpIHsKKyAgICByZXR1cm4gam5pUmVnaXN0ZXJOYXRpdmVNZXRob2RzKGVudiwgImxpYmNvcmUvaWN1L05hdGl2ZU5vcm1hbGl6ZXIiLCBnTWV0aG9kcywgTkVMRU0oZ01ldGhvZHMpKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL2xpYmNvcmVfaWN1X05hdGl2ZVBsdXJhbFJ1bGVzLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2xpYmNvcmVfaWN1X05hdGl2ZVBsdXJhbFJ1bGVzLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYTQ0M2Q3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pY3VfTmF0aXZlUGx1cmFsUnVsZXMuY3BwCkBAIC0wLDAgKzEsNjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIk5hdGl2ZVBsdXJhbFJ1bGVzIgorCisjaW5jbHVkZSAiSk5JSGVscC5oIgorI2luY2x1ZGUgIkpuaUNvbnN0YW50cy5oIgorI2luY2x1ZGUgIkpuaUV4Y2VwdGlvbi5oIgorI2luY2x1ZGUgIlNjb3BlZFV0ZkNoYXJzLmgiCisjaW5jbHVkZSAidW5pY29kZS9wbHVycnVsZS5oIgorCitzdGF0aWMgUGx1cmFsUnVsZXMqIHRvUGx1cmFsUnVsZXMoamludCBhZGRyZXNzKSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8UGx1cmFsUnVsZXMqPihzdGF0aWNfY2FzdDx1aW50cHRyX3Q+KGFkZHJlc3MpKTsKK30KKworc3RhdGljIHZvaWQgTmF0aXZlUGx1cmFsUnVsZXNfZmluYWxpemVJbXBsKEpOSUVudiosIGpjbGFzcywgamludCBhZGRyZXNzKSB7CisgICAgZGVsZXRlIHRvUGx1cmFsUnVsZXMoYWRkcmVzcyk7Cit9CisKK3N0YXRpYyBqaW50IE5hdGl2ZVBsdXJhbFJ1bGVzX2ZvckxvY2FsZUltcGwoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBsb2NhbGVOYW1lKSB7CisgICAgTG9jYWxlIGxvY2FsZSA9IExvY2FsZTo6Y3JlYXRlRnJvbU5hbWUoU2NvcGVkVXRmQ2hhcnMoZW52LCBsb2NhbGVOYW1lKS5jX3N0cigpKTsKKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBQbHVyYWxSdWxlcyogcmVzdWx0ID0gUGx1cmFsUnVsZXM6OmZvckxvY2FsZShsb2NhbGUsIHN0YXR1cyk7CisgICAgbWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihlbnYsIHN0YXR1cyk7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8dWludHB0cl90PihyZXN1bHQpOworfQorCitzdGF0aWMgamludCBOYXRpdmVQbHVyYWxSdWxlc19xdWFudGl0eUZvckludEltcGwoSk5JRW52KiwgamNsYXNzLCBqaW50IGFkZHJlc3MsIGppbnQgdmFsdWUpIHsKKyAgICBVbmljb2RlU3RyaW5nIGtleXdvcmQgPSB0b1BsdXJhbFJ1bGVzKGFkZHJlc3MpLT5zZWxlY3QodmFsdWUpOworICAgIGlmIChrZXl3b3JkID09ICJ6ZXJvIikgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9IGVsc2UgaWYgKGtleXdvcmQgPT0gIm9uZSIpIHsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfSBlbHNlIGlmIChrZXl3b3JkID09ICJ0d28iKSB7CisgICAgICAgIHJldHVybiAyOworICAgIH0gZWxzZSBpZiAoa2V5d29yZCA9PSAiZmV3IikgeworICAgICAgICByZXR1cm4gMzsKKyAgICB9IGVsc2UgaWYgKGtleXdvcmQgPT0gIm1hbnkiKSB7CisgICAgICAgIHJldHVybiA0OworICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiA1OworICAgIH0KK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBnTWV0aG9kc1tdID0geworICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlUGx1cmFsUnVsZXMsIGZpbmFsaXplSW1wbCwgIihJKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZVBsdXJhbFJ1bGVzLCBmb3JMb2NhbGVJbXBsLCAiKExqYXZhL2xhbmcvU3RyaW5nOylJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVQbHVyYWxSdWxlcywgcXVhbnRpdHlGb3JJbnRJbXBsLCAiKElJKUkiKSwKK307CitpbnQgcmVnaXN0ZXJfbGliY29yZV9pY3VfTmF0aXZlUGx1cmFsUnVsZXMoSk5JRW52KiBlbnYpIHsKKyAgICByZXR1cm4gam5pUmVnaXN0ZXJOYXRpdmVNZXRob2RzKGVudiwgImxpYmNvcmUvaWN1L05hdGl2ZVBsdXJhbFJ1bGVzIiwgZ01ldGhvZHMsIE5FTEVNKGdNZXRob2RzKSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS9saWJjb3JlX2ljdV9UaW1lWm9uZXMuY3BwIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pY3VfVGltZVpvbmVzLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZGExMDhkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pY3VfVGltZVpvbmVzLmNwcApAQCAtMCwwICsxLDIzMSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiVGltZVpvbmVzIgorCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgIkpOSUhlbHAuaCIKKyNpbmNsdWRlICJKbmlDb25zdGFudHMuaCIKKyNpbmNsdWRlICJKbmlFeGNlcHRpb24uaCIKKyNpbmNsdWRlICJTY29wZWRKYXZhVW5pY29kZVN0cmluZy5oIgorI2luY2x1ZGUgIlNjb3BlZExvY2FsUmVmLmgiCisjaW5jbHVkZSAiU2NvcGVkVXRmQ2hhcnMuaCIKKyNpbmNsdWRlICJVbmlxdWVQdHIuaCIKKyNpbmNsdWRlICJ1bmljb2RlL3NtcGR0Zm10LmgiCisjaW5jbHVkZSAidW5pY29kZS90aW1lem9uZS5oIgorCitleHRlcm4gTG9jYWxlIGdldExvY2FsZShKTklFbnYqIGVudiwganN0cmluZyBsb2NhbGVOYW1lKTsKKworc3RhdGljIGpvYmplY3RBcnJheSBUaW1lWm9uZXNfZm9yQ291bnRyeUNvZGUoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBjb3VudHJ5Q29kZSkgeworICAgIFNjb3BlZFV0ZkNoYXJzIGNvdW50cnlDaGFycyhlbnYsIGNvdW50cnlDb2RlKTsKKyAgICBpZiAoY291bnRyeUNoYXJzLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBVbmlxdWVQdHI8U3RyaW5nRW51bWVyYXRpb24+IGlkcyhUaW1lWm9uZTo6Y3JlYXRlRW51bWVyYXRpb24oY291bnRyeUNoYXJzLmNfc3RyKCkpKTsKKyAgICBpZiAoaWRzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOworICAgIGludDMyX3QgaWRDb3VudCA9IGlkcy0+Y291bnQoc3RhdHVzKTsKKyAgICBpZiAobWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihlbnYsIHN0YXR1cykpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgam9iamVjdEFycmF5IHJlc3VsdCA9IGVudi0+TmV3T2JqZWN0QXJyYXkoaWRDb3VudCwgSm5pQ29uc3RhbnRzOjpzdHJpbmdDbGFzcywgTlVMTCk7CisgICAgZm9yIChpbnQzMl90IGkgPSAwOyBpIDwgaWRDb3VudDsgKytpKSB7CisgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcqIGlkID0gaWRzLT5zbmV4dChzdGF0dXMpOworICAgICAgICBpZiAobWF5YmVUaHJvd0ljdUV4Y2VwdGlvbihlbnYsIHN0YXR1cykpIHsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIFNjb3BlZExvY2FsUmVmPGpzdHJpbmc+IGlkU3RyaW5nKGVudiwgZW52LT5OZXdTdHJpbmcoaWQtPmdldEJ1ZmZlcigpLCBpZC0+bGVuZ3RoKCkpKTsKKyAgICAgICAgZW52LT5TZXRPYmplY3RBcnJheUVsZW1lbnQocmVzdWx0LCBpLCBpZFN0cmluZy5nZXQoKSk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cnVjdCBUaW1lWm9uZU5hbWVzIHsKKyAgICBUaW1lWm9uZSogdHo7CisKKyAgICBVbmljb2RlU3RyaW5nIGxvbmdTdGQ7CisgICAgVW5pY29kZVN0cmluZyBzaG9ydFN0ZDsKKyAgICBVbmljb2RlU3RyaW5nIGxvbmdEc3Q7CisgICAgVW5pY29kZVN0cmluZyBzaG9ydERzdDsKKworICAgIFVEYXRlIHN0YW5kYXJkRGF0ZTsKKyAgICBVRGF0ZSBkYXlsaWdodFNhdmluZ0RhdGU7Cit9OworCitzdGF0aWMgdm9pZCBzZXRTdHJpbmdBcnJheUVsZW1lbnQoSk5JRW52KiBlbnYsIGpvYmplY3RBcnJheSBhcnJheSwgaW50IGksIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHMpIHsKKyAgICBTY29wZWRMb2NhbFJlZjxqc3RyaW5nPiBqYXZhU3RyaW5nKGVudiwgZW52LT5OZXdTdHJpbmcocy5nZXRCdWZmZXIoKSwgcy5sZW5ndGgoKSkpOworICAgIGVudi0+U2V0T2JqZWN0QXJyYXlFbGVtZW50KGFycmF5LCBpLCBqYXZhU3RyaW5nLmdldCgpKTsKK30KKworc3RhdGljIGJvb2wgaXNVdGMoY29uc3QgVW5pY29kZVN0cmluZyYgaWQpIHsKKyAgICBzdGF0aWMgVW5pY29kZVN0cmluZyBldGNVY3QoIkV0Yy9VQ1QiLCA3LCBVU19JTlYpOworICAgIHN0YXRpYyBVbmljb2RlU3RyaW5nIGV0Y1V0YygiRXRjL1VUQyIsIDcsIFVTX0lOVik7CisgICAgc3RhdGljIFVuaWNvZGVTdHJpbmcgZXRjVW5pdmVyc2FsKCJFdGMvVW5pdmVyc2FsIiwgMTMsIFVTX0lOVik7CisgICAgc3RhdGljIFVuaWNvZGVTdHJpbmcgZXRjWnVsdSgiRXRjL1p1bHUiLCA4LCBVU19JTlYpOworCisgICAgc3RhdGljIFVuaWNvZGVTdHJpbmcgdWN0KCJVQ1QiLCAzLCBVU19JTlYpOworICAgIHN0YXRpYyBVbmljb2RlU3RyaW5nIHV0YygiVVRDIiwgMywgVVNfSU5WKTsKKyAgICBzdGF0aWMgVW5pY29kZVN0cmluZyB1bml2ZXJzYWwoIlVuaXZlcnNhbCIsIDksIFVTX0lOVik7CisgICAgc3RhdGljIFVuaWNvZGVTdHJpbmcgenVsdSgiWnVsdSIsIDQsIFVTX0lOVik7CisKKyAgICByZXR1cm4gaWQgPT0gZXRjVWN0IHx8IGlkID09IGV0Y1V0YyB8fCBpZCA9PSBldGNVbml2ZXJzYWwgfHwgaWQgPT0gZXRjWnVsdSB8fAorICAgICAgICAgICAgaWQgPT0gdWN0IHx8IGlkID09IHV0YyB8fCBpZCA9PSB1bml2ZXJzYWwgfHwgaWQgPT0genVsdTsKK30KKworc3RhdGljIGpvYmplY3RBcnJheSBUaW1lWm9uZXNfZ2V0Wm9uZVN0cmluZ3NJbXBsKEpOSUVudiogZW52LCBqY2xhc3MsIGpzdHJpbmcgbG9jYWxlTmFtZSwgam9iamVjdEFycmF5IHRpbWVab25lSWRzKSB7CisgICAgTG9jYWxlIGxvY2FsZSA9IGdldExvY2FsZShlbnYsIGxvY2FsZU5hbWUpOworCisgICAgLy8gV2UgY291bGQgdXNlIFRpbWVab25lOjpnZXREaXNwbGF5TmFtZSwgYnV0IHRoYXQncyBldmVuIHNsb3dlcgorICAgIC8vIGJlY2F1c2UgaXQgY3JlYXRlcyBhIG5ldyBTaW1wbGVEYXRlRm9ybWF0IGVhY2ggdGltZS4KKyAgICAvLyBXZSdyZSBiZXR0ZXIgb2ZmIHVzaW5nIFNpbXBsZURhdGVGb3JtYXQgZGlyZWN0bHkuCisKKyAgICAvLyBXZSBjYW4ndCB1c2UgRGF0ZUZvcm1hdFN5bWJvbHM6OmdldFpvbmVTdHJpbmdzIGJlY2F1c2UgdGhhdAorICAgIC8vIHVzZXMgaXRzIG93biBzZXQgb2YgdGltZSB6b25lIGlkcyBhbmQgY29udGFpbnMgZW1wdHkgc3RyaW5ncworICAgIC8vIGluc3RlYWQgb2YgR01UIG9mZnNldHMgKGEgcGl0eSwgYmVjYXVzZSBpdCdzIGEgYml0IGZhc3RlciB0aGFuIHRoaXMgY29kZSkuCisKKyAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKKyAgICBVbmljb2RlU3RyaW5nIGxvbmdQYXR0ZXJuKCJ6enp6IiwgNCwgVVNfSU5WKTsKKyAgICBTaW1wbGVEYXRlRm9ybWF0IGxvbmdGb3JtYXQobG9uZ1BhdHRlcm4sIGxvY2FsZSwgc3RhdHVzKTsKKyAgICAvLyAneicgb25seSB1c2VzICJjb21tb24iIGFiYnJldmlhdGlvbnMuICdWJyBhbGxvd3MgYWxsIGtub3duIGFiYnJldmlhdGlvbnMuCisgICAgLy8gRm9yIGV4YW1wbGUsICJQU1QiIGlzIGluIGNvbW1vbiB1c2UgaW4gZW5fVVMsIGJ1dCAiQ0VUIiBpc24ndC4KKyAgICBVbmljb2RlU3RyaW5nIGNvbW1vblNob3J0UGF0dGVybigieiIsIDEsIFVTX0lOVik7CisgICAgU2ltcGxlRGF0ZUZvcm1hdCBzaG9ydEZvcm1hdChjb21tb25TaG9ydFBhdHRlcm4sIGxvY2FsZSwgc3RhdHVzKTsKKyAgICBVbmljb2RlU3RyaW5nIGFsbFNob3J0UGF0dGVybigiViIsIDEsIFVTX0lOVik7CisgICAgU2ltcGxlRGF0ZUZvcm1hdCBhbGxTaG9ydEZvcm1hdChhbGxTaG9ydFBhdHRlcm4sIGxvY2FsZSwgc3RhdHVzKTsKKworICAgIFVuaWNvZGVTdHJpbmcgdXRjKCJVVEMiLCAzLCBVU19JTlYpOworCisgICAgLy8gVE9ETzogdXNlIG9mIGZpeGVkIGRhdGVzIHByZXZlbnRzIHVzIGZyb20gdXNpbmcgdGhlIGNvcnJlY3QgaGlzdG9yaWNhbCBuYW1lIHdoZW4gZm9ybWF0dGluZyBkYXRlcy4KKyAgICAvLyBUT0RPOiB1c2Ugb2YgZGF0ZXMgbm90IGluIHRoZSBjdXJyZW50IHllYXIgY291bGQgY2F1c2UgdXMgdG8gb3V0cHV0IG9ic29sZXRlZCBuYW1lcy4KKyAgICAvLyAxNXRoIEphbnVhcnkgMjAwOAorICAgIFVEYXRlIGRhdGUxID0gMTIwMzEwNTYwMDAwMC4wOworICAgIC8vIDE1dGggSnVseSAyMDA4CisgICAgVURhdGUgZGF0ZTIgPSAxMjE4ODI2ODAwMDAwLjA7CisKKyAgICAvLyBJbiB0aGUgZmlyc3QgcGFzcywgd2UgZ2V0IHRoZSBsb25nIG5hbWVzIGZvciB0aGUgdGltZSB6b25lLgorICAgIC8vIFdlIGFsc28gZ2V0IGFueSBjb21tb25seS11c2VkIGFiYnJldmlhdGlvbnMuCisgICAgc3RkOjp2ZWN0b3I8VGltZVpvbmVOYW1lcz4gdGFibGU7CisgICAgdHlwZWRlZiBzdGQ6Om1hcDxVbmljb2RlU3RyaW5nLCBVbmljb2RlU3RyaW5nKj4gQWJicmV2aWF0aW9uTWFwOworICAgIEFiYnJldmlhdGlvbk1hcCB1c2VkQWJicmV2aWF0aW9uczsKKyAgICBzaXplX3QgaWRDb3VudCA9IGVudi0+R2V0QXJyYXlMZW5ndGgodGltZVpvbmVJZHMpOworICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgaWRDb3VudDsgKytpKSB7CisgICAgICAgIFNjb3BlZExvY2FsUmVmPGpzdHJpbmc+IGphdmFab25lSWQoZW52LAorICAgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8anN0cmluZz4oZW52LT5HZXRPYmplY3RBcnJheUVsZW1lbnQodGltZVpvbmVJZHMsIGkpKSk7CisgICAgICAgIFNjb3BlZEphdmFVbmljb2RlU3RyaW5nIHpvbmVJZChlbnYsIGphdmFab25lSWQuZ2V0KCkpOworICAgICAgICBVbmljb2RlU3RyaW5nIGlkKHpvbmVJZC51bmljb2RlU3RyaW5nKCkpOworCisgICAgICAgIFRpbWVab25lTmFtZXMgcm93OworICAgICAgICBpZiAoaXNVdGMoaWQpKSB7CisgICAgICAgICAgICAvLyBJQ1UgZG9lc24ndCBoYXZlIG5hbWVzIGZvciB0aGUgVVRDIHpvbmVzOyBpdCBqdXN0IHNheXMgIkdNVCswMDowMCIgZm9yIGJvdGgKKyAgICAgICAgICAgIC8vIGxvbmcgYW5kIHNob3J0IG5hbWVzLiBXZSBkb24ndCB3YW50IHRoaXMuIFRoZSBiZXN0IHdlIGNhbiBkbyBpcyB1c2UgIlVUQyIKKyAgICAgICAgICAgIC8vIGZvciBldmVyeXRoaW5nIChzaW5jZSB3ZSBkb24ndCBrbm93IGhvdyB0byBzYXkgIlVuaXZlcnNhbCBDb29yZGluYXRlZCBUaW1lIikuCisgICAgICAgICAgICByb3cudHogPSBOVUxMOworICAgICAgICAgICAgcm93LmxvbmdTdGQgPSByb3cuc2hvcnRTdGQgPSByb3cubG9uZ0RzdCA9IHJvdy5zaG9ydERzdCA9IHV0YzsKKyAgICAgICAgICAgIHRhYmxlLnB1c2hfYmFjayhyb3cpOworICAgICAgICAgICAgdXNlZEFiYnJldmlhdGlvbnNbdXRjXSA9ICZ1dGM7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorCisgICAgICAgIHJvdy50eiA9IFRpbWVab25lOjpjcmVhdGVUaW1lWm9uZShpZCk7CisgICAgICAgIGxvbmdGb3JtYXQuc2V0VGltZVpvbmUoKnJvdy50eik7CisgICAgICAgIHNob3J0Rm9ybWF0LnNldFRpbWVab25lKCpyb3cudHopOworCisgICAgICAgIGludDMyX3QgZGF5bGlnaHRPZmZzZXQ7CisgICAgICAgIGludDMyX3QgcmF3T2Zmc2V0OworICAgICAgICByb3cudHotPmdldE9mZnNldChkYXRlMSwgZmFsc2UsIHJhd09mZnNldCwgZGF5bGlnaHRPZmZzZXQsIHN0YXR1cyk7CisgICAgICAgIGlmIChkYXlsaWdodE9mZnNldCAhPSAwKSB7CisgICAgICAgICAgICAvLyBUaGUgVGltZVpvbmUgaXMgcmVwb3J0aW5nIHRoYXQgd2UgYXJlIGluIGRheWxpZ2h0IHRpbWUgZm9yIHRoZSB3aW50ZXIgZGF0ZS4KKyAgICAgICAgICAgIC8vIFRoZSBkYXRlcyBhcmUgZm9yIHRoZSB3cm9uZyBoZW1pc3BoZXJlLCBzbyBzd2FwIHRoZW0uCisgICAgICAgICAgICByb3cuc3RhbmRhcmREYXRlID0gZGF0ZTI7CisgICAgICAgICAgICByb3cuZGF5bGlnaHRTYXZpbmdEYXRlID0gZGF0ZTE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByb3cuc3RhbmRhcmREYXRlID0gZGF0ZTE7CisgICAgICAgICAgICByb3cuZGF5bGlnaHRTYXZpbmdEYXRlID0gZGF0ZTI7CisgICAgICAgIH0KKworICAgICAgICBsb25nRm9ybWF0LmZvcm1hdChyb3cuc3RhbmRhcmREYXRlLCByb3cubG9uZ1N0ZCk7CisgICAgICAgIHNob3J0Rm9ybWF0LmZvcm1hdChyb3cuc3RhbmRhcmREYXRlLCByb3cuc2hvcnRTdGQpOworICAgICAgICBpZiAocm93LnR6LT51c2VEYXlsaWdodFRpbWUoKSkgeworICAgICAgICAgICAgbG9uZ0Zvcm1hdC5mb3JtYXQocm93LmRheWxpZ2h0U2F2aW5nRGF0ZSwgcm93LmxvbmdEc3QpOworICAgICAgICAgICAgc2hvcnRGb3JtYXQuZm9ybWF0KHJvdy5kYXlsaWdodFNhdmluZ0RhdGUsIHJvdy5zaG9ydERzdCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByb3cubG9uZ0RzdCA9IHJvdy5sb25nU3RkOworICAgICAgICAgICAgcm93LnNob3J0RHN0ID0gcm93LnNob3J0U3RkOworICAgICAgICB9CisKKyAgICAgICAgdGFibGUucHVzaF9iYWNrKHJvdyk7CisgICAgICAgIHVzZWRBYmJyZXZpYXRpb25zW3Jvdy5zaG9ydFN0ZF0gPSAmcm93LmxvbmdTdGQ7CisgICAgICAgIHVzZWRBYmJyZXZpYXRpb25zW3Jvdy5zaG9ydERzdF0gPSAmcm93LmxvbmdEc3Q7CisgICAgfQorCisgICAgLy8gSW4gdGhlIHNlY29uZCBwYXNzLCB3ZSBjcmVhdGUgdGhlIEphdmEgU3RyaW5nW11bXS4KKyAgICAvLyBXZSBhbHNvIGxvb2sgZm9yIGFueSB1bmNvbW1vbiBhYmJyZXZpYXRpb25zIHRoYXQgZG9uJ3QgY29uZmxpY3Qgd2l0aCBvbmVzIHdlJ3ZlIGFscmVhZHkgc2Vlbi4KKyAgICBqb2JqZWN0QXJyYXkgcmVzdWx0ID0gZW52LT5OZXdPYmplY3RBcnJheShpZENvdW50LCBKbmlDb25zdGFudHM6OnN0cmluZ0FycmF5Q2xhc3MsIE5VTEwpOworICAgIFVuaWNvZGVTdHJpbmcgZ210KCJHTVQiLCAzLCBVU19JTlYpOworICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgdGFibGUuc2l6ZSgpOyArK2kpIHsKKyAgICAgICAgVGltZVpvbmVOYW1lcyYgcm93KHRhYmxlW2ldKTsKKyAgICAgICAgLy8gRGlkIHdlIGdldCBhIEdNVCBvZmZzZXQgaW5zdGVhZCBvZiBhbiBhYmJyZXZpYXRpb24/CisgICAgICAgIGlmIChyb3cuc2hvcnRTdGQubGVuZ3RoKCkgPiAzICYmIHJvdy5zaG9ydFN0ZC5zdGFydHNXaXRoKGdtdCkpIHsKKyAgICAgICAgICAgIC8vIFNlZSBpZiB3ZSBjYW4gZG8gYmV0dGVyLi4uCisgICAgICAgICAgICBVbmljb2RlU3RyaW5nIHVuY29tbW9uU3RkLCB1bmNvbW1vbkRzdDsKKyAgICAgICAgICAgIGFsbFNob3J0Rm9ybWF0LnNldFRpbWVab25lKCpyb3cudHopOworICAgICAgICAgICAgYWxsU2hvcnRGb3JtYXQuZm9ybWF0KHJvdy5zdGFuZGFyZERhdGUsIHVuY29tbW9uU3RkKTsKKyAgICAgICAgICAgIGlmIChyb3cudHotPnVzZURheWxpZ2h0VGltZSgpKSB7CisgICAgICAgICAgICAgICAgYWxsU2hvcnRGb3JtYXQuZm9ybWF0KHJvdy5kYXlsaWdodFNhdmluZ0RhdGUsIHVuY29tbW9uRHN0KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdW5jb21tb25Ec3QgPSB1bmNvbW1vblN0ZDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gSWYgdGhpcyBhYmJyZXZpYXRpb24gaXNuJ3QgYWxyZWFkeSBpbiB1c2UsIHdlIGNhbiB1c2UgaXQuCisgICAgICAgICAgICBBYmJyZXZpYXRpb25NYXA6Oml0ZXJhdG9yIGl0ID0gdXNlZEFiYnJldmlhdGlvbnMuZmluZCh1bmNvbW1vblN0ZCk7CisgICAgICAgICAgICBpZiAoaXQgPT0gdXNlZEFiYnJldmlhdGlvbnMuZW5kKCkgfHwgKihpdC0+c2Vjb25kKSA9PSByb3cubG9uZ1N0ZCkgeworICAgICAgICAgICAgICAgIHJvdy5zaG9ydFN0ZCA9IHVuY29tbW9uU3RkOworICAgICAgICAgICAgICAgIHVzZWRBYmJyZXZpYXRpb25zW3Jvdy5zaG9ydFN0ZF0gPSAmcm93LmxvbmdTdGQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpdCA9IHVzZWRBYmJyZXZpYXRpb25zLmZpbmQodW5jb21tb25Ec3QpOworICAgICAgICAgICAgaWYgKGl0ID09IHVzZWRBYmJyZXZpYXRpb25zLmVuZCgpIHx8ICooaXQtPnNlY29uZCkgPT0gcm93LmxvbmdEc3QpIHsKKyAgICAgICAgICAgICAgICByb3cuc2hvcnREc3QgPSB1bmNvbW1vbkRzdDsKKyAgICAgICAgICAgICAgICB1c2VkQWJicmV2aWF0aW9uc1tyb3cuc2hvcnREc3RdID0gJnJvdy5sb25nRHN0OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIEZpbGwgaW4gd2hhdGV2ZXIgd2UgZ290LgorICAgICAgICBTY29wZWRMb2NhbFJlZjxqb2JqZWN0QXJyYXk+IGphdmFSb3coZW52LCBlbnYtPk5ld09iamVjdEFycmF5KDUsIEpuaUNvbnN0YW50czo6c3RyaW5nQ2xhc3MsIE5VTEwpKTsKKyAgICAgICAgU2NvcGVkTG9jYWxSZWY8anN0cmluZz4gaWQoZW52LCByZWludGVycHJldF9jYXN0PGpzdHJpbmc+KGVudi0+R2V0T2JqZWN0QXJyYXlFbGVtZW50KHRpbWVab25lSWRzLCBpKSkpOworICAgICAgICBlbnYtPlNldE9iamVjdEFycmF5RWxlbWVudChqYXZhUm93LmdldCgpLCAwLCBpZC5nZXQoKSk7CisgICAgICAgIHNldFN0cmluZ0FycmF5RWxlbWVudChlbnYsIGphdmFSb3cuZ2V0KCksIDEsIHJvdy5sb25nU3RkKTsKKyAgICAgICAgc2V0U3RyaW5nQXJyYXlFbGVtZW50KGVudiwgamF2YVJvdy5nZXQoKSwgMiwgcm93LnNob3J0U3RkKTsKKyAgICAgICAgc2V0U3RyaW5nQXJyYXlFbGVtZW50KGVudiwgamF2YVJvdy5nZXQoKSwgMywgcm93LmxvbmdEc3QpOworICAgICAgICBzZXRTdHJpbmdBcnJheUVsZW1lbnQoZW52LCBqYXZhUm93LmdldCgpLCA0LCByb3cuc2hvcnREc3QpOworICAgICAgICBlbnYtPlNldE9iamVjdEFycmF5RWxlbWVudChyZXN1bHQsIGksIGphdmFSb3cuZ2V0KCkpOworICAgICAgICBkZWxldGUgcm93LnR6OworICAgIH0KKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBKTklOYXRpdmVNZXRob2QgZ01ldGhvZHNbXSA9IHsKKyAgICBOQVRJVkVfTUVUSE9EKFRpbWVab25lcywgZm9yQ291bnRyeUNvZGUsICIoTGphdmEvbGFuZy9TdHJpbmc7KVtMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFRpbWVab25lcywgZ2V0Wm9uZVN0cmluZ3NJbXBsLCAiKExqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL1N0cmluZzspW1tMamF2YS9sYW5nL1N0cmluZzsiKSwKK307CitpbnQgcmVnaXN0ZXJfbGliY29yZV9pY3VfVGltZVpvbmVzKEpOSUVudiogZW52KSB7CisgICAgcmV0dXJuIGpuaVJlZ2lzdGVyTmF0aXZlTWV0aG9kcyhlbnYsICJsaWJjb3JlL2ljdS9UaW1lWm9uZXMiLCBnTWV0aG9kcywgTkVMRU0oZ01ldGhvZHMpKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL2xpYmNvcmVfaW9fQXN5bmNocm9ub3VzQ2xvc2VNb25pdG9yLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2xpYmNvcmVfaW9fQXN5bmNocm9ub3VzQ2xvc2VNb25pdG9yLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kM2ZkYWJmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pb19Bc3luY2hyb25vdXNDbG9zZU1vbml0b3IuY3BwCkBAIC0wLDAgKzEsMzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIkFzeW5jaHJvbm91c0Nsb3NlTW9uaXRvciIKKworI2luY2x1ZGUgIkFzeW5jaHJvbm91c1NvY2tldENsb3NlTW9uaXRvci5oIgorI2luY2x1ZGUgIkpOSUhlbHAuaCIKKyNpbmNsdWRlICJKbmlDb25zdGFudHMuaCIKKyNpbmNsdWRlICJqbmkuaCIKKworc3RhdGljIHZvaWQgQXN5bmNocm9ub3VzQ2xvc2VNb25pdG9yX3NpZ25hbEJsb2NrZWRUaHJlYWRzKEpOSUVudiogZW52LCBqY2xhc3MsIGpvYmplY3QgamF2YUZkKSB7CisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIEFzeW5jaHJvbm91c1NvY2tldENsb3NlTW9uaXRvcjo6c2lnbmFsQmxvY2tlZFRocmVhZHMoZmQpOworfQorCitzdGF0aWMgSk5JTmF0aXZlTWV0aG9kIGdNZXRob2RzW10gPSB7CisgICAgTkFUSVZFX01FVEhPRChBc3luY2hyb25vdXNDbG9zZU1vbml0b3IsIHNpZ25hbEJsb2NrZWRUaHJlYWRzLCAiKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yOylWIiksCit9OworCitpbnQgcmVnaXN0ZXJfbGliY29yZV9pb19Bc3luY2hyb25vdXNDbG9zZU1vbml0b3IoSk5JRW52KiBlbnYpIHsKKyAgICBBc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3I6OmluaXQoKTsKKyAgICByZXR1cm4gam5pUmVnaXN0ZXJOYXRpdmVNZXRob2RzKGVudiwgImxpYmNvcmUvaW8vQXN5bmNocm9ub3VzQ2xvc2VNb25pdG9yIiwgZ01ldGhvZHMsIE5FTEVNKGdNZXRob2RzKSk7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS9saWJjb3JlX2lvX01lbW9yeS5jcHAgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9saWJjb3JlX2lvX01lbW9yeS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjIwMDQ1MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL2xpYmNvcmVfaW9fTWVtb3J5LmNwcApAQCAtMCwwICsxLDM1NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiTWVtb3J5IgorCisjaW5jbHVkZSAiSk5JSGVscC5oIgorI2luY2x1ZGUgIkpuaUNvbnN0YW50cy5oIgorI2luY2x1ZGUgIlNjb3BlZEJ5dGVzLmgiCisjaW5jbHVkZSAiU2NvcGVkUHJpbWl0aXZlQXJyYXkuaCIKKyNpbmNsdWRlICJVbmlxdWVQdHIuaCIKKworI2luY2x1ZGUgPGJ5dGVzd2FwLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxzeXMvbW1hbi5oPgorCisjaWYgZGVmaW5lZChfX2FybV9fKQorLy8gMzItYml0IEFSTSBoYXMgbG9hZC9zdG9yZSBhbGlnbm1lbnQgcmVzdHJpY3Rpb25zIGZvciBsb25ncy4KKyNkZWZpbmUgTE9OR19BTElHTk1FTlRfTUFTSyAweDMKKyNlbGlmIGRlZmluZWQoX19pMzg2X18pCisvLyB4ODYgY2FuIGxvYWQgYW55dGhpbmcgYXQgYW55IGFsaWdubWVudC4KKyNkZWZpbmUgTE9OR19BTElHTk1FTlRfTUFTSyAweDAKKyNlbHNlCisjZXJyb3IgdW5rbm93biBsb2FkL3N0b3JlIGFsaWdubWVudCByZXN0cmljdGlvbnMgZm9yIHRoaXMgYXJjaGl0ZWN0dXJlCisjZW5kaWYKKwordGVtcGxhdGUgPHR5cGVuYW1lIFQ+IHN0YXRpYyBUIGNhc3QoamludCBhZGRyZXNzKSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8VD4oc3RhdGljX2Nhc3Q8dWludHB0cl90PihhZGRyZXNzKSk7Cit9CisKK3N0YXRpYyBpbmxpbmUgdm9pZCBzd2FwU2hvcnRzKGpzaG9ydCogZHN0U2hvcnRzLCBjb25zdCBqc2hvcnQqIHNyY1Nob3J0cywgc2l6ZV90IGNvdW50KSB7CisgICAgLy8gRG8gMzItYml0IHN3YXBzIGFzIGxvbmcgYXMgcG9zc2libGUuLi4KKyAgICBqaW50KiBkc3QgPSByZWludGVycHJldF9jYXN0PGppbnQqPihkc3RTaG9ydHMpOworICAgIGNvbnN0IGppbnQqIHNyYyA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgamludCo+KHNyY1Nob3J0cyk7CisgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBjb3VudCAvIDI7ICsraSkgeworICAgICAgICBqaW50IHYgPSAqc3JjKys7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHY9QUJDRAorICAgICAgICB2ID0gYnN3YXBfMzIodik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHY9RENCQQorICAgICAgICBqaW50IHYyID0gKHYgPDwgMTYpIHwgKCh2ID4+IDE2KSAmIDB4ZmZmZik7IC8vIHY9QkFEQworICAgICAgICAqZHN0KysgPSB2MjsKKyAgICB9CisgICAgLy8gLi4ud2l0aCBvbmUgbGFzdCAxNi1iaXQgc3dhcCBpZiBuZWNlc3NhcnkuCisgICAgaWYgKChjb3VudCAlIDIpICE9IDApIHsKKyAgICAgICAganNob3J0IHYgPSAqcmVpbnRlcnByZXRfY2FzdDxjb25zdCBqc2hvcnQqPihzcmMpOworICAgICAgICAqcmVpbnRlcnByZXRfY2FzdDxqc2hvcnQqPihkc3QpID0gYnN3YXBfMTYodik7CisgICAgfQorfQorCitzdGF0aWMgaW5saW5lIHZvaWQgc3dhcEludHMoamludCogZHN0SW50cywgY29uc3QgamludCogc3JjSW50cywgc2l6ZV90IGNvdW50KSB7CisgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7CisgICAgICAgIGppbnQgdiA9ICpzcmNJbnRzKys7CisgICAgICAgICpkc3RJbnRzKysgPSBic3dhcF8zMih2KTsKKyAgICB9Cit9CisKK3N0YXRpYyBpbmxpbmUgdm9pZCBzd2FwTG9uZ3MoamxvbmcqIGRzdExvbmdzLCBjb25zdCBqbG9uZyogc3JjTG9uZ3MsIHNpemVfdCBjb3VudCkgeworICAgIGppbnQqIGRzdCA9IHJlaW50ZXJwcmV0X2Nhc3Q8amludCo+KGRzdExvbmdzKTsKKyAgICBjb25zdCBqaW50KiBzcmMgPSByZWludGVycHJldF9jYXN0PGNvbnN0IGppbnQqPihzcmNMb25ncyk7CisgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7CisgICAgICAgIGppbnQgdjEgPSAqc3JjKys7CisgICAgICAgIGppbnQgdjIgPSAqc3JjKys7CisgICAgICAgICpkc3QrKyA9IGJzd2FwXzMyKHYyKTsKKyAgICAgICAgKmRzdCsrID0gYnN3YXBfMzIodjEpOworICAgIH0KK30KKworc3RhdGljIHZvaWQgTWVtb3J5X21lbW1vdmUoSk5JRW52KiBlbnYsIGpjbGFzcywgam9iamVjdCBkc3RPYmplY3QsIGppbnQgZHN0T2Zmc2V0LCBqb2JqZWN0IHNyY09iamVjdCwgamludCBzcmNPZmZzZXQsIGpsb25nIGxlbmd0aCkgeworICAgIFNjb3BlZEJ5dGVzUlcgZHN0Qnl0ZXMoZW52LCBkc3RPYmplY3QpOworICAgIGlmIChkc3RCeXRlcy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgU2NvcGVkQnl0ZXNSTyBzcmNCeXRlcyhlbnYsIHNyY09iamVjdCk7CisgICAgaWYgKHNyY0J5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBtZW1tb3ZlKGRzdEJ5dGVzLmdldCgpICsgZHN0T2Zmc2V0LCBzcmNCeXRlcy5nZXQoKSArIHNyY09mZnNldCwgbGVuZ3RoKTsKK30KKworc3RhdGljIGpieXRlIE1lbW9yeV9wZWVrQnl0ZShKTklFbnYqLCBqY2xhc3MsIGppbnQgc3JjQWRkcmVzcykgeworICAgIHJldHVybiAqY2FzdDxjb25zdCBqYnl0ZSo+KHNyY0FkZHJlc3MpOworfQorCitzdGF0aWMgdm9pZCBNZW1vcnlfcGVla0J5dGVBcnJheShKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IHNyY0FkZHJlc3MsIGpieXRlQXJyYXkgZHN0LCBqaW50IGRzdE9mZnNldCwgamludCBieXRlQ291bnQpIHsKKyAgICBlbnYtPlNldEJ5dGVBcnJheVJlZ2lvbihkc3QsIGRzdE9mZnNldCwgYnl0ZUNvdW50LCBjYXN0PGNvbnN0IGpieXRlKj4oc3JjQWRkcmVzcykpOworfQorCisvLyBJbXBsZW1lbnRzIHRoZSBwZWVrWEFycmF5IG1ldGhvZHM6CisvLyAtIEZvciB1bnN3YXBwZWQgYWNjZXNzLCB3ZSBqdXN0IHVzZSB0aGUgSk5JIFNldFhBcnJheVJlZ2lvbiBmdW5jdGlvbnMuCisvLyAtIEZvciBzd2FwcGVkIGFjY2Vzcywgd2UgdXNlIEdldFhBcnJheUVsZW1lbnRzIGFuZCBvdXIgb3duIGNvcHktYW5kLXN3YXAgcm91dGluZXMuCisvLyAgIEdldFhBcnJheUVsZW1lbnRzIGlzIGRpc3Byb3BvcnRpb25hdGVseSBjaGVhcCBvbiBEYWx2aWsgYmVjYXVzZSBpdCBkb2Vzbid0IGNvcHkgKGFzIG9wcG9zZWQKKy8vICAgdG8gSG90c3BvdCwgd2hpY2ggYWx3YXlzIGNvcGllcykuIFRoZSBTV0FQX0ZOIGNvcGllcyBhbmQgc3dhcHMgaW4gb25lIHBhc3MsIHdoaWNoIGlzIGNoZWFwZXIKKy8vICAgdGhhbiBjb3B5aW5nIGFuZCB0aGVuIHN3YXBwaW5nIGluIGEgc2Vjb25kIHBhc3MuIERlcGVuZGluZyBvbiBmdXR1cmUgVk0vR0MgY2hhbmdlcywgdGhlCisvLyAgIHN3YXBwZWQgY2FzZSBtaWdodCBuZWVkIHRvIGJlIHJldmlzaXRlZC4KKyNkZWZpbmUgUEVFS0VSKFNDQUxBUl9UWVBFLCBKTklfTkFNRSwgU1dBUF9UWVBFLCBTV0FQX0ZOKSB7IFwKKyAgICBpZiAoc3dhcCkgeyBcCisgICAgICAgIFNjb3BlZCAjIyBKTklfTkFNRSAjIyBBcnJheVJXIGVsZW1lbnRzKGVudiwgZHN0KTsgXAorICAgICAgICBpZiAoZWxlbWVudHMuZ2V0KCkgPT0gTlVMTCkgeyBcCisgICAgICAgICAgICByZXR1cm47IFwKKyAgICAgICAgfSBcCisgICAgICAgIGNvbnN0IFNXQVBfVFlQRSogc3JjID0gY2FzdDxjb25zdCBTV0FQX1RZUEUqPihzcmNBZGRyZXNzKTsgXAorICAgICAgICBTV0FQX0ZOKHJlaW50ZXJwcmV0X2Nhc3Q8U1dBUF9UWVBFKj4oZWxlbWVudHMuZ2V0KCkpICsgZHN0T2Zmc2V0LCBzcmMsIGNvdW50KTsgXAorICAgIH0gZWxzZSB7IFwKKyAgICAgICAgY29uc3QgU0NBTEFSX1RZUEUqIHNyYyA9IGNhc3Q8Y29uc3QgU0NBTEFSX1RZUEUqPihzcmNBZGRyZXNzKTsgXAorICAgICAgICBlbnYtPlNldCAjIyBKTklfTkFNRSAjIyBBcnJheVJlZ2lvbihkc3QsIGRzdE9mZnNldCwgY291bnQsIHNyYyk7IFwKKyAgICB9IFwKK30KKworc3RhdGljIHZvaWQgTWVtb3J5X3BlZWtDaGFyQXJyYXkoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBzcmNBZGRyZXNzLCBqY2hhckFycmF5IGRzdCwgamludCBkc3RPZmZzZXQsIGppbnQgY291bnQsIGpib29sZWFuIHN3YXApIHsKKyAgICBQRUVLRVIoamNoYXIsIENoYXIsIGpzaG9ydCwgc3dhcFNob3J0cyk7Cit9CisKK3N0YXRpYyB2b2lkIE1lbW9yeV9wZWVrRG91YmxlQXJyYXkoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBzcmNBZGRyZXNzLCBqZG91YmxlQXJyYXkgZHN0LCBqaW50IGRzdE9mZnNldCwgamludCBjb3VudCwgamJvb2xlYW4gc3dhcCkgeworICAgIFBFRUtFUihqZG91YmxlLCBEb3VibGUsIGpsb25nLCBzd2FwTG9uZ3MpOworfQorCitzdGF0aWMgdm9pZCBNZW1vcnlfcGVla0Zsb2F0QXJyYXkoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBzcmNBZGRyZXNzLCBqZmxvYXRBcnJheSBkc3QsIGppbnQgZHN0T2Zmc2V0LCBqaW50IGNvdW50LCBqYm9vbGVhbiBzd2FwKSB7CisgICAgUEVFS0VSKGpmbG9hdCwgRmxvYXQsIGppbnQsIHN3YXBJbnRzKTsKK30KKworc3RhdGljIHZvaWQgTWVtb3J5X3BlZWtJbnRBcnJheShKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IHNyY0FkZHJlc3MsIGppbnRBcnJheSBkc3QsIGppbnQgZHN0T2Zmc2V0LCBqaW50IGNvdW50LCBqYm9vbGVhbiBzd2FwKSB7CisgICAgUEVFS0VSKGppbnQsIEludCwgamludCwgc3dhcEludHMpOworfQorCitzdGF0aWMgdm9pZCBNZW1vcnlfcGVla0xvbmdBcnJheShKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IHNyY0FkZHJlc3MsIGpsb25nQXJyYXkgZHN0LCBqaW50IGRzdE9mZnNldCwgamludCBjb3VudCwgamJvb2xlYW4gc3dhcCkgeworICAgIFBFRUtFUihqbG9uZywgTG9uZywgamxvbmcsIHN3YXBMb25ncyk7Cit9CisKK3N0YXRpYyB2b2lkIE1lbW9yeV9wZWVrU2hvcnRBcnJheShKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IHNyY0FkZHJlc3MsIGpzaG9ydEFycmF5IGRzdCwgamludCBkc3RPZmZzZXQsIGppbnQgY291bnQsIGpib29sZWFuIHN3YXApIHsKKyAgICBQRUVLRVIoanNob3J0LCBTaG9ydCwganNob3J0LCBzd2FwU2hvcnRzKTsKK30KKworc3RhdGljIHZvaWQgTWVtb3J5X3Bva2VCeXRlKEpOSUVudiosIGpjbGFzcywgamludCBkc3RBZGRyZXNzLCBqYnl0ZSB2YWx1ZSkgeworICAgICpjYXN0PGpieXRlKj4oZHN0QWRkcmVzcykgPSB2YWx1ZTsKK30KKworc3RhdGljIHZvaWQgTWVtb3J5X3Bva2VCeXRlQXJyYXkoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBkc3RBZGRyZXNzLCBqYnl0ZUFycmF5IHNyYywgamludCBvZmZzZXQsIGppbnQgbGVuZ3RoKSB7CisgICAgZW52LT5HZXRCeXRlQXJyYXlSZWdpb24oc3JjLCBvZmZzZXQsIGxlbmd0aCwgY2FzdDxqYnl0ZSo+KGRzdEFkZHJlc3MpKTsKK30KKworLy8gSW1wbGVtZW50cyB0aGUgcG9rZVhBcnJheSBtZXRob2RzOgorLy8gLSBGb3IgdW5zd2FwcGVkIGFjY2Vzcywgd2UganVzdCB1c2UgdGhlIEpOSSBHZXRYQXJyYXlSZWdpb24gZnVuY3Rpb25zLgorLy8gLSBGb3Igc3dhcHBlZCBhY2Nlc3MsIHdlIHVzZSBHZXRYQXJyYXlFbGVtZW50cyBhbmQgb3VyIG93biBjb3B5LWFuZC1zd2FwIHJvdXRpbmVzLgorLy8gICBHZXRYQXJyYXlFbGVtZW50cyBpcyBkaXNwcm9wb3J0aW9uYXRlbHkgY2hlYXAgb24gRGFsdmlrIGJlY2F1c2UgaXQgZG9lc24ndCBjb3B5IChhcyBvcHBvc2VkCisvLyAgIHRvIEhvdHNwb3QsIHdoaWNoIGFsd2F5cyBjb3BpZXMpLiBUaGUgU1dBUF9GTiBjb3BpZXMgYW5kIHN3YXBzIGluIG9uZSBwYXNzLCB3aGljaCBpcyBjaGVhcGVyCisvLyAgIHRoYW4gY29weWluZyBhbmQgdGhlbiBzd2FwcGluZyBpbiBhIHNlY29uZCBwYXNzLiBEZXBlbmRpbmcgb24gZnV0dXJlIFZNL0dDIGNoYW5nZXMsIHRoZQorLy8gICBzd2FwcGVkIGNhc2UgbWlnaHQgbmVlZCB0byBiZSByZXZpc2l0ZWQuCisjZGVmaW5lIFBPS0VSKFNDQUxBUl9UWVBFLCBKTklfTkFNRSwgU1dBUF9UWVBFLCBTV0FQX0ZOKSB7IFwKKyAgICBpZiAoc3dhcCkgeyBcCisgICAgICAgIFNjb3BlZCAjIyBKTklfTkFNRSAjIyBBcnJheVJPIGVsZW1lbnRzKGVudiwgc3JjKTsgXAorICAgICAgICBpZiAoZWxlbWVudHMuZ2V0KCkgPT0gTlVMTCkgeyBcCisgICAgICAgICAgICByZXR1cm47IFwKKyAgICAgICAgfSBcCisgICAgICAgIGNvbnN0IFNXQVBfVFlQRSogc3JjID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBTV0FQX1RZUEUqPihlbGVtZW50cy5nZXQoKSkgKyBzcmNPZmZzZXQ7IFwKKyAgICAgICAgU1dBUF9GTihjYXN0PFNXQVBfVFlQRSo+KGRzdEFkZHJlc3MpLCBzcmMsIGNvdW50KTsgXAorICAgIH0gZWxzZSB7IFwKKyAgICAgICAgZW52LT5HZXQgIyMgSk5JX05BTUUgIyMgQXJyYXlSZWdpb24oc3JjLCBzcmNPZmZzZXQsIGNvdW50LCBjYXN0PFNDQUxBUl9UWVBFKj4oZHN0QWRkcmVzcykpOyBcCisgICAgfSBcCit9CisKK3N0YXRpYyB2b2lkIE1lbW9yeV9wb2tlQ2hhckFycmF5KEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgZHN0QWRkcmVzcywgamNoYXJBcnJheSBzcmMsIGppbnQgc3JjT2Zmc2V0LCBqaW50IGNvdW50LCBqYm9vbGVhbiBzd2FwKSB7CisgICAgUE9LRVIoamNoYXIsIENoYXIsIGpzaG9ydCwgc3dhcFNob3J0cyk7Cit9CisKK3N0YXRpYyB2b2lkIE1lbW9yeV9wb2tlRG91YmxlQXJyYXkoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBkc3RBZGRyZXNzLCBqZG91YmxlQXJyYXkgc3JjLCBqaW50IHNyY09mZnNldCwgamludCBjb3VudCwgamJvb2xlYW4gc3dhcCkgeworICAgIFBPS0VSKGpkb3VibGUsIERvdWJsZSwgamxvbmcsIHN3YXBMb25ncyk7Cit9CisKK3N0YXRpYyB2b2lkIE1lbW9yeV9wb2tlRmxvYXRBcnJheShKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGRzdEFkZHJlc3MsIGpmbG9hdEFycmF5IHNyYywgamludCBzcmNPZmZzZXQsIGppbnQgY291bnQsIGpib29sZWFuIHN3YXApIHsKKyAgICBQT0tFUihqZmxvYXQsIEZsb2F0LCBqaW50LCBzd2FwSW50cyk7Cit9CisKK3N0YXRpYyB2b2lkIE1lbW9yeV9wb2tlSW50QXJyYXkoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBkc3RBZGRyZXNzLCBqaW50QXJyYXkgc3JjLCBqaW50IHNyY09mZnNldCwgamludCBjb3VudCwgamJvb2xlYW4gc3dhcCkgeworICAgIFBPS0VSKGppbnQsIEludCwgamludCwgc3dhcEludHMpOworfQorCitzdGF0aWMgdm9pZCBNZW1vcnlfcG9rZUxvbmdBcnJheShKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IGRzdEFkZHJlc3MsIGpsb25nQXJyYXkgc3JjLCBqaW50IHNyY09mZnNldCwgamludCBjb3VudCwgamJvb2xlYW4gc3dhcCkgeworICAgIFBPS0VSKGpsb25nLCBMb25nLCBqbG9uZywgc3dhcExvbmdzKTsKK30KKworc3RhdGljIHZvaWQgTWVtb3J5X3Bva2VTaG9ydEFycmF5KEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgZHN0QWRkcmVzcywganNob3J0QXJyYXkgc3JjLCBqaW50IHNyY09mZnNldCwgamludCBjb3VudCwgamJvb2xlYW4gc3dhcCkgeworICAgIFBPS0VSKGpzaG9ydCwgU2hvcnQsIGpzaG9ydCwgc3dhcFNob3J0cyk7Cit9CisKK3N0YXRpYyBqc2hvcnQgTWVtb3J5X3BlZWtTaG9ydChKTklFbnYqLCBqY2xhc3MsIGppbnQgc3JjQWRkcmVzcywgamJvb2xlYW4gc3dhcCkgeworICAgIGpzaG9ydCByZXN1bHQgPSAqY2FzdDxjb25zdCBqc2hvcnQqPihzcmNBZGRyZXNzKTsKKyAgICBpZiAoc3dhcCkgeworICAgICAgICByZXN1bHQgPSBic3dhcF8xNihyZXN1bHQpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgdm9pZCBNZW1vcnlfcG9rZVNob3J0KEpOSUVudiosIGpjbGFzcywgamludCBkc3RBZGRyZXNzLCBqc2hvcnQgdmFsdWUsIGpib29sZWFuIHN3YXApIHsKKyAgICBpZiAoc3dhcCkgeworICAgICAgICB2YWx1ZSA9IGJzd2FwXzE2KHZhbHVlKTsKKyAgICB9CisgICAgKmNhc3Q8anNob3J0Kj4oZHN0QWRkcmVzcykgPSB2YWx1ZTsKK30KKworc3RhdGljIGppbnQgTWVtb3J5X3BlZWtJbnQoSk5JRW52KiwgamNsYXNzLCBqaW50IHNyY0FkZHJlc3MsIGpib29sZWFuIHN3YXApIHsKKyAgICBqaW50IHJlc3VsdCA9ICpjYXN0PGNvbnN0IGppbnQqPihzcmNBZGRyZXNzKTsKKyAgICBpZiAoc3dhcCkgeworICAgICAgICByZXN1bHQgPSBic3dhcF8zMihyZXN1bHQpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgdm9pZCBNZW1vcnlfcG9rZUludChKTklFbnYqLCBqY2xhc3MsIGppbnQgZHN0QWRkcmVzcywgamludCB2YWx1ZSwgamJvb2xlYW4gc3dhcCkgeworICAgIGlmIChzd2FwKSB7CisgICAgICAgIHZhbHVlID0gYnN3YXBfMzIodmFsdWUpOworICAgIH0KKyAgICAqY2FzdDxqaW50Kj4oZHN0QWRkcmVzcykgPSB2YWx1ZTsKK30KKworc3RhdGljIGpsb25nIE1lbW9yeV9wZWVrTG9uZyhKTklFbnYqLCBqY2xhc3MsIGppbnQgc3JjQWRkcmVzcywgamJvb2xlYW4gc3dhcCkgeworICAgIGpsb25nIHJlc3VsdDsKKyAgICBpZiAoKHNyY0FkZHJlc3MgJiBMT05HX0FMSUdOTUVOVF9NQVNLKSA9PSAwKSB7CisgICAgICAgIHJlc3VsdCA9ICpjYXN0PGNvbnN0IGpsb25nKj4oc3JjQWRkcmVzcyk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gSGFuZGxlIHVuYWxpZ25lZCBtZW1vcnkgYWNjZXNzIG9uZSBieXRlIGF0IGEgdGltZQorICAgICAgICBjb25zdCBqYnl0ZSogc3JjID0gY2FzdDxjb25zdCBqYnl0ZSo+KHNyY0FkZHJlc3MpOworICAgICAgICBqYnl0ZSogZHN0ID0gcmVpbnRlcnByZXRfY2FzdDxqYnl0ZSo+KCZyZXN1bHQpOworICAgICAgICBkc3RbMF0gPSBzcmNbMF07CisgICAgICAgIGRzdFsxXSA9IHNyY1sxXTsKKyAgICAgICAgZHN0WzJdID0gc3JjWzJdOworICAgICAgICBkc3RbM10gPSBzcmNbM107CisgICAgICAgIGRzdFs0XSA9IHNyY1s0XTsKKyAgICAgICAgZHN0WzVdID0gc3JjWzVdOworICAgICAgICBkc3RbNl0gPSBzcmNbNl07CisgICAgICAgIGRzdFs3XSA9IHNyY1s3XTsKKyAgICB9CisgICAgaWYgKHN3YXApIHsKKyAgICAgICAgcmVzdWx0ID0gYnN3YXBfNjQocmVzdWx0KTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIHZvaWQgTWVtb3J5X3Bva2VMb25nKEpOSUVudiosIGpjbGFzcywgamludCBkc3RBZGRyZXNzLCBqbG9uZyB2YWx1ZSwgamJvb2xlYW4gc3dhcCkgeworICAgIGlmIChzd2FwKSB7CisgICAgICAgIHZhbHVlID0gYnN3YXBfNjQodmFsdWUpOworICAgIH0KKyAgICBpZiAoKGRzdEFkZHJlc3MgJiBMT05HX0FMSUdOTUVOVF9NQVNLKSA9PSAwKSB7CisgICAgICAgICpjYXN0PGpsb25nKj4oZHN0QWRkcmVzcykgPSB2YWx1ZTsKKyAgICB9IGVsc2UgeworICAgICAgICAvLyBIYW5kbGUgdW5hbGlnbmVkIG1lbW9yeSBhY2Nlc3Mgb25lIGJ5dGUgYXQgYSB0aW1lCisgICAgICAgIGNvbnN0IGpieXRlKiBzcmMgPSByZWludGVycHJldF9jYXN0PGNvbnN0IGpieXRlKj4oJnZhbHVlKTsKKyAgICAgICAgamJ5dGUqIGRzdCA9IGNhc3Q8amJ5dGUqPihkc3RBZGRyZXNzKTsKKyAgICAgICAgZHN0WzBdID0gc3JjWzBdOworICAgICAgICBkc3RbMV0gPSBzcmNbMV07CisgICAgICAgIGRzdFsyXSA9IHNyY1syXTsKKyAgICAgICAgZHN0WzNdID0gc3JjWzNdOworICAgICAgICBkc3RbNF0gPSBzcmNbNF07CisgICAgICAgIGRzdFs1XSA9IHNyY1s1XTsKKyAgICAgICAgZHN0WzZdID0gc3JjWzZdOworICAgICAgICBkc3RbN10gPSBzcmNbN107CisgICAgfQorfQorCitzdGF0aWMgdm9pZCB1bnNhZmVCdWxrQ29weShqYnl0ZSogZHN0LCBjb25zdCBqYnl0ZSogc3JjLCBqaW50IGJ5dGVDb3VudCwKKyAgICAgICAgamludCBzaXplb2ZFbGVtZW50LCBqYm9vbGVhbiBzd2FwKSB7CisgICAgaWYgKCFzd2FwKSB7CisgICAgICAgIG1lbWNweShkc3QsIHNyYywgYnl0ZUNvdW50KTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGlmIChzaXplb2ZFbGVtZW50ID09IDIpIHsKKyAgICAgICAganNob3J0KiBkc3RTaG9ydHMgPSByZWludGVycHJldF9jYXN0PGpzaG9ydCo+KGRzdCk7CisgICAgICAgIGNvbnN0IGpzaG9ydCogc3JjU2hvcnRzID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBqc2hvcnQqPihzcmMpOworICAgICAgICBzd2FwU2hvcnRzKGRzdFNob3J0cywgc3JjU2hvcnRzLCBieXRlQ291bnQgLyAyKTsKKyAgICB9IGVsc2UgaWYgKHNpemVvZkVsZW1lbnQgPT0gNCkgeworICAgICAgICBqaW50KiBkc3RJbnRzID0gcmVpbnRlcnByZXRfY2FzdDxqaW50Kj4oZHN0KTsKKyAgICAgICAgY29uc3QgamludCogc3JjSW50cyA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgamludCo+KHNyYyk7CisgICAgICAgIHN3YXBJbnRzKGRzdEludHMsIHNyY0ludHMsIGJ5dGVDb3VudCAvIDQpOworICAgIH0gZWxzZSBpZiAoc2l6ZW9mRWxlbWVudCA9PSA4KSB7CisgICAgICAgIGpsb25nKiBkc3RMb25ncyA9IHJlaW50ZXJwcmV0X2Nhc3Q8amxvbmcqPihkc3QpOworICAgICAgICBjb25zdCBqbG9uZyogc3JjTG9uZ3MgPSByZWludGVycHJldF9jYXN0PGNvbnN0IGpsb25nKj4oc3JjKTsKKyAgICAgICAgc3dhcExvbmdzKGRzdExvbmdzLCBzcmNMb25ncywgYnl0ZUNvdW50IC8gOCk7CisgICAgfQorfQorCitzdGF0aWMgdm9pZCBNZW1vcnlfdW5zYWZlQnVsa0dldChKTklFbnYqIGVudiwgamNsYXNzLCBqb2JqZWN0IGRzdE9iamVjdCwgamludCBkc3RPZmZzZXQsCisgICAgICAgIGppbnQgYnl0ZUNvdW50LCBqYnl0ZUFycmF5IHNyY0FycmF5LCBqaW50IHNyY09mZnNldCwgamludCBzaXplb2ZFbGVtZW50LCBqYm9vbGVhbiBzd2FwKSB7CisgICAgU2NvcGVkQnl0ZUFycmF5Uk8gc3JjQnl0ZXMoZW52LCBzcmNBcnJheSk7CisgICAgaWYgKHNyY0J5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBqYXJyYXkgZHN0QXJyYXkgPSByZWludGVycHJldF9jYXN0PGphcnJheT4oZHN0T2JqZWN0KTsKKyAgICBqYnl0ZSogZHN0Qnl0ZXMgPSByZWludGVycHJldF9jYXN0PGpieXRlKj4oZW52LT5HZXRQcmltaXRpdmVBcnJheUNyaXRpY2FsKGRzdEFycmF5LCBOVUxMKSk7CisgICAgaWYgKGRzdEJ5dGVzID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBqYnl0ZSogZHN0ID0gZHN0Qnl0ZXMgKyBkc3RPZmZzZXQqc2l6ZW9mRWxlbWVudDsKKyAgICBjb25zdCBqYnl0ZSogc3JjID0gc3JjQnl0ZXMuZ2V0KCkgKyBzcmNPZmZzZXQ7CisgICAgdW5zYWZlQnVsa0NvcHkoZHN0LCBzcmMsIGJ5dGVDb3VudCwgc2l6ZW9mRWxlbWVudCwgc3dhcCk7CisgICAgZW52LT5SZWxlYXNlUHJpbWl0aXZlQXJyYXlDcml0aWNhbChkc3RBcnJheSwgZHN0Qnl0ZXMsIDApOworfQorCitzdGF0aWMgdm9pZCBNZW1vcnlfdW5zYWZlQnVsa1B1dChKTklFbnYqIGVudiwgamNsYXNzLCBqYnl0ZUFycmF5IGRzdEFycmF5LCBqaW50IGRzdE9mZnNldCwKKyAgICAgICAgamludCBieXRlQ291bnQsIGpvYmplY3Qgc3JjT2JqZWN0LCBqaW50IHNyY09mZnNldCwgamludCBzaXplb2ZFbGVtZW50LCBqYm9vbGVhbiBzd2FwKSB7CisgICAgU2NvcGVkQnl0ZUFycmF5UlcgZHN0Qnl0ZXMoZW52LCBkc3RBcnJheSk7CisgICAgaWYgKGRzdEJ5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBqYXJyYXkgc3JjQXJyYXkgPSByZWludGVycHJldF9jYXN0PGphcnJheT4oc3JjT2JqZWN0KTsKKyAgICBqYnl0ZSogc3JjQnl0ZXMgPSByZWludGVycHJldF9jYXN0PGpieXRlKj4oZW52LT5HZXRQcmltaXRpdmVBcnJheUNyaXRpY2FsKHNyY0FycmF5LCBOVUxMKSk7CisgICAgaWYgKHNyY0J5dGVzID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBqYnl0ZSogZHN0ID0gZHN0Qnl0ZXMuZ2V0KCkgKyBkc3RPZmZzZXQ7CisgICAgY29uc3QgamJ5dGUqIHNyYyA9IHNyY0J5dGVzICsgc3JjT2Zmc2V0KnNpemVvZkVsZW1lbnQ7CisgICAgdW5zYWZlQnVsa0NvcHkoZHN0LCBzcmMsIGJ5dGVDb3VudCwgc2l6ZW9mRWxlbWVudCwgc3dhcCk7CisgICAgZW52LT5SZWxlYXNlUHJpbWl0aXZlQXJyYXlDcml0aWNhbChzcmNBcnJheSwgc3JjQnl0ZXMsIDApOworfQorCitzdGF0aWMgSk5JTmF0aXZlTWV0aG9kIGdNZXRob2RzW10gPSB7CisgICAgTkFUSVZFX01FVEhPRChNZW1vcnksIG1lbW1vdmUsICIoTGphdmEvbGFuZy9PYmplY3Q7SUxqYXZhL2xhbmcvT2JqZWN0O0lKKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1lbW9yeSwgcGVla0J5dGUsICIhKEkpQiIpLAorICAgIE5BVElWRV9NRVRIT0QoTWVtb3J5LCBwZWVrQnl0ZUFycmF5LCAiKElbQklJKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1lbW9yeSwgcGVla0NoYXJBcnJheSwgIihJW0NJSVopViIpLAorICAgIE5BVElWRV9NRVRIT0QoTWVtb3J5LCBwZWVrRG91YmxlQXJyYXksICIoSVtESUlaKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1lbW9yeSwgcGVla0Zsb2F0QXJyYXksICIoSVtGSUlaKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1lbW9yeSwgcGVla0ludCwgIiEoSVopSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTWVtb3J5LCBwZWVrSW50QXJyYXksICIoSVtJSUlaKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1lbW9yeSwgcGVla0xvbmcsICIhKElaKUoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1lbW9yeSwgcGVla0xvbmdBcnJheSwgIihJW0pJSVopViIpLAorICAgIE5BVElWRV9NRVRIT0QoTWVtb3J5LCBwZWVrU2hvcnQsICIhKElaKVMiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1lbW9yeSwgcGVla1Nob3J0QXJyYXksICIoSVtTSUlaKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1lbW9yeSwgcG9rZUJ5dGUsICIhKElCKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1lbW9yeSwgcG9rZUJ5dGVBcnJheSwgIihJW0JJSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChNZW1vcnksIHBva2VDaGFyQXJyYXksICIoSVtDSUlaKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1lbW9yeSwgcG9rZURvdWJsZUFycmF5LCAiKElbRElJWilWIiksCisgICAgTkFUSVZFX01FVEhPRChNZW1vcnksIHBva2VGbG9hdEFycmF5LCAiKElbRklJWilWIiksCisgICAgTkFUSVZFX01FVEhPRChNZW1vcnksIHBva2VJbnQsICIhKElJWilWIiksCisgICAgTkFUSVZFX01FVEhPRChNZW1vcnksIHBva2VJbnRBcnJheSwgIihJW0lJSVopViIpLAorICAgIE5BVElWRV9NRVRIT0QoTWVtb3J5LCBwb2tlTG9uZywgIiEoSUpaKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE1lbW9yeSwgcG9rZUxvbmdBcnJheSwgIihJW0pJSVopViIpLAorICAgIE5BVElWRV9NRVRIT0QoTWVtb3J5LCBwb2tlU2hvcnQsICIhKElTWilWIiksCisgICAgTkFUSVZFX01FVEhPRChNZW1vcnksIHBva2VTaG9ydEFycmF5LCAiKElbU0lJWilWIiksCisgICAgTkFUSVZFX01FVEhPRChNZW1vcnksIHVuc2FmZUJ1bGtHZXQsICIoTGphdmEvbGFuZy9PYmplY3Q7SUlbQklJWilWIiksCisgICAgTkFUSVZFX01FVEhPRChNZW1vcnksIHVuc2FmZUJ1bGtQdXQsICIoW0JJSUxqYXZhL2xhbmcvT2JqZWN0O0lJWilWIiksCit9OworaW50IHJlZ2lzdGVyX2xpYmNvcmVfaW9fTWVtb3J5KEpOSUVudiogZW52KSB7CisgICAgcmV0dXJuIGpuaVJlZ2lzdGVyTmF0aXZlTWV0aG9kcyhlbnYsICJsaWJjb3JlL2lvL01lbW9yeSIsIGdNZXRob2RzLCBORUxFTShnTWV0aG9kcykpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pb19Pc0NvbnN0YW50cy5jcHAgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9saWJjb3JlX2lvX09zQ29uc3RhbnRzLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NDJjZmNlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pb19Pc0NvbnN0YW50cy5jcHAKQEAgLTAsMCArMSw0NTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgIk9zQ29uc3RhbnRzIgorCisjaW5jbHVkZSAiSk5JSGVscC5oIgorI2luY2x1ZGUgIkpuaUNvbnN0YW50cy5oIgorCisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2luY2x1ZGUgPG5ldC9pZi5oPgorI2luY2x1ZGUgPG5ldGRiLmg+CisjaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgorI2luY2x1ZGUgPG5ldGluZXQvdGNwLmg+CisjaW5jbHVkZSA8cG9sbC5oPgorI2luY2x1ZGUgPHNpZ25hbC5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN5cy9pb2N0bC5oPgorI2luY2x1ZGUgPHN5cy9tbWFuLmg+CisjaW5jbHVkZSA8c3lzL3NvY2tldC5oPgorI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CisjaW5jbHVkZSA8c3lzL3dhaXQuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKworc3RhdGljIHZvaWQgaW5pdENvbnN0YW50KEpOSUVudiogZW52LCBqY2xhc3MgYywgY29uc3QgY2hhciogZmllbGROYW1lLCBpbnQgdmFsdWUpIHsKKyAgICBqZmllbGRJRCBmaWVsZCA9IGVudi0+R2V0U3RhdGljRmllbGRJRChjLCBmaWVsZE5hbWUsICJJIik7CisgICAgZW52LT5TZXRTdGF0aWNJbnRGaWVsZChjLCBmaWVsZCwgdmFsdWUpOworfQorCitzdGF0aWMgdm9pZCBPc0NvbnN0YW50c19pbml0Q29uc3RhbnRzKEpOSUVudiogZW52LCBqY2xhc3MgYykgeworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJBRl9JTkVUIiwgQUZfSU5FVCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkFGX0lORVQ2IiwgQUZfSU5FVDYpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJBRl9VTklYIiwgQUZfVU5JWCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkFGX1VOU1BFQyIsIEFGX1VOU1BFQyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkFJX0FERFJDT05GSUciLCBBSV9BRERSQ09ORklHKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiQUlfQUxMIiwgQUlfQUxMKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiQUlfQ0FOT05OQU1FIiwgQUlfQ0FOT05OQU1FKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiQUlfTlVNRVJJQ0hPU1QiLCBBSV9OVU1FUklDSE9TVCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkFJX05VTUVSSUNTRVJWIiwgQUlfTlVNRVJJQ1NFUlYpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJBSV9QQVNTSVZFIiwgQUlfUEFTU0lWRSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkFJX1Y0TUFQUEVEIiwgQUlfVjRNQVBQRUQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFMkJJRyIsIEUyQklHKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRUFDQ0VTIiwgRUFDQ0VTKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRUFERFJJTlVTRSIsIEVBRERSSU5VU0UpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFQUREUk5PVEFWQUlMIiwgRUFERFJOT1RBVkFJTCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVBRk5PU1VQUE9SVCIsIEVBRk5PU1VQUE9SVCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVBR0FJTiIsIEVBR0FJTik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVBSV9BR0FJTiIsIEVBSV9BR0FJTik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVBSV9CQURGTEFHUyIsIEVBSV9CQURGTEFHUyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVBSV9GQUlMIiwgRUFJX0ZBSUwpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFQUlfRkFNSUxZIiwgRUFJX0ZBTUlMWSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVBSV9NRU1PUlkiLCBFQUlfTUVNT1JZKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRUFJX05PREFUQSIsIEVBSV9OT0RBVEEpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFQUlfTk9OQU1FIiwgRUFJX05PTkFNRSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVBSV9PVkVSRkxPVyIsIEVBSV9PVkVSRkxPVyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVBSV9TRVJWSUNFIiwgRUFJX1NFUlZJQ0UpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFQUlfU09DS1RZUEUiLCBFQUlfU09DS1RZUEUpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFQUlfU1lTVEVNIiwgRUFJX1NZU1RFTSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVBTFJFQURZIiwgRUFMUkVBRFkpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFQkFERiIsIEVCQURGKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRUJBRE1TRyIsIEVCQURNU0cpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFQlVTWSIsIEVCVVNZKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRUNBTkNFTEVEIiwgRUNBTkNFTEVEKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRUNISUxEIiwgRUNISUxEKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRUNPTk5BQk9SVEVEIiwgRUNPTk5BQk9SVEVEKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRUNPTk5SRUZVU0VEIiwgRUNPTk5SRUZVU0VEKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRUNPTk5SRVNFVCIsIEVDT05OUkVTRVQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFREVBRExLIiwgRURFQURMSyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVERVNUQUREUlJFUSIsIEVERVNUQUREUlJFUSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVET00iLCBFRE9NKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRURRVU9UIiwgRURRVU9UKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRUVYSVNUIiwgRUVYSVNUKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRUZBVUxUIiwgRUZBVUxUKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRUZCSUciLCBFRkJJRyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVIT1NUVU5SRUFDSCIsIEVIT1NUVU5SRUFDSCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVJRFJNIiwgRUlEUk0pOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFSUxTRVEiLCBFSUxTRVEpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFSU5QUk9HUkVTUyIsIEVJTlBST0dSRVNTKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRUlOVFIiLCBFSU5UUik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVJTlZBTCIsIEVJTlZBTCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVJTyIsIEVJTyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVJU0NPTk4iLCBFSVNDT05OKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRUlTRElSIiwgRUlTRElSKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRUxPT1AiLCBFTE9PUCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVNRklMRSIsIEVNRklMRSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVNTElOSyIsIEVNTElOSyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVNU0dTSVpFIiwgRU1TR1NJWkUpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFTVVMVElIT1AiLCBFTVVMVElIT1ApOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFTkFNRVRPT0xPTkciLCBFTkFNRVRPT0xPTkcpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFTkVURE9XTiIsIEVORVRET1dOKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRU5FVFJFU0VUIiwgRU5FVFJFU0VUKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRU5FVFVOUkVBQ0giLCBFTkVUVU5SRUFDSCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVORklMRSIsIEVORklMRSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVOT0JVRlMiLCBFTk9CVUZTKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRU5PREFUQSIsIEVOT0RBVEEpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFTk9ERVYiLCBFTk9ERVYpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFTk9FTlQiLCBFTk9FTlQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFTk9FWEVDIiwgRU5PRVhFQyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVOT0xDSyIsIEVOT0xDSyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVOT0xJTksiLCBFTk9MSU5LKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRU5PTUVNIiwgRU5PTUVNKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRU5PTVNHIiwgRU5PTVNHKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRU5PUFJPVE9PUFQiLCBFTk9QUk9UT09QVCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVOT1NQQyIsIEVOT1NQQyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVOT1NSIiwgRU5PU1IpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFTk9TVFIiLCBFTk9TVFIpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFTk9TWVMiLCBFTk9TWVMpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFTk9UQ09OTiIsIEVOT1RDT05OKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRU5PVERJUiIsIEVOT1RESVIpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFTk9URU1QVFkiLCBFTk9URU1QVFkpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFTk9UU09DSyIsIEVOT1RTT0NLKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRU5PVFNVUCIsIEVOT1RTVVApOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFTk9UVFkiLCBFTk9UVFkpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFTlhJTyIsIEVOWElPKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRU9QTk9UU1VQUCIsIEVPUE5PVFNVUFApOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFT1ZFUkZMT1ciLCBFT1ZFUkZMT1cpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFUEVSTSIsIEVQRVJNKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRVBJUEUiLCBFUElQRSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVQUk9UTyIsIEVQUk9UTyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVQUk9UT05PU1VQUE9SVCIsIEVQUk9UT05PU1VQUE9SVCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVQUk9UT1RZUEUiLCBFUFJPVE9UWVBFKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRVJBTkdFIiwgRVJBTkdFKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRVJPRlMiLCBFUk9GUyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVTUElQRSIsIEVTUElQRSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVTUkNIIiwgRVNSQ0gpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFU1RBTEUiLCBFU1RBTEUpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFVElNRSIsIEVUSU1FKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRVRJTUVET1VUIiwgRVRJTUVET1VUKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRVRYVEJTWSIsIEVUWFRCU1kpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJFV09VTERCTE9DSyIsIEVXT1VMREJMT0NLKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRVhERVYiLCBFWERFVik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVYSVRfRkFJTFVSRSIsIEVYSVRfRkFJTFVSRSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkVYSVRfU1VDQ0VTUyIsIEVYSVRfU1VDQ0VTUyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkZEX0NMT0VYRUMiLCBGRF9DTE9FWEVDKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRklPTlJFQUQiLCBGSU9OUkVBRCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkZfRFVQRkQiLCBGX0RVUEZEKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRl9HRVRGRCIsIEZfR0VURkQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJGX0dFVEZMIiwgRl9HRVRGTCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkZfR0VUTEsiLCBGX0dFVExLKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRl9HRVRMSzY0IiwgRl9HRVRMSzY0KTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRl9HRVRPV04iLCBGX0dFVE9XTik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkZfT0siLCBGX09LKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRl9SRExDSyIsIEZfUkRMQ0spOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJGX1NFVEZEIiwgRl9TRVRGRCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIkZfU0VURkwiLCBGX1NFVEZMKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRl9TRVRMSyIsIEZfU0VUTEspOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJGX1NFVExLNjQiLCBGX1NFVExLNjQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJGX1NFVExLVyIsIEZfU0VUTEtXKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRl9TRVRMS1c2NCIsIEZfU0VUTEtXNjQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJGX1NFVE9XTiIsIEZfU0VUT1dOKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiRl9VTkxDSyIsIEZfVU5MQ0spOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJGX1dSTENLIiwgRl9XUkxDSyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklGRl9BTExNVUxUSSIsIElGRl9BTExNVUxUSSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklGRl9BVVRPTUVESUEiLCBJRkZfQVVUT01FRElBKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiSUZGX0JST0FEQ0FTVCIsIElGRl9CUk9BRENBU1QpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJJRkZfREVCVUciLCBJRkZfREVCVUcpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJJRkZfRFlOQU1JQyIsIElGRl9EWU5BTUlDKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiSUZGX0xPT1BCQUNLIiwgSUZGX0xPT1BCQUNLKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiSUZGX01BU1RFUiIsIElGRl9NQVNURVIpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJJRkZfTVVMVElDQVNUIiwgSUZGX01VTFRJQ0FTVCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklGRl9OT0FSUCIsIElGRl9OT0FSUCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklGRl9OT1RSQUlMRVJTIiwgSUZGX05PVFJBSUxFUlMpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJJRkZfUE9JTlRPUE9JTlQiLCBJRkZfUE9JTlRPUE9JTlQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJJRkZfUE9SVFNFTCIsIElGRl9QT1JUU0VMKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiSUZGX1BST01JU0MiLCBJRkZfUFJPTUlTQyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklGRl9SVU5OSU5HIiwgSUZGX1JVTk5JTkcpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJJRkZfU0xBVkUiLCBJRkZfU0xBVkUpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJJRkZfVVAiLCBJRkZfVVApOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJJUFBST1RPX0lDTVAiLCBJUFBST1RPX0lDTVApOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJJUFBST1RPX0lQIiwgSVBQUk9UT19JUCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklQUFJPVE9fSVBWNiIsIElQUFJPVE9fSVBWNik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklQUFJPVE9fUkFXIiwgSVBQUk9UT19SQVcpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJJUFBST1RPX1RDUCIsIElQUFJPVE9fVENQKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiSVBQUk9UT19VRFAiLCBJUFBST1RPX1VEUCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklQVjZfQ0hFQ0tTVU0iLCBJUFY2X0NIRUNLU1VNKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiSVBWNl9NVUxUSUNBU1RfSE9QUyIsIElQVjZfTVVMVElDQVNUX0hPUFMpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJJUFY2X01VTFRJQ0FTVF9JRiIsIElQVjZfTVVMVElDQVNUX0lGKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiSVBWNl9NVUxUSUNBU1RfTE9PUCIsIElQVjZfTVVMVElDQVNUX0xPT1ApOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJJUFY2X1JFQ1ZEU1RPUFRTIiwgSVBWNl9SRUNWRFNUT1BUUyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklQVjZfUkVDVkhPUExJTUlUIiwgSVBWNl9SRUNWSE9QTElNSVQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJJUFY2X1JFQ1ZIT1BPUFRTIiwgSVBWNl9SRUNWSE9QT1BUUyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklQVjZfUkVDVlBLVElORk8iLCBJUFY2X1JFQ1ZQS1RJTkZPKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiSVBWNl9SRUNWUlRIRFIiLCBJUFY2X1JFQ1ZSVEhEUik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklQVjZfUkVDVlRDTEFTUyIsIElQVjZfUkVDVlRDTEFTUyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklQVjZfVENMQVNTIiwgSVBWNl9UQ0xBU1MpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJJUFY2X1VOSUNBU1RfSE9QUyIsIElQVjZfVU5JQ0FTVF9IT1BTKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiSVBWNl9WNk9OTFkiLCBJUFY2X1Y2T05MWSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklQX01VTFRJQ0FTVF9JRiIsIElQX01VTFRJQ0FTVF9JRik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklQX01VTFRJQ0FTVF9MT09QIiwgSVBfTVVMVElDQVNUX0xPT1ApOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJJUF9NVUxUSUNBU1RfVFRMIiwgSVBfTVVMVElDQVNUX1RUTCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklQX1RPUyIsIElQX1RPUyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIklQX1RUTCIsIElQX1RUTCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIk1BUF9GSVhFRCIsIE1BUF9GSVhFRCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIk1BUF9QUklWQVRFIiwgTUFQX1BSSVZBVEUpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJNQVBfU0hBUkVEIiwgTUFQX1NIQVJFRCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIk1DQVNUX0pPSU5fR1JPVVAiLCBNQ0FTVF9KT0lOX0dST1VQKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiTUNBU1RfTEVBVkVfR1JPVVAiLCBNQ0FTVF9MRUFWRV9HUk9VUCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIk1DTF9DVVJSRU5UIiwgTUNMX0NVUlJFTlQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJNQ0xfRlVUVVJFIiwgTUNMX0ZVVFVSRSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIk1TR19DVFJVTkMiLCBNU0dfQ1RSVU5DKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiTVNHX0RPTlRST1VURSIsIE1TR19ET05UUk9VVEUpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJNU0dfRU9SIiwgTVNHX0VPUik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIk1TR19PT0IiLCBNU0dfT09CKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiTVNHX1BFRUsiLCBNU0dfUEVFSyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIk1TR19UUlVOQyIsIE1TR19UUlVOQyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIk1TR19XQUlUQUxMIiwgTVNHX1dBSVRBTEwpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJNU19BU1lOQyIsIE1TX0FTWU5DKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiTVNfSU5WQUxJREFURSIsIE1TX0lOVkFMSURBVEUpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJNU19TWU5DIiwgTVNfU1lOQyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIk5JX0RHUkFNIiwgTklfREdSQU0pOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJOSV9OQU1FUkVRRCIsIE5JX05BTUVSRVFEKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiTklfTk9GUUROIiwgTklfTk9GUUROKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiTklfTlVNRVJJQ0hPU1QiLCBOSV9OVU1FUklDSE9TVCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIk5JX05VTUVSSUNTRVJWIiwgTklfTlVNRVJJQ1NFUlYpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJPX0FDQ01PREUiLCBPX0FDQ01PREUpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJPX0FQUEVORCIsIE9fQVBQRU5EKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiT19DUkVBVCIsIE9fQ1JFQVQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJPX0VYQ0wiLCBPX0VYQ0wpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJPX05PQ1RUWSIsIE9fTk9DVFRZKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiT19OT05CTE9DSyIsIE9fTk9OQkxPQ0spOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJPX1JET05MWSIsIE9fUkRPTkxZKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiT19SRFdSIiwgT19SRFdSKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiT19TWU5DIiwgT19TWU5DKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiT19UUlVOQyIsIE9fVFJVTkMpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJPX1dST05MWSIsIE9fV1JPTkxZKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiUE9MTEVSUiIsIFBPTExFUlIpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJQT0xMSFVQIiwgUE9MTEhVUCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlBPTExJTiIsIFBPTExJTik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlBPTExOVkFMIiwgUE9MTE5WQUwpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJQT0xMT1VUIiwgUE9MTE9VVCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlBPTExQUkkiLCBQT0xMUFJJKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiUE9MTFJEQkFORCIsIFBPTExSREJBTkQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJQT0xMUkROT1JNIiwgUE9MTFJETk9STSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlBPTExXUkJBTkQiLCBQT0xMV1JCQU5EKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiUE9MTFdSTk9STSIsIFBPTExXUk5PUk0pOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJQUk9UX0VYRUMiLCBQUk9UX0VYRUMpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJQUk9UX05PTkUiLCBQUk9UX05PTkUpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJQUk9UX1JFQUQiLCBQUk9UX1JFQUQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJQUk9UX1dSSVRFIiwgUFJPVF9XUklURSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlJfT0siLCBSX09LKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0VFS19DVVIiLCBTRUVLX0NVUik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNFRUtfRU5EIiwgU0VFS19FTkQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTRUVLX1NFVCIsIFNFRUtfU0VUKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0hVVF9SRCIsIFNIVVRfUkQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTSFVUX1JEV1IiLCBTSFVUX1JEV1IpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTSFVUX1dSIiwgU0hVVF9XUik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNJR0FCUlQiLCBTSUdBQlJUKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0lHQUxSTSIsIFNJR0FMUk0pOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTSUdCVVMiLCBTSUdCVVMpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTSUdDSExEIiwgU0lHQ0hMRCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNJR0NPTlQiLCBTSUdDT05UKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0lHRlBFIiwgU0lHRlBFKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0lHSFVQIiwgU0lHSFVQKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0lHSUxMIiwgU0lHSUxMKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0lHSU5UIiwgU0lHSU5UKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0lHSU8iLCBTSUdJTyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNJR0tJTEwiLCBTSUdLSUxMKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0lHUElQRSIsIFNJR1BJUEUpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTSUdQUk9GIiwgU0lHUFJPRik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNJR1BXUiIsIFNJR1BXUik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNJR1FVSVQiLCBTSUdRVUlUKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0lHUlRNQVgiLCBTSUdSVE1BWCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNJR1JUTUlOIiwgU0lHUlRNSU4pOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTSUdTRUdWIiwgU0lHU0VHVik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNJR1NUS0ZMVCIsIFNJR1NUS0ZMVCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNJR1NUT1AiLCBTSUdTVE9QKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0lHU1lTIiwgU0lHU1lTKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0lHVEVSTSIsIFNJR1RFUk0pOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTSUdUUkFQIiwgU0lHVFJBUCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNJR1RTVFAiLCBTSUdUU1RQKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0lHVFRJTiIsIFNJR1RUSU4pOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTSUdUVE9VIiwgU0lHVFRPVSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNJR1VSRyIsIFNJR1VSRyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNJR1VTUjEiLCBTSUdVU1IxKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0lHVVNSMiIsIFNJR1VTUjIpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTSUdWVEFMUk0iLCBTSUdWVEFMUk0pOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTSUdXSU5DSCIsIFNJR1dJTkNIKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0lHWENQVSIsIFNJR1hDUFUpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTSUdYRlNaIiwgU0lHWEZTWik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNJT0NHSUZBRERSIiwgU0lPQ0dJRkFERFIpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTSU9DR0lGQlJEQUREUiIsIFNJT0NHSUZCUkRBRERSKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU0lPQ0dJRkRTVEFERFIiLCBTSU9DR0lGRFNUQUREUik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNJT0NHSUZORVRNQVNLIiwgU0lPQ0dJRk5FVE1BU0spOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTT0NLX0RHUkFNIiwgU09DS19ER1JBTSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNPQ0tfUkFXIiwgU09DS19SQVcpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTT0NLX1NFUVBBQ0tFVCIsIFNPQ0tfU0VRUEFDS0VUKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU09DS19TVFJFQU0iLCBTT0NLX1NUUkVBTSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNPTF9TT0NLRVQiLCBTT0xfU09DS0VUKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU09fQklORFRPREVWSUNFIiwgU09fQklORFRPREVWSUNFKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU09fQlJPQURDQVNUIiwgU09fQlJPQURDQVNUKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU09fREVCVUciLCBTT19ERUJVRyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNPX0RPTlRST1VURSIsIFNPX0RPTlRST1VURSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNPX0VSUk9SIiwgU09fRVJST1IpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTT19LRUVQQUxJVkUiLCBTT19LRUVQQUxJVkUpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTT19MSU5HRVIiLCBTT19MSU5HRVIpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTT19PT0JJTkxJTkUiLCBTT19PT0JJTkxJTkUpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTT19SQ1ZCVUYiLCBTT19SQ1ZCVUYpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTT19SQ1ZMT1dBVCIsIFNPX1JDVkxPV0FUKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU09fUkNWVElNRU8iLCBTT19SQ1ZUSU1FTyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNPX1JFVVNFQUREUiIsIFNPX1JFVVNFQUREUik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNPX1NOREJVRiIsIFNPX1NOREJVRik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNPX1NORExPV0FUIiwgU09fU05ETE9XQVQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTT19TTkRUSU1FTyIsIFNPX1NORFRJTUVPKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU09fVFlQRSIsIFNPX1RZUEUpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTVERFUlJfRklMRU5PIiwgU1RERVJSX0ZJTEVOTyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNURElOX0ZJTEVOTyIsIFNURElOX0ZJTEVOTyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNURE9VVF9GSUxFTk8iLCBTVERPVVRfRklMRU5PKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU19JRkJMSyIsIFNfSUZCTEspOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTX0lGQ0hSIiwgU19JRkNIUik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNfSUZESVIiLCBTX0lGRElSKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU19JRklGTyIsIFNfSUZJRk8pOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTX0lGTE5LIiwgU19JRkxOSyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNfSUZNVCIsIFNfSUZNVCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNfSUZSRUciLCBTX0lGUkVHKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU19JRlNPQ0siLCBTX0lGU09DSyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNfSVJHUlAiLCBTX0lSR1JQKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU19JUk9USCIsIFNfSVJPVEgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTX0lSVVNSIiwgU19JUlVTUik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNfSVJXWEciLCBTX0lSV1hHKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU19JUldYTyIsIFNfSVJXWE8pOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTX0lSV1hVIiwgU19JUldYVSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNfSVNHSUQiLCBTX0lTR0lEKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU19JU1VJRCIsIFNfSVNVSUQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTX0lTVlRYIiwgU19JU1ZUWCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNfSVdHUlAiLCBTX0lXR1JQKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU19JV09USCIsIFNfSVdPVEgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTX0lXVVNSIiwgU19JV1VTUik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlNfSVhHUlAiLCBTX0lYR1JQKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiU19JWE9USCIsIFNfSVhPVEgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJTX0lYVVNSIiwgU19JWFVTUik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlRDUF9OT0RFTEFZIiwgVENQX05PREVMQVkpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJXQ09OVElOVUVEIiwgV0NPTlRJTlVFRCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIldFWElURUQiLCBXRVhJVEVEKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiV05PSEFORyIsIFdOT0hBTkcpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJXTk9XQUlUIiwgV05PV0FJVCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIldTVE9QUEVEIiwgV1NUT1BQRUQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJXVU5UUkFDRUQiLCBXVU5UUkFDRUQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJXX09LIiwgV19PSyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIlhfT0siLCBYX09LKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDXzJfQ0hBUl9URVJNIiwgX1NDXzJfQ0hBUl9URVJNKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDXzJfQ19CSU5EIiwgX1NDXzJfQ19CSU5EKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDXzJfQ19ERVYiLCBfU0NfMl9DX0RFVik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ18yX0NfVkVSU0lPTiIsIF9TQ18yX0NfVkVSU0lPTik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ18yX0ZPUlRfREVWIiwgX1NDXzJfRk9SVF9ERVYpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfMl9GT1JUX1JVTiIsIF9TQ18yX0ZPUlRfUlVOKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDXzJfTE9DQUxFREVGIiwgX1NDXzJfTE9DQUxFREVGKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDXzJfU1dfREVWIiwgX1NDXzJfU1dfREVWKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDXzJfVVBFIiwgX1NDXzJfVVBFKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDXzJfVkVSU0lPTiIsIF9TQ18yX1ZFUlNJT04pOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfQUlPX0xJU1RJT19NQVgiLCBfU0NfQUlPX0xJU1RJT19NQVgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfQUlPX01BWCIsIF9TQ19BSU9fTUFYKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX0FJT19QUklPX0RFTFRBX01BWCIsIF9TQ19BSU9fUFJJT19ERUxUQV9NQVgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfQVJHX01BWCIsIF9TQ19BUkdfTUFYKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX0FTWU5DSFJPTk9VU19JTyIsIF9TQ19BU1lOQ0hST05PVVNfSU8pOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfQVRFWElUX01BWCIsIF9TQ19BVEVYSVRfTUFYKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX0FWUEhZU19QQUdFUyIsIF9TQ19BVlBIWVNfUEFHRVMpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfQkNfQkFTRV9NQVgiLCBfU0NfQkNfQkFTRV9NQVgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfQkNfRElNX01BWCIsIF9TQ19CQ19ESU1fTUFYKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX0JDX1NDQUxFX01BWCIsIF9TQ19CQ19TQ0FMRV9NQVgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfQkNfU1RSSU5HX01BWCIsIF9TQ19CQ19TVFJJTkdfTUFYKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX0NISUxEX01BWCIsIF9TQ19DSElMRF9NQVgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfQ0xLX1RDSyIsIF9TQ19DTEtfVENLKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX0NPTExfV0VJR0hUU19NQVgiLCBfU0NfQ09MTF9XRUlHSFRTX01BWCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19ERUxBWVRJTUVSX01BWCIsIF9TQ19ERUxBWVRJTUVSX01BWCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19FWFBSX05FU1RfTUFYIiwgX1NDX0VYUFJfTkVTVF9NQVgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfRlNZTkMiLCBfU0NfRlNZTkMpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfR0VUR1JfUl9TSVpFX01BWCIsIF9TQ19HRVRHUl9SX1NJWkVfTUFYKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX0dFVFBXX1JfU0laRV9NQVgiLCBfU0NfR0VUUFdfUl9TSVpFX01BWCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19JT1ZfTUFYIiwgX1NDX0lPVl9NQVgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfSk9CX0NPTlRST0wiLCBfU0NfSk9CX0NPTlRST0wpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfTElORV9NQVgiLCBfU0NfTElORV9NQVgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfTE9HSU5fTkFNRV9NQVgiLCBfU0NfTE9HSU5fTkFNRV9NQVgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfTUFQUEVEX0ZJTEVTIiwgX1NDX01BUFBFRF9GSUxFUyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19NRU1MT0NLIiwgX1NDX01FTUxPQ0spOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfTUVNTE9DS19SQU5HRSIsIF9TQ19NRU1MT0NLX1JBTkdFKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX01FTU9SWV9QUk9URUNUSU9OIiwgX1NDX01FTU9SWV9QUk9URUNUSU9OKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX01FU1NBR0VfUEFTU0lORyIsIF9TQ19NRVNTQUdFX1BBU1NJTkcpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfTVFfT1BFTl9NQVgiLCBfU0NfTVFfT1BFTl9NQVgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfTVFfUFJJT19NQVgiLCBfU0NfTVFfUFJJT19NQVgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfTkdST1VQU19NQVgiLCBfU0NfTkdST1VQU19NQVgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfTlBST0NFU1NPUlNfQ09ORiIsIF9TQ19OUFJPQ0VTU09SU19DT05GKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX05QUk9DRVNTT1JTX09OTE4iLCBfU0NfTlBST0NFU1NPUlNfT05MTik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19PUEVOX01BWCIsIF9TQ19PUEVOX01BWCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19QQUdFU0laRSIsIF9TQ19QQUdFU0laRSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19QQUdFX1NJWkUiLCBfU0NfUEFHRV9TSVpFKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1BBU1NfTUFYIiwgX1NDX1BBU1NfTUFYKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1BIWVNfUEFHRVMiLCBfU0NfUEhZU19QQUdFUyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19QUklPUklUSVpFRF9JTyIsIF9TQ19QUklPUklUSVpFRF9JTyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19QUklPUklUWV9TQ0hFRFVMSU5HIiwgX1NDX1BSSU9SSVRZX1NDSEVEVUxJTkcpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfUkVBTFRJTUVfU0lHTkFMUyIsIF9TQ19SRUFMVElNRV9TSUdOQUxTKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1JFX0RVUF9NQVgiLCBfU0NfUkVfRFVQX01BWCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19SVFNJR19NQVgiLCBfU0NfUlRTSUdfTUFYKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1NBVkVEX0lEUyIsIF9TQ19TQVZFRF9JRFMpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfU0VNQVBIT1JFUyIsIF9TQ19TRU1BUEhPUkVTKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1NFTV9OU0VNU19NQVgiLCBfU0NfU0VNX05TRU1TX01BWCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19TRU1fVkFMVUVfTUFYIiwgX1NDX1NFTV9WQUxVRV9NQVgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfU0hBUkVEX01FTU9SWV9PQkpFQ1RTIiwgX1NDX1NIQVJFRF9NRU1PUllfT0JKRUNUUyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19TSUdRVUVVRV9NQVgiLCBfU0NfU0lHUVVFVUVfTUFYKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1NUUkVBTV9NQVgiLCBfU0NfU1RSRUFNX01BWCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19TWU5DSFJPTklaRURfSU8iLCBfU0NfU1lOQ0hST05JWkVEX0lPKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1RIUkVBRFMiLCBfU0NfVEhSRUFEUyk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19USFJFQURfQVRUUl9TVEFDS0FERFIiLCBfU0NfVEhSRUFEX0FUVFJfU1RBQ0tBRERSKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1RIUkVBRF9BVFRSX1NUQUNLU0laRSIsIF9TQ19USFJFQURfQVRUUl9TVEFDS1NJWkUpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfVEhSRUFEX0RFU1RSVUNUT1JfSVRFUkFUSU9OUyIsIF9TQ19USFJFQURfREVTVFJVQ1RPUl9JVEVSQVRJT05TKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1RIUkVBRF9LRVlTX01BWCIsIF9TQ19USFJFQURfS0VZU19NQVgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfVEhSRUFEX1BSSU9SSVRZX1NDSEVEVUxJTkciLCBfU0NfVEhSRUFEX1BSSU9SSVRZX1NDSEVEVUxJTkcpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfVEhSRUFEX1BSSU9fSU5IRVJJVCIsIF9TQ19USFJFQURfUFJJT19JTkhFUklUKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1RIUkVBRF9QUklPX1BST1RFQ1QiLCBfU0NfVEhSRUFEX1BSSU9fUFJPVEVDVCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19USFJFQURfU0FGRV9GVU5DVElPTlMiLCBfU0NfVEhSRUFEX1NBRkVfRlVOQ1RJT05TKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1RIUkVBRF9TVEFDS19NSU4iLCBfU0NfVEhSRUFEX1NUQUNLX01JTik7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19USFJFQURfVEhSRUFEU19NQVgiLCBfU0NfVEhSRUFEX1RIUkVBRFNfTUFYKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1RJTUVSUyIsIF9TQ19USU1FUlMpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfVElNRVJfTUFYIiwgX1NDX1RJTUVSX01BWCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19UVFlfTkFNRV9NQVgiLCBfU0NfVFRZX05BTUVfTUFYKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1RaTkFNRV9NQVgiLCBfU0NfVFpOQU1FX01BWCk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19WRVJTSU9OIiwgX1NDX1ZFUlNJT04pOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfWEJTNV9JTFAzMl9PRkYzMiIsIF9TQ19YQlM1X0lMUDMyX09GRjMyKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1hCUzVfSUxQMzJfT0ZGQklHIiwgX1NDX1hCUzVfSUxQMzJfT0ZGQklHKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1hCUzVfTFA2NF9PRkY2NCIsIF9TQ19YQlM1X0xQNjRfT0ZGNjQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfWEJTNV9MUEJJR19PRkZCSUciLCBfU0NfWEJTNV9MUEJJR19PRkZCSUcpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfWE9QRU5fQ1JZUFQiLCBfU0NfWE9QRU5fQ1JZUFQpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfWE9QRU5fRU5IX0kxOE4iLCBfU0NfWE9QRU5fRU5IX0kxOE4pOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfWE9QRU5fTEVHQUNZIiwgX1NDX1hPUEVOX0xFR0FDWSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19YT1BFTl9SRUFMVElNRSIsIF9TQ19YT1BFTl9SRUFMVElNRSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19YT1BFTl9SRUFMVElNRV9USFJFQURTIiwgX1NDX1hPUEVOX1JFQUxUSU1FX1RIUkVBRFMpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfWE9QRU5fU0hNIiwgX1NDX1hPUEVOX1NITSk7CisgICAgaW5pdENvbnN0YW50KGVudiwgYywgIl9TQ19YT1BFTl9VTklYIiwgX1NDX1hPUEVOX1VOSVgpOworICAgIGluaXRDb25zdGFudChlbnYsIGMsICJfU0NfWE9QRU5fVkVSU0lPTiIsIF9TQ19YT1BFTl9WRVJTSU9OKTsKKyAgICBpbml0Q29uc3RhbnQoZW52LCBjLCAiX1NDX1hPUEVOX1hDVV9WRVJTSU9OIiwgX1NDX1hPUEVOX1hDVV9WRVJTSU9OKTsKK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBnTWV0aG9kc1tdID0geworICAgIE5BVElWRV9NRVRIT0QoT3NDb25zdGFudHMsIGluaXRDb25zdGFudHMsICIoKVYiKSwKK307CitpbnQgcmVnaXN0ZXJfbGliY29yZV9pb19Pc0NvbnN0YW50cyhKTklFbnYqIGVudikgeworICAgIHJldHVybiBqbmlSZWdpc3Rlck5hdGl2ZU1ldGhvZHMoZW52LCAibGliY29yZS9pby9Pc0NvbnN0YW50cyIsIGdNZXRob2RzLCBORUxFTShnTWV0aG9kcykpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pb19Qb3NpeC5jcHAgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9saWJjb3JlX2lvX1Bvc2l4LmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOTBjNTkzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvbGliY29yZV9pb19Qb3NpeC5jcHAKQEAgLTAsMCArMSwxMzA5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2RlZmluZSBMT0dfVEFHICJQb3NpeCIKKworI2luY2x1ZGUgIkFzeW5jaHJvbm91c1NvY2tldENsb3NlTW9uaXRvci5oIgorI2luY2x1ZGUgIkpOSUhlbHAuaCIKKyNpbmNsdWRlICJKbmlDb25zdGFudHMuaCIKKyNpbmNsdWRlICJKbmlFeGNlcHRpb24uaCIKKyNpbmNsdWRlICJOZXR3b3JrVXRpbGl0aWVzLmgiCisjaW5jbHVkZSAiU2NvcGVkQnl0ZXMuaCIKKyNpbmNsdWRlICJTY29wZWRMb2NhbFJlZi5oIgorI2luY2x1ZGUgIlNjb3BlZFByaW1pdGl2ZUFycmF5LmgiCisjaW5jbHVkZSAiU2NvcGVkVXRmQ2hhcnMuaCIKKyNpbmNsdWRlICJTdGF0aWNBc3NlcnQuaCIKKyNpbmNsdWRlICJVbmlxdWVQdHIuaCIKKyNpbmNsdWRlICJ0b1N0cmluZ0FycmF5LmgiCisKKyNpbmNsdWRlIDxhcnBhL2luZXQuaD4KKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8bmV0L2lmLmg+CisjaW5jbHVkZSA8bmV0ZGIuaD4KKyNpbmNsdWRlIDxuZXRpbmV0L2luLmg+CisjaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgorI2luY2x1ZGUgPHBvbGwuaD4KKyNpbmNsdWRlIDxwd2QuaD4KKyNpbmNsdWRlIDxzaWduYWwuaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzeXMvaW9jdGwuaD4KKyNpbmNsdWRlIDxzeXMvbW1hbi5oPgorI2luY2x1ZGUgPHN5cy9zZW5kZmlsZS5oPgorI2luY2x1ZGUgPHN5cy9zb2NrZXQuaD4KKyNpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CisjaW5jbHVkZSA8c3lzL3N0YXQuaD4KKyNpbmNsdWRlIDxzeXMvdGltZS5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHN5cy91aW8uaD4KKyNpbmNsdWRlIDxzeXMvdXRzbmFtZS5oPgorI2luY2x1ZGUgPHN5cy92ZnMuaD4gLy8gQmlvbmljIGRvZXNuJ3QgaGF2ZSA8c3lzL3N0YXR2ZnMuaD4KKyNpbmNsdWRlIDxzeXMvd2FpdC5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorCisjZGVmaW5lIFRPX0pBVkFfU1RSSU5HKE5BTUUsIEVYUCkgXAorICAgICAgICBqc3RyaW5nIE5BTUUgPSBlbnYtPk5ld1N0cmluZ1VURihFWFApOyBcCisgICAgICAgIGlmIChOQU1FID09IE5VTEwpIHJldHVybiBOVUxMOworCitzdHJ1Y3QgYWRkcmluZm9fZGVsZXRlciB7CisgICAgdm9pZCBvcGVyYXRvcigpKGFkZHJpbmZvKiBwKSBjb25zdCB7CisgICAgICAgIGlmIChwICE9IE5VTEwpIHsgLy8gYmlvbmljJ3MgZnJlZWFkZHJpbmZvKDMpIGNyYXNoZXMgd2hlbiBwYXNzZWQgTlVMTC4KKyAgICAgICAgICAgIGZyZWVhZGRyaW5mbyhwKTsKKyAgICAgICAgfQorICAgIH0KK307CisKKy8qKgorICogVXNlZCB0byByZXRyeSBzeXNjYWxscyB0aGF0IGNhbiByZXR1cm4gRUlOVFIuIFRoaXMgZGlmZmVycyBmcm9tIFRFTVBfRkFJTFVSRV9SRVRSWSBpbiB0aGF0CisgKiBpdCBhbHNvIGNvbnNpZGVycyB0aGUgY2FzZSB3aGVyZSB0aGUgcmVhc29uIGZvciBmYWlsdXJlIGlzIHRoYXQgYW5vdGhlciB0aHJlYWQgY2FsbGVkCisgKiBTb2NrZXQuY2xvc2UuCisgKgorICogQXNzdW1lcyAnSk5JRW52KiBlbnYnIGFuZCAnam9iamVjdCBqYXZhRmQnICh3aGljaCBpcyBhIGphdmEuaW8uRmlsZURlc2NyaXB0b3IpIGFyZSBpbiBzY29wZS4KKyAqCisgKiBSZXR1cm5zIHRoZSByZXN1bHQgb2YgJ2V4cCcsIHRob3VnaCBhIEphdmEgZXhjZXB0aW9uIHdpbGwgYmUgcGVuZGluZyBpZiB0aGUgcmVzdWx0IGlzIC0xLgorICoKKyAqIENvcnJlY3QgdXNhZ2UgbG9va3MgbGlrZSB0aGlzOgorICoKKyAqIHZvaWQgUG9zaXhfc3lzY2FsbChKTklFbnYqIGVudiwgam9iamVjdCBqYXZhRmQsIC4uLikgeworICogICAgIC4uLgorICogICAgIGludCBmZDsKKyAqICAgICBORVRfRkFJTFVSRV9SRVRSWSgic3lzY2FsbCIsIHN5c2NhbGwoZmQsIC4uLikpOyAvLyBUaHJvd3Mgb24gZXJyb3IuCisgKiB9CisgKi8KKyNkZWZpbmUgTkVUX0ZBSUxVUkVfUkVUUlkoc3lzY2FsbF9uYW1lLCBleHApICh7IFwKKyAgICB0eXBlb2YgKGV4cCkgX3JjID0gLTE7IFwKKyAgICBkbyB7IFwKKyAgICAgICAgeyBcCisgICAgICAgICAgICBmZCA9IGpuaUdldEZERnJvbUZpbGVEZXNjcmlwdG9yKGVudiwgamF2YUZkKTsgXAorICAgICAgICAgICAgQXN5bmNocm9ub3VzU29ja2V0Q2xvc2VNb25pdG9yIG1vbml0b3IoZmQpOyBcCisgICAgICAgICAgICBfcmMgPSAoZXhwKTsgXAorICAgICAgICB9IFwKKyAgICAgICAgaWYgKF9yYyA9PSAtMSkgeyBcCisgICAgICAgICAgICBpZiAoam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpID09IC0xKSB7IFwKKyAgICAgICAgICAgICAgICBqbmlUaHJvd0V4Y2VwdGlvbihlbnYsICJqYXZhL25ldC9Tb2NrZXRFeGNlcHRpb24iLCAiU29ja2V0IGNsb3NlZCIpOyBcCisgICAgICAgICAgICAgICAgYnJlYWs7IFwKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZXJybm8gIT0gRUlOVFIpIHsgXAorICAgICAgICAgICAgICAgIHRocm93RXJybm9FeGNlcHRpb24oZW52LCBzeXNjYWxsX25hbWUpOyBcCisgICAgICAgICAgICAgICAgYnJlYWs7IFwKKyAgICAgICAgICAgIH0gXAorICAgICAgICB9IFwKKyAgICB9IHdoaWxlIChfcmMgPT0gLTEpOyBcCisgICAgX3JjOyB9KQorCitzdGF0aWMgdm9pZCB0aHJvd0V4Y2VwdGlvbihKTklFbnYqIGVudiwgamNsYXNzIGV4Y2VwdGlvbkNsYXNzLCBqbWV0aG9kSUQgY3RvcjMsIGptZXRob2RJRCBjdG9yMiwKKyAgICAgICAgY29uc3QgY2hhciogZnVuY3Rpb25OYW1lLCBpbnQgZXJyb3IpIHsKKyAgICBqdGhyb3dhYmxlIGNhdXNlID0gTlVMTDsKKyAgICBpZiAoZW52LT5FeGNlcHRpb25DaGVjaygpKSB7CisgICAgICAgIGNhdXNlID0gZW52LT5FeGNlcHRpb25PY2N1cnJlZCgpOworICAgICAgICBlbnYtPkV4Y2VwdGlvbkNsZWFyKCk7CisgICAgfQorCisgICAgU2NvcGVkTG9jYWxSZWY8anN0cmluZz4gZGV0YWlsTWVzc2FnZShlbnYsIGVudi0+TmV3U3RyaW5nVVRGKGZ1bmN0aW9uTmFtZSkpOworICAgIGlmIChkZXRhaWxNZXNzYWdlLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgLy8gTm90IHJlYWxseSBtdWNoIHdlIGNhbiBkbyBoZXJlLiBXZSdyZSBwcm9iYWJseSBkZWFkIGluIHRoZSB3YXRlciwKKyAgICAgICAgLy8gYnV0IGxldCdzIHRyeSB0byBzdHVtYmxlIG9uLi4uCisgICAgICAgIGVudi0+RXhjZXB0aW9uQ2xlYXIoKTsKKyAgICB9CisKKyAgICBqb2JqZWN0IGV4Y2VwdGlvbjsKKyAgICBpZiAoY2F1c2UgIT0gTlVMTCkgeworICAgICAgICBleGNlcHRpb24gPSBlbnYtPk5ld09iamVjdChleGNlcHRpb25DbGFzcywgY3RvcjMsIGRldGFpbE1lc3NhZ2UuZ2V0KCksIGVycm9yLCBjYXVzZSk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgZXhjZXB0aW9uID0gZW52LT5OZXdPYmplY3QoZXhjZXB0aW9uQ2xhc3MsIGN0b3IyLCBkZXRhaWxNZXNzYWdlLmdldCgpLCBlcnJvcik7CisgICAgfQorICAgIGVudi0+VGhyb3cocmVpbnRlcnByZXRfY2FzdDxqdGhyb3dhYmxlPihleGNlcHRpb24pKTsKK30KKworc3RhdGljIHZvaWQgdGhyb3dFcnJub0V4Y2VwdGlvbihKTklFbnYqIGVudiwgY29uc3QgY2hhciogZnVuY3Rpb25OYW1lKSB7CisgICAgaW50IGVycm9yID0gZXJybm87CisgICAgc3RhdGljIGptZXRob2RJRCBjdG9yMyA9IGVudi0+R2V0TWV0aG9kSUQoSm5pQ29uc3RhbnRzOjplcnJub0V4Y2VwdGlvbkNsYXNzLAorICAgICAgICAgICAgIjxpbml0PiIsICIoTGphdmEvbGFuZy9TdHJpbmc7SUxqYXZhL2xhbmcvVGhyb3dhYmxlOylWIik7CisgICAgc3RhdGljIGptZXRob2RJRCBjdG9yMiA9IGVudi0+R2V0TWV0aG9kSUQoSm5pQ29uc3RhbnRzOjplcnJub0V4Y2VwdGlvbkNsYXNzLAorICAgICAgICAgICAgIjxpbml0PiIsICIoTGphdmEvbGFuZy9TdHJpbmc7SSlWIik7CisgICAgdGhyb3dFeGNlcHRpb24oZW52LCBKbmlDb25zdGFudHM6OmVycm5vRXhjZXB0aW9uQ2xhc3MsIGN0b3IzLCBjdG9yMiwgZnVuY3Rpb25OYW1lLCBlcnJvcik7Cit9CisKK3N0YXRpYyB2b2lkIHRocm93R2FpRXhjZXB0aW9uKEpOSUVudiogZW52LCBjb25zdCBjaGFyKiBmdW5jdGlvbk5hbWUsIGludCBlcnJvcikgeworICAgIGlmIChlcnJvciA9PSBFQUlfU1lTVEVNKSB7CisgICAgICAgIC8vIEVBSV9TWVNURU0gbWVhbnMgImxvb2sgYXQgZXJybm8gaW5zdGVhZCIsIHNvIHdlIHdhbnQgb3VyIEdhaUV4Y2VwdGlvbiB0byBoYXZlIHRoZQorICAgICAgICAvLyByZWxldmFudCBFcnJub0V4Y2VwdGlvbiBhcyBpdHMgY2F1c2UuCisgICAgICAgIHRocm93RXJybm9FeGNlcHRpb24oZW52LCBmdW5jdGlvbk5hbWUpOworICAgICAgICAvLyBEZWxpYmVyYXRlbHkgZmFsbCB0aHJvdWdoIHRvIHRocm93IGFub3RoZXIgZXhjZXB0aW9uLi4uCisgICAgfQorICAgIHN0YXRpYyBqbWV0aG9kSUQgY3RvcjMgPSBlbnYtPkdldE1ldGhvZElEKEpuaUNvbnN0YW50czo6Z2FpRXhjZXB0aW9uQ2xhc3MsCisgICAgICAgICAgICAiPGluaXQ+IiwgIihMamF2YS9sYW5nL1N0cmluZztJTGphdmEvbGFuZy9UaHJvd2FibGU7KVYiKTsKKyAgICBzdGF0aWMgam1ldGhvZElEIGN0b3IyID0gZW52LT5HZXRNZXRob2RJRChKbmlDb25zdGFudHM6OmdhaUV4Y2VwdGlvbkNsYXNzLAorICAgICAgICAgICAgIjxpbml0PiIsICIoTGphdmEvbGFuZy9TdHJpbmc7SSlWIik7CisgICAgdGhyb3dFeGNlcHRpb24oZW52LCBKbmlDb25zdGFudHM6OmdhaUV4Y2VwdGlvbkNsYXNzLCBjdG9yMywgY3RvcjIsIGZ1bmN0aW9uTmFtZSwgZXJyb3IpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgcmNfdD4KK3N0YXRpYyByY190IHRocm93SWZNaW51c09uZShKTklFbnYqIGVudiwgY29uc3QgY2hhciogbmFtZSwgcmNfdCByYykgeworICAgIGlmIChyYyA9PSByY190KC0xKSkgeworICAgICAgICB0aHJvd0Vycm5vRXhjZXB0aW9uKGVudiwgbmFtZSk7CisgICAgfQorICAgIHJldHVybiByYzsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFNjb3BlZFQ+CitjbGFzcyBJb1ZlYyB7CitwdWJsaWM6CisgICAgSW9WZWMoSk5JRW52KiBlbnYsIHNpemVfdCBidWZmZXJDb3VudCkgOiBtRW52KGVudiksIG1CdWZmZXJDb3VudChidWZmZXJDb3VudCkgeworICAgIH0KKworICAgIGJvb2wgaW5pdChqb2JqZWN0QXJyYXkgamF2YUJ1ZmZlcnMsIGppbnRBcnJheSBqYXZhT2Zmc2V0cywgamludEFycmF5IGphdmFCeXRlQ291bnRzKSB7CisgICAgICAgIC8vIFdlIGNhbid0IGRlbGV0ZSBvdXIgbG9jYWwgcmVmZXJlbmNlcyB1bnRpbCBhZnRlciB0aGUgSS9PLCBzbyBtYWtlIHN1cmUgd2UgaGF2ZSByb29tLgorICAgICAgICBpZiAobUVudi0+UHVzaExvY2FsRnJhbWUobUJ1ZmZlckNvdW50ICsgMTYpIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIFNjb3BlZEludEFycmF5Uk8gb2Zmc2V0cyhtRW52LCBqYXZhT2Zmc2V0cyk7CisgICAgICAgIGlmIChvZmZzZXRzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBTY29wZWRJbnRBcnJheVJPIGJ5dGVDb3VudHMobUVudiwgamF2YUJ5dGVDb3VudHMpOworICAgICAgICBpZiAoYnl0ZUNvdW50cy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgLy8gVE9ETzogTGludXggYWN0dWFsbHkgaGFzIGEgMTAyNCBidWZmZXIgbGltaXQuIGdsaWJjIHdvcmtzIGFyb3VuZCB0aGlzLCBhbmQgd2Ugc2hvdWxkIHRvby4KKyAgICAgICAgLy8gVE9ETzogeW91IGNhbiBxdWVyeSB0aGUgbGltaXQgYXQgcnVudGltZSB3aXRoIHN5c2NvbmYoX1NDX0lPVl9NQVgpLgorICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IG1CdWZmZXJDb3VudDsgKytpKSB7CisgICAgICAgICAgICBqb2JqZWN0IGJ1ZmZlciA9IG1FbnYtPkdldE9iamVjdEFycmF5RWxlbWVudChqYXZhQnVmZmVycywgaSk7IC8vIFdlIGtlZXAgdGhpcyBsb2NhbCByZWYuCisgICAgICAgICAgICBtU2NvcGVkQnVmZmVycy5wdXNoX2JhY2sobmV3IFNjb3BlZFQobUVudiwgYnVmZmVyKSk7CisgICAgICAgICAgICBqYnl0ZSogcHRyID0gY29uc3RfY2FzdDxqYnl0ZSo+KG1TY29wZWRCdWZmZXJzLmJhY2soKS0+Z2V0KCkpOworICAgICAgICAgICAgaWYgKHB0ciA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3RydWN0IGlvdmVjIGlvdjsKKyAgICAgICAgICAgIGlvdi5pb3ZfYmFzZSA9IHJlaW50ZXJwcmV0X2Nhc3Q8dm9pZCo+KHB0ciArIG9mZnNldHNbaV0pOworICAgICAgICAgICAgaW92Lmlvdl9sZW4gPSBieXRlQ291bnRzW2ldOworICAgICAgICAgICAgbUlvVmVjLnB1c2hfYmFjayhpb3YpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIH5Jb1ZlYygpIHsKKyAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBtU2NvcGVkQnVmZmVycy5zaXplKCk7ICsraSkgeworICAgICAgICAgICAgZGVsZXRlIG1TY29wZWRCdWZmZXJzW2ldOworICAgICAgICB9CisgICAgICAgIG1FbnYtPlBvcExvY2FsRnJhbWUoTlVMTCk7CisgICAgfQorCisgICAgaW92ZWMqIGdldCgpIHsKKyAgICAgICAgcmV0dXJuICZtSW9WZWNbMF07CisgICAgfQorCisgICAgc2l6ZV90IHNpemUoKSB7CisgICAgICAgIHJldHVybiBtQnVmZmVyQ291bnQ7CisgICAgfQorCitwcml2YXRlOgorICAgIEpOSUVudiogbUVudjsKKyAgICBzaXplX3QgbUJ1ZmZlckNvdW50OworICAgIHN0ZDo6dmVjdG9yPGlvdmVjPiBtSW9WZWM7CisgICAgc3RkOjp2ZWN0b3I8U2NvcGVkVCo+IG1TY29wZWRCdWZmZXJzOworfTsKKworc3RhdGljIGpvYmplY3QgbWFrZVNvY2tldEFkZHJlc3MoSk5JRW52KiBlbnYsIGNvbnN0IHNvY2thZGRyX3N0b3JhZ2UqIHNzKSB7CisgICAgLy8gVE9ETzogc3VwcG9ydCBBRl9VTklYIGFuZCBBRl9VTlNQRUMgKGFuZCBvdGhlciBmYW1pbGllcz8pCisgICAgamludCBwb3J0OworICAgIGpvYmplY3QgaW5ldEFkZHJlc3MgPSBzb2NrYWRkclRvSW5ldEFkZHJlc3MoZW52LCBzcywgJnBvcnQpOworICAgIGlmIChpbmV0QWRkcmVzcyA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBzdGF0aWMgam1ldGhvZElEIGN0b3IgPSBlbnYtPkdldE1ldGhvZElEKEpuaUNvbnN0YW50czo6aW5ldFNvY2tldEFkZHJlc3NDbGFzcywgIjxpbml0PiIsCisgICAgICAgICAgICAiKExqYXZhL25ldC9JbmV0QWRkcmVzcztJKVYiKTsKKyAgICByZXR1cm4gZW52LT5OZXdPYmplY3QoSm5pQ29uc3RhbnRzOjppbmV0U29ja2V0QWRkcmVzc0NsYXNzLCBjdG9yLCBpbmV0QWRkcmVzcywgcG9ydCk7Cit9CisKK3N0YXRpYyBqb2JqZWN0IG1ha2VTdHJ1Y3RQYXNzd2QoSk5JRW52KiBlbnYsIGNvbnN0IHN0cnVjdCBwYXNzd2QmIHB3KSB7CisgICAgVE9fSkFWQV9TVFJJTkcocHdfbmFtZSwgcHcucHdfbmFtZSk7CisgICAgVE9fSkFWQV9TVFJJTkcocHdfZGlyLCBwdy5wd19kaXIpOworICAgIFRPX0pBVkFfU1RSSU5HKHB3X3NoZWxsLCBwdy5wd19zaGVsbCk7CisgICAgc3RhdGljIGptZXRob2RJRCBjdG9yID0gZW52LT5HZXRNZXRob2RJRChKbmlDb25zdGFudHM6OnN0cnVjdFBhc3N3ZENsYXNzLCAiPGluaXQ+IiwKKyAgICAgICAgICAgICIoTGphdmEvbGFuZy9TdHJpbmc7SUlMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZzspViIpOworICAgIHJldHVybiBlbnYtPk5ld09iamVjdChKbmlDb25zdGFudHM6OnN0cnVjdFBhc3N3ZENsYXNzLCBjdG9yLAorICAgICAgICAgICAgcHdfbmFtZSwgc3RhdGljX2Nhc3Q8amludD4ocHcucHdfdWlkKSwgc3RhdGljX2Nhc3Q8amludD4ocHcucHdfZ2lkKSwgcHdfZGlyLCBwd19zaGVsbCk7Cit9CisKK3N0YXRpYyBqb2JqZWN0IG1ha2VTdHJ1Y3RTdGF0KEpOSUVudiogZW52LCBjb25zdCBzdHJ1Y3Qgc3RhdCYgc2IpIHsKKyAgICBzdGF0aWMgam1ldGhvZElEIGN0b3IgPSBlbnYtPkdldE1ldGhvZElEKEpuaUNvbnN0YW50czo6c3RydWN0U3RhdENsYXNzLCAiPGluaXQ+IiwKKyAgICAgICAgICAgICIoSkpJSklJSkpKSkpKSilWIik7CisgICAgcmV0dXJuIGVudi0+TmV3T2JqZWN0KEpuaUNvbnN0YW50czo6c3RydWN0U3RhdENsYXNzLCBjdG9yLAorICAgICAgICAgICAgc3RhdGljX2Nhc3Q8amxvbmc+KHNiLnN0X2RldiksIHN0YXRpY19jYXN0PGpsb25nPihzYi5zdF9pbm8pLAorICAgICAgICAgICAgc3RhdGljX2Nhc3Q8amludD4oc2Iuc3RfbW9kZSksIHN0YXRpY19jYXN0PGpsb25nPihzYi5zdF9ubGluayksCisgICAgICAgICAgICBzdGF0aWNfY2FzdDxqaW50PihzYi5zdF91aWQpLCBzdGF0aWNfY2FzdDxqaW50PihzYi5zdF9naWQpLAorICAgICAgICAgICAgc3RhdGljX2Nhc3Q8amxvbmc+KHNiLnN0X3JkZXYpLCBzdGF0aWNfY2FzdDxqbG9uZz4oc2Iuc3Rfc2l6ZSksCisgICAgICAgICAgICBzdGF0aWNfY2FzdDxqbG9uZz4oc2Iuc3RfYXRpbWUpLCBzdGF0aWNfY2FzdDxqbG9uZz4oc2Iuc3RfbXRpbWUpLAorICAgICAgICAgICAgc3RhdGljX2Nhc3Q8amxvbmc+KHNiLnN0X2N0aW1lKSwgc3RhdGljX2Nhc3Q8amxvbmc+KHNiLnN0X2Jsa3NpemUpLAorICAgICAgICAgICAgc3RhdGljX2Nhc3Q8amxvbmc+KHNiLnN0X2Jsb2NrcykpOworfQorCitzdGF0aWMgam9iamVjdCBtYWtlU3RydWN0U3RhdEZzKEpOSUVudiogZW52LCBjb25zdCBzdHJ1Y3Qgc3RhdGZzJiBzYikgeworICAgIFNUQVRJQ19BU1NFUlQoc2l6ZW9mKHNiLmZfYmF2YWlsKSA9PSBzaXplb2YoamxvbmcpLCBzdGF0ZnNfbm90XzY0X2JpdCk7CisgICAgU1RBVElDX0FTU0VSVChzaXplb2Yoc2IuZl9iZnJlZSkgPT0gc2l6ZW9mKGpsb25nKSwgc3RhdGZzX25vdF82NF9iaXQpOworICAgIFNUQVRJQ19BU1NFUlQoc2l6ZW9mKHNiLmZfYmxvY2tzKSA9PSBzaXplb2YoamxvbmcpLCBzdGF0ZnNfbm90XzY0X2JpdCk7CisKKyAgICBzdGF0aWMgam1ldGhvZElEIGN0b3IgPSBlbnYtPkdldE1ldGhvZElEKEpuaUNvbnN0YW50czo6c3RydWN0U3RhdEZzQ2xhc3MsICI8aW5pdD4iLAorICAgICAgICAgICAgIihKSkpKSkpKSilWIik7CisgICAgcmV0dXJuIGVudi0+TmV3T2JqZWN0KEpuaUNvbnN0YW50czo6c3RydWN0U3RhdEZzQ2xhc3MsIGN0b3IsIHN0YXRpY19jYXN0PGpsb25nPihzYi5mX2JzaXplKSwKKyAgICAgICAgICAgIHN0YXRpY19jYXN0PGpsb25nPihzYi5mX2Jsb2NrcyksIHN0YXRpY19jYXN0PGpsb25nPihzYi5mX2JmcmVlKSwKKyAgICAgICAgICAgIHN0YXRpY19jYXN0PGpsb25nPihzYi5mX2JhdmFpbCksIHN0YXRpY19jYXN0PGpsb25nPihzYi5mX2ZpbGVzKSwKKyAgICAgICAgICAgIHN0YXRpY19jYXN0PGpsb25nPihzYi5mX2ZmcmVlKSwgc3RhdGljX2Nhc3Q8amxvbmc+KHNiLmZfbmFtZWxlbiksCisgICAgICAgICAgICBzdGF0aWNfY2FzdDxqbG9uZz4oc2IuZl9mcnNpemUpKTsKK30KKworc3RhdGljIGpvYmplY3QgbWFrZVN0cnVjdExpbmdlcihKTklFbnYqIGVudiwgY29uc3Qgc3RydWN0IGxpbmdlciYgbCkgeworICAgIHN0YXRpYyBqbWV0aG9kSUQgY3RvciA9IGVudi0+R2V0TWV0aG9kSUQoSm5pQ29uc3RhbnRzOjpzdHJ1Y3RMaW5nZXJDbGFzcywgIjxpbml0PiIsICIoSUkpViIpOworICAgIHJldHVybiBlbnYtPk5ld09iamVjdChKbmlDb25zdGFudHM6OnN0cnVjdExpbmdlckNsYXNzLCBjdG9yLCBsLmxfb25vZmYsIGwubF9saW5nZXIpOworfQorCitzdGF0aWMgam9iamVjdCBtYWtlU3RydWN0VGltZXZhbChKTklFbnYqIGVudiwgY29uc3Qgc3RydWN0IHRpbWV2YWwmIHR2KSB7CisgICAgc3RhdGljIGptZXRob2RJRCBjdG9yID0gZW52LT5HZXRNZXRob2RJRChKbmlDb25zdGFudHM6OnN0cnVjdFRpbWV2YWxDbGFzcywgIjxpbml0PiIsICIoSkopViIpOworICAgIHJldHVybiBlbnYtPk5ld09iamVjdChKbmlDb25zdGFudHM6OnN0cnVjdFRpbWV2YWxDbGFzcywgY3RvciwKKyAgICAgICAgICAgIHN0YXRpY19jYXN0PGpsb25nPih0di50dl9zZWMpLCBzdGF0aWNfY2FzdDxqbG9uZz4odHYudHZfdXNlYykpOworfQorCitzdGF0aWMgam9iamVjdCBtYWtlU3RydWN0VXRzbmFtZShKTklFbnYqIGVudiwgY29uc3Qgc3RydWN0IHV0c25hbWUmIGJ1ZikgeworICAgIFRPX0pBVkFfU1RSSU5HKHN5c25hbWUsIGJ1Zi5zeXNuYW1lKTsKKyAgICBUT19KQVZBX1NUUklORyhub2RlbmFtZSwgYnVmLm5vZGVuYW1lKTsKKyAgICBUT19KQVZBX1NUUklORyhyZWxlYXNlLCBidWYucmVsZWFzZSk7CisgICAgVE9fSkFWQV9TVFJJTkcodmVyc2lvbiwgYnVmLnZlcnNpb24pOworICAgIFRPX0pBVkFfU1RSSU5HKG1hY2hpbmUsIGJ1Zi5tYWNoaW5lKTsKKyAgICBzdGF0aWMgam1ldGhvZElEIGN0b3IgPSBlbnYtPkdldE1ldGhvZElEKEpuaUNvbnN0YW50czo6c3RydWN0VXRzbmFtZUNsYXNzLCAiPGluaXQ+IiwKKyAgICAgICAgICAgICIoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7KVYiKTsKKyAgICByZXR1cm4gZW52LT5OZXdPYmplY3QoSm5pQ29uc3RhbnRzOjpzdHJ1Y3RVdHNuYW1lQ2xhc3MsIGN0b3IsCisgICAgICAgICAgICBzeXNuYW1lLCBub2RlbmFtZSwgcmVsZWFzZSwgdmVyc2lvbiwgbWFjaGluZSk7Cit9OworCitzdGF0aWMgYm9vbCBmaWxsSWZyZXEoSk5JRW52KiBlbnYsIGpzdHJpbmcgamF2YUludGVyZmFjZU5hbWUsIHN0cnVjdCBpZnJlcSYgcmVxKSB7CisgICAgU2NvcGVkVXRmQ2hhcnMgaW50ZXJmYWNlTmFtZShlbnYsIGphdmFJbnRlcmZhY2VOYW1lKTsKKyAgICBpZiAoaW50ZXJmYWNlTmFtZS5jX3N0cigpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBtZW1zZXQoJnJlcSwgMCwgc2l6ZW9mKHJlcSkpOworICAgIHN0cm5jcHkocmVxLmlmcl9uYW1lLCBpbnRlcmZhY2VOYW1lLmNfc3RyKCksIHNpemVvZihyZXEuaWZyX25hbWUpKTsKKyAgICByZXEuaWZyX25hbWVbc2l6ZW9mKHJlcS5pZnJfbmFtZSkgLSAxXSA9ICdcMCc7CisgICAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyBib29sIGZpbGxJbmV0U29ja2V0QWRkcmVzcyhKTklFbnYqIGVudiwgamludCByYywgam9iamVjdCBqYXZhSW5ldFNvY2tldEFkZHJlc3MsIGNvbnN0IHNvY2thZGRyX3N0b3JhZ2UqIHNzKSB7CisgICAgaWYgKHJjID09IC0xIHx8IGphdmFJbmV0U29ja2V0QWRkcmVzcyA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICAvLyBGaWxsIG91dCB0aGUgcGFzc2VkLWluIEluZXRTb2NrZXRBZGRyZXNzIHdpdGggdGhlIHNlbmRlcidzIElQIGFkZHJlc3MgYW5kIHBvcnQgbnVtYmVyLgorICAgIGppbnQgcG9ydDsKKyAgICBqb2JqZWN0IHNlbmRlciA9IHNvY2thZGRyVG9JbmV0QWRkcmVzcyhlbnYsIHNzLCAmcG9ydCk7CisgICAgaWYgKHNlbmRlciA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgc3RhdGljIGpmaWVsZElEIGFkZHJlc3NGaWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjppbmV0U29ja2V0QWRkcmVzc0NsYXNzLCAiYWRkciIsICJMamF2YS9uZXQvSW5ldEFkZHJlc3M7Iik7CisgICAgc3RhdGljIGpmaWVsZElEIHBvcnRGaWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjppbmV0U29ja2V0QWRkcmVzc0NsYXNzLCAicG9ydCIsICJJIik7CisgICAgZW52LT5TZXRPYmplY3RGaWVsZChqYXZhSW5ldFNvY2tldEFkZHJlc3MsIGFkZHJlc3NGaWQsIHNlbmRlcik7CisgICAgZW52LT5TZXRJbnRGaWVsZChqYXZhSW5ldFNvY2tldEFkZHJlc3MsIHBvcnRGaWQsIHBvcnQpOworICAgIHJldHVybiB0cnVlOworfQorCitzdGF0aWMgam9iamVjdCBkb1N0YXQoSk5JRW52KiBlbnYsIGpzdHJpbmcgamF2YVBhdGgsIGJvb2wgaXNMc3RhdCkgeworICAgIFNjb3BlZFV0ZkNoYXJzIHBhdGgoZW52LCBqYXZhUGF0aCk7CisgICAgaWYgKHBhdGguY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBzdHJ1Y3Qgc3RhdCBzYjsKKyAgICBpbnQgcmMgPSBpc0xzdGF0ID8gVEVNUF9GQUlMVVJFX1JFVFJZKGxzdGF0KHBhdGguY19zdHIoKSwgJnNiKSkKKyAgICAgICAgICAgICAgICAgICAgIDogVEVNUF9GQUlMVVJFX1JFVFJZKHN0YXQocGF0aC5jX3N0cigpLCAmc2IpKTsKKyAgICBpZiAocmMgPT0gLTEpIHsKKyAgICAgICAgdGhyb3dFcnJub0V4Y2VwdGlvbihlbnYsIGlzTHN0YXQgPyAibHN0YXQiIDogInN0YXQiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBtYWtlU3RydWN0U3RhdChlbnYsIHNiKTsKK30KKworY2xhc3MgUGFzc3dkIHsKK3B1YmxpYzoKKyAgICBQYXNzd2QoSk5JRW52KiBlbnYpIDogbUVudihlbnYpLCBtUmVzdWx0KE5VTEwpIHsKKyAgICAgICAgbUJ1ZmZlclNpemUgPSBzeXNjb25mKF9TQ19HRVRQV19SX1NJWkVfTUFYKTsKKyAgICAgICAgaWYgKG1CdWZmZXJTaXplID09IC0xVUwpIHsKKyAgICAgICAgICAgIC8vIFdlJ3JlIHByb2JhYmx5IG9uIGJpb25pYywgd2hlcmUgMUtpQiBzaG91bGQgYmUgZW5vdWdoIGZvciBhbnlvbmUuCisgICAgICAgICAgICAvLyBUT0RPOiBmaXggYmlvbmljIHRvIHJldHVybiAxMDI0IGxpa2UgZ2xpYmMuCisgICAgICAgICAgICBtQnVmZmVyU2l6ZSA9IDEwMjQ7CisgICAgICAgIH0KKyAgICAgICAgbUJ1ZmZlci5yZXNldChuZXcgY2hhclttQnVmZmVyU2l6ZV0pOworICAgIH0KKworICAgIGpvYmplY3QgZ2V0cHduYW0oY29uc3QgY2hhciogbmFtZSkgeworICAgICAgICByZXR1cm4gcHJvY2VzcygiZ2V0cHduYW1fciIsIGdldHB3bmFtX3IobmFtZSwgJm1Qd2QsIG1CdWZmZXIuZ2V0KCksIG1CdWZmZXJTaXplLCAmbVJlc3VsdCkpOworICAgIH0KKworICAgIGpvYmplY3QgZ2V0cHd1aWQodWlkX3QgdWlkKSB7CisgICAgICAgIHJldHVybiBwcm9jZXNzKCJnZXRwd3VpZF9yIiwgZ2V0cHd1aWRfcih1aWQsICZtUHdkLCBtQnVmZmVyLmdldCgpLCBtQnVmZmVyU2l6ZSwgJm1SZXN1bHQpKTsKKyAgICB9CisKKyAgICBzdHJ1Y3QgcGFzc3dkKiBnZXQoKSB7CisgICAgICAgIHJldHVybiBtUmVzdWx0OworICAgIH0KKworcHJpdmF0ZToKKyAgICBqb2JqZWN0IHByb2Nlc3MoY29uc3QgY2hhciogc3lzY2FsbCwgaW50IGVycm9yKSB7CisgICAgICAgIGlmIChtUmVzdWx0ID09IE5VTEwpIHsKKyAgICAgICAgICAgIGVycm5vID0gZXJyb3I7CisgICAgICAgICAgICB0aHJvd0Vycm5vRXhjZXB0aW9uKG1FbnYsIHN5c2NhbGwpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG1ha2VTdHJ1Y3RQYXNzd2QobUVudiwgKm1SZXN1bHQpOworICAgIH0KKworICAgIEpOSUVudiogbUVudjsKKyAgICBVbmlxdWVQdHI8Y2hhcltdPiBtQnVmZmVyOworICAgIHNpemVfdCBtQnVmZmVyU2l6ZTsKKyAgICBzdHJ1Y3QgcGFzc3dkIG1Qd2Q7CisgICAgc3RydWN0IHBhc3N3ZCogbVJlc3VsdDsKK307CisKK3N0YXRpYyBqb2JqZWN0IFBvc2l4X2FjY2VwdChKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdCBqYXZhRmQsIGpvYmplY3QgamF2YUluZXRTb2NrZXRBZGRyZXNzKSB7CisgICAgc29ja2FkZHJfc3RvcmFnZSBzczsKKyAgICBzb2NrbGVuX3Qgc2wgPSBzaXplb2Yoc3MpOworICAgIG1lbXNldCgmc3MsIDAsIHNpemVvZihzcykpOworICAgIGludCBmZDsKKyAgICBzb2NrYWRkciogcGVlciA9IChqYXZhSW5ldFNvY2tldEFkZHJlc3MgIT0gTlVMTCkgPyByZWludGVycHJldF9jYXN0PHNvY2thZGRyKj4oJnNzKSA6IE5VTEw7CisgICAgc29ja2xlbl90KiBwZWVyTGVuZ3RoID0gKGphdmFJbmV0U29ja2V0QWRkcmVzcyAhPSBOVUxMKSA/ICZzbCA6IDA7CisgICAgamludCBjbGllbnRGZCA9IE5FVF9GQUlMVVJFX1JFVFJZKCJhY2NlcHQiLCBhY2NlcHQoZmQsIHBlZXIsIHBlZXJMZW5ndGgpKTsKKyAgICBpZiAoY2xpZW50RmQgPT0gLTEgfHwgIWZpbGxJbmV0U29ja2V0QWRkcmVzcyhlbnYsIGNsaWVudEZkLCBqYXZhSW5ldFNvY2tldEFkZHJlc3MsICZzcykpIHsKKyAgICAgICAgY2xvc2UoY2xpZW50RmQpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIChjbGllbnRGZCAhPSAtMSkgPyBqbmlDcmVhdGVGaWxlRGVzY3JpcHRvcihlbnYsIGNsaWVudEZkKSA6IE5VTEw7Cit9CisKK3N0YXRpYyBqYm9vbGVhbiBQb3NpeF9hY2Nlc3MoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpzdHJpbmcgamF2YVBhdGgsIGppbnQgbW9kZSkgeworICAgIFNjb3BlZFV0ZkNoYXJzIHBhdGgoZW52LCBqYXZhUGF0aCk7CisgICAgaWYgKHBhdGguY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBKTklfRkFMU0U7CisgICAgfQorICAgIGludCByYyA9IFRFTVBfRkFJTFVSRV9SRVRSWShhY2Nlc3MocGF0aC5jX3N0cigpLCBtb2RlKSk7CisgICAgaWYgKHJjID09IC0xKSB7CisgICAgICAgIHRocm93RXJybm9FeGNlcHRpb24oZW52LCAiYWNjZXNzIik7CisgICAgfQorICAgIHJldHVybiAocmMgPT0gMCk7Cit9CisKK3N0YXRpYyB2b2lkIFBvc2l4X2JpbmQoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpvYmplY3QgamF2YUZkLCBqb2JqZWN0IGphdmFBZGRyZXNzLCBqaW50IHBvcnQpIHsKKyAgICBzb2NrYWRkcl9zdG9yYWdlIHNzOworICAgIGlmICghaW5ldEFkZHJlc3NUb1NvY2thZGRyKGVudiwgamF2YUFkZHJlc3MsIHBvcnQsICZzcykpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpbnQgZmQ7CisgICAgY29uc3Qgc29ja2FkZHIqIHNhID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBzb2NrYWRkcio+KCZzcyk7CisgICAgTkVUX0ZBSUxVUkVfUkVUUlkoImJpbmQiLCBiaW5kKGZkLCBzYSwgc2l6ZW9mKHNvY2thZGRyX3N0b3JhZ2UpKSk7Cit9CisKK3N0YXRpYyB2b2lkIFBvc2l4X2NobW9kKEpOSUVudiogZW52LCBqb2JqZWN0LCBqc3RyaW5nIGphdmFQYXRoLCBqaW50IG1vZGUpIHsKKyAgICBTY29wZWRVdGZDaGFycyBwYXRoKGVudiwgamF2YVBhdGgpOworICAgIGlmIChwYXRoLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm47CisgICAgfQorICAgIHRocm93SWZNaW51c09uZShlbnYsICJjaG1vZCIsIFRFTVBfRkFJTFVSRV9SRVRSWShjaG1vZChwYXRoLmNfc3RyKCksIG1vZGUpKSk7Cit9CisKK3N0YXRpYyB2b2lkIFBvc2l4X2Nsb3NlKEpOSUVudiogZW52LCBqb2JqZWN0LCBqb2JqZWN0IGphdmFGZCkgeworICAgIC8vIEdldCB0aGUgRmlsZURlc2NyaXB0b3IncyAnZmQnIGZpZWxkIGFuZCBjbGVhciBpdC4KKyAgICAvLyBXZSBuZWVkIHRvIGRvIHRoaXMgYmVmb3JlIHdlIGNhbiB0aHJvdyBhbiBJT0V4Y2VwdGlvbiAoaHR0cDovL2IvMzIyMjA4NykuCisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIGpuaVNldEZpbGVEZXNjcmlwdG9yT2ZGRChlbnYsIGphdmFGZCwgLTEpOworCisgICAgLy8gRXZlbiBpZiBjbG9zZSgyKSBmYWlscyB3aXRoIEVJTlRSLCB0aGUgZmQgd2lsbCBoYXZlIGJlZW4gY2xvc2VkLgorICAgIC8vIFVzaW5nIFRFTVBfRkFJTFVSRV9SRVRSWSB3aWxsIGVpdGhlciBsZWFkIHRvIEVCQURGIG9yIGNsb3Npbmcgc29tZW9uZSBlbHNlJ3MgZmQuCisgICAgLy8gaHR0cDovL2xrbWwuaW5kaWFuYS5lZHUvaHlwZXJtYWlsL2xpbnV4L2tlcm5lbC8wNTA5LjEvMDg3Ny5odG1sCisgICAgdGhyb3dJZk1pbnVzT25lKGVudiwgImNsb3NlIiwgY2xvc2UoZmQpKTsKK30KKworc3RhdGljIHZvaWQgUG9zaXhfY29ubmVjdChKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdCBqYXZhRmQsIGpvYmplY3QgamF2YUFkZHJlc3MsIGppbnQgcG9ydCkgeworICAgIHNvY2thZGRyX3N0b3JhZ2Ugc3M7CisgICAgaWYgKCFpbmV0QWRkcmVzc1RvU29ja2FkZHIoZW52LCBqYXZhQWRkcmVzcywgcG9ydCwgJnNzKSkgeworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGludCBmZDsKKyAgICBjb25zdCBzb2NrYWRkciogc2EgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHNvY2thZGRyKj4oJnNzKTsKKyAgICBORVRfRkFJTFVSRV9SRVRSWSgiY29ubmVjdCIsIGNvbm5lY3QoZmQsIHNhLCBzaXplb2Yoc29ja2FkZHJfc3RvcmFnZSkpKTsKK30KKworc3RhdGljIGpvYmplY3QgUG9zaXhfZHVwKEpOSUVudiogZW52LCBqb2JqZWN0LCBqb2JqZWN0IGphdmFPbGRGZCkgeworICAgIGludCBvbGRGZCA9IGpuaUdldEZERnJvbUZpbGVEZXNjcmlwdG9yKGVudiwgamF2YU9sZEZkKTsKKyAgICBpbnQgbmV3RmQgPSB0aHJvd0lmTWludXNPbmUoZW52LCAiZHVwIiwgVEVNUF9GQUlMVVJFX1JFVFJZKGR1cChvbGRGZCkpKTsKKyAgICByZXR1cm4gKG5ld0ZkICE9IC0xKSA/IGpuaUNyZWF0ZUZpbGVEZXNjcmlwdG9yKGVudiwgbmV3RmQpIDogTlVMTDsKK30KKworc3RhdGljIGpvYmplY3QgUG9zaXhfZHVwMihKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdCBqYXZhT2xkRmQsIGppbnQgbmV3RmQpIHsKKyAgICBpbnQgb2xkRmQgPSBqbmlHZXRGREZyb21GaWxlRGVzY3JpcHRvcihlbnYsIGphdmFPbGRGZCk7CisgICAgaW50IGZkID0gdGhyb3dJZk1pbnVzT25lKGVudiwgImR1cDIiLCBURU1QX0ZBSUxVUkVfUkVUUlkoZHVwMihvbGRGZCwgbmV3RmQpKSk7CisgICAgcmV0dXJuIChmZCAhPSAtMSkgPyBqbmlDcmVhdGVGaWxlRGVzY3JpcHRvcihlbnYsIGZkKSA6IE5VTEw7Cit9CisKK3N0YXRpYyBqb2JqZWN0QXJyYXkgUG9zaXhfZW52aXJvbihKTklFbnYqIGVudiwgam9iamVjdCkgeworICAgIGV4dGVybiBjaGFyKiogZW52aXJvbjsgLy8gU3RhbmRhcmQsIGJ1dCBub3QgaW4gYW55IGhlYWRlciBmaWxlLgorICAgIHJldHVybiB0b1N0cmluZ0FycmF5KGVudiwgZW52aXJvbik7Cit9CisKK3N0YXRpYyBqaW50IFBvc2l4X2ZjbnRsVm9pZChKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdCBqYXZhRmQsIGppbnQgY21kKSB7CisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIHJldHVybiB0aHJvd0lmTWludXNPbmUoZW52LCAiZmNudGwiLCBURU1QX0ZBSUxVUkVfUkVUUlkoZmNudGwoZmQsIGNtZCkpKTsKK30KKworc3RhdGljIGppbnQgUG9zaXhfZmNudGxMb25nKEpOSUVudiogZW52LCBqb2JqZWN0LCBqb2JqZWN0IGphdmFGZCwgamludCBjbWQsIGpsb25nIGFyZykgeworICAgIGludCBmZCA9IGpuaUdldEZERnJvbUZpbGVEZXNjcmlwdG9yKGVudiwgamF2YUZkKTsKKyAgICByZXR1cm4gdGhyb3dJZk1pbnVzT25lKGVudiwgImZjbnRsIiwgVEVNUF9GQUlMVVJFX1JFVFJZKGZjbnRsKGZkLCBjbWQsIGFyZykpKTsKK30KKworc3RhdGljIGppbnQgUG9zaXhfZmNudGxGbG9jayhKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdCBqYXZhRmQsIGppbnQgY21kLCBqb2JqZWN0IGphdmFGbG9jaykgeworICAgIHN0YXRpYyBqZmllbGRJRCB0eXBlRmlkID0gZW52LT5HZXRGaWVsZElEKEpuaUNvbnN0YW50czo6c3RydWN0RmxvY2tDbGFzcywgImxfdHlwZSIsICJTIik7CisgICAgc3RhdGljIGpmaWVsZElEIHdoZW5jZUZpZCA9IGVudi0+R2V0RmllbGRJRChKbmlDb25zdGFudHM6OnN0cnVjdEZsb2NrQ2xhc3MsICJsX3doZW5jZSIsICJTIik7CisgICAgc3RhdGljIGpmaWVsZElEIHN0YXJ0RmlkID0gZW52LT5HZXRGaWVsZElEKEpuaUNvbnN0YW50czo6c3RydWN0RmxvY2tDbGFzcywgImxfc3RhcnQiLCAiSiIpOworICAgIHN0YXRpYyBqZmllbGRJRCBsZW5GaWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjpzdHJ1Y3RGbG9ja0NsYXNzLCAibF9sZW4iLCAiSiIpOworICAgIHN0YXRpYyBqZmllbGRJRCBwaWRGaWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjpzdHJ1Y3RGbG9ja0NsYXNzLCAibF9waWQiLCAiSSIpOworCisgICAgc3RydWN0IGZsb2NrNjQgbG9jazsKKyAgICBtZW1zZXQoJmxvY2ssIDAsIHNpemVvZihsb2NrKSk7CisgICAgbG9jay5sX3R5cGUgPSBlbnYtPkdldFNob3J0RmllbGQoamF2YUZsb2NrLCB0eXBlRmlkKTsKKyAgICBsb2NrLmxfd2hlbmNlID0gZW52LT5HZXRTaG9ydEZpZWxkKGphdmFGbG9jaywgd2hlbmNlRmlkKTsKKyAgICBsb2NrLmxfc3RhcnQgPSBlbnYtPkdldExvbmdGaWVsZChqYXZhRmxvY2ssIHN0YXJ0RmlkKTsKKyAgICBsb2NrLmxfbGVuID0gZW52LT5HZXRMb25nRmllbGQoamF2YUZsb2NrLCBsZW5GaWQpOworICAgIGxvY2subF9waWQgPSBlbnYtPkdldEludEZpZWxkKGphdmFGbG9jaywgcGlkRmlkKTsKKworICAgIGludCBmZCA9IGpuaUdldEZERnJvbUZpbGVEZXNjcmlwdG9yKGVudiwgamF2YUZkKTsKKyAgICBpbnQgcmMgPSB0aHJvd0lmTWludXNPbmUoZW52LCAiZmNudGwiLCBURU1QX0ZBSUxVUkVfUkVUUlkoZmNudGwoZmQsIGNtZCwgJmxvY2spKSk7CisgICAgaWYgKHJjICE9IC0xKSB7CisgICAgICAgIGVudi0+U2V0U2hvcnRGaWVsZChqYXZhRmxvY2ssIHR5cGVGaWQsIGxvY2subF90eXBlKTsKKyAgICAgICAgZW52LT5TZXRTaG9ydEZpZWxkKGphdmFGbG9jaywgd2hlbmNlRmlkLCBsb2NrLmxfd2hlbmNlKTsKKyAgICAgICAgZW52LT5TZXRMb25nRmllbGQoamF2YUZsb2NrLCBzdGFydEZpZCwgbG9jay5sX3N0YXJ0KTsKKyAgICAgICAgZW52LT5TZXRMb25nRmllbGQoamF2YUZsb2NrLCBsZW5GaWQsIGxvY2subF9sZW4pOworICAgICAgICBlbnYtPlNldEludEZpZWxkKGphdmFGbG9jaywgcGlkRmlkLCBsb2NrLmxfcGlkKTsKKyAgICB9CisgICAgcmV0dXJuIHJjOworfQorCitzdGF0aWMgdm9pZCBQb3NpeF9mZGF0YXN5bmMoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpvYmplY3QgamF2YUZkKSB7CisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIHRocm93SWZNaW51c09uZShlbnYsICJmZGF0YXN5bmMiLCBURU1QX0ZBSUxVUkVfUkVUUlkoZmRhdGFzeW5jKGZkKSkpOworfQorCitzdGF0aWMgam9iamVjdCBQb3NpeF9mc3RhdChKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdCBqYXZhRmQpIHsKKyAgICBpbnQgZmQgPSBqbmlHZXRGREZyb21GaWxlRGVzY3JpcHRvcihlbnYsIGphdmFGZCk7CisgICAgc3RydWN0IHN0YXQgc2I7CisgICAgaW50IHJjID0gVEVNUF9GQUlMVVJFX1JFVFJZKGZzdGF0KGZkLCAmc2IpKTsKKyAgICBpZiAocmMgPT0gLTEpIHsKKyAgICAgICAgdGhyb3dFcnJub0V4Y2VwdGlvbihlbnYsICJmc3RhdCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIG1ha2VTdHJ1Y3RTdGF0KGVudiwgc2IpOworfQorCitzdGF0aWMgam9iamVjdCBQb3NpeF9mc3RhdGZzKEpOSUVudiogZW52LCBqb2JqZWN0LCBqb2JqZWN0IGphdmFGZCkgeworICAgIGludCBmZCA9IGpuaUdldEZERnJvbUZpbGVEZXNjcmlwdG9yKGVudiwgamF2YUZkKTsKKyAgICBzdHJ1Y3Qgc3RhdGZzIHNiOworICAgIGludCByYyA9IFRFTVBfRkFJTFVSRV9SRVRSWShmc3RhdGZzKGZkLCAmc2IpKTsKKyAgICBpZiAocmMgPT0gLTEpIHsKKyAgICAgICAgdGhyb3dFcnJub0V4Y2VwdGlvbihlbnYsICJmc3RhdGZzIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gbWFrZVN0cnVjdFN0YXRGcyhlbnYsIHNiKTsKK30KKworc3RhdGljIHZvaWQgUG9zaXhfZnN5bmMoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpvYmplY3QgamF2YUZkKSB7CisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIHRocm93SWZNaW51c09uZShlbnYsICJmc3luYyIsIFRFTVBfRkFJTFVSRV9SRVRSWShmc3luYyhmZCkpKTsKK30KKworc3RhdGljIHZvaWQgUG9zaXhfZnRydW5jYXRlKEpOSUVudiogZW52LCBqb2JqZWN0LCBqb2JqZWN0IGphdmFGZCwgamxvbmcgbGVuZ3RoKSB7CisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIHRocm93SWZNaW51c09uZShlbnYsICJmdHJ1bmNhdGUiLCBURU1QX0ZBSUxVUkVfUkVUUlkoZnRydW5jYXRlNjQoZmQsIGxlbmd0aCkpKTsKK30KKworc3RhdGljIGpzdHJpbmcgUG9zaXhfZ2FpX3N0cmVycm9yKEpOSUVudiogZW52LCBqb2JqZWN0LCBqaW50IGVycm9yKSB7CisgICAgcmV0dXJuIGVudi0+TmV3U3RyaW5nVVRGKGdhaV9zdHJlcnJvcihlcnJvcikpOworfQorCitzdGF0aWMgam9iamVjdEFycmF5IFBvc2l4X2dldGFkZHJpbmZvKEpOSUVudiogZW52LCBqb2JqZWN0LCBqc3RyaW5nIGphdmFOb2RlLCBqb2JqZWN0IGphdmFIaW50cykgeworICAgIFNjb3BlZFV0ZkNoYXJzIG5vZGUoZW52LCBqYXZhTm9kZSk7CisgICAgaWYgKG5vZGUuY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHN0YXRpYyBqZmllbGRJRCBmbGFnc0ZpZCA9IGVudi0+R2V0RmllbGRJRChKbmlDb25zdGFudHM6OnN0cnVjdEFkZHJpbmZvQ2xhc3MsICJhaV9mbGFncyIsICJJIik7CisgICAgc3RhdGljIGpmaWVsZElEIGZhbWlseUZpZCA9IGVudi0+R2V0RmllbGRJRChKbmlDb25zdGFudHM6OnN0cnVjdEFkZHJpbmZvQ2xhc3MsICJhaV9mYW1pbHkiLCAiSSIpOworICAgIHN0YXRpYyBqZmllbGRJRCBzb2NrdHlwZUZpZCA9IGVudi0+R2V0RmllbGRJRChKbmlDb25zdGFudHM6OnN0cnVjdEFkZHJpbmZvQ2xhc3MsICJhaV9zb2NrdHlwZSIsICJJIik7CisgICAgc3RhdGljIGpmaWVsZElEIHByb3RvY29sRmlkID0gZW52LT5HZXRGaWVsZElEKEpuaUNvbnN0YW50czo6c3RydWN0QWRkcmluZm9DbGFzcywgImFpX3Byb3RvY29sIiwgIkkiKTsKKworICAgIGFkZHJpbmZvIGhpbnRzOworICAgIG1lbXNldCgmaGludHMsIDAsIHNpemVvZihoaW50cykpOworICAgIGhpbnRzLmFpX2ZsYWdzID0gZW52LT5HZXRJbnRGaWVsZChqYXZhSGludHMsIGZsYWdzRmlkKTsKKyAgICBoaW50cy5haV9mYW1pbHkgPSBlbnYtPkdldEludEZpZWxkKGphdmFIaW50cywgZmFtaWx5RmlkKTsKKyAgICBoaW50cy5haV9zb2NrdHlwZSA9IGVudi0+R2V0SW50RmllbGQoamF2YUhpbnRzLCBzb2NrdHlwZUZpZCk7CisgICAgaGludHMuYWlfcHJvdG9jb2wgPSBlbnYtPkdldEludEZpZWxkKGphdmFIaW50cywgcHJvdG9jb2xGaWQpOworCisgICAgYWRkcmluZm8qIGFkZHJlc3NMaXN0ID0gTlVMTDsKKyAgICBpbnQgcmMgPSBnZXRhZGRyaW5mbyhub2RlLmNfc3RyKCksIE5VTEwsICZoaW50cywgJmFkZHJlc3NMaXN0KTsKKyAgICBVbmlxdWVQdHI8YWRkcmluZm8sIGFkZHJpbmZvX2RlbGV0ZXI+IGFkZHJlc3NMaXN0RGVsZXRlcihhZGRyZXNzTGlzdCk7CisgICAgaWYgKHJjICE9IDApIHsKKyAgICAgICAgdGhyb3dHYWlFeGNlcHRpb24oZW52LCAiZ2V0YWRkcmluZm8iLCByYyk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8vIENvdW50IHJlc3VsdHMgc28gd2Uga25vdyBob3cgdG8gc2l6ZSB0aGUgb3V0cHV0IGFycmF5LgorICAgIGludCBhZGRyZXNzQ291bnQgPSAwOworICAgIGZvciAoYWRkcmluZm8qIGFpID0gYWRkcmVzc0xpc3Q7IGFpICE9IE5VTEw7IGFpID0gYWktPmFpX25leHQpIHsKKyAgICAgICAgaWYgKGFpLT5haV9mYW1pbHkgPT0gQUZfSU5FVCB8fCBhaS0+YWlfZmFtaWx5ID09IEFGX0lORVQ2KSB7CisgICAgICAgICAgICArK2FkZHJlc3NDb3VudDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIExPR0UoImdldGFkZHJpbmZvIHVuZXhwZWN0ZWQgYWlfZmFtaWx5ICVpIiwgYWktPmFpX2ZhbWlseSk7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKGFkZHJlc3NDb3VudCA9PSAwKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8vIFByZXBhcmUgb3V0cHV0IGFycmF5LgorICAgIGpvYmplY3RBcnJheSByZXN1bHQgPSBlbnYtPk5ld09iamVjdEFycmF5KGFkZHJlc3NDb3VudCwgSm5pQ29uc3RhbnRzOjppbmV0QWRkcmVzc0NsYXNzLCBOVUxMKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgLy8gRXhhbWluZSByZXR1cm5lZCBhZGRyZXNzZXMgb25lIGJ5IG9uZSwgc2F2ZSB0aGVtIGluIHRoZSBvdXRwdXQgYXJyYXkuCisgICAgaW50IGluZGV4ID0gMDsKKyAgICBmb3IgKGFkZHJpbmZvKiBhaSA9IGFkZHJlc3NMaXN0OyBhaSAhPSBOVUxMOyBhaSA9IGFpLT5haV9uZXh0KSB7CisgICAgICAgIGlmIChhaS0+YWlfZmFtaWx5ICE9IEFGX0lORVQgJiYgYWktPmFpX2ZhbWlseSAhPSBBRl9JTkVUNikgeworICAgICAgICAgICAgLy8gVW5rbm93biBhZGRyZXNzIGZhbWlseS4gU2tpcCB0aGlzIGFkZHJlc3MuCisgICAgICAgICAgICBMT0dFKCJnZXRhZGRyaW5mbyB1bmV4cGVjdGVkIGFpX2ZhbWlseSAlaSIsIGFpLT5haV9mYW1pbHkpOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKworICAgICAgICAvLyBDb252ZXJ0IGVhY2ggSVAgYWRkcmVzcyBpbnRvIGEgSmF2YSBieXRlIGFycmF5LgorICAgICAgICBzb2NrYWRkcl9zdG9yYWdlKiBhZGRyZXNzID0gcmVpbnRlcnByZXRfY2FzdDxzb2NrYWRkcl9zdG9yYWdlKj4oYWktPmFpX2FkZHIpOworICAgICAgICBTY29wZWRMb2NhbFJlZjxqb2JqZWN0PiBpbmV0QWRkcmVzcyhlbnYsIHNvY2thZGRyVG9JbmV0QWRkcmVzcyhlbnYsIGFkZHJlc3MsIE5VTEwpKTsKKyAgICAgICAgaWYgKGluZXRBZGRyZXNzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGVudi0+U2V0T2JqZWN0QXJyYXlFbGVtZW50KHJlc3VsdCwgaW5kZXgsIGluZXRBZGRyZXNzLmdldCgpKTsKKyAgICAgICAgKytpbmRleDsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIGppbnQgUG9zaXhfZ2V0ZWdpZChKTklFbnYqLCBqb2JqZWN0KSB7CisgICAgcmV0dXJuIGdldGVnaWQoKTsKK30KKworc3RhdGljIGppbnQgUG9zaXhfZ2V0ZXVpZChKTklFbnYqLCBqb2JqZWN0KSB7CisgICAgcmV0dXJuIGdldGV1aWQoKTsKK30KKworc3RhdGljIGppbnQgUG9zaXhfZ2V0Z2lkKEpOSUVudiosIGpvYmplY3QpIHsKKyAgICByZXR1cm4gZ2V0Z2lkKCk7Cit9CisKK3N0YXRpYyBqc3RyaW5nIFBvc2l4X2dldGVudihKTklFbnYqIGVudiwgam9iamVjdCwganN0cmluZyBqYXZhTmFtZSkgeworICAgIFNjb3BlZFV0ZkNoYXJzIG5hbWUoZW52LCBqYXZhTmFtZSk7CisgICAgaWYgKG5hbWUuY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gZW52LT5OZXdTdHJpbmdVVEYoZ2V0ZW52KG5hbWUuY19zdHIoKSkpOworfQorCitzdGF0aWMganN0cmluZyBQb3NpeF9nZXRuYW1laW5mbyhKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdCBqYXZhQWRkcmVzcywgamludCBmbGFncykgeworICAgIHNvY2thZGRyX3N0b3JhZ2Ugc3M7CisgICAgaWYgKCFpbmV0QWRkcmVzc1RvU29ja2FkZHJWZXJiYXRpbShlbnYsIGphdmFBZGRyZXNzLCAwLCAmc3MpKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICAvLyBUT0RPOiBiaW9uaWMncyBnZXRuYW1laW5mbygzKSBzZWVtcyB0byB3YW50IGl0cyBsZW5ndGggcGFyYW1ldGVyIHRvIGJlIGV4YWN0bHkKKyAgICAvLyBzaXplb2Yoc29ja2FkZHJfaW4pIGZvciBhbiBJUHY0IGFkZHJlc3MgYW5kIHNpemVvZiAoc29ja2FkZHJfaW42KSBmb3IgYW4KKyAgICAvLyBJUHY2IGFkZHJlc3MuIEZpeCBnZXRuYW1laW5mbyBzbyBpdCBhY2NlcHRzIHNpemVvZihzb2NrYWRkcl9zdG9yYWdlKSwgYW5kCisgICAgLy8gdGhlbiByZW1vdmUgdGhpcyBoYWNrLgorICAgIHNvY2tsZW5fdCBzaXplID0gKHNzLnNzX2ZhbWlseSA9PSBBRl9JTkVUKSA/IHNpemVvZihzb2NrYWRkcl9pbikgOiBzaXplb2Yoc29ja2FkZHJfaW42KTsKKyAgICBjaGFyIGJ1ZltOSV9NQVhIT1NUXTsgLy8gTklfTUFYSE9TVCBpcyBsb25nZXIgdGhhbiBJTkVUNl9BRERSU1RSTEVOLgorICAgIGludCByYyA9IGdldG5hbWVpbmZvKHJlaW50ZXJwcmV0X2Nhc3Q8c29ja2FkZHIqPigmc3MpLCBzaXplLCBidWYsIHNpemVvZihidWYpLCBOVUxMLCAwLCBmbGFncyk7CisgICAgaWYgKHJjICE9IDApIHsKKyAgICAgICAgdGhyb3dHYWlFeGNlcHRpb24oZW52LCAiZ2V0bmFtZWluZm8iLCByYyk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gZW52LT5OZXdTdHJpbmdVVEYoYnVmKTsKK30KKworc3RhdGljIGppbnQgUG9zaXhfZ2V0cGlkKEpOSUVudiosIGpvYmplY3QpIHsKKyAgICByZXR1cm4gZ2V0cGlkKCk7Cit9CisKK3N0YXRpYyBqaW50IFBvc2l4X2dldHBwaWQoSk5JRW52Kiwgam9iamVjdCkgeworICAgIHJldHVybiBnZXRwcGlkKCk7Cit9CisKK3N0YXRpYyBqb2JqZWN0IFBvc2l4X2dldHB3bmFtKEpOSUVudiogZW52LCBqb2JqZWN0LCBqc3RyaW5nIGphdmFOYW1lKSB7CisgICAgU2NvcGVkVXRmQ2hhcnMgbmFtZShlbnYsIGphdmFOYW1lKTsKKyAgICBpZiAobmFtZS5jX3N0cigpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBQYXNzd2QoZW52KS5nZXRwd25hbShuYW1lLmNfc3RyKCkpOworfQorCitzdGF0aWMgam9iamVjdCBQb3NpeF9nZXRwd3VpZChKTklFbnYqIGVudiwgam9iamVjdCwgamludCB1aWQpIHsKKyAgICByZXR1cm4gUGFzc3dkKGVudikuZ2V0cHd1aWQodWlkKTsKK30KKworc3RhdGljIGpvYmplY3QgUG9zaXhfZ2V0c29ja25hbWUoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpvYmplY3QgamF2YUZkKSB7CisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIHNvY2thZGRyX3N0b3JhZ2Ugc3M7CisgICAgc29ja2FkZHIqIHNhID0gcmVpbnRlcnByZXRfY2FzdDxzb2NrYWRkcio+KCZzcyk7CisgICAgc29ja2xlbl90IGJ5dGVDb3VudCA9IHNpemVvZihzcyk7CisgICAgbWVtc2V0KCZzcywgMCwgYnl0ZUNvdW50KTsKKyAgICBpbnQgcmMgPSBURU1QX0ZBSUxVUkVfUkVUUlkoZ2V0c29ja25hbWUoZmQsIHNhLCAmYnl0ZUNvdW50KSk7CisgICAgaWYgKHJjID09IC0xKSB7CisgICAgICAgIHRocm93RXJybm9FeGNlcHRpb24oZW52LCAiZ2V0c29ja25hbWUiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBtYWtlU29ja2V0QWRkcmVzcyhlbnYsICZzcyk7Cit9CisKK3N0YXRpYyBqaW50IFBvc2l4X2dldHNvY2tvcHRCeXRlKEpOSUVudiogZW52LCBqb2JqZWN0LCBqb2JqZWN0IGphdmFGZCwgamludCBsZXZlbCwgamludCBvcHRpb24pIHsKKyAgICBpbnQgZmQgPSBqbmlHZXRGREZyb21GaWxlRGVzY3JpcHRvcihlbnYsIGphdmFGZCk7CisgICAgdV9jaGFyIHJlc3VsdCA9IDA7CisgICAgc29ja2xlbl90IHNpemUgPSBzaXplb2YocmVzdWx0KTsKKyAgICB0aHJvd0lmTWludXNPbmUoZW52LCAiZ2V0c29ja29wdCIsIFRFTVBfRkFJTFVSRV9SRVRSWShnZXRzb2Nrb3B0KGZkLCBsZXZlbCwgb3B0aW9uLCAmcmVzdWx0LCAmc2l6ZSkpKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgam9iamVjdCBQb3NpeF9nZXRzb2Nrb3B0SW5BZGRyKEpOSUVudiogZW52LCBqb2JqZWN0LCBqb2JqZWN0IGphdmFGZCwgamludCBsZXZlbCwgamludCBvcHRpb24pIHsKKyAgICBpbnQgZmQgPSBqbmlHZXRGREZyb21GaWxlRGVzY3JpcHRvcihlbnYsIGphdmFGZCk7CisgICAgc29ja2FkZHJfc3RvcmFnZSBzczsKKyAgICBtZW1zZXQoJnNzLCAwLCBzaXplb2Yoc3MpKTsKKyAgICBzcy5zc19mYW1pbHkgPSBBRl9JTkVUOyAvLyBUaGlzIGlzIG9ubHkgZm9yIHRoZSBJUHY0LW9ubHkgSVBfTVVMVElDQVNUX0lGLgorICAgIHNvY2thZGRyX2luKiBzYSA9IHJlaW50ZXJwcmV0X2Nhc3Q8c29ja2FkZHJfaW4qPigmc3MpOworICAgIHNvY2tsZW5fdCBzaXplID0gc2l6ZW9mKHNhLT5zaW5fYWRkcik7CisgICAgaW50IHJjID0gVEVNUF9GQUlMVVJFX1JFVFJZKGdldHNvY2tvcHQoZmQsIGxldmVsLCBvcHRpb24sICZzYS0+c2luX2FkZHIsICZzaXplKSk7CisgICAgaWYgKHJjID09IC0xKSB7CisgICAgICAgIHRocm93RXJybm9FeGNlcHRpb24oZW52LCAiZ2V0c29ja29wdCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIHNvY2thZGRyVG9JbmV0QWRkcmVzcyhlbnYsICZzcywgTlVMTCk7Cit9CisKK3N0YXRpYyBqaW50IFBvc2l4X2dldHNvY2tvcHRJbnQoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpvYmplY3QgamF2YUZkLCBqaW50IGxldmVsLCBqaW50IG9wdGlvbikgeworICAgIGludCBmZCA9IGpuaUdldEZERnJvbUZpbGVEZXNjcmlwdG9yKGVudiwgamF2YUZkKTsKKyAgICBqaW50IHJlc3VsdCA9IDA7CisgICAgc29ja2xlbl90IHNpemUgPSBzaXplb2YocmVzdWx0KTsKKyAgICB0aHJvd0lmTWludXNPbmUoZW52LCAiZ2V0c29ja29wdCIsIFRFTVBfRkFJTFVSRV9SRVRSWShnZXRzb2Nrb3B0KGZkLCBsZXZlbCwgb3B0aW9uLCAmcmVzdWx0LCAmc2l6ZSkpKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgam9iamVjdCBQb3NpeF9nZXRzb2Nrb3B0TGluZ2VyKEpOSUVudiogZW52LCBqb2JqZWN0LCBqb2JqZWN0IGphdmFGZCwgamludCBsZXZlbCwgamludCBvcHRpb24pIHsKKyAgICBpbnQgZmQgPSBqbmlHZXRGREZyb21GaWxlRGVzY3JpcHRvcihlbnYsIGphdmFGZCk7CisgICAgc3RydWN0IGxpbmdlciBsOworICAgIHNvY2tsZW5fdCBzaXplID0gc2l6ZW9mKGwpOworICAgIG1lbXNldCgmbCwgMCwgc2l6ZSk7CisgICAgaW50IHJjID0gVEVNUF9GQUlMVVJFX1JFVFJZKGdldHNvY2tvcHQoZmQsIGxldmVsLCBvcHRpb24sICZsLCAmc2l6ZSkpOworICAgIGlmIChyYyA9PSAtMSkgeworICAgICAgICB0aHJvd0Vycm5vRXhjZXB0aW9uKGVudiwgImdldHNvY2tvcHQiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBtYWtlU3RydWN0TGluZ2VyKGVudiwgbCk7Cit9CisKK3N0YXRpYyBqb2JqZWN0IFBvc2l4X2dldHNvY2tvcHRUaW1ldmFsKEpOSUVudiogZW52LCBqb2JqZWN0LCBqb2JqZWN0IGphdmFGZCwgamludCBsZXZlbCwgamludCBvcHRpb24pIHsKKyAgICBpbnQgZmQgPSBqbmlHZXRGREZyb21GaWxlRGVzY3JpcHRvcihlbnYsIGphdmFGZCk7CisgICAgc3RydWN0IHRpbWV2YWwgdHY7CisgICAgc29ja2xlbl90IHNpemUgPSBzaXplb2YodHYpOworICAgIG1lbXNldCgmdHYsIDAsIHNpemUpOworICAgIGludCByYyA9IFRFTVBfRkFJTFVSRV9SRVRSWShnZXRzb2Nrb3B0KGZkLCBsZXZlbCwgb3B0aW9uLCAmdHYsICZzaXplKSk7CisgICAgaWYgKHJjID09IC0xKSB7CisgICAgICAgIHRocm93RXJybm9FeGNlcHRpb24oZW52LCAiZ2V0c29ja29wdCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIG1ha2VTdHJ1Y3RUaW1ldmFsKGVudiwgdHYpOworfQorCitzdGF0aWMgamludCBQb3NpeF9nZXR1aWQoSk5JRW52Kiwgam9iamVjdCkgeworICAgIHJldHVybiBnZXR1aWQoKTsKK30KKworc3RhdGljIGpzdHJpbmcgUG9zaXhfaWZfaW5kZXh0b25hbWUoSk5JRW52KiBlbnYsIGpvYmplY3QsIGppbnQgaW5kZXgpIHsKKyAgICBjaGFyIGJ1ZltJRl9OQU1FU0laRV07CisgICAgY2hhciogbmFtZSA9IGlmX2luZGV4dG9uYW1lKGluZGV4LCBidWYpOworICAgIC8vIGlmX2luZGV4dG9uYW1lKDMpIHJldHVybnMgTlVMTCBvbiBmYWlsdXJlLCB3aGljaCB3aWxsIGNvbWUgb3V0IG9mIE5ld1N0cmluZ1VURiB1bnNjYXRoZWQuCisgICAgLy8gVGhlcmUncyBubyB1c2VmdWwgaW5mb3JtYXRpb24gaW4gZXJybm8sIHNvIHdlIGRvbid0IGJvdGhlciB0aHJvd2luZy4gQ2FsbGVycyBjYW4gbnVsbC1jaGVjay4KKyAgICByZXR1cm4gZW52LT5OZXdTdHJpbmdVVEYobmFtZSk7Cit9CisKK3N0YXRpYyBqb2JqZWN0IFBvc2l4X2luZXRfcHRvbihKTklFbnYqIGVudiwgam9iamVjdCwgamludCBmYW1pbHksIGpzdHJpbmcgamF2YU5hbWUpIHsKKyAgICBTY29wZWRVdGZDaGFycyBuYW1lKGVudiwgamF2YU5hbWUpOworICAgIGlmIChuYW1lLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgc29ja2FkZHJfc3RvcmFnZSBzczsKKyAgICBtZW1zZXQoJnNzLCAwLCBzaXplb2Yoc3MpKTsKKyAgICAvLyBzb2NrYWRkcl9pbiBhbmQgc29ja2FkZHJfaW42IGFyZSBhdCB0aGUgc2FtZSBhZGRyZXNzLCBzbyB3ZSBjYW4gdXNlIGVpdGhlciBoZXJlLgorICAgIHZvaWQqIGRzdCA9ICZyZWludGVycHJldF9jYXN0PHNvY2thZGRyX2luKj4oJnNzKS0+c2luX2FkZHI7CisgICAgaWYgKGluZXRfcHRvbihmYW1pbHksIG5hbWUuY19zdHIoKSwgZHN0KSAhPSAxKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBzcy5zc19mYW1pbHkgPSBmYW1pbHk7CisgICAgcmV0dXJuIHNvY2thZGRyVG9JbmV0QWRkcmVzcyhlbnYsICZzcywgTlVMTCk7Cit9CisKK3N0YXRpYyBqb2JqZWN0IFBvc2l4X2lvY3RsSW5ldEFkZHJlc3MoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpvYmplY3QgamF2YUZkLCBqaW50IGNtZCwganN0cmluZyBqYXZhSW50ZXJmYWNlTmFtZSkgeworICAgIHN0cnVjdCBpZnJlcSByZXE7CisgICAgaWYgKCFmaWxsSWZyZXEoZW52LCBqYXZhSW50ZXJmYWNlTmFtZSwgcmVxKSkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIGludCByYyA9IHRocm93SWZNaW51c09uZShlbnYsICJpb2N0bCIsIFRFTVBfRkFJTFVSRV9SRVRSWShpb2N0bChmZCwgY21kLCAmcmVxKSkpOworICAgIGlmIChyYyA9PSAtMSkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIHNvY2thZGRyVG9JbmV0QWRkcmVzcyhlbnYsIHJlaW50ZXJwcmV0X2Nhc3Q8c29ja2FkZHJfc3RvcmFnZSo+KCZyZXEuaWZyX2FkZHIpLCBOVUxMKTsKK30KKworc3RhdGljIGppbnQgUG9zaXhfaW9jdGxJbnQoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpvYmplY3QgamF2YUZkLCBqaW50IGNtZCwgam9iamVjdCBqYXZhQXJnKSB7CisgICAgLy8gVGhpcyBpcyBjb21wbGljYXRlZCBiZWNhdXNlIGlvY3RscyBtYXkgcmV0dXJuIHRoZWlyIHJlc3VsdCBieSB1cGRhdGluZyB0aGVpciBhcmd1bWVudAorICAgIC8vIG9yIHZpYSB0aGVpciByZXR1cm4gdmFsdWUsIHNvIHdlIG5lZWQgdG8gc3VwcG9ydCBib3RoLgorICAgIGludCBmZCA9IGpuaUdldEZERnJvbUZpbGVEZXNjcmlwdG9yKGVudiwgamF2YUZkKTsKKyAgICBzdGF0aWMgamZpZWxkSUQgdmFsdWVGaWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjptdXRhYmxlSW50Q2xhc3MsICJ2YWx1ZSIsICJJIik7CisgICAgamludCBhcmcgPSBlbnYtPkdldEludEZpZWxkKGphdmFBcmcsIHZhbHVlRmlkKTsKKyAgICBpbnQgcmMgPSB0aHJvd0lmTWludXNPbmUoZW52LCAiaW9jdGwiLCBURU1QX0ZBSUxVUkVfUkVUUlkoaW9jdGwoZmQsIGNtZCwgJmFyZykpKTsKKyAgICBpZiAoIWVudi0+RXhjZXB0aW9uQ2hlY2soKSkgeworICAgICAgICBlbnYtPlNldEludEZpZWxkKGphdmFBcmcsIHZhbHVlRmlkLCBhcmcpOworICAgIH0KKyAgICByZXR1cm4gcmM7Cit9CisKK3N0YXRpYyBqYm9vbGVhbiBQb3NpeF9pc2F0dHkoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpvYmplY3QgamF2YUZkKSB7CisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIHJldHVybiBURU1QX0ZBSUxVUkVfUkVUUlkoaXNhdHR5KGZkKSkgPT0gMDsKK30KKworc3RhdGljIHZvaWQgUG9zaXhfa2lsbChKTklFbnYqIGVudiwgam9iamVjdCwgamludCBwaWQsIGppbnQgc2lnKSB7CisgICAgdGhyb3dJZk1pbnVzT25lKGVudiwgImtpbGwiLCBURU1QX0ZBSUxVUkVfUkVUUlkoa2lsbChwaWQsIHNpZykpKTsKK30KKworc3RhdGljIHZvaWQgUG9zaXhfbGlzdGVuKEpOSUVudiogZW52LCBqb2JqZWN0LCBqb2JqZWN0IGphdmFGZCwgamludCBiYWNrbG9nKSB7CisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIHRocm93SWZNaW51c09uZShlbnYsICJsaXN0ZW4iLCBURU1QX0ZBSUxVUkVfUkVUUlkobGlzdGVuKGZkLCBiYWNrbG9nKSkpOworfQorCitzdGF0aWMgamxvbmcgUG9zaXhfbHNlZWsoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpvYmplY3QgamF2YUZkLCBqbG9uZyBvZmZzZXQsIGppbnQgd2hlbmNlKSB7CisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIHJldHVybiB0aHJvd0lmTWludXNPbmUoZW52LCAibHNlZWsiLCBURU1QX0ZBSUxVUkVfUkVUUlkobHNlZWs2NChmZCwgb2Zmc2V0LCB3aGVuY2UpKSk7Cit9CisKK3N0YXRpYyBqb2JqZWN0IFBvc2l4X2xzdGF0KEpOSUVudiogZW52LCBqb2JqZWN0LCBqc3RyaW5nIGphdmFQYXRoKSB7CisgICAgcmV0dXJuIGRvU3RhdChlbnYsIGphdmFQYXRoLCB0cnVlKTsKK30KKworc3RhdGljIHZvaWQgUG9zaXhfbWluY29yZShKTklFbnYqIGVudiwgam9iamVjdCwgamxvbmcgYWRkcmVzcywgamxvbmcgYnl0ZUNvdW50LCBqYnl0ZUFycmF5IGphdmFWZWN0b3IpIHsKKyAgICBTY29wZWRCeXRlQXJyYXlSVyB2ZWN0b3IoZW52LCBqYXZhVmVjdG9yKTsKKyAgICBpZiAodmVjdG9yLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICB2b2lkKiBwdHIgPSByZWludGVycHJldF9jYXN0PHZvaWQqPihzdGF0aWNfY2FzdDx1aW50cHRyX3Q+KGFkZHJlc3MpKTsKKyAgICB1bnNpZ25lZCBjaGFyKiB2ZWMgPSByZWludGVycHJldF9jYXN0PHVuc2lnbmVkIGNoYXIqPih2ZWN0b3IuZ2V0KCkpOworICAgIHRocm93SWZNaW51c09uZShlbnYsICJtaW5jb3JlIiwgVEVNUF9GQUlMVVJFX1JFVFJZKG1pbmNvcmUocHRyLCBieXRlQ291bnQsIHZlYykpKTsKK30KKworc3RhdGljIHZvaWQgUG9zaXhfbWtkaXIoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpzdHJpbmcgamF2YVBhdGgsIGppbnQgbW9kZSkgeworICAgIFNjb3BlZFV0ZkNoYXJzIHBhdGgoZW52LCBqYXZhUGF0aCk7CisgICAgaWYgKHBhdGguY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgdGhyb3dJZk1pbnVzT25lKGVudiwgIm1rZGlyIiwgVEVNUF9GQUlMVVJFX1JFVFJZKG1rZGlyKHBhdGguY19zdHIoKSwgbW9kZSkpKTsKK30KKworc3RhdGljIHZvaWQgUG9zaXhfbWxvY2soSk5JRW52KiBlbnYsIGpvYmplY3QsIGpsb25nIGFkZHJlc3MsIGpsb25nIGJ5dGVDb3VudCkgeworICAgIHZvaWQqIHB0ciA9IHJlaW50ZXJwcmV0X2Nhc3Q8dm9pZCo+KHN0YXRpY19jYXN0PHVpbnRwdHJfdD4oYWRkcmVzcykpOworICAgIHRocm93SWZNaW51c09uZShlbnYsICJtbG9jayIsIFRFTVBfRkFJTFVSRV9SRVRSWShtbG9jayhwdHIsIGJ5dGVDb3VudCkpKTsKK30KKworc3RhdGljIGpsb25nIFBvc2l4X21tYXAoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpsb25nIGFkZHJlc3MsIGpsb25nIGJ5dGVDb3VudCwgamludCBwcm90LCBqaW50IGZsYWdzLCBqb2JqZWN0IGphdmFGZCwgamxvbmcgb2Zmc2V0KSB7CisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIHZvaWQqIHN1Z2dlc3RlZFB0ciA9IHJlaW50ZXJwcmV0X2Nhc3Q8dm9pZCo+KHN0YXRpY19jYXN0PHVpbnRwdHJfdD4oYWRkcmVzcykpOworICAgIHZvaWQqIHB0ciA9IG1tYXAoc3VnZ2VzdGVkUHRyLCBieXRlQ291bnQsIHByb3QsIGZsYWdzLCBmZCwgb2Zmc2V0KTsKKyAgICBpZiAocHRyID09IE1BUF9GQUlMRUQpIHsKKyAgICAgICAgdGhyb3dFcnJub0V4Y2VwdGlvbihlbnYsICJtbWFwIik7CisgICAgfQorICAgIHJldHVybiBzdGF0aWNfY2FzdDxqbG9uZz4ocmVpbnRlcnByZXRfY2FzdDx1aW50cHRyX3Q+KHB0cikpOworfQorCitzdGF0aWMgdm9pZCBQb3NpeF9tc3luYyhKTklFbnYqIGVudiwgam9iamVjdCwgamxvbmcgYWRkcmVzcywgamxvbmcgYnl0ZUNvdW50LCBqaW50IGZsYWdzKSB7CisgICAgdm9pZCogcHRyID0gcmVpbnRlcnByZXRfY2FzdDx2b2lkKj4oc3RhdGljX2Nhc3Q8dWludHB0cl90PihhZGRyZXNzKSk7CisgICAgdGhyb3dJZk1pbnVzT25lKGVudiwgIm1zeW5jIiwgVEVNUF9GQUlMVVJFX1JFVFJZKG1zeW5jKHB0ciwgYnl0ZUNvdW50LCBmbGFncykpKTsKK30KKworc3RhdGljIHZvaWQgUG9zaXhfbXVubG9jayhKTklFbnYqIGVudiwgam9iamVjdCwgamxvbmcgYWRkcmVzcywgamxvbmcgYnl0ZUNvdW50KSB7CisgICAgdm9pZCogcHRyID0gcmVpbnRlcnByZXRfY2FzdDx2b2lkKj4oc3RhdGljX2Nhc3Q8dWludHB0cl90PihhZGRyZXNzKSk7CisgICAgdGhyb3dJZk1pbnVzT25lKGVudiwgIm11bmxvY2siLCBURU1QX0ZBSUxVUkVfUkVUUlkobXVubG9jayhwdHIsIGJ5dGVDb3VudCkpKTsKK30KKworc3RhdGljIHZvaWQgUG9zaXhfbXVubWFwKEpOSUVudiogZW52LCBqb2JqZWN0LCBqbG9uZyBhZGRyZXNzLCBqbG9uZyBieXRlQ291bnQpIHsKKyAgICB2b2lkKiBwdHIgPSByZWludGVycHJldF9jYXN0PHZvaWQqPihzdGF0aWNfY2FzdDx1aW50cHRyX3Q+KGFkZHJlc3MpKTsKKyAgICB0aHJvd0lmTWludXNPbmUoZW52LCAibXVubWFwIiwgVEVNUF9GQUlMVVJFX1JFVFJZKG11bm1hcChwdHIsIGJ5dGVDb3VudCkpKTsKK30KKworc3RhdGljIGpvYmplY3QgUG9zaXhfb3BlbihKTklFbnYqIGVudiwgam9iamVjdCwganN0cmluZyBqYXZhUGF0aCwgamludCBmbGFncywgamludCBtb2RlKSB7CisgICAgU2NvcGVkVXRmQ2hhcnMgcGF0aChlbnYsIGphdmFQYXRoKTsKKyAgICBpZiAocGF0aC5jX3N0cigpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGludCBmZCA9IHRocm93SWZNaW51c09uZShlbnYsICJvcGVuIiwgVEVNUF9GQUlMVVJFX1JFVFJZKG9wZW4ocGF0aC5jX3N0cigpLCBmbGFncywgbW9kZSkpKTsKKyAgICByZXR1cm4gZmQgIT0gLTEgPyBqbmlDcmVhdGVGaWxlRGVzY3JpcHRvcihlbnYsIGZkKSA6IE5VTEw7Cit9CisKK3N0YXRpYyBqb2JqZWN0QXJyYXkgUG9zaXhfcGlwZShKTklFbnYqIGVudiwgam9iamVjdCkgeworICAgIGludCBmZHNbMl07CisgICAgdGhyb3dJZk1pbnVzT25lKGVudiwgInBpcGUiLCBURU1QX0ZBSUxVUkVfUkVUUlkocGlwZSgmZmRzWzBdKSkpOworICAgIGpvYmplY3RBcnJheSByZXN1bHQgPSBlbnYtPk5ld09iamVjdEFycmF5KDIsIEpuaUNvbnN0YW50czo6ZmlsZURlc2NyaXB0b3JDbGFzcywgTlVMTCk7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDI7ICsraSkgeworICAgICAgICBTY29wZWRMb2NhbFJlZjxqb2JqZWN0PiBmZChlbnYsIGpuaUNyZWF0ZUZpbGVEZXNjcmlwdG9yKGVudiwgZmRzW2ldKSk7CisgICAgICAgIGlmIChmZC5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBlbnYtPlNldE9iamVjdEFycmF5RWxlbWVudChyZXN1bHQsIGksIGZkLmdldCgpKTsKKyAgICAgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIGppbnQgUG9zaXhfcG9sbChKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdEFycmF5IGphdmFTdHJ1Y3RzLCBqaW50IHRpbWVvdXRNcykgeworICAgIHN0YXRpYyBqZmllbGRJRCBmZEZpZCA9IGVudi0+R2V0RmllbGRJRChKbmlDb25zdGFudHM6OnN0cnVjdFBvbGxmZENsYXNzLCAiZmQiLCAiTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7Iik7CisgICAgc3RhdGljIGpmaWVsZElEIGV2ZW50c0ZpZCA9IGVudi0+R2V0RmllbGRJRChKbmlDb25zdGFudHM6OnN0cnVjdFBvbGxmZENsYXNzLCAiZXZlbnRzIiwgIlMiKTsKKyAgICBzdGF0aWMgamZpZWxkSUQgcmV2ZW50c0ZpZCA9IGVudi0+R2V0RmllbGRJRChKbmlDb25zdGFudHM6OnN0cnVjdFBvbGxmZENsYXNzLCAicmV2ZW50cyIsICJTIik7CisKKyAgICAvLyBUdXJuIHRoZSBKYXZhIGxpYmNvcmUuaW8uU3RydWN0UG9sbGZkW10gaW50byBhIEMrKyBzdHJ1Y3QgcG9sbGZkW10uCisgICAgc2l6ZV90IGFycmF5TGVuZ3RoID0gZW52LT5HZXRBcnJheUxlbmd0aChqYXZhU3RydWN0cyk7CisgICAgVW5pcXVlUHRyPHN0cnVjdCBwb2xsZmRbXT4gZmRzKG5ldyBzdHJ1Y3QgcG9sbGZkW2FycmF5TGVuZ3RoXSk7CisgICAgbWVtc2V0KGZkcy5nZXQoKSwgMCwgc2l6ZW9mKHN0cnVjdCBwb2xsZmQpICogYXJyYXlMZW5ndGgpOworICAgIHNpemVfdCBjb3VudCA9IDA7IC8vIFNvbWUgdHJhaWxpbmcgYXJyYXkgZWxlbWVudHMgbWF5IGJlIGlycmVsZXZhbnQuIChTZWUgYmVsb3cuKQorICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgYXJyYXlMZW5ndGg7ICsraSkgeworICAgICAgICBTY29wZWRMb2NhbFJlZjxqb2JqZWN0PiBqYXZhU3RydWN0KGVudiwgZW52LT5HZXRPYmplY3RBcnJheUVsZW1lbnQoamF2YVN0cnVjdHMsIGkpKTsKKyAgICAgICAgaWYgKGphdmFTdHJ1Y3QuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICAgICAgYnJlYWs7IC8vIFdlIGFsbG93IHRyYWlsaW5nIG51bGxzIGluIHRoZSBhcnJheSBmb3IgY2FsbGVyIGNvbnZlbmllbmNlLgorICAgICAgICB9CisgICAgICAgIFNjb3BlZExvY2FsUmVmPGpvYmplY3Q+IGphdmFGZChlbnYsIGVudi0+R2V0T2JqZWN0RmllbGQoamF2YVN0cnVjdC5nZXQoKSwgZmRGaWQpKTsKKyAgICAgICAgaWYgKGphdmFGZC5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgICAgICBicmVhazsgLy8gV2UgYWxzbyBhbGxvdyBjYWxsZXJzIHRvIGp1c3QgY2xlYXIgdGhlIGZkIGZpZWxkICh0aGlzIGlzIHdoYXQgU2VsZWN0b3IgZG9lcykuCisgICAgICAgIH0KKyAgICAgICAgZmRzW2NvdW50XS5mZCA9IGpuaUdldEZERnJvbUZpbGVEZXNjcmlwdG9yKGVudiwgamF2YUZkLmdldCgpKTsKKyAgICAgICAgZmRzW2NvdW50XS5ldmVudHMgPSBlbnYtPkdldFNob3J0RmllbGQoamF2YVN0cnVjdC5nZXQoKSwgZXZlbnRzRmlkKTsKKyAgICAgICAgKytjb3VudDsKKyAgICB9CisKKyAgICBpbnQgcmMgPSBURU1QX0ZBSUxVUkVfUkVUUlkocG9sbChmZHMuZ2V0KCksIGNvdW50LCB0aW1lb3V0TXMpKTsKKyAgICBpZiAocmMgPT0gLTEpIHsKKyAgICAgICAgdGhyb3dFcnJub0V4Y2VwdGlvbihlbnYsICJwb2xsIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvLyBVcGRhdGUgdGhlIHJldmVudHMgZmllbGRzIGluIHRoZSBKYXZhIGxpYmNvcmUuaW8uU3RydWN0UG9sbGZkW10uCisgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7CisgICAgICAgIFNjb3BlZExvY2FsUmVmPGpvYmplY3Q+IGphdmFTdHJ1Y3QoZW52LCBlbnYtPkdldE9iamVjdEFycmF5RWxlbWVudChqYXZhU3RydWN0cywgaSkpOworICAgICAgICBpZiAoamF2YVN0cnVjdC5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgZW52LT5TZXRTaG9ydEZpZWxkKGphdmFTdHJ1Y3QuZ2V0KCksIHJldmVudHNGaWQsIGZkc1tpXS5yZXZlbnRzKTsKKyAgICB9CisgICAgcmV0dXJuIHJjOworfQorCitzdGF0aWMgamludCBQb3NpeF9wcmVhZEJ5dGVzKEpOSUVudiogZW52LCBqb2JqZWN0LCBqb2JqZWN0IGphdmFGZCwgam9iamVjdCBqYXZhQnl0ZXMsIGppbnQgYnl0ZU9mZnNldCwgamludCBieXRlQ291bnQsIGpsb25nIG9mZnNldCkgeworICAgIFNjb3BlZEJ5dGVzUlcgYnl0ZXMoZW52LCBqYXZhQnl0ZXMpOworICAgIGlmIChieXRlcy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIHJldHVybiB0aHJvd0lmTWludXNPbmUoZW52LCAicHJlYWQiLCBURU1QX0ZBSUxVUkVfUkVUUlkocHJlYWQ2NChmZCwgYnl0ZXMuZ2V0KCkgKyBieXRlT2Zmc2V0LCBieXRlQ291bnQsIG9mZnNldCkpKTsKK30KKworc3RhdGljIGppbnQgUG9zaXhfcHdyaXRlQnl0ZXMoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpvYmplY3QgamF2YUZkLCBqYnl0ZUFycmF5IGphdmFCeXRlcywgamludCBieXRlT2Zmc2V0LCBqaW50IGJ5dGVDb3VudCwgamxvbmcgb2Zmc2V0KSB7CisgICAgU2NvcGVkQnl0ZXNSTyBieXRlcyhlbnYsIGphdmFCeXRlcyk7CisgICAgaWYgKGJ5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpbnQgZmQgPSBqbmlHZXRGREZyb21GaWxlRGVzY3JpcHRvcihlbnYsIGphdmFGZCk7CisgICAgcmV0dXJuIHRocm93SWZNaW51c09uZShlbnYsICJwd3JpdGUiLCBURU1QX0ZBSUxVUkVfUkVUUlkocHdyaXRlNjQoZmQsIGJ5dGVzLmdldCgpICsgYnl0ZU9mZnNldCwgYnl0ZUNvdW50LCBvZmZzZXQpKSk7Cit9CisKK3N0YXRpYyBqaW50IFBvc2l4X3JlYWRCeXRlcyhKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdCBqYXZhRmQsIGpvYmplY3QgamF2YUJ5dGVzLCBqaW50IGJ5dGVPZmZzZXQsIGppbnQgYnl0ZUNvdW50KSB7CisgICAgU2NvcGVkQnl0ZXNSVyBieXRlcyhlbnYsIGphdmFCeXRlcyk7CisgICAgaWYgKGJ5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpbnQgZmQgPSBqbmlHZXRGREZyb21GaWxlRGVzY3JpcHRvcihlbnYsIGphdmFGZCk7CisgICAgcmV0dXJuIHRocm93SWZNaW51c09uZShlbnYsICJyZWFkIiwgVEVNUF9GQUlMVVJFX1JFVFJZKHJlYWQoZmQsIGJ5dGVzLmdldCgpICsgYnl0ZU9mZnNldCwgYnl0ZUNvdW50KSkpOworfQorCitzdGF0aWMgamludCBQb3NpeF9yZWFkdihKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdCBqYXZhRmQsIGpvYmplY3RBcnJheSBidWZmZXJzLCBqaW50QXJyYXkgb2Zmc2V0cywgamludEFycmF5IGJ5dGVDb3VudHMpIHsKKyAgICBJb1ZlYzxTY29wZWRCeXRlc1JXPiBpb1ZlYyhlbnYsIGVudi0+R2V0QXJyYXlMZW5ndGgoYnVmZmVycykpOworICAgIGlmICghaW9WZWMuaW5pdChidWZmZXJzLCBvZmZzZXRzLCBieXRlQ291bnRzKSkgeworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGludCBmZCA9IGpuaUdldEZERnJvbUZpbGVEZXNjcmlwdG9yKGVudiwgamF2YUZkKTsKKyAgICByZXR1cm4gdGhyb3dJZk1pbnVzT25lKGVudiwgInJlYWR2IiwgVEVNUF9GQUlMVVJFX1JFVFJZKHJlYWR2KGZkLCBpb1ZlYy5nZXQoKSwgaW9WZWMuc2l6ZSgpKSkpOworfQorCitzdGF0aWMgamludCBQb3NpeF9yZWN2ZnJvbUJ5dGVzKEpOSUVudiogZW52LCBqb2JqZWN0LCBqb2JqZWN0IGphdmFGZCwgam9iamVjdCBqYXZhQnl0ZXMsIGppbnQgYnl0ZU9mZnNldCwgamludCBieXRlQ291bnQsIGppbnQgZmxhZ3MsIGpvYmplY3QgamF2YUluZXRTb2NrZXRBZGRyZXNzKSB7CisgICAgU2NvcGVkQnl0ZXNSVyBieXRlcyhlbnYsIGphdmFCeXRlcyk7CisgICAgaWYgKGJ5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBzb2NrYWRkcl9zdG9yYWdlIHNzOworICAgIHNvY2tsZW5fdCBzbCA9IHNpemVvZihzcyk7CisgICAgbWVtc2V0KCZzcywgMCwgc2l6ZW9mKHNzKSk7CisgICAgaW50IGZkOworICAgIHNvY2thZGRyKiBmcm9tID0gKGphdmFJbmV0U29ja2V0QWRkcmVzcyAhPSBOVUxMKSA/IHJlaW50ZXJwcmV0X2Nhc3Q8c29ja2FkZHIqPigmc3MpIDogTlVMTDsKKyAgICBzb2NrbGVuX3QqIGZyb21MZW5ndGggPSAoamF2YUluZXRTb2NrZXRBZGRyZXNzICE9IE5VTEwpID8gJnNsIDogMDsKKyAgICBqaW50IHJlY3ZDb3VudCA9IE5FVF9GQUlMVVJFX1JFVFJZKCJyZWN2ZnJvbSIsIHJlY3Zmcm9tKGZkLCBieXRlcy5nZXQoKSArIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCwgZmxhZ3MsIGZyb20sIGZyb21MZW5ndGgpKTsKKyAgICBmaWxsSW5ldFNvY2tldEFkZHJlc3MoZW52LCByZWN2Q291bnQsIGphdmFJbmV0U29ja2V0QWRkcmVzcywgJnNzKTsKKyAgICByZXR1cm4gcmVjdkNvdW50OworfQorCitzdGF0aWMgdm9pZCBQb3NpeF9yZW1vdmUoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpzdHJpbmcgamF2YVBhdGgpIHsKKyAgICBTY29wZWRVdGZDaGFycyBwYXRoKGVudiwgamF2YVBhdGgpOworICAgIGlmIChwYXRoLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm47CisgICAgfQorICAgIHRocm93SWZNaW51c09uZShlbnYsICJyZW1vdmUiLCBURU1QX0ZBSUxVUkVfUkVUUlkocmVtb3ZlKHBhdGguY19zdHIoKSkpKTsKK30KKworc3RhdGljIHZvaWQgUG9zaXhfcmVuYW1lKEpOSUVudiogZW52LCBqb2JqZWN0LCBqc3RyaW5nIGphdmFPbGRQYXRoLCBqc3RyaW5nIGphdmFOZXdQYXRoKSB7CisgICAgU2NvcGVkVXRmQ2hhcnMgb2xkUGF0aChlbnYsIGphdmFPbGRQYXRoKTsKKyAgICBpZiAob2xkUGF0aC5jX3N0cigpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBTY29wZWRVdGZDaGFycyBuZXdQYXRoKGVudiwgamF2YU5ld1BhdGgpOworICAgIGlmIChuZXdQYXRoLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm47CisgICAgfQorICAgIHRocm93SWZNaW51c09uZShlbnYsICJyZW5hbWUiLCBURU1QX0ZBSUxVUkVfUkVUUlkocmVuYW1lKG9sZFBhdGguY19zdHIoKSwgbmV3UGF0aC5jX3N0cigpKSkpOworfQorCitzdGF0aWMgamxvbmcgUG9zaXhfc2VuZGZpbGUoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpvYmplY3QgamF2YU91dEZkLCBqb2JqZWN0IGphdmFJbkZkLCBqb2JqZWN0IGphdmFPZmZzZXQsIGpsb25nIGJ5dGVDb3VudCkgeworICAgIGludCBvdXRGZCA9IGpuaUdldEZERnJvbUZpbGVEZXNjcmlwdG9yKGVudiwgamF2YU91dEZkKTsKKyAgICBpbnQgaW5GZCA9IGpuaUdldEZERnJvbUZpbGVEZXNjcmlwdG9yKGVudiwgamF2YUluRmQpOworICAgIHN0YXRpYyBqZmllbGRJRCB2YWx1ZUZpZCA9IGVudi0+R2V0RmllbGRJRChKbmlDb25zdGFudHM6Om11dGFibGVMb25nQ2xhc3MsICJ2YWx1ZSIsICJKIik7CisgICAgb2ZmX3Qgb2Zmc2V0ID0gMDsKKyAgICBvZmZfdCogb2Zmc2V0UHRyID0gTlVMTDsKKyAgICBpZiAoamF2YU9mZnNldCAhPSBOVUxMKSB7CisgICAgICAgIC8vIFRPRE86IGZpeCBiaW9uaWMgc28gd2UgY2FuIGhhdmUgYSA2NC1iaXQgb2ZmX3QhCisgICAgICAgIG9mZnNldCA9IGVudi0+R2V0TG9uZ0ZpZWxkKGphdmFPZmZzZXQsIHZhbHVlRmlkKTsKKyAgICAgICAgb2Zmc2V0UHRyID0gJm9mZnNldDsKKyAgICB9CisgICAgamxvbmcgcmVzdWx0ID0gdGhyb3dJZk1pbnVzT25lKGVudiwgInNlbmRmaWxlIiwgVEVNUF9GQUlMVVJFX1JFVFJZKHNlbmRmaWxlKG91dEZkLCBpbkZkLCBvZmZzZXRQdHIsIGJ5dGVDb3VudCkpKTsKKyAgICBpZiAoamF2YU9mZnNldCAhPSBOVUxMKSB7CisgICAgICAgIGVudi0+U2V0TG9uZ0ZpZWxkKGphdmFPZmZzZXQsIHZhbHVlRmlkLCBvZmZzZXQpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgamludCBQb3NpeF9zZW5kdG9CeXRlcyhKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdCBqYXZhRmQsIGpvYmplY3QgamF2YUJ5dGVzLCBqaW50IGJ5dGVPZmZzZXQsIGppbnQgYnl0ZUNvdW50LCBqaW50IGZsYWdzLCBqb2JqZWN0IGphdmFJbmV0QWRkcmVzcywgamludCBwb3J0KSB7CisgICAgU2NvcGVkQnl0ZXNSTyBieXRlcyhlbnYsIGphdmFCeXRlcyk7CisgICAgaWYgKGJ5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBzb2NrYWRkcl9zdG9yYWdlIHNzOworICAgIGlmIChqYXZhSW5ldEFkZHJlc3MgIT0gTlVMTCAmJiAhaW5ldEFkZHJlc3NUb1NvY2thZGRyKGVudiwgamF2YUluZXRBZGRyZXNzLCBwb3J0LCAmc3MpKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaW50IGZkOworICAgIGNvbnN0IHNvY2thZGRyKiB0byA9IChqYXZhSW5ldEFkZHJlc3MgIT0gTlVMTCkgPyByZWludGVycHJldF9jYXN0PGNvbnN0IHNvY2thZGRyKj4oJnNzKSA6IE5VTEw7CisgICAgc29ja2xlbl90IHRvTGVuZ3RoID0gKGphdmFJbmV0QWRkcmVzcyAhPSBOVUxMKSA/IHNpemVvZihzcykgOiAwOworICAgIHJldHVybiBORVRfRkFJTFVSRV9SRVRSWSgic2VuZHRvIiwgc2VuZHRvKGZkLCBieXRlcy5nZXQoKSArIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCwgZmxhZ3MsIHRvLCB0b0xlbmd0aCkpOworfQorCitzdGF0aWMgdm9pZCBQb3NpeF9zZXRlZ2lkKEpOSUVudiogZW52LCBqb2JqZWN0LCBqaW50IGVnaWQpIHsKKyAgICB0aHJvd0lmTWludXNPbmUoZW52LCAic2V0ZWdpZCIsIFRFTVBfRkFJTFVSRV9SRVRSWShzZXRlZ2lkKGVnaWQpKSk7Cit9CisKK3N0YXRpYyB2b2lkIFBvc2l4X3NldGV1aWQoSk5JRW52KiBlbnYsIGpvYmplY3QsIGppbnQgZXVpZCkgeworICAgIHRocm93SWZNaW51c09uZShlbnYsICJzZXRldWlkIiwgVEVNUF9GQUlMVVJFX1JFVFJZKHNldGV1aWQoZXVpZCkpKTsKK30KKworc3RhdGljIHZvaWQgUG9zaXhfc2V0Z2lkKEpOSUVudiogZW52LCBqb2JqZWN0LCBqaW50IGdpZCkgeworICAgIHRocm93SWZNaW51c09uZShlbnYsICJzZXRnaWQiLCBURU1QX0ZBSUxVUkVfUkVUUlkoc2V0Z2lkKGdpZCkpKTsKK30KKworc3RhdGljIHZvaWQgUG9zaXhfc2V0c29ja29wdEJ5dGUoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpvYmplY3QgamF2YUZkLCBqaW50IGxldmVsLCBqaW50IG9wdGlvbiwgamludCB2YWx1ZSkgeworICAgIGludCBmZCA9IGpuaUdldEZERnJvbUZpbGVEZXNjcmlwdG9yKGVudiwgamF2YUZkKTsKKyAgICB1X2NoYXIgYnl0ZSA9IHZhbHVlOworICAgIHRocm93SWZNaW51c09uZShlbnYsICJzZXRzb2Nrb3B0IiwgVEVNUF9GQUlMVVJFX1JFVFJZKHNldHNvY2tvcHQoZmQsIGxldmVsLCBvcHRpb24sICZieXRlLCBzaXplb2YoYnl0ZSkpKSk7Cit9CisKK3N0YXRpYyB2b2lkIFBvc2l4X3NldHNvY2tvcHRJZnJlcShKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdCBqYXZhRmQsIGppbnQgbGV2ZWwsIGppbnQgb3B0aW9uLCBqc3RyaW5nIGphdmFJbnRlcmZhY2VOYW1lKSB7CisgICAgc3RydWN0IGlmcmVxIHJlcTsKKyAgICBpZiAoIWZpbGxJZnJlcShlbnYsIGphdmFJbnRlcmZhY2VOYW1lLCByZXEpKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIHRocm93SWZNaW51c09uZShlbnYsICJzZXRzb2Nrb3B0IiwgVEVNUF9GQUlMVVJFX1JFVFJZKHNldHNvY2tvcHQoZmQsIGxldmVsLCBvcHRpb24sICZyZXEsIHNpemVvZihyZXEpKSkpOworfQorCitzdGF0aWMgdm9pZCBQb3NpeF9zZXRzb2Nrb3B0SW50KEpOSUVudiogZW52LCBqb2JqZWN0LCBqb2JqZWN0IGphdmFGZCwgamludCBsZXZlbCwgamludCBvcHRpb24sIGppbnQgdmFsdWUpIHsKKyAgICBpbnQgZmQgPSBqbmlHZXRGREZyb21GaWxlRGVzY3JpcHRvcihlbnYsIGphdmFGZCk7CisgICAgdGhyb3dJZk1pbnVzT25lKGVudiwgInNldHNvY2tvcHQiLCBURU1QX0ZBSUxVUkVfUkVUUlkoc2V0c29ja29wdChmZCwgbGV2ZWwsIG9wdGlvbiwgJnZhbHVlLCBzaXplb2YodmFsdWUpKSkpOworfQorCitzdGF0aWMgdm9pZCBQb3NpeF9zZXRzb2Nrb3B0SXBNcmVxbihKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdCBqYXZhRmQsIGppbnQgbGV2ZWwsIGppbnQgb3B0aW9uLCBqaW50IHZhbHVlKSB7CisgICAgaXBfbXJlcW4gcmVxOworICAgIG1lbXNldCgmcmVxLCAwLCBzaXplb2YocmVxKSk7CisgICAgcmVxLmltcl9pZmluZGV4ID0gdmFsdWU7CisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIHRocm93SWZNaW51c09uZShlbnYsICJzZXRzb2Nrb3B0IiwgVEVNUF9GQUlMVVJFX1JFVFJZKHNldHNvY2tvcHQoZmQsIGxldmVsLCBvcHRpb24sICZyZXEsIHNpemVvZihyZXEpKSkpOworfQorCitzdGF0aWMgdm9pZCBQb3NpeF9zZXRzb2Nrb3B0R3JvdXBSZXEoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpvYmplY3QgamF2YUZkLCBqaW50IGxldmVsLCBqaW50IG9wdGlvbiwgam9iamVjdCBqYXZhR3JvdXBSZXEpIHsKKyAgICBzdHJ1Y3QgZ3JvdXBfcmVxIHJlcTsKKyAgICBtZW1zZXQoJnJlcSwgMCwgc2l6ZW9mKHJlcSkpOworCisgICAgc3RhdGljIGpmaWVsZElEIGdySW50ZXJmYWNlRmlkID0gZW52LT5HZXRGaWVsZElEKEpuaUNvbnN0YW50czo6c3RydWN0R3JvdXBSZXFDbGFzcywgImdyX2ludGVyZmFjZSIsICJJIik7CisgICAgcmVxLmdyX2ludGVyZmFjZSA9IGVudi0+R2V0SW50RmllbGQoamF2YUdyb3VwUmVxLCBnckludGVyZmFjZUZpZCk7CisgICAgLy8gR2V0IHRoZSBJUHY0IG9yIElQdjYgbXVsdGljYXN0IGFkZHJlc3MgdG8gam9pbiBvciBsZWF2ZS4KKyAgICBzdGF0aWMgamZpZWxkSUQgZ3JHcm91cEZpZCA9IGVudi0+R2V0RmllbGRJRChKbmlDb25zdGFudHM6OnN0cnVjdEdyb3VwUmVxQ2xhc3MsICJncl9ncm91cCIsICJMamF2YS9uZXQvSW5ldEFkZHJlc3M7Iik7CisgICAgU2NvcGVkTG9jYWxSZWY8am9iamVjdD4gamF2YUdyb3VwKGVudiwgZW52LT5HZXRPYmplY3RGaWVsZChqYXZhR3JvdXBSZXEsIGdyR3JvdXBGaWQpKTsKKyAgICBpZiAoIWluZXRBZGRyZXNzVG9Tb2NrYWRkclZlcmJhdGltKGVudiwgamF2YUdyb3VwLmdldCgpLCAwLCAmcmVxLmdyX2dyb3VwKSkgeworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIGludCByYyA9IFRFTVBfRkFJTFVSRV9SRVRSWShzZXRzb2Nrb3B0KGZkLCBsZXZlbCwgb3B0aW9uLCAmcmVxLCBzaXplb2YocmVxKSkpOworICAgIGlmIChyYyA9PSAtMSAmJiBlcnJubyA9PSBFSU5WQUwpIHsKKyAgICAgICAgLy8gTWF5YmUgd2UncmUgYSAzMi1iaXQgYmluYXJ5IHRhbGtpbmcgdG8gYSA2NC1iaXQga2VybmVsPworICAgICAgICAvLyBnbGliYyBkb2Vzbid0IGF1dG9tYXRpY2FsbHkgaGFuZGxlIHRoaXMuCisgICAgICAgIHN0cnVjdCBHQ0NfSElEREVOIGdyb3VwX3JlcTY0IHsKKyAgICAgICAgICAgIHVpbnQzMl90IGdyX2ludGVyZmFjZTsKKyAgICAgICAgICAgIHVpbnQzMl90IG15X3BhZGRpbmc7CisgICAgICAgICAgICBzb2NrYWRkcl9zdG9yYWdlIGdyX2dyb3VwOworICAgICAgICB9OworICAgICAgICBncm91cF9yZXE2NCByZXE2NDsKKyAgICAgICAgcmVxNjQuZ3JfaW50ZXJmYWNlID0gcmVxLmdyX2ludGVyZmFjZTsKKyAgICAgICAgbWVtY3B5KCZyZXE2NC5ncl9ncm91cCwgJnJlcS5ncl9ncm91cCwgc2l6ZW9mKHJlcS5ncl9ncm91cCkpOworICAgICAgICByYyA9IFRFTVBfRkFJTFVSRV9SRVRSWShzZXRzb2Nrb3B0KGZkLCBsZXZlbCwgb3B0aW9uLCAmcmVxNjQsIHNpemVvZihyZXE2NCkpKTsKKyAgICB9CisgICAgdGhyb3dJZk1pbnVzT25lKGVudiwgInNldHNvY2tvcHQiLCByYyk7Cit9CisKK3N0YXRpYyB2b2lkIFBvc2l4X3NldHNvY2tvcHRMaW5nZXIoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpvYmplY3QgamF2YUZkLCBqaW50IGxldmVsLCBqaW50IG9wdGlvbiwgam9iamVjdCBqYXZhTGluZ2VyKSB7CisgICAgc3RhdGljIGpmaWVsZElEIGxPbm9mZkZpZCA9IGVudi0+R2V0RmllbGRJRChKbmlDb25zdGFudHM6OnN0cnVjdExpbmdlckNsYXNzLCAibF9vbm9mZiIsICJJIik7CisgICAgc3RhdGljIGpmaWVsZElEIGxMaW5nZXJGaWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjpzdHJ1Y3RMaW5nZXJDbGFzcywgImxfbGluZ2VyIiwgIkkiKTsKKyAgICBpbnQgZmQgPSBqbmlHZXRGREZyb21GaWxlRGVzY3JpcHRvcihlbnYsIGphdmFGZCk7CisgICAgc3RydWN0IGxpbmdlciB2YWx1ZTsKKyAgICB2YWx1ZS5sX29ub2ZmID0gZW52LT5HZXRJbnRGaWVsZChqYXZhTGluZ2VyLCBsT25vZmZGaWQpOworICAgIHZhbHVlLmxfbGluZ2VyID0gZW52LT5HZXRJbnRGaWVsZChqYXZhTGluZ2VyLCBsTGluZ2VyRmlkKTsKKyAgICB0aHJvd0lmTWludXNPbmUoZW52LCAic2V0c29ja29wdCIsIFRFTVBfRkFJTFVSRV9SRVRSWShzZXRzb2Nrb3B0KGZkLCBsZXZlbCwgb3B0aW9uLCAmdmFsdWUsIHNpemVvZih2YWx1ZSkpKSk7Cit9CisKK3N0YXRpYyB2b2lkIFBvc2l4X3NldHNvY2tvcHRUaW1ldmFsKEpOSUVudiogZW52LCBqb2JqZWN0LCBqb2JqZWN0IGphdmFGZCwgamludCBsZXZlbCwgamludCBvcHRpb24sIGpvYmplY3QgamF2YVRpbWV2YWwpIHsKKyAgICBzdGF0aWMgamZpZWxkSUQgdHZTZWNGaWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjpzdHJ1Y3RUaW1ldmFsQ2xhc3MsICJ0dl9zZWMiLCAiSiIpOworICAgIHN0YXRpYyBqZmllbGRJRCB0dlVzZWNGaWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjpzdHJ1Y3RUaW1ldmFsQ2xhc3MsICJ0dl91c2VjIiwgIkoiKTsKKyAgICBpbnQgZmQgPSBqbmlHZXRGREZyb21GaWxlRGVzY3JpcHRvcihlbnYsIGphdmFGZCk7CisgICAgc3RydWN0IHRpbWV2YWwgdmFsdWU7CisgICAgdmFsdWUudHZfc2VjID0gZW52LT5HZXRMb25nRmllbGQoamF2YVRpbWV2YWwsIHR2U2VjRmlkKTsKKyAgICB2YWx1ZS50dl91c2VjID0gZW52LT5HZXRMb25nRmllbGQoamF2YVRpbWV2YWwsIHR2VXNlY0ZpZCk7CisgICAgdGhyb3dJZk1pbnVzT25lKGVudiwgInNldHNvY2tvcHQiLCBURU1QX0ZBSUxVUkVfUkVUUlkoc2V0c29ja29wdChmZCwgbGV2ZWwsIG9wdGlvbiwgJnZhbHVlLCBzaXplb2YodmFsdWUpKSkpOworfQorCitzdGF0aWMgdm9pZCBQb3NpeF9zZXR1aWQoSk5JRW52KiBlbnYsIGpvYmplY3QsIGppbnQgdWlkKSB7CisgICAgdGhyb3dJZk1pbnVzT25lKGVudiwgInNldHVpZCIsIFRFTVBfRkFJTFVSRV9SRVRSWShzZXR1aWQodWlkKSkpOworfQorCitzdGF0aWMgdm9pZCBQb3NpeF9zaHV0ZG93bihKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdCBqYXZhRmQsIGppbnQgaG93KSB7CisgICAgaW50IGZkID0gam5pR2V0RkRGcm9tRmlsZURlc2NyaXB0b3IoZW52LCBqYXZhRmQpOworICAgIHRocm93SWZNaW51c09uZShlbnYsICJzaHV0ZG93biIsIFRFTVBfRkFJTFVSRV9SRVRSWShzaHV0ZG93bihmZCwgaG93KSkpOworfQorCitzdGF0aWMgam9iamVjdCBQb3NpeF9zb2NrZXQoSk5JRW52KiBlbnYsIGpvYmplY3QsIGppbnQgZG9tYWluLCBqaW50IHR5cGUsIGppbnQgcHJvdG9jb2wpIHsKKyAgICBpbnQgZmQgPSB0aHJvd0lmTWludXNPbmUoZW52LCAic29ja2V0IiwgVEVNUF9GQUlMVVJFX1JFVFJZKHNvY2tldChkb21haW4sIHR5cGUsIHByb3RvY29sKSkpOworICAgIHJldHVybiBmZCAhPSAtMSA/IGpuaUNyZWF0ZUZpbGVEZXNjcmlwdG9yKGVudiwgZmQpIDogTlVMTDsKK30KKworc3RhdGljIGpvYmplY3QgUG9zaXhfc3RhdChKTklFbnYqIGVudiwgam9iamVjdCwganN0cmluZyBqYXZhUGF0aCkgeworICAgIHJldHVybiBkb1N0YXQoZW52LCBqYXZhUGF0aCwgZmFsc2UpOworfQorCitzdGF0aWMgam9iamVjdCBQb3NpeF9zdGF0ZnMoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpzdHJpbmcgamF2YVBhdGgpIHsKKyAgICBTY29wZWRVdGZDaGFycyBwYXRoKGVudiwgamF2YVBhdGgpOworICAgIGlmIChwYXRoLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgc3RydWN0IHN0YXRmcyBzYjsKKyAgICBpbnQgcmMgPSBURU1QX0ZBSUxVUkVfUkVUUlkoc3RhdGZzKHBhdGguY19zdHIoKSwgJnNiKSk7CisgICAgaWYgKHJjID09IC0xKSB7CisgICAgICAgIHRocm93RXJybm9FeGNlcHRpb24oZW52LCAic3RhdGZzIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gbWFrZVN0cnVjdFN0YXRGcyhlbnYsIHNiKTsKK30KKworc3RhdGljIGpzdHJpbmcgUG9zaXhfc3RyZXJyb3IoSk5JRW52KiBlbnYsIGpvYmplY3QsIGppbnQgZXJybnVtKSB7CisgICAgY2hhciBidWZmZXJbQlVGU0laXTsKKyAgICBjb25zdCBjaGFyKiBtZXNzYWdlID0gam5pU3RyRXJyb3IoZXJybnVtLCBidWZmZXIsIHNpemVvZihidWZmZXIpKTsKKyAgICByZXR1cm4gZW52LT5OZXdTdHJpbmdVVEYobWVzc2FnZSk7Cit9CisKK3N0YXRpYyB2b2lkIFBvc2l4X3N5bWxpbmsoSk5JRW52KiBlbnYsIGpvYmplY3QsIGpzdHJpbmcgamF2YU9sZFBhdGgsIGpzdHJpbmcgamF2YU5ld1BhdGgpIHsKKyAgICBTY29wZWRVdGZDaGFycyBvbGRQYXRoKGVudiwgamF2YU9sZFBhdGgpOworICAgIGlmIChvbGRQYXRoLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm47CisgICAgfQorICAgIFNjb3BlZFV0ZkNoYXJzIG5ld1BhdGgoZW52LCBqYXZhTmV3UGF0aCk7CisgICAgaWYgKG5ld1BhdGguY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgdGhyb3dJZk1pbnVzT25lKGVudiwgInN5bWxpbmsiLCBURU1QX0ZBSUxVUkVfUkVUUlkoc3ltbGluayhvbGRQYXRoLmNfc3RyKCksIG5ld1BhdGguY19zdHIoKSkpKTsKK30KKworc3RhdGljIGpsb25nIFBvc2l4X3N5c2NvbmYoSk5JRW52KiBlbnYsIGpvYmplY3QsIGppbnQgbmFtZSkgeworICAgIC8vIFNpbmNlIC0xIGlzIGEgdmFsaWQgcmVzdWx0IGZyb20gc3lzY29uZigzKSwgZGV0ZWN0aW5nIGZhaWx1cmUgaXMgYSBsaXR0bGUgbW9yZSBhd2t3YXJkLgorICAgIGVycm5vID0gMDsKKyAgICBsb25nIHJlc3VsdCA9IHN5c2NvbmYobmFtZSk7CisgICAgaWYgKHJlc3VsdCA9PSAtMUwgJiYgZXJybm8gPT0gRUlOVkFMKSB7CisgICAgICAgIHRocm93RXJybm9FeGNlcHRpb24oZW52LCAic3lzY29uZiIpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgam9iamVjdCBQb3NpeF91bmFtZShKTklFbnYqIGVudiwgam9iamVjdCkgeworICAgIHN0cnVjdCB1dHNuYW1lIGJ1ZjsKKyAgICBpZiAoVEVNUF9GQUlMVVJFX1JFVFJZKHVuYW1lKCZidWYpKSA9PSAtMSkgeworICAgICAgICByZXR1cm4gTlVMTDsgLy8gQ2FuJ3QgaGFwcGVuLgorICAgIH0KKyAgICByZXR1cm4gbWFrZVN0cnVjdFV0c25hbWUoZW52LCBidWYpOworfQorCitzdGF0aWMgamludCBQb3NpeF93YWl0cGlkKEpOSUVudiogZW52LCBqb2JqZWN0LCBqaW50IHBpZCwgam9iamVjdCBqYXZhU3RhdHVzLCBqaW50IG9wdGlvbnMpIHsKKyAgICBpbnQgc3RhdHVzOworICAgIGludCByYyA9IHRocm93SWZNaW51c09uZShlbnYsICJ3YWl0cGlkIiwgVEVNUF9GQUlMVVJFX1JFVFJZKHdhaXRwaWQocGlkLCAmc3RhdHVzLCBvcHRpb25zKSkpOworICAgIGlmIChyYyAhPSAtMSkgeworICAgICAgICBzdGF0aWMgamZpZWxkSUQgdmFsdWVGaWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjptdXRhYmxlSW50Q2xhc3MsICJ2YWx1ZSIsICJJIik7CisgICAgICAgIGVudi0+U2V0SW50RmllbGQoamF2YVN0YXR1cywgdmFsdWVGaWQsIHN0YXR1cyk7CisgICAgfQorICAgIHJldHVybiByYzsKK30KKworc3RhdGljIGppbnQgUG9zaXhfd3JpdGVCeXRlcyhKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdCBqYXZhRmQsIGpieXRlQXJyYXkgamF2YUJ5dGVzLCBqaW50IGJ5dGVPZmZzZXQsIGppbnQgYnl0ZUNvdW50KSB7CisgICAgU2NvcGVkQnl0ZXNSTyBieXRlcyhlbnYsIGphdmFCeXRlcyk7CisgICAgaWYgKGJ5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpbnQgZmQgPSBqbmlHZXRGREZyb21GaWxlRGVzY3JpcHRvcihlbnYsIGphdmFGZCk7CisgICAgcmV0dXJuIHRocm93SWZNaW51c09uZShlbnYsICJ3cml0ZSIsIFRFTVBfRkFJTFVSRV9SRVRSWSh3cml0ZShmZCwgYnl0ZXMuZ2V0KCkgKyBieXRlT2Zmc2V0LCBieXRlQ291bnQpKSk7Cit9CisKK3N0YXRpYyBqaW50IFBvc2l4X3dyaXRldihKTklFbnYqIGVudiwgam9iamVjdCwgam9iamVjdCBqYXZhRmQsIGpvYmplY3RBcnJheSBidWZmZXJzLCBqaW50QXJyYXkgb2Zmc2V0cywgamludEFycmF5IGJ5dGVDb3VudHMpIHsKKyAgICBJb1ZlYzxTY29wZWRCeXRlc1JPPiBpb1ZlYyhlbnYsIGVudi0+R2V0QXJyYXlMZW5ndGgoYnVmZmVycykpOworICAgIGlmICghaW9WZWMuaW5pdChidWZmZXJzLCBvZmZzZXRzLCBieXRlQ291bnRzKSkgeworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGludCBmZCA9IGpuaUdldEZERnJvbUZpbGVEZXNjcmlwdG9yKGVudiwgamF2YUZkKTsKKyAgICByZXR1cm4gdGhyb3dJZk1pbnVzT25lKGVudiwgIndyaXRldiIsIFRFTVBfRkFJTFVSRV9SRVRSWSh3cml0ZXYoZmQsIGlvVmVjLmdldCgpLCBpb1ZlYy5zaXplKCkpKSk7Cit9CisKK3N0YXRpYyBKTklOYXRpdmVNZXRob2QgZ01ldGhvZHNbXSA9IHsKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBhY2NlcHQsICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7TGphdmEvbmV0L0luZXRTb2NrZXRBZGRyZXNzOylMamF2YS9pby9GaWxlRGVzY3JpcHRvcjsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBhY2Nlc3MsICIoTGphdmEvbGFuZy9TdHJpbmc7SSlaIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgYmluZCwgIihMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtMamF2YS9uZXQvSW5ldEFkZHJlc3M7SSlWIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgY2htb2QsICIoTGphdmEvbGFuZy9TdHJpbmc7SSlWIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgY2xvc2UsICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7KVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBjb25uZWN0LCAiKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yO0xqYXZhL25ldC9JbmV0QWRkcmVzcztJKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBkdXAsICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7KUxqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yOyIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIGR1cDIsICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7SSlMamF2YS9pby9GaWxlRGVzY3JpcHRvcjsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBlbnZpcm9uLCAiKClbTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgZmNudGxWb2lkLCAiKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yO0kpSSIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIGZjbnRsTG9uZywgIihMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtJSilJIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgZmNudGxGbG9jaywgIihMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtJTGxpYmNvcmUvaW8vU3RydWN0RmxvY2s7KUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBmZGF0YXN5bmMsICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7KVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBmc3RhdCwgIihMamF2YS9pby9GaWxlRGVzY3JpcHRvcjspTGxpYmNvcmUvaW8vU3RydWN0U3RhdDsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBmc3RhdGZzLCAiKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yOylMbGliY29yZS9pby9TdHJ1Y3RTdGF0RnM7IiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgZnN5bmMsICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7KVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBmdHJ1bmNhdGUsICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7SilWIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgZ2FpX3N0cmVycm9yLCAiKEkpTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgZ2V0YWRkcmluZm8sICIoTGphdmEvbGFuZy9TdHJpbmc7TGxpYmNvcmUvaW8vU3RydWN0QWRkcmluZm87KVtMamF2YS9uZXQvSW5ldEFkZHJlc3M7IiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgZ2V0ZWdpZCwgIigpSSIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIGdldGV1aWQsICIoKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBnZXRnaWQsICIoKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBnZXRlbnYsICIoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOyIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIGdldG5hbWVpbmZvLCAiKExqYXZhL25ldC9JbmV0QWRkcmVzcztJKUxqYXZhL2xhbmcvU3RyaW5nOyIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIGdldHBpZCwgIigpSSIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIGdldHBwaWQsICIoKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBnZXRwd25hbSwgIihMamF2YS9sYW5nL1N0cmluZzspTGxpYmNvcmUvaW8vU3RydWN0UGFzc3dkOyIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIGdldHB3dWlkLCAiKEkpTGxpYmNvcmUvaW8vU3RydWN0UGFzc3dkOyIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIGdldHNvY2tuYW1lLCAiKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yOylMamF2YS9uZXQvU29ja2V0QWRkcmVzczsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBnZXRzb2Nrb3B0Qnl0ZSwgIihMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtJSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgZ2V0c29ja29wdEluQWRkciwgIihMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtJSSlMamF2YS9uZXQvSW5ldEFkZHJlc3M7IiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgZ2V0c29ja29wdEludCwgIihMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtJSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgZ2V0c29ja29wdExpbmdlciwgIihMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtJSSlMbGliY29yZS9pby9TdHJ1Y3RMaW5nZXI7IiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgZ2V0c29ja29wdFRpbWV2YWwsICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7SUkpTGxpYmNvcmUvaW8vU3RydWN0VGltZXZhbDsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBnZXR1aWQsICIoKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBpZl9pbmRleHRvbmFtZSwgIihJKUxqYXZhL2xhbmcvU3RyaW5nOyIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIGluZXRfcHRvbiwgIihJTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL25ldC9JbmV0QWRkcmVzczsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBpb2N0bEluZXRBZGRyZXNzLCAiKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yO0lMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbmV0L0luZXRBZGRyZXNzOyIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIGlvY3RsSW50LCAiKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yO0lMbGliY29yZS91dGlsL011dGFibGVJbnQ7KUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBpc2F0dHksICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7KVoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBraWxsLCAiKElJKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBsaXN0ZW4sICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7SSlWIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgbHNlZWssICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7SkkpSiIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIGxzdGF0LCAiKExqYXZhL2xhbmcvU3RyaW5nOylMbGliY29yZS9pby9TdHJ1Y3RTdGF0OyIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIG1pbmNvcmUsICIoSkpbQilWIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgbWtkaXIsICIoTGphdmEvbGFuZy9TdHJpbmc7SSlWIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgbWxvY2ssICIoSkopViIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIG1tYXAsICIoSkpJSUxqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yO0opSiIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIG1zeW5jLCAiKEpKSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgbXVubG9jaywgIihKSilWIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgbXVubWFwLCAiKEpKKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBvcGVuLCAiKExqYXZhL2xhbmcvU3RyaW5nO0lJKUxqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yOyIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIHBpcGUsICIoKVtMamF2YS9pby9GaWxlRGVzY3JpcHRvcjsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBwb2xsLCAiKFtMbGliY29yZS9pby9TdHJ1Y3RQb2xsZmQ7SSlJIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgcHJlYWRCeXRlcywgIihMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtMamF2YS9sYW5nL09iamVjdDtJSUopSSIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIHB3cml0ZUJ5dGVzLCAiKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yO0xqYXZhL2xhbmcvT2JqZWN0O0lJSilJIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgcmVhZEJ5dGVzLCAiKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yO0xqYXZhL2xhbmcvT2JqZWN0O0lJKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCByZWFkdiwgIihMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtbTGphdmEvbGFuZy9PYmplY3Q7W0lbSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgcmVjdmZyb21CeXRlcywgIihMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtMamF2YS9sYW5nL09iamVjdDtJSUlMamF2YS9uZXQvSW5ldFNvY2tldEFkZHJlc3M7KUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCByZW1vdmUsICIoTGphdmEvbGFuZy9TdHJpbmc7KVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCByZW5hbWUsICIoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7KVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBzZW5kZmlsZSwgIihMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtMbGliY29yZS91dGlsL011dGFibGVMb25nO0opSiIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIHNlbmR0b0J5dGVzLCAiKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yO0xqYXZhL2xhbmcvT2JqZWN0O0lJSUxqYXZhL25ldC9JbmV0QWRkcmVzcztJKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBzZXRlZ2lkLCAiKEkpViIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIHNldGV1aWQsICIoSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgc2V0Z2lkLCAiKEkpViIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIHNldHNvY2tvcHRCeXRlLCAiKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yO0lJSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgc2V0c29ja29wdElmcmVxLCAiKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yO0lJTGphdmEvbGFuZy9TdHJpbmc7KVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBzZXRzb2Nrb3B0SW50LCAiKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yO0lJSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgc2V0c29ja29wdElwTXJlcW4sICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7SUlJKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBzZXRzb2Nrb3B0R3JvdXBSZXEsICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7SUlMbGliY29yZS9pby9TdHJ1Y3RHcm91cFJlcTspViIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIHNldHNvY2tvcHRMaW5nZXIsICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7SUlMbGliY29yZS9pby9TdHJ1Y3RMaW5nZXI7KVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBzZXRzb2Nrb3B0VGltZXZhbCwgIihMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtJSUxsaWJjb3JlL2lvL1N0cnVjdFRpbWV2YWw7KVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBzZXR1aWQsICIoSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgc2h1dGRvd24sICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7SSlWIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgc29ja2V0LCAiKElJSSlMamF2YS9pby9GaWxlRGVzY3JpcHRvcjsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKFBvc2l4LCBzdGF0LCAiKExqYXZhL2xhbmcvU3RyaW5nOylMbGliY29yZS9pby9TdHJ1Y3RTdGF0OyIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIHN0YXRmcywgIihMamF2YS9sYW5nL1N0cmluZzspTGxpYmNvcmUvaW8vU3RydWN0U3RhdEZzOyIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIHN0cmVycm9yLCAiKEkpTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgc3ltbGluaywgIihMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZzspViIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIHN5c2NvbmYsICIoSSlKIiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgdW5hbWUsICIoKUxsaWJjb3JlL2lvL1N0cnVjdFV0c25hbWU7IiksCisgICAgTkFUSVZFX01FVEhPRChQb3NpeCwgd2FpdHBpZCwgIihJTGxpYmNvcmUvdXRpbC9NdXRhYmxlSW50O0kpSSIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIHdyaXRlQnl0ZXMsICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7TGphdmEvbGFuZy9PYmplY3Q7SUkpSSIpLAorICAgIE5BVElWRV9NRVRIT0QoUG9zaXgsIHdyaXRldiwgIihMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtbTGphdmEvbGFuZy9PYmplY3Q7W0lbSSlJIiksCit9OworaW50IHJlZ2lzdGVyX2xpYmNvcmVfaW9fUG9zaXgoSk5JRW52KiBlbnYpIHsKKyAgICByZXR1cm4gam5pUmVnaXN0ZXJOYXRpdmVNZXRob2RzKGVudiwgImxpYmNvcmUvaW8vUG9zaXgiLCBnTWV0aG9kcywgTkVMRU0oZ01ldGhvZHMpKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL2xpYmNvcmVfbmV0X1Jhd1NvY2tldC5jcHAgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9saWJjb3JlX25ldF9SYXdTb2NrZXQuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE0Mzk4ZjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9saWJjb3JlX25ldF9SYXdTb2NrZXQuY3BwCkBAIC0wLDAgKzEsMjE1IEBACisvKgorICogQ29weXJpZ2h0IDIwMTAsIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSAiQXN5bmNocm9ub3VzU29ja2V0Q2xvc2VNb25pdG9yLmgiCisjaW5jbHVkZSAiSk5JSGVscC5oIgorI2luY2x1ZGUgIkpuaUV4Y2VwdGlvbi5oIgorI2luY2x1ZGUgIkpuaUNvbnN0YW50cy5oIgorI2luY2x1ZGUgIk5ldEZkLmgiCisjaW5jbHVkZSAiTmV0d29ya1V0aWxpdGllcy5oIgorI2luY2x1ZGUgIlNjb3BlZFV0ZkNoYXJzLmgiCisjaW5jbHVkZSAiU2NvcGVkUHJpbWl0aXZlQXJyYXkuaCIKKworI2luY2x1ZGUgImpuaS5oIgorCisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8c3lzL3NvY2tldC5oPgorI2luY2x1ZGUgPGxpbnV4L3J0bmV0bGluay5oPgorI2luY2x1ZGUgPG5ldC9pZi5oPgorI2luY2x1ZGUgPGxpbnV4L2lmX2V0aGVyLmg+CisjaW5jbHVkZSA8bGludXgvaWZfcGFja2V0Lmg+CisjaW5jbHVkZSA8YXJwYS9pbmV0Lmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2luY2x1ZGUgPHBvbGwuaD4KKyNpbmNsdWRlIDxuZXRpbmV0L2lwLmg+CisjaW5jbHVkZSA8bGludXgvdWRwLmg+CisKK3VuaW9uIEdDQ19ISURERU4gc29ja3VuaW9uIHsKKyAgICBzb2NrYWRkciBzYTsKKyAgICBzb2NrYWRkcl9sbCBzbGw7Cit9IHN1OworCisvKgorICogQ3JlYXRlcyBhIHNvY2tldCBzdWl0YWJsZSBmb3IgcmF3IHNvY2tldCBvcGVyYXRpb25zLiAgVGhlIHNvY2tldCBpcworICogYm91bmQgdG8gdGhlIGludGVyZmFjZSBzcGVjaWZpZWQgYnkgdGhlIHN1cHBsaWVkIG5hbWUuICBUaGUgc29ja2V0CisgKiB2YWx1ZSBpcyBwbGFjZWQgaW50byB0aGUgc3VwcGxpZWQgRmlsZURlc2NyaXB0b3IgaW5zdGFuY2UuCisgKgorICogVE9ETyhjaGVzbnV0dCk6IGNvbnNpZGVyIGJyZWFraW5nIHRoaXMgaW50byBwaWVjZXM6IGNyZWF0ZSBhCisgKiB2YXJpZXR5IG9mIGNvbnN0cnVjdG9ycyBmb3IgZGlmZmVyZW50IHNvY2tldCB0eXBlcywgdGhlbiBhIGdlbmVyaWMKKyAqIHNldEJsb2NraW5nKCkgbWV0aG9kIGZvbGxvd2VkIGJ5IHBvbHltb3JwaGljIGJpbmQoKS4KKyAqLworc3RhdGljIHZvaWQgUmF3U29ja2V0X2NyZWF0ZShKTklFbnYqIGVudiwgamNsYXNzLCBqb2JqZWN0IGZpbGVEZXNjcmlwdG9yLAorICAgIGpzdHJpbmcgaW50ZXJmYWNlTmFtZSkgeworCisgIFNjb3BlZFV0ZkNoYXJzIGlmbmFtZShlbnYsIGludGVyZmFjZU5hbWUpOworICBpZiAoaWZuYW1lLmNfc3RyKCkgPT0gTlVMTCkgeworICAgIHJldHVybjsKKyAgfQorCisgIHNob3J0IHByb3RvY29sID0gRVRIX1BfSVA7CisgIHNvY2t1bmlvbiBzdTsKKyAgbWVtc2V0KCZzdSwgMCwgc2l6ZW9mKHN1KSk7CisgIHN1LnNsbC5zbGxfZmFtaWx5ID0gUEZfUEFDS0VUOworICBzdS5zbGwuc2xsX3Byb3RvY29sID0gaHRvbnMocHJvdG9jb2wpOworICBzdS5zbGwuc2xsX2lmaW5kZXggPSBpZl9uYW1ldG9pbmRleChpZm5hbWUuY19zdHIoKSk7CisKKyAgaW50IHNvY2sgPSBzb2NrZXQoUEZfUEFDS0VULCBTT0NLX0RHUkFNLCBodG9ucyhwcm90b2NvbCkpOworICBpZiAoc29jayA9PSAtMSkgeworICAgIExPR0UoIkNhbid0IGNyZWF0ZSBzb2NrZXQgJXMiLCBzdHJlcnJvcihlcnJubykpOworICAgIGpuaVRocm93U29ja2V0RXhjZXB0aW9uKGVudiwgZXJybm8pOworICAgIHJldHVybjsKKyAgfQorCisgIGpuaVNldEZpbGVEZXNjcmlwdG9yT2ZGRChlbnYsIGZpbGVEZXNjcmlwdG9yLCBzb2NrKTsKKyAgaWYgKCFzZXRCbG9ja2luZyhzb2NrLCBmYWxzZSkpIHsKKyAgICBMT0dFKCJDYW4ndCBzZXQgbm9uLWJsb2NraW5nIG1vZGUgb24gc29ja2V0ICVzIiwgc3RyZXJyb3IoZXJybm8pKTsKKyAgICBqbmlUaHJvd1NvY2tldEV4Y2VwdGlvbihlbnYsIGVycm5vKTsKKyAgICByZXR1cm47CisgIH0KKworICBpbnQgZXJyID0gYmluZChzb2NrLCAmc3Uuc2EsIHNpemVvZihzdSkpOworICBpZiAoZXJyICE9IDApIHsKKyAgICBMT0dFKCJTb2NrZXQgYmluZCBlcnJvciAlcyIsIHN0cmVycm9yKGVycm5vKSk7CisgICAgam5pVGhyb3dTb2NrZXRFeGNlcHRpb24oZW52LCBlcnJubyk7CisgICAgcmV0dXJuOworICB9Cit9CisKKy8qCisgKiBXcml0ZXMgdGhlIEwzIChJUCkgcGFja2V0IHRvIHRoZSByYXcgc29ja2V0IHN1cHBsaWVkIGluIHRoZQorICogRmlsZURlc2NyaXB0b3IgaW5zdGFuY2UuCisgKgorICogQXNzdW1lcyB0aGF0IHRoZSBjYWxsZXIgaGFzIHZhbGlkYXRlZCB0aGUgb2Zmc2V0ICYgYnl0ZUNvdW50IHZhbHVlcy4KKyAqLworc3RhdGljIGludCBSYXdTb2NrZXRfc2VuZFBhY2tldChKTklFbnYqIGVudiwgamNsYXNzLCBqb2JqZWN0IGZpbGVEZXNjcmlwdG9yLAorICAgIGpzdHJpbmcgaW50ZXJmYWNlTmFtZSwgamJ5dGVBcnJheSBkZXN0TWFjLCBqYnl0ZUFycmF5IHBhY2tldCwgamludCBvZmZzZXQsCisgICAgamludCBieXRlQ291bnQpCit7CisgIE5ldEZkIGZkKGVudiwgZmlsZURlc2NyaXB0b3IpOworCisgIGlmIChmZC5pc0Nsb3NlZCgpKSB7CisgICAgcmV0dXJuIDA7CisgIH0KKworICBTY29wZWRVdGZDaGFycyBpZm5hbWUoZW52LCBpbnRlcmZhY2VOYW1lKTsKKyAgaWYgKGlmbmFtZS5jX3N0cigpID09IE5VTEwpIHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIFNjb3BlZEJ5dGVBcnJheVJPIGJ5dGVBcnJheShlbnYsIHBhY2tldCk7CisgIGlmIChieXRlQXJyYXkuZ2V0KCkgPT0gTlVMTCkgeworICAgIHJldHVybiAwOworICB9CisKKyAgU2NvcGVkQnl0ZUFycmF5Uk8gbWFjKGVudiwgZGVzdE1hYyk7CisgIGlmIChtYWMuZ2V0KCkgPT0gTlVMTCkgeworICAgIHJldHVybiAwOworICB9CisKKyAgc2hvcnQgcHJvdG9jb2wgPSBFVEhfUF9JUDsKKyAgc29ja3VuaW9uIHN1OworICBtZW1zZXQoJnN1LCAwLCBzaXplb2Yoc3UpKTsKKyAgc3Uuc2xsLnNsbF9oYXR5cGUgPSBodG9ucygxKTsgLy8gQVJQSFJEX0VUSEVSCisgIHN1LnNsbC5zbGxfaGFsZW4gPSBtYWMuc2l6ZSgpOworICBtZW1jcHkoJnN1LnNsbC5zbGxfYWRkciwgbWFjLmdldCgpLCBtYWMuc2l6ZSgpKTsKKyAgc3Uuc2xsLnNsbF9mYW1pbHkgPSBBRl9QQUNLRVQ7CisgIHN1LnNsbC5zbGxfcHJvdG9jb2wgPSBodG9ucyhwcm90b2NvbCk7CisgIHN1LnNsbC5zbGxfaWZpbmRleCA9IGlmX25hbWV0b2luZGV4KGlmbmFtZS5jX3N0cigpKTsKKworICBpbnQgZXJyOworICB7CisgICAgaW50IGludEZkID0gZmQuZ2V0KCk7CisgICAgQXN5bmNocm9ub3VzU29ja2V0Q2xvc2VNb25pdG9yIG1vbml0b3IoaW50RmQpOworICAgIGVyciA9IE5FVF9GQUlMVVJFX1JFVFJZKGZkLCBzZW5kdG8oaW50RmQsIGJ5dGVBcnJheS5nZXQoKSArIG9mZnNldCwKKyAgICAgICAgYnl0ZUNvdW50LCAwLCAmc3Uuc2EsIHNpemVvZihzdSkpKTsKKyAgfQorCisgIHJldHVybiBlcnI7Cit9CisKKy8qCisgKiBSZWFkcyBhIG5ldHdvcmsgcGFja2V0IGludG8gdGhlIHVzZXItc3VwcGxpZWQgYnVmZmVyLiAgUmV0dXJuIHRoZQorICogbGVuZ3RoIG9mIHRoZSBwYWNrZXQsIG9yIGEgMCBpZiB0aGVyZSB3YXMgYSB0aW1lb3V0IG9yIGFuCisgKiB1bmFjY2VwdGFibGUgcGFja2V0IHdhcyBhY3F1aXJlZC4KKyAqCisgKiBBc3N1bWVzIHRoYXQgdGhlIGNhbGxlciBoYXMgdmFsaWRhdGVkIHRoZSBvZmZzZXQgJiBieXRlQ291bnQgdmFsdWVzLgorICovCitzdGF0aWMgamludCBSYXdTb2NrZXRfcmVjdlBhY2tldChKTklFbnYqIGVudiwgamNsYXNzLCBqb2JqZWN0IGZpbGVEZXNjcmlwdG9yLAorICAgIGpieXRlQXJyYXkgcGFja2V0LCBqaW50IG9mZnNldCwgamludCBieXRlQ291bnQsIGppbnQgcG9ydCwKKyAgICBqaW50IHRpbWVvdXRfbWlsbGlzKQoreworICBOZXRGZCBmZChlbnYsIGZpbGVEZXNjcmlwdG9yKTsKKyAgaWYgKGZkLmlzQ2xvc2VkKCkpIHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIFNjb3BlZEJ5dGVBcnJheVJXIGJvZHkoZW52LCBwYWNrZXQpOworICBqYnl0ZSogcGFja2V0RGF0YSA9IGJvZHkuZ2V0KCk7CisgIGlmIChwYWNrZXREYXRhID09IE5VTEwpIHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIHBhY2tldERhdGEgKz0gb2Zmc2V0OworCisgIHBvbGxmZCBmZHNbMV07CisgIGZkc1swXS5mZCA9IGZkLmdldCgpOworICBmZHNbMF0uZXZlbnRzID0gUE9MTElOOworICBpbnQgcmV0dmFsID0gcG9sbChmZHMsIDEsIHRpbWVvdXRfbWlsbGlzKTsKKyAgaWYgKHJldHZhbCA8PSAwKSB7CisgICAgcmV0dXJuIDA7CisgIH0KKworICB1bnNpZ25lZCBpbnQgc2l6ZSA9IDA7CisgIHsKKyAgICBpbnQgcGFja2V0U2l6ZSA9IGJ5dGVDb3VudDsKKyAgICBpbnQgaW50RmQgPSBmZC5nZXQoKTsKKyAgICBBc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3IgbW9uaXRvcihpbnRGZCk7CisgICAgc2l6ZSA9IE5FVF9GQUlMVVJFX1JFVFJZKGZkLCByZWFkKGludEZkLCBwYWNrZXREYXRhLCBwYWNrZXRTaXplKSk7CisgIH0KKworICBpZiAoZW52LT5FeGNlcHRpb25PY2N1cnJlZCgpKSB7CisgICAgcmV0dXJuIDA7CisgIH0KKworICAvLyBxdWljayBjaGVjayBmb3IgVURQIHR5cGUgJiBVRFAgcG9ydAorICAvLyB0aGUgcGFja2V0IGlzIGFuIElQIGhlYWRlciwgVURQIGhlYWRlciwgYW5kIFVEUCBwYXlsb2FkCisgIGlmICgoc2l6ZSA8IChzaXplb2YoaXBoZHIpICsgc2l6ZW9mKHVkcGhkcikpKSkgeworICAgIHJldHVybiAwOyAgLy8gcnVudCBwYWNrZXQKKyAgfQorCisgIHVfaW50OF90IGlwX3Byb3RvID0gKChpcGhkciAqKSBwYWNrZXREYXRhKS0+cHJvdG9jb2w7CisgIGlmIChpcF9wcm90byAhPSBJUFBST1RPX1VEUCkgeworICAgIHJldHVybiAwOyAgLy8gc29tZXRoaW5nIG90aGVyIHRoYW4gVURQCisgIH0KKworICBfX2JlMTYgZGVzdFBvcnQgPSBodG9ucygocmVpbnRlcnByZXRfY2FzdDx1ZHBoZHIqPihwYWNrZXREYXRhICsgc2l6ZW9mKGlwaGRyKSkpLT5kZXN0KTsKKyAgaWYgKGRlc3RQb3J0ICE9IHBvcnQpIHsKKyAgICByZXR1cm4gMDsgLy8gc29tZXRoaW5nIG90aGVyIHRoYW4gcmVxdWVzdGVkIHBvcnQKKyAgfQorCisgIHJldHVybiBzaXplOworfQorCitzdGF0aWMgSk5JTmF0aXZlTWV0aG9kIGdSYXdNZXRob2RzW10gPSB7CisgIE5BVElWRV9NRVRIT0QoUmF3U29ja2V0LCBjcmVhdGUsICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7TGphdmEvbGFuZy9TdHJpbmc7KVYiKSwKKyAgTkFUSVZFX01FVEhPRChSYXdTb2NrZXQsIHNlbmRQYWNrZXQsICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7TGphdmEvbGFuZy9TdHJpbmc7W0JbQklJKUkiKSwKKyAgTkFUSVZFX01FVEhPRChSYXdTb2NrZXQsIHJlY3ZQYWNrZXQsICIoTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7W0JJSUlJKUkiKSwKK307CisKK2ludCByZWdpc3Rlcl9saWJjb3JlX25ldF9SYXdTb2NrZXQoSk5JRW52KiBlbnYpIHsKKyAgcmV0dXJuIGpuaVJlZ2lzdGVyTmF0aXZlTWV0aG9kcyhlbnYsICJsaWJjb3JlL25ldC9SYXdTb2NrZXQiLCBnUmF3TWV0aG9kcywgTkVMRU0oZ1Jhd01ldGhvZHMpKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL29yZ19hcGFjaGVfaGFybW9ueV94bWxfRXhwYXRQYXJzZXIuY3BwIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvb3JnX2FwYWNoZV9oYXJtb255X3htbF9FeHBhdFBhcnNlci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2Y2YzFhYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL29yZ19hcGFjaGVfaGFybW9ueV94bWxfRXhwYXRQYXJzZXIuY3BwCkBAIC0wLDAgKzEsMTQwNyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNkZWZpbmUgTE9HX1RBRyAiRXhwYXRQYXJzZXIiCisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisjaW5jbHVkZSAiSm5pRXhjZXB0aW9uLmgiCisjaW5jbHVkZSAiTG9jYWxBcnJheS5oIgorI2luY2x1ZGUgIlNjb3BlZExvY2FsUmVmLmgiCisjaW5jbHVkZSAiU2NvcGVkUHJpbWl0aXZlQXJyYXkuaCIKKyNpbmNsdWRlICJTY29wZWRTdHJpbmdDaGFycy5oIgorI2luY2x1ZGUgIlNjb3BlZFV0ZkNoYXJzLmgiCisjaW5jbHVkZSAiVW5pcXVlUHRyLmgiCisjaW5jbHVkZSAiam5pLmgiCisjaW5jbHVkZSAiY3V0aWxzL2xvZy5oIgorI2luY2x1ZGUgImN1dGlscy9qc3RyaW5nLmgiIC8vIGZvciBzdHJjcHlsZW44dG8xNgorCisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8ZXhwYXQuaD4KKworI2RlZmluZSBCVUNLRVRfQ09VTlQgMTI4CisKKy8qKgorICogV3JhcHBlciBhcm91bmQgYW4gaW50ZXJuZWQgc3RyaW5nLgorICovCitzdHJ1Y3QgSW50ZXJuZWRTdHJpbmcgeworICAgIEludGVybmVkU3RyaW5nKCkgOiBpbnRlcm5lZChOVUxMKSwgYnl0ZXMoTlVMTCkgeworICAgIH0KKworICAgIH5JbnRlcm5lZFN0cmluZygpIHsKKyAgICAgICAgZGVsZXRlW10gYnl0ZXM7CisgICAgfQorCisgICAgLyoqIFRoZSBpbnRlcm5lZCBzdHJpbmcgaXRzZWxmLiAqLworICAgIGpzdHJpbmcgaW50ZXJuZWQ7CisKKyAgICAvKiogVVRGLTggZXF1aXZhbGVudCBvZiB0aGUgaW50ZXJuZWQgc3RyaW5nLiAqLworICAgIGNvbnN0IGNoYXIqIGJ5dGVzOworCisgICAgLyoqIEhhc2ggY29kZSBvZiB0aGUgaW50ZXJuZWQgc3RyaW5nLiAqLworICAgIGludCBoYXNoOworfTsKKworLyoqCisgKiBLZWVwcyB0cmFjayBvZiBzdHJpbmdzIGJldHdlZW4gc3RhcnQgYW5kIGVuZCBldmVudHMuCisgKi8KK2NsYXNzIFN0cmluZ1N0YWNrIHsKK3B1YmxpYzoKKyAgICBTdHJpbmdTdGFjaygpIDogYXJyYXkobmV3IGpzdHJpbmdbREVGQVVMVF9DQVBBQ0lUWV0pLCBjYXBhY2l0eShERUZBVUxUX0NBUEFDSVRZKSwgc2l6ZSgwKSB7CisgICAgfQorCisgICAgflN0cmluZ1N0YWNrKCkgeworICAgICAgICBkZWxldGVbXSBhcnJheTsKKyAgICB9CisKKyAgICB2b2lkIHB1c2goSk5JRW52KiBlbnYsIGpzdHJpbmcgcykgeworICAgICAgICBpZiAoc2l6ZSA9PSBjYXBhY2l0eSkgeworICAgICAgICAgICAgaW50IG5ld0NhcGFjaXR5ID0gY2FwYWNpdHkgKiAyOworICAgICAgICAgICAganN0cmluZyogbmV3QXJyYXkgPSBuZXcganN0cmluZ1tuZXdDYXBhY2l0eV07CisgICAgICAgICAgICBpZiAobmV3QXJyYXkgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgIGpuaVRocm93T3V0T2ZNZW1vcnlFcnJvcihlbnYsIE5VTEwpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG1lbWNweShuZXdBcnJheSwgYXJyYXksIGNhcGFjaXR5ICogc2l6ZW9mKGpzdHJpbmcpKTsKKworICAgICAgICAgICAgYXJyYXkgPSBuZXdBcnJheTsKKyAgICAgICAgICAgIGNhcGFjaXR5ID0gbmV3Q2FwYWNpdHk7CisgICAgICAgIH0KKworICAgICAgICBhcnJheVtzaXplKytdID0gczsKKyAgICB9CisKKyAgICBqc3RyaW5nIHBvcCgpIHsKKyAgICAgICAgcmV0dXJuIChzaXplID09IDApID8gTlVMTCA6IGFycmF5Wy0tc2l6ZV07CisgICAgfQorCitwcml2YXRlOgorICAgIGVudW0geyBERUZBVUxUX0NBUEFDSVRZID0gMTAgfTsKKworICAgIGpzdHJpbmcqIGFycmF5OworICAgIGludCBjYXBhY2l0eTsKKyAgICBpbnQgc2l6ZTsKK307CisKKy8qKgorICogRGF0YSBwYXNzZWQgdG8gcGFyc2VyIGhhbmRsZXIgbWV0aG9kIGJ5IHRoZSBwYXJzZXIuCisgKi8KK3N0cnVjdCBQYXJzaW5nQ29udGV4dCB7CisgICAgUGFyc2luZ0NvbnRleHQoam9iamVjdCBvYmplY3QpIDogZW52KE5VTEwpLCBvYmplY3Qob2JqZWN0KSwgYnVmZmVyKE5VTEwpLCBidWZmZXJTaXplKC0xKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQlVDS0VUX0NPVU5UOyBpKyspIHsKKyAgICAgICAgICAgIGludGVybmVkU3RyaW5nc1tpXSA9IE5VTEw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBXYXJuaW5nOiAnZW52JyBtdXN0IGJlIHZhbGlkIG9uIGVudHJ5LgorICAgIH5QYXJzaW5nQ29udGV4dCgpIHsKKyAgICAgICAgZnJlZUJ1ZmZlcigpOworCisgICAgICAgIC8vIEZyZWUgaW50ZXJuZWQgc3RyaW5nIGNhY2hlLgorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEJVQ0tFVF9DT1VOVDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoaW50ZXJuZWRTdHJpbmdzW2ldKSB7CisgICAgICAgICAgICAgICAgSW50ZXJuZWRTdHJpbmcqKiBidWNrZXQgPSBpbnRlcm5lZFN0cmluZ3NbaV07CisgICAgICAgICAgICAgICAgSW50ZXJuZWRTdHJpbmcqIGN1cnJlbnQ7CisgICAgICAgICAgICAgICAgd2hpbGUgKChjdXJyZW50ID0gKihidWNrZXQrKykpICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gRnJlZSB0aGUgaW50ZXJuZWQgc3RyaW5nIHJlZmVyZW5jZS4KKyAgICAgICAgICAgICAgICAgICAgZW52LT5EZWxldGVHbG9iYWxSZWYoY3VycmVudC0+aW50ZXJuZWQpOworCisgICAgICAgICAgICAgICAgICAgIC8vIEZyZWUgdGhlIGJ1Y2tldC4KKyAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGN1cnJlbnQ7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gRnJlZSB0aGUgYnVja2V0cy4KKyAgICAgICAgICAgICAgICBkZWxldGVbXSBpbnRlcm5lZFN0cmluZ3NbaV07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBqY2hhckFycmF5IGVuc3VyZUNhcGFjaXR5KGludCBsZW5ndGgpIHsKKyAgICAgICAgaWYgKGJ1ZmZlclNpemUgPCBsZW5ndGgpIHsKKyAgICAgICAgICAgIC8vIEZyZWUgdGhlIGV4aXN0aW5nIGNoYXJbXS4KKyAgICAgICAgICAgIGZyZWVCdWZmZXIoKTsKKworICAgICAgICAgICAgLy8gQWxsb2NhdGUgYSBuZXcgY2hhcltdLgorICAgICAgICAgICAgamNoYXJBcnJheSBqYXZhQnVmZmVyID0gZW52LT5OZXdDaGFyQXJyYXkobGVuZ3RoKTsKKyAgICAgICAgICAgIGlmIChqYXZhQnVmZmVyID09IE5VTEwpIHJldHVybiBOVUxMOworCisgICAgICAgICAgICAvLyBDcmVhdGUgYSBnbG9iYWwgcmVmZXJlbmNlLgorICAgICAgICAgICAgamF2YUJ1ZmZlciA9IChqY2hhckFycmF5KSBlbnYtPk5ld0dsb2JhbFJlZihqYXZhQnVmZmVyKTsKKyAgICAgICAgICAgIGlmIChqYXZhQnVmZmVyID09IE5VTEwpIHJldHVybiBOVUxMOworCisgICAgICAgICAgICBidWZmZXIgPSBqYXZhQnVmZmVyOworICAgICAgICAgICAgYnVmZmVyU2l6ZSA9IGxlbmd0aDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnVmZmVyOworICAgIH0KKworcHJpdmF0ZToKKyAgICB2b2lkIGZyZWVCdWZmZXIoKSB7CisgICAgICAgIGlmIChidWZmZXIgIT0gTlVMTCkgeworICAgICAgICAgICAgZW52LT5EZWxldGVHbG9iYWxSZWYoYnVmZmVyKTsKKyAgICAgICAgICAgIGJ1ZmZlciA9IE5VTEw7CisgICAgICAgICAgICBidWZmZXJTaXplID0gLTE7CisgICAgICAgIH0KKyAgICB9CisKK3B1YmxpYzoKKyAgICAvKioKKyAgICAgKiBUaGUgSk5JIGVudmlyb25tZW50IGZvciB0aGUgY3VycmVudCB0aHJlYWQuIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZAorICAgICAqIHRvIGtlZXAgYSByZWZlcmVuY2UgdG8gdGhlIGVudiBmb3IgdXNlIGluIEV4cGF0IGNhbGxiYWNrcy4KKyAgICAgKi8KKyAgICBKTklFbnYqIGVudjsKKworICAgIC8qKiBUaGUgSmF2YSBwYXJzZXIgb2JqZWN0LiAqLworICAgIGpvYmplY3Qgb2JqZWN0OworCisgICAgLyoqIEJ1ZmZlciBmb3IgdGV4dCBldmVudHMuICovCisgICAgamNoYXJBcnJheSBidWZmZXI7CisKK3ByaXZhdGU6CisgICAgLyoqIFRoZSBzaXplIG9mIG91ciBidWZmZXIgaW4gamNoYXJzLiAqLworICAgIGludCBidWZmZXJTaXplOworCitwdWJsaWM6CisgICAgLyoqIEN1cnJlbnQgYXR0cmlidXRlcy4gKi8KKyAgICBjb25zdCBjaGFyKiogYXR0cmlidXRlczsKKworICAgIC8qKiBOdW1iZXIgb2YgYXR0cmlidXRlcy4gKi8KKyAgICBpbnQgYXR0cmlidXRlQ291bnQ7CisKKyAgICAvKiogVHJ1ZSBpZiBuYW1lc3BhY2Ugc3VwcG9ydCBpcyBlbmFibGVkLiAqLworICAgIGJvb2wgcHJvY2Vzc05hbWVzcGFjZXM7CisKKyAgICAvKiogS2VlcCB0cmFjayBvZiBuYW1lcy4gKi8KKyAgICBTdHJpbmdTdGFjayBzdHJpbmdTdGFjazsKKworICAgIC8qKiBDYWNoZSBvZiBpbnRlcm5lZCBzdHJpbmdzLiAqLworICAgIEludGVybmVkU3RyaW5nKiogaW50ZXJuZWRTdHJpbmdzW0JVQ0tFVF9DT1VOVF07Cit9OworCitzdGF0aWMgUGFyc2luZ0NvbnRleHQqIHRvUGFyc2luZ0NvbnRleHQodm9pZCogZGF0YSkgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PFBhcnNpbmdDb250ZXh0Kj4oZGF0YSk7Cit9CisKK3N0YXRpYyBQYXJzaW5nQ29udGV4dCogdG9QYXJzaW5nQ29udGV4dChYTUxfUGFyc2VyIHBhcnNlcikgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PFBhcnNpbmdDb250ZXh0Kj4oWE1MX0dldFVzZXJEYXRhKHBhcnNlcikpOworfQorCitzdGF0aWMgam1ldGhvZElEIGNvbW1lbnRNZXRob2Q7CitzdGF0aWMgam1ldGhvZElEIGVuZENkYXRhTWV0aG9kOworc3RhdGljIGptZXRob2RJRCBlbmREdGRNZXRob2Q7CitzdGF0aWMgam1ldGhvZElEIGVuZEVsZW1lbnRNZXRob2Q7CitzdGF0aWMgam1ldGhvZElEIGVuZE5hbWVzcGFjZU1ldGhvZDsKK3N0YXRpYyBqbWV0aG9kSUQgaGFuZGxlRXh0ZXJuYWxFbnRpdHlNZXRob2Q7CitzdGF0aWMgam1ldGhvZElEIGludGVybk1ldGhvZDsKK3N0YXRpYyBqbWV0aG9kSUQgbm90YXRpb25EZWNsTWV0aG9kOworc3RhdGljIGptZXRob2RJRCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb25NZXRob2Q7CitzdGF0aWMgam1ldGhvZElEIHN0YXJ0Q2RhdGFNZXRob2Q7CitzdGF0aWMgam1ldGhvZElEIHN0YXJ0RHRkTWV0aG9kOworc3RhdGljIGptZXRob2RJRCBzdGFydEVsZW1lbnRNZXRob2Q7CitzdGF0aWMgam1ldGhvZElEIHN0YXJ0TmFtZXNwYWNlTWV0aG9kOworc3RhdGljIGptZXRob2RJRCB0ZXh0TWV0aG9kOworc3RhdGljIGptZXRob2RJRCB1bnBhcnNlZEVudGl0eURlY2xNZXRob2Q7CitzdGF0aWMganN0cmluZyBlbXB0eVN0cmluZzsKKworLyoqCisgKiBDYWxjdWxhdGVzIGEgaGFzaCBjb2RlIGZvciBhIG51bGwtdGVybWluYXRlZCBzdHJpbmcuIFRoaXMgaXMgKm5vdCogZXF1aXZhbGVudAorICogdG8gSmF2YSdzIFN0cmluZy5oYXNoQ29kZSgpLiBUaGlzIGhhc2hlcyB0aGUgYnl0ZXMgd2hpbGUgU3RyaW5nLmhhc2hDb2RlKCkKKyAqIGhhc2hlcyBVVEYtMTYgY2hhcnMuCisgKgorICogQHBhcmFtIHMgbnVsbC10ZXJtaW5hdGVkIHN0cmluZyB0byBoYXNoCisgKiBAcmV0dXJucyBoYXNoIGNvZGUKKyAqLworc3RhdGljIGludCBoYXNoU3RyaW5nKGNvbnN0IGNoYXIqIHMpIHsKKyAgICBpbnQgaGFzaCA9IDA7CisgICAgaWYgKHMpIHsKKyAgICAgICAgd2hpbGUgKCpzKSB7CisgICAgICAgICAgICBoYXNoID0gaGFzaCAqIDMxICsgKnMrKzsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gaGFzaDsKK30KKworLyoqCisgKiBDcmVhdGVzIGEgbmV3IGludGVybmVkIHN0cmluZyB3cmFwcGVyLiBMb29rcyB1cCB0aGUgaW50ZXJuZWQgc3RyaW5nCisgKiByZXByZXNlbnRpbmcgdGhlIGdpdmVuIFVURi04IGJ5dGVzLgorICoKKyAqIEBwYXJhbSBieXRlcyBudWxsLXRlcm1pbmF0ZWQgc3RyaW5nIHRvIGludGVybgorICogQHBhcmFtIGhhc2ggb2YgYnl0ZXMKKyAqIEByZXR1cm5zIHdyYXBwZXIgb2YgaW50ZXJuZWQgSmF2YSBzdHJpbmcKKyAqLworc3RhdGljIEludGVybmVkU3RyaW5nKiBuZXdJbnRlcm5lZFN0cmluZyhKTklFbnYqIGVudiwgY29uc3QgY2hhciogYnl0ZXMsIGludCBoYXNoKSB7CisgICAgLy8gQWxsb2NhdGUgYSBuZXcgd3JhcHBlci4KKyAgICBVbmlxdWVQdHI8SW50ZXJuZWRTdHJpbmc+IHdyYXBwZXIobmV3IEludGVybmVkU3RyaW5nKTsKKyAgICBpZiAod3JhcHBlci5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIGpuaVRocm93T3V0T2ZNZW1vcnlFcnJvcihlbnYsIE5VTEwpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvLyBDcmVhdGUgYSBjb3B5IG9mIHRoZSBVVEYtOCBieXRlcy4KKyAgICAvLyBUT0RPOiBzb21ldGltZXMgd2UgYWxyZWFkeSBrbm93IHRoZSBsZW5ndGguIFJldXNlIGl0IGlmIHNvLgorICAgIGNoYXIqIGNvcHkgPSBuZXcgY2hhcltzdHJsZW4oYnl0ZXMpICsgMV07CisgICAgaWYgKGNvcHkgPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd091dE9mTWVtb3J5RXJyb3IoZW52LCBOVUxMKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHN0cmNweShjb3B5LCBieXRlcyk7CisgICAgd3JhcHBlci0+Ynl0ZXMgPSBjb3B5OworCisgICAgLy8gU2F2ZSB0aGUgaGFzaC4KKyAgICB3cmFwcGVyLT5oYXNoID0gaGFzaDsKKworICAgIC8vIFRvIGludGVybiBhIHN0cmluZywgd2UgbXVzdCBmaXJzdCBjcmVhdGUgYSBuZXcgc3RyaW5nIGFuZCB0aGVuIGNhbGwKKyAgICAvLyBpbnRlcm4oKSBvbiBpdC4gV2UgdGhlbiBrZWVwIGEgZ2xvYmFsIHJlZmVyZW5jZSB0byB0aGUgaW50ZXJuZWQgc3RyaW5nLgorICAgIFNjb3BlZExvY2FsUmVmPGpzdHJpbmc+IG5ld1N0cmluZyhlbnYsIGVudi0+TmV3U3RyaW5nVVRGKGJ5dGVzKSk7CisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvLyBDYWxsIGludGVybigpLgorICAgIFNjb3BlZExvY2FsUmVmPGpzdHJpbmc+IGludGVybmVkKGVudiwKKyAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8anN0cmluZz4oZW52LT5DYWxsT2JqZWN0TWV0aG9kKG5ld1N0cmluZy5nZXQoKSwgaW50ZXJuTWV0aG9kKSkpOworICAgIGlmIChlbnYtPkV4Y2VwdGlvbkNoZWNrKCkpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgLy8gQ3JlYXRlIGEgZ2xvYmFsIHJlZmVyZW5jZSB0byB0aGUgaW50ZXJuZWQgc3RyaW5nLgorICAgIHdyYXBwZXItPmludGVybmVkID0gKGpzdHJpbmcpIGVudi0+TmV3R2xvYmFsUmVmKGludGVybmVkLmdldCgpKTsKKyAgICBpZiAoZW52LT5FeGNlcHRpb25DaGVjaygpKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHJldHVybiB3cmFwcGVyLnJlbGVhc2UoKTsKK30KKworLyoqCisgKiBBbGxvY2F0ZXMgYSBuZXcgYnVja2V0IHdpdGggb25lIGVudHJ5LgorICoKKyAqIEBwYXJhbSBlbnRyeSB0byBzdG9yZSBpbiB0aGUgYnVja2V0CisgKiBAcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgYnVja2V0CisgKi8KK3N0YXRpYyBJbnRlcm5lZFN0cmluZyoqIG5ld0ludGVybmVkU3RyaW5nQnVja2V0KEludGVybmVkU3RyaW5nKiBlbnRyeSkgeworICAgIEludGVybmVkU3RyaW5nKiogYnVja2V0ID0gbmV3IEludGVybmVkU3RyaW5nKlsyXTsKKyAgICBpZiAoYnVja2V0ICE9IE5VTEwpIHsKKyAgICAgICAgYnVja2V0WzBdID0gZW50cnk7CisgICAgICAgIGJ1Y2tldFsxXSA9IE5VTEw7CisgICAgfQorICAgIHJldHVybiBidWNrZXQ7Cit9CisKKy8qKgorICogRXhwYW5kcyBhbiBpbnRlcm5lZCBzdHJpbmcgYnVja2V0IGFuZCBhZGRzIHRoZSBnaXZlbiBlbnRyeS4gRnJlZXMgdGhlCisgKiBwcm92aWRlZCBidWNrZXQgYW5kIHJldHVybnMgYSBuZXcgb25lLgorICoKKyAqIEBwYXJhbSBleGlzdGluZ0J1Y2tldCB0aGUgYnVja2V0IHRvIHJlcGxhY2UKKyAqIEBwYXJhbSBlbnRyeSB0byBhZGQgdG8gdGhlIGJ1Y2tldAorICogQHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIG5ld2x5LWFsbG9jYXRlZCBidWNrZXQgY29udGFpbmluZyB0aGUgZ2l2ZW4gZW50cnkKKyAqLworc3RhdGljIEludGVybmVkU3RyaW5nKiogZXhwYW5kSW50ZXJuZWRTdHJpbmdCdWNrZXQoCisgICAgICAgIEludGVybmVkU3RyaW5nKiogZXhpc3RpbmdCdWNrZXQsIEludGVybmVkU3RyaW5nKiBlbnRyeSkgeworICAgIC8vIERldGVybWluZSB0aGUgc2l6ZSBvZiB0aGUgZXhpc3RpbmcgYnVja2V0LgorICAgIGludCBzaXplID0gMDsKKyAgICB3aGlsZSAoZXhpc3RpbmdCdWNrZXRbc2l6ZV0pIHNpemUrKzsKKworICAgIC8vIEFsbG9jYXRlIHRoZSBuZXcgYnVja2V0IHdpdGggZW5vdWdoIHNwYWNlIGZvciBvbmUgbW9yZSBlbnRyeSBhbmQKKyAgICAvLyBhIG51bGwgdGVybWluYXRvci4KKyAgICBJbnRlcm5lZFN0cmluZyoqIG5ld0J1Y2tldCA9IG5ldyBJbnRlcm5lZFN0cmluZypbc2l6ZSArIDJdOworICAgIGlmIChuZXdCdWNrZXQgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CisKKyAgICBtZW1jcHkobmV3QnVja2V0LCBleGlzdGluZ0J1Y2tldCwgc2l6ZSAqIHNpemVvZihJbnRlcm5lZFN0cmluZyopKTsKKyAgICBuZXdCdWNrZXRbc2l6ZV0gPSBlbnRyeTsKKyAgICBuZXdCdWNrZXRbc2l6ZSArIDFdID0gTlVMTDsKKworICAgIHJldHVybiBuZXdCdWNrZXQ7Cit9CisKKy8qKgorICogUmV0dXJucyBhbiBpbnRlcm5lZCBzdHJpbmcgZm9yIHRoZSBnaXZlbiBVVEYtOCBzdHJpbmcuCisgKgorICogQHBhcmFtIGJ1Y2tldCB0byBzZWFyY2ggZm9yIHMKKyAqIEBwYXJhbSBzIG51bGwtdGVybWluYXRlZCBzdHJpbmcgdG8gZmluZAorICogQHBhcmFtIGhhc2ggb2YgcworICogQHJldHVybnMgaW50ZXJuZWQgSmF2YSBzdHJpbmcgZXF1aXZhbGVudCBvZiBzIG9yIG51bGwgaWYgbm90IGZvdW5kCisgKi8KK3N0YXRpYyBqc3RyaW5nIGZpbmRJbnRlcm5lZFN0cmluZyhJbnRlcm5lZFN0cmluZyoqIGJ1Y2tldCwgY29uc3QgY2hhciogcywgaW50IGhhc2gpIHsKKyAgICBJbnRlcm5lZFN0cmluZyogY3VycmVudDsKKyAgICB3aGlsZSAoKGN1cnJlbnQgPSAqKGJ1Y2tldCsrKSkgIT0gTlVMTCkgeworICAgICAgICBpZiAoY3VycmVudC0+aGFzaCAhPSBoYXNoKSBjb250aW51ZTsKKyAgICAgICAgaWYgKCFzdHJjbXAocywgY3VycmVudC0+Ynl0ZXMpKSByZXR1cm4gY3VycmVudC0+aW50ZXJuZWQ7CisgICAgfQorICAgIHJldHVybiBOVUxMOworfQorCisvKioKKyAqIFJldHVybnMgYW4gaW50ZXJuZWQgc3RyaW5nIGZvciB0aGUgZ2l2ZW4gVVRGLTggc3RyaW5nLgorICoKKyAqIEBwYXJhbSBzIG51bGwtdGVybWluYXRlZCBzdHJpbmcgdG8gaW50ZXJuCisgKiBAcmV0dXJucyBpbnRlcm5lZCBKYXZhIHN0cmluZyBlcXVpdmVsZW50IG9mIHMgb3IgTlVMTCBpZiBzIGlzIG51bGwKKyAqLworc3RhdGljIGpzdHJpbmcgaW50ZXJuU3RyaW5nKEpOSUVudiogZW52LCBQYXJzaW5nQ29udGV4dCogcGFyc2luZ0NvbnRleHQsIGNvbnN0IGNoYXIqIHMpIHsKKyAgICBpZiAocyA9PSBOVUxMKSByZXR1cm4gTlVMTDsKKworICAgIGludCBoYXNoID0gaGFzaFN0cmluZyhzKTsKKyAgICBpbnQgYnVja2V0SW5kZXggPSBoYXNoICYgKEJVQ0tFVF9DT1VOVCAtIDEpOworCisgICAgSW50ZXJuZWRTdHJpbmcqKiogYnVja2V0cyA9IHBhcnNpbmdDb250ZXh0LT5pbnRlcm5lZFN0cmluZ3M7CisgICAgSW50ZXJuZWRTdHJpbmcqKiBidWNrZXQgPSBidWNrZXRzW2J1Y2tldEluZGV4XTsKKyAgICBJbnRlcm5lZFN0cmluZyogaW50ZXJuZWRTdHJpbmc7CisKKyAgICBpZiAoYnVja2V0KSB7CisgICAgICAgIC8vIFdlIGhhdmUgYSBidWNrZXQgYWxyZWFkeS4gTG9vayBmb3IgdGhlIGdpdmVuIHN0cmluZy4KKyAgICAgICAganN0cmluZyBmb3VuZCA9IGZpbmRJbnRlcm5lZFN0cmluZyhidWNrZXQsIHMsIGhhc2gpOworICAgICAgICBpZiAoZm91bmQpIHsKKyAgICAgICAgICAgIC8vIFdlIGZvdW5kIGl0IQorICAgICAgICAgICAgcmV0dXJuIGZvdW5kOworICAgICAgICB9CisKKyAgICAgICAgLy8gV2UgZGlkbid0IGZpbmQgaXQuIDooCisgICAgICAgIC8vIENyZWF0ZSBhIG5ldyBlbnRyeS4KKyAgICAgICAgaW50ZXJuZWRTdHJpbmcgPSBuZXdJbnRlcm5lZFN0cmluZyhlbnYsIHMsIGhhc2gpOworICAgICAgICBpZiAoaW50ZXJuZWRTdHJpbmcgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CisKKyAgICAgICAgLy8gRXhwYW5kIHRoZSBidWNrZXQuCisgICAgICAgIGJ1Y2tldCA9IGV4cGFuZEludGVybmVkU3RyaW5nQnVja2V0KGJ1Y2tldCwgaW50ZXJuZWRTdHJpbmcpOworICAgICAgICBpZiAoYnVja2V0ID09IE5VTEwpIHsKKyAgICAgICAgICAgIGpuaVRocm93T3V0T2ZNZW1vcnlFcnJvcihlbnYsIE5VTEwpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKworICAgICAgICBidWNrZXRzW2J1Y2tldEluZGV4XSA9IGJ1Y2tldDsKKworICAgICAgICByZXR1cm4gaW50ZXJuZWRTdHJpbmctPmludGVybmVkOworICAgIH0gZWxzZSB7CisgICAgICAgIC8vIFdlIGRvbid0IGV2ZW4gaGF2ZSBhIGJ1Y2tldCB5ZXQuIENyZWF0ZSBhbiBlbnRyeS4KKyAgICAgICAgaW50ZXJuZWRTdHJpbmcgPSBuZXdJbnRlcm5lZFN0cmluZyhlbnYsIHMsIGhhc2gpOworICAgICAgICBpZiAoaW50ZXJuZWRTdHJpbmcgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CisKKyAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IGJ1Y2tldCB3aXRoIG9uZSBlbnRyeS4KKyAgICAgICAgYnVja2V0ID0gbmV3SW50ZXJuZWRTdHJpbmdCdWNrZXQoaW50ZXJuZWRTdHJpbmcpOworICAgICAgICBpZiAoYnVja2V0ID09IE5VTEwpIHsKKyAgICAgICAgICAgIGpuaVRocm93T3V0T2ZNZW1vcnlFcnJvcihlbnYsIE5VTEwpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKworICAgICAgICBidWNrZXRzW2J1Y2tldEluZGV4XSA9IGJ1Y2tldDsKKworICAgICAgICByZXR1cm4gaW50ZXJuZWRTdHJpbmctPmludGVybmVkOworICAgIH0KK30KKworc3RhdGljIHZvaWQgam5pVGhyb3dFeHBhdEV4Y2VwdGlvbihKTklFbnYqIGVudiwgWE1MX0Vycm9yIGVycm9yKSB7CisgICAgY29uc3QgY2hhciogbWVzc2FnZSA9IFhNTF9FcnJvclN0cmluZyhlcnJvcik7CisgICAgam5pVGhyb3dFeGNlcHRpb24oZW52LCAib3JnL2FwYWNoZS9oYXJtb255L3htbC9FeHBhdEV4Y2VwdGlvbiIsIG1lc3NhZ2UpOworfQorCisvKioKKyAqIENvcGllcyBVVEYtOCBjaGFyYWN0ZXJzIGludG8gdGhlIGJ1ZmZlci4gUmV0dXJucyB0aGUgbnVtYmVyIG9mIEphdmEgY2hhcnMKKyAqIHdoaWNoIHdlcmUgYnVmZmVyZWQuCisgKgorICogQHBhcmFtIGNoYXJhY3RlcnMgdG8gY29weSBpbnRvIHRoZSBidWZmZXIKKyAqIEBwYXJhbSBsZW5ndGggb2YgY2hhcmFjdGVycyB0byBjb3B5IChpbiBieXRlcykKKyAqIEByZXR1cm5zIG51bWJlciBvZiBVVEYtMTYgY2hhcmFjdGVycyB3aGljaCB3ZXJlIGNvcGllZAorICovCitzdGF0aWMgc2l6ZV90IGZpbGxCdWZmZXIoUGFyc2luZ0NvbnRleHQqIHBhcnNpbmdDb250ZXh0LCBjb25zdCBjaGFyKiBjaGFyYWN0ZXJzLCBpbnQgbGVuZ3RoKSB7CisgICAgSk5JRW52KiBlbnYgPSBwYXJzaW5nQ29udGV4dC0+ZW52OworCisgICAgLy8gR3JvdyBidWZmZXIgaWYgbmVjZXNzYXJ5LgorICAgIGpjaGFyQXJyYXkgYnVmZmVyID0gcGFyc2luZ0NvbnRleHQtPmVuc3VyZUNhcGFjaXR5KGxlbmd0aCk7CisgICAgaWYgKGJ1ZmZlciA9PSBOVUxMKSByZXR1cm4gLTE7CisKKyAgICAvLyBEZWNvZGUgVVRGLTggY2hhcmFjdGVycyBpbnRvIG91ciBidWZmZXIuCisgICAgU2NvcGVkQ2hhckFycmF5UlcgbmF0aXZlQnVmZmVyKGVudiwgYnVmZmVyKTsKKyAgICBpZiAobmF0aXZlQnVmZmVyLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIHNpemVfdCB1dGYxNmxlbmd0aDsKKyAgICBzdHJjcHlsZW44dG8xNihuYXRpdmVCdWZmZXIuZ2V0KCksIGNoYXJhY3RlcnMsIGxlbmd0aCwgJnV0ZjE2bGVuZ3RoKTsKKyAgICByZXR1cm4gdXRmMTZsZW5ndGg7Cit9CisKKy8qKgorICogQnVmZmVycyB0aGUgZ2l2ZW4gdGV4dCBhbmQgcGFzc2VzIGl0IHRvIHRoZSBnaXZlbiBtZXRob2QuCisgKgorICogQHBhcmFtIG1ldGhvZCB0byBwYXNzIHRoZSBjaGFyYWN0ZXJzIGFuZCBsZW5ndGggdG8gd2l0aCBzaWduYXR1cmUKKyAqICAoY2hhcltdLCBpbnQpCisgKiBAcGFyYW0gZGF0YSBwYXJzaW5nIGNvbnRleHQKKyAqIEBwYXJhbSB0ZXh0IHRvIGNvcHkgaW50byB0aGUgYnVmZmVyCisgKiBAcGFyYW0gbGVuZ3RoIG9mIHRleHQgdG8gY29weSAoaW4gYnl0ZXMpCisgKi8KK3N0YXRpYyB2b2lkIGJ1ZmZlckFuZEludm9rZShqbWV0aG9kSUQgbWV0aG9kLCB2b2lkKiBkYXRhLCBjb25zdCBjaGFyKiB0ZXh0LCBzaXplX3QgbGVuZ3RoKSB7CisgICAgUGFyc2luZ0NvbnRleHQqIHBhcnNpbmdDb250ZXh0ID0gdG9QYXJzaW5nQ29udGV4dChkYXRhKTsKKyAgICBKTklFbnYqIGVudiA9IHBhcnNpbmdDb250ZXh0LT5lbnY7CisKKyAgICAvLyBCYWlsIG91dCBpZiBhIHByZXZpb3VzbHkgY2FsbGVkIGhhbmRsZXIgdGhyZXcgYW4gZXhjZXB0aW9uLgorICAgIGlmIChlbnYtPkV4Y2VwdGlvbkNoZWNrKCkpIHJldHVybjsKKworICAgIC8vIEJ1ZmZlciB0aGUgZWxlbWVudCBuYW1lLgorICAgIHNpemVfdCB1dGYxNmxlbmd0aCA9IGZpbGxCdWZmZXIocGFyc2luZ0NvbnRleHQsIHRleHQsIGxlbmd0aCk7CisKKyAgICAvLyBJbnZva2UgZ2l2ZW4gbWV0aG9kLgorICAgIGpvYmplY3QgamF2YVBhcnNlciA9IHBhcnNpbmdDb250ZXh0LT5vYmplY3Q7CisgICAgamNoYXJBcnJheSBidWZmZXIgPSBwYXJzaW5nQ29udGV4dC0+YnVmZmVyOworICAgIGVudi0+Q2FsbFZvaWRNZXRob2QoamF2YVBhcnNlciwgbWV0aG9kLCBidWZmZXIsIHV0ZjE2bGVuZ3RoKTsKK30KKworc3RhdGljIGNvbnN0IGNoYXIqKiB0b0F0dHJpYnV0ZXMoamludCBhdHRyaWJ1dGVQb2ludGVyKSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcioqPihzdGF0aWNfY2FzdDx1aW50cHRyX3Q+KGF0dHJpYnV0ZVBvaW50ZXIpKTsKK30KKworLyoqCisgKiBUaGUgY29tcG9uZW50IHBhcnRzIG9mIGFuIGF0dHJpYnV0ZSBvciBlbGVtZW50IG5hbWUuCisgKi8KK2NsYXNzIEV4cGF0RWxlbWVudE5hbWUgeworcHVibGljOgorICAgIEV4cGF0RWxlbWVudE5hbWUoSk5JRW52KiBlbnYsIFBhcnNpbmdDb250ZXh0KiBwYXJzaW5nQ29udGV4dCwgamludCBhdHRyaWJ1dGVQb2ludGVyLCBqaW50IGluZGV4KSB7CisgICAgICAgIGNvbnN0IGNoYXIqKiBhdHRyaWJ1dGVzID0gdG9BdHRyaWJ1dGVzKGF0dHJpYnV0ZVBvaW50ZXIpOworICAgICAgICBjb25zdCBjaGFyKiBuYW1lID0gYXR0cmlidXRlc1tpbmRleCAqIDJdOworICAgICAgICBpbml0KGVudiwgcGFyc2luZ0NvbnRleHQsIG5hbWUpOworICAgIH0KKworICAgIEV4cGF0RWxlbWVudE5hbWUoSk5JRW52KiBlbnYsIFBhcnNpbmdDb250ZXh0KiBwYXJzaW5nQ29udGV4dCwgY29uc3QgY2hhciogcykgeworICAgICAgICBpbml0KGVudiwgcGFyc2luZ0NvbnRleHQsIHMpOworICAgIH0KKworICAgIH5FeHBhdEVsZW1lbnROYW1lKCkgeworICAgICAgICBmcmVlKG1Db3B5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lc3BhY2UgVVJJLCBsaWtlICJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIi4KKyAgICAgKiBQb3NzaWJseSBlbXB0eS4KKyAgICAgKi8KKyAgICBqc3RyaW5nIHVyaSgpIHsKKyAgICAgICAgcmV0dXJuIGludGVyblN0cmluZyhtRW52LCBtUGFyc2luZ0NvbnRleHQsIG1VcmkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGVsZW1lbnQgb3IgYXR0cmlidXRlIGxvY2FsIG5hbWUsIGxpa2UgImgxIi4gTmV2ZXIgZW1wdHkuIFdoZW4KKyAgICAgKiBuYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBkaXNhYmxlZCwgdGhpcyBtYXkgY29udGFpbiBhIHByZWZpeCwgeWllbGRpbmcgYQorICAgICAqIGxvY2FsIG5hbWUgbGlrZSAiaHRtbDpoMSIuIEluIHN1Y2ggY2FzZXMsIHRoZSBxTmFtZSB3aWxsIGFsd2F5cyBiZSBlbXB0eS4KKyAgICAgKi8KKyAgICBqc3RyaW5nIGxvY2FsTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIGludGVyblN0cmluZyhtRW52LCBtUGFyc2luZ0NvbnRleHQsIG1Mb2NhbE5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWVzcGFjZSBwcmVmaXgsIGxpa2UgImh0bWwiLiBQb3NzaWJseSBlbXB0eS4KKyAgICAgKi8KKyAgICBqc3RyaW5nIHFOYW1lKCkgeworICAgICAgICBpZiAoKm1QcmVmaXggPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGxvY2FsTmFtZSgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gcmV0dXJuIHByZWZpeCArICI6IiArIGxvY2FsTmFtZQorICAgICAgICBMb2NhbEFycmF5PDEwMjQ+IHFOYW1lKHN0cmxlbihtUHJlZml4KSArIDEgKyBzdHJsZW4obUxvY2FsTmFtZSkgKyAxKTsKKyAgICAgICAgc25wcmludGYoJnFOYW1lWzBdLCBxTmFtZS5zaXplKCksICIlczolcyIsIG1QcmVmaXgsIG1Mb2NhbE5hbWUpOworICAgICAgICByZXR1cm4gaW50ZXJuU3RyaW5nKG1FbnYsIG1QYXJzaW5nQ29udGV4dCwgJnFOYW1lWzBdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBleHBhdCBuYW1lIGhhcyB0aGUgc2FtZSBVUkkgYW5kIGxvY2FsIG5hbWUuCisgICAgICovCisgICAgYm9vbCBtYXRjaGVzKGNvbnN0IGNoYXIqIHVyaSwgY29uc3QgY2hhciogbG9jYWxOYW1lKSB7CisgICAgICAgIHJldHVybiBzdHJjbXAodXJpLCBtVXJpKSA9PSAwICYmIHN0cmNtcChsb2NhbE5hbWUsIG1Mb2NhbE5hbWUpID09IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgZXhwYXQgbmFtZSBoYXMgdGhlIHNhbWUgcXVhbGlmaWVkIG5hbWUuCisgICAgICovCisgICAgYm9vbCBtYXRjaGVzUU5hbWUoY29uc3QgY2hhciogcU5hbWUpIHsKKyAgICAgICAgY29uc3QgY2hhciogbGFzdENvbG9uID0gc3RycmNocihxTmFtZSwgJzonKTsKKworICAgICAgICAvLyBDb21wYXJlIGxvY2FsIG5hbWVzIG9ubHkgaWYgZWl0aGVyOgorICAgICAgICAvLyAgLSB0aGUgaW5wdXQgcXVhbGlmaWVkIG5hbWUgZG9lc24ndCBoYXZlIGEgY29sb24gKGxpa2UgImgxIikKKyAgICAgICAgLy8gIC0gdGhpcyBlbGVtZW50IGRvZXNuJ3QgaGF2ZSBhIHByZWZpeC4gU3VjaCBpcyB0aGUgY2FzZSB3aGVuIGl0CisgICAgICAgIC8vICAgIGRvZXNuJ3QgYmVsb25nIHRvIGEgbmFtZXNwYWNlLCBvciB3aGVuIHRoaXMgcGFyc2VyJ3MgbmFtZXNwYWNlCisgICAgICAgIC8vICAgIHByb2Nlc3NpbmcgaXMgZGlzYWJsZWQuIEluIHRoZSBsYXR0ZXIgY2FzZSwgdGhpcyBlbGVtZW50J3MgbG9jYWwKKyAgICAgICAgLy8gICAgbmFtZSBtYXkgc3RpbGwgY29udGFpbiBhIGNvbG9uIChsaWtlICJodG1sOmgxIikuCisgICAgICAgIGlmIChsYXN0Q29sb24gPT0gTlVMTCB8fCAqbVByZWZpeCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gc3RyY21wKHFOYW1lLCBtTG9jYWxOYW1lKSA9PSAwOworICAgICAgICB9CisKKyAgICAgICAgLy8gT3RoZXJ3aXNlIGNvbXBhcmUgYm90aCBwcmVmaXggYW5kIGxvY2FsIG5hbWUKKyAgICAgICAgc2l6ZV90IHByZWZpeExlbmd0aCA9IGxhc3RDb2xvbiAtIHFOYW1lOworICAgICAgICByZXR1cm4gc3RybGVuKG1QcmVmaXgpID09IHByZWZpeExlbmd0aAorICAgICAgICAgICAgJiYgc3RybmNtcChxTmFtZSwgbVByZWZpeCwgcHJlZml4TGVuZ3RoKSA9PSAwCisgICAgICAgICAgICAmJiBzdHJjbXAobGFzdENvbG9uICsgMSwgbUxvY2FsTmFtZSkgPT0gMDsKKyAgICB9CisKK3ByaXZhdGU6CisgICAgSk5JRW52KiBtRW52OworICAgIFBhcnNpbmdDb250ZXh0KiBtUGFyc2luZ0NvbnRleHQ7CisgICAgY2hhciogbUNvcHk7CisgICAgY29uc3QgY2hhciogbVVyaTsKKyAgICBjb25zdCBjaGFyKiBtTG9jYWxOYW1lOworICAgIGNvbnN0IGNoYXIqIG1QcmVmaXg7CisKKyAgICAvKioKKyAgICAgKiBEZWNvZGVzIGFuIEV4cGF0LWVuY29kZWQgbmFtZSBvZiBvbmUgb2YgdGhlc2UgdGhyZWUgZm9ybXM6CisgICAgICogICAgICJ1cml8bG9jYWxOYW1lfHByZWZpeCIgKGV4YW1wbGU6ICJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sfGgxfGh0bWwiKQorICAgICAqICAgICAidXJpfGxvY2FsTmFtZSIgKGV4YW1wbGU6ICJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sfGgxIikKKyAgICAgKiAgICAgImxvY2FsTmFtZSIgKGV4YW1wbGU6ICJoMSIpCisgICAgICovCisgICAgdm9pZCBpbml0KEpOSUVudiogZW52LCBQYXJzaW5nQ29udGV4dCogcGFyc2luZ0NvbnRleHQsIGNvbnN0IGNoYXIqIHMpIHsKKyAgICAgICAgbUVudiA9IGVudjsKKyAgICAgICAgbVBhcnNpbmdDb250ZXh0ID0gcGFyc2luZ0NvbnRleHQ7CisgICAgICAgIG1Db3B5ID0gc3RyZHVwKHMpOworCisgICAgICAgIC8vIHNwbGl0IHRoZSBpbnB1dCBpbnRvIHVwIHRvIDMgcGFydHM6IGF8YnxjCisgICAgICAgIGNoYXIqIGNvbnRleHQgPSBOVUxMOworICAgICAgICBjaGFyKiBhID0gc3RydG9rX3IobUNvcHksICJ8IiwgJmNvbnRleHQpOworICAgICAgICBjaGFyKiBiID0gc3RydG9rX3IoTlVMTCwgInwiLCAmY29udGV4dCk7CisgICAgICAgIGNoYXIqIGMgPSBzdHJ0b2tfcihOVUxMLCAifCIsICZjb250ZXh0KTsKKworICAgICAgICBpZiAoYyAhPSBOVUxMKSB7IC8vIGlucHV0IG9mIHRoZSBmb3JtICJ1cml8bG9jYWxOYW1lfHByZWZpeCIKKyAgICAgICAgICAgIG1VcmkgPSBhOworICAgICAgICAgICAgbUxvY2FsTmFtZSA9IGI7CisgICAgICAgICAgICBtUHJlZml4ID0gYzsKKyAgICAgICAgfSBlbHNlIGlmIChiICE9IE5VTEwpIHsgLy8gaW5wdXQgb2YgdGhlIGZvcm0gInVyaXxsb2NhbE5hbWUiCisgICAgICAgICAgICBtVXJpID0gYTsKKyAgICAgICAgICAgIG1Mb2NhbE5hbWUgPSBiOworICAgICAgICAgICAgbVByZWZpeCA9ICIiOworICAgICAgICB9IGVsc2UgeyAvLyBpbnB1dCBvZiB0aGUgZm9ybSAibG9jYWxOYW1lIgorICAgICAgICAgICAgbUxvY2FsTmFtZSA9IGE7CisgICAgICAgICAgICBtVXJpID0gIiI7CisgICAgICAgICAgICBtUHJlZml4ID0gIiI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBEaXNhbGxvdyBjb3B5IGFuZCBhc3NpZ25tZW50LgorICAgIEV4cGF0RWxlbWVudE5hbWUoY29uc3QgRXhwYXRFbGVtZW50TmFtZSYpOworICAgIHZvaWQgb3BlcmF0b3I9KGNvbnN0IEV4cGF0RWxlbWVudE5hbWUmKTsKK307CisKKy8qKgorICogQ2FsbGVkIGJ5IEV4cGF0IGF0IHRoZSBzdGFydCBvZiBhbiBlbGVtZW50LiBEZWxlZ2F0ZXMgdG8gdGhlIHNhbWUgbWV0aG9kCisgKiBvbiB0aGUgSmF2YSBwYXJzZXIuCisgKgorICogQHBhcmFtIGRhdGEgcGFyc2luZyBjb250ZXh0CisgKiBAcGFyYW0gZWxlbWVudE5hbWUgInVyaXxsb2NhbE5hbWUiIG9yICJsb2NhbE5hbWUiIGZvciB0aGUgY3VycmVudCBlbGVtZW50CisgKiBAcGFyYW0gYXR0cmlidXRlcyBhbHRlcm5hdGluZyBhdHRyaWJ1dGUgbmFtZXMgYW5kIHZhbHVlcy4gTGlrZSBlbGVtZW50CisgKiBuYW1lcywgYXR0cmlidXRlIG5hbWVzIGZvbGxvdyB0aGUgZm9ybWF0ICJ1cml8bG9jYWxOYW1lIiBvciAibG9jYWxOYW1lIi4KKyAqLworc3RhdGljIHZvaWQgc3RhcnRFbGVtZW50KHZvaWQqIGRhdGEsIGNvbnN0IGNoYXIqIGVsZW1lbnROYW1lLCBjb25zdCBjaGFyKiogYXR0cmlidXRlcykgeworICAgIFBhcnNpbmdDb250ZXh0KiBwYXJzaW5nQ29udGV4dCA9IHRvUGFyc2luZ0NvbnRleHQoZGF0YSk7CisgICAgSk5JRW52KiBlbnYgPSBwYXJzaW5nQ29udGV4dC0+ZW52OworCisgICAgLy8gQmFpbCBvdXQgaWYgYSBwcmV2aW91c2x5IGNhbGxlZCBoYW5kbGVyIHRocmV3IGFuIGV4Y2VwdGlvbi4KKyAgICBpZiAoZW52LT5FeGNlcHRpb25DaGVjaygpKSByZXR1cm47CisKKyAgICAvLyBDb3VudCB0aGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMuCisgICAgaW50IGNvdW50ID0gMDsKKyAgICB3aGlsZSAoYXR0cmlidXRlc1tjb3VudCAqIDJdKSBjb3VudCsrOworCisgICAgLy8gTWFrZSB0aGUgYXR0cmlidXRlcyBhdmFpbGFibGUgZm9yIHRoZSBkdXJhdGlvbiBvZiB0aGlzIGNhbGwuCisgICAgcGFyc2luZ0NvbnRleHQtPmF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzOworICAgIHBhcnNpbmdDb250ZXh0LT5hdHRyaWJ1dGVDb3VudCA9IGNvdW50OworCisgICAgam9iamVjdCBqYXZhUGFyc2VyID0gcGFyc2luZ0NvbnRleHQtPm9iamVjdDsKKworICAgIEV4cGF0RWxlbWVudE5hbWUgZShlbnYsIHBhcnNpbmdDb250ZXh0LCBlbGVtZW50TmFtZSk7CisgICAganN0cmluZyB1cmkgPSBwYXJzaW5nQ29udGV4dC0+cHJvY2Vzc05hbWVzcGFjZXMgPyBlLnVyaSgpIDogZW1wdHlTdHJpbmc7CisgICAganN0cmluZyBsb2NhbE5hbWUgPSBwYXJzaW5nQ29udGV4dC0+cHJvY2Vzc05hbWVzcGFjZXMgPyBlLmxvY2FsTmFtZSgpIDogZW1wdHlTdHJpbmc7CisgICAganN0cmluZyBxTmFtZSA9IGUucU5hbWUoKTsKKworICAgIHBhcnNpbmdDb250ZXh0LT5zdHJpbmdTdGFjay5wdXNoKGVudiwgcU5hbWUpOworICAgIHBhcnNpbmdDb250ZXh0LT5zdHJpbmdTdGFjay5wdXNoKGVudiwgdXJpKTsKKyAgICBwYXJzaW5nQ29udGV4dC0+c3RyaW5nU3RhY2sucHVzaChlbnYsIGxvY2FsTmFtZSk7CisKKyAgICBlbnYtPkNhbGxWb2lkTWV0aG9kKGphdmFQYXJzZXIsIHN0YXJ0RWxlbWVudE1ldGhvZCwgdXJpLCBsb2NhbE5hbWUsIHFOYW1lLCBhdHRyaWJ1dGVzLCBjb3VudCk7CisKKyAgICBwYXJzaW5nQ29udGV4dC0+YXR0cmlidXRlcyA9IE5VTEw7CisgICAgcGFyc2luZ0NvbnRleHQtPmF0dHJpYnV0ZUNvdW50ID0gLTE7Cit9CisKKy8qKgorICogQ2FsbGVkIGJ5IEV4cGF0IGF0IHRoZSBlbmQgb2YgYW4gZWxlbWVudC4gRGVsZWdhdGVzIHRvIHRoZSBzYW1lIG1ldGhvZAorICogb24gdGhlIEphdmEgcGFyc2VyLgorICoKKyAqIEBwYXJhbSBkYXRhIHBhcnNpbmcgY29udGV4dAorICogQHBhcmFtIGVsZW1lbnROYW1lICJ1cml8bG9jYWxOYW1lIiBvciAibG9jYWxOYW1lIiBmb3IgdGhlIGN1cnJlbnQgZWxlbWVudDsKKyAqICAgICAgICAgd2UgYXNzdW1lIHRoYXQgdGhpcyBtYXRjaGVzIHRoZSBsYXN0IGRhdGEgb24gb3VyIHN0YWNrLgorICovCitzdGF0aWMgdm9pZCBlbmRFbGVtZW50KHZvaWQqIGRhdGEsIGNvbnN0IGNoYXIqIC8qZWxlbWVudE5hbWUqLykgeworICAgIFBhcnNpbmdDb250ZXh0KiBwYXJzaW5nQ29udGV4dCA9IHRvUGFyc2luZ0NvbnRleHQoZGF0YSk7CisgICAgSk5JRW52KiBlbnYgPSBwYXJzaW5nQ29udGV4dC0+ZW52OworCisgICAgLy8gQmFpbCBvdXQgaWYgYSBwcmV2aW91c2x5IGNhbGxlZCBoYW5kbGVyIHRocmV3IGFuIGV4Y2VwdGlvbi4KKyAgICBpZiAoZW52LT5FeGNlcHRpb25DaGVjaygpKSByZXR1cm47CisKKyAgICBqb2JqZWN0IGphdmFQYXJzZXIgPSBwYXJzaW5nQ29udGV4dC0+b2JqZWN0OworCisgICAganN0cmluZyBsb2NhbE5hbWUgPSBwYXJzaW5nQ29udGV4dC0+c3RyaW5nU3RhY2sucG9wKCk7CisgICAganN0cmluZyB1cmkgPSBwYXJzaW5nQ29udGV4dC0+c3RyaW5nU3RhY2sucG9wKCk7CisgICAganN0cmluZyBxTmFtZSA9IHBhcnNpbmdDb250ZXh0LT5zdHJpbmdTdGFjay5wb3AoKTsKKworICAgIGVudi0+Q2FsbFZvaWRNZXRob2QoamF2YVBhcnNlciwgZW5kRWxlbWVudE1ldGhvZCwgdXJpLCBsb2NhbE5hbWUsIHFOYW1lKTsKK30KKworLyoqCisgKiBDYWxsZWQgYnkgRXhwYXQgd2hlbiBpdCBlbmNvdW50ZXJzIHRleHQuIERlbGVnYXRlcyB0byB0aGUgc2FtZSBtZXRob2QKKyAqIG9uIHRoZSBKYXZhIHBhcnNlci4gVGhpcyBtYXkgYmUgY2FsbGVkIG11dGlwbGUgdGltZXMgd2l0aCBpbmNyZW1lbnRhbCBwaWVjZXMKKyAqIG9mIHRoZSBzYW1lIGNvbnRpZ3VvdXMgYmxvY2sgb2YgdGV4dC4KKyAqCisgKiBAcGFyYW0gZGF0YSBwYXJzaW5nIGNvbnRleHQKKyAqIEBwYXJhbSBjaGFyYWN0ZXJzIGJ1ZmZlciBjb250YWluaW5nIGVuY291bnRlcmVkIHRleHQKKyAqIEBwYXJhbSBsZW5ndGggbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gdGhlIGJ1ZmZlcgorICovCitzdGF0aWMgdm9pZCB0ZXh0KHZvaWQqIGRhdGEsIGNvbnN0IGNoYXIqIGNoYXJhY3RlcnMsIGludCBsZW5ndGgpIHsKKyAgICBidWZmZXJBbmRJbnZva2UodGV4dE1ldGhvZCwgZGF0YSwgY2hhcmFjdGVycywgbGVuZ3RoKTsKK30KKworLyoqCisgKiBDYWxsZWQgYnkgRXhwYXQgd2hlbiBpdCBlbmNvdW50ZXJzIGEgY29tbWVudC4gRGVsZWdhdGVzIHRvIHRoZSBzYW1lIG1ldGhvZAorICogb24gdGhlIEphdmEgcGFyc2VyLgorCisgKiBAcGFyYW0gZGF0YSBwYXJzaW5nIGNvbnRleHQKKyAqIEBwYXJhbSBjb21tZW50IDAtdGVybWluYXRlZAorICovCitzdGF0aWMgdm9pZCBjb21tZW50KHZvaWQqIGRhdGEsIGNvbnN0IGNoYXIqIGNvbW1lbnQpIHsKKyAgICBidWZmZXJBbmRJbnZva2UoY29tbWVudE1ldGhvZCwgZGF0YSwgY29tbWVudCwgc3RybGVuKGNvbW1lbnQpKTsKK30KKworLyoqCisgKiBDYWxsZWQgYnkgRXhwYXQgYXQgdGhlIGJlZ2lubmluZyBvZiBhIG5hbWVzcGFjZSBtYXBwaW5nLgorICoKKyAqIEBwYXJhbSBkYXRhIHBhcnNpbmcgY29udGV4dAorICogQHBhcmFtIHByZWZpeCBudWxsLXRlcm1pbmF0ZWQgbmFtZXNwYWNlIHByZWZpeCB1c2VkIGluIHRoZSBYTUwKKyAqIEBwYXJhbSB1cmkgb2YgdGhlIG5hbWVzcGFjZQorICovCitzdGF0aWMgdm9pZCBzdGFydE5hbWVzcGFjZSh2b2lkKiBkYXRhLCBjb25zdCBjaGFyKiBwcmVmaXgsIGNvbnN0IGNoYXIqIHVyaSkgeworICAgIFBhcnNpbmdDb250ZXh0KiBwYXJzaW5nQ29udGV4dCA9IHRvUGFyc2luZ0NvbnRleHQoZGF0YSk7CisgICAgSk5JRW52KiBlbnYgPSBwYXJzaW5nQ29udGV4dC0+ZW52OworCisgICAgLy8gQmFpbCBvdXQgaWYgYSBwcmV2aW91c2x5IGNhbGxlZCBoYW5kbGVyIHRocmV3IGFuIGV4Y2VwdGlvbi4KKyAgICBpZiAoZW52LT5FeGNlcHRpb25DaGVjaygpKSByZXR1cm47CisKKyAgICBqc3RyaW5nIGludGVybmVkUHJlZml4ID0gZW1wdHlTdHJpbmc7CisgICAgaWYgKHByZWZpeCAhPSBOVUxMKSB7CisgICAgICAgIGludGVybmVkUHJlZml4ID0gaW50ZXJuU3RyaW5nKGVudiwgcGFyc2luZ0NvbnRleHQsIHByZWZpeCk7CisgICAgICAgIGlmIChlbnYtPkV4Y2VwdGlvbkNoZWNrKCkpIHJldHVybjsKKyAgICB9CisKKyAgICBqc3RyaW5nIGludGVybmVkVXJpID0gZW1wdHlTdHJpbmc7CisgICAgaWYgKHVyaSAhPSBOVUxMKSB7CisgICAgICAgIGludGVybmVkVXJpID0gaW50ZXJuU3RyaW5nKGVudiwgcGFyc2luZ0NvbnRleHQsIHVyaSk7CisgICAgICAgIGlmIChlbnYtPkV4Y2VwdGlvbkNoZWNrKCkpIHJldHVybjsKKyAgICB9CisKKyAgICBwYXJzaW5nQ29udGV4dC0+c3RyaW5nU3RhY2sucHVzaChlbnYsIGludGVybmVkUHJlZml4KTsKKworICAgIGpvYmplY3QgamF2YVBhcnNlciA9IHBhcnNpbmdDb250ZXh0LT5vYmplY3Q7CisgICAgZW52LT5DYWxsVm9pZE1ldGhvZChqYXZhUGFyc2VyLCBzdGFydE5hbWVzcGFjZU1ldGhvZCwgaW50ZXJuZWRQcmVmaXgsIGludGVybmVkVXJpKTsKK30KKworLyoqCisgKiBDYWxsZWQgYnkgRXhwYXQgYXQgdGhlIGVuZCBvZiBhIG5hbWVzcGFjZSBtYXBwaW5nLgorICoKKyAqIEBwYXJhbSBkYXRhIHBhcnNpbmcgY29udGV4dAorICogQHBhcmFtIHByZWZpeCBudWxsLXRlcm1pbmF0ZWQgbmFtZXNwYWNlIHByZWZpeCB1c2VkIGluIHRoZSBYTUw7CisgKiAgICAgICAgIHdlIGFzc3VtZSB0aGlzIGlzIHRoZSBzYW1lIGFzIHRoZSBsYXN0IHByZWZpeCBvbiB0aGUgc3RhY2suCisgKi8KK3N0YXRpYyB2b2lkIGVuZE5hbWVzcGFjZSh2b2lkKiBkYXRhLCBjb25zdCBjaGFyKiAvKnByZWZpeCovKSB7CisgICAgUGFyc2luZ0NvbnRleHQqIHBhcnNpbmdDb250ZXh0ID0gdG9QYXJzaW5nQ29udGV4dChkYXRhKTsKKyAgICBKTklFbnYqIGVudiA9IHBhcnNpbmdDb250ZXh0LT5lbnY7CisKKyAgICAvLyBCYWlsIG91dCBpZiBhIHByZXZpb3VzbHkgY2FsbGVkIGhhbmRsZXIgdGhyZXcgYW4gZXhjZXB0aW9uLgorICAgIGlmIChlbnYtPkV4Y2VwdGlvbkNoZWNrKCkpIHJldHVybjsKKworICAgIGpzdHJpbmcgaW50ZXJuZWRQcmVmaXggPSBwYXJzaW5nQ29udGV4dC0+c3RyaW5nU3RhY2sucG9wKCk7CisKKyAgICBqb2JqZWN0IGphdmFQYXJzZXIgPSBwYXJzaW5nQ29udGV4dC0+b2JqZWN0OworICAgIGVudi0+Q2FsbFZvaWRNZXRob2QoamF2YVBhcnNlciwgZW5kTmFtZXNwYWNlTWV0aG9kLCBpbnRlcm5lZFByZWZpeCk7Cit9CisKKy8qKgorICogQ2FsbGVkIGJ5IEV4cGF0IGF0IHRoZSBiZWdpbm5pbmcgb2YgYSBDREFUQSBzZWN0aW9uLgorICoKKyAqIEBwYXJhbSBkYXRhIHBhcnNpbmcgY29udGV4dAorICovCitzdGF0aWMgdm9pZCBzdGFydENkYXRhKHZvaWQqIGRhdGEpIHsKKyAgICBQYXJzaW5nQ29udGV4dCogcGFyc2luZ0NvbnRleHQgPSB0b1BhcnNpbmdDb250ZXh0KGRhdGEpOworICAgIEpOSUVudiogZW52ID0gcGFyc2luZ0NvbnRleHQtPmVudjsKKworICAgIC8vIEJhaWwgb3V0IGlmIGEgcHJldmlvdXNseSBjYWxsZWQgaGFuZGxlciB0aHJldyBhbiBleGNlcHRpb24uCisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgcmV0dXJuOworCisgICAgam9iamVjdCBqYXZhUGFyc2VyID0gcGFyc2luZ0NvbnRleHQtPm9iamVjdDsKKyAgICBlbnYtPkNhbGxWb2lkTWV0aG9kKGphdmFQYXJzZXIsIHN0YXJ0Q2RhdGFNZXRob2QpOworfQorCisvKioKKyAqIENhbGxlZCBieSBFeHBhdCBhdCB0aGUgZW5kIG9mIGEgQ0RBVEEgc2VjdGlvbi4KKyAqCisgKiBAcGFyYW0gZGF0YSBwYXJzaW5nIGNvbnRleHQKKyAqLworc3RhdGljIHZvaWQgZW5kQ2RhdGEodm9pZCogZGF0YSkgeworICAgIFBhcnNpbmdDb250ZXh0KiBwYXJzaW5nQ29udGV4dCA9IHRvUGFyc2luZ0NvbnRleHQoZGF0YSk7CisgICAgSk5JRW52KiBlbnYgPSBwYXJzaW5nQ29udGV4dC0+ZW52OworCisgICAgLy8gQmFpbCBvdXQgaWYgYSBwcmV2aW91c2x5IGNhbGxlZCBoYW5kbGVyIHRocmV3IGFuIGV4Y2VwdGlvbi4KKyAgICBpZiAoZW52LT5FeGNlcHRpb25DaGVjaygpKSByZXR1cm47CisKKyAgICBqb2JqZWN0IGphdmFQYXJzZXIgPSBwYXJzaW5nQ29udGV4dC0+b2JqZWN0OworICAgIGVudi0+Q2FsbFZvaWRNZXRob2QoamF2YVBhcnNlciwgZW5kQ2RhdGFNZXRob2QpOworfQorCisvKioKKyAqIENhbGxlZCBieSBFeHBhdCBhdCB0aGUgYmVnaW5uaW5nIG9mIGEgRE9DVFlQRSBzZWN0aW9uLgorICogRXhwYXQgZ2l2ZXMgdXMgJ2hhc0ludGVybmFsU3Vic2V0JywgYnV0IHRoZSBKYXZhIEFQSSBkb2Vzbid0IGV4cGVjdCBpdCwgc28gd2UgZG9uJ3QgbmVlZCBpdC4KKyAqLworc3RhdGljIHZvaWQgc3RhcnREdGQodm9pZCogZGF0YSwgY29uc3QgY2hhciogbmFtZSwKKyAgICAgICAgY29uc3QgY2hhciogc3lzdGVtSWQsIGNvbnN0IGNoYXIqIHB1YmxpY0lkLCBpbnQgLypoYXNJbnRlcm5hbFN1YnNldCovKSB7CisgICAgUGFyc2luZ0NvbnRleHQqIHBhcnNpbmdDb250ZXh0ID0gdG9QYXJzaW5nQ29udGV4dChkYXRhKTsKKyAgICBKTklFbnYqIGVudiA9IHBhcnNpbmdDb250ZXh0LT5lbnY7CisKKyAgICAvLyBCYWlsIG91dCBpZiBhIHByZXZpb3VzbHkgY2FsbGVkIGhhbmRsZXIgdGhyZXcgYW4gZXhjZXB0aW9uLgorICAgIGlmIChlbnYtPkV4Y2VwdGlvbkNoZWNrKCkpIHJldHVybjsKKworICAgIGpzdHJpbmcgamF2YU5hbWUgPSBpbnRlcm5TdHJpbmcoZW52LCBwYXJzaW5nQ29udGV4dCwgbmFtZSk7CisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgcmV0dXJuOworCisgICAganN0cmluZyBqYXZhUHVibGljSWQgPSBpbnRlcm5TdHJpbmcoZW52LCBwYXJzaW5nQ29udGV4dCwgcHVibGljSWQpOworICAgIGlmIChlbnYtPkV4Y2VwdGlvbkNoZWNrKCkpIHJldHVybjsKKworICAgIGpzdHJpbmcgamF2YVN5c3RlbUlkID0gaW50ZXJuU3RyaW5nKGVudiwgcGFyc2luZ0NvbnRleHQsIHN5c3RlbUlkKTsKKyAgICBpZiAoZW52LT5FeGNlcHRpb25DaGVjaygpKSByZXR1cm47CisKKyAgICBqb2JqZWN0IGphdmFQYXJzZXIgPSBwYXJzaW5nQ29udGV4dC0+b2JqZWN0OworICAgIGVudi0+Q2FsbFZvaWRNZXRob2QoamF2YVBhcnNlciwgc3RhcnREdGRNZXRob2QsIGphdmFOYW1lLCBqYXZhUHVibGljSWQsCisgICAgICAgIGphdmFTeXN0ZW1JZCk7Cit9CisKKy8qKgorICogQ2FsbGVkIGJ5IEV4cGF0IGF0IHRoZSBlbmQgb2YgYSBET0NUWVBFIHNlY3Rpb24uCisgKgorICogQHBhcmFtIGRhdGEgcGFyc2luZyBjb250ZXh0CisgKi8KK3N0YXRpYyB2b2lkIGVuZER0ZCh2b2lkKiBkYXRhKSB7CisgICAgUGFyc2luZ0NvbnRleHQqIHBhcnNpbmdDb250ZXh0ID0gdG9QYXJzaW5nQ29udGV4dChkYXRhKTsKKyAgICBKTklFbnYqIGVudiA9IHBhcnNpbmdDb250ZXh0LT5lbnY7CisKKyAgICAvLyBCYWlsIG91dCBpZiBhIHByZXZpb3VzbHkgY2FsbGVkIGhhbmRsZXIgdGhyZXcgYW4gZXhjZXB0aW9uLgorICAgIGlmIChlbnYtPkV4Y2VwdGlvbkNoZWNrKCkpIHJldHVybjsKKworICAgIGpvYmplY3QgamF2YVBhcnNlciA9IHBhcnNpbmdDb250ZXh0LT5vYmplY3Q7CisgICAgZW52LT5DYWxsVm9pZE1ldGhvZChqYXZhUGFyc2VyLCBlbmREdGRNZXRob2QpOworfQorCisvKioKKyAqIENhbGxlZCBieSBFeHBhdCB3aGVuIGl0IGVuY291bnRlcnMgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMuCisgKgorICogQHBhcmFtIGRhdGEgcGFyc2luZyBjb250ZXh0CisgKiBAcGFyYW0gdGFyZ2V0IG9mIHRoZSBpbnN0cnVjdGlvbgorICogQHBhcmFtIGluc3RydWN0aW9uRGF0YQorICovCitzdGF0aWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odm9pZCogZGF0YSwgY29uc3QgY2hhciogdGFyZ2V0LCBjb25zdCBjaGFyKiBpbnN0cnVjdGlvbkRhdGEpIHsKKyAgICBQYXJzaW5nQ29udGV4dCogcGFyc2luZ0NvbnRleHQgPSB0b1BhcnNpbmdDb250ZXh0KGRhdGEpOworICAgIEpOSUVudiogZW52ID0gcGFyc2luZ0NvbnRleHQtPmVudjsKKworICAgIC8vIEJhaWwgb3V0IGlmIGEgcHJldmlvdXNseSBjYWxsZWQgaGFuZGxlciB0aHJldyBhbiBleGNlcHRpb24uCisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgcmV0dXJuOworCisgICAganN0cmluZyBqYXZhVGFyZ2V0ID0gaW50ZXJuU3RyaW5nKGVudiwgcGFyc2luZ0NvbnRleHQsIHRhcmdldCk7CisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgcmV0dXJuOworCisgICAgU2NvcGVkTG9jYWxSZWY8anN0cmluZz4gamF2YUluc3RydWN0aW9uRGF0YShlbnYsIGVudi0+TmV3U3RyaW5nVVRGKGluc3RydWN0aW9uRGF0YSkpOworICAgIGlmIChlbnYtPkV4Y2VwdGlvbkNoZWNrKCkpIHJldHVybjsKKworICAgIGpvYmplY3QgamF2YVBhcnNlciA9IHBhcnNpbmdDb250ZXh0LT5vYmplY3Q7CisgICAgZW52LT5DYWxsVm9pZE1ldGhvZChqYXZhUGFyc2VyLCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb25NZXRob2QsIGphdmFUYXJnZXQsIGphdmFJbnN0cnVjdGlvbkRhdGEuZ2V0KCkpOworfQorCisvKioKKyAqIENyZWF0ZXMgYSBuZXcgZW50aXR5IHBhcnNlci4KKyAqCisgKiBAcGFyYW0gb2JqZWN0IHRoZSBKYXZhIEV4cGF0UGFyc2VyIGluc3RhbmNlCisgKiBAcGFyYW0gcGFyZW50UGFyc2VyIHBvaW50ZXIKKyAqIEBwYXJhbSBqYXZhRW5jb2RpbmcgdGhlIGNoYXJhY3RlciBlbmNvZGluZyBuYW1lCisgKiBAcGFyYW0gamF2YUNvbnRleHQgdGhhdCB3YXMgcHJvdmlkZWQgdG8gaGFuZGxlRXh0ZXJuYWxFbnRpdHkKKyAqIEByZXR1cm5zIHRoZSBwb2ludGVyIHRvIHRoZSBDIEV4cGF0IGVudGl0eSBwYXJzZXIKKyAqLworc3RhdGljIGppbnQgRXhwYXRQYXJzZXJfY3JlYXRlRW50aXR5UGFyc2VyKEpOSUVudiogZW52LCBqb2JqZWN0LCBqaW50IHBhcmVudFBhcnNlciwganN0cmluZyBqYXZhQ29udGV4dCkgeworICAgIFNjb3BlZFV0ZkNoYXJzIGNvbnRleHQoZW52LCBqYXZhQ29udGV4dCk7CisgICAgaWYgKGNvbnRleHQuY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIFhNTF9QYXJzZXIgcGFyZW50ID0gKFhNTF9QYXJzZXIpIHBhcmVudFBhcnNlcjsKKyAgICBYTUxfUGFyc2VyIGVudGl0eVBhcnNlciA9IFhNTF9FeHRlcm5hbEVudGl0eVBhcnNlckNyZWF0ZShwYXJlbnQsIGNvbnRleHQuY19zdHIoKSwgTlVMTCk7CisgICAgaWYgKGVudGl0eVBhcnNlciA9PSBOVUxMKSB7CisgICAgICAgIGpuaVRocm93T3V0T2ZNZW1vcnlFcnJvcihlbnYsIE5VTEwpOworICAgIH0KKworICAgIHJldHVybiAoamludCkgZW50aXR5UGFyc2VyOworfQorCisvKioKKyAqIEhhbmRsZXMgZXh0ZXJuYWwgZW50aXRpZXMuIFdlIGlnbm9yZSB0aGUgImJhc2UiIFVSSSBhbmQga2VlcCB0cmFjayBvZiBpdAorICogb3Vyc2VsdmVzLgorICovCitzdGF0aWMgaW50IGhhbmRsZUV4dGVybmFsRW50aXR5KFhNTF9QYXJzZXIgcGFyc2VyLCBjb25zdCBjaGFyKiBjb250ZXh0LAorICAgICAgICBjb25zdCBjaGFyKiwgY29uc3QgY2hhciogc3lzdGVtSWQsIGNvbnN0IGNoYXIqIHB1YmxpY0lkKSB7CisgICAgUGFyc2luZ0NvbnRleHQqIHBhcnNpbmdDb250ZXh0ID0gdG9QYXJzaW5nQ29udGV4dChwYXJzZXIpOworICAgIGpvYmplY3QgamF2YVBhcnNlciA9IHBhcnNpbmdDb250ZXh0LT5vYmplY3Q7CisgICAgSk5JRW52KiBlbnYgPSBwYXJzaW5nQ29udGV4dC0+ZW52OworICAgIGpvYmplY3Qgb2JqZWN0ID0gcGFyc2luZ0NvbnRleHQtPm9iamVjdDsKKworICAgIC8vIEJhaWwgb3V0IGlmIGEgcHJldmlvdXNseSBjYWxsZWQgaGFuZGxlciB0aHJldyBhbiBleGNlcHRpb24uCisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgeworICAgICAgICByZXR1cm4gWE1MX1NUQVRVU19FUlJPUjsKKyAgICB9CisKKyAgICBTY29wZWRMb2NhbFJlZjxqc3RyaW5nPiBqYXZhU3lzdGVtSWQoZW52LCBlbnYtPk5ld1N0cmluZ1VURihzeXN0ZW1JZCkpOworICAgIGlmIChlbnYtPkV4Y2VwdGlvbkNoZWNrKCkpIHsKKyAgICAgICAgcmV0dXJuIFhNTF9TVEFUVVNfRVJST1I7CisgICAgfQorICAgIFNjb3BlZExvY2FsUmVmPGpzdHJpbmc+IGphdmFQdWJsaWNJZChlbnYsIGVudi0+TmV3U3RyaW5nVVRGKHB1YmxpY0lkKSk7CisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgeworICAgICAgICByZXR1cm4gWE1MX1NUQVRVU19FUlJPUjsKKyAgICB9CisgICAgU2NvcGVkTG9jYWxSZWY8anN0cmluZz4gamF2YUNvbnRleHQoZW52LCBlbnYtPk5ld1N0cmluZ1VURihjb250ZXh0KSk7CisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgeworICAgICAgICByZXR1cm4gWE1MX1NUQVRVU19FUlJPUjsKKyAgICB9CisKKyAgICAvLyBQYXNzIHRoZSB3cmFwcGVkIHBhcnNlciBhbmQgYm90aCBzdHJpbmdzIHRvIGphdmEuCisgICAgZW52LT5DYWxsVm9pZE1ldGhvZChqYXZhUGFyc2VyLCBoYW5kbGVFeHRlcm5hbEVudGl0eU1ldGhvZCwgamF2YUNvbnRleHQuZ2V0KCksCisgICAgICAgICAgICBqYXZhUHVibGljSWQuZ2V0KCksIGphdmFTeXN0ZW1JZC5nZXQoKSk7CisKKyAgICAvKgorICAgICAqIFBhcnNpbmcgdGhlIGV4dGVybmFsIGVudGl0eSBsZWF2ZXMgcGFyc2luZ0NvbnRleHQtPmVudiBhbmQgb2JqZWN0IHNldCB0bworICAgICAqIE5VTEwsIHNvIHdlIG5lZWQgdG8gcmVzdG9yZSBib3RoLgorICAgICAqCisgICAgICogVE9ETzogY29uc2lkZXIgcmVzdG9yaW5nIHRoZSBvcmlnaW5hbCBlbnYgYW5kIG9iamVjdCBpbnN0ZWFkIG9mIHNldHRpbmcKKyAgICAgKiB0aGVtIHRvIE5VTEwgaW4gdGhlIGFwcGVuZCgpIGZ1bmN0aW9ucy4KKyAgICAgKi8KKyAgICBwYXJzaW5nQ29udGV4dC0+ZW52ID0gZW52OworICAgIHBhcnNpbmdDb250ZXh0LT5vYmplY3QgPSBvYmplY3Q7CisKKyAgICByZXR1cm4gZW52LT5FeGNlcHRpb25DaGVjaygpID8gWE1MX1NUQVRVU19FUlJPUiA6IFhNTF9TVEFUVVNfT0s7Cit9CisKKy8qKgorICogRXhwYXQgZ2l2ZXMgdXMgJ2Jhc2UnLCBidXQgdGhlIEphdmEgQVBJIGRvZXNuJ3QgZXhwZWN0IGl0LCBzbyB3ZSBkb24ndCBuZWVkIGl0LgorICovCitzdGF0aWMgdm9pZCB1bnBhcnNlZEVudGl0eURlY2wodm9pZCogZGF0YSwgY29uc3QgY2hhciogbmFtZSwgY29uc3QgY2hhciogLypiYXNlKi8sIGNvbnN0IGNoYXIqIHN5c3RlbUlkLCBjb25zdCBjaGFyKiBwdWJsaWNJZCwgY29uc3QgY2hhciogbm90YXRpb25OYW1lKSB7CisgICAgUGFyc2luZ0NvbnRleHQqIHBhcnNpbmdDb250ZXh0ID0gdG9QYXJzaW5nQ29udGV4dChkYXRhKTsKKyAgICBqb2JqZWN0IGphdmFQYXJzZXIgPSBwYXJzaW5nQ29udGV4dC0+b2JqZWN0OworICAgIEpOSUVudiogZW52ID0gcGFyc2luZ0NvbnRleHQtPmVudjsKKworICAgIC8vIEJhaWwgb3V0IGlmIGEgcHJldmlvdXNseSBjYWxsZWQgaGFuZGxlciB0aHJldyBhbiBleGNlcHRpb24uCisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgcmV0dXJuOworCisgICAgU2NvcGVkTG9jYWxSZWY8anN0cmluZz4gamF2YU5hbWUoZW52LCBlbnYtPk5ld1N0cmluZ1VURihuYW1lKSk7CisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgcmV0dXJuOworICAgIFNjb3BlZExvY2FsUmVmPGpzdHJpbmc+IGphdmFQdWJsaWNJZChlbnYsIGVudi0+TmV3U3RyaW5nVVRGKHB1YmxpY0lkKSk7CisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgcmV0dXJuOworICAgIFNjb3BlZExvY2FsUmVmPGpzdHJpbmc+IGphdmFTeXN0ZW1JZChlbnYsIGVudi0+TmV3U3RyaW5nVVRGKHN5c3RlbUlkKSk7CisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgcmV0dXJuOworICAgIFNjb3BlZExvY2FsUmVmPGpzdHJpbmc+IGphdmFOb3RhdGlvbk5hbWUoZW52LCBlbnYtPk5ld1N0cmluZ1VURihub3RhdGlvbk5hbWUpKTsKKyAgICBpZiAoZW52LT5FeGNlcHRpb25DaGVjaygpKSByZXR1cm47CisKKyAgICBlbnYtPkNhbGxWb2lkTWV0aG9kKGphdmFQYXJzZXIsIHVucGFyc2VkRW50aXR5RGVjbE1ldGhvZCwgamF2YU5hbWUuZ2V0KCksIGphdmFQdWJsaWNJZC5nZXQoKSwgamF2YVN5c3RlbUlkLmdldCgpLCBqYXZhTm90YXRpb25OYW1lLmdldCgpKTsKK30KKworLyoqCisgKiBFeHBhdCBnaXZlcyB1cyAnYmFzZScsIGJ1dCB0aGUgSmF2YSBBUEkgZG9lc24ndCBleHBlY3QgaXQsIHNvIHdlIGRvbid0IG5lZWQgaXQuCisgKi8KK3N0YXRpYyB2b2lkIG5vdGF0aW9uRGVjbCh2b2lkKiBkYXRhLCBjb25zdCBjaGFyKiBuYW1lLCBjb25zdCBjaGFyKiAvKmJhc2UqLywgY29uc3QgY2hhciogc3lzdGVtSWQsIGNvbnN0IGNoYXIqIHB1YmxpY0lkKSB7CisgICAgUGFyc2luZ0NvbnRleHQqIHBhcnNpbmdDb250ZXh0ID0gdG9QYXJzaW5nQ29udGV4dChkYXRhKTsKKyAgICBqb2JqZWN0IGphdmFQYXJzZXIgPSBwYXJzaW5nQ29udGV4dC0+b2JqZWN0OworICAgIEpOSUVudiogZW52ID0gcGFyc2luZ0NvbnRleHQtPmVudjsKKworICAgIC8vIEJhaWwgb3V0IGlmIGEgcHJldmlvdXNseSBjYWxsZWQgaGFuZGxlciB0aHJldyBhbiBleGNlcHRpb24uCisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgcmV0dXJuOworCisgICAgU2NvcGVkTG9jYWxSZWY8anN0cmluZz4gamF2YU5hbWUoZW52LCBlbnYtPk5ld1N0cmluZ1VURihuYW1lKSk7CisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgcmV0dXJuOworICAgIFNjb3BlZExvY2FsUmVmPGpzdHJpbmc+IGphdmFQdWJsaWNJZChlbnYsIGVudi0+TmV3U3RyaW5nVVRGKHB1YmxpY0lkKSk7CisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgcmV0dXJuOworICAgIFNjb3BlZExvY2FsUmVmPGpzdHJpbmc+IGphdmFTeXN0ZW1JZChlbnYsIGVudi0+TmV3U3RyaW5nVVRGKHN5c3RlbUlkKSk7CisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgcmV0dXJuOworCisgICAgZW52LT5DYWxsVm9pZE1ldGhvZChqYXZhUGFyc2VyLCBub3RhdGlvbkRlY2xNZXRob2QsIGphdmFOYW1lLmdldCgpLCBqYXZhUHVibGljSWQuZ2V0KCksIGphdmFTeXN0ZW1JZC5nZXQoKSk7Cit9CisKKy8qKgorICogQ3JlYXRlcyBhIG5ldyBFeHBhdCBwYXJzZXIuIENhbGxlZCBmcm9tIHRoZSBKYXZhIEV4cGF0UGFyc2VyIGNvbnN0cnVjdG9yLgorICoKKyAqIEBwYXJhbSBvYmplY3QgdGhlIEphdmEgRXhwYXRQYXJzZXIgaW5zdGFuY2UKKyAqIEBwYXJhbSBqYXZhRW5jb2RpbmcgdGhlIGNoYXJhY3RlciBlbmNvZGluZyBuYW1lCisgKiBAcGFyYW0gcHJvY2Vzc05hbWVzcGFjZXMgdHJ1ZSBpZiB0aGUgcGFyc2VyIHNob3VsZCBoYW5kbGUgbmFtZXNwYWNlcworICogQHJldHVybnMgdGhlIHBvaW50ZXIgdG8gdGhlIEMgRXhwYXQgcGFyc2VyCisgKi8KK3N0YXRpYyBqaW50IEV4cGF0UGFyc2VyX2luaXRpYWxpemUoSk5JRW52KiBlbnYsIGpvYmplY3Qgb2JqZWN0LCBqc3RyaW5nIGphdmFFbmNvZGluZywKKyAgICAgICAgamJvb2xlYW4gcHJvY2Vzc05hbWVzcGFjZXMpIHsKKyAgICAvLyBBbGxvY2F0ZSBwYXJzaW5nIGNvbnRleHQuCisgICAgVW5pcXVlUHRyPFBhcnNpbmdDb250ZXh0PiBjb250ZXh0KG5ldyBQYXJzaW5nQ29udGV4dChvYmplY3QpKTsKKyAgICBpZiAoY29udGV4dC5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIGpuaVRocm93T3V0T2ZNZW1vcnlFcnJvcihlbnYsIE5VTEwpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBjb250ZXh0LT5wcm9jZXNzTmFtZXNwYWNlcyA9IChib29sKSBwcm9jZXNzTmFtZXNwYWNlczsKKworICAgIC8vIENyZWF0ZSBhIHBhcnNlci4KKyAgICBYTUxfUGFyc2VyIHBhcnNlcjsKKyAgICBTY29wZWRVdGZDaGFycyBlbmNvZGluZyhlbnYsIGphdmFFbmNvZGluZyk7CisgICAgaWYgKGVuY29kaW5nLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgaWYgKHByb2Nlc3NOYW1lc3BhY2VzKSB7CisgICAgICAgIC8vIFVzZSAnfCcgdG8gc2VwYXJhdGUgVVJJcyBmcm9tIGxvY2FsIG5hbWVzLgorICAgICAgICBwYXJzZXIgPSBYTUxfUGFyc2VyQ3JlYXRlTlMoZW5jb2RpbmcuY19zdHIoKSwgJ3wnKTsKKyAgICB9IGVsc2UgeworICAgICAgICBwYXJzZXIgPSBYTUxfUGFyc2VyQ3JlYXRlKGVuY29kaW5nLmNfc3RyKCkpOworICAgIH0KKworICAgIGlmIChwYXJzZXIgIT0gTlVMTCkgeworICAgICAgICBpZiAocHJvY2Vzc05hbWVzcGFjZXMpIHsKKyAgICAgICAgICAgIFhNTF9TZXROYW1lc3BhY2VEZWNsSGFuZGxlcihwYXJzZXIsIHN0YXJ0TmFtZXNwYWNlLCBlbmROYW1lc3BhY2UpOworICAgICAgICAgICAgWE1MX1NldFJldHVybk5TVHJpcGxldChwYXJzZXIsIDEpOworICAgICAgICB9CisKKyAgICAgICAgWE1MX1NldENkYXRhU2VjdGlvbkhhbmRsZXIocGFyc2VyLCBzdGFydENkYXRhLCBlbmRDZGF0YSk7CisgICAgICAgIFhNTF9TZXRDaGFyYWN0ZXJEYXRhSGFuZGxlcihwYXJzZXIsIHRleHQpOworICAgICAgICBYTUxfU2V0Q29tbWVudEhhbmRsZXIocGFyc2VyLCBjb21tZW50KTsKKyAgICAgICAgWE1MX1NldERvY3R5cGVEZWNsSGFuZGxlcihwYXJzZXIsIHN0YXJ0RHRkLCBlbmREdGQpOworICAgICAgICBYTUxfU2V0RWxlbWVudEhhbmRsZXIocGFyc2VyLCBzdGFydEVsZW1lbnQsIGVuZEVsZW1lbnQpOworICAgICAgICBYTUxfU2V0RXh0ZXJuYWxFbnRpdHlSZWZIYW5kbGVyKHBhcnNlciwgaGFuZGxlRXh0ZXJuYWxFbnRpdHkpOworICAgICAgICBYTUxfU2V0Tm90YXRpb25EZWNsSGFuZGxlcihwYXJzZXIsIG5vdGF0aW9uRGVjbCk7CisgICAgICAgIFhNTF9TZXRQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25IYW5kbGVyKHBhcnNlciwgcHJvY2Vzc2luZ0luc3RydWN0aW9uKTsKKyAgICAgICAgWE1MX1NldFVucGFyc2VkRW50aXR5RGVjbEhhbmRsZXIocGFyc2VyLCB1bnBhcnNlZEVudGl0eURlY2wpOworICAgICAgICBYTUxfU2V0VXNlckRhdGEocGFyc2VyLCBjb250ZXh0LnJlbGVhc2UoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgam5pVGhyb3dPdXRPZk1lbW9yeUVycm9yKGVudiwgTlVMTCk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHJldHVybiAoamludCkgcGFyc2VyOworfQorCisvKioKKyAqIERlY29kZXMgdGhlIGJ5dGVzIGFzIGNoYXJhY3RlcnMgYW5kIHBhcnNlIHRoZSBjaGFyYWN0ZXJzIGFzIFhNTC4gVGhpcworICogcGVyZm9ybXMgY2hhcmFjdGVyIGRlY29kaW5nIHVzaW5nIHRoZSBjaGFyc2V0IHNwZWNpZmllZCBhdCBYTUxfUGFyc2VyCisgKiBjcmVhdGlvbi4gRm9yIEphdmEgY2hhcnMsIHRoYXQgY2hhcnNldCBtdXN0IGJlIFVURi0xNiBzbyB0aGF0IGEgSmF2YSBjaGFyW10KKyAqIGNhbiBiZSByZWludGVycHJldGVkIGFzIGEgVVRGLTE2IGVuY29kZWQgYnl0ZVtdLiBhcHBlbmRCeXRlcywgYXBwZW5kQ2hhcnMKKyAqIGFuZCBhcHBlbmRTdHJpbmcgYWxsIGNhbGwgdGhyb3VnaCB0aGlzIG1ldGhvZC4KKyAqLworc3RhdGljIHZvaWQgYXBwZW5kKEpOSUVudiogZW52LCBqb2JqZWN0IG9iamVjdCwgamludCBwb2ludGVyLAorICAgICAgICBjb25zdCBjaGFyKiBieXRlcywgc2l6ZV90IGJ5dGVPZmZzZXQsIHNpemVfdCBieXRlQ291bnQsIGpib29sZWFuIGlzRmluYWwpIHsKKyAgICBYTUxfUGFyc2VyIHBhcnNlciA9IChYTUxfUGFyc2VyKSBwb2ludGVyOworICAgIFBhcnNpbmdDb250ZXh0KiBjb250ZXh0ID0gdG9QYXJzaW5nQ29udGV4dChwYXJzZXIpOworICAgIGNvbnRleHQtPmVudiA9IGVudjsKKyAgICBjb250ZXh0LT5vYmplY3QgPSBvYmplY3Q7CisgICAgaWYgKCFYTUxfUGFyc2UocGFyc2VyLCBieXRlcyArIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCwgaXNGaW5hbCkgJiYgIWVudi0+RXhjZXB0aW9uQ2hlY2soKSkgeworICAgICAgICBqbmlUaHJvd0V4cGF0RXhjZXB0aW9uKGVudiwgWE1MX0dldEVycm9yQ29kZShwYXJzZXIpKTsKKyAgICB9CisgICAgY29udGV4dC0+b2JqZWN0ID0gTlVMTDsKKyAgICBjb250ZXh0LT5lbnYgPSBOVUxMOworfQorCitzdGF0aWMgdm9pZCBFeHBhdFBhcnNlcl9hcHBlbmRCeXRlcyhKTklFbnYqIGVudiwgam9iamVjdCBvYmplY3QsIGppbnQgcG9pbnRlciwKKyAgICAgICAgamJ5dGVBcnJheSB4bWwsIGppbnQgYnl0ZU9mZnNldCwgamludCBieXRlQ291bnQpIHsKKyAgICBTY29wZWRCeXRlQXJyYXlSTyBieXRlQXJyYXkoZW52LCB4bWwpOworICAgIGlmIChieXRlQXJyYXkuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgY29uc3QgY2hhciogYnl0ZXMgPSByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPihieXRlQXJyYXkuZ2V0KCkpOworICAgIGFwcGVuZChlbnYsIG9iamVjdCwgcG9pbnRlciwgYnl0ZXMsIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCwgWE1MX0ZBTFNFKTsKK30KKworc3RhdGljIHZvaWQgRXhwYXRQYXJzZXJfYXBwZW5kQ2hhcnMoSk5JRW52KiBlbnYsIGpvYmplY3Qgb2JqZWN0LCBqaW50IHBvaW50ZXIsCisgICAgICAgIGpjaGFyQXJyYXkgeG1sLCBqaW50IGNoYXJPZmZzZXQsIGppbnQgY2hhckNvdW50KSB7CisgICAgU2NvcGVkQ2hhckFycmF5Uk8gY2hhckFycmF5KGVudiwgeG1sKTsKKyAgICBpZiAoY2hhckFycmF5LmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGNvbnN0IGNoYXIqIGJ5dGVzID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4oY2hhckFycmF5LmdldCgpKTsKKyAgICBzaXplX3QgYnl0ZU9mZnNldCA9IDIgKiBjaGFyT2Zmc2V0OworICAgIHNpemVfdCBieXRlQ291bnQgPSAyICogY2hhckNvdW50OworICAgIGFwcGVuZChlbnYsIG9iamVjdCwgcG9pbnRlciwgYnl0ZXMsIGJ5dGVPZmZzZXQsIGJ5dGVDb3VudCwgWE1MX0ZBTFNFKTsKK30KKworc3RhdGljIHZvaWQgRXhwYXRQYXJzZXJfYXBwZW5kU3RyaW5nKEpOSUVudiogZW52LCBqb2JqZWN0IG9iamVjdCwgamludCBwb2ludGVyLCBqc3RyaW5nIGphdmFYbWwsIGpib29sZWFuIGlzRmluYWwpIHsKKyAgICBTY29wZWRTdHJpbmdDaGFycyB4bWwoZW52LCBqYXZhWG1sKTsKKyAgICBpZiAoeG1sLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBjb25zdCBjaGFyKiBieXRlcyA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHhtbC5nZXQoKSk7CisgICAgc2l6ZV90IGJ5dGVDb3VudCA9IDIgKiB4bWwuc2l6ZSgpOworICAgIGFwcGVuZChlbnYsIG9iamVjdCwgcG9pbnRlciwgYnl0ZXMsIDAsIGJ5dGVDb3VudCwgaXNGaW5hbCk7Cit9CisKKy8qKgorICogUmVsZWFzZXMgcGFyc2VyIG9ubHkuCisgKgorICogQHBhcmFtIG9iamVjdCB0aGUgSmF2YSBFeHBhdFBhcnNlciBpbnN0YW5jZQorICogQHBhcmFtIGkgcG9pbnRlciB0byB0aGUgQyBleHBhdCBwYXJzZXIKKyAqLworc3RhdGljIHZvaWQgRXhwYXRQYXJzZXJfcmVsZWFzZVBhcnNlcihKTklFbnYqLCBqb2JqZWN0LCBqaW50IGkpIHsKKyAgICBYTUxfUGFyc2VyIHBhcnNlciA9IChYTUxfUGFyc2VyKSBpOworICAgIFhNTF9QYXJzZXJGcmVlKHBhcnNlcik7Cit9CisKKy8qKgorICogQ2xlYW5zIHVwIGFmdGVyIHRoZSBwYXJzZXIuIENhbGxlZCBhdCBnYXJiYWdlIGNvbGxlY3Rpb24gdGltZS4KKyAqCisgKiBAcGFyYW0gb2JqZWN0IHRoZSBKYXZhIEV4cGF0UGFyc2VyIGluc3RhbmNlCisgKiBAcGFyYW0gaSBwb2ludGVyIHRvIHRoZSBDIGV4cGF0IHBhcnNlcgorICovCitzdGF0aWMgdm9pZCBFeHBhdFBhcnNlcl9yZWxlYXNlKEpOSUVudiogZW52LCBqb2JqZWN0LCBqaW50IGkpIHsKKyAgICBYTUxfUGFyc2VyIHBhcnNlciA9IChYTUxfUGFyc2VyKSBpOworCisgICAgUGFyc2luZ0NvbnRleHQqIGNvbnRleHQgPSB0b1BhcnNpbmdDb250ZXh0KHBhcnNlcik7CisgICAgY29udGV4dC0+ZW52ID0gZW52OworICAgIGRlbGV0ZSBjb250ZXh0OworCisgICAgWE1MX1BhcnNlckZyZWUocGFyc2VyKTsKK30KKworLyoqCisgKiBHZXRzIHRoZSBjdXJyZW50IGxpbmUuCisgKgorICogQHBhcmFtIG9iamVjdCB0aGUgSmF2YSBFeHBhdFBhcnNlciBpbnN0YW5jZQorICogQHBhcmFtIHBvaW50ZXIgdG8gdGhlIEMgZXhwYXQgcGFyc2VyCisgKiBAcmV0dXJucyBjdXJyZW50IGxpbmUgbnVtYmVyCisgKi8KK3N0YXRpYyBpbnQgRXhwYXRQYXJzZXJfbGluZShKTklFbnYqLCBqb2JqZWN0LCBqaW50IHBvaW50ZXIpIHsKKyAgICBYTUxfUGFyc2VyIHBhcnNlciA9IChYTUxfUGFyc2VyKSBwb2ludGVyOworICAgIHJldHVybiBYTUxfR2V0Q3VycmVudExpbmVOdW1iZXIocGFyc2VyKTsKK30KKworLyoqCisgKiBHZXRzIHRoZSBjdXJyZW50IGNvbHVtbi4KKyAqCisgKiBAcGFyYW0gb2JqZWN0IHRoZSBKYXZhIEV4cGF0UGFyc2VyIGluc3RhbmNlCisgKiBAcGFyYW0gcG9pbnRlciB0byB0aGUgQyBleHBhdCBwYXJzZXIKKyAqIEByZXR1cm5zIGN1cnJlbnQgY29sdW1uIG51bWJlcgorICovCitzdGF0aWMgaW50IEV4cGF0UGFyc2VyX2NvbHVtbihKTklFbnYqLCBqb2JqZWN0LCBqaW50IHBvaW50ZXIpIHsKKyAgICBYTUxfUGFyc2VyIHBhcnNlciA9IChYTUxfUGFyc2VyKSBwb2ludGVyOworICAgIHJldHVybiBYTUxfR2V0Q3VycmVudENvbHVtbk51bWJlcihwYXJzZXIpOworfQorCisvKioKKyAqIEdldHMgdGhlIFVSSSBvZiB0aGUgYXR0cmlidXRlIGF0IHRoZSBnaXZlbiBpbmRleC4KKyAqCisgKiBAcGFyYW0gb2JqZWN0IEphdmEgRXhwYXRQYXJzZXIgaW5zdGFuY2UKKyAqIEBwYXJhbSBwb2ludGVyIHRvIHRoZSBDIGV4cGF0IHBhcnNlcgorICogQHBhcmFtIGF0dHJpYnV0ZVBvaW50ZXIgdG8gdGhlIGF0dHJpYnV0ZSBhcnJheQorICogQHBhcmFtIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUKKyAqIEByZXR1cm5zIGludGVybmVkIEphdmEgc3RyaW5nIGNvbnRhaW5pbmcgYXR0cmlidXRlJ3MgVVJJCisgKi8KK3N0YXRpYyBqc3RyaW5nIEV4cGF0QXR0cmlidXRlc19nZXRVUkkoSk5JRW52KiBlbnYsIGpvYmplY3QsIGppbnQgcG9pbnRlciwKKyAgICAgICAgamludCBhdHRyaWJ1dGVQb2ludGVyLCBqaW50IGluZGV4KSB7CisgICAgWE1MX1BhcnNlciBwYXJzZXIgPSAoWE1MX1BhcnNlcikgcG9pbnRlcjsKKyAgICBQYXJzaW5nQ29udGV4dCogY29udGV4dCA9IHRvUGFyc2luZ0NvbnRleHQocGFyc2VyKTsKKyAgICByZXR1cm4gRXhwYXRFbGVtZW50TmFtZShlbnYsIGNvbnRleHQsIGF0dHJpYnV0ZVBvaW50ZXIsIGluZGV4KS51cmkoKTsKK30KKworLyoqCisgKiBHZXRzIHRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgYXQgdGhlIGdpdmVuIGluZGV4LgorICoKKyAqIEBwYXJhbSBvYmplY3QgSmF2YSBFeHBhdFBhcnNlciBpbnN0YW5jZQorICogQHBhcmFtIHBvaW50ZXIgdG8gdGhlIEMgZXhwYXQgcGFyc2VyCisgKiBAcGFyYW0gYXR0cmlidXRlUG9pbnRlciB0byB0aGUgYXR0cmlidXRlIGFycmF5CisgKiBAcGFyYW0gaW5kZXggb2YgdGhlIGF0dHJpYnV0ZQorICogQHJldHVybnMgaW50ZXJuZWQgSmF2YSBzdHJpbmcgY29udGFpbmluZyBhdHRyaWJ1dGUncyBsb2NhbCBuYW1lCisgKi8KK3N0YXRpYyBqc3RyaW5nIEV4cGF0QXR0cmlidXRlc19nZXRMb2NhbE5hbWUoSk5JRW52KiBlbnYsIGpvYmplY3QsIGppbnQgcG9pbnRlciwKKyAgICAgICAgamludCBhdHRyaWJ1dGVQb2ludGVyLCBqaW50IGluZGV4KSB7CisgICAgWE1MX1BhcnNlciBwYXJzZXIgPSAoWE1MX1BhcnNlcikgcG9pbnRlcjsKKyAgICBQYXJzaW5nQ29udGV4dCogY29udGV4dCA9IHRvUGFyc2luZ0NvbnRleHQocGFyc2VyKTsKKyAgICByZXR1cm4gRXhwYXRFbGVtZW50TmFtZShlbnYsIGNvbnRleHQsIGF0dHJpYnV0ZVBvaW50ZXIsIGluZGV4KS5sb2NhbE5hbWUoKTsKK30KKworLyoqCisgKiBHZXRzIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgYXR0cmlidXRlIGF0IHRoZSBnaXZlbiBpbmRleC4KKyAqCisgKiBAcGFyYW0gb2JqZWN0IEphdmEgRXhwYXRQYXJzZXIgaW5zdGFuY2UKKyAqIEBwYXJhbSBwb2ludGVyIHRvIHRoZSBDIGV4cGF0IHBhcnNlcgorICogQHBhcmFtIGF0dHJpYnV0ZVBvaW50ZXIgdG8gdGhlIGF0dHJpYnV0ZSBhcnJheQorICogQHBhcmFtIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUKKyAqIEByZXR1cm5zIGludGVybmVkIEphdmEgc3RyaW5nIGNvbnRhaW5pbmcgYXR0cmlidXRlJ3MgbG9jYWwgbmFtZQorICovCitzdGF0aWMganN0cmluZyBFeHBhdEF0dHJpYnV0ZXNfZ2V0UU5hbWUoSk5JRW52KiBlbnYsIGpvYmplY3QsIGppbnQgcG9pbnRlciwKKyAgICAgICAgamludCBhdHRyaWJ1dGVQb2ludGVyLCBqaW50IGluZGV4KSB7CisgICAgWE1MX1BhcnNlciBwYXJzZXIgPSAoWE1MX1BhcnNlcikgcG9pbnRlcjsKKyAgICBQYXJzaW5nQ29udGV4dCogY29udGV4dCA9IHRvUGFyc2luZ0NvbnRleHQocGFyc2VyKTsKKyAgICByZXR1cm4gRXhwYXRFbGVtZW50TmFtZShlbnYsIGNvbnRleHQsIGF0dHJpYnV0ZVBvaW50ZXIsIGluZGV4KS5xTmFtZSgpOworfQorCisvKioKKyAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgYXQgdGhlIGdpdmVuIGluZGV4LgorICoKKyAqIEBwYXJhbSBvYmplY3QgSmF2YSBFeHBhdFBhcnNlciBpbnN0YW5jZQorICogQHBhcmFtIGF0dHJpYnV0ZVBvaW50ZXIgdG8gdGhlIGF0dHJpYnV0ZSBhcnJheQorICogQHBhcmFtIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUKKyAqIEByZXR1cm5zIEphdmEgc3RyaW5nIGNvbnRhaW5pbmcgYXR0cmlidXRlJ3MgdmFsdWUKKyAqLworc3RhdGljIGpzdHJpbmcgRXhwYXRBdHRyaWJ1dGVzX2dldFZhbHVlQnlJbmRleChKTklFbnYqIGVudiwgam9iamVjdCwKKyAgICAgICAgamludCBhdHRyaWJ1dGVQb2ludGVyLCBqaW50IGluZGV4KSB7CisgICAgY29uc3QgY2hhcioqIGF0dHJpYnV0ZXMgPSB0b0F0dHJpYnV0ZXMoYXR0cmlidXRlUG9pbnRlcik7CisgICAgY29uc3QgY2hhciogdmFsdWUgPSBhdHRyaWJ1dGVzWyhpbmRleCAqIDIpICsgMV07CisgICAgcmV0dXJuIGVudi0+TmV3U3RyaW5nVVRGKHZhbHVlKTsKK30KKworLyoqCisgKiBHZXRzIHRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlIHdpdGggdGhlIGdpdmVuIHF1YWxpZmllZCBuYW1lLgorICoKKyAqIEBwYXJhbSBhdHRyaWJ1dGVQb2ludGVyIHRvIHRoZSBhdHRyaWJ1dGUgYXJyYXkKKyAqIEBwYXJhbSBxTmFtZSB0byBsb29rIGZvcgorICogQHJldHVybnMgaW5kZXggb2YgYXR0cmlidXRlIHdpdGggdGhlIGdpdmVuIHVyaSBhbmQgbG9jYWwgbmFtZSBvciAtMSBpZiBub3QKKyAqICBmb3VuZAorICovCitzdGF0aWMgamludCBFeHBhdEF0dHJpYnV0ZXNfZ2V0SW5kZXhGb3JRTmFtZShKTklFbnYqIGVudiwgam9iamVjdCwKKyAgICAgICAgamludCBhdHRyaWJ1dGVQb2ludGVyLCBqc3RyaW5nIHFOYW1lKSB7CisgICAgU2NvcGVkVXRmQ2hhcnMgcU5hbWVCeXRlcyhlbnYsIHFOYW1lKTsKKyAgICBpZiAocU5hbWVCeXRlcy5jX3N0cigpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIGNvbnN0IGNoYXIqKiBhdHRyaWJ1dGVzID0gdG9BdHRyaWJ1dGVzKGF0dHJpYnV0ZVBvaW50ZXIpOworICAgIGludCBmb3VuZCA9IC0xOworICAgIGZvciAoaW50IGluZGV4ID0gMDsgYXR0cmlidXRlc1tpbmRleCAqIDJdOyArK2luZGV4KSB7CisgICAgICAgIGlmIChFeHBhdEVsZW1lbnROYW1lKE5VTEwsIE5VTEwsIGF0dHJpYnV0ZVBvaW50ZXIsIGluZGV4KS5tYXRjaGVzUU5hbWUocU5hbWVCeXRlcy5jX3N0cigpKSkgeworICAgICAgICAgICAgZm91bmQgPSBpbmRleDsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIGZvdW5kOworfQorCisvKioKKyAqIEdldHMgdGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUgd2l0aCB0aGUgZ2l2ZW4gVVJJIGFuZCBuYW1lLgorICoKKyAqIEBwYXJhbSBhdHRyaWJ1dGVQb2ludGVyIHRvIHRoZSBhdHRyaWJ1dGUgYXJyYXkKKyAqIEBwYXJhbSB1cmkgdG8gbG9vayBmb3IKKyAqIEBwYXJhbSBsb2NhbE5hbWUgdG8gbG9vayBmb3IKKyAqIEByZXR1cm5zIGluZGV4IG9mIGF0dHJpYnV0ZSB3aXRoIHRoZSBnaXZlbiB1cmkgYW5kIGxvY2FsIG5hbWUgb3IgLTEgaWYgbm90CisgKiAgZm91bmQKKyAqLworc3RhdGljIGppbnQgRXhwYXRBdHRyaWJ1dGVzX2dldEluZGV4KEpOSUVudiogZW52LCBqb2JqZWN0LCBqaW50IGF0dHJpYnV0ZVBvaW50ZXIsCisgICAgICAgIGpzdHJpbmcgdXJpLCBqc3RyaW5nIGxvY2FsTmFtZSkgeworICAgIFNjb3BlZFV0ZkNoYXJzIHVyaUJ5dGVzKGVudiwgdXJpKTsKKyAgICBpZiAodXJpQnl0ZXMuY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBTY29wZWRVdGZDaGFycyBsb2NhbE5hbWVCeXRlcyhlbnYsIGxvY2FsTmFtZSk7CisgICAgaWYgKGxvY2FsTmFtZUJ5dGVzLmNfc3RyKCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgY29uc3QgY2hhcioqIGF0dHJpYnV0ZXMgPSB0b0F0dHJpYnV0ZXMoYXR0cmlidXRlUG9pbnRlcik7CisgICAgZm9yIChpbnQgaW5kZXggPSAwOyBhdHRyaWJ1dGVzW2luZGV4ICogMl07ICsraW5kZXgpIHsKKyAgICAgICAgaWYgKEV4cGF0RWxlbWVudE5hbWUoTlVMTCwgTlVMTCwgYXR0cmlidXRlUG9pbnRlciwgaW5kZXgpLm1hdGNoZXModXJpQnl0ZXMuY19zdHIoKSwKKyAgICAgICAgICAgICAgICBsb2NhbE5hbWVCeXRlcy5jX3N0cigpKSkgeworICAgICAgICAgICAgcmV0dXJuIGluZGV4OworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiAtMTsKK30KKworLyoqCisgKiBHZXRzIHRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlIHdpdGggdGhlIGdpdmVuIHF1YWxpZmllZCBuYW1lLgorICoKKyAqIEBwYXJhbSBhdHRyaWJ1dGVQb2ludGVyIHRvIHRoZSBhdHRyaWJ1dGUgYXJyYXkKKyAqIEBwYXJhbSB1cmkgdG8gbG9vayBmb3IKKyAqIEBwYXJhbSBsb2NhbE5hbWUgdG8gbG9vayBmb3IKKyAqIEByZXR1cm5zIHZhbHVlIG9mIGF0dHJpYnV0ZSB3aXRoIHRoZSBnaXZlbiB1cmkgYW5kIGxvY2FsIG5hbWUgb3IgTlVMTCBpZiBub3QKKyAqICBmb3VuZAorICovCitzdGF0aWMganN0cmluZyBFeHBhdEF0dHJpYnV0ZXNfZ2V0VmFsdWVGb3JRTmFtZShKTklFbnYqIGVudiwgam9iamVjdCBjbGF6eiwKKyAgICAgICAgamludCBhdHRyaWJ1dGVQb2ludGVyLCBqc3RyaW5nIHFOYW1lKSB7CisgICAgamludCBpbmRleCA9IEV4cGF0QXR0cmlidXRlc19nZXRJbmRleEZvclFOYW1lKGVudiwgY2xhenosIGF0dHJpYnV0ZVBvaW50ZXIsIHFOYW1lKTsKKyAgICByZXR1cm4gaW5kZXggPT0gLTEgPyBOVUxMCisgICAgICAgICAgICA6IEV4cGF0QXR0cmlidXRlc19nZXRWYWx1ZUJ5SW5kZXgoZW52LCBjbGF6eiwgYXR0cmlidXRlUG9pbnRlciwgaW5kZXgpOworfQorCisvKioKKyAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgd2l0aCB0aGUgZ2l2ZW4gVVJJIGFuZCBuYW1lLgorICoKKyAqIEBwYXJhbSBhdHRyaWJ1dGVQb2ludGVyIHRvIHRoZSBhdHRyaWJ1dGUgYXJyYXkKKyAqIEBwYXJhbSB1cmkgdG8gbG9vayBmb3IKKyAqIEBwYXJhbSBsb2NhbE5hbWUgdG8gbG9vayBmb3IKKyAqIEByZXR1cm5zIHZhbHVlIG9mIGF0dHJpYnV0ZSB3aXRoIHRoZSBnaXZlbiB1cmkgYW5kIGxvY2FsIG5hbWUgb3IgTlVMTCBpZiBub3QKKyAqICBmb3VuZAorICovCitzdGF0aWMganN0cmluZyBFeHBhdEF0dHJpYnV0ZXNfZ2V0VmFsdWUoSk5JRW52KiBlbnYsIGpvYmplY3QgY2xhenosCisgICAgICAgIGppbnQgYXR0cmlidXRlUG9pbnRlciwganN0cmluZyB1cmksIGpzdHJpbmcgbG9jYWxOYW1lKSB7CisgICAgamludCBpbmRleCA9IEV4cGF0QXR0cmlidXRlc19nZXRJbmRleChlbnYsIGNsYXp6LCBhdHRyaWJ1dGVQb2ludGVyLCB1cmksIGxvY2FsTmFtZSk7CisgICAgcmV0dXJuIGluZGV4ID09IC0xID8gTlVMTAorICAgICAgICAgICAgOiBFeHBhdEF0dHJpYnV0ZXNfZ2V0VmFsdWVCeUluZGV4KGVudiwgY2xhenosIGF0dHJpYnV0ZVBvaW50ZXIsIGluZGV4KTsKK30KKworLyoqCisgKiBDbG9uZXMgYW4gYXJyYXkgb2Ygc3RyaW5ncy4gVXNlcyBvbmUgY29udGlndW91cyBibG9jayBvZiBtZW1vcnkgc28gYXMgdG8KKyAqIG1heGltaXplIHBlcmZvcm1hbmNlLgorICoKKyAqIEBwYXJhbSBhZGRyZXNzIGNoYXIqKiB0byBjbG9uZQorICogQHBhcmFtIGNvdW50IG51bWJlciBvZiBhdHRyaWJ1dGVzCisgKi8KK3N0YXRpYyBqaW50IEV4cGF0UGFyc2VyX2Nsb25lQXR0cmlidXRlcyhKTklFbnYqIGVudiwgam9iamVjdCwgamludCBhZGRyZXNzLCBqaW50IGNvdW50KSB7CisgICAgY29uc3QgY2hhcioqIHNvdXJjZSA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcioqPihzdGF0aWNfY2FzdDx1aW50cHRyX3Q+KGFkZHJlc3MpKTsKKyAgICBjb3VudCAqPSAyOworCisgICAgLy8gRmlndXJlIG91dCBob3cgYmlnIHRoZSBidWZmZXIgbmVlZHMgdG8gYmUuCisgICAgaW50IGFycmF5U2l6ZSA9IChjb3VudCArIDEpICogc2l6ZW9mKGNoYXIqKTsKKyAgICBpbnQgdG90YWxTaXplID0gYXJyYXlTaXplOworICAgIGludCBzdHJpbmdMZW5ndGhzW2NvdW50XTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgICAgaW50IGxlbmd0aCA9IHN0cmxlbihzb3VyY2VbaV0pOworICAgICAgICBzdHJpbmdMZW5ndGhzW2ldID0gbGVuZ3RoOworICAgICAgICB0b3RhbFNpemUgKz0gbGVuZ3RoICsgMTsKKyAgICB9CisKKyAgICBjaGFyKiBidWZmZXIgPSBuZXcgY2hhclt0b3RhbFNpemVdOworICAgIGlmIChidWZmZXIgPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd091dE9mTWVtb3J5RXJyb3IoZW52LCBOVUxMKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLy8gQXJyYXkgaXMgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgYnVmZmVyLgorICAgIGNoYXIqKiBjbG9uZWRBcnJheSA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcioqPihidWZmZXIpOworICAgIGNsb25lZEFycmF5W2NvdW50XSA9IE5VTEw7IC8vIG51bGwgdGVybWluYXRlCisKKyAgICAvLyBTdHJpbmcgZGF0YSBmb2xsb3dzIGltbWVkaWF0ZWx5IGFmdGVyLgorICAgIGNoYXIqIGRlc3RpbmF0aW9uU3RyaW5nID0gYnVmZmVyICsgYXJyYXlTaXplOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgeworICAgICAgICBjb25zdCBjaGFyKiBzb3VyY2VTdHJpbmcgPSBzb3VyY2VbaV07CisgICAgICAgIGludCBzdHJpbmdMZW5ndGggPSBzdHJpbmdMZW5ndGhzW2ldOworICAgICAgICBtZW1jcHkoZGVzdGluYXRpb25TdHJpbmcsIHNvdXJjZVN0cmluZywgc3RyaW5nTGVuZ3RoICsgMSk7CisgICAgICAgIGNsb25lZEFycmF5W2ldID0gZGVzdGluYXRpb25TdHJpbmc7CisgICAgICAgIGRlc3RpbmF0aW9uU3RyaW5nICs9IHN0cmluZ0xlbmd0aCArIDE7CisgICAgfQorCisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGppbnQ+KHJlaW50ZXJwcmV0X2Nhc3Q8dWludHB0cl90PihidWZmZXIpKTsKK30KKworLyoqCisgKiBGcmVlcyBjbG9uZWQgYXR0cmlidXRlcy4KKyAqLworc3RhdGljIHZvaWQgRXhwYXRBdHRyaWJ1dGVzX2ZyZWVBdHRyaWJ1dGVzKEpOSUVudiosIGpvYmplY3QsIGppbnQgcG9pbnRlcikgeworICAgIGRlbGV0ZVtdIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KHN0YXRpY19jYXN0PHVpbnRwdHJfdD4ocG9pbnRlcikpOworfQorCisvKioKKyAqIENhbGxlZCB3aGVuIHdlIGluaXRpYWxpemUgb3VyIEphdmEgcGFyc2VyIGNsYXNzLgorICoKKyAqIEBwYXJhbSBjbGF6eiBKYXZhIEV4cGF0UGFyc2VyIGNsYXNzCisgKi8KK3N0YXRpYyB2b2lkIEV4cGF0UGFyc2VyX3N0YXRpY0luaXRpYWxpemUoSk5JRW52KiBlbnYsIGpvYmplY3QgY2xhc3NPYmplY3QsIGpzdHJpbmcgZW1wdHkpIHsKKyAgICBqY2xhc3MgY2xhenogPSByZWludGVycHJldF9jYXN0PGpjbGFzcz4oY2xhc3NPYmplY3QpOworICAgIHN0YXJ0RWxlbWVudE1ldGhvZCA9IGVudi0+R2V0TWV0aG9kSUQoY2xhenosICJzdGFydEVsZW1lbnQiLAorICAgICAgICAiKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nO0lJKVYiKTsKKyAgICBpZiAoc3RhcnRFbGVtZW50TWV0aG9kID09IE5VTEwpIHJldHVybjsKKworICAgIGVuZEVsZW1lbnRNZXRob2QgPSBlbnYtPkdldE1ldGhvZElEKGNsYXp6LCAiZW5kRWxlbWVudCIsCisgICAgICAgICIoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7KVYiKTsKKyAgICBpZiAoZW5kRWxlbWVudE1ldGhvZCA9PSBOVUxMKSByZXR1cm47CisKKyAgICB0ZXh0TWV0aG9kID0gZW52LT5HZXRNZXRob2RJRChjbGF6eiwgInRleHQiLCAiKFtDSSlWIik7CisgICAgaWYgKHRleHRNZXRob2QgPT0gTlVMTCkgcmV0dXJuOworCisgICAgY29tbWVudE1ldGhvZCA9IGVudi0+R2V0TWV0aG9kSUQoY2xhenosICJjb21tZW50IiwgIihbQ0kpViIpOworICAgIGlmIChjb21tZW50TWV0aG9kID09IE5VTEwpIHJldHVybjsKKworICAgIHN0YXJ0Q2RhdGFNZXRob2QgPSBlbnYtPkdldE1ldGhvZElEKGNsYXp6LCAic3RhcnRDZGF0YSIsICIoKVYiKTsKKyAgICBpZiAoc3RhcnRDZGF0YU1ldGhvZCA9PSBOVUxMKSByZXR1cm47CisKKyAgICBlbmRDZGF0YU1ldGhvZCA9IGVudi0+R2V0TWV0aG9kSUQoY2xhenosICJlbmRDZGF0YSIsICIoKVYiKTsKKyAgICBpZiAoZW5kQ2RhdGFNZXRob2QgPT0gTlVMTCkgcmV0dXJuOworCisgICAgc3RhcnREdGRNZXRob2QgPSBlbnYtPkdldE1ldGhvZElEKGNsYXp6LCAic3RhcnREdGQiLAorICAgICAgICAiKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nOylWIik7CisgICAgaWYgKHN0YXJ0RHRkTWV0aG9kID09IE5VTEwpIHJldHVybjsKKworICAgIGVuZER0ZE1ldGhvZCA9IGVudi0+R2V0TWV0aG9kSUQoY2xhenosICJlbmREdGQiLCAiKClWIik7CisgICAgaWYgKGVuZER0ZE1ldGhvZCA9PSBOVUxMKSByZXR1cm47CisKKyAgICBzdGFydE5hbWVzcGFjZU1ldGhvZCA9IGVudi0+R2V0TWV0aG9kSUQoY2xhenosICJzdGFydE5hbWVzcGFjZSIsCisgICAgICAgICIoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7KVYiKTsKKyAgICBpZiAoc3RhcnROYW1lc3BhY2VNZXRob2QgPT0gTlVMTCkgcmV0dXJuOworCisgICAgZW5kTmFtZXNwYWNlTWV0aG9kID0gZW52LT5HZXRNZXRob2RJRChjbGF6eiwgImVuZE5hbWVzcGFjZSIsCisgICAgICAgICIoTGphdmEvbGFuZy9TdHJpbmc7KVYiKTsKKyAgICBpZiAoZW5kTmFtZXNwYWNlTWV0aG9kID09IE5VTEwpIHJldHVybjsKKworICAgIHByb2Nlc3NpbmdJbnN0cnVjdGlvbk1ldGhvZCA9IGVudi0+R2V0TWV0aG9kSUQoY2xhenosCisgICAgICAgICJwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24iLCAiKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nOylWIik7CisgICAgaWYgKHByb2Nlc3NpbmdJbnN0cnVjdGlvbk1ldGhvZCA9PSBOVUxMKSByZXR1cm47CisKKyAgICBoYW5kbGVFeHRlcm5hbEVudGl0eU1ldGhvZCA9IGVudi0+R2V0TWV0aG9kSUQoY2xhenosCisgICAgICAgICJoYW5kbGVFeHRlcm5hbEVudGl0eSIsCisgICAgICAgICIoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7KVYiKTsKKyAgICBpZiAoaGFuZGxlRXh0ZXJuYWxFbnRpdHlNZXRob2QgPT0gTlVMTCkgcmV0dXJuOworCisgICAgbm90YXRpb25EZWNsTWV0aG9kID0gZW52LT5HZXRNZXRob2RJRChjbGF6eiwgIm5vdGF0aW9uRGVjbCIsCisgICAgICAgICAgICAiKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nOylWIik7CisgICAgaWYgKG5vdGF0aW9uRGVjbE1ldGhvZCA9PSBOVUxMKSByZXR1cm47CisKKyAgICB1bnBhcnNlZEVudGl0eURlY2xNZXRob2QgPSBlbnYtPkdldE1ldGhvZElEKGNsYXp6LCAidW5wYXJzZWRFbnRpdHlEZWNsIiwKKyAgICAgICAgICAgICIoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7KVYiKTsKKyAgICBpZiAodW5wYXJzZWRFbnRpdHlEZWNsTWV0aG9kID09IE5VTEwpIHJldHVybjsKKworICAgIGludGVybk1ldGhvZCA9IGVudi0+R2V0TWV0aG9kSUQoSm5pQ29uc3RhbnRzOjpzdHJpbmdDbGFzcywgImludGVybiIsICIoKUxqYXZhL2xhbmcvU3RyaW5nOyIpOworICAgIGlmIChpbnRlcm5NZXRob2QgPT0gTlVMTCkgcmV0dXJuOworCisgICAgLy8gUmVmZXJlbmNlIHRvICIiLgorICAgIGVtcHR5U3RyaW5nID0gKGpzdHJpbmcpIGVudi0+TmV3R2xvYmFsUmVmKGVtcHR5KTsKK30KKworc3RhdGljIEpOSU5hdGl2ZU1ldGhvZCBwYXJzZXJNZXRob2RzW10gPSB7CisgICAgTkFUSVZFX01FVEhPRChFeHBhdFBhcnNlciwgYXBwZW5kU3RyaW5nLCAiKElMamF2YS9sYW5nL1N0cmluZztaKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEV4cGF0UGFyc2VyLCBhcHBlbmRCeXRlcywgIihJW0JJSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChFeHBhdFBhcnNlciwgYXBwZW5kQ2hhcnMsICIoSVtDSUkpViIpLAorICAgIE5BVElWRV9NRVRIT0QoRXhwYXRQYXJzZXIsIGNsb25lQXR0cmlidXRlcywgIihJSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChFeHBhdFBhcnNlciwgY29sdW1uLCAiKEkpSSIpLAorICAgIE5BVElWRV9NRVRIT0QoRXhwYXRQYXJzZXIsIGNyZWF0ZUVudGl0eVBhcnNlciwgIihJTGphdmEvbGFuZy9TdHJpbmc7KUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEV4cGF0UGFyc2VyLCBpbml0aWFsaXplLCAiKExqYXZhL2xhbmcvU3RyaW5nO1opSSIpLAorICAgIE5BVElWRV9NRVRIT0QoRXhwYXRQYXJzZXIsIGxpbmUsICIoSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChFeHBhdFBhcnNlciwgcmVsZWFzZSwgIihJKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEV4cGF0UGFyc2VyLCByZWxlYXNlUGFyc2VyLCAiKEkpViIpLAorICAgIE5BVElWRV9NRVRIT0QoRXhwYXRQYXJzZXIsIHN0YXRpY0luaXRpYWxpemUsICIoTGphdmEvbGFuZy9TdHJpbmc7KVYiKSwKK307CisKK3N0YXRpYyBKTklOYXRpdmVNZXRob2QgYXR0cmlidXRlTWV0aG9kc1tdID0geworICAgIE5BVElWRV9NRVRIT0QoRXhwYXRBdHRyaWJ1dGVzLCBmcmVlQXR0cmlidXRlcywgIihJKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEV4cGF0QXR0cmlidXRlcywgZ2V0SW5kZXhGb3JRTmFtZSwgIihJTGphdmEvbGFuZy9TdHJpbmc7KUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEV4cGF0QXR0cmlidXRlcywgZ2V0SW5kZXgsICIoSUxqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nOylJIiksCisgICAgTkFUSVZFX01FVEhPRChFeHBhdEF0dHJpYnV0ZXMsIGdldExvY2FsTmFtZSwgIihJSUkpTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChFeHBhdEF0dHJpYnV0ZXMsIGdldFFOYW1lLCAiKElJSSlMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEV4cGF0QXR0cmlidXRlcywgZ2V0VVJJLCAiKElJSSlMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKEV4cGF0QXR0cmlidXRlcywgZ2V0VmFsdWVCeUluZGV4LCAiKElJKUxqYXZhL2xhbmcvU3RyaW5nOyIpLAorICAgIE5BVElWRV9NRVRIT0QoRXhwYXRBdHRyaWJ1dGVzLCBnZXRWYWx1ZUZvclFOYW1lLCAiKElMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7IiksCisgICAgTkFUSVZFX01FVEhPRChFeHBhdEF0dHJpYnV0ZXMsIGdldFZhbHVlLCAiKElMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7IiksCit9OworaW50IHJlZ2lzdGVyX29yZ19hcGFjaGVfaGFybW9ueV94bWxfRXhwYXRQYXJzZXIoSk5JRW52KiBlbnYpIHsKKyAgICBpbnQgcmVzdWx0ID0gam5pUmVnaXN0ZXJOYXRpdmVNZXRob2RzKGVudiwgIm9yZy9hcGFjaGUvaGFybW9ueS94bWwvRXhwYXRQYXJzZXIiLAorICAgICAgICBwYXJzZXJNZXRob2RzLCBORUxFTShwYXJzZXJNZXRob2RzKSk7CisgICAgaWYgKHJlc3VsdCAhPSAwKSB7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcmV0dXJuIGpuaVJlZ2lzdGVyTmF0aXZlTWV0aG9kcyhlbnYsICJvcmcvYXBhY2hlL2hhcm1vbnkveG1sL0V4cGF0QXR0cmlidXRlcyIsCisgICAgICAgIGF0dHJpYnV0ZU1ldGhvZHMsIE5FTEVNKGF0dHJpYnV0ZU1ldGhvZHMpKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL29yZ19hcGFjaGVfaGFybW9ueV94bmV0X3Byb3ZpZGVyX2pzc2VfTmF0aXZlQ3J5cHRvLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL29yZ19hcGFjaGVfaGFybW9ueV94bmV0X3Byb3ZpZGVyX2pzc2VfTmF0aXZlQ3J5cHRvLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zODhlYWQ3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvb3JnX2FwYWNoZV9oYXJtb255X3huZXRfcHJvdmlkZXJfanNzZV9OYXRpdmVDcnlwdG8uY3BwCkBAIC0wLDAgKzEsMzIwMiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNy0yMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisgKiBOYXRpdmUgZ2x1ZSBmb3IgSmF2YSBjbGFzcyBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlLk5hdGl2ZUNyeXB0bworICovCisKKyNkZWZpbmUgTE9HX1RBRyAiTmF0aXZlQ3J5cHRvIgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8c3lzL3NvY2tldC5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorCisjaW5jbHVkZSA8am5pLmg+CisKKyNpbmNsdWRlIDxvcGVuc3NsL2RzYS5oPgorI2luY2x1ZGUgPG9wZW5zc2wvZXJyLmg+CisjaW5jbHVkZSA8b3BlbnNzbC9ldnAuaD4KKyNpbmNsdWRlIDxvcGVuc3NsL3JhbmQuaD4KKyNpbmNsdWRlIDxvcGVuc3NsL3JzYS5oPgorI2luY2x1ZGUgPG9wZW5zc2wvc3NsLmg+CisKKyNpbmNsdWRlICJBc3luY2hyb25vdXNTb2NrZXRDbG9zZU1vbml0b3IuaCIKKyNpbmNsdWRlICJKTklIZWxwLmgiCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisjaW5jbHVkZSAiSm5pRXhjZXB0aW9uLmgiCisjaW5jbHVkZSAiTmV0RmQuaCIKKyNpbmNsdWRlICJOZXR3b3JrVXRpbGl0aWVzLmgiCisjaW5jbHVkZSAiU2NvcGVkTG9jYWxSZWYuaCIKKyNpbmNsdWRlICJTY29wZWRQcmltaXRpdmVBcnJheS5oIgorI2luY2x1ZGUgIlNjb3BlZFV0ZkNoYXJzLmgiCisjaW5jbHVkZSAiVW5pcXVlUHRyLmgiCisKKyN1bmRlZiBXSVRIX0pOSV9UUkFDRQorI3VuZGVmIFdJVEhfSk5JX1RSQUNFX0RBVEEKKworI2lmZGVmIFdJVEhfSk5JX1RSQUNFCisjZGVmaW5lIEpOSV9UUkFDRSguLi4pIFwKKyAgICAgICAgKCh2b2lkKUxPRyhMT0dfSU5GTywgTE9HX1RBRyAiLWpuaSIsIF9fVkFfQVJHU19fKSk7ICAgICBcCisvKgorICAgICAgICAoKHZvaWQpcHJpbnRmKCJJLyIgTE9HX1RBRyAiLWpuaToiKSk7ICAgICAgICAgXAorICAgICAgICAoKHZvaWQpcHJpbnRmKF9fVkFfQVJHU19fKSk7ICAgICAgICAgIFwKKyAgICAgICAgKCh2b2lkKXByaW50ZigiXG4iKSkKKyovCisjZWxzZQorI2RlZmluZSBKTklfVFJBQ0UoLi4uKSAoKHZvaWQpMCkKKyNlbmRpZgorLy8gZG9uJ3Qgb3ZlcndoZWxtIGxvZ2NhdAorI2RlZmluZSBXSVRIX0pOSV9UUkFDRV9EQVRBX0NIVU5LX1NJWkUgNTEyCisKK3N0cnVjdCBCSU9fRGVsZXRlIHsKKyAgICB2b2lkIG9wZXJhdG9yKCkoQklPKiBwKSBjb25zdCB7CisgICAgICAgIEJJT19mcmVlKHApOworICAgIH0KK307Cit0eXBlZGVmIFVuaXF1ZVB0cjxCSU8sIEJJT19EZWxldGU+IFVuaXF1ZV9CSU87CisKK3N0cnVjdCBCSUdOVU1fRGVsZXRlIHsKKyAgICB2b2lkIG9wZXJhdG9yKCkoQklHTlVNKiBwKSBjb25zdCB7CisgICAgICAgIEJOX2ZyZWUocCk7CisgICAgfQorfTsKK3R5cGVkZWYgVW5pcXVlUHRyPEJJR05VTSwgQklHTlVNX0RlbGV0ZT4gVW5pcXVlX0JJR05VTTsKKworc3RydWN0IERIX0RlbGV0ZSB7CisgICAgdm9pZCBvcGVyYXRvcigpKERIKiBwKSBjb25zdCB7CisgICAgICAgIERIX2ZyZWUocCk7CisgICAgfQorfTsKK3R5cGVkZWYgVW5pcXVlUHRyPERILCBESF9EZWxldGU+IFVuaXF1ZV9ESDsKKworc3RydWN0IERTQV9EZWxldGUgeworICAgIHZvaWQgb3BlcmF0b3IoKShEU0EqIHApIGNvbnN0IHsKKyAgICAgICAgRFNBX2ZyZWUocCk7CisgICAgfQorfTsKK3R5cGVkZWYgVW5pcXVlUHRyPERTQSwgRFNBX0RlbGV0ZT4gVW5pcXVlX0RTQTsKKworc3RydWN0IEVDX0tFWV9EZWxldGUgeworICAgIHZvaWQgb3BlcmF0b3IoKShFQ19LRVkqIHApIGNvbnN0IHsKKyAgICAgICAgRUNfS0VZX2ZyZWUocCk7CisgICAgfQorfTsKK3R5cGVkZWYgVW5pcXVlUHRyPEVDX0tFWSwgRUNfS0VZX0RlbGV0ZT4gVW5pcXVlX0VDX0tFWTsKKworc3RydWN0IEVWUF9NRF9DVFhfRGVsZXRlIHsKKyAgICB2b2lkIG9wZXJhdG9yKCkoRVZQX01EX0NUWCogcCkgY29uc3QgeworICAgICAgICBFVlBfTURfQ1RYX2Rlc3Ryb3kocCk7CisgICAgfQorfTsKK3R5cGVkZWYgVW5pcXVlUHRyPEVWUF9NRF9DVFgsIEVWUF9NRF9DVFhfRGVsZXRlPiBVbmlxdWVfRVZQX01EX0NUWDsKKworc3RydWN0IEVWUF9QS0VZX0RlbGV0ZSB7CisgICAgdm9pZCBvcGVyYXRvcigpKEVWUF9QS0VZKiBwKSBjb25zdCB7CisgICAgICAgIEVWUF9QS0VZX2ZyZWUocCk7CisgICAgfQorfTsKK3R5cGVkZWYgVW5pcXVlUHRyPEVWUF9QS0VZLCBFVlBfUEtFWV9EZWxldGU+IFVuaXF1ZV9FVlBfUEtFWTsKKworc3RydWN0IFBLQ1M4X1BSSVZfS0VZX0lORk9fRGVsZXRlIHsKKyAgICB2b2lkIG9wZXJhdG9yKCkoUEtDUzhfUFJJVl9LRVlfSU5GTyogcCkgY29uc3QgeworICAgICAgICBQS0NTOF9QUklWX0tFWV9JTkZPX2ZyZWUocCk7CisgICAgfQorfTsKK3R5cGVkZWYgVW5pcXVlUHRyPFBLQ1M4X1BSSVZfS0VZX0lORk8sIFBLQ1M4X1BSSVZfS0VZX0lORk9fRGVsZXRlPiBVbmlxdWVfUEtDUzhfUFJJVl9LRVlfSU5GTzsKKworc3RydWN0IFJTQV9EZWxldGUgeworICAgIHZvaWQgb3BlcmF0b3IoKShSU0EqIHApIGNvbnN0IHsKKyAgICAgICAgUlNBX2ZyZWUocCk7CisgICAgfQorfTsKK3R5cGVkZWYgVW5pcXVlUHRyPFJTQSwgUlNBX0RlbGV0ZT4gVW5pcXVlX1JTQTsKKworc3RydWN0IFNTTF9EZWxldGUgeworICAgIHZvaWQgb3BlcmF0b3IoKShTU0wqIHApIGNvbnN0IHsKKyAgICAgICAgU1NMX2ZyZWUocCk7CisgICAgfQorfTsKK3R5cGVkZWYgVW5pcXVlUHRyPFNTTCwgU1NMX0RlbGV0ZT4gVW5pcXVlX1NTTDsKKworc3RydWN0IFNTTF9DVFhfRGVsZXRlIHsKKyAgICB2b2lkIG9wZXJhdG9yKCkoU1NMX0NUWCogcCkgY29uc3QgeworICAgICAgICBTU0xfQ1RYX2ZyZWUocCk7CisgICAgfQorfTsKK3R5cGVkZWYgVW5pcXVlUHRyPFNTTF9DVFgsIFNTTF9DVFhfRGVsZXRlPiBVbmlxdWVfU1NMX0NUWDsKKworc3RydWN0IFg1MDlfRGVsZXRlIHsKKyAgICB2b2lkIG9wZXJhdG9yKCkoWDUwOSogcCkgY29uc3QgeworICAgICAgICBYNTA5X2ZyZWUocCk7CisgICAgfQorfTsKK3R5cGVkZWYgVW5pcXVlUHRyPFg1MDksIFg1MDlfRGVsZXRlPiBVbmlxdWVfWDUwOTsKKworc3RydWN0IFg1MDlfTkFNRV9EZWxldGUgeworICAgIHZvaWQgb3BlcmF0b3IoKShYNTA5X05BTUUqIHApIGNvbnN0IHsKKyAgICAgICAgWDUwOV9OQU1FX2ZyZWUocCk7CisgICAgfQorfTsKK3R5cGVkZWYgVW5pcXVlUHRyPFg1MDlfTkFNRSwgWDUwOV9OQU1FX0RlbGV0ZT4gVW5pcXVlX1g1MDlfTkFNRTsKKworc3RydWN0IHNrX1NTTF9DSVBIRVJfRGVsZXRlIHsKKyAgICB2b2lkIG9wZXJhdG9yKCkoU1RBQ0tfT0YoU1NMX0NJUEhFUikqIHApIGNvbnN0IHsKKyAgICAgICAgc2tfU1NMX0NJUEhFUl9mcmVlKHApOworICAgIH0KK307Cit0eXBlZGVmIFVuaXF1ZVB0cjxTVEFDS19PRihTU0xfQ0lQSEVSKSwgc2tfU1NMX0NJUEhFUl9EZWxldGU+IFVuaXF1ZV9za19TU0xfQ0lQSEVSOworCitzdHJ1Y3Qgc2tfWDUwOV9EZWxldGUgeworICAgIHZvaWQgb3BlcmF0b3IoKShTVEFDS19PRihYNTA5KSogcCkgY29uc3QgeworICAgICAgICBza19YNTA5X2ZyZWUocCk7CisgICAgfQorfTsKK3R5cGVkZWYgVW5pcXVlUHRyPFNUQUNLX09GKFg1MDkpLCBza19YNTA5X0RlbGV0ZT4gVW5pcXVlX3NrX1g1MDk7CisKK3N0cnVjdCBza19YNTA5X05BTUVfRGVsZXRlIHsKKyAgICB2b2lkIG9wZXJhdG9yKCkoU1RBQ0tfT0YoWDUwOV9OQU1FKSogcCkgY29uc3QgeworICAgICAgICBza19YNTA5X05BTUVfZnJlZShwKTsKKyAgICB9Cit9OwordHlwZWRlZiBVbmlxdWVQdHI8U1RBQ0tfT0YoWDUwOV9OQU1FKSwgc2tfWDUwOV9OQU1FX0RlbGV0ZT4gVW5pcXVlX3NrX1g1MDlfTkFNRTsKKworLyoqCisgKiBNYW55IE9wZW5TU0wgQVBJcyB0YWtlIG93bmVyc2hpcCBvZiBhbiBhcmd1bWVudCBvbiBzdWNjZXNzIGJ1dCBkb24ndCBmcmVlIHRoZSBhcmd1bWVudAorICogb24gZmFpbHVyZS4gVGhpcyBtZWFucyB3ZSBuZWVkIHRvIHRlbGwgb3VyIHNjb3BlZCBwb2ludGVycyB3aGVuIHdlJ3ZlIHRyYW5zZmVycmVkIG93bmVyc2hpcCwKKyAqIHdpdGhvdXQgdHJpZ2dlcmluZyBhIHdhcm5pbmcgYnkgbm90IHVzaW5nIHRoZSByZXN1bHQgb2YgcmVsZWFzZSgpLgorICovCisjZGVmaW5lIE9XTkVSU0hJUF9UUkFOU0ZFUlJFRChvYmopIFwKKyAgICB0eXBlb2YgKG9iai5yZWxlYXNlKCkpIF9kdW1teSBfX2F0dHJpYnV0ZV9fKCh1bnVzZWQpKSA9IG9iai5yZWxlYXNlKCkKKworLyoqCisgKiBGcmVlcyB0aGUgU1NMIGVycm9yIHN0YXRlLgorICoKKyAqIE9wZW5TU0wga2VlcHMgYW4gImVycm9yIHN0YWNrIiBwZXIgdGhyZWFkLCBhbmQgZ2l2ZW4gdGhhdCB0aGlzIGNvZGUKKyAqIGNhbiBiZSBjYWxsZWQgZnJvbSBhcmJpdHJhcnkgdGhyZWFkcyB0aGF0IHdlIGRvbid0IGtlZXAgdHJhY2sgb2YsCisgKiB3ZSBlcnIgb24gdGhlIHNpZGUgb2YgZnJlZWluZyB0aGUgZXJyb3Igc3RhdGUgcHJvbXB0bHkgKGluc3RlYWQgb2YsCisgKiBzYXksIGF0IHRocmVhZCBkZWF0aCkuCisgKi8KK3N0YXRpYyB2b2lkIGZyZWVPcGVuU3NsRXJyb3JTdGF0ZSh2b2lkKSB7CisgICAgRVJSX2NsZWFyX2Vycm9yKCk7CisgICAgRVJSX3JlbW92ZV9zdGF0ZSgwKTsKK30KKworLyoKKyAqIENoZWNrcyB0aGlzIHRocmVhZCdzIE9wZW5TU0wgZXJyb3IgcXVldWUgYW5kIHRocm93cyBhIFJ1bnRpbWVFeGNlcHRpb24gaWYKKyAqIG5lY2Vzc2FyeS4KKyAqCisgKiBAcmV0dXJuIHRydWUgaWYgYW4gZXhjZXB0aW9uIHdhcyB0aHJvd24sIGZhbHNlIGlmIG5vdC4KKyAqLworc3RhdGljIGJvb2wgdGhyb3dFeGNlcHRpb25JZk5lY2Vzc2FyeShKTklFbnYqIGVudiwgY29uc3QgY2hhciogbG9jYXRpb24gIF9fYXR0cmlidXRlX18gKCh1bnVzZWQpKSkgeworICAgIGludCBlcnJvciA9IEVSUl9nZXRfZXJyb3IoKTsKKyAgICBpbnQgcmVzdWx0ID0gZmFsc2U7CisKKyAgICBpZiAoZXJyb3IgIT0gMCkgeworICAgICAgICBjaGFyIG1lc3NhZ2VbMjU2XTsKKyAgICAgICAgRVJSX2Vycm9yX3N0cmluZ19uKGVycm9yLCBtZXNzYWdlLCBzaXplb2YobWVzc2FnZSkpOworICAgICAgICBKTklfVFJBQ0UoIk9wZW5TU0wgZXJyb3IgaW4gJXMgJWQ6ICVzIiwgbG9jYXRpb24sIGVycm9yLCBtZXNzYWdlKTsKKyAgICAgICAgam5pVGhyb3dSdW50aW1lRXhjZXB0aW9uKGVudiwgbWVzc2FnZSk7CisgICAgICAgIHJlc3VsdCA9IHRydWU7CisgICAgfQorCisgICAgZnJlZU9wZW5Tc2xFcnJvclN0YXRlKCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyoqCisgKiBUaHJvd3MgYW4gU29ja2V0VGltZW91dEV4Y2VwdGlvbiB3aXRoIHRoZSBnaXZlbiBzdHJpbmcgYXMgYSBtZXNzYWdlLgorICovCitzdGF0aWMgdm9pZCB0aHJvd1NvY2tldFRpbWVvdXRFeGNlcHRpb24oSk5JRW52KiBlbnYsIGNvbnN0IGNoYXIqIG1lc3NhZ2UpIHsKKyAgICBKTklfVFJBQ0UoInRocm93U29ja2V0VGltZW91dEV4Y2VwdGlvbiAlcyIsIG1lc3NhZ2UpOworICAgIGpuaVRocm93RXhjZXB0aW9uKGVudiwgImphdmEvbmV0L1NvY2tldFRpbWVvdXRFeGNlcHRpb24iLCBtZXNzYWdlKTsKK30KKworLyoqCisgKiBUaHJvd3MgYSBqYXZheC5uZXQuc3NsLlNTTEV4Y2VwdGlvbiB3aXRoIHRoZSBnaXZlbiBzdHJpbmcgYXMgYSBtZXNzYWdlLgorICovCitzdGF0aWMgdm9pZCB0aHJvd1NTTEV4Y2VwdGlvblN0cihKTklFbnYqIGVudiwgY29uc3QgY2hhciogbWVzc2FnZSkgeworICAgIEpOSV9UUkFDRSgidGhyb3dTU0xFeGNlcHRpb25TdHIgJXMiLCBtZXNzYWdlKTsKKyAgICBqbmlUaHJvd0V4Y2VwdGlvbihlbnYsICJqYXZheC9uZXQvc3NsL1NTTEV4Y2VwdGlvbiIsIG1lc3NhZ2UpOworfQorCisvKioKKyAqIFRocm93cyBhIGphdmF4Lm5ldC5zc2wuU1NMUHJvY290b2xFeGNlcHRpb24gd2l0aCB0aGUgZ2l2ZW4gc3RyaW5nIGFzIGEgbWVzc2FnZS4KKyAqLworc3RhdGljIHZvaWQgdGhyb3dTU0xQcm90b2NvbEV4Y2VwdGlvblN0cihKTklFbnYqIGVudiwgY29uc3QgY2hhciogbWVzc2FnZSkgeworICAgIEpOSV9UUkFDRSgidGhyb3dTU0xQcm90b2NvbEV4Y2VwdGlvblN0ciAlcyIsIG1lc3NhZ2UpOworICAgIGpuaVRocm93RXhjZXB0aW9uKGVudiwgImphdmF4L25ldC9zc2wvU1NMUHJvdG9jb2xFeGNlcHRpb24iLCBtZXNzYWdlKTsKK30KKworLyoqCisgKiBUaHJvd3MgYW4gU1NMRXhjZXB0aW9uIHdpdGggYSBtZXNzYWdlIGNvbnN0cnVjdGVkIGZyb20gdGhlIGN1cnJlbnQKKyAqIFNTTCBlcnJvcnMuIFRoaXMgd2lsbCBhbHNvIGxvZyB0aGUgZXJyb3JzLgorICoKKyAqIEBwYXJhbSBlbnYgdGhlIEpOSSBlbnZpcm9ubWVudAorICogQHBhcmFtIHNzbCB0aGUgcG9zc2libHkgTlVMTCBTU0wKKyAqIEBwYXJhbSBzc2xFcnJvckNvZGUgZXJyb3IgY29kZSByZXR1cm5lZCBmcm9tIFNTTF9nZXRfZXJyb3IoKSBvcgorICogU1NMX0VSUk9SX05PTkUgdG8gcHJvYmUgd2l0aCBFUlJfZ2V0X2Vycm9yCisgKiBAcGFyYW0gbWVzc2FnZSBudWxsLW9rOyBnZW5lcmFsIGVycm9yIG1lc3NhZ2UKKyAqLworc3RhdGljIHZvaWQgdGhyb3dTU0xFeGNlcHRpb25XaXRoU3NsRXJyb3JzKAorICAgICAgICBKTklFbnYqIGVudiwgU1NMKiBzc2wsIGludCBzc2xFcnJvckNvZGUsIGNvbnN0IGNoYXIqIG1lc3NhZ2UpIHsKKworICAgIGlmIChtZXNzYWdlID09IE5VTEwpIHsKKyAgICAgICAgbWVzc2FnZSA9ICJTU0wgZXJyb3IiOworICAgIH0KKworICAgIC8vIEZpcnN0IGNvbnN1bHQgdGhlIFNTTCBlcnJvciBjb2RlIGZvciB0aGUgZ2VuZXJhbCBtZXNzYWdlLgorICAgIGNvbnN0IGNoYXIqIHNzbEVycm9yU3RyID0gTlVMTDsKKyAgICBzd2l0Y2ggKHNzbEVycm9yQ29kZSkgeworICAgICAgICBjYXNlIFNTTF9FUlJPUl9OT05FOgorICAgICAgICAgICAgaWYgKEVSUl9wZWVrX2Vycm9yKCkgPT0gMCkgeworICAgICAgICAgICAgICAgIHNzbEVycm9yU3RyID0gIk9LIjsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc3NsRXJyb3JTdHIgPSAiIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFNTTF9FUlJPUl9TU0w6CisgICAgICAgICAgICBzc2xFcnJvclN0ciA9ICJGYWlsdXJlIGluIFNTTCBsaWJyYXJ5LCB1c3VhbGx5IGEgcHJvdG9jb2wgZXJyb3IiOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgU1NMX0VSUk9SX1dBTlRfUkVBRDoKKyAgICAgICAgICAgIHNzbEVycm9yU3RyID0gIlNTTF9FUlJPUl9XQU5UX1JFQUQgb2NjdXJyZWQuIFlvdSBzaG91bGQgbmV2ZXIgc2VlIHRoaXMuIjsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFNTTF9FUlJPUl9XQU5UX1dSSVRFOgorICAgICAgICAgICAgc3NsRXJyb3JTdHIgPSAiU1NMX0VSUk9SX1dBTlRfV1JJVEUgb2NjdXJyZWQuIFlvdSBzaG91bGQgbmV2ZXIgc2VlIHRoaXMuIjsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFNTTF9FUlJPUl9XQU5UX1g1MDlfTE9PS1VQOgorICAgICAgICAgICAgc3NsRXJyb3JTdHIgPSAiU1NMX0VSUk9SX1dBTlRfWDUwOV9MT09LVVAgb2NjdXJyZWQuIFlvdSBzaG91bGQgbmV2ZXIgc2VlIHRoaXMuIjsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFNTTF9FUlJPUl9TWVNDQUxMOgorICAgICAgICAgICAgc3NsRXJyb3JTdHIgPSAiSS9PIGVycm9yIGR1cmluZyBzeXN0ZW0gY2FsbCI7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBTU0xfRVJST1JfWkVST19SRVRVUk46CisgICAgICAgICAgICBzc2xFcnJvclN0ciA9ICJTU0xfRVJST1JfWkVST19SRVRVUk4gb2NjdXJyZWQuIFlvdSBzaG91bGQgbmV2ZXIgc2VlIHRoaXMuIjsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFNTTF9FUlJPUl9XQU5UX0NPTk5FQ1Q6CisgICAgICAgICAgICBzc2xFcnJvclN0ciA9ICJTU0xfRVJST1JfV0FOVF9DT05ORUNUIG9jY3VycmVkLiBZb3Ugc2hvdWxkIG5ldmVyIHNlZSB0aGlzLiI7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBTU0xfRVJST1JfV0FOVF9BQ0NFUFQ6CisgICAgICAgICAgICBzc2xFcnJvclN0ciA9ICJTU0xfRVJST1JfV0FOVF9BQ0NFUFQgb2NjdXJyZWQuIFlvdSBzaG91bGQgbmV2ZXIgc2VlIHRoaXMuIjsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgc3NsRXJyb3JTdHIgPSAiVW5rbm93biBTU0wgZXJyb3IiOworICAgIH0KKworICAgIC8vIFByZXBlbmQgZWl0aGVyIG91ciBleHBsaWNpdCBtZXNzYWdlIG9yIGEgZGVmYXVsdCBvbmUuCisgICAgY2hhciogc3RyOworICAgIGlmIChhc3ByaW50Zigmc3RyLCAiJXM6IHNzbD0lcDogJXMiLCBtZXNzYWdlLCBzc2wsIHNzbEVycm9yU3RyKSA8PSAwKSB7CisgICAgICAgIC8vIHByb2JsZW0gd2l0aCBhc3ByaW50ZiwganVzdCB0aHJvdyBhcmd1bWVudCBtZXNzYWdlLCBsb2cgZXZlcnl0aGluZworICAgICAgICB0aHJvd1NTTEV4Y2VwdGlvblN0cihlbnYsIG1lc3NhZ2UpOworICAgICAgICBMT0dWKCIlczogc3NsPSVwOiAlcyIsIG1lc3NhZ2UsIHNzbCwgc3NsRXJyb3JTdHIpOworICAgICAgICBmcmVlT3BlblNzbEVycm9yU3RhdGUoKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGNoYXIqIGFsbG9jU3RyID0gc3RyOworCisgICAgLy8gRm9yIHByb3RvY29sIGVycm9ycywgU1NMIG1pZ2h0IGhhdmUgbW9yZSBpbmZvcm1hdGlvbi4KKyAgICBpZiAoc3NsRXJyb3JDb2RlID09IFNTTF9FUlJPUl9OT05FIHx8IHNzbEVycm9yQ29kZSA9PSBTU0xfRVJST1JfU1NMKSB7CisgICAgICAgIC8vIEFwcGVuZCBlYWNoIGVycm9yIGFzIGFuIGFkZGl0aW9uYWwgbGluZSB0byB0aGUgbWVzc2FnZS4KKyAgICAgICAgZm9yICg7OykgeworICAgICAgICAgICAgY2hhciBlcnJTdHJbMjU2XTsKKyAgICAgICAgICAgIGNvbnN0IGNoYXIqIGZpbGU7CisgICAgICAgICAgICBpbnQgbGluZTsKKyAgICAgICAgICAgIGNvbnN0IGNoYXIqIGRhdGE7CisgICAgICAgICAgICBpbnQgZmxhZ3M7CisgICAgICAgICAgICB1bnNpZ25lZCBsb25nIGVyciA9IEVSUl9nZXRfZXJyb3JfbGluZV9kYXRhKCZmaWxlLCAmbGluZSwgJmRhdGEsICZmbGFncyk7CisgICAgICAgICAgICBpZiAoZXJyID09IDApIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgRVJSX2Vycm9yX3N0cmluZ19uKGVyciwgZXJyU3RyLCBzaXplb2YoZXJyU3RyKSk7CisKKyAgICAgICAgICAgIGludCByZXQgPSBhc3ByaW50Zigmc3RyLCAiJXNcbiVzICglczolZCAlcDoweCUwOHgpIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYWxsb2NTdHIgPT0gTlVMTCkgPyAiIiA6IGFsbG9jU3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVyclN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZsYWdzICYgRVJSX1RYVF9TVFJJTkcpID8gZGF0YSA6ICIobm8gZGF0YSkiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsYWdzKTsKKworICAgICAgICAgICAgaWYgKHJldCA8IDApIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZnJlZShhbGxvY1N0cik7CisgICAgICAgICAgICBhbGxvY1N0ciA9IHN0cjsKKyAgICAgICAgfQorICAgIC8vIEZvciBlcnJvcnMgZHVyaW5nIHN5c3RlbSBjYWxscywgZXJybm8gbWlnaHQgYmUgb3VyIGZyaWVuZC4KKyAgICB9IGVsc2UgaWYgKHNzbEVycm9yQ29kZSA9PSBTU0xfRVJST1JfU1lTQ0FMTCkgeworICAgICAgICBpZiAoYXNwcmludGYoJnN0ciwgIiVzLCAlcyIsIGFsbG9jU3RyLCBzdHJlcnJvcihlcnJubykpID49IDApIHsKKyAgICAgICAgICAgIGZyZWUoYWxsb2NTdHIpOworICAgICAgICAgICAgYWxsb2NTdHIgPSBzdHI7CisgICAgICAgIH0KKyAgICAvLyBJZiB0aGUgZXJyb3IgY29kZSBpcyBpbnZhbGlkLCBwcmludCBpdC4KKyAgICB9IGVsc2UgaWYgKHNzbEVycm9yQ29kZSA+IFNTTF9FUlJPUl9XQU5UX0FDQ0VQVCkgeworICAgICAgICBpZiAoYXNwcmludGYoJnN0ciwgIiwgZXJyb3IgY29kZSBpcyAlZCIsIHNzbEVycm9yQ29kZSkgPj0gMCkgeworICAgICAgICAgICAgZnJlZShhbGxvY1N0cik7CisgICAgICAgICAgICBhbGxvY1N0ciA9IHN0cjsKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmIChzc2xFcnJvckNvZGUgPT0gU1NMX0VSUk9SX1NTTCkgeworICAgICAgICB0aHJvd1NTTFByb3RvY29sRXhjZXB0aW9uU3RyKGVudiwgYWxsb2NTdHIpOworICAgIH0gZWxzZSB7CisgICAgICAgIHRocm93U1NMRXhjZXB0aW9uU3RyKGVudiwgYWxsb2NTdHIpOworICAgIH0KKworICAgIExPR1YoIiVzIiwgYWxsb2NTdHIpOworICAgIGZyZWUoYWxsb2NTdHIpOworICAgIGZyZWVPcGVuU3NsRXJyb3JTdGF0ZSgpOworfQorCisvKioKKyAqIEhlbHBlciBmdW5jdGlvbiB0aGF0IGdyYWJzIHRoZSBjYXN0cyBhbiBzc2wgcG9pbnRlciBhbmQgdGhlbiBjaGVja3MgZm9yIG51bGxuZXNzLgorICogSWYgdGhpcyBmdW5jdGlvbiByZXR1cm5zIE5VTEwgYW5kIDxjb2RlPnRocm93SWZOdWxsPC9jb2RlPiBpcworICogcGFzc2VkIGFzIDxjb2RlPnRydWU8L2NvZGU+LCB0aGVuIHRoaXMgZnVuY3Rpb24gd2lsbCBjYWxsCisgKiA8Y29kZT50aHJvd1NTTEV4Y2VwdGlvblN0cjwvY29kZT4gYmVmb3JlIHJldHVybmluZywgc28gaW4gdGhpcyBjYXNlIG9mCisgKiBOVUxMLCBhIGNhbGxlciBvZiB0aGlzIGZ1bmN0aW9uIHNob3VsZCBzaW1wbHkgcmV0dXJuIGFuZCBhbGxvdyBKTkkKKyAqIHRvIGRvIGl0cyB0aGluZy4KKyAqCisgKiBAcGFyYW0gZW52IHRoZSBKTkkgZW52aXJvbm1lbnQKKyAqIEBwYXJhbSBzc2xfYWRkcmVzczsgdGhlIHNzbF9hZGRyZXNzIHBvaW50ZXIgYXMgYW4gaW50ZWdlcgorICogQHBhcmFtIHRocm93SWZOdWxsIHdoZXRoZXIgdG8gdGhyb3cgaWYgdGhlIFNTTCBwb2ludGVyIGlzIE5VTEwKKyAqIEByZXR1cm5zIHRoZSBwb2ludGVyLCB3aGljaCBtYXkgYmUgTlVMTAorICovCitzdGF0aWMgU1NMX0NUWCogdG9fU1NMX0NUWChKTklFbnYqIGVudiwgaW50IHNzbF9jdHhfYWRkcmVzcywgYm9vbCB0aHJvd0lmTnVsbCkgeworICAgIFNTTF9DVFgqIHNzbF9jdHggPSByZWludGVycHJldF9jYXN0PFNTTF9DVFgqPihzdGF0aWNfY2FzdDx1aW50cHRyX3Q+KHNzbF9jdHhfYWRkcmVzcykpOworICAgIGlmICgoc3NsX2N0eCA9PSBOVUxMKSAmJiB0aHJvd0lmTnVsbCkgeworICAgICAgICBKTklfVFJBQ0UoInNzbF9jdHggPT0gbnVsbCIpOworICAgICAgICBqbmlUaHJvd051bGxQb2ludGVyRXhjZXB0aW9uKGVudiwgInNzbF9jdHggPT0gbnVsbCIpOworICAgIH0KKyAgICByZXR1cm4gc3NsX2N0eDsKK30KKworc3RhdGljIFNTTCogdG9fU1NMKEpOSUVudiogZW52LCBpbnQgc3NsX2FkZHJlc3MsIGJvb2wgdGhyb3dJZk51bGwpIHsKKyAgICBTU0wqIHNzbCA9IHJlaW50ZXJwcmV0X2Nhc3Q8U1NMKj4oc3RhdGljX2Nhc3Q8dWludHB0cl90Pihzc2xfYWRkcmVzcykpOworICAgIGlmICgoc3NsID09IE5VTEwpICYmIHRocm93SWZOdWxsKSB7CisgICAgICAgIEpOSV9UUkFDRSgic3NsID09IG51bGwiKTsKKyAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsICJzc2wgPT0gbnVsbCIpOworICAgIH0KKyAgICByZXR1cm4gc3NsOworfQorCitzdGF0aWMgU1NMX1NFU1NJT04qIHRvX1NTTF9TRVNTSU9OKEpOSUVudiogZW52LCBpbnQgc3NsX3Nlc3Npb25fYWRkcmVzcywgYm9vbCB0aHJvd0lmTnVsbCkgeworICAgIFNTTF9TRVNTSU9OKiBzc2xfc2Vzc2lvbgorICAgICAgICA9IHJlaW50ZXJwcmV0X2Nhc3Q8U1NMX1NFU1NJT04qPihzdGF0aWNfY2FzdDx1aW50cHRyX3Q+KHNzbF9zZXNzaW9uX2FkZHJlc3MpKTsKKyAgICBpZiAoKHNzbF9zZXNzaW9uID09IE5VTEwpICYmIHRocm93SWZOdWxsKSB7CisgICAgICAgIEpOSV9UUkFDRSgic3NsX3Nlc3Npb24gPT0gbnVsbCIpOworICAgICAgICBqbmlUaHJvd051bGxQb2ludGVyRXhjZXB0aW9uKGVudiwgInNzbF9zZXNzaW9uID09IG51bGwiKTsKKyAgICB9CisgICAgcmV0dXJuIHNzbF9zZXNzaW9uOworfQorCisvKioKKyAqIENvbnZlcnRzIGEgSmF2YSBieXRlW10gdG8gYW4gT3BlblNTTCBCSUdOVU0sIGFsbG9jYXRpbmcgdGhlIEJJR05VTSBvbiB0aGUKKyAqIGZseS4KKyAqLworc3RhdGljIEJJR05VTSogYXJyYXlUb0JpZ251bShKTklFbnYqIGVudiwgamJ5dGVBcnJheSBzb3VyY2UpIHsKKyAgICBKTklfVFJBQ0UoImFycmF5VG9CaWdudW0oJXApIiwgc291cmNlKTsKKworICAgIFNjb3BlZEJ5dGVBcnJheVJPIHNvdXJjZUJ5dGVzKGVudiwgc291cmNlKTsKKyAgICBpZiAoc291cmNlQnl0ZXMuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICBKTklfVFJBQ0UoImFycmF5VG9CaWdudW0oJXApID0+IE5VTEwiLCBzb3VyY2UpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgQklHTlVNKiBibiA9IEJOX2JpbjJibihyZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihzb3VyY2VCeXRlcy5nZXQoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VCeXRlcy5zaXplKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKKyAgICBKTklfVFJBQ0UoImFycmF5VG9CaWdudW0oJXApID0+ICVwIiwgc291cmNlLCBibik7CisgICAgcmV0dXJuIGJuOworfQorCisvKioKKyAqIE9wZW5TU0wgbG9ja2luZyBzdXBwb3J0LiBUYWtlbiBmcm9tIHRoZSBPJ1JlaWxseSBib29rIGJ5IFZpZWdhIGV0IGFsLiwgYnV0IEkKKyAqIHN1cHBvc2UgdGhlcmUgYXJlIG5vdCBtYW55IG90aGVyIHdheXMgdG8gZG8gdGhpcyBvbiBhIExpbnV4IHN5c3RlbSAobW9kdWxvCisgKiBpc29tb3JwaGlzbSkuCisgKi8KKyNkZWZpbmUgTVVURVhfVFlQRSBwdGhyZWFkX211dGV4X3QKKyNkZWZpbmUgTVVURVhfU0VUVVAoeCkgcHRocmVhZF9tdXRleF9pbml0KCYoeCksIE5VTEwpCisjZGVmaW5lIE1VVEVYX0NMRUFOVVAoeCkgcHRocmVhZF9tdXRleF9kZXN0cm95KCYoeCkpCisjZGVmaW5lIE1VVEVYX0xPQ0soeCkgcHRocmVhZF9tdXRleF9sb2NrKCYoeCkpCisjZGVmaW5lIE1VVEVYX1VOTE9DSyh4KSBwdGhyZWFkX211dGV4X3VubG9jaygmKHgpKQorI2RlZmluZSBUSFJFQURfSUQgcHRocmVhZF9zZWxmKCkKKyNkZWZpbmUgVEhST1dfU1NMRVhDRVBUSU9OICgtMikKKyNkZWZpbmUgVEhST1dfU09DS0VUVElNRU9VVEVYQ0VQVElPTiAoLTMpCisjZGVmaW5lIFRIUk9XTl9FWENFUFRJT04gKC00KQorCitzdGF0aWMgTVVURVhfVFlQRSogbXV0ZXhfYnVmID0gTlVMTDsKKworc3RhdGljIHZvaWQgbG9ja2luZ19mdW5jdGlvbihpbnQgbW9kZSwgaW50IG4sIGNvbnN0IGNoYXIqLCBpbnQpIHsKKyAgICBpZiAobW9kZSAmIENSWVBUT19MT0NLKSB7CisgICAgICAgIE1VVEVYX0xPQ0sobXV0ZXhfYnVmW25dKTsKKyAgICB9IGVsc2UgeworICAgICAgICBNVVRFWF9VTkxPQ0sobXV0ZXhfYnVmW25dKTsKKyAgICB9Cit9CisKK3N0YXRpYyB1bnNpZ25lZCBsb25nIGlkX2Z1bmN0aW9uKHZvaWQpIHsKKyAgICByZXR1cm4gKCh1bnNpZ25lZCBsb25nKVRIUkVBRF9JRCk7Cit9CisKK2ludCBUSFJFQURfc2V0dXAodm9pZCkgeworICAgIG11dGV4X2J1ZiA9IG5ldyBNVVRFWF9UWVBFW0NSWVBUT19udW1fbG9ja3MoKV07CisgICAgaWYgKCFtdXRleF9idWYpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBDUllQVE9fbnVtX2xvY2tzKCk7ICsraSkgeworICAgICAgICBNVVRFWF9TRVRVUChtdXRleF9idWZbaV0pOworICAgIH0KKworICAgIENSWVBUT19zZXRfaWRfY2FsbGJhY2soaWRfZnVuY3Rpb24pOworICAgIENSWVBUT19zZXRfbG9ja2luZ19jYWxsYmFjayhsb2NraW5nX2Z1bmN0aW9uKTsKKworICAgIHJldHVybiAxOworfQorCitpbnQgVEhSRUFEX2NsZWFudXAodm9pZCkgeworICAgIGlmICghbXV0ZXhfYnVmKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIENSWVBUT19zZXRfaWRfY2FsbGJhY2soTlVMTCk7CisgICAgQ1JZUFRPX3NldF9sb2NraW5nX2NhbGxiYWNrKE5VTEwpOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBDUllQVE9fbnVtX2xvY2tzKCApOyBpKyspIHsKKyAgICAgICAgTVVURVhfQ0xFQU5VUChtdXRleF9idWZbaV0pOworICAgIH0KKworICAgIGZyZWUobXV0ZXhfYnVmKTsKKyAgICBtdXRleF9idWYgPSBOVUxMOworCisgICAgcmV0dXJuIDE7Cit9CisKKy8qKgorICogSW5pdGlhbGl6YXRpb24gcGhhc2UgZm9yIGV2ZXJ5IE9wZW5TU0wgam9iOiBMb2FkcyB0aGUgRXJyb3Igc3RyaW5ncywgdGhlCisgKiBjcnlwdG8gYWxnb3JpdGhtcyBhbmQgcmVzZXQgdGhlIE9wZW5TU0wgbGlicmFyeQorICovCitzdGF0aWMgdm9pZCBOYXRpdmVDcnlwdG9fY2xpbml0KEpOSUVudiosIGpjbGFzcykKK3sKKyAgICBTU0xfbG9hZF9lcnJvcl9zdHJpbmdzKCk7CisgICAgRVJSX2xvYWRfY3J5cHRvX3N0cmluZ3MoKTsKKyAgICBTU0xfbGlicmFyeV9pbml0KCk7CisgICAgT3BlblNTTF9hZGRfYWxsX2FsZ29yaXRobXMoKTsKKyAgICBUSFJFQURfc2V0dXAoKTsKK30KKworLyoqCisgKiBwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgRVZQX1BLRVlfbmV3X0RTQShieXRlW10gcCwgYnl0ZVtdIHEsIGJ5dGVbXSBnLAorICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIHB1Yl9rZXksIGJ5dGVbXSBwcml2X2tleSk7CisgKi8KK3N0YXRpYyBFVlBfUEtFWSogTmF0aXZlQ3J5cHRvX0VWUF9QS0VZX25ld19EU0EoSk5JRW52KiBlbnYsIGpjbGFzcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamJ5dGVBcnJheSBwLCBqYnl0ZUFycmF5IHEsIGpieXRlQXJyYXkgZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamJ5dGVBcnJheSBwdWJfa2V5LCBqYnl0ZUFycmF5IHByaXZfa2V5KSB7CisgICAgSk5JX1RSQUNFKCJFVlBfUEtFWV9uZXdfRFNBKHA9JXAsIHE9JXAsIGc9JXAsIHB1Yl9rZXk9JXAsIHByaXZfa2V5PSVwKSIsCisgICAgICAgICAgICAgIHAsIHEsIGcsIHB1Yl9rZXksIHByaXZfa2V5KTsKKworICAgIFVuaXF1ZV9EU0EgZHNhKERTQV9uZXcoKSk7CisgICAgaWYgKGRzYS5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIGpuaVRocm93UnVudGltZUV4Y2VwdGlvbihlbnYsICJEU0FfbmV3IGZhaWxlZCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBkc2EtPnAgPSBhcnJheVRvQmlnbnVtKGVudiwgcCk7CisgICAgZHNhLT5xID0gYXJyYXlUb0JpZ251bShlbnYsIHEpOworICAgIGRzYS0+ZyA9IGFycmF5VG9CaWdudW0oZW52LCBnKTsKKyAgICBkc2EtPnB1Yl9rZXkgPSBhcnJheVRvQmlnbnVtKGVudiwgcHViX2tleSk7CisKKyAgICBpZiAocHJpdl9rZXkgIT0gTlVMTCkgeworICAgICAgICBkc2EtPnByaXZfa2V5ID0gYXJyYXlUb0JpZ251bShlbnYsIHByaXZfa2V5KTsKKyAgICB9CisKKyAgICBpZiAoZHNhLT5wID09IE5VTEwgfHwgZHNhLT5xID09IE5VTEwgfHwgZHNhLT5nID09IE5VTEwgfHwgZHNhLT5wdWJfa2V5ID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dSdW50aW1lRXhjZXB0aW9uKGVudiwgIlVuYWJsZSB0byBjb252ZXJ0IEJpZ0ludGVnZXIgdG8gQklHTlVNIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIFVuaXF1ZV9FVlBfUEtFWSBwa2V5KEVWUF9QS0VZX25ldygpKTsKKyAgICBpZiAocGtleS5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIGpuaVRocm93UnVudGltZUV4Y2VwdGlvbihlbnYsICJFVlBfUEtFWV9uZXcgZmFpbGVkIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoRVZQX1BLRVlfYXNzaWduX0RTQShwa2V5LmdldCgpLCBkc2EuZ2V0KCkpICE9IDEpIHsKKyAgICAgICAgam5pVGhyb3dSdW50aW1lRXhjZXB0aW9uKGVudiwgIkVWUF9QS0VZX2Fzc2lnbl9EU0EgZmFpbGVkIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBPV05FUlNISVBfVFJBTlNGRVJSRUQoZHNhKTsKKyAgICBKTklfVFJBQ0UoIkVWUF9QS0VZX25ld19EU0EocD0lcCwgcT0lcCwgZz0lcCwgcHViX2tleT0lcCwgcHJpdl9rZXk9JXApID0+ICVwIiwKKyAgICAgICAgICAgICAgcCwgcSwgZywgcHViX2tleSwgcHJpdl9rZXksIHBrZXkuZ2V0KCkpOworICAgIHJldHVybiBwa2V5LnJlbGVhc2UoKTsKK30KKworLyoqCisgKiBwcml2YXRlIHN0YXRpYyBuYXRpdmUgaW50IEVWUF9QS0VZX25ld19SU0EoYnl0ZVtdIG4sIGJ5dGVbXSBlLCBieXRlW10gZCwgYnl0ZVtdIHAsIGJ5dGVbXSBxKTsKKyAqLworc3RhdGljIEVWUF9QS0VZKiBOYXRpdmVDcnlwdG9fRVZQX1BLRVlfbmV3X1JTQShKTklFbnYqIGVudiwgamNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqYnl0ZUFycmF5IG4sIGpieXRlQXJyYXkgZSwgamJ5dGVBcnJheSBkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqYnl0ZUFycmF5IHAsIGpieXRlQXJyYXkgcSkgeworICAgIEpOSV9UUkFDRSgiRVZQX1BLRVlfbmV3X1JTQShuPSVwLCBlPSVwLCBkPSVwLCBwPSVwLCBxPSVwKSIsIG4sIGUsIGQsIHAsIHEpOworCisgICAgVW5pcXVlX1JTQSByc2EoUlNBX25ldygpKTsKKyAgICBpZiAocnNhLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dSdW50aW1lRXhjZXB0aW9uKGVudiwgIlJTQV9uZXcgZmFpbGVkIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHJzYS0+biA9IGFycmF5VG9CaWdudW0oZW52LCBuKTsKKyAgICByc2EtPmUgPSBhcnJheVRvQmlnbnVtKGVudiwgZSk7CisKKyAgICBpZiAoZCAhPSBOVUxMKSB7CisgICAgICAgIHJzYS0+ZCA9IGFycmF5VG9CaWdudW0oZW52LCBkKTsKKyAgICB9CisKKyAgICBpZiAocCAhPSBOVUxMKSB7CisgICAgICAgIHJzYS0+cCA9IGFycmF5VG9CaWdudW0oZW52LCBwKTsKKyAgICB9CisKKyAgICBpZiAocSAhPSBOVUxMKSB7CisgICAgICAgIHJzYS0+cSA9IGFycmF5VG9CaWdudW0oZW52LCBxKTsKKyAgICB9CisKKyNpZmRlZiBXSVRIX0pOSV9UUkFDRQorICAgIGlmIChwICE9IE5VTEwgJiYgcSAhPSBOVUxMKSB7CisgICAgICAgIGludCBjaGVjayA9IFJTQV9jaGVja19rZXkocnNhLmdldCgpKTsKKyAgICAgICAgSk5JX1RSQUNFKCJFVlBfUEtFWV9uZXdfUlNBKC4uLikgUlNBX2NoZWNrX2tleSByZXR1cm5zICVkIiwgY2hlY2spOworICAgIH0KKyNlbmRpZgorCisgICAgaWYgKHJzYS0+biA9PSBOVUxMIHx8IHJzYS0+ZSA9PSBOVUxMKSB7CisgICAgICAgIGpuaVRocm93UnVudGltZUV4Y2VwdGlvbihlbnYsICJVbmFibGUgdG8gY29udmVydCBCaWdJbnRlZ2VyIHRvIEJJR05VTSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBVbmlxdWVfRVZQX1BLRVkgcGtleShFVlBfUEtFWV9uZXcoKSk7CisgICAgaWYgKHBrZXkuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd1J1bnRpbWVFeGNlcHRpb24oZW52LCAiRVZQX1BLRVlfbmV3IGZhaWxlZCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKEVWUF9QS0VZX2Fzc2lnbl9SU0EocGtleS5nZXQoKSwgcnNhLmdldCgpKSAhPSAxKSB7CisgICAgICAgIGpuaVRocm93UnVudGltZUV4Y2VwdGlvbihlbnYsICJFVlBfUEtFWV9uZXcgZmFpbGVkIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBPV05FUlNISVBfVFJBTlNGRVJSRUQocnNhKTsKKyAgICBKTklfVFJBQ0UoIkVWUF9QS0VZX25ld19SU0Eobj0lcCwgZT0lcCwgZD0lcCwgcD0lcCwgcT0lcCkgPT4gJXAiLCBuLCBlLCBkLCBwLCBxLCBwa2V5LmdldCgpKTsKKyAgICByZXR1cm4gcGtleS5yZWxlYXNlKCk7Cit9CisKKy8qKgorICogcHJpdmF0ZSBzdGF0aWMgbmF0aXZlIHZvaWQgRVZQX1BLRVlfZnJlZShpbnQgcGtleSk7CisgKi8KK3N0YXRpYyB2b2lkIE5hdGl2ZUNyeXB0b19FVlBfUEtFWV9mcmVlKEpOSUVudiosIGpjbGFzcywgRVZQX1BLRVkqIHBrZXkpIHsKKyAgICBKTklfVFJBQ0UoIkVWUF9QS0VZX2ZyZWUoJXApIiwgcGtleSk7CisKKyAgICBpZiAocGtleSAhPSBOVUxMKSB7CisgICAgICAgIEVWUF9QS0VZX2ZyZWUocGtleSk7CisgICAgfQorfQorCisvKgorICogcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBFVlBfTURfQ1RYX2Rlc3Ryb3koaW50KQorICovCitzdGF0aWMgdm9pZCBOYXRpdmVDcnlwdG9fRVZQX01EX0NUWF9kZXN0cm95KEpOSUVudiosIGpjbGFzcywgRVZQX01EX0NUWCogY3R4KSB7CisgICAgSk5JX1RSQUNFKCJOYXRpdmVDcnlwdG9fRVZQX01EX0NUWF9kZXN0cm95KCVwKSIsIGN0eCk7CisKKyAgICBpZiAoY3R4ICE9IE5VTEwpIHsKKyAgICAgICAgRVZQX01EX0NUWF9kZXN0cm95KGN0eCk7CisgICAgfQorfQorCisvKgorICogcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEVWUF9NRF9DVFhfY29weShpbnQpCisgKi8KK3N0YXRpYyBqaW50IE5hdGl2ZUNyeXB0b19FVlBfTURfQ1RYX2NvcHkoSk5JRW52KiBlbnYsIGpjbGFzcywgRVZQX01EX0NUWCogY3R4KSB7CisgICAgSk5JX1RSQUNFKCJOYXRpdmVDcnlwdG9fRVZQX01EX0NUWF9jb3B5KCVwKSIsIGN0eCk7CisKKyAgICBpZiAoY3R4ID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsIE5VTEwpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgRVZQX01EX0NUWCogY29weSA9IEVWUF9NRF9DVFhfY3JlYXRlKCk7CisgICAgaWYgKGNvcHkgPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd091dE9mTWVtb3J5RXJyb3IoZW52LCAiVW5hYmxlIHRvIGFsbG9jYXRlIGNvcHkgb2YgRVZQX01EX0NUWCIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgRVZQX01EX0NUWF9pbml0KGNvcHkpOworICAgIGludCByZXN1bHQgPSBFVlBfTURfQ1RYX2NvcHlfZXgoY29weSwgY3R4KTsKKyAgICBpZiAocmVzdWx0ID09IDApIHsKKyAgICAgICAgRVZQX01EX0NUWF9kZXN0cm95KGNvcHkpOworICAgICAgICBqbmlUaHJvd1J1bnRpbWVFeGNlcHRpb24oZW52LCAiVW5hYmxlIHRvIGNvcHkgRVZQX01EX0NUWCIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgSk5JX1RSQUNFKCJOYXRpdmVDcnlwdG9fRVZQX01EX0NUWF9jb3B5KCVwKSA9PiAlcCIsIGN0eCwgY29weSk7CisgICAgcmV0dXJuIChqaW50KSBjb3B5OworfQorCisvKgorICogcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEVWUF9EaWdlc3RGaW5hbChpbnQsIGJ5dGVbXSwgaW50KQorICovCitzdGF0aWMgamludCBOYXRpdmVDcnlwdG9fRVZQX0RpZ2VzdEZpbmFsKEpOSUVudiogZW52LCBqY2xhc3MsIEVWUF9NRF9DVFgqIGN0eCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamJ5dGVBcnJheSBoYXNoLCBqaW50IG9mZnNldCkgeworICAgIEpOSV9UUkFDRSgiTmF0aXZlQ3J5cHRvX0VWUF9EaWdlc3RGaW5hbCglcCwgJXAsICVkKSIsIGN0eCwgaGFzaCwgb2Zmc2V0KTsKKworICAgIGlmIChjdHggPT0gTlVMTCB8fCBoYXNoID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsIE5VTEwpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgU2NvcGVkQnl0ZUFycmF5UlcgaGFzaEJ5dGVzKGVudiwgaGFzaCk7CisgICAgaWYgKGhhc2hCeXRlcy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgdW5zaWduZWQgaW50IGJ5dGVzV3JpdHRlbiA9IC0xOworICAgIGludCBvayA9IEVWUF9EaWdlc3RGaW5hbChjdHgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dW5zaWduZWQgY2hhcio+KGhhc2hCeXRlcy5nZXQoKSArIG9mZnNldCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZieXRlc1dyaXR0ZW4pOworICAgIGlmIChvayA9PSAwKSB7CisgICAgICAgIHRocm93RXhjZXB0aW9uSWZOZWNlc3NhcnkoZW52LCAiTmF0aXZlQ3J5cHRvX0VWUF9EaWdlc3RGaW5hbCIpOworICAgIH0KKyAgICBFVlBfTURfQ1RYX2Rlc3Ryb3koY3R4KTsKKworICAgIEpOSV9UUkFDRSgiTmF0aXZlQ3J5cHRvX0VWUF9EaWdlc3RGaW5hbCglcCwgJXAsICVkKSA9PiAlZCIsIGN0eCwgaGFzaCwgb2Zmc2V0LCBieXRlc1dyaXR0ZW4pOworICAgIHJldHVybiBieXRlc1dyaXR0ZW47Cit9CisKKy8qCisgKiBwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgRVZQX0RpZ2VzdEluaXQoaW50KQorICovCitzdGF0aWMgaW50IE5hdGl2ZUNyeXB0b19FVlBfRGlnZXN0SW5pdChKTklFbnYqIGVudiwgamNsYXNzLCBFVlBfTUQqIGV2cF9tZCkgeworICAgIEpOSV9UUkFDRSgiTmF0aXZlQ3J5cHRvX0VWUF9EaWdlc3RJbml0KCVwKSIsIGV2cF9tZCk7CisKKyAgICBpZiAoZXZwX21kID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsIE5VTEwpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBVbmlxdWVfRVZQX01EX0NUWCBjdHgoRVZQX01EX0NUWF9jcmVhdGUoKSk7CisgICAgaWYgKGN0eC5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIGpuaVRocm93T3V0T2ZNZW1vcnlFcnJvcihlbnYsICJVbmFibGUgdG8gYWxsb2NhdGUgRVZQX01EX0NUWCIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgSk5JX1RSQUNFKCJOYXRpdmVDcnlwdG9fRVZQX0RpZ2VzdEluaXQgY3R4PSVwIiwgY3R4LmdldCgpKTsKKworICAgIGludCBvayA9IEVWUF9EaWdlc3RJbml0KGN0eC5nZXQoKSwgZXZwX21kKTsKKyAgICBpZiAob2sgPT0gMCkgeworICAgICAgICBib29sIGV4Y2VwdGlvbiA9IHRocm93RXhjZXB0aW9uSWZOZWNlc3NhcnkoZW52LCAiTmF0aXZlQ3J5cHRvX0VWUF9EaWdlc3RJbml0Iik7CisgICAgICAgIGlmIChleGNlcHRpb24pIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiAoamludCkgY3R4LnJlbGVhc2UoKTsKK30KKworLyoKKyAqIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBFVlBfZ2V0X2RpZ2VzdGJ5bmFtZShqYXZhLmxhbmcuU3RyaW5nKQorICovCitzdGF0aWMgamludCBOYXRpdmVDcnlwdG9fRVZQX2dldF9kaWdlc3RieW5hbWUoSk5JRW52KiBlbnYsIGpjbGFzcywganN0cmluZyBhbGdvcml0aG0pIHsKKyAgICBKTklfVFJBQ0UoIk5hdGl2ZUNyeXB0b19FVlBfZ2V0X2RpZ2VzdGJ5bmFtZSglcCkiLCBhbGdvcml0aG0pOworCisgICAgaWYgKGFsZ29yaXRobSA9PSBOVUxMKSB7CisgICAgICAgIGpuaVRocm93TnVsbFBvaW50ZXJFeGNlcHRpb24oZW52LCBOVUxMKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIFNjb3BlZFV0ZkNoYXJzIGFsZ29yaXRobUNoYXJzKGVudiwgYWxnb3JpdGhtKTsKKyAgICBpZiAoYWxnb3JpdGhtQ2hhcnMuY19zdHIoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBKTklfVFJBQ0UoIk5hdGl2ZUNyeXB0b19FVlBfZ2V0X2RpZ2VzdGJ5bmFtZSglcykiLCBhbGdvcml0aG1DaGFycy5jX3N0cigpKTsKKworICAgIGNvbnN0IEVWUF9NRCogZXZwX21kID0gRVZQX2dldF9kaWdlc3RieW5hbWUoYWxnb3JpdGhtQ2hhcnMuY19zdHIoKSk7CisgICAgaWYgKGV2cF9tZCA9PSBOVUxMKSB7CisgICAgICAgIGpuaVRocm93UnVudGltZUV4Y2VwdGlvbihlbnYsICJIYXNoIGFsZ29yaXRobSBub3QgZm91bmQiKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgSk5JX1RSQUNFKCJOYXRpdmVDcnlwdG9fRVZQX2dldF9kaWdlc3RieW5hbWUoJXMpID0+ICVwIiwgYWxnb3JpdGhtQ2hhcnMuY19zdHIoKSwgZXZwX21kKTsKKyAgICByZXR1cm4gKGppbnQpIGV2cF9tZDsKK30KKworLyoKKyAqIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBFVlBfTURfc2l6ZShpbnQpCisgKi8KK3N0YXRpYyBqaW50IE5hdGl2ZUNyeXB0b19FVlBfTURfc2l6ZShKTklFbnYqIGVudiwgamNsYXNzLCBFVlBfTUQqIGV2cF9tZCkgeworICAgIEpOSV9UUkFDRSgiTmF0aXZlQ3J5cHRvX0VWUF9NRF9zaXplKCVwKSIsIGV2cF9tZCk7CisKKyAgICBpZiAoZXZwX21kID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsIE5VTEwpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgaW50IHJlc3VsdCA9IEVWUF9NRF9zaXplKGV2cF9tZCk7CisgICAgSk5JX1RSQUNFKCJOYXRpdmVDcnlwdG9fRVZQX01EX3NpemUoJXApID0+ICVkIiwgZXZwX21kLCByZXN1bHQpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qCisgKiBwdWJsaWMgc3RhdGljIGludCB2b2lkIEVWUF9NRF9ibG9ja19zaXplKGludCkKKyAqLworc3RhdGljIGppbnQgTmF0aXZlQ3J5cHRvX0VWUF9NRF9ibG9ja19zaXplKEpOSUVudiogZW52LCBqY2xhc3MsIEVWUF9NRCogZXZwX21kKSB7CisgICAgSk5JX1RSQUNFKCJOYXRpdmVDcnlwdG9fRVZQX01EX2Jsb2NrX3NpemUoJXApIiwgZXZwX21kKTsKKworICAgIGlmIChldnBfbWQgPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd051bGxQb2ludGVyRXhjZXB0aW9uKGVudiwgTlVMTCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpbnQgcmVzdWx0ID0gRVZQX01EX2Jsb2NrX3NpemUoZXZwX21kKTsKKyAgICBKTklfVFJBQ0UoIk5hdGl2ZUNyeXB0b19FVlBfTURfYmxvY2tfc2l6ZSglcCkgPT4gJWQiLCBldnBfbWQsIHJlc3VsdCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyoKKyAqIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgRVZQX0RpZ2VzdFVwZGF0ZShpbnQsIGJ5dGVbXSwgaW50LCBpbnQpCisgKi8KK3N0YXRpYyB2b2lkIE5hdGl2ZUNyeXB0b19FVlBfRGlnZXN0VXBkYXRlKEpOSUVudiogZW52LCBqY2xhc3MsIEVWUF9NRF9DVFgqIGN0eCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpieXRlQXJyYXkgYnVmZmVyLCBqaW50IG9mZnNldCwgamludCBsZW5ndGgpIHsKKyAgICBKTklfVFJBQ0UoIk5hdGl2ZUNyeXB0b19FVlBfRGlnZXN0VXBkYXRlKCVwLCAlcCwgJWQsICVkKSIsIGN0eCwgYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7CisKKyAgICBpZiAob2Zmc2V0IDwgMCB8fCBsZW5ndGggPCAwKSB7CisgICAgICAgIGpuaVRocm93RXhjZXB0aW9uKGVudiwgImphdmEvbGFuZy9JbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIiwgTlVMTCk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAoY3R4ID09IE5VTEwgfHwgYnVmZmVyID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsIE5VTEwpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgU2NvcGVkQnl0ZUFycmF5Uk8gYnVmZmVyQnl0ZXMoZW52LCBidWZmZXIpOworICAgIGlmIChidWZmZXJCeXRlcy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaW50IG9rID0gRVZQX0RpZ2VzdFVwZGF0ZShjdHgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihidWZmZXJCeXRlcy5nZXQoKSArIG9mZnNldCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGgpOworICAgIGlmIChvayA9PSAwKSB7CisgICAgICAgIHRocm93RXhjZXB0aW9uSWZOZWNlc3NhcnkoZW52LCAiTmF0aXZlQ3J5cHRvX0VWUF9EaWdlc3RVcGRhdGUiKTsKKyAgICB9Cit9CisKKy8qCisgKiBwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgRVZQX1ZlcmlmeUluaXQoamF2YS5sYW5nLlN0cmluZykKKyAqLworc3RhdGljIGppbnQgTmF0aXZlQ3J5cHRvX0VWUF9WZXJpZnlJbml0KEpOSUVudiogZW52LCBqY2xhc3MsIGpzdHJpbmcgYWxnb3JpdGhtKSB7CisgICAgSk5JX1RSQUNFKCJOYXRpdmVDcnlwdG9fRVZQX1ZlcmlmeUluaXQoJXApIiwgYWxnb3JpdGhtKTsKKworICAgIGlmIChhbGdvcml0aG0gPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd051bGxQb2ludGVyRXhjZXB0aW9uKGVudiwgTlVMTCk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIFVuaXF1ZV9FVlBfTURfQ1RYIGN0eChFVlBfTURfQ1RYX2NyZWF0ZSgpKTsKKyAgICBpZiAoY3R4LmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dPdXRPZk1lbW9yeUVycm9yKGVudiwgIlVuYWJsZSB0byBhbGxvY2F0ZSBFVlBfTURfQ1RYIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBKTklfVFJBQ0UoIk5hdGl2ZUNyeXB0b19FVlBfVmVyaWZ5SW5pdCBjdHg9JXAiLCBjdHguZ2V0KCkpOworCisgICAgU2NvcGVkVXRmQ2hhcnMgYWxnb3JpdGhtQ2hhcnMoZW52LCBhbGdvcml0aG0pOworICAgIGlmIChhbGdvcml0aG1DaGFycy5jX3N0cigpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIEpOSV9UUkFDRSgiTmF0aXZlQ3J5cHRvX0VWUF9WZXJpZnlJbml0IGFsZ29yaXRobUNoYXJzPSVzIiwgYWxnb3JpdGhtQ2hhcnMuY19zdHIoKSk7CisKKyAgICBjb25zdCBFVlBfTUQqIGRpZ2VzdCA9IEVWUF9nZXRfZGlnZXN0YnluaWQoT0JKX3R4dDJuaWQoYWxnb3JpdGhtQ2hhcnMuY19zdHIoKSkpOworICAgIGlmIChkaWdlc3QgPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd1J1bnRpbWVFeGNlcHRpb24oZW52LCAiSGFzaCBhbGdvcml0aG0gbm90IGZvdW5kIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGludCBvayA9IEVWUF9WZXJpZnlJbml0KGN0eC5nZXQoKSwgZGlnZXN0KTsKKyAgICBpZiAob2sgPT0gMCkgeworICAgICAgICBib29sIGV4Y2VwdGlvbiA9IHRocm93RXhjZXB0aW9uSWZOZWNlc3NhcnkoZW52LCAiTmF0aXZlQ3J5cHRvX0VWUF9WZXJpZnlJbml0Iik7CisgICAgICAgIGlmIChleGNlcHRpb24pIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiAoamludCkgY3R4LnJlbGVhc2UoKTsKK30KKworLyoKKyAqIHB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgRVZQX1ZlcmlmeVVwZGF0ZShpbnQsIGJ5dGVbXSwgaW50LCBpbnQpCisgKi8KK3N0YXRpYyB2b2lkIE5hdGl2ZUNyeXB0b19FVlBfVmVyaWZ5VXBkYXRlKEpOSUVudiogZW52LCBqY2xhc3MsIEVWUF9NRF9DVFgqIGN0eCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpieXRlQXJyYXkgYnVmZmVyLCBqaW50IG9mZnNldCwgamludCBsZW5ndGgpIHsKKyAgICBKTklfVFJBQ0UoIk5hdGl2ZUNyeXB0b19FVlBfVmVyaWZ5VXBkYXRlKCVwLCAlcCwgJWQsICVkKSIsIGN0eCwgYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7CisKKyAgICBpZiAoY3R4ID09IE5VTEwgfHwgYnVmZmVyID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsIE5VTEwpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgU2NvcGVkQnl0ZUFycmF5Uk8gYnVmZmVyQnl0ZXMoZW52LCBidWZmZXIpOworICAgIGlmIChidWZmZXJCeXRlcy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaW50IG9rID0gRVZQX1ZlcmlmeVVwZGF0ZShjdHgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihidWZmZXJCeXRlcy5nZXQoKSArIG9mZnNldCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGgpOworICAgIGlmIChvayA9PSAwKSB7CisgICAgICAgIHRocm93RXhjZXB0aW9uSWZOZWNlc3NhcnkoZW52LCAiTmF0aXZlQ3J5cHRvX0VWUF9WZXJpZnlVcGRhdGUiKTsKKyAgICB9Cit9CisKKy8qCisgKiBwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgRVZQX1ZlcmlmeUZpbmFsKGludCwgYnl0ZVtdLCBpbnQsIGludCwgaW50KQorICovCitzdGF0aWMgaW50IE5hdGl2ZUNyeXB0b19FVlBfVmVyaWZ5RmluYWwoSk5JRW52KiBlbnYsIGpjbGFzcywgRVZQX01EX0NUWCogY3R4LCBqYnl0ZUFycmF5IGJ1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaW50IG9mZnNldCwgamludCBsZW5ndGgsIEVWUF9QS0VZKiBwa2V5KSB7CisgICAgSk5JX1RSQUNFKCJOYXRpdmVDcnlwdG9fRVZQX1ZlcmlmeUZpbmFsKCVwLCAlcCwgJWQsICVkLCAlcCkiLAorICAgICAgICAgICAgICBjdHgsIGJ1ZmZlciwgb2Zmc2V0LCBsZW5ndGgsIHBrZXkpOworCisgICAgaWYgKGN0eCA9PSBOVUxMIHx8IGJ1ZmZlciA9PSBOVUxMIHx8IHBrZXkgPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd051bGxQb2ludGVyRXhjZXB0aW9uKGVudiwgTlVMTCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBTY29wZWRCeXRlQXJyYXlSTyBidWZmZXJCeXRlcyhlbnYsIGJ1ZmZlcik7CisgICAgaWYgKGJ1ZmZlckJ5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpbnQgb2sgPSBFVlBfVmVyaWZ5RmluYWwoY3R4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihidWZmZXJCeXRlcy5nZXQoKSArIG9mZnNldCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGtleSk7CisgICAgaWYgKG9rID09IDApIHsKKyAgICAgICAgdGhyb3dFeGNlcHRpb25JZk5lY2Vzc2FyeShlbnYsICJOYXRpdmVDcnlwdG9fRVZQX1ZlcmlmeUZpbmFsIik7CisgICAgfQorICAgIEpOSV9UUkFDRSgiTmF0aXZlQ3J5cHRvX0VWUF9WZXJpZnlGaW5hbCglcCwgJXAsICVkLCAlZCwgJXApID0+ICVkIiwKKyAgICAgICAgICAgICAgY3R4LCBidWZmZXIsIG9mZnNldCwgbGVuZ3RoLCBwa2V5LCBvayk7CisKKyAgICByZXR1cm4gb2s7Cit9CisKKy8qKgorICogVmVyaWZpZXMgYW4gUlNBIHNpZ25hdHVyZS4KKyAqLworc3RhdGljIHZvaWQgTmF0aXZlQ3J5cHRvX1JBTkRfc2VlZChKTklFbnYqIGVudiwgamNsYXNzLCBqYnl0ZUFycmF5IHNlZWQpIHsKKyAgICBKTklfVFJBQ0UoIk5hdGl2ZUNyeXB0b19SQU5EX3NlZWQgc2VlZD0lcCIsIHNlZWQpOworICAgIFNjb3BlZEJ5dGVBcnJheVJPIHJhbmRzZWVkKGVudiwgc2VlZCk7CisgICAgaWYgKHJhbmRzZWVkLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBSQU5EX3NlZWQocmFuZHNlZWQuZ2V0KCksIHJhbmRzZWVkLnNpemUoKSk7Cit9CisKK3N0YXRpYyBpbnQgTmF0aXZlQ3J5cHRvX1JBTkRfbG9hZF9maWxlKEpOSUVudiogZW52LCBqY2xhc3MsIGpzdHJpbmcgZmlsZW5hbWUsIGpsb25nIG1heF9ieXRlcykgeworICAgIEpOSV9UUkFDRSgiTmF0aXZlQ3J5cHRvX1JBTkRfbG9hZF9maWxlIGZpbGVuYW1lPSVwIG1heF9ieXRlcz0lbGxkIiwgZmlsZW5hbWUsIG1heF9ieXRlcyk7CisgICAgU2NvcGVkVXRmQ2hhcnMgZmlsZShlbnYsIGZpbGVuYW1lKTsKKyAgICBpZiAoZmlsZS5jX3N0cigpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpbnQgcmVzdWx0ID0gUkFORF9sb2FkX2ZpbGUoZmlsZS5jX3N0cigpLCBtYXhfYnl0ZXMpOworICAgIEpOSV9UUkFDRSgiTmF0aXZlQ3J5cHRvX1JBTkRfbG9hZF9maWxlIGZpbGU9JXMgPT4gJWQiLCBmaWxlLmNfc3RyKCksIHJlc3VsdCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworI2lmZGVmIFdJVEhfSk5JX1RSQUNFCisvKioKKyAqIEJhc2VkIG9uIGV4YW1wbGUgbG9nZ2luZyBjYWxsIGJhY2sgZnJvbSBTU0xfQ1RYX3NldF9pbmZvX2NhbGxiYWNrIG1hbiBwYWdlCisgKi8KK3N0YXRpYyB2b2lkIGluZm9fY2FsbGJhY2tfTE9HKGNvbnN0IFNTTCogcyBfX2F0dHJpYnV0ZV9fICgodW51c2VkKSksIGludCB3aGVyZSwgaW50IHJldCkKK3sKKyAgICBpbnQgdyA9IHdoZXJlICYgflNTTF9TVF9NQVNLOworICAgIGNvbnN0IGNoYXIqIHN0cjsKKyAgICBpZiAodyAmIFNTTF9TVF9DT05ORUNUKSB7CisgICAgICAgIHN0ciA9ICJTU0xfY29ubmVjdCI7CisgICAgfSBlbHNlIGlmICh3ICYgU1NMX1NUX0FDQ0VQVCkgeworICAgICAgICBzdHIgPSAiU1NMX2FjY2VwdCI7CisgICAgfSBlbHNlIHsKKyAgICAgICAgc3RyID0gInVuZGVmaW5lZCI7CisgICAgfQorCisgICAgaWYgKHdoZXJlICYgU1NMX0NCX0xPT1ApIHsKKyAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgJXM6JXMgJXMiLCBzLCBzdHIsIFNTTF9zdGF0ZV9zdHJpbmcocyksIFNTTF9zdGF0ZV9zdHJpbmdfbG9uZyhzKSk7CisgICAgfSBlbHNlIGlmICh3aGVyZSAmIFNTTF9DQl9BTEVSVCkgeworICAgICAgICBzdHIgPSAod2hlcmUgJiBTU0xfQ0JfUkVBRCkgPyAicmVhZCIgOiAid3JpdGUiOworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBTU0wzIGFsZXJ0ICVzOiVzOiVzICVzICVzIiwKKyAgICAgICAgICAgICAgICAgIHMsCisgICAgICAgICAgICAgICAgICBzdHIsCisgICAgICAgICAgICAgICAgICBTU0xfYWxlcnRfdHlwZV9zdHJpbmcocmV0KSwKKyAgICAgICAgICAgICAgICAgIFNTTF9hbGVydF9kZXNjX3N0cmluZyhyZXQpLAorICAgICAgICAgICAgICAgICAgU1NMX2FsZXJ0X3R5cGVfc3RyaW5nX2xvbmcocmV0KSwKKyAgICAgICAgICAgICAgICAgIFNTTF9hbGVydF9kZXNjX3N0cmluZ19sb25nKHJldCkpOworICAgIH0gZWxzZSBpZiAod2hlcmUgJiBTU0xfQ0JfRVhJVCkgeworICAgICAgICBpZiAocmV0ID09IDApIHsKKyAgICAgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwICVzOmZhaWxlZCBleGl0IGluICVzICVzIiwKKyAgICAgICAgICAgICAgICAgICAgICBzLCBzdHIsIFNTTF9zdGF0ZV9zdHJpbmcocyksIFNTTF9zdGF0ZV9zdHJpbmdfbG9uZyhzKSk7CisgICAgICAgIH0gZWxzZSBpZiAocmV0IDwgMCkgeworICAgICAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgJXM6ZXJyb3IgZXhpdCBpbiAlcyAlcyIsCisgICAgICAgICAgICAgICAgICAgICAgcywgc3RyLCBTU0xfc3RhdGVfc3RyaW5nKHMpLCBTU0xfc3RhdGVfc3RyaW5nX2xvbmcocykpOworICAgICAgICB9IGVsc2UgaWYgKHJldCA9PSAxKSB7CisgICAgICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCAlczpvayBleGl0IGluICVzICVzIiwKKyAgICAgICAgICAgICAgICAgICAgICBzLCBzdHIsIFNTTF9zdGF0ZV9zdHJpbmcocyksIFNTTF9zdGF0ZV9zdHJpbmdfbG9uZyhzKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCAlczp1bmtub3duIGV4aXQgJWQgaW4gJXMgJXMiLAorICAgICAgICAgICAgICAgICAgICAgIHMsIHN0ciwgcmV0LCBTU0xfc3RhdGVfc3RyaW5nKHMpLCBTU0xfc3RhdGVfc3RyaW5nX2xvbmcocykpOworICAgICAgICB9CisgICAgfSBlbHNlIGlmICh3aGVyZSAmIFNTTF9DQl9IQU5EU0hBS0VfU1RBUlQpIHsKKyAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgaGFuZHNoYWtlIHN0YXJ0IGluICVzICVzIiwKKyAgICAgICAgICAgICAgICAgIHMsIFNTTF9zdGF0ZV9zdHJpbmcocyksIFNTTF9zdGF0ZV9zdHJpbmdfbG9uZyhzKSk7CisgICAgfSBlbHNlIGlmICh3aGVyZSAmIFNTTF9DQl9IQU5EU0hBS0VfRE9ORSkgeworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBoYW5kc2hha2UgZG9uZSBpbiAlcyAlcyIsCisgICAgICAgICAgICAgICAgICBzLCBTU0xfc3RhdGVfc3RyaW5nKHMpLCBTU0xfc3RhdGVfc3RyaW5nX2xvbmcocykpOworICAgIH0gZWxzZSB7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwICVzOnVua25vd24gd2hlcmUgJWQgaW4gJXMgJXMiLAorICAgICAgICAgICAgICAgICAgcywgc3RyLCB3aGVyZSwgU1NMX3N0YXRlX3N0cmluZyhzKSwgU1NMX3N0YXRlX3N0cmluZ19sb25nKHMpKTsKKyAgICB9Cit9CisjZW5kaWYKKworLyoqCisgKiBSZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcgYWxsIHRoZSBYNTA5IGNlcnRpZmljYXRlJ3MgYnl0ZXMuCisgKi8KK3N0YXRpYyBqb2JqZWN0QXJyYXkgZ2V0Q2VydGlmaWNhdGVCeXRlcyhKTklFbnYqIGVudiwgY29uc3QgU1RBQ0tfT0YoWDUwOSkqIGNoYWluKQoreworICAgIGlmIChjaGFpbiA9PSBOVUxMKSB7CisgICAgICAgIC8vIENoYWluIGNhbiBiZSBOVUxMIGlmIHRoZSBhc3NvY2lhdGVkIGNpcGhlciBkb2Vzbid0IGRvIGNlcnRzLgorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpbnQgY291bnQgPSBza19YNTA5X251bShjaGFpbik7CisgICAgaWYgKGNvdW50IDw9IDApIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgam9iamVjdEFycmF5IGpvYSA9IGVudi0+TmV3T2JqZWN0QXJyYXkoY291bnQsIEpuaUNvbnN0YW50czo6Ynl0ZUFycmF5Q2xhc3MsIE5VTEwpOworICAgIGlmIChqb2EgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgICAgWDUwOSogY2VydCA9IHNrX1g1MDlfdmFsdWUoY2hhaW4sIGkpOworCisgICAgICAgIGludCBsZW4gPSBpMmRfWDUwOShjZXJ0LCBOVUxMKTsKKyAgICAgICAgaWYgKGxlbiA8IDApIHsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIFNjb3BlZExvY2FsUmVmPGpieXRlQXJyYXk+IGJ5dGVBcnJheShlbnYsIGVudi0+TmV3Qnl0ZUFycmF5KGxlbikpOworICAgICAgICBpZiAoYnl0ZUFycmF5LmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIFNjb3BlZEJ5dGVBcnJheVJXIGJ5dGVzKGVudiwgYnl0ZUFycmF5LmdldCgpKTsKKyAgICAgICAgaWYgKGJ5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIHVuc2lnbmVkIGNoYXIqIHAgPSByZWludGVycHJldF9jYXN0PHVuc2lnbmVkIGNoYXIqPihieXRlcy5nZXQoKSk7CisgICAgICAgIGludCBuID0gaTJkX1g1MDkoY2VydCwgJnApOworICAgICAgICBpZiAobiA8IDApIHsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGVudi0+U2V0T2JqZWN0QXJyYXlFbGVtZW50KGpvYSwgaSwgYnl0ZUFycmF5LmdldCgpKTsKKyAgICB9CisKKyAgICByZXR1cm4gam9hOworfQorCisvKioKKyAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgdGhlIFg1MDAgcHJpbmNpcGFsJ3MgYnl0ZXMuCisgKi8KK3N0YXRpYyBqb2JqZWN0QXJyYXkgZ2V0UHJpbmNpcGFsQnl0ZXMoSk5JRW52KiBlbnYsIGNvbnN0IFNUQUNLX09GKFg1MDlfTkFNRSkqIG5hbWVzKQoreworICAgIGlmIChuYW1lcyA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGludCBjb3VudCA9IHNrX1g1MDlfTkFNRV9udW0obmFtZXMpOworICAgIGlmIChjb3VudCA8PSAwKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGpvYmplY3RBcnJheSBqb2EgPSBlbnYtPk5ld09iamVjdEFycmF5KGNvdW50LCBKbmlDb25zdGFudHM6OmJ5dGVBcnJheUNsYXNzLCBOVUxMKTsKKyAgICBpZiAoam9hID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CisgICAgICAgIFg1MDlfTkFNRSogcHJpbmNpcGFsID0gc2tfWDUwOV9OQU1FX3ZhbHVlKG5hbWVzLCBpKTsKKworICAgICAgICBpbnQgbGVuID0gaTJkX1g1MDlfTkFNRShwcmluY2lwYWwsIE5VTEwpOworICAgICAgICBpZiAobGVuIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgU2NvcGVkTG9jYWxSZWY8amJ5dGVBcnJheT4gYnl0ZUFycmF5KGVudiwgZW52LT5OZXdCeXRlQXJyYXkobGVuKSk7CisgICAgICAgIGlmIChieXRlQXJyYXkuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgU2NvcGVkQnl0ZUFycmF5UlcgYnl0ZXMoZW52LCBieXRlQXJyYXkuZ2V0KCkpOworICAgICAgICBpZiAoYnl0ZXMuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgdW5zaWduZWQgY2hhciogcCA9IHJlaW50ZXJwcmV0X2Nhc3Q8dW5zaWduZWQgY2hhcio+KGJ5dGVzLmdldCgpKTsKKyAgICAgICAgaW50IG4gPSBpMmRfWDUwOV9OQU1FKHByaW5jaXBhbCwgJnApOworICAgICAgICBpZiAobiA8IDApIHsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGVudi0+U2V0T2JqZWN0QXJyYXlFbGVtZW50KGpvYSwgaSwgYnl0ZUFycmF5LmdldCgpKTsKKyAgICB9CisKKyAgICByZXR1cm4gam9hOworfQorCisvKioKKyAqIE91ciBhZGRpdGlvbmFsIGFwcGxpY2F0aW9uIGRhdGEgbmVlZGVkIGZvciBnZXR0aW5nIHN5bmNocm9uaXphdGlvbiByaWdodC4KKyAqIFRoaXMgbWF5YmUgd2FycmFudHMgYSBiaXQgb2YgbGVuZ3RoeSBwcm9zZToKKyAqCisgKiAoMSkgV2UgdXNlIGEgZmxhZyB0byByZWZsZWN0IHdoZXRoZXIgd2UgY29uc2lkZXIgdGhlIFNTTCBjb25uZWN0aW9uIGFsaXZlLgorICogQW55IHJlYWQgb3Igd3JpdGUgYXR0ZW1wdCBsb29wcyB3aWxsIGJlIGNhbmNlbGxlZCBvbmNlIHRoaXMgZmxhZyBiZWNvbWVzIDAuCisgKgorICogKDIpIFdlIHVzZSBhbiBpbnQgdG8gY291bnQgdGhlIG51bWJlciBvZiB0aHJlYWRzIHRoYXQgYXJlIGJsb2NrZWQgYnkgdGhlCisgKiB1bmRlcmx5aW5nIHNvY2tldC4gVGhpcyBtYXkgYmUgYXQgbW9zdCB0d28gKG9uZSByZWFkZXIgYW5kIG9uZSB3cml0ZXIpLCBzaW5jZQorICogdGhlIEphdmEgbGF5ZXIgZW5zdXJlcyB0aGF0IG5vIG1vcmUgdGhyZWFkcyB3aWxsIGVudGVyIHRoZSBuYXRpdmUgY29kZSBhdCB0aGUKKyAqIHNhbWUgdGltZS4KKyAqCisgKiAoMykgVGhlIHBpcGUgaXMgdXNlZCBwcmltYXJpbHkgYXMgYSBtZWFucyBvZiBjYW5jZWxsaW5nIGEgYmxvY2tpbmcgc2VsZWN0KCkKKyAqIHdoZW4gd2Ugd2FudCB0byBjbG9zZSB0aGUgY29ubmVjdGlvbiAoYWthICJlbWVyZ2VuY3kgYnV0dG9uIikuIEl0IGlzIGFsc28KKyAqIG5lY2Vzc2FyeSBmb3IgZGVhbGluZyB3aXRoIGEgcG9zc2libGUgcmFjZSBjb25kaXRpb24gc2l0dWF0aW9uOiBUaGVyZSBtaWdodAorICogYmUgY2FzZXMgd2hlcmUgYm90aCB0aHJlYWRzIHNlZSBhbiBTU0xfRVJST1JfV0FOVF9SRUFEIG9yCisgKiBTU0xfRVJST1JfV0FOVF9XUklURS4gQm90aCB3aWxsIGVudGVyIGEgc2VsZWN0KCkgd2l0aCB0aGUgcHJvcGVyIGFyZ3VtZW50LgorICogSWYgb25lIGxlYXZlcyB0aGUgc2VsZWN0KCkgc3VjY2Vzc2Z1bGx5IGJlZm9yZSB0aGUgb3RoZXIgZW50ZXJzIGl0LCB0aGUKKyAqICJzdWNjZXNzIiBldmVudCBpcyBhbHJlYWR5IGNvbnN1bWVkIGFuZCB0aGUgc2Vjb25kIHRocmVhZCB3aWxsIGJlIGJsb2NrZWQsCisgKiBwb3NzaWJseSBmb3JldmVyIChkZXBlbmRpbmcgb24gbmV0d29yayBjb25kaXRpb25zKS4KKyAqCisgKiBUaGUgaWRlYSBmb3Igc29sdmluZyB0aGUgcHJvYmxlbSBsb29rcyBsaWtlIHRoaXM6IFdoZW5ldmVyIGEgdGhyZWFkIGlzCisgKiBzdWNjZXNzZnVsIGluIG1vdmluZyBhcm91bmQgZGF0YSBvbiB0aGUgbmV0d29yaywgYW5kIGl0IGtub3dzIHRoZXJlIGlzCisgKiBhbm90aGVyIHRocmVhZCBzdHVjayBpbiBhIHNlbGVjdCgpLCBpdCB3aWxsIHdyaXRlIGEgYnl0ZSB0byB0aGUgcGlwZSwgd2FraW5nCisgKiB1cCB0aGUgb3RoZXIgdGhyZWFkLiBBIHRocmVhZCB0aGF0IHJldHVybmVkIGZyb20gc2VsZWN0KCksIG9uIHRoZSBvdGhlciBoYW5kLAorICoga25vd3Mgd2hldGhlciBpdCdzIGJlZW4gd29rZW4gdXAgYnkgdGhlIHBpcGUuIElmIHNvLCBpdCB3aWxsIGNvbnN1bWUgdGhlCisgKiBieXRlLCBhbmQgdGhlIG9yaWdpbmFsIHN0YXRlIG9mIGFmZmFpcnMgaGFzIGJlZW4gcmVzdG9yZWQuCisgKgorICogVGhlIHBpcGUgbWF5IHNlZW0gbGlrZSBhIGJpdCBvZiBvdmVyaGVhZCwgYnV0IGl0IGZpdHMgaW4gbmljZWx5IHdpdGggdGhlCisgKiBvdGhlciBmaWxlIGRlc2NyaXB0b3JzIG9mIHRoZSBzZWxlY3QoKSwgc28gdGhlcmUncyBvbmx5IG9uZSBjb25kaXRpb24gdG8gd2FpdAorICogZm9yLgorICoKKyAqICg0KSBGaW5hbGx5LCBhIG11dGV4IGlzIG5lZWRlZCB0byBtYWtlIHN1cmUgdGhhdCBhdCBtb3N0IG9uZSB0aHJlYWQgaXMgaW4KKyAqIGVpdGhlciBTU0xfcmVhZCgpIG9yIFNTTF93cml0ZSgpIGF0IGFueSBnaXZlbiB0aW1lLiBUaGlzIGlzIGFuIE9wZW5TU0wKKyAqIHJlcXVpcmVtZW50LiBXZSB1c2UgdGhlIHNhbWUgbXV0ZXggdG8gZ3VhcmQgdGhlIGZpZWxkIGZvciBjb3VudGluZyB0aGUKKyAqIHdhaXRpbmcgdGhyZWFkcy4KKyAqCisgKiBOb3RlOiBUaGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBhc3N1bWVzIHRoYXQgd2UgZG9uJ3QgaGF2ZSB0byBkZWFsIHdpdGgKKyAqIHByb2JsZW1zIGluZHVjZWQgYnkgbXVsdGlwbGUgY29yZXMgb3IgcHJvY2Vzc29ycyBhbmQgdGhlaXIgcmVzcGVjdGl2ZQorICogbWVtb3J5IGNhY2hlcy4gT25lIHBvc3NpYmxlIHByb2JsZW0gaXMgdGhhdCBvZiBpbmNvbnNpc3RlbnQgdmlld3Mgb24gdGhlCisgKiAiYWxpdmVBbmRLaWNraW5nIiBmaWVsZC4gVGhpcyBjb3VsZCBiZSB3b3JrZWQgYXJvdW5kIGJ5IGFsc28gZW5jbG9zaW5nIGFsbAorICogYWNjZXNzZXMgdG8gdGhhdCBmaWVsZCBpbnNpZGUgYSBsb2NrL3VubG9jayBzZXF1ZW5jZSBvZiBvdXIgbXV0ZXgsIGJ1dAorICogY3VycmVudGx5IHRoaXMgc2VlbXMgYSBiaXQgbGlrZSBvdmVya2lsbC4gTWFya2luZyB2b2xhdGlsZSBhdCB0aGUgdmVyeSBsZWFzdC4KKyAqCisgKiBEdXJpbmcgaGFuZHNoYWtpbmcsIGFkZGl0aW9uYWwgZmllbGRzIGFyZSB1c2VkIHRvIHVwLWNhbGwgaW50bworICogSmF2YSB0byBwZXJmb3JtIGNlcnRpZmljYXRlIHZlcmlmaWNhdGlvbiBhbmQgaGFuZHNoYWtlCisgKiBjb21wbGV0aW9uLiBUaGVzZSBhcmUgYWxzbyB1c2VkIGluIGFueSByZW5lZ290aWF0aW9uLgorICoKKyAqICg1KSB0aGUgSk5JRW52IHNvIHdlIGNhbiBpbnZva2UgdGhlIEphdmEgY2FsbGJhY2sKKyAqCisgKiAoNikgYSBOYXRpdmVDcnlwdG8uU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGluc3RhbmNlIGZvciBjYWxsYmFja3MgZnJvbSBuYXRpdmUgdG8gSmF2YQorICoKKyAqICg3KSBhIGphdmEuaW8uRmlsZURlc2NyaXB0b3Igd3JhcHBlciB0byBjaGVjayBmb3Igc29ja2V0IGNsb3NlCisgKgorICogQmVjYXVzZSByZW5lZ290aWF0aW9uIGNhbiBiZSByZXF1ZXN0ZWQgYnkgdGhlIHBlZXIgYXQgYW55IHRpbWUsCisgKiBjYXJlIHNob3VsZCBiZSB0YWtlbiB0byBtYWludGFpbiBhbiBhcHByb3ByaWF0ZSBKTklFbnYgb24gYW55CisgKiBkb3duY2FsbCB0byBvcGVuc3NsIHNpbmNlIGl0IGNvdWxkIHJlc3VsdCBpbiBhbiB1cGNhbGwgdG8gSmF2YS4gVGhlCisgKiBjdXJyZW50IGNvZGUgZG9lcyB0cnkgdG8gY292ZXIgdGhlc2UgY2FzZXMgYnkgY29uZGl0aW9uYWxseSBzZXR0aW5nCisgKiB0aGUgSk5JRW52IG9uIGNhbGxzIHRoYXQgY2FuIHJlYWQgYW5kIHdyaXRlIHRvIHRoZSBTU0wgc3VjaCBhcworICogU1NMX2RvX2hhbmRzaGFrZSwgU1NMX3JlYWQsIFNTTF93cml0ZSwgYW5kIFNTTF9zaHV0ZG93bi4KKyAqCisgKiBGaW5hbGx5LCB3ZSBoYXZlIHR3byBlbXBoZW1lcmFsIGtleXMgc2V0dXAgYnkgT3BlblNTTCBjYWxsYmFja3M6CisgKgorICogKDgpIGEgc2V0IG9mIGVwaGVtZXJhbCBSU0Ega2V5cyB0aGF0IGlzIGxhemlseSBnZW5lcmF0ZWQgaWYgYSBwZWVyCisgKiB3YW50cyB0byB1c2UgYW4gZXhwb3J0YWJsZSBSU0EgY2lwaGVyIHN1aXRlLgorICoKKyAqICg5KSBhIHNldCBvZiBlcGhlbWVyYWwgRUMga2V5cyB0aGF0IGlzIGxhemlseSBnZW5lcmF0ZWQgaWYgYSBwZWVyCisgKiB3YW50cyB0byB1c2UgYW4gVExTX0VDREhFXyogY2lwaGVyIHN1aXRlLgorICoKKyAqLworY2xhc3MgQXBwRGF0YSB7CisgIHB1YmxpYzoKKyAgICB2b2xhdGlsZSBpbnQgYWxpdmVBbmRLaWNraW5nOworICAgIGludCB3YWl0aW5nVGhyZWFkczsKKyAgICBpbnQgZmRzRW1lcmdlbmN5WzJdOworICAgIE1VVEVYX1RZUEUgbXV0ZXg7CisgICAgSk5JRW52KiBlbnY7CisgICAgam9iamVjdCBzc2xIYW5kc2hha2VDYWxsYmFja3M7CisgICAgam9iamVjdCBmaWxlRGVzY3JpcHRvcjsKKyAgICBVbmlxdWVfUlNBIGVwaGVtZXJhbFJzYTsKKyAgICBVbmlxdWVfRUNfS0VZIGVwaGVtZXJhbEVjOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgYXBwbGljYXRpb24gZGF0YSBjb250ZXh0IGZvciB0aGUgU1NMKi4KKyAgICAgKi8KKyAgcHVibGljOgorICAgIHN0YXRpYyBBcHBEYXRhKiBjcmVhdGUoKSB7CisgICAgICAgIFVuaXF1ZVB0cjxBcHBEYXRhPiBhcHBEYXRhKG5ldyBBcHBEYXRhKCkpOworICAgICAgICBpZiAocGlwZShhcHBEYXRhLmdldCgpLT5mZHNFbWVyZ2VuY3kpID09IC0xKSB7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXNldEJsb2NraW5nKGFwcERhdGEuZ2V0KCktPmZkc0VtZXJnZW5jeVswXSwgZmFsc2UpKSB7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBpZiAoTVVURVhfU0VUVVAoYXBwRGF0YS5nZXQoKS0+bXV0ZXgpID09IC0xKSB7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYXBwRGF0YS5yZWxlYXNlKCk7CisgICAgfQorCisgICAgfkFwcERhdGEoKSB7CisgICAgICAgIGFsaXZlQW5kS2lja2luZyA9IDA7CisgICAgICAgIGlmIChmZHNFbWVyZ2VuY3lbMF0gIT0gLTEpIHsKKyAgICAgICAgICAgIGNsb3NlKGZkc0VtZXJnZW5jeVswXSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZkc0VtZXJnZW5jeVsxXSAhPSAtMSkgeworICAgICAgICAgICAgY2xvc2UoZmRzRW1lcmdlbmN5WzFdKTsKKyAgICAgICAgfQorICAgICAgICBNVVRFWF9DTEVBTlVQKG11dGV4KTsKKyAgICB9CisKKyAgcHJpdmF0ZToKKyAgICBBcHBEYXRhKCkgOgorICAgICAgICAgICAgYWxpdmVBbmRLaWNraW5nKDEpLAorICAgICAgICAgICAgd2FpdGluZ1RocmVhZHMoMCksCisgICAgICAgICAgICBlbnYoTlVMTCksCisgICAgICAgICAgICBzc2xIYW5kc2hha2VDYWxsYmFja3MoTlVMTCksCisgICAgICAgICAgICBlcGhlbWVyYWxSc2EoTlVMTCksCisgICAgICAgICAgICBlcGhlbWVyYWxFYyhOVUxMKSB7CisgICAgICAgIGZkc0VtZXJnZW5jeVswXSA9IC0xOworICAgICAgICBmZHNFbWVyZ2VuY3lbMV0gPSAtMTsKKyAgICB9CisKKyAgcHVibGljOgorICAgIC8qKgorICAgICAqIFVzZWQgdG8gc2V0IHRoZSBTU0wtdG8tSmF2YSBjYWxsYmFjayBzdGF0ZSBiZWZvcmUgZWFjaCBTU0xfKgorICAgICAqIGNhbGwgdGhhdCBtYXkgcmVzdWx0IGluIGEgY2FsbGJhY2suIEl0IHNob3VsZCBiZSBjbGVhcmVkIGFmdGVyCisgICAgICogdGhlIG9wZXJhdGlvbiByZXR1cm5zIHdpdGggY2xlYXJDYWxsYmFja1N0YXRlLgorICAgICAqCisgICAgICogQHBhcmFtIGVudiBUaGUgSk5JRW52CisgICAgICogQHBhcmFtIHNoYyBUaGUgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzCisgICAgICogQHBhcmFtIGZkIFRoZSBGaWxlRGVzY3JpcHRvcgorICAgICAqLworICAgIGJvb2wgc2V0Q2FsbGJhY2tTdGF0ZShKTklFbnYqIGUsIGpvYmplY3Qgc2hjLCBqb2JqZWN0IGZkKSB7CisgICAgICAgIE5ldEZkIG5ldEZkKGUsIGZkKTsKKyAgICAgICAgaWYgKG5ldEZkLmlzQ2xvc2VkKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBlbnYgPSBlOworICAgICAgICBzc2xIYW5kc2hha2VDYWxsYmFja3MgPSBzaGM7CisgICAgICAgIGZpbGVEZXNjcmlwdG9yID0gZmQ7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIHZvaWQgY2xlYXJDYWxsYmFja1N0YXRlKCkgeworICAgICAgICBlbnYgPSBOVUxMOworICAgICAgICBzc2xIYW5kc2hha2VDYWxsYmFja3MgPSBOVUxMOworICAgICAgICBmaWxlRGVzY3JpcHRvciA9IE5VTEw7CisgICAgfQorCit9OworCisvKioKKyAqIERhcmsgbWFnaWMgaGVscGVyIGZ1bmN0aW9uIHRoYXQgY2hlY2tzLCBmb3IgYSBnaXZlbiBTU0wgc2Vzc2lvbiwgd2hldGhlciBpdAorICogY2FuIFNTTF9yZWFkKCkgb3IgU1NMX3dyaXRlKCkgd2l0aG91dCBibG9ja2luZy4gVGFrZXMgaW50byBhY2NvdW50IGFueQorICogY29uY3VycmVudCBhdHRlbXB0cyB0byBjbG9zZSB0aGUgU1NMU29ja2V0IGZyb20gdGhlIEphdmEgc2lkZS4gVGhpcyBpcworICogbmVlZGVkIHRvIGdldCByaWQgb2YgdGhlIGhhbmdzIHRoYXQgb2NjdXIgd2hlbiB0aHJlYWQgIzEgY2xvc2VzIHRoZSBTU0xTb2NrZXQKKyAqIHdoaWxlIHRocmVhZCAjMiBpcyBzaXR0aW5nIGluIGEgYmxvY2tpbmcgcmVhZCBvciB3cml0ZS4gVGhlIHR5cGUgYXJndW1lbnQKKyAqIHNwZWNpZmllcyB3aGV0aGVyIHdlIGFyZSB3YWl0aW5nIGZvciByZWFkYWJpbGl0eSBvciB3cml0YWJpbGl0eS4gSXQgZXhwZWN0cworICogdG8gYmUgcGFzc2VkIGVpdGhlciBTU0xfRVJST1JfV0FOVF9SRUFEIG9yIFNTTF9FUlJPUl9XQU5UX1dSSVRFLCBzaW5jZSB3ZQorICogb25seSBuZWVkIHRvIHdhaXQgaW4gY2FzZSBvbmUgb2YgdGhlc2UgcHJvYmxlbXMgb2NjdXJzLgorICoKKyAqIEBwYXJhbSBlbnYKKyAqIEBwYXJhbSB0eXBlIEVpdGhlciBTU0xfRVJST1JfV0FOVF9SRUFEIG9yIFNTTF9FUlJPUl9XQU5UX1dSSVRFCisgKiBAcGFyYW0gZmRPYmplY3QgVGhlIEZpbGVEZXNjcmlwdG9yLCBzaW5jZSBhcHBEYXRhLT5maWxlRGVzY3JpcHRvciBzaG91bGQgYmUgTlVMTAorICogQHBhcmFtIGFwcERhdGEgVGhlIGFwcGxpY2F0aW9uIGRhdGEgc3RydWN0dXJlIHdpdGggbXV0ZXggaW5mbyBldGMuCisgKiBAcGFyYW0gdGltZW91dCBUaGUgdGltZW91dCB2YWx1ZSBmb3Igc2VsZWN0IGNhbGwsIHdpdGggdGhlIHNwZWNpYWwgdmFsdWUKKyAqICAgICAgICAgICAgICAgIDAgbWVhbmluZyBubyB0aW1lb3V0IGF0IGFsbCAod2FpdCBpbmRlZmluaXRlbHkpLiBOb3RlOiBUaGlzIGlzCisgKiAgICAgICAgICAgICAgICB0aGUgSmF2YSBzZW1hbnRpY3Mgb2YgdGhlIHRpbWVvdXQgdmFsdWUsIG5vdCB0aGUgdXN1YWwKKyAqICAgICAgICAgICAgICAgIHNlbGVjdCgpIHNlbWFudGljcy4KKyAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgaW5uZXIgc2VsZWN0KCkgY2FsbCwKKyAqIFRIUk9XX1NPQ0tFVEVYQ0VQVElPTiBpZiBhIFNvY2tldEV4Y2VwdGlvbiB3YXMgdGhyb3duLCAtMSBvbgorICogYWRkaXRpb25hbCBlcnJvcnMKKyAqLworc3RhdGljIGludCBzc2xTZWxlY3QoSk5JRW52KiBlbnYsIGludCB0eXBlLCBqb2JqZWN0IGZkT2JqZWN0LCBBcHBEYXRhKiBhcHBEYXRhLCBpbnQgdGltZW91dCkgeworICAgIC8vIFRoaXMgbG9vcCBpcyBhbiBleHBhbmRlZCB2ZXJzaW9uIG9mIHRoZSBORVRfRkFJTFVSRV9SRVRSWQorICAgIC8vIG1hY3JvLiBJdCBjYW5ub3Qgc2ltcGx5IGJlIHVzZWQgaW4gdGhpcyBjYXNlIGJlY2F1c2Ugc2VsZWN0CisgICAgLy8gY2Fubm90IGJlIHJlc3RhcnRlZCB3aXRob3V0IHJlY3JlYXRpbmcgdGhlIGZkX3NldHMgYW5kIHRpbWVvdXQKKyAgICAvLyBzdHJ1Y3R1cmUuCisgICAgaW50IHJlc3VsdDsKKyAgICBmZF9zZXQgcmZkczsKKyAgICBmZF9zZXQgd2ZkczsKKyAgICBkbyB7CisgICAgICAgIE5ldEZkIGZkKGVudiwgZmRPYmplY3QpOworICAgICAgICBpZiAoZmQuaXNDbG9zZWQoKSkgeworICAgICAgICAgICAgcmVzdWx0ID0gVEhST1dOX0VYQ0VQVElPTjsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGludCBpbnRGZCA9IGZkLmdldCgpOworICAgICAgICBKTklfVFJBQ0UoInNzbFNlbGVjdCB0eXBlPSVzIGZkPSVkIGFwcERhdGE9JXAgdGltZW91dD0lZCIsCisgICAgICAgICAgICAgICAgICAodHlwZSA9PSBTU0xfRVJST1JfV0FOVF9SRUFEKSA/ICJSRUFEIiA6ICJXUklURSIsIGludEZkLCBhcHBEYXRhLCB0aW1lb3V0KTsKKworICAgICAgICBGRF9aRVJPKCZyZmRzKTsKKyAgICAgICAgRkRfWkVSTygmd2Zkcyk7CisKKyAgICAgICAgaWYgKHR5cGUgPT0gU1NMX0VSUk9SX1dBTlRfUkVBRCkgeworICAgICAgICAgICAgRkRfU0VUKGludEZkLCAmcmZkcyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBGRF9TRVQoaW50RmQsICZ3ZmRzKTsKKyAgICAgICAgfQorCisgICAgICAgIEZEX1NFVChhcHBEYXRhLT5mZHNFbWVyZ2VuY3lbMF0sICZyZmRzKTsKKworICAgICAgICBpbnQgbWF4RmQgPSAoaW50RmQgPiBhcHBEYXRhLT5mZHNFbWVyZ2VuY3lbMF0pID8gaW50RmQgOiBhcHBEYXRhLT5mZHNFbWVyZ2VuY3lbMF07CisKKyAgICAgICAgLy8gQnVpbGQgYSBzdHJ1Y3QgZm9yIHRoZSB0aW1lb3V0IGRhdGEgaWYgd2UgYWN0dWFsbHkgd2FudCBhIHRpbWVvdXQuCisgICAgICAgIHRpbWV2YWwgdHY7CisgICAgICAgIHRpbWV2YWwqIHB0djsKKyAgICAgICAgaWYgKHRpbWVvdXQgPiAwKSB7CisgICAgICAgICAgICB0di50dl9zZWMgPSB0aW1lb3V0IC8gMTAwMDsKKyAgICAgICAgICAgIHR2LnR2X3VzZWMgPSAwOworICAgICAgICAgICAgcHR2ID0gJnR2OworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcHR2ID0gTlVMTDsKKyAgICAgICAgfQorCisgICAgICAgIEFzeW5jaHJvbm91c1NvY2tldENsb3NlTW9uaXRvciBtb25pdG9yKGludEZkKTsKKyAgICAgICAgcmVzdWx0ID0gc2VsZWN0KG1heEZkICsgMSwgJnJmZHMsICZ3ZmRzLCBOVUxMLCBwdHYpOworICAgICAgICBKTklfVFJBQ0UoInNzbFNlbGVjdCAlcyBmZD0lZCBhcHBEYXRhPSVwIHRpbWVvdXQ9JWQgPT4gJWQiLAorICAgICAgICAgICAgICAgICAgKHR5cGUgPT0gU1NMX0VSUk9SX1dBTlRfUkVBRCkgPyAiUkVBRCIgOiAiV1JJVEUiLAorICAgICAgICAgICAgICAgICAgZmQuZ2V0KCksIGFwcERhdGEsIHRpbWVvdXQsIHJlc3VsdCk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gLTEpIHsKKyAgICAgICAgICAgIGlmIChmZC5pc0Nsb3NlZCgpKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gVEhST1dOX0VYQ0VQVElPTjsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChlcnJubyAhPSBFSU5UUikgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfSB3aGlsZSAocmVzdWx0ID09IC0xKTsKKworICAgIGlmIChNVVRFWF9MT0NLKGFwcERhdGEtPm11dGV4KSA9PSAtMSkgeworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgaWYgKHJlc3VsdCA+IDApIHsKKyAgICAgICAgLy8gV2UgaGF2ZSBiZWVuIHdva2VuIHVwIGJ5IGEgdG9rZW4gaW4gdGhlIGVtZXJnZW5jeSBwaXBlLiBXZQorICAgICAgICAvLyBjYW4ndCBiZSBzdXJlIHRoZSB0b2tlbiBpcyBzdGlsbCBpbiB0aGUgcGlwZSBhdCB0aGlzIHBvaW50CisgICAgICAgIC8vIGJlY2F1c2UgaXQgY291bGQgaGF2ZSBhbHJlYWR5IGJlZW4gcmVhZCBieSB0aGUgdGhyZWFkIHRoYXQKKyAgICAgICAgLy8gb3JpZ2luYWxseSB3cm90ZSBpdCBpZiBpdCBlbnRlcmVkIHNzbFNlbGVjdCBhbmQgYWNxdWlyZWQKKyAgICAgICAgLy8gdGhlIG11dGV4IGJlZm9yZSB3ZSBkaWQuIFRodXMgd2UgY2Fubm90IHNhZmVseSByZWFkIGZyb20KKyAgICAgICAgLy8gdGhlIHBpcGUgaW4gYSBibG9ja2luZyB3YXkgKHNvIHdlIG1ha2UgdGhlIHBpcGUKKyAgICAgICAgLy8gbm9uLWJsb2NraW5nIGF0IGNyZWF0aW9uKS4KKyAgICAgICAgaWYgKEZEX0lTU0VUKGFwcERhdGEtPmZkc0VtZXJnZW5jeVswXSwgJnJmZHMpKSB7CisgICAgICAgICAgICBjaGFyIHRva2VuOworICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIHJlYWQoYXBwRGF0YS0+ZmRzRW1lcmdlbmN5WzBdLCAmdG9rZW4sIDEpOworICAgICAgICAgICAgfSB3aGlsZSAoZXJybm8gPT0gRUlOVFIpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gVGVsbCB0aGUgd29ybGQgdGhhdCB0aGVyZSBpcyBub3cgb25lIHRocmVhZCBsZXNzIHdhaXRpbmcgZm9yIHRoZQorICAgIC8vIHVuZGVybHlpbmcgbmV0d29yay4KKyAgICBhcHBEYXRhLT53YWl0aW5nVGhyZWFkcy0tOworCisgICAgTVVURVhfVU5MT0NLKGFwcERhdGEtPm11dGV4KTsKKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qKgorICogSGVscGVyIGZ1bmN0aW9uIHRoYXQgd2FrZXMgdXAgYSB0aHJlYWQgYmxvY2tlZCBpbiBzZWxlY3QoKSwgaW4gY2FzZSB0aGVyZSBpcworICogb25lLiBJcyBiZWluZyBjYWxsZWQgYnkgc3NsUmVhZCgpIGFuZCBzc2xXcml0ZSgpIGFzIHdlbGwgYXMgYnkgSk5JIGdsdWUKKyAqIGJlZm9yZSBjbG9zaW5nIHRoZSBjb25uZWN0aW9uLgorICoKKyAqIEBwYXJhbSBkYXRhIFRoZSBhcHBsaWNhdGlvbiBkYXRhIHN0cnVjdHVyZSB3aXRoIG11dGV4IGluZm8gZXRjLgorICovCitzdGF0aWMgdm9pZCBzc2xOb3RpZnkoQXBwRGF0YSogYXBwRGF0YSkgeworICAgIC8vIFdyaXRlIGEgYnl0ZSB0byB0aGUgZW1lcmdlbmN5IHBpcGUsIHNvIGEgY29uY3VycmVudCBzZWxlY3QoKSBjYW4gcmV0dXJuLgorICAgIC8vIE5vdGUgd2UgaGF2ZSB0byByZXN0b3JlIHRoZSBlcnJubyBvZiB0aGUgb3JpZ2luYWwgc3lzdGVtIGNhbGwsIHNpbmNlIHRoZQorICAgIC8vIGNhbGxlciByZWxpZXMgb24gaXQgZm9yIGdlbmVyYXRpbmcgZXJyb3IgbWVzc2FnZXMuCisgICAgaW50IGVycm5vQmFja3VwID0gZXJybm87CisgICAgY2hhciB0b2tlbiA9ICcqJzsKKyAgICBkbyB7CisgICAgICAgIGVycm5vID0gMDsKKyAgICAgICAgd3JpdGUoYXBwRGF0YS0+ZmRzRW1lcmdlbmN5WzFdLCAmdG9rZW4sIDEpOworICAgIH0gd2hpbGUgKGVycm5vID09IEVJTlRSKTsKKyAgICBlcnJubyA9IGVycm5vQmFja3VwOworfQorCitzdGF0aWMgQXBwRGF0YSogdG9BcHBEYXRhKGNvbnN0IFNTTCogc3NsKSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8QXBwRGF0YSo+KFNTTF9nZXRfYXBwX2RhdGEoc3NsKSk7Cit9CisKKy8qKgorICogVmVyaWZ5IHRoZSBYNTA5IGNlcnRpZmljYXRlIHZpYSBTU0xfQ1RYX3NldF9jZXJ0X3ZlcmlmeV9jYWxsYmFjaworICovCitzdGF0aWMgaW50IGNlcnRfdmVyaWZ5X2NhbGxiYWNrKFg1MDlfU1RPUkVfQ1RYKiB4NTA5X3N0b3JlX2N0eCwgdm9pZCogYXJnIF9fYXR0cmlidXRlX18gKCh1bnVzZWQpKSkKK3sKKyAgICAvKiBHZXQgdGhlIGNvcnJlY3QgaW5kZXggdG8gdGhlIFNTTG9iamVjdCBzdG9yZWQgaW50byBYNTA5X1NUT1JFX0NUWC4gKi8KKyAgICBTU0wqIHNzbCA9IHJlaW50ZXJwcmV0X2Nhc3Q8U1NMKj4oWDUwOV9TVE9SRV9DVFhfZ2V0X2V4X2RhdGEoeDUwOV9zdG9yZV9jdHgsCisgICAgICAgICAgICBTU0xfZ2V0X2V4X2RhdGFfWDUwOV9TVE9SRV9DVFhfaWR4KCkpKTsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBjZXJ0X3ZlcmlmeV9jYWxsYmFjayB4NTA5X3N0b3JlX2N0eD0lcCBhcmc9JXAiLCBzc2wsIHg1MDlfc3RvcmVfY3R4LCBhcmcpOworCisgICAgQXBwRGF0YSogYXBwRGF0YSA9IHRvQXBwRGF0YShzc2wpOworICAgIEpOSUVudiogZW52ID0gYXBwRGF0YS0+ZW52OworICAgIGlmIChlbnYgPT0gTlVMTCkgeworICAgICAgICBMT0dFKCJBcHBEYXRhLT5lbnYgbWlzc2luZyBpbiBjZXJ0X3ZlcmlmeV9jYWxsYmFjayIpOworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBjZXJ0X3ZlcmlmeV9jYWxsYmFjayA9PiAwIiwgc3NsKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGpvYmplY3Qgc3NsSGFuZHNoYWtlQ2FsbGJhY2tzID0gYXBwRGF0YS0+c3NsSGFuZHNoYWtlQ2FsbGJhY2tzOworCisgICAgamNsYXNzIGNscyA9IGVudi0+R2V0T2JqZWN0Q2xhc3Moc3NsSGFuZHNoYWtlQ2FsbGJhY2tzKTsKKyAgICBqbWV0aG9kSUQgbWV0aG9kSUQKKyAgICAgICAgPSBlbnYtPkdldE1ldGhvZElEKGNscywgInZlcmlmeUNlcnRpZmljYXRlQ2hhaW4iLCAiKFtbQkxqYXZhL2xhbmcvU3RyaW5nOylWIik7CisKKyAgICBqb2JqZWN0QXJyYXkgb2JqZWN0QXJyYXkgPSBnZXRDZXJ0aWZpY2F0ZUJ5dGVzKGVudiwgeDUwOV9zdG9yZV9jdHgtPnVudHJ1c3RlZCk7CisKKyAgICBjb25zdCBjaGFyKiBhdXRoTWV0aG9kID0gU1NMX2F1dGhlbnRpY2F0aW9uX21ldGhvZChzc2wpOworICAgIEpOSV9UUkFDRSgic3NsPSVwIGNlcnRfdmVyaWZ5X2NhbGxiYWNrIGNhbGxpbmcgdmVyaWZ5Q2VydGlmaWNhdGVDaGFpbiBhdXRoTWV0aG9kPSVzIiwKKyAgICAgICAgICAgICAgc3NsLCBhdXRoTWV0aG9kKTsKKyAgICBqc3RyaW5nIGF1dGhNZXRob2RTdHJpbmcgPSBlbnYtPk5ld1N0cmluZ1VURihhdXRoTWV0aG9kKTsKKyAgICBlbnYtPkNhbGxWb2lkTWV0aG9kKHNzbEhhbmRzaGFrZUNhbGxiYWNrcywgbWV0aG9kSUQsIG9iamVjdEFycmF5LCBhdXRoTWV0aG9kU3RyaW5nKTsKKworICAgIGludCByZXN1bHQgPSAoZW52LT5FeGNlcHRpb25DaGVjaygpKSA/IDAgOiAxOworICAgIEpOSV9UUkFDRSgic3NsPSVwIGNlcnRfdmVyaWZ5X2NhbGxiYWNrID0+ICVkIiwgc3NsLCByZXN1bHQpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qKgorICogQ2FsbCBiYWNrIHRvIHdhdGNoIGZvciBoYW5kc2hha2UgdG8gYmUgY29tcGxldGVkLiBUaGlzIGlzIG5lY2Vzc2FyeQorICogZm9yIFNTTF9NT0RFX0hBTkRTSEFLRV9DVVRUSFJPVUdIIHN1cHBvcnQsIHNpbmNlIFNTTF9kb19oYW5kc2hha2UKKyAqIHJldHVybnMgYmVmb3JlIHRoZSBoYW5kc2hha2UgaXMgY29tcGxldGVkIGluIHRoaXMgY2FzZS4KKyAqLworc3RhdGljIHZvaWQgaW5mb19jYWxsYmFjayhjb25zdCBTU0wqIHNzbCwgaW50IHdoZXJlLCBpbnQgcmV0IF9fYXR0cmlidXRlX18gKCh1bnVzZWQpKSkgeworICAgIEpOSV9UUkFDRSgic3NsPSVwIGluZm9fY2FsbGJhY2sgd2hlcmU9MHgleCByZXQ9JWQiLCBzc2wsIHdoZXJlLCByZXQpOworI2lmZGVmIFdJVEhfSk5JX1RSQUNFCisgICAgaW5mb19jYWxsYmFja19MT0coc3NsLCB3aGVyZSwgcmV0KTsKKyNlbmRpZgorICAgIGlmICghKHdoZXJlICYgU1NMX0NCX0hBTkRTSEFLRV9ET05FKSkgeworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBpbmZvX2NhbGxiYWNrIGlnbm9yZWQiLCBzc2wpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgQXBwRGF0YSogYXBwRGF0YSA9IHRvQXBwRGF0YShzc2wpOworICAgIEpOSUVudiogZW52ID0gYXBwRGF0YS0+ZW52OworICAgIGlmIChlbnYgPT0gTlVMTCkgeworICAgICAgICBMT0dFKCJBcHBEYXRhLT5lbnYgbWlzc2luZyBpbiBpbmZvX2NhbGxiYWNrIik7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIGluZm9fY2FsbGJhY2sgZW52IGVycm9yIiwgc3NsKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoZW52LT5FeGNlcHRpb25DaGVjaygpKSB7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIGluZm9fY2FsbGJhY2sgYWxyZWFkeSBwZW5kaW5nIGV4Y2VwdGlvbiIsIHNzbCk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBqb2JqZWN0IHNzbEhhbmRzaGFrZUNhbGxiYWNrcyA9IGFwcERhdGEtPnNzbEhhbmRzaGFrZUNhbGxiYWNrczsKKworICAgIGpjbGFzcyBjbHMgPSBlbnYtPkdldE9iamVjdENsYXNzKHNzbEhhbmRzaGFrZUNhbGxiYWNrcyk7CisgICAgam1ldGhvZElEIG1ldGhvZElEID0gZW52LT5HZXRNZXRob2RJRChjbHMsICJoYW5kc2hha2VDb21wbGV0ZWQiLCAiKClWIik7CisKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBpbmZvX2NhbGxiYWNrIGNhbGxpbmcgaGFuZHNoYWtlQ29tcGxldGVkIiwgc3NsKTsKKyAgICBlbnYtPkNhbGxWb2lkTWV0aG9kKHNzbEhhbmRzaGFrZUNhbGxiYWNrcywgbWV0aG9kSUQpOworCisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgeworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBpbmZvX2NhbGxiYWNrIGV4Y2VwdGlvbiIsIHNzbCk7CisgICAgfQorICAgIEpOSV9UUkFDRSgic3NsPSVwIGluZm9fY2FsbGJhY2sgY29tcGxldGVkIiwgc3NsKTsKK30KKworLyoqCisgKiBDYWxsIGJhY2sgdG8gYXNrIGZvciBhIGNsaWVudCBjZXJ0aWZpY2F0ZQorICovCitzdGF0aWMgaW50IGNsaWVudF9jZXJ0X2NiKFNTTCogc3NsLCBYNTA5KiogeDUwOU91dCwgRVZQX1BLRVkqKiBwa2V5T3V0KSB7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgY2xpZW50X2NlcnRfY2IgeDUwOU91dD0lcCBwa2V5T3V0PSVwIiwgc3NsLCB4NTA5T3V0LCBwa2V5T3V0KTsKKworICAgIEFwcERhdGEqIGFwcERhdGEgPSB0b0FwcERhdGEoc3NsKTsKKyAgICBKTklFbnYqIGVudiA9IGFwcERhdGEtPmVudjsKKyAgICBpZiAoZW52ID09IE5VTEwpIHsKKyAgICAgICAgTE9HRSgiQXBwRGF0YS0+ZW52IG1pc3NpbmcgaW4gY2xpZW50X2NlcnRfY2IiKTsKKyAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgY2xpZW50X2NlcnRfY2IgZW52IGVycm9yID0+IDAiLCBzc2wpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgeworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBjbGllbnRfY2VydF9jYiBhbHJlYWR5IHBlbmRpbmcgZXhjZXB0aW9uIiwgc3NsKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGpvYmplY3Qgc3NsSGFuZHNoYWtlQ2FsbGJhY2tzID0gYXBwRGF0YS0+c3NsSGFuZHNoYWtlQ2FsbGJhY2tzOworCisgICAgamNsYXNzIGNscyA9IGVudi0+R2V0T2JqZWN0Q2xhc3Moc3NsSGFuZHNoYWtlQ2FsbGJhY2tzKTsKKyAgICBqbWV0aG9kSUQgbWV0aG9kSUQKKyAgICAgICAgPSBlbnYtPkdldE1ldGhvZElEKGNscywgImNsaWVudENlcnRpZmljYXRlUmVxdWVzdGVkIiwgIihbQltbQilWIik7CisKKyAgICAvLyBDYWxsIEphdmEgY2FsbGJhY2sgd2hpY2ggY2FuIHVzZSBTU0xfdXNlX2NlcnRpZmljYXRlIGFuZCBTU0xfdXNlX1ByaXZhdGVLZXkgdG8gc2V0IHZhbHVlcworICAgIGNoYXIgc3NsMl9jdHlwZSA9IFNTTDNfQ1RfUlNBX1NJR047CisgICAgY29uc3QgY2hhciogY3R5cGUgPSBOVUxMOworICAgIGludCBjdHlwZV9udW0gPSAwOworICAgIGpvYmplY3RBcnJheSBpc3N1ZXJzID0gTlVMTDsKKyAgICBzd2l0Y2ggKHNzbC0+dmVyc2lvbikgeworICAgICAgICBjYXNlIFNTTDJfVkVSU0lPTjoKKyAgICAgICAgICAgIGN0eXBlID0gJnNzbDJfY3R5cGU7CisgICAgICAgICAgICBjdHlwZV9udW0gPSAxOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgU1NMM19WRVJTSU9OOgorICAgICAgICBjYXNlIFRMUzFfVkVSU0lPTjoKKyAgICAgICAgY2FzZSBEVExTMV9WRVJTSU9OOgorICAgICAgICAgICAgY3R5cGUgPSBzc2wtPnMzLT50bXAuY3R5cGU7CisgICAgICAgICAgICBjdHlwZV9udW0gPSBzc2wtPnMzLT50bXAuY3R5cGVfbnVtOworICAgICAgICAgICAgaXNzdWVycyA9IGdldFByaW5jaXBhbEJ5dGVzKGVudiwgc3NsLT5zMy0+dG1wLmNhX25hbWVzKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgIH0KKyNpZmRlZiBXSVRIX0pOSV9UUkFDRQorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY3R5cGVfbnVtOyBpKyspIHsKKyAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgY2xpZW50Q2VydGlmaWNhdGVSZXF1ZXN0ZWQga2V5VHlwZXNbJWRdPSVkIiwgc3NsLCBpLCBjdHlwZVtpXSk7CisgICAgfQorI2VuZGlmCisKKyAgICBqYnl0ZUFycmF5IGtleVR5cGVzID0gZW52LT5OZXdCeXRlQXJyYXkoY3R5cGVfbnVtKTsKKyAgICBpZiAoa2V5VHlwZXMgPT0gTlVMTCkgeworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBjbGllbnRfY2VydF9jYiBieXRlcyA9PSBudWxsID0+IDAiLCBzc2wpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgZW52LT5TZXRCeXRlQXJyYXlSZWdpb24oa2V5VHlwZXMsIDAsIGN0eXBlX251bSwgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBqYnl0ZSo+KGN0eXBlKSk7CisKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBjbGllbnRDZXJ0aWZpY2F0ZVJlcXVlc3RlZCBjYWxsaW5nIGNsaWVudENlcnRpZmljYXRlUmVxdWVzdGVkICIKKyAgICAgICAgICAgICAgImtleVR5cGVzPSVwIGlzc3VlcnM9JXAiLCBzc2wsIGtleVR5cGVzLCBpc3N1ZXJzKTsKKyAgICBlbnYtPkNhbGxWb2lkTWV0aG9kKHNzbEhhbmRzaGFrZUNhbGxiYWNrcywgbWV0aG9kSUQsIGtleVR5cGVzLCBpc3N1ZXJzKTsKKworICAgIGlmIChlbnYtPkV4Y2VwdGlvbkNoZWNrKCkpIHsKKyAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgY2xpZW50X2NlcnRfY2IgZXhjZXB0aW9uID0+IDAiLCBzc2wpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvLyBDaGVjayBmb3IgdmFsdWVzIHNldCBmcm9tIEphdmEKKyAgICBYNTA5KiAgICAgY2VydGlmaWNhdGUgPSBTU0xfZ2V0X2NlcnRpZmljYXRlKHNzbCk7CisgICAgRVZQX1BLRVkqIHByaXZhdGVrZXkgID0gU1NMX2dldF9wcml2YXRla2V5KHNzbCk7CisgICAgaW50IHJlc3VsdDsKKyAgICBpZiAoY2VydGlmaWNhdGUgIT0gTlVMTCAmJiBwcml2YXRla2V5ICE9IE5VTEwpIHsKKyAgICAgICAgKng1MDlPdXQgPSBjZXJ0aWZpY2F0ZTsKKyAgICAgICAgKnBrZXlPdXQgPSBwcml2YXRla2V5OworICAgICAgICByZXN1bHQgPSAxOworICAgIH0gZWxzZSB7CisgICAgICAgICp4NTA5T3V0ID0gTlVMTDsKKyAgICAgICAgKnBrZXlPdXQgPSBOVUxMOworICAgICAgICByZXN1bHQgPSAwOworICAgIH0KKyAgICBKTklfVFJBQ0UoInNzbD0lcCBjbGllbnRfY2VydF9jYiA9PiAqeDUwOT0lcCAqcGtleT0lcCAlZCIsIHNzbCwgKng1MDlPdXQsICpwa2V5T3V0LCByZXN1bHQpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBSU0EqIHJzYUdlbmVyYXRlS2V5KGludCBrZXlsZW5ndGgpIHsKKyAgICBVbmlxdWVfQklHTlVNIGJuKEJOX25ldygpKTsKKyAgICBpZiAoYm4uZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaW50IHNldFdvcmRSZXN1bHQgPSBCTl9zZXRfd29yZChibi5nZXQoKSwgUlNBX0Y0KTsKKyAgICBpZiAoc2V0V29yZFJlc3VsdCAhPSAxKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBVbmlxdWVfUlNBIHJzYShSU0FfbmV3KCkpOworICAgIGlmIChyc2EuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaW50IGdlbmVyYXRlUmVzdWx0ID0gUlNBX2dlbmVyYXRlX2tleV9leChyc2EuZ2V0KCksIGtleWxlbmd0aCwgYm4uZ2V0KCksIE5VTEwpOworICAgIGlmIChnZW5lcmF0ZVJlc3VsdCAhPSAxKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gcnNhLnJlbGVhc2UoKTsKK30KKworLyoqCisgKiBDYWxsIGJhY2sgdG8gYXNrIGZvciBhbiBlcGhlbWVyYWwgUlNBIGtleSBmb3IgU1NMX1JTQV9FWFBPUlRfV0lUSF9SQzRfNDBfTUQ1IChha2EgRVhQLVJDNC1NRDUpCisgKi8KK3N0YXRpYyBSU0EqIHRtcF9yc2FfY2FsbGJhY2soU1NMKiBzc2wgX19hdHRyaWJ1dGVfXyAoKHVudXNlZCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaXNfZXhwb3J0IF9fYXR0cmlidXRlX18gKCh1bnVzZWQpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGtleWxlbmd0aCkgeworICAgIEpOSV9UUkFDRSgic3NsPSVwIHRtcF9yc2FfY2FsbGJhY2sgaXNfZXhwb3J0PSVkIGtleWxlbmd0aD0lZCIsIHNzbCwgaXNfZXhwb3J0LCBrZXlsZW5ndGgpOworCisgICAgQXBwRGF0YSogYXBwRGF0YSA9IHRvQXBwRGF0YShzc2wpOworICAgIGlmIChhcHBEYXRhLT5lcGhlbWVyYWxSc2EuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCB0bXBfcnNhX2NhbGxiYWNrIGdlbmVyYXRpbmcgZXBoZW1lcmFsIFJTQSBrZXkiLCBzc2wpOworICAgICAgICBhcHBEYXRhLT5lcGhlbWVyYWxSc2EucmVzZXQocnNhR2VuZXJhdGVLZXkoa2V5bGVuZ3RoKSk7CisgICAgfQorICAgIEpOSV9UUkFDRSgic3NsPSVwIHRtcF9yc2FfY2FsbGJhY2sgPT4gJXAiLCBzc2wsIGFwcERhdGEtPmVwaGVtZXJhbFJzYS5nZXQoKSk7CisgICAgcmV0dXJuIGFwcERhdGEtPmVwaGVtZXJhbFJzYS5nZXQoKTsKK30KKworc3RhdGljIERIKiBkaEdlbmVyYXRlUGFyYW1ldGVycyhpbnQga2V5bGVuZ3RoKSB7CisKKyAgICAvKgorICAgICAqIFRoZSBTU0xfQ1RYX3NldF90bXBfZGhfY2FsbGJhY2soM1NTTCkgbWFuIHBhZ2UgZGlzY3Vzc2VzIHR3bworICAgICAqIGRpZmZlcmVudCBvcHRpb25zIGZvciBnZW5lcmF0aW5nIERIIGtleXMuIE9uZSBpcyBnZW5lcmF0aW5nIHRoZQorICAgICAqIGtleXMgdXNpbmcgYSBzaW5nbGUgc2V0IG9mIERIIHBhcmFtZXRlcnMuIEhvd2V2ZXIsIGdlbmVyYXRpbmcKKyAgICAgKiBESCBwYXJhbWV0ZXJzIGlzIHNsb3cgZW5vdWdoIChtaW51dGVzKSB0aGF0IHRoZXkgc3VnZ2VzdCBkb2luZworICAgICAqIGl0IG9uY2UgYXQgaW5zdGFsbCB0aW1lLiBUaGUgb3RoZXIgaXMgdG8gZ2VuZXJhdGUgREgga2V5cyBmcm9tCisgICAgICogRFNBIHBhcmFtZXRlcnMuIEdlbmVyYXRpbmcgRFNBIHBhcmFtZXRlcnMgaXMgZmFzdGVyIHRoYW4gREgKKyAgICAgKiBwYXJhbWV0ZXJzLCBidXQgdG8gcHJldmVudCBzbWFsbCBzdWJncm91cCBhdHRhY2tzLCB0aGV5IG5lZWRlZAorICAgICAqIHRvIGJlIHJlZ2VuZXJhdGVkIGZvciBlYWNoIHNldCBvZiBESCBrZXlzLiBTZXR0aW5nIHRoZQorICAgICAqIFNTTF9PUF9TSU5HTEVfREhfVVNFIG9wdGlvbiBtYWtlIHN1cmUgT3BlblNTTCB3aWxsIGNhbGwgYmFjaworICAgICAqIGZvciBuZXcgREggcGFyYW1ldGVycyBldmVyeSB0eXBlIGl0IG5lZWRzIHRvIGdlbmVyYXRlIERIIGtleXMuCisgICAgICovCisjaWYgMAorICAgIC8vIFNsb3cgcGF0aCB0aGF0IHRha2VzIG1pbnV0ZXMgYnV0IGNvdWxkIGJlIGNhY2hlZAorICAgIFVuaXF1ZV9ESCBkaChESF9uZXcoKSk7CisgICAgaWYgKCFESF9nZW5lcmF0ZV9wYXJhbWV0ZXJzX2V4KGRoLmdldCgpLCBrZXlsZW5ndGgsIDIsIE5VTEwpKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gZGgucmVsZWFzZSgpOworI2Vsc2UKKyAgICAvLyBGYXN0ZXIgcGF0aCBidXQgbXVzdCBoYXZlIFNTTF9PUF9TSU5HTEVfREhfVVNFIHNldAorICAgIFVuaXF1ZV9EU0EgZHNhKERTQV9uZXcoKSk7CisgICAgaWYgKCFEU0FfZ2VuZXJhdGVfcGFyYW1ldGVyc19leChkc2EuZ2V0KCksIGtleWxlbmd0aCwgTlVMTCwgMCwgTlVMTCwgTlVMTCwgTlVMTCkpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIERIKiBkaCA9IERTQV9kdXBfREgoZHNhLmdldCgpKTsKKyAgICByZXR1cm4gZGg7CisjZW5kaWYKK30KKworLyoqCisgKiBDYWxsIGJhY2sgdG8gYXNrIGZvciBEaWZmaWUtSGVsbG1hbiBwYXJhbWV0ZXJzCisgKi8KK3N0YXRpYyBESCogdG1wX2RoX2NhbGxiYWNrKFNTTCogc3NsIF9fYXR0cmlidXRlX18gKCh1bnVzZWQpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpc19leHBvcnQgX19hdHRyaWJ1dGVfXyAoKHVudXNlZCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGtleWxlbmd0aCkgeworICAgIEpOSV9UUkFDRSgic3NsPSVwIHRtcF9kaF9jYWxsYmFjayBpc19leHBvcnQ9JWQga2V5bGVuZ3RoPSVkIiwgc3NsLCBpc19leHBvcnQsIGtleWxlbmd0aCk7CisgICAgREgqIHRtcF9kaCA9IGRoR2VuZXJhdGVQYXJhbWV0ZXJzKGtleWxlbmd0aCk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgdG1wX2RoX2NhbGxiYWNrID0+ICVwIiwgc3NsLCB0bXBfZGgpOworICAgIHJldHVybiB0bXBfZGg7Cit9CisKK3N0YXRpYyBFQ19LRVkqIGVjR2VuZXJhdGVLZXkoaW50IGtleWxlbmd0aCBfX2F0dHJpYnV0ZV9fICgodW51c2VkKSkpIHsKKyAgICAvLyBUT0RPIHNlbGVjdGVkIGN1cnZlIGJhc2VkIG9uIGtleWxlbmd0aAorICAgIFVuaXF1ZV9FQ19LRVkgZWMoRUNfS0VZX25ld19ieV9jdXJ2ZV9uYW1lKE5JRF9YOV82Ml9wcmltZTI1NnYxKSk7CisgICAgaWYgKGVjLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBlYy5yZWxlYXNlKCk7Cit9CisKKy8qKgorICogQ2FsbCBiYWNrIHRvIGFzayBmb3IgYW4gZXBoZW1lcmFsIEVDIGtleSBmb3IgVExTX0VDREhFXyogY2lwaGVyIHN1aXRlcworICovCitzdGF0aWMgRUNfS0VZKiB0bXBfZWNkaF9jYWxsYmFjayhTU0wqIHNzbCBfX2F0dHJpYnV0ZV9fICgodW51c2VkKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaXNfZXhwb3J0IF9fYXR0cmlidXRlX18gKCh1bnVzZWQpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBrZXlsZW5ndGgpIHsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCB0bXBfZWNkaF9jYWxsYmFjayBpc19leHBvcnQ9JWQga2V5bGVuZ3RoPSVkIiwgc3NsLCBpc19leHBvcnQsIGtleWxlbmd0aCk7CisgICAgQXBwRGF0YSogYXBwRGF0YSA9IHRvQXBwRGF0YShzc2wpOworICAgIGlmIChhcHBEYXRhLT5lcGhlbWVyYWxFYy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIHRtcF9lY2RoX2NhbGxiYWNrIGdlbmVyYXRpbmcgZXBoZW1lcmFsIEVDIGtleSIsIHNzbCk7CisgICAgICAgIGFwcERhdGEtPmVwaGVtZXJhbEVjLnJlc2V0KGVjR2VuZXJhdGVLZXkoa2V5bGVuZ3RoKSk7CisgICAgfQorICAgIEpOSV9UUkFDRSgic3NsPSVwIHRtcF9lY2RoX2NhbGxiYWNrID0+ICVwIiwgc3NsLCBhcHBEYXRhLT5lcGhlbWVyYWxFYy5nZXQoKSk7CisgICAgcmV0dXJuIGFwcERhdGEtPmVwaGVtZXJhbEVjLmdldCgpOworfQorCisvKgorICogcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNTTF9DVFhfbmV3KCk7CisgKi8KK3N0YXRpYyBpbnQgTmF0aXZlQ3J5cHRvX1NTTF9DVFhfbmV3KEpOSUVudiogZW52LCBqY2xhc3MpIHsKKyAgICBVbmlxdWVfU1NMX0NUWCBzc2xDdHgoU1NMX0NUWF9uZXcoU1NMdjIzX21ldGhvZCgpKSk7CisgICAgaWYgKHNzbEN0eC5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIGpuaVRocm93UnVudGltZUV4Y2VwdGlvbihlbnYsICJTU0xfQ1RYX25ldyIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgU1NMX0NUWF9zZXRfb3B0aW9ucyhzc2xDdHguZ2V0KCksCisgICAgICAgICAgICAgICAgICAgICAgICBTU0xfT1BfQUxMCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3RlOiBXZSBleHBsaWNpdGx5IGRvIG5vdCBhbGxvdyBTU0x2MiB0byBiZSB1c2VkLgorICAgICAgICAgICAgICAgICAgICAgICAgfCBTU0xfT1BfTk9fU1NMdjIKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIGFsc28gZGlzYWJsZSBzZXNzaW9uIHRpY2tldHMgZm9yIGJldHRlciBjb21wYXRpYmlsaXR5IGIvMjY4Mjg3NgorICAgICAgICAgICAgICAgICAgICAgICAgfCBTU0xfT1BfTk9fVElDS0VUCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBhbHNvIGRpc2FibGUgY29tcHJlc3Npb24gZm9yIGJldHRlciBjb21wYXRpYmlsaXR5IGIvMjcxMDQ5MiBiLzI3MTA0OTcKKyAgICAgICAgICAgICAgICAgICAgICAgIHwgU1NMX09QX05PX0NPTVBSRVNTSU9OCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBCZWNhdXNlIGRoR2VuZXJhdGVQYXJhbWV0ZXJzIHVzZXMgRFNBX2dlbmVyYXRlX3BhcmFtZXRlcnNfZXgKKyAgICAgICAgICAgICAgICAgICAgICAgIHwgU1NMX09QX1NJTkdMRV9ESF9VU0UKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJlY2F1c2UgZWNHZW5lcmF0ZVBhcmFtZXRlcnMgdXNlcyBhIGZpeGVkIG5hbWVkIGN1cnZlCisgICAgICAgICAgICAgICAgICAgICAgICB8IFNTTF9PUF9TSU5HTEVfRUNESF9VU0UpOworCisgICAgaW50IG1vZGUgPSBTU0xfQ1RYX2dldF9tb2RlKHNzbEN0eC5nZXQoKSk7CisgICAgLyoKKyAgICAgKiBUdXJuIG9uICJwYXJ0aWFsIHdyaXRlIiBtb2RlLiBUaGlzIG1lYW5zIHRoYXQgU1NMX3dyaXRlKCkgd2lsbAorICAgICAqIGJlaGF2ZSBsaWtlIFBvc2l4IHdyaXRlKCkgYW5kIHBvc3NpYmx5IHJldHVybiBhZnRlciBvbmx5CisgICAgICogd3JpdGluZyBhIHBhcnRpYWwgYnVmZmVyLiBOb3RlOiBUaGUgYWx0ZXJuYXRpdmUsIHBlcmhhcHMKKyAgICAgKiBzdXJwcmlzaW5nbHksIGlzIG5vdCB0aGF0IFNTTF93cml0ZSgpIGFsd2F5cyBkb2VzIGZ1bGwgd3JpdGVzCisgICAgICogYnV0IHRoYXQgaXQgd2lsbCBmb3JjZSB5b3UgdG8gcmV0cnkgd3JpdGUgY2FsbHMgaGF2aW5nCisgICAgICogcHJlc2VydmVkIHRoZSBmdWxsIHN0YXRlIG9mIHRoZSBvcmlnaW5hbCBjYWxsLiAoVGhpcyBpcyBpY2t5CisgICAgICogYW5kIHVuZGVzaXJhYmxlLikKKyAgICAgKi8KKyAgICBtb2RlIHw9IFNTTF9NT0RFX0VOQUJMRV9QQVJUSUFMX1dSSVRFOworI2lmIGRlZmluZWQoU1NMX01PREVfU01BTExfQlVGRkVSUykgLyogbm90IGFsbCBTU0wgdmVyc2lvbnMgaGF2ZSB0aGlzICovCisgICAgbW9kZSB8PSBTU0xfTU9ERV9TTUFMTF9CVUZGRVJTOyAgLyogbGF6aWx5IGFsbG9jYXRlIHJlY29yZCBidWZmZXJzOyB1c3VhbGx5IHNhdmVzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogNDRrIG92ZXIgdGhlIGRlZmF1bHQgKi8KKyNlbmRpZgorI2lmIGRlZmluZWQoU1NMX01PREVfSEFORFNIQUtFX0NVVFRIUk9VR0gpIC8qIG5vdCBhbGwgU1NMIHZlcnNpb25zIGhhdmUgdGhpcyAqLworICAgIG1vZGUgfD0gU1NMX01PREVfSEFORFNIQUtFX0NVVFRIUk9VR0g7ICAvKiBlbmFibGUgc2VuZGluZyBvZiBjbGllbnQgZGF0YSBhcyBzb29uIGFzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIENsaWVudENDUyBhbmQgQ2xpZW50RmluaXNoZWQgYXJlIHNlbnQgKi8KKyNlbmRpZgorICAgIFNTTF9DVFhfc2V0X21vZGUoc3NsQ3R4LmdldCgpLCBtb2RlKTsKKworICAgIFNTTF9DVFhfc2V0X2NlcnRfdmVyaWZ5X2NhbGxiYWNrKHNzbEN0eC5nZXQoKSwgY2VydF92ZXJpZnlfY2FsbGJhY2ssIE5VTEwpOworICAgIFNTTF9DVFhfc2V0X2luZm9fY2FsbGJhY2soc3NsQ3R4LmdldCgpLCBpbmZvX2NhbGxiYWNrKTsKKyAgICBTU0xfQ1RYX3NldF9jbGllbnRfY2VydF9jYihzc2xDdHguZ2V0KCksIGNsaWVudF9jZXJ0X2NiKTsKKyAgICBTU0xfQ1RYX3NldF90bXBfcnNhX2NhbGxiYWNrKHNzbEN0eC5nZXQoKSwgdG1wX3JzYV9jYWxsYmFjayk7CisgICAgU1NMX0NUWF9zZXRfdG1wX2RoX2NhbGxiYWNrKHNzbEN0eC5nZXQoKSwgdG1wX2RoX2NhbGxiYWNrKTsKKyAgICBTU0xfQ1RYX3NldF90bXBfZWNkaF9jYWxsYmFjayhzc2xDdHguZ2V0KCksIHRtcF9lY2RoX2NhbGxiYWNrKTsKKworICAgIEpOSV9UUkFDRSgiTmF0aXZlQ3J5cHRvX1NTTF9DVFhfbmV3ID0+ICVwIiwgc3NsQ3R4LmdldCgpKTsKKyAgICByZXR1cm4gKGppbnQpIHNzbEN0eC5yZWxlYXNlKCk7Cit9CisKKy8qKgorICogcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTU0xfQ1RYX2ZyZWUoaW50IHNzbF9jdHgpCisgKi8KK3N0YXRpYyB2b2lkIE5hdGl2ZUNyeXB0b19TU0xfQ1RYX2ZyZWUoSk5JRW52KiBlbnYsCisgICAgICAgIGpjbGFzcywgamludCBzc2xfY3R4X2FkZHJlc3MpCit7CisgICAgU1NMX0NUWCogc3NsX2N0eCA9IHRvX1NTTF9DVFgoZW52LCBzc2xfY3R4X2FkZHJlc3MsIHRydWUpOworICAgIEpOSV9UUkFDRSgic3NsX2N0eD0lcCBOYXRpdmVDcnlwdG9fU1NMX0NUWF9mcmVlIiwgc3NsX2N0eCk7CisgICAgaWYgKHNzbF9jdHggPT0gTlVMTCkgeworICAgICAgICByZXR1cm47CisgICAgfQorICAgIFNTTF9DVFhfZnJlZShzc2xfY3R4KTsKK30KKworLyoqCisgKiBwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgU1NMX25ldyhpbnQgc3NsX2N0eCkgdGhyb3dzIFNTTEV4Y2VwdGlvbjsKKyAqLworc3RhdGljIGppbnQgTmF0aXZlQ3J5cHRvX1NTTF9uZXcoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBzc2xfY3R4X2FkZHJlc3MpCit7CisgICAgU1NMX0NUWCogc3NsX2N0eCA9IHRvX1NTTF9DVFgoZW52LCBzc2xfY3R4X2FkZHJlc3MsIHRydWUpOworICAgIEpOSV9UUkFDRSgic3NsX2N0eD0lcCBOYXRpdmVDcnlwdG9fU1NMX25ldyIsIHNzbF9jdHgpOworICAgIGlmIChzc2xfY3R4ID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIFVuaXF1ZV9TU0wgc3NsKFNTTF9uZXcoc3NsX2N0eCkpOworICAgIGlmIChzc2wuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICB0aHJvd1NTTEV4Y2VwdGlvbldpdGhTc2xFcnJvcnMoZW52LCBOVUxMLCBTU0xfRVJST1JfTk9ORSwKKyAgICAgICAgICAgICAgICAiVW5hYmxlIHRvIGNyZWF0ZSBTU0wgc3RydWN0dXJlIik7CisgICAgICAgIEpOSV9UUkFDRSgic3NsX2N0eD0lcCBOYXRpdmVDcnlwdG9fU1NMX25ldyA9PiBOVUxMIiwgc3NsX2N0eCk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qIEphdmEgY29kZSBpbiBjbGFzcyBPcGVuU1NMU29ja2V0SW1wbCBkb2VzIHRoZSB2ZXJpZmljYXRpb24uIE1lYW5pbmcgb2YKKyAgICAgKiBTU0xfVkVSSUZZX05PTkUgZmxhZyBpbiBjbGllbnQgbW9kZTogaWYgbm90IHVzaW5nIGFuIGFub255bW91cyBjaXBoZXIKKyAgICAgKiAoYnkgZGVmYXVsdCBkaXNhYmxlZCksIHRoZSBzZXJ2ZXIgd2lsbCBzZW5kIGEgY2VydGlmaWNhdGUgd2hpY2ggd2lsbAorICAgICAqIGJlIGNoZWNrZWQuIFRoZSByZXN1bHQgb2YgdGhlIGNlcnRpZmljYXRlIHZlcmlmaWNhdGlvbiBwcm9jZXNzIGNhbiBiZQorICAgICAqIGNoZWNrZWQgYWZ0ZXIgdGhlIFRMUy9TU0wgaGFuZHNoYWtlIHVzaW5nIHRoZSBTU0xfZ2V0X3ZlcmlmeV9yZXN1bHQoMykKKyAgICAgKiBmdW5jdGlvbi4gVGhlIGhhbmRzaGFrZSB3aWxsIGJlIGNvbnRpbnVlZCByZWdhcmRsZXNzIG9mIHRoZQorICAgICAqIHZlcmlmaWNhdGlvbiByZXN1bHQuCisgICAgICovCisgICAgU1NMX3NldF92ZXJpZnkoc3NsLmdldCgpLCBTU0xfVkVSSUZZX05PTkUsIE5VTEwpOworCisgICAgSk5JX1RSQUNFKCJzc2xfY3R4PSVwIE5hdGl2ZUNyeXB0b19TU0xfbmV3ID0+IHNzbD0lcCIsIHNzbF9jdHgsIHNzbC5nZXQoKSk7CisgICAgcmV0dXJuIChqaW50KSBzc2wucmVsZWFzZSgpOworfQorCitzdGF0aWMgdm9pZCBOYXRpdmVDcnlwdG9fU1NMX3VzZV9Qcml2YXRlS2V5KEpOSUVudiogZW52LCBqY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppbnQgc3NsX2FkZHJlc3MsIGpieXRlQXJyYXkgcHJpdmF0ZWtleSkKK3sKKyAgICBTU0wqIHNzbCA9IHRvX1NTTChlbnYsIHNzbF9hZGRyZXNzLCB0cnVlKTsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3VzZV9Qcml2YXRlS2V5IHByaXZhdGVrZXk9JXAiLCBzc2wsIHByaXZhdGVrZXkpOworICAgIGlmIChzc2wgPT0gTlVMTCkgeworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgU2NvcGVkQnl0ZUFycmF5Uk8gYnVmKGVudiwgcHJpdmF0ZWtleSk7CisgICAgaWYgKGJ1Zi5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfdXNlX1ByaXZhdGVLZXkgPT4gdGhyZXcgZXhjZXB0aW9uIiwgc3NsKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBjb25zdCB1bnNpZ25lZCBjaGFyKiB0bXAgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihidWYuZ2V0KCkpOworICAgIFVuaXF1ZV9QS0NTOF9QUklWX0tFWV9JTkZPIHBrY3M4KGQyaV9QS0NTOF9QUklWX0tFWV9JTkZPKE5VTEwsICZ0bXAsIGJ1Zi5zaXplKCkpKTsKKyAgICBpZiAocGtjczguZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICBMT0dFKCIlcyIsIEVSUl9lcnJvcl9zdHJpbmcoRVJSX3BlZWtfZXJyb3IoKSwgTlVMTCkpOworICAgICAgICB0aHJvd1NTTEV4Y2VwdGlvbldpdGhTc2xFcnJvcnMoZW52LCBzc2wsIFNTTF9FUlJPUl9OT05FLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVycm9yIHBhcnNpbmcgcHJpdmF0ZSBrZXkgZnJvbSBERVIgdG8gUEtDUzgiKTsKKyAgICAgICAgU1NMX2NsZWFyKHNzbCk7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfdXNlX1ByaXZhdGVLZXkgPT4gZXJyb3IgZnJvbSBERVIgdG8gUEtDUzgiLCBzc2wpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgVW5pcXVlX0VWUF9QS0VZIHByaXZhdGVrZXlldnAoRVZQX1BLQ1M4MlBLRVkocGtjczguZ2V0KCkpKTsKKyAgICBpZiAocHJpdmF0ZWtleWV2cC5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIExPR0UoIiVzIiwgRVJSX2Vycm9yX3N0cmluZyhFUlJfcGVla19lcnJvcigpLCBOVUxMKSk7CisgICAgICAgIHRocm93U1NMRXhjZXB0aW9uV2l0aFNzbEVycm9ycyhlbnYsIHNzbCwgU1NMX0VSUk9SX05PTkUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRXJyb3IgY3JlYXRpbmcgcHJpdmF0ZSBrZXkgZnJvbSBQS0NTOCIpOworICAgICAgICBTU0xfY2xlYXIoc3NsKTsKKyAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF91c2VfUHJpdmF0ZUtleSA9PiBlcnJvciBmcm9tIFBLQ1M4IHRvIGtleSIsIHNzbCk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3VzZV9Qcml2YXRlS2V5IEVWUF9QS0VZX3R5cGU9JWQiLAorICAgICAgICAgICAgICBzc2wsIEVWUF9QS0VZX3R5cGUocHJpdmF0ZWtleWV2cC5nZXQoKS0+dHlwZSkpOworICAgIGludCByZXQgPSBTU0xfdXNlX1ByaXZhdGVLZXkoc3NsLCBwcml2YXRla2V5ZXZwLmdldCgpKTsKKyAgICBpZiAocmV0ID09IDEpIHsKKyAgICAgICAgT1dORVJTSElQX1RSQU5TRkVSUkVEKHByaXZhdGVrZXlldnApOworICAgIH0gZWxzZSB7CisgICAgICAgIExPR0UoIiVzIiwgRVJSX2Vycm9yX3N0cmluZyhFUlJfcGVla19lcnJvcigpLCBOVUxMKSk7CisgICAgICAgIHRocm93U1NMRXhjZXB0aW9uV2l0aFNzbEVycm9ycyhlbnYsIHNzbCwgU1NMX0VSUk9SX05PTkUsICJFcnJvciBzZXR0aW5nIHByaXZhdGUga2V5Iik7CisgICAgICAgIFNTTF9jbGVhcihzc2wpOworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3VzZV9Qcml2YXRlS2V5ID0+IGVycm9yIiwgc3NsKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfdXNlX1ByaXZhdGVLZXkgPT4gb2siLCBzc2wpOworfQorCitzdGF0aWMgdm9pZCBOYXRpdmVDcnlwdG9fU1NMX3VzZV9jZXJ0aWZpY2F0ZShKTklFbnYqIGVudiwgamNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamludCBzc2xfYWRkcmVzcywgam9iamVjdEFycmF5IGNlcnRpZmljYXRlcykKK3sKKyAgICBTU0wqIHNzbCA9IHRvX1NTTChlbnYsIHNzbF9hZGRyZXNzLCB0cnVlKTsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3VzZV9jZXJ0aWZpY2F0ZSBjZXJ0aWZpY2F0ZXM9JXAiLCBzc2wsIGNlcnRpZmljYXRlcyk7CisgICAgaWYgKHNzbCA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAoY2VydGlmaWNhdGVzID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsICJjZXJ0aWZpY2F0ZXMgPT0gbnVsbCIpOworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3VzZV9jZXJ0aWZpY2F0ZSA9PiBjZXJ0aWZpY2F0ZXMgPT0gbnVsbCIsIHNzbCk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpbnQgbGVuZ3RoID0gZW52LT5HZXRBcnJheUxlbmd0aChjZXJ0aWZpY2F0ZXMpOworICAgIGlmIChsZW5ndGggPT0gMCkgeworICAgICAgICBqbmlUaHJvd0V4Y2VwdGlvbihlbnYsICJqYXZhL2xhbmcvSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIiwgImNlcnRpZmljYXRlcy5sZW5ndGggPT0gMCIpOworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3VzZV9jZXJ0aWZpY2F0ZSA9PiBjZXJ0aWZpY2F0ZXMubGVuZ3RoID09IDAiLCBzc2wpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgVW5pcXVlX1g1MDkgY2VydGlmaWNhdGVzWDUwOVtsZW5ndGhdOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgU2NvcGVkTG9jYWxSZWY8amJ5dGVBcnJheT4gY2VydGlmaWNhdGUoZW52LAorICAgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8amJ5dGVBcnJheT4oZW52LT5HZXRPYmplY3RBcnJheUVsZW1lbnQoY2VydGlmaWNhdGVzLCBpKSkpOworICAgICAgICBpZiAoY2VydGlmaWNhdGUuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsICJjZXJ0aWZpY2F0ZXMgZWxlbWVudCA9PSBudWxsIik7CisgICAgICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3VzZV9jZXJ0aWZpY2F0ZSA9PiBjZXJ0aWZpY2F0ZXMgZWxlbWVudCBudWxsIiwgc3NsKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIFNjb3BlZEJ5dGVBcnJheVJPIGJ1ZihlbnYsIGNlcnRpZmljYXRlLmdldCgpKTsKKyAgICAgICAgaWYgKGJ1Zi5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3VzZV9jZXJ0aWZpY2F0ZSA9PiB0aHJldyBleGNlcHRpb24iLCBzc2wpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIqIHRtcCA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdW5zaWduZWQgY2hhcio+KGJ1Zi5nZXQoKSk7CisgICAgICAgIGNlcnRpZmljYXRlc1g1MDlbaV0ucmVzZXQoZDJpX1g1MDkoTlVMTCwgJnRtcCwgYnVmLnNpemUoKSkpOworCisgICAgICAgIGlmIChjZXJ0aWZpY2F0ZXNYNTA5W2ldLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgICAgIExPR0UoIiVzIiwgRVJSX2Vycm9yX3N0cmluZyhFUlJfcGVla19lcnJvcigpLCBOVUxMKSk7CisgICAgICAgICAgICB0aHJvd1NTTEV4Y2VwdGlvbldpdGhTc2xFcnJvcnMoZW52LCBzc2wsIFNTTF9FUlJPUl9OT05FLCAiRXJyb3IgcGFyc2luZyBjZXJ0aWZpY2F0ZSIpOworICAgICAgICAgICAgU1NMX2NsZWFyKHNzbCk7CisgICAgICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3VzZV9jZXJ0aWZpY2F0ZSA9PiBjZXJ0aWZpY2F0ZXMgcGFyc2luZyBlcnJvciIsIHNzbCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICB9CisKKyAgICBpbnQgcmV0ID0gU1NMX3VzZV9jZXJ0aWZpY2F0ZShzc2wsIGNlcnRpZmljYXRlc1g1MDlbMF0uZ2V0KCkpOworICAgIGlmIChyZXQgPT0gMSkgeworICAgICAgICBPV05FUlNISVBfVFJBTlNGRVJSRUQoY2VydGlmaWNhdGVzWDUwOVswXSk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgTE9HRSgiJXMiLCBFUlJfZXJyb3Jfc3RyaW5nKEVSUl9wZWVrX2Vycm9yKCksIE5VTEwpKTsKKyAgICAgICAgdGhyb3dTU0xFeGNlcHRpb25XaXRoU3NsRXJyb3JzKGVudiwgc3NsLCBTU0xfRVJST1JfTk9ORSwgIkVycm9yIHNldHRpbmcgY2VydGlmaWNhdGUiKTsKKyAgICAgICAgU1NMX2NsZWFyKHNzbCk7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfdXNlX2NlcnRpZmljYXRlID0+IFNTTF91c2VfY2VydGlmaWNhdGUgZXJyb3IiLCBzc2wpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgVW5pcXVlX3NrX1g1MDkgY2hhaW4oc2tfWDUwOV9uZXdfbnVsbCgpKTsKKyAgICBpZiAoY2hhaW4uZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd091dE9mTWVtb3J5RXJyb3IoZW52LCAiVW5hYmxlIHRvIGFsbG9jYXRlIGxvY2FsIGNlcnRpZmljYXRlIGNoYWluIik7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfdXNlX2NlcnRpZmljYXRlID0+IGNoYWluIGFsbG9jYXRpb24gZXJyb3IiLCBzc2wpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGZvciAoaW50IGkgPSAxOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgaWYgKCFza19YNTA5X3B1c2goY2hhaW4uZ2V0KCksIGNlcnRpZmljYXRlc1g1MDlbaV0ucmVsZWFzZSgpKSkgeworICAgICAgICAgICAgam5pVGhyb3dPdXRPZk1lbW9yeUVycm9yKGVudiwgIlVuYWJsZSB0byBwdXNoIGNlcnRpZmljYXRlIik7CisgICAgICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3VzZV9jZXJ0aWZpY2F0ZSA9PiBjZXJ0aWZpY2F0ZSBwdXNoIGVycm9yIiwgc3NsKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KKyAgICBpbnQgY2hhaW5SZXN1bHQgPSBTU0xfdXNlX2NlcnRpZmljYXRlX2NoYWluKHNzbCwgY2hhaW4uZ2V0KCkpOworICAgIGlmIChjaGFpblJlc3VsdCA9PSAwKSB7CisgICAgICAgIHRocm93U1NMRXhjZXB0aW9uV2l0aFNzbEVycm9ycyhlbnYsIHNzbCwgU1NMX0VSUk9SX05PTkUsICJFcnJvciBzZXR0aW5nIGNlcnRpZmljYXRlIGNoYWluIik7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfdXNlX2NlcnRpZmljYXRlID0+IFNTTF91c2VfY2VydGlmaWNhdGVfY2hhaW4gZXJyb3IiLAorICAgICAgICAgICAgICAgICAgc3NsKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0gZWxzZSB7CisgICAgICAgIE9XTkVSU0hJUF9UUkFOU0ZFUlJFRChjaGFpbik7CisgICAgfQorCisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF91c2VfY2VydGlmaWNhdGUgPT4gb2siLCBzc2wpOworfQorCitzdGF0aWMgdm9pZCBOYXRpdmVDcnlwdG9fU1NMX2NoZWNrX3ByaXZhdGVfa2V5KEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgc3NsX2FkZHJlc3MpCit7CisgICAgU1NMKiBzc2wgPSB0b19TU0woZW52LCBzc2xfYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9jaGVja19wcml2YXRlX2tleSIsIHNzbCk7CisgICAgaWYgKHNzbCA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaW50IHJldCA9IFNTTF9jaGVja19wcml2YXRlX2tleShzc2wpOworICAgIGlmIChyZXQgIT0gMSkgeworICAgICAgICB0aHJvd1NTTEV4Y2VwdGlvbldpdGhTc2xFcnJvcnMoZW52LCBzc2wsIFNTTF9FUlJPUl9OT05FLCAiRXJyb3IgY2hlY2tpbmcgcHJpdmF0ZSBrZXkiKTsKKyAgICAgICAgU1NMX2NsZWFyKHNzbCk7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfY2hlY2tfcHJpdmF0ZV9rZXkgPT4gZXJyb3IiLCBzc2wpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfY2hlY2tfcHJpdmF0ZV9rZXkgPT4gb2siLCBzc2wpOworfQorCitzdGF0aWMgdm9pZCBOYXRpdmVDcnlwdG9fU1NMX3NldF9jbGllbnRfQ0FfbGlzdChKTklFbnYqIGVudiwgamNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamludCBzc2xfYWRkcmVzcywgam9iamVjdEFycmF5IHByaW5jaXBhbHMpCit7CisgICAgU1NMKiBzc2wgPSB0b19TU0woZW52LCBzc2xfYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9zZXRfY2xpZW50X0NBX2xpc3QgcHJpbmNpcGFscz0lcCIsIHNzbCwgcHJpbmNpcGFscyk7CisgICAgaWYgKHNzbCA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAocHJpbmNpcGFscyA9PSBOVUxMKSB7CisgICAgICAgIGpuaVRocm93TnVsbFBvaW50ZXJFeGNlcHRpb24oZW52LCAicHJpbmNpcGFscyA9PSBudWxsIik7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfc2V0X2NsaWVudF9DQV9saXN0ID0+IHByaW5jaXBhbHMgPT0gbnVsbCIsIHNzbCk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpbnQgbGVuZ3RoID0gZW52LT5HZXRBcnJheUxlbmd0aChwcmluY2lwYWxzKTsKKyAgICBpZiAobGVuZ3RoID09IDApIHsKKyAgICAgICAgam5pVGhyb3dFeGNlcHRpb24oZW52LCAiamF2YS9sYW5nL0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIsICJwcmluY2lwYWxzLmxlbmd0aCA9PSAwIik7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfc2V0X2NsaWVudF9DQV9saXN0ID0+IHByaW5jaXBhbHMubGVuZ3RoID09IDAiLCBzc2wpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgVW5pcXVlX3NrX1g1MDlfTkFNRSBwcmluY2lwYWxzU3RhY2soc2tfWDUwOV9OQU1FX25ld19udWxsKCkpOworICAgIGlmIChwcmluY2lwYWxzU3RhY2suZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd091dE9mTWVtb3J5RXJyb3IoZW52LCAiVW5hYmxlIHRvIGFsbG9jYXRlIHByaW5jaXBhbCBzdGFjayIpOworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3NldF9jbGllbnRfQ0FfbGlzdCA9PiBzdGFjayBhbGxvY2F0aW9uIGVycm9yIiwgc3NsKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgIFNjb3BlZExvY2FsUmVmPGpieXRlQXJyYXk+IHByaW5jaXBhbChlbnYsCisgICAgICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxqYnl0ZUFycmF5PihlbnYtPkdldE9iamVjdEFycmF5RWxlbWVudChwcmluY2lwYWxzLCBpKSkpOworICAgICAgICBpZiAocHJpbmNpcGFsLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgICAgIGpuaVRocm93TnVsbFBvaW50ZXJFeGNlcHRpb24oZW52LCAicHJpbmNpcGFscyBlbGVtZW50ID09IG51bGwiKTsKKyAgICAgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfc2V0X2NsaWVudF9DQV9saXN0ID0+IHByaW5jaXBhbHMgZWxlbWVudCBudWxsIiwgc3NsKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIFNjb3BlZEJ5dGVBcnJheVJPIGJ1ZihlbnYsIHByaW5jaXBhbC5nZXQoKSk7CisgICAgICAgIGlmIChidWYuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9zZXRfY2xpZW50X0NBX2xpc3QgPT4gdGhyZXcgZXhjZXB0aW9uIiwgc3NsKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBjb25zdCB1bnNpZ25lZCBjaGFyKiB0bXAgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihidWYuZ2V0KCkpOworICAgICAgICBVbmlxdWVfWDUwOV9OQU1FIHByaW5jaXBhbFg1MDlOYW1lKGQyaV9YNTA5X05BTUUoTlVMTCwgJnRtcCwgYnVmLnNpemUoKSkpOworCisgICAgICAgIGlmIChwcmluY2lwYWxYNTA5TmFtZS5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgICAgICBMT0dFKCIlcyIsIEVSUl9lcnJvcl9zdHJpbmcoRVJSX3BlZWtfZXJyb3IoKSwgTlVMTCkpOworICAgICAgICAgICAgdGhyb3dTU0xFeGNlcHRpb25XaXRoU3NsRXJyb3JzKGVudiwgc3NsLCBTU0xfRVJST1JfTk9ORSwgIkVycm9yIHBhcnNpbmcgcHJpbmNpcGFsIik7CisgICAgICAgICAgICBTU0xfY2xlYXIoc3NsKTsKKyAgICAgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfc2V0X2NsaWVudF9DQV9saXN0ID0+IHByaW5jaXBhbHMgcGFyc2luZyBlcnJvciIsCisgICAgICAgICAgICAgICAgICAgICAgc3NsKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghc2tfWDUwOV9OQU1FX3B1c2gocHJpbmNpcGFsc1N0YWNrLmdldCgpLCBwcmluY2lwYWxYNTA5TmFtZS5yZWxlYXNlKCkpKSB7CisgICAgICAgICAgICBqbmlUaHJvd091dE9mTWVtb3J5RXJyb3IoZW52LCAiVW5hYmxlIHRvIHB1c2ggcHJpbmNpcGFsIik7CisgICAgICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3NldF9jbGllbnRfQ0FfbGlzdCA9PiBwcmluY2lwYWwgcHVzaCBlcnJvciIsIHNzbCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICB9CisKKyAgICBTU0xfc2V0X2NsaWVudF9DQV9saXN0KHNzbCwgcHJpbmNpcGFsc1N0YWNrLnJlbGVhc2UoKSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9zZXRfY2xpZW50X0NBX2xpc3QgPT4gb2siLCBzc2wpOworfQorCisvKioKKyAqIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGxvbmcgU1NMX2dldF9tb2RlKGludCBzc2wpOworICovCitzdGF0aWMgamxvbmcgTmF0aXZlQ3J5cHRvX1NTTF9nZXRfbW9kZShKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IHNzbF9hZGRyZXNzKSB7CisgICAgU1NMKiBzc2wgPSB0b19TU0woZW52LCBzc2xfYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9nZXRfbW9kZSIsIHNzbCk7CisgICAgaWYgKHNzbCA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgbG9uZyBtb2RlID0gU1NMX2dldF9tb2RlKHNzbCk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9nZXRfbW9kZSA9PiAweCVseCIsIHNzbCwgbW9kZSk7CisgICAgcmV0dXJuIG1vZGU7Cit9CisKKy8qKgorICogcHVibGljIHN0YXRpYyBuYXRpdmUgbG9uZyBTU0xfc2V0X21vZGUoaW50IHNzbCwgbG9uZyBtb2RlKTsKKyAqLworc3RhdGljIGpsb25nIE5hdGl2ZUNyeXB0b19TU0xfc2V0X21vZGUoSk5JRW52KiBlbnYsIGpjbGFzcywKKyAgICAgICAgamludCBzc2xfYWRkcmVzcywgamxvbmcgbW9kZSkgeworICAgIFNTTCogc3NsID0gdG9fU1NMKGVudiwgc3NsX2FkZHJlc3MsIHRydWUpOworICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfc2V0X21vZGUgbW9kZT0weCVsbHgiLCBzc2wsIG1vZGUpOworICAgIGlmIChzc2wgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGxvbmcgcmVzdWx0ID0gU1NMX3NldF9tb2RlKHNzbCwgbW9kZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9zZXRfbW9kZSA9PiAweCVseCIsIHNzbCwgcmVzdWx0KTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKioKKyAqIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGxvbmcgU1NMX2NsZWFyX21vZGUoaW50IHNzbCwgbG9uZyBtb2RlKTsKKyAqLworc3RhdGljIGpsb25nIE5hdGl2ZUNyeXB0b19TU0xfY2xlYXJfbW9kZShKTklFbnYqIGVudiwgamNsYXNzLAorICAgICAgICBqaW50IHNzbF9hZGRyZXNzLCBqbG9uZyBtb2RlKSB7CisgICAgU1NMKiBzc2wgPSB0b19TU0woZW52LCBzc2xfYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9jbGVhcl9tb2RlIG1vZGU9MHglbGx4Iiwgc3NsLCBtb2RlKTsKKyAgICBpZiAoc3NsID09IE5VTEwpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBsb25nIHJlc3VsdCA9IFNTTF9jbGVhcl9tb2RlKHNzbCwgbW9kZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9jbGVhcl9tb2RlID0+IDB4JWx4Iiwgc3NsLCByZXN1bHQpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qKgorICogcHVibGljIHN0YXRpYyBuYXRpdmUgbG9uZyBTU0xfZ2V0X29wdGlvbnMoaW50IHNzbCk7CisgKi8KK3N0YXRpYyBqbG9uZyBOYXRpdmVDcnlwdG9fU1NMX2dldF9vcHRpb25zKEpOSUVudiogZW52LCBqY2xhc3MsCisgICAgICAgIGppbnQgc3NsX2FkZHJlc3MpIHsKKyAgICBTU0wqIHNzbCA9IHRvX1NTTChlbnYsIHNzbF9hZGRyZXNzLCB0cnVlKTsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX2dldF9vcHRpb25zIiwgc3NsKTsKKyAgICBpZiAoc3NsID09IE5VTEwpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBsb25nIG9wdGlvbnMgPSBTU0xfZ2V0X29wdGlvbnMoc3NsKTsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX2dldF9vcHRpb25zID0+IDB4JWx4Iiwgc3NsLCBvcHRpb25zKTsKKyAgICByZXR1cm4gb3B0aW9uczsKK30KKworLyoqCisgKiBwdWJsaWMgc3RhdGljIG5hdGl2ZSBsb25nIFNTTF9zZXRfb3B0aW9ucyhpbnQgc3NsLCBsb25nIG9wdGlvbnMpOworICovCitzdGF0aWMgamxvbmcgTmF0aXZlQ3J5cHRvX1NTTF9zZXRfb3B0aW9ucyhKTklFbnYqIGVudiwgamNsYXNzLAorICAgICAgICBqaW50IHNzbF9hZGRyZXNzLCBqbG9uZyBvcHRpb25zKSB7CisgICAgU1NMKiBzc2wgPSB0b19TU0woZW52LCBzc2xfYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9zZXRfb3B0aW9ucyBvcHRpb25zPTB4JWxseCIsIHNzbCwgb3B0aW9ucyk7CisgICAgaWYgKHNzbCA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgbG9uZyByZXN1bHQgPSBTU0xfc2V0X29wdGlvbnMoc3NsLCBvcHRpb25zKTsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3NldF9vcHRpb25zID0+IDB4JWx4Iiwgc3NsLCByZXN1bHQpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qKgorICogcHVibGljIHN0YXRpYyBuYXRpdmUgbG9uZyBTU0xfY2xlYXJfb3B0aW9ucyhpbnQgc3NsLCBsb25nIG9wdGlvbnMpOworICovCitzdGF0aWMgamxvbmcgTmF0aXZlQ3J5cHRvX1NTTF9jbGVhcl9vcHRpb25zKEpOSUVudiogZW52LCBqY2xhc3MsCisgICAgICAgIGppbnQgc3NsX2FkZHJlc3MsIGpsb25nIG9wdGlvbnMpIHsKKyAgICBTU0wqIHNzbCA9IHRvX1NTTChlbnYsIHNzbF9hZGRyZXNzLCB0cnVlKTsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX2NsZWFyX29wdGlvbnMgb3B0aW9ucz0weCVsbHgiLCBzc2wsIG9wdGlvbnMpOworICAgIGlmIChzc2wgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGxvbmcgcmVzdWx0ID0gU1NMX2NsZWFyX29wdGlvbnMoc3NsLCBvcHRpb25zKTsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX2NsZWFyX29wdGlvbnMgPT4gMHglbHgiLCBzc2wsIHJlc3VsdCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyoqCisgKiBTZXRzIHRoZSBjaXBoZXJzIHN1aXRlcyB0aGF0IGFyZSBlbmFibGVkIGluIHRoZSBTU0wKKyAqLworc3RhdGljIHZvaWQgTmF0aXZlQ3J5cHRvX1NTTF9zZXRfY2lwaGVyX2xpc3RzKEpOSUVudiogZW52LCBqY2xhc3MsCisgICAgICAgIGppbnQgc3NsX2FkZHJlc3MsIGpvYmplY3RBcnJheSBjaXBoZXJTdWl0ZXMpCit7CisgICAgU1NMKiBzc2wgPSB0b19TU0woZW52LCBzc2xfYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9zZXRfY2lwaGVyX2xpc3RzIGNpcGhlclN1aXRlcz0lcCIsIHNzbCwgY2lwaGVyU3VpdGVzKTsKKyAgICBpZiAoc3NsID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoY2lwaGVyU3VpdGVzID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsICJjaXBoZXJTdWl0ZXMgPT0gbnVsbCIpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgVW5pcXVlX3NrX1NTTF9DSVBIRVIgY2lwaGVyc3RhY2soc2tfU1NMX0NJUEhFUl9uZXdfbnVsbCgpKTsKKyAgICBpZiAoY2lwaGVyc3RhY2suZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd1J1bnRpbWVFeGNlcHRpb24oZW52LCAic2tfU1NMX0NJUEhFUl9uZXdfbnVsbCBmYWlsZWQiKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGNvbnN0IFNTTF9NRVRIT0QqIHNzbF9tZXRob2QgPSBzc2wtPm1ldGhvZDsKKyAgICBpbnQgbnVtX2NpcGhlcnMgPSBzc2xfbWV0aG9kLT5udW1fY2lwaGVycygpOworCisgICAgaW50IGxlbmd0aCA9IGVudi0+R2V0QXJyYXlMZW5ndGgoY2lwaGVyU3VpdGVzKTsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3NldF9jaXBoZXJfbGlzdHMgbGVuZ3RoPSVkIiwgc3NsLCBsZW5ndGgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgU2NvcGVkTG9jYWxSZWY8anN0cmluZz4gY2lwaGVyU3VpdGUoZW52LAorICAgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8anN0cmluZz4oZW52LT5HZXRPYmplY3RBcnJheUVsZW1lbnQoY2lwaGVyU3VpdGVzLCBpKSkpOworICAgICAgICBTY29wZWRVdGZDaGFycyBjKGVudiwgY2lwaGVyU3VpdGUuZ2V0KCkpOworICAgICAgICBpZiAoYy5jX3N0cigpID09IE5VTEwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3NldF9jaXBoZXJfbGlzdHMgY2lwaGVyU3VpdGU9JXMiLCBzc2wsIGMuY19zdHIoKSk7CisgICAgICAgIGJvb2wgZm91bmQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBudW1fY2lwaGVyczsgaisrKSB7CisgICAgICAgICAgICBjb25zdCBTU0xfQ0lQSEVSKiBjaXBoZXIgPSBzc2xfbWV0aG9kLT5nZXRfY2lwaGVyKGopOworICAgICAgICAgICAgaWYgKChzdHJjbXAoYy5jX3N0cigpLCBjaXBoZXItPm5hbWUpID09IDApCisgICAgICAgICAgICAgICAgICAgICYmIChzdHJjbXAoU1NMX0NJUEhFUl9nZXRfdmVyc2lvbihjaXBoZXIpLCAiU1NMdjIiKSkpIHsKKyAgICAgICAgICAgICAgICBpZiAoIXNrX1NTTF9DSVBIRVJfcHVzaChjaXBoZXJzdGFjay5nZXQoKSwgY2lwaGVyKSkgeworICAgICAgICAgICAgICAgICAgICBqbmlUaHJvd091dE9mTWVtb3J5RXJyb3IoZW52LCAiVW5hYmxlIHRvIHB1c2ggY2lwaGVyIik7CisgICAgICAgICAgICAgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfc2V0X2NpcGhlcl9saXN0cyA9PiBjaXBoZXIgcHVzaCBlcnJvciIsIHNzbCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmICghZm91bmQpIHsKKyAgICAgICAgICAgIGpuaVRocm93RXhjZXB0aW9uKGVudiwgImphdmEvbGFuZy9JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNvdWxkIG5vdCBmaW5kIGNpcGhlciBzdWl0ZS4iKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KKworICAgIGludCByYyA9IFNTTF9zZXRfY2lwaGVyX2xpc3RzKHNzbCwgY2lwaGVyc3RhY2suZ2V0KCkpOworICAgIGlmIChyYyA9PSAwKSB7CisgICAgICAgIGZyZWVPcGVuU3NsRXJyb3JTdGF0ZSgpOworICAgICAgICBqbmlUaHJvd0V4Y2VwdGlvbihlbnYsICJqYXZhL2xhbmcvSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIklsbGVnYWwgY2lwaGVyIHN1aXRlIHN0cmluZ3MuIik7CisgICAgfSBlbHNlIHsKKyAgICAgICAgT1dORVJTSElQX1RSQU5TRkVSUkVEKGNpcGhlcnN0YWNrKTsKKyAgICB9Cit9CisKKy8qKgorICogU2V0cyBjZXJ0aWZpY2F0ZSBleHBlY3RhdGlvbnMsIGVzcGVjaWFsbHkgZm9yIHNlcnZlciB0byByZXF1ZXN0IGNsaWVudCBhdXRoCisgKi8KK3N0YXRpYyB2b2lkIE5hdGl2ZUNyeXB0b19TU0xfc2V0X3ZlcmlmeShKTklFbnYqIGVudiwKKyAgICAgICAgamNsYXNzLCBqaW50IHNzbF9hZGRyZXNzLCBqaW50IG1vZGUpCit7CisgICAgU1NMKiBzc2wgPSB0b19TU0woZW52LCBzc2xfYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9zZXRfdmVyaWZ5IG1vZGU9JXgiLCBzc2wsIG1vZGUpOworICAgIGlmIChzc2wgPT0gTlVMTCkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBTU0xfc2V0X3ZlcmlmeShzc2wsIChpbnQpbW9kZSwgTlVMTCk7Cit9CisKKy8qKgorICogU2V0cyB0aGUgY2lwaGVycyBzdWl0ZXMgdGhhdCBhcmUgZW5hYmxlZCBpbiB0aGUgU1NMCisgKi8KK3N0YXRpYyB2b2lkIE5hdGl2ZUNyeXB0b19TU0xfc2V0X3Nlc3Npb24oSk5JRW52KiBlbnYsIGpjbGFzcywKKyAgICAgICAgamludCBzc2xfYWRkcmVzcywgamludCBzc2xfc2Vzc2lvbl9hZGRyZXNzKQoreworICAgIFNTTCogc3NsID0gdG9fU1NMKGVudiwgc3NsX2FkZHJlc3MsIHRydWUpOworICAgIFNTTF9TRVNTSU9OKiBzc2xfc2Vzc2lvbiA9IHRvX1NTTF9TRVNTSU9OKGVudiwgc3NsX3Nlc3Npb25fYWRkcmVzcywgZmFsc2UpOworICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfc2V0X3Nlc3Npb24gc3NsX3Nlc3Npb249JXAiLCBzc2wsIHNzbF9zZXNzaW9uKTsKKyAgICBpZiAoc3NsID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGludCByZXQgPSBTU0xfc2V0X3Nlc3Npb24oc3NsLCBzc2xfc2Vzc2lvbik7CisgICAgaWYgKHJldCAhPSAxKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFRyYW5zbGF0ZSB0aGUgZXJyb3IsIGFuZCB0aHJvdyBpZiBpdCB0dXJucyBvdXQgdG8gYmUgYSByZWFsCisgICAgICAgICAqIHByb2JsZW0uCisgICAgICAgICAqLworICAgICAgICBpbnQgc3NsRXJyb3JDb2RlID0gU1NMX2dldF9lcnJvcihzc2wsIHJldCk7CisgICAgICAgIGlmIChzc2xFcnJvckNvZGUgIT0gU1NMX0VSUk9SX1pFUk9fUkVUVVJOKSB7CisgICAgICAgICAgICB0aHJvd1NTTEV4Y2VwdGlvbldpdGhTc2xFcnJvcnMoZW52LCBzc2wsIHNzbEVycm9yQ29kZSwgIlNTTCBzZXNzaW9uIHNldCIpOworICAgICAgICAgICAgU1NMX2NsZWFyKHNzbCk7CisgICAgICAgIH0KKyAgICB9Cit9CisKKy8qKgorICogU2V0cyB0aGUgY2lwaGVycyBzdWl0ZXMgdGhhdCBhcmUgZW5hYmxlZCBpbiB0aGUgU1NMCisgKi8KK3N0YXRpYyB2b2lkIE5hdGl2ZUNyeXB0b19TU0xfc2V0X3Nlc3Npb25fY3JlYXRpb25fZW5hYmxlZChKTklFbnYqIGVudiwgamNsYXNzLAorICAgICAgICBqaW50IHNzbF9hZGRyZXNzLCBqYm9vbGVhbiBjcmVhdGlvbl9lbmFibGVkKQoreworICAgIFNTTCogc3NsID0gdG9fU1NMKGVudiwgc3NsX2FkZHJlc3MsIHRydWUpOworICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfc2V0X3Nlc3Npb25fY3JlYXRpb25fZW5hYmxlZCBjcmVhdGlvbl9lbmFibGVkPSVkIiwKKyAgICAgICAgICAgICAgc3NsLCBjcmVhdGlvbl9lbmFibGVkKTsKKyAgICBpZiAoc3NsID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBTU0xfc2V0X3Nlc3Npb25fY3JlYXRpb25fZW5hYmxlZChzc2wsIGNyZWF0aW9uX2VuYWJsZWQpOworfQorCitzdGF0aWMgdm9pZCBOYXRpdmVDcnlwdG9fU1NMX3NldF90bHNleHRfaG9zdF9uYW1lKEpOSUVudiogZW52LCBqY2xhc3MsCisgICAgICAgIGppbnQgc3NsX2FkZHJlc3MsIGpzdHJpbmcgaG9zdG5hbWUpCit7CisgICAgU1NMKiBzc2wgPSB0b19TU0woZW52LCBzc2xfYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9zZXRfdGxzZXh0X2hvc3RfbmFtZSBob3N0bmFtZT0lcCIsCisgICAgICAgICAgICAgIHNzbCwgaG9zdG5hbWUpOworICAgIGlmIChzc2wgPT0gTlVMTCkgeworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgU2NvcGVkVXRmQ2hhcnMgaG9zdG5hbWVDaGFycyhlbnYsIGhvc3RuYW1lKTsKKyAgICBpZiAoaG9zdG5hbWVDaGFycy5jX3N0cigpID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3NldF90bHNleHRfaG9zdF9uYW1lIGhvc3RuYW1lQ2hhcnM9JXMiLAorICAgICAgICAgICAgICBzc2wsIGhvc3RuYW1lQ2hhcnMuY19zdHIoKSk7CisKKyAgICBpbnQgcmV0ID0gU1NMX3NldF90bHNleHRfaG9zdF9uYW1lKHNzbCwgaG9zdG5hbWVDaGFycy5jX3N0cigpKTsKKyAgICBpZiAocmV0ICE9IDEpIHsKKyAgICAgICAgdGhyb3dTU0xFeGNlcHRpb25XaXRoU3NsRXJyb3JzKGVudiwgc3NsLCBTU0xfRVJST1JfTk9ORSwgIkVycm9yIHNldHRpbmcgaG9zdCBuYW1lIik7CisgICAgICAgIFNTTF9jbGVhcihzc2wpOworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3NldF90bHNleHRfaG9zdF9uYW1lID0+IGVycm9yIiwgc3NsKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3NldF90bHNleHRfaG9zdF9uYW1lID0+IG9rIiwgc3NsKTsKK30KKworc3RhdGljIGpzdHJpbmcgTmF0aXZlQ3J5cHRvX1NTTF9nZXRfc2VydmVybmFtZShKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IHNzbF9hZGRyZXNzKSB7CisgICAgU1NMKiBzc2wgPSB0b19TU0woZW52LCBzc2xfYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9nZXRfc2VydmVybmFtZSIsIHNzbCk7CisgICAgaWYgKHNzbCA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBjb25zdCBjaGFyKiBzZXJ2ZXJuYW1lID0gU1NMX2dldF9zZXJ2ZXJuYW1lKHNzbCwgVExTRVhUX05BTUVUWVBFX2hvc3RfbmFtZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9nZXRfc2VydmVybmFtZSA9PiAlcyIsIHNzbCwgc2VydmVybmFtZSk7CisgICAgcmV0dXJuIGVudi0+TmV3U3RyaW5nVVRGKHNlcnZlcm5hbWUpOworfQorCisvKioKKyAqIFBlcmZvcm0gU1NMIGhhbmRzaGFrZQorICovCitzdGF0aWMgamludCBOYXRpdmVDcnlwdG9fU1NMX2RvX2hhbmRzaGFrZShKTklFbnYqIGVudiwgamNsYXNzLAorICAgIGppbnQgc3NsX2FkZHJlc3MsIGpvYmplY3QgZmRPYmplY3QsIGpvYmplY3Qgc2hjLCBqaW50IHRpbWVvdXQsIGpib29sZWFuIGNsaWVudF9tb2RlKQoreworICAgIFNTTCogc3NsID0gdG9fU1NMKGVudiwgc3NsX2FkZHJlc3MsIHRydWUpOworICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfZG9faGFuZHNoYWtlIGZkPSVwIHNoYz0lcCB0aW1lb3V0PSVkIGNsaWVudF9tb2RlPSVkIiwKKyAgICAgICAgICAgICAgc3NsLCBmZE9iamVjdCwgc2hjLCB0aW1lb3V0LCBjbGllbnRfbW9kZSk7CisgICAgaWYgKHNzbCA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgaWYgKGZkT2JqZWN0ID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsICJmZCA9PSBudWxsIik7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfZG9faGFuZHNoYWtlIGZkID09IG51bGwgPT4gMCIsIHNzbCk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBpZiAoc2hjID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsICJzc2xIYW5kc2hha2VDYWxsYmFja3MgPT0gbnVsbCIpOworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX2RvX2hhbmRzaGFrZSBzc2xIYW5kc2hha2VDYWxsYmFja3MgPT0gbnVsbCA9PiAwIiwgc3NsKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgTmV0RmQgZmQoZW52LCBmZE9iamVjdCk7CisgICAgaWYgKGZkLmlzQ2xvc2VkKCkpIHsKKyAgICAgICAgLy8gU29ja2V0RXhjZXB0aW9uIHRocm93biBieSBOZXRGZC5pc0Nsb3NlZAorICAgICAgICBTU0xfY2xlYXIoc3NsKTsKKyAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9kb19oYW5kc2hha2UgZmQuaXNDbG9zZWQoKSA9PiAwIiwgc3NsKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgaW50IHJldCA9IFNTTF9zZXRfZmQoc3NsLCBmZC5nZXQoKSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9kb19oYW5kc2hha2Ugcz0lZCIsIHNzbCwgZmQuZ2V0KCkpOworCisgICAgaWYgKHJldCAhPSAxKSB7CisgICAgICAgIHRocm93U1NMRXhjZXB0aW9uV2l0aFNzbEVycm9ycyhlbnYsIHNzbCwgU1NMX0VSUk9SX05PTkUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRXJyb3Igc2V0dGluZyB0aGUgZmlsZSBkZXNjcmlwdG9yIik7CisgICAgICAgIFNTTF9jbGVhcihzc2wpOworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX2RvX2hhbmRzaGFrZSBTU0xfc2V0X2ZkID0+IDAiLCBzc2wpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIE1ha2Ugc29ja2V0IG5vbi1ibG9ja2luZywgc28gU1NMX2Nvbm5lY3QgU1NMX3JlYWQoKSBhbmQgU1NMX3dyaXRlKCkgZG9uJ3QgaGFuZworICAgICAqIGZvcmV2ZXIgYW5kIHdlIGNhbiB1c2Ugc2VsZWN0KCkgdG8gZmluZCBvdXQgaWYgdGhlIHNvY2tldCBpcyByZWFkeS4KKyAgICAgKi8KKyAgICBpZiAoIXNldEJsb2NraW5nKGZkLmdldCgpLCBmYWxzZSkpIHsKKyAgICAgICAgdGhyb3dTU0xFeGNlcHRpb25TdHIoZW52LCAiVW5hYmxlIHRvIG1ha2Ugc29ja2V0IG5vbiBibG9ja2luZyIpOworICAgICAgICBTU0xfY2xlYXIoc3NsKTsKKyAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9kb19oYW5kc2hha2Ugc2V0QmxvY2tpbmcgPT4gMCIsIHNzbCk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qCisgICAgICogQ3JlYXRlIG91ciBzcGVjaWFsIGFwcGxpY2F0aW9uIGRhdGEuCisgICAgICovCisgICAgQXBwRGF0YSogYXBwRGF0YSA9IEFwcERhdGE6OmNyZWF0ZSgpOworICAgIGlmIChhcHBEYXRhID09IE5VTEwpIHsKKyAgICAgICAgdGhyb3dTU0xFeGNlcHRpb25TdHIoZW52LCAiVW5hYmxlIHRvIGNyZWF0ZSBhcHBsaWNhdGlvbiBkYXRhIik7CisgICAgICAgIFNTTF9jbGVhcihzc2wpOworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX2RvX2hhbmRzaGFrZSBhcHBEYXRhID0+IDAiLCBzc2wpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgU1NMX3NldF9hcHBfZGF0YShzc2wsIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KGFwcERhdGEpKTsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBBcHBEYXRhOjpjcmVhdGUgPT4gJXAiLCBzc2wsIGFwcERhdGEpOworCisgICAgaWYgKGNsaWVudF9tb2RlKSB7CisgICAgICAgIFNTTF9zZXRfY29ubmVjdF9zdGF0ZShzc2wpOworICAgIH0gZWxzZSB7CisgICAgICAgIFNTTF9zZXRfYWNjZXB0X3N0YXRlKHNzbCk7CisgICAgfQorCisgICAgcmV0ID0gMDsKKyAgICB3aGlsZSAoYXBwRGF0YS0+YWxpdmVBbmRLaWNraW5nKSB7CisgICAgICAgIGVycm5vID0gMDsKKworICAgICAgICBpZiAoIWFwcERhdGEtPnNldENhbGxiYWNrU3RhdGUoZW52LCBzaGMsIGZkT2JqZWN0KSkgeworICAgICAgICAgICAgLy8gU29ja2V0RXhjZXB0aW9uIHRocm93biBieSBOZXRGZC5pc0Nsb3NlZAorICAgICAgICAgICAgU1NMX2NsZWFyKHNzbCk7CisgICAgICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX2RvX2hhbmRzaGFrZSBzZXRDYWxsYmFja1N0YXRlID0+IDAiLCBzc2wpOworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgcmV0ID0gU1NMX2RvX2hhbmRzaGFrZShzc2wpOworICAgICAgICBhcHBEYXRhLT5jbGVhckNhbGxiYWNrU3RhdGUoKTsKKyAgICAgICAgLy8gY2VydF92ZXJpZnlfY2FsbGJhY2sgdGhyZXcgZXhjZXB0aW9uCisgICAgICAgIGlmIChlbnYtPkV4Y2VwdGlvbkNoZWNrKCkpIHsKKyAgICAgICAgICAgIFNTTF9jbGVhcihzc2wpOworICAgICAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9kb19oYW5kc2hha2UgZXhjZXB0aW9uID0+IDAiLCBzc2wpOworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgLy8gc3VjY2VzcyBjYXNlCisgICAgICAgIGlmIChyZXQgPT0gMSkgeworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgLy8gcmV0cnkgY2FzZQorICAgICAgICBpZiAoZXJybm8gPT0gRUlOVFIpIHsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIC8vIGVycm9yIGNhc2UKKyAgICAgICAgaW50IHNzbEVycm9yID0gU1NMX2dldF9lcnJvcihzc2wsIHJldCk7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfZG9faGFuZHNoYWtlIHJldD0lZCBlcnJubz0lZCBzc2xFcnJvcj0lZCB0aW1lb3V0PSVkIiwKKyAgICAgICAgICAgICAgICAgIHNzbCwgcmV0LCBlcnJubywgc3NsRXJyb3IsIHRpbWVvdXQpOworCisgICAgICAgIC8qCisgICAgICAgICAqIElmIFNTTF9kb19oYW5kc2hha2UgZG9lc24ndCBzdWNjZWVkIGR1ZSB0byB0aGUgc29ja2V0IGJlaW5nCisgICAgICAgICAqIGVpdGhlciB1bnJlYWRhYmxlIG9yIHVud3JpdGFibGUsIHdlIHVzZSBzc2xTZWxlY3QgdG8KKyAgICAgICAgICogd2FpdCBmb3IgaXQgdG8gYmVjb21lIHJlYWR5LiBJZiB0aGF0IGRvZXNuJ3QgaGFwcGVuCisgICAgICAgICAqIGJlZm9yZSB0aGUgc3BlY2lmaWVkIHRpbWVvdXQgb3IgYW4gZXJyb3Igb2NjdXJzLCB3ZQorICAgICAgICAgKiBjYW5jZWwgdGhlIGhhbmRzaGFrZS4gT3RoZXJ3aXNlIHdlIHRyeSB0aGUgU1NMX2Nvbm5lY3QKKyAgICAgICAgICogYWdhaW4uCisgICAgICAgICAqLworICAgICAgICBpZiAoc3NsRXJyb3IgPT0gU1NMX0VSUk9SX1dBTlRfUkVBRCB8fCBzc2xFcnJvciA9PSBTU0xfRVJST1JfV0FOVF9XUklURSkgeworICAgICAgICAgICAgYXBwRGF0YS0+d2FpdGluZ1RocmVhZHMrKzsKKyAgICAgICAgICAgIGludCBzZWxlY3RSZXN1bHQgPSBzc2xTZWxlY3QoZW52LCBzc2xFcnJvciwgZmRPYmplY3QsIGFwcERhdGEsIHRpbWVvdXQpOworCisgICAgICAgICAgICBpZiAoc2VsZWN0UmVzdWx0ID09IFRIUk9XTl9FWENFUFRJT04pIHsKKyAgICAgICAgICAgICAgICAvLyBTb2NrZXRFeGNlcHRpb24gdGhyb3duIGJ5IE5ldEZkLmlzQ2xvc2VkCisgICAgICAgICAgICAgICAgU1NMX2NsZWFyKHNzbCk7CisgICAgICAgICAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9kb19oYW5kc2hha2Ugc3NsU2VsZWN0ID0+IDAiLCBzc2wpOworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHNlbGVjdFJlc3VsdCA9PSAtMSkgeworICAgICAgICAgICAgICAgIHRocm93U1NMRXhjZXB0aW9uV2l0aFNzbEVycm9ycyhlbnYsIHNzbCwgU1NMX0VSUk9SX1NZU0NBTEwsICJoYW5kc2hha2UgZXJyb3IiKTsKKyAgICAgICAgICAgICAgICBTU0xfY2xlYXIoc3NsKTsKKyAgICAgICAgICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX2RvX2hhbmRzaGFrZSBzZWxlY3RSZXN1bHQgPT0gLTEgPT4gMCIsIHNzbCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc2VsZWN0UmVzdWx0ID09IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvd1NvY2tldFRpbWVvdXRFeGNlcHRpb24oZW52LCAiU1NMIGhhbmRzaGFrZSB0aW1lZCBvdXQiKTsKKyAgICAgICAgICAgICAgICBTU0xfY2xlYXIoc3NsKTsKKyAgICAgICAgICAgICAgICBmcmVlT3BlblNzbEVycm9yU3RhdGUoKTsKKyAgICAgICAgICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX2RvX2hhbmRzaGFrZSBzZWxlY3RSZXN1bHQgPT0gMCA9PiAwIiwgc3NsKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIExPR0UoIlVua25vd24gZXJyb3IgJWQgZHVyaW5nIGhhbmRzaGFrZSIsIGVycm9yKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gY2xlYW4gZXJyb3IuIFNlZSBTU0xfZG9faGFuZHNoYWtlKDNTU0wpIG1hbiBwYWdlLgorICAgIGlmIChyZXQgPT0gMCkgeworICAgICAgICAvKgorICAgICAgICAgKiBUaGUgb3RoZXIgc2lkZSBjbG9zZWQgdGhlIHNvY2tldCBiZWZvcmUgdGhlIGhhbmRzaGFrZSBjb3VsZCBiZQorICAgICAgICAgKiBjb21wbGV0ZWQsIGJ1dCBldmVyeXRoaW5nIGlzIHdpdGhpbiB0aGUgYm91bmRzIG9mIHRoZSBUTFMgcHJvdG9jb2wuCisgICAgICAgICAqIFdlIHN0aWxsIG1pZ2h0IHdhbnQgdG8gZmluZCBvdXQgdGhlIHJlYWwgcmVhc29uIG9mIHRoZSBmYWlsdXJlLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IHNzbEVycm9yID0gU1NMX2dldF9lcnJvcihzc2wsIHJldCk7CisgICAgICAgIGlmIChzc2xFcnJvciA9PSBTU0xfRVJST1JfTk9ORSB8fCAoc3NsRXJyb3IgPT0gU1NMX0VSUk9SX1NZU0NBTEwgJiYgZXJybm8gPT0gMCkpIHsKKyAgICAgICAgICAgIHRocm93U1NMRXhjZXB0aW9uU3RyKGVudiwgIkNvbm5lY3Rpb24gY2xvc2VkIGJ5IHBlZXIiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93U1NMRXhjZXB0aW9uV2l0aFNzbEVycm9ycyhlbnYsIHNzbCwgc3NsRXJyb3IsICJTU0wgaGFuZHNoYWtlIHRlcm1pbmF0ZWQiKTsKKyAgICAgICAgfQorICAgICAgICBTU0xfY2xlYXIoc3NsKTsKKyAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9kb19oYW5kc2hha2UgY2xlYW4gZXJyb3IgPT4gMCIsIHNzbCk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8vIHVuY2xlYW4gZXJyb3IuIFNlZSBTU0xfZG9faGFuZHNoYWtlKDNTU0wpIG1hbiBwYWdlLgorICAgIGlmIChyZXQgPCAwKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIFRyYW5zbGF0ZSB0aGUgZXJyb3IgYW5kIHRocm93IGV4Y2VwdGlvbi4gV2UgYXJlIHN1cmUgaXQgaXMgYW4gZXJyb3IKKyAgICAgICAgICogYXQgdGhpcyBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIGludCBzc2xFcnJvciA9IFNTTF9nZXRfZXJyb3Ioc3NsLCByZXQpOworICAgICAgICB0aHJvd1NTTEV4Y2VwdGlvbldpdGhTc2xFcnJvcnMoZW52LCBzc2wsIHNzbEVycm9yLCAiU1NMIGhhbmRzaGFrZSBhYm9ydGVkIik7CisgICAgICAgIFNTTF9jbGVhcihzc2wpOworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX2RvX2hhbmRzaGFrZSB1bmNsZWFuIGVycm9yID0+IDAiLCBzc2wpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgU1NMX1NFU1NJT04qIHNzbF9zZXNzaW9uID0gU1NMX2dldDFfc2Vzc2lvbihzc2wpOworICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfZG9faGFuZHNoYWtlID0+IHNzbF9zZXNzaW9uPSVwIiwgc3NsLCBzc2xfc2Vzc2lvbik7CisgICAgcmV0dXJuIChqaW50KSBzc2xfc2Vzc2lvbjsKK30KKworLyoqCisgKiBQZXJmb3JtIFNTTCByZW5lZ290aWF0aW9uCisgKi8KK3N0YXRpYyB2b2lkIE5hdGl2ZUNyeXB0b19TU0xfcmVuZWdvdGlhdGUoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBzc2xfYWRkcmVzcykKK3sKKyAgICBTU0wqIHNzbCA9IHRvX1NTTChlbnYsIHNzbF9hZGRyZXNzLCB0cnVlKTsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3JlbmVnb3RpYXRlIiwgc3NsKTsKKyAgICBpZiAoc3NsID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpbnQgcmVzdWx0ID0gU1NMX3JlbmVnb3RpYXRlKHNzbCk7CisgICAgaWYgKHJlc3VsdCAhPSAxKSB7CisgICAgICAgIHRocm93U1NMRXhjZXB0aW9uU3RyKGVudiwgIlByb2JsZW0gd2l0aCBTU0xfcmVuZWdvdGlhdGUiKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICAvLyBmaXJzdCBjYWxsIGFza3MgY2xpZW50IHRvIHBlcmZvcm0gcmVuZWdvdGlhdGlvbgorICAgIGludCByZXQgPSBTU0xfZG9faGFuZHNoYWtlKHNzbCk7CisgICAgaWYgKHJldCAhPSAxKSB7CisgICAgICAgIGludCBzc2xFcnJvciA9IFNTTF9nZXRfZXJyb3Ioc3NsLCByZXQpOworICAgICAgICB0aHJvd1NTTEV4Y2VwdGlvbldpdGhTc2xFcnJvcnMoZW52LCBzc2wsIHNzbEVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlByb2JsZW0gd2l0aCBTU0xfZG9faGFuZHNoYWtlIGFmdGVyIFNTTF9yZW5lZ290aWF0ZSIpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIC8vIGlmIGNsaWVudCBhZ3JlZXMsIHNldCBzc2wgc3RhdGUgYW5kIHBlcmZvcm0gcmVuZWdvdGlhdGlvbgorICAgIHNzbC0+c3RhdGUgPSBTU0xfU1RfQUNDRVBUOworICAgIFNTTF9kb19oYW5kc2hha2Uoc3NsKTsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3JlbmVnb3RpYXRlID0+Iiwgc3NsKTsKK30KKworLyoqCisgKiBwdWJsaWMgc3RhdGljIG5hdGl2ZSBieXRlW11bXSBTU0xfZ2V0X2NlcnRpZmljYXRlKGludCBzc2wpOworICovCitzdGF0aWMgam9iamVjdEFycmF5IE5hdGl2ZUNyeXB0b19TU0xfZ2V0X2NlcnRpZmljYXRlKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgc3NsX2FkZHJlc3MpCit7CisgICAgU1NMKiBzc2wgPSB0b19TU0woZW52LCBzc2xfYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9nZXRfY2VydGlmaWNhdGUiLCBzc2wpOworICAgIGlmIChzc2wgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgWDUwOSogY2VydGlmaWNhdGUgPSBTU0xfZ2V0X2NlcnRpZmljYXRlKHNzbCk7CisgICAgaWYgKGNlcnRpZmljYXRlID09IE5VTEwpIHsKKyAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9nZXRfY2VydGlmaWNhdGUgPT4gTlVMTCIsIHNzbCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIFVuaXF1ZV9za19YNTA5IGNoYWluKHNrX1g1MDlfbmV3X251bGwoKSk7CisgICAgaWYgKGNoYWluLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dPdXRPZk1lbW9yeUVycm9yKGVudiwgIlVuYWJsZSB0byBhbGxvY2F0ZSBsb2NhbCBjZXJ0aWZpY2F0ZSBjaGFpbiIpOworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX2dldF9jZXJ0aWZpY2F0ZSA9PiB0aHJldyBleGNlcHRpb24iLCBzc2wpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKCFza19YNTA5X3B1c2goY2hhaW4uZ2V0KCksIGNlcnRpZmljYXRlKSkgeworICAgICAgICBqbmlUaHJvd091dE9mTWVtb3J5RXJyb3IoZW52LCAiVW5hYmxlIHRvIHB1c2ggbG9jYWwgY2VydGlmaWNhdGUiKTsKKyAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9nZXRfY2VydGlmaWNhdGUgPT4gTlVMTCIsIHNzbCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBTVEFDS19PRihYNTA5KSogY2VydF9jaGFpbiA9IFNTTF9nZXRfY2VydGlmaWNhdGVfY2hhaW4oc3NsLCBjZXJ0aWZpY2F0ZSk7CisgICAgZm9yIChpbnQgaT0wOyBpPHNrX1g1MDlfbnVtKGNlcnRfY2hhaW4pOyBpKyspIHsKKyAgICAgICAgaWYgKCFza19YNTA5X3B1c2goY2hhaW4uZ2V0KCksIHNrX1g1MDlfdmFsdWUoY2VydF9jaGFpbiwgaSkpKSB7CisgICAgICAgICAgICBqbmlUaHJvd091dE9mTWVtb3J5RXJyb3IoZW52LCAiVW5hYmxlIHRvIHB1c2ggbG9jYWwgY2VydGlmaWNhdGUgY2hhaW4iKTsKKyAgICAgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfZ2V0X2NlcnRpZmljYXRlID0+IE5VTEwiLCBzc2wpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBqb2JqZWN0QXJyYXkgb2JqZWN0QXJyYXkgPSBnZXRDZXJ0aWZpY2F0ZUJ5dGVzKGVudiwgY2hhaW4uZ2V0KCkpOworICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfZ2V0X2NlcnRpZmljYXRlID0+ICVwIiwgc3NsLCBvYmplY3RBcnJheSk7CisgICAgcmV0dXJuIG9iamVjdEFycmF5OworfQorCisvLyBGaWxscyBhIGJ5dGVbXVtdIHdpdGggdGhlIHBlZXIgY2VydGlmaWNhdGVzIGluIHRoZSBjaGFpbi4KK3N0YXRpYyBqb2JqZWN0QXJyYXkgTmF0aXZlQ3J5cHRvX1NTTF9nZXRfcGVlcl9jZXJ0X2NoYWluKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgc3NsX2FkZHJlc3MpCit7CisgICAgU1NMKiBzc2wgPSB0b19TU0woZW52LCBzc2xfYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9nZXRfcGVlcl9jZXJ0X2NoYWluIiwgc3NsKTsKKyAgICBpZiAoc3NsID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFNUQUNLX09GKFg1MDkpKiBjaGFpbiA9IFNTTF9nZXRfcGVlcl9jZXJ0X2NoYWluKHNzbCk7CisgICAgVW5pcXVlX3NrX1g1MDkgY2hhaW5fY29weShOVUxMKTsKKyAgICBpZiAoc3NsLT5zZXJ2ZXIpIHsKKyAgICAgICAgWDUwOSogeDUwOSA9IFNTTF9nZXRfcGVlcl9jZXJ0aWZpY2F0ZShzc2wpOworICAgICAgICBpZiAoeDUwOSA9PSBOVUxMKSB7CisgICAgICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX2dldF9wZWVyX2NlcnRfY2hhaW4gPT4gTlVMTCIsIHNzbCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBjaGFpbl9jb3B5LnJlc2V0KHNrX1g1MDlfZHVwKGNoYWluKSk7CisgICAgICAgIGlmIChjaGFpbl9jb3B5LmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgICAgIGpuaVRocm93T3V0T2ZNZW1vcnlFcnJvcihlbnYsICJVbmFibGUgdG8gYWxsb2NhdGUgcGVlciBjZXJ0aWZpY2F0ZSBjaGFpbiIpOworICAgICAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9nZXRfcGVlcl9jZXJ0X2NoYWluID0+IGNlcnRpZmljYXRlIGR1cCBlcnJvciIsIHNzbCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXNrX1g1MDlfcHVzaChjaGFpbl9jb3B5LmdldCgpLCB4NTA5KSkgeworICAgICAgICAgICAgam5pVGhyb3dPdXRPZk1lbW9yeUVycm9yKGVudiwgIlVuYWJsZSB0byBwdXNoIHNlcnZlcidzIHBlZXIgY2VydGlmaWNhdGUiKTsKKyAgICAgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfZ2V0X3BlZXJfY2VydF9jaGFpbiA9PiBjZXJ0aWZpY2F0ZSBwdXNoIGVycm9yIiwgc3NsKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGNoYWluID0gY2hhaW5fY29weS5nZXQoKTsKKyAgICB9CisgICAgam9iamVjdEFycmF5IG9iamVjdEFycmF5ID0gZ2V0Q2VydGlmaWNhdGVCeXRlcyhlbnYsIGNoYWluKTsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX2dldF9wZWVyX2NlcnRfY2hhaW4gPT4gJXAiLCBzc2wsIG9iamVjdEFycmF5KTsKKyAgICByZXR1cm4gb2JqZWN0QXJyYXk7Cit9CisKKy8qKgorICogSGVscGVyIGZ1bmN0aW9uIHdoaWNoIGRvZXMgdGhlIGFjdHVhbCByZWFkaW5nLiBUaGUgSmF2YSBsYXllciBndWFyYW50ZWVzIHRoYXQKKyAqIGF0IG1vc3Qgb25lIHRocmVhZCB3aWxsIGVudGVyIHRoaXMgZnVuY3Rpb24gYXQgYW55IGdpdmVuIHRpbWUuCisgKgorICogQHBhcmFtIHNzbCBub24tbnVsbDsgdGhlIFNTTCBjb250ZXh0CisgKiBAcGFyYW0gYnVmIG5vbi1udWxsOyBidWZmZXIgdG8gcmVhZCBpbnRvCisgKiBAcGFyYW0gbGVuIGxlbmd0aCBvZiB0aGUgYnVmZmVyLCBpbiBieXRlcworICogQHBhcmFtIHNzbFJldHVybkNvZGUgb3JpZ2luYWwgU1NMIHJldHVybiBjb2RlCisgKiBAcGFyYW0gc3NsRXJyb3JDb2RlIGZpbGxlZCBpbiB3aXRoIHRoZSBTU0wgZXJyb3IgY29kZSBpbiBjYXNlIG9mIGVycm9yCisgKiBAcmV0dXJuIG51bWJlciBvZiBieXRlcyByZWFkIG9uIHN1Y2Nlc3MsIC0xIGlmIHRoZSBjb25uZWN0aW9uIHdhcworICogY2xlYW5seSBzaHV0IGRvd24sIG9yIFRIUk9XX1NTTEVYQ0VQVElPTiBpZiBhbiBleGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4KKyAqLworc3RhdGljIGludCBzc2xSZWFkKEpOSUVudiogZW52LCBTU0wqIHNzbCwgam9iamVjdCBmZE9iamVjdCwgam9iamVjdCBzaGMsIGNoYXIqIGJ1ZiwgamludCBsZW4sCisgICAgICAgICAgICAgICAgICAgaW50KiBzc2xSZXR1cm5Db2RlLCBpbnQqIHNzbEVycm9yQ29kZSwgaW50IHRpbWVvdXQpIHsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBzc2xSZWFkIGJ1Zj0lcCBsZW49JWQiLCBzc2wsIGJ1ZiwgbGVuKTsKKworICAgIGlmIChsZW4gPT0gMCkgeworICAgICAgICAvLyBEb24ndCBib3RoZXIgZG9pbmcgYW55dGhpbmcgaW4gdGhpcyBjYXNlLgorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBCSU8qIGJpbyA9IFNTTF9nZXRfcmJpbyhzc2wpOworCisgICAgQXBwRGF0YSogYXBwRGF0YSA9IHRvQXBwRGF0YShzc2wpOworICAgIGlmIChhcHBEYXRhID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIFRIUk9XX1NTTEVYQ0VQVElPTjsKKyAgICB9CisKKyAgICB3aGlsZSAoYXBwRGF0YS0+YWxpdmVBbmRLaWNraW5nKSB7CisgICAgICAgIGVycm5vID0gMDsKKworICAgICAgICBpZiAoTVVURVhfTE9DSyhhcHBEYXRhLT5tdXRleCkgPT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorCisgICAgICAgIHVuc2lnbmVkIGludCBieXRlc01vdmVkID0gQklPX251bWJlcl9yZWFkKGJpbykgKyBCSU9fbnVtYmVyX3dyaXR0ZW4oYmlvKTsKKworICAgICAgICBpZiAoIWFwcERhdGEtPnNldENhbGxiYWNrU3RhdGUoZW52LCBzaGMsIGZkT2JqZWN0KSkgeworICAgICAgICAgICAgTVVURVhfVU5MT0NLKGFwcERhdGEtPm11dGV4KTsKKyAgICAgICAgICAgIHJldHVybiBUSFJPV05fRVhDRVBUSU9OOworICAgICAgICB9CisgICAgICAgIGludCByZXN1bHQgPSBTU0xfcmVhZChzc2wsIGJ1ZiwgbGVuKTsKKyAgICAgICAgYXBwRGF0YS0+Y2xlYXJDYWxsYmFja1N0YXRlKCk7CisgICAgICAgIC8vIGNhbGxiYWNrcyBjYW4gaGFwcGVuIGlmIHNlcnZlciByZXF1ZXN0cyByZW5lZ290aWF0aW9uCisgICAgICAgIGlmIChlbnYtPkV4Y2VwdGlvbkNoZWNrKCkpIHsKKyAgICAgICAgICAgIFNTTF9jbGVhcihzc2wpOworICAgICAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgc3NsUmVhZCA9PiBUSFJPV05fRVhDRVBUSU9OIiwgc3NsKTsKKyAgICAgICAgICAgIHJldHVybiBUSFJPV05fRVhDRVBUSU9OOworICAgICAgICB9CisgICAgICAgIGludCBzc2xFcnJvciA9IFNTTF9FUlJPUl9OT05FOworICAgICAgICBpZiAocmVzdWx0IDw9IDApIHsKKyAgICAgICAgICAgIHNzbEVycm9yID0gU1NMX2dldF9lcnJvcihzc2wsIHJlc3VsdCk7CisgICAgICAgICAgICBmcmVlT3BlblNzbEVycm9yU3RhdGUoKTsKKyAgICAgICAgfQorICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBzc2xSZWFkIFNTTF9yZWFkIHJlc3VsdD0lZCBzc2xFcnJvcj0lZCIsIHNzbCwgcmVzdWx0LCBzc2xFcnJvcik7CisjaWZkZWYgV0lUSF9KTklfVFJBQ0VfREFUQQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlc3VsdDsgaSs9IFdJVEhfSk5JX1RSQUNFX0RBVEFfQ0hVTktfU0laRSkgeworICAgICAgICAgICAgaW50IG4gPSBzdGQ6Om1pbihyZXN1bHQgLSBpLCBXSVRIX0pOSV9UUkFDRV9EQVRBX0NIVU5LX1NJWkUpOworICAgICAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgc3NsUmVhZCBkYXRhOiAlZDpcbiUqcyIsIHNzbCwgbiwgbiwgYnVmK2kpOworICAgICAgICB9CisjZW5kaWYKKworICAgICAgICAvLyBJZiB3ZSBoYXZlIGJlZW4gc3VjY2Vzc2Z1bCBpbiBtb3ZpbmcgZGF0YSBhcm91bmQsIGNoZWNrIHdoZXRoZXIgaXQKKyAgICAgICAgLy8gbWlnaHQgbWFrZSBzZW5zZSB0byB3YWtlIHVwIG90aGVyIGJsb2NrZWQgdGhyZWFkcywgc28gdGhleSBjYW4gZ2l2ZQorICAgICAgICAvLyBpdCBhIHRyeSwgdG9vLgorICAgICAgICBpZiAoQklPX251bWJlcl9yZWFkKGJpbykgKyBCSU9fbnVtYmVyX3dyaXR0ZW4oYmlvKSAhPSBieXRlc01vdmVkCisgICAgICAgICAgICAgICAgJiYgYXBwRGF0YS0+d2FpdGluZ1RocmVhZHMgPiAwKSB7CisgICAgICAgICAgICBzc2xOb3RpZnkoYXBwRGF0YSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBJZiB3ZSBhcmUgYmxvY2tlZCBieSB0aGUgdW5kZXJseWluZyBzb2NrZXQsIHRlbGwgdGhlIHdvcmxkIHRoYXQKKyAgICAgICAgLy8gdGhlcmUgd2lsbCBiZSBvbmUgbW9yZSB3YWl0aW5nIHRocmVhZCBub3cuCisgICAgICAgIGlmIChzc2xFcnJvciA9PSBTU0xfRVJST1JfV0FOVF9SRUFEIHx8IHNzbEVycm9yID09IFNTTF9FUlJPUl9XQU5UX1dSSVRFKSB7CisgICAgICAgICAgICBhcHBEYXRhLT53YWl0aW5nVGhyZWFkcysrOworICAgICAgICB9CisKKyAgICAgICAgTVVURVhfVU5MT0NLKGFwcERhdGEtPm11dGV4KTsKKworICAgICAgICBzd2l0Y2ggKHNzbEVycm9yKSB7CisgICAgICAgICAgICAvLyBTdWNjZXNzZnVsbHkgcmVhZCBhdCBsZWFzdCBvbmUgYnl0ZS4KKyAgICAgICAgICAgIGNhc2UgU1NMX0VSUk9SX05PTkU6IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBSZWFkIHplcm8gYnl0ZXMuIEVuZCBvZiBzdHJlYW0gcmVhY2hlZC4KKyAgICAgICAgICAgIGNhc2UgU1NMX0VSUk9SX1pFUk9fUkVUVVJOOiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBOZWVkIHRvIHdhaXQgZm9yIGF2YWlsYWJpbGl0eSBvZiB1bmRlcmx5aW5nIGxheWVyLCB0aGVuIHJldHJ5LgorICAgICAgICAgICAgY2FzZSBTU0xfRVJST1JfV0FOVF9SRUFEOgorICAgICAgICAgICAgY2FzZSBTU0xfRVJST1JfV0FOVF9XUklURTogeworICAgICAgICAgICAgICAgIGludCBzZWxlY3RSZXN1bHQgPSBzc2xTZWxlY3QoZW52LCBzc2xFcnJvciwgZmRPYmplY3QsIGFwcERhdGEsIHRpbWVvdXQpOworICAgICAgICAgICAgICAgIGlmIChzZWxlY3RSZXN1bHQgPT0gVEhST1dOX0VYQ0VQVElPTikgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gVEhST1dOX0VYQ0VQVElPTjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHNlbGVjdFJlc3VsdCA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAqc3NsUmV0dXJuQ29kZSA9IC0xOworICAgICAgICAgICAgICAgICAgICAqc3NsRXJyb3JDb2RlID0gc3NsRXJyb3I7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBUSFJPV19TU0xFWENFUFRJT047CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChzZWxlY3RSZXN1bHQgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gVEhST1dfU09DS0VUVElNRU9VVEVYQ0VQVElPTjsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gQSBwcm9ibGVtIG9jY3VycmVkIGR1cmluZyBhIHN5c3RlbSBjYWxsLCBidXQgdGhpcyBpcyBub3QKKyAgICAgICAgICAgIC8vIG5lY2Vzc2FyaWx5IGFuIGVycm9yLgorICAgICAgICAgICAgY2FzZSBTU0xfRVJST1JfU1lTQ0FMTDogeworICAgICAgICAgICAgICAgIC8vIENvbm5lY3Rpb24gY2xvc2VkIHdpdGhvdXQgcHJvcGVyIHNodXRkb3duLiBUZWxsIGNhbGxlciB3ZQorICAgICAgICAgICAgICAgIC8vIGhhdmUgcmVhY2hlZCBlbmQtb2Ytc3RyZWFtLgorICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gU3lzdGVtIGNhbGwgaGFzIGJlZW4gaW50ZXJydXB0ZWQuIFNpbXBseSByZXRyeS4KKyAgICAgICAgICAgICAgICBpZiAoZXJybm8gPT0gRUlOVFIpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gTm90ZSB0aGF0IGZvciBhbGwgb3RoZXIgc3lzdGVtIGNhbGwgZXJyb3JzIHdlIGZhbGwgdGhyb3VnaAorICAgICAgICAgICAgICAgIC8vIHRvIHRoZSBkZWZhdWx0IGNhc2UsIHdoaWNoIHJlc3VsdHMgaW4gYW4gRXhjZXB0aW9uLgorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBFdmVyeXRoaW5nIGVsc2UgaXMgYmFzaWNhbGx5IGFuIGVycm9yLgorICAgICAgICAgICAgZGVmYXVsdDogeworICAgICAgICAgICAgICAgICpzc2xSZXR1cm5Db2RlID0gcmVzdWx0OworICAgICAgICAgICAgICAgICpzc2xFcnJvckNvZGUgPSBzc2xFcnJvcjsKKyAgICAgICAgICAgICAgICByZXR1cm4gVEhST1dfU1NMRVhDRVBUSU9OOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIC0xOworfQorCisvKioKKyAqIE9wZW5TU0wgcmVhZCBmdW5jdGlvbiAoMik6IHJlYWQgaW50byBidWZmZXIgYXQgb2Zmc2V0IG4gY2h1bmtzLgorICogUmV0dXJucyAxIChzdWNjZXNzKSBvciB2YWx1ZSA8PSAwIChmYWlsdXJlKS4KKyAqLworc3RhdGljIGppbnQgTmF0aXZlQ3J5cHRvX1NTTF9yZWFkKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgc3NsX2FkZHJlc3MsIGpvYmplY3QgZmRPYmplY3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgam9iamVjdCBzaGMsIGpieXRlQXJyYXkgYiwgamludCBvZmZzZXQsIGppbnQgbGVuLCBqaW50IHRpbWVvdXQpCit7CisgICAgU1NMKiBzc2wgPSB0b19TU0woZW52LCBzc2xfYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9yZWFkIGZkPSVwIHNoYz0lcCBiPSVwIG9mZnNldD0lZCBsZW49JWQgdGltZW91dD0lZCIsCisgICAgICAgICAgICAgIHNzbCwgZmRPYmplY3QsIHNoYywgYiwgb2Zmc2V0LCBsZW4sIHRpbWVvdXQpOworICAgIGlmIChzc2wgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgaWYgKGZkT2JqZWN0ID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsICJmZCA9PSBudWxsIik7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfcmVhZCA9PiBmZCA9PSBudWxsIiwgc3NsKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGlmIChzaGMgPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd051bGxQb2ludGVyRXhjZXB0aW9uKGVudiwgInNzbEhhbmRzaGFrZUNhbGxiYWNrcyA9PSBudWxsIik7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfcmVhZCA9PiBzc2xIYW5kc2hha2VDYWxsYmFja3MgPT0gbnVsbCIsIHNzbCk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIFNjb3BlZEJ5dGVBcnJheVJXIGJ5dGVzKGVudiwgYik7CisgICAgaWYgKGJ5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9yZWFkID0+IHRocmV3IGV4Y2VwdGlvbiIsIHNzbCk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBpbnQgcmV0dXJuQ29kZSA9IDA7CisgICAgaW50IHNzbEVycm9yQ29kZSA9IFNTTF9FUlJPUl9OT05FOzsKKworICAgIGludCByZXQgPSBzc2xSZWFkKGVudiwgc3NsLCBmZE9iamVjdCwgc2hjLCByZWludGVycHJldF9jYXN0PGNoYXIqPihieXRlcy5nZXQoKSArIG9mZnNldCksIGxlbiwKKyAgICAgICAgICAgICAgICAgICAgICAmcmV0dXJuQ29kZSwgJnNzbEVycm9yQ29kZSwgdGltZW91dCk7CisKKyAgICBpbnQgcmVzdWx0OworICAgIHN3aXRjaCAocmV0KSB7CisgICAgICAgIGNhc2UgVEhST1dfU1NMRVhDRVBUSU9OOgorICAgICAgICAgICAgLy8gU2VlIHNzbFJlYWQoKSByZWdhcmRpbmcgaW1wcm9wZXIgZmFpbHVyZSB0byBoYW5kbGUgbm9ybWFsIGNhc2VzLgorICAgICAgICAgICAgdGhyb3dTU0xFeGNlcHRpb25XaXRoU3NsRXJyb3JzKGVudiwgc3NsLCBzc2xFcnJvckNvZGUsICJSZWFkIGVycm9yIik7CisgICAgICAgICAgICByZXN1bHQgPSAtMTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFRIUk9XX1NPQ0tFVFRJTUVPVVRFWENFUFRJT046CisgICAgICAgICAgICB0aHJvd1NvY2tldFRpbWVvdXRFeGNlcHRpb24oZW52LCAiUmVhZCB0aW1lZCBvdXQiKTsKKyAgICAgICAgICAgIHJlc3VsdCA9IC0xOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgVEhST1dOX0VYQ0VQVElPTjoKKyAgICAgICAgICAgIC8vIFNvY2tldEV4Y2VwdGlvbiB0aHJvd24gYnkgTmV0RmQuaXNDbG9zZWQKKyAgICAgICAgICAgIC8vIG9yIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGJ5IGNhbGxiYWNrCisgICAgICAgICAgICByZXN1bHQgPSAtMTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgcmVzdWx0ID0gcmV0OworICAgICAgICAgICAgYnJlYWs7CisgICAgfQorCisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9yZWFkID0+ICVkIiwgc3NsLCByZXN1bHQpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qKgorICogSGVscGVyIGZ1bmN0aW9uIHdoaWNoIGRvZXMgdGhlIGFjdHVhbCB3cml0aW5nLiBUaGUgSmF2YSBsYXllciBndWFyYW50ZWVzIHRoYXQKKyAqIGF0IG1vc3Qgb25lIHRocmVhZCB3aWxsIGVudGVyIHRoaXMgZnVuY3Rpb24gYXQgYW55IGdpdmVuIHRpbWUuCisgKgorICogQHBhcmFtIHNzbCBub24tbnVsbDsgdGhlIFNTTCBjb250ZXh0CisgKiBAcGFyYW0gYnVmIG5vbi1udWxsOyBidWZmZXIgdG8gd3JpdGUKKyAqIEBwYXJhbSBsZW4gbGVuZ3RoIG9mIHRoZSBidWZmZXIsIGluIGJ5dGVzCisgKiBAcGFyYW0gc3NsUmV0dXJuQ29kZSBvcmlnaW5hbCBTU0wgcmV0dXJuIGNvZGUKKyAqIEBwYXJhbSBzc2xFcnJvckNvZGUgZmlsbGVkIGluIHdpdGggdGhlIFNTTCBlcnJvciBjb2RlIGluIGNhc2Ugb2YgZXJyb3IKKyAqIEByZXR1cm4gbnVtYmVyIG9mIGJ5dGVzIHJlYWQgb24gc3VjY2VzcywgLTEgaWYgdGhlIGNvbm5lY3Rpb24gd2FzCisgKiBjbGVhbmx5IHNodXQgZG93biwgb3IgVEhST1dfU1NMRVhDRVBUSU9OIGlmIGFuIGV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLgorICovCitzdGF0aWMgaW50IHNzbFdyaXRlKEpOSUVudiogZW52LCBTU0wqIHNzbCwgam9iamVjdCBmZE9iamVjdCwgam9iamVjdCBzaGMsIGNvbnN0IGNoYXIqIGJ1ZiwgamludCBsZW4sCisgICAgICAgICAgICAgICAgICAgIGludCogc3NsUmV0dXJuQ29kZSwgaW50KiBzc2xFcnJvckNvZGUpIHsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBzc2xXcml0ZSBidWY9JXAgbGVuPSVkIiwgc3NsLCBidWYsIGxlbik7CisKKyAgICBpZiAobGVuID09IDApIHsKKyAgICAgICAgLy8gRG9uJ3QgYm90aGVyIGRvaW5nIGFueXRoaW5nIGluIHRoaXMgY2FzZS4KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgQklPKiBiaW8gPSBTU0xfZ2V0X3diaW8oc3NsKTsKKworICAgIEFwcERhdGEqIGFwcERhdGEgPSB0b0FwcERhdGEoc3NsKTsKKyAgICBpZiAoYXBwRGF0YSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBUSFJPV19TU0xFWENFUFRJT047CisgICAgfQorCisgICAgaW50IGNvdW50ID0gbGVuOworCisgICAgd2hpbGUgKGFwcERhdGEtPmFsaXZlQW5kS2lja2luZyAmJiBsZW4gPiAwKSB7CisgICAgICAgIGVycm5vID0gMDsKKworICAgICAgICBpZiAoTVVURVhfTE9DSyhhcHBEYXRhLT5tdXRleCkgPT0gLTEpIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorCisgICAgICAgIHVuc2lnbmVkIGludCBieXRlc01vdmVkID0gQklPX251bWJlcl9yZWFkKGJpbykgKyBCSU9fbnVtYmVyX3dyaXR0ZW4oYmlvKTsKKworICAgICAgICAvLyBMT0dEKCJEb2luZyBTU0xfd3JpdGUoKSB3aXRoICVkIGJ5dGVzIHRvIGdvIiwgbGVuKTsKKyAgICAgICAgaWYgKCFhcHBEYXRhLT5zZXRDYWxsYmFja1N0YXRlKGVudiwgc2hjLCBmZE9iamVjdCkpIHsKKyAgICAgICAgICAgIE1VVEVYX1VOTE9DSyhhcHBEYXRhLT5tdXRleCk7CisgICAgICAgICAgICByZXR1cm4gVEhST1dOX0VYQ0VQVElPTjsKKyAgICAgICAgfQorICAgICAgICBpbnQgcmVzdWx0ID0gU1NMX3dyaXRlKHNzbCwgYnVmLCBsZW4pOworICAgICAgICBhcHBEYXRhLT5jbGVhckNhbGxiYWNrU3RhdGUoKTsKKyAgICAgICAgLy8gY2FsbGJhY2tzIGNhbiBoYXBwZW4gaWYgc2VydmVyIHJlcXVlc3RzIHJlbmVnb3RpYXRpb24KKyAgICAgICAgaWYgKGVudi0+RXhjZXB0aW9uQ2hlY2soKSkgeworICAgICAgICAgICAgU1NMX2NsZWFyKHNzbCk7CisgICAgICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBzc2xXcml0ZSBleGNlcHRpb24gPT4gVEhST1dOX0VYQ0VQVElPTiIsIHNzbCk7CisgICAgICAgICAgICByZXR1cm4gVEhST1dOX0VYQ0VQVElPTjsKKyAgICAgICAgfQorICAgICAgICBpbnQgc3NsRXJyb3IgPSBTU0xfRVJST1JfTk9ORTsKKyAgICAgICAgaWYgKHJlc3VsdCA8PSAwKSB7CisgICAgICAgICAgICBzc2xFcnJvciA9IFNTTF9nZXRfZXJyb3Ioc3NsLCByZXN1bHQpOworICAgICAgICAgICAgZnJlZU9wZW5Tc2xFcnJvclN0YXRlKCk7CisgICAgICAgIH0KKyAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgc3NsV3JpdGUgU1NMX3dyaXRlIHJlc3VsdD0lZCBzc2xFcnJvcj0lZCIsIHNzbCwgcmVzdWx0LCBzc2xFcnJvcik7CisjaWZkZWYgV0lUSF9KTklfVFJBQ0VfREFUQQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlc3VsdDsgaSs9IFdJVEhfSk5JX1RSQUNFX0RBVEFfQ0hVTktfU0laRSkgeworICAgICAgICAgICAgaW50IG4gPSBzdGQ6Om1pbihyZXN1bHQgLSBpLCBXSVRIX0pOSV9UUkFDRV9EQVRBX0NIVU5LX1NJWkUpOworICAgICAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgc3NsV3JpdGUgZGF0YTogJWQ6XG4lKnMiLCBzc2wsIG4sIG4sIGJ1ZitpKTsKKyAgICAgICAgfQorI2VuZGlmCisKKyAgICAgICAgLy8gSWYgd2UgaGF2ZSBiZWVuIHN1Y2Nlc3NmdWwgaW4gbW92aW5nIGRhdGEgYXJvdW5kLCBjaGVjayB3aGV0aGVyIGl0CisgICAgICAgIC8vIG1pZ2h0IG1ha2Ugc2Vuc2UgdG8gd2FrZSB1cCBvdGhlciBibG9ja2VkIHRocmVhZHMsIHNvIHRoZXkgY2FuIGdpdmUKKyAgICAgICAgLy8gaXQgYSB0cnksIHRvby4KKyAgICAgICAgaWYgKEJJT19udW1iZXJfcmVhZChiaW8pICsgQklPX251bWJlcl93cml0dGVuKGJpbykgIT0gYnl0ZXNNb3ZlZAorICAgICAgICAgICAgICAgICYmIGFwcERhdGEtPndhaXRpbmdUaHJlYWRzID4gMCkgeworICAgICAgICAgICAgc3NsTm90aWZ5KGFwcERhdGEpOworICAgICAgICB9CisKKyAgICAgICAgLy8gSWYgd2UgYXJlIGJsb2NrZWQgYnkgdGhlIHVuZGVybHlpbmcgc29ja2V0LCB0ZWxsIHRoZSB3b3JsZCB0aGF0CisgICAgICAgIC8vIHRoZXJlIHdpbGwgYmUgb25lIG1vcmUgd2FpdGluZyB0aHJlYWQgbm93LgorICAgICAgICBpZiAoc3NsRXJyb3IgPT0gU1NMX0VSUk9SX1dBTlRfUkVBRCB8fCBzc2xFcnJvciA9PSBTU0xfRVJST1JfV0FOVF9XUklURSkgeworICAgICAgICAgICAgYXBwRGF0YS0+d2FpdGluZ1RocmVhZHMrKzsKKyAgICAgICAgfQorCisgICAgICAgIE1VVEVYX1VOTE9DSyhhcHBEYXRhLT5tdXRleCk7CisKKyAgICAgICAgc3dpdGNoIChzc2xFcnJvcikgeworICAgICAgICAgICAgLy8gU3VjY2Vzc2Z1bGx5IHdyb3RlIGF0IGxlYXN0IG9uZSBieXRlLgorICAgICAgICAgICAgY2FzZSBTU0xfRVJST1JfTk9ORTogeworICAgICAgICAgICAgICAgIGJ1ZiArPSByZXN1bHQ7CisgICAgICAgICAgICAgICAgbGVuIC09IHJlc3VsdDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gV3JvdGUgemVybyBieXRlcy4gRW5kIG9mIHN0cmVhbSByZWFjaGVkLgorICAgICAgICAgICAgY2FzZSBTU0xfRVJST1JfWkVST19SRVRVUk46IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIE5lZWQgdG8gd2FpdCBmb3IgYXZhaWxhYmlsaXR5IG9mIHVuZGVybHlpbmcgbGF5ZXIsIHRoZW4gcmV0cnkuCisgICAgICAgICAgICAvLyBUaGUgY29uY2VwdCBvZiBhIHdyaXRlIHRpbWVvdXQgZG9lc24ndCByZWFsbHkgbWFrZSBzZW5zZSwgYW5kCisgICAgICAgICAgICAvLyBpdCdzIGFsc28gbm90IHN0YW5kYXJkIEphdmEgYmVoYXZpb3IsIHNvIHdlIHdhaXQgZm9yZXZlciBoZXJlLgorICAgICAgICAgICAgY2FzZSBTU0xfRVJST1JfV0FOVF9SRUFEOgorICAgICAgICAgICAgY2FzZSBTU0xfRVJST1JfV0FOVF9XUklURTogeworICAgICAgICAgICAgICAgIGludCBzZWxlY3RSZXN1bHQgPSBzc2xTZWxlY3QoZW52LCBzc2xFcnJvciwgZmRPYmplY3QsIGFwcERhdGEsIDApOworICAgICAgICAgICAgICAgIGlmIChzZWxlY3RSZXN1bHQgPT0gVEhST1dOX0VYQ0VQVElPTikgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gVEhST1dOX0VYQ0VQVElPTjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHNlbGVjdFJlc3VsdCA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAqc3NsUmV0dXJuQ29kZSA9IC0xOworICAgICAgICAgICAgICAgICAgICAqc3NsRXJyb3JDb2RlID0gc3NsRXJyb3I7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBUSFJPV19TU0xFWENFUFRJT047CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChzZWxlY3RSZXN1bHQgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gVEhST1dfU09DS0VUVElNRU9VVEVYQ0VQVElPTjsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gQSBwcm9ibGVtIG9jY3VycmVkIGR1cmluZyBhIHN5c3RlbSBjYWxsLCBidXQgdGhpcyBpcyBub3QKKyAgICAgICAgICAgIC8vIG5lY2Vzc2FyaWx5IGFuIGVycm9yLgorICAgICAgICAgICAgY2FzZSBTU0xfRVJST1JfU1lTQ0FMTDogeworICAgICAgICAgICAgICAgIC8vIENvbm5lY3Rpb24gY2xvc2VkIHdpdGhvdXQgcHJvcGVyIHNodXRkb3duLiBUZWxsIGNhbGxlciB3ZQorICAgICAgICAgICAgICAgIC8vIGhhdmUgcmVhY2hlZCBlbmQtb2Ytc3RyZWFtLgorICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gU3lzdGVtIGNhbGwgaGFzIGJlZW4gaW50ZXJydXB0ZWQuIFNpbXBseSByZXRyeS4KKyAgICAgICAgICAgICAgICBpZiAoZXJybm8gPT0gRUlOVFIpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gTm90ZSB0aGF0IGZvciBhbGwgb3RoZXIgc3lzdGVtIGNhbGwgZXJyb3JzIHdlIGZhbGwgdGhyb3VnaAorICAgICAgICAgICAgICAgIC8vIHRvIHRoZSBkZWZhdWx0IGNhc2UsIHdoaWNoIHJlc3VsdHMgaW4gYW4gRXhjZXB0aW9uLgorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBFdmVyeXRoaW5nIGVsc2UgaXMgYmFzaWNhbGx5IGFuIGVycm9yLgorICAgICAgICAgICAgZGVmYXVsdDogeworICAgICAgICAgICAgICAgICpzc2xSZXR1cm5Db2RlID0gcmVzdWx0OworICAgICAgICAgICAgICAgICpzc2xFcnJvckNvZGUgPSBzc2xFcnJvcjsKKyAgICAgICAgICAgICAgICByZXR1cm4gVEhST1dfU1NMRVhDRVBUSU9OOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIEpOSV9UUkFDRSgic3NsPSVwIHNzbFdyaXRlID0+IGNvdW50PSVkIiwgc3NsLCBjb3VudCk7CisKKyAgICByZXR1cm4gY291bnQ7Cit9CisKKy8qKgorICogT3BlblNTTCB3cml0ZSBmdW5jdGlvbiAoMik6IHdyaXRlIGludG8gYnVmZmVyIGF0IG9mZnNldCBuIGNodW5rcy4KKyAqLworc3RhdGljIHZvaWQgTmF0aXZlQ3J5cHRvX1NTTF93cml0ZShKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IHNzbF9hZGRyZXNzLCBqb2JqZWN0IGZkT2JqZWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqb2JqZWN0IHNoYywgamJ5dGVBcnJheSBiLCBqaW50IG9mZnNldCwgamludCBsZW4pCit7CisgICAgU1NMKiBzc2wgPSB0b19TU0woZW52LCBzc2xfYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF93cml0ZSBmZD0lcCBzaGM9JXAgYj0lcCBvZmZzZXQ9JWQgbGVuPSVkIiwKKyAgICAgICAgICAgICAgc3NsLCBmZE9iamVjdCwgc2hjLCBiLCBvZmZzZXQsIGxlbik7CisgICAgaWYgKHNzbCA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKGZkT2JqZWN0ID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsICJmZCA9PSBudWxsIik7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfd3JpdGUgPT4gZmQgPT0gbnVsbCIsIHNzbCk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKHNoYyA9PSBOVUxMKSB7CisgICAgICAgIGpuaVRocm93TnVsbFBvaW50ZXJFeGNlcHRpb24oZW52LCAic3NsSGFuZHNoYWtlQ2FsbGJhY2tzID09IG51bGwiKTsKKyAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF93cml0ZSA9PiBzc2xIYW5kc2hha2VDYWxsYmFja3MgPT0gbnVsbCIsIHNzbCk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBTY29wZWRCeXRlQXJyYXlSTyBieXRlcyhlbnYsIGIpOworICAgIGlmIChieXRlcy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfd3JpdGUgPT4gdGhyZXcgZXhjZXB0aW9uIiwgc3NsKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpbnQgcmV0dXJuQ29kZSA9IDA7CisgICAgaW50IHNzbEVycm9yQ29kZSA9IFNTTF9FUlJPUl9OT05FOworICAgIGludCByZXQgPSBzc2xXcml0ZShlbnYsIHNzbCwgZmRPYmplY3QsIHNoYywgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4oYnl0ZXMuZ2V0KCkgKyBvZmZzZXQpLAorICAgICAgICAgICAgICAgICAgICAgICBsZW4sICZyZXR1cm5Db2RlLCAmc3NsRXJyb3JDb2RlKTsKKworICAgIHN3aXRjaCAocmV0KSB7CisgICAgICAgIGNhc2UgVEhST1dfU1NMRVhDRVBUSU9OOgorICAgICAgICAgICAgLy8gU2VlIHNzbFdyaXRlKCkgcmVnYXJkaW5nIGltcHJvcGVyIGZhaWx1cmUgdG8gaGFuZGxlIG5vcm1hbCBjYXNlcy4KKyAgICAgICAgICAgIHRocm93U1NMRXhjZXB0aW9uV2l0aFNzbEVycm9ycyhlbnYsIHNzbCwgc3NsRXJyb3JDb2RlLCAiV3JpdGUgZXJyb3IiKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFRIUk9XX1NPQ0tFVFRJTUVPVVRFWENFUFRJT046CisgICAgICAgICAgICB0aHJvd1NvY2tldFRpbWVvdXRFeGNlcHRpb24oZW52LCAiV3JpdGUgdGltZWQgb3V0Iik7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBUSFJPV05fRVhDRVBUSU9OOgorICAgICAgICAgICAgLy8gU29ja2V0RXhjZXB0aW9uIHRocm93biBieSBOZXRGZC5pc0Nsb3NlZAorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBicmVhazsKKyAgICB9Cit9CisKKy8qKgorICogSW50ZXJydXB0IGFueSBwZW5kaW5nIElPIGJlZm9yZSBjbG9zaW5nIHRoZSBzb2NrZXQuCisgKi8KK3N0YXRpYyB2b2lkIE5hdGl2ZUNyeXB0b19TU0xfaW50ZXJydXB0KAorICAgICAgICBKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IHNzbF9hZGRyZXNzKSB7CisgICAgU1NMKiBzc2wgPSB0b19TU0woZW52LCBzc2xfYWRkcmVzcywgZmFsc2UpOworICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfaW50ZXJydXB0Iiwgc3NsKTsKKyAgICBpZiAoc3NsID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIC8qCisgICAgICogTWFyayB0aGUgY29ubmVjdGlvbiBhcyBxdWFzaS1kZWFkLCB0aGVuIHNlbmQgc29tZXRoaW5nIHRvIHRoZSBlbWVyZ2VuY3kKKyAgICAgKiBmaWxlIGRlc2NyaXB0b3IsIHNvIGFueSBibG9ja2luZyBzZWxlY3QoKSBjYWxscyBhcmUgd29rZW4gdXAuCisgICAgICovCisgICAgQXBwRGF0YSogYXBwRGF0YSA9IHRvQXBwRGF0YShzc2wpOworICAgIGlmIChhcHBEYXRhICE9IE5VTEwpIHsKKyAgICAgICAgYXBwRGF0YS0+YWxpdmVBbmRLaWNraW5nID0gMDsKKworICAgICAgICAvLyBBdCBtb3N0IHR3byB0aHJlYWRzIGNhbiBiZSB3YWl0aW5nLgorICAgICAgICBzc2xOb3RpZnkoYXBwRGF0YSk7CisgICAgICAgIHNzbE5vdGlmeShhcHBEYXRhKTsKKyAgICB9Cit9CisKKy8qKgorICogT3BlblNTTCBjbG9zZSBTU0wgc29ja2V0IGZ1bmN0aW9uLgorICovCitzdGF0aWMgdm9pZCBOYXRpdmVDcnlwdG9fU1NMX3NodXRkb3duKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgc3NsX2FkZHJlc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpvYmplY3QgZmRPYmplY3QsIGpvYmplY3Qgc2hjKSB7CisgICAgU1NMKiBzc2wgPSB0b19TU0woZW52LCBzc2xfYWRkcmVzcywgZmFsc2UpOworICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfc2h1dGRvd24gZmQ9JXAgc2hjPSVwIiwgc3NsLCBmZE9iamVjdCwgc2hjKTsKKyAgICBpZiAoc3NsID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoZmRPYmplY3QgPT0gTlVMTCkgeworICAgICAgICBqbmlUaHJvd051bGxQb2ludGVyRXhjZXB0aW9uKGVudiwgImZkID09IG51bGwiKTsKKyAgICAgICAgSk5JX1RSQUNFKCJzc2w9JXAgTmF0aXZlQ3J5cHRvX1NTTF9zaHV0ZG93biA9PiBmZCA9PSBudWxsIiwgc3NsKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoc2hjID09IE5VTEwpIHsKKyAgICAgICAgam5pVGhyb3dOdWxsUG9pbnRlckV4Y2VwdGlvbihlbnYsICJzc2xIYW5kc2hha2VDYWxsYmFja3MgPT0gbnVsbCIpOworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3NodXRkb3duID0+IHNzbEhhbmRzaGFrZUNhbGxiYWNrcyA9PSBudWxsIiwgc3NsKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIEFwcERhdGEqIGFwcERhdGEgPSB0b0FwcERhdGEoc3NsKTsKKyAgICBpZiAoYXBwRGF0YSAhPSBOVUxMKSB7CisgICAgICAgIGlmICghYXBwRGF0YS0+c2V0Q2FsbGJhY2tTdGF0ZShlbnYsIHNoYywgZmRPYmplY3QpKSB7CisgICAgICAgICAgICAvLyBTb2NrZXRFeGNlcHRpb24gdGhyb3duIGJ5IE5ldEZkLmlzQ2xvc2VkCisgICAgICAgICAgICBTU0xfY2xlYXIoc3NsKTsKKyAgICAgICAgICAgIGZyZWVPcGVuU3NsRXJyb3JTdGF0ZSgpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVHJ5IHRvIG1ha2Ugc29ja2V0IGJsb2NraW5nIGFnYWluLiBPcGVuU1NMIGxpdGVyYXR1cmUgcmVjb21tZW5kcyB0aGlzLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IGZkID0gU1NMX2dldF9mZChzc2wpOworICAgICAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX3NodXRkb3duIHM9JWQiLCBzc2wsIGZkKTsKKyAgICAgICAgaWYgKGZkICE9IC0xKSB7CisgICAgICAgICAgICBzZXRCbG9ja2luZyhmZCwgdHJ1ZSk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgcmV0ID0gU1NMX3NodXRkb3duKHNzbCk7CisgICAgICAgIGFwcERhdGEtPmNsZWFyQ2FsbGJhY2tTdGF0ZSgpOworICAgICAgICAvLyBjYWxsYmFja3MgY2FuIGhhcHBlbiBpZiBzZXJ2ZXIgcmVxdWVzdHMgcmVuZWdvdGlhdGlvbgorICAgICAgICBpZiAoZW52LT5FeGNlcHRpb25DaGVjaygpKSB7CisgICAgICAgICAgICBTU0xfY2xlYXIoc3NsKTsKKyAgICAgICAgICAgIEpOSV9UUkFDRSgic3NsPSVwIE5hdGl2ZUNyeXB0b19TU0xfc2h1dGRvd24gPT4gZXhjZXB0aW9uIiwgc3NsKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKHJldCkgeworICAgICAgICAgICAgY2FzZSAwOgorICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogU2h1dGRvd24gd2FzIG5vdCBzdWNjZXNzZnVsICh5ZXQpLCBidXQgdGhlcmUgYWxzbworICAgICAgICAgICAgICAgICAqIGlzIG5vIGVycm9yLiBTaW5jZSB3ZSBjYW4ndCBrbm93IHdoZXRoZXIgdGhlIHJlbW90ZQorICAgICAgICAgICAgICAgICAqIHNlcnZlciBpcyBhY3R1YWxseSBzdGlsbCB0aGVyZSwgYW5kIHdlIGRvbid0IHdhbnQgdG8KKyAgICAgICAgICAgICAgICAgKiBnZXQgc3R1Y2sgZm9yZXZlciBpbiBhIHNlY29uZCBTU0xfc2h1dGRvd24oKSBjYWxsLCB3ZQorICAgICAgICAgICAgICAgICAqIHNpbXBseSByZXR1cm4uIFRoaXMgaXMgbm90IHNlY3VyaXR5IGEgcHJvYmxlbSBhcyBsb25nCisgICAgICAgICAgICAgICAgICogYXMgd2UgY2xvc2UgdGhlIHVuZGVybHlpbmcgc29ja2V0LCB3aGljaCB3ZSBhY3R1YWxseQorICAgICAgICAgICAgICAgICAqIGRvLCBiZWNhdXNlIHRoYXQncyB3aGVyZSB3ZSBhcmUganVzdCBjb21pbmcgZnJvbS4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgMToKKyAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAqIFNodXRkb3duIHdhcyBzdWNjZXNzZnVsLiBXZSBjYW4gc2FmZWx5IHJldHVybi4gSG9vcmF5IQorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAqIEV2ZXJ5dGhpbmcgZWxzZSBpcyBhIHJlYWwgZXJyb3IgY29uZGl0aW9uLiBXZSBzaG91bGQKKyAgICAgICAgICAgICAgICAgKiBsZXQgdGhlIEphdmEgbGF5ZXIga25vdyBhYm91dCB0aGlzIGJ5IHRocm93aW5nIGFuCisgICAgICAgICAgICAgICAgICogZXhjZXB0aW9uLgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIGludCBzc2xFcnJvciA9IFNTTF9nZXRfZXJyb3Ioc3NsLCByZXQpOworICAgICAgICAgICAgICAgIHRocm93U1NMRXhjZXB0aW9uV2l0aFNzbEVycm9ycyhlbnYsIHNzbCwgc3NsRXJyb3IsICJTU0wgc2h1dGRvd24gZmFpbGVkIik7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBTU0xfY2xlYXIoc3NsKTsKKyAgICBmcmVlT3BlblNzbEVycm9yU3RhdGUoKTsKK30KKworLyoqCisgKiBwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFNTTF9mcmVlKGludCBzc2wpOworICovCitzdGF0aWMgdm9pZCBOYXRpdmVDcnlwdG9fU1NMX2ZyZWUoSk5JRW52KiBlbnYsIGpjbGFzcywgamludCBzc2xfYWRkcmVzcykKK3sKKyAgICBTU0wqIHNzbCA9IHRvX1NTTChlbnYsIHNzbF9hZGRyZXNzLCB0cnVlKTsKKyAgICBKTklfVFJBQ0UoInNzbD0lcCBOYXRpdmVDcnlwdG9fU1NMX2ZyZWUiLCBzc2wpOworICAgIGlmIChzc2wgPT0gTlVMTCkgeworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgQXBwRGF0YSogYXBwRGF0YSA9IHRvQXBwRGF0YShzc2wpOworICAgIFNTTF9zZXRfYXBwX2RhdGEoc3NsLCBOVUxMKTsKKyAgICBkZWxldGUgYXBwRGF0YTsKKyAgICBTU0xfZnJlZShzc2wpOworfQorCisvKioKKyAqIEdldHMgYW5kIHJldHVybnMgaW4gYSBieXRlIGFycmF5IHRoZSBJRCBvZiB0aGUgYWN0dWFsIFNTTCBzZXNzaW9uLgorICovCitzdGF0aWMgamJ5dGVBcnJheSBOYXRpdmVDcnlwdG9fU1NMX1NFU1NJT05fc2Vzc2lvbl9pZChKTklFbnYqIGVudiwgamNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamludCBzc2xfc2Vzc2lvbl9hZGRyZXNzKSB7CisgICAgU1NMX1NFU1NJT04qIHNzbF9zZXNzaW9uID0gdG9fU1NMX1NFU1NJT04oZW52LCBzc2xfc2Vzc2lvbl9hZGRyZXNzLCB0cnVlKTsKKyAgICBKTklfVFJBQ0UoInNzbF9zZXNzaW9uPSVwIE5hdGl2ZUNyeXB0b19TU0xfU0VTU0lPTl9zZXNzaW9uX2lkIiwgc3NsX3Nlc3Npb24pOworICAgIGlmIChzc2xfc2Vzc2lvbiA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBqYnl0ZUFycmF5IHJlc3VsdCA9IGVudi0+TmV3Qnl0ZUFycmF5KHNzbF9zZXNzaW9uLT5zZXNzaW9uX2lkX2xlbmd0aCk7CisgICAgaWYgKHJlc3VsdCAhPSBOVUxMKSB7CisgICAgICAgIGpieXRlKiBzcmMgPSByZWludGVycHJldF9jYXN0PGpieXRlKj4oc3NsX3Nlc3Npb24tPnNlc3Npb25faWQpOworICAgICAgICBlbnYtPlNldEJ5dGVBcnJheVJlZ2lvbihyZXN1bHQsIDAsIHNzbF9zZXNzaW9uLT5zZXNzaW9uX2lkX2xlbmd0aCwgc3JjKTsKKyAgICB9CisgICAgSk5JX1RSQUNFKCJzc2xfc2Vzc2lvbj0lcCBOYXRpdmVDcnlwdG9fU1NMX1NFU1NJT05fc2Vzc2lvbl9pZCA9PiAlcCBzZXNzaW9uX2lkX2xlbmd0aD0lZCIsCisgICAgICAgICAgICAgc3NsX3Nlc3Npb24sIHJlc3VsdCwgc3NsX3Nlc3Npb24tPnNlc3Npb25faWRfbGVuZ3RoKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKioKKyAqIEdldHMgYW5kIHJldHVybnMgaW4gYSBsb25nIGludGVnZXIgdGhlIGNyZWF0aW9uJ3MgdGltZSBvZiB0aGUKKyAqIGFjdHVhbCBTU0wgc2Vzc2lvbi4KKyAqLworc3RhdGljIGpsb25nIE5hdGl2ZUNyeXB0b19TU0xfU0VTU0lPTl9nZXRfdGltZShKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IHNzbF9zZXNzaW9uX2FkZHJlc3MpIHsKKyAgICBTU0xfU0VTU0lPTiogc3NsX3Nlc3Npb24gPSB0b19TU0xfU0VTU0lPTihlbnYsIHNzbF9zZXNzaW9uX2FkZHJlc3MsIHRydWUpOworICAgIEpOSV9UUkFDRSgic3NsX3Nlc3Npb249JXAgTmF0aXZlQ3J5cHRvX1NTTF9TRVNTSU9OX2dldF90aW1lIiwgc3NsX3Nlc3Npb24pOworICAgIGlmIChzc2xfc2Vzc2lvbiA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICAvLyByZXN1bHQgbXVzdCBiZSBqbG9uZywgbm90IGxvbmcgb3IgKjEwMDAgd2lsbCBvdmVyZmxvdworICAgIGpsb25nIHJlc3VsdCA9IFNTTF9TRVNTSU9OX2dldF90aW1lKHNzbF9zZXNzaW9uKTsKKyAgICByZXN1bHQgKj0gMTAwMDsgLy8gT3BlblNTTCB1c2VzIHNlY29uZHMsIEphdmEgdXNlcyBtaWxsaXNlY29uZHMuCisgICAgSk5JX1RSQUNFKCJzc2xfc2Vzc2lvbj0lcCBOYXRpdmVDcnlwdG9fU1NMX1NFU1NJT05fZ2V0X3RpbWUgPT4gJWxsZCIsIHNzbF9zZXNzaW9uLCByZXN1bHQpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qKgorICogR2V0cyBhbmQgcmV0dXJucyBpbiBhIHN0cmluZyB0aGUgdmVyc2lvbiBvZiB0aGUgU1NMIHByb3RvY29sLiBJZiBpdAorICogcmV0dXJucyB0aGUgc3RyaW5nICJ1bmtub3duIiBpdCBtZWFucyB0aGF0IG5vIGNvbm5lY3Rpb24gaXMgZXN0YWJsaXNoZWQuCisgKi8KK3N0YXRpYyBqc3RyaW5nIE5hdGl2ZUNyeXB0b19TU0xfU0VTU0lPTl9nZXRfdmVyc2lvbihKTklFbnYqIGVudiwgamNsYXNzLCBqaW50IHNzbF9zZXNzaW9uX2FkZHJlc3MpIHsKKyAgICBTU0xfU0VTU0lPTiogc3NsX3Nlc3Npb24gPSB0b19TU0xfU0VTU0lPTihlbnYsIHNzbF9zZXNzaW9uX2FkZHJlc3MsIHRydWUpOworICAgIEpOSV9UUkFDRSgic3NsX3Nlc3Npb249JXAgTmF0aXZlQ3J5cHRvX1NTTF9TRVNTSU9OX2dldF92ZXJzaW9uIiwgc3NsX3Nlc3Npb24pOworICAgIGlmIChzc2xfc2Vzc2lvbiA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBjb25zdCBjaGFyKiBwcm90b2NvbCA9IFNTTF9TRVNTSU9OX2dldF92ZXJzaW9uKHNzbF9zZXNzaW9uKTsKKyAgICBKTklfVFJBQ0UoInNzbF9zZXNzaW9uPSVwIE5hdGl2ZUNyeXB0b19TU0xfU0VTU0lPTl9nZXRfdmVyc2lvbiA9PiAlcyIsIHNzbF9zZXNzaW9uLCBwcm90b2NvbCk7CisgICAgcmV0dXJuIGVudi0+TmV3U3RyaW5nVVRGKHByb3RvY29sKTsKK30KKworLyoqCisgKiBHZXRzIGFuZCByZXR1cm5zIGluIGEgc3RyaW5nIHRoZSBjaXBoZXIgbmVnb3RpYXRlZCBmb3IgdGhlIFNTTCBzZXNzaW9uLgorICovCitzdGF0aWMganN0cmluZyBOYXRpdmVDcnlwdG9fU1NMX1NFU1NJT05fY2lwaGVyKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgc3NsX3Nlc3Npb25fYWRkcmVzcykgeworICAgIFNTTF9TRVNTSU9OKiBzc2xfc2Vzc2lvbiA9IHRvX1NTTF9TRVNTSU9OKGVudiwgc3NsX3Nlc3Npb25fYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2xfc2Vzc2lvbj0lcCBOYXRpdmVDcnlwdG9fU1NMX1NFU1NJT05fY2lwaGVyIiwgc3NsX3Nlc3Npb24pOworICAgIGlmIChzc2xfc2Vzc2lvbiA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBjb25zdCBTU0xfQ0lQSEVSKiBjaXBoZXIgPSBzc2xfc2Vzc2lvbi0+Y2lwaGVyOworICAgIGNvbnN0IGNoYXIqIG5hbWUgPSBTU0xfQ0lQSEVSX2dldF9uYW1lKGNpcGhlcik7CisgICAgSk5JX1RSQUNFKCJzc2xfc2Vzc2lvbj0lcCBOYXRpdmVDcnlwdG9fU1NMX1NFU1NJT05fY2lwaGVyID0+ICVzIiwgc3NsX3Nlc3Npb24sIG5hbWUpOworICAgIHJldHVybiBlbnYtPk5ld1N0cmluZ1VURihuYW1lKTsKK30KKworLyoqCisgKiBHZXRzIGFuZCByZXR1cm5zIGluIGEgc3RyaW5nIHRoZSBjb21wcmVzc2lvbiBtZXRob2QgbmVnb3RpYXRlZCBmb3IgdGhlIFNTTCBzZXNzaW9uLgorICovCitzdGF0aWMganN0cmluZyBOYXRpdmVDcnlwdG9fU1NMX1NFU1NJT05fY29tcHJlc3NfbWV0aChKTklFbnYqIGVudiwgamNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamludCBzc2xfY3R4X2FkZHJlc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqaW50IHNzbF9zZXNzaW9uX2FkZHJlc3MpIHsKKyAgICBTU0xfQ1RYKiBzc2xfY3R4ID0gdG9fU1NMX0NUWChlbnYsIHNzbF9jdHhfYWRkcmVzcywgdHJ1ZSk7CisgICAgU1NMX1NFU1NJT04qIHNzbF9zZXNzaW9uID0gdG9fU1NMX1NFU1NJT04oZW52LCBzc2xfc2Vzc2lvbl9hZGRyZXNzLCB0cnVlKTsKKyAgICBKTklfVFJBQ0UoInNzbF9zZXNzaW9uPSVwIE5hdGl2ZUNyeXB0b19TU0xfU0VTU0lPTl9jb21wcmVzc19tZXRoIHNzbF9jdHg9JXAiLAorICAgICAgICAgICAgICBzc2xfc2Vzc2lvbiwgc3NsX2N0eCk7CisgICAgaWYgKHNzbF9jdHggPT0gTlVMTCB8fCBzc2xfc2Vzc2lvbiA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGludCBjb21wcmVzc19tZXRoID0gc3NsX3Nlc3Npb24tPmNvbXByZXNzX21ldGg7CisgICAgaWYgKGNvbXByZXNzX21ldGggPT0gMCkgeworICAgICAgICBjb25zdCBjaGFyKiBuYW1lID0gIk5VTEwiOworICAgICAgICBKTklfVFJBQ0UoInNzbF9zZXNzaW9uPSVwIE5hdGl2ZUNyeXB0b19TU0xfU0VTU0lPTl9jb21wcmVzc19tZXRoID0+ICVzIiwgc3NsX3Nlc3Npb24sIG5hbWUpOworICAgICAgICByZXR1cm4gZW52LT5OZXdTdHJpbmdVVEYobmFtZSk7CisgICAgfQorCisgICAgaW50IG51bV9jb21wX21ldGhvZHMgPSBza19TU0xfQ09NUF9udW0oc3NsX2N0eC0+Y29tcF9tZXRob2RzKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bV9jb21wX21ldGhvZHM7IGkrKykgeworICAgICAgICBTU0xfQ09NUCogY29tcCA9IHNrX1NTTF9DT01QX3ZhbHVlKHNzbF9jdHgtPmNvbXBfbWV0aG9kcywgaSk7CisgICAgICAgIGlmIChjb21wLT5pZCAhPSBjb21wcmVzc19tZXRoKSB7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBjb25zdCBjaGFyKiBuYW1lID0gKChjb21wLT5tZXRob2QgJiYgY29tcC0+bWV0aG9kLT50eXBlID09IE5JRF96bGliX2NvbXByZXNzaW9uKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gU05femxpYl9jb21wcmVzc2lvbgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKGNvbXAtPm5hbWUgPyBjb21wLT5uYW1lIDogIlVOS05PV04iKSk7CisgICAgICAgIEpOSV9UUkFDRSgic3NsX3Nlc3Npb249JXAgTmF0aXZlQ3J5cHRvX1NTTF9TRVNTSU9OX2NvbXByZXNzX21ldGggPT4gJXMiLCBzc2xfc2Vzc2lvbiwgbmFtZSk7CisgICAgICAgIHJldHVybiBlbnYtPk5ld1N0cmluZ1VURihuYW1lKTsKKyAgICB9CisgICAgdGhyb3dTU0xFeGNlcHRpb25TdHIoZW52LCAiVW5rbm93biBjb21wcmVzc2lvbiBtZXRob2QiKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworLyoqCisgKiBGcmVlcyB0aGUgU1NMIHNlc3Npb24uCisgKi8KK3N0YXRpYyB2b2lkIE5hdGl2ZUNyeXB0b19TU0xfU0VTU0lPTl9mcmVlKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgc3NsX3Nlc3Npb25fYWRkcmVzcykgeworICAgIFNTTF9TRVNTSU9OKiBzc2xfc2Vzc2lvbiA9IHRvX1NTTF9TRVNTSU9OKGVudiwgc3NsX3Nlc3Npb25fYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2xfc2Vzc2lvbj0lcCBOYXRpdmVDcnlwdG9fU1NMX1NFU1NJT05fZnJlZSIsIHNzbF9zZXNzaW9uKTsKKyAgICBpZiAoc3NsX3Nlc3Npb24gPT0gTlVMTCkgeworICAgICAgICByZXR1cm47CisgICAgfQorICAgIFNTTF9TRVNTSU9OX2ZyZWUoc3NsX3Nlc3Npb24pOworfQorCisKKy8qKgorICogU2VyaWFsaXplcyB0aGUgbmF0aXZlIHN0YXRlIG9mIHRoZSBzZXNzaW9uIChJRCwgY2lwaGVyLCBhbmQga2V5cyBidXQKKyAqIG5vdCBjZXJ0aWZpY2F0ZXMpLiBSZXR1cm5zIGEgYnl0ZVtdIGNvbnRhaW5pbmcgdGhlIERFUi1lbmNvZGVkIHN0YXRlLgorICogU2VlIGFwYWNoZSBtb2Rfc3NsLgorICovCitzdGF0aWMgamJ5dGVBcnJheSBOYXRpdmVDcnlwdG9faTJkX1NTTF9TRVNTSU9OKEpOSUVudiogZW52LCBqY2xhc3MsIGppbnQgc3NsX3Nlc3Npb25fYWRkcmVzcykgeworICAgIFNTTF9TRVNTSU9OKiBzc2xfc2Vzc2lvbiA9IHRvX1NTTF9TRVNTSU9OKGVudiwgc3NsX3Nlc3Npb25fYWRkcmVzcywgdHJ1ZSk7CisgICAgSk5JX1RSQUNFKCJzc2xfc2Vzc2lvbj0lcCBOYXRpdmVDcnlwdG9faTJkX1NTTF9TRVNTSU9OIiwgc3NsX3Nlc3Npb24pOworICAgIGlmIChzc2xfc2Vzc2lvbiA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8vIENvbXB1dGUgdGhlIHNpemUgb2YgdGhlIERFUiBkYXRhCisgICAgaW50IHNpemUgPSBpMmRfU1NMX1NFU1NJT04oc3NsX3Nlc3Npb24sIE5VTEwpOworICAgIGlmIChzaXplID09IDApIHsKKyAgICAgICAgSk5JX1RSQUNFKCJzc2xfc2Vzc2lvbj0lcCBOYXRpdmVDcnlwdG9faTJkX1NTTF9TRVNTSU9OID0+IE5VTEwiLCBzc2xfc2Vzc2lvbik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGpieXRlQXJyYXkgamF2YUJ5dGVzID0gZW52LT5OZXdCeXRlQXJyYXkoc2l6ZSk7CisgICAgaWYgKGphdmFCeXRlcyAhPSBOVUxMKSB7CisgICAgICAgIFNjb3BlZEJ5dGVBcnJheVJXIGJ5dGVzKGVudiwgamF2YUJ5dGVzKTsKKyAgICAgICAgaWYgKGJ5dGVzLmdldCgpID09IE5VTEwpIHsKKyAgICAgICAgICAgIEpOSV9UUkFDRSgic3NsX3Nlc3Npb249JXAgTmF0aXZlQ3J5cHRvX2kyZF9TU0xfU0VTU0lPTiA9PiB0aHJldyBleGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICAgIHNzbF9zZXNzaW9uKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIHVuc2lnbmVkIGNoYXIqIHVjcCA9IHJlaW50ZXJwcmV0X2Nhc3Q8dW5zaWduZWQgY2hhcio+KGJ5dGVzLmdldCgpKTsKKyAgICAgICAgaTJkX1NTTF9TRVNTSU9OKHNzbF9zZXNzaW9uLCAmdWNwKTsKKyAgICB9CisKKyAgICBKTklfVFJBQ0UoInNzbF9zZXNzaW9uPSVwIE5hdGl2ZUNyeXB0b19pMmRfU1NMX1NFU1NJT04gPT4gc2l6ZT0lZCIsIHNzbF9zZXNzaW9uLCBzaXplKTsKKyAgICByZXR1cm4gamF2YUJ5dGVzOworfQorCisvKioKKyAqIERlc2VyaWFsaXplIHRoZSBzZXNzaW9uLgorICovCitzdGF0aWMgamludCBOYXRpdmVDcnlwdG9fZDJpX1NTTF9TRVNTSU9OKEpOSUVudiogZW52LCBqY2xhc3MsIGpieXRlQXJyYXkgamF2YUJ5dGVzKSB7CisgICAgSk5JX1RSQUNFKCJOYXRpdmVDcnlwdG9fZDJpX1NTTF9TRVNTSU9OIGJ5dGVzPSVwIiwgamF2YUJ5dGVzKTsKKworICAgIFNjb3BlZEJ5dGVBcnJheVJPIGJ5dGVzKGVudiwgamF2YUJ5dGVzKTsKKyAgICBpZiAoYnl0ZXMuZ2V0KCkgPT0gTlVMTCkgeworICAgICAgICBKTklfVFJBQ0UoIk5hdGl2ZUNyeXB0b19kMmlfU1NMX1NFU1NJT04gPT4gdGhyZXcgZXhjZXB0aW9uIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBjb25zdCB1bnNpZ25lZCBjaGFyKiB1Y3AgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihieXRlcy5nZXQoKSk7CisgICAgU1NMX1NFU1NJT04qIHNzbF9zZXNzaW9uID0gZDJpX1NTTF9TRVNTSU9OKE5VTEwsICZ1Y3AsIGJ5dGVzLnNpemUoKSk7CisKKyAgICBKTklfVFJBQ0UoIk5hdGl2ZUNyeXB0b19kMmlfU1NMX1NFU1NJT04gPT4gJXAiLCBzc2xfc2Vzc2lvbik7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGppbnQ+KHJlaW50ZXJwcmV0X2Nhc3Q8dWludHB0cl90Pihzc2xfc2Vzc2lvbikpOworfQorCisjZGVmaW5lIEZJTEVfREVTQ1JJUFRPUiAiTGphdmEvaW8vRmlsZURlc2NyaXB0b3I7IgorI2RlZmluZSBTU0xfQ0FMTEJBQ0tTICJMb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9OYXRpdmVDcnlwdG8kU1NMSGFuZHNoYWtlQ2FsbGJhY2tzOyIKK3N0YXRpYyBKTklOYXRpdmVNZXRob2Qgc05hdGl2ZUNyeXB0b01ldGhvZHNbXSA9IHsKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgY2xpbml0LCAiKClWIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIEVWUF9QS0VZX25ld19EU0EsICIoW0JbQltCW0JbQilJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIEVWUF9QS0VZX25ld19SU0EsICIoW0JbQltCW0JbQilJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIEVWUF9QS0VZX2ZyZWUsICIoSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIEVWUF9NRF9DVFhfZGVzdHJveSwgIihJKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgRVZQX01EX0NUWF9jb3B5LCAiKEkpSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBFVlBfRGlnZXN0RmluYWwsICIoSVtCSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIEVWUF9EaWdlc3RJbml0LCAiKEkpSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBFVlBfZ2V0X2RpZ2VzdGJ5bmFtZSwgIihMamF2YS9sYW5nL1N0cmluZzspSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBFVlBfTURfYmxvY2tfc2l6ZSwgIihJKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgRVZQX01EX3NpemUsICIoSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIEVWUF9EaWdlc3RVcGRhdGUsICIoSVtCSUkpViIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBFVlBfVmVyaWZ5SW5pdCwgIihMamF2YS9sYW5nL1N0cmluZzspSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBFVlBfVmVyaWZ5VXBkYXRlLCAiKElbQklJKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgRVZQX1ZlcmlmeUZpbmFsLCAiKElbQklJSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIFJBTkRfc2VlZCwgIihbQilWIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIFJBTkRfbG9hZF9maWxlLCAiKExqYXZhL2xhbmcvU3RyaW5nO0opSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBTU0xfQ1RYX25ldywgIigpSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBTU0xfQ1RYX2ZyZWUsICIoSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIFNTTF9uZXcsICIoSSlJIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIFNTTF91c2VfUHJpdmF0ZUtleSwgIihJW0IpViIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBTU0xfdXNlX2NlcnRpZmljYXRlLCAiKElbW0IpViIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBTU0xfY2hlY2tfcHJpdmF0ZV9rZXksICIoSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIFNTTF9zZXRfY2xpZW50X0NBX2xpc3QsICIoSVtbQilWIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIFNTTF9nZXRfbW9kZSwgIihJKUoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgU1NMX3NldF9tb2RlLCAiKElKKUoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgU1NMX2NsZWFyX21vZGUsICIoSUopSiIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBTU0xfZ2V0X29wdGlvbnMsICIoSSlKIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIFNTTF9zZXRfb3B0aW9ucywgIihJSilKIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIFNTTF9jbGVhcl9vcHRpb25zLCAiKElKKUoiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgU1NMX3NldF9jaXBoZXJfbGlzdHMsICIoSVtMamF2YS9sYW5nL1N0cmluZzspViIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBTU0xfc2V0X3ZlcmlmeSwgIihJSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIFNTTF9zZXRfc2Vzc2lvbiwgIihJSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIFNTTF9zZXRfc2Vzc2lvbl9jcmVhdGlvbl9lbmFibGVkLCAiKElaKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgU1NMX3NldF90bHNleHRfaG9zdF9uYW1lLCAiKElMamF2YS9sYW5nL1N0cmluZzspViIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBTU0xfZ2V0X3NlcnZlcm5hbWUsICIoSSlMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgU1NMX2RvX2hhbmRzaGFrZSwgIihJIiBGSUxFX0RFU0NSSVBUT1IgU1NMX0NBTExCQUNLUyAiSVopSSIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBTU0xfcmVuZWdvdGlhdGUsICIoSSlWIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIFNTTF9nZXRfY2VydGlmaWNhdGUsICIoSSlbW0IiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgU1NMX2dldF9wZWVyX2NlcnRfY2hhaW4sICIoSSlbW0IiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgU1NMX3JlYWQsICIoSSIgRklMRV9ERVNDUklQVE9SIFNTTF9DQUxMQkFDS1MgIltCSUlJKUkiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgU1NMX3dyaXRlLCAiKEkiIEZJTEVfREVTQ1JJUFRPUiBTU0xfQ0FMTEJBQ0tTICJbQklJKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgU1NMX2ludGVycnVwdCwgIihJKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgU1NMX3NodXRkb3duLCAiKEkiIEZJTEVfREVTQ1JJUFRPUiBTU0xfQ0FMTEJBQ0tTICIpViIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBTU0xfZnJlZSwgIihJKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgU1NMX1NFU1NJT05fc2Vzc2lvbl9pZCwgIihJKVtCIiksCisgICAgTkFUSVZFX01FVEhPRChOYXRpdmVDcnlwdG8sIFNTTF9TRVNTSU9OX2dldF90aW1lLCAiKEkpSiIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBTU0xfU0VTU0lPTl9nZXRfdmVyc2lvbiwgIihJKUxqYXZhL2xhbmcvU3RyaW5nOyIpLAorICAgIE5BVElWRV9NRVRIT0QoTmF0aXZlQ3J5cHRvLCBTU0xfU0VTU0lPTl9jaXBoZXIsICIoSSlMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgU1NMX1NFU1NJT05fY29tcHJlc3NfbWV0aCwgIihJSSlMamF2YS9sYW5nL1N0cmluZzsiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgU1NMX1NFU1NJT05fZnJlZSwgIihJKVYiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgaTJkX1NTTF9TRVNTSU9OLCAiKEkpW0IiKSwKKyAgICBOQVRJVkVfTUVUSE9EKE5hdGl2ZUNyeXB0bywgZDJpX1NTTF9TRVNTSU9OLCAiKFtCKUkiKSwKK307CisKK2ludCByZWdpc3Rlcl9vcmdfYXBhY2hlX2hhcm1vbnlfeG5ldF9wcm92aWRlcl9qc3NlX05hdGl2ZUNyeXB0byhKTklFbnYqIGVudikgeworICAgIEpOSV9UUkFDRSgicmVnaXN0ZXJfb3JnX2FwYWNoZV9oYXJtb255X3huZXRfcHJvdmlkZXJfanNzZV9OYXRpdmVDcnlwdG8iKTsKKyAgICAvLyBSZWdpc3RlciBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlLk5hdGl2ZUNyeXB0byBtZXRob2RzCisgICAgcmV0dXJuIGpuaVJlZ2lzdGVyTmF0aXZlTWV0aG9kcyhlbnYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9OYXRpdmVDcnlwdG8iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc05hdGl2ZUNyeXB0b01ldGhvZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORUxFTShzTmF0aXZlQ3J5cHRvTWV0aG9kcykpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvcmVhZGxpbmsuY3BwIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvcmVhZGxpbmsuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU1NWQ1MTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS9yZWFkbGluay5jcHAKQEAgLTAsMCArMSw0MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpbmNsdWRlICJMb2NhbEFycmF5LmgiCisjaW5jbHVkZSAicmVhZGxpbmsuaCIKKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKworYm9vbCByZWFkbGluayhjb25zdCBjaGFyKiBwYXRoLCBzdGQ6OnN0cmluZyYgcmVzdWx0KSB7CisgICAgLy8gV2UgY2FuJ3Qga25vdyBob3cgYmlnIGEgYnVmZmVyIHJlYWRsaW5rKDIpIHdpbGwgbmVlZCwgc28gd2UgbmVlZCB0bworICAgIC8vIGxvb3AgdW50aWwgaXQgc2F5cyAidGhhdCBmaXQiLgorICAgIHNpemVfdCBidWZTaXplID0gNTEyOworICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgIExvY2FsQXJyYXk8NTEyPiBidWYoYnVmU2l6ZSk7CisgICAgICAgIHNzaXplX3QgbGVuID0gcmVhZGxpbmsocGF0aCwgJmJ1ZlswXSwgYnVmLnNpemUoKSk7CisgICAgICAgIGlmIChsZW4gPT0gLTEpIHsKKyAgICAgICAgICAgIC8vIEFuIGVycm9yIG9jY3VycmVkLgorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmIChzdGF0aWNfY2FzdDxzaXplX3Q+KGxlbikgPCBidWYuc2l6ZSgpKSB7CisgICAgICAgICAgICAvLyBUaGUgYnVmZmVyIHdhcyBiaWcgZW5vdWdoLgorICAgICAgICAgICAgcmVzdWx0LmFzc2lnbigmYnVmWzBdLCBsZW4pOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgLy8gVHJ5IGFnYWluIHdpdGggYSBiaWdnZXIgYnVmZmVyLgorICAgICAgICBidWZTaXplICo9IDI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvcmVhZGxpbmsuaCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL3JlYWRsaW5rLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTQwMzFkYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL3JlYWRsaW5rLmgKQEAgLTAsMCArMSwyNSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKy8qKgorICogRmlsbHMgJ3Jlc3VsdCcgd2l0aCB0aGUgY29udGVudHMgb2YgdGhlIHN5bWJvbGljIGxpbmsgJ3BhdGgnLiBTZXRzIGVycm5vIGFuZCByZXR1cm5zIGZhbHNlIG9uCisgKiBmYWlsdXJlLCByZXR1cm5zIHRydWUgb24gc3VjY2Vzcy4gVGhlIGNvbnRlbnRzIG9mICdyZXN1bHQnIG9uIGZhaWx1cmUgYXJlIHVuZGVmaW5lZC4gUG9zc2libGUKKyAqIGVycm9ycyBhcmUgdGhvc2UgZGVmaW5lZCBmb3IgcmVhZGxpbmsoMiksIGV4Y2VwdCB0aGF0IHRoaXMgZnVuY3Rpb24gdGFrZXMgY2FyZSBvZiBzaXppbmcgdGhlCisgKiBidWZmZXIgYXBwcm9wcmlhdGVseS4KKyAqLworYm9vbCByZWFkbGluayhjb25zdCBjaGFyKiBwYXRoLCBzdGQ6OnN0cmluZyYgcmVzdWx0KTsKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL3JlYWxwYXRoLmNwcCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL3JlYWxwYXRoLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMTk2MGE0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvcmVhbHBhdGguY3BwCkBAIC0wLDAgKzEsMTI1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAzIENvbnN0YW50aW4gUy4gU3ZpbnRzb2ZmIDxrb3N0aWtAaWNsdWIubnN1LnJ1PgorICoKKyAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCisgKiBhcmUgbWV0OgorICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0CisgKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlCisgKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgorICogMy4gVGhlIG5hbWVzIG9mIHRoZSBhdXRob3JzIG1heSBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUKKyAqICAgIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbgorICogICAgcGVybWlzc2lvbi4KKyAqCisgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBBVVRIT1IgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECisgKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKKyAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCisgKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRQorICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKKyAqIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTCisgKiBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikKKyAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCisgKiBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZCisgKiBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCisgKiBTVUNIIERBTUFHRS4KKyAqLworCisjaW5jbHVkZSAicmVhZGxpbmsuaCIKKworI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8c3lzL3BhcmFtLmg+CisjaW5jbHVkZSA8c3lzL3N0YXQuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKworLyoqCisgKiBUaGlzIGRpZmZlcnMgZnJvbSByZWFscGF0aCgzKSBtYWlubHkgaW4gaXRzIGJlaGF2aW9yIHdoZW4gYSBwYXRoIGVsZW1lbnQgZG9lcyBub3QgZXhpc3Qgb3IgY2FuCisgKiBub3QgYmUgc2VhcmNoZWQuIHJlYWxwYXRoKDMpIHRyZWF0cyB0aGF0IGFzIGFuIGVycm9yIGFuZCBnaXZlcyB1cCwgYnV0IHdlIGhhdmUgSmF2YS1jb21wYXRpYmxlCisgKiBiZWhhdmlvciB3aGVyZSB3ZSBqdXN0IGFzc3VtZSB0aGUgcGF0aCBlbGVtZW50IHdhcyBub3QgYSBzeW1ib2xpYyBsaW5rLiBUaGlzIGxlYWRzIHRvIGEgdGV4dHVhbAorICogdHJlYXRtZW50IG9mICIuLiIgZnJvbSB0aGF0IHBvaW50IGluIHRoZSBwYXRoLCB3aGljaCBtYXkgYWN0dWFsbHkgbGVhZCB1cyBiYWNrIHRvIGEgcGF0aCB3ZQorICogY2FuIHJlc29sdmUgKGFzIGluICIvdG1wL2RvZXMtbm90LWV4aXN0Ly4uL2JsYWgudHh0IiB3aGljaCB3b3VsZCBiZSBhbiBlcnJvciBmb3IgcmVhbHBhdGgoMykKKyAqIGJ1dCAiL3RtcC9ibGFoLnR4dCIgdW5kZXIgdGhlIHRyYWRpdGlvbmFsIEphdmEgaW50ZXJwcmV0YXRpb24pLgorICoKKyAqIFRoaXMgaW1wbGVtZW50YXRpb24gYWxzbyByZW1vdmVzIGFsbCB0aGUgZml4ZWQtbGVuZ3RoIGJ1ZmZlcnMgb2YgdGhlIEMgb3JpZ2luYWwuCisgKi8KK2Jvb2wgcmVhbHBhdGgoY29uc3QgY2hhciogcGF0aCwgc3RkOjpzdHJpbmcmIHJlc29sdmVkKSB7CisgICAgLy8gJ3BhdGgnIG11c3QgYmUgYW4gYWJzb2x1dGUgcGF0aC4KKyAgICBpZiAocGF0aFswXSAhPSAnLycpIHsKKyAgICAgICAgZXJybm8gPSBFSU5WQUw7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICByZXNvbHZlZCA9ICIvIjsKKyAgICBpZiAocGF0aFsxXSA9PSAnXDAnKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8vIEl0ZXJhdGUgb3ZlciBwYXRoIGNvbXBvbmVudHMgaW4gJ2xlZnQnLgorICAgIGludCBzeW1saW5rQ291bnQgPSAwOworICAgIHN0ZDo6c3RyaW5nIGxlZnQocGF0aCArIDEpOworICAgIHdoaWxlICghbGVmdC5lbXB0eSgpKSB7CisgICAgICAgIC8vIEV4dHJhY3QgdGhlIG5leHQgcGF0aCBjb21wb25lbnQuCisgICAgICAgIHNpemVfdCBuZXh0U2xhc2ggPSBsZWZ0LmZpbmQoJy8nKTsKKyAgICAgICAgc3RkOjpzdHJpbmcgbmV4dFBhdGhDb21wb25lbnQgPSBsZWZ0LnN1YnN0cigwLCBuZXh0U2xhc2gpOworICAgICAgICBpZiAobmV4dFNsYXNoICE9IHN0ZDo6c3RyaW5nOjpucG9zKSB7CisgICAgICAgICAgICBsZWZ0LmVyYXNlKDAsIG5leHRTbGFzaCArIDEpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbGVmdC5jbGVhcigpOworICAgICAgICB9CisgICAgICAgIGlmIChuZXh0UGF0aENvbXBvbmVudC5lbXB0eSgpKSB7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfSBlbHNlIGlmIChuZXh0UGF0aENvbXBvbmVudCA9PSAiLiIpIHsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9IGVsc2UgaWYgKG5leHRQYXRoQ29tcG9uZW50ID09ICIuLiIpIHsKKyAgICAgICAgICAgIC8vIFN0cmlwIHRoZSBsYXN0IHBhdGggY29tcG9uZW50IGV4Y2VwdCB3aGVuIHdlIGhhdmUgc2luZ2xlICIvIi4KKyAgICAgICAgICAgIGlmIChyZXNvbHZlZC5zaXplKCkgPiAxKSB7CisgICAgICAgICAgICAgICAgcmVzb2x2ZWQuZXJhc2UocmVzb2x2ZWQucmZpbmQoJy8nKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEFwcGVuZCB0aGUgbmV4dCBwYXRoIGNvbXBvbmVudC4KKyAgICAgICAgaWYgKHJlc29sdmVkW3Jlc29sdmVkLnNpemUoKSAtIDFdICE9ICcvJykgeworICAgICAgICAgICAgcmVzb2x2ZWQgKz0gJy8nOworICAgICAgICB9CisgICAgICAgIHJlc29sdmVkICs9IG5leHRQYXRoQ29tcG9uZW50OworCisgICAgICAgIC8vIFNlZSBpZiB3ZSd2ZSBnb3QgYSBzeW1ib2xpYyBsaW5rLCBhbmQgcmVzb2x2ZSBpdCBpZiBzby4KKyAgICAgICAgc3RydWN0IHN0YXQgc2I7CisgICAgICAgIGlmIChsc3RhdChyZXNvbHZlZC5jX3N0cigpLCAmc2IpID09IDAgJiYgU19JU0xOSyhzYi5zdF9tb2RlKSkgeworICAgICAgICAgICAgaWYgKHN5bWxpbmtDb3VudCsrID4gTUFYU1lNTElOS1MpIHsKKyAgICAgICAgICAgICAgICBlcnJubyA9IEVMT09QOworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc3RkOjpzdHJpbmcgc3ltbGluazsKKyAgICAgICAgICAgIGlmICghcmVhZGxpbmsocmVzb2x2ZWQuY19zdHIoKSwgc3ltbGluaykpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc3ltbGlua1swXSA9PSAnLycpIHsKKyAgICAgICAgICAgICAgICAvLyBUaGUgc3ltYm9saWMgbGluayBpcyBhYnNvbHV0ZSwgc28gd2UgbmVlZCB0byBzdGFydCBmcm9tIHNjcmF0Y2guCisgICAgICAgICAgICAgICAgcmVzb2x2ZWQgPSAiLyI7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHJlc29sdmVkLnNpemUoKSA+IDEpIHsKKyAgICAgICAgICAgICAgICAvLyBUaGUgc3ltYm9saWMgbGluayBpcyByZWxhdGl2ZSwgc28gd2UganVzdCBsb3NlIHRoZSBsYXN0IHBhdGggY29tcG9uZW50ICh3aGljaAorICAgICAgICAgICAgICAgIC8vIHdhcyB0aGUgbGluaykuCisgICAgICAgICAgICAgICAgcmVzb2x2ZWQuZXJhc2UocmVzb2x2ZWQucmZpbmQoJy8nKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICghbGVmdC5lbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgY29uc3QgY2hhciogbWF5YmVTbGFzaCA9IChzeW1saW5rW3N5bWxpbmsuc2l6ZSgpIC0gMV0gIT0gJy8nKSA/ICIvIiA6ICIiOworICAgICAgICAgICAgICAgIGxlZnQgPSBzeW1saW5rICsgbWF5YmVTbGFzaCArIGxlZnQ7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGxlZnQgPSBzeW1saW5rOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gUmVtb3ZlIHRyYWlsaW5nIHNsYXNoIGV4Y2VwdCB3aGVuIHRoZSByZXNvbHZlZCBwYXRobmFtZSBpcyBhIHNpbmdsZSAiLyIuCisgICAgaWYgKHJlc29sdmVkLnNpemUoKSA+IDEgJiYgcmVzb2x2ZWRbcmVzb2x2ZWQuc2l6ZSgpIC0gMV0gPT0gJy8nKSB7CisgICAgICAgIHJlc29sdmVkLmVyYXNlKHJlc29sdmVkLnNpemUoKSAtIDEsIDEpOworICAgIH0KKyAgICByZXR1cm4gdHJ1ZTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL3N1Yi5tayBiL2x1bmkvc3JjL21haW4vbmF0aXZlL3N1Yi5tawpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NTM1Y2U2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvc3ViLm1rCkBAIC0wLDAgKzEsNzYgQEAKKyMgLSotIG1vZGU6IG1ha2VmaWxlIC0qLQorIyBUaGlzIGZpbGUgaXMgaW5jbHVkZWQgYnkgdGhlIHRvcC1sZXZlbCBsaWJjb3JlIEFuZHJvaWQubWsuCisjIEl0J3Mgbm90IGEgbm9ybWFsIG1ha2VmaWxlLCBzbyB3ZSBkb24ndCBpbmNsdWRlIENMRUFSX1ZBUlMKKyMgb3IgQlVJTERfKl9MSUJSQVJZLgorCitMT0NBTF9TUkNfRklMRVMgOj0gXAorCUFzeW5jaHJvbm91c1NvY2tldENsb3NlTW9uaXRvci5jcHAgXAorCUpuaUNvbnN0YW50cy5jcHAgXAorCUpuaUV4Y2VwdGlvbi5jcHAgXAorCU5ldHdvcmtVdGlsaXRpZXMuY3BwIFwKKwlSZWdpc3Rlci5jcHAgXAorCWNiaWdpbnQuY3BwIFwKKwlqYXZhX2lvX0NvbnNvbGUuY3BwIFwKKwlqYXZhX2lvX0ZpbGUuY3BwIFwKKwlqYXZhX2lvX09iamVjdFN0cmVhbUNsYXNzLmNwcCBcCisJamF2YV9sYW5nX0NoYXJhY3Rlci5jcHAgXAorCWphdmFfbGFuZ19NYXRoLmNwcCBcCisJamF2YV9sYW5nX1Byb2Nlc3NNYW5hZ2VyLmNwcCBcCisJamF2YV9sYW5nX1JlYWxUb1N0cmluZy5jcHAgXAorCWphdmFfbGFuZ19TdHJpY3RNYXRoLmNwcCBcCisJamF2YV9sYW5nX1N0cmluZ1RvUmVhbC5jcHAgXAorCWphdmFfbGFuZ19TeXN0ZW0uY3BwIFwKKwlqYXZhX21hdGhfTmF0aXZlQk4uY3BwIFwKKwlqYXZhX25pb19CeXRlT3JkZXIuY3BwIFwKKwlqYXZhX25pb19jaGFyc2V0X0NoYXJzZXRzLmNwcCBcCisJamF2YV90ZXh0X0JpZGkuY3BwIFwKKwlqYXZhX3V0aWxfcmVnZXhfTWF0Y2hlci5jcHAgXAorCWphdmFfdXRpbF9yZWdleF9QYXR0ZXJuLmNwcCBcCisJamF2YV91dGlsX3ppcF9BZGxlcjMyLmNwcCBcCisJamF2YV91dGlsX3ppcF9DUkMzMi5jcHAgXAorCWphdmFfdXRpbF96aXBfRGVmbGF0ZXIuY3BwIFwKKwlqYXZhX3V0aWxfemlwX0luZmxhdGVyLmNwcCBcCisJbGliY29yZV9pY3VfSUNVLmNwcCBcCisJbGliY29yZV9pY3VfTmF0aXZlQnJlYWtJdGVyYXRvci5jcHAgXAorCWxpYmNvcmVfaWN1X05hdGl2ZUNvbGxhdGlvbi5jcHAgXAorCWxpYmNvcmVfaWN1X05hdGl2ZUNvbnZlcnRlci5jcHAgXAorCWxpYmNvcmVfaWN1X05hdGl2ZURlY2ltYWxGb3JtYXQuY3BwIFwKKwlsaWJjb3JlX2ljdV9OYXRpdmVJRE4uY3BwIFwKKwlsaWJjb3JlX2ljdV9OYXRpdmVOb3JtYWxpemVyLmNwcCBcCisJbGliY29yZV9pY3VfTmF0aXZlUGx1cmFsUnVsZXMuY3BwIFwKKwlsaWJjb3JlX2ljdV9UaW1lWm9uZXMuY3BwIFwKKwlsaWJjb3JlX2lvX0FzeW5jaHJvbm91c0Nsb3NlTW9uaXRvci5jcHAgXAorCWxpYmNvcmVfaW9fTWVtb3J5LmNwcCBcCisJbGliY29yZV9pb19Pc0NvbnN0YW50cy5jcHAgXAorCWxpYmNvcmVfaW9fUG9zaXguY3BwIFwKKwlsaWJjb3JlX25ldF9SYXdTb2NrZXQuY3BwIFwKKwlvcmdfYXBhY2hlX2hhcm1vbnlfeG1sX0V4cGF0UGFyc2VyLmNwcCBcCisJb3JnX2FwYWNoZV9oYXJtb255X3huZXRfcHJvdmlkZXJfanNzZV9OYXRpdmVDcnlwdG8uY3BwIFwKKwlyZWFkbGluay5jcHAgXAorCXJlYWxwYXRoLmNwcCBcCisJdG9TdHJpbmdBcnJheS5jcHAgXAorCXZhbHVlT2YuY3BwCisKK0xPQ0FMX0NfSU5DTFVERVMgKz0gXAorCWV4dGVybmFsL2V4cGF0L2xpYiBcCisJZXh0ZXJuYWwvaWN1NGMvY29tbW9uIFwKKwlleHRlcm5hbC9pY3U0Yy9pMThuIFwKKwlleHRlcm5hbC9vcGVuc3NsL2luY2x1ZGUgXAorCWV4dGVybmFsL3psaWIKKworIyBBbnkgc2hhcmVkL3N0YXRpYyBsaWJzIHRoYXQgYXJlIGxpc3RlZCBoZXJlIG11c3QgYWxzbworIyBiZSBsaXN0ZWQgaW4gbGlicy9uYXRpdmVoZWxwZXIvQW5kcm9pZC5tay4KKyMgVE9ETzogZml4IHRoaXMgcmVxdWlyZW1lbnQKKworTE9DQUxfU0hBUkVEX0xJQlJBUklFUyArPSBcCisJbGliY3J5cHRvIFwKKwlsaWJjdXRpbHMgXAorCWxpYmV4cGF0IFwKKwlsaWJpY3V1YyBcCisJbGliaWN1aTE4biBcCisJbGlic3NsIFwKKwlsaWJ1dGlscyBcCisJbGliegorCitMT0NBTF9TVEFUSUNfTElCUkFSSUVTICs9IFwKKwlsaWJmZGxpYm0KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL3RvU3RyaW5nQXJyYXkuY3BwIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvdG9TdHJpbmdBcnJheS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWZmZDIzOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL3RvU3RyaW5nQXJyYXkuY3BwCkBAIC0wLDAgKzEsNjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjaW5jbHVkZSAiSm5pQ29uc3RhbnRzLmgiCisjaW5jbHVkZSAidG9TdHJpbmdBcnJheS5oIgorCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKworc3RydWN0IFZlY3RvckNvdW50ZXIgeworICAgIGNvbnN0IHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiYgc3RyaW5nczsKKyAgICBWZWN0b3JDb3VudGVyKGNvbnN0IHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiYgc3RyaW5ncykgOiBzdHJpbmdzKHN0cmluZ3MpIHt9CisgICAgc2l6ZV90IG9wZXJhdG9yKCkoKSB7CisgICAgICAgIHJldHVybiBzdHJpbmdzLnNpemUoKTsKKyAgICB9Cit9Oworc3RydWN0IFZlY3RvckdldHRlciB7CisgICAgY29uc3Qgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+JiBzdHJpbmdzOworICAgIFZlY3RvckdldHRlcihjb25zdCBzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4mIHN0cmluZ3MpIDogc3RyaW5ncyhzdHJpbmdzKSB7fQorICAgIGNvbnN0IGNoYXIqIG9wZXJhdG9yKCkoc2l6ZV90IGkpIHsKKyAgICAgICAgcmV0dXJuIHN0cmluZ3NbaV0uY19zdHIoKTsKKyAgICB9Cit9OworCitqb2JqZWN0QXJyYXkgdG9TdHJpbmdBcnJheShKTklFbnYqIGVudiwgY29uc3Qgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+JiBzdHJpbmdzKSB7CisgICAgVmVjdG9yQ291bnRlciBjb3VudGVyKHN0cmluZ3MpOworICAgIFZlY3RvckdldHRlciBnZXR0ZXIoc3RyaW5ncyk7CisgICAgcmV0dXJuIHRvU3RyaW5nQXJyYXk8VmVjdG9yQ291bnRlciwgVmVjdG9yR2V0dGVyPihlbnYsICZjb3VudGVyLCAmZ2V0dGVyKTsKK30KKworc3RydWN0IEFycmF5Q291bnRlciB7CisgICAgY29uc3QgY2hhciogY29uc3QqIHN0cmluZ3M7CisgICAgQXJyYXlDb3VudGVyKGNvbnN0IGNoYXIqIGNvbnN0KiBzdHJpbmdzKSA6IHN0cmluZ3Moc3RyaW5ncykge30KKyAgICBzaXplX3Qgb3BlcmF0b3IoKSgpIHsKKyAgICAgICAgc2l6ZV90IGNvdW50ID0gMDsKKyAgICAgICAgd2hpbGUgKHN0cmluZ3NbY291bnRdICE9IE5VTEwpIHsKKyAgICAgICAgICAgICsrY291bnQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvdW50OworICAgIH0KK307CisKK3N0cnVjdCBBcnJheUdldHRlciB7CisgICAgY29uc3QgY2hhciogY29uc3QqIHN0cmluZ3M7CisgICAgQXJyYXlHZXR0ZXIoY29uc3QgY2hhciogY29uc3QqIHN0cmluZ3MpIDogc3RyaW5ncyhzdHJpbmdzKSB7fQorICAgIGNvbnN0IGNoYXIqIG9wZXJhdG9yKCkoc2l6ZV90IGkpIHsKKyAgICAgICAgcmV0dXJuIHN0cmluZ3NbaV07CisgICAgfQorfTsKKworam9iamVjdEFycmF5IHRvU3RyaW5nQXJyYXkoSk5JRW52KiBlbnYsIGNvbnN0IGNoYXIqIGNvbnN0KiBzdHJpbmdzKSB7CisgICAgQXJyYXlDb3VudGVyIGNvdW50ZXIoc3RyaW5ncyk7CisgICAgQXJyYXlHZXR0ZXIgZ2V0dGVyKHN0cmluZ3MpOworICAgIHJldHVybiB0b1N0cmluZ0FycmF5KGVudiwgJmNvdW50ZXIsICZnZXR0ZXIpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvdG9TdHJpbmdBcnJheS5oIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvdG9TdHJpbmdBcnJheS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg1ZWZjYjAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS90b1N0cmluZ0FycmF5LmgKQEAgLTAsMCArMSw2NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpbmNsdWRlICJqbmkuaCIKKyNpbmNsdWRlICJTY29wZWRMb2NhbFJlZi5oIgorCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKwordGVtcGxhdGUgPHR5cGVuYW1lIENvdW50ZXIsIHR5cGVuYW1lIEdldHRlcj4KK2pvYmplY3RBcnJheSB0b1N0cmluZ0FycmF5KEpOSUVudiogZW52LCBDb3VudGVyKiBjb3VudGVyLCBHZXR0ZXIqIGdldHRlcikgeworICAgIHNpemVfdCBjb3VudCA9ICgqY291bnRlcikoKTsKKyAgICBqb2JqZWN0QXJyYXkgcmVzdWx0ID0gZW52LT5OZXdPYmplY3RBcnJheShjb3VudCwgSm5pQ29uc3RhbnRzOjpzdHJpbmdDbGFzcywgTlVMTCk7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGNvdW50OyArK2kpIHsKKyAgICAgICAgU2NvcGVkTG9jYWxSZWY8anN0cmluZz4gcyhlbnYsIGVudi0+TmV3U3RyaW5nVVRGKCgqZ2V0dGVyKShpKSkpOworICAgICAgICBpZiAoZW52LT5FeGNlcHRpb25DaGVjaygpKSB7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBlbnYtPlNldE9iamVjdEFycmF5RWxlbWVudChyZXN1bHQsIGksIHMuZ2V0KCkpOworICAgICAgICBpZiAoZW52LT5FeGNlcHRpb25DaGVjaygpKSB7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQ291bnRlciwgdHlwZW5hbWUgR2V0dGVyPgoram9iamVjdEFycmF5IHRvU3RyaW5nQXJyYXkxNihKTklFbnYqIGVudiwgQ291bnRlciogY291bnRlciwgR2V0dGVyKiBnZXR0ZXIpIHsKKyAgICBzaXplX3QgY291bnQgPSAoKmNvdW50ZXIpKCk7CisgICAgam9iamVjdEFycmF5IHJlc3VsdCA9IGVudi0+TmV3T2JqZWN0QXJyYXkoY291bnQsIEpuaUNvbnN0YW50czo6c3RyaW5nQ2xhc3MsIE5VTEwpOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7CisgICAgICAgIGludDMyX3QgY2hhckNvdW50OworICAgICAgICBjb25zdCBqY2hhciogY2hhcnMgPSAoKmdldHRlcikoJmNoYXJDb3VudCk7CisgICAgICAgIFNjb3BlZExvY2FsUmVmPGpzdHJpbmc+IHMoZW52LCBlbnYtPk5ld1N0cmluZyhjaGFycywgY2hhckNvdW50KSk7CisgICAgICAgIGlmIChlbnYtPkV4Y2VwdGlvbkNoZWNrKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGVudi0+U2V0T2JqZWN0QXJyYXlFbGVtZW50KHJlc3VsdCwgaSwgcy5nZXQoKSk7CisgICAgICAgIGlmIChlbnYtPkV4Y2VwdGlvbkNoZWNrKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKK2pvYmplY3RBcnJheSB0b1N0cmluZ0FycmF5KEpOSUVudiogZW52LCBjb25zdCBzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4mIHN0cmluZ3MpOworam9iamVjdEFycmF5IHRvU3RyaW5nQXJyYXkoSk5JRW52KiBlbnYsIGNvbnN0IGNoYXIqIGNvbnN0KiBzdHJpbmdzKTsKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL21haW4vbmF0aXZlL3ZhbHVlT2YuY3BwIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvdmFsdWVPZi5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzEwZDQ4YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL21haW4vbmF0aXZlL3ZhbHVlT2YuY3BwCkBAIC0wLDAgKzEsNTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjZGVmaW5lIExPR19UQUcgInZhbHVlT2YiCisKKyNpbmNsdWRlICJ2YWx1ZU9mLmgiCisjaW5jbHVkZSAiSk5JSGVscC5oIgorI2luY2x1ZGUgIkpuaUNvbnN0YW50cy5oIgorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KK3N0YXRpYyBqb2JqZWN0IHZhbHVlT2YoSk5JRW52KiBlbnYsIGpjbGFzcyBjLCBjb25zdCBjaGFyKiBzaWduYXR1cmUsIGNvbnN0IFQmIHZhbHVlKSB7CisgICAgc3RhdGljIGptZXRob2RJRCB2YWx1ZU9mTWV0aG9kID0gZW52LT5HZXRTdGF0aWNNZXRob2RJRChjLCAidmFsdWVPZiIsIHNpZ25hdHVyZSk7CisgICAgcmV0dXJuIGVudi0+Q2FsbFN0YXRpY09iamVjdE1ldGhvZChjLCB2YWx1ZU9mTWV0aG9kLCB2YWx1ZSk7Cit9CisKK2pvYmplY3QgYm9vbGVhblZhbHVlT2YoSk5JRW52KiBlbnYsIGpib29sZWFuIHZhbHVlKSB7CisgICAgcmV0dXJuIHZhbHVlT2YoZW52LCBKbmlDb25zdGFudHM6OmJvb2xlYW5DbGFzcywgIihaKUxqYXZhL2xhbmcvQm9vbGVhbjsiLCB2YWx1ZSk7Cit9CisKK2pvYmplY3QgZG91YmxlVmFsdWVPZihKTklFbnYqIGVudiwgamRvdWJsZSB2YWx1ZSkgeworICAgIHJldHVybiB2YWx1ZU9mKGVudiwgSm5pQ29uc3RhbnRzOjpkb3VibGVDbGFzcywgIihEKUxqYXZhL2xhbmcvRG91YmxlOyIsIHZhbHVlKTsKK30KKworam9iamVjdCBpbnRlZ2VyVmFsdWVPZihKTklFbnYqIGVudiwgamludCB2YWx1ZSkgeworICAgIHJldHVybiB2YWx1ZU9mKGVudiwgSm5pQ29uc3RhbnRzOjppbnRlZ2VyQ2xhc3MsICIoSSlMamF2YS9sYW5nL0ludGVnZXI7IiwgdmFsdWUpOworfQorCitqb2JqZWN0IGxvbmdWYWx1ZU9mKEpOSUVudiogZW52LCBqbG9uZyB2YWx1ZSkgeworICAgIHJldHVybiB2YWx1ZU9mKGVudiwgSm5pQ29uc3RhbnRzOjpsb25nQ2xhc3MsICIoSilMamF2YS9sYW5nL0xvbmc7IiwgdmFsdWUpOworfQorCitqYm9vbGVhbiBib29sZWFuVmFsdWUoSk5JRW52KiBlbnYsIGpvYmplY3QgamF2YUxhbmdCb29sZWFuKSB7CisgICAgc3RhdGljIGpmaWVsZElEIGZpZCA9IGVudi0+R2V0RmllbGRJRChKbmlDb25zdGFudHM6OmJvb2xlYW5DbGFzcywgInZhbHVlIiwgIloiKTsKKyAgICByZXR1cm4gZW52LT5HZXRCb29sZWFuRmllbGQoamF2YUxhbmdCb29sZWFuLCBmaWQpOworfQorCitqaW50IGludFZhbHVlKEpOSUVudiogZW52LCBqb2JqZWN0IGphdmFMYW5nSW50ZWdlcikgeworICAgIHN0YXRpYyBqZmllbGRJRCBmaWQgPSBlbnYtPkdldEZpZWxkSUQoSm5pQ29uc3RhbnRzOjppbnRlZ2VyQ2xhc3MsICJ2YWx1ZSIsICJJIik7CisgICAgcmV0dXJuIGVudi0+R2V0SW50RmllbGQoamF2YUxhbmdJbnRlZ2VyLCBmaWQpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvbWFpbi9uYXRpdmUvdmFsdWVPZi5oIGIvbHVuaS9zcmMvbWFpbi9uYXRpdmUvdmFsdWVPZi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5Mjk3N2QKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS92YWx1ZU9mLmgKQEAgLTAsMCArMSwzMiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZm5kZWYgVkFMVUVfT0ZfSF9pbmNsdWRlZAorI2RlZmluZSBWQUxVRV9PRl9IX2luY2x1ZGVkCisKKyNpbmNsdWRlICJKTklIZWxwLmgiCisKK2pvYmplY3QgYm9vbGVhblZhbHVlT2YoSk5JRW52KiBlbnYsIGpib29sZWFuIGIpOworam9iamVjdCBkb3VibGVWYWx1ZU9mKEpOSUVudiogZW52LCBqZG91YmxlIGQpOworam9iamVjdCBpbnRlZ2VyVmFsdWVPZihKTklFbnYqIGVudiwgamludCBpKTsKK2pvYmplY3QgbG9uZ1ZhbHVlT2YoSk5JRW52KiBlbnYsIGpsb25nIGwpOworCisvLyBOb3RlIHRoYXQgdGhlc2UgYXJlbid0IGVxdWl2YWxlbnQgdG8gdGhlIE51bWJlciBtZXRob2RzOiB0aGUgam9iamVjdCBNVVNUIGJlIG9mIHRoZSBleGFjdAorLy8gdHlwZSBzcGVjaWZpZWQuIFRoaXMgaXMgbGVzcyBnZW5lcmFsIGJ1dCBmYXN0ZXIgKGFuZCBjdXJyZW50bHkgc3VmZmljaWVudCkuCitqYm9vbGVhbiBib29sZWFuVmFsdWUoSk5JRW52KiBlbnYsIGpvYmplY3QgamF2YUxhbmdCb29sZWFuKTsKK2ppbnQgaW50VmFsdWUoSk5JRW52KiBlbnYsIGpvYmplY3QgamF2YUxhbmdJbnRlZ2VyKTsKKworI2VuZGlmICAvLyBWQUxVRV9PRl9IX2luY2x1ZGVkCmRpZmYgLS1naXQgYS9sdW5pL3NyYy9tYWluL25hdGl2ZS96aXAuaCBiL2x1bmkvc3JjL21haW4vbmF0aXZlL3ppcC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBmM2MwYzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy9tYWluL25hdGl2ZS96aXAuaApAQCAtMCwwICsxLDEwMCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKyNpZiAhZGVmaW5lZCh6aXBfaCkKKyNkZWZpbmUgemlwX2gKKworI2luY2x1ZGUgIkpOSUhlbHAuaCIKKyNpbmNsdWRlICJKbmlFeGNlcHRpb24uaCIKKyNpbmNsdWRlICJVbmlxdWVQdHIuaCIKKyNpbmNsdWRlICJqbmkuaCIKKyNpbmNsdWRlICJ6bGliLmgiCisjaW5jbHVkZSAienV0aWwuaCIKKworc3RhdGljIHZvaWQgdGhyb3dFeGNlcHRpb25Gb3JabGliRXJyb3IoSk5JRW52KiBlbnYsIGNvbnN0IGNoYXIqIGV4Y2VwdGlvbkNsYXNzTmFtZSwgaW50IGVycm9yKSB7CisgICAgaWYgKGVycm9yID09IFpfTUVNX0VSUk9SKSB7CisgICAgICAgIGpuaVRocm93T3V0T2ZNZW1vcnlFcnJvcihlbnYsIE5VTEwpOworICAgIH0gZWxzZSB7CisgICAgICAgIGpuaVRocm93RXhjZXB0aW9uKGVudiwgZXhjZXB0aW9uQ2xhc3NOYW1lLCB6RXJyb3IoZXJyb3IpKTsKKyAgICB9Cit9CisKK2NsYXNzIE5hdGl2ZVppcFN0cmVhbSB7CitwdWJsaWM6CisgICAgVW5pcXVlUHRyPGpieXRlW10+IGlucHV0OworICAgIGludCBpbkNhcDsKKyAgICB6X3N0cmVhbSBzdHJlYW07CisKKyAgICBOYXRpdmVaaXBTdHJlYW0oKSA6IGlucHV0KE5VTEwpLCBpbkNhcCgwKSwgbURpY3QoTlVMTCkgeworICAgICAgICAvLyBMZXQgemxpYiB1c2UgaXRzIGRlZmF1bHQgYWxsb2NhdG9yLgorICAgICAgICBzdHJlYW0ub3BhcXVlID0gWl9OVUxMOworICAgICAgICBzdHJlYW0uemFsbG9jID0gWl9OVUxMOworICAgICAgICBzdHJlYW0uemZyZWUgPSBaX05VTEw7CisgICAgfQorCisgICAgfk5hdGl2ZVppcFN0cmVhbSgpIHsKKyAgICB9CisKKyAgICB2b2lkIHNldERpY3Rpb25hcnkoSk5JRW52KiBlbnYsIGpieXRlQXJyYXkgamF2YURpY3Rpb25hcnksIGludCBvZmYsIGludCBsZW4sIGJvb2wgaW5mbGF0ZSkgeworICAgICAgICBVbmlxdWVQdHI8amJ5dGVbXT4gZGljdGlvbmFyeUJ5dGVzKG5ldyBqYnl0ZVtsZW5dKTsKKyAgICAgICAgaWYgKGRpY3Rpb25hcnlCeXRlcy5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgICAgICBqbmlUaHJvd091dE9mTWVtb3J5RXJyb3IoZW52LCBOVUxMKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBlbnYtPkdldEJ5dGVBcnJheVJlZ2lvbihqYXZhRGljdGlvbmFyeSwgb2ZmLCBsZW4sICZkaWN0aW9uYXJ5Qnl0ZXNbMF0pOworICAgICAgICBjb25zdCBCeXRlZiogZGljdGlvbmFyeSA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgQnl0ZWYqPigmZGljdGlvbmFyeUJ5dGVzWzBdKTsKKyAgICAgICAgaW50IGVycjsKKyAgICAgICAgaWYgKGluZmxhdGUpIHsKKyAgICAgICAgICAgIGVyciA9IGluZmxhdGVTZXREaWN0aW9uYXJ5KCZzdHJlYW0sIGRpY3Rpb25hcnksIGxlbik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBlcnIgPSBkZWZsYXRlU2V0RGljdGlvbmFyeSgmc3RyZWFtLCBkaWN0aW9uYXJ5LCBsZW4pOworICAgICAgICB9CisgICAgICAgIGlmIChlcnIgIT0gWl9PSykgeworICAgICAgICAgICAgdGhyb3dFeGNlcHRpb25Gb3JabGliRXJyb3IoZW52LCAiamF2YS9sYW5nL0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIsIGVycik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgbURpY3QucmVzZXQoZGljdGlvbmFyeUJ5dGVzLnJlbGVhc2UoKSk7CisgICAgfQorCisgICAgdm9pZCBzZXRJbnB1dChKTklFbnYqIGVudiwgamJ5dGVBcnJheSBidWYsIGppbnQgb2ZmLCBqaW50IGxlbikgeworICAgICAgICBpbnB1dC5yZXNldChuZXcgamJ5dGVbbGVuXSk7CisgICAgICAgIGlmIChpbnB1dC5nZXQoKSA9PSBOVUxMKSB7CisgICAgICAgICAgICBpbkNhcCA9IDA7CisgICAgICAgICAgICBqbmlUaHJvd091dE9mTWVtb3J5RXJyb3IoZW52LCBOVUxMKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpbkNhcCA9IGxlbjsKKyAgICAgICAgaWYgKGJ1ZiAhPSBOVUxMKSB7CisgICAgICAgICAgICBlbnYtPkdldEJ5dGVBcnJheVJlZ2lvbihidWYsIG9mZiwgbGVuLCAmaW5wdXRbMF0pOworICAgICAgICB9CisgICAgICAgIHN0cmVhbS5uZXh0X2luID0gcmVpbnRlcnByZXRfY2FzdDxCeXRlZio+KCZpbnB1dFswXSk7CisgICAgICAgIHN0cmVhbS5hdmFpbF9pbiA9IGxlbjsKKyAgICB9CisKK3ByaXZhdGU6CisgICAgVW5pcXVlUHRyPGpieXRlW10+IG1EaWN0OworCisgICAgLy8gRGlzYWxsb3cgY29weSBhbmQgYXNzaWdubWVudC4KKyAgICBOYXRpdmVaaXBTdHJlYW0oY29uc3QgTmF0aXZlWmlwU3RyZWFtJik7CisgICAgdm9pZCBvcGVyYXRvcj0oY29uc3QgTmF0aXZlWmlwU3RyZWFtJik7Cit9OworCitzdGF0aWMgTmF0aXZlWmlwU3RyZWFtKiB0b05hdGl2ZVppcFN0cmVhbShqbG9uZyBhZGRyZXNzKSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8TmF0aXZlWmlwU3RyZWFtKj4oc3RhdGljX2Nhc3Q8dWludHB0cl90PihhZGRyZXNzKSk7Cit9CisKKyNlbmRpZiAvKiB6aXBfaCAqLwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9ldGMvbG9hZGluZy10ZXN0LWphci9SRUFETUUudHh0IGIvbHVuaS9zcmMvdGVzdC9ldGMvbG9hZGluZy10ZXN0LWphci9SRUFETUUudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyZmIxOTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2V0Yy9sb2FkaW5nLXRlc3QtamFyL1JFQURNRS50eHQKQEAgLTAsMCArMSw4IEBACitUaGlzIGRpcmVjdG9yeSBjb250YWlucyB0aGUgc291cmNlIGNvZGUgZm9yIHRoZSBsb2FkaW5nLXRlc3QgamFyIGFuZAorZGV4IGZpbGVzLCB3aGljaCBhcmUgaW5jbHVkZWQgYXMgcmVzb3VyY2VzIGluIHRoZSBsdW5pIHRlc3RzLiBUaGVzZQorZmlsZXMgYXJlIHVzZWQgZm9yIHRlc3RpbmcgdGhlIHZhcmlvdXMgY2xhc3MgbG9hZGVycy4KKworVGhlIEFuZHJvaWQgYnVpbGQgc3lzdGVtIGRvZXNuJ3Qgc3VwcG9ydCBkeW5hbWljYWxseSBwcm9kdWNpbmcKK3Jlc291cmNlcyBpbiBhbnkgc2FuZSB3YXkuIFRvIHVwZGF0ZSB0aGUgcmVzb3VyY2UsIHVzZSB0aGUgc2NyaXB0CitidWlsZC5zaCBpbiB0aGlzIGRpcmVjdG9yeSwgd2hpY2ggY29waWVzIHJlc3VsdGluZyBmaWxlcyBpbnRvIHRoZSBsdW5pCit0ZXN0IHJlc291cmNlcyBkaXJlY3RvcnkuCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2V0Yy9sb2FkaW5nLXRlc3QtamFyL1RhcmdldC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9ldGMvbG9hZGluZy10ZXN0LWphci9UYXJnZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mODcxNDRkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9ldGMvbG9hZGluZy10ZXN0LWphci9UYXJnZXQuamF2YQpAQCAtMCwwICsxLDQ1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0OworCisvKioKKyAqIENsYXNzIHdoaWNoIGlzIHByb2JlZCBhdCBieSB0aGUgY2xhc3MgbG9hZGluZyB0ZXN0cy4KKyAqLworcHVibGljIGNsYXNzIFRhcmdldCB7CisgICAgcHVibGljIHN0YXRpYyBpbnQgc3RhdGljVmFyaWFibGUgPSAwOworICAgIHB1YmxpYyBpbnQgaW5zdGFuY2VWYXJpYWJsZSA9IDA7CisKKyAgICBwdWJsaWMgVGFyZ2V0KCkgeworICAgICAgICAvLyBUaGlzIHNwYWNlIGludGVudGlvbmFsbHkgbGVmdCBibGFuay4KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBibG9ydCgpIHsKKyAgICAgICAgcmV0dXJuICJibG9ydCI7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldFN0YXRpY1ZhcmlhYmxlKGludCBuKSB7CisgICAgICAgIHN0YXRpY1ZhcmlhYmxlID0gbjsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIHpvcmNoKCkgeworICAgICAgICByZXR1cm4gInpvcmNoIjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbnN0YW5jZVZhcmlhYmxlKGludCBuKSB7CisgICAgICAgIGluc3RhbmNlVmFyaWFibGUgPSBuOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvZXRjL2xvYWRpbmctdGVzdC1qYXIvVGVzdDEuamF2YSBiL2x1bmkvc3JjL3Rlc3QvZXRjL2xvYWRpbmctdGVzdC1qYXIvVGVzdDEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44Mjk2MTQ1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9ldGMvbG9hZGluZy10ZXN0LWphci9UZXN0MS5qYXZhCkBAIC0wLDAgKzEsMjYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3Q7CisKKy8qKgorICogQ2xhc3MgdXNlZCBhcyBwYXJ0IG9mIHRoZSBjbGFzcyBsb2FkaW5nIHRlc3RzLgorICovCitwdWJsaWMgY2xhc3MgVGVzdDEgeworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRlc3QoKSB7CisgICAgICAgIHJldHVybiAiYmxvcnQiOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvZXRjL2xvYWRpbmctdGVzdC1qYXIvVGVzdE1ldGhvZHMuamF2YSBiL2x1bmkvc3JjL3Rlc3QvZXRjL2xvYWRpbmctdGVzdC1qYXIvVGVzdE1ldGhvZHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYzIyZGMzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9ldGMvbG9hZGluZy10ZXN0LWphci9UZXN0TWV0aG9kcy5qYXZhCkBAIC0wLDAgKzEsMTkwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0OworCitpbXBvcnQgdGVzdDIuVGFyZ2V0MjsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKKy8qKgorICogQ2xhc3MgdXNlZCBhcyBwYXJ0IG9mIHRoZSBjbGFzcyBsb2FkaW5nIHRlc3RzLiBUaGlzIGNsYXNzIHVzZXMKKyAqIG90aGVyIGNsYXNzZXMsIHNvbWUgb2Ygd2hpY2ggc2hvdWxkIGhhdmUgY29tZSBmcm9tIHRoZSBzYW1lIGphci9kZXgKKyAqIGZpbGUgYW5kIG90aGVycyBvZiB3aGljaCBzaG91bGQgaGF2ZSBjb21lIGZyb20gYSBkaWZmZXJlbnQgamFyL2RleAorICogZmlsZS4gRWFjaCB0ZXN0IG1ldGhvZCBpbiB0aGlzIGNsYXNzIGlzIGNhbGxlZCBmcm9tIHRoZSBzYW1lLW5hbWVkCisgKiBtZXRob2QgaW4ge0Bjb2RlIERleENsYXNzTG9hZGVyVGVzdH0uCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0TWV0aG9kcyB7CisgICAgLyoKKyAgICAgKiBUaGUgZm9sbG93aW5nIGFyZSBhbGwgc2ltcGxlIHV0aWxpdHkgbWV0aG9kcyB3aGljaCwgdW5kZXIKKyAgICAgKiBub3JtYWwgY2lyY3Vtc3RhbmNlcywgd291bGQgYmUgcGFydCBvZiBvdGhlciBsaWJyYXJpZXMKKyAgICAgKiAoc3BlY2lmaWNhbGx5LCBKVW5pdCBhbmQgdGhlIEFuZHJvaWQgbGliY29yZSBzdXBwb3J0IGxpYnJhcnkpLgorICAgICAqCisgICAgICogSG93ZXZlciwgdGhpcyBmaWxlIGdldHMgY29tcGlsZWQgYXMgYW4gaW5kZXBlbmRlbnQgdW5pdCB3aXRob3V0CisgICAgICogYW55IGRlcGVuZGVuY2llcy4gV2UgY291bGQgdGhlb3JldGljYWxseSBhZGQgZGVwZW5kZW5jaWVzIG9uIG90aGVyCisgICAgICogbGlicmFyaWVzLCBidXQgdGhhdCB3b3VsZCBtYWtlIHRoaW5ncyBtdWNoIG1vcmUgY29tcGxpY2F0ZWQgYW5kCisgICAgICogZnJhZ2lsZSwgYW5kIGZvciB2ZXJ5IGxpdHRsZSBiZW5lZml0LgorICAgICAqLworCisgICAgLyoqCisgICAgICogU2ltcGxlIHNhbWVuZXNzIGFzc2VydGlvbiBjaGVja2VyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRTYW1lKE9iamVjdCBleHBlY3RlZCwgT2JqZWN0IGFjdHVhbCkgeworICAgICAgICBpZiAoZXhwZWN0ZWQgIT0gYWN0dWFsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiRVhQRUNURUQ6ICIgKyBleHBlY3RlZCArICI7IEFDVFVBTDogIiArIGFjdHVhbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTaW1wbGUgc2FtZW5lc3MgYXNzZXJ0aW9uIGNoZWNrZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydFNhbWUoaW50IGV4cGVjdGVkLCBpbnQgYWN0dWFsKSB7CisgICAgICAgIGlmIChleHBlY3RlZCAhPSBhY3R1YWwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJFWFBFQ1RFRDogIiArIGV4cGVjdGVkICsgIjsgQUNUVUFMOiAiICsgYWN0dWFsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZ1bGx5IHJlYWQgdGhlIGNvbnRlbnRzIG9mIHRoZSBnaXZlbiBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gcmVhZEZ1bGx5KElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBUaGlzIGlzIGEgY29weSBvZiB0aGUgc2FtZS1uYW1lZCBtZXRob2QgaW4gbGliY29yZS5pby5TdHJlYW1zLgorICAgICAgICBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbMTAyNF07CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBieXRlcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIGludCBieXRlQ291bnQgPSBpbi5yZWFkKGJ1ZmZlcik7CisgICAgICAgICAgICBpZiAoYnl0ZUNvdW50ID09IC0xKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGJ5dGVzLnRvQnl0ZUFycmF5KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBieXRlcy53cml0ZShidWZmZXIsIDAsIGJ5dGVDb3VudCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFRlc3QgbWV0aG9kcyB0aGF0IHVzZSBhbm90aGVyIGNsYXNzIGZyb20gdGhlIHNhbWUgZGV4L2phciBmaWxlCisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgYW4gaW5zdGFuY2Ugb2YgYSBzaWJsaW5nIGNsYXNzIGNhbiBiZSBjb25zdHJ1Y3RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdGVzdF9jb25zdHJ1Y3RvcigpIHsKKyAgICAgICAgbmV3IFRhcmdldCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgY2FsbGluZyBhIHN0YXRpYyBtZXRob2Qgb24gYSBzaWJsaW5nIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0ZXN0X2NhbGxTdGF0aWNNZXRob2QoKSB7CisgICAgICAgIGFzc2VydFNhbWUoImJsb3J0IiwgVGFyZ2V0LmJsb3J0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZ2V0dGluZyBhIHN0YXRpYyB2YXJpYWJsZSBvZiBhIHNpYmxpbmcgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHRlc3RfZ2V0U3RhdGljVmFyaWFibGUoKSB7CisgICAgICAgIFRhcmdldC5zZXRTdGF0aWNWYXJpYWJsZSgyMik7CisgICAgICAgIGFzc2VydFNhbWUoMjIsIFRhcmdldC5zdGF0aWNWYXJpYWJsZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBjYWxsaW5nIGFuIGluc3RhbmNlIG1ldGhvZCBvbiBhIHNpYmxpbmcgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHRlc3RfY2FsbEluc3RhbmNlTWV0aG9kKCkgeworICAgICAgICBUYXJnZXQgdGFyZ2V0ID0gbmV3IFRhcmdldCgpOworICAgICAgICBhc3NlcnRTYW1lKCJ6b3JjaCIsIHRhcmdldC56b3JjaCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGdldHRpbmcgYW4gaW5zdGFuY2UgdmFyaWFibGUgb2YgYSBzaWJsaW5nIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlVmFyaWFibGUoKSB7CisgICAgICAgIFRhcmdldCB0YXJnZXQgPSBuZXcgVGFyZ2V0KCk7CisgICAgICAgIHRhcmdldC5zZXRJbnN0YW5jZVZhcmlhYmxlKDEwMDk4KTsKKyAgICAgICAgYXNzZXJ0U2FtZSgxMDA5OCwgdGFyZ2V0Lmluc3RhbmNlVmFyaWFibGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZ2V0dGluZyBhIHJlc291cmNlIHdoaWNoIHNob3VsZCBiZSBpbiB0aGUgc2FtZSBqYXIKKyAgICAgKiBmaWxlIGFzIHRoaXMgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHRlc3RfZ2V0UmVzb3VyY2VBc1N0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIENsYXNzTG9hZGVyIGNsID0gVGVzdE1ldGhvZHMuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBjbC5nZXRSZXNvdXJjZUFzU3RyZWFtKCJ0ZXN0L1Jlc291cmNlMS50eHQiKTsKKyAgICAgICAgYnl0ZVtdIGNvbnRlbnRzID0gcmVhZEZ1bGx5KGluKTsKKyAgICAgICAgU3RyaW5nIHMgPSBuZXcgU3RyaW5nKGNvbnRlbnRzLCAiVVRGLTgiKTsKKworICAgICAgICBhc3NlcnRTYW1lKCJNdWZmaW5zIGFyZSB0YXN0eSFcbiIsIHMuaW50ZXJuKCkpOworICAgIH0KKworICAgIC8qCisgICAgICogVGVzdCBtZXRob2RzIHRoYXQgdXNlIGEgY2xhc3MgZnJvbSBhIGRpZmZlcmVudCBkZXgvamFyIGZpbGUKKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBhbiBpbnN0YW5jZSBvZiBhIGNvdXNpbiBjbGFzcyBjYW4gYmUgY29uc3RydWN0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHRlc3RfZGlmZl9jb25zdHJ1Y3RvcigpIHsKKyAgICAgICAgbmV3IFRhcmdldDIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGNhbGxpbmcgYSBzdGF0aWMgbWV0aG9kIG9uIGEgY291c2luIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0ZXN0X2RpZmZfY2FsbFN0YXRpY01ldGhvZCgpIHsKKyAgICAgICAgYXNzZXJ0U2FtZSgiZnJvdHoiLCBUYXJnZXQyLmZyb3R6KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZ2V0dGluZyBhIHN0YXRpYyB2YXJpYWJsZSBvZiBhIGNvdXNpbiBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdGVzdF9kaWZmX2dldFN0YXRpY1ZhcmlhYmxlKCkgeworICAgICAgICBUYXJnZXQyLnNldFN0YXRpY0lncmFtKDIyMCk7CisgICAgICAgIGFzc2VydFNhbWUoMjIwLCBUYXJnZXQyLnN0YXRpY0lncmFtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGNhbGxpbmcgYW4gaW5zdGFuY2UgbWV0aG9kIG9uIGEgY291c2luIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0ZXN0X2RpZmZfY2FsbEluc3RhbmNlTWV0aG9kKCkgeworICAgICAgICBUYXJnZXQyIHRhcmdldCA9IG5ldyBUYXJnZXQyKCk7CisgICAgICAgIGFzc2VydFNhbWUoImZpem1vIiwgdGFyZ2V0LmZpem1vKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZ2V0dGluZyBhbiBpbnN0YW5jZSB2YXJpYWJsZSBvZiBhIGNvdXNpbiBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdGVzdF9kaWZmX2dldEluc3RhbmNlVmFyaWFibGUoKSB7CisgICAgICAgIFRhcmdldDIgdGFyZ2V0ID0gbmV3IFRhcmdldDIoKTsKKyAgICAgICAgdGFyZ2V0LnNldEluc3RhbmNlTWFncmkoMTAwOTgpOworICAgICAgICBhc3NlcnRTYW1lKDEwMDk4LCB0YXJnZXQuaW5zdGFuY2VNYWdyaSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBnZXR0aW5nIGEgcmVzb3VyY2Ugd2hpY2ggc2hvdWxkIGJlIGluIGEgZGlmZmVyZW50IGphcgorICAgICAqIGZpbGUgYXMgdGhpcyBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdGVzdF9kaWZmX2dldFJlc291cmNlQXNTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBDbGFzc0xvYWRlciBjbCA9IFRlc3RNZXRob2RzLmNsYXNzLmdldENsYXNzTG9hZGVyKCk7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gY2wuZ2V0UmVzb3VyY2VBc1N0cmVhbSgidGVzdDIvUmVzb3VyY2UyLnR4dCIpOworICAgICAgICBieXRlW10gY29udGVudHMgPSByZWFkRnVsbHkoaW4pOworICAgICAgICBTdHJpbmcgcyA9IG5ldyBTdHJpbmcoY29udGVudHMsICJVVEYtOCIpOworCisgICAgICAgIGFzc2VydFNhbWUoIldobyBkb2Vzbid0IGxpa2UgYSBnb29kIGJpc2N1aXQ/XG4iLCBzLmludGVybigpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2V0Yy9sb2FkaW5nLXRlc3QtamFyL2J1aWxkLnNoIGIvbHVuaS9zcmMvdGVzdC9ldGMvbG9hZGluZy10ZXN0LWphci9idWlsZC5zaApuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi40NzM3ZjE0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9ldGMvbG9hZGluZy10ZXN0LWphci9idWlsZC5zaApAQCAtMCwwICsxLDU2IEBACisjIS9iaW4vYmFzaCAtZQorIworIyBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworIyBTZXQgdXAgcHJvZyB0byBiZSB0aGUgcGF0aCBvZiB0aGlzIHNjcmlwdCwgaW5jbHVkaW5nIGZvbGxvd2luZworIyBzeW1saW5rcywgYW5kIHNldCB1cCBwcm9nZGlyIHRvIGJlIHRoZSBmdWxseS1xdWFsaWZpZWQgcGF0aG5hbWUgb2YKKyMgaXRzIGRpcmVjdG9yeS4gIFN3aXRjaCB0aGUgY3VycmVudCBkaXJlY3RvcnkgdG8gcHJvZ2RpciBmb3IgdGhlCisjIHJlbWFpbmRlciBvZiB0aGUgc2NyaXB0LgorcHJvZz0iJDAiCit3aGlsZSBbIC1oICIke3Byb2d9IiBdOyBkbworICAgIG5ld1Byb2c9YC9iaW4vbHMgLWxkICIke3Byb2d9ImAKKyAgICBuZXdQcm9nPWBleHByICIke25ld1Byb2d9IiA6ICIuKiAtPiBcKC4qXCkkImAKKyAgICBpZiBleHByICJ4JHtuZXdQcm9nfSIgOiAneC8nID4vZGV2L251bGw7IHRoZW4KKyAgICAgICAgcHJvZz0iJHtuZXdQcm9nfSIKKyAgICBlbHNlCisgICAgICAgIHByb2dkaXI9YGRpcm5hbWUgIiR7cHJvZ30iYAorICAgICAgICBwcm9nPSIke3Byb2dkaXJ9LyR7bmV3UHJvZ30iCisgICAgZmkKK2RvbmUKK29sZHdkPWBwd2RgCitwcm9nZGlyPWBkaXJuYW1lICIke3Byb2d9ImAKK2NkICIke3Byb2dkaXJ9IgorCityZXNvdXJjZURpcj0uLi8uLi9yZXNvdXJjZXMvZGFsdmlrL3N5c3RlbQorCitybSAtcmYgY2xhc3Nlcworcm0gLXJmIGNsYXNzZXMyCitybSAtcmYgY2xhc3Nlcy5kZXgKK3JtIC1yZiBsb2FkaW5nLXRlc3QuamFyCisKKyMgVGhpcyBsaWJyYXJ5IGRlcGVuZHMgb24gbG9hZGluZy10ZXN0Miwgc28gY29tcGlsZSB0aG9zZSBjbGFzc2VzIGZpcnN0LAorIyBidXQga2VlcCB0aGVtIHNlcGFyYXRlLgorbWtkaXIgY2xhc3NlczIKK2phdmFjIC1kIGNsYXNzZXMyIC4uL2xvYWRpbmctdGVzdDItamFyLyouamF2YQorCitta2RpciBjbGFzc2VzCitqYXZhYyAtY2xhc3NwYXRoIGNsYXNzZXMyIC1kIGNsYXNzZXMgKi5qYXZhCitkeCAtLWRleCAtLW91dHB1dD1jbGFzc2VzLmRleCBjbGFzc2VzCitqYXIgY2YgbG9hZGluZy10ZXN0LmphciBjbGFzc2VzLmRleCAtQyByZXNvdXJjZXMgLgorCitybSAtcmYgY2xhc3Nlcworcm0gLXJmIGNsYXNzZXMyCittdiBjbGFzc2VzLmRleCAke3Jlc291cmNlRGlyfS9sb2FkaW5nLXRlc3QuZGV4CittdiBsb2FkaW5nLXRlc3QuamFyICR7cmVzb3VyY2VEaXJ9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2V0Yy9sb2FkaW5nLXRlc3QtamFyL3Jlc291cmNlcy90ZXN0L1Jlc291cmNlMS50eHQgYi9sdW5pL3NyYy90ZXN0L2V0Yy9sb2FkaW5nLXRlc3QtamFyL3Jlc291cmNlcy90ZXN0L1Jlc291cmNlMS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmVmODdmYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvZXRjL2xvYWRpbmctdGVzdC1qYXIvcmVzb3VyY2VzL3Rlc3QvUmVzb3VyY2UxLnR4dApAQCAtMCwwICsxIEBACitNdWZmaW5zIGFyZSB0YXN0eSEKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvZXRjL2xvYWRpbmctdGVzdDItamFyL1JFQURNRS50eHQgYi9sdW5pL3NyYy90ZXN0L2V0Yy9sb2FkaW5nLXRlc3QyLWphci9SRUFETUUudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUxZDhiYmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2V0Yy9sb2FkaW5nLXRlc3QyLWphci9SRUFETUUudHh0CkBAIC0wLDAgKzEsOCBAQAorVGhpcyBkaXJlY3RvcnkgY29udGFpbnMgdGhlIHNvdXJjZSBjb2RlIGZvciB0aGUgbG9hZGluZy10ZXN0MiBqYXIgYW5kCitkZXggZmlsZXMsIHdoaWNoIGFyZSBpbmNsdWRlZCBhcyByZXNvdXJjZXMgaW4gdGhlIGx1bmkgdGVzdHMuIFRoZXNlCitmaWxlcyBhcmUgdXNlZCBmb3IgdGVzdGluZyB0aGUgdmFyaW91cyBjbGFzcyBsb2FkZXJzLgorCitUaGUgQW5kcm9pZCBidWlsZCBzeXN0ZW0gZG9lc24ndCBzdXBwb3J0IGR5bmFtaWNhbGx5IHByb2R1Y2luZworcmVzb3VyY2VzIGluIGFueSBzYW5lIHdheS4gVG8gdXBkYXRlIHRoZSByZXNvdXJjZSwgdXNlIHRoZSBzY3JpcHQKK2J1aWxkLnNoIGluIHRoaXMgZGlyZWN0b3J5LCB3aGljaCBjb3BpZXMgcmVzdWx0aW5nIGZpbGVzIGludG8gdGhlIGx1bmkKK3Rlc3QgcmVzb3VyY2VzIGRpcmVjdG9yeS4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvZXRjL2xvYWRpbmctdGVzdDItamFyL1RhcmdldDIuamF2YSBiL2x1bmkvc3JjL3Rlc3QvZXRjL2xvYWRpbmctdGVzdDItamFyL1RhcmdldDIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNzJhMjdlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9ldGMvbG9hZGluZy10ZXN0Mi1qYXIvVGFyZ2V0Mi5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3QyOworCisvKioKKyAqIENsYXNzIHdoaWNoIGlzIHByb2JlZCBhdCBieSB0aGUgY2xhc3MgbG9hZGluZyB0ZXN0cy4KKyAqLworcHVibGljIGNsYXNzIFRhcmdldDIgeworICAgIHB1YmxpYyBzdGF0aWMgaW50IHN0YXRpY0lncmFtID0gMDsKKyAgICBwdWJsaWMgaW50IGluc3RhbmNlTWFncmkgPSAwOworCisgICAgcHVibGljIFRhcmdldDIoKSB7CisgICAgICAgIC8vIFRoaXMgc3BhY2UgaW50ZW50aW9uYWxseSBsZWZ0IGJsYW5rLgorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGZyb3R6KCkgeworICAgICAgICByZXR1cm4gImZyb3R6IjsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0U3RhdGljSWdyYW0oaW50IG4pIHsKKyAgICAgICAgc3RhdGljSWdyYW0gPSBuOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZml6bW8oKSB7CisgICAgICAgIHJldHVybiAiZml6bW8iOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEluc3RhbmNlTWFncmkoaW50IG4pIHsKKyAgICAgICAgaW5zdGFuY2VNYWdyaSA9IG47CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9ldGMvbG9hZGluZy10ZXN0Mi1qYXIvYnVpbGQuc2ggYi9sdW5pL3NyYy90ZXN0L2V0Yy9sb2FkaW5nLXRlc3QyLWphci9idWlsZC5zaApuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi4wZDk4YTJhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9ldGMvbG9hZGluZy10ZXN0Mi1qYXIvYnVpbGQuc2gKQEAgLTAsMCArMSw0OSBAQAorIyEvYmluL2Jhc2ggLWUKKyMKKyMgQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKyMgU2V0IHVwIHByb2cgdG8gYmUgdGhlIHBhdGggb2YgdGhpcyBzY3JpcHQsIGluY2x1ZGluZyBmb2xsb3dpbmcKKyMgc3ltbGlua3MsIGFuZCBzZXQgdXAgcHJvZ2RpciB0byBiZSB0aGUgZnVsbHktcXVhbGlmaWVkIHBhdGhuYW1lIG9mCisjIGl0cyBkaXJlY3RvcnkuICBTd2l0Y2ggdGhlIGN1cnJlbnQgZGlyZWN0b3J5IHRvIHByb2dkaXIgZm9yIHRoZQorIyByZW1haW5kZXIgb2YgdGhlIHNjcmlwdC4KK3Byb2c9IiQwIgord2hpbGUgWyAtaCAiJHtwcm9nfSIgXTsgZG8KKyAgICBuZXdQcm9nPWAvYmluL2xzIC1sZCAiJHtwcm9nfSJgCisgICAgbmV3UHJvZz1gZXhwciAiJHtuZXdQcm9nfSIgOiAiLiogLT4gXCguKlwpJCJgCisgICAgaWYgZXhwciAieCR7bmV3UHJvZ30iIDogJ3gvJyA+L2Rldi9udWxsOyB0aGVuCisgICAgICAgIHByb2c9IiR7bmV3UHJvZ30iCisgICAgZWxzZQorICAgICAgICBwcm9nZGlyPWBkaXJuYW1lICIke3Byb2d9ImAKKyAgICAgICAgcHJvZz0iJHtwcm9nZGlyfS8ke25ld1Byb2d9IgorICAgIGZpCitkb25lCitvbGR3ZD1gcHdkYAorcHJvZ2Rpcj1gZGlybmFtZSAiJHtwcm9nfSJgCitjZCAiJHtwcm9nZGlyfSIKKworcmVzb3VyY2VEaXI9Li4vLi4vcmVzb3VyY2VzL2RhbHZpay9zeXN0ZW0KKworcm0gLXJmIGNsYXNzZXMKK3JtIC1yZiBjbGFzc2VzLmRleAorcm0gLXJmIGxvYWRpbmctdGVzdDIuamFyCisKK21rZGlyIGNsYXNzZXMKK2phdmFjIC1kIGNsYXNzZXMgKi5qYXZhCitkeCAtLWRleCAtLW91dHB1dD1jbGFzc2VzLmRleCBjbGFzc2VzCitqYXIgY2YgbG9hZGluZy10ZXN0Mi5qYXIgY2xhc3Nlcy5kZXggLUMgcmVzb3VyY2VzIC4KKworcm0gLXJmIGNsYXNzZXMKK212IGNsYXNzZXMuZGV4ICR7cmVzb3VyY2VEaXJ9L2xvYWRpbmctdGVzdDIuZGV4CittdiBsb2FkaW5nLXRlc3QyLmphciAke3Jlc291cmNlRGlyfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9ldGMvbG9hZGluZy10ZXN0Mi1qYXIvcmVzb3VyY2VzL3Rlc3QyL1Jlc291cmNlMi50eHQgYi9sdW5pL3NyYy90ZXN0L2V0Yy9sb2FkaW5nLXRlc3QyLWphci9yZXNvdXJjZXMvdGVzdDIvUmVzb3VyY2UyLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MmY1YzJkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9ldGMvbG9hZGluZy10ZXN0Mi1qYXIvcmVzb3VyY2VzL3Rlc3QyL1Jlc291cmNlMi50eHQKQEAgLTAsMCArMSBAQAorV2hvIGRvZXNuJ3QgbGlrZSBhIGdvb2QgYmlzY3VpdD8KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9jb20vYW5kcm9pZC9vcmcvYm91bmN5Y2FzdGxlL2NyeXB0by9kaWdlc3RzL0RpZ2VzdFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9jb20vYW5kcm9pZC9vcmcvYm91bmN5Y2FzdGxlL2NyeXB0by9kaWdlc3RzL0RpZ2VzdFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMjI0N2NmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2NvbS9hbmRyb2lkL29yZy9ib3VuY3ljYXN0bGUvY3J5cHRvL2RpZ2VzdHMvRGlnZXN0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTM2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBjb20uYW5kcm9pZC5vcmcuYm91bmN5Y2FzdGxlLmNyeXB0by5kaWdlc3RzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGNvbS5hbmRyb2lkLm9yZy5ib3VuY3ljYXN0bGUuY3J5cHRvLkRpZ2VzdDsKK2ltcG9ydCBjb20uYW5kcm9pZC5vcmcuYm91bmN5Y2FzdGxlLmNyeXB0by5FeHRlbmRlZERpZ2VzdDsKKworLyoqCisgKiBJbXBsZW1lbnRzIHVuaXQgdGVzdHMgZm9yIG91ciBKTkkgd3JhcHBlciBhcm91bmQgT3BlblNTTC4gV2UgdXNlIHRoZQorICogZXhpc3RpbmcgQm91bmN5IENhc3RsZSBpbXBsZW1lbnRhdGlvbiBhcyBvdXIgdGVzdCBvcmFjbGUuCisgKi8KK3B1YmxpYyBjbGFzcyBEaWdlc3RUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogUHJvY2Vzc2VzIHRoZSB0d28gZ2l2ZW4gbWVzc2FnZSBkaWdlc3RzIGZvciB0aGUgc2FtZSBkYXRhIGFuZCBjaGVja3MKKyAgICAgKiB0aGUgcmVzdWx0cy4gUmVxdWlyZW1lbnQgaXMgdGhhdCB0aGUgcmVzdWx0cyBtdXN0IGJlIGVxdWFsLCB0aGUgZGlnZXN0CisgICAgICogaW1wbGVtZW50YXRpb25zIG11c3QgaGF2ZSB0aGUgc2FtZSBwcm9wZXJ0aWVzLCBhbmQgdGhlIG5ldyBpbXBsZW1lbnRhdGlvbgorICAgICAqIG11c3QgYmUgZmFzdGVyIHRoYW4gdGhlIG9sZCBvbmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2xkRGlnZXN0IFRoZSBvbGQgZGlnZXN0IGltcGxlbWVudGF0aW9uLCBwcm92aWRlZCBieSBCb3VuY3kgQ2FzdGxlCisgICAgICogQHBhcmFtIG5ld0RpZ2VzdCBUaGUgbmV3IGRpZ2VzdCBpbXBsZW1lbnRhdGlvbiwgcHJvdmlkZWQgYnkgT3BlblNTTAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRvVGVzdE1lc3NhZ2VEaWdlc3QoRGlnZXN0IG9sZERpZ2VzdCwgRGlnZXN0IG5ld0RpZ2VzdCkgeworICAgICAgICBmaW5hbCBpbnQgSVRFUkFUSU9OUyA9IDEwOworCisgICAgICAgIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbMTAyNF07CisKKyAgICAgICAgYnl0ZVtdIG9sZEhhc2ggPSBuZXcgYnl0ZVtvbGREaWdlc3QuZ2V0RGlnZXN0U2l6ZSgpXTsKKyAgICAgICAgYnl0ZVtdIG5ld0hhc2ggPSBuZXcgYnl0ZVtuZXdEaWdlc3QuZ2V0RGlnZXN0U2l6ZSgpXTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkhhc2ggbmFtZXMgbXVzdCBiZSBlcXVhbCIsCisgICAgICAgICAgICAgICAgICAgICBvbGREaWdlc3QuZ2V0QWxnb3JpdGhtTmFtZSgpLCBuZXdEaWdlc3QuZ2V0QWxnb3JpdGhtTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJIYXNoIHNpemVzIG11c3QgYmUgZXF1YWwiLAorICAgICAgICAgICAgICAgICAgICAgb2xkSGFzaC5sZW5ndGgsIG5ld0hhc2gubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJIYXNoIGJsb2NrIHNpemVzIG11c3QgYmUgZXF1YWwiLAorICAgICAgICAgICAgICAgICAgICAgKChFeHRlbmRlZERpZ2VzdClvbGREaWdlc3QpLmdldEJ5dGVMZW5ndGgoKSwKKyAgICAgICAgICAgICAgICAgICAgICgoRXh0ZW5kZWREaWdlc3QpbmV3RGlnZXN0KS5nZXRCeXRlTGVuZ3RoKCkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGRhdGFbaV0gPSAoYnl0ZSlpOworICAgICAgICB9CisKKyAgICAgICAgbG9uZyBvbGRUaW1lID0gMDsKKyAgICAgICAgbG9uZyBuZXdUaW1lID0gMDsKKworICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IElURVJBVElPTlM7IGorKykgeworICAgICAgICAgICAgbG9uZyB0MCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA0OyBpKyspIHsKKyAgICAgICAgICAgICAgICBvbGREaWdlc3QudXBkYXRlKGRhdGEsIDAsIGRhdGEubGVuZ3RoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBvbGRMZW5ndGggPSBvbGREaWdlc3QuZG9GaW5hbChvbGRIYXNoLCAwKTsKKyAgICAgICAgICAgIGxvbmcgdDEgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKworICAgICAgICAgICAgb2xkVGltZSA9IG9sZFRpbWUgKyAodDEgLSB0MCk7CisKKyAgICAgICAgICAgIGxvbmcgdDIgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNDsgaSsrKSB7CisgICAgICAgICAgICAgICAgbmV3RGlnZXN0LnVwZGF0ZShkYXRhLCAwLCBkYXRhLmxlbmd0aCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgbmV3TGVuZ3RoID0gbmV3RGlnZXN0LmRvRmluYWwobmV3SGFzaCwgMCk7CisgICAgICAgICAgICBsb25nIHQzID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisKKyAgICAgICAgICAgIG5ld1RpbWUgPSBuZXdUaW1lICsgKHQzIC0gdDIpOworCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkhhc2ggc2l6ZXMgbXVzdCBiZSBlcXVhbCIsIG9sZExlbmd0aCwgbmV3TGVuZ3RoKTsKKworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvbGRMZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSGFzaGVzWyIgKyBpICsgIl0gbXVzdCBiZSBlcXVhbCIsIG9sZEhhc2hbaV0sIG5ld0hhc2hbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUaW1lIGZvciAiICsgSVRFUkFUSU9OUyArICIgeCBvbGQgaGFzaCBwcm9jZXNzaW5nOiAiICsgb2xkVGltZSArICIgbXMiKTsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUaW1lIGZvciAiICsgSVRFUkFUSU9OUyArICIgeCBuZXcgaGFzaCBwcm9jZXNzaW5nOiAiICsgbmV3VGltZSArICIgbXMiKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJOZXcgaGFzaCBzaG91bGQgYmUgZmFzdGVyIiwgbmV3VGltZSA8IG9sZFRpbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHRoZSBNRDUgaW1wbGVtZW50YXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE1ENSgpIHsKKyAgICAgICAgRGlnZXN0IG9sZERpZ2VzdCA9IG5ldyBNRDVEaWdlc3QoKTsKKyAgICAgICAgRGlnZXN0IG5ld0RpZ2VzdCA9IG5ldyBPcGVuU1NMRGlnZXN0Lk1ENSgpOworICAgICAgICBkb1Rlc3RNZXNzYWdlRGlnZXN0KG9sZERpZ2VzdCwgbmV3RGlnZXN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB0aGUgU0hBLTEgaW1wbGVtZW50YXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNIQTEoKSB7CisgICAgICAgIERpZ2VzdCBvbGREaWdlc3QgPSBuZXcgU0hBMURpZ2VzdCgpOworICAgICAgICBEaWdlc3QgbmV3RGlnZXN0ID0gbmV3IE9wZW5TU0xEaWdlc3QuU0hBMSgpOworICAgICAgICBkb1Rlc3RNZXNzYWdlRGlnZXN0KG9sZERpZ2VzdCwgbmV3RGlnZXN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB0aGUgU0hBLTI1NiBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U0hBMjU2KCkgeworICAgICAgICBEaWdlc3Qgb2xkRGlnZXN0ID0gbmV3IFNIQTI1NkRpZ2VzdCgpOworICAgICAgICBEaWdlc3QgbmV3RGlnZXN0ID0gbmV3IE9wZW5TU0xEaWdlc3QuU0hBMjU2KCk7CisgICAgICAgIGRvVGVzdE1lc3NhZ2VEaWdlc3Qob2xkRGlnZXN0LCBuZXdEaWdlc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHRoZSBTSEEtMzg0IGltcGxlbWVudGF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTSEEzODQoKSB7CisgICAgICAgIERpZ2VzdCBvbGREaWdlc3QgPSBuZXcgU0hBMzg0RGlnZXN0KCk7CisgICAgICAgIERpZ2VzdCBuZXdEaWdlc3QgPSBuZXcgT3BlblNTTERpZ2VzdC5TSEEzODQoKTsKKyAgICAgICAgZG9UZXN0TWVzc2FnZURpZ2VzdChvbGREaWdlc3QsIG5ld0RpZ2VzdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgdGhlIFNIQS01MTIgaW1wbGVtZW50YXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNIQTUxMigpIHsKKyAgICAgICAgRGlnZXN0IG9sZERpZ2VzdCA9IG5ldyBTSEE1MTJEaWdlc3QoKTsKKyAgICAgICAgRGlnZXN0IG5ld0RpZ2VzdCA9IG5ldyBPcGVuU1NMRGlnZXN0LlNIQTUxMigpOworICAgICAgICBkb1Rlc3RNZXNzYWdlRGlnZXN0KG9sZERpZ2VzdCwgbmV3RGlnZXN0KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvZGFsdmlrL3N5c3RlbS9EZXhDbGFzc0xvYWRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9kYWx2aWsvc3lzdGVtL0RleENsYXNzTG9hZGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUxMzNlYTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvZGFsdmlrL3N5c3RlbS9EZXhDbGFzc0xvYWRlclRlc3QuamF2YQpAQCAtMCwwICsxLDQ4NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgZGFsdmlrLnN5c3RlbTsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGxpYmNvcmUuaW8uU3RyZWFtczsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIHRoZSBjbGFzcyB7QGxpbmsgRGV4Q2xhc3NMb2FkZXJ9LgorICovCitwdWJsaWMgY2xhc3MgRGV4Q2xhc3NMb2FkZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpbGUgVE1QX0RJUiA9CisgICAgICAgIG5ldyBGaWxlKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKSwgImxvYWRpbmctdGVzdCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQQUNLQUdFX1BBVEggPSAiZGFsdmlrL3N5c3RlbS8iOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBKQVJfTkFNRSA9ICJsb2FkaW5nLXRlc3QuamFyIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVYX05BTUUgPSAibG9hZGluZy10ZXN0LmRleCI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEpBUjJfTkFNRSA9ICJsb2FkaW5nLXRlc3QyLmphciI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIERFWDJfTkFNRSA9ICJsb2FkaW5nLXRlc3QyLmRleCI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmlsZSBKQVJfRklMRSA9IG5ldyBGaWxlKFRNUF9ESVIsIEpBUl9OQU1FKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWxlIERFWF9GSUxFID0gbmV3IEZpbGUoVE1QX0RJUiwgREVYX05BTUUpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpbGUgSkFSMl9GSUxFID0gbmV3IEZpbGUoVE1QX0RJUiwgSkFSMl9OQU1FKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWxlIERFWDJfRklMRSA9IG5ldyBGaWxlKFRNUF9ESVIsIERFWDJfTkFNRSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmlsZSBPUFRJTUlaRURfRElSID0gbmV3IEZpbGUoVE1QX0RJUiwgIm9wdGltaXplZCIpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZW51bSBDb25maWd1cmF0aW9uIHsKKyAgICAgICAgLyoqIGp1c3Qgb25lIGNsYXNzcGF0aCBlbGVtZW50LCBhIHJhdyBkZXggZmlsZSAqLworICAgICAgICBPTkVfREVYKDEpLAorCisgICAgICAgIC8qKiBqdXN0IG9uZSBjbGFzc3BhdGggZWxlbWVudCwgYSBqYXIgZmlsZSAqLworICAgICAgICBPTkVfSkFSKDEpLAorCisgICAgICAgIC8qKiB0d28gY2xhc3NwYXRoIGVsZW1lbnRzLCBib3RoIHJhdyBkZXggZmlsZXMgKi8KKyAgICAgICAgVFdPX0RFWCgyKSwKKworICAgICAgICAvKiogdHdvIGNsYXNzcGF0aCBlbGVtZW50cywgYm90aCBqYXIgZmlsZXMgKi8KKyAgICAgICAgVFdPX0pBUigyKTsKKworICAgICAgICBwdWJsaWMgZmluYWwgaW50IGV4cGVjdGVkRmlsZXM7CisKKyAgICAgICAgQ29uZmlndXJhdGlvbihpbnQgZXhwZWN0ZWRGaWxlcykgeworICAgICAgICAgICAgdGhpcy5leHBlY3RlZEZpbGVzID0gZXhwZWN0ZWRGaWxlczsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgVE1QX0RJUi5ta2RpcnMoKTsKKworICAgICAgICBDbGFzc0xvYWRlciBjbCA9IERleENsYXNzTG9hZGVyVGVzdC5jbGFzcy5nZXRDbGFzc0xvYWRlcigpOworICAgICAgICBjb3B5UmVzb3VyY2UoY2wsIEpBUl9OQU1FLCBKQVJfRklMRSk7CisgICAgICAgIGNvcHlSZXNvdXJjZShjbCwgREVYX05BTUUsIERFWF9GSUxFKTsKKyAgICAgICAgY29weVJlc291cmNlKGNsLCBKQVIyX05BTUUsIEpBUjJfRklMRSk7CisgICAgICAgIGNvcHlSZXNvdXJjZShjbCwgREVYMl9OQU1FLCBERVgyX0ZJTEUpOworCisgICAgICAgIE9QVElNSVpFRF9ESVIubWtkaXJzKCk7CisgICAgICAgIEZpbGVbXSBmaWxlcyA9IE9QVElNSVpFRF9ESVIubGlzdEZpbGVzKCk7CisgICAgICAgIGZvciAoRmlsZSBmaWxlIDogZmlsZXMpIHsKKyAgICAgICAgICAgIGZpbGUuZGVsZXRlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3B5IGEgcmVzb3VyY2UgaW4gdGhlIHBhY2thZ2UgZGlyZWN0b3J5IHRvIHRoZSBpbmRpY2F0ZWQKKyAgICAgKiB0YXJnZXQgZmlsZSwgYnV0IG9ubHkgaWYgdGhlIHRhcmdldCBmaWxlIGRvZXNuJ3QgZXhpc3QuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjb3B5UmVzb3VyY2UoQ2xhc3NMb2FkZXIgbG9hZGVyLCBTdHJpbmcgcmVzb3VyY2VOYW1lLAorICAgICAgICAgICAgRmlsZSBkZXN0aW5hdGlvbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGRlc3RpbmF0aW9uLmV4aXN0cygpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgICAgICBsb2FkZXIuZ2V0UmVzb3VyY2VBc1N0cmVhbShQQUNLQUdFX1BBVEggKyByZXNvdXJjZU5hbWUpOworICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGRlc3RpbmF0aW9uKTsKKyAgICAgICAgU3RyZWFtcy5jb3B5KGluLCBvdXQpOworICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBIZWxwZXIgdG8gY29uc3RydWN0IGFuIGluc3RhbmNlIHRvIHRlc3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29uZmlnIGhvdyB0byBjb25maWd1cmUgdGhlIGNsYXNzcGF0aAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIERleENsYXNzTG9hZGVyIGNyZWF0ZUluc3RhbmNlKENvbmZpZ3VyYXRpb24gY29uZmlnKSB7CisgICAgICAgIEZpbGUgZmlsZTE7CisgICAgICAgIEZpbGUgZmlsZTI7CisKKyAgICAgICAgc3dpdGNoIChjb25maWcpIHsKKyAgICAgICAgICAgIGNhc2UgT05FX0RFWDogZmlsZTEgPSBERVhfRklMRTsgZmlsZTIgPSBudWxsOyAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSBPTkVfSkFSOiBmaWxlMSA9IEpBUl9GSUxFOyBmaWxlMiA9IG51bGw7ICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFRXT19ERVg6IGZpbGUxID0gREVYX0ZJTEU7IGZpbGUyID0gREVYMl9GSUxFOyBicmVhazsKKyAgICAgICAgICAgIGNhc2UgVFdPX0pBUjogZmlsZTEgPSBKQVJfRklMRTsgZmlsZTIgPSBKQVIyX0ZJTEU7IGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJzaG91bGRuJ3QgaGFwcGVuIik7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgcGF0aCA9IGZpbGUxLmdldEFic29sdXRlUGF0aCgpOworICAgICAgICBpZiAoZmlsZTIgIT0gbnVsbCkgeworICAgICAgICAgICAgcGF0aCArPSBGaWxlLnBhdGhTZXBhcmF0b3IgKyBmaWxlMi5nZXRBYnNvbHV0ZVBhdGgoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgRGV4Q2xhc3NMb2FkZXIoCisgICAgICAgICAgICBwYXRoLCBPUFRJTUlaRURfRElSLmdldEFic29sdXRlUGF0aCgpLCBudWxsLAorICAgICAgICAgICAgQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSGVscGVyIHRvIGNvbnN0cnVjdCBhbiBpbnN0YW5jZSB0byB0ZXN0LCB1c2luZyB0aGUgamFyIGZpbGUgYXMKKyAgICAgKiB0aGUgc291cmNlLCBhbmQgY2FsbCBhIG5hbWVkIG5vLWFyZ3VtZW50IHN0YXRpYyBtZXRob2Qgb24gYQorICAgICAqIG5hbWVkIGNsYXNzLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbmZpZyBob3cgdG8gY29uZmlndXJlIHRoZSBjbGFzc3BhdGgKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIE9iamVjdCBjcmVhdGVJbnN0YW5jZUFuZENhbGxTdGF0aWNNZXRob2QoCisgICAgICAgICAgICBDb25maWd1cmF0aW9uIGNvbmZpZywgU3RyaW5nIGNsYXNzTmFtZSwgU3RyaW5nIG1ldGhvZE5hbWUpCisgICAgICAgICAgICB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwgTm9TdWNoTWV0aG9kRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiB7CisgICAgICAgIERleENsYXNzTG9hZGVyIGRjbCA9IGNyZWF0ZUluc3RhbmNlKGNvbmZpZyk7CisgICAgICAgIENsYXNzIGMgPSBkY2wubG9hZENsYXNzKGNsYXNzTmFtZSk7CisgICAgICAgIE1ldGhvZCBtID0gYy5nZXRNZXRob2QobWV0aG9kTmFtZSwgKENsYXNzW10pIG51bGwpOworICAgICAgICByZXR1cm4gbS5pbnZva2UobnVsbCwgKE9iamVjdFtdKSBudWxsKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFRlc3RzIHRoYXQgYXJlIHBhcmFtZXRyaWMgd2l0aCByZXNwZWN0IHRvIHdoZXRoZXIgdG8gdXNlIGEgamFyCisgICAgICogZmlsZSBvciBhIGRleCBmaWxlIGFzIHRoZSBzb3VyY2Ugb2YgdGhlIGNvZGUKKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIEp1c3QgYSB0cml2aWFsIHRlc3Qgb2YgY29uc3RydWN0aW9uLiBUaGlzIG9uZSBtZXJlbHkgbWFrZXMKKyAgICAgKiBzdXJlIHRoYXQgYSB2YWxpZCBjb25zdHJ1Y3Rpb24gZG9lc24ndCBmYWlsLiBJdCBkb2Vzbid0IHRyeQorICAgICAqIHRvIHZlcmlmeSBhbnl0aGluZyBhYm91dCB0aGUgY29uc3RydWN0ZWQgaW5zdGFuY2UsIG90aGVyIHRoYW4KKyAgICAgKiBjaGVja2luZyBmb3IgdGhlIGV4aXN0ZW5jZSBvZiBvcHRpbWl6ZWQgZGV4IGZpbGVzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdGVzdF9pbml0KENvbmZpZ3VyYXRpb24gY29uZmlnKSB7CisgICAgICAgIGNyZWF0ZUluc3RhbmNlKGNvbmZpZyk7CisKKyAgICAgICAgaW50IGV4cGVjdGVkRmlsZXMgPSBjb25maWcuZXhwZWN0ZWRGaWxlczsKKyAgICAgICAgaW50IGFjdHVhbEZpbGVzID0gT1BUSU1JWkVEX0RJUi5saXN0RmlsZXMoKS5sZW5ndGg7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkRmlsZXMsIGFjdHVhbEZpbGVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB0aGF0IGEgY2xhc3MgaW4gdGhlIGphci9kZXggZmlsZSBtYXkgYmUgdXNlZCBzdWNjZXNzZnVsbHkuIEluIHRoaXMKKyAgICAgKiBjYXNlLCBhIHRyaXZpYWwgc3RhdGljIG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB0ZXN0X3NpbXBsZVVzZShDb25maWd1cmF0aW9uIGNvbmZpZykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyByZXN1bHQgPSAoU3RyaW5nKQorICAgICAgICAgICAgY3JlYXRlSW5zdGFuY2VBbmRDYWxsU3RhdGljTWV0aG9kKGNvbmZpZywgInRlc3QuVGVzdDEiLCAidGVzdCIpOworCisgICAgICAgIGFzc2VydFNhbWUoImJsb3J0IiwgcmVzdWx0KTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEFsbCB0aGUgZm9sbG93aW5nIHRlc3RzIGFyZSBqdXN0IHBhc3MtdGhyb3VnaHMgdG8gdGVzdCBjb2RlCisgICAgICogdGhhdCBsaXZlcyBpbnNpZGUgdGhlIGxvYWRpbmctdGVzdCBkZXgvamFyIGZpbGUuCisgICAgICovCisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHRlc3RfY29uc3RydWN0b3IoQ29uZmlndXJhdGlvbiBjb25maWcpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY3JlYXRlSW5zdGFuY2VBbmRDYWxsU3RhdGljTWV0aG9kKAorICAgICAgICAgICAgY29uZmlnLCAidGVzdC5UZXN0TWV0aG9kcyIsICJ0ZXN0X2NvbnN0cnVjdG9yIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB0ZXN0X2NhbGxTdGF0aWNNZXRob2QoQ29uZmlndXJhdGlvbiBjb25maWcpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY3JlYXRlSW5zdGFuY2VBbmRDYWxsU3RhdGljTWV0aG9kKAorICAgICAgICAgICAgY29uZmlnLCAidGVzdC5UZXN0TWV0aG9kcyIsICJ0ZXN0X2NhbGxTdGF0aWNNZXRob2QiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHRlc3RfZ2V0U3RhdGljVmFyaWFibGUoQ29uZmlndXJhdGlvbiBjb25maWcpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY3JlYXRlSW5zdGFuY2VBbmRDYWxsU3RhdGljTWV0aG9kKAorICAgICAgICAgICAgY29uZmlnLCAidGVzdC5UZXN0TWV0aG9kcyIsICJ0ZXN0X2dldFN0YXRpY1ZhcmlhYmxlIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB0ZXN0X2NhbGxJbnN0YW5jZU1ldGhvZChDb25maWd1cmF0aW9uIGNvbmZpZykKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjcmVhdGVJbnN0YW5jZUFuZENhbGxTdGF0aWNNZXRob2QoCisgICAgICAgICAgICBjb25maWcsICJ0ZXN0LlRlc3RNZXRob2RzIiwgInRlc3RfY2FsbEluc3RhbmNlTWV0aG9kIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlVmFyaWFibGUoQ29uZmlndXJhdGlvbiBjb25maWcpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY3JlYXRlSW5zdGFuY2VBbmRDYWxsU3RhdGljTWV0aG9kKAorICAgICAgICAgICAgY29uZmlnLCAidGVzdC5UZXN0TWV0aG9kcyIsICJ0ZXN0X2dldEluc3RhbmNlVmFyaWFibGUiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHRlc3RfZGlmZl9jb25zdHJ1Y3RvcihDb25maWd1cmF0aW9uIGNvbmZpZykKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjcmVhdGVJbnN0YW5jZUFuZENhbGxTdGF0aWNNZXRob2QoCisgICAgICAgICAgICBjb25maWcsICJ0ZXN0LlRlc3RNZXRob2RzIiwgInRlc3RfZGlmZl9jb25zdHJ1Y3RvciIpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdGVzdF9kaWZmX2NhbGxTdGF0aWNNZXRob2QoQ29uZmlndXJhdGlvbiBjb25maWcpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY3JlYXRlSW5zdGFuY2VBbmRDYWxsU3RhdGljTWV0aG9kKAorICAgICAgICAgICAgY29uZmlnLCAidGVzdC5UZXN0TWV0aG9kcyIsICJ0ZXN0X2RpZmZfY2FsbFN0YXRpY01ldGhvZCIpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdGVzdF9kaWZmX2dldFN0YXRpY1ZhcmlhYmxlKENvbmZpZ3VyYXRpb24gY29uZmlnKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNyZWF0ZUluc3RhbmNlQW5kQ2FsbFN0YXRpY01ldGhvZCgKKyAgICAgICAgICAgIGNvbmZpZywgInRlc3QuVGVzdE1ldGhvZHMiLCAidGVzdF9kaWZmX2dldFN0YXRpY1ZhcmlhYmxlIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB0ZXN0X2RpZmZfY2FsbEluc3RhbmNlTWV0aG9kKENvbmZpZ3VyYXRpb24gY29uZmlnKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNyZWF0ZUluc3RhbmNlQW5kQ2FsbFN0YXRpY01ldGhvZCgKKyAgICAgICAgICAgIGNvbmZpZywgInRlc3QuVGVzdE1ldGhvZHMiLCAidGVzdF9kaWZmX2NhbGxJbnN0YW5jZU1ldGhvZCIpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdGVzdF9kaWZmX2dldEluc3RhbmNlVmFyaWFibGUoQ29uZmlndXJhdGlvbiBjb25maWcpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY3JlYXRlSW5zdGFuY2VBbmRDYWxsU3RhdGljTWV0aG9kKAorICAgICAgICAgICAgY29uZmlnLCAidGVzdC5UZXN0TWV0aG9kcyIsICJ0ZXN0X2RpZmZfZ2V0SW5zdGFuY2VWYXJpYWJsZSIpOworICAgIH0KKworICAgIC8qCisgICAgICogVGhlc2UgbWV0aG9kcyBhcmUgYWxsIGVzc2VudGlhbGx5IGp1c3QgY2FsbHMgdG8gdGhlCisgICAgICogcGFyYW1ldHJpY2FsbHktZGVmaW5lZCB0ZXN0cyBhYm92ZS4KKyAgICAgKi8KKworICAgIC8vIE9ORV9KQVIKKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfb25lSmFyX2luaXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9pbml0KENvbmZpZ3VyYXRpb24uT05FX0pBUik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9vbmVKYXJfc2ltcGxlVXNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3Rfc2ltcGxlVXNlKENvbmZpZ3VyYXRpb24uT05FX0pBUik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9vbmVKYXJfY29uc3RydWN0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9jb25zdHJ1Y3RvcihDb25maWd1cmF0aW9uLk9ORV9KQVIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfb25lSmFyX2NhbGxTdGF0aWNNZXRob2QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9jYWxsU3RhdGljTWV0aG9kKENvbmZpZ3VyYXRpb24uT05FX0pBUik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9vbmVKYXJfZ2V0U3RhdGljVmFyaWFibGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9nZXRTdGF0aWNWYXJpYWJsZShDb25maWd1cmF0aW9uLk9ORV9KQVIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfb25lSmFyX2NhbGxJbnN0YW5jZU1ldGhvZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0X2NhbGxJbnN0YW5jZU1ldGhvZChDb25maWd1cmF0aW9uLk9ORV9KQVIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfb25lSmFyX2dldEluc3RhbmNlVmFyaWFibGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9nZXRJbnN0YW5jZVZhcmlhYmxlKENvbmZpZ3VyYXRpb24uT05FX0pBUik7CisgICAgfQorCisgICAgLy8gT05FX0RFWAorCisgICAgcHVibGljIHZvaWQgdGVzdF9vbmVEZXhfaW5pdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0X2luaXQoQ29uZmlndXJhdGlvbi5PTkVfREVYKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X29uZURleF9zaW1wbGVVc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9zaW1wbGVVc2UoQ29uZmlndXJhdGlvbi5PTkVfREVYKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X29uZURleF9jb25zdHJ1Y3RvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0X2NvbnN0cnVjdG9yKENvbmZpZ3VyYXRpb24uT05FX0RFWCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9vbmVEZXhfY2FsbFN0YXRpY01ldGhvZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0X2NhbGxTdGF0aWNNZXRob2QoQ29uZmlndXJhdGlvbi5PTkVfREVYKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X29uZURleF9nZXRTdGF0aWNWYXJpYWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0X2dldFN0YXRpY1ZhcmlhYmxlKENvbmZpZ3VyYXRpb24uT05FX0RFWCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9vbmVEZXhfY2FsbEluc3RhbmNlTWV0aG9kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RfY2FsbEluc3RhbmNlTWV0aG9kKENvbmZpZ3VyYXRpb24uT05FX0RFWCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9vbmVEZXhfZ2V0SW5zdGFuY2VWYXJpYWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0X2dldEluc3RhbmNlVmFyaWFibGUoQ29uZmlndXJhdGlvbi5PTkVfREVYKTsKKyAgICB9CisKKyAgICAvLyBUV09fSkFSCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3R3b0phcl9pbml0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RfaW5pdChDb25maWd1cmF0aW9uLlRXT19KQVIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdHdvSmFyX3NpbXBsZVVzZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0X3NpbXBsZVVzZShDb25maWd1cmF0aW9uLlRXT19KQVIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdHdvSmFyX2NvbnN0cnVjdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RfY29uc3RydWN0b3IoQ29uZmlndXJhdGlvbi5UV09fSkFSKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3R3b0phcl9jYWxsU3RhdGljTWV0aG9kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RfY2FsbFN0YXRpY01ldGhvZChDb25maWd1cmF0aW9uLlRXT19KQVIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdHdvSmFyX2dldFN0YXRpY1ZhcmlhYmxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RfZ2V0U3RhdGljVmFyaWFibGUoQ29uZmlndXJhdGlvbi5UV09fSkFSKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3R3b0phcl9jYWxsSW5zdGFuY2VNZXRob2QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9jYWxsSW5zdGFuY2VNZXRob2QoQ29uZmlndXJhdGlvbi5UV09fSkFSKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3R3b0phcl9nZXRJbnN0YW5jZVZhcmlhYmxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RfZ2V0SW5zdGFuY2VWYXJpYWJsZShDb25maWd1cmF0aW9uLlRXT19KQVIpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0ZXN0X3R3b0phcl9kaWZmX2NvbnN0cnVjdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RfZGlmZl9jb25zdHJ1Y3RvcihDb25maWd1cmF0aW9uLlRXT19KQVIpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0ZXN0X3R3b0phcl9kaWZmX2NhbGxTdGF0aWNNZXRob2QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9kaWZmX2NhbGxTdGF0aWNNZXRob2QoQ29uZmlndXJhdGlvbi5UV09fSkFSKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdGVzdF90d29KYXJfZGlmZl9nZXRTdGF0aWNWYXJpYWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0X2RpZmZfZ2V0U3RhdGljVmFyaWFibGUoQ29uZmlndXJhdGlvbi5UV09fSkFSKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdGVzdF90d29KYXJfZGlmZl9jYWxsSW5zdGFuY2VNZXRob2QoKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RfZGlmZl9jYWxsSW5zdGFuY2VNZXRob2QoQ29uZmlndXJhdGlvbi5UV09fSkFSKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdGVzdF90d29KYXJfZGlmZl9nZXRJbnN0YW5jZVZhcmlhYmxlKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0X2RpZmZfZ2V0SW5zdGFuY2VWYXJpYWJsZShDb25maWd1cmF0aW9uLlRXT19KQVIpOworICAgIH0KKworICAgIC8vIFRXT19ERVgKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdHdvRGV4X2luaXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9pbml0KENvbmZpZ3VyYXRpb24uVFdPX0RFWCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90d29EZXhfc2ltcGxlVXNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3Rfc2ltcGxlVXNlKENvbmZpZ3VyYXRpb24uVFdPX0RFWCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90d29EZXhfY29uc3RydWN0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9jb25zdHJ1Y3RvcihDb25maWd1cmF0aW9uLlRXT19ERVgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdHdvRGV4X2NhbGxTdGF0aWNNZXRob2QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9jYWxsU3RhdGljTWV0aG9kKENvbmZpZ3VyYXRpb24uVFdPX0RFWCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90d29EZXhfZ2V0U3RhdGljVmFyaWFibGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9nZXRTdGF0aWNWYXJpYWJsZShDb25maWd1cmF0aW9uLlRXT19ERVgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdHdvRGV4X2NhbGxJbnN0YW5jZU1ldGhvZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0X2NhbGxJbnN0YW5jZU1ldGhvZChDb25maWd1cmF0aW9uLlRXT19ERVgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdHdvRGV4X2dldEluc3RhbmNlVmFyaWFibGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9nZXRJbnN0YW5jZVZhcmlhYmxlKENvbmZpZ3VyYXRpb24uVFdPX0RFWCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHRlc3RfdHdvRGV4X2RpZmZfY29uc3RydWN0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9kaWZmX2NvbnN0cnVjdG9yKENvbmZpZ3VyYXRpb24uVFdPX0RFWCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHRlc3RfdHdvRGV4X2RpZmZfY2FsbFN0YXRpY01ldGhvZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0X2RpZmZfY2FsbFN0YXRpY01ldGhvZChDb25maWd1cmF0aW9uLlRXT19ERVgpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0ZXN0X3R3b0RleF9kaWZmX2dldFN0YXRpY1ZhcmlhYmxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RfZGlmZl9nZXRTdGF0aWNWYXJpYWJsZShDb25maWd1cmF0aW9uLlRXT19ERVgpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0ZXN0X3R3b0RleF9kaWZmX2NhbGxJbnN0YW5jZU1ldGhvZCgpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9kaWZmX2NhbGxJbnN0YW5jZU1ldGhvZChDb25maWd1cmF0aW9uLlRXT19ERVgpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0ZXN0X3R3b0RleF9kaWZmX2dldEluc3RhbmNlVmFyaWFibGUoKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RfZGlmZl9nZXRJbnN0YW5jZVZhcmlhYmxlKENvbmZpZ3VyYXRpb24uVFdPX0RFWCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUZXN0cyBzcGVjaWZpY2FsbHkgZm9yIHJlc291cmNlLXJlbGF0ZWQgZnVuY3Rpb25hbGl0eS4gIFNpbmNlCisgICAgICogcmF3IGRleCBmaWxlcyBkb24ndCBjb250YWluIHJlc291cmNlcywgdGhlc2UgdGVzdCBvbmx5IHdvcmsKKyAgICAgKiB3aXRoIGphciBmaWxlcy4gVGhlIGZpcnN0IGNvdXBsZSBtZXRob2RzIGhlcmUgYXJlIGhlbHBlcnMsCisgICAgICogYW5kIHRoZXkgYXJlIGZvbGxvd2VkIGJ5IHRoZSB0ZXN0cyBwZXIgc2UuCisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBDaGVjayB0aGF0IGEgZ2l2ZW4gcmVzb3VyY2UgKGJ5IG5hbWUpIGlzIHJldHJpZXZhYmxlIGFuZCBjb250YWlucworICAgICAqIHRoZSBnaXZlbiBleHBlY3RlZCBjb250ZW50cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHRlc3RfZGlyZWN0R2V0UmVzb3VyY2VBc1N0cmVhbShDb25maWd1cmF0aW9uIGNvbmZpZywKKyAgICAgICAgICAgIFN0cmluZyByZXNvdXJjZU5hbWUsIFN0cmluZyBleHBlY3RlZENvbnRlbnRzKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIERleENsYXNzTG9hZGVyIGRjbCA9IGNyZWF0ZUluc3RhbmNlKGNvbmZpZyk7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gZGNsLmdldFJlc291cmNlQXNTdHJlYW0ocmVzb3VyY2VOYW1lKTsKKyAgICAgICAgYnl0ZVtdIGNvbnRlbnRzID0gU3RyZWFtcy5yZWFkRnVsbHkoaW4pOworICAgICAgICBTdHJpbmcgcyA9IG5ldyBTdHJpbmcoY29udGVudHMsICJVVEYtOCIpOworCisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZENvbnRlbnRzLCBzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB0aGF0IGEgcmVzb3VyY2UgaW4gdGhlIGphciBmaWxlIGlzIHJldHJpZXZhYmxlIGFuZCBjb250YWlucworICAgICAqIHRoZSBleHBlY3RlZCBjb250ZW50cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHRlc3RfZGlyZWN0R2V0UmVzb3VyY2VBc1N0cmVhbShDb25maWd1cmF0aW9uIGNvbmZpZykKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0X2RpcmVjdEdldFJlc291cmNlQXNTdHJlYW0oCisgICAgICAgICAgICBjb25maWcsICJ0ZXN0L1Jlc291cmNlMS50eHQiLCAiTXVmZmlucyBhcmUgdGFzdHkhXG4iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB0aGF0IGEgcmVzb3VyY2UgaW4gdGhlIGphciBmaWxlIGNhbiBiZSByZXRyaWV2ZWQgZnJvbQorICAgICAqIGEgY2xhc3Mgd2l0aGluIHRoYXQgamFyIGZpbGUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB0ZXN0X2dldFJlc291cmNlQXNTdHJlYW0oQ29uZmlndXJhdGlvbiBjb25maWcpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY3JlYXRlSW5zdGFuY2VBbmRDYWxsU3RhdGljTWV0aG9kKAorICAgICAgICAgICAgY29uZmlnLCAidGVzdC5UZXN0TWV0aG9kcyIsICJ0ZXN0X2dldFJlc291cmNlQXNTdHJlYW0iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X29uZUphcl9kaXJlY3RHZXRSZXNvdXJjZUFzU3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RfZGlyZWN0R2V0UmVzb3VyY2VBc1N0cmVhbShDb25maWd1cmF0aW9uLk9ORV9KQVIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfb25lSmFyX2dldFJlc291cmNlQXNTdHJlYW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdF9nZXRSZXNvdXJjZUFzU3RyZWFtKENvbmZpZ3VyYXRpb24uT05FX0pBUik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90d29KYXJfZGlyZWN0R2V0UmVzb3VyY2VBc1N0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0X2RpcmVjdEdldFJlc291cmNlQXNTdHJlYW0oQ29uZmlndXJhdGlvbi5UV09fSkFSKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3R3b0phcl9nZXRSZXNvdXJjZUFzU3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RfZ2V0UmVzb3VyY2VBc1N0cmVhbShDb25maWd1cmF0aW9uLlRXT19KQVIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIHRoYXQgYSByZXNvdXJjZSBpbiB0aGUgc2Vjb25kIGphciBmaWxlIGlzIHJldHJpZXZhYmxlIGFuZAorICAgICAqIGNvbnRhaW5zIHRoZSBleHBlY3RlZCBjb250ZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3R3b0phcl9kaWZmX2RpcmVjdEdldFJlc291cmNlQXNTdHJlYW0oKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RfZGlyZWN0R2V0UmVzb3VyY2VBc1N0cmVhbSgKKyAgICAgICAgICAgIENvbmZpZ3VyYXRpb24uVFdPX0pBUiwgInRlc3QyL1Jlc291cmNlMi50eHQiLAorICAgICAgICAgICAgIldobyBkb2Vzbid0IGxpa2UgYSBnb29kIGJpc2N1aXQ/XG4iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB0aGF0IGEgcmVzb3VyY2UgaW4gYSBqYXIgZmlsZSBjYW4gYmUgcmV0cmlldmVkIGZyb20KKyAgICAgKiBhIGNsYXNzIHdpdGhpbiB0aGUgb3RoZXIgamFyIGZpbGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF90d29KYXJfZGlmZl9nZXRSZXNvdXJjZUFzU3RyZWFtKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjcmVhdGVJbnN0YW5jZUFuZENhbGxTdGF0aWNNZXRob2QoCisgICAgICAgICAgICBDb25maWd1cmF0aW9uLlRXT19KQVIsICJ0ZXN0LlRlc3RNZXRob2RzIiwKKyAgICAgICAgICAgICJ0ZXN0X2RpZmZfZ2V0UmVzb3VyY2VBc1N0cmVhbSIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2RhbHZpay9zeXN0ZW0vUGF0aENsYXNzTG9hZGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvZGFsdmlrL3N5c3RlbS9QYXRoQ2xhc3NMb2FkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWU2ZDhkNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2RhbHZpay9zeXN0ZW0vUGF0aENsYXNzTG9hZGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuZGFsdmlrLnN5c3RlbTsKKworaW1wb3J0IGRhbHZpay5zeXN0ZW0uUGF0aENsYXNzTG9hZGVyOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBQYXRoQ2xhc3NMb2FkZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogTWFrZSBzdXJlIHdlJ3JlIHNlYXJjaGluZyB0aGUgYXBwbGljYXRpb24gbGlicmFyeSBwYXRoIGZpcnN0LgorICAgICAqIGh0dHA6Ly9iL2lzc3VlP2lkPTI5MzM0NTYKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TGlicmFyeVBhdGhTZWFyY2hPcmRlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgdG1wID0gbmV3IEZpbGUoU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmlvLnRtcGRpciIpKTsKKyAgICAgICAgRmlsZSBzeXN0ZW1MaWJQYXRoID0gbmV3IEZpbGUodG1wLCAic3lzdGVtTGliUGF0aCIpOworICAgICAgICBGaWxlIGFwcGxpY2F0aW9uTGliUGF0aCA9IG5ldyBGaWxlKHRtcCwgImFwcGxpY2F0aW9uTGliUGF0aCIpOworICAgICAgICBtYWtlVGVtcEZpbGUoc3lzdGVtTGliUGF0aCwgImxpYmR1cGxpY2F0ZWQuc28iKTsKKyAgICAgICAgRmlsZSBhcHBsaWNhdGlvbkxpYiA9IG1ha2VUZW1wRmlsZShhcHBsaWNhdGlvbkxpYlBhdGgsICJsaWJkdXBsaWNhdGVkLnNvIik7CisKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJqYXZhLmxpYnJhcnkucGF0aCIsIHN5c3RlbUxpYlBhdGgudG9TdHJpbmcoKSk7CisgICAgICAgIFBhdGhDbGFzc0xvYWRlciBwYXRoQ2xhc3NMb2FkZXIgPSBuZXcgUGF0aENsYXNzTG9hZGVyKGFwcGxpY2F0aW9uTGliUGF0aC50b1N0cmluZygpLAorICAgICAgICAgICAgICAgIGFwcGxpY2F0aW9uTGliUGF0aC50b1N0cmluZygpLCBnZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCkpOworCisgICAgICAgIFN0cmluZyBwYXRoID0gcGF0aENsYXNzTG9hZGVyLmZpbmRMaWJyYXJ5KCJkdXBsaWNhdGVkIik7CisgICAgICAgIGFzc2VydEVxdWFscyhhcHBsaWNhdGlvbkxpYi50b1N0cmluZygpLCBwYXRoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIEZpbGUgbWFrZVRlbXBGaWxlKEZpbGUgZGlyZWN0b3J5LCBTdHJpbmcgbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZGlyZWN0b3J5Lm1rZGlycygpOworICAgICAgICBGaWxlIHJlc3VsdCA9IG5ldyBGaWxlKGRpcmVjdG9yeSwgbmFtZSk7CisgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gc3RyZWFtID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0ocmVzdWx0KTsKKyAgICAgICAgc3RyZWFtLmNsb3NlKCk7CisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LmV4aXN0cygpKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9pY3UvSUNVVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvaWN1L0lDVVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MjgyMTY3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvaWN1L0lDVVRlc3QuamF2YQpAQCAtMCwwICsxLDU2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmljdTsKKworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CisKK3B1YmxpYyBjbGFzcyBJQ1VUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldElTT0xhbmd1YWdlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBDaGVjayB0aGF0IGNvcnJ1cHRpbmcgb3VyIGFycmF5IGRvZXNuJ3QgYWZmZWN0IG90aGVyIGNhbGxlcnMuCisgICAgICAgIGFzc2VydE5vdE51bGwoSUNVLmdldElTT0xhbmd1YWdlcygpWzBdKTsKKyAgICAgICAgSUNVLmdldElTT0xhbmd1YWdlcygpWzBdID0gbnVsbDsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChJQ1UuZ2V0SVNPTGFuZ3VhZ2VzKClbMF0pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SVNPQ291bnRyaWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIENoZWNrIHRoYXQgY29ycnVwdGluZyBvdXIgYXJyYXkgZG9lc24ndCBhZmZlY3Qgb3RoZXIgY2FsbGVycy4KKyAgICAgICAgYXNzZXJ0Tm90TnVsbChJQ1UuZ2V0SVNPQ291bnRyaWVzKClbMF0pOworICAgICAgICBJQ1UuZ2V0SVNPQ291bnRyaWVzKClbMF0gPSBudWxsOworICAgICAgICBhc3NlcnROb3ROdWxsKElDVS5nZXRJU09Db3VudHJpZXMoKVswXSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBdmFpbGFibGVMb2NhbGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIENoZWNrIHRoYXQgY29ycnVwdGluZyBvdXIgYXJyYXkgZG9lc24ndCBhZmZlY3Qgb3RoZXIgY2FsbGVycy4KKyAgICAgICAgYXNzZXJ0Tm90TnVsbChJQ1UuZ2V0QXZhaWxhYmxlTG9jYWxlcygpWzBdKTsKKyAgICAgICAgSUNVLmdldEF2YWlsYWJsZUxvY2FsZXMoKVswXSA9IG51bGw7CisgICAgICAgIGFzc2VydE5vdE51bGwoSUNVLmdldEF2YWlsYWJsZUxvY2FsZXMoKVswXSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sb2NhbGVGcm9tU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIGxvY2FsZUZyb21TdHJpbmcgaXMgcHJldHR5IGxlbmllbnQuIFNvbWUgb2YgdGhlc2UgY2FuJ3QgYmUgcm91bmQtdHJpcHBlZAorICAgICAgICAvLyB0aHJvdWdoIExvY2FsZS50b1N0cmluZy4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKExvY2FsZS5FTkdMSVNILCBJQ1UubG9jYWxlRnJvbVN0cmluZygiZW4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhMb2NhbGUuRU5HTElTSCwgSUNVLmxvY2FsZUZyb21TdHJpbmcoImVuXyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExvY2FsZS5FTkdMSVNILCBJQ1UubG9jYWxlRnJvbVN0cmluZygiZW5fXyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExvY2FsZS5VUywgSUNVLmxvY2FsZUZyb21TdHJpbmcoImVuX1VTIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoTG9jYWxlLlVTLCBJQ1UubG9jYWxlRnJvbVN0cmluZygiZW5fVVNfIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IExvY2FsZSgiIiwgIlVTIiwgIiIpLCBJQ1UubG9jYWxlRnJvbVN0cmluZygiX1VTIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IExvY2FsZSgiIiwgIlVTIiwgIiIpLCBJQ1UubG9jYWxlRnJvbVN0cmluZygiX1VTXyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBMb2NhbGUoIiIsICIiLCAiUE9TSVgiKSwgSUNVLmxvY2FsZUZyb21TdHJpbmcoIl9fUE9TSVgiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgTG9jYWxlKCJhYSIsICJCQiIsICJDQyIpLCBJQ1UubG9jYWxlRnJvbVN0cmluZygiYWFfQkJfQ0MiKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvaWN1L05hdGl2ZVBsdXJhbFJ1bGVzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvaWN1L05hdGl2ZVBsdXJhbFJ1bGVzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjYzNjYTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9pY3UvTmF0aXZlUGx1cmFsUnVsZXNUZXN0LmphdmEKQEAgLTAsMCArMSw1OCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pY3U7CisKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCitwdWJsaWMgY2xhc3MgTmF0aXZlUGx1cmFsUnVsZXNUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5nbGlzaCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBOYXRpdmVQbHVyYWxSdWxlcyBucHIgPSBOYXRpdmVQbHVyYWxSdWxlcy5mb3JMb2NhbGUobmV3IExvY2FsZSgiZW4iLCAiVVMiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhOYXRpdmVQbHVyYWxSdWxlcy5PVEhFUiwgbnByLnF1YW50aXR5Rm9ySW50KC0xKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhOYXRpdmVQbHVyYWxSdWxlcy5PVEhFUiwgbnByLnF1YW50aXR5Rm9ySW50KDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE5hdGl2ZVBsdXJhbFJ1bGVzLk9ORSwgbnByLnF1YW50aXR5Rm9ySW50KDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE5hdGl2ZVBsdXJhbFJ1bGVzLk9USEVSLCBucHIucXVhbnRpdHlGb3JJbnQoMikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDemVjaCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBOYXRpdmVQbHVyYWxSdWxlcyBucHIgPSBOYXRpdmVQbHVyYWxSdWxlcy5mb3JMb2NhbGUobmV3IExvY2FsZSgiY3MiLCAiQ1oiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhOYXRpdmVQbHVyYWxSdWxlcy5PVEhFUiwgbnByLnF1YW50aXR5Rm9ySW50KC0xKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhOYXRpdmVQbHVyYWxSdWxlcy5PVEhFUiwgbnByLnF1YW50aXR5Rm9ySW50KDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE5hdGl2ZVBsdXJhbFJ1bGVzLk9ORSwgbnByLnF1YW50aXR5Rm9ySW50KDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE5hdGl2ZVBsdXJhbFJ1bGVzLkZFVywgbnByLnF1YW50aXR5Rm9ySW50KDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE5hdGl2ZVBsdXJhbFJ1bGVzLkZFVywgbnByLnF1YW50aXR5Rm9ySW50KDMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE5hdGl2ZVBsdXJhbFJ1bGVzLkZFVywgbnByLnF1YW50aXR5Rm9ySW50KDQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE5hdGl2ZVBsdXJhbFJ1bGVzLk9USEVSLCBucHIucXVhbnRpdHlGb3JJbnQoNSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBcmFiaWMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTmF0aXZlUGx1cmFsUnVsZXMgbnByID0gTmF0aXZlUGx1cmFsUnVsZXMuZm9yTG9jYWxlKG5ldyBMb2NhbGUoImFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoTmF0aXZlUGx1cmFsUnVsZXMuT1RIRVIsIG5wci5xdWFudGl0eUZvckludCgtMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoTmF0aXZlUGx1cmFsUnVsZXMuWkVSTywgbnByLnF1YW50aXR5Rm9ySW50KDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE5hdGl2ZVBsdXJhbFJ1bGVzLk9ORSwgbnByLnF1YW50aXR5Rm9ySW50KDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE5hdGl2ZVBsdXJhbFJ1bGVzLlRXTywgbnByLnF1YW50aXR5Rm9ySW50KDIpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDM7IGkgPD0gMTA7ICsraSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKE5hdGl2ZVBsdXJhbFJ1bGVzLkZFVywgbnByLnF1YW50aXR5Rm9ySW50KGkpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoTmF0aXZlUGx1cmFsUnVsZXMuTUFOWSwgbnByLnF1YW50aXR5Rm9ySW50KDExKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhOYXRpdmVQbHVyYWxSdWxlcy5NQU5ZLCBucHIucXVhbnRpdHlGb3JJbnQoOTkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE5hdGl2ZVBsdXJhbFJ1bGVzLk9USEVSLCBucHIucXVhbnRpdHlGb3JJbnQoMTAwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhOYXRpdmVQbHVyYWxSdWxlcy5PVEhFUiwgbnByLnF1YW50aXR5Rm9ySW50KDEwMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoTmF0aXZlUGx1cmFsUnVsZXMuT1RIRVIsIG5wci5xdWFudGl0eUZvckludCgxMDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE5hdGl2ZVBsdXJhbFJ1bGVzLkZFVywgbnByLnF1YW50aXR5Rm9ySW50KDEwMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoTmF0aXZlUGx1cmFsUnVsZXMuTUFOWSwgbnByLnF1YW50aXR5Rm9ySW50KDExMSkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2ludGVybmFsL1N0cmluZ1Bvb2xUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9pbnRlcm5hbC9TdHJpbmdQb29sVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyYzdjNGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9pbnRlcm5hbC9TdHJpbmdQb29sVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuaW50ZXJuYWw7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgbGliY29yZS5pbnRlcm5hbC5TdHJpbmdQb29sOworCitwdWJsaWMgZmluYWwgY2xhc3MgU3RyaW5nUG9vbFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RyaW5nUG9vbCgpIHsKKyAgICAgIFN0cmluZ1Bvb2wgc3RyaW5nUG9vbCA9IG5ldyBTdHJpbmdQb29sKCk7CisgICAgICBTdHJpbmcgYmNkID0gc3RyaW5nUG9vbC5nZXQobmV3IGNoYXJbXSB7ICdhJywgJ2InLCAnYycsICdkJywgJ2UnIH0sIDEsIDMpOworICAgICAgYXNzZXJ0RXF1YWxzKCJiY2QiLCBiY2QpOworICAgICAgYXNzZXJ0U2FtZShiY2QsIHN0cmluZ1Bvb2wuZ2V0KG5ldyBjaGFyW10geyAnYScsICdiJywgJ2MnLCAnZCcsICdlJyB9LCAxLCAzKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEhhc2hDb2xsaXNpb24oKSB7CisgICAgICBTdHJpbmdQb29sIHN0cmluZ1Bvb2wgPSBuZXcgU3RyaW5nUG9vbCgpOworICAgICAgY2hhcltdIGEgPSB7IChjaGFyKSAxLCAoY2hhcikgMCB9OworICAgICAgY2hhcltdIGIgPSB7IChjaGFyKSAwLCAoY2hhcikgMzEgfTsKKyAgICAgIGFzc2VydEVxdWFscyhuZXcgU3RyaW5nKGEpLmhhc2hDb2RlKCksIG5ldyBTdHJpbmcoYikuaGFzaENvZGUoKSk7CisKKyAgICAgIFN0cmluZyBhU3RyaW5nID0gc3RyaW5nUG9vbC5nZXQoYSwgMCwgMik7CisgICAgICBhc3NlcnRFcXVhbHMobmV3IFN0cmluZyhhKSwgYVN0cmluZyk7CisgICAgICBTdHJpbmcgYlN0cmluZyA9IHN0cmluZ1Bvb2wuZ2V0KGIsIDAsIDIpOworICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBTdHJpbmcoYiksIGJTdHJpbmcpOworICAgICAgYXNzZXJ0U2FtZShiU3RyaW5nLCBzdHJpbmdQb29sLmdldChiLCAwLCAyKSk7CisgICAgICBhc3NlcnROb3RTYW1lKGFTdHJpbmcsIHN0cmluZ1Bvb2wuZ2V0KGEsIDAsIDIpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9pby9CYXNlNjRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9pby9CYXNlNjRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWRmMjRkNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2lvL0Jhc2U2NFRlc3QuamF2YQpAQCAtMCwwICsxLDU1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuaW87CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIEJhc2U2NFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVjb2RlRW1wdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbXSIsIEFycmF5cy50b1N0cmluZyhCYXNlNjQuZGVjb2RlKG5ldyBieXRlWzBdKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbmNvZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RW5jb2RlZCgiIik7CisgICAgICAgIGFzc2VydEVuY29kZWQoIkVnPT0iLCAweDEyKTsKKyAgICAgICAgYXNzZXJ0RW5jb2RlZCgiRWpRPSIsIDB4MTIsIDB4MzQgKTsKKyAgICAgICAgYXNzZXJ0RW5jb2RlZCgiRWpSVyIsIDB4MTIsIDB4MzQsIDB4NTYpOworICAgICAgICBhc3NlcnRFbmNvZGVkKCJFalJXZUE9PSIsIDB4MTIsIDB4MzQsIDB4NTYsIDB4NzgpOworICAgICAgICBhc3NlcnRFbmNvZGVkKCJFalJXZUpvPSIsIDB4MTIsIDB4MzQsIDB4NTYsIDB4NzgsIDB4OUEpOworICAgICAgICBhc3NlcnRFbmNvZGVkKCJFalJXZUpxOCIsIDB4MTIsIDB4MzQsIDB4NTYsIDB4NzgsIDB4OWEsIDB4YmMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbmNvZGVEb2VzTm90V3JhcCgpIHsKKyAgICAgICAgaW50W10gZGF0YSA9IG5ldyBpbnRbNjFdOworICAgICAgICBBcnJheXMuZmlsbChkYXRhLCAweGZmKTsKKyAgICAgICAgU3RyaW5nIGV4cGVjdGVkID0gIi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIgorICAgICAgICAgICAgICAgICsgIi8vLy8vLy8vLy93PT0iOyAvLyA4NCBjaGFycworICAgICAgICBhc3NlcnRFbmNvZGVkKGV4cGVjdGVkLCBkYXRhKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhc3NlcnRFbmNvZGVkKFN0cmluZyBleHBlY3RlZCAsIGludC4uLiBkYXRhKSB7CisgICAgICAgIGJ5dGVbXSBkYXRhQnl0ZXMgPSBuZXcgYnl0ZVtkYXRhLmxlbmd0aF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZGF0YUJ5dGVzW2ldID0gKGJ5dGUpIGRhdGFbaV07CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBCYXNlNjQuZW5jb2RlKGRhdGFCeXRlcykpOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvaW8vRGlza0xydUNhY2hlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvaW8vRGlza0xydUNhY2hlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgwODkxOGQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9pby9EaXNrTHJ1Q2FjaGVUZXN0LmphdmEKQEAgLTAsMCArMSw3NTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuaW87CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVSZWFkZXI7CitpbXBvcnQgamF2YS5pby5GaWxlV3JpdGVyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLldyaXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IHN0YXRpYyBsaWJjb3JlLmlvLkRpc2tMcnVDYWNoZS5KT1VSTkFMX0ZJTEU7CitpbXBvcnQgc3RhdGljIGxpYmNvcmUuaW8uRGlza0xydUNhY2hlLk1BR0lDOworaW1wb3J0IHN0YXRpYyBsaWJjb3JlLmlvLkRpc2tMcnVDYWNoZS5WRVJTSU9OXzE7CitpbXBvcnQgdGVzdHMuaW8uTW9ja09zOworCitwdWJsaWMgZmluYWwgY2xhc3MgRGlza0xydUNhY2hlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwcml2YXRlIGZpbmFsIGludCBhcHBWZXJzaW9uID0gMTAwOworICAgIHByaXZhdGUgU3RyaW5nIGphdmFUbXBEaXI7CisgICAgcHJpdmF0ZSBGaWxlIGNhY2hlRGlyOworICAgIHByaXZhdGUgRmlsZSBqb3VybmFsRmlsZTsKKyAgICBwcml2YXRlIERpc2tMcnVDYWNoZSBjYWNoZTsKKyAgICBwcml2YXRlIGZpbmFsIE1vY2tPcyBtb2NrT3MgPSBuZXcgTW9ja09zKCk7CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgamF2YVRtcERpciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKTsKKyAgICAgICAgY2FjaGVEaXIgPSBuZXcgRmlsZShqYXZhVG1wRGlyLCAiRGlza0xydUNhY2hlVGVzdCIpOworICAgICAgICBjYWNoZURpci5ta2RpcigpOworICAgICAgICBqb3VybmFsRmlsZSA9IG5ldyBGaWxlKGNhY2hlRGlyLCBKT1VSTkFMX0ZJTEUpOworICAgICAgICBmb3IgKEZpbGUgZmlsZSA6IGNhY2hlRGlyLmxpc3RGaWxlcygpKSB7CisgICAgICAgICAgICBmaWxlLmRlbGV0ZSgpOworICAgICAgICB9CisgICAgICAgIGNhY2hlID0gRGlza0xydUNhY2hlLm9wZW4oY2FjaGVEaXIsIGFwcFZlcnNpb24sIDIsIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgbW9ja09zLmluc3RhbGwoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbW9ja09zLnVuaW5zdGFsbCgpOworICAgICAgICBjYWNoZS5jbG9zZSgpOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eUNhY2hlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNhY2hlLmNsb3NlKCk7CisgICAgICAgIGFzc2VydEpvdXJuYWxFcXVhbHMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGVBbmRSZWFkRW50cnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRGlza0xydUNhY2hlLkVkaXRvciBjcmVhdG9yID0gY2FjaGUuZWRpdCgiazEiKTsKKyAgICAgICAgY3JlYXRvci5zZXQoMCwgIkFCQyIpOworICAgICAgICBjcmVhdG9yLnNldCgxLCAiREUiKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjcmVhdG9yLmdldFN0cmluZygwKSk7CisgICAgICAgIGFzc2VydE51bGwoY3JlYXRvci5uZXdJbnB1dFN0cmVhbSgwKSk7CisgICAgICAgIGFzc2VydE51bGwoY3JlYXRvci5nZXRTdHJpbmcoMSkpOworICAgICAgICBhc3NlcnROdWxsKGNyZWF0b3IubmV3SW5wdXRTdHJlYW0oMSkpOworICAgICAgICBjcmVhdG9yLmNvbW1pdCgpOworCisgICAgICAgIERpc2tMcnVDYWNoZS5TbmFwc2hvdCBzbmFwc2hvdCA9IGNhY2hlLmdldCgiazEiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkMiLCBzbmFwc2hvdC5nZXRTdHJpbmcoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkRFIiwgc25hcHNob3QuZ2V0U3RyaW5nKDEpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZEFuZFdyaXRlRW50cnlBY3Jvc3NDYWNoZU9wZW5BbmRDbG9zZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEaXNrTHJ1Q2FjaGUuRWRpdG9yIGNyZWF0b3IgPSBjYWNoZS5lZGl0KCJrMSIpOworICAgICAgICBjcmVhdG9yLnNldCgwLCAiQSIpOworICAgICAgICBjcmVhdG9yLnNldCgxLCAiQiIpOworICAgICAgICBjcmVhdG9yLmNvbW1pdCgpOworICAgICAgICBjYWNoZS5jbG9zZSgpOworCisgICAgICAgIGNhY2hlID0gRGlza0xydUNhY2hlLm9wZW4oY2FjaGVEaXIsIGFwcFZlcnNpb24sIDIsIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgRGlza0xydUNhY2hlLlNuYXBzaG90IHNuYXBzaG90ID0gY2FjaGUuZ2V0KCJrMSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCBzbmFwc2hvdC5nZXRTdHJpbmcoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkIiLCBzbmFwc2hvdC5nZXRTdHJpbmcoMSkpOworICAgICAgICBzbmFwc2hvdC5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RKb3VybmFsV2l0aEVkaXRBbmRQdWJsaXNoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIERpc2tMcnVDYWNoZS5FZGl0b3IgY3JlYXRvciA9IGNhY2hlLmVkaXQoImsxIik7CisgICAgICAgIGFzc2VydEpvdXJuYWxFcXVhbHMoIkRJUlRZIGsxIik7IC8vIERJUlRZIG11c3QgYWx3YXlzIGJlIGZsdXNoZWQKKyAgICAgICAgY3JlYXRvci5zZXQoMCwgIkFCIik7CisgICAgICAgIGNyZWF0b3Iuc2V0KDEsICJDIik7CisgICAgICAgIGNyZWF0b3IuY29tbWl0KCk7CisgICAgICAgIGNhY2hlLmNsb3NlKCk7CisgICAgICAgIGFzc2VydEpvdXJuYWxFcXVhbHMoIkRJUlRZIGsxIiwgIkNMRUFOIGsxIDIgMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXZlcnRlZE5ld0ZpbGVJc1JlbW92ZUluSm91cm5hbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEaXNrTHJ1Q2FjaGUuRWRpdG9yIGNyZWF0b3IgPSBjYWNoZS5lZGl0KCJrMSIpOworICAgICAgICBhc3NlcnRKb3VybmFsRXF1YWxzKCJESVJUWSBrMSIpOyAvLyBESVJUWSBtdXN0IGFsd2F5cyBiZSBmbHVzaGVkCisgICAgICAgIGNyZWF0b3Iuc2V0KDAsICJBQiIpOworICAgICAgICBjcmVhdG9yLnNldCgxLCAiQyIpOworICAgICAgICBjcmVhdG9yLmFib3J0KCk7CisgICAgICAgIGNhY2hlLmNsb3NlKCk7CisgICAgICAgIGFzc2VydEpvdXJuYWxFcXVhbHMoIkRJUlRZIGsxIiwgIlJFTU9WRSBrMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVbnRlcm1pbmF0ZWRFZGl0SXNSZXZlcnRlZE9uQ2xvc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2FjaGUuZWRpdCgiazEiKTsKKyAgICAgICAgY2FjaGUuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0Sm91cm5hbEVxdWFscygiRElSVFkgazEiLCAiUkVNT1ZFIGsxIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEpvdXJuYWxEb2VzTm90SW5jbHVkZVJlYWRPZllldFVucHVibGlzaGVkVmFsdWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRGlza0xydUNhY2hlLkVkaXRvciBjcmVhdG9yID0gY2FjaGUuZWRpdCgiazEiKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjYWNoZS5nZXQoImsxIikpOworICAgICAgICBjcmVhdG9yLnNldCgwLCAiQSIpOworICAgICAgICBjcmVhdG9yLnNldCgxLCAiQkMiKTsKKyAgICAgICAgY3JlYXRvci5jb21taXQoKTsKKyAgICAgICAgY2FjaGUuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0Sm91cm5hbEVxdWFscygiRElSVFkgazEiLCAiQ0xFQU4gazEgMSAyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEpvdXJuYWxXaXRoRWRpdEFuZFB1Ymxpc2hBbmRSZWFkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIERpc2tMcnVDYWNoZS5FZGl0b3IgazFDcmVhdG9yID0gY2FjaGUuZWRpdCgiazEiKTsKKyAgICAgICAgazFDcmVhdG9yLnNldCgwLCAiQUIiKTsKKyAgICAgICAgazFDcmVhdG9yLnNldCgxLCAiQyIpOworICAgICAgICBrMUNyZWF0b3IuY29tbWl0KCk7CisgICAgICAgIERpc2tMcnVDYWNoZS5FZGl0b3IgazJDcmVhdG9yID0gY2FjaGUuZWRpdCgiazIiKTsKKyAgICAgICAgazJDcmVhdG9yLnNldCgwLCAiREVGIik7CisgICAgICAgIGsyQ3JlYXRvci5zZXQoMSwgIkciKTsKKyAgICAgICAgazJDcmVhdG9yLmNvbW1pdCgpOworICAgICAgICBEaXNrTHJ1Q2FjaGUuU25hcHNob3QgazFTbmFwc2hvdCA9IGNhY2hlLmdldCgiazEiKTsKKyAgICAgICAgazFTbmFwc2hvdC5jbG9zZSgpOworICAgICAgICBjYWNoZS5jbG9zZSgpOworICAgICAgICBhc3NlcnRKb3VybmFsRXF1YWxzKCJESVJUWSBrMSIsICJDTEVBTiBrMSAyIDEiLAorICAgICAgICAgICAgICAgICJESVJUWSBrMiIsICJDTEVBTiBrMiAzIDEiLAorICAgICAgICAgICAgICAgICJSRUFEIGsxIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENhbm5vdE9wZXJhdGVPbkVkaXRBZnRlclB1Ymxpc2goKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRGlza0xydUNhY2hlLkVkaXRvciBlZGl0b3IgPSBjYWNoZS5lZGl0KCJrMSIpOworICAgICAgICBlZGl0b3Iuc2V0KDAsICJBIik7CisgICAgICAgIGVkaXRvci5zZXQoMSwgIkIiKTsKKyAgICAgICAgZWRpdG9yLmNvbW1pdCgpOworICAgICAgICBhc3NlcnRJbm9wZXJhYmxlKGVkaXRvcik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENhbm5vdE9wZXJhdGVPbkVkaXRBZnRlclJldmVydCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEaXNrTHJ1Q2FjaGUuRWRpdG9yIGVkaXRvciA9IGNhY2hlLmVkaXQoImsxIik7CisgICAgICAgIGVkaXRvci5zZXQoMCwgIkEiKTsKKyAgICAgICAgZWRpdG9yLnNldCgxLCAiQiIpOworICAgICAgICBlZGl0b3IuYWJvcnQoKTsKKyAgICAgICAgYXNzZXJ0SW5vcGVyYWJsZShlZGl0b3IpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFeHBsaWNpdFJlbW92ZUFwcGxpZWRUb0Rpc2tJbW1lZGlhdGVseSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEaXNrTHJ1Q2FjaGUuRWRpdG9yIGVkaXRvciA9IGNhY2hlLmVkaXQoImsxIik7CisgICAgICAgIGVkaXRvci5zZXQoMCwgIkFCQyIpOworICAgICAgICBlZGl0b3Iuc2V0KDEsICJCIik7CisgICAgICAgIGVkaXRvci5jb21taXQoKTsKKyAgICAgICAgRmlsZSBrMSA9IGdldENsZWFuRmlsZSgiazEiLCAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkMiLCByZWFkRmlsZShrMSkpOworICAgICAgICBjYWNoZS5yZW1vdmUoImsxIik7CisgICAgICAgIGFzc2VydEZhbHNlKGsxLmV4aXN0cygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFYWNoIHJlYWQgc2VlcyBhIHNuYXBzaG90IG9mIHRoZSBmaWxlIGF0IHRoZSB0aW1lIHJlYWQgd2FzIGNhbGxlZC4KKyAgICAgKiBUaGlzIG1lYW5zIHRoYXQgdHdvIHJlYWRzIG9mIHRoZSBzYW1lIGtleSBjYW4gc2VlIGRpZmZlcmVudCBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkQW5kV3JpdGVPdmVybGFwc01haW50YWluQ29uc2lzdGVuY3koKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRGlza0xydUNhY2hlLkVkaXRvciB2MUNyZWF0b3IgPSBjYWNoZS5lZGl0KCJrMSIpOworICAgICAgICB2MUNyZWF0b3Iuc2V0KDAsICJBQWFhIik7CisgICAgICAgIHYxQ3JlYXRvci5zZXQoMSwgIkJCYmIiKTsKKyAgICAgICAgdjFDcmVhdG9yLmNvbW1pdCgpOworCisgICAgICAgIERpc2tMcnVDYWNoZS5TbmFwc2hvdCBzbmFwc2hvdDEgPSBjYWNoZS5nZXQoImsxIik7CisgICAgICAgIElucHV0U3RyZWFtIGluVjEgPSBzbmFwc2hvdDEuZ2V0SW5wdXRTdHJlYW0oMCk7CisgICAgICAgIGFzc2VydEVxdWFscygnQScsIGluVjEucmVhZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdBJywgaW5WMS5yZWFkKCkpOworCisgICAgICAgIERpc2tMcnVDYWNoZS5FZGl0b3IgdjFVcGRhdGVyID0gY2FjaGUuZWRpdCgiazEiKTsKKyAgICAgICAgdjFVcGRhdGVyLnNldCgwLCAiQ0NjYyIpOworICAgICAgICB2MVVwZGF0ZXIuc2V0KDEsICJERGRkIik7CisgICAgICAgIHYxVXBkYXRlci5jb21taXQoKTsKKworICAgICAgICBEaXNrTHJ1Q2FjaGUuU25hcHNob3Qgc25hcHNob3QyID0gY2FjaGUuZ2V0KCJrMSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkNDY2MiLCBzbmFwc2hvdDIuZ2V0U3RyaW5nKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJERGRkIiwgc25hcHNob3QyLmdldFN0cmluZygxKSk7CisgICAgICAgIHNuYXBzaG90Mi5jbG9zZSgpOworCisgICAgICAgIGFzc2VydEVxdWFscygnYScsIGluVjEucmVhZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdhJywgaW5WMS5yZWFkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkJCYmIiLCBzbmFwc2hvdDEuZ2V0U3RyaW5nKDEpKTsKKyAgICAgICAgc25hcHNob3QxLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE9wZW5XaXRoRGlydHlLZXlEZWxldGVzQWxsRmlsZXNGb3JUaGF0S2V5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNhY2hlLmNsb3NlKCk7CisgICAgICAgIEZpbGUgY2xlYW5GaWxlMCA9IGdldENsZWFuRmlsZSgiazEiLCAwKTsKKyAgICAgICAgRmlsZSBjbGVhbkZpbGUxID0gZ2V0Q2xlYW5GaWxlKCJrMSIsIDEpOworICAgICAgICBGaWxlIGRpcnR5RmlsZTAgPSBnZXREaXJ0eUZpbGUoImsxIiwgMCk7CisgICAgICAgIEZpbGUgZGlydHlGaWxlMSA9IGdldERpcnR5RmlsZSgiazEiLCAxKTsKKyAgICAgICAgd3JpdGVGaWxlKGNsZWFuRmlsZTAsICJBIik7CisgICAgICAgIHdyaXRlRmlsZShjbGVhbkZpbGUxLCAiQiIpOworICAgICAgICB3cml0ZUZpbGUoZGlydHlGaWxlMCwgIkMiKTsKKyAgICAgICAgd3JpdGVGaWxlKGRpcnR5RmlsZTEsICJEIik7CisgICAgICAgIGNyZWF0ZUpvdXJuYWwoIkNMRUFOIGsxIDEgMSIsICJESVJUWSAgIGsxIik7CisgICAgICAgIGNhY2hlID0gRGlza0xydUNhY2hlLm9wZW4oY2FjaGVEaXIsIGFwcFZlcnNpb24sIDIsIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoY2xlYW5GaWxlMC5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGNsZWFuRmlsZTEuZXhpc3RzKCkpOworICAgICAgICBhc3NlcnRGYWxzZShkaXJ0eUZpbGUwLmV4aXN0cygpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZGlydHlGaWxlMS5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydE51bGwoY2FjaGUuZ2V0KCJrMSIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T3BlbldpdGhJbnZhbGlkVmVyc2lvbkNsZWFyc0RpcmVjdG9yeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjYWNoZS5jbG9zZSgpOworICAgICAgICBnZW5lcmF0ZVNvbWVHYXJiYWdlRmlsZXMoKTsKKyAgICAgICAgY3JlYXRlSm91cm5hbFdpdGhIZWFkZXIoTUFHSUMsICIwIiwgIjEwMCIsICIyIiwgIiIpOworICAgICAgICBjYWNoZSA9IERpc2tMcnVDYWNoZS5vcGVuKGNhY2hlRGlyLCBhcHBWZXJzaW9uLCAyLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIGFzc2VydEdhcmJhZ2VGaWxlc0FsbERlbGV0ZWQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T3BlbldpdGhJbnZhbGlkQXBwVmVyc2lvbkNsZWFyc0RpcmVjdG9yeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjYWNoZS5jbG9zZSgpOworICAgICAgICBnZW5lcmF0ZVNvbWVHYXJiYWdlRmlsZXMoKTsKKyAgICAgICAgY3JlYXRlSm91cm5hbFdpdGhIZWFkZXIoTUFHSUMsICIxIiwgIjEwMSIsICIyIiwgIiIpOworICAgICAgICBjYWNoZSA9IERpc2tMcnVDYWNoZS5vcGVuKGNhY2hlRGlyLCBhcHBWZXJzaW9uLCAyLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIGFzc2VydEdhcmJhZ2VGaWxlc0FsbERlbGV0ZWQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T3BlbldpdGhJbnZhbGlkVmFsdWVDb3VudENsZWFyc0RpcmVjdG9yeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjYWNoZS5jbG9zZSgpOworICAgICAgICBnZW5lcmF0ZVNvbWVHYXJiYWdlRmlsZXMoKTsKKyAgICAgICAgY3JlYXRlSm91cm5hbFdpdGhIZWFkZXIoTUFHSUMsICIxIiwgIjEwMCIsICIxIiwgIiIpOworICAgICAgICBjYWNoZSA9IERpc2tMcnVDYWNoZS5vcGVuKGNhY2hlRGlyLCBhcHBWZXJzaW9uLCAyLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIGFzc2VydEdhcmJhZ2VGaWxlc0FsbERlbGV0ZWQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T3BlbldpdGhJbnZhbGlkQmxhbmtMaW5lQ2xlYXJzRGlyZWN0b3J5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNhY2hlLmNsb3NlKCk7CisgICAgICAgIGdlbmVyYXRlU29tZUdhcmJhZ2VGaWxlcygpOworICAgICAgICBjcmVhdGVKb3VybmFsV2l0aEhlYWRlcihNQUdJQywgIjEiLCAiMTAwIiwgIjIiLCAieCIpOworICAgICAgICBjYWNoZSA9IERpc2tMcnVDYWNoZS5vcGVuKGNhY2hlRGlyLCBhcHBWZXJzaW9uLCAyLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIGFzc2VydEdhcmJhZ2VGaWxlc0FsbERlbGV0ZWQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T3BlbldpdGhJbnZhbGlkSm91cm5hbExpbmVDbGVhcnNEaXJlY3RvcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2FjaGUuY2xvc2UoKTsKKyAgICAgICAgZ2VuZXJhdGVTb21lR2FyYmFnZUZpbGVzKCk7CisgICAgICAgIGNyZWF0ZUpvdXJuYWwoIkNMRUFOIGsxIDEgMSIsICJCT0dVUyIpOworICAgICAgICBjYWNoZSA9IERpc2tMcnVDYWNoZS5vcGVuKGNhY2hlRGlyLCBhcHBWZXJzaW9uLCAyLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIGFzc2VydEdhcmJhZ2VGaWxlc0FsbERlbGV0ZWQoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjYWNoZS5nZXQoImsxIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RPcGVuV2l0aEludmFsaWRGaWxlU2l6ZUNsZWFyc0RpcmVjdG9yeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjYWNoZS5jbG9zZSgpOworICAgICAgICBnZW5lcmF0ZVNvbWVHYXJiYWdlRmlsZXMoKTsKKyAgICAgICAgY3JlYXRlSm91cm5hbCgiQ0xFQU4gazEgMDAwMHgwMDEgMSIpOworICAgICAgICBjYWNoZSA9IERpc2tMcnVDYWNoZS5vcGVuKGNhY2hlRGlyLCBhcHBWZXJzaW9uLCAyLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIGFzc2VydEdhcmJhZ2VGaWxlc0FsbERlbGV0ZWQoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjYWNoZS5nZXQoImsxIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RPcGVuV2l0aFRydW5jYXRlZExpbmVEaXNjYXJkc1RoYXRMaW5lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNhY2hlLmNsb3NlKCk7CisgICAgICAgIHdyaXRlRmlsZShnZXRDbGVhbkZpbGUoImsxIiwgMCksICJBIik7CisgICAgICAgIHdyaXRlRmlsZShnZXRDbGVhbkZpbGUoImsxIiwgMSksICJCIik7CisgICAgICAgIFdyaXRlciB3cml0ZXIgPSBuZXcgRmlsZVdyaXRlcihqb3VybmFsRmlsZSk7CisgICAgICAgIHdyaXRlci53cml0ZShNQUdJQyArICJcbiIgKyBWRVJTSU9OXzEgKyAiXG4xMDBcbjJcblxuQ0xFQU4gazEgMSAxIik7IC8vIG5vIHRyYWlsaW5nIG5ld2xpbmUKKyAgICAgICAgd3JpdGVyLmNsb3NlKCk7CisgICAgICAgIGNhY2hlID0gRGlza0xydUNhY2hlLm9wZW4oY2FjaGVEaXIsIGFwcFZlcnNpb24sIDIsIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjYWNoZS5nZXQoImsxIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RPcGVuV2l0aFRvb01hbnlGaWxlU2l6ZXNDbGVhcnNEaXJlY3RvcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2FjaGUuY2xvc2UoKTsKKyAgICAgICAgZ2VuZXJhdGVTb21lR2FyYmFnZUZpbGVzKCk7CisgICAgICAgIGNyZWF0ZUpvdXJuYWwoIkNMRUFOIGsxIDEgMSAxIik7CisgICAgICAgIGNhY2hlID0gRGlza0xydUNhY2hlLm9wZW4oY2FjaGVEaXIsIGFwcFZlcnNpb24sIDIsIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0R2FyYmFnZUZpbGVzQWxsRGVsZXRlZCgpOworICAgICAgICBhc3NlcnROdWxsKGNhY2hlLmdldCgiazEiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEtleVdpdGhTcGFjZU5vdFBlcm1pdHRlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2FjaGUuZWRpdCgibXkga2V5Iik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEtleVdpdGhOZXdsaW5lTm90UGVybWl0dGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjYWNoZS5lZGl0KCJteVxua2V5Iik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEtleVdpdGhDYXJyaWFnZVJldHVybk5vdFBlcm1pdHRlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2FjaGUuZWRpdCgibXlccmtleSIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROdWxsS2V5VGhyb3dzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjYWNoZS5lZGl0KG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZU5ld0VudHJ5V2l0aFRvb0Zld1ZhbHVlc0ZhaWxzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIERpc2tMcnVDYWNoZS5FZGl0b3IgY3JlYXRvciA9IGNhY2hlLmVkaXQoImsxIik7CisgICAgICAgIGNyZWF0b3Iuc2V0KDEsICJBIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjcmVhdG9yLmNvbW1pdCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEZhbHNlKGdldENsZWFuRmlsZSgiazEiLCAwKS5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGdldENsZWFuRmlsZSgiazEiLCAxKS5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGdldERpcnR5RmlsZSgiazEiLCAwKS5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGdldERpcnR5RmlsZSgiazEiLCAxKS5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydE51bGwoY2FjaGUuZ2V0KCJrMSIpKTsKKworICAgICAgICBEaXNrTHJ1Q2FjaGUuRWRpdG9yIGNyZWF0b3IyID0gY2FjaGUuZWRpdCgiazEiKTsKKyAgICAgICAgY3JlYXRvcjIuc2V0KDAsICJCIik7CisgICAgICAgIGNyZWF0b3IyLnNldCgxLCAiQyIpOworICAgICAgICBjcmVhdG9yMi5jb21taXQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmV2ZXJ0V2l0aFRvb0Zld1ZhbHVlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEaXNrTHJ1Q2FjaGUuRWRpdG9yIGNyZWF0b3IgPSBjYWNoZS5lZGl0KCJrMSIpOworICAgICAgICBjcmVhdG9yLnNldCgxLCAiQSIpOworICAgICAgICBjcmVhdG9yLmFib3J0KCk7CisgICAgICAgIGFzc2VydEZhbHNlKGdldENsZWFuRmlsZSgiazEiLCAwKS5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGdldENsZWFuRmlsZSgiazEiLCAxKS5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGdldERpcnR5RmlsZSgiazEiLCAwKS5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGdldERpcnR5RmlsZSgiazEiLCAxKS5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydE51bGwoY2FjaGUuZ2V0KCJrMSIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXBkYXRlRXhpc3RpbmdFbnRyeVdpdGhUb29GZXdWYWx1ZXNSZXVzZXNQcmV2aW91c1ZhbHVlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEaXNrTHJ1Q2FjaGUuRWRpdG9yIGNyZWF0b3IgPSBjYWNoZS5lZGl0KCJrMSIpOworICAgICAgICBjcmVhdG9yLnNldCgwLCAiQSIpOworICAgICAgICBjcmVhdG9yLnNldCgxLCAiQiIpOworICAgICAgICBjcmVhdG9yLmNvbW1pdCgpOworCisgICAgICAgIERpc2tMcnVDYWNoZS5FZGl0b3IgdXBkYXRlciA9IGNhY2hlLmVkaXQoImsxIik7CisgICAgICAgIHVwZGF0ZXIuc2V0KDAsICJDIik7CisgICAgICAgIHVwZGF0ZXIuY29tbWl0KCk7CisKKyAgICAgICAgRGlza0xydUNhY2hlLlNuYXBzaG90IHNuYXBzaG90ID0gY2FjaGUuZ2V0KCJrMSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkMiLCBzbmFwc2hvdC5nZXRTdHJpbmcoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkIiLCBzbmFwc2hvdC5nZXRTdHJpbmcoMSkpOworICAgICAgICBzbmFwc2hvdC5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFdmljdE9uSW5zZXJ0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNhY2hlLmNsb3NlKCk7CisgICAgICAgIGNhY2hlID0gRGlza0xydUNhY2hlLm9wZW4oY2FjaGVEaXIsIGFwcFZlcnNpb24sIDIsIDEwKTsKKworICAgICAgICBzZXQoIkEiLCAiYSIsICJhYWEiKTsgLy8gc2l6ZSA0CisgICAgICAgIHNldCgiQiIsICJiYiIsICJiYmJiIik7IC8vIHNpemUgNgorICAgICAgICBhc3NlcnRFcXVhbHMoMTAsIGNhY2hlLnNpemUoKSk7CisKKyAgICAgICAgLy8gY2F1c2UgdGhlIHNpemUgdG8gZ3JvdyB0byAxMiBzaG91bGQgZXZpY3QgJ0EnCisgICAgICAgIHNldCgiQyIsICJjIiwgImMiKTsKKyAgICAgICAgY2FjaGUuZmx1c2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDgsIGNhY2hlLnNpemUoKSk7CisgICAgICAgIGFzc2VydEFic2VudCgiQSIpOworICAgICAgICBhc3NlcnRWYWx1ZSgiQiIsICJiYiIsICJiYmJiIik7CisgICAgICAgIGFzc2VydFZhbHVlKCJDIiwgImMiLCAiYyIpOworCisgICAgICAgIC8vIGNhdXNpbmcgdGhlIHNpemUgdG8gZ3JvdyB0byAxMCBzaG91bGQgZXZpY3Qgbm90aGluZworICAgICAgICBzZXQoIkQiLCAiZCIsICJkIik7CisgICAgICAgIGNhY2hlLmZsdXNoKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxMCwgY2FjaGUuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0QWJzZW50KCJBIik7CisgICAgICAgIGFzc2VydFZhbHVlKCJCIiwgImJiIiwgImJiYmIiKTsKKyAgICAgICAgYXNzZXJ0VmFsdWUoIkMiLCAiYyIsICJjIik7CisgICAgICAgIGFzc2VydFZhbHVlKCJEIiwgImQiLCAiZCIpOworCisgICAgICAgIC8vIGNhdXNpbmcgdGhlIHNpemUgdG8gZ3JvdyB0byAxOCBzaG91bGQgZXZpY3QgJ0InIGFuZCAnQycKKyAgICAgICAgc2V0KCJFIiwgImVlZWUiLCAiZWVlZSIpOworICAgICAgICBjYWNoZS5mbHVzaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTAsIGNhY2hlLnNpemUoKSk7CisgICAgICAgIGFzc2VydEFic2VudCgiQSIpOworICAgICAgICBhc3NlcnRBYnNlbnQoIkIiKTsKKyAgICAgICAgYXNzZXJ0QWJzZW50KCJDIik7CisgICAgICAgIGFzc2VydFZhbHVlKCJEIiwgImQiLCAiZCIpOworICAgICAgICBhc3NlcnRWYWx1ZSgiRSIsICJlZWVlIiwgImVlZWUiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXZpY3RPblVwZGF0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjYWNoZS5jbG9zZSgpOworICAgICAgICBjYWNoZSA9IERpc2tMcnVDYWNoZS5vcGVuKGNhY2hlRGlyLCBhcHBWZXJzaW9uLCAyLCAxMCk7CisKKyAgICAgICAgc2V0KCJBIiwgImEiLCAiYWEiKTsgLy8gc2l6ZSAzCisgICAgICAgIHNldCgiQiIsICJiIiwgImJiIik7IC8vIHNpemUgMworICAgICAgICBzZXQoIkMiLCAiYyIsICJjYyIpOyAvLyBzaXplIDMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDksIGNhY2hlLnNpemUoKSk7CisKKyAgICAgICAgLy8gY2F1c2luZyB0aGUgc2l6ZSB0byBncm93IHRvIDExIHNob3VsZCBldmljdCAnQScKKyAgICAgICAgc2V0KCJCIiwgImIiLCAiYmJiYiIpOworICAgICAgICBjYWNoZS5mbHVzaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoOCwgY2FjaGUuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0QWJzZW50KCJBIik7CisgICAgICAgIGFzc2VydFZhbHVlKCJCIiwgImIiLCAiYmJiYiIpOworICAgICAgICBhc3NlcnRWYWx1ZSgiQyIsICJjIiwgImNjIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEV2aWN0aW9uSG9ub3JzTHJ1RnJvbUN1cnJlbnRTZXNzaW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNhY2hlLmNsb3NlKCk7CisgICAgICAgIGNhY2hlID0gRGlza0xydUNhY2hlLm9wZW4oY2FjaGVEaXIsIGFwcFZlcnNpb24sIDIsIDEwKTsKKyAgICAgICAgc2V0KCJBIiwgImEiLCAiYSIpOworICAgICAgICBzZXQoIkIiLCAiYiIsICJiIik7CisgICAgICAgIHNldCgiQyIsICJjIiwgImMiKTsKKyAgICAgICAgc2V0KCJEIiwgImQiLCAiZCIpOworICAgICAgICBzZXQoIkUiLCAiZSIsICJlIik7CisgICAgICAgIGNhY2hlLmdldCgiQiIpLmNsb3NlKCk7IC8vICdCJyBpcyBub3cgbGVhc3QgcmVjZW50bHkgdXNlZAorCisgICAgICAgIC8vIGNhdXNpbmcgdGhlIHNpemUgdG8gZ3JvdyB0byAxMiBzaG91bGQgZXZpY3QgJ0EnCisgICAgICAgIHNldCgiRiIsICJmIiwgImYiKTsKKyAgICAgICAgLy8gY2F1c2luZyB0aGUgc2l6ZSB0byBncm93IHRvIDEyIHNob3VsZCBldmljdCAnQycKKyAgICAgICAgc2V0KCJHIiwgImciLCAiZyIpOworICAgICAgICBjYWNoZS5mbHVzaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTAsIGNhY2hlLnNpemUoKSk7CisgICAgICAgIGFzc2VydEFic2VudCgiQSIpOworICAgICAgICBhc3NlcnRWYWx1ZSgiQiIsICJiIiwgImIiKTsKKyAgICAgICAgYXNzZXJ0QWJzZW50KCJDIik7CisgICAgICAgIGFzc2VydFZhbHVlKCJEIiwgImQiLCAiZCIpOworICAgICAgICBhc3NlcnRWYWx1ZSgiRSIsICJlIiwgImUiKTsKKyAgICAgICAgYXNzZXJ0VmFsdWUoIkYiLCAiZiIsICJmIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEV2aWN0aW9uSG9ub3JzTHJ1RnJvbVByZXZpb3VzU2Vzc2lvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXQoIkEiLCAiYSIsICJhIik7CisgICAgICAgIHNldCgiQiIsICJiIiwgImIiKTsKKyAgICAgICAgc2V0KCJDIiwgImMiLCAiYyIpOworICAgICAgICBzZXQoIkQiLCAiZCIsICJkIik7CisgICAgICAgIHNldCgiRSIsICJlIiwgImUiKTsKKyAgICAgICAgc2V0KCJGIiwgImYiLCAiZiIpOworICAgICAgICBjYWNoZS5nZXQoIkIiKS5jbG9zZSgpOyAvLyAnQicgaXMgbm93IGxlYXN0IHJlY2VudGx5IHVzZWQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEyLCBjYWNoZS5zaXplKCkpOworICAgICAgICBjYWNoZS5jbG9zZSgpOworICAgICAgICBjYWNoZSA9IERpc2tMcnVDYWNoZS5vcGVuKGNhY2hlRGlyLCBhcHBWZXJzaW9uLCAyLCAxMCk7CisKKyAgICAgICAgc2V0KCJHIiwgImciLCAiZyIpOworICAgICAgICBjYWNoZS5mbHVzaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTAsIGNhY2hlLnNpemUoKSk7CisgICAgICAgIGFzc2VydEFic2VudCgiQSIpOworICAgICAgICBhc3NlcnRWYWx1ZSgiQiIsICJiIiwgImIiKTsKKyAgICAgICAgYXNzZXJ0QWJzZW50KCJDIik7CisgICAgICAgIGFzc2VydFZhbHVlKCJEIiwgImQiLCAiZCIpOworICAgICAgICBhc3NlcnRWYWx1ZSgiRSIsICJlIiwgImUiKTsKKyAgICAgICAgYXNzZXJ0VmFsdWUoIkYiLCAiZiIsICJmIik7CisgICAgICAgIGFzc2VydFZhbHVlKCJHIiwgImciLCAiZyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDYWNoZVNpbmdsZUVudHJ5T2ZTaXplR3JlYXRlclRoYW5NYXhTaXplKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNhY2hlLmNsb3NlKCk7CisgICAgICAgIGNhY2hlID0gRGlza0xydUNhY2hlLm9wZW4oY2FjaGVEaXIsIGFwcFZlcnNpb24sIDIsIDEwKTsKKyAgICAgICAgc2V0KCJBIiwgImFhYWFhIiwgImFhYWFhYSIpOyAvLyBzaXplPTExCisgICAgICAgIGNhY2hlLmZsdXNoKCk7CisgICAgICAgIGFzc2VydEFic2VudCgiQSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDYWNoZVNpbmdsZVZhbHVlT2ZTaXplR3JlYXRlclRoYW5NYXhTaXplKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNhY2hlLmNsb3NlKCk7CisgICAgICAgIGNhY2hlID0gRGlza0xydUNhY2hlLm9wZW4oY2FjaGVEaXIsIGFwcFZlcnNpb24sIDIsIDEwKTsKKyAgICAgICAgc2V0KCJBIiwgImFhYWFhYWFhYWFhIiwgImEiKTsgLy8gc2l6ZT0xMgorICAgICAgICBjYWNoZS5mbHVzaCgpOworICAgICAgICBhc3NlcnRBYnNlbnQoIkEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RydWN0b3JEb2VzTm90QWxsb3daZXJvQ2FjaGVTaXplKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEaXNrTHJ1Q2FjaGUub3BlbihjYWNoZURpciwgYXBwVmVyc2lvbiwgMiwgMCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdG9yRG9lc05vdEFsbG93WmVyb1ZhbHVlc1BlckVudHJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEaXNrTHJ1Q2FjaGUub3BlbihjYWNoZURpciwgYXBwVmVyc2lvbiwgMCwgMTApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVBYnNlbnRFbGVtZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNhY2hlLnJlbW92ZSgiQSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkaW5nVGhlU2FtZVN0cmVhbU11bHRpcGxlVGltZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2V0KCJBIiwgImEiLCAiYiIpOworICAgICAgICBEaXNrTHJ1Q2FjaGUuU25hcHNob3Qgc25hcHNob3QgPSBjYWNoZS5nZXQoIkEiKTsKKyAgICAgICAgYXNzZXJ0U2FtZShzbmFwc2hvdC5nZXRJbnB1dFN0cmVhbSgwKSwgc25hcHNob3QuZ2V0SW5wdXRTdHJlYW0oMCkpOworICAgICAgICBzbmFwc2hvdC5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWJ1aWxkSm91cm5hbE9uUmVwZWF0ZWRSZWFkcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXQoIkEiLCAiYSIsICJhIik7CisgICAgICAgIHNldCgiQiIsICJiIiwgImIiKTsKKyAgICAgICAgbG9uZyBsYXN0Sm91cm5hbExlbmd0aCA9IDA7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBsb25nIGpvdXJuYWxMZW5ndGggPSBqb3VybmFsRmlsZS5sZW5ndGgoKTsKKyAgICAgICAgICAgIGFzc2VydFZhbHVlKCJBIiwgImEiLCAiYSIpOworICAgICAgICAgICAgYXNzZXJ0VmFsdWUoIkIiLCAiYiIsICJiIik7CisgICAgICAgICAgICBpZiAoam91cm5hbExlbmd0aCA8IGxhc3RKb3VybmFsTGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGYoIkpvdXJuYWwgY29tcGFjdGVkIGZyb20gJXMgYnl0ZXMgdG8gJXMgYnl0ZXNcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICBsYXN0Sm91cm5hbExlbmd0aCwgam91cm5hbExlbmd0aCk7CisgICAgICAgICAgICAgICAgYnJlYWs7IC8vIHRlc3QgcGFzc2VkIQorICAgICAgICAgICAgfQorICAgICAgICAgICAgbGFzdEpvdXJuYWxMZW5ndGggPSBqb3VybmFsTGVuZ3RoOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlYnVpbGRKb3VybmFsT25SZXBlYXRlZEVkaXRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgbGFzdEpvdXJuYWxMZW5ndGggPSAwOworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgbG9uZyBqb3VybmFsTGVuZ3RoID0gam91cm5hbEZpbGUubGVuZ3RoKCk7CisgICAgICAgICAgICBzZXQoIkEiLCAiYSIsICJhIik7CisgICAgICAgICAgICBzZXQoIkIiLCAiYiIsICJiIik7CisgICAgICAgICAgICBpZiAoam91cm5hbExlbmd0aCA8IGxhc3RKb3VybmFsTGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGYoIkpvdXJuYWwgY29tcGFjdGVkIGZyb20gJXMgYnl0ZXMgdG8gJXMgYnl0ZXNcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICBsYXN0Sm91cm5hbExlbmd0aCwgam91cm5hbExlbmd0aCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsYXN0Sm91cm5hbExlbmd0aCA9IGpvdXJuYWxMZW5ndGg7CisgICAgICAgIH0KKworICAgICAgICAvLyBzYW5pdHkgY2hlY2sgdGhhdCBhIHJlYnVpbHQgam91cm5hbCBiZWhhdmVzIG5vcm1hbGx5CisgICAgICAgIGFzc2VydFZhbHVlKCJBIiwgImEiLCAiYSIpOworICAgICAgICBhc3NlcnRWYWx1ZSgiQiIsICJiIiwgImIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T3BlbkNyZWF0ZXNEaXJlY3RvcnlJZk5lY2Vzc2FyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjYWNoZS5jbG9zZSgpOworICAgICAgICBGaWxlIGRpciA9IG5ldyBGaWxlKGphdmFUbXBEaXIsICJ0ZXN0T3BlbkNyZWF0ZXNEaXJlY3RvcnlJZk5lY2Vzc2FyeSIpOworICAgICAgICBjYWNoZSA9IERpc2tMcnVDYWNoZS5vcGVuKGRpciwgYXBwVmVyc2lvbiwgMiwgSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICBzZXQoIkEiLCAiYSIsICJhIik7CisgICAgICAgIGFzc2VydFRydWUobmV3IEZpbGUoZGlyLCAiQS4wIikuZXhpc3RzKCkpOworICAgICAgICBhc3NlcnRUcnVlKG5ldyBGaWxlKGRpciwgIkEuMSIpLmV4aXN0cygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuZXcgRmlsZShkaXIsICJqb3VybmFsIikuZXhpc3RzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGaWxlRGVsZXRlZEV4dGVybmFsbHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2V0KCJBIiwgImEiLCAiYSIpOworICAgICAgICBnZXRDbGVhbkZpbGUoIkEiLCAxKS5kZWxldGUoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjYWNoZS5nZXQoIkEiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZpbGVCZWNvbWVzSW5hY2Nlc3NpYmxlRHVyaW5nUmVhZFJlc3VsdHNJbklvRXhjZXB0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNldCgiQSIsICJhYWFhYSIsICJhIik7CisgICAgICAgIERpc2tMcnVDYWNoZS5TbmFwc2hvdCBzbmFwc2hvdCA9IGNhY2hlLmdldCgiQSIpOworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IHNuYXBzaG90LmdldElucHV0U3RyZWFtKDApOworICAgICAgICBhc3NlcnRFcXVhbHMoJ2EnLCBpbi5yZWFkKCkpOworICAgICAgICBtb2NrT3MuZW5xdWV1ZUZhdWx0KCJyZWFkIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbi5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgc25hcHNob3QuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmlsZUJlY29tZXNJbmFjY2Vzc2libGVEdXJpbmdXcml0ZUlzU2lsZW50bHlEaXNjYXJkZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2V0KCJBIiwgImEiLCAiYSIpOworICAgICAgICBEaXNrTHJ1Q2FjaGUuRWRpdG9yIGVkaXRvciA9IGNhY2hlLmVkaXQoIkEiKTsKKyAgICAgICAgT3V0cHV0U3RyZWFtIG91dDAgPSBlZGl0b3IubmV3T3V0cHV0U3RyZWFtKDApOworICAgICAgICBvdXQwLndyaXRlKCdiJyk7CisgICAgICAgIG91dDAuY2xvc2UoKTsKKyAgICAgICAgT3V0cHV0U3RyZWFtIG91dDEgPSBlZGl0b3IubmV3T3V0cHV0U3RyZWFtKDEpOworICAgICAgICBvdXQxLndyaXRlKCdjJyk7CisgICAgICAgIG1vY2tPcy5lbnF1ZXVlRmF1bHQoIndyaXRlIik7CisgICAgICAgIG91dDEud3JpdGUoJ2MnKTsgLy8gdGhpcyBkb2Vzbid0IHRocm93Li4uCisgICAgICAgIG91dDEuY2xvc2UoKTsKKyAgICAgICAgZWRpdG9yLmNvbW1pdCgpOyAvLyAuLi4gYnV0IHRoaXMgd2lsbCBhYm9ydAorICAgICAgICBhc3NlcnRBYnNlbnQoIkEiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0Sm91cm5hbEVxdWFscyhTdHJpbmcuLi4gZXhwZWN0ZWRCb2R5TGluZXMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBMaXN0PFN0cmluZz4gZXhwZWN0ZWRMaW5lcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBleHBlY3RlZExpbmVzLmFkZChNQUdJQyk7CisgICAgICAgIGV4cGVjdGVkTGluZXMuYWRkKFZFUlNJT05fMSk7CisgICAgICAgIGV4cGVjdGVkTGluZXMuYWRkKCIxMDAiKTsKKyAgICAgICAgZXhwZWN0ZWRMaW5lcy5hZGQoIjIiKTsKKyAgICAgICAgZXhwZWN0ZWRMaW5lcy5hZGQoIiIpOworICAgICAgICBleHBlY3RlZExpbmVzLmFkZEFsbChBcnJheXMuYXNMaXN0KGV4cGVjdGVkQm9keUxpbmVzKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZExpbmVzLCByZWFkSm91cm5hbExpbmVzKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjcmVhdGVKb3VybmFsKFN0cmluZy4uLiBib2R5TGluZXMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjcmVhdGVKb3VybmFsV2l0aEhlYWRlcihNQUdJQywgVkVSU0lPTl8xLCAiMTAwIiwgIjIiLCAiIiwgYm9keUxpbmVzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY3JlYXRlSm91cm5hbFdpdGhIZWFkZXIoU3RyaW5nIG1hZ2ljLCBTdHJpbmcgdmVyc2lvbiwgU3RyaW5nIGFwcFZlcnNpb24sCisgICAgICAgICAgICBTdHJpbmcgdmFsdWVDb3VudCwgU3RyaW5nIGJsYW5rLCBTdHJpbmcuLi4gYm9keUxpbmVzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgV3JpdGVyIHdyaXRlciA9IG5ldyBGaWxlV3JpdGVyKGpvdXJuYWxGaWxlKTsKKyAgICAgICAgd3JpdGVyLndyaXRlKG1hZ2ljICsgIlxuIik7CisgICAgICAgIHdyaXRlci53cml0ZSh2ZXJzaW9uICsgIlxuIik7CisgICAgICAgIHdyaXRlci53cml0ZShhcHBWZXJzaW9uICsgIlxuIik7CisgICAgICAgIHdyaXRlci53cml0ZSh2YWx1ZUNvdW50ICsgIlxuIik7CisgICAgICAgIHdyaXRlci53cml0ZShibGFuayArICJcbiIpOworICAgICAgICBmb3IgKFN0cmluZyBsaW5lIDogYm9keUxpbmVzKSB7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUobGluZSk7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoJ1xuJyk7CisgICAgICAgIH0KKyAgICAgICAgd3JpdGVyLmNsb3NlKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBMaXN0PFN0cmluZz4gcmVhZEpvdXJuYWxMaW5lcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBMaXN0PFN0cmluZz4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIEJ1ZmZlcmVkUmVhZGVyIHJlYWRlciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgRmlsZVJlYWRlcihqb3VybmFsRmlsZSkpOworICAgICAgICBTdHJpbmcgbGluZTsKKyAgICAgICAgd2hpbGUgKChsaW5lID0gcmVhZGVyLnJlYWRMaW5lKCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hZGQobGluZSk7CisgICAgICAgIH0KKyAgICAgICAgcmVhZGVyLmNsb3NlKCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBGaWxlIGdldENsZWFuRmlsZShTdHJpbmcga2V5LCBpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBGaWxlKGNhY2hlRGlyLCBrZXkgKyAiLiIgKyBpbmRleCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBGaWxlIGdldERpcnR5RmlsZShTdHJpbmcga2V5LCBpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBGaWxlKGNhY2hlRGlyLCBrZXkgKyAiLiIgKyBpbmRleCArICIudG1wIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgcmVhZEZpbGUoRmlsZSBmaWxlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUmVhZGVyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKGZpbGUpOworICAgICAgICBTdHJpbmdXcml0ZXIgd3JpdGVyID0gbmV3IFN0cmluZ1dyaXRlcigpOworICAgICAgICBjaGFyW10gYnVmZmVyID0gbmV3IGNoYXJbMTAyNF07CisgICAgICAgIGludCBjb3VudDsKKyAgICAgICAgd2hpbGUgKChjb3VudCA9IHJlYWRlci5yZWFkKGJ1ZmZlcikpICE9IC0xKSB7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoYnVmZmVyLCAwLCBjb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgcmVhZGVyLmNsb3NlKCk7CisgICAgICAgIHJldHVybiB3cml0ZXIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZUZpbGUoRmlsZSBmaWxlLCBTdHJpbmcgY29udGVudCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGVXcml0ZXIgd3JpdGVyID0gbmV3IEZpbGVXcml0ZXIoZmlsZSk7CisgICAgICAgIHdyaXRlci53cml0ZShjb250ZW50KTsKKyAgICAgICAgd3JpdGVyLmNsb3NlKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydElub3BlcmFibGUoRGlza0xydUNhY2hlLkVkaXRvciBlZGl0b3IpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgZWRpdG9yLmdldFN0cmluZygwKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVkaXRvci5zZXQoMCwgIkEiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVkaXRvci5uZXdJbnB1dFN0cmVhbSgwKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVkaXRvci5uZXdPdXRwdXRTdHJlYW0oMCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlZGl0b3IuY29tbWl0KCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlZGl0b3IuYWJvcnQoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZ2VuZXJhdGVTb21lR2FyYmFnZUZpbGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgZGlyMSA9IG5ldyBGaWxlKGNhY2hlRGlyLCAiZGlyMSIpOworICAgICAgICBGaWxlIGRpcjIgPSBuZXcgRmlsZShkaXIxLCAiZGlyMiIpOworICAgICAgICB3cml0ZUZpbGUoZ2V0Q2xlYW5GaWxlKCJnMSIsIDApLCAiQSIpOworICAgICAgICB3cml0ZUZpbGUoZ2V0Q2xlYW5GaWxlKCJnMSIsIDEpLCAiQiIpOworICAgICAgICB3cml0ZUZpbGUoZ2V0Q2xlYW5GaWxlKCJnMiIsIDApLCAiQyIpOworICAgICAgICB3cml0ZUZpbGUoZ2V0Q2xlYW5GaWxlKCJnMiIsIDEpLCAiRCIpOworICAgICAgICB3cml0ZUZpbGUoZ2V0Q2xlYW5GaWxlKCJnMiIsIDEpLCAiRCIpOworICAgICAgICB3cml0ZUZpbGUobmV3IEZpbGUoY2FjaGVEaXIsICJvdGhlckZpbGUwIiksICJFIik7CisgICAgICAgIGRpcjEubWtkaXIoKTsKKyAgICAgICAgZGlyMi5ta2RpcigpOworICAgICAgICB3cml0ZUZpbGUobmV3IEZpbGUoZGlyMiwgIm90aGVyRmlsZTEiKSwgIkYiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0R2FyYmFnZUZpbGVzQWxsRGVsZXRlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShnZXRDbGVhbkZpbGUoImcxIiwgMCkuZXhpc3RzKCkpOworICAgICAgICBhc3NlcnRGYWxzZShnZXRDbGVhbkZpbGUoImcxIiwgMSkuZXhpc3RzKCkpOworICAgICAgICBhc3NlcnRGYWxzZShnZXRDbGVhbkZpbGUoImcyIiwgMCkuZXhpc3RzKCkpOworICAgICAgICBhc3NlcnRGYWxzZShnZXRDbGVhbkZpbGUoImcyIiwgMSkuZXhpc3RzKCkpOworICAgICAgICBhc3NlcnRGYWxzZShuZXcgRmlsZShjYWNoZURpciwgIm90aGVyRmlsZTAiKS5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG5ldyBGaWxlKGNhY2hlRGlyLCAiZGlyMSIpLmV4aXN0cygpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc2V0KFN0cmluZyBrZXksIFN0cmluZyB2YWx1ZTAsIFN0cmluZyB2YWx1ZTEpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEaXNrTHJ1Q2FjaGUuRWRpdG9yIGVkaXRvciA9IGNhY2hlLmVkaXQoa2V5KTsKKyAgICAgICAgZWRpdG9yLnNldCgwLCB2YWx1ZTApOworICAgICAgICBlZGl0b3Iuc2V0KDEsIHZhbHVlMSk7CisgICAgICAgIGVkaXRvci5jb21taXQoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0QWJzZW50KFN0cmluZyBrZXkpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEaXNrTHJ1Q2FjaGUuU25hcHNob3Qgc25hcHNob3QgPSBjYWNoZS5nZXQoa2V5KTsKKyAgICAgICAgaWYgKHNuYXBzaG90ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNuYXBzaG90LmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoZ2V0Q2xlYW5GaWxlKGtleSwgMCkuZXhpc3RzKCkpOworICAgICAgICBhc3NlcnRGYWxzZShnZXRDbGVhbkZpbGUoa2V5LCAxKS5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGdldERpcnR5RmlsZShrZXksIDApLmV4aXN0cygpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZ2V0RGlydHlGaWxlKGtleSwgMSkuZXhpc3RzKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRWYWx1ZShTdHJpbmcga2V5LCBTdHJpbmcgdmFsdWUwLCBTdHJpbmcgdmFsdWUxKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRGlza0xydUNhY2hlLlNuYXBzaG90IHNuYXBzaG90ID0gY2FjaGUuZ2V0KGtleSk7CisgICAgICAgIGFzc2VydEVxdWFscyh2YWx1ZTAsIHNuYXBzaG90LmdldFN0cmluZygwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh2YWx1ZTEsIHNuYXBzaG90LmdldFN0cmluZygxKSk7CisgICAgICAgIGFzc2VydFRydWUoZ2V0Q2xlYW5GaWxlKGtleSwgMCkuZXhpc3RzKCkpOworICAgICAgICBhc3NlcnRUcnVlKGdldENsZWFuRmlsZShrZXksIDEpLmV4aXN0cygpKTsKKyAgICAgICAgc25hcHNob3QuY2xvc2UoKTsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvaW8vTWVtb3J5VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvaW8vTWVtb3J5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1MzNmMTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9pby9NZW1vcnlUZXN0LmphdmEKQEAgLTAsMCArMSw5MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pbzsKKworaW1wb3J0IGRhbHZpay5zeXN0ZW0uVk1SdW50aW1lOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE1lbW9yeVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdFNldEludEFycmF5KCkgeworICAgICAgICBpbnRbXSB2YWx1ZXMgPSB7IDMsIDcsIDMxLCAxMjcsIDgxOTEsIDEzMTA3MSwgNTI0Mjg3LCAyMTQ3NDgzNjQ3IH07CisgICAgICAgIGludFtdIHN3YXBwZWRWYWx1ZXMgPSBuZXcgaW50W3ZhbHVlcy5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgc3dhcHBlZFZhbHVlc1tpXSA9IEludGVnZXIucmV2ZXJzZUJ5dGVzKHZhbHVlc1tpXSk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgc2NhbGUgPSA0OworICAgICAgICBWTVJ1bnRpbWUgcnVudGltZSA9IFZNUnVudGltZS5nZXRSdW50aW1lKCk7CisgICAgICAgIGJ5dGVbXSBhcnJheSA9IChieXRlW10pIHJ1bnRpbWUubmV3Tm9uTW92YWJsZUFycmF5KGJ5dGUuY2xhc3MsIHNjYWxlICogdmFsdWVzLmxlbmd0aCk7CisgICAgICAgIGludCBwdHIgPSAoaW50KSBydW50aW1lLmFkZHJlc3NPZihhcnJheSk7CisKKyAgICAgICAgLy8gUmVndWxhciBjb3B5LgorICAgICAgICBNZW1vcnkucG9rZUludEFycmF5KHB0ciwgdmFsdWVzLCAwLCB2YWx1ZXMubGVuZ3RoLCBmYWxzZSk7CisgICAgICAgIGFzc2VydEludHNFcXVhbCh2YWx1ZXMsIHB0ciwgZmFsc2UpOworICAgICAgICBhc3NlcnRJbnRzRXF1YWwoc3dhcHBlZFZhbHVlcywgcHRyLCB0cnVlKTsKKworICAgICAgICAvLyBTd2FwcGVkIGNvcHkuCisgICAgICAgIE1lbW9yeS5wb2tlSW50QXJyYXkocHRyLCB2YWx1ZXMsIDAsIHZhbHVlcy5sZW5ndGgsIHRydWUpOworICAgICAgICBhc3NlcnRJbnRzRXF1YWwodmFsdWVzLCBwdHIsIHRydWUpOworICAgICAgICBhc3NlcnRJbnRzRXF1YWwoc3dhcHBlZFZhbHVlcywgcHRyLCBmYWxzZSk7CisKKyAgICAgICAgLy8gU3dhcHBlZCBjb3BpZXMgb2Ygc2xpY2VzICh0byBlbnN1cmUgd2UgdGVzdCBub24temVybyBvZmZzZXRzKS4KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIE1lbW9yeS5wb2tlSW50QXJyYXkocHRyICsgaSAqIHNjYWxlLCB2YWx1ZXMsIGksIDEsIHRydWUpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEludHNFcXVhbCh2YWx1ZXMsIHB0ciwgdHJ1ZSk7CisgICAgICAgIGFzc2VydEludHNFcXVhbChzd2FwcGVkVmFsdWVzLCBwdHIsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0SW50c0VxdWFsKGludFtdIGV4cGVjdGVkVmFsdWVzLCBpbnQgcHRyLCBib29sZWFuIHN3YXApIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHBlY3RlZFZhbHVlcy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkVmFsdWVzW2ldLCBNZW1vcnkucGVla0ludChwdHIgKyA0ICogaSwgc3dhcCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldFNob3J0QXJyYXkoKSB7CisgICAgICAgIHNob3J0W10gdmFsdWVzID0geyAweDAwMDEsIDB4MDAyMCwgMHgwMzAwLCAweDQwMDAgfTsKKyAgICAgICAgc2hvcnRbXSBzd2FwcGVkVmFsdWVzID0geyAweDAxMDAsIDB4MjAwMCwgMHgwMDAzLCAweDAwNDAgfTsKKworICAgICAgICBpbnQgc2NhbGUgPSAyOworICAgICAgICBWTVJ1bnRpbWUgcnVudGltZSA9IFZNUnVudGltZS5nZXRSdW50aW1lKCk7CisgICAgICAgIGJ5dGVbXSBhcnJheSA9IChieXRlW10pIHJ1bnRpbWUubmV3Tm9uTW92YWJsZUFycmF5KGJ5dGUuY2xhc3MsIHNjYWxlICogdmFsdWVzLmxlbmd0aCk7CisgICAgICAgIGludCBwdHIgPSAoaW50KSBydW50aW1lLmFkZHJlc3NPZihhcnJheSk7CisKKyAgICAgICAgLy8gUmVndWxhciBjb3B5LiBNZW1zZXQgZmlyc3Qgc28gd2Ugc3RhcnQgZnJvbSBhIGtub3duIHN0YXRlLgorICAgICAgICBNZW1vcnkucG9rZVNob3J0QXJyYXkocHRyLCB2YWx1ZXMsIDAsIHZhbHVlcy5sZW5ndGgsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0U2hvcnRzRXF1YWwodmFsdWVzLCBwdHIsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0U2hvcnRzRXF1YWwoc3dhcHBlZFZhbHVlcywgcHRyLCB0cnVlKTsKKworICAgICAgICAvLyBTd2FwcGVkIGNvcHkuCisgICAgICAgIE1lbW9yeS5wb2tlU2hvcnRBcnJheShwdHIsIHZhbHVlcywgMCwgdmFsdWVzLmxlbmd0aCwgdHJ1ZSk7CisgICAgICAgIGFzc2VydFNob3J0c0VxdWFsKHZhbHVlcywgcHRyLCB0cnVlKTsKKyAgICAgICAgYXNzZXJ0U2hvcnRzRXF1YWwoc3dhcHBlZFZhbHVlcywgcHRyLCBmYWxzZSk7CisKKyAgICAgICAgLy8gU3dhcHBlZCBjb3BpZXMgb2Ygc2xpY2VzICh0byBlbnN1cmUgd2UgdGVzdCBub24temVybyBvZmZzZXRzKS4KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIE1lbW9yeS5wb2tlU2hvcnRBcnJheShwdHIgKyBpICogc2NhbGUsIHZhbHVlcywgaSwgMSwgdHJ1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0U2hvcnRzRXF1YWwodmFsdWVzLCBwdHIsIHRydWUpOworICAgICAgICBhc3NlcnRTaG9ydHNFcXVhbChzd2FwcGVkVmFsdWVzLCBwdHIsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0U2hvcnRzRXF1YWwoc2hvcnRbXSBleHBlY3RlZFZhbHVlcywgaW50IHB0ciwgYm9vbGVhbiBzd2FwKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZXhwZWN0ZWRWYWx1ZXMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZFZhbHVlc1tpXSwgTWVtb3J5LnBlZWtTaG9ydChwdHIgKyAyICogaSwgc3dhcCkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvaW8vT3NUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9pby9Pc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjQ0NmFlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvaW8vT3NUZXN0LmphdmEKQEAgLTAsMCArMSwzNyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5pbzsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5TZXJ2ZXJTb2NrZXQ7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgc3RhdGljIGxpYmNvcmUuaW8uT3NDb25zdGFudHMuKjsKKworcHVibGljIGNsYXNzIE9zVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNTb2NrZXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoIi9kZXYvbnVsbCIpOworICAgICAgICBGaWxlSW5wdXRTdHJlYW0gZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoU19JU1NPQ0soTGliY29yZS5vcy5mc3RhdChmaXMuZ2V0RkQoKSkuc3RfbW9kZSkpOworICAgICAgICBmaXMuY2xvc2UoKTsKKworICAgICAgICBTZXJ2ZXJTb2NrZXQgcyA9IG5ldyBTZXJ2ZXJTb2NrZXQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShTX0lTU09DSyhMaWJjb3JlLm9zLmZzdGF0KHMuZ2V0SW1wbCQoKS5nZXRGRCQoKSkuc3RfbW9kZSkpOworICAgICAgICBzLmNsb3NlKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9hd3QvZm9udC9UZXh0QXR0cmlidXRlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9hd3QvZm9udC9UZXh0QXR0cmlidXRlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYyZDhkM2UKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2F3dC9mb250L1RleHRBdHRyaWJ1dGVUZXN0LmphdmEKQEAgLTAsMCArMSwzOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmF3dC5mb250OworCitpbXBvcnQgamF2YS5hd3QuZm9udC5UZXh0QXR0cmlidXRlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIFRleHRBdHRyaWJ1dGVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdEF0dHJpYnV0ZU5hbWVzKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoImphdmEuYXd0LmZvbnQuVGV4dEF0dHJpYnV0ZShrZXJuaW5nKSIsCisgICAgICAgICAgICAgICAgVGV4dEF0dHJpYnV0ZS5LRVJOSU5HLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImphdmEuYXd0LmZvbnQuVGV4dEF0dHJpYnV0ZShsaWdhdHVyZXMpIiwKKyAgICAgICAgICAgICAgICBUZXh0QXR0cmlidXRlLkxJR0FUVVJFUy50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJqYXZhLmF3dC5mb250LlRleHRBdHRyaWJ1dGUodHJhY2tpbmcpIiwKKyAgICAgICAgICAgICAgICBUZXh0QXR0cmlidXRlLlRSQUNLSU5HLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdHRyaWJ1dGVWYWx1ZXMoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgSW50ZWdlcigxKSwgVGV4dEF0dHJpYnV0ZS5LRVJOSU5HX09OKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBJbnRlZ2VyKDEpLCBUZXh0QXR0cmlidXRlLkxJR0FUVVJFU19PTik7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgRmxvYXQoMC4wNGYpLCBUZXh0QXR0cmlidXRlLlRSQUNLSU5HX0xPT1NFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBGbG9hdCgtMC4wNGYpLCBUZXh0QXR0cmlidXRlLlRSQUNLSU5HX1RJR0hUKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL0RhdGFPdXRwdXRTdHJlYW1UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL0RhdGFPdXRwdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjY2YTQ0ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vRGF0YU91dHB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDE1MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5EYXRhT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uVVRGRGF0YUZvcm1hdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIERhdGFPdXRwdXRTdHJlYW1UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHByaXZhdGUgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVzID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgIHByaXZhdGUgRGF0YU91dHB1dFN0cmVhbSBvcyA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKGJ5dGVzKTsKKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGVCb29sZWFuKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG9zLndyaXRlQm9vbGVhbih0cnVlKTsKKyAgICAgICAgb3Mud3JpdGVCb29sZWFuKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbMDEsIDAwXSIsIHRvSGV4U3RyaW5nKGJ5dGVzLnRvQnl0ZUFycmF5KCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlQnl0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBvcy53cml0ZUJ5dGUoLTEpOworICAgICAgICBvcy53cml0ZUJ5dGUoMCk7CisgICAgICAgIG9zLndyaXRlQnl0ZSgxKTsKKyAgICAgICAgb3Mud3JpdGVCeXRlKDEyOSk7CisgICAgICAgIC8vIHdyaXRlQnl0ZSB0YWtlcyBvbmx5IHRoZSBib3R0b20gYnl0ZSBmcm9tIGl0cyBpbnQgcGFyYW1ldGVyLgorICAgICAgICBvcy53cml0ZUJ5dGUoMHgxMjM0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbZmYsIDAwLCAwMSwgODEsIDM0XSIsIHRvSGV4U3RyaW5nKGJ5dGVzLnRvQnl0ZUFycmF5KCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlQnl0ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gd3JpdGVCeXRlcyB0YWtlcyBvbmx5IHRoZSBib3R0b20gYnl0ZSBmcm9tIGVhY2ggY2hhcmFjdGVyLgorICAgICAgICBvcy53cml0ZUJ5dGVzKCIwXHUxMjM0MSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlszMCwgMzQsIDMxXSIsIHRvSGV4U3RyaW5nKGJ5dGVzLnRvQnl0ZUFycmF5KCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlQ2hhcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyB3cml0ZUNoYXIgd3JpdGVzIHR3by1ieXRlIGJpZy1lbmRpYW4gY2hhcmFjdGVycy4KKyAgICAgICAgb3Mud3JpdGVDaGFyKCcwJyk7CisgICAgICAgIG9zLndyaXRlQ2hhcigweDEyMzQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlswMCwgMzAsIDEyLCAzNF0iLCB0b0hleFN0cmluZyhieXRlcy50b0J5dGVBcnJheSgpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZUNoYXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIHdyaXRlQ2hhcnMgd3JpdGVzIHR3by1ieXRlIGJpZy1lbmRpYW4gY2hhcmFjdGVycy4KKyAgICAgICAgb3Mud3JpdGVDaGFycygiMFx1MTIzNDEiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbMDAsIDMwLCAxMiwgMzQsIDAwLCAzMV0iLCB0b0hleFN0cmluZyhieXRlcy50b0J5dGVBcnJheSgpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZURvdWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBvcy53cml0ZURvdWJsZShEb3VibGUubG9uZ0JpdHNUb0RvdWJsZSgweDAxMjM0NTY3ODlhYmNkZWZMKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWzAxLCAyMywgNDUsIDY3LCA4OSwgYWIsIGNkLCBlZl0iLCB0b0hleFN0cmluZyhieXRlcy50b0J5dGVBcnJheSgpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZUZsb2F0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG9zLndyaXRlRmxvYXQoRmxvYXQuaW50Qml0c1RvRmxvYXQoMHgwMTIzNDU2NykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlswMSwgMjMsIDQ1LCA2N10iLCB0b0hleFN0cmluZyhieXRlcy50b0J5dGVBcnJheSgpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZUludCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBvcy53cml0ZUludCgweDAxMjM0NTY3KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbMDEsIDIzLCA0NSwgNjddIiwgdG9IZXhTdHJpbmcoYnl0ZXMudG9CeXRlQXJyYXkoKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGVMb25nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG9zLndyaXRlTG9uZygweDAxMjM0NTY3ODlhYmNkZWZMKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbMDEsIDIzLCA0NSwgNjcsIDg5LCBhYiwgY2QsIGVmXSIsIHRvSGV4U3RyaW5nKGJ5dGVzLnRvQnl0ZUFycmF5KCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlU2hvcnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gd3JpdGVTaG9ydCBvbmx5IHdyaXRlcyB0aGUgYm90dG9tbW9zdCAxNiBiaXRzIG9mIGl0cyBpbnQgcGFyYW1ldGVyLgorICAgICAgICBvcy53cml0ZVNob3J0KDB4MDEyMzQ1NjcpOworICAgICAgICBhc3NlcnRFcXVhbHMoIls0NSwgNjddIiwgdG9IZXhTdHJpbmcoYnl0ZXMudG9CeXRlQXJyYXkoKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGVVVEYoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGhlIGxpbWl0IGlzIDY1NTM1ICpieXRlcyogYnV0IHdlIHdhbnQgdG8gdGVzdCAyLSBhbmQgMy1ieXRlIGNoYXJhY3RlcnMgdG9vLgorICAgICAgICBjaGFyW10gY2hhcnMgPSBuZXcgY2hhcls2NTUzNSAtIDEgLSAyXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoY2hhcnMsIDAsIGNoYXJzLmxlbmd0aCwgJ2EnKTsKKyAgICAgICAgY2hhcnNbMF0gPSAnXHUwNjY2JzsgLy8gYSB0d28tYnl0ZSBjaGFyYWN0ZXIKKyAgICAgICAgY2hhcnNbMV0gPSAnXHUyNjAzJzsgLy8gYSB0aHJlZS1ieXRlIGNoYXJhY3RlcgorICAgICAgICBTdHJpbmcgbWF4TGVuZ3RoID0gbmV3IFN0cmluZyhjaGFycyk7CisgICAgICAgIG9zLndyaXRlVVRGKG1heExlbmd0aCk7CisgICAgICAgIGJ5dGVbXSBleHBlY3RlZCA9IG5ldyBieXRlWzIgKyA2NTUzNV07CisgICAgICAgIGV4cGVjdGVkWzBdID0gKGJ5dGUpIDB4ZmY7CisgICAgICAgIGV4cGVjdGVkWzFdID0gKGJ5dGUpIDB4ZmY7CisgICAgICAgIC8vIFUrMDY2NiA9IDB4RDkgMHhBNgorICAgICAgICBleHBlY3RlZFsyXSA9IChieXRlKSAweGQ5OworICAgICAgICBleHBlY3RlZFszXSA9IChieXRlKSAweGE2OworICAgICAgICAvLyBVKzI2MDMgPSAweEUyIDB4OTggMHg4MworICAgICAgICBleHBlY3RlZFs0XSA9IChieXRlKSAweGUyOworICAgICAgICBleHBlY3RlZFs1XSA9IChieXRlKSAweDk4OworICAgICAgICBleHBlY3RlZFs2XSA9IChieXRlKSAweDgzOworICAgICAgICBBcnJheXMuZmlsbChleHBlY3RlZCwgNywgZXhwZWN0ZWQubGVuZ3RoLCAoYnl0ZSkgJ2EnKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy50b1N0cmluZyhleHBlY3RlZCksIEFycmF5cy50b1N0cmluZyhieXRlcy50b0J5dGVBcnJheSgpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZVVURl9OVUwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGhpcyBpcyBhIHNwZWNpYWwgY2FzZSwgcmVwcmVzZW50ZWQgd2l0aCB0d28gbm9uLXplcm8gYnl0ZXMuCisgICAgICAgIG9zLndyaXRlVVRGKCJcdTAwMDAiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbMDAsIDAyLCBjMCwgODBdIiwgdG9IZXhTdHJpbmcoYnl0ZXMudG9CeXRlQXJyYXkoKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGVVVEZfdG9vX2xvbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHRvb0xvbmcgPSBuZXcgU3RyaW5nKG5ldyBjaGFyWzY1NTM2XSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcy53cml0ZVVURih0b29Mb25nKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBVVEZEYXRhRm9ybWF0RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFVURkRhdGFGb3JtYXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIltdIiwgdG9IZXhTdHJpbmcoYnl0ZXMudG9CeXRlQXJyYXkoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBieXRlIGFycmF5IHRoYXQncyBtb3JlIHVzZWZ1bCBmb3IgZGVidWdnaW5nLgorICAgICAqIFRPRE86IG1vdmUgdGhpcyBzb21ld2hlcmUgd2hlcmUgaXQncyBhdmFpbGFibGUgdG8gYWxsIHRlc3RzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvSGV4U3RyaW5nKGJ5dGVbXSBhcnJheSkgeworICAgICAgICBpZiAoYXJyYXkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGFycmF5Lmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gIltdIjsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgc2IuYXBwZW5kKCdbJyk7CisgICAgICAgIC8vIFRPRE86IGRvbid0IHVzZSBTdHJpbmcuZm9ybWF0IGlmIHdlIHB1dCB0aGlzIGluIHRoZSBsaWJyYXJ5LiBUb28gZXhwZW5zaXZlIQorICAgICAgICBzYi5hcHBlbmQoU3RyaW5nLmZvcm1hdCgiJTAyeCIsIGFycmF5WzBdICYgMHhmZikpOworICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoIiwgIik7CisgICAgICAgICAgICBzYi5hcHBlbmQoU3RyaW5nLmZvcm1hdCgiJTAyeCIsIGFycmF5W2ldICYgMHhmZikpOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZCgnXScpOworICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL0ZpbGVEZXNjcmlwdG9yVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9GaWxlRGVzY3JpcHRvclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MzE1YjgxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9GaWxlRGVzY3JpcHRvclRlc3QuamF2YQpAQCAtMCwwICsxLDMwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGU7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgRmlsZURlc2NyaXB0b3JUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkT25seUZpbGVEZXNjcmlwdG9yU3luYygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGaWxlIGY9IEZpbGUuY3JlYXRlVGVtcEZpbGUoIkZpbGVEZXNjcmlwdG9yVGVzdCIsICJ0bXAiKTsKKyAgICAgICAgbmV3IFJhbmRvbUFjY2Vzc0ZpbGUoZiwgInIiKS5nZXRGRCgpLnN5bmMoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL0ZpbGVJbnB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vRmlsZUlucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE0OTUwZWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL0ZpbGVJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDE5NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgbGliY29yZS5pby5Jb1V0aWxzOworaW1wb3J0IGxpYmNvcmUuaW8uTGliY29yZTsKKworcHVibGljIGZpbmFsIGNsYXNzIEZpbGVJbnB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRPVEFMX1NJWkUgPSAxMDI0OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTS0lQX1NJWkUgPSAxMDA7CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBEYXRhRmVlZGVyIGV4dGVuZHMgVGhyZWFkIHsKKyAgICAgICAgcHJpdmF0ZSBGaWxlRGVzY3JpcHRvciBtT3V0RmQ7CisKKyAgICAgICAgcHVibGljIERhdGFGZWVkZXIoRmlsZURlc2NyaXB0b3IgZmQpIHsKKyAgICAgICAgICAgIG1PdXRGZCA9IGZkOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBmb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShtT3V0RmQpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtUT1RBTF9TSVpFXTsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBidWZmZXIubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlcltpXSA9IChieXRlKSBpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGZvcy53cml0ZShidWZmZXIpOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIElvVXRpbHMuY2xvc2VRdWlldGx5KGZvcyk7CisgICAgICAgICAgICAgICAgICAgIElvVXRpbHMuY2xvc2UobU91dEZkKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdmVyaWZ5RGF0YShGaWxlSW5wdXRTdHJlYW0gaXMsIGludCBzdGFydCwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlIGJ1ZmZlcltdID0gbmV3IGJ5dGVbY291bnRdOworICAgICAgICBhc3NlcnRFcXVhbHMoY291bnQsIGlzLnJlYWQoYnVmZmVyKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7ICsraSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAoaSArIHN0YXJ0KSwgYnVmZmVyW2ldKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTa2lwSW5QaXBlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGaWxlRGVzY3JpcHRvcltdIHBpcGUgPSBMaWJjb3JlLm9zLnBpcGUoKTsKKyAgICAgICAgRGF0YUZlZWRlciBmZWVkZXIgPSBuZXcgRGF0YUZlZWRlcihwaXBlWzFdKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZlZWRlci5zdGFydCgpOworICAgICAgICAgICAgRmlsZUlucHV0U3RyZWFtIGZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0ocGlwZVswXSk7CisgICAgICAgICAgICBmaXMuc2tpcChTS0lQX1NJWkUpOworICAgICAgICAgICAgdmVyaWZ5RGF0YShmaXMsIFNLSVBfU0laRSwgVE9UQUxfU0laRSAtIFNLSVBfU0laRSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGZpcy5yZWFkKCkpOworICAgICAgICAgICAgZmVlZGVyLmpvaW4oMTAwMCk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShmZWVkZXIuaXNBbGl2ZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIElvVXRpbHMuY2xvc2VRdWlldGx5KHBpcGVbMF0pOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERpcmVjdG9yaWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRmlsZUlucHV0U3RyZWFtKCIuIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBGaWxlIG1ha2VGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgdG1wID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiRmlsZU91dHB1dFN0cmVhbVRlc3QiLCAidG1wIik7CisgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gZm9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0odG1wKTsKKyAgICAgICAgZm9zLndyaXRlKDEpOworICAgICAgICBmb3Mud3JpdGUoMSk7CisgICAgICAgIGZvcy5jbG9zZSgpOworICAgICAgICByZXR1cm4gdG1wOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGaWxlRGVzY3JpcHRvck93bmVyc2hpcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGaWxlIHRtcCA9IG1ha2VGaWxlKCk7CisKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGZpczEgPSBuZXcgRmlsZUlucHV0U3RyZWFtKHRtcCk7CisgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBmaXMyID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmaXMxLmdldEZEKCkpOworCisgICAgICAgIC8vIENsb3NlIHRoZSBzZWNvbmQgRmlsZURlc2NyaXB0b3IgYW5kIGNoZWNrIHdlIGNhbid0IHVzZSBpdC4uLgorICAgICAgICBmaXMyLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaXMyLmF2YWlsYWJsZSgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaXMyLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZmlzMi5yZWFkKG5ldyBieXRlWzFdLCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZmlzMi5za2lwKDEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIC8vIC4uLmJ1dCB0aGF0IHdlIGNhbiBzdGlsbCB1c2UgdGhlIGZpcnN0LgorICAgICAgICBhc3NlcnRGYWxzZShmaXMxLnJlYWQoKSA9PSAtMSk7CisKKyAgICAgICAgLy8gQ2xvc2UgdGhlIGZpcnN0IEZpbGVEZXNjcmlwdG9yIGFuZCBjaGVjayB3ZSBjYW4ndCB1c2UgaXQuLi4KKyAgICAgICAgZmlzMS5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmlzMS5hdmFpbGFibGUoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZmlzMS5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpczEucmVhZChuZXcgYnl0ZVsxXSwgMCwgMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpczEuc2tpcCgxKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDbG9zZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGaWxlIHRtcCA9IG1ha2VGaWxlKCk7CisgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBmaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKHRtcCk7CisKKyAgICAgICAgLy8gQ2xvc2luZyBhbiBhbHJlYWR5LWNsb3NlZCBzdHJlYW0gaXMgYSBuby1vcC4uLgorICAgICAgICBmaXMuY2xvc2UoKTsKKyAgICAgICAgZmlzLmNsb3NlKCk7CisKKyAgICAgICAgLy8gQnV0IGFueSBleHBsaWNpdCBhY3Rpdml0eSBpcyBhbiBlcnJvci4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpcy5hdmFpbGFibGUoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZmlzLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZmlzLnJlYWQobmV3IGJ5dGVbMV0sIDAsIDEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaXMuc2tpcCgxKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICAvLyBJbmNsdWRpbmcgMC1ieXRlIHNraXBzLi4uCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaXMuc2tpcCgwKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICAvLyAuLi5idXQgbm90IDAtYnl0ZSByZWFkcy4uLgorICAgICAgICBmaXMucmVhZChuZXcgYnl0ZVswXSwgMCwgMCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9GaWxlT3V0cHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9GaWxlT3V0cHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEyZWYxOWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL0ZpbGVPdXRwdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSw5MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgRmlsZU91dHB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdEZpbGVEZXNjcmlwdG9yT3duZXJzaGlwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgdG1wID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiRmlsZU91dHB1dFN0cmVhbVRlc3QiLCAidG1wIik7CisgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gZm9zMSA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKHRtcCk7CisgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gZm9zMiA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZvczEuZ2V0RkQoKSk7CisKKyAgICAgICAgLy8gQ2xvc2UgdGhlIHNlY29uZCBGaWxlRGVzY3JpcHRvciBhbmQgY2hlY2sgd2UgY2FuJ3QgdXNlIGl0Li4uCisgICAgICAgIGZvczIuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvczIud3JpdGUoMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvczIud3JpdGUobmV3IGJ5dGVbMV0sIDAsIDEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIC8vIC4uLmJ1dCB0aGF0IHdlIGNhbiBzdGlsbCB1c2UgdGhlIGZpcnN0LgorICAgICAgICBmb3MxLndyaXRlKDEpOworCisgICAgICAgIC8vIENsb3NlIHRoZSBmaXJzdCBGaWxlRGVzY3JpcHRvciBhbmQgY2hlY2sgd2UgY2FuJ3QgdXNlIGl0Li4uCisgICAgICAgIGZvczEuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvczEud3JpdGUoMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvczEud3JpdGUobmV3IGJ5dGVbMV0sIDAsIDEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENsb3NlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gZm9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oRmlsZS5jcmVhdGVUZW1wRmlsZSgiRmlsZU91dHB1dFN0cmVhbVRlc3QiLCAidG1wIikpOworCisgICAgICAgIC8vIENsb3NpbmcgYW4gYWxyZWFkeS1jbG9zZWQgc3RyZWFtIGlzIGEgbm8tb3AuLi4KKyAgICAgICAgZm9zLmNsb3NlKCk7CisgICAgICAgIGZvcy5jbG9zZSgpOworICAgICAgICAvLyAuLi5hcyBpcyBmbHVzaGluZy4uLgorICAgICAgICBmb3MuZmx1c2goKTsKKworICAgICAgICAvLyAuLi5idXQgYW55IGV4cGxpY2l0IHdyaXRlIGlzIGFuIGVycm9yLgorICAgICAgICBieXRlW10gYnl0ZXMgPSAiaGVsbG8iLmdldEJ5dGVzKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3Mud3JpdGUoYnl0ZXMpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3Mud3JpdGUoYnl0ZXMsIDAsIDIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3Mud3JpdGUoNDIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gLi4uZXhjZXB0IGEgMC1ieXRlIHdyaXRlLgorICAgICAgICBmb3Mud3JpdGUobmV3IGJ5dGVbMF0sIDAsIDApOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vRmlsZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vRmlsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNTkxMTFkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9GaWxlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjM1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVGaWx0ZXI7CitpbXBvcnQgamF2YS5pby5GaWxlbmFtZUZpbHRlcjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlVVSUQ7CitpbXBvcnQgbGliY29yZS5pby5MaWJjb3JlOworCitwdWJsaWMgY2xhc3MgRmlsZVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIHByaXZhdGUgc3RhdGljIEZpbGUgY3JlYXRlVGVtcG9yYXJ5RGlyZWN0b3J5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBiYXNlID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmlvLnRtcGRpciIpOworICAgICAgICBGaWxlIGRpcmVjdG9yeSA9IG5ldyBGaWxlKGJhc2UsIFVVSUQucmFuZG9tVVVJRCgpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRUcnVlKGRpcmVjdG9yeS5ta2RpcnMoKSk7CisgICAgICAgIHJldHVybiBkaXJlY3Rvcnk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGxvbmdTdHJpbmcoaW50IG4pIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47ICsraSkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgneCcpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBGaWxlIGNyZWF0ZURlZXBTdHJ1Y3R1cmUoRmlsZSBiYXNlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gZXh0IGhhcyBhIGxpbWl0IG9mIGFyb3VuZCAyNTYgY2hhcmFjdGVycyBmb3IgZWFjaCBwYXRoIGVudHJ5LgorICAgICAgICAvLyAxMjggY2hhcmFjdGVycyBzaG91bGQgYmUgc2FmZSBmb3IgZXZlcnl0aGluZyBidXQgRkFULgorICAgICAgICBTdHJpbmcgbG9uZ1N0cmluZyA9IGxvbmdTdHJpbmcoMTI4KTsKKyAgICAgICAgLy8gS2VlcCBjcmVhdGluZyBzdWJkaXJlY3RvcmllcyB1bnRpbCB0aGUgcGF0aCBsZW5ndGggaXMgZ3JlYXRlciB0aGFuIDFLaUIuCisgICAgICAgIC8vIFVidW50dSA4LjA0J3Mga2VybmVsIGlzIGhhcHB5IHVwIHRvIGFib3V0IDRLaUIuCisgICAgICAgIEZpbGUgZiA9IGJhc2U7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBmLnRvU3RyaW5nKCkubGVuZ3RoKCkgPD0gMTAyNDsgKytpKSB7CisgICAgICAgICAgICBmID0gbmV3IEZpbGUoZiwgbG9uZ1N0cmluZyk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGYubWtkaXIoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGY7CisgICAgfQorCisgICAgLy8gUmF0aGVyIHRoYW4gdGVzdCBhbGwgbWV0aG9kcywgYXNzdW1lIHRoYXQgaWYgY3JlYXRlVGVtcEZpbGUgY3JlYXRlcyBhIGxvbmcgcGF0aCBhbmQKKyAgICAvLyBleGlzdHMgY2FuIHNlZSBpdCwgdGhlIGNvZGUgZm9yIGNvcGluZyB3aXRoIGxvbmcgcGF0aHMgKHNoYXJlZCBieSBhbGwgbWV0aG9kcykgd29ya3MuCisgICAgcHVibGljIHZvaWQgdGVzdF9sb25nUGF0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGaWxlIGJhc2UgPSBjcmVhdGVUZW1wb3JhcnlEaXJlY3RvcnkoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjcmVhdGVEZWVwU3RydWN0dXJlKGJhc2UpLmV4aXN0cygpKTsKKyAgICB9CisKKyAgICAvLyByZWFkbGluaygyKSBpcyBhIHNwZWNpYWwgY2FzZSwuCisgICAgcHVibGljIHZvaWQgdGVzdF9sb25nUmVhZGxpbmsoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZSBiYXNlID0gY3JlYXRlVGVtcG9yYXJ5RGlyZWN0b3J5KCk7CisgICAgICAgIEZpbGUgdGFyZ2V0ID0gY3JlYXRlRGVlcFN0cnVjdHVyZShiYXNlKTsKKyAgICAgICAgRmlsZSBzb3VyY2UgPSBuZXcgRmlsZShiYXNlLCAic291cmNlIik7CisgICAgICAgIGFzc2VydEZhbHNlKHNvdXJjZS5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydFRydWUodGFyZ2V0LmV4aXN0cygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0YXJnZXQuZ2V0Q2Fub25pY2FsUGF0aCgpLmxlbmd0aCgpID4gMTAyNCk7CisgICAgICAgIGxuX3ModGFyZ2V0LCBzb3VyY2UpOworICAgICAgICBhc3NlcnRUcnVlKHNvdXJjZS5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0YXJnZXQuZ2V0Q2Fub25pY2FsUGF0aCgpLCBzb3VyY2UuZ2V0Q2Fub25pY2FsUGF0aCgpKTsKKyAgICB9CisKKyAgICAvLyBUT0RPOiBGaWxlLmxpc3QgaXMgYSBzcGVjaWFsIGNhc2UgdG9vLCBidXQgSSBoYXZlbid0IGZpeGVkIGl0IHlldCwgYW5kIHRoZSBuZXcgY29kZSwKKyAgICAvLyBsaWtlIHRoZSBvbGQgY29kZSwgd2lsbCBkaWUgb2YgYSBuYXRpdmUgYnVmZmVyIG92ZXJydW4gaWYgd2UgZXhlcmNpc2UgaXQuCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VtcHR5RmlsZW5hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGhlIGJlaGF2aW9yIG9mIHRoZSBlbXB0eSBmaWxlbmFtZSBpcyBhbiBvZGQgbWl4dHVyZS4KKyAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoIiIpOworICAgICAgICAvLyBNb3N0bHkgaXQgYmVoYXZlcyBsaWtlIGFuIGludmFsaWQgcGF0aC4uLgorICAgICAgICBhc3NlcnRGYWxzZShmLmNhbkV4ZWN1dGUoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGYuY2FuUmVhZCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZi5jYW5Xcml0ZSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYuY3JlYXRlTmV3RmlsZSgpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZShmLmRlbGV0ZSgpKTsKKyAgICAgICAgZi5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZi5leGlzdHMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgZi5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZi5nZXRQYXJlbnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBmLmdldFBhcmVudEZpbGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgZi5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRGYWxzZShmLmlzQWJzb2x1dGUoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGYuaXNEaXJlY3RvcnkoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGYuaXNGaWxlKCkpOworICAgICAgICBhc3NlcnRGYWxzZShmLmlzSGlkZGVuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZi5sYXN0TW9kaWZpZWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBmLmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGYubGlzdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGYubGlzdChudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBmLmxpc3RGaWxlcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGYubGlzdEZpbGVzKChGaWxlRmlsdGVyKSBudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBmLmxpc3RGaWxlcygoRmlsZW5hbWVGaWx0ZXIpIG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZi5ta2RpcigpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZi5ta2RpcnMoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGYucmVuYW1lVG8oZikpOworICAgICAgICBhc3NlcnRGYWxzZShmLnNldExhc3RNb2RpZmllZCgxMjMpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZi5zZXRFeGVjdXRhYmxlKHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZi5zZXRSZWFkT25seSgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZi5zZXRSZWFkYWJsZSh0cnVlKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGYuc2V0V3JpdGFibGUodHJ1ZSkpOworICAgICAgICAvLyAuLi5idXQgc29tZXRpbWVzIGl0IGJlaGF2ZXMgbGlrZSAidXNlci5kaXIiLgorICAgICAgICBTdHJpbmcgY3dkID0gU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLmRpciIpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IEZpbGUoY3dkKSwgZi5nZXRBYnNvbHV0ZUZpbGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjd2QsIGYuZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgICAgICAvLyBUT0RPOiBob3cgZG8gd2UgdGVzdCB0aGVzZSB3aXRob3V0IGhhcmQtY29kaW5nIGFzc3VtcHRpb25zIGFib3V0IHdoZXJlIG91ciB0ZW1wb3JhcnkKKyAgICAgICAgLy8gZGlyZWN0b3J5IGlzPyAoSW4gcHJhY3RpY2UsIG9uIEFuZHJvaWQsIG91ciB0ZW1wb3JhcnkgZGlyZWN0b3J5IGlzIGFjY2Vzc2VkIHRocm91Z2gKKyAgICAgICAgLy8gYSBzeW1ib2xpYyBsaW5rLCBzbyB0aGUgY2Fub25pY2FsIGZpbGUvcGF0aCB3aWxsIGJlIGRpZmZlcmVudC4pCisgICAgICAgIC8vYXNzZXJ0RXF1YWxzKG5ldyBGaWxlKGN3ZCksIGYuZ2V0Q2Fub25pY2FsRmlsZSgpKTsKKyAgICAgICAgLy9hc3NlcnRFcXVhbHMoY3dkLCBmLmdldENhbm9uaWNhbFBhdGgoKSk7CisgICAgfQorCisgICAgLy8gaHR0cDovL2IvMjQ4Njk0MyAtIGJldHdlZW4gZWNsYWlyIGFuZCBmcm95bywgd2UgYWRkZWQgYSBjYWxsIHRvCisgICAgLy8gaXNBYnNvbHV0ZSBmcm9tIHRoZSBGaWxlIGNvbnN0cnVjdG9yLCBwb3RlbnRpYWxseSBicmVha2luZyBzdWJjbGFzc2VzLgorICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3ViY2xhc3NpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2xhc3MgTXlGaWxlIGV4dGVuZHMgRmlsZSB7CisgICAgICAgICAgICBwcml2YXRlIFN0cmluZyBmaWVsZDsKKyAgICAgICAgICAgIE15RmlsZShTdHJpbmcgcykgeworICAgICAgICAgICAgICAgIHN1cGVyKHMpOworICAgICAgICAgICAgICAgIGZpZWxkID0gIiI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaXNBYnNvbHV0ZSgpIHsKKyAgICAgICAgICAgICAgICBmaWVsZC5sZW5ndGgoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuaXNBYnNvbHV0ZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIG5ldyBNeUZpbGUoIiIpOworICAgIH0KKworICAgIC8vIGh0dHA6Ly9iLzMwNDc4OTMgLSBnZXRDYW5vbmljYWxQYXRoIHdhc24ndCBhY3R1YWxseSByZXNvbHZpbmcgc3ltYm9saWMgbGlua3MuCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDYW5vbmljYWxQYXRoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChuZXcgRmlsZSgiL3NkY2FyZCIpLmV4aXN0cygpKSB7CisgICAgICAgICAgICAvLyBUaGlzIGFzc3VtZXMgdGhlIGN1cnJlbnQgQW5kcm9pZCBzZXR1cCB3aGVyZSAvc2RjYXJkIGlzIGEgc3ltYm9saWMgbGluayB0bworICAgICAgICAgICAgLy8gL21udC9zZGNhcmQuCisgICAgICAgICAgICBGaWxlIHRlc3RGaWxlID0gbmV3IEZpbGUoIi9zZGNhcmQvdGVzdDEudHh0Iik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIi9tbnQvc2RjYXJkL3Rlc3QxLnR4dCIsIHRlc3RGaWxlLmdldENhbm9uaWNhbFBhdGgoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBUaGlzIGFzc3VtZXMgeW91IGNhbiBjcmVhdGUgc3ltYm9saWMgbGlua3MgaW4gdGhlIHRlbXBvcmFyeSBkaXJlY3RvcnkuIFRoaXMgaXNuJ3QKKyAgICAgICAgLy8gdHJ1ZSBvbiBBbmRyb2lkIGlmIHlvdSdyZSB1c2luZyAvc2RjYXJkLiBJdCB3aWxsIHdvcmsgaW4gL2RhdGEvbG9jYWwgdGhvdWdoLgorICAgICAgICBGaWxlIGJhc2UgPSBjcmVhdGVUZW1wb3JhcnlEaXJlY3RvcnkoKTsKKyAgICAgICAgRmlsZSB0YXJnZXQgPSBuZXcgRmlsZShiYXNlLCAidGFyZ2V0Iik7CisgICAgICAgIHRhcmdldC5jcmVhdGVOZXdGaWxlKCk7IC8vIFRoZSBSSSB3b24ndCBmb2xsb3cgYSBkYW5nbGluZyBzeW1saW5rLCB3aGljaCBzZWVtcyBsaWtlIGEgYnVnIQorICAgICAgICBGaWxlIGxpbmtOYW1lID0gbmV3IEZpbGUoYmFzZSwgImxpbmsiKTsKKyAgICAgICAgbG5fcyh0YXJnZXQsIGxpbmtOYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRhcmdldC5nZXRDYW5vbmljYWxQYXRoKCksIGxpbmtOYW1lLmdldENhbm9uaWNhbFBhdGgoKSk7CisKKyAgICAgICAgLy8gLi4uL3N1YmRpci9zaG9ydGVyIC0+IC4uLi90YXJnZXQgKHVzaW5nIGEgbGluayB0byAuLi90YXJnZXQpLgorICAgICAgICBGaWxlIHN1YmRpciA9IG5ldyBGaWxlKGJhc2UsICJzdWJkaXIiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzdWJkaXIubWtkaXIoKSk7CisgICAgICAgIGxpbmtOYW1lID0gbmV3IEZpbGUoc3ViZGlyLCAic2hvcnRlciIpOworICAgICAgICBsbl9zKCIuLi90YXJnZXQiLCBsaW5rTmFtZS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRhcmdldC5nZXRDYW5vbmljYWxQYXRoKCksIGxpbmtOYW1lLmdldENhbm9uaWNhbFBhdGgoKSk7CisKKyAgICAgICAgLy8gLi4uL2wgLT4gLi4uL3N1YmRpci9sb25nZXIgKHVzaW5nIGEgcmVsYXRpdmUgbGluayB0byBzdWJkaXIvbG9uZ2VyKS4KKyAgICAgICAgbGlua05hbWUgPSBuZXcgRmlsZShiYXNlLCAibCIpOworICAgICAgICBsbl9zKCJzdWJkaXIvbG9uZ2VyIiwgbGlua05hbWUudG9TdHJpbmcoKSk7CisgICAgICAgIEZpbGUgbG9uZ2VyID0gbmV3IEZpbGUoYmFzZSwgInN1YmRpci9sb25nZXIiKTsKKyAgICAgICAgbG9uZ2VyLmNyZWF0ZU5ld0ZpbGUoKTsgLy8gVGhlIFJJIHdvbid0IGZvbGxvdyBhIGRhbmdsaW5nIHN5bWxpbmssIHdoaWNoIHNlZW1zIGxpa2UgYSBidWchCisgICAgICAgIGFzc2VydEVxdWFscyhsb25nZXIuZ2V0Q2Fub25pY2FsUGF0aCgpLCBsaW5rTmFtZS5nZXRDYW5vbmljYWxQYXRoKCkpOworCisgICAgICAgIC8vIC4uLi9kb3VibGUgLT4gLi4uL3RhcmdldCAodmlhIGEgbGluayBpbnRvIHN1YmRpciBhbmQgYSBsaW5rIGJhY2sgb3V0KS4KKyAgICAgICAgbGlua05hbWUgPSBuZXcgRmlsZShiYXNlLCAiZG91YmxlIik7CisgICAgICAgIGxuX3MoInN1YmRpci9zaG9ydGVyIiwgbGlua05hbWUudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0YXJnZXQuZ2V0Q2Fub25pY2FsUGF0aCgpLCBsaW5rTmFtZS5nZXRDYW5vbmljYWxQYXRoKCkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgbG5fcyhGaWxlIHRhcmdldCwgRmlsZSBsaW5rTmFtZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGxuX3ModGFyZ2V0LnRvU3RyaW5nKCksIGxpbmtOYW1lLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgbG5fcyhTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgbGlua05hbWUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBMaWJjb3JlLm9zLnN5bWxpbmsodGFyZ2V0LCBsaW5rTmFtZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jcmVhdGVOZXdGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgZiA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoIkZpbGVUZXN0IiwgInRtcCIpOworICAgICAgICBhc3NlcnRGYWxzZShmLmNyZWF0ZU5ld0ZpbGUoKSk7IC8vIEVFWElTVCAtPiBmYWxzZQorICAgICAgICBhc3NlcnRGYWxzZShmLmdldFBhcmVudEZpbGUoKS5jcmVhdGVOZXdGaWxlKCkpOyAvLyBFRVhJU1QgLT4gZmFsc2UsIGV2ZW4gaWYgU19JU0RJUgorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEZpbGUoZiwgInBvb3AiKS5jcmVhdGVOZXdGaWxlKCk7IC8vIEVOT1RESVIgLT4gdGhyb3cKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEZpbGUoIiIpLmNyZWF0ZU5ld0ZpbGUoKTsgLy8gRU5PRU5UIC0+IHRocm93CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlbmFtZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGaWxlIGYgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJGaWxlVGVzdCIsICJ0bXAiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZi5yZW5hbWVUbyhuZXcgRmlsZSgiIikpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobmV3IEZpbGUoIiIpLnJlbmFtZVRvKGYpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZi5yZW5hbWVUbyhuZXcgRmlsZSgiLiIpKSk7CisgICAgICAgIGFzc2VydFRydWUoZi5yZW5hbWVUbyhmKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBYnNvbHV0ZVBhdGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIG9yaWdpbmFsVXNlckRpciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgidXNlci5kaXIiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEZpbGUgZiA9IG5ldyBGaWxlKCJwb29wIik7CisgICAgICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoInVzZXIuZGlyIiwgIi9hIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIi9hL3Bvb3AiLCBmLmdldEFic29sdXRlUGF0aCgpKTsKKyAgICAgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgidXNlci5kaXIiLCAiL2IiKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiL2IvcG9vcCIsIGYuZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJ1c2VyLmRpciIsIG9yaWdpbmFsVXNlckRpcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFNwYWNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUobmV3IEZpbGUoIi8iKS5nZXRGcmVlU3BhY2UoKSA+PSAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuZXcgRmlsZSgiLyIpLmdldFRvdGFsU3BhY2UoKSA+PSAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuZXcgRmlsZSgiLyIpLmdldFVzYWJsZVNwYWNlKCkgPj0gMCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9GaWx0ZXJJbnB1dFN0cmVhbU51bGxTb3VyY2VUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL0ZpbHRlcklucHV0U3RyZWFtTnVsbFNvdXJjZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNWRkNDRmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9GaWx0ZXJJbnB1dFN0cmVhbU51bGxTb3VyY2VUZXN0LmphdmEKQEAgLTAsMCArMSwxNDAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkxpbmVOdW1iZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlB1c2hiYWNrSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5EaWdlc3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLnppcC5DUkMzMjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkNoZWNrZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkluZmxhdGVyOworaW1wb3J0IGphdmEudXRpbC56aXAuSW5mbGF0ZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uQ2lwaGVySW5wdXRTdHJlYW07CitpbXBvcnQgamF2YXguY3J5cHRvLk51bGxDaXBoZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgRmlsdGVySW5wdXRTdHJlYW1OdWxsU291cmNlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RCdWZmZXJlZElucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UmVhZHNGYWlsV2l0aElvRXhjZXB0aW9uKG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0UmVhZHNGYWlsV2l0aElvRXhjZXB0aW9uKG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKG51bGwsIDEwMjQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2hlY2tlZElucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UmVhZHNGYWlsV2l0aE51bGxQb2ludGVyRXhjZXB0aW9uKG5ldyBDaGVja2VkSW5wdXRTdHJlYW0obnVsbCwgbmV3IENSQzMyKCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2lwaGVySW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG5ldyBDaXBoZXJJbnB1dFN0cmVhbShudWxsLCBuZXcgTnVsbENpcGhlcigpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygwLCBpbi5hdmFpbGFibGUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGF0YUlucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UmVhZHNGYWlsV2l0aE51bGxQb2ludGVyRXhjZXB0aW9uKG5ldyBEYXRhSW5wdXRTdHJlYW0obnVsbCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REaWdlc3RJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgTWVzc2FnZURpZ2VzdCBtZDUgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJNRDUiKTsKKyAgICAgICAgYXNzZXJ0UmVhZHNGYWlsV2l0aE51bGxQb2ludGVyRXhjZXB0aW9uKG5ldyBEaWdlc3RJbnB1dFN0cmVhbShudWxsLCBtZDUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmlsdGVySW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBhc3NlcnRSZWFkc0ZhaWxXaXRoTnVsbFBvaW50ZXJFeGNlcHRpb24obmV3IEZpbHRlcklucHV0U3RyZWFtKG51bGwpIHt9KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5mbGF0ZXJJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSW5mbGF0ZXJJbnB1dFN0cmVhbShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEluZmxhdGVySW5wdXRTdHJlYW0obnVsbCwgbmV3IEluZmxhdGVyKCkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSW5mbGF0ZXJJbnB1dFN0cmVhbShudWxsLCBuZXcgSW5mbGF0ZXIoKSwgMTAyNCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TGluZU51bWJlcklucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UmVhZHNGYWlsV2l0aE51bGxQb2ludGVyRXhjZXB0aW9uKG5ldyBMaW5lTnVtYmVySW5wdXRTdHJlYW0obnVsbCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQdXNoYmFja0lucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UmVhZHNGYWlsV2l0aElvRXhjZXB0aW9uKG5ldyBQdXNoYmFja0lucHV0U3RyZWFtKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0UmVhZHNGYWlsV2l0aElvRXhjZXB0aW9uKG5ldyBQdXNoYmFja0lucHV0U3RyZWFtKG51bGwsIDEwMjQpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0UmVhZHNGYWlsV2l0aElvRXhjZXB0aW9uKElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4ucmVhZCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluLmF2YWlsYWJsZSgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgaW4uY2xvc2UoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0UmVhZHNGYWlsV2l0aE51bGxQb2ludGVyRXhjZXB0aW9uKElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4ucmVhZCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluLmF2YWlsYWJsZSgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL0lucHV0U3RyZWFtUmVhZGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9JbnB1dFN0cmVhbVJlYWRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNTY4NTliCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9JbnB1dFN0cmVhbVJlYWRlclRlc3QuamF2YQpAQCAtMCwwICsxLDQxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7CitpbXBvcnQgamF2YS5pby5QaXBlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUGlwZWRPdXRwdXRTdHJlYW07CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgSW5wdXRTdHJlYW1SZWFkZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogVGhpcyBidWcgY2xhaW1zIHRoYXQgSW5wdXRTdHJlYW1SZWFkZXIgYmxvY2tzIHVubmVjZXNzYXJpbHk6CisgICAgICogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD0xMDI1MgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkRG9lc05vdEJsb2NrVW5uZWNlc3NhcmlseSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFBpcGVkSW5wdXRTdHJlYW0gcGluID0gbmV3IFBpcGVkSW5wdXRTdHJlYW0oKTsKKyAgICAgICAgUGlwZWRPdXRwdXRTdHJlYW0gcG9zID0gbmV3IFBpcGVkT3V0cHV0U3RyZWFtKHBpbik7CisgICAgICAgIHBvcy53cml0ZSgiaGVsbG8iLmdldEJ5dGVzKCJVVEYtOCIpKTsKKworICAgICAgICBJbnB1dFN0cmVhbVJlYWRlciByZWFkZXIgPSBuZXcgSW5wdXRTdHJlYW1SZWFkZXIocGluKTsKKyAgICAgICAgY2hhcltdIGJ1ZmZlciA9IG5ldyBjaGFyWzEwMjRdOworICAgICAgICBpbnQgY291bnQgPSByZWFkZXIucmVhZChidWZmZXIpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgY291bnQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vSW50ZXJydXB0ZWRTdHJlYW1UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL0ludGVycnVwdGVkU3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU5NzNiOGYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL0ludGVycnVwdGVkU3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTgwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnRlcnJ1cHRlZElPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUGlwZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlBpcGVkT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUGlwZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5QaXBlZFdyaXRlcjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0U29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5DbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5QaXBlOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlJlYWRhYmxlQnl0ZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU2VydmVyU29ja2V0Q2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5Tb2NrZXRDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLldyaXRhYmxlQnl0ZUNoYW5uZWw7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3QgdGhhdCBpbnRlcnJ1cHRpbmcgYSB0aHJlYWQgYmxvY2tlZCBvbiBJL08gY2F1c2VzIHRoYXQgdGhyZWFkIHRvIHRocm93CisgKiBhbiBJbnRlcnJ1cHRlZElPRXhjZXB0aW9uLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSW50ZXJydXB0ZWRTdHJlYW1UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJVRkZFUl9TSVpFID0gMTAyNCAqIDEwMjQ7CisKKyAgICBwcml2YXRlIFNvY2tldFtdIHNvY2tldHM7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNvY2tldHMgIT0gbnVsbCkgeworICAgICAgICAgICAgc29ja2V0c1swXS5jbG9zZSgpOworICAgICAgICAgICAgc29ja2V0c1sxXS5jbG9zZSgpOworICAgICAgICB9CisgICAgICAgIFRocmVhZC5pbnRlcnJ1cHRlZCgpOyAvLyBjbGVhciBpbnRlcnJ1cHRlZCBiaXQKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW50ZXJydXB0UGlwZWRJbnB1dFN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQaXBlZE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgUGlwZWRPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgUGlwZWRJbnB1dFN0cmVhbSBpbiA9IG5ldyBQaXBlZElucHV0U3RyZWFtKG91dCk7CisgICAgICAgIHRlc3RJbnRlcnJ1cHRJbnB1dFN0cmVhbShpbik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEludGVycnVwdFBpcGVkT3V0cHV0U3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFBpcGVkT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBQaXBlZE91dHB1dFN0cmVhbSgpOworICAgICAgICBuZXcgUGlwZWRJbnB1dFN0cmVhbShvdXQpOworICAgICAgICB0ZXN0SW50ZXJydXB0T3V0cHV0U3RyZWFtKG91dCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEludGVycnVwdFBpcGVkUmVhZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFBpcGVkV3JpdGVyIHdyaXRlciA9IG5ldyBQaXBlZFdyaXRlcigpOworICAgICAgICBQaXBlZFJlYWRlciByZWFkZXIgPSBuZXcgUGlwZWRSZWFkZXIod3JpdGVyKTsKKyAgICAgICAgdGVzdEludGVycnVwdFJlYWRlcihyZWFkZXIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnRlcnJ1cHRQaXBlZFdyaXRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBQaXBlZFdyaXRlciB3cml0ZXIgPSBuZXcgUGlwZWRXcml0ZXIoKTsKKyAgICAgICAgbmV3IFBpcGVkUmVhZGVyKHdyaXRlcik7CisgICAgICAgIHRlc3RJbnRlcnJ1cHRXcml0ZXIod3JpdGVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW50ZXJydXB0UmVhZGFibGVQaXBlQ2hhbm5lbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0SW50ZXJydXB0UmVhZGFibGVDaGFubmVsKFBpcGUub3BlbigpLnNvdXJjZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW50ZXJydXB0V3JpdGFibGVQaXBlQ2hhbm5lbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0SW50ZXJydXB0V3JpdGFibGVDaGFubmVsKFBpcGUub3BlbigpLnNpbmsoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEludGVycnVwdFJlYWRhYmxlU29ja2V0Q2hhbm5lbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzb2NrZXRzID0gbmV3U29ja2V0Q2hhbm5lbFBhaXIoKTsKKyAgICAgICAgdGVzdEludGVycnVwdFJlYWRhYmxlQ2hhbm5lbChzb2NrZXRzWzBdLmdldENoYW5uZWwoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEludGVycnVwdFdyaXRhYmxlU29ja2V0Q2hhbm5lbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzb2NrZXRzID0gbmV3U29ja2V0Q2hhbm5lbFBhaXIoKTsKKyAgICAgICAgdGVzdEludGVycnVwdFJlYWRhYmxlQ2hhbm5lbChzb2NrZXRzWzBdLmdldENoYW5uZWwoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHBhaXIgb2YgY29ubmVjdGVkIHNvY2tldHMgYmFja2VkIGJ5IE5JTyBzb2NrZXQgY2hhbm5lbHMuCisgICAgICovCisgICAgcHJpdmF0ZSBTb2NrZXRbXSBuZXdTb2NrZXRDaGFubmVsUGFpcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFNlcnZlclNvY2tldENoYW5uZWwgc2VydmVyU29ja2V0Q2hhbm5lbCA9IFNlcnZlclNvY2tldENoYW5uZWwub3BlbigpOworICAgICAgICBzZXJ2ZXJTb2NrZXRDaGFubmVsLnNvY2tldCgpLmJpbmQobmV3IEluZXRTb2NrZXRBZGRyZXNzKDApKTsKKyAgICAgICAgU29ja2V0Q2hhbm5lbCBjbGllbnRTb2NrZXRDaGFubmVsID0gU29ja2V0Q2hhbm5lbC5vcGVuKCk7CisgICAgICAgIGNsaWVudFNvY2tldENoYW5uZWwuY29ubmVjdChzZXJ2ZXJTb2NrZXRDaGFubmVsLnNvY2tldCgpLmdldExvY2FsU29ja2V0QWRkcmVzcygpKTsKKyAgICAgICAgU29ja2V0Q2hhbm5lbCBzZXJ2ZXIgPSBzZXJ2ZXJTb2NrZXRDaGFubmVsLmFjY2VwdCgpOworICAgICAgICBzZXJ2ZXJTb2NrZXRDaGFubmVsLmNsb3NlKCk7CisgICAgICAgIHJldHVybiBuZXcgU29ja2V0W10geyBjbGllbnRTb2NrZXRDaGFubmVsLnNvY2tldCgpLCBzZXJ2ZXIuc29ja2V0KCkgfTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdEludGVycnVwdElucHV0U3RyZWFtKGZpbmFsIElucHV0U3RyZWFtIGluKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaW50ZXJydXB0TWVMYXRlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4ucmVhZCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdEludGVycnVwdFJlYWRlcihmaW5hbCBQaXBlZFJlYWRlciByZWFkZXIpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbnRlcnJ1cHRNZUxhdGVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkZXIucmVhZCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdEludGVycnVwdFJlYWRhYmxlQ2hhbm5lbChmaW5hbCBSZWFkYWJsZUJ5dGVDaGFubmVsIGNoYW5uZWwpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbnRlcnJ1cHRNZUxhdGVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGFubmVsLnJlYWQoQnl0ZUJ1ZmZlci5hbGxvY2F0ZShCVUZGRVJfU0laRSkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RJbnRlcnJ1cHRPdXRwdXRTdHJlYW0oZmluYWwgT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGludGVycnVwdE1lTGF0ZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIHRoaXMgd2lsbCBibG9jayB3aGVuIHRoZSByZWNlaXZpbmcgYnVmZmVyIGZpbGxzIHVwCisgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgIG91dC53cml0ZShuZXcgYnl0ZVtCVUZGRVJfU0laRV0pOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdEludGVycnVwdFdyaXRlcihmaW5hbCBQaXBlZFdyaXRlciB3cml0ZXIpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbnRlcnJ1cHRNZUxhdGVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyB0aGlzIHdpbGwgYmxvY2sgd2hlbiB0aGUgcmVjZWl2aW5nIGJ1ZmZlciBmaWxscyB1cAorICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUobmV3IGNoYXJbQlVGRkVSX1NJWkVdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RJbnRlcnJ1cHRXcml0YWJsZUNoYW5uZWwoZmluYWwgV3JpdGFibGVCeXRlQ2hhbm5lbCBjaGFubmVsKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaW50ZXJydXB0TWVMYXRlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gdGhpcyB3aWxsIGJsb2NrIHdoZW4gdGhlIHJlY2VpdmluZyBidWZmZXIgZmlsbHMgdXAKKyAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgY2hhbm5lbC53cml0ZShCeXRlQnVmZmVyLmFsbG9jYXRlKEJVRkZFUl9TSVpFKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKENsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgaW50ZXJydXB0TWVMYXRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBUaHJlYWQgdG9JbnRlcnJ1cHQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICBuZXcgVGhyZWFkKG5ldyBSdW5uYWJsZSAoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRvSW50ZXJydXB0LmludGVycnVwdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9KS5zdGFydCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2JqZWN0T3V0cHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PYmplY3RPdXRwdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTIyODE2MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2JqZWN0T3V0cHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIE9iamVjdE91dHB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdExvbmdTdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gTW9zdCBtb2RpZmllZCBVVEYtOCBpcyBsaW1pdGVkIHRvIDY0S2lCLCBidXQgc2VyaWFsaXplZCBzdHJpbmdzIGNhbiBoYXZlIGFuIDgtYnl0ZQorICAgICAgICAvLyBsZW5ndGgsIHNvIHRoaXMgc2hvdWxkIG5ldmVyIHRocm93IGphdmEuaW8uVVRGRGF0YUZvcm1hdEV4Y2VwdGlvbi4uLgorICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2NCoxMDI0ICogMjsgKytpKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoJ2EnKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcyA9IHNiLnRvU3RyaW5nKCk7CisgICAgICAgIE9iamVjdE91dHB1dFN0cmVhbSBvcyA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0obmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpKTsKKyAgICAgICAgb3Mud3JpdGVPYmplY3Qocyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkQnVmZmVyZWRJbnB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZEJ1ZmZlcmVkSW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTVlZjIyZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZEJ1ZmZlcmVkSW5wdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSwxMTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyB0byB2ZXJpZnkgdGhhdCBzaW1wbGUgZnVuY3Rpb25hbGl0eSB3b3JrcyBmb3IgQnVmZmVyZWRJbnB1dFN0cmVhbXMuCisgKi8KK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkQnVmZmVyZWRJbnB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QnVmZmVyZWRJbnB1dFN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc3RyID0gIkFiQ2RFZkdoSWpLbE1cbk9wUXJTdFV2V3hZeiI7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGFhID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHN0ci5nZXRCeXRlcygpKTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmEgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc3RyLmdldEJ5dGVzKCkpOworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBjYSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShzdHIuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGRhID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHN0ci5nZXRCeXRlcygpKTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gZWEgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc3RyLmdldEJ5dGVzKCkpOworCisgICAgICAgIEJ1ZmZlcmVkSW5wdXRTdHJlYW0gYSA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGFhLCA2KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoc3RyLCByZWFkKGEpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGEuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIEJ1ZmZlcmVkSW5wdXRTdHJlYW0gYiA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGJhLCA3KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIkFiQ2RFZkdoSWoiLCByZWFkKGIsIDEwKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBiLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBCdWZmZXJlZElucHV0U3RyZWFtIGMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShjYSwgOSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImJkZmhqbFxucHJ0dnh6Iiwgc2tpcFJlYWQoYykpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgYy5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgQnVmZmVyZWRJbnB1dFN0cmVhbSBkID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oZGEsIDkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCdBJywgZC5yZWFkKCkpOworICAgICAgICAgICAgZC5tYXJrKDE1KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygnYicsIGQucmVhZCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygnQycsIGQucmVhZCgpKTsKKyAgICAgICAgICAgIGQucmVzZXQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygnYicsIGQucmVhZCgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGQuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIEJ1ZmZlcmVkSW5wdXRTdHJlYW0gZSA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGVhLCAxMSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyB0ZXN0IHRoYXQgd2UgY2FuIGFzayBmb3IgbW9yZSB0aGFuIGlzIHByZXNlbnQsIGFuZCB0aGF0IHdlJ2xsIGdldAorICAgICAgICAgICAgLy8gYmFjayBvbmx5IHdoYXQgaXMgdGhlcmUuCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoc3RyLCByZWFkKGUsIDEwMDAwKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBlLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyByZWFkKElucHV0U3RyZWFtIGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBkbyB7CisgICAgICAgICAgICByID0gYS5yZWFkKCk7CisgICAgICAgICAgICBpZiAociAhPSAtMSkKKyAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgoY2hhcikgcik7CisgICAgICAgIH0gd2hpbGUgKHIgIT0gLTEpOworICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHNraXBSZWFkKElucHV0U3RyZWFtIGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBkbyB7CisgICAgICAgICAgICBhLnNraXAoMSk7CisgICAgICAgICAgICByID0gYS5yZWFkKCk7CisgICAgICAgICAgICBpZiAociAhPSAtMSkKKyAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgoY2hhcikgcik7CisgICAgICAgIH0gd2hpbGUgKHIgIT0gLTEpOworICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlYWQoSW5wdXRTdHJlYW0gYSwgaW50IHgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBiID0gbmV3IGJ5dGVbeF07CisgICAgICAgIGludCBsZW4gPSBhLnJlYWQoYiwgMCwgeCk7CisgICAgICAgIGlmIChsZW4gPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gIiI7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoYiwgMCwgbGVuKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRCdWZmZXJlZE91dHB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZEJ1ZmZlcmVkT3V0cHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZkNWEyNTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRCdWZmZXJlZE91dHB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDQ3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyB0byB2ZXJpZnkgdGhhdCBzaW1wbGUgZnVuY3Rpb25hbGl0eSB3b3JrcyBmb3IgQnVmZmVyZWRPdXRwdXRTdHJlYW1zLgorICovCitwdWJsaWMgY2xhc3MgT2xkQW5kcm9pZEJ1ZmZlcmVkT3V0cHV0U3RyZWFtVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RCdWZmZXJlZE91dHB1dFN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc3RyID0gIkFiQ2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6IjsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGFhID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBCdWZmZXJlZE91dHB1dFN0cmVhbSBhID0gbmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKGFhLCAxNSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhLndyaXRlKHN0ci5nZXRCeXRlcygpLCAwLCAyNik7CisgICAgICAgICAgICBhLndyaXRlKCdBJyk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygyNiwgYWEuc2l6ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhhYS50b1N0cmluZygpLCBzdHIpOworCisgICAgICAgICAgICBhLmZsdXNoKCk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygyNywgYWEuc2l6ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiQWJDZEVmR2hJaktsTW5PcFFyU3RVdld4WXpBIiwgYWEudG9TdHJpbmcoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBhLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRCdWZmZXJlZFJlYWRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZEJ1ZmZlcmVkUmVhZGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjOGRjMTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRCdWZmZXJlZFJlYWRlclRlc3QuamF2YQpAQCAtMCwwICsxLDExNSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZFJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUmVhZGVyOworaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyB0byB2ZXJpZnkgdGhhdCBzaW1wbGUgZnVuY3Rpb25hbGl0eSB3b3JrcyBmb3IgQnVmZmVyZWRSZWFkZXJzLgorICovCitwdWJsaWMgY2xhc3MgT2xkQW5kcm9pZEJ1ZmZlcmVkUmVhZGVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RCdWZmZXJlZFJlYWRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc3RyID0gIkFiQ2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6IjsKKyAgICAgICAgU3RyaW5nUmVhZGVyIGFhID0gbmV3IFN0cmluZ1JlYWRlcihzdHIpOworICAgICAgICBTdHJpbmdSZWFkZXIgYmEgPSBuZXcgU3RyaW5nUmVhZGVyKHN0cik7CisgICAgICAgIFN0cmluZ1JlYWRlciBjYSA9IG5ldyBTdHJpbmdSZWFkZXIoc3RyKTsKKyAgICAgICAgU3RyaW5nUmVhZGVyIGRhID0gbmV3IFN0cmluZ1JlYWRlcihzdHIpOworCisgICAgICAgIEJ1ZmZlcmVkUmVhZGVyIGEgPSBuZXcgQnVmZmVyZWRSZWFkZXIoYWEsIDUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHN0ciwgcmVhZChhKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBhLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBCdWZmZXJlZFJlYWRlciBiID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKGJhLCAxNSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkFiQ2RFZkdoSWoiLCByZWFkKGIsIDEwKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBiLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBCdWZmZXJlZFJlYWRlciBjID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKGNhKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiYmRmaGpsbnBydHZ4eiIsIHNraXBSZWFkKGMpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGMuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIEJ1ZmZlcmVkUmVhZGVyIGQgPSBuZXcgQnVmZmVyZWRSZWFkZXIoZGEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJBYkNkRWZHZEVmR2hJaktsTW5PcFFyU3RVdld4WXoiLCBtYXJrUmVhZChkLCAzLCA0KSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBkLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyByZWFkKFJlYWRlciBhKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgcjsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZG8geworICAgICAgICAgICAgciA9IGEucmVhZCgpOworICAgICAgICAgICAgaWYgKHIgIT0gLTEpCisgICAgICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoKGNoYXIpIHIpOworICAgICAgICB9IHdoaWxlIChyICE9IC0xKTsKKyAgICAgICAgcmV0dXJuIGJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyByZWFkKFJlYWRlciBhLCBpbnQgeCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcltdIGIgPSBuZXcgY2hhclt4XTsKKyAgICAgICAgaW50IGxlbiA9IGEucmVhZChiLCAwLCB4KTsKKyAgICAgICAgaWYgKGxlbiA8IDApIHsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhiLCAwLCBsZW4pOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHNraXBSZWFkKFJlYWRlciBhKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgcjsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZG8geworICAgICAgICAgICAgYS5za2lwKDEpOworICAgICAgICAgICAgciA9IGEucmVhZCgpOworICAgICAgICAgICAgaWYgKHIgIT0gLTEpCisgICAgICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoKGNoYXIpIHIpOworICAgICAgICB9IHdoaWxlIChyICE9IC0xKTsKKyAgICAgICAgcmV0dXJuIGJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBtYXJrUmVhZChSZWFkZXIgYSwgaW50IHgsIGludCB5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgbSA9IDA7CisgICAgICAgIGludCByOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBkbyB7CisgICAgICAgICAgICBtKys7CisgICAgICAgICAgICByID0gYS5yZWFkKCk7CisgICAgICAgICAgICBpZiAobSA9PSB4KQorICAgICAgICAgICAgICAgIGEubWFyaygoeCArIHkpKTsKKyAgICAgICAgICAgIGlmIChtID09ICh4ICsgeSkpCisgICAgICAgICAgICAgICAgYS5yZXNldCgpOworCisgICAgICAgICAgICBpZiAociAhPSAtMSkKKyAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgoY2hhcikgcik7CisgICAgICAgIH0gd2hpbGUgKHIgIT0gLTEpOworICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZEJ1ZmZlcmVkV3JpdGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkQnVmZmVyZWRXcml0ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjdmMTIxNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZEJ1ZmZlcmVkV3JpdGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRXcml0ZXI7CitpbXBvcnQgamF2YS5pby5TdHJpbmdXcml0ZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFNvbWUgYmFzaWMgdGVzdHMgZm9yIEJ1ZmZlcmVkV3JpdGVyLgorICovCitwdWJsaWMgY2xhc3MgT2xkQW5kcm9pZEJ1ZmZlcmVkV3JpdGVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RCdWZmZXJlZFdyaXRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc3RyID0gIkFiQ2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6IjsKKyAgICAgICAgU3RyaW5nV3JpdGVyIGFhID0gbmV3IFN0cmluZ1dyaXRlcigpOworCisgICAgICAgIEJ1ZmZlcmVkV3JpdGVyIGEgPSBuZXcgQnVmZmVyZWRXcml0ZXIoYWEsIDIwKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGEud3JpdGUoc3RyLnRvQ2hhckFycmF5KCksIDAsIDI2KTsKKyAgICAgICAgICAgIGEud3JpdGUoJ1gnKTsKKyAgICAgICAgICAgIGEuZmx1c2goKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiQWJDZEVmR2hJaktsTW5PcFFyU3RVdld4WXpYIiwgYWEudG9TdHJpbmcoKSk7CisKKyAgICAgICAgICAgIGEud3JpdGUoImFscGhhYnJhdm9kZWx0YSIsIDUsIDUpOworICAgICAgICAgICAgYS5mbHVzaCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJBYkNkRWZHaElqS2xNbk9wUXJTdFV2V3hZelhicmF2byIsIGFhLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgYS5uZXdMaW5lKCk7CisgICAgICAgICAgICBhLndyaXRlKCJJJ20gb24gYSBuZXcgbGluZS4iKTsKKyAgICAgICAgICAgIGEuZmx1c2goKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiQWJDZEVmR2hJaktsTW5PcFFyU3RVdld4WXpYYnJhdm9cbklcJ20gb24gYSBuZXcgbGluZS4iLCBhYS50b1N0cmluZygpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGEuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZEJ5dGVBcnJheUlucHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkQnl0ZUFycmF5SW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTY0YzFmMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZEJ5dGVBcnJheUlucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5Bc3NlcnQ7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIHRvIHZlcmlmeSB0aGF0IHNpbXBsZSBmdW5jdGlvbmFsaXR5IHdvcmtzIGZvciBCeXRlQXJyYXlJbnB1dFN0cmVhbXMuCisgKi8KK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkQnl0ZUFycmF5SW5wdXRTdHJlYW1UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdEJ5dGVBcnJheUlucHV0U3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzdHIgPSAiQWJDZEVmR2hJaktsTW5PcFFyU3RVdld4WXoiOworCisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGEgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc3RyLmdldEJ5dGVzKCkpOworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHN0ci5nZXRCeXRlcygpKTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShzdHIuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGQgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc3RyLmdldEJ5dGVzKCkpOworCisgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoc3RyLCByZWFkKGEpKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiQWJDZEVmR2hJaiIsIHJlYWQoYiwgMTApKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiYmRmaGpsbnBydHZ4eiIsIHNraXBSZWFkKGMpKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiQWJDZEVmR2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6IiwgbWFya1JlYWQoZCwgMywgNCkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlYWQoSW5wdXRTdHJlYW0gYSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHI7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIHIgPSBhLnJlYWQoKTsKKyAgICAgICAgICAgIGlmIChyICE9IC0xKQorICAgICAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKChjaGFyKSByKTsKKyAgICAgICAgfSB3aGlsZSAociAhPSAtMSk7CisgICAgICAgIHJldHVybiBidWlsZGVyLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgcmVhZChJbnB1dFN0cmVhbSBhLCBpbnQgeCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVt4XTsKKyAgICAgICAgaW50IGxlbiA9IGEucmVhZChiLCAwLCB4KTsKKyAgICAgICAgaWYgKGxlbiA8IDApIHsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhiLCAwLCBsZW4pOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHNraXBSZWFkKElucHV0U3RyZWFtIGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBkbyB7CisgICAgICAgICAgICBhLnNraXAoMSk7CisgICAgICAgICAgICByID0gYS5yZWFkKCk7CisgICAgICAgICAgICBpZiAociAhPSAtMSkKKyAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgoY2hhcikgcik7CisgICAgICAgIH0gd2hpbGUgKHIgIT0gLTEpOworICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG1hcmtSZWFkKElucHV0U3RyZWFtIGEsIGludCB4LCBpbnQgeSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IG0gPSAwOworICAgICAgICBpbnQgcjsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZG8geworICAgICAgICAgICAgbSsrOworICAgICAgICAgICAgciA9IGEucmVhZCgpOworICAgICAgICAgICAgaWYgKG0gPT0geCkKKyAgICAgICAgICAgICAgICBhLm1hcmsoKHggKyB5KSk7CisgICAgICAgICAgICBpZiAobSA9PSAoeCArIHkpKQorICAgICAgICAgICAgICAgIGEucmVzZXQoKTsKKworICAgICAgICAgICAgaWYgKHIgIT0gLTEpCisgICAgICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoKGNoYXIpIHIpOworICAgICAgICB9IHdoaWxlIChyICE9IC0xKTsKKyAgICAgICAgcmV0dXJuIGJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRCeXRlQXJyYXlPdXRwdXRTdHJlYW1UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRCeXRlQXJyYXlPdXRwdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGQzYjc5MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZEJ5dGVBcnJheU91dHB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogQSBiYXNpYyB0ZXN0IGZvciBCeXRlQXJyYXlPdXRwdXRTdHJlYW0uCisgKi8KK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkQnl0ZUFycmF5T3V0cHV0U3RyZWFtVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHN0ciA9ICJBYkNkRWZHaElqS2xNbk9wUXJTdFV2V3hZeiI7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBhID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYiA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oMTApOworCisgICAgICAgIGEud3JpdGUoc3RyLmdldEJ5dGVzKCksIDAsIDI2KTsKKyAgICAgICAgYS53cml0ZSgnWCcpOworICAgICAgICBhLndyaXRlVG8oYik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDI3LCBhLnNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQWJDZEVmR2hJaktsTW5PcFFyU3RVdld4WXpYIiwgYS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBYkNkRWZHaElqS2xNbk9wUXJTdFV2V3hZelgiLCBiLnRvU3RyaW5nKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZENoYXJBcnJheVJlYWRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZENoYXJBcnJheVJlYWRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZTZmOGNlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkQ2hhckFycmF5UmVhZGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQ2hhckFycmF5UmVhZGVyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogQmFzaWMgdGVzdHMgZm9yIENoYXJBcnJheVJlYWRlci4KKyAqLworcHVibGljIGNsYXNzIE9sZEFuZHJvaWRDaGFyQXJyYXlSZWFkZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdENoYXJBcnJheVJlYWRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc3RyID0gIkFiQ2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6IjsKKyAgICAgICAgQ2hhckFycmF5UmVhZGVyIGEgPSBuZXcgQ2hhckFycmF5UmVhZGVyKHN0ci50b0NoYXJBcnJheSgpKTsKKyAgICAgICAgQ2hhckFycmF5UmVhZGVyIGIgPSBuZXcgQ2hhckFycmF5UmVhZGVyKHN0ci50b0NoYXJBcnJheSgpKTsKKyAgICAgICAgQ2hhckFycmF5UmVhZGVyIGMgPSBuZXcgQ2hhckFycmF5UmVhZGVyKHN0ci50b0NoYXJBcnJheSgpKTsKKyAgICAgICAgQ2hhckFycmF5UmVhZGVyIGQgPSBuZXcgQ2hhckFycmF5UmVhZGVyKHN0ci50b0NoYXJBcnJheSgpKTsKKworICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKHN0ciwgcmVhZChhKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIkFiQ2RFZkdoSWoiLCByZWFkKGIsIDEwKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoImJkZmhqbG5wcnR2eHoiLCBza2lwUmVhZChjKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIkFiQ2RFZkdkRWZHaElqS2xNbk9wUXJTdFV2V3hZeiIsIG1hcmtSZWFkKGQsIDMsIDQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyByZWFkKFJlYWRlciBhKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgcjsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZG8geworICAgICAgICAgICAgciA9IGEucmVhZCgpOworICAgICAgICAgICAgaWYgKHIgIT0gLTEpCisgICAgICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoKGNoYXIpIHIpOworICAgICAgICB9IHdoaWxlIChyICE9IC0xKTsKKyAgICAgICAgcmV0dXJuIGJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyByZWFkKFJlYWRlciBhLCBpbnQgeCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcltdIGIgPSBuZXcgY2hhclt4XTsKKyAgICAgICAgaW50IGxlbiA9IGEucmVhZChiLCAwLCB4KTsKKyAgICAgICAgaWYgKGxlbiA8IDApIHsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhiLCAwLCBsZW4pOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHNraXBSZWFkKFJlYWRlciBhKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgcjsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZG8geworICAgICAgICAgICAgYS5za2lwKDEpOworICAgICAgICAgICAgciA9IGEucmVhZCgpOworICAgICAgICAgICAgaWYgKHIgIT0gLTEpCisgICAgICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoKGNoYXIpIHIpOworICAgICAgICB9IHdoaWxlIChyICE9IC0xKTsKKyAgICAgICAgcmV0dXJuIGJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBtYXJrUmVhZChSZWFkZXIgYSwgaW50IHgsIGludCB5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgbSA9IDA7CisgICAgICAgIGludCByOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBkbyB7CisgICAgICAgICAgICBtKys7CisgICAgICAgICAgICByID0gYS5yZWFkKCk7CisgICAgICAgICAgICBpZiAobSA9PSB4KQorICAgICAgICAgICAgICAgIGEubWFyaygoeCArIHkpKTsKKyAgICAgICAgICAgIGlmIChtID09ICh4ICsgeSkpCisgICAgICAgICAgICAgICAgYS5yZXNldCgpOworCisgICAgICAgICAgICBpZiAociAhPSAtMSkKKyAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgoY2hhcikgcik7CisgICAgICAgIH0gd2hpbGUgKHIgIT0gLTEpOworICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZERhdGFJbnB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZERhdGFJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOTdjYjNhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkRGF0YUlucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTU3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkRGF0YUlucHV0U3RyZWFtVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3REYXRhSW5wdXRTdHJlYW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHN0ciA9ICJBYkNkRWZHaElqS2xNXG5PcFFcclN0VXZXeFl6IjsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYWEgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc3RyLmdldEJ5dGVzKCkpOworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiYSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShzdHIuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGNhID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHN0ci5nZXRCeXRlcygpKTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gZGEgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc3RyLmdldEJ5dGVzKCkpOworCisgICAgICAgIERhdGFJbnB1dFN0cmVhbSBhID0gbmV3IERhdGFJbnB1dFN0cmVhbShhYSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKHN0ciwgcmVhZChhKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBhLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBEYXRhSW5wdXRTdHJlYW0gYiA9IG5ldyBEYXRhSW5wdXRTdHJlYW0oYmEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiQWJDZEVmR2hJaiIsIHJlYWQoYiwgMTApKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGIuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIERhdGFJbnB1dFN0cmVhbSBjID0gbmV3IERhdGFJbnB1dFN0cmVhbShjYSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCJiZGZoamxcbnBccnR2eHoiLCBza2lwUmVhZChjKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBjLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBEYXRhSW5wdXRTdHJlYW0gZCA9IG5ldyBEYXRhSW5wdXRTdHJlYW0oZGEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJBYkNkRWZHaElqS2xNIiwgZC5yZWFkTGluZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiT3BRIiwgZC5yZWFkTGluZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiU3RVdld4WXoiLCBkLnJlYWRMaW5lKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZC5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGUgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIERhdGFPdXRwdXRTdHJlYW0gZiA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKGUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZi53cml0ZUJvb2xlYW4odHJ1ZSk7CisgICAgICAgICAgICBmLndyaXRlQnl0ZSgnYScpOworICAgICAgICAgICAgZi53cml0ZUJ5dGVzKCJCQ0QiKTsKKyAgICAgICAgICAgIGYud3JpdGVDaGFyKCdlJyk7CisgICAgICAgICAgICBmLndyaXRlQ2hhcnMoIkZHSCIpOworICAgICAgICAgICAgZi53cml0ZVVURigiaWprbG0iKTsKKyAgICAgICAgICAgIGYud3JpdGVEb3VibGUoMSk7CisgICAgICAgICAgICBmLndyaXRlRmxvYXQoMik7CisgICAgICAgICAgICBmLndyaXRlSW50KDMpOworICAgICAgICAgICAgZi53cml0ZUxvbmcoNCk7CisgICAgICAgICAgICBmLndyaXRlU2hvcnQoNSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBmLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBnYSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShlLnRvQnl0ZUFycmF5KCkpOworICAgICAgICBEYXRhSW5wdXRTdHJlYW0gZyA9IG5ldyBEYXRhSW5wdXRTdHJlYW0oZ2EpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGcucmVhZEJvb2xlYW4oKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoJ2EnLCBnLnJlYWRCeXRlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGcuc2tpcEJ5dGVzKDIpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygnRCcsIGcucmVhZEJ5dGUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoJ2UnLCBnLnJlYWRDaGFyKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCdGJywgZy5yZWFkQ2hhcigpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygnRycsIGcucmVhZENoYXIoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoJ0gnLCBnLnJlYWRDaGFyKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJpamtsbSIsIGcucmVhZFVURigpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnLnJlYWREb3VibGUoKSwgMCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMmYsIGcucmVhZEZsb2F0KCksIDBmKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygzLCBnLnJlYWRJbnQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgZy5yZWFkTG9uZygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyg1LCBnLnJlYWRTaG9ydCgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGcuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlYWQoSW5wdXRTdHJlYW0gYSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHI7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIHIgPSBhLnJlYWQoKTsKKyAgICAgICAgICAgIGlmIChyICE9IC0xKQorICAgICAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKChjaGFyKSByKTsKKyAgICAgICAgfSB3aGlsZSAociAhPSAtMSk7CisgICAgICAgIHJldHVybiBidWlsZGVyLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgcmVhZChJbnB1dFN0cmVhbSBhLCBpbnQgeCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVt4XTsKKyAgICAgICAgaW50IGxlbiA9IGEucmVhZChiLCAwLCB4KTsKKyAgICAgICAgaWYgKGxlbiA8IDApIHsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhiLCAwLCBsZW4pOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHNraXBSZWFkKElucHV0U3RyZWFtIGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBkbyB7CisgICAgICAgICAgICBhLnNraXAoMSk7CisgICAgICAgICAgICByID0gYS5yZWFkKCk7CisgICAgICAgICAgICBpZiAociAhPSAtMSkKKyAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgoY2hhcikgcik7CisgICAgICAgIH0gd2hpbGUgKHIgIT0gLTEpOworICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG1hcmtSZWFkKElucHV0U3RyZWFtIGEsIGludCB4LCBpbnQgeSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IG0gPSAwOworICAgICAgICBpbnQgcjsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZG8geworICAgICAgICAgICAgbSsrOworICAgICAgICAgICAgciA9IGEucmVhZCgpOworICAgICAgICAgICAgaWYgKG0gPT0geCkKKyAgICAgICAgICAgICAgICBhLm1hcmsoKHggKyB5KSk7CisgICAgICAgICAgICBpZiAobSA9PSAoeCArIHkpKQorICAgICAgICAgICAgICAgIGEucmVzZXQoKTsKKworICAgICAgICAgICAgaWYgKHIgIT0gLTEpCisgICAgICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoKGNoYXIpIHIpOworICAgICAgICB9IHdoaWxlIChyICE9IC0xKTsKKyAgICAgICAgcmV0dXJuIGJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWREYXRhT3V0cHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkRGF0YU91dHB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZDlmY2RhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkRGF0YU91dHB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDQ4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXRTdHJlYW07CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIEJhc2ljIHRlc3RzIGZvciBEYXRhT3V0cHV0U3RyZWFtcy4KKyAqLworcHVibGljIGNsYXNzIE9sZEFuZHJvaWREYXRhT3V0cHV0U3RyZWFtVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3REYXRhT3V0cHV0U3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzdHIgPSAiQWJDZEVmR2hJaktsTW5PcFFyU3RVdld4WXoiOworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYWEgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIERhdGFPdXRwdXRTdHJlYW0gYSA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKGFhKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYS53cml0ZShzdHIuZ2V0Qnl0ZXMoKSwgMCwgMjYpOworICAgICAgICAgICAgYS53cml0ZSgnQScpOworCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMjcsIGFhLnNpemUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkFiQ2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6QSIsIGFhLnRvU3RyaW5nKCkpOworCisgICAgICAgICAgICBhLndyaXRlQnl0ZSgnQicpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJBYkNkRWZHaElqS2xNbk9wUXJTdFV2V3hZekFCIiwgYWEudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBhLndyaXRlQnl0ZXMoIkJZVEVTIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkFiQ2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6QUJCWVRFUyIsIGFhLnRvU3RyaW5nKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgYS5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkRmlsZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZEZpbGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2NlYWMwZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZEZpbGVUZXN0LmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBDaGVja3MgY3JlYXRpb24gYW5kIGRlbGV0aW9uIG9mIGEgZmlsZS4KKyAqLworcHVibGljIGNsYXNzIE9sZEFuZHJvaWRGaWxlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgZmlsZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoU3RyaW5nLnZhbHVlT2YoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpLCBudWxsLCBudWxsKTsKKworICAgICAgICBhc3NlcnRUcnVlKGZpbGUuZXhpc3RzKCkpOworICAgICAgICBhc3NlcnRUcnVlKGZpbGUuZGVsZXRlKCkpOworICAgICAgICBhc3NlcnRGYWxzZShmaWxlLmV4aXN0cygpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRJbnB1dFN0cmVhbVJlYWRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZElucHV0U3RyZWFtUmVhZGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdhMGQ1ZmMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRJbnB1dFN0cmVhbVJlYWRlclRlc3QuamF2YQpAQCAtMCwwICsxLDEwOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBDaGVja3MgYmFzaWMgSW5wdXRTdHJlYW1SZWFkZXIgZnVuY3Rpb25hbGl0eS4KKyAqLworcHVibGljIGNsYXNzIE9sZEFuZHJvaWRJbnB1dFN0cmVhbVJlYWRlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgQVNDSUkgZW5jb2Rpbmcgd29ya3Mgd2l0aCBJbnB1dFN0cmVhbVJlYWRlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RBc2NpaSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc3RyID0gIkFiQ2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6WCI7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGFhID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHN0ci5nZXRCeXRlcygiSVNPODg1OV8xIikpOworICAgICAgICBJbnB1dFN0cmVhbVJlYWRlciBhID0gbmV3IElucHV0U3RyZWFtUmVhZGVyKGFhLCAiSVNPODg1OV8xIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCB4ID0gYS5yZWFkKCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoJ0EnLCB4KTsKKyAgICAgICAgICAgIGNoYXJbXSBjID0gbmV3IGNoYXJbMjZdOworICAgICAgICAgICAgeCA9IGEucmVhZChjLCAwLCAyNik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGEuZ2V0RW5jb2RpbmcoKS5lcXVhbHNJZ25vcmVDYXNlKCJJU084ODU5XzEiKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMjYsIHgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJiQ2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6WCIsIFN0cmluZy52YWx1ZU9mKGMpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGEuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBpZiBVdGY4IGVuY29kaW5nIHdvcmtzIHdpdGggSW5wdXRTdHJlYW1SZWFkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXRmOCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc3RyID0gIkFiQ2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6WCIgKworICAgICAgICAgICAgICAgICJcdTAwYTNcdTAwYzVcdTAwYzkiOyAgICAgICAvLyB0b3RhbCBvZiAzMCBjaGFyYWN0ZXJzCisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGFhID0KKyAgICAgICAgICAgICAgICBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc3RyLmdldEJ5dGVzKCkpOworCisgICAgICAgIElucHV0U3RyZWFtUmVhZGVyIGEgPSBuZXcgSW5wdXRTdHJlYW1SZWFkZXIoYWEpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlVURjgiLCBhLmdldEVuY29kaW5nKCkpOworCisgICAgICAgICAgICBpbnQgeCA9IGEucmVhZCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCdBJywgeCk7CisKKyAgICAgICAgICAgIGNoYXJbXSBjID0gbmV3IGNoYXJbMjldOworICAgICAgICAgICAgeCA9IGEucmVhZChjLCAwLCAzKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygzLCB4KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiYkNkIiwgbmV3IFN0cmluZyhjLCAwLCAzKSk7CisKKyAgICAgICAgICAgIHggPSBhLnJlYWQoYywgMywgMjYpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDI2LCB4KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiRWZHaElqS2xNbk9wUXJTdFV2V3hZelhcdTAwYTNcdTAwYzVcdTAwYzkiLCBuZXcgU3RyaW5nKGMsIDMsIDI2KSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBhLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgaWYgc2V2ZXJhbCBlbmNvZGluZ3Mgd29ya3Mgd2l0aCBJbnB1dFN0cmVhbVJlYWRlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTdHJpbmd5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzcmMgPSAiVGhlIHF1aWNrIGJyb3duIGZveFx1MDBBMFx1MDBGRiIgKworICAgICAgICAgICAgICAgICJcdUZGRkNcdUQ3QzVcdURDMDNibG9vZiI7CisKKyAgICAgICAgU3RyaW5nW10gZW5jID0gbmV3IFN0cmluZ1tdeworICAgICAgICAgICAgICAgICJ1dGYtOCIsICJ1cy1hc2NpaSIsICJpc28tODg1OS0xIiwgInV0Zi0xNmJlIiwgInV0Zi0xNmxlIiwKKyAgICAgICAgICAgICAgICAidXRmLTE2IiwKKyAgICAgICAgfTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVuYy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYnl0ZVtdIGJhID0gc3JjLmdldEJ5dGVzKGVuY1tpXSk7CisKKyAgICAgICAgICAgIFN0cmluZyBzMSA9IG5ldyBTdHJpbmcoYmEsIGVuY1tpXSk7CisKKyAgICAgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJhaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmEpOworICAgICAgICAgICAgSW5wdXRTdHJlYW1SZWFkZXIgciA9IG5ldyBJbnB1dFN0cmVhbVJlYWRlcihiYWlzLCBlbmNbaV0pOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjaGFyW10gY2EgPSBuZXcgY2hhcls2MDBdOworICAgICAgICAgICAgICAgIGludCBuID0gci5yZWFkKGNhLCAwLCA2MDApOworCisgICAgICAgICAgICAgICAgU3RyaW5nIHMyID0gbmV3IFN0cmluZyhjYSwgMCwgbik7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHMxLCBzMik7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHIuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZExpbmVOdW1iZXJSZWFkZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRMaW5lTnVtYmVyUmVhZGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZhY2I5NTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRMaW5lTnVtYmVyUmVhZGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTI5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uTGluZU51bWJlclJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLlJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1JlYWRlcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBDaGVja3MgYmFzaWMgZnVuY3Rpb25hbGl0eSBmb3IgTGluZU51bWJlclJlYWRlci4KKyAqLworcHVibGljIGNsYXNzIE9sZEFuZHJvaWRMaW5lTnVtYmVyUmVhZGVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RMaW5lTnVtYmVyUmVhZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzdHIgPSAiQWJDZEVmR2hJaktsTVxuT3BRclN0VXZXeFl6IjsKKworICAgICAgICBTdHJpbmdSZWFkZXIgYWEgPSBuZXcgU3RyaW5nUmVhZGVyKHN0cik7CisgICAgICAgIFN0cmluZ1JlYWRlciBiYSA9IG5ldyBTdHJpbmdSZWFkZXIoc3RyKTsKKyAgICAgICAgU3RyaW5nUmVhZGVyIGNhID0gbmV3IFN0cmluZ1JlYWRlcihzdHIpOworICAgICAgICBTdHJpbmdSZWFkZXIgZGEgPSBuZXcgU3RyaW5nUmVhZGVyKHN0cik7CisgICAgICAgIFN0cmluZ1JlYWRlciBlYSA9IG5ldyBTdHJpbmdSZWFkZXIoc3RyKTsKKworICAgICAgICBMaW5lTnVtYmVyUmVhZGVyIGEgPSBuZXcgTGluZU51bWJlclJlYWRlcihhYSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYS5nZXRMaW5lTnVtYmVyKCkpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhzdHIsIHJlYWQoYSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGEuZ2V0TGluZU51bWJlcigpKTsKKyAgICAgICAgICAgIGEuc2V0TGluZU51bWJlcig1KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyg1LCBhLmdldExpbmVOdW1iZXIoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBhLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBMaW5lTnVtYmVyUmVhZGVyIGIgPSBuZXcgTGluZU51bWJlclJlYWRlcihiYSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCJBYkNkRWZHaElqIiwgcmVhZChiLCAxMCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgYi5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgTGluZU51bWJlclJlYWRlciBjID0gbmV3IExpbmVOdW1iZXJSZWFkZXIoY2EpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiYmRmaGpsXG5wcnR2eHoiLCBza2lwUmVhZChjKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBjLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBMaW5lTnVtYmVyUmVhZGVyIGQgPSBuZXcgTGluZU51bWJlclJlYWRlcihkYSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCJBYkNkRWZHZEVmR2hJaktsTVxuT3BRclN0VXZXeFl6IiwgbWFya1JlYWQoZCwgMywgNCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZC5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgTGluZU51bWJlclJlYWRlciBlID0gbmV3IExpbmVOdW1iZXJSZWFkZXIoZWEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJBYkNkRWZHaElqS2xNIiwgZS5yZWFkTGluZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGUuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlYWQoUmVhZGVyIGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBkbyB7CisgICAgICAgICAgICByID0gYS5yZWFkKCk7CisgICAgICAgICAgICBpZiAociAhPSAtMSkKKyAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgoY2hhcikgcik7CisgICAgICAgIH0gd2hpbGUgKHIgIT0gLTEpOworICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlYWQoUmVhZGVyIGEsIGludCB4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGFyW10gYiA9IG5ldyBjaGFyW3hdOworICAgICAgICBpbnQgbGVuID0gYS5yZWFkKGIsIDAsIHgpOworICAgICAgICBpZiAobGVuIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuICIiOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGIsIDAsIGxlbik7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgc2tpcFJlYWQoUmVhZGVyIGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBkbyB7CisgICAgICAgICAgICBhLnNraXAoMSk7CisgICAgICAgICAgICByID0gYS5yZWFkKCk7CisgICAgICAgICAgICBpZiAociAhPSAtMSkKKyAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgoY2hhcikgcik7CisgICAgICAgIH0gd2hpbGUgKHIgIT0gLTEpOworICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG1hcmtSZWFkKFJlYWRlciBhLCBpbnQgeCwgaW50IHkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBtID0gMDsKKyAgICAgICAgaW50IHI7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIG0rKzsKKyAgICAgICAgICAgIHIgPSBhLnJlYWQoKTsKKyAgICAgICAgICAgIGlmIChtID09IHgpCisgICAgICAgICAgICAgICAgYS5tYXJrKCh4ICsgeSkpOworICAgICAgICAgICAgaWYgKG0gPT0gKHggKyB5KSkKKyAgICAgICAgICAgICAgICBhLnJlc2V0KCk7CisKKyAgICAgICAgICAgIGlmIChyICE9IC0xKQorICAgICAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKChjaGFyKSByKTsKKyAgICAgICAgfSB3aGlsZSAociAhPSAtMSk7CisgICAgICAgIHJldHVybiBidWlsZGVyLnRvU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkT3V0cHV0U3RyZWFtV3JpdGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkT3V0cHV0U3RyZWFtV3JpdGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlNTU5ZmYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRPdXRwdXRTdHJlYW1Xcml0ZXJUZXN0LmphdmEKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW1Xcml0ZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGJhc2ljIGZ1bmN0aW9uYWxpdHkgb2YgYW4gT3V0cHV0U3RyZWFtV3JpdGVyLgorICovCitwdWJsaWMgY2xhc3MgT2xkQW5kcm9pZE91dHB1dFN0cmVhbVdyaXRlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T3V0cHV0U3RyZWFtV3JpdGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzdHIgPSAiQWJDZEVmR2hJaktsTW5PcFFyU3RVdld4WXoiOworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYWEgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIE91dHB1dFN0cmVhbVdyaXRlciBhID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihhYSwgIklTTzg4NTlfMSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYS53cml0ZShzdHIsIDAsIDQpOworICAgICAgICAgICAgYS53cml0ZSgnQScpOworICAgICAgICAgICAgLy8gV2UgaGF2ZSB0byBmbHVzaCB0aGUgT3V0cHV0U3RyZWFtV3JpdGVyIHRvIGd1YXJhbnRlZQorICAgICAgICAgICAgLy8gdGhhdCB0aGUgcmVzdWx0cyB3aWxsIGFwcGVhciBpbiB0aGUgdW5kZXJseWluZyBPdXRwdXRTdHJlYW0KKyAgICAgICAgICAgIGEuZmx1c2goKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSVNPODg1OV8xIiwgYS5nZXRFbmNvZGluZygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyg1LCBhYS5zaXplKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJBYkNkQSIsIGFhLnRvU3RyaW5nKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgYS5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkUGlwZWRTdHJlYW1UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRQaXBlZFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYzU1NjEyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkUGlwZWRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSwyOTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uUGlwZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlBpcGVkT3V0cHV0U3RyZWFtOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZEFuZHJvaWRQaXBlZFN0cmVhbVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIGFic3RyYWN0IHN0YXRpYyBjbGFzcyBUZXN0VGhyZWFkIGV4dGVuZHMgVGhyZWFkIHsKKyAgICAgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcnVuVGVzdCgpIHRocm93cyBFeGNlcHRpb247CisKKyAgICAgICAgcHVibGljIGZpbmFsIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBydW5UZXN0KCk7CisgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZSkgeworICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBUaHJvd2FibGUgZXhjZXB0aW9uOworICAgICAgICBpbnQgY291bnRSZWFkID0gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QSgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIGZpbmFsIFBpcGVkSW5wdXRTdHJlYW0gaW4gPSBuZXcgUGlwZWRJbnB1dFN0cmVhbSgpOworICAgICAgICBmaW5hbCBQaXBlZE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgUGlwZWRPdXRwdXRTdHJlYW0oaW4pOworCisgICAgICAgIGFzc2VydEVxdWFscygwLCBpbi5hdmFpbGFibGUoKSk7CisKKyAgICAgICAgVGVzdFRocmVhZCByZWFkZXIsIHdyaXRlcjsKKworICAgICAgICByZWFkZXIgPSBuZXcgVGVzdFRocmVhZCgpIHsKKyAgICAgICAgICAgIEZpYm9uYWNjaSBmaWIgPSBuZXcgRmlib25hY2NpKCk7CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgIGludCByZWFkSW50OworICAgICAgICAgICAgICAgIGJ5dGUgcmVhZEJ5dGU7CisKKyAgICAgICAgICAgICAgICBmb3IgKDsgOykgeworICAgICAgICAgICAgICAgICAgICByZWFkSW50ID0gaW4ucmVhZCgpOworCisgICAgICAgICAgICAgICAgICAgIGlmIChyZWFkSW50ID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICByZWFkQnl0ZSA9IChieXRlKSByZWFkSW50OworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMocmVhZEJ5dGUsIChieXRlKSBmaWIubmV4dCgpKTsKKyAgICAgICAgICAgICAgICAgICAgY291bnRSZWFkKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHJlYWRlci5zdGFydCgpOworCisgICAgICAgIHdyaXRlciA9IG5ldyBUZXN0VGhyZWFkKCkgeworICAgICAgICAgICAgRmlib25hY2NpIGZpYiA9IG5ldyBGaWJvbmFjY2koKTsKKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDAwOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHRvV3JpdGUgPSBmaWIubmV4dCgpOworICAgICAgICAgICAgICAgICAgICBvdXQud3JpdGUodG9Xcml0ZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHdyaXRlci5zdGFydCgpOworCisKKyAgICAgICAgZm9yICg7IDspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmVhZGVyLmpvaW4oNjAgKiAxMDAwKTsKKyAgICAgICAgICAgICAgICB3cml0ZXIuam9pbigxMDAwKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoMjAwMCwgcmVhZGVyLmNvdW50UmVhZCk7CisKKyAgICAgICAgaWYgKHdyaXRlci5leGNlcHRpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbih3cml0ZXIuZXhjZXB0aW9uKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocmVhZGVyLmV4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKHJlYWRlci5leGNlcHRpb24pOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgUGlwZWRJbnB1dFN0cmVhbSBpbiA9IG5ldyBQaXBlZElucHV0U3RyZWFtKCk7CisgICAgICAgIGZpbmFsIFBpcGVkT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBQaXBlZE91dHB1dFN0cmVhbShpbik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGluLmF2YWlsYWJsZSgpKTsKKworICAgICAgICBUZXN0VGhyZWFkIHJlYWRlciwgd3JpdGVyOworCisgICAgICAgIHJlYWRlciA9IG5ldyBUZXN0VGhyZWFkKCkgeworICAgICAgICAgICAgRmlib25hY2NpIGZpYiA9IG5ldyBGaWJvbmFjY2koKTsKKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgYnl0ZSByZWFkQnl0ZXNbXSA9IG5ldyBieXRlWzVdOworICAgICAgICAgICAgICAgIGludCByZXQ7CisKKyAgICAgICAgICAgICAgICBmb3IgKDsgOykgeworICAgICAgICAgICAgICAgICAgICBpbnQgbnJlYWQgPSAwOworICAgICAgICAgICAgICAgICAgICB3aGlsZSAobnJlYWQgPCA1KSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXQgPSBpbi5yZWFkKHJlYWRCeXRlcywgbnJlYWQsIHJlYWRCeXRlcy5sZW5ndGggLSBucmVhZCk7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXQgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBucmVhZCArPSByZXQ7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNSwgbnJlYWQpOworCisgICAgICAgICAgICAgICAgICAgIGludCByZWFkSW50ID0gKCgoaW50KSByZWFkQnl0ZXNbMF0gJiAweGZmKSA8PCAyNCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICgoKGludCkgcmVhZEJ5dGVzWzFdICYgMHhmZikgPDwgMTYpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAoKChpbnQpIHJlYWRCeXRlc1syXSAmIDB4ZmYpIDw8IDgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAoKChpbnQpIHJlYWRCeXRlc1szXSAmIDB4ZmYpKTsKKworCisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiRXJyb3IgYXQgIiArIGNvdW50UmVhZCwgZmliLm5leHQoKSwgcmVhZEludCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiRXJyb3IgYXQgIiArIGNvdW50UmVhZCwgMCwgcmVhZEJ5dGVzWzRdKTsKKyAgICAgICAgICAgICAgICAgICAgY291bnRSZWFkKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHJlYWRlci5zdGFydCgpOworCisgICAgICAgIHdyaXRlciA9IG5ldyBUZXN0VGhyZWFkKCkgeworICAgICAgICAgICAgRmlib25hY2NpIGZpYiA9IG5ldyBGaWJvbmFjY2koKTsKKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgYnl0ZSB3cml0ZUJ5dGVzW10gPSBuZXcgYnl0ZVs1XTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDIwMDA7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBpbnQgdG9Xcml0ZSA9IGZpYi5uZXh0KCk7CisgICAgICAgICAgICAgICAgICAgIHdyaXRlQnl0ZXNbMF0gPSAoYnl0ZSkgKHRvV3JpdGUgPj4gMjQpOworICAgICAgICAgICAgICAgICAgICB3cml0ZUJ5dGVzWzFdID0gKGJ5dGUpICh0b1dyaXRlID4+IDE2KTsKKyAgICAgICAgICAgICAgICAgICAgd3JpdGVCeXRlc1syXSA9IChieXRlKSAodG9Xcml0ZSA+PiA4KTsKKyAgICAgICAgICAgICAgICAgICAgd3JpdGVCeXRlc1szXSA9IChieXRlKSAodG9Xcml0ZSk7CisgICAgICAgICAgICAgICAgICAgIHdyaXRlQnl0ZXNbNF0gPSAwOworICAgICAgICAgICAgICAgICAgICBvdXQud3JpdGUod3JpdGVCeXRlcywgMCwgd3JpdGVCeXRlcy5sZW5ndGgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICB3cml0ZXIuc3RhcnQoKTsKKworCisgICAgICAgIGZvciAoOyA7KSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJlYWRlci5qb2luKDYwICogMTAwMCk7CisgICAgICAgICAgICAgICAgd3JpdGVyLmpvaW4oMTAwMCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKHJlYWRlci5leGNlcHRpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbihyZWFkZXIuZXhjZXB0aW9uKTsKKyAgICAgICAgfQorICAgICAgICBpZiAod3JpdGVyLmV4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKHdyaXRlci5leGNlcHRpb24pOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIwMDAsIHJlYWRlci5jb3VudFJlYWQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFBpcGVkSW5wdXRTdHJlYW0gaW4gPSBuZXcgUGlwZWRJbnB1dFN0cmVhbSgpOworICAgICAgICBmaW5hbCBQaXBlZE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgUGlwZWRPdXRwdXRTdHJlYW0oaW4pOworICAgICAgICBmaW5hbCBieXRlIHJlYWRCeXRlc1tdID0gbmV3IGJ5dGVbMTAyNCAqIDJdOworCisgICAgICAgIGFzc2VydEVxdWFscygwLCBpbi5hdmFpbGFibGUoKSk7CisKKyAgICAgICAgVGVzdFRocmVhZCByZWFkZXIsIHdyaXRlcjsKKworICAgICAgICByZWFkZXIgPSBuZXcgVGVzdFRocmVhZCgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgIGludCByZXQ7CisKKyAgICAgICAgICAgICAgICBmb3IgKDsgOykgeworICAgICAgICAgICAgICAgICAgICBpbnQgbnJlYWQgPSAwOworICAgICAgICAgICAgICAgICAgICB3aGlsZSAobnJlYWQgPCByZWFkQnl0ZXMubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXQgPSBpbi5yZWFkKHJlYWRCeXRlcywgbnJlYWQsIHJlYWRCeXRlcy5sZW5ndGggLSBucmVhZCk7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXQgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBucmVhZCArPSByZXQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgcmVhZGVyLnN0YXJ0KCk7CisKKyAgICAgICAgd3JpdGVyID0gbmV3IFRlc3RUaHJlYWQoKSB7CisgICAgICAgICAgICBGaWJvbmFjY2kgZmliID0gbmV3IEZpYm9uYWNjaSgpOworCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBieXRlIHdyaXRlQnl0ZXNbXSA9IG5ldyBieXRlWzEwMjQgKiAyXTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICh3cml0ZUJ5dGVzLmxlbmd0aCAtIDQpOyBpICs9IDQpIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHRvV3JpdGUgPSBmaWIubmV4dCgpOworICAgICAgICAgICAgICAgICAgICB3cml0ZUJ5dGVzW2kgICAgXSA9IChieXRlKSAodG9Xcml0ZSA+PiAyNCk7CisgICAgICAgICAgICAgICAgICAgIHdyaXRlQnl0ZXNbaSArIDFdID0gKGJ5dGUpICh0b1dyaXRlID4+IDE2KTsKKyAgICAgICAgICAgICAgICAgICAgd3JpdGVCeXRlc1tpICsgMl0gPSAoYnl0ZSkgKHRvV3JpdGUgPj4gOCk7CisgICAgICAgICAgICAgICAgICAgIHdyaXRlQnl0ZXNbaSArIDNdID0gKGJ5dGUpICh0b1dyaXRlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgb3V0LndyaXRlKHdyaXRlQnl0ZXMsIDAsIHdyaXRlQnl0ZXMubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICB3cml0ZXIuc3RhcnQoKTsKKworCisgICAgICAgIGZvciAoOyA7KSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJlYWRlci5qb2luKDYwICogMTAwMCk7CisgICAgICAgICAgICAgICAgd3JpdGVyLmpvaW4oMTAwMCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKHJlYWRlci5leGNlcHRpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbihyZWFkZXIuZXhjZXB0aW9uKTsKKyAgICAgICAgfQorICAgICAgICBpZiAod3JpdGVyLmV4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKHdyaXRlci5leGNlcHRpb24pOworICAgICAgICB9CisKKyAgICAgICAgRmlib25hY2NpIGZpYiA9IG5ldyBGaWJvbmFjY2koKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAocmVhZEJ5dGVzLmxlbmd0aCAtIDQpOyBpICs9IDQpIHsKKyAgICAgICAgICAgIGludCByZWFkSW50ID0gKCgoaW50KSByZWFkQnl0ZXNbaV0gJiAweGZmKSA8PCAyNCkKKyAgICAgICAgICAgICAgICAgICAgfCAoKChpbnQpIHJlYWRCeXRlc1tpICsgMV0gJiAweGZmKSA8PCAxNikKKyAgICAgICAgICAgICAgICAgICAgfCAoKChpbnQpIHJlYWRCeXRlc1tpICsgMl0gJiAweGZmKSA8PCA4KQorICAgICAgICAgICAgICAgICAgICB8ICgoKGludCkgcmVhZEJ5dGVzW2kgKyAzXSAmIDB4ZmYpKTsKKworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJFcnJvciBhdCAiICsgaSwgcmVhZEludCwgZmliLm5leHQoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgRmlib25hY2NpIHsKKyAgICAgICAgaW50IG4xID0gLTE7CisgICAgICAgIGludCBuMjsKKworICAgICAgICBwdWJsaWMgaW50IG5leHQoKSB7CisgICAgICAgICAgICBpZiAobjEgPCAwKSB7CisgICAgICAgICAgICAgICAgbjEgPSAwOworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfSBlbHNlIGlmIChuMSA9PSAwKSB7CisgICAgICAgICAgICAgICAgbjIgPSAwOworICAgICAgICAgICAgICAgIG4xID0gMTsKKyAgICAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaW50IHJldCA9IG4xICsgbjI7CisgICAgICAgICAgICAgICAgbjIgPSBuMTsKKyAgICAgICAgICAgICAgICBuMSA9IHJldDsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmV0OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkUHJpbnRXcml0ZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRQcmludFdyaXRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43Zjk5MDM2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkUHJpbnRXcml0ZXJUZXN0LmphdmEKQEAgLTAsMCArMSw3MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkUHJpbnRXcml0ZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdFByaW50V3JpdGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzdHIgPSAiQWJDZEVmR2hJaktsTW5PcFFyU3RVdld4WXoiOworICAgICAgICBTdHJpbmdXcml0ZXIgYWEgPSBuZXcgU3RyaW5nV3JpdGVyKCk7CisgICAgICAgIFByaW50V3JpdGVyIGEgPSBuZXcgUHJpbnRXcml0ZXIoYWEpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhLndyaXRlKHN0ciwgMCwgMjYpOworICAgICAgICAgICAgYS53cml0ZSgnWCcpOworCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkFiQ2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6WCIsIGFhLnRvU3RyaW5nKCkpOworCisgICAgICAgICAgICBhLndyaXRlKCJhbHBoYWJyYXZvZGVsdGEiLCA1LCA1KTsKKyAgICAgICAgICAgIGEuYXBwZW5kKCdYJyk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkFiQ2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6WGJyYXZvWCIsIGFhLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgYS5hcHBlbmQoIm9tZWdhIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkFiQ2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6WGJyYXZvWG9tZWdhIiwgYWEudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBhLnByaW50KCJaWloiKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiQWJDZEVmR2hJaktsTW5PcFFyU3RVdld4WXpYYnJhdm9Yb21lZ2FaWloiLCBhYS50b1N0cmluZygpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGEuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ1dyaXRlciBiYSA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKKyAgICAgICAgUHJpbnRXcml0ZXIgYiA9IG5ldyBQcmludFdyaXRlcihiYSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiLnByaW50KHRydWUpOworICAgICAgICAgICAgYi5wcmludCgoY2hhcikgJ0EnKTsKKyAgICAgICAgICAgIGIucHJpbnQoIkJDRCIudG9DaGFyQXJyYXkoKSk7CisgICAgICAgICAgICBiLnByaW50KChkb3VibGUpIDEuMik7CisgICAgICAgICAgICBiLnByaW50KChmbG9hdCkgMyk7CisgICAgICAgICAgICBiLnByaW50KChpbnQpIDQpOworICAgICAgICAgICAgYi5wcmludCgobG9uZykgNSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInRydWVBQkNEMS4yMy4wNDUiLCBiYS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGIucHJpbnRsbigpOworICAgICAgICAgICAgYi5wcmludGxuKHRydWUpOworICAgICAgICAgICAgYi5wcmludGxuKChjaGFyKSAnQScpOworICAgICAgICAgICAgYi5wcmludGxuKCJCQ0QiLnRvQ2hhckFycmF5KCkpOworICAgICAgICAgICAgYi5wcmludGxuKChkb3VibGUpIDEuMik7CisgICAgICAgICAgICBiLnByaW50bG4oKGZsb2F0KSAzKTsKKyAgICAgICAgICAgIGIucHJpbnRsbigoaW50KSA0KTsKKyAgICAgICAgICAgIGIucHJpbnRsbigobG9uZykgNSk7CisgICAgICAgICAgICBiLnByaW50KCJUSEUgRU5EIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInRydWVBQkNEMS4yMy4wNDVcbnRydWVcbkFcbkJDRFxuMS4yXG4zLjBcbjRcbjVcblRIRSBFTkQiLCBiYS50b1N0cmluZygpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGIuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZFB1c2hiYWNrSW5wdXRTdHJlYW1UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRQdXNoYmFja0lucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdlZGRlY2EKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRQdXNoYmFja0lucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlB1c2hiYWNrSW5wdXRTdHJlYW07CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkUHVzaGJhY2tJbnB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHVzaGJhY2tJbnB1dFN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc3RyID0gIkFiQ2RFZkdoSWpLbE1cbk9wUXJTdFV2V3hZeiI7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGFhID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHN0ci5nZXRCeXRlcygpKTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmEgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc3RyLmdldEJ5dGVzKCkpOworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBjYSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShzdHIuZ2V0Qnl0ZXMoKSk7CisKKyAgICAgICAgUHVzaGJhY2tJbnB1dFN0cmVhbSBhID0gbmV3IFB1c2hiYWNrSW5wdXRTdHJlYW0oYWEsIDcpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYS51bnJlYWQoInB1c2giLmdldEJ5dGVzKCkpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygicHVzaEFiQ2RFZkdoSWpLbE1cbk9wUXJTdFV2V3hZeiIsIHJlYWQoYSkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgYS5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgUHVzaGJhY2tJbnB1dFN0cmVhbSBiID0gbmV3IFB1c2hiYWNrSW5wdXRTdHJlYW0oYmEsIDkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYi51bnJlYWQoJ1gnKTsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIlhBYkNkRWZHaEkiLCByZWFkKGIsIDEwKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBiLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBQdXNoYmFja0lucHV0U3RyZWFtIGMgPSBuZXcgUHVzaGJhY2tJbnB1dFN0cmVhbShjYSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCJiZGZoamxcbnBydHZ4eiIsIHNraXBSZWFkKGMpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGMuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlYWQoSW5wdXRTdHJlYW0gYSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHI7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIHIgPSBhLnJlYWQoKTsKKyAgICAgICAgICAgIGlmIChyICE9IC0xKQorICAgICAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKChjaGFyKSByKTsKKyAgICAgICAgfSB3aGlsZSAociAhPSAtMSk7CisgICAgICAgIHJldHVybiBidWlsZGVyLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgcmVhZChJbnB1dFN0cmVhbSBhLCBpbnQgeCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVt4XTsKKyAgICAgICAgaW50IGxlbiA9IGEucmVhZChiLCAwLCB4KTsKKyAgICAgICAgaWYgKGxlbiA8IDApIHsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhiLCAwLCBsZW4pOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHNraXBSZWFkKElucHV0U3RyZWFtIGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBkbyB7CisgICAgICAgICAgICBhLnNraXAoMSk7CisgICAgICAgICAgICByID0gYS5yZWFkKCk7CisgICAgICAgICAgICBpZiAociAhPSAtMSkKKyAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgoY2hhcikgcik7CisgICAgICAgIH0gd2hpbGUgKHIgIT0gLTEpOworICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG1hcmtSZWFkKElucHV0U3RyZWFtIGEsIGludCB4LCBpbnQgeSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IG0gPSAwOworICAgICAgICBpbnQgcjsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZG8geworICAgICAgICAgICAgbSsrOworICAgICAgICAgICAgciA9IGEucmVhZCgpOworICAgICAgICAgICAgaWYgKG0gPT0geCkKKyAgICAgICAgICAgICAgICBhLm1hcmsoKHggKyB5KSk7CisgICAgICAgICAgICBpZiAobSA9PSAoeCArIHkpKQorICAgICAgICAgICAgICAgIGEucmVzZXQoKTsKKworICAgICAgICAgICAgaWYgKHIgIT0gLTEpCisgICAgICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoKGNoYXIpIHIpOworICAgICAgICB9IHdoaWxlIChyICE9IC0xKTsKKyAgICAgICAgcmV0dXJuIGJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRQdXNoYmFja1JlYWRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZFB1c2hiYWNrUmVhZGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhM2Y4ZmEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRQdXNoYmFja1JlYWRlclRlc3QuamF2YQpAQCAtMCwwICsxLDg5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUHVzaGJhY2tSZWFkZXI7CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CitpbXBvcnQgamF2YS5pby5TdHJpbmdSZWFkZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkUHVzaGJhY2tSZWFkZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdFB1c2hiYWNrUmVhZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzdHIgPSAiQWJDZEVmR2hJaktsTW5PcFFyU3RVdld4WXoiOworICAgICAgICBTdHJpbmdSZWFkZXIgYWEgPSBuZXcgU3RyaW5nUmVhZGVyKHN0cik7CisgICAgICAgIFN0cmluZ1JlYWRlciBiYSA9IG5ldyBTdHJpbmdSZWFkZXIoc3RyKTsKKyAgICAgICAgU3RyaW5nUmVhZGVyIGNhID0gbmV3IFN0cmluZ1JlYWRlcihzdHIpOworCisgICAgICAgIFB1c2hiYWNrUmVhZGVyIGEgPSBuZXcgUHVzaGJhY2tSZWFkZXIoYWEsIDUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYS51bnJlYWQoIlBVU0giLnRvQ2hhckFycmF5KCkpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiUFVTSEFiQ2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6IiwgcmVhZChhKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBhLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBQdXNoYmFja1JlYWRlciBiID0gbmV3IFB1c2hiYWNrUmVhZGVyKGJhLCAxNSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiLnVucmVhZCgnWCcpOworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiWEFiQ2RFZkdoSSIsIHJlYWQoYiwgMTApKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGIuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIFB1c2hiYWNrUmVhZGVyIGMgPSBuZXcgUHVzaGJhY2tSZWFkZXIoY2EpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiYmRmaGpsbnBydHZ4eiIsIHNraXBSZWFkKGMpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGMuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlYWQoUmVhZGVyIGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBkbyB7CisgICAgICAgICAgICByID0gYS5yZWFkKCk7CisgICAgICAgICAgICBpZiAociAhPSAtMSkKKyAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgoY2hhcikgcik7CisgICAgICAgIH0gd2hpbGUgKHIgIT0gLTEpOworICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlYWQoUmVhZGVyIGEsIGludCB4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGFyW10gYiA9IG5ldyBjaGFyW3hdOworICAgICAgICBpbnQgbGVuID0gYS5yZWFkKGIsIDAsIHgpOworICAgICAgICBpZiAobGVuIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuICIiOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGIsIDAsIGxlbik7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgc2tpcFJlYWQoUmVhZGVyIGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBkbyB7CisgICAgICAgICAgICBhLnNraXAoMSk7CisgICAgICAgICAgICByID0gYS5yZWFkKCk7CisgICAgICAgICAgICBpZiAociAhPSAtMSkKKyAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgoY2hhcikgcik7CisgICAgICAgIH0gd2hpbGUgKHIgIT0gLTEpOworICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZFNlcmlhbGl6YXRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRTZXJpYWxpemF0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIwNjQ1ODEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRTZXJpYWxpemF0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBzZXJpYWxpemF0aW9uIG9mIHVzZXItbGV2ZWwgY2xhc3Nlcy4KKyAqLworcHVibGljIGNsYXNzIE9sZEFuZHJvaWRTZXJpYWxpemF0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBjbGFzcyBNeVNlcmlhbGl6YWJsZSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7fQorCisgICAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6YXRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtIG9vdXQgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKGJvdXQpOworICAgICAgICBvb3V0LndyaXRlT2JqZWN0KG5ldyBNeVNlcmlhbGl6YWJsZSgpKTsKKyAgICAgICAgb291dC5jbG9zZSgpOworCisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShib3V0LnRvQnl0ZUFycmF5KCkpOworICAgICAgICBPYmplY3QgbyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShiaW4pLnJlYWRPYmplY3QoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShvIGluc3RhbmNlb2YgTXlTZXJpYWxpemFibGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZFN0cmVhbVRva2VuaXplclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZFN0cmVhbVRva2VuaXplclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMTNiYTk5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkU3RyZWFtVG9rZW5pemVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TdHJlYW1Ub2tlbml6ZXI7CitpbXBvcnQgamF2YS5pby5TdHJpbmdSZWFkZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciB0aGUgU3RyZWFtVG9rZW5pemVyCisgKi8KK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkU3RyZWFtVG9rZW5pemVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdHJlYW1Ub2tlbml6ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHN0ciA9ICJUZXN0aW5nIDEyMzQ1IFxuIGFscGhhIFxyXG4gb21lZ2EiOworICAgICAgICBTdHJpbmcgc3RyYiA9ICItMy44ICdCTElORCBtaWNlJyBcciBzRWUgLyogaG93ICovIHRoZXkgcnVuIjsKKyAgICAgICAgU3RyaW5nUmVhZGVyIGFhID0gbmV3IFN0cmluZ1JlYWRlcihzdHIpOworICAgICAgICBTdHJpbmdSZWFkZXIgYmEgPSBuZXcgU3RyaW5nUmVhZGVyKHN0cmIpOworICAgICAgICBTdHJlYW1Ub2tlbml6ZXIgYSA9IG5ldyBTdHJlYW1Ub2tlbml6ZXIoYWEpOworICAgICAgICBTdHJlYW1Ub2tlbml6ZXIgYiA9IG5ldyBTdHJlYW1Ub2tlbml6ZXIoYmEpOworCisgICAgICAgIGFzc2VydEVxdWFscygxLCBhLmxpbmVubygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFN0cmVhbVRva2VuaXplci5UVF9XT1JELCBhLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUb2tlbltUZXN0aW5nXSwgbGluZSAxIiwgYS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFN0cmVhbVRva2VuaXplci5UVF9OVU1CRVIsIGEubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRva2VuW249MTIzNDUuMF0sIGxpbmUgMSIsIGEudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhTdHJlYW1Ub2tlbml6ZXIuVFRfV09SRCwgYS5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVG9rZW5bYWxwaGFdLCBsaW5lIDIiLCBhLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoU3RyZWFtVG9rZW5pemVyLlRUX1dPUkQsIGEubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRva2VuW29tZWdhXSwgbGluZSAzIiwgYS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFN0cmVhbVRva2VuaXplci5UVF9FT0YsIGEubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRva2VuW0VPRl0sIGxpbmUgMyIsIGEudG9TdHJpbmcoKSk7CisKKyAgICAgICAgYi5jb21tZW50Q2hhcigndScpOworICAgICAgICBiLmVvbElzU2lnbmlmaWNhbnQodHJ1ZSk7CisgICAgICAgIGIubG93ZXJDYXNlTW9kZSh0cnVlKTsKKyAgICAgICAgYi5vcmRpbmFyeUNoYXIoJ3knKTsKKyAgICAgICAgYi5zbGFzaFN0YXJDb21tZW50cyh0cnVlKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoU3RyZWFtVG9rZW5pemVyLlRUX05VTUJFUiwgYi5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMy44LCBiLm52YWwpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRva2VuW249LTMuOF0sIGxpbmUgMSIsIGIudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzOSwgYi5uZXh0VG9rZW4oKSk7IC8vICcKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUb2tlbltCTElORCBtaWNlXSwgbGluZSAxIiwgYi50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEwLCBiLm5leHRUb2tlbigpKTsgLy8gXG4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUb2tlbltFT0xdLCBsaW5lIDIiLCBiLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoU3RyZWFtVG9rZW5pemVyLlRUX1dPUkQsIGIubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRva2VuW3NlZV0sIGxpbmUgMiIsIGIudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhTdHJlYW1Ub2tlbml6ZXIuVFRfV09SRCwgYi5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVG9rZW5bdGhlXSwgbGluZSAyIiwgYi50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEyMSwgYi5uZXh0VG9rZW4oKSk7IC8vIHkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUb2tlblsneSddLCBsaW5lIDIiLCBiLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoU3RyZWFtVG9rZW5pemVyLlRUX1dPUkQsIGIubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRva2VuW3JdLCBsaW5lIDIiLCBiLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoU3RyZWFtVG9rZW5pemVyLlRUX0VPRiwgYi5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVG9rZW5bRU9GXSwgbGluZSAyIiwgYi50b1N0cmluZygpKTsKKworICAgICAgICAvLyBBIGhhcm1vbnkgcmVncmVzc2lvbiB0ZXN0CisgICAgICAgIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbXXsoYnl0ZSkgJy0nfTsKKyAgICAgICAgU3RyZWFtVG9rZW5pemVyIHRva2VuaXplciA9IG5ldyBTdHJlYW1Ub2tlbml6ZXIobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpKTsKKyAgICAgICAgdG9rZW5pemVyLm5leHRUb2tlbigpOworICAgICAgICBTdHJpbmcgcmVzdWx0ID0gdG9rZW5pemVyLnRvU3RyaW5nKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVG9rZW5bJy0nXSwgbGluZSAxIiwgcmVzdWx0KTsKKworICAgICAgICAvLyBhbm90aGVyIGhhcm1vbnkgcmVncmVzc2lvbiB0ZXN0CisgICAgICAgIGJ5dGVbXSBkYXRhMiA9IG5ldyBieXRlW117KGJ5dGUpICciJywKKyAgICAgICAgICAgICAgICAoYnl0ZSkgJ0gnLAorICAgICAgICAgICAgICAgIChieXRlKSAnZScsCisgICAgICAgICAgICAgICAgKGJ5dGUpICdsJywKKyAgICAgICAgICAgICAgICAoYnl0ZSkgJ2wnLAorICAgICAgICAgICAgICAgIChieXRlKSAnbycsCisgICAgICAgICAgICAgICAgKGJ5dGUpICciJ307CisgICAgICAgIFN0cmVhbVRva2VuaXplciB0b2tlbml6ZXIyID0gbmV3IFN0cmVhbVRva2VuaXplcihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YTIpKTsKKyAgICAgICAgdG9rZW5pemVyMi5uZXh0VG9rZW4oKTsKKyAgICAgICAgcmVzdWx0ID0gdG9rZW5pemVyMi50b1N0cmluZygpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRva2VuW0hlbGxvXSwgbGluZSAxIiwgcmVzdWx0KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRTdHJpbmdSZWFkZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRTdHJpbmdSZWFkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTY1ZDk4ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQW5kcm9pZFN0cmluZ1JlYWRlclRlc3QuamF2YQpAQCAtMCwwICsxLDkwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUmVhZGVyOworaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5Bc3NlcnQ7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkQW5kcm9pZFN0cmluZ1JlYWRlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RyaW5nUmVhZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzdHIgPSAiQWJDZEVmR2hJaktsTW5PcFFyU3RVdld4WXoiOworCisgICAgICAgIFN0cmluZ1JlYWRlciBhID0gbmV3IFN0cmluZ1JlYWRlcihzdHIpOworICAgICAgICBTdHJpbmdSZWFkZXIgYiA9IG5ldyBTdHJpbmdSZWFkZXIoc3RyKTsKKyAgICAgICAgU3RyaW5nUmVhZGVyIGMgPSBuZXcgU3RyaW5nUmVhZGVyKHN0cik7CisgICAgICAgIFN0cmluZ1JlYWRlciBkID0gbmV3IFN0cmluZ1JlYWRlcihzdHIpOworCisgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoc3RyLCByZWFkKGEpKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiQWJDZEVmR2hJaiIsIHJlYWQoYiwgMTApKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiYmRmaGpsbnBydHZ4eiIsIHNraXBSZWFkKGMpKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiQWJDZEVmR2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6IiwgbWFya1JlYWQoZCwgMywgNCkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlYWQoUmVhZGVyIGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBkbyB7CisgICAgICAgICAgICByID0gYS5yZWFkKCk7CisgICAgICAgICAgICBpZiAociAhPSAtMSkKKyAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgoY2hhcikgcik7CisgICAgICAgIH0gd2hpbGUgKHIgIT0gLTEpOworICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlYWQoUmVhZGVyIGEsIGludCB4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGFyW10gYiA9IG5ldyBjaGFyW3hdOworICAgICAgICBpbnQgbGVuID0gYS5yZWFkKGIsIDAsIHgpOworICAgICAgICBpZiAobGVuIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuICIiOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGIsIDAsIGxlbik7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgc2tpcFJlYWQoUmVhZGVyIGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCByOworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBkbyB7CisgICAgICAgICAgICBhLnNraXAoMSk7CisgICAgICAgICAgICByID0gYS5yZWFkKCk7CisgICAgICAgICAgICBpZiAociAhPSAtMSkKKyAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgoY2hhcikgcik7CisgICAgICAgIH0gd2hpbGUgKHIgIT0gLTEpOworICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG1hcmtSZWFkKFJlYWRlciBhLCBpbnQgeCwgaW50IHkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBtID0gMDsKKyAgICAgICAgaW50IHI7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIG0rKzsKKyAgICAgICAgICAgIHIgPSBhLnJlYWQoKTsKKyAgICAgICAgICAgIGlmIChtID09IHgpCisgICAgICAgICAgICAgICAgYS5tYXJrKCh4ICsgeSkpOworICAgICAgICAgICAgaWYgKG0gPT0gKHggKyB5KSkKKyAgICAgICAgICAgICAgICBhLnJlc2V0KCk7CisKKyAgICAgICAgICAgIGlmIChyICE9IC0xKQorICAgICAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKChjaGFyKSByKTsKKyAgICAgICAgfSB3aGlsZSAociAhPSAtMSk7CisgICAgICAgIHJldHVybiBidWlsZGVyLnRvU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkU3RyaW5nV3JpdGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRBbmRyb2lkU3RyaW5nV3JpdGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkxNjczZjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEFuZHJvaWRTdHJpbmdXcml0ZXJUZXN0LmphdmEKQEAgLTAsMCArMSwzOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5TdHJpbmdXcml0ZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkQW5kcm9pZFN0cmluZ1dyaXRlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RyaW5nV3JpdGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzdHIgPSAiQWJDZEVmR2hJaktsTW5PcFFyU3RVdld4WXoiOworICAgICAgICBTdHJpbmdXcml0ZXIgYSA9IG5ldyBTdHJpbmdXcml0ZXIoMTApOworCisgICAgICAgIGEud3JpdGUoc3RyLCAwLCAyNik7CisgICAgICAgIGEud3JpdGUoJ1gnKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkFiQ2RFZkdoSWpLbE1uT3BRclN0VXZXeFl6WCIsIGEudG9TdHJpbmcoKSk7CisKKyAgICAgICAgYS53cml0ZSgiYWxwaGFicmF2b2RlbHRhIiwgNSwgNSk7CisgICAgICAgIGEuYXBwZW5kKCdYJyk7CisgICAgICAgIGFzc2VydEVxdWFscygiQWJDZEVmR2hJaktsTW5PcFFyU3RVdld4WXpYYnJhdm9YIiwgYS50b1N0cmluZygpKTsKKyAgICAgICAgYS5hcHBlbmQoIm9tZWdhIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQWJDZEVmR2hJaktsTW5PcFFyU3RVdld4WXpYYnJhdm9Yb21lZ2EiLCBhLnRvU3RyaW5nKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQnVmZmVyZWRJbnB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQnVmZmVyZWRJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hM2VmNGU0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRCdWZmZXJlZElucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjI4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9QbGF0Zm9ybUZpbGU7CisKK3B1YmxpYyBjbGFzcyBPbGRCdWZmZXJlZElucHV0U3RyZWFtVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyBTdHJpbmcgZmlsZU5hbWU7CisgICAgcHJpdmF0ZSBCdWZmZXJlZElucHV0U3RyZWFtIGlzOworICAgIHByaXZhdGUgRmlsZUlucHV0U3RyZWFtIGlzRmlsZTsKKyAgICBwdWJsaWMgU3RyaW5nIGZpbGVTdHJpbmcgPSAiVGVzdF9BbGxfVGVzdHNcblRlc3RfQnVmZmVyZWRJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0J1ZmZlcmVkT3V0cHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fQnl0ZUFycmF5SW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19CeXRlQXJyYXlPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19EYXRhSW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19GaWxlXG5UZXN0X2phdmFfaW9fRmlsZURlc2NyaXB0b3JcblRlc3RfamF2YV9pb19GaWxlSW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19GaWxlTm90Rm91bmRFeGNlcHRpb25cblRlc3RfamF2YV9pb19GaWxlT3V0cHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fRmlsdGVySW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19GaWx0ZXJPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19JbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0lPRXhjZXB0aW9uXG5UZXN0X2phdmFfaW9fT3V0cHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fUHJpbnRTdHJlYW1cblRlc3RfamF2YV9pb19SYW5kb21BY2Nlc3NGaWxlXG5UZXN0X2phdmFfaW9fU3luY0ZhaWxlZEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQWJzdHJhY3RNZXRob2RFcnJvclxuVGVzdF9qYXZhX2xhbmdfQXJpdGhtZXRpY0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19BcnJheVN0b3JlRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19Cb29sZWFuXG5UZXN0X2phdmFfbGFuZ19CeXRlXG5UZXN0X2phdmFfbGFuZ19DaGFyYWN0ZXJcblRlc3RfamF2YV9sYW5nX0NsYXNzXG5UZXN0X2phdmFfbGFuZ19DbGFzc0Nhc3RFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0NsYXNzQ2lyY3VsYXJpdHlFcnJvclxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NGb3JtYXRFcnJvclxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NMb2FkZXJcblRlc3RfamF2YV9sYW5nX0NsYXNzTm90Rm91bmRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0Nsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19Eb3VibGVcblRlc3RfamF2YV9sYW5nX0Vycm9yXG5UZXN0X2phdmFfbGFuZ19FeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0V4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvclxuVGVzdF9qYXZhX2xhbmdfRmxvYXRcblRlc3RfamF2YV9sYW5nX0lsbGVnYWxBY2Nlc3NFcnJvclxuVGVzdF9qYXZhX2xhbmdfSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbGxlZ2FsVGhyZWFkU3RhdGVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0luY29tcGF0aWJsZUNsYXNzQ2hhbmdlRXJyb3JcblRlc3RfamF2YV9sYW5nX0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0luc3RhbnRpYXRpb25FcnJvclxuVGVzdF9qYXZhX2xhbmdfSW5zdGFudGlhdGlvbkV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSW50ZWdlclxuVGVzdF9qYXZhX2xhbmdfSW50ZXJuYWxFcnJvclxuVGVzdF9qYXZhX2xhbmdfSW50ZXJydXB0ZWRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0xpbmthZ2VFcnJvclxuVGVzdF9qYXZhX2xhbmdfTG9uZ1xuVGVzdF9qYXZhX2xhbmdfTWF0aFxuVGVzdF9qYXZhX2xhbmdfTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX05vQ2xhc3NEZWZGb3VuZEVycm9yXG5UZXN0X2phdmFfbGFuZ19Ob1N1Y2hGaWVsZEVycm9yXG5UZXN0X2phdmFfbGFuZ19Ob1N1Y2hNZXRob2RFcnJvclxuVGVzdF9qYXZhX2xhbmdfTnVsbFBvaW50ZXJFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX051bWJlclxuVGVzdF9qYXZhX2xhbmdfTnVtYmVyRm9ybWF0RXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19PYmplY3RcblRlc3RfamF2YV9sYW5nX091dE9mTWVtb3J5RXJyb3JcblRlc3RfamF2YV9sYW5nX1J1bnRpbWVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX1NlY3VyaXR5TWFuYWdlclxuVGVzdF9qYXZhX2xhbmdfU2hvcnRcblRlc3RfamF2YV9sYW5nX1N0YWNrT3ZlcmZsb3dFcnJvclxuVGVzdF9qYXZhX2xhbmdfU3RyaW5nXG5UZXN0X2phdmFfbGFuZ19TdHJpbmdCdWZmZXJcblRlc3RfamF2YV9sYW5nX1N0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX1N5c3RlbVxuVGVzdF9qYXZhX2xhbmdfVGhyZWFkXG5UZXN0X2phdmFfbGFuZ19UaHJlYWREZWF0aFxuVGVzdF9qYXZhX2xhbmdfVGhyZWFkR3JvdXBcblRlc3RfamF2YV9sYW5nX1Rocm93YWJsZVxuVGVzdF9qYXZhX2xhbmdfVW5rbm93bkVycm9yXG5UZXN0X2phdmFfbGFuZ19VbnNhdGlzZmllZExpbmtFcnJvclxuVGVzdF9qYXZhX2xhbmdfVmVyaWZ5RXJyb3JcblRlc3RfamF2YV9sYW5nX1ZpcnR1YWxNYWNoaW5lRXJyb3JcblRlc3RfamF2YV9sYW5nX3ZtX0ltYWdlXG5UZXN0X2phdmFfbGFuZ192bV9NZW1vcnlTZWdtZW50XG5UZXN0X2phdmFfbGFuZ192bV9ST01TdG9yZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfdm1fVk1cblRlc3RfamF2YV9sYW5nX1ZvaWRcblRlc3RfamF2YV9uZXRfQmluZEV4Y2VwdGlvblxuVGVzdF9qYXZhX25ldF9Db25uZWN0RXhjZXB0aW9uXG5UZXN0X2phdmFfbmV0X0RhdGFncmFtUGFja2V0XG5UZXN0X2phdmFfbmV0X0RhdGFncmFtU29ja2V0XG5UZXN0X2phdmFfbmV0X0RhdGFncmFtU29ja2V0SW1wbFxuVGVzdF9qYXZhX25ldF9JbmV0QWRkcmVzc1xuVGVzdF9qYXZhX25ldF9Ob1JvdXRlVG9Ib3N0RXhjZXB0aW9uXG5UZXN0X2phdmFfbmV0X1BsYWluRGF0YWdyYW1Tb2NrZXRJbXBsXG5UZXN0X2phdmFfbmV0X1BsYWluU29ja2V0SW1wbFxuVGVzdF9qYXZhX25ldF9Tb2NrZXRcblRlc3RfamF2YV9uZXRfU29ja2V0RXhjZXB0aW9uXG5UZXN0X2phdmFfbmV0X1NvY2tldEltcGxcblRlc3RfamF2YV9uZXRfU29ja2V0SW5wdXRTdHJlYW1cblRlc3RfamF2YV9uZXRfU29ja2V0T3V0cHV0U3RyZWFtXG5UZXN0X2phdmFfbmV0X1Vua25vd25Ib3N0RXhjZXB0aW9uXG5UZXN0X2phdmFfdXRpbF9BcnJheUVudW1lcmF0b3JcblRlc3RfamF2YV91dGlsX0RhdGVcblRlc3RfamF2YV91dGlsX0V2ZW50T2JqZWN0XG5UZXN0X2phdmFfdXRpbF9IYXNoRW51bWVyYXRvclxuVGVzdF9qYXZhX3V0aWxfSGFzaHRhYmxlXG5UZXN0X2phdmFfdXRpbF9Qcm9wZXJ0aWVzXG5UZXN0X2phdmFfdXRpbF9SZXNvdXJjZUJ1bmRsZVxuVGVzdF9qYXZhX3V0aWxfdG1cblRlc3RfamF2YV91dGlsX1ZlY3RvclxuIjsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9pb19JbnB1dFN0cmVhbSgpIHsKKyAgICAgICAgaXMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShpc0ZpbGUpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZWFkKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IFJlYWQgZmFpbGVkIG9uIGEgZnJlc2hseSBjb25zdHJ1Y3RlZCBidWZmZXIuIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fSW5wdXRTdHJlYW1JKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gcmVncmVzc2lvbiB0ZXN0IGZvciBoYXJtb255LTI0MDcKKyAgICAgICAgbmV3IHRlc3RCdWZmZXJlZElucHV0U3RyZWFtKG51bGwpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRlc3RCdWZmZXJlZElucHV0U3RyZWFtLmJ1Zik7CisgICAgICAgIHRlc3RCdWZmZXJlZElucHV0U3RyZWFtLmJ1ZiA9IG51bGw7CisgICAgICAgIG5ldyB0ZXN0QnVmZmVyZWRJbnB1dFN0cmVhbShudWxsLCAxMDApOworICAgICAgICBhc3NlcnROb3ROdWxsKHRlc3RCdWZmZXJlZElucHV0U3RyZWFtLmJ1Zik7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIHRlc3RCdWZmZXJlZElucHV0U3RyZWFtIGV4dGVuZHMgQnVmZmVyZWRJbnB1dFN0cmVhbSB7CisgICAgICAgIHN0YXRpYyBieXRlW10gYnVmOworICAgICAgICB0ZXN0QnVmZmVyZWRJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyKGlzKTsKKyAgICAgICAgICAgIGJ1ZiA9IHN1cGVyLmJ1ZjsKKyAgICAgICAgfQorCisgICAgICAgIHRlc3RCdWZmZXJlZElucHV0U3RyZWFtKElucHV0U3RyZWFtIGlzLCBpbnQgc2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyKGlzLCBzaXplKTsKKyAgICAgICAgICAgIGJ1ZiA9IHN1cGVyLmJ1ZjsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYXZhaWxhYmxlKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbS5hdmFpbGFibGUoKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IG51bWJlciBvZiBhdmFpbGFibGUgYnl0ZXMiLCBpcworICAgICAgICAgICAgICAgICAgICAuYXZhaWxhYmxlKCkgPT0gZmlsZVN0cmluZy5sZW5ndGgoKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgYXZhaWxhYmxlIHRlc3QiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3QgdGhhdCBhIGNsb3NlZCBzdHJlYW0gdGhyb3dzIGFuIElPRSBmb3IgYXZhaWxhYmxlKCkKKyAgICAgICAgQnVmZmVyZWRJbnB1dFN0cmVhbSBiaXMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbXSB7ICdoJywgJ2UnLCAnbCcsICdsJywgJ28nLAorICAgICAgICAgICAgICAgICAgICAgICAgJyAnLCAndCcsICdpJywgJ20nIH0pKTsKKyAgICAgICAgaW50IGF2YWlsYWJsZSA9IDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhdmFpbGFibGUgPSBiaXMuYXZhaWxhYmxlKCk7CisgICAgICAgICAgICBiaXMuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKGF2YWlsYWJsZSAhPSAwKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmlzLmF2YWlsYWJsZSgpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgdGVzdCB0byB0aHJvdyBJT0UuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIHRlc3QgdG8gdGhyb3cgSU9FIG5vdCAiCisgICAgICAgICAgICAgICAgICAgICsgZXguZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlzLmNsb3NlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSU9FeGNlcHRpb24gZXhwZWN0ZWQgd2hlbiByZWFkaW5nIGFmdGVyIGNsb3NpbmcgIiArCisgICAgICAgICAgICAgICAgICJ0aGUgc3RyZWFtLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIFN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtIHNpcyA9IG5ldyBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbSh0cnVlKTsKKyAgICAgICAgaXMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShzaXMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIHNpcy50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbWFya0lfcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gYnVmMSA9IG5ldyBieXRlWzEwMF07CisgICAgICAgIGJ5dGVbXSBidWYyID0gbmV3IGJ5dGVbMTAwXTsKKworICAgICAgICAvLyBUZXN0IDE6IENoZWNrIHRoYXQgcmVzZXQgZmFpbHMgaWYgbm8gbWFyayBoYXMgYmVlbiBzZXQuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZXNldCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJT0V4Y2VwdGlvbiBleHBlY3RlZCBpZiBubyBtYXJrIGhhcyBiZWVuIHNldC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICAvLyBUZXN0IDI6IENoZWNrIHRoYXQgbWFyayAvIHJlc2V0IHdvcmtzIHdoZW4gdGhlIG1hcmsgaXMgbm90IGludmFsaWRhdGVkLgorICAgICAgICBpcy5za2lwKDEwKTsKKyAgICAgICAgaXMubWFyaygxMDApOworICAgICAgICBpcy5yZWFkKGJ1ZjEsIDAsIGJ1ZjEubGVuZ3RoKTsKKyAgICAgICAgaXMucmVzZXQoKTsKKyAgICAgICAgaXMucmVhZChidWYyLCAwLCBidWYyLmxlbmd0aCk7CisgICAgICAgIGlzLnJlc2V0KCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMjogRmFpbGVkIHRvIG1hcmsgY29ycmVjdCBwb3NpdGlvbiBvciByZXNldCBmYWlsZWQuIiwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKGJ1ZjEsIDAsIGJ1ZjEubGVuZ3RoKS5lcXVhbHMobmV3IFN0cmluZyhidWYyLCAwLCBidWYyLmxlbmd0aCkpKTsKKworICAgICAgICAvLyBUZXN0cyAzIGFuZCA0OiBDaGVjayB0aGF0IHNraXBwaW5nIGxlc3MgdGhhbiByZWFkbGltaXQgYnl0ZXMgZG9lcworICAgICAgICAvLyBub3QgaW52YWxpZGF0ZSB0aGUgbWFyay4KKyAgICAgICAgaXMuc2tpcCgxMCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZXNldCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IFVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBpcy5yZWFkKGJ1ZjIsIDAsIGJ1ZjIubGVuZ3RoKTsKKyAgICAgICAgaXMucmVzZXQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCA0OiBGYWlsZWQgdG8gbWFyayBjb3JyZWN0IHBvc2l0aW9uLCBvciByZXNldCBmYWlsZWQuIiwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKGJ1ZjEsIDAsIGJ1ZjEubGVuZ3RoKS5lcXVhbHMobmV3IFN0cmluZyhidWYyLCAwLCBidWYyLmxlbmd0aCkpKTsKKworICAgICAgICAvLyBUZXN0IDg6IENoZWNrIHRoYXQgcmVzZXQgZmFpbHMgZm9yIGEgY2xvc2VkIGlucHV0IHN0cmVhbS4KKyAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlc2V0KCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDg6IElPRXhjZXB0aW9uIGV4cGVjdGVkIGJlY2F1c2UgdGhlIGlucHV0IHN0cmVhbSBpcyBjbG9zZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGMgPSBpcy5yZWFkKCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogSW5jb3JyZWN0IGNoYXJhY3RlciByZWFkLiIsCisgICAgICAgICAgICAgICAgYyA9PSBmaWxlU3RyaW5nLmNoYXJBdCgwKSk7CisKKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbMjU2XTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyNTY7IGkrKykgeworICAgICAgICAgICAgYnl0ZXNbaV0gPSAoYnl0ZSkgaTsKKyAgICAgICAgfQorCisgICAgICAgIEJ1ZmZlcmVkSW5wdXRTdHJlYW0gaW4gPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZXMpLCA1KTsKKworICAgICAgICAvLyBSZWFkIG1vcmUgYnl0ZXMgdGhhbiBhcmUgYnVmZmVyZWQuCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IEluY29ycmVjdCBieXRlIHJlYWQ7IiwgYnl0ZXNbaV0sIGluLnJlYWQoKSk7CisgICAgICAgIH0KKworICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4ucmVhZCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbGVOYW1lID0gU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLmRpciIpOworICAgICAgICAgICAgU3RyaW5nIHNlcGFyYXRvciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiZmlsZS5zZXBhcmF0b3IiKTsKKyAgICAgICAgICAgIGlmIChmaWxlTmFtZS5jaGFyQXQoZmlsZU5hbWUubGVuZ3RoKCkgLSAxKSA9PSBzZXBhcmF0b3IuY2hhckF0KDApKSB7CisgICAgICAgICAgICAgICAgZmlsZU5hbWUgPSBTdXBwb3J0X1BsYXRmb3JtRmlsZS5nZXROZXdQbGF0Zm9ybUZpbGUoZmlsZU5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAiaW5wdXQudHN0Iik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZpbGVOYW1lID0gU3VwcG9ydF9QbGF0Zm9ybUZpbGUuZ2V0TmV3UGxhdGZvcm1GaWxlKGZpbGVOYW1lCisgICAgICAgICAgICAgICAgICAgICAgICArIHNlcGFyYXRvciwgImlucHV0LnRzdCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgT3V0cHV0U3RyZWFtIGZvcyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZpbGVOYW1lKTsKKyAgICAgICAgICAgIGZvcy53cml0ZShmaWxlU3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICAgICAgZm9zLmNsb3NlKCk7CisgICAgICAgICAgICBpc0ZpbGUgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGVOYW1lKTsKKyAgICAgICAgaXMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShpc0ZpbGUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoZmlsZU5hbWUpOworICAgICAgICAgICAgZi5kZWxldGUoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQnVmZmVyZWRPdXRwdXRTdHJlYW1UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEJ1ZmZlcmVkT3V0cHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNmYjMxN2IKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEJ1ZmZlcmVkT3V0cHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTk4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfT3V0cHV0U3RyZWFtOworCitwdWJsaWMgY2xhc3MgT2xkQnVmZmVyZWRPdXRwdXRTdHJlYW1UZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgamF2YS5pby5PdXRwdXRTdHJlYW0gb3M7CisKKyAgICBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zOworCisgICAgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbSBiYWlzOworCisgICAgU3VwcG9ydF9PdXRwdXRTdHJlYW0gc29zOworCisgICAgcHVibGljIFN0cmluZyBmaWxlU3RyaW5nID0gIlRlc3RfQWxsX1Rlc3RzXG5UZXN0X2phdmFfaW9fQnVmZmVyZWRJbnB1dFN0cmVhbVxuVGVzdF9CdWZmZXJlZE91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0J5dGVBcnJheUlucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fQnl0ZUFycmF5T3V0cHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fRGF0YUlucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fRmlsZVxuVGVzdF9qYXZhX2lvX0ZpbGVEZXNjcmlwdG9yXG5UZXN0X2phdmFfaW9fRmlsZUlucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fRmlsZU5vdEZvdW5kRXhjZXB0aW9uXG5UZXN0X2phdmFfaW9fRmlsZU91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0ZpbHRlcklucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fRmlsdGVyT3V0cHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fSW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19JT0V4Y2VwdGlvblxuVGVzdF9qYXZhX2lvX091dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX1ByaW50U3RyZWFtXG5UZXN0X2phdmFfaW9fUmFuZG9tQWNjZXNzRmlsZVxuVGVzdF9qYXZhX2lvX1N5bmNGYWlsZWRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0Fic3RyYWN0TWV0aG9kRXJyb3JcblRlc3RfamF2YV9sYW5nX0FyaXRobWV0aWNFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0FycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQXJyYXlTdG9yZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQm9vbGVhblxuVGVzdF9qYXZhX2xhbmdfQnl0ZVxuVGVzdF9qYXZhX2xhbmdfQ2hhcmFjdGVyXG5UZXN0X2phdmFfbGFuZ19DbGFzc1xuVGVzdF9qYXZhX2xhbmdfQ2xhc3NDYXN0RXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19DbGFzc0NpcmN1bGFyaXR5RXJyb3JcblRlc3RfamF2YV9sYW5nX0NsYXNzRm9ybWF0RXJyb3JcblRlc3RfamF2YV9sYW5nX0NsYXNzTG9hZGVyXG5UZXN0X2phdmFfbGFuZ19DbGFzc05vdEZvdW5kRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19DbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfRG91YmxlXG5UZXN0X2phdmFfbGFuZ19FcnJvclxuVGVzdF9qYXZhX2xhbmdfRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19FeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3JcblRlc3RfamF2YV9sYW5nX0Zsb2F0XG5UZXN0X2phdmFfbGFuZ19JbGxlZ2FsQWNjZXNzRXJyb3JcblRlc3RfamF2YV9sYW5nX0lsbGVnYWxBY2Nlc3NFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbmNvbXBhdGlibGVDbGFzc0NoYW5nZUVycm9yXG5UZXN0X2phdmFfbGFuZ19JbmRleE91dE9mQm91bmRzRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbnN0YW50aWF0aW9uRXJyb3JcblRlc3RfamF2YV9sYW5nX0luc3RhbnRpYXRpb25FeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0ludGVnZXJcblRlc3RfamF2YV9sYW5nX0ludGVybmFsRXJyb3JcblRlc3RfamF2YV9sYW5nX0ludGVycnVwdGVkRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19MaW5rYWdlRXJyb3JcblRlc3RfamF2YV9sYW5nX0xvbmdcblRlc3RfamF2YV9sYW5nX01hdGhcblRlc3RfamF2YV9sYW5nX05lZ2F0aXZlQXJyYXlTaXplRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19Ob0NsYXNzRGVmRm91bmRFcnJvclxuVGVzdF9qYXZhX2xhbmdfTm9TdWNoRmllbGRFcnJvclxuVGVzdF9qYXZhX2xhbmdfTm9TdWNoTWV0aG9kRXJyb3JcblRlc3RfamF2YV9sYW5nX051bGxQb2ludGVyRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19OdW1iZXJcblRlc3RfamF2YV9sYW5nX051bWJlckZvcm1hdEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfT2JqZWN0XG5UZXN0X2phdmFfbGFuZ19PdXRPZk1lbW9yeUVycm9yXG5UZXN0X2phdmFfbGFuZ19SdW50aW1lRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19TZWN1cml0eU1hbmFnZXJcblRlc3RfamF2YV9sYW5nX1Nob3J0XG5UZXN0X2phdmFfbGFuZ19TdGFja092ZXJmbG93RXJyb3JcblRlc3RfamF2YV9sYW5nX1N0cmluZ1xuVGVzdF9qYXZhX2xhbmdfU3RyaW5nQnVmZmVyXG5UZXN0X2phdmFfbGFuZ19TdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19TeXN0ZW1cblRlc3RfamF2YV9sYW5nX1RocmVhZFxuVGVzdF9qYXZhX2xhbmdfVGhyZWFkRGVhdGhcblRlc3RfamF2YV9sYW5nX1RocmVhZEdyb3VwXG5UZXN0X2phdmFfbGFuZ19UaHJvd2FibGVcblRlc3RfamF2YV9sYW5nX1Vua25vd25FcnJvclxuVGVzdF9qYXZhX2xhbmdfVW5zYXRpc2ZpZWRMaW5rRXJyb3JcblRlc3RfamF2YV9sYW5nX1ZlcmlmeUVycm9yXG5UZXN0X2phdmFfbGFuZ19WaXJ0dWFsTWFjaGluZUVycm9yXG5UZXN0X2phdmFfbGFuZ192bV9JbWFnZVxuVGVzdF9qYXZhX2xhbmdfdm1fTWVtb3J5U2VnbWVudFxuVGVzdF9qYXZhX2xhbmdfdm1fUk9NU3RvcmVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX3ZtX1ZNXG5UZXN0X2phdmFfbGFuZ19Wb2lkXG5UZXN0X2phdmFfbmV0X0JpbmRFeGNlcHRpb25cblRlc3RfamF2YV9uZXRfQ29ubmVjdEV4Y2VwdGlvblxuVGVzdF9qYXZhX25ldF9EYXRhZ3JhbVBhY2tldFxuVGVzdF9qYXZhX25ldF9EYXRhZ3JhbVNvY2tldFxuVGVzdF9qYXZhX25ldF9EYXRhZ3JhbVNvY2tldEltcGxcblRlc3RfamF2YV9uZXRfSW5ldEFkZHJlc3NcblRlc3RfamF2YV9uZXRfTm9Sb3V0ZVRvSG9zdEV4Y2VwdGlvblxuVGVzdF9qYXZhX25ldF9QbGFpbkRhdGFncmFtU29ja2V0SW1wbFxuVGVzdF9qYXZhX25ldF9QbGFpblNvY2tldEltcGxcblRlc3RfamF2YV9uZXRfU29ja2V0XG5UZXN0X2phdmFfbmV0X1NvY2tldEV4Y2VwdGlvblxuVGVzdF9qYXZhX25ldF9Tb2NrZXRJbXBsXG5UZXN0X2phdmFfbmV0X1NvY2tldElucHV0U3RyZWFtXG5UZXN0X2phdmFfbmV0X1NvY2tldE91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX25ldF9Vbmtub3duSG9zdEV4Y2VwdGlvblxuVGVzdF9qYXZhX3V0aWxfQXJyYXlFbnVtZXJhdG9yXG5UZXN0X2phdmFfdXRpbF9EYXRlXG5UZXN0X2phdmFfdXRpbF9FdmVudE9iamVjdFxuVGVzdF9qYXZhX3V0aWxfSGFzaEVudW1lcmF0b3JcblRlc3RfamF2YV91dGlsX0hhc2h0YWJsZVxuVGVzdF9qYXZhX3V0aWxfUHJvcGVydGllc1xuVGVzdF9qYXZhX3V0aWxfUmVzb3VyY2VCdW5kbGVcblRlc3RfamF2YV91dGlsX3RtXG5UZXN0X2phdmFfdXRpbF9WZWN0b3JcbiI7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fT3V0cHV0U3RyZWFtKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmFvcyA9IG5ldyBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgb3MgPSBuZXcgamF2YS5pby5CdWZmZXJlZE91dHB1dFN0cmVhbShiYW9zKTsKKyAgICAgICAgICAgIG9zLndyaXRlKGZpbGVTdHJpbmcuZ2V0Qnl0ZXMoKSwgMCwgNTAwKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJDb25zdHJ1Y3RvciB0ZXN0IGZhaWxlZCIpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fT3V0cHV0U3RyZWFtSSgpIHsKKyAgICAgICAgYmFvcyA9IG5ldyBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcyA9IG5ldyBqYXZhLmlvLkJ1ZmZlcmVkT3V0cHV0U3RyZWFtKGJhb3MsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9zID0gbmV3IGphdmEuaW8uQnVmZmVyZWRPdXRwdXRTdHJlYW0oYmFvcywgMTAyNCk7CisgICAgICAgICAgICBvcy53cml0ZShmaWxlU3RyaW5nLmdldEJ5dGVzKCksIDAsIDUwMCk7CisgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBVbmV4cGVjdGVkIElPRXhjZXB0aW9uLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9mbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIG9zID0gbmV3IGphdmEuaW8uQnVmZmVyZWRPdXRwdXRTdHJlYW0oYmFvcywgNjAwKTsKKyAgICAgICAgb3Mud3JpdGUoZmlsZVN0cmluZy5nZXRCeXRlcygpLCAwLCA1MDApOworICAgICAgICBvcy5mbHVzaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogQnl0ZXMgbm90IHdyaXR0ZW4gYWZ0ZXIgZmx1c2g7IiwKKyAgICAgICAgICAgICAgICA1MDAsICgoQnl0ZUFycmF5T3V0cHV0U3RyZWFtKSBiYW9zKS5zaXplKCkpOworICAgICAgICBvcy5jbG9zZSgpOworCisgICAgICAgIHNvcyA9IG5ldyBTdXBwb3J0X091dHB1dFN0cmVhbSh0cnVlKTsKKyAgICAgICAgb3MgPSBuZXcgQnVmZmVyZWRPdXRwdXRTdHJlYW0oc29zLCAxMCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcy5mbHVzaCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgLy8gVG8gYXZvaWQgZXhjZXB0aW9uIGR1cmluZyB0ZWFyRG93bigpLgorICAgICAgICBzb3Muc2V0VGhyb3dzRXhjZXB0aW9uKGZhbHNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlJEJJSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9zID0gbmV3IGphdmEuaW8uQnVmZmVyZWRPdXRwdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgYmFvcyA9IG5ldyBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbSgpLDUxMik7CisgICAgICAgIG9zLndyaXRlKGZpbGVTdHJpbmcuZ2V0Qnl0ZXMoKSwgMCwgNTAwKTsKKyAgICAgICAgYmFpcyA9IG5ldyBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtKGJhb3MudG9CeXRlQXJyYXkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBCeXRlcyB3cml0dGVuLCBub3QgYnVmZmVyZWQ7IiwKKyAgICAgICAgICAgICAgICAwLCBiYWlzLmF2YWlsYWJsZSgpKTsKKyAgICAgICAgb3MuZmx1c2goKTsKKyAgICAgICAgYmFpcyA9IG5ldyBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtKGJhb3MudG9CeXRlQXJyYXkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBCeXRlcyBub3Qgd3JpdHRlbiBhZnRlciBmbHVzaDsiLAorICAgICAgICAgICAgICAgIDUwMCwgYmFpcy5hdmFpbGFibGUoKSk7CisgICAgICAgIG9zLndyaXRlKGZpbGVTdHJpbmcuZ2V0Qnl0ZXMoKSwgNTAwLCA1MTMpOworICAgICAgICBiYWlzID0gbmV3IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvcy50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAzOiBCeXRlcyBub3Qgd3JpdHRlbiB3aGVuIGJ1ZmZlciBmdWxsLiIsCisgICAgICAgICAgICAgICAgYmFpcy5hdmFpbGFibGUoKSA+PSAxMDAwKTsKKyAgICAgICAgYnl0ZVtdIHdieXRlcyA9IG5ldyBieXRlWzEwMTNdOworICAgICAgICBiYWlzLnJlYWQod2J5dGVzLCAwLCAxMDEzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCA0OiBJbmNvcnJlY3QgYnl0ZXMgd3JpdHRlbiBvciByZWFkLiIsCisgICAgICAgICAgICAgICAgZmlsZVN0cmluZy5zdWJzdHJpbmcoMCwgMTAxMykuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZyh3Ynl0ZXMsIDAsIHdieXRlcy5sZW5ndGgpKSk7CisgICAgICAgIG9zLmNsb3NlKCk7CisKKyAgICAgICAgc29zID0gbmV3IFN1cHBvcnRfT3V0cHV0U3RyZWFtKHRydWUpOworICAgICAgICBvcyA9IG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShzb3MsIDEwKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9zLndyaXRlKGZpbGVTdHJpbmcuZ2V0Qnl0ZXMoKSwgMCwgNTAwKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIC8vIFRvIGF2b2lkIGV4Y2VwdGlvbiBkdXJpbmcgdGVhckRvd24oKS4KKyAgICAgICAgc29zLnNldFRocm93c0V4Y2VwdGlvbihmYWxzZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZSRCSUlfRXhjZXB0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgT3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCkpOworICAgICAgICBieXRlW10gbnVsbEJ5dGVBcnJheSA9IG51bGw7CisgICAgICAgIGJ5dGVbXSBieXRlQXJyYXkgPSBuZXcgYnl0ZVsxMF07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJvcy53cml0ZShudWxsQnl0ZUFycmF5LCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJvcy53cml0ZShieXRlQXJyYXksIC0xLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJvcy53cml0ZShieXRlQXJyYXksIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJvcy53cml0ZShieXRlQXJyYXksIDEsIDEwKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZUkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBiYW9zID0gbmV3IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIG9zID0gbmV3IGphdmEuaW8uQnVmZmVyZWRPdXRwdXRTdHJlYW0oYmFvcyk7CisgICAgICAgIG9zLndyaXRlKCd0Jyk7CisgICAgICAgIGJhaXMgPSBuZXcgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbShiYW9zLnRvQnl0ZUFycmF5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogQnl0ZSB3cml0dGVuLCBub3QgYnVmZmVyZWQ7IiwKKyAgICAgICAgICAgICAgICAwLCBiYWlzLmF2YWlsYWJsZSgpKTsKKyAgICAgICAgb3MuZmx1c2goKTsKKyAgICAgICAgYmFpcyA9IG5ldyBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtKGJhb3MudG9CeXRlQXJyYXkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBCeXRlIG5vdCB3cml0dGVuIGFmdGVyIGZsdXNoOyIsCisgICAgICAgICAgICAgICAgMSwgYmFpcy5hdmFpbGFibGUoKSk7CisgICAgICAgIGJ5dGVbXSB3Ynl0ZXMgPSBuZXcgYnl0ZVsxXTsKKyAgICAgICAgYmFpcy5yZWFkKHdieXRlcywgMCwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAzOiBJbmNvcnJlY3QgYnl0ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICAndCcsIHdieXRlc1swXSk7CisgICAgICAgIG9zLmNsb3NlKCk7CisKKyAgICAgICAgc29zID0gbmV3IFN1cHBvcnRfT3V0cHV0U3RyZWFtKHRydWUpOworICAgICAgICBvcyA9IG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShzb3MsIDEpOworICAgICAgICBvcy53cml0ZSgndCcpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gRXhjZXB0aW9uIGlzIG9ubHkgdGhyb3duIHdoZW4gdGhlIGJ1ZmZlciBpcyBmbHVzaGVkLgorICAgICAgICAgICAgb3Mud3JpdGUoJ2UnKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIC8vIFRvIGF2b2lkIGV4Y2VwdGlvbiBkdXJpbmcgdGVhckRvd24oKS4KKyAgICAgICAgc29zLnNldFRocm93c0V4Y2VwdGlvbihmYWxzZSk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoYmFpcyAhPSBudWxsKQorICAgICAgICAgICAgICAgIGJhaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIGlmIChvcyAhPSBudWxsKQorICAgICAgICAgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgICAgICBpZiAoYmFvcyAhPSBudWxsKQorICAgICAgICAgICAgICAgIGJhb3MuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXhjZXB0aW9uIGR1cmluZyB0ZWFyRG93biIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRCdWZmZXJlZFJlYWRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQnVmZmVyZWRSZWFkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjE0YzFiMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQnVmZmVyZWRSZWFkZXJUZXN0LmphdmEKQEAgLTAsMCArMSwzMjEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZFJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLkNoYXJBcnJheVJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUGlwZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CitpbXBvcnQgamF2YS5pby5TdHJpbmdSZWFkZXI7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0FTaW1wbGVSZWFkZXI7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1N0cmluZ1JlYWRlcjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlRocm93aW5nUmVhZGVyOworCitwdWJsaWMgY2xhc3MgT2xkQnVmZmVyZWRSZWFkZXJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIEJ1ZmZlcmVkUmVhZGVyIGJyOworCisgICAgU3RyaW5nIHRlc3RTdHJpbmcgPSAiVGVzdF9BbGxfVGVzdHNcblRlc3RfamF2YV9pb19CdWZmZXJlZElucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fQnVmZmVyZWRPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19CeXRlQXJyYXlJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0J5dGVBcnJheU91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0RhdGFJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0ZpbGVcblRlc3RfamF2YV9pb19GaWxlRGVzY3JpcHRvclxuVGVzdF9qYXZhX2lvX0ZpbGVJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0ZpbGVOb3RGb3VuZEV4Y2VwdGlvblxuVGVzdF9qYXZhX2lvX0ZpbGVPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19GaWx0ZXJJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0ZpbHRlck91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0lucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fSU9FeGNlcHRpb25cblRlc3RfamF2YV9pb19PdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19QcmludFN0cmVhbVxuVGVzdF9qYXZhX2lvX1JhbmRvbUFjY2Vzc0ZpbGVcblRlc3RfamF2YV9pb19TeW5jRmFpbGVkRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19BYnN0cmFjdE1ldGhvZEVycm9yXG5UZXN0X2phdmFfbGFuZ19Bcml0aG1ldGljRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0FycmF5U3RvcmVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0Jvb2xlYW5cblRlc3RfamF2YV9sYW5nX0J5dGVcblRlc3RfamF2YV9sYW5nX0NoYXJhY3RlclxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NcblRlc3RfamF2YV9sYW5nX0NsYXNzQ2FzdEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NDaXJjdWxhcml0eUVycm9yXG5UZXN0X2phdmFfbGFuZ19DbGFzc0Zvcm1hdEVycm9yXG5UZXN0X2phdmFfbGFuZ19DbGFzc0xvYWRlclxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0RvdWJsZVxuVGVzdF9qYXZhX2xhbmdfRXJyb3JcblRlc3RfamF2YV9sYW5nX0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfRXhjZXB0aW9uSW5Jbml0aWFsaXplckVycm9yXG5UZXN0X2phdmFfbGFuZ19GbG9hdFxuVGVzdF9qYXZhX2xhbmdfSWxsZWdhbEFjY2Vzc0Vycm9yXG5UZXN0X2phdmFfbGFuZ19JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0lsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0lsbGVnYWxUaHJlYWRTdGF0ZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSW5jb21wYXRpYmxlQ2xhc3NDaGFuZ2VFcnJvclxuVGVzdF9qYXZhX2xhbmdfSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSW5zdGFudGlhdGlvbkVycm9yXG5UZXN0X2phdmFfbGFuZ19JbnN0YW50aWF0aW9uRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbnRlZ2VyXG5UZXN0X2phdmFfbGFuZ19JbnRlcm5hbEVycm9yXG5UZXN0X2phdmFfbGFuZ19JbnRlcnJ1cHRlZEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfTGlua2FnZUVycm9yXG5UZXN0X2phdmFfbGFuZ19Mb25nXG5UZXN0X2phdmFfbGFuZ19NYXRoXG5UZXN0X2phdmFfbGFuZ19OZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfTm9DbGFzc0RlZkZvdW5kRXJyb3JcblRlc3RfamF2YV9sYW5nX05vU3VjaEZpZWxkRXJyb3JcblRlc3RfamF2YV9sYW5nX05vU3VjaE1ldGhvZEVycm9yXG5UZXN0X2phdmFfbGFuZ19OdWxsUG9pbnRlckV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfTnVtYmVyXG5UZXN0X2phdmFfbGFuZ19OdW1iZXJGb3JtYXRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX09iamVjdFxuVGVzdF9qYXZhX2xhbmdfT3V0T2ZNZW1vcnlFcnJvclxuVGVzdF9qYXZhX2xhbmdfUnVudGltZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfU2VjdXJpdHlNYW5hZ2VyXG5UZXN0X2phdmFfbGFuZ19TaG9ydFxuVGVzdF9qYXZhX2xhbmdfU3RhY2tPdmVyZmxvd0Vycm9yXG5UZXN0X2phdmFfbGFuZ19TdHJpbmdcblRlc3RfamF2YV9sYW5nX1N0cmluZ0J1ZmZlclxuVGVzdF9qYXZhX2xhbmdfU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfU3lzdGVtXG5UZXN0X2phdmFfbGFuZ19UaHJlYWRcblRlc3RfamF2YV9sYW5nX1RocmVhZERlYXRoXG5UZXN0X2phdmFfbGFuZ19UaHJlYWRHcm91cFxuVGVzdF9qYXZhX2xhbmdfVGhyb3dhYmxlXG5UZXN0X2phdmFfbGFuZ19Vbmtub3duRXJyb3JcblRlc3RfamF2YV9sYW5nX1Vuc2F0aXNmaWVkTGlua0Vycm9yXG5UZXN0X2phdmFfbGFuZ19WZXJpZnlFcnJvclxuVGVzdF9qYXZhX2xhbmdfVmlydHVhbE1hY2hpbmVFcnJvclxuVGVzdF9qYXZhX2xhbmdfdm1fSW1hZ2VcblRlc3RfamF2YV9sYW5nX3ZtX01lbW9yeVNlZ21lbnRcblRlc3RfamF2YV9sYW5nX3ZtX1JPTVN0b3JlRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ192bV9WTVxuVGVzdF9qYXZhX2xhbmdfVm9pZFxuVGVzdF9qYXZhX25ldF9CaW5kRXhjZXB0aW9uXG5UZXN0X2phdmFfbmV0X0Nvbm5lY3RFeGNlcHRpb25cblRlc3RfamF2YV9uZXRfRGF0YWdyYW1QYWNrZXRcblRlc3RfamF2YV9uZXRfRGF0YWdyYW1Tb2NrZXRcblRlc3RfamF2YV9uZXRfRGF0YWdyYW1Tb2NrZXRJbXBsXG5UZXN0X2phdmFfbmV0X0luZXRBZGRyZXNzXG5UZXN0X2phdmFfbmV0X05vUm91dGVUb0hvc3RFeGNlcHRpb25cblRlc3RfamF2YV9uZXRfUGxhaW5EYXRhZ3JhbVNvY2tldEltcGxcblRlc3RfamF2YV9uZXRfUGxhaW5Tb2NrZXRJbXBsXG5UZXN0X2phdmFfbmV0X1NvY2tldFxuVGVzdF9qYXZhX25ldF9Tb2NrZXRFeGNlcHRpb25cblRlc3RfamF2YV9uZXRfU29ja2V0SW1wbFxuVGVzdF9qYXZhX25ldF9Tb2NrZXRJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX25ldF9Tb2NrZXRPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9uZXRfVW5rbm93bkhvc3RFeGNlcHRpb25cblRlc3RfamF2YV91dGlsX0FycmF5RW51bWVyYXRvclxuVGVzdF9qYXZhX3V0aWxfRGF0ZVxuVGVzdF9qYXZhX3V0aWxfRXZlbnRPYmplY3RcblRlc3RfamF2YV91dGlsX0hhc2hFbnVtZXJhdG9yXG5UZXN0X2phdmFfdXRpbF9IYXNodGFibGVcblRlc3RfamF2YV91dGlsX1Byb3BlcnRpZXNcblRlc3RfamF2YV91dGlsX1Jlc291cmNlQnVuZGxlXG5UZXN0X2phdmFfdXRpbF90bVxuVGVzdF9qYXZhX3V0aWxfVmVjdG9yXG4iOworCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX1JlYWRlcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEuaW8uQnVmZmVyZWRSZWFkZXIoamF2YS5pby5SZWFkZXIpCisgICAgICAgIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBTdXBwb3J0X1N0cmluZ1JlYWRlcih0ZXN0U3RyaW5nKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoYnIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9pb19SZWFkZXJJKCkgeworICAgICAgICAvLyBJbGxlZ2FsIG5lZ2F0aXZlIHNpemUgYXJndW1lbnQgdGVzdC4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBTdXBwb3J0X1N0cmluZ1JlYWRlcih0ZXN0U3RyaW5nKSwgMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgYnIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IFN1cHBvcnRfU3RyaW5nUmVhZGVyKHRlc3RTdHJpbmcpLCAxMDI0KTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChicik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jbG9zZSgpIHsKKyAgICAgICAgU3VwcG9ydF9BU2ltcGxlUmVhZGVyIHNzciA9IG5ldyBTdXBwb3J0X0FTaW1wbGVSZWFkZXIodHJ1ZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgU3VwcG9ydF9TdHJpbmdSZWFkZXIodGVzdFN0cmluZykpOworICAgICAgICAgICAgYnIuY2xvc2UoKTsKKyAgICAgICAgICAgIGJyLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogUmVhZCBvbiBjbG9zZWQgc3RyZWFtLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiB4KSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgY2xvc2UgdGVzdCAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKHNzcik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBici5jbG9zZSgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgLy8gQXZvaWQgSU9FeGNlcHRpb24gaW4gdGVhckRvd24oKS4KKyAgICAgICAgc3NyLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gZmFsc2U7CisgICAgfQorCisJcHVibGljIHZvaWQgdGVzdF9tYXJrSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEuaW8uQnVmZmVyZWRSZWFkZXIubWFyayhpbnQpCisgICAgICAgIGNoYXJbXSBidWYgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IFN1cHBvcnRfU3RyaW5nUmVhZGVyKHRlc3RTdHJpbmcpKTsKKyAgICAgICAgICAgIGJyLnNraXAoNTAwKTsKKyAgICAgICAgICAgIGJyLm1hcmsoMTAwMCk7CisgICAgICAgICAgICBici5za2lwKDI1MCk7CisgICAgICAgICAgICBici5yZXNldCgpOworICAgICAgICAgICAgYnVmID0gbmV3IGNoYXJbdGVzdFN0cmluZy5sZW5ndGgoKV07CisgICAgICAgICAgICBici5yZWFkKGJ1ZiwgMCwgNTAwKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBzZXQgbWFyayBwcm9wZXJseSIsIHRlc3RTdHJpbmcuc3Vic3RyaW5nKDUwMCwKKyAgICAgICAgICAgICAgICAgICAgMTAwMCkuZXF1YWxzKG5ldyBTdHJpbmcoYnVmLCAwLCA1MDApKSk7CisgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBtYXJrIHRlc3QiKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYnIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IFN1cHBvcnRfU3RyaW5nUmVhZGVyKHRlc3RTdHJpbmcpLCA4MDApOworICAgICAgICAgICAgYnIuc2tpcCg1MDApOworICAgICAgICAgICAgYnIubWFyaygyNTApOworICAgICAgICAgICAgYnIucmVhZChidWYsIDAsIDEwMDApOworICAgICAgICAgICAgYnIucmVzZXQoKTsKKyAgICAgICAgICAgIGZhaWwoIkZhaWxlZCB0byBpbnZhbGlkYXRlIG1hcmsgcHJvcGVybHkiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24geCkgeworICAgICAgICB9CisKKyAgICAgICAgY2hhcltdIGNoYXJzID0gbmV3IGNoYXJbMjU2XTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyNTY7IGkrKykKKyAgICAgICAgICAgIGNoYXJzW2ldID0gKGNoYXIpIGk7CisgICAgICAgIFJlYWRlciBpbiA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgU3VwcG9ydF9TdHJpbmdSZWFkZXIobmV3IFN0cmluZygKKyAgICAgICAgICAgICAgICBjaGFycykpLCAxMik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbi5za2lwKDYpOworICAgICAgICAgICAgaW4ubWFyaygxNCk7CisgICAgICAgICAgICBpbi5yZWFkKG5ldyBjaGFyWzE0XSwgMCwgMTQpOworICAgICAgICAgICAgaW4ucmVzZXQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIldyb25nIGNoYXJzIiwgaW4ucmVhZCgpID09IChjaGFyKSA2CisgICAgICAgICAgICAgICAgICAgICYmIGluLnJlYWQoKSA9PSAoY2hhcikgNyk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgbWFyayB0ZXN0IDI6IiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgaW4gPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IFN1cHBvcnRfU3RyaW5nUmVhZGVyKG5ldyBTdHJpbmcoY2hhcnMpKSwgMTIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4uc2tpcCg2KTsKKyAgICAgICAgICAgIGluLm1hcmsoOCk7CisgICAgICAgICAgICBpbi5za2lwKDcpOworICAgICAgICAgICAgaW4ucmVzZXQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIldyb25nIGNoYXJzIDIiLCBpbi5yZWFkKCkgPT0gKGNoYXIpIDYKKyAgICAgICAgICAgICAgICAgICAgJiYgaW4ucmVhZCgpID09IChjaGFyKSA3KTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBtYXJrIHRlc3QgMzoiICsgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X21hcmtTdXBwb3J0ZWQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEuaW8uQnVmZmVyZWRSZWFkZXIubWFya1N1cHBvcnRlZCgpCisgICAgICAgIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBTdXBwb3J0X1N0cmluZ1JlYWRlcih0ZXN0U3RyaW5nKSk7CisgICAgICAgIGFzc2VydFRydWUoIm1hcmtTdXBwb3J0ZWQgcmV0dXJuZWQgZmFsc2UuIiwgYnIubWFya1N1cHBvcnRlZCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdXBwb3J0X0FTaW1wbGVSZWFkZXIgc3NyID0gbmV3IFN1cHBvcnRfQVNpbXBsZVJlYWRlcih0cnVlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBTdXBwb3J0X1N0cmluZ1JlYWRlcih0ZXN0U3RyaW5nKSk7CisgICAgICAgICAgICBpbnQgciA9IGJyLnJlYWQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkNoYXIgcmVhZCBpbXByb3Blcmx5IiwgdGVzdFN0cmluZy5jaGFyQXQoMCkgPT0gcik7CisgICAgICAgICAgICBiciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgU3VwcG9ydF9TdHJpbmdSZWFkZXIobmV3IFN0cmluZygKKyAgICAgICAgICAgICAgICAgICAgbmV3IGNoYXJbXSB7ICdcdTg3NjUnIH0pKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBkb3VibGUgYnl0ZSBjaGFyYWN0ZXIiLCBici5yZWFkKCkgPT0gJ1x1ODc2NScpOworICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgcmVhZCB0ZXN0Iik7CisgICAgICAgIH0KKworICAgICAgICBjaGFyW10gY2hhcnMgPSBuZXcgY2hhclsyNTZdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDI1NjsgaSsrKQorICAgICAgICAgICAgY2hhcnNbaV0gPSAoY2hhcikgaTsKKyAgICAgICAgUmVhZGVyIGluID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBTdXBwb3J0X1N0cmluZ1JlYWRlcihuZXcgU3RyaW5nKAorICAgICAgICAgICAgICAgIGNoYXJzKSksIDEyKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgaW5pdGlhbCBjaGFyIiwgMCwgaW4ucmVhZCgpKTsgLy8gRmlsbCB0aGUKKyAgICAgICAgICAgIC8vIGJ1ZmZlcgorICAgICAgICAgICAgY2hhcltdIGJ1ZiA9IG5ldyBjaGFyWzE0XTsKKyAgICAgICAgICAgIGluLnJlYWQoYnVmLCAwLCAxNCk7IC8vIFJlYWQgZ3JlYXRlciB0aGFuIHRoZSBidWZmZXIKKyAgICAgICAgICAgIGFzc2VydFRydWUoIldyb25nIGJsb2NrIHJlYWQgZGF0YSIsIG5ldyBTdHJpbmcoYnVmKQorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKG5ldyBTdHJpbmcoY2hhcnMsIDEsIDE0KSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBjaGFycyIsIDE1LCBpbi5yZWFkKCkpOyAvLyBDaGVjayBuZXh0IGJ5dGUKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyByZWFkIHRlc3QgMjoiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICAvLyByZWdyZXNzaW9uIHRlc3QgZm9yIEhBUk1PTlktODQxCisgICAgICAgIGFzc2VydFRydWUobmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBDaGFyQXJyYXlSZWFkZXIobmV3IGNoYXJbNV0sIDEsIDApLCAyKS5yZWFkKCkgPT0gLTEpOworCisgICAgICAgIGJyLmNsb3NlKCk7CisgICAgICAgIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKHNzcik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBici5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgLy8gQXZvaWQgSU9FeGNlcHRpb24gaW4gdGVhckRvd24oKS4KKyAgICAgICAgc3NyLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkJENJSV9FeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IFN1cHBvcnRfU3RyaW5nUmVhZGVyKHRlc3RTdHJpbmcpKTsKKyAgICAgICAgdHJ5eworICAgICAgICAgICAgYnIucmVhZChuZXcgY2hhclsxMF0sIC0xLCAxKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeXsKKyAgICAgICAgICAgIGJyLnJlYWQobmV3IGNoYXJbMTBdLCAwLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnl7CisgICAgICAgICAgICBici5yZWFkKG5ldyBjaGFyWzEwXSwgMTAsIDEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy9yZWdyZXNzaW9uIGZvciBIQVJNT05ZLTgzMQorICAgICAgICB0cnl7CisgICAgICAgICAgICBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IFBpcGVkUmVhZGVyKCksIDkpLnJlYWQobmV3IGNoYXJbXSB7fSwgNywgMCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiIpOworICAgICAgICB9Y2F0Y2goSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKXsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZExpbmUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbGluZTsKKyAgICAgICAgYnIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IFN1cHBvcnRfU3RyaW5nUmVhZGVyKCJMb3JlbVxuaXBzdW1ccmRvbG9yIHNpdCBhbWV0Li4uIikpOworCisgICAgICAgIGxpbmUgPSBici5yZWFkTGluZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IEluY29ycmVjdCBsaW5lIHdyaXR0ZW4gb3IgcmVhZDogIiArIGxpbmUsCisgICAgICAgICAgICAgICAgbGluZS5lcXVhbHMoIkxvcmVtIikpOworICAgICAgICBsaW5lID0gYnIucmVhZExpbmUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAyOiBJbmNvcnJlY3QgbGluZSB3cml0dGVuIG9yIHJlYWQ6ICIgKyBsaW5lLAorICAgICAgICAgICAgICAgIGxpbmUuZXF1YWxzKCJpcHN1bSIpKTsKKyAgICAgICAgbGluZSA9IGJyLnJlYWRMaW5lKCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMzogSW5jb3JyZWN0IGxpbmUgd3JpdHRlbiBvciByZWFkOiAiICsgbGluZSwKKyAgICAgICAgICAgICAgICBsaW5lLmVxdWFscygiZG9sb3Igc2l0IGFtZXQuLi4iKSk7CisKKyAgICAgICAgYnIuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJyLnJlYWRMaW5lKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdXBwb3J0X0FTaW1wbGVSZWFkZXIgc3NyID0gbmV3IFN1cHBvcnRfQVNpbXBsZVJlYWRlcih0cnVlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBTdXBwb3J0X1N0cmluZ1JlYWRlcih0ZXN0U3RyaW5nKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IHJlYWR5KCkgcmV0dXJuZWQgZmFsc2UiLCBici5yZWFkeSgpKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHJlYWR5IHRlc3QiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIGJyLmNsb3NlKCk7CisgICAgICAgIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKHNzcik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBici5jbG9zZSgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgLy8gQXZvaWQgSU9FeGNlcHRpb24gaW4gdGVhckRvd24oKS4KKyAgICAgICAgc3NyLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9za2lwSigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN1cHBvcnRfQVNpbXBsZVJlYWRlciBzc3IgPSBuZXcgU3VwcG9ydF9BU2ltcGxlUmVhZGVyKHRydWUpOworICAgICAgICBiciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgU3VwcG9ydF9TdHJpbmdSZWFkZXIodGVzdFN0cmluZykpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBici5za2lwKC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBici5za2lwKDUwMCk7CisgICAgICAgIGNoYXJbXSBidWYgPSBuZXcgY2hhclt0ZXN0U3RyaW5nLmxlbmd0aCgpXTsKKyAgICAgICAgYnIucmVhZChidWYsIDAsIDUwMCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMjogRmFpbGVkIHRvIHNldCBza2lwIHByb3Blcmx5LiIsCisgICAgICAgICAgICAgICAgdGVzdFN0cmluZy5zdWJzdHJpbmcoNTAwLCAxMDAwKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKGJ1ZiwgMCwgNTAwKSkpOworCisgICAgICAgIGJyLmNsb3NlKCk7CisgICAgICAgIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKHNzcik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBici5za2lwKDEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgLy8gQXZvaWQgSU9FeGNlcHRpb24gaW4gdGVhckRvd24oKS4KKyAgICAgICAgc3NyLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRaZXJvTGVuZ3RoQXJyYXkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBiciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgU3VwcG9ydF9TdHJpbmdSZWFkZXIoIkFCQ0RFRiIpKTsKKyAgICAgICAgYnIucmVhZCgpOworICAgICAgICBici5yZWFkKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBici5yZWFkKG5ldyBjaGFyWzZdLCAzLCAwKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNvdXJjZVRocm93c1dpdGhNYXJrKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IFRocm93aW5nUmVhZGVyKAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdSZWFkZXIoIkFCQ0RFRkdISSIpLCA0KSk7CisKKyAgICAgICAgYnIucmVhZCgpOworICAgICAgICBici5yZWFkKCk7CisgICAgICAgIGJyLm1hcmsoMTApOworICAgICAgICBici5yZWFkKCk7CisgICAgICAgIGJyLnJlYWQoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnIucmVhZCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBmcm9tVGhyb3dpbmdSZWFkZXIpIHsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygnRScsIGJyLnJlYWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygnRicsIGJyLnJlYWQoKSk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBici5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRCdWZmZXJlZFdyaXRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQnVmZmVyZWRXcml0ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWQ1Yjg2MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQnVmZmVyZWRXcml0ZXJUZXN0LmphdmEKQEAgLTAsMCArMSwzMTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZFdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9BU2ltcGxlV3JpdGVyOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9TdHJpbmdXcml0ZXI7CisKK3B1YmxpYyBjbGFzcyBPbGRCdWZmZXJlZFdyaXRlclRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgQnVmZmVyZWRXcml0ZXIgYnc7CisKKyAgICBTdXBwb3J0X1N0cmluZ1dyaXRlciBzdzsKKworICAgIFN1cHBvcnRfQVNpbXBsZVdyaXRlciBzc3c7CisKKyAgICBwdWJsaWMgU3RyaW5nIHRlc3RTdHJpbmcgPSAiVGVzdF9BbGxfVGVzdHNcblRlc3RfamF2YV9pb19CdWZmZXJlZElucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fQnVmZmVyZWRPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19CeXRlQXJyYXlJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0J5dGVBcnJheU91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0RhdGFJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0ZpbGVcblRlc3RfamF2YV9pb19GaWxlRGVzY3JpcHRvclxuVGVzdF9qYXZhX2lvX0ZpbGVJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0ZpbGVOb3RGb3VuZEV4Y2VwdGlvblxuVGVzdF9qYXZhX2lvX0ZpbGVPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19GaWx0ZXJJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0ZpbHRlck91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0lucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fSU9FeGNlcHRpb25cblRlc3RfamF2YV9pb19PdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19QcmludFN0cmVhbVxuVGVzdF9qYXZhX2lvX1JhbmRvbUFjY2Vzc0ZpbGVcblRlc3RfamF2YV9pb19TeW5jRmFpbGVkRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19BYnN0cmFjdE1ldGhvZEVycm9yXG5UZXN0X2phdmFfbGFuZ19Bcml0aG1ldGljRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0FycmF5U3RvcmVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0Jvb2xlYW5cblRlc3RfamF2YV9sYW5nX0J5dGVcblRlc3RfamF2YV9sYW5nX0NoYXJhY3RlclxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NcblRlc3RfamF2YV9sYW5nX0NsYXNzQ2FzdEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NDaXJjdWxhcml0eUVycm9yXG5UZXN0X2phdmFfbGFuZ19DbGFzc0Zvcm1hdEVycm9yXG5UZXN0X2phdmFfbGFuZ19DbGFzc0xvYWRlclxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0RvdWJsZVxuVGVzdF9qYXZhX2xhbmdfRXJyb3JcblRlc3RfamF2YV9sYW5nX0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfRXhjZXB0aW9uSW5Jbml0aWFsaXplckVycm9yXG5UZXN0X2phdmFfbGFuZ19GbG9hdFxuVGVzdF9qYXZhX2xhbmdfSWxsZWdhbEFjY2Vzc0Vycm9yXG5UZXN0X2phdmFfbGFuZ19JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0lsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0lsbGVnYWxUaHJlYWRTdGF0ZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSW5jb21wYXRpYmxlQ2xhc3NDaGFuZ2VFcnJvclxuVGVzdF9qYXZhX2xhbmdfSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSW5zdGFudGlhdGlvbkVycm9yXG5UZXN0X2phdmFfbGFuZ19JbnN0YW50aWF0aW9uRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbnRlZ2VyXG5UZXN0X2phdmFfbGFuZ19JbnRlcm5hbEVycm9yXG5UZXN0X2phdmFfbGFuZ19JbnRlcnJ1cHRlZEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfTGlua2FnZUVycm9yXG5UZXN0X2phdmFfbGFuZ19Mb25nXG5UZXN0X2phdmFfbGFuZ19NYXRoXG5UZXN0X2phdmFfbGFuZ19OZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfTm9DbGFzc0RlZkZvdW5kRXJyb3JcblRlc3RfamF2YV9sYW5nX05vU3VjaEZpZWxkRXJyb3JcblRlc3RfamF2YV9sYW5nX05vU3VjaE1ldGhvZEVycm9yXG5UZXN0X2phdmFfbGFuZ19OdWxsUG9pbnRlckV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfTnVtYmVyXG5UZXN0X2phdmFfbGFuZ19OdW1iZXJGb3JtYXRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX09iamVjdFxuVGVzdF9qYXZhX2xhbmdfT3V0T2ZNZW1vcnlFcnJvclxuVGVzdF9qYXZhX2xhbmdfUnVudGltZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfU2VjdXJpdHlNYW5hZ2VyXG5UZXN0X2phdmFfbGFuZ19TaG9ydFxuVGVzdF9qYXZhX2xhbmdfU3RhY2tPdmVyZmxvd0Vycm9yXG5UZXN0X2phdmFfbGFuZ19TdHJpbmdcblRlc3RfamF2YV9sYW5nX1N0cmluZ0J1ZmZlclxuVGVzdF9qYXZhX2xhbmdfU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfU3lzdGVtXG5UZXN0X2phdmFfbGFuZ19UaHJlYWRcblRlc3RfamF2YV9sYW5nX1RocmVhZERlYXRoXG5UZXN0X2phdmFfbGFuZ19UaHJlYWRHcm91cFxuVGVzdF9qYXZhX2xhbmdfVGhyb3dhYmxlXG5UZXN0X2phdmFfbGFuZ19Vbmtub3duRXJyb3JcblRlc3RfamF2YV9sYW5nX1Vuc2F0aXNmaWVkTGlua0Vycm9yXG5UZXN0X2phdmFfbGFuZ19WZXJpZnlFcnJvclxuVGVzdF9qYXZhX2xhbmdfVmlydHVhbE1hY2hpbmVFcnJvclxuVGVzdF9qYXZhX2xhbmdfdm1fSW1hZ2VcblRlc3RfamF2YV9sYW5nX3ZtX01lbW9yeVNlZ21lbnRcblRlc3RfamF2YV9sYW5nX3ZtX1JPTVN0b3JlRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ192bV9WTVxuVGVzdF9qYXZhX2xhbmdfVm9pZFxuVGVzdF9qYXZhX25ldF9CaW5kRXhjZXB0aW9uXG5UZXN0X2phdmFfbmV0X0Nvbm5lY3RFeGNlcHRpb25cblRlc3RfamF2YV9uZXRfRGF0YWdyYW1QYWNrZXRcblRlc3RfamF2YV9uZXRfRGF0YWdyYW1Tb2NrZXRcblRlc3RfamF2YV9uZXRfRGF0YWdyYW1Tb2NrZXRJbXBsXG5UZXN0X2phdmFfbmV0X0luZXRBZGRyZXNzXG5UZXN0X2phdmFfbmV0X05vUm91dGVUb0hvc3RFeGNlcHRpb25cblRlc3RfamF2YV9uZXRfUGxhaW5EYXRhZ3JhbVNvY2tldEltcGxcblRlc3RfamF2YV9uZXRfUGxhaW5Tb2NrZXRJbXBsXG5UZXN0X2phdmFfbmV0X1NvY2tldFxuVGVzdF9qYXZhX25ldF9Tb2NrZXRFeGNlcHRpb25cblRlc3RfamF2YV9uZXRfU29ja2V0SW1wbFxuVGVzdF9qYXZhX25ldF9Tb2NrZXRJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX25ldF9Tb2NrZXRPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9uZXRfVW5rbm93bkhvc3RFeGNlcHRpb25cblRlc3RfamF2YV91dGlsX0FycmF5RW51bWVyYXRvclxuVGVzdF9qYXZhX3V0aWxfRGF0ZVxuVGVzdF9qYXZhX3V0aWxfRXZlbnRPYmplY3RcblRlc3RfamF2YV91dGlsX0hhc2hFbnVtZXJhdG9yXG5UZXN0X2phdmFfdXRpbF9IYXNodGFibGVcblRlc3RfamF2YV91dGlsX1Byb3BlcnRpZXNcblRlc3RfamF2YV91dGlsX1Jlc291cmNlQnVuZGxlXG5UZXN0X2phdmFfdXRpbF90bVxuVGVzdF9qYXZhX3V0aWxfVmVjdG9yXG4iOworCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX1dyaXRlcigpIHsKKyAgICAgICAgYncgPSBuZXcgQnVmZmVyZWRXcml0ZXIoc3cpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYncud3JpdGUoIkhpIiwgMCwgMik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IEJ1ZmZlcmluZyBmYWlsZWQuIiwgc3cudG9TdHJpbmcoKS5lcXVhbHMoIiIpKTsKKyAgICAgICAgICAgIGJ3LmZsdXNoKCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMjogSW5jb3JyZWN0IHZhbHVlOyIsICJIaSIsIHN3LnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IFVuZXhwZWN0ZWQgSU9FeGNlcHRpb24uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fV3JpdGVySSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ3ID0gbmV3IEJ1ZmZlcmVkV3JpdGVyKHN3LCAwKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgYncgPSBuZXcgQnVmZmVyZWRXcml0ZXIoc3csIDEwKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ3LndyaXRlKCJIaSIsIDAsIDIpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAyOiBCdWZmZXJpbmcgZmFpbGVkLiIsIHN3LnRvU3RyaW5nKCkuZXF1YWxzKCIiKSk7CisgICAgICAgICAgICBidy5mbHVzaCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDM6IEluY29ycmVjdCB2YWx1ZTsiLCAiSGkiLCBzdy50b1N0cmluZygpKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBVbmV4cGVjdGVkIElPRXhjZXB0aW9uLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jbG9zZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS5pby5CdWZmZXJlZFdyaXRlci5jbG9zZSgpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidy5jbG9zZSgpOworICAgICAgICAgICAgYncud3JpdGUodGVzdFN0cmluZyk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZSgiVGVzdCAyOiBXcml0ZSBhZnRlciBjbG9zZS4iLCBzdy50b1N0cmluZygpLmVxdWFscyh0ZXN0U3RyaW5nKSk7CisKKyAgICAgICAgYncgPSBuZXcgQnVmZmVyZWRXcml0ZXIoc3N3KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ3LmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBidy53cml0ZSgiVGhpcyBzaG91bGQgbm90IGNhdXNlIGEgZmx1c2giKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBCeXRlcyB3cml0dGVuIHdpdGhvdXQgZmx1c2guIiwKKyAgICAgICAgICAgICAgICBzdy50b1N0cmluZygpLmVxdWFscygiIikpOworICAgICAgICBidy5mbHVzaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMjogQnl0ZXMgbm90IGZsdXNoZWQuIiwKKyAgICAgICAgICAgICAgICAiVGhpcyBzaG91bGQgbm90IGNhdXNlIGEgZmx1c2giLCBzdy50b1N0cmluZygpKTsKKworICAgICAgICBidy5jbG9zZSgpOworICAgICAgICBidyA9IG5ldyBCdWZmZXJlZFdyaXRlcihzc3cpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYncuZmx1c2goKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9uZXdMaW5lKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHNlcGFyYXRvciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgibGluZS5zZXBhcmF0b3IiKTsKKyAgICAgICAgYncud3JpdGUoIkhlbGxvIik7CisgICAgICAgIGJ3Lm5ld0xpbmUoKTsKKyAgICAgICAgYncud3JpdGUoIldvcmxkIik7CisgICAgICAgIGJ3LmZsdXNoKCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogSW5jb3JyZWN0IHN0cmluZyB3cml0dGVuOiAiICsgc3cudG9TdHJpbmcoKSwKKyAgICAgICAgICAgICAgICBzdy50b1N0cmluZygpLmVxdWFscygiSGVsbG8iICsgc2VwYXJhdG9yICsgIldvcmxkIikpOworCisgICAgICAgIGJ3LmNsb3NlKCk7CisgICAgICAgIGJ3ID0gbmV3IEJ1ZmZlcmVkV3JpdGVyKHNzdywgMSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidy5uZXdMaW5lKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZSRDSUkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEuaW8uQnVmZmVyZWRXcml0ZXIud3JpdGUoY2hhciBbXSwgaW50LCBpbnQpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGFyW10gdGVzdENoYXJBcnJheSA9IHRlc3RTdHJpbmcudG9DaGFyQXJyYXkoKTsKKyAgICAgICAgICAgIGJ3LndyaXRlKHRlc3RDaGFyQXJyYXksIDUwMCwgMTAwMCk7CisgICAgICAgICAgICBidy5mbHVzaCgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHN0cmluZyB3cml0dGVuIiwgc3cudG9TdHJpbmcoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgIHRlc3RTdHJpbmcuc3Vic3RyaW5nKDUwMCwgMTUwMCkpKTsKKworICAgICAgICAgICAgaW50IGlkeCA9IHN3LnRvU3RyaW5nKCkubGVuZ3RoKCk7CisgICAgICAgICAgICBidy53cml0ZSh0ZXN0Q2hhckFycmF5LCAwLCB0ZXN0Q2hhckFycmF5Lmxlbmd0aCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaWR4ICsgdGVzdENoYXJBcnJheS5sZW5ndGgsIHN3LnRvU3RyaW5nKCkubGVuZ3RoKCkpOworICAgICAgICAgICAgYncud3JpdGUodGVzdENoYXJBcnJheSwgMCwgMCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaWR4ICsgdGVzdENoYXJBcnJheS5sZW5ndGgsIHN3LnRvU3RyaW5nKCkubGVuZ3RoKCkpOworICAgICAgICAgICAgYncud3JpdGUodGVzdENoYXJBcnJheSwgdGVzdENoYXJBcnJheS5sZW5ndGgsIDApOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGlkeCArIHRlc3RDaGFyQXJyYXkubGVuZ3RoLCBzdy50b1N0cmluZygpLmxlbmd0aCgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgd3JpdGUgdGVzdCIpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlJENJSV9FeGNlcHRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGFyW10gbnVsbENoYXJBcnJheSA9IG51bGw7CisgICAgICAgIGNoYXJbXSBjaGFyQXJyYXkgPSB0ZXN0U3RyaW5nLnRvQ2hhckFycmF5KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ3LndyaXRlKG51bGxDaGFyQXJyYXksIDAsIDEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYncud3JpdGUoY2hhckFycmF5LCAtMSwgMCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidy53cml0ZShjaGFyQXJyYXksIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ3LndyaXRlKGNoYXJBcnJheSwgY2hhckFycmF5Lmxlbmd0aCArIDEsIDApOworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYncud3JpdGUoY2hhckFycmF5LCBjaGFyQXJyYXkubGVuZ3RoLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNTogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ3LndyaXRlKGNoYXJBcnJheSwgMCwgY2hhckFycmF5Lmxlbmd0aCArIDEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA2OiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYncud3JpdGUoY2hhckFycmF5LCAxLCBjaGFyQXJyYXkubGVuZ3RoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNzogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYncuY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYncud3JpdGUoY2hhckFycmF5LCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgYncgPSBuZXcgQnVmZmVyZWRXcml0ZXIoc3N3LCBjaGFyQXJyYXkubGVuZ3RoIC8gMik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidy53cml0ZShjaGFyQXJyYXksIDAsIGNoYXJBcnJheS5sZW5ndGgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA4OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ3LndyaXRlKCdUJyk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogQ2hhciB3cml0dGVuIHdpdGhvdXQgZmx1c2guIiwKKyAgICAgICAgICAgICAgICBzdy50b1N0cmluZygpLmVxdWFscygiIikpOworICAgICAgICBidy5mbHVzaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMjogSW5jb3JyZWN0IGNoYXIgd3JpdHRlbjsiLAorICAgICAgICAgICAgICAgICJUIiwgc3cudG9TdHJpbmcoKSk7CisKKyAgICAgICAgYncuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ3LndyaXRlKCdFJyk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IElPRXhjZXB0aW9uIGV4cGVjdGVkIHNpbmNlIHRoZSB0YXJnZXQgd3JpdGVyIGlzIGNsb3NlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICAvLyBJT0V4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIHdoZW4gdGhlIGJ1ZmZlciBpcyBmdWxsIGFuZCBkYXRhIGlzCisgICAgICAgIC8vIHdyaXR0ZW4gb3V0IHRvIHRoZSB0YXJnZXQgd3JpdGVyLgorICAgICAgICBidyA9IG5ldyBCdWZmZXJlZFdyaXRlcihzc3csIDEpOworICAgICAgICBidy53cml0ZSgnUycpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYncud3JpdGUoJ1QnKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogSU9FeGNlcHRpb24gZXhwZWN0ZWQgc2luY2UgdGhlIHRhcmdldCB3cml0ZXIgdGhyb3dzIGl0LiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGVMamF2YV9sYW5nX1N0cmluZ0lJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLmlvLkJ1ZmZlcmVkV3JpdGVyLndyaXRlKGphdmEubGFuZy5TdHJpbmcsCisgICAgICAgIC8vIGludCwgaW50KQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYncud3JpdGUodGVzdFN0cmluZyk7CisgICAgICAgICAgICBidy5mbHVzaCgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHN0cmluZyB3cml0dGVuIiwgc3cudG9TdHJpbmcoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgIHRlc3RTdHJpbmcpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgd3JpdGUgdGVzdCIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZUxqYXZhX2xhbmdfU3RyaW5nSUlfRXhjZXB0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBidy53cml0ZSgoU3RyaW5nKSBudWxsICwgLTEsIC0xKTsKKyAgICAgICAgYncud3JpdGUoKFN0cmluZykgbnVsbCAsIC0xLCAwKTsKKyAgICAgICAgYncud3JpdGUoKFN0cmluZykgbnVsbCAsIDAgLCAtMSk7CisgICAgICAgIGJ3LndyaXRlKChTdHJpbmcpIG51bGwgLCAwICwgMCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ3LndyaXRlKChTdHJpbmcpIG51bGwsIDAsIDEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYncud3JpdGUodGVzdFN0cmluZywgLTEsIDEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ3LndyaXRlKHRlc3RTdHJpbmcsIDEsIHRlc3RTdHJpbmcubGVuZ3RoKCkpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgYncuY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYncud3JpdGUodGVzdFN0cmluZywgMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIGJ3ID0gbmV3IEJ1ZmZlcmVkV3JpdGVyKHNzdywgdGVzdFN0cmluZy5sZW5ndGgoKSAvIDIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYncud3JpdGUodGVzdFN0cmluZywgMCwgdGVzdFN0cmluZy5sZW5ndGgoKSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICBzdyA9IG5ldyBTdXBwb3J0X1N0cmluZ1dyaXRlcigpOworICAgICAgICBzc3cgPSBuZXcgU3VwcG9ydF9BU2ltcGxlV3JpdGVyKHRydWUpOworICAgICAgICBidyA9IG5ldyBCdWZmZXJlZFdyaXRlcihzdywgNTAwKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgc3N3LnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRCeXRlQXJyYXlJbnB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQnl0ZUFycmF5SW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjVmM2Y0ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQnl0ZUFycmF5SW5wdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSwyMjAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgT2xkQnl0ZUFycmF5SW5wdXRTdHJlYW1UZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgQnl0ZUFycmF5SW5wdXRTdHJlYW0gaXM7CisKKyAgICBwdWJsaWMgU3RyaW5nIGZpbGVTdHJpbmcgPSAiVGVzdF9BbGxfVGVzdHNcblRlc3RfamF2YV9pb19CdWZmZXJlZElucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fQnVmZmVyZWRPdXRwdXRTdHJlYW1cblRlc3RfQnl0ZUFycmF5SW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19CeXRlQXJyYXlPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19EYXRhSW5wdXRTdHJlYW1cbiI7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yJEIoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGUgW10pCisKKyAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBiaXMgPSBuZXcgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbShmaWxlU3RyaW5nCisgICAgICAgICAgICAgICAgLmdldEJ5dGVzKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJVbmFibGUgdG8gY3JlYXRlIEJ5dGVBcnJheUlucHV0U3RyZWFtIiwKKyAgICAgICAgICAgICAgICAgICAgYmlzLmF2YWlsYWJsZSgpID09IGZpbGVTdHJpbmcubGVuZ3RoKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFeGNlcHRpb24gZHVyaW5nIENvbnN0cnVjdG9yIHRlc3QiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IkQklJKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZSBbXSwgaW50LCBpbnQpCisKKyAgICAgICAgYnl0ZVtdIHp6ID0gZmlsZVN0cmluZy5nZXRCeXRlcygpOworICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGJpcyA9IG5ldyBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtKHp6LCAwLCAxMDApOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlVuYWJsZSB0byBjcmVhdGUgQnl0ZUFycmF5SW5wdXRTdHJlYW0iLAorICAgICAgICAgICAgICAgICAgICAxMDAsIGJpcy5hdmFpbGFibGUoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIENvbnN0cnVjdG9yIHRlc3QiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgSGFybW9ueS0yNDA1CisgICAgICAgIG5ldyBTdWJCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVtdIHsgMSwgMiB9LCA0NDQsIDEzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQ0NCwgU3ViQnl0ZUFycmF5SW5wdXRTdHJlYW0ucG9zKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQ0NCwgU3ViQnl0ZUFycmF5SW5wdXRTdHJlYW0ubWFyayk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBTdWJCeXRlQXJyYXlJbnB1dFN0cmVhbS5jb3VudCk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFN1YkJ5dGVBcnJheUlucHV0U3RyZWFtIGV4dGVuZHMgQnl0ZUFycmF5SW5wdXRTdHJlYW0geworICAgICAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBidWY7CisKKyAgICAgICAgcHVibGljIHN0YXRpYyBpbnQgbWFyaywgcG9zLCBjb3VudDsKKworICAgICAgICBTdWJCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlW10gYnVmLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcihidWYsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgICAgIGJ1ZiA9IHN1cGVyLmJ1ZjsKKyAgICAgICAgICAgIG1hcmsgPSBzdXBlci5tYXJrOworICAgICAgICAgICAgcG9zID0gc3VwZXIucG9zOworICAgICAgICAgICAgY291bnQgPSBzdXBlci5jb3VudDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYXZhaWxhYmxlKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW0uYXZhaWxhYmxlKCkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBudW1iZXIgb2YgYXZhaWxhYmxlIGJ5dGVzIiwgaXMKKyAgICAgICAgICAgICAgICAgICAgLmF2YWlsYWJsZSgpID09IGZpbGVTdHJpbmcubGVuZ3RoKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBhdmFpbGFibGUgdGVzdCIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jbG9zZSgpIHsKKyAgICAgICAgaXMucmVhZCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IEZhaWxlZCB0byBjbG9zZSB0aGUgaW5wdXQgc3RyZWFtLiIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZWFkKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IFNob3VsZCBiZSBhYmxlIHRvIHJlYWQgZnJvbSBjbG9zZWQgc3RyZWFtLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9tYXJrSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbS5tYXJrKGludCkKKyAgICAgICAgYnl0ZVtdIGJ1ZjEgPSBuZXcgYnl0ZVsxMDBdOworICAgICAgICBieXRlW10gYnVmMiA9IG5ldyBieXRlWzEwMF07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5za2lwKDMwMDApOworICAgICAgICAgICAgaXMubWFyaygxMDAwKTsKKyAgICAgICAgICAgIGlzLnJlYWQoYnVmMSwgMCwgYnVmMS5sZW5ndGgpOworICAgICAgICAgICAgaXMucmVzZXQoKTsKKyAgICAgICAgICAgIGlzLnJlYWQoYnVmMiwgMCwgYnVmMi5sZW5ndGgpOworICAgICAgICAgICAgaXMucmVzZXQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBtYXJrIGNvcnJlY3QgcG9zaXRpb24iLCBuZXcgU3RyaW5nKGJ1ZjEsIDAsCisgICAgICAgICAgICAgICAgICAgIGJ1ZjEubGVuZ3RoKS5lcXVhbHMobmV3IFN0cmluZyhidWYyLCAwLCBidWYyLmxlbmd0aCkpKTsKKworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBtYXJrIHRlc3QiKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9tYXJrU3VwcG9ydGVkKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtLm1hcmtTdXBwb3J0ZWQoKQorICAgICAgICBhc3NlcnRUcnVlKCJtYXJrU3VwcG9ydGVkIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIGlzLm1hcmtTdXBwb3J0ZWQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW0ucmVhZCgpCisgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgIGludCBjID0gaXMucmVhZCgpOworICAgICAgICAgICAgaXMucmVzZXQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoInJlYWQgcmV0dXJuZWQgaW5jb3JyZWN0IGNoYXIiLCBjID09IGZpbGVTdHJpbmcKKyAgICAgICAgICAgICAgICAgICAgLmNoYXJBdCgwKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHJlYWQgdGVzdCIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkJEJJSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBidWYxID0gbmV3IGJ5dGVbMjBdOworICAgICAgICBpcy5za2lwKDUwKTsKKyAgICAgICAgaXMubWFyaygxMDApOworICAgICAgICBpcy5yZWFkKGJ1ZjEsIDAsIGJ1ZjEubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBGYWlsZWQgdG8gcmVhZCBjb3JyZWN0IGRhdGEuIiwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKGJ1ZjEsIDAsIGJ1ZjEubGVuZ3RoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICAgICBmaWxlU3RyaW5nLnN1YnN0cmluZyg1MCwgNzApKSk7CisKKyAgICAgICAgLy8gSWxsZWdhbCBhcmd1bWVudCBjaGVja3MuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZWFkKG51bGwsIDEsIDApOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZChidWYxICwgLTEsIDEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZChidWYxICwgMSwgLTEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZChidWYxLCAxLCBidWYxLmxlbmd0aCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVzZXQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW0ucmVzZXQoKQorICAgICAgICBieXRlW10gYnVmMSA9IG5ldyBieXRlWzEwXTsKKyAgICAgICAgYnl0ZVtdIGJ1ZjIgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5tYXJrKDIwMCk7CisgICAgICAgICAgICBpcy5yZWFkKGJ1ZjEsIDAsIDEwKTsKKyAgICAgICAgICAgIGlzLnJlc2V0KCk7CisgICAgICAgICAgICBpcy5yZWFkKGJ1ZjIsIDAsIDEwKTsKKyAgICAgICAgICAgIGlzLnJlc2V0KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXNldCBmYWlsZWQiLCBuZXcgU3RyaW5nKGJ1ZjEsIDAsIGJ1ZjEubGVuZ3RoKQorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKG5ldyBTdHJpbmcoYnVmMiwgMCwgYnVmMi5sZW5ndGgpKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHJlc2V0IHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9za2lwSigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGxvbmcgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbS5za2lwKGxvbmcpCisgICAgICAgIGJ5dGVbXSBidWYxID0gbmV3IGJ5dGVbMTBdOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMuc2tpcCgxMDApOworICAgICAgICAgICAgaXMucmVhZChidWYxLCAwLCBidWYxLmxlbmd0aCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gc2tpcCB0byBjb3JyZWN0IHBvc2l0aW9uIiwgbmV3IFN0cmluZyhidWYxLAorICAgICAgICAgICAgICAgICAgICAwLCBidWYxLmxlbmd0aCkuZXF1YWxzKGZpbGVTdHJpbmcuc3Vic3RyaW5nKDEwMCwgMTEwKSkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBza2lwIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIGlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGZpbGVTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEJ5dGVBcnJheU91dHB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQnl0ZUFycmF5T3V0cHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBlZjdmNzUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEJ5dGVBcnJheU91dHB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDExMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfT3V0cHV0U3RyZWFtOworCisvKioKKyAqIEF1dG9tYXRlZCBUZXN0IFN1aXRlIGZvciBjbGFzcyBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbQorICoKKyAqIEBzZWUgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW0KKyAqLworcHVibGljIGNsYXNzIE9sZEJ5dGVBcnJheU91dHB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbnVsbDsKKworICAgIHB1YmxpYyBTdHJpbmcgZmlsZVN0cmluZyA9ICJUZXN0X0FsbF9UZXN0c1xuVGVzdF9qYXZhX2lvX0J1ZmZlcmVkSW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19CdWZmZXJlZE91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0J5dGVBcnJheUlucHV0U3RyZWFtXG5UZXN0X0J5dGVBcnJheU91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0RhdGFJbnB1dFN0cmVhbVxuIjsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JJKCkgeworICAgICAgICBib3MgPSBuZXcgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW0oMTAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEZhaWxlZCB0byBjcmVhdGUgc3RyZWFtOyIsIDAsIGJvcy5zaXplKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCisgICAgICAgIGJvcy53cml0ZShmaWxlU3RyaW5nLmdldEJ5dGVzKCksIDAsIGZpbGVTdHJpbmcubGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IFJldHVybmVkIGluY29ycmVjdCA4ODU5LTEgU3RyaW5nIiwKKyAgICAgICAgICAgICAgICBib3MudG9TdHJpbmcoIjg4NTlfMSIpLmVxdWFscyhmaWxlU3RyaW5nKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMjogUmV0dXJuZWQgaW5jb3JyZWN0IDg4NTktMiBTdHJpbmciLAorICAgICAgICAgICAgICAgIGJvcy50b1N0cmluZygiODg1OV8yIikuZXF1YWxzKGZpbGVTdHJpbmcpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYm9zLnRvU3RyaW5nKCJOb3RBbkVjb2RpbmciKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGUkQklJX0V4Y2VwdGlvbigpIHsKKyAgICAgICAgYnl0ZVtdIHRhcmdldCA9IG5ldyBieXRlWzEwXTsKKyAgICAgICAgYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYm9zLndyaXRlKHRhcmdldCwgLTEsIDEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJvcy53cml0ZSh0YXJnZXQsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBib3Mud3JpdGUodGFyZ2V0LCAxLCB0YXJnZXQubGVuZ3RoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBib3Mud3JpdGUobnVsbCwgMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGVUb0xqYXZhX2lvX091dHB1dFN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdXBwb3J0X091dHB1dFN0cmVhbSBzb3MgPSBuZXcgU3VwcG9ydF9PdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgYm9zID0gbmV3IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGJvcy53cml0ZShmaWxlU3RyaW5nLmdldEJ5dGVzKCksIDAsIDEwKTsKKyAgICAgICAgYm9zLndyaXRlVG8oc29zKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBJbmNvcnJlY3Qgc3RyaW5nIHdyaXR0ZW4uIiwKKyAgICAgICAgICAgICAgICBzb3MudG9TdHJpbmcoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICAgICBmaWxlU3RyaW5nLnN1YnN0cmluZygwLCAxMCkpKTsKKworICAgICAgICBzb3Muc2V0VGhyb3dzRXhjZXB0aW9uKHRydWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYm9zLndyaXRlVG8oc29zKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRDaGFyQXJyYXlSZWFkZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZENoYXJBcnJheVJlYWRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMjhiODRmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRDaGFyQXJyYXlSZWFkZXJUZXN0LmphdmEKQEAgLTAsMCArMSwyNTkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5DaGFyQXJyYXlSZWFkZXI7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworcHVibGljIGNsYXNzIE9sZENoYXJBcnJheVJlYWRlclRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgY2hhcltdIGh3ID0geyAnSCcsICdlJywgJ2wnLCAnbCcsICdvJywgJ1cnLCAnbycsICdyJywgJ2wnLCAnZCcgfTsKKworICAgIENoYXJBcnJheVJlYWRlciBjcjsKKworICAgIC8qKgorICAgICAqIGphdmEuaW8uQ2hhckFycmF5UmVhZGVyI0NoYXJBcnJheVJlYWRlcihjaGFyW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvciRDKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5pby5DaGFyQXJyYXlSZWFkZXIoY2hhciBbXSkKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY3IgPSBuZXcgQ2hhckFycmF5UmVhZGVyKGh3KTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBjcmVhdGUgcmVhZGVyIiwgY3IucmVhZHkoKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkZXRlcm1pbmluZyByZWFkeSBzdGF0ZSA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLkNoYXJBcnJheVJlYWRlciNDaGFyQXJyYXlSZWFkZXIoY2hhcltdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yJENJSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjciA9IG5ldyBDaGFyQXJyYXlSZWFkZXIobnVsbCwgMCwgMCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY3IgPSBuZXcgQ2hhckFycmF5UmVhZGVyKGh3LCAtMSwgMCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjciA9IG5ldyBDaGFyQXJyYXlSZWFkZXIoaHcsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNyID0gbmV3IENoYXJBcnJheVJlYWRlcihodywgaHcubGVuZ3RoICsgMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgY3IgPSBuZXcgQ2hhckFycmF5UmVhZGVyKGh3LCA1LCA1KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCA1OiBGYWlsZWQgdG8gY3JlYXRlIHJlYWRlciIsIGNyLnJlYWR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNjogSW5jb3JyZWN0IGNoYXJhY3RlciByZWFkOyIsCisgICAgICAgICAgICAgICAgJ1cnLCBjci5yZWFkKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uQ2hhckFycmF5UmVhZGVyI2Nsb3NlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb3NlKCkgeworICAgICAgICBjciA9IG5ldyBDaGFyQXJyYXlSZWFkZXIoaHcpOworICAgICAgICBjci5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY3IucmVhZCgpOworICAgICAgICAgICAgZmFpbCgiRmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiBvbiByZWFkIGZyb20gY2xvc2VkIHN0cmVhbSIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5DaGFyQXJyYXlSZWFkZXIjbWFyayhpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9tYXJrSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNyID0gbmV3IENoYXJBcnJheVJlYWRlcihodyk7CisgICAgICAgIGNyLnNraXAoNUwpOworICAgICAgICBjci5tYXJrKDEwMCk7CisgICAgICAgIGNyLnJlYWQoKTsKKyAgICAgICAgY3IucmVzZXQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEZhaWxlZCB0byBtYXJrIGNvcnJlY3QgcG9zaXRpb247IiwKKyAgICAgICAgICAgICAgICAnVycsIGNyLnJlYWQoKSk7CisKKyAgICAgICAgY3IuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNyLm1hcmsoMTAwKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5DaGFyQXJyYXlSZWFkZXIjbWFya1N1cHBvcnRlZCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9tYXJrU3VwcG9ydGVkKCkgeworICAgICAgICBjciA9IG5ldyBDaGFyQXJyYXlSZWFkZXIoaHcpOworICAgICAgICBhc3NlcnRUcnVlKCJtYXJrU3VwcG9ydGVkIHJldHVybmVkIGZhbHNlIiwgY3IubWFya1N1cHBvcnRlZCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLkNoYXJBcnJheVJlYWRlciNyZWFkKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjciA9IG5ldyBDaGFyQXJyYXlSZWFkZXIoaHcpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogUmVhZCByZXR1cm5lZCBpbmNvcnJlY3QgY2hhcjsiLAorICAgICAgICAgICAgICAgICdIJywgY3IucmVhZCgpKTsKKyAgICAgICAgY3IgPSBuZXcgQ2hhckFycmF5UmVhZGVyKG5ldyBjaGFyW10geyAnXHU4NzY1JyB9KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAyOiBJbmNvcnJlY3QgZG91YmxlIGJ5dGUgY2hhcjsiLAorICAgICAgICAgICAgICAgIGNyLnJlYWQoKSA9PSAnXHU4NzY1Jyk7CisKKyAgICAgICAgY3IuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNyLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5DaGFyQXJyYXlSZWFkZXIjcmVhZChjaGFyW10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCRDSUkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEuaW8uQ2hhckFycmF5UmVhZGVyLnJlYWQoY2hhciBbXSwgaW50LCBpbnQpCisgICAgICAgIGNoYXJbXSBjID0gbmV3IGNoYXJbMTFdOworICAgICAgICBjciA9IG5ldyBDaGFyQXJyYXlSZWFkZXIoaHcpOworICAgICAgICBjci5yZWFkKGMsIDEsIDEwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBSZWFkIHJldHVybmVkIGluY29ycmVjdCBjaGFycy4iLAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmcoYywgMSwgMTApLmVxdWFscyhuZXcgU3RyaW5nKGh3LCAwLCAxMCkpKTsKKworICAgICAgICAvLyBJbGxlZ2FsIGFyZ3VtZW50IGNoZWNrcy4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNyLnJlYWQobnVsbCwgMSwgMCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjci5yZWFkKGMgLCAtMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNyLnJlYWQoYyAsIDEsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY3IucmVhZChjLCAxLCBjLmxlbmd0aCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgY3IuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNyLnJlYWQoYywgMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDY6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZHkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEuaW8uQ2hhckFycmF5UmVhZGVyLnJlYWR5KCkKKyAgICAgICAgY3IgPSBuZXcgQ2hhckFycmF5UmVhZGVyKGh3KTsKKyAgICAgICAgYm9vbGVhbiBleHBlY3RFeGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoInJlYWR5IHJldHVybmVkIGZhbHNlIiwgY3IucmVhZHkoKSk7CisgICAgICAgICAgICBjci5za2lwKDEwMDApOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgicmVhZHkgcmV0dXJuZWQgdHJ1ZSIsICFjci5yZWFkeSgpKTsKKyAgICAgICAgICAgIGNyLmNsb3NlKCk7CisgICAgICAgICAgICBleHBlY3RFeGNlcHRpb24gPSB0cnVlOworICAgICAgICAgICAgY3IucmVhZHkoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4Y2VwdGlvbiAxIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGlmICghZXhwZWN0RXhjZXB0aW9uKQorICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQ6ICIgKyBlKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY3IgPSBuZXcgQ2hhckFycmF5UmVhZGVyKGh3KTsKKyAgICAgICAgICAgIGNyLmNsb3NlKCk7CisgICAgICAgICAgICBjci5yZWFkeSgpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhjZXB0aW9uIDIiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5DaGFyQXJyYXlSZWFkZXIjcmVzZXQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjciA9IG5ldyBDaGFyQXJyYXlSZWFkZXIoaHcpOworICAgICAgICBjci5za2lwKDVMKTsKKyAgICAgICAgY3IubWFyaygxMDApOworICAgICAgICBjci5yZWFkKCk7CisgICAgICAgIGNyLnJlc2V0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBSZXNldCBmYWlsZWQgdG8gcmV0dXJuIHRvIG1hcmtlciBwb3NpdGlvbi4iLAorICAgICAgICAgICAgICAgICdXJywgY3IucmVhZCgpKTsKKworICAgICAgICBjci5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY3IucmVzZXQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9za2lwSigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxvbmcgc2tpcHBlZCA9IDA7CisgICAgICAgIGNyID0gbmV3IENoYXJBcnJheVJlYWRlcihodyk7CisgICAgICAgIHNraXBwZWQgPSBjci5za2lwKDVMKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEZhaWxlZCB0byBza2lwIGNvcnJlY3QgbnVtYmVyIG9mIGNoYXJzOyIsCisgICAgICAgICAgICAgICAgNUwsIHNraXBwZWQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMjogU2tpcCBza2lwcGVkIHdyb25nIGNoYXJzOyIsCisgICAgICAgICAgICAgICAgJ1cnLCBjci5yZWFkKCkpOworCisgICAgICAgIGNyLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjci5za2lwKDEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgaWYgKGNyICE9IG51bGwpCisgICAgICAgICAgICBjci5jbG9zZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQ2hhckFycmF5V3JpdGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRDaGFyQXJyYXlXcml0ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjYyYWQyNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkQ2hhckFycmF5V3JpdGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTQwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQ2hhckFycmF5UmVhZGVyOworaW1wb3J0IGphdmEuaW8uQ2hhckFycmF5V3JpdGVyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5TdHJpbmdXcml0ZXI7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0FTaW1wbGVXcml0ZXI7CisKK3B1YmxpYyBjbGFzcyBPbGRDaGFyQXJyYXlXcml0ZXJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIENoYXJBcnJheVdyaXRlciBjdzsKKyAgICBDaGFyQXJyYXlSZWFkZXIgY3I7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEuaW8uQ2hhckFycmF5V3JpdGVyKGludCkKKyAgICAgICAgY3cgPSBuZXcgQ2hhckFycmF5V3JpdGVyKDkwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCB3cml0ZXIgY3JlYXRlZC4iLCAwLCBjdy5zaXplKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjdyA9IG5ldyBDaGFyQXJyYXlXcml0ZXIoLTEpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlJENJSV9FeGNlcHRpb24oKSB7CisgICAgICAgIGNoYXJbXSB0YXJnZXQgPSBuZXcgY2hhclsxMF07CisgICAgICAgIGN3ID0gbmV3IENoYXJBcnJheVdyaXRlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY3cud3JpdGUodGFyZ2V0LCAtMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY3cud3JpdGUodGFyZ2V0LCAwLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY3cud3JpdGUodGFyZ2V0LCAxLCB0YXJnZXQubGVuZ3RoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjdy53cml0ZSgoY2hhcltdKSBudWxsLCAxLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZVRvTGphdmFfaW9fV3JpdGVyKCkgeworICAgICAgICBTdXBwb3J0X0FTaW1wbGVXcml0ZXIgc3N3ID0gbmV3IFN1cHBvcnRfQVNpbXBsZVdyaXRlcih0cnVlKTsKKyAgICAgICAgY3cud3JpdGUoIkhlbGxvV29ybGQiLCAwLCAxMCk7CisgICAgICAgIFN0cmluZ1dyaXRlciBzdyA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGN3LndyaXRlVG8oc3cpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IFdyaXRlciBmYWlsZWQgdG8gd3JpdGUgY29ycmVjdCBjaGFyczsiLAorICAgICAgICAgICAgICAgICAgICAgICAgICJIZWxsb1dvcmxkIiwgc3cudG9TdHJpbmcoKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgd3JpdGVUbyB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjdy53cml0ZVRvKHNzdyk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYXBwZW5kTGphdmFfbGFuZ0NoYXJTZXF1ZW5jZUlJKCkgeworICAgICAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJNeSBUZXN0IFN0cmluZyI7CisgICAgICAgIENoYXJBcnJheVdyaXRlciB3cml0ZXIgPSBuZXcgQ2hhckFycmF5V3JpdGVyKDEwKTsKKworICAgICAgICAvLyBJbGxlZ2FsIGFyZ3VtZW50IGNoZWNrcy4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlci5hcHBlbmQodGVzdFN0cmluZywgLTEsIDApOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZXIuYXBwZW5kKHRlc3RTdHJpbmcsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVyLmFwcGVuZCh0ZXN0U3RyaW5nLCAxLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVyLmFwcGVuZCh0ZXN0U3RyaW5nLCAxLCB0ZXN0U3RyaW5nLmxlbmd0aCgpICsgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB3cml0ZXIuYXBwZW5kKHRlc3RTdHJpbmcsIDEsIDMpOworICAgICAgICB3cml0ZXIuZmx1c2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDU6IEFwcGVuZGluZyBmYWlsZWQ7IiwKKyAgICAgICAgICAgICAgICB0ZXN0U3RyaW5nLnN1YnN0cmluZygxLCAzKSwgd3JpdGVyLnRvU3RyaW5nKCkpOworICAgICAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgY3cgPSBuZXcgQ2hhckFycmF5V3JpdGVyKCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIGlmIChjciAhPSBudWxsKSB7CisgICAgICAgICAgICBjci5jbG9zZSgpOworICAgICAgICB9CisgICAgICAgIGN3LmNsb3NlKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGREYXRhSW5wdXRPdXRwdXRTdHJlYW1UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZERhdGFJbnB1dE91dHB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYTJlMzI1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGREYXRhSW5wdXRPdXRwdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSwzNDQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5FT0ZFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfT3V0cHV0U3RyZWFtOworCitwdWJsaWMgY2xhc3MgT2xkRGF0YUlucHV0T3V0cHV0U3RyZWFtVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIERhdGFPdXRwdXRTdHJlYW0gb3M7CisKKyAgICBwcml2YXRlIERhdGFJbnB1dFN0cmVhbSBkaXM7CisKKyAgICBwcml2YXRlIFN1cHBvcnRfT3V0cHV0U3RyZWFtIHNvczsKKworICAgIFN0cmluZyB1bmlodyA9ICJcdTAwNDhcdTAwNjVcdTAwNkNcdTAwNkNcdTAwNkZcdTAwMjBcdTAwNTdcdTAwNkZcdTAwNzJcdTAwNkNcdTAwNjQiOworCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkX3dyaXRlQm9vbGVhbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9zLndyaXRlQm9vbGVhbih0cnVlKTsKKyAgICAgICAgc29zLnNldFRocm93c0V4Y2VwdGlvbih0cnVlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9zLndyaXRlQm9vbGVhbihmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICBzb3Muc2V0VGhyb3dzRXhjZXB0aW9uKGZhbHNlKTsKKworICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICBvcGVuRGF0YUlucHV0U3RyZWFtKCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMjogSW5jb3JyZWN0IGJvb2xlYW4gd3JpdHRlbiBvciByZWFkLiIsCisgICAgICAgICAgICAgICAgZGlzLnJlYWRCb29sZWFuKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkaXMucmVhZEJvb2xlYW4oKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBkaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRpcy5yZWFkQm9vbGVhbigpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfd3JpdGVCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3Mud3JpdGVCeXRlKChieXRlKSAxMjcpOworICAgICAgICBzb3Muc2V0VGhyb3dzRXhjZXB0aW9uKHRydWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3Mud3JpdGVCeXRlKChieXRlKSAxMjcpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgc29zLnNldFRocm93c0V4Y2VwdGlvbihmYWxzZSk7CisKKyAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgb3BlbkRhdGFJbnB1dFN0cmVhbSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMjogSW5jb3JyZWN0IGJ5dGUgd3JpdHRlbiBvciByZWFkOyIsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDEyNywgZGlzLnJlYWRCeXRlKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkaXMucmVhZEJ5dGUoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBkaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRpcy5yZWFkQnl0ZSgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfd3JpdGVDaGFyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3Mud3JpdGVDaGFyKCdiJyk7CisgICAgICAgIHNvcy5zZXRUaHJvd3NFeGNlcHRpb24odHJ1ZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcy53cml0ZUNoYXIoJ2snKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIHNvcy5zZXRUaHJvd3NFeGNlcHRpb24oZmFsc2UpOworCisgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIG9wZW5EYXRhSW5wdXRTdHJlYW0oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IEluY29ycmVjdCBjaGFyIHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgICdiJywgZGlzLnJlYWRDaGFyKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkaXMucmVhZENoYXIoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBkaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRpcy5yZWFkQ2hhcigpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfd3JpdGVEb3VibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvcy53cml0ZURvdWJsZSgyMzQ1Ljc2ODM0NzIwMjAyKTsKKyAgICAgICAgc29zLnNldFRocm93c0V4Y2VwdGlvbih0cnVlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9zLndyaXRlRG91YmxlKDIzNDUuNzY4MzQ3MjAyMDIpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgc29zLnNldFRocm93c0V4Y2VwdGlvbihmYWxzZSk7CisKKyAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgb3BlbkRhdGFJbnB1dFN0cmVhbSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IGRvdWJsZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICAyMzQ1Ljc2ODM0NzIwMjAyLCBkaXMucmVhZERvdWJsZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGlzLnJlYWREb3VibGUoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBkaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRpcy5yZWFkRG91YmxlKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZF93cml0ZUZsb2F0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3Mud3JpdGVGbG9hdCgyOS4wODc2NGYpOworICAgICAgICBzb3Muc2V0VGhyb3dzRXhjZXB0aW9uKHRydWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3Mud3JpdGVGbG9hdCgyOS4wODc2NGYpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgc29zLnNldFRocm93c0V4Y2VwdGlvbihmYWxzZSk7CisKKyAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgb3BlbkRhdGFJbnB1dFN0cmVhbSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMjogSW5jb3JyZWN0IGZsb2F0IHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIDI5LjA4NzY0ZiwgZGlzLnJlYWRGbG9hdCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGlzLnJlYWRGbG9hdCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBFT0ZFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIGRpcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGlzLnJlYWRGbG9hdCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfd3JpdGVJbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvcy53cml0ZUludCg3NjgzNDcyMDIpOworICAgICAgICBzb3Muc2V0VGhyb3dzRXhjZXB0aW9uKHRydWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3Mud3JpdGVJbnQoNzY4MzQ3MjAyKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIHNvcy5zZXRUaHJvd3NFeGNlcHRpb24oZmFsc2UpOworCisgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIG9wZW5EYXRhSW5wdXRTdHJlYW0oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCBpbnQgd3JpdHRlbiBvciByZWFkOyIsCisgICAgICAgICAgICAgICAgNzY4MzQ3MjAyLCBkaXMucmVhZEludCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGlzLnJlYWRJbnQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBkaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRpcy5yZWFkSW50KCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZF93cml0ZUxvbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvcy53cml0ZUxvbmcoOTg3NTY0NTI4MzMzM0wpOworICAgICAgICBzb3Muc2V0VGhyb3dzRXhjZXB0aW9uKHRydWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3Mud3JpdGVMb25nKDk4NzU2NDUyODMzMzNMKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIHNvcy5zZXRUaHJvd3NFeGNlcHRpb24oZmFsc2UpOworCisgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIG9wZW5EYXRhSW5wdXRTdHJlYW0oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IEluY29ycmVjdCBsb25nIHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIDk4NzU2NDUyODMzMzNMLCBkaXMucmVhZExvbmcoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRpcy5yZWFkTG9uZygpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBFT0ZFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIGRpcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGlzLnJlYWRMb25nKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZF93cml0ZVNob3J0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3Mud3JpdGVTaG9ydCg5ODc1KTsKKyAgICAgICAgc29zLnNldFRocm93c0V4Y2VwdGlvbih0cnVlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9zLndyaXRlU2hvcnQoOTg3NSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICBzb3Muc2V0VGhyb3dzRXhjZXB0aW9uKGZhbHNlKTsKKworICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICBvcGVuRGF0YUlucHV0U3RyZWFtKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3Qgc2hvcnQgd3JpdHRlbiBvciByZWFkOyIsCisgICAgICAgICAgICAgICAgOTg3NSwgZGlzLnJlYWRTaG9ydCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGlzLnJlYWRTaG9ydCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBFT0ZFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIGRpcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGlzLnJlYWRTaG9ydCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfd3JpdGVVVEYoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvcy53cml0ZVVURih1bmlodyk7CisgICAgICAgIHNvcy5zZXRUaHJvd3NFeGNlcHRpb24odHJ1ZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcy53cml0ZVVURih1bmlodyk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICBzb3Muc2V0VGhyb3dzRXhjZXB0aW9uKGZhbHNlKTsKKworICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICBvcGVuRGF0YUlucHV0U3RyZWFtKCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogSW5jb3JyZWN0IFVURi04IHN0cmluZyB3cml0dGVuIG9yIHJlYWQuIiwKKyAgICAgICAgICAgICAgICBkaXMucmVhZFVURigpLmVxdWFscyh1bmlodykpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkaXMucmVhZFVURigpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBFT0ZFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIGRpcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGlzLnJlYWRVVEYoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG9wZW5EYXRhSW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBkaXMgPSBuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShzb3MudG9CeXRlQXJyYXkoKSkpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICBzb3MgPSBuZXcgU3VwcG9ydF9PdXRwdXRTdHJlYW0oMjU2KTsKKyAgICAgICAgb3MgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShzb3MpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZGlzLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZERhdGFJbnB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkRGF0YUlucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI3MjQwZTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZERhdGFJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDM4MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkVPRkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW07CisKK3B1YmxpYyBjbGFzcyBPbGREYXRhSW5wdXRTdHJlYW1UZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgRGF0YU91dHB1dFN0cmVhbSBvczsKKworICAgIHByaXZhdGUgRGF0YUlucHV0U3RyZWFtIGRpczsKKworICAgIHByaXZhdGUgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvczsKKworICAgIFN0cmluZyB1bmlodyA9ICJcdTAwNDhcdTAwNjVcdTAwNkNcdTAwNkNcdTAwNkZcdTAwMjBcdTAwNTdcdTAwNkZcdTAwNzJcdTAwNkNcdTAwNjQiOworCisgICAgcHVibGljIFN0cmluZyBmaWxlU3RyaW5nID0gIlRlc3RfQWxsX1Rlc3RzXG5UZXN0X2phdmFfaW9fQnVmZmVyZWRJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0J1ZmZlcmVkT3V0cHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fQnl0ZUFycmF5SW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19CeXRlQXJyYXlPdXRwdXRTdHJlYW1cblRlc3RfRGF0YUlucHV0U3RyZWFtXG4iOworCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdGVzdExlbmd0aCA9IGZpbGVTdHJpbmcubGVuZ3RoKCk7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fSW5wdXRTdHJlYW0oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcy53cml0ZUNoYXIoJ3QnKTsKKyAgICAgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgICAgICBvcGVuRGF0YUlucHV0U3RyZWFtKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIGR1cmluZyBjb25zdHJ1Y3RvciB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZGlzLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gZHVyaW5nIGNvbnN0cnVjdG9yIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkJEIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlIHJieXRlc1tdID0gbmV3IGJ5dGVbdGVzdExlbmd0aCAtIDVdOworICAgICAgICBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbSBzaXMgPSBuZXcgU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW0oKTsKKyAgICAgICAgaW50IHI7CisKKyAgICAgICAgb3Mud3JpdGUoZmlsZVN0cmluZy5nZXRCeXRlcygpKTsKKyAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgb3BlbkRhdGFJbnB1dFN0cmVhbSgpOworCisgICAgICAgIHIgPSBkaXMucmVhZChyYnl0ZXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IG51bWJlciBvZiBieXRlcyByZWFkOyIsCisgICAgICAgICAgICAgICAgdGVzdExlbmd0aCAtIDUsIHIpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDI6IEluY29ycmVjdCBkYXRhIHdyaXR0ZW4gb3IgcmVhZC4iLAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmcocmJ5dGVzKS5lcXVhbHMoZmlsZVN0cmluZy5zdWJzdHJpbmcoMCwgdGVzdExlbmd0aCAtIDUpKSk7CisKKyAgICAgICAgciA9IGRpcy5yZWFkKHJieXRlcyk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAzOiBJbmNvcnJlY3QgbnVtYmVyIG9mIGJ5dGVzIHJlYWQ7IiwgNSwgcik7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgNDogSW5jb3JyZWN0IGRhdGEgd3JpdHRlbiBvciByZWFkLiIsCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZyhyYnl0ZXMsIDAsIDUpLmVxdWFscyhmaWxlU3RyaW5nLnN1YnN0cmluZyh0ZXN0TGVuZ3RoIC0gNSkpKTsKKworICAgICAgICBkaXMuY2xvc2UoKTsKKyAgICAgICAgc2lzLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gdHJ1ZTsKKyAgICAgICAgZGlzID0gbmV3IERhdGFJbnB1dFN0cmVhbShzaXMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGlzLnJlYWQocmJ5dGVzKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkJEJJSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGUgcmJ5dGVzW10gPSBuZXcgYnl0ZVt0ZXN0TGVuZ3RoIC0gNV07CisgICAgICAgIFN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtIHNpcyA9IG5ldyBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbSgpOworICAgICAgICBpbnQgcjsKKworICAgICAgICBvcy53cml0ZShmaWxlU3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICBvcGVuRGF0YUlucHV0U3RyZWFtKCk7CisKKyAgICAgICAgciA9IGRpcy5yZWFkKHJieXRlcywgMSwgdGVzdExlbmd0aCAtIDEwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCBudW1iZXIgb2YgYnl0ZXMgcmVhZDsiLAorICAgICAgICAgICAgICAgIHRlc3RMZW5ndGggLSAxMCwgcik7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBJbmNvcnJlY3QgZGF0YSByZWFkLiIsIDAsIHJieXRlc1swXSk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMzogSW5jb3JyZWN0IGRhdGEgd3JpdHRlbiBvciByZWFkLiIsCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZyhyYnl0ZXMsIDEsIHIpLmVxdWFscyhmaWxlU3RyaW5nLnN1YnN0cmluZygwLCByKSkpOworCisgICAgICAgIHIgPSBkaXMucmVhZChyYnl0ZXMsIDAsIDE1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDM6IEluY29ycmVjdCBudW1iZXIgb2YgYnl0ZXMgcmVhZDsiLCAxMCwgcik7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgNDogSW5jb3JyZWN0IGRhdGEgd3JpdHRlbiBvciByZWFkLiIsCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZyhyYnl0ZXMsIDAsIHIpLmVxdWFscyhmaWxlU3RyaW5nLnN1YnN0cmluZyh0ZXN0TGVuZ3RoIC0gMTApKSk7CisKKyAgICAgICAgZGlzLmNsb3NlKCk7CisgICAgICAgIHNpcy50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IHRydWU7CisgICAgICAgIGRpcyA9IG5ldyBEYXRhSW5wdXRTdHJlYW0oc2lzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRpcy5yZWFkKHJieXRlcywgMSwgNSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCRCSUlfRXhjZXB0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZSByYnl0ZXNbXSA9IG5ldyBieXRlW3Rlc3RMZW5ndGggLSA1XTsKKworICAgICAgICBvcy53cml0ZShmaWxlU3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICBvcGVuRGF0YUlucHV0U3RyZWFtKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRpcy5yZWFkKHJieXRlcywgLTEsIDEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRpcy5yZWFkKHJieXRlcywgMCwgLTEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRpcy5yZWFkKHJieXRlcywgcmJ5dGVzLmxlbmd0aCwgMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRGdWxseSRCKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZSByYnl0ZXNbXSA9IG5ldyBieXRlW3Rlc3RMZW5ndGhdOworCisgICAgICAgIG9zLndyaXRlKGZpbGVTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIG9wZW5EYXRhSW5wdXRTdHJlYW0oKTsKKworICAgICAgICBkaXMucmVhZEZ1bGx5KHJieXRlcyk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogSW5jb3JyZWN0IGRhdGEgd3JpdHRlbiBvciByZWFkLiIsCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZyhyYnl0ZXMsIDAsIHRlc3RMZW5ndGgpLmVxdWFscyhmaWxlU3RyaW5nKSk7CisKKyAgICAgICAgZGlzLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkaXMucmVhZEZ1bGx5KHJieXRlcyk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIG9wZW5EYXRhSW5wdXRTdHJlYW0oKTsKKyAgICAgICAgZGlzLnJlYWRCeXRlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkaXMucmVhZEZ1bGx5KHJieXRlcyk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IEVPRkV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkRnVsbHkkQklJKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZSByYnl0ZXNbXSA9IG5ldyBieXRlW3Rlc3RMZW5ndGhdOworCisgICAgICAgIG9zLndyaXRlKGZpbGVTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIG9wZW5EYXRhSW5wdXRTdHJlYW0oKTsKKworICAgICAgICBkaXMucmVhZEZ1bGx5KHJieXRlcywgMiwgdGVzdExlbmd0aCAtIDQpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IEluY29ycmVjdCBkYXRhIHdyaXR0ZW4gb3IgcmVhZC4iLAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmcocmJ5dGVzLCAyLCB0ZXN0TGVuZ3RoIC0gNCkuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVN0cmluZy5zdWJzdHJpbmcoMCwgdGVzdExlbmd0aCAtIDQpKSk7CisKKyAgICAgICAgZGlzLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkaXMucmVhZEZ1bGx5KHJieXRlcywgMCwgdGVzdExlbmd0aCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIG9wZW5EYXRhSW5wdXRTdHJlYW0oKTsKKyAgICAgICAgZGlzLnJlYWRCeXRlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkaXMucmVhZEZ1bGx5KHJieXRlcywgMCwgdGVzdExlbmd0aCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IEVPRkV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkRnVsbHkkQklJX0V4Y2VwdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIERhdGFJbnB1dFN0cmVhbSBpcyA9ICBuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVt0ZXN0TGVuZ3RoXSkpOworCisgICAgICAgIGJ5dGVbXSBieXRlQXJyYXkgPSBuZXcgYnl0ZVt0ZXN0TGVuZ3RoXTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZEZ1bGx5KGJ5dGVBcnJheSwgMCwgLTEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWRGdWxseShieXRlQXJyYXksIDAsIGJ5dGVBcnJheS5sZW5ndGggKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZWFkRnVsbHkoYnl0ZUFycmF5LCAxLCBieXRlQXJyYXkubGVuZ3RoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZWFkRnVsbHkoYnl0ZUFycmF5LCAtMSwgYnl0ZUFycmF5Lmxlbmd0aCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZEZ1bGx5KG51bGwsIDAsIDEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA1OiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBpcyA9IG5ldyBEYXRhSW5wdXRTdHJlYW0obnVsbCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWRGdWxseShieXRlQXJyYXksIDAsIDEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA2OiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZExpbmUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbGluZTsKKyAgICAgICAgb3Mud3JpdGVCeXRlcygiTG9yZW1cbmlwc3VtXHJkb2xvciBzaXQgYW1ldC4uLiIpOworICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICBvcGVuRGF0YUlucHV0U3RyZWFtKCk7CisgICAgICAgIGxpbmUgPSBkaXMucmVhZExpbmUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBJbmNvcnJlY3QgbGluZSB3cml0dGVuIG9yIHJlYWQ6ICIgKyBsaW5lLAorICAgICAgICAgICAgICAgIGxpbmUuZXF1YWxzKCJMb3JlbSIpKTsKKyAgICAgICAgbGluZSA9IGRpcy5yZWFkTGluZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDI6IEluY29ycmVjdCBsaW5lIHdyaXR0ZW4gb3IgcmVhZDogIiArIGxpbmUsCisgICAgICAgICAgICAgICAgbGluZS5lcXVhbHMoImlwc3VtIikpOworICAgICAgICBsaW5lID0gZGlzLnJlYWRMaW5lKCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMzogSW5jb3JyZWN0IGxpbmUgd3JpdHRlbiBvciByZWFkOiAiICsgbGluZSwKKyAgICAgICAgICAgICAgICBsaW5lLmVxdWFscygiZG9sb3Igc2l0IGFtZXQuLi4iKSk7CisKKyAgICAgICAgZGlzLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkaXMucmVhZExpbmUoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkVW5zaWduZWRCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3Mud3JpdGVCeXRlKChieXRlKSAtMTI3KTsKKyAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgb3BlbkRhdGFJbnB1dFN0cmVhbSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IGJ5dGUgd3JpdHRlbiBvciByZWFkOyIsCisgICAgICAgICAgICAgICAgMTI5LCBkaXMucmVhZFVuc2lnbmVkQnl0ZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGlzLnJlYWRVbnNpZ25lZEJ5dGUoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBkaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRpcy5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZFVuc2lnbmVkU2hvcnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvcy53cml0ZVNob3J0KFNob3J0Lk1JTl9WQUxVRSk7CisgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIG9wZW5EYXRhSW5wdXRTdHJlYW0oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCBzaG9ydCB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICAoU2hvcnQuTUFYX1ZBTFVFICsgMSksIGRpcy5yZWFkVW5zaWduZWRTaG9ydCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGlzLnJlYWRVbnNpZ25lZFNob3J0KCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEVPRkV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgZGlzLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkaXMucmVhZFVuc2lnbmVkU2hvcnQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkVVRGTGphdmFfaW9fRGF0YUlucHV0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3Mud3JpdGVVVEYodW5paHcpOworICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICBvcGVuRGF0YUlucHV0U3RyZWFtKCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogSW5jb3JyZWN0IFVURi04IHN0cmluZyB3cml0dGVuIG9yIHJlYWQuIiwKKyAgICAgICAgICAgICAgICBEYXRhSW5wdXRTdHJlYW0ucmVhZFVURihkaXMpLmVxdWFscyh1bmlodykpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEYXRhSW5wdXRTdHJlYW0ucmVhZFVURihkaXMpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBFT0ZFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIGRpcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgRGF0YUlucHV0U3RyZWFtLnJlYWRVVEYoZGlzKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG9wZW5EYXRhSW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBkaXMgPSBuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShib3MudG9CeXRlQXJyYXkoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdXAgdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBvcGVuIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzIG1ldGhvZAorICAgICAqIGlzIGNhbGxlZCBiZWZvcmUgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIG9zID0gbmV3IERhdGFPdXRwdXRTdHJlYW0oYm9zKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWFycyBkb3duIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgY2xvc2UgYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMKKyAgICAgKiBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRpcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGREYXRhT3V0cHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGREYXRhT3V0cHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE0YmZjOGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZERhdGFPdXRwdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSwxOTkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9PdXRwdXRTdHJlYW07CisKK3B1YmxpYyBjbGFzcyBPbGREYXRhT3V0cHV0U3RyZWFtVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIERhdGFPdXRwdXRTdHJlYW0gb3M7CisKKyAgICBwcml2YXRlIERhdGFJbnB1dFN0cmVhbSBkaXM7CisKKyAgICBwcml2YXRlIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3M7CisKKyAgICBwcml2YXRlIFN1cHBvcnRfT3V0cHV0U3RyZWFtIHNvczsKKworICAgIFN0cmluZyB1bmlodyA9ICJcdTAwNDhcdTAwNjVcdTAwNkNcdTAwNkNcdTAwNkZcdTAwMjBcdTAwNTdcdTAwNkZcdTAwNzJcdTAwNkNcdTAwNjQiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHRlc3RTdHJpbmcgPSAiTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsXG4iICsKKyAgICAiY29uc2VjdGV0dXIgYWRpcGlzaWNpbmcgZWxpdCxcbnNlZCBkbyBlaXVzbW9kIHRlbXBvciBpbmNpZGlkdW50IHV0IiArCisgICAgImxhYm9yZSBldCBkb2xvcmUgbWFnbmEgYWxpcXVhLlxuIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCB0ZXN0TGVuZ3RoID0gdGVzdFN0cmluZy5sZW5ndGgoKTsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCdWZmZXJlZE91dHB1dFN0cmVhbSBidWYgPSBuZXcgQnVmZmVyZWRPdXRwdXRTdHJlYW0oYm9zKTsKKworICAgICAgICBvcyA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKGJ1Zik7CisgICAgICAgIG9zLndyaXRlSW50KDkwODc1ODkpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IFdyaXR0ZW4gZGF0YSBzaG91bGQgbm90IGJlIGF2YWlsYWJsZS4iLAorICAgICAgICAgICAgICAgIGJvcy50b0J5dGVBcnJheSgpLmxlbmd0aCA9PSAwKTsKKyAgICAgICAgb3MuZmx1c2goKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAyOiBXcml0dGVuIGRhdGEgc2hvdWxkIGJlIGF2YWlsYWJsZS4iLAorICAgICAgICAgICAgICAgIGJvcy50b0J5dGVBcnJheSgpLmxlbmd0aCA+IDApOworICAgICAgICBvcy5jbG9zZSgpOworCisgICAgICAgIG9wZW5EYXRhSW5wdXRTdHJlYW0oKTsKKyAgICAgICAgaW50IGMgPSBkaXMucmVhZEludCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMzogRmFpbGVkIHRvIGZsdXNoIGNvcnJlY3RseTsiLCA5MDg3NTg5LCBjKTsKKyAgICAgICAgZGlzLmNsb3NlKCk7CisKKyAgICAgICAgb3MgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShzb3MpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3MuZmx1c2goKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZSRCSUkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgcjsKKyAgICAgICAgb3Mud3JpdGUodGVzdFN0cmluZy5nZXRCeXRlcygpLCA1LCB0ZXN0TGVuZ3RoIC0gNyk7CisgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIG9wZW5EYXRhSW5wdXRTdHJlYW0oKTsKKyAgICAgICAgYnl0ZVtdIHJidWYgPSBuZXcgYnl0ZVt0ZXN0TGVuZ3RoXTsKKyAgICAgICAgciA9IGRpcy5yZWFkKHJidWYsIDAsIHRlc3RMZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IG51bWJlciBvZiBieXRlcyByZWFkOyIsCisgICAgICAgICAgICAgICAgdGVzdExlbmd0aCAtIDcsIHIpOworICAgICAgICBkaXMuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAyOiBJbmNvcnJlY3QgYnl0ZXMgd3JpdHRlbiBvciByZWFkLiIsCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZyhyYnVmLCAwLCByKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0U3RyaW5nLnN1YnN0cmluZyg1LCB0ZXN0TGVuZ3RoIC0gMikpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlJEJJSV9FeGNlcHRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gbnVsbEJ5dGVBcnJheSA9IG51bGw7CisgICAgICAgIGJ5dGVbXSBieXRlQXJyYXkgPSBuZXcgYnl0ZVsxMF07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9zLndyaXRlKG51bGxCeXRlQXJyYXksIDAsIDEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3Mud3JpdGUoYnl0ZUFycmF5LCAtMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3Mud3JpdGUoYnl0ZUFycmF5LCAwLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3Mud3JpdGUoYnl0ZUFycmF5LCAxLCAxMCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9zLndyaXRlKDQyKTsKKyAgICAgICAgb3MuY2xvc2UoKTsKKworICAgICAgICBvcGVuRGF0YUlucHV0U3RyZWFtKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgaW50IHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIDQyLCBkaXMucmVhZCgpKTsKKyAgICAgICAgZGlzLmNsb3NlKCk7CisKKyAgICAgICAgb3MgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShzb3MpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3Mud3JpdGUoNDIpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlQnl0ZXNMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9zLndyaXRlQnl0ZXModGVzdFN0cmluZyk7CisgICAgICAgIG9zLmNsb3NlKCk7CisKKyAgICAgICAgb3BlbkRhdGFJbnB1dFN0cmVhbSgpOworICAgICAgICBieXRlW10gcmJ1ZiA9IG5ldyBieXRlW3Rlc3RMZW5ndGhdOworICAgICAgICBkaXMucmVhZChyYnVmLCAwLCB0ZXN0TGVuZ3RoKTsKKyAgICAgICAgZGlzLmNsb3NlKCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogSW5jb3JyZWN0IGJ5dGVzIHdyaXR0ZW4gb3IgcmVhZC4iLAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmcocmJ1ZiwgMCwgdGVzdExlbmd0aCkuZXF1YWxzKHRlc3RTdHJpbmcpKTsKKworICAgICAgICBvcyA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKHNvcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcy53cml0ZUJ5dGVzKHRlc3RTdHJpbmcpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlQ2hhcnNMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9zLndyaXRlQ2hhcnModW5paHcpOworICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICBvcGVuRGF0YUlucHV0U3RyZWFtKCk7CisgICAgICAgIGNoYXJbXSBjaGFycyA9IG5ldyBjaGFyW3VuaWh3Lmxlbmd0aCgpXTsKKyAgICAgICAgaW50IGksIGEgPSBkaXMuYXZhaWxhYmxlKCkgLyAyOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYTsgaSsrKSBjaGFyc1tpXSA9IGRpcy5yZWFkQ2hhcigpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IGNoYXJzIHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIHVuaWh3LCBuZXcgU3RyaW5nKGNoYXJzLCAwLCBpKQorICAgICAgICApOworICAgICAgICBkaXMuY2xvc2UoKTsKKworICAgICAgICBvcyA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKHNvcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcy53cml0ZUNoYXJzKHVuaWh3KTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG9wZW5EYXRhSW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBkaXMgPSBuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShib3MudG9CeXRlQXJyYXkoKSkpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICBzb3MgPSBuZXcgU3VwcG9ydF9PdXRwdXRTdHJlYW0odHJ1ZSk7CisgICAgICAgIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgb3MgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShib3MpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgICAgICBzb3Muc2V0VGhyb3dzRXhjZXB0aW9uKGZhbHNlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChvcyAhPSBudWxsKQorICAgICAgICAgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgICAgICBpZiAoZGlzICE9IG51bGwpCisgICAgICAgICAgICAgICAgZGlzLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkRmlsZUlucHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRGaWxlSW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODk0ODQ5YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkRmlsZUlucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjA5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkZpbGVDaGFubmVsOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfUGxhdGZvcm1GaWxlOworCitwdWJsaWMgY2xhc3MgT2xkRmlsZUlucHV0U3RyZWFtVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyBTdHJpbmcgZmlsZU5hbWU7CisgICAgcHJpdmF0ZSBGaWxlSW5wdXRTdHJlYW0gaXM7CisgICAgcHVibGljIFN0cmluZyBmaWxlU3RyaW5nID0gIlRlc3RfQWxsX1Rlc3RzXG5UZXN0X2phdmFfaW9fQnVmZmVyZWRJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0J1ZmZlcmVkT3V0cHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fQnl0ZUFycmF5SW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19CeXRlQXJyYXlPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19EYXRhSW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19GaWxlXG5UZXN0X2phdmFfaW9fRmlsZURlc2NyaXB0b3JcblRlc3RfRmlsZUlucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fRmlsZU5vdEZvdW5kRXhjZXB0aW9uXG5UZXN0X2phdmFfaW9fRmlsZU91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0ZpbHRlcklucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fRmlsdGVyT3V0cHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fSW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19JT0V4Y2VwdGlvblxuVGVzdF9qYXZhX2lvX091dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX1ByaW50U3RyZWFtXG5UZXN0X2phdmFfaW9fUmFuZG9tQWNjZXNzRmlsZVxuVGVzdF9qYXZhX2lvX1N5bmNGYWlsZWRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0Fic3RyYWN0TWV0aG9kRXJyb3JcblRlc3RfamF2YV9sYW5nX0FyaXRobWV0aWNFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0FycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQXJyYXlTdG9yZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQm9vbGVhblxuVGVzdF9qYXZhX2xhbmdfQnl0ZVxuVGVzdF9qYXZhX2xhbmdfQ2hhcmFjdGVyXG5UZXN0X2phdmFfbGFuZ19DbGFzc1xuVGVzdF9qYXZhX2xhbmdfQ2xhc3NDYXN0RXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19DbGFzc0NpcmN1bGFyaXR5RXJyb3JcblRlc3RfamF2YV9sYW5nX0NsYXNzRm9ybWF0RXJyb3JcblRlc3RfamF2YV9sYW5nX0NsYXNzTG9hZGVyXG5UZXN0X2phdmFfbGFuZ19DbGFzc05vdEZvdW5kRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19DbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfRG91YmxlXG5UZXN0X2phdmFfbGFuZ19FcnJvclxuVGVzdF9qYXZhX2xhbmdfRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19FeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3JcblRlc3RfamF2YV9sYW5nX0Zsb2F0XG5UZXN0X2phdmFfbGFuZ19JbGxlZ2FsQWNjZXNzRXJyb3JcblRlc3RfamF2YV9sYW5nX0lsbGVnYWxBY2Nlc3NFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbmNvbXBhdGlibGVDbGFzc0NoYW5nZUVycm9yXG5UZXN0X2phdmFfbGFuZ19JbmRleE91dE9mQm91bmRzRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbnN0YW50aWF0aW9uRXJyb3JcblRlc3RfamF2YV9sYW5nX0luc3RhbnRpYXRpb25FeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0ludGVnZXJcblRlc3RfamF2YV9sYW5nX0ludGVybmFsRXJyb3JcblRlc3RfamF2YV9sYW5nX0ludGVycnVwdGVkRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19MaW5rYWdlRXJyb3JcblRlc3RfamF2YV9sYW5nX0xvbmdcblRlc3RfamF2YV9sYW5nX01hdGhcblRlc3RfamF2YV9sYW5nX05lZ2F0aXZlQXJyYXlTaXplRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19Ob0NsYXNzRGVmRm91bmRFcnJvclxuVGVzdF9qYXZhX2xhbmdfTm9TdWNoRmllbGRFcnJvclxuVGVzdF9qYXZhX2xhbmdfTm9TdWNoTWV0aG9kRXJyb3JcblRlc3RfamF2YV9sYW5nX051bGxQb2ludGVyRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19OdW1iZXJcblRlc3RfamF2YV9sYW5nX051bWJlckZvcm1hdEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfT2JqZWN0XG5UZXN0X2phdmFfbGFuZ19PdXRPZk1lbW9yeUVycm9yXG5UZXN0X2phdmFfbGFuZ19SdW50aW1lRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19TZWN1cml0eU1hbmFnZXJcblRlc3RfamF2YV9sYW5nX1Nob3J0XG5UZXN0X2phdmFfbGFuZ19TdGFja092ZXJmbG93RXJyb3JcblRlc3RfamF2YV9sYW5nX1N0cmluZ1xuVGVzdF9qYXZhX2xhbmdfU3RyaW5nQnVmZmVyXG5UZXN0X2phdmFfbGFuZ19TdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19TeXN0ZW1cblRlc3RfamF2YV9sYW5nX1RocmVhZFxuVGVzdF9qYXZhX2xhbmdfVGhyZWFkRGVhdGhcblRlc3RfamF2YV9sYW5nX1RocmVhZEdyb3VwXG5UZXN0X2phdmFfbGFuZ19UaHJvd2FibGVcblRlc3RfamF2YV9sYW5nX1Vua25vd25FcnJvclxuVGVzdF9qYXZhX2xhbmdfVW5zYXRpc2ZpZWRMaW5rRXJyb3JcblRlc3RfamF2YV9sYW5nX1ZlcmlmeUVycm9yXG5UZXN0X2phdmFfbGFuZ19WaXJ0dWFsTWFjaGluZUVycm9yXG5UZXN0X2phdmFfbGFuZ192bV9JbWFnZVxuVGVzdF9qYXZhX2xhbmdfdm1fTWVtb3J5U2VnbWVudFxuVGVzdF9qYXZhX2xhbmdfdm1fUk9NU3RvcmVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX3ZtX1ZNXG5UZXN0X2phdmFfbGFuZ19Wb2lkXG5UZXN0X2phdmFfbmV0X0JpbmRFeGNlcHRpb25cblRlc3RfamF2YV9uZXRfQ29ubmVjdEV4Y2VwdGlvblxuVGVzdF9qYXZhX25ldF9EYXRhZ3JhbVBhY2tldFxuVGVzdF9qYXZhX25ldF9EYXRhZ3JhbVNvY2tldFxuVGVzdF9qYXZhX25ldF9EYXRhZ3JhbVNvY2tldEltcGxcblRlc3RfamF2YV9uZXRfSW5ldEFkZHJlc3NcblRlc3RfamF2YV9uZXRfTm9Sb3V0ZVRvSG9zdEV4Y2VwdGlvblxuVGVzdF9qYXZhX25ldF9QbGFpbkRhdGFncmFtU29ja2V0SW1wbFxuVGVzdF9qYXZhX25ldF9QbGFpblNvY2tldEltcGxcblRlc3RfamF2YV9uZXRfU29ja2V0XG5UZXN0X2phdmFfbmV0X1NvY2tldEV4Y2VwdGlvblxuVGVzdF9qYXZhX25ldF9Tb2NrZXRJbXBsXG5UZXN0X2phdmFfbmV0X1NvY2tldElucHV0U3RyZWFtXG5UZXN0X2phdmFfbmV0X1NvY2tldE91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX25ldF9Vbmtub3duSG9zdEV4Y2VwdGlvblxuVGVzdF9qYXZhX3V0aWxfQXJyYXlFbnVtZXJhdG9yXG5UZXN0X2phdmFfdXRpbF9EYXRlXG5UZXN0X2phdmFfdXRpbF9FdmVudE9iamVjdFxuVGVzdF9qYXZhX3V0aWxfSGFzaEVudW1lcmF0b3JcblRlc3RfamF2YV91dGlsX0hhc2h0YWJsZVxuVGVzdF9qYXZhX3V0aWxfUHJvcGVydGllc1xuVGVzdF9qYXZhX3V0aWxfUmVzb3VyY2VCdW5kbGVcblRlc3RfamF2YV91dGlsX3RtXG5UZXN0X2phdmFfdXRpbF9WZWN0b3JcbiI7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fRmlsZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIEZpbGVJbnB1dFN0cmVhbShGaWxlKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoZmlsZU5hbWUpOworICAgICAgICAgICAgaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGYpOworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkZhaWxlZCB0byBjcmVhdGUgRmlsZUlucHV0U3RyZWFtIDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBGaWxlIGYyID0gbmV3IEZpbGUoIkltcHJvYmFibGVGaWxlLjQyIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZjIpOworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIGYyLmRlbGV0ZSgpOworICAgICAgICAgICAgZmFpbCgiRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fRmlsZURlc2NyaXB0b3IoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBGaWxlSW5wdXRTdHJlYW0gZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbSgoRmlsZURlc2NyaXB0b3IpIG51bGwpOworICAgICAgICAgICAgZmlzLmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBGaWxlSW5wdXRTdHJlYW0oamF2YS5sYW5nLlN0cmluZykKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlTmFtZSk7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRmFpbGVkIHRvIGNyZWF0ZSBGaWxlSW5wdXRTdHJlYW0gOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oIkltcHJvYmFibGVGaWxlLjQyIik7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICAgICAgbmV3IEZpbGUoIkltcHJvYmFibGVGaWxlLjQyIikuZGVsZXRlKCk7CisgICAgICAgICAgICBmYWlsKCJGaWxlTm90Rm91bmRFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGVOYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IFJldHVybmVkIGluY29ycmVjdCBudW1iZXIgb2YgYXZhaWxhYmxlIGJ5dGVzOyIsCisgICAgICAgICAgICAgICAgZmlsZVN0cmluZy5sZW5ndGgoKSwgaXMuYXZhaWxhYmxlKCkpOworICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMuYXZhaWxhYmxlKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Q2hhbm5lbCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIEZpbGVDaGFubmVsIEZpbGVJbnB1dFN0cmVhbS5nZXRDaGFubmVsKCkKKyAgICAgICAgRmlsZUNoYW5uZWwgY2hhbm5lbDsKKyAgICAgICAgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlWzEwMF07CisgICAgICAgIGJ5dGVbXSBzdHJpbmdCeXRlczsKKyAgICAgICAgZmluYWwgaW50IG9mZnNldCA9IDU7CisgICAgICAgIGJvb2xlYW4gZXF1YWwgPSB0cnVlOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBGaWxlSW5wdXRTdHJlYW0gZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlTmFtZSk7CisgICAgICAgICAgICBjaGFubmVsID0gZmlzLmdldENoYW5uZWwoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoY2hhbm5lbCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJDaGFubmVsIGlzIGNsb3NlZC4iLCBjaGFubmVsLmlzT3BlbigpKTsKKworICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGUgY2hhbm5lbCBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIGlucHV0IHN0cmVhbS4KKyAgICAgICAgICAgIGNoYW5uZWwucG9zaXRpb24ob2Zmc2V0KTsKKyAgICAgICAgICAgIGZpcy5yZWFkKGJ1ZmZlciwgMCwgMTApOworICAgICAgICAgICAgc3RyaW5nQnl0ZXMgPSBmaWxlU3RyaW5nLmdldEJ5dGVzKCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICAgICAgICAgICAgICBlcXVhbCAmPSAoYnVmZmVyW2ldID09IHN0cmluZ0J5dGVzW2kgKyBvZmZzZXRdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoIkNoYW5uZWwgaXMgbm90IGFzc29jaWF0ZWQgd2l0aCB0aGlzIHN0cmVhbS4iLCBlcXVhbCk7CisKKyAgICAgICAgICAgIGZpcy5jbG9zZSgpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIkNoYW5uZWwgaGFzIG5vdCBiZWVuIGNsb3NlZC4iLCBjaGFubmVsLmlzT3BlbigpKTsKKyAgICAgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkNvdWxkIG5vdCBmaW5kIDogIiArIGZpbGVOYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGVOYW1lKTsKKyAgICAgICAgaW50IGMgPSBpcy5yZWFkKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBSZWFkIHJldHVybmVkIGluY29ycmVjdCBjaGFyOyIsCisgICAgICAgICAgICAgICAgZmlsZVN0cmluZy5jaGFyQXQoMCksIGMpOworCisgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCRCKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZjEgPSBuZXcgYnl0ZVsxMDBdOworICAgICAgICBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZU5hbWUpOworICAgICAgICBpcy5za2lwKDMwMDApOworICAgICAgICBpcy5yZWFkKGJ1ZjEpOworICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IEZhaWxlZCB0byByZWFkIGNvcnJlY3QgZGF0YS4iLAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmcoYnVmMSwgMCwgYnVmMS5sZW5ndGgpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVTdHJpbmcuc3Vic3RyaW5nKDMwMDAsIDMxMDApKSk7CisKKyAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWQoYnVmMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2tpcEooKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gYnVmMSA9IG5ldyBieXRlWzEwXTsKKyAgICAgICAgaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGVOYW1lKTsKKyAgICAgICAgaXMuc2tpcCgxMDAwKTsKKyAgICAgICAgaXMucmVhZChidWYxLCAwLCBidWYxLmxlbmd0aCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogRmFpbGVkIHRvIHNraXAgdG8gY29ycmVjdCBwb3NpdGlvbi4iLAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmcoYnVmMSwgMCwgYnVmMS5sZW5ndGgpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVTdHJpbmcuc3Vic3RyaW5nKDEwMDAsIDEwMTApKSk7CisKKyAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmlsZU5hbWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaW8udG1wZGlyIik7CisgICAgICAgIFN0cmluZyBzZXBhcmF0b3IgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImZpbGUuc2VwYXJhdG9yIik7CisgICAgICAgIGlmIChmaWxlTmFtZS5jaGFyQXQoZmlsZU5hbWUubGVuZ3RoKCkgLSAxKSA9PSBzZXBhcmF0b3IuY2hhckF0KDApKQorICAgICAgICAgICAgZmlsZU5hbWUgPSBTdXBwb3J0X1BsYXRmb3JtRmlsZS5nZXROZXdQbGF0Zm9ybUZpbGUoZmlsZU5hbWUsCisgICAgICAgICAgICAgICAgICAgICJpbnB1dC50c3QiKTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgZmlsZU5hbWUgPSBTdXBwb3J0X1BsYXRmb3JtRmlsZS5nZXROZXdQbGF0Zm9ybUZpbGUoZmlsZU5hbWUKKyAgICAgICAgICAgICAgICAgICAgKyBzZXBhcmF0b3IsICJpbnB1dC50c3QiKTsKKyAgICAgICAgamF2YS5pby5PdXRwdXRTdHJlYW0gZm9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZU5hbWUpOworICAgICAgICBmb3Mud3JpdGUoZmlsZVN0cmluZy5nZXRCeXRlcygpKTsKKyAgICAgICAgZm9zLmNsb3NlKCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGlzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICAgICAgbmV3IEZpbGUoZmlsZU5hbWUpLmRlbGV0ZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkRmlsZVJlYWRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkRmlsZVJlYWRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYjU0MWYzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRGaWxlUmVhZGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsZVJlYWRlcjsKKworcHVibGljIGNsYXNzIE9sZEZpbGVSZWFkZXJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIEZpbGVSZWFkZXIgYnI7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fRmlsZSgpIHsKKyAgICAgICAgRmlsZSBub0ZpbGUgPSBuZXcgRmlsZShTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaW8udG1wZGlyIiksICJub3JlYWRlci50c3QiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJyID0gbmV3IEZpbGVSZWFkZXIobm9GaWxlKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiciA9IG5ldyBGaWxlUmVhZGVyKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKSArICIvbm9yZWFkZXIudHN0Iik7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRGaWxlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRGaWxlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyNjVkMjAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEZpbGVUZXN0LmphdmEKQEAgLTAsMCArMSwyNDEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IHN0YXRpYyB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfRXhlYy5leGVjQW5kR2V0T3V0cHV0OworaW1wb3J0IHN0YXRpYyB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfRXhlYy5qYXZhUHJvY2Vzc0J1aWxkZXI7CisKK3B1YmxpYyBjbGFzcyBPbGRGaWxlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKiBMb2NhdGlvbiB0byBzdG9yZSB0ZXN0cyBpbiAqLworICAgIHByaXZhdGUgRmlsZSB0ZW1wRGlyZWN0b3J5OworCisgICAgLyoqIFRlbXAgZmlsZSB0aGF0IGRvZXMgZXhpc3QgKi8KKyAgICBwcml2YXRlIEZpbGUgdGVtcEZpbGU7CisKKyAgICAvKiogRmlsZSBzZXBhcmF0b3IgKi8KKyAgICBwcml2YXRlIFN0cmluZyBzbGFzaCA9IEZpbGUuc2VwYXJhdG9yOworCisgICAgcHVibGljIFN0cmluZyBmaWxlU3RyaW5nID0gIlRlc3RfQWxsX1Rlc3RzXG5UZXN0X2phdmFfaW9fQnVmZmVyZWRJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0J1ZmZlcmVkT3V0cHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fQnl0ZUFycmF5SW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19CeXRlQXJyYXlPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19EYXRhSW5wdXRTdHJlYW1cblRlc3RfRmlsZVxuVGVzdF9GaWxlRGVzY3JpcHRvclxuVGVzdF9GaWxlSW5wdXRTdHJlYW1cblRlc3RfRmlsZU5vdEZvdW5kRXhjZXB0aW9uXG5UZXN0X0ZpbGVPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19GaWx0ZXJJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0ZpbHRlck91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0lucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fSU9FeGNlcHRpb25cblRlc3RfamF2YV9pb19PdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19QcmludFN0cmVhbVxuVGVzdF9qYXZhX2lvX1JhbmRvbUFjY2Vzc0ZpbGVcblRlc3RfamF2YV9pb19TeW5jRmFpbGVkRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19BYnN0cmFjdE1ldGhvZEVycm9yXG5UZXN0X2phdmFfbGFuZ19Bcml0aG1ldGljRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0FycmF5U3RvcmVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0Jvb2xlYW5cblRlc3RfamF2YV9sYW5nX0J5dGVcblRlc3RfamF2YV9sYW5nX0NoYXJhY3RlclxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NcblRlc3RfamF2YV9sYW5nX0NsYXNzQ2FzdEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NDaXJjdWxhcml0eUVycm9yXG5UZXN0X2phdmFfbGFuZ19DbGFzc0Zvcm1hdEVycm9yXG5UZXN0X2phdmFfbGFuZ19DbGFzc0xvYWRlclxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0RvdWJsZVxuVGVzdF9qYXZhX2xhbmdfRXJyb3JcblRlc3RfamF2YV9sYW5nX0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfRXhjZXB0aW9uSW5Jbml0aWFsaXplckVycm9yXG5UZXN0X2phdmFfbGFuZ19GbG9hdFxuVGVzdF9qYXZhX2xhbmdfSWxsZWdhbEFjY2Vzc0Vycm9yXG5UZXN0X2phdmFfbGFuZ19JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0lsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0lsbGVnYWxUaHJlYWRTdGF0ZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSW5jb21wYXRpYmxlQ2xhc3NDaGFuZ2VFcnJvclxuVGVzdF9qYXZhX2xhbmdfSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSW5zdGFudGlhdGlvbkVycm9yXG5UZXN0X2phdmFfbGFuZ19JbnN0YW50aWF0aW9uRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbnRlZ2VyXG5UZXN0X2phdmFfbGFuZ19JbnRlcm5hbEVycm9yXG5UZXN0X2phdmFfbGFuZ19JbnRlcnJ1cHRlZEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfTGlua2FnZUVycm9yXG5UZXN0X2phdmFfbGFuZ19Mb25nXG5UZXN0X2phdmFfbGFuZ19NYXRoXG5UZXN0X2phdmFfbGFuZ19OZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfTm9DbGFzc0RlZkZvdW5kRXJyb3JcblRlc3RfamF2YV9sYW5nX05vU3VjaEZpZWxkRXJyb3JcblRlc3RfamF2YV9sYW5nX05vU3VjaE1ldGhvZEVycm9yXG5UZXN0X2phdmFfbGFuZ19OdWxsUG9pbnRlckV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfTnVtYmVyXG5UZXN0X2phdmFfbGFuZ19OdW1iZXJGb3JtYXRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX09iamVjdFxuVGVzdF9qYXZhX2xhbmdfT3V0T2ZNZW1vcnlFcnJvclxuVGVzdF9qYXZhX2xhbmdfUnVudGltZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfU2VjdXJpdHlNYW5hZ2VyXG5UZXN0X2phdmFfbGFuZ19TaG9ydFxuVGVzdF9qYXZhX2xhbmdfU3RhY2tPdmVyZmxvd0Vycm9yXG5UZXN0X2phdmFfbGFuZ19TdHJpbmdcblRlc3RfamF2YV9sYW5nX1N0cmluZ0J1ZmZlclxuVGVzdF9qYXZhX2xhbmdfU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfU3lzdGVtXG5UZXN0X2phdmFfbGFuZ19UaHJlYWRcblRlc3RfamF2YV9sYW5nX1RocmVhZERlYXRoXG5UZXN0X2phdmFfbGFuZ19UaHJlYWRHcm91cFxuVGVzdF9qYXZhX2xhbmdfVGhyb3dhYmxlXG5UZXN0X2phdmFfbGFuZ19Vbmtub3duRXJyb3JcblRlc3RfamF2YV9sYW5nX1Vuc2F0aXNmaWVkTGlua0Vycm9yXG5UZXN0X2phdmFfbGFuZ19WZXJpZnlFcnJvclxuVGVzdF9qYXZhX2xhbmdfVmlydHVhbE1hY2hpbmVFcnJvclxuVGVzdF9qYXZhX2xhbmdfdm1fSW1hZ2VcblRlc3RfamF2YV9sYW5nX3ZtX01lbW9yeVNlZ21lbnRcblRlc3RfamF2YV9sYW5nX3ZtX1JPTVN0b3JlRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ192bV9WTVxuVGVzdF9qYXZhX2xhbmdfVm9pZFxuVGVzdF9qYXZhX25ldF9CaW5kRXhjZXB0aW9uXG5UZXN0X2phdmFfbmV0X0Nvbm5lY3RFeGNlcHRpb25cblRlc3RfamF2YV9uZXRfRGF0YWdyYW1QYWNrZXRcblRlc3RfamF2YV9uZXRfRGF0YWdyYW1Tb2NrZXRcblRlc3RfamF2YV9uZXRfRGF0YWdyYW1Tb2NrZXRJbXBsXG5UZXN0X2phdmFfbmV0X0luZXRBZGRyZXNzXG5UZXN0X2phdmFfbmV0X05vUm91dGVUb0hvc3RFeGNlcHRpb25cblRlc3RfamF2YV9uZXRfUGxhaW5EYXRhZ3JhbVNvY2tldEltcGxcblRlc3RfamF2YV9uZXRfUGxhaW5Tb2NrZXRJbXBsXG5UZXN0X2phdmFfbmV0X1NvY2tldFxuVGVzdF9qYXZhX25ldF9Tb2NrZXRFeGNlcHRpb25cblRlc3RfamF2YV9uZXRfU29ja2V0SW1wbFxuVGVzdF9qYXZhX25ldF9Tb2NrZXRJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX25ldF9Tb2NrZXRPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9uZXRfVW5rbm93bkhvc3RFeGNlcHRpb25cblRlc3RfamF2YV91dGlsX0FycmF5RW51bWVyYXRvclxuVGVzdF9qYXZhX3V0aWxfRGF0ZVxuVGVzdF9qYXZhX3V0aWxfRXZlbnRPYmplY3RcblRlc3RfamF2YV91dGlsX0hhc2hFbnVtZXJhdG9yXG5UZXN0X2phdmFfdXRpbF9IYXNodGFibGVcblRlc3RfamF2YV91dGlsX1Byb3BlcnRpZXNcblRlc3RfamF2YV91dGlsX1Jlc291cmNlQnVuZGxlXG5UZXN0X2phdmFfdXRpbF90bVxuVGVzdF9qYXZhX3V0aWxfVmVjdG9yXG4iOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHBsYXRmb3JtSWQgPSAiQW5kcm9pZCIKKyAgICAgICAgICAgICsgU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLnZtLnZlcnNpb24iKS5yZXBsYWNlKCcuJywgJy0nKTsKKworICAgIHsKKyAgICAgICAgLy8gRGVsZXRlIGFsbCBvbGQgdGVtcG9yYXJ5IGZpbGVzCisgICAgICAgIEZpbGUgdGVtcERpciA9IG5ldyBGaWxlKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKSk7CisgICAgICAgIFN0cmluZ1tdIGZpbGVzID0gdGVtcERpci5saXN0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIEZpbGUgZiA9IG5ldyBGaWxlKHRlbXBEaXIsIGZpbGVzW2ldKTsKKyAgICAgICAgICAgIGlmIChmLmlzRGlyZWN0b3J5KCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoZmlsZXNbaV0uc3RhcnRzV2l0aCgiaHl0c19yZXNvdXJjZXMiKSkKKyAgICAgICAgICAgICAgICAgICAgZGVsZXRlVGVtcEZvbGRlcihmKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChmaWxlc1tpXS5zdGFydHNXaXRoKCJoeXRzXyIpIHx8IGZpbGVzW2ldLnN0YXJ0c1dpdGgoImh5amFyXyIpKQorICAgICAgICAgICAgICAgIG5ldyBGaWxlKHRlbXBEaXIsIGZpbGVzW2ldKS5kZWxldGUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBkZWxldGVUZW1wRm9sZGVyKEZpbGUgZGlyKSB7CisgICAgICAgIFN0cmluZyBmaWxlc1tdID0gZGlyLmxpc3QoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoZGlyLCBmaWxlc1tpXSk7CisgICAgICAgICAgICBpZiAoZi5pc0RpcmVjdG9yeSgpKQorICAgICAgICAgICAgICAgIGRlbGV0ZVRlbXBGb2xkZXIoZik7CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICBmLmRlbGV0ZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGRpci5kZWxldGUoKTsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9pb19GaWxlTGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGVycm9yOworICAgICAgICBTdHJpbmcgZGlyTmFtZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKTsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJ1c2VyLmRpciIsIGRpck5hbWUpOworCisgICAgICAgIEZpbGUgZCA9IG5ldyBGaWxlKGRpck5hbWUpOworICAgICAgICBGaWxlIGYgPSBuZXcgRmlsZShkLCAiaW5wdXQudHN0Iik7CisgICAgICAgIGlmICghZGlyTmFtZS5yZWdpb25NYXRjaGVzKChkaXJOYW1lLmxlbmd0aCgpIC0gMSksIHNsYXNoLCAwLCAxKSkKKyAgICAgICAgICAgIGRpck5hbWUgKz0gc2xhc2g7CisgICAgICAgIGRpck5hbWUgKz0gImlucHV0LnRzdCI7CisgICAgICAgIGVycm9yID0gU3RyaW5nLmZvcm1hdCgiVGVzdCAxOiBJbmNvcnJlY3QgZmlsZSBjcmVhdGVkOiAlczsgJXMgZXhwZWN0ZWQuIiwgZi5nZXRQYXRoKCksIGRpck5hbWUpOworICAgICAgICBhc3NlcnRUcnVlKGVycm9yLCBmLmdldFBhdGgoKS5lcXVhbHMoZGlyTmFtZSkpOworCisgICAgICAgIFN0cmluZyBmaWxlTmFtZSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0gbmV3IEZpbGUoZCwgZmlsZU5hbWUpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgZCA9IG51bGw7CisgICAgICAgIGYgPSBuZXcgRmlsZShkLCAiaW5wdXQudHN0Iik7CisgICAgICAgIGVycm9yID0gU3RyaW5nLmZvcm1hdCgiVGVzdCAzOiBJbmNvcnJlY3QgZmlsZSBjcmVhdGVkOiAlczsgJXMgZXhwZWN0ZWQuIiwKKyAgICAgICAgICAgICAgICBmLmdldEFic29sdXRlUGF0aCgpLCBkaXJOYW1lKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShlcnJvciwgZi5nZXRBYnNvbHV0ZVBhdGgoKS5lcXVhbHMoZGlyTmFtZSkpOworCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgSGFybW9ueS0zODIKKyAgICAgICAgRmlsZSBzID0gbnVsbDsKKyAgICAgICAgZiA9IG5ldyBGaWxlKCIvYWJjIik7CisgICAgICAgIGQgPSBuZXcgRmlsZShzLCAiL2FiYyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNDogSW5jb3JyZWN0IGZpbGUgY3JlYXRlZDsiLAorICAgICAgICAgICAgICAgIGYuZ2V0QWJzb2x1dGVQYXRoKCksIGQuZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGRpck5hbWUgPSBudWxsOworICAgICAgICBTdHJpbmcgZmlsZU5hbWUgPSAiaW5wdXQudHN0IjsKKworICAgICAgICBTdHJpbmcgdXNlckRpciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKTsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJ1c2VyLmRpciIsIHVzZXJEaXIpOworCisgICAgICAgIEZpbGUgZiA9IG5ldyBGaWxlKGRpck5hbWUsIGZpbGVOYW1lKTsKKyAgICAgICAgaWYgKCF1c2VyRGlyLnJlZ2lvbk1hdGNoZXMoKHVzZXJEaXIubGVuZ3RoKCkgLSAxKSwgc2xhc2gsIDAsIDEpKQorICAgICAgICAgICAgdXNlckRpciArPSBzbGFzaDsKKyAgICAgICAgdXNlckRpciArPSAiaW5wdXQudHN0IjsKKyAgICAgICAgU3RyaW5nIGVycm9yID0gU3RyaW5nLmZvcm1hdCgiVGVzdCAxOiBJbmNvcnJlY3QgZmlsZSBjcmVhdGVkOiAlczsgJXMgZXhwZWN0ZWQuIiwKKyAgICAgICAgICAgICAgICBmLmdldEFic29sdXRlUGF0aCgpLCB1c2VyRGlyKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShlcnJvciwgZi5nZXRBYnNvbHV0ZVBhdGgoKS5lcXVhbHModXNlckRpcikpOworCisgICAgICAgIGRpck5hbWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaW8udG1wZGlyIik7CisgICAgICAgIGZpbGVOYW1lID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSBuZXcgRmlsZShkaXJOYW1lLCBmaWxlTmFtZSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIGZpbGVOYW1lID0gImlucHV0LnRzdCI7CisgICAgICAgIGYgPSBuZXcgRmlsZShkaXJOYW1lLCBmaWxlTmFtZSk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMzogSW5jb3JyZWN0IGZpbGUgY3JlYXRlZC4iLCBmLmdldFBhdGgoKQorICAgICAgICAgICAgICAgIC5lcXVhbHModXNlckRpcikpOworCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgSGFybW9ueS0zODIKKyAgICAgICAgU3RyaW5nIHMgPSBudWxsOworICAgICAgICBmID0gbmV3IEZpbGUoIi9hYmMiKTsKKyAgICAgICAgRmlsZSBkID0gbmV3IEZpbGUocywgIi9hYmMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDQ6IEluY29ycmVjdCBmaWxlIGNyZWF0ZWQ7IiwgZC5nZXRBYnNvbHV0ZVBhdGgoKSwgZgorICAgICAgICAgICAgICAgIC5nZXRBYnNvbHV0ZVBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDM6IENyZWF0ZWQgSW5jb3JyZWN0IEZpbGUiLCAiL2FiYyIsIGYKKyAgICAgICAgICAgICAgICAuZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY3JlYXRlVGVtcEZpbGVMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gUHJvdmlkaW5nIGFuIGlsbGVnYWwgZmlsZSBwcmVmaXguCisgICAgICAgICAgICBGaWxlIGYzID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiLy4uLy4uLy4uLy4uLy4uLyIsIG51bGwpOworICAgICAgICAgICAgZjMuZGVsZXRlKCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVuYW1lVG9MamF2YV9pb19GaWxlKCkgeworICAgICAgICBTdHJpbmcgYmFzZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKTsKKyAgICAgICAgRmlsZSBkaXIgPSBuZXcgRmlsZShiYXNlLCBwbGF0Zm9ybUlkKTsKKyAgICAgICAgZGlyLm1rZGlyKCk7CisgICAgICAgIEZpbGUgZiA9IG5ldyBGaWxlKGRpciwgInh4eC54eHgiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYucmVuYW1lVG8obnVsbCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9VUkwzKCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgZGlyID0gbmV3IEZpbGUoIiIpOyAvLyBjdXJyZW50IGRpcmVjdG9yeQorICAgICAgICBTdHJpbmcgbmV3RGlyVVJMID0gZGlyLnRvVVJMKCkudG9TdHJpbmcoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBVUkwgZG9lcyBub3QgZW5kIHdpdGggc2xhc2guIiwKKyAgICAgICAgICAgICAgICBuZXdEaXJVUkwuZW5kc1dpdGgoIi8iKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9kZWxldGVPbkV4aXQoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGN0cyA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKTsKKyAgICAgICAgRmlsZSBkaXIgPSBuZXcgRmlsZShjdHMgKyAiL2hlbGxvIik7CisgICAgICAgIGRpci5ta2RpcigpOworICAgICAgICBhc3NlcnRUcnVlKGRpci5leGlzdHMoKSk7CisgICAgICAgIEZpbGUgc3ViRGlyID0gbmV3IEZpbGUoY3RzICsgIi9oZWxsby93b3JsZCIpOworICAgICAgICBzdWJEaXIubWtkaXIoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzdWJEaXIuZXhpc3RzKCkpOworCisgICAgICAgIFVSTCB1cmwgPSBnZXRDbGFzcygpLmdldFJlc291cmNlKCIvSGVsbG9Xb3JsZC50eHQiKTsKKyAgICAgICAgU3RyaW5nIGNsYXNzUGF0aCA9IHVybC50b1N0cmluZygpOworICAgICAgICBpbnQgaWR4ID0gY2xhc3NQYXRoLmluZGV4T2YoIiEiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiY291bGQgbm90IGZpbmQgdGhlIHBhdGggb2YgdGhlIHRlc3QgamFyL2FwayIsIGlkeCA+IDApOworICAgICAgICBjbGFzc1BhdGggPSBjbGFzc1BhdGguc3Vic3RyaW5nKDksIGlkeCk7IC8vIGN1dHRpbmcgb2ZmIGphcjpmaWxlOgorCisgICAgICAgIFByb2Nlc3NCdWlsZGVyIGJ1aWxkZXIgPSBqYXZhUHJvY2Vzc0J1aWxkZXIoKTsKKyAgICAgICAgYnVpbGRlci5jb21tYW5kKCkuYWRkKCItY3AiKTsKKyAgICAgICAgYnVpbGRlci5jb21tYW5kKCkuYWRkKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5jbGFzcy5wYXRoIikpOworICAgICAgICBidWlsZGVyLmNvbW1hbmQoKS5hZGQoInRlc3RzLnN1cHBvcnQuU3VwcG9ydF9EZWxldGVPbkV4aXRUZXN0Iik7CisgICAgICAgIGJ1aWxkZXIuY29tbWFuZCgpLmFkZChkaXIuZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgICAgICBidWlsZGVyLmNvbW1hbmQoKS5hZGQoc3ViRGlyLmdldEFic29sdXRlUGF0aCgpKTsKKyAgICAgICAgZXhlY0FuZEdldE91dHB1dChidWlsZGVyKTsKKworICAgICAgICBhc3NlcnRGYWxzZShkaXIuZXhpc3RzKCkpOworICAgICAgICBhc3NlcnRGYWxzZShzdWJEaXIuZXhpc3RzKCkpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisKKyAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgc3lzdGVtIHByb3BlcnRpZXMgYXJlIHNldCBjb3JyZWN0bHkKKyAgICAgICAgU3RyaW5nIHVzZXJEaXIgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaW8udG1wZGlyIik7CisgICAgICAgIGlmICh1c2VyRGlyID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJTeXN0ZW0gcHJvcGVydHkgamF2YS5pby50bXBkaXIgbm90IGRlZmluZWQuIik7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiLCB1c2VyRGlyKTsKKworICAgICAgICAvKiogU2V0dXAgdGhlIHRlbXBvcmFyeSBkaXJlY3RvcnkgKi8KKyAgICAgICAgaWYgKCF1c2VyRGlyLnJlZ2lvbk1hdGNoZXMoKHVzZXJEaXIubGVuZ3RoKCkgLSAxKSwgc2xhc2gsIDAsIDEpKQorICAgICAgICAgICAgdXNlckRpciArPSBzbGFzaDsKKyAgICAgICAgdGVtcERpcmVjdG9yeSA9IG5ldyBGaWxlKHVzZXJEaXIgKyAidGVtcERpciIKKyAgICAgICAgICAgICAgICArIFN0cmluZy52YWx1ZU9mKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKSk7CisgICAgICAgIGlmICghdGVtcERpcmVjdG9yeS5ta2RpcigpKQorICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJTZXR1cCBmb3IgT2xkRmlsZVRlc3QgZmFpbGVkICgxKS4iKTsKKworICAgICAgICAvKiogU2V0dXAgdGhlIHRlbXBvcmFyeSBmaWxlICovCisgICAgICAgIHRlbXBGaWxlID0gbmV3IEZpbGUodGVtcERpcmVjdG9yeSwgInRlbXBmaWxlIik7CisgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gdGVtcFN0cmVhbTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRlbXBTdHJlYW0gPSBuZXcgRmlsZU91dHB1dFN0cmVhbSh0ZW1wRmlsZS5nZXRQYXRoKCksIGZhbHNlKTsKKyAgICAgICAgICAgIHRlbXBTdHJlYW0uY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJTZXR1cCBmb3IgT2xkRmlsZVRlc3QgZmFpbGVkICgyKS4iKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgICAgICBpZiAodGVtcEZpbGUuZXhpc3RzKCkgJiYgIXRlbXBGaWxlLmRlbGV0ZSgpKQorICAgICAgICAgICAgU3lzdGVtLm91dAorICAgICAgICAgICAgICAgICAgICAucHJpbnRsbigiT2xkRmlsZVRlc3QudGVhckRvd24oKSBmYWlsZWQsIGNvdWxkIG5vdCBkZWxldGUgZmlsZSEiKTsKKyAgICAgICAgaWYgKCF0ZW1wRGlyZWN0b3J5LmRlbGV0ZSgpKQorICAgICAgICAgICAgU3lzdGVtLm91dAorICAgICAgICAgICAgICAgICAgICAucHJpbnRsbigiT2xkRmlsZVRlc3QudGVhckRvd24oKSBmYWlsZWQsIGNvdWxkIG5vdCBkZWxldGUgZGlyZWN0b3J5ISIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkRmlsZVdyaXRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkRmlsZVdyaXRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZGI5YTNlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRGaWxlV3JpdGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTY0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRXcml0ZXI7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZVJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLkZpbGVXcml0ZXI7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZEZpbGVXcml0ZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgRmlsZVdyaXRlciBmdzsKKworICAgIEZpbGVJbnB1dFN0cmVhbSBmaXM7CisKKyAgICBCdWZmZXJlZFdyaXRlciBidzsKKworICAgIEZpbGUgZjsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9pb19GaWxlX0lPRXhjZXB0aW9uKCkgeworICAgICAgICBGaWxlIGRpciA9IG5ldyBGaWxlKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZ3ID0gbmV3IEZpbGVXcml0ZXIoZGlyKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX0ZpbGVaX0lPRXhjZXB0aW9uKCkgeworICAgICAgICBGaWxlIGRpciA9IG5ldyBGaWxlKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZ3ID0gbmV3IEZpbGVXcml0ZXIoZGlyLCB0cnVlKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfU3RyaW5nX0lPRXhjZXB0aW9uKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgZncgPSBuZXcgRmlsZVdyaXRlcihTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaW8udG1wZGlyIikpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZ1pfSU9FeGNlcHRpb24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmdyA9IG5ldyBGaWxlV3JpdGVyKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKSwgZmFsc2UpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhbmRsZUVhcmx5RU9GQ2hhcl8xKCkgeworICAgICAgICBTdHJpbmcgc3RyID0gIkFsbCB3b3JrIGFuZCBubyBwbGF5IG1ha2VzIEphY2sgYSBkdWxsIGJveVxuIjsKKyAgICAgICAgaW50IE5VTUJFUiA9IDIwNDg7CisgICAgICAgIGludCBqID0gMDsKKyAgICAgICAgaW50IGxlbiA9IHN0ci5sZW5ndGgoKSAqIE5VTUJFUjsKKyAgICAgICAgLyogPT0gODgwNjQgKi8vKiBOVU1CRVIgY29tcHVsc2l2ZWx5IHdyaXR0ZW4gY29waWVzIG9mIHRoZSBzYW1lIHN0cmluZyAqLworICAgICAgICBjaGFyW10gc3RyQ2hhcnMgPSBuZXcgY2hhcltsZW5dOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE5VTUJFUjsgKytpKSB7CisgICAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IHN0ci5sZW5ndGgoKTsgKytrKSB7CisgICAgICAgICAgICAgICAgc3RyQ2hhcnNbaisrXSA9IHN0ci5jaGFyQXQoayk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgRmlsZSBmID0gbnVsbDsKKyAgICAgICAgRmlsZVdyaXRlciBmdyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgib255IiwgImJ5X29uZSIpOworICAgICAgICAgICAgZncgPSBuZXcgRmlsZVdyaXRlcihmKTsKKyAgICAgICAgICAgIGZ3LndyaXRlKHN0ckNoYXJzKTsKKyAgICAgICAgICAgIGZ3LmNsb3NlKCk7CisgICAgICAgICAgICBJbnB1dFN0cmVhbVJlYWRlciBpbiA9IG51bGw7CisgICAgICAgICAgICBGaWxlSW5wdXRTdHJlYW0gZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmKTsKKyAgICAgICAgICAgIGluID0gbmV3IElucHV0U3RyZWFtUmVhZGVyKGZpcyk7CisgICAgICAgICAgICBpbnQgYjsKKyAgICAgICAgICAgIGludCBlcnJvcnMgPSAwOworICAgICAgICAgICAgZm9yIChpbnQgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgc3RyQ2hhcnMubGVuZ3RoOyArK29mZnNldCkgeworICAgICAgICAgICAgICAgIGIgPSBpbi5yZWFkKCk7CisgICAgICAgICAgICAgICAgaWYgKGIgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiRWFybHkgRU9GIGF0IG9mZnNldCAiICsgb2Zmc2V0ICsgIlxuIik7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZXJyb3JzKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGFuZGxlRWFybHlFT0ZDaGFyXzIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgY2FwYWNpdHkgPSA2NTUzNjsKKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbY2FwYWNpdHldOworICAgICAgICBieXRlW10gYnMgPSB7CisgICAgICAgICAgICAgICAgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLCAnSCcKKyAgICAgICAgfTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYnl0ZXNbaV0gPSBic1tpIC8gODE5Ml07CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIGlucHV0U3RyID0gbmV3IFN0cmluZyhieXRlcyk7CisgICAgICAgIGludCBsZW4gPSBpbnB1dFN0ci5sZW5ndGgoKTsKKyAgICAgICAgRmlsZSBmID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiRmlsZVdyaXRlckJ1Z1Rlc3QgIiwgbnVsbCk7CisgICAgICAgIEZpbGVXcml0ZXIgd3JpdGVyID0gbmV3IEZpbGVXcml0ZXIoZik7CisgICAgICAgIHdyaXRlci53cml0ZShpbnB1dFN0cik7CisgICAgICAgIHdyaXRlci5jbG9zZSgpOworICAgICAgICBsb25nIGZsZW4gPSBmLmxlbmd0aCgpOworCisgICAgICAgIEZpbGVSZWFkZXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoZik7CisgICAgICAgIGNoYXJbXSBvdXRDaGFycyA9IG5ldyBjaGFyW2NhcGFjaXR5XTsKKyAgICAgICAgaW50IG91dENvdW50ID0gcmVhZGVyLnJlYWQob3V0Q2hhcnMpOworICAgICAgICBTdHJpbmcgb3V0U3RyID0gbmV3IFN0cmluZyhvdXRDaGFycywgMCwgb3V0Q291bnQpOworCisgICAgICAgIGYuZGVsZXRlT25FeGl0KCk7CisgICAgICAgIGFzc2VydEVxdWFscyhsZW4sIGZsZW4pOworICAgICAgICBhc3NlcnRFcXVhbHMoaW5wdXRTdHIsIG91dFN0cik7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZiA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoIndyaXRlciIsICIudHN0Iik7CisKKyAgICAgICAgaWYgKGYuZXhpc3RzKCkpCisgICAgICAgICAgICBpZiAoIWYuZGVsZXRlKCkpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmFibGUgdG8gZGVsZXRlIHRlc3QgZmlsZSIpOworICAgICAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYncuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZmlzLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZi5kZWxldGUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEZpbHRlcklucHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRGaWx0ZXJJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NDhiMWJmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRGaWx0ZXJJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDMyMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWx0ZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfUGxhdGZvcm1GaWxlOworCitwdWJsaWMgY2xhc3MgT2xkRmlsdGVySW5wdXRTdHJlYW1UZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBjbGFzcyBNeUZpbHRlcklucHV0U3RyZWFtIGV4dGVuZHMgamF2YS5pby5GaWx0ZXJJbnB1dFN0cmVhbSB7CisgICAgICAgIHB1YmxpYyBNeUZpbHRlcklucHV0U3RyZWFtKGphdmEuaW8uSW5wdXRTdHJlYW0gaXMpIHsKKyAgICAgICAgICAgIHN1cGVyKGlzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGZpbGVOYW1lOworCisgICAgcHJpdmF0ZSBGaWx0ZXJJbnB1dFN0cmVhbSBpczsKKworICAgIGJ5dGVbXSBpYnVmID0gbmV3IGJ5dGVbNDA5Nl07CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgdGVzdFN0cmluZyA9ICJMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCxcbiIgKworICAgICJjb25zZWN0ZXR1ciBhZGlwaXNpY2luZyBlbGl0LFxuc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQiICsKKyAgICAibGFib3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdWEuXG4iOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IHRlc3RMZW5ndGggPSB0ZXN0U3RyaW5nLmxlbmd0aCgpOworCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgLy8gVGhlIEZpbHRlcklucHV0U3RyZWFtIG9iamVjdCBoYXMgYWxyZWFkeSBiZWVuIGNyZWF0ZWQgaW4gc2V0VXAoKS4KKyAgICAgICAgLy8gSWYgYW55dGhpbmcgaGFzIGdvbmUgd3JvbmcsIGNsb3NpbmcgaXQgc2hvdWxkIHRocm93IGEKKyAgICAgICAgLy8gTnVsbFBvaW50ZXJFeGNlcHRpb24uCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2F2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBSZXR1cm5lZCBpbmNvcnJlY3QgbnVtYmVyIG9mIGF2YWlsYWJsZSBieXRlczsiLAorICAgICAgICAgICAgICAgIHRlc3RMZW5ndGgsIGlzLmF2YWlsYWJsZSgpKTsKKworICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMuYXZhaWxhYmxlKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IFJlYWQgZnJvbSBjbG9zZWQgc3RyZWFtIHN1Y2NlZWRlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbSBzaXMgPSBuZXcgU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW0odHJ1ZSk7CisgICAgICAgIGlzID0gbmV3IE15RmlsdGVySW5wdXRTdHJlYW0oc2lzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICBzaXMudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X21hcmtJKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEuaW8uRmlsdGVySW5wdXRTdHJlYW0ubWFyayhpbnQpCisgICAgICAgIGZpbmFsIGludCBidWZTaXplID0gMTA7CisgICAgICAgIGJ5dGVbXSBidWYxID0gbmV3IGJ5dGVbYnVmU2l6ZV07CisgICAgICAgIGJ5dGVbXSBidWYyID0gbmV3IGJ5dGVbYnVmU2l6ZV07CisKKyAgICAgICAgLy8gUHVycG9zZSAxOiBDaGVjayB0aGF0IG1hcmsoKSBkb2VzIG5vdGhpbmcgaWYgdGhlIGZpbHRlcmVkIHN0cmVhbQorICAgICAgICAvLyBpcyBhIEZpbGVJbnB1dFN0cmVhbS4KKyAgICAgICAgaXMucmVhZChidWYxLCAwLCBidWZTaXplKTsKKyAgICAgICAgaXMubWFyaygyICogYnVmU2l6ZSk7CisgICAgICAgIGlzLnJlYWQoYnVmMSwgMCwgYnVmU2l6ZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZXNldCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIGlzLnJlYWQoYnVmMiwgMCwgYnVmU2l6ZSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUZXN0IDE6IG1hcmsoKSBzaG91bGQgaGF2ZSBubyBlZmZlY3QuIiwKKyAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKGJ1ZjEsIGJ1ZjIpKTsKKyAgICAgICAgaXMuY2xvc2UoKTsKKworICAgICAgICAvLyBQdXJwb3NlIDI6IENoZWNrIHRoYXQgbWFyaygpIGluIGNvbWJpbmF0aW9uIHdpdGggcmVzZXQoKSB3b3JrcyBpZgorICAgICAgICAvLyB0aGUgZmlsdGVyZWQgc3RyZWFtIGlzIGEgQnVmZmVyZWRJbnB1dFN0cmVhbS4KKyAgICAgICAgaXMgPSBuZXcgTXlGaWx0ZXJJbnB1dFN0cmVhbShuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICBuZXcgamF2YS5pby5GaWxlSW5wdXRTdHJlYW0oZmlsZU5hbWUpLCAxMDApKTsKKyAgICAgICAgaXMucmVhZChidWYxLCAwLCBidWZTaXplKTsKKyAgICAgICAgaXMubWFyaygyICogYnVmU2l6ZSk7CisgICAgICAgIGlzLnJlYWQoYnVmMSwgMCwgYnVmU2l6ZSk7CisgICAgICAgIGlzLnJlc2V0KCk7CisgICAgICAgIGlzLnJlYWQoYnVmMiwgMCwgYnVmU2l6ZSk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMjogbWFyaygpIG9yIHJlc2V0KCkgaGFzIGZhaWxlZC4iLAorICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMoYnVmMSwgYnVmMikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbWFya1N1cHBvcnRlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtLm1hcmtTdXBwb3J0ZWQoKQorCisgICAgICAgIC8vIFRlc3QgMTogQ2hlY2sgdGhhdCBtYXJrU3VwcG9ydGVkKCkgcmV0dXJucyBmYWxzZSBmb3IgYSBmaWx0ZXJlZAorICAgICAgICAvLyBpbnB1dCBzdHJlYW0gdGhhdCBpcyBrbm93biB0byBub3Qgc3VwcG9ydCBtYXJrKCkuCisgICAgICAgIGFzc2VydEZhbHNlKCJUZXN0IDE6IG1hcmtTdXBwb3J0ZWQoKSBpbmNvcnJlY3RseSByZXR1cm5lZCB0cnVlICIgKworICAgICAgICAgICAgICAgICJmb3IgYSBGaWxlSW5wdXRTdHJlYW0uIiwgaXMubWFya1N1cHBvcnRlZCgpKTsKKyAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgLy8gVGVzdCAyOiBDaGVjayB0aGF0IG1hcmtTdXBwb3J0ZWQoKSByZXR1cm5zIHRydWUgZm9yIGEgZmlsdGVyZWQKKyAgICAgICAgLy8gaW5wdXQgc3RyZWFtIHRoYXQgaXMga25vd24gdG8gc3VwcG9ydCBtYXJrKCkuCisgICAgICAgIGlzID0gbmV3IE15RmlsdGVySW5wdXRTdHJlYW0obmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgbmV3IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtKGZpbGVOYW1lKSwgMTAwKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMjogbWFya1N1cHBvcnRlZCgpIGluY29ycmVjdGx5IHJldHVybmVkIGZhbHNlICIgKworICAgICAgICAgICAgICAgICJmb3IgYSBCdWZmZXJlZElucHV0U3RyZWFtLiIsIGlzLm1hcmtTdXBwb3J0ZWQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGMgPSBpcy5yZWFkKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBSZWFkIHJldHVybmVkIGluY29ycmVjdCBjaGFyOyIsCisgICAgICAgICAgICAgICAgdGVzdFN0cmluZy5jaGFyQXQoMCksIGMpOworCisgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCRCKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtLnJlYWQoYnl0ZSBbXSkKKyAgICAgICAgYnl0ZVtdIGJ1ZjEgPSBuZXcgYnl0ZVsxMDBdOworICAgICAgICBpcy5yZWFkKGJ1ZjEpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IEZhaWxlZCB0byByZWFkIGNvcnJlY3QgZGF0YS4iLAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmcoYnVmMSwgMCwgYnVmMS5sZW5ndGgpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgIHRlc3RTdHJpbmcuc3Vic3RyaW5nKDAsIDEwMCkpKTsKKworICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZChidWYxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkJEJJSV9FeGNlcHRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gYnVmID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWQoYnVmLCAtMSwgMCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIGJ1ZiA9IG5ldyBieXRlWzEwMDBdOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZChidWYsIC0xLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZWFkKGJ1ZiwgMCwgLTEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWQoYnVmLCAtMSwgLTEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWQoYnVmLCAwLCAxMDAxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNTogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZWFkKGJ1ZiwgMTAwMSwgMCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDY6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZChidWYsIDUwMCwgNTAxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNzogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZWFkKGJ1ZiwgMCwgMTAwKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgODogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZXNldCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtLnJlc2V0KCkKKworICAgICAgICAvLyBUZXN0IDE6IENoZWNrIHRoYXQgcmVzZXQoKSB0aHJvd3MgYW4gSU9FeGNlcHRpb24gaWYgdGhlCisgICAgICAgIC8vIGZpbHRlcmVkIHN0cmVhbSBpcyBhIEZpbGVJbnB1dFN0cmVhbS4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlc2V0KCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gVGVzdCAyOiBDaGVjayB0aGF0IHJlc2V0KCkgdGhyb3dzIGFuIElPRXhjZXB0aW9uIGlmIHRoZQorICAgICAgICAvLyBmaWx0ZXJlZCBzdHJlYW0gaXMgYSBCdWZmZXJlZElucHV0U3RyZWFtIGJ1dCBtYXJrKCkgaGFzIG5vdAorICAgICAgICAvLyB5ZXQgYmVlbiBjYWxsZWQuCisgICAgICAgIGlzID0gbmV3IE15RmlsdGVySW5wdXRTdHJlYW0obmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgbmV3IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtKGZpbGVOYW1lKSwgMTAwKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZXNldCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3QgMzogQ2hlY2sgdGhhdCByZXNldCgpIGluIGNvbWJpbmF0aW9uIHdpdGggbWFyaygpCisgICAgICAgIC8vIHdvcmtzIGNvcnJlY3RseS4KKyAgICAgICAgZmluYWwgaW50IGJ1ZlNpemUgPSAxMDsKKyAgICAgICAgYnl0ZVtdIGJ1ZjEgPSBuZXcgYnl0ZVtidWZTaXplXTsKKyAgICAgICAgYnl0ZVtdIGJ1ZjIgPSBuZXcgYnl0ZVtidWZTaXplXTsKKyAgICAgICAgaXMucmVhZChidWYxLCAwLCBidWZTaXplKTsKKyAgICAgICAgaXMubWFyaygyICogYnVmU2l6ZSk7CisgICAgICAgIGlzLnJlYWQoYnVmMSwgMCwgYnVmU2l6ZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZXNldCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IFVuZXhwZWN0ZWQgSU9FeGNlcHRpb24uIik7CisgICAgICAgIH0KKyAgICAgICAgaXMucmVhZChidWYyLCAwLCBidWZTaXplKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCA0OiBtYXJrKCkgb3IgcmVzZXQoKSBoYXMgZmFpbGVkLiIsCisgICAgICAgICAgICAgICAgQXJyYXlzLmVxdWFscyhidWYxLCBidWYyKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9za2lwSigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBidWYxID0gbmV3IGJ5dGVbMTBdOworICAgICAgICBpcy5za2lwKDEwKTsKKyAgICAgICAgaXMucmVhZChidWYxLCAwLCBidWYxLmxlbmd0aCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogRmFpbGVkIHRvIHNraXAgdG8gdGhlIGNvcnJlY3QgcG9zaXRpb24uIiwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKGJ1ZjEsIDAsIGJ1ZjEubGVuZ3RoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0U3RyaW5nLnN1YnN0cmluZygxMCwgMjApKSk7CisKKyAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaWxlTmFtZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKTsKKyAgICAgICAgICAgIFN0cmluZyBzZXBhcmF0b3IgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImZpbGUuc2VwYXJhdG9yIik7CisgICAgICAgICAgICBpZiAoZmlsZU5hbWUuY2hhckF0KGZpbGVOYW1lLmxlbmd0aCgpIC0gMSkgPT0gc2VwYXJhdG9yLmNoYXJBdCgwKSkKKyAgICAgICAgICAgICAgICBmaWxlTmFtZSA9IFN1cHBvcnRfUGxhdGZvcm1GaWxlLmdldE5ld1BsYXRmb3JtRmlsZShmaWxlTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICJpbnB1dC50c3QiKTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBmaWxlTmFtZSA9IFN1cHBvcnRfUGxhdGZvcm1GaWxlLmdldE5ld1BsYXRmb3JtRmlsZShmaWxlTmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgKyBzZXBhcmF0b3IsICJpbnB1dC50c3QiKTsKKyAgICAgICAgICAgIGphdmEuaW8uT3V0cHV0U3RyZWFtIGZvcyA9IG5ldyBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW0oZmlsZU5hbWUpOworICAgICAgICAgICAgZm9zLndyaXRlKHRlc3RTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICBmb3MuY2xvc2UoKTsKKyAgICAgICAgICAgIGlzID0gbmV3IE15RmlsdGVySW5wdXRTdHJlYW0obmV3IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtKGZpbGVOYW1lKSk7CisgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFeGNlcHRpb24gZHVyaW5nIHNldHVwIik7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiBpbiB0ZWFyRG93bigpLiIpOworICAgICAgICB9CisgICAgICAgIG5ldyBqYXZhLmlvLkZpbGUoZmlsZU5hbWUpLmRlbGV0ZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkRmlsdGVyT3V0cHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRGaWx0ZXJPdXRwdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGE4Yjg1ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkRmlsdGVyT3V0cHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjAzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWx0ZXJPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfT3V0cHV0U3RyZWFtOworCitwdWJsaWMgY2xhc3MgT2xkRmlsdGVyT3V0cHV0U3RyZWFtVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIGphdmEuaW8uRmlsdGVyT3V0cHV0U3RyZWFtIG9zOworCisgICAgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zOworCisgICAgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbSBiaXM7CisKKyAgICBieXRlW10gaWJ1ZiA9IG5ldyBieXRlWzQwOTZdOworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZmlsZVN0cmluZyA9ICJUZXN0X0FsbF9UZXN0c1xuVGVzdF9qYXZhX2lvX0J1ZmZlcmVkSW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19CdWZmZXJlZE91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0J5dGVBcnJheUlucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fQnl0ZUFycmF5T3V0cHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fRGF0YUlucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fRmlsZVxuVGVzdF9qYXZhX2lvX0ZpbGVEZXNjcmlwdG9yXG5UZXN0X2phdmFfaW9fRmlsZUlucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fRmlsZU5vdEZvdW5kRXhjZXB0aW9uXG5UZXN0X2phdmFfaW9fRmlsZU91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0ZpbHRlcklucHV0U3RyZWFtXG5UZXN0X0ZpbHRlck91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0lucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fSU9FeGNlcHRpb25cblRlc3RfamF2YV9pb19PdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19QcmludFN0cmVhbVxuVGVzdF9qYXZhX2lvX1JhbmRvbUFjY2Vzc0ZpbGVcblRlc3RfamF2YV9pb19TeW5jRmFpbGVkRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19BYnN0cmFjdE1ldGhvZEVycm9yXG5UZXN0X2phdmFfbGFuZ19Bcml0aG1ldGljRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0FycmF5U3RvcmVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0Jvb2xlYW5cblRlc3RfamF2YV9sYW5nX0J5dGVcblRlc3RfamF2YV9sYW5nX0NoYXJhY3RlclxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NcblRlc3RfamF2YV9sYW5nX0NsYXNzQ2FzdEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NDaXJjdWxhcml0eUVycm9yXG5UZXN0X2phdmFfbGFuZ19DbGFzc0Zvcm1hdEVycm9yXG5UZXN0X2phdmFfbGFuZ19DbGFzc0xvYWRlclxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0RvdWJsZVxuVGVzdF9qYXZhX2xhbmdfRXJyb3JcblRlc3RfamF2YV9sYW5nX0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfRXhjZXB0aW9uSW5Jbml0aWFsaXplckVycm9yXG5UZXN0X2phdmFfbGFuZ19GbG9hdFxuVGVzdF9qYXZhX2xhbmdfSWxsZWdhbEFjY2Vzc0Vycm9yXG5UZXN0X2phdmFfbGFuZ19JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0lsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0lsbGVnYWxUaHJlYWRTdGF0ZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSW5jb21wYXRpYmxlQ2xhc3NDaGFuZ2VFcnJvclxuVGVzdF9qYXZhX2xhbmdfSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSW5zdGFudGlhdGlvbkVycm9yXG5UZXN0X2phdmFfbGFuZ19JbnN0YW50aWF0aW9uRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbnRlZ2VyXG5UZXN0X2phdmFfbGFuZ19JbnRlcm5hbEVycm9yXG5UZXN0X2phdmFfbGFuZ19JbnRlcnJ1cHRlZEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfTGlua2FnZUVycm9yXG5UZXN0X2phdmFfbGFuZ19Mb25nXG5UZXN0X2phdmFfbGFuZ19NYXRoXG5UZXN0X2phdmFfbGFuZ19OZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfTm9DbGFzc0RlZkZvdW5kRXJyb3JcblRlc3RfamF2YV9sYW5nX05vU3VjaEZpZWxkRXJyb3JcblRlc3RfamF2YV9sYW5nX05vU3VjaE1ldGhvZEVycm9yXG5UZXN0X2phdmFfbGFuZ19OdWxsUG9pbnRlckV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfTnVtYmVyXG5UZXN0X2phdmFfbGFuZ19OdW1iZXJGb3JtYXRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX09iamVjdFxuVGVzdF9qYXZhX2xhbmdfT3V0T2ZNZW1vcnlFcnJvclxuVGVzdF9qYXZhX2xhbmdfUnVudGltZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfU2VjdXJpdHlNYW5hZ2VyXG5UZXN0X2phdmFfbGFuZ19TaG9ydFxuVGVzdF9qYXZhX2xhbmdfU3RhY2tPdmVyZmxvd0Vycm9yXG5UZXN0X2phdmFfbGFuZ19TdHJpbmdcblRlc3RfamF2YV9sYW5nX1N0cmluZ0J1ZmZlclxuVGVzdF9qYXZhX2xhbmdfU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfU3lzdGVtXG5UZXN0X2phdmFfbGFuZ19UaHJlYWRcblRlc3RfamF2YV9sYW5nX1RocmVhZERlYXRoXG5UZXN0X2phdmFfbGFuZ19UaHJlYWRHcm91cFxuVGVzdF9qYXZhX2xhbmdfVGhyb3dhYmxlXG5UZXN0X2phdmFfbGFuZ19Vbmtub3duRXJyb3JcblRlc3RfamF2YV9sYW5nX1Vuc2F0aXNmaWVkTGlua0Vycm9yXG5UZXN0X2phdmFfbGFuZ19WZXJpZnlFcnJvclxuVGVzdF9qYXZhX2xhbmdfVmlydHVhbE1hY2hpbmVFcnJvclxuVGVzdF9qYXZhX2xhbmdfdm1fSW1hZ2VcblRlc3RfamF2YV9sYW5nX3ZtX01lbW9yeVNlZ21lbnRcblRlc3RfamF2YV9sYW5nX3ZtX1JPTVN0b3JlRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ192bV9WTVxuVGVzdF9qYXZhX2xhbmdfVm9pZFxuVGVzdF9qYXZhX25ldF9CaW5kRXhjZXB0aW9uXG5UZXN0X2phdmFfbmV0X0Nvbm5lY3RFeGNlcHRpb25cblRlc3RfamF2YV9uZXRfRGF0YWdyYW1QYWNrZXRcblRlc3RfamF2YV9uZXRfRGF0YWdyYW1Tb2NrZXRcblRlc3RfamF2YV9uZXRfRGF0YWdyYW1Tb2NrZXRJbXBsXG5UZXN0X2phdmFfbmV0X0luZXRBZGRyZXNzXG5UZXN0X2phdmFfbmV0X05vUm91dGVUb0hvc3RFeGNlcHRpb25cblRlc3RfamF2YV9uZXRfUGxhaW5EYXRhZ3JhbVNvY2tldEltcGxcblRlc3RfamF2YV9uZXRfUGxhaW5Tb2NrZXRJbXBsXG5UZXN0X2phdmFfbmV0X1NvY2tldFxuVGVzdF9qYXZhX25ldF9Tb2NrZXRFeGNlcHRpb25cblRlc3RfamF2YV9uZXRfU29ja2V0SW1wbFxuVGVzdF9qYXZhX25ldF9Tb2NrZXRJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX25ldF9Tb2NrZXRPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9uZXRfVW5rbm93bkhvc3RFeGNlcHRpb25cblRlc3RfamF2YV91dGlsX0FycmF5RW51bWVyYXRvclxuVGVzdF9qYXZhX3V0aWxfRGF0ZVxuVGVzdF9qYXZhX3V0aWxfRXZlbnRPYmplY3RcblRlc3RfamF2YV91dGlsX0hhc2hFbnVtZXJhdG9yXG5UZXN0X2phdmFfdXRpbF9IYXNodGFibGVcblRlc3RfamF2YV91dGlsX1Byb3BlcnRpZXNcblRlc3RfamF2YV91dGlsX1Jlc291cmNlQnVuZGxlXG5UZXN0X2phdmFfdXRpbF90bVxuVGVzdF9qYXZhX3V0aWxfVmVjdG9yXG4iOworCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdGVzdExlbmd0aCA9IGZpbGVTdHJpbmcubGVuZ3RoKCk7CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9pb19PdXRwdXRTdHJlYW0oKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmlvLkZpbHRlck91dHB1dFN0cmVhbShqYXZhLmlvLk91dHB1dFN0cmVhbSkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIG9zID0gbmV3IEZpbHRlck91dHB1dFN0cmVhbShib3MpOworICAgICAgICAgICAgb3Mud3JpdGUoJ3QnKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJDb25zdHJ1Y3RvciB0ZXN0IGZhaWxlZCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3VwcG9ydF9PdXRwdXRTdHJlYW0gc29zID0gbmV3IFN1cHBvcnRfT3V0cHV0U3RyZWFtKCk7CisgICAgICAgIG9zID0gbmV3IEZpbHRlck91dHB1dFN0cmVhbShzb3MpOworICAgICAgICBvcy5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcy53cml0ZSg0Mik7CisgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBVbmV4cGVjdGVkIElPRXhjZXB0aW9uLiIpOworICAgICAgICB9CisKKyAgICAgICAgc29zLnNldFRocm93c0V4Y2VwdGlvbih0cnVlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9zLndyaXRlKDQyKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBvcyA9IG5ldyBGaWx0ZXJPdXRwdXRTdHJlYW0oc29zKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdXBwb3J0X091dHB1dFN0cmVhbSBzb3MgPSBuZXcgU3VwcG9ydF9PdXRwdXRTdHJlYW0oNTUwKTsKKyAgICAgICAgb3MgPSBuZXcgRmlsdGVyT3V0cHV0U3RyZWFtKHNvcyk7CisgICAgICAgIG9zLndyaXRlKGZpbGVTdHJpbmcuZ2V0Qnl0ZXMoKSwgMCwgNTAwKTsKKyAgICAgICAgb3MuZmx1c2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEJ5dGVzIG5vdCB3cml0dGVuIGFmdGVyIGZsdXNoOyIsCisgICAgICAgICAgICAgICAgNTAwLCBzb3Muc2l6ZSgpKTsKKworICAgICAgICBzb3Muc2V0VGhyb3dzRXhjZXB0aW9uKHRydWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3MuZmx1c2goKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIHNvcy5zZXRUaHJvd3NFeGNlcHRpb24oZmFsc2UpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGUkQigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN1cHBvcnRfT3V0cHV0U3RyZWFtIHNvcyA9IG5ldyBTdXBwb3J0X091dHB1dFN0cmVhbSh0ZXN0TGVuZ3RoKTsKKyAgICAgICAgb3MgPSBuZXcgRmlsdGVyT3V0cHV0U3RyZWFtKHNvcyk7CisgICAgICAgIG9zLndyaXRlKGZpbGVTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisKKyAgICAgICAgYmlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHNvcy50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBCeXRlcyBoYXZlIG5vdCBiZWVuIHdyaXR0ZW4uIiwKKyAgICAgICAgICAgICAgICBiaXMuYXZhaWxhYmxlKCkgPT0gdGVzdExlbmd0aCk7CisgICAgICAgIGJ5dGVbXSB3Ynl0ZXMgPSBuZXcgYnl0ZVt0ZXN0TGVuZ3RoXTsKKyAgICAgICAgYmlzLnJlYWQod2J5dGVzLCAwLCB0ZXN0TGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAyOiBJbmNvcnJlY3QgYnl0ZXMgd3JpdHRlbiBvciByZWFkLiIsCisgICAgICAgICAgICAgICAgZmlsZVN0cmluZy5lcXVhbHMobmV3IFN0cmluZyh3Ynl0ZXMpKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFN1cHBvcnRfT3V0cHV0U3RyZWFtIHRocm93cyBhbiBJT0V4Y2VwdGlvbiBpZiB0aGUgaW50ZXJuYWwKKyAgICAgICAgICAgIC8vIGJ1ZmZlciBpcyBmdWxsLCB3aGljaCBpdCBzaG91bGQgYmUgbm93LgorICAgICAgICAgICAgb3Mud3JpdGUoNDIpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlJEJJSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN1cHBvcnRfT3V0cHV0U3RyZWFtIHNvcyA9IG5ldyBTdXBwb3J0X091dHB1dFN0cmVhbSh0ZXN0TGVuZ3RoKTsKKyAgICAgICAgb3MgPSBuZXcgRmlsdGVyT3V0cHV0U3RyZWFtKHNvcyk7CisgICAgICAgIG9zLndyaXRlKGZpbGVTdHJpbmcuZ2V0Qnl0ZXMoKSwgMTAsIHRlc3RMZW5ndGggLSAxMCk7CisKKyAgICAgICAgYmlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHNvcy50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBCeXRlcyBoYXZlIG5vdCBiZWVuIHdyaXR0ZW4uIiwKKyAgICAgICAgICAgICAgICBiaXMuYXZhaWxhYmxlKCkgPT0gdGVzdExlbmd0aCAtIDEwKTsKKyAgICAgICAgYnl0ZVtdIHdieXRlcyA9IG5ldyBieXRlW3Rlc3RMZW5ndGggLSAxMF07CisgICAgICAgIGJpcy5yZWFkKHdieXRlcyk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMjogSW5jb3JyZWN0IGJ5dGVzIHdyaXR0ZW4gb3IgcmVhZC4iLAorICAgICAgICAgICAgICAgIGZpbGVTdHJpbmcuc3Vic3RyaW5nKDEwKS5lcXVhbHMobmV3IFN0cmluZyh3Ynl0ZXMpKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFN1cHBvcnRfT3V0cHV0U3RyZWFtIHRocm93cyBhbiBJT0V4Y2VwdGlvbiBpZiB0aGUgaW50ZXJuYWwKKyAgICAgICAgICAgIC8vIGJ1ZmZlciBpcyBmdWxsLCB3aGljaCBpdCBzaG91bGQgYmUgZXZlbnR1YWxseS4KKyAgICAgICAgICAgIG9zLndyaXRlKGZpbGVTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGUkQklJX0V4Y2VwdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN1cHBvcnRfT3V0cHV0U3RyZWFtIHNvcyA9IG5ldyBTdXBwb3J0X091dHB1dFN0cmVhbSh0ZXN0TGVuZ3RoKTsKKyAgICAgICAgb3MgPSBuZXcgRmlsdGVyT3V0cHV0U3RyZWFtKHNvcyk7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsxMF07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9zLndyaXRlKGJ1ZiwgLTEsIDEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcy53cml0ZShidWYsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3Mud3JpdGUoYnVmLCAxMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZUkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdXBwb3J0X091dHB1dFN0cmVhbSBzb3MgPSBuZXcgU3VwcG9ydF9PdXRwdXRTdHJlYW0oMSk7CisgICAgICAgIG9zID0gbmV3IEZpbHRlck91dHB1dFN0cmVhbShzb3MpOworICAgICAgICBvcy53cml0ZSg0Mik7CisKKyAgICAgICAgYmlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHNvcy50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBCeXRlIGhhcyBub3QgYmVlbiB3cml0dGVuLiIsCisgICAgICAgICAgICAgICAgYmlzLmF2YWlsYWJsZSgpID09IDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMjogSW5jb3JyZWN0IGJ5dGUgd3JpdHRlbiBvciByZWFkOyIsCisgICAgICAgICAgICAgICAgNDIsIGJpcy5yZWFkKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBTdXBwb3J0X091dHB1dFN0cmVhbSB0aHJvd3MgYW4gSU9FeGNlcHRpb24gaWYgdGhlIGludGVybmFsCisgICAgICAgICAgICAvLyBidWZmZXIgaXMgZnVsbCwgd2hpY2ggaXQgc2hvdWxkIGJlIG5vdy4KKyAgICAgICAgICAgIG9zLndyaXRlKDQyKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoYm9zICE9IG51bGwpCisgICAgICAgICAgICAgICAgYm9zLmNsb3NlKCk7CisgICAgICAgICAgICBpZiAoYmlzICE9IG51bGwpCisgICAgICAgICAgICAgICAgYmlzLmNsb3NlKCk7CisgICAgICAgICAgICBpZiAob3MgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRGaWx0ZXJSZWFkZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZEZpbHRlclJlYWRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZDFkM2RlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRGaWx0ZXJSZWFkZXJUZXN0LmphdmEKQEAgLTAsMCArMSwxNzYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbHRlclJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7CisKK3B1YmxpYyBjbGFzcyBPbGRGaWx0ZXJSZWFkZXJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgYm9vbGVhbiBjYWxsZWQ7CisgICAgcHJpdmF0ZSBGaWx0ZXJSZWFkZXIgZnI7CisKKyAgICBzdGF0aWMgY2xhc3MgTXlGaWx0ZXJSZWFkZXIgZXh0ZW5kcyBqYXZhLmlvLkZpbHRlclJlYWRlciB7CisgICAgICAgIHB1YmxpYyBNeUZpbHRlclJlYWRlcihqYXZhLmlvLlJlYWRlciByZWFkZXIpIHsKKyAgICAgICAgICAgIHN1cGVyKHJlYWRlcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBNb2NrUmVhZGVyIGV4dGVuZHMgamF2YS5pby5SZWFkZXIgeworICAgICAgICBwdWJsaWMgTW9ja1JlYWRlcigpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGNhbGxlZCA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBtYXJrKGludCByZWFkTGltaXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBjYWxsZWQgPSB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gbWFya1N1cHBvcnRlZCgpIHsKKyAgICAgICAgICAgIGNhbGxlZCA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgY2FsbGVkID0gdHJ1ZTsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCByZWFkKGNoYXJbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGNhbGxlZCA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIHJlYWR5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGNhbGxlZCA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGNhbGxlZCA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgbG9uZyBza2lwKGxvbmcgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBjYWxsZWQgPSB0cnVlOworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fUmVhZGVyKCkgeworCisgICAgICAgIEZpbHRlclJlYWRlciBteVJlYWRlciA9IG51bGw7CisKKyAgICAgICAgY2FsbGVkID0gdHJ1ZTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXlSZWFkZXIgPSBuZXcgTXlGaWx0ZXJSZWFkZXIobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmci5jbG9zZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJjbG9zZSgpIGhhcyBub3QgYmVlbiBjYWxsZWQuIiwgY2FsbGVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X21hcmtJKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZnIubWFyaygwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibWFyayhpbnQpIGhhcyBub3QgYmVlbiBjYWxsZWQuIiwgY2FsbGVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X21hcmtTdXBwb3J0ZWQoKSB7CisgICAgICAgIGZyLm1hcmtTdXBwb3J0ZWQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibWFya1N1cHBvcnRlZCgpIGhhcyBub3QgYmVlbiBjYWxsZWQuIiwgY2FsbGVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmci5yZWFkKCk7CisgICAgICAgIGFzc2VydFRydWUoInJlYWQoKSBoYXMgbm90IGJlZW4gY2FsbGVkLiIsIGNhbGxlZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkJENJSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJbXSBidWZmZXIgPSBuZXcgY2hhcls1XTsKKyAgICAgICAgZnIucmVhZChidWZmZXIsIDAsIDUpOworICAgICAgICBhc3NlcnRUcnVlKCJyZWFkKGNoYXJbXSwgaW50LCBpbnQpIGhhcyBub3QgYmVlbiBjYWxsZWQuIiwgY2FsbGVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWQkQ0lJX0V4Y2VwdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBiYnVmZmVyID0gbmV3IGJ5dGVbMjBdOworICAgICAgICBjaGFyW10gYnVmZmVyID0gbmV3IGNoYXJbMTBdOworCisgICAgICAgIGZyID0gbmV3IE15RmlsdGVyUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcigKKyAgICAgICAgICAgIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYnVmZmVyKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmci5yZWFkKGJ1ZmZlciwgMCwgLTEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZyLnJlYWQoYnVmZmVyLCAtMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZnIucmVhZChidWZmZXIsIDEwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmci5yZWFkeSgpOworICAgICAgICBhc3NlcnRUcnVlKCJyZWFkeSgpIGhhcyBub3QgYmVlbiBjYWxsZWQuIiwgY2FsbGVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Jlc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZnIucmVzZXQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgicmVzZXQoKSBoYXMgbm90IGJlZW4gY2FsbGVkLiIsIGNhbGxlZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9za2lwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZnIuc2tpcCgxMCk7CisgICAgICAgIGFzc2VydFRydWUoInNraXAobG9uZykgaGFzIG5vdCBiZWVuIGNhbGxlZC4iLCBjYWxsZWQpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworCisgICAgICAgIGZyID0gbmV3IE15RmlsdGVyUmVhZGVyKG5ldyBNb2NrUmVhZGVyKCkpOworICAgICAgICBjYWxsZWQgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZnIuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXhjZXB0aW9uIGR1cmluZyBGaWx0ZXJSZWFkZXJUZXN0IHRlYXIgZG93bi4iKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkRmlsdGVyV3JpdGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRGaWx0ZXJXcml0ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjRjOTc5NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkRmlsdGVyV3JpdGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTQ4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsdGVyV3JpdGVyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW1Xcml0ZXI7CisKK3B1YmxpYyBjbGFzcyBPbGRGaWx0ZXJXcml0ZXJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgYm9vbGVhbiBjYWxsZWQ7CisgICAgcHJpdmF0ZSBGaWx0ZXJXcml0ZXIgZnc7CisKKyAgICBzdGF0aWMgY2xhc3MgTXlGaWx0ZXJXcml0ZXIgZXh0ZW5kcyBqYXZhLmlvLkZpbHRlcldyaXRlciB7CisgICAgICAgIHB1YmxpYyBNeUZpbHRlcldyaXRlcihqYXZhLmlvLldyaXRlciB3cml0ZXIpIHsKKyAgICAgICAgICAgIHN1cGVyKHdyaXRlcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBNb2NrV3JpdGVyIGV4dGVuZHMgamF2YS5pby5Xcml0ZXIgeworICAgICAgICBwdWJsaWMgTW9ja1dyaXRlcigpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGNhbGxlZCA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBjYWxsZWQgPSB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgd3JpdGUoY2hhcltdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgY2FsbGVkID0gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBvbmVDaGFyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgY2FsbGVkID0gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKFN0cmluZyBzdHIsIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGNhbGxlZCA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgbG9uZyBza2lwKGxvbmcgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBjYWxsZWQgPSB0cnVlOworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fV3JpdGVyKCkgeworCisgICAgICAgIEZpbHRlcldyaXRlciBteVdyaXRlciA9IG51bGw7CisKKyAgICAgICAgY2FsbGVkID0gdHJ1ZTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXlXcml0ZXIgPSBuZXcgTXlGaWx0ZXJXcml0ZXIobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmdy5jbG9zZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJjbG9zZSgpIGhhcyBub3QgYmVlbiBjYWxsZWQuIiwgY2FsbGVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ZsdXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZncuZmx1c2goKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZmx1c2goKSBoYXMgbm90IGJlZW4gY2FsbGVkLiIsIGNhbGxlZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZUkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmdy53cml0ZSgwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgid3JpdGUoaW50KSBoYXMgbm90IGJlZW4gY2FsbGVkLiIsIGNhbGxlZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZSRDSUkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGFyW10gYnVmZmVyID0gbmV3IGNoYXJbNV07CisgICAgICAgIGZ3LndyaXRlKGJ1ZmZlciwgMCwgNSk7CisgICAgICAgIGFzc2VydFRydWUoIndyaXRlKGNoYXJbXSwgaW50LCBpbnQpIGhhcyBub3QgYmVlbiBjYWxsZWQuIiwgY2FsbGVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlJENJSV9FeGNlcHRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGFyW10gYnVmZmVyID0gbmV3IGNoYXJbMTBdOworCisgICAgICAgIGZ3ID0gbmV3IE15RmlsdGVyV3JpdGVyKG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoCisgICAgICAgICAgICBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCkpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZncud3JpdGUoYnVmZmVyLCAwLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZncud3JpdGUoYnVmZmVyLCAtMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZncud3JpdGUoYnVmZmVyLCAxMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlTGphdmFfbGFuZ19TdHJpbmdJSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZ3LndyaXRlKCJIZWxsbyB3b3JsZCIsIDAsIDUpOworICAgICAgICBhc3NlcnRUcnVlKCJ3cml0ZShTdHJpbmcsIGludCwgaW50KSBoYXMgbm90IGJlZW4gY2FsbGVkLiIsIGNhbGxlZCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisKKyAgICAgICAgZncgPSBuZXcgTXlGaWx0ZXJXcml0ZXIobmV3IE1vY2tXcml0ZXIoKSk7CisgICAgICAgIGNhbGxlZCA9IGZhbHNlOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmdy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFeGNlcHRpb24gZHVyaW5nIE9sZEZpbHRlcldyaXRlclRlc3QgdGVhciBkb3duLiIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRJbnB1dFN0cmVhbVJlYWRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkSW5wdXRTdHJlYW1SZWFkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGI1YTM3NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkSW5wdXRTdHJlYW1SZWFkZXJUZXN0LmphdmEKQEAgLTAsMCArMSwyOTUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbTsKKworcHVibGljIGNsYXNzIE9sZElucHV0U3RyZWFtUmVhZGVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHNvdXJjZSA9ICJUaGlzIGlzIGEgdGVzdCBtZXNzYWdlIHdpdGggVW5pY29kZSBjaGFyYWN0ZXIuIFx1NGUyZFx1NTZmZCBpcyBDaGluYSdzIG5hbWUgaW4gQ2hpbmVzZSI7CisKKyAgICBwcml2YXRlIElucHV0U3RyZWFtIGluOworCisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbVJlYWRlciByZWFkZXI7CisKKyAgICBwcml2YXRlIElucHV0U3RyZWFtUmVhZGVyIGlzOworCisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBmaXM7CisKKyAgICBwdWJsaWMgU3RyaW5nIGZpbGVTdHJpbmcgPSAiVGVzdF9BbGxfVGVzdHNcblRlc3RfamF2YV9pb19CdWZmZXJlZElucHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fQnVmZmVyZWRPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19CeXRlQXJyYXlJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0J5dGVBcnJheU91dHB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0RhdGFJbnB1dFN0cmVhbVxuIjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisKKyAgICAgICAgaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc291cmNlLmdldEJ5dGVzKCJVVEYtOCIpKTsKKyAgICAgICAgcmVhZGVyID0gbmV3IElucHV0U3RyZWFtUmVhZGVyKGluLCAiVVRGLTgiKTsKKworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBPdXRwdXRTdHJlYW1Xcml0ZXIgb3N3ID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihib3MpOworICAgICAgICBjaGFyW10gYnVmID0gbmV3IGNoYXJbZmlsZVN0cmluZy5sZW5ndGgoKV07CisgICAgICAgIGZpbGVTdHJpbmcuZ2V0Q2hhcnMoMCwgZmlsZVN0cmluZy5sZW5ndGgoKSwgYnVmLCAwKTsKKyAgICAgICAgb3N3LndyaXRlKGJ1Zik7CisgICAgICAgIG9zdy5jbG9zZSgpOworICAgICAgICBmaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYm9zLnRvQnl0ZUFycmF5KCkpOworICAgICAgICBpcyA9IG5ldyBJbnB1dFN0cmVhbVJlYWRlcihmaXMpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIGZpcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkY2hhckFycmF5aW50aW50KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRlci5yZWFkKG5ldyBjaGFyWzNdLCAtMSwgMCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZGVyLnJlYWQobmV3IGNoYXJbM10sIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkZXIucmVhZChuZXcgY2hhclszXSwgNCwgMCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZGVyLnJlYWQobmV3IGNoYXJbM10sIDMsIDEpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRlci5yZWFkKG5ldyBjaGFyWzNdLCAxLCAzKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkZXIucmVhZChuZXcgY2hhclszXSwgMCwgNCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkZXIucmVhZChudWxsLCAwLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgcmVhZGVyLnJlYWQobmV3IGNoYXJbM10sIDMsIDApKTsKKyAgICAgICAgY2hhcltdIGNoYXJzID0gbmV3IGNoYXJbc291cmNlLmxlbmd0aCgpXTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHJlYWRlci5yZWFkKGNoYXJzLCAwLCAwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBjaGFyc1swXSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCByZWFkZXIucmVhZChjaGFycywgMCwgMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgcmVhZGVyLnJlYWQoY2hhcnMsIDMsIDUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNvdXJjZS5sZW5ndGgoKSAtIDgsIHJlYWRlci5yZWFkKGNoYXJzLCA4LAorICAgICAgICAgICAgICAgIGNoYXJzLmxlbmd0aCAtIDgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGNoYXJzLCBzb3VyY2UudG9DaGFyQXJyYXkoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIHJlYWRlci5yZWFkKGNoYXJzLCAwLCBjaGFycy5sZW5ndGgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGNoYXJzLCBzb3VyY2UudG9DaGFyQXJyYXkoKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkY2hhckFycmF5aW50aW50MigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJbXSBjaGFycyA9IG5ldyBjaGFyW3NvdXJjZS5sZW5ndGgoKV07CisgICAgICAgIGFzc2VydEVxdWFscyhzb3VyY2UubGVuZ3RoKCkgLSAzLCByZWFkZXIucmVhZChjaGFycywgMCwKKyAgICAgICAgICAgICAgICBjaGFycy5sZW5ndGggLSAzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCByZWFkZXIucmVhZChjaGFycywgMCwgMTApKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKHJlYWRlci5yZWFkeSgpKTsKKyAgICAgICAgcmVhZGVyLnJlYWQobmV3IGNoYXJbc291cmNlLmxlbmd0aCgpXSk7CisgICAgICAgIGFzc2VydEZhbHNlKHJlYWRlci5yZWFkeSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5wdXRTdHJlYW1SZWFkZXJTdWNjZXNzaXZlUmVhZHMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlWzgxOTIgKiAyXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZGF0YSwgKGJ5dGUpIDExNik7IC8vIDExNiA9IElTTy04ODU5LTEgdmFsdWUgZm9yICd0JworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSk7CisgICAgICAgIElucHV0U3RyZWFtUmVhZGVyIGlzciA9IG5ldyBJbnB1dFN0cmVhbVJlYWRlcihiaXMsICJJU08tODg1OS0xIik7CisKKyAgICAgICAgLy8gT25lIGxlc3MgdGhhbiB0aGUgSW5wdXRTdHJlYW1SZWFkZXIuQlVGRkVSX1NJWkUKKyAgICAgICAgY2hhcltdIGJ1ZiA9IG5ldyBjaGFyWzgxOTFdOworICAgICAgICBpbnQgYnl0ZXNSZWFkID0gaXNyLnJlYWQoYnVmLCAwLCBidWYubGVuZ3RoKTsKKyAgICAgICAgaWYgKGJ5dGVzUmVhZCA9PSAtMSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBieXRlc1JlYWQgPSBpc3IucmVhZChidWYsIDAsIGJ1Zi5sZW5ndGgpOworICAgICAgICBpZiAoYnl0ZXNSZWFkID09IC0xKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX0lucHV0U3RyZWFtKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcihqYXZhLmlvLklucHV0U3RyZWFtKQorICAgICAgICBhc3NlcnRUcnVlKCJVc2VkIHRvIHRlc3Qgb3RoZXIgbWV0aG9kcyIsIHRydWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9pb19JbnB1dFN0cmVhbUxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcihqYXZhLmlvLklucHV0U3RyZWFtLAorICAgICAgICAvLyBqYXZhLmxhbmcuU3RyaW5nKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMgPSBuZXcgSW5wdXRTdHJlYW1SZWFkZXIoZmlzLCAiODg1OV8xIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5hYmxlIHRvIGNyZWF0ZSBpbnB1dCBzdHJlYW0gOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzID0gbmV3IElucHV0U3RyZWFtUmVhZGVyKGZpcywgIkJvZ3VzIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGZhaWwoIkZhaWxlZCB0byB0aHJvdyBVbnN1cHBvcnRlZCBFbmNvZGluZyBleGNlcHRpb24iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb3NlKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyLmNsb3NlKCkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkZhaWxlZCB0byBjbG9zZSByZWFkZXIgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeGNlcHRpb24gbWVhbnMgcmVhZCBmYWlsZWQgZHVlIHRvIGNsb3NlCisgICAgICAgIH0KKworICAgICAgICBpcyA9IG5ldyBJbnB1dFN0cmVhbVJlYWRlcihuZXcgU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW0odHJ1ZSkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJlYWRlci5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZGVyLnJlYWR5KCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHJlYWRlci5jbG9zZSgpOworICAgIH0KKworICAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWQkQ0lJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXIucmVhZChjaGFyIFtdLCBpbnQsIGludCkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNoYXJbXSByYnVmID0gbmV3IGNoYXJbMTAwXTsKKyAgICAgICAgICAgIGNoYXJbXSBzYnVmID0gbmV3IGNoYXJbMTAwXTsKKyAgICAgICAgICAgIGZpbGVTdHJpbmcuZ2V0Q2hhcnMoMCwgMTAwLCBzYnVmLCAwKTsKKyAgICAgICAgICAgIGlzLnJlYWQocmJ1ZiwgMCwgMTAwKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmJ1Zi5sZW5ndGg7IGkrKykKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJyZXR1cm5lZCBpbmNvcnJlY3QgY2hhcnMiLCByYnVmW2ldID09IHNidWZbaV0pOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHJlYWQgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWR5KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyLnJlYWR5KCkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJlYWR5IHRlc3QgZmFpbGVkIiwgaXMucmVhZHkoKSk7CisgICAgICAgICAgICBpcy5yZWFkKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJNb3JlIGNoYXJzLCBidXQgbm90IHJlYWR5IiwgaXMucmVhZHkoKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgcmVhZHkgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciByZWdyZXNzaW9uIG9mIGEgYnVnIHRoYXQgZHJvcHBlZCBjaGFyYWN0ZXJzIHdoZW4KKyAgICAgKiBtdWx0aWJ5dGUgZW5jb2RpbmdzIHNwYW5uZWQgYnVmZmVyIGJvdW5kYXJpZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkV2hlbkNoYXJhY3RlclNwYW5zQnVmZmVyKCkgeworICAgICAgICBmaW5hbCBieXRlW10gc3VmZml4ID0geworICAgICAgICAgICAgKGJ5dGUpIDB4OTMsIChieXRlKSAweGExLCAoYnl0ZSkgMHg4YywgKGJ5dGUpIDB4YjQsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NywgKGJ5dGUpIDB4NDMsIChieXRlKSAweDg4LCAoYnl0ZSkgMHhlYSwKKyAgICAgICAgICAgIChieXRlKSAweDk4LCAoYnl0ZSkgMHg1OQorICAgICAgICB9OworICAgICAgICBmaW5hbCBjaGFyW10gZGVjb2RlZFN1ZmZpeCA9IHsKKyAgICAgICAgICAgIChjaGFyKSAweDg1ZTQsIChjaGFyKSAweDUzOWYsIChjaGFyKSAweDRmNTEsIChjaGFyKSAweDRlMDAsCisgICAgICAgICAgICAoY2hhcikgMHg5MGNlCisgICAgICAgIH07CisgICAgICAgIGZpbmFsIGludCBwcmVmaXhMZW5ndGggPSA4MTg5OworCisgICAgICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlW3ByZWZpeExlbmd0aCArIDEwXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoYnl0ZXMsIChieXRlKSAnICcpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHN1ZmZpeCwgMCwgYnl0ZXMsIHByZWZpeExlbmd0aCwgc3VmZml4Lmxlbmd0aCk7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW5wdXRTdHJlYW1SZWFkZXIgaXNyID0gbmV3IElucHV0U3RyZWFtUmVhZGVyKGlzLCAiU0hJRlRfSklTIik7CisgICAgICAgICAgICBjaGFyW10gY2hhcnMgPSBuZXcgY2hhcls4MTkyXTsKKyAgICAgICAgICAgIGludCBhdCA9IDA7CisKKyAgICAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICAgICBpbnQgYW10ID0gaXNyLnJlYWQoY2hhcnMpOworICAgICAgICAgICAgICAgIGlmIChhbXQgPD0gMCkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFtdDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGNoYXIgYyA9IGNoYXJzW2ldOworICAgICAgICAgICAgICAgICAgICBpZiAoYXQgPCBwcmVmaXhMZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjICE9ICcgJykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoIkZvdW5kIGJhZCBwcmVmaXggY2hhcmFjdGVyICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludCkgYyArICIgYXQgIiArIGF0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgZGVjb2RlZCA9IGRlY29kZWRTdWZmaXhbYXQgLSBwcmVmaXhMZW5ndGhdOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMgIT0gZGVjb2RlZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoIkZvdW5kIG1pc21hdGNoZWQgY2hhcmFjdGVyICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludCkgYyArICIgYXQgIiArIGF0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBhdCsrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGV4KTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkSW5wdXRTdHJlYW1UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZElucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA0ZWMxMjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZElucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjcyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworcHVibGljIGNsYXNzIE9sZElucHV0U3RyZWFtVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyB0ZXN0U3RyaW5nID0gIkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LFxuIiArCisgICAgICAgICJjb25zZWN0ZXR1ciBhZGlwaXNpY2luZyBlbGl0LFxuc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQiICsKKyAgICAgICAgImxhYm9yZSBldCBkb2xvcmUgbWFnbmEgYWxpcXVhLlxuIjsKKworICAgIHByaXZhdGUgSW5wdXRTdHJlYW0gaXM7CisKKyAgICBjbGFzcyBNb2NrSW5wdXRTdHJlYW0gZXh0ZW5kcyBqYXZhLmlvLklucHV0U3RyZWFtIHsKKworICAgICAgICBwcml2YXRlIGJ5dGVbXSBpbnB1dDsKKyAgICAgICAgcHJpdmF0ZSBpbnQgcG9zaXRpb247CisKKyAgICAgICAgcHVibGljIE1vY2tJbnB1dFN0cmVhbSgpIHsKKyAgICAgICAgICAgIHN1cGVyKCk7CisgICAgICAgICAgICBpbnB1dCA9IHRlc3RTdHJpbmcuZ2V0Qnl0ZXMoKTsKKyAgICAgICAgICAgIHBvc2l0aW9uID0gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpbnQgcmVzdWx0ID0gLTE7CisgICAgICAgICAgICBpZiAocG9zaXRpb24gPCBpbnB1dC5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSBpbnB1dFtwb3NpdGlvbl07CisgICAgICAgICAgICAgICAgcG9zaXRpb24rKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW5wdXRTdHJlYW0gbXlJUyA9IG5ldyBNb2NrSW5wdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIG15SVMuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9hdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoaXMuYXZhaWxhYmxlKCksIDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvc2UoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X21hcmtJKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMubWFyaygxMCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbWFya1N1cHBvcnRlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKCJtYXJrU3VwcG9ydGVkKCkgaGFzIHJldHVybmVkIHRoZSB3cm9uZyBkZWZhdWx0IHZhbHVlLiIsCisgICAgICAgICAgICAgICAgaXMubWFya1N1cHBvcnRlZCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWQkQigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBiID0gbmV3IGJ5dGVbMTBdOworICAgICAgICBieXRlW10gcmVmID0gdGVzdFN0cmluZy5nZXRCeXRlcygpOworICAgICAgICBib29sZWFuIGVxdWFsID0gdHJ1ZTsKKyAgICAgICAgaW50IGJ5dGVzUmVhZCA9IDA7CisgICAgICAgIGludCBpOworCisgICAgICAgIC8vIFRlc3QgMTogVGhpcyByZWFkIG9wZXJhdGlvbiBzaG91bGQgY29tcGxldGUgd2l0aG91dCBhbiBlcnJvci4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCBjb3VudCBvZiBieXRlcyByZWFkLiIsCisgICAgICAgICAgICAgICAgaXMucmVhZChiKSwgMTApOworCisgICAgICAgIGZvciAoaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgICAgICAgICBlcXVhbCAmPSAoYltpXSA9PSByZWZbaV0pOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogV3JvbmcgYnl0ZXMgcmVhZC4iLCBlcXVhbCk7CisKKyAgICAgICAgLy8gVGVzdCAyOiBUZXN0IHRoYXQgdGhlIGNvcnJlY3QgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgaXMgcmV0dXJuZWQKKyAgICAgICAgLy8gaWYgdGhlIHNvdXJjZSBoYXMgbGVzcyBieXRlcyBhdmFpbGFibGUgdGhhbiBmaXQgaW4gdGhlIGJ1ZmZlci4KKyAgICAgICAgYiA9IG5ldyBieXRlW3JlZi5sZW5ndGhdOworICAgICAgICBieXRlc1JlYWQgPSBpcy5yZWFkKGIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMjogSW5jb3JyZWN0IGNvdW50IG9mIGJ5dGVzIHJlYWQuIiwKKyAgICAgICAgICAgICAgICBieXRlc1JlYWQsIHJlZi5sZW5ndGggLSAxMCk7CisKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IGJ5dGVzUmVhZDsgaSsrKSB7CisgICAgICAgICAgICBlcXVhbCAmPSAoYltpXSA9PSByZWZbaSArIDEwXSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAyOiBXcm9uZyBieXRlcyByZWFkLiIsIGVxdWFsKTsKKworICAgICAgICAvLyBUZXN0IDM6IFNpbmNlIHdlIGhhdmUgbm93IHJlYWNoZWQgdGhlIGVuZCBvZiB0aGUgc291cmNlLAorICAgICAgICAvLyB0aGUgbmV4dCBjYWxsIG9mIHJlYWQoYnl0ZVtdKSBzaG91bGQgcmV0dXJuIC0xLgorICAgICAgICBieXRlc1JlYWQgPSBpcy5yZWFkKGIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMzoiLCBieXRlc1JlYWQsIC0xKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWQkQklJX0V4Y2VwdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBiID0gbmV3IGJ5dGVbMTBdOworICAgICAgICBpbnQgYnl0ZXNSZWFkID0gMDsKKworICAgICAgICAvLyBUZXN0IDE6IEludmFsaWQgb2Zmc2V0LgorICAgICAgICB0cnkgeworICAgICAgICAgICAgYnl0ZXNSZWFkID0gaXMucmVhZChiLCAtMSwgNSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3QgMjogSW52YWxpZCBsZW5ndGguCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBieXRlc1JlYWQgPSBpcy5yZWFkKGIsIDUsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gVGVzdCAzOiBJbnZhbGlkIG9mZnNldCBhbmQgbGVuZ3RoIGNvbWJpbmF0aW9uIChzdW0gaXMgbGFyZ2VyCisgICAgICAgIC8vIHRoYW4gdGhlIGxlbmd0aCBvZiBiKS4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ5dGVzUmVhZCA9IGlzLnJlYWQoYiwgNiwgNSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3QgNDogQm9yZGVyIGNhc2UuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBieXRlc1JlYWQgPSBpcy5yZWFkKGIsIDYsIDQpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogVW5leHBlY3RlZCBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLiIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCA0OiIsIGJ5dGVzUmVhZCwgNCk7CisKKyAgICAgICAgLy8gVGVzdCA1OiBCb3JkZXIgY2FzZS4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ5dGVzUmVhZCA9IGlzLnJlYWQoYiwgNiwgMCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IFVuZXhwZWN0ZWQgRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDU6IiwgYnl0ZXNSZWFkLCAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWQkQklJKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgIGJ5dGVbXSByZWYgPSB0ZXN0U3RyaW5nLmdldEJ5dGVzKCk7CisgICAgICAgIGJvb2xlYW4gZXF1YWwgPSB0cnVlOworICAgICAgICBpbnQgYnl0ZXNSZWFkID0gMDsKKyAgICAgICAgaW50IGk7CisKKyAgICAgICAgLy8gVGVzdCAxOiBUaGlzIHJlYWQgb3BlcmF0aW9uIHNob3VsZCBjb21wbGV0ZSB3aXRob3V0IGFuIGVycm9yLgorICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IGNvdW50IG9mIGJ5dGVzIHJlYWQuIiwKKyAgICAgICAgICAgICAgICBpcy5yZWFkKGIsIDAsIDUpLCA1KTsKKworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNTsgaSsrKSB7CisgICAgICAgICAgICBlcXVhbCAmPSAoYltpXSA9PSByZWZbaV0pOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogV3JvbmcgYnl0ZXMgcmVhZC4iLCBlcXVhbCk7CisKKyAgICAgICAgLy8gVGVzdCAyOiBSZWFkIG9wZXJhdGlvbiB3aXRoIG9mZnNldC4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IEluY29ycmVjdCBjb3VudCBvZiBieXRlcyByZWFkLiIsCisgICAgICAgICAgICAgICAgaXMucmVhZChiLCA1LCAzKSwgMyk7CisKKyAgICAgICAgZm9yIChpID0gNTsgaSA8IDg7IGkrKykgeworICAgICAgICAgICAgZXF1YWwgJj0gKGJbaV0gPT0gcmVmW2ldKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDI6IFdyb25nIGJ5dGVzIHJlYWQuIiwgZXF1YWwpOworCisgICAgICAgIC8vIFRlc3QgMzogVGVzdCB0aGF0IHRoZSBjb3JyZWN0IG51bWJlciBvZiBieXRlcyByZWFkIGlzIHJldHVybmVkCisgICAgICAgIC8vIGlmIHRoZSBzb3VyY2UgaGFzIGxlc3MgYnl0ZXMgYXZhaWxhYmxlIHRoYW4gZml0IGluIHRoZSBidWZmZXIuCisgICAgICAgIGIgPSBuZXcgYnl0ZVtyZWYubGVuZ3RoXTsKKyAgICAgICAgYnl0ZXNSZWFkID0gaXMucmVhZChiLCAyLCBiLmxlbmd0aCAtIDIpOworCisgICAgICAgIC8vIDggYnl0ZXMgaGF2ZSBiZWVuIHJlYWQgZHVyaW5nIHRlc3RzIDEgYW5kIDIuCisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAzOiBJbmNvcnJlY3QgY291bnQgb2YgYnl0ZXMgcmVhZC4iLAorICAgICAgICAgICAgICAgIGJ5dGVzUmVhZCwgcmVmLmxlbmd0aCAtIDgpOworCisgICAgICAgIC8vIFRoZSBmaXJzdCB0d28gYnl0ZXMgb2YgYiBzaG91bGQgYmUgMCBiZWNhdXNlIG9mIHRoZSBvZmZzZXQuCisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAzOiIsIGJbMF0sIDApOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMzoiLCBiWzFdLCAwKTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IGJ5dGVzUmVhZDsgaSsrKSB7CisgICAgICAgICAgICBlcXVhbCAmPSAoYltpICsgMl0gPT0gcmVmW2kgKyA4XSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAyOiBXcm9uZyBieXRlcyByZWFkLiIsIGVxdWFsKTsKKworICAgICAgICAvLyBUZXN0IDQ6IFNpbmNlIHdlIGhhdmUgbm93IHJlYWNoZWQgdGhlIGVuZCBvZiB0aGUgc291cmNlLAorICAgICAgICAvLyB0aGUgbmV4dCBjYWxsIG9mIHJlYWQoYnl0ZVtdLCBpbnQsIGludCkgc2hvdWxkIHJldHVybiAtMS4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDQ6IiwgaXMucmVhZChiLCAwLCAyKSwgLTEpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVzZXQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZXNldCgpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NraXBMKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVsxMl07CisgICAgICAgIGJ5dGVbXSByZWYgPSB0ZXN0U3RyaW5nLmdldEJ5dGVzKCk7CisgICAgICAgIGludCBpOworICAgICAgICBib29sZWFuIGVxdWFsID0gdHJ1ZTsKKworICAgICAgICAvLyBUZXN0IDE6IENoZWNrIHRoYXQgc2tpcChsb25nKSBqdXN0IHJldHVybnMgMCBpZiBjYWxsZWQgd2l0aCBhCisgICAgICAgIC8vIG5lZ2F0aXZlIG51bWJlci4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IiwgaXMuc2tpcCgtNDIpLCAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCBjb3VudCBvZiBieXRlcyByZWFkLiIsCisgICAgICAgICAgICAgICAgaXMucmVhZChiKSwgMTIpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMTI7IGkrKykgeworICAgICAgICAgICAgZXF1YWwgJj0gKGJbaV0gPT0gcmVmW2ldKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IFdyb25nIGJ5dGVzIHJlYWQuIiwgZXF1YWwpOworCisgICAgICAgIC8vIFRlc3QgMjogQ2hlY2sgaWYgdGhlIG51bWJlciBvZiBieXRlcyBza2lwcGVkIG1hdGNoZXMgdGhlIHJlcXVlc3RlZAorICAgICAgICAvLyBudW1iZXIgb2YgYnl0ZXMgdG8gc2tpcC4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IEluY29ycmVjdCBjb3VudCBvZiBieXRlcyBza2lwcGVkLiIsCisgICAgICAgICAgICAgICAgaXMuc2tpcCgxNyksIDE3KTsKKworICAgICAgICAvLyBUZXN0IDM6IENoZWNrIHRoYXQgYnl0ZXMgaGF2ZSBhY3R1YWxseSBiZWVuIHNraXBwZWQKKyAgICAgICAgaXMucmVhZChiLCAwLCAxMCk7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgICAgICAgICBlcXVhbCAmPSAoYltpXSA9PSByZWZbaSArIDI5XSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAzOiBXcm9uZyBieXRlcyByZWFkLiIsIGVxdWFsKTsKKworICAgICAgICAvLyBUZXN0IDQ6IFRlc3QgdGhhdCB0aGUgY29ycmVjdCBudW1iZXIgb2YgYnl0ZXMgc2tpcHBlZCBpcyByZXR1cm5lZAorICAgICAgICAvLyBpZiB0aGUgc291cmNlIGhhcyBsZXNzIGJ5dGVzIGF2YWlsYWJsZSB0aGFuIGZpdCBpbiB0aGUgYnVmZmVyLgorICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNDogSW5jb3JyZWN0IGNvdW50IG9mIGJ5dGVzIHNraXBwZWQuIiwKKyAgICAgICAgICAgICAgICBpcy5za2lwKHJlZi5sZW5ndGgpLCByZWYubGVuZ3RoIC0gMzkpOworCisgICAgICAgIC8vIFRlc3QgNTogU2luY2Ugd2UgaGF2ZSBub3cgcmVhY2hlZCB0aGUgZW5kIG9mIHRoZSBzb3VyY2UsCisgICAgICAgIC8vIHRoZSBuZXh0IGNhbGwgb2YgcmVhZChieXRlW10pIHNob3VsZCByZXR1cm4gLTEgYW5kIGNhbGxpbmcKKyAgICAgICAgLy8gc2tpcChsb25nKSBzaG91bGQgcmV0dXJuIDAuCisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCA1OiIsIGlzLnJlYWQoYiksIC0xKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDU6IiwgaXMuc2tpcCgxMCksIDApOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICBpcyA9IG5ldyBNb2NrSW5wdXRTdHJlYW0oKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZExpbmVOdW1iZXJJbnB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkTGluZU51bWJlcklucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFmNTU0NGIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZExpbmVOdW1iZXJJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDE3OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkxpbmVOdW1iZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRMaW5lTnVtYmVySW5wdXRTdHJlYW1UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgZmluYWwgU3RyaW5nIHRleHQgPSAiMFxuMVxuMlxuM1xuNFxuNVxuNlxuN1xuOFxuOVxuMTBcbjExXG4xMlxuMTNcbjE0XG4xNVxuMTZcbjE3XG4xOFxuMTlcbjIwXG4yMVxuMjJcbjIzXG4yNFxuMjVcbjI2XG4yN1xuMjhcbjI5XG4zMFxuMzFcbjMyXG4zM1xuMzRcbjM1XG4zNlxuMzdcbjM4XG4zOVxuNDBcbjQxXG40MlxuNDNcbjQ0XG40NVxuNDZcbjQ3XG40OFxuNDlcbjUwXG41MVxuNTJcbjUzXG41NFxuNTVcbjU2XG41N1xuNThcbjU5XG42MFxuNjFcbjYyXG42M1xuNjRcbjY1XG42NlxuNjdcbjY4XG42OVxuNzBcbjcxXG43MlxuNzNcbjc0XG43NVxuNzZcbjc3XG43OFxuNzlcbjgwXG44MVxuODJcbjgzXG44NFxuODVcbjg2XG44N1xuODhcbjg5XG45MFxuOTFcbjkyXG45M1xuOTRcbjk1XG45NlxuOTdcbjk4XG45OVxuMTAwXG4xMDFcbjEwMlxuMTAzXG4xMDRcbjEwNVxuMTA2XG4xMDdcbjEwOFxuMTA5XG4xMTBcbjExMVxuMTEyXG4xMTNcbjExNFxuMTE1XG4xMTZcbjExN1xuMTE4XG4xMTlcbjEyMFxuMTIxXG4xMjJcbjEyM1xuMTI0XG4xMjVcbjEyNlxuMTI3XG4xMjhcbjEyOVxuMTMwXG4xMzFcbjEzMlxuMTMzXG4xMzRcbjEzNVxuMTM2XG4xMzdcbjEzOFxuMTM5XG4xNDBcbjE0MVxuMTQyXG4xNDNcbjE0NFxuMTQ1XG4xNDZcbjE0N1xuMTQ4XG4xNDlcbjE1MFxuMTUxXG4xNTJcbjE1M1xuMTU0XG4xNTVcbjE1NlxuMTU3XG4xNThcbjE1OVxuMTYwXG4xNjFcbjE2MlxuMTYzXG4xNjRcbjE2NVxuMTY2XG4xNjdcbjE2OFxuMTY5XG4xNzBcbjE3MVxuMTcyXG4xNzNcbjE3NFxuMTc1XG4xNzZcbjE3N1xuMTc4XG4xNzlcbjE4MFxuMTgxXG4xODJcbjE4M1xuMTg0XG4xODVcbjE4NlxuMTg3XG4xODhcbjE4OVxuMTkwXG4xOTFcbjE5MlxuMTkzXG4xOTRcbjE5NVxuMTk2XG4xOTdcbjE5OFxuMTk5XG4yMDBcbjIwMVxuMjAyXG4yMDNcbjIwNFxuMjA1XG4yMDZcbjIwN1xuMjA4XG4yMDlcbjIxMFxuMjExXG4yMTJcbjIxM1xuMjE0XG4yMTVcbjIxNlxuMjE3XG4yMThcbjIxOVxuMjIwXG4yMjFcbjIyMlxuMjIzXG4yMjRcbjIyNVxuMjI2XG4yMjdcbjIyOFxuMjI5XG4yMzBcbjIzMVxuMjMyXG4yMzNcbjIzNFxuMjM1XG4yMzZcbjIzN1xuMjM4XG4yMzlcbjI0MFxuMjQxXG4yNDJcbjI0M1xuMjQ0XG4yNDVcbjI0NlxuMjQ3XG4yNDhcbjI0OVxuMjUwXG4yNTFcbjI1MlxuMjUzXG4yNTRcbjI1NVxuMjU2XG4yNTdcbjI1OFxuMjU5XG4yNjBcbjI2MVxuMjYyXG4yNjNcbjI2NFxuMjY1XG4yNjZcbjI2N1xuMjY4XG4yNjlcbjI3MFxuMjcxXG4yNzJcbjI3M1xuMjc0XG4yNzVcbjI3NlxuMjc3XG4yNzhcbjI3OVxuMjgwXG4yODFcbjI4MlxuMjgzXG4yODRcbjI4NVxuMjg2XG4yODdcbjI4OFxuMjg5XG4yOTBcbjI5MVxuMjkyXG4yOTNcbjI5NFxuMjk1XG4yOTZcbjI5N1xuMjk4XG4yOTlcbjMwMFxuMzAxXG4zMDJcbjMwM1xuMzA0XG4zMDVcbjMwNlxuMzA3XG4zMDhcbjMwOVxuMzEwXG4zMTFcbjMxMlxuMzEzXG4zMTRcbjMxNVxuMzE2XG4zMTdcbjMxOFxuMzE5XG4zMjBcbjMyMVxuMzIyXG4zMjNcbjMyNFxuMzI1XG4zMjZcbjMyN1xuMzI4XG4zMjlcbjMzMFxuMzMxXG4zMzJcbjMzM1xuMzM0XG4zMzVcbjMzNlxuMzM3XG4zMzhcbjMzOVxuMzQwXG4zNDFcbjM0MlxuMzQzXG4zNDRcbjM0NVxuMzQ2XG4zNDdcbjM0OFxuMzQ5XG4zNTBcbjM1MVxuMzUyXG4zNTNcbjM1NFxuMzU1XG4zNTZcbjM1N1xuMzU4XG4zNTlcbjM2MFxuMzYxXG4zNjJcbjM2M1xuMzY0XG4zNjVcbjM2NlxuMzY3XG4zNjhcbjM2OVxuMzcwXG4zNzFcbjM3MlxuMzczXG4zNzRcbjM3NVxuMzc2XG4zNzdcbjM3OFxuMzc5XG4zODBcbjM4MVxuMzgyXG4zODNcbjM4NFxuMzg1XG4zODZcbjM4N1xuMzg4XG4zODlcbjM5MFxuMzkxXG4zOTJcbjM5M1xuMzk0XG4zOTVcbjM5NlxuMzk3XG4zOThcbjM5OVxuNDAwXG40MDFcbjQwMlxuNDAzXG40MDRcbjQwNVxuNDA2XG40MDdcbjQwOFxuNDA5XG40MTBcbjQxMVxuNDEyXG40MTNcbjQxNFxuNDE1XG40MTZcbjQxN1xuNDE4XG40MTlcbjQyMFxuNDIxXG40MjJcbjQyM1xuNDI0XG40MjVcbjQyNlxuNDI3XG40MjhcbjQyOVxuNDMwXG40MzFcbjQzMlxuNDMzXG40MzRcbjQzNVxuNDM2XG40MzdcbjQzOFxuNDM5XG40NDBcbjQ0MVxuNDQyXG40NDNcbjQ0NFxuNDQ1XG40NDZcbjQ0N1xuNDQ4XG40NDlcbjQ1MFxuNDUxXG40NTJcbjQ1M1xuNDU0XG40NTVcbjQ1NlxuNDU3XG40NThcbjQ1OVxuNDYwXG40NjFcbjQ2MlxuNDYzXG40NjRcbjQ2NVxuNDY2XG40NjdcbjQ2OFxuNDY5XG40NzBcbjQ3MVxuNDcyXG40NzNcbjQ3NFxuNDc1XG40NzZcbjQ3N1xuNDc4XG40NzlcbjQ4MFxuNDgxXG40ODJcbjQ4M1xuNDg0XG40ODVcbjQ4NlxuNDg3XG40ODhcbjQ4OVxuNDkwXG40OTFcbjQ5MlxuNDkzXG40OTRcbjQ5NVxuNDk2XG40OTdcbjQ5OFxuNDk5XG41MDBcbjUwMSI7CisKKyAgICBTdHJpbmcgZG9zVGV4dCA9ICIwXHJcbjFcclxuMiI7CisKKyAgICBMaW5lTnVtYmVySW5wdXRTdHJlYW0gbG5pczsKKworICAgIExpbmVOdW1iZXJJbnB1dFN0cmVhbSBsbmlzMjsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IFJldHVybmVkIGluY29ycmVjdCBudW1iZXIgb2YgYXZhaWxhYmxlIGJ5dGVzOyIsCisgICAgICAgICAgICAgICAgdGV4dC5sZW5ndGgoKSAvIDIsIGxuaXMuYXZhaWxhYmxlKCkpOworCisgICAgICAgIGxuaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxuaXMuYXZhaWxhYmxlKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBGYWlsZWQgdG8gcmVhZCBjb3JyZWN0IGJ5dGU7IiwKKyAgICAgICAgICAgICAgICAnMCcsIGxuaXMucmVhZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IEZhaWxlZCB0byByZWFkIGNvcnJlY3QgYnl0ZSBvbiBkb3MgdGV4dDsiLAorICAgICAgICAgICAgICAgICcwJywgbG5pczIucmVhZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDM6IEZhaWxlZCB0byByZWFkIGNvcnJlY3QgYnl0ZSBvbiBkb3MgdGV4dDsiLAorICAgICAgICAgICAgICAgICdcbicsIGxuaXMyLnJlYWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCA0OiBGYWlsZWQgdG8gcmVhZCBjb3JyZWN0IGJ5dGUgb24gZG9zIHRleHQ7IiwKKyAgICAgICAgICAgICAgICAnMScsIGxuaXMyLnJlYWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCA1OiBGYWlsZWQgdG8gcmVhZCBjb3JyZWN0IGJ5dGUgb24gZG9zIHRleHQ7IiwKKyAgICAgICAgICAgICAgICAnXG4nLCBsbmlzMi5yZWFkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNjogRmFpbGVkIHRvIHJlYWQgY29ycmVjdCBieXRlIG9uIGRvcyB0ZXh0OyIsCisgICAgICAgICAgICAgICAgJzInLCBsbmlzMi5yZWFkKCkpOworCisgICAgICAgIGxuaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxuaXMucmVhZCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA3OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWQkQklJKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzEwMF07CisgICAgICAgIGxuaXMucmVhZChidWYsIDAsIDEwMCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogSW5jb3JyZWN0IGJ5dGVzIHJlYWQuIiwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKGJ1ZiwgMCwgMTAwKS5lcXVhbHModGV4dC5zdWJzdHJpbmcoMCwgMTAwKSkpOworCisgICAgICAgIGxuaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxuaXMucmVhZChidWYsIDAsIDEwMCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCRCSUlfRXhjZXB0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzEwXTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbG5pcy5yZWFkKGJ1ZiwgLTEsIDEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsbmlzLnJlYWQoYnVmLCAwLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxuaXMucmVhZChidWYsIDEwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Jlc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgbG5pcy5tYXJrKDQwKTsKKyAgICAgICAgbG5pcy5za2lwKDQpOworICAgICAgICBsbmlzLnJlc2V0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBGYWlsZWQgdG8gcmVzZXQiLCAwLCBsbmlzLmdldExpbmVOdW1iZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBGYWlsZWQgdG8gcmVzZXQiLCAnMCcsIGxuaXMucmVhZCgpKTsKKyAgICAgICAgbG5pcy5yZXNldCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsbmlzLm1hcmsoNSk7CisgICAgICAgICAgICBsbmlzLnNraXAoMTAwKTsKKyAgICAgICAgICAgIGxuaXMucmVzZXQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogRmFpbGVkIHRvIGludmFsaWRhdGUgbWFyay4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdDsgbWFyayBoYXMgYmVlbiBpbnZhbGlkYXRlZC4KKyAgICAgICAgfQorCisgICAgICAgIGxuaXMubWFyayg1KTsKKyAgICAgICAgbG5pcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbG5pcy5yZXNldCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldExpbmVOdW1iZXJJKCkgeworICAgICAgICBsbmlzLnNldExpbmVOdW1iZXIoNDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogRmFpbGVkIHRvIHNldCBsaW5lIG51bWJlcjsiLAorICAgICAgICAgICAgICAgIDQyLCBsbmlzLmdldExpbmVOdW1iZXIoKSk7CisgICAgICAgIC8vIFJlcGVhdCB0aGUgdGVzdCB3aXRoIGEgZGlmZmVyZW50IG51bWJlciB0byBtYWtlIHN1cmUgdGhhdCB0aGUKKyAgICAgICAgLy8gbGluZSBudW1iZXIgaXMgcmVhbGx5IHNldC4KKyAgICAgICAgbG5pcy5zZXRMaW5lTnVtYmVyKDg5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IEZhaWxlZCB0byBzZXQgbGluZSBudW1iZXI7IiwKKyAgICAgICAgICAgICAgICA4OSwgbG5pcy5nZXRMaW5lTnVtYmVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2tpcEooKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBsb25nIHNraXBwZWQgPSBsbmlzLnNraXAoNCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgbnVtYmVyIG9mIGNoYXJhY3RlcnMgc2tpcHBlZDsiLAorICAgICAgICAgICAgICAgIDQsIHNraXBwZWQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMjogU2tpcCBmYWlsZWQgdG8gaW5jcmVtZW50IGxpbmUgbnVtYmVyOyIsCisgICAgICAgICAgICAgICAgMiwgbG5pcy5nZXRMaW5lTnVtYmVyKCkpOworCisgICAgICAgIGxuaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxuaXMuc2tpcCg0KTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIEluIG9yZGVyIGZvciBJT0V4Y2VwdGlvbiB0byBiZSB0aHJvd24gaW4gcmVzZXQoKSx0aGUgaW5wdXRTdHJlYW0gdG8KKyAgICAgICAgICogdGhlIGNvbnN0cnVjdG9yIGNhbm5vdCBiZSBhIGJ5dGVBcnJheUlucHV0c3RyZWFtIGJlY2F1c2UgdGhlIHJlc2V0KCkKKyAgICAgICAgICogaW4gYnl0ZUFycmF5SW5wdXRTdHJlYW0gZG9lcyBub3QgdGhyb3cgSU9FeGNlcHRpb24uIFdoZW4KKyAgICAgICAgICogQnVmZmVyZWRJbnB1dFN0cmVhbSBpcyB1c2VkLCB0aGUgc2l6ZSBvZiB0aGUgYnVmZmVyIG11c3QgYmUgc21hbGxlcgorICAgICAgICAgKiB0aGFuIHRoZSByZWFkbGltaXQgaW4gbWFyayBpbm9yZGVyIGZvciBJT0V4Y2VwdGlvbiB0byBiZSB0aHJvd24KKyAgICAgICAgICovCisgICAgICAgIEJ1ZmZlcmVkSW5wdXRTdHJlYW0gYnVmdGVtcCA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSh0ZXh0LmdldEJ5dGVzKCkpLCA0KTsKKyAgICAgICAgbG5pcyA9IG5ldyBMaW5lTnVtYmVySW5wdXRTdHJlYW0oYnVmdGVtcCk7CisgICAgICAgIGxuaXMyID0gbmV3IExpbmVOdW1iZXJJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZG9zVGV4dAorICAgICAgICAgICAgICAgIC5nZXRCeXRlcygpKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRMaW5lTnVtYmVyUmVhZGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRMaW5lTnVtYmVyUmVhZGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcxYzdiYmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZExpbmVOdW1iZXJSZWFkZXJUZXN0LmphdmEKQEAgLTAsMCArMSwxODYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkxpbmVOdW1iZXJSZWFkZXI7CitpbXBvcnQgamF2YS5pby5TdHJpbmdSZWFkZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkTGluZU51bWJlclJlYWRlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBTdHJpbmcgdGV4dCA9ICIwXG4xXG4yXG4zXG40XG41XG42XG43XG44XG45XG4xMFxuMTFcbjEyXG4xM1xuMTRcbjE1XG4xNlxuMTdcbjE4XG4xOVxuMjBcbjIxXG4yMlxuMjNcbjI0XG4yNVxuMjZcbjI3XG4yOFxuMjlcbjMwXG4zMVxuMzJcbjMzXG4zNFxuMzVcbjM2XG4zN1xuMzhcbjM5XG40MFxuNDFcbjQyXG40M1xuNDRcbjQ1XG40NlxuNDdcbjQ4XG40OVxuNTBcbjUxXG41MlxuNTNcbjU0XG41NVxuNTZcbjU3XG41OFxuNTlcbjYwXG42MVxuNjJcbjYzXG42NFxuNjVcbjY2XG42N1xuNjhcbjY5XG43MFxuNzFcbjcyXG43M1xuNzRcbjc1XG43NlxuNzdcbjc4XG43OVxuODBcbjgxXG44MlxuODNcbjg0XG44NVxuODZcbjg3XG44OFxuODlcbjkwXG45MVxuOTJcbjkzXG45NFxuOTVcbjk2XG45N1xuOThcbjk5XG4xMDBcbjEwMVxuMTAyXG4xMDNcbjEwNFxuMTA1XG4xMDZcbjEwN1xuMTA4XG4xMDlcbjExMFxuMTExXG4xMTJcbjExM1xuMTE0XG4xMTVcbjExNlxuMTE3XG4xMThcbjExOVxuMTIwXG4xMjFcbjEyMlxuMTIzXG4xMjRcbjEyNVxuMTI2XG4xMjdcbjEyOFxuMTI5XG4xMzBcbjEzMVxuMTMyXG4xMzNcbjEzNFxuMTM1XG4xMzZcbjEzN1xuMTM4XG4xMzlcbjE0MFxuMTQxXG4xNDJcbjE0M1xuMTQ0XG4xNDVcbjE0NlxuMTQ3XG4xNDhcbjE0OVxuMTUwXG4xNTFcbjE1MlxuMTUzXG4xNTRcbjE1NVxuMTU2XG4xNTdcbjE1OFxuMTU5XG4xNjBcbjE2MVxuMTYyXG4xNjNcbjE2NFxuMTY1XG4xNjZcbjE2N1xuMTY4XG4xNjlcbjE3MFxuMTcxXG4xNzJcbjE3M1xuMTc0XG4xNzVcbjE3NlxuMTc3XG4xNzhcbjE3OVxuMTgwXG4xODFcbjE4MlxuMTgzXG4xODRcbjE4NVxuMTg2XG4xODdcbjE4OFxuMTg5XG4xOTBcbjE5MVxuMTkyXG4xOTNcbjE5NFxuMTk1XG4xOTZcbjE5N1xuMTk4XG4xOTlcbjIwMFxuMjAxXG4yMDJcbjIwM1xuMjA0XG4yMDVcbjIwNlxuMjA3XG4yMDhcbjIwOVxuMjEwXG4yMTFcbjIxMlxuMjEzXG4yMTRcbjIxNVxuMjE2XG4yMTdcbjIxOFxuMjE5XG4yMjBcbjIyMVxuMjIyXG4yMjNcbjIyNFxuMjI1XG4yMjZcbjIyN1xuMjI4XG4yMjlcbjIzMFxuMjMxXG4yMzJcbjIzM1xuMjM0XG4yMzVcbjIzNlxuMjM3XG4yMzhcbjIzOVxuMjQwXG4yNDFcbjI0MlxuMjQzXG4yNDRcbjI0NVxuMjQ2XG4yNDdcbjI0OFxuMjQ5XG4yNTBcbjI1MVxuMjUyXG4yNTNcbjI1NFxuMjU1XG4yNTZcbjI1N1xuMjU4XG4yNTlcbjI2MFxuMjYxXG4yNjJcbjI2M1xuMjY0XG4yNjVcbjI2NlxuMjY3XG4yNjhcbjI2OVxuMjcwXG4yNzFcbjI3MlxuMjczXG4yNzRcbjI3NVxuMjc2XG4yNzdcbjI3OFxuMjc5XG4yODBcbjI4MVxuMjgyXG4yODNcbjI4NFxuMjg1XG4yODZcbjI4N1xuMjg4XG4yODlcbjI5MFxuMjkxXG4yOTJcbjI5M1xuMjk0XG4yOTVcbjI5NlxuMjk3XG4yOThcbjI5OVxuMzAwXG4zMDFcbjMwMlxuMzAzXG4zMDRcbjMwNVxuMzA2XG4zMDdcbjMwOFxuMzA5XG4zMTBcbjMxMVxuMzEyXG4zMTNcbjMxNFxuMzE1XG4zMTZcbjMxN1xuMzE4XG4zMTlcbjMyMFxuMzIxXG4zMjJcbjMyM1xuMzI0XG4zMjVcbjMyNlxuMzI3XG4zMjhcbjMyOVxuMzMwXG4zMzFcbjMzMlxuMzMzXG4zMzRcbjMzNVxuMzM2XG4zMzdcbjMzOFxuMzM5XG4zNDBcbjM0MVxuMzQyXG4zNDNcbjM0NFxuMzQ1XG4zNDZcbjM0N1xuMzQ4XG4zNDlcbjM1MFxuMzUxXG4zNTJcbjM1M1xuMzU0XG4zNTVcbjM1NlxuMzU3XG4zNThcbjM1OVxuMzYwXG4zNjFcbjM2MlxuMzYzXG4zNjRcbjM2NVxuMzY2XG4zNjdcbjM2OFxuMzY5XG4zNzBcbjM3MVxuMzcyXG4zNzNcbjM3NFxuMzc1XG4zNzZcbjM3N1xuMzc4XG4zNzlcbjM4MFxuMzgxXG4zODJcbjM4M1xuMzg0XG4zODVcbjM4NlxuMzg3XG4zODhcbjM4OVxuMzkwXG4zOTFcbjM5MlxuMzkzXG4zOTRcbjM5NVxuMzk2XG4zOTdcbjM5OFxuMzk5XG40MDBcbjQwMVxuNDAyXG40MDNcbjQwNFxuNDA1XG40MDZcbjQwN1xuNDA4XG40MDlcbjQxMFxuNDExXG40MTJcbjQxM1xuNDE0XG40MTVcbjQxNlxuNDE3XG40MThcbjQxOVxuNDIwXG40MjFcbjQyMlxuNDIzXG40MjRcbjQyNVxuNDI2XG40MjdcbjQyOFxuNDI5XG40MzBcbjQzMVxuNDMyXG40MzNcbjQzNFxuNDM1XG40MzZcbjQzN1xuNDM4XG40MzlcbjQ0MFxuNDQxXG40NDJcbjQ0M1xuNDQ0XG40NDVcbjQ0NlxuNDQ3XG40NDhcbjQ0OVxuNDUwXG40NTFcbjQ1MlxuNDUzXG40NTRcbjQ1NVxuNDU2XG40NTdcbjQ1OFxuNDU5XG40NjBcbjQ2MVxuNDYyXG40NjNcbjQ2NFxuNDY1XG40NjZcbjQ2N1xuNDY4XG40NjlcbjQ3MFxuNDcxXG40NzJcbjQ3M1xuNDc0XG40NzVcbjQ3NlxuNDc3XG40NzhcbjQ3OVxuNDgwXG40ODFcbjQ4MlxuNDgzXG40ODRcbjQ4NVxuNDg2XG40ODdcbjQ4OFxuNDg5XG40OTBcbjQ5MVxuNDkyXG40OTNcbjQ5NFxuNDk1XG40OTZcbjQ5N1xuNDk4XG40OTlcbjUwMFxuIjsKKworICAgIExpbmVOdW1iZXJSZWFkZXIgbG5yOworCisgICAgcHVibGljIHZvaWQgdGVzdF9tYXJrSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxuciA9IG5ldyBMaW5lTnVtYmVyUmVhZGVyKG5ldyBTdHJpbmdSZWFkZXIodGV4dCkpOworICAgICAgICBTdHJpbmcgbGluZTsKKyAgICAgICAgbG5yLnNraXAoODApOworICAgICAgICBsbnIubWFyaygxMDApOworICAgICAgICBsaW5lID0gbG5yLnJlYWRMaW5lKCk7CisgICAgICAgIGxuci5yZXNldCgpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IEZhaWxlZCB0byByZXR1cm4gdG8gbWFya2VkIHBvc2l0aW9uLiIsCisgICAgICAgICAgICAgICAgbGluZS5lcXVhbHMobG5yLnJlYWRMaW5lKCkpKTsKKworICAgICAgICBsbnIuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxuci5tYXJrKDQyKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgLy8gVGhlIHNwZWMgZG9lcyBub3Qgc2F5IHRoZSBtYXJrIGhhcyB0byBiZSBpbnZhbGlkYXRlZAorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uTGluZU51bWJlclJlYWRlciNyZWFkKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBsbnIgPSBuZXcgTGluZU51bWJlclJlYWRlcihuZXcgU3RyaW5nUmVhZGVyKHRleHQpKTsKKworICAgICAgICBpbnQgYyA9IGxuci5yZWFkKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBSZWFkIHJldHVybmVkIGluY29ycmVjdCBjaGFyYWN0ZXI7IiwKKyAgICAgICAgICAgICAgICAnMCcsIGMpOworICAgICAgICBsbnIucmVhZCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMjogUmVhZCBmYWlsZWQgdG8gaW5jcmVhc2UgdGhlIGxpbmUgbnVtYmVyOyIsCisgICAgICAgICAgICAgICAgMSwgbG5yLmdldExpbmVOdW1iZXIoKSk7CisKKyAgICAgICAgbG5yLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsbnIucmVhZCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLkxpbmVOdW1iZXJSZWFkZXIjcmVhZChjaGFyW10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCRDSUkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBsbnIgPSBuZXcgTGluZU51bWJlclJlYWRlcihuZXcgU3RyaW5nUmVhZGVyKHRleHQpKTsKKyAgICAgICAgY2hhcltdIGMgPSBuZXcgY2hhclsxMDBdOworICAgICAgICBsbnIucmVhZChjLCAwLCA0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBSZWFkIHJldHVybmVkIGluY29ycmVjdCBjaGFyYWN0ZXJzLiIsICIwXG4xXG4iCisgICAgICAgICAgICAgICAgLmVxdWFscyhuZXcgU3RyaW5nKGMsIDAsIDQpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBSZWFkIGZhaWxlZCB0byBpbmMgbGluZU51bWJlciIsCisgICAgICAgICAgICAgICAgMiwgbG5yLmdldExpbmVOdW1iZXIoKSk7CisKKyAgICAgICAgbG5yLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsbnIucmVhZChjLCAwLCA0KTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkJENJSV9FeGNlcHRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBsbnIgPSBuZXcgTGluZU51bWJlclJlYWRlcihuZXcgU3RyaW5nUmVhZGVyKHRleHQpKTsKKyAgICAgICAgY2hhcltdIGMgPSBuZXcgY2hhclsxMF07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxuci5yZWFkKGMsIC0xLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbG5yLnJlYWQoYywgMCwgLTEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsbnIucmVhZChjLCAxMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkTGluZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxuciA9IG5ldyBMaW5lTnVtYmVyUmVhZGVyKG5ldyBTdHJpbmdSZWFkZXIodGV4dCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBsaW5lIG51bWJlciIsIDAsIGxuci5nZXRMaW5lTnVtYmVyKCkpOworICAgICAgICBTdHJpbmcgbGluZSA9IG51bGw7CisgICAgICAgIGxuci5yZWFkTGluZSgpOworICAgICAgICBsaW5lID0gbG5yLnJlYWRMaW5lKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBSZXR1cm5lZCBpbmNvcnJlY3Qgc3RyaW5nOyIsICIxIiwgbGluZSk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMjogUmV0dXJuZWQgaW5jb3JyZWN0IGxpbmUgbnVtYmVyOiIgKyBsbnIuZ2V0TGluZU51bWJlcigpLAorICAgICAgICAgICAgICAgIGxuci5nZXRMaW5lTnVtYmVyKCkgPT0gMik7CisKKyAgICAgICAgbG5yLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsbnIucmVhZExpbmUoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZXNldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxuciA9IG5ldyBMaW5lTnVtYmVyUmVhZGVyKG5ldyBTdHJpbmdSZWFkZXIodGV4dCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogUmV0dXJuZWQgaW5jb3JyZWN0IGxpbmUgbnVtYmVyOyIsCisgICAgICAgICAgICAgICAgMCwgbG5yLmdldExpbmVOdW1iZXIoKSk7CisgICAgICAgIFN0cmluZyBsaW5lID0gbnVsbDsKKyAgICAgICAgbG5yLm1hcmsoMTAwKTsKKyAgICAgICAgbG5yLnJlYWRMaW5lKCk7CisgICAgICAgIGxuci5yZXNldCgpOworICAgICAgICBsaW5lID0gbG5yLnJlYWRMaW5lKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBGYWlsZWQgdG8gcmVzZXQgcmVhZGVyIiwgIjAiLCBsaW5lKTsKKworICAgICAgICBsbnIubWFyaygxMDApOworICAgICAgICBsbnIuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxuci5yZXNldCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NraXBKKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgbG5yID0gbmV3IExpbmVOdW1iZXJSZWFkZXIobmV3IFN0cmluZ1JlYWRlcih0ZXh0KSk7CisgICAgICAgIGNoYXJbXSBjID0gbmV3IGNoYXJbMTAwXTsKKyAgICAgICAgbG9uZyBza2lwcGVkID0gbG5yLnNraXAoODApOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IG51bWJlciBvZiBjaGFyYWN0ZXJzIHNraXBwZWQ7IiwKKyAgICAgICAgICAgICAgICA4MCwgc2tpcHBlZCk7CisgICAgICAgIGxuci5yZWFkKGMsIDAsIDEwMCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMjogRmFpbGVkIHRvIHNraXAgdG8gY29ycmVjdCBwb3NpdGlvbi4iLAorICAgICAgICAgICAgICAgIHRleHQuc3Vic3RyaW5nKDgwLCAxODApLmVxdWFscyhuZXcgU3RyaW5nKGMsIDAsIGMubGVuZ3RoKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsbnIuc2tpcCgtMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgbG5yLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsbnIuc2tpcCgxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRPYmplY3RJbnB1dE91dHB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkT2JqZWN0SW5wdXRPdXRwdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2IzZTkyZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkT2JqZWN0SW5wdXRPdXRwdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSwyNzIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5FT0ZFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9PdXRwdXRTdHJlYW07CisKK3B1YmxpYyBjbGFzcyBPbGRPYmplY3RJbnB1dE91dHB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBPYmplY3RPdXRwdXRTdHJlYW0gb3M7CisKKyAgICBwcml2YXRlIE9iamVjdElucHV0U3RyZWFtIGlzOworCisgICAgcHJpdmF0ZSBTdXBwb3J0X091dHB1dFN0cmVhbSBzb3M7CisKKyAgICBTdHJpbmcgdW5paHcgPSAiXHUwMDQ4XHUwMDY1XHUwMDZDXHUwMDZDXHUwMDZGXHUwMDIwXHUwMDU3XHUwMDZGXHUwMDcyXHUwMDZDXHUwMDY0IjsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZF93cml0ZUJvb2xlYW4oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvcy53cml0ZUJvb2xlYW4odHJ1ZSk7CisKKyAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgb3Blbk9iamVjdElucHV0U3RyZWFtKCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogSW5jb3JyZWN0IGJvb2xlYW4gd3JpdHRlbiBvciByZWFkLiIsCisgICAgICAgICAgICAgICAgaXMucmVhZEJvb2xlYW4oKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWRCb29sZWFuKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEVPRkV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWRCb29sZWFuKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZF93cml0ZUJ5dGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvcy53cml0ZUJ5dGUoKGJ5dGUpIDEyNyk7CisKKyAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgb3Blbk9iamVjdElucHV0U3RyZWFtKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgYnl0ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMTI3LCBpcy5yZWFkQnl0ZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZEJ5dGUoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZEJ5dGUoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkX3dyaXRlQ2hhcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9zLndyaXRlQ2hhcignYicpOworCisgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIG9wZW5PYmplY3RJbnB1dFN0cmVhbSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IGNoYXIgd3JpdHRlbiBvciByZWFkOyIsCisgICAgICAgICAgICAgICAgJ2InLCBpcy5yZWFkQ2hhcigpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZENoYXIoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZENoYXIoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkX3dyaXRlRG91YmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3Mud3JpdGVEb3VibGUoMjM0NS43NjgzNDcyMDIwMik7CisKKyAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgb3Blbk9iamVjdElucHV0U3RyZWFtKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgZG91YmxlIHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIDIzNDUuNzY4MzQ3MjAyMDIsIGlzLnJlYWREb3VibGUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWREb3VibGUoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZERvdWJsZSgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfd3JpdGVGbG9hdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9zLndyaXRlRmxvYXQoMjkuMDg3NjRmKTsKKworICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICBvcGVuT2JqZWN0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCBmbG9hdCB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICAyOS4wODc2NGYsIGlzLnJlYWRGbG9hdCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZEZsb2F0KCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEVPRkV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWRGbG9hdCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfd3JpdGVJbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvcy53cml0ZUludCg3NjgzNDcyMDIpOworCisgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIG9wZW5PYmplY3RJbnB1dFN0cmVhbSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IGludCB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICA3NjgzNDcyMDIsIGlzLnJlYWRJbnQoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWRJbnQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZEludCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfd3JpdGVMb25nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3Mud3JpdGVMb25nKDk4NzU2NDUyODMzMzNMKTsKKworICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICBvcGVuT2JqZWN0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCBsb25nIHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIDk4NzU2NDUyODMzMzNMLCBpcy5yZWFkTG9uZygpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZExvbmcoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZExvbmcoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkX3dyaXRlU2hvcnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvcy53cml0ZVNob3J0KDk4NzUpOworCisgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIG9wZW5PYmplY3RJbnB1dFN0cmVhbSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IHNob3J0IHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIDk4NzUsIGlzLnJlYWRTaG9ydCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZFNob3J0KCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEVPRkV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWRTaG9ydCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfd3JpdGVVVEYoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvcy53cml0ZVVURih1bmlodyk7CisKKyAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgb3Blbk9iamVjdElucHV0U3RyZWFtKCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogSW5jb3JyZWN0IFVURi04IHN0cmluZyB3cml0dGVuIG9yIHJlYWQuIiwKKyAgICAgICAgICAgICAgICBpcy5yZWFkVVRGKCkuZXF1YWxzKHVuaWh3KSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWRVVEYoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZFVURigpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgb3Blbk9iamVjdElucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHNvcy50b0J5dGVBcnJheSgpKSk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzb3MgPSBuZXcgU3VwcG9ydF9PdXRwdXRTdHJlYW0oMjU2KTsKKyAgICAgICAgb3MgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKHNvcyk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRPYmplY3RJbnB1dFN0cmVhbUdldEZpZWxkVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRPYmplY3RJbnB1dFN0cmVhbUdldEZpZWxkVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5NmQxMzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZE9iamVjdElucHV0U3RyZWFtR2V0RmllbGRUZXN0LmphdmEKQEAgLTAsMCArMSwyNTkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfR2V0UHV0RmllbGRzOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9HZXRQdXRGaWVsZHNEZWZhdWx0ZWQ7CisKKworLyoqCisgKiBUZXN0cyB0aGUgbWV0aG9kcyBvZiB7QGNvZGUgT2JqZWN0SW5wdXRTdHJlYW0uR2V0RmllbGR9LiBUaHJlZSB0aGluZ3MgbWFrZQorICogdGhpcyBjbGFzcyBzb21ld2hhdCBkaWZmaWN1bHQgdG8gdGVzdDoKKyAqIDxvbD4KKyAqIDxsaT5JdCBpcyBhIGNvbXBsZXRlbHkgYWJzdHJhY3QgY2xhc3M7IG5vbmUgb2YgdGhlIG1ldGhvZHMgaXMgaW1wbGVtZW50ZWQgaW4KKyAqIHtAY29kZSBPYmplY3RJbnB1dFN0cmVhbS5HZXRGaWVsZH0uPC9saT4KKyAqIDxsaT5UaGVyZSBpcyBubyBwdWJsaWMgY2xhc3MgdGhhdCBpbXBsZW1lbnRzCisgKiB7QGNvZGUgT2JqZWN0SW5wdXRTdHJlYW0uR2V0RmllbGR9LiBUaGUgb25seSB3YXkgdG8gZ2V0IGFuIGltcGxlbWVudGF0aW9uIGlzCisgKiBieSBjYWxsaW5nIHtAY29kZSBPYmplY3RJbnB1dFN0cmVhbS5nZXRGaWVsZHMoKX0uPC9saT4KKyAqIDxsaT5JbnZva2luZyB7QGNvZGUgT2JqZWN0T3V0cHV0U3RyZWFtLmdldEZpZWxkcygpfSBvbmx5IHdvcmtzIGZyb20gd2l0aGluCisgKiB0aGUgcHJpdmF0ZSB7QGNvZGUgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSl9IG1ldGhvZCBvZiBhIGNsYXNzIHRoYXQKKyAqIGltcGxlbWVudHMge0Bjb2RlIFNlcmlhbGl6YWJsZX07IGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24gb3RoZXJ3aXNlLjwvbGk+CisgKiA8L29sPgorICogPHA+CisgKiBHaXZlbiB0aGVzZSByZXN0cmljdGlvbnMsIGFuIGluZGlyZWN0IGFwcHJvYWNoIGlzIHVzZWQgdG8gdGVzdAorICoge0Bjb2RlIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkfTogVGhyZWUgc2VyaWFsaXphYmxlIGhlbHBlciBjbGFzc2VzIGluCisgKiBwYWNrYWdlIHtAY29kZSB0ZXN0cy5zdXBwb3J0fSAoe0Bjb2RlIFN1cHBvcnRfR2V0UHV0RmllbGRzfSwKKyAqIHtAY29kZSBTdXBwb3J0X0dldFB1dEZpZWxkc0RlcHJlY2F0ZWR9IGFuZAorICoge0Bjb2RlIFN1cHBvcnRfR2V0UHV0RmllbGRzRGVmYXVsdGVkfSkgaW1wbGVtZW50CisgKiB7QGNvZGUgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSl9IHRvIHJlYWQgZGF0YSBmcm9tIGFuIGlucHV0IHN0cmVhbS4KKyAqIFRoaXMgaW5wdXQgc3RyZWFtIGluIHR1cm4gcmVhZHMgZnJvbSBvbmUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZmlsZXMKKyAqICh7QGNvZGUgdGVzdEZpZWxkcy5zZXJ9LCB7QGNvZGUgdGVzdEZpZWxkc0RlcHJlY2F0ZWQuc2VyfSBhbmQKKyAqIHtAY29kZSB0ZXN0RmllbGRzRGVmYXVsdGVkLnNlcn0pIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgd2l0aAorICoge0Bjb2RlIHRlc3RzLnV0aWwuRmllbGRUZXN0RmlsZUdlbmVyYXRvcn0gb24gYSByZWZlcmVuY2UgcGxhdGZvcm0uCisgKiA8L3A+CisgKiA8cD4KKyAqIFRoZSB0ZXN0IG1ldGhvZCBpbiB0aGlzIGNsYXNzIGV4cGVjdHMgdG8gZmluZCB0aGUgcmVmZXJlbmNlIGZpbGVzIGFzIGEKKyAqIHJlc291cmNlIHN0b3JlZCBhdCB7QGNvZGUgdGVzdHMvYXBpL2phdmEvaW99LgorICogPC9wPgorICovCitwdWJsaWMgY2xhc3MgT2xkT2JqZWN0SW5wdXRTdHJlYW1HZXRGaWVsZFRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBPYmplY3RJbnB1dFN0cmVhbSBvaXMgPSBudWxsOworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgRklMRU5BTUUgPQorICAgICAgICAgICAgIi90ZXN0cy9hcGkvamF2YS9pby90ZXN0RmllbGRzLnNlciI7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgREVGQVVMVEVEX0ZJTEVOQU1FID0KKyAgICAgICAgICAgICIvdGVzdHMvYXBpL2phdmEvaW8vdGVzdEZpZWxkc0RlZmF1bHRlZC5zZXIiOworCisgICAgcHVibGljIGJvb2xlYW4gYm9vbGVhblZhbHVlOworICAgIHB1YmxpYyBieXRlIGJ5dGVWYWx1ZTsKKyAgICBwdWJsaWMgY2hhciBjaGFyVmFsdWU7CisgICAgcHVibGljIGludCBpbnRWYWx1ZTsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGluaXRPaXMoRklMRU5BTUUpOworICAgICAgICBTdXBwb3J0X0dldFB1dEZpZWxkcyBvYmplY3QgPSAoU3VwcG9ydF9HZXRQdXRGaWVsZHMpIG9pcy5yZWFkT2JqZWN0KCk7CisgICAgICAgIFN1cHBvcnRfR2V0UHV0RmllbGRzIG5ld09iamVjdCA9IG5ldyBTdXBwb3J0X0dldFB1dEZpZWxkcygpOworICAgICAgICBuZXdPYmplY3QuaW5pdFRlc3RWYWx1ZXMoKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IFRoZSBvYmplY3QgcmVhZCBmcm9tIHRoZSByZWZlcmVuY2UgZmlsZSBkb2VzICIgKworICAgICAgICAgICAgICAgICAgICJub3QgbWF0Y2ggYSBsb2NhbGx5IGNyZWF0ZWQgaW5zdGFuY2Ugb2YgdGhlIHNhbWUgY2xhc3MuIiwKKyAgICAgICAgICAgICAgICAgICBvYmplY3QuZXF1YWxzKG5ld09iamVjdCkpOworCisgICAgICAgIGluaXRPaXMoREVGQVVMVEVEX0ZJTEVOQU1FKTsKKyAgICAgICAgU3VwcG9ydF9HZXRQdXRGaWVsZHNEZWZhdWx0ZWQgZGVmYXVsdGVkID0KKyAgICAgICAgICAgICAgICAoU3VwcG9ydF9HZXRQdXRGaWVsZHNEZWZhdWx0ZWQpIG9pcy5yZWFkT2JqZWN0KCk7CisgICAgICAgIFN1cHBvcnRfR2V0UHV0RmllbGRzRGVmYXVsdGVkIG5ld0RlZmF1bHRlZCA9CisgICAgICAgICAgICAgICAgbmV3IFN1cHBvcnRfR2V0UHV0RmllbGRzRGVmYXVsdGVkKCk7CisgICAgICAgIG5ld0RlZmF1bHRlZC5pbml0VGVzdFZhbHVlcygpOworCisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMjogVGhlIG9iamVjdCByZWFkIGZyb20gdGhlIHJlZmVyZW5jZSBmaWxlIGRvZXMgIiArCisgICAgICAgICAgICAgICAgICAgIm5vdCBtYXRjaCBhIGxvY2FsbHkgY3JlYXRlZCBpbnN0YW5jZSBvZiB0aGUgc2FtZSBjbGFzcy4iLAorICAgICAgICAgICAgICAgICAgIGRlZmF1bHRlZC5lcXVhbHMobmV3RGVmYXVsdGVkKSk7CisKKyAgICAgICAgLy8gRXhlY3V0aW5nIHRoZSBzYW1lIHByb2NlZHVyZSBhZ2FpbnN0IHRoZSBmaWxlIGNyZWF0ZWQgd2l0aCB0aGUKKyAgICAgICAgLy8gZGVwcmVjYXRlZCBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGRzLndyaXRlKE9iamVjdE91dHB1dCkgbWV0aG9kCisgICAgICAgIC8vIGlzIG5vdCBwb3NzaWJsZSBzaW5jZSB0aGVyZSBpcyBubyBjb3JyZXNwb25kaW5nIHJlYWQoT2JqZWN0SW5wdXQpCisgICAgICAgIC8vIG1ldGhvZC4gV2hlbiB0cnlpbmcgdG8gZG8gaXQgYXMgaW4gdGVzdHMgMSBhbmQgMiwgYQorICAgICAgICAvLyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9kZWZhdWx0ZWRMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbml0T2lzKEZJTEVOQU1FKTsKKyAgICAgICAgU3VwcG9ydF9HZXRQdXRGaWVsZHMgb2JqZWN0ID0gKFN1cHBvcnRfR2V0UHV0RmllbGRzKSBvaXMucmVhZE9iamVjdCgpOworICAgICAgICBPYmplY3RJbnB1dFN0cmVhbS5HZXRGaWVsZCBmaWVsZHMgPSBvYmplY3QuZ2V0RmllbGQ7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpZWxkcy5kZWZhdWx0ZWQoIm5vRmllbGQiKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHt9CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBmaWVsZCBsb25nVmFsdWUgc2hvdWxkIG5vdCBiZSBkZWZhdWx0ZWQuIiwKKyAgICAgICAgICAgICAgICAgICBmaWVsZHMuZGVmYXVsdGVkKCJsb25nVmFsdWUiKSk7CisKKyAgICAgICAgLy8gTm93IHRoZSBzYW1lIHdpdGggZGVmYXVsdGVkIGZpZWxkcy4KKyAgICAgICAgaW5pdE9pcyhERUZBVUxURURfRklMRU5BTUUpOworICAgICAgICBTdXBwb3J0X0dldFB1dEZpZWxkc0RlZmF1bHRlZCBkZWZhdWx0ZWRPYmplY3QgPQorICAgICAgICAgICAgKFN1cHBvcnRfR2V0UHV0RmllbGRzRGVmYXVsdGVkKSBvaXMucmVhZE9iamVjdCgpOworICAgICAgICBmaWVsZHMgPSBkZWZhdWx0ZWRPYmplY3QuZ2V0RmllbGQ7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGZpZWxkIGxvbmdWYWx1ZSBzaG91bGQgYmUgZGVmYXVsdGVkLiIsCisgICAgICAgICAgICAgICAgICAgZmllbGRzLmRlZmF1bHRlZCgibG9uZ1ZhbHVlIikpOworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRFeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaW5pdE9pcyhGSUxFTkFNRSk7CisgICAgICAgIFN1cHBvcnRfR2V0UHV0RmllbGRzIG9iamVjdCA9IChTdXBwb3J0X0dldFB1dEZpZWxkcykgb2lzLnJlYWRPYmplY3QoKTsKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0uR2V0RmllbGQgZmllbGRzID0gb2JqZWN0LmdldEZpZWxkOworCisgICAgICAgIC8vIE1ldGhvZHMgY2FsbGVkIHdpdGggaW52YWxpZCBmaWVsZCBuYW1lLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgZmllbGRzLmdldCgibm9WYWx1ZSIsIGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCBmb3Igbm90IGV4aXN0aW5nIG5hbWUgIiArCisgICAgICAgICAgICAgICAgICJhcmd1bWVudCBpbiBnZXQoU3RyaW5nLCBib29sZWFuKS4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHt9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpZWxkcy5nZXQoIm5vVmFsdWUiLCAoYnl0ZSkgMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgZm9yIG5vdCBleGlzdGluZyBuYW1lICIgKworICAgICAgICAgICAgICAgICAiYXJndW1lbnQgaW4gZ2V0KFN0cmluZywgYnl0ZSkuIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7fQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaWVsZHMuZ2V0KCJub1ZhbHVlIiwgKGNoYXIpIDApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGZvciBub3QgZXhpc3RpbmcgbmFtZSAiICsKKyAgICAgICAgICAgICAgICAgImFyZ3VtZW50IGluIGdldChTdHJpbmcsIGNoYXIpLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkge30KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmllbGRzLmdldCgibm9WYWx1ZSIsIDAuMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgZm9yIG5vdCBleGlzdGluZyBuYW1lICIgKworICAgICAgICAgICAgICAgICAiYXJndW1lbnQgaW4gZ2V0KFN0cmluZywgZG91YmxlKS4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHt9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpZWxkcy5nZXQoIm5vVmFsdWUiLCAwLjBmKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCBmb3Igbm90IGV4aXN0aW5nIG5hbWUgIiArCisgICAgICAgICAgICAgICAgICJhcmd1bWVudCBpbiBnZXQoU3RyaW5nLCBmbG9hdCkuIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7fQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaWVsZHMuZ2V0KCJub1ZhbHVlIiwgKGxvbmcpIDApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGZvciBub3QgZXhpc3RpbmcgbmFtZSAiICsKKyAgICAgICAgICAgICAgICAgImFyZ3VtZW50IGluIGdldChTdHJpbmcsIGxvbmcpLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkge30KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmllbGRzLmdldCgibm9WYWx1ZSIsIDApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGZvciBub3QgZXhpc3RpbmcgbmFtZSAiICsKKyAgICAgICAgICAgICAgICAgImFyZ3VtZW50IGluIGdldChTdHJpbmcsIGludCkuIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7fQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaWVsZHMuZ2V0KCJub1ZhbHVlIiwgbmV3IE9iamVjdCgpKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCBmb3Igbm90IGV4aXN0aW5nIG5hbWUgIiArCisgICAgICAgICAgICAgICAgICJhcmd1bWVudCBpbiBnZXQoU3RyaW5nLCBPYmplY3QpLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkge30KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmllbGRzLmdldCgibm9WYWx1ZSIsIChzaG9ydCkgMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgZm9yIG5vdCBleGlzdGluZyBuYW1lICIgKworICAgICAgICAgICAgICAgICAiYXJndW1lbnQgaW4gZ2V0KFN0cmluZywgc2hvcnQpLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkge30KKworICAgICAgICAvLyBNZXRob2RzIGNhbGxlZCB3aXRoIGNvcnJlY3QgZmllbGQgbmFtZSBidXQgbm9uLW1hdGNoaW5nIHR5cGUuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaWVsZHMuZ2V0KCJieXRlVmFsdWUiLCBmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgZm9yIG5vbi1tYXRjaGluZyBuYW1lICIgKworICAgICAgICAgICAgICAgICAiYW5kIHR5cGUgYXJndW1lbnRzIGluIGdldChTdHJpbmcsIGJvb2xlYW4pLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkge30KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmllbGRzLmdldCgiYm9vbGVhblZhbHVlIiwgKGJ5dGUpIDApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGZvciBub24tbWF0Y2hpbmcgbmFtZSAiICsKKyAgICAgICAgICAgICAgICAgImFuZCB0eXBlIGFyZ3VtZW50cyBpbiBnZXQoU3RyaW5nLCBieXRlKS4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHt9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpZWxkcy5nZXQoImludFZhbHVlIiwgKGNoYXIpIDApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGZvciBub24tbWF0Y2hpbmcgbmFtZSAiICsKKyAgICAgICAgICAgICAgICAgImFuZCB0eXBlIGFyZ3VtZW50cyBpbiBnZXQoU3RyaW5nLCBjaGFyKS4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHt9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpZWxkcy5nZXQoImZsb2F0VmFsdWUiLCAwLjApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGZvciBub24tbWF0Y2hpbmcgbmFtZSAiICsKKyAgICAgICAgICAgICAgICAgImFuZCB0eXBlIGFyZ3VtZW50cyBpbiBnZXQoU3RyaW5nLCBkb3VibGUpLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkge30KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmllbGRzLmdldCgiZG91YmxlVmFsdWUiLCAwLjBmKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCBmb3Igbm9uLW1hdGNoaW5nIG5hbWUgIiArCisgICAgICAgICAgICAgICAgICJhbmQgdHlwZSBhcmd1bWVudHMgaW4gZ2V0KFN0cmluZywgZmxvYXQpLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkge30KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmllbGRzLmdldCgiaW50VmFsdWUiLCAobG9uZykgMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgZm9yIG5vbi1tYXRjaGluZyBuYW1lICIgKworICAgICAgICAgICAgICAgICAiYW5kIHR5cGUgYXJndW1lbnRzIGluIGdldChTdHJpbmcsIGxvbmcpLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkge30KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmllbGRzLmdldCgic2hvcnRWYWx1ZSIsIDApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGZvciBub24tbWF0Y2hpbmcgbmFtZSAiICsKKyAgICAgICAgICAgICAgICAgImFuZCB0eXBlIGFyZ3VtZW50cyBpbiBnZXQoU3RyaW5nLCBpbnQpLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkge30KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmllbGRzLmdldCgiYm9vbGVhblZhbHVlIiwgbmV3IE9iamVjdCgpKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCBmb3Igbm9uLW1hdGNoaW5nIG5hbWUgIiArCisgICAgICAgICAgICAgICAgICJhbmQgdHlwZSBhcmd1bWVudHMgaW4gZ2V0KFN0cmluZywgT2JqZWN0KS4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHt9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpZWxkcy5nZXQoImxvbmdWYWx1ZSIsIChzaG9ydCkgMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgZm9yIG5vbi1tYXRjaGluZyBuYW1lICIgKworICAgICAgICAgICAgICAgICAiYW5kIHR5cGUgYXJndW1lbnRzIGluIGdldChTdHJpbmcsIHNob3J0KS4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHt9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRPYmplY3RTdHJlYW1DbGFzcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbml0T2lzKEZJTEVOQU1FKTsKKyAgICAgICAgU3VwcG9ydF9HZXRQdXRGaWVsZHMgb2JqZWN0ID0gKFN1cHBvcnRfR2V0UHV0RmllbGRzKSBvaXMucmVhZE9iamVjdCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJSZXR1cm4gdmFsdWUgb2YgZ2V0T2JqZWN0U3RyZWFtQ2xhc3MoKSBzaG91bGQgbm90IGJlIG51bGwuIiwKKyAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuZ2V0RmllbGQuZ2V0T2JqZWN0U3RyZWFtQ2xhc3MoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGluaXRPaXMoU3RyaW5nIGZpbGVOYW1lKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG9pcyAhPSBudWxsKSB7CisgICAgICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICAgICAgfQorICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgIGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbShmaWxlTmFtZSkpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChvaXMgIT0gbnVsbCkgeworICAgICAgICAgICAgb2lzLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkT2JqZWN0T3V0cHV0U3RyZWFtUHV0RmllbGRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZE9iamVjdE91dHB1dFN0cmVhbVB1dEZpZWxkVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5MDA4YWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZE9iamVjdE91dHB1dFN0cmVhbVB1dEZpZWxkVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTQwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0dldFB1dEZpZWxkczsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfR2V0UHV0RmllbGRzRGVwcmVjYXRlZDsKKworLyoqCisgKiBUZXN0cyB0aGUgbWV0aG9kcyBvZiB7QGNvZGUgT2JqZWN0T3V0cHV0U3RyZWFtLlB1dEZpZWxkfS4gVGhyZWUgdGhpbmdzIG1ha2UKKyAqIHRoaXMgY2xhc3Mgc29tZXdoYXQgZGlmZmljdWx0IHRvIHRlc3Q6CisgKiA8b2w+CisgKiA8bGk+SXQgaXMgYSBjb21wbGV0ZWx5IGFic3RyYWN0IGNsYXNzOyBub25lIG9mIHRoZSBtZXRob2RzIGlzIGltcGxlbWVudGVkIGluCisgKiB7QGNvZGUgT2JqZWN0T3V0cHV0U3RyZWFtLlB1dEZpZWxkfS48L2xpPgorICogPGxpPlRoZXJlIGlzIG5vIHB1YmxpYyBjbGFzcyB0aGF0IGltcGxlbWVudHMKKyAqIHtAY29kZSBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGR9LiBUaGUgb25seSB3YXkgdG8gZ2V0IGFuIGltcGxlbWVudGF0aW9uCisgKiBpcyBieSBjYWxsaW5nIHtAY29kZSBPYmplY3RPdXRwdXRTdHJlYW0ucHV0RmllbGRzKCl9LjwvbGk+CisgKiA8bGk+SW52b2tpbmcgdGhlIG1ldGhvZHMgb2Yge0Bjb2RlIE9iamVjdE91dHB1dFN0cmVhbS5QdXRGaWVsZH0gb25seSB3b3JrcworICogZnJvbSB3aXRoaW4gdGhlIHByaXZhdGUge0Bjb2RlIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSl9IG1ldGhvZCBvZiBhCisgKiBjbGFzcyB0aGF0IGltcGxlbWVudHMge0Bjb2RlIFNlcmlhbGl6YWJsZX07IGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24KKyAqIG90aGVyd2lzZS48L2xpPgorICogPC9vbD4KKyAqIDxwPgorICogR2l2ZW4gdGhlc2UgcmVzdHJpY3Rpb25zLCBhbiBpbmRpcmVjdCBhcHByb2FjaCBpcyB1c2VkIHRvIHRlc3QKKyAqIHtAY29kZSBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGR9OiBUaGUgc2VyaWFsaXphYmxlIGhlbHBlciBjbGFzcworICoge0Bjb2RlIHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9HZXRQdXRGaWVsZHN9IGltcGxlbWVudHMKKyAqIHtAY29kZSB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0pfSBhbmQgdXNlcyBhbGwge0Bjb2RlIHB1dFh9IG1ldGhvZHMgaW4KKyAqIHtAY29kZSBQdXRGaWVsZH0gdG8gd3JpdGUgZGF0YSB0byB0aGUgb3V0cHV0IHN0cmVhbS4gQSBzZWNvbmQgaGVscGVyIGNsYXNzLAorICoge0Bjb2RlIHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9HZXRQdXRGaWVsZHNEZXByZWNhdGVkfSwgYWxzbyB1c2VzIHRoZQorICogZGVwcmVjYXRlZCB7QGNvZGUgT2JqZWN0T3V0cHV0U3RyZWFtLlB1dEZpZWxkLndyaXRlKE9iamVjdE91dHB1dCl9LgorICoge0Bjb2RlIHRlc3RzLnV0aWwuRmllbGRUZXN0RmlsZUdlbmVyYXRvcn0gY2FuIHRoZW4gYmUgdXNlZCBvbiBhIHJlZmVyZW5jZQorICogcGxhdGZvcm0gdG8gd3JpdGUgdGhlc2UgdHdvIGNsYXNzZXMgdG8gdGhlIGZpbGUge0Bjb2RlIHRlc3RGaWVsZHMuc2VyfSBhbmQKKyAqIHtAY29kZSB0ZXN0RmllbGRzRGVwcmVjYXRlZC5zZXJ9IHJlc3BlY3RpdmVseS4KKyAqIDwvcD4KKyAqIDxwPgorICogVGhlIHRlc3QgbWV0aG9kcyBpbiB0aGlzIGNsYXNzIGV4cGVjdCB0byBmaW5kIHtAY29kZSB0ZXN0RmllbGRzLnNlcn0gYW5kCisgKiB7QGNvZGUgdGVzdEZpZWxkc0RlcHJlY2F0ZWQuc2VyfSBhcyBhIHJlc291cmNlIHN0b3JlZCBhdAorICoge0Bjb2RlIHRlc3RzL2FwaS9qYXZhL2lvfS4gVGhlIGNvbnRlbnRzIG9mIHRoZXNlIGZpbGVzIGlzIGNvbXBhcmVkIHRvIHdoYXQKKyAqIGlzIHdyaXR0ZW4gd2hlbiB7QGNvZGUgU3VwcG9ydF9HZXRQdXRGaWVsZHMud3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtKX0KKyAqIGFuZCB7QGNvZGUgU3VwcG9ydF9HZXRQdXRGaWVsZHNEZXByZWNhdGVkLndyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSl9IGlzCisgKiBjYWxsZWQgYnkgdGhlIHRlc3QgbWV0aG9kcy4KKyAqIDwvcD4KKyAqLworcHVibGljIGNsYXNzIE9sZE9iamVjdE91dHB1dFN0cmVhbVB1dEZpZWxkVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIEZJTEVOQU1FID0KKyAgICAgICAgIi90ZXN0cy9hcGkvamF2YS9pby90ZXN0RmllbGRzLnNlciI7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgREVQUkVDQVRFRF9GSUxFTkFNRSA9CisgICAgICAgICIvdGVzdHMvYXBpL2phdmEvaW8vdGVzdEZpZWxkc0RlcHJlY2F0ZWQuc2VyIjsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcHV0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN1cHBvcnRfR2V0UHV0RmllbGRzIHRvU2VyaWFsaXplID0gbmV3IFN1cHBvcnRfR2V0UHV0RmllbGRzKCk7CisgICAgICAgIGJ5dGVbXSBjb250ZW50OworICAgICAgICBieXRlW10gcmVmQ29udGVudDsKKyAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtIG9vcyA9IG51bGw7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zOworCisgICAgICAgIHRvU2VyaWFsaXplLmluaXRUZXN0VmFsdWVzKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlZkNvbnRlbnQgPSBnZXRSZWZDb250ZW50KEZJTEVOQU1FKTsKKworICAgICAgICAgICAgYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0ocmVmQ29udGVudC5sZW5ndGgpOworICAgICAgICAgICAgb29zID0gbmV3IE9iamVjdE91dHB1dFN0cmVhbShiYW9zKTsKKworICAgICAgICAgICAgb29zLndyaXRlT2JqZWN0KHRvU2VyaWFsaXplKTsKKyAgICAgICAgICAgIGNvbnRlbnQgPSBiYW9zLnRvQnl0ZUFycmF5KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTZXJpYWxpemF0aW9uIGlzIG5vdCBlcXVhbCB0byByZWZlcmVuY2UgcGxhdGZvcm0uIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMoY29udGVudCwgcmVmQ29udGVudCkpOworICAgICAgICB9CisgICAgICAgIGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKG9vcyAhPSBudWxsKSBvb3MuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGVMamF2YV9pb19PYmplY3RPdXRwdXRTdHJlYW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3VwcG9ydF9HZXRQdXRGaWVsZHNEZXByZWNhdGVkIHRvU2VyaWFsaXplID0gbmV3IFN1cHBvcnRfR2V0UHV0RmllbGRzRGVwcmVjYXRlZCgpOworICAgICAgICBieXRlW10gY29udGVudDsKKyAgICAgICAgYnl0ZVtdIHJlZkNvbnRlbnQ7CisgICAgICAgIE9iamVjdE91dHB1dFN0cmVhbSBvb3MgPSBudWxsOworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvczsKKworICAgICAgICB0b1NlcmlhbGl6ZS5pbml0VGVzdFZhbHVlcygpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWZDb250ZW50ID0gZ2V0UmVmQ29udGVudChERVBSRUNBVEVEX0ZJTEVOQU1FKTsKKworICAgICAgICAgICAgYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0ocmVmQ29udGVudC5sZW5ndGgpOworICAgICAgICAgICAgb29zID0gbmV3IE9iamVjdE91dHB1dFN0cmVhbShiYW9zKTsKKworICAgICAgICAgICAgb29zLndyaXRlT2JqZWN0KHRvU2VyaWFsaXplKTsKKyAgICAgICAgICAgIGNvbnRlbnQgPSBiYW9zLnRvQnl0ZUFycmF5KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTZXJpYWxpemF0aW9uIGlzIG5vdCBlcXVhbCB0byByZWZlcmVuY2UgcGxhdGZvcm0uIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMoY29udGVudCwgcmVmQ29udGVudCkpOworICAgICAgICB9CisgICAgICAgIGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKG9vcyAhPSBudWxsKSBvb3MuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgYnl0ZVtdIGdldFJlZkNvbnRlbnQoU3RyaW5nIHBhdGgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbnQgYnl0ZXNSZWFkOworICAgICAgICBieXRlW10gcmVmQ29udGVudDsKKyAgICAgICAgYnl0ZVtdIHN0cmVhbUNvbnRlbnQgPSBuZXcgYnl0ZVsyMDAwXTsKKyAgICAgICAgSW5wdXRTdHJlYW0gcmVmU3RyZWFtID0gbnVsbDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVmU3RyZWFtID0gZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKHBhdGgpOworICAgICAgICAgICAgYnl0ZXNSZWFkID0gcmVmU3RyZWFtLnJlYWQoc3RyZWFtQ29udGVudCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IGNhc2UgaW1wbGVtZW50YXRpb24gZXJyb3I6IFRoZSBieXRlIGFycmF5IHRvICIgKworICAgICAgICAgICAgICAgICAgICAgICAic3RvcmUgdGhlIHJlZmVyZW5jZSBmaWxlIGlzIHRvbyBzbWFsbC4iLAorICAgICAgICAgICAgICAgICAgICAgICAocmVmU3RyZWFtLnJlYWQoKSA9PSAtMSkpOworICAgICAgICAgICAgcmVmQ29udGVudCA9IG5ldyBieXRlW2J5dGVzUmVhZF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHN0cmVhbUNvbnRlbnQsIDAsIHJlZkNvbnRlbnQsIDAsIGJ5dGVzUmVhZCk7CisgICAgICAgIH0KKyAgICAgICAgZmluYWxseSB7CisgICAgICAgICAgICBpZiAocmVmU3RyZWFtICE9IG51bGwpIHJlZlN0cmVhbS5jbG9zZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZWZDb250ZW50OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkT2JqZWN0T3V0cHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRPYmplY3RPdXRwdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjA1ZGE2OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkT2JqZWN0T3V0cHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDM1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5Ob3RBY3RpdmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0FTaW1wbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X091dHB1dFN0cmVhbTsKKworcHVibGljIGNsYXNzIE9sZE9iamVjdE91dHB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICBqYXZhLmlvLkZpbGUgZjsKKworICAgIHB1YmxpYyBjbGFzcyBTZXJpYWxpemFibGVUZXN0SGVscGVyIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHVibGljIFN0cmluZyBhRmllbGQxOworCisgICAgICAgIHB1YmxpYyBTdHJpbmcgYUZpZWxkMjsKKworICAgICAgICBTZXJpYWxpemFibGVUZXN0SGVscGVyKFN0cmluZyBzLCBTdHJpbmcgdCkgeworICAgICAgICAgICAgYUZpZWxkMSA9IHM7CisgICAgICAgICAgICBhRmllbGQyID0gdDsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIG9pcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIC8vIG5vdGUgYUZpZWxkMiBpcyBub3QgcmVhZAorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBPYmplY3RJbnB1dFN0cmVhbS5HZXRGaWVsZCBmaWVsZHMgPSBvaXMucmVhZEZpZWxkcygpOworICAgICAgICAgICAgICAgIGFGaWVsZDEgPSAoU3RyaW5nKSBmaWVsZHMuZ2V0KCJhRmllbGQxIiwgIlphcCIpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gb29zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgLy8gbm90ZSBhRmllbGQyIGlzIG5vdCB3cml0dGVuCisgICAgICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGQgZmllbGRzID0gb29zLnB1dEZpZWxkcygpOworICAgICAgICAgICAgZmllbGRzLnB1dCgiYUZpZWxkMSIsIGFGaWVsZDEpOworICAgICAgICAgICAgb29zLndyaXRlRmllbGRzKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRleHQxKCkgeworICAgICAgICAgICAgcmV0dXJuIGFGaWVsZDE7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRleHQyKCkgeworICAgICAgICAgICAgcmV0dXJuIGFGaWVsZDI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBCYXNpY09iamVjdE91dHB1dFN0cmVhbSBleHRlbmRzIE9iamVjdE91dHB1dFN0cmVhbSB7CisgICAgICAgIHB1YmxpYyBib29sZWFuIHdyaXRlU3RyZWFtSGVhZGVyQ2FsbGVkOworCisgICAgICAgIHB1YmxpYyBCYXNpY09iamVjdE91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiwgU2VjdXJpdHlFeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgICAgIHdyaXRlU3RyZWFtSGVhZGVyQ2FsbGVkID0gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgQmFzaWNPYmplY3RPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG91dHB1dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyKG91dHB1dCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBkcmFpbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlci5kcmFpbigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZW5hYmxlUmVwbGFjZU9iamVjdChib29sZWFuIGVuYWJsZSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVuYWJsZVJlcGxhY2VPYmplY3QoZW5hYmxlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlT2JqZWN0T3ZlcnJpZGUoT2JqZWN0IG9iamVjdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyLndyaXRlT2JqZWN0T3ZlcnJpZGUob2JqZWN0KTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlU3RyZWFtSGVhZGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyLndyaXRlU3RyZWFtSGVhZGVyKCk7CisgICAgICAgICAgICB3cml0ZVN0cmVhbUhlYWRlckNhbGxlZCA9IHRydWU7CisgICAgICAgIH0KK30KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIE5vRmx1c2hUZXN0T3V0cHV0U3RyZWFtIGV4dGVuZHMgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIHsKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZmx1c2hDYWxsZWQ7CisKKyAgICAgICAgcHVibGljIE5vRmx1c2hUZXN0T3V0cHV0U3RyZWFtKCkgeworICAgICAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgICAgIGZsdXNoQ2FsbGVkID0gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlci5mbHVzaCgpOworICAgICAgICAgICAgZmx1c2hDYWxsZWQgPSB0cnVlOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTU9ERV9YTE9BRCA9ICJ4bG9hZCI7CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBNT0RFX1hEVU1QID0gInhkdW1wIjsKKworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRk9PID0gImZvbyI7CisKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIE1TR19XSVRFX0ZBSUxFRCA9ICJGYWlsZWQgdG8gd3JpdGU6ICI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHID0gZmFsc2U7CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGJvb2xlYW4geGxvYWQgPSBmYWxzZTsKKworICAgIHByb3RlY3RlZCBzdGF0aWMgYm9vbGVhbiB4ZHVtcCA9IGZhbHNlOworCisgICAgcHJvdGVjdGVkIHN0YXRpYyBTdHJpbmcgeEZpbGVOYW1lID0gbnVsbDsKKworICAgIHByb3RlY3RlZCBPYmplY3RJbnB1dFN0cmVhbSBvaXM7CisKKyAgICBwcm90ZWN0ZWQgT2JqZWN0T3V0cHV0U3RyZWFtIG9vczsKKworICAgIHByb3RlY3RlZCBPYmplY3RPdXRwdXRTdHJlYW0gb29zX2lvZTsKKworICAgIHByb3RlY3RlZCBTdXBwb3J0X091dHB1dFN0cmVhbSBzb3M7CisKKyAgICBwcm90ZWN0ZWQgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhbzsKKworICAgIHN0YXRpYyBmaW5hbCBpbnQgSU5JVF9JTlRfVkFMVUUgPSA3OworCisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBJTklUX1NUUl9WQUxVRSA9ICJhIHN0cmluZyB0aGF0IGlzIGJsb3J0eiI7CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbSNPYmplY3RPdXRwdXRTdHJlYW0oamF2YS5pby5PdXRwdXRTdHJlYW0pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX091dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9vcy5jbG9zZSgpOworICAgICAgICBvb3MgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSk7CisgICAgICAgIG9vcy5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvb3MgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKG51bGwpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBTdXBwb3J0X0FTaW1wbGVPdXRwdXRTdHJlYW0gc29zID0gbmV3IFN1cHBvcnRfQVNpbXBsZU91dHB1dFN0cmVhbSh0cnVlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9vcyA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0oc29zKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBvdXRwdXRTaXplID0gYmFvLnNpemUoKTsKKyAgICAgICAgLy8gV3JpdGluZyBvZiBhIHByaW1pdGl2ZSB0eXBlIHNob3VsZCBiZSBidWZmZXJlZC4KKyAgICAgICAgb29zLndyaXRlSW50KDQyKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBQcmltaXRpdmUgZGF0YSB1bmV4cGVjdGVkbHkgd3JpdHRlbiB0byB0aGUgdGFyZ2V0IHN0cmVhbS4iLAorICAgICAgICAgICAgICAgIGJhby5zaXplKCkgPT0gb3V0cHV0U2l6ZSk7CisgICAgICAgIC8vIENsb3Npbmcgc2hvdWxkIHdyaXRlIHRoZSBidWZmZXJlZCBkYXRhIHRvIHRoZSB0YXJnZXQgc3RyZWFtLgorICAgICAgICBvb3MuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAyOiBQcmltaXRpdmUgZGF0YSBoYXMgbm90IGJlZW4gd3JpdHRlbiB0byB0aGUgdGhlIHRhcmdldCBzdHJlYW0uIiwKKyAgICAgICAgICAgICAgICBiYW8uc2l6ZSgpID4gb3V0cHV0U2l6ZSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9vc19pb2UuY2xvc2UoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9kcmFpbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIE5vRmx1c2hUZXN0T3V0cHV0U3RyZWFtIHRhcmdldCA9IG5ldyBOb0ZsdXNoVGVzdE91dHB1dFN0cmVhbSgpOworICAgICAgICBCYXNpY09iamVjdE91dHB1dFN0cmVhbSBib29zID0gbmV3IEJhc2ljT2JqZWN0T3V0cHV0U3RyZWFtKHRhcmdldCk7CisgICAgICAgIGludCBpbml0aWFsU2l6ZSA9IHRhcmdldC5zaXplKCk7CisgICAgICAgIGJvb2xlYW4gd3JpdHRlbiA9IGZhbHNlOworCisgICAgICAgIGJvb3Mud3JpdGVCeXRlcygiTG9yZW0gaXBzdW0iKTsKKyAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gYnVmZmVyIHRoZW4gdGhlIGJ5dGVzIGhhdmUgYWxyZWFkeSBiZWVuIHdyaXR0ZW4uCisgICAgICAgIHdyaXR0ZW4gPSAodGFyZ2V0LnNpemUoKSA+IGluaXRpYWxTaXplKTsKKworICAgICAgICBib29zLmRyYWluKCk7CisgICAgICAgIGFzc2VydFRydWUoIkNvbnRlbnQgaGFzIG5vdCBiZWVuIHdyaXR0ZW4gdG8gdGhlIHRhcmdldC4iLAorICAgICAgICAgICAgICAgIHdyaXR0ZW4gfHwgKHRhcmdldC5zaXplKCkgPiBpbml0aWFsU2l6ZSkpOworICAgICAgICBhc3NlcnRGYWxzZSgiZmx1c2goKSBoYXMgYmVlbiBjYWxsZWQgb24gdGhlIHRhcmdldC4iLAorICAgICAgICAgICAgICAgIHRhcmdldC5mbHVzaENhbGxlZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9lbmFibGVSZXBsYWNlT2JqZWN0QigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFN0YXJ0IHRlc3Rpbmcgd2l0aG91dCBhIFNlY3VyaXR5TWFuYWdlci4KKyAgICAgICAgQmFzaWNPYmplY3RPdXRwdXRTdHJlYW0gYm9vcyA9IG5ldyBCYXNpY09iamVjdE91dHB1dFN0cmVhbSgpOworICAgICAgICBhc3NlcnRGYWxzZSgiVGVzdCAxOiBPYmplY3QgcmVzb2x2aW5nIG11c3QgYmUgZGlzYWJsZWQgYnkgZGVmYXVsdC4iLAorICAgICAgICAgICAgICAgIGJvb3MuZW5hYmxlUmVwbGFjZU9iamVjdCh0cnVlKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAyOiBlbmFibGVSZXBsYWNlT2JqZWN0IGRpZCBub3QgcmV0dXJuIHRoZSBwcmV2aW91cyB2YWx1ZS4iLAorICAgICAgICAgICAgICAgIGJvb3MuZW5hYmxlUmVwbGFjZU9iamVjdChmYWxzZSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmx1c2goKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW0uZmx1c2goKQorICAgICAgICBpbnQgc2l6ZSA9IGJhby5zaXplKCk7CisgICAgICAgIG9vcy53cml0ZUJ5dGUoMTI3KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBEYXRhIGFscmVhZHkgZmx1c2hlZC4iLCBiYW8uc2l6ZSgpID09IHNpemUpOworICAgICAgICBvb3MuZmx1c2goKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAyOiBGYWlsZWQgdG8gZmx1c2ggZGF0YS4iLCBiYW8uc2l6ZSgpID4gc2l6ZSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9vc19pb2UuZmx1c2goKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9wdXRGaWVsZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogIlNlcmlhbGl6YWJsZVRlc3RIZWxwZXIiIGlzIGFuIG9iamVjdCBjcmVhdGVkIGZvciB0aGVzZSB0ZXN0cyB3aXRoCisgICAgICAgICAqIHR3byBmaWVsZHMgKFN0cmluZ3MpIGFuZCBzaW1wbGUgaW1wbGVtZW50YXRpb25zIG9mIHJlYWRPYmplY3QgYW5kCisgICAgICAgICAqIHdyaXRlT2JqZWN0IHdoaWNoIHNpbXBseSByZWFkIGFuZCB3cml0ZSB0aGUgZmlyc3QgZmllbGQgYnV0IG5vdCB0aGUKKyAgICAgICAgICogc2Vjb25kIG9uZS4KKyAgICAgICAgICovCisgICAgICAgIFNlcmlhbGl6YWJsZVRlc3RIZWxwZXIgc3RoOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvb3MucHV0RmllbGRzKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IE5vdEFjdGl2ZUV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTm90QWN0aXZlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgb29zLndyaXRlT2JqZWN0KG5ldyBTZXJpYWxpemFibGVUZXN0SGVscGVyKCJHYWJiYSIsICJKYWJiYSIpKTsKKyAgICAgICAgb29zLmZsdXNoKCk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgc3RoID0gKFNlcmlhbGl6YWJsZVRlc3RIZWxwZXIpIChvaXMucmVhZE9iamVjdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IHJlYWRGaWVsZHMgb3Igd3JpdGVGaWVsZHMgZmFpbGVkOyBmaXJzdCBmaWVsZCBub3Qgc2V0LiIsCisgICAgICAgICAgICAgICAgIkdhYmJhIiwgc3RoLmdldFRleHQxKCkpOworICAgICAgICBhc3NlcnROdWxsKCJUZXN0IDM6IHJlYWRGaWVsZHMgb3Igd3JpdGVGaWVsZHMgZmFpbGVkOyBzZWNvbmQgZmllbGQgc2hvdWxkIG5vdCBoYXZlIGJlZW4gc2V0LiIsCisgICAgICAgICAgICAgICAgc3RoLmdldFRleHQyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVzZXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIG8gPSAiSGVsbG9Xb3JsZCI7CisgICAgICAgIHNvcyA9IG5ldyBTdXBwb3J0X091dHB1dFN0cmVhbSgyMDApOworICAgICAgICBvb3MuY2xvc2UoKTsKKyAgICAgICAgb29zID0gbmV3IE9iamVjdE91dHB1dFN0cmVhbShzb3MpOworICAgICAgICBvb3Mud3JpdGVPYmplY3Qobyk7CisgICAgICAgIG9vcy53cml0ZU9iamVjdChvKTsKKyAgICAgICAgb29zLnJlc2V0KCk7CisgICAgICAgIG9vcy53cml0ZU9iamVjdChvKTsKKworICAgICAgICBzb3Muc2V0VGhyb3dzRXhjZXB0aW9uKHRydWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb29zLnJlc2V0KCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICBzb3Muc2V0VGhyb3dzRXhjZXB0aW9uKGZhbHNlKTsKKworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHNvcy50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBJbmNvcnJlY3Qgb2JqZWN0IHJlYWQuIiwgbywgb2lzLnJlYWRPYmplY3QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAzOiBJbmNvcnJlY3Qgb2JqZWN0IHJlYWQuIiwgbywgb2lzLnJlYWRPYmplY3QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCA0OiBJbmNvcnJlY3Qgb2JqZWN0IHJlYWQuIiwgbywgb2lzLnJlYWRPYmplY3QoKSk7CisgICAgICAgIG9pcy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGUkQklJKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9pcy5yZWFkKGJ1ZiwgMCwgLTEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgb2lzLnJlYWQoYnVmLCAtMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvaXMucmVhZChidWYsIDEwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgb2lzLmNsb3NlKCk7CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlT2JqZWN0T3ZlcnJpZGVMamF2YV9sYW5nX09iamVjdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJhc2ljT2JqZWN0T3V0cHV0U3RyZWFtIGJvb3MgPQorICAgICAgICAgICAgICAgIG5ldyBCYXNpY09iamVjdE91dHB1dFN0cmVhbShuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBib29zLndyaXRlT2JqZWN0T3ZlcnJpZGUobmV3IE9iamVjdCgpKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9CisgICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZmluYWxseSB7CisgICAgICAgICAgICBib29zLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlU3RyZWFtSGVhZGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQmFzaWNPYmplY3RPdXRwdXRTdHJlYW0gYm9vczsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIHNob3J0IHM7CisgICAgICAgIGJ5dGVbXSBidWZmZXI7CisKKyAgICAgICAgLy8gVGVzdCAxOiBNYWtlIHN1cmUgdGhhdCB3cml0ZVN0cmVhbUhlYWRlcigpIGhhcyBiZWVuIGNhbGxlZC4KKyAgICAgICAgYm9vcyA9IG5ldyBCYXNpY09iamVjdE91dHB1dFN0cmVhbShiYW9zKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogd3JpdGVTdHJlYW1IZWFkZXIoKSBoYXMgbm90IGJlZW4gY2FsbGVkLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgYm9vcy53cml0ZVN0cmVhbUhlYWRlckNhbGxlZCk7CisKKyAgICAgICAgICAgIC8vIFRlc3QgMjogQ2hlY2sgdGhhdCBhdCBsZWFzdCBmb3VyIGJ5dGVzIGhhdmUgYmVlbiB3cml0dGVuLgorICAgICAgICAgICAgYnVmZmVyID0gYmFvcy50b0J5dGVBcnJheSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAyOiBBdCBsZWFzdCBmb3VyIGJ5dGVzIHNob3VsZCBoYXZlIGJlZW4gd3JpdHRlbiIsCisgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIubGVuZ3RoID49IDQpOworCisgICAgICAgICAgICAvLyBUZXN0IDM6IENoZWNrIHRoZSBtYWdpYyBudW1iZXIuCisgICAgICAgICAgICBzID0gYnVmZmVyWzBdOworICAgICAgICAgICAgcyA8PD0gODsKKyAgICAgICAgICAgIHMgKz0gKChzaG9ydCkgYnVmZmVyWzFdICYgMHgwMGZmKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAzOiBJbnZhbGlkIG1hZ2ljIG51bWJlciB3cml0dGVuLiIsCisgICAgICAgICAgICAgICAgICAgICAgICBqYXZhLmlvLk9iamVjdFN0cmVhbUNvbnN0YW50cy5TVFJFQU1fTUFHSUMsIHMpOworCisgICAgICAgICAgICAvLyBUZXN0IDQ6IENoZWNrIHRoZSBzdHJlYW0gdmVyc2lvbiBudW1iZXIuCisgICAgICAgICAgICBzID0gYnVmZmVyWzJdOworICAgICAgICAgICAgcyA8PD0gODsKKyAgICAgICAgICAgIHMgKz0gKChzaG9ydCkgYnVmZmVyWzNdICYgMHgwMGZmKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW52YWxpZCBzdHJlYW0gdmVyc2lvbiBudW1iZXIgd3JpdHRlbi4iLAorICAgICAgICAgICAgICAgICAgICAgICAgamF2YS5pby5PYmplY3RTdHJlYW1Db25zdGFudHMuU1RSRUFNX1ZFUlNJT04sIHMpOworICAgICAgICB9CisgICAgICAgIGZpbmFsbHkgeworICAgICAgICAgICAgYm9vcy5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgb29zID0gbmV3IE9iamVjdE91dHB1dFN0cmVhbShiYW8gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCkpOworICAgICAgICBvb3NfaW9lID0gbmV3IE9iamVjdE91dHB1dFN0cmVhbShzb3MgPSBuZXcgU3VwcG9ydF9PdXRwdXRTdHJlYW0oKSk7CisgICAgICAgIHNvcy5zZXRUaHJvd3NFeGNlcHRpb24odHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVhcnMgZG93biB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIGNsb3NlIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzCisgICAgICogbWV0aG9kIGlzIGNhbGxlZCBhZnRlciBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICAgICAgaWYgKG9vcyAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG9vcy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHt9CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9vc19pb2UgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBvb3NfaW9lLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkge30KKyAgICAgICAgfQorICAgICAgICBpZiAoZiAhPSBudWxsICYmIGYuZXhpc3RzKCkpIHsKKyAgICAgICAgICAgIGlmICghZi5kZWxldGUoKSkgeworICAgICAgICAgICAgICAgIGZhaWwoIkVycm9yIGNsZWFuaW5nIHVwIGZpbGVzIGR1cmluZyB0ZWFyZG93biIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIE9iamVjdCByZWxvYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworCisgICAgICAgIC8vIENob29zZSB0aGUgbG9hZCBzdHJlYW0KKyAgICAgICAgaWYgKHhsb2FkIHx8IHhkdW1wKSB7CisgICAgICAgICAgICAvLyBMb2FkIGZyb20gcHJlLWV4aXN0aW5nIGZpbGUKKyAgICAgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKHhGaWxlTmFtZSArICItIgorICAgICAgICAgICAgICAgICAgICArIGdldE5hbWUoKSArICIuc2VyIikpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gSnVzdCBsb2FkIGZyb20gbWVtb3J5LCB3ZSBkdW1wZWQgdG8gbWVtb3J5CisgICAgICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhbworICAgICAgICAgICAgICAgICAgICAudG9CeXRlQXJyYXkoKSkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBvaXMucmVhZE9iamVjdCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgb2lzLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBkdW1wKE9iamVjdCBvKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworCisgICAgICAgIC8vIENob29zZSB0aGUgZHVtcCBzdHJlYW0KKyAgICAgICAgaWYgKHhkdW1wKSB7CisgICAgICAgICAgICBvb3MgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKAorICAgICAgICAgICAgICAgICAgICBmID0gbmV3IGphdmEuaW8uRmlsZSh4RmlsZU5hbWUgKyAiLSIgKyBnZXROYW1lKCkgKyAiLnNlciIpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBvb3MgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKGJhbyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBEdW1wIHRoZSBvYmplY3QKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9vcy53cml0ZU9iamVjdChvKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG9vcy5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRPYmplY3RTdHJlYW1GaWVsZFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkT2JqZWN0U3RyZWFtRmllbGRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWUwOTIyMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkT2JqZWN0U3RyZWFtRmllbGRUZXN0LmphdmEKQEAgLTAsMCArMSwxNzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1DbGFzczsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUZpZWxkOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCitwdWJsaWMgY2xhc3MgT2xkT2JqZWN0U3RyZWFtRmllbGRUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBjbGFzcyBEdW1teUNsYXNzIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gOTk5OTk5OTk5OTk5OTk4TDsKKworICAgICAgICBib29sZWFuIGJGaWVsZCA9IHRydWU7CisgICAgICAgIGNoYXIgY0ZpZWxkID0gJ2MnOworICAgICAgICBkb3VibGUgZEZpZWxkID0gNDI0MjQyLjQyNDI7CisgICAgICAgIGZsb2F0IGZGaWVsZCA9IDI0LjEyRjsKKyAgICAgICAgaW50IGlGaWVsZCA9IDE5NjU7CisgICAgICAgIGxvbmcgbEZpZWxkID0gOTk5OTk5OUw7CisgICAgICAgIHNob3J0IHNGaWVsZCA9IDQyOworCisgICAgICAgIGxvbmcgYmFtID0gOTk5TDsKKworICAgICAgICBpbnQgaGFtID0gOTk5OTsKKworICAgICAgICBpbnQgc2FtID0gODg4ODsKKworICAgICAgICBPYmplY3QgaG9sYSA9IG5ldyBPYmplY3QoKTsKKworICAgICAgICBwdWJsaWMgc3RhdGljIGxvbmcgZ2V0VUlEKCkgeworICAgICAgICAgICAgcmV0dXJuIHNlcmlhbFZlcnNpb25VSUQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBNeU9iamVjdFN0cmVhbUZpZWxkIGV4dGVuZHMgT2JqZWN0U3RyZWFtRmllbGQgeworICAgICAgICBwdWJsaWMgTXlPYmplY3RTdHJlYW1GaWVsZChTdHJpbmcgbmFtZSwgQ2xhc3M8Pz4gY2wpIHsKKyAgICAgICAgICAgIHN1cGVyKG5hbWUsIGNsKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldE9mZnNldChpbnQgbmV3VmFsdWUpIHsKKyAgICAgICAgICAgIHN1cGVyLnNldE9mZnNldChuZXdWYWx1ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBPYmplY3RTdHJlYW1DbGFzcyBvc2M7CisKKyAgICBPYmplY3RTdHJlYW1GaWVsZCBoYW1GaWVsZDsKKworICAgIE9iamVjdFN0cmVhbUZpZWxkIHNhbUZpZWxkOworCisgICAgT2JqZWN0U3RyZWFtRmllbGQgYmFtRmllbGQ7CisKKyAgICBPYmplY3RTdHJlYW1GaWVsZCBob2xhRmllbGQ7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX0NsYXNzKCkgeworICAgICAgICBPYmplY3RTdHJlYW1GaWVsZCBvc2YgPSBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImFGaWVsZCIsIGludC5jbGFzcyk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogTmFtZSBtZW1iZXIgbm90IHNldCBjb3JyZWN0bHkuIiwKKyAgICAgICAgICAgICAgICAgICBvc2YuZ2V0TmFtZSgpLmVxdWFscygiYUZpZWxkIikpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDI6IFR5cGUgbWVtYmVyIG5vdCBzZXQgY29ycmVjdGx5LiIsCisgICAgICAgICAgICAgICAgICAgb3NmLmdldFR5cGUoKS5lcXVhbHMoaW50LmNsYXNzKSk7CisKKyAgICAgICAgLy8gUmVwZWF0IHRoZSB0ZXN0cyB3aXRoIGEgZGlmZmVyZW50IG9iamVjdCB0byBtYWtlIHN1cmUKKyAgICAgICAgLy8gdGhhdCB3ZSBoYXZlIG5vdCB0ZXN0ZWQgYWdhaW5zdCBkZWZhdWx0IHZhbHVlcy4KKyAgICAgICAgb3NmID0gbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJhbm90aGVyRmllbGQiLCBTdHJpbmcuY2xhc3MpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDM6IE5hbWUgbWVtYmVyIG5vdCBzZXQgY29ycmVjdGx5LiIsCisgICAgICAgICAgICAgICAgICAgb3NmLmdldE5hbWUoKS5lcXVhbHMoImFub3RoZXJGaWVsZCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCA0OiBUeXBlIG1lbWJlciBub3Qgc2V0IGNvcnJlY3RseS4iLAorICAgICAgICAgICAgICAgICAgIG9zZi5nZXRUeXBlKCkuZXF1YWxzKFN0cmluZy5jbGFzcykpOworCisgICAgICAgIC8vIEludmFsaWQgYXJndW1lbnQgdGVzdHMuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvc2YgPSBuZXcgT2JqZWN0U3RyZWFtRmllbGQobnVsbCwgYm9vbGVhbi5jbGFzcyk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgb3NmID0gbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJ0aGlzRmllbGQiLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNjogTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19DbGFzc0IoKSB7CisgICAgICAgIE9iamVjdFN0cmVhbUZpZWxkIG9zZiA9IG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiYUZpZWxkIiwgaW50LmNsYXNzLCBmYWxzZSk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogTmFtZSBtZW1iZXIgbm90IHNldCBjb3JyZWN0bHkuIiwKKyAgICAgICAgICAgICAgICAgICBvc2YuZ2V0TmFtZSgpLmVxdWFscygiYUZpZWxkIikpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDI6IFR5cGUgbWVtYmVyIG5vdCBzZXQgY29ycmVjdGx5LiIsCisgICAgICAgICAgICAgICAgICAgb3NmLmdldFR5cGUoKS5lcXVhbHMoaW50LmNsYXNzKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUZXN0IDM6IFVuc2hhcmVkIG1lbWJlciBub3Qgc2V0IGNvcnJlY3RseS4iLAorICAgICAgICAgICAgICAgICAgICBvc2YuaXNVbnNoYXJlZCgpKTsKKworICAgICAgICAvLyBSZXBlYXQgdGhlIHRlc3RzIHdpdGggYSBkaWZmZXJlbnQgb2JqZWN0IHRvIG1ha2Ugc3VyZQorICAgICAgICAvLyB0aGF0IHdlIGhhdmUgbm90IHRlc3RlZCBhZ2FpbnN0IGRlZmF1bHQgdmFsdWVzLgorICAgICAgICBvc2YgPSBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImFub3RoZXJGaWVsZCIsIFN0cmluZy5jbGFzcywgdHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgNDogTmFtZSBtZW1iZXIgbm90IHNldCBjb3JyZWN0bHkuIiwKKyAgICAgICAgICAgICAgICAgICBvc2YuZ2V0TmFtZSgpLmVxdWFscygiYW5vdGhlckZpZWxkIikpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDU6IFR5cGUgbWVtYmVyIG5vdCBzZXQgY29ycmVjdGx5LiIsCisgICAgICAgICAgICAgICAgICAgb3NmLmdldFR5cGUoKS5lcXVhbHMoU3RyaW5nLmNsYXNzKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgNjogVW5zaGFyZWQgbWVtYmVyIG5vdCBzZXQgY29ycmVjdGx5LiIsCisgICAgICAgICAgICAgICAgICAgb3NmLmlzVW5zaGFyZWQoKSk7CisKKyAgICAgICAgLy8gSW52YWxpZCBhcmd1bWVudCB0ZXN0cy4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9zZiA9IG5ldyBPYmplY3RTdHJlYW1GaWVsZChudWxsLCBib29sZWFuLmNsYXNzKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNzogTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvc2YgPSBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInRoaXNGaWVsZCIsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA4OiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0T2Zmc2V0KCkgeworICAgICAgICBPYmplY3RTdHJlYW1GaWVsZFtdIG9zZkFycmF5OworICAgICAgICBvc2ZBcnJheSA9IG9zYy5nZXRGaWVsZHMoKTsKKyAgICAgICAgaW50W10gZXhwZWN0ZWRPZmZzZXRzID0gezAsIDEsIDksIDExLCAxOSwgMjMsIDI3LCAzMSwgMzksIDQxLCAwfTsKKworICAgICAgICBhc3NlcnRUcnVlKCJnZXRPZmZzZXQoKSBkaWQgbm90IHJldHVybiByZWFzb25hYmxlIHZhbHVlcy4iLCBvc2ZBcnJheVswXQorICAgICAgICAgICAgICAgIC5nZXRPZmZzZXQoKSAhPSBvc2ZBcnJheVsxXS5nZXRPZmZzZXQoKSk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHBlY3RlZE9mZnNldHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhTdHJpbmcuZm9ybWF0KCJVbmV4cGVjdGVkIHZhbHVlIGZvciBvc2ZBcnJheVslZF0uZ2V0T2Zmc2V0KCk6ICIsIGkpLAorICAgICAgICAgICAgICAgICAgICBleHBlY3RlZE9mZnNldHNbaV0sIG9zZkFycmF5W2ldLmdldE9mZnNldCgpKTsKKworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRPZmZzZXRJKCkgeworICAgICAgICBNeU9iamVjdFN0cmVhbUZpZWxkIGYgPSBuZXcgTXlPYmplY3RTdHJlYW1GaWVsZCgiYUZpZWxkIiwgaW50LmNsYXNzKTsKKyAgICAgICAgZi5zZXRPZmZzZXQoNDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogVW5leHBlY3RlZCBvZmZzZXQgdmFsdWUuIiwgNDIsIGYuZ2V0T2Zmc2V0KCkpOworICAgICAgICBmLnNldE9mZnNldCgyMDA4KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IFVuZXhwZWN0ZWQgb2Zmc2V0IHZhbHVlLiIsIDIwMDgsIGYuZ2V0T2Zmc2V0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNQcmltaXRpdmUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS5pby5PYmplY3RTdHJlYW1GaWVsZC5nZXRPZmZzZXQoKQorICAgICAgICBPYmplY3RTdHJlYW1GaWVsZFtdIG9zZkFycmF5OworICAgICAgICBvc2ZBcnJheSA9IG9zYy5nZXRGaWVsZHMoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IChvc2ZBcnJheS5sZW5ndGggLSAxKTsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKFN0cmluZy5mb3JtYXQoIm9zZkFycmF5WyVkXS5pc1ByaW1pdGl2ZSgpIHNob3VsZCByZXR1cm4gdHJ1ZS4iLCBpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgb3NmQXJyYXlbaV0uaXNQcmltaXRpdmUoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoU3RyaW5nLmZvcm1hdCgib3NmQXJyYXlbJWRdLmlzUHJpbWl0aXZlKCkgc2hvdWxkIHJldHVybiBmYWxzZS4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9zZkFycmF5Lmxlbmd0aCAtIDEpLAorICAgICAgICAgICAgICAgICAgICBvc2ZBcnJheVsob3NmQXJyYXkubGVuZ3RoIC0gMSldLmlzUHJpbWl0aXZlKCkpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICBvc2MgPSBPYmplY3RTdHJlYW1DbGFzcy5sb29rdXAoRHVtbXlDbGFzcy5jbGFzcyk7CisgICAgICAgIGJhbUZpZWxkID0gb3NjLmdldEZpZWxkKCJiYW0iKTsKKyAgICAgICAgc2FtRmllbGQgPSBvc2MuZ2V0RmllbGQoInNhbSIpOworICAgICAgICBoYW1GaWVsZCA9IG9zYy5nZXRGaWVsZCgiaGFtIik7CisgICAgICAgIGhvbGFGaWVsZCA9IG9zYy5nZXRGaWVsZCgiaG9sYSIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkT3V0cHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRPdXRwdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTg1NjEyYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkT3V0cHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTI5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKK3B1YmxpYyBjbGFzcyBPbGRPdXRwdXRTdHJlYW1UZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIGNsYXNzIEJhc2ljT3V0cHV0U3RyZWFtIGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQlVGRkVSX1NJWkUgPSAyMDsKKyAgICAgICAgcHJpdmF0ZSBieXRlW10gYnVmZmVyOworICAgICAgICBwcml2YXRlIGludCBwb3NpdGlvbjsKKworICAgICAgICBwdWJsaWMgQmFzaWNPdXRwdXRTdHJlYW0oKSB7CisgICAgICAgICAgICBidWZmZXIgPSBuZXcgYnl0ZVtCVUZGRVJfU0laRV07CisgICAgICAgICAgICBwb3NpdGlvbiA9IDA7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgb25lQnl0ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChwb3NpdGlvbiA8IEJVRkZFUl9TSVpFKSB7CisgICAgICAgICAgICAgICAgYnVmZmVyW3Bvc2l0aW9uXSA9IChieXRlKSAob25lQnl0ZSAmIDI1NSk7CisgICAgICAgICAgICAgICAgcG9zaXRpb24rKzsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbnRlcm5hbCBidWZmZXIgb3ZlcmZsb3cuIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEJ1ZmZlcigpIHsKKyAgICAgICAgICAgIHJldHVybiBidWZmZXI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBzaG9ydEJ5dGVBcnJheSA9ICJMb3JlbSBpcHN1bS4uLiIuZ2V0Qnl0ZXMoKTsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBsb25nQnl0ZUFycmF5ID0gIkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0Li4uIi5nZXRCeXRlcygpOworCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZSRCKCkgeworICAgICAgICBCYXNpY091dHB1dFN0cmVhbSBib3MgPSBuZXcgQmFzaWNPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgYm9vbGVhbiBleHBlY3RlZDsKKyAgICAgICAgYnl0ZVtdIGJ1ZmZlcjsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYm9zLndyaXRlKHNob3J0Qnl0ZUFycmF5KTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBVbmV4cGVjdGVkIElPRXhjZXB0aW9uIGVuY291bnRlcmVkLiIpOworICAgICAgICB9CisKKyAgICAgICAgZXhwZWN0ZWQgPSB0cnVlOworICAgICAgICBidWZmZXIgPSBib3MuZ2V0QnVmZmVyKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgKHNob3J0Qnl0ZUFycmF5Lmxlbmd0aCkgJiYgZXhwZWN0ZWQ7IGkrKykgeworICAgICAgICAgICAgZXhwZWN0ZWQgPSAoc2hvcnRCeXRlQXJyYXlbaV0gPT0gYnVmZmVyW2ldKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IFRlc3QgYnl0ZSBhcnJheSBoYXMgbm90IGJlZW4gd3JpdHRlbiBjb3JyZWN0bHkuIiwKKyAgICAgICAgICAgICAgICAgICBleHBlY3RlZCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJvcy53cml0ZShsb25nQnl0ZUFycmF5KTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHt9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZSRCSUkoKSB7CisgICAgICAgIEJhc2ljT3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCYXNpY091dHB1dFN0cmVhbSgpOworICAgICAgICBib29sZWFuIGV4cGVjdGVkOworICAgICAgICBieXRlW10gYnVmZmVyOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBib3Mud3JpdGUoc2hvcnRCeXRlQXJyYXksIDYsIDUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IFVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gZW5jb3VudGVyZWQuIik7CisgICAgICAgIH0KKworICAgICAgICBleHBlY3RlZCA9IHRydWU7CisgICAgICAgIGJ1ZmZlciA9IGJvcy5nZXRCdWZmZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDYsIGogPSAwOyBqIDwgNSAmJiBleHBlY3RlZDsgaSsrLCBqKyspIHsKKyAgICAgICAgICAgIGV4cGVjdGVkID0gKHNob3J0Qnl0ZUFycmF5W2ldID09IGJ1ZmZlcltqXSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBUZXN0IGJ5dGUgYXJyYXkgaGFzIG5vdCBiZWVuIHdyaXR0ZW4gY29ycmVjdGx5LiIsCisgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBib3Mud3JpdGUobG9uZ0J5dGVBcnJheSwgNSwgMjApOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkge30KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYm9zLndyaXRlKGxvbmdCeXRlQXJyYXksIC0xLCAxMCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBVbmV4cGVjdGVkIElPRXhjZXB0aW9uIGVuY291bnRlcmVkLiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJvcy53cml0ZShsb25nQnl0ZUFycmF5LCAxMCwgLTEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiBlbmNvdW50ZXJlZC4iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBib3Mud3JpdGUobG9uZ0J5dGVBcnJheSwgMjAsIDEwKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNTogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IFVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gZW5jb3VudGVyZWQuIik7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZE91dHB1dFN0cmVhbVdyaXRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkT3V0cHV0U3RyZWFtV3JpdGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjNTE1NTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZE91dHB1dFN0cmVhbVdyaXRlclRlc3QuamF2YQpAQCAtMCwwICsxLDU4OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldEVuY29kZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9PdXRwdXRTdHJlYW07CisKK3B1YmxpYyBjbGFzcyBPbGRPdXRwdXRTdHJlYW1Xcml0ZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgT3V0cHV0U3RyZWFtV3JpdGVyIG9zdzsKKyAgICBJbnB1dFN0cmVhbVJlYWRlciBpc3I7CisKKyAgICBwcml2YXRlIFN1cHBvcnRfT3V0cHV0U3RyZWFtIGZvczsKKworICAgIHB1YmxpYyBTdHJpbmcgdGVzdFN0cmluZyA9ICJUaGlzIGlzIGEgdGVzdCBtZXNzYWdlIHdpdGggVW5pY29kZSBjaGFyYWN0ZXJzLiBcdTRlMmRcdTU2ZmQgaXMgQ2hpbmEncyBuYW1lIGluIENoaW5lc2UiOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgZm9zID0gbmV3IFN1cHBvcnRfT3V0cHV0U3RyZWFtKDUwMCk7CisgICAgICAgIG9zdyA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoZm9zLCAiVVRGLTgiKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGlzciAhPSBudWxsKSBpc3IuY2xvc2UoKTsKKyAgICAgICAgICAgIG9zdy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fT3V0cHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgT3V0cHV0U3RyZWFtV3JpdGVyIHdyaXRlciA9IG51bGw7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlciA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlciA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIobmV3IFN1cHBvcnRfT3V0cHV0U3RyZWFtKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3QgdGhhdCB0aGUgZGVmYXVsdCBlbmNvZGluZyBoYXMgYmVlbiB1c2VkLgorICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMzogSW5jb3JyZWN0IGRlZmF1bHQgZW5jb2RpbmcgdXNlZC4iLAorICAgICAgICAgICAgICAgICAgICAgQ2hhcnNldC5kZWZhdWx0Q2hhcnNldCgpLAorICAgICAgICAgICAgICAgICAgICAgQ2hhcnNldC5mb3JOYW1lKHdyaXRlci5nZXRFbmNvZGluZygpKSk7CisKKyAgICAgICAgaWYgKHdyaXRlciAhPSBudWxsKSB3cml0ZXIuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fT3V0cHV0U3RyZWFtTGphdmFfbGFuZ19TdHJpbmcoKQorICAgICAgICAgICAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvc3cgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG51bGwsICJ1dGYtOCIpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvc3cgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKGZvcywgKFN0cmluZykgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9zdyA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoZm9zLCAiIik7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvc3cgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKGZvcywgIkJvZ3VzIik7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvc3cgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKGZvcywgIjg4NTlfMSIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNTogVW5leHBlY3RlZCBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uLiIpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDY6IEVuY29kaW5nIG5vdCBzZXQgY29ycmVjdGx5LiAiLAorICAgICAgICAgICAgICAgIENoYXJzZXQuZm9yTmFtZSgiODg1OV8xIiksCisgICAgICAgICAgICAgICAgQ2hhcnNldC5mb3JOYW1lKG9zdy5nZXRFbmNvZGluZygpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX091dHB1dFN0cmVhbUxqYXZhX25pb19jaGFyc2V0X0NoYXJzZXQoKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgT3V0cHV0U3RyZWFtV3JpdGVyIHdyaXRlcjsKKyAgICAgICAgU3VwcG9ydF9PdXRwdXRTdHJlYW0gb3V0ID0gbmV3IFN1cHBvcnRfT3V0cHV0U3RyZWFtKCk7CisgICAgICAgIENoYXJzZXQgY3MgPSBDaGFyc2V0LmZvck5hbWUoImFzY2lpIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlciA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIobnVsbCwgY3MpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZXIgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG91dCwgKENoYXJzZXQpIG51bGwpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHdyaXRlciA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIob3V0LCBjcyk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAzOiBFbmNvZGluZyBub3Qgc2V0IGNvcnJlY3RseS4gIiwKKyAgICAgICAgICAgICAgICAgICAgIGNzLCBDaGFyc2V0LmZvck5hbWUod3JpdGVyLmdldEVuY29kaW5nKCkpKTsKKyAgICAgICAgd3JpdGVyLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX091dHB1dFN0cmVhbUxqYXZhX25pb19jaGFyc2V0X0NoYXJzZXRFbmNvZGVyKCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIE91dHB1dFN0cmVhbVdyaXRlciB3cml0ZXI7CisgICAgICAgIFN1cHBvcnRfT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBTdXBwb3J0X091dHB1dFN0cmVhbSgpOworICAgICAgICBDaGFyc2V0IGNzID0gQ2hhcnNldC5mb3JOYW1lKCJhc2NpaSIpOworICAgICAgICBDaGFyc2V0RW5jb2RlciBlbmMgPSBjcy5uZXdFbmNvZGVyKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlciA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIobnVsbCwgZW5jKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVyID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihvdXQsIChDaGFyc2V0RW5jb2RlcikgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgd3JpdGVyID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihvdXQsIGNzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDM6IENoYXJhY3RlckVuY29kZXIgbm90IHNldCBjb3JyZWN0bHkuICIsCisgICAgICAgICAgICAgICAgICAgICBjcywgQ2hhcnNldC5mb3JOYW1lKHdyaXRlci5nZXRFbmNvZGluZygpKSk7CisgICAgICAgIHdyaXRlci5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvc2UoKSB7CisKKyAgICAgICAgZm9zLnNldFRocm93c0V4Y2VwdGlvbih0cnVlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9zdy5jbG9zZSgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworLyogVGVzdCAyIGRvZXMgbm90IHdvcmsgYW5kIGhhcyB0aGVyZWZvcmUgYmVlbiBkaXNhYmxlZCAoc2VlIFRpY2tldCAjODcpLgorICAgICAgICAvLyBUZXN0IDI6IFdyaXRlIHNob3VsZCBub3QgZmFpbCBzaW5jZSB0aGUgY2xvc2luZworICAgICAgICAvLyBpbiB0ZXN0IDEgaGFzIG5vdCBiZWVuIHN1Y2Nlc3NmdWwuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvc3cud3JpdGUoIkxvcmVtIGlwc3VtLi4uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogVW5leHBlY3RlZCBJT0V4Y2VwdGlvbi4iKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3QgMzogQ2xvc2Ugc2hvdWxkIHN1Y2NlZWQuCisgICAgICAgIGZvcy5zZXRUaHJvd3NFeGNlcHRpb24oZmFsc2UpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3N3LmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogVW5leHBlY3RlZCBJT0V4Y2VwdGlvbi4iKTsKKyAgICAgICAgfQorKi8KKworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE91dHB1dFN0cmVhbVdyaXRlciB3cml0ZXIgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKGJvdXQsCisgICAgICAgICAgICAgICAgICAgICJJU08yMDIySlAiKTsKKyAgICAgICAgICAgIHdyaXRlci53cml0ZShuZXcgY2hhcltdIHsgJ2EnIH0pOworICAgICAgICAgICAgd3JpdGVyLmNsb3NlKCk7CisgICAgICAgICAgICAvLyBUaGUgZGVmYXVsdCBpcyBBU0NJSSwgdGhlcmUgc2hvdWxkIG5vdCBiZSBhbnkgbW9kZSBjaGFuZ2VzLgorICAgICAgICAgICAgU3RyaW5nIGNvbnZlcnRlZCA9IG5ldyBTdHJpbmcoYm91dC50b0J5dGVBcnJheSgpLCAiSVNPODg1OV8xIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDQ6IEludmFsaWQgY29udmVyc2lvbjogIiArIGNvbnZlcnRlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgY29udmVydGVkLmVxdWFscygiYSIpKTsKKworICAgICAgICAgICAgYm91dC5yZXNldCgpOworICAgICAgICAgICAgd3JpdGVyID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihib3V0LCAiSVNPMjAyMkpQIik7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUobmV3IGNoYXJbXSB7ICdcdTMwNDgnIH0pOworICAgICAgICAgICAgd3JpdGVyLmZsdXNoKCk7CisgICAgICAgICAgICAvLyBUaGUgYnl0ZSBzZXF1ZW5jZSBzaG91bGQgbm90IHN3aXRjaCB0byBBU0NJSSBtb2RlIHVudGlsIHRoZQorICAgICAgICAgICAgLy8gc3RyZWFtIGlzIGNsb3NlZC4KKyAgICAgICAgICAgIGNvbnZlcnRlZCA9IG5ldyBTdHJpbmcoYm91dC50b0J5dGVBcnJheSgpLCAiSVNPODg1OV8xIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDU6IEludmFsaWQgY29udmVyc2lvbjogIiArIGNvbnZlcnRlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgY29udmVydGVkLmVxdWFscygiXHUwMDFiJEIkKCIpKTsKKyAgICAgICAgICAgIHdyaXRlci5jbG9zZSgpOworICAgICAgICAgICAgY29udmVydGVkID0gbmV3IFN0cmluZyhib3V0LnRvQnl0ZUFycmF5KCksICJJU084ODU5XzEiKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlRlc3QgNjogSW52YWxpZCBjb252ZXJzaW9uOiAiICsgY29udmVydGVkLAorICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ZWQuZXF1YWxzKCJcdTAwMWIkQiQoXHUwMDFiKEIiKSk7CisKKyAgICAgICAgICAgIGJvdXQucmVzZXQoKTsKKyAgICAgICAgICAgIHdyaXRlciA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoYm91dCwgIklTTzIwMjJKUCIpOworICAgICAgICAgICAgd3JpdGVyLndyaXRlKG5ldyBjaGFyW10geyAnXHUzMDQ4JyB9KTsKKyAgICAgICAgICAgIHdyaXRlci53cml0ZShuZXcgY2hhcltdIHsgJ1x1MzA0OCcgfSk7CisgICAgICAgICAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICAgICAgICAgIC8vIFRoZXJlIHNob3VsZCBub3QgYmUgYSBtb2RlIHN3aXRjaCBiZXR3ZWVuIHdyaXRlcy4KKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCA3OiBJbnZhbGlkIGNvbnZlcnNpb24uICIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIlx1MDAxYiRCJCgkKFx1MDAxYihCIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKGJvdXQudG9CeXRlQXJyYXkoKSwgIklTTzg4NTlfMSIpKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDYW4ndCB0ZXN0IG1pc3NpbmcgY29udmVydGVyLgorICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkOiAiICsgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ZsdXNoKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlci5mbHVzaCgpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGFyW10gYnVmID0gbmV3IGNoYXJbdGVzdFN0cmluZy5sZW5ndGgoKV07CisgICAgICAgICAgICBvc3cud3JpdGUodGVzdFN0cmluZywgMCwgdGVzdFN0cmluZy5sZW5ndGgoKSk7CisgICAgICAgICAgICBvc3cuZmx1c2goKTsKKyAgICAgICAgICAgIG9wZW5JbnB1dFN0cmVhbSgpOworICAgICAgICAgICAgaXNyLnJlYWQoYnVmLCAwLCBidWYubGVuZ3RoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogQ2hhcmFjdGVycyBoYXZlIG5vdCBiZWVuIGZsdXNoZWQuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZyhidWYsIDAsIGJ1Zi5sZW5ndGgpLmVxdWFscyh0ZXN0U3RyaW5nKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IFVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgZm9zLnNldFRocm93c0V4Y2VwdGlvbih0cnVlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9zdy5mbHVzaCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBmb3Muc2V0VGhyb3dzRXhjZXB0aW9uKGZhbHNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlX1VTX0FTQ0lJKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RFbmNvZGVDaGFyc2V0KCJVUy1BU0NJSSIsIDEyOCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZV9JU09fODg1OV8xKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RFbmNvZGVDaGFyc2V0KCJJU08tODg1OS0xIiwgMjU2KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlX1VURl8xNkJFKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RFbmNvZGVDaGFyc2V0KCJVVEYtMTZCRSIsIDB4ZDgwMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZV9VVEZfMTZMRSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0RW5jb2RlQ2hhcnNldCgiVVRGLTE2TEUiLCAweGQ4MDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGVfVVRGXzE2KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RFbmNvZGVDaGFyc2V0KCJVVEYtMTYiLCAweGQ4MDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGVfVVRGXzgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEVuY29kZUNoYXJzZXQoIlVURi04IiwgMHhkODAwKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdEVuY29kZUNoYXJzZXQoU3RyaW5nIGNoYXJzZXQsIGludCBtYXhDaGFyKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcltdIGNoYXJzID0gbmV3IGNoYXJbbWF4Q2hhcl07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWF4Q2hhcjsgaSsrKSB7CisgICAgICAgICAgICBjaGFyc1tpXSA9IChjaGFyKSBpOworICAgICAgICB9CisKKyAgICAgICAgLy8gdG8gYnl0ZSBhcnJheQorICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZXNPdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIE91dHB1dFN0cmVhbVdyaXRlciBjaGFyc091dCA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoYnl0ZXNPdXQsIGNoYXJzZXQpOworICAgICAgICBjaGFyc091dC53cml0ZShjaGFycyk7CisgICAgICAgIGNoYXJzT3V0LmZsdXNoKCk7CisKKyAgICAgICAgLy8gZGVjb2RlIGZyb20gYnl0ZSBhcnJheSwgb25lIGNoYXJhY3RlciBhdCBhIHRpbWUKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYnl0ZXNJbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlc091dC50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgSW5wdXRTdHJlYW1SZWFkZXIgY2hhcnNJbiA9IG5ldyBJbnB1dFN0cmVhbVJlYWRlcihieXRlc0luLCBjaGFyc2V0KTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXhDaGFyOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpLCBjaGFyc0luLnJlYWQoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBjaGFyc0luLnJlYWQoKSk7CisKKyAgICAgICAgLy8gZGVjb2RlIGZyb20gYnl0ZSBhcnJheSwgdXNpbmcgYnl0ZSBidWZmZXJzCisgICAgICAgIGJ5dGVzSW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZXNPdXQudG9CeXRlQXJyYXkoKSk7CisgICAgICAgIGNoYXJzSW4gPSBuZXcgSW5wdXRTdHJlYW1SZWFkZXIoYnl0ZXNJbiwgY2hhcnNldCk7CisgICAgICAgIGNoYXJbXSBkZWNvZGVkID0gbmV3IGNoYXJbbWF4Q2hhcl07CisgICAgICAgIGZvciAoaW50IHIgPSAwOyByIDwgbWF4Q2hhcjsgKSB7CisgICAgICAgICAgICByICs9IGNoYXJzSW4ucmVhZChkZWNvZGVkLCByLCBtYXhDaGFyIC0gcik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBjaGFyc0luLnJlYWQoKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWF4Q2hhcjsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaSwgZGVjb2RlZFtpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEVuY29kaW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgT3V0cHV0U3RyZWFtV3JpdGVyIHdyaXRlcjsKKyAgICAgICAgd3JpdGVyID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihuZXcgU3VwcG9ydF9PdXRwdXRTdHJlYW0oKSwgInV0Zi04Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgZW5jb2RpbmcgcmV0dXJuZWQuIiwKKyAgICAgICAgICAgICAgICAgICAgIENoYXJzZXQuZm9yTmFtZSgidXRmLTgiKSwKKyAgICAgICAgICAgICAgICAgICAgIENoYXJzZXQuZm9yTmFtZSh3cml0ZXIuZ2V0RW5jb2RpbmcoKSkpOworCisgICAgICAgIHdyaXRlci5jbG9zZSgpOworICAgICAgICBhc3NlcnROdWxsKCJUZXN0IDI6IGdldEVuY29kaW5nKCkgZGlkIG5vdCByZXR1cm4gbnVsbCBmb3IgYSBjbG9zZWQgd3JpdGVyLiIsCisgICAgICAgICAgICAgICAgICAgd3JpdGVyLmdldEVuY29kaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGUkQ0lJKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcltdIGNoYXJzID0gdGVzdFN0cmluZy50b0NoYXJBcnJheSgpOworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgU3VwcG9ydF9PdXRwdXRTdHJlYW0gb3V0ID0gbmV3IFN1cHBvcnRfT3V0cHV0U3RyZWFtKDUwMCk7CisgICAgICAgIE91dHB1dFN0cmVhbVdyaXRlciB3cml0ZXI7CisKKyAgICAgICAgd3JpdGVyID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihvdXQsICJ1dGYtOCIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoY2hhcnMsIC0xLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlci53cml0ZShjaGFycywgMCwgLTEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVyLndyaXRlKG5ldyBjaGFyWzBdLCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlci53cml0ZSgoY2hhcltdKSBudWxsLCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVyLndyaXRlKGNoYXJzLCAxLCBjaGFycy5sZW5ndGgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA1YTogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoY2hhcnMsIDAsIGNoYXJzLmxlbmd0aCArIDEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA1YjogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoY2hhcnMsIGNoYXJzLmxlbmd0aCwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDVjOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlci53cml0ZShjaGFycywgY2hhcnMubGVuZ3RoICsgMSwgMCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDVkOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBvdXQuc2V0VGhyb3dzRXhjZXB0aW9uKHRydWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDA7IGkrKykgeworICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShjaGFycywgMCwgY2hhcnMubGVuZ3RoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgb3V0LnNldFRocm93c0V4Y2VwdGlvbihmYWxzZSk7CisKKyAgICAgICAgd3JpdGVyLmNsb3NlKCk7CisgICAgICAgIHdyaXRlciA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoYmFvcywgInV0Zi04Iik7CisgICAgICAgIHdyaXRlci53cml0ZShjaGFycywgMSwgMik7CisgICAgICAgIHdyaXRlci5mbHVzaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNzogd3JpdGUoY2hhcltdLCBpbnQsIGludCkgaGFzIG5vdCBwcm9kdWNlZCB0aGUgIiArCisgICAgICAgICAgICAgICAgICAgICAiZXhwZWN0ZWQgY29udGVudCBpbiB0aGUgb3V0cHV0IHN0cmVhbS4iLAorICAgICAgICAgICAgICAgICAgICAgImhpIiwgYmFvcy50b1N0cmluZygidXRmLTgiKSk7CisKKyAgICAgICAgd3JpdGVyLndyaXRlKGNoYXJzLCAwLCBjaGFycy5sZW5ndGgpOworICAgICAgICB3cml0ZXIuZmx1c2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDg6IHdyaXRlKGNoYXJbXSwgaW50LCBpbnQpIGhhcyBub3QgcHJvZHVjZWQgdGhlICIgKworICAgICAgICAgICAgICAgICJleHBlY3RlZCBjb250ZW50IGluIHRoZSBvdXRwdXQgc3RyZWFtLiIsCisgICAgICAgICAgICAgICAgImhpIiArIHRlc3RTdHJpbmcsIGJhb3MudG9TdHJpbmcoInV0Zi04IikpOworCisgICAgICAgIHdyaXRlci5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVyLndyaXRlKChjaGFyW10pIG51bGwsIC0xLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDk6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZUkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdXBwb3J0X091dHB1dFN0cmVhbSBvdXQgPSBuZXcgU3VwcG9ydF9PdXRwdXRTdHJlYW0oNTAwKTsKKyAgICAgICAgT3V0cHV0U3RyZWFtV3JpdGVyIHdyaXRlcjsKKworICAgICAgICBvdXQuc2V0VGhyb3dzRXhjZXB0aW9uKHRydWUpOworICAgICAgICB3cml0ZXIgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG91dCwgInV0Zi04Iik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBTaW5jZSB0aGVyZSBpcyBhbiBpbnRlcm5hbCBidWZmZXIgaW4gdGhlIGVuY29kZXIsIG1vcmUgdGhhbgorICAgICAgICAgICAgLy8gb25lIGNoYXJhY3RlciBuZWVkcyB0byBiZSB3cml0dGVuLgorICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDA7IGkrKykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgdGVzdFN0cmluZy5sZW5ndGgoKTsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSh0ZXN0U3RyaW5nLmNoYXJBdChqKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBvdXQuc2V0VGhyb3dzRXhjZXB0aW9uKGZhbHNlKTsKKyAgICAgICAgd3JpdGVyLmNsb3NlKCk7CisKKyAgICAgICAgd3JpdGVyID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihvdXQsICJ1dGYtOCIpOworICAgICAgICB3cml0ZXIud3JpdGUoMSk7CisgICAgICAgIHdyaXRlci5mbHVzaCgpOworICAgICAgICBTdHJpbmcgc3RyID0gbmV3IFN0cmluZyhvdXQudG9CeXRlQXJyYXkoKSwgInV0Zi04Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiAiLCAiXHUwMDAxIiwgc3RyKTsKKworICAgICAgICB3cml0ZXIud3JpdGUoMik7CisgICAgICAgIHdyaXRlci5mbHVzaCgpOworICAgICAgICBzdHIgPSBuZXcgU3RyaW5nKG91dC50b0J5dGVBcnJheSgpLCAidXRmLTgiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDM6ICIsICJcdTAwMDFcdTAwMDIiLCBzdHIpOworCisgICAgICAgIHdyaXRlci53cml0ZSgtMSk7CisgICAgICAgIHdyaXRlci5mbHVzaCgpOworICAgICAgICBzdHIgPSBuZXcgU3RyaW5nKG91dC50b0J5dGVBcnJheSgpLCAidXRmLTgiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDQ6ICIsICJcdTAwMDFcdTAwMDJcdWZmZmYiLCBzdHIpOworCisgICAgICAgIHdyaXRlci53cml0ZSgweGZlZGNiKTsKKyAgICAgICAgd3JpdGVyLmZsdXNoKCk7CisgICAgICAgIHN0ciA9IG5ldyBTdHJpbmcob3V0LnRvQnl0ZUFycmF5KCksICJ1dGYtOCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNTogIiwgIlx1MDAwMVx1MDAwMlx1ZmZmZlx1ZWRjYiIsIHN0cik7CisKKyAgICAgICAgd3JpdGVyLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDY6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZUxqYXZhX2xhbmdfU3RyaW5nSUkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgU3VwcG9ydF9PdXRwdXRTdHJlYW0gb3V0ID0gbmV3IFN1cHBvcnRfT3V0cHV0U3RyZWFtKDUwMCk7CisgICAgICAgIE91dHB1dFN0cmVhbVdyaXRlciB3cml0ZXI7CisKKyAgICAgICAgd3JpdGVyID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihvdXQsICJ1dGYtOCIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoIkxvcmVtIiwgLTEsIDApOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVyLndyaXRlKCJMb3JlbSIsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlci53cml0ZSgiIiwgMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUodGVzdFN0cmluZywgMSwgdGVzdFN0cmluZy5sZW5ndGgoKSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDRhOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVyLndyaXRlKHRlc3RTdHJpbmcsIDAsIHRlc3RTdHJpbmcubGVuZ3RoKCkgKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNGI6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUodGVzdFN0cmluZywgdGVzdFN0cmluZy5sZW5ndGgoKSwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDRjOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVyLndyaXRlKHRlc3RTdHJpbmcsIHRlc3RTdHJpbmcubGVuZ3RoKCkgKyAxLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNGQ6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoKFN0cmluZykgbnVsbCwgMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgb3V0LnNldFRocm93c0V4Y2VwdGlvbih0cnVlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjAwOyBpKyspIHsKKyAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUodGVzdFN0cmluZywgMCwgdGVzdFN0cmluZy5sZW5ndGgoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmYWlsKCJUZXN0IDY6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIG91dC5zZXRUaHJvd3NFeGNlcHRpb24oZmFsc2UpOworCisgICAgICAgIHdyaXRlci5jbG9zZSgpOworICAgICAgICB3cml0ZXIgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKGJhb3MsICJ1dGYtOCIpOworCisgICAgICAgIHdyaXRlci53cml0ZSgiYWJjIiwgMSwgMik7CisgICAgICAgIHdyaXRlci5mbHVzaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNzogd3JpdGUoU3RyaW5nLCBpbnQsIGludCkgaGFzIG5vdCBwcm9kdWNlZCB0aGUgIiArCisgICAgICAgICAgICAgICAgICAgICAiZXhwZWN0ZWQgY29udGVudCBpbiB0aGUgb3V0cHV0IHN0cmVhbS4iLAorICAgICAgICAgICAgICAgICAgICAgImJjIiwgYmFvcy50b1N0cmluZygidXRmLTgiKSk7CisKKyAgICAgICAgd3JpdGVyLndyaXRlKHRlc3RTdHJpbmcsIDAsIHRlc3RTdHJpbmcubGVuZ3RoKCkpOworICAgICAgICB3cml0ZXIuZmx1c2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDc6IHdyaXRlKFN0cmluZywgaW50LCBpbnQpIGhhcyBub3QgcHJvZHVjZWQgdGhlICIgKworICAgICAgICAgICAgICAgICAgICAgImV4cGVjdGVkIGNvbnRlbnQgaW4gdGhlIG91dHB1dCBzdHJlYW0uIiwKKyAgICAgICAgICAgICAgICAgICAgICJiYyIgKyB0ZXN0U3RyaW5nLCBiYW9zLnRvU3RyaW5nKCJ1dGYtOCIpKTsKKworICAgICAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlci53cml0ZSgiYWJjIiwgMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDg6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG9wZW5JbnB1dFN0cmVhbSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzciA9IG5ldyBJbnB1dFN0cmVhbVJlYWRlcihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZm9zLnRvQnl0ZUFycmF5KCkpLCAiVVRGLTgiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVVEYtOCBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZFBpcGVkT3V0cHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRQaXBlZE91dHB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hODJhODlhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRQaXBlZE91dHB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDI3MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUGlwZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlBpcGVkT3V0cHV0U3RyZWFtOworCitwdWJsaWMgY2xhc3MgT2xkUGlwZWRPdXRwdXRTdHJlYW1UZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBjbGFzcyBQUmVhZGVyIGltcGxlbWVudHMgUnVubmFibGUgeworICAgICAgICBQaXBlZElucHV0U3RyZWFtIHJlYWRlcjsKKworICAgICAgICBwdWJsaWMgUGlwZWRJbnB1dFN0cmVhbSBnZXRSZWFkZXIoKSB7CisgICAgICAgICAgICByZXR1cm4gcmVhZGVyOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFBSZWFkZXIoUGlwZWRPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJlYWRlciA9IG5ldyBQaXBlZElucHV0U3RyZWFtKG91dCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXhjZXB0aW9uIHNldHRpbmcgdXAgcmVhZGVyOiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWRlci5hdmFpbGFibGUoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgICAgICAgICAgICAgICAgIFRocmVhZC55aWVsZCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgcmVhZChpbnQgbmJ5dGVzKSB7CisgICAgICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbbmJ5dGVzXTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmVhZGVyLnJlYWQoYnVmLCAwLCBuYnl0ZXMpOworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGJ1Zik7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFeGNlcHRpb24gcmVhZGluZyAoIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldE5hbWUoKSArICIpOiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuICJFUlJPUiI7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIHRlc3RTdHJpbmcgPSAiTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsXG4iICsKKyAgICAgICAgImNvbnNlY3RldHVyIGFkaXBpc2ljaW5nIGVsaXQsXG5zZWQgZG8gZWl1c21vZCB0ZW1wb3IgaW5jaWRpZHVudCB1dCIgKworICAgICAgICAibGFib3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdWEuXG4iOworICAgIHN0YXRpYyBmaW5hbCBpbnQgdGVzdExlbmd0aCA9IHRlc3RTdHJpbmcubGVuZ3RoKCk7CisKKyAgICBUaHJlYWQgcnQ7CisKKyAgICBQUmVhZGVyIHJlYWRlcjsKKworICAgIFBpcGVkT3V0cHV0U3RyZWFtIG91dDsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB7CisgICAgICAgIG91dCA9IG5ldyBQaXBlZE91dHB1dFN0cmVhbSgpOworICAgICAgICBhc3NlcnROb3ROdWxsKG91dCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY2V0ZWQgSU9FeGNlcHRpb24uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fUGlwZWRJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmlvLlBpcGVkT3V0cHV0U3RyZWFtKGphdmEuaW8uUGlwZWRJbnB1dFN0cmVhbSkKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3V0ID0gbmV3IFBpcGVkT3V0cHV0U3RyZWFtKG5ldyBQaXBlZElucHV0U3RyZWFtKCkpOworICAgICAgICAgICAgb3V0LndyaXRlKCdiJyk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IENvbnN0cnVjdG9yIGZhaWxlZDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBvdXQuY2xvc2UoKTsKKworICAgICAgICBQaXBlZElucHV0U3RyZWFtIHBpcyA9IG5ldyBQaXBlZElucHV0U3RyZWFtKG5ldyBQaXBlZE91dHB1dFN0cmVhbSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG91dCA9IG5ldyBQaXBlZE91dHB1dFN0cmVhbShwaXMpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBJT0V4Y2VwdGlvbiBleHBlY3RlZCBiZWNhdXNlIHRoZSBpbnB1dCBzdHJlYW0gaXMgYWxyZWFkeSBjb25uZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jbG9zZSgpIHsKKyAgICAgICAgb3V0ID0gbmV3IFBpcGVkT3V0cHV0U3RyZWFtKCk7CisgICAgICAgIHJ0ID0gbmV3IFRocmVhZChyZWFkZXIgPSBuZXcgUFJlYWRlcihvdXQpKTsKKyAgICAgICAgcnQuc3RhcnQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IFVuZXhwZWN0ZWQgSU9FeGNlcHRpb246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nvbm5lY3RMamF2YV9pb19QaXBlZElucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0ID0gbmV3IFBpcGVkT3V0cHV0U3RyZWFtKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG91dC5jb25uZWN0KG5ldyBQaXBlZElucHV0U3RyZWFtKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBVbmV4cGVjdGVkIGV4Y2VwdGlvbiB3aGVuIGNvbm5lY3Rpbmc6ICIgKworICAgICAgICAgICAgICAgICAgICBlLmdldExvY2FsaXplZE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3V0LndyaXRlKCdCJyk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiB3aGVuIHdyaXRpbmcgYWZ0ZXIgY29ubmVjdGluZy4iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXQuY29ubmVjdChuZXcgUGlwZWRJbnB1dFN0cmVhbSgpKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQgd2hlbiByZWNvbm5lY3RpbmcgdGhlIHN0cmVhbS4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3V0LmNvbm5lY3QobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmx1c2goKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0ID0gbmV3IFBpcGVkT3V0cHV0U3RyZWFtKCk7CisgICAgICAgIHJ0ID0gbmV3IFRocmVhZChyZWFkZXIgPSBuZXcgUFJlYWRlcihvdXQpKTsKKyAgICAgICAgcnQuc3RhcnQoKTsKKyAgICAgICAgb3V0LndyaXRlKHRlc3RTdHJpbmcuZ2V0Qnl0ZXMoKSwgMCwgMTApOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IEJ5dGVzIGhhdmUgYmVlbiB3cml0dGVuIGJlZm9yZSBmbHVzaC4iLCByZWFkZXIuYXZhaWxhYmxlKCkgIT0gMCk7CisgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMjogRmx1c2ggZmFpbGVkLiAiLAorICAgICAgICAgICAgICAgIHRlc3RTdHJpbmcuc3Vic3RyaW5nKDAsIDEwKSwgcmVhZGVyLnJlYWQoMTApKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlJEJJSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dCA9IG5ldyBQaXBlZE91dHB1dFN0cmVhbSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXQud3JpdGUodGVzdFN0cmluZy5nZXRCeXRlcygpLCAwLCA1KTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgb3V0ID0gbmV3IFBpcGVkT3V0cHV0U3RyZWFtKG5ldyBQaXBlZElucHV0U3RyZWFtKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXQud3JpdGUodGVzdFN0cmluZy5nZXRCeXRlcygpLCAtMSwgMTApOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG91dC53cml0ZSh0ZXN0U3RyaW5nLmdldEJ5dGVzKCksIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXQud3JpdGUodGVzdFN0cmluZy5nZXRCeXRlcygpLCA1LCB0ZXN0U3RyaW5nLmxlbmd0aCgpKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICBvdXQgPSBuZXcgUGlwZWRPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJ0ID0gbmV3IFRocmVhZChyZWFkZXIgPSBuZXcgUFJlYWRlcihvdXQpKTsKKyAgICAgICAgICAgIHJ0LnN0YXJ0KCk7CisgICAgICAgICAgICBvdXQud3JpdGUodGVzdFN0cmluZy5nZXRCeXRlcygpLCAwLCB0ZXN0U3RyaW5nLmxlbmd0aCgpKTsKKyAgICAgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDU6IEJ5dGVzIHJlYWQgZG8gbm90IG1hdGNoIHRoZSBieXRlcyB3cml0dGVuLiAiLAorICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3RTdHJpbmcsIHJlYWRlci5yZWFkKHRlc3RTdHJpbmcubGVuZ3RoKCkpKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVGVzdCA1OiBVbmV4cGVjdGVkIElPRXhjZXB0aW9uOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgcmVhZGVyLmdldFJlYWRlcigpLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXQud3JpdGUodGVzdFN0cmluZy5nZXRCeXRlcygpLCAwLCA1KTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dCA9IG5ldyBQaXBlZE91dHB1dFN0cmVhbSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXQud3JpdGUoNDIpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBydCA9IG5ldyBUaHJlYWQocmVhZGVyID0gbmV3IFBSZWFkZXIob3V0KSk7CisgICAgICAgIHJ0LnN0YXJ0KCk7CisgICAgICAgIG91dC53cml0ZSgnYycpOworICAgICAgICBvdXQuZmx1c2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IFRoZSBieXRlIHJlYWQgZG9lcyBub3QgbWF0Y2ggdGhlIGJ5dGUgd3JpdHRlbi4gIiwKKyAgICAgICAgICAgICAgICAgICAgICJjIiwgcmVhZGVyLnJlYWQoMSkpOworCisvKiBUZXN0IGRpc2FibGVkIGR1ZSB0byBpbmNvbXBsZXRlIGltcGxlbWVudGF0aW9uLCBzZWUgdGlja2V0ICM5Mi4KKyAgICAgICAgcnQuaW50ZXJydXB0KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG91dC53cml0ZSg0Mik7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKyovCisgICAgICAgIHJlYWRlci5nZXRSZWFkZXIoKS5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3V0LndyaXRlKDQyKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVhcnMgZG93biB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIGNsb3NlIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzCisgICAgICogbWV0aG9kIGlzIGNhbGxlZCBhZnRlciBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHJ0ICE9IG51bGwpCisgICAgICAgICAgICBydC5pbnRlcnJ1cHQoKTsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZFBpcGVkV3JpdGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRQaXBlZFdyaXRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNmY2ODZlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRQaXBlZFdyaXRlclRlc3QuamF2YQpAQCAtMCwwICsxLDI3NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUGlwZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5QaXBlZFdyaXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitwdWJsaWMgY2xhc3MgT2xkUGlwZWRXcml0ZXJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgdGVzdFN0cmluZyA9ICJMb3JlbSBpcHN1bS4uLiI7CisgICAgc3RhdGljIGZpbmFsIGludCB0ZXN0TGVuZ3RoID0gdGVzdFN0cmluZy5sZW5ndGgoKTsKKworICAgIHN0YXRpYyBjbGFzcyBQUmVhZGVyIGltcGxlbWVudHMgUnVubmFibGUgeworICAgICAgICBwdWJsaWMgUGlwZWRSZWFkZXIgcHI7CisKKyAgICAgICAgcHVibGljIGNoYXJbXSBidWY7CisKKyAgICAgICAgcHVibGljIFBSZWFkZXIoUGlwZWRXcml0ZXIgcHcpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHIgPSBuZXcgUGlwZWRSZWFkZXIocHcpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXhjZXB0aW9uIHNldHRpbmcgdXAgcmVhZGVyOiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUFJlYWRlcihQaXBlZFJlYWRlciBwcikgeworICAgICAgICAgICAgdGhpcy5wciA9IHByOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgICAgICAgICAgICAgICAgIFRocmVhZC55aWVsZCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgcmVhZChpbnQgbmJ5dGVzKSB7CisgICAgICAgICAgICBidWYgPSBuZXcgY2hhcltuYnl0ZXNdOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwci5yZWFkKGJ1ZiwgMCwgbmJ5dGVzKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhidWYpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXhjZXB0aW9uIHJlYWRpbmcgKCIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXROYW1lKCkgKyAiKTogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIHJldHVybiAiRVJST1IiOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgVGhyZWFkIHJlYWRlclRocmVhZDsKKyAgICBQUmVhZGVyIHJlYWRlcjsKKyAgICBQaXBlZFdyaXRlciBwdzsKKyAgICBjaGFyW10gdGVzdEJ1ZjsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB7CisgICAgICAgIHB3ID0gbmV3IFBpcGVkV3JpdGVyKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwocHcpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHcuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY2V0ZWQgSU9FeGNlcHRpb24uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fUGlwZWRSZWFkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUGlwZWRSZWFkZXIgcmQgPSBuZXcgUGlwZWRSZWFkZXIoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHcgPSBuZXcgUGlwZWRXcml0ZXIocmQpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBDb25zdHJ1dG9yIGZhaWxlZDoiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgcmVhZGVyVGhyZWFkID0gbmV3IFRocmVhZChyZWFkZXIgPSBuZXcgUFJlYWRlcihyZCksICJDb25zdHJ1Y3RvcihSZWFkZXIpIik7CisgICAgICAgIHJlYWRlclRocmVhZC5zdGFydCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHcud3JpdGUodGVzdEJ1Zik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IENvdWxkIG5vdCB3cml0ZSB0byB0aGUgY29uc3RydWN0ZWQgd3JpdGVyOiAiCisgICAgICAgICAgICAgICAgICAgICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIHB3LmNsb3NlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAzOiBJbmNvcnJlY3QgY2hhcmFjdGVyIHN0cmluZyByZWNlaXZlZC4iLCB0ZXN0U3RyaW5nLAorICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkKHRlc3RMZW5ndGgpKTsKKworICAgICAgICByZCA9IG5ldyBQaXBlZFJlYWRlcihuZXcgUGlwZWRXcml0ZXIoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwdyA9IG5ldyBQaXBlZFdyaXRlcihyZCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IElPRXhjZXB0aW9uIGV4cGVjdGVkIGJlY2F1c2UgdGhlIHJlYWRlciBpcyBhbHJlYWR5IGNvbm5lY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb3NlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFBpcGVkUmVhZGVyIHJkID0gbmV3IFBpcGVkUmVhZGVyKCk7CisgICAgICAgIHB3ID0gbmV3IFBpcGVkV3JpdGVyKHJkKTsKKyAgICAgICAgcmVhZGVyID0gbmV3IFBSZWFkZXIocmQpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHcuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBVbmV4cGVjdGVkIElPRXhjZXB0aW9uOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25uZWN0TGphdmFfaW9fUGlwZWRSZWFkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUGlwZWRSZWFkZXIgcmQgPSBuZXcgUGlwZWRSZWFkZXIoKTsKKyAgICAgICAgcHcgPSBuZXcgUGlwZWRXcml0ZXIoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHcuY29ubmVjdChyZCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IFVuZXhwZWN0ZWQgZXhjZXB0aW9uIHdoZW4gY29ubmVjdGluZzogIiArCisgICAgICAgICAgICAgICAgICAgIGUuZ2V0TG9jYWxpemVkTWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHJlYWRlclRocmVhZCA9IG5ldyBUaHJlYWQocmVhZGVyID0gbmV3IFBSZWFkZXIocmQpLCAiY29ubmVjdCIpOworICAgICAgICByZWFkZXJUaHJlYWQuc3RhcnQoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHcud3JpdGUodGVzdEJ1Zik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiB3aGVuIHdyaXRpbmcgYWZ0ZXIgY29ubmVjdGluZy4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMzogSW5jb3JyZWN0IGNoYXJhY3RlciBzdHJpbmcgcmVjZWl2ZWQuIiwgdGVzdFN0cmluZywKKyAgICAgICAgICAgICAgICByZWFkZXIucmVhZCh0ZXN0TGVuZ3RoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHB3LmNvbm5lY3QobmV3IFBpcGVkUmVhZGVyKCkpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBJT0V4Y2VwdGlvbiBleHBlY3RlZCB3aGVuIHJlY29ubmVjdGluZyB0aGUgd3JpdGVyLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmx1c2goKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS5pby5QaXBlZFdyaXRlci5mbHVzaCgpCisgICAgICAgIHB3ID0gbmV3IFBpcGVkV3JpdGVyKCk7CisgICAgICAgIHJlYWRlclRocmVhZCA9IG5ldyBUaHJlYWQocmVhZGVyID0gbmV3IFBSZWFkZXIocHcpLCAiZmx1c2giKTsKKyAgICAgICAgcmVhZGVyVGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIHB3LndyaXRlKHRlc3RCdWYpOworICAgICAgICBwdy5mbHVzaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogRmx1c2ggZmFpbGVkLiAiLCB0ZXN0U3RyaW5nLAorICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkKHRlc3RMZW5ndGgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlJENJSSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBwdyA9IG5ldyBQaXBlZFdyaXRlcigpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwdy53cml0ZSh0ZXN0QnVmLCAwLCA1KTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgcHcgPSBuZXcgUGlwZWRXcml0ZXIobmV3IFBpcGVkUmVhZGVyKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwdy53cml0ZSh0ZXN0QnVmLCAtMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHcud3JpdGUodGVzdEJ1ZiwgMCwgLTEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHB3LndyaXRlKHRlc3RCdWYsIDUsIHRlc3RTdHJpbmcubGVuZ3RoKCkpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgcHcuY2xvc2UoKTsKKyAgICAgICAgcHcgPSBuZXcgUGlwZWRXcml0ZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRlclRocmVhZCA9IG5ldyBUaHJlYWQocmVhZGVyID0gbmV3IFBSZWFkZXIocHcpLCAid3JpdGVDSUkiKTsKKyAgICAgICAgICAgIHJlYWRlclRocmVhZC5zdGFydCgpOworICAgICAgICAgICAgcHcud3JpdGUodGVzdEJ1ZiwgMCwgdGVzdExlbmd0aCk7CisgICAgICAgICAgICBwdy5jbG9zZSgpOworICAgICAgICAgICAgcmVhZGVyLnJlYWQodGVzdExlbmd0aCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDU6IENoYXJhY3RlcnMgcmVhZCBkbyBub3QgbWF0Y2ggdGhlIGNoYXJhY3RlcnMgd3JpdHRlbi4iLAorICAgICAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKCB0ZXN0QnVmLCByZWFkZXIuYnVmKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNTogVW5leHBlY3RlZCBJT0V4Y2VwdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHJlYWRlclRocmVhZC5pbnRlcnJ1cHQoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHcud3JpdGUodGVzdEJ1ZiwgMCwgNSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDY6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHJlYWRlci5wci5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHcud3JpdGUodGVzdEJ1ZiwgMCwgNSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDc6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGVJKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEuaW8uUGlwZWRXcml0ZXIud3JpdGUoaW50KQorCisgICAgICAgIHB3ID0gbmV3IFBpcGVkV3JpdGVyKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHB3LndyaXRlKDQyKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgcmVhZGVyVGhyZWFkID0gbmV3IFRocmVhZChyZWFkZXIgPSBuZXcgUFJlYWRlcihwdyksICJ3cml0ZUkiKTsKKyAgICAgICAgcmVhZGVyVGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIHB3LndyaXRlKDEpOworICAgICAgICBwdy53cml0ZSgyKTsKKyAgICAgICAgcHcud3JpdGUoMyk7CisgICAgICAgIHB3LmNsb3NlKCk7CisgICAgICAgIHJlYWRlci5yZWFkKDMpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDI6IFRoZSBjaGFyYWFjdGVycyByZWFkIGRvIG5vdCBtYXRjaCB0aGUgY2hhcmFjdGVycyB3cml0dGVuOiAiICsKKyAgICAgICAgICAgICAgICAoaW50KSByZWFkZXIuYnVmWzBdICsgIiAiICsgKGludCkgcmVhZGVyLmJ1ZlsxXSArICIgIiArIChpbnQpIHJlYWRlci5idWZbMl0sCisgICAgICAgICAgICAgICAgcmVhZGVyLmJ1ZlswXSA9PSAxICYmIHJlYWRlci5idWZbMV0gPT0gMiAmJiByZWFkZXIuYnVmWzJdID09IDMpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRlc3RCdWYgPSBuZXcgY2hhclt0ZXN0TGVuZ3RoXTsKKyAgICAgICAgdGVzdFN0cmluZy5nZXRDaGFycygwLCB0ZXN0TGVuZ3RoLCB0ZXN0QnVmLCAwKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKHJlYWRlclRocmVhZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmVhZGVyVGhyZWFkLmludGVycnVwdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gaWdub3JlKSB7fQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKHB3ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBwdy5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gaWdub3JlKSB7fQorICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkUHVzaGJhY2tJbnB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkUHVzaGJhY2tJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNzA2NTBlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRQdXNoYmFja0lucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzU2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlB1c2hiYWNrSW5wdXRTdHJlYW07CisKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtOworCitwdWJsaWMgY2xhc3MgT2xkUHVzaGJhY2tJbnB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW0gdW5kZXJseWluZyA9IG5ldyBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbSgpOworICAgIFB1c2hiYWNrSW5wdXRTdHJlYW0gcGlzOworCisgICAgcHVibGljIFN0cmluZyBmaWxlU3RyaW5nID0gIlRlc3RfQWxsX1Rlc3RzXG5UZXN0X2phdmFfaW9fQnVmZmVyZWRJbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0J1ZmZlcmVkT3V0cHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fQnl0ZUFycmF5SW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19CeXRlQXJyYXlPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19EYXRhSW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19GaWxlXG5UZXN0X2phdmFfaW9fRmlsZURlc2NyaXB0b3JcblRlc3RfamF2YV9pb19GaWxlSW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19GaWxlTm90Rm91bmRFeGNlcHRpb25cblRlc3RfamF2YV9pb19GaWxlT3V0cHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fRmlsdGVySW5wdXRTdHJlYW1cblRlc3RfamF2YV9pb19GaWx0ZXJPdXRwdXRTdHJlYW1cblRlc3RfamF2YV9pb19JbnB1dFN0cmVhbVxuVGVzdF9qYXZhX2lvX0lPRXhjZXB0aW9uXG5UZXN0X2phdmFfaW9fT3V0cHV0U3RyZWFtXG5UZXN0X2phdmFfaW9fUHJpbnRTdHJlYW1cblRlc3RfamF2YV9pb19SYW5kb21BY2Nlc3NGaWxlXG5UZXN0X2phdmFfaW9fU3luY0ZhaWxlZEV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQWJzdHJhY3RNZXRob2RFcnJvclxuVGVzdF9qYXZhX2xhbmdfQXJpdGhtZXRpY0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19BcnJheVN0b3JlRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19Cb29sZWFuXG5UZXN0X2phdmFfbGFuZ19CeXRlXG5UZXN0X2phdmFfbGFuZ19DaGFyYWN0ZXJcblRlc3RfamF2YV9sYW5nX0NsYXNzXG5UZXN0X2phdmFfbGFuZ19DbGFzc0Nhc3RFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0NsYXNzQ2lyY3VsYXJpdHlFcnJvclxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NGb3JtYXRFcnJvclxuVGVzdF9qYXZhX2xhbmdfQ2xhc3NMb2FkZXJcblRlc3RfamF2YV9sYW5nX0NsYXNzTm90Rm91bmRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0Nsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19Eb3VibGVcblRlc3RfamF2YV9sYW5nX0Vycm9yXG5UZXN0X2phdmFfbGFuZ19FeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0V4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvclxuVGVzdF9qYXZhX2xhbmdfRmxvYXRcblRlc3RfamF2YV9sYW5nX0lsbGVnYWxBY2Nlc3NFcnJvclxuVGVzdF9qYXZhX2xhbmdfSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19JbGxlZ2FsVGhyZWFkU3RhdGVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0luY29tcGF0aWJsZUNsYXNzQ2hhbmdlRXJyb3JcblRlc3RfamF2YV9sYW5nX0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0luc3RhbnRpYXRpb25FcnJvclxuVGVzdF9qYXZhX2xhbmdfSW5zdGFudGlhdGlvbkV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfSW50ZWdlclxuVGVzdF9qYXZhX2xhbmdfSW50ZXJuYWxFcnJvclxuVGVzdF9qYXZhX2xhbmdfSW50ZXJydXB0ZWRFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX0xpbmthZ2VFcnJvclxuVGVzdF9qYXZhX2xhbmdfTG9uZ1xuVGVzdF9qYXZhX2xhbmdfTWF0aFxuVGVzdF9qYXZhX2xhbmdfTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX05vQ2xhc3NEZWZGb3VuZEVycm9yXG5UZXN0X2phdmFfbGFuZ19Ob1N1Y2hGaWVsZEVycm9yXG5UZXN0X2phdmFfbGFuZ19Ob1N1Y2hNZXRob2RFcnJvclxuVGVzdF9qYXZhX2xhbmdfTnVsbFBvaW50ZXJFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX051bWJlclxuVGVzdF9qYXZhX2xhbmdfTnVtYmVyRm9ybWF0RXhjZXB0aW9uXG5UZXN0X2phdmFfbGFuZ19PYmplY3RcblRlc3RfamF2YV9sYW5nX091dE9mTWVtb3J5RXJyb3JcblRlc3RfamF2YV9sYW5nX1J1bnRpbWVFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX1NlY3VyaXR5TWFuYWdlclxuVGVzdF9qYXZhX2xhbmdfU2hvcnRcblRlc3RfamF2YV9sYW5nX1N0YWNrT3ZlcmZsb3dFcnJvclxuVGVzdF9qYXZhX2xhbmdfU3RyaW5nXG5UZXN0X2phdmFfbGFuZ19TdHJpbmdCdWZmZXJcblRlc3RfamF2YV9sYW5nX1N0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb25cblRlc3RfamF2YV9sYW5nX1N5c3RlbVxuVGVzdF9qYXZhX2xhbmdfVGhyZWFkXG5UZXN0X2phdmFfbGFuZ19UaHJlYWREZWF0aFxuVGVzdF9qYXZhX2xhbmdfVGhyZWFkR3JvdXBcblRlc3RfamF2YV9sYW5nX1Rocm93YWJsZVxuVGVzdF9qYXZhX2xhbmdfVW5rbm93bkVycm9yXG5UZXN0X2phdmFfbGFuZ19VbnNhdGlzZmllZExpbmtFcnJvclxuVGVzdF9qYXZhX2xhbmdfVmVyaWZ5RXJyb3JcblRlc3RfamF2YV9sYW5nX1ZpcnR1YWxNYWNoaW5lRXJyb3JcblRlc3RfamF2YV9sYW5nX3ZtX0ltYWdlXG5UZXN0X2phdmFfbGFuZ192bV9NZW1vcnlTZWdtZW50XG5UZXN0X2phdmFfbGFuZ192bV9ST01TdG9yZUV4Y2VwdGlvblxuVGVzdF9qYXZhX2xhbmdfdm1fVk1cblRlc3RfamF2YV9sYW5nX1ZvaWRcblRlc3RfamF2YV9uZXRfQmluZEV4Y2VwdGlvblxuVGVzdF9qYXZhX25ldF9Db25uZWN0RXhjZXB0aW9uXG5UZXN0X2phdmFfbmV0X0RhdGFncmFtUGFja2V0XG5UZXN0X2phdmFfbmV0X0RhdGFncmFtU29ja2V0XG5UZXN0X2phdmFfbmV0X0RhdGFncmFtU29ja2V0SW1wbFxuVGVzdF9qYXZhX25ldF9JbmV0QWRkcmVzc1xuVGVzdF9qYXZhX25ldF9Ob1JvdXRlVG9Ib3N0RXhjZXB0aW9uXG5UZXN0X2phdmFfbmV0X1BsYWluRGF0YWdyYW1Tb2NrZXRJbXBsXG5UZXN0X2phdmFfbmV0X1BsYWluU29ja2V0SW1wbFxuVGVzdF9qYXZhX25ldF9Tb2NrZXRcblRlc3RfamF2YV9uZXRfU29ja2V0RXhjZXB0aW9uXG5UZXN0X2phdmFfbmV0X1NvY2tldEltcGxcblRlc3RfamF2YV9uZXRfU29ja2V0SW5wdXRTdHJlYW1cblRlc3RfamF2YV9uZXRfU29ja2V0T3V0cHV0U3RyZWFtXG5UZXN0X2phdmFfbmV0X1Vua25vd25Ib3N0RXhjZXB0aW9uXG5UZXN0X2phdmFfdXRpbF9BcnJheUVudW1lcmF0b3JcblRlc3RfamF2YV91dGlsX0RhdGVcblRlc3RfamF2YV91dGlsX0V2ZW50T2JqZWN0XG5UZXN0X2phdmFfdXRpbF9IYXNoRW51bWVyYXRvclxuVGVzdF9qYXZhX3V0aWxfSGFzaHRhYmxlXG5UZXN0X2phdmFfdXRpbF9Qcm9wZXJ0aWVzXG5UZXN0X2phdmFfdXRpbF9SZXNvdXJjZUJ1bmRsZVxuVGVzdF9qYXZhX3V0aWxfdG1cblRlc3RfamF2YV91dGlsX1ZlY3RvclxuIjsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9pb19JbnB1dFN0cmVhbSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEuaW8uUHVzaGJhY2tJbnB1dFN0cmVhbShqYXZhLmlvLklucHV0U3RyZWFtKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcGlzID0gbmV3IFB1c2hiYWNrSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKCJIZWxsbyIKKyAgICAgICAgICAgICAgICAgICAgLmdldEJ5dGVzKCkpKTsKKyAgICAgICAgICAgIHBpcy51bnJlYWQoIkhlIi5nZXRCeXRlcygpKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdAorICAgICAgICAgICAgLy8gUHVzaGJhY2sgYnVmZmVyIHNob3VsZCBiZSBmdWxsCisgICAgICAgICAgICByZXR1cm47CisKKyAgICAgICAgfQorICAgICAgICBmYWlsKCJGYWlsZWQgdG8gdGhyb3cgZXhjZXB0aW9uIG9uIHVucmVhZCB3aGVuIGJ1ZmZlciBmdWxsIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX0lucHV0U3RyZWFtSSgpIHsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKCJIZWxsbyIuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwaXMgPSBuZXcgUHVzaGJhY2tJbnB1dFN0cmVhbShiYXMsIDApOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcGlzID0gbmV3IFB1c2hiYWNrSW5wdXRTdHJlYW0oYmFzLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgcGlzID0gbmV3IFB1c2hiYWNrSW5wdXRTdHJlYW0oYmFzICwgNSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwaXMudW5yZWFkKCJIZWxsbyB3b3JsZCIuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IElPRXhjZXB0aW9uIGV4cGVjdGVkIHdoZW4gdGhlIHVucmVhZCBidWZmZXIgaXMgZnVsbC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUHVzaGJhY2tJbnB1dFN0cmVhbSB0b2JqOworCisgICAgICAgIHRvYmogPSBuZXcgUHVzaGJhY2tJbnB1dFN0cmVhbSh1bmRlcmx5aW5nKTsKKyAgICAgICAgdG9iai5jbG9zZSgpOworICAgICAgICB0b2JqLmNsb3NlKCk7CisgICAgICAgIHRvYmogPSBuZXcgUHVzaGJhY2tJbnB1dFN0cmVhbSh1bmRlcmx5aW5nKTsKKyAgICAgICAgdW5kZXJseWluZy50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2JqLmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9hdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBQdXNoYmFja0lucHV0U3RyZWFtIHRvYmo7CisKKyAgICAgICAgdG9iaiA9IG5ldyBQdXNoYmFja0lucHV0U3RyZWFtKHVuZGVybHlpbmcpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciEiLCAzMCwgdG9iai5hdmFpbGFibGUoKSk7CisgICAgICAgIHVuZGVybHlpbmcudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9iai5hdmFpbGFibGUoKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X21hcmtTdXBwb3J0ZWQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEuaW8uUHVzaGJhY2tJbnB1dFN0cmVhbS5tYXJrU3VwcG9ydGVkKCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibWFya1N1cHBvcnRlZCByZXR1cm5lZCB0cnVlIiwgIXBpcy5tYXJrU3VwcG9ydGVkKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFB1c2hiYWNrSW5wdXRTdHJlYW0gdG9iajsKKworICAgICAgICB0b2JqID0gbmV3IFB1c2hiYWNrSW5wdXRTdHJlYW0odW5kZXJseWluZyk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgYnl0ZSByZWFkOyIsIDY2LCB0b2JqLnJlYWQoKSk7CisgICAgICAgIHVuZGVybHlpbmcudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9iai5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDM6IEluY29ycmVjdCBieXRlIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICBmaWxlU3RyaW5nLmdldEJ5dGVzKClbMF0sIHBpcy5yZWFkKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCRCSUkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBQdXNoYmFja0lucHV0U3RyZWFtIHRvYmo7CisgICAgICAgIGJ5dGVbXSBidWYgPSAoIjAxMjM0NTY3ODkwMTIzNDU2Nzg5IikuZ2V0Qnl0ZXMoKTsKKworICAgICAgICB0b2JqID0gbmV3IFB1c2hiYWNrSW5wdXRTdHJlYW0odW5kZXJseWluZyk7CisgICAgICAgIHRvYmoucmVhZChidWYsIDYsIDUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIHJlYWQhIiwgIkJFR0lOIiwgbmV3IFN0cmluZyhidWYsIDYsIDUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUb28gbXVjaCByZWFkISIsICIwMTIzNDVCRUdJTjEyMzQ1Njc4OSIsIG5ldyBTdHJpbmcoYnVmKSk7CisgICAgICAgIHVuZGVybHlpbmcudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9iai5yZWFkKGJ1ZiwgNiwgNSk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkJEJJSV9FeGNlcHRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBQdXNoYmFja0lucHV0U3RyZWFtIHRvYmo7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsxMF07CisKKyAgICAgICAgdG9iaiA9IG5ldyBQdXNoYmFja0lucHV0U3RyZWFtKHVuZGVybHlpbmcpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9iai5yZWFkKGJ1ZiwgLTEsIDEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRvYmoucmVhZChidWYsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2JqLnJlYWQoYnVmLCAxMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2tpcEooKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBQdXNoYmFja0lucHV0U3RyZWFtIHRvYmo7CisgICAgICAgIGJ5dGVbXSBidWYgPSAoIjAxMjM0NTY3ODkwMTIzNDU2Nzg5IikuZ2V0Qnl0ZXMoKTsKKworICAgICAgICB0b2JqID0gbmV3IFB1c2hiYWNrSW5wdXRTdHJlYW0odW5kZXJseWluZyk7CisgICAgICAgIHRvYmouc2tpcCg2KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIhIiwgMzAgLSA2LCB0b2JqLmF2YWlsYWJsZSgpKTsKKyAgICAgICAgdG9iai5za2lwKDEwMDAwMDApOworICAgICAgICB0b2JqLnNraXAoMTAwMDAwMCk7CisgICAgICAgIHVuZGVybHlpbmcudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9iai5za2lwKDEpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBsb25nIGphdmEuaW8uUHVzaGJhY2tJbnB1dFN0cmVhbS5za2lwKGxvbmcpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidWYgPSBuZXcgYnl0ZVs1MF07CisgICAgICAgICAgICBwaXMuc2tpcCg1MCk7CisgICAgICAgICAgICBwaXMucmVhZChidWYsIDAsIGJ1Zi5sZW5ndGgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiYSkgSW5jb3JyZWN0IGJ5dGVzIHJlYWQiLCBuZXcgU3RyaW5nKGJ1ZikKKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhmaWxlU3RyaW5nLnN1YnN0cmluZyg1MCwgMTAwKSkpOworICAgICAgICAgICAgcGlzLnVucmVhZChidWYpOworICAgICAgICAgICAgcGlzLnNraXAoMjUpOworICAgICAgICAgICAgYnl0ZVtdIGJ1ZjIgPSBuZXcgYnl0ZVsyNV07CisgICAgICAgICAgICBwaXMucmVhZChidWYyLCAwLCBidWYyLmxlbmd0aCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJiKSBJbmNvcnJlY3QgYnl0ZXMgcmVhZCIsIG5ldyBTdHJpbmcoYnVmMikKKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhmaWxlU3RyaW5nLnN1YnN0cmluZyg3NSwgMTAwKSkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdW5yZWFkJEIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBQdXNoYmFja0lucHV0U3RyZWFtIHRvYmo7CisgICAgICAgIFN0cmluZyBzdHIyID0gIjAxMjM0NTY3ODkiOworICAgICAgICBieXRlW10gYnVmMiA9IHN0cjIuZ2V0Qnl0ZXMoKTsKKyAgICAgICAgYnl0ZVtdIHJlYWRCdWYgPSBuZXcgYnl0ZVsxMF07CisKKyAgICAgICAgdG9iaiA9IG5ldyBQdXNoYmFja0lucHV0U3RyZWFtKHVuZGVybHlpbmcsIDEwKTsKKyAgICAgICAgdG9iai51bnJlYWQoYnVmMik7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyISIsIDMwICsgMTAsIHRvYmouYXZhaWxhYmxlKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9iai51bnJlYWQoYnVmMik7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRvYmoucmVhZChyZWFkQnVmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYnl0ZXMgcmVhZCIsIHN0cjIsIG5ldyBTdHJpbmcocmVhZEJ1ZikpOworICAgICAgICB1bmRlcmx5aW5nLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRvYmoucmVhZChidWYyKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLmlvLlB1c2hiYWNrSW5wdXRTdHJlYW0udW5yZWFkKGJ5dGUgW10pCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbMTAwXTsKKyAgICAgICAgICAgIHBpcy5yZWFkKGJ1ZiwgMCwgYnVmLmxlbmd0aCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgYnl0ZXMgcmVhZCIsIG5ldyBTdHJpbmcoYnVmKQorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKGZpbGVTdHJpbmcuc3Vic3RyaW5nKDAsIDEwMCkpKTsKKyAgICAgICAgICAgIHBpcy51bnJlYWQoYnVmKTsKKyAgICAgICAgICAgIHBpcy5yZWFkKGJ1ZiwgMCwgNTApOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIHVucmVhZCBieXRlcyIsIG5ldyBTdHJpbmcoYnVmLCAwLCA1MCkKKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhmaWxlU3RyaW5nLnN1YnN0cmluZygwLCA1MCkpKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gZHVyaW5nIHVucmVhZCB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdW5yZWFkJEJJSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFB1c2hiYWNrSW5wdXRTdHJlYW0gdG9iajsKKyAgICAgICAgU3RyaW5nIHN0cjIgPSAiMDEyMzQ1Njc4OSI7CisgICAgICAgIGJ5dGVbXSBidWYyID0gKHN0cjIgKyBzdHIyICsgc3RyMikuZ2V0Qnl0ZXMoKTsKKyAgICAgICAgYnl0ZVtdIHJlYWRCdWYgPSBuZXcgYnl0ZVsxMF07CisKKyAgICAgICAgdG9iaiA9IG5ldyBQdXNoYmFja0lucHV0U3RyZWFtKHVuZGVybHlpbmcsIDEwKTsKKyAgICAgICAgdG9iai51bnJlYWQoYnVmMiwgMTUsIDEwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIhIiwgMzAgKyAxMCwgdG9iai5hdmFpbGFibGUoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2JqLnVucmVhZChidWYyLCAxNSwgMTApOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0b2JqLnJlYWQocmVhZEJ1Zik7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGJ5dGVzIHJlYWQiLCAiNTY3ODkwMTIzNCIsIG5ldyBTdHJpbmcocmVhZEJ1ZikpOworICAgICAgICB1bmRlcmx5aW5nLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRvYmoucmVhZChidWYyLCAxNSwgMTApOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEuaW8uUHVzaGJhY2tJbnB1dFN0cmVhbS51bnJlYWQoYnl0ZSBbXSwgaW50LAorICAgICAgICAvLyBpbnQpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbMTAwXTsKKyAgICAgICAgICAgIHBpcy5yZWFkKGJ1ZiwgMCwgYnVmLmxlbmd0aCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgYnl0ZXMgcmVhZCIsIG5ldyBTdHJpbmcoYnVmKQorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKGZpbGVTdHJpbmcuc3Vic3RyaW5nKDAsIDEwMCkpKTsKKyAgICAgICAgICAgIHBpcy51bnJlYWQoYnVmLCA1MCwgNTApOworICAgICAgICAgICAgcGlzLnJlYWQoYnVmLCAwLCA1MCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gdW5yZWFkIGJ5dGVzIiwgbmV3IFN0cmluZyhidWYsIDAsIDUwKQorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKGZpbGVTdHJpbmcuc3Vic3RyaW5nKDUwLCAxMDApKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIGR1cmluZyB1bnJlYWQgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzEwXTsKKyAgICAgICAgICAgIHBpcy51bnJlYWQoYnVmLCAwLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbMTBdOworICAgICAgICAgICAgcGlzLnVucmVhZChidWYsIC0xLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgICAgICBwaXMudW5yZWFkKGJ1ZiwgMTAsIDEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VucmVhZEkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBQdXNoYmFja0lucHV0U3RyZWFtIHRvYmo7CisKKyAgICAgICAgdG9iaiA9IG5ldyBQdXNoYmFja0lucHV0U3RyZWFtKHVuZGVybHlpbmcpOworICAgICAgICB0b2JqLnVucmVhZCgyMyk7IC8vIFdoeSBkb2VzIHRoaXMgd29yaz8hPworICAgICAgICB0b2JqLnNraXAoMik7CisgICAgICAgIHRvYmoudW5yZWFkKDIzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIhIiwgMzAsIHRvYmouYXZhaWxhYmxlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIHJlYWQhIiwgMjMsIHRvYmoucmVhZCgpKTsKKyAgICAgICAgdG9iai51bnJlYWQoMTMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9iai51bnJlYWQoMTMpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93biAoQUNUVUFMTFkgTk9UIFNVUkUgV0hFVEhFUiBJVCBSRUFMTFkgTVVTVCBCRSBUSFJPV04hKS4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEuaW8uUHVzaGJhY2tJbnB1dFN0cmVhbS51bnJlYWQoaW50KQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IHg7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgYnl0ZSByZWFkIiwgKHggPSBwaXMucmVhZCgpKSA9PSBmaWxlU3RyaW5nCisgICAgICAgICAgICAgICAgICAgIC5nZXRCeXRlcygpWzBdKTsKKyAgICAgICAgICAgIHBpcy51bnJlYWQoeCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gdW5yZWFkIiwgcGlzLnJlYWQoKSA9PSB4KTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gZHVyaW5nIHJlYWQgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKworICAgICAgICBwaXMgPSBuZXcgUHVzaGJhY2tJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZmlsZVN0cmluZworICAgICAgICAgICAgICAgIC5nZXRCeXRlcygpKSwgNjU1MzUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGlzLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIGR1cmluZyB0ZWFyRG93biA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZFB1c2hiYWNrUmVhZGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRQdXNoYmFja1JlYWRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNGY1YWI2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRQdXNoYmFja1JlYWRlclRlc3QuamF2YQpAQCAtMCwwICsxLDM4NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUHVzaGJhY2tSZWFkZXI7CitpbXBvcnQgamF2YS5pby5TdHJpbmdSZWFkZXI7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0FTaW1wbGVSZWFkZXI7CisKK3B1YmxpYyBjbGFzcyBPbGRQdXNoYmFja1JlYWRlclRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgU3VwcG9ydF9BU2ltcGxlUmVhZGVyIHVuZGVybHlpbmcgPSBuZXcgU3VwcG9ydF9BU2ltcGxlUmVhZGVyKCk7CisgICAgUHVzaGJhY2tSZWFkZXIgcGJyOworCisgICAgU3RyaW5nIHBiU3RyaW5nID0gIkhlbGxvIFdvcmxkIjsKKworICAgIC8qKgorICAgICAqIGphdmEuaW8uUHVzaGJhY2tSZWFkZXIjUHVzaGJhY2tSZWFkZXIoamF2YS5pby5SZWFkZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX1JlYWRlcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEuaW8uUHVzaGJhY2tSZWFkZXIoamF2YS5pby5SZWFkZXIpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYnIuY2xvc2UoKTsKKyAgICAgICAgICAgIHBiciA9IG5ldyBQdXNoYmFja1JlYWRlcihuZXcgU3RyaW5nUmVhZGVyKHBiU3RyaW5nKSk7CisgICAgICAgICAgICBjaGFyIGJ1ZltdID0gbmV3IGNoYXJbNV07CisgICAgICAgICAgICBwYnIucmVhZChidWYsIDAsIDUpOworICAgICAgICAgICAgcGJyLnVucmVhZChidWYpOworICAgICAgICAgICAgZmFpbCgiQ3JlYXRlZCByZWFkZXIgd2l0aCBidWZmZXIgbGFyZ2VyIHRoYW4gMSIpOzsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYnIgPSBuZXcgUHVzaGJhY2tSZWFkZXIobnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEVYcGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLlB1c2hiYWNrUmVhZGVyI1B1c2hiYWNrUmVhZGVyKGphdmEuaW8uUmVhZGVyLCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX1JlYWRlckkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBQdXNoYmFja1JlYWRlciB0b2JqOworCisgICAgICAgIHRvYmogPSBuZXcgUHVzaGJhY2tSZWFkZXIodW5kZXJseWluZywgMTAwMDApOworICAgICAgICB0b2JqID0gbmV3IFB1c2hiYWNrUmVhZGVyKHVuZGVybHlpbmcsIDEpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2JqID0gbmV3IFB1c2hiYWNrUmVhZGVyKHVuZGVybHlpbmcsIC0xKTsKKyAgICAgICAgICAgIHRvYmouY2xvc2UoKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2JqID0gbmV3IFB1c2hiYWNrUmVhZGVyKHVuZGVybHlpbmcsIDApOworICAgICAgICAgICAgdG9iai5jbG9zZSgpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLlB1c2hiYWNrUmVhZGVyI2Nsb3NlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUHVzaGJhY2tSZWFkZXIgdG9iajsKKworICAgICAgICB0b2JqID0gbmV3IFB1c2hiYWNrUmVhZGVyKHVuZGVybHlpbmcpOworICAgICAgICB0b2JqLmNsb3NlKCk7CisgICAgICAgIHRvYmouY2xvc2UoKTsKKyAgICAgICAgdG9iaiA9IG5ldyBQdXNoYmFja1JlYWRlcih1bmRlcmx5aW5nKTsKKyAgICAgICAgdW5kZXJseWluZy50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2JqLmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5QdXNoYmFja1JlYWRlciNtYXJrU3VwcG9ydGVkKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X21hcmtTdXBwb3J0ZWQoKSB7CisgICAgICAgIGFzc2VydEZhbHNlKCJUZXN0IDE6IG1hcmtTdXBwb3J0ZWQoKSBtdXN0IHJldHVybiBmYWxzZS4iLAorICAgICAgICAgICAgICAgIHBici5tYXJrU3VwcG9ydGVkKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uUHVzaGJhY2tSZWFkZXIjcmVhZCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUHVzaGJhY2tSZWFkZXIgdG9iajsKKworICAgICAgICB0b2JqID0gbmV3IFB1c2hiYWNrUmVhZGVyKHVuZGVybHlpbmcpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIHJlYWQhIiwgNjYsIHRvYmoucmVhZCgpKTsKKyAgICAgICAgdW5kZXJseWluZy50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2JqLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLlB1c2hiYWNrUmVhZGVyI3JlYWQoY2hhcltdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWQkQ0lJKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUHVzaGJhY2tSZWFkZXIgdG9iajsKKyAgICAgICAgY2hhcltdIGJ1ZiA9ICgiMDEyMzQ1Njc4OTAxMjM0NTY3ODkiKS50b0NoYXJBcnJheSgpOworCisgICAgICAgIHRvYmogPSBuZXcgUHVzaGJhY2tSZWFkZXIodW5kZXJseWluZyk7CisgICAgICAgIHRvYmoucmVhZChidWYsIDYsIDUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIHJlYWQhIiwgIkJFR0lOIiwgbmV3IFN0cmluZyhidWYsIDYsIDUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUb28gbXVjaCByZWFkISIsICIwMTIzNDVCRUdJTjEyMzQ1Njc4OSIsIG5ldyBTdHJpbmcoYnVmKSk7CisgICAgICAgIHVuZGVybHlpbmcudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9iai5yZWFkKGJ1ZiwgNiwgNSk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLmlvLlB1c2hiYWNrUmVhZGVyLnJlYWQoY2hhciBbXSwgaW50LCBpbnQpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGFyW10gYyA9IG5ldyBjaGFyWzVdOworICAgICAgICAgICAgcGJyLnJlYWQoYywgMCwgNSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gcmVhZCBjaGFycyIsIG5ldyBTdHJpbmcoYykuZXF1YWxzKHBiU3RyaW5nCisgICAgICAgICAgICAgICAgICAgIC5zdWJzdHJpbmcoMCwgNSkpKTsKKworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHBici5yZWFkKGMsIDAsIDApKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjLmxlbmd0aCwgcGJyLnJlYWQoYywgMCwgYy5sZW5ndGgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBwYnIucmVhZChjLCBjLmxlbmd0aCwgMCkpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBkdXJpbmcgcmVhZCB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uUHVzaGJhY2tSZWFkZXIjcmVhZChjaGFyW10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZF8kQ0lJX0V4Y2VwdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHBiciA9IG5ldyBQdXNoYmFja1JlYWRlcihuZXcgU3RyaW5nUmVhZGVyKHBiU3RyaW5nKSwgMTApOworCisgICAgICAgIGNoYXJbXSBudWxsQ2hhckFycmF5ID0gbnVsbDsKKyAgICAgICAgY2hhcltdIGNoYXJBcnJheSA9IG5ldyBjaGFyWzEwXTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGJyLnJlYWQobnVsbENoYXJBcnJheSwgMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYnIucmVhZChjaGFyQXJyYXksIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYnIucmVhZChjaGFyQXJyYXksIC0xLCAwKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYnIucmVhZChjaGFyQXJyYXksIGNoYXJBcnJheS5sZW5ndGggKyAxLCAwKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYnIucmVhZChjaGFyQXJyYXksIGNoYXJBcnJheS5sZW5ndGgsIDEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBici5yZWFkKGNoYXJBcnJheSwgMSwgY2hhckFycmF5Lmxlbmd0aCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGJyLnJlYWQoY2hhckFycmF5LCAwLCBjaGFyQXJyYXkubGVuZ3RoICsgMSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBwYnIuY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGJyLnJlYWQoY2hhckFycmF5LCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJT0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5QdXNoYmFja1JlYWRlciNyZWFkeSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFB1c2hiYWNrUmVhZGVyIHRvYmo7CisKKyAgICAgICAgdG9iaiA9IG5ldyBQdXNoYmFja1JlYWRlcih1bmRlcmx5aW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGJlIHJlYWR5ISIsIHRvYmoucmVhZHkoKSk7CisgICAgICAgIHVuZGVybHlpbmcudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9iai5yZWFkeSgpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLlB1c2hiYWNrUmVhZGVyI3VucmVhZChjaGFyW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF91bnJlYWQkQygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFB1c2hiYWNrUmVhZGVyIHRvYmo7CisgICAgICAgIFN0cmluZyBzdHIyID0gIjAxMjM0NTY3ODkiOworICAgICAgICBjaGFyW10gYnVmMiA9IHN0cjIudG9DaGFyQXJyYXkoKTsKKyAgICAgICAgY2hhcltdIHJlYWRCdWYgPSBuZXcgY2hhclsxMF07CisKKyAgICAgICAgdG9iaiA9IG5ldyBQdXNoYmFja1JlYWRlcih1bmRlcmx5aW5nLCAxMCk7CisgICAgICAgIHRvYmoudW5yZWFkKGJ1ZjIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9iai51bnJlYWQoYnVmMik7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRvYmoucmVhZChyZWFkQnVmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYnl0ZXMgcmVhZCIsIHN0cjIsIG5ldyBTdHJpbmcocmVhZEJ1ZikpOworICAgICAgICB1bmRlcmx5aW5nLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRvYmoucmVhZChidWYyKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLmlvLlB1c2hiYWNrUmVhZGVyLnVucmVhZChjaGFyIFtdKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY2hhcltdIGMgPSBuZXcgY2hhcls1XTsKKyAgICAgICAgICAgIHBici5yZWFkKGMsIDAsIDUpOworICAgICAgICAgICAgcGJyLnVucmVhZChjKTsKKyAgICAgICAgICAgIHBici5yZWFkKGMsIDAsIDUpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIHVucmVhZCBjaGFycyIsIG5ldyBTdHJpbmcoYykuZXF1YWxzKHBiU3RyaW5nCisgICAgICAgICAgICAgICAgICAgIC5zdWJzdHJpbmcoMCwgNSkpKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gZHVyaW5nIHJlYWQgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogamF2YS5pby5QdXNoYmFja1JlYWRlciNza2lwKGxvbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9za2lwJEooKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBQdXNoYmFja1JlYWRlciB0b2JqOworCisgICAgICAgIHRvYmogPSBuZXcgUHVzaGJhY2tSZWFkZXIodW5kZXJseWluZyk7CisgICAgICAgIHRvYmouc2tpcCg2KTsKKyAgICAgICAgdG9iai5za2lwKDEwMDAwMDApOworICAgICAgICB0b2JqLnNraXAoMTAwMDAwMCk7CisgICAgICAgIHVuZGVybHlpbmcudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9iai5za2lwKDEpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uUHVzaGJhY2tSZWFkZXIjdW5yZWFkKGNoYXJbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF91bnJlYWQkQ0lJKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUHVzaGJhY2tSZWFkZXIgdG9iajsKKyAgICAgICAgU3RyaW5nIHN0cjIgPSAiMDEyMzQ1Njc4OSI7CisgICAgICAgIGNoYXJbXSBidWYyID0gKHN0cjIgKyBzdHIyICsgc3RyMikudG9DaGFyQXJyYXkoKTsKKyAgICAgICAgY2hhcltdIHJlYWRCdWYgPSBuZXcgY2hhclsxMF07CisKKyAgICAgICAgdG9iaiA9IG5ldyBQdXNoYmFja1JlYWRlcih1bmRlcmx5aW5nLCAxMCk7CisgICAgICAgIHRvYmoudW5yZWFkKGJ1ZjIsIDE1LCAxMCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2JqLnVucmVhZChidWYyLCAxNSwgMTApOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0b2JqLnJlYWQocmVhZEJ1Zik7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGJ5dGVzIHJlYWQiLCAiNTY3ODkwMTIzNCIsIG5ldyBTdHJpbmcocmVhZEJ1ZikpOworICAgICAgICB1bmRlcmx5aW5nLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRvYmoucmVhZChidWYyLCAxNSwgMTApOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdW5yZWFkXyRDSUlfQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy9hIHB1c2hiYWNrIHJlYWRlciB3aXRoIG9uZSBjaGFyYWN0ZXIgYnVmZmVyCisgICAgICAgIHBiciA9IG5ldyBQdXNoYmFja1JlYWRlcihuZXcgU3RyaW5nUmVhZGVyKHBiU3RyaW5nKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYnIudW5yZWFkKG5ldyBjaGFyW3BiU3RyaW5nLmxlbmd0aCgpXSwgMCAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYnIudW5yZWFkKG5ldyBjaGFyWzEwXSwgMTAgLCAxKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5QdXNoYmFja1JlYWRlciN1bnJlYWQoaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdW5yZWFkSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFB1c2hiYWNrUmVhZGVyIHRvYmo7CisKKyAgICAgICAgdG9iaiA9IG5ldyBQdXNoYmFja1JlYWRlcih1bmRlcmx5aW5nKTsKKyAgICAgICAgdG9iai51bnJlYWQoMjMpOyAvLyBXaHkgZG9lcyB0aGlzIHdvcms/IT8KKyAgICAgICAgdG9iai5za2lwKDIpOworICAgICAgICB0b2JqLnVucmVhZCgyMyk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgcmVhZCEiLCAyMywgdG9iai5yZWFkKCkpOworICAgICAgICB0b2JqLnVucmVhZCgxMyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2JqLnVucmVhZCgxMyk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBub3QgdGhyb3duIChBQ1RVQUxMWSBOT1QgU1VSRSBXSEVUSEVSIElUIFJFQUxMWSBNVVNUIEJFIFRIUk9XTiEpLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIHBiciA9IG5ldyBQdXNoYmFja1JlYWRlcihuZXcgU3RyaW5nUmVhZGVyKHBiU3RyaW5nKSwgMTApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGJyLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkUmFuZG9tQWNjZXNzRmlsZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkUmFuZG9tQWNjZXNzRmlsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZTM2MGNjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRSYW5kb21BY2Nlc3NGaWxlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTIxMCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLkVPRkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlOworCitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuTm9uV3JpdGFibGVDaGFubmVsRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgT2xkUmFuZG9tQWNjZXNzRmlsZVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgcHVibGljIFN0cmluZyBmaWxlTmFtZTsKKworICAgIHB1YmxpYyBib29sZWFuIHVmaWxlID0gdHJ1ZTsKKworICAgIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSByYWY7CisKKyAgICBqYXZhLmlvLkZpbGUgZjsKKworICAgIFN0cmluZyB1bmlodyA9ICJcdTAwNDhcdTAwNjVcdTAwNkNcdTA4MDFcdTAwNkNcdTAwNkZcdTAwMjBcdTAwNTdcdTAwODFcdTAwNkZcdTAwNzJcdTAwNkNcdTAwNjQiOworCisgICAgc3RhdGljIGZpbmFsIFN0cmluZyB0ZXN0U3RyaW5nID0gIkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LFxuIiArCisgICAgImNvbnNlY3RldHVyIGFkaXBpc2ljaW5nIGVsaXQsXG5zZWQgZG8gZWl1c21vZCB0ZW1wb3IgaW5jaWRpZHVudCB1dCIgKworICAgICJsYWJvcmUgZXQgZG9sb3JlIG1hZ25hIGFsaXF1YS5cbiI7CisgICAgc3RhdGljIGZpbmFsIGludCB0ZXN0TGVuZ3RoID0gdGVzdFN0cmluZy5sZW5ndGgoKTsKKworICAgIC8qKgorICAgICAqIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSNSYW5kb21BY2Nlc3NGaWxlKGphdmEuaW8uRmlsZSwKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fRmlsZUxqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFJhbmRvbUFjY2Vzc0ZpbGUgcmFmID0gbnVsbDsKKyAgICAgICAgRmlsZSB0bXBGaWxlID0gbmV3IEZpbGUoZmlsZU5hbWUpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYWYgPSBuZXcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlKHRtcEZpbGUsICJyIik7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBVbmV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRtcEZpbGUuY3JlYXRlTmV3RmlsZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBDaGVja2luZyB0aGUgcmVtYWluaW5nIHZhbGlkIG1vZGUgcGFyYW1ldGVycy4KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmFmID0gbmV3IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSh0bXBGaWxlLCAicndkIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogVW5leHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByYWYuY2xvc2UoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmFmID0gbmV3IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSh0bXBGaWxlLCAicndzIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogVW5leHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByYWYuY2xvc2UoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmFmID0gbmV3IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSh0bXBGaWxlLCAicnciKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVGVzdCA1OiBVbmV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJhZi5jbG9zZSgpOworCisgICAgICAgICAgICAvLyBDaGVja2luZyBhbiBpbnZhbGlkIG1vZGUgcGFyYW1ldGVyLgorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByYWYgPSBuZXcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlKHRtcEZpbGUsICJpIik7CisgICAgICAgICAgICAgICAgZmFpbCgiVGVzdCA2OiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHJhZiAhPSBudWxsICkgcmFmLmNsb3NlKCk7CisgICAgICAgICAgICB0bXBGaWxlLmRlbGV0ZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI1JhbmRvbUFjY2Vzc0ZpbGUoamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZygpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBSYW5kb21BY2Nlc3NGaWxlIHJhZiA9IG51bGw7CisgICAgICAgIEZpbGUgdG1wRmlsZSA9IG5ldyBGaWxlKGZpbGVOYW1lKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmID0gbmV3IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZShmaWxlTmFtZSwgInIiKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IFVuZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIENoZWNraW5nIHRoZSByZW1haW5pbmcgdmFsaWQgbW9kZSBwYXJhbWV0ZXJzLgorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByYWYgPSBuZXcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlKGZpbGVOYW1lLCAicndkIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogVW5leHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByYWYuY2xvc2UoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmFmID0gbmV3IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZShmaWxlTmFtZSwgInJ3cyIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IFVuZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmFmLmNsb3NlKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJhZiA9IG5ldyBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUoZmlsZU5hbWUsICJydyIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IFVuZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmFmLmNsb3NlKCk7CisKKyAgICAgICAgICAgIC8vIENoZWNraW5nIGFuIGludmFsaWQgbW9kZSBwYXJhbWV0ZXIuCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJhZiA9IG5ldyBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUoZmlsZU5hbWUsICJpIik7CisgICAgICAgICAgICAgICAgZmFpbCgiVGVzdCA2OiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBDaGVja2luZyBmb3IgTm9Xcml0YWJsZUNoYW5uZWxFeGNlcHRpb24uCisgICAgICAgICAgICByYWYgPSBuZXcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlKGZpbGVOYW1lLCAiciIpOworICAgICAgICAgICAgRmlsZUNoYW5uZWwgZmNyID0gcmFmLmdldENoYW5uZWwoKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmY3IubG9jaygwTCwgTG9uZy5NQVhfVkFMVUUsIGZhbHNlKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJUZXN0IDc6IE5vbldyaXRhYmxlQ2hhbm5lbEV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vbldyaXRhYmxlQ2hhbm5lbEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgICAgICB9CisKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChyYWYgIT0gbnVsbCApIHJhZi5jbG9zZSgpOworICAgICAgICAgICAgaWYgKHRtcEZpbGUuZXhpc3RzKCkpIHRtcEZpbGUuZGVsZXRlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUjY2xvc2UoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvc2UoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZS5jbG9zZSgpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSYW5kb21BY2Nlc3NGaWxlIHJhZiA9IG5ldyBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUoZmlsZU5hbWUsICJydyIpOworICAgICAgICAgICAgcmFmLmNsb3NlKCk7CisgICAgICAgICAgICByYWYud3JpdGUoIlRlc3QiLmdldEJ5dGVzKCksIDAsIDQpOworICAgICAgICAgICAgZmFpbCgiRmFpbGVkIHRvIGNsb3NlIGZpbGUgcHJvcGVybHkuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHt9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI2dldENoYW5uZWwoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Q2hhbm5lbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgUmFuZG9tQWNjZXNzRmlsZSByYWYgPSBuZXcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlKGZpbGVOYW1lLCAicnciKTsKKyAgICAgICAgRmlsZUNoYW5uZWwgZmMgPSByYWYuZ2V0Q2hhbm5lbCgpOworCisgICAgICAgIC8vIEluZGlyZWN0IHRlc3Q6IElmIHRoZSBmaWxlJ3MgZmlsZSBwb2ludGVyIG1vdmVzIHRoZW4gdGhlIHBvc2l0aW9uCisgICAgICAgIC8vIGluIHRoZSBjaGFubmVsIGhhcyB0byBtb3ZlIGFjY29yZGluZ2x5LgorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IENoYW5uZWwgcG9zaXRpb24gZXhwZWN0ZWQgdG8gYmUgMC4iLCBmYy5wb3NpdGlvbigpID09IDApOworCisgICAgICAgIHJhZi53cml0ZSh0ZXN0U3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMjogVW5leHBlY3RlZCBjaGFubmVsIHBvc2l0aW9uLiIsCisgICAgICAgICAgICAgICAgdGVzdExlbmd0aCwgZmMucG9zaXRpb24oKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMzogQ2hhbm5lbCBwb3NpdGlvbiBpcyBub3QgZXF1YWwgdG8gZmlsZSBwb2ludGVyLiIsCisgICAgICAgICAgICAgICAgZmMucG9zaXRpb24oKSA9PSByYWYuZ2V0RmlsZVBvaW50ZXIoKSk7CisgICAgICAgIHJhZi5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSNnZXRGRCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRGRCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yCisgICAgICAgIC8vIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZS5nZXRGRCgpCisKKyAgICAgICAgUmFuZG9tQWNjZXNzRmlsZSByYWYgPSBuZXcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlKGZpbGVOYW1lLCAicnciKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBSZXR1cm5lZCBpbnZhbGlkIGZkLiIsIHJhZi5nZXRGRCgpLnZhbGlkKCkpOworCisgICAgICAgIHJhZi5jbG9zZSgpOworICAgICAgICBhc3NlcnRGYWxzZSgiVGVzdCAyOiBSZXR1cm5lZCB2YWxpZCBmZCBhZnRlciBjbG9zZSIsIHJhZi5nZXRGRCgpLnZhbGlkKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSNnZXRGaWxlUG9pbnRlcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRGaWxlUG9pbnRlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBsb25nIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZS5nZXRGaWxlUG9pbnRlcigpCisgICAgICAgIFJhbmRvbUFjY2Vzc0ZpbGUgcmFmID0gbmV3IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZShmaWxlTmFtZSwgInJ3Iik7CisgICAgICAgIHJhZi53cml0ZSh0ZXN0U3RyaW5nLmdldEJ5dGVzKCksIDAsIHRlc3RMZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IGZpbGVQb2ludGVyIHJldHVybmVkLiAiLCB0ZXN0TGVuZ3RoLCByYWYKKyAgICAgICAgICAgICAgICAuZ2V0RmlsZVBvaW50ZXIoKSk7CisgICAgICAgIHJhZi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLmdldEZpbGVQb2ludGVyKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSNsZW5ndGgoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGVuZ3RoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGxvbmcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlLmxlbmd0aCgpCisgICAgICAgIFJhbmRvbUFjY2Vzc0ZpbGUgcmFmID0gbmV3IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZShmaWxlTmFtZSwgInJ3Iik7CisgICAgICAgIHJhZi53cml0ZSh0ZXN0U3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IGxlbmd0aCByZXR1cm5lZC4gIiwgdGVzdExlbmd0aCwKKyAgICAgICAgICAgICAgICByYWYubGVuZ3RoKCkpOworICAgICAgICByYWYuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5sZW5ndGgoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI3JlYWQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZF93cml0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBpOworICAgICAgICBieXRlW10gdGVzdEJ1ZiA9IHRlc3RTdHJpbmcuZ2V0Qnl0ZXMoKTsKKyAgICAgICAgUmFuZG9tQWNjZXNzRmlsZSByYWYgPSBuZXcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlKGZpbGVOYW1lLCAicnciKTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IHRlc3RTdHJpbmcubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByYWYud3JpdGUodGVzdEJ1ZltpXSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogVW5leHBlY3RlZCBleGNlcHRpb24gd2hpbGUgd3JpdGluZzogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByYWYuc2VlaygwKTsKKworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGVzdFN0cmluZy5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoU3RyaW5nLmZvcm1hdCgiVGVzdCAyOiBJbmNvcnJlY3QgdmFsdWUgd3JpdHRlbiBvciByZWFkIGF0IGluZGV4ICVkOyAiLCBpKSwKKyAgICAgICAgICAgICAgICAgICAgdGVzdEJ1ZltpXSwgcmFmLnJlYWQoKSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDM6IEVuZCBvZiBmaWxlIGluZGljYXRvciAoLTEpIGV4cGVjdGVkLiIsIHJhZi5yZWFkKCkgPT0gLTEpOworCisgICAgICAgIHJhZi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLndyaXRlKDQyKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYWYucmVhZCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA1OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUjcmVhZChieXRlW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkJEIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIGZvcyA9IG5ldyBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW0oZmlsZU5hbWUpOworICAgICAgICBmb3Mud3JpdGUodGVzdFN0cmluZy5nZXRCeXRlcygpLCAwLCB0ZXN0TGVuZ3RoKTsKKyAgICAgICAgZm9zLmNsb3NlKCk7CisKKyAgICAgICAgUmFuZG9tQWNjZXNzRmlsZSByYWYgPSBuZXcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlKGZpbGVOYW1lLCAiciIpOworICAgICAgICBieXRlW10gcmJ1ZiA9IG5ldyBieXRlW3Rlc3RMZW5ndGggKyAxMF07CisKKyAgICAgICAgaW50IGJ5dGVzUmVhZCA9IHJhZi5yZWFkKHJidWYpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IG51bWJlciBvZiBieXRlcyByZWFkLiAiLAorICAgICAgICAgICAgICAgIHRlc3RMZW5ndGgsIGJ5dGVzUmVhZCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBJbmNvcnJlY3QgYnl0ZXMgcmVhZC4gIiwgdGVzdFN0cmluZywKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKHJidWYsIDAsIHRlc3RMZW5ndGgpKTsKKworICAgICAgICBieXRlc1JlYWQgPSByYWYucmVhZChyYnVmKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAzOiBFT0YgKC0xKSBleHBlY3RlZC4gIiwgYnl0ZXNSZWFkID09IC0xKTsKKworICAgICAgICByYWYuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ5dGVzUmVhZCA9IHJhZi5yZWFkKHJidWYpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUjcmVhZChieXRlW10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCRCSUkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgYnl0ZXNSZWFkOworICAgICAgICBSYW5kb21BY2Nlc3NGaWxlIHJhZiA9IG5ldyBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUoZmlsZU5hbWUsICJydyIpOworICAgICAgICBieXRlW10gcmJ1ZiA9IG5ldyBieXRlWzQwMDBdOworCisgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gZm9zID0gbmV3IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbShmaWxlTmFtZSk7CisgICAgICAgIGZvcy53cml0ZSh0ZXN0U3RyaW5nLmdldEJ5dGVzKCksIDAsIHRlc3RMZW5ndGgpOworICAgICAgICBmb3MuY2xvc2UoKTsKKworICAgICAgICAvLyBSZWFkIGhhbGYgb2YgdGhlIGZpbGUgY29udGVudHMuCisgICAgICAgIGJ5dGVzUmVhZCA9IHJhZi5yZWFkKHJidWYsIDEwLCB0ZXN0TGVuZ3RoIC8gMik7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuICIsCisgICAgICAgICAgICAgICAgdGVzdExlbmd0aCAvIDIsIGJ5dGVzUmVhZCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBJbmNvcnJlY3QgYnl0ZXMgcmVhZC4gIiwKKyAgICAgICAgICAgICAgICB0ZXN0U3RyaW5nLnN1YnN0cmluZygwLCB0ZXN0TGVuZ3RoIC8gMiksCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZyhyYnVmLCAxMCwgdGVzdExlbmd0aCAvIDIpKTsKKworICAgICAgICAvLyBSZWFkIHRoZSByZXN0IG9mIHRoZSBmaWxlIGNvbnRlbnRzLgorICAgICAgICBieXRlc1JlYWQgPSByYWYucmVhZChyYnVmLCAwLCB0ZXN0TGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDM6IEluY29ycmVjdCBudW1iZXIgb2YgYnl0ZXMgcmVhZC4gIiwKKyAgICAgICAgICAgICAgICB0ZXN0TGVuZ3RoIC0gKHRlc3RMZW5ndGggLyAyKSwgYnl0ZXNSZWFkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDQ6IEluY29ycmVjdCBieXRlcyByZWFkLiAiLAorICAgICAgICAgICAgICAgIHRlc3RTdHJpbmcuc3Vic3RyaW5nKHRlc3RMZW5ndGggLyAyLCAodGVzdExlbmd0aCAvIDIpICsgYnl0ZXNSZWFkKSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKHJidWYsIDAsIGJ5dGVzUmVhZCkpOworCisgICAgICAgIC8vIFRyeSB0byByZWFkIGV2ZW4gbW9yZS4KKyAgICAgICAgYnl0ZXNSZWFkID0gcmFmLnJlYWQocmJ1ZiwgMCwgMSk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgNTogRU9GICgtMSkgZXhwZWN0ZWQuICIsIGJ5dGVzUmVhZCA9PSAtMSk7CisKKyAgICAgICAgLy8gSWxsZWdhbCBwYXJhbWV0ZXIgdmFsdWUgdGVzdHMuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYWYucmVhZChyYnVmLCAtMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDY6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkKHJidWYsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNzogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnJlYWQocmJ1ZiwgMjAwMCwgMjAwMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDg6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICAvLyBJT0V4Y2VwdGlvbiB0ZXN0LgorICAgICAgICByYWYuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ5dGVzUmVhZCA9IHJhZi5yZWFkKHJidWYsIDAsIDEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA5OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUjcmVhZEJvb2xlYW4oKQorICAgICAqIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSN3cml0ZUJvb2xlYW4oYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfd3JpdGVCb29sZWFuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUmFuZG9tQWNjZXNzRmlsZSByYWYgPSBuZXcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlKGZpbGVOYW1lLCAicnciKTsKKyAgICAgICAgcmFmLndyaXRlQm9vbGVhbih0cnVlKTsKKyAgICAgICAgcmFmLndyaXRlQm9vbGVhbihmYWxzZSk7CisgICAgICAgIHJhZi5zZWVrKDApOworCisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgdmFsdWUgd3JpdHRlbiBvciByZWFkOyIsCisgICAgICAgICAgICAgICAgdHJ1ZSwgcmFmLnJlYWRCb29sZWFuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMjogSW5jb3JyZWN0IHZhbHVlIHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIGZhbHNlLCByYWYucmVhZEJvb2xlYW4oKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkQm9vbGVhbigpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBFT0ZFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHJhZi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLndyaXRlQm9vbGVhbihmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnJlYWRCb29sZWFuKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSNyZWFkQnl0ZSgpCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI3dyaXRlQnl0ZShieXRlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZF93cml0ZUJ5dGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBSYW5kb21BY2Nlc3NGaWxlIHJhZiA9IG5ldyBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUoZmlsZU5hbWUsICJydyIpOworICAgICAgICByYWYud3JpdGVCeXRlKEJ5dGUuTUlOX1ZBTFVFKTsKKyAgICAgICAgcmFmLndyaXRlQnl0ZSgxMSk7CisgICAgICAgIHJhZi53cml0ZUJ5dGUoQnl0ZS5NQVhfVkFMVUUpOworICAgICAgICByYWYud3JpdGVCeXRlKEJ5dGUuTUlOX1ZBTFVFIC0gMSk7CisgICAgICAgIHJhZi53cml0ZUJ5dGUoQnl0ZS5NQVhfVkFMVUUgKyAxKTsKKyAgICAgICAgcmFmLnNlZWsoMCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCB2YWx1ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICBCeXRlLk1JTl9WQUxVRSwgcmFmLnJlYWRCeXRlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMjogSW5jb3JyZWN0IHZhbHVlIHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIDExLCByYWYucmVhZEJ5dGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAzOiBJbmNvcnJlY3QgdmFsdWUgd3JpdHRlbiBvciByZWFkOyIsCisgICAgICAgICAgICAgICAgQnl0ZS5NQVhfVkFMVUUsIHJhZi5yZWFkQnl0ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDQ6IEluY29ycmVjdCB2YWx1ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICAxMjcsIHJhZi5yZWFkQnl0ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDU6IEluY29ycmVjdCB2YWx1ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICAtMTI4LCByYWYucmVhZEJ5dGUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkQnl0ZSgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA2OiBFT0ZFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHJhZi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLndyaXRlQnl0ZSgxMyk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDc6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnJlYWRCeXRlKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDg6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSNyZWFkQ2hhcigpCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI3dyaXRlQ2hhcihjaGFyKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZF93cml0ZUNoYXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBSYW5kb21BY2Nlc3NGaWxlIHJhZiA9IG5ldyBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUoZmlsZU5hbWUsICJydyIpOworICAgICAgICByYWYud3JpdGVDaGFyKENoYXJhY3Rlci5NSU5fVkFMVUUpOworICAgICAgICByYWYud3JpdGVDaGFyKCdUJyk7CisgICAgICAgIHJhZi53cml0ZUNoYXIoQ2hhcmFjdGVyLk1BWF9WQUxVRSk7CisgICAgICAgIHJhZi53cml0ZUNoYXIoQ2hhcmFjdGVyLk1JTl9WQUxVRSAtIDEpOworICAgICAgICByYWYud3JpdGVDaGFyKENoYXJhY3Rlci5NQVhfVkFMVUUgKyAxKTsKKyAgICAgICAgcmFmLnNlZWsoMCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCB2YWx1ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICBDaGFyYWN0ZXIuTUlOX1ZBTFVFLCByYWYucmVhZENoYXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBJbmNvcnJlY3QgdmFsdWUgd3JpdHRlbiBvciByZWFkOyIsCisgICAgICAgICAgICAgICAgJ1QnLCByYWYucmVhZENoYXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAzOiBJbmNvcnJlY3QgdmFsdWUgd3JpdHRlbiBvciByZWFkOyIsCisgICAgICAgICAgICAgICAgQ2hhcmFjdGVyLk1BWF9WQUxVRSwgcmFmLnJlYWRDaGFyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNDogSW5jb3JyZWN0IHZhbHVlIHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIDB4ZmZmZiwgcmFmLnJlYWRDaGFyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNTogSW5jb3JyZWN0IHZhbHVlIHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIDAsIHJhZi5yZWFkQ2hhcigpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnJlYWRDaGFyKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDY6IEVPRkV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgcmFmLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYWYud3JpdGVDaGFyKCdFJyk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDc6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnJlYWRDaGFyKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDg6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSNyZWFkRG91YmxlKCkKKyAgICAgKiBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUjd3JpdGVEb3VibGUoZG91YmxlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZF93cml0ZURvdWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFJhbmRvbUFjY2Vzc0ZpbGUgcmFmID0gbmV3IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZShmaWxlTmFtZSwgInJ3Iik7CisgICAgICAgIHJhZi53cml0ZURvdWJsZShEb3VibGUuTUFYX1ZBTFVFKTsKKyAgICAgICAgcmFmLndyaXRlRG91YmxlKDQyNDI0Mi40MjQyKTsKKyAgICAgICAgcmFmLnNlZWsoMCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCB2YWx1ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICBEb3VibGUuTUFYX1ZBTFVFLCByYWYucmVhZERvdWJsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IEluY29ycmVjdCB2YWx1ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICA0MjQyNDIuNDI0MiwgcmFmLnJlYWREb3VibGUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkRG91YmxlKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IEVPRkV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgcmFmLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYWYud3JpdGVEb3VibGUoRG91YmxlLk1JTl9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnJlYWREb3VibGUoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI3JlYWRGbG9hdCgpCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI3dyaXRlRmxvYXQoZG91YmxlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZF93cml0ZUZsb2F0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUmFuZG9tQWNjZXNzRmlsZSByYWYgPSBuZXcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlKGZpbGVOYW1lLCAicnciKTsKKyAgICAgICAgcmFmLndyaXRlRmxvYXQoRmxvYXQuTUFYX1ZBTFVFKTsKKyAgICAgICAgcmFmLndyaXRlRmxvYXQoNTU1LjU1Zik7CisgICAgICAgIHJhZi5zZWVrKDApOworCisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgdmFsdWUgd3JpdHRlbiBvciByZWFkLiAiLAorICAgICAgICAgICAgICAgIEZsb2F0Lk1BWF9WQUxVRSwgcmFmLnJlYWRGbG9hdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IEluY29ycmVjdCB2YWx1ZSB3cml0dGVuIG9yIHJlYWQuICIsCisgICAgICAgICAgICAgICAgNTU1LjU1ZiwgcmFmLnJlYWRGbG9hdCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnJlYWRGbG9hdCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBFT0ZFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHJhZi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLndyaXRlRmxvYXQoRmxvYXQuTUlOX1ZBTFVFKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYWYucmVhZEZsb2F0KCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSNyZWFkSW50KCkKKyAgICAgKiBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUjd3JpdGVJbnQoY2hhcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfd3JpdGVJbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBSYW5kb21BY2Nlc3NGaWxlIHJhZiA9IG5ldyBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUoZmlsZU5hbWUsICJydyIpOworICAgICAgICByYWYud3JpdGVJbnQoSW50ZWdlci5NSU5fVkFMVUUpOworICAgICAgICByYWYud3JpdGVJbnQoJ1QnKTsKKyAgICAgICAgcmFmLndyaXRlSW50KEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgcmFmLndyaXRlSW50KEludGVnZXIuTUlOX1ZBTFVFIC0gMSk7CisgICAgICAgIHJhZi53cml0ZUludChJbnRlZ2VyLk1BWF9WQUxVRSArIDEpOworICAgICAgICByYWYuc2VlaygwKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IHZhbHVlIHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIEludGVnZXIuTUlOX1ZBTFVFLCByYWYucmVhZEludCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IEluY29ycmVjdCB2YWx1ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICAnVCcsIHJhZi5yZWFkSW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMzogSW5jb3JyZWN0IHZhbHVlIHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIEludGVnZXIuTUFYX1ZBTFVFLCByYWYucmVhZEludCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDQ6IEluY29ycmVjdCB2YWx1ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICAweDdmZmZmZmZmLCByYWYucmVhZEludCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDU6IEluY29ycmVjdCB2YWx1ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICAweDgwMDAwMDAwLCByYWYucmVhZEludCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnJlYWRJbnQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNjogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICByYWYuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi53cml0ZUludCgnRScpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA3OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkSW50KCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDg6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSNyZWFkTG9uZygpCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI3dyaXRlTG9uZyhjaGFyKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZF93cml0ZUxvbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBSYW5kb21BY2Nlc3NGaWxlIHJhZiA9IG5ldyBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUoZmlsZU5hbWUsICJydyIpOworICAgICAgICByYWYud3JpdGVMb25nKExvbmcuTUlOX1ZBTFVFKTsKKyAgICAgICAgcmFmLndyaXRlTG9uZygnVCcpOworICAgICAgICByYWYud3JpdGVMb25nKExvbmcuTUFYX1ZBTFVFKTsKKyAgICAgICAgcmFmLndyaXRlTG9uZyhMb25nLk1JTl9WQUxVRSAtIDEpOworICAgICAgICByYWYud3JpdGVMb25nKExvbmcuTUFYX1ZBTFVFICsgMSk7CisgICAgICAgIHJhZi5zZWVrKDApOworCisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgdmFsdWUgd3JpdHRlbiBvciByZWFkOyIsCisgICAgICAgICAgICAgICAgTG9uZy5NSU5fVkFMVUUsIHJhZi5yZWFkTG9uZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IEluY29ycmVjdCB2YWx1ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICAnVCcsIHJhZi5yZWFkTG9uZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDM6IEluY29ycmVjdCB2YWx1ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICBMb25nLk1BWF9WQUxVRSwgcmFmLnJlYWRMb25nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNDogSW5jb3JyZWN0IHZhbHVlIHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIDB4N2ZmZmZmZmZmZmZmZmZmZmwsIHJhZi5yZWFkTG9uZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDU6IEluY29ycmVjdCB2YWx1ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICAweDgwMDAwMDAwMDAwMDAwMDBsLCByYWYucmVhZExvbmcoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkTG9uZygpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA2OiBFT0ZFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHJhZi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLndyaXRlTG9uZygnRScpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA3OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkTG9uZygpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA4OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUjcmVhZFNob3J0KCkKKyAgICAgKiBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUjd3JpdGVTaG9ydChzaG9ydCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfd3JpdGVTaG9ydCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFJhbmRvbUFjY2Vzc0ZpbGUgcmFmID0gbmV3IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZShmaWxlTmFtZSwgInJ3Iik7CisgICAgICAgIHJhZi53cml0ZVNob3J0KFNob3J0Lk1JTl9WQUxVRSk7CisgICAgICAgIHJhZi53cml0ZVNob3J0KCdUJyk7CisgICAgICAgIHJhZi53cml0ZVNob3J0KFNob3J0Lk1BWF9WQUxVRSk7CisgICAgICAgIHJhZi53cml0ZVNob3J0KFNob3J0Lk1JTl9WQUxVRSAtIDEpOworICAgICAgICByYWYud3JpdGVTaG9ydChTaG9ydC5NQVhfVkFMVUUgKyAxKTsKKyAgICAgICAgcmFmLnNlZWsoMCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCB2YWx1ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICBTaG9ydC5NSU5fVkFMVUUsIHJhZi5yZWFkU2hvcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBJbmNvcnJlY3QgdmFsdWUgd3JpdHRlbiBvciByZWFkOyIsCisgICAgICAgICAgICAgICAgJ1QnLCByYWYucmVhZFNob3J0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMzogSW5jb3JyZWN0IHZhbHVlIHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIFNob3J0Lk1BWF9WQUxVRSwgcmFmLnJlYWRTaG9ydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDQ6IEluY29ycmVjdCB2YWx1ZSB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICAweDdmZmYsIHJhZi5yZWFkU2hvcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCA1OiBJbmNvcnJlY3QgdmFsdWUgd3JpdHRlbiBvciByZWFkOyIsCisgICAgICAgICAgICAgICAgKHNob3J0KSAweDgwMDAsIHJhZi5yZWFkU2hvcnQoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkU2hvcnQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNjogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICByYWYuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi53cml0ZVNob3J0KCdFJyk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDc6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnJlYWRTaG9ydCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA4OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUjcmVhZFVURigpCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI3dyaXRlU2hvcnQoY2hhcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfd3JpdGVVVEYoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBSYW5kb21BY2Nlc3NGaWxlIHJhZiA9IG5ldyBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUoZmlsZU5hbWUsICJydyIpOworICAgICAgICByYWYud3JpdGVVVEYodW5paHcpOworICAgICAgICByYWYuc2VlaygwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCBVVEYgc3RyaW5nIHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIHVuaWh3LCByYWYucmVhZFVURigpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnJlYWRVVEYoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICByYWYuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi53cml0ZVVURigiQWxyZWFkeSBjbG9zZWQuIik7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnJlYWRVVEYoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI3dyaXRlQnl0ZXMoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKiBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUjcmVhZEZ1bGx5KGJ5dGVbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRGdWxseSRCX3dyaXRlQnl0ZXNMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVt0ZXN0TGVuZ3RoXTsKKyAgICAgICAgUmFuZG9tQWNjZXNzRmlsZSByYWYgPSBuZXcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlKGZpbGVOYW1lLCAicnciKTsKKyAgICAgICAgcmFmLndyaXRlQnl0ZXModGVzdFN0cmluZyk7CisgICAgICAgIHJhZi5zZWVrKDApOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYWYucmVhZEZ1bGx5KG51bGwpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICByYWYucmVhZEZ1bGx5KGJ1Zik7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBJbmNvcnJlY3QgYnl0ZXMgd3JpdHRlbiBvciByZWFkOyIsCisgICAgICAgICAgICAgICAgdGVzdFN0cmluZywgbmV3IFN0cmluZyhidWYpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnJlYWRGdWxseShidWYpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBFT0ZFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHJhZi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLndyaXRlQnl0ZXMoIkFscmVhZHkgY2xvc2VkLiIpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkRnVsbHkoYnVmKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI3dyaXRlQnl0ZXMoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKiBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUjcmVhZEZ1bGx5KGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkRnVsbHkkQklJKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlW3Rlc3RMZW5ndGhdOworICAgICAgICBSYW5kb21BY2Nlc3NGaWxlIHJhZiA9IG5ldyBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUoZmlsZU5hbWUsICJydyIpOworICAgICAgICByYWYud3JpdGVCeXRlcyh0ZXN0U3RyaW5nKTsKKyAgICAgICAgcmFmLnNlZWsoMCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkRnVsbHkobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHJhZi5yZWFkRnVsbHkoYnVmLCA1LCB0ZXN0TGVuZ3RoIC0gMTApOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDU7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IEluY29ycmVjdCBieXRlcyByZWFkOyIsIDAsIGJ1ZltpXSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDM6IEluY29ycmVjdCBieXRlcyB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICB0ZXN0U3RyaW5nLnN1YnN0cmluZygwLCB0ZXN0TGVuZ3RoIC0gMTApLAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmcoYnVmLCA1LCB0ZXN0TGVuZ3RoIC0gMTApKTsKKworICAgICAgICAvLyBSZWFkaW5nIHBhc3QgdGhlIGVuZCBvZiB0aGUgZmlsZS4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkRnVsbHkoYnVmLCAzLCB0ZXN0TGVuZ3RoIC0gNik7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IEVPRkV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgLy8gUGFzc2luZyBpbnZhbGlkIGFyZ3VtZW50cy4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkRnVsbHkoYnVmLCAtMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkRnVsbHkoYnVmLCAwLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDY6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkRnVsbHkoYnVmLCAyLCB0ZXN0TGVuZ3RoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNzogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIC8vIFJlYWRpbmcgZnJvbSBhIGNsb3NlZCBmaWxlLgorICAgICAgICByYWYuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkRnVsbHkoYnVmKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgODogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI3JlYWRVbnNpZ25lZEJ5dGUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZFVuc2lnbmVkQnl0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFJhbmRvbUFjY2Vzc0ZpbGUgcmFmID0gbmV3IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZShmaWxlTmFtZSwgInJ3Iik7CisgICAgICAgIHJhZi53cml0ZUJ5dGUoLTEpOworICAgICAgICByYWYuc2VlaygwKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IHZhbHVlIHdyaXR0ZW4gb3IgcmVhZDsiLAorICAgICAgICAgICAgICAgIDI1NSwgcmFmLnJlYWRVbnNpZ25lZEJ5dGUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5yZWFkVW5zaWduZWRCeXRlKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEVPRkV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgcmFmLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYWYucmVhZFVuc2lnbmVkQnl0ZSgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUjcmVhZFVuc2lnbmVkU2hvcnQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZFVuc2lnbmVkU2hvcnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBSYW5kb21BY2Nlc3NGaWxlIHJhZiA9IG5ldyBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUoZmlsZU5hbWUsICJydyIpOworICAgICAgICByYWYud3JpdGVTaG9ydCgtMSk7CisgICAgICAgIHJhZi5zZWVrKDApOworCisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgdmFsdWUgd3JpdHRlbiBvciByZWFkOyIsCisgICAgICAgICAgICAgICAgNjU1MzUsIHJhZi5yZWFkVW5zaWduZWRTaG9ydCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnJlYWRVbnNpZ25lZFNob3J0KCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEVPRkV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgcmFmLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYWYucmVhZFVuc2lnbmVkU2hvcnQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI3JlYWRMaW5lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRMaW5lKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlLnJlYWRMaW5lKCkKKyAgICAgICAgUmFuZG9tQWNjZXNzRmlsZSByYWYgPSBuZXcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlKGZpbGVOYW1lLCAicnciKTsKKyAgICAgICAgU3RyaW5nIHMgPSAiR29vZGJ5ZVxuQ3J1ZWxcbldvcmxkXG4iOworICAgICAgICByYWYud3JpdGUocy5nZXRCeXRlcygpLCAwLCBzLmxlbmd0aCgpKTsKKyAgICAgICAgcmFmLnNlZWsoMCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCBsaW5lIHJlYWQ7IiwgIkdvb2RieWUiLCByYWYucmVhZExpbmUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBJbmNvcnJlY3QgbGluZSByZWFkOyIsICJDcnVlbCIsIHJhZi5yZWFkTGluZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDM6IEluY29ycmVjdCBsaW5lIHJlYWQ7IiwgIldvcmxkIiwgcmFmLnJlYWRMaW5lKCkpOworICAgICAgICBhc3NlcnROdWxsKCJUZXN0IDQ6IEluY29ycmVjdCBsaW5lIHJlYWQ7IG51bGwgZXhwZWN0ZWQuIiwgcmFmLnJlYWRMaW5lKCkpOworCisgICAgICAgIHJhZi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnJlYWRMaW5lKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI3NlZWsobG9uZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NlZWtKKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlLnNlZWsobG9uZykKKyAgICAgICAgUmFuZG9tQWNjZXNzRmlsZSByYWYgPSBuZXcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlKGZpbGVOYW1lLCAicnciKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnNlZWsoLTEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICByYWYud3JpdGUodGVzdFN0cmluZy5nZXRCeXRlcygpLCAwLCB0ZXN0TGVuZ3RoKTsKKyAgICAgICAgcmFmLnNlZWsoMTIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMzogU2VlayBmYWlsZWQgdG8gc2V0IGZpbGUgcG9pbnRlci4iLCAxMiwKKyAgICAgICAgICAgICAgICByYWYuZ2V0RmlsZVBvaW50ZXIoKSk7CisKKyAgICAgICAgcmFmLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYWYuc2VlaygxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI3NraXBCeXRlcyhpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9za2lwQnl0ZXNJKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzVdOworICAgICAgICBSYW5kb21BY2Nlc3NGaWxlIHJhZiA9IG5ldyBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUoZmlsZU5hbWUsICJydyIpOworICAgICAgICByYWYud3JpdGVCeXRlcygiSGVsbG9Xb3JsZCIpOworICAgICAgICByYWYuc2VlaygwKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IE5vdGhpbmcgc2hvdWxkIGJlIHNraXBwZWQgaWYgcGFyYW1ldGVyIGlzIGxlc3MgdGhhbiB6ZXJvIiwKKyAgICAgICAgICAgICAgICByYWYuc2tpcEJ5dGVzKC0xKSA9PSAwKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNDogSW5jb3JyZWN0IG51bWJlciBvZiBieXRlcyBza2lwcGVkOyAiLAorICAgICAgICAgICAgICAgIDUsIHJhZi5za2lwQnl0ZXMoNSkpOworCisgICAgICAgIHJhZi5yZWFkRnVsbHkoYnVmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDM6IEZhaWxlZCB0byBza2lwIGJ5dGVzLiIsCisgICAgICAgICAgICAgICAgIldvcmxkIiwgbmV3IFN0cmluZyhidWYsIDAsIDUpKTsKKworICAgICAgICByYWYuc2VlaygwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDQ6IEluY29ycmVjdCBudW1iZXIgb2YgYnl0ZXMgc2tpcHBlZDsgIiwKKyAgICAgICAgICAgICAgICAxMCwgcmFmLnNraXBCeXRlcygyMCkpOworCisgICAgICAgIHJhZi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnNraXBCeXRlcygxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI3NraXBCeXRlcyhpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRMZW5ndGhKKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGJ5dGVzUmVhZDsKKyAgICAgICAgbG9uZyB0cnVuY0xlbmd0aCA9IChsb25nKSAodGVzdExlbmd0aCAqIDAuNzUpOworICAgICAgICBieXRlW10gcmJ1ZiA9IG5ldyBieXRlW3Rlc3RMZW5ndGggKyAxMF07CisKKyAgICAgICAgLy8gU2V0dXAgdGhlIHRlc3QgZmlsZS4KKyAgICAgICAgUmFuZG9tQWNjZXNzRmlsZSByYWYgPSBuZXcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlKGZpbGVOYW1lLCAicnciKTsKKyAgICAgICAgcmFmLndyaXRlKHRlc3RTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgZmlsZSBsZW5ndGg7IiwKKyAgICAgICAgICAgICAgICB0ZXN0TGVuZ3RoLCByYWYubGVuZ3RoKCkpOworCisgICAgICAgIC8vIFRydW5jYXRlIHRoZSBmaWxlLgorICAgICAgICByYWYuc2V0TGVuZ3RoKHRydW5jTGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAyOiBGaWxlIHBvaW50ZXIgbm90IG1vdmVkIHRvIHRoZSBlbmQgb2YgdGhlIHRydW5jYXRlZCBmaWxlLiIsCisgICAgICAgICAgICAgICAgcmFmLmdldEZpbGVQb2ludGVyKCkgPT0gdHJ1bmNMZW5ndGgpOworCisgICAgICAgIHJhZi5jbG9zZSgpOworICAgICAgICByYWYgPSBuZXcgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlKGZpbGVOYW1lLCAicnciKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDM6IEluY29ycmVjdCBmaWxlIGxlbmd0aDsiLAorICAgICAgICAgICAgICAgIHRydW5jTGVuZ3RoLCByYWYubGVuZ3RoKCkpOworICAgICAgICBieXRlc1JlYWQgPSByYWYucmVhZChyYnVmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDQ6IEluY29ycmVjdCBudW1iZXIgb2YgYnl0ZXMgcmVhZDsiLAorICAgICAgICAgICAgICAgIHRydW5jTGVuZ3RoLCBieXRlc1JlYWQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNTogSW5jb3JyZWN0IGJ5dGVzIHJlYWQuICIsCisgICAgICAgICAgICAgICAgdGVzdFN0cmluZy5zdWJzdHJpbmcoMCwgYnl0ZXNSZWFkKSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKHJidWYsIDAsIGJ5dGVzUmVhZCkpOworCisgICAgICAgIC8vIEV4cGFuZCB0aGUgZmlsZS4KKyAgICAgICAgcmFmLnNldExlbmd0aCh0ZXN0TGVuZ3RoICsgMik7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgNjogRmlsZSBwb2ludGVyIGluY29ycmVjdGx5IG1vdmVkLiIsCisgICAgICAgICAgICAgICAgcmFmLmdldEZpbGVQb2ludGVyKCkgPT0gdHJ1bmNMZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNzogSW5jb3JyZWN0IGZpbGUgbGVuZ3RoOyIsCisgICAgICAgICAgICAgICAgdGVzdExlbmd0aCArIDIsIHJhZi5sZW5ndGgoKSk7CisKKyAgICAgICAgLy8gRXhjZXB0aW9uIHRlc3RpbmcuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYWYuc2V0TGVuZ3RoKC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgOTogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHJhZi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLnNldExlbmd0aCh0cnVuY0xlbmd0aCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDEwOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUjd3JpdGUoYnl0ZVtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGUkQigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSByYnVmID0gbmV3IGJ5dGVbNDAwMF07CisgICAgICAgIFJhbmRvbUFjY2Vzc0ZpbGUgcmFmID0gbmV3IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZShmaWxlTmFtZSwgInJ3Iik7CisKKyAgICAgICAgYnl0ZVtdIG51bGxCeXRlQXJyYXkgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLndyaXRlKG51bGxCeXRlQXJyYXkpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLndyaXRlKHRlc3RTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IFVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgcmFmLmNsb3NlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi53cml0ZShuZXcgYnl0ZVswXSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogVW5leHBlY3RlZCBJT0V4Y2VwdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYWYud3JpdGUodGVzdFN0cmluZy5nZXRCeXRlcygpKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGZpcyA9IG5ldyBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbShmaWxlTmFtZSk7CisgICAgICAgIGZpcy5yZWFkKHJidWYsIDAsIHRlc3RMZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBieXRlcyB3cml0dGVuIiwgdGVzdFN0cmluZywgbmV3IFN0cmluZyhyYnVmLCAwLAorICAgICAgICAgICAgICAgIHRlc3RMZW5ndGgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUjd3JpdGUoYnl0ZVtdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlJEJJSSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBSYW5kb21BY2Nlc3NGaWxlIHJhZiA9IG5ldyBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGUoZmlsZU5hbWUsICJydyIpOworICAgICAgICBieXRlW10gcmJ1ZiA9IG5ldyBieXRlWzQwMDBdOworICAgICAgICBieXRlW10gdGVzdEJ1ZiA9IG51bGw7CisgICAgICAgIGludCBieXRlc1JlYWQ7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi53cml0ZSh0ZXN0QnVmLCAxLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgdGVzdEJ1ZiA9IHRlc3RTdHJpbmcuZ2V0Qnl0ZXMoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLndyaXRlKHRlc3RCdWYsIC0xLCAxMCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYWYud3JpdGUodGVzdEJ1ZiwgMCwgLTEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLndyaXRlKHRlc3RCdWYsIDUsIHRlc3RMZW5ndGgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICAvLyBQb3NpdGl2ZSB0ZXN0OiBUaGUgZm9sbG93aW5nIHdyaXRlIHNob3VsZCBub3QgZmFpbC4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi53cml0ZSh0ZXN0QnVmLCAzLCB0ZXN0TGVuZ3RoIC0gNSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IFVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgcmFmLmNsb3NlKCk7CisKKyAgICAgICAgLy8gV3JpdGluZyBub3RoaW5nIHRvIGEgY2xvc2VkIGZpbGUgc2hvdWxkIG5vdCBmYWlsIGVpdGhlci4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi53cml0ZShuZXcgYnl0ZVswXSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNjogVW5leHBlY3RlZCBJT0V4Y2VwdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFdyaXRpbmcgc29tZXRoaW5nIHRvIGEgY2xvc2VkIGZpbGUgc2hvdWxkIGZhaWwuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYWYud3JpdGUodGVzdFN0cmluZy5nZXRCeXRlcygpKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGZpcyA9IG5ldyBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbShmaWxlTmFtZSk7CisgICAgICAgIGJ5dGVzUmVhZCA9IGZpcy5yZWFkKHJidWYsIDAsIHRlc3RMZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgODogSW5jb3JyZWN0IG51bWJlciBvZiBieXRlcyB3cml0dGVuIG9yIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICB0ZXN0TGVuZ3RoIC0gNSwgYnl0ZXNSZWFkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDk6IEluY29ycmVjdCBieXRlcyB3cml0dGVuIG9yIHJlYWQ7ICIsCisgICAgICAgICAgICAgICAgdGVzdFN0cmluZy5zdWJzdHJpbmcoMywgdGVzdExlbmd0aCAtIDIpLAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmcocmJ1ZiwgMCwgYnl0ZXNSZWFkKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlI3dyaXRlQ2hhcnMoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlQ2hhcnNMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFJhbmRvbUFjY2Vzc0ZpbGUgcmFmID0gbmV3IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZShmaWxlTmFtZSwgInJ3Iik7CisgICAgICAgIHJhZi53cml0ZUNoYXJzKHVuaWh3KTsKKyAgICAgICAgY2hhcltdIGhjaGFycyA9IG5ldyBjaGFyW3VuaWh3Lmxlbmd0aCgpXTsKKyAgICAgICAgdW5paHcuZ2V0Q2hhcnMoMCwgdW5paHcubGVuZ3RoKCksIGhjaGFycywgMCk7CisgICAgICAgIHJhZi5zZWVrKDApOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGhjaGFycy5sZW5ndGg7IGkrKykKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgY2hhcmFjdGVyIHdyaXR0ZW4gb3IgcmVhZCBhdCBpbmRleCAiICsgaSArICI7IiwKKyAgICAgICAgICAgICAgICAgICAgaGNoYXJzW2ldLCByYWYucmVhZENoYXIoKSk7CisgICAgICAgIHJhZi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmFmLndyaXRlQ2hhcnMoIkFscmVhZHkgY2xvc2VkLiIpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworCisgICAgICAgIGYgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJyYWYiLCAidHN0Iik7CisgICAgICAgIGlmICghZi5kZWxldGUoKSkgeworICAgICAgICAgICAgZmFpbCgiVW5hYmxlIHRvIGRlbGV0ZSB0ZXN0IGZpbGUgOiAiICsgZik7CisgICAgICAgIH0KKyAgICAgICAgZmlsZU5hbWUgPSBmLmdldEFic29sdXRlUGF0aCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGYuZXhpc3RzKCkpIHsKKyAgICAgICAgICAgIGYuZGVsZXRlKCk7CisgICAgICAgIH0KKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkUmVhZGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRSZWFkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWI3NzY3ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkUmVhZGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTI0IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CitpbXBvcnQgamF2YS5uaW8uQ2hhckJ1ZmZlcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfQVNpbXBsZVJlYWRlcjsKKworcHVibGljIGNsYXNzIE9sZFJlYWRlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1JlYWRlcigpIHsKKyAgICAgICAgTW9ja1JlYWRlciByID0gbmV3IE1vY2tSZWFkZXIoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBMb2NrIGhhcyBub3QgYmVlbiBzZXQgY29ycmVjdGx5LiIsIHIubG9ja1NldChyKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9SZWFkZXJfQ2hhckJ1ZmZlckNoYXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdXBwb3J0X0FTaW1wbGVSZWFkZXIgc2ltcGxlOworICAgICAgICBzaW1wbGUgPSBuZXcgU3VwcG9ydF9BU2ltcGxlUmVhZGVyKCJCbGEgYmxhLCB3aGF0IGVsc2U/Iik7CisgICAgICAgIENoYXJCdWZmZXIgYnVmID0gQ2hhckJ1ZmZlci5hbGxvY2F0ZSg0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXR1cm4gdmFsdWUhIiwgNCwgc2ltcGxlLnJlYWQoYnVmKSk7CisgICAgICAgIGJ1Zi5yZXdpbmQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzdHVmZiByZWFkISIsICJCbGEgIiwgU3RyaW5nLnZhbHVlT2YoYnVmKSk7CisgICAgICAgIHNpbXBsZS5yZWFkKGJ1Zik7CisgICAgICAgIGJ1Zi5yZXdpbmQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzdHVmZiByZWFkISIsICJibGEsIiwgU3RyaW5nLnZhbHVlT2YoYnVmKSk7CisgICAgICAgIHNpbXBsZS50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaW1wbGUucmVhZChidWYpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93biEiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfUmVhZF8kQygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN1cHBvcnRfQVNpbXBsZVJlYWRlciBzaW1wbGU7CisgICAgICAgIHNpbXBsZSA9IG5ldyBTdXBwb3J0X0FTaW1wbGVSZWFkZXIoIkJsYSBibGEsIHdoYXQgZWxzZT8iKTsKKyAgICAgICAgY2hhcltdIGJ1ZiA9IG5ldyBjaGFyWzRdOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHJldHVybiB2YWx1ZSEiLCA0LCBzaW1wbGUucmVhZChidWYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzdHVmZiByZWFkISIsICJCbGEgIiwgbmV3IFN0cmluZyhidWYpKTsKKyAgICAgICAgc2ltcGxlLnJlYWQoYnVmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzdHVmZiByZWFkISIsICJibGEsIiwgbmV3IFN0cmluZyhidWYpKTsKKyAgICAgICAgc2ltcGxlLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpbXBsZS5yZWFkKGJ1Zik7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBub3QgdGhyb3duISIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X21hcmtTdXBwb3J0ZWQoKSB7CisgICAgICAgIGFzc2VydEZhbHNlKCJtYXJrU3VwcG9ydGVkIG11c3QgcmV0dXJuIGZhbHNlIiwgbmV3IE1vY2tSZWFkZXIoKS5tYXJrU3VwcG9ydGVkKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN1cHBvcnRfQVNpbXBsZVJlYWRlciBzaW1wbGUgPSBuZXcgU3VwcG9ydF9BU2ltcGxlUmVhZGVyKCJCbGEgYmxhLCB3aGF0IGVsc2U/Iik7CisgICAgICAgIGludCByZXMgPSBzaW1wbGUucmVhZCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHN0dWZmIHJlYWQhIiwgJ0InLCByZXMpOworICAgICAgICByZXMgPSBzaW1wbGUucmVhZCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHN0dWZmIHJlYWQhIiwgJ2wnLCByZXMpOworICAgICAgICBzaW1wbGUudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2ltcGxlLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIG5vdCB0aHJvd24hIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWR5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3VwcG9ydF9BU2ltcGxlUmVhZGVyIHNpbXBsZSA9IG5ldyBTdXBwb3J0X0FTaW1wbGVSZWFkZXIoIkJsYSBibGEsIHdoYXQgZWxzZT8iKTsKKyAgICAgICAgc2ltcGxlLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpbXBsZS5yZWFkeSgpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93biEiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2tpcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN1cHBvcnRfQVNpbXBsZVJlYWRlciBzaW1wbGUgPSBuZXcgU3VwcG9ydF9BU2ltcGxlUmVhZGVyKCJCbGEgYmxhLCB3aGF0IGVsc2U/Iik7CisgICAgICAgIGNoYXJbXSBidWYgPSBuZXcgY2hhcls0XTsKKyAgICAgICAgc2ltcGxlLnJlYWQoYnVmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzdHVmZiByZWFkISIsICJCbGEgIiwgbmV3IFN0cmluZyhidWYpKTsKKyAgICAgICAgc2ltcGxlLnNraXAoNSk7CisgICAgICAgIHNpbXBsZS5yZWFkKGJ1Zik7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc3R1ZmYgcmVhZCEiLCAid2hhdCIsIG5ldyBTdHJpbmcoYnVmKSk7CisgICAgICAgIHNpbXBsZS50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaW1wbGUuc2tpcCgxKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIG5vdCB0aHJvd24hIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBNb2NrUmVhZGVyIGV4dGVuZHMgUmVhZGVyIHsKKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgY2xvc2UoKSB7fQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHJlYWQoY2hhcltdIGJ1ZiwgaW50IG9mZnNldCwgaW50IGNvdW50KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGxvY2tTZXQoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIHJldHVybiAobG9jayA9PSBvKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkU2VxdWVuY2VJbnB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkU2VxdWVuY2VJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mN2Q5YTQ5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRTZXF1ZW5jZUlucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTYwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5TZXF1ZW5jZUlucHV0U3RyZWFtOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW07CisKK3B1YmxpYyBjbGFzcyBPbGRTZXF1ZW5jZUlucHV0U3RyZWFtVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbSBzaW1wbGUxLCBzaW1wbGUyOworICAgIFNlcXVlbmNlSW5wdXRTdHJlYW0gc2k7CisgICAgU3RyaW5nIHMxID0gIkhlbGxvIjsKKyAgICBTdHJpbmcgczIgPSAiV29ybGQiOworCisgICAgcHVibGljIHZvaWQgdGVzdF9hdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBudW1iZXIgb2YgYnl0ZXMhIiwgczEubGVuZ3RoKCksIHNpLmF2YWlsYWJsZSgpKTsKKyAgICAgICAgc2ltcGxlMi50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IHRydWU7CisgICAgICAgIGFzc2VydFRydWUoIklPRXhjZXB0aW9uIG9uIHNlY29uZCBzdHJlYW0gc2hvdWxkIG5vdCBhZmZlY3QgYXQgdGhpcyB0aW1lISIsCisgICAgICAgICAgICAgICAgc2kuYXZhaWxhYmxlKCkgPT0gczEubGVuZ3RoKCkpOworICAgICAgICBzaW1wbGUxLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpLmF2YWlsYWJsZSgpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93biEiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvc2UyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc2ltcGxlMS50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaS5jbG9zZSgpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93biEiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHNpLnJlYWQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCBjaGFyIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICBzMS5jaGFyQXQoMSksIChjaGFyKSBzaS5yZWFkKCkpOworCisgICAgICAgIC8vIFdlIGFyZSBzdGlsbCByZWFkaW5nIGZyb20gdGhlIGZpcnN0IGlucHV0IHN0cmVhbSwgc2hvdWxkIGJlIG9rLgorICAgICAgICBzaW1wbGUyLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBJbmNvcnJlY3QgY2hhciByZWFkOyIsCisgICAgICAgICAgICAgICAgICAgIHMxLmNoYXJBdCgyKSwgKGNoYXIpIHNpLnJlYWQoKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogVW5leHBlY3RlZCBJT0V4Y2VwdGlvbi4iKTsKKyAgICAgICAgfQorCisgICAgICAgIHNpbXBsZTEudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2kucmVhZCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCA0OiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgc2ltcGxlMS50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IGZhbHNlOworCisgICAgICAgIC8vIFJlYWRpbmcgYnl0ZXMgNCBhbmQgNSBvZiB0aGUgZmlyc3QgaW5wdXQgc3RyZWFtIHNob3VsZCBiZSBvayBhZ2Fpbi4KKyAgICAgICAgc2kucmVhZCgpOworICAgICAgICBzaS5yZWFkKCk7CisKKyAgICAgICAgLy8gUmVhZGluZyB0aGUgZmlyc3QgYnl0ZSBvZiB0aGUgc2Vjb25kIGlucHV0IHN0cmVhbSBzaG91bGQgZmFpbC4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgLy8gUmVhZGluZyBmcm9tIHRoZSBzZWNvbmQgaW5wdXQgc3RyZWFtIHNob3VsZCBiZSBvayBub3cuCisgICAgICAgIHNpbXBsZTIudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCA2OiBJbmNvcnJlY3QgY2hhciByZWFkOyIsCisgICAgICAgICAgICAgICAgICAgIHMyLmNoYXJBdCgwKSwgKGNoYXIpIHNpLnJlYWQoKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNzogVW5leHBlY3RlZCBJT0V4Y2VwdGlvbi4iKTsKKyAgICAgICAgfQorCisgICAgICAgIHNpLmNsb3NlKCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgODogLTEgZXhwZWN0ZWQgd2hlbiByZWFkaW5nIGZyb20gYSBjbG9zZWQgIiArCisgICAgICAgICAgICAgICAgICAgInNlcXVlbmNlIGlucHV0IHN0cmVhbS4iLCBzaS5yZWFkKCkgPT0gLTEpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZF9leGMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzaW1wbGUyLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gdHJ1ZTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJT0V4Y2VwdGlvbiBvbiBzZWNvbmQgc3RyZWFtIHNob3VsZCBub3QgYWZmZWN0IGF0IHRoaXMgdGltZSEiLCA3Miwgc2kucmVhZCgpKTsKKyAgICAgICAgc2ltcGxlMS50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaS5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBub3QgdGhyb3duISIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkJEJJSV9FeGNwZXRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbNF07CisgICAgICAgIHNpLnJlYWQoYnVmLCAwLCAyKTsKKyAgICAgICAgc2kucmVhZChidWYsIDIsIDEpOworICAgICAgICBzaW1wbGUyLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gdHJ1ZTsKKyAgICAgICAgc2kucmVhZChidWYsIDMsIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHN0dWZmIHJlYWQhIiwgIkhlbGwiLCBuZXcgU3RyaW5nKGJ1ZikpOworICAgICAgICBzaW1wbGUxLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpLnJlYWQoYnVmLCAzLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIG5vdCB0aHJvd24hIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBidWYgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgIHNpbXBsZTEgPSBuZXcgU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW0oczEpOworICAgICAgICBzaW1wbGUyID0gbmV3IFN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtKHMyKTsKKyAgICAgICAgc2kgPSBuZXcgU2VxdWVuY2VJbnB1dFN0cmVhbShzaW1wbGUxLCBzaW1wbGUyKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpLnJlYWQoYnVmLCAtMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc2kucmVhZChidWYsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaS5yZWFkKGJ1ZiwgMSwgMTApOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgc2ltcGxlMSA9IG5ldyBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbShzMSk7CisgICAgICAgIHNpbXBsZTIgPSBuZXcgU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW0oczIpOworICAgICAgICBzaSA9IG5ldyBTZXF1ZW5jZUlucHV0U3RyZWFtKHNpbXBsZTEsIHNpbXBsZTIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkU3RyZWFtVG9rZW5pemVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRTdHJlYW1Ub2tlbml6ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjJiMjc2YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkU3RyZWFtVG9rZW5pemVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTI0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlN0cmVhbVRva2VuaXplcjsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1JlYWRlcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0OworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW07CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1N0cmluZ1JlYWRlcjsKKworcHVibGljIGNsYXNzIE9sZFN0cmVhbVRva2VuaXplclRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIFN0cmVhbVRva2VuaXplciBzdDsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbmV4dFRva2VuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3QgPSBuZXcgU3RyZWFtVG9rZW5pemVyKG5ldyBTdXBwb3J0X1N0cmluZ1JlYWRlcigiXG4gXHJcbiMiKSk7CisgICAgICAgIHN0Lm9yZGluYXJ5Q2hhcignXG4nKTsgLy8gbWFrZSBcbiBvcmRpbmFyeQorICAgICAgICBzdC5lb2xJc1NpZ25pZmljYW50KHRydWUpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyB0b2tlbiAyLDEiLCBzdC5uZXh0VG9rZW4oKSA9PSAnXG4nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgdG9rZW4gMiwyIiwgc3QubmV4dFRva2VuKCkgPT0gJ1xuJyk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdG9rZW4gMiwzIiwgJyMnLCBzdC5uZXh0VG9rZW4oKSk7CisKKyAgICAgICAgU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW0gc2lzID0gbmV3IFN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtKCk7CisgICAgICAgIHNpcy50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IHRydWU7CisgICAgICAgIHN0ID0gbmV3IFN0cmVhbVRva2VuaXplcihzaXMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QubmV4dFRva2VuKCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Jhc2ljU3RyaW5nVG9rZW5pemVyTWV0aG9kcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzdHIgPSAiVGVzdGluZyAxMjM0NSBcbiBhbHBoYSBcclxuIG9tZWdhIjsKKyAgICAgICAgU3RyaW5nIHN0cmIgPSAiLTMuOCAnQkxJTkQgbWljZScgXHIgc0VlIC8qIGhvdyAqLyB0aGV5IHJ1biI7CisgICAgICAgIFN0cmluZ1JlYWRlciBhYSA9IG5ldyBTdHJpbmdSZWFkZXIoc3RyKTsKKyAgICAgICAgU3RyaW5nUmVhZGVyIGJhID0gbmV3IFN0cmluZ1JlYWRlcihzdHJiKTsKKyAgICAgICAgU3RyZWFtVG9rZW5pemVyIGEgPSBuZXcgU3RyZWFtVG9rZW5pemVyKGFhKTsKKyAgICAgICAgU3RyZWFtVG9rZW5pemVyIGIgPSBuZXcgU3RyZWFtVG9rZW5pemVyKGJhKTsKKworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShhLmxpbmVubygpID09IDEpOworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShhLm5leHRUb2tlbigpID09IFN0cmVhbVRva2VuaXplci5UVF9XT1JEKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoYS50b1N0cmluZygpLmVxdWFscygiVG9rZW5bVGVzdGluZ10sIGxpbmUgMSIpKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoYS5uZXh0VG9rZW4oKSA9PSBTdHJlYW1Ub2tlbml6ZXIuVFRfTlVNQkVSKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoYS50b1N0cmluZygpLmVxdWFscygiVG9rZW5bbj0xMjM0NS4wXSwgbGluZSAxIikpOworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShhLm5leHRUb2tlbigpID09IFN0cmVhbVRva2VuaXplci5UVF9XT1JEKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoYS50b1N0cmluZygpLmVxdWFscygiVG9rZW5bYWxwaGFdLCBsaW5lIDIiKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKGEubmV4dFRva2VuKCkgPT0gU3RyZWFtVG9rZW5pemVyLlRUX1dPUkQpOworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShhLnRvU3RyaW5nKCkuZXF1YWxzKCJUb2tlbltvbWVnYV0sIGxpbmUgMyIpKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoYS5uZXh0VG9rZW4oKSA9PSBTdHJlYW1Ub2tlbml6ZXIuVFRfRU9GKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoYS50b1N0cmluZygpLmVxdWFscygiVG9rZW5bRU9GXSwgbGluZSAzIikpOworCisgICAgICAgIGIuY29tbWVudENoYXIoJ3UnKTsKKyAgICAgICAgYi5lb2xJc1NpZ25pZmljYW50KHRydWUpOworICAgICAgICBiLmxvd2VyQ2FzZU1vZGUodHJ1ZSk7CisgICAgICAgIGIub3JkaW5hcnlDaGFyKCd5Jyk7CisgICAgICAgIGIuc2xhc2hTdGFyQ29tbWVudHModHJ1ZSk7CisKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoYi5uZXh0VG9rZW4oKSA9PSBTdHJlYW1Ub2tlbml6ZXIuVFRfTlVNQkVSKTsKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoYi5udmFsID09IC0zLjgpOworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShiLnRvU3RyaW5nKCkuZXF1YWxzKCJUb2tlbltuPS0zLjhdLCBsaW5lIDEiKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKGIubmV4dFRva2VuKCkgPT0gMzkpOyAvLyAnCisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKGIudG9TdHJpbmcoKS5lcXVhbHMoIlRva2VuW0JMSU5EIG1pY2VdLCBsaW5lIDEiKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKGIubmV4dFRva2VuKCkgPT0gMTApOyAvLyBcbgorICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShiLnRvU3RyaW5nKCkuZXF1YWxzKCJUb2tlbltFT0xdLCBsaW5lIDIiKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKGIubmV4dFRva2VuKCkgPT0gU3RyZWFtVG9rZW5pemVyLlRUX1dPUkQpOworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShiLnRvU3RyaW5nKCkuZXF1YWxzKCJUb2tlbltzZWVdLCBsaW5lIDIiKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKGIubmV4dFRva2VuKCkgPT0gU3RyZWFtVG9rZW5pemVyLlRUX1dPUkQpOworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShiLnRvU3RyaW5nKCkuZXF1YWxzKCJUb2tlblt0aGVdLCBsaW5lIDIiKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKGIubmV4dFRva2VuKCkgPT0gMTIxKTsgLy8geQorICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShiLnRvU3RyaW5nKCkuZXF1YWxzKCJUb2tlblsneSddLCBsaW5lIDIiKSk7CisgICAgICAgIEFzc2VydC5hc3NlcnRUcnVlKGIubmV4dFRva2VuKCkgPT0gU3RyZWFtVG9rZW5pemVyLlRUX1dPUkQpOworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShiLnRvU3RyaW5nKCkuZXF1YWxzKCJUb2tlbltyXSwgbGluZSAyIikpOworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShiLm5leHRUb2tlbigpID09IFN0cmVhbVRva2VuaXplci5UVF9FT0YpOworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShiLnRvU3RyaW5nKCkuZXF1YWxzKCJUb2tlbltFT0ZdLCBsaW5lIDIiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXJtb255UmVncmVzc2lvblRlc3QoKSB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbXSB7KGJ5dGUpICctJ307CisgICAgICAgIFN0cmVhbVRva2VuaXplciB0b2tlbml6ZXIgPSBuZXcgU3RyZWFtVG9rZW5pemVyKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShkYXRhKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2tlbml6ZXIubmV4dFRva2VuKCk7CisgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gdG9rZW5pemVyLnRvU3RyaW5nKCk7CisgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIlRva2VuWyctJ10sIGxpbmUgMSIsIHJlc3VsdCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXJtb255UmVncmVzc2lvblRlc3QyKCkgeworICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlW10geyhieXRlKSAnIicsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpICdIJywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgJ2UnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAnbCcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpICdsJywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgJ28nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAnIid9OworICAgICAgICBTdHJlYW1Ub2tlbml6ZXIgdG9rZW5pemVyID0gbmV3IFN0cmVhbVRva2VuaXplcihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9rZW5pemVyLm5leHRUb2tlbigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gdG9rZW5pemVyLnRvU3RyaW5nKCk7CisgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIlRva2VuW0hlbGxvXSwgbGluZSAxIiwgcmVzdWx0KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZFN0cmluZ0J1ZmZlcklucHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRTdHJpbmdCdWZmZXJJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mN2FhYWU5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRTdHJpbmdCdWZmZXJJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDUzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uU3RyaW5nQnVmZmVySW5wdXRTdHJlYW07CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkU3RyaW5nQnVmZmVySW5wdXRTdHJlYW1UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgU3RyaW5nQnVmZmVySW5wdXRTdHJlYW0gc2JpczsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCRCSUlfRXhjZXB0aW9uKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEuaW8uU3RyaW5nQnVmZmVySW5wdXRTdHJlYW0ucmVhZCgpCisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzYmlzLnJlYWQoYnVmLCAwLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc2Jpcy5yZWFkKGJ1ZiwgLTEsIDEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNiaXMucmVhZChidWYsIDEwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIHNiaXMgPSBuZXcgU3RyaW5nQnVmZmVySW5wdXRTdHJlYW0oIkhlbGxvIFdvcmxkIik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRTdHJpbmdSZWFkZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZFN0cmluZ1JlYWRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hM2M2YmYwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PbGRTdHJpbmdSZWFkZXJUZXN0LmphdmEKQEAgLTAsMCArMSw2OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOworCitwdWJsaWMgY2xhc3MgT2xkU3RyaW5nUmVhZGVyVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJUaGlzIGlzIGEgdGVzdCBzdHJpbmciOworCisgICAgU3RyaW5nUmVhZGVyIHNyOworCisgICAgcHVibGljIHZvaWQgdGVzdF9tYXJrSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHNyID0gbmV3IFN0cmluZ1JlYWRlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNyLm1hcmsoLTEpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG5vdCB0aHJvd24hIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWQkQ0lJKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJbXSBidWYgPSBuZXcgY2hhclt0ZXN0U3RyaW5nLmxlbmd0aCgpXTsKKyAgICAgICAgc3IgPSBuZXcgU3RyaW5nUmVhZGVyKHRlc3RTdHJpbmcpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3IucmVhZChidWYsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzci5yZWFkKGJ1ZiwgLTEsIDEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNyLnJlYWQoYnVmLCAxLCB0ZXN0U3RyaW5nLmxlbmd0aCgpKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNyLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZFN0cmluZ1dyaXRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkU3RyaW5nV3JpdGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZmZjJiNzQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZFN0cmluZ1dyaXRlclRlc3QuamF2YQpAQCAtMCwwICsxLDQ3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5TdHJpbmdXcml0ZXI7CisKK3B1YmxpYyBjbGFzcyBPbGRTdHJpbmdXcml0ZXJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIFN0cmluZ1dyaXRlciBzdzsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYXBwZW5kQ2hhclNlcXVlbmNlSW50SW50KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZ1dyaXRlciB0b2JqID0gbmV3IFN0cmluZ1dyaXRlcig5KTsKKyAgICAgICAgICAgIHRvYmouYXBwZW5kKCIwMTIzNDU2Nzg5MDEyMzQ1Njc4OSIsIDE5LCAyKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gbm90IHRocm93biEiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmdXcml0ZXIgdG9iaiA9IG5ldyBTdHJpbmdXcml0ZXIoOSk7CisgICAgICAgICAgICB0b2JqLmFwcGVuZCgiMDEyMzQ1Njc4OTAxMjM0NTY3ODkiLCAyOSwgMik7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIG5vdCB0aHJvd24hIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICBzdyA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZFdyaXRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vT2xkV3JpdGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI4OGUzYmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL09sZFdyaXRlclRlc3QuamF2YQpAQCAtMCwwICsxLDE5NCBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uV3JpdGVyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfQVNpbXBsZVdyaXRlcjsKKworcHVibGljIGNsYXNzIE9sZFdyaXRlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FwcGVuZENoYXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBXcml0ZXIgdG9iaiA9IG5ldyBTdXBwb3J0X0FTaW1wbGVXcml0ZXIoMik7CisgICAgICAgIHRvYmouYXBwZW5kKCdhJyk7CisgICAgICAgIHRvYmouYXBwZW5kKCdiJyk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc3R1ZmYgd3JpdHRlbiEiLCAiYWIiLCB0b2JqLnRvU3RyaW5nKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9iai5hcHBlbmQoJ2MnKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIG5vdCB0aHJvd24hIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FwcGVuZENoYXJTZXF1ZW5jZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gIk15IFRlc3QgU3RyaW5nIjsKKyAgICAgICAgV3JpdGVyIHRvYmogPSBuZXcgU3VwcG9ydF9BU2ltcGxlV3JpdGVyKDIwKTsKKyAgICAgICAgdG9iai5hcHBlbmQodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc3R1ZmYgd3JpdHRlbiEiLCB0ZXN0U3RyaW5nLCB0b2JqLnRvU3RyaW5nKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9iai5hcHBlbmQodGVzdFN0cmluZyk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBub3QgdGhyb3duISIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9hcHBlbmRDaGFyU2VxdWVuY2VJbnRJbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJNeSBUZXN0IFN0cmluZyI7CisgICAgICAgIFdyaXRlciB0b2JqID0gbmV3IFN1cHBvcnRfQVNpbXBsZVdyaXRlcigyMSk7CisgICAgICAgIHRlc3RTdHJpbmcgPSAiMDEyMzQ1Njc4OWFiY2RlZmdoaWpBQkNERUZHSElKIjsKKyAgICAgICAgdG9iai5hcHBlbmQodGVzdFN0cmluZywgMCwgNSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc3R1ZmYgd3JpdHRlbiEiLCAiMDEyMzQiLCB0b2JqLnRvU3RyaW5nKCkpOworICAgICAgICB0b2JqLmFwcGVuZCh0ZXN0U3RyaW5nLCAxMCwgMTUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHN0dWZmIHdyaXR0ZW4hIiwgIjAxMjM0YWJjZGUiLCB0b2JqLnRvU3RyaW5nKCkpOworICAgICAgICB0b2JqLmFwcGVuZCh0ZXN0U3RyaW5nLCAyMCwgMzApOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHN0dWZmIHdyaXR0ZW4hIiwgIjAxMjM0YWJjZGVBQkNERUZHSElKIiwgdG9iai50b1N0cmluZygpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRvYmouYXBwZW5kKHRlc3RTdHJpbmcsIDMwLCAzMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIG5vdCB0aHJvd24hIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0b2JqLmFwcGVuZCh0ZXN0U3RyaW5nLCAyMCwgMjEpOyAvLyBKdXN0IGZpbGwgdGhlIHdyaXRlciB0byBpdHMgbGltaXQhCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2JqLmFwcGVuZCh0ZXN0U3RyaW5nLCAyOSwgMzApOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93biEiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYXBwZW5kQ2hhclNlcXVlbmNlSW50SW50X0V4Y2VwdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gIk15IFRlc3QgU3RyaW5nIjsKKyAgICAgICAgV3JpdGVyIHRvYmogPSBuZXcgU3VwcG9ydF9BU2ltcGxlV3JpdGVyKDIxKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRvYmouYXBwZW5kKHRlc3RTdHJpbmcsIDMwLCAzMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIG5vdCB0aHJvd24hIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9iai5hcHBlbmQodGVzdFN0cmluZywgLTEsIDEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBub3QgdGhyb3duISIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRvYmouYXBwZW5kKHRlc3RTdHJpbmcsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gbm90IHRocm93biEiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZSRDKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgV3JpdGVyIHRvYmogPSBuZXcgU3VwcG9ydF9BU2ltcGxlV3JpdGVyKDIxKTsKKyAgICAgICAgdG9iai53cml0ZSgiMDEyMzQiLnRvQ2hhckFycmF5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHN0dWZmIHdyaXR0ZW4hIiwgIjAxMjM0IiwgdG9iai50b1N0cmluZygpKTsKKyAgICAgICAgdG9iai53cml0ZSgiYWJjZGUiLnRvQ2hhckFycmF5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHN0dWZmIHdyaXR0ZW4hIiwgIjAxMjM0YWJjZGUiLCB0b2JqLnRvU3RyaW5nKCkpOworICAgICAgICB0b2JqLndyaXRlKCJBQkNERUZHSElKIi50b0NoYXJBcnJheSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzdHVmZiB3cml0dGVuISIsICIwMTIzNGFiY2RlQUJDREVGR0hJSiIsIHRvYmoudG9TdHJpbmcoKSk7CisgICAgICAgIHRvYmoud3JpdGUoInoiLnRvQ2hhckFycmF5KCkpOyAvLyBKdXN0IGZpbGwgdGhlIHdyaXRlciB0byBpdHMgbGltaXQhCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2JqLndyaXRlKCJMRVMgSkVVWCBTT05UIEZBSVRTIi50b0NoYXJBcnJheSgpKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIG5vdCB0aHJvd24hIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFdyaXRlciB0b2JqID0gbmV3IFN1cHBvcnRfQVNpbXBsZVdyaXRlcigyKTsKKyAgICAgICAgdG9iai53cml0ZSgnYScpOworICAgICAgICB0b2JqLndyaXRlKCdiJyk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc3R1ZmYgd3JpdHRlbiEiLCAiYWIiLCB0b2JqLnRvU3RyaW5nKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG9iai53cml0ZSgnYycpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93biEiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGVMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFdyaXRlciB0b2JqID0gbmV3IFN1cHBvcnRfQVNpbXBsZVdyaXRlcigyMSk7CisgICAgICAgIHRvYmoud3JpdGUoIjAxMjM0Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc3R1ZmYgd3JpdHRlbiEiLCAiMDEyMzQiLCB0b2JqLnRvU3RyaW5nKCkpOworICAgICAgICB0b2JqLndyaXRlKCJhYmNkZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHN0dWZmIHdyaXR0ZW4hIiwgIjAxMjM0YWJjZGUiLCB0b2JqLnRvU3RyaW5nKCkpOworICAgICAgICB0b2JqLndyaXRlKCJBQkNERUZHSElKIik7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc3R1ZmYgd3JpdHRlbiEiLCAiMDEyMzRhYmNkZUFCQ0RFRkdISUoiLCB0b2JqLnRvU3RyaW5nKCkpOworICAgICAgICB0b2JqLndyaXRlKCJ6Iik7IC8vIEp1c3QgZmlsbCB0aGUgd3JpdGVyIHRvIGl0cyBsaW1pdCEKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRvYmoud3JpdGUoIkxFUyBKRVVYIFNPTlQgRkFJVFMiKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIG5vdCB0aHJvd24hIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlTGphdmFfbGFuZ19TdHJpbmdJSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nOworICAgICAgICBXcml0ZXIgdG9iaiA9IG5ldyBTdXBwb3J0X0FTaW1wbGVXcml0ZXIoMjEpOworICAgICAgICB0ZXN0U3RyaW5nID0gIjAxMjM0NTY3ODlhYmNkZWZnaGlqQUJDREVGR0hJSiI7CisgICAgICAgIHRvYmoud3JpdGUodGVzdFN0cmluZywgMCwgNSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc3R1ZmYgd3JpdHRlbiEiLCAiMDEyMzQiLCB0b2JqLnRvU3RyaW5nKCkpOworICAgICAgICB0b2JqLndyaXRlKHRlc3RTdHJpbmcsIDEwLCA1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzdHVmZiB3cml0dGVuISIsICIwMTIzNGFiY2RlIiwgdG9iai50b1N0cmluZygpKTsKKyAgICAgICAgdG9iai53cml0ZSh0ZXN0U3RyaW5nLCAyMCwgMTApOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHN0dWZmIHdyaXR0ZW4hIiwgIjAxMjM0YWJjZGVBQkNERUZHSElKIiwgdG9iai50b1N0cmluZygpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRvYmoud3JpdGUodGVzdFN0cmluZywgMzAsIDEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBub3QgdGhyb3duISIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdG9iai53cml0ZSh0ZXN0U3RyaW5nLCAyMCwgMSk7IC8vIEp1c3QgZmlsbCB0aGUgd3JpdGVyIHRvIGl0cyBsaW1pdCEKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRvYmoud3JpdGUodGVzdFN0cmluZywgMjksIDEpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbm90IHRocm93biEiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGVMamF2YV9sYW5nX1N0cmluZ0lJX0V4Y2VwdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gIk15IFRlc3QgU3RyaW5nIjsKKyAgICAgICAgV3JpdGVyIHRvYmogPSBuZXcgU3VwcG9ydF9BU2ltcGxlV3JpdGVyKDIxKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRvYmoud3JpdGUodGVzdFN0cmluZywgMzAsIDMxKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gbm90IHRocm93biEiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2JqLndyaXRlKHRlc3RTdHJpbmcsIC0xLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gbm90IHRocm93biEiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0b2JqLndyaXRlKHRlc3RTdHJpbmcsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gbm90IHRocm93biEiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PdXRwdXRTdHJlYW1Xcml0ZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL091dHB1dFN0cmVhbVdyaXRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZjllYzliCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9PdXRwdXRTdHJlYW1Xcml0ZXJUZXN0LmphdmEKQEAgLTAsMCArMSw5NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT3V0cHV0U3RyZWFtV3JpdGVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwcml2YXRlIGNsYXNzIEZsdXNoQ291bnRpbmdPdXRwdXRTdHJlYW0gZXh0ZW5kcyBPdXRwdXRTdHJlYW0geworICAgICAgICBpbnQgZmx1c2hDb3VudDsKKyAgICAgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHsKKyAgICAgICAgfQorICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgKytmbHVzaENvdW50OworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZsdXNoQ291bnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmx1c2hDb3VudGluZ091dHB1dFN0cmVhbSBvcyA9IG5ldyBGbHVzaENvdW50aW5nT3V0cHV0U3RyZWFtKCk7CisgICAgICAgIE91dHB1dFN0cmVhbVdyaXRlciB3cml0ZXIgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG9zLCAiVVRGLTgiKTsKKyAgICAgICAgY2hhcltdIGNoYXJzID0gbmV3IGNoYXJbMTYqMTAyNF07CisgICAgICAgIEFycmF5cy5maWxsKGNoYXJzLCAneCcpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICAgICAgICAgIHdyaXRlci53cml0ZShjaGFycyk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG9zLmZsdXNoQ291bnQpOworICAgICAgICB3cml0ZXIuZmx1c2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG9zLmZsdXNoQ291bnQpOworICAgICAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG9zLmZsdXNoQ291bnQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0Rmx1c2goYm9vbGVhbiBpbmNsdWRlU2Vjb25kSGFsZikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIE91dHB1dFN0cmVhbVdyaXRlciBoYXMgYW4gaW50ZXJuYWwgOEtpQiBidWZmZXIuCisgICAgICAgIC8vIFdlIHdyaXRlIGVub3VnaCBjaGFyYWN0ZXJzIHRvIGZpbGwgdGhhdCwgYnV0IGxlYXZlIGRhdGEgaW4gdGhlIGVuY29kZXIuCisgICAgICAgIC8vIChTcGVjaWZpY2FsbHksIGhhbGYgYSBzdXJyb2dhdGUgcGFpci4pCisgICAgICAgIC8vIE9uIGZsdXNoL2Nsb3NlLCB0aGUgd3JpdGVyIG5lZWRzIHRvIGFkbWl0IGRlZmVhdCBhbmQgd3JpdGUgdGhlIHJlcGxhY2VtZW50IGNoYXJhY3Rlci4KKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIE91dHB1dFN0cmVhbVdyaXRlciB3cml0ZXIgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKGJhb3MsICJVVEYtMzJCRSIpOworICAgICAgICBjaGFyW10gY3MgPSBuZXcgY2hhcls4MTkyLzQgKyAxXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoY3MsICd4Jyk7CisgICAgICAgIGNzW2NzLmxlbmd0aCAtIDFdID0gJ1x1ZDg0Mic7IC8vIE9uZSBoYWxmIG9mIGEgc3Vycm9nYXRlIHBhaXIgKHRoZSBvdGhlciBiZWluZyBVK2RmOWYpLgorICAgICAgICB3cml0ZXIud3JpdGUoY3MsIDAsIGNzLmxlbmd0aCk7CisgICAgICAgIHdyaXRlci5mbHVzaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoODE5MiwgYmFvcy5zaXplKCkpOyAvLyBKdXN0IHRoZSAneCdzIHNvIGZhci4KKyAgICAgICAgaWYgKGluY2x1ZGVTZWNvbmRIYWxmKSB7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoMHhkZjlmKTsKKyAgICAgICAgfQorICAgICAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICAgICAgLy8gV2Ugc2hvdWxkIGhhdmUgODE5MiAzMi1iaXQgYmlnLWVuZGlhbiAneCdzLi4uCisgICAgICAgIGJ5dGVbXSBieXRlcyA9IGJhb3MudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDgxOTYsIGJ5dGVzLmxlbmd0aCk7CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgd2hpbGUgKGkgPCA4MTkyKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDAsIGJ5dGVzW2krK10pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAwLCBieXRlc1tpKytdKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMCwgYnl0ZXNbaSsrXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpICd4JywgYnl0ZXNbaSsrXSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGluY2x1ZGVTZWNvbmRIYWxmKSB7CisgICAgICAgICAgICAvLyAuLi5mb2xsb3dlZCBieSBhIDMyLWJpdCBiaWctZW5kaWFuIFUrMjBiOWYuCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDB4MDAsIGJ5dGVzW2krK10pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweDAyLCBieXRlc1tpKytdKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHgwYiwgYnl0ZXNbaSsrXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDB4OWYsIGJ5dGVzW2krK10pOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gLi4uZm9sbG93ZWQgYnkgYSAzMi1iaXQgYmlnLWVuZGlhbiByZXBsYWNlbWVudCBjaGFyYWN0ZXIgKFUrZmZmZCkuCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDAsIGJ5dGVzW2krK10pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAwLCBieXRlc1tpKytdKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHhmZiwgYnl0ZXNbaSsrXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDB4ZmQsIGJ5dGVzW2krK10pOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZsdXNoX2hhbGZTdXJyb2dhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEZsdXNoKGZhbHNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rmx1c2hfd2hvbGVTdXJyb2dhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEZsdXNoKHRydWUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vUmFuZG9tQWNjZXNzRmlsZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vUmFuZG9tQWNjZXNzRmlsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMTE0MmQ1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9SYW5kb21BY2Nlc3NGaWxlVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBSYW5kb21BY2Nlc3NGaWxlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgRmlsZSBmaWxlOworCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbGUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJSYW5kb21BY2Nlc3NGaWxlVGVzdCIsICJ0bXAiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmlsZS5kZWxldGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2Vla1Rvb0xhcmdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFJhbmRvbUFjY2Vzc0ZpbGUgcmFmID0gbmV3IFJhbmRvbUFjY2Vzc0ZpbGUoZmlsZSwgInJ3Iik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYWYuc2VlayhMb25nLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0TGVuZ3RoVG9vTGFyZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUmFuZG9tQWNjZXNzRmlsZSByYWYgPSBuZXcgUmFuZG9tQWNjZXNzRmlsZShmaWxlLCAicnciKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhZi5zZXRMZW5ndGgoTG9uZy5NQVhfVkFMVUUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldExlbmd0aDY0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFJhbmRvbUFjY2Vzc0ZpbGUgcmFmID0gbmV3IFJhbmRvbUFjY2Vzc0ZpbGUoZmlsZSwgInJ3Iik7CisgICAgICAgIHJhZi5zZXRMZW5ndGgoMCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBmaWxlLmxlbmd0aCgpKTsKKyAgICAgICAgbG9uZyBtb3JlVGhhbkZvdXJHaWcgPSAoKGxvbmcpIEludGVnZXIuTUFYX1ZBTFVFKSArIDFMOworICAgICAgICByYWYuc2V0TGVuZ3RoKG1vcmVUaGFuRm91ckdpZyk7CisgICAgICAgIGFzc2VydEVxdWFscyhtb3JlVGhhbkZvdXJHaWcsIGZpbGUubGVuZ3RoKCkpOworICAgIH0KKworICAgIC8vIGh0dHA6Ly9iLzMwMTUwMjMKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmFuZG9tQWNjZXNzRmlsZUhhc0NsZWFudXBGaW5hbGl6ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVE9ETzogdGhpcyBhbHdheXMgc3VjY2VlZHMgb24gdGhlIGhvc3QgYmVjYXVzZSBvdXIgZGVmYXVsdCBvcGVuIGZpbGUgbGltaXQgaXMgMzJLaS4KKyAgICAgICAgLy8gQWRkIExpYmNvcmUub3MuZ2V0cmxpbWl0IGFuZCB1c2UgdGhhdCBpbnN0ZWFkIG9mIGhhcmQtY29kaW5nLgorICAgICAgICBpbnQgdG9vTWFueU9wZW5GaWxlcyA9IDIwMDA7CisgICAgICAgIEZpbGUgZmlsZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoIlJhbmRvbUFjY2Vzc0ZpbGVUZXN0IiwgInRtcCIpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRvb01hbnlPcGVuRmlsZXM7IGkrKykgeworICAgICAgICAgICAgY3JlYXRlUmFuZG9tQWNjZXNzRmlsZShmaWxlKTsKKyAgICAgICAgICAgIFN5c3RlbS5nYygpOworICAgICAgICAgICAgU3lzdGVtLnJ1bkZpbmFsaXphdGlvbigpOworICAgICAgICB9CisgICAgfQorICAgIHByaXZhdGUgdm9pZCBjcmVhdGVSYW5kb21BY2Nlc3NGaWxlKEZpbGUgZmlsZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRPRE86IGZpeCBvdXIgcmVnaXN0ZXIgbWFwcyBhbmQgcmVtb3ZlIHRoaXMgb3RoZXJ3aXNlIHVubmVjZXNzYXJ5CisgICAgICAgIC8vIGluZGlyZWN0aW9uISAoaHR0cDovL2IvNTQxMjU4MCkKKyAgICAgICAgbmV3IFJhbmRvbUFjY2Vzc0ZpbGUoZmlsZSwgInJ3Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERpcmVjdG9yaWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUmFuZG9tQWNjZXNzRmlsZSgiLiIsICJyIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUmFuZG9tQWNjZXNzRmlsZSgiLiIsICJydyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vU2VyaWFsaXphdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vU2VyaWFsaXphdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NGJlY2ZlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9TZXJpYWxpemF0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBsaWJjb3JlLmphdmEudXRpbC5TZXJpYWxpemFibGVUZXN0ZXI7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBTZXJpYWxpemF0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8vIGh0dHA6Ly9iLzQ0NzEyNDkKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXplRmllbGRNYWRlVHJhbnNpZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIHRoaXMgd2FzIGNyZWF0ZWQgYnkgc2VyaWFsaXppbmcgYSBGaWVsZE1hZGVUcmFuc2llbnQgd2l0aCBhIG5vbi0wIHRyYW5zaWVudEludAorICAgICAgICBTdHJpbmcgcyA9ICJhY2VkMDAwNTczNzIwMDM0NmM2OTYyNjM2ZjcyNjUyZTZhNjE3NjYxMmU2OTZmMmU1MzY1NzI2OTYxNmM2OTdhNjE3NDY5NmY2ZTU0NjU3IgorICAgICAgICAgICAgICAgICsgIjM3NDI0NDY2OTY1NmM2NDRkNjE2NDY1NTQ3MjYxNmU3MzY5NjU2ZTc0MDAwMDAwMDAwMDAwMDAwMDAyMDAwMTQ5MDAwYzc0NzI2MTZlNzM2IgorICAgICAgICAgICAgICAgICsgIjk2NTZlNzQ0OTZlNzQ3ODcwYWJhYmFiYWIiOworICAgICAgICBGaWVsZE1hZGVUcmFuc2llbnQgZGVzZXJpYWxpemVkID0gKEZpZWxkTWFkZVRyYW5zaWVudCkgU2VyaWFsaXphYmxlVGVzdGVyLmRlc2VyaWFsaXplSGV4KHMpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZGVzZXJpYWxpemVkLnRyYW5zaWVudEludCk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIEZpZWxkTWFkZVRyYW5zaWVudCBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOworICAgICAgICBwcml2YXRlIHRyYW5zaWVudCBpbnQgdHJhbnNpZW50SW50OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vU3RyZWFtVG9rZW5pemVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9TdHJlYW1Ub2tlbml6ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDE4ZDE5MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvaW8vU3RyZWFtVG9rZW5pemVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uU3RyZWFtVG9rZW5pemVyOworaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgU3RyZWFtVG9rZW5pemVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG93ZXJDYXNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KExvY2FsZS5VUyk7CisgICAgICAgIFN0cmVhbVRva2VuaXplciBzdCA9IG5ldyBTdHJlYW1Ub2tlbml6ZXIobmV3IFN0cmluZ1JlYWRlcigiYUliIGFJYiIpKTsKKyAgICAgICAgc3QubG93ZXJDYXNlTW9kZSh0cnVlKTsKKyAgICAgICAgc3QubmV4dFRva2VuKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiYWliIiwgc3Quc3ZhbCk7CisKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobmV3IExvY2FsZSgidHIiLCAiVFIiKSk7CisgICAgICAgIHN0Lm5leHRUb2tlbigpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFcdTAxMzFiIiwgc3Quc3ZhbCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0FycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOThlNDk3ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw4MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RBcHV0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBicyA9IG5ldyBieXRlWzFdOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnNbMl0gPSAwOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoPTE7IGluZGV4PTIiLCBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFnZXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJzID0gbmV3IGJ5dGVbMV07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBieXRlIGIgPSBic1syXTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImxlbmd0aD0xOyBpbmRleD0yIiwgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBcHV0V2lkZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkb3VibGVbXSBkcyA9IG5ldyBkb3VibGVbMV07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkc1syXSA9IDAuMDsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImxlbmd0aD0xOyBpbmRleD0yIiwgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZ2V0V2lkZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkb3VibGVbXSBkcyA9IG5ldyBkb3VibGVbMV07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkb3VibGUgZCA9IGRzWzJdOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoPTE7IGluZGV4PTIiLCBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFwdXRPYmplY3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0W10gb3MgPSBuZXcgT2JqZWN0WzFdOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3NbMl0gPSBudWxsOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoPTE7IGluZGV4PTIiLCBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFnZXRPYmplY3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0W10gb3MgPSBuZXcgT2JqZWN0WzFdOworICAgICAgICB0cnkgeworICAgICAgICAgICAgT2JqZWN0IG8gPSBvc1syXTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImxlbmd0aD0xOyBpbmRleD0yIiwgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9BcnJheVN0b3JlRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0FycmF5U3RvcmVFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzI1MjQ1ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9BcnJheVN0b3JlRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTU0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIEFycmF5U3RvcmVFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RBcnJheVN0b3JlRXhjZXB0aW9uX3N0b3JlMSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBPYmplY3RbXSBhcnJheSA9IG5ldyBTdHJpbmdbMTBdOworICAgICAgICBPYmplY3QgbyA9IG5ldyBFeGNlcHRpb24oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFycmF5WzBdID0gbzsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlTdG9yZUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImphdmEubGFuZy5FeGNlcHRpb24gY2Fubm90IGJlIHN0b3JlZCBpbiBhbiBhcnJheSBvZiB0eXBlICIKKyAgICAgICAgICAgICAgICAgICAgKyAiamF2YS5sYW5nLlN0cmluZ1tdIiwKKyAgICAgICAgICAgICAgICAgICAgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBcnJheVN0b3JlRXhjZXB0aW9uX3N0b3JlMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBPYmplY3RbXSBhcnJheSA9IG5ldyBOb25jZVsxMF1bXTsKKyAgICAgICAgT2JqZWN0IG8gPSBuZXcgSW50ZWdlcig1KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFycmF5WzBdID0gbzsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlTdG9yZUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJqYXZhLmxhbmcuSW50ZWdlciBjYW5ub3QgYmUgc3RvcmVkIGluIGFuIGFycmF5IG9mIHR5cGUgIgorICAgICAgICAgICAgICAgICAgICArICJsaWJjb3JlLmphdmEubGFuZy5BcnJheVN0b3JlRXhjZXB0aW9uVGVzdCROb25jZVtdW10iLAorICAgICAgICAgICAgICAgICAgICBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFycmF5U3RvcmVFeGNlcHRpb25fc3RvcmUzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdFtdIGFycmF5ID0gbmV3IEZsb2F0WzEwXVtdOworICAgICAgICBPYmplY3QgbyA9IG5ldyBOb25jZVsxXTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFycmF5WzBdID0gbzsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlTdG9yZUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJsaWJjb3JlLmphdmEubGFuZy5BcnJheVN0b3JlRXhjZXB0aW9uVGVzdCROb25jZVtdIGNhbm5vdCBiZSBzdG9yZWQgIgorICAgICAgICAgICAgICAgICAgICArICJpbiBhbiBhcnJheSBvZiB0eXBlIGphdmEubGFuZy5GbG9hdFtdW10iLAorICAgICAgICAgICAgICAgICAgICBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFycmF5U3RvcmVFeGNlcHRpb25fYXJyYXljb3B5MSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmdbXSBzcmMgPSBuZXcgU3RyaW5nW10geyBudWxsLCBudWxsLCBudWxsLCBudWxsLCAiaGVsbG8iLCAiZ29vZGJ5ZSIgfTsKKyAgICAgICAgSW50ZWdlcltdIGRlc3QgPSBuZXcgSW50ZWdlclsxMF07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHNyYywgMSwgZGVzdCwgMCwgNSk7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5U3RvcmVFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJzb3VyY2VbNF0gb2YgdHlwZSBqYXZhLmxhbmcuU3RyaW5nIGNhbm5vdCBiZSBzdG9yZWQgaW4gZGVzdGluYXRpb24gIgorICAgICAgICAgICAgICAgICAgICArICJhcnJheSBvZiB0eXBlIGphdmEubGFuZy5JbnRlZ2VyW10iLAorICAgICAgICAgICAgICAgICAgICBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFycmF5U3RvcmVFeGNlcHRpb25fYXJyYXljb3B5MigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmdbXSBzcmMgPSBuZXcgU3RyaW5nWzFdOworICAgICAgICBpbnRbXSBkZXN0ID0gbmV3IGludFsxXTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc3JjLCAwLCBkZXN0LCAwLCAxKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlTdG9yZUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJqYXZhLmxhbmcuU3RyaW5nW10gYW5kIGludFtdIGFyZSBpbmNvbXBhdGlibGUgYXJyYXkgdHlwZXMiLAorICAgICAgICAgICAgICAgICAgICBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFycmF5U3RvcmVFeGNlcHRpb25fYXJyYXljb3B5MygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmbG9hdFtdIHNyYyA9IG5ldyBmbG9hdFsxXTsKKyAgICAgICAgUnVubmFibGVbXSBkZXN0ID0gbmV3IFJ1bm5hYmxlWzFdOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzcmMsIDAsIGRlc3QsIDAsIDEpOworICAgICAgICB9IGNhdGNoIChBcnJheVN0b3JlRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImZsb2F0W10gYW5kIGphdmEubGFuZy5SdW5uYWJsZVtdIGFyZSBpbmNvbXBhdGlibGUgYXJyYXkgdHlwZXMiLAorICAgICAgICAgICAgICAgICAgICBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFycmF5U3RvcmVFeGNlcHRpb25fYXJyYXljb3B5NCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBib29sZWFuW10gc3JjID0gbmV3IGJvb2xlYW5bMV07CisgICAgICAgIGRvdWJsZVtdW10gZGVzdCA9IG5ldyBkb3VibGVbMV1bXTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc3JjLCAwLCBkZXN0LCAwLCAxKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlTdG9yZUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJib29sZWFuW10gYW5kIGRvdWJsZVtdW10gYXJlIGluY29tcGF0aWJsZSBhcnJheSB0eXBlcyIsCisgICAgICAgICAgICAgICAgICAgIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXJyYXlTdG9yZUV4Y2VwdGlvbl9hcnJheWNvcHk1KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzcmMgPSAiYmxvcnQiOworICAgICAgICBPYmplY3RbXSBkZXN0ID0gbmV3IE9iamVjdFsxXTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc3JjLCAwLCBkZXN0LCAwLCAxKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlTdG9yZUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJzb3VyY2Ugb2YgdHlwZSBqYXZhLmxhbmcuU3RyaW5nIGlzIG5vdCBhbiBhcnJheSIsCisgICAgICAgICAgICAgICAgICAgIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXJyYXlTdG9yZUV4Y2VwdGlvbl9hcnJheWNvcHk2KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdFtdIHNyYyA9IG5ldyBPYmplY3RbMV07CisgICAgICAgIEludGVnZXIgZGVzdCA9IG5ldyBJbnRlZ2VyKDUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzcmMsIDAsIGRlc3QsIDAsIDEpOworICAgICAgICB9IGNhdGNoIChBcnJheVN0b3JlRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImRlc3RpbmF0aW9uIG9mIHR5cGUgamF2YS5sYW5nLkludGVnZXIgaXMgbm90IGFuIGFycmF5IiwKKyAgICAgICAgICAgICAgICAgICAgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBcnJheVN0b3JlRXhjZXB0aW9uX2FycmF5Y29weTcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogVGhpcyB0ZXN0IGRlbW9uc3RyYXRlcyB0aGF0IHRoZSBleGNlcHRpb24gbWVzc2FnZSBjb21wbGFpbnMKKyAgICAgICAgICogYWJvdXQgdGhlIHNvdXJjZSBpbiBjYXNlcyB3aGVyZSBuZWl0aGVyIHNvdXJjZSBub3IKKyAgICAgICAgICogZGVzdGluYXRpb24gaXMgYW4gYXJyYXkuCisgICAgICAgICAqLworICAgICAgICBOb25jZSBzcmMgPSBuZXcgTm9uY2UoKTsKKyAgICAgICAgU3RyaW5nIGRlc3QgPSAiYmxvcnQiOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzcmMsIDAsIGRlc3QsIDAsIDEpOworICAgICAgICB9IGNhdGNoIChBcnJheVN0b3JlRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInNvdXJjZSBvZiB0eXBlIGxpYmNvcmUuamF2YS5sYW5nLkFycmF5U3RvcmVFeGNlcHRpb25UZXN0JE5vbmNlICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaXMgbm90IGFuIGFycmF5IiwKKyAgICAgICAgICAgICAgICAgICAgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgY2xhc3MgaXMganVzdCB1c2VkIHNvIHRoYXQgd2UgaGF2ZSBhbiBleGFtcGxlIG9mIGdldHRpbmcgYQorICAgICAqIG1lc3NhZ2UgdGhhdCBpbmNsdWRlcyBhbiBpbm5lciBjbGFzcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBOb25jZSB7CisgICAgICAgIC8vIFRoaXMgc3BhY2UgaW50ZW50aW9uYWxseSBsZWZ0IGJsYW5rLgorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9Cb29sZWFuVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0Jvb2xlYW5UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWVlNTQyMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9Cb29sZWFuVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitwdWJsaWMgY2xhc3MgQm9vbGVhblRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RfVFJVRSgpIHsKKyAgICAgICAgYXNzZXJ0U2FtZShCb29sZWFuLlRSVUUsIEJvb2xlYW4udmFsdWVPZih0cnVlKSk7CisgICAgICAgIGFzc2VydFRydWUoQm9vbGVhbi5UUlVFLmJvb2xlYW5WYWx1ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0ZBTFNFKCkgeworICAgICAgICBhc3NlcnRTYW1lKEJvb2xlYW4uRkFMU0UsIEJvb2xlYW4udmFsdWVPZihmYWxzZSkpOworICAgICAgICBhc3NlcnRGYWxzZShCb29sZWFuLkZBTFNFLmJvb2xlYW5WYWx1ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbXBhcmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIEJvb2xlYW4uY29tcGFyZSh0cnVlLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBCb29sZWFuLmNvbXBhcmUoZmFsc2UsIGZhbHNlKSk7CisgICAgICAgIGFzc2VydFRydWUoQm9vbGVhbi5jb21wYXJlKGZhbHNlLCB0cnVlKSA8IDApOworICAgICAgICBhc3NlcnRUcnVlKEJvb2xlYW4uY29tcGFyZSh0cnVlLCBmYWxzZSkgPiAwKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvQnl0ZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9CeXRlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2MWE3ZjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvQnl0ZVRlc3QuamF2YQpAQCAtMCwwICsxLDM0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZzsKKworcHVibGljIGNsYXNzIEJ5dGVUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbXBhcmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgYnl0ZSBtaW4gPSBCeXRlLk1JTl9WQUxVRTsKKyAgICAgICAgZmluYWwgYnl0ZSB6ZXJvID0gKGJ5dGUpIDA7CisgICAgICAgIGZpbmFsIGJ5dGUgbWF4ID0gQnl0ZS5NQVhfVkFMVUU7CisgICAgICAgIGFzc2VydFRydWUoQnl0ZS5jb21wYXJlKG1heCwgIG1heCkgID09IDApOworICAgICAgICBhc3NlcnRUcnVlKEJ5dGUuY29tcGFyZShtaW4sICBtaW4pICA9PSAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShCeXRlLmNvbXBhcmUoemVybywgemVybykgPT0gMCk7CisgICAgICAgIGFzc2VydFRydWUoQnl0ZS5jb21wYXJlKG1heCwgIHplcm8pID4gMCk7CisgICAgICAgIGFzc2VydFRydWUoQnl0ZS5jb21wYXJlKG1heCwgIG1pbikgID4gMCk7CisgICAgICAgIGFzc2VydFRydWUoQnl0ZS5jb21wYXJlKHplcm8sIG1heCkgIDwgMCk7CisgICAgICAgIGFzc2VydFRydWUoQnl0ZS5jb21wYXJlKHplcm8sIG1pbikgID4gMCk7CisgICAgICAgIGFzc2VydFRydWUoQnl0ZS5jb21wYXJlKG1pbiwgIHplcm8pIDwgMCk7CisgICAgICAgIGFzc2VydFRydWUoQnl0ZS5jb21wYXJlKG1pbiwgIG1heCkgIDwgMCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0NoYXJhY3RlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9DaGFyYWN0ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWRiYzI4ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9DaGFyYWN0ZXJUZXN0LmphdmEKQEAgLTAsMCArMSwxMTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitwdWJsaWMgY2xhc3MgQ2hhcmFjdGVyVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdF92YWx1ZU9mQygpIHsKKyAgICAgICAgLy8gVGhlIEpMUyByZXF1aXJlcyBjYWNoaW5nIGZvciBjaGFycyBiZXR3ZWVuICJcdTAwMDAgdG8gXHUwMDdmIjoKKyAgICAgICAgLy8gaHR0cDovL2phdmEuc3VuLmNvbS9kb2NzL2Jvb2tzL2pscy90aGlyZF9lZGl0aW9uL2h0bWwvY29udmVyc2lvbnMuaHRtbCM1LjEuNworICAgICAgICAvLyBIYXJtb255IGNhY2hlcyAwLTUxMiBhbmQgdGVzdHMgZm9yIHRoaXMgYmVoYXZpb3IsIHNvIHdlIHN1cHByZXNzIHRoYXQgdGVzdCBhbmQgdXNlIHRoaXMuCisgICAgICAgIGZvciAoY2hhciBjID0gJ1x1MDAwMCc7IGMgPD0gJ1x1MDA3Zic7ICsrYykgeworICAgICAgICAgICAgQ2hhcmFjdGVyIGUgPSBuZXcgQ2hhcmFjdGVyKGMpOworICAgICAgICAgICAgQ2hhcmFjdGVyIGEgPSBDaGFyYWN0ZXIudmFsdWVPZihjKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhlLCBhKTsKKyAgICAgICAgICAgIGFzc2VydFNhbWUoQ2hhcmFjdGVyLnZhbHVlT2YoYyksIENoYXJhY3Rlci52YWx1ZU9mKGMpKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBjID0gJ1x1MDA4MCc7IGMgPD0gQ2hhcmFjdGVyLk1BWF9WQUxVRTsgKytjKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobmV3IENoYXJhY3RlcigoY2hhcikgYyksIENoYXJhY3Rlci52YWx1ZU9mKChjaGFyKSBjKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzQm1wQ29kZVBvaW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoQ2hhcmFjdGVyLmlzQm1wQ29kZVBvaW50KDB4MDAwMCkpOworICAgICAgICBhc3NlcnRUcnVlKENoYXJhY3Rlci5pc0JtcENvZGVQb2ludCgweDA2NjYpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShDaGFyYWN0ZXIuaXNCbXBDb2RlUG9pbnQoMHhmZmZmKSk7CisgICAgICAgIGFzc2VydEZhbHNlKENoYXJhY3Rlci5pc0JtcENvZGVQb2ludCgweDEwMDAwKSk7CisgICAgICAgIGFzc2VydEZhbHNlKENoYXJhY3Rlci5pc0JtcENvZGVQb2ludCgtMSkpOworICAgICAgICBhc3NlcnRGYWxzZShDaGFyYWN0ZXIuaXNCbXBDb2RlUG9pbnQoSW50ZWdlci5NQVhfVkFMVUUpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoQ2hhcmFjdGVyLmlzQm1wQ29kZVBvaW50KEludGVnZXIuTUlOX1ZBTFVFKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc1N1cnJvZ2F0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShDaGFyYWN0ZXIuaXNTdXJyb2dhdGUoJ1x1MDAwMCcpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoQ2hhcmFjdGVyLmlzU3Vycm9nYXRlKCdcdTA2NjYnKSk7CisgICAgICAgIGFzc2VydEZhbHNlKENoYXJhY3Rlci5pc1N1cnJvZ2F0ZSgoY2hhcikgKENoYXJhY3Rlci5NSU5fU1VSUk9HQVRFIC0gMSkpKTsKKyAgICAgICAgZm9yIChjaGFyIGNoID0gQ2hhcmFjdGVyLk1JTl9TVVJST0dBVEU7IGNoIDw9IENoYXJhY3Rlci5NQVhfU1VSUk9HQVRFOyArK2NoKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKENoYXJhY3Rlci5pc1N1cnJvZ2F0ZShjaCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEZhbHNlKENoYXJhY3Rlci5pc1N1cnJvZ2F0ZSgoY2hhcikgKENoYXJhY3Rlci5NQVhfU1VSUk9HQVRFICsgMSkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hpZ2hTdXJyb2dhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGhlIGJlaGF2aW9yIGZvciBub24tc3VwcGxlbWVudGFyeSBjb2RlIHBvaW50cyAobGlrZSB0aGVzZSB0d28pIGlzIHVuZGVmaW5lZC4KKyAgICAgICAgLy8gVGhlc2UgYXJlIHRoZSBvYnZpb3VzIHJlc3VsdHMgaWYgeW91IGRvbid0IGRvIGFueXRoaW5nIHNwZWNpYWwuCisgICAgICAgIGFzc2VydEVxdWFscygweGQ3YzAsIENoYXJhY3Rlci5oaWdoU3Vycm9nYXRlKDB4MDAwMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHhkN2MxLCBDaGFyYWN0ZXIuaGlnaFN1cnJvZ2F0ZSgweDA2NjYpKTsKKyAgICAgICAgLy8gVGhlc2UgdHdvIHRlc3RzIG11c3QgcGFzcywgdGhvdWdoLgorICAgICAgICBhc3NlcnRFcXVhbHMoMHhkODAwLCBDaGFyYWN0ZXIuaGlnaFN1cnJvZ2F0ZSgweDAxMDAwMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHhkYmZmLCBDaGFyYWN0ZXIuaGlnaFN1cnJvZ2F0ZSgweDEwZmZmZikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbG93U3Vycm9nYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRoZSBiZWhhdmlvciBmb3Igbm9uLXN1cHBsZW1lbnRhcnkgY29kZSBwb2ludHMgKGxpa2UgdGhlc2UgdHdvKSBpcyB1bmRlZmluZWQuCisgICAgICAgIC8vIFRoZXNlIGFyZSB0aGUgb2J2aW91cyByZXN1bHRzIGlmIHlvdSBkb24ndCBkbyBhbnl0aGluZyBzcGVjaWFsLgorICAgICAgICBhc3NlcnRFcXVhbHMoMHhkYzAwLCBDaGFyYWN0ZXIubG93U3Vycm9nYXRlKDB4MDAwMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHhkZTY2LCBDaGFyYWN0ZXIubG93U3Vycm9nYXRlKDB4MDY2NikpOworICAgICAgICAvLyBUaGVzZSB0d28gdGVzdHMgbXVzdCBwYXNzLCB0aG91Z2guCisgICAgICAgIGFzc2VydEVxdWFscygweGRjMDAsIENoYXJhY3Rlci5sb3dTdXJyb2dhdGUoMHgwMTAwMDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4ZGZmZiwgQ2hhcmFjdGVyLmxvd1N1cnJvZ2F0ZSgweDEwZmZmZikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TmFtZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBDaGFyYWN0ZXIuZ2V0TmFtZSByZXF1aXJlcyB0aGUgY29ycmVzcG9uZGluZyBJQ1UgZGF0YS4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJOVUxMIiwgQ2hhcmFjdGVyLmdldE5hbWUoMHgwMDAwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQkVMTCIsIENoYXJhY3Rlci5nZXROYW1lKDB4MDAwNykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkxBVElOIFNNQUxMIExFVFRFUiBMIiwgQ2hhcmFjdGVyLmdldE5hbWUoJ2wnKSk7CisgICAgICAgIC8vIFRoaXMgY2hhbmdlZCBuYW1lIGZyb20gVW5pY29kZSAxLjAuIFVzZWQgdG8gYmUgIk9QRU5JTkcuLi4iLgorICAgICAgICBhc3NlcnRFcXVhbHMoIkxFRlQgQ1VSTFkgQlJBQ0tFVCIsIENoYXJhY3Rlci5nZXROYW1lKCd7JykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFSQUJJQy1JTkRJQyBESUdJVCBTSVgiLCBDaGFyYWN0ZXIuZ2V0TmFtZSgweDA2NjYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJMSU5FQVIgQiBTWUxMQUJMRSBCMDA4IEEiLCBDaGFyYWN0ZXIuZ2V0TmFtZSgweDAxMDAwMCkpOworCisgICAgICAgIC8vIFNvbWUgcHJpdmF0ZSB1c2UgY29kZSBwb2ludHMuCisgICAgICAgIGFzc2VydEVxdWFscygiUFJJVkFURSBVU0UgQVJFQSBFMDAwIiwgQ2hhcmFjdGVyLmdldE5hbWUoMHhlMDAwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU1VQUExFTUVOVEFSWSBQUklWQVRFIFVTRSBBUkVBIEEgRjAwMDAiLCBDaGFyYWN0ZXIuZ2V0TmFtZSgweGYwMDAwKSk7CisKKyAgICAgICAgLy8gQW4gdW5hc3NpZ25lZCBjb2RlIHBvaW50LgorICAgICAgICBhc3NlcnROdWxsKENoYXJhY3Rlci5nZXROYW1lKDB4MTBmZmZmKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENoYXJhY3Rlci5nZXROYW1lKC0xKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENoYXJhY3Rlci5nZXROYW1lKEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENoYXJhY3Rlci5nZXROYW1lKEludGVnZXIuTUlOX1ZBTFVFKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbXBhcmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIENoYXJhY3Rlci5jb21wYXJlKCdhJywgJ2EnKSk7CisgICAgICAgIGFzc2VydFRydWUoQ2hhcmFjdGVyLmNvbXBhcmUoJ2EnLCAnYicpIDwgMCk7CisgICAgICAgIGFzc2VydFRydWUoQ2hhcmFjdGVyLmNvbXBhcmUoJ2InLCAnYScpID4gMCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0NsYXNzQ2FzdEV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9DbGFzc0Nhc3RFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWMzYWE0NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9DbGFzc0Nhc3RFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSwxODkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5BcnJheTsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bU1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBDbGFzc0Nhc3RFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RDYXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdCBvID0gbmV3IEV4Y2VwdGlvbigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHMgPSAoU3RyaW5nKSBvOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiamF2YS5sYW5nLkV4Y2VwdGlvbiBjYW5ub3QgYmUgY2FzdCB0byBqYXZhLmxhbmcuU3RyaW5nIiwgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDbGFzc0Nhc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0IG8gPSBuZXcgRXhjZXB0aW9uKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcuY2xhc3MuY2FzdChvKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImphdmEubGFuZy5FeGNlcHRpb24gY2Fubm90IGJlIGNhc3QgdG8gamF2YS5sYW5nLlN0cmluZyIsIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xhc3NBc1N1YmNsYXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFeGNlcHRpb24uY2xhc3MuYXNTdWJjbGFzcyhTdHJpbmcuY2xhc3MpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiamF2YS5sYW5nLkV4Y2VwdGlvbiBjYW5ub3QgYmUgY2FzdCB0byBqYXZhLmxhbmcuU3RyaW5nIiwKKyAgICAgICAgICAgICAgICAgICAgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDYXN0T3BlcmF0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE9iamVjdCBvID0gKElucHV0U3RyZWFtKSBtYWtlSW50ZWdlcigpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiamF2YS5sYW5nLkludGVnZXIgY2Fubm90IGJlIGNhc3QgdG8gamF2YS5pby5JbnB1dFN0cmVhbSIsCisgICAgICAgICAgICAgICAgICAgIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2FzdE9wZXJhdG9yV2l0aEFycmF5cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgT2JqZWN0IG8gPSAoRSkgbWFrZUFycmF5KFN0cmluZy5jbGFzcyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJqYXZhLmxhbmcuU3RyaW5nW10gY2Fubm90IGJlIGNhc3QgdG8gIgorICAgICAgICAgICAgICAgICAgICArICJsaWJjb3JlLmphdmEubGFuZy5DbGFzc0Nhc3RFeGNlcHRpb25UZXN0JEUiLAorICAgICAgICAgICAgICAgICAgICBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE9iamVjdCBvID0gKEUpIG1ha2VBcnJheShmbG9hdC5jbGFzcyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmbG9hdFtdIGNhbm5vdCBiZSBjYXN0IHRvIGxpYmNvcmUuamF2YS5sYW5nLkNsYXNzQ2FzdEV4Y2VwdGlvblRlc3QkRSIsCisgICAgICAgICAgICAgICAgICAgIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgT2JqZWN0IG8gPSAoRSkgbWFrZUFycmF5KGNoYXJbXS5jbGFzcyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyW11bXSBjYW5ub3QgYmUgY2FzdCB0byBsaWJjb3JlLmphdmEubGFuZy5DbGFzc0Nhc3RFeGNlcHRpb25UZXN0JEUiLAorICAgICAgICAgICAgICAgICAgICBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE9iamVjdCBvID0gKE9iamVjdFtdW11bXSkgbWFrZUludGVnZXIoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImphdmEubGFuZy5JbnRlZ2VyIGNhbm5vdCBiZSBjYXN0IHRvIGphdmEubGFuZy5PYmplY3RbXVtdW10iLAorICAgICAgICAgICAgICAgICAgICBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSGVscGVyIGZvciB7QGxpbmsgI3Rlc3RDYXN0T3BlcmF0b3J9IGFuZCB7QGxpbmsKKyAgICAgKiAjdGVzdENhc3RPcGVyYXRvcldpdGhBcnJheXN9LCBhYm92ZS4gSXQncyBpbXBvcnRhbnQgdGhhdCB0aGUKKyAgICAgKiByZXR1cm4gdHlwZSBpcyB7QGNvZGUgT2JqZWN0fSwgc2luY2Ugb3RoZXJ3aXNlIHRoZSBjb21waWxlcgorICAgICAqIHdpbGwganVzdCByZWplY3QgdGhlIGNvZGUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgT2JqZWN0IG1ha2VJbnRlZ2VyKCkgeworICAgICAgICByZXR1cm4gbmV3IEludGVnZXIoNSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSGVscGVyIGZvciB7QGxpbmsgI3Rlc3RDYXN0T3BlcmF0b3JXaXRoQXJyYXlzfSBhYm92ZS4gSXQncyBpbXBvcnRhbnQgdGhhdAorICAgICAqIHRoZSByZXR1cm4gdHlwZSBpcyB7QGNvZGUgT2JqZWN0fS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBPYmplY3QgbWFrZUFycmF5KENsYXNzIGNsYXp6KSB7CisgICAgICAgIHJldHVybiBBcnJheS5uZXdJbnN0YW5jZShjbGF6eiwgMSk7CisgICAgfQorCisgICAgZW51bSBFIHsgQSwgQiwgQyB9OworICAgIGVudW0gRiB7IEEsIEIsIEMgfTsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbnVtTWFwUHV0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEVudW1NYXAgbSA9IG5ldyBFbnVtTWFwKEUuY2xhc3MpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbS5wdXQoRi5BLCAid29ybGQiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNaW5pRW51bVNldEFkZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBFbnVtU2V0IG0gPSBFbnVtU2V0Lm5vbmVPZihFLmNsYXNzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG0uYWRkKEYuQSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWluaUVudW1TZXRBZGRBbGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRW51bVNldCBtID0gRW51bVNldC5ub25lT2YoRS5jbGFzcyk7CisgICAgICAgIEVudW1TZXQgbiA9IEVudW1TZXQuYWxsT2YoRi5jbGFzcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLmFkZEFsbChuKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGVudW0gSHVnZUUgeworICAgICAgICBBMCwgQjAsIEMwLCBEMCwgRTAsIEYwLCBHMCwgSDAsIEkwLCBKMCwgSzAsIEwwLCBNMCwgTjAsIE8wLCBQMCwgUTAsIFIwLCBTMCwgVDAsIFUwLCBWMCwgVzAsIFgwLCBZMCwgWjAsCisgICAgICAgIEExLCBCMSwgQzEsIEQxLCBFMSwgRjEsIEcxLCBIMSwgSTEsIEoxLCBLMSwgTDEsIE0xLCBOMSwgTzEsIFAxLCBRMSwgUjEsIFMxLCBUMSwgVTEsIFYxLCBXMSwgWDEsIFkxLCBaMSwKKyAgICAgICAgQTIsIEIyLCBDMiwgRDIsIEUyLCBGMiwgRzIsIEgyLCBJMiwgSjIsIEsyLCBMMiwgTTIsIE4yLCBPMiwgUDIsIFEyLCBSMiwgUzIsIFQyLCBVMiwgVjIsIFcyLCBYMiwgWTIsIFoyLAorICAgIH07CisgICAgZW51bSBIdWdlRiB7CisgICAgICAgIEEwLCBCMCwgQzAsIEQwLCBFMCwgRjAsIEcwLCBIMCwgSTAsIEowLCBLMCwgTDAsIE0wLCBOMCwgTzAsIFAwLCBRMCwgUjAsIFMwLCBUMCwgVTAsIFYwLCBXMCwgWDAsIFkwLCBaMCwKKyAgICAgICAgQTEsIEIxLCBDMSwgRDEsIEUxLCBGMSwgRzEsIEgxLCBJMSwgSjEsIEsxLCBMMSwgTTEsIE4xLCBPMSwgUDEsIFExLCBSMSwgUzEsIFQxLCBVMSwgVjEsIFcxLCBYMSwgWTEsIFoxLAorICAgICAgICBBMiwgQjIsIEMyLCBEMiwgRTIsIEYyLCBHMiwgSDIsIEkyLCBKMiwgSzIsIEwyLCBNMiwgTjIsIE8yLCBQMiwgUTIsIFIyLCBTMiwgVDIsIFUyLCBWMiwgVzIsIFgyLCBZMiwgWjIsCisgICAgfTsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RIdWdlRW51bVNldEFkZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBFbnVtU2V0IG0gPSBFbnVtU2V0Lm5vbmVPZihIdWdlRS5jbGFzcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLmFkZChIdWdlRi5BMCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SHVnZUVudW1TZXRBZGRBbGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRW51bVNldCBtID0gRW51bVNldC5ub25lT2YoSHVnZUUuY2xhc3MpOworICAgICAgICBFbnVtU2V0IG4gPSBFbnVtU2V0LmFsbE9mKEh1Z2VGLmNsYXNzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG0uYWRkQWxsKG4pOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0NsYXNzTm90Rm91bmRFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZWI5N2MyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0NsYXNzTm90Rm91bmRFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWxsZWdhbE5hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFRoZXJlIGlzIG5vIHN1Y2ggdGhpbmcgYXMgYW4gYXJyYXkgb2Ygdm9pZC4KKyAgICAgICAgICAgIENsYXNzLmZvck5hbWUoIltWIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiW1YiLCBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFZhbGlkTmFtZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3MuZm9yTmFtZSgiYmxvcnQuWm9yY2giKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJibG9ydC5ab3JjaCIsIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmFsaWRBcnJheU5hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENsYXNzLmZvck5hbWUoIltbTGJsb3J0LlpvcmNoOyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIltbTGJsb3J0LlpvcmNoOyIsIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvRG91YmxlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0RvdWJsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ODdkM2UzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0RvdWJsZVRlc3QuamF2YQpAQCAtMCwwICsxLDEzMCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBEb3VibGVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3REb3VibGVUb1N0cmluZ1Vuc2lnbmVkRGl2aWRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIGh0dHA6Ly9iLzMyMzgzMzMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIwLjAwOCIsIERvdWJsZS50b1N0cmluZygwLjAwOCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjAuMDA4MzY2IiwgRG91YmxlLnRvU3RyaW5nKDAuMDA4MzY2KSk7CisgICAgICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9MTQwMzMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIwLjAwOSIsIERvdWJsZS50b1N0cmluZygwLjAwOSkpOworICAgICAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTE0MzAyCisgICAgICAgIGFzc2VydEVxdWFscygiMC4wMDg1Njc4NTYwMTI2Mzg5ODYiLCBEb3VibGUudG9TdHJpbmcoMC4wMDg1Njc4NTYwMTI2Mzg5ODYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIwLjAxMDIwNjcxMzc1MjIyOTg5NiIsIERvdWJsZS50b1N0cmluZygwLjAxMDIwNjcxMzc1MjIyOTg5NikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROYW1lZERvdWJsZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5OYU4sIERvdWJsZS5wYXJzZURvdWJsZSgiTmFOIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLk5hTiwgRG91YmxlLnBhcnNlRG91YmxlKCItTmFOIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLk5hTiwgRG91YmxlLnBhcnNlRG91YmxlKCIrTmFOIikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgRG91YmxlLnBhcnNlRG91YmxlKCJOTmFOIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEb3VibGUucGFyc2VEb3VibGUoIk5hTk4iKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCBEb3VibGUucGFyc2VEb3VibGUoIitJbmZpbml0eSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgRG91YmxlLnBhcnNlRG91YmxlKCJJbmZpbml0eSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSwgRG91YmxlLnBhcnNlRG91YmxlKCItSW5maW5pdHkiKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEb3VibGUucGFyc2VEb3VibGUoIklJbmZpbml0eSIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgRG91YmxlLnBhcnNlRG91YmxlKCJJbmZpbml0eXkiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3VmZml4UGFyc2luZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmdbXSBiYWRTdHJpbmdzID0geyAiMWZmIiwgIjFmZCIsICIxZGYiLCAiMWRkIiB9OworICAgICAgICBmb3IgKFN0cmluZyBzdHJpbmcgOiBiYWRTdHJpbmdzKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIERvdWJsZS5wYXJzZURvdWJsZShzdHJpbmcpOworICAgICAgICAgICAgICAgIGZhaWwoc3RyaW5nKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygxLjAsIERvdWJsZS5wYXJzZURvdWJsZSgiMWYiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLjAsIERvdWJsZS5wYXJzZURvdWJsZSgiMWQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLjAsIERvdWJsZS5wYXJzZURvdWJsZSgiMUYiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLjAsIERvdWJsZS5wYXJzZURvdWJsZSgiMUQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLjAsIERvdWJsZS5wYXJzZURvdWJsZSgiMS5EIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMS4wLCBEb3VibGUucGFyc2VEb3VibGUoIjEuRTBEIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMS4wLCBEb3VibGUucGFyc2VEb3VibGUoIi4xRTFEIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFeHBvbmVudFBhcnNpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nW10gc3RyaW5ncyA9IHsKKyAgICAgICAgICAgIC8vIEV4cG9uZW50cyBtaXNzaW5nIGludGVnZXIgdmFsdWVzLgorICAgICAgICAgICAgIjEuMGUiLCAiMS4wZSsiLCAiMS4wZS0iLAorICAgICAgICAgICAgLy8gRXhwb25lbnRzIHdpdGggdG9vIG1hbnkgZXhwbGljaXQgc2lnbnMuCisgICAgICAgICAgICAiMS4wZSsrMSIsICIxLjBlKy0xIiwgIjEuMGUtKzEiLCAiMS4wZS0tMSIsCisgICAgICAgICAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTIwNzI4CisgICAgICAgICAgICAic2F2ZSsiLCAic2F2ZS0iLAorICAgICAgICB9OworICAgICAgICBmb3IgKFN0cmluZyBzdHJpbmcgOiBzdHJpbmdzKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIERvdWJsZS5wYXJzZURvdWJsZShzdHJpbmcpOworICAgICAgICAgICAgICAgIGZhaWwoc3RyaW5nKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMGUtMzIzLCBEb3VibGUucGFyc2VEb3VibGUoIjEuMGUtMzIzIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMC4wLCBEb3VibGUucGFyc2VEb3VibGUoIjEuMGUtMzI0IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEuMGUtMzIzLCBEb3VibGUucGFyc2VEb3VibGUoIi0xLjBlLTMyMyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0wLjAsIERvdWJsZS5wYXJzZURvdWJsZSgiLTEuMGUtMzI0IikpOworCisgICAgICAgIGFzc2VydEVxdWFscygxLjBlKzMwOCwgRG91YmxlLnBhcnNlRG91YmxlKCIxLjBlKzMwOCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgRG91YmxlLnBhcnNlRG91YmxlKCIxLjBlKzMwOSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLjBlKzMwOCwgRG91YmxlLnBhcnNlRG91YmxlKCItMS4wZSszMDgiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFksIERvdWJsZS5wYXJzZURvdWJsZSgiLTEuMGUrMzA5IikpOworCisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIERvdWJsZS5wYXJzZURvdWJsZSgiMS4wZSs5OTk5OTk5OTk5IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLk5FR0FUSVZFX0lORklOSVRZLCBEb3VibGUucGFyc2VEb3VibGUoIi0xLjBlKzk5OTk5OTk5OTkiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLjAsIERvdWJsZS5wYXJzZURvdWJsZSgiMS4wZS05OTk5OTk5OTk5IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTAuMCwgRG91YmxlLnBhcnNlRG91YmxlKCItMS4wZS05OTk5OTk5OTk5IikpOworCisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIERvdWJsZS5wYXJzZURvdWJsZSgiMzIwLjBlKzIxNDc0ODM2NDciKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMC4wLCBEb3VibGUucGFyc2VEb3VibGUoIi0xLjRlLTIxNDc0ODMzMTQiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyB2YWx1ZSBoYXMgYmVlbiBrbm93biB0byBjYXVzZSBqYXZhYyBhbmQgamF2YSB0byBpbmZpbml0ZSBsb29wLgorICAgICAqIGh0dHA6Ly93d3cuZXhwbG9yaW5nYmluYXJ5LmNvbS9qYXZhLWhhbmdzLXdoZW4tY29udmVydGluZy0yLTIyNTA3Mzg1ODUwNzIwMTJlLTMwOC8KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VMYXJnZXN0U3Vibm9ybWFsRG91YmxlUHJlY2lzaW9uKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoMi4yMjUwNzM4NTg1MDcyMDE0RS0zMDgsIERvdWJsZS5wYXJzZURvdWJsZSgiMi4yMjUwNzM4NTg1MDcyMDEyZS0zMDgiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLjIyNTA3Mzg1ODUwNzIwMTRFLTMwOCwgRG91YmxlLnBhcnNlRG91YmxlKCIwLjAwMDIyMjUwNzM4NTg1MDcyMDEyZS0zMDQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLjIyNTA3Mzg1ODUwNzIwMTRFLTMwOCwgRG91YmxlLnBhcnNlRG91YmxlKCIwMDAwMDAwMi4yMjUwNzM4NTg1MDcyMDEyZS0zMDgiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLjIyNTA3Mzg1ODUwNzIwMTRFLTMwOCwgRG91YmxlLnBhcnNlRG91YmxlKCIyLjIyNTA3Mzg1ODUwNzIwMTIwMDAwMGUtMzA4IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMi4yMjUwNzM4NTg1MDcyMDE0RS0zMDgsIERvdWJsZS5wYXJzZURvdWJsZSgiMi4yMjUwNzM4NTg1MDcyMDEyZS0wMDMwOCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIuMjI1MDczODU4NTA3MjAxNEUtMzA4LCBEb3VibGUucGFyc2VEb3VibGUoIjIuMjI1MDczODU4NTA3MjAxMjk5NzgwMDFlLTMwOCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0yLjIyNTA3Mzg1ODUwNzIwMTRFLTMwOCwgRG91YmxlLnBhcnNlRG91YmxlKCItMi4yMjUwNzM4NTg1MDcyMDEyZS0zMDgiKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0Zsb2F0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0Zsb2F0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkyZTdhZTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvRmxvYXRUZXN0LmphdmEKQEAgLTAsMCArMSwxMjQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitwdWJsaWMgY2xhc3MgRmxvYXRUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICAvLyBOZWVkZWQgdG8gcHJldmVudCB0ZXN0VmVyaWZpZXJUeXBpbmcgZnJvbSBzdGF0aWNhbGx5IHJlc29sdmluZyB0aGUgaWYgc3RhdGVtZW50LgorICAgIHN0YXRpYyBib29sZWFuIHRlc3RWZXJpZmllclR5cGluZ0Jvb2wgPSBmYWxzZTsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdmFsdWVPZl9TdHJpbmcxKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRoaXMgdGhyZXcgT3V0T2ZNZW1vcnlFeGNlcHRpb24uCisgICAgICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9NDE4NQorICAgICAgICBhc3NlcnRFcXVhbHMoMjM1OC4xNjYwMTZmLCBGbG9hdC52YWx1ZU9mKCIyMzU4LjE2NjAxNiIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3ZhbHVlT2ZfU3RyaW5nMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUaGlzIHRocmV3IE91dE9mTWVtb3J5RXhjZXB0aW9uLgorICAgICAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTMxNTYKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0yLjE0NzQ4MzY1RTlmLCBGbG9hdC52YWx1ZU9mKFN0cmluZy52YWx1ZU9mKEludGVnZXIuTUlOX1ZBTFVFKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROYW1lZEZsb2F0cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoRmxvYXQuTmFOLCBGbG9hdC5wYXJzZUZsb2F0KCJOYU4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhGbG9hdC5OYU4sIEZsb2F0LnBhcnNlRmxvYXQoIi1OYU4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhGbG9hdC5OYU4sIEZsb2F0LnBhcnNlRmxvYXQoIitOYU4iKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBGbG9hdC5wYXJzZUZsb2F0KCJOTmFOIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBGbG9hdC5wYXJzZUZsb2F0KCJOYU5OIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEZsb2F0LlBPU0lUSVZFX0lORklOSVRZLCBGbG9hdC5wYXJzZUZsb2F0KCIrSW5maW5pdHkiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhGbG9hdC5QT1NJVElWRV9JTkZJTklUWSwgRmxvYXQucGFyc2VGbG9hdCgiSW5maW5pdHkiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhGbG9hdC5ORUdBVElWRV9JTkZJTklUWSwgRmxvYXQucGFyc2VGbG9hdCgiLUluZmluaXR5IikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgRmxvYXQucGFyc2VGbG9hdCgiSUluZmluaXR5Iik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBGbG9hdC5wYXJzZUZsb2F0KCJJbmZpbml0eXkiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3VmZml4UGFyc2luZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmdbXSBiYWRTdHJpbmdzID0geyAiMWZmIiwgIjFmZCIsICIxZGYiLCAiMWRkIiB9OworICAgICAgICBmb3IgKFN0cmluZyBzdHJpbmcgOiBiYWRTdHJpbmdzKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEZsb2F0LnBhcnNlRmxvYXQoc3RyaW5nKTsKKyAgICAgICAgICAgICAgICBmYWlsKHN0cmluZyk7CisgICAgICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoMS4wZiwgRmxvYXQucGFyc2VGbG9hdCgiMWYiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLjBmLCBGbG9hdC5wYXJzZUZsb2F0KCIxZCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMGYsIEZsb2F0LnBhcnNlRmxvYXQoIjFGIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMS4wZiwgRmxvYXQucGFyc2VGbG9hdCgiMUQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLjBmLCBGbG9hdC5wYXJzZUZsb2F0KCIxLkQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLjBmLCBGbG9hdC5wYXJzZUZsb2F0KCIxLkUwRCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMGYsIEZsb2F0LnBhcnNlRmxvYXQoIi4xRTFEIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFeHBvbmVudFBhcnNpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nW10gc3RyaW5ncyA9IHsKKyAgICAgICAgICAgIC8vIEV4cG9uZW50cyBtaXNzaW5nIGludGVnZXIgdmFsdWVzLgorICAgICAgICAgICAgIjEuMGUiLCAiMS4wZSsiLCAiMS4wZS0iLAorICAgICAgICAgICAgLy8gRXhwb25lbnRzIHdpdGggdG9vIG1hbnkgZXhwbGljaXQgc2lnbnMuCisgICAgICAgICAgICAiMS4wZSsrMSIsICIxLjBlKy0xIiwgIjEuMGUtKzEiLCAiMS4wZS0tMSIKKyAgICAgICAgfTsKKyAgICAgICAgZm9yIChTdHJpbmcgc3RyaW5nIDogc3RyaW5ncykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBGbG9hdC5wYXJzZUZsb2F0KHN0cmluZyk7CisgICAgICAgICAgICAgICAgZmFpbChzdHJpbmcpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoMS4wZS00NWYsIEZsb2F0LnBhcnNlRmxvYXQoIjEuMGUtNDUiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLjBmLCBGbG9hdC5wYXJzZUZsb2F0KCIxLjBlLTQ2IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEuMGUtNDVmLCBGbG9hdC5wYXJzZUZsb2F0KCItMS4wZS00NSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0wLjBmLCBGbG9hdC5wYXJzZUZsb2F0KCItMS4wZS00NiIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMS4wZSszOGYsIEZsb2F0LnBhcnNlRmxvYXQoIjEuMGUrMzgiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhGbG9hdC5QT1NJVElWRV9JTkZJTklUWSwgRmxvYXQucGFyc2VGbG9hdCgiMS4wZSszOSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLjBlKzM4ZiwgRmxvYXQucGFyc2VGbG9hdCgiLTEuMGUrMzgiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhGbG9hdC5ORUdBVElWRV9JTkZJTklUWSwgRmxvYXQucGFyc2VGbG9hdCgiLTEuMGUrMzkiKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEZsb2F0LlBPU0lUSVZFX0lORklOSVRZLCBGbG9hdC5wYXJzZUZsb2F0KCIxLjBlKzk5OTk5OTk5OTkiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhGbG9hdC5ORUdBVElWRV9JTkZJTklUWSwgRmxvYXQucGFyc2VGbG9hdCgiLTEuMGUrOTk5OTk5OTk5OSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAuMGYsIEZsb2F0LnBhcnNlRmxvYXQoIjEuMGUtOTk5OTk5OTk5OSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0wLjBmLCBGbG9hdC5wYXJzZUZsb2F0KCItMS4wZS05OTk5OTk5OTk5IikpOworCisgICAgICAgIGFzc2VydEVxdWFscyhGbG9hdC5QT1NJVElWRV9JTkZJTklUWSwgRmxvYXQucGFyc2VGbG9hdCgiMzIwLjBFKzIxNDc0ODM2NDciKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMC4wZiwgRmxvYXQucGFyc2VGbG9hdCgiLTEuNEUtMjE0NzQ4MzMxNCIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmVyaWZpZXJUeXBpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgIGZsb2F0IGYxID0gMDsKKyAgICAgIGlmICh0ZXN0VmVyaWZpZXJUeXBpbmdCb29sKSB7CisgICAgICAgIGYxID0gRmxvYXQuTUlOX1ZBTFVFOworICAgICAgfQorICAgICAgYXNzZXJ0RXF1YWxzKGYxLCAwZik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0ludGVnZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvSW50ZWdlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZDhjMDgyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0ludGVnZXJUZXN0LmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK3B1YmxpYyBjbGFzcyBJbnRlZ2VyVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdF9jb21wYXJlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludCBtaW4gPSBJbnRlZ2VyLk1JTl9WQUxVRTsKKyAgICAgICAgZmluYWwgaW50IHplcm8gPSAwOworICAgICAgICBmaW5hbCBpbnQgbWF4ID0gSW50ZWdlci5NQVhfVkFMVUU7CisgICAgICAgIGFzc2VydFRydWUoSW50ZWdlci5jb21wYXJlKG1heCwgIG1heCkgID09IDApOworICAgICAgICBhc3NlcnRUcnVlKEludGVnZXIuY29tcGFyZShtaW4sICBtaW4pICA9PSAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShJbnRlZ2VyLmNvbXBhcmUoemVybywgemVybykgPT0gMCk7CisgICAgICAgIGFzc2VydFRydWUoSW50ZWdlci5jb21wYXJlKG1heCwgIHplcm8pID4gMCk7CisgICAgICAgIGFzc2VydFRydWUoSW50ZWdlci5jb21wYXJlKG1heCwgIG1pbikgID4gMCk7CisgICAgICAgIGFzc2VydFRydWUoSW50ZWdlci5jb21wYXJlKHplcm8sIG1heCkgIDwgMCk7CisgICAgICAgIGFzc2VydFRydWUoSW50ZWdlci5jb21wYXJlKHplcm8sIG1pbikgID4gMCk7CisgICAgICAgIGFzc2VydFRydWUoSW50ZWdlci5jb21wYXJlKG1pbiwgIHplcm8pIDwgMCk7CisgICAgICAgIGFzc2VydFRydWUoSW50ZWdlci5jb21wYXJlKG1pbiwgIG1heCkgIDwgMCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0ludGVncmFsVG9TdHJpbmdUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvSW50ZWdyYWxUb1N0cmluZ1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMmIxYjBhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0ludGVncmFsVG9TdHJpbmdUZXN0LmphdmEKQEAgLTAsMCArMSw0MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBJbnRlZ3JhbFRvU3RyaW5nVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW50VG9IZXhTdHJpbmcoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiMCIsIEludGVncmFsVG9TdHJpbmcuaW50VG9IZXhTdHJpbmcoMCwgZmFsc2UsIDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIwIiwgSW50ZWdyYWxUb1N0cmluZy5pbnRUb0hleFN0cmluZygwLCBmYWxzZSwgMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjAwIiwgSW50ZWdyYWxUb1N0cmluZy5pbnRUb0hleFN0cmluZygwLCBmYWxzZSwgMikpOworCisgICAgICAgIGFzc2VydEVxdWFscygiMSIsIEludGVncmFsVG9TdHJpbmcuaW50VG9IZXhTdHJpbmcoMSwgZmFsc2UsIDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxIiwgSW50ZWdyYWxUb1N0cmluZy5pbnRUb0hleFN0cmluZygxLCBmYWxzZSwgMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjAxIiwgSW50ZWdyYWxUb1N0cmluZy5pbnRUb0hleFN0cmluZygxLCBmYWxzZSwgMikpOworCisgICAgICAgIGFzc2VydEVxdWFscygiZmZmZmZmZmYiLCBJbnRlZ3JhbFRvU3RyaW5nLmludFRvSGV4U3RyaW5nKC0xLCBmYWxzZSwgMCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCeXRlc1RvSGV4U3RyaW5nKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoImFiY2RlZiIsIEludGVncmFsVG9TdHJpbmcuYnl0ZXNUb0hleFN0cmluZygKKyAgICAgICAgICAgICAgICBuZXcgYnl0ZVtdIHsgKGJ5dGUpIDB4YWIsIChieXRlKSAweGNkLCAoYnl0ZSkgMHhlZiB9LCBmYWxzZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFCQ0RFRiIsIEludGVncmFsVG9TdHJpbmcuYnl0ZXNUb0hleFN0cmluZygKKyAgICAgICAgICAgICAgICBuZXcgYnl0ZVtdIHsgKGJ5dGUpIDB4YWIsIChieXRlKSAweGNkLCAoYnl0ZSkgMHhlZiB9LCB0cnVlKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0ludHJpbnNpY1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9JbnRyaW5zaWNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmNmMDUyMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9JbnRyaW5zaWNUZXN0LmphdmEKQEAgLTAsMCArMSwxMTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgSW50cmluc2ljVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RyaW5nX2NoYXJBdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAiaGVsbG8iLmNoYXJBdCgwKTsKKyAgICAgICAgU3RyaW5nLmNsYXNzLmdldE1ldGhvZCgiY2hhckF0IiwgaW50LmNsYXNzKS5pbnZva2UoImhlbGxvIiwgMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0cmluZ19jb21wYXJlVG8oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgImhlbGxvIi5jb21wYXJlVG8oIndvcmxkIik7CisgICAgICAgIFN0cmluZy5jbGFzcy5nZXRNZXRob2QoImNvbXBhcmVUbyIsIFN0cmluZy5jbGFzcykuaW52b2tlKCJoZWxsbyIsICJ3b3JsZCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdHJpbmdfZXF1YWxzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICJoZWxsbyIuZXF1YWxzKCJ3b3JsZCIpOworICAgICAgICBTdHJpbmcuY2xhc3MuZ2V0TWV0aG9kKCJlcXVhbHMiLCBPYmplY3QuY2xhc3MpLmludm9rZSgiaGVsbG8iLCAid29ybGQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RyaW5nX2Zhc3RJbmRleE9mX0lJKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICJoZWxsbyIuaW5kZXhPZignbCcpOworICAgICAgICBTdHJpbmcuY2xhc3MuZ2V0TWV0aG9kKCJpbmRleE9mIiwgaW50LmNsYXNzKS5pbnZva2UoImhlbGxvIiwgJ2wnKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RyaW5nX2lzRW1wdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgImhlbGxvIi5pc0VtcHR5KCk7CisgICAgICAgIFN0cmluZy5jbGFzcy5nZXRNZXRob2QoImlzRW1wdHkiKS5pbnZva2UoImhlbGxvIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0cmluZ19sZW5ndGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgImhlbGxvIi5sZW5ndGgoKTsKKyAgICAgICAgU3RyaW5nLmNsYXNzLmdldE1ldGhvZCgibGVuZ3RoIikuaW52b2tlKCJoZWxsbyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYXRoX2FicygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNYXRoLmFicygxKTsKKyAgICAgICAgTWF0aC5jbGFzcy5nZXRNZXRob2QoImFicyIsIGludC5jbGFzcykuaW52b2tlKG51bGwsIDEpOworICAgICAgICBNYXRoLmFicygxTCk7CisgICAgICAgIE1hdGguY2xhc3MuZ2V0TWV0aG9kKCJhYnMiLCBsb25nLmNsYXNzKS5pbnZva2UobnVsbCwgMUwpOworICAgICAgICBNYXRoLmFicygxLjBmKTsKKyAgICAgICAgTWF0aC5jbGFzcy5nZXRNZXRob2QoImFicyIsIGZsb2F0LmNsYXNzKS5pbnZva2UobnVsbCwgMS4wZik7CisgICAgICAgIE1hdGguYWJzKDEuMCk7CisgICAgICAgIE1hdGguY2xhc3MuZ2V0TWV0aG9kKCJhYnMiLCBkb3VibGUuY2xhc3MpLmludm9rZShudWxsLCAxLjApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYXRoX21pbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNYXRoLm1pbigxLCAyKTsKKyAgICAgICAgTWF0aC5jbGFzcy5nZXRNZXRob2QoIm1pbiIsIGludC5jbGFzcywgaW50LmNsYXNzKS5pbnZva2UobnVsbCwgMSwgMik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1hdGhfbWF4KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1hdGgubWF4KDEsIDIpOworICAgICAgICBNYXRoLmNsYXNzLmdldE1ldGhvZCgibWF4IiwgaW50LmNsYXNzLCBpbnQuY2xhc3MpLmludm9rZShudWxsLCAxLCAyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF0aF9zcXJ0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1hdGguc3FydCgyLjApOworICAgICAgICBNYXRoLmNsYXNzLmdldE1ldGhvZCgic3FydCIsIGRvdWJsZS5jbGFzcykuaW52b2tlKG51bGwsIDIuMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1hdGhfY29zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1hdGguY29zKE1hdGguUEkpOworICAgICAgICBNYXRoLmNsYXNzLmdldE1ldGhvZCgiY29zIiwgZG91YmxlLmNsYXNzKS5pbnZva2UobnVsbCwgTWF0aC5QSSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1hdGhfc2luKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1hdGguc2luKE1hdGguUEkpOworICAgICAgICBNYXRoLmNsYXNzLmdldE1ldGhvZCgic2luIiwgZG91YmxlLmNsYXNzKS5pbnZva2UobnVsbCwgTWF0aC5QSSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZsb2F0X2Zsb2F0VG9JbnRCaXRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZsb2F0LmZsb2F0VG9JbnRCaXRzKDAuMGYpOworICAgICAgICBGbG9hdC5jbGFzcy5nZXRNZXRob2QoImZsb2F0VG9JbnRCaXRzIiwgZmxvYXQuY2xhc3MpLmludm9rZShudWxsLCAwLjBmKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmxvYXRfZmxvYXRUb1Jhd0ludEJpdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMoMC4wZik7CisgICAgICAgIEZsb2F0LmNsYXNzLmdldE1ldGhvZCgiZmxvYXRUb1Jhd0ludEJpdHMiLCBmbG9hdC5jbGFzcykuaW52b2tlKG51bGwsIDAuMGYpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGbG9hdF9pbnRCaXRzVG9GbG9hdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGbG9hdC5pbnRCaXRzVG9GbG9hdCgwKTsKKyAgICAgICAgRmxvYXQuY2xhc3MuZ2V0TWV0aG9kKCJpbnRCaXRzVG9GbG9hdCIsIGludC5jbGFzcykuaW52b2tlKG51bGwsIDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REb3VibGVfZG91YmxlVG9Mb25nQml0cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEb3VibGUuZG91YmxlVG9Mb25nQml0cygwLjApOworICAgICAgICBEb3VibGUuY2xhc3MuZ2V0TWV0aG9kKCJkb3VibGVUb0xvbmdCaXRzIiwgZG91YmxlLmNsYXNzKS5pbnZva2UobnVsbCwgMC4wKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RG91YmxlX2RvdWJsZVRvUmF3TG9uZ0JpdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRG91YmxlLmRvdWJsZVRvUmF3TG9uZ0JpdHMoMC4wKTsKKyAgICAgICAgRG91YmxlLmNsYXNzLmdldE1ldGhvZCgiZG91YmxlVG9SYXdMb25nQml0cyIsIGRvdWJsZS5jbGFzcykuaW52b2tlKG51bGwsIDAuMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERvdWJsZV9sb25nQml0c1RvRG91YmxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIERvdWJsZS5sb25nQml0c1RvRG91YmxlKDBMKTsKKyAgICAgICAgRG91YmxlLmNsYXNzLmdldE1ldGhvZCgibG9uZ0JpdHNUb0RvdWJsZSIsIGxvbmcuY2xhc3MpLmludm9rZShudWxsLCAwTCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0xvbmdUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvTG9uZ1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wOGJkZDE1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL0xvbmdUZXN0LmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK3B1YmxpYyBjbGFzcyBMb25nVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdF9jb21wYXJlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGxvbmcgbWluID0gTG9uZy5NSU5fVkFMVUU7CisgICAgICAgIGZpbmFsIGxvbmcgemVybyA9IDBMOworICAgICAgICBmaW5hbCBsb25nIG1heCA9IExvbmcuTUFYX1ZBTFVFOworICAgICAgICBhc3NlcnRUcnVlKExvbmcuY29tcGFyZShtYXgsICBtYXgpICA9PSAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShMb25nLmNvbXBhcmUobWluLCAgbWluKSAgPT0gMCk7CisgICAgICAgIGFzc2VydFRydWUoTG9uZy5jb21wYXJlKHplcm8sIHplcm8pID09IDApOworICAgICAgICBhc3NlcnRUcnVlKExvbmcuY29tcGFyZShtYXgsICB6ZXJvKSA+IDApOworICAgICAgICBhc3NlcnRUcnVlKExvbmcuY29tcGFyZShtYXgsICBtaW4pICA+IDApOworICAgICAgICBhc3NlcnRUcnVlKExvbmcuY29tcGFyZSh6ZXJvLCBtYXgpICA8IDApOworICAgICAgICBhc3NlcnRUcnVlKExvbmcuY29tcGFyZSh6ZXJvLCBtaW4pICA+IDApOworICAgICAgICBhc3NlcnRUcnVlKExvbmcuY29tcGFyZShtaW4sICB6ZXJvKSA8IDApOworICAgICAgICBhc3NlcnRUcnVlKExvbmcuY29tcGFyZShtaW4sICBtYXgpICA8IDApOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRBbmRyb2lkQm9vbGVhblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRBbmRyb2lkQm9vbGVhblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZjM5ZGJiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZEFuZHJvaWRCb29sZWFuVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIHNvbWUgYmFzaWMgZnVuY3Rpb25hbGl0eSBvZiBCb29sZWFucy4KKyAqLworcHVibGljIGNsYXNzIE9sZEFuZHJvaWRCb29sZWFuVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RCb29sZWFuKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEJvb2xlYW4gYSA9IG5ldyBCb29sZWFuKHRydWUpOworICAgICAgICBCb29sZWFuIGIgPSBuZXcgQm9vbGVhbigiVHJ1ZSIpOworICAgICAgICBCb29sZWFuIGMgPSBuZXcgQm9vbGVhbihmYWxzZSk7CisgICAgICAgIEJvb2xlYW4gZCA9IG5ldyBCb29sZWFuKCJZZXMiKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoYSwgYik7CisgICAgICAgIGFzc2VydEVxdWFscyhjLCBkKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhLmJvb2xlYW5WYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoYy5ib29sZWFuVmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidHJ1ZSIsIGEudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZmFsc2UiLCBjLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQm9vbGVhbi5UUlVFLCBhKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJvb2xlYW4uRkFMU0UsIGMpOworICAgICAgICBhc3NlcnRTYW1lKEJvb2xlYW4udmFsdWVPZih0cnVlKSwgQm9vbGVhbi5UUlVFKTsKKyAgICAgICAgYXNzZXJ0U2FtZShCb29sZWFuLnZhbHVlT2YoZmFsc2UpLCBCb29sZWFuLkZBTFNFKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRBbmRyb2lkRW51bVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRBbmRyb2lkRW51bVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNzJhZGNiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZEFuZHJvaWRFbnVtVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGJhc2ljIGJlaGF2aW9yIG9mIGVudW1zLgorICovCitwdWJsaWMgY2xhc3MgT2xkQW5kcm9pZEVudW1UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIGVudW0gTXlFbnVtIHsKKyAgICAgICAgWkVSTywgT05FLCBUV08sIFRIUkVFLCBGT1VSIHtib29sZWFuIGlzRm91cigpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfX07CisKKyAgICAgICAgYm9vbGVhbiBpc0ZvdXIoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBlbnVtIE15RW51bVR3byB7CisgICAgICAgIEZJVkUsIFNJWAorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbnVtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoTXlFbnVtLlpFUk8uY29tcGFyZVRvKE15RW51bS5PTkUpIDwgMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhNeUVudW0uWkVSTywgTXlFbnVtLlpFUk8pOworICAgICAgICBhc3NlcnRUcnVlKE15RW51bS5UV08uY29tcGFyZVRvKE15RW51bS5PTkUpID4gMCk7CisgICAgICAgIGFzc2VydFRydWUoTXlFbnVtLkZPVVIuY29tcGFyZVRvKE15RW51bS5PTkUpID4gMCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJPTkUiLCBNeUVudW0uT05FLm5hbWUoKSk7CisgICAgICAgIGFzc2VydFNhbWUoTXlFbnVtLk9ORS5nZXREZWNsYXJpbmdDbGFzcygpLCBNeUVudW0uY2xhc3MpOworICAgICAgICBhc3NlcnRTYW1lKE15RW51bS5GT1VSLmdldERlY2xhcmluZ0NsYXNzKCksIE15RW51bS5jbGFzcyk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShNeUVudW0uRk9VUi5pc0ZvdXIoKSk7CisKKyAgICAgICAgTXlFbnVtIGU7CisKKyAgICAgICAgZSA9IE15RW51bS5aRVJPOworCisgICAgICAgIHN3aXRjaCAoZSkgeworICAgICAgICAgICAgY2FzZSBaRVJPOgorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICBmYWlsKCJ3cm9uZyBzd2l0Y2giKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRBbmRyb2lkRmxvYXREb3VibGVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkQW5kcm9pZEZsb2F0RG91YmxlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNlZDdkZjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkQW5kcm9pZEZsb2F0RG91YmxlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTQ4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgYmFzaWMgZnVuY3Rpb25hbGl0eSBvZiBmbG9hdHMgYW5kIGRvdWJsZXMuCisgKi8KK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkRmxvYXREb3VibGVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdEZsb2F0RG91YmxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIERvdWJsZSBkID0gRG91YmxlLnZhbHVlT2YoMS4wKTsKKyAgICAgICAgRmxvYXQgZiA9IEZsb2F0LnZhbHVlT2YoMS4wZik7CisgICAgICAgIE9iamVjdCBvID0gbmV3IE9iamVjdCgpOworCisgICAgICAgIGFzc2VydEZhbHNlKGYuZXF1YWxzKGQpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZC5lcXVhbHMoZikpOworICAgICAgICBhc3NlcnRGYWxzZShmLmVxdWFscyhvKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGQuZXF1YWxzKG8pKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZi5lcXVhbHMobnVsbCkpOworICAgICAgICBhc3NlcnRGYWxzZShkLmVxdWFscyhudWxsKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZsb2F0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZsb2F0IHB6ID0gMC4wZjsKKyAgICAgICAgZmxvYXQgbnogPSAtMC4wZjsKKworICAgICAgICBmbG9hdCBwemVybyA9IDEuMGYgLyBGbG9hdC5QT1NJVElWRV9JTkZJTklUWTsKKyAgICAgICAgZmxvYXQgbnplcm8gPSAxLjBmIC8gRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFk7CisKKyAgICAgICAgLy8gRXZlcnl0aGluZyBjb21wYXJlcyBhcyAnPT0nCisgICAgICAgIGFzc2VydFRydWUocHogPT0gcHopOworICAgICAgICBhc3NlcnRUcnVlKHB6ID09IG56KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShweiA9PSBwemVybyk7CisgICAgICAgIGFzc2VydFRydWUocHogPT0gbnplcm8pOworCisgICAgICAgIGFzc2VydFRydWUobnogPT0gcHopOworICAgICAgICBhc3NlcnRUcnVlKG56ID09IG56KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShueiA9PSBwemVybyk7CisgICAgICAgIGFzc2VydFRydWUobnogPT0gbnplcm8pOworCisgICAgICAgIGFzc2VydFRydWUocHplcm8gPT0gcHopOworICAgICAgICBhc3NlcnRUcnVlKHB6ZXJvID09IG56KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwemVybyA9PSBwemVybyk7CisgICAgICAgIGFzc2VydFRydWUocHplcm8gPT0gbnplcm8pOworCisgICAgICAgIGFzc2VydFRydWUobnplcm8gPT0gcHopOworICAgICAgICBhc3NlcnRUcnVlKG56ZXJvID09IG56KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuemVybyA9PSBwemVybyk7CisgICAgICAgIGFzc2VydFRydWUobnplcm8gPT0gbnplcm8pOworCisgICAgICAgIC8vICstMCBhcmUgZGlzdGluY3QgYXMgRmxvYXRzCisgICAgICAgIGFzc2VydEVxdWFscyhGbG9hdC52YWx1ZU9mKHB6KSwgRmxvYXQudmFsdWVPZihweikpOworICAgICAgICBhc3NlcnRUcnVlKCFGbG9hdC52YWx1ZU9mKHB6KS5lcXVhbHMoRmxvYXQudmFsdWVPZihueikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEZsb2F0LnZhbHVlT2YocHopLCBGbG9hdC52YWx1ZU9mKHB6ZXJvKSk7CisgICAgICAgIGFzc2VydFRydWUoIUZsb2F0LnZhbHVlT2YocHopLmVxdWFscyhGbG9hdC52YWx1ZU9mKG56ZXJvKSkpOworCisgICAgICAgIGFzc2VydFRydWUoIUZsb2F0LnZhbHVlT2YobnopLmVxdWFscyhGbG9hdC52YWx1ZU9mKHB6KSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRmxvYXQudmFsdWVPZihueiksIEZsb2F0LnZhbHVlT2YobnopKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSghRmxvYXQudmFsdWVPZihueikuZXF1YWxzKEZsb2F0LnZhbHVlT2YocHplcm8pKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhGbG9hdC52YWx1ZU9mKG56KSwgRmxvYXQudmFsdWVPZihuemVybykpOworCisgICAgICAgIGFzc2VydEVxdWFscyhGbG9hdC52YWx1ZU9mKHB6ZXJvKSwgRmxvYXQudmFsdWVPZihweikpOworICAgICAgICBhc3NlcnRUcnVlKCFGbG9hdC52YWx1ZU9mKHB6ZXJvKS5lcXVhbHMoRmxvYXQudmFsdWVPZihueikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEZsb2F0LnZhbHVlT2YocHplcm8pLCBGbG9hdC52YWx1ZU9mKHB6ZXJvKSk7CisgICAgICAgIGFzc2VydFRydWUoIUZsb2F0LnZhbHVlT2YocHplcm8pLmVxdWFscyhGbG9hdC52YWx1ZU9mKG56ZXJvKSkpOworCisgICAgICAgIGFzc2VydFRydWUoIUZsb2F0LnZhbHVlT2Yobnplcm8pLmVxdWFscyhGbG9hdC52YWx1ZU9mKHB6KSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRmxvYXQudmFsdWVPZihuemVybyksIEZsb2F0LnZhbHVlT2YobnopKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSghRmxvYXQudmFsdWVPZihuemVybykuZXF1YWxzKEZsb2F0LnZhbHVlT2YocHplcm8pKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhGbG9hdC52YWx1ZU9mKG56ZXJvKSwgRmxvYXQudmFsdWVPZihuemVybykpOworCisgICAgICAgIC8vIE5hbidzIGNvbXBhcmUgYXMgZXF1YWwKKyAgICAgICAgRmxvYXQgc3FydG0yID0gRmxvYXQudmFsdWVPZigoZmxvYXQpIE1hdGguc3FydCgtMi4wZikpOworICAgICAgICBGbG9hdCBzcXJ0bTMgPSBGbG9hdC52YWx1ZU9mKChmbG9hdCkgTWF0aC5zcXJ0KC0zLjBmKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzcXJ0bTIsIHNxcnRtMyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERvdWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkb3VibGUgcHogPSAwLjA7CisgICAgICAgIGRvdWJsZSBueiA9IC0wLjA7CisKKyAgICAgICAgZG91YmxlIHB6ZXJvID0gMS4wIC8gRG91YmxlLlBPU0lUSVZFX0lORklOSVRZOworICAgICAgICBkb3VibGUgbnplcm8gPSAxLjAgLyBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFk7CisKKyAgICAgICAgLy8gRXZlcnl0aGluZyBjb21wYXJlcyBhcyAnPT0nCisgICAgICAgIGFzc2VydFRydWUocHogPT0gcHopOworICAgICAgICBhc3NlcnRUcnVlKHB6ID09IG56KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShweiA9PSBwemVybyk7CisgICAgICAgIGFzc2VydFRydWUocHogPT0gbnplcm8pOworCisgICAgICAgIGFzc2VydFRydWUobnogPT0gcHopOworICAgICAgICBhc3NlcnRUcnVlKG56ID09IG56KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShueiA9PSBwemVybyk7CisgICAgICAgIGFzc2VydFRydWUobnogPT0gbnplcm8pOworCisgICAgICAgIGFzc2VydFRydWUocHplcm8gPT0gcHopOworICAgICAgICBhc3NlcnRUcnVlKHB6ZXJvID09IG56KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwemVybyA9PSBwemVybyk7CisgICAgICAgIGFzc2VydFRydWUocHplcm8gPT0gbnplcm8pOworCisgICAgICAgIGFzc2VydFRydWUobnplcm8gPT0gcHopOworICAgICAgICBhc3NlcnRUcnVlKG56ZXJvID09IG56KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuemVybyA9PSBwemVybyk7CisgICAgICAgIGFzc2VydFRydWUobnplcm8gPT0gbnplcm8pOworCisgICAgICAgIC8vICstMCBhcmUgZGlzdGluY3QgYXMgRG91YmxlcworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLnZhbHVlT2YocHopLCBEb3VibGUudmFsdWVPZihweikpOworICAgICAgICBhc3NlcnRUcnVlKCFEb3VibGUudmFsdWVPZihweikuZXF1YWxzKERvdWJsZS52YWx1ZU9mKG56KSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLnZhbHVlT2YocHopLCBEb3VibGUudmFsdWVPZihwemVybykpOworICAgICAgICBhc3NlcnRUcnVlKCFEb3VibGUudmFsdWVPZihweikuZXF1YWxzKERvdWJsZS52YWx1ZU9mKG56ZXJvKSkpOworCisgICAgICAgIGFzc2VydFRydWUoIURvdWJsZS52YWx1ZU9mKG56KS5lcXVhbHMoRG91YmxlLnZhbHVlT2YocHopKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUudmFsdWVPZihueiksIERvdWJsZS52YWx1ZU9mKG56KSk7CisgICAgICAgIGFzc2VydFRydWUoIURvdWJsZS52YWx1ZU9mKG56KS5lcXVhbHMoRG91YmxlLnZhbHVlT2YocHplcm8pKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUudmFsdWVPZihueiksIERvdWJsZS52YWx1ZU9mKG56ZXJvKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS52YWx1ZU9mKHB6ZXJvKSwgRG91YmxlLnZhbHVlT2YocHopKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSghRG91YmxlLnZhbHVlT2YocHplcm8pLmVxdWFscyhEb3VibGUudmFsdWVPZihueikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS52YWx1ZU9mKHB6ZXJvKSwgRG91YmxlLnZhbHVlT2YocHplcm8pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSghRG91YmxlLnZhbHVlT2YocHplcm8pLmVxdWFscyhEb3VibGUudmFsdWVPZihuemVybykpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCFEb3VibGUudmFsdWVPZihuemVybykuZXF1YWxzKERvdWJsZS52YWx1ZU9mKHB6KSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLnZhbHVlT2Yobnplcm8pLCBEb3VibGUudmFsdWVPZihueikpOworICAgICAgICBhc3NlcnRUcnVlKCFEb3VibGUudmFsdWVPZihuemVybykuZXF1YWxzKERvdWJsZS52YWx1ZU9mKHB6ZXJvKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLnZhbHVlT2Yobnplcm8pLCBEb3VibGUudmFsdWVPZihuemVybykpOworCisgICAgICAgIC8vIE5hbidzIGNvbXBhcmUgYXMgZXF1YWwKKyAgICAgICAgRG91YmxlIHNxcnRtMiA9IERvdWJsZS52YWx1ZU9mKE1hdGguc3FydCgtMi4wKSk7CisgICAgICAgIERvdWJsZSBzcXJ0bTMgPSBEb3VibGUudmFsdWVPZihNYXRoLnNxcnQoLTMuMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoc3FydG0yLCBzcXJ0bTMpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRBbmRyb2lkSW5zdGFuY2VvZlRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRBbmRyb2lkSW5zdGFuY2VvZlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZTk3YzIzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZEFuZHJvaWRJbnN0YW5jZW9mVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTMxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA2IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZEFuZHJvaWRJbnN0YW5jZW9mVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByb3RlY3RlZCBBIG1BOworICAgIHByb3RlY3RlZCBDaGlsZE9mQU9uZSBtT25lOworICAgIHByb3RlY3RlZCBDaGlsZE9mQU9uZSBtVHdvOworICAgIHByb3RlY3RlZCBDaGlsZE9mQU9uZSBtVGhyZWU7CisgICAgcHJvdGVjdGVkIENoaWxkT2ZBT25lIG1Gb3VyOworICAgIHByb3RlY3RlZCBDaGlsZE9mQUZpdmUgbUZpdmU7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworCisgICAgICAgIG1BID0gbmV3IEEoKTsKKyAgICAgICAgbU9uZSA9IG5ldyBDaGlsZE9mQU9uZSgpOworICAgICAgICBtVHdvID0gbmV3IENoaWxkT2ZBVHdvKCk7CisgICAgICAgIG1UaHJlZSA9IG5ldyBDaGlsZE9mQVRocmVlKCk7CisgICAgICAgIG1Gb3VyID0gbmV3IENoaWxkT2ZBRm91cigpOworICAgICAgICBtRml2ZSA9IG5ldyBDaGlsZE9mQUZpdmUoKTsKKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3ROb0ludGVyZmFjZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBBIGEgPSBtQTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDAwMDA7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIm1fYSBzaG91bGQgbm90IGJlIGEgQ2hpbGRPZkFGaXZlIiwgYSBpbnN0YW5jZW9mIENoaWxkT2ZBRml2ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVyaXZlZE9uZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBJbnRlcmZhY2VPbmUgb25lID0gbU9uZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDAwMDA7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIm1fb25lIHNob3VsZCBub3QgYmUgYSBDaGlsZE9mQUZpdmUiLCBvbmUgaW5zdGFuY2VvZiBDaGlsZE9mQUZpdmUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERlcml2ZWRUd28oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSW50ZXJmYWNlVHdvIHR3byA9IG1Ud287CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwMDAwOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJtX3R3byBzaG91bGQgbm90IGJlIGEgQ2hpbGRPZkFGaXZlIiwgdHdvIGluc3RhbmNlb2YgQ2hpbGRPZkFGaXZlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REZXJpdmVkVGhyZWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSW50ZXJmYWNlVGhyZWUgdGhyZWUgPSBtVGhyZWU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwMDAwOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJtX3RocmVlIHNob3VsZCBub3QgYmUgYSBDaGlsZE9mQUZpdmUiLCB0aHJlZSBpbnN0YW5jZW9mIENoaWxkT2ZBRml2ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVyaXZlZEZvdXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSW50ZXJmYWNlRm91ciBmb3VyID0gbUZvdXI7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwMDAwOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJtX2ZvdXIgc2hvdWxkIG5vdCBiZSBhIENoaWxkT2ZBRml2ZSIsIGZvdXIgaW5zdGFuY2VvZiBDaGlsZE9mQUZpdmUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN1Y2Nlc3NDbGFzcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaGlsZE9mQU9uZSBmaXZlID0gbUZpdmU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwMDAwOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIm1fZml2ZSBpcyBzdXBwb3NlIHRvIGJlIGEgQ2hpbGRPZkFGaXZlIiwgZml2ZSBpbnN0YW5jZW9mIENoaWxkT2ZBRml2ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3VjY2Vzc0ludGVyZmFjZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaGlsZE9mQUZpdmUgZml2ZSA9IG1GaXZlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDAwMDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJtX2ZpdmUgaXMgc3VwcG9zZSB0byBiZSBhIEludGVyZmFjZUZvdXIiLCBmaXZlIGluc3RhbmNlb2YgSW50ZXJmYWNlRm91cik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmFpbEludGVyZmFjZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBJbnRlcmZhY2VPbmUgb25lID0gbUZpdmU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwMDAwOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJtX2ZpdmUgZG9lcyBub3QgaW1wbGVtZW50IEludGVyZmFjZUZpdmUiLCBvbmUgaW5zdGFuY2VvZiBJbnRlcmZhY2VGaXZlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgaW50ZXJmYWNlIEludGVyZmFjZU9uZSB7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnRlcmZhY2UgSW50ZXJmYWNlVHdvIHsKKyAgICB9CisKKyAgICBwcml2YXRlIGludGVyZmFjZSBJbnRlcmZhY2VUaHJlZSB7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnRlcmZhY2UgSW50ZXJmYWNlRm91ciB7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnRlcmZhY2UgSW50ZXJmYWNlRml2ZSB7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQSB7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQ2hpbGRPZkFPbmUgZXh0ZW5kcyBBIGltcGxlbWVudHMgSW50ZXJmYWNlT25lLCBJbnRlcmZhY2VUd28sIEludGVyZmFjZVRocmVlLCBJbnRlcmZhY2VGb3VyIHsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBDaGlsZE9mQVR3byBleHRlbmRzIENoaWxkT2ZBT25lIHsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBDaGlsZE9mQVRocmVlIGV4dGVuZHMgQ2hpbGRPZkFUd28geworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIENoaWxkT2ZBRm91ciBleHRlbmRzIENoaWxkT2ZBVGhyZWUgeworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIENoaWxkT2ZBRml2ZSBleHRlbmRzIENoaWxkT2ZBRm91ciB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZEFuZHJvaWRNYXRoVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZEFuZHJvaWRNYXRoVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxOGYyYmQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkQW5kcm9pZE1hdGhUZXN0LmphdmEKQEAgLTAsMCArMSw2NTMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZEFuZHJvaWRNYXRoVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGRvdWJsZSBIWVAgPSBNYXRoLnNxcnQoMi4wKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGRvdWJsZSBPUFAgPSAxLjA7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBkb3VibGUgQURKID0gMS4wOworCisgICAgLyogUmVxdWlyZWQgdG8gbWFrZSBwcmV2aW91cyBwcmVwcm9jZXNzb3IgZmxhZ3Mgd29yayAtIGRvIG5vdCByZW1vdmUgKi8KKyAgICBpbnQgdW51c2VkID0gMDsKKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIG1lc3NhZ2UsIGRvdWJsZSBleHBlY3RlZCwgZG91YmxlIGFjdHVhbCwgZG91YmxlIGRlbHRhKSB7CisgICAgICAgIGlmIChkZWx0YSA9PSAwRCkgeworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhtZXNzYWdlLCBleHBlY3RlZCwgYWN0dWFsLCBNYXRoLnVscChleHBlY3RlZCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhtZXNzYWdlLCBleHBlY3RlZCwgYWN0dWFsLCBkZWx0YSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYXNzZXJ0RXF1YWxzKFN0cmluZyBtZXNzYWdlLCBmbG9hdCBleHBlY3RlZCwgZmxvYXQgYWN0dWFsLCBmbG9hdCBkZWx0YSkgeworICAgICAgICBpZiAoZGVsdGEgPT0gMEYpIHsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMobWVzc2FnZSwgZXhwZWN0ZWQsIGFjdHVhbCwgTWF0aC51bHAoZXhwZWN0ZWQpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMobWVzc2FnZSwgZXhwZWN0ZWQsIGFjdHVhbCwgZGVsdGEpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFic0QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBkb3VibGUgamF2YS5sYW5nLk1hdGguYWJzKGRvdWJsZSkKKworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZG91YmxlIGFicyB2YWx1ZSIsCisgICAgICAgICAgICAgICAgKE1hdGguYWJzKC0xOTA4Ljg5NzYpID09IDE5MDguODk3NikpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZG91YmxlIGFicyB2YWx1ZSIsCisgICAgICAgICAgICAgICAgKE1hdGguYWJzKDE5MDguODk3NikgPT0gMTkwOC44OTc2KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFic0YoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBmbG9hdCBqYXZhLmxhbmcuTWF0aC5hYnMoZmxvYXQpCisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBmbG9hdCBhYnMgdmFsdWUiLAorICAgICAgICAgICAgICAgIChNYXRoLmFicygtMTkwOC44OTc2ZikgPT0gMTkwOC44OTc2ZikpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZmxvYXQgYWJzIHZhbHVlIiwKKyAgICAgICAgICAgICAgICAoTWF0aC5hYnMoMTkwOC44OTc2ZikgPT0gMTkwOC44OTc2ZikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBYnNJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEubGFuZy5NYXRoLmFicyhpbnQpCisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBpbnQgYWJzIHZhbHVlIiwgKE1hdGguYWJzKC0xOTA4ODk3KSA9PSAxOTA4ODk3KSk7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBpbnQgYWJzIHZhbHVlIiwgKE1hdGguYWJzKDE5MDg4OTcpID09IDE5MDg4OTcpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWJzSigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGxvbmcgamF2YS5sYW5nLk1hdGguYWJzKGxvbmcpCisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBsb25nIGFicyB2YWx1ZSIsCisgICAgICAgICAgICAgICAgKE1hdGguYWJzKC0xOTA4ODk3NjAwMDA4OUwpID09IDE5MDg4OTc2MDAwMDg5TCkpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgbG9uZyBhYnMgdmFsdWUiLAorICAgICAgICAgICAgICAgIChNYXRoLmFicygxOTA4ODk3NjAwMDA4OUwpID09IDE5MDg4OTc2MDAwMDg5TCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBY29zRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLmxhbmcuTWF0aC5hY29zKGRvdWJsZSkKKyAgICAgICAgZG91YmxlIHIgPSBNYXRoLmNvcyhNYXRoLmFjb3MoQURKIC8gSFlQKSk7CisgICAgICAgIGxvbmcgbHIgPSBEb3VibGUuZG91YmxlVG9Mb25nQml0cyhyKTsKKyAgICAgICAgbG9uZyB0ID0gRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoQURKIC8gSFlQKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGFyYyBjb3NpbmUiLCBsciA9PSB0IHx8IChsciArIDEpID09IHQKKyAgICAgICAgICAgICAgICB8fCAobHIgLSAxKSA9PSB0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXNpbkQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBkb3VibGUgamF2YS5sYW5nLk1hdGguYXNpbihkb3VibGUpCisgICAgICAgIGRvdWJsZSByID0gTWF0aC5zaW4oTWF0aC5hc2luKE9QUCAvIEhZUCkpOworICAgICAgICBsb25nIGxyID0gRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMocik7CisgICAgICAgIGxvbmcgdCA9IERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKE9QUCAvIEhZUCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBhcmMgc2luZSIsIGxyID09IHQgfHwgKGxyICsgMSkgPT0gdAorICAgICAgICAgICAgICAgIHx8IChsciAtIDEpID09IHQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdGFuRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLmxhbmcuTWF0aC5hdGFuKGRvdWJsZSkKKyAgICAgICAgZG91YmxlIGFuc3dlciA9IE1hdGgudGFuKE1hdGguYXRhbigxLjApKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGFyYyB0YW5nZW50OiAiICsgYW5zd2VyLCBhbnN3ZXIgPD0gMS4wCisgICAgICAgICAgICAgICAgJiYgYW5zd2VyID49IDkuOTk5OTk5OTk5OTk5OTk4M0UtMSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEF0YW4yREQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBkb3VibGUgamF2YS5sYW5nLk1hdGguYXRhbjIoZG91YmxlLCBkb3VibGUpCisgICAgICAgIGRvdWJsZSBhbnN3ZXIgPSBNYXRoLmF0YW4oTWF0aC50YW4oMS4wKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBhcmMgdGFuZ2VudDogIiArIGFuc3dlciwgYW5zd2VyIDw9IDEuMAorICAgICAgICAgICAgICAgICYmIGFuc3dlciA+PSA5Ljk5OTk5OTk5OTk5OTk5ODNFLTEpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDYnJ0RCgpIHsKKyAgICAgICAgLy9UZXN0IGZvciBzcGVjaWFsIHNpdHVhdGlvbnMKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiBEb3VibGUuTmFOIiwgRG91YmxlLmlzTmFOKE1hdGgKKyAgICAgICAgICAgICAgICAuY2JydChEb3VibGUuTmFOKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gRG91YmxlLlBPU0lUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIE1hdGgKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jYnJ0KERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSIsCisgICAgICAgICAgICAgICAgRG91YmxlLk5FR0FUSVZFX0lORklOSVRZLCBNYXRoCisgICAgICAgICAgICAgICAgICAgICAgICAuY2JydChEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuZG91YmxlVG9Mb25nQml0cygwLjApLCBEb3VibGUuZG91YmxlVG9Mb25nQml0cyhNYXRoCisgICAgICAgICAgICAgICAgLmNicnQoMC4wKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoKzAuMCksIERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKE1hdGgKKyAgICAgICAgICAgICAgICAuY2JydCgrMC4wKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoLTAuMCksIERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKE1hdGgKKyAgICAgICAgICAgICAgICAuY2JydCgtMC4wKSkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiAzLjAiLCAzLjAsIE1hdGguY2JydCgyNy4wKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gMjMuMTExOTkzMTcyNTU4Njg0IiwgMjMuMTExOTkzMTcyNTU4Njg0LAorICAgICAgICAgICAgICAgIE1hdGguY2JydCgxMjM0NS42KSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gNS42NDM4MDMwOTQxMjIzNjJFMTAyIiwKKyAgICAgICAgICAgICAgICA1LjY0MzgwMzA5NDEyMjM2MkUxMDIsIE1hdGguY2JydChEb3VibGUuTUFYX1ZBTFVFKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gMC4wMSIsIDAuMDEsIE1hdGguY2JydCgwLjAwMDAwMSksIDBEKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gLTMuMCIsIC0zLjAsIE1hdGguY2JydCgtMjcuMCksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIC0yMy4xMTE5OTMxNzI1NTg2ODQiLCAtMjMuMTExOTkzMTcyNTU4Njg0LAorICAgICAgICAgICAgICAgIE1hdGguY2JydCgtMTIzNDUuNiksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDEuNzAzMTgzOTM2MDAzMjYwM0UtMTA4IiwKKyAgICAgICAgICAgICAgICAxLjcwMzE4MzkzNjAwMzI2MDNFLTEwOCwgTWF0aC5jYnJ0KERvdWJsZS5NSU5fVkFMVUUpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiAtMC4wMSIsIC0wLjAxLCBNYXRoLmNicnQoLTAuMDAwMDAxKSwgMEQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDZWlsRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLmxhbmcuTWF0aC5jZWlsKGRvdWJsZSkKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBjZWlsaW5nIGZvciBkb3VibGUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA3OSwgTWF0aC5jZWlsKDc4Ljg5KSwgMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGNlaWxpbmcgZm9yIGRvdWJsZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC03OCwgTWF0aC5jZWlsKC03OC44OSksIDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb3NEKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgZG91YmxlIGphdmEubGFuZy5NYXRoLmNvcyhkb3VibGUpCisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFuc3dlciIsIDEuMCwgTWF0aC5jb3MoMCksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYW5zd2VyIiwgMC41NDAzMDIzMDU4NjgxMzk4LCBNYXRoLmNvcygxKSwgMEQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb3NoRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3Igc3BlY2lhbCBzaXR1YXRpb25zCisgICAgICAgIGFzc2VydFRydWUoRG91YmxlLmlzTmFOKE1hdGguY29zaChEb3VibGUuTmFOKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgTWF0aC5jb3NoKERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIFBPU0lUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIE1hdGguY29zaChEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiAxLjAiLCAxLjAsIE1hdGguY29zaCgrMC4wKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gMS4wIiwgMS4wLCBNYXRoLmNvc2goLTAuMCksIDBEKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgTWF0aC5jb3NoKDEyMzQuNTYpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiBQT1NJVElWRV9JTkZJTklUWSIsCisgICAgICAgICAgICAgICAgRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCBNYXRoLmNvc2goLTEyMzQuNTYpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiAxLjAwMDAwMDAwMDAwMDUiLCAxLjAwMDAwMDAwMDAwMDUsIE1hdGgKKyAgICAgICAgICAgICAgICAuY29zaCgwLjAwMDAwMSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDEuMDAwMDAwMDAwMDAwNSIsIDEuMDAwMDAwMDAwMDAwNSwgTWF0aAorICAgICAgICAgICAgICAgIC5jb3NoKC0wLjAwMDAwMSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDUuMjEyMjE0MzUxOTQ1NTk4IiwgNS4yMTIyMTQzNTE5NDU1OTgsIE1hdGgKKyAgICAgICAgICAgICAgICAuY29zaCgyLjMzNDgyKSwgMEQpOworCisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiBQT1NJVElWRV9JTkZJTklUWSIsCisgICAgICAgICAgICAgICAgRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCBNYXRoLmNvc2goRG91YmxlLk1BWF9WQUxVRSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDEuMCIsIDEuMCwgTWF0aC5jb3NoKERvdWJsZS5NSU5fVkFMVUUpLCAwRCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEV4cEQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBkb3VibGUgamF2YS5sYW5nLk1hdGguZXhwKGRvdWJsZSkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGFuc3dlciByZXR1cm5lZCBmb3Igc2ltcGxlIHBvd2VyIiwgTWF0aC5hYnMoTWF0aAorICAgICAgICAgICAgICAgIC5leHAoNEQpCisgICAgICAgICAgICAgICAgLSBNYXRoLkUgKiBNYXRoLkUgKiBNYXRoLkUgKiBNYXRoLkUpIDwgMC4xRCk7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBhbnN3ZXIgcmV0dXJuZWQgZm9yIGxhcmdlciBwb3dlciIsIE1hdGgubG9nKE1hdGgKKyAgICAgICAgICAgICAgICAuYWJzKE1hdGguZXhwKDUuNUQpKSAtIDUuNUQpIDwgMTAuMEQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFeHBtMUQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIHNwZWNpYWwgY2FzZXMKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiBOYU4iLCBEb3VibGUuaXNOYU4oTWF0aC5leHBtMShEb3VibGUuTmFOKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgTWF0aC5leHBtMShEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFkpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiAtMS4wIiwgLTEuMCwgTWF0aAorICAgICAgICAgICAgICAgIC5leHBtMShEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuZG91YmxlVG9Mb25nQml0cygwLjApLCBEb3VibGUuZG91YmxlVG9Mb25nQml0cyhNYXRoCisgICAgICAgICAgICAgICAgLmV4cG0xKDAuMCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKCswLjApLCBEb3VibGUKKyAgICAgICAgICAgICAgICAuZG91YmxlVG9Mb25nQml0cyhNYXRoLmV4cG0xKCswLjApKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuZG91YmxlVG9Mb25nQml0cygtMC4wKSwgRG91YmxlCisgICAgICAgICAgICAgICAgLmRvdWJsZVRvTG9uZ0JpdHMoTWF0aC5leHBtMSgtMC4wKSkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiAtOS45OTk5NTAwMDAxNjY2NjZFLTYiLAorICAgICAgICAgICAgICAgIC05Ljk5OTk1MDAwMDE2NjY2NkUtNiwgTWF0aC5leHBtMSgtMC4wMDAwMSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDEuMDE0NTEwMzA3NDQ2OTYzNUU2MCIsCisgICAgICAgICAgICAgICAgMS4wMTQ1MTAzMDc0NDY5NjM1RTYwLCBNYXRoLmV4cG0xKDEzOC4xNjk1MTE2MiksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIFBPU0lUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIE1hdGgKKyAgICAgICAgICAgICAgICAgICAgICAgIC5leHBtMSgxMjM0NTY3ODkxMjM0NTY3ODkxMjM0NTY3ODkuNDUyMTU4NDIyMyksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIFBPU0lUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIE1hdGguZXhwbTEoRG91YmxlLk1BWF9WQUxVRSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIE1JTl9WQUxVRSIsIERvdWJsZS5NSU5fVkFMVUUsIE1hdGgKKyAgICAgICAgICAgICAgICAuZXhwbTEoRG91YmxlLk1JTl9WQUxVRSksIDBEKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rmxvb3JEKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgZG91YmxlIGphdmEubGFuZy5NYXRoLmZsb29yKGRvdWJsZSkKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBmbG9vciBmb3IgZG91YmxlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNzgsIE1hdGguZmxvb3IoNzguODkpLCAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgZmxvb3IgZm9yIGRvdWJsZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC03OSwgTWF0aC5mbG9vcigtNzguODkpLCAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SHlwb3RERCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3Igc3BlY2lhbCBjYXNlcworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgTWF0aC5oeXBvdChEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksCisgICAgICAgICAgICAgICAgICAgICAgICAxLjApLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiBQT1NJVElWRV9JTkZJTklUWSIsCisgICAgICAgICAgICAgICAgRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCBNYXRoLmh5cG90KERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSwKKyAgICAgICAgICAgICAgICAgICAgICAgIDEyMy4zMjQpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiBQT1NJVElWRV9JTkZJTklUWSIsCisgICAgICAgICAgICAgICAgRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCBNYXRoLmh5cG90KC03NTguMjU4NywKKyAgICAgICAgICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIFBPU0lUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIE1hdGguaHlwb3QoNTY4Ny4yMSwKKyAgICAgICAgICAgICAgICAgICAgICAgIERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIFBPU0lUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIE1hdGguaHlwb3QoRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLAorICAgICAgICAgICAgICAgICAgICAgICAgRG91YmxlLk5FR0FUSVZFX0lORklOSVRZKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgTWF0aC5oeXBvdChEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFksCisgICAgICAgICAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFkpLCAwRCk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBiZSBOYU4iLCBEb3VibGUuaXNOYU4oTWF0aC5oeXBvdChEb3VibGUuTmFOLAorICAgICAgICAgICAgICAgIDIzNDIzMDEuODk4NDMpKSk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBiZSBOYU4iLCBEb3VibGUuaXNOYU4oTWF0aC5oeXBvdCgtMzQ1LjI2ODAsCisgICAgICAgICAgICAgICAgRG91YmxlLk5hTikpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gMjM5NjQyNC45MDU0MTY2OTciLCAyMzk2NDI0LjkwNTQxNjY5NywgTWF0aAorICAgICAgICAgICAgICAgIC5oeXBvdCgxMjMyMi4xMiwgLTIzOTYzOTMuMjI1OCksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDEzOC4xNjk1ODA3MDU1ODU1NiIsIDEzOC4xNjk1ODA3MDU1ODU1NiwKKyAgICAgICAgICAgICAgICBNYXRoLmh5cG90KC0xMzguMTY5NTExNjIsIDAuMTM4MTcwMzU4NjQpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiAxLjc5NzY5MzEzNDg2MjMxNTdFMzA4IiwKKyAgICAgICAgICAgICAgICAxLjc5NzY5MzEzNDg2MjMxNTdFMzA4LCBNYXRoLmh5cG90KERvdWJsZS5NQVhfVkFMVUUsIDIxMTM3MC4zNSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDU0MTMuNzE4NSIsIDU0MTMuNzE4NSwgTWF0aC5oeXBvdCgKKyAgICAgICAgICAgICAgICAtNTQxMy43MTg1LCBEb3VibGUuTUlOX1ZBTFVFKSwgMEQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJRUVFcmVtYWluZGVyREQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBkb3VibGUgamF2YS5sYW5nLk1hdGguSUVFRXJlbWFpbmRlcihkb3VibGUsIGRvdWJsZSkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcmVtYWluZGVyIHJldHVybmVkIiwKKyAgICAgICAgICAgICAgICAwLjAsIE1hdGguSUVFRXJlbWFpbmRlcigxLjAsIDEuMCksIDBEKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHJlbWFpbmRlciByZXR1cm5lZCIsIE1hdGguSUVFRXJlbWFpbmRlcigxLjMyLAorICAgICAgICAgICAgICAgIDg5Ljc2NSkgPj0gMS40NzA1MDYzMjIwNjMxNjQ3RS0yCisgICAgICAgICAgICAgICAgfHwgTWF0aC5JRUVFcmVtYWluZGVyKDEuMzIsIDg5Ljc2NSkgPj0gMS40NzA1MDYzMjIwNjMxNjQ5RS0yKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9nRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLmxhbmcuTWF0aC5sb2coZG91YmxlKQorICAgICAgICBmb3IgKGRvdWJsZSBkID0gMTA7IGQgPj0gLTEwOyBkIC09IDAuNSkgeworICAgICAgICAgICAgZG91YmxlIGFuc3dlciA9IE1hdGgubG9nKE1hdGguZXhwKGQpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFuc3dlciBkb2VzIG5vdCBlcXVhbCBleHBlY3RlZCBhbnN3ZXIgZm9yIGQgPSAiICsgZAorICAgICAgICAgICAgICAgICAgICArICIgYW5zd2VyID0gIiArIGFuc3dlciwgTWF0aC5hYnMoYW5zd2VyIC0gZCkgPD0gTWF0aAorICAgICAgICAgICAgICAgICAgICAuYWJzKGQgKiAwLjAwMDAwMDAxKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiYm94aW5nIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9nMTBEKCkgeworICAgICAgICAvLyBUZXN0IGZvciBzcGVjaWFsIGNhc2VzCisgICAgICAgIGFzc2VydFRydWUoRG91YmxlLmlzTmFOKE1hdGgubG9nMTAoRG91YmxlLk5hTikpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShEb3VibGUuaXNOYU4oTWF0aC5sb2cxMCgtMjU0MS4wNTc0NTY4NzIzNDE4NzUzMikpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShEb3VibGUuaXNOYU4oTWF0aC5sb2cxMCgtMC4xKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCBNYXRoLmxvZzEwKERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLk5FR0FUSVZFX0lORklOSVRZLCBNYXRoLmxvZzEwKDAuMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLk5FR0FUSVZFX0lORklOSVRZLCBNYXRoLmxvZzEwKCswLjApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSwgTWF0aC5sb2cxMCgtMC4wKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMuMCwgTWF0aC5sb2cxMCgxMDAwLjApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDE0LjAsIE1hdGgubG9nMTAoTWF0aC5wb3coMTAsIDE0KSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMy43Mzg5NTYxMjY5NTQwNDA2LCBNYXRoLmxvZzEwKDU0ODIuMjE1OCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTQuNjYxNTUxMTQyODkzODMzLCBNYXRoLmxvZzEwKDQ1ODcyMzY2MjMxMjg3Mi4xMjU3ODIzMzI1ODcpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0wLjkwODM4Mjg2MjIxOTIzMzQsIE1hdGgubG9nMTAoMC4xMjM0ODU4MzM1ODg3MSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMzA4LjI1NDcxNTU1OTkxNjc1LCBNYXRoLmxvZzEwKERvdWJsZS5NQVhfVkFMVUUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0zMjMuMzA2MjE1MzQzMTE1OCwgTWF0aC5sb2cxMChEb3VibGUuTUlOX1ZBTFVFKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdExvZzFwRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3Igc3BlY2lhbCBjYXNlcworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIE5hTiIsIERvdWJsZS5pc05hTihNYXRoLmxvZzFwKERvdWJsZS5OYU4pKSk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCByZXR1cm4gTmFOIiwgRG91YmxlLmlzTmFOKE1hdGgubG9nMXAoLTMyLjA0ODIxNzUpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiBQT1NJVElWRV9JTkZJTklUWSIsCisgICAgICAgICAgICAgICAgRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCBNYXRoLmxvZzFwKERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKDAuMCksIERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKE1hdGgKKyAgICAgICAgICAgICAgICAubG9nMXAoMC4wKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoKzAuMCksIERvdWJsZQorICAgICAgICAgICAgICAgIC5kb3VibGVUb0xvbmdCaXRzKE1hdGgubG9nMXAoKzAuMCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKC0wLjApLCBEb3VibGUKKyAgICAgICAgICAgICAgICAuZG91YmxlVG9Mb25nQml0cyhNYXRoLmxvZzFwKC0wLjApKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIC0wLjI5NDE3ODIyOTUzMTI1NDEiLCAtMC4yOTQxNzgyMjk1MzEyNTQxLAorICAgICAgICAgICAgICAgIE1hdGgubG9nMXAoLTAuMjU0ODU2MzI3KSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gNy4zNjgwNTA2ODU1NjQxNTEiLCA3LjM2ODA1MDY4NTU2NDE1MSwgTWF0aAorICAgICAgICAgICAgICAgIC5sb2cxcCgxNTgzLjU0MiksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDAuNDYzMzcwODY4NTQwOTkyMSIsIDAuNDYzMzcwODY4NTQwOTkyMSwKKyAgICAgICAgICAgICAgICBNYXRoLmxvZzFwKDAuNTg5NDIyNyksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDcwOS43ODI3MTI4OTMzODQiLCA3MDkuNzgyNzEyODkzMzg0LCBNYXRoCisgICAgICAgICAgICAgICAgLmxvZzFwKERvdWJsZS5NQVhfVkFMVUUpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiBEb3VibGUuTUlOX1ZBTFVFIiwgRG91YmxlLk1JTl9WQUxVRSwgTWF0aAorICAgICAgICAgICAgICAgIC5sb2cxcChEb3VibGUuTUlOX1ZBTFVFKSwgMEQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYXhERCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLmxhbmcuTWF0aC5tYXgoZG91YmxlLCBkb3VibGUpCisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRvdWJsZSBtYXggdmFsdWUiLCAxOTA4ODk3LjYwMDAwODksIE1hdGgubWF4KC0xOTA4ODk3LjYwMDAwODksCisgICAgICAgICAgICAgICAgMTkwODg5Ny42MDAwMDg5KSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBkb3VibGUgbWF4IHZhbHVlIiwKKyAgICAgICAgICAgICAgICAxOTA4ODk3LjYwMDAwODksIE1hdGgubWF4KDIuMCwgMTkwODg5Ny42MDAwMDg5KSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBkb3VibGUgbWF4IHZhbHVlIiwgLTIuMCwgTWF0aC5tYXgoLTIuMCwKKyAgICAgICAgICAgICAgICAtMTkwODg5Ny42MDAwMDg5KSwgMEQpOworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1heEZGKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgZmxvYXQgamF2YS5sYW5nLk1hdGgubWF4KGZsb2F0LCBmbG9hdCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGZsb2F0IG1heCB2YWx1ZSIsIE1hdGgubWF4KC0xOTA4ODk3LjYwMGYsCisgICAgICAgICAgICAgICAgMTkwODg5Ny42MDBmKSA9PSAxOTA4ODk3LjYwMGYpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZmxvYXQgbWF4IHZhbHVlIiwKKyAgICAgICAgICAgICAgICBNYXRoLm1heCgyLjBmLCAxOTA4ODk3LjYwMGYpID09IDE5MDg4OTcuNjAwZik7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBmbG9hdCBtYXggdmFsdWUiLAorICAgICAgICAgICAgICAgIE1hdGgubWF4KC0yLjBmLCAtMTkwODg5Ny42MDBmKSA9PSAtMi4wZik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1heElJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEubGFuZy5NYXRoLm1heChpbnQsIGludCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgaW50IG1heCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgMTkwODg5NzYsIE1hdGgubWF4KC0xOTA4ODk3NiwgMTkwODg5NzYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgaW50IG1heCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgMTkwODg5NzYsIE1hdGgubWF4KDIwLCAxOTA4ODk3NikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBpbnQgbWF4IHZhbHVlIiwgLTIwLCBNYXRoLm1heCgtMjAsIC0xOTA4ODk3NikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYXhKSigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGxvbmcgamF2YS5sYW5nLk1hdGgubWF4KGxvbmcsIGxvbmcpCisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGxvbmcgbWF4IHZhbHVlIiwgMTkwODg5NzYwMDAwODlMLCBNYXRoLm1heCgtMTkwODg5NzYwMDAwODlMLAorICAgICAgICAgICAgICAgIDE5MDg4OTc2MDAwMDg5TCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBsb25nIG1heCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgMTkwODg5NzYwMDAwODlMLCBNYXRoLm1heCgyMCwgMTkwODg5NzYwMDAwODlMKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGxvbmcgbWF4IHZhbHVlIiwKKyAgICAgICAgICAgICAgICAtMjAsIE1hdGgubWF4KC0yMCwgLTE5MDg4OTc2MDAwMDg5TCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNaW5ERCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLmxhbmcuTWF0aC5taW4oZG91YmxlLCBkb3VibGUpCisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRvdWJsZSBtaW4gdmFsdWUiLCAtMTkwODg5Ny42MDAwMDg5LCBNYXRoLm1pbigtMTkwODg5Ny42MDAwMDg5LAorICAgICAgICAgICAgICAgIDE5MDg4OTcuNjAwMDA4OSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgZG91YmxlIG1pbiB2YWx1ZSIsCisgICAgICAgICAgICAgICAgMi4wLCBNYXRoLm1pbigyLjAsIDE5MDg4OTcuNjAwMDA4OSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgZG91YmxlIG1pbiB2YWx1ZSIsIC0xOTA4ODk3LjYwMDAwODksIE1hdGgubWluKC0yLjAsCisgICAgICAgICAgICAgICAgLTE5MDg4OTcuNjAwMDA4OSksIDBEKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWluRkYoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBmbG9hdCBqYXZhLmxhbmcuTWF0aC5taW4oZmxvYXQsIGZsb2F0KQorICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZmxvYXQgbWluIHZhbHVlIiwgTWF0aC5taW4oLTE5MDg4OTcuNjAwZiwKKyAgICAgICAgICAgICAgICAxOTA4ODk3LjYwMGYpID09IC0xOTA4ODk3LjYwMGYpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZmxvYXQgbWluIHZhbHVlIiwKKyAgICAgICAgICAgICAgICBNYXRoLm1pbigyLjBmLCAxOTA4ODk3LjYwMGYpID09IDIuMGYpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZmxvYXQgbWluIHZhbHVlIiwKKyAgICAgICAgICAgICAgICBNYXRoLm1pbigtMi4wZiwgLTE5MDg4OTcuNjAwZikgPT0gLTE5MDg4OTcuNjAwZik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1pbklJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEubGFuZy5NYXRoLm1pbihpbnQsIGludCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgaW50IG1pbiB2YWx1ZSIsCisgICAgICAgICAgICAgICAgLTE5MDg4OTc2LCBNYXRoLm1pbigtMTkwODg5NzYsIDE5MDg4OTc2KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGludCBtaW4gdmFsdWUiLCAyMCwgTWF0aC5taW4oMjAsIDE5MDg4OTc2KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGludCBtaW4gdmFsdWUiLAorICAgICAgICAgICAgICAgIC0xOTA4ODk3NiwgTWF0aC5taW4oLTIwLCAtMTkwODg5NzYpKTsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNaW5KSigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGxvbmcgamF2YS5sYW5nLk1hdGgubWluKGxvbmcsIGxvbmcpCisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGxvbmcgbWluIHZhbHVlIiwgLTE5MDg4OTc2MDAwMDg5TCwgTWF0aC5taW4oLTE5MDg4OTc2MDAwMDg5TCwKKyAgICAgICAgICAgICAgICAxOTA4ODk3NjAwMDA4OUwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbG9uZyBtaW4gdmFsdWUiLAorICAgICAgICAgICAgICAgIDIwLCBNYXRoLm1pbigyMCwgMTkwODg5NzYwMDAwODlMKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGxvbmcgbWluIHZhbHVlIiwKKyAgICAgICAgICAgICAgICAtMTkwODg5NzYwMDAwODlMLCBNYXRoLm1pbigtMjAsIC0xOTA4ODk3NjAwMDA4OUwpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UG93REQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBkb3VibGUgamF2YS5sYW5nLk1hdGgucG93KGRvdWJsZSwgZG91YmxlKQorICAgICAgICBhc3NlcnRUcnVlKCJwb3cgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwKKyAgICAgICAgICAgICAgICAobG9uZykgTWF0aC5wb3coMiwgOCkgPT0gMjU2bCk7CisgICAgICAgIGFzc2VydFRydWUoInBvdyByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLAorICAgICAgICAgICAgICAgIE1hdGgucG93KDIsIC04KSA9PSAwLjAwMzkwNjI1ZCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHJvb3QgcmV0dXJuZWQxIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMiwgTWF0aC5zcXJ0KE1hdGgucG93KE1hdGguc3FydCgyKSwgNCkpLCAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmludEQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBkb3VibGUgamF2YS5sYW5nLk1hdGgucmludChkb3VibGUpCisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHRvIHJvdW5kIHByb3Blcmx5IC0gdXAgdG8gb2RkIiwKKyAgICAgICAgICAgICAgICAzLjAsIE1hdGgucmludCgyLjkpLCAwRCk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byByb3VuZCBwcm9wZXJseSAtIE5hTiIsIERvdWJsZS5pc05hTihNYXRoCisgICAgICAgICAgICAgICAgLnJpbnQoRG91YmxlLk5hTikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gcm91bmQgcHJvcGVybHkgZG93biAgdG8gZXZlbiIsCisgICAgICAgICAgICAgICAgMi4wLCBNYXRoLnJpbnQoMi4xKSwgMEQpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gcm91bmQgcHJvcGVybHkgIiArIDIuNSArICIgdG8gZXZlbiIsIE1hdGgKKyAgICAgICAgICAgICAgICAucmludCgyLjUpID09IDIuMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJvdW5kRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGxvbmcgamF2YS5sYW5nLk1hdGgucm91bmQoZG91YmxlKQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCByb3VuZGluZyBvZiBhIGZsb2F0IiwgLTkxLCBNYXRoLnJvdW5kKC05MC44OWQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Um91bmRGKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEubGFuZy5NYXRoLnJvdW5kKGZsb2F0KQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCByb3VuZGluZyBvZiBhIGZsb2F0IiwgLTkxLCBNYXRoLnJvdW5kKC05MC44OWYpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2lnbnVtRCgpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShEb3VibGUuaXNOYU4oTWF0aC5zaWdudW0oRG91YmxlLk5hTikpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShEb3VibGUuaXNOYU4oTWF0aC5zaWdudW0oRG91YmxlLk5hTikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKDAuMCksIERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKE1hdGgKKyAgICAgICAgICAgICAgICAuc2lnbnVtKDAuMCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKCswLjApLCBEb3VibGUKKyAgICAgICAgICAgICAgICAuZG91YmxlVG9Mb25nQml0cyhNYXRoLnNpZ251bSgrMC4wKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoLTAuMCksIERvdWJsZQorICAgICAgICAgICAgICAgIC5kb3VibGVUb0xvbmdCaXRzKE1hdGguc2lnbnVtKC0wLjApKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMCwgTWF0aC5zaWdudW0oMjUzNjgxLjIxODc5NjIpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygtMS4wLCBNYXRoLnNpZ251bSgtMTI1ODc0NjkzLjU2KSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoMS4wLCBNYXRoLnNpZ251bSgxLjI1ODdFLTMwOCksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLjAsIE1hdGguc2lnbnVtKC0xLjI1ODdFLTMwOCksIDBEKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMS4wLCBNYXRoLnNpZ251bShEb3VibGUuTUFYX1ZBTFVFKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoMS4wLCBNYXRoLnNpZ251bShEb3VibGUuTUlOX1ZBTFVFKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEuMCwgTWF0aC5zaWdudW0oLURvdWJsZS5NQVhfVkFMVUUpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygtMS4wLCBNYXRoLnNpZ251bSgtRG91YmxlLk1JTl9WQUxVRSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMCwgTWF0aC5zaWdudW0oRG91YmxlLlBPU0lUSVZFX0lORklOSVRZKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEuMCwgTWF0aC5zaWdudW0oRG91YmxlLk5FR0FUSVZFX0lORklOSVRZKSwgMEQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTaWdudW1GKCkgeworICAgICAgICBhc3NlcnRUcnVlKEZsb2F0LmlzTmFOKE1hdGguc2lnbnVtKEZsb2F0Lk5hTikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEZsb2F0LmZsb2F0VG9JbnRCaXRzKDAuMGYpLCBGbG9hdAorICAgICAgICAgICAgICAgIC5mbG9hdFRvSW50Qml0cyhNYXRoLnNpZ251bSgwLjBmKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRmxvYXQuZmxvYXRUb0ludEJpdHMoKzAuMGYpLCBGbG9hdAorICAgICAgICAgICAgICAgIC5mbG9hdFRvSW50Qml0cyhNYXRoLnNpZ251bSgrMC4wZikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEZsb2F0LmZsb2F0VG9JbnRCaXRzKC0wLjBmKSwgRmxvYXQKKyAgICAgICAgICAgICAgICAuZmxvYXRUb0ludEJpdHMoTWF0aC5zaWdudW0oLTAuMGYpKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMGYsIE1hdGguc2lnbnVtKDI1MzY4MS4yMTg3OTYyZiksIDBmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLjBmLCBNYXRoLnNpZ251bSgtMTI1ODc0NjkzLjU2ZiksIDBmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMGYsIE1hdGguc2lnbnVtKDEuMjU4N0UtMTFmKSwgMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEuMGYsIE1hdGguc2lnbnVtKC0xLjI1ODdFLTExZiksIDBmKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMS4wZiwgTWF0aC5zaWdudW0oRmxvYXQuTUFYX1ZBTFVFKSwgMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoMS4wZiwgTWF0aC5zaWdudW0oRmxvYXQuTUlOX1ZBTFVFKSwgMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEuMGYsIE1hdGguc2lnbnVtKC1GbG9hdC5NQVhfVkFMVUUpLCAwZik7CisgICAgICAgIGFzc2VydEVxdWFscygtMS4wZiwgTWF0aC5zaWdudW0oLUZsb2F0Lk1JTl9WQUxVRSksIDBmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMGYsIE1hdGguc2lnbnVtKEZsb2F0LlBPU0lUSVZFX0lORklOSVRZKSwgMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEuMGYsIE1hdGguc2lnbnVtKEZsb2F0Lk5FR0FUSVZFX0lORklOSVRZKSwgMGYpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTaW5EKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgZG91YmxlIGphdmEubGFuZy5NYXRoLnNpbihkb3VibGUpCisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFuc3dlciIsIDAuMCwgTWF0aC5zaW4oMCksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYW5zd2VyIiwgMC44NDE0NzA5ODQ4MDc4OTY1LCBNYXRoLnNpbigxKSwgMEQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTaW5oRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3Igc3BlY2lhbCBzaXR1YXRpb25zCisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCByZXR1cm4gTmFOIiwgRG91YmxlLmlzTmFOKE1hdGguc2luaChEb3VibGUuTmFOKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgTWF0aC5zaW5oKERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIE5FR0FUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFksIE1hdGguc2luaChEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuZG91YmxlVG9Mb25nQml0cygwLjApLCBEb3VibGUuZG91YmxlVG9Mb25nQml0cyhNYXRoCisgICAgICAgICAgICAgICAgLnNpbmgoMC4wKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoKzAuMCksIERvdWJsZQorICAgICAgICAgICAgICAgIC5kb3VibGVUb0xvbmdCaXRzKE1hdGguc2luaCgrMC4wKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoLTAuMCksIERvdWJsZQorICAgICAgICAgICAgICAgIC5kb3VibGVUb0xvbmdCaXRzKE1hdGguc2luaCgtMC4wKSkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiBQT1NJVElWRV9JTkZJTklUWSIsCisgICAgICAgICAgICAgICAgRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCBNYXRoLnNpbmgoMTIzNC41NiksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIE5FR0FUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFksIE1hdGguc2luaCgtMTIzNC41NiksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDEuMDAwMDAwMDAwMDAwMTY2NkUtNiIsCisgICAgICAgICAgICAgICAgMS4wMDAwMDAwMDAwMDAxNjY2RS02LCBNYXRoLnNpbmgoMC4wMDAwMDEpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiAtMS4wMDAwMDAwMDAwMDAxNjY2RS02IiwKKyAgICAgICAgICAgICAgICAtMS4wMDAwMDAwMDAwMDAxNjY2RS02LCBNYXRoLnNpbmgoLTAuMDAwMDAxKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gNS4xMTUzODY0NDE5NjM4NTkiLCA1LjExNTM4NjQ0MTk2Mzg1OSwgTWF0aAorICAgICAgICAgICAgICAgIC5zaW5oKDIuMzM0ODIpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiBQT1NJVElWRV9JTkZJTklUWSIsCisgICAgICAgICAgICAgICAgRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCBNYXRoLnNpbmgoRG91YmxlLk1BWF9WQUxVRSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDQuOUUtMzI0IiwgNC45RS0zMjQsIE1hdGgKKyAgICAgICAgICAgICAgICAuc2luaChEb3VibGUuTUlOX1ZBTFVFKSwgMEQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTcXJ0RCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLmxhbmcuTWF0aC5zcXJ0KGRvdWJsZSkKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCByb290IHJldHVybmVkMiIsIDcsIE1hdGguc3FydCg0OSksIDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUYW5EKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgZG91YmxlIGphdmEubGFuZy5NYXRoLnRhbihkb3VibGUpCisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFuc3dlciIsIDAuMCwgTWF0aC50YW4oMCksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYW5zd2VyIiwgMS41NTc0MDc3MjQ2NTQ5MDIzLCBNYXRoLnRhbigxKSwgMEQpOworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRhbmhEKCkgeworICAgICAgICAvLyBUZXN0IGZvciBzcGVjaWFsIHNpdHVhdGlvbnMKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiBOYU4iLCBEb3VibGUuaXNOYU4oTWF0aC50YW5oKERvdWJsZS5OYU4pKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiArMS4wIiwgKzEuMCwgTWF0aAorICAgICAgICAgICAgICAgIC50YW5oKERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIC0xLjAiLCAtMS4wLCBNYXRoCisgICAgICAgICAgICAgICAgLnRhbmgoRG91YmxlLk5FR0FUSVZFX0lORklOSVRZKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoMC4wKSwgRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoTWF0aAorICAgICAgICAgICAgICAgIC50YW5oKDAuMCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKCswLjApLCBEb3VibGUKKyAgICAgICAgICAgICAgICAuZG91YmxlVG9Mb25nQml0cyhNYXRoLnRhbmgoKzAuMCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKC0wLjApLCBEb3VibGUKKyAgICAgICAgICAgICAgICAuZG91YmxlVG9Mb25nQml0cyhNYXRoLnRhbmgoLTAuMCkpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gMS4wIiwgMS4wLCBNYXRoLnRhbmgoMTIzNC41NiksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIC0xLjAiLCAtMS4wLCBNYXRoLnRhbmgoLTEyMzQuNTYpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiA5Ljk5OTk5OTk5OTk5NjY2NkUtNyIsCisgICAgICAgICAgICAgICAgOS45OTk5OTk5OTk5OTY2NjZFLTcsIE1hdGgudGFuaCgwLjAwMDAwMSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDAuOTgxNDIyODg0MTI0OTQxIiwgMC45ODE0MjI4ODQxMjQ5NDEsIE1hdGgKKyAgICAgICAgICAgICAgICAudGFuaCgyLjMzNDgyKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gMS4wIiwgMS4wLCBNYXRoLnRhbmgoRG91YmxlLk1BWF9WQUxVRSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDQuOUUtMzI0IiwgNC45RS0zMjQsIE1hdGgKKyAgICAgICAgICAgICAgICAudGFuaChEb3VibGUuTUlOX1ZBTFVFKSwgMEQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSYW5kb20oKSB7CisgICAgICAgIC8vIFRoZXJlIGlzbid0IGEgcGxhY2UgZm9yIHRoZXNlIHRlc3RzIHNvIGp1c3Qgc3RpY2sgdGhlbSBoZXJlCisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgRSIsCisgICAgICAgICAgICAgICAgNDYxMzMwMzQ0NTMxNDg4NTQ4MUwsIERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKE1hdGguRSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIFBJIiwKKyAgICAgICAgICAgICAgICA0NjE0MjU2NjU2NTUyMDQ1ODQ4TCwgRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoTWF0aC5QSSkpOworCisgICAgICAgIGZvciAoaW50IGkgPSA1MDA7IGkgPj0gMDsgaS0tKSB7CisgICAgICAgICAgICBkb3VibGUgZCA9IE1hdGgucmFuZG9tKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJHZW5lcmF0ZWQgbnVtYmVyIGlzIG91dCBvZiByYW5nZTogIiArIGQsIGQgPj0gMC4wCisgICAgICAgICAgICAgICAgICAgICYmIGQgPCAxLjApOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRvUmFkaWFuc0QoKSB7CisgICAgICAgIGZvciAoZG91YmxlIGQgPSA1MDA7IGQgPj0gMDsgZCAtPSAxLjApIHsKKyAgICAgICAgICAgIGRvdWJsZSBjb252ZXJ0ZWQgPSBNYXRoLnRvRGVncmVlcyhNYXRoLnRvUmFkaWFucyhkKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJDb252ZXJ0ZWQgbnVtYmVyIG5vdCBlcXVhbCB0byBvcmlnaW5hbC4gZCA9ICIgKyBkLAorICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ZWQgPj0gZCAqIDAuOTk5OTk5OTkgJiYgY29udmVydGVkIDw9IGQgKiAxLjAwMDAwMDAxKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUb0RlZ3JlZXNEKCkgeworICAgICAgICBmb3IgKGRvdWJsZSBkID0gNTAwOyBkID49IDA7IGQgLT0gMS4wKSB7CisgICAgICAgICAgICBkb3VibGUgY29udmVydGVkID0gTWF0aC50b1JhZGlhbnMoTWF0aC50b0RlZ3JlZXMoZCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29udmVydGVkIG51bWJlciBub3QgZXF1YWwgdG8gb3JpZ2luYWwuIGQgPSAiICsgZCwKKyAgICAgICAgICAgICAgICAgICAgY29udmVydGVkID49IGQgKiAwLjk5OTk5OTk5ICYmIGNvbnZlcnRlZCA8PSBkICogMS4wMDAwMDAwMSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiYm94aW5nIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VWxwRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3Igc3BlY2lhbCBjYXNlcworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIE5hTiIsIERvdWJsZS5pc05hTihNYXRoLnVscChEb3VibGUuTmFOKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgTWF0aAorICAgICAgICAgICAgICAgIC51bHAoRG91YmxlLlBPU0lUSVZFX0lORklOSVRZKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgTWF0aAorICAgICAgICAgICAgICAgIC51bHAoRG91YmxlLk5FR0FUSVZFX0lORklOSVRZKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIERvdWJsZS5NSU5fVkFMVUUsIE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKDAuMCksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBEb3VibGUuTUlOX1ZBTFVFLCBNYXRoCisgICAgICAgICAgICAgICAgLnVscCgrMC4wKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIERvdWJsZS5NSU5fVkFMVUUsIE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKC0wLjApLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgTWF0aC5wb3coMiwgOTcxKSwgTWF0aAorICAgICAgICAgICAgICAgIC51bHAoRG91YmxlLk1BWF9WQUxVRSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBNYXRoLnBvdygyLCA5NzEpLCBNYXRoCisgICAgICAgICAgICAgICAgLnVscCgtRG91YmxlLk1BWF9WQUxVRSksIDBEKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIERvdWJsZS5NSU5fVkFMVUUsIE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKERvdWJsZS5NSU5fVkFMVUUpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgRG91YmxlLk1JTl9WQUxVRSwgTWF0aAorICAgICAgICAgICAgICAgIC51bHAoLURvdWJsZS5NSU5fVkFMVUUpLCAwRCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAyLjIyMDQ0NjA0OTI1MDMxM0UtMTYsIE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKDEuMCksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAyLjIyMDQ0NjA0OTI1MDMxM0UtMTYsIE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKC0xLjApLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgMi4yNzM3MzY3NTQ0MzIzMjA2RS0xMywgTWF0aAorICAgICAgICAgICAgICAgIC51bHAoMTE1My4wKSwgMEQpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJib3hpbmciKQorICAgIHB1YmxpYyB2b2lkIHRlc3RVbHBmKCkgeworICAgICAgICAvLyBUZXN0IGZvciBzcGVjaWFsIGNhc2VzCisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCByZXR1cm4gTmFOIiwgRmxvYXQuaXNOYU4oTWF0aC51bHAoRmxvYXQuTmFOKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIEZsb2F0LlBPU0lUSVZFX0lORklOSVRZLCBNYXRoCisgICAgICAgICAgICAgICAgLnVscChGbG9hdC5QT1NJVElWRV9JTkZJTklUWSksIDBmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBGbG9hdC5QT1NJVElWRV9JTkZJTklUWSwgTWF0aAorICAgICAgICAgICAgICAgIC51bHAoRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFkpLCAwZik7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgRmxvYXQuTUlOX1ZBTFVFLCBNYXRoCisgICAgICAgICAgICAgICAgLnVscCgwLjBmKSwgMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIEZsb2F0Lk1JTl9WQUxVRSwgTWF0aAorICAgICAgICAgICAgICAgIC51bHAoKzAuMGYpLCAwZik7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgRmxvYXQuTUlOX1ZBTFVFLCBNYXRoCisgICAgICAgICAgICAgICAgLnVscCgtMC4wZiksIDBmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAyLjAyODI0MUUzMWYsIE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKEZsb2F0Lk1BWF9WQUxVRSksIDBmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAyLjAyODI0MUUzMWYsIE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKC1GbG9hdC5NQVhfVkFMVUUpLCAwZik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAxLjRFLTQ1ZiwgTWF0aAorICAgICAgICAgICAgICAgIC51bHAoRmxvYXQuTUlOX1ZBTFVFKSwgMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIDEuNEUtNDVmLCBNYXRoCisgICAgICAgICAgICAgICAgLnVscCgtRmxvYXQuTUlOX1ZBTFVFKSwgMGYpOworCisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgMS4xOTIwOTI5RS03ZiwgTWF0aC51bHAoMS4wZiksCisgICAgICAgICAgICAgICAgMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIDEuMTkyMDkyOUUtN2YsCisgICAgICAgICAgICAgICAgTWF0aC51bHAoLTEuMGYpLCAwZik7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgMS4yMjA3MDMxRS00ZiwgTWF0aAorICAgICAgICAgICAgICAgIC51bHAoMTE1My4wZiksIDBmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCA1LjZFLTQ1ZiwgTWF0aAorICAgICAgICAgICAgICAgIC51bHAoOS40MDM5NTRFLTM4ZiksIDBmKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkQW5kcm9pZE1vbml0b3JUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkQW5kcm9pZE1vbml0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDE3MDRmYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRBbmRyb2lkTW9uaXRvclRlc3QuamF2YQpAQCAtMCwwICsxLDQ2NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkTW9uaXRvclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V2FpdEFyZ3VtZW50c1Rlc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIC8qIFRyeSBzb21lIHZhbGlkIGFyZ3VtZW50cy4gIFRoZXNlIHNob3VsZCBhbGwKKyAgICAgICAgICAgICAqIHJldHVybiB2ZXJ5IHF1aWNrbHkuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICAgICAgICAgIC8qIG1pbGxpc2Vjb25kIHZlcnNpb24gKi8KKyAgICAgICAgICAgICAgICAgICAgd2FpdCgxKTsKKyAgICAgICAgICAgICAgICAgICAgd2FpdCgxMCk7CisKKyAgICAgICAgICAgICAgICAgICAgLyogbWlsbGlzZWNvbmQgKyBuYW5vc2Vjb25kIHZlcnNpb24gKi8KKyAgICAgICAgICAgICAgICAgICAgd2FpdCgwLCAxKTsKKyAgICAgICAgICAgICAgICAgICAgd2FpdCgwLCA5OTk5OTkpOworICAgICAgICAgICAgICAgICAgICB3YWl0KDEsIDEpOworICAgICAgICAgICAgICAgICAgICB3YWl0KDEsIDk5OTk5OSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiZ29vZCBPYmplY3Qud2FpdCgpIGludGVycnVwdGVkIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGV4KTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiB3aGVuIGNhbGxpbmciICsKKyAgICAgICAgICAgICAgICAgICAgICAgICJPYmplY3Qud2FpdCgpIHdpdGggZ29vZCBhcmd1bWVudHMiLCBleCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qIFRyeSBzb21lIGludmFsaWQgYXJndW1lbnRzLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBib29sZWFuIHNhd0V4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgICAgICAgICAgd2FpdCgtMSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiYmFkIE9iamVjdC53YWl0KCkgaW50ZXJydXB0ZWQiLCBleCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzYXdFeGNlcHRpb24gPSB0cnVlOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIHdoZW4gY2FsbGluZyIgKworICAgICAgICAgICAgICAgICAgICAgICAgIk9iamVjdC53YWl0KCkgd2l0aCBiYWQgYXJndW1lbnRzIiwgZXgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFzYXdFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiYmFkIGNhbGwgdG8gT2JqZWN0LndhaXQoKSBzaG91bGQgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAiaGF2ZSB0aHJvd24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHNhd0V4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgICAgICAgICAgd2FpdCgwLCAtMSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiYmFkIE9iamVjdC53YWl0KCkgaW50ZXJydXB0ZWQiLCBleCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzYXdFeGNlcHRpb24gPSB0cnVlOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIHdoZW4gY2FsbGluZyIgKworICAgICAgICAgICAgICAgICAgICAgICAgIk9iamVjdC53YWl0KCkgd2l0aCBiYWQgYXJndW1lbnRzIiwgZXgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFzYXdFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiYmFkIGNhbGwgdG8gT2JqZWN0LndhaXQoKSBzaG91bGQgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAiaGF2ZSB0aHJvd24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHNhd0V4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgICAgICAgICAgLyogVGhlIGxlZ2FsIHJhbmdlIG9mIG5hbm9zIGlzIDAtOTk5OTk5LiAqLworICAgICAgICAgICAgICAgICAgICB3YWl0KDAsIDEwMDAwMDApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oImJhZCBPYmplY3Qud2FpdCgpIGludGVycnVwdGVkIiwgZXgpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgc2F3RXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiB3aGVuIGNhbGxpbmciICsKKyAgICAgICAgICAgICAgICAgICAgICAgICJPYmplY3Qud2FpdCgpIHdpdGggYmFkIGFyZ3VtZW50cyIsIGV4KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghc2F3RXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oImJhZCBjYWxsIHRvIE9iamVjdC53YWl0KCkgc2hvdWxkICIgKworICAgICAgICAgICAgICAgICAgICAgICAgImhhdmUgdGhyb3duIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgSW50ZXJydXB0ZXIgZXh0ZW5kcyBUaHJlYWQgeworICAgICAgICAgICAgV2FpdGVyIHdhaXRlcjsKKworICAgICAgICAgICAgSW50ZXJydXB0ZXIoU3RyaW5nIG5hbWUsIFdhaXRlciB3YWl0ZXIpIHsKKyAgICAgICAgICAgICAgICBzdXBlcihuYW1lKTsKKyAgICAgICAgICAgICAgICB0aGlzLndhaXRlciA9IHdhaXRlcjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHJ1bl9pbm5lcigpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgICAgICAgICAgIE9sZEFuZHJvaWRNb25pdG9yVGVzdC5lcnJvckV4Y2VwdGlvbiA9IHQ7CisgICAgICAgICAgICAgICAgICAgIE9sZEFuZHJvaWRNb25pdG9yVGVzdC50ZXN0VGhyZWFkLmludGVycnVwdCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdm9pZCBydW5faW5uZXIoKSB7CisgICAgICAgICAgICAgICAgd2FpdGVyLnNwaW4gPSB0cnVlOworICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiSW50ZXJydXB0VGVzdDogc3RhcnRpbmcgd2FpdGVyIik7CisgICAgICAgICAgICAgICAgd2FpdGVyLnN0YXJ0KCk7CisKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLnNsZWVwKDUwMCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlRlc3Qgc2xlZXAgaW50ZXJydXB0ZWQuIiwgZXgpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8qIFdhaXRlciBpcyBzcGlubmluZywgYW5kIGl0cyBtb25pdG9yIHNob3VsZCBzdGlsbCBiZSB0aGluLgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiVGVzdCBpbnRlcnJ1cHRpbmcgd2FpdGVyIik7CisgICAgICAgICAgICAgICAgd2FpdGVyLmludGVycnVwdCgpOworICAgICAgICAgICAgICAgIHdhaXRlci5zcGluID0gZmFsc2U7CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAvKiBXYWl0IGZvciB0aGUgd2FpdGVyIHRvIHN0YXJ0IHdhaXRpbmcuCisgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHdhaXRlci5pbnRlcnJ1cHRlckxvY2spIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2FpdGVyLmludGVycnVwdGVyTG9jay53YWl0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJUZXN0IHdhaXQgaW50ZXJydXB0ZWQuIiwgZXgpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgLyogQmVmb3JlIGludGVycnVwdGluZywgZ3JhYiB0aGUgd2FpdGVyIGxvY2ssIHdoaWNoCisgICAgICAgICAgICAgICAgICAgICAqIGd1YXJhbnRlZXMgdGhhdCB0aGUgd2FpdGVyIGlzIGFscmVhZHkgc2l0dGluZyBpbiB3YWl0KCkuCisgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHdhaXRlcikgeworICAgICAgICAgICAgICAgICAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oIlRlc3QgaW50ZXJydXB0aW5nIHdhaXRlciAoIiArIGkgKyAiKSIpOworICAgICAgICAgICAgICAgICAgICAgICAgd2FpdGVyLmludGVycnVwdCgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJUZXN0IHdhaXRpbmcgZm9yIHdhaXRlciB0byBkaWUuIik7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgd2FpdGVyLmpvaW4oKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVGVzdCBqb2luIGludGVycnVwdGVkLiIsIGV4KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJJbnRlcnJ1cHRUZXN0IGRvbmUuIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgV2FpdGVyIGV4dGVuZHMgVGhyZWFkIHsKKyAgICAgICAgICAgIE9iamVjdCBpbnRlcnJ1cHRlckxvY2sgPSBuZXcgT2JqZWN0KCk7CisgICAgICAgICAgICBCb29sZWFuIHNwaW4gPSBmYWxzZTsKKworICAgICAgICAgICAgV2FpdGVyKFN0cmluZyBuYW1lKSB7CisgICAgICAgICAgICAgICAgc3VwZXIobmFtZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBydW5faW5uZXIoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgICAgICAgICBPbGRBbmRyb2lkTW9uaXRvclRlc3QuZXJyb3JFeGNlcHRpb24gPSB0OworICAgICAgICAgICAgICAgICAgICBPbGRBbmRyb2lkTW9uaXRvclRlc3QudGVzdFRocmVhZC5pbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHZvaWQgcnVuX2lubmVyKCkgeworICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiV2FpdGVyIHNwaW5uaW5nIik7CisgICAgICAgICAgICAgICAgd2hpbGUgKHNwaW4pIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gV2UncmUgZ29pbmcgdG8gZ2V0IGludGVycnVwdGVkIHdoaWxlIHdlIHNwaW4uCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChpbnRlcnJ1cHRlZCgpKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiV2FpdGVyIGRvbmUgc3Bpbm5pbmc7IGludGVycnVwdGVkLiIpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJUaHJlYWQgbm90IGludGVycnVwdGVkICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZHVyaW5nIHNwaW4iKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgICAgICAgICAgQm9vbGVhbiBzYXdFeCA9IGZhbHNlOworCisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGludGVycnVwdGVyTG9jaykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVycnVwdGVyTG9jay5ub3RpZnkoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiV2FpdGVyIGNhbGxpbmcgd2FpdCgpIik7CisgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndhaXQoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNhd0V4ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigid2FpdCgpOiBXYWl0ZXIgY2F1Z2h0ICIgKyBleCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJ3YWl0KCkgZmluaXNoZWQiKTsKKworICAgICAgICAgICAgICAgICAgICBpZiAoIXNhd0V4KSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVGhyZWFkIG5vdCBpbnRlcnJ1cHRlZCAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkdXJpbmcgd2FpdCgpIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICAgICAgICAgIEJvb2xlYW4gc2F3RXggPSBmYWxzZTsKKworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVkIChpbnRlcnJ1cHRlckxvY2spIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnJ1cHRlckxvY2subm90aWZ5KCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIldhaXRlciBjYWxsaW5nIHdhaXQoMTAwMCkiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2FpdCgxMDAwKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNhd0V4ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigid2FpdCgxMDAwKTogV2FpdGVyIGNhdWdodCAiICsgZXgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigid2FpdCgxMDAwKSBmaW5pc2hlZCIpOworCisgICAgICAgICAgICAgICAgICAgIGlmICghc2F3RXgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJUaHJlYWQgbm90IGludGVycnVwdGVkICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImR1cmluZyB3YWl0KDEwMDApIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICAgICAgICAgIEJvb2xlYW4gc2F3RXggPSBmYWxzZTsKKworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVkIChpbnRlcnJ1cHRlckxvY2spIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnJ1cHRlckxvY2subm90aWZ5KCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIldhaXRlciBjYWxsaW5nIHdhaXQoMTAwMCwgNTAwMCkiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2FpdCgxMDAwLCA1MDAwKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNhd0V4ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigid2FpdCgxMDAwLCA1MDAwKTogV2FpdGVyIGNhdWdodCAiICsgZXgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigid2FpdCgxMDAwLCA1MDAwKSBmaW5pc2hlZCIpOworCisgICAgICAgICAgICAgICAgICAgIGlmICghc2F3RXgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJUaHJlYWQgbm90IGludGVycnVwdGVkICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImR1cmluZyB3YWl0KDEwMDAsIDUwMDApIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgIC8vICBTeXN0ZW0ub3V0LnByaW50bG4oIldhaXRlciByZXR1cm5pbmciKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgVGhyb3dhYmxlIGVycm9yRXhjZXB0aW9uOworICAgIHByaXZhdGUgc3RhdGljIFRocmVhZCB0ZXN0VGhyZWFkOworCisgICAgLy8gVE9ETzogRmxha3kgdGVzdC4gQWRkIGJhY2sgTWVkaXVtVGVzdCBhbm5vdGF0aW9uIG9uY2UgZml4ZWQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW50ZXJydXB0VGVzdCgpIHRocm93cyBFeGNlcHRpb24geworCisKKyAgICAgICAgICAgIHRlc3RUaHJlYWQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICAgICAgZXJyb3JFeGNlcHRpb24gPSBudWxsOworCisgICAgICAgICAgICBXYWl0ZXIgd2FpdGVyID0gbmV3IFdhaXRlcigiSW50ZXJydXB0VGVzdCBXYWl0ZXIiKTsKKyAgICAgICAgICAgIEludGVycnVwdGVyIGludGVycnVwdGVyID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IEludGVycnVwdGVyKCJJbnRlcnJ1cHRUZXN0IEludGVycnVwdGVyIiwgd2FpdGVyKTsKKyAgICAgICAgICAgIGludGVycnVwdGVyLnN0YXJ0KCk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaW50ZXJydXB0ZXIuam9pbigpOworICAgICAgICAgICAgICAgIHdhaXRlci5qb2luKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJUZXN0IGpvaW4gaW50ZXJydXB0ZWQuIiwgZXgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZXJyb3JFeGNlcHRpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbnRlcnJ1cHRUZXN0IGZhaWxlZCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JFeGNlcHRpb24pOworICAgICAgICAgICAgfQorCisKKworCisgICAgfQorCisgICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZGVlcFdhaXQoaW50IGRlcHRoLCBPYmplY3QgbG9jaykgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICAgICAgaWYgKGRlcHRoID4gMCkgeworICAgICAgICAgICAgICAgICAgICBkZWVwV2FpdChkZXB0aCAtIDEsIGxvY2spOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyB0aHJlYWROYW1lID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXROYW1lKCk7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4odGhyZWFkTmFtZSArICIgd2FpdGluZyIpOworICAgICAgICAgICAgICAgICAgICAgICAgbG9jay53YWl0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4odGhyZWFkTmFtZSArICIgZG9uZSB3YWl0aW5nIik7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4odGhyZWFkTmFtZSArICIgaW50ZXJydXB0ZWQuIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIGNsYXNzIFdvcmtlciBleHRlbmRzIFRocmVhZCB7CisgICAgICAgICAgICBPYmplY3QgbG9jazsKKyAgICAgICAgICAgIGludCBpZDsKKworICAgICAgICAgICAgV29ya2VyKGludCBpZCwgT2JqZWN0IGxvY2spIHsKKyAgICAgICAgICAgICAgICBzdXBlcigiV29ya2VyKCIgKyBpZCArICIpIik7CisgICAgICAgICAgICAgICAgdGhpcy5pZCA9IGlkOworICAgICAgICAgICAgICAgIHRoaXMubG9jayA9IGxvY2s7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICBpbnQgaXRlcmF0aW9ucyA9IDA7CisKKyAgICAgICAgICAgICAgICB3aGlsZSAoT2xkQW5kcm9pZE1vbml0b3JUZXN0LnJ1bm5pbmcpIHsKKyAgICAgICAgICAgICAgICAgICAgT2xkQW5kcm9pZE1vbml0b3JUZXN0LmRlZXBXYWl0KGlkLCBsb2NrKTsKKyAgICAgICAgICAgICAgICAgICAgaXRlcmF0aW9ucysrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oZ2V0TmFtZSgpICsgIiBkb25lIGFmdGVyICIgKyBpdGVyYXRpb25zICsgIiBpdGVyYXRpb25zLiIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBPYmplY3QgY29tbW9uTG9jayA9IG5ldyBPYmplY3QoKTsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgQm9vbGVhbiBydW5uaW5nID0gZmFsc2U7CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3ROZXN0ZWRNb25pdG9ycygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgTlVNX1dPUktFUlMgPSA1OworCisgICAgICAgICAgICBXb3JrZXIgd1tdID0gbmV3IFdvcmtlcltOVU1fV09SS0VSU107CisgICAgICAgICAgICBpbnQgaTsKKworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IE5VTV9XT1JLRVJTOyBpKyspIHsKKyAgICAgICAgICAgICAgICB3W2ldID0gbmV3IFdvcmtlcihpICogMiAtIDEsIG5ldyBPYmplY3QoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJ1bm5pbmcgPSB0cnVlOworCisgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIk5lc3RlZE1vbml0b3JzOiBzdGFydGluZyB3b3JrZXJzIik7CisgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX1dPUktFUlM7IGkrKykgeworICAgICAgICAgICAgICAgIHdbaV0uc3RhcnQoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLnNsZWVwKDEwMDApOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiVGVzdCBzbGVlcCBpbnRlcnJ1cHRlZC4iKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IDEwMDsgaSsrKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBOVU1fV09SS0VSUzsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAod1tqXS5sb2NrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB3W2pdLmxvY2subm90aWZ5KCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiTmVzdGVyTW9uaXRvcnM6IHN0b3BwaW5nIHdvcmtlcnMiKTsKKyAgICAgICAgICAgIHJ1bm5pbmcgPSBmYWxzZTsKKyAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fV09SS0VSUzsgaSsrKSB7CisgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICh3W2ldLmxvY2spIHsKKyAgICAgICAgICAgICAgICAgICAgd1tpXS5sb2NrLm5vdGlmeUFsbCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBDb21wYXJlQW5kRXhjaGFuZ2UgZXh0ZW5kcyBUaHJlYWQgeworICAgICAgICBzdGF0aWMgT2JqZWN0IHRvZ2dsZUxvY2sgPSBudWxsOworICAgICAgICBzdGF0aWMgaW50IHRvZ2dsZSA9IC0xOworICAgICAgICBzdGF0aWMgQm9vbGVhbiBydW5uaW5nID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgdG9nZ2xlTG9jayA9IG5ldyBPYmplY3QoKTsKKyAgICAgICAgICAgIHRvZ2dsZSA9IC0xOworCisgICAgICAgICAgICBXb3JrZXIgdzEgPSBuZXcgV29ya2VyKDAsIDEpOworICAgICAgICAgICAgV29ya2VyIHcyID0gbmV3IFdvcmtlcigyLCAzKTsKKyAgICAgICAgICAgIFdvcmtlciB3MyA9IG5ldyBXb3JrZXIoNCwgNSk7CisgICAgICAgICAgICBXb3JrZXIgdzQgPSBuZXcgV29ya2VyKDYsIDcpOworCisgICAgICAgICAgICBydW5uaW5nID0gdHJ1ZTsKKworICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJDb21wYXJlQW5kRXhjaGFuZ2U6IHN0YXJ0aW5nIHdvcmtlcnMiKTsKKworICAgICAgICAgICAgdzEuc3RhcnQoKTsKKyAgICAgICAgICAgIHcyLnN0YXJ0KCk7CisgICAgICAgICAgICB3My5zdGFydCgpOworICAgICAgICAgICAgdzQuc3RhcnQoKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0aGlzLnNsZWVwKDEwMDAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKGdldE5hbWUoKSArICIgaW50ZXJydXB0ZWQuIik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiTW9uaXRvclRlc3Q6IHN0b3BwaW5nIHdvcmtlcnMiKTsKKyAgICAgICAgICAgIHJ1bm5pbmcgPSBmYWxzZTsKKworICAgICAgICAgICAgdG9nZ2xlTG9jayA9IG51bGw7CisgICAgICAgIH0KKworICAgICAgICBjbGFzcyBXb3JrZXIgZXh0ZW5kcyBUaHJlYWQgeworICAgICAgICAgICAgaW50IGkxOworICAgICAgICAgICAgaW50IGkyOworCisgICAgICAgICAgICBXb3JrZXIoaW50IGkxLCBpbnQgaTIpIHsKKyAgICAgICAgICAgICAgICBzdXBlcigiV29ya2VyKCIgKyBpMSArICIsICIgKyBpMiArICIpIik7CisgICAgICAgICAgICAgICAgdGhpcy5pMSA9IGkxOworICAgICAgICAgICAgICAgIHRoaXMuaTIgPSBpMjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIGludCBpdGVyYXRpb25zID0gMDsKKworICAgICAgICAgICAgICAgIC8qIExhdGNoIHRoaXMgYmVjYXVzZSBydW4oKSBtYXkgc2V0IHRoZSBzdGF0aWMgZmllbGQgdG8KKyAgICAgICAgICAgICAgICAgKiBudWxsIGF0IHNvbWUgcG9pbnQuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgT2JqZWN0IHRvZ2dsZUxvY2sgPSBDb21wYXJlQW5kRXhjaGFuZ2UudG9nZ2xlTG9jazsKKworICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihnZXROYW1lKCkgKyAiIHJ1bm5pbmciKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICB3aGlsZSAoQ29tcGFyZUFuZEV4Y2hhbmdlLnJ1bm5pbmcpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAodG9nZ2xlTG9jaykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB0ZXN0OworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjaGVjazsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChDb21wYXJlQW5kRXhjaGFuZ2UudG9nZ2xlID09IGkxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2xlZXAoNSArIGkyKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29tcGFyZUFuZEV4Y2hhbmdlLnRvZ2dsZSA9IHRlc3QgPSBpMjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNsZWVwKDUgKyBpMSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbXBhcmVBbmRFeGNoYW5nZS50b2dnbGUgPSB0ZXN0ID0gaTE7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoY2hlY2sgPSBDb21wYXJlQW5kRXhjaGFuZ2UudG9nZ2xlKSAhPSB0ZXN0KSB7CisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJXb3JrZXIoIiArIGkxICsgIiwgIiArCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkyICsgIikgIiArICJ0ZXN0ICIgKyB0ZXN0ICsKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAhPSB0b2dnbGUgIiArIGNoZWNrKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxvY2tlZCB2YWx1ZSBjaGFuZ2VkIik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICBpdGVyYXRpb25zKys7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihnZXROYW1lKCkgKyAiIGludGVycnVwdGVkLiIpOworICAgICAgICAgICAgICAgIH0KKworLy8gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGdldE5hbWUoKSArICIgZG9uZSBhZnRlciAiICsKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVyYXRpb25zICsgIiBpdGVyYXRpb25zLiIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZEFuZHJvaWRQYXJzZUludFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRBbmRyb2lkUGFyc2VJbnRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDgzNTFkNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRBbmRyb2lkUGFyc2VJbnRUZXN0LmphdmEKQEAgLTAsMCArMSwxMDggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciBmdW5jdGlvbmFsaXR5IG9mIGNsYXNzIEludGVnZXIgdG8gcGFyc2UgaW50ZWdlcnMuCisgKi8KK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkUGFyc2VJbnRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlSW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBJbnRlZ2VyLnBhcnNlSW50KCIwIiwgMTApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQ3MywgSW50ZWdlci5wYXJzZUludCgiNDczIiwgMTApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIEludGVnZXIucGFyc2VJbnQoIi0wIiwgMTApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0yNTUsIEludGVnZXIucGFyc2VJbnQoIi1GRiIsIDE2KSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMDIsIEludGVnZXIucGFyc2VJbnQoIjExMDAxMTAiLCAyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyMTQ3NDgzNjQ3LCBJbnRlZ2VyLnBhcnNlSW50KCIyMTQ3NDgzNjQ3IiwgMTApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0yMTQ3NDgzNjQ4LCBJbnRlZ2VyLnBhcnNlSW50KCItMjE0NzQ4MzY0OCIsIDEwKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEludGVnZXIucGFyc2VJbnQoIjIxNDc0ODM2NDgiLCAxMCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEludGVnZXIucGFyc2VJbnQoIi0yMTQ3NDgzNjQ5IiwgMTApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgICAgIC8vIE9uZSBkaWdpdCB0b28gbWFueQorICAgICAgICB0cnkgeworICAgICAgICAgICAgSW50ZWdlci5wYXJzZUludCgiMjE0NzQ4MzY0NzAiLCAxMCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEludGVnZXIucGFyc2VJbnQoIi0yMTQ3NDgzNjQ4MCIsIDEwKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW50ZWdlci5wYXJzZUludCgiMjE0NzQ4MzY0NzEiLCAxMCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEludGVnZXIucGFyc2VJbnQoIi0yMTQ3NDgzNjQ4MSIsIDEwKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW50ZWdlci5wYXJzZUludCgiMjE0NzQ4MzY0NzEwIiwgMTApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbnRlZ2VyLnBhcnNlSW50KCItMjE0NzQ4MzY0ODExIiwgMTApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbnRlZ2VyLnBhcnNlSW50KCI5OSIsIDgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbnRlZ2VyLnBhcnNlSW50KCJLb25hIiwgMTApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscyg0MTE3ODcsIEludGVnZXIucGFyc2VJbnQoIktvbmEiLCAyNykpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRBbmRyb2lkU3RyaWN0TWF0aFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRBbmRyb2lkU3RyaWN0TWF0aFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYTYwM2JhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZEFuZHJvaWRTdHJpY3RNYXRoVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjc3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkQW5kcm9pZFN0cmljdE1hdGhUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBmaW5hbCBkb3VibGUgSFlQID0gU3RyaWN0TWF0aC5zcXJ0KDIuMCk7CisKKyAgICBwcml2YXRlIGZpbmFsIGRvdWJsZSBPUFAgPSAxLjA7CisKKyAgICBwcml2YXRlIGZpbmFsIGRvdWJsZSBBREogPSAxLjA7CisKKyAgICAvKiBSZXF1aXJlZCB0byBtYWtlIHByZXZpb3VzIHByZXByb2Nlc3NvciBmbGFncyB3b3JrIC0gZG8gbm90IHJlbW92ZSAqLworICAgIGludCB1bnVzZWQgPSAwOworCisgICAgcHVibGljIHZvaWQgdGVzdEFic0QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBkb3VibGUgamF2YS5sYW5nLlN0cmljdE1hdGguYWJzKGRvdWJsZSkKKworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZG91YmxlIGFicyB2YWx1ZSIsCisgICAgICAgICAgICAgICAgKFN0cmljdE1hdGguYWJzKC0xOTA4Ljg5NzYpID09IDE5MDguODk3NikpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZG91YmxlIGFicyB2YWx1ZSIsCisgICAgICAgICAgICAgICAgKFN0cmljdE1hdGguYWJzKDE5MDguODk3NikgPT0gMTkwOC44OTc2KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFic0YoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBmbG9hdCBqYXZhLmxhbmcuU3RyaWN0TWF0aC5hYnMoZmxvYXQpCisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBmbG9hdCBhYnMgdmFsdWUiLAorICAgICAgICAgICAgICAgIChTdHJpY3RNYXRoLmFicygtMTkwOC44OTc2ZikgPT0gMTkwOC44OTc2ZikpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZmxvYXQgYWJzIHZhbHVlIiwKKyAgICAgICAgICAgICAgICAoU3RyaWN0TWF0aC5hYnMoMTkwOC44OTc2ZikgPT0gMTkwOC44OTc2ZikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBYnNJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEubGFuZy5TdHJpY3RNYXRoLmFicyhpbnQpCisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBpbnQgYWJzIHZhbHVlIiwKKyAgICAgICAgICAgICAgICAoU3RyaWN0TWF0aC5hYnMoLTE5MDg4OTcpID09IDE5MDg4OTcpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGludCBhYnMgdmFsdWUiLAorICAgICAgICAgICAgICAgIChTdHJpY3RNYXRoLmFicygxOTA4ODk3KSA9PSAxOTA4ODk3KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFic0ooKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBsb25nIGphdmEubGFuZy5TdHJpY3RNYXRoLmFicyhsb25nKQorICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgbG9uZyBhYnMgdmFsdWUiLCAoU3RyaWN0TWF0aAorICAgICAgICAgICAgICAgIC5hYnMoLTE5MDg4OTc2MDAwMDg5TCkgPT0gMTkwODg5NzYwMDAwODlMKSk7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBsb25nIGFicyB2YWx1ZSIsCisgICAgICAgICAgICAgICAgKFN0cmljdE1hdGguYWJzKDE5MDg4OTc2MDAwMDg5TCkgPT0gMTkwODg5NzYwMDAwODlMKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFjb3NEKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgZG91YmxlIGphdmEubGFuZy5TdHJpY3RNYXRoLmFjb3MoZG91YmxlKQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgYXJjIGNvc2luZSIsIFN0cmljdE1hdGguY29zKFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAuYWNvcyhBREogLyBIWVApKSA9PSBBREogLyBIWVApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBc2luRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLmxhbmcuU3RyaWN0TWF0aC5hc2luKGRvdWJsZSkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGFyYyBzaW5lIiwgU3RyaWN0TWF0aC5zaW4oU3RyaWN0TWF0aAorICAgICAgICAgICAgICAgIC5hc2luKE9QUCAvIEhZUCkpID09IE9QUCAvIEhZUCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEF0YW5EKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgZG91YmxlIGphdmEubGFuZy5TdHJpY3RNYXRoLmF0YW4oZG91YmxlKQorICAgICAgICBkb3VibGUgYW5zd2VyID0gU3RyaWN0TWF0aC50YW4oU3RyaWN0TWF0aC5hdGFuKDEuMCkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgYXJjIHRhbmdlbnQ6ICIgKyBhbnN3ZXIsIGFuc3dlciA8PSAxLjAKKyAgICAgICAgICAgICAgICAmJiBhbnN3ZXIgPj0gOS45OTk5OTk5OTk5OTk5OTgzRS0xKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXRhbjJERCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLmxhbmcuU3RyaWN0TWF0aC5hdGFuMihkb3VibGUsIGRvdWJsZSkKKyAgICAgICAgZG91YmxlIGFuc3dlciA9IFN0cmljdE1hdGguYXRhbihTdHJpY3RNYXRoLnRhbigxLjApKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGFyYyB0YW5nZW50OiAiICsgYW5zd2VyLCBhbnN3ZXIgPD0gMS4wCisgICAgICAgICAgICAgICAgJiYgYW5zd2VyID49IDkuOTk5OTk5OTk5OTk5OTk4M0UtMSk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoImJveGluZyIpCisgICAgcHVibGljIHZvaWQgdGVzdENicnREKCkgeworICAgICAgICAvLyBUZXN0IGZvciBzcGVjaWFsIHNpdHVhdGlvbnMKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiBEb3VibGUuTmFOIiwgRG91YmxlLmlzTmFOKFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAuY2JydChEb3VibGUuTmFOKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gRG91YmxlLlBPU0lUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAuY2JydChEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSIsCisgICAgICAgICAgICAgICAgRG91YmxlLk5FR0FUSVZFX0lORklOSVRZLCBTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLmNicnQoRG91YmxlLk5FR0FUSVZFX0lORklOSVRZKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuZG91YmxlVG9Mb25nQml0cygwLjApLCBEb3VibGUKKyAgICAgICAgICAgICAgICAuZG91YmxlVG9Mb25nQml0cyhTdHJpY3RNYXRoLmNicnQoMC4wKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoKzAuMCksIERvdWJsZQorICAgICAgICAgICAgICAgIC5kb3VibGVUb0xvbmdCaXRzKFN0cmljdE1hdGguY2JydCgrMC4wKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoLTAuMCksIERvdWJsZQorICAgICAgICAgICAgICAgIC5kb3VibGVUb0xvbmdCaXRzKFN0cmljdE1hdGguY2JydCgtMC4wKSkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiAzLjAiLCAzLjAsIFN0cmljdE1hdGguY2JydCgyNy4wKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiAyMy4xMTE5OTMxNzI1NTg2ODQiLCAyMy4xMTE5OTMxNzI1NTg2ODQsCisgICAgICAgICAgICAgICAgU3RyaWN0TWF0aC5jYnJ0KDEyMzQ1LjYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDUuNjQzODAzMDk0MTIyMzYyRTEwMiIsCisgICAgICAgICAgICAgICAgNS42NDM4MDMwOTQxMjIzNjJFMTAyLCBTdHJpY3RNYXRoLmNicnQoRG91YmxlLk1BWF9WQUxVRSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gMC4wMSIsIDAuMDEsIFN0cmljdE1hdGguY2JydCgwLjAwMDAwMSkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiAtMy4wIiwgLTMuMCwgU3RyaWN0TWF0aC5jYnJ0KC0yNy4wKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiAtMjMuMTExOTkzMTcyNTU4Njg0IiwgLTIzLjExMTk5MzE3MjU1ODY4NCwKKyAgICAgICAgICAgICAgICBTdHJpY3RNYXRoLmNicnQoLTEyMzQ1LjYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDEuNzAzMTgzOTM2MDAzMjYwM0UtMTA4IiwKKyAgICAgICAgICAgICAgICAxLjcwMzE4MzkzNjAwMzI2MDNFLTEwOCwgU3RyaWN0TWF0aC5jYnJ0KERvdWJsZS5NSU5fVkFMVUUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIC0wLjAxIiwgLTAuMDEsIFN0cmljdE1hdGguY2JydCgtMC4wMDAwMDEpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaWN0TWF0aC5jYnJ0KChEb3VibGUpIG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDZWlsRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLmxhbmcuU3RyaWN0TWF0aC5jZWlsKGRvdWJsZSkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgY2VpbGluZyBmb3IgZG91YmxlIiwKKyAgICAgICAgICAgICAgICA3OSwgU3RyaWN0TWF0aC5jZWlsKDc4Ljg5KSwgMC4wKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgY2VpbGluZyBmb3IgZG91YmxlIiwKKyAgICAgICAgICAgICAgICAtNzgsIFN0cmljdE1hdGguY2VpbCgtNzguODkpLCAwLjApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb3NEKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgZG91YmxlIGphdmEubGFuZy5TdHJpY3RNYXRoLmNvcyhkb3VibGUpCisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGNvc2luZSIsIFN0cmljdE1hdGguY29zKFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAuYWNvcyhBREogLyBIWVApKSA9PSBBREogLyBIWVApOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJib3hpbmciKQorICAgIHB1YmxpYyB2b2lkIHRlc3RDb3NoX0QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIHNwZWNpYWwgc2l0dWF0aW9ucworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIE5hTiIsIERvdWJsZS5pc05hTihTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLmNvc2goRG91YmxlLk5hTikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIFBPU0lUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAuY29zaChEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIFBPU0lUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAuY29zaChEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDEuMCIsIDEuMCwgU3RyaWN0TWF0aC5jb3NoKCswLjApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDEuMCIsIDEuMCwgU3RyaWN0TWF0aC5jb3NoKC0wLjApKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgU3RyaWN0TWF0aC5jb3NoKDEyMzQuNTYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIFBPU0lUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIFN0cmljdE1hdGguY29zaCgtMTIzNC41NikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gMS4wMDAwMDAwMDAwMDA1IiwgMS4wMDAwMDAwMDAwMDA1LAorICAgICAgICAgICAgICAgIFN0cmljdE1hdGguY29zaCgwLjAwMDAwMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gMS4wMDAwMDAwMDAwMDA1IiwgMS4wMDAwMDAwMDAwMDA1LAorICAgICAgICAgICAgICAgIFN0cmljdE1hdGguY29zaCgtMC4wMDAwMDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDUuMjEyMjE0MzUxOTQ1NTk4IiwgNS4yMTIyMTQzNTE5NDU1OTgsCisgICAgICAgICAgICAgICAgU3RyaWN0TWF0aC5jb3NoKDIuMzM0ODIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgU3RyaWN0TWF0aC5jb3NoKERvdWJsZS5NQVhfVkFMVUUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDEuMCIsIDEuMCwgU3RyaWN0TWF0aAorICAgICAgICAgICAgICAgIC5jb3NoKERvdWJsZS5NSU5fVkFMVUUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXhwRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLmxhbmcuU3RyaWN0TWF0aC5leHAoZG91YmxlKQorICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgYW5zd2VyIHJldHVybmVkIGZvciBzaW1wbGUgcG93ZXIiLCBTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLmFicyhTdHJpY3RNYXRoLmV4cCg0RCkgLSBTdHJpY3RNYXRoLkUgKiBTdHJpY3RNYXRoLkUKKyAgICAgICAgICAgICAgICAgICAgICAgICogU3RyaWN0TWF0aC5FICogU3RyaWN0TWF0aC5FKSA8IDAuMUQpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgYW5zd2VyIHJldHVybmVkIGZvciBsYXJnZXIgcG93ZXIiLCBTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLmxvZyhTdHJpY3RNYXRoLmFicyhTdHJpY3RNYXRoLmV4cCg1LjVEKSkgLSA1LjVEKSA8IDEwLjBEKTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiYm94aW5nIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXhwbTFEKCkgeworICAgICAgICAvL1Rlc3QgZm9yIHNwZWNpYWwgY2FzZXMKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiBOYU4iLCBEb3VibGUuaXNOYU4oU3RyaWN0TWF0aC5leHBtMShEb3VibGUuTmFOKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgU3RyaWN0TWF0aC5leHBtMShEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIC0xLjAiLCAtMS4wLCBTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLmV4cG0xKERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoMC4wKSwgRG91YmxlCisgICAgICAgICAgICAgICAgLmRvdWJsZVRvTG9uZ0JpdHMoU3RyaWN0TWF0aC5leHBtMSgwLjApKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuZG91YmxlVG9Mb25nQml0cygrMC4wKSwgRG91YmxlCisgICAgICAgICAgICAgICAgLmRvdWJsZVRvTG9uZ0JpdHMoU3RyaWN0TWF0aC5leHBtMSgrMC4wKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoLTAuMCksIERvdWJsZQorICAgICAgICAgICAgICAgIC5kb3VibGVUb0xvbmdCaXRzKFN0cmljdE1hdGguZXhwbTEoLTAuMCkpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gLTkuOTk5OTUwMDAwMTY2NjY2RS02IiwKKyAgICAgICAgICAgICAgICAtOS45OTk5NTAwMDAxNjY2NjZFLTYsIFN0cmljdE1hdGguZXhwbTEoLTAuMDAwMDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDEuMDE0NTEwMzA3NDQ2OTYzNUU2MCIsCisgICAgICAgICAgICAgICAgMS4wMTQ1MTAzMDc0NDY5NjM1RTYwLCBTdHJpY3RNYXRoLmV4cG0xKDEzOC4xNjk1MTE2MikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgU3RyaWN0TWF0aAorICAgICAgICAgICAgICAgIC5leHBtMSgxMjM0NTY3ODkxMjM0NTY3ODkxMjM0NTY3ODkuNDUyMTU4NDIyMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgU3RyaWN0TWF0aC5leHBtMShEb3VibGUuTUFYX1ZBTFVFKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiBNSU5fVkFMVUUiLCBEb3VibGUuTUlOX1ZBTFVFLCBTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLmV4cG0xKERvdWJsZS5NSU5fVkFMVUUpKTsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGbG9vckQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBkb3VibGUgamF2YS5sYW5nLlN0cmljdE1hdGguZmxvb3IoZG91YmxlKQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBmbG9vciBmb3IgZG91YmxlIiwKKyAgICAgICAgICAgICAgICA3OCwgU3RyaWN0TWF0aC5mbG9vcig3OC44OSksIDAuMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGZsb29yIGZvciBkb3VibGUiLAorICAgICAgICAgICAgICAgIC03OSwgU3RyaWN0TWF0aC5mbG9vcigtNzguODkpLCAwLjApOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJib3hpbmciKQorICAgIHB1YmxpYyB2b2lkIHRlc3RIeXBvdEREKCkgeworICAgICAgICAvLyBUZXN0IGZvciBzcGVjaWFsIGNhc2VzCisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiBQT1NJVElWRV9JTkZJTklUWSIsCisgICAgICAgICAgICAgICAgRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCBTdHJpY3RNYXRoLmh5cG90KERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwKKyAgICAgICAgICAgICAgICAxLjApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIFBPU0lUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIFN0cmljdE1hdGguaHlwb3QoRG91YmxlLk5FR0FUSVZFX0lORklOSVRZLAorICAgICAgICAgICAgICAgIDEyMy4zMjQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIFBPU0lUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIFN0cmljdE1hdGguaHlwb3QoLTc1OC4yNTg3LAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgU3RyaWN0TWF0aC5oeXBvdCg1Njg3LjIxLAorICAgICAgICAgICAgICAgIERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgU3RyaWN0TWF0aC5oeXBvdChEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksCisgICAgICAgICAgICAgICAgRG91YmxlLk5FR0FUSVZFX0lORklOSVRZKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiBQT1NJVElWRV9JTkZJTklUWSIsCisgICAgICAgICAgICAgICAgRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCBTdHJpY3RNYXRoLmh5cG90KERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSwKKyAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiBOYU4iLCBEb3VibGUuaXNOYU4oU3RyaWN0TWF0aC5oeXBvdChEb3VibGUuTmFOLAorICAgICAgICAgICAgICAgIDIzNDIzMDEuODk4NDMpKSk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCByZXR1cm4gTmFOIiwgRG91YmxlLmlzTmFOKFN0cmljdE1hdGguaHlwb3QoLTM0NS4yNjgwLAorICAgICAgICAgICAgICAgIERvdWJsZS5OYU4pKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDIzOTY0MjQuOTA1NDE2Njk3IiwgMjM5NjQyNC45MDU0MTY2OTcsIFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAuaHlwb3QoMTIzMjIuMTIsIC0yMzk2MzkzLjIyNTgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDEzOC4xNjk1ODA3MDU1ODU1NiIsIDEzOC4xNjk1ODA3MDU1ODU1NiwKKyAgICAgICAgICAgICAgICBTdHJpY3RNYXRoLmh5cG90KC0xMzguMTY5NTExNjIsIDAuMTM4MTcwMzU4NjQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDEuNzk3NjkzMTM0ODYyMzE1N0UzMDgiLAorICAgICAgICAgICAgICAgIDEuNzk3NjkzMTM0ODYyMzE1N0UzMDgsIFN0cmljdE1hdGguaHlwb3QoRG91YmxlLk1BWF9WQUxVRSwgMjExMzcwLjM1KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiA1NDEzLjcxODUiLCA1NDEzLjcxODUsIFN0cmljdE1hdGguaHlwb3QoCisgICAgICAgICAgICAgICAgLTU0MTMuNzE4NSwgRG91YmxlLk1JTl9WQUxVRSkpOworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdElFRUVyZW1haW5kZXJERCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLmxhbmcuU3RyaWN0TWF0aC5JRUVFcmVtYWluZGVyKGRvdWJsZSwKKyAgICAgICAgLy8gZG91YmxlKQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCByZW1haW5kZXIgcmV0dXJuZWQiLCAwLjAsIFN0cmljdE1hdGguSUVFRXJlbWFpbmRlcigKKyAgICAgICAgICAgICAgICAxLjAsIDEuMCksIDAuMCk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIkluY29ycmVjdCByZW1haW5kZXIgcmV0dXJuZWQiLAorICAgICAgICAgICAgICAgIFN0cmljdE1hdGguSUVFRXJlbWFpbmRlcigxLjMyLCA4OS43NjUpID49IDEuNDcwNTA2MzIyMDYzMTY0N0UtMgorICAgICAgICAgICAgICAgICAgICAgICAgfHwgU3RyaWN0TWF0aC5JRUVFcmVtYWluZGVyKDEuMzIsIDg5Ljc2NSkgPj0gMS40NzA1MDYzMjIwNjMxNjQ5RS0yKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9nRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLmxhbmcuU3RyaWN0TWF0aC5sb2coZG91YmxlKQorICAgICAgICBmb3IgKGRvdWJsZSBkID0gMTA7IGQgPj0gLTEwOyBkIC09IDAuNSkgeworICAgICAgICAgICAgZG91YmxlIGFuc3dlciA9IFN0cmljdE1hdGgubG9nKFN0cmljdE1hdGguZXhwKGQpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFuc3dlciBkb2VzIG5vdCBlcXVhbCBleHBlY3RlZCBhbnN3ZXIgZm9yIGQgPSAiICsgZAorICAgICAgICAgICAgICAgICAgICArICIgYW5zd2VyID0gIiArIGFuc3dlciwKKyAgICAgICAgICAgICAgICAgICAgU3RyaWN0TWF0aC5hYnMoYW5zd2VyIC0gZCkgPD0gU3RyaWN0TWF0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hYnMoZCAqIDAuMDAwMDAwMDEpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJib3hpbmciKQorICAgIHB1YmxpYyB2b2lkIHRlc3RMb2cxMEQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIHNwZWNpYWwgY2FzZXMKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiBOYU4iLCBEb3VibGUuaXNOYU4oU3RyaWN0TWF0aAorICAgICAgICAgICAgICAgIC5sb2cxMChEb3VibGUuTmFOKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIE5hTiIsIERvdWJsZS5pc05hTihTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLmxvZzEwKC0yNTQxLjA1NzQ1Njg3MjM0MTg3NTMyKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgU3RyaWN0TWF0aAorICAgICAgICAgICAgICAgIC5sb2cxMChEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIE5FR0FUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFksIFN0cmljdE1hdGgubG9nMTAoMC4wKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiBORUdBVElWRV9JTkZJTklUWSIsCisgICAgICAgICAgICAgICAgRG91YmxlLk5FR0FUSVZFX0lORklOSVRZLCBTdHJpY3RNYXRoLmxvZzEwKCswLjApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIE5FR0FUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFksIFN0cmljdE1hdGgubG9nMTAoLTAuMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gMTQuMCIsIDE0LjAsIFN0cmljdE1hdGgubG9nMTAoU3RyaWN0TWF0aAorICAgICAgICAgICAgICAgIC5wb3coMTAsIDE0KSkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiAzLjczODk1NjEyNjk1NDA0MDYiLCAzLjczODk1NjEyNjk1NDA0MDYsCisgICAgICAgICAgICAgICAgU3RyaWN0TWF0aC5sb2cxMCg1NDgyLjIxNTgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDE0LjY2MTU1MTE0Mjg5MzgzMyIsIDE0LjY2MTU1MTE0Mjg5MzgzMywKKyAgICAgICAgICAgICAgICBTdHJpY3RNYXRoLmxvZzEwKDQ1ODcyMzY2MjMxMjg3Mi4xMjU3ODIzMzI1ODcpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIC0wLjkwODM4Mjg2MjIxOTIzMzQiLCAtMC45MDgzODI4NjIyMTkyMzM0LAorICAgICAgICAgICAgICAgIFN0cmljdE1hdGgubG9nMTAoMC4xMjM0ODU4MzM1ODg3MSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gMzA4LjI1NDcxNTU1OTkxNjc1IiwgMzA4LjI1NDcxNTU1OTkxNjc1LAorICAgICAgICAgICAgICAgIFN0cmljdE1hdGgubG9nMTAoRG91YmxlLk1BWF9WQUxVRSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gLTMyMy4zMDYyMTUzNDMxMTU4IiwgLTMyMy4zMDYyMTUzNDMxMTU4LAorICAgICAgICAgICAgICAgIFN0cmljdE1hdGgubG9nMTAoRG91YmxlLk1JTl9WQUxVRSkpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJib3hpbmciKQorICAgIHB1YmxpYyB2b2lkIHRlc3RMb2cxcEQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIHNwZWNpYWwgY2FzZXMKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiBOYU4iLCBEb3VibGUuaXNOYU4oU3RyaWN0TWF0aAorICAgICAgICAgICAgICAgIC5sb2cxcChEb3VibGUuTmFOKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIE5hTiIsIERvdWJsZS5pc05hTihTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLmxvZzFwKC0zMi4wNDgyMTc1KSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgU3RyaWN0TWF0aAorICAgICAgICAgICAgICAgIC5sb2cxcChEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKDAuMCksIERvdWJsZQorICAgICAgICAgICAgICAgIC5kb3VibGVUb0xvbmdCaXRzKFN0cmljdE1hdGgubG9nMXAoMC4wKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoKzAuMCksIERvdWJsZQorICAgICAgICAgICAgICAgIC5kb3VibGVUb0xvbmdCaXRzKFN0cmljdE1hdGgubG9nMXAoKzAuMCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKC0wLjApLCBEb3VibGUKKyAgICAgICAgICAgICAgICAuZG91YmxlVG9Mb25nQml0cyhTdHJpY3RNYXRoLmxvZzFwKC0wLjApKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIC0wLjI5NDE3ODIyOTUzMTI1NDEiLCAtMC4yOTQxNzgyMjk1MzEyNTQxLAorICAgICAgICAgICAgICAgIFN0cmljdE1hdGgubG9nMXAoLTAuMjU0ODU2MzI3KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiA3LjM2ODA1MDY4NTU2NDE1MSIsIDcuMzY4MDUwNjg1NTY0MTUxLAorICAgICAgICAgICAgICAgIFN0cmljdE1hdGgubG9nMXAoMTU4My41NDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDAuNDYzMzcwODY4NTQwOTkyMSIsIDAuNDYzMzcwODY4NTQwOTkyMSwKKyAgICAgICAgICAgICAgICBTdHJpY3RNYXRoLmxvZzFwKDAuNTg5NDIyNykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gNzA5Ljc4MjcxMjg5MzM4NCIsIDcwOS43ODI3MTI4OTMzODQsCisgICAgICAgICAgICAgICAgU3RyaWN0TWF0aC5sb2cxcChEb3VibGUuTUFYX1ZBTFVFKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiBEb3VibGUuTUlOX1ZBTFVFIiwgRG91YmxlLk1JTl9WQUxVRSwKKyAgICAgICAgICAgICAgICBTdHJpY3RNYXRoLmxvZzFwKERvdWJsZS5NSU5fVkFMVUUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF4REQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBkb3VibGUgamF2YS5sYW5nLlN0cmljdE1hdGgubWF4KGRvdWJsZSwgZG91YmxlKQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBkb3VibGUgbWF4IHZhbHVlIiwgMTkwODg5Ny42MDAwMDg5LCBTdHJpY3RNYXRoLm1heCgKKyAgICAgICAgICAgICAgICAtMTkwODg5Ny42MDAwMDg5LCAxOTA4ODk3LjYwMDAwODkpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRvdWJsZSBtYXggdmFsdWUiLCAxOTA4ODk3LjYwMDAwODksIFN0cmljdE1hdGgubWF4KDIuMCwKKyAgICAgICAgICAgICAgICAxOTA4ODk3LjYwMDAwODkpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRvdWJsZSBtYXggdmFsdWUiLCAtMi4wLCBTdHJpY3RNYXRoLm1heCgtMi4wLAorICAgICAgICAgICAgICAgIC0xOTA4ODk3LjYwMDAwODkpLCAwRCk7CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF4RkYoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBmbG9hdCBqYXZhLmxhbmcuU3RyaWN0TWF0aC5tYXgoZmxvYXQsIGZsb2F0KQorICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZmxvYXQgbWF4IHZhbHVlIiwgU3RyaWN0TWF0aC5tYXgoLTE5MDg4OTcuNjAwZiwKKyAgICAgICAgICAgICAgICAxOTA4ODk3LjYwMGYpID09IDE5MDg4OTcuNjAwZik7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBmbG9hdCBtYXggdmFsdWUiLCBTdHJpY3RNYXRoLm1heCgyLjBmLAorICAgICAgICAgICAgICAgIDE5MDg4OTcuNjAwZikgPT0gMTkwODg5Ny42MDBmKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGZsb2F0IG1heCB2YWx1ZSIsIFN0cmljdE1hdGgubWF4KC0yLjBmLAorICAgICAgICAgICAgICAgIC0xOTA4ODk3LjYwMGYpID09IC0yLjBmKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF4SUkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS5sYW5nLlN0cmljdE1hdGgubWF4KGludCwgaW50KQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBpbnQgbWF4IHZhbHVlIiwgMTkwODg5NzYsIFN0cmljdE1hdGgubWF4KC0xOTA4ODk3NiwKKyAgICAgICAgICAgICAgICAxOTA4ODk3NikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBpbnQgbWF4IHZhbHVlIiwKKyAgICAgICAgICAgICAgICAxOTA4ODk3NiwgU3RyaWN0TWF0aC5tYXgoMjAsIDE5MDg4OTc2KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGludCBtYXggdmFsdWUiLAorICAgICAgICAgICAgICAgIC0yMCwgU3RyaWN0TWF0aC5tYXgoLTIwLCAtMTkwODg5NzYpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF4SkooKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBsb25nIGphdmEubGFuZy5TdHJpY3RNYXRoLm1heChsb25nLCBsb25nKQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBsb25nIG1heCB2YWx1ZSIsIDE5MDg4OTc2MDAwMDg5TCwgU3RyaWN0TWF0aC5tYXgoLTE5MDg4OTc2MDAwMDg5TCwKKyAgICAgICAgICAgICAgICAxOTA4ODk3NjAwMDA4OUwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbG9uZyBtYXggdmFsdWUiLCAxOTA4ODk3NjAwMDA4OUwsIFN0cmljdE1hdGgubWF4KDIwLAorICAgICAgICAgICAgICAgIDE5MDg4OTc2MDAwMDg5TCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBsb25nIG1heCB2YWx1ZSIsIC0yMCwgU3RyaWN0TWF0aC5tYXgoLTIwLAorICAgICAgICAgICAgICAgIC0xOTA4ODk3NjAwMDA4OUwpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWluREQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBkb3VibGUgamF2YS5sYW5nLlN0cmljdE1hdGgubWluKGRvdWJsZSwgZG91YmxlKQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBkb3VibGUgbWluIHZhbHVlIiwgLTE5MDg4OTcuNjAwMDA4OSwgU3RyaWN0TWF0aC5taW4oCisgICAgICAgICAgICAgICAgLTE5MDg4OTcuNjAwMDA4OSwgMTkwODg5Ny42MDAwMDg5KSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBkb3VibGUgbWluIHZhbHVlIiwgMi4wLCBTdHJpY3RNYXRoLm1pbigyLjAsCisgICAgICAgICAgICAgICAgMTkwODg5Ny42MDAwMDg5KSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBkb3VibGUgbWluIHZhbHVlIiwgLTE5MDg4OTcuNjAwMDA4OSwgU3RyaWN0TWF0aC5taW4oLTIuMCwKKyAgICAgICAgICAgICAgICAtMTkwODg5Ny42MDAwMDg5KSwgMEQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNaW5GRigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGZsb2F0IGphdmEubGFuZy5TdHJpY3RNYXRoLm1pbihmbG9hdCwgZmxvYXQpCisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBmbG9hdCBtaW4gdmFsdWUiLCBTdHJpY3RNYXRoLm1pbigtMTkwODg5Ny42MDBmLAorICAgICAgICAgICAgICAgIDE5MDg4OTcuNjAwZikgPT0gLTE5MDg4OTcuNjAwZik7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBmbG9hdCBtaW4gdmFsdWUiLCBTdHJpY3RNYXRoLm1pbigyLjBmLAorICAgICAgICAgICAgICAgIDE5MDg4OTcuNjAwZikgPT0gMi4wZik7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBmbG9hdCBtaW4gdmFsdWUiLCBTdHJpY3RNYXRoLm1pbigtMi4wZiwKKyAgICAgICAgICAgICAgICAtMTkwODg5Ny42MDBmKSA9PSAtMTkwODg5Ny42MDBmKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWluSUkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS5sYW5nLlN0cmljdE1hdGgubWluKGludCwgaW50KQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBpbnQgbWluIHZhbHVlIiwgLTE5MDg4OTc2LCBTdHJpY3RNYXRoLm1pbigtMTkwODg5NzYsCisgICAgICAgICAgICAgICAgMTkwODg5NzYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgaW50IG1pbiB2YWx1ZSIsCisgICAgICAgICAgICAgICAgMjAsIFN0cmljdE1hdGgubWluKDIwLCAxOTA4ODk3NikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBpbnQgbWluIHZhbHVlIiwKKyAgICAgICAgICAgICAgICAtMTkwODg5NzYsIFN0cmljdE1hdGgubWluKC0yMCwgLTE5MDg4OTc2KSk7CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWluSkooKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBsb25nIGphdmEubGFuZy5TdHJpY3RNYXRoLm1pbihsb25nLCBsb25nKQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBsb25nIG1pbiB2YWx1ZSIsIC0xOTA4ODk3NjAwMDA4OUwsIFN0cmljdE1hdGgubWluKC0xOTA4ODk3NjAwMDA4OUwsCisgICAgICAgICAgICAgICAgMTkwODg5NzYwMDAwODlMKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGxvbmcgbWluIHZhbHVlIiwgMjAsIFN0cmljdE1hdGgubWluKDIwLAorICAgICAgICAgICAgICAgIDE5MDg4OTc2MDAwMDg5TCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBsb25nIG1pbiB2YWx1ZSIsIC0xOTA4ODk3NjAwMDA4OUwsIFN0cmljdE1hdGgubWluKC0yMCwKKyAgICAgICAgICAgICAgICAtMTkwODg5NzYwMDAwODlMKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBvd0REKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgZG91YmxlIGphdmEubGFuZy5TdHJpY3RNYXRoLnBvdyhkb3VibGUsIGRvdWJsZSkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgicG93IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgKGxvbmcpIFN0cmljdE1hdGgucG93KDIsIDgpID09IDI1NmwpOworICAgICAgICBhc3NlcnRUcnVlKCJwb3cgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwKKyAgICAgICAgICAgICAgICBTdHJpY3RNYXRoLnBvdygyLCAtOCkgPT0gMC4wMDM5MDYyNWQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSaW50RCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLmxhbmcuU3RyaWN0TWF0aC5yaW50KGRvdWJsZSkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gcm91bmQgcHJvcGVybHkgLSB1cCB0byBvZGQiLAorICAgICAgICAgICAgICAgIDMuMCwgU3RyaWN0TWF0aC5yaW50KDIuOSksIDBEKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIHJvdW5kIHByb3Blcmx5IC0gTmFOIiwgRG91YmxlLmlzTmFOKFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAucmludChEb3VibGUuTmFOKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCB0byByb3VuZCBwcm9wZXJseSBkb3duICB0byBldmVuIiwgMi4wLCBTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLnJpbnQoMi4xKSwgMEQpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gcm91bmQgcHJvcGVybHkgIiArIDIuNSArICIgdG8gZXZlbiIsIFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAucmludCgyLjUpID09IDIuMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJvdW5kRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGxvbmcgamF2YS5sYW5nLlN0cmljdE1hdGgucm91bmQoZG91YmxlKQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCByb3VuZGluZyBvZiBhIGZsb2F0IiwKKyAgICAgICAgICAgICAgICAtOTEsIFN0cmljdE1hdGgucm91bmQoLTkwLjg5ZCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSb3VuZEYoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS5sYW5nLlN0cmljdE1hdGgucm91bmQoZmxvYXQpCisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHJvdW5kaW5nIG9mIGEgZmxvYXQiLAorICAgICAgICAgICAgICAgIC05MSwgU3RyaWN0TWF0aC5yb3VuZCgtOTAuODlmKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNpZ251bUQoKSB7CisgICAgICAgIGFzc2VydFRydWUoRG91YmxlLmlzTmFOKFN0cmljdE1hdGguc2lnbnVtKERvdWJsZS5OYU4pKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuZG91YmxlVG9Mb25nQml0cygwLjApLCBEb3VibGUKKyAgICAgICAgICAgICAgICAuZG91YmxlVG9Mb25nQml0cyhTdHJpY3RNYXRoLnNpZ251bSgwLjApKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuZG91YmxlVG9Mb25nQml0cygrMC4wKSwgRG91YmxlCisgICAgICAgICAgICAgICAgLmRvdWJsZVRvTG9uZ0JpdHMoU3RyaWN0TWF0aC5zaWdudW0oKzAuMCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKC0wLjApLCBEb3VibGUKKyAgICAgICAgICAgICAgICAuZG91YmxlVG9Mb25nQml0cyhTdHJpY3RNYXRoLnNpZ251bSgtMC4wKSkpOworCisgICAgICAgIGFzc2VydEVxdWFscygxLjAsIFN0cmljdE1hdGguc2lnbnVtKDI1MzY4MS4yMTg3OTYyKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEuMCwgU3RyaWN0TWF0aC5zaWdudW0oLTEyNTg3NDY5My41NiksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMCwgU3RyaWN0TWF0aC5zaWdudW0oMS4yNTg3RS0zMDgpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygtMS4wLCBTdHJpY3RNYXRoLnNpZ251bSgtMS4yNTg3RS0zMDgpLCAwRCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMCwgU3RyaWN0TWF0aC5zaWdudW0oRG91YmxlLk1BWF9WQUxVRSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMCwgU3RyaWN0TWF0aC5zaWdudW0oRG91YmxlLk1JTl9WQUxVRSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLjAsIFN0cmljdE1hdGguc2lnbnVtKC1Eb3VibGUuTUFYX1ZBTFVFKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEuMCwgU3RyaWN0TWF0aC5zaWdudW0oLURvdWJsZS5NSU5fVkFMVUUpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLjAsIFN0cmljdE1hdGguc2lnbnVtKERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLjAsIFN0cmljdE1hdGguc2lnbnVtKERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSksIDBEKTsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTaWdudW1GKCkgeworICAgICAgICBhc3NlcnRUcnVlKEZsb2F0LmlzTmFOKFN0cmljdE1hdGguc2lnbnVtKEZsb2F0Lk5hTikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEZsb2F0LmZsb2F0VG9JbnRCaXRzKDAuMGYpLCBGbG9hdAorICAgICAgICAgICAgICAgIC5mbG9hdFRvSW50Qml0cyhTdHJpY3RNYXRoLnNpZ251bSgwLjBmKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRmxvYXQuZmxvYXRUb0ludEJpdHMoKzAuMGYpLCBGbG9hdAorICAgICAgICAgICAgICAgIC5mbG9hdFRvSW50Qml0cyhTdHJpY3RNYXRoLnNpZ251bSgrMC4wZikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEZsb2F0LmZsb2F0VG9JbnRCaXRzKC0wLjBmKSwgRmxvYXQKKyAgICAgICAgICAgICAgICAuZmxvYXRUb0ludEJpdHMoU3RyaWN0TWF0aC5zaWdudW0oLTAuMGYpKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMGYsIFN0cmljdE1hdGguc2lnbnVtKDI1MzY4MS4yMTg3OTYyZiksIDBmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLjBmLCBTdHJpY3RNYXRoLnNpZ251bSgtMTI1ODc0NjkzLjU2ZiksIDBmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMGYsIFN0cmljdE1hdGguc2lnbnVtKDEuMjU4N0UtMTFmKSwgMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEuMGYsIFN0cmljdE1hdGguc2lnbnVtKC0xLjI1ODdFLTExZiksIDBmKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMS4wZiwgU3RyaWN0TWF0aC5zaWdudW0oRmxvYXQuTUFYX1ZBTFVFKSwgMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoMS4wZiwgU3RyaWN0TWF0aC5zaWdudW0oRmxvYXQuTUlOX1ZBTFVFKSwgMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEuMGYsIFN0cmljdE1hdGguc2lnbnVtKC1GbG9hdC5NQVhfVkFMVUUpLCAwZik7CisgICAgICAgIGFzc2VydEVxdWFscygtMS4wZiwgU3RyaWN0TWF0aC5zaWdudW0oLUZsb2F0Lk1JTl9WQUxVRSksIDBmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMGYsIFN0cmljdE1hdGguc2lnbnVtKEZsb2F0LlBPU0lUSVZFX0lORklOSVRZKSwgMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEuMGYsIFN0cmljdE1hdGguc2lnbnVtKEZsb2F0Lk5FR0FUSVZFX0lORklOSVRZKSwgMGYpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTaW5EKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgZG91YmxlIGphdmEubGFuZy5TdHJpY3RNYXRoLnNpbihkb3VibGUpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBzaW5lIiwgU3RyaWN0TWF0aC5zaW4oU3RyaWN0TWF0aAorICAgICAgICAgICAgICAgIC5hc2luKE9QUCAvIEhZUCkpID09IE9QUCAvIEhZUCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNpbmhEKCkgeworICAgICAgICAvLyBUZXN0IGZvciBzcGVjaWFsIHNpdHVhdGlvbnMKKyAgICAgICAgYXNzZXJ0VHJ1ZShEb3VibGUuaXNOYU4oU3RyaWN0TWF0aC5zaW5oKERvdWJsZS5OYU4pKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiBQT1NJVElWRV9JTkZJTklUWSIsCisgICAgICAgICAgICAgICAgRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCBTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLnNpbmgoRG91YmxlLlBPU0lUSVZFX0lORklOSVRZKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gTkVHQVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSwgU3RyaWN0TWF0aAorICAgICAgICAgICAgICAgIC5zaW5oKERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKDAuMCksIERvdWJsZQorICAgICAgICAgICAgICAgIC5kb3VibGVUb0xvbmdCaXRzKFN0cmljdE1hdGguc2luaCgwLjApKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuZG91YmxlVG9Mb25nQml0cygrMC4wKSwgRG91YmxlCisgICAgICAgICAgICAgICAgLmRvdWJsZVRvTG9uZ0JpdHMoU3RyaWN0TWF0aC5zaW5oKCswLjApKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuZG91YmxlVG9Mb25nQml0cygtMC4wKSwgRG91YmxlCisgICAgICAgICAgICAgICAgLmRvdWJsZVRvTG9uZ0JpdHMoU3RyaWN0TWF0aC5zaW5oKC0wLjApKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIFBPU0lUSVZFX0lORklOSVRZIiwKKyAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIFN0cmljdE1hdGguc2luaCgxMjM0LjU2KSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gTkVHQVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSwgU3RyaWN0TWF0aC5zaW5oKC0xMjM0LjU2KSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gMS4wMDAwMDAwMDAwMDAxNjY2RS02IiwKKyAgICAgICAgICAgICAgICAxLjAwMDAwMDAwMDAwMDE2NjZFLTYsIFN0cmljdE1hdGguc2luaCgwLjAwMDAwMSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIC0xLjAwMDAwMDAwMDAwMDE2NjZFLTYiLAorICAgICAgICAgICAgICAgIC0xLjAwMDAwMDAwMDAwMDE2NjZFLTYsIFN0cmljdE1hdGguc2luaCgtMC4wMDAwMDEpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiA1LjExNTM4NjQ0MTk2Mzg1OSIsIDUuMTE1Mzg2NDQxOTYzODU5LAorICAgICAgICAgICAgICAgIFN0cmljdE1hdGguc2luaCgyLjMzNDgyKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gUE9TSVRJVkVfSU5GSU5JVFkiLAorICAgICAgICAgICAgICAgIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwgU3RyaWN0TWF0aC5zaW5oKERvdWJsZS5NQVhfVkFMVUUpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiA0LjlFLTMyNCIsIDQuOUUtMzI0LCBTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLnNpbmgoRG91YmxlLk1JTl9WQUxVRSksIDBEKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3FydEQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBkb3VibGUgamF2YS5sYW5nLlN0cmljdE1hdGguc3FydChkb3VibGUpCisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHJvb3QgcmV0dXJuZWQxIiwKKyAgICAgICAgICAgICAgICAyLCBTdHJpY3RNYXRoLnNxcnQoU3RyaWN0TWF0aC5wb3coU3RyaWN0TWF0aC5zcXJ0KDIpLCA0KSksIDAuMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHJvb3QgcmV0dXJuZWQyIiwgNywgU3RyaWN0TWF0aC5zcXJ0KDQ5KSwgMC4wKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VGFuRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLmxhbmcuU3RyaWN0TWF0aC50YW4oZG91YmxlKQorICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJSZXR1cm5lZCBpbmNvcnJlY3QgdGFuZ2VudDogIiwKKyAgICAgICAgICAgICAgICBTdHJpY3RNYXRoLnRhbihTdHJpY3RNYXRoLmF0YW4oMS4wKSkgPD0gMS4wCisgICAgICAgICAgICAgICAgICAgICAgICB8fCBTdHJpY3RNYXRoLnRhbihTdHJpY3RNYXRoLmF0YW4oMS4wKSkgPj0gOS45OTk5OTk5OTk5OTk5OTgzRS0xKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VGFuaEQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIHNwZWNpYWwgc2l0dWF0aW9ucworICAgICAgICBhc3NlcnRUcnVlKERvdWJsZS5pc05hTihTdHJpY3RNYXRoLnRhbmgoRG91YmxlLk5hTikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuICsxLjAiLCArMS4wLCBTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLnRhbmgoRG91YmxlLlBPU0lUSVZFX0lORklOSVRZKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gLTEuMCIsIC0xLjAsIFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAudGFuaChEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuZG91YmxlVG9Mb25nQml0cygwLjApLCBEb3VibGUKKyAgICAgICAgICAgICAgICAuZG91YmxlVG9Mb25nQml0cyhTdHJpY3RNYXRoLnRhbmgoMC4wKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoKzAuMCksIERvdWJsZQorICAgICAgICAgICAgICAgIC5kb3VibGVUb0xvbmdCaXRzKFN0cmljdE1hdGgudGFuaCgrMC4wKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoLTAuMCksIERvdWJsZQorICAgICAgICAgICAgICAgIC5kb3VibGVUb0xvbmdCaXRzKFN0cmljdE1hdGgudGFuaCgtMC4wKSkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiAxLjAiLCAxLjAsIFN0cmljdE1hdGgudGFuaCgxMjM0LjU2KSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gLTEuMCIsIC0xLjAsIFN0cmljdE1hdGgudGFuaCgtMTIzNC41NiksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDkuOTk5OTk5OTk5OTk2NjY2RS03IiwKKyAgICAgICAgICAgICAgICA5Ljk5OTk5OTk5OTk5NjY2NkUtNywgU3RyaWN0TWF0aC50YW5oKDAuMDAwMDAxKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gMC45ODE0MjI4ODQxMjQ5NDEiLCAwLjk4MTQyMjg4NDEyNDk0MSwKKyAgICAgICAgICAgICAgICBTdHJpY3RNYXRoLnRhbmgoMi4zMzQ4MiksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgcmV0dXJuIDEuMCIsIDEuMCwgU3RyaWN0TWF0aAorICAgICAgICAgICAgICAgIC50YW5oKERvdWJsZS5NQVhfVkFMVUUpLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiA0LjlFLTMyNCIsIDQuOUUtMzI0LCBTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLnRhbmgoRG91YmxlLk1JTl9WQUxVRSksIDBEKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmFuZG9tKCkgeworICAgICAgICAvLyBUaGVyZSBpc24ndCBhIHBsYWNlIGZvciB0aGVzZSB0ZXN0cyBzbyBqdXN0IHN0aWNrIHRoZW0gaGVyZQorICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIEUiLAorICAgICAgICAgICAgICAgIDQ2MTMzMDM0NDUzMTQ4ODU0ODFMLCBEb3VibGUuZG91YmxlVG9Mb25nQml0cyhTdHJpY3RNYXRoLkUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSBQSSIsCisgICAgICAgICAgICAgICAgNDYxNDI1NjY1NjU1MjA0NTg0OEwsIERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKFN0cmljdE1hdGguUEkpKTsKKworICAgICAgICBmb3IgKGludCBpID0gNTAwOyBpID49IDA7IGktLSkgeworICAgICAgICAgICAgZG91YmxlIGQgPSBTdHJpY3RNYXRoLnJhbmRvbSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiR2VuZXJhdGVkIG51bWJlciBpcyBvdXQgb2YgcmFuZ2U6ICIgKyBkLCBkID49IDAuMAorICAgICAgICAgICAgICAgICAgICAmJiBkIDwgMS4wKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUb1JhZGlhbnNEKCkgeworICAgICAgICBmb3IgKGRvdWJsZSBkID0gNTAwOyBkID49IDA7IGQgLT0gMS4wKSB7CisgICAgICAgICAgICBkb3VibGUgY29udmVydGVkID0gU3RyaWN0TWF0aC50b0RlZ3JlZXMoU3RyaWN0TWF0aC50b1JhZGlhbnMoZCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29udmVydGVkIG51bWJlciBub3QgZXF1YWwgdG8gb3JpZ2luYWwuIGQgPSAiICsgZCwKKyAgICAgICAgICAgICAgICAgICAgY29udmVydGVkID49IGQgKiAwLjk5OTk5OTk5ICYmIGNvbnZlcnRlZCA8PSBkICogMS4wMDAwMDAwMSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9EZWdyZWVzRCgpIHsKKyAgICAgICAgZm9yIChkb3VibGUgZCA9IDUwMDsgZCA+PSAwOyBkIC09IDEuMCkgeworICAgICAgICAgICAgZG91YmxlIGNvbnZlcnRlZCA9IFN0cmljdE1hdGgudG9SYWRpYW5zKFN0cmljdE1hdGgudG9EZWdyZWVzKGQpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkNvbnZlcnRlZCBudW1iZXIgbm90IGVxdWFsIHRvIG9yaWdpbmFsLiBkID0gIiArIGQsCisgICAgICAgICAgICAgICAgICAgIGNvbnZlcnRlZCA+PSBkICogMC45OTk5OTk5OSAmJiBjb252ZXJ0ZWQgPD0gZCAqIDEuMDAwMDAwMDEpOworICAgICAgICB9CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoImJveGluZyIpCisgICAgcHVibGljIHZvaWQgdGVzdFVscF9EKCkgeworICAgICAgICAvLyBUZXN0IGZvciBzcGVjaWFsIGNhc2VzCisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCByZXR1cm4gTmFOIiwgRG91YmxlCisgICAgICAgICAgICAgICAgLmlzTmFOKFN0cmljdE1hdGgudWxwKERvdWJsZS5OYU4pKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLAorICAgICAgICAgICAgICAgIFN0cmljdE1hdGgudWxwKERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksCisgICAgICAgICAgICAgICAgU3RyaWN0TWF0aC51bHAoRG91YmxlLk5FR0FUSVZFX0lORklOSVRZKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIERvdWJsZS5NSU5fVkFMVUUsIFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKDAuMCksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBEb3VibGUuTUlOX1ZBTFVFLCBTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLnVscCgrMC4wKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIERvdWJsZS5NSU5fVkFMVUUsIFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKC0wLjApLCAwRCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgU3RyaWN0TWF0aC5wb3coMiwgOTcxKSwKKyAgICAgICAgICAgICAgICBTdHJpY3RNYXRoLnVscChEb3VibGUuTUFYX1ZBTFVFKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIFN0cmljdE1hdGgucG93KDIsIDk3MSksCisgICAgICAgICAgICAgICAgU3RyaWN0TWF0aC51bHAoLURvdWJsZS5NQVhfVkFMVUUpLCAwRCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBEb3VibGUuTUlOX1ZBTFVFLCBTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLnVscChEb3VibGUuTUlOX1ZBTFVFKSwgMEQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIERvdWJsZS5NSU5fVkFMVUUsIFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKC1Eb3VibGUuTUlOX1ZBTFVFKSwgMEQpOworCisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgMi4yMjA0NDYwNDkyNTAzMTNFLTE2LAorICAgICAgICAgICAgICAgIFN0cmljdE1hdGgudWxwKDEuMCksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAyLjIyMDQ0NjA0OTI1MDMxM0UtMTYsCisgICAgICAgICAgICAgICAgU3RyaWN0TWF0aC51bHAoLTEuMCksIDBEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAyLjI3MzczNjc1NDQzMjMyMDZFLTEzLAorICAgICAgICAgICAgICAgIFN0cmljdE1hdGgudWxwKDExNTMuMCksIDBEKTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiYm94aW5nIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VWxwRigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3Igc3BlY2lhbCBjYXNlcworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIE5hTiIsIEZsb2F0LmlzTmFOKFN0cmljdE1hdGgudWxwKEZsb2F0Lk5hTikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBGbG9hdC5QT1NJVElWRV9JTkZJTklUWSwKKyAgICAgICAgICAgICAgICBTdHJpY3RNYXRoLnVscChGbG9hdC5QT1NJVElWRV9JTkZJTklUWSksIDBmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBGbG9hdC5QT1NJVElWRV9JTkZJTklUWSwKKyAgICAgICAgICAgICAgICBTdHJpY3RNYXRoLnVscChGbG9hdC5ORUdBVElWRV9JTkZJTklUWSksIDBmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBGbG9hdC5NSU5fVkFMVUUsIFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKDAuMGYpLCAwZik7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgRmxvYXQuTUlOX1ZBTFVFLCBTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLnVscCgrMC4wZiksIDBmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBGbG9hdC5NSU5fVkFMVUUsIFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKC0wLjBmKSwgMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIDIuMDI4MjQxRTMxZiwgU3RyaWN0TWF0aAorICAgICAgICAgICAgICAgIC51bHAoRmxvYXQuTUFYX1ZBTFVFKSwgMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIDIuMDI4MjQxRTMxZiwgU3RyaWN0TWF0aAorICAgICAgICAgICAgICAgIC51bHAoLUZsb2F0Lk1BWF9WQUxVRSksIDBmKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIDEuNEUtNDVmLCBTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLnVscChGbG9hdC5NSU5fVkFMVUUpLCAwZik7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgMS40RS00NWYsIFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKC1GbG9hdC5NSU5fVkFMVUUpLCAwZik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAxLjE5MjA5MjlFLTdmLCBTdHJpY3RNYXRoCisgICAgICAgICAgICAgICAgLnVscCgxLjBmKSwgMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIDEuMTkyMDkyOUUtN2YsIFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKC0xLjBmKSwgMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIDEuMjIwNzAzMUUtNGYsIFN0cmljdE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKDExNTMuMGYpLCAwZik7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgNS42RS00NWYsIE1hdGgKKyAgICAgICAgICAgICAgICAudWxwKDkuNDAzOTU0RS0zOGYpLCAwZik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZENoYXJhY3RlclN1YnNldFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRDaGFyYWN0ZXJTdWJzZXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjE1NzQ3YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRDaGFyYWN0ZXJTdWJzZXRUZXN0LmphdmEKQEAgLTAsMCArMSwzOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZENoYXJhY3RlclN1YnNldFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VxdWFscygpIHsKKyAgICAgIENoYXJhY3Rlci5TdWJzZXQgc3Vic2V0MSA9IG5ldyBDaGFyYWN0ZXIuU3Vic2V0KCJuYW1lIikgeyB9OworICAgICAgYXNzZXJ0VHJ1ZShzdWJzZXQxLmVxdWFscyhzdWJzZXQxKSk7CisgICAgICBhc3NlcnRGYWxzZShzdWJzZXQxLmVxdWFscyhuZXcgQ2hhcmFjdGVyLlN1YnNldCgibmFtZSIpIHt9KSk7CisgICAgICBhc3NlcnRGYWxzZShzdWJzZXQxLmVxdWFscyhuZXcgQ2hhcmFjdGVyLlN1YnNldCgibmFtZTEiKSB7fSkpOworICAgICAgYXNzZXJ0RmFsc2Uoc3Vic2V0MS5lcXVhbHMobmV3IEludGVnZXIoMCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc2hDb2RlKCkgeworICAgICAgQ2hhcmFjdGVyLlN1YnNldCBzdWJzZXQxID0gbmV3IENoYXJhY3Rlci5TdWJzZXQoIm5hbWUiKSB7fTsKKyAgICAgIENoYXJhY3Rlci5TdWJzZXQgc3Vic2V0MiA9IG5ldyBDaGFyYWN0ZXIuU3Vic2V0KCJuYW1lIikge307CisgICAgICBDaGFyYWN0ZXIuU3Vic2V0IHN1YnNldDMgPSBuZXcgQ2hhcmFjdGVyLlN1YnNldCgibmFtZTEiKSB7fTsKKyAgICAgIGFzc2VydEZhbHNlKHN1YnNldDEuaGFzaENvZGUoKSA9PSBzdWJzZXQyLmhhc2hDb2RlKCkpOworICAgICAgYXNzZXJ0RmFsc2Uoc3Vic2V0MS5oYXNoQ29kZSgpID09IHN1YnNldDMuaGFzaENvZGUoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZENoYXJhY3RlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRDaGFyYWN0ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGU2ZjlhYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRDaGFyYWN0ZXJUZXN0LmphdmEKQEAgLTAsMCArMSwxNTIgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRDaGFyYWN0ZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF9jb2RlUG9pbnRDb3VudExqYXZhX2xhbmdfQ2hhckFycmF5SUkoKSB7CisKKyAgICAgIGFzc2VydEVxdWFscygxLCBDaGFyYWN0ZXIuY29kZVBvaW50Q291bnQoIlx1RDgwMFx1REMwMCIudG9DaGFyQXJyYXkoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMikpOworICAgICAgYXNzZXJ0RXF1YWxzKDMsIENoYXJhY3Rlci5jb2RlUG9pbnRDb3VudCgiYVx1RDgwMFx1REMwMGIiLnRvQ2hhckFycmF5KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDQpKTsKKyAgICAgIGFzc2VydEVxdWFscyg0LCBDaGFyYWN0ZXIuY29kZVBvaW50Q291bnQoImFcdUQ4MDBcdURDMDBiXHVEODAwIi50b0NoYXJBcnJheSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCA1KSk7CisgICAgICBhc3NlcnRFcXVhbHMoNCwgQ2hhcmFjdGVyLmNvZGVQb2ludENvdW50KCJhYlx1RDgwMFx1REMwMGJcdUQ4MDAiLnRvQ2hhckFycmF5KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCA1KSk7CisKKyAgICAgIHRyeSB7CisgICAgICAgICAgQ2hhcmFjdGVyLmNvZGVQb2ludENvdW50KChjaGFyW10pIG51bGwsIDAsIDEpOworICAgICAgICAgIGZhaWwoIk5vIE5QRSwgbnVsbCBjaGFyIHNlcXVlbmNlLiIpOworICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgfQorCisgICAgICB0cnkgeworICAgICAgICAgIENoYXJhY3Rlci5jb2RlUG9pbnRDb3VudCgiYWJjIi50b0NoYXJBcnJheSgpLCAtMSwgMSk7CisgICAgICAgICAgZmFpbCgiTm8gSU9PQkUsIG5lZ2F0aXZlIHN0YXJ0LiIpOworICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICB9CisKKyAgICAgIHRyeSB7CisgICAgICAgICAgQ2hhcmFjdGVyLmNvZGVQb2ludENvdW50KCJhYmMiLnRvQ2hhckFycmF5KCksIDAsIDQpOworICAgICAgICAgIGZhaWwoIk5vIElPT0JFLCBlbmQgZ3JlYXRlciB0aGFuIGxlbmd0aC4iKTsKKyAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgfQorCisgICAgICB0cnkgeworICAgICAgICAgIENoYXJhY3Rlci5jb2RlUG9pbnRDb3VudCgiYWJjIi50b0NoYXJBcnJheSgpLCAxLCAzKTsKKyAgICAgICAgICBmYWlsKCJObyBJT09CRSwgZW5kIGdyZWF0ZXIgdGhhbiBzdGFydC4iKTsKKyAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGlyZWN0aW9uYWxpdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBieXRlW10gZGlyZWN0aW9uYWxpdGllcyA9IHsKKyAgICAgICAgICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgICAgICAgICAvLyBVbmljb2RlIDUuMSBkZWZpbmVzIFUrMDM3MCB0byBiZSBHcmVlayBjYXBpdGFsIGxldHRlciBIZXRhLgorICAgICAgICAgICAgICAgIENoYXJhY3Rlci5ESVJFQ1RJT05BTElUWV9MRUZUX1RPX1JJR0hULAorICAgICAgICAgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQuCisKKyAgICAgICAgICAgICAgICBDaGFyYWN0ZXIuRElSRUNUSU9OQUxJVFlfTEVGVF9UT19SSUdIVCwKKyAgICAgICAgICAgICAgICBDaGFyYWN0ZXIuRElSRUNUSU9OQUxJVFlfUklHSFRfVE9fTEVGVCwKKworICAgICAgICAgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICAgICAgICAgIC8vIFVuaWNvZGUgc3RhbmRhcmQgNS4xIGNoYW5nZWQgY2F0ZWdvcnkgb2YgdW5pY29kZSBwb2ludCAweDA2MDAgZnJvbSBBTCB0byBBTgorICAgICAgICAgICAgICAgIENoYXJhY3Rlci5ESVJFQ1RJT05BTElUWV9BUkFCSUNfTlVNQkVSLAorICAgICAgICAgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQuCisKKyAgICAgICAgICAgICAgICBDaGFyYWN0ZXIuRElSRUNUSU9OQUxJVFlfRVVST1BFQU5fTlVNQkVSLAorICAgICAgICAgICAgICAgIC8vIENoYXJhY3Rlci5ESVJFQ1RJT05BTElUWV9FVVJPUEVBTl9OVU1CRVJfU0VQQVJBVE9SLAorICAgICAgICAgICAgICAgIENoYXJhY3Rlci5ESVJFQ1RJT05BTElUWV9FVVJPUEVBTl9OVU1CRVJfVEVSTUlOQVRPUiwKKyAgICAgICAgICAgICAgICBDaGFyYWN0ZXIuRElSRUNUSU9OQUxJVFlfQVJBQklDX05VTUJFUiwKKyAgICAgICAgICAgICAgICBDaGFyYWN0ZXIuRElSRUNUSU9OQUxJVFlfQ09NTU9OX05VTUJFUl9TRVBBUkFUT1IsCisgICAgICAgICAgICAgICAgQ2hhcmFjdGVyLkRJUkVDVElPTkFMSVRZX05PTlNQQUNJTkdfTUFSSywKKyAgICAgICAgICAgICAgICBDaGFyYWN0ZXIuRElSRUNUSU9OQUxJVFlfQk9VTkRBUllfTkVVVFJBTCwKKyAgICAgICAgICAgICAgICBDaGFyYWN0ZXIuRElSRUNUSU9OQUxJVFlfUEFSQUdSQVBIX1NFUEFSQVRPUiwKKyAgICAgICAgICAgICAgICBDaGFyYWN0ZXIuRElSRUNUSU9OQUxJVFlfU0VHTUVOVF9TRVBBUkFUT1IsCisgICAgICAgICAgICAgICAgQ2hhcmFjdGVyLkRJUkVDVElPTkFMSVRZX1dISVRFU1BBQ0UsCisgICAgICAgICAgICAgICAgQ2hhcmFjdGVyLkRJUkVDVElPTkFMSVRZX09USEVSX05FVVRSQUxTLAorICAgICAgICAgICAgICAgIENoYXJhY3Rlci5ESVJFQ1RJT05BTElUWV9MRUZUX1RPX1JJR0hUX0VNQkVERElORywKKyAgICAgICAgICAgICAgICBDaGFyYWN0ZXIuRElSRUNUSU9OQUxJVFlfTEVGVF9UT19SSUdIVF9PVkVSUklERSwKKyAgICAgICAgICAgICAgICBDaGFyYWN0ZXIuRElSRUNUSU9OQUxJVFlfUklHSFRfVE9fTEVGVF9FTUJFRERJTkcsCisgICAgICAgICAgICAgICAgQ2hhcmFjdGVyLkRJUkVDVElPTkFMSVRZX1JJR0hUX1RPX0xFRlRfT1ZFUlJJREUsCisgICAgICAgICAgICAgICAgQ2hhcmFjdGVyLkRJUkVDVElPTkFMSVRZX1BPUF9ESVJFQ1RJT05BTF9GT1JNQVQKKyAgICAgICAgICAgICAgICB9OworCisgICAgICAgIGNoYXJbXSBjaGFyYWN0ZXJzID0geworICAgICAgICAgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICAgICAgICAgIC8vIFVuaWNvZGUgNS4xIGRlZmluZXMgVSswMzcwIHRvIGJlIEdyZWVrIGNhcGl0YWwgbGV0dGVyIEhldGEuCisgICAgICAgICAgICAgICAgJ1x1MDM3MCcsIC8vIDEKKyAgICAgICAgICAgICAgICAvLyBFTkQgYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgICAgICAgICAgJ1x1MDBCNScsIC8vIDAKKyAgICAgICAgICAgICAgICAnXHUwNUJFJywgLy8gMQorICAgICAgICAgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICAgICAgICAgICdcdTA2MDAnLCAvLyA2CisgICAgICAgICAgICAgICAgLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICAgICAgICAgICdcdTAwQjInLCAvLyAzCisgICAgICAgICAgICAgICAgLy8gJycsIC8vIE5vIGNvbW1vbiBjaGFyIGluIHRoaXMgZ3JvdXAgb24gYW5kcm9pZCBhbmQgamF2YS4KKyAgICAgICAgICAgICAgICAnXHUwMEIxJywgLy8gNQorICAgICAgICAgICAgICAgICdcdTA2NjAnLCAvLyA2CisgICAgICAgICAgICAgICAgJ1x1MDBBMCcsIC8vIDcKKyAgICAgICAgICAgICAgICAnXHUwMzAwJywgLy8gOAorICAgICAgICAgICAgICAgICdcdTAwOUYnLCAvLyA5CisgICAgICAgICAgICAgICAgJ1x1MDA4NScsIC8vIDEwCisgICAgICAgICAgICAgICAgJ1x1MDAxRicsIC8vIDExCisgICAgICAgICAgICAgICAgJ1x1MDAyMCcsIC8vIDEyCisgICAgICAgICAgICAgICAgJ1x1MDBBQicsIC8vIDEzCisgICAgICAgICAgICAgICAgJ1x1MjAyQScsIC8vIDE0CisgICAgICAgICAgICAgICAgJ1x1MjAyRCcsIC8vIDE1CisgICAgICAgICAgICAgICAgJ1x1MjAyQicsIC8vIDE2CisgICAgICAgICAgICAgICAgJ1x1MjAyRScsIC8vIDE3CisgICAgICAgICAgICAgICAgJ1x1MjAyQycgLy8gMTgKKyAgICAgICAgICAgICAgICB9OworCisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBkaXJlY3Rpb25hbGl0aWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZGlyZWN0aW9uYWxpdGllc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgQ2hhcmFjdGVyLmdldERpcmVjdGlvbmFsaXR5KGNoYXJhY3RlcnNbaV0pKTsKKyAgICAgICAgfQorCisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RpZ2l0Q0koKSB7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgQ2hhcmFjdGVyLmRpZ2l0KCdcdUZGRkYnLCAxKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc1VwcGVyQ2FzZUMoKSB7CisgICAgICAgIGFzc2VydEZhbHNlKCJJbmNvcnJlY3QgY2FzZSB2YWx1ZSIsIENoYXJhY3Rlci5pc1VwcGVyQ2FzZSgnMScpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkluY29ycmVjdCBjYXNlIHZhbHVlIiwgQ2hhcmFjdGVyLmlzVXBwZXJDYXNlKCc/JykpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9Mb3dlckNhc2VDKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCB0byBjaGFuZ2UgY2FzZSIsICd0JywgQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKCd0JykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCB0byBjaGFuZ2UgY2FzZSIsICcxJywgQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKCcxJykpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9TdHJpbmcoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IFN0cmluZyByZXR1cm5lZCIsICJUIiwgbmV3IENoYXJhY3RlcignVCcpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBTdHJpbmcgcmV0dXJuZWQiLCAiMSIsIG5ldyBDaGFyYWN0ZXIoJzEnKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgU3RyaW5nIHJldHVybmVkIiwgIiQiLCBuZXcgQ2hhcmFjdGVyKCckJykudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90b1N0cmluZ19jaGFyKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBTdHJpbmcgcmV0dXJuZWQiLCAiVCIsIENoYXJhY3Rlci50b1N0cmluZygnVCcpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkQ2xhc3NUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkQ2xhc3NUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzUxNjQ2NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRDbGFzc1Rlc3QuamF2YQpAQCAtMCwwICsxLDEwMjQgQEAKKy8qCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuUGFyYW1ldGVyaXplZFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5UeXBlVmFyaWFibGU7CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEubmV0LlVSTENsYXNzTG9hZGVyOworaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdExpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfQ2xhc3NMb2FkZXI7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5yZXNvdXJjZS5TdXBwb3J0X1Jlc291cmNlczsKKworQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKK3B1YmxpYyBjbGFzcyBPbGRDbGFzc1Rlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRU5BTUUgPQorICAgICAgICBPbGRDbGFzc1Rlc3QuY2xhc3MuZ2V0UGFja2FnZSgpLmdldE5hbWUoKS5yZXBsYWNlKCcuJywgJy8nKSArCisgICAgICAgICIvdGVzdCMucHJvcGVydGllcyI7CisKKyAgICBmaW5hbCBTdHJpbmcgcGFja2FnZU5hbWUgPSBnZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXROYW1lKCk7CisgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZUluaXRFcnJvcjEgPSBwYWNrYWdlTmFtZSArICIuVGVzdENsYXNzMSI7CisgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZUluaXRFcnJvcjIgPSBwYWNrYWdlTmFtZSArICIuVGVzdENsYXNzMUIiOworICAgIGZpbmFsIFN0cmluZyBjbGFzc05hbWVMaW5rYWdlRXJyb3IgPSBwYWNrYWdlTmFtZSArICIuVGVzdENsYXNzIjsKKyAgICBmaW5hbCBTdHJpbmcgc291cmNlSkFSZmlsZSA9ICJpbGxlZ2FsQ2xhc3Nlcy5qYXIiOworICAgIGZpbmFsIFN0cmluZyBpbGxlZ2FsQ2xhc3NOYW1lID0gImlsbGVnYWxDbGFzcyI7CisKKyAgICBAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorICAgIHB1YmxpYyBAaW50ZXJmYWNlIFRlc3RBbm5vdGF0aW9uIHsKKyAgICAgICAgU3RyaW5nIHZhbHVlKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBUZXN0Q2xhc3MxQyB7CisgICAgICAgIHN0YXRpYyBUZXN0Q2xhc3MyIHRjID0gbmV3IFRlc3RDbGFzczIoMCk7CisKKyAgICAgICAgVGVzdENsYXNzMUMoKSB7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgVGVzdENsYXNzMiB7CisKKyAgICAgICAgcHVibGljIFRlc3RDbGFzczIoaW50IGkpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBUZXN0Q2xhc3MzIHsKKyAgICAgICAgcHJpdmF0ZSBUZXN0Q2xhc3MzKCkge30KKyAgICB9CisKKyAgICBpbnRlcmZhY2UgVGVzdEludGVyZmFjZSB7CisgICAgICAgIHB1YmxpYyBzdGF0aWMgaW50IFRFU1RfSU5URVJGQUNFX0ZJRUxEID0gMDsKKworICAgICAgICBpbnQgZ2V0Q291bnQoKTsKKyAgICAgICAgdm9pZCBzZXRDb3VudChpbnQgdmFsdWUpOworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBTdGF0aWNNZW1iZXIkQ2xhc3MgeworICAgICAgICBjbGFzcyBNZW1iZXIyJEEgeworICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgTWVtYmVyJENsYXNzIHsKKyAgICAgICAgY2xhc3MgTWVtYmVyMyRCIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBEZXByZWNhdGVkCisgICAgQFRlc3RBbm5vdGF0aW9uKCJsaWJjb3JlLmphdmEubGFuZy5PbGRDbGFzc1Rlc3QkRXh0ZW5kVGVzdENsYXNzIikKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEV4dGVuZFRlc3RDbGFzcyBleHRlbmRzIFB1YmxpY1Rlc3RDbGFzcyB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAgICAgcHVibGljIGVudW0gZW51bUV4bSB7T05FLCBUV08sIFRIUkVFfTsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHNldENvdW50KGludCB2YWx1ZSkgeworCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgRXh0ZW5kVGVzdENsYXNzMSBleHRlbmRzIEV4dGVuZFRlc3RDbGFzcyB7CisKKyAgICB9CisKKyAgICBAVGVzdEFubm90YXRpb24oImxpYmNvcmUuamF2YS5sYW5nLk9sZENsYXNzVGVzdCRQdWJsaWNUZXN0Q2xhc3MiKQorICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgUHVibGljVGVzdENsYXNzIGltcGxlbWVudHMgVGVzdEludGVyZmFjZSwgU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIFRFU1RfRklFTEQgPSAidGVzdCBmaWVsZCI7CisKKyAgICAgICAgT2JqZWN0IGNsYXp6OworCisgICAgICAgIHB1YmxpYyBQdWJsaWNUZXN0Q2xhc3MoKSB7CisgICAgICAgICAgICBjbGFzcyBMb2NhbENsYXNzIHsgfQorCisgICAgICAgICAgICBjbGF6eiA9IG5ldyBMb2NhbENsYXNzKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IGdldExvY2FsQ2xhc3MoKSB7CisgICAgICAgICAgICBjbGFzcyBMb2NhbENsYXNzIHt9CisgICAgICAgICAgICBPYmplY3QgcmV0dXJuZWRPYmplY3QgPSBuZXcgTG9jYWxDbGFzcygpOworICAgICAgICAgICAgcmV0dXJuIHJldHVybmVkT2JqZWN0OworICAgICAgICB9CisKKyAgICAgICAgaW50IGNvdW50ID0gMDsKKworICAgICAgICBwdWJsaWMgaW50IGdldENvdW50KCkgeworICAgICAgICAgICAgcmV0dXJuIGNvdW50OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0Q291bnQoaW50IHZhbHVlKSB7CisgICAgICAgICAgICBjb3VudCA9IHZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBjbGFzcyBQcml2YXRlQ2xhc3MxIHsKKworICAgICAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gIlByaXZhdGVDbGFzczAiOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGNsYXNzIFByaXZhdGVDbGFzczIgeworCisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgICAgIHJldHVybiAiUHJpdmF0ZUNsYXNzMSI7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFRlc3RDbGFzcyB7CisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgICAgICBwcml2YXRlIGludCBwcml2RmllbGQgPSAxOworCisgICAgICAgIHB1YmxpYyBpbnQgcHViRmllbGQgPSAyOworCisgICAgICAgIHByaXZhdGUgT2JqZWN0IGNWYWx1ZSA9IG51bGw7CisKKyAgICAgICAgcHVibGljIE9iamVjdCBhY2sgPSBuZXcgT2JqZWN0KCk7CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgICAgICAgIHByaXZhdGUgaW50IHByaXZNZXRob2QoKSB7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgcHViTWV0aG9kKCkgeworICAgICAgICAgICAgcmV0dXJuIDI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IGNWYWx1ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBjVmFsdWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgVGVzdENsYXNzKCkgeworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgICAgICAgIHByaXZhdGUgVGVzdENsYXNzKE9iamVjdCBvKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFN1YlRlc3RDbGFzcyBleHRlbmRzIFRlc3RDbGFzcyB7CisgICAgfQorCisgICAgaW50ZXJmYWNlIEludGYxIHsKKyAgICAgICAgcHVibGljIGludCBmaWVsZDEgPSAxOworICAgICAgICBwdWJsaWMgaW50IGZpZWxkMiA9IDE7CisgICAgICAgIHZvaWQgdGVzdCgpOworICAgIH0KKworICAgIGludGVyZmFjZSBJbnRmMiB7CisgICAgICAgIHB1YmxpYyBpbnQgZmllbGQxID0gMTsKKyAgICAgICAgdm9pZCB0ZXN0KCk7CisgICAgfQorCisgICAgaW50ZXJmYWNlIEludGYzIGV4dGVuZHMgSW50ZjEgeworICAgICAgICBwdWJsaWMgaW50IGZpZWxkMSA9IDE7CisgICAgfQorCisgICAgaW50ZXJmYWNlIEludGY0IGV4dGVuZHMgSW50ZjEsIEludGYyIHsKKyAgICAgICAgcHVibGljIGludCBmaWVsZDEgPSAxOworICAgICAgICB2b2lkIHRlc3QyKGludCBhLCBPYmplY3QgYik7CisgICAgfQorCisgICAgaW50ZXJmYWNlIEludGY1IGV4dGVuZHMgSW50ZjEgeworICAgIH0KKworICAgIGNsYXNzIENsczEgaW1wbGVtZW50cyBJbnRmMiB7CisgICAgICAgIHB1YmxpYyBpbnQgZmllbGQxID0gMjsKKyAgICAgICAgcHVibGljIGludCBmaWVsZDIgPSAyOworICAgICAgICBwdWJsaWMgdm9pZCB0ZXN0KCkgeworICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgQ2xzMiBleHRlbmRzIENsczEgaW1wbGVtZW50cyBJbnRmMSB7CisgICAgICAgIHB1YmxpYyBpbnQgZmllbGQxID0gMjsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHRlc3QoKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBDbHMzIGltcGxlbWVudHMgSW50ZjMsIEludGY0IHsKKyAgICAgICAgcHVibGljIHZvaWQgdGVzdCgpIHsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgdm9pZCB0ZXN0MihpbnQgYSwgT2JqZWN0IGIpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBDbHM0IHsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0QW5ub3RhdGlvbnMoKSB7CisgICAgICBBbm5vdGF0aW9uIFtdIGFubm90YXRpb25zID0gUHVibGljVGVzdENsYXNzLmNsYXNzLmdldEFubm90YXRpb25zKCk7CisgICAgICBhc3NlcnRFcXVhbHMoMSwgYW5ub3RhdGlvbnMubGVuZ3RoKTsKKyAgICAgIGFzc2VydEVxdWFscyhUZXN0QW5ub3RhdGlvbi5jbGFzcywgYW5ub3RhdGlvbnNbMF0uYW5ub3RhdGlvblR5cGUoKSk7CisKKyAgICAgIGFubm90YXRpb25zID0gRXh0ZW5kVGVzdENsYXNzLmNsYXNzLmdldEFubm90YXRpb25zKCk7CisgICAgICBhc3NlcnRFcXVhbHMoMiwgYW5ub3RhdGlvbnMubGVuZ3RoKTsKKworICAgICAgZm9yKGludCBpID0gMDsgaSA8IGFubm90YXRpb25zLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgQ2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+IHR5cGUgPSBhbm5vdGF0aW9uc1tpXS5hbm5vdGF0aW9uVHlwZSgpOworICAgICAgICAgIGFzc2VydFRydWUoIkFubm90YXRpb24ncyB0eXBlICIgKyBpICsgIjogIiArIHR5cGUsCisgICAgICAgICAgICAgIHR5cGUuZXF1YWxzKERlcHJlY2F0ZWQuY2xhc3MpIHx8CisgICAgICAgICAgICAgIHR5cGUuZXF1YWxzKFRlc3RBbm5vdGF0aW9uLmNsYXNzKSk7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9mb3JOYW1lTGphdmFfbGFuZ19TdHJpbmdMYm9vbGVhbkxDbGFzc0xvYWRlcigpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIENsYXNzTG9hZGVyIHBjbCA9IGdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKTsKKworICAgICAgICBDbGFzczw/PiBbXSBjbGFzc2VzID0ge1B1YmxpY1Rlc3RDbGFzcy5jbGFzcywgRXh0ZW5kVGVzdENsYXNzLmNsYXNzLAorICAgICAgICAgICAgICAgIEV4dGVuZFRlc3RDbGFzczEuY2xhc3MsIFRlc3RJbnRlcmZhY2UuY2xhc3MsIFN0cmluZy5jbGFzc307CisKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGNsYXNzZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIENsYXNzPD8+IGNsYXp6ID0gQ2xhc3MuZm9yTmFtZShjbGFzc2VzW2ldLmdldE5hbWUoKSwgdHJ1ZSwgcGNsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjbGFzc2VzW2ldLCBjbGF6eik7CisKKyAgICAgICAgICAgIGNsYXp6ID0gQ2xhc3MuZm9yTmFtZShjbGFzc2VzW2ldLmdldE5hbWUoKSwgZmFsc2UsIHBjbCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoY2xhc3Nlc1tpXSwgY2xhenopOworICAgICAgICB9CisKKyAgICAgICAgQ2xhc3M8Pz4gW10gc3lzdGVtQ2xhc3NlcyA9IHtTdHJpbmcuY2xhc3MsIEludGVnZXIuY2xhc3MsIE9iamVjdC5jbGFzcywKKyAgICAgICAgICAgICAgICBPYmplY3RbXS5jbGFzc307CisKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IHN5c3RlbUNsYXNzZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIENsYXNzPD8+IGNsYXp6ID0gQ2xhc3MuZm9yTmFtZShzeXN0ZW1DbGFzc2VzW2ldLmdldE5hbWUoKSwgdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoc3lzdGVtQ2xhc3Nlc1tpXSwgY2xhenopOworCisgICAgICAgICAgICBjbGF6eiA9IENsYXNzLmZvck5hbWUoc3lzdGVtQ2xhc3Nlc1tpXS5nZXROYW1lKCksIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhzeXN0ZW1DbGFzc2VzW2ldLCBjbGF6eik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgIHsKKyAgICAgICAgICAgIENsYXNzLmZvck5hbWUobnVsbCwgdHJ1ZSwgcGNsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gIG5wZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENsYXNzLmZvck5hbWUoIk5vdEV4aXN0Q2xhc3MiLCB0cnVlLCBwY2wpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIGZvciBub24gZXhpc3RlbnQgY2xhc3MuIik7CisgICAgICAgIH0gY2F0Y2goQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBjbmZlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3MuZm9yTmFtZSgiU3RyaW5nIiwgZmFsc2UsIHBjbCk7CisgICAgICAgICAgICBmYWlsKCJDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24gZm9yIG5vbiBleGlzdGVudCBjbGFzcy4iKTsKKyAgICAgICAgfSBjYXRjaChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDbGFzcy5mb3JOYW1lKCJsaWJjb3JlLmphdmEubGFuZy5Ob25leGlzdGVudENsYXNzIiwgZmFsc2UsIHBjbCk7CisgICAgICAgICAgICBmYWlsKCJDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24gZm9yIG5vbiBleGlzdGVudCBjbGFzcy4iKTsKKyAgICAgICAgfSBjYXRjaChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIEFuZHJvaWRPbmx5OiBDbGFzcy5mb3JOYW1lIG1ldGhvZCB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBvbiBBbmRyb2lkLgorICAgIHB1YmxpYyB2b2lkIHRlc3RfZm9yTmFtZUxqYXZhX2xhbmdfU3RyaW5nTGJvb2xlYW5MQ2xhc3NMb2FkZXJfQW5kcm9pZE9ubHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICAvLyBBbmRyb2lkIGRvZXNuJ3Qgc3VwcG9ydCBsb2FkaW5nIGNsYXNzIGZpbGVzIGZyb20gYSBqYXIuCisgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgIFVSTCB1cmwgPSBnZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCkuZ2V0UmVzb3VyY2UoCisgICAgICAgICAgICAgICAgICAgIHBhY2thZ2VOYW1lLnJlcGxhY2UoIi4iLCAiLyIpICsgIi8iICsgc291cmNlSkFSZmlsZSk7CisKKyAgICAgICAgICAgIENsYXNzTG9hZGVyIGxvYWRlciA9IG5ldyBVUkxDbGFzc0xvYWRlcihuZXcgVVJMW10geyB1cmwgfSwKKyAgICAgICAgICAgICAgICAgICAgZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2xhc3MuZm9yTmFtZShjbGFzc05hbWVMaW5rYWdlRXJyb3IsIHRydWUsIGxvYWRlcik7CisgICAgICAgICAgICAgICAgZmFpbCgiTGlua2FnZUVycm9yIG9yIENsYXNzTm90Rm91bmRFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgICAgICB9IGNhdGNoIChqYXZhLmxhbmcuTGlua2FnZUVycm9yIGxlKSB7CisgICAgICAgICAgICAgICAgLy8gRXhwZWN0ZWQgZm9yIHRoZSBSSS4KKyAgICAgICAgICAgIH0gY2F0Y2ggKGphdmEubGFuZy5DbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNlKSB7CisgICAgICAgICAgICAgICAgLy8gRXhwZWN0ZWQgZm9yIEFuZHJvaWQuCisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIHdhcyB0aHJvd246ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENsYXNzLmZvck5hbWUoY2xhc3NOYW1lSW5pdEVycm9yMiwKKyAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvciBvciBDbGFzc05vdEZvdW5kRXhjZXB0aW9uICIgKworICAgICAgICAgICAgInNob3VsZCBiZSB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKGphdmEubGFuZy5FeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3IgaWUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkIGZvciB0aGUgUkkuCisgICAgICAgIC8vIFJlbW92ZSB0aGlzIGNvbW1lbnQgdG8gbGV0IHRoZSB0ZXN0IHBhc3Mgb24gQW5kcm9pZC4KKyAgICAgICAgfSBjYXRjaCAoamF2YS5sYW5nLkNsYXNzTm90Rm91bmRFeGNlcHRpb24gY2UpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkIGZvciBBbmRyb2lkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBbm5vdGF0aW9uKCkgeworICAgICAgVGVzdEFubm90YXRpb24gdGFyZ2V0ID0gUHVibGljVGVzdENsYXNzLmNsYXNzLmdldEFubm90YXRpb24oVGVzdEFubm90YXRpb24uY2xhc3MpOworICAgICAgYXNzZXJ0RXF1YWxzKHRhcmdldC52YWx1ZSgpLCBQdWJsaWNUZXN0Q2xhc3MuY2xhc3MuZ2V0TmFtZSgpKTsKKworICAgICAgYXNzZXJ0TnVsbChQdWJsaWNUZXN0Q2xhc3MuY2xhc3MuZ2V0QW5ub3RhdGlvbihEZXByZWNhdGVkLmNsYXNzKSk7CisKKyAgICAgIERlcHJlY2F0ZWQgdGFyZ2V0MiA9IEV4dGVuZFRlc3RDbGFzcy5jbGFzcy5nZXRBbm5vdGF0aW9uKERlcHJlY2F0ZWQuY2xhc3MpOworICAgICAgYXNzZXJ0Tm90TnVsbCh0YXJnZXQyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERlY2xhcmVkQW5ub3RhdGlvbnMoKSB7CisgICAgICAgIEFubm90YXRpb24gW10gYW5ub3RhdGlvbnMgPSBQdWJsaWNUZXN0Q2xhc3MuY2xhc3MuZ2V0RGVjbGFyZWRBbm5vdGF0aW9ucygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgYW5ub3RhdGlvbnMubGVuZ3RoKTsKKworICAgICAgICBhbm5vdGF0aW9ucyA9IEV4dGVuZFRlc3RDbGFzcy5jbGFzcy5nZXREZWNsYXJlZEFubm90YXRpb25zKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBhbm5vdGF0aW9ucy5sZW5ndGgpOworCisgICAgICAgIGFubm90YXRpb25zID0gVGVzdEludGVyZmFjZS5jbGFzcy5nZXREZWNsYXJlZEFubm90YXRpb25zKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBhbm5vdGF0aW9ucy5sZW5ndGgpOworCisgICAgICAgIGFubm90YXRpb25zID0gU3RyaW5nLmNsYXNzLmdldERlY2xhcmVkQW5ub3RhdGlvbnMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGFubm90YXRpb25zLmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRFbmNsb3NpbmdDbGFzcygpIHsKKyAgICAgICAgQ2xhc3MgY2xhenogPSBPbGRDbGFzc1Rlc3QuY2xhc3MuZ2V0RW5jbG9zaW5nQ2xhc3MoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjbGF6eik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGdldENsYXNzKCksIENsczEuY2xhc3MuZ2V0RW5jbG9zaW5nQ2xhc3MoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhnZXRDbGFzcygpLCBJbnRmMS5jbGFzcy5nZXRFbmNsb3NpbmdDbGFzcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGdldENsYXNzKCksIENsczQuY2xhc3MuZ2V0RW5jbG9zaW5nQ2xhc3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRFbmNsb3NpbmdNZXRob2QoKSB7CisgICAgICAgIE1ldGhvZCBjbGF6eiA9IEV4dGVuZFRlc3RDbGFzcy5jbGFzcy5nZXRFbmNsb3NpbmdNZXRob2QoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjbGF6eik7CisKKyAgICAgICAgUHVibGljVGVzdENsYXNzIHB0YyA9IG5ldyBQdWJsaWNUZXN0Q2xhc3MoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0RW5jbG9zaW5nTWV0aG9kIHJldHVybnMgaW5jb3JyZWN0IG1ldGhvZC4iLAorICAgICAgICAgICAgICAgICAgICBQdWJsaWNUZXN0Q2xhc3MuY2xhc3MuZ2V0TWV0aG9kKCJnZXRMb2NhbENsYXNzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQ2xhc3MgW10pIG51bGwpLAorICAgICAgICAgICAgICAgICAgICBwdGMuZ2V0TG9jYWxDbGFzcygpLmdldENsYXNzKCkuZ2V0RW5jbG9zaW5nTWV0aG9kKCkpOworICAgICAgICB9IGNhdGNoKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBuc21lKSB7CisgICAgICAgICAgICBmYWlsKCJOb1N1Y2hNZXRob2RFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RW5jbG9zaW5nQ29uc3RydWN0b3IoKSB7CisKKyAgICAgICAgUHVibGljVGVzdENsYXNzIHB0YyA9IG5ldyBQdWJsaWNUZXN0Q2xhc3MoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoImdldEVuY2xvc2luZ0NvbnN0cnVjdG9yIG1ldGhvZCByZXR1cm5zIGluY29ycmVjdCBjbGFzcy4iLAorICAgICAgICAgICAgICAgIFB1YmxpY1Rlc3RDbGFzcy5jbGFzcy5nZXRDb25zdHJ1Y3RvcnMoKVswXSwKKyAgICAgICAgICAgICAgICBwdGMuY2xhenouZ2V0Q2xhc3MoKS5nZXRFbmNsb3NpbmdDb25zdHJ1Y3RvcigpKTsKKworICAgICAgICBhc3NlcnROdWxsKCJnZXRFbmNsb3NpbmdDb25zdHJ1Y3RvciBzaG91bGQgcmV0dXJuIG51bGwgZm9yIGxvY2FsICIgKworICAgICAgICAgICAgICAgICJjbGFzcyBkZWNsYXJlZCBpbiBtZXRob2QuIiwKKyAgICAgICAgICAgICAgICBwdGMuZ2V0TG9jYWxDbGFzcygpLmdldENsYXNzKCkuZ2V0RW5jbG9zaW5nQ29uc3RydWN0b3IoKSk7CisKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0RW5jbG9zaW5nQ29uc3RydWN0b3Igc2hvdWxkIHJldHVybiBudWxsIGZvciBsb2NhbCAiICsKKyAgICAgICAgICAgICAgICAiY2xhc3MgZGVjbGFyZWQgaW4gbWV0aG9kLiIsCisgICAgICAgICAgICAgICAgRXh0ZW5kVGVzdENsYXNzLmNsYXNzLmdldEVuY2xvc2luZ0NvbnN0cnVjdG9yKCkpOworICAgIH0KKworCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRFbnVtQ29uc3RhbnRzKCkgeworICAgICAgICBPYmplY3QgW10gY2xhenogPSBFeHRlbmRUZXN0Q2xhc3MuY2xhc3MuZ2V0RW51bUNvbnN0YW50cygpOworICAgICAgICBhc3NlcnROdWxsKGNsYXp6KTsKKyAgICAgICAgT2JqZWN0IFtdIGNvbnN0YW50cyA9IFRlc3RFbnVtLmNsYXNzLmdldEVudW1Db25zdGFudHMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFRlc3RFbnVtLnZhbHVlcygpLmxlbmd0aCwgY29uc3RhbnRzLmxlbmd0aCk7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBjb25zdGFudHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhUZXN0RW51bS52YWx1ZXMoKVtpXSwgY29uc3RhbnRzW2ldKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoMCwgVGVzdEVtcHR5RW51bS5jbGFzcy5nZXRFbnVtQ29uc3RhbnRzKCkubGVuZ3RoKTsKKyAgICB9CisgICAgcHVibGljIGVudW0gVGVzdEVudW0geworICAgICAgICBPTkUsIFRXTywgVEhSRUUKKyAgICB9CisgICAgcHVibGljIGVudW0gVGVzdEVtcHR5RW51bSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRHZW5lcmljSW50ZXJmYWNlcygpIHsKKyAgICAgICAgVHlwZSBbXSB0eXBlcyA9IEV4dGVuZFRlc3RDbGFzczEuY2xhc3MuZ2V0R2VuZXJpY0ludGVyZmFjZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHR5cGVzLmxlbmd0aCk7CisKKyAgICAgICAgQ2xhc3MgW10gaW50ZXJmYWNlcyA9IHtUZXN0SW50ZXJmYWNlLmNsYXNzLCBTZXJpYWxpemFibGUuY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xvbmVhYmxlLmNsYXNzfTsKKyAgICAgICAgdHlwZXMgPSBQdWJsaWNUZXN0Q2xhc3MuY2xhc3MuZ2V0R2VuZXJpY0ludGVyZmFjZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGludGVyZmFjZXMubGVuZ3RoLCB0eXBlcy5sZW5ndGgpOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgdHlwZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpbnRlcmZhY2VzW2ldLCB0eXBlc1tpXSk7CisgICAgICAgIH0KKworICAgICAgICB0eXBlcyA9IFRlc3RJbnRlcmZhY2UuY2xhc3MuZ2V0R2VuZXJpY0ludGVyZmFjZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHR5cGVzLmxlbmd0aCk7CisKKyAgICAgICAgdHlwZXMgPSBMaXN0LmNsYXNzLmdldEdlbmVyaWNJbnRlcmZhY2VzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCB0eXBlcy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29sbGVjdGlvbi5jbGFzcywgKChQYXJhbWV0ZXJpemVkVHlwZSl0eXBlc1swXSkuZ2V0UmF3VHlwZSgpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaW50LmNsYXNzLmdldEdlbmVyaWNJbnRlcmZhY2VzKCkubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHZvaWQuY2xhc3MuZ2V0R2VuZXJpY0ludGVyZmFjZXMoKS5sZW5ndGgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0R2VuZXJpY1N1cGVyY2xhc3MgKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoUHVibGljVGVzdENsYXNzLmNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuZFRlc3RDbGFzcy5jbGFzcy5nZXRHZW5lcmljU3VwZXJjbGFzcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEV4dGVuZFRlc3RDbGFzcy5jbGFzcywKKyAgICAgICAgICAgICAgICBFeHRlbmRUZXN0Q2xhc3MxLmNsYXNzLmdldEdlbmVyaWNTdXBlcmNsYXNzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoT2JqZWN0LmNsYXNzLCBQdWJsaWNUZXN0Q2xhc3MuY2xhc3MuZ2V0R2VuZXJpY1N1cGVyY2xhc3MoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhPYmplY3QuY2xhc3MsIFN0cmluZy5jbGFzcy5nZXRHZW5lcmljU3VwZXJjbGFzcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIFRlc3RJbnRlcmZhY2UuY2xhc3MuZ2V0R2VuZXJpY1N1cGVyY2xhc3MoKSk7CisKKyAgICAgICAgUGFyYW1ldGVyaXplZFR5cGUgdHlwZSA9IChQYXJhbWV0ZXJpemVkVHlwZSkgVmVjdG9yLmNsYXNzLmdldEdlbmVyaWNTdXBlcmNsYXNzKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhBYnN0cmFjdExpc3QuY2xhc3MsIHR5cGUuZ2V0UmF3VHlwZSgpKTsKKyAgICB9CisKKyAgICAvLyBBbmRyb2lkT25seTogVXNlcyBkYWx2aWsuc3lzdGVtLlBhdGhDbGFzc0xvYWRlci4KKyAgICAvLyBEaWZmZXJlbnQgYmVoYXZpb3IgYmV0d2VlbiBjdHMgaG9zdCBhbmQgcnVuLWNvcmUtdGVzdCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQYWNrYWdlKCkgeworCisgICAgICBQYWNrYWdlIHRoaXNQYWNrYWdlID0gZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImxpYmNvcmUuamF2YS5sYW5nIiwKKyAgICAgICAgICAgICAgICAgICAgICB0aGlzUGFja2FnZS5nZXROYW1lKCkpOworCisgICAgICBQYWNrYWdlIHN0cmluZ1BhY2thZ2UgPSBTdHJpbmcuY2xhc3MuZ2V0UGFja2FnZSgpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiamF2YS5sYW5nIiwgc3RyaW5nUGFja2FnZS5nZXROYW1lKCkpOworCisgICAgICBTdHJpbmcgaHl0c19wYWNrYWdlX25hbWUgPSAiaHl0c19wYWNrYWdlX2RleC5qYXIiOworICAgICAgRmlsZSByZXNvdXJjZXMgPSBTdXBwb3J0X1Jlc291cmNlcy5jcmVhdGVUZW1wRm9sZGVyKCk7CisgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsICJQYWNrYWdlIiwgaHl0c19wYWNrYWdlX25hbWUpOworCisgICAgICBTdHJpbmcgcmVzUGF0aCA9IHJlc291cmNlcy50b1N0cmluZygpOworICAgICAgaWYgKHJlc1BhdGguY2hhckF0KDApID09ICcvJyB8fCByZXNQYXRoLmNoYXJBdCgwKSA9PSAnXFwnKQorICAgICAgICAgIHJlc1BhdGggPSByZXNQYXRoLnN1YnN0cmluZygxKTsKKworICAgICAgdHJ5IHsKKworICAgICAgICAgIFVSTCByZXNvdXJjZVVSTCA9IG5ldyBVUkwoImZpbGU6LyIgKyByZXNQYXRoICsgIi9QYWNrYWdlLyIKKyAgICAgICAgICAgICAgICAgICsgaHl0c19wYWNrYWdlX25hbWUpOworCisgICAgICAgICAgQ2xhc3NMb2FkZXIgY2wgPSBTdXBwb3J0X0NsYXNzTG9hZGVyLmdldEluc3RhbmNlKHJlc291cmNlVVJMLAorICAgICAgICAgICAgICAgICAgZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpKTsKKworICAgICAgICAgIENsYXNzIGNsYXp6ID0gY2wubG9hZENsYXNzKCJDIik7CisgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0UGFja2FnZSBmb3IgQy5jbGFzcyBzaG91bGQgcmV0dXJuIG51bGwiLAorICAgICAgICAgICAgICAgICAgY2xhenouZ2V0UGFja2FnZSgpKTsKKworICAgICAgICAgIGNsYXp6ID0gY2wubG9hZENsYXNzKCJhLmIuQyIpOworICAgICAgICAgIFBhY2thZ2UgY1BhY2thZ2UgPSBjbGF6ei5nZXRQYWNrYWdlKCk7CisgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0UGFja2FnZSBmb3IgYS5iLkMuY2xhc3Mgc2hvdWxkIG5vdCByZXR1cm4gbnVsbCIsCisgICAgICAgICAgICAgICAgICBjUGFja2FnZSk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVVJMQ2xhc3NMb2FkZXIgZG9lc24ndCB3b3JrIG9uIEFuZHJvaWQgZm9yIGphciBmaWxlcworICAgICAgICAgKgorICAgICAgICAgKiBVUkwgdXJsID0gZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpLmdldFJlc291cmNlKAorICAgICAgICAgKiAgICAgICAgIHBhY2thZ2VOYW1lLnJlcGxhY2UoIi4iLCAiLyIpICsgIi8iICsgc291cmNlSkFSZmlsZSk7CisgICAgICAgICAqCisgICAgICAgICAqIENsYXNzTG9hZGVyIGxvYWRlciA9IG5ldyBVUkxDbGFzc0xvYWRlcihuZXcgVVJMW10geyB1cmwgfSwgbnVsbCk7CisgICAgICAgICAqCisgICAgICAgICAqIHRyeSB7CisgICAgICAgICAqICAgICBDbGFzczw/PiBjbGF6eiA9IGxvYWRlci5sb2FkQ2xhc3MoaWxsZWdhbENsYXNzTmFtZSk7CisgICAgICAgICAqICAgICBQYWNrYWdlIHBhY2sgPSBjbGF6ei5nZXRQYWNrYWdlKCk7CisgICAgICAgICAqICAgICBhc3NlcnROdWxsKHBhY2spOworICAgICAgICAgKiB9IGNhdGNoKENsYXNzTm90Rm91bmRFeGNlcHRpb24gY25lKSB7CisgICAgICAgICAqICAgICBmYWlsKCJDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHdhcyB0aHJvd24gZm9yICIgKyBpbGxlZ2FsQ2xhc3NOYW1lKTsKKyAgICAgICAgICogfQorICAgICAgICAqLworICAgICAgfSBjYXRjaChFeGNlcHRpb24gZSkgeworICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIHdhcyB0aHJvd246ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0U2lnbmVycygpIHsKKyAgICAgICAgYXNzZXJ0TnVsbCh2b2lkLmNsYXNzLmdldFNpZ25lcnMoKSk7CisgICAgICAgIGFzc2VydE51bGwoUHVibGljVGVzdENsYXNzLmNsYXNzLmdldFNpZ25lcnMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTaW1wbGVOYW1lKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIlB1YmxpY1Rlc3RDbGFzcyIsIFB1YmxpY1Rlc3RDbGFzcy5jbGFzcy5nZXRTaW1wbGVOYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInZvaWQiLCB2b2lkLmNsYXNzLmdldFNpbXBsZU5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW50W10iLCBpbnRbXS5jbGFzcy5nZXRTaW1wbGVOYW1lKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0VHlwZVBhcmFtZXRlcnMoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBQdWJsaWNUZXN0Q2xhc3MuY2xhc3MuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGgpOworICAgICAgICBUeXBlVmFyaWFibGUgW10gdHYgPSBUZW1wVGVzdENsYXNzMS5jbGFzcy5nZXRUeXBlUGFyYW1ldGVycygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgdHYubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE9iamVjdC5jbGFzcywgdHZbMF0uZ2V0Qm91bmRzKClbMF0pOworCisgICAgICAgIFRlbXBUZXN0Q2xhc3MyPFN0cmluZz4gdGMgPSBuZXcgVGVtcFRlc3RDbGFzczI8U3RyaW5nPigpOworICAgICAgICB0diA9IHRjLmdldENsYXNzKCkuZ2V0VHlwZVBhcmFtZXRlcnMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHR2Lmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscyhTdHJpbmcuY2xhc3MsIHR2WzBdLmdldEJvdW5kcygpWzBdKTsKKyAgICB9CisKKyAgICBjbGFzcyBUZW1wVGVzdENsYXNzMTxUPiB7CisgICAgfQorCisgICAgY2xhc3MgVGVtcFRlc3RDbGFzczI8UyBleHRlbmRzIFN0cmluZz4gZXh0ZW5kcyBUZW1wVGVzdENsYXNzMTxTPiB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0Fubm90YXRpb24oKSB7CisgICAgICAgIGFzc2VydFRydWUoRGVwcmVjYXRlZC5jbGFzcy5pc0Fubm90YXRpb24oKSk7CisgICAgICAgIGFzc2VydFRydWUoVGVzdEFubm90YXRpb24uY2xhc3MuaXNBbm5vdGF0aW9uKCkpOworICAgICAgICBhc3NlcnRGYWxzZShQdWJsaWNUZXN0Q2xhc3MuY2xhc3MuaXNBbm5vdGF0aW9uKCkpOworICAgICAgICBhc3NlcnRGYWxzZShTdHJpbmcuY2xhc3MuaXNBbm5vdGF0aW9uKCkpOworICAgIH0KKworICAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzQW5ub3RhdGlvblByZXNlbnQoKSB7CisgICAgICAgIGFzc2VydFRydWUoUHVibGljVGVzdENsYXNzLmNsYXNzLmlzQW5ub3RhdGlvblByZXNlbnQoVGVzdEFubm90YXRpb24uY2xhc3MpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoRXh0ZW5kVGVzdENsYXNzMS5jbGFzcy5pc0Fubm90YXRpb25QcmVzZW50KFRlc3RBbm5vdGF0aW9uLmNsYXNzKSk7CisgICAgICAgIGFzc2VydEZhbHNlKFN0cmluZy5jbGFzcy5pc0Fubm90YXRpb25QcmVzZW50KERlcHJlY2F0ZWQuY2xhc3MpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShFeHRlbmRUZXN0Q2xhc3MuY2xhc3MuaXNBbm5vdGF0aW9uUHJlc2VudChUZXN0QW5ub3RhdGlvbi5jbGFzcykpOworICAgICAgICBhc3NlcnRUcnVlKEV4dGVuZFRlc3RDbGFzcy5jbGFzcy5pc0Fubm90YXRpb25QcmVzZW50KERlcHJlY2F0ZWQuY2xhc3MpKTsKKyAgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0Fub255bW91c0NsYXNzKCkgeworICAgICAgICBhc3NlcnRGYWxzZShQdWJsaWNUZXN0Q2xhc3MuY2xhc3MuaXNBbm9ueW1vdXNDbGFzcygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgobmV3IFRocmVhZCgpIHt9KS5nZXRDbGFzcygpLmlzQW5vbnltb3VzQ2xhc3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0VudW0oKSB7CisgICAgICBhc3NlcnRGYWxzZShQdWJsaWNUZXN0Q2xhc3MuY2xhc3MuaXNFbnVtKCkpOworICAgICAgYXNzZXJ0RmFsc2UoRXh0ZW5kVGVzdENsYXNzLmNsYXNzLmlzRW51bSgpKTsKKyAgICAgIGFzc2VydFRydWUoVGVzdEVudW0uT05FLmdldENsYXNzKCkuaXNFbnVtKCkpOworICAgICAgYXNzZXJ0VHJ1ZShUZXN0RW51bS5jbGFzcy5pc0VudW0oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0xvY2FsQ2xhc3MoKSB7CisgICAgICAgIGFzc2VydEZhbHNlKEV4dGVuZFRlc3RDbGFzcy5jbGFzcy5pc0xvY2FsQ2xhc3MoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKFRlc3RJbnRlcmZhY2UuY2xhc3MuaXNMb2NhbENsYXNzKCkpOworICAgICAgICBhc3NlcnRGYWxzZShUZXN0RW51bS5jbGFzcy5pc0xvY2FsQ2xhc3MoKSk7CisgICAgICAgIGNsYXNzIEludGVybmFsQ2xhc3Mge30KKyAgICAgICAgYXNzZXJ0VHJ1ZShJbnRlcm5hbENsYXNzLmNsYXNzLmlzTG9jYWxDbGFzcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzTWVtYmVyQ2xhc3MoKSB7CisgICAgICAgIGFzc2VydEZhbHNlKE9sZENsYXNzVGVzdC5jbGFzcy5pc01lbWJlckNsYXNzKCkpOworICAgICAgICBhc3NlcnRGYWxzZShTdHJpbmcuY2xhc3MuaXNNZW1iZXJDbGFzcygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShUZXN0RW51bS5jbGFzcy5pc01lbWJlckNsYXNzKCkpOworICAgICAgICBhc3NlcnRUcnVlKFN0YXRpY01lbWJlciRDbGFzcy5jbGFzcy5pc01lbWJlckNsYXNzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNTeW50aGV0aWMoKSB7CisgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3Igbm9uIHN5bnRoZXRpYyBjbGFzcy4iLAorICAgICAgICAgICAgICBFeHRlbmRUZXN0Q2xhc3MuY2xhc3MuaXNTeW50aGV0aWMoKSk7CisgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3Igbm9uIHN5bnRoZXRpYyBjbGFzcy4iLAorICAgICAgICAgICAgICBUZXN0SW50ZXJmYWNlLmNsYXNzLmlzU3ludGhldGljKCkpOworICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIG5vbiBzeW50aGV0aWMgY2xhc3MuIiwKKyAgICAgICAgICAgICAgU3RyaW5nLmNsYXNzLmlzU3ludGhldGljKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Q2Fub25pY2FsTmFtZSgpIHsKKyAgICAgICAgQ2xhc3MgW10gY2xhc3NBcnJheSA9IHsgaW50LmNsYXNzLCBpbnRbXS5jbGFzcywgU3RyaW5nLmNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQdWJsaWNUZXN0Q2xhc3MuY2xhc3MsIFRlc3RJbnRlcmZhY2UuY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuZFRlc3RDbGFzcy5jbGFzcyB9OworICAgICAgICBTdHJpbmcgW10gY2xhc3NOYW1lcyA9IHsiaW50IiwgImludFtdIiwgImphdmEubGFuZy5TdHJpbmciLAorICAgICAgICAgICAgICAgICAgICAgICJsaWJjb3JlLmphdmEubGFuZy5PbGRDbGFzc1Rlc3QuUHVibGljVGVzdENsYXNzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJsaWJjb3JlLmphdmEubGFuZy5PbGRDbGFzc1Rlc3QuVGVzdEludGVyZmFjZSIsCisgICAgICAgICAgICAgICAgICAgICAibGliY29yZS5qYXZhLmxhbmcuT2xkQ2xhc3NUZXN0LkV4dGVuZFRlc3RDbGFzcyJ9OworCisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBjbGFzc0FycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoY2xhc3NOYW1lc1tpXSwgY2xhc3NBcnJheVtpXS5nZXRDYW5vbmljYWxOYW1lKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDbGFzc0xvYWRlcigpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEV4dGVuZFRlc3RDbGFzcy5jbGFzcy5nZXRDbGFzc0xvYWRlcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgIFB1YmxpY1Rlc3RDbGFzcy5jbGFzcy5nZXRDbGFzc0xvYWRlcigpKTsKKworICAgICAgICBhc3NlcnROdWxsKGludC5jbGFzcy5nZXRDbGFzc0xvYWRlcigpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh2b2lkLmNsYXNzLmdldENsYXNzTG9hZGVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Q2xhc3NlcygpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgY2xhc3MgYXJyYXkgcmV0dXJuZWQiLAorICAgICAgICAgICAgICAgICAgICAgMTEsIE9sZENsYXNzVGVzdC5jbGFzcy5nZXRDbGFzc2VzKCkubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERlY2xhcmVkQ2xhc3NlcygpIHsKKyAgICAgICAgQ2xhc3MgW10gZGVjbENsYXNzZXMgPSBPYmplY3QuY2xhc3MuZ2V0RGVjbGFyZWRDbGFzc2VzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGxlbmd0aCBvZiBkZWNsYXJlZCBjbGFzc2VzIGFycmF5IGlzIHJldHVybmVkICIgKworICAgICAgICAgICAgICAgICJmb3IgT2JqZWN0LiIsIDAsIGRlY2xDbGFzc2VzLmxlbmd0aCk7CisKKyAgICAgICAgZGVjbENsYXNzZXMgPSBQdWJsaWNUZXN0Q2xhc3MuY2xhc3MuZ2V0RGVjbGFyZWRDbGFzc2VzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBkZWNsQ2xhc3Nlcy5sZW5ndGgpOworCisgICAgICAgIGFzc2VydEVxdWFscygwLCBpbnQuY2xhc3MuZ2V0RGVjbGFyZWRDbGFzc2VzKCkubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHZvaWQuY2xhc3MuZ2V0RGVjbGFyZWRDbGFzc2VzKCkubGVuZ3RoKTsKKworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgZGVjbENsYXNzZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIENvbnN0cnVjdG9yPD8+IGNvbnN0ciA9IGRlY2xDbGFzc2VzW2ldLmdldERlY2xhcmVkQ29uc3RydWN0b3JzKClbMF07CisgICAgICAgICAgICBjb25zdHIuc2V0QWNjZXNzaWJsZSh0cnVlKTsKKyAgICAgICAgICAgIFB1YmxpY1Rlc3RDbGFzcyBwdWJsaWNDbGF6eiA9IG5ldyBQdWJsaWNUZXN0Q2xhc3MoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgT2JqZWN0IG8gPSBjb25zdHIubmV3SW5zdGFuY2UocHVibGljQ2xhenopOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBjbGFzczogIiArIG8udG9TdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG8udG9TdHJpbmcoKS5zdGFydHNXaXRoKCJQcml2YXRlQ2xhc3MiKSk7CisgICAgICAgICAgICB9IGNhdGNoKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gd2FzIHRocm93bjogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBkZWNsQ2xhc3NlcyA9IFRlc3RJbnRlcmZhY2UuY2xhc3MuZ2V0RGVjbGFyZWRDbGFzc2VzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBkZWNsQ2xhc3Nlcy5sZW5ndGgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGVjbGFyZWRDb25zdHJ1Y3RvciRMamF2YV9sYW5nX0NsYXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUZXN0Q2xhc3MuY2xhc3MuZ2V0RGVjbGFyZWRDb25zdHJ1Y3RvcihTdHJpbmcuY2xhc3MpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoTWV0aG9kRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTm9TdWNoTWV0aG9kRXhjZXB0aW9uIG5zbWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGVjbGFyZWRGaWVsZExqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUZXN0Q2xhc3MuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgVGVzdENsYXNzLmNsYXNzLmdldERlY2xhcmVkRmllbGQoIk5vbkV4aXN0ZW50RmllbGQiKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaEZpZWxkRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTm9TdWNoRmllbGRFeGNlcHRpb24gbnNmZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREZWNsYXJlZE1ldGhvZExqYXZhX2xhbmdfU3RyaW5nJExqYXZhX2xhbmdfQ2xhc3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRlc3RDbGFzcy5jbGFzcy5nZXREZWNsYXJlZE1ldGhvZChudWxsLCBuZXcgQ2xhc3NbMF0pOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUZXN0Q2xhc3MuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoIk5vbkV4aXN0ZW50TWV0aG9kIiwgbmV3IENsYXNzWzBdKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBuc21lKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1ldGhvZExqYXZhX2xhbmdfU3RyaW5nJExqYXZhX2xhbmdfQ2xhc3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG0gPSBFeHRlbmRUZXN0Q2xhc3MxLmNsYXNzLmdldE1ldGhvZCgiZ2V0Q291bnQiLCBuZXcgQ2xhc3NbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBtZXRob2QiLCAwLCAoKEludGVnZXIpIChtLmludm9rZShuZXcgRXh0ZW5kVGVzdENsYXNzMSgpKSkpCisgICAgICAgICAgICAgICAgLmludFZhbHVlKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtID0gVGVzdENsYXNzLmNsYXNzLmdldE1ldGhvZCgiaW5pdCIsIG5ldyBDbGFzc1swXSk7CisgICAgICAgICAgICBmYWlsKCJGYWlsZWQgdG8gdGhyb3cgZXhjZXB0aW9uIGFjY2Vzc2luZyB0byBpbml0IG1ldGhvZCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdAorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRlc3RDbGFzcy5jbGFzcy5nZXRNZXRob2QoInB1Yk1ldGhvZCIsIG5ldyBDbGFzc1swXSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREZWNsYXJpbmdDbGFzcygpIHsKKyAgICAgICAgYXNzZXJ0TnVsbChPbGRDbGFzc1Rlc3QuY2xhc3MuZ2V0RGVjbGFyaW5nQ2xhc3MoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoUHVibGljVGVzdENsYXNzLmNsYXNzLmdldERlY2xhcmluZ0NsYXNzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RmllbGRMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGaWVsZCBmID0gVGVzdENsYXNzLmNsYXNzLmdldEZpZWxkKCJwdWJGaWVsZCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBmaWVsZCIsIDIsIGYuZ2V0SW50KG5ldyBUZXN0Q2xhc3MoKSkpOworCisgICAgICAgIGYgPSBQdWJsaWNUZXN0Q2xhc3MuY2xhc3MuZ2V0RmllbGQoIlRFU1RfRklFTEQiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgZmllbGQiLCAidGVzdCBmaWVsZCIsCisgICAgICAgICAgICAgICAgZi5nZXQobmV3IFB1YmxpY1Rlc3RDbGFzcygpKSk7CisKKyAgICAgICAgZiA9IFB1YmxpY1Rlc3RDbGFzcy5jbGFzcy5nZXRGaWVsZCgiVEVTVF9JTlRFUkZBQ0VfRklFTEQiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgZmllbGQiLCAwLAorICAgICAgICAgICAgICAgIGYuZ2V0SW50KG5ldyBQdWJsaWNUZXN0Q2xhc3MoKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUZXN0Q2xhc3MuY2xhc3MuZ2V0RmllbGQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcyB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEZpZWxkczIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmllbGRbXSBmOworICAgICAgICBGaWVsZCBleHBlY3RlZCA9IG51bGw7CisKKyAgICAgICAgZiA9IFB1YmxpY1Rlc3RDbGFzcy5jbGFzcy5nZXRGaWVsZHMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCBudW1iZXIgb2YgZmllbGRzOyIsIDIsIGYubGVuZ3RoKTsKKworICAgICAgICBmID0gQ2xzMi5jbGFzcy5nZXRGaWVsZHMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IEluY29ycmVjdCBudW1iZXIgb2YgZmllbGRzOyIsIDYsIGYubGVuZ3RoKTsKKworICAgICAgICBmID0gQ2xzMy5jbGFzcy5nZXRGaWVsZHMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IEluY29ycmVjdCBudW1iZXIgb2YgZmllbGRzOyIsIDUsIGYubGVuZ3RoKTsKKworICAgICAgICBmb3IgKEZpZWxkIGZpZWxkIDogZikgeworICAgICAgICAgICAgaWYgKGZpZWxkLnRvU3RyaW5nKCkuZXF1YWxzKCJwdWJsaWMgc3RhdGljIGZpbmFsIGludCAiCisgICAgICAgICAgICAgICAgICAgICsgImxpYmNvcmUuamF2YS5sYW5nLk9sZENsYXNzVGVzdCRJbnRmMy5maWVsZDEiKSkgeworICAgICAgICAgICAgICAgIGV4cGVjdGVkID0gZmllbGQ7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGV4cGVjdGVkID09IG51bGwpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogZ2V0RmllbGRzKCkgZGlkIG5vdCByZXR1cm4gYWxsIGZpZWxkcy4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNDogSW5jb3JyZWN0IGZpZWxkOyIsIGV4cGVjdGVkLAorICAgICAgICAgICAgICAgIENsczMuY2xhc3MuZ2V0RmllbGQoImZpZWxkMSIpKTsKKworICAgICAgICBleHBlY3RlZCA9IG51bGw7CisgICAgICAgIGZvciAoRmllbGQgZmllbGQgOiBmKSB7CisgICAgICAgICAgICBpZihmaWVsZC50b1N0cmluZygpLmVxdWFscygicHVibGljIHN0YXRpYyBmaW5hbCBpbnQgIiArCisgICAgICAgICAgICAgICAgICAgICJsaWJjb3JlLmphdmEubGFuZy5PbGRDbGFzc1Rlc3QkSW50ZjEuZmllbGQyIikpIHsKKyAgICAgICAgICAgICAgICBleHBlY3RlZCA9IGZpZWxkOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChleHBlY3RlZCA9PSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IGdldEZpZWxkcygpIGRpZCBub3QgcmV0dXJuIGFsbCBmaWVsZHMuIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDY6IEluY29ycmVjdCBmaWVsZDsiLCBleHBlY3RlZCwKKyAgICAgICAgICAgICAgICBDbHMzLmNsYXNzLmdldEZpZWxkKCJmaWVsZDIiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRGaWVsZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmllbGQgZXhwZWN0ZWQgPSBudWxsOworICAgICAgICBGaWVsZFtdIGZpZWxkcyA9IENsczIuY2xhc3MuZ2V0RmllbGRzKCk7CisgICAgICAgIGZvciAoRmllbGQgZmllbGQgOiBmaWVsZHMpIHsKKyAgICAgICAgICAgIGlmKGZpZWxkLnRvU3RyaW5nKCkuZXF1YWxzKCJwdWJsaWMgaW50IGxpYmNvcmUuamF2YS5sYW5nLk9sZENsYXNzVGVzdCRDbHMyLmZpZWxkMSIpKSB7CisgICAgICAgICAgICAgICAgZXhwZWN0ZWQgPSBmaWVsZDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoZXhwZWN0ZWQgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbCgiZ2V0RmllbGRzKCkgZGlkIG5vdCByZXR1cm4gYWxsIGZpZWxkcyIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwgQ2xzMi5jbGFzcy5nZXRGaWVsZCgiZmllbGQxIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW50ZXJmYWNlcygpIHsKKyAgICAgICAgQ2xhc3MgW10gaW50ZXJmYWNlczEgPSBDbHMxLmNsYXNzLmdldEludGVyZmFjZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGludGVyZmFjZXMxLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscyhJbnRmMi5jbGFzcywgaW50ZXJmYWNlczFbMF0pOworCisgICAgICAgIENsYXNzIFtdIGludGVyZmFjZXMyID0gQ2xzMi5jbGFzcy5nZXRJbnRlcmZhY2VzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBpbnRlcmZhY2VzMi5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoSW50ZjEuY2xhc3MsIGludGVyZmFjZXMyWzBdKTsKKworICAgICAgICBDbGFzcyBbXSBpbnRlcmZhY2VzMyA9IENsczMuY2xhc3MuZ2V0SW50ZXJmYWNlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgaW50ZXJmYWNlczMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEludGYzLmNsYXNzLCBpbnRlcmZhY2VzM1swXSk7CisgICAgICAgIGFzc2VydEVxdWFscyhJbnRmNC5jbGFzcywgaW50ZXJmYWNlczNbMV0pOworCisgICAgICAgIENsYXNzIFtdIGludGVyZmFjZXM0ID0gQ2xzNC5jbGFzcy5nZXRJbnRlcmZhY2VzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBpbnRlcmZhY2VzNC5sZW5ndGgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TWV0aG9kcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBudW1iZXIgb2YgbWV0aG9kcyIsIDEwLAorICAgICAgICAgICAgICAgIENsczIuY2xhc3MuZ2V0TWV0aG9kcygpLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IG51bWJlciBvZiBtZXRob2RzIiwgMTEsCisgICAgICAgICAgICAgICAgQ2xzMy5jbGFzcy5nZXRNZXRob2RzKCkubGVuZ3RoKTsKKworICAgICAgICBNZXRob2QgZXhwZWN0ZWQgPSBudWxsOworICAgICAgICBNZXRob2RbXSBtZXRob2RzID0gQ2xzMi5jbGFzcy5nZXRNZXRob2RzKCk7CisgICAgICAgIGZvciAoTWV0aG9kIG1ldGhvZCA6IG1ldGhvZHMpIHsKKyAgICAgICAgICAgIGlmKG1ldGhvZC50b1N0cmluZygpLmVxdWFscygicHVibGljIHZvaWQgbGliY29yZS5qYXZhLmxhbmcuT2xkQ2xhc3NUZXN0JENsczIudGVzdCgpIikpIHsKKyAgICAgICAgICAgICAgICBleHBlY3RlZCA9IG1ldGhvZDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoZXhwZWN0ZWQgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbCgiZ2V0TWV0aG9kcygpIGRpZCBub3QgcmV0dXJuIGFsbCBtZXRob2RzIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBDbHMyLmNsYXNzLmdldE1ldGhvZCgidGVzdCIpKTsKKworICAgICAgICBleHBlY3RlZCA9IG51bGw7CisgICAgICAgIG1ldGhvZHMgPSBDbHMzLmNsYXNzLmdldE1ldGhvZHMoKTsKKyAgICAgICAgZm9yIChNZXRob2QgbWV0aG9kIDogbWV0aG9kcykgeworICAgICAgICAgICAgaWYobWV0aG9kLnRvU3RyaW5nKCkuZXF1YWxzKCJwdWJsaWMgdm9pZCBsaWJjb3JlLmphdmEubGFuZy5PbGRDbGFzc1Rlc3QkQ2xzMy50ZXN0KCkiKSkgeworICAgICAgICAgICAgICAgIGV4cGVjdGVkID0gbWV0aG9kOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChleHBlY3RlZCA9PSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKCJnZXRNZXRob2RzKCkgZGlkIG5vdCByZXR1cm4gYWxsIG1ldGhvZHMiKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIENsczMuY2xhc3MuZ2V0TWV0aG9kKCJ0ZXN0IikpOworCisgICAgICAgIGV4cGVjdGVkID0gbnVsbDsKKyAgICAgICAgbWV0aG9kcyA9IENsczMuY2xhc3MuZ2V0TWV0aG9kcygpOworICAgICAgICBmb3IgKE1ldGhvZCBtZXRob2QgOiBtZXRob2RzKSB7CisgICAgICAgICAgICBpZihtZXRob2QudG9TdHJpbmcoKS5lcXVhbHMoInB1YmxpYyB2b2lkIGxpYmNvcmUuamF2YS5sYW5nLk9sZENsYXNzVGVzdCRDbHMzLnRlc3QyKGludCwiCisgICAgICAgICAgICAgICAgICAgICsgImphdmEubGFuZy5PYmplY3QpIikpIHsKKyAgICAgICAgICAgICAgICBleHBlY3RlZCA9IG1ldGhvZDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoZXhwZWN0ZWQgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbCgiZ2V0TWV0aG9kcygpIGRpZCBub3QgcmV0dXJuIGFsbCBtZXRob2RzIik7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIENsczMuY2xhc3MuZ2V0TWV0aG9kKCJ0ZXN0MiIsIGludC5jbGFzcywKKyAgICAgICAgICAgICAgICBPYmplY3QuY2xhc3MpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBudW1iZXIgb2YgbWV0aG9kcyIsIDEsCisgICAgICAgICAgICAgICAgSW50ZjUuY2xhc3MuZ2V0TWV0aG9kcygpLmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRSZXNvdXJjZUxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICBhc3NlcnROdWxsKGdldENsYXNzKCkuZ2V0UmVzb3VyY2UoCisgICAgICAgICAgICAgICAgImxpYmNvcmUvamF2YS9sYW5nL05vbkV4aXN0ZW50UmVzb3VyY2UiKSk7CisgICAgICAgIGFzc2VydE51bGwoZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZShnZXRDbGFzcygpLmdldE5hbWUoKSArICJOb25FeGlzdGVudFJlc291cmNlIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UmVzb3VyY2VBc1N0cmVhbUxqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBuYW1lID0gIi9IZWxsb1dvcmxkLnR4dCI7CisgICAgICAgIGFzc2VydE5vdE51bGwoInRoZSBmaWxlICIgKyBuYW1lICsgIiBjYW4gbm90IGJlIGZvdW5kIGluIHRoaXMgIiArCisgICAgICAgICAgICAgICAgImRpcmVjdG9yeSIsIGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbShuYW1lKSk7CisKKyAgICAgICAgZmluYWwgU3RyaW5nIG5hbWVCYWRVUkkgPSAib3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvdGVzdF9yZXNvdXJjZS50eHQiOworICAgICAgICBhc3NlcnROdWxsKCJ0aGUgZmlsZSAiICsgbmFtZUJhZFVSSSArICIgc2hvdWxkIG5vdCBiZSBmb3VuZCBpbiB0aGlzIGRpcmVjdG9yeSIsCisgICAgICAgICAgICAgICAgZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKG5hbWVCYWRVUkkpKTsKKworICAgICAgICBDbGFzc0xvYWRlciBwY2wgPSBnZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCk7CisgICAgICAgIENsYXNzPD8+IGNsYXp6ID0gcGNsLmxvYWRDbGFzcygibGliY29yZS5qYXZhLmxhbmcuT2xkQ2xhc3NUZXN0Iik7CisgICAgICAgIGFzc2VydE5vdE51bGwoY2xhenouZ2V0UmVzb3VyY2VBc1N0cmVhbSgiSGVsbG9Xb3JsZDEudHh0IikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0obnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0Fzc2lnbmFibGVGcm9tTGphdmFfbGFuZ19DbGFzcygpIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoInJldHVybmVkIHRydWUgbm90IGFzc2lnbmFibGUgY2xhc3NlcyIsCisgICAgICAgICAgICAgICAgSW50ZWdlci5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKFN0cmluZy5jbGFzcykpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSdW5uYWJsZS5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbmV3SW5zdGFuY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRlc3RDbGFzczMuY2xhc3MubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uICBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUZXN0Q2xhc3MxQy5jbGFzcy5uZXdJbnN0YW5jZSgpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uSW5Jbml0aWFsaXplckVycm9yIHNob3VsZCBiZSB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKGphdmEubGFuZy5FeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3IgaWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYXNTdWJjbGFzczEoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhFeHRlbmRUZXN0Q2xhc3MuY2xhc3MsCisgICAgICAgICAgICAgICAgRXh0ZW5kVGVzdENsYXNzLmNsYXNzLmFzU3ViY2xhc3MoUHVibGljVGVzdENsYXNzLmNsYXNzKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFB1YmxpY1Rlc3RDbGFzcy5jbGFzcywKKyAgICAgICAgICAgICAgICBQdWJsaWNUZXN0Q2xhc3MuY2xhc3MuYXNTdWJjbGFzcyhUZXN0SW50ZXJmYWNlLmNsYXNzKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEV4dGVuZFRlc3RDbGFzczEuY2xhc3MsCisgICAgICAgICAgICAgICAgRXh0ZW5kVGVzdENsYXNzMS5jbGFzcy5hc1N1YmNsYXNzKFB1YmxpY1Rlc3RDbGFzcy5jbGFzcykpOworCisgICAgICAgIGFzc2VydEVxdWFscyhQdWJsaWNUZXN0Q2xhc3MuY2xhc3MsCisgICAgICAgICAgICAgICAgUHVibGljVGVzdENsYXNzLmNsYXNzLmFzU3ViY2xhc3MoUHVibGljVGVzdENsYXNzLmNsYXNzKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9hc1N1YmNsYXNzMigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFB1YmxpY1Rlc3RDbGFzcy5jbGFzcy5hc1N1YmNsYXNzKEV4dGVuZFRlc3RDbGFzcy5jbGFzcyk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IENsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaChDbGFzc0Nhc3RFeGNlcHRpb24gY2NlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQdWJsaWNUZXN0Q2xhc3MuY2xhc3MuYXNTdWJjbGFzcyhTdHJpbmcuY2xhc3MpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBDbGFzc0Nhc3RFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2goQ2xhc3NDYXN0RXhjZXB0aW9uIGNjZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nhc3QoKSB7CisgICAgICAgIE9iamVjdCBvID0gUHVibGljVGVzdENsYXNzLmNsYXNzLmNhc3QobmV3IEV4dGVuZFRlc3RDbGFzcygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShvIGluc3RhbmNlb2YgRXh0ZW5kVGVzdENsYXNzKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgRXh0ZW5kVGVzdENsYXNzLmNsYXNzLmNhc3QobmV3IFB1YmxpY1Rlc3RDbGFzcygpKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoKENsYXNzQ2FzdEV4Y2VwdGlvbiBjY2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFeHRlbmRUZXN0Q2xhc3MuY2xhc3MuY2FzdChuZXcgU3RyaW5nKCkpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goQ2xhc3NDYXN0RXhjZXB0aW9uIGNjZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9kZXNpcmVkQXNzZXJ0aW9uU3RhdHVzKCkgeworICAgICAgQ2xhc3MgW10gY2xhc3NBcnJheSA9IHsgT2JqZWN0LmNsYXNzLCBJbnRlZ2VyLmNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nLmNsYXNzLCBQdWJsaWNUZXN0Q2xhc3MuY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbmRUZXN0Q2xhc3MuY2xhc3MsIEV4dGVuZFRlc3RDbGFzczEuY2xhc3N9OworCisgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgY2xhc3NBcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgIGFzc2VydEZhbHNlKCJhc3NlcnRpb24gc3RhdHVzIGZvciAiICsgY2xhc3NBcnJheVtpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NBcnJheVtpXS5kZXNpcmVkQXNzZXJ0aW9uU3RhdHVzKCkpOworICAgICAgfQorICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFJlc291cmNlQXNTdHJlYW0xKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQ2xhc3MgY2xhenogPSBnZXRDbGFzcygpOworCisgICAgICAgIElucHV0U3RyZWFtIHN0cmVhbSA9IGNsYXp6LmdldFJlc291cmNlQXNTdHJlYW0oIkhlbGxvV29ybGQudHh0Iik7CisgICAgICAgIGFzc2VydChzdHJlYW0gIT0gbnVsbCk7CisKKyAgICAgICAgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlWzIwXTsKKyAgICAgICAgaW50IGxlbmd0aCA9IHN0cmVhbS5yZWFkKGJ1ZmZlcik7CisgICAgICAgIFN0cmluZyBzID0gbmV3IFN0cmluZyhidWZmZXIsIDAsIGxlbmd0aCk7CisgICAgICAgIGFzc2VydCgiSGVsbG8sIFdvcmxkLiIuZXF1YWxzKHMpKTsKKworICAgICAgICBzdHJlYW0uY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UmVzb3VyY2VBc1N0cmVhbTIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBDbGFzcyBjbGF6eiA9IGdldENsYXNzKCk7CisKKyAgICAgICAgSW5wdXRTdHJlYW0gc3RyZWFtID0gY2xhenouZ2V0UmVzb3VyY2VBc1N0cmVhbSgiL2xpYmNvcmUvamF2YS9sYW5nL0hlbGxvV29ybGQudHh0Iik7CisgICAgICAgIGFzc2VydChzdHJlYW0gIT0gbnVsbCk7CisKKyAgICAgICAgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlWzIwXTsKKyAgICAgICAgaW50IGxlbmd0aCA9IHN0cmVhbS5yZWFkKGJ1ZmZlcik7CisgICAgICAgIFN0cmluZyBzID0gbmV3IFN0cmluZyhidWZmZXIsIDAsIGxlbmd0aCk7CisgICAgICAgIGFzc2VydCgiSGVsbG8sIFdvcmxkLiIuZXF1YWxzKHMpKTsKKworICAgICAgICBzdHJlYW0uY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2xhenouZ2V0UmVzb3VyY2VBc1N0cmVhbShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0TnVsbChjbGF6ei5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvTm9uRXhpc3RlbnRSZXNvdXJjZSIpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjbGF6ei5nZXRSZXNvdXJjZUFzU3RyZWFtKCJsaWJjb3JlL2phdmEvbGFuZy9IZWxsb1dvcmxkLnR4dCIpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkRG91YmxlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZERvdWJsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYWNiNTIxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZERvdWJsZVRlc3QuamF2YQpAQCAtMCwwICsxLDc5IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkRG91YmxlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYnl0ZVZhbHVlKCkgeworICAgICAgICBEb3VibGUgZCA9IG5ldyBEb3VibGUoQnl0ZS5NQVhfVkFMVUUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBieXRlIHZhbHVlIiwgQnl0ZS5NQVhfVkFMVUUsIGQuYnl0ZVZhbHVlKCkpOworICAgICAgICBkPSBuZXcgRG91YmxlKEJ5dGUuTUlOX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgYnl0ZSB2YWx1ZSIsIEJ5dGUuTUlOX1ZBTFVFLCBkLmJ5dGVWYWx1ZSgpKTsKKyAgICAgICAgZD0gbmV3IERvdWJsZShEb3VibGUuTUFYX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgYnl0ZSB2YWx1ZSIsIC0xLCBkLmJ5dGVWYWx1ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RvdWJsZVRvTG9uZ0JpdHNEKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoMHg3ZmY4MDAwMDAwMDAwMDAwTCwgRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoRG91YmxlLk5hTikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHg3ZmYwMDAwMDAwMDAwMDAwTCwgRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoRG91YmxlLlBPU0lUSVZFX0lORklOSVRZKSk7CisgICAgICAgIGFzc2VydEVxdWFscygweGZmZjAwMDAwMDAwMDAwMDBMLCBEb3VibGUuZG91YmxlVG9Mb25nQml0cyhEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RvdWJsZVRvUmF3TG9uZ0JpdHNEKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoMHg3ZmY4MDAwMDAwMDAwMDAwTCwgRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoRG91YmxlLk5hTikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHg3ZmYwMDAwMDAwMDAwMDAwTCwgRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoRG91YmxlLlBPU0lUSVZFX0lORklOSVRZKSk7CisgICAgICAgIGFzc2VydEVxdWFscygweGZmZjAwMDAwMDAwMDAwMDBMLCBEb3VibGUuZG91YmxlVG9Mb25nQml0cyhEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RvdWJsZVZhbHVlKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCBuZXcgRG91YmxlKCIxLjc5NzY5MzEzNDg2MjMxNTlFMzA4IikuZG91YmxlVmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFksIG5ldyBEb3VibGUoIi0xLjc5NzY5MzEzNDg2MjMxNTlFMzA4IikuZG91YmxlVmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuTUFYX1ZBTFVFLCBuZXcgRG91YmxlKCIxLjc5NzY5MzEzNDg2MjMxNTdFMzA4IikuZG91YmxlVmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhEb3VibGUuTUlOX1ZBTFVFLCBuZXcgRG91YmxlKCI0LjlFLTMyNCIpLmRvdWJsZVZhbHVlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmxvYXRWYWx1ZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEZsb2F0LlBPU0lUSVZFX0lORklOSVRZLCBuZXcgRG91YmxlKCIzLjQwMjgyMzZFMzgiKS5mbG9hdFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFksIG5ldyBEb3VibGUoIi0zLjQwMjgyMzZFMzgiKS5mbG9hdFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRmxvYXQuTUFYX1ZBTFVFLCBuZXcgRG91YmxlKCIzLjQwMjgyMzVFMzgiKS5mbG9hdFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRmxvYXQuTUlOX1ZBTFVFLCBuZXcgRG91YmxlKCIxLjRFLTQ1IikuZmxvYXRWYWx1ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ludFZhbHVlKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBpbnQgdmFsdWUiLCBJbnRlZ2VyLk1BWF9WQUxVRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IERvdWJsZSgyMTQ3NDgzNjQ4ZCkuaW50VmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGludCB2YWx1ZSIsIEludGVnZXIuTUlOX1ZBTFVFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBEb3VibGUoLTIxNDc0ODM2NDlkKS5pbnRWYWx1ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzTmFORCgpIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkRvZXNuJ3QgcmV0dXJuIGZhbHNlIHZhbHVlIiwgRG91YmxlLmlzTmFOKG5ldyBEb3VibGUoRG91YmxlLk1BWF9WQUxVRSkpKTsKKyAgICB9CisKKyAgICAvLyBSZWdyZXNzaW9uIHRlc3QgZm9yIGhvdGZpeCBpbiBuYXRpdmUgY29kZSBvZiBkb3VibGUgcGFyc2VyLgorICAgIHB1YmxpYyB2b2lkIHRlc3RfcGFyc2VEb3VibGVfTFN0cmluZ19BbmRyb2lkUmVncmVzc2lvbigpIHsKKyAgICAgICAgLy8gQW5kcm9pZCByZWdyZXNzaW9uIHRlc3QKKyAgICAgICAgbG9uZyBzdGFydFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgZG91YmxlIGFjdHVhbCA9IERvdWJsZS5wYXJzZURvdWJsZSgiOWU1NTEwMjciKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgicGFyc2luZyBkb3VibGUgOWU1NTEwMjcgdG9vayB0b28gbG9uZy4iLAorICAgICAgICAgICAgICAgIChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0VGltZSkgPCAxMDAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksCisgICAgICAgICAgICAgICAgYWN0dWFsLCAwLjBEKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkRmxvYXRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkRmxvYXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWJiYWMxMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRGbG9hdFRlc3QuamF2YQpAQCAtMCwwICsxLDkyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkRmxvYXRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEZsb2F0KCI5MDAuODlmZiIpOworICAgICAgICAgICAgZmFpbCgiTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVtYmVyRm9ybWF0RXhjZXB0aW9uIG5mZSkgeworICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yRCgpIHsKKyAgICAgICAgRmxvYXQgZiA9IG5ldyBGbG9hdChEb3VibGUuTUFYX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ3JlYXRlZCBpbmNvcnJlY3QgZmxvYXQiLCBmLmZsb2F0VmFsdWUoKSA9PSBGbG9hdC5QT1NJVElWRV9JTkZJTklUWSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9wYXJzZUZsb2F0TEV4Y2VwdGlvbnMoKSB7CisgICAgICAgIFN0cmluZyBbXSBpbmNvcnJlY3RTdHJpbmdzID0geyIiLCAiOyIsICI5OTk5OTk5OUVFOTk5OTk5IiwgIjk5OTk5bCIsCisgICAgICAgICAgICAgICAgICIweDEuZi5mZmZmZXAxMjcifTsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGluY29ycmVjdFN0cmluZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgRmxvYXQucGFyc2VGbG9hdChpbmNvcnJlY3RTdHJpbmdzW2ldKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOdW1iZXJGb3JtYXRFeGNlcHRpb24gaXMgbm90IHRocm93biBmb3Igc3RyaW5nOiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIGluY29ycmVjdFN0cmluZ3NbaV0pOworICAgICAgICAgICAgfSBjYXRjaChOdW1iZXJGb3JtYXRFeGNlcHRpb24gbmZlKSB7CisgICAgICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9mbG9hdFRvSW50Qml0c0YoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygweDdmODAwMDAwLCBGbG9hdC5mbG9hdFRvSW50Qml0cyhGbG9hdC5QT1NJVElWRV9JTkZJTklUWSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHhmZjgwMDAwMCwgRmxvYXQuZmxvYXRUb0ludEJpdHMoRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4N2ZjMDAwMDAsIEZsb2F0LmZsb2F0VG9JbnRCaXRzKEZsb2F0Lk5hTikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmxvYXRUb1Jhd0ludEJpdHNGKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoMHg3ZjgwMDAwMCwgRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMoRmxvYXQuUE9TSVRJVkVfSU5GSU5JVFkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4ZmY4MDAwMDAsIEZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKEZsb2F0Lk5FR0FUSVZFX0lORklOSVRZKSk7CisgICAgICAgIGFzc2VydEVxdWFscygweDdmYzAwMDAwLCBGbG9hdC5mbG9hdFRvUmF3SW50Qml0cyhGbG9hdC5OYU4pKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc2hDb2RlKCkgeworICAgICAgICBhc3NlcnRUcnVlKG5ldyBGbG9hdChGbG9hdC5NQVhfVkFMVUUpLmhhc2hDb2RlKCkgIT0gbmV3IEZsb2F0KEZsb2F0Lk1JTl9WQUxVRSkuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pbnRCaXRzVG9GbG9hdEkoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhGbG9hdC5QT1NJVElWRV9JTkZJTklUWSwgRmxvYXQuaW50Qml0c1RvRmxvYXQoMHg3ZjgwMDAwMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFksIEZsb2F0LmludEJpdHNUb0Zsb2F0KDB4ZmY4MDAwMDApKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoRmxvYXQuTmFOLCBGbG9hdC5pbnRCaXRzVG9GbG9hdCgweDdmODAwMDAxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhGbG9hdC5OYU4sIEZsb2F0LmludEJpdHNUb0Zsb2F0KDB4N2ZmZmZmZmYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEZsb2F0Lk5hTiwgRmxvYXQuaW50Qml0c1RvRmxvYXQoMHhmZjgwMDAwMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRmxvYXQuTmFOLCBGbG9hdC5pbnRCaXRzVG9GbG9hdCgweGZmZmZmZmZmKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pbnRWYWx1ZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEludGVnZXIuTUFYX1ZBTFVFLCBuZXcgRmxvYXQoRmxvYXQuTUFYX1ZBTFVFKS5pbnRWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG5ldyBGbG9hdChGbG9hdC5NSU5fVkFMVUUpLmludFZhbHVlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNOYU5GKCkgeworICAgICAgICBhc3NlcnRGYWxzZShGbG9hdC5pc05hTigxMi4wOWYpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoRmxvYXQuaXNOYU4oRmxvYXQuTUFYX1ZBTFVFKSk7CisgICAgICAgIGFzc2VydEZhbHNlKEZsb2F0LmlzTmFOKEZsb2F0Lk1JTl9WQUxVRSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbG9uZ1ZhbHVlKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoTG9uZy5NQVhfVkFMVUUsIG5ldyBGbG9hdChGbG9hdC5NQVhfVkFMVUUpLmxvbmdWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG5ldyBGbG9hdChGbG9hdC5NSU5fVkFMVUUpLmxvbmdWYWx1ZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkSW5oZXJpdGFibGVUaHJlYWRMb2NhbFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRJbmhlcml0YWJsZVRocmVhZExvY2FsVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRkOWI5ZjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkSW5oZXJpdGFibGVUaHJlYWRMb2NhbFRlc3QuamF2YQpAQCAtMCwwICsxLDY2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkSW5oZXJpdGFibGVUaHJlYWRMb2NhbFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0xqYXZhX2xhbmdfSW5oZXJpdGFibGVUaHJlYWRMb2NhbCgpCisgICAgICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBmaW5hbCBPYmplY3QgdmFsdWUgPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIGZpbmFsIE9iamVjdCBpbmhlcml0ZWRWYWx1ZSA9IG5ldyBPYmplY3QoKTsKKyAgICAgICAgZmluYWwgVGhyZWFkTG9jYWw8T2JqZWN0PiB0aHJlYWRMb2NhbAorICAgICAgICAgICAgICAgID0gbmV3IEluaGVyaXRhYmxlVGhyZWFkTG9jYWw8T2JqZWN0PigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHJvdGVjdGVkIE9iamVjdCBjaGlsZFZhbHVlKE9iamVjdCBwYXJlbnRWYWx1ZSkgeworICAgICAgICAgICAgICAgIGFzc2VydFNhbWUodmFsdWUsIHBhcmVudFZhbHVlKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gaW5oZXJpdGVkVmFsdWU7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIHRocmVhZExvY2FsLnNldCh2YWx1ZSk7CisgICAgICAgIGZpbmFsIE9iamVjdFtdIGhvbGRlciA9IG5ldyBPYmplY3RbMV07CisgICAgICAgIFRocmVhZCB0aHJlYWQgPSBuZXcgVGhyZWFkKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIGhvbGRlclswXSA9IHRocmVhZExvY2FsLmdldCgpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICB0aHJlYWQuc3RhcnQoKTsKKyAgICAgICAgdGhyZWFkLmpvaW4oKTsKKyAgICAgICAgYXNzZXJ0U2FtZSh2YWx1ZSwgdGhyZWFkTG9jYWwuZ2V0KCkpOworICAgICAgICBhc3NlcnRTYW1lKGluaGVyaXRlZFZhbHVlLCBob2xkZXJbMF0pOworCisgICAgICAgIC8vIENsZWFudXAgcHJvcGVybHksIHNvIG90aGVyIHRlc3RzIGFyZSBub3QgYWZmZWN0ZWQuCisgICAgICAgIHRocmVhZExvY2FsLnJlbW92ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2hpbGRWYWx1ZSgpIHsKKyAgICAgICAgSW5oZXJpdGFibGVUaHJlYWRMb2NhbDxTdHJpbmc+IGl0bCA9IG5ldyBJbmhlcml0YWJsZVRocmVhZExvY2FsPFN0cmluZz4oKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHByb3RlY3RlZCBTdHJpbmcgaW5pdGlhbFZhbHVlKCkgeworICAgICAgICAgICAgICAgIHJldHVybiAiaW5pdGlhbCI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHByb3RlY3RlZCBTdHJpbmcgY2hpbGRWYWx1ZShTdHJpbmcgcGFyZW50VmFsdWUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gImNoaWxkVmFsdWUiOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBhc3NlcnRFcXVhbHMoImluaXRpYWwiLCBpdGwuZ2V0KCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZEludGVnZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkSW50ZWdlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NjJlZTE5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZEludGVnZXJUZXN0LmphdmEKQEAgLTAsMCArMSw2OSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZzsKKworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZEludGVnZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHByaXZhdGUgUHJvcGVydGllcyBvcmdQcm9wczsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICBvcmdQcm9wcyA9IFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0aWVzKG9yZ1Byb3BzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEludGVnZXJMamF2YV9sYW5nX1N0cmluZ0koKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuSW50ZWdlcgorICAgICAgICAvLyBqYXZhLmxhbmcuSW50ZWdlci5nZXRJbnRlZ2VyKGphdmEubGFuZy5TdHJpbmcsIGludCkKKyAgICAgICAgUHJvcGVydGllcyB0UHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICB0UHJvcHMucHV0KCJ0ZXN0SW5jSW50IiwgIm5vdEludCIpOworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydGllcyh0UHJvcHMpOworICAgICAgICBhc3NlcnRUcnVlKCJyZXR1cm5lZCBpbmNvcnJlY3QgZGVmYXVsdCBJbnRlZ2VyIiwgSW50ZWdlci5nZXRJbnRlZ2VyKAorICAgICAgICAgICAgICAgICJ0ZXN0SW5jSW50IiwgNCkuZXF1YWxzKG5ldyBJbnRlZ2VyKDQpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnRlZ2VyTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX0ludGVnZXIoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuSW50ZWdlcgorICAgICAgICAvLyBqYXZhLmxhbmcuSW50ZWdlci5nZXRJbnRlZ2VyKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyKQorICAgICAgICBQcm9wZXJ0aWVzIHRQcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgIHRQcm9wcy5wdXQoInRlc3RJbmNJbnQiLCAibm90SW50Iik7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0aWVzKHRQcm9wcyk7CisgICAgICAgIGFzc2VydFRydWUoInJldHVybmVkIGluY29ycmVjdCBkZWZhdWx0IEludGVnZXIiLCBJbnRlZ2VyLmdldEludGVnZXIoCisgICAgICAgICAgICAgICAgInRlc3RJbmNJbnQiLCBuZXcgSW50ZWdlcig0KSkuZXF1YWxzKG5ldyBJbnRlZ2VyKDQpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pbnRWYWx1ZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEludGVnZXIuTUFYX1ZBTFVFLCBuZXcgSW50ZWdlcihJbnRlZ2VyLk1BWF9WQUxVRSkuaW50VmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLk1JTl9WQUxVRSwgbmV3IEludGVnZXIoSW50ZWdlci5NSU5fVkFMVUUpLmludFZhbHVlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbG9uZ1ZhbHVlKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoSW50ZWdlci5NQVhfVkFMVUUsIG5ldyBJbnRlZ2VyKEludGVnZXIuTUFYX1ZBTFVFKS5sb25nVmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLk1JTl9WQUxVRSwgbmV3IEludGVnZXIoSW50ZWdlci5NSU5fVkFMVUUpLmxvbmdWYWx1ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Nob3J0VmFsdWUoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgbmV3IEludGVnZXIoSW50ZWdlci5NQVhfVkFMVUUpLnNob3J0VmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBuZXcgSW50ZWdlcihJbnRlZ2VyLk1JTl9WQUxVRSkuc2hvcnRWYWx1ZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkTG9uZ1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRMb25nVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZmYjdkNDkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkTG9uZ1Rlc3QuamF2YQpAQCAtMCwwICsxLDgzIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkTG9uZ1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHJpdmF0ZSBQcm9wZXJ0aWVzIG9yZ1Byb3BzOworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIG9yZ1Byb3BzID0gU3lzdGVtLmdldFByb3BlcnRpZXMoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnRpZXMob3JnUHJvcHMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TG9uZ0xqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICBQcm9wZXJ0aWVzIHRQcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgIHRQcm9wcy5wdXQoInRlc3RMb25nIiwgIjk5Iik7CisgICAgICAgIHRQcm9wcy5wdXQoInRlc3RJbmNMb25nIiwgInN0cmluZyIpOworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydGllcyh0UHJvcHMpOworICAgICAgICBhc3NlcnROdWxsKCJyZXR1cm5lZCBpbmNvcnJlY3QgZGVmYXVsdCBMb25nIiwKKyAgICAgICAgICAgICAgICBMb25nLmdldExvbmcoInRlc3RJbmNMb25nIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TG9uZ0xqYXZhX2xhbmdfU3RyaW5nSigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5Mb25nCisgICAgICAgIC8vIGphdmEubGFuZy5Mb25nLmdldExvbmcoamF2YS5sYW5nLlN0cmluZywgbG9uZykKKyAgICAgICAgUHJvcGVydGllcyB0UHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICB0UHJvcHMucHV0KCJ0ZXN0SW5jTG9uZyIsICJzdHJpbmciKTsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnRpZXModFByb3BzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgicmV0dXJuZWQgaW5jb3JyZWN0IGRlZmF1bHQgTG9uZyIsIExvbmcuZ2V0TG9uZygidGVzdEluY0xvbmciLCA0TCkKKyAgICAgICAgICAgICAgICAuZXF1YWxzKG5ldyBMb25nKDQpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRMb25nTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX0xvbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuTG9uZworICAgICAgICAvLyBqYXZhLmxhbmcuTG9uZy5nZXRMb25nKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nKQorICAgICAgICBQcm9wZXJ0aWVzIHRQcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgIHRQcm9wcy5wdXQoInRlc3RJbmNMb25nIiwgInN0cmluZyIpOworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydGllcyh0UHJvcHMpOworICAgICAgICBhc3NlcnRUcnVlKCJyZXR1cm5lZCBpbmNvcnJlY3QgZGVmYXVsdCBMb25nIiwgTG9uZy5nZXRMb25nKCJ0ZXN0SW5jTG9uZyIsCisgICAgICAgICAgICAgICAgbmV3IExvbmcoNCkpLmVxdWFscyhuZXcgTG9uZyg0KSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmxvYXRWYWx1ZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExvbmcuTUFYX1ZBTFVFLCBuZXcgTG9uZyhMb25nLk1BWF9WQUxVRSkuZmxvYXRWYWx1ZSgpLCAwRik7CisgICAgICAgIGFzc2VydEVxdWFscyhMb25nLk1JTl9WQUxVRSwgbmV3IExvbmcoTG9uZy5NSU5fVkFMVUUpLmZsb2F0VmFsdWUoKSwgMEYpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW50VmFsdWUoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgbmV3IExvbmcoTG9uZy5NQVhfVkFMVUUpLmludFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbmV3IExvbmcoTG9uZy5NSU5fVkFMVUUpLmludFZhbHVlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbG9uZ1ZhbHVlKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoTG9uZy5NQVhfVkFMVUUsIG5ldyBMb25nKExvbmcuTUFYX1ZBTFVFKS5sb25nVmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhMb25nLk1JTl9WQUxVRSwgbmV3IExvbmcoTG9uZy5NSU5fVkFMVUUpLmxvbmdWYWx1ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Nob3J0VmFsdWUoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgbmV3IExvbmcoTG9uZy5NQVhfVkFMVUUpLnNob3J0VmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBuZXcgTG9uZyhMb25nLk1JTl9WQUxVRSkuc2hvcnRWYWx1ZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkT2JqZWN0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZE9iamVjdFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wODQ3MWIyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZE9iamVjdFRlc3QuamF2YQpAQCAtMCwwICsxLDIxOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5TaWRlRWZmZWN0OworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkT2JqZWN0VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyBib29sZWFuIGlzQ2FsbGVkID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IG9iamVjdHMuCisgICAgICovCisgICAgT2JqZWN0IG9iajEgPSBuZXcgT2JqZWN0KCk7CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmljIHN0YXRlIGluZGljYXRvci4KKyAgICAgKi8KKyAgICBpbnQgc3RhdHVzID0gMDsKKworICAgIGludCByZWFkeSA9IDA7CisgICAgVGVzdFRocmVhZDEgdGhyMTsKKyAgICBUZXN0VGhyZWFkMiB0aHIyOworCisgICAgcHVibGljIHZvaWQgdGVzdF9jbG9uZSgpIHsKKyAgICAgICAgTW9ja0Nsb25lYWJsZU9iamVjdCBtY28gPSBuZXcgTW9ja0Nsb25lYWJsZU9iamVjdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UobWNvLmVxdWFscyhtY28uY2xvbmUoKSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG1jby5nZXRDbGFzcygpLCBtY28uY2xvbmUoKS5nZXRDbGFzcygpKTsKKyAgICAgICAgfSBjYXRjaChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBjbnNlKSB7CisgICAgICAgICAgICBmYWlsKCJDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisKKyAgICAgICAgTW9ja09iamVjdCBtbyA9IG5ldyBNb2NrT2JqZWN0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtby5jbG9uZSgpOworICAgICAgICAgICAgZmFpbCgiQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgTW9ja0Nsb25lYWJsZU9iamVjdCBleHRlbmRzIE9iamVjdCBpbXBsZW1lbnRzIENsb25lYWJsZSB7CisgICAgICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBNb2NrT2JqZWN0IGV4dGVuZHMgT2JqZWN0IHsKKworICAgICAgICBib29sZWFuIGlzQ2FsbGVkID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgICAgIHN1cGVyLmZpbmFsaXplKCk7CisgICAgICAgICAgICBpc0NhbGxlZCA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9ub3RpZnkoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBPYmplY3Qgb2JqID0gbmV3IE9iamVjdCgpOworICAgICAgICAgICAgb2JqLm5vdGlmeSgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGltc2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfbm90aWZ5QWxsKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgT2JqZWN0IG9iaiA9IG5ldyBPYmplY3QoKTsKKyAgICAgICAgICAgIG9iai5ub3RpZnlBbGwoKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbiBpbXNlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dhaXQoKSB7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE9iamVjdCBvYmogPSBuZXcgT2JqZWN0KCk7CisgICAgICAgICAgICBvYmoud2FpdCgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGltc2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiSW50ZXJydXB0ZWRFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorCisgICAgICAgdHJ5IHsKKyAgICAgICAgICAgdGhyMSA9IG5ldyBUZXN0VGhyZWFkMShUZXN0VGhyZWFkMS5DQVNFX1dBSVQpOworICAgICAgICAgICB0aHIyID0gbmV3IFRlc3RUaHJlYWQyKCk7CisgICAgICAgICAgIHRocjEuc3RhcnQoKTsKKyAgICAgICAgICAgdGhyMi5zdGFydCgpOworICAgICAgICAgICB0aHIyLmpvaW4oKTsKKyAgICAgICAgICAgdGhyMS5qb2luKCk7CisgICAgICAgICAgIHRocjEgPSBudWxsOworICAgICAgICAgICB0aHIyID0gbnVsbDsKKyAgICAgICAgfSBjYXRjaChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygzLCBzdGF0dXMpOworICAgIH0KKworICAgIGNsYXNzIFRlc3RUaHJlYWQxIGV4dGVuZHMgVGhyZWFkIHsKKworICAgICAgICBzdGF0aWMgZmluYWwgaW50IENBU0VfV0FJVCA9IDA7CisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgQ0FTRV9XQUlUX0xPTkcgPSAxOworICAgICAgICBzdGF0aWMgZmluYWwgaW50IENBU0VfV0FJVF9MT05HX0lOVCA9IDI7CisKKyAgICAgICAgaW50IHRlc3RDYXNlID0gQ0FTRV9XQUlUOworCisgICAgICAgIHB1YmxpYyBUZXN0VGhyZWFkMShpbnQgb3B0aW9uKSB7CisgICAgICAgICAgICB0ZXN0Q2FzZSA9IG9wdGlvbjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAob2JqMSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN3aXRjaCh0ZXN0Q2FzZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBDQVNFX1dBSVQ6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqMS53YWl0KCk7Ly8gV2FpdCBmb3IgZXZlci4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ0FTRV9XQUlUX0xPTkc6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqMS53YWl0KDUwMDBMKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ0FTRV9XQUlUX0xPTkdfSU5UOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iajEud2FpdCgxMDAwMEwsIDk5OTk5OSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IDM7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgVGVzdFRocmVhZDIgZXh0ZW5kcyBUaHJlYWQgeworICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICB0aHIxLmludGVycnVwdCgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93YWl0SkkoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBPYmplY3Qgb2JqID0gbmV3IE9iamVjdCgpOworICAgICAgICAgICAgb2JqLndhaXQoNTAwMEwsIDEpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbE1vbml0b3JTdGF0ZUV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIGltc2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiSW50ZXJydXB0ZWRFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorCisgICAgICAgdHJ5IHsKKyAgICAgICAgICAgdGhyMSA9IG5ldyBUZXN0VGhyZWFkMShUZXN0VGhyZWFkMS5DQVNFX1dBSVRfTE9OR19JTlQpOworICAgICAgICAgICB0aHIyID0gbmV3IFRlc3RUaHJlYWQyKCk7CisgICAgICAgICAgIHRocjEuc3RhcnQoKTsKKyAgICAgICAgICAgdGhyMi5zdGFydCgpOworICAgICAgICAgICB0aHIyLmpvaW4oKTsKKyAgICAgICAgICAgdGhyMS5qb2luKCk7CisgICAgICAgICAgIHRocjEgPSBudWxsOworICAgICAgICAgICB0aHIyID0gbnVsbDsKKyAgICAgICAgfSBjYXRjaChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygzLCBzdGF0dXMpOworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93YWl0SigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE9iamVjdCBvYmogPSBuZXcgT2JqZWN0KCk7CisgICAgICAgICAgICBvYmoud2FpdCg1MDAwTCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxNb25pdG9yU3RhdGVFeGNlcHRpb24gaW1zZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisKKyAgICAgICB0cnkgeworICAgICAgICAgICB0aHIxID0gbmV3IFRlc3RUaHJlYWQxKFRlc3RUaHJlYWQxLkNBU0VfV0FJVF9MT05HKTsKKyAgICAgICAgICAgdGhyMiA9IG5ldyBUZXN0VGhyZWFkMigpOworICAgICAgICAgICB0aHIxLnN0YXJ0KCk7CisgICAgICAgICAgIHRocjIuc3RhcnQoKTsKKyAgICAgICAgICAgdGhyMi5qb2luKCk7CisgICAgICAgICAgIHRocjEuam9pbigpOworICAgICAgICAgICB0aHIxID0gbnVsbDsKKyAgICAgICAgICAgdGhyMiA9IG51bGw7CisgICAgICAgIH0gY2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSW50ZXJydXB0ZWRFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoMywgc3RhdHVzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkUnVudGltZUV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRSdW50aW1lRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgwMDQxMjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkUnVudGltZUV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDQ2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkUnVudGltZUV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTFN0cmluZ0xUaHJvd2FibGUoKSB7CisgICAgICAgIFN0cmluZyBtZXNzYWdlID0gIlRlc3QgbWVzc2FnZSI7CisgICAgICAgIE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSA9IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBSdW50aW1lRXhjZXB0aW9uIHJlID0gbmV3IFJ1bnRpbWVFeGNlcHRpb24obWVzc2FnZSwgbnBlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsIHJlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhucGUsIHJlLmdldENhdXNlKCkpOworCisgICAgICAgIHJlID0gbmV3IFJ1bnRpbWVFeGNlcHRpb24obnVsbCwgbnBlKTsKKyAgICAgICAgYXNzZXJ0TnVsbChyZS5nZXRNZXNzYWdlKCkpOworCisgICAgICAgIHJlID0gbmV3IFJ1bnRpbWVFeGNlcHRpb24obWVzc2FnZSwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwocmUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxUaHJvd2FibGUoKSB7CisgICAgICAgIE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSA9IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBSdW50aW1lRXhjZXB0aW9uIHJlID0gbmV3IFJ1bnRpbWVFeGNlcHRpb24obnBlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5wZSwgcmUuZ2V0Q2F1c2UoKSk7CisKKyAgICAgICAgcmUgPSBuZXcgUnVudGltZUV4Y2VwdGlvbigoVGhyb3dhYmxlKSBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChyZS5nZXRDYXVzZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkUnVudGltZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRSdW50aW1lVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRiNjkyZDcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkUnVudGltZVRlc3QuamF2YQpAQCAtMCwwICsxLDU1MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZzsKKworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLktub3duRmFpbHVyZTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LnJlc291cmNlLlN1cHBvcnRfUmVzb3VyY2VzOworCitwdWJsaWMgY2xhc3MgT2xkUnVudGltZVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgUnVudGltZSByID0gUnVudGltZS5nZXRSdW50aW1lKCk7CisKKyAgICBJbnB1dFN0cmVhbSBpczsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZnJlZU1lbW9yeSgpIHsKKyAgICAgICAgLy8gSGVhcCBtaWdodCBncm93IG9yIGRvIEdDIGF0IGFueSB0aW1lLAorICAgICAgICAvLyBzbyB3ZSBjYW4ndCByZWFsbHkgdGVzdCBhIGxvdC4gSGVuY2UKKyAgICAgICAgLy8gd2UgYXJlIGp1c3QgZG9pbmcgc29tZSBiYXNpYyBzYW5pdHkKKyAgICAgICAgLy8gY2hlY2tzIGhlcmUuCisgICAgICAgIGFzc2VydFRydWUoIm11c3QgaGF2ZSBzb21lIGZyZWUgbWVtb3J5IiwKKyAgICAgICAgICAgICAgICByLmZyZWVNZW1vcnkoKSA+IDApOworCisgICAgICAgIGFzc2VydFRydWUoIm11c3Qgbm90IGV4Y2VlZCB0b3RhbCBtZW1vcnkiLAorICAgICAgICAgICAgICAgIHIuZnJlZU1lbW9yeSgpIDwgci50b3RhbE1lbW9yeSgpKTsKKworICAgICAgICBsb25nIGJlZm9yZSA9IHIudG90YWxNZW1vcnkoKSAtIHIuZnJlZU1lbW9yeSgpOworICAgICAgICBWZWN0b3I8Ynl0ZVtdPiB2ID0gbmV3IFZlY3RvcjxieXRlW10+KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgMTA7IGkrKykgeworICAgICAgICAgICAgdi5hZGRFbGVtZW50KG5ldyBieXRlWzEwMDAwXSk7CisgICAgICAgIH0KKyAgICAgICAgbG9uZyBhZnRlciA9ICByLnRvdGFsTWVtb3J5KCkgLSByLmZyZWVNZW1vcnkoKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJmcmVlIG1lbW9yeSBtdXN0IGNoYW5nZSB3aXRoIGFsbG9jYXRpb25zIiwKKyAgICAgICAgICAgICAgICBhZnRlciAhPSBiZWZvcmUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UnVudGltZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5SdW50aW1lIGphdmEubGFuZy5SdW50aW1lLmdldFJ1bnRpbWUoKQorICAgICAgICBhc3NlcnROb3ROdWxsKFJ1bnRpbWUuZ2V0UnVudGltZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZFNodXRkb3duSG9vaygpIHsKKyAgICAgICAgVGhyZWFkIHRockV4Y2VwdGlvbiA9IG5ldyBUaHJlYWQgKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmFkZFNodXRkb3duSG9vayh0aGlzKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2goSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlzZSkgeworICAgICAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5hZGRTaHV0ZG93bkhvb2sodGhyRXhjZXB0aW9uKTsKKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgIGZhaWwodC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmFkZFNodXRkb3duSG9vayh0aHJFeGNlcHRpb24pOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAgaWFlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgU2VjdXJpdHlNYW5hZ2VyIHNtID0gbmV3IFNlY3VyaXR5TWFuYWdlcigpIHsKKworICAgICAgICAgICAgcHVibGljIHZvaWQgY2hlY2tQZXJtaXNzaW9uKFBlcm1pc3Npb24gcGVybSkgeworICAgICAgICAgICAgICAgIGlmIChwZXJtLmdldE5hbWUoKS5lcXVhbHMoInNodXRkb3duSG9va3MiKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgLy8gcmVtb3ZlIHByZXZpb3VzbHkgYWRkZWQgaG9vayBzbyB3ZSdyZSBub3QgZGVwZW5kaW5nIG9uIHRoZSBwcmlvcml0eQorICAgICAgICAvLyBvZiB0aGUgRXhjZXB0aW9ucyB0byBiZSB0aHJvd24uCisgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLnJlbW92ZVNodXRkb3duSG9vayh0aHJFeGNlcHRpb24pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLnNsZWVwKDEwMDApOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9hdmFpbGFibGVQcm9jZXNzb3JzKCkgeworICAgICAgICBhc3NlcnRUcnVlKFJ1bnRpbWUuZ2V0UnVudGltZSgpLmF2YWlsYWJsZVByb2Nlc3NvcnMoKSA+IDApOworICAgIH0KKworCisgICAgcHVibGljIHZvaWQgdGVzdF9leGVjTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZ0FycmF5KCkgeworICAgICAgICBTdHJpbmcgW10gZW52cCA9ICBnZXRFbnYoKTsKKworICAgICAgICBjaGVja0V4ZWMoMCwgZW52cCwgbnVsbCk7CisgICAgICAgIGNoZWNrRXhlYygwLCBudWxsLCBudWxsKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYygoU3RyaW5nKW51bGwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBTZWN1cml0eU1hbmFnZXIgc20gPSBuZXcgU2VjdXJpdHlNYW5hZ2VyKCkgeworCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBjaGVja1Blcm1pc3Npb24oUGVybWlzc2lvbiBwZXJtKSB7CisgICAgICAgICAgICAgICAgaWYgKHBlcm0uZ2V0TmFtZSgpLmVxdWFscygiY2hlY2tFeGVjIikpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBjaGVja0V4ZWMoU3RyaW5nIGNtZCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKCIiLCBlbnZwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXhlY0xqYXZhX2xhbmdfU3RyaW5nQXJyYXlMamF2YV9sYW5nX1N0cmluZ0FycmF5KCkgeworICAgICAgICBTdHJpbmcgW10gZW52cCA9ICBnZXRFbnYoKTsKKworICAgICAgICBjaGVja0V4ZWMoNCwgZW52cCwgbnVsbCk7CisgICAgICAgIGNoZWNrRXhlYyg0LCBudWxsLCBudWxsKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYygoU3RyaW5nW10pbnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKG5ldyBTdHJpbmdbXXsibHMiLCBudWxsfSwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIFNlY3VyaXR5TWFuYWdlciBzbSA9IG5ldyBTZWN1cml0eU1hbmFnZXIoKSB7CisKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihQZXJtaXNzaW9uIHBlcm0pIHsKKyAgICAgICAgICAgICAgICBpZiAocGVybS5nZXROYW1lKCkuZXF1YWxzKCJjaGVja0V4ZWMiKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrRXhlYyhTdHJpbmcgY21kKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmV4ZWMobmV3IFN0cmluZ1tde30sIGVudnApOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9vYikgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmV4ZWMobmV3IFN0cmluZ1tdeyIifSwgZW52cCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7IC8qIGV4cGVjdGVkICovIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2V4ZWNMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nQXJyYXlMamF2YV9pb19GaWxlKCkgeworCisgICAgICAgIFN0cmluZyBbXSBlbnZwID0gIGdldEVudigpOworCisgICAgICAgIEZpbGUgd29ya0ZvbGRlciA9IFN1cHBvcnRfUmVzb3VyY2VzLmNyZWF0ZVRlbXBGb2xkZXIoKTsKKworICAgICAgICBjaGVja0V4ZWMoMiwgZW52cCwgd29ya0ZvbGRlcik7CisgICAgICAgIGNoZWNrRXhlYygyLCBudWxsLCBudWxsKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYygoU3RyaW5nKW51bGwsIG51bGwsIHdvcmtGb2xkZXIpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBTZWN1cml0eU1hbmFnZXIgc20gPSBuZXcgU2VjdXJpdHlNYW5hZ2VyKCkgeworCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBjaGVja1Blcm1pc3Npb24oUGVybWlzc2lvbiBwZXJtKSB7CisgICAgICAgICAgICAgICAgaWYgKHBlcm0uZ2V0TmFtZSgpLmVxdWFscygiY2hlY2tFeGVjIikpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBjaGVja0V4ZWMoU3RyaW5nIGNtZCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKCIiLCAgZW52cCwgd29ya0ZvbGRlcik7CisgICAgICAgICAgICBmYWlsKCJTZWN1cml0eUV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXhlY0xqYXZhX2xhbmdfU3RyaW5nQXJyYXlMamF2YV9sYW5nX1N0cmluZ0FycmF5TGphdmFfaW9fRmlsZSgpIHsKKyAgICAgICAgU3RyaW5nIFtdIGVudnAgPSAgZ2V0RW52KCk7CisKKyAgICAgICAgRmlsZSB3b3JrRm9sZGVyID0gU3VwcG9ydF9SZXNvdXJjZXMuY3JlYXRlVGVtcEZvbGRlcigpOworCisgICAgICAgIGNoZWNrRXhlYyg1LCBlbnZwLCB3b3JrRm9sZGVyKTsKKyAgICAgICAgY2hlY2tFeGVjKDUsIG51bGwsIG51bGwpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKChTdHJpbmdbXSludWxsLCBudWxsLCB3b3JrRm9sZGVyKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmV4ZWMobmV3IFN0cmluZ1tdeyJscyIsIG51bGx9LCBudWxsLCB3b3JrRm9sZGVyKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgU2VjdXJpdHlNYW5hZ2VyIHNtID0gbmV3IFNlY3VyaXR5TWFuYWdlcigpIHsKKworICAgICAgICAgICAgcHVibGljIHZvaWQgY2hlY2tQZXJtaXNzaW9uKFBlcm1pc3Npb24gcGVybSkgeworICAgICAgICAgICAgICAgIGlmIChwZXJtLmdldE5hbWUoKS5lcXVhbHMoImNoZWNrRXhlYyIpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHZvaWQgY2hlY2tFeGVjKFN0cmluZyBjbWQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhuZXcgU3RyaW5nW117IiJ9LCBlbnZwLCB3b3JrRm9sZGVyKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIFN0cmluZyBbXSBnZXRFbnYoKSB7CisgICAgICAgIE9iamVjdCBbXSB2YWx1ZVNldCA9IFN5c3RlbS5nZXRlbnYoKS52YWx1ZXMoKS50b0FycmF5KCk7CisgICAgICAgIE9iamVjdCBbXSBrZXlTZXQgPSBTeXN0ZW0uZ2V0ZW52KCkua2V5U2V0KCkudG9BcnJheSgpOworICAgICAgICBTdHJpbmcgW10gZW52cCA9IG5ldyBTdHJpbmdbdmFsdWVTZXQubGVuZ3RoXTsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGVudnAubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGVudnBbaV0gPSBrZXlTZXRbaV0gKyAiPSIgKyB2YWx1ZVNldFtpXTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZW52cDsKKyAgICB9CisKKyAgICB2b2lkIGNoZWNrRXhlYyhpbnQgdGVzdENhc2UsIFN0cmluZyBbXSBlbnZwLCBGaWxlIGZpbGUpIHsKKyAgICAgICAgU3RyaW5nIGRpck5hbWUgPSAiVGVzdF9EaXJlY3RvcnkiOworICAgICAgICBTdHJpbmcgZGlyUGFyZW50TmFtZSA9ICJQYXJlbnRfRGlyZWN0b3J5IjsKKyAgICAgICAgRmlsZSByZXNvdXJjZXMgPSBTdXBwb3J0X1Jlc291cmNlcy5jcmVhdGVUZW1wRm9sZGVyKCk7CisgICAgICAgIFN0cmluZyBmb2xkZXIgPSByZXNvdXJjZXMuZ2V0QWJzb2x1dGVQYXRoKCkgKyAiLyIgKyBkaXJOYW1lOworICAgICAgICBTdHJpbmcgZm9sZGVyV2l0aFBhcmVudCA9IHJlc291cmNlcy5nZXRBYnNvbHV0ZVBhdGgoKSArICIvIiAgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlyUGFyZW50TmFtZSArICIvIiArIGRpck5hbWU7CisgICAgICAgIFN0cmluZyBjb21tYW5kID0gIm1rZGlyICIgKyBmb2xkZXI7CisgICAgICAgIFN0cmluZyBbXSBjb21tYW5kQXJndW1lbnRzID0geyJta2RpciIsIGZvbGRlcn07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQcm9jZXNzIHByb2MgPSBudWxsOworICAgICAgICAgICAgc3dpdGNoKHRlc3RDYXNlKSB7CisgICAgICAgICAgICAgICAgY2FzZSAwOgorICAgICAgICAgICAgICAgICAgICBwcm9jID0gUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhjb21tYW5kLCBlbnZwKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAxOgorICAgICAgICAgICAgICAgICAgICBwcm9jID0gUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhjb21tYW5kKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAyOgorICAgICAgICAgICAgICAgICAgICBwcm9jID0gUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhjb21tYW5kLCBlbnZwLCBmaWxlKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAzOgorICAgICAgICAgICAgICAgICAgICBwcm9jID0gUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhjb21tYW5kQXJndW1lbnRzKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSA0OgorICAgICAgICAgICAgICAgICAgICBwcm9jID0gUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhjb21tYW5kQXJndW1lbnRzLCBlbnZwKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSA1OgorICAgICAgICAgICAgICAgICAgICBwcm9jID0gUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhjb21tYW5kQXJndW1lbnRzLCBlbnZwLCBmaWxlKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb2MpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMzAwMCk7CisgICAgICAgICAgICB9IGNhdGNoKEludGVycnVwdGVkRXhjZXB0aW9uIGllKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiSW50ZXJydXB0ZWRFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEZpbGUgZiA9IG5ldyBGaWxlKGZvbGRlcik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGYuZXhpc3RzKCkpOworICAgICAgICAgICAgaWYoZi5leGlzdHMoKSkgeworICAgICAgICAgICAgICAgIGYuZGVsZXRlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gaW8pIHsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2V4ZWNMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgY2hlY2tFeGVjKDEsIG51bGwsIG51bGwpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKChTdHJpbmcpIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYygiIik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9leGVjTGphdmFfbGFuZ19TdHJpbmdBcnJheSgpIHsKKworICAgICAgICBjaGVja0V4ZWMoMywgbnVsbCwgbnVsbCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmV4ZWMoKFN0cmluZ1tdKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmV4ZWMobmV3IFN0cmluZ1tdeyJscyIsIG51bGx9KTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmV4ZWMobmV3IFN0cmluZ1tde30pOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlvYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKG5ldyBTdHJpbmdbXXsiIn0pOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9ydW5GaW5hbGl6ZXJzT25FeGl0KCkgeworICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5ydW5GaW5hbGl6ZXJzT25FeGl0KHRydWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlU2h1dGRvd25Ib29rTGphdmFfbGFuZ19UaHJlYWQoKSB7CisgICAgICAgIFRocmVhZCB0aHIxID0gbmV3IFRocmVhZCAoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgUnVudGltZS5nZXRSdW50aW1lKCkuYWRkU2h1dGRvd25Ib29rKHRoaXMpOworICAgICAgICAgICAgICAgIH0gY2F0Y2goSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlzZSkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gc2hvdWxkbid0IGJlIHRocm93bi4iKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmFkZFNodXRkb3duSG9vayh0aHIxKTsKKyAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLnJlbW92ZVNodXRkb3duSG9vayh0aHIxKTsKKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgIGZhaWwodC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgVGhyZWFkIHRocjIgPSBuZXcgVGhyZWFkICgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5yZW1vdmVTaHV0ZG93bkhvb2sodGhpcyk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duLiIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2goSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlzZSkgeworICAgICAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5hZGRTaHV0ZG93bkhvb2sodGhyMik7CisgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgICBmYWlsKHQuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLnNsZWVwKDEwMDApOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9tYXhNZW1vcnkoKSB7CisgICAgICAgIGFzc2VydFRydWUoUnVudGltZS5nZXRSdW50aW1lKCkubWF4TWVtb3J5KCkgPCBMb25nLk1BWF9WQUxVRSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90cmFjZUluc3RydWN0aW9ucygpIHsKKyAgICAgICAgUnVudGltZS5nZXRSdW50aW1lKCkudHJhY2VJbnN0cnVjdGlvbnMoZmFsc2UpOworICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS50cmFjZUluc3RydWN0aW9ucyh0cnVlKTsKKyAgICAgICAgUnVudGltZS5nZXRSdW50aW1lKCkudHJhY2VJbnN0cnVjdGlvbnMoZmFsc2UpOworICAgIH0KKworICAgIEBLbm93bkZhaWx1cmUoIkZhaWxzIGluIENUUyBidXQgcGFzc2VzIHVuZGVyIHJ1bi1jb3JlLXRlc3RzIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RyYWNlTWV0aG9kQ2FsbHMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS50cmFjZU1ldGhvZENhbGxzKGZhbHNlKTsKKyAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLnRyYWNlTWV0aG9kQ2FsbHModHJ1ZSk7CisgICAgICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS50cmFjZU1ldGhvZENhbGxzKGZhbHNlKTsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgLy8gU2xpZ2h0bHkgdWdseTogd2UgZGVmYXVsdCB0byB0aGUgU0QgY2FyZCwgd2hpY2ggbWF5IG9yIG1heSBub3QKKyAgICAgICAgICAgIC8vIGJlIHRoZXJlLiBTbyB3ZSBhbHNvIGFjY2VwdCB0aGUgZXJyb3IgY2FzZSBhcyBhIHN1Y2Nlc3MsIHNpbmNlCisgICAgICAgICAgICAvLyBpdCBtZWFucyB3ZSBhY3R1YWxseSBkaWQgZW5hYmxlIHRyYWNpbmcgKG9yIHRyaWVkIHRvKS4KKyAgICAgICAgICAgIGlmICghImZpbGUgb3BlbiBmYWlsZWQiLmVxdWFscyhleC5nZXRNZXNzYWdlKCkpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgZXg7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TG9jYWxpemVkSW5wdXRTdHJlYW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHNpbXBsZVN0cmluZyA9ICJIZWFydCBcdTJmM2MiOworICAgICAgICBieXRlW10gZXhwZWN0ZWQgPSBzaW1wbGVTdHJpbmcuZ2V0Qnl0ZXMoIlVURi04Iik7CisgICAgICAgIGJ5dGVbXSByZXR1cm5lZCA9IG5ldyBieXRlW2V4cGVjdGVkLmxlbmd0aF07CisKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICBzaW1wbGVTdHJpbmcuZ2V0Qnl0ZXMoIlVURi04IikpOworCisgICAgICAgIElucHV0U3RyZWFtIGxjSW4gPQorICAgICAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmdldExvY2FsaXplZElucHV0U3RyZWFtKGJhaXMpOworICAgICAgICBsY0luLnJlYWQocmV0dXJuZWQpOworCisgICAgICAgIGFzc2VydFRydWUoIndyb25nIHJlc3VsdCBmb3IgU3RyaW5nOiAiICsgc2ltcGxlU3RyaW5nLAorICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMoZXhwZWN0ZWQsIHJldHVybmVkKSk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldExvY2FsaXplZE91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzaW1wbGVTdHJpbmcgPSAiSGVhcnQgXHUyZjNjIjsKKyAgICAgICAgYnl0ZVtdIGV4cGVjdGVkID0gc2ltcGxlU3RyaW5nLmdldEJ5dGVzKCJVVEYtOCIpOworCisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisKKyAgICAgICAgT3V0cHV0U3RyZWFtIGxjT3V0ID0KKyAgICAgICAgICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5nZXRMb2NhbGl6ZWRPdXRwdXRTdHJlYW0ob3V0KTsKKyAgICAgICAgbGNPdXQud3JpdGUoc2ltcGxlU3RyaW5nLmdldEJ5dGVzKCJVVEYtOCIpKTsKKyAgICAgICAgbGNPdXQuZmx1c2goKTsKKyAgICAgICAgbGNPdXQuY2xvc2UoKTsKKworICAgICAgICBieXRlW10gcmV0dXJuZWQgPSBvdXQudG9CeXRlQXJyYXkoKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJ3cm9uZyByZXN1bHQgZm9yIFN0cmluZzogIiArIHJldHVybmVkLnRvU3RyaW5nKCkgKworICAgICAgICAgICAgICAgICIgZXhwZWN0ZWQgc3RyaW5nOiAiICsgZXhwZWN0ZWQudG9TdHJpbmcoKSwKKyAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKGV4cGVjdGVkLCByZXR1cm5lZCkpOworICAgIH0KKworCisgICAgcHVibGljIHZvaWQgdGVzdF9sb2FkKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgUnVudGltZS5nZXRSdW50aW1lKCkubG9hZCgibm9uRXhpc3RlbnRMaWJyYXJ5Iik7CisgICAgICAgICAgICBmYWlsKCJVbnNhdGlzZmllZExpbmtFcnJvciB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChVbnNhdGlzZmllZExpbmtFcnJvciB1bGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5sb2FkKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xvYWRMaWJyYXJ5KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgUnVudGltZS5nZXRSdW50aW1lKCkubG9hZExpYnJhcnkoIm5vbkV4aXN0ZW50TGlicmFyeSIpOworICAgICAgICAgICAgZmFpbCgiVW5zYXRpc2ZpZWRMaW5rRXJyb3Igd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goVW5zYXRpc2ZpZWRMaW5rRXJyb3IgdWxlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUnVudGltZS5nZXRSdW50aW1lKCkubG9hZExpYnJhcnkobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRTdGFja1RyYWNlRWxlbWVudFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRTdGFja1RyYWNlRWxlbWVudFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YTA5YzQ1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZFN0YWNrVHJhY2VFbGVtZW50VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjE0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkU3RhY2tUcmFjZUVsZW1lbnRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIGNsYXNzIE9yaWdpbmFsIGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgICAgIHB1YmxpYyB2b2lkIHB1cmVKYXZhTWV0aG9kKE9iamVjdCB0ZXN0KSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oInB1cmUgamF2YSBtZXRob2QiKTsKKyAgICAgICAgfQorCisgICAgICAgIG5hdGl2ZSBwdWJsaWMgdm9pZCBwdXJlTmF0aXZlTWV0aG9kKE9iamVjdCB0ZXN0KTsKKyAgICB9CisKKyAgICBwcml2YXRlIE9yaWdpbmFsIG9yaWdpbmFsOworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgb3JpZ2luYWwgPSBuZXcgT3JpZ2luYWwoKTsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdJKCkgeworICAgICAgICBTdGFja1RyYWNlRWxlbWVudCBzdGUyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9yaWdpbmFsLnB1cmVKYXZhTWV0aG9kKG5ldyBPYmplY3QoKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBTdGFja1RyYWNlRWxlbWVudCBzdGUxID0gZS5nZXRTdGFja1RyYWNlKClbMF07CisgICAgICAgICAgICBzdGUyID0gbmV3IFN0YWNrVHJhY2VFbGVtZW50KHN0ZTEuZ2V0Q2xhc3NOYW1lKCksCisgICAgICAgICAgICAgICAgICAgIHN0ZTEuZ2V0TWV0aG9kTmFtZSgpLAorICAgICAgICAgICAgICAgICAgICBzdGUxLmdldEZpbGVOYW1lKCksCisgICAgICAgICAgICAgICAgICAgIHN0ZTEuZ2V0TGluZU51bWJlcigpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHZhbHVlIG9mIGNsYXNzIG5hbWUiLAorICAgICAgICAgICAgICAgICAgICBzdGUxLmdldENsYXNzTmFtZSgpLCBzdGUyLmdldENsYXNzTmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHZhbHVlIG9mIG1ldGhvZCBuYW1lIiwKKyAgICAgICAgICAgICAgICAgICAgc3RlMS5nZXRNZXRob2ROYW1lKCksIHN0ZTIuZ2V0TWV0aG9kTmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHZhbHVlIG9mIGZpbGUgbmFtZSIsCisgICAgICAgICAgICAgICAgICAgIHN0ZTEuZ2V0RmlsZU5hbWUoKSwgc3RlMi5nZXRGaWxlTmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHZhbHVlIG9mIGxpbmUgbnVtYmVyIiwKKyAgICAgICAgICAgICAgICAgICAgc3RlMS5nZXRMaW5lTnVtYmVyKCksIHN0ZTIuZ2V0TGluZU51bWJlcigpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROb3ROdWxsKCJJbmNvcnJlY3Qgc3RhY2sgdHJhY2Ugb2JqZWN0Iiwgc3RlMik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU3RhY2tUcmFjZUVsZW1lbnQobnVsbCwKKyAgICAgICAgICAgICAgICAgICAgc3RlMi5nZXRNZXRob2ROYW1lKCksCisgICAgICAgICAgICAgICAgICAgIHN0ZTIuZ2V0RmlsZU5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgc3RlMi5nZXRMaW5lTnVtYmVyKCkpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFN0YWNrVHJhY2VFbGVtZW50KHN0ZTIuZ2V0Q2xhc3NOYW1lKCksCisgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgICAgIHN0ZTIuZ2V0RmlsZU5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgc3RlMi5nZXRMaW5lTnVtYmVyKCkpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFN0YWNrVHJhY2VFbGVtZW50KHN0ZTIuZ2V0Q2xhc3NOYW1lKCksCisgICAgICAgICAgICAgICAgICAgIHN0ZTIuZ2V0TWV0aG9kTmFtZSgpLAorICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICBzdGUyLmdldExpbmVOdW1iZXIoKSk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9lcXVhbHNMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9yaWdpbmFsLnB1cmVKYXZhTWV0aG9kKG5ldyBPYmplY3QoKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBTdGFja1RyYWNlRWxlbWVudCBzdGUxID0gZS5nZXRTdGFja1RyYWNlKClbMF07CisgICAgICAgICAgICBTdGFja1RyYWNlRWxlbWVudCBzdGUyID0KKyAgICAgICAgICAgICAgICBuZXcgU3RhY2tUcmFjZUVsZW1lbnQoc3RlMS5nZXRDbGFzc05hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0ZTEuZ2V0TWV0aG9kTmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgc3RlMS5nZXRGaWxlTmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgc3RlMS5nZXRMaW5lTnVtYmVyKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJPYmplY3RzIGFyZSBlcXVhbGVkIiwgc3RlMSwgc3RlMik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldENsYXNzTmFtZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9yaWdpbmFsLnB1cmVKYXZhTWV0aG9kKG5ldyBPYmplY3QoKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBjbGFzcyBuYW1lIiwKKyAgICAgICAgICAgICAgICAgICAgImxpYmNvcmUuamF2YS5sYW5nLk9sZFN0YWNrVHJhY2VFbGVtZW50VGVzdCRPcmlnaW5hbCIsCisgICAgICAgICAgICAgICAgICAgIGUuZ2V0U3RhY2tUcmFjZSgpWzBdLmdldENsYXNzTmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGNsYXNzIG5hbWUiLAorICAgICAgICAgICAgICAgICAgICAibGliY29yZS5qYXZhLmxhbmcuT2xkU3RhY2tUcmFjZUVsZW1lbnRUZXN0IiwKKyAgICAgICAgICAgICAgICAgICAgZS5nZXRTdGFja1RyYWNlKClbMV0uZ2V0Q2xhc3NOYW1lKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRGaWxlTmFtZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9yaWdpbmFsLnB1cmVKYXZhTWV0aG9kKG5ldyBPYmplY3QoKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBmaWxlIG5hbWUiLAorICAgICAgICAgICAgICAgICAgICAiT2xkU3RhY2tUcmFjZUVsZW1lbnRUZXN0LmphdmEiLAorICAgICAgICAgICAgICAgICAgICBlLmdldFN0YWNrVHJhY2UoKVswXS5nZXRGaWxlTmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGZpbGUgbmFtZSIsCisgICAgICAgICAgICAgICAgICAgICJPbGRTdGFja1RyYWNlRWxlbWVudFRlc3QuamF2YSIsCisgICAgICAgICAgICAgICAgICAgIGUuZ2V0U3RhY2tUcmFjZSgpWzFdLmdldEZpbGVOYW1lKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRMaW5lTnVtYmVyKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3JpZ2luYWwucHVyZUphdmFNZXRob2QobmV3IE9iamVjdCgpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGxpbmUgbnVtYmVyIiwKKyAgICAgICAgICAgICAgICAgICAgMjYsIGUuZ2V0U3RhY2tUcmFjZSgpWzBdLmdldExpbmVOdW1iZXIoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1ldGhvZE5hbWUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcmlnaW5hbC5wdXJlSmF2YU1ldGhvZChuZXcgT2JqZWN0KCkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbWV0aG9kIG5hbWUiLAorICAgICAgICAgICAgICAgICAgICAicHVyZUphdmFNZXRob2QiLAorICAgICAgICAgICAgICAgICAgICBlLmdldFN0YWNrVHJhY2UoKVswXS5nZXRNZXRob2ROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbWV0aG9kIG5hbWUiLAorICAgICAgICAgICAgICAgICAgICAidGVzdF9nZXRNZXRob2ROYW1lIiwKKyAgICAgICAgICAgICAgICAgICAgZS5nZXRTdGFja1RyYWNlKClbMV0uZ2V0TWV0aG9kTmFtZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGFzaENvZGUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcmlnaW5hbC5wdXJlSmF2YU1ldGhvZChuZXcgT2JqZWN0KCkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnQgc3RlMSA9IGUuZ2V0U3RhY2tUcmFjZSgpWzBdOworICAgICAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnQgc3RlMiA9CisgICAgICAgICAgICAgICAgbmV3IFN0YWNrVHJhY2VFbGVtZW50KHN0ZTEuZ2V0Q2xhc3NOYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICBzdGUxLmdldE1ldGhvZE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0ZTEuZ2V0RmlsZU5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0ZTEuZ2V0TGluZU51bWJlcigpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHZhbHVlIG9mIGhhc2ggY29kZSIsCisgICAgICAgICAgICAgICAgICAgIHN0ZTEuaGFzaENvZGUoKSwgc3RlMi5oYXNoQ29kZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJJbmNvcnJlY3QgdmFsdWUgb2YgaGFzaCBjb2RlIiwKKyAgICAgICAgICAgICAgICAgICAgc3RlMS5oYXNoQ29kZSgpID09IGUuZ2V0U3RhY2tUcmFjZSgpWzFdLmhhc2hDb2RlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc05hdGl2ZU1ldGhvZCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9yaWdpbmFsLnB1cmVKYXZhTWV0aG9kKG5ldyBPYmplY3QoKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSgiSW5jb3JyZWN0IG1ldGhvZCB0eXBlIiwKKyAgICAgICAgICAgICAgICAgICAgZS5nZXRTdGFja1RyYWNlKClbMF0uaXNOYXRpdmVNZXRob2QoKSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9yaWdpbmFsLnB1cmVOYXRpdmVNZXRob2QobmV3IE9iamVjdCgpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoRXJyb3IgZSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG1ldGhvZCB0eXBlIiwKKyAgICAgICAgICAgICAgICAgICAgZS5nZXRTdGFja1RyYWNlKClbMF0uaXNOYXRpdmVNZXRob2QoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3JpZ2luYWwucHVyZUphdmFNZXRob2QobmV3IE9iamVjdCgpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50IHN0ZSA9IGUuZ2V0U3RhY2tUcmFjZSgpWzBdOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RyaW5nIHJlcHJlc2VudGF0aW9uIGRvZXNuJ3QgY29udGFpbiBhIHBhY2thZ2UgbmFtZSIsCisgICAgICAgICAgICAgICAgICAgIHN0ZS50b1N0cmluZygpLmNvbnRhaW5zKGdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldE5hbWUoKSkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RyaW5nIHJlcHJlc2VudGF0aW9uIGRvZXNuJ3QgY29udGFpbiBhIGNsYXNzIG5hbWUiLAorICAgICAgICAgICAgICAgICAgICBzdGUudG9TdHJpbmcoKS5jb250YWlucygiT3JpZ2luYWwiKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTdHJpbmcgcmVwcmVzZW50YXRpb24gZG9lc24ndCBjb250YWluIGEgZmlsZSBuYW1lIiwKKyAgICAgICAgICAgICAgICAgICAgc3RlLnRvU3RyaW5nKCkuY29udGFpbnMoIk9sZFN0YWNrVHJhY2VFbGVtZW50VGVzdC5qYXZhIikpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RyaW5nIHJlcHJlc2VudGF0aW9uIGRvZXNuJ3QgY29udGFpbiBhIGxpbmUgbnVtYmVyIiwKKyAgICAgICAgICAgICAgICAgICAgc3RlLnRvU3RyaW5nKCkuY29udGFpbnMoIjI2IikpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RyaW5nIHJlcHJlc2VudGF0aW9uIGRvZXNuJ3QgY29udGFpbiBhIG1ldGhvZCBuYW1lIiwKKyAgICAgICAgICAgICAgICAgICAgc3RlLnRvU3RyaW5nKCkuY29udGFpbnMoInB1cmVKYXZhTWV0aG9kIikpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZFN0cmluZ0J1ZmZlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRTdHJpbmdCdWZmZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjgxY2U1ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRTdHJpbmdCdWZmZXJUZXN0LmphdmEKQEAgLTAsMCArMSwzMjEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRTdHJpbmdCdWZmZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgU3RyaW5nQnVmZmVyIHRlc3RCdWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCJUaGlzIGlzIGEgdGVzdCBidWZmZXIiKTsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZGVsZXRlQ2hhckF0SSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRlc3RCdWZmZXIuZGVsZXRlQ2hhckF0KHRlc3RCdWZmZXIubGVuZ3RoKCkgKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIlN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBzaW9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0QnVmZmVyLmRlbGV0ZUNoYXJBdCgtMSk7CisgICAgICAgICAgICBmYWlsKCJTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2lvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Vuc3VyZUNhcGFjaXR5SSgpIHsKKyAgICAgICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigxMCk7CisgICAgICAgIHNiLmVuc3VyZUNhcGFjaXR5KC0yKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gaW5jcmVhc2UgY2FwYWNpdHkuIiwgMTAsIHNiLmNhcGFjaXR5KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Q2hhcnNJSSRDSSgpIHsKKyAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZjIgPSBuZXcgU3RyaW5nQnVmZmVyKCIiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ1ZjIuZ2V0Q2hhcnMoLTEsIDAsIG5ldyBjaGFyWzVdLCAyKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnVmMi5nZXRDaGFycygwLCAtMSwgbmV3IGNoYXJbNV0sIDIpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidWYyLmdldENoYXJzKDAsIC0xLCBuZXcgY2hhcls1XSwgMik7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ1ZjIuZ2V0Q2hhcnMoMiwgMSwgbmV3IGNoYXJbNV0sIDIpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidWYyLmdldENoYXJzKDAsIDYsIG5ldyBjaGFyWzVdLCAyKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnVmMi5nZXRDaGFycygwLCA2LCBuZXcgY2hhclsxMF0sIDUpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5zZXJ0SUQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0QnVmZmVyLmluc2VydCgtMSwgRG91YmxlLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBzaW9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0QnVmZmVyLmluc2VydCh0ZXN0QnVmZmVyLmxlbmd0aCgpICsgMSwgRG91YmxlLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBzaW9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5zZXJ0SUYoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0QnVmZmVyLmluc2VydCgtMSwgRmxvYXQuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgIGZhaWwoIlN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHNpb29iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRlc3RCdWZmZXIuaW5zZXJ0KHRlc3RCdWZmZXIubGVuZ3RoKCkgKyAxLCBGbG9hdC5NQVhfVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2lvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luc2VydElJKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdEJ1ZmZlci5pbnNlcnQoLTEsIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgIGZhaWwoIlN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHNpb29iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRlc3RCdWZmZXIuaW5zZXJ0KHRlc3RCdWZmZXIubGVuZ3RoKCkgKyAxLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBzaW9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5zZXJ0SUooKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0QnVmZmVyLmluc2VydCgtMSwgTG9uZy5NQVhfVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2lvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdEJ1ZmZlci5pbnNlcnQodGVzdEJ1ZmZlci5sZW5ndGgoKSArIDEsIExvbmcuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgIGZhaWwoIlN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHNpb29iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pbnNlcnRJTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIE9iamVjdCBvYmoxID0gbmV3IE9iamVjdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdEJ1ZmZlci5pbnNlcnQoLTEsIG9iajEpOworICAgICAgICAgICAgZmFpbCgiU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2lvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdEJ1ZmZlci5pbnNlcnQodGVzdEJ1ZmZlci5sZW5ndGgoKSArIDEsIG9iajEpOworICAgICAgICAgICAgZmFpbCgiU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2lvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luc2VydElMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRlc3RCdWZmZXIuaW5zZXJ0KC0xLCAiIik7CisgICAgICAgICAgICBmYWlsKCJTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBzaW9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0QnVmZmVyLmluc2VydCh0ZXN0QnVmZmVyLmxlbmd0aCgpICsgMSwgIiIpOworICAgICAgICAgICAgZmFpbCgiU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2lvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luc2VydElaKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdEJ1ZmZlci5pbnNlcnQodGVzdEJ1ZmZlci5sZW5ndGgoKSArIDEsIHRydWUpOworICAgICAgICAgICAgZmFpbCgiU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2lvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdEJ1ZmZlci5pbnNlcnQoLTEsIHRydWUpOworICAgICAgICAgICAgZmFpbCgiU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2lvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlcGxhY2VJSUxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdEJ1ZmZlci5yZXBsYWNlKC0xLCAwLCAidGV4dCIpOworICAgICAgICAgICAgZmFpbCgiU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2lvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdEJ1ZmZlci5yZXBsYWNlKDAsIC0xLCAidGV4dCIpOworICAgICAgICAgICAgZmFpbCgiU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2lvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdEJ1ZmZlci5yZXBsYWNlKDIsIDEsICJ0ZXh0Iik7CisgICAgICAgICAgICBmYWlsKCJTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBzaW9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0QnVmZmVyLnJlcGxhY2UodGVzdEJ1ZmZlci5sZW5ndGgoKSArIDEsIHRlc3RCdWZmZXIubGVuZ3RoKCkgKyAxLAorICAgICAgICAgICAgICAgICAgICAidGV4dCIpOworICAgICAgICAgICAgZmFpbCgiU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2lvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldENoYXJBdElDKCkgeworICAgICAgICBTdHJpbmdCdWZmZXIgcyA9IG5ldyBTdHJpbmdCdWZmZXIoIkhlbGxvV29ybGQiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMuc2V0Q2hhckF0KC0xLCAnWicpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5zZXRDaGFyQXQocy5sZW5ndGgoKSArIDEsICdaJyk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpb29iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdWJzdHJpbmdJKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdEJ1ZmZlci5zdWJzdHJpbmcodGVzdEJ1ZmZlci5sZW5ndGgoKSArIDEpOworICAgICAgICAgICAgZmFpbCgiU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gb29iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRlc3RCdWZmZXIuc3Vic3RyaW5nKC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIG9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3Vic3RyaW5nSUkoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0QnVmZmVyLnN1YnN0cmluZygtMSwgdGVzdEJ1ZmZlci5sZW5ndGgoKSk7CisgICAgICAgICAgICBmYWlsKCJTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdEJ1ZmZlci5zdWJzdHJpbmcoMCwgLTEpOworICAgICAgICAgICAgZmFpbCgiU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gb29iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRlc3RCdWZmZXIuc3Vic3RyaW5nKDIsIDEpOworICAgICAgICAgICAgZmFpbCgiU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gb29iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdWJTZXF1ZW5jZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3Qgc3Vic3RyaW5nIHJldHVybmVkIiwgIiBpcyIsCisgICAgICAgICAgICAgICAgdGVzdEJ1ZmZlci5zdWJTZXF1ZW5jZSg0LCA3KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHN1YnN0cmluZyByZXR1cm5lZCIsICJ0ZXN0IGJ1ZmZlciIsCisgICAgICAgICAgICAgICAgdGVzdEJ1ZmZlci5zdWJTZXF1ZW5jZSgxMCwgMjEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub3QgaWRlbnRpY2FsIiwgIlRoaXMgaXMgYSB0ZXN0IGJ1ZmZlciIsCisgICAgICAgICAgICAgICAgdGVzdEJ1ZmZlci5zdWJTZXF1ZW5jZSgwLCB0ZXN0QnVmZmVyLmxlbmd0aCgpKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRlc3RCdWZmZXIuc3ViU2VxdWVuY2UoMCwgSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpb29iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRlc3RCdWZmZXIuc3ViU2VxdWVuY2UoSW50ZWdlci5NQVhfVkFMVUUsIHRlc3RCdWZmZXIubGVuZ3RoKCkpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpb29iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRlc3RCdWZmZXIuc3ViU2VxdWVuY2UoLTEsIHRlc3RCdWZmZXIubGVuZ3RoKCkpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpb29iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZFN0cmluZ1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRTdHJpbmdUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzNjMzIxNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRTdHJpbmdUZXN0LmphdmEKQEAgLTAsMCArMSw1MTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5JbGxlZ2FsRm9ybWF0RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm5TeW50YXhFeGNlcHRpb247CisKK3B1YmxpYyBjbGFzcyBPbGRTdHJpbmdUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIFN0cmluZyBodzEgPSAiSGVsbG9Xb3JsZCI7CisKKyAgICBTdHJpbmcgaHcyID0gIkhlbGxvV29ybGQiOworCisgICAgU3RyaW5nIGh3bGMgPSAiaGVsbG93b3JsZCI7CisKKyAgICBTdHJpbmcgaHd1YyA9ICJIRUxMT1dPUkxEIjsKKworICAgIFN0cmluZyBjb21wMTEgPSAiVGVzdCBTdHJpbmciOworCisgICAgY2hhcltdIGJ1ZiA9IHsgJ1cnLCAnbycsICdyJywgJ2wnLCAnZCcgfTsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2hhckF0SSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGNoYXIgamF2YS5sYW5nLlN0cmluZy5jaGFyQXQoaW50KQorICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgY2hhcmFjdGVyIHJldHVybmVkIiwgaHcxLmNoYXJBdCg1KSA9PSAnVycKKyAgICAgICAgICAgICAgICAmJiAoaHcxLmNoYXJBdCgxKSAhPSAnWicpKTsKKworICAgICAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJUZXN0IFN0cmluZyI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0U3RyaW5nLmNoYXJBdCh0ZXN0U3RyaW5nLmxlbmd0aCgpKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdFN0cmluZy5jaGFyQXQoSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlvYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0U3RyaW5nLmNoYXJBdCgtMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9lbmRzV2l0aExqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICBhc3NlcnRGYWxzZSgiRG9lc24ndCByZXR1cm4gZmFsc2UgdmFsdWUuIiwgaHcxLmVuZHNXaXRoKCJsZCAiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJEb2Vzbid0IHJldHVybiBmYWxzZSB2YWx1ZS4iLCBodzEuZW5kc1dpdGgoIiAiKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCB2YWx1ZSBmb3IgZW1wdHkgc3RyaW5nLiIsIGh3MS5lbmRzV2l0aCgiIikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaHcxLmVuZHNXaXRoKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIGFzc2VydFRydWUoIlN0cmluZyBub3QgZXF1YWwiLCBodzEuZXF1YWxzKGh3MikgJiYgIShodzEuZXF1YWxzKGNvbXAxMSkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VxdWFsc0lnbm9yZUNhc2VMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIGVxdWFscyBzdHJpbmdzLiIsIGh3bGMKKyAgICAgICAgICAgICAgICAuZXF1YWxzSWdub3JlQ2FzZShod2xjKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIGRpZmZlcmVudCBzdHJpbmdzLiIsIGh3bGMKKyAgICAgICAgICAgICAgICAuZXF1YWxzSWdub3JlQ2FzZShod3VjICsgIiAiKSk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEJ5dGVzSUkkQkkoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAiSGVsbG8gV29ybGQiLmdldEJ5dGVzKC0xLCAxLCBudWxsLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICJIZWxsbyBXb3JsZCIuZ2V0Qnl0ZXMoNiwgMiwgbnVsbCwgMCk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgIkhlbGxvIFdvcmxkIi5nZXRCeXRlcygyLCAxMCwgbmV3IGJ5dGVbMTBdLCA0KTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Q2hhcnNJSSRDSSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICJIZWxsbyBXb3JsZCIuZ2V0Q2hhcnMoLTEsIDEsIG51bGwsIDApOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgIkhlbGxvIFdvcmxkIi5nZXRDaGFycyg2LCAyLCBudWxsLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAiSGVsbG8gV29ybGQiLmdldENoYXJzKDIsIDEwLCBuZXcgY2hhclsxMF0sIDQpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWdpb25NYXRjaGVzSUxqYXZhX2xhbmdfU3RyaW5nSUkoKSB7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIGZvciBuZWdhdGl2ZSBvZmZzZXQuIiwgaHcxLnJlZ2lvbk1hdGNoZXMoLTEsCisgICAgICAgICAgICAgICAgaHcyLCAyLCA1KSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIGZvciBuZWdhdGl2ZSBvZmZzZXQuIiwgaHcxLnJlZ2lvbk1hdGNoZXMoMiwKKyAgICAgICAgICAgICAgICBodzIsIC0xLCA1KSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIGZvciB0b2Zmc2V0K2xlbiBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aC4iLAorICAgICAgICAgICAgICAgIGh3MS5yZWdpb25NYXRjaGVzKDUsIGh3MiwgMiwgNikpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3Igb29mZnNldCtsZW4gaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGguIiwKKyAgICAgICAgICAgICAgICBodzEucmVnaW9uTWF0Y2hlcygyLCBodzIsIDUsIDYpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlZ2lvbk1hdGNoZXNaSUxqYXZhX2xhbmdfU3RyaW5nSUkoKSB7CisgICAgICAgIFN0cmluZyBib2d1c1N0cmluZyA9ICJ4eGNlZGtlZGtsZWlvcmVtIGx2dndyIGUnJycgM3IzciAyM3IiOworCisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIGZvciBuZWdhdGl2ZSBvZmZzZXQuIiwgaHcxLnJlZ2lvbk1hdGNoZXModHJ1ZSwKKyAgICAgICAgICAgICAgICAtMSwgaHcyLCAyLCA1KSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIGZvciBuZWdhdGl2ZSBvZmZzZXQuIiwgaHcxLnJlZ2lvbk1hdGNoZXMoZmFsc2UsCisgICAgICAgICAgICAgICAgMiwgaHcyLCAtMSwgNSkpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgdG9mZnNldCtsZW4gaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGguIiwKKyAgICAgICAgICAgICAgICBodzEucmVnaW9uTWF0Y2hlcyh0cnVlLCA1LCBodzIsIDIsIDYpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIG9vZmZzZXQrbGVuIGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoLiIsCisgICAgICAgICAgICAgICAgaHcxLnJlZ2lvbk1hdGNoZXMoZmFsc2UsIDIsIGh3MiwgNSwgNikpOworCisgICAgICAgIGFzc2VydFRydWUoImlkZW50aWNhbCByZWdpb25zIGZhaWxlZCBjb21wYXJpc29uIiwgaHd1Yy5yZWdpb25NYXRjaGVzKAorICAgICAgICAgICAgICAgIHRydWUsIDAsIGh3bGMsIDAsIGh3dWMubGVuZ3RoKCkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIm5vbiBpZGVudGljYWwgcmVnaW9ucyBmYWlsZWQgY29tcGFyaXNvbiIsIGh3dWMucmVnaW9uTWF0Y2hlcygKKyAgICAgICAgICAgICAgICBmYWxzZSwgMCwgaHdsYywgMCwgaHd1Yy5sZW5ndGgoKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVwbGFjZUNDKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBzdHJpbmcuIiwgaHcxLCBodzEucmVwbGFjZSgiISIsICIuIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVwbGFjZUFsbCgpIHsKKyAgICAgICAgU3RyaW5nIHN0ciA9ICIhJzEyMzEyMy4xMjNIZWxsb1dvcmxkITEyMzEyM2hlbGxvd29ybGQjIjsKKyAgICAgICAgU3RyaW5nIFtdIHBhdHRlcm5zID0geyJbaHdcXHB7VXBwZXJ9XSIsICIob3xsKXsyLH0iLCAiKFtcJ1wiXT8pKFxcZCspIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJeIS4qIyQifTsKKworICAgICAgICBTdHJpbmcgW10gcmVzdWx0cyA9IHsiIVwnMTIzMTIzLjEyMz9lbGxvP29ybGQhMTIzMTIzP2VsbG8/b3JsZCMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIVwnMTIzMTIzLjEyM0hlP1dvcmxkITEyMzEyM2hlP3dvcmxkIyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIhPy4/SGVsbG9Xb3JsZCE/aGVsbG93b3JsZCMiLCAiPyJ9OworCisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBwYXR0ZXJucy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3Qgc3RyaW5nIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzW2ldLCBzdHIucmVwbGFjZUFsbChwYXR0ZXJuc1tpXSwgIj8iKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RyLnJlcGxhY2VBbGwoIlthYmMqIiwgIj8iKTsKKyAgICAgICAgICAgIGZhaWwoIlBhdHRlcm5TeW50YXhFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIHBzZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZXBsYWNlRmlyc3QoKSB7CisgICAgICAgIFN0cmluZyBzdHIgPSAiIScxMjMxMjMuMTIzSGVsbG9Xb3JsZCExMjMxMjNoZWxsb3dvcmxkIyI7CisgICAgICAgIFN0cmluZyBbXSBwYXR0ZXJucyA9IHsiW2h3XFxwe1VwcGVyfV0iLCAiKG98bCl7Mix9IiwgIihbXCdcIl0/KShcXGQrKSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXiEuKiMkIn07CisKKyAgICAgICAgU3RyaW5nIFtdIHJlc3VsdHMgPSB7IiEnMTIzMTIzLjEyMz9lbGxvV29ybGQhMTIzMTIzaGVsbG93b3JsZCMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIScxMjMxMjMuMTIzSGU/V29ybGQhMTIzMTIzaGVsbG93b3JsZCMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIT8uMTIzSGVsbG9Xb3JsZCExMjMxMjNoZWxsb3dvcmxkIyIsICI/In07CisKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IHBhdHRlcm5zLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBzdHJpbmciLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHNbaV0sIHN0ci5yZXBsYWNlRmlyc3QocGF0dGVybnNbaV0sICI/IikpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ci5yZXBsYWNlRmlyc3QoIlthYmMqIiwgIj8iKTsKKyAgICAgICAgICAgIGZhaWwoIlBhdHRlcm5TeW50YXhFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIHBzZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zcGxpdExTdHJpbmcoKSB7CisgICAgICAgIFN0cmluZyBzdHIgPSAiIScxMjMxMjMuMTIzSGVsbG9Xb3JsZCExMjMxMjNoZWxsb3dvcmxkIyI7CisgICAgICAgIFN0cmluZyBbXSBwYXR0ZXJucyA9IHsiWyEuMV0iLCAiKFxcZCspLiplKGwrKW8uKm9ybGQifTsKKyAgICAgICAgU3RyaW5nIFtdW10gcmVzdWx0cyA9IHt7IiIsICInIiwiMjMiLCAiMjMiLCAiIiwgIjIzSGVsbG9Xb3JsZCIsICIiLCAiMjMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyM2hlbGxvd29ybGQjIn0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyIhJyIsICIjIn19OworCisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBwYXR0ZXJucy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IHN0cmluZyBhcnJheSBmb3IgcGF0dGVybjogIiArCisgICAgICAgICAgICAgICAgcGF0dGVybnNbaV0sIEFycmF5cy5lcXVhbHMocmVzdWx0c1tpXSwgc3RyLnNwbGl0KHBhdHRlcm5zW2ldKSkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ci5zcGxpdCgiW2F9Iik7CisgICAgICAgICAgICBmYWlsKCJQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBwc2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3BsaXRMU3RyaW5nTGludCgpIHsKKyAgICAgICAgU3RyaW5nIHN0ciA9ICIhJzEyMzEyMy4xMjNIZWxsb1dvcmxkITEyMzEyM2hlbGxvd29ybGQjIjsKKyAgICAgICAgU3RyaW5nIHBhdHRlcm4gPSAiWyEuMV0iOworICAgICAgICBTdHJpbmcgW11bXSByZXN1bHRzID0ge3siIiwgIiciLCIyMyIsICIyMy4xMjNIZWxsb1dvcmxkITEyMzEyM2hlbGxvd29ybGQjIn0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyIiLCAiJyIsIjIzIiwgIjIzIiwgIiIsICIyM0hlbGxvV29ybGQiLCAiIiwgIjIzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjNoZWxsb3dvcmxkIyJ9fTsKKworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3Qgc3RyaW5nIGFycmF5IGZvciBsaW1pdCA0IiwKKyAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKHJlc3VsdHNbMF0sIHN0ci5zcGxpdChwYXR0ZXJuLCA0KSkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3Qgc3RyaW5nIGFycmF5IGZvciBsaW1pdCA5IiwKKyAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKHJlc3VsdHNbMV0sIHN0ci5zcGxpdChwYXR0ZXJuLCA5KSkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3Qgc3RyaW5nIGFycmF5IGZvciBsaW1pdCAwIiwKKyAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKHJlc3VsdHNbMV0sIHN0ci5zcGxpdChwYXR0ZXJuLCAwKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3Qgc3RyaW5nIGFycmF5IGZvciBsaW1pdCAtMSIsCisgICAgICAgICAgICAgICAgQXJyYXlzLmVxdWFscyhyZXN1bHRzWzFdLCBzdHIuc3BsaXQocGF0dGVybiwgLTEpKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBzdHJpbmcgYXJyYXkgZm9yIGxpbWl0IDEwIiwKKyAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKHJlc3VsdHNbMV0sIHN0ci5zcGxpdChwYXR0ZXJuLCAxMCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IHN0cmluZyBhcnJheSBmb3IgbGltaXQgSW50ZWdlci5NQVhfVkFMVUUiLAorICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMocmVzdWx0c1sxXSwgc3RyLnNwbGl0KHBhdHRlcm4sIEludGVnZXIuTUFYX1ZBTFVFKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdHIuc3BsaXQoIlthfSIsIDApOworICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gcHNlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlcGxhY2VMamF2YV9sYW5nQ2hhclNlcXVlbmNlTGphdmFfbGFuZ0NoYXJTZXF1ZW5jZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgcmVwbGFjZSIsICJhYWNjZGQiLCAiYWFiYmRkIi5yZXBsYWNlKAorICAgICAgICAgICAgbmV3IFN0cmluZ0J1ZmZlcigiYmIiKSwgImNjIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCByZXBsYWNlIGJ5IGJpZ2dlciBzZXEiLCAiY2NjYmNjYyIsICJhYmEiLnJlcGxhY2UoCisgICAgICAgICAgICAiYSIsICJjY2MiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHJlcGxhY2UgYnkgc21hbGxlciBzZXEiLCAiJGJiYV4iLAorICAgICAgICAgICAgIiRhYWFhYV4iLnJlcGxhY2UobmV3IFN0cmluZ0J1aWxkZXIoImFhIiksICJiIikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAiIi5yZXBsYWNlKChDaGFyU2VxdWVuY2UpIG51bGwsICIxMjMiLnN1YlNlcXVlbmNlKDAsIDEpKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgIiIucmVwbGFjZSgiMTIzIi5zdWJTZXF1ZW5jZSgwLCAxKSwgKENoYXJTZXF1ZW5jZSkgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdWJzdHJpbmdJKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaHcxLnN1YnN0cmluZygtMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBodzEuc3Vic3RyaW5nKGh3MS5sZW5ndGgoKSArIDEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaHcxLnN1YnN0cmluZyhJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3Vic3RyaW5nSUkoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBodzEuc3Vic3RyaW5nKC0xLCBodzEubGVuZ3RoKCkpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaHcxLnN1YnN0cmluZyhJbnRlZ2VyLk1BWF9WQUxVRSwgaHcxLmxlbmd0aCgpKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpb29iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGh3MS5zdWJzdHJpbmcoMCwgSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1YlNlcXVlbmNlKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLlN0cmluZyBqYXZhLmxhbmcuU3RyaW5nLnN1YnN0cmluZyhpbnQsIGludCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHN1YnN0cmluZyByZXR1cm5lZCIsIGh3MS5zdWJTZXF1ZW5jZSgwLCA1KS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICAgIkhlbGxvIikgJiYgKGh3MS5zdWJTZXF1ZW5jZSg1LCAxMCkuZXF1YWxzKCJXb3JsZCIpKSk7CisgICAgICAgIGFzc2VydFRydWUoIm5vdCBpZGVudGljYWwiLCBodzEuc3ViU2VxdWVuY2UoMCwgaHcxLmxlbmd0aCgpKSA9PSBodzEpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBodzEuc3ViU2VxdWVuY2UoMCwgSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaHcxLnN1YlNlcXVlbmNlKEludGVnZXIuTUFYX1ZBTFVFLCBodzEubGVuZ3RoKCkpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaHcxLnN1YlNlcXVlbmNlKC0xLCBodzEubGVuZ3RoKCkpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RyaW0oKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHN0cmluZyByZXR1cm5lZCIsIGh3MSwgIiAgSGVsbG9Xb3JsZCAgIi50cmltKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3Qgc3RyaW5nIHJldHVybmVkIiwgIiAgICIudHJpbSgpLmVxdWFscygiIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdmFsdWVPZiRDKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBTdHJpbmciLAorICAgICAgICAgICAgICAgICJXb3JsZCIsIFN0cmluZy52YWx1ZU9mKGJ1ZikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBTdHJpbmciLAorICAgICAgICAgICAgICAgICIiLCBTdHJpbmcudmFsdWVPZihuZXcgY2hhcltde30pKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZy52YWx1ZU9mKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3ZhbHVlT2YkQ0lJKCkgeworICAgICAgICBjaGFyW10gdCA9IHsgJ0gnLCAnZScsICdsJywgJ2wnLCAnbycsICdXJywgJ28nLCAncicsICdsJywgJ2QnIH07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZy52YWx1ZU9mKHQsIDAsIHQubGVuZ3RoICsgMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcudmFsdWVPZih0LCAwLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcudmFsdWVPZih0LCAwLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdmFsdWVPZkxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB2YWx1ZSB3YXMgcmV0dXJuZWQgZm9yIG51bGwuIiwKKyAgICAgICAgICAgICAgICAgIm51bGwiLCBTdHJpbmcudmFsdWVPZigoT2JqZWN0KSBudWxsKSk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoImJveGluZyIpCisgICAgcHVibGljIHZvaWQgdGVzdF9mb3JtYXQoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiMyAyIDEgNCAzIDIgMSIsIFN0cmluZy5mb3JtYXQoCisgICAgICAgICAgICAgICAgIiUzJGQgJTIkZCAlMSRkICU0JGQgJTMkZCAlMiRkICUxJGQiLCAxLCAyLCAzLCA0KSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbXB0eSBmb3JtYXQiLCAiIiwgU3RyaW5nLmZvcm1hdCgiIiwgMTIzLCB0aGlzKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcuZm9ybWF0KG51bGwpOworICAgICAgICAgICAgZmFpbCgiTlBFIGlzIGV4cGVjdGVkIG9uIG51bGwgZm9ybWF0Iik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG9rKXt9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZy5mb3JtYXQoIiVkJSUgb2YgJXMgaXMgMHgleCIsICIxMjMiKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxGb3JtYXRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbiBpZmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcuZm9ybWF0KCIldHUiLCAiMTIzIik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsRm9ybWF0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxGb3JtYXRFeGNlcHRpb24gaWZlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJib3hpbmciKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZm9ybWF0X0xvY2FsZSgpIHsKKyAgICAgICAgTG9jYWxlIGwgPSBuZXcgTG9jYWxlKCJVSyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEzJSBvZiBzdW0gaXMgMHgxMSIsCisgICAgICAgICAgICAgICAgU3RyaW5nLmZvcm1hdChsLCAiJWQlJSBvZiAlcyBpcyAweCV4IiwgMTMsICJzdW0iLCAxNykpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVtcHR5IGZvcm1hdCIsICIiLCBTdHJpbmcuZm9ybWF0KCIiLCAxMjMsIHRoaXMpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZy5mb3JtYXQobCwgbnVsbCwgIiIpOworICAgICAgICAgICAgZmFpbCgiTlBFIGlzIGV4cGVjdGVkIG9uIG51bGwgZm9ybWF0Iik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG9rKXt9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZy5mb3JtYXQobCwgIiVkIiwgInRlc3QiKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxGb3JtYXRFeGNlcHRpb24gd2Fzbid0IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsRm9ybWF0RXhjZXB0aW9uIGlmZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9tYXRjaGVzKCkgeworICAgICAgICBTdHJpbmdbXSBwYXR0ZXJucyA9IHsKKyAgICAgICAgICAgICAgICAiKGF8YikqYWJiIiwKKyAgICAgICAgICAgICAgICAiKDEqMiozKjQqKSo1NjciLAorICAgICAgICAgICAgICAgICIoYXxifGN8ZCkqYWFiIiwKKyAgICAgICAgICAgICAgICAiKDF8MnwzfDR8NXw2fDd8OHw5fDApKDF8MnwzfDR8NXw2fDd8OHw5fDApKiIsCisgICAgICAgICAgICAgICAgIihhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaKSoiLAorICAgICAgICAgICAgICAgICIoYXxiKSooYXxiKSpBKGF8YikqbGljZS4qIiwKKyAgICAgICAgICAgICAgICAiKGF8YnxjfGR8ZXxmfGd8aHxpfGp8a3xsfG18bnxvfHB8cXxyfHN8dHx1fHZ8d3x4fHl8eikoYXxifGN8ZHxlfGZ8Z3xofCIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIml8anxrfGx8bXxufG98cHxxfHJ8c3x0fHV8dnx3fHh8eXx6KSooMXwyfDN8NHw1fDZ8N3w4fDl8MCkqfHdoaWxlfGZvcnxzdHJ1Y3R8aWZ8ZG8iLAorCisgICAgICAgfTsKKworICAgICAgICBTdHJpbmdbXSBwYXR0ZXJuc0luYyA9IHsKKyAgICAgICAgICAgICAgICAiKGFjKSpiYiIsCisgICAgICAgICAgICAgICAgIigxKSo1NjciLAorICAgICAgICAgICAgICAgICIoYykqYWIiLAorICAgICAgICAgICAgICAgICIofDh8OXwwKSgxfDJ8N3w4fDl8MCkqIiwKKyAgICAgICAgICAgICAgICAiKHopIiwKKyAgICAgICAgICAgICAgICAiKGEpKkEoYikqbGljZS4iLAorICAgICAgICAgICAgICAgICIoYXxifGN8ZHxlKSIsCisKKyAgICAgICB9OworCisgICAgICAgIFN0cmluZ1tdW10gc3RyaW5ncyA9IHsKKyAgICAgICAgICAgICAgICB7ICJhYmIiLCAiYWJhYmIiLCAiYWJhYmFiYmFiYWJiIiwgImFiYWJhYmJhYmFiYmFiYWJhYmJiYmJhYmIiIH0sCisgICAgICAgICAgICAgICAgeyAiMjEzNTY3IiwgIjEyMzI0NTY3IiwgIjEyMzQ1NjciLCAiMjEzMjEzNTY3IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICIyMTMxMjMxMjMxMjU2NyIsICI0NDQ0NDQ1NjciIH0sCisgICAgICAgICAgICAgICAgeyAiYWJjZGFhYiIsICJhYWIiLCAiYWJhYWIiLCAiY2RhYWIiLCAiYWNiZGFkY2JhYWIiIH0sCisgICAgICAgICAgICAgICAgeyAiMjEzMjM0NTY3IiwgIjM0NTgiLCAiMDk4NzY1NCIsICI3Njg5NTQ2NDMyIiwgIjAzOTg1NzYiLAorICAgICAgICAgICAgICAgICAgICAgICAgIjk4NDMyIiwgIjUiIH0sCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoiLAorICAgICAgICAgICAgICAgICAgICAgICAgImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoiIH0sCisgICAgICAgICAgICAgICAgeyAiYWJhYmJhQWFiYWJhYmJsaWNlIiwgImFiYWJiYUFsaWNlYWJhYmFiIiwgImFiYWJiQWFibGljZWFhYSIsCisgICAgICAgICAgICAgICAgICAgICAgICAiYWJiYkFiYmJsaWNlYWFhIiwgIkFsaWNlIiB9LAorICAgICAgICAgICAgICAgIHsgImExMjMiLCAiYm54bnZnZHMxNTYiLCAiZm9yIiwgIndoaWxlIiwgImlmIiwgInN0cnVjdCIgfSwKKyAgICAgICAgICAgICAgICB7ICJ4eSIgfSwgeyAieHkiIH0sIHsgInhjeSIgfQorCisgICAgICAgIH07CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXR0ZXJucy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBzdHJpbmdzW2ldLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG1hdGNoOiAiICsgcGF0dGVybnNbaV0gKyAiIHZzICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgc3RyaW5nc1tpXVtqXSwgc3RyaW5nc1tpXVtqXS5tYXRjaGVzKHBhdHRlcm5zW2ldKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIiIgKyBpLCBzdHJpbmdzW2ldW2pdLm1hdGNoZXMocGF0dGVybnNJbmNbaV0pKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5kZXhPZkkoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiRG9lc24ndCByZXR1cm4gLTEgaWYgdGhlcmUgaXMgbm8gc3VjaCBjaGFyYWN0ZXIuIiwgLTEsCisgICAgICAgICAgICAgICAgaHcxLmluZGV4T2YoJ3EnKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pbmRleE9mSUkoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiRG9lc24ndCByZXR1cm4gLTEgaWYgdGhlcmUgaXMgbm8gc3VjaCBjaGFyYWN0ZXIuIiwgLTEsCisgICAgICAgICAgICAgICAgaHcxLmluZGV4T2YoJ0gnLCAyKSk7CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luZGV4T2ZMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJEb2Vzbid0IHJldHVybiAtMSBmb3IgdW5rbm93biBzdHJpbmcuIiwKKyAgICAgICAgICAgICAgICAtMSwgaHcxLmluZGV4T2YoIkhlbyIpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkU3lzdGVtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZFN5c3RlbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZWU1YmRkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZFN5c3RlbVRlc3QuamF2YQpAQCAtMCwwICsxLDM2MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5zcGkuU2VsZWN0b3JQcm92aWRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKK3B1YmxpYyBjbGFzcyBPbGRTeXN0ZW1UZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYXJyYXljb3B5TGphdmFfbGFuZ19PYmplY3RJTGphdmFfbGFuZ19PYmplY3RJSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS5sYW5nLlN5c3RlbS5hcnJheWNvcHkoamF2YS5sYW5nLk9iamVjdCwKKyAgICAgICAgLy8gaW50LCBqYXZhLmxhbmcuT2JqZWN0LCBpbnQsIGludCkKKyAgICAgICAgSW50ZWdlciBhW10gPSBuZXcgSW50ZWdlclsyMF07CisgICAgICAgIEludGVnZXIgYltdID0gbmV3IEludGVnZXJbMjBdOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBjb3B5IGZyb20gbm9uIGFycmF5IG9iamVjdCBpbnRvIE9iamVjdCBhcnJheQorICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShuZXcgT2JqZWN0KCksIDAsIGIsIDAsIDApOworICAgICAgICAgICAgZmFpbCgiQXJyYXlTdG9yZUV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKEFycmF5U3RvcmVFeGNlcHRpb24gIGFzZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGNvcHkgZnJvbSBPYmplY3QgYXJyYXkgaW50byBub24gYXJyYXkgb2JqZWN0CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIDAsIG5ldyBPYmplY3QoKSwgMCwgMCk7CisgICAgICAgICAgICBmYWlsKCJBcnJheVN0b3JlRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goQXJyYXlTdG9yZUV4Y2VwdGlvbiAgYXNlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gY29weSBmcm9tIHByaW1pdGl2ZSBhcnJheSBpbnRvIG9iamVjdCBhcnJheQorICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShuZXcgY2hhcltdIHsnYSd9LCAwLCBuZXcgU3RyaW5nWzFdLCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5U3RvcmVFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChBcnJheVN0b3JlRXhjZXB0aW9uICBhc2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBjb3B5IGZyb20gb2JqZWN0IGFycmF5IGludG8gcHJpbWl0aXZlIGFycmF5CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5ldyBTdHJpbmdbXSB7ImEifSwgMCwgbmV3IGNoYXJbMV0sIDAsIDEpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlTdG9yZUV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKEFycmF5U3RvcmVFeGNlcHRpb24gIGFzZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGNvcHkgZnJvbSBwcmltaXRpdmUgYXJyYXkgaW50byBhbiBhcnJheSBvZiBhbm90aGVyIHByaW1pdGl2ZSB0eXBlCisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5ldyBjaGFyW10geydhJ30sIDAsIG5ldyBpbnRbMV0sIDAsIDEpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlTdG9yZUV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKEFycmF5U3RvcmVFeGNlcHRpb24gIGFzZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGNvcHkgZnJvbSBvYmplY3QgYXJyYXkgaW50byBhbiBhcnJheSBvZiBhbm90aGVyIE9iamVjdCB0eXBlCisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5ldyBDaGFyYWN0ZXJbXSB7J2EnfSwgMCwgbmV3IEludGVnZXJbMV0sIDAsIDEpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlTdG9yZUV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKEFycmF5U3RvcmVFeGNlcHRpb24gIGFzZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGNvcHkgZnJvbSBudWxsIGludG8gYW4gYXJyYXkgb2YgYSBwcmltaXRpdmUgdHlwZQorICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShudWxsLCAwLCBuZXcgaW50WzFdLCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gY29weSBmcm9tIGEgcHJpbWl0aXZlIGFycmF5IGludG8gbnVsbAorICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShuZXcgaW50W117JzEnfSwgMCwgbnVsbCwgMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYSwgYS5sZW5ndGggKyAxLCBiLCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhLCAtMSwgYiwgMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpb29iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYSwgMCwgYiwgLTEsIDEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIDAsIGIsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhLCAxMSwgYiwgMCwgMTApOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGEsIEludGVnZXIuTUFYX1ZBTFVFLCBiLCAwLCAxMCk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpb29iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYSwgMCwgYiwgSW50ZWdlci5NQVhfVkFMVUUsIDEwKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlvb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhLCAwLCBiLCAxMCwgSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9vYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY3VycmVudFRpbWVNaWxsaXMoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBsb25nIGphdmEubGFuZy5TeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbG9uZyBmaXJzdFJlYWQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDE1MCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsb25nIHNlY29uZFJlYWQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCB0aW1lcyByZXR1cm5lZDogIiArIGZpcnN0UmVhZCArICIsICIKKyAgICAgICAgICAgICAgICAgICAgKyBzZWNvbmRSZWFkLCBmaXJzdFJlYWQgPCBzZWNvbmRSZWFkKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgdGVzdDogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFByb3BlcnRpZXMoKSB7CisgICAgICAgIFN0cmluZyBbXSBwcm9wcyA9IHsiamF2YS52ZW5kb3IudXJsIiwKKyAgICAgICAgICAgICAgICAiamF2YS5jbGFzcy5wYXRoIiwgInVzZXIuaG9tZSIsCisgICAgICAgICAgICAgICAgImphdmEuY2xhc3MudmVyc2lvbiIsICJvcy52ZXJzaW9uIiwKKyAgICAgICAgICAgICAgICAiamF2YS52ZW5kb3IiLCAidXNlci5kaXIiLAorICAgICAgICAgICAgICAgIC8qInVzZXIudGltZXpvbmUiLCovICJwYXRoLnNlcGFyYXRvciIsCisgICAgICAgICAgICAgICAgIm9zLm5hbWUiLCAib3MuYXJjaCIsCisgICAgICAgICAgICAgICAgImxpbmUuc2VwYXJhdG9yIiwgImZpbGUuc2VwYXJhdG9yIiwKKyAgICAgICAgICAgICAgICAidXNlci5uYW1lIiwgImphdmEudmVyc2lvbiIsICJqYXZhLmhvbWUiIH07CisKKyAgICAgICAgUHJvcGVydGllcyBwID0gU3lzdGVtLmdldFByb3BlcnRpZXMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwLnNpemUoKSA+IDApOworCisgICAgICAgIC8vIEVuc3VyZSBzcGVjJ2VkIHByb3BlcnRpZXMgYXJlIG5vbi1udWxsLiBTZWUgU3lzdGVtLmdldFByb3BlcnRpZXMoKQorICAgICAgICAvLyBzcGVjLgorCisgICAgICAgIGZvciAoU3RyaW5nIHByb3AgOiBwcm9wcykgeworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiVGhlcmUgaXMgbm8gcHJvcGVydHkgYW1vbmcgcmV0dXJuZWQgcHJvcGVydGllczogIgorICAgICAgICAgICAgICAgICAgICArIHByb3AsIHAuZ2V0UHJvcGVydHkocHJvcCkpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiU3lzdGVtIHByb3BlcnR5IGlzIG51bGw6ICIgKyBwcm9wLAorICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZ2V0UHJvcGVydHkocHJvcCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQcm9wZXJ0eUxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLmdldFByb3BlcnR5KG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTeXN0ZW0uZ2V0UHJvcGVydHkoIiIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UHJvcGVydHlMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLmdldFByb3BlcnR5KG51bGwsICIwLjAiKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLmdldFByb3BlcnR5KCIiLCAiMCIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5oZXJpdGVkQ2hhbm5lbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIENoYW5uZWwgaUNoYW5uZWwgPSBTeXN0ZW0uaW5oZXJpdGVkQ2hhbm5lbCgpOworICAgICAgICBhc3NlcnROdWxsKCJJbmNvcnJlY3QgdmFsdWUgb2YgY2hhbm5lbCIsIGlDaGFubmVsKTsKKyAgICAgICAgU2VsZWN0b3JQcm92aWRlciBzcCA9IFNlbGVjdG9yUHJvdmlkZXIucHJvdmlkZXIoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdmFsdWUgb2YgY2hhbm5lbCIsCisgICAgICAgICAgICAgICAgc3AuaW5oZXJpdGVkQ2hhbm5lbCgpLCBpQ2hhbm5lbCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jbGVhclByb3BlcnR5KCkgeworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoInRlc3QiLCAidmFsdWUiKTsKKyAgICAgICAgU3lzdGVtLmNsZWFyUHJvcGVydHkoInRlc3QiKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiUHJvcGVydHkgd2FzIG5vdCBkZWxldGVkLiIsIFN5c3RlbS5nZXRQcm9wZXJ0eSgidGVzdCIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLmNsZWFyUHJvcGVydHkobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN5c3RlbS5jbGVhclByb3BlcnR5KCIiKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2MoKSB7CisgICAgICAgIFJ1bnRpbWUgcnQgPSAgUnVudGltZS5nZXRSdW50aW1lKCk7CisgICAgICAgIFZlY3RvcjxTdHJpbmdCdWZmZXI+IHZlYyA9IG5ldyBWZWN0b3I8U3RyaW5nQnVmZmVyPigpOworICAgICAgICBsb25nIGJlZm9yZVRlc3QgPSBydC5mcmVlTWVtb3J5KCk7CisgICAgICAgIHdoaWxlKHJ0LmZyZWVNZW1vcnkoKSA8IGJlZm9yZVRlc3QgKiAyLzMpIHsKKyAgICAgICAgICAgICB2ZWMuYWRkKG5ldyBTdHJpbmdCdWZmZXIoMTAwMCkpOworICAgICAgICB9CisgICAgICAgIGxvbmcgYmVmb3JlR0MgPSBydC5mcmVlTWVtb3J5KCk7CisgICAgICAgIFN5c3RlbS5nYygpOworICAgICAgICBsb25nIGFmdGVyR0MgPSBydC5mcmVlTWVtb3J5KCk7CisgICAgICAgIGFzc2VydFRydWUoIm1lbW9yeSB3YXMgbm90IHJlbGVhc2VkIGFmdGVyIGNhbGxpbmcgU3lzdGVtLmdjKCkuIiArCisgICAgICAgICAgICAgICAgImJlZm9yZSBnYzogIiArIGJlZm9yZUdDICsgIjsgYWZ0ZXIgZ2M6ICIgKyBhZnRlckdDLAorICAgICAgICAgICAgICAgIGJlZm9yZUdDIDwgYWZ0ZXJHQyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRlbnYoKSB7CisgICAgICAgIC8vIFN0cmluZ1tdIHByb3BzID0geyAiUEFUSCIsICJIT01FIiwgIlVTRVIifTsKKyAgICAgICAgLy8gb25seSBQQVRIIG9mIHRoZXNlIHRocmVlIGV4aXN0cyBvbiBhbmRyb2lkCisgICAgICAgIFN0cmluZ1tdIHByb3BzID0geyAiUEFUSCIgfTsKKworICAgICAgICBNYXA8U3RyaW5nLFN0cmluZz4gZW52TWFwID0gU3lzdGVtLmdldGVudigpOworICAgICAgICBhc3NlcnRGYWxzZSgiZW52aXJvbm1lbnQgbWFwIGlzIGVtcHR5LiIsIGVudk1hcC5pc0VtcHR5KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJlbnYgbWFwIGNvbnRhaW5zIGxlc3MgdGhhbiAzIGtleXMuIiwKKyAgICAgICAgICAgICAgICBwcm9wcy5sZW5ndGggPCBlbnZNYXAua2V5U2V0KCkuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChTdHJpbmcgcHJvcCA6IHByb3BzKSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJUaGVyZSBpcyBubyBwcm9wZXJ0eTogIiArIHByb3AsCisgICAgICAgICAgICAgICAgICAgIGVudk1hcC5nZXQocHJvcCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRlbnZMU3RyaW5nKCkgeworICAgICAgICBhc3NlcnROb3ROdWxsKCJQQVRIIGVudmlyb25tZW50IHZhcmlhYmxlIGlzIG5vdCBmb3VuZCIsCisgICAgICAgICAgICAgICAgICBTeXN0ZW0uZ2V0ZW52KCJQQVRIIikpOworCisgICAgICAgIGFzc2VydE51bGwoIkRvZXNuJ3QgcmV0dXJuIE5VTEwgZm9yIG5vbiBleGlzdGVudCBwcm9wZXJ0eSIsCisgICAgICAgICAgICAgICAgICBTeXN0ZW0uZ2V0ZW52KCJub25leGlzdGVudC5wcm9wZXJ0eSIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLmdldGVudihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xvYWQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5sb2FkKCJub25FeGlzdGVudExpYnJhcnkiKTsKKyAgICAgICAgICAgIGZhaWwoIlVuc2F0aXNmaWVkTGlua0Vycm9yIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFVuc2F0aXNmaWVkTGlua0Vycm9yICBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLmxvYWQoIm5vbkV4aXN0ZW50TGlicmFyeSIpOworICAgICAgICAgICAgZmFpbCgiVW5zYXRpc2ZpZWRMaW5rRXJyb3Igd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goVW5zYXRpc2ZpZWRMaW5rRXJyb3IgdWxlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLmxvYWQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbG9hZExpYnJhcnkoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTeXN0ZW0ubG9hZExpYnJhcnkoIm5vbkV4aXN0ZW50TGlicmFyeSIpOworICAgICAgICAgICAgZmFpbCgiVW5zYXRpc2ZpZWRMaW5rRXJyb3Igd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goVW5zYXRpc2ZpZWRMaW5rRXJyb3IgdWxlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLmxvYWRMaWJyYXJ5KG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X21hcExpYnJhcnlOYW1lKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoImxpYm5hbWUuc28iLCBTeXN0ZW0ubWFwTGlicmFyeU5hbWUoIm5hbWUiKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN5c3RlbS5tYXBMaWJyYXJ5TmFtZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X25hbm9UaW1lKCkgeworICAgICAgICBsb25nIHNsZWVwVGltZSA9IDUwMDA7CisgICAgICAgIGxvbmcgYmVnaW5UaW1lID0gU3lzdGVtLm5hbm9UaW1lKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUaHJlYWQuc2xlZXAoc2xlZXBUaW1lKTsKKyAgICAgICAgfSBjYXRjaChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5rbm93biBleGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBsb25nIGVuZFRpbWUgPSBTeXN0ZW0ubmFub1RpbWUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgoZW5kVGltZSAtIGJlZ2luVGltZSkgPiBzbGVlcFRpbWUgKiAxMDAwMDAwKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkVGhyZWFkR3JvdXBUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkVGhyZWFkR3JvdXBUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDhmMTUzYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRUaHJlYWRHcm91cFRlc3QuamF2YQpAQCAtMCwwICsxLDM3OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZFRocmVhZEdyb3VwVGVzdCBleHRlbmRzIFRlc3RDYXNlIGltcGxlbWVudHMgVGhyZWFkLlVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlciB7CisKKyAgICBjbGFzcyBNeVRocmVhZCBleHRlbmRzIFRocmVhZCB7CisgICAgICAgIHB1YmxpYyB2b2xhdGlsZSBpbnQgaGVhcnRCZWF0ID0gMDsKKworICAgICAgICBwdWJsaWMgTXlUaHJlYWQoVGhyZWFkR3JvdXAgZ3JvdXAsIFN0cmluZyBuYW1lKQorICAgICAgICAgICAgICAgIHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiwgSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyKGdyb3VwLCBuYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgIGhlYXJ0QmVhdCsrOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCg1MCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0FjdGl2ZWx5UnVubmluZygpIHsKKyAgICAgICAgICAgIGxvbmcgTUFYX1dBSVQgPSAxMDA7CisgICAgICAgICAgICByZXR1cm4gaXNBY3RpdmVseVJ1bm5pbmcoTUFYX1dBSVQpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNBY3RpdmVseVJ1bm5pbmcobG9uZyBtYXhXYWl0KSB7CisgICAgICAgICAgICBpbnQgYmVhdCA9IGhlYXJ0QmVhdDsKKyAgICAgICAgICAgIGxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICBUaHJlYWQueWllbGQoKTsKKyAgICAgICAgICAgICAgICBpbnQgYmVhdDIgPSBoZWFydEJlYXQ7CisgICAgICAgICAgICAgICAgaWYgKGJlYXQgIT0gYmVhdDIpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSB3aGlsZSAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydCA8IG1heFdhaXQpOworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIFRocmVhZEdyb3VwIGluaXRpYWxUaHJlYWRHcm91cCA9IG51bGw7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FjdGl2ZUdyb3VwQ291bnQoKSB7CisgICAgICAgIFRocmVhZEdyb3VwIHRnID0gbmV3IFRocmVhZEdyb3VwKCJncm91cCBjb3VudCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBudW1iZXIgb2YgZ3JvdXBzIiwKKyAgICAgICAgICAgICAgICAwLCB0Zy5hY3RpdmVHcm91cENvdW50KCkpOworICAgICAgICBUaHJlYWQgdDEgPSBuZXcgVGhyZWFkKHRnLCBuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IG51bWJlciBvZiBncm91cHMiLAorICAgICAgICAgICAgICAgIDAsIHRnLmFjdGl2ZUdyb3VwQ291bnQoKSk7CisgICAgICAgIHQxLnN0YXJ0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IG51bWJlciBvZiBncm91cHMiLAorICAgICAgICAgICAgICAgIDAsIHRnLmFjdGl2ZUdyb3VwQ291bnQoKSk7CisgICAgICAgIG5ldyBUaHJlYWRHcm91cCh0ZywgInRlc3QgZ3JvdXAgMSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBudW1iZXIgb2YgZ3JvdXBzIiwKKyAgICAgICAgICAgICAgICAxLCB0Zy5hY3RpdmVHcm91cENvdW50KCkpOworICAgICAgICBuZXcgVGhyZWFkR3JvdXAodGcsICJ0ZXN0IGdyb3VwIDIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbnVtYmVyIG9mIGdyb3VwcyIsCisgICAgICAgICAgICAgICAgMiwgdGcuYWN0aXZlR3JvdXBDb3VudCgpKTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfYWxsb3dUaHJlYWRTdXNwZW5zaW9uWigpIHsKKyAgICAgICAgVGhyZWFkR3JvdXAgdGcgPSBuZXcgVGhyZWFkR3JvdXAoInRocmVhZCBzdXNwZW5zaW9uIik7CisgICAgICAgIGFzc2VydFRydWUoIlRocmVhZCBzdXNwZW50aW9uIGNhbiBub3QgYmUgY2hhbmdlZCIsCisgICAgICAgICAgICAgICAgdGcuYWxsb3dUaHJlYWRTdXNwZW5zaW9uKGZhbHNlKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRocmVhZCBzdXNwZW50aW9uIGNhbiBub3QgYmUgY2hhbmdlZCIsCisgICAgICAgICAgICAgICAgdGcuYWxsb3dUaHJlYWRTdXNwZW5zaW9uKHRydWUpKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBjdXJyZW50IFRocmVhZCBpcyBpbiB0aGUgZ2l2ZW4gbGlzdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaW5MaXN0T2ZUaHJlYWRzKFRocmVhZFtdIHRocmVhZHMpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aHJlYWRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoVGhyZWFkLmN1cnJlbnRUaHJlYWQoKSA9PSB0aHJlYWRzW2ldKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9lbnVtZXJhdGVMVGhyZWFkQXJyYXkoKSB7CisgICAgICAgIGludCBudW1UaHJlYWRzID0gaW5pdGlhbFRocmVhZEdyb3VwLmFjdGl2ZUNvdW50KCk7CisgICAgICAgIFRocmVhZFtdIGxpc3RPZlRocmVhZHMgPSBuZXcgVGhyZWFkW251bVRocmVhZHNdOworCisgICAgICAgIGludCBjb3VudFRocmVhZCA9IGluaXRpYWxUaHJlYWRHcm91cC5lbnVtZXJhdGUobGlzdE9mVGhyZWFkcyk7CisgICAgICAgIGFzc2VydEVxdWFscyhudW1UaHJlYWRzLCBjb3VudFRocmVhZCk7CisgICAgICAgIGFzc2VydFRydWUoIkN1cnJlbnQgdGhyZWFkIG11c3QgYmUgaW4gZW51bWVyYXRpb24gb2YgdGhyZWFkcyIsCisgICAgICAgICAgICAgICAgaW5MaXN0T2ZUaHJlYWRzKGxpc3RPZlRocmVhZHMpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VudW1lcmF0ZUxUaHJlYWRBcnJheUxadGVzdF9lbnVtZXJhdGVMVGhyZWFkQXJyYXlMWigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBjYXB0dXJlIHRoZSBpbml0aWFsIGNvbmRpdGlvbgorICAgICAgICBpbnQgaW5pdGlhbFRocmVhZENvdW50ID0gaW5pdGlhbFRocmVhZEdyb3VwLmFjdGl2ZUNvdW50KCk7CisgICAgICAgIFRocmVhZFtdIGluaXRpYWxUaHJlYWRzID0gbmV3IFRocmVhZFtpbml0aWFsVGhyZWFkQ291bnRdOworICAgICAgICBhc3NlcnRFcXVhbHMoaW5pdGlhbFRocmVhZENvdW50LCBpbml0aWFsVGhyZWFkR3JvdXAuZW51bWVyYXRlKGluaXRpYWxUaHJlYWRzLCBmYWxzZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoaW5pdGlhbFRocmVhZENvdW50LCBpbml0aWFsVGhyZWFkR3JvdXAuZW51bWVyYXRlKGluaXRpYWxUaHJlYWRzLCB0cnVlKSk7CisgICAgICAgIGFzc2VydFRydWUoaW5MaXN0T2ZUaHJlYWRzKGluaXRpYWxUaHJlYWRzKSk7CisKKyAgICAgICAgLy8gc3RhcnQgc29tZSB0aGUgdGhyZWFkcyBhbmQgc2VlIGhvdyB0aGUgY291bnQgY2hhbmdlcworICAgICAgICBUaHJlYWRHcm91cCBncm91cCA9IG5ldyBUaHJlYWRHcm91cChpbml0aWFsVGhyZWFkR3JvdXAsICJlbnVtZXJhdGVUaHJlYWRBcnJheSIpOworICAgICAgICBpbnQgZ3JvdXBTaXplID0gMzsKKyAgICAgICAgTGlzdDxNeVRocmVhZD4gbmV3VGhyZWFkcyA9IHBvcHVsYXRlR3JvdXBzV2l0aFRocmVhZHMoZ3JvdXAsIGdyb3VwU2l6ZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhpbml0aWFsVGhyZWFkQ291bnQsIGluaXRpYWxUaHJlYWRHcm91cC5lbnVtZXJhdGUoaW5pdGlhbFRocmVhZHMsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShpbkxpc3RPZlRocmVhZHMoaW5pdGlhbFRocmVhZHMpKTsKKyAgICAgICAgZm9yKE15VGhyZWFkIHRocmVhZCA6IG5ld1RocmVhZHMpIHsKKyAgICAgICAgICAgIHRocmVhZC5zdGFydCgpOworICAgICAgICB9CisgICAgICAgIFRocmVhZC5zbGVlcCg1MDApOyAvLyBzdGFydGluZyB0aHJlYWRzIGlzbid0IGluc3RhbnQhCisgICAgICAgIGludCBhZnRlclN0YXJ0Q291bnQgPSBpbml0aWFsVGhyZWFkR3JvdXAuYWN0aXZlQ291bnQoKTsKKyAgICAgICAgU2V0PFRocmVhZD4gaW5pdGlhbFBsdXNOZXcgPSBuZXcgSGFzaFNldDxUaHJlYWQ+KCk7CisgICAgICAgIGluaXRpYWxQbHVzTmV3LmFkZEFsbChBcnJheXMuYXNMaXN0KGluaXRpYWxUaHJlYWRzKSk7CisgICAgICAgIGluaXRpYWxQbHVzTmV3LmFkZEFsbChuZXdUaHJlYWRzKTsKKyAgICAgICAgVGhyZWFkW10gYWZ0ZXJTdGFydFRocmVhZHMgPSBuZXcgVGhyZWFkW2FmdGVyU3RhcnRDb3VudF07CisgICAgICAgIGFzc2VydEVxdWFscyhhZnRlclN0YXJ0Q291bnQsIGluaXRpYWxUaHJlYWRHcm91cC5lbnVtZXJhdGUoYWZ0ZXJTdGFydFRocmVhZHMsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGluaXRpYWxQbHVzTmV3LCBuZXcgSGFzaFNldDxUaHJlYWQ+KEFycmF5cy5hc0xpc3QoYWZ0ZXJTdGFydFRocmVhZHMpKSk7CisgICAgICAgIGFzc2VydFRydWUoaW5MaXN0T2ZUaHJlYWRzKGFmdGVyU3RhcnRUaHJlYWRzKSk7CisKKyAgICAgICAgLy8ga2lsbCB0aGUgdGhyZWFkcyBhbmQgY291bnQgJ2VtIGFnYWluCisgICAgICAgIGZvcihNeVRocmVhZCB0aHJlYWQgOiBuZXdUaHJlYWRzKSB7CisgICAgICAgICAgICB0aHJlYWQuaW50ZXJydXB0KCk7CisgICAgICAgIH0KKyAgICAgICAgVGhyZWFkLnNsZWVwKDUwMCk7IC8vIGtpbGxpbmcgdGhyZWFkcyBpc24ndCBpbnN0YW50CisgICAgICAgIGludCBhZnRlckRlYXRoQ291bnQgPSBpbml0aWFsVGhyZWFkR3JvdXAuYWN0aXZlQ291bnQoKTsKKyAgICAgICAgVGhyZWFkW10gYWZ0ZXJEZWF0aFRocmVhZHMgPSBuZXcgVGhyZWFkW2FmdGVyRGVhdGhDb3VudF07CisgICAgICAgIGFzc2VydEVxdWFscyhhZnRlckRlYXRoQ291bnQsIGluaXRpYWxUaHJlYWRHcm91cC5lbnVtZXJhdGUoYWZ0ZXJEZWF0aFRocmVhZHMsIGZhbHNlKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KGluaXRpYWxUaHJlYWRzKSwgQXJyYXlzLmFzTGlzdChhZnRlckRlYXRoVGhyZWFkcykpOworICAgICAgICBhc3NlcnRUcnVlKGluTGlzdE9mVGhyZWFkcyhhZnRlckRlYXRoVGhyZWFkcykpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZW51bWVyYXRlTFRocmVhZEdyb3VwQXJyYXkoKSB7CisgICAgICAgIGludCBudW1DaGlsZEdyb3Vwc0JlZm9yZSA9IGluaXRpYWxUaHJlYWRHcm91cC5hY3RpdmVHcm91cENvdW50KCk7CisgICAgICAgIFRocmVhZEdyb3VwIGNoaWxkR3JvdXAgPSBuZXcgVGhyZWFkR3JvdXAoaW5pdGlhbFRocmVhZEdyb3VwLCAiY2hpbGQgZ3JvdXAiKTsKKworICAgICAgICBpbnQgbnVtQ2hpbGRHcm91cHNBZnRlciA9IGluaXRpYWxUaHJlYWRHcm91cC5hY3RpdmVHcm91cENvdW50KCk7CisgICAgICAgIGFzc2VydFRydWUoaW5pdGlhbFRocmVhZEdyb3VwLnRvU3RyaW5nKCksIG51bUNoaWxkR3JvdXBzQWZ0ZXIgPT0gbnVtQ2hpbGRHcm91cHNCZWZvcmUgKyAxKTsKKyAgICAgICAgVGhyZWFkR3JvdXBbXSBsaXN0T2ZHcm91cHMgPSBuZXcgVGhyZWFkR3JvdXBbbnVtQ2hpbGRHcm91cHNBZnRlcl07CisKKyAgICAgICAgaW50IGNvdW50R3JvdXBUaHJlYWQgPSBpbml0aWFsVGhyZWFkR3JvdXAuZW51bWVyYXRlKGxpc3RPZkdyb3Vwcyk7CisgICAgICAgIGFzc2VydEVxdWFscyhudW1DaGlsZEdyb3Vwc0FmdGVyLCBjb3VudEdyb3VwVGhyZWFkKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuYXNMaXN0KGxpc3RPZkdyb3VwcykuY29udGFpbnMoY2hpbGRHcm91cCkpOworCisgICAgICAgIFRocmVhZEdyb3VwW10gbGlzdE9mR3JvdXBzMSA9IG5ldyBUaHJlYWRHcm91cFtudW1DaGlsZEdyb3Vwc0FmdGVyICsgMV07CisgICAgICAgIGNvdW50R3JvdXBUaHJlYWQgPSBpbml0aWFsVGhyZWFkR3JvdXAuZW51bWVyYXRlKGxpc3RPZkdyb3VwczEpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVtQ2hpbGRHcm91cHNBZnRlciwgY291bnRHcm91cFRocmVhZCk7CisgICAgICAgIGFzc2VydE51bGwobGlzdE9mR3JvdXBzMVtsaXN0T2ZHcm91cHMxLmxlbmd0aCAtIDFdKTsKKworICAgICAgICBUaHJlYWRHcm91cFtdIGxpc3RPZkdyb3VwczIgPSBuZXcgVGhyZWFkR3JvdXBbbnVtQ2hpbGRHcm91cHNBZnRlciAtIDFdOworICAgICAgICBjb3VudEdyb3VwVGhyZWFkID0gaW5pdGlhbFRocmVhZEdyb3VwLmVudW1lcmF0ZShsaXN0T2ZHcm91cHMyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bUNoaWxkR3JvdXBzQWZ0ZXIgLSAxLCBjb3VudEdyb3VwVGhyZWFkKTsKKworICAgICAgICBUaHJlYWRHcm91cCB0aHJHcm91cDEgPSBuZXcgVGhyZWFkR3JvdXAoIlRlc3QgR3JvdXAgMSIpOworICAgICAgICBjb3VudEdyb3VwVGhyZWFkID0gdGhyR3JvdXAxLmVudW1lcmF0ZShsaXN0T2ZHcm91cHMpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgY291bnRHcm91cFRocmVhZCk7CisKKyAgICAgICAgY2hpbGRHcm91cC5kZXN0cm95KCk7CisgICAgICAgIGFzc2VydFRydWUoaW5pdGlhbFRocmVhZEdyb3VwLmFjdGl2ZUdyb3VwQ291bnQoKSA9PSBudW1DaGlsZEdyb3Vwc0JlZm9yZSArIDEpOworICAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VudW1lcmF0ZUxUaHJlYWRHcm91cEFycmF5TFooKSB7CisgICAgICAgIFRocmVhZEdyb3VwIHRockdyb3VwID0gbmV3IFRocmVhZEdyb3VwKCJUZXN0IEdyb3VwIDEiKTsKKyAgICAgICAgTGlzdDxNeVRocmVhZD4gc3ViVGhyZWFkcyA9IHBvcHVsYXRlR3JvdXBzV2l0aFRocmVhZHModGhyR3JvdXAsIDMpOworICAgICAgICBpbnQgbnVtR3JvdXBUaHJlYWRzID0gdGhyR3JvdXAuYWN0aXZlR3JvdXBDb3VudCgpOworICAgICAgICBUaHJlYWRHcm91cFtdIGxpc3RPZkdyb3VwcyA9IG5ldyBUaHJlYWRHcm91cFtudW1Hcm91cFRocmVhZHNdOworCisgICAgICAgIGFzc2VydEVxdWFscygwLCB0aHJHcm91cC5lbnVtZXJhdGUobGlzdE9mR3JvdXBzLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCB0aHJHcm91cC5lbnVtZXJhdGUobGlzdE9mR3JvdXBzLCBmYWxzZSkpOworCisgICAgICAgIGZvcihNeVRocmVhZCB0aHI6c3ViVGhyZWFkcykgeworICAgICAgICAgICAgdGhyLnN0YXJ0KCk7CisgICAgICAgIH0KKworICAgICAgICBudW1Hcm91cFRocmVhZHMgPSB0aHJHcm91cC5hY3RpdmVHcm91cENvdW50KCk7CisgICAgICAgIGxpc3RPZkdyb3VwcyA9IG5ldyBUaHJlYWRHcm91cFtudW1Hcm91cFRocmVhZHNdOworCisgICAgICAgIGFzc2VydEVxdWFscygwLCB0aHJHcm91cC5lbnVtZXJhdGUobGlzdE9mR3JvdXBzLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCB0aHJHcm91cC5lbnVtZXJhdGUobGlzdE9mR3JvdXBzLCBmYWxzZSkpOworCisgICAgICAgIFRocmVhZEdyb3VwIHN1Ykdyb3VwMSA9IG5ldyBUaHJlYWRHcm91cCh0aHJHcm91cCwgIlRlc3QgR3JvdXAgMiIpOworICAgICAgICBMaXN0PE15VGhyZWFkPiBzdWJUaHJlYWRzMSA9IHBvcHVsYXRlR3JvdXBzV2l0aFRocmVhZHMoc3ViR3JvdXAxLCAzKTsKKyAgICAgICAgbnVtR3JvdXBUaHJlYWRzID0gdGhyR3JvdXAuYWN0aXZlR3JvdXBDb3VudCgpOworICAgICAgICBsaXN0T2ZHcm91cHMgPSBuZXcgVGhyZWFkR3JvdXBbbnVtR3JvdXBUaHJlYWRzXTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgdGhyR3JvdXAuZW51bWVyYXRlKGxpc3RPZkdyb3VwcywgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgdGhyR3JvdXAuZW51bWVyYXRlKGxpc3RPZkdyb3VwcywgZmFsc2UpKTsKKworICAgICAgICBmb3IoTXlUaHJlYWQgdGhyOnN1YlRocmVhZHMxKSB7CisgICAgICAgICAgICB0aHIuc3RhcnQoKTsKKyAgICAgICAgfQorICAgICAgICBudW1Hcm91cFRocmVhZHMgPSB0aHJHcm91cC5hY3RpdmVHcm91cENvdW50KCk7CisgICAgICAgIGxpc3RPZkdyb3VwcyA9IG5ldyBUaHJlYWRHcm91cFtudW1Hcm91cFRocmVhZHNdOworCisgICAgICAgIGFzc2VydEVxdWFscygxLCB0aHJHcm91cC5lbnVtZXJhdGUobGlzdE9mR3JvdXBzLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCB0aHJHcm91cC5lbnVtZXJhdGUobGlzdE9mR3JvdXBzLCBmYWxzZSkpOworCisgICAgICAgIGZvcihNeVRocmVhZCB0aHI6c3ViVGhyZWFkcykgeworICAgICAgICAgICAgdGhyLmludGVycnVwdCgpOworICAgICAgICAgfQorCisgICAgICAgIFRocmVhZEdyb3VwIHN1Ykdyb3VwMiA9IG5ldyBUaHJlYWRHcm91cChzdWJHcm91cDEsICJUZXN0IEdyb3VwIDMiKTsKKyAgICAgICAgTGlzdDxNeVRocmVhZD4gc3ViVGhyZWFkczIgPSBwb3B1bGF0ZUdyb3Vwc1dpdGhUaHJlYWRzKHN1Ykdyb3VwMiwgMyk7CisgICAgICAgIG51bUdyb3VwVGhyZWFkcyA9IHRockdyb3VwLmFjdGl2ZUdyb3VwQ291bnQoKTsKKyAgICAgICAgbGlzdE9mR3JvdXBzID0gbmV3IFRocmVhZEdyb3VwW251bUdyb3VwVGhyZWFkc107CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHRockdyb3VwLmVudW1lcmF0ZShsaXN0T2ZHcm91cHMsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHRockdyb3VwLmVudW1lcmF0ZShsaXN0T2ZHcm91cHMsIGZhbHNlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLlRocmVhZEdyb3VwI2ludGVycnVwdCgpCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpbnRlcnJ1cHRlZCA9IGZhbHNlOworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW50ZXJydXB0KCkgeworCisgICAgICAgIFRocmVhZC5zZXREZWZhdWx0VW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyKHRoaXMpOworICAgICAgICBUaHJlYWRHcm91cCB0ZyA9IG5ldyBUaHJlYWRHcm91cCgiaW50ZXJydXB0Iik7CisgICAgICAgIFRocmVhZCB0MSA9IG5ldyBUaHJlYWQodGcsIG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoNTAwMCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKCJvayIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJJbmNvcnJlY3Qgc3RhdGUgb2YgdGhyZWFkIiwgaW50ZXJydXB0ZWQpOworICAgICAgICB0MS5zdGFydCgpOworICAgICAgICBhc3NlcnRGYWxzZSgiSW5jb3JyZWN0IHN0YXRlIG9mIHRocmVhZCIsIGludGVycnVwdGVkKTsKKyAgICAgICAgdDEuaW50ZXJydXB0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0MS5qb2luKCk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3Qgc3RhdGUgb2YgdGhyZWFkIiwgaW50ZXJydXB0ZWQpOworICAgICAgICB0Zy5kZXN0cm95KCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0Rlc3Ryb3llZCgpIHsKKyAgICAgICAgZmluYWwgVGhyZWFkR3JvdXAgb3JpZ2luYWxDdXJyZW50ID0gZ2V0SW5pdGlhbFRocmVhZEdyb3VwKCk7CisgICAgICAgIGZpbmFsIFRocmVhZEdyb3VwIHRlc3RSb290ID0gbmV3IFRocmVhZEdyb3VwKG9yaWdpbmFsQ3VycmVudCwKKyAgICAgICAgICAgICAgICAiVGVzdCBncm91cCIpOworICAgICAgICBhc3NlcnRGYWxzZSgiVGVzdCBncm91cCBpcyBub3QgZGVzdHJveWVkIHlldCIsCisgICAgICAgICAgICAgICAgdGVzdFJvb3QuaXNEZXN0cm95ZWQoKSk7CisgICAgICAgIHRlc3RSb290LmRlc3Ryb3koKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCBncm91cCBhbHJlYWR5IGRlc3Ryb3llZCIsCisgICAgICAgICAgICAgICAgdGVzdFJvb3QuaXNEZXN0cm95ZWQoKSk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Jlc3VtZSgpIHsKKyAgICAgICAgVGhyZWFkR3JvdXAgZ3JvdXAgPSBuZXcgVGhyZWFkR3JvdXAoIkZvbyIpOworCisgICAgICAgIFRocmVhZCB0aHJlYWQgPSBsYXVuY2hGaXZlU2Vjb25kRHVtbXlUaHJlYWQoZ3JvdXApOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIElnbm9yZQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGdyb3VwLnJlc3VtZSgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBUaHJlYWQgbGF1bmNoRml2ZVNlY29uZER1bW15VGhyZWFkKFRocmVhZEdyb3VwIGdyb3VwKSB7CisgICAgICAgIFRocmVhZCB0aHJlYWQgPSBuZXcgVGhyZWFkKGdyb3VwLCAiQmFyIikgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCg1MDAwKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIElnbm9yZQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICB0aHJlYWQuc3RhcnQoKTsKKworICAgICAgICByZXR1cm4gdGhyZWFkOworICAgIH0KKworICAgIC8qCisgICAgICogQHNlZSBqYXZhLmxhbmcuVGhyZWFkLlVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlciN1bmNhdWdodEV4Y2VwdGlvbihqYXZhLmxhbmcuVGhyZWFkLCBqYXZhLmxhbmcuVGhyb3dhYmxlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVuY2F1Z2h0RXhjZXB0aW9uKFRocmVhZCB0LCBUaHJvd2FibGUgZSkgeworICAgICAgICBpbnRlcnJ1cHRlZCA9IHRydWU7CisgICAgICAgIFRocmVhZC5zZXREZWZhdWx0VW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyKG51bGwpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICBpbml0aWFsVGhyZWFkR3JvdXAgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldFRocmVhZEdyb3VwKCk7CisgICAgICAgIFRocmVhZEdyb3VwIHJvb3RUaHJlYWRHcm91cCA9IGluaXRpYWxUaHJlYWRHcm91cDsKKyAgICAgICAgd2hpbGUgKHJvb3RUaHJlYWRHcm91cC5nZXRQYXJlbnQoKSAhPSBudWxsKSB7CisgICAgICAgICAgICByb290VGhyZWFkR3JvdXAgPSByb290VGhyZWFkR3JvdXAuZ2V0UGFyZW50KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIEdpdmUgdGhlIHRocmVhZHMgYSBjaGFuY2UgdG8gZGllLgorICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDUwKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBUaHJlYWRHcm91cCBnZXRJbml0aWFsVGhyZWFkR3JvdXAoKSB7CisgICAgICAgIHJldHVybiBpbml0aWFsVGhyZWFkR3JvdXA7CisgICAgfQorCisgICAgcHJpdmF0ZSBUaHJlYWRHcm91cFtdIGdyb3VwcyhUaHJlYWRHcm91cCBwYXJlbnQpIHsKKyAgICAgICAgLy8gTm8gQVBJIHRvIGdldCB0aGUgY291bnQgb2YgaW1tZWRpYXRlIGNoaWxkcmVuIG9ubHkKKyAgICAgICAgaW50IGNvdW50ID0gcGFyZW50LmFjdGl2ZUdyb3VwQ291bnQoKTsKKyAgICAgICAgVGhyZWFkR3JvdXBbXSBhbGwgPSBuZXcgVGhyZWFkR3JvdXBbY291bnRdOworICAgICAgICBwYXJlbnQuZW51bWVyYXRlKGFsbCwgZmFsc2UpOworICAgICAgICAvLyBOb3cgd2UgbWF5IGhhdmUgbnVsbHMgaW4gdGhlIGFycmF5LCB3ZSBtdXN0IGZpbmQgdGhlIGFjdHVhbCBzaXplCisgICAgICAgIGludCBhY3R1YWxTaXplID0gMDsKKyAgICAgICAgZm9yICg7IGFjdHVhbFNpemUgPCBhbGwubGVuZ3RoOyBhY3R1YWxTaXplKyspIHsKKyAgICAgICAgICAgIGlmIChhbGxbYWN0dWFsU2l6ZV0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBBcnJheXMuY29weU9mUmFuZ2UoYWxsLCAwLCBhY3R1YWxTaXplKTsKKyAgICB9CisKKyAgICBwcml2YXRlIExpc3Q8TXlUaHJlYWQ+IHBvcHVsYXRlR3JvdXBzV2l0aFRocmVhZHMoVGhyZWFkR3JvdXAgZ3JvdXAsIGludCB0aHJlYWRDb3VudCkgeworICAgICAgICBMaXN0PE15VGhyZWFkPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PE15VGhyZWFkPigpOworICAgICAgICBwb3B1bGF0ZUdyb3Vwc1dpdGhUaHJlYWRzKGdyb3VwLCB0aHJlYWRDb3VudCwgcmVzdWx0KTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcG9wdWxhdGVHcm91cHNXaXRoVGhyZWFkcyhUaHJlYWRHcm91cCBncm91cCwgaW50IHRocmVhZENvdW50LCBMaXN0PE15VGhyZWFkPiBvdXQpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aHJlYWRDb3VudDsgaSsrKSB7CisgICAgICAgICAgICBvdXQuYWRkKG5ldyBNeVRocmVhZChncm91cCwgIk15VGhyZWFkICIgKyBpICsgIiBvZiAiICsgdGhyZWFkQ291bnQpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGZvciBzdWJncm91cHMgKGlmIGFueSkKKyAgICAgICAgVGhyZWFkR3JvdXBbXSBjaGlsZHJlbiA9IGdyb3Vwcyhncm91cCk7CisgICAgICAgIGZvciAoVGhyZWFkR3JvdXAgZWxlbWVudCA6IGNoaWxkcmVuKSB7CisgICAgICAgICAgICBwb3B1bGF0ZUdyb3Vwc1dpdGhUaHJlYWRzKGVsZW1lbnQsIHRocmVhZENvdW50LCBvdXQpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZFRocmVhZFN0YXRlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL09sZFRocmVhZFN0YXRlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg1NTY1NWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkVGhyZWFkU3RhdGVUZXN0LmphdmEKQEAgLTAsMCArMSw2MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRUaHJlYWRTdGF0ZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBUaHJlYWQuU3RhdGUgW10gZXhTdGF0ZXMgPSB7IFRocmVhZC5TdGF0ZS5ORVcsIFRocmVhZC5TdGF0ZS5SVU5OQUJMRSwKKyAgICAgICAgICAgIFRocmVhZC5TdGF0ZS5CTE9DS0VELCBUaHJlYWQuU3RhdGUuV0FJVElORywKKyAgICAgICAgICAgIFRocmVhZC5TdGF0ZS5USU1FRF9XQUlUSU5HLCBUaHJlYWQuU3RhdGUuVEVSTUlOQVRFRCB9OworCisgICAgcHVibGljIHZvaWQgdGVzdF92YWx1ZU9mTFN0cmluZygpeworICAgICAgICBTdHJpbmcgW10gc3BOYW1lcyA9IHsiTkVXIiwgIlJVTk5BQkxFIiwgIkJMT0NLRUQiLCAiV0FJVElORyIsCisgICAgICAgICAgICAgICAgIlRJTUVEX1dBSVRJTkciLCAiVEVSTUlOQVRFRCJ9OworCisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBleFN0YXRlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4U3RhdGVzW2ldLCBUaHJlYWQuU3RhdGUudmFsdWVPZihzcE5hbWVzW2ldKSk7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgW10gaWxsZWdhbE5hbWVzID0geyJOZXciLCAibmV3IiwgIiIsICJOQU1FIiwgIlRJTUUifTsKKyAgICAgICAgZm9yKFN0cmluZyBzOmlsbGVnYWxOYW1lcykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBUaHJlYWQuU3RhdGUudmFsdWVPZihzKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24gZm9yIHN0cmluZzogIitzKTsKKyAgICAgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdmFsdWVzKCkgeworICAgICAgICBUaHJlYWQuU3RhdGUgW10gdGhTdGF0ZXMgPSBUaHJlYWQuU3RhdGUudmFsdWVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhleFN0YXRlcy5sZW5ndGgsIHRoU3RhdGVzLmxlbmd0aCk7CisgICAgICAgIGZvcihUaHJlYWQuU3RhdGUgdHM6dGhTdGF0ZXMpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoaXNDb250YWluKHRzKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBib29sZWFuIGlzQ29udGFpbihUaHJlYWQuU3RhdGUgc3RhdGUpIHsKKyAgICAgICAgZm9yKFRocmVhZC5TdGF0ZSB0czpleFN0YXRlcykgeworICAgICAgICAgICAgaWYodHMuZXF1YWxzKHN0YXRlKSkgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRUaHJlYWRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkVGhyZWFkVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFlMTg5ZjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkVGhyZWFkVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDg1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QcmludFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5TZW1hcGhvcmU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3MuTG9ja1N1cHBvcnQ7CisKK3B1YmxpYyBjbGFzcyBPbGRUaHJlYWRUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBjbGFzcyBTaW1wbGVUaHJlYWQgaW1wbGVtZW50cyBSdW5uYWJsZSB7CisgICAgICAgIGludCBkZWxheTsKKworICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgICAgICAgICB0aGlzLm5vdGlmeSgpOworICAgICAgICAgICAgICAgICAgICB0aGlzLndhaXQoZGVsYXkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTaW1wbGVUaHJlYWQoaW50IGQpIHsKKyAgICAgICAgICAgIGlmIChkID49IDApCisgICAgICAgICAgICAgICAgZGVsYXkgPSBkOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfVGhyZWFkR3JvdXBMamF2YV9sYW5nX1J1bm5hYmxlTGphdmFfbGFuZ19TdHJpbmdMJEwoKSB7CisgICAgICAgIFRocmVhZEdyb3VwIHRnID0gbmV3IFRocmVhZEdyb3VwKCJUZXN0IEdyb3VwMiIpOworICAgICAgICBzdCA9IG5ldyBUaHJlYWQodGcsIG5ldyBTaW1wbGVUaHJlYWQoMSksICJTaW1wbGVUaHJlYWQzIiwgMSk7CisgICAgICAgIGFzc2VydFRydWUoIkNvbnN0cnVjdGVkIGluY29ycmVjdCB0aHJlYWQiLCAoc3QuZ2V0VGhyZWFkR3JvdXAoKSA9PSB0ZykKKyAgICAgICAgICAgICAgICAmJiBzdC5nZXROYW1lKCkuZXF1YWxzKCJTaW1wbGVUaHJlYWQzIikpOworICAgICAgICBzdC5zdGFydCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3Quam9pbigpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdGcuZGVzdHJveSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVGhyZWFkKHRnLCBuZXcgU2ltcGxlVGhyZWFkKDEpLCAiU2ltcGxlVGhyZWFkMyIsCisgICAgICAgICAgICAgICAgICAgIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgIGZhaWwoIlN0YWNrT3ZlcmZsb3dFcnJvci9PdXRPZk1lbW9yeUVycm9yIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbFRocmVhZFN0YXRlRXhjZXB0aW9uIGl0c2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9kdW1wU3RhY2soKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQcmludFN0cmVhbSBzYXZlZEVyciA9IFN5c3RlbS5lcnI7CisgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIFN5c3RlbS5zZXRFcnIobmV3IFByaW50U3RyZWFtKGJhb3MpKTsKKyAgICAgICAgICAgIFRocmVhZC5kdW1wU3RhY2soKTsKKyAgICAgICAgICAgIFN5c3RlbS5zZXRFcnIoc2F2ZWRFcnIpOworCisgICAgICAgICAgICBTdHJpbmcgcyA9IG5ldyBTdHJpbmcoYmFvcy50b0J5dGVBcnJheSgpKTsKKworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShzLmNvbnRhaW5zKCJqYXZhLmxhbmcuVGhyZWFkLmR1bXBTdGFjayIpKTsKKworICAgICAgICB9IGNhdGNoKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiB3YXMgdGhyb3duOiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIE1vbml0b3JlZENsYXNzIHsKKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGVudGVyTG9ja2VkKCkgeworICAgICAgICAgICAgYm9vbGVhbiBiID0gVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlRocmVhZCBzaG91bGQgaG9sZCBsb2NrIGZvciBvYmplY3QiLCBiKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGVudGVyTm9uTG9ja2VkKCkgeworICAgICAgICAgICAgYm9vbGVhbiBiID0gVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJUaHJlYWQgc2hvdWxkIG5vdCBob2xkIGxvY2sgZm9yIG9iamVjdCIsIGIpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBib29sZWFuIHdhc0ludGVycnVwdGVkID0gZmFsc2U7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2pvaW5XaXRoU3B1cmlvdXNJbnRlcnJ1cHRpb24oKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBmaW5hbCBUaHJlYWQgcGFya2VyID0gbmV3IFRocmVhZCgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAvLyB3ZSB1c2VkIHRvIGdldCBzcHVyaW91cyB3YWtldXBzIHVwb24gdW5wYXJraW5nCisgICAgICAgICAgICAgICAgICAgIExvY2tTdXBwb3J0LnBhcmsoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIFRocmVhZCB1bnBhcmtlciA9IG5ldyBUaHJlYWQoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxMDApOworICAgICAgICAgICAgICAgICAgICAgICAgTG9ja1N1cHBvcnQudW5wYXJrKHBhcmtlcik7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgbG9uZyBzdGFydE5hbm9zID0gU3lzdGVtLm5hbm9UaW1lKCk7CisgICAgICAgIHBhcmtlci5zdGFydCgpOworICAgICAgICB1bnBhcmtlci5zdGFydCgpOworICAgICAgICBwYXJrZXIuam9pbig1MDAsIDUwMDAwMCk7CisgICAgICAgIGxvbmcgbmV0V2FpdFRpbWUgPSBTeXN0ZW0ubmFub1RpbWUoKSAtIHN0YXJ0TmFub3M7CisgICAgICAgIGFzc2VydFRydWUoIkV4cGVjdGVkIHRvIHdhaXQgYXQgbGVhc3QgNTAwMDAwMDAwbnMsIGJ1dCB3YXMgIiArIG5ldFdhaXRUaW1lICsgIm5zIiwKKyAgICAgICAgICAgICAgICBuZXRXYWl0VGltZSA+IDUwMDAwMDAwMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSB7CisgICAgICAgIENsYXNzTG9hZGVyIHBjbCA9IG5ldyBDbGFzc0xvYWRlcigpIHt9OworICAgICAgICBzdCA9IG5ldyBUaHJlYWQoKTsKKyAgICAgICAgc3Quc2V0Q29udGV4dENsYXNzTG9hZGVyKHBjbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhwY2wsIHN0LmdldENvbnRleHRDbGFzc0xvYWRlcigpKTsKKworICAgICAgICBzdC5zZXRDb250ZXh0Q2xhc3NMb2FkZXIobnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoc3QuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0RGFlbW9uWigpIHsKKyAgICAgICAgc3QgPSBuZXcgVGhyZWFkKG5ldyBTaW1wbGVUaHJlYWQoNSkpOworICAgICAgICBzdC5zdGFydCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3Quc2V0RGFlbW9uKGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoInNldERhZW1vbigpIG11c3QgdGhyb3cgZXhjZXB0aW9uIGZvciBzdGFydGVkIHRocmVhZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsVGhyZWFkU3RhdGVFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIFdlIGV4cGVjdCB0aGlzIG9uZS4KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgVGhyZWFkIGxhdW5jaEZpdmVTZWNvbmREdW1teVRocmVhZCgpIHsKKyAgICAgICAgVGhyZWFkIHRocmVhZCA9IG5ldyBUaHJlYWQoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDUwMDApOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gSWdub3JlCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHRocmVhZC5zdGFydCgpOworCisgICAgICAgIHJldHVybiB0aHJlYWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLlRocmVhZCNzbGVlcChsb25nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2xlZXBKKCkgeworICAgICAgICAvLyBOb3RlOiBOb3QgdG9vIG11Y2ggd2UgY2FuIHRlc3QgaGVyZSB0aGF0IGNhbiBiZSByZWxpYWJseSBtZWFzdXJlZC4KKworICAgICAgICAvLyBDaGVjayB0aGF0IGJhc2ljIGJlaGF2aW9yIGlzIGFib3V0IHJpZ2h0ICh3aXRoIHNvbWUgdG9sZXJhbmNlKQorICAgICAgICBsb25nIHN0aW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxMDAwKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKworICAgICAgICBsb25nIGZ0aW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIHNsZWVwIGxvbmcgZW5vdWdoIiwgKGZ0aW1lIC0gc3RpbWUpID49IDUwMCk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byB3YWtlIHVwIGVhcmx5IGVub3VnaCIsIChmdGltZSAtIHN0aW1lKSA8PSAxNTAwKTsKKworICAgICAgICAvLyBDaGVjayB0aGF0IGludGVycnVwdCB3b3JrcworICAgICAgICBzdCA9IG5ldyBUaHJlYWQoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc2xlZXAoMTAwMDApOworICAgICAgICAgICAgICAgIH0gY2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gaWUpIHsKKyAgICAgICAgICAgICAgICAgICAgd2FzSW50ZXJydXB0ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBzdC5zdGFydCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUaHJlYWQuc2xlZXAoNTAwMCk7CisgICAgICAgIH0gY2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKworICAgICAgICBzdC5pbnRlcnJ1cHQoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDUwMDApOworICAgICAgICB9IGNhdGNoKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSW50ZXJydXB0ZWRFeGNlcHRpb24gd2FzIHRocm93biIpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSh3YXNJbnRlcnJ1cHRlZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zbGVlcEpJKCkgeworICAgICAgICAvLyBOb3RlOiBOb3QgdG9vIG11Y2ggd2UgY2FuIHRlc3QgaGVyZSB0aGF0IGNhbiBiZSByZWxpYWJseSBtZWFzdXJlZC4KKworICAgICAgICAvLyBDaGVjayB0aGF0IGJhc2ljIGJlaGF2aW9yIGlzIGFib3V0IHJpZ2h0ICh3aXRoIHNvbWUgdG9sZXJhbmNlKQorICAgICAgICBsb25nIHN0aW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxMDAwLCA5OTk5OSk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSW50ZXJydXB0ZWRFeGNlcHRpb24gd2FzIHRocm93biIpOworICAgICAgICB9CisKKyAgICAgICAgbG9uZyBmdGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworCisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBzbGVlcCBsb25nIGVub3VnaCIsIChmdGltZSAtIHN0aW1lKSA+PSA1MDApOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gd2FrZSB1cCBlYXJseSBlbm91Z2giLCAoZnRpbWUgLSBzdGltZSkgPD0gMTUwMCk7CisKKyAgICAgICAgLy8gQ2hlY2sgdGhhdCBpbnRlcnJ1cHQgd29ya3MKKyAgICAgICAgc3QgPSBuZXcgVGhyZWFkKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHNsZWVwKDEwMDAwLCA5OTk5OSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSkgeworICAgICAgICAgICAgICAgICAgICB3YXNJbnRlcnJ1cHRlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHN0LnN0YXJ0KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRocmVhZC5zbGVlcCg1MDAwLCA5OTk5OSk7CisgICAgICAgIH0gY2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKworICAgICAgICBzdC5pbnRlcnJ1cHQoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDUwMDApOworICAgICAgICB9IGNhdGNoKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSW50ZXJydXB0ZWRFeGNlcHRpb24gd2FzIHRocm93biIpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSh3YXNJbnRlcnJ1cHRlZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF95aWVsZCgpIHsKKworICAgICAgICBDb3VudGVyIFtdIGNvdW50ZXJzTm90WWVsZCA9IG5ldyBDb3VudGVyWzEwXTsKKworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgICAgICAgICAgY291bnRlcnNOb3RZZWxkW2ldID0gbmV3IENvdW50ZXIoZmFsc2UpOworICAgICAgICB9CisgICAgICAgIENvdW50ZXIgY291bnRlcnNZZWxkID0gbmV3IENvdW50ZXIodHJ1ZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTEwMDApOworICAgICAgICB9IGNhdGNoKEludGVycnVwdGVkRXhjZXB0aW9uIGllKSB7fQorCisgICAgICAgIGZvcihDb3VudGVyIGM6Y291bnRlcnNOb3RZZWxkKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGNvdW50ZXJzWWVsZC5jb3VudGVyID09IGMuY291bnRlcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBDb3VudGVyIGV4dGVuZHMgVGhyZWFkIHsKKyAgICAgICAgcHVibGljIGludCBjb3VudGVyID0gMDsKKyAgICAgICAgYm9vbGVhbiBpc0RvWWllbGQgPSBmYWxzZTsKKworICAgICAgICBwdWJsaWMgQ291bnRlcihib29sZWFuIGlzRG9ZaWVsZCkgeworICAgICAgICAgICAgdGhpcy5pc0RvWWllbGQgPSBpc0RvWWllbGQ7CisgICAgICAgICAgICBzdGFydCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IDEwMDAwOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZihpc0RvWWllbGQpCisgICAgICAgICAgICAgICAgICAgIHlpZWxkKCk7CisgICAgICAgICAgICAgICAgY291bnRlciArKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTdGF0ZSgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIFRocmVhZC5TdGF0ZSBzdGF0ZSA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0U3RhdGUoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzdGF0ZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhUaHJlYWQuU3RhdGUuUlVOTkFCTEUsIHN0YXRlKTsKKworICAgICAgICBmaW5hbCBTZW1hcGhvcmUgc2VtID0gbmV3IFNlbWFwaG9yZSgwKTsKKyAgICAgICAgZmluYWwgT2JqZWN0IGxvY2sgPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIFRocmVhZCB0aCA9IG5ldyBUaHJlYWQoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICAgIHdoaWxlICghc2VtLmhhc1F1ZXVlZFRocmVhZHMoKSkge30KKyAgICAgICAgICAgICAgICAgIHNlbS5yZWxlYXNlKCk7CisKKyAgICAgICAgICAgICAgICAgIC8vIFJVTk5BQkxFCisgICAgICAgICAgICAgICAgICB3aGlsZSAocnVuKSB7fQorCisgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgIC8vIFdBSVRJTkcKKyAgICAgICAgICAgICAgICAgICAgICBzZW0uYWNxdWlyZSgpOworICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgIGZhaWwoIkludGVycnVwdGVkRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgIC8vIEJMT0NLRUQKKyAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgICAgICAgICAgIGxvY2suZXF1YWxzKG5ldyBPYmplY3QoKSk7CisgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgc2VtLnJlbGVhc2UoKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgLy8gVElNRURfV0FJVElORworICAgICAgICAgICAgICAgICAgICAgICAgbG9jay53YWl0KExvbmcuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAvLyBURVJNSU5BVEVEIHVwb24gcmV0dXJuCisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIGFzc2VydEVxdWFscyhUaHJlYWQuU3RhdGUuTkVXLCB0aC5nZXRTdGF0ZSgpKTsKKyAgICAgICAgdGguc3RhcnQoKTsKKyAgICAgICAgc2VtLmFjcXVpcmUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFRocmVhZC5TdGF0ZS5SVU5OQUJMRSwgdGguZ2V0U3RhdGUoKSk7CisgICAgICAgIHJ1biA9IGZhbHNlOworCisgICAgICAgIFRocmVhZC5zbGVlcCgyMDApOworCisgICAgICAgIGFzc2VydEVxdWFscyhUaHJlYWQuU3RhdGUuV0FJVElORywgdGguZ2V0U3RhdGUoKSk7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgc2VtLnJlbGVhc2UoKTsKKyAgICAgICAgICAgIGxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgICAgIHdoaWxlKHN0YXJ0ICsgMTAwMCA+IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKSB7fQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFRocmVhZC5TdGF0ZS5CTE9DS0VELCB0aC5nZXRTdGF0ZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHNlbS5hY3F1aXJlKCk7CisKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoVGhyZWFkLlN0YXRlLlRJTUVEX1dBSVRJTkcsIHRoLmdldFN0YXRlKCkpOworICAgICAgICAgICAgdGguaW50ZXJydXB0KCk7CisgICAgICAgIH0KKworICAgICAgICB0aC5qb2luKDEwMDApOworICAgICAgICBhc3NlcnRFcXVhbHMoVGhyZWFkLlN0YXRlLlRFUk1JTkFURUQsIHRoLmdldFN0YXRlKCkpOworICAgIH0KKyAgICB2b2xhdGlsZSBib29sZWFuIHJ1biA9IHRydWU7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hvbGRzTG9jaygpIHsKKyAgICAgICAgTW9uaXRvcmVkQ2xhc3MgbW9uaXRvciA9IG5ldyBNb25pdG9yZWRDbGFzcygpOworCisgICAgICAgIG1vbml0b3IuZW50ZXJMb2NrZWQoKTsKKyAgICAgICAgbW9uaXRvci5lbnRlck5vbkxvY2tlZCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUaHJlYWQuaG9sZHNMb2NrKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3RvcCgpIHsKKyAgICAgICAgVGhyZWFkIHRocmVhZCA9IGxhdW5jaEZpdmVTZWNvbmREdW1teVRocmVhZCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIElnbm9yZQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRocmVhZC5zdG9wKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N0YXJ0KCkgeworICAgICAgICBUaHJlYWQgdGhyID0gbmV3IFRocmVhZCgpOworICAgICAgICB0aHIuc3RhcnQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoci5zdGFydCgpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxUaHJlYWRTdGF0ZUV4Y2VwdGlvbiBpdHNlKXsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCisgICAgcHVibGljIHZvaWQgdGVzdF9zdG9wTGphdmFfbGFuZ19UaHJvd2FibGVfc3VidGVzdDAoKSB7CisgICAgICAgIFRocmVhZCB0aHJlYWQgPSBuZXcgVGhyZWFkKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCg1MDAwKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIElnbm9yZQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICB0aHJlYWQuc3RhcnQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxMDAwKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gSWdub3JlCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhyZWFkLnN0b3AobmV3IEV4Y2VwdGlvbigiT29wcyEiKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VzcGVuZCgpIHsKKyAgICAgICAgVGhyZWFkIHRocmVhZCA9IGxhdW5jaEZpdmVTZWNvbmREdW1teVRocmVhZCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIElnbm9yZQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRocmVhZC5zdXNwZW5kKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBUaHJlYWQgc3QsIGN0LCBzcGlubmVyOworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoc3QgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICBzdC5pbnRlcnJ1cHQoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKHNwaW5uZXIgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICBzcGlubmVyLmludGVycnVwdCgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoY3QgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICBjdC5pbnRlcnJ1cHQoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzcGlubmVyID0gbnVsbDsKKyAgICAgICAgICAgIHN0ID0gbnVsbDsKKyAgICAgICAgICAgIGN0ID0gbnVsbDsKKyAgICAgICAgICAgIFN5c3RlbS5ydW5GaW5hbGl6YXRpb24oKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9PbGRUaHJvd2FibGVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkVGhyb3dhYmxlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE2MTY4NTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvT2xkVGhyb3dhYmxlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTMxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZFRocm93YWJsZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTFN0cmluZ0xUaHJvd2FibGUoKSB7CisgICAgICAgIFN0cmluZyBtZXNzYWdlID0gIlRlc3QgbWVzc2FnZSI7CisgICAgICAgIE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSA9IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBUaHJvd2FibGUgdGhyID0gbmV3IFRocm93YWJsZShtZXNzYWdlLCBucGUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm1lc3NhZ2UgaXMgaW5jb3JyZWN0LiIsIG1lc3NhZ2UsIHRoci5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImNhdXNlIGlzIGluY29ycmVjdC4iLCBucGUsIHRoci5nZXRDYXVzZSgpKTsKKworICAgICAgICB0aHIgPSBuZXcgVGhyb3dhYmxlKG51bGwsIG5wZSk7CisgICAgICAgIGFzc2VydE51bGwoIm1lc3NhZ2UgaXMgbm90IG51bGwuIiwgdGhyLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiY2F1c2UgaXMgaW5jb3JyZWN0LiIsIG5wZSwgdGhyLmdldENhdXNlKCkpOworCisgICAgICAgIHRociA9IG5ldyBUaHJvd2FibGUobWVzc2FnZSwgbnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscygibWVzc2FnZSBpcyBpbmNvcnJlY3QuIiwgbWVzc2FnZSwgdGhyLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImNhdXNlIGlzIG5vdCBudWxsLiIsIHRoci5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTFRocm93YWJsZSgpIHsKKworICAgICAgICBOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUgPSBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgVGhyb3dhYmxlIHRociA9IG5ldyBUaHJvd2FibGUobnBlKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGNhdXNlIGlzIGluY29ycmVjdC4iLCBucGUsIHRoci5nZXRDYXVzZSgpKTsKKworICAgICAgICB0aHIgPSBuZXcgVGhyb3dhYmxlKChUaHJvd2FibGUpIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJUaGUgY2F1c2UgaXMgbm90IG51bGwuIiwgdGhyLmdldENhdXNlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TG9jYWxpemVkTWVzc2FnZSgpIHsKKyAgICAgICAgU3RyaW5nIHRlc3RNZXNzYWdlID0gIlRlc3QgbWVzc2FnZSI7CisgICAgICAgIFRocm93YWJsZSBlID0gbmV3IFRocm93YWJsZSh0ZXN0TWVzc2FnZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGxvY2FsaXplZCBtZXNzYWdlLiIsCisgICAgICAgICAgICAgICAgdGVzdE1lc3NhZ2UsIGUuZ2V0TG9jYWxpemVkTWVzc2FnZSgpKTsKKworICAgICAgICBUZXN0VGhyb3dhYmxlIHR0ID0gbmV3IFRlc3RUaHJvd2FibGUodGVzdE1lc3NhZ2UpOworICAgICAgICBhc3NlcnRFcXVhbHMoImxvY2FsaXplZCBtZXNzYWdlIiwgdHQuZ2V0TG9jYWxpemVkTWVzc2FnZSgpKTsKKyAgICB9CisKKyAgICBjbGFzcyBUZXN0VGhyb3dhYmxlIGV4dGVuZHMgVGhyb3dhYmxlIHsKKworICAgICAgICBwdWJsaWMgVGVzdFRocm93YWJsZShTdHJpbmcgbWVzc2FnZSkgeworICAgICAgICAgICAgc3VwZXIobWVzc2FnZSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsaXplZE1lc3NhZ2UoKSB7CisgICAgICAgICAgICByZXR1cm4gImxvY2FsaXplZCBtZXNzYWdlIjsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0U3RhY2tUcmFjZSgpIHsKKyAgICAgICAgU3RyaW5nIG1lc3NhZ2UgPSAiVGVzdCBtZXNzYWdlIjsKKyAgICAgICAgTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlID0gbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIFRocm93YWJsZSB0aHIgPSBuZXcgVGhyb3dhYmxlKG1lc3NhZ2UsIG5wZSk7CisgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50W10gc3RlID0gdGhyLmdldFN0YWNrVHJhY2UoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiUmV0dXJuZWQgc3RhY2sgdHJhY2UgaXMgZW1wdHkiLCBzdGUubGVuZ3RoICE9IDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5pdENhdXNlKCkgeworICAgICAgICBTdHJpbmcgbWVzc2FnZSA9ICJUZXN0IG1lc3NhZ2UiOworICAgICAgICBOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUgPSBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSA9IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgVGhyb3dhYmxlIHRociA9IG5ldyBUaHJvd2FibGUoKTsKKyAgICAgICAgdGhyLmluaXRDYXVzZShpYWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlIHJldHVybnMgaW5jb3JyZWN0IGNhdXNlLiIsIGlhZSwgdGhyLmdldENhdXNlKCkpOworCisgICAgICAgIHRociA9IG5ldyBUaHJvd2FibGUoIm1lc3NhZ2UiKTsKKyAgICAgICAgdGhyLmluaXRDYXVzZShucGUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlIHJldHVybnMgaW5jb3JyZWN0IGNhdXNlLiIsIG5wZSwgdGhyLmdldENhdXNlKCkpOworCisgICAgICAgIHRociA9IG5ldyBUaHJvd2FibGUobWVzc2FnZSwgbnBlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoci5pbml0Q2F1c2UoaWFlKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaXNlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0aHIgPSBuZXcgVGhyb3dhYmxlKG5wZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aHIuaW5pdENhdXNlKGlhZSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlzZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdGhyID0gbmV3IFRocm93YWJsZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhyLmluaXRDYXVzZSh0aHIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpc2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0U3RhY2tUcmFjZSgpIHsKKyAgICAgICAgTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlID0gbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIFRocm93YWJsZSB0aHIgPSBuZXcgVGhyb3dhYmxlKG5wZSk7CisgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50W10gc3RlID0gdGhyLmdldFN0YWNrVHJhY2UoKTsKKyAgICAgICAgVGhyb3dhYmxlIHRocjEgPSBuZXcgVGhyb3dhYmxlKG5wZSk7CisgICAgICAgIHRocjEuc2V0U3RhY2tUcmFjZShzdGUpOworICAgICAgICBhc3NlcnRFcXVhbHMoc3RlLmxlbmd0aCwgdGhyMS5nZXRTdGFja1RyYWNlKCkubGVuZ3RoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhyLnNldFN0YWNrVHJhY2UobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvUGFja2FnZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9QYWNrYWdlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZlMjc0YTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvUGFja2FnZVRlc3QuamF2YQpAQCAtMCwwICsxLDQzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgUGFja2FnZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgLyoqIGFzc2lnbiBwYWNrYWdlcyBpbW1lZGlhdGVseSBzbyB0aGF0IENsYXNzLmdldFBhY2thZ2UoKSBjYWxscyBjYW5ub3Qgc2lkZS1lZmZlY3QgaXQgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMaXN0PFBhY2thZ2U+IHBhY2thZ2VzID0gQXJyYXlzLmFzTGlzdChQYWNrYWdlLmdldFBhY2thZ2VzKCkpOworCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBbm5vdGF0aW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBQYWNrYWdlIGFubm90YXRpb25zIGFyZW4ndCBzdXBwb3J0ZWQsIGJ1dCBwcmUtSUNTIHdlIGNyYXNoZWQuCisgICAgICAgIGFzc2VydEVxdWFscygwLCBnZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRBbm5vdGF0aW9ucygpLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBnZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXREZWNsYXJlZEFubm90YXRpb25zKCkubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UGFja2FnZSgpIHsKKyAgICAgICAgUGFja2FnZSBsaWJjb3JlSmF2YUxhbmcgPSBQYWNrYWdlLmdldFBhY2thZ2UoImxpYmNvcmUuamF2YS5sYW5nIik7CisgICAgICAgIGFzc2VydEVxdWFscygibGliY29yZS5qYXZhLmxhbmciLCBsaWJjb3JlSmF2YUxhbmcuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGdldENsYXNzKCkuZ2V0UGFja2FnZSgpLCBsaWJjb3JlSmF2YUxhbmcpOworICAgIH0KKworICAgIC8vIGh0dHA6Ly9iLzUxNzExMzYKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UGFja2FnZXMoKSB7CisgICAgICAgIGFzc2VydFRydWUocGFja2FnZXMuY29udGFpbnMoZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvUHJvY2Vzc0J1aWxkZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvUHJvY2Vzc0J1aWxkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDAzYWU2NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9Qcm9jZXNzQnVpbGRlclRlc3QuamF2YQpAQCAtMCwwICsxLDExMyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgbGliY29yZS5kYWx2aWsuc3lzdGVtLkNsb3NlR3VhcmRUZXN0ZXI7CitpbXBvcnQgc3RhdGljIHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9FeGVjLmV4ZWNBbmRDaGVja091dHB1dDsKKworcHVibGljIGNsYXNzIFByb2Nlc3NCdWlsZGVyVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgc2hlbGwoKSB7CisgICAgICAgIFN0cmluZyBkZXZpY2VTaCA9ICIvc3lzdGVtL2Jpbi9zaCI7CisgICAgICAgIFN0cmluZyBkZXNrdG9wU2ggPSAiL2Jpbi9zaCI7CisgICAgICAgIHJldHVybiBuZXcgRmlsZShkZXZpY2VTaCkuZXhpc3RzKCkgPyBkZXZpY2VTaCA6IGRlc2t0b3BTaDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGFzc2VydFJlZGlyZWN0RXJyb3JTdHJlYW0oYm9vbGVhbiBkb1JlZGlyZWN0LAorICAgICAgICAgICAgU3RyaW5nIGV4cGVjdGVkT3V0LCBTdHJpbmcgZXhwZWN0ZWRFcnIpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQcm9jZXNzQnVpbGRlciBwYiA9IG5ldyBQcm9jZXNzQnVpbGRlcihzaGVsbCgpLCAiLWMiLCAiZWNobyBvdXQ7IGVjaG8gZXJyIDE+JjIiKTsKKyAgICAgICAgcGIucmVkaXJlY3RFcnJvclN0cmVhbShkb1JlZGlyZWN0KTsKKyAgICAgICAgZXhlY0FuZENoZWNrT3V0cHV0KHBiLCBleHBlY3RlZE91dCwgZXhwZWN0ZWRFcnIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVkaXJlY3RFcnJvclN0cmVhbV90cnVlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFJlZGlyZWN0RXJyb3JTdHJlYW0odHJ1ZSwgIm91dFxuZXJyXG4iLCAiIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWRpcmVjdEVycm9yU3RyZWFtX2ZhbHNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFJlZGlyZWN0RXJyb3JTdHJlYW0oZmFsc2UsICJvdXRcbiIsICJlcnJcbiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbnZpcm9ubWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQcm9jZXNzQnVpbGRlciBwYiA9IG5ldyBQcm9jZXNzQnVpbGRlcihzaGVsbCgpLCAiLWMiLCAiZWNobyAkQSIpOworICAgICAgICBwYi5lbnZpcm9ubWVudCgpLnB1dCgiQSIsICJhbmRyb2lkIik7CisgICAgICAgIGV4ZWNBbmRDaGVja091dHB1dChwYiwgImFuZHJvaWRcbiIsICIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVzdHJveUNsb3Nlc0V2ZXJ5dGhpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBQcm9jZXNzIHByb2Nlc3MgPSBuZXcgUHJvY2Vzc0J1aWxkZXIoc2hlbGwoKSwgIi1jIiwgImVjaG8gb3V0OyBlY2hvIGVyciAxPiYyIikuc3RhcnQoKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBwcm9jZXNzLmdldElucHV0U3RyZWFtKCk7CisgICAgICAgIElucHV0U3RyZWFtIGVyciA9IHByb2Nlc3MuZ2V0RXJyb3JTdHJlYW0oKTsKKyAgICAgICAgT3V0cHV0U3RyZWFtIG91dCA9IHByb2Nlc3MuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIHByb2Nlc3MuZGVzdHJveSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbi5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVyci5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBXZSB0ZXN0IHdyaXRlK2ZsdXNoIGJlY2F1c2UgdGhlIFJJIHJldHVybnMgYSB3cmFwcGVkIHN0cmVhbSwgYnV0CisgICAgICAgICAgICAgKiBvbmx5IGJvdGhlcnMgdG8gY2xvc2UgdGhlIHVuZGVybHlpbmcgc3RyZWFtLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBvdXQud3JpdGUoMSk7CisgICAgICAgICAgICBvdXQuZmx1c2goKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REZXN0cm95RG9lc05vdExlYWsoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBDbG9zZUd1YXJkVGVzdGVyIGNsb3NlR3VhcmRUZXN0ZXIgPSBuZXcgQ2xvc2VHdWFyZFRlc3RlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgUHJvY2VzcyBwcm9jZXNzID0gbmV3IFByb2Nlc3NCdWlsZGVyKHNoZWxsKCksICItYyIsICJlY2hvIG91dDsgZWNobyBlcnIgMT4mMiIpLnN0YXJ0KCk7CisgICAgICAgICAgICBwcm9jZXNzLmRlc3Ryb3koKTsKKyAgICAgICAgICAgIGNsb3NlR3VhcmRUZXN0ZXIuYXNzZXJ0RXZlcnl0aGluZ1dhc0Nsb3NlZCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgY2xvc2VHdWFyZFRlc3Rlci5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVudmlyb25tZW50TWFwRm9yYmlkc051bGxzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFByb2Nlc3NCdWlsZGVyIHBiID0gbmV3IFByb2Nlc3NCdWlsZGVyKHNoZWxsKCksICItYyIsICJlY2hvICRBIik7CisgICAgICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gZW52aXJvbm1lbnQgPSBwYi5lbnZpcm9ubWVudCgpOworICAgICAgICBNYXA8U3RyaW5nLCBTdHJpbmc+IGJlZm9yZSA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPihlbnZpcm9ubWVudCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbnZpcm9ubWVudC5wdXQoIkEiLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZW52aXJvbm1lbnQucHV0KG51bGwsICJhbmRyb2lkIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJlZm9yZSwgZW52aXJvbm1lbnQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9TaG9ydFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9TaG9ydFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYjk4N2JkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL1Nob3J0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitwdWJsaWMgY2xhc3MgU2hvcnRUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbXBhcmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgc2hvcnQgbWluID0gU2hvcnQuTUlOX1ZBTFVFOworICAgICAgICBmaW5hbCBzaG9ydCB6ZXJvID0gMDsKKyAgICAgICAgZmluYWwgc2hvcnQgbWF4ID0gU2hvcnQuTUFYX1ZBTFVFOworICAgICAgICBhc3NlcnRUcnVlKFNob3J0LmNvbXBhcmUobWF4LCAgbWF4KSAgPT0gMCk7CisgICAgICAgIGFzc2VydFRydWUoU2hvcnQuY29tcGFyZShtaW4sICBtaW4pICA9PSAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShTaG9ydC5jb21wYXJlKHplcm8sIHplcm8pID09IDApOworICAgICAgICBhc3NlcnRUcnVlKFNob3J0LmNvbXBhcmUobWF4LCAgemVybykgPiAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShTaG9ydC5jb21wYXJlKG1heCwgIG1pbikgID4gMCk7CisgICAgICAgIGFzc2VydFRydWUoU2hvcnQuY29tcGFyZSh6ZXJvLCBtYXgpICA8IDApOworICAgICAgICBhc3NlcnRUcnVlKFNob3J0LmNvbXBhcmUoemVybywgbWluKSAgPiAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShTaG9ydC5jb21wYXJlKG1pbiwgIHplcm8pIDwgMCk7CisgICAgICAgIGFzc2VydFRydWUoU2hvcnQuY29tcGFyZShtaW4sICBtYXgpICA8IDApOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9TdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL1N0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODIyZTM3ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9TdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdENoYXJBdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgImhlbGxvIi5jaGFyQXQoLTEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImxlbmd0aD01OyBpbmRleD0tMSIsIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgImhlbGxvIi5jaGFyQXQoNyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoPTU7IGluZGV4PTciLCBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN1YnN0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgImhlbGxvIHRoZXJlIi5zdWJzdHJpbmcoOSwxNCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygibGVuZ3RoPTExOyByZWdpb25TdGFydD05OyByZWdpb25MZW5ndGg9NSIsCisgICAgICAgICAgICAgICAgICAgIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvU3RyaW5nVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL1N0cmluZ1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MmE3YWFkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL1N0cmluZ1Rlc3QuamF2YQpAQCAtMCwwICsxLDMxMyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllcjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLkNoYXJCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uUmVhZE9ubHlCdWZmZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldERlY29kZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0RW5jb2RlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNvZGVyUmVzdWx0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBTdHJpbmdUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RJc0VtcHR5KCkgeworICAgICAgICBhc3NlcnRUcnVlKCIiLmlzRW1wdHkoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJ4Ii5pc0VtcHR5KCkpOworICAgIH0KKworICAgIC8vIFRoZSBldmlsIGRlY29kZXIga2VlcHMgaG9sZCBvZiB0aGUgQ2hhckJ1ZmZlciBpdCB3cm90ZSB0by4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBFdmlsQ2hhcnNldERlY29kZXIgZXh0ZW5kcyBDaGFyc2V0RGVjb2RlciB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGNoYXJbXSBjaGFyczsKKyAgICAgICAgcHVibGljIEV2aWxDaGFyc2V0RGVjb2RlcihDaGFyc2V0IGNzKSB7CisgICAgICAgICAgICBzdXBlcihjcywgMS4wZiwgMS4wZik7CisgICAgICAgIH0KKyAgICAgICAgcHJvdGVjdGVkIENvZGVyUmVzdWx0IGRlY29kZUxvb3AoQnl0ZUJ1ZmZlciBpbiwgQ2hhckJ1ZmZlciBvdXQpIHsKKyAgICAgICAgICAgIGNoYXJzID0gb3V0LmFycmF5KCk7CisgICAgICAgICAgICBpbnQgaW5MZW5ndGggPSBpbi5yZW1haW5pbmcoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5MZW5ndGg7ICsraSkgeworICAgICAgICAgICAgICAgIGluLnB1dCgoYnl0ZSkgJ1gnKTsKKyAgICAgICAgICAgICAgICBvdXQucHV0KCdZJyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gQ29kZXJSZXN1bHQuVU5ERVJGTE9XOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjb3JydXB0KCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaGFycy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgICAgIGNoYXJzW2ldID0gJyQnOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gVGhlIGV2aWwgZW5jb2RlciB0cmllcyB0byB3cml0ZSB0byB0aGUgQ2hhckJ1ZmZlciBpdCB3YXMgZ2l2ZW4gdG8KKyAgICAvLyByZWFkIGZyb20uCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRXZpbENoYXJzZXRFbmNvZGVyIGV4dGVuZHMgQ2hhcnNldEVuY29kZXIgeworICAgICAgICBwdWJsaWMgRXZpbENoYXJzZXRFbmNvZGVyKENoYXJzZXQgY3MpIHsKKyAgICAgICAgICAgIHN1cGVyKGNzLCAxLjBmLCAxLjBmKTsKKyAgICAgICAgfQorICAgICAgICBwcm90ZWN0ZWQgQ29kZXJSZXN1bHQgZW5jb2RlTG9vcChDaGFyQnVmZmVyIGluLCBCeXRlQnVmZmVyIG91dCkgeworICAgICAgICAgICAgaW50IGluTGVuZ3RoID0gaW4ucmVtYWluaW5nKCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGluTGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICBpbi5wdXQoJ3gnKTsKKyAgICAgICAgICAgICAgICBvdXQucHV0KChieXRlKSAneScpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIENvZGVyUmVzdWx0LlVOREVSRkxPVzsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENoYXJzZXQgRVZJTF9DSEFSU0VUID0gbmV3IENoYXJzZXQoImV2aWwiLCBudWxsKSB7CisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKENoYXJzZXQgY2hhcnNldCkgeyByZXR1cm4gZmFsc2U7IH0KKyAgICAgICAgcHVibGljIENoYXJzZXRFbmNvZGVyIG5ld0VuY29kZXIoKSB7IHJldHVybiBuZXcgRXZpbENoYXJzZXRFbmNvZGVyKHRoaXMpOyB9CisgICAgICAgIHB1YmxpYyBDaGFyc2V0RGVjb2RlciBuZXdEZWNvZGVyKCkgeyByZXR1cm4gbmV3IEV2aWxDaGFyc2V0RGVjb2Rlcih0aGlzKTsgfQorICAgIH07CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Qnl0ZXNfTWFsaWNpb3VzQ2hhcnNldCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBzID0gImhpIjsKKyAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgb3VyIGVuY29kZXIgY2FuJ3Qgd3JpdGUgdG8gdGhlIGlucHV0IENoYXJCdWZmZXIKKyAgICAgICAgICAgIC8vIGl0IHdhcyBnaXZlbi4KKyAgICAgICAgICAgIHMuZ2V0Qnl0ZXMoRVZJTF9DSEFSU0VUKTsKKyAgICAgICAgICAgIGZhaWwoKTsgLy8gV2Ugc2hvdWxkbid0IGhhdmUgZ290IGhlcmUhCisgICAgICAgIH0gY2F0Y2ggKFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAvLyBXZSBjYXVnaHQgeW91IHRyeWluZyB0byBiZSBuYXVnaHR5IQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0cmluZ0Zyb21DaGFyc2V0KCkgeworICAgICAgICBDaGFyc2V0IGNzID0gQ2hhcnNldC5mb3JOYW1lKCJVVEYtOCIpOworICAgICAgICBieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVtdIHsoYnl0ZSkgJ2gnLCAoYnl0ZSkgJ2knfTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJoaSIsIG5ldyBTdHJpbmcoYnl0ZXMsIGNzKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0cmluZ0Zyb21DaGFyc2V0X01hbGljaW91c0NoYXJzZXQoKSB7CisgICAgICAgIENoYXJzZXQgY3MgPSBFVklMX0NIQVJTRVQ7CisgICAgICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlW10geyhieXRlKSAnaCcsIChieXRlKSAnaSd9OworICAgICAgICBmaW5hbCBTdHJpbmcgcmVzdWx0ID0gbmV3IFN0cmluZyhieXRlcywgY3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoIllZIiwgcmVzdWx0KTsgLy8gKE91ciBkZWNvZGVyIGFsd2F5cyBvdXRwdXRzICdZJ3MuKQorICAgICAgICAvLyBDaGVjayB0aGF0IGV2ZW4gaWYgdGhlIGRlY29kZXIgbWVzc2VzIHdpdGggdGhlIG91dHB1dCBDaGFyQnVmZmVyCisgICAgICAgIC8vIGFmdGVyIHdlJ3ZlIGNyZWF0ZWQgYSBzdHJpbmcgZnJvbSBpdCwgaXQgZG9lc24ndCBhZmZlY3QgdGhlIHN0cmluZy4KKyAgICAgICAgRXZpbENoYXJzZXREZWNvZGVyLmNvcnJ1cHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJZWSIsIHJlc3VsdCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRCeXRlc19iYWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQ2hlY2sgdGhhdCB3ZSB1c2UgJz8nIGFzIHRoZSByZXBsYWNlbWVudCBieXRlIGZvciBpbnZhbGlkIGNoYXJhY3RlcnMuCisgICAgICAgIGFzc2VydEVxdWFscygiWzk3LCA2MywgOThdIiwgQXJyYXlzLnRvU3RyaW5nKCJhXHUwNjY2YiIuZ2V0Qnl0ZXMoIlVTLUFTQ0lJIikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbOTcsIDYzLCA5OF0iLCBBcnJheXMudG9TdHJpbmcoImFcdTA2NjZiIi5nZXRCeXRlcyhDaGFyc2V0LmZvck5hbWUoIlVTLUFTQ0lJIikpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRCeXRlc19VVEZfOCgpIHsKKyAgICAgICAgLy8gV2UgaGF2ZSBhIGZhc3QgcGF0aCBpbXBsZW1lbnRhdGlvbiBvZiBTdHJpbmcuZ2V0Qnl0ZXMgZm9yIFVURi04LgorICAgICAgICBDaGFyc2V0IGNzID0gQ2hhcnNldC5mb3JOYW1lKCJVVEYtOCIpOworCisgICAgICAgIC8vIFRlc3QgdGhlIGVtcHR5IHN0cmluZy4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbXSIsIEFycmF5cy50b1N0cmluZygiIi5nZXRCeXRlcyhjcykpKTsKKworICAgICAgICAvLyBUZXN0IG9uZS1ieXRlIGNoYXJhY3RlcnMuCisgICAgICAgIGFzc2VydEVxdWFscygiWzBdIiwgQXJyYXlzLnRvU3RyaW5nKCJcdTAwMDAiLmdldEJ5dGVzKGNzKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlsxMjddIiwgQXJyYXlzLnRvU3RyaW5nKCJcdTAwN2YiLmdldEJ5dGVzKGNzKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlsxMDQsIDEwNV0iLCBBcnJheXMudG9TdHJpbmcoImhpIi5nZXRCeXRlcyhjcykpKTsKKworICAgICAgICAvLyBUZXN0IHR3by1ieXRlIGNoYXJhY3RlcnMuCisgICAgICAgIGFzc2VydEVxdWFscygiWy02MiwgLTEyOF0iLCBBcnJheXMudG9TdHJpbmcoIlx1MDA4MCIuZ2V0Qnl0ZXMoY3MpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWy0zOSwgLTkwXSIsIEFycmF5cy50b1N0cmluZygiXHUwNjY2Ii5nZXRCeXRlcyhjcykpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbLTMzLCAtNjVdIiwgQXJyYXlzLnRvU3RyaW5nKCJcdTA3ZmYiLmdldEJ5dGVzKGNzKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlsxMDQsIC0zOSwgLTkwLCAxMDVdIiwgQXJyYXlzLnRvU3RyaW5nKCJoXHUwNjY2aSIuZ2V0Qnl0ZXMoY3MpKSk7CisKKyAgICAgICAgLy8gVGVzdCB0aHJlZS1ieXRlIGNoYXJhY3RlcnMuCisgICAgICAgIGFzc2VydEVxdWFscygiWy0zMiwgLTk2LCAtMTI4XSIsIEFycmF5cy50b1N0cmluZygiXHUwODAwIi5nZXRCeXRlcyhjcykpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbLTMxLCAtMTIwLCAtNzZdIiwgQXJyYXlzLnRvU3RyaW5nKCJcdTEyMzQiLmdldEJ5dGVzKGNzKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlstMTcsIC02NSwgLTY1XSIsIEFycmF5cy50b1N0cmluZygiXHVmZmZmIi5nZXRCeXRlcyhjcykpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbMTA0LCAtMzEsIC0xMjAsIC03NiwgMTA1XSIsIEFycmF5cy50b1N0cmluZygiaFx1MTIzNGkiLmdldEJ5dGVzKGNzKSkpOworCisgICAgICAgIC8vIFRlc3Qgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzLgorICAgICAgICAvLyBNaW5pbXVtIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyOiBVKzEwMDAwCisgICAgICAgIGFzc2VydEVxdWFscygiWy0xNiwgLTExMiwgLTEyOCwgLTEyOF0iLCBBcnJheXMudG9TdHJpbmcoIlx1ZDgwMFx1ZGMwMCIuZ2V0Qnl0ZXMoY3MpKSk7CisgICAgICAgIC8vIFJhbmRvbSBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcjogVSsxMDM4MSBVZ2FyaXRpYyBsZXR0ZXIgYmV0YQorICAgICAgICBhc3NlcnRFcXVhbHMoIlstMTYsIC0xMTIsIC0xMTQsIC0xMjddIiwgQXJyYXlzLnRvU3RyaW5nKCJcdWQ4MDBcdWRmODEiLmdldEJ5dGVzKGNzKSkpOworICAgICAgICAvLyBNYXhpbXVtIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyOiBVKzEwRkZGRgorICAgICAgICBhc3NlcnRFcXVhbHMoIlstMTIsIC0xMTMsIC02NSwgLTY1XSIsIEFycmF5cy50b1N0cmluZygiXHVkYmZmXHVkZmZmIi5nZXRCeXRlcyhjcykpKTsKKyAgICAgICAgLy8gQSBoaWdoIHN1cnJvZ2F0ZSBhdCBlbmQgb2Ygc3RyaW5nIGlzIGFuIGVycm9yIHJlcGxhY2VkIHdpdGggJz8nLgorICAgICAgICBhc3NlcnRFcXVhbHMoIlsxMDQsIDYzXSIsIEFycmF5cy50b1N0cmluZygiaFx1ZDgwMCIuZ2V0Qnl0ZXMoY3MpKSk7CisgICAgICAgIC8vIEEgaGlnaCBzdXJyb2dhdGUgbm90IGZvbGxvd2VkIGJ5IGEgbG93IHN1cnJvZ2F0ZSBpcyBhbiBlcnJvciByZXBsYWNlZCB3aXRoICc/Jy4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbMTA0LCA2MywgMTA1XSIsIEFycmF5cy50b1N0cmluZygiaFx1ZDgwMGkiLmdldEJ5dGVzKGNzKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbmV3X1N0cmluZ19iYWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQ2hlY2sgdGhhdCB3ZSB1c2UgVStGRkZEIGFzIHRoZSByZXBsYWNlbWVudCBzdHJpbmcgZm9yIGludmFsaWQgYnl0ZXMuCisgICAgICAgIGFzc2VydEVxdWFscygiYVx1ZmZmZGIiLCBuZXcgU3RyaW5nKG5ldyBieXRlW10geyA5NywgLTIsIDk4IH0sICJVUy1BU0NJSSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhXHVmZmZkYiIsIG5ldyBTdHJpbmcobmV3IGJ5dGVbXSB7IDk3LCAtMiwgOTggfSwgQ2hhcnNldC5mb3JOYW1lKCJVUy1BU0NJSSIpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgYSB3aWRlbHkgYXNzdW1lZCBwZXJmb3JtYW5jZSBjaGFyYWN0ZXJpc3RpYyBvZiBTdHJpbmcuc3Vic3RyaW5nKCk6CisgICAgICogdGhhdCBpdCByZXVzZXMgdGhlIG9yaWdpbmFsJ3MgYmFja2luZyBhcnJheS4gQWx0aG91Z2ggYmVoYXZpb3VyIHNob3VsZCBiZQorICAgICAqIGNvcnJlY3QgZXZlbiBpZiB0aGlzIHRlc3QgZmFpbHMsIG1hbnkgYXBwbGljYXRpb25zIG1heSBzdWZmZXIKKyAgICAgKiBzaWduaWZpY2FudCBwZXJmb3JtYW5jZSBkZWdyYWRhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3Vic3RyaW5nU2hhcmVzQmFja2luZ0FycmF5KCkgdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgYWJjZGVmZ2hpaiA9ICJBQkNERUZHSElKIjsKKyAgICAgICAgU3RyaW5nIGNkZWZnID0gYWJjZGVmZ2hpai5zdWJzdHJpbmcoMiwgNyk7CisgICAgICAgIGFzc2VydFNhbWUoZ2V0QmFja2luZ0FycmF5KGFiY2RlZmdoaWopLCBnZXRCYWNraW5nQXJyYXkoY2RlZmcpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBhIHdpZGVseSBhc3N1bWVkIHBlcmZvcm1hbmNlIGNoYXJhY3RlcmlzdGljIG9mIHN0cmluZydzIGNvcHkKKyAgICAgKiBjb25zdHJ1Y3RvcjogdGhhdCBpdCBlbnN1cmVzIHRoZSBiYWNraW5nIGFycmF5IGlzIHRoZSBzYW1lIGxlbmd0aCBhcyB0aGUKKyAgICAgKiBzdHJpbmcuIEFsdGhvdWdoIGJlaGF2aW91ciBzaG91bGQgYmUgY29ycmVjdCBldmVuIGlmIHRoaXMgdGVzdCBmYWlscywKKyAgICAgKiBtYW55IGFwcGxpY2F0aW9ucyBtYXkgc3VmZmVyIHNpZ25pZmljYW50IHBlcmZvcm1hbmNlIGRlZ3JhZGF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTdHJpbmdDb3BpZXNBdm9pZEhlYXBSZXRlbnRpb24oKSB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBhYmNkZWZnaGlqID0gIkFCQ0RFRkdISUoiOworICAgICAgICBhc3NlcnRTYW1lKGdldEJhY2tpbmdBcnJheShhYmNkZWZnaGlqKSwgZ2V0QmFja2luZ0FycmF5KG5ldyBTdHJpbmcoYWJjZGVmZ2hpaikpKTsKKworICAgICAgICBTdHJpbmcgY2RlZmcgPSBhYmNkZWZnaGlqLnN1YnN0cmluZygyLCA3KTsKKyAgICAgICAgYXNzZXJ0U2FtZShnZXRCYWNraW5nQXJyYXkoYWJjZGVmZ2hpaiksIGdldEJhY2tpbmdBcnJheShjZGVmZykpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgZ2V0QmFja2luZ0FycmF5KG5ldyBTdHJpbmcoY2RlZmcpKS5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVzZXMgcmVmbGVjdGlvbiB0byByZXR1cm4gdGhlIGNoYXJbXSBiYWNraW5nIHRoZSBnaXZlbiBzdHJpbmcuIFRoaXMKKyAgICAgKiByZXR1cm5zIHRoZSBhY3R1YWwgYmFja2luZyBhcnJheTsgd2hpY2ggbXVzdCBub3QgYmUgbW9kaWZpZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBjaGFyW10gZ2V0QmFja2luZ0FycmF5KFN0cmluZyBzdHJpbmcpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChGaWVsZCBmIDogU3RyaW5nLmNsYXNzLmdldERlY2xhcmVkRmllbGRzKCkpIHsKKyAgICAgICAgICAgIGlmICghTW9kaWZpZXIuaXNTdGF0aWMoZi5nZXRNb2RpZmllcnMoKSkgJiYgZi5nZXRUeXBlKCkgPT0gY2hhcltdLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgZi5zZXRBY2Nlc3NpYmxlKHRydWUpOworICAgICAgICAgICAgICAgIHJldHVybiAoY2hhcltdKSBmLmdldChzdHJpbmcpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm8gY2hhcnNbXSBmaWVsZCBvbiBTdHJpbmchIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHN0cmluZ3MgaW50ZXJuZWQgbWFudWFsbHkgYW5kIHRoZW4gbGF0ZXIgbG9hZGVkIGFzIGxpdGVyYWxzCisgICAgICogbWFpbnRhaW4gcmVmZXJlbmNlIGVxdWFsaXR5LiBodHRwOi8vYi8zMDk4OTYwCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEludGVybkJlZm9yZUxpdGVyYWxJc0xvYWRlZCgpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIFN0cmluZyBwcm9ncmFtbWF0aWMgPSBBcnJheXMuYXNMaXN0KCI1MDU4IiwgIjk5NjIiLCAiMTU2MyIsICI1NzQ0IikudG9TdHJpbmcoKS5pbnRlcm4oKTsKKyAgICAgICAgU3RyaW5nIGxpdGVyYWwgPSAoU3RyaW5nKSBDbGFzcy5mb3JOYW1lKCJsaWJjb3JlLmphdmEubGFuZy5TdHJpbmdUZXN0JEhhc0xpdGVyYWwiKQorICAgICAgICAgICAgICAgIC5nZXREZWNsYXJlZEZpZWxkKCJsaXRlcmFsIikuZ2V0KG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoU3lzdGVtLmlkZW50aXR5SGFzaENvZGUocHJvZ3JhbW1hdGljKSwgU3lzdGVtLmlkZW50aXR5SGFzaENvZGUobGl0ZXJhbCkpOworICAgICAgICBhc3NlcnRTYW1lKHByb2dyYW1tYXRpYywgbGl0ZXJhbCk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIEhhc0xpdGVyYWwgeworICAgICAgICBzdGF0aWMgU3RyaW5nIGxpdGVyYWwgPSAiWzUwNTgsIDk5NjIsIDE1NjMsIDU3NDRdIjsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTEFUSU5fQ0FQSVRBTF9JID0gIkkiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBMQVRJTl9DQVBJVEFMX0lfV0lUSF9ET1RfQUJPVkUgPSAiXHUwMTMwIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTEFUSU5fU01BTExfSSA9ICJpIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTEFUSU5fU01BTExfRE9UTEVTU19JID0gIlx1MDEzMSI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBMQVRJTl9JX1ZBUklBTlRTID0geworICAgICAgICBMQVRJTl9TTUFMTF9JLAorICAgICAgICBMQVRJTl9TTUFMTF9ET1RMRVNTX0ksCisgICAgICAgIExBVElOX0NBUElUQUxfSSwKKyAgICAgICAgTEFUSU5fQ0FQSVRBTF9JX1dJVEhfRE9UX0FCT1ZFLAorICAgIH07CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2FzZU1hcHBpbmdfdHJfVFIoKSB7CisgICAgICAgIExvY2FsZSB0clRSID0gbmV3IExvY2FsZSgidHIiLCAiVFIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExBVElOX1NNQUxMX0ksIExBVElOX1NNQUxMX0kudG9Mb3dlckNhc2UodHJUUikpOworICAgICAgICBhc3NlcnRFcXVhbHMoTEFUSU5fU01BTExfSSwgTEFUSU5fQ0FQSVRBTF9JX1dJVEhfRE9UX0FCT1ZFLnRvTG93ZXJDYXNlKHRyVFIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExBVElOX1NNQUxMX0RPVExFU1NfSSwgTEFUSU5fU01BTExfRE9UTEVTU19JLnRvTG93ZXJDYXNlKHRyVFIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoTEFUSU5fQ0FQSVRBTF9JLCBMQVRJTl9DQVBJVEFMX0kudG9VcHBlckNhc2UodHJUUikpOworICAgICAgICBhc3NlcnRFcXVhbHMoTEFUSU5fQ0FQSVRBTF9JX1dJVEhfRE9UX0FCT1ZFLCBMQVRJTl9DQVBJVEFMX0lfV0lUSF9ET1RfQUJPVkUudG9VcHBlckNhc2UodHJUUikpOworICAgICAgICBhc3NlcnRFcXVhbHMoTEFUSU5fQ0FQSVRBTF9JX1dJVEhfRE9UX0FCT1ZFLCBMQVRJTl9TTUFMTF9JLnRvVXBwZXJDYXNlKHRyVFIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoTEFUSU5fQ0FQSVRBTF9JLCBMQVRJTl9TTUFMTF9ET1RMRVNTX0kudG9VcHBlckNhc2UodHJUUikpOworICAgICAgICBhc3NlcnRFcXVhbHMoTEFUSU5fU01BTExfRE9UTEVTU19JLCBMQVRJTl9DQVBJVEFMX0kudG9Mb3dlckNhc2UodHJUUikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDYXNlTWFwcGluZ19lbl9VUygpIHsKKyAgICAgICAgTG9jYWxlIGVuVXMgPSBuZXcgTG9jYWxlKCJlbiIsICJVUyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoTEFUSU5fQ0FQSVRBTF9JLCBMQVRJTl9TTUFMTF9JLnRvVXBwZXJDYXNlKGVuVXMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExBVElOX0NBUElUQUxfSSwgTEFUSU5fQ0FQSVRBTF9JLnRvVXBwZXJDYXNlKGVuVXMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExBVElOX0NBUElUQUxfSV9XSVRIX0RPVF9BQk9WRSwgTEFUSU5fQ0FQSVRBTF9JX1dJVEhfRE9UX0FCT1ZFLnRvVXBwZXJDYXNlKGVuVXMpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoTEFUSU5fU01BTExfSSwgTEFUSU5fU01BTExfSS50b0xvd2VyQ2FzZShlblVzKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhMQVRJTl9TTUFMTF9JLCBMQVRJTl9DQVBJVEFMX0kudG9Mb3dlckNhc2UoZW5VcykpOworICAgICAgICBhc3NlcnRFcXVhbHMoTEFUSU5fU01BTExfRE9UTEVTU19JLCBMQVRJTl9TTUFMTF9ET1RMRVNTX0kudG9Mb3dlckNhc2UoZW5VcykpOworCisgICAgICAgIGFzc2VydEVxdWFscyhMQVRJTl9DQVBJVEFMX0ksIExBVElOX1NNQUxMX0RPVExFU1NfSS50b1VwcGVyQ2FzZShlblVzKSk7CisgICAgICAgIC8vIGh0dHA6Ly9iLzMzMjU3OTk6IEFuZHJvaWQgZmFpbHMgdGhpcyB3aXRoIGFuIGV4dHJhIGNvbWJpbmluZyAiZG90IGFib3ZlIi4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKExBVElOX1NNQUxMX0ksIExBVElOX0NBUElUQUxfSV9XSVRIX0RPVF9BQk9WRS50b0xvd2VyQ2FzZShlblVzKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVxdWFsc0lnbm9yZUNhc2VfdHJfVFIoKSB7CisgICAgICAgIHRlc3RFcXVhbHNJZ25vcmVDYXNlKG5ldyBMb2NhbGUoInRyIiwgIlRSIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHNJZ25vcmVDYXNlX2VuX1VTKCkgeworICAgICAgICB0ZXN0RXF1YWxzSWdub3JlQ2FzZShuZXcgTG9jYWxlKCJlbiIsICJVUyIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdHJpbmcuZXF1YWxzSWdub3JlQ2FzZSBzaG91bGQgbm90IGRlcGVuZCBvbiB0aGUgbG9jYWxlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB0ZXN0RXF1YWxzSWdub3JlQ2FzZShMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIExvY2FsZSBkZWZhdWx0TG9jYWxlID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobG9jYWxlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIGEgOiBMQVRJTl9JX1ZBUklBTlRTKSB7CisgICAgICAgICAgICAgICAgZm9yIChTdHJpbmcgYiA6IExBVElOX0lfVkFSSUFOVFMpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFhLmVxdWFsc0lnbm9yZUNhc2UoYikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkICIgKyBhICsgIiB0byBlcXVhbCAiICsgYiArICIgaW4gIiArICBsb2NhbGUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgTG9jYWxlLnNldERlZmF1bHQoZGVmYXVsdExvY2FsZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVnaW9uTWF0Y2hlc19pZ25vcmVDYXNlX2VuX1VTKCkgeworICAgICAgICB0ZXN0UmVnaW9uTWF0Y2hlc19pZ25vcmVDYXNlKG5ldyBMb2NhbGUoImVuIiwgIlVTIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWdpb25NYXRjaGVzX2lnbm9yZUNhc2VfdHJfVFIoKSB7CisgICAgICAgIHRlc3RSZWdpb25NYXRjaGVzX2lnbm9yZUNhc2UobmV3IExvY2FsZSgidHIiLCAiVFIiKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RSZWdpb25NYXRjaGVzX2lnbm9yZUNhc2UoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBMb2NhbGUgZGVmYXVsdExvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KGxvY2FsZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKFN0cmluZyBhIDogTEFUSU5fSV9WQVJJQU5UUykgeworICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIGIgOiBMQVRJTl9JX1ZBUklBTlRTKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICghYS5yZWdpb25NYXRjaGVzKHRydWUsIDAsIGIsIDAsIGIubGVuZ3RoKCkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCAiICsgYSArICIgdG8gZXF1YWwgIiArIGIgKyAiIGluICIgKyAgbG9jYWxlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KGRlZmF1bHRMb2NhbGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD0xNTI2NgorICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVwbGFjZUFsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoInByb2plY3RfSWQiLCAicHJvamVjdElkIi5yZXBsYWNlQWxsKCIoPyFeKShcXHB7VXBwZXJ9KSg/ISQpIiwgIl8kMSIpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvU3lzdGVtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL1N5c3RlbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOTk1OTU0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL1N5c3RlbVRlc3QuamF2YQpAQCAtMCwwICsxLDEyMSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmc7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkV3JpdGVyOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuRm9ybWF0dGVyOworCitwdWJsaWMgY2xhc3MgU3lzdGVtVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RMaW5lU2VwYXJhdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBCZWZvcmUgSmF2YSA3LCB0aGUgc21hbGwgbnVtYmVyIG9mIGNsYXNzZXMgdGhhdCB3YW50ZWQgdGhlIGxpbmUgc2VwYXJhdG9yIHdvdWxkCisgICAgICAgICAgICAvLyB1c2UgU3lzdGVtLmdldFByb3BlcnR5LiBOb3cgdGhleSBzaG91bGQgdXNlIFN5c3RlbS5saW5lU2VwYXJhdG9yIGluc3RlYWQsIGFuZCB0aGUKKyAgICAgICAgICAgIC8vICJsaW5lLnNlcGFyYXRvciIgcHJvcGVydHkgaGFzIG5vIGVmZmVjdCBhZnRlciB0aGUgVk0gaGFzIHN0YXJ0ZWQuCisKKyAgICAgICAgICAgIC8vIFRlc3QgU3lzdGVtLmxpbmVTZXBhcmF0b3IgZGlyZWN0bHkuCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlxuIiwgU3lzdGVtLmxpbmVTZXBhcmF0b3IoKSk7CisgICAgICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoImxpbmUuc2VwYXJhdG9yIiwgInBvb3AiKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiXG4iLCBTeXN0ZW0ubGluZVNlcGFyYXRvcigpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKFN5c3RlbS5saW5lU2VwYXJhdG9yKCkuZXF1YWxzKFN5c3RlbS5nZXRQcm9wZXJ0eSgibGluZS5zZXBhcmF0b3IiKSkpOworCisgICAgICAgICAgICAvLyBqYXZhLmlvLkJ1ZmZlcmVkV3JpdGVyIC0tLSB1c2VzIFN5c3RlbS5saW5lU2VwYXJhdG9yIG9uIEFuZHJvaWQgYnV0IG5vdCBvbiBSSS4KKyAgICAgICAgICAgIFN0cmluZ1dyaXRlciBzdyA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKKyAgICAgICAgICAgIEJ1ZmZlcmVkV3JpdGVyIGJ3ID0gbmV3IEJ1ZmZlcmVkV3JpdGVyKHN3KTsKKyAgICAgICAgICAgIGJ3Lm5ld0xpbmUoKTsKKyAgICAgICAgICAgIGJ3LmZsdXNoKCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoU3lzdGVtLmxpbmVTZXBhcmF0b3IoKSwgc3cudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShTeXN0ZW0ubGluZVNlcGFyYXRvcigpLmVxdWFscyhTeXN0ZW0uZ2V0UHJvcGVydHkoImxpbmUuc2VwYXJhdG9yIikpKTsKKworICAgICAgICAgICAgLy8gamF2YS5pby5QcmludFN0cmVhbSAtLS0gdXNlcyBTeXN0ZW0ubGluZVNlcGFyYXRvciBvbiBBbmRyb2lkIGJ1dCBub3Qgb24gUkkuCisgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIG5ldyBQcmludFN0cmVhbShiYW9zKS5wcmludGxuKCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoU3lzdGVtLmxpbmVTZXBhcmF0b3IoKSwgbmV3IFN0cmluZyhiYW9zLnRvQnl0ZUFycmF5KCksICJVVEYtOCIpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKFN5c3RlbS5saW5lU2VwYXJhdG9yKCkuZXF1YWxzKFN5c3RlbS5nZXRQcm9wZXJ0eSgibGluZS5zZXBhcmF0b3IiKSkpOworCisgICAgICAgICAgICAvLyBqYXZhLmlvLlByaW50V3JpdGVyIC0tLSB1c2VzIFN5c3RlbS5saW5lU2VwYXJhdG9yIG9uIEFuZHJvaWQgYnV0IG5vdCBvbiBSSS4KKyAgICAgICAgICAgIHN3ID0gbmV3IFN0cmluZ1dyaXRlcigpOworICAgICAgICAgICAgbmV3IFByaW50V3JpdGVyKHN3KS5wcmludGxuKCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoU3lzdGVtLmxpbmVTZXBhcmF0b3IoKSwgc3cudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShTeXN0ZW0ubGluZVNlcGFyYXRvcigpLmVxdWFscyhTeXN0ZW0uZ2V0UHJvcGVydHkoImxpbmUuc2VwYXJhdG9yIikpKTsKKworICAgICAgICAgICAgLy8gamF2YS51dGlsLkZvcm1hdHRlciAtLS0gdXNlcyBTeXN0ZW0ubGluZVNlcGFyYXRvciBvbiBib3RoLgorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFN5c3RlbS5saW5lU2VwYXJhdG9yKCksIG5ldyBGb3JtYXR0ZXIoKS5mb3JtYXQoIiVuIikudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShTeXN0ZW0ubGluZVNlcGFyYXRvcigpLmVxdWFscyhTeXN0ZW0uZ2V0UHJvcGVydHkoImxpbmUuc2VwYXJhdG9yIikpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgibGluZS5zZXBhcmF0b3IiLCAiXG4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBcnJheUNvcHlUYXJnZXROb3RBcnJheSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobmV3IGNoYXJbNV0sIDAsICJIZWxsbyIsIDAsIDMpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChBcnJheVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZGVzdGluYXRpb24gb2YgdHlwZSBqYXZhLmxhbmcuU3RyaW5nIGlzIG5vdCBhbiBhcnJheSIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBcnJheUNvcHlTb3VyY2VOb3RBcnJheSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoIkhlbGxvIiwgMCwgbmV3IGNoYXJbNV0sIDAsIDMpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChBcnJheVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygic291cmNlIG9mIHR5cGUgamF2YS5sYW5nLlN0cmluZyBpcyBub3QgYW4gYXJyYXkiLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXJyYXlDb3B5QXJyYXlUeXBlTWlzbWF0Y2goKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5ldyBjaGFyWzVdLCAwLCBuZXcgT2JqZWN0WzVdLCAwLCAzKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImNoYXJbXSBhbmQgamF2YS5sYW5nLk9iamVjdFtdIGFyZSBpbmNvbXBhdGlibGUgYXJyYXkgdHlwZXMiLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXJyYXlDb3B5RWxlbWVudFR5cGVNaXNtYXRjaCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobmV3IE9iamVjdFtdIHsgbnVsbCwgNSwgImhlbGxvIiB9LCAwLAorICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcltdIHsgMSwgMiwgMywgbnVsbCwgbnVsbCB9LCAwLCAzKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInNvdXJjZVsyXSBvZiB0eXBlIGphdmEubGFuZy5TdHJpbmcgY2Fubm90IGJlIHN0b3JlZCBpbiBkZXN0aW5hdGlvbiBhcnJheSBvZiB0eXBlIGphdmEubGFuZy5JbnRlZ2VyW10iLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXJyYXlDb3B5TnVsbCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobnVsbCwgMCwgbmV3IGNoYXJbNV0sIDAsIDMpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInNyYyA9PSBudWxsIiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5ldyBjaGFyWzVdLCAwLCBudWxsLCAwLCAzKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJkc3QgPT0gbnVsbCIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9UaHJlYWRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvVGhyZWFkVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2OTVlM2UKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvVGhyZWFkVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nOworCitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0ludGVnZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgVGhyZWFkVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RMZWFraW5nU3RhcnRlZFRocmVhZHMoKSB7CisgICAgICAgIGZpbmFsIEF0b21pY0ludGVnZXIgZmluYWxpemVkVGhyZWFkc0NvdW50ID0gbmV3IEF0b21pY0ludGVnZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IHRydWU7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBuZXdUaHJlYWQoZmluYWxpemVkVGhyZWFkc0NvdW50LCAxMDI0IDw8IGkpLnN0YXJ0KCk7CisgICAgICAgICAgICB9IGNhdGNoIChPdXRPZk1lbW9yeUVycm9yIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLnJ1bkZpbmFsaXphdGlvbigpOworICAgICAgICBhc3NlcnRUcnVlKCJTdGFydGVkIHRocmVhZHMgd2VyZSBuZXZlciBmaW5hbGl6ZWQhIiwgZmluYWxpemVkVGhyZWFkc0NvdW50LmdldCgpID4gMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdExlYWtpbmdVbnN0YXJ0ZWRUaHJlYWRzKCkgeworICAgICAgICBmaW5hbCBBdG9taWNJbnRlZ2VyIGZpbmFsaXplZFRocmVhZHNDb3VudCA9IG5ldyBBdG9taWNJbnRlZ2VyKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyB0cnVlOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbmV3VGhyZWFkKGZpbmFsaXplZFRocmVhZHNDb3VudCwgMTAyNCA8PCBpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE91dE9mTWVtb3J5RXJyb3IgZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0ucnVuRmluYWxpemF0aW9uKCk7CisgICAgICAgIGFzc2VydFRydWUoIlVuc3RhcnRlZCB0aHJlYWRzIHdlcmUgbmV2ZXIgZmluYWxpemVkISIsIGZpbmFsaXplZFRocmVhZHNDb3VudC5nZXQoKSA+IDApOworICAgIH0KKworICAgIHByaXZhdGUgVGhyZWFkIG5ld1RocmVhZChmaW5hbCBBdG9taWNJbnRlZ2VyIGZpbmFsaXplZFRocmVhZHNDb3VudCwgZmluYWwgaW50IHNpemUpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBUaHJlYWQoKSB7CisgICAgICAgICAgICBieXRlW10gbWVtb3J5UHJlc3N1cmUgPSBuZXcgYnl0ZVtzaXplXTsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICAgICAgICAgIHN1cGVyLmZpbmFsaXplKCk7CisgICAgICAgICAgICAgICAgZmluYWxpemVkVGhyZWFkc0NvdW50LmluY3JlbWVudEFuZEdldCgpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9UaHJvd2FibGVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvVGhyb3dhYmxlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcwMGY2MTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvVGhyb3dhYmxlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzIyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZzsKKworaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CitpbXBvcnQgamF2YS5pby5TdHJpbmdXcml0ZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgbGliY29yZS5qYXZhLnV0aWwuU2VyaWFsaXphYmxlVGVzdGVyOworCitwdWJsaWMgY2xhc3MgVGhyb3dhYmxlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBOb1N0YWNrVHJhY2VFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCBUaHJvd2FibGUgZmlsbEluU3RhY2tUcmFjZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3ROdWxsU3RhY2tUcmFjZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N0YWNrVHJhY2VFeGNlcHRpb24oKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdGFja1RyYWNlRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAvLyBXZSB1c2VkIHRvIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gcHJpbnRpbmcgYW4gZXhjZXB0aW9uIHdpdGggbm8gc3RhY2sgdHJhY2UuCisgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UobmV3IFByaW50V3JpdGVyKG5ldyBTdHJpbmdXcml0ZXIoKSkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgU3VwcHJlc3Npb25zVGhyb3dhYmxlIGV4dGVuZHMgVGhyb3dhYmxlIHsKKyAgICAgICAgcHVibGljIFN1cHByZXNzaW9uc1Rocm93YWJsZShTdHJpbmcgZGV0YWlsTWVzc2FnZSwgVGhyb3dhYmxlIHRocm93YWJsZSwKKyAgICAgICAgICAgICAgICBib29sZWFuIGVuYWJsZVN1cHByZXNzaW9uKSB7CisgICAgICAgICAgICBzdXBlcihkZXRhaWxNZXNzYWdlLCB0aHJvd2FibGUsIGVuYWJsZVN1cHByZXNzaW9uKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRTdXBwcmVzc2VkKCkgeworICAgICAgICBUaHJvd2FibGUgdGhyb3dhYmxlID0gbmV3IFRocm93YWJsZSgpOworICAgICAgICBhc3NlcnRTdXBwcmVzc2VkKHRocm93YWJsZSk7CisgICAgICAgIFRocm93YWJsZSBzdXBwcmVzc2VkQSA9IG5ldyBUaHJvd2FibGUoKTsKKyAgICAgICAgdGhyb3dhYmxlLmFkZFN1cHByZXNzZWQoc3VwcHJlc3NlZEEpOworICAgICAgICBhc3NlcnRTdXBwcmVzc2VkKHRocm93YWJsZSwgc3VwcHJlc3NlZEEpOworICAgICAgICBUaHJvd2FibGUgc3VwcHJlc3NlZEIgPSBuZXcgVGhyb3dhYmxlKCk7CisgICAgICAgIHRocm93YWJsZS5hZGRTdXBwcmVzc2VkKHN1cHByZXNzZWRCKTsKKyAgICAgICAgYXNzZXJ0U3VwcHJlc3NlZCh0aHJvd2FibGUsIHN1cHByZXNzZWRBLCBzdXBwcmVzc2VkQik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFkZER1cGxpY2F0ZVN1cHByZXNzZWQoKSB7CisgICAgICAgIFRocm93YWJsZSB0aHJvd2FibGUgPSBuZXcgVGhyb3dhYmxlKCk7CisgICAgICAgIFRocm93YWJsZSBzdXBwcmVzc2VkQSA9IG5ldyBUaHJvd2FibGUoKTsKKyAgICAgICAgdGhyb3dhYmxlLmFkZFN1cHByZXNzZWQoc3VwcHJlc3NlZEEpOworICAgICAgICB0aHJvd2FibGUuYWRkU3VwcHJlc3NlZChzdXBwcmVzc2VkQSk7CisgICAgICAgIHRocm93YWJsZS5hZGRTdXBwcmVzc2VkKHN1cHByZXNzZWRBKTsKKyAgICAgICAgYXNzZXJ0U3VwcHJlc3NlZCh0aHJvd2FibGUsIHN1cHByZXNzZWRBLCBzdXBwcmVzc2VkQSwgc3VwcHJlc3NlZEEpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRTdXBwcmVzc2VkUmV0dXJuc0NvcHkoKSB7CisgICAgICAgIFRocm93YWJsZSB0aHJvd2FibGUgPSBuZXcgVGhyb3dhYmxlKCk7CisgICAgICAgIFRocm93YWJsZSBzdXBwcmVzc2VkQSA9IG5ldyBUaHJvd2FibGUoKTsKKyAgICAgICAgVGhyb3dhYmxlIHN1cHByZXNzZWRCID0gbmV3IFRocm93YWJsZSgpOworICAgICAgICB0aHJvd2FibGUuYWRkU3VwcHJlc3NlZChzdXBwcmVzc2VkQSk7CisgICAgICAgIHRocm93YWJsZS5hZGRTdXBwcmVzc2VkKHN1cHByZXNzZWRCKTsKKyAgICAgICAgVGhyb3dhYmxlW10gbXV0YWJsZSA9IHRocm93YWJsZS5nZXRTdXBwcmVzc2VkKCk7CisgICAgICAgIG11dGFibGVbMF0gPSBudWxsOworICAgICAgICBtdXRhYmxlWzFdID0gbnVsbDsKKyAgICAgICAgYXNzZXJ0U3VwcHJlc3NlZCh0aHJvd2FibGUsIHN1cHByZXNzZWRBLCBzdXBwcmVzc2VkQik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFkZFN1cHByZXNzZWRXaXRoU3VwcHJlc3Npb25EaXNhYmxlZCgpIHsKKyAgICAgICAgVGhyb3dhYmxlIHRocm93YWJsZSA9IG5ldyBTdXBwcmVzc2lvbnNUaHJvd2FibGUoImZvbyIsIG51bGwsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0U3VwcHJlc3NlZCh0aHJvd2FibGUpOworICAgICAgICB0aHJvd2FibGUuYWRkU3VwcHJlc3NlZChuZXcgVGhyb3dhYmxlKCkpOworICAgICAgICBhc3NlcnRTdXBwcmVzc2VkKHRocm93YWJsZSk7CisgICAgICAgIHRocm93YWJsZS5hZGRTdXBwcmVzc2VkKG5ldyBUaHJvd2FibGUoKSk7CisgICAgICAgIGFzc2VydFN1cHByZXNzZWQodGhyb3dhYmxlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWRkU3VwcHJlc3NlZFNlbGYoKSB7CisgICAgICAgIFRocm93YWJsZSB0aHJvd2FibGUgPSBuZXcgVGhyb3dhYmxlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aHJvd2FibGUuYWRkU3VwcHJlc3NlZCh0aHJvd2FibGUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRTdXBwcmVzc2VkTnVsbCgpIHsKKyAgICAgICAgVGhyb3dhYmxlIHRocm93YWJsZSA9IG5ldyBUaHJvd2FibGUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRocm93YWJsZS5hZGRTdXBwcmVzc2VkKG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFByaW50U3RhY2tUcmFjZVdpdGhDYXVzZSgpIHsKKyAgICAgICAgVGhyb3dhYmxlIHRocm93YWJsZSA9IG5ld1Rocm93YWJsZSgiVGhyb3dhYmxlIiwgIkEiLCAiQiIpOworICAgICAgICB0aHJvd2FibGUuaW5pdENhdXNlKG5ld1Rocm93YWJsZSgiQ2F1c2UiLCAiQSIsICJCIiwgIkMiLCAiRCIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoImphdmEubGFuZy5UaHJvd2FibGU6IFRocm93YWJsZVxuIgorICAgICAgICAgICAgICAgICsgIlx0YXQgQ2xhc3NCLmRvQihDbGFzc0IuamF2YToxKVxuIgorICAgICAgICAgICAgICAgICsgIlx0YXQgQ2xhc3NBLmRvQShDbGFzc0EuamF2YTowKVxuIgorICAgICAgICAgICAgICAgICsgIkNhdXNlZCBieTogamF2YS5sYW5nLlRocm93YWJsZTogQ2F1c2VcbiIKKyAgICAgICAgICAgICAgICArICJcdGF0IENsYXNzRC5kb0QoQ2xhc3NELmphdmE6MylcbiIKKyAgICAgICAgICAgICAgICArICJcdGF0IENsYXNzQy5kb0MoQ2xhc3NDLmphdmE6MilcbiIKKyAgICAgICAgICAgICAgICArICJcdC4uLiAyIG1vcmVcbiIsIHByaW50U3RhY2tUcmFjZVRvU3RyaW5nKHRocm93YWJsZSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQcmludFN0YWNrVHJhY2VXaXRoQ2F1c2VBbmRTdXBwcmVzc2VkKCkgeworICAgICAgICBUaHJvd2FibGUgdGhyb3dhYmxlID0gbmV3VGhyb3dhYmxlKCJUaHJvd2FibGUiLCAiQSIsICJCIik7CisgICAgICAgIHRocm93YWJsZS5pbml0Q2F1c2UobmV3VGhyb3dhYmxlKCJDYXVzZSIsICJBIiwgIkIiLCAiQyIsICJEIikpOworICAgICAgICB0aHJvd2FibGUuYWRkU3VwcHJlc3NlZChuZXdUaHJvd2FibGUoIlN1cHByZXNzZWQiLCAiQSIsICJCIiwgIkUiLCAiRiIpKTsKKyAgICAgICAgdGhyb3dhYmxlLmFkZFN1cHByZXNzZWQobmV3VGhyb3dhYmxlKCJTdXBwcmVzc2VkIiwgIkEiLCAiQiIsICJHIiwgIkgiKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJqYXZhLmxhbmcuVGhyb3dhYmxlOiBUaHJvd2FibGVcbiIKKyAgICAgICAgICAgICAgICArICJcdGF0IENsYXNzQi5kb0IoQ2xhc3NCLmphdmE6MSlcbiIKKyAgICAgICAgICAgICAgICArICJcdGF0IENsYXNzQS5kb0EoQ2xhc3NBLmphdmE6MClcbiIKKyAgICAgICAgICAgICAgICArICJcdFN1cHByZXNzZWQ6IGphdmEubGFuZy5UaHJvd2FibGU6IFN1cHByZXNzZWRcbiIKKyAgICAgICAgICAgICAgICArICJcdFx0YXQgQ2xhc3NGLmRvRihDbGFzc0YuamF2YTozKVxuIgorICAgICAgICAgICAgICAgICsgIlx0XHRhdCBDbGFzc0UuZG9FKENsYXNzRS5qYXZhOjIpXG4iCisgICAgICAgICAgICAgICAgKyAiXHRcdC4uLiAyIG1vcmVcbiIKKyAgICAgICAgICAgICAgICArICJcdFN1cHByZXNzZWQ6IGphdmEubGFuZy5UaHJvd2FibGU6IFN1cHByZXNzZWRcbiIKKyAgICAgICAgICAgICAgICArICJcdFx0YXQgQ2xhc3NILmRvSChDbGFzc0guamF2YTozKVxuIgorICAgICAgICAgICAgICAgICsgIlx0XHRhdCBDbGFzc0cuZG9HKENsYXNzRy5qYXZhOjIpXG4iCisgICAgICAgICAgICAgICAgKyAiXHRcdC4uLiAyIG1vcmVcbiIKKyAgICAgICAgICAgICAgICArICJDYXVzZWQgYnk6IGphdmEubGFuZy5UaHJvd2FibGU6IENhdXNlXG4iCisgICAgICAgICAgICAgICAgKyAiXHRhdCBDbGFzc0QuZG9EKENsYXNzRC5qYXZhOjMpXG4iCisgICAgICAgICAgICAgICAgKyAiXHRhdCBDbGFzc0MuZG9DKENsYXNzQy5qYXZhOjIpXG4iCisgICAgICAgICAgICAgICAgKyAiXHQuLi4gMiBtb3JlXG4iLCBwcmludFN0YWNrVHJhY2VUb1N0cmluZyh0aHJvd2FibGUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJpbnRTdGFja1RyYWNlV2l0aEV2ZXJ5dGhpbmcoKSB7CisgICAgICAgIFRocm93YWJsZSB0aHJvd2FibGUgPSBuZXdUaHJvd2FibGUoIlRocm93YWJsZSIsICJBIiwgIkIiKTsKKyAgICAgICAgVGhyb3dhYmxlIGNhdXNlID0gbmV3VGhyb3dhYmxlKCJDYXVzZSIsICJBIiwgIkIiLCAiQyIsICJEIik7CisgICAgICAgIFRocm93YWJsZSBzdXBwcmVzc2VkID0gbmV3VGhyb3dhYmxlKCJTdXBwcmVzc2VkIiwgIkEiLCAiQiIsICJFIiwgIkYiKTsKKworICAgICAgICB0aHJvd2FibGUuYWRkU3VwcHJlc3NlZChzdXBwcmVzc2VkKTsKKyAgICAgICAgc3VwcHJlc3NlZC5hZGRTdXBwcmVzc2VkKG5ld1Rocm93YWJsZSgiU3VwcHJlc3NlZC9TdXBwcmVzc2VkIiwgIkEiLCAiQiIsICJFIiwgIkciKSk7CisgICAgICAgIHN1cHByZXNzZWQuaW5pdENhdXNlKG5ld1Rocm93YWJsZSgiU3VwcHJlc3NlZC9DYXVzZSIsICJBIiwgIkIiLCAiRSIsICJIIikpOworCisgICAgICAgIHRocm93YWJsZS5pbml0Q2F1c2UoY2F1c2UpOworICAgICAgICBjYXVzZS5hZGRTdXBwcmVzc2VkKG5ld1Rocm93YWJsZSgiQ2F1c2UvU3VwcHJlc3NlZCIsICJBIiwgIkIiLCAiQyIsICJJIikpOworICAgICAgICBjYXVzZS5pbml0Q2F1c2UobmV3VGhyb3dhYmxlKCJDYXVzZS9DYXVzZSIsICJBIiwgIkIiLCAiQyIsICJKIikpOworCisgICAgICAgIGFzc2VydEVxdWFscygiamF2YS5sYW5nLlRocm93YWJsZTogVGhyb3dhYmxlXG4iCisgICAgICAgICAgICAgICAgKyAiXHRhdCBDbGFzc0IuZG9CKENsYXNzQi5qYXZhOjEpXG4iCisgICAgICAgICAgICAgICAgKyAiXHRhdCBDbGFzc0EuZG9BKENsYXNzQS5qYXZhOjApXG4iCisgICAgICAgICAgICAgICAgKyAiXHRTdXBwcmVzc2VkOiBqYXZhLmxhbmcuVGhyb3dhYmxlOiBTdXBwcmVzc2VkXG4iCisgICAgICAgICAgICAgICAgKyAiXHRcdGF0IENsYXNzRi5kb0YoQ2xhc3NGLmphdmE6MylcbiIKKyAgICAgICAgICAgICAgICArICJcdFx0YXQgQ2xhc3NFLmRvRShDbGFzc0UuamF2YToyKVxuIgorICAgICAgICAgICAgICAgICsgIlx0XHQuLi4gMiBtb3JlXG4iCisgICAgICAgICAgICAgICAgKyAiXHRcdFN1cHByZXNzZWQ6IGphdmEubGFuZy5UaHJvd2FibGU6IFN1cHByZXNzZWQvU3VwcHJlc3NlZFxuIgorICAgICAgICAgICAgICAgICsgIlx0XHRcdGF0IENsYXNzRy5kb0coQ2xhc3NHLmphdmE6MylcbiIKKyAgICAgICAgICAgICAgICArICJcdFx0XHQuLi4gMyBtb3JlXG4iCisgICAgICAgICAgICAgICAgKyAiXHRDYXVzZWQgYnk6IGphdmEubGFuZy5UaHJvd2FibGU6IFN1cHByZXNzZWQvQ2F1c2VcbiIKKyAgICAgICAgICAgICAgICArICJcdFx0YXQgQ2xhc3NILmRvSChDbGFzc0guamF2YTozKVxuIgorICAgICAgICAgICAgICAgICsgIlx0XHQuLi4gMyBtb3JlXG4iCisgICAgICAgICAgICAgICAgKyAiQ2F1c2VkIGJ5OiBqYXZhLmxhbmcuVGhyb3dhYmxlOiBDYXVzZVxuIgorICAgICAgICAgICAgICAgICsgIlx0YXQgQ2xhc3NELmRvRChDbGFzc0QuamF2YTozKVxuIgorICAgICAgICAgICAgICAgICsgIlx0YXQgQ2xhc3NDLmRvQyhDbGFzc0MuamF2YToyKVxuIgorICAgICAgICAgICAgICAgICsgIlx0Li4uIDIgbW9yZVxuIgorICAgICAgICAgICAgICAgICsgIlx0U3VwcHJlc3NlZDogamF2YS5sYW5nLlRocm93YWJsZTogQ2F1c2UvU3VwcHJlc3NlZFxuIgorICAgICAgICAgICAgICAgICsgIlx0XHRhdCBDbGFzc0kuZG9JKENsYXNzSS5qYXZhOjMpXG4iCisgICAgICAgICAgICAgICAgKyAiXHRcdC4uLiAzIG1vcmVcbiIKKyAgICAgICAgICAgICAgICArICJDYXVzZWQgYnk6IGphdmEubGFuZy5UaHJvd2FibGU6IENhdXNlL0NhdXNlXG4iCisgICAgICAgICAgICAgICAgKyAiXHRhdCBDbGFzc0ouZG9KKENsYXNzSi5qYXZhOjMpXG4iCisgICAgICAgICAgICAgICAgKyAiXHQuLi4gMyBtb3JlXG4iLCBwcmludFN0YWNrVHJhY2VUb1N0cmluZyh0aHJvd2FibGUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0U3RhY2tUcmFjZVdpdGhOdWxsRWxlbWVudCgpIHsKKyAgICAgICAgVGhyb3dhYmxlIHRocm93YWJsZSA9IG5ldyBUaHJvd2FibGUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRocm93YWJsZS5zZXRTdGFja1RyYWNlKG5ldyBTdGFja1RyYWNlRWxlbWVudFtdeyBudWxsIH0pOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENhdXNlU2VyaWFsaXphdGlvbigpIHsKKyAgICAgICAgU3RyaW5nIHMgPSAiYWNlZDAwMDU3MzcyMDAxMzZhNjE3NjYxMmU2YzYxNmU2NzJlNTQ2ODcyNmY3NzYxNjI2YzY1ZDVjNjM1MjczOTc3YjhjYjAzMDAwMzRjMCIKKyAgICAgICAgICAgICAgICArICIwMDU2MzYxNzU3MzY1NzQwMDE1NGM2YTYxNzY2MTJmNmM2MTZlNjcyZjU0Njg3MjZmNzc2MTYyNmM2NTNiNGMwMDBkNjQ2NTc0NjE2OTZjNCIKKyAgICAgICAgICAgICAgICArICJkNjU3MzczNjE2NzY1NzQwMDEyNGM2YTYxNzY2MTJmNmM2MTZlNjcyZjUzNzQ3MjY5NmU2NzNiNWIwMDBhNzM3NDYxNjM2YjU0NzI2MTYzNiIKKyAgICAgICAgICAgICAgICArICI1NzQwMDFlNWI0YzZhNjE3NjYxMmY2YzYxNmU2NzJmNTM3NDYxNjM2YjU0NzI2MTYzNjU0NTZjNjU2ZDY1NmU3NDNiNzg3MDczNzEwMDdlMCIKKyAgICAgICAgICAgICAgICArICIwMDA3MTAwN2UwMDA1NzQwMDA1NDM2MTc1NzM2NTc1NzIwMDFlNWI0YzZhNjE3NjYxMmU2YzYxNmU2NzJlNTM3NDYxNjM2YjU0NzI2MTYzNiIKKyAgICAgICAgICAgICAgICArICI1NDU2YzY1NmQ2NTZlNzQzYjAyNDYyYTNjM2NmZDIyMzkwMjAwMDA3ODcwMDAwMDAwMDQ3MzcyMDAxYjZhNjE3NjYxMmU2YzYxNmU2NzJlNSIKKyAgICAgICAgICAgICAgICArICIzNzQ2MTYzNmI1NDcyNjE2MzY1NDU2YzY1NmQ2NTZlNzQ2MTA5YzU5YTI2MzZkZDg1MDIwMDA0NDkwMDBhNmM2OTZlNjU0ZTc1NmQ2MjY1NyIKKyAgICAgICAgICAgICAgICArICIyNGMwMDBlNjQ2NTYzNmM2MTcyNjk2ZTY3NDM2YzYxNzM3MzcxMDA3ZTAwMDI0YzAwMDg2NjY5NmM2NTRlNjE2ZDY1NzEwMDdlMDAwMjRjMCIKKyAgICAgICAgICAgICAgICArICIwMGE2ZDY1NzQ2ODZmNjQ0ZTYxNmQ2NTcxMDA3ZTAwMDI3ODcwMDAwMDAwMDM3NDAwMDY0MzZjNjE3MzczNDQ3NDAwMGI0MzZjNjE3MzczNCIKKyAgICAgICAgICAgICAgICArICI0MmU2YTYxNzY2MTc0MDAwMzY0NmY0NDczNzEwMDdlMDAwOTAwMDAwMDAyNzQwMDA2NDM2YzYxNzM3MzQzNzQwMDBiNDM2YzYxNzM3MzQzMiIKKyAgICAgICAgICAgICAgICArICJlNmE2MTc2NjE3NDAwMDM2NDZmNDM3MzcxMDA3ZTAwMDkwMDAwMDAwMTc0MDAwNjQzNmM2MTczNzM0Mjc0MDAwYjQzNmM2MTczNzM0MjJlNiIKKyAgICAgICAgICAgICAgICArICJhNjE3NjYxNzQwMDAzNjQ2ZjQyNzM3MTAwN2UwMDA5MDAwMDAwMDA3NDAwMDY0MzZjNjE3MzczNDE3NDAwMGI0MzZjNjE3MzczNDEyZTZhNiIKKyAgICAgICAgICAgICAgICArICIxNzY2MTc0MDAwMzY0NmY0MTc4NzQwMDA5NTQ2ODcyNmY3NzYxNjI2YzY1NzU3MTAwN2UwMDA3MDAwMDAwMDI3MzcxMDA3ZTAwMDkwMDAwMCIKKyAgICAgICAgICAgICAgICArICIwMDE3NDAwMDY0MzZjNjE3MzczNDI3NDAwMGI0MzZjNjE3MzczNDIyZTZhNjE3NjYxNzQwMDAzNjQ2ZjQyNzM3MTAwN2UwMDA5MDAwMDAwMCIKKyAgICAgICAgICAgICAgICArICIwNzQwMDA2NDM2YzYxNzM3MzQxNzQwMDBiNDM2YzYxNzM3MzQxMmU2YTYxNzY2MTc0MDAwMzY0NmY0MTc4IjsKKyAgICAgICAgVGhyb3dhYmxlIHRocm93YWJsZSA9IG5ld1Rocm93YWJsZSgiVGhyb3dhYmxlIiwgIkEiLCAiQiIpOworICAgICAgICB0aHJvd2FibGUuaW5pdENhdXNlKG5ld1Rocm93YWJsZSgiQ2F1c2UiLCAiQSIsICJCIiwgIkMiLCAiRCIpKTsKKyAgICAgICAgYXNzZXJ0U2VyaWFsaXplZCh0aHJvd2FibGUsIHMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdXBwcmVzc2VkU2VyaWFsaXphdGlvbigpIHsKKyAgICAgICAgU3RyaW5nIHMgPSAiYWNlZDAwMDU3MzcyMDAxMzZhNjE3NjYxMmU2YzYxNmU2NzJlNTQ2ODcyNmY3NzYxNjI2YzY1ZDVjNjM1MjczOTc3YjhjYjAzMDAwNDRjMCIKKyAgICAgICAgICAgICAgICArICIwMDU2MzYxNzU3MzY1NzQwMDE1NGM2YTYxNzY2MTJmNmM2MTZlNjcyZjU0Njg3MjZmNzc2MTYyNmM2NTNiNGMwMDBkNjQ2NTc0NjE2OTZjNCIKKyAgICAgICAgICAgICAgICArICJkNjU3MzczNjE2NzY1NzQwMDEyNGM2YTYxNzY2MTJmNmM2MTZlNjcyZjUzNzQ3MjY5NmU2NzNiNWIwMDBhNzM3NDYxNjM2YjU0NzI2MTYzNiIKKyAgICAgICAgICAgICAgICArICI1NzQwMDFlNWI0YzZhNjE3NjYxMmY2YzYxNmU2NzJmNTM3NDYxNjM2YjU0NzI2MTYzNjU0NTZjNjU2ZDY1NmU3NDNiNGMwMDE0NzM3NTcwNyIKKyAgICAgICAgICAgICAgICArICIwNzI2NTczNzM2NTY0NDU3ODYzNjU3MDc0Njk2ZjZlNzM3NDAwMTA0YzZhNjE3NjYxMmY3NTc0Njk2YzJmNGM2OTczNzQzYjc4NzA3MTAwNyIKKyAgICAgICAgICAgICAgICArICJlMDAwNTc0MDAwYTUzNjU3MjY5NjE2YzY5N2E2NTY0NzU3MjAwMWU1YjRjNmE2MTc2NjEyZTZjNjE2ZTY3MmU1Mzc0NjE2MzZiNTQ3MjYxNiIKKyAgICAgICAgICAgICAgICArICIzNjU0NTZjNjU2ZDY1NmU3NDNiMDI0NjJhM2MzY2ZkMjIzOTAyMDAwMDc4NzAwMDAwMDAwMjczNzIwMDFiNmE2MTc2NjEyZTZjNjE2ZTY3MiIKKyAgICAgICAgICAgICAgICArICJlNTM3NDYxNjM2YjU0NzI2MTYzNjU0NTZjNjU2ZDY1NmU3NDYxMDljNTlhMjYzNmRkODUwMjAwMDQ0OTAwMGE2YzY5NmU2NTRlNzU2ZDYyNiIKKyAgICAgICAgICAgICAgICArICI1NzI0YzAwMGU2NDY1NjM2YzYxNzI2OTZlNjc0MzZjNjE3MzczNzEwMDdlMDAwMjRjMDAwODY2Njk2YzY1NGU2MTZkNjU3MTAwN2UwMDAyNCIKKyAgICAgICAgICAgICAgICArICJjMDAwYTZkNjU3NDY4NmY2NDRlNjE2ZDY1NzEwMDdlMDAwMjc4NzAwMDAwMDAwMTc0MDAwNjQzNmM2MTczNzM0Mjc0MDAwYjQzNmM2MTczNyIKKyAgICAgICAgICAgICAgICArICIzNDIyZTZhNjE3NjYxNzQwMDAzNjQ2ZjQyNzM3MTAwN2UwMDA5MDAwMDAwMDA3NDAwMDY0MzZjNjE3MzczNDE3NDAwMGI0MzZjNjE3MzczNCIKKyAgICAgICAgICAgICAgICArICIxMmU2YTYxNzY2MTc0MDAwMzY0NmY0MTczNzIwMDEzNmE2MTc2NjEyZTc1NzQ2OTZjMmU0MTcyNzI2MTc5NGM2OTczNzQ3ODgxZDIxZDk5YyIKKyAgICAgICAgICAgICAgICArICI3NjE5ZDAzMDAwMTQ5MDAwNDczNjk3YTY1Nzg3MDAwMDAwMDAxNzcwNDAwMDAwMDAxNzM3MTAwN2UwMDAwNzEwMDdlMDAxNDc0MDAwYTUzNyIKKyAgICAgICAgICAgICAgICArICI1NzA3MDcyNjU3MzczNjU2NDc1NzEwMDdlMDAwNzAwMDAwMDA0NzM3MTAwN2UwMDA5MDAwMDAwMDM3NDAwMDY0MzZjNjE3MzczNDQ3NDAwMCIKKyAgICAgICAgICAgICAgICArICJiNDM2YzYxNzM3MzQ0MmU2YTYxNzY2MTc0MDAwMzY0NmY0NDczNzEwMDdlMDAwOTAwMDAwMDAyNzQwMDA2NDM2YzYxNzM3MzQzNzQwMDBiNCIKKyAgICAgICAgICAgICAgICArICIzNmM2MTczNzM0MzJlNmE2MTc2NjE3NDAwMDM2NDZmNDM3MzcxMDA3ZTAwMDkwMDAwMDAwMTc0MDAwNjQzNmM2MTczNzM0Mjc0MDAwYjQzNiIKKyAgICAgICAgICAgICAgICArICJjNjE3MzczNDIyZTZhNjE3NjYxNzQwMDAzNjQ2ZjQyNzM3MTAwN2UwMDA5MDAwMDAwMDA3NDAwMDY0MzZjNjE3MzczNDE3NDAwMGI0MzZjNiIKKyAgICAgICAgICAgICAgICArICIxNzM3MzQxMmU2YTYxNzY2MTc0MDAwMzY0NmY0MTczNzIwMDI2NmE2MTc2NjEyZTc1NzQ2OTZjMmU0MzZmNmM2YzY1NjM3NDY5NmY2ZTczMiIKKyAgICAgICAgICAgICAgICArICI0NTU2ZTZkNmY2NDY5NjY2OTYxNjI2YzY1NGM2OTczNzRmYzBmMjUzMWI1ZWM4ZTEwMDIwMDAxNGMwMDA0NmM2OTczNzQ3MTAwN2UwMDA0NyIKKyAgICAgICAgICAgICAgICArICI4NzIwMDJjNmE2MTc2NjEyZTc1NzQ2OTZjMmU0MzZmNmM2YzY1NjM3NDY5NmY2ZTczMjQ1NTZlNmQ2ZjY0Njk2NjY5NjE2MjZjNjU0MzZmNiIKKyAgICAgICAgICAgICAgICArICJjNmM2NTYzNzQ2OTZmNmUxOTQyMDA4MGNiNWVmNzFlMDIwMDAxNGMwMDAxNjM3NDAwMTY0YzZhNjE3NjYxMmY3NTc0Njk2YzJmNDM2ZjZjNiIKKyAgICAgICAgICAgICAgICArICJjNjU2Mzc0Njk2ZjZlM2I3ODcwNzM3MTAwN2UwMDEyMDAwMDAwMDA3NzA0MDAwMDAwMDA3ODcxMDA3ZTAwMmI3ODc4NzgiOworICAgICAgICBUaHJvd2FibGUgdGhyb3dhYmxlID0gbmV3VGhyb3dhYmxlKCJTZXJpYWxpemVkIiwgIkEiLCAiQiIpOworICAgICAgICB0aHJvd2FibGUuYWRkU3VwcHJlc3NlZChuZXdUaHJvd2FibGUoIlN1cHByZXNzZWQiLCAiQSIsICJCIiwgIkMiLCAiRCIpKTsKKyAgICAgICAgYXNzZXJ0U2VyaWFsaXplZCh0aHJvd2FibGUsIHMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REaXNhYmxlU3VwcHJlc3Npb25TZXJpYWxpemF0aW9uKCkgeworICAgICAgICBTdHJpbmcgcyA9ICJhY2VkMDAwNTczNzIwMDM1NmM2OTYyNjM2ZjcyNjUyZTZhNjE3NjYxMmU2YzYxNmU2NzJlNTQ2ODcyNmY3NzYxNjI2YzY1NTQ2NTczNzQyIgorICAgICAgICAgICAgICAgICsgIjQ1Mzc1NzA3MDcyNjU3MzczNjk2ZjZlNzM1NDY4NzI2Zjc3NjE2MjZjNjUwMmNmZjQzYjUzOTBkMTM3MDIwMDAwNzg3MjAwMTM2YTYxNzY2IgorICAgICAgICAgICAgICAgICsgIjEyZTZjNjE2ZTY3MmU1NDY4NzI2Zjc3NjE2MjZjNjVkNWM2MzUyNzM5NzdiOGNiMDMwMDA0NGMwMDA1NjM2MTc1NzM2NTc0MDAxNTRjNmE2IgorICAgICAgICAgICAgICAgICsgIjE3NjYxMmY2YzYxNmU2NzJmNTQ2ODcyNmY3NzYxNjI2YzY1M2I0YzAwMGQ2NDY1NzQ2MTY5NmM0ZDY1NzM3MzYxNjc2NTc0MDAxMjRjNmE2IgorICAgICAgICAgICAgICAgICsgIjE3NjYxMmY2YzYxNmU2NzJmNTM3NDcyNjk2ZTY3M2I1YjAwMGE3Mzc0NjE2MzZiNTQ3MjYxNjM2NTc0MDAxZTViNGM2YTYxNzY2MTJmNmM2IgorICAgICAgICAgICAgICAgICsgIjE2ZTY3MmY1Mzc0NjE2MzZiNTQ3MjYxNjM2NTQ1NmM2NTZkNjU2ZTc0M2I0YzAwMTQ3Mzc1NzA3MDcyNjU3MzczNjU2NDQ1Nzg2MzY1NzA3IgorICAgICAgICAgICAgICAgICsgIjQ2OTZmNmU3Mzc0MDAxMDRjNmE2MTc2NjEyZjc1NzQ2OTZjMmY0YzY5NzM3NDNiNzg3MDcwNzQwMDAzNjY2ZjZmNzU3MjAwMWU1YjRjNmE2IgorICAgICAgICAgICAgICAgICsgIjE3NjYxMmU2YzYxNmU2NzJlNTM3NDYxNjM2YjU0NzI2MTYzNjU0NTZjNjU2ZDY1NmU3NDNiMDI0NjJhM2MzY2ZkMjIzOTAyMDAwMDc4NzAwIgorICAgICAgICAgICAgICAgICsgIjAwMDAwMDA3MDc4IjsKKyAgICAgICAgVGhyb3dhYmxlIHRocm93YWJsZSA9IG5ldyBTdXBwcmVzc2lvbnNUaHJvd2FibGUoImZvbyIsIG51bGwsIGZhbHNlKTsKKyAgICAgICAgdGhyb3dhYmxlLnNldFN0YWNrVHJhY2UobmV3IFN0YWNrVHJhY2VFbGVtZW50WzBdKTsKKyAgICAgICAgbmV3IFNlcmlhbGl6YWJsZVRlc3RlcjxUaHJvd2FibGU+KHRocm93YWJsZSwgcykgeworICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBib29sZWFuIGVxdWFscyhUaHJvd2FibGUgYSwgVGhyb3dhYmxlIGIpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcHJpbnRTdGFja1RyYWNlVG9TdHJpbmcoYSkuZXF1YWxzKHByaW50U3RhY2tUcmFjZVRvU3RyaW5nKGIpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCB2ZXJpZnkoVGhyb3dhYmxlIGRlc2VyaWFsaXplZCkgeworICAgICAgICAgICAgICAgIC8vIHRoZSBzdXBwcmVzc2VkIGV4Y2VwdGlvbiBpcyBzaWxlbnRseSBkaXNjYXJkZWQKKyAgICAgICAgICAgICAgICBkZXNlcmlhbGl6ZWQuYWRkU3VwcHJlc3NlZChuZXdUaHJvd2FibGUoIlN1cHByZXNzZWQiKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0U3VwcHJlc3NlZChkZXNlcmlhbGl6ZWQpOworICAgICAgICAgICAgfQorICAgICAgICB9LnRlc3QoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5hYmxlU3VwcHJlc3Npb25TZXJpYWxpemF0aW9uKCkgeworICAgICAgICBTdHJpbmcgcyA9ICJhY2VkMDAwNTczNzIwMDM1NmM2OTYyNjM2ZjcyNjUyZTZhNjE3NjYxMmU2YzYxNmU2NzJlNTQ2ODcyNmY3NzYxNjI2YzY1NTQ2NTczNzQyIgorICAgICAgICAgICAgICAgICsgIjQ1Mzc1NzA3MDcyNjU3MzczNjk2ZjZlNzM1NDY4NzI2Zjc3NjE2MjZjNjUwMmNmZjQzYjUzOTBkMTM3MDIwMDAwNzg3MjAwMTM2YTYxNzY2IgorICAgICAgICAgICAgICAgICsgIjEyZTZjNjE2ZTY3MmU1NDY4NzI2Zjc3NjE2MjZjNjVkNWM2MzUyNzM5NzdiOGNiMDMwMDA0NGMwMDA1NjM2MTc1NzM2NTc0MDAxNTRjNmE2IgorICAgICAgICAgICAgICAgICsgIjE3NjYxMmY2YzYxNmU2NzJmNTQ2ODcyNmY3NzYxNjI2YzY1M2I0YzAwMGQ2NDY1NzQ2MTY5NmM0ZDY1NzM3MzYxNjc2NTc0MDAxMjRjNmE2IgorICAgICAgICAgICAgICAgICsgIjE3NjYxMmY2YzYxNmU2NzJmNTM3NDcyNjk2ZTY3M2I1YjAwMGE3Mzc0NjE2MzZiNTQ3MjYxNjM2NTc0MDAxZTViNGM2YTYxNzY2MTJmNmM2IgorICAgICAgICAgICAgICAgICsgIjE2ZTY3MmY1Mzc0NjE2MzZiNTQ3MjYxNjM2NTQ1NmM2NTZkNjU2ZTc0M2I0YzAwMTQ3Mzc1NzA3MDcyNjU3MzczNjU2NDQ1Nzg2MzY1NzA3IgorICAgICAgICAgICAgICAgICsgIjQ2OTZmNmU3Mzc0MDAxMDRjNmE2MTc2NjEyZjc1NzQ2OTZjMmY0YzY5NzM3NDNiNzg3MDcwNzQwMDAzNjY2ZjZmNzU3MjAwMWU1YjRjNmE2IgorICAgICAgICAgICAgICAgICsgIjE3NjYxMmU2YzYxNmU2NzJlNTM3NDYxNjM2YjU0NzI2MTYzNjU0NTZjNjU2ZDY1NmU3NDNiMDI0NjJhM2MzY2ZkMjIzOTAyMDAwMDc4NzAwIgorICAgICAgICAgICAgICAgICsgIjAwMDAwMDA3MzcyMDAyNjZhNjE3NjYxMmU3NTc0Njk2YzJlNDM2ZjZjNmM2NTYzNzQ2OTZmNmU3MzI0NTU2ZTZkNmY2NDY5NjY2OTYxNjI2IgorICAgICAgICAgICAgICAgICsgImM2NTRjNjk3Mzc0ZmMwZjI1MzFiNWVjOGUxMDAyMDAwMTRjMDAwNDZjNjk3Mzc0NzEwMDdlMDAwNTc4NzIwMDJjNmE2MTc2NjEyZTc1NzQ2IgorICAgICAgICAgICAgICAgICsgIjk2YzJlNDM2ZjZjNmM2NTYzNzQ2OTZmNmU3MzI0NTU2ZTZkNmY2NDY5NjY2OTYxNjI2YzY1NDM2ZjZjNmM2NTYzNzQ2OTZmNmUxOTQyMDA4IgorICAgICAgICAgICAgICAgICsgIjBjYjVlZjcxZTAyMDAwMTRjMDAwMTYzNzQwMDE2NGM2YTYxNzY2MTJmNzU3NDY5NmMyZjQzNmY2YzZjNjU2Mzc0Njk2ZjZlM2I3ODcwNzM3IgorICAgICAgICAgICAgICAgICsgIjIwMDEzNmE2MTc2NjEyZTc1NzQ2OTZjMmU0MTcyNzI2MTc5NGM2OTczNzQ3ODgxZDIxZDk5Yzc2MTlkMDMwMDAxNDkwMDA0NzM2OTdhNjU3IgorICAgICAgICAgICAgICAgICsgIjg3MDAwMDAwMDAwNzcwNDAwMDAwMDAwNzg3MTAwN2UwMDBmNzgiOworICAgICAgICBUaHJvd2FibGUgdGhyb3dhYmxlID0gbmV3IFN1cHByZXNzaW9uc1Rocm93YWJsZSgiZm9vIiwgbnVsbCwgdHJ1ZSk7CisgICAgICAgIHRocm93YWJsZS5zZXRTdGFja1RyYWNlKG5ldyBTdGFja1RyYWNlRWxlbWVudFswXSk7CisgICAgICAgIG5ldyBTZXJpYWxpemFibGVUZXN0ZXI8VGhyb3dhYmxlPih0aHJvd2FibGUsIHMpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgYm9vbGVhbiBlcXVhbHMoVGhyb3dhYmxlIGEsIFRocm93YWJsZSBiKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHByaW50U3RhY2tUcmFjZVRvU3RyaW5nKGEpLmVxdWFscyhwcmludFN0YWNrVHJhY2VUb1N0cmluZyhiKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgdmVyaWZ5KFRocm93YWJsZSBkZXNlcmlhbGl6ZWQpIHsKKyAgICAgICAgICAgICAgICAvLyB0aGUgc3VwcHJlc3NlZCBleGNlcHRpb24gaXMgcGVybWl0dGVkCisgICAgICAgICAgICAgICAgVGhyb3dhYmxlIHN1cHByZXNzZWQgPSBuZXdUaHJvd2FibGUoIlN1cHByZXNzZWQiKTsKKyAgICAgICAgICAgICAgICBkZXNlcmlhbGl6ZWQuYWRkU3VwcHJlc3NlZChzdXBwcmVzc2VkKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRTdXBwcmVzc2VkKGRlc2VyaWFsaXplZCwgc3VwcHJlc3NlZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0udGVzdCgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRTZXJpYWxpemVkKGZpbmFsIFRocm93YWJsZSB0aHJvd2FibGUsIFN0cmluZyBnb2xkZW4pIHsKKyAgICAgICAgbmV3IFNlcmlhbGl6YWJsZVRlc3RlcjxUaHJvd2FibGU+KHRocm93YWJsZSwgZ29sZGVuKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIGJvb2xlYW4gZXF1YWxzKFRocm93YWJsZSBhLCBUaHJvd2FibGUgYikgeworICAgICAgICAgICAgICAgIHJldHVybiBwcmludFN0YWNrVHJhY2VUb1N0cmluZyhhKS5lcXVhbHMocHJpbnRTdGFja1RyYWNlVG9TdHJpbmcoYikpOworICAgICAgICAgICAgfQorICAgICAgICB9LnRlc3QoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFRocm93YWJsZSBuZXdUaHJvd2FibGUoU3RyaW5nIG1lc3NhZ2UsIFN0cmluZy4uLiBzdGFja1RyYWNlRWxlbWVudHMpIHsKKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnRbXSBhcnJheSA9IG5ldyBTdGFja1RyYWNlRWxlbWVudFtzdGFja1RyYWNlRWxlbWVudHMubGVuZ3RoXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdGFja1RyYWNlRWxlbWVudHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFN0cmluZyBzID0gc3RhY2tUcmFjZUVsZW1lbnRzW2ldOworICAgICAgICAgICAgYXJyYXlbc3RhY2tUcmFjZUVsZW1lbnRzLmxlbmd0aCAtIDEgLSBpXQorICAgICAgICAgICAgICAgICAgICA9IG5ldyBTdGFja1RyYWNlRWxlbWVudCgiQ2xhc3MiICsgcywgImRvIiArIHMsICJDbGFzcyIgKyBzICsgIi5qYXZhIiwgaSk7CisgICAgICAgIH0KKyAgICAgICAgVGhyb3dhYmxlIHJlc3VsdCA9IG5ldyBUaHJvd2FibGUobWVzc2FnZSk7CisgICAgICAgIHJlc3VsdC5zZXRTdGFja1RyYWNlKGFycmF5KTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyBwcmludFN0YWNrVHJhY2VUb1N0cmluZyhUaHJvd2FibGUgdGhyb3dhYmxlKSB7CisgICAgICAgIFN0cmluZ1dyaXRlciB3cml0ZXIgPSBuZXcgU3RyaW5nV3JpdGVyKCk7CisgICAgICAgIHRocm93YWJsZS5wcmludFN0YWNrVHJhY2UobmV3IFByaW50V3JpdGVyKHdyaXRlcikpOworICAgICAgICByZXR1cm4gd3JpdGVyLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydFN1cHByZXNzZWQoVGhyb3dhYmxlIHRocm93YWJsZSwgVGhyb3dhYmxlLi4uIGV4cGVjdGVkU3VwcHJlc3NlZCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdCh0aHJvd2FibGUuZ2V0U3VwcHJlc3NlZCgpKSwgQXJyYXlzLmFzTGlzdChleHBlY3RlZFN1cHByZXNzZWQpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvYW5ub3RhdGlvbi9Bbm5vdGF0aW9uVHlwZU1pc21hdGNoRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL2Fubm90YXRpb24vQW5ub3RhdGlvblR5cGVNaXNtYXRjaEV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZTNlOTgyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL2Fubm90YXRpb24vQW5ub3RhdGlvblR5cGVNaXNtYXRjaEV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDQ2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZy5hbm5vdGF0aW9uOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5Ob3RTZXJpYWxpemFibGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvblR5cGVNaXNtYXRjaEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CisKK3B1YmxpYyBjbGFzcyBBbm5vdGF0aW9uVHlwZU1pc21hdGNoRXhjZXB0aW9uVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdEdldHRlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG0gPSBTdHJpbmcuY2xhc3MuZ2V0TWV0aG9kKCJsZW5ndGgiKTsKKyAgICAgICAgQW5ub3RhdGlvblR5cGVNaXNtYXRjaEV4Y2VwdGlvbiBleCA9IG5ldyBBbm5vdGF0aW9uVHlwZU1pc21hdGNoRXhjZXB0aW9uKG0sICJwb29wIik7CisgICAgICAgIGFzc2VydFNhbWUobSwgZXguZWxlbWVudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwb29wIiwgZXguZm91bmRUeXBlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZCBtID0gU3RyaW5nLmNsYXNzLmdldE1ldGhvZCgibGVuZ3RoIik7CisgICAgICAgIEFubm90YXRpb25UeXBlTWlzbWF0Y2hFeGNlcHRpb24gb3JpZ2luYWwgPSBuZXcgQW5ub3RhdGlvblR5cGVNaXNtYXRjaEV4Y2VwdGlvbihtLCAicG9vcCIpOworCisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBBbm5vdGF0aW9uVHlwZU1pc21hdGNoRXhjZXB0aW9uIGlzIGJyb2tlbjogaXQncyBTZXJpYWxpemFibGUgYnV0IGhhcyBhIG5vbi10cmFuc2llbnQKKyAgICAgICAgICAgIC8vIG5vbi1zZXJpYWxpemFibGUgZmllbGQgb2YgdHlwZSBNZXRob2QuCisgICAgICAgICAgICBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKG91dCkud3JpdGVPYmplY3Qob3JpZ2luYWwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOb3RTZXJpYWxpemFibGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWYvRmluYWxpemVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvcmVmL0ZpbmFsaXplVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2ZjkzMGMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvcmVmL0ZpbmFsaXplVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTQwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIEdvb2dsZSBJbmMuCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nLnJlZjsKKworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNvdW50RG93bkxhdGNoOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNCb29sZWFuOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNJbnRlZ2VyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIEZpbmFsaXplVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RGaW5hbGl6ZUlzQ2FsbGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEF0b21pY0Jvb2xlYW4gZmluYWxpemVkID0gbmV3IEF0b21pY0Jvb2xlYW4oKTsKKyAgICAgICAgY3JlYXRlRmluYWxpemFibGVPYmplY3QoZmluYWxpemVkKTsKKworICAgICAgICBpbmR1Y2VGaW5hbGl6YXRpb24oKTsKKyAgICAgICAgaWYgKCFmaW5hbGl6ZWQuZ2V0KCkpIHsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFByZXZlbnQgbGl2ZS1wcmVjaXNlIGJ1Z3MgZnJvbSBpbnRlcmZlcmluZyB3aXRoIGFuYWx5c2lzIG9mIHdoYXQgaXMKKyAgICAgKiByZWFjaGFibGUuIERvIG5vdCBpbmxpbmUgdGhpcyBtZXRob2Q7IG90aGVyd2lzZSB0ZXN0cyBtYXkgZmFpbCBvbiBWTXMKKyAgICAgKiB0aGF0IGFyZSBub3QgbGl2ZS1wcmVjaXNlLiBodHRwOi8vYi80MTkxMzQ1CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZUZpbmFsaXphYmxlT2JqZWN0KGZpbmFsIEF0b21pY0Jvb2xlYW4gZmluYWxpemVkKSB7CisgICAgICAgIG5ldyBYKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgICAgICAgICAgc3VwZXIuZmluYWxpemUoKTsKKyAgICAgICAgICAgICAgICBmaW5hbGl6ZWQuc2V0KHRydWUpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBYIHt9CisKKyAgICAvLyBodHRwOi8vYi9pc3N1ZT9pZD0yMTM2NDYyCisgICAgcHVibGljIHZvaWQgdGVzdEJhY2tGcm9tVGhlRGVhZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IENvbnN0cnVjdGlvbkZhaWxzKCk7CisgICAgICAgIH0gY2F0Y2ggKEFzc2VydGlvbkVycm9yIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBpbmR1Y2VGaW5hbGl6YXRpb24oKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgib2JqZWN0IHdob3NlIGNvbnN0cnVjdG9yIHRocmV3IHdhcyBub3QgZmluYWxpemVkIiwgQ29uc3RydWN0aW9uRmFpbHMuZmluYWxpemVkKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgaW5kdWNlRmluYWxpemF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN5c3RlbS5nYygpOworICAgICAgICBlbnF1ZXVlUmVmZXJlbmNlcygpOworICAgICAgICBTeXN0ZW0ucnVuRmluYWxpemF0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSGFjay4gV2UgZG9uJ3QgaGF2ZSBhIHByb2dyYW1tYXRpYyB3YXkgdG8gd2FpdCBmb3IgdGhlIHJlZmVyZW5jZSBxdWV1ZQorICAgICAqIGRhZW1vbiB0byBtb3ZlIHJlZmVyZW5jZXMgdG8gdGhlIGFwcHJvcHJpYXRlIHF1ZXVlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZW5xdWV1ZVJlZmVyZW5jZXMoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBUaHJlYWQuc2xlZXAoMTAwKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgQ29uc3RydWN0aW9uRmFpbHMgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGZpbmFsaXplZDsKKworICAgICAgICBDb25zdHJ1Y3Rpb25GYWlscygpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgICAgICBmaW5hbGl6ZWQgPSB0cnVlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGZpbmFsaXplciB3YXRjaCBkb2cgZXhpdHMgdGhlIFZNIGlmIGFueSBvYmplY3QgdGFrZXMgbW9yZSB0aGFuIDEwIHMKKyAgICAgKiB0byBmaW5hbGl6ZS4gQ2hlY2sgdGhhdCBvYmplY3RzIG5lYXIgdGhhdCBsaW1pdCBhcmUgb2theS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0V2F0Y2hkb2dEb2VzTm90RmFpbEZvck9iamVjdHNUaGF0QXJlTmVhclRoZURlYWRsaW5lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENvdW50RG93bkxhdGNoIGxhdGNoID0gbmV3IENvdW50RG93bkxhdGNoKDUpOworICAgICAgICBjcmVhdGVTbG93RmluYWxpemVyKCAgIDEsIGxhdGNoKTsKKyAgICAgICAgY3JlYXRlU2xvd0ZpbmFsaXplcigxMDAwLCBsYXRjaCk7CisgICAgICAgIGNyZWF0ZVNsb3dGaW5hbGl6ZXIoMjAwMCwgbGF0Y2gpOworICAgICAgICBjcmVhdGVTbG93RmluYWxpemVyKDQwMDAsIGxhdGNoKTsKKyAgICAgICAgY3JlYXRlU2xvd0ZpbmFsaXplcig4MDAwLCBsYXRjaCk7CisgICAgICAgIGluZHVjZUZpbmFsaXphdGlvbigpOworICAgICAgICBsYXRjaC5hd2FpdCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGNyZWF0ZVNsb3dGaW5hbGl6ZXIoZmluYWwgbG9uZyBtaWxsaXMsIGZpbmFsIENvdW50RG93bkxhdGNoIGxhdGNoKSB7CisgICAgICAgIG5ldyBPYmplY3QoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZpbmFsaXplIHNsZWVwaW5nICIgKyBtaWxsaXMgKyAiIG1zIik7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKG1pbGxpcyk7CisgICAgICAgICAgICAgICAgbGF0Y2guY291bnREb3duKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFrZSBzdXJlIHRoYXQgU3lzdGVtLnJ1bkZpbmFsaXphdGlvbigpIHJldHVybnMgZXZlbiBpZiB0aGUgZmluYWxpemF0aW9uCisgICAgICogcXVldWUgaXMgbmV2ZXIgY29tcGxldGVseSBlbXB0eS4gaHR0cDovL2IvNDE5MzUxNworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTeXN0ZW1SdW5GaW5hbGl6YXRpb25SZXR1cm5zRXZlbklmUXVldWVJc05vbkVtcHR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEF0b21pY0ludGVnZXIgY291bnQgPSBuZXcgQXRvbWljSW50ZWdlcigpOworICAgICAgICBBdG9taWNCb29sZWFuIGtlZXBHb2luZyA9IG5ldyBBdG9taWNCb29sZWFuKHRydWUpOworICAgICAgICBjcmVhdGVDaGFpbmVkRmluYWxpemVyKGNvdW50LCBrZWVwR29pbmcpOworICAgICAgICBpbmR1Y2VGaW5hbGl6YXRpb24oKTsKKyAgICAgICAga2VlcEdvaW5nLnNldChmYWxzZSk7CisgICAgICAgIGFzc2VydFRydWUoY291bnQuZ2V0KCkgPiAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjcmVhdGVDaGFpbmVkRmluYWxpemVyKGZpbmFsIEF0b21pY0ludGVnZXIgY291bnRlciwgZmluYWwgQXRvbWljQm9vbGVhbiBrZWVwR29pbmcpIHsKKyAgICAgICAgbmV3IE9iamVjdCgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICAgICAgICAgIGludCBjb3VudCA9IGNvdW50ZXIuaW5jcmVtZW50QW5kR2V0KCk7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGNvdW50KTsKKyAgICAgICAgICAgICAgICBpZiAoa2VlcEdvaW5nLmdldCgpKSB7CisgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUNoYWluZWRGaW5hbGl6ZXIoY291bnRlciwga2VlcEdvaW5nKTsgLy8gcmVjdXJzaXZlIQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBTeXN0ZW0uZ2MoKTsKKyAgICAgICAgICAgICAgICBlbnF1ZXVlUmVmZXJlbmNlcygpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWYvUmVmZXJlbmNlUXVldWVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvcmVmL1JlZmVyZW5jZVF1ZXVlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5ZTFhMWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvcmVmL1JlZmVyZW5jZVF1ZXVlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZy5yZWY7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmLlJlZmVyZW5jZVF1ZXVlOworaW1wb3J0IGphdmEubGFuZy5yZWYuV2Vha1JlZmVyZW5jZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5TY2hlZHVsZWRUaHJlYWRQb29sRXhlY3V0b3I7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQ7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgUmVmZXJlbmNlUXVldWVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZVdpdGhJbnZhbGlkVGltZW91dCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBSZWZlcmVuY2VRdWV1ZTxPYmplY3Q+IHJlZmVyZW5jZVF1ZXVlID0gbmV3IFJlZmVyZW5jZVF1ZXVlPE9iamVjdD4oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlZmVyZW5jZVF1ZXVlLnJlbW92ZSgtMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZVdpdGhWZXJ5TGFyZ2VUaW1lb3V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFJlZmVyZW5jZVF1ZXVlPE9iamVjdD4gcmVmZXJlbmNlUXVldWUgPSBuZXcgUmVmZXJlbmNlUXVldWU8T2JqZWN0PigpOworICAgICAgICBlbnF1ZXVlTGF0ZXIocmVmZXJlbmNlUXVldWUsIDUwMCk7CisgICAgICAgIHJlZmVyZW5jZVF1ZXVlLnJlbW92ZShMb25nLk1BWF9WQUxVRSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZVdpdGhTcHVyaW91c05vdGlmeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBSZWZlcmVuY2VRdWV1ZTxPYmplY3Q+IHJlZmVyZW5jZVF1ZXVlID0gbmV3IFJlZmVyZW5jZVF1ZXVlPE9iamVjdD4oKTsKKworICAgICAgICBydW5MYXRlcihuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAocmVmZXJlbmNlUXVldWUpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVmZXJlbmNlUXVldWUubm90aWZ5QWxsKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9LCA1MDApOworCisgICAgICAgIGxvbmcgc3RhcnROYW5vcyA9IFN5c3RlbS5uYW5vVGltZSgpOworICAgICAgICByZWZlcmVuY2VRdWV1ZS5yZW1vdmUoMTAwMCk7CisgICAgICAgIGxvbmcgZHVyYXRpb25OYW5vcyA9IFN5c3RlbS5uYW5vVGltZSgpIC0gc3RhcnROYW5vczsKKyAgICAgICAgbG9uZyBkdXJhdGlvbk1pbGxpcyA9IFRpbWVVbml0Lk5BTk9TRUNPTkRTLnRvTWlsbGlzKGR1cmF0aW9uTmFub3MpOworICAgICAgICBhc3NlcnRUcnVlKGR1cmF0aW9uTWlsbGlzID4gNzUwICYmIGR1cmF0aW9uTWlsbGlzIDwgMTI1MCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZVdpdGhJbW1lZGlhdGVSZXN1bHRBbmROb1RpbWVvdXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUmVmZXJlbmNlUXVldWU8T2JqZWN0PiByZWZlcmVuY2VRdWV1ZSA9IG5ldyBSZWZlcmVuY2VRdWV1ZTxPYmplY3Q+KCk7CisgICAgICAgIGVucXVldWUocmVmZXJlbmNlUXVldWUpOworICAgICAgICBhc3NlcnROb3ROdWxsKHJlZmVyZW5jZVF1ZXVlLnJlbW92ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlV2l0aEltbWVkaWF0ZVJlc3VsdEFuZFRpbWVvdXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUmVmZXJlbmNlUXVldWU8T2JqZWN0PiByZWZlcmVuY2VRdWV1ZSA9IG5ldyBSZWZlcmVuY2VRdWV1ZTxPYmplY3Q+KCk7CisgICAgICAgIGVucXVldWUocmVmZXJlbmNlUXVldWUpOworICAgICAgICBhc3NlcnROb3ROdWxsKHJlZmVyZW5jZVF1ZXVlLnJlbW92ZSgxMDAwKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZVdpdGhEZWxheWVkUmVzdWx0QW5kTm9UaW1lb3V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFJlZmVyZW5jZVF1ZXVlPE9iamVjdD4gcmVmZXJlbmNlUXVldWUgPSBuZXcgUmVmZXJlbmNlUXVldWU8T2JqZWN0PigpOworICAgICAgICBlbnF1ZXVlTGF0ZXIocmVmZXJlbmNlUXVldWUsIDUwMCk7CisgICAgICAgIGxvbmcgc3RhcnROYW5vcyA9IFN5c3RlbS5uYW5vVGltZSgpOworICAgICAgICByZWZlcmVuY2VRdWV1ZS5yZW1vdmUoKTsKKyAgICAgICAgbG9uZyBkdXJhdGlvbk5hbm9zID0gU3lzdGVtLm5hbm9UaW1lKCkgLSBzdGFydE5hbm9zOworICAgICAgICBsb25nIGR1cmF0aW9uTWlsbGlzID0gVGltZVVuaXQuTkFOT1NFQ09ORFMudG9NaWxsaXMoZHVyYXRpb25OYW5vcyk7CisgICAgICAgIGFzc2VydFRydWUoZHVyYXRpb25NaWxsaXMgPiAyNTAgJiYgZHVyYXRpb25NaWxsaXMgPCA3NTApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVXaXRoRGVsYXllZFJlc3VsdEFuZFRpbWVvdXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUmVmZXJlbmNlUXVldWU8T2JqZWN0PiByZWZlcmVuY2VRdWV1ZSA9IG5ldyBSZWZlcmVuY2VRdWV1ZTxPYmplY3Q+KCk7CisgICAgICAgIGVucXVldWVMYXRlcihyZWZlcmVuY2VRdWV1ZSwgNTAwKTsKKyAgICAgICAgbG9uZyBzdGFydE5hbm9zID0gU3lzdGVtLm5hbm9UaW1lKCk7CisgICAgICAgIHJlZmVyZW5jZVF1ZXVlLnJlbW92ZSgxMDAwKTsKKyAgICAgICAgbG9uZyBkdXJhdGlvbk5hbm9zID0gU3lzdGVtLm5hbm9UaW1lKCkgLSBzdGFydE5hbm9zOworICAgICAgICBsb25nIGR1cmF0aW9uTWlsbGlzID0gVGltZVVuaXQuTkFOT1NFQ09ORFMudG9NaWxsaXMoZHVyYXRpb25OYW5vcyk7CisgICAgICAgIGFzc2VydFRydWUoZHVyYXRpb25NaWxsaXMgPiAyNTAgJiYgZHVyYXRpb25NaWxsaXMgPCA3NTApOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBydW5MYXRlcihSdW5uYWJsZSBydW5uYWJsZSwgaW50IGRlbGF5TWlsbGlzKSB7CisgICAgICAgIFNjaGVkdWxlZFRocmVhZFBvb2xFeGVjdXRvciBleGVjdXRvciA9IG5ldyBTY2hlZHVsZWRUaHJlYWRQb29sRXhlY3V0b3IoMSk7CisgICAgICAgIGV4ZWN1dG9yLnNjaGVkdWxlKHJ1bm5hYmxlLCBkZWxheU1pbGxpcywgVGltZVVuaXQuTUlMTElTRUNPTkRTKTsKKyAgICAgICAgZXhlY3V0b3Iuc2h1dGRvd24oKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZW5xdWV1ZUxhdGVyKGZpbmFsIFJlZmVyZW5jZVF1ZXVlPE9iamVjdD4gcXVldWUsIGludCBkZWxheU1pbGxpcykgeworICAgICAgICBydW5MYXRlcihuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIGVucXVldWUocXVldWUpOworICAgICAgICAgICAgfQorICAgICAgICB9LCBkZWxheU1pbGxpcyk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGVucXVldWUoUmVmZXJlbmNlUXVldWU8T2JqZWN0PiBxdWV1ZSkgeworICAgICAgICBuZXcgV2Vha1JlZmVyZW5jZTxPYmplY3Q+KG5ldyBPYmplY3QoKSwgcXVldWUpLmVucXVldWUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvcmVmbGVjdC9Bbm5vdGF0aW9uc1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L0Fubm90YXRpb25zVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyMzc3NWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvcmVmbGVjdC9Bbm5vdGF0aW9uc1Rlc3QuamF2YQpAQCAtMCwwICsxLDEzNyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmcucmVmbGVjdDsKKworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uSW5oZXJpdGVkOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3k7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQW5ub3RhdGVkRWxlbWVudDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIEFubm90YXRpb25zVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RDbGFzc0RpcmVjdEFubm90YXRpb25zKCkgeworICAgICAgICBhc3NlcnRBbm5vdGF0ZWRFbGVtZW50KFR5cGUuY2xhc3MsIEFubm90YXRpb25BLmNsYXNzLCBBbm5vdGF0aW9uQi5jbGFzcyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENsYXNzSW5oZXJpdGVkQW5ub3RhdGlvbnMoKSB7CisgICAgICAgIGFzc2VydEFubm90YXRlZEVsZW1lbnQoRXh0ZW5kc1R5cGUuY2xhc3MsIEFubm90YXRpb25CLmNsYXNzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RydWN0b3JBbm5vdGF0aW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDb25zdHJ1Y3RvcjxUeXBlPiBjb25zdHJ1Y3RvciA9IFR5cGUuY2xhc3MuZ2V0Q29uc3RydWN0b3IoKTsKKyAgICAgICAgYXNzZXJ0QW5ub3RhdGVkRWxlbWVudChjb25zdHJ1Y3RvciwgQW5ub3RhdGlvbkEuY2xhc3MsIEFubm90YXRpb25DLmNsYXNzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmllbGRBbm5vdGF0aW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGaWVsZCBmaWVsZCA9IFR5cGUuY2xhc3MuZ2V0RmllbGQoImZpZWxkIik7CisgICAgICAgIGFzc2VydEFubm90YXRlZEVsZW1lbnQoZmllbGQsIEFubm90YXRpb25BLmNsYXNzLCBBbm5vdGF0aW9uRC5jbGFzcyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1ldGhvZEFubm90YXRpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBUeXBlLmNsYXNzLmdldE1ldGhvZCgibWV0aG9kIiwgU3RyaW5nLmNsYXNzLCBTdHJpbmcuY2xhc3MpOworICAgICAgICBhc3NlcnRBbm5vdGF0ZWRFbGVtZW50KG1ldGhvZCwgQW5ub3RhdGlvbkIuY2xhc3MsIEFubm90YXRpb25DLmNsYXNzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyYW1ldGVyQW5ub3RhdGlvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IFR5cGUuY2xhc3MuZ2V0TWV0aG9kKCJtZXRob2QiLCBTdHJpbmcuY2xhc3MsIFN0cmluZy5jbGFzcyk7CisgICAgICAgIEFubm90YXRpb25bXVtdIHBhcmFtZXRlckFubm90YXRpb25zID0gbWV0aG9kLmdldFBhcmFtZXRlckFubm90YXRpb25zKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBwYXJhbWV0ZXJBbm5vdGF0aW9ucy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoc2V0KEFubm90YXRpb25CLmNsYXNzLCBBbm5vdGF0aW9uRC5jbGFzcyksCisgICAgICAgICAgICAgICAgYW5ub3RhdGlvbnNUb1R5cGVzKHBhcmFtZXRlckFubm90YXRpb25zWzBdKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzZXQoQW5ub3RhdGlvbkMuY2xhc3MsIEFubm90YXRpb25ELmNsYXNzKSwKKyAgICAgICAgICAgICAgICBhbm5vdGF0aW9uc1RvVHlwZXMocGFyYW1ldGVyQW5ub3RhdGlvbnNbMV0pKTsKKyAgICB9CisKKyAgICBAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorICAgIHB1YmxpYyBAaW50ZXJmYWNlIEFubm90YXRpb25BIHt9CisKKyAgICBASW5oZXJpdGVkCisgICAgQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKKyAgICBwdWJsaWMgQGludGVyZmFjZSBBbm5vdGF0aW9uQiB7fQorCisgICAgQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKKyAgICBwdWJsaWMgQGludGVyZmFjZSBBbm5vdGF0aW9uQyB7fQorCisgICAgQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKKyAgICBwdWJsaWMgQGludGVyZmFjZSBBbm5vdGF0aW9uRCB7fQorCisgICAgQEFubm90YXRpb25BIEBBbm5vdGF0aW9uQgorICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgVHlwZSB7CisgICAgICAgIEBBbm5vdGF0aW9uQSBAQW5ub3RhdGlvbkMgcHVibGljIFR5cGUoKSB7fQorICAgICAgICBAQW5ub3RhdGlvbkEgQEFubm90YXRpb25EIHB1YmxpYyBTdHJpbmcgZmllbGQ7CisgICAgICAgIEBBbm5vdGF0aW9uQiBAQW5ub3RhdGlvbkMgcHVibGljIHZvaWQgbWV0aG9kKEBBbm5vdGF0aW9uQiBAQW5ub3RhdGlvbkQgU3RyaW5nIHBhcmFtZXRlcjEsCisgICAgICAgICAgICAgICAgQEFubm90YXRpb25DIEBBbm5vdGF0aW9uRCBTdHJpbmcgcGFyYW1ldGVyMikge30KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEV4dGVuZHNUeXBlIGV4dGVuZHMgVHlwZSB7fQorCisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0QW5ub3RhdGVkRWxlbWVudCgKKyAgICAgICAgICAgIEFubm90YXRlZEVsZW1lbnQgZWxlbWVudCwgQ2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+Li4uIGV4cGVjdGVkQW5ub3RhdGlvbnMpIHsKKyAgICAgICAgU2V0PENsYXNzPD8gZXh0ZW5kcyBBbm5vdGF0aW9uPj4gYWN0dWFsVHlwZXMgPSBhbm5vdGF0aW9uc1RvVHlwZXMoZWxlbWVudC5nZXRBbm5vdGF0aW9ucygpKTsKKyAgICAgICAgU2V0PENsYXNzPD8gZXh0ZW5kcyBBbm5vdGF0aW9uPj4gZXhwZWN0ZWRUeXBlcyA9IHNldChleHBlY3RlZEFubm90YXRpb25zKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkVHlwZXMsIGFjdHVhbFR5cGVzKTsKKworICAgICAgICAvLyBnZXRBbm5vdGF0aW9ucygpIHNob3VsZCBiZSBjb25zaXN0ZW50IHdpdGggaXNBbm5vdGF0aW9uUHJlc2VudCgpIGFuZCBnZXRBbm5vdGF0aW9uKCkKKyAgICAgICAgYXNzZXJ0UHJlc2VudChleHBlY3RlZFR5cGVzLmNvbnRhaW5zKEFubm90YXRpb25BLmNsYXNzKSwgZWxlbWVudCwgQW5ub3RhdGlvbkEuY2xhc3MpOworICAgICAgICBhc3NlcnRQcmVzZW50KGV4cGVjdGVkVHlwZXMuY29udGFpbnMoQW5ub3RhdGlvbkIuY2xhc3MpLCBlbGVtZW50LCBBbm5vdGF0aW9uQi5jbGFzcyk7CisgICAgICAgIGFzc2VydFByZXNlbnQoZXhwZWN0ZWRUeXBlcy5jb250YWlucyhBbm5vdGF0aW9uQy5jbGFzcyksIGVsZW1lbnQsIEFubm90YXRpb25DLmNsYXNzKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZWxlbWVudC5pc0Fubm90YXRpb25QcmVzZW50KG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVsZW1lbnQuZ2V0QW5ub3RhdGlvbihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgU2V0PENsYXNzPD8gZXh0ZW5kcyBBbm5vdGF0aW9uPj4gYW5ub3RhdGlvbnNUb1R5cGVzKEFubm90YXRpb25bXSBhbm5vdGF0aW9ucykgeworICAgICAgICBTZXQ8Q2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+PiByZXN1bHQgPSBuZXcgSGFzaFNldDxDbGFzczw/IGV4dGVuZHMgQW5ub3RhdGlvbj4+KCk7CisgICAgICAgIGZvciAoQW5ub3RhdGlvbiBhbm5vdGF0aW9uIDogYW5ub3RhdGlvbnMpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hZGQoYW5ub3RhdGlvbi5hbm5vdGF0aW9uVHlwZSgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRQcmVzZW50KGJvb2xlYW4gcHJlc2VudCwgQW5ub3RhdGVkRWxlbWVudCBlbGVtZW50LAorICAgICAgICAgICAgQ2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+IGFubm90YXRpb24pIHsKKyAgICAgICAgaWYgKHByZXNlbnQpIHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZWxlbWVudC5nZXRBbm5vdGF0aW9uKGFubm90YXRpb24pKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZWxlbWVudC5pc0Fubm90YXRpb25QcmVzZW50KGFubm90YXRpb24pKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFzc2VydE51bGwoZWxlbWVudC5nZXRBbm5vdGF0aW9uKGFubm90YXRpb24pKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGVsZW1lbnQuaXNBbm5vdGF0aW9uUHJlc2VudChhbm5vdGF0aW9uKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIDxUPiBTZXQ8VD4gc2V0KFQuLi4gaW5zdGFuY2VzKSB7CisgICAgICAgIHJldHVybiBuZXcgSGFzaFNldDxUPihBcnJheXMuYXNMaXN0KGluc3RhbmNlcykpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L0NsYXNzTG9hZGVyUmVmbGVjdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L0NsYXNzTG9hZGVyUmVmbGVjdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZTE1ZGUyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL3JlZmxlY3QvQ2xhc3NMb2FkZXJSZWZsZWN0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTYzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZy5yZWZsZWN0OworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuRmllbGQ7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlBhcmFtZXRlcml6ZWRUeXBlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVHlwZVZhcmlhYmxlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5DYWxsYWJsZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgdGVzdHMudXRpbC5DbGFzc0xvYWRlckJ1aWxkZXI7CisKKy8qKgorICogVGhpcyBjbGFzcyBjcmVhdGVzIGFub3RoZXIgY2xhc3MgbG9hZGVyIHRvIGxvYWQgbXVsdGlwbGUgY29waWVzIG9mIHZhcmlvdXMKKyAqIGNsYXNzZXMgaW50byB0aGUgVk0gYXQgb25jZS4gVGhlbiBpdCB2ZXJpZmllcyB0aGF0IHJlZmxlY3Rpb24gcmVzb2x2ZXMgdGhlCisgKiBjbGFzcyBuYW1lcyB1c2luZyB0aGUgY29ycmVjdCBjbGFzcyBsb2FkZXIuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBDbGFzc0xvYWRlclJlZmxlY3Rpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoKKyAgICAgKiBFYWNoIG9mIHRoZXNlIGNsYXNzIGluc3RhbmNlcyBwb2ludHMgdG8gYSBkaWZmZXJlbnQgY29weSBvZiB0aGUgY2xhc3MKKyAgICAgKiB0aGFuIHRoZSBvbmUgaW4gdGhlIGFwcGxpY2F0aW9uIGNsYXNzIGxvYWRlciEKKyAgICAgKi8KKyAgICBwcml2YXRlIENsYXNzPD8+IGFDbGFzczsKKyAgICBwcml2YXRlIENsYXNzPD8+IGFMaXN0Q2xhc3M7CisgICAgcHJpdmF0ZSBDbGFzczw/PiBiQ2xhc3M7CisgICAgcHJpdmF0ZSBDbGFzczw/PiBiU3RyaW5nQ2xhc3M7CisgICAgcHJpdmF0ZSBDbGFzczw/PiBjQ2xhc3M7CisgICAgcHJpdmF0ZSBDbGFzczw/PiBkQ2xhc3M7CisgICAgcHJpdmF0ZSBDbGFzczw/PiBlQ2xhc3M7CisgICAgcHJpdmF0ZSBDbGFzczw/PiBmQ2xhc3M7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHByZWZpeCA9IENsYXNzTG9hZGVyUmVmbGVjdGlvblRlc3QuY2xhc3MuZ2V0TmFtZSgpOworICAgICAgICBDbGFzc0xvYWRlciBsb2FkZXIgPSBuZXcgQ2xhc3NMb2FkZXJCdWlsZGVyKCkud2l0aFByaXZhdGVDb3B5KHByZWZpeCkuYnVpbGQoKTsKKyAgICAgICAgYUNsYXNzID0gbG9hZGVyLmxvYWRDbGFzcyhwcmVmaXggKyAiJEEiKTsKKyAgICAgICAgYkNsYXNzID0gbG9hZGVyLmxvYWRDbGFzcyhwcmVmaXggKyAiJEIiKTsKKyAgICAgICAgY0NsYXNzID0gbG9hZGVyLmxvYWRDbGFzcyhwcmVmaXggKyAiJEMiKTsKKyAgICAgICAgZENsYXNzID0gbG9hZGVyLmxvYWRDbGFzcyhwcmVmaXggKyAiJEQiKTsKKyAgICAgICAgZUNsYXNzID0gbG9hZGVyLmxvYWRDbGFzcyhwcmVmaXggKyAiJEUiKTsKKyAgICAgICAgZkNsYXNzID0gbG9hZGVyLmxvYWRDbGFzcyhwcmVmaXggKyAiJEYiKTsKKyAgICAgICAgYUxpc3RDbGFzcyA9IGxvYWRlci5sb2FkQ2xhc3MocHJlZml4ICsgIiRBTGlzdCIpOworICAgICAgICBiU3RyaW5nQ2xhc3MgPSBsb2FkZXIubG9hZENsYXNzKHByZWZpeCArICIkQlN0cmluZyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RMb2FkT25lQ2xhc3NJblR3b0NsYXNzTG9hZGVyc1NpbXVsdGFuZW91c2x5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyhhQ2xhc3MuZ2V0TmFtZSgpLCBBLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydE5vdFNhbWUoYUNsYXNzLCBBLmNsYXNzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmllbGQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGFDbGFzcywgYUxpc3RDbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJmaWVsZCIpLmdldFR5cGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD0xMDExMQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmljU3VwZXJjbGFzc1BhcmFtZXRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRQYXJhbWV0ZXJpemVkVHlwZShhTGlzdENsYXNzLmdldEdlbmVyaWNTdXBlcmNsYXNzKCksIEFycmF5TGlzdC5jbGFzcywgYUNsYXNzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2VuZXJpY1N1cGVyY2xhc3NSYXdUeXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFBhcmFtZXRlcml6ZWRUeXBlKGJTdHJpbmdDbGFzcy5nZXRHZW5lcmljU3VwZXJjbGFzcygpLCBiQ2xhc3MsIFN0cmluZy5jbGFzcyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFR5cGVQYXJhbWV0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFR5cGVWYXJpYWJsZTw/IGV4dGVuZHMgQ2xhc3M8Pz4+W10gdHlwZVZhcmlhYmxlcyA9IGNDbGFzcy5nZXRUeXBlUGFyYW1ldGVycygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgdHlwZVZhcmlhYmxlcy5sZW5ndGgpOworICAgICAgICBhc3NlcnRUeXBlVmFyaWFibGUodHlwZVZhcmlhYmxlc1swXSwgIksiLCBTdHJpbmcuY2xhc3MpOworICAgICAgICBhc3NlcnRUeXBlVmFyaWFibGUodHlwZVZhcmlhYmxlc1sxXSwgIlYiLCBhQ2xhc3MpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmljSW50ZXJmYWNlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUeXBlW10gdHlwZXMgPSBlQ2xhc3MuZ2V0R2VuZXJpY0ludGVyZmFjZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHR5cGVzLmxlbmd0aCk7CisgICAgICAgIC8vIFRPRE86IHRoaXMgdGVzdCBpbmNvcnJlY3RseSBhc3N1bWVzIHRoYXQgaW50ZXJmYWNlcyB3aWxsIGJlIHJldHVybmVkIGluIHNvdXJjZSBvcmRlciEKKyAgICAgICAgYXNzZXJ0UGFyYW1ldGVyaXplZFR5cGUodHlwZXNbMF0sIENhbGxhYmxlLmNsYXNzLCBhQ2xhc3MpOworICAgICAgICBhc3NlcnRQYXJhbWV0ZXJpemVkVHlwZSh0eXBlc1sxXSwgZENsYXNzLCBhQ2xhc3MpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGaWVsZEdlbmVyaWNUeXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpZWxkIGJTdHJpbmcgPSBmQ2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgiYlN0cmluZyIpOworICAgICAgICBhc3NlcnRQYXJhbWV0ZXJpemVkVHlwZShiU3RyaW5nLmdldEdlbmVyaWNUeXBlKCksIGJDbGFzcywgU3RyaW5nLmNsYXNzKTsKKyAgICAgICAgRmllbGQgbGlzdEEgPSBmQ2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgibGlzdEEiKTsKKyAgICAgICAgYXNzZXJ0UGFyYW1ldGVyaXplZFR5cGUobGlzdEEuZ2V0R2VuZXJpY1R5cGUoKSwgTGlzdC5jbGFzcywgYUNsYXNzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RydWN0b3JHZW5lcmljVHlwZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDb25zdHJ1Y3Rvcjw/PiBjb25zdHJ1Y3RvciA9IGZDbGFzcy5nZXREZWNsYXJlZENvbnN0cnVjdG9ycygpWzBdOworICAgICAgICBUeXBlW10gcGFyYW1ldGVycyA9IGNvbnN0cnVjdG9yLmdldEdlbmVyaWNQYXJhbWV0ZXJUeXBlcygpOworICAgICAgICBhc3NlcnRQYXJhbWV0ZXJpemVkVHlwZShwYXJhbWV0ZXJzWzBdLCBiQ2xhc3MsIFN0cmluZy5jbGFzcyk7CisgICAgICAgIGFzc2VydFBhcmFtZXRlcml6ZWRUeXBlKHBhcmFtZXRlcnNbMV0sIExpc3QuY2xhc3MsIGFDbGFzcyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1ldGhvZEdlbmVyaWNSZXR1cm5UeXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBmQ2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoIm1ldGhvZCIsIGJDbGFzcywgTGlzdC5jbGFzcyk7CisgICAgICAgIGFzc2VydFBhcmFtZXRlcml6ZWRUeXBlKG1ldGhvZC5nZXRHZW5lcmljUmV0dXJuVHlwZSgpLCBiQ2xhc3MsIFN0cmluZy5jbGFzcyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1ldGhvZEdlbmVyaWNQYXJhbWV0ZXJUeXBlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNZXRob2QgbWV0aG9kID0gZkNsYXNzLmdldERlY2xhcmVkTWV0aG9kKCJtZXRob2QiLCBiQ2xhc3MsIExpc3QuY2xhc3MpOworICAgICAgICBUeXBlW10gdHlwZXMgPSBtZXRob2QuZ2V0R2VuZXJpY1BhcmFtZXRlclR5cGVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCB0eXBlcy5sZW5ndGgpOworICAgICAgICBhc3NlcnRQYXJhbWV0ZXJpemVkVHlwZSh0eXBlc1swXSwgYkNsYXNzLCBTdHJpbmcuY2xhc3MpOworICAgICAgICBhc3NlcnRQYXJhbWV0ZXJpemVkVHlwZSh0eXBlc1sxXSwgTGlzdC5jbGFzcywgYUNsYXNzKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgQSB7fQorICAgIHN0YXRpYyBjbGFzcyBCPFQ+IHsKKyAgICAgICAgVCBmaWVsZDsKKyAgICB9CisgICAgc3RhdGljIGNsYXNzIEM8SyBleHRlbmRzIFN0cmluZywgViBleHRlbmRzIEE+IHt9CisgICAgaW50ZXJmYWNlIEQ8VD4ge30KKyAgICBjbGFzcyBFIGltcGxlbWVudHMgQ2FsbGFibGU8QT4sIEQ8QT4geworICAgICAgICBwdWJsaWMgQSBjYWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKyAgICBjbGFzcyBGIHsKKyAgICAgICAgQjxTdHJpbmc+IGJTdHJpbmc7CisgICAgICAgIExpc3Q8QT4gbGlzdEE7CisgICAgICAgIEYoQjxTdHJpbmc+IHBhcmFtZXRlciwgTGlzdDxBPiBhbm90aGVyUGFyYW1ldGVyKSB7fQorICAgICAgICBCPFN0cmluZz4gbWV0aG9kKEI8U3RyaW5nPiBwYXJhbWV0ZXIsIExpc3Q8QT4gYW5vdGhlclBhcmFtZXRlcikgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisgICAgc3RhdGljIGNsYXNzIEFMaXN0IGV4dGVuZHMgQXJyYXlMaXN0PEE+IHsKKyAgICAgICAgQSBmaWVsZDsKKyAgICB9CisgICAgc3RhdGljIGNsYXNzIEJTdHJpbmcgZXh0ZW5kcyBCPFN0cmluZz4ge30KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRQYXJhbWV0ZXJpemVkVHlwZShUeXBlIGFjdHVhbCwgVHlwZSByYXcsIFR5cGUuLi4gYXJncykgeworICAgICAgICBhc3NlcnRUcnVlKGFjdHVhbC50b1N0cmluZygpLCBhY3R1YWwgaW5zdGFuY2VvZiBQYXJhbWV0ZXJpemVkVHlwZSk7CisgICAgICAgIFBhcmFtZXRlcml6ZWRUeXBlIHBhcmFtZXRlcml6ZWRUeXBlID0gKFBhcmFtZXRlcml6ZWRUeXBlKSBhY3R1YWw7CisgICAgICAgIGFzc2VydEVxdWFscyhyYXcsIHBhcmFtZXRlcml6ZWRUeXBlLmdldFJhd1R5cGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuPFR5cGU+YXNMaXN0KGFyZ3MpLAorICAgICAgICAgICAgICAgIEFycmF5cy5hc0xpc3QocGFyYW1ldGVyaXplZFR5cGUuZ2V0QWN0dWFsVHlwZUFyZ3VtZW50cygpKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydFR5cGVWYXJpYWJsZShUeXBlVmFyaWFibGUgYWN0dWFsLCBTdHJpbmcgbmFtZSwgVHlwZS4uLiBib3VuZHMpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5hbWUsIGFjdHVhbC5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLjxUeXBlPmFzTGlzdChib3VuZHMpLCBBcnJheXMuYXNMaXN0KGFjdHVhbC5nZXRCb3VuZHMoKSkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L0NvbnN0cnVjdG9yVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL3JlZmxlY3QvQ29uc3RydWN0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWQ5ODc5NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L0NvbnN0cnVjdG9yVGVzdC5qYXZhCkBAIC0wLDAgKzEsODAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBDb25zdHJ1Y3RvclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRFeGNlcHRpb25UeXBlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDb25zdHJ1Y3Rvcjw/PiBjb25zdHJ1Y3RvciA9IENvbnN0cnVjdG9yVGVzdEhlbHBlci5jbGFzcy5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbMF0pOworICAgICAgICBDbGFzc1tdIGV4Y2VwdGlvbnMgPSBjb25zdHJ1Y3Rvci5nZXRFeGNlcHRpb25UeXBlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZXhjZXB0aW9ucy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbi5jbGFzcywgZXhjZXB0aW9uc1swXSk7CisgICAgICAgIC8vIENoZWNrIHRoYXQgY29ycnVwdGluZyBvdXIgYXJyYXkgZG9lc24ndCBhZmZlY3Qgb3RoZXIgY2FsbGVycy4KKyAgICAgICAgZXhjZXB0aW9uc1swXSA9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzOworICAgICAgICBleGNlcHRpb25zID0gY29uc3RydWN0b3IuZ2V0RXhjZXB0aW9uVHlwZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGV4Y2VwdGlvbnMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24uY2xhc3MsIGV4Y2VwdGlvbnNbMF0pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UGFyYW1ldGVyVHlwZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2xhc3NbXSBleHBlY3RlZFBhcmFtZXRlcnMgPSBuZXcgQ2xhc3NbXSB7IE9iamVjdC5jbGFzcyB9OworICAgICAgICBDb25zdHJ1Y3Rvcjw/PiBjb25zdHJ1Y3RvciA9IENvbnN0cnVjdG9yVGVzdEhlbHBlci5jbGFzcy5nZXRDb25zdHJ1Y3RvcihleHBlY3RlZFBhcmFtZXRlcnMpOworICAgICAgICBDbGFzc1tdIHBhcmFtZXRlcnMgPSBjb25zdHJ1Y3Rvci5nZXRQYXJhbWV0ZXJUeXBlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgcGFyYW1ldGVycy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRQYXJhbWV0ZXJzWzBdLCBwYXJhbWV0ZXJzWzBdKTsKKyAgICAgICAgLy8gQ2hlY2sgdGhhdCBjb3JydXB0aW5nIG91ciBhcnJheSBkb2Vzbid0IGFmZmVjdCBvdGhlciBjYWxsZXJzLgorICAgICAgICBwYXJhbWV0ZXJzWzBdID0gU3RyaW5nLmNsYXNzOworICAgICAgICBwYXJhbWV0ZXJzID0gY29uc3RydWN0b3IuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHBhcmFtZXRlcnMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkUGFyYW1ldGVyc1swXSwgcGFyYW1ldGVyc1swXSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldENvbnN0cnVjdG9yV2l0aE51bGxBcmd1bWVudHNBcnJheSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDb25zdHJ1Y3Rvcjw/PiBjb25zdHJ1Y3RvciA9IENvbnN0cnVjdG9yVGVzdEhlbHBlci5jbGFzcy5nZXRDb25zdHJ1Y3RvcigoQ2xhc3NbXSkgbnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBjb25zdHJ1Y3Rvci5nZXRQYXJhbWV0ZXJUeXBlcygpLmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldENvbnN0cnVjdG9yV2l0aE51bGxBcmd1bWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29uc3RydWN0b3JUZXN0SGVscGVyLmNsYXNzLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHsgbnVsbCB9KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q29uc3RydWN0b3JSZXR1cm5zRG9lc05vdFJldHVyblByaXZhdGVDb25zdHJ1Y3RvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29uc3RydWN0b3JUZXN0SGVscGVyLmNsYXNzLmdldENvbnN0cnVjdG9yKE9iamVjdC5jbGFzcywgT2JqZWN0LmNsYXNzKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RGVjbGFyZWRDb25zdHJ1Y3RvclJldHVybnNQcml2YXRlQ29uc3RydWN0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ29uc3RydWN0b3I8Pz4gY29uc3RydWN0b3IgPSBDb25zdHJ1Y3RvclRlc3RIZWxwZXIuY2xhc3MuZ2V0RGVjbGFyZWRDb25zdHJ1Y3RvcigKKyAgICAgICAgICAgICAgICBPYmplY3QuY2xhc3MsIE9iamVjdC5jbGFzcyk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBjb25zdHJ1Y3Rvci5nZXRQYXJhbWV0ZXJUeXBlcygpLmxlbmd0aCk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIENvbnN0cnVjdG9yVGVzdEhlbHBlciB7CisgICAgICAgIHB1YmxpYyBDb25zdHJ1Y3RvclRlc3RIZWxwZXIoKSB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB7IH0KKyAgICAgICAgcHVibGljIENvbnN0cnVjdG9yVGVzdEhlbHBlcihPYmplY3QgbykgeyB9CisgICAgICAgIHByaXZhdGUgQ29uc3RydWN0b3JUZXN0SGVscGVyKE9iamVjdCBhLCBPYmplY3QgYikgeyB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL3JlZmxlY3QvR2VuZXJpY0V4Y2VwdGlvbnNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvcmVmbGVjdC9HZW5lcmljRXhjZXB0aW9uc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYzk1OWMwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL3JlZmxlY3QvR2VuZXJpY0V4Y2VwdGlvbnNUZXN0LmphdmEKQEAgLTAsMCArMSwxMTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5UeXBlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGVWYXJpYWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIEdlbmVyaWNFeGNlcHRpb25zVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmljRXhjZXB0aW9uc09mTWV0aG9kc1dpdGhUeXBlUGFyYW1ldGVycygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNZXRob2QgbWV0aG9kID0gVGhyb3dlci5jbGFzcy5nZXRNZXRob2QoInBhcmFtZXRlcml6ZWRNZXRob2QiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy48VHlwZT5hc0xpc3QoSU9FeGNlcHRpb24uY2xhc3MpLAorICAgICAgICAgICAgICAgIEFycmF5cy5hc0xpc3QobWV0aG9kLmdldEdlbmVyaWNFeGNlcHRpb25UeXBlcygpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdlbmVyaWNFeGNlcHRpb25zT2ZNZXRob2RzV2l0aEdlbmVyaWNQYXJhbWV0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBUaHJvd2VyLmNsYXNzLmdldE1ldGhvZCgiZ2VuZXJpY1BhcmFtZXRlcnMiLCBMaXN0LmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy48VHlwZT5hc0xpc3QoSU9FeGNlcHRpb24uY2xhc3MpLAorICAgICAgICAgICAgICAgIEFycmF5cy5hc0xpc3QobWV0aG9kLmdldEdlbmVyaWNFeGNlcHRpb25UeXBlcygpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdlbmVyaWNFeGNlcHRpb25zT2ZDb25zdHJ1Y3RvcnNXaXRoVHlwZVBhcmFtZXRlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ29uc3RydWN0b3IgY29uc3RydWN0b3IgPSBUaHJvd2VyLmNsYXNzLmdldENvbnN0cnVjdG9yKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuPFR5cGU+YXNMaXN0KElPRXhjZXB0aW9uLmNsYXNzKSwKKyAgICAgICAgICAgICAgICBBcnJheXMuYXNMaXN0KGNvbnN0cnVjdG9yLmdldEdlbmVyaWNFeGNlcHRpb25UeXBlcygpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdlbmVyaWNFeGNlcHRpb25zT2ZDb25zdHJ1Y3RvcnNXaXRoR2VuZXJpY1BhcmFtZXRlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ29uc3RydWN0b3IgY29uc3RydWN0b3IgPSBUaHJvd2VyLmNsYXNzLmdldENvbnN0cnVjdG9yKExpc3QuY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLjxUeXBlPmFzTGlzdChJT0V4Y2VwdGlvbi5jbGFzcyksCisgICAgICAgICAgICAgICAgQXJyYXlzLmFzTGlzdChjb25zdHJ1Y3Rvci5nZXRHZW5lcmljRXhjZXB0aW9uVHlwZXMoKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25zdHJ1Y3RvclRocm93aW5nVHlwZVZhcmlhYmxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENvbnN0cnVjdG9yIGNvbnN0cnVjdG9yID0gVGhyb3dlclQuY2xhc3MuZ2V0Q29uc3RydWN0b3IoKTsKKyAgICAgICAgVHlwZVZhcmlhYmxlIHR5cGVWYXJpYWJsZSA9IGdldE9ubHlWYWx1ZShjb25zdHJ1Y3Rvci5nZXRHZW5lcmljRXhjZXB0aW9uVHlwZXMoKSwKKyAgICAgICAgICAgICAgICBUeXBlVmFyaWFibGUuY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlQiLCB0eXBlVmFyaWFibGUuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy48VHlwZT5hc0xpc3QoVGhyb3dhYmxlLmNsYXNzKSwgQXJyYXlzLmFzTGlzdCh0eXBlVmFyaWFibGUuZ2V0Qm91bmRzKCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWV0aG9kVGhyb3dpbmdUeXBlVmFyaWFibGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IFRocm93ZXJULmNsYXNzLmdldE1ldGhvZCgidGhyb3dzVHlwZVZhcmlhYmxlIik7CisgICAgICAgIFR5cGVWYXJpYWJsZSB0eXBlVmFyaWFibGUgPSBnZXRPbmx5VmFsdWUobWV0aG9kLmdldEdlbmVyaWNFeGNlcHRpb25UeXBlcygpLAorICAgICAgICAgICAgICAgIFR5cGVWYXJpYWJsZS5jbGFzcyk7CisgICAgICAgIGFzc2VydEVxdWFscygiVCIsIHR5cGVWYXJpYWJsZS5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLjxUeXBlPmFzTGlzdChUaHJvd2FibGUuY2xhc3MpLCBBcnJheXMuYXNMaXN0KHR5cGVWYXJpYWJsZS5nZXRCb3VuZHMoKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUaHJvd2luZ01ldGhvZFR5cGVQYXJhbWV0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IFRocm93ZXJULmNsYXNzLmdldE1ldGhvZCgidGhyb3dzTWV0aG9kVHlwZVBhcmFtZXRlciIpOworICAgICAgICBUeXBlVmFyaWFibGUgdHlwZVZhcmlhYmxlID0gZ2V0T25seVZhbHVlKG1ldGhvZC5nZXRHZW5lcmljRXhjZXB0aW9uVHlwZXMoKSwKKyAgICAgICAgICAgICAgICBUeXBlVmFyaWFibGUuY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlgiLCB0eXBlVmFyaWFibGUuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy48VHlwZT5hc0xpc3QoRXhjZXB0aW9uLmNsYXNzKSwgQXJyYXlzLmFzTGlzdCh0eXBlVmFyaWFibGUuZ2V0Qm91bmRzKCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VGhyb3dpbmdNZXRob2RUaHJvd3NFdmVyeXRoaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBUaHJvd2VyVC5jbGFzcy5nZXRNZXRob2QoInRocm93c0V2ZXJ5dGhpbmciKTsKKyAgICAgICAgVHlwZVtdIGV4Y2VwdGlvbnMgPSBtZXRob2QuZ2V0R2VuZXJpY0V4Y2VwdGlvblR5cGVzKCk7CisgICAgICAgIFR5cGVWYXJpYWJsZSB0ID0gKFR5cGVWYXJpYWJsZSkgZXhjZXB0aW9uc1swXTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGV4Y2VwdGlvbnMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUIiwgdC5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLjxUeXBlPmFzTGlzdChUaHJvd2FibGUuY2xhc3MpLCBBcnJheXMuYXNMaXN0KHQuZ2V0Qm91bmRzKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEV4Y2VwdGlvbi5jbGFzcywgZXhjZXB0aW9uc1sxXSk7CisgICAgICAgIFR5cGVWYXJpYWJsZSB4ID0gKFR5cGVWYXJpYWJsZSkgZXhjZXB0aW9uc1syXTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJYIiwgeC5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLjxUeXBlPmFzTGlzdChFeGNlcHRpb24uY2xhc3MpLCBBcnJheXMuYXNMaXN0KHguZ2V0Qm91bmRzKCkpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIDxUPiBUIGdldE9ubHlWYWx1ZShPYmplY3RbXSBhcnJheSwgQ2xhc3M8VD4gZXhwZWN0ZWRUeXBlKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiRXhwZWN0ZWQgYSAiICsgZXhwZWN0ZWRUeXBlLmdldE5hbWUoKSArICIgYnV0IHdhcyAiICsgQXJyYXlzLnRvU3RyaW5nKGFycmF5KSwKKyAgICAgICAgICAgICAgICAxLCBhcnJheS5sZW5ndGgpOworICAgICAgICBhc3NlcnRUcnVlKCJFeHBlY3RlZCBhICIgKyBleHBlY3RlZFR5cGUuZ2V0TmFtZSgpICsgIiBidXQgd2FzICIgKyBhcnJheVswXSwKKyAgICAgICAgICAgICAgICBleHBlY3RlZFR5cGUuaXNJbnN0YW5jZShhcnJheVswXSkpOworICAgICAgICByZXR1cm4gZXhwZWN0ZWRUeXBlLmNhc3QoYXJyYXlbMF0pOworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBUaHJvd2VyIHsKKyAgICAgICAgcHVibGljIDxUPiBUaHJvd2VyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHt9CisgICAgICAgIHB1YmxpYyBUaHJvd2VyKExpc3Q8Pz4gdW51c2VkKSB0aHJvd3MgSU9FeGNlcHRpb24ge30KKyAgICAgICAgcHVibGljIDxUPiB2b2lkIHBhcmFtZXRlcml6ZWRNZXRob2QoKSB0aHJvd3MgSU9FeGNlcHRpb24ge30KKyAgICAgICAgcHVibGljIHZvaWQgZ2VuZXJpY1BhcmFtZXRlcnMoTGlzdDw/PiB1bnVzZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7fQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBUaHJvd2VyVDxUIGV4dGVuZHMgVGhyb3dhYmxlPiB7CisgICAgICAgIHB1YmxpYyBUaHJvd2VyVCgpIHRocm93cyBUIHt9CisgICAgICAgIHB1YmxpYyB2b2lkIHRocm93c1R5cGVWYXJpYWJsZSgpIHRocm93cyBUIHt9CisgICAgICAgIHB1YmxpYyA8WCBleHRlbmRzIEV4Y2VwdGlvbj4gdm9pZCB0aHJvd3NNZXRob2RUeXBlUGFyYW1ldGVyKCkgdGhyb3dzIFgge30KKyAgICAgICAgcHVibGljIDxYIGV4dGVuZHMgRXhjZXB0aW9uPiB2b2lkIHRocm93c0V2ZXJ5dGhpbmcoKSB0aHJvd3MgVCwgRXhjZXB0aW9uLCBYe30KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvcmVmbGVjdC9NZXRob2RPdmVycmlkZXNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvcmVmbGVjdC9NZXRob2RPdmVycmlkZXNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGQ0NmY0NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L01ldGhvZE92ZXJyaWRlc1Rlc3QuamF2YQpAQCAtMCwwICsxLDE3NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLmxhbmcucmVmbGVjdDsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE1ldGhvZE92ZXJyaWRlc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmFtZSgpIHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24geworICAgICAgICBNZXRob2QgbWV0aG9kID0gU3RyaW5nQnVpbGRlci5jbGFzcy5nZXRNZXRob2QoImFwcGVuZCIsIGNoYXIuY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFwcGVuZCIsIG1ldGhvZC5nZXROYW1lKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJhbWV0ZXJUeXBlcygpIHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24geworICAgICAgICBNZXRob2QgbWV0aG9kID0gU3RyaW5nQnVpbGRlci5jbGFzcy5nZXRNZXRob2QoImFwcGVuZCIsIGNoYXIuY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLjxDbGFzczw/Pj5hc0xpc3QoY2hhci5jbGFzcyksCisgICAgICAgICAgICAgICAgQXJyYXlzLmFzTGlzdChtZXRob2QuZ2V0UGFyYW1ldGVyVHlwZXMoKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REZWNsYXJpbmdDbGFzcygpIHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24geworICAgICAgICBNZXRob2QgbWV0aG9kID0gU3RyaW5nQnVpbGRlci5jbGFzcy5nZXRNZXRob2QoImFwcGVuZCIsIGNoYXIuY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoU3RyaW5nQnVpbGRlci5jbGFzcywgbWV0aG9kLmdldERlY2xhcmluZ0NsYXNzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXR1cm5UeXBlKCkgdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBTdHJpbmdCdWlsZGVyLmNsYXNzLmdldE1ldGhvZCgiYXBwZW5kIiwgY2hhci5jbGFzcyk7CisgICAgICAgIGFzc2VydEVxdWFscyhTdHJpbmdCdWlsZGVyLmNsYXNzLCBtZXRob2QuZ2V0UmV0dXJuVHlwZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VGhyb3duRXhjZXB0aW9ucygpIHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24geworICAgICAgICBNZXRob2QgbWV0aG9kID0gU3RyaW5nQnVpbGRlci5jbGFzcy5nZXRNZXRob2QoImFwcGVuZCIsIGNoYXIuY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29sbGVjdGlvbnMuPENsYXNzPD8+PmVtcHR5TGlzdCgpLCBBcnJheXMuYXNMaXN0KG1ldGhvZC5nZXRFeGNlcHRpb25UeXBlcygpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldE1ldGhvZHNJbmNsdWRlc0luaGVyaXRlZE1ldGhvZHMoKSB7CisgICAgICAgIFNldDxTdHJpbmc+IHNpZ25hdHVyZXMgPSBzaWduYXR1cmVzKFN1Yi5jbGFzcy5nZXRNZXRob2RzKCkpOworICAgICAgICBhc3NlcnRDb250YWlucyhzaWduYXR1cmVzLCAidm9pZCBub3RPdmVycmlkZGVuW10gdGhyb3dzIFtdIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldERlY2xhcmVkTWV0aG9kc0RvZXNOb3RJbmNsdWRlSW5oZXJpdGVkTWV0aG9kcygpIHsKKyAgICAgICAgU2V0PFN0cmluZz4gc2lnbmF0dXJlcyA9IHNpZ25hdHVyZXMoU3ViLmNsYXNzLmdldERlY2xhcmVkTWV0aG9kcygpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2lnbmF0dXJlcy5jb250YWlucygidm9pZCBub3RPdmVycmlkZGVuW10gdGhyb3dzIFtdIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXREZWNsYXJpbmdDbGFzc1JldHVybnNPdmVycmlkaW5nQ2xhc3MoKSB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFN1Yi5jbGFzcywgU3ViLmNsYXNzLmdldE1ldGhvZCgidW5jaGFuZ2VkIikuZ2V0RGVjbGFyaW5nQ2xhc3MoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhTdWIuY2xhc3MsIFN1Yi5jbGFzcy5nZXREZWNsYXJlZE1ldGhvZCgidW5jaGFuZ2VkIikuZ2V0RGVjbGFyaW5nQ2xhc3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldE1ldGhvZHNEb2VzTm90SW5jbHVkZUV4Y2VwdGlvbkNoYW5nZXMoKSB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIHsKKyAgICAgICAgU2V0PFN0cmluZz4gc2lnbmF0dXJlcyA9IHNpZ25hdHVyZXMoU3ViLmNsYXNzLmdldE1ldGhvZHMoKSk7CisgICAgICAgIGFzc2VydENvbnRhaW5zKHNpZ25hdHVyZXMsICJ2b2lkIHRocm93ZXJbXSB0aHJvd3MgW10iKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2lnbmF0dXJlcy5jb250YWlucygidm9pZCB0aHJvd2VyW10gdGhyb3dzIFtqYXZhLmxhbmcuRXhjZXB0aW9uXSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFN1Yi5jbGFzcywgU3ViLmNsYXNzLmdldE1ldGhvZCgidGhyb3dlciIpLmdldERlY2xhcmluZ0NsYXNzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRNZXRob2RzSW5jbHVkZXNTeW50aGV0aWNNZXRob2RzKCkgdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiB7CisgICAgICAgIFNldDxTdHJpbmc+IHNpZ25hdHVyZXMgPSBzaWduYXR1cmVzKFN1Yi5jbGFzcy5nZXRNZXRob2RzKCkpOworICAgICAgICBhc3NlcnRDb250YWlucyhzaWduYXR1cmVzLCAiamF2YS5sYW5nLlN0cmluZyByZXR1cm5lcltdIHRocm93cyBbXSIpOworICAgICAgICBhc3NlcnRDb250YWlucyhzaWduYXR1cmVzLCAiamF2YS5sYW5nLk9iamVjdCByZXR1cm5lcltdIHRocm93cyBbXSIpOworCisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBTdWIuY2xhc3MuZ2V0TWV0aG9kKCJyZXR1cm5lciIpOworICAgICAgICBhc3NlcnRFcXVhbHMoU3ViLmNsYXNzLCBtZXRob2QuZ2V0RGVjbGFyaW5nQ2xhc3MoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGhvZC5pc1N5bnRoZXRpYygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RGVjbGFyZWRNZXRob2RzSW5jbHVkZXNTeW50aGV0aWNNZXRob2RzKCkgdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiB7CisgICAgICAgIFNldDxTdHJpbmc+IHNpZ25hdHVyZXMgPSBzaWduYXR1cmVzKFN1Yi5jbGFzcy5nZXREZWNsYXJlZE1ldGhvZHMoKSk7CisgICAgICAgIGFzc2VydENvbnRhaW5zKHNpZ25hdHVyZXMsICJqYXZhLmxhbmcuU3RyaW5nIHJldHVybmVyW10gdGhyb3dzIFtdIik7CisgICAgICAgIGFzc2VydENvbnRhaW5zKHNpZ25hdHVyZXMsICJqYXZhLmxhbmcuT2JqZWN0IHJldHVybmVyW10gdGhyb3dzIFtdIik7CisKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IFN1Yi5jbGFzcy5nZXRNZXRob2QoInJldHVybmVyIik7CisgICAgICAgIGFzc2VydEVxdWFscyhTdWIuY2xhc3MsIG1ldGhvZC5nZXREZWNsYXJpbmdDbGFzcygpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0aG9kLmlzU3ludGhldGljKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdWJjbGFzc0NoYW5nZXNWaXNpYmlsaXR5KCkgdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZFtdIG1ldGhvZHMgPSBTdWIuY2xhc3MuZ2V0TWV0aG9kcygpOworICAgICAgICBpbnQgY291bnQgPSAwOworICAgICAgICBmb3IgKE1ldGhvZCBtZXRob2QgOiBtZXRob2RzKSB7CisgICAgICAgICAgICBpZiAoc2lnbmF0dXJlKG1ldGhvZCkuZXF1YWxzKCJ2b2lkIHZpc2liaWxpdHlbXSB0aHJvd3MgW10iKSkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhTdWIuY2xhc3MsIG1ldGhvZC5nZXREZWNsYXJpbmdDbGFzcygpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShtZXRob2QuaXNTeW50aGV0aWMoKSk7CisgICAgICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY291bnQpOworCisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBTdWIuY2xhc3MuZ2V0TWV0aG9kKCJ2aXNpYmlsaXR5Iik7CisgICAgICAgIGFzc2VydEVxdWFscyhTdWIuY2xhc3MsIG1ldGhvZC5nZXREZWNsYXJpbmdDbGFzcygpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0aG9kLmlzU3ludGhldGljKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNb3JlVmlzaWJsZVN1YmNsYXNzQ2hhbmdlc1Zpc2liaWxpdHkoKSB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kW10gbWV0aG9kcyA9IFB1YmxpY1N1Yi5jbGFzcy5nZXRNZXRob2RzKCk7CisgICAgICAgIGludCBjb3VudCA9IDA7CisgICAgICAgIGZvciAoTWV0aG9kIG1ldGhvZCA6IG1ldGhvZHMpIHsKKyAgICAgICAgICAgIGlmIChzaWduYXR1cmUobWV0aG9kKS5lcXVhbHMoInZvaWQgdW5jaGFuZ2VkW10gdGhyb3dzIFtdIikpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoUHVibGljU3ViLmNsYXNzLCBtZXRob2QuZ2V0RGVjbGFyaW5nQ2xhc3MoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShtZXRob2QuaXNTeW50aGV0aWMoKSk7CisgICAgICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY291bnQpOworCisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBQdWJsaWNTdWIuY2xhc3MuZ2V0TWV0aG9kKCJ1bmNoYW5nZWQiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFB1YmxpY1N1Yi5jbGFzcywgbWV0aG9kLmdldERlY2xhcmluZ0NsYXNzKCkpOworICAgICAgICBhc3NlcnRUcnVlKG1ldGhvZC5pc1N5bnRoZXRpYygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFN1cGVyIHsKKyAgICAgICAgcHVibGljIHZvaWQgbm90T3ZlcnJpZGRlbigpIHt9CisgICAgICAgIHB1YmxpYyB2b2lkIHVuY2hhbmdlZCgpIHt9CisgICAgICAgIHB1YmxpYyB2b2lkIHRocm93ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHt9CisgICAgICAgIHB1YmxpYyBPYmplY3QgcmV0dXJuZXIoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCB2aXNpYmlsaXR5KCkge30KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFN1YiBleHRlbmRzIFN1cGVyIHsKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHVuY2hhbmdlZCgpIHt9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCB0aHJvd2VyKCkge30KKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgcmV0dXJuZXIoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgdmlzaWJpbGl0eSgpIHt9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFBhY2thZ2VTdXBlciB7CisgICAgICAgIHB1YmxpYyB2b2lkIHVuY2hhbmdlZCgpIHt9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBQdWJsaWNTdWIgZXh0ZW5kcyBQYWNrYWdlU3VwZXIge30KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBtZXRob2Qgc2lnbmF0dXJlIG9mIHRoaXMgZm9ybToKKyAgICAgKiB7QGNvZGUgamF2YS5sYW5nLlN0cmluZyBjb25jYXRbY2xhc3MgamF2YS5sYW5nLlN0cmluZ10gdGhyb3dzIFtdfS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBzaWduYXR1cmUoTWV0aG9kIG1ldGhvZCkgeworICAgICAgICByZXR1cm4gbWV0aG9kLmdldFJldHVyblR5cGUoKS5nZXROYW1lKCkgKyAiICIgKyBtZXRob2QuZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgKyBBcnJheXMudG9TdHJpbmcobWV0aG9kLmdldFBhcmFtZXRlclR5cGVzKCkpCisgICAgICAgICAgICAgICAgKyAiIHRocm93cyAiICsgQXJyYXlzLnRvU3RyaW5nKG1ldGhvZC5nZXRFeGNlcHRpb25UeXBlcygpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFNldDxTdHJpbmc+IHNpZ25hdHVyZXMoTWV0aG9kW10gbWV0aG9kcykgeworICAgICAgICBTZXQ8U3RyaW5nPiBzaWduYXR1cmVzID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgICBmb3IgKE1ldGhvZCBtZXRob2QgOiBtZXRob2RzKSB7CisgICAgICAgICAgICBzaWduYXR1cmVzLmFkZChzaWduYXR1cmUobWV0aG9kKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNpZ25hdHVyZXM7CisgICAgfQorCisgICAgcHJpdmF0ZSA8VD4gdm9pZCBhc3NlcnRDb250YWlucyhDb2xsZWN0aW9uPFQ+IGVsZW1lbnRzLCBUIHZhbHVlKSB7CisgICAgICAgIGFzc2VydFRydWUoIkV4cGVjdGVkICIgKyB2YWx1ZSArICIgaW4gIiArIGVsZW1lbnRzLCBlbGVtZW50cy5jb250YWlucyh2YWx1ZSkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L01ldGhvZFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L01ldGhvZFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMDU5ZDk2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjE5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZy5yZWZsZWN0OworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIE1ldGhvZFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgLy8gQ2hlY2sgdGhhdCB0aGUgVk0gZ2l2ZXMgdXNlZnVsIGRldGFpbCBtZXNzYWdlcy4KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ludm9rZUV4Y2VwdGlvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG0gPSBTdHJpbmcuY2xhc3MuZ2V0TWV0aG9kKCJjaGFyQXQiLCBpbnQuY2xhc3MpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbS5pbnZva2UoImhlbGxvIik7IC8vIFdyb25nIG51bWJlciBvZiBhcmd1bWVudHMuCisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygid3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50czsgZXhwZWN0ZWQgMSwgZ290IDAiLCBpYWUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbS5pbnZva2UoImhlbGxvIiwgIndvcmxkIik7IC8vIFdyb25nIHR5cGUuCisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiYXJndW1lbnQgMSBzaG91bGQgaGF2ZSB0eXBlIGludCwgZ290IGphdmEubGFuZy5TdHJpbmciLCBpYWUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbS5pbnZva2UoImhlbGxvIiwgKE9iamVjdCkgbnVsbCk7IC8vIE51bGwgZm9yIGEgcHJpbWl0aXZlIGFyZ3VtZW50LgorICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImFyZ3VtZW50IDEgc2hvdWxkIGhhdmUgdHlwZSBpbnQsIGdvdCBudWxsIiwgaWFlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG0uaW52b2tlKG5ldyBJbnRlZ2VyKDUpKTsgLy8gV3JvbmcgdHlwZSBmb3IgJ3RoaXMnLgorICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImV4cGVjdGVkIHJlY2VpdmVyIG9mIHR5cGUgamF2YS5sYW5nLlN0cmluZywgYnV0IGdvdCBqYXZhLmxhbmcuSW50ZWdlciIsIGlhZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLmludm9rZShudWxsKTsgLy8gTnVsbCBmb3IgJ3RoaXMnLgorICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZXhwZWN0ZWQgcmVjZWl2ZXIgb2YgdHlwZSBqYXZhLmxhbmcuU3RyaW5nLCBidXQgZ290IG51bGwiLAorICAgICAgICAgICAgICAgICAgICBucGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RXhjZXB0aW9uVHlwZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IE1ldGhvZFRlc3RIZWxwZXIuY2xhc3MuZ2V0TWV0aG9kKCJtMSIsIG5ldyBDbGFzc1swXSk7CisgICAgICAgIENsYXNzW10gZXhjZXB0aW9ucyA9IG1ldGhvZC5nZXRFeGNlcHRpb25UeXBlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZXhjZXB0aW9ucy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbi5jbGFzcywgZXhjZXB0aW9uc1swXSk7CisgICAgICAgIC8vIENoZWNrIHRoYXQgY29ycnVwdGluZyBvdXIgYXJyYXkgZG9lc24ndCBhZmZlY3Qgb3RoZXIgY2FsbGVycy4KKyAgICAgICAgZXhjZXB0aW9uc1swXSA9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzOworICAgICAgICBleGNlcHRpb25zID0gbWV0aG9kLmdldEV4Y2VwdGlvblR5cGVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBleGNlcHRpb25zLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscyhJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLmNsYXNzLCBleGNlcHRpb25zWzBdKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFBhcmFtZXRlclR5cGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENsYXNzW10gZXhwZWN0ZWRQYXJhbWV0ZXJzID0gbmV3IENsYXNzW10geyBPYmplY3QuY2xhc3MgfTsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IE1ldGhvZFRlc3RIZWxwZXIuY2xhc3MuZ2V0TWV0aG9kKCJtMiIsIGV4cGVjdGVkUGFyYW1ldGVycyk7CisgICAgICAgIENsYXNzW10gcGFyYW1ldGVycyA9IG1ldGhvZC5nZXRQYXJhbWV0ZXJUeXBlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgcGFyYW1ldGVycy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRQYXJhbWV0ZXJzWzBdLCBwYXJhbWV0ZXJzWzBdKTsKKyAgICAgICAgLy8gQ2hlY2sgdGhhdCBjb3JydXB0aW5nIG91ciBhcnJheSBkb2Vzbid0IGFmZmVjdCBvdGhlciBjYWxsZXJzLgorICAgICAgICBwYXJhbWV0ZXJzWzBdID0gU3RyaW5nLmNsYXNzOworICAgICAgICBwYXJhbWV0ZXJzID0gbWV0aG9kLmdldFBhcmFtZXRlclR5cGVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBwYXJhbWV0ZXJzLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZFBhcmFtZXRlcnNbMF0sIHBhcmFtZXRlcnNbMF0pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRNZXRob2RXaXRoUHJpdmF0ZU1ldGhvZEFuZEludGVyZmFjZU1ldGhvZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoSW50ZXJmYWNlQS5jbGFzcywgU3ViLmNsYXNzLmdldE1ldGhvZCgiYSIpLmdldERlY2xhcmluZ0NsYXNzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRNZXRob2RSZXR1cm5zSW5kaXJlY3RseUltcGxlbWVudGVkSW50ZXJmYWNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlcmZhY2VBLmNsYXNzLCBJbXBsZW1lbnRzQy5jbGFzcy5nZXRNZXRob2QoImEiKS5nZXREZWNsYXJpbmdDbGFzcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEludGVyZmFjZUEuY2xhc3MsIEV4dGVuZHNJbXBsZW1lbnRzQy5jbGFzcy5nZXRNZXRob2QoImEiKS5nZXREZWNsYXJpbmdDbGFzcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RGVjbGFyZWRNZXRob2RSZXR1cm5zSW5kaXJlY3RseUltcGxlbWVudGVkSW50ZXJmYWNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbXBsZW1lbnRzQy5jbGFzcy5nZXREZWNsYXJlZE1ldGhvZCgiYSIpLmdldERlY2xhcmluZ0NsYXNzKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFeHRlbmRzSW1wbGVtZW50c0MuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoImEiKS5nZXREZWNsYXJpbmdDbGFzcygpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRNZXRob2RXaXRoQ29uc3RydWN0b3JOYW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNZXRob2RUZXN0SGVscGVyLmNsYXNzLmdldE1ldGhvZCgiPGluaXQ+Iik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldE1ldGhvZFdpdGhOdWxsTmFtZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgTWV0aG9kVGVzdEhlbHBlci5jbGFzcy5nZXRNZXRob2QobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TWV0aG9kV2l0aE51bGxBcmd1bWVudHNBcnJheSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNZXRob2QgbTEgPSBNZXRob2RUZXN0SGVscGVyLmNsYXNzLmdldE1ldGhvZCgibTEiLCAoQ2xhc3NbXSkgbnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBtMS5nZXRQYXJhbWV0ZXJUeXBlcygpLmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldE1ldGhvZFdpdGhOdWxsQXJndW1lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE1ldGhvZFRlc3RIZWxwZXIuY2xhc3MuZ2V0TWV0aG9kKCJtMiIsIG5ldyBDbGFzc1tdIHsgbnVsbCB9KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TWV0aG9kUmV0dXJuc0luaGVyaXRlZFN0YXRpY01ldGhvZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNZXRob2QgYiA9IFN1Yi5jbGFzcy5nZXRNZXRob2QoImIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHZvaWQuY2xhc3MsIGIuZ2V0UmV0dXJuVHlwZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RGVjbGFyZWRNZXRob2RSZXR1cm5zUHJpdmF0ZU1ldGhvZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IFN1cGVyLmNsYXNzLmdldERlY2xhcmVkTWV0aG9kKCJhIik7CisgICAgICAgIGFzc2VydEVxdWFscyh2b2lkLmNsYXNzLCBtZXRob2QuZ2V0UmV0dXJuVHlwZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RGVjbGFyZWRNZXRob2REb2VzTm90UmV0dXJuU3VwZXJjbGFzc01ldGhvZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN1Yi5jbGFzcy5nZXREZWNsYXJlZE1ldGhvZCgiYSIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXREZWNsYXJlZE1ldGhvZERvZXNOb3RSZXR1cm5JbXBsZW1lbnRlZEludGVyZmFjZU1ldGhvZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEludGVyZmFjZUIuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoImEiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW1wbGVtZW50ZWRJbnRlcmZhY2VNZXRob2RPZkFub255bW91c0NsYXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdCBhbm9ueW1vdXMgPSBuZXcgSW50ZXJmYWNlQSgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBhKCkgeworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBNZXRob2QgbWV0aG9kID0gYW5vbnltb3VzLmdldENsYXNzKCkuZ2V0TWV0aG9kKCJhIik7CisgICAgICAgIGFzc2VydEVxdWFscyhhbm9ueW1vdXMuZ2V0Q2xhc3MoKSwgbWV0aG9kLmdldERlY2xhcmluZ0NsYXNzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQdWJsaWNNZXRob2RPZkFub255bW91c0NsYXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdCBhbm9ueW1vdXMgPSBuZXcgT2JqZWN0KCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgYSgpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IGFub255bW91cy5nZXRDbGFzcygpLmdldE1ldGhvZCgiYSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoYW5vbnltb3VzLmdldENsYXNzKCksIG1ldGhvZC5nZXREZWNsYXJpbmdDbGFzcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TWV0aG9kRG9lc05vdFJldHVyblByaXZhdGVNZXRob2RPZkFub255bW91c0NsYXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdCBhbm9ueW1vdXMgPSBuZXcgT2JqZWN0KCkgeworICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIGEoKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhbm9ueW1vdXMuZ2V0Q2xhc3MoKS5nZXRNZXRob2QoImEiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RGVjbGFyZWRNZXRob2RSZXR1cm5zUHJpdmF0ZU1ldGhvZE9mQW5vbnltb3VzQ2xhc3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0IGFub255bW91cyA9IG5ldyBPYmplY3QoKSB7CisgICAgICAgICAgICBwcml2YXRlIHZvaWQgYSgpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IGFub255bW91cy5nZXRDbGFzcygpLmdldERlY2xhcmVkTWV0aG9kKCJhIik7CisgICAgICAgIGFzc2VydEVxdWFscyhhbm9ueW1vdXMuZ2V0Q2xhc3MoKSwgbWV0aG9kLmdldERlY2xhcmluZ0NsYXNzKCkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTWV0aG9kVGVzdEhlbHBlciB7CisgICAgICAgIHB1YmxpYyB2b2lkIG0xKCkgdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24geyB9CisgICAgICAgIHB1YmxpYyB2b2lkIG0yKE9iamVjdCBvKSB7IH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFN1cGVyIHsKKyAgICAgICAgcHJpdmF0ZSB2b2lkIGEoKSB7fQorICAgICAgICBwdWJsaWMgc3RhdGljIHZvaWQgYigpIHt9CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgaW50ZXJmYWNlIEludGVyZmFjZUEgeworICAgICAgICB2b2lkIGEoKTsKKyAgICB9CisgICAgcHVibGljIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBTdWIgZXh0ZW5kcyBTdXBlciBpbXBsZW1lbnRzIEludGVyZmFjZUEgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgaW50ZXJmYWNlIEludGVyZmFjZUIgZXh0ZW5kcyBJbnRlcmZhY2VBIHt9CisgICAgcHVibGljIHN0YXRpYyBpbnRlcmZhY2UgSW50ZXJmYWNlQyBleHRlbmRzIEludGVyZmFjZUIge30KKyAgICBwdWJsaWMgc3RhdGljIGFic3RyYWN0IGNsYXNzIEltcGxlbWVudHNDIGltcGxlbWVudHMgSW50ZXJmYWNlQyB7fQorICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgRXh0ZW5kc0ltcGxlbWVudHNDIGV4dGVuZHMgSW1wbGVtZW50c0Mge30KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L01pc3NpbmdDbGFzc2VzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL3JlZmxlY3QvTWlzc2luZ0NsYXNzZXNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGI0YzgzNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L01pc3NpbmdDbGFzc2VzVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgdGVzdHMudXRpbC5DbGFzc0xvYWRlckJ1aWxkZXI7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBNaXNzaW5nQ2xhc3Nlc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIENsYXNzPD8+IGxvYWRhYmxlQ2xhc3M7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHByZWZpeCA9IE1pc3NpbmdDbGFzc2VzVGVzdC5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIENsYXNzTG9hZGVyIGNsID0gbmV3IENsYXNzTG9hZGVyQnVpbGRlcigpCisgICAgICAgICAgICAgICAgLndpdGhQcml2YXRlQ29weShwcmVmaXggKyAiJExvYWRhYmxlIikKKyAgICAgICAgICAgICAgICAud2l0aG91dChwcmVmaXggKyAiJFVubG9hZGFibGUiKQorICAgICAgICAgICAgICAgIC5idWlsZCgpOworICAgICAgICBsb2FkYWJsZUNsYXNzID0gY2wubG9hZENsYXNzKHByZWZpeCArICIkTG9hZGFibGUiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBodHRwOi8vYi9pc3N1ZT9pZD0yNjM0MDA1CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldERlY2xhcmVkRmllbGRzRmFpbHMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsb2FkYWJsZUNsYXNzLmdldERlY2xhcmVkRmllbGRzKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vQ2xhc3NEZWZGb3VuZEVycm9yIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RGVjbGFyZWRNZXRob2RzRmFpbHMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsb2FkYWJsZUNsYXNzLmdldERlY2xhcmVkTWV0aG9kcygpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOb0NsYXNzRGVmRm91bmRFcnJvciBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldE1ldGhvZEZhaWxzKCkgdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsb2FkYWJsZUNsYXNzLmdldERlY2xhcmVkTWV0aG9kKCJtZXRob2QiLCBVbmxvYWRhYmxlLmNsYXNzKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9DbGFzc0RlZkZvdW5kRXJyb3IgZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRGaWVsZEZhaWxzKCkgdGhyb3dzIE5vU3VjaEZpZWxkRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxvYWRhYmxlQ2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgiZmllbGQiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9DbGFzc0RlZkZvdW5kRXJyb3IgZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIExvYWRhYmxlIHsKKyAgICAgICAgVW5sb2FkYWJsZSBmaWVsZDsKKyAgICAgICAgdm9pZCBtZXRob2QoVW5sb2FkYWJsZSB1bmxvYWRhYmxlKSB7fQorICAgIH0KKworICAgIGNsYXNzIFVubG9hZGFibGUge30KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L01vZGlmaWVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL3JlZmxlY3QvTW9kaWZpZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWJkZTE1NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L01vZGlmaWVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZy5yZWZsZWN0OworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXI7CisKK3B1YmxpYyBjbGFzcyBNb2RpZmllclRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xhc3NNb2RpZmllcnMoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygweGMxZiwgTW9kaWZpZXIuY2xhc3NNb2RpZmllcnMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25zdHJ1Y3Rvck1vZGlmaWVycygpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MDA3LCBNb2RpZmllci5jb25zdHJ1Y3Rvck1vZGlmaWVycygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ZpZWxkTW9kaWZpZXJzKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoMHgwZGYsIE1vZGlmaWVyLmZpZWxkTW9kaWZpZXJzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW50ZXJmYWNlTW9kaWZpZXJzKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoMHhjMGYsIE1vZGlmaWVyLmludGVyZmFjZU1vZGlmaWVycygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X21ldGhvZE1vZGlmaWVycygpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4ZDNmLCBNb2RpZmllci5tZXRob2RNb2RpZmllcnMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0Fic3RyYWN0SSgpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShNb2RpZmllci5pc0Fic3RyYWN0KE1vZGlmaWVyLkFCU1RSQUNUKSk7CisgICAgICAgIGFzc2VydFRydWUoIU1vZGlmaWVyLmlzQWJzdHJhY3QoLTEgJiB+TW9kaWZpZXIuQUJTVFJBQ1QpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzRmluYWxJKCkgeworICAgICAgICBhc3NlcnRUcnVlKE1vZGlmaWVyLmlzRmluYWwoTW9kaWZpZXIuRklOQUwpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSghTW9kaWZpZXIuaXNGaW5hbCgtMSAmIH5Nb2RpZmllci5GSU5BTCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNJbnRlcmZhY2VJKCkgeworICAgICAgICBhc3NlcnRUcnVlKE1vZGlmaWVyLmlzSW50ZXJmYWNlKE1vZGlmaWVyLklOVEVSRkFDRSkpOworICAgICAgICBhc3NlcnRUcnVlKCFNb2RpZmllci5pc0ludGVyZmFjZSgtMSAmIH5Nb2RpZmllci5JTlRFUkZBQ0UpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzTmF0aXZlSSgpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShNb2RpZmllci5pc05hdGl2ZShNb2RpZmllci5OQVRJVkUpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSghTW9kaWZpZXIuaXNOYXRpdmUoLTEgJiB+TW9kaWZpZXIuTkFUSVZFKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc1ByaXZhdGVJKCkgeworICAgICAgICBhc3NlcnRUcnVlKE1vZGlmaWVyLmlzUHJpdmF0ZShNb2RpZmllci5QUklWQVRFKSk7CisgICAgICAgIGFzc2VydFRydWUoIU1vZGlmaWVyLmlzUHJpdmF0ZSgtMSAmIH5Nb2RpZmllci5QUklWQVRFKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc1Byb3RlY3RlZEkoKSB7CisgICAgICAgIGFzc2VydFRydWUoTW9kaWZpZXIuaXNQcm90ZWN0ZWQoTW9kaWZpZXIuUFJPVEVDVEVEKSk7CisgICAgICAgIGFzc2VydFRydWUoIU1vZGlmaWVyLmlzUHJvdGVjdGVkKC0xICYgfk1vZGlmaWVyLlBST1RFQ1RFRCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNQdWJsaWNJKCkgeworICAgICAgICBhc3NlcnRUcnVlKE1vZGlmaWVyLmlzUHVibGljKE1vZGlmaWVyLlBVQkxJQykpOworICAgICAgICBhc3NlcnRUcnVlKCFNb2RpZmllci5pc1B1YmxpYygtMSAmIH5Nb2RpZmllci5QVUJMSUMpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzU3RhdGljSSgpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShNb2RpZmllci5pc1N0YXRpYyhNb2RpZmllci5TVEFUSUMpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSghTW9kaWZpZXIuaXNTdGF0aWMoLTEgJiB+TW9kaWZpZXIuU1RBVElDKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc1N0cmljdEkoKSB7CisgICAgICAgIGFzc2VydFRydWUoTW9kaWZpZXIuaXNTdHJpY3QoTW9kaWZpZXIuU1RSSUNUKSk7CisgICAgICAgIGFzc2VydFRydWUoIU1vZGlmaWVyLmlzU3RyaWN0KC0xICYgfk1vZGlmaWVyLlNUUklDVCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNTeW5jaHJvbml6ZWRJKCkgeworICAgICAgICBhc3NlcnRUcnVlKE1vZGlmaWVyLmlzU3luY2hyb25pemVkKE1vZGlmaWVyLlNZTkNIUk9OSVpFRCkpOworICAgICAgICBhc3NlcnRUcnVlKCFNb2RpZmllci5pc1N5bmNocm9uaXplZCgtMSAmIH5Nb2RpZmllci5TWU5DSFJPTklaRUQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzVHJhbnNpZW50SSgpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShNb2RpZmllci5pc1RyYW5zaWVudChNb2RpZmllci5UUkFOU0lFTlQpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSghTW9kaWZpZXIuaXNUcmFuc2llbnQoLTEgJiB+TW9kaWZpZXIuVFJBTlNJRU5UKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc1ZvbGF0aWxlSSgpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShNb2RpZmllci5pc1ZvbGF0aWxlKE1vZGlmaWVyLlZPTEFUSUxFKSk7CisgICAgICAgIGFzc2VydFRydWUoIU1vZGlmaWVyLmlzVm9sYXRpbGUoLTEgJiB+TW9kaWZpZXIuVk9MQVRJTEUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nSSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwdWJsaWMgYWJzdHJhY3QiLCBNb2RpZmllci50b1N0cmluZyhNb2RpZmllci5QVUJMSUMgfCBNb2RpZmllci5BQlNUUkFDVCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L09sZEFuZHJvaWRBcnJheVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L09sZEFuZHJvaWRBcnJheVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMDUzNGE0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL3JlZmxlY3QvT2xkQW5kcm9pZEFycmF5VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTMwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZy5yZWZsZWN0OworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQXJyYXk7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3QgamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkgbWV0aG9kcy4KKyAqLworcHVibGljIGNsYXNzIE9sZEFuZHJvaWRBcnJheVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2luZ2xlSW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdCBpbnRBcnJheSA9IEFycmF5Lm5ld0luc3RhbmNlKEludGVnZXIuVFlQRSwgMik7CisKKyAgICAgICAgaW50W10gYXJyYXkgPSAoaW50W10pIGludEFycmF5OworICAgICAgICBhcnJheVswXSA9IDU7CisgICAgICAgIEFycmF5LnNldEludChpbnRBcnJheSwgMSwgNik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIEFycmF5LmdldEludChpbnRBcnJheSwgMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNiwgYXJyYXlbMV0pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcnJheVsyXSA9IDI3OworICAgICAgICAgICAgZmFpbCgic3RvcmUgc2hvdWxkIGhhdmUgZmFpbGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBhYmUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgYXJyYXkubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5LmdldExlbmd0aChpbnRBcnJheSksIGFycmF5Lmxlbmd0aCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludFtdW10gd3JvbmdBcnJheSA9IChpbnRbXVtdKSBpbnRBcnJheTsKKyAgICAgICAgICAgIGZhaWwoImNhc3Qgc2hvdWxkIGhhdmUgZmFpbGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBjY2UpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBpbnRBcnJheSA9IEFycmF5Lm5ld0luc3RhbmNlKEludGVnZXIuVFlQRSwgMCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBBcnJheS5nZXRMZW5ndGgoaW50QXJyYXkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2luZ2xlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdCBzdHJBcnJheSA9IEFycmF5Lm5ld0luc3RhbmNlKFN0cmluZy5jbGFzcywgMik7CisKKyAgICAgICAgU3RyaW5nW10gYXJyYXkgPSAoU3RyaW5nW10pIHN0ckFycmF5OworICAgICAgICBhcnJheVswXSA9ICJlbnRyeSB6ZXJvIjsKKyAgICAgICAgQXJyYXkuc2V0KHN0ckFycmF5LCAxLCAiZW50cnkgb25lIik7CisKKyAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oImFycmF5OiAiICsgYXJyYXkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiZW50cnkgemVybyIsIEFycmF5LmdldChzdHJBcnJheSwgMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVudHJ5IG9uZSIsIGFycmF5WzFdKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgYXJyYXkubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5LmdldExlbmd0aChzdHJBcnJheSksIGFycmF5Lmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE11bHRpSW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGludFtdIGRpbWVuc2lvbnMgPSB7MywgMiwgMX07CisgICAgICAgIE9iamVjdCBpbnRJbnRJbnRBcnJheSA9IEFycmF5Lm5ld0luc3RhbmNlKEludGVnZXIuVFlQRSwgZGltZW5zaW9ucyk7CisgICAgICAgIGludFtdW11bXSBhcnJheTMgPSAoaW50W11bXVtdKSBpbnRJbnRJbnRBcnJheTsKKworICAgICAgICBhcnJheTNbMF1bMF1bMF0gPSAxMjM7CisgICAgICAgIGFycmF5M1syXVsxXVswXSA9IDQ1NjsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXJyYXkzWzJdWzFdWzFdID0gNzY4OworICAgICAgICAgICAgZmFpbCgic3RvcmUgc2hvdWxkIGhhdmUgZmFpbGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBhYmUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigiYXJyYXkzOiAiICsgYXJyYXkzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TXVsdGkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaW50W10gZGltZW5zaW9ucyA9IHsxLCAyLCAzfTsKKyAgICAgICAgT2JqZWN0IHN0clN0clN0ckFycmF5ID0gQXJyYXkubmV3SW5zdGFuY2UoU3RyaW5nLmNsYXNzLCBkaW1lbnNpb25zKTsKKyAgICAgICAgU3RyaW5nW11bXVtdIGFycmF5MyA9IChTdHJpbmdbXVtdW10pIHN0clN0clN0ckFycmF5OworCisgICAgICAgIGFycmF5M1swXVswXVswXSA9ICJ6ZXJvIHplcm8gemVybyI7CisgICAgICAgIGFycmF5M1swXVsxXVsyXSA9ICJ6ZXJvIG9uZSB0d28iOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcnJheTNbMV1bMF1bMF0gPSAiYmFkIHN0b3JlIjsKKyAgICAgICAgICAgIGZhaWwoInN0b3JlIHNob3VsZCBoYXZlIGZhaWxlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gYWJlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZ1tdW10gYXJyYXkyID0gKFN0cmluZ1tdW10pIHN0clN0clN0ckFycmF5OworICAgICAgICAgICAgZmFpbCgiZXhwZWN0aW5nIGJhZCBjYXN0Iik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBjY2UpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oImFycmF5MzogIiArIGFycmF5Myk7CisKKworICAgICAgICBpbnRbXSBkaW1lbnNpb25zMiA9IHsxLCAyfTsKKyAgICAgICAgc3RyU3RyU3RyQXJyYXkgPSBBcnJheS5uZXdJbnN0YW5jZShTdHJpbmdbXS5jbGFzcywgZGltZW5zaW9uczIpOworICAgICAgICBhcnJheTMgPSAoU3RyaW5nW11bXVtdKSBzdHJTdHJTdHJBcnJheTsKKyAgICAgICAgYXJyYXkzWzBdWzFdID0gbmV3IFN0cmluZ1szXTsKKyAgICAgICAgYXJyYXkzWzBdWzFdWzJdID0gInplcm8gb25lIHR3byI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcnJheTNbMV1bMF1bMF0gPSAiYmFkIHN0b3JlIjsKKyAgICAgICAgICAgIGZhaWwoInN0b3JlIHNob3VsZCBoYXZlIGZhaWxlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gYWJlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJhcnJheTM6ICIgKyBhcnJheTMpOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL3JlZmxlY3QvT2xkR2VuZXJpY1JlZmxlY3Rpb25Db3JuZXJDYXNlcy5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL3JlZmxlY3QvT2xkR2VuZXJpY1JlZmxlY3Rpb25Db3JuZXJDYXNlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkwN2I4ZWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2xhbmcvcmVmbGVjdC9PbGRHZW5lcmljUmVmbGVjdGlvbkNvcm5lckNhc2VzLmphdmEKQEAgLTAsMCArMSwyMjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5Lbm93bkZhaWx1cmU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlBhcmFtZXRlcml6ZWRUeXBlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVHlwZVZhcmlhYmxlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LldpbGRjYXJkVHlwZTsKK2ltcG9ydCB0ZXN0cy5hcGkuamF2YS5sYW5nLnJlZmxlY3QuR2VuZXJpY1JlZmxlY3Rpb25UZXN0c0Jhc2U7CisKKy8qKgorICogVGVzdHMgZ2VuZXJpYyByZWZsZWN0aW9uIGluIG1vcmUgY29tcGxpY2F0ZWQgY2FzZXMuIEluIHBhcnRpY3VsYXI6IFNjb3Bpbmcgb2YKKyAqIHR5cGUgcGFyYW1ldGVycywgZXF1YWxpdHkgb2YgdHlwZSBwYXJhbWV0ZXJzLCB3aWxkY2FyZCB0eXBlcywgcGFyYW1ldGVyaXplZAorICogdHlwZXMgYW5kIG11bHRpcGxlIGJvdW5kcy4KKyAqLworcHVibGljIGNsYXNzIE9sZEdlbmVyaWNSZWZsZWN0aW9uQ29ybmVyQ2FzZXMgZXh0ZW5kcyBHZW5lcmljUmVmbGVjdGlvblRlc3RzQmFzZSB7CisKKyAgICBzdGF0aWMgY2xhc3MgUGFpcjxULCBTPiB7fQorCisgICAgc3RhdGljIGNsYXNzIFdpbGRjYXJkRXF1YWxpdHk8VD4geworICAgICAgICB2b2lkIHdpbGRjYXJkRXF1YWxpdHkoUGFpcjw/IGV4dGVuZHMgVCwgPyBleHRlbmRzIFQ+IHBhcmFtKSB7fQorICAgIH0KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V2lsZGNhcmRFcXVhbGl0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDbGFzczw/IGV4dGVuZHMgV2lsZGNhcmRFcXVhbGl0eT4gY2xhenogPSBXaWxkY2FyZEVxdWFsaXR5LmNsYXNzOworCisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBjbGF6ei5nZXREZWNsYXJlZE1ldGhvZCgid2lsZGNhcmRFcXVhbGl0eSIsIFBhaXIuY2xhc3MpOworICAgICAgICBUeXBlVmFyaWFibGU8Pz5bXSB0eXBlUGFyYW1ldGVycyA9IGNsYXp6LmdldFR5cGVQYXJhbWV0ZXJzKCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZSh0eXBlUGFyYW1ldGVycyk7CisgICAgICAgIFR5cGVWYXJpYWJsZTw/PiB0eXBlUGFyYW1ldGVyID0gdHlwZVBhcmFtZXRlcnNbMF07CisKKyAgICAgICAgVHlwZVtdIHBhcmFtZXRlclR5cGVzID0gbWV0aG9kLmdldEdlbmVyaWNQYXJhbWV0ZXJUeXBlcygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUocGFyYW1ldGVyVHlwZXMpOworICAgICAgICBUeXBlIHBhcmFtZXRlciA9IHBhcmFtZXRlclR5cGVzWzBdOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKFBhcmFtZXRlcml6ZWRUeXBlLmNsYXNzLCBwYXJhbWV0ZXIpOworICAgICAgICBQYXJhbWV0ZXJpemVkVHlwZSBwYXJhbVR5cGUgPSAoUGFyYW1ldGVyaXplZFR5cGUpIHBhcmFtZXRlcjsKKyAgICAgICAgVHlwZVtdIGFjdHVhbFR5cGVBcmd1bWVudHMgPSBwYXJhbVR5cGUuZ2V0QWN0dWFsVHlwZUFyZ3VtZW50cygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgYWN0dWFsVHlwZUFyZ3VtZW50cy5sZW5ndGgpOworCisgICAgICAgIFR5cGUgZmlyc3RBcmd1bWVudCA9IGFjdHVhbFR5cGVBcmd1bWVudHNbMF07CisgICAgICAgIGFzc2VydEluc3RhbmNlT2YoV2lsZGNhcmRUeXBlLmNsYXNzLCBmaXJzdEFyZ3VtZW50KTsKKyAgICAgICAgV2lsZGNhcmRUeXBlIGZpcnN0V2lsZGNhcmRBcmd1bWVudCA9IChXaWxkY2FyZFR5cGUpIGZpcnN0QXJndW1lbnQ7CisgICAgICAgIFR5cGUgc2Vjb25kQXJndW1lbnQgPSBhY3R1YWxUeXBlQXJndW1lbnRzWzFdOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKFdpbGRjYXJkVHlwZS5jbGFzcywgc2Vjb25kQXJndW1lbnQpOworICAgICAgICBXaWxkY2FyZFR5cGUgc2Vjb25kV2lsZGNhcmRBcmd1bWVudCA9IChXaWxkY2FyZFR5cGUpIHNlY29uZEFyZ3VtZW50OworCisgICAgICAgIGFzc2VydEVxdWFscyhmaXJzdFdpbGRjYXJkQXJndW1lbnQsIHNlY29uZFdpbGRjYXJkQXJndW1lbnQpOworCisgICAgICAgIFR5cGVbXSBmaXJzdFdpbGRjYXJkQXJndW1lbnRVcHBlckJvdW5kcyA9IGZpcnN0V2lsZGNhcmRBcmd1bWVudC5nZXRVcHBlckJvdW5kcygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUoZmlyc3RXaWxkY2FyZEFyZ3VtZW50VXBwZXJCb3VuZHMpOworICAgICAgICBUeXBlIGZpcnN0V2lsZGNhcmRBcmd1bWVudFVwcGVyQm91bmRzVHlwZSA9IGZpcnN0V2lsZGNhcmRBcmd1bWVudFVwcGVyQm91bmRzWzBdOworCisgICAgICAgIFR5cGVbXSBzZWNvbmRXaWxkY2FyZEFyZ3VtZW50VXBwZXJCb3VuZHMgPSBzZWNvbmRXaWxkY2FyZEFyZ3VtZW50LmdldFVwcGVyQm91bmRzKCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZShzZWNvbmRXaWxkY2FyZEFyZ3VtZW50VXBwZXJCb3VuZHMpOworICAgICAgICBUeXBlIHNlY29uZFdpbGRjYXJkQXJndW1lbnRVcHBlckJvdW5kc1R5cGUgPSBzZWNvbmRXaWxkY2FyZEFyZ3VtZW50VXBwZXJCb3VuZHNbMF07CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZpcnN0V2lsZGNhcmRBcmd1bWVudFVwcGVyQm91bmRzVHlwZSwgc2Vjb25kV2lsZGNhcmRBcmd1bWVudFVwcGVyQm91bmRzVHlwZSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHR5cGVQYXJhbWV0ZXIsIGZpcnN0V2lsZGNhcmRBcmd1bWVudFVwcGVyQm91bmRzVHlwZSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0eXBlUGFyYW1ldGVyLCBzZWNvbmRXaWxkY2FyZEFyZ3VtZW50VXBwZXJCb3VuZHNUeXBlKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgV2lsZGNhcmRVbkVxdWFsaXR5PFQ+IHsKKyAgICAgICAgdm9pZCB3aWxkY2FyZFVuRXF1YWxpdHkoUGFpcjw/IGV4dGVuZHMgVCwgPyBzdXBlciBUPiBwYXJhbSkge30KKyAgICB9CisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdFdpbGRjYXJkVW5FcXVhbGl0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDbGFzczw/IGV4dGVuZHMgV2lsZGNhcmRVbkVxdWFsaXR5PiBjbGF6eiA9IFdpbGRjYXJkVW5FcXVhbGl0eS5jbGFzczsKKworICAgICAgICBNZXRob2QgbWV0aG9kID0gY2xhenouZ2V0RGVjbGFyZWRNZXRob2QoIndpbGRjYXJkVW5FcXVhbGl0eSIsIFBhaXIuY2xhc3MpOworICAgICAgICBUeXBlVmFyaWFibGU8Pz5bXSB0eXBlUGFyYW1ldGVycyA9IGNsYXp6LmdldFR5cGVQYXJhbWV0ZXJzKCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZSh0eXBlUGFyYW1ldGVycyk7CisgICAgICAgIFR5cGVWYXJpYWJsZTw/PiB0eXBlUGFyYW1ldGVyID0gdHlwZVBhcmFtZXRlcnNbMF07CisKKyAgICAgICAgVHlwZVtdIHBhcmFtZXRlclR5cGVzID0gbWV0aG9kLmdldEdlbmVyaWNQYXJhbWV0ZXJUeXBlcygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUocGFyYW1ldGVyVHlwZXMpOworICAgICAgICBUeXBlIHBhcmFtZXRlciA9IHBhcmFtZXRlclR5cGVzWzBdOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKFBhcmFtZXRlcml6ZWRUeXBlLmNsYXNzLCBwYXJhbWV0ZXIpOworICAgICAgICBQYXJhbWV0ZXJpemVkVHlwZSBwYXJhbVR5cGUgPSAoUGFyYW1ldGVyaXplZFR5cGUpIHBhcmFtZXRlcjsKKyAgICAgICAgVHlwZVtdIGFjdHVhbFR5cGVBcmd1bWVudHMgPSBwYXJhbVR5cGUuZ2V0QWN0dWFsVHlwZUFyZ3VtZW50cygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgYWN0dWFsVHlwZUFyZ3VtZW50cy5sZW5ndGgpOworCisgICAgICAgIFR5cGUgZmlyc3RBcmd1bWVudCA9IGFjdHVhbFR5cGVBcmd1bWVudHNbMF07CisgICAgICAgIGFzc2VydEluc3RhbmNlT2YoV2lsZGNhcmRUeXBlLmNsYXNzLCBmaXJzdEFyZ3VtZW50KTsKKyAgICAgICAgV2lsZGNhcmRUeXBlIGZpcnN0V2lsZGNhcmRBcmd1bWVudCA9IChXaWxkY2FyZFR5cGUpIGZpcnN0QXJndW1lbnQ7CisgICAgICAgIFR5cGUgc2Vjb25kQXJndW1lbnQgPSBhY3R1YWxUeXBlQXJndW1lbnRzWzFdOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKFdpbGRjYXJkVHlwZS5jbGFzcywgc2Vjb25kQXJndW1lbnQpOworICAgICAgICBXaWxkY2FyZFR5cGUgc2Vjb25kV2lsZGNhcmRBcmd1bWVudCA9IChXaWxkY2FyZFR5cGUpIHNlY29uZEFyZ3VtZW50OworCisgICAgICAgIGFzc2VydE5vdEVxdWFscyhmaXJzdFdpbGRjYXJkQXJndW1lbnQsIHNlY29uZFdpbGRjYXJkQXJndW1lbnQpOworCisgICAgICAgIFR5cGVbXSBmaXJzdFdpbGRjYXJkQXJndW1lbnRVcHBlckJvdW5kcyA9IGZpcnN0V2lsZGNhcmRBcmd1bWVudC5nZXRVcHBlckJvdW5kcygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUoZmlyc3RXaWxkY2FyZEFyZ3VtZW50VXBwZXJCb3VuZHMpOworICAgICAgICBUeXBlIGZpcnN0V2lsZGNhcmRBcmd1bWVudFVwcGVyQm91bmRzVHlwZSA9IGZpcnN0V2lsZGNhcmRBcmd1bWVudFVwcGVyQm91bmRzWzBdOworCisgICAgICAgIFR5cGVbXSBzZWNvbmRXaWxkY2FyZEFyZ3VtZW50TG93ZXJCb3VuZHMgPSBzZWNvbmRXaWxkY2FyZEFyZ3VtZW50LmdldExvd2VyQm91bmRzKCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZShzZWNvbmRXaWxkY2FyZEFyZ3VtZW50TG93ZXJCb3VuZHMpOworICAgICAgICBUeXBlIHNlY29uZFdpbGRjYXJkQXJndW1lbnRMb3dlcm91bmRzVHlwZSA9IHNlY29uZFdpbGRjYXJkQXJndW1lbnRMb3dlckJvdW5kc1swXTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoZmlyc3RXaWxkY2FyZEFyZ3VtZW50VXBwZXJCb3VuZHNUeXBlLCBzZWNvbmRXaWxkY2FyZEFyZ3VtZW50TG93ZXJvdW5kc1R5cGUpOworICAgICAgICBhc3NlcnRFcXVhbHModHlwZVBhcmFtZXRlciwgZmlyc3RXaWxkY2FyZEFyZ3VtZW50VXBwZXJCb3VuZHNUeXBlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHR5cGVQYXJhbWV0ZXIsIHNlY29uZFdpbGRjYXJkQXJndW1lbnRMb3dlcm91bmRzVHlwZSk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIE11bHRpcGxlQm91bmRlZFdpbGRjYXJkVW5FcXVhbGl0eTxUIGV4dGVuZHMgT2JqZWN0ICYgQ29tcGFyYWJsZTxNdWx0aXBsZUJvdW5kZWRXaWxkY2FyZFVuRXF1YWxpdHk8VD4+PiB7CisgICAgICAgIHZvaWQgbXVsdGlwbGVCb3VuZGVkV2lsZGNhcmRVbkVxdWFsaXR5KFBhaXI8PyBleHRlbmRzIFQsID8gc3VwZXIgVD4gcGFyYW0pIHt9CisgICAgfQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIEBLbm93bkZhaWx1cmUoIkZhaWxzIGluIENUUyBidXQgcGFzc2VzIHVuZGVyIHJ1bi1jb3JlLXRlc3RzIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TXVsdGlwbGVCb3VuZGVkV2lsZGNhcmRVbkVxdWFsaXR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBNdWx0aXBsZUJvdW5kZWRXaWxkY2FyZFVuRXF1YWxpdHk+IGNsYXp6ID0gTXVsdGlwbGVCb3VuZGVkV2lsZGNhcmRVbkVxdWFsaXR5LmNsYXNzOworCisgICAgICAgIC8vIG5ldyBXaWxkY2FyZEVxdWFsaXR5PE9iamVjdD4oKS53aWxkY2FyZEVxdWFsaXR5KG5ldyBQYWlyPFN0cmluZywKKyAgICAgICAgLy8gSW50ZWdlcj4oKSk7CisKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IGNsYXp6LmdldERlY2xhcmVkTWV0aG9kKCJtdWx0aXBsZUJvdW5kZWRXaWxkY2FyZFVuRXF1YWxpdHkiLCBQYWlyLmNsYXNzKTsKKyAgICAgICAgVHlwZVZhcmlhYmxlPD8+W10gdHlwZVBhcmFtZXRlcnMgPSBjbGF6ei5nZXRUeXBlUGFyYW1ldGVycygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUodHlwZVBhcmFtZXRlcnMpOworICAgICAgICBUeXBlVmFyaWFibGU8Pz4gdHlwZVBhcmFtZXRlciA9IHR5cGVQYXJhbWV0ZXJzWzBdOworICAgICAgICBUeXBlW10gdHlwZVBhcmFtZXRlckJvdW5kcyA9IHR5cGVQYXJhbWV0ZXIuZ2V0Qm91bmRzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCB0eXBlUGFyYW1ldGVyQm91bmRzLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscyhPYmplY3QuY2xhc3MsIHR5cGVQYXJhbWV0ZXJCb3VuZHNbMF0pOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKFBhcmFtZXRlcml6ZWRUeXBlLmNsYXNzLCB0eXBlUGFyYW1ldGVyQm91bmRzWzFdKTsKKyAgICAgICAgUGFyYW1ldGVyaXplZFR5cGUgcGFyYW1ldGVyaXplZFR5cGUgPSAoUGFyYW1ldGVyaXplZFR5cGUpIHR5cGVQYXJhbWV0ZXJCb3VuZHNbMV07CisgICAgICAgIGFzc2VydEVxdWFscyhDb21wYXJhYmxlLmNsYXNzLCBwYXJhbWV0ZXJpemVkVHlwZS5nZXRSYXdUeXBlKCkpOworICAgICAgICBUeXBlW10gdHlwZUFyZ3VtZW50cyA9IHBhcmFtZXRlcml6ZWRUeXBlLmdldEFjdHVhbFR5cGVBcmd1bWVudHMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKHR5cGVBcmd1bWVudHMpOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKFBhcmFtZXRlcml6ZWRUeXBlLmNsYXNzLCB0eXBlQXJndW1lbnRzWzBdKTsKKyAgICAgICAgUGFyYW1ldGVyaXplZFR5cGUgdHlwZSA9IChQYXJhbWV0ZXJpemVkVHlwZSkgdHlwZUFyZ3VtZW50c1swXTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHR5cGVQYXJhbWV0ZXIsIHR5cGUuZ2V0QWN0dWFsVHlwZUFyZ3VtZW50cygpWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE11bHRpcGxlQm91bmRlZFdpbGRjYXJkVW5FcXVhbGl0eS5jbGFzcywgdHlwZS5nZXRSYXdUeXBlKCkpOworCisgICAgICAgIFR5cGVbXSBwYXJhbWV0ZXJUeXBlcyA9IG1ldGhvZC5nZXRHZW5lcmljUGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKHBhcmFtZXRlclR5cGVzKTsKKyAgICAgICAgVHlwZSBwYXJhbWV0ZXIgPSBwYXJhbWV0ZXJUeXBlc1swXTsKKyAgICAgICAgYXNzZXJ0SW5zdGFuY2VPZihQYXJhbWV0ZXJpemVkVHlwZS5jbGFzcywgcGFyYW1ldGVyKTsKKyAgICAgICAgUGFyYW1ldGVyaXplZFR5cGUgcGFyYW1UeXBlID0gKFBhcmFtZXRlcml6ZWRUeXBlKSBwYXJhbWV0ZXI7CisgICAgICAgIFR5cGVbXSBhY3R1YWxUeXBlQXJndW1lbnRzID0gcGFyYW1UeXBlLmdldEFjdHVhbFR5cGVBcmd1bWVudHMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGFjdHVhbFR5cGVBcmd1bWVudHMubGVuZ3RoKTsKKworICAgICAgICBUeXBlIGZpcnN0QXJndW1lbnQgPSBhY3R1YWxUeXBlQXJndW1lbnRzWzBdOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKFdpbGRjYXJkVHlwZS5jbGFzcywgZmlyc3RBcmd1bWVudCk7CisgICAgICAgIFdpbGRjYXJkVHlwZSBmaXJzdFdpbGRjYXJkQXJndW1lbnQgPSAoV2lsZGNhcmRUeXBlKSBmaXJzdEFyZ3VtZW50OworICAgICAgICBUeXBlIHNlY29uZEFyZ3VtZW50ID0gYWN0dWFsVHlwZUFyZ3VtZW50c1sxXTsKKyAgICAgICAgYXNzZXJ0SW5zdGFuY2VPZihXaWxkY2FyZFR5cGUuY2xhc3MsIHNlY29uZEFyZ3VtZW50KTsKKyAgICAgICAgV2lsZGNhcmRUeXBlIHNlY29uZFdpbGRjYXJkQXJndW1lbnQgPSAoV2lsZGNhcmRUeXBlKSBzZWNvbmRBcmd1bWVudDsKKworICAgICAgICBhc3NlcnROb3RFcXVhbHMoZmlyc3RXaWxkY2FyZEFyZ3VtZW50LCBzZWNvbmRXaWxkY2FyZEFyZ3VtZW50KTsKKworICAgICAgICBUeXBlW10gZmlyc3RXaWxkY2FyZEFyZ3VtZW50VXBwZXJCb3VuZHMgPSBmaXJzdFdpbGRjYXJkQXJndW1lbnQuZ2V0VXBwZXJCb3VuZHMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGZpcnN0V2lsZGNhcmRBcmd1bWVudFVwcGVyQm91bmRzKTsKKyAgICAgICAgVHlwZSBmaXJzdFdpbGRjYXJkQXJndW1lbnRVcHBlckJvdW5kc1R5cGUgPSBmaXJzdFdpbGRjYXJkQXJndW1lbnRVcHBlckJvdW5kc1swXTsKKworICAgICAgICBUeXBlW10gc2Vjb25kV2lsZGNhcmRBcmd1bWVudExvd2VyQm91bmRzID0gc2Vjb25kV2lsZGNhcmRBcmd1bWVudC5nZXRMb3dlckJvdW5kcygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUoc2Vjb25kV2lsZGNhcmRBcmd1bWVudExvd2VyQm91bmRzKTsKKyAgICAgICAgVHlwZSBzZWNvbmRXaWxkY2FyZEFyZ3VtZW50TG93ZXJvdW5kc1R5cGUgPSBzZWNvbmRXaWxkY2FyZEFyZ3VtZW50TG93ZXJCb3VuZHNbMF07CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZpcnN0V2lsZGNhcmRBcmd1bWVudFVwcGVyQm91bmRzVHlwZSwgc2Vjb25kV2lsZGNhcmRBcmd1bWVudExvd2Vyb3VuZHNUeXBlKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgTXVsdGlwbGVCb3VuZGVkV2lsZGNhcmRFcXVhbGl0eTxUIGV4dGVuZHMgT2JqZWN0ICYgQ29tcGFyYWJsZTxNdWx0aXBsZUJvdW5kZWRXaWxkY2FyZEVxdWFsaXR5PFQ+Pj4geworICAgICAgICB2b2lkIG11bHRpcGxlQm91bmRlZFdpbGRjYXJkRXF1YWxpdHkoUGFpcjw/IGV4dGVuZHMgVCwgPyBleHRlbmRzIFQ+IHBhcmFtKSB7fQorICAgIH0KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBAS25vd25GYWlsdXJlKCJGYWlscyBpbiBDVFMgYnV0IHBhc3NlcyB1bmRlciBydW4tY29yZS10ZXN0cyIpCisgICAgcHVibGljIHZvaWQgdGVzdE11bHRpcGxlQm91bmRlZFdpbGRjYXJkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBNdWx0aXBsZUJvdW5kZWRXaWxkY2FyZEVxdWFsaXR5PiBjbGF6eiA9IE11bHRpcGxlQm91bmRlZFdpbGRjYXJkRXF1YWxpdHkuY2xhc3M7CisKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IGNsYXp6LmdldERlY2xhcmVkTWV0aG9kKCJtdWx0aXBsZUJvdW5kZWRXaWxkY2FyZEVxdWFsaXR5IiwgUGFpci5jbGFzcyk7CisgICAgICAgIFR5cGVWYXJpYWJsZTw/PltdIHR5cGVQYXJhbWV0ZXJzID0gY2xhenouZ2V0VHlwZVBhcmFtZXRlcnMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKHR5cGVQYXJhbWV0ZXJzKTsKKyAgICAgICAgVHlwZVZhcmlhYmxlPD8+IHR5cGVQYXJhbWV0ZXIgPSB0eXBlUGFyYW1ldGVyc1swXTsKKyAgICAgICAgVHlwZVtdIHR5cGVQYXJhbWV0ZXJCb3VuZHMgPSB0eXBlUGFyYW1ldGVyLmdldEJvdW5kcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgdHlwZVBhcmFtZXRlckJvdW5kcy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoT2JqZWN0LmNsYXNzLCB0eXBlUGFyYW1ldGVyQm91bmRzWzBdKTsKKyAgICAgICAgYXNzZXJ0SW5zdGFuY2VPZihQYXJhbWV0ZXJpemVkVHlwZS5jbGFzcywgdHlwZVBhcmFtZXRlckJvdW5kc1sxXSk7CisgICAgICAgIFBhcmFtZXRlcml6ZWRUeXBlIHBhcmFtZXRlcml6ZWRUeXBlID0gKFBhcmFtZXRlcml6ZWRUeXBlKSB0eXBlUGFyYW1ldGVyQm91bmRzWzFdOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29tcGFyYWJsZS5jbGFzcywgcGFyYW1ldGVyaXplZFR5cGUuZ2V0UmF3VHlwZSgpKTsKKyAgICAgICAgVHlwZVtdIHR5cGVBcmd1bWVudHMgPSBwYXJhbWV0ZXJpemVkVHlwZS5nZXRBY3R1YWxUeXBlQXJndW1lbnRzKCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZSh0eXBlQXJndW1lbnRzKTsKKyAgICAgICAgYXNzZXJ0SW5zdGFuY2VPZihQYXJhbWV0ZXJpemVkVHlwZS5jbGFzcywgdHlwZUFyZ3VtZW50c1swXSk7CisgICAgICAgIFBhcmFtZXRlcml6ZWRUeXBlIHR5cGUgPSAoUGFyYW1ldGVyaXplZFR5cGUpIHR5cGVBcmd1bWVudHNbMF07CisgICAgICAgIGFzc2VydEVxdWFscyh0eXBlUGFyYW1ldGVyLCB0eXBlLmdldEFjdHVhbFR5cGVBcmd1bWVudHMoKVswXSk7CisgICAgICAgIGFzc2VydEVxdWFscyhNdWx0aXBsZUJvdW5kZWRXaWxkY2FyZEVxdWFsaXR5LmNsYXNzLCB0eXBlLmdldFJhd1R5cGUoKSk7CisKKyAgICAgICAgVHlwZVtdIHBhcmFtZXRlclR5cGVzID0gbWV0aG9kLmdldEdlbmVyaWNQYXJhbWV0ZXJUeXBlcygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUocGFyYW1ldGVyVHlwZXMpOworICAgICAgICBUeXBlIHBhcmFtZXRlciA9IHBhcmFtZXRlclR5cGVzWzBdOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKFBhcmFtZXRlcml6ZWRUeXBlLmNsYXNzLCBwYXJhbWV0ZXIpOworICAgICAgICBQYXJhbWV0ZXJpemVkVHlwZSBwYXJhbVR5cGUgPSAoUGFyYW1ldGVyaXplZFR5cGUpIHBhcmFtZXRlcjsKKyAgICAgICAgVHlwZVtdIGFjdHVhbFR5cGVBcmd1bWVudHMgPSBwYXJhbVR5cGUuZ2V0QWN0dWFsVHlwZUFyZ3VtZW50cygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgYWN0dWFsVHlwZUFyZ3VtZW50cy5sZW5ndGgpOworCisgICAgICAgIFR5cGUgZmlyc3RBcmd1bWVudCA9IGFjdHVhbFR5cGVBcmd1bWVudHNbMF07CisgICAgICAgIGFzc2VydEluc3RhbmNlT2YoV2lsZGNhcmRUeXBlLmNsYXNzLCBmaXJzdEFyZ3VtZW50KTsKKyAgICAgICAgV2lsZGNhcmRUeXBlIGZpcnN0V2lsZGNhcmRBcmd1bWVudCA9IChXaWxkY2FyZFR5cGUpIGZpcnN0QXJndW1lbnQ7CisgICAgICAgIFR5cGUgc2Vjb25kQXJndW1lbnQgPSBhY3R1YWxUeXBlQXJndW1lbnRzWzFdOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKFdpbGRjYXJkVHlwZS5jbGFzcywgc2Vjb25kQXJndW1lbnQpOworICAgICAgICBXaWxkY2FyZFR5cGUgc2Vjb25kV2lsZGNhcmRBcmd1bWVudCA9IChXaWxkY2FyZFR5cGUpIHNlY29uZEFyZ3VtZW50OworCisgICAgICAgIGFzc2VydEVxdWFscyhmaXJzdFdpbGRjYXJkQXJndW1lbnQsIHNlY29uZFdpbGRjYXJkQXJndW1lbnQpOworCisgICAgICAgIFR5cGVbXSBmaXJzdFdpbGRjYXJkQXJndW1lbnRVcHBlckJvdW5kcyA9IGZpcnN0V2lsZGNhcmRBcmd1bWVudC5nZXRVcHBlckJvdW5kcygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUoZmlyc3RXaWxkY2FyZEFyZ3VtZW50VXBwZXJCb3VuZHMpOworICAgICAgICBUeXBlIGZpcnN0V2lsZGNhcmRBcmd1bWVudFVwcGVyQm91bmRzVHlwZSA9IGZpcnN0V2lsZGNhcmRBcmd1bWVudFVwcGVyQm91bmRzWzBdOworCisgICAgICAgIFR5cGVbXSBzZWNvbmRXaWxkY2FyZEFyZ3VtZW50VXBwZXJCb3VuZHMgPSBzZWNvbmRXaWxkY2FyZEFyZ3VtZW50LmdldFVwcGVyQm91bmRzKCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZShzZWNvbmRXaWxkY2FyZEFyZ3VtZW50VXBwZXJCb3VuZHMpOworICAgICAgICBUeXBlIHNlY29uZFdpbGRjYXJkQXJndW1lbnRMb3dlcm91bmRzVHlwZSA9IHNlY29uZFdpbGRjYXJkQXJndW1lbnRVcHBlckJvdW5kc1swXTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoZmlyc3RXaWxkY2FyZEFyZ3VtZW50VXBwZXJCb3VuZHNUeXBlLCBzZWNvbmRXaWxkY2FyZEFyZ3VtZW50TG93ZXJvdW5kc1R5cGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L09sZEdlbmVyaWNUeXBlc1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L09sZEdlbmVyaWNUeXBlc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOTNiNjgzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL3JlZmxlY3QvT2xkR2VuZXJpY1R5cGVzVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjM3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubGFuZy5yZWZsZWN0OworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uS25vd25GYWlsdXJlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5QYXJhbWV0ZXJpemVkVHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5UeXBlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGVWYXJpYWJsZTsKK2ltcG9ydCB0ZXN0cy5hcGkuamF2YS5sYW5nLnJlZmxlY3QuR2VuZXJpY1JlZmxlY3Rpb25UZXN0c0Jhc2U7CisKKworLyoqCisgKiBUZXN0cyB0eXBlIHBhcmFtZXRlcnMgZGVjbGFyZWQgb24gY2xhc3Nlcy4KKyAqLworcHVibGljIGNsYXNzIE9sZEdlbmVyaWNUeXBlc1Rlc3QgZXh0ZW5kcyBHZW5lcmljUmVmbGVjdGlvblRlc3RzQmFzZSB7CisKKyAgICBzdGF0aWMgY2xhc3MgR2VuZXJpY1R5cGU8VD57CisgICAgICAgIFQgbWV0aG9kR2VuZXJpY1R5cGUoVCB0KXsgcmV0dXJuIHQ7fQorICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygiaGlkaW5nIikKKyAgICAgICAgPFQ+IFQgaGlkaW5nTWV0aG9kR2VuZXJpY1R5cGUoVCB0KXsgcmV0dXJuIHQ7fQorICAgICAgICBzdGF0aWMgPFQ+IFQgc3RhdGljTWV0aG9kR2VuZXJpY1R5cGUoVCB0KXsgcmV0dXJuIHQ7fQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBNdWx0aXBsZUJvdW5kZWRHZW5lcmljVHlwZXM8VCxTIGV4dGVuZHMgVD57CisgICAgICAgIHZvaWQgbXVsdGlwbGVCb3VuZGVkR2VuZXJpY1R5cGVzVFMoVCB0LCBTIHMpe30KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgU2ltcGxlSW5oZXJpdGFuY2UgPFQ+IGV4dGVuZHMgR2VuZXJpY1R5cGU8VD57fQorCisgICAgc3RhdGljIGNsYXNzIENvbnN0cnVjdG9yR2VuZXJpY1R5cGU8VD57CisgICAgICAgIENvbnN0cnVjdG9yR2VuZXJpY1R5cGUoVCB0KXt9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIElubmVyQ2xhc3NUZXN0PFQ+eworICAgICAgICBjbGFzcyBJbm5lckNsYXNzIHsKKyAgICAgICAgICAgIElubmVyQ2xhc3MoVCB0KSB7fQorICAgICAgICAgICAgdm9pZCBpbm5lck1ldGhvZChUIHQpe30KKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBFeGNlcHRpb25UZXN0PFQgZXh0ZW5kcyBFeGNlcHRpb24+eworICAgICAgICB2b2lkIGV4Y2VwdGlvblRlc3QoKSB0aHJvd3MgVHt9CisgICAgICAgIGNsYXNzIElubmVyQ2xhc3N7CisgICAgICAgICAgICB2b2lkIGlubmVyRXhjZXB0aW9uVGVzdCgpIHRocm93cyBUe30KKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBpbnRlcmZhY2UgSW50ZXJmYWNlVGVzdDxUPnt9CisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdG9yR2VuZXJpY1R5cGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2xhc3M8PyBleHRlbmRzIENvbnN0cnVjdG9yR2VuZXJpY1R5cGU+IGNsYXp6ID0gQ29uc3RydWN0b3JHZW5lcmljVHlwZS5jbGFzczsKKyAgICAgICAgVHlwZVZhcmlhYmxlPENsYXNzPiB0eXBlVmFyaWFibGUgPSBnZXRUeXBlUGFyYW1ldGVyKGNsYXp6KTsKKyAgICAgICAgQ29uc3RydWN0b3I8Pz4gY29uc3RydWN0b3IgPSBjbGF6ei5nZXREZWNsYXJlZENvbnN0cnVjdG9yKE9iamVjdC5jbGFzcyk7CisgICAgICAgIFR5cGVbXSBnZW5lcmljUGFyYW1ldGVyVHlwZXMgPSBjb25zdHJ1Y3Rvci5nZXRHZW5lcmljUGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGdlbmVyaWNQYXJhbWV0ZXJUeXBlcyk7CisgICAgICAgIFR5cGUgcGFyYW1ldGVyVHlwZSA9IGdlbmVyaWNQYXJhbWV0ZXJUeXBlc1swXTsKKworICAgICAgICBhc3NlcnRFcXVhbHModHlwZVZhcmlhYmxlLCBwYXJhbWV0ZXJUeXBlKTsKKyAgICB9CisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdFN0YXRpY01ldGhvZEdlbmVyaWNUeXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBHZW5lcmljVHlwZT4gY2xhenogPSBHZW5lcmljVHlwZS5jbGFzczsKKyAgICAgICAgVHlwZVZhcmlhYmxlPENsYXNzPiB0eXBlVmFyaWFibGUgPSBnZXRUeXBlUGFyYW1ldGVyKGNsYXp6KTsKKworICAgICAgICBNZXRob2QgbWV0aG9kID0gY2xhenouZ2V0RGVjbGFyZWRNZXRob2QoInN0YXRpY01ldGhvZEdlbmVyaWNUeXBlIiwgT2JqZWN0LmNsYXNzKTsKKyAgICAgICAgVHlwZVtdIGdlbmVyaWNQYXJhbWV0ZXJUeXBlcyA9IG1ldGhvZC5nZXRHZW5lcmljUGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGdlbmVyaWNQYXJhbWV0ZXJUeXBlcyk7CisgICAgICAgIFR5cGUgcGFyYW1ldGVyVHlwZSA9IGdlbmVyaWNQYXJhbWV0ZXJUeXBlc1swXTsKKyAgICAgICAgYXNzZXJ0Tm90RXF1YWxzKHR5cGVWYXJpYWJsZSwgcGFyYW1ldGVyVHlwZSk7CisgICAgICAgIGFzc2VydEluc3RhbmNlT2YoVHlwZVZhcmlhYmxlLmNsYXNzLCBwYXJhbWV0ZXJUeXBlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1ldGhvZCwgKChUeXBlVmFyaWFibGUpcGFyYW1ldGVyVHlwZSkuZ2V0R2VuZXJpY0RlY2xhcmF0aW9uKCkpOworICAgIH0KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGlkaW5nTWV0aG9kR2VuZXJpY1R5cGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2xhc3M8PyBleHRlbmRzIEdlbmVyaWNUeXBlPiBjbGF6eiA9IEdlbmVyaWNUeXBlLmNsYXNzOworICAgICAgICBUeXBlVmFyaWFibGU8Q2xhc3M+IHR5cGVWYXJpYWJsZSA9IGdldFR5cGVQYXJhbWV0ZXIoY2xhenopOworCisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBjbGF6ei5nZXREZWNsYXJlZE1ldGhvZCgiaGlkaW5nTWV0aG9kR2VuZXJpY1R5cGUiLCAgT2JqZWN0LmNsYXNzKTsKKyAgICAgICAgVHlwZVtdIGdlbmVyaWNQYXJhbWV0ZXJUeXBlcyA9IG1ldGhvZC5nZXRHZW5lcmljUGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGdlbmVyaWNQYXJhbWV0ZXJUeXBlcyk7CisgICAgICAgIFR5cGUgcGFyYW1ldGVyVHlwZSA9IGdlbmVyaWNQYXJhbWV0ZXJUeXBlc1swXTsKKyAgICAgICAgYXNzZXJ0Tm90RXF1YWxzKHR5cGVWYXJpYWJsZSwgcGFyYW1ldGVyVHlwZSk7CisgICAgICAgIGFzc2VydEluc3RhbmNlT2YoVHlwZVZhcmlhYmxlLmNsYXNzLCBwYXJhbWV0ZXJUeXBlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1ldGhvZCwgKChUeXBlVmFyaWFibGUpcGFyYW1ldGVyVHlwZSkuZ2V0R2VuZXJpY0RlY2xhcmF0aW9uKCkpOworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBNdWx0aXBsZUdlbmVyaWNUeXBlczxULFM+eworICAgICAgICB2b2lkIG11bHRpcGxlR2VuZXJpY1R5cGVzVChUIHQpe30KKyAgICAgICAgdm9pZCBtdWx0aXBsZUdlbmVyaWNUeXBlc1MoUyBzKXt9CisgICAgICAgIHZvaWQgbXVsdGlwbGVHZW5lcmljVHlwZXNUUyhUIHQsIFMgcyl7fQorICAgIH0KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TXVsdGlwbGVHZW5lcmljVHlwZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy9UeXBlIHBhcmFtZXRlcnMKKyAgICAgICAgQ2xhc3M8PyBleHRlbmRzIE11bHRpcGxlR2VuZXJpY1R5cGVzPiBjbGF6eiA9IE11bHRpcGxlR2VuZXJpY1R5cGVzLmNsYXNzOworICAgICAgICBUeXBlVmFyaWFibGU8Pz5bXSB0eXBlUGFyYW1ldGVycyA9IGNsYXp6LmdldFR5cGVQYXJhbWV0ZXJzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCB0eXBlUGFyYW1ldGVycy5sZW5ndGgpOworICAgICAgICBUeXBlVmFyaWFibGU8Pz4gdHlwZVZhcmlhYmxlVCA9IHR5cGVQYXJhbWV0ZXJzWzBdOworICAgICAgICBhc3NlcnRFcXVhbHMoY2xhenosIHR5cGVWYXJpYWJsZVQuZ2V0R2VuZXJpY0RlY2xhcmF0aW9uKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlQiLCB0eXBlVmFyaWFibGVULmdldE5hbWUoKSk7CisgICAgICAgIFR5cGVWYXJpYWJsZTw/PiB0eXBlVmFyaWFibGVTID0gdHlwZVBhcmFtZXRlcnNbMV07CisgICAgICAgIGFzc2VydEVxdWFscygiUyIsIHR5cGVWYXJpYWJsZVMuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNsYXp6LCB0eXBlVmFyaWFibGVTLmdldEdlbmVyaWNEZWNsYXJhdGlvbigpKTsKKworICAgICAgICAvLyBtdWx0aXBsZUdlbmVyaWNUeXBlc1QKKyAgICAgICAgTWV0aG9kIG11bHRpcGxlR2VuZXJpY1R5cGVzVCA9IGNsYXp6LmdldERlY2xhcmVkTWV0aG9kKCJtdWx0aXBsZUdlbmVyaWNUeXBlc1QiLCBuZXcgQ2xhc3NbXXtPYmplY3QuY2xhc3N9KTsKKyAgICAgICAgVHlwZVtdIG11bHRpcGxlR2VuZXJpY1R5cGVzVFR5cGVzID0gbXVsdGlwbGVHZW5lcmljVHlwZXNULmdldEdlbmVyaWNQYXJhbWV0ZXJUeXBlcygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUobXVsdGlwbGVHZW5lcmljVHlwZXNUVHlwZXMpOworICAgICAgICBUeXBlIG11bHRpcGxlR2VuZXJpY1R5cGVzVFR5cGUgPSBtdWx0aXBsZUdlbmVyaWNUeXBlc1RUeXBlc1swXTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHR5cGVWYXJpYWJsZVQsIG11bHRpcGxlR2VuZXJpY1R5cGVzVFR5cGUpOworCisgICAgICAgIC8vIG11bHRpcGxlR2VuZXJpY1R5cGVzUworICAgICAgICBNZXRob2QgbXVsdGlwbGVHZW5lcmljVHlwZXNTID0gY2xhenouZ2V0RGVjbGFyZWRNZXRob2QoIm11bHRpcGxlR2VuZXJpY1R5cGVzUyIsIG5ldyBDbGFzc1tde09iamVjdC5jbGFzc30pOworICAgICAgICBUeXBlW10gbXVsdGlwbGVHZW5lcmljVHlwZXNTVHlwZXMgPSBtdWx0aXBsZUdlbmVyaWNUeXBlc1MuZ2V0R2VuZXJpY1BhcmFtZXRlclR5cGVzKCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZShtdWx0aXBsZUdlbmVyaWNUeXBlc1NUeXBlcyk7CisgICAgICAgIFR5cGUgbXVsdGlwbGVHZW5lcmljVHlwZXNTVHlwZSA9IG11bHRpcGxlR2VuZXJpY1R5cGVzU1R5cGVzWzBdOworICAgICAgICBhc3NlcnRFcXVhbHModHlwZVZhcmlhYmxlUywgbXVsdGlwbGVHZW5lcmljVHlwZXNTVHlwZSk7CisKKyAgICAgICAgLy8gbXVsdGlwbGVHZW5lcmljVHlwZXNTCisgICAgICAgIE1ldGhvZCBtdWx0aXBsZUdlbmVyaWNUeXBlc1RTID0gY2xhenouZ2V0RGVjbGFyZWRNZXRob2QoIm11bHRpcGxlR2VuZXJpY1R5cGVzVFMiLCBuZXcgQ2xhc3NbXXtPYmplY3QuY2xhc3MsIE9iamVjdC5jbGFzc30pOworICAgICAgICBUeXBlW10gbXVsdGlwbGVHZW5lcmljVHlwZXNUU1R5cGVzID0gbXVsdGlwbGVHZW5lcmljVHlwZXNUUy5nZXRHZW5lcmljUGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIG11bHRpcGxlR2VuZXJpY1R5cGVzVFNUeXBlcy5sZW5ndGgpOworICAgICAgICBUeXBlIG11bHRpcGxlR2VuZXJpY1R5cGVzVFNUeXBlVCA9IG11bHRpcGxlR2VuZXJpY1R5cGVzVFNUeXBlc1swXTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHR5cGVWYXJpYWJsZVQsIG11bHRpcGxlR2VuZXJpY1R5cGVzVFNUeXBlVCk7CisgICAgICAgIFR5cGUgbXVsdGlwbGVHZW5lcmljVHlwZXNUU1R5cGVTID0gbXVsdGlwbGVHZW5lcmljVHlwZXNUU1R5cGVzWzFdOworICAgICAgICBhc3NlcnRFcXVhbHModHlwZVZhcmlhYmxlUywgbXVsdGlwbGVHZW5lcmljVHlwZXNUU1R5cGVTKTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TXVsdGlwbGVCb3VuZGVkR2VuZXJpY1R5cGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vVHlwZSBwYXJhbWV0ZXJzCisgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBNdWx0aXBsZUJvdW5kZWRHZW5lcmljVHlwZXM+IGNsYXp6ID0gTXVsdGlwbGVCb3VuZGVkR2VuZXJpY1R5cGVzLmNsYXNzOworICAgICAgICBUeXBlVmFyaWFibGU8Pz5bXSB0eXBlUGFyYW1ldGVycyA9IGNsYXp6LmdldFR5cGVQYXJhbWV0ZXJzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCB0eXBlUGFyYW1ldGVycy5sZW5ndGgpOworICAgICAgICBUeXBlVmFyaWFibGU8Pz4gdHlwZVZhcmlhYmxlVCA9IHR5cGVQYXJhbWV0ZXJzWzBdOworICAgICAgICBhc3NlcnRFcXVhbHMoY2xhenosIHR5cGVWYXJpYWJsZVQuZ2V0R2VuZXJpY0RlY2xhcmF0aW9uKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlQiLCB0eXBlVmFyaWFibGVULmdldE5hbWUoKSk7CisgICAgICAgIFR5cGVWYXJpYWJsZTw/PiB0eXBlVmFyaWFibGVTID0gdHlwZVBhcmFtZXRlcnNbMV07CisgICAgICAgIGFzc2VydEVxdWFscygiUyIsIHR5cGVWYXJpYWJsZVMuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNsYXp6LCB0eXBlVmFyaWFibGVTLmdldEdlbmVyaWNEZWNsYXJhdGlvbigpKTsKKyAgICAgICAgVHlwZVtdIGJvdW5kc1MgPSB0eXBlVmFyaWFibGVTLmdldEJvdW5kcygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUoYm91bmRzUyk7CisgICAgICAgIFR5cGUgYm91bmRTID0gYm91bmRzU1swXTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHR5cGVWYXJpYWJsZVQsIGJvdW5kUyk7CisgICAgfQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIEBLbm93bkZhaWx1cmUoIkZhaWxzIGluIENUUyBidXQgcGFzc2VzIHVuZGVyIHJ1bi1jb3JlLXRlc3RzIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2ltcGxlSW5oZXJpdGFuY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2xhc3M8PyBleHRlbmRzIFNpbXBsZUluaGVyaXRhbmNlPiBjbGF6eiA9IFNpbXBsZUluaGVyaXRhbmNlLmNsYXNzOworICAgICAgICBUeXBlVmFyaWFibGU8Q2xhc3M+IHN1YlR5cGVWYXJpYWJsZSA9IGdldFR5cGVQYXJhbWV0ZXIoY2xhenopOworCisgICAgICAgIGFzc2VydEluc3RhbmNlT2YoUGFyYW1ldGVyaXplZFR5cGUuY2xhc3MsIGNsYXp6LmdldEdlbmVyaWNTdXBlcmNsYXNzKCkpOworICAgICAgICBQYXJhbWV0ZXJpemVkVHlwZSBwYXJhbWV0ZXJpemVkU3VwZXJUeXBlID0gKFBhcmFtZXRlcml6ZWRUeXBlKSBjbGF6ei5nZXRHZW5lcmljU3VwZXJjbGFzcygpOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKENsYXNzLmNsYXNzLCBwYXJhbWV0ZXJpemVkU3VwZXJUeXBlLmdldFJhd1R5cGUoKSk7CisKKyAgICAgICAgVHlwZVZhcmlhYmxlPENsYXNzPiBzdXBlclR5cGVQYXJhbWV0ZXIgPSBnZXRUeXBlUGFyYW1ldGVyKChDbGFzczw/PilwYXJhbWV0ZXJpemVkU3VwZXJUeXBlLmdldFJhd1R5cGUoKSk7CisgICAgICAgIFR5cGVWYXJpYWJsZTxDbGFzcz4gdHlwZVBhcmFtZXRlciA9IGdldFR5cGVQYXJhbWV0ZXIoR2VuZXJpY1R5cGUuY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoc3VwZXJUeXBlUGFyYW1ldGVyLCB0eXBlUGFyYW1ldGVyKTsKKworICAgICAgICBhc3NlcnROb3RFcXVhbHMoc3ViVHlwZVZhcmlhYmxlLCBzdXBlclR5cGVQYXJhbWV0ZXIpOworCisgICAgICAgIFR5cGVbXSBhY3R1YWxUeXBlQXJndW1lbnRzID0gcGFyYW1ldGVyaXplZFN1cGVyVHlwZS5nZXRBY3R1YWxUeXBlQXJndW1lbnRzKCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZShhY3R1YWxUeXBlQXJndW1lbnRzKTsKKyAgICAgICAgYXNzZXJ0SW5zdGFuY2VPZihUeXBlVmFyaWFibGUuY2xhc3MsIGFjdHVhbFR5cGVBcmd1bWVudHNbMF0pOworICAgICAgICBUeXBlVmFyaWFibGUgYWN0dWFsU3VwZXJUeXBlVmFyaWFibGUgPSAoVHlwZVZhcmlhYmxlKSBhY3R1YWxUeXBlQXJndW1lbnRzWzBdOworICAgICAgICBhc3NlcnRFcXVhbHMoc3ViVHlwZVZhcmlhYmxlLCBhY3R1YWxTdXBlclR5cGVWYXJpYWJsZSk7CisgICAgfQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbm5lckNsYXNzVGVzdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDbGFzczw/IGV4dGVuZHMgSW5uZXJDbGFzc1Rlc3Q+IGNsYXp6ID1Jbm5lckNsYXNzVGVzdC5jbGFzczsKKyAgICAgICAgVHlwZVZhcmlhYmxlPENsYXNzPiB0eXBlVmFyaWFibGUgPSBnZXRUeXBlUGFyYW1ldGVyKGNsYXp6KTsKKworICAgICAgICBDbGFzczw/PltdIGRlY2xhcmVkQ2xhc3NlcyA9IGNsYXp6LmdldERlY2xhcmVkQ2xhc3NlcygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUoZGVjbGFyZWRDbGFzc2VzKTsKKyAgICAgICAgQ2xhc3M8Pz4gaW5uZXJDbGF6eiA9IGRlY2xhcmVkQ2xhc3Nlc1swXTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKElubmVyQ2xhc3NUZXN0LklubmVyQ2xhc3MuY2xhc3MsIGlubmVyQ2xhenopOworCisgICAgICAgIC8vY29uc3RydWN0b3IKKyAgICAgICAgQ29uc3RydWN0b3I8Pz5bXSBkZWNsYXJlZENvbnN0cnVjdG9ycyA9IGlubmVyQ2xhenouZ2V0RGVjbGFyZWRDb25zdHJ1Y3RvcnMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGRlY2xhcmVkQ29uc3RydWN0b3JzKTsKKyAgICAgICAgQ29uc3RydWN0b3I8Pz4gZGVjbGFyZWRDb25zdHJ1Y3RvciA9IGRlY2xhcmVkQ29uc3RydWN0b3JzWzBdOworICAgICAgICBUeXBlW10gZ2VuZXJpY1BhcmFtZXRlclR5cGVzID0gZGVjbGFyZWRDb25zdHJ1Y3Rvci5nZXRHZW5lcmljUGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGdlbmVyaWNQYXJhbWV0ZXJUeXBlcyk7CisgICAgICAgIGFzc2VydEVxdWFscyh0eXBlVmFyaWFibGUsIGdlbmVyaWNQYXJhbWV0ZXJUeXBlc1swXSk7CisgICAgICAgIGFzc2VydEluc3RhbmNlT2YoVHlwZVZhcmlhYmxlLmNsYXNzLCBnZW5lcmljUGFyYW1ldGVyVHlwZXNbMF0pOworICAgICAgICBUeXBlVmFyaWFibGU8Pz4gY29uc3RydWN0b3JUeXBlVmFyaWFibGUgPSAoVHlwZVZhcmlhYmxlPD8+KSBnZW5lcmljUGFyYW1ldGVyVHlwZXNbMF07CisgICAgICAgIGFzc2VydEVxdWFscyhjbGF6eiAsY29uc3RydWN0b3JUeXBlVmFyaWFibGUuZ2V0R2VuZXJpY0RlY2xhcmF0aW9uKCkpOworCisgICAgICAgIC8vbWV0aG9kCisgICAgICAgIE1ldGhvZCBkZWNsYXJlZE1ldGhvZHMgPSBpbm5lckNsYXp6LmdldERlY2xhcmVkTWV0aG9kKCJpbm5lck1ldGhvZCIsIE9iamVjdC5jbGFzcyk7CisgICAgICAgIFR5cGVbXSBtZXRob2RQYXJhbWV0ZXJUeXBlcyA9IGRlY2xhcmVkTWV0aG9kcy5nZXRHZW5lcmljUGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKG1ldGhvZFBhcmFtZXRlclR5cGVzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHR5cGVWYXJpYWJsZSwgbWV0aG9kUGFyYW1ldGVyVHlwZXNbMF0pOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKFR5cGVWYXJpYWJsZS5jbGFzcywgbWV0aG9kUGFyYW1ldGVyVHlwZXNbMF0pOworICAgICAgICBUeXBlVmFyaWFibGU8Pz4gbWV0aG9kVHlwZVZhcmlhYmxlID0gKFR5cGVWYXJpYWJsZTw/PikgbWV0aG9kUGFyYW1ldGVyVHlwZXNbMF07CisgICAgICAgIGFzc2VydEVxdWFscyhjbGF6eiwgbWV0aG9kVHlwZVZhcmlhYmxlLmdldEdlbmVyaWNEZWNsYXJhdGlvbigpKTsKKyAgICB9CisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdEV4Y2VwdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDbGFzczw/IGV4dGVuZHMgRXhjZXB0aW9uVGVzdD4gY2xhenogPSBFeGNlcHRpb25UZXN0LmNsYXNzOworICAgICAgICBUeXBlVmFyaWFibGU8Q2xhc3M+IHR5cGVWYXJpYWJsZSA9IGdldFR5cGVQYXJhbWV0ZXIoY2xhenopOworICAgICAgICBNZXRob2QgbWV0aG9kID0gY2xhenouZ2V0RGVjbGFyZWRNZXRob2QoImV4Y2VwdGlvblRlc3QiKTsKKyAgICAgICAgVHlwZVtdIGdlbmVyaWNFeGNlcHRpb25UeXBlcyA9IG1ldGhvZC5nZXRHZW5lcmljRXhjZXB0aW9uVHlwZXMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGdlbmVyaWNFeGNlcHRpb25UeXBlcyk7CisgICAgICAgIGFzc2VydEVxdWFscyh0eXBlVmFyaWFibGUsIGdlbmVyaWNFeGNlcHRpb25UeXBlc1swXSk7CisKKyAgICAgICAgQ2xhc3M8Pz5bXSBkZWNsYXJlZENsYXNzZXMgPSBjbGF6ei5nZXREZWNsYXJlZENsYXNzZXMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGRlY2xhcmVkQ2xhc3Nlcyk7CisgICAgICAgIENsYXNzPD8+IGlubmVyQ2xhenogPSBkZWNsYXJlZENsYXNzZXNbMF07CisgICAgICAgIGFzc2VydEVxdWFscyhFeGNlcHRpb25UZXN0LklubmVyQ2xhc3MuY2xhc3MsIGlubmVyQ2xhenopOworCisgICAgICAgIC8vbWV0aG9kCisgICAgICAgIE1ldGhvZCBkZWNsYXJlZE1ldGhvZHMgPSBpbm5lckNsYXp6LmdldERlY2xhcmVkTWV0aG9kKCJpbm5lckV4Y2VwdGlvblRlc3QiKTsKKyAgICAgICAgVHlwZVtdIGV4Y2VwdGlvblR5cGVzID0gZGVjbGFyZWRNZXRob2RzLmdldEdlbmVyaWNFeGNlcHRpb25UeXBlcygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUoZXhjZXB0aW9uVHlwZXMpOworICAgICAgICBhc3NlcnRFcXVhbHModHlwZVZhcmlhYmxlLCBleGNlcHRpb25UeXBlc1swXSk7CisgICAgICAgIGFzc2VydEluc3RhbmNlT2YoVHlwZVZhcmlhYmxlLmNsYXNzLCBleGNlcHRpb25UeXBlc1swXSk7CisgICAgICAgIFR5cGVWYXJpYWJsZTw/PiBtZXRob2RUeXBlVmFyaWFibGUgPSAoVHlwZVZhcmlhYmxlPD8+KSBleGNlcHRpb25UeXBlc1swXTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNsYXp6LCBtZXRob2RUeXBlVmFyaWFibGUuZ2V0R2VuZXJpY0RlY2xhcmF0aW9uKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L1Byb3h5VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL3JlZmxlY3QvUHJveHlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjZhZThiMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L1Byb3h5VGVzdC5qYXZhCkBAIC0wLDAgKzEsNjYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uSGFuZGxlcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuUHJveHk7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IHRlc3RzLnV0aWwuQ2xhc3NMb2FkZXJCdWlsZGVyOworCitwdWJsaWMgZmluYWwgY2xhc3MgUHJveHlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogTWFrZSBzdXJlIHRoZSBwcm94eSdzIGNsYXNzIGxvYWRlciBmYWlscyBpZiBpdCBjYW5ub3Qgc2VlIHRoZSBjbGFzcworICAgICAqIGxvYWRlcnMgb2YgaXRzIGltcGxlbWVudGVkIGludGVyZmFjZXMuIGh0dHA6Ly9iLzE2MDg0ODEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xhc3NMb2FkZXJNdXN0U2VlSW1wbGVtZW50ZWRJbnRlcmZhY2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBwcmVmaXggPSBQcm94eVRlc3QuY2xhc3MuZ2V0TmFtZSgpOworICAgICAgICBDbGFzc0xvYWRlciBsb2FkZXJBID0gbmV3IENsYXNzTG9hZGVyQnVpbGRlcigpLndpdGhQcml2YXRlQ29weShwcmVmaXgpLmJ1aWxkKCk7CisgICAgICAgIENsYXNzTG9hZGVyIGxvYWRlckIgPSBuZXcgQ2xhc3NMb2FkZXJCdWlsZGVyKCkud2l0aFByaXZhdGVDb3B5KHByZWZpeCkuYnVpbGQoKTsKKworICAgICAgICBDbGFzc1tdIGludGVyZmFjZXNBID0geyBsb2FkZXJBLmxvYWRDbGFzcyhwcmVmaXggKyAiJEVjaG8iKSB9OworICAgICAgICB0cnkgeworICAgICAgICAgICAgUHJveHkubmV3UHJveHlJbnN0YW5jZShsb2FkZXJCLCBpbnRlcmZhY2VzQSwgbmV3IFRlc3RJbnZvY2F0aW9uSGFuZGxlcigpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xhc3NMb2FkZXJEb2VzTm90TmVlZFRvU2VlSW52b2NhdGlvbkhhbmRsZXJMb2FkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHByZWZpeCA9IFByb3h5VGVzdC5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIENsYXNzTG9hZGVyIGxvYWRlckEgPSBuZXcgQ2xhc3NMb2FkZXJCdWlsZGVyKCkud2l0aFByaXZhdGVDb3B5KHByZWZpeCkuYnVpbGQoKTsKKyAgICAgICAgQ2xhc3NMb2FkZXIgbG9hZGVyQiA9IG5ldyBDbGFzc0xvYWRlckJ1aWxkZXIoKS53aXRoUHJpdmF0ZUNvcHkocHJlZml4KS5idWlsZCgpOworICAgICAgICBJbnZvY2F0aW9uSGFuZGxlciBpbnZvY2F0aW9uSGFuZGxlckIgPSAoSW52b2NhdGlvbkhhbmRsZXIpIGxvYWRlckIubG9hZENsYXNzKAorICAgICAgICAgICAgICAgIHByZWZpeCArICIkVGVzdEludm9jYXRpb25IYW5kbGVyIikubmV3SW5zdGFuY2UoKTsKKworICAgICAgICBDbGFzc1tdIGludGVyZmFjZXNBID0geyBsb2FkZXJBLmxvYWRDbGFzcyhwcmVmaXggKyAiJEVjaG8iKSB9OworICAgICAgICBPYmplY3QgcHJveHkgPSBQcm94eS5uZXdQcm94eUluc3RhbmNlKGxvYWRlckEsIGludGVyZmFjZXNBLCBpbnZvY2F0aW9uSGFuZGxlckIpOworICAgICAgICBhc3NlcnRFcXVhbHMobG9hZGVyQSwgcHJveHkuZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBwcm94eS5nZXRDbGFzcygpLmdldE1ldGhvZCgiZWNobyIsIFN0cmluZy5jbGFzcykuaW52b2tlKHByb3h5LCAiZm9vIikpOworICAgIH0KKworICAgIHB1YmxpYyBpbnRlcmZhY2UgRWNobyB7CisgICAgICAgIFN0cmluZyBlY2hvKFN0cmluZyBzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFRlc3RJbnZvY2F0aW9uSGFuZGxlciBpbXBsZW1lbnRzIEludm9jYXRpb25IYW5kbGVyIHsKKyAgICAgICAgcHVibGljIE9iamVjdCBpbnZva2UoT2JqZWN0IHByb3h5LCBNZXRob2QgbWV0aG9kLCBPYmplY3RbXSBhcmdzKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgICAgIHJldHVybiBhcmdzWzBdOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9sYW5nL3JlZmxlY3QvUmVmbGVjdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L1JlZmxlY3Rpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2IwOTJlNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbGFuZy9yZWZsZWN0L1JlZmxlY3Rpb25UZXN0LmphdmEKQEAgLTAsMCArMSwzMjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZW1iZXI7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlBhcmFtZXRlcml6ZWRUeXBlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVHlwZVZhcmlhYmxlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tQWNjZXNzOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgUmVmbGVjdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBTdHJpbmcgY2xhc3NBID0gImxpYmNvcmUuamF2YS5sYW5nLnJlZmxlY3QuUmVmbGVjdGlvblRlc3QkQSI7CisgICAgU3RyaW5nIGNsYXNzQiA9ICJsaWJjb3JlLmphdmEubGFuZy5yZWZsZWN0LlJlZmxlY3Rpb25UZXN0JEIiOworICAgIFN0cmluZyBjbGFzc0MgPSAibGliY29yZS5qYXZhLmxhbmcucmVmbGVjdC5SZWZsZWN0aW9uVGVzdCRDIjsKKworICAgIC8qKgorICAgICAqIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9NjYzNgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmljU3VwZXJjbGFzc1RvU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiamF2YS51dGlsLkFycmF5TGlzdDwiICsgY2xhc3NBICsgIj4iLAorICAgICAgICAgICAgICAgIEFMaXN0LmNsYXNzLmdldEdlbmVyaWNTdXBlcmNsYXNzKCkudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZpZWxkVG9TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmllbGQgZmllbGRPbmUgPSBDLmNsYXNzLmdldERlY2xhcmVkRmllbGQoImZpZWxkT25lIik7CisgICAgICAgIFN0cmluZyBmaWVsZE9uZVJhdyA9ICJwdWJsaWMgc3RhdGljICIgKyBjbGFzc0EgKyAiICIgKyBjbGFzc0MgKyAiLmZpZWxkT25lIjsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZpZWxkT25lUmF3LCBmaWVsZE9uZS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZpZWxkT25lUmF3LCBmaWVsZE9uZS50b0dlbmVyaWNTdHJpbmcoKSk7CisKKyAgICAgICAgRmllbGQgZmllbGRUd28gPSBDLmNsYXNzLmdldERlY2xhcmVkRmllbGQoImZpZWxkVHdvIik7CisgICAgICAgIGFzc2VydEVxdWFscygicHJpdmF0ZSB0cmFuc2llbnQgdm9sYXRpbGUgamF2YS51dGlsLk1hcCAiICsgY2xhc3NDICsgIi5maWVsZFR3byIsCisgICAgICAgICAgICAgICAgZmllbGRUd28udG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygicHJpdmF0ZSB0cmFuc2llbnQgdm9sYXRpbGUgamF2YS51dGlsLk1hcDwiICsgY2xhc3NBICsgIiwgamF2YS5sYW5nLlN0cmluZz4gIgorICAgICAgICAgICAgICAgICsgY2xhc3NDICsgIi5maWVsZFR3byIsIGZpZWxkVHdvLnRvR2VuZXJpY1N0cmluZygpKTsKKworICAgICAgICBGaWVsZCBmaWVsZFRocmVlID0gQy5jbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJmaWVsZFRocmVlIik7CisgICAgICAgIFN0cmluZyBmaWVsZFRocmVlUmF3ID0gInByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0W10gIiArIGNsYXNzQyArICIuZmllbGRUaHJlZSI7CisgICAgICAgIGFzc2VydEVxdWFscyhmaWVsZFRocmVlUmF3LCBmaWVsZFRocmVlLnRvU3RyaW5nKCkpOworICAgICAgICBTdHJpbmcgZmllbGRUaHJlZUdlbmVyaWMgPSAicHJvdGVjdGVkIEtbXSAiICsgY2xhc3NDICsgIi5maWVsZFRocmVlIjsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZpZWxkVGhyZWVHZW5lcmljLCBmaWVsZFRocmVlLnRvR2VuZXJpY1N0cmluZygpKTsKKworICAgICAgICBGaWVsZCBmaWVsZEZvdXIgPSBDLmNsYXNzLmdldERlY2xhcmVkRmllbGQoImZpZWxkRm91ciIpOworICAgICAgICBTdHJpbmcgZmllbGRGb3VyUmF3ID0gImphdmEudXRpbC5NYXAgIiArIGNsYXNzQyArICIuZmllbGRGb3VyIjsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZpZWxkRm91clJhdywgZmllbGRGb3VyLnRvU3RyaW5nKCkpOworICAgICAgICBTdHJpbmcgZmllbGRGb3VyR2VuZXJpYyA9ICJqYXZhLnV0aWwuTWFwPD8gc3VwZXIgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyW10+ICIKKyAgICAgICAgICAgICAgICArIGNsYXNzQyArICIuZmllbGRGb3VyIjsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZpZWxkRm91ckdlbmVyaWMsIGZpZWxkRm91ci50b0dlbmVyaWNTdHJpbmcoKSk7CisKKyAgICAgICAgRmllbGQgZmllbGRGaXZlID0gQy5jbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJmaWVsZEZpdmUiKTsKKyAgICAgICAgU3RyaW5nIGZpZWxkRml2ZVJhdyA9ICJqYXZhLmxhbmcuU3RyaW5nW11bXVtdW11bXSAiICsgY2xhc3NDICsgIi5maWVsZEZpdmUiOworICAgICAgICBhc3NlcnRFcXVhbHMoZmllbGRGaXZlUmF3LCBmaWVsZEZpdmUudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmaWVsZEZpdmVSYXcsIGZpZWxkRml2ZS50b0dlbmVyaWNTdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdG9yVG9TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ29uc3RydWN0b3IgY29uc3RydWN0b3JPbmUgPSBDLmNsYXNzLmdldERlY2xhcmVkQ29uc3RydWN0b3IoQS5jbGFzcyk7CisgICAgICAgIFN0cmluZyBjb25zdHJ1Y3Rvck9uZVJhdyA9IGNsYXNzQyArICIoIiArIGNsYXNzQSArICIpIHRocm93cyAiICsgY2xhc3NCOworICAgICAgICBhc3NlcnRFcXVhbHMoY29uc3RydWN0b3JPbmVSYXcsIGNvbnN0cnVjdG9yT25lLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoY29uc3RydWN0b3JPbmVSYXcsIGNvbnN0cnVjdG9yT25lLnRvR2VuZXJpY1N0cmluZygpKTsKKworICAgICAgICBDb25zdHJ1Y3RvciBjb25zdHJ1Y3RvclR3byA9IEMuY2xhc3MuZ2V0RGVjbGFyZWRDb25zdHJ1Y3RvcihNYXAuY2xhc3MsIE9iamVjdC5jbGFzcyk7CisgICAgICAgIFN0cmluZyBjb25zdHJ1Y3RvclR3b1JhdyA9ICJwcm90ZWN0ZWQgIiArIGNsYXNzQyArICIoamF2YS51dGlsLk1hcCxqYXZhLmxhbmcuT2JqZWN0KSI7CisgICAgICAgIGFzc2VydEVxdWFscyhjb25zdHJ1Y3RvclR3b1JhdywgY29uc3RydWN0b3JUd28udG9TdHJpbmcoKSk7CisgICAgICAgIFN0cmluZyBjb25zdHJ1Y3RvclR3b0dlbmVyaWMgPSAicHJvdGVjdGVkIDxUMT4gIiArIGNsYXNzQworICAgICAgICAgICAgICAgICsgIihqYXZhLnV0aWwuTWFwPD8gc3VwZXIgIiArIGNsYXNzQSArICIsIFQxPixLKSI7CisgICAgICAgIGFzc2VydEVxdWFscyhjb25zdHJ1Y3RvclR3b0dlbmVyaWMsIGNvbnN0cnVjdG9yVHdvLnRvR2VuZXJpY1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWV0aG9kVG9TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG1ldGhvZE9uZSA9IEMuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoIm1ldGhvZE9uZSIsIEEuY2xhc3MsIEMuY2xhc3MpOworICAgICAgICBTdHJpbmcgbWV0aG9kT25lUmF3ID0gInByb3RlY3RlZCBmaW5hbCBzeW5jaHJvbml6ZWQgIiArIGNsYXNzQSArICIgIgorICAgICAgICAgICAgICAgICsgY2xhc3NDICsgIi5tZXRob2RPbmUoIiArIGNsYXNzQSArICIsIiArIGNsYXNzQyArICIpIHRocm93cyAiICsgY2xhc3NCOworICAgICAgICBhc3NlcnRFcXVhbHMobWV0aG9kT25lUmF3LCBtZXRob2RPbmUudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtZXRob2RPbmVSYXcsIG1ldGhvZE9uZS50b0dlbmVyaWNTdHJpbmcoKSk7CisKKyAgICAgICAgTWV0aG9kIG1ldGhvZFR3byA9IEMuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoIm1ldGhvZFR3byIsIExpc3QuY2xhc3MpOworICAgICAgICBTdHJpbmcgbWV0aG9kVHdvUmF3ID0gInB1YmxpYyBhYnN0cmFjdCBqYXZhLnV0aWwuTWFwICIKKyAgICAgICAgICAgICAgICArIGNsYXNzQyArICIubWV0aG9kVHdvKGphdmEudXRpbC5MaXN0KSI7CisgICAgICAgIGFzc2VydEVxdWFscyhtZXRob2RUd29SYXcsIG1ldGhvZFR3by50b1N0cmluZygpKTsKKyAgICAgICAgU3RyaW5nIG1ldGhvZFR3b0dlbmVyaWMgPSAicHVibGljIGFic3RyYWN0IGphdmEudXRpbC5NYXA8IiArIGNsYXNzQSArICIsIGphdmEubGFuZy5TdHJpbmc+ICIKKyAgICAgICAgICAgICAgICArIGNsYXNzQyArICIubWV0aG9kVHdvKGphdmEudXRpbC5MaXN0PCIgKyBjbGFzc0EgKyAiPikiOworICAgICAgICBhc3NlcnRFcXVhbHMobWV0aG9kVHdvR2VuZXJpYywgbWV0aG9kVHdvLnRvR2VuZXJpY1N0cmluZygpKTsKKworICAgICAgICBNZXRob2QgbWV0aG9kVGhyZWUgPSBDLmNsYXNzLmdldERlY2xhcmVkTWV0aG9kKCJtZXRob2RUaHJlZSIsIEEuY2xhc3MsIFNldC5jbGFzcyk7CisgICAgICAgIFN0cmluZyBtZXRob2RUaHJlZVJhdyA9ICJwcml2YXRlIHN0YXRpYyBqYXZhLnV0aWwuTWFwICIKKyAgICAgICAgICAgICAgICArIGNsYXNzQyArICIubWV0aG9kVGhyZWUoIiArIGNsYXNzQSArICIsamF2YS51dGlsLlNldCkiOworICAgICAgICBhc3NlcnRFcXVhbHMobWV0aG9kVGhyZWVSYXcsIG1ldGhvZFRocmVlLnRvU3RyaW5nKCkpOworICAgICAgICBTdHJpbmcgbWV0aG9kVGhyZWVHZW5lcmljID0gInByaXZhdGUgc3RhdGljIDxUMSxUMj4gamF2YS51dGlsLk1hcDxUMSwgPz4gIgorICAgICAgICAgICAgICAgICsgY2xhc3NDICsgIi5tZXRob2RUaHJlZShUMSxqYXZhLnV0aWwuU2V0PD8gc3VwZXIgVDI+KSI7CisgICAgICAgIGFzc2VydEVxdWFscyhtZXRob2RUaHJlZUdlbmVyaWMsIG1ldGhvZFRocmVlLnRvR2VuZXJpY1N0cmluZygpKTsKKworICAgICAgICBNZXRob2QgbWV0aG9kRm91ciA9IEMuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoIm1ldGhvZEZvdXIiLCBTZXQuY2xhc3MpOworICAgICAgICBTdHJpbmcgbWV0aG9kRm91clJhdyA9ICJwdWJsaWMgamF2YS5sYW5nLkNvbXBhcmFibGUgIiArIGNsYXNzQyArICIubWV0aG9kRm91cihqYXZhLnV0aWwuU2V0KSI7CisgICAgICAgIGFzc2VydEVxdWFscyhtZXRob2RGb3VyUmF3LCBtZXRob2RGb3VyLnRvU3RyaW5nKCkpOworICAgICAgICBTdHJpbmcgbWV0aG9kRm91ckdlbmVyaWMgPSAicHVibGljIDxUPiBUICIgKyBjbGFzc0MgKyAiLm1ldGhvZEZvdXIoamF2YS51dGlsLlNldDxUPikiOworICAgICAgICBhc3NlcnRFcXVhbHMobWV0aG9kRm91ckdlbmVyaWMsIG1ldGhvZEZvdXIudG9HZW5lcmljU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUeXBlVmFyaWFibGVXaXRoTXVsdGlwbGVCb3VuZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVHlwZVZhcmlhYmxlIHQgPSBDLmNsYXNzLmdldERlY2xhcmVkTWV0aG9kKCJtZXRob2RGb3VyIiwgU2V0LmNsYXNzKS5nZXRUeXBlUGFyYW1ldGVycygpWzBdOworICAgICAgICBhc3NlcnRFcXVhbHMoIlQiLCB0LnRvU3RyaW5nKCkpOworCisgICAgICAgIFR5cGVbXSBib3VuZHMgPSB0LmdldEJvdW5kcygpOworICAgICAgICBQYXJhbWV0ZXJpemVkVHlwZSBjb21wYXJhYmxlVCA9IChQYXJhbWV0ZXJpemVkVHlwZSkgYm91bmRzWzBdOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29tcGFyYWJsZS5jbGFzcywgY29tcGFyYWJsZVQuZ2V0UmF3VHlwZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUIiwgKChUeXBlVmFyaWFibGUpIGNvbXBhcmFibGVULmdldEFjdHVhbFR5cGVBcmd1bWVudHMoKVswXSkuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGJvdW5kcy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoU2VyaWFsaXphYmxlLmNsYXNzLCBib3VuZHNbMV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoUmFuZG9tQWNjZXNzLmNsYXNzLCBib3VuZHNbMl0pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRGaWVsZE5vdEZvdW5kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBELmNsYXNzLmdldEZpZWxkKCJub0ZpZWxkIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEZpZWxkRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RGVjbGFyZWRGaWVsZE5vdEZvdW5kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBELmNsYXNzLmdldERlY2xhcmVkRmllbGQoIm5vRmllbGQiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRmllbGRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRGaWVsZE51bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEQuY2xhc3MuZ2V0RmllbGQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RGVjbGFyZWRGaWVsZE51bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEQuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRGaWVsZElzUmVjdXJzaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpZWxkIGZpZWxkID0gRC5jbGFzcy5nZXRGaWVsZCgiZmllbGRPbmUiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEMuY2xhc3MsIGZpZWxkLmdldERlY2xhcmluZ0NsYXNzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXREZWNsYXJlZEZpZWxkSXNOb3RSZWN1cnNpdmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBELmNsYXNzLmdldERlY2xhcmVkRmllbGQoImZpZWxkT25lIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEZpZWxkRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RmllbGRJc1B1YmxpY09ubHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQy5jbGFzcy5nZXRGaWVsZCgiZmllbGRPbmUiKTsgLy8gcHVibGljCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDLmNsYXNzLmdldEZpZWxkKCJmaWVsZFR3byIpOyAvLyBwcml2YXRlCisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEZpZWxkRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEMuY2xhc3MuZ2V0RmllbGQoImZpZWxkVGhyZWUiKTsgLy8gcHJvdGVjdGVkCisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEZpZWxkRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEMuY2xhc3MuZ2V0RmllbGQoImZpZWxkRm91ciIpOyAvLyBwYWNrYWdlLXByaXZhdGUKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRmllbGRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXREZWNsYXJlZEZpZWxkSXNBbGxWaXNpYmlsaXRpZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQy5jbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJmaWVsZE9uZSIpOyAvLyBwdWJsaWMKKyAgICAgICAgQy5jbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJmaWVsZFR3byIpOyAvLyBwcml2YXRlCisgICAgICAgIEMuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgiZmllbGRUaHJlZSIpOyAvLyBwcm90ZWN0ZWQKKyAgICAgICAgQy5jbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJmaWVsZEZvdXIiKTsgLy8gcGFja2FnZS1wcml2YXRlCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEZpZWxkVmlhRXh0ZW5kc1RoZW5JbXBsZW1lbnRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpZWxkIGZpZWxkID0gRXh0ZW5kc0ltcGxlbWVudHNEZWZpbmVzTWVtYmVyLmNsYXNzLmdldEZpZWxkKCJmaWVsZCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoRGVmaW5lc01lbWJlci5jbGFzcywgZmllbGQuZ2V0RGVjbGFyaW5nQ2xhc3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEZpZWxkVmlhSW1wbGVtZW50c1RoZW5FeHRlbmRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpZWxkIGZpZWxkID0gSW1wbGVtZW50c0V4dGVuZHNEZWZpbmVzTWVtYmVyLmNsYXNzLmdldEZpZWxkKCJmaWVsZCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoRGVmaW5lc01lbWJlci5jbGFzcywgZmllbGQuZ2V0RGVjbGFyaW5nQ2xhc3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEZpZWxkc1ZpYUV4dGVuZHNUaGVuSW1wbGVtZW50cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGaWVsZFtdIGZpZWxkcyA9IEV4dGVuZHNJbXBsZW1lbnRzRGVmaW5lc01lbWJlci5jbGFzcy5nZXRGaWVsZHMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuYW1lcyhmaWVsZHMpLmNvbnRhaW5zKCJmaWVsZCIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RmllbGRzVmlhSW1wbGVtZW50c1RoZW5FeHRlbmRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpZWxkW10gZmllbGRzID0gSW1wbGVtZW50c0V4dGVuZHNEZWZpbmVzTWVtYmVyLmNsYXNzLmdldEZpZWxkcygpOworICAgICAgICBhc3NlcnRUcnVlKG5hbWVzKGZpZWxkcykuY29udGFpbnMoImZpZWxkIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRNZXRob2RWaWFFeHRlbmRzVGhlbkltcGxlbWVudHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IEV4dGVuZHNJbXBsZW1lbnRzRGVmaW5lc01lbWJlci5jbGFzcy5nZXRNZXRob2QoIm1ldGhvZCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoRGVmaW5lc01lbWJlci5jbGFzcywgbWV0aG9kLmdldERlY2xhcmluZ0NsYXNzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRNZXRob2RWaWFJbXBsZW1lbnRzVGhlbkV4dGVuZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IEltcGxlbWVudHNFeHRlbmRzRGVmaW5lc01lbWJlci5jbGFzcy5nZXRNZXRob2QoIm1ldGhvZCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoRGVmaW5lc01lbWJlci5jbGFzcywgbWV0aG9kLmdldERlY2xhcmluZ0NsYXNzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRNZXRob2RzVmlhRXh0ZW5kc1RoZW5JbXBsZW1lbnRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZFtdIG1ldGhvZHMgPSBFeHRlbmRzSW1wbGVtZW50c0RlZmluZXNNZW1iZXIuY2xhc3MuZ2V0TWV0aG9kcygpOworICAgICAgICBhc3NlcnRUcnVlKG5hbWVzKG1ldGhvZHMpLmNvbnRhaW5zKCJtZXRob2QiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldE1ldGhvZHNWaWFJbXBsZW1lbnRzVGhlbkV4dGVuZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kW10gbWV0aG9kcyA9IEltcGxlbWVudHNFeHRlbmRzRGVmaW5lc01lbWJlci5jbGFzcy5nZXRNZXRob2RzKCk7CisgICAgICAgIGFzc2VydFRydWUobmFtZXMobWV0aG9kcykuY29udGFpbnMoIm1ldGhvZCIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TWV0aG9kc0NvbnRhaW5zTm9EdXBsaWNhdGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZFtdIG1ldGhvZHMgPSBFeHRlbmRzQW5kSW1wbGVtZW50c0RlZmluZXNNZW1iZXIuY2xhc3MuZ2V0TWV0aG9kcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY291bnQobmFtZXMobWV0aG9kcyksICJtZXRob2QiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEZpZWxkc0NvbnRhaW5zTm9EdXBsaWNhdGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpZWxkW10gZmllbGRzID0gRXh0ZW5kc0FuZEltcGxlbWVudHNEZWZpbmVzTWVtYmVyLmNsYXNzLmdldEZpZWxkcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY291bnQobmFtZXMoZmllbGRzKSwgImZpZWxkIikpOworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBBIHt9CisgICAgc3RhdGljIGNsYXNzIEFMaXN0IGV4dGVuZHMgQXJyYXlMaXN0PEE+IHt9CisKKyAgICBzdGF0aWMgY2xhc3MgQiBleHRlbmRzIEV4Y2VwdGlvbiB7fQorCisgICAgcHVibGljIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBDPEs+IHsKKyAgICAgICAgcHVibGljIHN0YXRpYyBBIGZpZWxkT25lOworICAgICAgICBwcml2YXRlIHRyYW5zaWVudCB2b2xhdGlsZSBNYXA8QSwgU3RyaW5nPiBmaWVsZFR3bzsKKyAgICAgICAgcHJvdGVjdGVkIEtbXSBmaWVsZFRocmVlOworICAgICAgICBNYXA8PyBzdXBlciBJbnRlZ2VyLCBJbnRlZ2VyW10+IGZpZWxkRm91cjsKKyAgICAgICAgU3RyaW5nW11bXVtdW11bXSBmaWVsZEZpdmU7CisKKyAgICAgICAgQyhBIGEpIHRocm93cyBCIHt9CisgICAgICAgIHByb3RlY3RlZCA8VDEgZXh0ZW5kcyBBPiBDKE1hcDw/IHN1cGVyIEEsIFQxPiBhLCBLIHMpIHt9CisKKyAgICAgICAgcHJvdGVjdGVkIGZpbmFsIHN5bmNocm9uaXplZCBBIG1ldGhvZE9uZShBIHBhcmFtZXRlck9uZSwgQyBwYXJhbWV0ZXJUd28pIHRocm93cyBCIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBhYnN0cmFjdCBNYXA8QSwgU3RyaW5nPiBtZXRob2RUd28oTGlzdDxBPiBvbmx5UGFyYW1ldGVyKTsKKyAgICAgICAgQERlcHJlY2F0ZWQgLyoqIHRoaXMgYW5ub3RhdGlvbiBpcyB1c2VkIGJlY2F1c2UgaXQgaGFzIHJ1bnRpbWUgcmV0ZW50aW9uICovCisgICAgICAgIHByaXZhdGUgc3RhdGljIDxUMSBleHRlbmRzIEEsIFQyPiBNYXA8VDEsID8+IG1ldGhvZFRocmVlKFQxIHQsIFNldDw/IHN1cGVyIFQyPiB0MnMpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyA8VCBleHRlbmRzIENvbXBhcmFibGU8VD4gJiBTZXJpYWxpemFibGUgJiBSYW5kb21BY2Nlc3M+IFQgbWV0aG9kRm91cihTZXQ8VD4gdCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEQgZXh0ZW5kcyBDPFN0cmluZz4geworICAgICAgICBwdWJsaWMgRChBIGEpIHRocm93cyBCIHsKKyAgICAgICAgICAgIHN1cGVyKGEpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgTWFwPEEsIFN0cmluZz4gbWV0aG9kVHdvKExpc3Q8QT4gb25seVBhcmFtZXRlcikgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBpbnRlcmZhY2UgRGVmaW5lc01lbWJlciB7CisgICAgICAgIFN0cmluZyBmaWVsZCA9ICJzIjsKKyAgICAgICAgdm9pZCBtZXRob2QoKTsKKyAgICB9CisgICAgc3RhdGljIGFic3RyYWN0IGNsYXNzIEltcGxlbWVudHNEZWZpbmVzTWVtYmVyIGltcGxlbWVudHMgRGVmaW5lc01lbWJlciB7fQorICAgIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBFeHRlbmRzSW1wbGVtZW50c0RlZmluZXNNZW1iZXIgZXh0ZW5kcyBJbXBsZW1lbnRzRGVmaW5lc01lbWJlciB7fQorICAgIGludGVyZmFjZSBFeHRlbmRzRGVmaW5lc01lbWJlciBleHRlbmRzIERlZmluZXNNZW1iZXIge30KKyAgICBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgSW1wbGVtZW50c0V4dGVuZHNEZWZpbmVzTWVtYmVyIGltcGxlbWVudHMgRXh0ZW5kc0RlZmluZXNNZW1iZXIge30KKyAgICBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgRXh0ZW5kc0FuZEltcGxlbWVudHNEZWZpbmVzTWVtYmVyIGV4dGVuZHMgSW1wbGVtZW50c0RlZmluZXNNZW1iZXIKKyAgICAgICAgICAgIGltcGxlbWVudHMgRGVmaW5lc01lbWJlciB7fQorCisgICAgcHJpdmF0ZSBMaXN0PFN0cmluZz4gbmFtZXMoTWVtYmVyW10gbWV0aG9kcykgeworICAgICAgICBMaXN0PFN0cmluZz4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGZvciAoTWVtYmVyIG1ldGhvZCA6IG1ldGhvZHMpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hZGQobWV0aG9kLmdldE5hbWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBjb3VudChMaXN0PD8+IGxpc3QsIE9iamVjdCBlbGVtZW50KSB7CisgICAgICAgIGludCByZXN1bHQgPSAwOworICAgICAgICBmb3IgKE9iamVjdCBvIDogbGlzdCkgeworICAgICAgICAgICAgaWYgKG8uZXF1YWxzKGVsZW1lbnQpKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0Kys7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvQmlnRGVjaW1hbFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbWF0aC9CaWdEZWNpbWFsVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU3NzFlOWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvQmlnRGVjaW1hbFRlc3QuamF2YQpAQCAtMCwwICsxLDY3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubWF0aDsKKworaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOworaW1wb3J0IGphdmEubWF0aC5NYXRoQ29udGV4dDsKK2ltcG9ydCBqYXZhLm1hdGguUm91bmRpbmdNb2RlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIEJpZ0RlY2ltYWxUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdEdldFByZWNpc2lvbigpIHsKKyAgICAgICAgYXNzZXJ0UHJlY2lzaW9uKDEsICIwIik7CisgICAgICAgIGFzc2VydFByZWNpc2lvbigxLCAiMC45Iik7CisgICAgICAgIGFzc2VydFByZWNpc2lvbigxNiwgIjAuOTk5OTk5OTk5OTk5OTk5OSIpOworICAgICAgICBhc3NlcnRQcmVjaXNpb24oMTYsICI5OTk5OTk5OTk5OTk5OTk5Iik7CisgICAgICAgIGFzc2VydFByZWNpc2lvbigxOSwgIjEwMDAwMDAwMDAwMDAwMDAwMDAiKTsKKyAgICAgICAgYXNzZXJ0UHJlY2lzaW9uKDE5LCAiMTAwMDAwMDAwMDAwMDAwMDAwMSIpOworICAgICAgICBhc3NlcnRQcmVjaXNpb24oMTksICItMTAwMDAwMDAwMDAwMDAwMDAwMSIpOworICAgICAgICBhc3NlcnRQcmVjaXNpb24oMTksICItMTAwMDAwMDAwMDAwMDAwMDAwMCIpOworCisgICAgICAgIFN0cmluZyB0ZW5OaW5lcyA9ICI5OTk5OTk5OTk5IjsKKyAgICAgICAgU3RyaW5nIGZpZnR5TmluZXMgPSB0ZW5OaW5lcyArIHRlbk5pbmVzICsgdGVuTmluZXMgKyB0ZW5OaW5lcyArIHRlbk5pbmVzOworICAgICAgICBhc3NlcnRQcmVjaXNpb24oMTAsICIwLiIgKyB0ZW5OaW5lcyk7CisgICAgICAgIGFzc2VydFByZWNpc2lvbig1MCwgIjAuIiArIGZpZnR5TmluZXMpOworICAgICAgICBhc3NlcnRQcmVjaXNpb24oMjUwLCAiMC4iICsgZmlmdHlOaW5lcyArIGZpZnR5TmluZXMgKyBmaWZ0eU5pbmVzICsgZmlmdHlOaW5lcyArIGZpZnR5TmluZXMpOworICAgICAgICBhc3NlcnRQcmVjaXNpb24oMTAsIHRlbk5pbmVzKTsKKyAgICAgICAgYXNzZXJ0UHJlY2lzaW9uKDUwLCBmaWZ0eU5pbmVzKTsKKyAgICAgICAgYXNzZXJ0UHJlY2lzaW9uKDI1MCwgZmlmdHlOaW5lcyArIGZpZnR5TmluZXMgKyBmaWZ0eU5pbmVzICsgZmlmdHlOaW5lcyArIGZpZnR5TmluZXMpOworCisgICAgICAgIC8vIHRlc3QgdGhlc2Ugc3BlY2lhbCBjYXNlcyBiZWNhdXNlIHdlIGtub3cgcHJlY2lzaW9uKCkgdXNlcyBsb25ncyBpbnRlcm5hbGx5CisgICAgICAgIFN0cmluZyBtYXhMb25nID0gTG9uZy50b1N0cmluZyhMb25nLk1BWF9WQUxVRSk7CisgICAgICAgIGFzc2VydFByZWNpc2lvbihtYXhMb25nLmxlbmd0aCgpLCBtYXhMb25nKTsKKyAgICAgICAgU3RyaW5nIG1pbkxvbmcgPSBMb25nLnRvU3RyaW5nKExvbmcuTUlOX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0UHJlY2lzaW9uKG1pbkxvbmcubGVuZ3RoKCkgLSAxLCBtaW5Mb25nKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0UHJlY2lzaW9uKGludCBleHBlY3RlZFByZWNpc2lvbiwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIEJpZ0RlY2ltYWwgcGFyc2VkID0gbmV3IEJpZ0RlY2ltYWwodmFsdWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlVuZXhwZWN0ZWQgcHJlY2lzaW9uIGZvciBwYXJzZWQgdmFsdWUgIiArIHZhbHVlLAorICAgICAgICAgICAgICAgIGV4cGVjdGVkUHJlY2lzaW9uLCBwYXJzZWQucHJlY2lzaW9uKCkpOworCisgICAgICAgIEJpZ0RlY2ltYWwgY29tcHV0ZWQgPSBwYXJzZWQuZGl2aWRlKEJpZ0RlY2ltYWwuT05FKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJVbmV4cGVjdGVkIHByZWNpc2lvbiBmb3IgY29tcHV0ZWQgdmFsdWUgIiArIHZhbHVlLAorICAgICAgICAgICAgICAgIGV4cGVjdGVkUHJlY2lzaW9uLCBjb21wdXRlZC5wcmVjaXNpb24oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJvdW5kKCkgeworICAgICAgICBCaWdEZWNpbWFsIGJpZ0RlY2ltYWwgPSBuZXcgQmlnRGVjaW1hbCgiMC45OTk5OTk5OTk5OTk5OTkiKTsKKyAgICAgICAgQmlnRGVjaW1hbCByb3VuZGVkID0gYmlnRGVjaW1hbC5yb3VuZChuZXcgTWF0aENvbnRleHQoMiwgUm91bmRpbmdNb2RlLkZMT09SKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMC45OSIsIHJvdW5kZWQudG9TdHJpbmcoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9tYXRoL0JpZ0ludGVnZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvQmlnSW50ZWdlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iM2NmOTNmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9tYXRoL0JpZ0ludGVnZXJUZXN0LmphdmEKQEAgLTAsMCArMSw4NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm1hdGg7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKKworcHVibGljIGNsYXNzIEJpZ0ludGVnZXJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTE4NDUyCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSgpIHsKKyAgICAgICAgQmlnSW50ZWdlciBmaXJzdEJpZyAgPSBuZXcgQmlnSW50ZWdlcigiMzAwMDM1NDM2Njc4OTgzMTg4NTMiKTsKKyAgICAgICAgQmlnSW50ZWdlciBzZWNvbmRCaWcgPSBuZXcgQmlnSW50ZWdlcigiMzI5ODUzNTAyMjU5NyIpOworICAgICAgICBCaWdJbnRlZ2VyIGFuZGVkQmlncyA9IGZpcnN0QmlnLmFuZChzZWNvbmRCaWcpOworICAgICAgICBCaWdJbnRlZ2VyIHRvQ29tcGFyZUJpZyA9IEJpZ0ludGVnZXIudmFsdWVPZihhbmRlZEJpZ3MubG9uZ1ZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYW5kZWRCaWdzLCB0b0NvbXBhcmVCaWcpOworICAgICAgICBhc3NlcnRFcXVhbHMoYW5kZWRCaWdzLmhhc2hDb2RlKCksIHRvQ29tcGFyZUJpZy5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICAvLyBodHRwOi8vYi8yOTgxMDcyIC0gb2ZmLWJ5LW9uZSBlcnJvciBpbiBCaWdJbnRlZ2VyLnZhbHVlT2YKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3ZhbHVlT2YoKSB7CisgICAgICAgIC8vIEkgYXNzdW1lIGhlcmUgdGhhdCB3ZSdsbCBuZXZlciBjYWNoZSBtb3JlIHRoYW4gMTAyNCB2YWx1ZXMuCisgICAgICAgIC8vIChBdCB0aGUgbW9tZW50LCB3ZSBjYWNoZSAtMSB0byAxMC4pCisgICAgICAgIGZvciAoaW50IGkgPSAtMTAyNDsgaSA8PSAxMDI0OyArK2kpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpLCBCaWdJbnRlZ2VyLnZhbHVlT2YoaSkuaW50VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTcwMzYKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ludmFsaWRCaWdJbnRlZ2VyU3RyaW5nQ29udmVyc2lvbnMoKSB7CisgICAgICAgIC8vIENoZWNrIHdlIGRvbid0IGRpc2FsbG93IHJlbGF0ZWQgcmVhc29uYWJsZSBzdHJpbmdzLi4uCisgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIxIiwgMTApOworICAgICAgICBuZXcgQmlnSW50ZWdlcigiMWEiLCAxNik7CisgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCItMSIsIDEwKTsKKyAgICAgICAgbmV3IEJpZ0ludGVnZXIoIi0xYSIsIDE2KTsKKyAgICAgICAgbmV3IEJpZ0ludGVnZXIoIlx1MDY2MSIsIDEwKTsKKyAgICAgICAgbmV3IEJpZ0ludGVnZXIoIlx1MDY2MWEiLCAxNik7CisgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCItXHUwNjYxIiwgMTApOworICAgICAgICBuZXcgQmlnSW50ZWdlcigiLVx1MDY2MWEiLCAxNik7CisgICAgICAgIC8vIFRoaXMgaXMgYWxsb3dlZCBmcm9tIEphdmEgNyBvbi4KKyAgICAgICAgbmV3IEJpZ0ludGVnZXIoIisxIik7CisgICAgICAgIC8vIE5vdyBjaGVjayB0aGUgaW52YWxpZCBjYXNlcy4uLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIi1hIik7IC8vIG5vIGRpZ2l0cyBmcm9tIG90aGVyIGJhc2VzLgorICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIi0xYSIpOyAvLyBubyB0cmFpbGluZyBkaWdpdHMgZnJvbSBvdGhlciBiYXNlcy4KKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCItMSBoZWxsbyIpOyAvLyBubyB0cmFpbGluZyBqdW5rIGF0IGFsbC4KKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCItLTEiKTsgLy8gb25seSBvbmUgc2lnbi4KKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIiKTsgLy8gYXQgbGVhc3Qgb25lIGRpZ2l0LgorICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIi0iKTsgLy8gYXQgbGVhc3Qgb25lIGRpZ2l0LCBldmVuIGFmdGVyIGEgc2lnbi4KKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvTWF0aENvbnRleHRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvTWF0aENvbnRleHRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjAyMTIxOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbWF0aC9NYXRoQ29udGV4dFRlc3QuamF2YQpAQCAtMCwwICsxLDg3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubWF0aDsKKworaW1wb3J0IGphdmEubWF0aC5NYXRoQ29udGV4dDsKK2ltcG9ydCBqYXZhLm1hdGguUm91bmRpbmdNb2RlOworCitwdWJsaWMgY2xhc3MgTWF0aENvbnRleHRUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RydWN0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQWxsIHRoZSByb3VuZGluZyBtb2Rlcy4KKyAgICAgICAgZm9yIChSb3VuZGluZ01vZGUgcm0gOiBSb3VuZGluZ01vZGUudmFsdWVzKCkpIHsKKyAgICAgICAgICAgIE1hdGhDb250ZXh0IG1jID0gbmV3IE1hdGhDb250ZXh0KCJwcmVjaXNpb249MSByb3VuZGluZ01vZGU9IiArIHJtKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBtYy5nZXRQcmVjaXNpb24oKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMocm0sIG1jLmdldFJvdW5kaW5nTW9kZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEEgZmV3IHByZWNpc2lvbnMuCisgICAgICAgIGZvciAoaW50IHAgPSAwOyBwIDwgMTA7ICsrcCkgeworICAgICAgICAgICAgTWF0aENvbnRleHQgbWMgPSBuZXcgTWF0aENvbnRleHQoInByZWNpc2lvbj0iICsgcCArICIgcm91bmRpbmdNb2RlPSIgKyBSb3VuZGluZ01vZGUuVVApOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHAsIG1jLmdldFByZWNpc2lvbigpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhSb3VuZGluZ01vZGUuVVAsIG1jLmdldFJvdW5kaW5nTW9kZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIENhc2Utc2Vuc2l0aXZlIGtleXdvcmRzLgorICAgICAgICBuZXcgTWF0aENvbnRleHQoInByZWNpc2lvbj0xIHJvdW5kaW5nTW9kZT1VUCIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IE1hdGhDb250ZXh0KCJQcmVjaXNpb249MSByb3VuZGluZ01vZGU9VVAiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBNYXRoQ29udGV4dCgicHJlY2lzaW9uPTEgUm91bmRpbmdNb2RlPVVQIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gQ2FzZS1zZW5zaXRpdmUgcm91bmRpbmcgbW9kZXMuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgTWF0aENvbnRleHQoInByZWNpc2lvbj0xIHJvdW5kaW5nTW9kZT11cCIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEV4YWN0bHkgb25lIHNwYWNlIChVKzAwMjApLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IE1hdGhDb250ZXh0KCJwcmVjaXNpb249MXJvdW5kaW5nTW9kZT1VUCIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IE1hdGhDb250ZXh0KCJwcmVjaXNpb249MSAgcm91bmRpbmdNb2RlPVVQIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgTWF0aENvbnRleHQoInByZWNpc2lvbj0xXHRyb3VuZGluZ01vZGU9VVAiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICAvLyBObyBsZWFkaW5nIG9yIHRyYWlsaW5nIHNwYWNlLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IE1hdGhDb250ZXh0KCIgcHJlY2lzaW9uPTEgcm91bmRpbmdNb2RlPVVQIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgTWF0aENvbnRleHQoInByZWNpc2lvbj0xIHJvdW5kaW5nTW9kZT1VUCAiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvT2xkQmlnRGVjaW1hbEFyaXRobWV0aWNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvT2xkQmlnRGVjaW1hbEFyaXRobWV0aWNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjIzYjg1NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbWF0aC9PbGRCaWdEZWNpbWFsQXJpdGhtZXRpY1Rlc3QuamF2YQpAQCAtMCwwICsxLDY2OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubWF0aDsKKworaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEubWF0aC5NYXRoQ29udGV4dDsKK2ltcG9ydCBqYXZhLm1hdGguUm91bmRpbmdNb2RlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZEJpZ0RlY2ltYWxBcml0aG1ldGljVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRNYXRoQ29udGV4dE5vblRyaXZpYWwoKSB7CisgICAgICAgIE1hdGhDb250ZXh0IG1jOworICAgICAgICBCaWdEZWNpbWFsIGEsIGIsIHJlczsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgxNywgUm91bmRpbmdNb2RlLkZMT09SKTsKKyAgICAgICAgYSA9IG5ldyBCaWdEZWNpbWFsKCIxMjM0NTY3ODkwMTIzNDUuNjc4Iik7CisgICAgICAgIGIgPSBuZXcgQmlnRGVjaW1hbCgiMTAwMDAwMDAwMDAwMDAwLjAwOSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIxMjM0NTY3ODkwMTIzNDUuNjciLAorICAgICAgICAgICAgICAgIGEucm91bmQobWMpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIxMDAwMDAwMDAwMDAwMDAuMDAiLAorICAgICAgICAgICAgICAgIGIucm91bmQobWMpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIyMjM0NTY3ODkwMTIzNDUuNjciLAorICAgICAgICAgICAgICAgIGEucm91bmQobWMpLmFkZChiLnJvdW5kKG1jKSkudG9TdHJpbmcoKSk7CisgICAgICAgIHJlcyA9IGEuYWRkKGIsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiMjIzNDU2Nzg5MDEyMzQ1LjY4IiwgcmVzLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDMzLCBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkpOworICAgICAgICBhID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2NzguOTAxMjM5NSIpOworICAgICAgICBiID0gbmV3IEJpZ0RlY2ltYWwoIjEwMDAwMDAwMDAwMDAwMDAwOTAwMDAwMDAwMDAuMDAwMDAwNSIpOworICAgICAgICByZXMgPSBhLmFkZChiLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHZhbHVlISIsICIyMjM0NTY3ODkwMTIzNDU2ODc5MDEyMzQ1Njc4LjkwMTI0IiwgcmVzLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBzY2FsZSEiLCA1LCByZXMuc2NhbGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByZWNpc2lvbiEiLCAzMywgcmVzLnByZWNpc2lvbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3VidHJhY3RNYXRoQ29udGV4dE5vblRyaXZpYWwoKSB7CisgICAgICAgIE1hdGhDb250ZXh0IG1jOworICAgICAgICBCaWdEZWNpbWFsIGEsIGIsIHJlczsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgxNywgUm91bmRpbmdNb2RlLkZMT09SKTsKKyAgICAgICAgYSA9IG5ldyBCaWdEZWNpbWFsKCIxMjM0NTY3ODkwMTIzNDU2Ny44Iik7CisgICAgICAgIGIgPSBuZXcgQmlnRGVjaW1hbCgiMTAwMDAwMDAwMDAwMDAwMDAuOSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIyMzQ1Njc4OTAxMjM0NTY3IiwKKyAgICAgICAgICAgICAgICBhLnJvdW5kKG1jKS5zdWJ0cmFjdChiLnJvdW5kKG1jKSkudG9TdHJpbmcoKSk7CisgICAgICAgIHJlcyA9IGEuc3VidHJhY3QoYiwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIyMzQ1Njc4OTAxMjM0NTY2LjkiLCByZXMudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHNjYWxlISIsIDEsIHJlcy5zY2FsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJlY2lzaW9uISIsIDE3LCByZXMucHJlY2lzaW9uKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDMzLCBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkpOworICAgICAgICBhID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2NzguOTAxMjM5NSIpOworICAgICAgICBiID0gbmV3IEJpZ0RlY2ltYWwoIjEwMDAwMDAwMDAwMDAwMDAwOTAwMDAwMDAwMDAuMDAwMDAwNSIpOworICAgICAgICByZXMgPSBhLnN1YnRyYWN0KGIsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiMjM0NTY3ODkwMTIzNDU2Njk5MDEyMzQ1Njc4LjkwMTIzOSIsIHJlcy50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3Qgc2NhbGUhIiwgNiwgcmVzLnNjYWxlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcmVjaXNpb24hIiwgMzMsIHJlcy5wcmVjaXNpb24oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE11bHRpcGx5TWF0aENvbnRleHROb25Ucml2aWFsKCkgeworICAgICAgICBNYXRoQ29udGV4dCBtYzsKKyAgICAgICAgQmlnRGVjaW1hbCBhLCBiLCByZXM7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMTcsIFJvdW5kaW5nTW9kZS5GTE9PUik7CisgICAgICAgIGEgPSBuZXcgQmlnRGVjaW1hbCgiOTIzNDU2Nzg5MDEyMzQ1NjcuOCIpOworICAgICAgICBiID0gbmV3IEJpZ0RlY2ltYWwoIjEwMDAwMDAwMDAwMDAwMDAwLjkiKTsKKyAgICAgICAgcmVzID0gYS5yb3VuZChtYykubXVsdGlwbHkoYi5yb3VuZChtYykpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICI5MjM0NTY3ODkwMTIzNDU2NzAwMDAwMDAwMDAwMDAwMDAiLCByZXMudG9TdHJpbmcoKSk7CisgICAgICAgIHJlcyA9IHJlcy5yb3VuZChtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjkuMjM0NTY3ODkwMTIzNDU2N0UrMzIiLCByZXMudG9TdHJpbmcoKSk7CisgICAgICAgIHJlcyA9IGEubXVsdGlwbHkoYiwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICI5LjIzNDU2Nzg5MDEyMzQ1NzZFKzMyIiwgcmVzLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBzY2FsZSEiLCAtMTYsIHJlcy5zY2FsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJlY2lzaW9uISIsIDE3LCByZXMucHJlY2lzaW9uKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQb3dOb25Ucml2aWFsKCkgeworICAgICAgICBCaWdEZWNpbWFsIGEsIGIsIHJlczsKKworICAgICAgICBhID0gbmV3IEJpZ0RlY2ltYWwoIjEwMC45Iik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXMgPSBhLnBvdygtMSk7CisgICAgICAgICAgICBmYWlsKCJBcml0aG1ldGljRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24gZm9yIG5lZ2F0aXZlIGV4cG9uZW50Iik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzID0gYS5wb3coLTEwMyk7CisgICAgICAgICAgICBmYWlsKCJBcml0aG1ldGljRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24gZm9yIG5lZ2F0aXZlIGV4cG9uZW50Iik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQb3dNYXRoQ29udGV4dCgpIHsKKyAgICAgICAgU3RyaW5nIGEgPSAiMTIzMTIxMjQ3ODk4NzQ4Mjk4ODQyOTgwIjsKKyAgICAgICAgaW50IGFTY2FsZSA9IDEwOworICAgICAgICBpbnQgZXhwID0gMTA7CisgICAgICAgIFN0cmluZyBjID0gIjguMDA0NEUrMTMwIjsKKyAgICAgICAgaW50IGNTY2FsZSA9IC0xMjY7CisgICAgICAgIEJpZ0RlY2ltYWwgYU51bWJlciA9IG5ldyBCaWdEZWNpbWFsKG5ldyBCaWdJbnRlZ2VyKGEpLCBhU2NhbGUpOworICAgICAgICBNYXRoQ29udGV4dCBtYyA9IG5ldyBNYXRoQ29udGV4dCg1LCBSb3VuZGluZ01vZGUuSEFMRl9VUCk7CisgICAgICAgIEJpZ0RlY2ltYWwgcmVzdWx0ID0gYU51bWJlci5wb3coZXhwLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgYywgcmVzdWx0LnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCBzY2FsZSIsIGNTY2FsZSwgcmVzdWx0LnNjYWxlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQb3dNYXRoQ29udGV4dE5vblRyaXZpYWwoKSB7CisgICAgICAgIE1hdGhDb250ZXh0IG1jOworICAgICAgICBCaWdEZWNpbWFsIGEsIGIsIHJlczsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCg3LCBSb3VuZGluZ01vZGUuRkxPT1IpOworICAgICAgICBhID0gbmV3IEJpZ0RlY2ltYWwoIjEwMDAwMDAuOSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIxLjAwMDAwMEUrNjAwMCIsCisgICAgICAgICAgICAgICAgYS5yb3VuZChtYykucG93KDEwMDApLnJvdW5kKG1jKS50b1N0cmluZygpKTsKKyAgICAgICAgcmVzID0gYS5wb3coMTAwMCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIxLjAwMDkwMEUrNjAwMCIsIHJlcy50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCg0LCBSb3VuZGluZ01vZGUuRkxPT1IpOworICAgICAgICBhID0gbmV3IEJpZ0RlY2ltYWwoIjEwMDAuOSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIxLjAwMEUrMzAwMCIsCisgICAgICAgICAgICAgICAgYS5yb3VuZChtYykucG93KDEwMDApLnJvdW5kKG1jKS50b1N0cmluZygpKTsKKyAgICAgICAgcmVzID0gYS5wb3coMTAwMCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIyLjQ1OEUrMzAwMCIsIHJlcy50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgyLCBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkpOworICAgICAgICBhID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcyA9IGEucG93KC0yLCBtYyk7CisgICAgICAgICAgICBmYWlsKCJBcml0aG1ldGljRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYSA9IG5ldyBCaWdEZWNpbWFsKCIxMDAiKTsKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoNCwgUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZKTsKKyAgICAgICAgcmVzID0gYS5wb3coLTIsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiMC4wMDAxIiwgcmVzLnRvU3RyaW5nKCkpOworCisgICAgICAgIGEgPSBuZXcgQmlnRGVjaW1hbCgiMTAwMC45Iik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgwLCBSb3VuZGluZ01vZGUuRkxPT1IpOworICAgICAgICAgICAgcmVzID0gYS5wb3coLTEsIG1jKTsKKyAgICAgICAgICAgIGZhaWwoIkFyaXRobWV0aWNFeGNlcHRpb24gaXMgbm90IHRocm93biBmb3IgbmVnYXRpdmUgZXhwb25lbnQgYW5kIHByZWNpc2lvbiA9IDAiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYSA9IG5ldyBCaWdEZWNpbWFsKCIwMDAuMDAwMSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMCwgUm91bmRpbmdNb2RlLkZMT09SKTsKKyAgICAgICAgICAgIHJlcyA9IGEucG93KC0xLCBtYyk7CisgICAgICAgICAgICBmYWlsKCJBcml0aG1ldGljRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24gZm9yIG5lZ2F0aXZlIGV4cG9uZW50IGFuZCBwcmVjaXNpb24gPSAwIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGEgPSBuZXcgQmlnRGVjaW1hbCgiMUUtNDAwIik7CisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDQsIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSk7CisgICAgICAgIHJlcyA9IGEucG93KC0xLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjFFKzQwMCIsIHJlcy50b1N0cmluZygpKTsKKworLy8gICAgICAgIERvZXNuJ3Qgc3VjY2VlZCBhZ2FpbnN0IEpESyBvZiBTdW4hOgorLy8gICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDMsIFJvdW5kaW5nTW9kZS5GTE9PUik7CisvLyAgICAgICAgYSA9IG5ldyBCaWdEZWNpbWFsKCIxMDAuOSIpOworLy8gICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjEuMDBFKzIwMDAiLAorLy8gICAgICAgICAgICAgICAgYS5yb3VuZChtYykucG93KDEwMDApLnJvdW5kKG1jKS50b1N0cmluZygpKTsKKy8vICAgICAgICByZXMgPSBhLnBvdygxMDAwKS5yb3VuZChtYyk7CisvLyAgICAgICAgcmVzID0gYS5wb3coMTAwMCwgbWMpOworLy8gICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjcuNzgzRSsyMDAzIiwgcmVzLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REaXZpZGVJTm9uVHJpdmlhbCgpIHsKKyAgICAgICAgTWF0aENvbnRleHQgbWM7CisgICAgICAgIEJpZ0RlY2ltYWwgYSwgYiwgcmVzOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDE3LCBSb3VuZGluZ01vZGUuRkxPT1IpOworICAgICAgICBhID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1Njc4OTAxMjM0NTY3RTEyMzQiKTsKKyAgICAgICAgYiA9IG5ldyBCaWdEZWNpbWFsKCIxLjIzNDU2Nzg5MDEyMzQ1Njc5Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjFFKzEyNTAiLAorICAgICAgICAgICAgICAgIGEucm91bmQobWMpLmRpdmlkZShiLnJvdW5kKG1jKSkudG9TdHJpbmcoKSk7CisgICAgICAgIHJlcyA9IGEuZGl2aWRlKGIsIEJpZ0RlY2ltYWwuUk9VTkRfRkxPT1IpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICI5Ljk5OTk5OTk5OTk5OTk5OUUrMTI0OSIsIHJlcy50b1N0cmluZygpKTsKKworICAgICAgICBhID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2NzguOTAxMjM5NSIpOworICAgICAgICBiID0gbmV3IEJpZ0RlY2ltYWwoIjYxNzI4Mzk0NTA2MTcyODM5NDUwNjE3MjgzOTQuNTA2MTk3NSIpOworICAgICAgICByZXMgPSBhLmRpdmlkZShiLCBCaWdEZWNpbWFsLlJPVU5EX1VOTkVDRVNTQVJZKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiMC4yMDAwMDAwIiwgcmVzLnRvU3RyaW5nKCkpOworCisgICAgICAgIGEgPSBuZXcgQmlnRGVjaW1hbCgiMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3OC45MDEyMzk1Iik7CisgICAgICAgIGIgPSBuZXcgQmlnRGVjaW1hbCgiMTAwMDAwMDAwMDAwMDAwMDA5MDAwMDAwMDAwMC4wMDAwMDA1Iik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXMgPSBhLmRpdmlkZShiLCBCaWdEZWNpbWFsLlJPVU5EX1VOTkVDRVNTQVJZKTsKKyAgICAgICAgICAgIGZhaWwoIkFyaXRobWV0aWNFeGNlcHRpb24gaXMgbm90IHRocm93biBmb3IgUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REaXZpZGVJSU5vblRyaXZpYWwoKSB7CisgICAgICAgIE1hdGhDb250ZXh0IG1jOworICAgICAgICBCaWdEZWNpbWFsIGEsIGIsIHJlczsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgxNywgUm91bmRpbmdNb2RlLkZMT09SKTsKKyAgICAgICAgYSA9IG5ldyBCaWdEZWNpbWFsKCIxMjM0NTY3ODkwMTIzNDU2N0UxMjM0Iik7CisgICAgICAgIGIgPSBuZXcgQmlnRGVjaW1hbCgiMS4yMzQ1Njc4OTAxMjM0NTY3OSIpOworICAgICAgICByZXMgPSBhLmRpdmlkZShiLCAtMTIyMCwgQmlnRGVjaW1hbC5ST1VORF9GTE9PUik7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjkuOTk5OTk5OTk5OTk5OTk5MjcwOTk5OTkzNDM4OTlFKzEyNDkiLCByZXMudG9TdHJpbmcoKSk7CisKKyAgICAgICAgYSA9IG5ldyBCaWdEZWNpbWFsKCIxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4LjkwMTIzOTUiKTsKKyAgICAgICAgYiA9IG5ldyBCaWdEZWNpbWFsKCI2MTcyODM5NDUwNjE3MjgzOTQ1MDYxNzI4Mzk0LjUwNjE5NzUiKTsKKyAgICAgICAgcmVzID0gYS5kaXZpZGUoYiwgMSwgQmlnRGVjaW1hbC5ST1VORF9VTk5FQ0VTU0FSWSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjAuMiIsIHJlcy50b1N0cmluZygpKTsKKworICAgICAgICBhID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2NzguOTAxMjM5NSIpOworICAgICAgICBiID0gbmV3IEJpZ0RlY2ltYWwoIjYxNzI4Mzk0NTA2MTcyODM5NDUwNjE3MjgzOTQuNTA2MTk3NSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzID0gYS5kaXZpZGUoYiwgMCwgQmlnRGVjaW1hbC5ST1VORF9VTk5FQ0VTU0FSWSk7CisgICAgICAgICAgICBmYWlsKCJBcml0aG1ldGljRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24gZm9yIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBIYXMgYSByb3VuZGluZyBwcm9ibGVtLiBzZWVtcyBsaWtlIHRoZSBwcmVjaXNpb24gaXMKKyAgICAvLyAxIHRvbyBzbWFsbCBhbmQgY3V0cyBvZmYgdGhlIGxhc3QgZGlnaXQuIGFsc28gdGhpcyB0ZXN0IG1pZ2h0CisgICAgLy8gbm90IGJlIGNvcnJlY3QuIFRoZSBuYW1lIGltcGxpZXMgdGhhdCBzY2FsZSBzaG91bGQgYmUgdXNlZC4KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGl2aWRlU2NhbGVSb3VuZGluZ01vZGVOb25Ucml2aWFsKCkgeworICAgICAgICBNYXRoQ29udGV4dCBtYzsKKyAgICAgICAgQmlnRGVjaW1hbCBhLCBiLCByZXM7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMTcsIFJvdW5kaW5nTW9kZS5GTE9PUik7CisgICAgICAgIGEgPSBuZXcgQmlnRGVjaW1hbCgiMTIzNDU2Nzg5MDEyMzQ1NjcuMSIpOworICAgICAgICBiID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1Njc4OTAxMjM0NTY3LjkiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiMSIsCisgICAgICAgICAgICAgICAgYS5yb3VuZChtYykuZGl2aWRlKGIucm91bmQobWMpKS50b1N0cmluZygpKTsKKyAgICAgICAgcmVzID0gYS5kaXZpZGUoYiwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIwLjk5OTk5OTk5OTk5OTk5OTkzIiwgcmVzLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDEzLCBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkpOworICAgICAgICBhID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2NzguOTAxMjM5NSIpOworICAgICAgICBiID0gbmV3IEJpZ0RlY2ltYWwoIjYxNzI4Mzk0NTA2MTcyODM5NDUwNjE3MjgzOTQuNTA2MTk3NSIpOworICAgICAgICByZXMgPSBhLmRpdmlkZShiLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjAuMiIsIHJlcy50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzMywgUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZKTsKKyAgICAgICAgYSA9IG5ldyBCaWdEZWNpbWFsKCIxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4LjkwMTIzOTUiKTsKKyAgICAgICAgYiA9IG5ldyBCaWdEZWNpbWFsKCIxMDAwMDAwMDAwMDAwMDAwMDkwMDAwMDAwMDAwLjAwMDAwMDUiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcyA9IGEuZGl2aWRlKGIsIG1jKTsKKyAgICAgICAgICAgIGZhaWwoIkFyaXRobWV0aWNFeGNlcHRpb24gaXMgbm90IHRocm93biBmb3IgUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRoZSBzYW1lIHRlc3QgYW5kIHRoZSBzYW1lIHByb2JsZW0gbGlrZSB0ZXN0RGl2aWRlU2NhbGVSb3VuZGluZ01vZGVOb25Ucml2aWFsLgorICAgIHB1YmxpYyB2b2lkIHRlc3REaXZpZGVNYXRoQ29udGV4dE5vblRyaXZpYWwoKSB7CisgICAgICAgIE1hdGhDb250ZXh0IG1jOworICAgICAgICBCaWdEZWNpbWFsIGEsIGIsIHJlczsKKworLy8gRkFJTFMgQUdBSU5TVCBSSSE6CisvLyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoNiwgUm91bmRpbmdNb2RlLkZMT09SKTsKKy8vICAgICAgICBhID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1LjEiKTsKKy8vICAgICAgICBiID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1LjkiKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIxIiwKKy8vICAgICAgICAgICAgICAgIGEucm91bmQobWMpLmRpdmlkZShiLnJvdW5kKG1jKSkudG9TdHJpbmcoKSk7CisvLyAgICAgICAgcmVzID0gYS5kaXZpZGUoYiwgbWMpOworLy8gICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjAuOTk5OTMiLCByZXMudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoNSwgUm91bmRpbmdNb2RlLkZMT09SKTsKKyAgICAgICAgYSA9IG5ldyBCaWdEZWNpbWFsKCIxMjM0NS4xIik7CisgICAgICAgIGIgPSBuZXcgQmlnRGVjaW1hbCgiMTIzNDUuOSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIxIiwKKyAgICAgICAgICAgICAgICBhLnJvdW5kKG1jKS5kaXZpZGUoYi5yb3VuZChtYykpLnRvU3RyaW5nKCkpOworICAgICAgICByZXMgPSBhLmRpdmlkZShiLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjAuOTk5OTMiLCByZXMudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMTcsIFJvdW5kaW5nTW9kZS5GTE9PUik7CisgICAgICAgIGEgPSBuZXcgQmlnRGVjaW1hbCgiMTIzNDU2Nzg5MDEyMzQ1NjcuMSIpOworICAgICAgICBiID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1Njc4OTAxMjM0NTY3LjkiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiMSIsCisgICAgICAgICAgICAgICAgYS5yb3VuZChtYykuZGl2aWRlKGIucm91bmQobWMpKS50b1N0cmluZygpKTsKKyAgICAgICAgcmVzID0gYS5kaXZpZGUoYiwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIwLjk5OTk5OTk5OTk5OTk5OTkzIiwgcmVzLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsIHJlcy5yb3VuZChtYykudG9TdHJpbmcoKSwgcmVzLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDEzLCBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkpOworICAgICAgICBhID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2NzguOTAxMjM5NSIpOworICAgICAgICBiID0gbmV3IEJpZ0RlY2ltYWwoIjYxNzI4Mzk0NTA2MTcyODM5NDUwNjE3MjgzOTQuNTA2MTk3NSIpOworICAgICAgICByZXMgPSBhLmRpdmlkZShiLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjAuMiIsIHJlcy50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzMywgUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZKTsKKyAgICAgICAgYSA9IG5ldyBCaWdEZWNpbWFsKCIxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4LjkwMTIzOTUiKTsKKyAgICAgICAgYiA9IG5ldyBCaWdEZWNpbWFsKCIxMDAwMDAwMDAwMDAwMDAwMDkwMDAwMDAwMDAwLjAwMDAwMDUiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcyA9IGEuZGl2aWRlKGIsIG1jKTsKKyAgICAgICAgICAgIGZhaWwoIkFyaXRobWV0aWNFeGNlcHRpb24gaXMgbm90IHRocm93biBmb3IgUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REaXZpZGVUb0ludGVncmFsVmFsdWVCeVplcm8oKSB7CisgICAgICAgIFN0cmluZyBhID0gIjM3MzYxODY1Njc4NzY4NzY1Nzg5NTY5NTg3NjU2NzU2NzExMTkyMzgxMTg5MTE4OTM5Mzk1OTE3MzUiOworICAgICAgICBpbnQgYVNjYWxlID0gNDU7CisgICAgICAgIFN0cmluZyBiID0gIjAiOworICAgICAgICBpbnQgYlNjYWxlID0gLTcwOworICAgICAgICBTdHJpbmcgcmVzID0gIjI3NzkyMzE4NTUxNDY5MDM2NzQ3NDc3MDY4MyI7CisgICAgICAgIGludCByZXNTY2FsZSA9IDA7CisgICAgICAgIFN0cmluZyByZW0gPSAiMS4zMDMyNjkzODcxMjg4MzA5NTg3NTU4ODg1OTQzMzkxMDcwMDg3OTYwMzE5NDUyNDY1Nzg5OTkwRS0xNSI7CisgICAgICAgIGludCByZW1TY2FsZSA9IDcwOworICAgICAgICBCaWdEZWNpbWFsIGFOdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChuZXcgQmlnSW50ZWdlcihhKSwgYVNjYWxlKTsKKyAgICAgICAgQmlnRGVjaW1hbCBiTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwobmV3IEJpZ0ludGVnZXIoYiksIGJTY2FsZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBCaWdEZWNpbWFsIHJlc3VsdCA9IGFOdW1iZXIuZGl2aWRlVG9JbnRlZ3JhbFZhbHVlKGJOdW1iZXIpOworICAgICAgICAgICAgZmFpbCgiQXJpdGhtZXRpY0V4Y2VwdGlvbiBub3QgdGhyb3duIGZvciBkaXZpc2lvbiBieSAwIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REaXZpZGVUb0ludGVncmFsVmFsdWVNYXRoQ29udGV4dE5vblRyaXZpYWwoKSB7CisgICAgICAgIE1hdGhDb250ZXh0IG1jOworICAgICAgICBCaWdEZWNpbWFsIGEsIGIsIHJlczsKKworICAgICAgICBhID0gbmV3IEJpZ0RlY2ltYWwoIjkyMzQ1Njc4OTAxMjM0NTY3LjgiKTsKKyAgICAgICAgYiA9IG5ldyBCaWdEZWNpbWFsKCI0MyIpOworICAgICAgICByZXMgPSBhLm11bHRpcGx5KGIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIzOTcwODY0MTkyNzUzMDg2NDE1LjQiLCByZXMudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMjAsIFJvdW5kaW5nTW9kZS5ET1dOKTsKKyAgICAgICAgYSA9IG5ldyBCaWdEZWNpbWFsKCIzOTcwODY0MTkyNzUzMDg2NDE1LjQiKTsKKyAgICAgICAgYiA9IG5ldyBCaWdEZWNpbWFsKCI5MjM0NTY3ODkwMTIzNDU2Ny44Iik7CisgICAgICAgIGIgPSBuZXcgQmlnRGVjaW1hbCgiOTIzNDU2Nzg5MDEyMzQ1NjcuODAwMSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICI0MyIsCisgICAgICAgICAgICAgICAgYS5yb3VuZChtYykuZGl2aWRlVG9JbnRlZ3JhbFZhbHVlKGIucm91bmQobWMpKS50b1N0cmluZygpKTsKKyAgICAgICAgcmVzID0gYS5kaXZpZGVUb0ludGVncmFsVmFsdWUoYiwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICI0MiIsIHJlcy50b1N0cmluZygpKTsKKworLy8gICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDEsIFJvdW5kaW5nTW9kZS5ET1dOKTsKKy8vICAgICAgICByZXMgPSBhLmRpdmlkZVRvSW50ZWdyYWxWYWx1ZShiLCBtYyk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiNDIiLCByZXMudG9TdHJpbmcoKSk7CisKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgxNywgUm91bmRpbmdNb2RlLkZMT09SKTsKKyAgICAgICAgYSA9IG5ldyBCaWdEZWNpbWFsKCI1MTg1MTg1MTM4NTE4NTE4MzAiKTsKKyAgICAgICAgYiA9IG5ldyBCaWdEZWNpbWFsKCIxMjM0NTY3ODkwMTIzNDU2Ny45Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjQyIiwKKyAgICAgICAgICAgICAgICBhLnJvdW5kKG1jKS5kaXZpZGVUb0ludGVncmFsVmFsdWUoYi5yb3VuZChtYykpLnRvU3RyaW5nKCkpOworICAgICAgICByZXMgPSBhLmRpdmlkZVRvSW50ZWdyYWxWYWx1ZShiLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjQxIiwgcmVzLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGRpdmlkZUFuZFJlbWFpbmRlcihCaWdEZWNpbWFsKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REaXZpZGVBbmRSZW1haW5kZXJCeVplcm8oKSB7CisgICAgICAgIFN0cmluZyBhID0gIjM3MzYxODY1Njc4NzY4NzY1Nzg5NTY5NTg3NjU2NzU2NzExMTkyMzgxMTg5MTE4OTM5Mzk1OTE3MzUiOworICAgICAgICBpbnQgYVNjYWxlID0gNDU7CisgICAgICAgIFN0cmluZyBiID0gIjAiOworICAgICAgICBpbnQgYlNjYWxlID0gLTcwOworICAgICAgICBTdHJpbmcgcmVzID0gIjI3NzkyMzE4NTUxNDY5MDM2NzQ3NDc3MDY4MyI7CisgICAgICAgIGludCByZXNTY2FsZSA9IDA7CisgICAgICAgIFN0cmluZyByZW0gPSAiMS4zMDMyNjkzODcxMjg4MzA5NTg3NTU4ODg1OTQzMzkxMDcwMDg3OTYwMzE5NDUyNDY1Nzg5OTkwRS0xNSI7CisgICAgICAgIGludCByZW1TY2FsZSA9IDcwOworICAgICAgICBCaWdEZWNpbWFsIGFOdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChuZXcgQmlnSW50ZWdlcihhKSwgYVNjYWxlKTsKKyAgICAgICAgQmlnRGVjaW1hbCBiTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwobmV3IEJpZ0ludGVnZXIoYiksIGJTY2FsZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBCaWdEZWNpbWFsIHJlc3VsdFtdID0gYU51bWJlci5kaXZpZGVBbmRSZW1haW5kZXIoYk51bWJlcik7CisgICAgICAgICAgICBmYWlsKCJBcml0aG1ldGljRXhjZXB0aW9uIG5vdCB0aHJvd24gZm9yIGRpdmlzaW9uIGJ5IDAiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERpdmlkZUFuZFJlbWFpbmRlck1hdGhDb250ZXh0Tm9uVHJpdmlhbCgpIHsKKyAgICAgICAgTWF0aENvbnRleHQgbWM7CisgICAgICAgIEJpZ0RlY2ltYWwgYSwgYiwgcmVzW107CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMTMsIFJvdW5kaW5nTW9kZS5GTE9PUik7CisgICAgICAgIGEgPSBuZXcgQmlnRGVjaW1hbCgiMTIzNDU2Nzg5MDEyMzQ1NjcuMSIpOworICAgICAgICBiID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1Njc4OTAxMjM0NTY3LjkiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiMEUrNCIsCisgICAgICAgICAgICAgICAgYS5yb3VuZChtYykuZGl2aWRlQW5kUmVtYWluZGVyKGIucm91bmQobWMpKVsxXS50b1N0cmluZygpKTsKKyAgICAgICAgcmVzID0gYS5kaXZpZGVBbmRSZW1haW5kZXIoYiwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIxMjM0NTY3ODkwMTIzNDU2Ny4xIiwgcmVzWzFdLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDEsIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSk7CisgICAgICAgIGEgPSBuZXcgQmlnRGVjaW1hbCgiNjE3MjgzOTQ1MDYxNzI4Mzk0NTA2MTcyODM5NC41MDYxOTc2Iik7CisgICAgICAgIGIgPSBuZXcgQmlnRGVjaW1hbCgiMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3OC45MDEyMzk1Iik7CisgICAgICAgIHJlcyA9IGEuZGl2aWRlQW5kUmVtYWluZGVyKGIsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiMUUtNyIsIHJlc1sxXS50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzLCBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkpOworICAgICAgICBhID0gbmV3IEJpZ0RlY2ltYWwoIjYxNzI4Mzk0NTA2MTcyODM5NDUwNjE3MjgzOTQuNjAwMDAwMCIpOworICAgICAgICBiID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2NzguOTAxMjM5NSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzID0gYS5kaXZpZGVBbmRSZW1haW5kZXIoYiwgbWMpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiMC4wOTM4MDI1IiwgcmVzWzFdLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiMC4wOSIsIHJlc1sxXS5yb3VuZChtYykudG9TdHJpbmcoKSk7CisvLyAgICAgICAgICAgIGZhaWwoIkFyaXRobWV0aWNFeGNlcHRpb24gaXMgbm90IHRocm93biBmb3IgUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtYWluZGVyQnlaZXJvKCkgeworICAgICAgICBTdHJpbmcgYSA9ICIzNzM2MTg2NTY3ODc2ODc2NTc4OTU2OTU4NzY1Njc1NjcxMTE5MjM4MTE4OTExODkzOTM5NTkxNzM1IjsKKyAgICAgICAgaW50IGFTY2FsZSA9IDQ1OworICAgICAgICBTdHJpbmcgYiA9ICIwIjsKKyAgICAgICAgaW50IGJTY2FsZSA9IC03MDsKKyAgICAgICAgU3RyaW5nIHJlcyA9ICIyNzc5MjMxODU1MTQ2OTAzNjc0NzQ3NzA2ODMiOworICAgICAgICBpbnQgcmVzU2NhbGUgPSAwOworICAgICAgICBTdHJpbmcgcmVtID0gIjEuMzAzMjY5Mzg3MTI4ODMwOTU4NzU1ODg4NTk0MzM5MTA3MDA4Nzk2MDMxOTQ1MjQ2NTc4OTk5MEUtMTUiOworICAgICAgICBpbnQgcmVtU2NhbGUgPSA3MDsKKyAgICAgICAgQmlnRGVjaW1hbCBhTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwobmV3IEJpZ0ludGVnZXIoYSksIGFTY2FsZSk7CisgICAgICAgIEJpZ0RlY2ltYWwgYk51bWJlciA9IG5ldyBCaWdEZWNpbWFsKG5ldyBCaWdJbnRlZ2VyKGIpLCBiU2NhbGUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQmlnRGVjaW1hbCByZXN1bHQgPSBhTnVtYmVyLnJlbWFpbmRlcihiTnVtYmVyKTsKKyAgICAgICAgICAgIGZhaWwoIkFyaXRobWV0aWNFeGNlcHRpb24gbm90IHRocm93biBmb3IgZGl2aXNpb24gYnkgMCIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtYWluZGVyTWF0aENvbnRleHROb25Ucml2aWFsKCkgeworICAgICAgICBNYXRoQ29udGV4dCBtYzsKKyAgICAgICAgQmlnRGVjaW1hbCBhLCBiLCByZXM7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMTMsIFJvdW5kaW5nTW9kZS5ET1dOKTsKKyAgICAgICAgYSA9IG5ldyBCaWdEZWNpbWFsKCIxMjM0NTY3ODkwMTIzNDU2Ny4xIik7CisgICAgICAgIGIgPSBuZXcgQmlnRGVjaW1hbCgiMTIzNDU2Nzg5MDEyMzQ1NjcuOSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIwRSs0IiwKKyAgICAgICAgICAgICAgICBhLnJvdW5kKG1jKS5kaXZpZGVBbmRSZW1haW5kZXIoYi5yb3VuZChtYykpWzFdLnRvU3RyaW5nKCkpOworICAgICAgICByZXMgPSBhLnJlbWFpbmRlcihiLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjEyMzQ1Njc4OTAxMjM0NTY3LjEiLCByZXMudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMSwgUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZKTsKKyAgICAgICAgYSA9IG5ldyBCaWdEZWNpbWFsKCI2MTcyODM5NDUwNjE3MjgzOTQ1MDYxNzI4Mzk0LjUwNjE5NzYiKTsKKyAgICAgICAgYiA9IG5ldyBCaWdEZWNpbWFsKCIxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4LjkwMTIzOTUiKTsKKyAgICAgICAgcmVzID0gYS5yZW1haW5kZXIoYiwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIxRS03IiwgcmVzLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDMsIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSk7CisgICAgICAgIGEgPSBuZXcgQmlnRGVjaW1hbCgiNjE3MjgzOTQ1MDYxNzI4Mzk0NTA2MTcyODM5NC42MDAwMDAwIik7CisgICAgICAgIGIgPSBuZXcgQmlnRGVjaW1hbCgiMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3OC45MDEyMzk1Iik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXMgPSBhLnJlbWFpbmRlcihiLCBtYyk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIwLjA5MzgwMjUiLCByZXMudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIwLjA5IiwgcmVzLnJvdW5kKG1jKS50b1N0cmluZygpKTsKKy8vICAgICAgICAgICAgZmFpbCgiQXJpdGhtZXRpY0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duIGZvciBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RSb3VuZE5vblRyaXZpYWwoKSB7CisgICAgICAgIE1hdGhDb250ZXh0IG1jOworICAgICAgICBTdHJpbmcgYmlTdHIgPSBuZXcgU3RyaW5nKCAiMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDUuMEUrMTAiKTsKKyAgICAgICAgU3RyaW5nIG5iaVN0ciA9IG5ldyBTdHJpbmcoIi0xMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NS5FKzEwIik7CisgICAgICAgIEJpZ0RlY2ltYWwgYmQ7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMTcsIFJvdW5kaW5nTW9kZS5GTE9PUik7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmV3IEJpZ0ludGVnZXIoIjEyMzQ1Njc4OTAxMjM0NTY3OCIpLCAzLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjEyMzQ1Njc4OTAxMjM0NS42NyIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDMxLCBSb3VuZGluZ01vZGUuVVApOworICAgICAgICBiZCA9IChuZXcgQmlnRGVjaW1hbChiaVN0cikpLnJvdW5kKG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAyRSs0NCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IChuZXcgQmlnRGVjaW1hbChuYmlTdHIpKS5yb3VuZChtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMkUrNDQiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgyOCwgUm91bmRpbmdNb2RlLkRPV04pOworICAgICAgICBiZCA9IChuZXcgQmlnRGVjaW1hbChiaVN0cikpLnJvdW5kKG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4RSs0NCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IChuZXcgQmlnRGVjaW1hbChuYmlTdHIpKS5yb3VuZChtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3OEUrNDQiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzMywgUm91bmRpbmdNb2RlLkNFSUxJTkcpOworICAgICAgICBiZCA9IChuZXcgQmlnRGVjaW1hbChiaVN0cikpLnJvdW5kKG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjRFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gKG5ldyBCaWdEZWNpbWFsKG5iaVN0cikpLnJvdW5kKG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjNFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMzQsIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiZCA9IChuZXcgQmlnRGVjaW1hbChiaVN0cikpLnJvdW5kKG1jKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIEFyaXRobWV0aWNFeGNlcHRpb24gZm9yIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJkID0gKG5ldyBCaWdEZWNpbWFsKG5iaVN0cikpLnJvdW5kKG1jKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIEFyaXRobWV0aWNFeGNlcHRpb24gZm9yIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCg3LCBSb3VuZGluZ01vZGUuRkxPT1IpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKCIxMDAwMDAwLjkiLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjEwMDAwMDAiLCBiZC50b1N0cmluZygpKTsKKyAgICB9CisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0RlY2ltYWwjYWRkKGphdmEubWF0aC5CaWdEZWNpbWFsKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkQmlnRGVjaW1hbCgpIHsKKyAgICAgICAgQmlnRGVjaW1hbCBhZGQxID0gbmV3IEJpZ0RlY2ltYWwoIjIzLjQ1NiIpOworICAgICAgICBCaWdEZWNpbWFsIGFkZDIgPSBuZXcgQmlnRGVjaW1hbCgiMzg0OS4yMzUiKTsKKyAgICAgICAgQmlnRGVjaW1hbCBzdW0gPSBhZGQxLmFkZChhZGQyKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhlIHN1bSBvZiAyMy40NTYgKyAzODQ5LjIzNSBpcyB3cm9uZyIsIHN1bS51bnNjYWxlZFZhbHVlKCkudG9TdHJpbmcoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgIjM4NzI2OTEiKQorICAgICAgICAgICAgICAgICYmIHN1bS5zY2FsZSgpID09IDMpOworICAgICAgICBhc3NlcnRUcnVlKCJ0aGUgc3VtIG9mIDIzLjQ1NiArIDM4NDkuMjM1IGlzIG5vdCBwcmludGVkIGNvcnJlY3RseSIsIHN1bS50b1N0cmluZygpLmVxdWFscygKKyAgICAgICAgICAgICAgICAiMzg3Mi42OTEiKSk7CisgICAgICAgIEJpZ0RlY2ltYWwgYWRkMyA9IG5ldyBCaWdEZWNpbWFsKDEyLjM0RTAyRCk7CisgICAgICAgIGFzc2VydFRydWUoInRoZSBzdW0gb2YgMjMuNDU2ICsgMTIuMzRFMDIgaXMgbm90IHByaW50ZWQgY29ycmVjdGx5IiwgKGFkZDEuYWRkKGFkZDMpKQorICAgICAgICAgICAgICAgIC50b1N0cmluZygpLmVxdWFscygiMTI1Ny40NTYiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0RlY2ltYWwjZGl2aWRlKGphdmEubWF0aC5CaWdEZWNpbWFsLAorICAgICAqICAgICAgICBqYXZhLm1hdGguTWF0aENvbnRleHQpIGRpdmlkZShCaWdEZWNpbWFsLCBSb3VuZGluZ01vZGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9EaXZpZGVCaWdEZWNpbWFsUm91bmRpbmdNb2RlVVAoKSB7CisgICAgICAgIFN0cmluZyBhID0gIi0zNzM2MTY3MTExOTIzODExODkxMTg5MzkzOTU5MTczNSI7CisgICAgICAgIFN0cmluZyBiID0gIjc0NzIzMzQyMjM4NDc2MjM3ODIzNzg3ODc5MTgzNDcwIjsKKyAgICAgICAgUm91bmRpbmdNb2RlIHJtID0gUm91bmRpbmdNb2RlLlVQOworICAgICAgICBTdHJpbmcgYyA9ICItMSI7CisgICAgICAgIEJpZ0RlY2ltYWwgYU51bWJlciA9IG5ldyBCaWdEZWNpbWFsKG5ldyBCaWdJbnRlZ2VyKGEpKTsKKyAgICAgICAgQmlnRGVjaW1hbCBiTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwobmV3IEJpZ0ludGVnZXIoYikpOworICAgICAgICBCaWdEZWNpbWFsIHJlc3VsdCA9IGFOdW1iZXIuZGl2aWRlKGJOdW1iZXIsIHJtKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCBjLCByZXN1bHQudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0RlY2ltYWwjZGl2aWRlKGphdmEubWF0aC5CaWdEZWNpbWFsLAorICAgICAqICAgICAgICBqYXZhLm1hdGguUm91bmRpbmdNb2RlKSBkaXZpZGUoQmlnRGVjaW1hbCwgUm91bmRpbmdNb2RlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfRGl2aWRlQmlnRGVjaW1hbFJvdW5kaW5nTW9kZURPV04oKSB7CisgICAgICAgIFN0cmluZyBhID0gIi0zNzM2MTY3MTExOTIzODExODkxMTg5MzkzOTU5MTczNSI7CisgICAgICAgIFN0cmluZyBiID0gIjc0NzIzMzQyMjM4NDc2MjM3ODIzNzg3ODc5MTgzNDcwIjsKKyAgICAgICAgUm91bmRpbmdNb2RlIHJtID0gUm91bmRpbmdNb2RlLkRPV047CisgICAgICAgIFN0cmluZyBjID0gIjAiOworICAgICAgICBCaWdEZWNpbWFsIGFOdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChuZXcgQmlnSW50ZWdlcihhKSk7CisgICAgICAgIEJpZ0RlY2ltYWwgYk51bWJlciA9IG5ldyBCaWdEZWNpbWFsKG5ldyBCaWdJbnRlZ2VyKGIpKTsKKyAgICAgICAgQmlnRGVjaW1hbCByZXN1bHQgPSBhTnVtYmVyLmRpdmlkZShiTnVtYmVyLCBybSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgYywgcmVzdWx0LnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdEZWNpbWFsI2RpdmlkZShqYXZhLm1hdGguQmlnRGVjaW1hbCwKKyAgICAgKiAgICAgICAgamF2YS5tYXRoLlJvdW5kaW5nTW9kZSkgZGl2aWRlKEJpZ0RlY2ltYWwsIFJvdW5kaW5nTW9kZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0RpdmlkZUJpZ0RlY2ltYWxSb3VuZGluZ01vZGVDRUlMSU5HKCkgeworICAgICAgICBTdHJpbmcgYSA9ICIzNzM2MTg2NTY3ODc2ODc2NTc4OTU2OTU4NzY1Njc1NjcxMTE5MjM4MTE4OTExODkzOTM5NTkxNzM1IjsKKyAgICAgICAgU3RyaW5nIGIgPSAiNzQ3MjMzNDIyMzg0NzYyMzc4MjM3ODc4NzkxODM0NzAiOworICAgICAgICBSb3VuZGluZ01vZGUgcm0gPSBSb3VuZGluZ01vZGUuQ0VJTElORzsKKyAgICAgICAgU3RyaW5nIGMgPSAiNTAwMDAyNjAzNzMxNjQyODY0MDEzNjE5MTQiOworICAgICAgICBCaWdEZWNpbWFsIGFOdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChuZXcgQmlnSW50ZWdlcihhKSk7CisgICAgICAgIEJpZ0RlY2ltYWwgYk51bWJlciA9IG5ldyBCaWdEZWNpbWFsKG5ldyBCaWdJbnRlZ2VyKGIpKTsKKyAgICAgICAgQmlnRGVjaW1hbCByZXN1bHQgPSBhTnVtYmVyLmRpdmlkZShiTnVtYmVyLCBybSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgYywgcmVzdWx0LnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdEZWNpbWFsI2RpdmlkZShqYXZhLm1hdGguQmlnRGVjaW1hbCwKKyAgICAgKiAgICAgICAgamF2YS5tYXRoLlJvdW5kaW5nTW9kZSkgZGl2aWRlKEJpZ0RlY2ltYWwsIFJvdW5kaW5nTW9kZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0RpdmlkZUJpZ0RlY2ltYWxSb3VuZGluZ01vZGVGTE9PUigpIHsKKyAgICAgICAgU3RyaW5nIGEgPSAiMzczNjE4NjU2Nzg3Njg3NjU3ODk1Njk1ODc2NTY3NTY3MTExOTIzODExODkxMTg5MzkzOTU5MTczNSI7CisgICAgICAgIFN0cmluZyBiID0gIjc0NzIzMzQyMjM4NDc2MjM3ODIzNzg3ODc5MTgzNDcwIjsKKyAgICAgICAgUm91bmRpbmdNb2RlIHJtID0gUm91bmRpbmdNb2RlLkZMT09SOworICAgICAgICBTdHJpbmcgYyA9ICI1MDAwMDI2MDM3MzE2NDI4NjQwMTM2MTkxMyI7CisgICAgICAgIEJpZ0RlY2ltYWwgYU51bWJlciA9IG5ldyBCaWdEZWNpbWFsKG5ldyBCaWdJbnRlZ2VyKGEpKTsKKyAgICAgICAgQmlnRGVjaW1hbCBiTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwobmV3IEJpZ0ludGVnZXIoYikpOworICAgICAgICBCaWdEZWNpbWFsIHJlc3VsdCA9IGFOdW1iZXIuZGl2aWRlKGJOdW1iZXIsIHJtKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCBjLCByZXN1bHQudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0RlY2ltYWwjZGl2aWRlKGphdmEubWF0aC5CaWdEZWNpbWFsLAorICAgICAqICAgICAgICBqYXZhLm1hdGguUm91bmRpbmdNb2RlKSBkaXZpZGUoQmlnRGVjaW1hbCwgUm91bmRpbmdNb2RlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfRGl2aWRlQmlnRGVjaW1hbFJvdW5kaW5nTW9kZUhBTEZfVVAoKSB7CisgICAgICAgIFN0cmluZyBhID0gIjM3MzYxODY1Njc4NzY4NzY1Nzg5NTY5NTg3NjU2NzU2NzExMTkyMzgxMTg5MTE4OTM5Mzk1OTE3MzUiOworICAgICAgICBTdHJpbmcgYiA9ICI3NDcyMzM0MjIzODQ3NjIzNzgyMzc4Nzg3OTE4MzQ3MCI7CisgICAgICAgIFJvdW5kaW5nTW9kZSBybSA9IFJvdW5kaW5nTW9kZS5IQUxGX1VQOworICAgICAgICBTdHJpbmcgYyA9ICI1MDAwMDI2MDM3MzE2NDI4NjQwMTM2MTkxMyI7CisgICAgICAgIEJpZ0RlY2ltYWwgYU51bWJlciA9IG5ldyBCaWdEZWNpbWFsKG5ldyBCaWdJbnRlZ2VyKGEpKTsKKyAgICAgICAgQmlnRGVjaW1hbCBiTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwobmV3IEJpZ0ludGVnZXIoYikpOworICAgICAgICBCaWdEZWNpbWFsIHJlc3VsdCA9IGFOdW1iZXIuZGl2aWRlKGJOdW1iZXIsIHJtKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCBjLCByZXN1bHQudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0RlY2ltYWwjZGl2aWRlKGphdmEubWF0aC5CaWdEZWNpbWFsLAorICAgICAqICAgICAgICBqYXZhLm1hdGguUm91bmRpbmdNb2RlKSBkaXZpZGUoQmlnRGVjaW1hbCwgUm91bmRpbmdNb2RlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfRGl2aWRlQmlnRGVjaW1hbFJvdW5kaW5nTW9kZUhBTEZfRE9XTigpIHsKKyAgICAgICAgU3RyaW5nIGEgPSAiMzczNjE4NjU2Nzg3Njg3NjU3ODk1Njk1ODc2NTY3NTY3MTExOTIzODExODkxMTg5MzkzOTU5MTczNSI7CisgICAgICAgIGludCBhU2NhbGUgPSA1OworICAgICAgICBTdHJpbmcgYiA9ICI3NDcyMzM0MjIzODQ3NjIzNzgyMzc4Nzg3OTE4MzQ3MCI7CisgICAgICAgIGludCBiU2NhbGUgPSAxNTsKKyAgICAgICAgaW50IG5ld1NjYWxlID0gNzsKKyAgICAgICAgUm91bmRpbmdNb2RlIHJtID0gUm91bmRpbmdNb2RlLkhBTEZfRE9XTjsKKyAgICAgICAgU3RyaW5nIGMgPSAiNTAwMDAyNjAzNzMxNjQyODY0MDEzNjE5MTMyNjIxMDA5NzIyLjE4MDM4MTAiOworICAgICAgICBCaWdEZWNpbWFsIGFOdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChuZXcgQmlnSW50ZWdlcihhKSwgYVNjYWxlKTsKKyAgICAgICAgQmlnRGVjaW1hbCBiTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwobmV3IEJpZ0ludGVnZXIoYiksIGJTY2FsZSk7CisgICAgICAgIEJpZ0RlY2ltYWwgcmVzdWx0ID0gYU51bWJlci5kaXZpZGUoYk51bWJlciwgbmV3U2NhbGUsIHJtKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCBjLCByZXN1bHQudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHNjYWxlIiwgbmV3U2NhbGUsIHJlc3VsdC5zY2FsZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm1hdGguQmlnRGVjaW1hbCNkaXZpZGUoamF2YS5tYXRoLkJpZ0RlY2ltYWwsCisgICAgICogICAgICAgIGphdmEubWF0aC5Sb3VuZGluZ01vZGUpIGRpdmlkZShCaWdEZWNpbWFsLCBSb3VuZGluZ01vZGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9EaXZpZGVCaWdEZWNpbWFsUm91bmRpbmdNb2RlSEFMRl9FVkVOKCkgeworICAgICAgICBTdHJpbmcgYSA9ICIzNzM2MTg2NTY3ODc2ODc2NTc4OTU2OTU4NzY1Njc1NjcxMTE5MjM4MTE4OTExODkzOTM5NTkxNzM1IjsKKyAgICAgICAgU3RyaW5nIGIgPSAiNzQ3MjMzNDIyMzg0NzYyMzc4MjM3ODc4NzkxODM0NzAiOworICAgICAgICBSb3VuZGluZ01vZGUgcm0gPSBSb3VuZGluZ01vZGUuSEFMRl9FVkVOOworICAgICAgICBTdHJpbmcgYyA9ICI1MDAwMDI2MDM3MzE2NDI4NjQwMTM2MTkxMyI7CisgICAgICAgIEJpZ0RlY2ltYWwgYU51bWJlciA9IG5ldyBCaWdEZWNpbWFsKG5ldyBCaWdJbnRlZ2VyKGEpKTsKKyAgICAgICAgQmlnRGVjaW1hbCBiTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwobmV3IEJpZ0ludGVnZXIoYikpOworICAgICAgICBCaWdEZWNpbWFsIHJlc3VsdCA9IGFOdW1iZXIuZGl2aWRlKGJOdW1iZXIsIHJtKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCBjLCByZXN1bHQudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0RlY2ltYWwjZGl2aWRlKGphdmEubWF0aC5CaWdEZWNpbWFsLAorICAgICAqICAgICAgICBqYXZhLm1hdGguUm91bmRpbmdNb2RlKSBkaXZpZGUoQmlnRGVjaW1hbCwgUm91bmRpbmdNb2RlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfRGl2aWRlQmlnRGVjaW1hbFJvdW5kaW5nRXhjKCkgeworICAgICAgICBTdHJpbmcgYSA9ICIzNzM2MTg2NTY3ODc2ODc2NTc4OTU2OTU4NzY1Njc1NjcxMTE5MjM4MTE4OTExODkzOTM5NTkxNzM1IjsKKyAgICAgICAgU3RyaW5nIGIgPSAiNzQ3MjMzNDIyMzg0NzYyMzc4MjM3ODc4NzkxODM0NzAiOworICAgICAgICBSb3VuZGluZ01vZGUgcm0gPSBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlk7CisgICAgICAgIEJpZ0RlY2ltYWwgYU51bWJlciA9IG5ldyBCaWdEZWNpbWFsKG5ldyBCaWdJbnRlZ2VyKGEpKTsKKyAgICAgICAgQmlnRGVjaW1hbCBiTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwobmV3IEJpZ0ludGVnZXIoYikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYU51bWJlci5kaXZpZGUoYk51bWJlciwgcm0pOworICAgICAgICAgICAgZmFpbCgiQXJpdGhtZXRpY0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duIGZvciBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkgZGl2aWRlciIpOworICAgICAgICB9IGNhdGNoIChqYXZhLmxhbmcuQXJpdGhtZXRpY0V4Y2VwdGlvbiBhZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYk51bWJlciA9IG5ldyBCaWdEZWNpbWFsKDApOworICAgICAgICAgICAgYU51bWJlci5kaXZpZGUoYk51bWJlciwgcm0pOworICAgICAgICAgICAgZmFpbCgiQXJpdGhtZXRpY0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duIGZvciB6ZXJvIGRpdmlkZXIiKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5sYW5nLkFyaXRobWV0aWNFeGNlcHRpb24gYWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvT2xkQmlnRGVjaW1hbENvbXBhcmVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvT2xkQmlnRGVjaW1hbENvbXBhcmVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzNhNmQ1ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbWF0aC9PbGRCaWdEZWNpbWFsQ29tcGFyZVRlc3QuamF2YQpAQCAtMCwwICsxLDYzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIEVsZW5hIFNlbXVraGluYQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm1hdGg7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnRGVjaW1hbDsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLm1hdGguTWF0aENvbnRleHQ7CitpbXBvcnQgamF2YS5tYXRoLlJvdW5kaW5nTW9kZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRCaWdEZWNpbWFsQ29tcGFyZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWJzTWF0aENvbnRleHROZWcoKSB7CisgICAgICAgIFN0cmluZyBhID0gIi0xMjM4MDk2NDgzOTIzODQ3NTQ1NzM1NjczNTY3NDU3MzUuNjM1Njc4OTAyOTU3ODQ5MDI3Njg3ODc2NzgyODdFKzIxIjsKKyAgICAgICAgQmlnRGVjaW1hbCBhTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoYSk7CisgICAgICAgIE1hdGhDb250ZXh0IG1jID0gbmV3IE1hdGhDb250ZXh0KDM0LCBSb3VuZGluZ01vZGUuVVApOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIxLjIzODA5NjQ4MzkyMzg0NzU0NTczNTY3MzU2NzQ1NzM1N0UrNTMiLCBhTnVtYmVyLmFicyhtYykudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMzQsIFJvdW5kaW5nTW9kZS5ET1dOKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiMS4yMzgwOTY0ODM5MjM4NDc1NDU3MzU2NzM1Njc0NTczNTZFKzUzIiwgYU51bWJlci5hYnMobWMpLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDM0LCBSb3VuZGluZ01vZGUuRkxPT1IpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIxLjIzODA5NjQ4MzkyMzg0NzU0NTczNTY3MzU2NzQ1NzM1NkUrNTMiLCBhTnVtYmVyLmFicyhtYykudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMzQsIFJvdW5kaW5nTW9kZS5DRUlMSU5HKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiMS4yMzgwOTY0ODM5MjM4NDc1NDU3MzU2NzM1Njc0NTczNTdFKzUzIiwgYU51bWJlci5hYnMobWMpLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDM0LCBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYU51bWJlci5hYnMobWMpOworICAgICAgICAgICAgZmFpbCgiTm8gQXJpdGhtZXRpY0V4Y2VwdGlvbiBmb3IgUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROZWdhdGVNYXRoQ29udGV4dFBvc2l0aXZlKCkgeworICAgICAgIFN0cmluZyBhID0gIjkyOTQ4NzgyMDk0NDg4NDc4MjMxMjEyNDc4OTg3NDgyOTg4NDI5ODA4Nzc5ODEwNDU3NjM0NzgxMzg0NzU2Nzk0OTg3IjsKKyAgICAgICBNYXRoQ29udGV4dCBtYyA9IG5ldyBNYXRoQ29udGV4dCgzNywgUm91bmRpbmdNb2RlLkZMT09SKTsKKyAgICAgICBCaWdEZWNpbWFsIGFOdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChuZXcgQmlnSW50ZWdlcihhKSwgNDEpOworICAgICAgIEJpZ0RlY2ltYWwgcmVzID0gYU51bWJlci5uZWdhdGUobWMpOworICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi05Mjk0ODc4MjA5NDQ4ODQ3ODIzMTIxMjQ3ODkuODc0ODI5ODg0MyIsIHJlcy50b1N0cmluZygpKTsKKyAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCBzY2FsZSIsIDEwLCByZXMuc2NhbGUoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9tYXRoL09sZEJpZ0RlY2ltYWxDb25zdHJ1Y3RvcnNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvT2xkQmlnRGVjaW1hbENvbnN0cnVjdG9yc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMGNhNTBkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9tYXRoL09sZEJpZ0RlY2ltYWxDb25zdHJ1Y3RvcnNUZXN0LmphdmEKQEAgLTAsMCArMSw3NzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgRWxlbmEgU2VtdWtoaW5hCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubWF0aDsKKworaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEubWF0aC5NYXRoQ29udGV4dDsKK2ltcG9ydCBqYXZhLm1hdGguUm91bmRpbmdNb2RlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZEJpZ0RlY2ltYWxDb25zdHJ1Y3RvcnNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogbmV3IEJpZ0RlY2ltYWwoQmlnSW50ZWdlciB2YWx1ZSwgTWF0aENvbnRleHQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0ckJpZ0ludGVnZXJNYXRoQ29udGV4dCgpIHsKKyAgICAgICAgU3RyaW5nIGEgPSAiMTIzMTIxMjQ3ODk4NzQ4Mjk4ODQyOTgwODc3OTgxMDQ1NzYzNDc4MTM4NDc1Njc5NDk4NyI7CisgICAgICAgIEJpZ0ludGVnZXIgYkEgPSBuZXcgQmlnSW50ZWdlcihhKTsKKyAgICAgICAgaW50IHByZWNpc2lvbiA9IDQ2OworICAgICAgICBSb3VuZGluZ01vZGUgcm0gPSBSb3VuZGluZ01vZGUuQ0VJTElORzsKKyAgICAgICAgTWF0aENvbnRleHQgbWMgPSBuZXcgTWF0aENvbnRleHQocHJlY2lzaW9uLCBybSk7CisgICAgICAgIFN0cmluZyByZXMgPSAiMTIzMTIxMjQ3ODk4NzQ4Mjk4ODQyOTgwODc3OTgxMDQ1NzYzNDc4MTM4NDc1NyI7CisgICAgICAgIGludCByZXNTY2FsZSA9IC02OworICAgICAgICBCaWdEZWNpbWFsIHJlc3VsdCA9IG5ldyBCaWdEZWNpbWFsKGJBLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgcmVzLCByZXN1bHQudW5zY2FsZWRWYWx1ZSgpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCBzY2FsZSIsIHJlc1NjYWxlLCByZXN1bHQuc2NhbGUoKSk7CisKKyAgICAgICAgLy8gTm93IHRlc3QgbW9yZSB0aGFuIGp1c3QgUm91bmRpbmdNb2RlLkNFSUxJTkc6CisgICAgICAgIC8vCisgICAgICAgIEJpZ0RlY2ltYWwgYmQ7CisgICAgICAgIEJpZ0ludGVnZXIgYmkgPSAgbmV3IEJpZ0ludGVnZXIoICIxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NSIpOworICAgICAgICBCaWdJbnRlZ2VyIG5iaSA9IG5ldyBCaWdJbnRlZ2VyKCItMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDUiKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzMSwgUm91bmRpbmdNb2RlLlVQKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChiaSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiMS4yMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDJFKzM0IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmJpLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMkUrMzQiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgyOCwgUm91bmRpbmdNb2RlLkRPV04pOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKGJpLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3OEUrMzQiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChuYmksIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4RSszNCIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDMzLCBSb3VuZGluZ01vZGUuQ0VJTElORyk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoYmksIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjRFKzM0IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmJpLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzRSszNCIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDM0LCBSb3VuZGluZ01vZGUuRkxPT1IpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKGJpLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNEUrMzQiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChuYmksIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM1RSszNCIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDM0LCBSb3VuZGluZ01vZGUuSEFMRl9FVkVOKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChiaSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiMS4yMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzRFKzM0IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmJpLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNEUrMzQiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChuZXcgQmlnSW50ZWdlcigiLTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzM1IiksIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0RSszNCIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDM0LCBSb3VuZGluZ01vZGUuSEFMRl9VUCk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoYmksIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM1RSszNCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5iaSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMS4yMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzVFKzM0IiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMzQsIFJvdW5kaW5nTW9kZS5IQUxGX0RPV04pOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKGJpLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNEUrMzQiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChuYmksIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0RSszNCIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDM0LCBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChiaSwgbWMpOworICAgICAgICAgICAgZmFpbCgiTm8gQXJpdGhtZXRpY0V4Y2VwdGlvbiBmb3IgUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChuYmksIG1jKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIEFyaXRobWV0aWNFeGNlcHRpb24gZm9yIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBuZXcgQmlnRGVjaW1hbChCaWdJbnRlZ2VyIHZhbHVlLCBpbnQgc2NhbGUsIE1hdGhDb250ZXh0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25zdHJCaWdJbnRlZ2VyU2NhbGVNYXRoQ29udGV4dCgpIHsKKyAgICAgICAgU3RyaW5nIGEgPSAiMTIzMTIxMjQ3ODk4NzQ4Mjk4ODQyOTgwODc3OTgxMDQ1NzYzNDc4MTM4NDc1Njc5NDk4NyI7CisgICAgICAgIEJpZ0ludGVnZXIgYkEgPSBuZXcgQmlnSW50ZWdlcihhKTsKKyAgICAgICAgaW50IGFTY2FsZSA9IDEwOworICAgICAgICBpbnQgcHJlY2lzaW9uID0gNDY7CisgICAgICAgIFJvdW5kaW5nTW9kZSBybSA9IFJvdW5kaW5nTW9kZS5DRUlMSU5HOworICAgICAgICBNYXRoQ29udGV4dCBtYyA9IG5ldyBNYXRoQ29udGV4dChwcmVjaXNpb24sIHJtKTsKKyAgICAgICAgU3RyaW5nIHJlcyA9ICIxMjMxMjEyNDc4OTg3NDgyOTg4NDI5ODA4Nzc5ODEwNDU3NjM0NzgxMzg0NzU3IjsKKyAgICAgICAgaW50IHJlc1NjYWxlID0gNDsKKyAgICAgICAgQmlnRGVjaW1hbCByZXN1bHQgPSBuZXcgQmlnRGVjaW1hbChiQSwgYVNjYWxlLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgcmVzLCByZXN1bHQudW5zY2FsZWRWYWx1ZSgpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCBzY2FsZSIsIHJlc1NjYWxlLCByZXN1bHQuc2NhbGUoKSk7CisKKyAgICAgICAgLy8gTm93IHRlc3QgbW9yZSB0aGFuIGp1c3QgUm91bmRpbmdNb2RlLkNFSUxJTkc6CisgICAgICAgIC8vCisgICAgICAgIC8vIEFUVEVOVElPTjoKKyAgICAgICAgLy8gICBUaGUgcmVtYWluaW5nIHNlY3Rpb24gaXMgVEVYVFVBTExZIENPUElFRAorICAgICAgICAvLyAgIGZyb20gdGVzdENvbnN0ckJpZ0ludGVnZXJNYXRoQ29udGV4dAorICAgICAgICAvLyAgIHdpdGggbWlub3IgcmVwZXRpdGl2ZSBtb2RpZmljYXRpb25zLgorICAgICAgICAvLworICAgICAgICBCaWdEZWNpbWFsIGJkOworCisgICAgICAgIEJpZ0ludGVnZXIgYmkgPSAgbmV3IEJpZ0ludGVnZXIoICIxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NSIpOworICAgICAgICBCaWdJbnRlZ2VyIG5iaSA9IG5ldyBCaWdJbnRlZ2VyKCItMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDUiKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzMSwgUm91bmRpbmdNb2RlLlVQKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChiaSwgLTEwLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMkUrNDQiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChuYmksIC0xMCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMS4yMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDJFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMjgsIFJvdW5kaW5nTW9kZS5ET1dOKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChiaSwgLTEwLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3OEUrNDQiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChuYmksIC0xMCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMS4yMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2NzhFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMzMsIFJvdW5kaW5nTW9kZS5DRUlMSU5HKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChiaSwgLTEwLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI0RSs0NCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5iaSwgLTEwLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzRSs0NCIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDM0LCBSb3VuZGluZ01vZGUuRkxPT1IpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKGJpLCAtMTAsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0RSs0NCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5iaSwgLTEwLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNUUrNDQiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzNCwgUm91bmRpbmdNb2RlLkhBTEZfRVZFTik7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoYmksIC0xMCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiMS4yMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzRFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmJpLCAtMTAsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0RSs0NCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5ldyBCaWdJbnRlZ2VyKCItMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzMzUiKSwgLTEwLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNEUrNDQiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzNCwgUm91bmRpbmdNb2RlLkhBTEZfVVApOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKGJpLCAtMTAsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM1RSs0NCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5iaSwgLTEwLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNUUrNDQiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzNCwgUm91bmRpbmdNb2RlLkhBTEZfRE9XTik7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoYmksIC0xMCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiMS4yMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzRFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmJpLCAtMTAsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0RSs0NCIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDM0LCBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChiaSwgLTEwLCBtYyk7CisgICAgICAgICAgICBmYWlsKCJObyBBcml0aG1ldGljRXhjZXB0aW9uIGZvciBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5iaSwgLTEwLCBtYyk7CisgICAgICAgICAgICBmYWlsKCJObyBBcml0aG1ldGljRXhjZXB0aW9uIGZvciBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gQW5kIGp1c3QgVEVYVFVBTExZIENPUElFRCBhZ2FpbjoKKyAgICAgICAgLy8KKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMzEsIFJvdW5kaW5nTW9kZS5VUCk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoYmksIDEwLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1LjY3ODkwMiIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5iaSwgMTAsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDUuNjc4OTAyIiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMjgsIFJvdW5kaW5nTW9kZS5ET1dOKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChiaSwgMTAsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDUuNjc4IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmJpLCAxMCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NS42NzgiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzMywgUm91bmRpbmdNb2RlLkNFSUxJTkcpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKGJpLCAxMCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NS42Nzg5MDEyNCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5iaSwgMTAsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDUuNjc4OTAxMjMiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzNCwgUm91bmRpbmdNb2RlLkZMT09SKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChiaSwgMTAsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDUuNjc4OTAxMjM0IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmJpLCAxMCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NS42Nzg5MDEyMzUiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzNCwgUm91bmRpbmdNb2RlLkhBTEZfRVZFTik7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoYmksIDEwLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1LjY3ODkwMTIzNCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5iaSwgMTAsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDUuNjc4OTAxMjM0IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmV3IEJpZ0ludGVnZXIoIi0xMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjMzNSIpLCAxMCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NS42Nzg5MDEyMzQiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzNCwgUm91bmRpbmdNb2RlLkhBTEZfVVApOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKGJpLCAxMCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NS42Nzg5MDEyMzUiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChuYmksIDEwLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1LjY3ODkwMTIzNSIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDM0LCBSb3VuZGluZ01vZGUuSEFMRl9ET1dOKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChiaSwgMTAsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDUuNjc4OTAxMjM0IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmJpLCAxMCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NS42Nzg5MDEyMzQiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzNCwgUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoYmksIDEwLCBtYyk7CisgICAgICAgICAgICBmYWlsKCJObyBBcml0aG1ldGljRXhjZXB0aW9uIGZvciBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5iaSwgMTAsIG1jKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIEFyaXRobWV0aWNFeGNlcHRpb24gZm9yIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgyOCwgUm91bmRpbmdNb2RlLkZMT09SKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChiaSwgMTAsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDUuNjc4IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmJpLCAxMCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NS42NzkiLCBiZC50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RyQmlnSW50ZWdlclNjYWxlTWF0aENvbnRleHRfQW5kcm9pZEZhaWx1cmUoKSB7CisgICAgICAgIE1hdGhDb250ZXh0IG1jOworICAgICAgICBCaWdEZWNpbWFsIGJkOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDE3LCBSb3VuZGluZ01vZGUuRkxPT1IpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5ldyBCaWdJbnRlZ2VyKCIxMjM0NTY3ODkwMTIzNDU2NzgiKSwgMywgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIxMjM0NTY3ODkwMTIzNDUuNjciLCBiZC50b1N0cmluZygpKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIG5ldyBCaWdEZWNpbWFsKGNoYXJbXSB2YWx1ZSwgaW50IG9mZnNldCwgaW50IGxlbiwgTWF0aENvbnRleHQgbWMpOworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25zdHJDaGFySW50SW50TWF0aENvbnRleHQoKSB7CisgICAgICAgIGNoYXIgdmFsdWVbXSA9IHsnLScsICcxJywgJzInLCAnMycsICc4JywgJzAnLCAnLicsICc0JywgJzcnLCAnMycsICc4JywgJ0UnLCAnLScsICc0JywgJzInLCAnMyd9OworICAgICAgICBpbnQgb2Zmc2V0ID0gMzsKKyAgICAgICAgaW50IGxlbiA9IDEyOworICAgICAgICBpbnQgcHJlY2lzaW9uID0gNDsKKyAgICAgICAgUm91bmRpbmdNb2RlIHJtID0gUm91bmRpbmdNb2RlLkNFSUxJTkc7CisgICAgICAgIE1hdGhDb250ZXh0IG1jID0gbmV3IE1hdGhDb250ZXh0KHByZWNpc2lvbiwgcm0pOworICAgICAgICBCaWdEZWNpbWFsIHJlc3VsdCA9IG5ldyBCaWdEZWNpbWFsKHZhbHVlLCBvZmZzZXQsIGxlbiwgbWMpOworICAgICAgICBTdHJpbmcgcmVzID0gIjMuODA1RS00MCI7CisgICAgICAgIGludCByZXNTY2FsZSA9IDQzOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsIHJlcywgcmVzdWx0LnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCBzY2FsZSIsIHJlc1NjYWxlLCByZXN1bHQuc2NhbGUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktNzgzCisgICAgICAgICAgICBuZXcgQmlnRGVjaW1hbChuZXcgY2hhcltdIHt9LCAwLCAwLCBNYXRoQ29udGV4dC5ERUNJTUFMMzIpOworICAgICAgICAgICAgZmFpbCgiTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIE5vdyB0ZXN0IG1vcmUgdGhhbiBqdXN0IFJvdW5kaW5nTW9kZS5DRUlMSU5HOgorICAgICAgICAvLworICAgICAgICAvLyBBVFRFTlRJT046CisgICAgICAgIC8vICAgVGhlIHJlbWFpbmluZyBzZWN0aW9uIGlzIFRFWFRVQUxMWSBDT1BJRUQKKyAgICAgICAgLy8gICBmcm9tIHRlc3RDb25zdHJCaWdJbnRlZ2VyU2NhbGVNYXRoQ29udGV4dAorICAgICAgICAvLyAgIHdpdGggbWlub3IgcmVwZXRpdGl2ZSBtb2RpZmljYXRpb25zLgorICAgICAgICAvLworICAgICAgICBjaGFyW10gYmlDQSA9ICAiYmxhOiAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NS4wRSsxMCwgYW5kIG1vcmUgYmxhIi50b0NoYXJBcnJheSgpOworICAgICAgICBjaGFyW10gbmJpQ0EgPSAiYmxhOiAtMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDUuRSsxMCwgYW5kIG1vcmUgYmxhIi50b0NoYXJBcnJheSgpOworICAgICAgICBCaWdEZWNpbWFsIGJkOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDMxLCBSb3VuZGluZ01vZGUuVVApOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKGJpQ0EsIDUsIDQxLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMkUrNDQiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChuYmlDQSwgNSwgNDEsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAyRSs0NCIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDI4LCBSb3VuZGluZ01vZGUuRE9XTik7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoYmlDQSwgNSwgNDEsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4RSs0NCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5iaUNBLCA1LCA0MSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMS4yMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2NzhFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMzMsIFJvdW5kaW5nTW9kZS5DRUlMSU5HKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChiaUNBLCA1LCA0MSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiMS4yMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyNEUrNDQiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChuYmlDQSwgNSwgNDEsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjNFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMzQsIFJvdW5kaW5nTW9kZS5GTE9PUik7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoYmlDQSwgNSwgNDEsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0RSs0NCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5iaUNBLCA1LCA0MSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMS4yMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzVFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMzQsIFJvdW5kaW5nTW9kZS5IQUxGX0VWRU4pOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKGJpQ0EsIDUsIDQxLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNEUrNDQiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChuYmlDQSwgNSwgNDEsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0RSs0NCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKCItMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzMzUwMDAwMDAwMDAwIi50b0NoYXJBcnJheSgpLCAwLCA0NiwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMS4yMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzRFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMzQsIFJvdW5kaW5nTW9kZS5IQUxGX1VQKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChiaUNBLCA1LCA0MSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiMS4yMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzVFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmJpQ0EsIDUsIDQxLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNUUrNDQiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzNCwgUm91bmRpbmdNb2RlLkhBTEZfRE9XTik7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoYmlDQSwgNSwgNDEsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0RSs0NCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5iaUNBLCA1LCA0MSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMS4yMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzRFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMzQsIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKGJpQ0EsIDUsIDQxLCBtYyk7CisgICAgICAgICAgICBmYWlsKCJObyBBcml0aG1ldGljRXhjZXB0aW9uIGZvciBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5iaUNBLCA1LCA0MSwgbWMpOworICAgICAgICAgICAgZmFpbCgiTm8gQXJpdGhtZXRpY0V4Y2VwdGlvbiBmb3IgUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIG5ldyBCaWdEZWNpbWFsKGNoYXJbXSB2YWx1ZSwgaW50IG9mZnNldCwgaW50IGxlbiwgTWF0aENvbnRleHQgbWMpOworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25zdHJDaGFySW50SW50TWF0aENvbnRleHRFeGNlcHRpb24xKCkgeworICAgICAgICBjaGFyIHZhbHVlW10gPSB7Jy0nLCAnMScsICcyJywgJzMnLCAnOCcsICcwJywgJy4nLCAnNCcsICc3JywgJzMnLCAnOCcsICdFJywgJy0nLCAnNCcsICcyJywgJzMnfTsKKyAgICAgICAgaW50IG9mZnNldCA9IDM7CisgICAgICAgIGludCBsZW4gPSAxMjA7CisgICAgICAgIGludCBwcmVjaXNpb24gPSA0OworICAgICAgICBSb3VuZGluZ01vZGUgcm0gPSBSb3VuZGluZ01vZGUuQ0VJTElORzsKKyAgICAgICAgTWF0aENvbnRleHQgbWMgPSBuZXcgTWF0aENvbnRleHQocHJlY2lzaW9uLCBybSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgQmlnRGVjaW1hbCh2YWx1ZSwgb2Zmc2V0LCBsZW4sIG1jKTsKKyAgICAgICAgICAgIGZhaWwoIk51bWJlckZvcm1hdEV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgfQorCisgICAgLyoqCisgICAgICogbmV3IEJpZ0RlY2ltYWwoY2hhcltdIHZhbHVlLCBNYXRoQ29udGV4dCBtYyk7CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0ckNoYXJNYXRoQ29udGV4dCgpIHsKKyAgICAgICAgLy8gTm93IHRlc3QgbW9yZSB0aGFuIGp1c3QgcmVncmVzc2lvbgorICAgICAgICAvLyAoZXZlbiBpZiBmb3IgcXVpdGUgc3VyZSB0aGUgaW1wbGVtZW50YXRpb24gd2lsbCB1c2UgdGhlIG9mZnNldC9sZW4gdmFyaWFudCBpbnRlcm5hbGx5KToKKyAgICAgICAgLy8KKyAgICAgICAgY2hhcltdIGJpQ0EgPSAgIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1LjBFKzEwIi50b0NoYXJBcnJheSgpOworICAgICAgICBjaGFyW10gbmJpQ0EgPSAiLTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1LkUrMTAiLnRvQ2hhckFycmF5KCk7CisgICAgICAgIEJpZ0RlY2ltYWwgYmQ7CisgICAgICAgIE1hdGhDb250ZXh0IG1jOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDMxLCBSb3VuZGluZ01vZGUuVVApOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKGJpQ0EsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAyRSs0NCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5iaUNBLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMkUrNDQiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgyOCwgUm91bmRpbmdNb2RlLkRPV04pOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKGJpQ0EsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4RSs0NCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKG5iaUNBLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3OEUrNDQiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzMywgUm91bmRpbmdNb2RlLkNFSUxJTkcpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKGJpQ0EsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjRFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmJpQ0EsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjNFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMzQsIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKGJpQ0EsIG1jKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIEFyaXRobWV0aWNFeGNlcHRpb24gZm9yIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmJpQ0EsIG1jKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIEFyaXRobWV0aWNFeGNlcHRpb24gZm9yIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBuZXcgQmlnRGVjaW1hbChkb3VibGUsIE1hdGhDb250ZXh0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25zdHJEb3VibGVNYXRoQ29udGV4dCgpIHsKKyAgICAgICAgZG91YmxlIGEgPSA3MzI1NDY5ODIzNzQ5ODIzNDc4OTIzNzkyODM1NzEwOTQ3OTcuMjg3MzQ2NzgyMzU5Mjg0NzU2OworICAgICAgICBpbnQgcHJlY2lzaW9uID0gMjE7CisgICAgICAgIFJvdW5kaW5nTW9kZSBybSA9IFJvdW5kaW5nTW9kZS5DRUlMSU5HOworICAgICAgICBNYXRoQ29udGV4dCBtYyA9IG5ldyBNYXRoQ29udGV4dChwcmVjaXNpb24sIHJtKTsKKyAgICAgICAgU3RyaW5nIHJlcyA9ICI3MzI1NDY5ODIzNzQ5ODIyODUwNzQiOworICAgICAgICBpbnQgcmVzU2NhbGUgPSAtMTU7CisgICAgICAgIEJpZ0RlY2ltYWwgcmVzdWx0ID0gbmV3IEJpZ0RlY2ltYWwoYSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsIHJlcywgcmVzdWx0LnVuc2NhbGVkVmFsdWUoKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3Qgc2NhbGUiLCByZXNTY2FsZSwgcmVzdWx0LnNjYWxlKCkpOworCisgICAgICAgIC8vIE5vdyB0ZXN0IG1vcmUgdGhhbiBqdXN0IFJvdW5kaW5nTW9kZS5DRUlMSU5HCisgICAgICAgIC8vCisgICAgICAgIEJpZ0RlY2ltYWwgYmQ7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoOSwgUm91bmRpbmdNb2RlLlVQKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgxMjM0NTY3ODkuMTI1LCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxMjM0NTY3OTAiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgtMTIzNDU2Nzg5LjEyNSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMTIzNDU2NzkwIiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoOCwgUm91bmRpbmdNb2RlLkRPV04pOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKDEyMzQ1Njc4OS4xMjUsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEuMjM0NTY3OEUrOCIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKC0xMjM0NTY3ODkuMTI1LCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xLjIzNDU2NzhFKzgiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgxMCwgUm91bmRpbmdNb2RlLkNFSUxJTkcpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKDEyMzQ1Njc4OS4xMjUsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEyMzQ1Njc4OS4yIiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoLTEyMzQ1Njc4OS4xMjUsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEyMzQ1Njc4OS4xIiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoOCwgUm91bmRpbmdNb2RlLkZMT09SKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgxMjM0NTY3ODkuMTI1LCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxLjIzNDU2NzhFKzgiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgtMTIzNDU2Nzg5LjEyNSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMS4yMzQ1Njc5RSs4IiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMTEsIFJvdW5kaW5nTW9kZS5IQUxGX0VWRU4pOworICAgICAgICAvLworICAgICAgICAvLyBWRVJZIEZVTk5ZOgorICAgICAgICAvLyBUaGlzIHdvcmtzOgorICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKCIxMjM0NTY3ODkuMTI1IiwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiMTIzNDU2Nzg5LjEyIiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIC8vIEJ1dCB0aGlzIGRvZXNuJ3Q6CisvLyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgxMjM0NTY3ODkuMTI1LCBtYyk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEyMzQ1Njc4OS4xMiIsIGJkLnRvU3RyaW5nKCkpOworCisvLyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgtMTIzNDU2Nzg5LjEyNSwgbWMpOworLy8gICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xMjM0NTY3ODkuMTIiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgtMTIzNDU2Nzg5LjEzNSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMTIzNDU2Nzg5LjE0IiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMTEsIFJvdW5kaW5nTW9kZS5IQUxGX1VQKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgiMTIzNDU2Nzg5LjEyNSIsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEyMzQ1Njc4OS4xMyIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIC8vIEFORCBIRVJFLCBUT086CisvLyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMTEsIFJvdW5kaW5nTW9kZS5IQUxGX1VQKTsKKy8vICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKDEyMzQ1Njc4OS4xMjUsIG1jKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiMTIzNDU2Nzg5LjEzIiwgYmQudG9TdHJpbmcoKSk7CisvLyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgtMTIzNDU2Nzg5LjEyNSwgbWMpOworLy8gICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xMjM0NTY3ODkuMTMiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgxMSwgUm91bmRpbmdNb2RlLkhBTEZfRE9XTik7CisgICAgICAgIC8vCisgICAgICAgIC8vIFNBTUUgSEVSRToKKyAgICAgICAgLy8gVGhpcyB3b3JrczoKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgiMTIzNDU2Nzg5LjEyNSIsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEyMzQ1Njc4OS4xMiIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICAvLyBCdXQgdGhpcyBkb2Vzbid0OgorLy8gICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoMTIzNDU2Nzg5LjEyNSwgbWMpOworLy8gICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxMjM0NTY3ODkuMTIiLCBiZC50b1N0cmluZygpKTsKKworLy8gICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoMTIzNDU2Nzg5LjEyNSwgbWMpOworLy8gICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxMjM0NTY3ODkuMTIiLCBiZC50b1N0cmluZygpKTsKKy8vICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKC0xMjM0NTY3ODkuMTI1LCBtYyk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEyMzQ1Njc4OS4xMiIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDgsIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKDEyMzQ1Njc4OS4xMjUsIG1jKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIEFyaXRobWV0aWNFeGNlcHRpb24gZm9yIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoLTEyMzQ1Njc4OS4xMjUsIG1jKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIEFyaXRobWV0aWNFeGNlcHRpb24gZm9yIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RyRG91YmxlTWF0aENvbnRleHRfQW5kcm9pZEZhaWx1cmUoKSB7CisgICAgICAgIEJpZ0RlY2ltYWwgYmQ7CisgICAgICAgIE1hdGhDb250ZXh0IG1jOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDExLCBSb3VuZGluZ01vZGUuSEFMRl9FVkVOKTsKKyAgICAgICAgLy8KKyAgICAgICAgLy8gVkVSWSBGVU5OWToKKyAgICAgICAgLy8gVGhpcyB3b3JrczoKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgiMTIzNDU2Nzg5LjEyNSIsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEyMzQ1Njc4OS4xMiIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICAvLyBCdXQgdGhpcyBkb2Vzbid0OgorICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKDEyMzQ1Njc4OS4xMjUsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEyMzQ1Njc4OS4xMiIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoLTEyMzQ1Njc4OS4xMjUsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEyMzQ1Njc4OS4xMiIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIC8vIEFORCBIRVJFLCBUT086CisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDExLCBSb3VuZGluZ01vZGUuSEFMRl9VUCk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoMTIzNDU2Nzg5LjEyNSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiMTIzNDU2Nzg5LjEzIiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoLTEyMzQ1Njc4OS4xMjUsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEyMzQ1Njc4OS4xMyIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDExLCBSb3VuZGluZ01vZGUuSEFMRl9ET1dOKTsKKyAgICAgICAgLy8KKyAgICAgICAgLy8gU0FNRSBIRVJFOgorICAgICAgICAvLyBUaGlzIHdvcmtzOgorICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKCIxMjM0NTY3ODkuMTI1IiwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiMTIzNDU2Nzg5LjEyIiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIC8vIEJ1dCB0aGlzIGRvZXNuJ3Q6CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoMTIzNDU2Nzg5LjEyNSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiMTIzNDU2Nzg5LjEyIiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgxMjM0NTY3ODkuMTI1LCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxMjM0NTY3ODkuMTIiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgtMTIzNDU2Nzg5LjEyNSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItMTIzNDU2Nzg5LjEyIiwgYmQudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogbmV3IEJpZ0RlY2ltYWwobG9uZywgTWF0aENvbnRleHQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0ckxvbmdNYXRoQ29udGV4dCgpIHsKKyAgICAgICAgbG9uZyBhID0gNDU3NjU3ODY3NzczMjU0Njk4Mkw7CisgICAgICAgIGludCBwcmVjaXNpb24gPSA1OworICAgICAgICBSb3VuZGluZ01vZGUgcm0gPSBSb3VuZGluZ01vZGUuQ0VJTElORzsKKyAgICAgICAgTWF0aENvbnRleHQgbWMgPSBuZXcgTWF0aENvbnRleHQocHJlY2lzaW9uLCBybSk7CisgICAgICAgIFN0cmluZyByZXMgPSAiNDU3NjYiOworICAgICAgICBpbnQgcmVzU2NhbGUgPSAtMTQ7CisgICAgICAgIEJpZ0RlY2ltYWwgcmVzdWx0ID0gbmV3IEJpZ0RlY2ltYWwoYSwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsIHJlcywgcmVzdWx0LnVuc2NhbGVkVmFsdWUoKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3Qgc2NhbGUiLCByZXNTY2FsZSwgcmVzdWx0LnNjYWxlKCkpOworCisgICAgICAgIC8vIE5vdyB0ZXN0IG1vcmUgdGhhbiBqdXN0IFJvdW5kaW5nTW9kZS5DRUlMSU5HCisgICAgICAgIC8vCisgICAgICAgIEJpZ0RlY2ltYWwgYmQ7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMTUsIFJvdW5kaW5nTW9kZS5VUCk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoNzg5MDEyMzQ1Njc4OTAxMjVMLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICI3Ljg5MDEyMzQ1Njc4OTAyRSsxNiIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKC03ODkwMTIzNDU2Nzg5MDEyNUwsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTcuODkwMTIzNDU2Nzg5MDJFKzE2IiwgYmQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgbWMgPSBuZXcgTWF0aENvbnRleHQoMTIsIFJvdW5kaW5nTW9kZS5ET1dOKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCg3ODkwMTIzNDU2Nzg5MDEyNUwsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjcuODkwMTIzNDU2NzhFKzE2IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoLTc4OTAxMjM0NTY3ODkwMTI1TCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICItNy44OTAxMjM0NTY3OEUrMTYiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgxNSwgUm91bmRpbmdNb2RlLkNFSUxJTkcpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKDc4OTAxMjM0NTY3ODkwMTI1TCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiNy44OTAxMjM0NTY3ODkwMkUrMTYiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgtNzg5MDEyMzQ1Njc4OTAxMjVMLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi03Ljg5MDEyMzQ1Njc4OTAxRSsxNiIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDEyLCBSb3VuZGluZ01vZGUuRkxPT1IpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKDc4OTAxMjM0NTY3ODkwMTI1TCwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiNy44OTAxMjM0NTY3OEUrMTYiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgtNzg5MDEyMzQ1Njc4OTAxMjVMLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi03Ljg5MDEyMzQ1Njc5RSsxNiIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDE2LCBSb3VuZGluZ01vZGUuSEFMRl9FVkVOKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCg3ODkwMTIzNDU2Nzg5MDEyNUwsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjcuODkwMTIzNDU2Nzg5MDEyRSsxNiIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKC03ODkwMTIzNDU2Nzg5MDEyNUwsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTcuODkwMTIzNDU2Nzg5MDEyRSsxNiIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKC03ODkwMTIzNDU2Nzg5MDEzNUwsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTcuODkwMTIzNDU2Nzg5MDE0RSsxNiIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDE2LCBSb3VuZGluZ01vZGUuSEFMRl9VUCk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoNzg5MDEyMzQ1Njc4OTAxMjVMLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICI3Ljg5MDEyMzQ1Njc4OTAxM0UrMTYiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgtNzg5MDEyMzQ1Njc4OTAxMjVMLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi03Ljg5MDEyMzQ1Njc4OTAxM0UrMTYiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgxNiwgUm91bmRpbmdNb2RlLkhBTEZfRE9XTik7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoNzg5MDEyMzQ1Njc4OTAxMjVMLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICI3Ljg5MDEyMzQ1Njc4OTAxMkUrMTYiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgtNzg5MDEyMzQ1Njc4OTAxMjVMLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi03Ljg5MDEyMzQ1Njc4OTAxMkUrMTYiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCg4LCBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCg3ODkwMTIzNDU2Nzg5MDEyNUwsIG1jKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIEFyaXRobWV0aWNFeGNlcHRpb24gZm9yIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoLTc4OTAxMjM0NTY3ODkwMTI1TCwgbWMpOworICAgICAgICAgICAgZmFpbCgiTm8gQXJpdGhtZXRpY0V4Y2VwdGlvbiBmb3IgUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIG5ldyBCaWdEZWNpbWFsKFN0cmluZyB2YWx1ZSkKKyAgICAgKiB3aGVuIHZhbHVlIGlzIG5vdCBhIHZhbGlkIHJlcHJlc2VudGF0aW9uIG9mIEJpZ0RlY2ltYWwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0clN0cmluZ0V4Y2VwdGlvbigpIHsKKyAgICAgICAgU3RyaW5nIGEgPSAiLTIzODc2OC43ODc2NzgyODdhKzEwIjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEJpZ0RlY2ltYWwgYmQgPSBuZXcgQmlnRGVjaW1hbChhKTsKKyAgICAgICAgICAgIGZhaWwoIk51bWJlckZvcm1hdEV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gY2F1Z2h0OiAiICsgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7fQorICAgIH0KKworICAgIC8qKgorICAgICAqIG5ldyBCaWdEZWNpbWFsKFN0cmluZyB2YWx1ZSwgTWF0aENvbnRleHQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0clN0cmluZ01hdGhDb250ZXh0KCkgeworICAgICAgICBTdHJpbmcgYSA9ICItMjM4NzY4Nzg3Njc4Mjg3ZTIxNCI7CisgICAgICAgIGludCBwcmVjaXNpb24gPSA1OworICAgICAgICBSb3VuZGluZ01vZGUgcm0gPSBSb3VuZGluZ01vZGUuQ0VJTElORzsKKyAgICAgICAgTWF0aENvbnRleHQgbWMgPSBuZXcgTWF0aENvbnRleHQocHJlY2lzaW9uLCBybSk7CisgICAgICAgIFN0cmluZyByZXMgPSAiLTIzODc2IjsKKyAgICAgICAgaW50IHJlc1NjYWxlID0gLTIyNDsKKyAgICAgICAgQmlnRGVjaW1hbCByZXN1bHQgPSBuZXcgQmlnRGVjaW1hbChhLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgcmVzLCByZXN1bHQudW5zY2FsZWRWYWx1ZSgpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCBzY2FsZSIsIHJlc1NjYWxlLCByZXN1bHQuc2NhbGUoKSk7CisKKyAgICAgICAgLy8gTm93IHRlc3QgbW9yZSB0aGFuIGp1c3QgUm91bmRpbmdNb2RlLkNFSUxJTkc6CisgICAgICAgIC8vCisgICAgICAgIFN0cmluZyBiaVN0ciA9IG5ldyBTdHJpbmcoICIxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NS4wRSsxMCIpOworICAgICAgICBTdHJpbmcgbmJpU3RyID0gbmV3IFN0cmluZygiLTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1LkUrMTAiKTsKKyAgICAgICAgQmlnRGVjaW1hbCBiZDsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgzMSwgUm91bmRpbmdNb2RlLlVQKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChiaVN0ciwgbWMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICAiMS4yMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDJFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmJpU3RyLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMkUrNDQiLCBiZC50b1N0cmluZygpKTsKKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCgyOCwgUm91bmRpbmdNb2RlLkRPV04pOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKGJpU3RyLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIxLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3OEUrNDQiLCBiZC50b1N0cmluZygpKTsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChuYmlTdHIsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiLTEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4RSs0NCIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDMzLCBSb3VuZGluZ01vZGUuQ0VJTElORyk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwoYmlTdHIsIG1jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIjEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjRFKzQ0IiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIGJkID0gbmV3IEJpZ0RlY2ltYWwobmJpU3RyLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIi0xLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzRSs0NCIsIGJkLnRvU3RyaW5nKCkpOworCisgICAgICAgIG1jID0gbmV3IE1hdGhDb250ZXh0KDM0LCBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChiaVN0ciwgbWMpOworICAgICAgICAgICAgZmFpbCgiTm8gQXJpdGhtZXRpY0V4Y2VwdGlvbiBmb3IgUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbChuYmlTdHIsIG1jKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIEFyaXRobWV0aWNFeGNlcHRpb24gZm9yIFJvdW5kaW5nTW9kZS5VTk5FQ0VTU0FSWSIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBtYyA9IG5ldyBNYXRoQ29udGV4dCg3LCBSb3VuZGluZ01vZGUuRkxPT1IpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKCIxMDAwMDAwLjkiLCBtYyk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjEwMDAwMDAiLCBiZC50b1N0cmluZygpKTsKKyAgICB9CisKKy8vIEFORFJPSUQgQURERUQKKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdEZWNpbWFsI0JpZ0RlY2ltYWwoamF2YS5tYXRoLkJpZ0ludGVnZXIsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yX2phdmFfbWF0aF9CaWdJbnRlZ2VyX2ludCgpIHsKKyAgICAgICAgQmlnSW50ZWdlciB2YWx1ZSA9IG5ldyBCaWdJbnRlZ2VyKCIxMjM0NTkwOCIpOworICAgICAgICBCaWdEZWNpbWFsIGJpZyA9IG5ldyBCaWdEZWNpbWFsKHZhbHVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhlIEJpZ0RlY2ltYWwgdmFsdWUgaXMgbm90IGluaXRpYWxpemVkIHByb3Blcmx5IiwKKyAgICAgICAgICAgICAgICBiaWcudW5zY2FsZWRWYWx1ZSgpLmVxdWFscyh2YWx1ZSkKKyAgICAgICAgICAgICAgICAmJiBiaWcuc2NhbGUoKSA9PSAwKTsKKworICAgICAgICBCaWdJbnRlZ2VyIHZhbHVlMiA9IG5ldyBCaWdJbnRlZ2VyKCIxMjMzNDU2MDAwMCIpOworICAgICAgICBCaWdEZWNpbWFsIGJpZzIgPSBuZXcgQmlnRGVjaW1hbCh2YWx1ZTIsIDUpOworICAgICAgICBhc3NlcnRUcnVlKCJ0aGUgQmlnRGVjaW1hbCB2YWx1ZSBpcyBub3QgaW5pdGlhbGl6ZWQgcHJvcGVybHkiLAorICAgICAgICAgICAgICAgIGJpZzIudW5zY2FsZWRWYWx1ZSgpLmVxdWFscyh2YWx1ZTIpCisgICAgICAgICAgICAgICAgJiYgYmlnMi5zY2FsZSgpID09IDUpOworICAgICAgICBhc3NlcnRUcnVlKCJ0aGUgQmlnRGVjaW1hbCB2YWx1ZSBpcyBub3QgcmVwcmVzZW50ZWQgcHJvcGVybHkiLCBiaWcyLnRvU3RyaW5nKCkuZXF1YWxzKAorICAgICAgICAgICAgICAgICIxMjMzNDUuNjAwMDAiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0RlY2ltYWwjQmlnRGVjaW1hbChkb3VibGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3Rvcl9Eb3VibGUoKSB7CisgICAgICAgIEJpZ0RlY2ltYWwgYmlnID0gbmV3IEJpZ0RlY2ltYWwoMTIzRTA0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhlIEJpZ0RlY2ltYWwgdmFsdWUgdGFraW5nIGEgZG91YmxlIGFyZ3VtZW50IGlzIG5vdCBpbml0aWFsaXplZCBwcm9wZXJseSIsIGJpZworICAgICAgICAgICAgICAgIC50b1N0cmluZygpLmVxdWFscygiMTIzMDAwMCIpKTsKKyAgICAgICAgYmlnID0gbmV3IEJpZ0RlY2ltYWwoMS4yMzQ1RS0xMik7CisgICAgICAgIGFzc2VydFRydWUoInRoZSBkb3VibGUgcmVwcmVzZW50YXRpb24gaXMgbm90IGNvcnJlY3QgZm9yIDEuMjM0NUUtMTIiLAorICAgICAgICAgICAgICAgIGJpZy5kb3VibGVWYWx1ZSgpID09IDEuMjM0NUUtMTIpOworICAgICAgICBiaWcgPSBuZXcgQmlnRGVjaW1hbCgtMTIzNDVFLTMpOworICAgICAgICBhc3NlcnRUcnVlKCJ0aGUgZG91YmxlIHJlcHJlc2VudGF0aW9uIGlzIG5vdCBjb3JyZWN0IGZvciAtMTIzNDVFLTMiLAorICAgICAgICAgICAgICAgIGJpZy5kb3VibGVWYWx1ZSgpID09IC0xMi4zNDUpOworICAgICAgICBiaWcgPSBuZXcgQmlnRGVjaW1hbCg1LjEyMzQ1Njc4OTc2NTQzMjFlMTM4KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhlIGRvdWJsZSByZXByZXNlbnRhdGlvbiBpcyBub3QgY29ycmVjdCBmb3IgNS4xMjM0NTY3ODk3NjU0MzIxZTEzOCIsIGJpZworICAgICAgICAgICAgICAgIC5kb3VibGVWYWx1ZSgpID09IDUuMTIzNDU2Nzg5NzY1NDMyMUUxMzgKKyAgICAgICAgICAgICAgICAmJiBiaWcuc2NhbGUoKSA9PSAwKTsKKyAgICAgICAgYmlnID0gbmV3IEJpZ0RlY2ltYWwoMC4xKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhlIGRvdWJsZSByZXByZXNlbnRhdGlvbiBvZiAwLjEgYmlnRGVjaW1hbCBpcyBub3QgY29ycmVjdCIsCisgICAgICAgICAgICAgICAgYmlnLmRvdWJsZVZhbHVlKCkgPT0gMC4xKTsKKyAgICAgICAgYmlnID0gbmV3IEJpZ0RlY2ltYWwoMC4wMDM0NSk7CisgICAgICAgIGFzc2VydFRydWUoInRoZSBkb3VibGUgcmVwcmVzZW50YXRpb24gb2YgMC4wMDM0NSBiaWdEZWNpbWFsIGlzIG5vdCBjb3JyZWN0IiwgYmlnCisgICAgICAgICAgICAgICAgLmRvdWJsZVZhbHVlKCkgPT0gMC4wMDM0NSk7CisgICAgICAgIC8vIHJlZ3Jlc3Npb24gdGVzdCBmb3IgSEFSTU9OWS0yNDI5CisgICAgICAgIGJpZyA9IG5ldyBCaWdEZWNpbWFsKC0wLjApOworICAgICAgICBhc3NlcnRUcnVlKCJ0aGUgZG91YmxlIHJlcHJlc2VudGF0aW9uIG9mIC0wLjAgYmlnRGVjaW1hbCBpcyBub3QgY29ycmVjdCIsIGJpZy5zY2FsZSgpID09IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdEZWNpbWFsI0JpZ0RlY2ltYWwoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yX2phdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgQmlnRGVjaW1hbCBiaWcgPSBuZXcgQmlnRGVjaW1hbCgiMzQ1LjIzNDk5NjAwMjkzODUwIik7CisgICAgICAgIGFzc2VydFRydWUoInRoZSBCaWdEZWNpbWFsIHZhbHVlIGlzIG5vdCBpbml0aWFsaXplZCBwcm9wZXJseSIsIGJpZy50b1N0cmluZygpLmVxdWFscygKKyAgICAgICAgICAgICAgICAiMzQ1LjIzNDk5NjAwMjkzODUwIikKKyAgICAgICAgICAgICAgICAmJiBiaWcuc2NhbGUoKSA9PSAxNCk7CisgICAgICAgIGJpZyA9IG5ldyBCaWdEZWNpbWFsKCItMTIzNDUiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhlIEJpZ0RlY2ltYWwgdmFsdWUgaXMgbm90IGluaXRpYWxpemVkIHByb3Blcmx5IiwgYmlnLnRvU3RyaW5nKCkuZXF1YWxzKAorICAgICAgICAgICAgICAgICItMTIzNDUiKQorICAgICAgICAgICAgICAgICYmIGJpZy5zY2FsZSgpID09IDApOworICAgICAgICBiaWcgPSBuZXcgQmlnRGVjaW1hbCgiMTIzLiIpOworICAgICAgICBhc3NlcnRUcnVlKCJ0aGUgQmlnRGVjaW1hbCB2YWx1ZSBpcyBub3QgaW5pdGlhbGl6ZWQgcHJvcGVybHkiLCBiaWcudG9TdHJpbmcoKS5lcXVhbHMoIjEyMyIpCisgICAgICAgICAgICAgICAgJiYgYmlnLnNjYWxlKCkgPT0gMCk7CisKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvT2xkQmlnRGVjaW1hbENvbnZlcnRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvT2xkQmlnRGVjaW1hbENvbnZlcnRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGYwMWExNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbWF0aC9PbGRCaWdEZWNpbWFsQ29udmVydFRlc3QuamF2YQpAQCAtMCwwICsxLDQ1MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBFbGVuYSBTZW11a2hpbmEKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5tYXRoOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7CitpbXBvcnQgamF2YS5tYXRoLk1hdGhDb250ZXh0OworaW1wb3J0IGphdmEubWF0aC5Sb3VuZGluZ01vZGU7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkQmlnRGVjaW1hbENvbnZlcnRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF9JbnRWYWx1ZUV4YWN0TmVnKCkgeworICAgICAgICBTdHJpbmcgYSA9ICItMTIzODA5NjQ4MzkyMzg0NzU0NTczNTY3MzU2NzQ1NzM1LjYzNTY3ODkwMjk1Nzg0OTAyNzY4Nzg3Njc4Mjg3RSsyMSI7CisgICAgICAgIEJpZ0RlY2ltYWwgYU51bWJlciA9IG5ldyBCaWdEZWNpbWFsKGEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYU51bWJlci5pbnRWYWx1ZUV4YWN0KCk7CisgICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuQXJpdGhtZXRpY0V4Y2VwdGlvbiBpc24ndCB0aHJvd24gYWZ0ZXIgY2FsbGluZyBpbnRWYWx1ZUV4YWN0Iik7CisgICAgICAgIH0gY2F0Y2ggKGphdmEubGFuZy5Bcml0aG1ldGljRXhjZXB0aW9uIGFlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfSW50VmFsdWVFeGFjdFBvcygpIHsKKyAgICAgICAgU3RyaW5nIGEgPSAiMTIzODA5NjQ4MzkyMzg0NzU0NTczNTY3MzU2NzQ1NzM1LjYzNTY3ODkwMjk1Nzg0OTAyNzY4Nzg3Njc4Mjg3RSsyMSI7CisgICAgICAgIEJpZ0RlY2ltYWwgYU51bWJlciA9IG5ldyBCaWdEZWNpbWFsKGEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYU51bWJlci5pbnRWYWx1ZUV4YWN0KCk7CisgICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuQXJpdGhtZXRpY0V4Y2VwdGlvbiBpc24ndCB0aHJvd24gYWZ0ZXIgY2FsbGluZyBpbnRWYWx1ZUV4YWN0Iik7CisgICAgICAgIH0gY2F0Y2ggKGphdmEubGFuZy5Bcml0aG1ldGljRXhjZXB0aW9uIGFlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfSW50VmFsdWVFeGFjdEZsb2F0TmVnKCkgeworICAgICAgICBCaWdEZWNpbWFsIGFOdW1iZXIgPSBuZXcgQmlnRGVjaW1hbCgiLTIxNDc0ODM2NDcuOTk5Iik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhTnVtYmVyLmludFZhbHVlRXhhY3QoKTsKKyAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5Bcml0aG1ldGljRXhjZXB0aW9uIGlzbid0IHRocm93biBhZnRlciBjYWxsaW5nIGludFZhbHVlRXhhY3QiKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5sYW5nLkFyaXRobWV0aWNFeGNlcHRpb24gYWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9JbnRWYWx1ZUV4YWN0RmxvYXRQb3MoKSB7CisgICAgICAgIGZsb2F0IGEgPSAyMTQ3NDgzNjQ2Ljk5OTk5RjsKKyAgICAgICAgQmlnRGVjaW1hbCBhTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoYSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhTnVtYmVyLmludFZhbHVlRXhhY3QoKTsKKyAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5Bcml0aG1ldGljRXhjZXB0aW9uIGlzbid0IHRocm93biBhZnRlciBjYWxsaW5nIGludFZhbHVlRXhhY3QiKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5sYW5nLkFyaXRobWV0aWNFeGNlcHRpb24gYWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9JbnRWYWx1ZUV4YWN0TG9uZ1BvcygpIHsKKyAgICAgICAgbG9uZyBhID0gMjE0NzQ4MzY0N0w7CisgICAgICAgIEJpZ0RlY2ltYWwgYU51bWJlciA9IG5ldyBCaWdEZWNpbWFsKGEpOworICAgICAgICBpbnQgaU51bWJlciA9IGFOdW1iZXIuaW50VmFsdWVFeGFjdCgpOworICAgICAgICBhc3NlcnRUcnVlKCJpbmNvcnJlY3QgdmFsdWUiLCBpTnVtYmVyID09IGEpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfSW50VmFsdWVFeGFjdExvbmdOZWcoKSB7CisgICAgICAgIGxvbmcgYSA9IC0yMTQ3NDgzNjQ4TDsKKyAgICAgICAgQmlnRGVjaW1hbCBhTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoYSk7CisgICAgICAgIGludCBpTnVtYmVyID0gYU51bWJlci5pbnRWYWx1ZUV4YWN0KCk7CisgICAgICAgIGFzc2VydFRydWUoImluY29ycmVjdCB2YWx1ZSIsIGlOdW1iZXIgPT0gYSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Mb25nVmFsdWVFeGFjdE5lZygpIHsKKyAgICAgICAgU3RyaW5nIGEgPSAiLTEyMzgwOTY0ODM5MjM4NDc1NDU3MzU2NzM1Njc0NTczNS42MzU2Nzg5MDI5NTc4NDkwMjc2ODc4NzY3ODI4N0UrMjEiOworICAgICAgICBCaWdEZWNpbWFsIGFOdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChhKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFOdW1iZXIubG9uZ1ZhbHVlRXhhY3QoKTsKKyAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5Bcml0aG1ldGljRXhjZXB0aW9uIGlzbid0IHRocm93biBhZnRlciBjYWxsaW5nIGxvbmdWYWx1ZUV4YWN0Iik7CisgICAgICAgIH0gY2F0Y2ggKGphdmEubGFuZy5Bcml0aG1ldGljRXhjZXB0aW9uIGFlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfTG9uZ1ZhbHVlRXhhY3RQb3MoKSB7CisgICAgICAgIFN0cmluZyBhID0gIjEyMzgwOTY0ODM5MjM4NDc1NDU3MzU2NzM1Njc0NTczNS42MzU2Nzg5MDI5NTc4NDkwMjc2ODc4NzY3ODI4N0UrMjEiOworICAgICAgICBCaWdEZWNpbWFsIGFOdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChhKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFOdW1iZXIubG9uZ1ZhbHVlRXhhY3QoKTsKKyAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5Bcml0aG1ldGljRXhjZXB0aW9uIGlzbid0IHRocm93biBhZnRlciBjYWxsaW5nIGxvbmdWYWx1ZUV4YWN0Iik7CisgICAgICAgIH0gY2F0Y2ggKGphdmEubGFuZy5Bcml0aG1ldGljRXhjZXB0aW9uIGFlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfTG9uZ1ZhbHVlRXhhY3RGbG9hdE5lZygpIHsKKyAgICAgICAgQmlnRGVjaW1hbCBhTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoIi05MjIzMzcyMDM2ODU0Nzc1ODA3Ljk5OTk5Iik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhTnVtYmVyLmxvbmdWYWx1ZUV4YWN0KCk7CisgICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuQXJpdGhtZXRpY0V4Y2VwdGlvbiBpc24ndCB0aHJvd24gYWZ0ZXIgY2FsbGluZyBsb25nVmFsdWVFeGFjdCIpOworICAgICAgICB9IGNhdGNoIChqYXZhLmxhbmcuQXJpdGhtZXRpY0V4Y2VwdGlvbiBhZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm1hdGguQmlnRGVjaW1hbCNsb25nVmFsdWVFeGFjdCgpIExvbmcgdmFsdWUgb2YgYSBwb3NpdGl2ZQorICAgICAqICAgICAgICBCaWdEZWNpbWFsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Mb25nVmFsdWVFeGFjdEZsb2F0UG9zKCkgeworICAgICAgICBmbG9hdCBhID0gOTIyMzM3MjAzNjg1NDc3NTgwNi45OTk5OUY7CisgICAgICAgIEJpZ0RlY2ltYWwgYU51bWJlciA9IG5ldyBCaWdEZWNpbWFsKGEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYU51bWJlci5sb25nVmFsdWVFeGFjdCgpOworICAgICAgICAgICAgZmFpbCgiamF2YS5sYW5nLkFyaXRobWV0aWNFeGNlcHRpb24gaXNuJ3QgdGhyb3duIGFmdGVyIGNhbGxpbmcgbG9uZ1ZhbHVlRXhhY3QiKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5sYW5nLkFyaXRobWV0aWNFeGNlcHRpb24gYWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9CeXRlVmFsdWVFeGFjdFBvcygpIHsKKyAgICAgICAgaW50IGkgPSAxMjc7CisgICAgICAgIEJpZ0RlY2ltYWwgYmROdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChpKTsKKyAgICAgICAgYnl0ZSBiTnVtYmVyID0gYmROdW1iZXIuYnl0ZVZhbHVlRXhhY3QoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaW5jb3JyZWN0IGJ5dGVWYWx1ZUV4YWN0IiwgaSA9PSBiTnVtYmVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0J5dGVWYWx1ZUV4YWN0TmVnKCkgeworICAgICAgICBTdHJpbmcgc051bWJlciA9ICItMTI3LjU2Nzg5IjsKKyAgICAgICAgaW50IGlOdW1iZXIgPSAtMTI4OworICAgICAgICBpbnQgaVByZXNpdGlvbiA9IDM7CisgICAgICAgIE1hdGhDb250ZXh0IG1jID0gbmV3IE1hdGhDb250ZXh0KGlQcmVzaXRpb24sIFJvdW5kaW5nTW9kZS5VUCk7CisgICAgICAgIEJpZ0RlY2ltYWwgYmROdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChzTnVtYmVyLCBtYyk7CisgICAgICAgIGJ5dGUgYk51bWJlciA9IGJkTnVtYmVyLmJ5dGVWYWx1ZUV4YWN0KCk7CisgICAgICAgIGFzc2VydFRydWUoImluY29ycmVjdCBieXRlVmFsdWVFeGFjdCIsIGlOdW1iZXIgPT0gYk51bWJlcik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9CeXRlVmFsdWVFeGFjdENoYXJaZXJvKCkgeworICAgICAgICBjaGFyW10gY051bWJlciA9IHsKKyAgICAgICAgICAgICAgICAnLScsICcwJywgJy4nLCAnMCcKKyAgICAgICAgfTsKKyAgICAgICAgaW50IGlOdW1iZXIgPSAwOworICAgICAgICBpbnQgaVByZXNpdGlvbiA9IDU7CisgICAgICAgIE1hdGhDb250ZXh0IG1jID0gbmV3IE1hdGhDb250ZXh0KGlQcmVzaXRpb24sIFJvdW5kaW5nTW9kZS5IQUxGX0RPV04pOworICAgICAgICBCaWdEZWNpbWFsIGJkTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoY051bWJlciwgbWMpOworICAgICAgICBieXRlIGJOdW1iZXIgPSBiZE51bWJlci5ieXRlVmFsdWVFeGFjdCgpOworICAgICAgICBhc3NlcnRUcnVlKCJpbmNvcnJlY3QgYnl0ZVZhbHVlRXhhY3QiLCBpTnVtYmVyID09IGJOdW1iZXIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQnl0ZVZhbHVlRXhhY3RTdHJpbmdaZXJvKCkgeworICAgICAgICBTdHJpbmcgc051bWJlciA9ICIwMDAwMDAwMDAwMDAwMCI7CisgICAgICAgIGludCBpTnVtYmVyID0gMDsKKyAgICAgICAgaW50IGlQcmVzaXRpb24gPSAwOworICAgICAgICBNYXRoQ29udGV4dCBtYyA9IG5ldyBNYXRoQ29udGV4dChpUHJlc2l0aW9uLCBSb3VuZGluZ01vZGUuSEFMRl9VUCk7CisgICAgICAgIEJpZ0RlY2ltYWwgYmROdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChzTnVtYmVyLCBtYyk7CisgICAgICAgIGJ5dGUgYk51bWJlciA9IGJkTnVtYmVyLmJ5dGVWYWx1ZUV4YWN0KCk7CisgICAgICAgIGFzc2VydFRydWUoImluY29ycmVjdCBieXRlVmFsdWVFeGFjdCIsIGlOdW1iZXIgPT0gYk51bWJlcik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9CeXRlVmFsdWVFeGFjdERvdWJsZU1heCgpIHsKKyAgICAgICAgZG91YmxlIGROdW1iZXIgPSBEb3VibGUuTUFYX1ZBTFVFOworICAgICAgICBCaWdEZWNpbWFsIGJkTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoZE51bWJlcik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiZE51bWJlci5ieXRlVmFsdWVFeGFjdCgpOworICAgICAgICAgICAgZmFpbCgiamF2YS5sYW5nLkFyaXRobWV0aWNFeGNlcHRpb24gaXNuJ3QgdGhyb3duIGFmdGVyIGNhbGxpbmcgYnl0ZVZhbHVlRXhhY3QiKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5sYW5nLkFyaXRobWV0aWNFeGNlcHRpb24gYWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0J5dGVWYWx1ZUV4YWN0RG91YmxlTWluKCkgeworICAgICAgICBkb3VibGUgZE51bWJlciA9IERvdWJsZS5NSU5fVkFMVUU7CisgICAgICAgIEJpZ0RlY2ltYWwgYmROdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChkTnVtYmVyKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJkTnVtYmVyLmJ5dGVWYWx1ZUV4YWN0KCk7CisgICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuQXJpdGhtZXRpY0V4Y2VwdGlvbiBpc24ndCB0aHJvd24gYWZ0ZXIgY2FsbGluZyBieXRlVmFsdWVFeGFjdCIpOworICAgICAgICB9IGNhdGNoIChqYXZhLmxhbmcuQXJpdGhtZXRpY0V4Y2VwdGlvbiBhZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQnl0ZVZhbHVlRXhhY3RGbG9hdFBvcygpIHsKKyAgICAgICAgZmxvYXQgZk51bWJlciA9IDEyMy41NDQ1RjsKKyAgICAgICAgQmlnRGVjaW1hbCBiZE51bWJlciA9IG5ldyBCaWdEZWNpbWFsKGZOdW1iZXIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmROdW1iZXIuYnl0ZVZhbHVlRXhhY3QoKTsKKyAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5Bcml0aG1ldGljRXhjZXB0aW9uIGlzbid0IHRocm93biBhZnRlciBjYWxsaW5nIGJ5dGVWYWx1ZUV4YWN0Iik7CisgICAgICAgIH0gY2F0Y2ggKGphdmEubGFuZy5Bcml0aG1ldGljRXhjZXB0aW9uIGFlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9CeXRlVmFsdWVFeGFjdEZsb2F0TmVnKCkgeworICAgICAgICBmbG9hdCBmTnVtYmVyID0gLTEyLjk4NzY1NDMyMUY7CisgICAgICAgIEJpZ0RlY2ltYWwgYmROdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChmTnVtYmVyKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJkTnVtYmVyLmJ5dGVWYWx1ZUV4YWN0KCk7CisgICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuQXJpdGhtZXRpY0V4Y2VwdGlvbiBpc24ndCB0aHJvd24gYWZ0ZXIgY2FsbGluZyBieXRlVmFsdWVFeGFjdCIpOworICAgICAgICB9IGNhdGNoIChqYXZhLmxhbmcuQXJpdGhtZXRpY0V4Y2VwdGlvbiBhZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQnl0ZVZhbHVlRXhhY3REb3VibGUoKSB7CisgICAgICAgIGRvdWJsZSBkTnVtYmVyID0gMTIzLjAwMDBEOworICAgICAgICBCaWdEZWNpbWFsIGJkTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoZE51bWJlcik7CisgICAgICAgIGJ5dGUgYk51bWJlciA9IGJkTnVtYmVyLmJ5dGVWYWx1ZUV4YWN0KCk7CisgICAgICAgIGFzc2VydFRydWUoImluY29ycmVjdCBieXRlVmFsdWVFeGFjdCIsIGROdW1iZXIgPT0gYk51bWJlcik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9CeXRlVmFsdWVFeGFjdExvbmdNaW4oKSB7CisgICAgICAgIGxvbmcgbE51bWJlciA9IExvbmcuTUlOX1ZBTFVFOworICAgICAgICBCaWdEZWNpbWFsIGJkTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwobE51bWJlcik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiZE51bWJlci5ieXRlVmFsdWVFeGFjdCgpOworICAgICAgICAgICAgZmFpbCgiamF2YS5sYW5nLkFyaXRobWV0aWNFeGNlcHRpb24gaXNuJ3QgdGhyb3duIGFmdGVyIGNhbGxpbmcgYnl0ZVZhbHVlRXhhY3QiKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5sYW5nLkFyaXRobWV0aWNFeGNlcHRpb24gYWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0J5dGVWYWx1ZUV4YWN0SW50TWF4KCkgeworICAgICAgICBpbnQgaU51bWJlciA9IEludGVnZXIuTUFYX1ZBTFVFOworICAgICAgICBCaWdEZWNpbWFsIGJkTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoaU51bWJlcik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiZE51bWJlci5ieXRlVmFsdWVFeGFjdCgpOworICAgICAgICAgICAgZmFpbCgiamF2YS5sYW5nLkFyaXRobWV0aWNFeGNlcHRpb24gaXNuJ3QgdGhyb3duIGFmdGVyIGNhbGxpbmcgYnl0ZVZhbHVlRXhhY3QiKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5sYW5nLkFyaXRobWV0aWNFeGNlcHRpb24gYWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0J5dGVWYWx1ZVBvcygpIHsKKyAgICAgICAgaW50IGkgPSAxMjc7CisgICAgICAgIEJpZ0RlY2ltYWwgYmROdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChpKTsKKyAgICAgICAgYnl0ZSBiTnVtYmVyID0gYmROdW1iZXIuYnl0ZVZhbHVlKCk7CisgICAgICAgIGFzc2VydFRydWUoImluY29ycmVjdCBieXRlVmFsdWUiLCBpID09IGJOdW1iZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0ZXN0IGphdmEubWF0aC5CaWdEZWNpbWFsI2J5dGVWYWx1ZSgpIENvbnZlcnQgbmVnYXRpdmUgQmlnRGVzaW1hbCB0bworICAgICAqICAgICAgIGJ5dGUgdHlwZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQnl0ZVZhbHVlTmVnKCkgeworICAgICAgICBTdHJpbmcgc051bWJlciA9ICItMTI3LjU2Nzg5IjsKKyAgICAgICAgaW50IGlOdW1iZXIgPSAtMTI4OworICAgICAgICBpbnQgaVByZXNpdGlvbiA9IDM7CisgICAgICAgIE1hdGhDb250ZXh0IG1jID0gbmV3IE1hdGhDb250ZXh0KGlQcmVzaXRpb24sIFJvdW5kaW5nTW9kZS5VUCk7CisgICAgICAgIEJpZ0RlY2ltYWwgYmROdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChzTnVtYmVyLCBtYyk7CisgICAgICAgIGJ5dGUgYk51bWJlciA9IGJkTnVtYmVyLmJ5dGVWYWx1ZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJpbmNvcnJlY3QgYnl0ZVZhbHVlRXhhY3QiLCBpTnVtYmVyID09IGJOdW1iZXIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQnl0ZVZhbHVlQ2hhclplcm8oKSB7CisgICAgICAgIGNoYXJbXSBjTnVtYmVyID0geworICAgICAgICAgICAgICAgICctJywgJzAnLCAnLicsICcwJworICAgICAgICB9OworICAgICAgICBpbnQgaU51bWJlciA9IDA7CisgICAgICAgIGludCBpUHJlc2l0aW9uID0gMDsKKyAgICAgICAgTWF0aENvbnRleHQgbWMgPSBuZXcgTWF0aENvbnRleHQoaVByZXNpdGlvbiwgUm91bmRpbmdNb2RlLkhBTEZfVVApOworICAgICAgICBCaWdEZWNpbWFsIGJkTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoY051bWJlciwgbWMpOworICAgICAgICBieXRlIGJOdW1iZXIgPSBiZE51bWJlci5ieXRlVmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaW5jb3JyZWN0IGJ5dGVWYWx1ZSIsIGlOdW1iZXIgPT0gYk51bWJlcik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9CeXRlVmFsdWVTdHJpbmdaZXJvKCkgeworICAgICAgICBTdHJpbmcgc051bWJlciA9ICIwMDAwMCI7CisgICAgICAgIGludCBpTnVtYmVyID0gMDsKKyAgICAgICAgaW50IGlQcmVzaXRpb24gPSAwOworICAgICAgICBNYXRoQ29udGV4dCBtYyA9IG5ldyBNYXRoQ29udGV4dChpUHJlc2l0aW9uLCBSb3VuZGluZ01vZGUuSEFMRl9VUCk7CisgICAgICAgIEJpZ0RlY2ltYWwgYmROdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChzTnVtYmVyLCBtYyk7CisgICAgICAgIGJ5dGUgYk51bWJlciA9IGJkTnVtYmVyLmJ5dGVWYWx1ZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJpbmNvcnJlY3QgYnl0ZVZhbHVlIiwgaU51bWJlciA9PSBiTnVtYmVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0J5dGVWYWx1ZURvdWJsZU1heCgpIHsKKyAgICAgICAgZG91YmxlIGROdW1iZXIgPSBEb3VibGUuTUFYX1ZBTFVFOworICAgICAgICBCaWdEZWNpbWFsIGJkTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoZE51bWJlcik7CisgICAgICAgIGludCByZXN1bHQgPSAwOworICAgICAgICBieXRlIGJOdW1iZXIgPSBiZE51bWJlci5ieXRlVmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaW5jb3JyZWN0IGJ5dGVWYWx1ZSIsIGJOdW1iZXIgPT0gcmVzdWx0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0J5dGVWYWx1ZURvdWJsZU1pbigpIHsKKyAgICAgICAgZG91YmxlIGROdW1iZXIgPSBEb3VibGUuTUlOX1ZBTFVFOworICAgICAgICBCaWdEZWNpbWFsIGJkTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoZE51bWJlcik7CisgICAgICAgIGludCByZXN1bHQgPSAwOworICAgICAgICBieXRlIGJOdW1iZXIgPSBiZE51bWJlci5ieXRlVmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaW5jb3JyZWN0IGJ5dGVWYWx1ZSIsIGJOdW1iZXIgPT0gcmVzdWx0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0J5dGVWYWx1ZUZsb2F0TmVnKCkgeworICAgICAgICBmbG9hdCBmTnVtYmVyID0gLTEyLjk4NzY1NDMyMUY7CisgICAgICAgIGJ5dGUgYlZhbHVlID0gLTEyOworICAgICAgICBCaWdEZWNpbWFsIGJkTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoZk51bWJlcik7CisgICAgICAgIGJ5dGUgYk51bWJlciA9IGJkTnVtYmVyLmJ5dGVWYWx1ZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJpbmNvcnJlY3QgYnl0ZVZhbHVlIiwgYk51bWJlciA9PSBiVmFsdWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQnl0ZVZhbHVlRG91YmxlKCkgeworICAgICAgICBkb3VibGUgZE51bWJlciA9IDEyMy4wMDAwRDsKKyAgICAgICAgQmlnRGVjaW1hbCBiZE51bWJlciA9IG5ldyBCaWdEZWNpbWFsKGROdW1iZXIpOworICAgICAgICBieXRlIGJOdW1iZXIgPSBiZE51bWJlci5ieXRlVmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaW5jb3JyZWN0IGJ5dGVWYWx1ZSIsIGROdW1iZXIgPT0gYk51bWJlcik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9CeXRlVmFsdWVMb25nTWluKCkgeworICAgICAgICBsb25nIGxOdW1iZXIgPSBMb25nLk1JTl9WQUxVRTsKKyAgICAgICAgaW50IHJlc3VsdCA9IDA7CisgICAgICAgIEJpZ0RlY2ltYWwgYmROdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChsTnVtYmVyKTsKKyAgICAgICAgYnl0ZSBiTnVtYmVyID0gYmROdW1iZXIuYnl0ZVZhbHVlKCk7CisgICAgICAgIGFzc2VydFRydWUoImluY29ycmVjdCBieXRlVmFsdWUiLCBiTnVtYmVyID09IHJlc3VsdCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9CeXRlVmFsdWVJbnRNaW4oKSB7CisgICAgICAgIGludCBpTnVtYmVyID0gSW50ZWdlci5NSU5fVkFMVUU7CisgICAgICAgIGludCByZXN1bHQgPSAwOworICAgICAgICBCaWdEZWNpbWFsIGJkTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoaU51bWJlcik7CisgICAgICAgIGJ5dGUgYk51bWJlciA9IGJkTnVtYmVyLmJ5dGVWYWx1ZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJpbmNvcnJlY3QgYnl0ZVZhbHVlIiwgYk51bWJlciA9PSByZXN1bHQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQnl0ZVZhbHVlSW50TWF4KCkgeworICAgICAgICBpbnQgaU51bWJlciA9IEludGVnZXIuTUFYX1ZBTFVFOworICAgICAgICBpbnQgcmVzdWx0ID0gLTE7CisgICAgICAgIEJpZ0RlY2ltYWwgYmROdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChpTnVtYmVyKTsKKyAgICAgICAgYnl0ZSBiTnVtYmVyID0gYmROdW1iZXIuYnl0ZVZhbHVlKCk7CisgICAgICAgIGFzc2VydFRydWUoImluY29ycmVjdCBieXRlVmFsdWUiLCBiTnVtYmVyID09IHJlc3VsdCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TaG9ydFZhbHVlTmVnKCkgeworICAgICAgICBTdHJpbmcgYSA9ICItMTIzODA5NjQ4MzkyMzg0NzU0NTczNTY3MzU2NzQ1NzM1LjYzNTY3ODkwMjk1Nzg0OTAyNzY4Nzg3Njc4Mjg3RSsyMSI7CisgICAgICAgIEJpZ0RlY2ltYWwgYU51bWJlciA9IG5ldyBCaWdEZWNpbWFsKGEpOworICAgICAgICBpbnQgcmVzdWx0ID0gMjM0NDk7CisgICAgICAgIGFzc2VydFRydWUoImluY29ycmVjdCB2YWx1ZSIsIGFOdW1iZXIuc2hvcnRWYWx1ZSgpID09IHJlc3VsdCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TaG9ydFZhbHVlUG9zKCkgeworICAgICAgICBTdHJpbmcgYSA9ICIxMjM4MDk2NDgzOTIzODQ3NTQ1NzM1NjczNTY3NDU3MzUuNjM1Njc4OTAyOTU3ODQ5MDI3Njg3ODc2NzgyODdFKzIxIjsKKyAgICAgICAgQmlnRGVjaW1hbCBhTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoYSk7CisgICAgICAgIGludCByZXN1bHQgPSAtMjM0NDk7CisgICAgICAgIGFzc2VydFRydWUoImluY29ycmVjdCB2YWx1ZSIsIGFOdW1iZXIuc2hvcnRWYWx1ZSgpID09IHJlc3VsdCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TaG9ydFZhbHVlRXhhY3ROZWcoKSB7CisgICAgICAgIFN0cmluZyBhID0gIi0xMjM4MDk2NDgzOTIzODQ3NTQ1NzM1NjczNTY3NDU3MzUuNjM1Njc4OTAyOTU3ODQ5MDI3Njg3ODc2NzgyODdFKzIxIjsKKyAgICAgICAgQmlnRGVjaW1hbCBhTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoYSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhTnVtYmVyLnNob3J0VmFsdWVFeGFjdCgpOworICAgICAgICAgICAgZmFpbCgiamF2YS5sYW5nLkFyaXRobWV0aWNFeGNlcHRpb24gaXNuJ3QgdGhyb3duIGFmdGVyIGNhbGxpbmcgaW50VmFsdWVFeGFjdCIpOworICAgICAgICB9IGNhdGNoIChqYXZhLmxhbmcuQXJpdGhtZXRpY0V4Y2VwdGlvbiBhZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1Nob3J0VmFsdWVFeGFjdFBvcygpIHsKKyAgICAgICAgU3RyaW5nIGEgPSAiMTIzODA5NjQ4MzkyMzg0NzU0NTczNTY3MzU2NzQ1NzM1LjYzNTY3ODkwMjk1Nzg0OTAyNzY4Nzg3Njc4Mjg3RSsyMSI7CisgICAgICAgIEJpZ0RlY2ltYWwgYU51bWJlciA9IG5ldyBCaWdEZWNpbWFsKGEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYU51bWJlci5zaG9ydFZhbHVlRXhhY3QoKTsKKyAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5Bcml0aG1ldGljRXhjZXB0aW9uIGlzbid0IHRocm93biBhZnRlciBjYWxsaW5nIGludFZhbHVlRXhhY3QiKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5sYW5nLkFyaXRobWV0aWNFeGNlcHRpb24gYWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TaG9ydFZhbHVlRXhhY3RGbG9hdE5lZygpIHsKKyAgICAgICAgQmlnRGVjaW1hbCBhTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoIi0zMjc2Ni45OTk5OSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYU51bWJlci5zaG9ydFZhbHVlRXhhY3QoKTsKKyAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5Bcml0aG1ldGljRXhjZXB0aW9uIGlzbid0IHRocm93biBhZnRlciBjYWxsaW5nIGludFZhbHVlRXhhY3QiKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5sYW5nLkFyaXRobWV0aWNFeGNlcHRpb24gYWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TaG9ydFZhbHVlRXhhY3RGbG9hdFBvcygpIHsKKyAgICAgICAgZmxvYXQgYSA9IDMyNzY3Ljk5OTk5RjsKKyAgICAgICAgQmlnRGVjaW1hbCBhTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoYSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhTnVtYmVyLnNob3J0VmFsdWVFeGFjdCgpOworICAgICAgICAgICAgZmFpbCgiamF2YS5sYW5nLkFyaXRobWV0aWNFeGNlcHRpb24gaXNuJ3QgdGhyb3duIGFmdGVyIGNhbGxpbmcgaW50VmFsdWVFeGFjdCIpOworICAgICAgICB9IGNhdGNoIChqYXZhLmxhbmcuQXJpdGhtZXRpY0V4Y2VwdGlvbiBhZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1Nob3J0VmFsdWVFeGFjdExvbmdQb3MoKSB7CisgICAgICAgIGxvbmcgYSA9IDEyMzQ1TDsKKyAgICAgICAgQmlnRGVjaW1hbCBhTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwoYSk7CisgICAgICAgIHNob3J0IHNoTnVtYmVyID0gYU51bWJlci5zaG9ydFZhbHVlRXhhY3QoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaW5jb3JyZWN0IHZhbHVlIiwgc2hOdW1iZXIgPT0gYSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TaG9ydFZhbHVlRXhhY3RMb25nTmVnKCkgeworICAgICAgICBsb25nIGEgPSAtMTIzNDVMOworICAgICAgICBCaWdEZWNpbWFsIGFOdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChhKTsKKyAgICAgICAgaW50IGlOdW1iZXIgPSBhTnVtYmVyLnNob3J0VmFsdWVFeGFjdCgpOworICAgICAgICBhc3NlcnRUcnVlKCJpbmNvcnJlY3QgdmFsdWUiLCBpTnVtYmVyID09IGEpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3RyaXBUcmFpbGluZ1plcm9zWmVyb3MoKSB7CisKKyAgICAgICAgQmlnRGVjaW1hbCBiZE51bWJlciA9IG5ldyBCaWdEZWNpbWFsKCIwMDAwMDAwIik7CisgICAgICAgIEJpZ0RlY2ltYWwgcmVzdWx0ID0gYmROdW1iZXIuc3RyaXBUcmFpbGluZ1plcm9zKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgcmVzdWx0LnVuc2NhbGVkVmFsdWUoKSwgYmROdW1iZXIudW5zY2FsZWRWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaW5jb3JyZWN0IHZhbHVlIiwgcmVzdWx0LnNjYWxlKCkgPT0gMCk7CisKKyAgICAgICAgYmROdW1iZXIgPSBuZXcgQmlnRGVjaW1hbCgwKTsKKyAgICAgICAgcmVzdWx0ID0gYmROdW1iZXIuc3RyaXBUcmFpbGluZ1plcm9zKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgcmVzdWx0LnVuc2NhbGVkVmFsdWUoKSwgYmROdW1iZXIudW5zY2FsZWRWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaW5jb3JyZWN0IHZhbHVlIiwgcmVzdWx0LnNjYWxlKCkgPT0gMCk7CisKKyAgICAgICAgYmROdW1iZXIgPSBuZXcgQmlnRGVjaW1hbCgwLjAwMDAwMCk7CisgICAgICAgIHJlc3VsdCA9IGJkTnVtYmVyLnN0cmlwVHJhaWxpbmdaZXJvcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsIHJlc3VsdC51bnNjYWxlZFZhbHVlKCksIGJkTnVtYmVyLnVuc2NhbGVkVmFsdWUoKSk7CisgICAgICAgIGFzc2VydFRydWUoImluY29ycmVjdCB2YWx1ZSIsIHJlc3VsdC5zY2FsZSgpID09IDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3RyaXBUcmFpbGluZ1plcm9zKCkgeworICAgICAgICBTdHJpbmcgcyA9ICIwMDAwMDAwMDEwMDAwMDAwMDEwMDAwMDAwMC4wMDAwMDAwMDAxMDAwMDAwMDAiOworICAgICAgICBpbnQgaVNjYWxlID0gMTA7CisgICAgICAgIEJpZ0RlY2ltYWwgYmRWYWx1ZSA9IG5ldyBCaWdEZWNpbWFsKCIxMDAwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAxIik7CisgICAgICAgIEJpZ0RlY2ltYWwgYmROdW1iZXIgPSBuZXcgQmlnRGVjaW1hbChzKTsKKyAgICAgICAgQmlnRGVjaW1hbCBiZFJlc3VsdCA9IGJkTnVtYmVyLnN0cmlwVHJhaWxpbmdaZXJvcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsIGJkUmVzdWx0LnVuc2NhbGVkVmFsdWUoKSwgYmRWYWx1ZS51bnNjYWxlZFZhbHVlKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJpbmNvcnJlY3QgdmFsdWUiLCBiZFJlc3VsdC5zY2FsZSgpID09IGlTY2FsZSk7CisKKyAgICAgICAgcyA9ICIxMDAwLjAiOworICAgICAgICBpU2NhbGUgPSAtMzsKKyAgICAgICAgQmlnRGVjaW1hbCBiZCA9IG5ldyBCaWdEZWNpbWFsKCIxIik7CisgICAgICAgIGJkTnVtYmVyID0gbmV3IEJpZ0RlY2ltYWwocyk7CisgICAgICAgIGJkUmVzdWx0ID0gYmROdW1iZXIuc3RyaXBUcmFpbGluZ1plcm9zKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgYmRSZXN1bHQudW5zY2FsZWRWYWx1ZSgpLCBiZC51bnNjYWxlZFZhbHVlKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJpbmNvcnJlY3QgdmFsdWUiLCBiZFJlc3VsdC5zY2FsZSgpID09IGlTY2FsZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9tYXRoL09sZEJpZ0RlY2ltYWxTY2FsZU9wZXJhdGlvbnNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvT2xkQmlnRGVjaW1hbFNjYWxlT3BlcmF0aW9uc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMzk4OTljCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9tYXRoL09sZEJpZ0RlY2ltYWxTY2FsZU9wZXJhdGlvbnNUZXN0LmphdmEKQEAgLTAsMCArMSw5OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBFbGVuYSBTZW11a2hpbmEKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5tYXRoOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkQmlnRGVjaW1hbFNjYWxlT3BlcmF0aW9uc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TW92ZVBvaW50UmlnaHRFeCgpIHsKKyAgICAgICAgQmlnRGVjaW1hbCBhID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1LjY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkiKTsKKyAgICAgICAgQmlnRGVjaW1hbCByZXMgPSBhLm1vdmVQb2ludFJpZ2h0KDEwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3Qgc2NhbGUiLCAyNCwgcmVzLnNjYWxlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIxMjM0NTY3ODkwMTIzNDUuNjc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5IiwgcmVzLnRvU3RyaW5nKCkpOworICAgICAgICByZXMgPSBhLm1vdmVQb2ludFJpZ2h0KC01MCk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHNjYWxlIiwgODQsIHJlcy5zY2FsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAiMS4yMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OUUtNDYiLCByZXMudG9TdHJpbmcoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhLm1vdmVQb2ludFJpZ2h0KEludGVnZXIuTUlOX1ZBTFVFICsgMik7CisgICAgICAgICAgICBmYWlsKCJBcml0aG1ldGljRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLy8gVGhyb3dzIE91dE9mTWVtb3J5RXJyb3IgaW5zdGVhZCBvZiBBcml0aG1ldGljRXhjZXB0aW9uIQorICAgIHB1YmxpYyB2b2lkIHRlc3RNb3ZlUG9pbnRSaWdodEV4MigpIHsKKyAgICAgICAgQmlnRGVjaW1hbCBhID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OUUyNSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYS5tb3ZlUG9pbnRSaWdodChJbnRlZ2VyLk1BWF9WQUxVRSAtIDIpOworICAgICAgICAgICAgZmFpbCgiQXJpdGhtZXRpY0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTY2FsZUJ5UG93ZXJPZlRlbkV4KCkgeworICAgICAgICBCaWdEZWNpbWFsIGEgPSBuZXcgQmlnRGVjaW1hbCgiMTIzNDUuNjc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OSIpOworICAgICAgICBCaWdEZWNpbWFsIHJlcyA9IGEubW92ZVBvaW50UmlnaHQoMTApOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCBzY2FsZSIsIDI0LCByZXMuc2NhbGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjEyMzQ1Njc4OTAxMjM0NS42Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkiLCByZXMudG9TdHJpbmcoKSk7CisgICAgICAgIHJlcyA9IGEuc2NhbGVCeVBvd2VyT2ZUZW4oLTUwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3Qgc2NhbGUiLCA4NCwgcmVzLnNjYWxlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCB2YWx1ZSIsICIxLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5RS00NiIsIHJlcy50b1N0cmluZygpKTsKKyAgICAgICAgcmVzID0gYS5zY2FsZUJ5UG93ZXJPZlRlbig1MCk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHNjYWxlIiwgLTE2LCByZXMuc2NhbGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgIjEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODlFKzU0IiwgcmVzLnRvU3RyaW5nKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYS5zY2FsZUJ5UG93ZXJPZlRlbihJbnRlZ2VyLk1JTl9WQUxVRSArIDIpOworICAgICAgICAgICAgZmFpbCgiQXJpdGhtZXRpY0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhID0gbmV3IEJpZ0RlY2ltYWwoIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OUUyNSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYS5zY2FsZUJ5UG93ZXJPZlRlbihJbnRlZ2VyLk1BWF9WQUxVRSAtIDIpOworICAgICAgICAgICAgZmFpbCgiQXJpdGhtZXRpY0V4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGNoZWNrIHRoYXQgc2V0U2NhbGUgd2l0aCBhIHNjYWxlIGdyZWF0ZXIgdG8gdGhlIGV4aXN0aW5nIHNjYWxlIGRvZXMgbm90CisgICAgICogY2hhbmdlIHRoZSB2YWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0U2NhbGUoKSB7CisgICAgICAgIEJpZ0RlY2ltYWwgeDEgPSBuZXcgQmlnRGVjaW1hbCgxLjIzNDAwKTsKKyAgICAgICAgQmlnRGVjaW1hbCB4MiA9IHgxLnNldFNjYWxlKDc1KTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgeDEuY29tcGFyZVRvKHgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCB4Mi5jb21wYXJlVG8oeDEpKTsKKworICAgICAgICB4MS5wcmVjaXNpb24oKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgeDEuY29tcGFyZVRvKHgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCB4Mi5jb21wYXJlVG8oeDEpKTsKKworICAgICAgICB4Mi5wcmVjaXNpb24oKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgeDEuY29tcGFyZVRvKHgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCB4Mi5jb21wYXJlVG8oeDEpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvT2xkQmlnRGVjaW1hbFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbWF0aC9PbGRCaWdEZWNpbWFsVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA4NzI0YzUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvT2xkQmlnRGVjaW1hbFRlc3QuamF2YQpAQCAtMCwwICsxLDIwMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubWF0aDsKKworaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEubWF0aC5Sb3VuZGluZ01vZGU7CisKK3B1YmxpYyBjbGFzcyBPbGRCaWdEZWNpbWFsVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgQmlnSW50ZWdlciB2YWx1ZSA9IG5ldyBCaWdJbnRlZ2VyKCIxMjM0NTkwOCIpOworCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0RlY2ltYWwjQmlnRGVjaW1hbChkb3VibGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckQoKSB7CisgICAgICAgIC8vCisgICAgICAgIC8vIFRoZXNlIG51bWJlcnMgaGF2ZSBhbiBleGFjdCByZXByZXNlbnRhdGlvbiBhcyBkb3VibGVzOgorICAgICAgICAvLworICAgICAgICBCaWdEZWNpbWFsIGJpZyA9IG5ldyBCaWdEZWNpbWFsKDEyM0UwNCk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgInRoZSBCaWdEZWNpbWFsIHZhbHVlIHRha2luZyBhIGRvdWJsZSBhcmd1bWVudCBpcyBub3QgaW5pdGlhbGl6ZWQgcHJvcGVybHkiLAorICAgICAgICAgICAgICAgIGJpZy50b1N0cmluZygpLmVxdWFscygiMTIzMDAwMCIpKTsKKyAgICAgICAgYmlnID0gbmV3IEJpZ0RlY2ltYWwoMTIzLjM3NSk7CisgICAgICAgIGFzc2VydFRydWUoImluaXQoRCkgZmFpbGVkIGZvciAxMjMuMzc1OyBiZWNhbWUgIiArIGJpZywKKyAgICAgICAgICAgICAgICBiaWcudG9TdHJpbmcoKS5lcXVhbHMoIjEyMy4zNzUiKSApOworICAgICAgICBiaWcgPSBuZXcgQmlnRGVjaW1hbChNYXRoLnBvdygyLCAtMzMpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaW5pdChEKSBmYWlsZWQgZm9yIDJeKC0zMykgPSAxLjE2NDE1MzIxODI2OTM0ODE0NDUzMTI1RS0xMDsgYmVjYW1lICIgKyBiaWcsCisgICAgICAgICAgICAgICAgYmlnLnRvU3RyaW5nKCkuZXF1YWxzKCIxLjE2NDE1MzIxODI2OTM0ODE0NDUzMTI1RS0xMCIpICk7CisgICAgICAgIGJpZyA9IG5ldyBCaWdEZWNpbWFsKDEyMzQ1NiAqIE1hdGgucG93KDIsIC0zMykpOworICAgICAgICBhc3NlcnRUcnVlKCJpbml0KEQpIGZhaWxlZCBmb3IgMTIzNDU2ICogMl4oLTMzKSA9IDAuMDAwMDE0MzcyMTY5OTcxNDY2MDY0NDUzMTI1OyBiZWNhbWUgIiArIGJpZywKKyAgICAgICAgICAgICAgICBiaWcudG9TdHJpbmcoKS5lcXVhbHMoIjAuMDAwMDE0MzcyMTY5OTcxNDY2MDY0NDUzMTI1IikgKTsKKyAgICAgICAgYmlnID0gbmV3IEJpZ0RlY2ltYWwoLTEyMzQ1NiAqIE1hdGgucG93KDIsIC0zMykpOworICAgICAgICBhc3NlcnRUcnVlKCJpbml0KEQpIGZhaWxlZCBmb3IgMTIzNDU2ICogMl4oLTMzKSA9IC0wLjAwMDAxNDM3MjE2OTk3MTQ2NjA2NDQ1MzEyNTsgYmVjYW1lICIgKyBiaWcsCisgICAgICAgICAgICAgICAgYmlnLnRvU3RyaW5nKCkuZXF1YWxzKCItMC4wMDAwMTQzNzIxNjk5NzE0NjYwNjQ0NTMxMjUiKSApOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdEZWNpbWFsI0JpZ0RlY2ltYWwoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbnN0cnVjdG9yX1N0cmluZ19wbHVzX2V4cCgpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogQmlnRGVjaW1hbCBkb2VzIG5vdCBzdXBwb3J0IGEgKyBzaWduIGluIHRoZSBleHBvbmVudCB3aGVuIGNvbnZlcnRpbmcKKyAgICAgICAgICogZnJvbSBhIFN0cmluZy4KKyAgICAgICAgICoKKyAgICAgICAgICogbWMgMDgxMTA2OiB3aG8gc2F5cyBzbz8hPworICAgICAgICAgKi8KKyAgICAgICAgQmlnRGVjaW1hbCBiZDsKKyAgICAgICAgYmQgPSBuZXcgQmlnRGVjaW1hbCgiKzIzZS0wIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHZhbHVlIiwgICIyMyIsIGJkLnRvU3RyaW5nKCkpOworICAgICAgICBiZCA9IG5ldyBCaWdEZWNpbWFsKCItMjNlKzAiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgdmFsdWUiLCAgIi0yMyIsIGJkLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdEZWNpbWFsI3NldFNjYWxlKGludCwgamF2YS5tYXRoLlJvdW5kaW5nTW9kZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFNjYWxlSUxqYXZhX21hdGhfUm91bmRpbmdNb2RlKCkgeworICAgICAgICBCaWdEZWNpbWFsIHNldFNjYWxlMSA9IG5ldyBCaWdEZWNpbWFsKDIuMzIzRTEwMik7CisgICAgICAgIEJpZ0RlY2ltYWwgc2V0U2NhbGUyID0gc2V0U2NhbGUxLnNldFNjYWxlKDQpOworICAgICAgICBhc3NlcnRUcnVlKCJ0aGUgbnVtYmVyIDIuMzIzRTEwMiBhZnRlciBzZXR0aW5nIHNjYWxlIGlzIHdyb25nIiwKKyAgICAgICAgICAgICAgICBzZXRTY2FsZTIuc2NhbGUoKSA9PSA0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBudW1iZXIgMi4zMjNFMTAyIGlzIHdyb25nIiwKKyAgICAgICAgICAgICAgICBzZXRTY2FsZTIuZG91YmxlVmFsdWUoKSA9PSAyLjMyM0UxMDIpOworCisgICAgICAgIHNldFNjYWxlMSA9IG5ldyBCaWdEZWNpbWFsKCItMS4yNTNFLTEyIik7CisgICAgICAgIHNldFNjYWxlMiA9IHNldFNjYWxlMS5zZXRTY2FsZSgxNywgUm91bmRpbmdNb2RlLkNFSUxJTkcpOworICAgICAgICBhc3NlcnRUcnVlKCJ0aGUgc2NhbGUgb2YgdGhlIG51bWJlciAtMS4yNTNFLTEyIGFmdGVyIHNldHRpbmcgc2NhbGUgaXMgd3JvbmciLAorICAgICAgICAgICAgICAgIHNldFNjYWxlMi5zY2FsZSgpID09IDE3KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAidGhlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBudW1iZXIgLTEuMjUzRS0xMiBhZnRlciBzZXR0aW5nIHNjYWxlIGlzIHdyb25nLCAiICsgc2V0U2NhbGUyLnRvU3RyaW5nKCksCisgICAgICAgICAgICAgICAgc2V0U2NhbGUyLnRvU3RyaW5nKCkuZXF1YWxzKCItMS4yNTMwMEUtMTIiKSk7CisKKyAgICAgICAgLy8gdGVzdGluZyByb3VuZGluZyBNb2RlIFJvdW5kaW5nTW9kZS5DRUlMSU5HCisgICAgICAgIHNldFNjYWxlMSA9IG5ldyBCaWdEZWNpbWFsKHZhbHVlLCA0KTsKKyAgICAgICAgc2V0U2NhbGUyID0gc2V0U2NhbGUxLnNldFNjYWxlKDEsIFJvdW5kaW5nTW9kZS5DRUlMSU5HKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAidGhlIG51bWJlciAxMjM0LjU5MDggYWZ0ZXIgc2V0dGluZyBzY2FsZSB0byAxL1JvdW5kaW5nTW9kZS5DRUlMSU5HIGlzIHdyb25nIiwKKyAgICAgICAgICAgICAgICBzZXRTY2FsZTIudG9TdHJpbmcoKS5lcXVhbHMoIjEyMzQuNiIpICYmIHNldFNjYWxlMi5zY2FsZSgpID09IDEpOworICAgICAgICBCaWdEZWNpbWFsIHNldE5lZyA9IG5ldyBCaWdEZWNpbWFsKHZhbHVlLm5lZ2F0ZSgpLCA0KTsKKyAgICAgICAgc2V0U2NhbGUyID0gc2V0TmVnLnNldFNjYWxlKDEsIFJvdW5kaW5nTW9kZS5DRUlMSU5HKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAidGhlIG51bWJlciAtMTIzNC41OTA4IGFmdGVyIHNldHRpbmcgc2NhbGUgdG8gMS9Sb3VuZGluZ01vZGUuQ0VJTElORyBpcyB3cm9uZyIsCisgICAgICAgICAgICAgICAgc2V0U2NhbGUyLnRvU3RyaW5nKCkuZXF1YWxzKCItMTIzNC41IikKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIHNldFNjYWxlMi5zY2FsZSgpID09IDEpOworCisgICAgICAgIC8vIHRlc3Rpbmcgcm91bmRpbmcgTW9kZSBSb3VuZGluZ01vZGUuRE9XTgorICAgICAgICBzZXRTY2FsZTIgPSBzZXROZWcuc2V0U2NhbGUoMSwgUm91bmRpbmdNb2RlLkRPV04pOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJ0aGUgbnVtYmVyIC0xMjM0LjU5MDggYWZ0ZXIgc2V0dGluZyBzY2FsZSB0byAxL1JvdW5kaW5nTW9kZS5ET1dOIGlzIHdyb25nIiwKKyAgICAgICAgICAgICAgICBzZXRTY2FsZTIudG9TdHJpbmcoKS5lcXVhbHMoIi0xMjM0LjUiKQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgc2V0U2NhbGUyLnNjYWxlKCkgPT0gMSk7CisgICAgICAgIHNldFNjYWxlMSA9IG5ldyBCaWdEZWNpbWFsKHZhbHVlLCA0KTsKKyAgICAgICAgc2V0U2NhbGUyID0gc2V0U2NhbGUxLnNldFNjYWxlKDEsIFJvdW5kaW5nTW9kZS5ET1dOKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAidGhlIG51bWJlciAxMjM0LjU5MDggYWZ0ZXIgc2V0dGluZyBzY2FsZSB0byAxL1JvdW5kaW5nTW9kZS5ET1dOIGlzIHdyb25nIiwKKyAgICAgICAgICAgICAgICBzZXRTY2FsZTIudG9TdHJpbmcoKS5lcXVhbHMoIjEyMzQuNSIpICYmIHNldFNjYWxlMi5zY2FsZSgpID09IDEpOworCisgICAgICAgIC8vIHRlc3Rpbmcgcm91bmRpbmcgTW9kZSBSb3VuZGluZ01vZGUuRkxPT1IKKyAgICAgICAgc2V0U2NhbGUyID0gc2V0U2NhbGUxLnNldFNjYWxlKDEsIFJvdW5kaW5nTW9kZS5GTE9PUik7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgInRoZSBudW1iZXIgMTIzNC41OTA4IGFmdGVyIHNldHRpbmcgc2NhbGUgdG8gMS9Sb3VuZGluZ01vZGUuRkxPT1IgaXMgd3JvbmciLAorICAgICAgICAgICAgICAgIHNldFNjYWxlMi50b1N0cmluZygpLmVxdWFscygiMTIzNC41IikgJiYgc2V0U2NhbGUyLnNjYWxlKCkgPT0gMSk7CisgICAgICAgIHNldFNjYWxlMiA9IHNldE5lZy5zZXRTY2FsZSgxLCBSb3VuZGluZ01vZGUuRkxPT1IpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJ0aGUgbnVtYmVyIC0xMjM0LjU5MDggYWZ0ZXIgc2V0dGluZyBzY2FsZSB0byAxL1JvdW5kaW5nTW9kZS5GTE9PUiBpcyB3cm9uZyIsCisgICAgICAgICAgICAgICAgc2V0U2NhbGUyLnRvU3RyaW5nKCkuZXF1YWxzKCItMTIzNC42IikKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIHNldFNjYWxlMi5zY2FsZSgpID09IDEpOworCisgICAgICAgIC8vIHRlc3Rpbmcgcm91bmRpbmcgTW9kZSBSb3VuZGluZ01vZGUuSEFMRl9ET1dOCisgICAgICAgIHNldFNjYWxlMiA9IHNldFNjYWxlMS5zZXRTY2FsZSgzLCBSb3VuZGluZ01vZGUuSEFMRl9ET1dOKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAidGhlIG51bWJlciAxMjM0LjU5MDggYWZ0ZXIgc2V0dGluZyBzY2FsZSB0byAzL1JvdW5kaW5nTW9kZS5IQUxGX0RPV04gaXMgd3JvbmciLAorICAgICAgICAgICAgICAgIHNldFNjYWxlMi50b1N0cmluZygpLmVxdWFscygiMTIzNC41OTEiKQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgc2V0U2NhbGUyLnNjYWxlKCkgPT0gMyk7CisgICAgICAgIHNldFNjYWxlMSA9IG5ldyBCaWdEZWNpbWFsKG5ldyBCaWdJbnRlZ2VyKCIxMjM0NTAwMCIpLCA1KTsKKyAgICAgICAgc2V0U2NhbGUyID0gc2V0U2NhbGUxLnNldFNjYWxlKDEsIFJvdW5kaW5nTW9kZS5IQUxGX0RPV04pOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJ0aGUgbnVtYmVyIDEyMy40NTkwOCBhZnRlciBzZXR0aW5nIHNjYWxlIHRvIDEvUm91bmRpbmdNb2RlLkhBTEZfRE9XTiBpcyB3cm9uZyIsCisgICAgICAgICAgICAgICAgc2V0U2NhbGUyLnRvU3RyaW5nKCkuZXF1YWxzKCIxMjMuNCIpICYmIHNldFNjYWxlMi5zY2FsZSgpID09IDEpOworICAgICAgICBzZXRTY2FsZTIgPSBuZXcgQmlnRGVjaW1hbCgiLTEyMzQuNTAwMCIpLnNldFNjYWxlKDAsCisgICAgICAgICAgICAgICAgUm91bmRpbmdNb2RlLkhBTEZfRE9XTik7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgInRoZSBudW1iZXIgLTEyMzQuNTkwOCBhZnRlciBzZXR0aW5nIHNjYWxlIHRvIDAvUm91bmRpbmdNb2RlLkhBTEZfRE9XTiBpcyB3cm9uZyIsCisgICAgICAgICAgICAgICAgc2V0U2NhbGUyLnRvU3RyaW5nKCkuZXF1YWxzKCItMTIzNCIpICYmIHNldFNjYWxlMi5zY2FsZSgpID09IDApOworCisgICAgICAgIC8vIHRlc3Rpbmcgcm91bmRpbmcgTW9kZSBSb3VuZGluZ01vZGUuSEFMRl9FVkVOCisgICAgICAgIHNldFNjYWxlMSA9IG5ldyBCaWdEZWNpbWFsKDEuMjM0NTc4OUQpOworICAgICAgICBzZXRTY2FsZTIgPSBzZXRTY2FsZTEuc2V0U2NhbGUoNCwgUm91bmRpbmdNb2RlLkhBTEZfRVZFTik7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgInRoZSBudW1iZXIgMS4yMzQ1Nzg5IGFmdGVyIHNldHRpbmcgc2NhbGUgdG8gNC9Sb3VuZGluZ01vZGUuSEFMRl9FVkVOIGlzIHdyb25nIiwKKyAgICAgICAgICAgICAgICBzZXRTY2FsZTIuZG91YmxlVmFsdWUoKSA9PSAxLjIzNDZEICYmIHNldFNjYWxlMi5zY2FsZSgpID09IDQpOworICAgICAgICBzZXROZWcgPSBuZXcgQmlnRGVjaW1hbCgtMS4yMzM1Nzg5RCk7CisgICAgICAgIHNldFNjYWxlMiA9IHNldE5lZy5zZXRTY2FsZSgyLCBSb3VuZGluZ01vZGUuSEFMRl9FVkVOKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAidGhlIG51bWJlciAtMS4yMzM1Nzg5IGFmdGVyIHNldHRpbmcgc2NhbGUgdG8gMi9Sb3VuZGluZ01vZGUuSEFMRl9FVkVOIGlzIHdyb25nIiwKKyAgICAgICAgICAgICAgICBzZXRTY2FsZTIuZG91YmxlVmFsdWUoKSA9PSAtMS4yM0QgJiYgc2V0U2NhbGUyLnNjYWxlKCkgPT0gMik7CisgICAgICAgIHNldFNjYWxlMiA9IG5ldyBCaWdEZWNpbWFsKCIxLjIzNDUwMDAiKS5zZXRTY2FsZSgzLAorICAgICAgICAgICAgICAgIFJvdW5kaW5nTW9kZS5IQUxGX0VWRU4pOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJ0aGUgbnVtYmVyIDEuMjM0NTc4OSBhZnRlciBzZXR0aW5nIHNjYWxlIHRvIDMvUm91bmRpbmdNb2RlLkhBTEZfRVZFTiBpcyB3cm9uZyIsCisgICAgICAgICAgICAgICAgc2V0U2NhbGUyLmRvdWJsZVZhbHVlKCkgPT0gMS4yMzREICYmIHNldFNjYWxlMi5zY2FsZSgpID09IDMpOworICAgICAgICBzZXRTY2FsZTIgPSBuZXcgQmlnRGVjaW1hbCgiLTEuMjM0NTAwMCIpLnNldFNjYWxlKDMsCisgICAgICAgICAgICAgICAgUm91bmRpbmdNb2RlLkhBTEZfRVZFTik7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgInRoZSBudW1iZXIgLTEuMjMzNTc4OSBhZnRlciBzZXR0aW5nIHNjYWxlIHRvIDMvUm91bmRpbmdNb2RlLkhBTEZfRVZFTiBpcyB3cm9uZyIsCisgICAgICAgICAgICAgICAgc2V0U2NhbGUyLmRvdWJsZVZhbHVlKCkgPT0gLTEuMjM0RCAmJiBzZXRTY2FsZTIuc2NhbGUoKSA9PSAzKTsKKworICAgICAgICAvLyB0ZXN0aW5nIHJvdW5kaW5nIE1vZGUgUm91bmRpbmdNb2RlLkhBTEZfVVAKKyAgICAgICAgc2V0U2NhbGUxID0gbmV3IEJpZ0RlY2ltYWwoIjEzNDU2Ny4zNDY1MCIpOworICAgICAgICBzZXRTY2FsZTIgPSBzZXRTY2FsZTEuc2V0U2NhbGUoMywgUm91bmRpbmdNb2RlLkhBTEZfVVApOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJ0aGUgbnVtYmVyIDEzNDU2Ny4zNDY1OCBhZnRlciBzZXR0aW5nIHNjYWxlIHRvIDMvUm91bmRpbmdNb2RlLkhBTEZfVVAgaXMgd3JvbmciLAorICAgICAgICAgICAgICAgIHNldFNjYWxlMi50b1N0cmluZygpLmVxdWFscygiMTM0NTY3LjM0NyIpCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBzZXRTY2FsZTIuc2NhbGUoKSA9PSAzKTsKKyAgICAgICAgc2V0TmVnID0gbmV3IEJpZ0RlY2ltYWwoIi0xMjM0LjQ1NjciKTsKKyAgICAgICAgc2V0U2NhbGUyID0gc2V0TmVnLnNldFNjYWxlKDAsIFJvdW5kaW5nTW9kZS5IQUxGX1VQKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAidGhlIG51bWJlciAtMTIzNC40NTY3IGFmdGVyIHNldHRpbmcgc2NhbGUgdG8gMC9Sb3VuZGluZ01vZGUuSEFMRl9VUCBpcyB3cm9uZyIsCisgICAgICAgICAgICAgICAgc2V0U2NhbGUyLnRvU3RyaW5nKCkuZXF1YWxzKCItMTIzNCIpICYmIHNldFNjYWxlMi5zY2FsZSgpID09IDApOworCisgICAgICAgIC8vIHRlc3Rpbmcgcm91bmRpbmcgTW9kZSBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldFNjYWxlMS5zZXRTY2FsZSgzLCBSb3VuZGluZ01vZGUuVU5ORUNFU1NBUlkpOworICAgICAgICAgICAgZmFpbCgiYXJpdGhtZXRpYyBFeGNlcHRpb24gbm90IGNhdWdodCBmb3Igcm91bmQgdW5uZWNlc3NhcnkiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICAvLyB0ZXN0aW5nIHJvdW5kaW5nIE1vZGUgUm91bmRpbmdNb2RlLlVQCisgICAgICAgIHNldFNjYWxlMSA9IG5ldyBCaWdEZWNpbWFsKCIxMDAwMDAuMzc0Iik7CisgICAgICAgIHNldFNjYWxlMiA9IHNldFNjYWxlMS5zZXRTY2FsZSgyLCBSb3VuZGluZ01vZGUuVVApOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJ0aGUgbnVtYmVyIDEwMDAwMC4zNzQgYWZ0ZXIgc2V0dGluZyBzY2FsZSB0byAyL1JvdW5kaW5nTW9kZS5VUCBpcyB3cm9uZyIsCisgICAgICAgICAgICAgICAgc2V0U2NhbGUyLnRvU3RyaW5nKCkuZXF1YWxzKCIxMDAwMDAuMzgiKQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgc2V0U2NhbGUyLnNjYWxlKCkgPT0gMik7CisgICAgICAgIHNldE5lZyA9IG5ldyBCaWdEZWNpbWFsKC0xMzQuMzQ1ODlEKTsKKyAgICAgICAgc2V0U2NhbGUyID0gc2V0TmVnLnNldFNjYWxlKDIsIFJvdW5kaW5nTW9kZS5VUCk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgInRoZSBudW1iZXIgLTEzNC4zNDU4OSBhZnRlciBzZXR0aW5nIHNjYWxlIHRvIDIvUm91bmRpbmdNb2RlLlVQIGlzIHdyb25nIiwKKyAgICAgICAgICAgICAgICBzZXRTY2FsZTIuZG91YmxlVmFsdWUoKSA9PSAtMTM0LjM1RCAmJiBzZXRTY2FsZTIuc2NhbGUoKSA9PSAyKTsKKworICAgICAgICAvLyB0ZXN0aW5nIGludmFsaWQgcm91bmRpbmcgbW9kZXMKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldFNjYWxlMiA9IHNldFNjYWxlMS5zZXRTY2FsZSgwLCAtMTIzKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyBub3QgY2F1Z2h0IGZvciB3cm9uZyByb3VuZGluZyBtb2RlIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvT2xkQmlnSW50ZWdlckNvbnN0cnVjdG9yc1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbWF0aC9PbGRCaWdJbnRlZ2VyQ29uc3RydWN0b3JzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ0Y2FlYzIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvT2xkQmlnSW50ZWdlckNvbnN0cnVjdG9yc1Rlc3QuamF2YQpAQCAtMCwwICsxLDEwNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQGF1dGhvciBFbGVuYSBTZW11a2hpbmEKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5tYXRoOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkQmlnSW50ZWdlckNvbnN0cnVjdG9yc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm1hdGguQmlnSW50ZWdlciNCaWdJbnRlZ2VyKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJTdHJpbmcxKCkgeworICAgICAgICBTdHJpbmcgcyA9ICIwIjsKKyAgICAgICAgQmlnSW50ZWdlciBiaV9zID0gbmV3IEJpZ0ludGVnZXIocyk7CisgICAgICAgIGFzc2VydFRydWUoInRoZSBCaWdJbnRlZ2VyIHZhbHVlIGlzIG5vdCBpbml0aWFsaXplZCBwcm9wZXJseSIsIGJpX3MuaW50VmFsdWUoKSA9PSAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0aGUgQmlnSW50ZWdlciB2YWx1ZSBpcyBub3QgaW5pdGlhbGl6ZWQgcHJvcGVybHkiLCBiaV9zLnRvU3RyaW5nKCksIHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI0JpZ0ludGVnZXIoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0clN0cmluZzIoKSB7CisgICAgICAgIFN0cmluZyBzID0gIi0yMTQ3NDgzNjQ4IjsKKyAgICAgICAgQmlnSW50ZWdlciBiaV9zID0gbmV3IEJpZ0ludGVnZXIocyk7CisgICAgICAgIGFzc2VydFRydWUoInRoZSBCaWdJbnRlZ2VyIHZhbHVlIGlzIG5vdCBpbml0aWFsaXplZCBwcm9wZXJseSIsCisgICAgICAgICAgICAgICAgYmlfcy5pbnRWYWx1ZSgpID09IEludGVnZXIuTUlOX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0aGUgQmlnSW50ZWdlciB2YWx1ZSBpcyBub3QgaW5pdGlhbGl6ZWQgcHJvcGVybHkiLCBiaV9zLnRvU3RyaW5nKCksIHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI0JpZ0ludGVnZXIoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0clN0cmluZzMoKSB7CisgICAgICAgIFN0cmluZyBzID0gIjIxNDc0ODM2NDciOworICAgICAgICBCaWdJbnRlZ2VyIGJpX3MgPSBuZXcgQmlnSW50ZWdlcihzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhlIEJpZ0ludGVnZXIgdmFsdWUgaXMgbm90IGluaXRpYWxpemVkIHByb3Blcmx5IiwKKyAgICAgICAgICAgICAgICBiaV9zLmludFZhbHVlKCkgPT0gSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRoZSBCaWdJbnRlZ2VyIHZhbHVlIGlzIG5vdCBpbml0aWFsaXplZCBwcm9wZXJseSIsIGJpX3MudG9TdHJpbmcoKSwgcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0ludGVnZXIjQmlnSW50ZWdlcihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RyU3RyaW5nRXhjMSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIwMTIzNCA1NiIpOworICAgICAgICAgICAgZmFpbCgiTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGhhcyBub3QgYmVlbiBjYXVnaHQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI0JpZ0ludGVnZXIoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0clN0cmluZ0V4YzIoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMTIzNCM1NiIpOworICAgICAgICAgICAgZmFpbCgiTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGhhcyBub3QgYmVlbiBjYXVnaHQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI0JpZ0ludGVnZXIoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0clN0cmluZ0V4YzMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMTIzNC41NiIpOworICAgICAgICAgICAgZmFpbCgiTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGhhcyBub3QgYmVlbiBjYXVnaHQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI0JpZ0ludGVnZXIoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0clN0cmluZ0V4YzQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMUUrMSIpOworICAgICAgICAgICAgZmFpbCgiTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGhhcyBub3QgYmVlbiBjYXVnaHQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbWF0aC9PbGRCaWdJbnRlZ2VyRGl2aWRlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9tYXRoL09sZEJpZ0ludGVnZXJEaXZpZGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTc1M2EwYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbWF0aC9PbGRCaWdJbnRlZ2VyRGl2aWRlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgRWxlbmEgU2VtdWtoaW5hCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubWF0aDsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZEJpZ0ludGVnZXJEaXZpZGVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogZGl2aWRlQW5kUmVtYWluZGVyIG9mIGRpdmlzaW9uIGJ5IHplcm8KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2FzZTIxYnlaZXJvKCkgeworICAgICAgICBieXRlIGFCeXRlc1tdID0gezEsIDIsIDMsIDQsIDUsIDYsIDd9OworICAgICAgICBieXRlIGJCeXRlc1tdID0gezB9OworICAgICAgICBpbnQgYVNpZ24gPSAxOworICAgICAgICBpbnQgYlNpZ24gPSAwOworICAgICAgICBCaWdJbnRlZ2VyIGFOdW1iZXIgPSBuZXcgQmlnSW50ZWdlcihhU2lnbiwgYUJ5dGVzKTsKKyAgICAgICAgQmlnSW50ZWdlciBiTnVtYmVyID0gbmV3IEJpZ0ludGVnZXIoYlNpZ24sIGJCeXRlcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhTnVtYmVyLmRpdmlkZUFuZFJlbWFpbmRlcihiTnVtYmVyKTsKKyAgICAgICAgICAgIGZhaWwoIkFyaXRobWV0aWNFeGNlcHRpb24gaGFzIG5vdCBiZWVuIGNhdWdodCIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbWF0aC9PbGRCaWdJbnRlZ2VyT3BlcmF0ZUJpdHNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvT2xkQmlnSW50ZWdlck9wZXJhdGVCaXRzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYyMTVjMTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvT2xkQmlnSW50ZWdlck9wZXJhdGVCaXRzVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEBhdXRob3IgRWxlbmEgU2VtdWtoaW5hCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubWF0aDsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZEJpZ0ludGVnZXJPcGVyYXRlQml0c1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI2dldExvd2VzdFNldEJpdCgpIGdldExvd2VzdFNldEJpdCBmb3IKKyAgICAgKiAgICAgICAgbmVnYXRpdmUgQmlnSW50ZWdlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TG93ZXN0U2V0Qml0TmVnKCkgeworICAgICAgICBieXRlIGFCeXRlc1tdID0geworICAgICAgICAgICAgICAgIC0xLCAtMTI4LCA1NiwgMTAwLCAtMiwgLTc2LCA4OSwgNDUsIDkxLCAzLCAtMTUsIDM1LCAyNgorICAgICAgICB9OworICAgICAgICBpbnQgYVNpZ24gPSAtMTsKKyAgICAgICAgaW50IGlOdW1iZXIgPSAxOworICAgICAgICBCaWdJbnRlZ2VyIGFOdW1iZXIgPSBuZXcgQmlnSW50ZWdlcihhU2lnbiwgYUJ5dGVzKTsKKyAgICAgICAgaW50IHJlc3VsdCA9IGFOdW1iZXIuZ2V0TG93ZXN0U2V0Qml0KCk7CisgICAgICAgIGFzc2VydFRydWUoImluY29ycmVjdCB2YWx1ZSIsIHJlc3VsdCA9PSBpTnVtYmVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm1hdGguQmlnSW50ZWdlciNnZXRMb3dlc3RTZXRCaXQoKSBnZXRMb3dlc3RTZXRCaXQgZm9yCisgICAgICogICAgICAgIHBvc2l0aXZlIEJpZ0ludGVnZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldExvd2VzdFNldEJpdFBvcygpIHsKKyAgICAgICAgYnl0ZSBhQnl0ZXNbXSA9IHsKKyAgICAgICAgICAgICAgICAtMSwgLTEyOCwgNTYsIDEwMCwgLTIsIC03NiwgODksIDQ1LCA5MSwgMywgLTE1LCAzNSwgMjYKKyAgICAgICAgfTsKKyAgICAgICAgaW50IGFTaWduID0gMTsKKyAgICAgICAgaW50IGlOdW1iZXIgPSAxOworICAgICAgICBCaWdJbnRlZ2VyIGFOdW1iZXIgPSBuZXcgQmlnSW50ZWdlcihhU2lnbiwgYUJ5dGVzKTsKKyAgICAgICAgaW50IHJlc3VsdCA9IGFOdW1iZXIuZ2V0TG93ZXN0U2V0Qml0KCk7CisgICAgICAgIGFzc2VydFRydWUoImluY29ycmVjdCB2YWx1ZSIsIHJlc3VsdCA9PSBpTnVtYmVyKTsKKworICAgICAgICBieXRlW10gYUJ5dGVzXyA9IHsKKyAgICAgICAgICAgICAgICAxMjcsIDAsIDMKKyAgICAgICAgfTsKKyAgICAgICAgaU51bWJlciA9IDA7CisgICAgICAgIGFOdW1iZXIgPSBuZXcgQmlnSW50ZWdlcihhU2lnbiwgYUJ5dGVzXyk7CisgICAgICAgIHJlc3VsdCA9IGFOdW1iZXIuZ2V0TG93ZXN0U2V0Qml0KCk7CisgICAgICAgIGFzc2VydFRydWUoImluY29ycmVjdCB2YWx1ZSIsIHJlc3VsdCA9PSBpTnVtYmVyKTsKKworICAgICAgICBieXRlW10gYUJ5dGVzX18gPSB7CisgICAgICAgICAgICAgICAgLTEyOCwgMCwgMAorICAgICAgICB9OworICAgICAgICBpTnVtYmVyID0gMjM7CisgICAgICAgIGFOdW1iZXIgPSBuZXcgQmlnSW50ZWdlcihhU2lnbiwgYUJ5dGVzX18pOworICAgICAgICByZXN1bHQgPSBhTnVtYmVyLmdldExvd2VzdFNldEJpdCgpOworICAgICAgICBhc3NlcnRUcnVlKCJpbmNvcnJlY3QgdmFsdWUiLCByZXN1bHQgPT0gaU51bWJlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0ludGVnZXIjZ2V0TG93ZXN0U2V0Qml0KCkgZ2V0TG93ZXN0U2V0Qml0IGZvciB6ZXJvCisgICAgICogICAgICAgIEJpZ0ludGVnZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldExvd2VzdFNldEJpdFplcm8oKSB7CisgICAgICAgIGJ5dGVbXSBhQnl0ZXMgPSB7CisgICAgICAgICAgICAwCisgICAgICAgIH07CisgICAgICAgIGludCBhU2lnbiA9IDA7CisgICAgICAgIGludCBpTnVtYmVyID0gLTE7CisgICAgICAgIEJpZ0ludGVnZXIgYU51bWJlciA9IG5ldyBCaWdJbnRlZ2VyKGFTaWduLCBhQnl0ZXMpOworICAgICAgICBpbnQgcmVzdWx0ID0gYU51bWJlci5nZXRMb3dlc3RTZXRCaXQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaW5jb3JyZWN0IHZhbHVlIiwgcmVzdWx0ID09IGlOdW1iZXIpOworCisgICAgICAgIGJ5dGVbXSBhQnl0ZXNfID0geworICAgICAgICAgICAgICAgIDAsIDAsIDAKKyAgICAgICAgfTsKKyAgICAgICAgaU51bWJlciA9IC0xOworICAgICAgICBhTnVtYmVyID0gbmV3IEJpZ0ludGVnZXIoYVNpZ24sIGFCeXRlc18pOworICAgICAgICByZXN1bHQgPSBhTnVtYmVyLmdldExvd2VzdFNldEJpdCgpOworICAgICAgICBhc3NlcnRUcnVlKCJpbmNvcnJlY3QgdmFsdWUiLCByZXN1bHQgPT0gaU51bWJlcik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL21hdGgvT2xkQmlnSW50ZWdlclRvU3RyaW5nVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9tYXRoL09sZEJpZ0ludGVnZXJUb1N0cmluZ1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYzc2MWJjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9tYXRoL09sZEJpZ0ludGVnZXJUb1N0cmluZ1Rlc3QuamF2YQpAQCAtMCwwICsxLDgzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBAYXV0aG9yIEVsZW5hIFNlbXVraGluYQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm1hdGg7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRCaWdJbnRlZ2VyVG9TdHJpbmdUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF90b1N0cmluZzEoKSB7CisKKyAgICAgICAgU3RyaW5nIHMgPSAiMDAwMDAwMDAwMCI7CisgICAgICAgIEJpZ0ludGVnZXIgYmkgPSBuZXcgQmlnSW50ZWdlcihzKTsKKyAgICAgICAgU3RyaW5nIHNCSSA9IGJpLnRvU3RyaW5nKCk7CisgICAgICAgIGFzc2VydEVxdWFscygidG9TdHJpbmcgbWV0aG9kIHJldHVybnMgaW5jb3JyZWN0IHZhbHVlIGluc3RlYWQgb2YgIiArIHMsIHNCSSwgIjAiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nMigpIHsKKyAgICAgICAgU3RyaW5nIHMgPSAiMTIzNDU2Nzg5MDk4NzY1NDMyMSI7CisgICAgICAgIEJpZ0ludGVnZXIgYmkgPSBuZXcgQmlnSW50ZWdlcihzKTsKKyAgICAgICAgU3RyaW5nIHNCSSA9IGJpLnRvU3RyaW5nKCk7CisgICAgICAgIGFzc2VydEVxdWFscygidG9TdHJpbmcgbWV0aG9kIHJldHVybnMgaW5jb3JyZWN0IHZhbHVlIGluc3RlYWQgb2YgIiArIHMsIHNCSSwgcyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90b1N0cmluZzMoKSB7CisgICAgICAgIFN0cmluZyBzID0gIi0xMjM0NTY3ODkwOTg3NjU0MzIxIjsKKyAgICAgICAgQmlnSW50ZWdlciBiaSA9IG5ldyBCaWdJbnRlZ2VyKHMpOworICAgICAgICBTdHJpbmcgc0JJID0gYmkudG9TdHJpbmcoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0b1N0cmluZyBtZXRob2QgcmV0dXJucyBpbmNvcnJlY3QgdmFsdWUgaW5zdGVhZCBvZiAiICsgcywgc0JJLCBzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nNCgpIHsKKyAgICAgICAgU3RyaW5nIHMgPSAiMTIzNDU2Nzg5MDEyMzQiOworICAgICAgICBsb25nIGwgPSAxMjM0NTY3ODkwMTIzNEw7CisgICAgICAgIEJpZ0ludGVnZXIgYmkgPSBCaWdJbnRlZ2VyLnZhbHVlT2YobCk7CisgICAgICAgIFN0cmluZyBzQkkgPSBiaS50b1N0cmluZygpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRvU3RyaW5nIG1ldGhvZCByZXR1cm5zIGluY29ycmVjdCB2YWx1ZSBpbnN0ZWFkIG9mICIgKyBzLCBzQkksIHMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9TdHJpbmc1KCkgeworICAgICAgICBTdHJpbmcgcyA9ICItMTIzNDU2Nzg5MDEyMzQiOworICAgICAgICBsb25nIGwgPSAtMTIzNDU2Nzg5MDEyMzRMOworICAgICAgICBCaWdJbnRlZ2VyIGJpID0gQmlnSW50ZWdlci52YWx1ZU9mKGwpOworICAgICAgICBTdHJpbmcgc0JJID0gYmkudG9TdHJpbmcoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0b1N0cmluZyBtZXRob2QgcmV0dXJucyBpbmNvcnJlY3QgdmFsdWUgaW5zdGVhZCBvZiAiICsgcywgc0JJLCBzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nKCkgeworICAgICAgICBieXRlIGFCeXRlc1tdID0geworICAgICAgICAgICAgICAgIDEyLCA1NiwgMTAwLCAtMiwgLTc2LCA4OSwgNDUsIDkxLCAzLCAtMTUsIDM1LCAyNiwgMywgOTEKKyAgICAgICAgfTsKKyAgICAgICAgU3RyaW5nIHMgPSAiMjQ3ODU2OTQ4NzY0NDMwMTU5OTY0NjczNDE3MDIwMjUxIjsKKyAgICAgICAgQmlnSW50ZWdlciBiaSA9IG5ldyBCaWdJbnRlZ2VyKGFCeXRlcyk7CisgICAgICAgIFN0cmluZyBzQkkgPSBiaS50b1N0cmluZygpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRvU3RyaW5nIG1ldGhvZCByZXR1cm5zIGluY29ycmVjdCB2YWx1ZSBpbnN0ZWFkIG9mICIgKyBzLCBzQkksIHMpOworICAgICAgICBieXRlIGFCeXRlc19bXSA9IHsKKyAgICAgICAgICAgICAgICAtMTIsIDU2LCAxMDAsIC0yLCAtNzYsIDg5LCA0NSwgOTEsIDMsIC0xNSwgMzUsIDI2LCAzLCA5MQorICAgICAgICB9OworICAgICAgICBzID0gIi0yMzg5MjA4ODE3MjMyMDk5MzAyMTAwNjA2MTM4NDQxMzMiOworICAgICAgICBiaSA9IG5ldyBCaWdJbnRlZ2VyKGFCeXRlc18pOworICAgICAgICBzQkkgPSBiaS50b1N0cmluZygpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRvU3RyaW5nIG1ldGhvZCByZXR1cm5zIGluY29ycmVjdCB2YWx1ZSBpbnN0ZWFkIG9mICIgKyBzLCBzQkksIHMpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L0NvbmN1cnJlbnRDbG9zZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L0NvbmN1cnJlbnRDbG9zZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MjZiMDVhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvQ29uY3VycmVudENsb3NlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjMwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmV0OworCitpbXBvcnQgamF2YS5uZXQuRGF0YWdyYW1QYWNrZXQ7CitpbXBvcnQgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU2VydmVyU29ja2V0OworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5Tb2NrZXRDaGFubmVsOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29weU9uV3JpdGVBcnJheUxpc3Q7CitpbXBvcnQgdGVzdHMubmV0LlN0dWNrU2VydmVyOworCisvKioKKyAqIFRlc3QgdGhhdCBTb2NrZXQuY2xvc2UgY2FsbGVkIG9uIGFub3RoZXIgdGhyZWFkIGludGVycnVwdHMgYSB0aHJlYWQgdGhhdCdzIGJsb2NrZWQgZG9pbmcKKyAqIG5ldHdvcmsgSS9PLgorICovCitwdWJsaWMgY2xhc3MgQ29uY3VycmVudENsb3NlVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdF9hY2NlcHQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2VydmVyU29ja2V0IHMgPSBuZXcgU2VydmVyU29ja2V0KDApOworICAgICAgICBuZXcgS2lsbGVyKHMpLnN0YXJ0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oImFjY2VwdC4uLiIpOworICAgICAgICAgICAgcy5hY2NlcHQoKTsKKyAgICAgICAgICAgIGZhaWwoImFjY2VwdCByZXR1cm5lZCEiKTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlNvY2tldCBjbG9zZWQiLCBleHBlY3RlZC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25uZWN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0dWNrU2VydmVyIHNzID0gbmV3IFN0dWNrU2VydmVyKCk7CisgICAgICAgIFNvY2tldCBzID0gbmV3IFNvY2tldCgpOworICAgICAgICBuZXcgS2lsbGVyKHMpLnN0YXJ0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oImNvbm5lY3QuLi4iKTsKKyAgICAgICAgICAgIHMuY29ubmVjdChzcy5nZXRMb2NhbFNvY2tldEFkZHJlc3MoKSk7CisgICAgICAgICAgICBmYWlsKCJjb25uZWN0IHJldHVybmVkISIpOworICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiU29ja2V0IGNsb3NlZCIsIGV4cGVjdGVkLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzcy5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25uZWN0X25vbkJsb2NraW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0dWNrU2VydmVyIHNzID0gbmV3IFN0dWNrU2VydmVyKCk7CisgICAgICAgIFNvY2tldENoYW5uZWwgcyA9IFNvY2tldENoYW5uZWwub3BlbigpOworICAgICAgICBuZXcgS2lsbGVyKHMuc29ja2V0KCkpLnN0YXJ0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oImNvbm5lY3QgKG5vbi1ibG9ja2luZykuLi4iKTsKKyAgICAgICAgICAgIHMuY29uZmlndXJlQmxvY2tpbmcoZmFsc2UpOworICAgICAgICAgICAgcy5jb25uZWN0KHNzLmdldExvY2FsU29ja2V0QWRkcmVzcygpKTsKKyAgICAgICAgICAgIHdoaWxlICghcy5maW5pc2hDb25uZWN0KCkpIHsKKyAgICAgICAgICAgICAgICAvLyBTcGluIGxpa2UgYSBtYWQgdGhpbmchCisgICAgICAgICAgICB9CisgICAgICAgICAgICBmYWlsKCJjb25uZWN0IHJldHVybmVkISIpOworICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiU29ja2V0IGNsb3NlZCIsIGV4cGVjdGVkLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKEFzeW5jaHJvbm91c0Nsb3NlRXhjZXB0aW9uIGFsc29Pa2F5KSB7CisgICAgICAgICAgICAvLyBTZWUgYmVsb3cuCisgICAgICAgIH0gY2F0Y2ggKENsb3NlZENoYW5uZWxFeGNlcHRpb24gYWxzb09rYXkpIHsKKyAgICAgICAgICAgIC8vIEZvciBub3csIEknbSBhc3N1bWluZyB0aGF0IHdlJ3JlIGhhcHB5IGFzIGxvbmcgYXMgd2UgZ2V0IGFueSByZWFzb25hYmxlIGV4Y2VwdGlvbi4KKyAgICAgICAgICAgIC8vIEl0IG1heSBiZSB0aGF0IHdlJ3JlIHN1cHBvc2VkIHRvIGd1YXJhbnRlZSBvbmx5IG9uZSBvciB0aGUgb3RoZXIuCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzcy5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFNlcnZlclNvY2tldCBzcyA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisgICAgICAgIG5ldyBUaHJlYWQobmV3IFJ1bm5hYmxlKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHNzLmFjY2VwdCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0pLnN0YXJ0KCk7CisgICAgICAgIFNvY2tldCBzID0gbmV3IFNvY2tldCgpOworICAgICAgICBzLmNvbm5lY3Qoc3MuZ2V0TG9jYWxTb2NrZXRBZGRyZXNzKCkpOworICAgICAgICBuZXcgS2lsbGVyKHMpLnN0YXJ0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oInJlYWQuLi4iKTsKKyAgICAgICAgICAgIGludCBpID0gcy5nZXRJbnB1dFN0cmVhbSgpLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoInJlYWQgcmV0dXJuZWQgIiArIGkpOworICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiU29ja2V0IGNsb3NlZCIsIGV4cGVjdGVkLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgc3MuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfbXVsdGlwbGUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgZmluYWwgU2VydmVyU29ja2V0IHNzID0gbmV3IFNlcnZlclNvY2tldCgwKTsKKyAgICAgICAgbmV3IFRocmVhZChuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3MuYWNjZXB0KCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSkuc3RhcnQoKTsKKyAgICAgICAgZmluYWwgU29ja2V0IHMgPSBuZXcgU29ja2V0KCk7CisgICAgICAgIHMuY29ubmVjdChzcy5nZXRMb2NhbFNvY2tldEFkZHJlc3MoKSk7CisKKyAgICAgICAgLy8gV2Ugd2FudCB0byB0ZXN0IHRoYXQgd2UgdW5ibG9jayAqYWxsKiB0aGUgdGhyZWFkcyBibG9ja2VkIG9uIGEgc29ja2V0LCBub3QganVzdCBvbmUuCisgICAgICAgIC8vIFdlIGtub3cgdGhlIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlIHNhbWUgbWVjaGFuaXNtIGZvciBhbGwgYmxvY2tpbmcgY2FsbHMsIHNvIHdlIGp1c3QKKyAgICAgICAgLy8gdGVzdCByZWFkKDIpIGJlY2F1c2UgaXQncyB0aGUgZWFzaWVzdCB0byB0ZXN0LiAocmVjdigyKSwgZm9yIGV4YW1wbGUsIGlzIG9ubHkgYWNjZXNzaWJsZQorICAgICAgICAvLyBmcm9tIEphdmEgdmlhIGEgc3luY2hyb25pemVkIG1ldGhvZC4pCisgICAgICAgIGZpbmFsIEFycmF5TGlzdDxUaHJlYWQ+IHRocmVhZHMgPSBuZXcgQXJyYXlMaXN0PFRocmVhZD4oKTsKKyAgICAgICAgZmluYWwgTGlzdDxUaHJvd2FibGU+IHRocm93bkV4Y2VwdGlvbnMgPSBuZXcgQ29weU9uV3JpdGVBcnJheUxpc3Q8VGhyb3dhYmxlPigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICAgICAgICAgIFRocmVhZCB0ID0gbmV3IFRocmVhZChuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oInJlYWQuLi4iKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaSA9IHMuZ2V0SW5wdXRTdHJlYW0oKS5yZWFkKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCgicmVhZCByZXR1cm5lZCAiICsgaSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlNvY2tldCBjbG9zZWQiLCBleHBlY3RlZC5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93bkV4Y2VwdGlvbnMuYWRkKGV4KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICAgICAgICAgICAgdGhyZWFkcy5hZGQodCk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChUaHJlYWQgdCA6IHRocmVhZHMpIHsKKyAgICAgICAgICAgIHQuc3RhcnQoKTsKKyAgICAgICAgfQorICAgICAgICBuZXcgS2lsbGVyKHMpLnN0YXJ0KCk7CisgICAgICAgIGZvciAoVGhyZWFkIHQgOiB0aHJlYWRzKSB7CisgICAgICAgICAgICB0LmpvaW4oKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKFRocm93YWJsZSBleGNlcHRpb24gOiB0aHJvd25FeGNlcHRpb25zKSB7CisgICAgICAgICAgICB0aHJvdyBleGNlcHRpb247CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlY3YoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRGF0YWdyYW1Tb2NrZXQgcyA9IG5ldyBEYXRhZ3JhbVNvY2tldCgpOworICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbMjAwXTsKKyAgICAgICAgRGF0YWdyYW1QYWNrZXQgcCA9IG5ldyBEYXRhZ3JhbVBhY2tldChidWYsIDIwMCk7CisgICAgICAgIG5ldyBLaWxsZXIocykuc3RhcnQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigicmVjZWl2ZS4uLiIpOworICAgICAgICAgICAgcy5yZWNlaXZlKHApOworICAgICAgICAgICAgZmFpbCgicmVjZWl2ZSByZXR1cm5lZCEiKTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlNvY2tldCBjbG9zZWQiLCBleHBlY3RlZC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTZXJ2ZXJTb2NrZXQgc3MgPSBuZXcgU2VydmVyU29ja2V0KDApOworICAgICAgICBuZXcgVGhyZWFkKG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oImFjY2VwdGluZy4uLiIpOworCisgICAgICAgICAgICAgICAgICAgIFNvY2tldCBjbGllbnQgPSBzcy5hY2NlcHQoKTsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJhY2NlcHRlZC4uLiIpOworICAgICAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMzAgKiAxMDAwKTsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJzZXJ2ZXIgZXhpdGluZy4uLiIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0pLnN0YXJ0KCk7CisgICAgICAgIFNvY2tldCBzID0gbmV3IFNvY2tldCgpOworICAgICAgICBzLmNvbm5lY3Qoc3MuZ2V0TG9jYWxTb2NrZXRBZGRyZXNzKCkpOworICAgICAgICBuZXcgS2lsbGVyKHMpLnN0YXJ0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIndyaXRlLi4uIik7CisgICAgICAgICAgICAvLyBXZSBqdXN0IGtlZXAgd3JpdGluZyBoZXJlIHVudGlsIGFsbCB0aGUgYnVmZmVycyBhcmUgZnVsbCBhbmQgd2UgYmxvY2ssCisgICAgICAgICAgICAvLyB3YWl0aW5nIGZvciB0aGUgc2VydmVyIHRvIHJlYWQgKHdoaWNoIGl0IG5ldmVyIHdpbGwpLiBJZiB0aGUgYXN5bmNocm9ub3VzIGNsb3NlCisgICAgICAgICAgICAvLyBmYWlscywgd2UnbGwgc2VlIGEgdGVzdCB0aW1lb3V0IGhlcmUuCisgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsyNTYqMTAyNF07CisgICAgICAgICAgICAgICAgcy5nZXRPdXRwdXRTdHJlYW0oKS53cml0ZShidWYpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIC8vIFdlIHRocm93ICJDb25uZWN0aW9uIHJlc2V0IGJ5IHBlZXIiLCB3aGljaCBJIGRvbid0IF90aGlua18gaXMgYSBwcm9ibGVtLgorICAgICAgICAgICAgLy8gYXNzZXJ0RXF1YWxzKCJTb2NrZXQgY2xvc2VkIiwgZXhwZWN0ZWQuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBzcy5jbG9zZSgpOworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBLaWxsZXI8VD4gZXh0ZW5kcyBUaHJlYWQgeworICAgICAgICBwcml2YXRlIGZpbmFsIFQgczsKKworICAgICAgICBwdWJsaWMgS2lsbGVyKFQgcykgeworICAgICAgICAgICAgdGhpcy5zID0gczsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJzbGVlcC4uLiIpOworICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCgyMDAwKTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oImNsb3NlLi4uIik7CisgICAgICAgICAgICAgICAgcy5nZXRDbGFzcygpLmdldE1ldGhvZCgiY2xvc2UiKS5pbnZva2Uocyk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L0Nvb2tpZXNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9Db29raWVzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE2NjE2NzMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9Db29raWVzVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjA5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmV0OworCitpbXBvcnQgY29tLmdvb2dsZS5tb2Nrd2Vic2VydmVyLk1vY2tSZXNwb25zZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vY2t3ZWJzZXJ2ZXIuTW9ja1dlYlNlcnZlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vY2t3ZWJzZXJ2ZXIuUmVjb3JkZWRSZXF1ZXN0OworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuQ29va2llSGFuZGxlcjsKK2ltcG9ydCBqYXZhLm5ldC5Db29raWVNYW5hZ2VyOworaW1wb3J0IHN0YXRpYyBqYXZhLm5ldC5Db29raWVQb2xpY3kuQUNDRVBUX09SSUdJTkFMX1NFUlZFUjsKK2ltcG9ydCBqYXZhLm5ldC5Db29raWVTdG9yZTsKK2ltcG9ydCBqYXZhLm5ldC5IdHRwQ29va2llOworaW1wb3J0IGphdmEubmV0Lkh0dHBVUkxDb25uZWN0aW9uOworaW1wb3J0IGphdmEubmV0LlVSSTsKK2ltcG9ydCBqYXZhLm5ldC5VUklTeW50YXhFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5Db21wYXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBDb29raWVzVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gRU1QVFlfQ09PS0lFU19NQVAgPSBDb2xsZWN0aW9ucy5lbXB0eU1hcCgpOworCisgICAgcHVibGljIHZvaWQgdGVzdE5ldHNjYXBlUmVzcG9uc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ29va2llTWFuYWdlciBjb29raWVNYW5hZ2VyID0gbmV3IENvb2tpZU1hbmFnZXIobnVsbCwgQUNDRVBUX09SSUdJTkFMX1NFUlZFUik7CisgICAgICAgIENvb2tpZUhhbmRsZXIuc2V0RGVmYXVsdChjb29raWVNYW5hZ2VyKTsKKyAgICAgICAgTW9ja1dlYlNlcnZlciBzZXJ2ZXIgPSBuZXcgTW9ja1dlYlNlcnZlcigpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5hZGRIZWFkZXIoIlNldC1Db29raWU6IGE9YW5kcm9pZDsgIgorICAgICAgICAgICAgICAgICsgImV4cGlyZXM9RnJpLCAzMS1EZWMtOTk5OSAyMzo1OTo1OSBHTVQ7ICIKKyAgICAgICAgICAgICAgICArICJwYXRoPS9wYXRoOyAiCisgICAgICAgICAgICAgICAgKyAiZG9tYWluPS5sb2NhbDsgIgorICAgICAgICAgICAgICAgICsgInNlY3VyZSIpKTsKKyAgICAgICAgZ2V0KHNlcnZlciwgIi9wYXRoL2ZvbyIpOworCisgICAgICAgIExpc3Q8SHR0cENvb2tpZT4gY29va2llcyA9IGNvb2tpZU1hbmFnZXIuZ2V0Q29va2llU3RvcmUoKS5nZXRDb29raWVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBjb29raWVzLnNpemUoKSk7CisgICAgICAgIEh0dHBDb29raWUgY29va2llID0gY29va2llcy5nZXQoMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIGNvb2tpZS5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFuZHJvaWQiLCBjb29raWUuZ2V0VmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBjb29raWUuZ2V0Q29tbWVudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGNvb2tpZS5nZXRDb21tZW50VVJMKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIGNvb2tpZS5nZXREaXNjYXJkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi5sb2NhbCIsIGNvb2tpZS5nZXREb21haW4oKSk7CisgICAgICAgIGFzc2VydFRydWUoY29va2llLmdldE1heEFnZSgpID4gMTAwMDAwMDAwMDAwTCk7CisgICAgICAgIGFzc2VydEVxdWFscygiL3BhdGgiLCBjb29raWUuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGNvb2tpZS5nZXRTZWN1cmUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBjb29raWUuZ2V0VmVyc2lvbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmZjMjEwOVJlc3BvbnNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENvb2tpZU1hbmFnZXIgY29va2llTWFuYWdlciA9IG5ldyBDb29raWVNYW5hZ2VyKG51bGwsIEFDQ0VQVF9PUklHSU5BTF9TRVJWRVIpOworICAgICAgICBDb29raWVIYW5kbGVyLnNldERlZmF1bHQoY29va2llTWFuYWdlcik7CisgICAgICAgIE1vY2tXZWJTZXJ2ZXIgc2VydmVyID0gbmV3IE1vY2tXZWJTZXJ2ZXIoKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuYWRkSGVhZGVyKCJTZXQtQ29va2llOiBhPWFuZHJvaWQ7ICIKKyAgICAgICAgICAgICAgICArICJDb21tZW50PXRoaXMgY29va2llIGlzIGRlbGljaW91czsgIgorICAgICAgICAgICAgICAgICsgIkRvbWFpbj0ubG9jYWw7ICIKKyAgICAgICAgICAgICAgICArICJNYXgtQWdlPTYwOyAiCisgICAgICAgICAgICAgICAgKyAiUGF0aD0vcGF0aDsgIgorICAgICAgICAgICAgICAgICsgIlNlY3VyZTsgIgorICAgICAgICAgICAgICAgICsgIlZlcnNpb249MSIpKTsKKyAgICAgICAgZ2V0KHNlcnZlciwgIi9wYXRoL2ZvbyIpOworCisgICAgICAgIExpc3Q8SHR0cENvb2tpZT4gY29va2llcyA9IGNvb2tpZU1hbmFnZXIuZ2V0Q29va2llU3RvcmUoKS5nZXRDb29raWVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBjb29raWVzLnNpemUoKSk7CisgICAgICAgIEh0dHBDb29raWUgY29va2llID0gY29va2llcy5nZXQoMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIGNvb2tpZS5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFuZHJvaWQiLCBjb29raWUuZ2V0VmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidGhpcyBjb29raWUgaXMgZGVsaWNpb3VzIiwgY29va2llLmdldENvbW1lbnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBjb29raWUuZ2V0Q29tbWVudFVSTCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBjb29raWUuZ2V0RGlzY2FyZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIubG9jYWwiLCBjb29raWUuZ2V0RG9tYWluKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNjAsIGNvb2tpZS5nZXRNYXhBZ2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL3BhdGgiLCBjb29raWUuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGNvb2tpZS5nZXRTZWN1cmUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBjb29raWUuZ2V0VmVyc2lvbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmZjMjk2NVJlc3BvbnNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENvb2tpZU1hbmFnZXIgY29va2llTWFuYWdlciA9IG5ldyBDb29raWVNYW5hZ2VyKG51bGwsIEFDQ0VQVF9PUklHSU5BTF9TRVJWRVIpOworICAgICAgICBDb29raWVIYW5kbGVyLnNldERlZmF1bHQoY29va2llTWFuYWdlcik7CisgICAgICAgIE1vY2tXZWJTZXJ2ZXIgc2VydmVyID0gbmV3IE1vY2tXZWJTZXJ2ZXIoKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuYWRkSGVhZGVyKCJTZXQtQ29va2llMjogYT1hbmRyb2lkOyAiCisgICAgICAgICAgICAgICAgKyAiQ29tbWVudD10aGlzIGNvb2tpZSBpcyBkZWxpY2lvdXM7ICIKKyAgICAgICAgICAgICAgICArICJDb21tZW50VVJMPWh0dHA6Ly9nb29nbGUuY29tLzsgIgorICAgICAgICAgICAgICAgICsgIkRpc2NhcmQ7ICIKKyAgICAgICAgICAgICAgICArICJEb21haW49LmxvY2FsOyAiCisgICAgICAgICAgICAgICAgKyAiTWF4LUFnZT02MDsgIgorICAgICAgICAgICAgICAgICsgIlBhdGg9L3BhdGg7ICIKKyAgICAgICAgICAgICAgICArICJQb3J0PVwiODAsNDQzLCIgKyBzZXJ2ZXIuZ2V0UG9ydCgpICsgIlwiOyAiCisgICAgICAgICAgICAgICAgKyAiU2VjdXJlOyAiCisgICAgICAgICAgICAgICAgKyAiVmVyc2lvbj0xIikpOworICAgICAgICBnZXQoc2VydmVyLCAiL3BhdGgvZm9vIik7CisKKyAgICAgICAgTGlzdDxIdHRwQ29va2llPiBjb29raWVzID0gY29va2llTWFuYWdlci5nZXRDb29raWVTdG9yZSgpLmdldENvb2tpZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNvb2tpZXMuc2l6ZSgpKTsKKyAgICAgICAgSHR0cENvb2tpZSBjb29raWUgPSBjb29raWVzLmdldCgwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgY29va2llLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYW5kcm9pZCIsIGNvb2tpZS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0aGlzIGNvb2tpZSBpcyBkZWxpY2lvdXMiLCBjb29raWUuZ2V0Q29tbWVudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vZ29vZ2xlLmNvbS8iLCBjb29raWUuZ2V0Q29tbWVudFVSTCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGNvb2tpZS5nZXREaXNjYXJkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi5sb2NhbCIsIGNvb2tpZS5nZXREb21haW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg2MCwgY29va2llLmdldE1heEFnZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvcGF0aCIsIGNvb2tpZS5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjgwLDQ0MywiICsgc2VydmVyLmdldFBvcnQoKSwgY29va2llLmdldFBvcnRsaXN0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgY29va2llLmdldFNlY3VyZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNvb2tpZS5nZXRWZXJzaW9uKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RRdW90ZWRBdHRyaWJ1dGVWYWx1ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ29va2llTWFuYWdlciBjb29raWVNYW5hZ2VyID0gbmV3IENvb2tpZU1hbmFnZXIobnVsbCwgQUNDRVBUX09SSUdJTkFMX1NFUlZFUik7CisgICAgICAgIENvb2tpZUhhbmRsZXIuc2V0RGVmYXVsdChjb29raWVNYW5hZ2VyKTsKKyAgICAgICAgTW9ja1dlYlNlcnZlciBzZXJ2ZXIgPSBuZXcgTW9ja1dlYlNlcnZlcigpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5hZGRIZWFkZXIoIlNldC1Db29raWUyOiBhPVwiYW5kcm9pZFwiOyAiCisgICAgICAgICAgICAgICAgKyAiQ29tbWVudD1cInRoaXMgY29va2llIGlzIGRlbGljaW91c1wiOyAiCisgICAgICAgICAgICAgICAgKyAiQ29tbWVudFVSTD1cImh0dHA6Ly9nb29nbGUuY29tL1wiOyAiCisgICAgICAgICAgICAgICAgKyAiRGlzY2FyZDsgIgorICAgICAgICAgICAgICAgICsgIkRvbWFpbj1cIi5sb2NhbFwiOyAiCisgICAgICAgICAgICAgICAgKyAiTWF4LUFnZT1cIjYwXCI7ICIKKyAgICAgICAgICAgICAgICArICJQYXRoPVwiL3BhdGhcIjsgIgorICAgICAgICAgICAgICAgICsgIlBvcnQ9XCI4MCw0NDMsIiArIHNlcnZlci5nZXRQb3J0KCkgKyAiXCI7ICIKKyAgICAgICAgICAgICAgICArICJTZWN1cmU7ICIKKyAgICAgICAgICAgICAgICArICJWZXJzaW9uPVwiMVwiIikpOworICAgICAgICBnZXQoc2VydmVyLCAiL3BhdGgvZm9vIik7CisKKyAgICAgICAgTGlzdDxIdHRwQ29va2llPiBjb29raWVzID0gY29va2llTWFuYWdlci5nZXRDb29raWVTdG9yZSgpLmdldENvb2tpZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNvb2tpZXMuc2l6ZSgpKTsKKyAgICAgICAgSHR0cENvb2tpZSBjb29raWUgPSBjb29raWVzLmdldCgwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgY29va2llLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYW5kcm9pZCIsIGNvb2tpZS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0aGlzIGNvb2tpZSBpcyBkZWxpY2lvdXMiLCBjb29raWUuZ2V0Q29tbWVudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vZ29vZ2xlLmNvbS8iLCBjb29raWUuZ2V0Q29tbWVudFVSTCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGNvb2tpZS5nZXREaXNjYXJkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi5sb2NhbCIsIGNvb2tpZS5nZXREb21haW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg2MCwgY29va2llLmdldE1heEFnZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvcGF0aCIsIGNvb2tpZS5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjgwLDQ0MywiICsgc2VydmVyLmdldFBvcnQoKSwgY29va2llLmdldFBvcnRsaXN0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgY29va2llLmdldFNlY3VyZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNvb2tpZS5nZXRWZXJzaW9uKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXNwb25zZVdpdGhNdWx0aXBsZUNvb2tpZUhlYWRlckxpbmVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RDb29raWVTdG9yZSBjb29raWVTdG9yZSA9IG5ldyBUZXN0Q29va2llU3RvcmUoKTsKKyAgICAgICAgQ29va2llTWFuYWdlciBjb29raWVNYW5hZ2VyID0gbmV3IENvb2tpZU1hbmFnZXIoY29va2llU3RvcmUsIEFDQ0VQVF9PUklHSU5BTF9TRVJWRVIpOworICAgICAgICBjb29raWVNYW5hZ2VyLnB1dChuZXcgVVJJKCJodHRwOi8vYW5kcm9pZC5jb20iKSwgY29va2llSGVhZGVycygiYT1hbmRyb2lkIiwgImI9YmFuYW5hIikpOworICAgICAgICBMaXN0PEh0dHBDb29raWU+IGNvb2tpZXMgPSBzb3J0ZWRDb3B5KGNvb2tpZVN0b3JlLmNvb2tpZXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgY29va2llcy5zaXplKCkpOworICAgICAgICBIdHRwQ29va2llIGNvb2tpZUEgPSBjb29raWVzLmdldCgwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgY29va2llQS5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFuZHJvaWQiLCBjb29raWVBLmdldFZhbHVlKCkpOworICAgICAgICBIdHRwQ29va2llIGNvb2tpZUIgPSBjb29raWVzLmdldCgxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiIiwgY29va2llQi5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJhbmFuYSIsIGNvb2tpZUIuZ2V0VmFsdWUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERvbWFpbkRlZmF1bHRpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdENvb2tpZVN0b3JlIGNvb2tpZVN0b3JlID0gbmV3IFRlc3RDb29raWVTdG9yZSgpOworICAgICAgICBDb29raWVNYW5hZ2VyIGNvb2tpZU1hbmFnZXIgPSBuZXcgQ29va2llTWFuYWdlcihjb29raWVTdG9yZSwgQUNDRVBUX09SSUdJTkFMX1NFUlZFUik7CisgICAgICAgIGNvb2tpZU1hbmFnZXIucHV0KG5ldyBVUkkoImh0dHA6Ly9hbmRyb2lkLmNvbS8iKSwgY29va2llSGVhZGVycygiYT1hbmRyb2lkIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFuZHJvaWQuY29tIiwgY29va2llU3RvcmUuZ2V0Q29va2llKCJhIikuZ2V0RG9tYWluKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROb25NYXRjaGluZ0RvbWFpbnNSZWplY3RlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0Q29va2llU3RvcmUgY29va2llU3RvcmUgPSBuZXcgVGVzdENvb2tpZVN0b3JlKCk7CisgICAgICAgIENvb2tpZU1hbmFnZXIgY29va2llTWFuYWdlciA9IG5ldyBDb29raWVNYW5hZ2VyKGNvb2tpZVN0b3JlLCBBQ0NFUFRfT1JJR0lOQUxfU0VSVkVSKTsKKyAgICAgICAgY29va2llTWFuYWdlci5wdXQobmV3IFVSSSgiaHR0cDovL2FuZHJvaWQuY29tLyIpLAorICAgICAgICAgICAgICAgIGNvb2tpZUhlYWRlcnMoImE9YW5kcm9pZDtkb21haW49Z29vZ2xlLmNvbSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENvbGxlY3Rpb25zLjxIdHRwQ29va2llPmVtcHR5TGlzdCgpLCBjb29raWVTdG9yZS5jb29raWVzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF0Y2hpbmdEb21haW5zQWNjZXB0ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdENvb2tpZVN0b3JlIGNvb2tpZVN0b3JlID0gbmV3IFRlc3RDb29raWVTdG9yZSgpOworICAgICAgICBDb29raWVNYW5hZ2VyIGNvb2tpZU1hbmFnZXIgPSBuZXcgQ29va2llTWFuYWdlcihjb29raWVTdG9yZSwgQUNDRVBUX09SSUdJTkFMX1NFUlZFUik7CisgICAgICAgIGNvb2tpZU1hbmFnZXIucHV0KG5ldyBVUkkoImh0dHA6Ly93d3cuYW5kcm9pZC5jb20vIiksCisgICAgICAgICAgICAgICAgY29va2llSGVhZGVycygiYT1hbmRyb2lkO2RvbWFpbj0uYW5kcm9pZC5jb20iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLmFuZHJvaWQuY29tIiwgY29va2llU3RvcmUuZ2V0Q29va2llKCJhIikuZ2V0RG9tYWluKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXRoRGVmYXVsdGluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0Q29va2llU3RvcmUgY29va2llU3RvcmUgPSBuZXcgVGVzdENvb2tpZVN0b3JlKCk7CisgICAgICAgIENvb2tpZU1hbmFnZXIgY29va2llTWFuYWdlciA9IG5ldyBDb29raWVNYW5hZ2VyKGNvb2tpZVN0b3JlLCBBQ0NFUFRfT1JJR0lOQUxfU0VSVkVSKTsKKyAgICAgICAgY29va2llTWFuYWdlci5wdXQobmV3IFVSSSgiaHR0cDovL2FuZHJvaWQuY29tL2Zvby9iYXIiKSwgY29va2llSGVhZGVycygiYT1hbmRyb2lkIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9mb28vIiwgY29va2llU3RvcmUuZ2V0Q29va2llKCJhIikuZ2V0UGF0aCgpKTsKKyAgICAgICAgY29va2llTWFuYWdlci5wdXQobmV3IFVSSSgiaHR0cDovL2FuZHJvaWQuY29tLyIpLCBjb29raWVIZWFkZXJzKCJiPWJhbmFuYSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvIiwgY29va2llU3RvcmUuZ2V0Q29va2llKCJiIikuZ2V0UGF0aCgpKTsKKyAgICAgICAgY29va2llTWFuYWdlci5wdXQobmV3IFVSSSgiaHR0cDovL2FuZHJvaWQuY29tL2Zvby8iKSwgY29va2llSGVhZGVycygiYz1jYXJyb3QiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL2Zvby8iLCBjb29raWVTdG9yZS5nZXRDb29raWUoImMiKS5nZXRQYXRoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROb25NYXRjaGluZ1BhdGhzUmVqZWN0ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdENvb2tpZVN0b3JlIGNvb2tpZVN0b3JlID0gbmV3IFRlc3RDb29raWVTdG9yZSgpOworICAgICAgICBDb29raWVNYW5hZ2VyIGNvb2tpZU1hbmFnZXIgPSBuZXcgQ29va2llTWFuYWdlcihjb29raWVTdG9yZSwgQUNDRVBUX09SSUdJTkFMX1NFUlZFUik7CisgICAgICAgIGNvb2tpZU1hbmFnZXIucHV0KG5ldyBVUkkoImh0dHA6Ly9hbmRyb2lkLmNvbS9mb28vYmFyIiksCisgICAgICAgICAgICAgICAgY29va2llSGVhZGVycygiYT1hbmRyb2lkO3BhdGg9L2Jhei9iYXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRXhwZWN0ZWQgdG8gcmVqZWN0IGNvb2tpZXMgd2hvc2UgcGF0aCBpcyBub3QgYSBwcmVmaXggb2YgdGhlIHJlcXVlc3QgcGF0aCIsCisgICAgICAgICAgICAgICAgQ29sbGVjdGlvbnMuPEh0dHBDb29raWU+ZW1wdHlMaXN0KCksIGNvb2tpZVN0b3JlLmNvb2tpZXMpOyAvLyBSSTYgZmFpbHMgdGhpcworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYXRjaGluZ1BhdGhzQWNjZXB0ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdENvb2tpZVN0b3JlIGNvb2tpZVN0b3JlID0gbmV3IFRlc3RDb29raWVTdG9yZSgpOworICAgICAgICBDb29raWVNYW5hZ2VyIGNvb2tpZU1hbmFnZXIgPSBuZXcgQ29va2llTWFuYWdlcihjb29raWVTdG9yZSwgQUNDRVBUX09SSUdJTkFMX1NFUlZFUik7CisgICAgICAgIGNvb2tpZU1hbmFnZXIucHV0KG5ldyBVUkkoImh0dHA6Ly9hbmRyb2lkLmNvbS9mb28vYmFyLyIpLAorICAgICAgICAgICAgICAgIGNvb2tpZUhlYWRlcnMoImE9YW5kcm9pZDtwYXRoPS9mb28iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL2ZvbyIsIGNvb2tpZVN0b3JlLmdldENvb2tpZSgiYSIpLmdldFBhdGgoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vQ29va2llSGVhZGVyU2VudElmTm9Db29raWVzTWF0Y2goKSB0aHJvd3MgSU9FeGNlcHRpb24sIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIENvb2tpZU1hbmFnZXIgY29va2llTWFuYWdlciA9IG5ldyBDb29raWVNYW5hZ2VyKG51bGwsIEFDQ0VQVF9PUklHSU5BTF9TRVJWRVIpOworICAgICAgICBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IGNvb2tpZUhlYWRlcnMgPSBjb29raWVNYW5hZ2VyLmdldCgKKyAgICAgICAgICAgICAgICBuZXcgVVJJKCJodHRwOi8vYW5kcm9pZC5jb20vZm9vL2Jhci8iKSwgRU1QVFlfQ09PS0lFU19NQVApOworICAgICAgICBhc3NlcnRUcnVlKGNvb2tpZUhlYWRlcnMudG9TdHJpbmcoKSwgY29va2llSGVhZGVycy5pc0VtcHR5KCkKKyAgICAgICAgICAgICAgICB8fCAoY29va2llSGVhZGVycy5zaXplKCkgPT0gMSAmJiBjb29raWVIZWFkZXJzLmdldCgiQ29va2llIikuaXNFbXB0eSgpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNlbmRpbmdDb29raWVzRnJvbVN0b3JlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1vY2tXZWJTZXJ2ZXIgc2VydmVyID0gbmV3IE1vY2tXZWJTZXJ2ZXIoKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBDb29raWVNYW5hZ2VyIGNvb2tpZU1hbmFnZXIgPSBuZXcgQ29va2llTWFuYWdlcihudWxsLCBBQ0NFUFRfT1JJR0lOQUxfU0VSVkVSKTsKKyAgICAgICAgSHR0cENvb2tpZSBjb29raWVBID0gbmV3IEh0dHBDb29raWUoImEiLCAiYW5kcm9pZCIpOworICAgICAgICBjb29raWVBLnNldERvbWFpbigiLmxvY2FsIik7CisgICAgICAgIGNvb2tpZUEuc2V0UGF0aCgiLyIpOworICAgICAgICBjb29raWVNYW5hZ2VyLmdldENvb2tpZVN0b3JlKCkuYWRkKHNlcnZlci5nZXRVcmwoIi8iKS50b1VSSSgpLCBjb29raWVBKTsKKyAgICAgICAgSHR0cENvb2tpZSBjb29raWVCID0gbmV3IEh0dHBDb29raWUoImIiLCAiYmFuYW5hIik7CisgICAgICAgIGNvb2tpZUIuc2V0RG9tYWluKCIubG9jYWwiKTsKKyAgICAgICAgY29va2llQi5zZXRQYXRoKCIvIik7CisgICAgICAgIGNvb2tpZU1hbmFnZXIuZ2V0Q29va2llU3RvcmUoKS5hZGQoc2VydmVyLmdldFVybCgiLyIpLnRvVVJJKCksIGNvb2tpZUIpOworICAgICAgICBDb29raWVIYW5kbGVyLnNldERlZmF1bHQoY29va2llTWFuYWdlcik7CisKKyAgICAgICAgZ2V0KHNlcnZlciwgIi8iKTsKKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IHJlcXVlc3QgPSBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsKKworICAgICAgICBMaXN0PFN0cmluZz4gcmVjZWl2ZWRIZWFkZXJzID0gcmVxdWVzdC5nZXRIZWFkZXJzKCk7CisgICAgICAgIGFzc2VydENvbnRhaW5zKHJlY2VpdmVkSGVhZGVycywgIkNvb2tpZTogJFZlcnNpb249XCIxXCI7ICIKKyAgICAgICAgICAgICAgICArICJhPVwiYW5kcm9pZFwiOyRQYXRoPVwiL1wiOyREb21haW49XCIubG9jYWxcIjsgIgorICAgICAgICAgICAgICAgICsgImI9XCJiYW5hbmFcIjskUGF0aD1cIi9cIjskRG9tYWluPVwiLmxvY2FsXCIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVkaXJlY3RzRG9Ob3RJbmNsdWRlVG9vTWFueUNvb2tpZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja1dlYlNlcnZlciByZWRpcmVjdFRhcmdldCA9IG5ldyBNb2NrV2ViU2VydmVyKCk7CisgICAgICAgIHJlZGlyZWN0VGFyZ2V0LmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkEiKSk7CisgICAgICAgIHJlZGlyZWN0VGFyZ2V0LnBsYXkoKTsKKworICAgICAgICBNb2NrV2ViU2VydmVyIHJlZGlyZWN0U291cmNlID0gbmV3IE1vY2tXZWJTZXJ2ZXIoKTsKKyAgICAgICAgcmVkaXJlY3RTb3VyY2UuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuc2V0UmVzcG9uc2VDb2RlKEh0dHBVUkxDb25uZWN0aW9uLkhUVFBfTU9WRURfVEVNUCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMb2NhdGlvbjogIiArIHJlZGlyZWN0VGFyZ2V0LmdldFVybCgiLyIpKSk7CisgICAgICAgIHJlZGlyZWN0U291cmNlLnBsYXkoKTsKKworICAgICAgICBDb29raWVNYW5hZ2VyIGNvb2tpZU1hbmFnZXIgPSBuZXcgQ29va2llTWFuYWdlcihudWxsLCBBQ0NFUFRfT1JJR0lOQUxfU0VSVkVSKTsKKyAgICAgICAgSHR0cENvb2tpZSBjb29raWUgPSBuZXcgSHR0cENvb2tpZSgiYyIsICJjb29raWUiKTsKKyAgICAgICAgY29va2llLnNldERvbWFpbigiLmxvY2FsIik7CisgICAgICAgIGNvb2tpZS5zZXRQYXRoKCIvIik7CisgICAgICAgIFN0cmluZyBwb3J0TGlzdCA9IEludGVnZXIudG9TdHJpbmcocmVkaXJlY3RTb3VyY2UuZ2V0UG9ydCgpKTsKKyAgICAgICAgY29va2llLnNldFBvcnRsaXN0KHBvcnRMaXN0KTsKKyAgICAgICAgY29va2llTWFuYWdlci5nZXRDb29raWVTdG9yZSgpLmFkZChyZWRpcmVjdFNvdXJjZS5nZXRVcmwoIi8iKS50b1VSSSgpLCBjb29raWUpOworICAgICAgICBDb29raWVIYW5kbGVyLnNldERlZmF1bHQoY29va2llTWFuYWdlcik7CisKKyAgICAgICAgZ2V0KHJlZGlyZWN0U291cmNlLCAiLyIpOworICAgICAgICBSZWNvcmRlZFJlcXVlc3QgcmVxdWVzdCA9IHJlZGlyZWN0U291cmNlLnRha2VSZXF1ZXN0KCk7CisKKyAgICAgICAgYXNzZXJ0Q29udGFpbnMocmVxdWVzdC5nZXRIZWFkZXJzKCksICJDb29raWU6ICRWZXJzaW9uPVwiMVwiOyAiCisgICAgICAgICAgICAgICAgKyAiYz1cImNvb2tpZVwiOyRQYXRoPVwiL1wiOyREb21haW49XCIubG9jYWxcIjskUG9ydD1cIiIgKyBwb3J0TGlzdCArICJcIiIpOworCisgICAgICAgIGZvciAoU3RyaW5nIGhlYWRlciA6IHJlZGlyZWN0VGFyZ2V0LnRha2VSZXF1ZXN0KCkuZ2V0SGVhZGVycygpKSB7CisgICAgICAgICAgICBpZiAoaGVhZGVyLnN0YXJ0c1dpdGgoIkNvb2tpZSIpKSB7CisgICAgICAgICAgICAgICAgZmFpbChoZWFkZXIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB3aGljaCBoZWFkZXJzIHNob3cgdXAgd2hlcmUuIFRoZSBjb29raWUgbWFuYWdlciBzaG91bGQgYmUgbm90aWZpZWQKKyAgICAgKiBvZiBib3RoIHVzZXItc3BlY2lmaWVkIGFuZCBkZXJpdmVkIGhlYWRlcnMgbGlrZSB7QGNvZGUgSG9zdH0uIEhlYWRlcnMKKyAgICAgKiBuYW1lZCB7QGNvZGUgQ29va2llfSBvciB7QGNvZGUgQ29va2llMn0gdGhhdCBhcmUgcmV0dXJuZWQgYnkgdGhlIGNvb2tpZQorICAgICAqIG1hbmFnZXIgc2hvdWxkIHNob3cgdXAgaW4gdGhlIHJlcXVlc3QgYW5kIGluIHtAY29kZQorICAgICAqIGdldFJlcXVlc3RQcm9wZXJ0aWVzfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCAgICAgdGVzdEhlYWRlcnNTZW50VG9Db29raWVIYW5kbGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gY29va2llSGFuZGxlckhlYWRlcnMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4oKTsKKyAgICAgICAgQ29va2llSGFuZGxlci5zZXREZWZhdWx0KG5ldyBDb29raWVNYW5hZ2VyKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IGdldChVUkkgdXJpLAorICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IHJlcXVlc3RIZWFkZXJzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIGNvb2tpZUhhbmRsZXJIZWFkZXJzLnB1dEFsbChyZXF1ZXN0SGVhZGVycyk7CisgICAgICAgICAgICAgICAgTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PiByZXN1bHQgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4oKTsKKyAgICAgICAgICAgICAgICByZXN1bHQucHV0KCJDb29raWUiLCBDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KCJCYXI9YmFyIikpOworICAgICAgICAgICAgICAgIHJlc3VsdC5wdXQoIkNvb2tpZTIiLCBDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KCJCYXo9YmF6IikpOworICAgICAgICAgICAgICAgIHJlc3VsdC5wdXQoIlF1dXgiLCBDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KCJxdXV4IikpOworICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgICAgICBNb2NrV2ViU2VydmVyIHNlcnZlciA9IG5ldyBNb2NrV2ViU2VydmVyKCk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb2xsZWN0aW9ucy48U3RyaW5nLCBMaXN0PFN0cmluZz4+ZW1wdHlNYXAoKSwKKyAgICAgICAgICAgICAgICBjb25uZWN0aW9uLmdldFJlcXVlc3RQcm9wZXJ0aWVzKCkpOworCisgICAgICAgIGNvbm5lY3Rpb24uc2V0UmVxdWVzdFByb3BlcnR5KCJGb28iLCAiZm9vIik7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0RG9PdXRwdXQodHJ1ZSk7CisgICAgICAgIGNvbm5lY3Rpb24uZ2V0T3V0cHV0U3RyZWFtKCkud3JpdGUoNSk7CisgICAgICAgIGNvbm5lY3Rpb24uZ2V0T3V0cHV0U3RyZWFtKCkuY2xvc2UoKTsKKyAgICAgICAgY29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpLmNsb3NlKCk7CisKKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IHJlcXVlc3QgPSBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsKKworICAgICAgICBhc3NlcnRDb250YWluc0FsbChjb29raWVIYW5kbGVySGVhZGVycy5rZXlTZXQoKSwgIkZvbyIpOworICAgICAgICBhc3NlcnRDb250YWluc0FsbChjb29raWVIYW5kbGVySGVhZGVycy5rZXlTZXQoKSwKKyAgICAgICAgICAgICAgICAiQ29udGVudC1UeXBlIiwgIlVzZXItQWdlbnQiLCAiQ29ubmVjdGlvbiIsICJIb3N0Iik7CisgICAgICAgIGFzc2VydEZhbHNlKGNvb2tpZUhhbmRsZXJIZWFkZXJzLmNvbnRhaW5zS2V5KCJDb29raWUiKSk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVGhlIEFQSSBzcGVjaWZpZXMgdGhhdCBjYWxsaW5nIGdldFJlcXVlc3RQcm9wZXJ0aWVzKCkgb24gYSBjb25uZWN0ZWQgaW5zdGFuY2Ugc2hvdWxkIGZhaWwKKyAgICAgICAgICogd2l0aCBhbiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24sIGJ1dCB0aGUgUkkgdmlvbGF0ZXMgdGhlIHNwZWMgYW5kIHJldHVybnMgYSB2YWxpZCBtYXAuCisgICAgICAgICAqIGh0dHA6Ly93d3cubWFpbC1hcmNoaXZlLmNvbS9uZXQtZGV2QG9wZW5qZGsuamF2YS5uZXQvbXNnMDE3NjguaHRtbAorICAgICAgICAgKi8KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydENvbnRhaW5zQWxsKGNvbm5lY3Rpb24uZ2V0UmVxdWVzdFByb3BlcnRpZXMoKS5rZXlTZXQoKSwgIkZvbyIpOworICAgICAgICAgICAgYXNzZXJ0Q29udGFpbnNBbGwoY29ubmVjdGlvbi5nZXRSZXF1ZXN0UHJvcGVydGllcygpLmtleVNldCgpLAorICAgICAgICAgICAgICAgICAgICAiQ29udGVudC1UeXBlIiwgIkNvbnRlbnQtTGVuZ3RoIiwgIlVzZXItQWdlbnQiLCAiQ29ubmVjdGlvbiIsICJIb3N0Iik7CisgICAgICAgICAgICBhc3NlcnRDb250YWluc0FsbChjb25uZWN0aW9uLmdldFJlcXVlc3RQcm9wZXJ0aWVzKCkua2V5U2V0KCksICJDb29raWUiLCAiQ29va2llMiIpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoY29ubmVjdGlvbi5nZXRSZXF1ZXN0UHJvcGVydGllcygpLmNvbnRhaW5zS2V5KCJRdXV4IikpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydENvbnRhaW5zQWxsKHJlcXVlc3QuZ2V0SGVhZGVycygpLCAiRm9vOiBmb28iLCAiQ29va2llOiBCYXI9YmFyIiwgIkNvb2tpZTI6IEJhej1iYXoiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVxdWVzdC5nZXRIZWFkZXJzKCkuY29udGFpbnMoIlF1dXg6IHF1dXgiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvb2tpZXNTZW50SWdub3Jlc0Nhc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ29va2llSGFuZGxlci5zZXREZWZhdWx0KG5ldyBDb29raWVNYW5hZ2VyKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IGdldChVUkkgdXJpLAorICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IHJlcXVlc3RIZWFkZXJzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gcmVzdWx0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+KCk7CisgICAgICAgICAgICAgICAgcmVzdWx0LnB1dCgiQ09PS0lFIiwgQ29sbGVjdGlvbnMuc2luZ2xldG9uTGlzdCgiQmFyPWJhciIpKTsKKyAgICAgICAgICAgICAgICByZXN1bHQucHV0KCJjb29LSUUyIiwgQ29sbGVjdGlvbnMuc2luZ2xldG9uTGlzdCgiQmF6PWJheiIpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAgICAgTW9ja1dlYlNlcnZlciBzZXJ2ZXIgPSBuZXcgTW9ja1dlYlNlcnZlcigpOworICAgICAgICBzZXJ2ZXIuIGVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBnZXQoc2VydmVyLCAiLyIpOworCisgICAgICAgIFJlY29yZGVkUmVxdWVzdCByZXF1ZXN0ID0gc2VydmVyLnRha2VSZXF1ZXN0KCk7CisgICAgICAgIGFzc2VydENvbnRhaW5zQWxsKHJlcXVlc3QuZ2V0SGVhZGVycygpLCAiQ09PS0lFOiBCYXI9YmFyIiwgImNvb0tJRTI6IEJhej1iYXoiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVxdWVzdC5nZXRIZWFkZXJzKCkuY29udGFpbnMoIlF1dXg6IHF1dXgiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUkZDIDIxMDkgYW5kIFJGQyAyOTY1IGRpc2FncmVlIGhlcmUuIDIxMDkgc2F5cyB0d28gZXF1YWxzIHN0cmluZ3MgbWF0Y2ggb25seSBpZiB0aGV5IGFyZQorICAgICAqIGZ1bGx5LXF1YWxpZmllZCBkb21haW4gbmFtZXMuIDI5NjUgc2F5cyB0d28gZXF1YWwgc3RyaW5ncyBhbHdheXMgbWF0Y2guIFdlJ3JlIHRlc3RpbmcgZm9yCisgICAgICogMjEwOSBiZWhhdmlvciBiZWNhdXNlIGl0J3MgbW9yZSB3aWRlbHkgdXNlZCwgaXQncyBtb3JlIGNvbnNlcnZhdGl2ZSwgYW5kIGl0J3Mgd2hhdCB0aGUgUkkKKyAgICAgKiBkb2VzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REb21haW5NYXRjaGVzT25Mb2NhbEFkZHJlc3NlcygpIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoSHR0cENvb2tpZS5kb21haW5NYXRjaGVzKCJsb2NhbGhvc3QiLCAibG9jYWxob3N0IikpOworICAgICAgICBhc3NlcnRGYWxzZShIdHRwQ29va2llLmRvbWFpbk1hdGNoZXMoImIiLCAiYiIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RG9tYWluTWF0Y2hlc09uSXBBZGRyZXNzKCkgeworICAgICAgICBhc3NlcnRUcnVlKEh0dHBDb29raWUuZG9tYWluTWF0Y2hlcygiMTI3LjAuMC4xIiwgIjEyNy4wLjAuMSIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoSHR0cENvb2tpZS5kb21haW5NYXRjaGVzKCIxMjcuMC4wLjEiLCAiMTI3LjAuMC4wIikpOworICAgICAgICBhc3NlcnRGYWxzZShIdHRwQ29va2llLmRvbWFpbk1hdGNoZXMoIjEyNy4wLjAuMSIsICJsb2NhbGhvc3QiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERvbWFpbk1hdGNoZXNDYXNlTWFwcGluZygpIHsKKyAgICAgICAgdGVzdERvbWFpbk1hdGNoZXNDYXNlTWFwcGluZyhMb2NhbGUuVVMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REb21haW5NYXRjaGVzQ2FzZU1hcHBpbmdFeG90aWNMb2NhbGUoKSB7CisgICAgICAgIHRlc3REb21haW5NYXRjaGVzQ2FzZU1hcHBpbmcobmV3IExvY2FsZSgidHIiLCAiVFIiKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3REb21haW5NYXRjaGVzQ2FzZU1hcHBpbmcoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBMb2NhbGUgZGVmYXVsdExvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KGxvY2FsZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKEh0dHBDb29raWUuZG9tYWluTWF0Y2hlcygiLmFuZHJvaWQuY29tIiwgIldXVy5BTkRST0lELkNPTSIpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKEh0dHBDb29raWUuZG9tYWluTWF0Y2hlcygiYW5kcm9pZC5jb20iLCAiV1dXLkFORFJPSUQuQ09NIikpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgTG9jYWxlLnNldERlZmF1bHQoZGVmYXVsdExvY2FsZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGcm9tIHRoZSBzcGVjLCAiSWYgYW4gZXhwbGljaXRseSBzcGVjaWZpZWQgdmFsdWUgZG9lcyBub3Qgc3RhcnQgd2l0aCBhIGRvdCwgdGhlIHVzZXIgYWdlbnQKKyAgICAgKiBzdXBwbGllcyBhIGxlYWRpbmcgZG90LiIuIFRoaXMgcHJlcGVuZGluZyBkb2Vzbid0IGhhcHBlbiBpbiBzZXREb21haW4uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdERvbWFpbk5vdEF1dG9tYXRpY2FsbHlQcmVmaXhlZFdpdGhEb3QoKSB7CisgICAgICAgIEh0dHBDb29raWUgY29va2llID0gbmV3IEh0dHBDb29raWUoIkZvbyIsICJmb28iKTsKKyAgICAgICAgY29va2llLnNldERvbWFpbigibG9jYWxob3N0Iik7CisgICAgICAgIGFzc2VydEVxdWFscygibG9jYWxob3N0IiwgY29va2llLmdldERvbWFpbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29va2llU3RvcmVOdWxsVXJpcygpIHsKKyAgICAgICAgQ29va2llU3RvcmUgY29va2llU3RvcmUgPSBuZXcgQ29va2llTWFuYWdlcigpLmdldENvb2tpZVN0b3JlKCk7CisgICAgICAgIEh0dHBDb29raWUgY29va2llQSA9IG5ldyBIdHRwQ29va2llKCJhIiwgImFuZHJvaWQiKTsKKyAgICAgICAgY29va2llQS5zZXREb21haW4oIi5hbmRyb2lkLmNvbSIpOworICAgICAgICBjb29raWVBLnNldFBhdGgoIi9zb3VyY2UiKTsKKyAgICAgICAgSHR0cENvb2tpZSBjb29raWVCID0gbmV3IEh0dHBDb29raWUoImIiLCAiYmFuYW5hIik7CisgICAgICAgIGNvb2tpZUEuc2V0RG9tYWluKCJjb2RlLmdvb2dsZS5jb20iKTsKKyAgICAgICAgY29va2llQS5zZXRQYXRoKCIvcC9hbmRyb2lkIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvb2tpZVN0b3JlLmFkZChudWxsLCBjb29raWVBKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIC8vIHRoZSBSSSBjcmFzaGVzIGV2ZW4gdGhvdWdoIHRoZSBjb29raWUgZG9lcyBnZXQgYWRkZWQgdG8gdGhlIHN0b3JlOyBzaWdoCisgICAgICAgICAgICBleHBlY3RlZC5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChjb29raWVBKSwgY29va2llU3RvcmUuZ2V0Q29va2llcygpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvb2tpZVN0b3JlLmFkZChudWxsLCBjb29raWVCKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChjb29raWVBLCBjb29raWVCKSwgY29va2llU3RvcmUuZ2V0Q29va2llcygpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29va2llU3RvcmUuZ2V0KG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENvbGxlY3Rpb25zLjxVUkk+ZW1wdHlMaXN0KCksIGNvb2tpZVN0b3JlLmdldFVSSXMoKSk7CisgICAgICAgIGFzc2VydFRydWUoY29va2llU3RvcmUucmVtb3ZlKG51bGwsIGNvb2tpZUEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoY29va2llQiksIGNvb2tpZVN0b3JlLmdldENvb2tpZXMoKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShjb29raWVTdG9yZS5yZW1vdmVBbGwoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb2xsZWN0aW9ucy48VVJJPmVtcHR5TGlzdCgpLCBjb29raWVTdG9yZS5nZXRVUklzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29sbGVjdGlvbnMuPEh0dHBDb29raWU+ZW1wdHlMaXN0KCksIGNvb2tpZVN0b3JlLmdldENvb2tpZXMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvb2tpZVN0b3JlUmVtb3ZlQWxsKCkgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIENvb2tpZVN0b3JlIGNvb2tpZVN0b3JlID0gbmV3IENvb2tpZU1hbmFnZXIoKS5nZXRDb29raWVTdG9yZSgpOworICAgICAgICBjb29raWVTdG9yZS5hZGQobmV3IFVSSSgiaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS8iKSwgbmV3IEh0dHBDb29raWUoImEiLCAiYW5kcm9pZCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjb29raWVTdG9yZS5yZW1vdmVBbGwoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb2xsZWN0aW9ucy48VVJJPmVtcHR5TGlzdCgpLCBjb29raWVTdG9yZS5nZXRVUklzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29sbGVjdGlvbnMuPEh0dHBDb29raWU+ZW1wdHlMaXN0KCksIGNvb2tpZVN0b3JlLmdldENvb2tpZXMoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJFeHBlY3RlZCByZW1vdmVBbGwoKSB0byByZXR1cm4gZmFsc2Ugd2hlbiB0aGUgY2FsbCBkb2Vzbid0IG11dGF0ZSB0aGUgc3RvcmUiLAorICAgICAgICAgICAgICAgIGNvb2tpZVN0b3JlLnJlbW92ZUFsbCgpKTsgIC8vIFJJNiBmYWlscyB0aGlzCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvb2tpZVN0b3JlQWRkQWNjZXB0c0NvbmZsaWN0aW5nVXJpKCkgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIENvb2tpZVN0b3JlIGNvb2tpZVN0b3JlID0gbmV3IENvb2tpZU1hbmFnZXIoKS5nZXRDb29raWVTdG9yZSgpOworICAgICAgICBIdHRwQ29va2llIGNvb2tpZUEgPSBuZXcgSHR0cENvb2tpZSgiYSIsICJhbmRyb2lkIik7CisgICAgICAgIGNvb2tpZUEuc2V0RG9tYWluKCIuYW5kcm9pZC5jb20iKTsKKyAgICAgICAgY29va2llQS5zZXRQYXRoKCIvc291cmNlLyIpOworICAgICAgICBjb29raWVTdG9yZS5hZGQobmV3IFVSSSgiaHR0cDovL2dvb2dsZS5jb20vc291cmNlLyIpLCBjb29raWVBKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoY29va2llQSksIGNvb2tpZVN0b3JlLmdldENvb2tpZXMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvb2tpZVN0b3JlUmVtb3ZlUmVxdWlyZXNVcmkoKSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgQ29va2llU3RvcmUgY29va2llU3RvcmUgPSBuZXcgQ29va2llTWFuYWdlcigpLmdldENvb2tpZVN0b3JlKCk7CisgICAgICAgIEh0dHBDb29raWUgY29va2llQSA9IG5ldyBIdHRwQ29va2llKCJhIiwgImFuZHJvaWQiKTsKKyAgICAgICAgY29va2llU3RvcmUuYWRkKG5ldyBVUkkoImh0dHA6Ly9hbmRyb2lkLmNvbS9zb3VyY2UvIiksIGNvb2tpZUEpOworICAgICAgICBhc3NlcnRGYWxzZSgiRXhwZWN0ZWQgcmVtb3ZlKCkgdG8gdGFrZSB0aGUgY29va2llIFVSSSBpbnRvIGFjY291bnQuIiwgLy8gUkk2IGZhaWxzIHRoaXMKKyAgICAgICAgICAgICAgICBjb29raWVTdG9yZS5yZW1vdmUobmV3IFVSSSgiaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS8iKSwgY29va2llQSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChjb29raWVBKSwgY29va2llU3RvcmUuZ2V0Q29va2llcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29va2llU3RvcmVVcmlVc2VzSHR0cFNjaGVtZUFsd2F5cygpIHRocm93cyBVUklTeW50YXhFeGNlcHRpb24geworICAgICAgICBDb29raWVTdG9yZSBjb29raWVTdG9yZSA9IG5ldyBDb29raWVNYW5hZ2VyKCkuZ2V0Q29va2llU3RvcmUoKTsKKyAgICAgICAgY29va2llU3RvcmUuYWRkKG5ldyBVUkkoImh0dHBzOi8vYS5jb20vIiksIG5ldyBIdHRwQ29va2llKCJhIiwgImFuZHJvaWQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KG5ldyBVUkkoImh0dHA6Ly9hLmNvbSIpKSwgY29va2llU3RvcmUuZ2V0VVJJcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29va2llU3RvcmVVcmlEcm9wc1VzZXJJbmZvKCkgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIENvb2tpZVN0b3JlIGNvb2tpZVN0b3JlID0gbmV3IENvb2tpZU1hbmFnZXIoKS5nZXRDb29raWVTdG9yZSgpOworICAgICAgICBjb29raWVTdG9yZS5hZGQobmV3IFVSSSgiaHR0cDovL2plc3NlOnNlY3JldEBhLmNvbS8iKSwgbmV3IEh0dHBDb29raWUoImEiLCAiYW5kcm9pZCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QobmV3IFVSSSgiaHR0cDovL2EuY29tIikpLCBjb29raWVTdG9yZS5nZXRVUklzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb29raWVTdG9yZVVyaUtlZXBzSG9zdCgpIHRocm93cyBVUklTeW50YXhFeGNlcHRpb24geworICAgICAgICBDb29raWVTdG9yZSBjb29raWVTdG9yZSA9IG5ldyBDb29raWVNYW5hZ2VyKCkuZ2V0Q29va2llU3RvcmUoKTsKKyAgICAgICAgY29va2llU3RvcmUuYWRkKG5ldyBVUkkoImh0dHA6Ly9iLmNvbS8iKSwgbmV3IEh0dHBDb29raWUoImEiLCAiYW5kcm9pZCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QobmV3IFVSSSgiaHR0cDovL2IuY29tIikpLCBjb29raWVTdG9yZS5nZXRVUklzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb29raWVTdG9yZVVyaURyb3BzUG9ydCgpIHRocm93cyBVUklTeW50YXhFeGNlcHRpb24geworICAgICAgICBDb29raWVTdG9yZSBjb29raWVTdG9yZSA9IG5ldyBDb29raWVNYW5hZ2VyKCkuZ2V0Q29va2llU3RvcmUoKTsKKyAgICAgICAgY29va2llU3RvcmUuYWRkKG5ldyBVUkkoImh0dHA6Ly9hLmNvbTo0NDMvIiksIG5ldyBIdHRwQ29va2llKCJhIiwgImFuZHJvaWQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KG5ldyBVUkkoImh0dHA6Ly9hLmNvbSIpKSwgY29va2llU3RvcmUuZ2V0VVJJcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29va2llU3RvcmVVcmlEcm9wc1BhdGgoKSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgQ29va2llU3RvcmUgY29va2llU3RvcmUgPSBuZXcgQ29va2llTWFuYWdlcigpLmdldENvb2tpZVN0b3JlKCk7CisgICAgICAgIGNvb2tpZVN0b3JlLmFkZChuZXcgVVJJKCJodHRwOi8vYS5jb20vYS8iKSwgbmV3IEh0dHBDb29raWUoImEiLCAiYW5kcm9pZCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QobmV3IFVSSSgiaHR0cDovL2EuY29tIikpLCBjb29raWVTdG9yZS5nZXRVUklzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb29raWVTdG9yZVVyaURyb3BzRnJhZ21lbnQoKSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgQ29va2llU3RvcmUgY29va2llU3RvcmUgPSBuZXcgQ29va2llTWFuYWdlcigpLmdldENvb2tpZVN0b3JlKCk7CisgICAgICAgIGNvb2tpZVN0b3JlLmFkZChuZXcgVVJJKCJodHRwOi8vYS5jb20vYS9mb28jZnJhZ21lbnQiKSwgbmV3IEh0dHBDb29raWUoImEiLCAiYW5kcm9pZCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QobmV3IFVSSSgiaHR0cDovL2EuY29tIikpLCBjb29raWVTdG9yZS5nZXRVUklzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb29raWVTdG9yZVVyaURyb3BzUXVlcnkoKSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgQ29va2llU3RvcmUgY29va2llU3RvcmUgPSBuZXcgQ29va2llTWFuYWdlcigpLmdldENvb2tpZVN0b3JlKCk7CisgICAgICAgIGNvb2tpZVN0b3JlLmFkZChuZXcgVVJJKCJodHRwOi8vYS5jb20vYS9mb28/cXVlcnk9dmFsdWUiKSwgbmV3IEh0dHBDb29raWUoImEiLCAiYW5kcm9pZCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QobmV3IFVSSSgiaHR0cDovL2EuY29tIikpLCBjb29raWVTdG9yZS5nZXRVUklzKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRDb250YWlucyhDb2xsZWN0aW9uPFN0cmluZz4gY29sbGVjdGlvbiwgU3RyaW5nIGVsZW1lbnQpIHsKKyAgICAgICAgZm9yIChTdHJpbmcgYyA6IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIGlmIChjICE9IG51bGwgJiYgYy5lcXVhbHNJZ25vcmVDYXNlKGVsZW1lbnQpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZhaWwoIk5vICIgKyBlbGVtZW50ICsgIiBpbiAiICsgY29sbGVjdGlvbik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydENvbnRhaW5zQWxsKENvbGxlY3Rpb248U3RyaW5nPiBjb2xsZWN0aW9uLCBTdHJpbmcuLi4gdG9GaW5kKSB7CisgICAgICAgIGZvciAoU3RyaW5nIHMgOiB0b0ZpbmQpIHsKKyAgICAgICAgICAgIGFzc2VydENvbnRhaW5zKGNvbGxlY3Rpb24sIHMpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBMaXN0PEh0dHBDb29raWU+IHNvcnRlZENvcHkoTGlzdDxIdHRwQ29va2llPiBjb29raWVzKSB7CisgICAgICAgIExpc3Q8SHR0cENvb2tpZT4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxIdHRwQ29va2llPihjb29raWVzKTsKKyAgICAgICAgQ29sbGVjdGlvbnMuc29ydChyZXN1bHQsIG5ldyBDb21wYXJhdG9yPEh0dHBDb29raWU+KCkgeworICAgICAgICAgICAgcHVibGljIGludCBjb21wYXJlKEh0dHBDb29raWUgYSwgSHR0cENvb2tpZSBiKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGEuZ2V0TmFtZSgpLmNvbXBhcmVUbyhiLmdldE5hbWUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgTWFwPFN0cmluZyxMaXN0PFN0cmluZz4+IGdldChNb2NrV2ViU2VydmVyIHNlcnZlciwgU3RyaW5nIHBhdGgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSBzZXJ2ZXIuZ2V0VXJsKHBhdGgpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gaGVhZGVycyA9IGNvbm5lY3Rpb24uZ2V0SGVhZGVyRmllbGRzKCk7CisgICAgICAgIGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKS5jbG9zZSgpOworICAgICAgICByZXR1cm4gaGVhZGVyczsKKyAgICB9CisKKyAgICBwcml2YXRlIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gY29va2llSGVhZGVycyhTdHJpbmcuLi4gaGVhZGVycykgeworICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuc2luZ2xldG9uTWFwKCJTZXQtQ29va2llIiwgQXJyYXlzLmFzTGlzdChoZWFkZXJzKSk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFRlc3RDb29raWVTdG9yZSBpbXBsZW1lbnRzIENvb2tpZVN0b3JlIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PEh0dHBDb29raWU+IGNvb2tpZXMgPSBuZXcgQXJyYXlMaXN0PEh0dHBDb29raWU+KCk7CisKKyAgICAgICAgcHVibGljIHZvaWQgYWRkKFVSSSB1cmksIEh0dHBDb29raWUgY29va2llKSB7CisgICAgICAgICAgICBjb29raWVzLmFkZChjb29raWUpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEh0dHBDb29raWUgZ2V0Q29va2llKFN0cmluZyBuYW1lKSB7CisgICAgICAgICAgICBmb3IgKEh0dHBDb29raWUgY29va2llIDogY29va2llcykgeworICAgICAgICAgICAgICAgIGlmIChjb29raWUuZ2V0TmFtZSgpLmVxdWFscyhuYW1lKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5vIGNvb2tpZSAiICsgbmFtZSArICIgaW4gIiArIGNvb2tpZXMpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIExpc3Q8SHR0cENvb2tpZT4gZ2V0KFVSSSB1cmkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIExpc3Q8SHR0cENvb2tpZT4gZ2V0Q29va2llcygpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIExpc3Q8VVJJPiBnZXRVUklzKCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoVVJJIHVyaSwgSHR0cENvb2tpZSBjb29raWUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlQWxsKCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9JRE5UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9JRE5UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjAxZWNhMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L0lETlRlc3QuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmV0OworCitpbXBvcnQgamF2YS5uZXQuSUROOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIElETlRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIG1ha2VQdW55U3RyaW5nKGludCB4Q291bnQpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgcy5hcHBlbmQoInhuLS1iY2hlciIpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHhDb3VudDsgKytpKSB7CisgICAgICAgICAgICBzLmFwcGVuZCgneCcpOworICAgICAgICB9CisgICAgICAgIHMuYXBwZW5kKCIta3ZhIik7CisgICAgICAgIHJldHVybiBzLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90b1VuaWNvZGVfZmFpbHVyZXMoKSB7CisgICAgICAgIC8vIFRoaXMgaXMgc2hvcnQgZW5vdWdoIHRvIHdvcmsuLi4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiXHUwMGZjY2hlciIsIElETi50b1VuaWNvZGUobWFrZVB1bnlTdHJpbmcoMCkpKTsKKyAgICAgICAgLy8gVGhpcyBpcyB0b28gbG9uZywgYW5kIHRoZSBSSSBqdXN0IHJldHVybnMgdGhlIGlucHV0IHN0cmluZy4uLgorICAgICAgICBTdHJpbmcgbG9uZ0lucHV0ID0gbWFrZVB1bnlTdHJpbmcoNTEyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxvbmdJbnB1dCwgSUROLnRvVW5pY29kZShsb25nSW5wdXQpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9JbmV0QWRkcmVzc1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L0luZXRBZGRyZXNzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2ZWE0NjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9JbmV0QWRkcmVzc1Rlc3QuamF2YQpAQCAtMCwwICsxLDI4MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5ldDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuSW5ldDRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LkluZXQ2QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5OZXR3b3JrSW50ZXJmYWNlOworaW1wb3J0IGphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCB0ZXN0cy51dGlsLlNlcmlhbGl6YXRpb25UZXN0ZXI7CisKK3B1YmxpYyBjbGFzcyBJbmV0QWRkcmVzc1Rlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBMT09QQkFDSzZfQllURVMgPSB7IDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIElOVkFMSURfSVB2NF9OVU1FUklDX0FERFJFU1NFUyA9IG5ldyBTdHJpbmdbXSB7CisgICAgICAgIC8vIElQdjQgYWRkcmVzc2VzIG1heSBub3QgYmUgc3Vycm91bmRlZCBieSBzcXVhcmUgYnJhY2tldHMuCisgICAgICAgICJbMTI3LjAuMC4xXSIsCisKKyAgICAgICAgLy8gVHJhaWxpbmcgZG90cyBhcmUgbm90IGFsbG93ZWQuCisgICAgICAgICIxLjIuMy40LiIsCisgICAgICAgIC8vIE5vciBpcyBhbnkga2luZCBvZiB0cmFpbGluZyBqdW5rLgorICAgICAgICAiMS4yLjMuNGhlbGxvIiwKKworICAgICAgICAvLyBPdXQgb2YgcmFuZ2UuCisgICAgICAgICIyNTYuMi4zLjQiLAorICAgICAgICAiMS4yNTYuMy40IiwKKyAgICAgICAgIjEuMi4yNTYuNCIsCisgICAgICAgICIxLjIuMy4yNTYiLAorCisgICAgICAgIC8vIERlcHJlY2F0ZWQuCisgICAgICAgICIxLjIuMyIsCisgICAgICAgICIxLjIiLAorICAgICAgICAiMSIsCisgICAgICAgICIxMjM0IiwKKyAgICAgICAgIjAiLCAvLyBTaW5nbGUgb3V0IHRoZSBkZXByZWNhdGVkIGZvcm0gb2YgdGhlIEFOWSBhZGRyZXNzLgorCisgICAgICAgIC8vIEhleC4KKyAgICAgICAgIjB4MS4weDIuMHgzLjB4NCIsCisgICAgICAgICIweDdmLjB4MDAuMHgwMC4weDAxIiwKKyAgICAgICAgIjdmLjAuMC4xIiwKKworICAgICAgICAvLyBPY3RhbC4KKyAgICAgICAgIjAxNzcuMDAuMDAuMDEiLCAvLyBIaXN0b3JpY2FsbHksIHRoaXMgd291bGQgaGF2ZSBiZWVuIGludGVycHJldGVkIGFzIDEyNy4wLjAuMS4KKworICAgICAgICAvLyBOZWdhdGl2ZSBudW1iZXJzLgorICAgICAgICAiLTEuMC4wLjEiLAorICAgICAgICAiMS4tMS4wLjEiLAorICAgICAgICAiMS4wLi0xLjEiLAorICAgICAgICAiMS4wLjAuLTEiLAorICAgIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBJbmV0NkFkZHJlc3MgbG9vcGJhY2s2KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiAoSW5ldDZBZGRyZXNzKSBJbmV0QWRkcmVzcy5nZXRCeUFkZHJlc3MoTE9PUEJBQ0s2X0JZVEVTKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBJbmV0NkFkZHJlc3MgbG9jYWxob3N0NigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICByZXR1cm4gKEluZXQ2QWRkcmVzcykgSW5ldEFkZHJlc3MuZ2V0QnlBZGRyZXNzKCJsb2NhbGhvc3QiLCBMT09QQkFDSzZfQllURVMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcGFyc2VOdW1lcmljQWRkcmVzcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBSZWd1bGFyIElQdjQuCisgICAgICAgIGFzc2VydEVxdWFscygiLzEuMi4zLjQiLCBJbmV0QWRkcmVzcy5wYXJzZU51bWVyaWNBZGRyZXNzKCIxLjIuMy40IikudG9TdHJpbmcoKSk7CisgICAgICAgIC8vIFJlZ3VsYXIgSVB2Ni4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvMjAwMTo0ODYwOjgwMGQ6OjY4IiwgSW5ldEFkZHJlc3MucGFyc2VOdW1lcmljQWRkcmVzcygiMjAwMTo0ODYwOjgwMGQ6OjY4IikudG9TdHJpbmcoKSk7CisgICAgICAgIC8vIE9wdGlvbmFsIHNxdWFyZSBicmFja2V0cyBhcm91bmQgSVB2NiBhZGRyZXNzZXMsIGluY2x1ZGluZyBtYXBwZWQgSVB2NC4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvMjAwMTo0ODYwOjgwMGQ6OjY4IiwgSW5ldEFkZHJlc3MucGFyc2VOdW1lcmljQWRkcmVzcygiWzIwMDE6NDg2MDo4MDBkOjo2OF0iKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvMTI3LjAuMC4xIiwgSW5ldEFkZHJlc3MucGFyc2VOdW1lcmljQWRkcmVzcygiWzo6ZmZmZjoxMjcuMC4wLjFdIikudG9TdHJpbmcoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEluZXRBZGRyZXNzLnBhcnNlTnVtZXJpY0FkZHJlc3MoImV4YW1wbGUuY29tIik7IC8vIE5vdCBudW1lcmljLgorICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoU3RyaW5nIGludmFsaWQgOiBJTlZBTElEX0lQdjRfTlVNRVJJQ19BRERSRVNTRVMpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MucGFyc2VOdW1lcmljQWRkcmVzcyhpbnZhbGlkKTsKKyAgICAgICAgICAgICAgICBmYWlsKGludmFsaWQpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBTdHJhbmdlIHNwZWNpYWwgY2FzZXMsIGZvciBjb21wYXRpYmlsaXR5IHdpdGggSW5ldEFkZHJlc3MuZ2V0QnlOYW1lLgorICAgICAgICBhc3NlcnRUcnVlKEluZXRBZGRyZXNzLnBhcnNlTnVtZXJpY0FkZHJlc3MobnVsbCkuaXNMb29wYmFja0FkZHJlc3MoKSk7CisgICAgICAgIGFzc2VydFRydWUoSW5ldEFkZHJlc3MucGFyc2VOdW1lcmljQWRkcmVzcygiIikuaXNMb29wYmFja0FkZHJlc3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc051bWVyaWMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShJbmV0QWRkcmVzcy5pc051bWVyaWMoIjEuMi4zLjQiKSk7CisgICAgICAgIGFzc2VydFRydWUoSW5ldEFkZHJlc3MuaXNOdW1lcmljKCIxMjcuMC4wLjEiKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoSW5ldEFkZHJlc3MuaXNOdW1lcmljKCJleGFtcGxlLmNvbSIpKTsKKworICAgICAgICBmb3IgKFN0cmluZyBpbnZhbGlkIDogSU5WQUxJRF9JUHY0X05VTUVSSUNfQUREUkVTU0VTKSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShpbnZhbGlkLCBJbmV0QWRkcmVzcy5pc051bWVyaWMoaW52YWxpZCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0xpbmtMb2NhbEFkZHJlc3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoSW5ldEFkZHJlc3MuZ2V0QnlOYW1lKCIxMjcuMC4wLjEiKS5pc0xpbmtMb2NhbEFkZHJlc3MoKSk7CisgICAgICAgIGFzc2VydFRydWUoSW5ldEFkZHJlc3MuZ2V0QnlOYW1lKCIxNjkuMjU0LjEuMiIpLmlzTGlua0xvY2FsQWRkcmVzcygpKTsKKworICAgICAgICBhc3NlcnRGYWxzZShJbmV0QWRkcmVzcy5nZXRCeU5hbWUoImZlYzA6OiIpLmlzTGlua0xvY2FsQWRkcmVzcygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShJbmV0QWRkcmVzcy5nZXRCeU5hbWUoImZlODA6OiIpLmlzTGlua0xvY2FsQWRkcmVzcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzTUNTaXRlTG9jYWxBZGRyZXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKEluZXRBZGRyZXNzLmdldEJ5TmFtZSgiMjM5LjI1NC4yNTUuMjU1IikuaXNNQ1NpdGVMb2NhbCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShJbmV0QWRkcmVzcy5nZXRCeU5hbWUoIjIzOS4yNTUuMC4wIikuaXNNQ1NpdGVMb2NhbCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShJbmV0QWRkcmVzcy5nZXRCeU5hbWUoIjIzOS4yNTUuMjU1LjI1NSIpLmlzTUNTaXRlTG9jYWwoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKEluZXRBZGRyZXNzLmdldEJ5TmFtZSgiMjQwLjAuMC4wIikuaXNNQ1NpdGVMb2NhbCgpKTsKKworICAgICAgICBhc3NlcnRGYWxzZShJbmV0QWRkcmVzcy5nZXRCeU5hbWUoImZmMDY6OiIpLmlzTUNTaXRlTG9jYWwoKSk7CisgICAgICAgIGFzc2VydFRydWUoSW5ldEFkZHJlc3MuZ2V0QnlOYW1lKCJmZjA1OjoiKS5pc01DU2l0ZUxvY2FsKCkpOworICAgICAgICBhc3NlcnRUcnVlKEluZXRBZGRyZXNzLmdldEJ5TmFtZSgiZmYxNTo6IikuaXNNQ1NpdGVMb2NhbCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzUmVhY2hhYmxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9MjAyMDMKKyAgICAgICAgSW5ldEFkZHJlc3MgYWRkciA9IFNlcmlhbGl6YXRpb25UZXN0ZXIuZ2V0RGVzZXJpYWxpemVkT2JqZWN0KEluZXRBZGRyZXNzLmdldEJ5TmFtZSgid3d3Lmdvb2dsZS5jb20iKSk7CisgICAgICAgIGFkZHIuaXNSZWFjaGFibGUoNTAwKTsKKyAgICAgICAgZm9yIChOZXR3b3JrSW50ZXJmYWNlIG5pZiA6IENvbGxlY3Rpb25zLmxpc3QoTmV0d29ya0ludGVyZmFjZS5nZXROZXR3b3JrSW50ZXJmYWNlcygpKSkgeworICAgICAgICAgICAgYWRkci5pc1JlYWNoYWJsZShuaWYsIDIwLCA1MDApOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc1NpdGVMb2NhbEFkZHJlc3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoSW5ldEFkZHJlc3MuZ2V0QnlOYW1lKCIxNDQuMzIuMzIuMSIpLmlzU2l0ZUxvY2FsQWRkcmVzcygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShJbmV0QWRkcmVzcy5nZXRCeU5hbWUoIjEwLjAuMC4xIikuaXNTaXRlTG9jYWxBZGRyZXNzKCkpOworICAgICAgICBhc3NlcnRUcnVlKEluZXRBZGRyZXNzLmdldEJ5TmFtZSgiMTcyLjE2LjAuMSIpLmlzU2l0ZUxvY2FsQWRkcmVzcygpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoSW5ldEFkZHJlc3MuZ2V0QnlOYW1lKCIxNzIuMzIuMC4xIikuaXNTaXRlTG9jYWxBZGRyZXNzKCkpOworICAgICAgICBhc3NlcnRUcnVlKEluZXRBZGRyZXNzLmdldEJ5TmFtZSgiMTkyLjE2OC4wLjEiKS5pc1NpdGVMb2NhbEFkZHJlc3MoKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoSW5ldEFkZHJlc3MuZ2V0QnlOYW1lKCJmYzAwOjoiKS5pc1NpdGVMb2NhbEFkZHJlc3MoKSk7CisgICAgICAgIGFzc2VydFRydWUoSW5ldEFkZHJlc3MuZ2V0QnlOYW1lKCJmZWMwOjoiKS5pc1NpdGVMb2NhbEFkZHJlc3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRCeU5hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChTdHJpbmcgaW52YWxpZCA6IElOVkFMSURfSVB2NF9OVU1FUklDX0FERFJFU1NFUykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcy5nZXRCeU5hbWUoaW52YWxpZCk7CisgICAgICAgICAgICAgICAgZmFpbChpbnZhbGlkKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFVua25vd25Ib3N0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldExvb3BiYWNrQWRkcmVzcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKEluZXRBZGRyZXNzLmdldExvb3BiYWNrQWRkcmVzcygpLmlzTG9vcGJhY2tBZGRyZXNzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEluZXRBZGRyZXNzIGFkZHIgPSBJbmV0QWRkcmVzcy5nZXRCeU5hbWUoIjIzOS4xOTEuMjU1LjI1NSIpOworICAgICAgICBhc3NlcnRUcnVlKGFkZHIuZXF1YWxzKGFkZHIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShsb29wYmFjazYoKS5lcXVhbHMobG9jYWxob3N0NigpKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGFkZHIuZXF1YWxzKGxvb3BiYWNrNigpKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShJbmV0NEFkZHJlc3MuTE9PUEJBQ0suZXF1YWxzKEluZXQ0QWRkcmVzcy5MT09QQkFDSykpOworCisgICAgICAgIC8vIGh0dHA6Ly9iLzQzMjgyOTQgLSB0aGUgc2NvcGUgaWQgaXNuJ3QgaW5jbHVkZWQgd2hlbiBjb21wYXJpbmcgSW5ldDZBZGRyZXNzIGluc3RhbmNlcy4KKyAgICAgICAgYnl0ZVtdIGJzID0gbmV3IGJ5dGVbMTZdOworICAgICAgICBhc3NlcnRFcXVhbHMoSW5ldDZBZGRyZXNzLmdldEJ5QWRkcmVzcygiMSIsIGJzLCAxKSwgSW5ldDZBZGRyZXNzLmdldEJ5QWRkcmVzcygiMiIsIGJzLCAyKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRIb3N0QWRkcmVzcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoIjo6MSIsIGxvY2FsaG9zdDYoKS5nZXRIb3N0QWRkcmVzcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI6OjEiLCBJbmV0QWRkcmVzcy5nZXRCeU5hbWUoIjo6MSIpLmdldEhvc3RBZGRyZXNzKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiMTI3LjAuMC4xIiwgSW5ldDRBZGRyZXNzLkxPT1BCQUNLLmdldEhvc3RBZGRyZXNzKCkpOworCisgICAgICAgIEluZXRBZGRyZXNzIGFBZGRyID0gSW5ldEFkZHJlc3MuZ2V0QnlOYW1lKCIyMjQuMC4wLjAiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIyMjQuMC4wLjAiLCBhQWRkci5nZXRIb3N0QWRkcmVzcygpKTsKKworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbmV0QWRkcmVzcy5nZXRCeU5hbWUoIjEiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGVbXSBiQWRkciA9IHsKKyAgICAgICAgICAgIChieXRlKSAweEZFLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MTEsIChieXRlKSAweDI1LCAoYnl0ZSkgMHhGRiwKKyAgICAgICAgICAgIChieXRlKSAweEZFLCAoYnl0ZSkgMHhGOCwgKGJ5dGUpIDB4N0MsIChieXRlKSAweEIyCisgICAgICAgIH07CisgICAgICAgIGFBZGRyID0gSW5ldDZBZGRyZXNzLmdldEJ5QWRkcmVzcyhiQWRkcik7CisgICAgICAgIFN0cmluZyBhU3RyaW5nID0gYUFkZHIuZ2V0SG9zdEFkZHJlc3MoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhU3RyaW5nLmVxdWFscygiZmU4MDowOjA6MDoyMTE6MjVmZjpmZWY4OjdjYjIiKSB8fCBhU3RyaW5nLmVxdWFscygiZmU4MDo6MjExOjI1ZmY6ZmVmODo3Y2IyIikpOworCisgICAgICAgIGJ5dGVbXSBjQWRkciA9IHsKKyAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLAorICAgICAgICAgICAgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsCisgICAgICAgICAgICAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwKKyAgICAgICAgICAgIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZGCisgICAgICAgIH07CisgICAgICAgIGFBZGRyID0gSW5ldDZBZGRyZXNzLmdldEJ5QWRkcmVzcyhjQWRkcik7CisgICAgICAgIGFzc2VydEVxdWFscygiZmZmZjpmZmZmOmZmZmY6ZmZmZjpmZmZmOmZmZmY6ZmZmZjpmZmZmIiwgYUFkZHIuZ2V0SG9zdEFkZHJlc3MoKSk7CisKKyAgICAgICAgYnl0ZVtdIGRBZGRyID0geworICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwKKyAgICAgICAgICAgIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAKKyAgICAgICAgfTsKKyAgICAgICAgYUFkZHIgPSBJbmV0NkFkZHJlc3MuZ2V0QnlBZGRyZXNzKGRBZGRyKTsKKyAgICAgICAgYVN0cmluZyA9IGFBZGRyLmdldEhvc3RBZGRyZXNzKCk7CisgICAgICAgIGFzc2VydFRydWUoYVN0cmluZy5lcXVhbHMoIjA6MDowOjA6MDowOjA6MCIpIHx8IGFTdHJpbmcuZXF1YWxzKCI6OiIpKTsKKworICAgICAgICBieXRlW10gZUFkZHIgPSB7CisgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwMywKKyAgICAgICAgICAgIChieXRlKSAweDA0LCAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4MDYsIChieXRlKSAweDA3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDgsIChieXRlKSAweDA5LCAoYnl0ZSkgMHgwYSwgKGJ5dGUpIDB4MGIsCisgICAgICAgICAgICAoYnl0ZSkgMHgwYywgKGJ5dGUpIDB4MGQsIChieXRlKSAweDBlLCAoYnl0ZSkgMHgwZgorICAgICAgICB9OworICAgICAgICBhQWRkciA9IEluZXQ2QWRkcmVzcy5nZXRCeUFkZHJlc3MoZUFkZHIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjE6MjAzOjQwNTo2MDc6ODA5OmEwYjpjMGQ6ZTBmIiwgYUFkZHIuZ2V0SG9zdEFkZHJlc3MoKSk7CisKKyAgICAgICAgYnl0ZVtdIGZBZGRyID0geworICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDEwLCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4MzAsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NTAsIChieXRlKSAweDYwLCAoYnl0ZSkgMHg3MCwKKyAgICAgICAgICAgIChieXRlKSAweDgwLCAoYnl0ZSkgMHg5MCwgKGJ5dGUpIDB4YTAsIChieXRlKSAweGIwLAorICAgICAgICAgICAgKGJ5dGUpIDB4YzAsIChieXRlKSAweGQwLCAoYnl0ZSkgMHhlMCwgKGJ5dGUpIDB4ZjAKKyAgICAgICAgfTsKKyAgICAgICAgYUFkZHIgPSBJbmV0NkFkZHJlc3MuZ2V0QnlBZGRyZXNzKGZBZGRyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMDoyMDMwOjQwNTA6NjA3MDo4MDkwOmEwYjA6YzBkMDplMGYwIiwgYUFkZHIuZ2V0SG9zdEFkZHJlc3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBJbmV0QWRkcmVzcyBhZGRyMSA9IEluZXRBZGRyZXNzLmdldEJ5TmFtZSgiMS4wLjAuMSIpOworICAgICAgICBJbmV0QWRkcmVzcyBhZGRyMiA9IEluZXRBZGRyZXNzLmdldEJ5TmFtZSgiMS4wLjAuMSIpOworICAgICAgICBhc3NlcnRUcnVlKGFkZHIxLmhhc2hDb2RlKCkgPT0gYWRkcjIuaGFzaENvZGUoKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShsb29wYmFjazYoKS5oYXNoQ29kZSgpID09IGxvY2FsaG9zdDYoKS5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB2YWxpZElQQWRkcmVzc2VzW10gPSB7CisgICAgICAgICAgICAiOjoxLjIuMy40IiwgIjo6IiwgIjo6IiwgIjE6OjAiLCAiMTo6IiwgIjo6MSIsCisgICAgICAgICAgICAiRkZGRjpGRkZGOkZGRkY6RkZGRjpGRkZGOkZGRkY6RkZGRjpGRkZGIiwKKyAgICAgICAgICAgICJGRkZGOkZGRkY6RkZGRjpGRkZGOkZGRkY6RkZGRjoyNTUuMjU1LjI1NS4yNTUiLAorICAgICAgICAgICAgIjA6MDowOjA6MDowOjA6MCIsICIwOjA6MDowOjA6MDowLjAuMC4wIgorICAgICAgICB9OworCisgICAgICAgIFN0cmluZyBbXSByZXN1bHRTdHJpbmdzID0geworICAgICAgICAgICAgIi86OjEuMi4zLjQiLCAiLzo6IiwgIi86OiIsICIvMTo6IiwgIi8xOjoiLCAiLzo6MSIsCisgICAgICAgICAgICAiL2ZmZmY6ZmZmZjpmZmZmOmZmZmY6ZmZmZjpmZmZmOmZmZmY6ZmZmZiIsCisgICAgICAgICAgICAiL2ZmZmY6ZmZmZjpmZmZmOmZmZmY6ZmZmZjpmZmZmOmZmZmY6ZmZmZiIsICIvOjoiLAorICAgICAgICAgICAgIi86OiIKKyAgICAgICAgfTsKKworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgdmFsaWRJUEFkZHJlc3Nlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgSW5ldEFkZHJlc3MgaWEgPSBJbmV0QWRkcmVzcy5nZXRCeU5hbWUodmFsaWRJUEFkZHJlc3Nlc1tpXSk7CisgICAgICAgICAgICBTdHJpbmcgcmVzdWx0ID0gaWEudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocmVzdWx0KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHRTdHJpbmdzW2ldLCByZXN1bHQpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvSW5ldFNvY2tldEFkZHJlc3NUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9JbmV0U29ja2V0QWRkcmVzc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xY2JjZDFhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvSW5ldFNvY2tldEFkZHJlc3NUZXN0LmphdmEKQEAgLTAsMCArMSwxNTkgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5ldDsKKworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIEluZXRTb2NrZXRBZGRyZXNzVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmdJKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoIjEyNy4wLjAuMSIsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBJbmV0U29ja2V0QWRkcmVzcygiMTI3LjAuMC4xIiwgNjU1MzYpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMSW5ldEFkZHJlc3NJKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIHZhbGlkSVBBZGRyZXNzZXMgPSB7CisgICAgICAgICAgICAiOjoxLjIuMy40IiwKKyAgICAgICAgICAgICI6OiIsICI6OiIsCisgICAgICAgICAgICAiMTo6MCIsICIxOjoiLCAiOjoxIiwKKyAgICAgICAgICAgICJGRkZGOkZGRkY6RkZGRjpGRkZGOkZGRkY6RkZGRjpGRkZGOkZGRkYiLAorICAgICAgICAgICAgIkZGRkY6RkZGRjpGRkZGOkZGRkY6RkZGRjpGRkZGOjI1NS4yNTUuMjU1LjI1NSIsCisgICAgICAgICAgICAiMDowOjA6MDowOjA6MDowIiwgIjA6MDowOjA6MDowOjAuMC4wLjAiLAorICAgICAgICAgICAgIjEyNy4wLjAuMSIsICJsb2NhbGhvc3QiLCAiNDIuNDIuNDIuNDIiLCAiMC4wLjAuMCIKKyAgICAgICAgfTsKKworICAgICAgICBTdHJpbmdbXSByZXN1bHRzID0geworICAgICAgICAgICAgIjA6MDowOjA6MDowOjEwMjozMDQiLAorICAgICAgICAgICAgIjA6MDowOjA6MDowOjA6MCIsICIwOjA6MDowOjA6MDowOjAiLAorICAgICAgICAgICAgIjE6MDowOjA6MDowOjA6MCIsICIxOjA6MDowOjA6MDowOjAiLCAiMDowOjA6MDowOjA6MDoxIiwKKyAgICAgICAgICAgICJmZmZmOmZmZmY6ZmZmZjpmZmZmOmZmZmY6ZmZmZjpmZmZmOmZmZmYiLAorICAgICAgICAgICAgImZmZmY6ZmZmZjpmZmZmOmZmZmY6ZmZmZjpmZmZmOmZmZmY6ZmZmZiIsCisgICAgICAgICAgICAiMDowOjA6MDowOjA6MDowIiwgIjA6MDowOjA6MDowOjA6MCIsCisgICAgICAgICAgICAibG9jYWxob3N0IiwgImxvY2FsaG9zdCIsICI0Mi40Mi40Mi40MiIsICIwLjAuMC4wIgorICAgICAgICB9OworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRJUEFkZHJlc3Nlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgSW5ldEFkZHJlc3MgaWEgPSBJbmV0QWRkcmVzcy5nZXRCeU5hbWUodmFsaWRJUEFkZHJlc3Nlc1tpXSk7CisgICAgICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBpc2EgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoaWEsIDgwKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyg4MCxpc2EuZ2V0UG9ydCgpKTsKKyAgICAgICAgICAgIC8vYXNzZXJ0RXF1YWxzKHJlc3VsdHNbaV0sIGlzYS5nZXRIb3N0TmFtZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIGlzYSA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcygoSW5ldEFkZHJlc3MpbnVsbCwgODApOworICAgICAgICBhc3NlcnRFcXVhbHMoIjAuMC4wLjAiLCBpc2EuZ2V0SG9zdE5hbWUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcy5nZXRCeU5hbWUoImxvY2FsaG9zdCIpLCA2NTUzNik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzLmdldEJ5TmFtZSgibG9jYWxob3N0IiksIC0xKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySSgpIHsKKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgaXNhID0gbmV3ICBJbmV0U29ja2V0QWRkcmVzcyg2NTUzNSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMC4wLjAuMCIsIGlzYS5nZXRIb3N0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDY1NTM1LCBpc2EuZ2V0UG9ydCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3ICBJbmV0U29ja2V0QWRkcmVzcygtMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAgZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgIEluZXRTb2NrZXRBZGRyZXNzKDY1NTM2KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9lcXVhbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgaXNhMSA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcygxKTsKKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgaXNhMiA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcygyKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoaXNhMS5lcXVhbHMoaXNhMikpOworICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBpc2EzID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKDEpOworICAgICAgICBhc3NlcnRUcnVlKGlzYTEuZXF1YWxzKGlzYTMpKTsKKworICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbGhvc3QgPSBJbmV0QWRkcmVzcy5nZXRCeU5hbWUoImxvY2FsaG9zdCIpOworICAgICAgICBpc2ExID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKGxvY2FsaG9zdC5nZXRIb3N0TmFtZSgpLCA4MCk7CisgICAgICAgIGlzYTIgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MobG9jYWxob3N0LmdldEhvc3RBZGRyZXNzKCksIDgwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShpc2ExLmVxdWFscyhpc2EyKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBZGRyZXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIHZhbGlkSVBBZGRyZXNzZXMgPSB7CisgICAgICAgICAgICAiOjoxLjIuMy40IiwgIjo6IiwgIjo6IiwgIjE6OjAiLCAiMTo6IiwgIjo6MSIsCisgICAgICAgICAgICAiRkZGRjpGRkZGOkZGRkY6RkZGRjpGRkZGOkZGRkY6RkZGRjpGRkZGIiwKKyAgICAgICAgICAgICJGRkZGOkZGRkY6RkZGRjpGRkZGOkZGRkY6RkZGRjoyNTUuMjU1LjI1NS4yNTUiLAorICAgICAgICAgICAgIjA6MDowOjA6MDowOjA6MCIsICIwOjA6MDowOjA6MDowLjAuMC4wIiwKKyAgICAgICAgICAgICIxMjcuMC4wLjEiLCAibG9jYWxob3N0IiwgIjQyLjQyLjQyLjQyIiwgIjAuMC4wLjAiCisgICAgICAgIH07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRJUEFkZHJlc3Nlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgSW5ldEFkZHJlc3MgaWEgPSBJbmV0QWRkcmVzcy5nZXRCeU5hbWUodmFsaWRJUEFkZHJlc3Nlc1tpXSk7CisgICAgICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBpc2EgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoaWEsIDApOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGlhLCBpc2EuZ2V0QWRkcmVzcygpKTsKKyAgICAgICAgfQorICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBpc2EgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoKEluZXRBZGRyZXNzKSBudWxsLCAwKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChpc2EuZ2V0QWRkcmVzcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc2hDb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEluZXRBZGRyZXNzIGxvY2FsaG9zdCA9IEluZXRBZGRyZXNzLmdldEJ5TmFtZSgibG9jYWxob3N0Iik7CisgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIGlzYTEgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MobG9jYWxob3N0LmdldEhvc3ROYW1lKCksIDgwODApOworICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBpc2EyID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKGxvY2FsaG9zdC5nZXRIb3N0QWRkcmVzcygpLCA4MDgwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShpc2ExLmhhc2hDb2RlKCkgPT0gaXNhMi5oYXNoQ29kZSgpKTsKKworICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBpc2EzID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKCIwLjAuMC4wIiwgODA4MCk7CisgICAgICAgIGFzc2VydEZhbHNlKGlzYTEuaGFzaENvZGUoKSA9PSBpc2EzLmhhc2hDb2RlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNVbnJlc29sdmVkKCkgeworICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBpc2ExID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKCJsb2NhbGhvc3QiLCA4MCk7CisgICAgICAgIGFzc2VydEZhbHNlKGlzYTEuaXNVbnJlc29sdmVkKCkpOworCisgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIHNvY2tBZGRyID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKCJ1bmtub3duLmhvc3QiLCAxMDAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzb2NrQWRkci5pc1VucmVzb2x2ZWQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRIb3N0U3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFdoZW4gd2UgaGF2ZSBhIGhvc3RuYW1lLCB3ZSdsbCBnZXQgaXQgYmFjayBiZWNhdXNlIHRoYXQgZG9lc24ndCBjb3N0IGEgRE5TIGxvb2t1cC4uLgorICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBoYXNIb3N0bmFtZSA9IEluZXRTb2NrZXRBZGRyZXNzLmNyZWF0ZVVucmVzb2x2ZWQoInNvbWUgaG9zdCIsIDEyMzQpOworICAgICAgICBhc3NlcnRFcXVhbHMoInNvbWUgaG9zdCIsIGhhc0hvc3RuYW1lLmdldEhvc3RTdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygic29tZSBob3N0IiwgaGFzSG9zdG5hbWUuZ2V0SG9zdE5hbWUoKSk7CisgICAgICAgIC8vIFdoZW4gd2UgZG9uJ3QgaGF2ZSBhIGhvc3RuYW1lLCB3aGV0aGVyIG9yIG5vdCB3ZSBkbyB0aGUgcmV2ZXJzZSBsb29rdXAgaXMgdGhlIGRpZmZlcmVuY2UKKyAgICAgICAgLy8gYmV0d2VlbiBnZXRIb3N0U3RyaW5nIGFuZCBnZXRIb3N0TmFtZS4uLgorICAgICAgICBJbmV0QWRkcmVzcyBhZGRyZXNzID0gSW5ldEFkZHJlc3MuZ2V0QnlBZGRyZXNzKG5ldyBieXRlW10geyAxMjcsIDAsIDAsIDEgfSk7CisgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIG5vSG9zdG5hbWUgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoYWRkcmVzcywgMTIzNCk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTI3LjAuMC4xIiwgbm9Ib3N0bmFtZS5nZXRIb3N0U3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImxvY2FsaG9zdCIsIG5vSG9zdG5hbWUuZ2V0SG9zdE5hbWUoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvTmV0d29ya0ludGVyZmFjZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L05ldHdvcmtJbnRlcmZhY2VUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmRkZTY0NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L05ldHdvcmtJbnRlcmZhY2VUZXN0LmphdmEKQEAgLTAsMCArMSw5OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5ldDsKKworaW1wb3J0IGphdmEubmV0Lio7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBOZXR3b3JrSW50ZXJmYWNlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTEzNzg0CisgICAgcHVibGljIHZvaWQgdGVzdElQdjYoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTmV0d29ya0ludGVyZmFjZSBsbyA9IE5ldHdvcmtJbnRlcmZhY2UuZ2V0QnlOYW1lKCJsbyIpOworICAgICAgICBTZXQ8SW5ldEFkZHJlc3M+IGFjdHVhbCA9IG5ldyBIYXNoU2V0PEluZXRBZGRyZXNzPihDb2xsZWN0aW9ucy5saXN0KGxvLmdldEluZXRBZGRyZXNzZXMoKSkpOworCisgICAgICAgIFNldDxJbmV0QWRkcmVzcz4gZXhwZWN0ZWQgPSBuZXcgSGFzaFNldDxJbmV0QWRkcmVzcz4oKTsKKyAgICAgICAgZXhwZWN0ZWQuYWRkKEluZXQ0QWRkcmVzcy5MT09QQkFDSyk7CisgICAgICAgIGV4cGVjdGVkLmFkZChJbmV0NkFkZHJlc3MuZ2V0QnlBZGRyZXNzKCJsb2NhbGhvc3QiLCBuZXcgYnl0ZVtdIHsgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSB9LCBudWxsKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RMb29wYmFjaygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBXZSBrbm93IGxvIHNob3VsZG4ndCBoYXZlIGEgaGFyZHdhcmUgYWRkcmVzcyBvciBhbiBJUHY0IGJyb2FkY2FzdCBhZGRyZXNzLgorICAgICAgICBOZXR3b3JrSW50ZXJmYWNlIGxvID0gTmV0d29ya0ludGVyZmFjZS5nZXRCeU5hbWUoImxvIik7CisgICAgICAgIGFzc2VydE51bGwobG8uZ2V0SGFyZHdhcmVBZGRyZXNzKCkpOworICAgICAgICBmb3IgKEludGVyZmFjZUFkZHJlc3MgaWEgOiBsby5nZXRJbnRlcmZhY2VBZGRyZXNzZXMoKSkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbChpYS5nZXRCcm9hZGNhc3QoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBCdXQgZXRoMCwgaWYgaXQgZXhpc3RzLCBzaG91bGQuLi4KKyAgICAgICAgTmV0d29ya0ludGVyZmFjZSBldGgwID0gTmV0d29ya0ludGVyZmFjZS5nZXRCeU5hbWUoImV0aDAiKTsKKyAgICAgICAgaWYgKGV0aDAgIT0gbnVsbCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDYsIGV0aDAuZ2V0SGFyZHdhcmVBZGRyZXNzKCkubGVuZ3RoKTsKKyAgICAgICAgICAgIGZvciAoSW50ZXJmYWNlQWRkcmVzcyBpYSA6IGV0aDAuZ2V0SW50ZXJmYWNlQWRkcmVzc2VzKCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoaWEuZ2V0QWRkcmVzcygpIGluc3RhbmNlb2YgSW5ldDRBZGRyZXNzKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoaWEuZ2V0QnJvYWRjYXN0KCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REdW1wQWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNldDxTdHJpbmc+IGFsbE5hbWVzID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgICBTZXQ8SW50ZWdlcj4gYWxsSW5kZXhlcyA9IG5ldyBIYXNoU2V0PEludGVnZXI+KCk7CisgICAgICAgIGZvciAoTmV0d29ya0ludGVyZmFjZSBuaWYgOiBDb2xsZWN0aW9ucy5saXN0KE5ldHdvcmtJbnRlcmZhY2UuZ2V0TmV0d29ya0ludGVyZmFjZXMoKSkpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihuaWYpOworICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG5pZi5nZXRJbnRlcmZhY2VBZGRyZXNzZXMoKSk7CisgICAgICAgICAgICBTdHJpbmcgZmxhZ3MgPSBuaWYuaXNVcCgpID8gIlVQIiA6ICJET1dOIjsKKyAgICAgICAgICAgIGlmIChuaWYuaXNMb29wYmFjaygpKSB7CisgICAgICAgICAgICAgICAgZmxhZ3MgKz0gIiBMT09QQkFDSyI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobmlmLmlzUG9pbnRUb1BvaW50KCkpIHsKKyAgICAgICAgICAgICAgICBmbGFncyArPSAiIFBUUCI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobmlmLmlzVmlydHVhbCgpKSB7CisgICAgICAgICAgICAgICAgZmxhZ3MgKz0gIiBWSVJUVUFMIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChuaWYuc3VwcG9ydHNNdWx0aWNhc3QoKSkgeworICAgICAgICAgICAgICAgIGZsYWdzICs9ICIgTVVMVElDQVNUIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZsYWdzICs9ICIgTVRVPSIgKyBuaWYuZ2V0TVRVKCk7CisgICAgICAgICAgICBieXRlW10gbWFjID0gbmlmLmdldEhhcmR3YXJlQWRkcmVzcygpOworICAgICAgICAgICAgaWYgKG1hYyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZmxhZ3MgKz0gIiBIV0FERFI9IjsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1hYy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgICAgICAgICBpZiAoaSA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZsYWdzICs9ICI6IjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBmbGFncyArPSBTdHJpbmcuZm9ybWF0KCIlMDJ4IiwgbWFjW2ldKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oZmxhZ3MpOworICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCItIik7CisKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGFsbE5hbWVzLmNvbnRhaW5zKG5pZi5nZXROYW1lKCkpKTsKKyAgICAgICAgICAgIGFsbE5hbWVzLmFkZChuaWYuZ2V0TmFtZSgpKTsKKworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoYWxsSW5kZXhlcy5jb250YWlucyhuaWYuZ2V0SW5kZXgoKSkpOworICAgICAgICAgICAgYWxsSW5kZXhlcy5hZGQobmlmLmdldEluZGV4KCkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkQW5kcm9pZERhdGFncmFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkQW5kcm9pZERhdGFncmFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhkNzkwMjcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRBbmRyb2lkRGF0YWdyYW1UZXN0LmphdmEKQEAgLTAsMCArMSwxODggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkRhdGFncmFtUGFja2V0OworaW1wb3J0IGphdmEubmV0LkRhdGFncmFtU29ja2V0OworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNvY2tldFRpbWVvdXRFeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIEltcGxlbWVudHMgc29tZSBzaW1wbGUgdGVzdHMgZm9yIGRhdGFncmFtcy4gTm90IGFzIGV4Y2Vzc2l2ZSBhcyB0aGUgY29yZQorICogdGVzdHMsIGJ1dCBnb29kIGVub3VnaCBmb3IgdGhlIGhhcm5lc3MuCisgKi8KK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkRGF0YWdyYW1UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogSGVscGVyIGNsYXNzIHRoYXQgbGlzdGVucyB0byBpbmNvbWluZyBkYXRhZ3JhbXMgYW5kIHJlZmxlY3RzIHRoZW0gdG8gdGhlCisgICAgICogc2VuZGVyLiBJbmNvbWluZyBkYXRhZ3JhbSBpcyBpbnRlcnByZXRlZCBhcyBhIFN0cmluZy4gSXQgaXMgdXBwZXJjYXNlZAorICAgICAqIGJlZm9yZSBiZWluZyBzZW50IGJhY2suCisgICAgICovCisKKyAgICBjbGFzcyBSZWZsZWN0b3IgZXh0ZW5kcyBUaHJlYWQgeworICAgICAgICAvLyBIZWxwZXIgY2xhc3MgZm9yIHJlZmxlY3RpbmcgaW5jb21pbmcgZGF0YWdyYW1zLiAKKyAgICAgICAgRGF0YWdyYW1Tb2NrZXQgc29ja2V0OworCisgICAgICAgIGJvb2xlYW4gYWxpdmUgPSB0cnVlOworCisgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVsyNTZdOworCisgICAgICAgIERhdGFncmFtUGFja2V0IHBhY2tldDsKKworICAgICAgICAvKioKKyAgICAgICAgICogTWFpbiBsb29wLiBSZWNlaXZlcyBkYXRhZ3JhbXMgYW5kIHJlZmxlY3RzIHRoZW0uCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB3aGlsZSAoYWxpdmUpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldC5zZXRMZW5ndGgoYnVmZmVyLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgICAgICAgICBzb2NrZXQucmVjZWl2ZShwYWNrZXQpOworICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHMgPSBzdHJpbmdGcm9tUGFja2V0KHBhY2tldCk7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4ocyArICIgKGZyb20gIiArIHBhY2tldC5nZXRBZGRyZXNzKCkgKyAiOiIgKyBwYWNrZXQuZ2V0UG9ydCgpICsgIikiKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWdub3JlLgorICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdUb1BhY2tldChzLnRvVXBwZXJDYXNlKCksIHBhY2tldCk7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldC5zZXRBZGRyZXNzKEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldC5zZXRQb3J0KDIzNDUpOworCisgICAgICAgICAgICAgICAgICAgICAgICBzb2NrZXQuc2VuZChwYWNrZXQpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLkludGVycnVwdGVkSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBzb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IFJlbGZlY3RvciBvYmplY3QgZm9yIHRoZSBnaXZlbiBsb2NhbCBhZGRyZXNzIGFuZCBwb3J0LgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFJlZmxlY3RvcihpbnQgcG9ydCwgSW5ldEFkZHJlc3MgYWRkcmVzcykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwYWNrZXQgPSBuZXcgRGF0YWdyYW1QYWNrZXQoYnVmZmVyLCBidWZmZXIubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBzb2NrZXQgPSBuZXcgRGF0YWdyYW1Tb2NrZXQocG9ydCwgYWRkcmVzcyk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgIkNyZWF0aW5nIGRhdGFncmFtIHJlZmxlY3RvciBmYWlsZWQiLCBleCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyBhIGdpdmVuIGRhdGFncmFtIHBhY2tldCdzIGNvbnRlbnRzIHRvIGEgU3RyaW5nLgorICAgICAqLworICAgIHN0YXRpYyBTdHJpbmcgc3RyaW5nRnJvbVBhY2tldChEYXRhZ3JhbVBhY2tldCBwYWNrZXQpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcocGFja2V0LmdldERhdGEoKSwgMCwgcGFja2V0LmdldExlbmd0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyBhIGdpdmVuIFN0cmluZyBpbnRvIGEgZGF0YWdyYW0gcGFja2V0LgorICAgICAqLworICAgIHN0YXRpYyB2b2lkIHN0cmluZ1RvUGFja2V0KFN0cmluZyBzLCBEYXRhZ3JhbVBhY2tldCBwYWNrZXQpIHsKKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0gcy5nZXRCeXRlcygpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ5dGVzLCAwLCBwYWNrZXQuZ2V0RGF0YSgpLCAwLCBieXRlcy5sZW5ndGgpOworICAgICAgICBwYWNrZXQuc2V0TGVuZ3RoKGJ5dGVzLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW1wbGVtZW50cyB0aGUgbWFpbiBwYXJ0IG9mIHRoZSBEYXRhZ3JhbSB0ZXN0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REYXRhZ3JhbSgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIFJlZmxlY3RvciByZWZsZWN0b3IgPSBudWxsOworICAgICAgICBEYXRhZ3JhbVNvY2tldCBzb2NrZXQgPSBudWxsOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBTZXR1cCB0aGUgcmVmbGVjdG9yLCBzbyB3ZSBoYXZlIGEgcGFydG5lciB0byBzZW5kIHRvCisgICAgICAgICAgICByZWZsZWN0b3IgPSBuZXcgUmVmbGVjdG9yKDEyMzQsIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpKTsKKyAgICAgICAgICAgIHJlZmxlY3Rvci5zdGFydCgpOworCisgICAgICAgICAgICBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbMjU2XTsKKworICAgICAgICAgICAgRGF0YWdyYW1QYWNrZXQgcGFja2V0ID0gbmV3IERhdGFncmFtUGFja2V0KGJ1ZmZlciwgYnVmZmVyLmxlbmd0aCk7CisgICAgICAgICAgICBzb2NrZXQgPSBuZXcgRGF0YWdyYW1Tb2NrZXQoMjM0NSwgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCkpOworCisgICAgICAgICAgICAvLyBTZW5kIHRlbiBzaW1wbGUgcGFja2V0cyBhbmQgY2hlY2sgZm9yIHRoZSBleHBlY3RlZCByZXNwb25zZXMuCisgICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSAxMDsgaSsrKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHMgPSAiSGVsbG8sIEFuZHJvaWQgd29ybGQgIyIgKyBpICsgIiEiOworICAgICAgICAgICAgICAgIHN0cmluZ1RvUGFja2V0KHMsIHBhY2tldCk7CisKKyAgICAgICAgICAgICAgICBwYWNrZXQuc2V0QWRkcmVzcyhJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSk7CisgICAgICAgICAgICAgICAgcGFja2V0LnNldFBvcnQoMTIzNCk7CisKKyAgICAgICAgICAgICAgICBzb2NrZXQuc2VuZChwYWNrZXQpOworCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gSWdub3JlLgorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHBhY2tldC5zZXRMZW5ndGgoYnVmZmVyLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgc29ja2V0LnJlY2VpdmUocGFja2V0KTsKKyAgICAgICAgICAgICAgICBTdHJpbmcgdCA9IHN0cmluZ0Zyb21QYWNrZXQocGFja2V0KTsKKyAgICAgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4odCArICIgKGZyb20gIiArIHBhY2tldC5nZXRBZGRyZXNzKCkgKyAiOiIgKyBwYWNrZXQuZ2V0UG9ydCgpICsgIikiKTsKKworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhzLnRvVXBwZXJDYXNlKCksIHQpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHJlZmxlY3RvciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmVmbGVjdG9yLmFsaXZlID0gZmFsc2U7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChzb2NrZXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gUmVncmVzc2lvbiB0ZXN0IGZvciBpc3N1ZSAxMDE4MDAzOiBEYXRhZ3JhbVNvY2tldCBpZ25vcmVkIGEgc2V0IHRpbWVvdXQuCisgICAgcHVibGljIHZvaWQgdGVzdERhdGFncmFtU29ja2V0U2V0U09UaW1lb3V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIERhdGFncmFtU29ja2V0IHNvY2sgPSBudWxsOworICAgICAgICBpbnQgdGltZW91dCA9IDUwMDA7CisgICAgICAgIGxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNvY2sgPSBuZXcgRGF0YWdyYW1Tb2NrZXQoKTsKKyAgICAgICAgICAgIERhdGFncmFtUGFja2V0IHBhY2sgPSBuZXcgRGF0YWdyYW1QYWNrZXQobmV3IGJ5dGVbMTAwXSwgMTAwKTsKKyAgICAgICAgICAgIHNvY2suc2V0U29UaW1lb3V0KHRpbWVvdXQpOworICAgICAgICAgICAgc29jay5yZWNlaXZlKHBhY2spOworICAgICAgICB9IGNhdGNoIChTb2NrZXRUaW1lb3V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICBsb25nIGRlbGF5ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydDsKKyAgICAgICAgICAgIGlmIChNYXRoLmFicyhkZWxheSAtIHRpbWVvdXQpID4gMTAwMCkgeworICAgICAgICAgICAgICAgIGZhaWwoInRpbWVvdXQgd2FzIG5vdCBhY2N1cmF0ZS4gZXhwZWN0ZWQ6ICIgKyB0aW1lb3V0CisgICAgICAgICAgICAgICAgICAgICAgICArICIgYWN0dWFsOiAiICsgZGVsYXkgKyAiIG1pbGlzZWNvbmRzLiIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHNvY2sgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNvY2suY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZEFuZHJvaWRVUklUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRBbmRyb2lkVVJJVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRkYjM5OWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRBbmRyb2lkVVJJVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLm5ldC5VUkk7CitpbXBvcnQgamF2YS5uZXQuVVJJU3ludGF4RXhjZXB0aW9uOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZEFuZHJvaWRVUklUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjb25zdHJ1Y3QoImh0dHA6Ly93d3cuZ29vZ2xlLmNvbS90aGlzL2lzLXRoZS9wYXRoP3F1ZXJ5I2ZyYWdtZW50IiwKKyAgICAgICAgICAgICAgICAid3d3Lmdvb2dsZS5jb20iLCAiL3RoaXMvaXMtdGhlL3BhdGgiLCB0cnVlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNvbnN0cnVjdChTdHJpbmcgc3RyLCBTdHJpbmcgaG9zdCwgU3RyaW5nIHBhdGgsIGJvb2xlYW4gYWJzb2x1dGUpCisgICAgICAgICAgICB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIHVyaSA9IG5ldyBVUkkoc3RyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGhvc3QsIHVyaS5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMocGF0aCwgdXJpLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhhYnNvbHV0ZSwgdXJpLmlzQWJzb2x1dGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlc29sdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcmVzb2x2ZSgiaHR0cDovL3d3dy5nb29nbGUuY29tL3lvdXIiLAorICAgICAgICAgICAgICAgICJtb20iLAorICAgICAgICAgICAgICAgICJodHRwOi8vd3d3Lmdvb2dsZS5jb20vbW9tIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCByZXNvbHZlKFN0cmluZyBiYXNlLCBTdHJpbmcgdXJpLCBTdHJpbmcgZXhwZWN0ZWQpIHsKKyAgICAgICAgVVJJIGIgPSBVUkkuY3JlYXRlKGJhc2UpOworICAgICAgICBVUkkgcmVzb2x2ZWQgPSBiLnJlc29sdmUodXJpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCByZXNvbHZlZC50b1N0cmluZygpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRBdXRoZW50aWNhdG9yUmVxdWVzdG9yVHlwZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZEF1dGhlbnRpY2F0b3JSZXF1ZXN0b3JUeXBlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlZDZkNzIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRBdXRoZW50aWNhdG9yUmVxdWVzdG9yVHlwZVRlc3QuamF2YQpAQCAtMCwwICsxLDQ5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmV0OworCitpbXBvcnQgamF2YS5uZXQuQXV0aGVudGljYXRvcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRBdXRoZW50aWNhdG9yUmVxdWVzdG9yVHlwZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3ZhbHVlT2ZMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEF1dGhlbnRpY2F0b3IuUmVxdWVzdG9yVHlwZS5QUk9YWSwKKyAgICAgICAgICAgICAgICBBdXRoZW50aWNhdG9yLlJlcXVlc3RvclR5cGUudmFsdWVPZigiUFJPWFkiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBdXRoZW50aWNhdG9yLlJlcXVlc3RvclR5cGUuU0VSVkVSLAorICAgICAgICAgICAgICAgIEF1dGhlbnRpY2F0b3IuUmVxdWVzdG9yVHlwZS52YWx1ZU9mKCJTRVJWRVIiKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBdXRoZW50aWNhdG9yLlJlcXVlc3RvclR5cGUudmFsdWVPZigiVEVTVCIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF92YWx1ZXMgKCkgeworICAgICAgICBBdXRoZW50aWNhdG9yLlJlcXVlc3RvclR5cGVbXSBleHBlY3RlZFR5cGVzID0geworICAgICAgICAgICAgICAgIEF1dGhlbnRpY2F0b3IuUmVxdWVzdG9yVHlwZS5QUk9YWSwKKyAgICAgICAgICAgICAgICBBdXRoZW50aWNhdG9yLlJlcXVlc3RvclR5cGUuU0VSVkVSCisgICAgICAgIH07CisKKyAgICAgICAgQXV0aGVudGljYXRvci5SZXF1ZXN0b3JUeXBlW10gdHlwZXMgPSBBdXRoZW50aWNhdG9yLlJlcXVlc3RvclR5cGUudmFsdWVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZFR5cGVzLmxlbmd0aCwgdHlwZXMubGVuZ3RoKTsKKworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgZXhwZWN0ZWRUeXBlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkVHlwZXNbaV0sIHR5cGVzW2ldKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZEF1dGhlbnRpY2F0b3JUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRBdXRoZW50aWNhdG9yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUzZjcwMTcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRBdXRoZW50aWNhdG9yVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjggQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5ldDsKKworaW1wb3J0IGphdmEubmV0LkF1dGhlbnRpY2F0b3I7CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuUGFzc3dvcmRBdXRoZW50aWNhdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5uZXQuVW5rbm93bkhvc3RFeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkQXV0aGVudGljYXRvclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldERlZmF1bHQoKSB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24geworICAgICAgICBJbmV0QWRkcmVzcyBhZGRyID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCk7CisgICAgICAgIFBhc3N3b3JkQXV0aGVudGljYXRpb24gIHBhID0gQXV0aGVudGljYXRvci5yZXF1ZXN0UGFzc3dvcmRBdXRoZW50aWNhdGlvbigKKyAgICAgICAgICAgICAgICBhZGRyLCA4MDgwLCAiaHR0cCIsICJwcm9tdCIsICJIVFRQIik7CisgICAgICAgIGFzc2VydE51bGwocGEpOworCisgICAgICAgIE1vY2tBdXRoZW50aWNhdG9yIG1vY2sgPSBuZXcgTW9ja0F1dGhlbnRpY2F0b3IoKTsKKyAgICAgICAgQXV0aGVudGljYXRvci5zZXREZWZhdWx0KG1vY2spOworCisgICAgICAgIGFkZHIgPSBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKTsKKyAgICAgICAgcGEgPSBBdXRoZW50aWNhdG9yLnJlcXVlc3RQYXNzd29yZEF1dGhlbnRpY2F0aW9uKGFkZHIsIDgwLCAiaHR0cCIsICJwcm9tdCIsICJIVFRQIik7CisgICAgICAgIGFzc2VydE51bGwocGEpOworCisgICAgICAgIEF1dGhlbnRpY2F0b3Iuc2V0RGVmYXVsdChudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICBNb2NrQXV0aGVudGljYXRvciBtYSA9IG5ldyBNb2NrQXV0aGVudGljYXRvcigpOworICAgICAgICBhc3NlcnROdWxsKG1hLmdldFJlcXVlc3RpbmdVUkwoKSk7CisgICAgICAgIGFzc2VydE51bGwobWEuZ2V0UmVxdWVzdG9yVHlwZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFBhc3N3b3JkQXV0aGVudGljYXRpb24oKSB7CisgICAgICAgIE1vY2tBdXRoZW50aWNhdG9yIG1hID0gbmV3IE1vY2tBdXRoZW50aWNhdG9yKCk7CisgICAgICAgIGFzc2VydE51bGwobWEuZ2V0UGFzc3dvcmRBdXRoZW50aWNhdGlvbigpKTsKKyAgICB9CisKKyAgICBjbGFzcyBNb2NrQXV0aGVudGljYXRvciBleHRlbmRzIEF1dGhlbnRpY2F0b3IgeworICAgICAgICBwdWJsaWMgVVJMIGdldFJlcXVlc3RpbmdVUkwoKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0UmVxdWVzdGluZ1VSTCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEF1dGhlbnRpY2F0b3IuUmVxdWVzdG9yVHlwZSBnZXRSZXF1ZXN0b3JUeXBlKCkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldFJlcXVlc3RvclR5cGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBQYXNzd29yZEF1dGhlbnRpY2F0aW9uIGdldFBhc3N3b3JkQXV0aGVudGljYXRpb24oKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0UGFzc3dvcmRBdXRoZW50aWNhdGlvbigpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkQ29va2llSGFuZGxlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZENvb2tpZUhhbmRsZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjQ5YzMyNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZENvb2tpZUhhbmRsZXJUZXN0LmphdmEKQEAgLTAsMCArMSw5MSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Db29raWVIYW5kbGVyOworaW1wb3J0IGphdmEubmV0LlVSSTsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5uZXQuVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfQ29uZmlndXJhdGlvbjsKKworcHVibGljIGNsYXNzIE9sZENvb2tpZUhhbmRsZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgVVJJIGdldFVSSSwgcHV0VVJJOworICAgIFN0cmluZyBsaW5rID0gImh0dHA6Ly8iICsgU3VwcG9ydF9Db25maWd1cmF0aW9uLlNwZWNpYWxJbmV0VGVzdEFkZHJlc3MgKyAiLyI7CisgICAgYm9vbGVhbiBpc0dldENhbGxlZCA9IGZhbHNlOworICAgIGJvb2xlYW4gaXNQdXRDYWxsZWQgPSBmYWxzZTsKKyAgICBib29sZWFuIGNvbXBsZXRlZFN1Y2Nlc3NmdWxseSA9IGZhbHNlOworCisgICAgcHVibGljIHZvaWQgdGVzdF9Db29raWVIYW5kbGVyKCkgeworICAgICAgICBhc3NlcnROdWxsKENvb2tpZUhhbmRsZXIuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldF9wdXQoKSB7CisgICAgICAgIE1vY2tDb29raWVIYW5kbGVyIG1jaCA9IG5ldyBNb2NrQ29va2llSGFuZGxlcigpOworICAgICAgICBDb29raWVIYW5kbGVyIGRlZmF1bHRIYW5kbGVyID0gQ29va2llSGFuZGxlci5nZXREZWZhdWx0KCk7CisgICAgICAgIENvb2tpZUhhbmRsZXIuc2V0RGVmYXVsdChtY2gpOworCisgICAgICAgIGNsYXNzIFRlc3RUaHJlYWQgZXh0ZW5kcyBUaHJlYWQgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKGxpbmspOworICAgICAgICAgICAgICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm4gPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgY29ubi5nZXRDb250ZW50KCk7CisgICAgICAgICAgICAgICAgICAgIHVybCA9IG5ldyBVUkwobGluayk7CisgICAgICAgICAgICAgICAgICAgIGNvbm4gPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgY29ubi5nZXRDb250ZW50KCk7CisgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlZFN1Y2Nlc3NmdWxseSA9IHRydWU7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgVGVzdFRocmVhZCB0aHJlYWQgPSBuZXcgVGVzdFRocmVhZCgpOworCisgICAgICAgICAgICB0aHJlYWQuc3RhcnQoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdGhyZWFkLmpvaW4oKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBhc3NlcnRUcnVlKGlzR2V0Q2FsbGVkKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoaXNQdXRDYWxsZWQpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShjb21wbGV0ZWRTdWNjZXNzZnVsbHkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgQ29va2llSGFuZGxlci5zZXREZWZhdWx0KGRlZmF1bHRIYW5kbGVyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIE1vY2tDb29raWVIYW5kbGVyIGV4dGVuZHMgQ29va2llSGFuZGxlciB7CisKKyAgICAgICAgcHVibGljIE1hcCBnZXQoVVJJIHVyaSwgTWFwIHJlcXVlc3RIZWFkZXJzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgZ2V0VVJJID0gdXJpOworICAgICAgICAgICAgaXNHZXRDYWxsZWQgPSB0cnVlOworICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RIZWFkZXJzOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcHV0KFVSSSB1cmksIE1hcCByZXNwb25zZUhlYWRlcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBwdXRVUkkgPSB1cmk7CisgICAgICAgICAgICBpc1B1dENhbGxlZCA9IHRydWU7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGREYXRhZ3JhbVBhY2tldFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZERhdGFncmFtUGFja2V0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE3N2E0NGQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGREYXRhZ3JhbVBhY2tldFRlc3QuamF2YQpAQCAtMCwwICsxLDEyMyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5EYXRhZ3JhbVBhY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfUG9ydE1hbmFnZXI7CisKK3B1YmxpYyBjbGFzcyBPbGREYXRhZ3JhbVBhY2tldFRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgRGF0YWdyYW1QYWNrZXQgZHA7CisKKyAgICB2b2xhdGlsZSBib29sZWFuIHN0YXJ0ZWQgPSBmYWxzZTsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UG9ydCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGRwID0gbmV3IERhdGFncmFtUGFja2V0KCJIZWxsbyIuZ2V0Qnl0ZXMoKSwgNSwgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIDEwMDApOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwb3J0IHJldHVybmVkIiwgMTAwMCwgZHAuZ2V0UG9ydCgpKTsKKworICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbGhvc3QgPSBJbmV0QWRkcmVzcy5nZXRCeU5hbWUoImxvY2FsaG9zdCIpOworCisgICAgICAgIGludFtdIHBvcnRzID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydHNGb3JVRFAoMik7CisgICAgICAgIGZpbmFsIGludCBwb3J0ID0gcG9ydHNbMF07CisgICAgICAgIGZpbmFsIE9iamVjdCBsb2NrID0gbmV3IE9iamVjdCgpOworCisgICAgICAgIFRocmVhZCB0aHJlYWQgPSBuZXcgVGhyZWFkKG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICBEYXRhZ3JhbVNvY2tldCBzb2NrZXQgPSBudWxsOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHNvY2tldCA9IG5ldyBEYXRhZ3JhbVNvY2tldChwb3J0KTsKKyAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzdGFydGVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvY2subm90aWZ5QWxsKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgc29ja2V0LnNldFNvVGltZW91dCgzMDAwKTsKKyAgICAgICAgICAgICAgICAgICAgRGF0YWdyYW1QYWNrZXQgcGFja2V0ID0gbmV3IERhdGFncmFtUGFja2V0KG5ldyBieXRlWzI1Nl0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMjU2KTsKKyAgICAgICAgICAgICAgICAgICAgc29ja2V0LnJlY2VpdmUocGFja2V0KTsKKyAgICAgICAgICAgICAgICAgICAgc29ja2V0LnNlbmQocGFja2V0KTsKKyAgICAgICAgICAgICAgICAgICAgc29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInRocmVhZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNvY2tldCAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgc29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAgICAgdGhyZWFkLnN0YXJ0KCk7CisKKyAgICAgICAgRGF0YWdyYW1Tb2NrZXQgc29ja2V0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNvY2tldCA9IG5ldyBEYXRhZ3JhbVNvY2tldChwb3J0c1sxXSk7CisgICAgICAgICAgICBzb2NrZXQuc2V0U29UaW1lb3V0KDMwMDApOworICAgICAgICAgICAgRGF0YWdyYW1QYWNrZXQgcGFja2V0ID0gbmV3IERhdGFncmFtUGFja2V0KG5ldyBieXRlW10geyAxLCAyLCAzLCA0LAorICAgICAgICAgICAgICAgICAgICA1LCA2IH0sIDYsIGxvY2FsaG9zdCwgcG9ydCk7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBpZiAoIXN0YXJ0ZWQpCisgICAgICAgICAgICAgICAgICAgICAgICBsb2NrLndhaXQoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzb2NrZXQuc2VuZChwYWNrZXQpOworICAgICAgICAgICAgc29ja2V0LnJlY2VpdmUocGFja2V0KTsKKyAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZGF0YWdyYW0gcmVjZWl2ZWQgd3JvbmcgcG9ydDogIiArIHBhY2tldC5nZXRQb3J0KCksCisgICAgICAgICAgICAgICAgICAgIHBhY2tldC5nZXRQb3J0KCkgPT0gcG9ydCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoc29ja2V0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0TGVuZ3RoSSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBEYXRhZ3JhbVBhY2tldCgiSGVsbG8iLmdldEJ5dGVzKCksIDYpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBEYXRhZ3JhbVBhY2tldCgiSGVsbG8iLmdldEJ5dGVzKCksIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0RGF0YSRCSUkoKSB7CisgICAgICAgIGRwID0gbmV3IERhdGFncmFtUGFja2V0KCJIZWxsbyIuZ2V0Qnl0ZXMoKSwgNSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkcC5zZXREYXRhKG51bGwsIDIsIDMpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0RGF0YSRCKCkgeworICAgICAgICBkcCA9IG5ldyBEYXRhZ3JhbVBhY2tldCgiSGVsbG8iLmdldEJ5dGVzKCksIDUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZHAuc2V0RGF0YShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGREYXRhZ3JhbVNvY2tldEltcGxGYWN0b3J5VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkRGF0YWdyYW1Tb2NrZXRJbXBsRmFjdG9yeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MmRhYzFlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkRGF0YWdyYW1Tb2NrZXRJbXBsRmFjdG9yeVRlc3QuamF2YQpAQCAtMCwwICsxLDIwNSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5ldDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuRmllbGQ7CitpbXBvcnQgamF2YS5uZXQuRGF0YWdyYW1QYWNrZXQ7CitpbXBvcnQgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXRJbXBsOworaW1wb3J0IGphdmEubmV0LkRhdGFncmFtU29ja2V0SW1wbEZhY3Rvcnk7CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuTmV0d29ya0ludGVyZmFjZTsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNvY2tldEV4Y2VwdGlvbjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGREYXRhZ3JhbVNvY2tldEltcGxGYWN0b3J5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIERhdGFncmFtU29ja2V0SW1wbEZhY3Rvcnkgb2xkRmFjdG9yeSA9IG51bGw7CisgICAgRmllbGQgZmFjdG9yeUZpZWxkID0gbnVsbDsKKworICAgIGJvb2xlYW4gaXNUZXN0YWJsZSA9IGZhbHNlOworCisgICAgYm9vbGVhbiBpc0RhdGFncmFtU29ja2V0SW1wbENhbGxlZCA9IGZhbHNlOworICAgIGJvb2xlYW4gaXNDcmVhdGVEYXRhZ3JhbVNvY2tldEltcGwgPSBmYWxzZTsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY3JlYXRlRGF0YWdyYW1Tb2NrZXRJbXBsKCkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaXNUZXN0YWJsZSkgeworCisgICAgICAgICAgICBEYXRhZ3JhbVNvY2tldEltcGxGYWN0b3J5IGZhY3RvcnkgPSBuZXcgVGVzdERhdGFncmFtU29ja2V0SW1wbEZhY3RvcnkoKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGlzQ3JlYXRlRGF0YWdyYW1Tb2NrZXRJbXBsKTsKKyAgICAgICAgICAgIERhdGFncmFtU29ja2V0LnNldERhdGFncmFtU29ja2V0SW1wbEZhY3RvcnkoZmFjdG9yeSk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbmV3IGphdmEubmV0LkRhdGFncmFtU29ja2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShpc0NyZWF0ZURhdGFncmFtU29ja2V0SW1wbCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShpc0RhdGFncmFtU29ja2V0SW1wbENhbGxlZCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBEYXRhZ3JhbVNvY2tldC5zZXREYXRhZ3JhbVNvY2tldEltcGxGYWN0b3J5KGZhY3RvcnkpOworICAgICAgICAgICAgICAgIGZhaWwoIlNvY2tldEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2goU29ja2V0RXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIERhdGFncmFtU29ja2V0LnNldERhdGFncmFtU29ja2V0SW1wbEZhY3RvcnkobnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICAgICAgfSBjYXRjaChTb2NrZXRFeGNlcHRpb24gc2UpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9CisKKyAgICAgICAgfSBlbHNlIHsKKworICAgICAgICAgICAgVGVzdERhdGFncmFtU29ja2V0SW1wbEZhY3RvcnkgZHNmID0gbmV3IFRlc3REYXRhZ3JhbVNvY2tldEltcGxGYWN0b3J5KCk7CisgICAgICAgICAgICBEYXRhZ3JhbVNvY2tldEltcGwgZHNpID0gZHNmLmNyZWF0ZURhdGFncmFtU29ja2V0SW1wbCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGRzaS5nZXRPcHRpb24oMCkpOworICAgICAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgeworICAgICAgICBGaWVsZCBbXSBmaWVsZHMgPSBEYXRhZ3JhbVNvY2tldC5jbGFzcy5nZXREZWNsYXJlZEZpZWxkcygpOworICAgICAgICBpbnQgY291bnRlciA9IDA7CisgICAgICAgIGZvciAoRmllbGQgZmllbGQgOiBmaWVsZHMpIHsKKyAgICAgICAgICAgIGlmIChEYXRhZ3JhbVNvY2tldEltcGxGYWN0b3J5LmNsYXNzLmVxdWFscyhmaWVsZC5nZXRUeXBlKCkpKSB7CisgICAgICAgICAgICAgICAgY291bnRlcisrOworICAgICAgICAgICAgICAgIGZhY3RvcnlGaWVsZCA9IGZpZWxkOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYoY291bnRlciA9PSAxKSB7CisKKyAgICAgICAgICAgIGlzVGVzdGFibGUgPSB0cnVlOworCisgICAgICAgICAgICBmYWN0b3J5RmllbGQuc2V0QWNjZXNzaWJsZSh0cnVlKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgb2xkRmFjdG9yeSA9IChEYXRhZ3JhbVNvY2tldEltcGxGYWN0b3J5KSBmYWN0b3J5RmllbGQuZ2V0KG51bGwpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIHRocm93biBkdXJpbmcgc2V0VXA6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiB3YXMgdGhyb3duIGR1cmluZyBzZXRVcDogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgaWYoaXNUZXN0YWJsZSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmYWN0b3J5RmllbGQuc2V0KG51bGwsIG9sZEZhY3RvcnkpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIHRocm93biBkdXJpbmcgdGVhckRvd246ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiB3YXMgdGhyb3duIGR1cmluZyB0ZWFyRG93bjogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBUZXN0RGF0YWdyYW1Tb2NrZXRJbXBsRmFjdG9yeSBpbXBsZW1lbnRzIERhdGFncmFtU29ja2V0SW1wbEZhY3RvcnkgeworICAgICAgICBwdWJsaWMgRGF0YWdyYW1Tb2NrZXRJbXBsIGNyZWF0ZURhdGFncmFtU29ja2V0SW1wbCgpIHsKKyAgICAgICAgICAgIGlzQ3JlYXRlRGF0YWdyYW1Tb2NrZXRJbXBsID0gdHJ1ZTsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVGVzdERhdGFncmFtU29ja2V0SW1wbCgpOworICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgVGVzdERhdGFncmFtU29ja2V0SW1wbCBleHRlbmRzIERhdGFncmFtU29ja2V0SW1wbCB7CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGJpbmQoaW50IGFyZzAsIEluZXRBZGRyZXNzIGFyZzEpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGNsb3NlKCkgeworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGNyZWF0ZSgpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICAgICAgaXNEYXRhZ3JhbVNvY2tldEltcGxDYWxsZWQgPSB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBieXRlIGdldFRUTCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgaW50IGdldFRpbWVUb0xpdmUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgam9pbihJbmV0QWRkcmVzcyBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGpvaW5Hcm91cChTb2NrZXRBZGRyZXNzIGFyZzAsIE5ldHdvcmtJbnRlcmZhY2UgYXJnMSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBsZWF2ZShJbmV0QWRkcmVzcyBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGxlYXZlR3JvdXAoU29ja2V0QWRkcmVzcyBhcmcwLCBOZXR3b3JrSW50ZXJmYWNlIGFyZzEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBwZWVrKEluZXRBZGRyZXNzIGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gMTA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGludCBwZWVrRGF0YShEYXRhZ3JhbVBhY2tldCBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgcmVjZWl2ZShEYXRhZ3JhbVBhY2tldCBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIHNlbmQoRGF0YWdyYW1QYWNrZXQgYXJnMCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBzZXRUVEwoYnl0ZSBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIHNldFRpbWVUb0xpdmUoaW50IGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IGdldE9wdGlvbihpbnQgYXJnMCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldE9wdGlvbihpbnQgYXJnMCwgT2JqZWN0IGFyZzEpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkRGF0YWdyYW1Tb2NrZXRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGREYXRhZ3JhbVNvY2tldFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NjZhNTAzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkRGF0YWdyYW1Tb2NrZXRUZXN0LmphdmEKQEAgLTAsMCArMSwyMTY2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5CaW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkRhdGFncmFtUGFja2V0OworaW1wb3J0IGphdmEubmV0LkRhdGFncmFtU29ja2V0OworaW1wb3J0IGphdmEubmV0LkRhdGFncmFtU29ja2V0SW1wbDsKK2ltcG9ydCBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldEltcGxGYWN0b3J5OworaW1wb3J0IGphdmEubmV0LkluZXQ0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0NkFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuTmV0d29ya0ludGVyZmFjZTsKK2ltcG9ydCBqYXZhLm5ldC5Qb3J0VW5yZWFjaGFibGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuU29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuU29ja2V0VGltZW91dEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5EYXRhZ3JhbUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Db25maWd1cmF0aW9uOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Qb3J0TWFuYWdlcjsKKworcHVibGljIGNsYXNzIE9sZERhdGFncmFtU29ja2V0VGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay4vKlNvY2tldCovVGVzdENhc2UgeworCisgICAgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQgZHM7CisKKyAgICBqYXZhLm5ldC5EYXRhZ3JhbVBhY2tldCBkcDsKKworICAgIERhdGFncmFtU29ja2V0IHNkcyA9IG51bGw7CisKKyAgICBTdHJpbmcgcmV0dmFsOworCisgICAgU3RyaW5nIHRlc3RTdHJpbmcgPSAiVGVzdCBTdHJpbmciOworCisgICAgYm9vbGVhbiBpbnRlcnJ1cHRlZDsKKworICAgIGNsYXNzIERhdGFncmFtU2VydmVyIGV4dGVuZHMgVGhyZWFkIHsKKworICAgICAgICBwdWJsaWMgRGF0YWdyYW1Tb2NrZXQgbXM7CisKKyAgICAgICAgYm9vbGVhbiBydW5uaW5nID0gdHJ1ZTsKKworICAgICAgICBwdWJsaWMgdm9sYXRpbGUgYnl0ZVtdIHJidWYgPSBuZXcgYnl0ZVs1MTJdOworCisgICAgICAgIHZvbGF0aWxlIERhdGFncmFtUGFja2V0IHJkcCA9IG51bGw7CisKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB3aGlsZSAocnVubmluZykgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgbXMucmVjZWl2ZShyZHApOworICAgICAgICAgICAgICAgICAgICAgICAgLy8gZWNobyB0aGUgcGFja2V0IGJhY2sKKyAgICAgICAgICAgICAgICAgICAgICAgIG1zLnNlbmQocmRwKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JbnRlcnJ1cHRlZElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFRocmVhZC55aWVsZCgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgOworICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJEYXRhZ3JhbVNlcnZlciBzZXJ2ZXIgZmFpbGVkOiAiICsgZSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIG1zLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzdG9wU2VydmVyKCkgeworICAgICAgICAgICAgcnVubmluZyA9IGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIERhdGFncmFtU2VydmVyKGludCBhUG9ydCwgSW5ldEFkZHJlc3MgYWRkcmVzcykKKyAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByYnVmID0gbmV3IGJ5dGVbNTEyXTsKKyAgICAgICAgICAgIHJidWZbMF0gPSAtMTsKKyAgICAgICAgICAgIHJkcCA9IG5ldyBEYXRhZ3JhbVBhY2tldChyYnVmLCByYnVmLmxlbmd0aCk7CisgICAgICAgICAgICBtcyA9IG5ldyBEYXRhZ3JhbVNvY2tldChhUG9ydCwgYWRkcmVzcyk7CisgICAgICAgICAgICBtcy5zZXRTb1RpbWVvdXQoMjAwMCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQoKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZHMgPSBuZXcgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkNvdWxkIG5vdCBjcmVhdGUgRGF0YWdyYW1Tb2NrZXQgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgU2VjdXJpdHlNYW5hZ2VyIHNtID0gbmV3IFNlY3VyaXR5TWFuYWdlcigpIHsKKworICAgICAgICAgICAgcHVibGljIHZvaWQgY2hlY2tQZXJtaXNzaW9uKFBlcm1pc3Npb24gcGVybSkgeworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBjaGVja0xpc3RlbihpbnQgcG9ydCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIFNlY3VyaXR5TWFuYWdlciBvbGRTbSA9IFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKTsKKyAgICAgICAgU3lzdGVtLnNldFNlY3VyaXR5TWFuYWdlcihzbSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRGF0YWdyYW1Tb2NrZXQoKTsKKyAgICAgICAgICAgIGZhaWwoIlNlY3VyaXR5RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIFN5c3RlbS5zZXRTZWN1cml0eU1hbmFnZXIob2xkU20pOworICAgICAgICB9CisgICAgICAgICovCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldChpbnQpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnRGb3JVRFAoKTsKKyAgICAgICAgICAgIGRzID0gbmV3IGphdmEubmV0LkRhdGFncmFtU29ja2V0KHBvcnROdW1iZXIpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQ3JlYXRlZCBzb2NrZXQgd2l0aCBpbmNvcnJlY3QgcG9ydCIsCisgICAgICAgICAgICAgICAgICAgIGRzLmdldExvY2FsUG9ydCgpID09IHBvcnROdW1iZXIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiQ291bGQgbm90IGNyZWF0ZSBEYXRhZ3JhbVNvY2tldCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICBTZWN1cml0eU1hbmFnZXIgc20gPSBuZXcgU2VjdXJpdHlNYW5hZ2VyKCkgeworCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBjaGVja1Blcm1pc3Npb24oUGVybWlzc2lvbiBwZXJtKSB7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrTGlzdGVuKGludCBwb3J0KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgU2VjdXJpdHlNYW5hZ2VyIG9sZFNtID0gU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpOworICAgICAgICBTeXN0ZW0uc2V0U2VjdXJpdHlNYW5hZ2VyKHNtKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBEYXRhZ3JhbVNvY2tldCg4MDgwKTsKKyAgICAgICAgICAgIGZhaWwoIlNlY3VyaXR5RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIFN5c3RlbS5zZXRTZWN1cml0eU1hbmFnZXIob2xkU20pOworICAgICAgICB9CisgICAgICAgICovCisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIERhdGFncmFtU29ja2V0IGRzID0gbmV3IGphdmEubmV0LkRhdGFncmFtU29ja2V0KDEpOworICAgICAgICAgICAgaWYgKCEoInJvb3QiLmVxdWFscyhTeXN0ZW0uZ2V0UHJvcGVydHkoInVzZXIubmFtZSIpKSkpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JJTGphdmFfbmV0X0luZXRBZGRyZXNzKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQoaW50LCBqYXZhLm5ldC5JbmV0QWRkcmVzcykKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydEZvclVEUCgpOworICAgICAgICAgICAgZHMgPSBuZXcgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQocG9ydE51bWJlciwgSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgLmdldExvY2FsSG9zdCgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkNyZWF0ZWQgc29ja2V0IHdpdGggaW5jb3JyZWN0IHBvcnQiLAorICAgICAgICAgICAgICAgICAgICBkcy5nZXRMb2NhbFBvcnQoKSA9PSBwb3J0TnVtYmVyKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkNyZWF0ZWQgc29ja2V0IHdpdGggaW5jb3JyZWN0IGFkZHJlc3MiLCBkcworICAgICAgICAgICAgICAgICAgICAuZ2V0TG9jYWxBZGRyZXNzKCkuZXF1YWxzKEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJDb3VsZCBub3QgY3JlYXRlIERhdGFncmFtU29ja2V0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgIFNlY3VyaXR5TWFuYWdlciBzbSA9IG5ldyBTZWN1cml0eU1hbmFnZXIoKSB7CisKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihQZXJtaXNzaW9uIHBlcm0pIHsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHZvaWQgY2hlY2tMaXN0ZW4oaW50IHBvcnQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBTZWN1cml0eU1hbmFnZXIgb2xkU20gPSBTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCk7CisgICAgICAgIFN5c3RlbS5zZXRTZWN1cml0eU1hbmFnZXIoc20pOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IGphdmEubmV0LkRhdGFncmFtU29ja2V0KDgwODAsIEluZXRBZGRyZXNzCisgICAgICAgICAgICAgICAgICAgIC5nZXRMb2NhbEhvc3QoKSk7CisgICAgICAgICAgICBmYWlsKCJTZWN1cml0eUV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKFVua25vd25Ib3N0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVua25vd25Ib3N0RXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBTeXN0ZW0uc2V0U2VjdXJpdHlNYW5hZ2VyKG9sZFNtKTsKKyAgICAgICAgfQorICAgICAgICAqLworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQoMSwgSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgLmdldExvY2FsSG9zdCgpKTsKKyAgICAgICAgICAgIGZhaWwoIlNvY2tldEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChTb2NrZXRFeGNlcHRpb24gc2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5rbm93bkhvc3RFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvc2UoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEubmV0LkRhdGFncmFtU29ja2V0LmNsb3NlKCkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydEZvclVEUCgpOworICAgICAgICAgICAgZHMgPSBuZXcgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQocG9ydE51bWJlcik7CisgICAgICAgICAgICBkcCA9IG5ldyBEYXRhZ3JhbVBhY2tldCgiVGVzdCBTdHJpbmciLmdldEJ5dGVzKCksIDExLCBJbmV0QWRkcmVzcworICAgICAgICAgICAgICAgICAgICAuZ2V0TG9jYWxIb3N0KCksIDApOworICAgICAgICAgICAgZHMuY2xvc2UoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZHMuc2VuZChkcCk7CisgICAgICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25uZWN0TGphdmFfbmV0X0luZXRBZGRyZXNzSSgpIHRocm93cworICAgICAgICAgICAgVW5rbm93bkhvc3RFeGNlcHRpb24sIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkcyA9IG5ldyBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldCgpOworICAgICAgICAgICAgSW5ldEFkZHJlc3MgaW5ldEFkZHJlc3MgPSBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKTsKKyAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydEZvclVEUCgpOworICAgICAgICAgICAgZHMuY29ubmVjdChpbmV0QWRkcmVzcywgcG9ydE51bWJlcik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgSW5ldEFkZHJlc3MiLCBkcy5nZXRJbmV0QWRkcmVzcygpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgaW5ldEFkZHJlc3MpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBQb3J0IiwgZHMuZ2V0UG9ydCgpID09IHBvcnROdW1iZXIpOworICAgICAgICAgICAgZHMuZGlzY29ubmVjdCgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgICAgICBTeXN0ZW0ub3V0CisgICAgICAgICAgICAgICAgICAgIC5wcmludGxuKCJSdW5uaW5nIHRlc3RfY29ubmVjdExqYXZhX25ldF9JbmV0QWRkcmVzc0kiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKERhdGFncmFtU29ja2V0VGVzdCkgd2l0aCBJUHY2R2xvYmFsQWRkcmVzc0pjbDQ6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIFN1cHBvcnRfQ29uZmlndXJhdGlvbi5JUHY2R2xvYmFsQWRkcmVzc0pjbDQpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBkcyA9IG5ldyBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldCgpOworICAgICAgICAgICAgICAgIEluZXRBZGRyZXNzIGluZXRBZGRyZXNzID0gSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRCeU5hbWUoU3VwcG9ydF9Db25maWd1cmF0aW9uLklQdjZHbG9iYWxBZGRyZXNzSmNsNCk7CisgICAgICAgICAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0Rm9yVURQKCk7CisgICAgICAgICAgICAgICAgZHMuY29ubmVjdChpbmV0QWRkcmVzcywgcG9ydE51bWJlcik7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IEluZXRBZGRyZXNzIiwgZHMuZ2V0SW5ldEFkZHJlc3MoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICAgICBpbmV0QWRkcmVzcykpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBQb3J0IiwgZHMuZ2V0UG9ydCgpID09IHBvcnROdW1iZXIpOworICAgICAgICAgICAgICAgIGRzLmRpc2Nvbm5lY3QoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gQ3JlYXRlIGEgY29ubmVjdGVkIGRhdGFncmFtIHNvY2tldCB0byB0ZXN0CisgICAgICAgICAgICAvLyBQbGFpbkRhdGFncmFtU29ja2V0SW1wbC5wZWVrKCkKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIGxvY2FsSG9zdCA9IEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpOworICAgICAgICAgICAgRGF0YWdyYW1Tb2NrZXQgZHMgPSBuZXcgRGF0YWdyYW1Tb2NrZXQoKTsKKyAgICAgICAgICAgIGludCBwb3J0ID0gZHMuZ2V0TG9jYWxQb3J0KCk7CisgICAgICAgICAgICBkcy5jb25uZWN0KGxvY2FsSG9zdCwgcG9ydCk7CisgICAgICAgICAgICBEYXRhZ3JhbVBhY2tldCBzZW5kID0gbmV3IERhdGFncmFtUGFja2V0KG5ldyBieXRlWzEwXSwgMTAsCisgICAgICAgICAgICAgICAgICAgIGxvY2FsSG9zdCwgcG9ydCk7CisgICAgICAgICAgICBkcy5zZW5kKHNlbmQpOworICAgICAgICAgICAgRGF0YWdyYW1QYWNrZXQgcmVjZWl2ZSA9IG5ldyBEYXRhZ3JhbVBhY2tldChuZXcgYnl0ZVsyMF0sIDIwKTsKKyAgICAgICAgICAgIGRzLnNldFNvVGltZW91dCgyMDAwKTsKKyAgICAgICAgICAgIGRzLnJlY2VpdmUocmVjZWl2ZSk7CisgICAgICAgICAgICBkcy5jbG9zZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3Jvbmcgc2l6ZTogIiArIHJlY2VpdmUuZ2V0TGVuZ3RoKCksIHJlY2VpdmUKKyAgICAgICAgICAgICAgICAgICAgLmdldExlbmd0aCgpID09IDEwKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIldyb25nIHJlY2VpdmVyIiwgcmVjZWl2ZS5nZXRBZGRyZXNzKCkuZXF1YWxzKGxvY2FsSG9zdCkpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uIDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGNsYXNzIERhdGFncmFtU2VydmVyIGV4dGVuZHMgVGhyZWFkIHsKKworICAgICAgICAgICAgcHVibGljIERhdGFncmFtU29ja2V0IG1zOworCisgICAgICAgICAgICBib29sZWFuIHJ1bm5pbmcgPSB0cnVlOworCisgICAgICAgICAgICBwdWJsaWMgYnl0ZVtdIHJidWYgPSBuZXcgYnl0ZVs1MTJdOworCisgICAgICAgICAgICBEYXRhZ3JhbVBhY2tldCByZHAgPSBudWxsOworCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHJ1bm5pbmcpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXMucmVjZWl2ZShyZHApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVjaG8gdGhlIHBhY2tldCBiYWNrCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXMuc2VuZChyZHApOworICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JbnRlcnJ1cHRlZElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaHJlYWQueWllbGQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJNdWx0aWNhc3Qgc2VydmVyIGZhaWxlZDogIiArIGUpOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIG1zLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBzdG9wU2VydmVyKCkgeworICAgICAgICAgICAgICAgIHJ1bm5pbmcgPSBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIERhdGFncmFtU2VydmVyKGludCBhUG9ydCwgSW5ldEFkZHJlc3MgYWRkcmVzcykKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJidWYgPSBuZXcgYnl0ZVs1MTJdOworICAgICAgICAgICAgICAgIHJidWZbMF0gPSAtMTsKKyAgICAgICAgICAgICAgICByZHAgPSBuZXcgRGF0YWdyYW1QYWNrZXQocmJ1ZiwgcmJ1Zi5sZW5ndGgpOworICAgICAgICAgICAgICAgIG1zID0gbmV3IERhdGFncmFtU29ja2V0KGFQb3J0LCBhZGRyZXNzKTsKKyAgICAgICAgICAgICAgICBtcy5zZXRTb1RpbWVvdXQoMjAwMCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyB2YWxpZGF0ZSB0aGF0IHdlIGdldCB0aGUgUG9ydFVucmVhY2hhYmxlIGV4Y2VwdGlvbiBpZiB3ZSB0cnkgdG8KKyAgICAgICAgLy8gc2VuZCBhIGRncmFtIHRvIGEgc2VydmVyIHRoYXQgaXMgbm90IHJ1bm5pbmcgYW5kIHRoZW4gZG8gYSByZWN2CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkcyA9IG5ldyBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldCgpOworICAgICAgICAgICAgSW5ldEFkZHJlc3MgaW5ldEFkZHJlc3MgPSBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKTsKKyAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydEZvclVEUCgpOworICAgICAgICAgICAgZHMuY29ubmVjdChpbmV0QWRkcmVzcywgcG9ydE51bWJlcik7CisgICAgICAgICAgICBEYXRhZ3JhbVBhY2tldCBzZW5kID0gbmV3IERhdGFncmFtUGFja2V0KG5ldyBieXRlWzEwXSwgMTApOworICAgICAgICAgICAgZHMuc2VuZChzZW5kKTsKKyAgICAgICAgICAgIERhdGFncmFtUGFja2V0IHJlY2VpdmUgPSBuZXcgRGF0YWdyYW1QYWNrZXQobmV3IGJ5dGVbMjBdLCAyMCk7CisgICAgICAgICAgICBkcy5zZXRTb1RpbWVvdXQoMTAwMDApOworICAgICAgICAgICAgZHMucmVjZWl2ZShyZWNlaXZlKTsKKyAgICAgICAgICAgIGRzLmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAiTm8gUG9ydFVucmVhY2hhYmxlRXhjZXB0aW9uIHdoZW4gY29ubmVjdGVkIGF0IG5hdGl2ZSBsZXZlbCBvbiByZWN2ICIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIldyb25nIGV4Y2VwdGlvbiB3aGVuIHRyeWluZyB0byBjb25uZWN0IGF0IG5hdGl2ZSBsZXZlbCBvbiByZWN2OiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgIChlIGluc3RhbmNlb2YgUG9ydFVucmVhY2hhYmxlRXhjZXB0aW9uKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyB2YWxpZGF0ZSB0aGF0IHdlIGNhbiBzZW5kL3JlY2VpdmUgd2l0aCBkYXRhZ3JhbSBzb2NrZXRzIGNvbm5lY3RlZCBhdAorICAgICAgICAvLyB0aGUgbmF0aXZlIGxldmVsCisgICAgICAgIERhdGFncmFtU2VydmVyIHNlcnZlciA9IG51bGw7CisgICAgICAgIGludFtdIHBvcnRzID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydHNGb3JVRFAoMyk7CisgICAgICAgIGludCBzZXJ2ZXJQb3J0TnVtYmVyID0gcG9ydHNbMF07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbEhvc3QgPSBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKTsKKyAgICAgICAgICAgIERhdGFncmFtU29ja2V0IGRzID0gbmV3IERhdGFncmFtU29ja2V0KHBvcnRzWzFdKTsKKyAgICAgICAgICAgIERhdGFncmFtU29ja2V0IGRzMiA9IG5ldyBEYXRhZ3JhbVNvY2tldChwb3J0c1syXSk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2VydmVyID0gbmV3IERhdGFncmFtU2VydmVyKHNlcnZlclBvcnROdW1iZXIsIGxvY2FsSG9zdCk7CisgICAgICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAgICAgIkZhaWxlZCB0byBzZXQgdXAgZGF0YWdyYW0gc2VydmVyIGZvciBuYXRpdmUgY29ubmVjdGVkIERncmFtIHNvY2tldCB0ZXN0ICIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgcG9ydCA9IGRzLmdldExvY2FsUG9ydCgpOworICAgICAgICAgICAgZHMuY29ubmVjdChsb2NhbEhvc3QsIHNlcnZlclBvcnROdW1iZXIpOworCisgICAgICAgICAgICBieXRlW10gc2VuZEJ5dGVzID0geyAnVCcsICdlJywgJ3MnLCAndCcsIDAgfTsKKyAgICAgICAgICAgIERhdGFncmFtUGFja2V0IHNlbmQgPSBuZXcgRGF0YWdyYW1QYWNrZXQoc2VuZEJ5dGVzLAorICAgICAgICAgICAgICAgICAgICBzZW5kQnl0ZXMubGVuZ3RoKTsKKyAgICAgICAgICAgIGRzLnNlbmQoc2VuZCk7CisgICAgICAgICAgICBEYXRhZ3JhbVBhY2tldCByZWNlaXZlID0gbmV3IERhdGFncmFtUGFja2V0KG5ldyBieXRlWzIwXSwgMjApOworICAgICAgICAgICAgZHMuc2V0U29UaW1lb3V0KDIwMDApOworICAgICAgICAgICAgZHMucmVjZWl2ZShyZWNlaXZlKTsKKyAgICAgICAgICAgIGRzLmNsb3NlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBzaXplIGRhdGEgcmVjZWl2ZWQ6ICIgKyByZWNlaXZlLmdldExlbmd0aCgpLAorICAgICAgICAgICAgICAgICAgICByZWNlaXZlLmdldExlbmd0aCgpID09IHNlbmRCeXRlcy5sZW5ndGgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgZGF0YSByZWNlaXZlZCIKKyAgICAgICAgICAgICAgICAgICAgKyBuZXcgU3RyaW5nKHJlY2VpdmUuZ2V0RGF0YSgpLCAwLCByZWNlaXZlLmdldExlbmd0aCgpKQorICAgICAgICAgICAgICAgICAgICArICI6IiArIG5ldyBTdHJpbmcoc2VuZEJ5dGVzKSwgbmV3IFN0cmluZygKKyAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZS5nZXREYXRhKCksIDAsIHJlY2VpdmUuZ2V0TGVuZ3RoKCkpCisgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMobmV3IFN0cmluZyhzZW5kQnl0ZXMpKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyByZWNlaXZlcjoiICsgcmVjZWl2ZS5nZXRBZGRyZXNzKCkgKyAiOiIKKyAgICAgICAgICAgICAgICAgICAgKyBsb2NhbEhvc3QsIHJlY2VpdmUuZ2V0QWRkcmVzcygpLmVxdWFscyhsb2NhbEhvc3QpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoCisgICAgICAgICAgICAgICAgICAgICJVbmV4cGVjdGVkIGV4Y2VwdGlvbiB3aGVuIHNlbmRpbmcgZGF0YSBvbiBkZ3JhbSBjb25uZWN0ZWQgYXQgbmF0aXZlIGxldmVsOiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNlcnZlci5zdG9wU2VydmVyKCk7CisgICAgICAgIH0KKworICAgICAgICAvLyB2YWxpZGF0ZSB0aGF0IHdlIGNhbiBkaXNjb25uZWN0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkcyA9IG5ldyBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldCgpOworICAgICAgICAgICAgSW5ldEFkZHJlc3MgaW5ldEFkZHJlc3MgPSBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKTsKKyAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydEZvclVEUCgpOworICAgICAgICAgICAgZHMuY29ubmVjdChpbmV0QWRkcmVzcywgcG9ydE51bWJlcik7CisgICAgICAgICAgICBkcy5kaXNjb25uZWN0KCk7CisgICAgICAgICAgICBkcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVW5leHBlY3RlZCBleGNlcHRpb24gd2hlbiB0cnlpbmcgdG8gY29ubmVjdCBhdCBuYXRpdmUiCisgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpLCAoZSBpbnN0YW5jZW9mIFBvcnRVbnJlYWNoYWJsZUV4Y2VwdGlvbikpOworICAgICAgICB9CisKKyAgICAgICAgLy8gdmFsaWRhdGUgdGhhdCBvbmNlIGNvbm5lY3RlZCB3ZSBjYW5ub3Qgc2VuZCB0byBhbm90aGVyIGFkZHJlc3MKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRzID0gbmV3IGphdmEubmV0LkRhdGFncmFtU29ja2V0KCk7CisgICAgICAgICAgICBJbmV0QWRkcmVzcyBpbmV0QWRkcmVzcyA9IEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpOworICAgICAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0Rm9yVURQKCk7CisgICAgICAgICAgICBkcy5jb25uZWN0KGluZXRBZGRyZXNzLCBwb3J0TnVtYmVyKTsKKyAgICAgICAgICAgIERhdGFncmFtUGFja2V0IHNlbmQgPSBuZXcgRGF0YWdyYW1QYWNrZXQobmV3IGJ5dGVbMTBdLCAxMCwKKyAgICAgICAgICAgICAgICAgICAgaW5ldEFkZHJlc3MsIHBvcnROdW1iZXIgKyAxKTsKKyAgICAgICAgICAgIGRzLnNlbmQoc2VuZCk7CisgICAgICAgICAgICBkcy5jbG9zZSgpOworICAgICAgICAgICAgZmFpbCgKKyAgICAgICAgICAgICAgICAgICAgIk5vIEV4Y2VwdGlvbiB3aGVuIHRyeWluZyB0byBzZW5kIHRvIGEgZGlmZmVyZW50IGFkZHJlc3Mgb24gYSBjb25uZWN0ZWQgc29ja2V0ICIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIldyb25nIGV4Y2VwdGlvbiB3aGVuIHRyeWluZyB0byBzZW5kIHRvIGEgZGlmZmVyZW50IGFkZHJlc3Mgb24gYSBjb25uZWN0ZWQgc29ja2V0OiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgIChlIGluc3RhbmNlb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyB2YWxpZGF0ZSB0aGF0IHdlIGNhbiBjb25uZWN0LCB0aGVuIGRpc2Nvbm5lY3QsIHRoZW4gY29ubmVjdCB0aGVuCisgICAgICAgIC8vIHNlbmQvcmVjdgorICAgICAgICBzZXJ2ZXIgPSBudWxsOworICAgICAgICBwb3J0cyA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnRzRm9yVURQKDMpOworICAgICAgICBzZXJ2ZXJQb3J0TnVtYmVyID0gcG9ydHNbMF07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbEhvc3QgPSBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKTsKKyAgICAgICAgICAgIERhdGFncmFtU29ja2V0IGRzID0gbmV3IERhdGFncmFtU29ja2V0KHBvcnRzWzFdKTsKKyAgICAgICAgICAgIERhdGFncmFtU29ja2V0IGRzMiA9IG5ldyBEYXRhZ3JhbVNvY2tldChwb3J0c1syXSk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2VydmVyID0gbmV3IERhdGFncmFtU2VydmVyKHNlcnZlclBvcnROdW1iZXIsIGxvY2FsSG9zdCk7CisgICAgICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAgICAgIkZhaWxlZCB0byBzZXQgdXAgZGF0YWdyYW0gc2VydmVyIGZvciBuYXRpdmUgY29ubmVjdGVkIERncmFtIHNvY2tldCB0ZXN0ICIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgcG9ydCA9IGRzLmdldExvY2FsUG9ydCgpOworICAgICAgICAgICAgZHMuY29ubmVjdChsb2NhbEhvc3QsIHNlcnZlclBvcnROdW1iZXIgKyAxKTsKKyAgICAgICAgICAgIGRzLmRpc2Nvbm5lY3QoKTsKKyAgICAgICAgICAgIGRzLmNvbm5lY3QobG9jYWxIb3N0LCBzZXJ2ZXJQb3J0TnVtYmVyKTsKKworICAgICAgICAgICAgYnl0ZVtdIHNlbmRCeXRlcyA9IHsgJ1QnLCAnZScsICdzJywgJ3QnLCAwIH07CisgICAgICAgICAgICBEYXRhZ3JhbVBhY2tldCBzZW5kID0gbmV3IERhdGFncmFtUGFja2V0KHNlbmRCeXRlcywKKyAgICAgICAgICAgICAgICAgICAgc2VuZEJ5dGVzLmxlbmd0aCk7CisgICAgICAgICAgICBkcy5zZW5kKHNlbmQpOworICAgICAgICAgICAgRGF0YWdyYW1QYWNrZXQgcmVjZWl2ZSA9IG5ldyBEYXRhZ3JhbVBhY2tldChuZXcgYnl0ZVsyMF0sIDIwKTsKKyAgICAgICAgICAgIGRzLnNldFNvVGltZW91dCgyMDAwKTsKKyAgICAgICAgICAgIGRzLnJlY2VpdmUocmVjZWl2ZSk7CisgICAgICAgICAgICBkcy5jbG9zZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgImNvbm5lY3QvZGlzY29ubmVjdC9jb25uZWN0IC0gV3Jvbmcgc2l6ZSBkYXRhIHJlY2VpdmVkOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyByZWNlaXZlLmdldExlbmd0aCgpLAorICAgICAgICAgICAgICAgICAgICByZWNlaXZlLmdldExlbmd0aCgpID09IHNlbmRCeXRlcy5sZW5ndGgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiY29ubmVjdC9kaXNjb25uZWN0L2Nvbm5lY3QgLSBXcm9uZyBkYXRhIHJlY2VpdmVkIgorICAgICAgICAgICAgICAgICAgICArIG5ldyBTdHJpbmcocmVjZWl2ZS5nZXREYXRhKCksIDAsIHJlY2VpdmUuZ2V0TGVuZ3RoKCkpCisgICAgICAgICAgICAgICAgICAgICsgIjoiICsgbmV3IFN0cmluZyhzZW5kQnl0ZXMpLCBuZXcgU3RyaW5nKAorICAgICAgICAgICAgICAgICAgICByZWNlaXZlLmdldERhdGEoKSwgMCwgcmVjZWl2ZS5nZXRMZW5ndGgoKSkKKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhuZXcgU3RyaW5nKHNlbmRCeXRlcykpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImNvbm5lY3QvZGlzY29ubmVjdC9jb25uZWN0IC0gV3JvbmcgcmVjZWl2ZXI6IgorICAgICAgICAgICAgICAgICAgICArIHJlY2VpdmUuZ2V0QWRkcmVzcygpICsgIjoiICsgbG9jYWxIb3N0LCByZWNlaXZlCisgICAgICAgICAgICAgICAgICAgIC5nZXRBZGRyZXNzKCkuZXF1YWxzKGxvY2FsSG9zdCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgKKyAgICAgICAgICAgICAgICAgICAgIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIHdoZW4gc2VuZGluZyBkYXRhIG9uIGRncmFtIGNvbm5lY3RlZCBhdCBuYXRpdmUgbGV2ZWwgYWZ0ZXIgY29ubmVjdC9kaXNjb25uZWN0L2Nvbm5lY3Q6IgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgc2VydmVyLnN0b3BTZXJ2ZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHZhbGlkYXRlIHRoYXQgd2UgY2FuIGNvbm5lY3QvZGlzY29ubmVjdCB0aGVuIHNlbmQvcmVjdiB0byBhbnkgYWRkcmVzcworICAgICAgICBzZXJ2ZXIgPSBudWxsOworICAgICAgICBwb3J0cyA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnRzRm9yVURQKDMpOworICAgICAgICBzZXJ2ZXJQb3J0TnVtYmVyID0gcG9ydHNbMF07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbEhvc3QgPSBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKTsKKyAgICAgICAgICAgIERhdGFncmFtU29ja2V0IGRzID0gbmV3IERhdGFncmFtU29ja2V0KHBvcnRzWzFdKTsKKyAgICAgICAgICAgIERhdGFncmFtU29ja2V0IGRzMiA9IG5ldyBEYXRhZ3JhbVNvY2tldChwb3J0c1syXSk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2VydmVyID0gbmV3IERhdGFncmFtU2VydmVyKHNlcnZlclBvcnROdW1iZXIsIGxvY2FsSG9zdCk7CisgICAgICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAgICAgIkZhaWxlZCB0byBzZXQgdXAgZGF0YWdyYW0gc2VydmVyIGZvciBuYXRpdmUgY29ubmVjdGVkIERncmFtIHNvY2tldCB0ZXN0ICIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgcG9ydCA9IGRzLmdldExvY2FsUG9ydCgpOworICAgICAgICAgICAgZHMuY29ubmVjdChsb2NhbEhvc3QsIHNlcnZlclBvcnROdW1iZXIgKyAxKTsKKyAgICAgICAgICAgIGRzLmRpc2Nvbm5lY3QoKTsKKworICAgICAgICAgICAgYnl0ZVtdIHNlbmRCeXRlcyA9IHsgJ1QnLCAnZScsICdzJywgJ3QnLCAwIH07CisgICAgICAgICAgICBEYXRhZ3JhbVBhY2tldCBzZW5kID0gbmV3IERhdGFncmFtUGFja2V0KHNlbmRCeXRlcywKKyAgICAgICAgICAgICAgICAgICAgc2VuZEJ5dGVzLmxlbmd0aCwgbG9jYWxIb3N0LCBzZXJ2ZXJQb3J0TnVtYmVyKTsKKyAgICAgICAgICAgIGRzLnNlbmQoc2VuZCk7CisgICAgICAgICAgICBEYXRhZ3JhbVBhY2tldCByZWNlaXZlID0gbmV3IERhdGFncmFtUGFja2V0KG5ldyBieXRlWzIwXSwgMjApOworICAgICAgICAgICAgZHMuc2V0U29UaW1lb3V0KDIwMDApOworICAgICAgICAgICAgZHMucmVjZWl2ZShyZWNlaXZlKTsKKyAgICAgICAgICAgIGRzLmNsb3NlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJjb25uZWN0L2Rpc2Nvbm5lY3QgLSBXcm9uZyBzaXplIGRhdGEgcmVjZWl2ZWQ6ICIKKyAgICAgICAgICAgICAgICAgICAgKyByZWNlaXZlLmdldExlbmd0aCgpLAorICAgICAgICAgICAgICAgICAgICByZWNlaXZlLmdldExlbmd0aCgpID09IHNlbmRCeXRlcy5sZW5ndGgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiY29ubmVjdC9kaXNjb25uZWN0IC0gV3JvbmcgZGF0YSByZWNlaXZlZCIKKyAgICAgICAgICAgICAgICAgICAgKyBuZXcgU3RyaW5nKHJlY2VpdmUuZ2V0RGF0YSgpLCAwLCByZWNlaXZlLmdldExlbmd0aCgpKQorICAgICAgICAgICAgICAgICAgICArICI6IiArIG5ldyBTdHJpbmcoc2VuZEJ5dGVzKSwgbmV3IFN0cmluZygKKyAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZS5nZXREYXRhKCksIDAsIHJlY2VpdmUuZ2V0TGVuZ3RoKCkpCisgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMobmV3IFN0cmluZyhzZW5kQnl0ZXMpKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJjb25uZWN0L2Rpc2Nvbm5lY3QgLSBXcm9uZyByZWNlaXZlcjoiCisgICAgICAgICAgICAgICAgICAgICsgcmVjZWl2ZS5nZXRBZGRyZXNzKCkgKyAiOiIgKyBsb2NhbEhvc3QsIHJlY2VpdmUKKyAgICAgICAgICAgICAgICAgICAgLmdldEFkZHJlc3MoKS5lcXVhbHMobG9jYWxIb3N0KSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAiVW5leHBlY3RlZCBleGNlcHRpb24gd2hlbiBzZW5kaW5nIGRhdGEgb24gZGdyYW0gY29ubmVjdGVkIGF0IG5hdGl2ZSBsZXZlbCBhZnRlciBjb25uZWN0L2Rpc2Nvbm5lY3Q6IgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgc2VydmVyLnN0b3BTZXJ2ZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHZhbGlkYXRlIHRoYXQgd2UgY2FuIGNvbm5lY3Qgb24gYW4gYWxscmVhZHkgY29ubmVjdGVkIHNvY2tldCBhbmQgdGhlbgorICAgICAgICAvLyBzZW5kL3JlY3YKKyAgICAgICAgc2VydmVyID0gbnVsbDsKKyAgICAgICAgcG9ydHMgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0c0ZvclVEUCgzKTsKKyAgICAgICAgc2VydmVyUG9ydE51bWJlciA9IHBvcnRzWzBdOworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW5ldEFkZHJlc3MgbG9jYWxIb3N0ID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCk7CisgICAgICAgICAgICBEYXRhZ3JhbVNvY2tldCBkcyA9IG5ldyBEYXRhZ3JhbVNvY2tldChwb3J0c1sxXSk7CisgICAgICAgICAgICBEYXRhZ3JhbVNvY2tldCBkczIgPSBuZXcgRGF0YWdyYW1Tb2NrZXQocG9ydHNbMl0pOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHNlcnZlciA9IG5ldyBEYXRhZ3JhbVNlcnZlcihzZXJ2ZXJQb3J0TnVtYmVyLCBsb2NhbEhvc3QpOworICAgICAgICAgICAgICAgIHNlcnZlci5zdGFydCgpOworICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxMDAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgKKyAgICAgICAgICAgICAgICAgICAgICAgICJGYWlsZWQgdG8gc2V0IHVwIGRhdGFncmFtIHNlcnZlciBmb3IgbmF0aXZlIGNvbm5lY3RlZCBEZ3JhbSBzb2NrZXQgdGVzdCAiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IHBvcnQgPSBkcy5nZXRMb2NhbFBvcnQoKTsKKyAgICAgICAgICAgIGRzLmNvbm5lY3QobG9jYWxIb3N0LCBzZXJ2ZXJQb3J0TnVtYmVyICsgMSk7CisgICAgICAgICAgICBkcy5jb25uZWN0KGxvY2FsSG9zdCwgc2VydmVyUG9ydE51bWJlcik7CisKKyAgICAgICAgICAgIGJ5dGVbXSBzZW5kQnl0ZXMgPSB7ICdUJywgJ2UnLCAncycsICd0JywgMCB9OworICAgICAgICAgICAgRGF0YWdyYW1QYWNrZXQgc2VuZCA9IG5ldyBEYXRhZ3JhbVBhY2tldChzZW5kQnl0ZXMsCisgICAgICAgICAgICAgICAgICAgIHNlbmRCeXRlcy5sZW5ndGgpOworICAgICAgICAgICAgZHMuc2VuZChzZW5kKTsKKyAgICAgICAgICAgIERhdGFncmFtUGFja2V0IHJlY2VpdmUgPSBuZXcgRGF0YWdyYW1QYWNrZXQobmV3IGJ5dGVbMjBdLCAyMCk7CisgICAgICAgICAgICBkcy5zZXRTb1RpbWVvdXQoMjAwMCk7CisgICAgICAgICAgICBkcy5yZWNlaXZlKHJlY2VpdmUpOworICAgICAgICAgICAgZHMuY2xvc2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImNvbm5lY3QvY29ubmVjdCAtIFdyb25nIHNpemUgZGF0YSByZWNlaXZlZDogIgorICAgICAgICAgICAgICAgICAgICArIHJlY2VpdmUuZ2V0TGVuZ3RoKCksCisgICAgICAgICAgICAgICAgICAgIHJlY2VpdmUuZ2V0TGVuZ3RoKCkgPT0gc2VuZEJ5dGVzLmxlbmd0aCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJjb25uZWN0L2Nvbm5lY3QgLSBXcm9uZyBkYXRhIHJlY2VpdmVkIgorICAgICAgICAgICAgICAgICAgICArIG5ldyBTdHJpbmcocmVjZWl2ZS5nZXREYXRhKCksIDAsIHJlY2VpdmUuZ2V0TGVuZ3RoKCkpCisgICAgICAgICAgICAgICAgICAgICsgIjoiICsgbmV3IFN0cmluZyhzZW5kQnl0ZXMpLCBuZXcgU3RyaW5nKAorICAgICAgICAgICAgICAgICAgICByZWNlaXZlLmdldERhdGEoKSwgMCwgcmVjZWl2ZS5nZXRMZW5ndGgoKSkKKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhuZXcgU3RyaW5nKHNlbmRCeXRlcykpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImNvbm5lY3QvY29ubmVjdCAtIFdyb25nIHJlY2VpdmVyOiIKKyAgICAgICAgICAgICAgICAgICAgKyByZWNlaXZlLmdldEFkZHJlc3MoKSArICI6IiArIGxvY2FsSG9zdCwgcmVjZWl2ZQorICAgICAgICAgICAgICAgICAgICAuZ2V0QWRkcmVzcygpLmVxdWFscyhsb2NhbEhvc3QpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoCisgICAgICAgICAgICAgICAgICAgICJVbmV4cGVjdGVkIGV4Y2VwdGlvbiB3aGVuIHNlbmRpbmcgZGF0YSBvbiBkZ3JhbSBjb25uZWN0ZWQgYXQgbmF0aXZlIGxldmVsIGFmdGVyIGNvbm5lY3QvY29ubmVjdDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgc2VydmVyLnN0b3BTZXJ2ZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3QgZm9yIHdoZW4gd2UgZmFpbCB0byBjb25uZWN0IGF0IHRoZSBuYXRpdmUgbGV2ZWwuIEV2ZW4gdGhvdWdoIHdlCisgICAgICAgIC8vIGZhaWwgYXQgdGhlIG5hdGl2ZSBsZXZlbCB0aGVyZSBpcyBubyB3YXkgdG8gcmV0dXJuIGFuIGV4Y2VwdGlvbiBzbworICAgICAgICAvLyB0aGVyZSBzaG91bGQgYmUgbm8gZXhjZXB0aW9uCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkcyA9IG5ldyBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldCgpOworICAgICAgICAgICAgYnl0ZVtdIGFkZHJlc3NCeXRlcyA9IHsgMCwgMCwgMCwgMCB9OworICAgICAgICAgICAgSW5ldEFkZHJlc3MgaW5ldEFkZHJlc3MgPSBJbmV0QWRkcmVzcy5nZXRCeUFkZHJlc3MoYWRkcmVzc0J5dGVzKTsKKyAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydEZvclVEUCgpOworICAgICAgICAgICAgZHMuY29ubmVjdChpbmV0QWRkcmVzcywgcG9ydE51bWJlcik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAiVW5leGNwZWN0ZWQgZXhjZXB0aW9uIHdoZW4gdHJ5aW5nIHRvIGNvbm5lY3QgYXQgbmF0aXZlIGxldmVsIHdpdGggYmFkIGFkZHJlc3MgZm9yIHNpZ25hdHVyZSB3aXRoIG5vIGV4Y2VwdGlvbiB0byBiZSByZXR1cm5lZDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgICAgICBTeXN0ZW0ub3V0CisgICAgICAgICAgICAgICAgICAgIC5wcmludGxuKCJSdW5uaW5nIHRlc3RfY29ubmVjdExqYXZhX25ldF9JbmV0QWRkcmVzc0koRGF0YWdyYW1Tb2NrZXRUZXN0KSB3aXRoIElQdjYgYWRkcmVzcyIpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBkcyA9IG5ldyBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldCgpOworICAgICAgICAgICAgICAgIGJ5dGVbXSBhZGRyZXNzQnl0ZXMgPSB7IDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwIH07CisgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MgaW5ldEFkZHJlc3MgPSBJbmV0QWRkcmVzcworICAgICAgICAgICAgICAgICAgICAgICAgLmdldEJ5QWRkcmVzcyhhZGRyZXNzQnl0ZXMpOworICAgICAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydEZvclVEUCgpOworICAgICAgICAgICAgICAgIGRzLmNvbm5lY3QoaW5ldEFkZHJlc3MsIHBvcnROdW1iZXIpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAgICAgIlVuZXhjcGVjdGVkIGV4Y2VwdGlvbiB3aGVuIHRyeWluZyB0byBjb25uZWN0IGF0IG5hdGl2ZSBsZXZlbCB3aXRoIGJhZCBJUHY2IGFkZHJlc3MgZm9yIHNpZ25hdHVyZSB3aXRoIG5vIGV4Y2VwdGlvbiB0byBiZSByZXR1cm5lZDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9kaXNjb25uZWN0KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgZHMgPSBuZXcgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQoKTsKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIGluZXRBZGRyZXNzID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCk7CisgICAgICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnRGb3JVRFAoKTsKKyAgICAgICAgICAgIGRzLmNvbm5lY3QoaW5ldEFkZHJlc3MsIHBvcnROdW1iZXIpOworICAgICAgICAgICAgZHMuZGlzY29ubmVjdCgpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiSW5jb3JyZWN0IEluZXRBZGRyZXNzIiwgZHMuZ2V0SW5ldEFkZHJlc3MoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBQb3J0IiwgLTEsIGRzLmdldFBvcnQoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgICAgIFN5c3RlbS5vdXQKKyAgICAgICAgICAgICAgICAgICAgLnByaW50bG4oIlJ1bm5pbmcgdGVzdF9kaXNjb25uZWN0KERhdGFncmFtU29ja2V0VGVzdCkgd2l0aCBJUHY2R2xvYmFsQWRkcmVzc0pjbDQ6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIFN1cHBvcnRfQ29uZmlndXJhdGlvbi5JUHY2R2xvYmFsQWRkcmVzc0pjbDQpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBkcyA9IG5ldyBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldCgpOworICAgICAgICAgICAgICAgIEluZXRBZGRyZXNzIGluZXRBZGRyZXNzID0gSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRCeU5hbWUoU3VwcG9ydF9Db25maWd1cmF0aW9uLklQdjZHbG9iYWxBZGRyZXNzSmNsNCk7CisgICAgICAgICAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0Rm9yVURQKCk7CisgICAgICAgICAgICAgICAgZHMuY29ubmVjdChpbmV0QWRkcmVzcywgcG9ydE51bWJlcik7CisgICAgICAgICAgICAgICAgZHMuZGlzY29ubmVjdCgpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCBJbmV0QWRkcmVzcyIsIGRzLmdldEluZXRBZGRyZXNzKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IFBvcnQiLCAtMSwgZHMuZ2V0UG9ydCgpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluZXRBZGRyZXNzKCkgeworICAgICAgICBWZWN0b3I8SW5ldEFkZHJlc3M+IGlhcyA9IG5ldyBWZWN0b3I8SW5ldEFkZHJlc3M+KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpYXMuYWRkKEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpKTsKKyAgICAgICAgICAgIGlhcy5hZGQoSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgICAgLmdldEJ5TmFtZShTdXBwb3J0X0NvbmZpZ3VyYXRpb24uSVB2Nkdsb2JhbEFkZHJlc3NKY2w0KSk7CisgICAgICAgICAgICBpYXMuYWRkKEluZXRBZGRyZXNzCisgICAgICAgICAgICAgICAgICAgICAgIC5nZXRCeU5hbWUoU3VwcG9ydF9Db25maWd1cmF0aW9uLkluZXRUZXN0QWRkcmVzczIpKTsKKyAgICAgICAgICAgIGlhcy5hZGQoSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgLmdldEJ5TmFtZShTdXBwb3J0X0NvbmZpZ3VyYXRpb24uSW5ldFRlc3RBZGRyZXNzMikpOworICAgICAgICAgICAgaWFzLmFkZChJbmV0QWRkcmVzcworICAgICAgICAgICAgICAgICAgICAuZ2V0QnlOYW1lKFN1cHBvcnRfQ29uZmlndXJhdGlvbi5JbmV0VGVzdElQKSk7CisgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIHdhcyB0aHJvd246ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgZm9yKEluZXRBZGRyZXNzIGlhOmlhcykgeworICAgICAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0Rm9yVURQKCk7CisgICAgICAgICAgICBEYXRhZ3JhbVNvY2tldCBkcyA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGRzID0gbmV3IERhdGFncmFtU29ja2V0KCk7CisgICAgICAgICAgICAgICAgZHMuY29ubmVjdChpYSwgcG9ydE51bWJlcik7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGlhLCBkcy5nZXRJbmV0QWRkcmVzcygpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIiIgKyBpYSwgaWEsIGRzLmdldEluZXRBZGRyZXNzKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgZHMuZGlzY29ubmVjdCgpOworICAgICAgICAgICAgICAgIGRzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbChuZXcgRGF0YWdyYW1Tb2NrZXQoKS5nZXRJbmV0QWRkcmVzcygpKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldExvY2FsUG9ydCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldC5nZXRMb2NhbFBvcnQoKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0Rm9yVURQKCk7CisgICAgICAgICAgICBkcyA9IG5ldyBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldChwb3J0TnVtYmVyKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBwb3J0IiwKKyAgICAgICAgICAgICAgICAgICAgZHMuZ2V0TG9jYWxQb3J0KCkgPT0gcG9ydE51bWJlcik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldExvY2FsQWRkcmVzcyA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFBvcnQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnRGb3JVRFAoKTsKKyAgICAgICAgICAgIERhdGFncmFtU29ja2V0IHRoZVNvY2tldCA9IG5ldyBEYXRhZ3JhbVNvY2tldChwb3J0TnVtYmVyKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiRXhwZWN0ZWQgLTEgZm9yIHJlbW90ZSBwb3J0IGFzIG5vdCBjb25uZWN0ZWQiLAorICAgICAgICAgICAgICAgICAgICAtMSwgdGhlU29ja2V0LmdldFBvcnQoKSk7CisKKyAgICAgICAgICAgIC8vIG5vdyBjb25uZWN0IHRoZSBzb2NrZXQgYW5kIHZhbGlkYXRlIHRoYXQgd2UgZ2V0IHRoZSByaWdodCBwb3J0CisgICAgICAgICAgICB0aGVTb2NrZXQuY29ubmVjdChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgcG9ydE51bWJlcik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRQb3J0IHJldHVybmVkIHdyb25nIHZhbHVlOiIgKyB0aGVTb2NrZXQuZ2V0UG9ydCgpCisgICAgICAgICAgICAgICAgICAgICsgIjpFeHBlY3RlZDoiICsgcG9ydE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0LmdldFBvcnQoKSA9PSBwb3J0TnVtYmVyKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uIGR1cmluZyBnZXRQb3J0IHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRSZWNlaXZlQnVmZmVyU2l6ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnRGb3JVRFAoKTsKKyAgICAgICAgZHMgPSBuZXcgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQocG9ydE51bWJlcik7CisgICAgICAgIGRzLnNldFJlY2VpdmVCdWZmZXJTaXplKDEzMCk7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBidWZmZXIgc2l6ZSIsIGRzLmdldFJlY2VpdmVCdWZmZXJTaXplKCkgPj0gMTMwKTsKKyAgICAgICAgZHMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRzLmdldFJlY2VpdmVCdWZmZXJTaXplKCk7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU29ja2V0RXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFNlbmRCdWZmZXJTaXplKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydEZvclVEUCgpOworICAgICAgICBkcyA9IG5ldyBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldChwb3J0TnVtYmVyKTsKKyAgICAgICAgZHMuc2V0U2VuZEJ1ZmZlclNpemUoMTM0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGJ1ZmZlciBzaXplIiwgZHMuZ2V0U2VuZEJ1ZmZlclNpemUoKSA+PSAxMzQpOworICAgICAgICBkcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZHMuZ2V0U2VuZEJ1ZmZlclNpemUoKTsKKyAgICAgICAgICAgIGZhaWwoIlNvY2tldEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChTb2NrZXRFeGNlcHRpb24gc2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0U29UaW1lb3V0X3NldFNvVGltZW91dCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUT0RPOiBhIHVzZWZ1bCB0ZXN0IHdvdWxkIGNoZWNrIHRoYXQgc2V0U29UaW1lb3V0IGFjdHVhbGx5IGNhdXNlcyB0aW1lb3V0cyEKKyAgICAgICAgRGF0YWdyYW1Tb2NrZXQgcyA9IG5ldyBEYXRhZ3JhbVNvY2tldCgpOworICAgICAgICBzLnNldFNvVGltZW91dCgxNTAwKTsKKyAgICAgICAgaW50IG1zID0gcy5nZXRTb1RpbWVvdXQoKTsKKyAgICAgICAgaWYgKG1zIDwgMTUwMC0xMCB8fCBtcyA+IDE1MDArMTApIHsKKyAgICAgICAgICAgIGZhaWwoInN1c3BpY2lvdXMgdGltZW91dDogIiArIG1zKTsKKyAgICAgICAgfQorICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmdldFNvVGltZW91dCgpOworICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5zZXRTb1RpbWVvdXQoMTAwMCk7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWNlaXZlTGphdmFfbmV0X0RhdGFncmFtUGFja2V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkCisgICAgICAgIC8vIGphdmEubmV0LkRhdGFncmFtU29ja2V0LnJlY2VpdmUoamF2YS5uZXQuRGF0YWdyYW1QYWNrZXQpCisKKyAgICAgICAgcmVjZWl2ZV9vdmVyc2l6ZV9qYXZhX25ldF9EYXRhZ3JhbVBhY2tldCgpOworICAgICAgICBmaW5hbCBpbnRbXSBwb3J0cyA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnRzRm9yVURQKDIpOworICAgICAgICBmaW5hbCBpbnQgcG9ydE51bWJlciA9IHBvcnRzWzBdOworCisgICAgICAgIGNsYXNzIFRlc3RER1JjdiBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbEhvc3QgPSBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKTsKKyAgICAgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgICAgICAgICAgICAgICBEYXRhZ3JhbVNvY2tldCBzZHMgPSBuZXcgRGF0YWdyYW1Tb2NrZXQocG9ydHNbMV0pOworICAgICAgICAgICAgICAgICAgICBEYXRhZ3JhbVBhY2tldCByZHAgPSBuZXcgRGF0YWdyYW1QYWNrZXQoIlRlc3QgU3RyaW5nIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRCeXRlcygpLCAxMSwgbG9jYWxIb3N0LCBwb3J0TnVtYmVyKTsKKyAgICAgICAgICAgICAgICAgICAgc2RzLnNlbmQocmRwKTsKKyAgICAgICAgICAgICAgICAgICAgc2RzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBUaHJlYWQobmV3IFRlc3RER1JjdigpLCAiREdTZW5kZXIiKS5zdGFydCgpOworICAgICAgICAgICAgZHMgPSBuZXcgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQocG9ydE51bWJlcik7CisgICAgICAgICAgICBkcy5zZXRTb1RpbWVvdXQoNjAwMCk7CisgICAgICAgICAgICBieXRlIHJidWZbXSA9IG5ldyBieXRlWzEwMDBdOworICAgICAgICAgICAgRGF0YWdyYW1QYWNrZXQgcmRwID0gbmV3IERhdGFncmFtUGFja2V0KHJidWYsIHJidWYubGVuZ3RoKTsKKyAgICAgICAgICAgIGRzLnJlY2VpdmUocmRwKTsKKyAgICAgICAgICAgIGRzLmNsb3NlKCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlNlbmQvUmVjZWl2ZSBmYWlsZWQgdG8gcmV0dXJuIGNvcnJlY3QgZGF0YTogIgorICAgICAgICAgICAgICAgICAgICArIG5ldyBTdHJpbmcocmJ1ZiwgMCwgMTEpLCAiVGVzdCBTdHJpbmciLCBuZXcgU3RyaW5nKHJidWYsIDAsIDExKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBkcy5jbG9zZSgpOworICAgICAgICB9CisgICAgICAgIERhdGFncmFtU29ja2V0IHNvY2tldCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBieXRlIHJidWZbXSA9IG5ldyBieXRlWzEwMDBdOworICAgICAgICAgICAgRGF0YWdyYW1QYWNrZXQgcmRwID0gbmV3IERhdGFncmFtUGFja2V0KHJidWYsIHJidWYubGVuZ3RoKTsKKyAgICAgICAgICAgIERhdGFncmFtQ2hhbm5lbCBjaGFubmVsID0gRGF0YWdyYW1DaGFubmVsLm9wZW4oKTsKKyAgICAgICAgICAgIGNoYW5uZWwuY29uZmlndXJlQmxvY2tpbmcoZmFsc2UpOworICAgICAgICAgICAgc29ja2V0ID0gY2hhbm5lbC5zb2NrZXQoKTsKKyAgICAgICAgICAgIHNvY2tldC5yZWNlaXZlKHJkcCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRzID0gbmV3IGphdmEubmV0LkRhdGFncmFtU29ja2V0KHBvcnROdW1iZXIpOworICAgICAgICAgICAgZHMuc2V0U29UaW1lb3V0KDEwMDApOworICAgICAgICAgICAgYnl0ZSByYnVmW10gPSBuZXcgYnl0ZVsxMDAwXTsKKyAgICAgICAgICAgIERhdGFncmFtUGFja2V0IHJkcCA9IG5ldyBEYXRhZ3JhbVBhY2tldChyYnVmLCByYnVmLmxlbmd0aCk7CisgICAgICAgICAgICBkcy5yZWNlaXZlKHJkcCk7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRUaW1lb3V0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFNvY2tldFRpbWVvdXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGRzLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBpbnRlcnJ1cHRlZCA9IGZhbHNlOworICAgICAgICBmaW5hbCBEYXRhZ3JhbVNvY2tldCBkcyA9IG5ldyBEYXRhZ3JhbVNvY2tldCgpOworICAgICAgICBkcy5zZXRTb1RpbWVvdXQoMTIwMDApOworICAgICAgICBSdW5uYWJsZSBydW5uYWJsZSA9IG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBkcy5yZWNlaXZlKG5ldyBEYXRhZ3JhbVBhY2tldChuZXcgYnl0ZVsxXSwgMSkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBpbnRlcnJ1cHRlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgVGhyZWFkIHRocmVhZCA9IG5ldyBUaHJlYWQocnVubmFibGUsICJEYXRhZ3JhbVNvY2tldC5yZWNlaXZlMSIpOworICAgICAgICB0aHJlYWQuc3RhcnQoKTsKKyAgICAgICAgZG8geworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDUwMCk7CisgICAgICAgIH0gd2hpbGUgKCF0aHJlYWQuaXNBbGl2ZSgpKTsKKyAgICAgICAgZHMuY2xvc2UoKTsKKyAgICAgICAgaW50IGMgPSAwOworICAgICAgICBkbyB7CisgICAgICAgICAgICBUaHJlYWQuc2xlZXAoNTAwKTsKKyAgICAgICAgICAgIGlmIChpbnRlcnJ1cHRlZCkgeworICAgICAgICAgICAgICAgIGZhaWwoInJlY2VpdmVkIGludGVycnVwdCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCsrYyA+IDQpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJyZWFkIGNhbGwgZGlkIG5vdCBleGl0Iik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gd2hpbGUgKHRocmVhZC5pc0FsaXZlKCkpOworCisgICAgICAgIGludGVycnVwdGVkID0gZmFsc2U7CisgICAgICAgIGZpbmFsIGludCBwb3J0TnVtID0gcG9ydHNbMF07CisgICAgICAgIGZpbmFsIERhdGFncmFtU29ja2V0IGRzMiA9IG5ldyBEYXRhZ3JhbVNvY2tldChwb3J0c1sxXSk7CisgICAgICAgIGRzMi5zZXRTb1RpbWVvdXQoMTIwMDApOworICAgICAgICBSdW5uYWJsZSBydW5uYWJsZTIgPSBuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZHMyLnJlY2VpdmUobmV3IERhdGFncmFtUGFja2V0KG5ldyBieXRlWzFdLCAxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBwb3J0TnVtKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGludGVycnVwdGVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBUaHJlYWQgdGhyZWFkMiA9IG5ldyBUaHJlYWQocnVubmFibGUyLCAiRGF0YWdyYW1Tb2NrZXQucmVjZWl2ZTIiKTsKKyAgICAgICAgdGhyZWFkMi5zdGFydCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCg1MDApOworICAgICAgICAgICAgfSB3aGlsZSAoIXRocmVhZDIuaXNBbGl2ZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaWdub3JlZCkgeworICAgICAgICB9CisgICAgICAgIGRzMi5jbG9zZSgpOworICAgICAgICBpbnQgYzIgPSAwOworICAgICAgICBkbyB7CisgICAgICAgICAgICBUaHJlYWQuc2xlZXAoNTAwKTsKKyAgICAgICAgICAgIGlmIChpbnRlcnJ1cHRlZCkgeworICAgICAgICAgICAgICAgIGZhaWwoInJlY2VpdmUyIHdhcyBpbnRlcnJ1cHRlZCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCsrYzIgPiA0KSB7CisgICAgICAgICAgICAgICAgZmFpbCgicmVhZDIgY2FsbCBkaWQgbm90IGV4aXQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSB3aGlsZSAodGhyZWFkMi5pc0FsaXZlKCkpOworCisgICAgICAgIGludGVycnVwdGVkID0gZmFsc2U7CisgICAgICAgIERhdGFncmFtU29ja2V0IGRzMyA9IG5ldyBEYXRhZ3JhbVNvY2tldCgpOworICAgICAgICBkczMuc2V0U29UaW1lb3V0KDUwMCk7CisgICAgICAgIERhdGUgc3RhcnQgPSBuZXcgRGF0ZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZHMzLnJlY2VpdmUobmV3IERhdGFncmFtUGFja2V0KG5ldyBieXRlWzFdLCAxKSk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaW50ZXJydXB0ZWQgPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGRzMy5jbG9zZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJyZWNlaXZlIG5vdCBpbnRlcnJ1cHRlZCIsIGludGVycnVwdGVkKTsKKyAgICAgICAgaW50IGRlbGF5ID0gKGludCkgKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gc3RhcnQuZ2V0VGltZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGltZW91dCB0b28gc29vbjogIiArIGRlbGF5LCBkZWxheSA+PSA0OTApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2VuZExqYXZhX25ldF9EYXRhZ3JhbVBhY2tldCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZAorICAgICAgICAvLyBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldC5zZW5kKGphdmEubmV0LkRhdGFncmFtUGFja2V0KQorICAgICAgICBpbnRbXSBwb3J0cyA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnRzRm9yVURQKDIpOworICAgICAgICBmaW5hbCBpbnQgcG9ydE51bWJlciA9IHBvcnRzWzBdOworCisgICAgICAgIGNsYXNzIFRlc3RER1NlbmQgaW1wbGVtZW50cyBSdW5uYWJsZSB7CisgICAgICAgICAgICBUaHJlYWQgcFRocmVhZDsKKworICAgICAgICAgICAgcHVibGljIFRlc3RER1NlbmQoVGhyZWFkIHQpIHsKKyAgICAgICAgICAgICAgICBwVGhyZWFkID0gdDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSByYnVmID0gbmV3IGJ5dGVbMTAwMF07CisKKyAgICAgICAgICAgICAgICAgICAgc2RzID0gbmV3IERhdGFncmFtU29ja2V0KHBvcnROdW1iZXIpOworICAgICAgICAgICAgICAgICAgICBEYXRhZ3JhbVBhY2tldCBzZHAgPSBuZXcgRGF0YWdyYW1QYWNrZXQocmJ1ZiwgcmJ1Zi5sZW5ndGgpOworICAgICAgICAgICAgICAgICAgICBzZHMuc2V0U29UaW1lb3V0KDYwMDApOworICAgICAgICAgICAgICAgICAgICBzZHMucmVjZWl2ZShzZHApOworICAgICAgICAgICAgICAgICAgICByZXR2YWwgPSBuZXcgU3RyaW5nKHJidWYsIDAsIHRlc3RTdHJpbmcubGVuZ3RoKCkpOworICAgICAgICAgICAgICAgICAgICBwVGhyZWFkLmludGVycnVwdCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUmVjdiBvcGVyYXRpb24gdGltZWQgb3V0Iik7CisgICAgICAgICAgICAgICAgICAgIHBUaHJlYWQuaW50ZXJydXB0KCk7CisgICAgICAgICAgICAgICAgICAgIGRzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJGYWlsZWQgdG8gZXN0YWJsaXNoIERncmFtIHNlcnZlcjogIiArIGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFRocmVhZChuZXcgVGVzdERHU2VuZChUaHJlYWQuY3VycmVudFRocmVhZCgpKSwgIkRHU2VydmVyIikKKyAgICAgICAgICAgICAgICAgICAgLnN0YXJ0KCk7CisgICAgICAgICAgICBkcyA9IG5ldyBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldChwb3J0c1sxXSk7CisgICAgICAgICAgICBkcCA9IG5ldyBEYXRhZ3JhbVBhY2tldCh0ZXN0U3RyaW5nLmdldEJ5dGVzKCksIHRlc3RTdHJpbmcubGVuZ3RoKCksCisgICAgICAgICAgICAgICAgICAgIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBwb3J0TnVtYmVyKTsKKyAgICAgICAgICAgIC8vIFdhaXQgdG8gYWxsb3cgc2VuZCB0byBvY2N1cgorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoNTAwKTsKKyAgICAgICAgICAgICAgICBkcy5zZW5kKGRwKTsKKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoNTAwMCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZHMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZGF0YSBzZW50OiAiICsgcmV0dmFsLCByZXR2YWwKKyAgICAgICAgICAgICAgICAgICAgICAgIC5lcXVhbHModGVzdFN0cmluZykpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBzZW5kIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZHMuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgIFNlY3VyaXR5TWFuYWdlciBzbSA9IG5ldyBTZWN1cml0eU1hbmFnZXIoKSB7CisKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihQZXJtaXNzaW9uIHBlcm0pIHsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHZvaWQgY2hlY2tNdWx0aWNhc3QoSW5ldEFkZHJlc3MgbWFkZHIpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHZvaWQgY2hlY2tDb25uZWN0KFN0cmluZyBob3N0LAorICAgICAgICAgICAgICAgICAgICBpbnQgcG9ydCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBkcyA9IG5ldyBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldChwb3J0c1sxXSk7CisgICAgICAgICAgICBkcCA9IG5ldyBEYXRhZ3JhbVBhY2tldCh0ZXN0U3RyaW5nLmdldEJ5dGVzKCksIHRlc3RTdHJpbmcubGVuZ3RoKCksCisgICAgICAgICAgICAgICAgICAgIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBwb3J0TnVtYmVyKTsKKworICAgICAgICAgICAgU2VjdXJpdHlNYW5hZ2VyIG9sZFNtID0gU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpOworICAgICAgICAgICAgU3lzdGVtLnNldFNlY3VyaXR5TWFuYWdlcihzbSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGRzLnNlbmQoZHApOworICAgICAgICAgICAgICAgIGZhaWwoIlNlY3VyaXR5RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uIik7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5zZXRTZWN1cml0eU1hbmFnZXIob2xkU20pOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiB3YXMgdGhyb3duOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgICovCisKKyAgICAgICAgRGF0YWdyYW1Tb2NrZXQgc29ja2V0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ5dGUgcmJ1ZltdID0gbmV3IGJ5dGVbMTAwMF07CisgICAgICAgICAgICBEYXRhZ3JhbVBhY2tldCByZHAgPSBuZXcgRGF0YWdyYW1QYWNrZXQocmJ1ZiwgcmJ1Zi5sZW5ndGgpOworICAgICAgICAgICAgU29ja2V0QWRkcmVzcyBhZGRyZXNzID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKHBvcnROdW1iZXIpOworICAgICAgICAgICAgRGF0YWdyYW1DaGFubmVsIGNoYW5uZWwgPSBEYXRhZ3JhbUNoYW5uZWwub3BlbigpOworICAgICAgICAgICAgY2hhbm5lbC5jb25maWd1cmVCbG9ja2luZyhmYWxzZSk7CisgICAgICAgICAgICBzb2NrZXQgPSBjaGFubmVsLnNvY2tldCgpOworICAgICAgICAgICAgc29ja2V0LnNlbmQocmRwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbiBpYm1lKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duOiAiICsgaW9lLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vUmVncmVzc2lvbiBmb3IgSEFSTU9OWS0xMTE4CisgICAgICAgIGNsYXNzIHRlc3REYXRhZ3JhbVNvY2tldCBleHRlbmRzIERhdGFncmFtU29ja2V0IHsKKyAgICAgICAgICAgIHB1YmxpYyB0ZXN0RGF0YWdyYW1Tb2NrZXQoRGF0YWdyYW1Tb2NrZXRJbXBsIGltcGwpeworICAgICAgICAgICAgICAgc3VwZXIoaW1wbCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY2xhc3MgdGVzdERhdGFncmFtU29ja2V0SW1wbCBleHRlbmRzIERhdGFncmFtU29ja2V0SW1wbCB7CisgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHt9CisgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBiaW5kKGludCBhcmcwLCBJbmV0QWRkcmVzcyBhcmcxKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHt9CisgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBzZW5kKERhdGFncmFtUGFja2V0IGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7fQorICAgICAgICAgICAgcHJvdGVjdGVkIGludCBwZWVrKEluZXRBZGRyZXNzIGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwcm90ZWN0ZWQgaW50IHBlZWtEYXRhKERhdGFncmFtUGFja2V0IGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZWNlaXZlKERhdGFncmFtUGFja2V0IGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7fQorICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgc2V0VFRMKGJ5dGUgYXJnMCkgdGhyb3dzIElPRXhjZXB0aW9uIHt9CisgICAgICAgICAgICBwcm90ZWN0ZWQgYnl0ZSBnZXRUVEwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgc2V0VGltZVRvTGl2ZShpbnQgYXJnMCkgdGhyb3dzIElPRXhjZXB0aW9uIHt9CisgICAgICAgICAgICBwcm90ZWN0ZWQgaW50IGdldFRpbWVUb0xpdmUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgam9pbihJbmV0QWRkcmVzcyBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24ge30KKyAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGxlYXZlKEluZXRBZGRyZXNzIGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7fQorICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgam9pbkdyb3VwKFNvY2tldEFkZHJlc3MgYXJnMCwgTmV0d29ya0ludGVyZmFjZSBhcmcxKSB0aHJvd3MgSU9FeGNlcHRpb24ge30KKyAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGxlYXZlR3JvdXAoU29ja2V0QWRkcmVzcyBhcmcwLCBOZXR3b3JrSW50ZXJmYWNlIGFyZzEpIHRocm93cyBJT0V4Y2VwdGlvbiB7fQorICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgY2xvc2UoKSB7fQorICAgICAgICAgICAgcHVibGljIHZvaWQgc2V0T3B0aW9uKGludCBhcmcwLCBPYmplY3QgYXJnMSkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7fQorICAgICAgICAgICAgcHVibGljIE9iamVjdCBnZXRPcHRpb24oaW50IGFyZzApIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIHNhID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCAwKTsKKyAgICAgICAgLy9ubyBleGNlcHRpb24gZXhwZWN0ZWQgZm9yIG5leHQgbGluZQorICAgICAgICBuZXcgdGVzdERhdGFncmFtU29ja2V0KG5ldyB0ZXN0RGF0YWdyYW1Tb2NrZXRJbXBsKCkpLnNlbmQobmV3IERhdGFncmFtUGFja2V0KG5ldyBieXRlWzI3Ml0sIDMsIHNhKSk7CisKKyAgICAgICAgLy8gUmVncmVzc2lvbiB0ZXN0IGZvciBIYXJtb255LTI5MzgKKyAgICAgICAgSW5ldEFkZHJlc3MgaSA9IEluZXRBZGRyZXNzLmdldEJ5TmFtZSgiMTI3LjAuMC4xIik7CisgICAgICAgIERhdGFncmFtU29ja2V0IGQgPSBuZXcgRGF0YWdyYW1Tb2NrZXQoMCwgaSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkLnNlbmQobmV3IERhdGFncmFtUGFja2V0KG5ldyBieXRlW10geyAxIH0sIDEpKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOUEUuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZC5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRTZW5kQnVmZmVyU2l6ZUkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0Rm9yVURQKCk7CisgICAgICAgIGRzID0gbmV3IGphdmEubmV0LkRhdGFncmFtU29ja2V0KHBvcnROdW1iZXIpOworICAgICAgICBkcy5zZXRTZW5kQnVmZmVyU2l6ZSgxMzQpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgYnVmZmVyIHNpemUiLCBkcy5nZXRTZW5kQnVmZmVyU2l6ZSgpID49IDEzNCk7CisgICAgICAgIGRzLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkcy5zZXRTZW5kQnVmZmVyU2l6ZSgxKTsKKyAgICAgICAgICAgIGZhaWwoIlNvY2tldEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChTb2NrZXRFeGNlcHRpb24gc2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0UmVjZWl2ZUJ1ZmZlclNpemVJKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydEZvclVEUCgpOworICAgICAgICBkcyA9IG5ldyBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldChwb3J0TnVtYmVyKTsKKyAgICAgICAgZHMuc2V0UmVjZWl2ZUJ1ZmZlclNpemUoMTMwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGJ1ZmZlciBzaXplIiwgZHMuZ2V0UmVjZWl2ZUJ1ZmZlclNpemUoKSA+PSAxMzApOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkcy5zZXRSZWNlaXZlQnVmZmVyU2l6ZSgwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZHMuc2V0UmVjZWl2ZUJ1ZmZlclNpemUoLTEpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGRzLmNsb3NlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRzLnNldFJlY2VpdmVCdWZmZXJTaXplKDEpOworICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX25ldF9EYXRhZ3JhbVNvY2tldEltcGwoKSB7CisgICAgICAgIGNsYXNzIHRlc3REYXRhZ3JhbVNvY2tldCBleHRlbmRzIERhdGFncmFtU29ja2V0IHsKKyAgICAgICAgICAgIHB1YmxpYyB0ZXN0RGF0YWdyYW1Tb2NrZXQoRGF0YWdyYW1Tb2NrZXRJbXBsIGltcGwpeworICAgICAgICAgICAgICAgc3VwZXIoaW1wbCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IHRlc3REYXRhZ3JhbVNvY2tldCgoRGF0YWdyYW1Tb2NrZXRJbXBsKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoImV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX25ldF9Tb2NrZXRBZGRyZXNzKCkgeworICAgICAgICBjbGFzcyBteVNvY2tldEFkZHJlc3MgZXh0ZW5kcyBTb2NrZXRBZGRyZXNzIHsKKworICAgICAgICAgICAgcHVibGljIG15U29ja2V0QWRkcmVzcygpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydEZvclVEUCgpOworICAgICAgICAgICAgICAgIGRzID0gbmV3IGphdmEubmV0LkRhdGFncmFtU29ja2V0KG5ldyBJbmV0U29ja2V0QWRkcmVzcygKKyAgICAgICAgICAgICAgICAgICAgICAgIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBwb3J0TnVtYmVyKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShkcy5nZXRCcm9hZGNhc3QoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQ3JlYXRlZCBzb2NrZXQgd2l0aCBpbmNvcnJlY3QgcG9ydCIsIGRzCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TG9jYWxQb3J0KCkgPT0gcG9ydE51bWJlcik7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQ3JlYXRlZCBzb2NrZXQgd2l0aCBpbmNvcnJlY3QgYWRkcmVzcyIsIGRzCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TG9jYWxBZGRyZXNzKCkuZXF1YWxzKEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpKSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIkNvdWxkIG5vdCBjcmVhdGUgRGF0YWdyYW1Tb2NrZXQgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydEZvclVEUCgpOworICAgICAgICAgICAgICAgIGRzID0gbmV3IGphdmEubmV0LkRhdGFncmFtU29ja2V0KG5ldyBteVNvY2tldEFkZHJlc3MoKSk7CisgICAgICAgICAgICAgICAgZmFpbCgKKyAgICAgICAgICAgICAgICAgICAgICAgICJObyBleGNlcHRpb24gd2hlbiBjb25zdHVjdGluZyBkYXRhZ3JhbVNvY2tldCB3aXRoIHVuc3VwcG9ydGVkIFNvY2tldEFkZHJlc3MgdHlwZSIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy9yZWdyZXNzaW9uIGZvciBIYXJtb255LTg5NAorICAgICAgICAgICAgZHMgPSBuZXcgRGF0YWdyYW1Tb2NrZXQoKFNvY2tldEFkZHJlc3MpbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGRzLmdldEJyb2FkY2FzdCgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAidW5leHBlY3RlZCBleGNlcHRpb24gd2hlbiBkYXRhZ3JhbVNvY2tldCBTb2NrZXRBZGRyZXNzIGNvbnN0cnVjdG9yIHRlc3QiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgIFNlY3VyaXR5TWFuYWdlciBzbSA9IG5ldyBTZWN1cml0eU1hbmFnZXIoKSB7CisKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihQZXJtaXNzaW9uIHBlcm0pIHsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHZvaWQgY2hlY2tMaXN0ZW4oaW50IHBvcnQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBTZWN1cml0eU1hbmFnZXIgb2xkU20gPSBTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCk7CisgICAgICAgIFN5c3RlbS5zZXRTZWN1cml0eU1hbmFnZXIoc20pOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IERhdGFncmFtU29ja2V0KG5ldyBJbmV0U29ja2V0QWRkcmVzcygKKyAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIDEpKTsKKyAgICAgICAgICAgIGZhaWwoIlNlY3VyaXR5RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5rbm93bkhvc3RFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIFN5c3RlbS5zZXRTZWN1cml0eU1hbmFnZXIob2xkU20pOworICAgICAgICB9CisgICAgICAgICovCisKKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgaXNhID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzYSA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcygKKyAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIDEpOworICAgICAgICB9IGNhdGNoIChVbmtub3duSG9zdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmtub3duSG9zdEV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9iaW5kTGphdmFfbmV0X1NvY2tldEFkZHJlc3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaW50W10gcG9ydHMgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0c0ZvclVEUCgzKTsKKyAgICAgICAgaW50IHNlcnZlclBvcnROdW1iZXIgPSBwb3J0c1sxXTsKKworICAgICAgICAvLyBub3cgY3JlYXRlIGEgc29ja2V0IHRoYXQgaXMgbm90IGJvdW5kIGFuZCB0aGVuIGJpbmQgaXQKKyAgICAgICAgSW5ldEFkZHJlc3MgbG9jYWxIb3N0ID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCk7CisgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIGxvY2FsQWRkcmVzczEgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MobG9jYWxIb3N0LCBwb3J0c1swXSk7CisgICAgICAgIERhdGFncmFtU29ja2V0IHRoZVNvY2tldCA9IG5ldyBEYXRhZ3JhbVNvY2tldChsb2NhbEFkZHJlc3MxKTsKKworICAgICAgICAvLyB2YWxpZGF0ZSB0aGF0IHRoZSBsb2NhbFNvY2tldEFkZHJlc3MgcmVmbGVjdHMgdGhlIGFkZHJlc3Mgd2UgYm91bmQgdG8KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxvY2FsQWRkcmVzczEsIHRoZVNvY2tldC5nZXRMb2NhbFNvY2tldEFkZHJlc3MoKSk7CisKKyAgICAgICAgLy8gbm93IG1ha2Ugc3VyZSB0aGF0IGRhdGFncmFtcyBzZW50IGZyb20gdGhpcyBzb2NrZXQgYXBwZWFyIHRvIGNvbWUKKyAgICAgICAgLy8gZnJvbSB0aGUgYWRkcmVzcyB3ZSBib3VuZCB0bworICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBsb2NhbEFkZHJlc3MyID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKGxvY2FsSG9zdCwgcG9ydHNbMl0pOworICAgICAgICBEYXRhZ3JhbVNvY2tldCBkcyA9IG5ldyBEYXRhZ3JhbVNvY2tldCgoU29ja2V0QWRkcmVzcykgbnVsbCk7CisgICAgICAgIGRzLmJpbmQobG9jYWxBZGRyZXNzMik7CisKKyAgICAgICAgRGF0YWdyYW1TZXJ2ZXIgc2VydmVyID0gbmV3IERhdGFncmFtU2VydmVyKHNlcnZlclBvcnROdW1iZXIsIGxvY2FsSG9zdCk7CisgICAgICAgIHNlcnZlci5zdGFydCgpOworICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisKKyAgICAgICAgZHMuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MobG9jYWxIb3N0LCBzZXJ2ZXJQb3J0TnVtYmVyKSk7CisKKyAgICAgICAgYnl0ZVtdIHNlbmRCeXRlcyA9IHsgJ1QnLCAnZScsICdzJywgJ3QnLCAwIH07CisgICAgICAgIERhdGFncmFtUGFja2V0IHNlbmQgPSBuZXcgRGF0YWdyYW1QYWNrZXQoc2VuZEJ5dGVzLCBzZW5kQnl0ZXMubGVuZ3RoKTsKKyAgICAgICAgZHMuc2VuZChzZW5kKTsKKyAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgICBkcy5jbG9zZSgpOworICAgICAgICAvLyBDaGVjayB0aGF0IHRoZSBhZGRyZXNzIGluIHRoZSBwYWNrZXQgbWF0Y2hlcyB0aGUgYm91bmQgYWRkcmVzcy4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxvY2FsQWRkcmVzczIsIHNlcnZlci5yZHAuZ2V0U29ja2V0QWRkcmVzcygpKTsKKworICAgICAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNlcnZlci5zdG9wU2VydmVyKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2JpbmRMamF2YV9uZXRfU29ja2V0QWRkcmVzc19udWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIHZhbGlkYXRlIGlmIHdlIHBhc3MgaW4gbnVsbCB0aGF0IGl0IHBpY2tzIGFuIGFkZHJlc3MgZm9yIHVzLgorICAgICAgICBEYXRhZ3JhbVNvY2tldCB0aGVTb2NrZXQgPSBuZXcgRGF0YWdyYW1Tb2NrZXQoKFNvY2tldEFkZHJlc3MpIG51bGwpOworICAgICAgICB0aGVTb2NrZXQuYmluZChudWxsKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0aGVTb2NrZXQuZ2V0TG9jYWxTb2NrZXRBZGRyZXNzKCkpOworICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2JpbmRMamF2YV9uZXRfU29ja2V0QWRkcmVzc19iYWRfYWRkcmVzcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBBZGRyZXNzIHdlIGNhbm5vdCBiaW5kIHRvCisgICAgICAgIERhdGFncmFtU29ja2V0IHRoZVNvY2tldCA9IG5ldyBEYXRhZ3JhbVNvY2tldCgoU29ja2V0QWRkcmVzcykgbnVsbCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbmV0QWRkcmVzcyBiYWRBZGRyZXNzID0gSW5ldEFkZHJlc3MuZ2V0QnlBZGRyZXNzKFN1cHBvcnRfQ29uZmlndXJhdGlvbi5ub25Mb2NhbEFkZHJlc3NCeXRlcyk7CisgICAgICAgICAgICB0aGVTb2NrZXQuYmluZChuZXcgSW5ldFNvY2tldEFkZHJlc3MoYmFkQWRkcmVzcywgU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydEZvclVEUCgpKSk7CisgICAgICAgICAgICBmYWlsKCJObyBleGNlcHRpb24gd2hlbiBiaW5kaW5nIHRvIGJhZCBhZGRyZXNzIik7CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYmluZExqYXZhX25ldF9Tb2NrZXRBZGRyZXNzX2FkZHJlc3NfaW5fdXNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIEFkZHJlc3MgdGhhdCB3ZSBoYXZlIGFscmVhZHkgYm91bmQgdG8KKyAgICAgICAgaW50W10gcG9ydHMgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0c0ZvclVEUCgyKTsKKyAgICAgICAgRGF0YWdyYW1Tb2NrZXQgdGhlU29ja2V0MSA9IG5ldyBEYXRhZ3JhbVNvY2tldCgoU29ja2V0QWRkcmVzcykgbnVsbCk7CisgICAgICAgIERhdGFncmFtU29ja2V0IHRoZVNvY2tldDIgPSBuZXcgRGF0YWdyYW1Tb2NrZXQocG9ydHNbMF0pOworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgdGhlQWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgcG9ydHNbMV0pOworICAgICAgICAgICAgdGhlU29ja2V0MS5iaW5kKHRoZUFkZHJlc3MpOworICAgICAgICAgICAgdGhlU29ja2V0Mi5iaW5kKHRoZUFkZHJlc3MpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhjZXB0aW9uIGJpbmRpbmcgdG8gYWRkcmVzcyB0aGF0IGlzIG5vdCBhdmFpbGFibGUiKTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdGhlU29ja2V0MS5jbG9zZSgpOworICAgICAgICB0aGVTb2NrZXQyLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9iaW5kTGphdmFfbmV0X1NvY2tldEFkZHJlc3NfdW5zdXBwb3J0ZWRfYWRkcmVzc190eXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNsYXNzIG15U29ja2V0QWRkcmVzcyBleHRlbmRzIFNvY2tldEFkZHJlc3MgeworICAgICAgICAgICAgcHVibGljIG15U29ja2V0QWRkcmVzcygpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHVuc3VwcG9ydGVkIFNvY2tldEFkZHJlc3Mgc3ViY2xhc3MKKyAgICAgICAgRGF0YWdyYW1Tb2NrZXQgdGhlU29ja2V0ID0gbmV3IERhdGFncmFtU29ja2V0KChTb2NrZXRBZGRyZXNzKSBudWxsKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoZVNvY2tldC5iaW5kKG5ldyBteVNvY2tldEFkZHJlc3MoKSk7CisgICAgICAgICAgICBmYWlsKCJObyBleGNlcHRpb24gd2hlbiBiaW5kaW5nIHVzaW5nIHVuc3VwcG9ydGVkIFNvY2tldEFkZHJlc3Mgc3ViY2xhc3MiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25uZWN0TGphdmFfbmV0X1NvY2tldEFkZHJlc3MoKSB7CisKKyAgICAgICAgLy8gdmFsaWRhdGUgdGhhdCB3ZSBnZXQgdGhlIFBvcnRVbnJlYWNoYWJsZSBleGNlcHRpb24gaWYgd2UgdHJ5IHRvCisgICAgICAgIC8vIHNlbmQgYSBkZ3JhbSB0byBhIHNlcnZlciB0aGF0IGlzIG5vdCBydW5uaW5nIGFuZCB0aGVuIGRvIGEgcmVjdgorICAgICAgICB0cnkgeworICAgICAgICAgICAgZHMgPSBuZXcgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQoKTsKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIGluZXRBZGRyZXNzID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCk7CisgICAgICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnRGb3JVRFAoKTsKKyAgICAgICAgICAgIGRzLmNvbm5lY3QobmV3IEluZXRTb2NrZXRBZGRyZXNzKGluZXRBZGRyZXNzLCBwb3J0TnVtYmVyKSk7CisgICAgICAgICAgICBEYXRhZ3JhbVBhY2tldCBzZW5kID0gbmV3IERhdGFncmFtUGFja2V0KG5ldyBieXRlWzEwXSwgMTApOworICAgICAgICAgICAgZHMuc2VuZChzZW5kKTsKKyAgICAgICAgICAgIERhdGFncmFtUGFja2V0IHJlY2VpdmUgPSBuZXcgRGF0YWdyYW1QYWNrZXQobmV3IGJ5dGVbMjBdLCAyMCk7CisgICAgICAgICAgICBkcy5zZXRTb1RpbWVvdXQoMTAwMDApOworICAgICAgICAgICAgZHMucmVjZWl2ZShyZWNlaXZlKTsKKyAgICAgICAgICAgIGRzLmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAiTm8gUG9ydFVucmVhY2hhYmxlRXhjZXB0aW9uIHdoZW4gY29ubmVjdGVkIGF0IG5hdGl2ZSBsZXZlbCBvbiByZWN2ICIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIldyb25nIGV4Y2VwdGlvbiB3aGVuIHRyeWluZyB0byBjb25uZWN0IGF0IG5hdGl2ZSBsZXZlbCBvbiByZWN2OiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgIChlIGluc3RhbmNlb2YgUG9ydFVucmVhY2hhYmxlRXhjZXB0aW9uKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZHMgPSBuZXcgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQoKTsKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIGluZXRBZGRyZXNzID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCk7CisgICAgICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnRGb3JVRFAoKTsKKworICAgICAgICAgICAgZHMuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MoImFzZGZhc2RmIiwgMSkpOworICAgICAgICAgICAgZHMuY2xvc2UoKTsKKyAgICAgICAgICAgIGZhaWwoIlNvY2tldEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJXcm9uZyBleGNlcHRpb24gd2hlbiB0cnlpbmcgdG8gY29ubmVjdCB0byB1bmtub3duIGhvc3Q6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgKGUgaW5zdGFuY2VvZiBTb2NrZXRFeGNlcHRpb24pKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHZhbGlkYXRlIHRoYXQgd2UgY2FuIHNlbmQvcmVjZWl2ZSB3aXRoIGRhdGFncmFtIHNvY2tldHMgY29ubmVjdGVkIGF0CisgICAgICAgIC8vIHRoZSBuYXRpdmUgbGV2ZWwKKyAgICAgICAgRGF0YWdyYW1TZXJ2ZXIgc2VydmVyID0gbnVsbDsKKyAgICAgICAgaW50W10gcG9ydHMgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0c0ZvclVEUCgzKTsKKyAgICAgICAgaW50IHNlcnZlclBvcnROdW1iZXIgPSBwb3J0c1swXTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIGxvY2FsSG9zdCA9IEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpOworICAgICAgICAgICAgRGF0YWdyYW1Tb2NrZXQgZHMgPSBuZXcgRGF0YWdyYW1Tb2NrZXQocG9ydHNbMV0pOworICAgICAgICAgICAgRGF0YWdyYW1Tb2NrZXQgZHMyID0gbmV3IERhdGFncmFtU29ja2V0KHBvcnRzWzJdKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgRGF0YWdyYW1TZXJ2ZXIoc2VydmVyUG9ydE51bWJlciwgbG9jYWxIb3N0KTsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIuc3RhcnQoKTsKKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoCisgICAgICAgICAgICAgICAgICAgICAgICAiRmFpbGVkIHRvIHNldCB1cCBkYXRhZ3JhbSBzZXJ2ZXIgZm9yIG5hdGl2ZSBjb25uZWN0ZWQgRGdyYW0gc29ja2V0IHRlc3QgIik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGludCBwb3J0ID0gZHMuZ2V0TG9jYWxQb3J0KCk7CisgICAgICAgICAgICBkcy5jb25uZWN0KG5ldyBJbmV0U29ja2V0QWRkcmVzcyhsb2NhbEhvc3QsIHNlcnZlclBvcnROdW1iZXIpKTsKKworICAgICAgICAgICAgYnl0ZVtdIHNlbmRCeXRlcyA9IHsgJ1QnLCAnZScsICdzJywgJ3QnLCAwIH07CisgICAgICAgICAgICBEYXRhZ3JhbVBhY2tldCBzZW5kID0gbmV3IERhdGFncmFtUGFja2V0KHNlbmRCeXRlcywKKyAgICAgICAgICAgICAgICAgICAgc2VuZEJ5dGVzLmxlbmd0aCk7CisgICAgICAgICAgICBkcy5zZW5kKHNlbmQpOworICAgICAgICAgICAgRGF0YWdyYW1QYWNrZXQgcmVjZWl2ZSA9IG5ldyBEYXRhZ3JhbVBhY2tldChuZXcgYnl0ZVsyMF0sIDIwKTsKKyAgICAgICAgICAgIGRzLnNldFNvVGltZW91dCgyMDAwKTsKKyAgICAgICAgICAgIGRzLnJlY2VpdmUocmVjZWl2ZSk7CisgICAgICAgICAgICBkcy5jbG9zZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3Jvbmcgc2l6ZSBkYXRhIHJlY2VpdmVkOiAiICsgcmVjZWl2ZS5nZXRMZW5ndGgoKSwKKyAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZS5nZXRMZW5ndGgoKSA9PSBzZW5kQnl0ZXMubGVuZ3RoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIldyb25nIGRhdGEgcmVjZWl2ZWQiCisgICAgICAgICAgICAgICAgICAgICsgbmV3IFN0cmluZyhyZWNlaXZlLmdldERhdGEoKSwgMCwgcmVjZWl2ZS5nZXRMZW5ndGgoKSkKKyAgICAgICAgICAgICAgICAgICAgKyAiOiIgKyBuZXcgU3RyaW5nKHNlbmRCeXRlcyksIG5ldyBTdHJpbmcoCisgICAgICAgICAgICAgICAgICAgIHJlY2VpdmUuZ2V0RGF0YSgpLCAwLCByZWNlaXZlLmdldExlbmd0aCgpKQorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKG5ldyBTdHJpbmcoc2VuZEJ5dGVzKSkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcmVjZWl2ZXI6IiArIHJlY2VpdmUuZ2V0QWRkcmVzcygpICsgIjoiCisgICAgICAgICAgICAgICAgICAgICsgbG9jYWxIb3N0LCByZWNlaXZlLmdldEFkZHJlc3MoKS5lcXVhbHMobG9jYWxIb3N0KSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAiVW5leHBlY3RlZCBleGNlcHRpb24gd2hlbiBzZW5kaW5nIGRhdGEgb24gZGdyYW0gY29ubmVjdGVkIGF0IG5hdGl2ZSBsZXZlbDoiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICBzZXJ2ZXIuc3RvcFNlcnZlcigpOworICAgICAgICB9CisKKyAgICAgICAgLy8gdmFsaWRhdGUgdGhhdCB3ZSBjYW4gZGlzY29ubmVjdAorICAgICAgICB0cnkgeworICAgICAgICAgICAgZHMgPSBuZXcgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQoKTsKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIGluZXRBZGRyZXNzID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCk7CisgICAgICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnRGb3JVRFAoKTsKKyAgICAgICAgICAgIGRzLmNvbm5lY3QobmV3IEluZXRTb2NrZXRBZGRyZXNzKGluZXRBZGRyZXNzLCBwb3J0TnVtYmVyKSk7CisgICAgICAgICAgICBkcy5kaXNjb25uZWN0KCk7CisgICAgICAgICAgICBkcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVW5leHBlY3RlZCBleGNlcHRpb24gd2hlbiB0cnlpbmcgdG8gY29ubmVjdCBhdCBuYXRpdmUiCisgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpLCAoZSBpbnN0YW5jZW9mIFBvcnRVbnJlYWNoYWJsZUV4Y2VwdGlvbikpOworICAgICAgICB9CisKKyAgICAgICAgLy8gdmFsaWRhdGUgdGhhdCBvbmNlIGNvbm5lY3RlZCB3ZSBjYW5ub3Qgc2VuZCB0byBhbm90aGVyIGFkZHJlc3MKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRzID0gbmV3IGphdmEubmV0LkRhdGFncmFtU29ja2V0KCk7CisgICAgICAgICAgICBJbmV0QWRkcmVzcyBpbmV0QWRkcmVzcyA9IEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpOworICAgICAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0Rm9yVURQKCk7CisgICAgICAgICAgICBkcy5jb25uZWN0KG5ldyBJbmV0U29ja2V0QWRkcmVzcyhpbmV0QWRkcmVzcywgcG9ydE51bWJlcikpOworICAgICAgICAgICAgRGF0YWdyYW1QYWNrZXQgc2VuZCA9IG5ldyBEYXRhZ3JhbVBhY2tldChuZXcgYnl0ZVsxMF0sIDEwLAorICAgICAgICAgICAgICAgICAgICBpbmV0QWRkcmVzcywgcG9ydE51bWJlciArIDEpOworICAgICAgICAgICAgZHMuc2VuZChzZW5kKTsKKyAgICAgICAgICAgIGRzLmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAiTm8gRXhjZXB0aW9uIHdoZW4gdHJ5aW5nIHRvIHNlbmQgdG8gYSBkaWZmZXJlbnQgYWRkcmVzcyBvbiBhIGNvbm5lY3RlZCBzb2NrZXQgIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiV3JvbmcgZXhjZXB0aW9uIHdoZW4gdHJ5aW5nIHRvIHNlbmQgdG8gYSBkaWZmZXJlbnQgYWRkcmVzcyBvbiBhIGNvbm5lY3RlZCBzb2NrZXQ6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgKGUgaW5zdGFuY2VvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24pKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHZhbGlkYXRlIHRoYXQgd2UgY2FuIGNvbm5lY3QsIHRoZW4gZGlzY29ubmVjdCwgdGhlbiBjb25uZWN0IHRoZW4KKyAgICAgICAgLy8gc2VuZC9yZWN2CisgICAgICAgIHNlcnZlciA9IG51bGw7CisgICAgICAgIHBvcnRzID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydHNGb3JVRFAoMyk7CisgICAgICAgIHNlcnZlclBvcnROdW1iZXIgPSBwb3J0c1swXTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIGxvY2FsSG9zdCA9IEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpOworICAgICAgICAgICAgRGF0YWdyYW1Tb2NrZXQgZHMgPSBuZXcgRGF0YWdyYW1Tb2NrZXQocG9ydHNbMV0pOworICAgICAgICAgICAgRGF0YWdyYW1Tb2NrZXQgZHMyID0gbmV3IERhdGFncmFtU29ja2V0KHBvcnRzWzJdKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgRGF0YWdyYW1TZXJ2ZXIoc2VydmVyUG9ydE51bWJlciwgbG9jYWxIb3N0KTsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIuc3RhcnQoKTsKKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoCisgICAgICAgICAgICAgICAgICAgICAgICAiRmFpbGVkIHRvIHNldCB1cCBkYXRhZ3JhbSBzZXJ2ZXIgZm9yIG5hdGl2ZSBjb25uZWN0ZWQgRGdyYW0gc29ja2V0IHRlc3QgIik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGludCBwb3J0ID0gZHMuZ2V0TG9jYWxQb3J0KCk7CisgICAgICAgICAgICBkcy5jb25uZWN0KG5ldyBJbmV0U29ja2V0QWRkcmVzcyhsb2NhbEhvc3QsIHNlcnZlclBvcnROdW1iZXIgKyAxKSk7CisgICAgICAgICAgICBkcy5kaXNjb25uZWN0KCk7CisgICAgICAgICAgICBkcy5jb25uZWN0KG5ldyBJbmV0U29ja2V0QWRkcmVzcyhsb2NhbEhvc3QsIHNlcnZlclBvcnROdW1iZXIpKTsKKworICAgICAgICAgICAgYnl0ZVtdIHNlbmRCeXRlcyA9IHsgJ1QnLCAnZScsICdzJywgJ3QnLCAwIH07CisgICAgICAgICAgICBEYXRhZ3JhbVBhY2tldCBzZW5kID0gbmV3IERhdGFncmFtUGFja2V0KHNlbmRCeXRlcywKKyAgICAgICAgICAgICAgICAgICAgc2VuZEJ5dGVzLmxlbmd0aCk7CisgICAgICAgICAgICBkcy5zZW5kKHNlbmQpOworICAgICAgICAgICAgRGF0YWdyYW1QYWNrZXQgcmVjZWl2ZSA9IG5ldyBEYXRhZ3JhbVBhY2tldChuZXcgYnl0ZVsyMF0sIDIwKTsKKyAgICAgICAgICAgIGRzLnNldFNvVGltZW91dCgyMDAwKTsKKyAgICAgICAgICAgIGRzLnJlY2VpdmUocmVjZWl2ZSk7CisgICAgICAgICAgICBkcy5jbG9zZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgImNvbm5lY3QvZGlzY29ubmVjdC9jb25uZWN0IC0gV3Jvbmcgc2l6ZSBkYXRhIHJlY2VpdmVkOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyByZWNlaXZlLmdldExlbmd0aCgpLAorICAgICAgICAgICAgICAgICAgICByZWNlaXZlLmdldExlbmd0aCgpID09IHNlbmRCeXRlcy5sZW5ndGgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiY29ubmVjdC9kaXNjb25uZWN0L2Nvbm5lY3QgLSBXcm9uZyBkYXRhIHJlY2VpdmVkIgorICAgICAgICAgICAgICAgICAgICArIG5ldyBTdHJpbmcocmVjZWl2ZS5nZXREYXRhKCksIDAsIHJlY2VpdmUuZ2V0TGVuZ3RoKCkpCisgICAgICAgICAgICAgICAgICAgICsgIjoiICsgbmV3IFN0cmluZyhzZW5kQnl0ZXMpLCBuZXcgU3RyaW5nKAorICAgICAgICAgICAgICAgICAgICByZWNlaXZlLmdldERhdGEoKSwgMCwgcmVjZWl2ZS5nZXRMZW5ndGgoKSkKKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhuZXcgU3RyaW5nKHNlbmRCeXRlcykpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImNvbm5lY3QvZGlzY29ubmVjdC9jb25uZWN0IC0gV3JvbmcgcmVjZWl2ZXI6IgorICAgICAgICAgICAgICAgICAgICArIHJlY2VpdmUuZ2V0QWRkcmVzcygpICsgIjoiICsgbG9jYWxIb3N0LCByZWNlaXZlCisgICAgICAgICAgICAgICAgICAgIC5nZXRBZGRyZXNzKCkuZXF1YWxzKGxvY2FsSG9zdCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgKKyAgICAgICAgICAgICAgICAgICAgIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIHdoZW4gc2VuZGluZyBkYXRhIG9uIGRncmFtIGNvbm5lY3RlZCBhdCBuYXRpdmUgbGV2ZWwgYWZ0ZXIgY29ubmVjdC9kaXNjb25uZWN0L2Nvbm5lY3Q6IgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgc2VydmVyLnN0b3BTZXJ2ZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHZhbGlkYXRlIHRoYXQgd2UgY2FuIGNvbm5lY3QvZGlzY29ubmVjdCB0aGVuIHNlbmQvcmVjdiB0byBhbnkgYWRkcmVzcworICAgICAgICBzZXJ2ZXIgPSBudWxsOworICAgICAgICBwb3J0cyA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnRzRm9yVURQKDMpOworICAgICAgICBzZXJ2ZXJQb3J0TnVtYmVyID0gcG9ydHNbMF07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbEhvc3QgPSBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKTsKKyAgICAgICAgICAgIERhdGFncmFtU29ja2V0IGRzID0gbmV3IERhdGFncmFtU29ja2V0KHBvcnRzWzFdKTsKKyAgICAgICAgICAgIERhdGFncmFtU29ja2V0IGRzMiA9IG5ldyBEYXRhZ3JhbVNvY2tldChwb3J0c1syXSk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2VydmVyID0gbmV3IERhdGFncmFtU2VydmVyKHNlcnZlclBvcnROdW1iZXIsIGxvY2FsSG9zdCk7CisgICAgICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAgICAgIkZhaWxlZCB0byBzZXQgdXAgZGF0YWdyYW0gc2VydmVyIGZvciBuYXRpdmUgY29ubmVjdGVkIERncmFtIHNvY2tldCB0ZXN0ICIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgcG9ydCA9IGRzLmdldExvY2FsUG9ydCgpOworICAgICAgICAgICAgZHMuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MobG9jYWxIb3N0LCBzZXJ2ZXJQb3J0TnVtYmVyICsgMSkpOworICAgICAgICAgICAgZHMuZGlzY29ubmVjdCgpOworCisgICAgICAgICAgICBieXRlW10gc2VuZEJ5dGVzID0geyAnVCcsICdlJywgJ3MnLCAndCcsIDAgfTsKKyAgICAgICAgICAgIERhdGFncmFtUGFja2V0IHNlbmQgPSBuZXcgRGF0YWdyYW1QYWNrZXQoc2VuZEJ5dGVzLAorICAgICAgICAgICAgICAgICAgICBzZW5kQnl0ZXMubGVuZ3RoLCBsb2NhbEhvc3QsIHNlcnZlclBvcnROdW1iZXIpOworICAgICAgICAgICAgZHMuc2VuZChzZW5kKTsKKyAgICAgICAgICAgIERhdGFncmFtUGFja2V0IHJlY2VpdmUgPSBuZXcgRGF0YWdyYW1QYWNrZXQobmV3IGJ5dGVbMjBdLCAyMCk7CisgICAgICAgICAgICBkcy5zZXRTb1RpbWVvdXQoMjAwMCk7CisgICAgICAgICAgICBkcy5yZWNlaXZlKHJlY2VpdmUpOworICAgICAgICAgICAgZHMuY2xvc2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImNvbm5lY3QvZGlzY29ubmVjdCAtIFdyb25nIHNpemUgZGF0YSByZWNlaXZlZDogIgorICAgICAgICAgICAgICAgICAgICArIHJlY2VpdmUuZ2V0TGVuZ3RoKCksCisgICAgICAgICAgICAgICAgICAgIHJlY2VpdmUuZ2V0TGVuZ3RoKCkgPT0gc2VuZEJ5dGVzLmxlbmd0aCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJjb25uZWN0L2Rpc2Nvbm5lY3QgLSBXcm9uZyBkYXRhIHJlY2VpdmVkIgorICAgICAgICAgICAgICAgICAgICArIG5ldyBTdHJpbmcocmVjZWl2ZS5nZXREYXRhKCksIDAsIHJlY2VpdmUuZ2V0TGVuZ3RoKCkpCisgICAgICAgICAgICAgICAgICAgICsgIjoiICsgbmV3IFN0cmluZyhzZW5kQnl0ZXMpLCBuZXcgU3RyaW5nKAorICAgICAgICAgICAgICAgICAgICByZWNlaXZlLmdldERhdGEoKSwgMCwgcmVjZWl2ZS5nZXRMZW5ndGgoKSkKKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhuZXcgU3RyaW5nKHNlbmRCeXRlcykpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImNvbm5lY3QvZGlzY29ubmVjdCAtIFdyb25nIHJlY2VpdmVyOiIKKyAgICAgICAgICAgICAgICAgICAgKyByZWNlaXZlLmdldEFkZHJlc3MoKSArICI6IiArIGxvY2FsSG9zdCwgcmVjZWl2ZQorICAgICAgICAgICAgICAgICAgICAuZ2V0QWRkcmVzcygpLmVxdWFscyhsb2NhbEhvc3QpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoCisgICAgICAgICAgICAgICAgICAgICJVbmV4cGVjdGVkIGV4Y2VwdGlvbiB3aGVuIHNlbmRpbmcgZGF0YSBvbiBkZ3JhbSBjb25uZWN0ZWQgYXQgbmF0aXZlIGxldmVsIGFmdGVyIGNvbm5lY3QvZGlzY29ubmVjdDoiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICBzZXJ2ZXIuc3RvcFNlcnZlcigpOworICAgICAgICB9CisKKyAgICAgICAgLy8gdmFsaWRhdGUgdGhhdCB3ZSBjYW4gY29ubmVjdCBvbiBhbiBhbGxyZWFkeSBjb25uZWN0ZWQgc29ja2V0IGFuZCB0aGVuCisgICAgICAgIC8vIHNlbmQvcmVjdgorICAgICAgICBzZXJ2ZXIgPSBudWxsOworICAgICAgICBwb3J0cyA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnRzRm9yVURQKDMpOworICAgICAgICBzZXJ2ZXJQb3J0TnVtYmVyID0gcG9ydHNbMF07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbEhvc3QgPSBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKTsKKyAgICAgICAgICAgIERhdGFncmFtU29ja2V0IGRzID0gbmV3IERhdGFncmFtU29ja2V0KHBvcnRzWzFdKTsKKyAgICAgICAgICAgIERhdGFncmFtU29ja2V0IGRzMiA9IG5ldyBEYXRhZ3JhbVNvY2tldChwb3J0c1syXSk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2VydmVyID0gbmV3IERhdGFncmFtU2VydmVyKHNlcnZlclBvcnROdW1iZXIsIGxvY2FsSG9zdCk7CisgICAgICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAgICAgIkZhaWxlZCB0byBzZXQgdXAgZGF0YWdyYW0gc2VydmVyIGZvciBuYXRpdmUgY29ubmVjdGVkIERncmFtIHNvY2tldCB0ZXN0ICIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgcG9ydCA9IGRzLmdldExvY2FsUG9ydCgpOworICAgICAgICAgICAgZHMuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MobG9jYWxIb3N0LCBzZXJ2ZXJQb3J0TnVtYmVyICsgMSkpOworICAgICAgICAgICAgZHMuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MobG9jYWxIb3N0LCBzZXJ2ZXJQb3J0TnVtYmVyKSk7CisKKyAgICAgICAgICAgIGJ5dGVbXSBzZW5kQnl0ZXMgPSB7ICdUJywgJ2UnLCAncycsICd0JywgMCB9OworICAgICAgICAgICAgRGF0YWdyYW1QYWNrZXQgc2VuZCA9IG5ldyBEYXRhZ3JhbVBhY2tldChzZW5kQnl0ZXMsCisgICAgICAgICAgICAgICAgICAgIHNlbmRCeXRlcy5sZW5ndGgpOworICAgICAgICAgICAgZHMuc2VuZChzZW5kKTsKKyAgICAgICAgICAgIERhdGFncmFtUGFja2V0IHJlY2VpdmUgPSBuZXcgRGF0YWdyYW1QYWNrZXQobmV3IGJ5dGVbMjBdLCAyMCk7CisgICAgICAgICAgICBkcy5zZXRTb1RpbWVvdXQoMjAwMCk7CisgICAgICAgICAgICBkcy5yZWNlaXZlKHJlY2VpdmUpOworICAgICAgICAgICAgZHMuY2xvc2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImNvbm5lY3QvY29ubmVjdCAtIFdyb25nIHNpemUgZGF0YSByZWNlaXZlZDogIgorICAgICAgICAgICAgICAgICAgICArIHJlY2VpdmUuZ2V0TGVuZ3RoKCksCisgICAgICAgICAgICAgICAgICAgIHJlY2VpdmUuZ2V0TGVuZ3RoKCkgPT0gc2VuZEJ5dGVzLmxlbmd0aCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJjb25uZWN0L2Nvbm5lY3QgLSBXcm9uZyBkYXRhIHJlY2VpdmVkIgorICAgICAgICAgICAgICAgICAgICArIG5ldyBTdHJpbmcocmVjZWl2ZS5nZXREYXRhKCksIDAsIHJlY2VpdmUuZ2V0TGVuZ3RoKCkpCisgICAgICAgICAgICAgICAgICAgICsgIjoiICsgbmV3IFN0cmluZyhzZW5kQnl0ZXMpLCBuZXcgU3RyaW5nKAorICAgICAgICAgICAgICAgICAgICByZWNlaXZlLmdldERhdGEoKSwgMCwgcmVjZWl2ZS5nZXRMZW5ndGgoKSkKKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhuZXcgU3RyaW5nKHNlbmRCeXRlcykpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImNvbm5lY3QvY29ubmVjdCAtIFdyb25nIHJlY2VpdmVyOiIKKyAgICAgICAgICAgICAgICAgICAgKyByZWNlaXZlLmdldEFkZHJlc3MoKSArICI6IiArIGxvY2FsSG9zdCwgcmVjZWl2ZQorICAgICAgICAgICAgICAgICAgICAuZ2V0QWRkcmVzcygpLmVxdWFscyhsb2NhbEhvc3QpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoCisgICAgICAgICAgICAgICAgICAgICJVbmV4cGVjdGVkIGV4Y2VwdGlvbiB3aGVuIHNlbmRpbmcgZGF0YSBvbiBkZ3JhbSBjb25uZWN0ZWQgYXQgbmF0aXZlIGxldmVsIGFmdGVyIGNvbm5lY3QvY29ubmVjdDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgc2VydmVyLnN0b3BTZXJ2ZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3QgZm9yIHdoZW4gd2UgZmFpbCB0byBjb25uZWN0IGF0IHRoZSBuYXRpdmUgbGV2ZWwuIEl0IHNlZW1zIHRvCisgICAgICAgIC8vIGZhaWwgZm9yIHRoZSBhbnkgYWRkcmVzcyBzbyB3ZSB1c2UgdGhpcy4gTm93IHRvIGJlIGNvbXBhdGlibGUgd2UKKyAgICAgICAgLy8gZG9uJ3QgdGhyb3cgdGhlIGV4Y2VwdGlvbiBidXQgZWF0IGl0IGFuZCB0aGVuIGFjdCBhcyBpZiB3ZSB3ZXJlCisgICAgICAgIC8vIGNvbm5lY3RlZCBhdCB0aGUgSmF2YSBsZXZlbC4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRzID0gbmV3IGphdmEubmV0LkRhdGFncmFtU29ja2V0KCk7CisgICAgICAgICAgICBieXRlW10gYWRkcmVzc0J5dGVzID0geyAwLCAwLCAwLCAwIH07CisgICAgICAgICAgICBJbmV0QWRkcmVzcyBpbmV0QWRkcmVzcyA9IEluZXRBZGRyZXNzLmdldEJ5QWRkcmVzcyhhZGRyZXNzQnl0ZXMpOworICAgICAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0Rm9yVURQKCk7CisgICAgICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbEhvc3QgPSBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKTsKKyAgICAgICAgICAgIGRzLmNvbm5lY3QobmV3IEluZXRTb2NrZXRBZGRyZXNzKGluZXRBZGRyZXNzLCBwb3J0TnVtYmVyKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJcyBub3QgY29ubmVjdGVkIGFmdGVyIGNvbm5lY3QgdG8gaW5hZGRyIGFueSIsIGRzCisgICAgICAgICAgICAgICAgICAgIC5pc0Nvbm5lY3RlZCgpKTsKKyAgICAgICAgICAgIGJ5dGVbXSBzZW5kQnl0ZXMgPSB7ICdUJywgJ2UnLCAncycsICd0JywgMCB9OworICAgICAgICAgICAgRGF0YWdyYW1QYWNrZXQgc2VuZCA9IG5ldyBEYXRhZ3JhbVBhY2tldChzZW5kQnl0ZXMsCisgICAgICAgICAgICAgICAgICAgIHNlbmRCeXRlcy5sZW5ndGgsIGxvY2FsSG9zdCwgcG9ydE51bWJlcik7CisgICAgICAgICAgICBkcy5zZW5kKHNlbmQpOworICAgICAgICAgICAgZmFpbCgKKyAgICAgICAgICAgICAgICAgICAgIk5vIGV4Y2VwdGlvbiB3aGVuIHRyeWluZyB0byBjb25uZWN0IGF0IG5hdGl2ZSBsZXZlbCB3aXRoIGJhZCBhZGRyZXNzIChleGNlcHRpb24gZnJvbSBzZW5kKSAgIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiV3JvbmcgZXhjZXB0aW9uIHdoZW4gdHJ5aW5nIHRvIGNvbm5lY3QgYXQgbmF0aXZlIGxldmVsIHdpdGggYmFkIGFkZHJlc3MgKGV4Y2VwdGlvbiBmcm9tIHNlbmQpOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgIChlIGluc3RhbmNlb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzQm91bmQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJbmV0QWRkcmVzcyBhZGRyID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCk7CisgICAgICAgICAgICBpbnRbXSBwb3J0cyA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnRzRm9yVURQKDMpOworICAgICAgICAgICAgaW50IHBvcnQgPSBwb3J0c1swXTsKKworICAgICAgICAgICAgRGF0YWdyYW1Tb2NrZXQgdGhlU29ja2V0ID0gbmV3IERhdGFncmFtU29ja2V0KHBvcnRzWzFdKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlNvY2tldCBpbmRpY2F0ZWQgIG5vdCBib3VuZCB3aGVuIGl0IHNob3VsZCBiZSAoMSkiLAorICAgICAgICAgICAgICAgICAgICB0aGVTb2NrZXQuaXNCb3VuZCgpKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworCisgICAgICAgICAgICB0aGVTb2NrZXQgPSBuZXcgRGF0YWdyYW1Tb2NrZXQobmV3IEluZXRTb2NrZXRBZGRyZXNzKGFkZHIsIHBvcnQpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlNvY2tldCBpbmRpY2F0ZWQgIG5vdCBib3VuZCB3aGVuIGl0IHNob3VsZCBiZSAoMikiLAorICAgICAgICAgICAgICAgICAgICB0aGVTb2NrZXQuaXNCb3VuZCgpKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworCisgICAgICAgICAgICB0aGVTb2NrZXQgPSBuZXcgRGF0YWdyYW1Tb2NrZXQoKFNvY2tldEFkZHJlc3MpIG51bGwpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIlNvY2tldCBpbmRpY2F0ZWQgIGJvdW5kIHdoZW4gaXQgc2hvdWxkIG5vdCBiZSAoMSkiLAorICAgICAgICAgICAgICAgICAgICB0aGVTb2NrZXQuaXNCb3VuZCgpKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworCisgICAgICAgICAgICAvLyBjb25uZWN0IGNhdXNlcyBpbXBsaWNpdCBiaW5kCisgICAgICAgICAgICB0aGVTb2NrZXQgPSBuZXcgRGF0YWdyYW1Tb2NrZXQoKFNvY2tldEFkZHJlc3MpIG51bGwpOworICAgICAgICAgICAgdGhlU29ja2V0LmNvbm5lY3QobmV3IEluZXRTb2NrZXRBZGRyZXNzKGFkZHIsIHBvcnQpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlNvY2tldCBpbmRpY2F0ZWQgbm90IGJvdW5kIHdoZW4gaXQgc2hvdWxkIGJlICgzKSIsCisgICAgICAgICAgICAgICAgICAgIHRoZVNvY2tldC5pc0JvdW5kKCkpOworICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisKKyAgICAgICAgICAgIC8vIG5vdyB0ZXN0IHdoZW4gd2UgYmluZCBleHBsaWNpdGVseQorICAgICAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgdGhlTG9jYWxBZGRyZXNzID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKAorICAgICAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgcG9ydHNbMl0pOworICAgICAgICAgICAgdGhlU29ja2V0ID0gbmV3IERhdGFncmFtU29ja2V0KChTb2NrZXRBZGRyZXNzKSBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJTb2NrZXQgaW5kaWNhdGVkIGJvdW5kIHdoZW4gaXQgc2hvdWxkIG5vdCBiZSAoMikiLAorICAgICAgICAgICAgICAgICAgICB0aGVTb2NrZXQuaXNCb3VuZCgpKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5iaW5kKHRoZUxvY2FsQWRkcmVzcyk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTb2NrZXQgaW5kaWNhdGVkIG5vdCBib3VuZCB3aGVuIGl0IHNob3VsZCBiZSAoNCkiLAorICAgICAgICAgICAgICAgICAgICB0aGVTb2NrZXQuaXNCb3VuZCgpKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU29ja2V0IGluZGljYXRlZCBub3QgYm91bmQgd2hlbiBpdCBzaG91bGQgYmUgKDUpIiwKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0LmlzQm91bmQoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJHb3QgZXhjZXB0aW9uIGR1cmluZyBpc0JvdW5kIHRlc3RzIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzQ29ubmVjdGVkKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW5ldEFkZHJlc3MgYWRkciA9IEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpOworICAgICAgICAgICAgaW50W10gcG9ydHMgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0c0ZvclVEUCg0KTsKKyAgICAgICAgICAgIGludCBwb3J0ID0gcG9ydHNbMF07CisKKyAgICAgICAgICAgIC8vIGJhc2UgdGVzdAorICAgICAgICAgICAgRGF0YWdyYW1Tb2NrZXQgdGhlU29ja2V0ID0gbmV3IERhdGFncmFtU29ja2V0KHBvcnRzWzFdKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJTb2NrZXQgaW5kaWNhdGVkIGNvbm5lY3RlZCB3aGVuIGl0IHNob3VsZCBub3QgYmUiLAorICAgICAgICAgICAgICAgICAgICB0aGVTb2NrZXQuaXNDb25uZWN0ZWQoKSk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MoYWRkciwgcG9ydCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU29ja2V0IGluZGljYXRlZCAgbm90IGNvbm5lY3RlZCB3aGVuIGl0IHNob3VsZCBiZSIsCisgICAgICAgICAgICAgICAgICAgIHRoZVNvY2tldC5pc0Nvbm5lY3RlZCgpKTsKKworICAgICAgICAgICAgLy8gcmVjb25uZWN0IHRoZSBzb2NrZXQgYW5kIG1ha2Ugc3VyZSB3ZSBnZXQgdGhlIHJpZ2h0IGFuc3dlcgorICAgICAgICAgICAgdGhlU29ja2V0LmNvbm5lY3QobmV3IEluZXRTb2NrZXRBZGRyZXNzKGFkZHIsIHBvcnRzWzJdKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTb2NrZXQgaW5kaWNhdGVkICBub3QgY29ubmVjdGVkIHdoZW4gaXQgc2hvdWxkIGJlIiwKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0LmlzQ29ubmVjdGVkKCkpOworCisgICAgICAgICAgICAvLyBub3cgZGlzY29ubmVjdCB0aGUgc29ja2V0IGFuZCBtYWtlIHN1cmUgd2UgZ2V0IHRoZSByaWdodCBhbnN3ZXIKKyAgICAgICAgICAgIHRoZVNvY2tldC5kaXNjb25uZWN0KCk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSgiU29ja2V0IGluZGljYXRlZCBjb25uZWN0ZWQgd2hlbiBpdCBzaG91bGQgbm90IGJlIiwKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0LmlzQ29ubmVjdGVkKCkpOworICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisKKyAgICAgICAgICAgIC8vIG5vdyBjaGVjayBiZWhhdmlvciB3aGVuIHNvY2tldCBpcyBjbG9zZWQgd2hlbiBjb25uZWN0ZWQKKyAgICAgICAgICAgIHRoZVNvY2tldCA9IG5ldyBEYXRhZ3JhbVNvY2tldChwb3J0c1szXSk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MoYWRkciwgcG9ydCkpOworICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTb2NrZXQgaW5kaWNhdGVkICBub3QgY29ubmVjdGVkIHdoZW4gaXQgc2hvdWxkIGJlIiwKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0LmlzQ29ubmVjdGVkKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiR290IGV4Y2VwdGlvbiBkdXJpbmcgaXNDb25uZWN0ZWQgdGVzdHMiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UmVtb3RlU29ja2V0QWRkcmVzcygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludFtdIHBvcnRzID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydHNGb3JVRFAoMyk7CisgICAgICAgICAgICBpbnQgc3BvcnQgPSBwb3J0c1swXTsKKyAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gcG9ydHNbMV07CisgICAgICAgICAgICBEYXRhZ3JhbVNvY2tldCBzID0gbmV3IERhdGFncmFtU29ja2V0KG5ldyBJbmV0U29ja2V0QWRkcmVzcygKKyAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHBvcnROdW1iZXIpKTsKKyAgICAgICAgICAgIHMuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHNwb3J0KSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgSW5ldFNvY2tldEFkZHJlc3MoMSk6IgorICAgICAgICAgICAgICAgICAgICArIHMuZ2V0TG9jYWxTb2NrZXRBZGRyZXNzKCkudG9TdHJpbmcoKSwgcworICAgICAgICAgICAgICAgICAgICAuZ2V0UmVtb3RlU29ja2V0QWRkcmVzcygpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcG9ydCkpKTsKKyAgICAgICAgICAgIHMuY2xvc2UoKTsKKworICAgICAgICAgICAgLy8gbm93IGNyZWF0ZSBvbmUgdGhhdCBpcyBub3QgY29ubmVjdGVkIGFuZCB2YWxpZGF0ZSB0aGF0IHdlIGdldCB0aGUKKyAgICAgICAgICAgIC8vIHJpZ2h0IGFuc3dlcgorICAgICAgICAgICAgRGF0YWdyYW1Tb2NrZXQgdGhlU29ja2V0ID0gbmV3IERhdGFncmFtU29ja2V0KChTb2NrZXRBZGRyZXNzKSBudWxsKTsKKyAgICAgICAgICAgIHBvcnROdW1iZXIgPSBwb3J0c1syXTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5iaW5kKG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwKKyAgICAgICAgICAgICAgICAgICAgcG9ydE51bWJlcikpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgKKyAgICAgICAgICAgICAgICAgICAgIlJldHVybmVkIGluY29ycmVjdCBJbmV0U29ja2V0QWRkcmVzcyAtdW5jb25uZWN0ZWQgc29ja2V0OiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJFeHBlY3RlZDogTlVMTCIsIHRoZVNvY2tldAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRSZW1vdGVTb2NrZXRBZGRyZXNzKCkpOworCisgICAgICAgICAgICAvLyBub3cgY29ubmVjdCBhbmQgdmFsaWRhdGUgd2UgZ2V0IHRoZSByaWdodCBhbnN3ZXIKKyAgICAgICAgICAgIHRoZVNvY2tldC5jb25uZWN0KG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwKKyAgICAgICAgICAgICAgICAgICAgc3BvcnQpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBJbmV0U29ja2V0QWRkcmVzcygyKToiCisgICAgICAgICAgICAgICAgICAgICsgdGhlU29ja2V0LmdldFJlbW90ZVNvY2tldEFkZHJlc3MoKS50b1N0cmluZygpLCB0aGVTb2NrZXQKKyAgICAgICAgICAgICAgICAgICAgLmdldFJlbW90ZVNvY2tldEFkZHJlc3MoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BvcnQpKSk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXRSZW1vdGVTb2NrZXRBZGRyZXNzIHRlc3Q6ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0UmV1c2VBZGRyZXNzWigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyB0ZXN0IGNhc2Ugd2VyZSB3ZSBzZXQgaXQgdG8gZmFsc2UKKyAgICAgICAgRGF0YWdyYW1Tb2NrZXQgdGhlU29ja2V0MSA9IG51bGw7CisgICAgICAgIERhdGFncmFtU29ja2V0IHRoZVNvY2tldDIgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgdGhlQWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcygKKyAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIFN1cHBvcnRfUG9ydE1hbmFnZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TmV4dFBvcnRGb3JVRFAoKSk7CisgICAgICAgICAgICB0aGVTb2NrZXQxID0gbmV3IERhdGFncmFtU29ja2V0KChTb2NrZXRBZGRyZXNzKSBudWxsKTsKKyAgICAgICAgICAgIHRoZVNvY2tldDIgPSBuZXcgRGF0YWdyYW1Tb2NrZXQoKFNvY2tldEFkZHJlc3MpIG51bGwpOworICAgICAgICAgICAgdGhlU29ja2V0MS5zZXRSZXVzZUFkZHJlc3MoZmFsc2UpOworICAgICAgICAgICAgdGhlU29ja2V0Mi5zZXRSZXVzZUFkZHJlc3MoZmFsc2UpOworICAgICAgICAgICAgdGhlU29ja2V0MS5iaW5kKHRoZUFkZHJlc3MpOworICAgICAgICAgICAgdGhlU29ja2V0Mi5iaW5kKHRoZUFkZHJlc3MpOworICAgICAgICAgICAgZmFpbCgKKyAgICAgICAgICAgICAgICAgICAgIk5vIGV4Y2VwdGlvbiB3aGVuIHRyeWluZyB0byBjb25uZWN0IHRvIGRvIGR1cGxpY2F0ZSBzb2NrZXQgYmluZCB3aXRoIHJlLXVzZWFkZHIgc2V0IHRvIGZhbHNlIik7CisgICAgICAgIH0gY2F0Y2ggKEJpbmRFeGNlcHRpb24gZSkgeworCisgICAgICAgIH0KKyAgICAgICAgaWYgKHRoZVNvY2tldDEgIT0gbnVsbCkKKyAgICAgICAgICAgIHRoZVNvY2tldDEuY2xvc2UoKTsKKyAgICAgICAgaWYgKHRoZVNvY2tldDIgIT0gbnVsbCkKKyAgICAgICAgICAgIHRoZVNvY2tldDIuY2xvc2UoKTsKKworICAgICAgICAvLyB0ZXN0IGNhc2Ugd2VyZSB3ZSBzZXQgaXQgdG8gdHJ1ZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgdGhlQWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcygKKyAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIFN1cHBvcnRfUG9ydE1hbmFnZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TmV4dFBvcnRGb3JVRFAoKSk7CisgICAgICAgICAgICB0aGVTb2NrZXQxID0gbmV3IERhdGFncmFtU29ja2V0KChTb2NrZXRBZGRyZXNzKSBudWxsKTsKKyAgICAgICAgICAgIHRoZVNvY2tldDIgPSBuZXcgRGF0YWdyYW1Tb2NrZXQoKFNvY2tldEFkZHJlc3MpIG51bGwpOworICAgICAgICAgICAgdGhlU29ja2V0MS5zZXRSZXVzZUFkZHJlc3ModHJ1ZSk7CisgICAgICAgICAgICB0aGVTb2NrZXQyLnNldFJldXNlQWRkcmVzcyh0cnVlKTsKKyAgICAgICAgICAgIHRoZVNvY2tldDEuYmluZCh0aGVBZGRyZXNzKTsKKyAgICAgICAgICAgIHRoZVNvY2tldDIuYmluZCh0aGVBZGRyZXNzKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoCisgICAgICAgICAgICAgICAgICAgICJ1bmV4cGVjdGVkIGV4Y2VwdGlvbiB3aGVuIHRyeWluZyB0byBjb25uZWN0IHRvIGRvIGR1cGxpY2F0ZSBzb2NrZXQgYmluZCB3aXRoIHJlLXVzZWFkZHIgc2V0IHRvIHRydWUiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodGhlU29ja2V0MSAhPSBudWxsKQorICAgICAgICAgICAgdGhlU29ja2V0MS5jbG9zZSgpOworICAgICAgICBpZiAodGhlU29ja2V0MiAhPSBudWxsKQorICAgICAgICAgICAgdGhlU29ja2V0Mi5jbG9zZSgpOworCisgICAgICAgIC8vIHRlc3QgdGhlIGRlZmF1bHQgY2FzZSB3aGljaCB3ZSBleHBlY3QgdG8gYmUgdGhlIHNhbWUgb24gYWxsCisgICAgICAgIC8vIHBsYXRmb3JtcworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgdGhlQWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcygKKyAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIFN1cHBvcnRfUG9ydE1hbmFnZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TmV4dFBvcnRGb3JVRFAoKSk7CisgICAgICAgICAgICB0aGVTb2NrZXQxID0gbmV3IERhdGFncmFtU29ja2V0KChTb2NrZXRBZGRyZXNzKSBudWxsKTsKKyAgICAgICAgICAgIHRoZVNvY2tldDIgPSBuZXcgRGF0YWdyYW1Tb2NrZXQoKFNvY2tldEFkZHJlc3MpIG51bGwpOworICAgICAgICAgICAgdGhlU29ja2V0MS5iaW5kKHRoZUFkZHJlc3MpOworICAgICAgICAgICAgdGhlU29ja2V0Mi5iaW5kKHRoZUFkZHJlc3MpOworICAgICAgICAgICAgZmFpbCgKKyAgICAgICAgICAgICAgICAgICAgIk5vIGV4Y2VwdGlvbiB3aGVuIHRyeWluZyB0byBjb25uZWN0IHRvIGRvIGR1cGxpY2F0ZSBzb2NrZXQgYmluZCB3aXRoIHJlLXVzZWFkZHIgbGVmdCBhcyBkZWZhdWx0Iik7CisgICAgICAgIH0gY2F0Y2ggKEJpbmRFeGNlcHRpb24gZSkgeworCisgICAgICAgIH0KKyAgICAgICAgaWYgKHRoZVNvY2tldDEgIT0gbnVsbCkKKyAgICAgICAgICAgIHRoZVNvY2tldDEuY2xvc2UoKTsKKyAgICAgICAgaWYgKHRoZVNvY2tldDIgIT0gbnVsbCkKKyAgICAgICAgICAgIHRoZVNvY2tldDIuY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhlU29ja2V0MS5zZXRSZXVzZUFkZHJlc3ModHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU29ja2V0RXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFJldXNlQWRkcmVzcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEYXRhZ3JhbVNvY2tldCB0aGVTb2NrZXQgPSBuZXcgRGF0YWdyYW1Tb2NrZXQoKTsKKyAgICAgICAgdGhlU29ja2V0LnNldFJldXNlQWRkcmVzcyh0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0UmV1c2VBZGRyZXNzIGZhbHNlIHdoZW4gaXQgc2hvdWxkIGJlIHRydWUiLAorICAgICAgICAgICAgICAgIHRoZVNvY2tldC5nZXRSZXVzZUFkZHJlc3MoKSk7CisgICAgICAgIHRoZVNvY2tldC5zZXRSZXVzZUFkZHJlc3MoZmFsc2UpOworICAgICAgICBhc3NlcnRGYWxzZSgiZ2V0UmV1c2VBZGRyZXNzIHRydWUgd2hlbiBpdCBzaG91bGQgYmUgZmFsc2UiLAorICAgICAgICAgICAgICAgIHRoZVNvY2tldC5nZXRSZXVzZUFkZHJlc3MoKSk7CisgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhlU29ja2V0LmdldFJldXNlQWRkcmVzcygpOworICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFNvY2tldEV4Y2VwdGlvbiBzZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRCcm9hZGNhc3RaKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGludFtdIHBvcnRzID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydHNGb3JVRFAoMyk7CisgICAgICAgIERhdGFncmFtU29ja2V0IHRoZVNvY2tldCA9IG5ldyBEYXRhZ3JhbVNvY2tldChwb3J0c1swXSk7CisgICAgICAgIHRoZVNvY2tldC5zZXRCcm9hZGNhc3QoZmFsc2UpOworICAgICAgICBieXRlIHRoZUJ5dGVzW10gPSB7IC0xLCAtMSwgLTEsIC0xIH07CisKKyAgICAgICAgLy8gdmFsaWRhdGUgd2UgY2Fubm90IGNvbm5lY3QgdG8gdGhlIGJyb2FkY2FzdCBhZGRyZXNzIHdoZW4KKyAgICAgICAgLy8gc2V0QnJvYWRjYXN0IGlzIGZhbHNlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGVTb2NrZXQuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgLmdldEJ5QWRkcmVzcyh0aGVCeXRlcyksIHBvcnRzWzFdKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSgKKyAgICAgICAgICAgICAgICAgICAgIk5vIGV4Y2VwdGlvbiB3aGVuIGNvbm5lY3RpbmcgdG8gYnJvYWRjYXN0IGFkZHJlc3Mgd2l0aCBzZXRCcm9hZGNhc3QoZmFsc2UpIiwKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0LmdldEJyb2FkY2FzdCgpKTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBub3cgdmFsaWRhdGUgdGhhdCB3ZSBjYW4gY29ubmVjdCB0byB0aGUgYnJvYWRjYXN0IGFkZHJlc3Mgd2hlbgorICAgICAgICAvLyBzZXRCcm9hZGNhc3QgaXMgdHJ1ZQorICAgICAgICB0aGVTb2NrZXQuc2V0QnJvYWRjYXN0KHRydWUpOworICAgICAgICB0aGVTb2NrZXQuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRCeUFkZHJlc3ModGhlQnl0ZXMpLCBwb3J0c1syXSkpOworCisgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhlU29ja2V0LnNldEJyb2FkY2FzdChmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU29ja2V0RXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEJyb2FkY2FzdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEYXRhZ3JhbVNvY2tldCB0aGVTb2NrZXQgPSBuZXcgRGF0YWdyYW1Tb2NrZXQoKTsKKyAgICAgICAgdGhlU29ja2V0LnNldEJyb2FkY2FzdCh0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0QnJvYWRjYXN0IGZhbHNlIHdoZW4gaXQgc2hvdWxkIGJlIHRydWUiLCB0aGVTb2NrZXQKKyAgICAgICAgICAgICAgICAuZ2V0QnJvYWRjYXN0KCkpOworICAgICAgICB0aGVTb2NrZXQuc2V0QnJvYWRjYXN0KGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoImdldEJyb2FkY2FzdCB0cnVlIHdoZW4gaXQgc2hvdWxkIGJlIEZhbHNlIiwgdGhlU29ja2V0CisgICAgICAgICAgICAgICAgLmdldEJyb2FkY2FzdCgpKTsKKyAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGVTb2NrZXQuZ2V0QnJvYWRjYXN0KCk7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU29ja2V0RXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFRyYWZmaWNDbGFzc0koKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IElQVE9TX0xPV0NPU1QgPSAweDI7CisgICAgICAgIGludCBJUFRPU19SRUxJQUJJTFRZID0gMHg0OworICAgICAgICBpbnQgSVBUT1NfVEhST1VHSFBVVCA9IDB4ODsKKyAgICAgICAgaW50IElQVE9TX0xPV0RFTEFZID0gMHgxMDsKKyAgICAgICAgaW50W10gcG9ydHMgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0c0ZvclVEUCgyKTsKKworICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgcG9ydHNbMF0pOworICAgICAgICBEYXRhZ3JhbVNvY2tldCB0aGVTb2NrZXQgPSBuZXcgRGF0YWdyYW1Tb2NrZXQocG9ydHNbMV0pOworCisgICAgICAgIC8vIHZhbGlkYXRlIHRoYXQgdmFsdWUgc2V0IG11c3QgYmUgYmV0d2VlbiAwIGFuZCAyNTUKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoZVNvY2tldC5zZXRUcmFmZmljQ2xhc3MoMjU2KTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4Y2VwdGlvbiB3aGVuIHRyYWZmaWMgY2xhc3Mgc2V0IHRvIDI1NiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoZVNvY2tldC5zZXRUcmFmZmljQ2xhc3MoLTEpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhjZXB0aW9uIHdoZW4gdHJhZmZpYyBjbGFzcyBzZXQgdG8gLTEiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIG5vdyB2YWxpZGF0ZSB0aGF0IHdlIGNhbiBzZXQgaXQgdG8gc29tZSBnb29kIHZhbHVlcworICAgICAgICB0aGVTb2NrZXQuc2V0VHJhZmZpY0NsYXNzKElQVE9TX0xPV0NPU1QpOworICAgICAgICB0aGVTb2NrZXQuc2V0VHJhZmZpY0NsYXNzKElQVE9TX1RIUk9VR0hQVVQpOworCisgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhlU29ja2V0LnNldFRyYWZmaWNDbGFzcygxKTsKKyAgICAgICAgICAgIGZhaWwoIlNvY2tldEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChTb2NrZXRFeGNlcHRpb24gc2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0VHJhZmZpY0NsYXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBJUFRPU19MT1dDT1NUID0gMHgyOworICAgICAgICBpbnQgSVBUT1NfUkVMSUFCSUxUWSA9IDB4NDsKKyAgICAgICAgaW50IElQVE9TX1RIUk9VR0hQVVQgPSAweDg7CisgICAgICAgIGludCBJUFRPU19MT1dERUxBWSA9IDB4MTA7CisgICAgICAgIGludFtdIHBvcnRzID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydHNGb3JVRFAoMik7CisKKyAgICAgICAgbmV3IEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLAorICAgICAgICAgICAgICAgIHBvcnRzWzBdKTsKKyAgICAgICAgRGF0YWdyYW1Tb2NrZXQgdGhlU29ja2V0ID0gbmV3IERhdGFncmFtU29ja2V0KHBvcnRzWzFdKTsKKworICAgICAgICAvKgorICAgICAgICAgKiB3ZSBjYW5ub3QgYWN0dWFsbHkgY2hlY2sgdGhhdCB0aGUgdmFsdWVzIGFyZSBzZXQgYXMgaWYgYSBwbGF0Zm9ybQorICAgICAgICAgKiBkb2VzIG5vdCBzdXBwb3J0IHRoZSBvcHRpb24gdGhlbiBpdCBtYXkgY29tZSBiYWNrIHVuc2V0IGV2ZW4KKyAgICAgICAgICogdGhvdWdoIHdlIHNldCBpdCBzbyBqdXN0IGdldCB0aGUgdmFsdWUgdG8gbWFrZSBzdXJlIHdlIGNhbiBnZXQgaXQKKyAgICAgICAgICovCisgICAgICAgIGludCB0cmFmZmljQ2xhc3MgPSB0aGVTb2NrZXQuZ2V0VHJhZmZpY0NsYXNzKCk7CisKKyAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGVTb2NrZXQuZ2V0VHJhZmZpY0NsYXNzKCk7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU29ja2V0RXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzQ2xvc2VkKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgRGF0YWdyYW1Tb2NrZXQgdGhlU29ja2V0ID0gbmV3IERhdGFncmFtU29ja2V0KCk7CisKKyAgICAgICAgICAgIC8vIHZhbGlkYXRlIGlzQ2xvc2VkIHJldHVybnMgZXhwZWN0ZWQgdmFsdWVzCisgICAgICAgICAgICBhc3NlcnRGYWxzZSgiU29ja2V0IHNob3VsZCBpbmRpY2F0ZSBpdCBpcyBub3QgY2xvc2VkKDEpOiIsCisgICAgICAgICAgICAgICAgICAgIHRoZVNvY2tldC5pc0Nsb3NlZCgpKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU29ja2V0IHNob3VsZCBpbmRpY2F0ZSBpdCBpcyBub3QgY2xvc2VkKDEpOiIsIHRoZVNvY2tldAorICAgICAgICAgICAgICAgICAgICAuaXNDbG9zZWQoKSk7CisKKyAgICAgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIHRoZUFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgLmdldExvY2FsSG9zdCgpLCBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0Rm9yVURQKCkpOworICAgICAgICAgICAgdGhlU29ja2V0ID0gbmV3IERhdGFncmFtU29ja2V0KHRoZUFkZHJlc3MpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIlNvY2tldCBzaG91bGQgaW5kaWNhdGUgaXQgaXMgbm90IGNsb3NlZCgyKToiLAorICAgICAgICAgICAgICAgICAgICB0aGVTb2NrZXQuaXNDbG9zZWQoKSk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlNvY2tldCBzaG91bGQgaW5kaWNhdGUgaXQgaXMgbm90IGNsb3NlZCgyKToiLCB0aGVTb2NrZXQKKyAgICAgICAgICAgICAgICAgICAgLmlzQ2xvc2VkKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiR290IGV4Y2VwdGlvbiBkdXJpbmcgaXNDbG9zZWQgdGVzdHMiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Q2hhbm5lbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnROdWxsKG5ldyBEYXRhZ3JhbVNvY2tldCgpLmdldENoYW5uZWwoKSk7CisKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0Rm9yVURQKCk7CisgICAgICAgIERhdGFncmFtU29ja2V0IGRzID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIGlhID0gSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRCeU5hbWUoU3VwcG9ydF9Db25maWd1cmF0aW9uLklQdjZHbG9iYWxBZGRyZXNzSmNsNCk7CisgICAgICAgICAgICBkcyA9IG5ldyBEYXRhZ3JhbVNvY2tldCgpOworICAgICAgICAgICAgYXNzZXJ0TnVsbChkcy5nZXRDaGFubmVsKCkpOworICAgICAgICAgICAgZHMuY29ubmVjdChpYSwgcG9ydE51bWJlcik7CisgICAgICAgICAgICBhc3NlcnROdWxsKGRzLmdldENoYW5uZWwoKSk7CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGRzLmRpc2Nvbm5lY3QoKTsKKyAgICAgICAgICAgIGRzLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICAgICAgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnRGb3JVRFAoKTsKKyAgICAgICAgU29ja2V0QWRkcmVzcyBhZGRyZXNzID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKHBvcnROdW1iZXIpOworICAgICAgICBEYXRhZ3JhbUNoYW5uZWwgY2hhbm5lbCA9IERhdGFncmFtQ2hhbm5lbC5vcGVuKCk7CisgICAgICAgIERhdGFncmFtU29ja2V0IHNvY2tldCA9IGNoYW5uZWwuc29ja2V0KCk7CisgICAgICAgIGFzc2VydEVxdWFscyhjaGFubmVsLCBzb2NrZXQuZ2V0Q2hhbm5lbCgpKTsKKyAgICAgICAgc29ja2V0LmNsb3NlKCk7CisgICAgfQorCisgICAgY2xhc3MgVGVzdERhdGFncmFtU29ja2V0SW1wbEZhY3RvcnkgaW1wbGVtZW50cyBEYXRhZ3JhbVNvY2tldEltcGxGYWN0b3J5IHsKKyAgICAgICAgcHVibGljIERhdGFncmFtU29ja2V0SW1wbCBjcmVhdGVEYXRhZ3JhbVNvY2tldEltcGwoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFRlc3REYXRhZ3JhbVNvY2tldEltcGwoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIFRlc3REYXRhZ3JhbVNvY2tldEltcGwgZXh0ZW5kcyBEYXRhZ3JhbVNvY2tldEltcGwgeworCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBiaW5kKGludCBhcmcwLCBJbmV0QWRkcmVzcyBhcmcxKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGNsb3NlKCkgeworICAgICAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorCisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgYnl0ZSBnZXRUVEwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGludCBnZXRUaW1lVG9MaXZlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGpvaW4oSW5ldEFkZHJlc3MgYXJnMCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGpvaW5Hcm91cChTb2NrZXRBZGRyZXNzIGFyZzAsIE5ldHdvcmtJbnRlcmZhY2UgYXJnMSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGxlYXZlKEluZXRBZGRyZXNzIGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBsZWF2ZUdyb3VwKFNvY2tldEFkZHJlc3MgYXJnMCwgTmV0d29ya0ludGVyZmFjZSBhcmcxKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorCisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGludCBwZWVrKEluZXRBZGRyZXNzIGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgaW50IHBlZWtEYXRhKERhdGFncmFtUGFja2V0IGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZWNlaXZlKERhdGFncmFtUGFja2V0IGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBzZW5kKERhdGFncmFtUGFja2V0IGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBzZXRUVEwoYnl0ZSBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorCisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgc2V0VGltZVRvTGl2ZShpbnQgYXJnMCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBnZXRPcHRpb24oaW50IGFyZzApIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXRPcHRpb24oaW50IGFyZzAsIE9iamVjdCBhcmcxKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgcmV0dmFsID0gIkJvZ3VzIHJldHZhbCI7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVhcnMgZG93biB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIGNsb3NlIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzCisgICAgICogbWV0aG9kIGlzIGNhbGxlZCBhZnRlciBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkcy5jbG9zZSgpOworICAgICAgICAgICAgc2RzLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCByZWNlaXZlX292ZXJzaXplX2phdmFfbmV0X0RhdGFncmFtUGFja2V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIGludFtdIHBvcnRzID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydHNGb3JVRFAoMik7CisgICAgICAgIGZpbmFsIGludCBwb3J0TnVtYmVyID0gcG9ydHNbMF07CisKKyAgICAgICAgY2xhc3MgVGVzdERHUmN2T3ZlciBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbEhvc3QgPSBudWxsOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGxvY2FsSG9zdCA9IEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpOworICAgICAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgICAgICAgICAgICAgICAgIERhdGFncmFtU29ja2V0IHNkcyA9IG5ldyBEYXRhZ3JhbVNvY2tldChwb3J0c1sxXSk7CisgICAgICAgICAgICAgICAgICAgIERhdGFncmFtUGFja2V0IHJkcCA9IG5ldyBEYXRhZ3JhbVBhY2tldCgiMDEyMzQ1Njc4OSIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0Qnl0ZXMoKSwgMTAsIGxvY2FsSG9zdCwgcG9ydE51bWJlcik7CisgICAgICAgICAgICAgICAgICAgIHNkcy5zZW5kKHJkcCk7CisgICAgICAgICAgICAgICAgICAgIHNkcy5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVGhyZWFkKG5ldyBUZXN0REdSY3ZPdmVyKCksICJER1NlbmRlck92ZXIiKS5zdGFydCgpOworICAgICAgICAgICAgZHMgPSBuZXcgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQocG9ydE51bWJlcik7CisgICAgICAgICAgICBkcy5zZXRTb1RpbWVvdXQoNjAwMCk7CisgICAgICAgICAgICBieXRlIHJidWZbXSA9IG5ldyBieXRlWzVdOworICAgICAgICAgICAgRGF0YWdyYW1QYWNrZXQgcmRwID0gbmV3IERhdGFncmFtUGFja2V0KHJidWYsIHJidWYubGVuZ3RoKTsKKyAgICAgICAgICAgIDsKKyAgICAgICAgICAgIGRzLnJlY2VpdmUocmRwKTsKKyAgICAgICAgICAgIGRzLmNsb3NlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTZW5kL1JlY2VpdmUgb3ZlcnNpemUgZmFpbGVkIHRvIHJldHVybiBjb3JyZWN0IGRhdGE6ICIKKyAgICAgICAgICAgICAgICAgICAgKyBuZXcgU3RyaW5nKHJidWYsIDAsIDUpLCBuZXcgU3RyaW5nKHJidWYsIDAsIDUpCisgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoIjAxMjM0IikpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZHMuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZEZpbGVOYW1lTWFwVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkRmlsZU5hbWVNYXBUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGU5Y2FhOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZEZpbGVOYW1lTWFwVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uZXQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLm5ldC5GaWxlTmFtZU1hcDsKK2ltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOworCitwdWJsaWMgY2xhc3MgT2xkRmlsZU5hbWVNYXBUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDb250ZW50VHlwZUZvcigpIHsKKyAgICAgICAgU3RyaW5nIFtdIGZpbGVzID0geyJ0ZXh0IiwgInR4dCIsICJodG0iLCAiaHRtbCJ9OworCisgICAgICAgIFN0cmluZyBbXSBtaW1lVHlwZXMgPSB7InRleHQvcGxhaW4iLCAidGV4dC9wbGFpbiIsCisgICAgICAgICAgICAgICAgInRleHQvaHRtbCIsICJ0ZXh0L2h0bWwifTsKKworICAgICAgICBGaWxlTmFtZU1hcCBmaWxlTmFtZU1hcCA9IFVSTENvbm5lY3Rpb24uZ2V0RmlsZU5hbWVNYXAoKTsKKworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgZmlsZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFN0cmluZyBtaW1lVHlwZSA9IGZpbGVOYW1lTWFwLmdldENvbnRlbnRUeXBlRm9yKCJ0ZXN0LiIgKyBmaWxlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldENvbnRlbnRUeXBlRm9yIHJldHVybnMgaW5jb3JyZWN0IE1JTUUgdHlwZSBmb3IgIiArCisgICAgICAgICAgICAgICAgICAgIGZpbGVzW2ldLCBtaW1lVHlwZXNbaV0sIG1pbWVUeXBlKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZEh0dHBSZXRyeUV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZEh0dHBSZXRyeUV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNzFlYWJhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkSHR0cFJldHJ5RXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLm5ldC5IdHRwUmV0cnlFeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkSHR0cFJldHJ5RXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMU3RyaW5nSSgpIHsKKyAgICAgICAgU3RyaW5nIFtdIG1lc3NhZ2UgPSB7IlRlc3QgbWVzc2FnZSIsICIiLCAiTWVzc2FnZSIsICJ+IUAjJCUgJiooIiwgbnVsbH07CisgICAgICAgIGludCBbXSBjb2RlcyA9IHs0MDAsIDQwNCwgMjAwLCA1MDAsIDB9OworCisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBIdHRwUmV0cnlFeGNlcHRpb24gaHJlID0gbmV3IEh0dHBSZXRyeUV4Y2VwdGlvbihtZXNzYWdlW2ldLAorICAgICAgICAgICAgICAgICAgICBjb2Rlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZVtpXSwgaHJlLmdldFJlYXNvbigpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoInJlc3BvbnNlQ29kZSBpcyBpbmNvcnJlY3Q6ICIgKyBocmUucmVzcG9uc2VDb2RlKCksCisgICAgICAgICAgICAgICAgICAgIGhyZS5yZXNwb25zZUNvZGUoKSA9PSBjb2Rlc1tpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTFN0cmluZ0lMU3RyaW5nKCkgeworICAgICAgICBTdHJpbmcgW10gbWVzc2FnZSA9IHsiVGVzdCBtZXNzYWdlIiwgIiIsICJNZXNzYWdlIiwgIn4hQCMkJSAmKigiLCBudWxsfTsKKyAgICAgICAgaW50IFtdIGNvZGVzID0gezQwMCwgLTEsIEludGVnZXIuTUFYX1ZBTFVFLCBJbnRlZ2VyLk1JTl9WQUxVRSwgMH07CisgICAgICAgIFN0cmluZyBbXSBsb2NhdGlvbnMgPSB7ImZpbGU6XFxlcnJvci50eHQiLCAiaHR0cDpcXGxvY2FsaG9zdCIsCisgICAgICAgICAgICAgICAgIiIsIG51bGwsICIifTsKKworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgSHR0cFJldHJ5RXhjZXB0aW9uIGhyZSA9IG5ldyBIdHRwUmV0cnlFeGNlcHRpb24obWVzc2FnZVtpXSwKKyAgICAgICAgICAgICAgICAgICAgY29kZXNbaV0sIGxvY2F0aW9uc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZVtpXSwgaHJlLmdldFJlYXNvbigpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoInJlc3BvbnNlQ29kZSBpcyBpbmNvcnJlY3Q6ICIgKyBocmUucmVzcG9uc2VDb2RlKCksCisgICAgICAgICAgICAgICAgICAgIGhyZS5yZXNwb25zZUNvZGUoKSA9PSBjb2Rlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobG9jYXRpb25zW2ldLCBocmUuZ2V0TG9jYXRpb24oKSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRKYXJVUkxDb25uZWN0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkSmFyVVJMQ29ubmVjdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40OGU4MmMwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkSmFyVVJMQ29ubmVjdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDM1NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5KYXJVUkxDb25uZWN0aW9uOworaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5uZXQuVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5qYXIuQXR0cmlidXRlczsKK2ltcG9ydCBqYXZhLnV0aWwuamFyLkphckVudHJ5OworaW1wb3J0IGphdmEudXRpbC5qYXIuSmFyRmlsZTsKK2ltcG9ydCBqYXZhLnV0aWwuamFyLkphck91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuamFyLk1hbmlmZXN0OworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRW50cnk7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBGaWxlOworaW1wb3J0IHRlc3RzLnN1cHBvcnQucmVzb3VyY2UuU3VwcG9ydF9SZXNvdXJjZXM7CisKK3B1YmxpYyBjbGFzcyBPbGRKYXJVUkxDb25uZWN0aW9uVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBKYXJVUkxDb25uZWN0aW9uIGp1YzsKKworICAgIHByaXZhdGUgVVJMIGNyZWF0ZUNvbnRlbnQoU3RyaW5nIGphckZpbGUsIFN0cmluZyBpbkZpbGUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKworICAgICAgICBGaWxlIHJlc291cmNlcyA9IFN1cHBvcnRfUmVzb3VyY2VzLmNyZWF0ZVRlbXBGb2xkZXIoKTsKKworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsICJuZXQiLCBqYXJGaWxlKTsKKyAgICAgICAgRmlsZSBmaWxlID0gbmV3IEZpbGUocmVzb3VyY2VzLnRvU3RyaW5nKCkgKyAiL25ldC8iICsgamFyRmlsZSk7CisKKyAgICAgICAgcmV0dXJuIG5ldyBVUkwoImphcjpmaWxlOiIgKyBmaWxlLmdldFBhdGgoKSArICIhLyIgKyBpbkZpbGUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0QXR0cmlidXRlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdSA9IGNyZWF0ZUNvbnRlbnQoImxmLmphciIsICJzd3QuZGxsIik7CisgICAgICAgIGp1YyA9IChKYXJVUkxDb25uZWN0aW9uKSB1Lm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGphdmEudXRpbC5qYXIuQXR0cmlidXRlcyBhID0ganVjLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgQXR0cmlidXRlcyIsICJTSEEgTUQ1IiwgYQorICAgICAgICAgICAgICAgIC5nZXQobmV3IGphdmEudXRpbC5qYXIuQXR0cmlidXRlcy5OYW1lKCJEaWdlc3QtQWxnb3JpdGhtcyIpKSk7CisgICAgICAgIFVSTCBpbnZVUkwgPSBjcmVhdGVDb250ZW50KCJJbnZhbGlkSmFyLmphciIsICJUZXN0LmNsYXNzIik7CisKKyAgICAgICAgSmFyVVJMQ29ubmVjdGlvbiBqdUNvbm4gPSAoSmFyVVJMQ29ubmVjdGlvbikgaW52VVJMLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBqdUNvbm4uZ2V0QXR0cmlidXRlcygpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goamF2YS5pby5JT0V4Y2VwdGlvbiBpbykgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDZXJ0aWZpY2F0ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHUgPSBjcmVhdGVDb250ZW50KCJUZXN0Q29kZVNpZ25lcnMuamFyIiwgIlRlc3QuY2xhc3MiKTsKKworICAgICAgICBqdWMgPSAoSmFyVVJMQ29ubmVjdGlvbikgdS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBhc3NlcnROdWxsKGp1Yy5nZXRDZXJ0aWZpY2F0ZXMoKSk7CisKKyAgICAgICAgSmFyRW50cnkgamUgPSBqdWMuZ2V0SmFyRW50cnkoKTsKKyAgICAgICAgSmFyRmlsZSBqZiA9IGp1Yy5nZXRKYXJGaWxlKCk7CisgICAgICAgIElucHV0U3RyZWFtIGlzID0gamYuZ2V0SW5wdXRTdHJlYW0oamUpOworICAgICAgICBpcy5za2lwKGplLmdldFNpemUoKSk7CisKKyAgICAgICAgQ2VydGlmaWNhdGUgW10gY2VydHMgPSBqdWMuZ2V0Q2VydGlmaWNhdGVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBjZXJ0cy5sZW5ndGgpOworCisgICAgICAgIFVSTCBpbnZVUkwgPSBjcmVhdGVDb250ZW50KCJJbnZhbGlkSmFyLmphciIsICJUZXN0LmNsYXNzIik7CisKKyAgICAgICAgSmFyVVJMQ29ubmVjdGlvbiBqdUNvbm4gPSAoSmFyVVJMQ29ubmVjdGlvbikgaW52VVJMLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBqdUNvbm4uZ2V0Q2VydGlmaWNhdGVzKCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChqYXZhLmlvLklPRXhjZXB0aW9uIGlvKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1hbmlmZXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1ID0gY3JlYXRlQ29udGVudCgibGYuamFyIiwgInN3dC5kbGwiKTsKKworICAgICAgICBqdWMgPSAoSmFyVVJMQ29ubmVjdGlvbikgdS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBNYW5pZmVzdCBtYW5pZmVzdCA9IGp1Yy5nZXRNYW5pZmVzdCgpOworICAgICAgICBNYXA8U3RyaW5nLCBBdHRyaWJ1dGVzPiBhdHRyID0gbWFuaWZlc3QuZ2V0RW50cmllcygpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IEhhc2hTZXQ8U3RyaW5nPihBcnJheXMuYXNMaXN0KCJwbHVzLmJtcCIsICJzd3QuZGxsIikpLAorICAgICAgICAgICAgICAgIGF0dHIua2V5U2V0KCkpOworCisgICAgICAgIFVSTCBpbnZVUkwgPSBjcmVhdGVDb250ZW50KCJJbnZhbGlkSmFyLmphciIsICJUZXN0LmNsYXNzIik7CisKKyAgICAgICAgSmFyVVJMQ29ubmVjdGlvbiBqdUNvbm4gPSAoSmFyVVJMQ29ubmVjdGlvbikgaW52VVJMLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBqdUNvbm4uZ2V0TWFuaWZlc3QoKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKGphdmEuaW8uSU9FeGNlcHRpb24gaW8pIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RW50cnlOYW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1ID0gY3JlYXRlQ29udGVudCgibGYuamFyIiwgInBsdXMuYm1wIik7CisKKyAgICAgICAganVjID0gKEphclVSTENvbm5lY3Rpb24pIHUub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgZW50cnlOYW1lIiwgInBsdXMuYm1wIiwganVjCisgICAgICAgICAgICAgICAgLmdldEVudHJ5TmFtZSgpKTsKKworICAgICAgICB1ID0gY3JlYXRlQ29udGVudCgibGYuamFyIiwgIiIpOworCisgICAgICAgIGp1YyA9IChKYXJVUkxDb25uZWN0aW9uKSB1Lm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoIlJldHVybmVkIGluY29ycmVjdCBlbnRyeU5hbWUiLCBqdWMuZ2V0RW50cnlOYW1lKCkpOworCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgaGFybW9ueS0zMDUzCisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJqYXI6ZmlsZTovLy9iYXIuamFyIS9mb28uamFyIS9CdWdzL0hlbGxvV29ybGQuY2xhc3MiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28uamFyIS9CdWdzL0hlbGxvV29ybGQuY2xhc3MiLCgoSmFyVVJMQ29ubmVjdGlvbil1cmwub3BlbkNvbm5lY3Rpb24oKSkuZ2V0RW50cnlOYW1lKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SmFyRW50cnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHUgPSBjcmVhdGVDb250ZW50KCJsZi5qYXIiLCAicGx1cy5ibXAiKTsKKworICAgICAgICBqdWMgPSAoSmFyVVJMQ29ubmVjdGlvbikgdS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBKYXJFbnRyeSIsICJwbHVzLmJtcCIsIGp1YworICAgICAgICAgICAgICAgIC5nZXRKYXJFbnRyeSgpLmdldE5hbWUoKSk7CisKKyAgICAgICAgdSA9IGNyZWF0ZUNvbnRlbnQoImxmLmphciIsICIiKTsKKworICAgICAgICBqdWMgPSAoSmFyVVJMQ29ubmVjdGlvbikgdS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBhc3NlcnROdWxsKCJSZXR1cm5lZCBpbmNvcnJlY3QgSmFyRW50cnkiLCBqdWMuZ2V0SmFyRW50cnkoKSk7CisKKyAgICAgICAgVVJMIGludlVSTCA9IGNyZWF0ZUNvbnRlbnQoIkludmFsaWRKYXIuamFyIiwgIlRlc3QuY2xhc3MiKTsKKworICAgICAgICBKYXJVUkxDb25uZWN0aW9uIGp1Q29ubiA9IChKYXJVUkxDb25uZWN0aW9uKSBpbnZVUkwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGp1Q29ubi5nZXRKYXJFbnRyeSgpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goamF2YS5pby5JT0V4Y2VwdGlvbiBpbykgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRKYXJGaWxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IGNyZWF0ZUNvbnRlbnQoImxmLmphciIsICJtaXNzaW5nIik7CisKKyAgICAgICAgSmFyVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEphclVSTENvbm5lY3Rpb24pIHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5jb25uZWN0KCk7CisgICAgICAgICAgICBmYWlsKCJEaWQgbm90IHRocm93IGV4Y2VwdGlvbiBvbiBjb25uZWN0Iik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5nZXRKYXJGaWxlKCk7CisgICAgICAgICAgICBmYWlsKCJEaWQgbm90IHRocm93IGV4Y2VwdGlvbiBhZnRlciBjb25uZWN0Iik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBVUkwgaW52VVJMID0gY3JlYXRlQ29udGVudCgiSW52YWxpZEphci5qYXIiLCAiVGVzdC5jbGFzcyIpOworCisgICAgICAgIEphclVSTENvbm5lY3Rpb24ganVDb25uID0gKEphclVSTENvbm5lY3Rpb24pIGludlVSTC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAganVDb25uLmdldEphckZpbGUoKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKGphdmEuaW8uSU9FeGNlcHRpb24gaW8pIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIEZpbGUgcmVzb3VyY2VzID0gU3VwcG9ydF9SZXNvdXJjZXMuY3JlYXRlVGVtcEZvbGRlcigpOworCisgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgImh5dHNfYXR0LmphciIpOworICAgICAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShyZXNvdXJjZXMudG9TdHJpbmcoKSArICIvaHl0c19hdHQuamFyIik7CisgICAgICAgIFVSTCBmVXJsMSA9IG5ldyBVUkwoImphcjpmaWxlOiIgKyBmaWxlLmdldFBhdGgoKSArICIhLyIpOworICAgICAgICBKYXJVUkxDb25uZWN0aW9uIGNvbjEgPSAoSmFyVVJMQ29ubmVjdGlvbikgZlVybDEub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgWmlwRmlsZSBqZjEgPSBjb24xLmdldEphckZpbGUoKTsKKyAgICAgICAgSmFyVVJMQ29ubmVjdGlvbiBjb24yID0gKEphclVSTENvbm5lY3Rpb24pIGZVcmwxLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIFppcEZpbGUgamYyID0gY29uMi5nZXRKYXJGaWxlKCk7CisgICAgICAgIGFzc2VydFRydWUoImZpbGU6IEphckZpbGVzIG5vdCB0aGUgc2FtZSIsIGpmMSA9PSBqZjIpOworICAgICAgICBqZjEuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmlsZSBzaG91bGQgZXhpc3QiLCBmaWxlLmV4aXN0cygpKTsKKworICAgICAgICBmVXJsMSA9IGNyZWF0ZUNvbnRlbnQoImxmLmphciIsICIiKTsKKworICAgICAgICBjb24xID0gKEphclVSTENvbm5lY3Rpb24pIGZVcmwxLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGpmMSA9IGNvbjEuZ2V0SmFyRmlsZSgpOworICAgICAgICBjb24yID0gKEphclVSTENvbm5lY3Rpb24pIGZVcmwxLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGpmMiA9IGNvbjIuZ2V0SmFyRmlsZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJodHRwOiBKYXJGaWxlcyBub3QgdGhlIHNhbWUiLCBqZjEgPT0gamYyKTsKKyAgICAgICAgamYxLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRKYXJGaWxlMjkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZSBqYXJGaWxlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiMSsyIDMiLCAidGVzdC5qYXIiKTsKKyAgICAgICAgamFyRmlsZS5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgSmFyT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBKYXJPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oamFyRmlsZSkpOworICAgICAgICBvdXQucHV0TmV4dEVudHJ5KG5ldyBaaXBFbnRyeSgidGVzdCIpKTsKKyAgICAgICAgb3V0LmNsb3NlRW50cnkoKTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisKKyAgICAgICAgSmFyVVJMQ29ubmVjdGlvbiBjb25uID0gKEphclVSTENvbm5lY3Rpb24pIG5ldyBVUkwoImphcjpmaWxlOiIKKyAgICAgICAgICAgICAgICArIGphckZpbGUuZ2V0QWJzb2x1dGVQYXRoKCkucmVwbGFjZUFsbCgiICIsICIlMjAiKSArICIhLyIpCisgICAgICAgICAgICAgICAgLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm4uZ2V0SmFyRmlsZSgpLmVudHJpZXMoKTsKKyAgICB9CisKKyAgICAvL1JlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMzQzNgorICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0VXNlQ2FjaGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgcmVzb3VyY2VzID0gU3VwcG9ydF9SZXNvdXJjZXMuY3JlYXRlVGVtcEZvbGRlcigpOworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsICJoeXRzX2F0dC5qYXIiKTsKKyAgICAgICAgRmlsZSBmaWxlID0gbmV3IEZpbGUocmVzb3VyY2VzLnRvU3RyaW5nKCkgKyAiL2h5dHNfYXR0LmphciIpOworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiamFyOmZpbGU6IiArIGZpbGUuZ2V0UGF0aCgpICsgIiEvSGFzQXR0cmlidXRlcy50eHQiKTsKKworICAgICAgICBKYXJVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSmFyVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0VXNlQ2FjaGVzKGZhbHNlKTsKKyAgICAgICAgY29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgSmFyRmlsZSBqYXJGaWxlMSA9IGNvbm5lY3Rpb24uZ2V0SmFyRmlsZSgpOworICAgICAgICBKYXJFbnRyeSBqYXJFbnRyeTEgPSBjb25uZWN0aW9uLmdldEphckVudHJ5KCk7CisgICAgICAgIGluLnJlYWQoKTsKKyAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgSmFyRmlsZSBqYXJGaWxlMiA9IGNvbm5lY3Rpb24uZ2V0SmFyRmlsZSgpOworICAgICAgICBKYXJFbnRyeSBqYXJFbnRyeTIgPSBjb25uZWN0aW9uLmdldEphckVudHJ5KCk7CisgICAgICAgIGFzc2VydFNhbWUoamFyRmlsZTEsIGphckZpbGUyKTsKKyAgICAgICAgYXNzZXJ0U2FtZShqYXJFbnRyeTEsIGphckVudHJ5Mik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEphckZpbGVVUkwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHUgPSBjcmVhdGVDb250ZW50KCJsZi5qYXIiLCAicGx1cy5ibXAiKTsKKworICAgICAgICBVUkwgZmlsZVVSTCA9IG5ldyBVUkwodS5nZXRQYXRoKCkuc3Vic3RyaW5nKDAsIHUuZ2V0UGF0aCgpLmluZGV4T2YoIiEiKSkpOworCisgICAgICAgIGp1YyA9IChKYXJVUkxDb25uZWN0aW9uKSB1Lm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBmaWxlIFVSTCIsIGp1Yy5nZXRKYXJGaWxlVVJMKCkuZXF1YWxzKAorICAgICAgICAgICAgICAgIGZpbGVVUkwpKTsKKworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiamFyOmZpbGU6Ly8vYmFyLmphciEvZm9vLmphciEvQnVncy9IZWxsb1dvcmxkLmNsYXNzIik7CisgICAgICAgIFN0cmluZyBqYXJGaWxlVXJsID0gKChKYXJVUkxDb25uZWN0aW9uKSB1cmwub3BlbkNvbm5lY3Rpb24oKSkuZ2V0SmFyRmlsZVVSTCgpLnRvU3RyaW5nKCk7CisgICAgICAgIC8vIFRoZSBSSSBvbWl0cyB0aGUgZW1wdHkgYXV0aG9yaXR5ICIvLyIgYnV0IHRoZSBSRkMgZG9lc24ndCBzYXkgdGhpcyBpcyBuZWNlc3NhcnkKKyAgICAgICAgYXNzZXJ0VHJ1ZShqYXJGaWxlVXJsLmVxdWFscygiZmlsZTovLy9iYXIuamFyIikgfHwgamFyRmlsZVVybC5lcXVhbHMoImZpbGU6L2Jhci5qYXIiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRNYWluQXR0cmlidXRlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdSA9IGNyZWF0ZUNvbnRlbnQoImxmLmphciIsICJzd3QuZGxsIik7CisKKyAgICAgICAganVjID0gKEphclVSTENvbm5lY3Rpb24pIHUub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgamF2YS51dGlsLmphci5BdHRyaWJ1dGVzIGEgPSBqdWMuZ2V0TWFpbkF0dHJpYnV0ZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgQXR0cmlidXRlcyIsICIxLjAiLCBhCisgICAgICAgICAgICAgICAgLmdldChqYXZhLnV0aWwuamFyLkF0dHJpYnV0ZXMuTmFtZS5NQU5JRkVTVF9WRVJTSU9OKSk7CisKKyAgICAgICAgVVJMIGludlVSTCA9IGNyZWF0ZUNvbnRlbnQoIkludmFsaWRKYXIuamFyIiwgIlRlc3QuY2xhc3MiKTsKKworICAgICAgICBKYXJVUkxDb25uZWN0aW9uIGp1Q29ubiA9IChKYXJVUkxDb25uZWN0aW9uKSBpbnZVUkwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGp1Q29ubi5nZXRNYWluQXR0cmlidXRlcygpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goamF2YS5pby5JT0V4Y2VwdGlvbiBpbykgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnB1dFN0cmVhbV9EZWxldGVKYXJGaWxlVXNpbmdVUkxDb25uZWN0aW9uKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgZW50cnkgPSAidGV4dC50eHQiOworICAgICAgICBTdHJpbmcgY3RzID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmlvLnRtcGRpciIpOworICAgICAgICBGaWxlIHRtcERpciA9IG5ldyBGaWxlKGN0cyk7CisgICAgICAgIEZpbGUgamFyRmlsZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoImZpbGUiLCAiLmphciIsIHRtcERpcik7CisgICAgICAgIFN0cmluZyBqYXJGaWxlTmFtZSA9IGphckZpbGUuZ2V0UGF0aCgpOworICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIGphckZpbGVPdXRwdXRTdHJlYW0gPSBuZXcgRmlsZU91dHB1dFN0cmVhbShqYXJGaWxlTmFtZSk7CisgICAgICAgIEphck91dHB1dFN0cmVhbSBvdXQgPSBuZXcgSmFyT3V0cHV0U3RyZWFtKG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICBqYXJGaWxlT3V0cHV0U3RyZWFtKSk7CisgICAgICAgIEphckVudHJ5IGphckVudHJ5ID0gbmV3IEphckVudHJ5KGVudHJ5KTsKKyAgICAgICAgb3V0LnB1dE5leHRFbnRyeShqYXJFbnRyeSk7CisgICAgICAgIG91dC53cml0ZShuZXcgYnl0ZVtdIHsgJ2EnLCAnYicsICdjJyB9KTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImphcjpmaWxlOiIgKyBqYXJGaWxlTmFtZSArICIhLyIgKyBlbnRyeSk7CisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubiA9IHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uLnNldFVzZUNhY2hlcyhmYWxzZSk7CisgICAgICAgIElucHV0U3RyZWFtIGlzID0gY29ubi5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgIGFzc2VydFRydWUoamFyRmlsZS5kZWxldGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBqYXJGaWxlTmFtZSA9ICJmaWxlLmphciI7CisgICAgICAgICAgICBTdHJpbmcgZW50cnkgPSAidGV4dC50eHQiOworICAgICAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImphcjpmaWxlOiIgKyBqYXJGaWxlTmFtZSArICIhLyIgKyBlbnRyeSk7CisgICAgICAgICAgICBUZXN0SmFyVVJMQ29ubmVjdGlvbiBqYXJDb25uID0gbmV3IFRlc3RKYXJVUkxDb25uZWN0aW9uKHVybCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobmV3IFVSTCgiZmlsZTpmaWxlLmphciIpLCBqYXJDb25uLmdldEphckZpbGVVUkwoKSk7CisgICAgICAgIH0gY2F0Y2goTWFsZm9ybWVkVVJMRXhjZXB0aW9uIG1lKSB7CisgICAgICAgICAgICBmYWlsKCJNYWxmb3JtZWRVUkxFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkwgW10gdXJscyA9IHtuZXcgVVJMKCJmaWxlOmZpbGUuamFyIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVVJMKCJodHRwOi8vZm9vLmNvbS9mb28vZm9vLmphciIpfTsKKworICAgICAgICAgICAgZm9yKFVSTCB1cmwgOiB1cmxzKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgbmV3IFRlc3RKYXJVUkxDb25uZWN0aW9uKHVybCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIk1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtZSkgeworICAgICAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtZSkgeworICAgICAgICAgICAgZmFpbCgiTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBUZXN0SmFyVVJMQ29ubmVjdGlvbiBleHRlbmRzIEphclVSTENvbm5lY3Rpb24geworCisgICAgICAgIHByb3RlY3RlZCBUZXN0SmFyVVJMQ29ubmVjdGlvbihVUkwgYXJnMCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcihhcmcwKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgSmFyRmlsZSBnZXRKYXJGaWxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNvbm5lY3QoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIH0KKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZFBhc3N3b3JkQXV0aGVudGljYXRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRQYXNzd29yZEF1dGhlbnRpY2F0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlkNWUxNDcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRQYXNzd29yZEF1dGhlbnRpY2F0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5ldDsKKworaW1wb3J0IGphdmEubmV0LlBhc3N3b3JkQXV0aGVudGljYXRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkUGFzc3dvcmRBdXRoZW50aWNhdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmckQygpIHsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSAibmFtZSI7CisgICAgICAgIGNoYXJbXSBwYXNzd29yZCA9ICJodW50ZXIyIi50b0NoYXJBcnJheSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFBhc3N3b3JkQXV0aGVudGljYXRpb24obmFtZSwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBQYXNzd29yZEF1dGhlbnRpY2F0aW9uIHBhID0gbmV3IFBhc3N3b3JkQXV0aGVudGljYXRpb24obnVsbCwgcGFzc3dvcmQpOworICAgICAgICBhc3NlcnROdWxsKHBhLmdldFVzZXJOYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMocGFzc3dvcmQubGVuZ3RoLCBwYS5nZXRQYXNzd29yZCgpLmxlbmd0aCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkUHJveHlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRQcm94eVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMTViYmQwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkUHJveHlUZXN0LmphdmEKQEAgLTAsMCArMSw3MCBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLm5ldDsKKworaW1wb3J0IGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlByb3h5OworaW1wb3J0IGphdmEubmV0LlNvY2tldEFkZHJlc3M7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkUHJveHlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBTb2NrZXRBZGRyZXNzIGFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoIjEyNy4wLjAuMSIsIDEyMzQpOworCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRyZXNzKCkgeworICAgICAgICBQcm94eSBwcm94eSA9IG5ldyBQcm94eShQcm94eS5UeXBlLlNPQ0tTLCBhZGRyZXNzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGFkZHJlc3MsIHByb3h5LmFkZHJlc3MoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBQcm94eShQcm94eS5UeXBlLlNPQ0tTLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGFzaENvZGUoKSB7CisgICAgICAgIFNvY2tldEFkZHJlc3MgYWRkcmVzczEgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoIjEyNy4wLjAuMSIsIDEyMzQpOworCisgICAgICAgIFByb3h5IHByb3h5MSA9IG5ldyBQcm94eShQcm94eS5UeXBlLkhUVFAsIGFkZHJlc3MxKTsKKyAgICAgICAgUHJveHkgcHJveHkyID0gbmV3IFByb3h5KFByb3h5LlR5cGUuSFRUUCwgYWRkcmVzczEpOworICAgICAgICBhc3NlcnRUcnVlKHByb3h5MS5oYXNoQ29kZSgpID09IHByb3h5Mi5oYXNoQ29kZSgpKTsKKworICAgICAgICBuZXcgUHJveHkoUHJveHkuVHlwZS5TT0NLUywgYWRkcmVzczEpOworICAgICAgICBQcm94eSBwcm94eTQgPSBuZXcgUHJveHkoUHJveHkuVHlwZS5TT0NLUywgYWRkcmVzczEpOworICAgICAgICBhc3NlcnRUcnVlKHByb3h5MS5oYXNoQ29kZSgpID09IHByb3h5Mi5oYXNoQ29kZSgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKHByb3h5MS5oYXNoQ29kZSgpICE9IHByb3h5NC5oYXNoQ29kZSgpKTsKKworICAgICAgICBTb2NrZXRBZGRyZXNzIGFkZHJlc3MyID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKCIxMjcuMC4wLjEiLCAxMjM1KTsKKworICAgICAgICBQcm94eSBwcm94eTUgPSBuZXcgUHJveHkoUHJveHkuVHlwZS5TT0NLUywgYWRkcmVzczEpOworICAgICAgICBQcm94eSBwcm94eTYgPSBuZXcgUHJveHkoUHJveHkuVHlwZS5TT0NLUywgYWRkcmVzczIpOworICAgICAgICBhc3NlcnRUcnVlKHByb3h5NS5oYXNoQ29kZSgpICE9IHByb3h5Ni5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3R5cGUoKSB7CisKKyAgICAgICAgUHJveHkgcHJveHkgPSBuZXcgUHJveHkoUHJveHkuVHlwZS5IVFRQLCBhZGRyZXNzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFByb3h5LlR5cGUuSFRUUCwgcHJveHkudHlwZSgpKTsKKworICAgICAgICBwcm94eSA9IG5ldyBQcm94eShQcm94eS5UeXBlLlNPQ0tTLCBhZGRyZXNzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFByb3h5LlR5cGUuU09DS1MsIHByb3h5LnR5cGUoKSk7CisKKyAgICAgICAgcHJveHkgPSBQcm94eS5OT19QUk9YWTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFByb3h5LlR5cGUuRElSRUNULCBwcm94eS50eXBlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZFNlcnZlclNvY2tldFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZFNlcnZlclNvY2tldFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZjM1NDg5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkU2VydmVyU29ja2V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMzkzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU2VydmVyU29ja2V0OworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNvY2tldEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRJbXBsOworaW1wb3J0IGphdmEubmV0LlNvY2tldEltcGxGYWN0b3J5OworaW1wb3J0IGphdmEubmV0LlNvY2tldFRpbWVvdXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5TZXJ2ZXJTb2NrZXRDaGFubmVsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfUG9ydE1hbmFnZXI7CisKK3B1YmxpYyBjbGFzcyBPbGRTZXJ2ZXJTb2NrZXRUZXN0IGV4dGVuZHMgT2xkU29ja2V0VGVzdENhc2UgeworCisgICAgYm9vbGVhbiBpc0NyZWF0ZUNhbGxlZCA9IGZhbHNlOworICAgIFNlcnZlclNvY2tldCBzOworICAgIFNvY2tldCBzY29ubjsKKyAgICBUaHJlYWQgdDsKKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0UGVyZm9ybWFuY2VQcmVmZXJlbmNlX0ludF9JbnRfSW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHBlcmZvcm1hbmNlUHJlZmVyZW5jZVRlc3QoMSwgMCwgMCk7CisgICAgICAgIHBlcmZvcm1hbmNlUHJlZmVyZW5jZVRlc3QoMSwgMSwgMSk7CisgICAgICAgIHBlcmZvcm1hbmNlUHJlZmVyZW5jZVRlc3QoMCwgMSwgMik7CisgICAgICAgIHBlcmZvcm1hbmNlUHJlZmVyZW5jZVRlc3QoSW50ZWdlci5NQVhfVkFMVUUsIEludGVnZXIuTUFYX1ZBTFVFLAorICAgICAgICAgICAgICAgIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICB9CisKKyAgICB2b2lkIHBlcmZvcm1hbmNlUHJlZmVyZW5jZVRlc3QoaW50IGNvbm5lY3Rpb25UaW1lLCBpbnQgbGF0ZW5jeSwKKyAgICAgICAgICAgIGludCBiYW5kd2lkdGgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTZXJ2ZXJTb2NrZXQgdGhlU29ja2V0ID0gbmV3IFNlcnZlclNvY2tldCgpOworICAgICAgICB0aGVTb2NrZXQuc2V0UGVyZm9ybWFuY2VQcmVmZXJlbmNlcyhjb25uZWN0aW9uVGltZSwgbGF0ZW5jeSwgYmFuZHdpZHRoKTsKKworICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyB0aGVBZGRyZXNzID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzCisgICAgICAgICAgICAgICAgLmdldExvY2FsSG9zdCgpLCAwKTsKKyAgICAgICAgdGhlU29ja2V0LmJpbmQodGhlQWRkcmVzcyk7CisgICAgICAgIGludCBwb3J0TnVtYmVyID0gdGhlU29ja2V0LmdldExvY2FsUG9ydCgpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJSZXR1cm5lZCBpbmNvcnJlY3QgSW5ldFNvY2tldEFkZHJlc3MoMik6IgorICAgICAgICAgICAgICAgICAgICAgICAgKyB0aGVTb2NrZXQuZ2V0TG9jYWxTb2NrZXRBZGRyZXNzKCkudG9TdHJpbmcoKQorICAgICAgICAgICAgICAgICAgICAgICAgKyAiRXhwZWN0ZWQ6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgKG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9ydE51bWJlcikpLnRvU3RyaW5nKCksIHRoZVNvY2tldAorICAgICAgICAgICAgICAgICAgICAgICAgLmdldExvY2FsU29ja2V0QWRkcmVzcygpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldExvY2FsSG9zdCgpLCBwb3J0TnVtYmVyKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJTZXJ2ZXIgc29ja2V0IG5vdCBib3VuZCB3aGVuIGl0IHNob3VsZCBiZToiLCB0aGVTb2NrZXQKKyAgICAgICAgICAgICAgICAuaXNCb3VuZCgpKTsKKworICAgICAgICAvLyBub3cgbWFrZSBzdXJlIHRoYXQgaXQgaXMgYWN0dWFsbHkgYm91bmQgYW5kIGxpc3RlbmluZyBvbiB0aGUKKyAgICAgICAgLy8gYWRkcmVzcyB3ZSBwcm92aWRlZAorICAgICAgICBTb2NrZXQgY2xpZW50U29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBjbEFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAuZ2V0TG9jYWxIb3N0KCksIHBvcnROdW1iZXIpOworICAgICAgICBjbGllbnRTb2NrZXQuY29ubmVjdChjbEFkZHJlc3MpOworICAgICAgICBTb2NrZXQgc2VydlNvY2sgPSB0aGVTb2NrZXQuYWNjZXB0KCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNsQWRkcmVzcywgY2xpZW50U29ja2V0LmdldFJlbW90ZVNvY2tldEFkZHJlc3MoKSk7CisgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICBzZXJ2U29jay5jbG9zZSgpOworICAgICAgICBjbGllbnRTb2NrZXQuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySUkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgZnJlZVBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgIHMgPSBuZXcgU2VydmVyU29ja2V0KGZyZWVQb3J0TnVtYmVyLCAxKTsKKyAgICAgICAgcy5zZXRTb1RpbWVvdXQoMjAwMCk7CisgICAgICAgIHN0YXJ0Q2xpZW50KGZyZWVQb3J0TnVtYmVyKTsKKyAgICAgICAgc2Nvbm4gPSBzLmFjY2VwdCgpOworICAgICAgICBzY29ubi5jbG9zZSgpOworICAgICAgICBzLmNsb3NlKCk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFNTQ2xpZW50IGltcGxlbWVudHMgUnVubmFibGUgeworICAgICAgICBTb2NrZXQgY3M7CisKKyAgICAgICAgaW50IHBvcnQ7CisKKyAgICAgICAgcHVibGljIFNTQ2xpZW50KGludCBwcnQpIHsKKyAgICAgICAgICAgIHBvcnQgPSBwcnQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIEdvIHRvIHNsZWVwIHNvIHRoZSBzZXJ2ZXIgY2FuIHNldHVwIGFuZCB3YWl0IGZvciBjb25uZWN0aW9uCisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgICAgICAgICAgIGNzID0gbmV3IFNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKS5nZXRIb3N0TmFtZSgpLCBwb3J0KTsKKyAgICAgICAgICAgICAgICAvLyBTbGVlcCBhZ2FpbiB0byBhbGxvdyBzZXJ2ZXIgc2lkZSBwcm9jZXNzaW5nLiBUaHJlYWQgaXMKKyAgICAgICAgICAgICAgICAvLyBzdG9wcGVkIGJ5IHNlcnZlci4KKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMDApOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFcnJvciBlc3RhYmxpc2hpbmcgY2xpZW50OiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNzICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgICAgICBjcy5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFNlcnZlclNvY2tldCBzcyA9IG5ldyBTZXJ2ZXJTb2NrZXQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBzcy5nZXRMb2NhbFBvcnQoKSk7CisgICAgICAgIHNzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgIHMgPSBuZXcgU2VydmVyU29ja2V0KHBvcnROdW1iZXIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFNlcnZlclNvY2tldChwb3J0TnVtYmVyKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdGFydENsaWVudChzLmdldExvY2FsUG9ydCgpKTsKKyAgICAgICAgICAgIHNjb25uID0gcy5hY2NlcHQoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIldhcyB1bmFibGUgdG8gYWNjZXB0IGNvbm5lY3Rpb24iLCBzY29ubik7CisgICAgICAgICAgICBzY29ubi5jbG9zZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgcy5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgcyA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdGFydENsaWVudChzLmdldExvY2FsUG9ydCgpKTsKKyAgICAgICAgICAgIHNjb25uID0gcy5hY2NlcHQoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIldhcyB1bmFibGUgdG8gYWNjZXB0IGNvbm5lY3Rpb24iLCBzY29ubik7CisgICAgICAgICAgICBzY29ubi5jbG9zZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgcy5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcklJTGphdmFfbmV0X0luZXRBZGRyZXNzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGZyZWVQb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworCisgICAgICAgIFNlcnZlclNvY2tldCBzcyA9IG5ldyBTZXJ2ZXJTb2NrZXQoZnJlZVBvcnROdW1iZXIsIDEwLCBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2VydmVyU29ja2V0KGZyZWVQb3J0TnVtYmVyLCAxMCwgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCkpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBzcy5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2VydmVyU29ja2V0KDY1NTM2LCAxMCwgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCkpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Mb2NhbFBvcnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTZXJ2ZXJTb2NrZXQgc3MxID0gbmV3IFNlcnZlclNvY2tldCg0MjQyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNzMS5nZXRMb2NhbFBvcnQoKSwgNDI0Mik7CisgICAgICAgIHNzMS5jbG9zZSgpOworCisgICAgICAgIFNlcnZlclNvY2tldCBzczIgPSBuZXcgU2VydmVyU29ja2V0KCk7CisgICAgICAgIHNzMi5iaW5kKG5ldyBJbmV0U29ja2V0QWRkcmVzcygiMTI3LjAuMC4xIiwgNDM0MykpOworICAgICAgICBhc3NlcnRFcXVhbHMoc3MyLmdldExvY2FsUG9ydCgpLCA0MzQzKTsKKyAgICAgICAgc3MyLmNsb3NlKCk7CisKKyAgICAgICAgU2VydmVyU29ja2V0IHNzMyA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisgICAgICAgIGFzc2VydFRydWUoc3MzLmdldExvY2FsUG9ydCgpICE9IDApOworICAgICAgICBzczMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBjbGFzcyBNb2NrU29ja2V0RmFjdG9yeSBpbXBsZW1lbnRzIFNvY2tldEltcGxGYWN0b3J5IHsKKyAgICAgICAgcHVibGljIFNvY2tldEltcGwgY3JlYXRlU29ja2V0SW1wbCgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgTW9ja1NvY2tldEltcGwoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JJX1NvY2tzU2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gSGFybW9ueS02MjMgcmVncmVzc2lvbiB0ZXN0CisgICAgICAgIFNlcnZlclNvY2tldCBzcyA9IG51bGw7CisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSAoUHJvcGVydGllcykgU3lzdGVtLmdldFByb3BlcnRpZXMoKS5jbG9uZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJzb2Nrc1Byb3h5SG9zdCIsICIxMjcuMC4wLjEiKTsKKyAgICAgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgic29ja3NQcm94eVBvcnQiLCAiMTIzNDUiKTsKKyAgICAgICAgICAgIHNzID0gbmV3IFNlcnZlclNvY2tldCgwKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0aWVzKHByb3BzKTsKKyAgICAgICAgICAgIGlmIChudWxsICE9IHNzKSB7CisgICAgICAgICAgICAgICAgc3MuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWNjZXB0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisKKyAgICAgICAgU2VydmVyU29ja2V0IG5ld1NvY2tldCA9IG5ldyBTZXJ2ZXJTb2NrZXQocG9ydE51bWJlcik7CisgICAgICAgIG5ld1NvY2tldC5zZXRTb1RpbWVvdXQoNTAwKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldCBhY2NlcHRlZCA9IG5ld1NvY2tldC5hY2NlcHQoKTsKKyAgICAgICAgICAgIGZhaWwoIlNvY2tldFRpbWVvdXRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd246ICIgKyBhY2NlcHRlZCk7CisgICAgICAgIH0gY2F0Y2goU29ja2V0VGltZW91dEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIG5ld1NvY2tldC5jbG9zZSgpOworCisgICAgICAgIFNlcnZlclNvY2tldENoYW5uZWwgc3NjID0gU2VydmVyU29ja2V0Q2hhbm5lbC5vcGVuKCk7CisgICAgICAgIFNlcnZlclNvY2tldCBzcyA9IHNzYy5zb2NrZXQoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3MuYWNjZXB0KCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb24gaWJtZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc3MuY2xvc2UoKTsKKyAgICAgICAgICAgIHNzYy5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTb1RpbWVvdXRfc2V0U29UaW1lb3V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRPRE86IGEgdXNlZnVsIHRlc3Qgd291bGQgY2hlY2sgdGhhdCBzZXRTb1RpbWVvdXQgYWN0dWFsbHkgY2F1c2VzIHRpbWVvdXRzIQorICAgICAgICBTZXJ2ZXJTb2NrZXQgcyA9IG5ldyBTZXJ2ZXJTb2NrZXQoKTsKKyAgICAgICAgcy5zZXRTb1RpbWVvdXQoMTUwMCk7CisgICAgICAgIGludCBtcyA9IHMuZ2V0U29UaW1lb3V0KCk7CisgICAgICAgIGlmIChtcyA8IDE1MDAtMTAgfHwgbXMgPiAxNTAwKzEwKSB7CisgICAgICAgICAgICBmYWlsKCJzdXNwaWNpb3VzIHRpbWVvdXQ6ICIgKyBtcyk7CisgICAgICAgIH0KKyAgICAgICAgcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5nZXRTb1RpbWVvdXQoKTsKKyAgICAgICAgICAgIGZhaWwoIlNvY2tldEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMuc2V0U29UaW1lb3V0KDEwMDApOworICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcyA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisgICAgICAgIGludCBwb3J0TnVtYmVyID0gcy5nZXRMb2NhbFBvcnQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzLnRvU3RyaW5nKCkuY29udGFpbnMoIiIgKyBwb3J0TnVtYmVyKSk7CisgICAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFJldXNlQWRkcmVzc1ooKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTZXJ2ZXJTb2NrZXQgbmV3U29ja2V0ID0gbmV3IFNlcnZlclNvY2tldCgpOworICAgICAgICBuZXdTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ld1NvY2tldC5zZXRSZXVzZUFkZHJlc3ModHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU29ja2V0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFJldXNlQWRkcmVzcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFNlcnZlclNvY2tldCBuZXdTb2NrZXQgPSBuZXcgU2VydmVyU29ja2V0KCk7CisgICAgICAgIG5ld1NvY2tldC5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3U29ja2V0LmdldFJldXNlQWRkcmVzcygpOworICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFNvY2tldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFJlY2VpdmVCdWZmZXJTaXplSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFNlcnZlclNvY2tldCBuZXdTb2NrZXQgPSBuZXcgU2VydmVyU29ja2V0KCk7CisgICAgICAgIG5ld1NvY2tldC5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3U29ja2V0LnNldFJlY2VpdmVCdWZmZXJTaXplKDEwKTsKKyAgICAgICAgICAgIGZhaWwoIlNvY2tldEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChTb2NrZXRFeGNlcHRpb24gc2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UmVjZWl2ZUJ1ZmZlclNpemUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTZXJ2ZXJTb2NrZXQgbmV3U29ja2V0ID0gbmV3IFNlcnZlclNvY2tldCgpOworICAgICAgICBuZXdTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ld1NvY2tldC5nZXRSZWNlaXZlQnVmZmVyU2l6ZSgpOworICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAocyAhPSBudWxsKQorICAgICAgICAgICAgICAgIHMuY2xvc2UoKTsKKyAgICAgICAgICAgIGlmIChzY29ubiAhPSBudWxsKQorICAgICAgICAgICAgICAgIHNjb25uLmNsb3NlKCk7CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKQorICAgICAgICAgICAgICAgIHQuaW50ZXJydXB0KCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzdGFydENsaWVudChpbnQgcG9ydCkgeworICAgICAgICB0ID0gbmV3IFRocmVhZChuZXcgU1NDbGllbnQocG9ydCksICJTU0NsaWVudCIpOworICAgICAgICB0LnN0YXJ0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXhjZXB0aW9uIGR1cmluZyBzdGFydENsaW5ldCgpIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBNb2NrU29ja2V0SW1wbCBleHRlbmRzIFNvY2tldEltcGwgeworICAgICAgICBwdWJsaWMgTW9ja1NvY2tldEltcGwoKSB7CisgICAgICAgICAgICBpc0NyZWF0ZUNhbGxlZCA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoYm9vbGVhbiBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgY29ubmVjdChTdHJpbmcgYXJnMCwgaW50IGFyZzEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgdm9pZCBjb25uZWN0KEluZXRBZGRyZXNzIGFyZzAsIGludCBhcmcxKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgY29ubmVjdChTb2NrZXRBZGRyZXNzIGFyZzAsIGludCBhcmcxKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgYmluZChJbmV0QWRkcmVzcyBhcmcwLCBpbnQgYXJnMSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGxpc3RlbihpbnQgYXJnMCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGFjY2VwdChTb2NrZXRJbXBsIGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgT3V0cHV0U3RyZWFtIGdldE91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgc2VuZFVyZ2VudERhdGEoaW50IGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXRPcHRpb24oaW50IGFyZzAsIE9iamVjdCBhcmcxKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0T3B0aW9uKGludCBhcmcwKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkU29ja2V0SW1wbEZhY3RvcnlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRTb2NrZXRJbXBsRmFjdG9yeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YzEzMzM3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkU29ja2V0SW1wbEZhY3RvcnlUZXN0LmphdmEKQEAgLTAsMCArMSwxNzcgQEAKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5ldDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuU29ja2V0SW1wbDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRJbXBsRmFjdG9yeTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKworcHVibGljIGNsYXNzIE9sZFNvY2tldEltcGxGYWN0b3J5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIFNvY2tldEltcGxGYWN0b3J5IG9sZEZhY3RvcnkgPSBudWxsOworICAgIEZpZWxkIGZhY3RvcnlGaWVsZCA9IG51bGw7CisKKyAgICBib29sZWFuIGlzVGVzdGFibGUgPSBmYWxzZTsKKworICAgIGJvb2xlYW4gaVNvY2tldEltcGxDYWxsZWQgPSBmYWxzZTsKKyAgICBib29sZWFuIGlzQ3JlYXRlU29ja2V0SW1wbCA9IGZhbHNlOworCisgICAgcHVibGljIHZvaWQgdGVzdF9jcmVhdGVTb2NrZXRJbXBsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja1NvY2tldEltcGxGYWN0b3J5IGZhY3RvcnkgPSBuZXcgTW9ja1NvY2tldEltcGxGYWN0b3J5KCk7CisgICAgICAgIGlmKGlzVGVzdGFibGUpIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGlzQ3JlYXRlU29ja2V0SW1wbCk7CisgICAgICAgICAgICBTb2NrZXQuc2V0U29ja2V0SW1wbEZhY3RvcnkoZmFjdG9yeSk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbmV3IFNvY2tldCgpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoaXNDcmVhdGVTb2NrZXRJbXBsKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGlTb2NrZXRJbXBsQ2FsbGVkKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTb2NrZXQuc2V0U29ja2V0SW1wbEZhY3RvcnkoZmFjdG9yeSk7CisgICAgICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICAgICAgfSBjYXRjaChTb2NrZXRFeGNlcHRpb24gc2UpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgU29ja2V0LnNldFNvY2tldEltcGxGYWN0b3J5KG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoIlNvY2tldEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2goU29ja2V0RXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICAgICAgfQorCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBTb2NrZXRJbXBsIHNpID0gZmFjdG9yeS5jcmVhdGVTb2NrZXRJbXBsKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChzaS5nZXRPcHRpb24oMCkpOworICAgICAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgeworICAgICAgICBGaWVsZCBbXSBmaWVsZHMgPSBTb2NrZXQuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZHMoKTsKKyAgICAgICAgaW50IGNvdW50ZXIgPSAwOworICAgICAgICBmb3IgKEZpZWxkIGZpZWxkIDogZmllbGRzKSB7CisgICAgICAgICAgICBpZiAoU29ja2V0SW1wbEZhY3RvcnkuY2xhc3MuZXF1YWxzKGZpZWxkLmdldFR5cGUoKSkpIHsKKyAgICAgICAgICAgICAgICBjb3VudGVyKys7CisgICAgICAgICAgICAgICAgZmFjdG9yeUZpZWxkID0gZmllbGQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZihjb3VudGVyID09IDEpIHsKKworICAgICAgICAgICAgaXNUZXN0YWJsZSA9IHRydWU7CisKKyAgICAgICAgICAgIGZhY3RvcnlGaWVsZC5zZXRBY2Nlc3NpYmxlKHRydWUpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBvbGRGYWN0b3J5ID0gKFNvY2tldEltcGxGYWN0b3J5KSBmYWN0b3J5RmllbGQuZ2V0KG51bGwpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIHRocm93biBkdXJpbmcgc2V0VXA6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiB3YXMgdGhyb3duIGR1cmluZyBzZXRVcDogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgaWYoaXNUZXN0YWJsZSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmYWN0b3J5RmllbGQuc2V0KG51bGwsIG9sZEZhY3RvcnkpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIHRocm93biBkdXJpbmcgdGVhckRvd246ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiB3YXMgdGhyb3duIGR1cmluZyB0ZWFyRG93bjogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBNb2NrU29ja2V0SW1wbEZhY3RvcnkgaW1wbGVtZW50cyBTb2NrZXRJbXBsRmFjdG9yeSB7CisKKyAgICAgICAgcHVibGljIFNvY2tldEltcGwgY3JlYXRlU29ja2V0SW1wbCgpIHsKKyAgICAgICAgICAgIGlzQ3JlYXRlU29ja2V0SW1wbCA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gbmV3IE1vY2tTb2NrZXRJbXBsKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBNb2NrU29ja2V0SW1wbCBleHRlbmRzIFNvY2tldEltcGwgeworCisgICAgICAgIHB1YmxpYyBNb2NrU29ja2V0SW1wbCgpIHsKKyAgICAgICAgICAgIHN1cGVyKCk7CisgICAgICAgICAgICBpU29ja2V0SW1wbENhbGxlZCA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGFjY2VwdChTb2NrZXRJbXBsIGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgYmluZChJbmV0QWRkcmVzcyBhcmcwLCBpbnQgYXJnMSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgY29ubmVjdChTdHJpbmcgYXJnMCwgaW50IGFyZzEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgY29ubmVjdChJbmV0QWRkcmVzcyBhcmcwLCBpbnQgYXJnMSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBjb25uZWN0KFNvY2tldEFkZHJlc3MgYXJnMCwgaW50IGFyZzEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgY3JlYXRlKGJvb2xlYW4gYXJnMCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgbGlzdGVuKGludCBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIHNlbmRVcmdlbnREYXRhKGludCBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBnZXRPcHRpb24oaW50IGFyZzApIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXRPcHRpb24oaW50IGFyZzAsIE9iamVjdCBhcmcxKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZFNvY2tldFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZFNvY2tldFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZGE5NTU3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkU29ja2V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjQ1MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEubmV0LkJpbmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuQ29ubmVjdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0NEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuSW5ldDZBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlByb3h5OworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuU29ja2V0SW1wbDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRUaW1lb3V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLklsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU29ja2V0Q2hhbm5lbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0NvbmZpZ3VyYXRpb247CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1BvcnRNYW5hZ2VyOworCitwdWJsaWMgY2xhc3MgT2xkU29ja2V0VGVzdCBleHRlbmRzIE9sZFNvY2tldFRlc3RDYXNlIHsKKworICAgIFNlcnZlclNvY2tldCBzczsKKworICAgIFNvY2tldCBzOworCisgICAgVGhyZWFkIHQ7CisKKyAgICBTZWN1cml0eU1hbmFnZXIgc20gPSBuZXcgU2VjdXJpdHlNYW5hZ2VyKCkgeworCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihQZXJtaXNzaW9uIHBlcm0pIHt9CisKKyAgICAgICAgcHVibGljIHZvaWQgY2hlY2tDb25uZWN0KFN0cmluZyBob3N0LCBpbnQgcG9ydCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9OworCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgLy8gY3JlYXRlIHRoZSBzb2NrZXQgYW5kIHRoZW4gdmFsaWRhdGUgc29tZSBiYXNpYyBzdGF0ZQorICAgICAgICBzID0gbmV3IFNvY2tldCgpOworICAgICAgICBhc3NlcnRGYWxzZSgibmV3IHNvY2tldCBzaG91bGQgbm90IGJlIGNvbm5lY3RlZCIsIHMuaXNDb25uZWN0ZWQoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJuZXcgc29ja2V0IHNob3VsZCBub3QgYmUgYm91bmQiLCBzLmlzQm91bmQoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJuZXcgc29ja2V0IHNob3VsZCBub3QgYmUgY2xvc2VkIiwgcy5pc0Nsb3NlZCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIm5ldyBzb2NrZXQgc2hvdWxkIG5vdCBiZSBpbiBJbnB1dFNodXRkb3duIiwgcworICAgICAgICAgICAgICAgIC5pc0lucHV0U2h1dGRvd24oKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJuZXcgc29ja2V0IHNob3VsZCBub3QgYmUgaW4gT3V0cHV0U2h1dGRvd24iLCBzCisgICAgICAgICAgICAgICAgLmlzT3V0cHV0U2h1dGRvd24oKSk7CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmdJKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubmV0LlNvY2tldChqYXZhLmxhbmcuU3RyaW5nLCBpbnQpCisgICAgICAgIGludCBzcG9ydCA9IHN0YXJ0U2VydmVyKCJDb25zIFN0cmluZyxJIik7CisgICAgICAgIHMgPSBuZXcgU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLmdldEhvc3ROYW1lKCksIHNwb3J0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGNyZWF0ZSBzb2NrZXQiLCBzLmdldFBvcnQoKSA9PSBzcG9ydCk7CisKKyAgICAgICAgLy9yZWdyZXNzaW9uIGZvciBIQVJNT05ZLTk0NgorICAgICAgICBTZXJ2ZXJTb2NrZXQgc3MgPSBudWxsOworICAgICAgICBTb2NrZXQgcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzcyA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisgICAgICAgICAgICBzID0gbmV3IFNvY2tldCgiMC4wLjAuMCIsIHNzLmdldExvY2FsUG9ydCgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3MuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvL2lnbm9yZQorICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy9pZ25vcmUKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU29ja2V0KCJ1bmtub3duLmhvc3QiLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIlVua25vd25Ib3N0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFVua25vd25Ib3N0RXhjZXB0aW9uIHVoZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgICAgIFNvY2tldCBzb2NrZXQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc29ja2V0ID0gbmV3IFNvY2tldChJbmV0QWRkcmVzcy5nZXRCeU5hbWUobnVsbCksIHNwb3J0KTsKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIGFkZHJlc3MgPSBzb2NrZXQuZ2V0TG9jYWxBZGRyZXNzKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGFkZHJlc3MuaXNMb29wYmFja0FkZHJlc3MoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaChFeGNlcHRpb24gZSkge30KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZ0lMamF2YV9uZXRfSW5ldEFkZHJlc3NJMSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBzcG9ydCA9IHN0YXJ0U2VydmVyKCJDb25zIFN0cmluZyxJLEluZXRBZGRyZXNzLEkiKTsKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgIHMgPSBuZXcgU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLmdldEhvc3ROYW1lKCksIHNwb3J0LAorICAgICAgICAgICAgICAgIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBwb3J0TnVtYmVyKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGNyZWF0ZSBzb2NrZXQiLCBzLmdldFBvcnQoKSA9PSBzcG9ydCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfU3RyaW5nSUxqYXZhX25ldF9JbmV0QWRkcmVzc0kyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHRlc3RQb3J0ID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICBTb2NrZXQgczEgPSBuZXcgU29ja2V0KCJ3d3cuZ29vZ2xlLmNvbSIsIDgwLCBudWxsLCB0ZXN0UG9ydCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTb2NrZXQgczIgPSBuZXcgU29ja2V0KCJ3d3cuZ29vZ2xlLmNvbSIsIDgwLCBudWxsLCB0ZXN0UG9ydCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHMyLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmYWlsKCJzZWNvbmQgY29ubmVjdCBzaG91bGQgaGF2ZSBmYWlsZWQgd2l0aCBFQUREUklOVVNFIik7CisgICAgICAgIH0gY2F0Y2ggKEJpbmRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIC8vIHN1Y2Nlc3MhCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHMxLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmdJWigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLm5ldC5Tb2NrZXQoamF2YS5sYW5nLlN0cmluZywgaW50LCBib29sZWFuKQorICAgICAgICBpbnQgc3BvcnQgPSBzdGFydFNlcnZlcigiQ29ucyBTdHJpbmcsSSxaIik7CisgICAgICAgIHMgPSBuZXcgU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLmdldEhvc3ROYW1lKCksIHNwb3J0LCB0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGNyZWF0ZSBzb2NrZXQiLCBzLmdldFBvcnQoKSA9PSBzcG9ydCk7CisKKyAgICAgICAgcyA9IG5ldyBTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCkuZ2V0SG9zdE5hbWUoKSwgc3BvcnQsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbmV0X0luZXRBZGRyZXNzSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLm5ldC5Tb2NrZXQoamF2YS5uZXQuSW5ldEFkZHJlc3MsIGludCkKKyAgICAgICAgaW50IHNwb3J0ID0gc3RhcnRTZXJ2ZXIoIkNvbnMgSW5ldEFkZHJlc3MsSSIpOworICAgICAgICBzID0gbmV3IFNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgc3BvcnQpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gY3JlYXRlIHNvY2tldCIsIHMuZ2V0UG9ydCgpID09IHNwb3J0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbmV0X0luZXRBZGRyZXNzSUxqYXZhX25ldF9JbmV0QWRkcmVzc0koKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubmV0LlNvY2tldChqYXZhLm5ldC5JbmV0QWRkcmVzcywgaW50LAorICAgICAgICAvLyBqYXZhLm5ldC5JbmV0QWRkcmVzcywgaW50KQorICAgICAgICBpbnQgc3BvcnQgPSBzdGFydFNlcnZlcigiQ29ucyBJbmV0QWRkcmVzcyxJLEluZXRBZGRyZXNzLEkiKTsKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgIHMgPSBuZXcgU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLmdldEhvc3ROYW1lKCksIHNwb3J0LAorICAgICAgICAgICAgICAgIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBwb3J0TnVtYmVyKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGNyZWF0ZSBzb2NrZXQiLCBzLmdldExvY2FsUG9ydCgpID09IHBvcnROdW1iZXIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9uZXRfSW5ldEFkZHJlc3NJWigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLm5ldC5Tb2NrZXQoamF2YS5uZXQuSW5ldEFkZHJlc3MsIGludCwgYm9vbGVhbikKKyAgICAgICAgaW50IHNwb3J0ID0gc3RhcnRTZXJ2ZXIoIkNvbnMgSW5ldEFkZHJlc3MsSSxaIik7CisgICAgICAgIHMgPSBuZXcgU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBzcG9ydCwgdHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBjcmVhdGUgc29ja2V0Iiwgcy5nZXRQb3J0KCkgPT0gc3BvcnQpOworCisgICAgICAgIHMgPSBuZXcgU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBzcG9ydCwgZmFsc2UpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLm5ldC5Tb2NrZXQuY2xvc2UoKQorICAgICAgICBpbnQgc3BvcnQgPSBzdGFydFNlcnZlcigiU1NlcnZlciBjbG9zZSIpOworICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICAgICAgcyA9IG5ldyBTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHNwb3J0LCBudWxsLCBwb3J0TnVtYmVyKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMuc2V0U29MaW5nZXIoZmFsc2UsIDEwMCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGhhbmRsZUV4Y2VwdGlvbihlLCBTT19MSU5HRVIpOworICAgICAgICB9CisgICAgICAgIHMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluZXRBZGRyZXNzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubmV0LkluZXRBZGRyZXNzIGphdmEubmV0LlNvY2tldC5nZXRJbmV0QWRkcmVzcygpCisgICAgICAgIGludCBzcG9ydCA9IHN0YXJ0U2VydmVyKCJTU2VydmVyIGdldEluZXRBZGRyZXNzIik7CisgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICBzID0gbmV3IFNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgc3BvcnQsIG51bGwsIHBvcnROdW1iZXIpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgSW5ldEFkZHJlc3MiLCBzLmdldEluZXRBZGRyZXNzKCkuZXF1YWxzKAorICAgICAgICAgICAgICAgIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpKSk7CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldElucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gU2ltcGxlIGZldGNoIHRlc3QKKyAgICAgICAgU2VydmVyU29ja2V0IHNlcnZlciA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisgICAgICAgIFNvY2tldCBjbGllbnQgPSBuZXcgU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBzZXJ2ZXIuZ2V0TG9jYWxQb3J0KCkpOworICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IGNsaWVudC5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJGYWlsZWQgdG8gZ2V0IHN0cmVhbSIsIGlzKTsKKyAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgY2xpZW50LmNsb3NlKCk7CisgICAgICAgIHNlcnZlci5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0S2VlcEFsaXZlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IHNwb3J0ID0gc3RhcnRTZXJ2ZXIoIlNTZXJ2ZXIgZ2V0S2VlcEFsaXZlIik7CisgICAgICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICAgICAgICAgIFNvY2tldCB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBzcG9ydCwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCwgcG9ydE51bWJlcik7CisgICAgICAgICAgICB0aGVTb2NrZXQuc2V0S2VlcEFsaXZlKHRydWUpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0S2VlcEFsaXZlIGZhbHNlIHdoZW4gaXQgc2hvdWxkIGJlIHRydWUiLCB0aGVTb2NrZXQKKyAgICAgICAgICAgICAgICAgICAgLmdldEtlZXBBbGl2ZSgpKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5zZXRLZWVwQWxpdmUoZmFsc2UpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoImdldEtlZXBBbGl2ZSB0cnVlIHdoZW4gaXQgc2hvdWxkIGJlIEZhbHNlIiwgdGhlU29ja2V0CisgICAgICAgICAgICAgICAgICAgIC5nZXRLZWVwQWxpdmUoKSk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdGhlU29ja2V0LnNldEtlZXBBbGl2ZShmYWxzZSk7CisgICAgICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIG5vdCB0aHJvd24gYWZ0ZXIgY2FsbGluZyBzZXRLZWVwQWxpdmUgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAibWV0aG9kLiIpOworICAgICAgICAgICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRoZVNvY2tldC5nZXRLZWVwQWxpdmUoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgbm90IHRocm93biBhZnRlciBjYWxsaW5nIGdldEtlZXBBbGl2ZSArIiArCisgICAgICAgICAgICAgICAgICAgICAgICAibWV0aG9kLiIpOworICAgICAgICAgICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbnN1cmVFeGNlcHRpb25UaHJvd25JZk9wdGlvbklzVW5zdXBwb3J0ZWRPbk9TKFNPX0tFRVBBTElWRSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBoYW5kbGVFeGNlcHRpb24oZSwgU09fS0VFUEFMSVZFKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TG9jYWxBZGRyZXNzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubmV0LkluZXRBZGRyZXNzCisgICAgICAgIC8vIGphdmEubmV0LlNvY2tldC5nZXRMb2NhbEFkZHJlc3MoKQorICAgICAgICBpbnQgc3BvcnQgPSBzdGFydFNlcnZlcigiU1NlcnZlciBnZXRMb2NBZGRyZXNzIik7CisgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICBzID0gbmV3IFNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgc3BvcnQsIG51bGwsIHBvcnROdW1iZXIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBJbmV0QWRkcmVzcyIsCisgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHMuZ2V0TG9jYWxBZGRyZXNzKCkpOworCisgICAgICAgIC8vIG5vdyBjaGVjayBiZWhhdmlvciB3aGVuIHRoZSBBTlkgYWRkcmVzcyBpcyByZXR1cm5lZAorICAgICAgICBzID0gbmV3IFNvY2tldCgpOworICAgICAgICBzLmJpbmQobmV3IEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzLmdldEJ5TmFtZSgiMC4wLjAuMCIpLCAwKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQU5ZIGFkZHJlc3Mgbm90IElQdjY6ICIgKyBzLmdldExvY2FsU29ja2V0QWRkcmVzcygpLAorICAgICAgICAgICAgICAgICAgICBzLmdldExvY2FsQWRkcmVzcygpIGluc3RhbmNlb2YgSW5ldDZBZGRyZXNzKTsKKyAgICAgICAgcy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TG9jYWxQb3J0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLm5ldC5Tb2NrZXQuZ2V0TG9jYWxQb3J0KCkKKyAgICAgICAgaW50IHNwb3J0ID0gc3RhcnRTZXJ2ZXIoIlNTZXJ2ZXIgZ2V0TG9jYWxQb3J0Iik7CisgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICBzID0gbmV3IFNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKS5nZXRIb3N0TmFtZSgpLCBzcG9ydCwKKyAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgcG9ydE51bWJlcik7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBwb3J0Iiwgcy5nZXRMb2NhbFBvcnQoKSA9PSBwb3J0TnVtYmVyKTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0T3V0cHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEuaW8uT3V0cHV0U3RyZWFtCisgICAgICAgIC8vIGphdmEubmV0LlNvY2tldC5nZXRPdXRwdXRTdHJlYW0oKQorICAgICAgICBpbnQgc3BvcnQgPSBzdGFydFNlcnZlcigiU1NlcnZlciBnZXRPdXRwdXRTdHJlYW0iKTsKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgIHMgPSBuZXcgU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBzcG9ydCwgbnVsbCwgcG9ydE51bWJlcik7CisgICAgICAgIGphdmEuaW8uT3V0cHV0U3RyZWFtIG9zID0gcy5nZXRPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiRmFpbGVkIHRvIGdldCBzdHJlYW0iLCBvcyk7CisgICAgICAgIG9zLndyaXRlKDEpOworICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgaGFybW9ueS0yOTM0CisgICAgICAgIHMgPSBuZXcgU29ja2V0KCIxMjcuMC4wLjEiLCBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCksCisgICAgICAgICAgICAgICAgZmFsc2UpOworICAgICAgICBPdXRwdXRTdHJlYW0gbyA9IHMuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIG8ud3JpdGUoMSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBvLmNsb3NlKCk7CisgICAgICAgIHMuY2xvc2UoKTsKKworICAgICAgICAvLyBSZWdyZXNzaW9uIHRlc3QgZm9yIGhhcm1vbnktMjk0MgorICAgICAgICBzID0gbmV3IFNvY2tldCgiMC4wLjAuMCIsIFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKSwKKyAgICAgICAgICAgICAgICBmYWxzZSk7CisgICAgICAgIG8gPSBzLmdldE91dHB1dFN0cmVhbSgpOworICAgICAgICBvLndyaXRlKDEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgby5jbG9zZSgpOworICAgICAgICBzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQb3J0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLm5ldC5Tb2NrZXQuZ2V0UG9ydCgpCisgICAgICAgIGludCBzcG9ydCA9IHN0YXJ0U2VydmVyKCJTU2VydmVyIGdldFBvcnQiKTsKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgIHMgPSBuZXcgU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBzcG9ydCwgbnVsbCwgcG9ydE51bWJlcik7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBwb3J0IiArIHMuZ2V0UG9ydCgpLAorICAgICAgICAgICAgICAgIHMuZ2V0UG9ydCgpID09IHNwb3J0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFNvTGluZ2VyKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEubmV0LlNvY2tldC5nZXRTb0xpbmdlcigpCisgICAgICAgIGludCBzcG9ydCA9IHN0YXJ0U2VydmVyKCJTU2VydmVyIGdldFNvTGluZ2VyIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICAgICAgICAgIHMgPSBuZXcgU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBzcG9ydCwgbnVsbCwgcG9ydE51bWJlcik7CisgICAgICAgICAgICBzLnNldFNvTGluZ2VyKHRydWUsIDIwMCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBsaW5nZXIiLCAyMDAsIHMuZ2V0U29MaW5nZXIoKSk7CisgICAgICAgICAgICBlbnN1cmVFeGNlcHRpb25UaHJvd25JZk9wdGlvbklzVW5zdXBwb3J0ZWRPbk9TKFNPX0xJTkdFUik7CisgICAgICAgICAgICBzLnNldFNvTGluZ2VyKGZhbHNlLCAwKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGhhbmRsZUV4Y2VwdGlvbihlLCBTT19MSU5HRVIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICAgICAgcyA9IG5ldyBTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHNwb3J0LCBudWxsLCBwb3J0TnVtYmVyKTsKKyAgICAgICAgICAgIHMuY2xvc2UoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcy5nZXRTb0xpbmdlcigpOworICAgICAgICAgICAgICAgIGZhaWwoIlNvY2tldEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2goU29ja2V0RXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gd2FzIHRocm93bjogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFJlY2VpdmVCdWZmZXJTaXplKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IHNwb3J0ID0gc3RhcnRTZXJ2ZXIoIlNTZXJ2ZXIgZ2V0UmVjZWl2ZUJ1ZmZlclNpemUiKTsKKyAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICAgICAgcyA9IG5ldyBTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCkuZ2V0SG9zdE5hbWUoKSwgc3BvcnQsCisgICAgICAgICAgICAgICAgICAgIG51bGwsIHBvcnROdW1iZXIpOworICAgICAgICAgICAgcy5zZXRSZWNlaXZlQnVmZmVyU2l6ZSgxMzApOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGJ1ZmZlciBzaXplIiwgcy5nZXRSZWNlaXZlQnVmZmVyU2l6ZSgpID49IDEzMCk7CisgICAgICAgICAgICBlbnN1cmVFeGNlcHRpb25UaHJvd25JZk9wdGlvbklzVW5zdXBwb3J0ZWRPbk9TKFNPX1JDVkJVRik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBoYW5kbGVFeGNlcHRpb24oZSwgU09fUkNWQlVGKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTb2NrZXQgbmV3U29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICAgICAgbmV3U29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG5ld1NvY2tldC5nZXRSZWNlaXZlQnVmZmVyU2l6ZSgpOworICAgICAgICAgICAgICAgIGZhaWwoIlNvY2tldEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2goU29ja2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTZW5kQnVmZmVyU2l6ZSgpIHsKKyAgICAgICAgaW50IHNwb3J0ID0gc3RhcnRTZXJ2ZXIoIlNTZXJ2ZXIgc2V0U2VuZEJ1ZmZlclNpemUiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICAgICAgcyA9IG5ldyBTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCkuZ2V0SG9zdE5hbWUoKSwgc3BvcnQsCisgICAgICAgICAgICAgICAgICAgIG51bGwsIHBvcnROdW1iZXIpOworICAgICAgICAgICAgcy5zZXRTZW5kQnVmZmVyU2l6ZSgxMzQpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGJ1ZmZlciBzaXplIiwgcy5nZXRTZW5kQnVmZmVyU2l6ZSgpID49IDEzNCk7CisgICAgICAgICAgICBlbnN1cmVFeGNlcHRpb25UaHJvd25JZk9wdGlvbklzVW5zdXBwb3J0ZWRPbk9TKFNPX1NOREJVRik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBoYW5kbGVFeGNlcHRpb24oZSwgU09fU05EQlVGKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgICAgICBzID0gbmV3IFNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgc3BvcnQsIG51bGwsIHBvcnROdW1iZXIpOworICAgICAgICAgICAgcy5jbG9zZSgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzLmdldFNlbmRCdWZmZXJTaXplKCk7CisgICAgICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gd2FzIHRocm93bjogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFNvVGltZW91dF9zZXRTb1RpbWVvdXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVE9ETzogYSB1c2VmdWwgdGVzdCB3b3VsZCBjaGVjayB0aGF0IHNldFNvVGltZW91dCBhY3R1YWxseSBjYXVzZXMgdGltZW91dHMhCisgICAgICAgIFNvY2tldCBzID0gbmV3IFNvY2tldCgpOworICAgICAgICBzLnNldFNvVGltZW91dCgxNTAwKTsKKyAgICAgICAgaW50IG1zID0gcy5nZXRTb1RpbWVvdXQoKTsKKyAgICAgICAgaWYgKG1zIDwgMTUwMC0xMCB8fCBtcyA+IDE1MDArMTApIHsKKyAgICAgICAgICAgIGZhaWwoInN1c3BpY2lvdXMgdGltZW91dDogIiArIG1zKTsKKyAgICAgICAgfQorICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmdldFNvVGltZW91dCgpOworICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5zZXRTb1RpbWVvdXQoMTAwMCk7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRUY3BOb0RlbGF5KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLm5ldC5Tb2NrZXQuZ2V0VGNwTm9EZWxheSgpCisgICAgICAgIGludCBzcG9ydCA9IHN0YXJ0U2VydmVyKCJTU2VydmVyIGdldFRjcE5vRGVsYXkiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICAgICAgcyA9IG5ldyBTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHNwb3J0LCBudWxsLCBwb3J0TnVtYmVyKTsKKyAgICAgICAgICAgIGJvb2xlYW4gYm9vbCA9ICFzLmdldFRjcE5vRGVsYXkoKTsKKyAgICAgICAgICAgIHMuc2V0VGNwTm9EZWxheShib29sKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBnZXQgbm8gZGVsYXkgc2V0dGluZzogIiArIHMuZ2V0VGNwTm9EZWxheSgpLAorICAgICAgICAgICAgICAgICAgICBzLmdldFRjcE5vRGVsYXkoKSA9PSBib29sKTsKKyAgICAgICAgICAgIGVuc3VyZUV4Y2VwdGlvblRocm93bklmT3B0aW9uSXNVbnN1cHBvcnRlZE9uT1MoVENQX05PREVMQVkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaGFuZGxlRXhjZXB0aW9uKGUsIFRDUF9OT0RFTEFZKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICAgICAgICAgIHMgPSBuZXcgU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBzcG9ydCwgbnVsbCwgcG9ydE51bWJlcik7CisgICAgICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHMuZ2V0VGNwTm9EZWxheSgpOworICAgICAgICAgICAgICAgIGZhaWwoIlNvY2tldEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2goU29ja2V0RXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gd2FzIHRocm93bjogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEtlZXBBbGl2ZVooKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGhlcmUgaXMgbm90IHJlYWxseSBhIGdvb2QgdGVzdCBmb3IgdGhpcyBhcyBpdCBpcyB0aGVyZSB0byBkZXRlY3QKKyAgICAgICAgLy8gY3Jhc2hlZCBtYWNoaW5lcy4gSnVzdCBtYWtlIHN1cmUgd2UgY2FuIHNldCBpdAorICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IHNwb3J0ID0gc3RhcnRTZXJ2ZXIoIlNTZXJ2ZXIgc2V0S2VlcEFsaXZlIik7CisgICAgICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICAgICAgICAgIFNvY2tldCB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBzcG9ydCwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCwgcG9ydE51bWJlcik7CisgICAgICAgICAgICB0aGVTb2NrZXQuc2V0S2VlcEFsaXZlKHRydWUpOworICAgICAgICAgICAgdGhlU29ja2V0LnNldEtlZXBBbGl2ZShmYWxzZSk7CisgICAgICAgICAgICBlbnN1cmVFeGNlcHRpb25UaHJvd25JZk9wdGlvbklzVW5zdXBwb3J0ZWRPbk9TKFNPX0tFRVBBTElWRSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBoYW5kbGVFeGNlcHRpb24oZSwgU09fS0VFUEFMSVZFKTsKKyAgICAgICAgfQorICAgICAgICAvLyByZWdyZXNzaW9uIHRlc3QgZm9yIEhBUk1PTlktMTEzNgorICAgICAgICBuZXcgVGVzdFNvY2tldCgoU29ja2V0SW1wbCkgbnVsbCkuc2V0S2VlcEFsaXZlKHRydWUpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTb2NrZXQgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuc2V0S2VlcEFsaXZlKHRydWUpOworICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFNvY2tldEV4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKyAgICBjbGFzcyBUZXN0U29ja2V0IGV4dGVuZHMgU29ja2V0IHsKKyAgICAgICAgcHVibGljIFRlc3RTb2NrZXQoU29ja2V0SW1wbCBpbXBsKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyKGltcGwpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRTb2NrZXRJbXBsRmFjdG9yeUxqYXZhX25ldF9Tb2NrZXRJbXBsRmFjdG9yeSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQKKyAgICAgICAgLy8gamF2YS5uZXQuU29ja2V0LnNldFNvY2tldEltcGxGYWN0b3J5KGphdmEubmV0LlNvY2tldEltcGxGYWN0b3J5KQorCisgICAgICAgIC8vIENhbm5vdCB0ZXN0IGFzIHNldHRpbmcgd2lsbCBjYXVzZSB0aGUgZmFjdG9yeSB0byBiZSBjaGFuZ2VkIGZvcgorICAgICAgICAvLyBhbGwgc3Vic2VxdWVudCBzb2NrZXRzCisKKyAgICAgICAgU2VjdXJpdHlNYW5hZ2VyIHNtID0gbmV3IFNlY3VyaXR5TWFuYWdlcigpIHsKKworICAgICAgICAgICAgcHVibGljIHZvaWQgY2hlY2tQZXJtaXNzaW9uKFBlcm1pc3Npb24gcGVybSkgeworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBjaGVja1NldEZhY3RvcnkoKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRTZW5kQnVmZmVyU2l6ZUkoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgc3BvcnQgPSBzdGFydFNlcnZlcigiU1NlcnZlciBzZXRTZW5kQnVmZmVyU2l6ZUkiKTsKKyAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICAgICAgcyA9IG5ldyBTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHNwb3J0LCBudWxsLCBwb3J0TnVtYmVyKTsKKyAgICAgICAgICAgIHMuc2V0U2VuZEJ1ZmZlclNpemUoMTM0KTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBidWZmZXIgc2l6ZSIsIHMuZ2V0U2VuZEJ1ZmZlclNpemUoKSA+PSAxMzQpOworICAgICAgICAgICAgZW5zdXJlRXhjZXB0aW9uVGhyb3duSWZPcHRpb25Jc1Vuc3VwcG9ydGVkT25PUyhTT19TTkRCVUYpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaGFuZGxlRXhjZXB0aW9uKGUsIFNPX1NOREJVRik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU29ja2V0IHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgdGhlU29ja2V0LnNldFNlbmRCdWZmZXJTaXplKDEpOworICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFNvY2tldEV4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFJlY2VpdmVCdWZmZXJTaXplSSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBzcG9ydCA9IHN0YXJ0U2VydmVyKCJTU2VydmVyIHNldFJlY2VpdmVCdWZmZXJTaXplSSIpOworICAgICAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgICAgICBzID0gbmV3IFNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgc3BvcnQsIG51bGwsIHBvcnROdW1iZXIpOworICAgICAgICAgICAgcy5zZXRSZWNlaXZlQnVmZmVyU2l6ZSgxMzApOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGJ1ZmZlciBzaXplIiwgcy5nZXRSZWNlaXZlQnVmZmVyU2l6ZSgpID49IDEzMCk7CisgICAgICAgICAgICBlbnN1cmVFeGNlcHRpb25UaHJvd25JZk9wdGlvbklzVW5zdXBwb3J0ZWRPbk9TKFNPX1JDVkJVRik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBoYW5kbGVFeGNlcHRpb24oZSwgU09fUkNWQlVGKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTb2NrZXQgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuc2V0UmVjZWl2ZUJ1ZmZlclNpemUoMSk7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU29ja2V0RXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0U29MaW5nZXJaSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS5uZXQuU29ja2V0LnNldFNvTGluZ2VyKGJvb2xlYW4sIGludCkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBzcG9ydCA9IHN0YXJ0U2VydmVyKCJTU2VydmVyIHNldFNvTGluZ2VyWkkiKTsKKyAgICAgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICAgICAgcyA9IG5ldyBTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHNwb3J0LCBudWxsLCBwb3J0TnVtYmVyKTsKKyAgICAgICAgICAgIHMuc2V0U29MaW5nZXIodHJ1ZSwgNTAwKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiU2V0IGluY29ycmVjdCBsaW5nZXIiLCA1MDAsIHMuZ2V0U29MaW5nZXIoKSk7CisgICAgICAgICAgICBlbnN1cmVFeGNlcHRpb25UaHJvd25JZk9wdGlvbklzVW5zdXBwb3J0ZWRPbk9TKFNPX0xJTkdFUik7CisgICAgICAgICAgICBzLnNldFNvTGluZ2VyKGZhbHNlLCAwKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGhhbmRsZUV4Y2VwdGlvbihlLCBTT19MSU5HRVIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldCB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5zZXRTb0xpbmdlcih0cnVlLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIlNvY2tldEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChTb2NrZXRFeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRUY3BOb0RlbGF5WigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS5uZXQuU29ja2V0LnNldFRjcE5vRGVsYXkoYm9vbGVhbikKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBzcG9ydCA9IHN0YXJ0U2VydmVyKCJTU2VydmVyIHNldFRjcE5vRGVsYXlaIik7CisgICAgICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICAgICAgICAgIHMgPSBuZXcgU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBzcG9ydCwgbnVsbCwgcG9ydE51bWJlcik7CisgICAgICAgICAgICBib29sZWFuIGJvb2w7CisgICAgICAgICAgICBzLnNldFRjcE5vRGVsYXkoYm9vbCA9ICFzLmdldFRjcE5vRGVsYXkoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gc2V0IG5vIGRlbGF5IHNldHRpbmc6ICIgKyBzLmdldFRjcE5vRGVsYXkoKSwKKyAgICAgICAgICAgICAgICAgICAgcy5nZXRUY3BOb0RlbGF5KCkgPT0gYm9vbCk7CisgICAgICAgICAgICBlbnN1cmVFeGNlcHRpb25UaHJvd25JZk9wdGlvbklzVW5zdXBwb3J0ZWRPbk9TKFRDUF9OT0RFTEFZKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGhhbmRsZUV4Y2VwdGlvbihlLCBUQ1BfTk9ERUxBWSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU29ja2V0IHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgdGhlU29ja2V0LnNldFRjcE5vRGVsYXkodHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU29ja2V0RXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9TdHJpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLlN0cmluZyBqYXZhLm5ldC5Tb2NrZXQudG9TdHJpbmcoKQorICAgICAgICBpbnQgc3BvcnQgPSBzdGFydFNlcnZlcigiU1NlcnZlciB0b1N0cmluZyIpOworICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICAgICAgcyA9IG5ldyBTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCkuZ2V0SG9zdE5hbWUoKSwgc3BvcnQsCisgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHBvcnROdW1iZXIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNvY2tldFthZGRyZXNzPSIgKyBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSArICIscG9ydD0iICsgcy5nZXRQb3J0KCkKKyAgICAgICAgICAgICAgICArICIsbG9jYWxQb3J0PSIgKyBzLmdldExvY2FsUG9ydCgpICsgIl0iLCBzLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8vIEFuZHJvaWRPbmx5OiBSSSByZXR1cm5zIHdyb25nIHZhbHVlIGZvciBFT0YKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NodXRkb3duSW5wdXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSW5ldEFkZHJlc3MgYWRkciA9IEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpOworICAgICAgICBpbnQgcG9ydCA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICAgICAgU2VydmVyU29ja2V0IHNlcnZlclNvY2tldCA9IG5ldyBTZXJ2ZXJTb2NrZXQocG9ydCwgNSwgYWRkcik7CisgICAgICAgIFNvY2tldCB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KGFkZHIsIHBvcnQpOworICAgICAgICBTb2NrZXQgc2VydlNvY2sgPSBzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisKKyAgICAgICAgSW5wdXRTdHJlYW0gdGhlSW5wdXQgPSB0aGVTb2NrZXQuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgT3V0cHV0U3RyZWFtIHRoZU91dHB1dCA9IHNlcnZTb2NrLmdldE91dHB1dFN0cmVhbSgpOworCisgICAgICAgIC8vIHNodXRkb3duIHRoZSBpbnB1dAorICAgICAgICB0aGVTb2NrZXQuc2h1dGRvd25JbnB1dCgpOworCisgICAgICAgIC8vIHNlbmQgdGhlIHJlZ3VsYXIgZGF0YQorICAgICAgICBTdHJpbmcgc2VuZFN0cmluZyA9IG5ldyBTdHJpbmcoIlRlc3QiKTsKKyAgICAgICAgdGhlT3V0cHV0LndyaXRlKHNlbmRTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIHRoZU91dHB1dC5mbHVzaCgpOworCisgICAgICAgIC8vIGdpdmUgdGhpbmdzIHNvbWUgdGltZSB0byBzZXR0bGUKKyAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworCisgICAgICAgIC8vIFJJIGZhaWxzIGhlcmUuIEl0IGlzIGEgUkkgYnVnIG5vdCB0byByZXR1cm4gMCB0byBpbmRpY2F0ZSBFT0YKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHRoZUlucHV0LmF2YWlsYWJsZSgpKTsKKworICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgc2VydmVyU29ja2V0LmNsb3NlKCk7CisKKyAgICAgICAgU29ja2V0IHNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgc29ja2V0LmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzb2NrZXQuc2h1dGRvd25JbnB1dCgpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NodXRkb3duT3V0cHV0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSW5ldEFkZHJlc3MgYWRkciA9IEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpOworICAgICAgICBpbnQgcG9ydCA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICAgICAgU2VydmVyU29ja2V0IHNlcnZlclNvY2tldCA9IG5ldyBTZXJ2ZXJTb2NrZXQocG9ydCwgNSwgYWRkcik7CisgICAgICAgIFNvY2tldCB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KGFkZHIsIHBvcnQpOworICAgICAgICBTb2NrZXQgc2VydlNvY2sgPSBzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisKKyAgICAgICAgSW5wdXRTdHJlYW0gdGhlSW5wdXQgPSB0aGVTb2NrZXQuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgT3V0cHV0U3RyZWFtIHRoZU91dHB1dCA9IHNlcnZTb2NrLmdldE91dHB1dFN0cmVhbSgpOworCisgICAgICAgIC8vIHNodXRkb3duIHRoZSBvdXRwdXQKKyAgICAgICAgc2VydlNvY2suc2h1dGRvd25PdXRwdXQoKTsKKworICAgICAgICAvLyBzZW5kIHRoZSByZWd1bGFyIGRhdGEKKyAgICAgICAgU3RyaW5nIHNlbmRTdHJpbmcgPSBuZXcgU3RyaW5nKCJUZXN0Iik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGVPdXRwdXQud3JpdGUoc2VuZFN0cmluZy5nZXRCeXRlcygpKTsKKyAgICAgICAgICAgIHRoZU91dHB1dC5mbHVzaCgpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhjZXB0aW9uIHdoZW4gd3JpdGluZyBvbiBzb2NrZXQgd2l0aCBvdXRwdXQgc2h1dGRvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICBzZXJ2ZXJTb2NrZXQuY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhlU29ja2V0LnNodXRkb3duSW5wdXQoKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRMb2NhbFNvY2tldEFkZHJlc3MoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBzZXQgdXAgc2VydmVyIGNvbm5lY3QgYW5kIHRoZW4gdmFsaWRhdGUgdGhhdCB3ZSBnZXQgdGhlIHJpZ2h0CisgICAgICAgIC8vIHJlc3BvbnNlIGZvciB0aGUgbG9jYWwgYWRkcmVzcworICAgICAgICBpbnQgc3BvcnQgPSBzdGFydFNlcnZlcigiU1NlcnZlciBnZXRMb2NTb2NrZXRBZGRyZXNzIik7CisgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICBzID0gbmV3IFNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgc3BvcnQsIG51bGwsIHBvcnROdW1iZXIpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJSZXR1cm5lZCBpbmNvcnJlY3QgSW5ldFNvY2tldEFkZHJlc3MoMSk6IgorICAgICAgICAgICAgICAgICAgICAgICAgKyBzLmdldExvY2FsU29ja2V0QWRkcmVzcygpLnRvU3RyaW5nKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIkV4cGVjdGVkOiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIChuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcnROdW1iZXIpKS50b1N0cmluZygpLCBzCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TG9jYWxTb2NrZXRBZGRyZXNzKCkuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TG9jYWxIb3N0KCksIHBvcnROdW1iZXIpKSk7CisgICAgICAgIHMuY2xvc2UoKTsKKworICAgICAgICAvLyBub3cgY3JlYXRlIGEgc29ja2V0IHRoYXQgaXMgbm90IGJvdW5kIGFuZCB2YWxpZGF0ZSB3ZSBnZXQgdGhlCisgICAgICAgIC8vIHJpZ2h0IGFuc3dlcgorICAgICAgICBTb2NrZXQgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICBhc3NlcnROdWxsKAorICAgICAgICAgICAgICAgICJSZXR1cm5lZCBpbmNvcnJlY3QgSW5ldFNvY2tldEFkZHJlc3MgLXVuYm91bmQgc29ja2V0LSBFeHBlY3RlZCBudWxsIiwKKyAgICAgICAgICAgICAgICB0aGVTb2NrZXQuZ2V0TG9jYWxTb2NrZXRBZGRyZXNzKCkpOworCisgICAgICAgIC8vIG5vdyBiaW5kIHRoZSBzb2NrZXQgYW5kIG1ha2Ugc3VyZSB3ZSBnZXQgdGhlIHJpZ2h0IGFuc3dlcgorICAgICAgICBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICB0aGVTb2NrZXQuYmluZChuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgcG9ydE51bWJlcikpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJSZXR1cm5lZCBpbmNvcnJlY3QgSW5ldFNvY2tldEFkZHJlc3MoMik6IgorICAgICAgICAgICAgICAgICAgICAgICAgKyB0aGVTb2NrZXQuZ2V0TG9jYWxTb2NrZXRBZGRyZXNzKCkudG9TdHJpbmcoKQorICAgICAgICAgICAgICAgICAgICAgICAgKyAiRXhwZWN0ZWQ6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgKG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9ydE51bWJlcikpLnRvU3RyaW5nKCksIHRoZVNvY2tldAorICAgICAgICAgICAgICAgICAgICAgICAgLmdldExvY2FsU29ja2V0QWRkcmVzcygpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldExvY2FsSG9zdCgpLCBwb3J0TnVtYmVyKSkpOworICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKworICAgICAgICAvLyBub3cgdmFsaWRhdGUgdGhhdCBiZWhhdmlvdXIgd2hlbiB0aGUgYW55IGFkZHJlc3MgaXMgcmV0dXJuZWQKKyAgICAgICAgcyA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgcy5iaW5kKG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcy5nZXRCeU5hbWUoIjAuMC4wLjAiKSwgMCkpOworCisgICAgICAgIGFzc2VydFRydWUoIkFOWSBhZGRyZXNzIG5vdCBJUHY2OiAiICsgcy5nZXRMb2NhbFNvY2tldEFkZHJlc3MoKSwKKyAgICAgICAgICAgICAgICAoKEluZXRTb2NrZXRBZGRyZXNzKSBzLmdldExvY2FsU29ja2V0QWRkcmVzcygpKS5nZXRBZGRyZXNzKCkgaW5zdGFuY2VvZiBJbmV0NkFkZHJlc3MpOworICAgICAgICBzLmNsb3NlKCk7CisKKyAgICAgICAgLy8gbm93IHZhbGlkYXRlIHRoZSBzYW1lIGZvciBnZXRMb2NhbEFkZHJlc3MKKyAgICAgICAgcyA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgcy5iaW5kKG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcy5nZXRCeU5hbWUoIjAuMC4wLjAiKSwgMCkpOworICAgICAgICBhc3NlcnRUcnVlKCJBTlkgYWRkcmVzcyBub3QgSVB2NjogIiArIHMuZ2V0TG9jYWxTb2NrZXRBZGRyZXNzKCksCisgICAgICAgICAgICAgICAgKChJbmV0U29ja2V0QWRkcmVzcykgcy5nZXRMb2NhbFNvY2tldEFkZHJlc3MoKSkuZ2V0QWRkcmVzcygpIGluc3RhbmNlb2YgSW5ldDZBZGRyZXNzKTsKKyAgICAgICAgcy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UmVtb3RlU29ja2V0QWRkcmVzcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIHNldCB1cCBzZXJ2ZXIgY29ubmVjdCBhbmQgdGhlbiB2YWxpZGF0ZSB0aGF0IHdlIGdldCB0aGUgcmlnaHQKKyAgICAgICAgLy8gcmVzcG9uc2UgZm9yIHRoZSByZW1vdGUgYWRkcmVzcworICAgICAgICBpbnQgc3BvcnQgPSBzdGFydFNlcnZlcigiU1NlcnZlciBnZXRMb2NSZW1vdGVBZGRyZXNzIik7CisgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICBzID0gbmV3IFNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgc3BvcnQsIG51bGwsIHBvcnROdW1iZXIpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgSW5ldFNvY2tldEFkZHJlc3MoMSk6IgorICAgICAgICAgICAgICAgICsgcy5nZXRMb2NhbFNvY2tldEFkZHJlc3MoKS50b1N0cmluZygpLAorICAgICAgICAgICAgICAgIHMuZ2V0UmVtb3RlU29ja2V0QWRkcmVzcygpCisgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TG9jYWxIb3N0KCksIHNwb3J0KSkpOworICAgICAgICBzLmNsb3NlKCk7CisKKyAgICAgICAgLy8gbm93IGNyZWF0ZSBvbmUgdGhhdCBpcyBub3QgY29ubmVjdCBhbmQgdmFsaWRhdGUgdGhhdCB3ZSBnZXQgdGhlCisgICAgICAgIC8vIHJpZ2h0IGFuc3dlcgorICAgICAgICBTb2NrZXQgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICB0aGVTb2NrZXQuYmluZChuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgcG9ydE51bWJlcikpOworCisgICAgICAgIGFzc2VydE51bGwoIlJldHVybmVkIGluY29ycmVjdCBJbmV0U29ja2V0QWRkcmVzcyAtdW5jb25uZWN0ZWQgc29ja2V0OiIKKyAgICAgICAgICAgICAgICArICJFeHBlY3RlZDogTlVMTCIsIHRoZVNvY2tldC5nZXRSZW1vdGVTb2NrZXRBZGRyZXNzKCkpOworCisgICAgICAgIC8vIG5vdyBjb25uZWN0IGFuZCB2YWxpZGF0ZSB3ZSBnZXQgdGhlIHJpZ2h0IGFuc3dlcgorICAgICAgICB0aGVTb2NrZXQuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgc3BvcnQpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IEluZXRTb2NrZXRBZGRyZXNzKDIpOiIKKyAgICAgICAgICAgICAgICArIHRoZVNvY2tldC5nZXRSZW1vdGVTb2NrZXRBZGRyZXNzKCkudG9TdHJpbmcoKSwKKyAgICAgICAgICAgICAgICB0aGVTb2NrZXQuZ2V0UmVtb3RlU29ja2V0QWRkcmVzcygpCisgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TG9jYWxIb3N0KCksIHNwb3J0KSkpOworICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNCb3VuZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEluZXRBZGRyZXNzIGFkZHIgPSBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKTsKKyAgICAgICAgaW50IHBvcnQgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgIFNlcnZlclNvY2tldCBzZXJ2ZXJTb2NrZXQgPSBuZXcgU2VydmVyU29ja2V0KHBvcnQsIDUsIGFkZHIpOworICAgICAgICBTb2NrZXQgdGhlU29ja2V0ID0gbmV3IFNvY2tldChhZGRyLCBwb3J0KTsKKyAgICAgICAgU29ja2V0IHNlcnZTb2NrID0gc2VydmVyU29ja2V0LmFjY2VwdCgpOworICAgICAgICBhc3NlcnRUcnVlKCJTb2NrZXQgaW5kaWNhdGVkICBub3QgYm91bmQgd2hlbiBpdCBzaG91bGQgYmUgKDEpIiwKKyAgICAgICAgICAgICAgICB0aGVTb2NrZXQuaXNCb3VuZCgpKTsKKyAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgIHNlcnZlclNvY2tldC5jbG9zZSgpOworCisgICAgICAgIC8vIG5vdyBkbyBpdCB3aXRoIHRoZSBuZXcgY29uc3RydWN0b3JzIGFuZCByZXZhbGlkYXRlLiBDb25uZWN0IGNhdXNlcworICAgICAgICAvLyB0aGUgc29ja2V0IHRvIGJlIGJvdW5kCisgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIHRoZUFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAuZ2V0TG9jYWxIb3N0KCksIFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKSk7CisgICAgICAgIHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNvY2tldCBpbmRpY2F0ZWQgYm91bmQgd2hlbiBpdCB3YXMgbm90ICgyKSIsIHRoZVNvY2tldAorICAgICAgICAgICAgICAgIC5pc0JvdW5kKCkpOworICAgICAgICBzZXJ2ZXJTb2NrZXQgPSBuZXcgU2VydmVyU29ja2V0KCk7CisgICAgICAgIHNlcnZlclNvY2tldC5iaW5kKHRoZUFkZHJlc3MpOworICAgICAgICB0aGVTb2NrZXQuY29ubmVjdCh0aGVBZGRyZXNzKTsKKyAgICAgICAgc2VydlNvY2sgPSBzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgIGFzc2VydFRydWUoIlNvY2tldCBpbmRpY2F0ZWQgbm90IGJvdW5kIHdoZW4gaXQgc2hvdWxkIGJlICgyKSIsCisgICAgICAgICAgICAgICAgdGhlU29ja2V0LmlzQm91bmQoKSk7CisgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICBzZXJ2ZXJTb2NrZXQuY2xvc2UoKTsKKworICAgICAgICAvLyBub3cgdGVzdCB3aGVuIHdlIGJpbmQgZXhwbGljaXRseQorICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyB0aGVMb2NhbEFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAuZ2V0TG9jYWxIb3N0KCksIFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKSk7CisgICAgICAgIHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNvY2tldCBpbmRpY2F0ZWQgYm91bmQgd2hlbiBpdCB3YXMgbm90ICgzKSIsIHRoZVNvY2tldAorICAgICAgICAgICAgICAgIC5pc0JvdW5kKCkpOworICAgICAgICB0aGVTb2NrZXQuYmluZCh0aGVMb2NhbEFkZHJlc3MpOworICAgICAgICBhc3NlcnRUcnVlKCJTb2NrZXQgaW5kaWNhdGVkIG5vdCBib3VuZCB3aGVuIGl0IHNob3VsZCBiZSAoM2EpIiwKKyAgICAgICAgICAgICAgICB0aGVTb2NrZXQuaXNCb3VuZCgpKTsKKyAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgIGFzc2VydFRydWUoIlNvY2tldCBpbmRpY2F0ZWQgbm90IGJvdW5kIHdoZW4gaXQgc2hvdWxkIGJlICgzYikiLAorICAgICAgICAgICAgICAgIHRoZVNvY2tldC5pc0JvdW5kKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNDb25uZWN0ZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBJbmV0QWRkcmVzcyBhZGRyID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCk7CisgICAgICAgIGludCBwb3J0ID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICBTZXJ2ZXJTb2NrZXQgc2VydmVyU29ja2V0ID0gbmV3IFNlcnZlclNvY2tldChwb3J0LCA1LCBhZGRyKTsKKyAgICAgICAgU29ja2V0IHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoYWRkciwgcG9ydCk7CisgICAgICAgIFNvY2tldCBzZXJ2U29jayA9IHNlcnZlclNvY2tldC5hY2NlcHQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU29ja2V0IGluZGljYXRlZCAgbm90IGNvbm5lY3RlZCB3aGVuIGl0IHNob3VsZCBiZSIsCisgICAgICAgICAgICAgICAgdGhlU29ja2V0LmlzQ29ubmVjdGVkKCkpOworICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgc2VydmVyU29ja2V0LmNsb3NlKCk7CisKKyAgICAgICAgLy8gbm93IGRvIGl0IHdpdGggdGhlIG5ldyBjb25zdHJ1Y3RvcnMgYW5kIHJldmFsaWRhdGUKKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgdGhlQWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcworICAgICAgICAgICAgICAgIC5nZXRMb2NhbEhvc3QoKSwgU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpKTsKKyAgICAgICAgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICBhc3NlcnRGYWxzZSgiU29ja2V0IGluZGljYXRlZCBjb25uZWN0ZWQgd2hlbiBpdCB3YXMgbm90IiwgdGhlU29ja2V0CisgICAgICAgICAgICAgICAgLmlzQ29ubmVjdGVkKCkpOworICAgICAgICBzZXJ2ZXJTb2NrZXQgPSBuZXcgU2VydmVyU29ja2V0KCk7CisgICAgICAgIHNlcnZlclNvY2tldC5iaW5kKHRoZUFkZHJlc3MpOworICAgICAgICB0aGVTb2NrZXQuY29ubmVjdCh0aGVBZGRyZXNzKTsKKyAgICAgICAgc2VydlNvY2sgPSBzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgIGFzc2VydFRydWUoIlNvY2tldCBpbmRpY2F0ZWQgIG5vdCBjb25uZWN0ZWQgd2hlbiBpdCBzaG91bGQgYmUiLAorICAgICAgICAgICAgICAgIHRoZVNvY2tldC5pc0Nvbm5lY3RlZCgpKTsKKyAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgIHNlcnZlclNvY2tldC5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNDbG9zZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBJbmV0QWRkcmVzcyBhZGRyID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCk7CisgICAgICAgIGludCBwb3J0ID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICBTZXJ2ZXJTb2NrZXQgc2VydmVyU29ja2V0ID0gbmV3IFNlcnZlclNvY2tldChwb3J0LCA1LCBhZGRyKTsKKyAgICAgICAgU29ja2V0IHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoYWRkciwgcG9ydCk7CisgICAgICAgIFNvY2tldCBzZXJ2U29jayA9IHNlcnZlclNvY2tldC5hY2NlcHQoKTsKKworICAgICAgICAvLyB2YWxpZGF0ZSBpc0Nsb3NlZCByZXR1cm5zIGV4cGVjdGVkIHZhbHVlcworICAgICAgICBhc3NlcnRGYWxzZSgiU29ja2V0IHNob3VsZCBpbmRpY2F0ZSBpdCBpcyBub3QgY2xvc2VkKDEpOiIsIHRoZVNvY2tldAorICAgICAgICAgICAgICAgIC5pc0Nsb3NlZCgpKTsKKyAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgIGFzc2VydFRydWUoIlNvY2tldCBzaG91bGQgaW5kaWNhdGUgaXQgaXMgY2xvc2VkKDEpOiIsIHRoZVNvY2tldAorICAgICAgICAgICAgICAgIC5pc0Nsb3NlZCgpKTsKKworICAgICAgICB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KGFkZHIsIHBvcnQpOworICAgICAgICBhc3NlcnRGYWxzZSgiU29ja2V0IHNob3VsZCBpbmRpY2F0ZSBpdCBpcyBub3QgY2xvc2VkKDIpOiIsIHRoZVNvY2tldAorICAgICAgICAgICAgICAgIC5pc0Nsb3NlZCgpKTsKKyAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgIGFzc2VydFRydWUoIlNvY2tldCBzaG91bGQgaW5kaWNhdGUgaXQgaXMgY2xvc2VkKDIpOiIsIHRoZVNvY2tldAorICAgICAgICAgICAgICAgIC5pc0Nsb3NlZCgpKTsKKworICAgICAgICAvLyB2YWxpZGF0ZSB0aGF0IGlzQ2xvc2VkIHdvcmtzIG9rIGZvciBzb2NrZXRzIHJldHVybmVkIGZyb20KKyAgICAgICAgLy8gU2VydmVyU29ja2V0LmFjY2VwdCgpCisgICAgICAgIGFzc2VydEZhbHNlKCJTZXJ2ZXIgU29ja2V0IHNob3VsZCBpbmRpY2F0ZSBpdCBpcyBub3QgY2xvc2VkOiIsIHNlcnZTb2NrCisgICAgICAgICAgICAgICAgLmlzQ2xvc2VkKCkpOworICAgICAgICBzZXJ2U29jay5jbG9zZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJTZXJ2ZXIgU29ja2V0IHNob3VsZCBpbmRpY2F0ZSBpdCBpcyBjbG9zZWQ6Iiwgc2VydlNvY2sKKyAgICAgICAgICAgICAgICAuaXNDbG9zZWQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9iaW5kTGphdmFfbmV0X1NvY2tldEFkZHJlc3MoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIGNsYXNzIG15U29ja2V0QWRkcmVzcyBleHRlbmRzIFNvY2tldEFkZHJlc3MgeworCisgICAgICAgICAgICBwdWJsaWMgbXlTb2NrZXRBZGRyZXNzKCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gQWRkcmVzcyB3ZSBjYW5ub3QgYmluZCB0bworICAgICAgICBTb2NrZXQgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhlU29ja2V0LmJpbmQobmV3IEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzCisgICAgICAgICAgICAgICAgICAgIC5nZXRCeUFkZHJlc3MoU3VwcG9ydF9Db25maWd1cmF0aW9uLm5vbkxvY2FsQWRkcmVzc0J5dGVzKSwKKyAgICAgICAgICAgICAgICAgICAgU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpKSk7CisgICAgICAgICAgICBmYWlsKCJObyBleGNlcHRpb24gd2hlbiBiaW5kaW5nIHRvIGJhZCBhZGRyZXNzOiIKKyAgICAgICAgICAgICAgICAgICArIHRoZVNvY2tldC5nZXRMb2NhbFNvY2tldEFkZHJlc3MoKS50b1N0cmluZygpKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgfQorICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKworICAgICAgICAvLyBub3cgY3JlYXRlIGEgc29ja2V0IHRoYXQgaXMgbm90IGJvdW5kIGFuZCB0aGVuIGJpbmQgaXQKKyAgICAgICAgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICAgICAgdGhlU29ja2V0LmJpbmQobmV3IEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLAorICAgICAgICAgICAgICAgIHBvcnROdW1iZXIpKTsKKworICAgICAgICAvLyB2YWxpZGF0ZSB0aGF0IHRoZSBsb2NhbFNvY2tldEFkZHJlc3MgcmVmbGVjdHMgdGhlIGFkZHJlc3Mgd2UKKyAgICAgICAgLy8gYm91bmQgdG8KKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiTG9jYWwgYWRkcmVzcyBub3QgY29ycmVjdCBhZnRlciBiaW5kOiIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgdGhlU29ja2V0LmdldExvY2FsU29ja2V0QWRkcmVzcygpLnRvU3RyaW5nKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiBFeHBlY3RlZDogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAobmV3IEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3J0TnVtYmVyKSkudG9TdHJpbmcoKSwgdGhlU29ja2V0CisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TG9jYWxTb2NrZXRBZGRyZXNzKCkuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TG9jYWxIb3N0KCksIHBvcnROdW1iZXIpKSk7CisKKyAgICAgICAgLy8gbWFrZSBzdXJlIHdlIGNhbiBub3cgY29ubmVjdCBhbmQgdGhhdCBjb25uZWN0aW9ucyBhcHBlYXIgdG8gY29tZQorICAgICAgICAvLyBmcm9tIHRoZSBhZGRyZXNzIHdlIGJvdW5kIHRvLgorICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyB0aGVBZGRyZXNzID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzCisgICAgICAgICAgICAgICAgLmdldExvY2FsSG9zdCgpLCBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCkpOworICAgICAgICBTZXJ2ZXJTb2NrZXQgc2VydmVyU29ja2V0ID0gbmV3IFNlcnZlclNvY2tldCgpOworICAgICAgICBzZXJ2ZXJTb2NrZXQuYmluZCh0aGVBZGRyZXNzKTsKKyAgICAgICAgdGhlU29ja2V0LmNvbm5lY3QodGhlQWRkcmVzcyk7CisgICAgICAgIFNvY2tldCBzZXJ2U29jayA9IHNlcnZlclNvY2tldC5hY2NlcHQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiUmV0dXJuZWQgUmVtb3RlIGFkZHJlc3MgZnJvbSBzZXJ2ZXIgY29ubmVjdGVkIHRvIGRvZXMgbm90IG1hdGNoIGV4cGVjdGVkIGxvY2FsIGFkZHJlc3M6IgorICAgICAgICAgICAgICAgICAgICAgICAgKyBzZXJ2U29jay5nZXRSZW1vdGVTb2NrZXRBZGRyZXNzKCkudG9TdHJpbmcoKQorICAgICAgICAgICAgICAgICAgICAgICAgKyAiIEV4cGVjdGVkOiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIChuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcnROdW1iZXIpKS50b1N0cmluZygpLCBzZXJ2U29jaworICAgICAgICAgICAgICAgICAgICAgICAgLmdldFJlbW90ZVNvY2tldEFkZHJlc3MoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRMb2NhbEhvc3QoKSwgcG9ydE51bWJlcikpKTsKKyAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgIHNlcnZTb2NrLmNsb3NlKCk7CisgICAgICAgIHNlcnZlclNvY2tldC5jbG9zZSgpOworCisgICAgICAgIC8vIHZhbGlkYXRlIGlmIHdlIHBhc3MgaW4gbnVsbCB0aGF0IGl0IHBpY2tzIGFuIGFkZHJlc3MgZm9yIHVzIGFuZAorICAgICAgICAvLyBhbGwgaXMgb2sKKyAgICAgICAgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICB0aGVTb2NrZXQuYmluZChudWxsKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQmluZCB3aXRoIG51bGwgZGlkIG5vdCB3b3JrIiwgdGhlU29ja2V0CisgICAgICAgICAgICAgICAgLmdldExvY2FsU29ja2V0QWRkcmVzcygpKTsKKyAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisKKyAgICAgICAgLy8gbm93IGNoZWNrIHRoZSBlcnJvciBjb25kaXRpb25zCisKKyAgICAgICAgLy8gQWRkcmVzcyB0aGF0IHdlIGhhdmUgYWxyZWFkeSBib3VuZCB0bworICAgICAgICB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgIFNvY2tldCB0aGVTb2NrZXQyID0gbmV3IFNvY2tldCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhlQWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwKKyAgICAgICAgICAgICAgICAgICAgU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5iaW5kKHRoZUFkZHJlc3MpOworICAgICAgICAgICAgdGhlU29ja2V0Mi5iaW5kKHRoZUFkZHJlc3MpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhjZXB0aW9uIGJpbmRpbmcgdG8gYWRkcmVzcyB0aGF0IGlzIG5vdCBhdmFpbGFibGUiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgfQorICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgdGhlU29ja2V0Mi5jbG9zZSgpOworCisgICAgICAgIC8vIHVuc3VwcG9ydGVkIFNvY2tldEFkZHJlc3Mgc3ViY2xhc3MKKyAgICAgICAgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhlU29ja2V0LmJpbmQobmV3IG15U29ja2V0QWRkcmVzcygpKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4Y2VwdGlvbiB3aGVuIGJpbmRpbmcgdXNpbmcgdW5zdXBwb3J0ZWQgU29ja2V0QWRkcmVzcyBzdWJjbGFzcyIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgfQorICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2JpbmRMamF2YV9uZXRfU29ja2V0QWRkcmVzc19Qcm94eSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vVGhlIFByb3h5IHdpbGwgbm90IGltcGFjdCBvbiB0aGUgYmluZCBvcGVyYXRpb24uSXQgY2FuIGJlIGFzc2lnbmVkIHdpdGggYW55IGFkZHJlc3MuCisgICAgICAgIFByb3h5IHByb3h5ID0gbmV3IFByb3h5KFByb3h5LlR5cGUuU09DS1MsIG5ldyBJbmV0U29ja2V0QWRkcmVzcygiMTI3LjAuMC4xIiwgMCkpOworICAgICAgICBTb2NrZXQgc29ja2V0ID0gbmV3IFNvY2tldChwcm94eSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEluZXRBZGRyZXNzIGFkZHJlc3MgPSBJbmV0QWRkcmVzcy5nZXRCeU5hbWUoImxvY2FsaG9zdCIpOworICAgICAgICAgICAgaW50IHBvcnQgPSAwOworICAgICAgICAgICAgc29ja2V0LmJpbmQobmV3IEluZXRTb2NrZXRBZGRyZXNzKGFkZHJlc3MsIHBvcnQpKTsKKworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFkZHJlc3MsIHNvY2tldC5nZXRMb2NhbEFkZHJlc3MoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHBvcnQhPXNvY2tldC5nZXRMb2NhbFBvcnQoKSk7CisKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25uZWN0TGphdmFfbmV0X1NvY2tldEFkZHJlc3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gbmVlZGVkIGZvciBzb21lIHRlc3RzCisgICAgICAgIGNsYXNzIG15U29ja2V0QWRkcmVzcyBleHRlbmRzIFNvY2tldEFkZHJlc3MgeworCisgICAgICAgICAgICBwdWJsaWMgbXlTb2NrZXRBZGRyZXNzKCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgY2xhc3MgU29ja2V0Q2xvc2VyIGV4dGVuZHMgVGhyZWFkIHsKKworICAgICAgICAgICAgaW50IHRpbWVvdXQgPSAwOworCisgICAgICAgICAgICBTb2NrZXQgdGhlU29ja2V0ID0gbnVsbDsKKworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0KTsKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIFNvY2tldENsb3NlcihpbnQgdGltZW91dCwgU29ja2V0IHRoZVNvY2tldCkgeworICAgICAgICAgICAgICAgIHRoaXMudGltZW91dCA9IHRpbWVvdXQ7CisgICAgICAgICAgICAgICAgdGhpcy50aGVTb2NrZXQgPSB0aGVTb2NrZXQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBzdGFydCBieSB2YWxpZGF0aW5nIHRoZSBlcnJvciBjaGVja3MKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgIFNvY2tldCB0aGVTb2NrZXQgPSBudWxsOworICAgICAgICBTZXJ2ZXJTb2NrZXQgc2VydmVyU29ja2V0ID0gbnVsbDsKKyAgICAgICAgU29ja2V0QWRkcmVzcyB0aGVBZGRyZXNzID0gbnVsbDsKKyAgICAgICAgU29ja2V0QWRkcmVzcyBub25Db25uZWN0YWJsZUFkZHJlc3MgPSBudWxsOworICAgICAgICBTb2NrZXRBZGRyZXNzIG5vblJlYWNoYWJsZUFkZHJlc3MgPSBudWxsOworICAgICAgICBTb2NrZXRBZGRyZXNzIGludmFsaWRUeXBlID0gbnVsbDsKKyAgICAgICAgLy8gYnl0ZVtdIHRoZUJ5dGVzID0gey0xLC0xLC0xLC0xfTsKKyAgICAgICAgYnl0ZVtdIHRoZUJ5dGVzID0geyAwLCAwLCAwLCAwIH07CisgICAgICAgIHRoZUFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgcG9ydE51bWJlcik7CisgICAgICAgIG5vbkNvbm5lY3RhYmxlQWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcworICAgICAgICAgICAgICAgIC5nZXRCeUFkZHJlc3ModGhlQnl0ZXMpLCBwb3J0TnVtYmVyKTsKKyAgICAgICAgbm9uUmVhY2hhYmxlQWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcworICAgICAgICAgICAgICAgIC5nZXRCeU5hbWUoU3VwcG9ydF9Db25maWd1cmF0aW9uLlJlc29sdmVkTm90RXhpc3RpbmdIb3N0KSwKKyAgICAgICAgICAgICAgICBwb3J0TnVtYmVyKTsKKworICAgICAgICBpbnZhbGlkVHlwZSA9IG5ldyBteVNvY2tldEFkZHJlc3MoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICAgICAgdGhlU29ja2V0LmNvbm5lY3QobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJObyBleGNlcHRpb24gYWZ0ZXIgbnVsbCBhZGRyZXNzIHBhc3NlZCBpbiIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgZXhjZXB0aW9uIG51bGwgYWRkcmVzcyBwYXNzZWQgaW46ICIKKyAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCksIChlIGluc3RhbmNlb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICAgICAgdGhlU29ja2V0LmNvbm5lY3QoaW52YWxpZFR5cGUpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhjZXB0aW9uIHdoZW4gaW52YWxpZCBzb2NrZXQgYWRkcmVzcyB0eXBlIHBhc3NlZCBpbjogIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiV3JvbmcgZXhjZXB0aW9uIHdoZW4gd2hlbiBpbnZhbGlkIHNvY2tldCBhZGRyZXNzIHR5cGUgcGFzc2VkIGluOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgIChlIGluc3RhbmNlb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICAgICAgdGhlU29ja2V0LmNvbm5lY3Qobm9uQ29ubmVjdGFibGVBZGRyZXNzKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4Y2VwdGlvbiB3aGVuIG5vbiBDb25uZWN0YWJsZSBBZGRyZXNzIHBhc3NlZCBpbjogIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiV3JvbmcgZXhjZXB0aW9uIHdoZW4gbm9uIENvbm5lY3RhYmxlIEFkZHJlc3MgcGFzc2VkIGluOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCksIChlIGluc3RhbmNlb2YgQ29ubmVjdEV4Y2VwdGlvbikpOworICAgICAgICB9CisKKyAgICAgICAgLy8gbm93IHZhbGlkYXRlIHRoYXQgd2UgZ2V0IGEgY29ubmVjdCBleGNlcHRpb24gaWYgd2UgdHJ5IHRvIGNvbm5lY3QgdG8KKyAgICAgICAgLy8gYW4gYWRkcmVzcyBvbiB3aGljaCBub2JvZHkgaXMgbGlzdGVuaW5nCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY29ubmVjdCh0aGVBZGRyZXNzKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhjZXB0aW9uIHdoZW4gY29ubmVjdGluZyB0byBhZGRyZXNzIG5vYm9keSBsaXN0ZW5pbmcgb246ICIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIldyb25nIGV4Y2VwdGlvbiB3aGVuIGNvbm5lY3RpbmcgdG8gYWRkcmVzcyBub2JvZHkgbGlzdGVuaW5nIG9uOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCksIChlIGluc3RhbmNlb2YgQ29ubmVjdEV4Y2VwdGlvbikpOworICAgICAgICB9CisKKyAgICAgICAgLy8gbm93IHZhbGlkYXRlIHRoYXQgd2UgY2FuIGFjdHVhbGx5IGNvbm5lY3Qgd2hlbiBzb21lYm9keSBpcyBsaXN0ZW5pbmcKKyAgICAgICAgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICBzZXJ2ZXJTb2NrZXQgPSBuZXcgU2VydmVyU29ja2V0KCk7CisgICAgICAgIHNlcnZlclNvY2tldC5iaW5kKHRoZUFkZHJlc3MpOworICAgICAgICB0aGVTb2NrZXQuY29ubmVjdCh0aGVBZGRyZXNzKTsKKyAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgIHNlcnZlclNvY2tldC5jbG9zZSgpOworCisgICAgICAgIC8vIG5vdyB2YWxpZGF0ZSB0aGF0IHdlIGNhbiBhY3R1YWxseSBjb25uZWN0IHdoZW4gc29tZWJvZHkgaXMgbGlzdGVuaW5nCisgICAgICAgIHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgc2VydmVyU29ja2V0ID0gbmV3IFNlcnZlclNvY2tldCgpOworICAgICAgICBzZXJ2ZXJTb2NrZXQuYmluZCh0aGVBZGRyZXNzKTsKKyAgICAgICAgdGhlU29ja2V0LmNvbm5lY3QodGhlQWRkcmVzcyk7CisKKyAgICAgICAgLy8gdmFsaWRhdGUgdGhhdCB3aGVuIGEgc29ja2V0IGlzIGNvbm5lY3RlZCB0aGF0IGl0IGFuc3dlcnMKKyAgICAgICAgLy8gY29ycmVjdGx5IHRvIHJlbGF0ZWQgcXVlcmllcworICAgICAgICBhc3NlcnRUcnVlKCJTb2NrZXQgZGlkIG5vdCByZXR1cm5lZCBjb25uZWN0ZWQgd2hlbiBpdCBpczogIiwgdGhlU29ja2V0CisgICAgICAgICAgICAgICAgLmlzQ29ubmVjdGVkKCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiU29ja2V0IHJldHVybmVkIGNsb3NlZCB3aGVuIGl0IHNob3VsZCBiZSBjb25uZWN0ZWQgIiwKKyAgICAgICAgICAgICAgICB0aGVTb2NrZXQuaXNDbG9zZWQoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlNvY2tldCByZXR1cm5lZCBub3QgYm91bmQgd2hlbiBpdCBzaG91bGQgYmU6ICIsIHRoZVNvY2tldAorICAgICAgICAgICAgICAgIC5pc0JvdW5kKCkpOworICAgICAgICBhc3NlcnRGYWxzZSgKKyAgICAgICAgICAgICAgICAiU29ja2V0IHJldHVybmVkIGlucHV0IFNodXRkb3duIHdoZW4gaXQgc2hvdWxkIGJlIGNvbm5lY3RlZCAiLAorICAgICAgICAgICAgICAgIHRoZVNvY2tldC5pc0lucHV0U2h1dGRvd24oKSk7CisgICAgICAgIGFzc2VydEZhbHNlKAorICAgICAgICAgICAgICAgICJTb2NrZXQgcmV0dXJuZWQgb3V0cHV0IFNodXRkb3duIHdoZW4gaXQgc2hvdWxkIGJlIGNvbm5lY3RlZCAiLAorICAgICAgICAgICAgICAgIHRoZVNvY2tldC5pc091dHB1dFNodXRkb3duKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJMb2NhbCBwb3J0IG9uIGNvbm5lY3RlZCBzb2NrZXQgd2FzIDAiLCB0aGVTb2NrZXQKKyAgICAgICAgICAgICAgICAuZ2V0TG9jYWxQb3J0KCkgIT0gMCk7CisgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICBzZXJ2ZXJTb2NrZXQuY2xvc2UoKTsKKworICAgICAgICAvLyBub3cgdmFsaWRhdGUgdGhhdCB3ZSBnZXQgdGhlIHJpZ2h0IGV4Y2VwdGlvbiBpZiB3ZSBjb25uZWN0IHdoZW4gd2UKKyAgICAgICAgLy8gYXJlIGFscmVhZHkgY29ubmVjdGVkCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQgPSBuZXcgU2VydmVyU29ja2V0KCk7CisgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQuYmluZCh0aGVBZGRyZXNzKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5jb25uZWN0KHRoZUFkZHJlc3MpOworICAgICAgICAgICAgdGhlU29ja2V0LmNvbm5lY3QodGhlQWRkcmVzcyk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIHNlcnZlclNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhjZXB0aW9uIHdoZW4gd2UgdHJ5IHRvIGNvbm5lY3Qgb24gYSBjb25uZWN0ZWQgc29ja2V0OiAiKTsKKworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIldyb25nIGV4Y2VwdGlvbiB3aGVuIGNvbm5lY3Rpbmcgb24gc29ja2V0IHRoYXQgaXMgYWxscmVhZHkgY29ubmVjdGVkIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpLCAoZSBpbnN0YW5jZW9mIFNvY2tldEV4Y2VwdGlvbikpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgICAgICAgICAgICJXcm9uZyBleGNlcHRpb24gd2hlbiBjb25uZWN0aW5nIG9uIHNvY2tldCB0aGF0IGlzIGFsbHJlYWR5IGNvbm5lY3RlZCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgKGUgaW5zdGFuY2VvZiBTb2NrZXRUaW1lb3V0RXhjZXB0aW9uKSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgICAgIHNlcnZlclNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUyKSB7CisgICAgICAgICAgICB9CisKKyAgICAgICAgfQorCisgICAgICAgIC8vIG5vdyB2YWxpZGF0ZSB0aGF0IGNvbm5lY3RlZCBzb2NrZXQgY2FuIGJlIHVzZWQgdG8gcmVhZC93cml0ZQorICAgICAgICB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgIHNlcnZlclNvY2tldCA9IG5ldyBTZXJ2ZXJTb2NrZXQoKTsKKyAgICAgICAgc2VydmVyU29ja2V0LmJpbmQodGhlQWRkcmVzcyk7CisgICAgICAgIHRoZVNvY2tldC5jb25uZWN0KHRoZUFkZHJlc3MpOworICAgICAgICBTb2NrZXQgc2VydlNvY2sgPSBzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgIElucHV0U3RyZWFtIHRoZUlucHV0ID0gdGhlU29ja2V0LmdldElucHV0U3RyZWFtKCk7CisgICAgICAgIE91dHB1dFN0cmVhbSB0aGVPdXRwdXQgPSBzZXJ2U29jay5nZXRPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gdGhlSW5wdXQyID0gc2VydlNvY2suZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgT3V0cHV0U3RyZWFtIHRoZU91dHB1dDIgPSB0aGVTb2NrZXQuZ2V0T3V0cHV0U3RyZWFtKCk7CisKKyAgICAgICAgU3RyaW5nIHNlbmRTdHJpbmcgPSBuZXcgU3RyaW5nKCJUZXN0Iik7CisgICAgICAgIHRoZU91dHB1dC53cml0ZShzZW5kU3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICB0aGVPdXRwdXQuZmx1c2goKTsKKworICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisKKyAgICAgICAgaW50IHRvdGFsQnl0ZXNSZWFkID0gMDsKKyAgICAgICAgYnl0ZVtdIG15Qnl0ZXMgPSBuZXcgYnl0ZVsxMDBdOworICAgICAgICB3aGlsZSAodGhlSW5wdXQuYXZhaWxhYmxlKCkgPiAwKSB7CisgICAgICAgICAgICBpbnQgYnl0ZXNSZWFkID0gdGhlSW5wdXQucmVhZChteUJ5dGVzLCB0b3RhbEJ5dGVzUmVhZCwKKyAgICAgICAgICAgICAgICAgICAgbXlCeXRlcy5sZW5ndGggLSB0b3RhbEJ5dGVzUmVhZCk7CisgICAgICAgICAgICB0b3RhbEJ5dGVzUmVhZCA9IHRvdGFsQnl0ZXNSZWFkICsgYnl0ZXNSZWFkOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIHJlY2VpdmVkU3RyaW5nID0gbmV3IFN0cmluZyhteUJ5dGVzLCAwLCB0b3RhbEJ5dGVzUmVhZCk7CisgICAgICAgIGFzc2VydFRydWUoIkNvdWxkIG5vdCByZWN2IG9uIHNvY2tldCBjb25uZWN0ZWQgd2l0aCB0aW1lb3V0OiIKKyAgICAgICAgICAgICAgICArIHJlY2VpdmVkU3RyaW5nICsgIjoiICsgc2VuZFN0cmluZywgcmVjZWl2ZWRTdHJpbmcKKyAgICAgICAgICAgICAgICAuZXF1YWxzKHNlbmRTdHJpbmcpKTsKKworICAgICAgICBzZW5kU3RyaW5nID0gbmV3IFN0cmluZygiU0VORCAtIFRlc3QiKTsKKyAgICAgICAgdGhlT3V0cHV0Mi53cml0ZShzZW5kU3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICB0aGVPdXRwdXQyLmZsdXNoKCk7CisgICAgICAgIFRocmVhZC5zbGVlcCgxMDAwKTsKKworICAgICAgICB0b3RhbEJ5dGVzUmVhZCA9IDA7CisgICAgICAgIG15Qnl0ZXMgPSBuZXcgYnl0ZVsxMDBdOworICAgICAgICB3aGlsZSAodGhlSW5wdXQyLmF2YWlsYWJsZSgpID4gMCkgeworICAgICAgICAgICAgaW50IGJ5dGVzUmVhZCA9IHRoZUlucHV0Mi5yZWFkKG15Qnl0ZXMsIHRvdGFsQnl0ZXNSZWFkLAorICAgICAgICAgICAgICAgICAgICBteUJ5dGVzLmxlbmd0aCAtIHRvdGFsQnl0ZXNSZWFkKTsKKyAgICAgICAgICAgIHRvdGFsQnl0ZXNSZWFkID0gdG90YWxCeXRlc1JlYWQgKyBieXRlc1JlYWQ7CisgICAgICAgIH0KKworICAgICAgICByZWNlaXZlZFN0cmluZyA9IG5ldyBTdHJpbmcobXlCeXRlcywgMCwgdG90YWxCeXRlc1JlYWQpOworICAgICAgICBhc3NlcnRUcnVlKCJDb3VsZCBub3Qgc2VuZCBvbiBzb2NrZXQgY29ubmVjdGVkIHdpdGggdGltZW91dDoiCisgICAgICAgICAgICAgICAgKyByZWNlaXZlZFN0cmluZyArICI6IiArIHNlbmRTdHJpbmcsIHJlY2VpdmVkU3RyaW5nCisgICAgICAgICAgICAgICAgLmVxdWFscyhzZW5kU3RyaW5nKSk7CisKKyAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgIHNlcnZlclNvY2tldC5jbG9zZSgpOworCisgICAgICAgIFNvY2tldENoYW5uZWwgY2hhbm5lbCA9IFNvY2tldENoYW5uZWwub3BlbigpOworICAgICAgICBjaGFubmVsLmNvbmZpZ3VyZUJsb2NraW5nKGZhbHNlKTsKKyAgICAgICAgU29ja2V0IHNvY2tldCA9IGNoYW5uZWwuc29ja2V0KCk7CisgICAgICAgIGludCBwb3J0ID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc29ja2V0LmNvbm5lY3QoIG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwKKyAgICAgICAgICAgICAgICAgICAgU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgc29ja2V0LmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25uZWN0TGphdmFfbmV0X1NvY2tldEFkZHJlc3NJKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgLy8gbmVlZGVkIGZvciBzb21lIHRlc3RzCisgICAgICAgIGNsYXNzIG15U29ja2V0QWRkcmVzcyBleHRlbmRzIFNvY2tldEFkZHJlc3MgeworCisgICAgICAgICAgICBwdWJsaWMgbXlTb2NrZXRBZGRyZXNzKCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgY2xhc3MgU29ja2V0Q2xvc2VyIGV4dGVuZHMgVGhyZWFkIHsKKworICAgICAgICAgICAgaW50IHRpbWVvdXQgPSAwOworCisgICAgICAgICAgICBTb2NrZXQgdGhlU29ja2V0ID0gbnVsbDsKKworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0KTsKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgU29ja2V0Q2xvc2VyKGludCB0aW1lb3V0LCBTb2NrZXQgdGhlU29ja2V0KSB7CisgICAgICAgICAgICAgICAgdGhpcy50aW1lb3V0ID0gdGltZW91dDsKKyAgICAgICAgICAgICAgICB0aGlzLnRoZVNvY2tldCA9IHRoZVNvY2tldDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGNsYXNzIFNvY2tldENvbm5lY3RvciBleHRlbmRzIFRocmVhZCB7CisKKyAgICAgICAgICAgIGludCB0aW1lb3V0ID0gMDsKKworICAgICAgICAgICAgU29ja2V0IHRoZVNvY2tldCA9IG51bGw7CisKKyAgICAgICAgICAgIFNvY2tldEFkZHJlc3MgYWRkcmVzcyA9IG51bGw7CisKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICB0aGVTb2NrZXQuY29ubmVjdChhZGRyZXNzLCB0aW1lb3V0KTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIFNvY2tldENvbm5lY3RvcihpbnQgdGltZW91dCwgU29ja2V0IHRoZVNvY2tldCwKKyAgICAgICAgICAgICAgICAgICAgU29ja2V0QWRkcmVzcyBhZGRyZXNzKSB7CisgICAgICAgICAgICAgICAgdGhpcy50aW1lb3V0ID0gdGltZW91dDsKKyAgICAgICAgICAgICAgICB0aGlzLnRoZVNvY2tldCA9IHRoZVNvY2tldDsKKyAgICAgICAgICAgICAgICB0aGlzLmFkZHJlc3MgPSBhZGRyZXNzOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gc3RhcnQgYnkgdmFsaWRhdGluZyB0aGUgZXJyb3IgY2hlY2tzCisgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICBTb2NrZXQgdGhlU29ja2V0ID0gbnVsbDsKKyAgICAgICAgU2VydmVyU29ja2V0IHNlcnZlclNvY2tldCA9IG51bGw7CisgICAgICAgIFNvY2tldEFkZHJlc3MgdGhlQWRkcmVzcyA9IG51bGw7CisgICAgICAgIFNvY2tldEFkZHJlc3Mgbm9uQ29ubmVjdGFibGVBZGRyZXNzID0gbnVsbDsKKyAgICAgICAgU29ja2V0QWRkcmVzcyBub25SZWFjaGFibGVBZGRyZXNzID0gbnVsbDsKKyAgICAgICAgU29ja2V0QWRkcmVzcyBub25MaXN0ZW5pbmdBZGRyZXNzID0gbnVsbDsKKyAgICAgICAgU29ja2V0QWRkcmVzcyBpbnZhbGlkVHlwZSA9IG51bGw7CisgICAgICAgIGJ5dGVbXSB0aGVCeXRlcyA9IHsgMCwgMCwgMCwgMCB9OworCisgICAgICAgIHRoZUFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgcG9ydE51bWJlcik7CisgICAgICAgIG5vbkNvbm5lY3RhYmxlQWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcworICAgICAgICAgICAgICAgIC5nZXRCeUFkZHJlc3ModGhlQnl0ZXMpLCBwb3J0TnVtYmVyKTsKKyAgICAgICAgbm9uUmVhY2hhYmxlQWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcworICAgICAgICAgICAgICAgIC5nZXRCeU5hbWUoU3VwcG9ydF9Db25maWd1cmF0aW9uLlJlc29sdmVkTm90RXhpc3RpbmdIb3N0KSwKKyAgICAgICAgICAgICAgICBwb3J0TnVtYmVyKTsKKyAgICAgICAgLy8gbWFrZSBzdXJlIHdlIGdldCBhbm90aGVyIHBvcnQKKyAgICAgICAgVGhyZWFkLnNsZWVwKDcwMDApOworICAgICAgICBub25MaXN0ZW5pbmdBZGRyZXNzID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLAorICAgICAgICAgICAgICAgIFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKSk7CisgICAgICAgIGludmFsaWRUeXBlID0gbmV3IG15U29ja2V0QWRkcmVzcygpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY29ubmVjdCh0aGVBZGRyZXNzLCAtMTAwKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4Y2VwdGlvbiBhZnRlciBuZWdhdGl2ZSB0aW1lb3V0IHBhc3NlZCBpbiIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgZXhjZXB0aW9uIHdoZW4gbmVnYXRpdmUgdGltZW91dCBwYXNzZWQgaW46ICIKKyAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCksIChlIGluc3RhbmNlb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICAgICAgdGhlU29ja2V0LmNvbm5lY3QobnVsbCwgMCk7CisgICAgICAgICAgICBmYWlsKCJObyBleGNlcHRpb24gYWZ0ZXIgbnVsbCBhZGRyZXNzIHBhc3NlZCBpbiIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgZXhjZXB0aW9uIG51bGwgYWRkcmVzcyBwYXNzZWQgaW46ICIKKyAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCksIChlIGluc3RhbmNlb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICAgICAgdGhlU29ja2V0LmNvbm5lY3QoaW52YWxpZFR5cGUsIDEwMDAwMCk7CisgICAgICAgICAgICBmYWlsKCJObyBleGNlcHRpb24gd2hlbiBpbnZhbGlkIHNvY2tldCBhZGRyZXNzIHR5cGUgcGFzc2VkIGluOiAiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJXcm9uZyBleGNlcHRpb24gd2hlbiB3aGVuIGludmFsaWQgc29ja2V0IGFkZHJlc3MgdHlwZSBwYXNzZWQgaW46ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgKGUgaW5zdGFuY2VvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24pKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY29ubmVjdChub25Db25uZWN0YWJsZUFkZHJlc3MsIDEwMDAwMCk7CisgICAgICAgICAgICBmYWlsKCJObyBleGNlcHRpb24gd2hlbiBub24gQ29ubmVjdGFibGUgQWRkcmVzcyBwYXNzZWQgaW46ICIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIldyb25nIGV4Y2VwdGlvbiB3aGVuIG5vbiBDb25uZWN0YWJsZSBBZGRyZXNzIHBhc3NlZCBpbjogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpLCAoZSBpbnN0YW5jZW9mIFNvY2tldEV4Y2VwdGlvbikpOworICAgICAgICB9CisKKyAgICAgICAgLy8gbm93IHZhbGlkYXRlIHRoYXQgd2UgZ2V0IGEgY29ubmVjdCBleGNlcHRpb24gaWYgd2UgdHJ5IHRvIGNvbm5lY3QgdG8KKyAgICAgICAgLy8gYW4gYWRkcmVzcyBvbiB3aGljaCBub2JvZHkgaXMgbGlzdGVuaW5nCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY29ubmVjdCh0aGVBZGRyZXNzLCAwKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgZmFpbCgiTm8gdGltZW91dDpObyBleGNlcHRpb24gd2hlbiBjb25uZWN0aW5nIHRvIGFkZHJlc3Mgbm9ib2R5IGxpc3RlbmluZyBvbjogIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiTm8gdGltZW91dDpXcm9uZyBleGNlcHRpb24gd2hlbiBjb25uZWN0aW5nIHRvIGFkZHJlc3Mgbm9ib2R5IGxpc3RlbmluZyBvbjogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpLCAoZSBpbnN0YW5jZW9mIENvbm5lY3RFeGNlcHRpb24pKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIG5vdyB2YWxpZGF0ZSB0aGF0IHdlIGNhbiBhY3R1YWxseSBjb25uZWN0IHdoZW4gc29tZWJvZHkgaXMgbGlzdGVuaW5nCisgICAgICAgIHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgc2VydmVyU29ja2V0ID0gbmV3IFNlcnZlclNvY2tldCgpOworICAgICAgICBzZXJ2ZXJTb2NrZXQuYmluZCh0aGVBZGRyZXNzKTsKKyAgICAgICAgdGhlU29ja2V0LmNvbm5lY3QodGhlQWRkcmVzcywgMCk7CisgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICBzZXJ2ZXJTb2NrZXQuY2xvc2UoKTsKKworICAgICAgICAvLyBub3cgdmFsaWRhdGUgdGhhdCB3ZSBnZXQgYSBjb25uZWN0IGV4Y2VwdGlvbiBpZiB3ZSB0cnkgdG8gY29ubmVjdCB0bworICAgICAgICAvLyBhbiBhZGRyZXNzIG9uIHdoaWNoIG5vYm9keSBpcyBsaXN0ZW5pbmcKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5jb25uZWN0KG5vbkxpc3RlbmluZ0FkZHJlc3MsIDEwMDAwMCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4Y2VwdGlvbiB3aGVuIGNvbm5lY3RpbmcgdG8gYWRkcmVzcyBub2JvZHkgbGlzdGVuaW5nIG9uOiAiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJXcm9uZyBleGNlcHRpb24gd2hlbiBjb25uZWN0aW5nIHRvIGFkZHJlc3Mgbm9ib2R5IGxpc3RlbmluZyBvbjogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpLCAoZSBpbnN0YW5jZW9mIENvbm5lY3RFeGNlcHRpb24pKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIG5vdyB2YWxpZGF0ZSB0aGF0IHdlIGdldCBhIGludGVycnVwdGVkIGV4Y2VwdGlvbiBpZiB3ZSB0cnkgdG8gY29ubmVjdAorICAgICAgICAvLyB0byBhbiBhZGRyZXNzIG9uIHdoaWNoIG5vYm9keSBpcyBhY2NlcHRpbmcgY29ubmVjdGlvbnMgYW5kIHRoZQorICAgICAgICAvLyB0aW1lb3V0IGV4cGlyZWQKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5jb25uZWN0KG5vblJlYWNoYWJsZUFkZHJlc3MsIDIwMCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGludGVycnVwdGVkIGV4Y2VwdGlvbiB3aGVuIGNvbm5lY3RpbmcgdG8gYWRkcmVzcyBub2JvZHkgbGlzdGVuaW5nIG9uIHdpdGggc2hvcnQgdGltZW91dCAyMDA6ICIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIldyb25nIGV4Y2VwdGlvbiB3aGVuIGNvbm5lY3RpbmcgdG8gYWRkcmVzcyBub2JvZHkgbGlzdGVuaW5nIG9uIHdpdGggc2hvcnQgdGltZW91dCAyMDA6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgKGUgaW5zdGFuY2VvZiBTb2NrZXRUaW1lb3V0RXhjZXB0aW9uKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBub3cgdmFsaWRhdGUgdGhhdCB3ZSBnZXQgYSBpbnRlcnJ1cHRlZCBleGNlcHRpb24gaWYgd2UgdHJ5IHRvIGNvbm5lY3QKKyAgICAgICAgLy8gdG8gYW4gYWRkcmVzcyBvbiB3aGljaCBub2JvZHkgaXMgYWNjZXB0aW5nIGNvbm5lY3Rpb25zIGFuZCB0aGUKKyAgICAgICAgLy8gdGltZW91dCBleHBpcmVkCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY29ubmVjdChub25SZWFjaGFibGVBZGRyZXNzLCA0MCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGludGVycnVwdGVkIGV4Y2VwdGlvbiB3aGVuIGNvbm5lY3RpbmcgdG8gYWRkcmVzcyBub2JvZHkgbGlzdGVuaW5nIG9uIHdpdGggc2hvcnQgdGltZW91dCA0MDogIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiV3JvbmcgZXhjZXB0aW9uIHdoZW4gY29ubmVjdGluZyB0byBhZGRyZXNzIG5vYm9keSBsaXN0ZW5pbmcgb24gd2l0aCBzaG9ydCB0aW1lb3V0IDQwOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgIChlIGluc3RhbmNlb2YgU29ja2V0VGltZW91dEV4Y2VwdGlvbikpOworICAgICAgICB9CisKKyAgICAgICAgLy8gbm93IHZhbGlkYXRlIHRoYXQgd2UgY2FuIGFjdHVhbGx5IGNvbm5lY3Qgd2hlbiBzb21lYm9keSBpcyBsaXN0ZW5pbmcKKyAgICAgICAgbmV3IEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBTdXBwb3J0X1BvcnRNYW5hZ2VyCisgICAgICAgICAgICAgICAgLmdldE5leHRQb3J0KCkpOworICAgICAgICB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgIHNlcnZlclNvY2tldCA9IG5ldyBTZXJ2ZXJTb2NrZXQoKTsKKyAgICAgICAgc2VydmVyU29ja2V0LmJpbmQodGhlQWRkcmVzcyk7CisgICAgICAgIHRoZVNvY2tldC5jb25uZWN0KHRoZUFkZHJlc3MsIDEwMDAwMCk7CisKKyAgICAgICAgLy8gdmFsaWRhdGUgdGhhdCB3aGVuIGEgc29ja2V0IGlzIGNvbm5lY3RlZCB0aGF0IGl0IGFuc3dlcnMKKyAgICAgICAgLy8gY29ycmVjdGx5IHRvIHJlbGF0ZWQgcXVlcmllcworICAgICAgICBhc3NlcnRUcnVlKCJTb2NrZXQgZGlkIG5vdCByZXR1cm5lZCBjb25uZWN0ZWQgd2hlbiBpdCBpczogIiwgdGhlU29ja2V0CisgICAgICAgICAgICAgICAgLmlzQ29ubmVjdGVkKCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiU29ja2V0IHJldHVybmVkIGNsb3NlZCB3aGVuIGl0IHNob3VsZCBiZSBjb25uZWN0ZWQgIiwKKyAgICAgICAgICAgICAgICB0aGVTb2NrZXQuaXNDbG9zZWQoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlNvY2tldCByZXR1cm5lZCBub3QgYm91bmQgd2hlbiBpdCBzaG91bGQgYmU6ICIsIHRoZVNvY2tldAorICAgICAgICAgICAgICAgIC5pc0JvdW5kKCkpOworICAgICAgICBhc3NlcnRGYWxzZSgKKyAgICAgICAgICAgICAgICAiU29ja2V0IHJldHVybmVkIGlucHV0IFNodXRkb3duIHdoZW4gaXQgc2hvdWxkIGJlIGNvbm5lY3RlZCAiLAorICAgICAgICAgICAgICAgIHRoZVNvY2tldC5pc0lucHV0U2h1dGRvd24oKSk7CisgICAgICAgIGFzc2VydEZhbHNlKAorICAgICAgICAgICAgICAgICJTb2NrZXQgcmV0dXJuZWQgb3V0cHV0IFNodXRkb3duIHdoZW4gaXQgc2hvdWxkIGJlIGNvbm5lY3RlZCAiLAorICAgICAgICAgICAgICAgIHRoZVNvY2tldC5pc091dHB1dFNodXRkb3duKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJMb2NhbCBwb3J0IG9uIGNvbm5lY3RlZCBzb2NrZXQgd2FzIDAiLCB0aGVTb2NrZXQKKyAgICAgICAgICAgICAgICAuZ2V0TG9jYWxQb3J0KCkgIT0gMCk7CisgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICBzZXJ2ZXJTb2NrZXQuY2xvc2UoKTsKKworICAgICAgICAvLyBub3cgdmFsaWRhdGUgdGhhdCB3ZSBnZXQgdGhlIHJpZ2h0IGV4Y2VwdGlvbiBpZiB3ZSBjb25uZWN0IHdoZW4gd2UKKyAgICAgICAgLy8gYXJlIGFscmVhZHkgY29ubmVjdGVkCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgICAgIFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKSk7CisgICAgICAgICAgICB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQgPSBuZXcgU2VydmVyU29ja2V0KCk7CisgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQuYmluZCh0aGVBZGRyZXNzKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5jb25uZWN0KHRoZUFkZHJlc3MsIDEwMDAwMCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY29ubmVjdCh0aGVBZGRyZXNzLCAxMDAwMDApOworICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4Y2VwdGlvbiB3aGVuIHdlIHRyeSB0byBjb25uZWN0IG9uIGEgY29ubmVjdGVkIHNvY2tldDogIik7CisKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJXcm9uZyBleGNlcHRpb24gd2hlbiBjb25uZWN0aW5nIG9uIHNvY2tldCB0aGF0IGlzIGFscmVhZHkgY29ubmVjdGVkIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpLCAoZSBpbnN0YW5jZW9mIFNvY2tldEV4Y2VwdGlvbikpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgICAgICAgICAgICJXcm9uZyBleGNlcHRpb24gd2hlbiBjb25uZWN0aW5nIG9uIHNvY2tldCB0aGF0IGlzIGFscmVhZHkgY29ubmVjdGVkIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpLAorICAgICAgICAgICAgICAgICAgICAoZSBpbnN0YW5jZW9mIFNvY2tldFRpbWVvdXRFeGNlcHRpb24pKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZTIpIHsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisKKyAgICAgICAgLy8gbm93IHZhbGlkYXRlIHRoYXQgY29ubmVjdGVkIHNvY2tldCBjYW4gYmUgdXNlZCB0byByZWFkL3dyaXRlCisgICAgICAgIG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgU3VwcG9ydF9Qb3J0TWFuYWdlcgorICAgICAgICAgICAgICAgIC5nZXROZXh0UG9ydCgpKTsKKyAgICAgICAgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICBzZXJ2ZXJTb2NrZXQgPSBuZXcgU2VydmVyU29ja2V0KCk7CisgICAgICAgIHNlcnZlclNvY2tldC5iaW5kKHRoZUFkZHJlc3MpOworICAgICAgICB0aGVTb2NrZXQuY29ubmVjdCh0aGVBZGRyZXNzLCAxMDAwMDApOworICAgICAgICBTb2NrZXQgc2VydlNvY2sgPSBzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgIElucHV0U3RyZWFtIHRoZUlucHV0ID0gdGhlU29ja2V0LmdldElucHV0U3RyZWFtKCk7CisgICAgICAgIE91dHB1dFN0cmVhbSB0aGVPdXRwdXQgPSBzZXJ2U29jay5nZXRPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gdGhlSW5wdXQyID0gc2VydlNvY2suZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgT3V0cHV0U3RyZWFtIHRoZU91dHB1dDIgPSB0aGVTb2NrZXQuZ2V0T3V0cHV0U3RyZWFtKCk7CisKKyAgICAgICAgU3RyaW5nIHNlbmRTdHJpbmcgPSBuZXcgU3RyaW5nKCJUZXN0Iik7CisgICAgICAgIHRoZU91dHB1dC53cml0ZShzZW5kU3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICB0aGVPdXRwdXQuZmx1c2goKTsKKworICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisKKyAgICAgICAgaW50IHRvdGFsQnl0ZXNSZWFkID0gMDsKKyAgICAgICAgYnl0ZVtdIG15Qnl0ZXMgPSBuZXcgYnl0ZVsxMDBdOworICAgICAgICB3aGlsZSAodGhlSW5wdXQuYXZhaWxhYmxlKCkgPiAwKSB7CisgICAgICAgICAgICBpbnQgYnl0ZXNSZWFkID0gdGhlSW5wdXQucmVhZChteUJ5dGVzLCB0b3RhbEJ5dGVzUmVhZCwKKyAgICAgICAgICAgICAgICAgICAgbXlCeXRlcy5sZW5ndGggLSB0b3RhbEJ5dGVzUmVhZCk7CisgICAgICAgICAgICB0b3RhbEJ5dGVzUmVhZCA9IHRvdGFsQnl0ZXNSZWFkICsgYnl0ZXNSZWFkOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIHJlY2VpdmVkU3RyaW5nID0gbmV3IFN0cmluZyhteUJ5dGVzLCAwLCB0b3RhbEJ5dGVzUmVhZCk7CisgICAgICAgIGFzc2VydFRydWUoIkNvdWxkIG5vdCByZWN2IG9uIHNvY2tldCBjb25uZWN0ZWQgd2l0aCB0aW1lb3V0OiIKKyAgICAgICAgICAgICAgICArIHJlY2VpdmVkU3RyaW5nICsgIjoiICsgc2VuZFN0cmluZywgcmVjZWl2ZWRTdHJpbmcKKyAgICAgICAgICAgICAgICAuZXF1YWxzKHNlbmRTdHJpbmcpKTsKKworICAgICAgICBzZW5kU3RyaW5nID0gbmV3IFN0cmluZygiU0VORCAtIFRlc3QiKTsKKyAgICAgICAgdGhlT3V0cHV0Mi53cml0ZShzZW5kU3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICB0aGVPdXRwdXQyLmZsdXNoKCk7CisKKyAgICAgICAgdG90YWxCeXRlc1JlYWQgPSAwOworICAgICAgICBteUJ5dGVzID0gbmV3IGJ5dGVbMTAwXTsKKyAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgICB3aGlsZSAodGhlSW5wdXQyLmF2YWlsYWJsZSgpID4gMCkgeworICAgICAgICAgICAgaW50IGJ5dGVzUmVhZCA9IHRoZUlucHV0Mi5yZWFkKG15Qnl0ZXMsIHRvdGFsQnl0ZXNSZWFkLAorICAgICAgICAgICAgICAgICAgICBteUJ5dGVzLmxlbmd0aCAtIHRvdGFsQnl0ZXNSZWFkKTsKKyAgICAgICAgICAgIHRvdGFsQnl0ZXNSZWFkID0gdG90YWxCeXRlc1JlYWQgKyBieXRlc1JlYWQ7CisgICAgICAgIH0KKworICAgICAgICByZWNlaXZlZFN0cmluZyA9IG5ldyBTdHJpbmcobXlCeXRlcywgMCwgdG90YWxCeXRlc1JlYWQpOworICAgICAgICBhc3NlcnRUcnVlKCJDb3VsZCBub3Qgc2VuZCBvbiBzb2NrZXQgY29ubmVjdGVkIHdpdGggdGltZW91dDoiCisgICAgICAgICAgICAgICAgKyByZWNlaXZlZFN0cmluZyArICI6IiArIHNlbmRTdHJpbmcsIHJlY2VpdmVkU3RyaW5nCisgICAgICAgICAgICAgICAgLmVxdWFscyhzZW5kU3RyaW5nKSk7CisKKyAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgIHNlcnZlclNvY2tldC5jbG9zZSgpOworCisgICAgICAgIC8vIG5vdyB0cnkgdG8gc2V0IG9wdGlvbnMgd2hpbGUgd2UgYXJlIGNvbm5lY3RpbmcKKyAgICAgICAgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICBTb2NrZXRDb25uZWN0b3IgY29ubmVjdG9yID0gbmV3IFNvY2tldENvbm5lY3Rvcig1MDAwLCB0aGVTb2NrZXQsIG5vblJlYWNoYWJsZUFkZHJlc3MpOworICAgICAgICBjb25uZWN0b3Iuc3RhcnQoKTsKKyAgICAgICAgdGhlU29ja2V0LnNldFNvVGltZW91dCgxMDAwKTsKKyAgICAgICAgVGhyZWFkLnNsZWVwKDEwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTb2NrZXQgb3B0aW9uIG5vdCBzZXQgZHVyaW5nIGNvbm5lY3Q6IDEwICIsIDEwMDAsIHRoZVNvY2tldC5nZXRTb1RpbWVvdXQoKSk7CisgICAgICAgIFRocmVhZC5zbGVlcCg1MCk7CisgICAgICAgIHRoZVNvY2tldC5zZXRTb1RpbWVvdXQoMjAwMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU29ja2V0IG9wdGlvbiBub3Qgc2V0IGR1cmluZyBjb25uZWN0OiA1MCAiLCAyMDAwLCB0aGVTb2NrZXQuZ2V0U29UaW1lb3V0KCkpOworICAgICAgICBUaHJlYWQuc2xlZXAoNTAwMCk7CisgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworCisgICAgICAgIFNvY2tldENoYW5uZWwgY2hhbm5lbCA9IFNvY2tldENoYW5uZWwub3BlbigpOworICAgICAgICBjaGFubmVsLmNvbmZpZ3VyZUJsb2NraW5nKGZhbHNlKTsKKyAgICAgICAgU29ja2V0IHNvY2tldCA9IGNoYW5uZWwuc29ja2V0KCk7CisgICAgICAgIGludCBwb3J0ID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc29ja2V0LmNvbm5lY3QoIG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwKKyAgICAgICAgICAgICAgICAgICAgU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpKSwgcG9ydCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgY2hhbm5lbC5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNJbnB1dFNodXRkb3duKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgdGhlQWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcworICAgICAgICAgICAgICAgIC5nZXRMb2NhbEhvc3QoKSwgU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpKTsKKyAgICAgICAgU29ja2V0IHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgU2VydmVyU29ja2V0IHNlcnZlclNvY2tldCA9IG5ldyBTZXJ2ZXJTb2NrZXQoKTsKKyAgICAgICAgc2VydmVyU29ja2V0LmJpbmQodGhlQWRkcmVzcyk7CisgICAgICAgIHRoZVNvY2tldC5jb25uZWN0KHRoZUFkZHJlc3MpOworICAgICAgICBTb2NrZXQgc2VydlNvY2sgPSBzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgIElucHV0U3RyZWFtIHRoZUlucHV0ID0gdGhlU29ja2V0LmdldElucHV0U3RyZWFtKCk7CisgICAgICAgIE91dHB1dFN0cmVhbSB0aGVPdXRwdXQgPSBzZXJ2U29jay5nZXRPdXRwdXRTdHJlYW0oKTsKKworICAgICAgICAvLyBtYWtlIHN1cmUgd2UgZ2V0IHRoZSByaWdodCBhbnN3ZXIgd2l0aCBuZXdseSBjb25uZWN0ZWQgc29ja2V0CisgICAgICAgIGFzc2VydEZhbHNlKCJTb2NrZXQgaW5kaWNhdGVkIGlucHV0IHNodXRkb3duIHdoZW4gaXQgc2hvdWxkIG5vdCBoYXZlIiwKKyAgICAgICAgICAgICAgICB0aGVTb2NrZXQuaXNJbnB1dFNodXRkb3duKCkpOworCisgICAgICAgIC8vIHNodXRkb3duIHRoZSBvdXRwdXQKKyAgICAgICAgdGhlU29ja2V0LnNodXRkb3duSW5wdXQoKTsKKworICAgICAgICAvLyBtYWtlIHN1cmUgd2UgZ2V0IHRoZSByaWdodCBhbnN3ZXIgb25jZSBpdCBpcyBzaHV0IGRvd24KKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiU29ja2V0IGluZGljYXRlZCBpbnB1dCB3YXMgTk9UIHNodXRkb3duIHdoZW4gaXQgc2hvdWxkIGhhdmUgYmVlbiIsCisgICAgICAgICAgICAgICAgdGhlU29ja2V0LmlzSW5wdXRTaHV0ZG93bigpKTsKKworICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgc2VydmVyU29ja2V0LmNsb3NlKCk7CisKKyAgICAgICAgLy8gbWFrZSBzdXJlIHdlIGdldCB0aGUgcmlnaHQgYW5zd2VyIGZvciBjbG9zZWQgc29ja2V0cworICAgICAgICBhc3NlcnRGYWxzZSgKKyAgICAgICAgICAgICAgICAiU29ja2V0IGluZGljYXRlZCBpbnB1dCB3YXMgc2h1dGRvd24gd2hlbiBzb2NrZXQgd2FzIGNsb3NlZCIsCisgICAgICAgICAgICAgICAgc2VydlNvY2suaXNJbnB1dFNodXRkb3duKCkpOworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc091dHB1dFNodXRkb3duKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgdGhlQWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcworICAgICAgICAgICAgICAgIC5nZXRMb2NhbEhvc3QoKSwgU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpKTsKKyAgICAgICAgU29ja2V0IHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgU2VydmVyU29ja2V0IHNlcnZlclNvY2tldCA9IG5ldyBTZXJ2ZXJTb2NrZXQoKTsKKyAgICAgICAgc2VydmVyU29ja2V0LmJpbmQodGhlQWRkcmVzcyk7CisgICAgICAgIHRoZVNvY2tldC5jb25uZWN0KHRoZUFkZHJlc3MpOworICAgICAgICBTb2NrZXQgc2VydlNvY2sgPSBzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgIElucHV0U3RyZWFtIHRoZUlucHV0ID0gdGhlU29ja2V0LmdldElucHV0U3RyZWFtKCk7CisgICAgICAgIE91dHB1dFN0cmVhbSB0aGVPdXRwdXQgPSBzZXJ2U29jay5nZXRPdXRwdXRTdHJlYW0oKTsKKworICAgICAgICAvLyBtYWtlIHN1cmUgd2UgZ2V0IHRoZSByaWdodCBhbnN3ZXIgd2l0aCBuZXdseSBjb25uZWN0ZWQgc29ja2V0CisgICAgICAgIGFzc2VydEZhbHNlKCJTb2NrZXQgaW5kaWNhdGVkIG91dHB1dCBzaHV0ZG93biB3aGVuIGl0IHNob3VsZCBub3QgaGF2ZSIsCisgICAgICAgICAgICAgICAgc2VydlNvY2suaXNPdXRwdXRTaHV0ZG93bigpKTsKKworICAgICAgICAvLyBzaHV0ZG93biB0aGUgb3V0cHV0CisgICAgICAgIHNlcnZTb2NrLnNodXRkb3duT3V0cHV0KCk7CisKKyAgICAgICAgLy8gbWFrZSBzdXJlIHdlIGdldCB0aGUgcmlnaHQgYW5zd2VyIG9uY2UgaXQgaXMgc2h1dCBkb3duCisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIlNvY2tldCBpbmRpY2F0ZWQgb3V0cHV0IHdhcyBOT1Qgc2h1dGRvd24gd2hlbiBpdCBzaG91bGQgaGF2ZSBiZWVuIiwKKyAgICAgICAgICAgICAgICBzZXJ2U29jay5pc091dHB1dFNodXRkb3duKCkpOworCisgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICBzZXJ2ZXJTb2NrZXQuY2xvc2UoKTsKKworICAgICAgICAvLyBtYWtlIHN1cmUgd2UgZ2V0IHRoZSByaWdodCBhbnN3ZXIgZm9yIGNsb3NlZCBzb2NrZXRzCisgICAgICAgIGFzc2VydEZhbHNlKAorICAgICAgICAgICAgICAgICJTb2NrZXQgaW5kaWNhdGVkIG91dHB1dCB3YXMgb3V0cHV0IHNodXRkb3duIHdoZW4gdGhlIHNvY2tldCB3YXMgY2xvc2VkIiwKKyAgICAgICAgICAgICAgICB0aGVTb2NrZXQuaXNPdXRwdXRTaHV0ZG93bigpKTsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0UmV1c2VBZGRyZXNzWigpIHsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW5ldEFkZHJlc3MgYWxsQWRkcmVzc2VzW10gPSBJbmV0QWRkcmVzcy5nZXRBbGxCeU5hbWUoSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgLmdldExvY2FsSG9zdCgpLmdldEhvc3ROYW1lKCkpOworICAgICAgICAgICAgaWYgKGFsbEFkZHJlc3Nlcy5sZW5ndGggPiAxKSB7CisKKyAgICAgICAgICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyB0aGVBZGRyZXNzID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKAorICAgICAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIFN1cHBvcnRfUG9ydE1hbmFnZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldE5leHRQb3J0KCkpOworICAgICAgICAgICAgICAgIFNlcnZlclNvY2tldCBzZXJ2ZXJTb2NrZXQgPSBuZXcgU2VydmVyU29ja2V0KCk7CisgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0LmJpbmQodGhlQWRkcmVzcyk7CisKKyAgICAgICAgICAgICAgICAvLyB0cnkgdG8gYmluZCB0byBwb3J0IGFkZHJlc3MgdGhhdCBpcyBhbHJlYWR5IGluIHVzZSB3aXRoCisgICAgICAgICAgICAgICAgLy8gcmV1c2VBZGRyZXNzID0gZmFsc2UuCisgICAgICAgICAgICAgICAgLy8gT24gd2luZG93cyBwbGF0Zm9ybXMgdGhlIGJpbmQgaXMgYWxsb3dlZCBldmVuIHRoZW4KKyAgICAgICAgICAgICAgICAvLyByZVVzZUFkZHJlc3MgaXMgZmFsc2UgKE9OTFkgSUYgQk9USCBTT0NLRVRTCisgICAgICAgICAgICAgICAgLy8gQVJFIElQVjQgU29ja2V0cykgc28gb3VyIHRlc3QgdXNlcyB0aGUgcGxhdGZvcm0gdG8gZGV0ZXJtaW5lCisgICAgICAgICAgICAgICAgLy8gd2hhdCB0aGUgZXhwZWN0ZWQgcmVzdWx0IGlzLiBJdCBzZWVtcyB0aGF0IG9uIGxpbnV4CisgICAgICAgICAgICAgICAgLy8gcGxhdGZvcm1zIHdlIGFsc28gZG9uJ3QgZ2V0IGFuIGV4Y2VwdGlvbi4KKyAgICAgICAgICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyB0aGVMb2NhbEFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoCisgICAgICAgICAgICAgICAgICAgICAgICAoSW5ldEFkZHJlc3MpIGFsbEFkZHJlc3Nlc1sxXSwgU3VwcG9ydF9Qb3J0TWFuYWdlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TmV4dFBvcnQoKSk7CisgICAgICAgICAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgdGhlT3RoZXJMb2NhbEFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoCisgICAgICAgICAgICAgICAgICAgICAgICAoSW5ldEFkZHJlc3MpIGFsbEFkZHJlc3Nlc1swXSwgdGhlTG9jYWxBZGRyZXNzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRQb3J0KCkpOworICAgICAgICAgICAgICAgIFNvY2tldCB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgICAgICAgICAgdGhlU29ja2V0LnNldFJldXNlQWRkcmVzcyhmYWxzZSk7CisgICAgICAgICAgICAgICAgdGhlU29ja2V0LmJpbmQodGhlTG9jYWxBZGRyZXNzKTsKKyAgICAgICAgICAgICAgICBTb2NrZXQgdGhlU29ja2V0MiA9IG51bGw7CisgICAgICAgICAgICAgICAgU3RyaW5nIHBsYXRmb3JtID0gU3lzdGVtLmdldFByb3BlcnR5KCJvcy5uYW1lIik7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0MiA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0Mi5zZXRSZXVzZUFkZHJlc3MoZmFsc2UpOworICAgICAgICAgICAgICAgICAgICB0aGVTb2NrZXQyLmJpbmQodGhlT3RoZXJMb2NhbEFkZHJlc3MpOworCisgICAgICAgICAgICAgICAgICAgIGlmICgoIXBsYXRmb3JtLnN0YXJ0c1dpdGgoIkxpbnV4IikpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKCghcGxhdGZvcm0uc3RhcnRzV2l0aCgiV2luZG93cyIpKSB8fAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciB3aW5kb3dzIHdlIGRvbid0IGdldCBhbiBleGNlcHRpb24gd2l0aAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNldHJldXNlIHNldCB0byBmYWxzZSB1bmxlc3Mgb25lIG9mIHRoZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFkZHJlc3NlcyB3ZSBiaW5kIHRvIGlzIGFuIElQdjYgYWRkcmVzcyBhbmQgd2UKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhcmUgdGhlcmVmb3JlIHVzaW5nIHRoZSBJUHY2IHN0YWNrLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICEoKCgoSW5ldEFkZHJlc3MpIGFsbEFkZHJlc3Nlc1swXSkgaW5zdGFuY2VvZiBJbmV0NEFkZHJlc3MpICYmICgoKEluZXRBZGRyZXNzKSBhbGxBZGRyZXNzZXNbMV0pIGluc3RhbmNlb2YgSW5ldDRBZGRyZXNzKSkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKCJObyBleGNlcHRpb24gd2hlbiBzZXRSZXVzZUFkZHJlc3MgaXMgZmFsc2UgYW5kIHdlIGJpbmQ6IgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHRoZUxvY2FsQWRkcmVzcy50b1N0cmluZygpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIjoiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdGhlT3RoZXJMb2NhbEFkZHJlc3MudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoKHBsYXRmb3JtLnN0YXJ0c1dpdGgoIkxpbnV4IikpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKChwbGF0Zm9ybS5zdGFydHNXaXRoKCJXaW5kb3dzIikpICYmICgoKChJbmV0QWRkcmVzcykgYWxsQWRkcmVzc2VzWzBdKSBpbnN0YW5jZW9mIEluZXQ0QWRkcmVzcykgJiYgKCgoSW5ldEFkZHJlc3MpIGFsbEFkZHJlc3Nlc1sxXSkgaW5zdGFuY2VvZiBJbmV0NEFkZHJlc3MpKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoIkdvdCB1bmV4cGVjdGVkIGV4Y2VwdGlvbiB3aGVuIGJpbmRpbmcgd2l0aCBzZXRSZXVzZUFkZHJlc3MgZmFsc2Ugb24gd2luZG93cyBwbGF0Zm9ybToiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdGhlQWRkcmVzcy50b1N0cmluZygpICsgIjoiICsgZXgudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgdGhlU29ja2V0Mi5jbG9zZSgpOworCisgICAgICAgICAgICAgICAgLy8gdHJ5IHRvIGJpbmQgdG8gcG9ydCB0aGF0IGlzIGFscmVhZHkgaW4gdXNlIHdpdGggcmV1c2VBZGRyZXNzCisgICAgICAgICAgICAgICAgLy8gPSB0cnVlCisgICAgICAgICAgICAgICAgdGhlTG9jYWxBZGRyZXNzID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKAorICAgICAgICAgICAgICAgICAgICAgICAgKEluZXRBZGRyZXNzKSBhbGxBZGRyZXNzZXNbMF0sIFN1cHBvcnRfUG9ydE1hbmFnZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldE5leHRQb3J0KCkpOworICAgICAgICAgICAgICAgIHRoZU90aGVyTG9jYWxBZGRyZXNzID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKAorICAgICAgICAgICAgICAgICAgICAgICAgKEluZXRBZGRyZXNzKSBhbGxBZGRyZXNzZXNbMV0sIHRoZUxvY2FsQWRkcmVzcworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0UG9ydCgpKTsKKworICAgICAgICAgICAgICAgIHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgICAgICB0aGVTb2NrZXQuc2V0UmV1c2VBZGRyZXNzKHRydWUpOworICAgICAgICAgICAgICAgIHRoZVNvY2tldC5iaW5kKHRoZUxvY2FsQWRkcmVzcyk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0MiA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0Mi5zZXRSZXVzZUFkZHJlc3ModHJ1ZSk7CisgICAgICAgICAgICAgICAgICAgIHRoZVNvY2tldDIuYmluZCh0aGVPdGhlckxvY2FsQWRkcmVzcyk7CisgICAgICAgICAgICAgICAgICAgIHRoZVNvY2tldDIuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3aGVuIHNldFJldXNlQWRkcmVzcyBpcyB0cnVlIGFuZCB3ZSBiaW5kIDoiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBleC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0LmNsb3NlKCk7CisKKyAgICAgICAgICAgICAgICAvLyB0cnkgd2l0aCBkZWZhdWx0IGJlaGF2aW9yIHdoaWNoIHNob3VsZCBiZSB0aGUgc2FtZSBvbiBhbGwKKyAgICAgICAgICAgICAgICAvLyBwbGF0Zm9ybXMKKyAgICAgICAgICAgICAgICB0aGVMb2NhbEFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoCisgICAgICAgICAgICAgICAgICAgICAgICAoSW5ldEFkZHJlc3MpIGFsbEFkZHJlc3Nlc1swXSwgU3VwcG9ydF9Qb3J0TWFuYWdlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TmV4dFBvcnQoKSk7CisgICAgICAgICAgICAgICAgdGhlT3RoZXJMb2NhbEFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoCisgICAgICAgICAgICAgICAgICAgICAgICAoSW5ldEFkZHJlc3MpIGFsbEFkZHJlc3Nlc1sxXSwgdGhlTG9jYWxBZGRyZXNzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRQb3J0KCkpOworCisgICAgICAgICAgICAgICAgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICAgICAgICAgIHRoZVNvY2tldC5iaW5kKHRoZUxvY2FsQWRkcmVzcyk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0MiA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0Mi5iaW5kKHRoZU90aGVyTG9jYWxBZGRyZXNzKTsKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0Mi5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICBpZiAoKCFwbGF0Zm9ybS5zdGFydHNXaXRoKCJMaW51eCIpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmICgoIXBsYXRmb3JtLnN0YXJ0c1dpdGgoIldpbmRvd3MiKSkgfHwgISgoKChJbmV0QWRkcmVzcykgYWxsQWRkcmVzc2VzWzBdKSBpbnN0YW5jZW9mIEluZXQ0QWRkcmVzcykgJiYgKCgoSW5ldEFkZHJlc3MpIGFsbEFkZHJlc3Nlc1sxXSkgaW5zdGFuY2VvZiBJbmV0NEFkZHJlc3MpKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoIk5vIGV4Y2VwdGlvbiB3aGVuIHNldFJldXNlQWRkcmVzcyBpcyBkZWZhdWx0IGFuZCB3ZSBiaW5kOiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyB0aGVMb2NhbEFkZHJlc3MudG9TdHJpbmcoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICI6IgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHRoZU90aGVyTG9jYWxBZGRyZXNzLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKChwbGF0Zm9ybS5zdGFydHNXaXRoKCJMaW51eCIpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICgocGxhdGZvcm0uc3RhcnRzV2l0aCgiV2luZG93cyIpKSAmJiAoKCgoSW5ldEFkZHJlc3MpIGFsbEFkZHJlc3Nlc1swXSkgaW5zdGFuY2VvZiBJbmV0NEFkZHJlc3MpICYmICgoKEluZXRBZGRyZXNzKSBhbGxBZGRyZXNzZXNbMV0pIGluc3RhbmNlb2YgSW5ldDRBZGRyZXNzKSkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKCJHb3QgdW5leHBlY3RlZCBleGNlcHRpb24gd2hlbiBiaW5kaW5nIHdpdGggc2V0UmV1c2VBZGRyZXNzIGRlZmF1bHQgb24gd2luZG93cyBwbGF0Zm9ybToiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdGhlQWRkcmVzcy50b1N0cmluZygpICsgIjoiICsgZXgudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0LmNsb3NlKCk7CisKKyAgICAgICAgICAgICAgICBlbnN1cmVFeGNlcHRpb25UaHJvd25JZk9wdGlvbklzVW5zdXBwb3J0ZWRPbk9TKFNPX1JFVVNFQUREUik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBoYW5kbGVFeGNlcHRpb24oZSwgU09fUkVVU0VBRERSKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTb2NrZXQgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuc2V0UmV1c2VBZGRyZXNzKHRydWUpOworICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFNvY2tldEV4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFJldXNlQWRkcmVzcygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldCB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuc2V0UmV1c2VBZGRyZXNzKHRydWUpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0UmV1c2VBZGRyZXNzIGZhbHNlIHdoZW4gaXQgc2hvdWxkIGJlIHRydWUiLAorICAgICAgICAgICAgICAgICAgICB0aGVTb2NrZXQuZ2V0UmV1c2VBZGRyZXNzKCkpOworICAgICAgICAgICAgdGhlU29ja2V0LnNldFJldXNlQWRkcmVzcyhmYWxzZSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSgiZ2V0UmV1c2VBZGRyZXNzIHRydWUgd2hlbiBpdCBzaG91bGQgYmUgRmFsc2UiLAorICAgICAgICAgICAgICAgICAgICB0aGVTb2NrZXQuZ2V0UmV1c2VBZGRyZXNzKCkpOworICAgICAgICAgICAgZW5zdXJlRXhjZXB0aW9uVGhyb3duSWZPcHRpb25Jc1Vuc3VwcG9ydGVkT25PUyhTT19SRVVTRUFERFIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaGFuZGxlRXhjZXB0aW9uKGUsIFNPX1JFVVNFQUREUik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU29ja2V0IG5ld1NvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgIG5ld1NvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBuZXdTb2NrZXQuZ2V0UmV1c2VBZGRyZXNzKCk7CisgICAgICAgICAgICAgICAgZmFpbCgiU29ja2V0RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICAgICAgfSBjYXRjaChTb2NrZXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldE9PQklubGluZVooKSB7CisgICAgICAgIC8vIG1vc3RseSB0ZXN0ZWQgaW4gZ2V0T09CSW5saW5lLiBKdXN0IHNldCB0byBtYWtlIHN1cmUgY2FsbCB3b3JrcyBvaworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEluZXRTb2NrZXRBZGRyZXNzKEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLAorICAgICAgICAgICAgICAgICAgICBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCkpOworICAgICAgICAgICAgU29ja2V0IHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5zZXRPT0JJbmxpbmUodHJ1ZSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJleHBlY3RlZCBPT0JJbGluZSB0byBiZSB0cnVlIiwgdGhlU29ja2V0LmdldE9PQklubGluZSgpKTsKKyAgICAgICAgICAgIGVuc3VyZUV4Y2VwdGlvblRocm93bklmT3B0aW9uSXNVbnN1cHBvcnRlZE9uT1MoU09fT09CSU5MSU5FKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGhhbmRsZUV4Y2VwdGlvbihlLCBTT19PT0JJTkxJTkUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldCB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5zZXRPT0JJbmxpbmUodHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU29ja2V0RXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0T09CSW5saW5lKCkgeworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgICAgIFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKSk7CisgICAgICAgICAgICBTb2NrZXQgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworCisgICAgICAgICAgICAvLyB2YWxpZGF0ZSB0aGF0IHZhbHVlIHJlZmxlY3RzIHdoYXQgd2Ugc2V0IGl0IHRvIHRydWUgYWZ0ZXIgdHJ1ZSwKKyAgICAgICAgICAgIC8vIGZhbHNlIGFmdGVyIGZhbHNlIGFuZCBmYWxzZSBhZnRlciBmYWxzZSBmYWxzZQorICAgICAgICAgICAgdGhlU29ja2V0LnNldE9PQklubGluZSh0cnVlKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImV4cGVjdGVkIE9PQklsaW5lIHRvIGJlIHRydWUiLCB0aGVTb2NrZXQuZ2V0T09CSW5saW5lKCkpOworICAgICAgICAgICAgdGhlU29ja2V0LnNldE9PQklubGluZShmYWxzZSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSgiZXhwZWN0ZWQgT09CSWxpbmUgdG8gYmUgdHJ1ZSIsIHRoZVNvY2tldAorICAgICAgICAgICAgICAgICAgICAuZ2V0T09CSW5saW5lKCkpOworICAgICAgICAgICAgdGhlU29ja2V0LnNldE9PQklubGluZShmYWxzZSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSgiZXhwZWN0ZWQgT09CSWxpbmUgdG8gYmUgdHJ1ZSIsIHRoZVNvY2tldAorICAgICAgICAgICAgICAgICAgICAuZ2V0T09CSW5saW5lKCkpOworICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRoZVNvY2tldC5nZXRPT0JJbmxpbmUoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTb2NrZXRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgICAgICB9IGNhdGNoKFNvY2tldEV4Y2VwdGlvbiBzZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVuc3VyZUV4Y2VwdGlvblRocm93bklmT3B0aW9uSXNVbnN1cHBvcnRlZE9uT1MoU09fT09CSU5MSU5FKTsKKworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaGFuZGxlRXhjZXB0aW9uKGUsIFNPX09PQklOTElORSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFRyYWZmaWNDbGFzc0koKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgSVBUT1NfTE9XQ09TVCA9IDB4MjsKKyAgICAgICAgICAgIGludCBJUFRPU19USFJPVUdIUFVUID0gMHg4OworCisgICAgICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgICAgIFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKSk7CisgICAgICAgICAgICBTb2NrZXQgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworCisgICAgICAgICAgICAvLyB2YWxpZGF0ZSB0aGF0IHZhbHVlIHNldCBtdXN0IGJlIGJldHdlZW4gMCBhbmQgMjU1CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRoZVNvY2tldC5zZXRUcmFmZmljQ2xhc3MoMjU2KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJObyBleGNlcHRpb24gd2FzIHRocm93biB3aGVuIHRyYWZmaWMgY2xhc3Mgc2V0IHRvIDI1NiIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0aGVTb2NrZXQuc2V0VHJhZmZpY0NsYXNzKC0xKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJObyBleGNlcHRpb24gd2FzIHRocm93biB3aGVuIHRyYWZmaWMgY2xhc3Mgc2V0IHRvIC0xIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBub3cgdmFsaWRhdGUgdGhhdCB3ZSBjYW4gc2V0IGl0IHRvIHNvbWUgZ29vZCB2YWx1ZXMKKyAgICAgICAgICAgIHRoZVNvY2tldC5zZXRUcmFmZmljQ2xhc3MoSVBUT1NfTE9XQ09TVCk7CisgICAgICAgICAgICB0aGVTb2NrZXQuc2V0VHJhZmZpY0NsYXNzKElQVE9TX1RIUk9VR0hQVVQpOworICAgICAgICAgICAgZW5zdXJlRXhjZXB0aW9uVGhyb3duSWZPcHRpb25Jc1Vuc3VwcG9ydGVkT25PUyhJUF9UT1MpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaGFuZGxlRXhjZXB0aW9uKGUsIElQX1RPUyk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU29ja2V0IHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgdGhlU29ja2V0LnNldFRyYWZmaWNDbGFzcygwKTsKKyAgICAgICAgICAgIGZhaWwoIlNvY2tldEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChTb2NrZXRFeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRUcmFmZmljQ2xhc3MoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgICAgIFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKSk7CisgICAgICAgICAgICBTb2NrZXQgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogd2UgY2Fubm90IGFjdHVhbGx5IGNoZWNrIHRoYXQgdGhlIHZhbHVlcyBhcmUgc2V0IGFzIGlmIGEgcGxhdGZvcm0KKyAgICAgICAgICAgICAqIGRvZXMgbm90IHN1cHBvcnQgdGhlIG9wdGlvbiB0aGVuIGl0IG1heSBjb21lIGJhY2sgdW5zZXQgZXZlbgorICAgICAgICAgICAgICogdGhvdWdoIHdlIHNldCBpdCBzbyBqdXN0IGdldCB0aGUgdmFsdWUgdG8gbWFrZSBzdXJlIHdlIGNhbiBnZXQgaXQKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaW50IHRyYWZmaWNDbGFzcyA9IHRoZVNvY2tldC5nZXRUcmFmZmljQ2xhc3MoKTsKKyAgICAgICAgICAgIGVuc3VyZUV4Y2VwdGlvblRocm93bklmT3B0aW9uSXNVbnN1cHBvcnRlZE9uT1MoSVBfVE9TKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGhhbmRsZUV4Y2VwdGlvbihlLCBJUF9UT1MpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDaGFubmVsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydE51bGwobmV3IFNvY2tldCgpLmdldENoYW5uZWwoKSk7CisKKyAgICAgICAgU29ja2V0Q2hhbm5lbCBjaGFubmVsID0gU29ja2V0Q2hhbm5lbC5vcGVuKCk7CisgICAgICAgIFNvY2tldCBzb2NrZXQgPSBjaGFubmVsLnNvY2tldCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoY2hhbm5lbCwgc29ja2V0LmdldENoYW5uZWwoKSk7CisgICAgICAgIHNvY2tldC5jbG9zZSgpOworICAgICAgICBjaGFubmVsLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZW5kVXJnZW50RGF0YUkoKSB7CisKKyAgICAgICAgLy8gU29tZSBwbGF0Zm9ybXMgbWF5IG5vdCBzdXBwb3J0IHVyZ2VudCBkYXRhIGluIHRoaXMgY2FzZSB3ZSB3aWxsIG5vdAorICAgICAgICAvLyBydW4gdGhlc2UgdGVzdHMuIEZvciBub3cgcnVuIG9uIGFsbCBwbGF0Zm9ybXMgdW50aWwgd2UgZmluZCB0aG9zZQorICAgICAgICAvLyB0aGF0IGRvIG5vdCBzdXBwb3J0IHVyZ2VudCBkYXRhCisgICAgICAgIFN0cmluZyBwbGF0Zm9ybSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgib3MubmFtZSIpOworICAgICAgICBpZiAoIXBsYXRmb3JtLmVxdWFscygiRHVtbXkiKSkgeworICAgICAgICAgICAgLy8gdmFsaWRhdGUgdGhhdCB3aGVuIE9PQklubGluZSBpcyBmYWxzZSB0aGF0IGFueSB1cmdlbnQgZGF0YQorICAgICAgICAgICAgLy8gaXMgc2lsZW50bHkgaWdub3JlZAorICAgICAgICAgICAgU3RyaW5nIHVyZ2VudERhdGEgPSAiVSI7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIHRoZUFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoCisgICAgICAgICAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgU3VwcG9ydF9Qb3J0TWFuYWdlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TmV4dFBvcnQoKSk7CisgICAgICAgICAgICAgICAgU29ja2V0IHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgICAgICBTZXJ2ZXJTb2NrZXQgc2VydmVyU29ja2V0ID0gbmV3IFNlcnZlclNvY2tldCgpOworICAgICAgICAgICAgICAgIHNlcnZlclNvY2tldC5iaW5kKHRoZUFkZHJlc3MpOworICAgICAgICAgICAgICAgIHRoZVNvY2tldC5jb25uZWN0KHRoZUFkZHJlc3MpOworICAgICAgICAgICAgICAgIFNvY2tldCBzZXJ2U29jayA9IHNlcnZlclNvY2tldC5hY2NlcHQoKTsKKyAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSB0aGVJbnB1dCA9IHRoZVNvY2tldC5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgIE91dHB1dFN0cmVhbSB0aGVPdXRwdXQgPSBzZXJ2U29jay5nZXRPdXRwdXRTdHJlYW0oKTsKKworICAgICAgICAgICAgICAgIC8vIHNlbmQgdGhlIHJlZ3VsYXIgZGF0YQorICAgICAgICAgICAgICAgIFN0cmluZyBzZW5kU3RyaW5nID0gbmV3IFN0cmluZygiVGVzdCIpOworICAgICAgICAgICAgICAgIHRoZU91dHB1dC53cml0ZShzZW5kU3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICAgICAgICAgIHRoZU91dHB1dC5mbHVzaCgpOworCisgICAgICAgICAgICAgICAgLy8gc2VuZCB0aGUgdXJnZW50IGRhdGEgd2hpY2ggc2hvdWxkIG5vdCBiZSByZWNlaXZlZAorICAgICAgICAgICAgICAgIHRoZVNvY2tldC5zZXRPT0JJbmxpbmUoZmFsc2UpOworICAgICAgICAgICAgICAgIHNlcnZTb2NrLnNlbmRVcmdlbnREYXRhKHVyZ2VudERhdGEuZ2V0Qnl0ZXMoKVswXSk7CisgICAgICAgICAgICAgICAgdGhlT3V0cHV0LndyaXRlKHNlbmRTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICAgICAgdGhlT3V0cHV0LmZsdXNoKCk7CisKKyAgICAgICAgICAgICAgICAvLyBnaXZlIHRoaW5ncyBzb21lIHRpbWUgdG8gc2V0dGxlCisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworCisgICAgICAgICAgICAgICAgaW50IHRvdGFsQnl0ZXNSZWFkID0gMDsKKyAgICAgICAgICAgICAgICBieXRlW10gbXlCeXRlcyA9IG5ldyBieXRlWzEwMF07CisgICAgICAgICAgICAgICAgd2hpbGUgKHRoZUlucHV0LmF2YWlsYWJsZSgpID4gMCkgeworICAgICAgICAgICAgICAgICAgICBpbnQgYnl0ZXNSZWFkID0gdGhlSW5wdXQucmVhZChteUJ5dGVzLCB0b3RhbEJ5dGVzUmVhZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBteUJ5dGVzLmxlbmd0aCAtIHRvdGFsQnl0ZXNSZWFkKTsKKyAgICAgICAgICAgICAgICAgICAgdG90YWxCeXRlc1JlYWQgPSB0b3RhbEJ5dGVzUmVhZCArIGJ5dGVzUmVhZDsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBTdHJpbmcgcmVjZWl2ZWRTdHJpbmcgPSBuZXcgU3RyaW5nKG15Qnl0ZXMsIDAsIHRvdGFsQnl0ZXNSZWFkKTsKKyAgICAgICAgICAgICAgICAvL2Fzc2VydFRydWUoIlVyZ2VudCBEYXRhIHNlZW1zIHRvIGhhdmUgYmVlbiByZWNlaXZlZDoiCisgICAgICAgICAgICAgICAgLy8gICAgICAgICsgcmVjZWl2ZWRTdHJpbmcgKyAiOiIgKyBzZW5kU3RyaW5nLCByZWNlaXZlZFN0cmluZworICAgICAgICAgICAgICAgIC8vICAgICAgICAuZXF1YWxzKHNlbmRTdHJpbmcgKyBzZW5kU3RyaW5nKSk7CisKKyAgICAgICAgICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQuY2xvc2UoKTsKKworICAgICAgICAgICAgICAgIC8vIG5vdyB2YWxpZGF0ZSB0aGF0IHVyZ2VudCBkYXRhIGlzIHJlY2VpdmVkIGFzIGV4cGVjdGVkLiBFeHBlY3QKKyAgICAgICAgICAgICAgICAvLyB0aGF0IGl0IHNob3VsZCBiZSBiZXR3ZWVuIHRoZSB0d28gd3JpdGVzLgorICAgICAgICAgICAgICAgIHRoZUFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgICAgICAgICBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCkpOworICAgICAgICAgICAgICAgIHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQgPSBuZXcgU2VydmVyU29ja2V0KCk7CisgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0LmJpbmQodGhlQWRkcmVzcyk7CisgICAgICAgICAgICAgICAgdGhlU29ja2V0LmNvbm5lY3QodGhlQWRkcmVzcyk7CisgICAgICAgICAgICAgICAgc2VydlNvY2sgPSBzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgICAgICAgICAgdGhlSW5wdXQgPSB0aGVTb2NrZXQuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgICAgICAgICB0aGVPdXRwdXQgPSBzZXJ2U29jay5nZXRPdXRwdXRTdHJlYW0oKTsKKworICAgICAgICAgICAgICAgIC8vIHNlbmQgdGhlIHJlZ3VsYXIgZGF0YQorICAgICAgICAgICAgICAgIHNlbmRTdHJpbmcgPSBuZXcgU3RyaW5nKCJUZXN0IC0gVXJnZW50IERhdGEiKTsKKyAgICAgICAgICAgICAgICB0aGVPdXRwdXQud3JpdGUoc2VuZFN0cmluZy5nZXRCeXRlcygpKTsKKyAgICAgICAgICAgICAgICB0aGVPdXRwdXQuZmx1c2goKTsKKworICAgICAgICAgICAgICAgIC8vIHNlbmQgdGhlIHVyZ2VudCBkYXRhIHdoaWNoIHNob3VsZCBiZSByZWNlaXZlZAorICAgICAgICAgICAgICAgIHRoZVNvY2tldC5zZXRPT0JJbmxpbmUodHJ1ZSk7CisgICAgICAgICAgICAgICAgc2VydlNvY2suc2VuZFVyZ2VudERhdGEodXJnZW50RGF0YS5nZXRCeXRlcygpWzBdKTsKKworICAgICAgICAgICAgICAgIHRoZU91dHB1dC53cml0ZShzZW5kU3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICAgICAgICAgIHRoZU91dHB1dC5mbHVzaCgpOworCisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworCisgICAgICAgICAgICAgICAgdG90YWxCeXRlc1JlYWQgPSAwOworICAgICAgICAgICAgICAgIG15Qnl0ZXMgPSBuZXcgYnl0ZVsxMDBdOworICAgICAgICAgICAgICAgIHdoaWxlICh0aGVJbnB1dC5hdmFpbGFibGUoKSA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGJ5dGVzUmVhZCA9IHRoZUlucHV0LnJlYWQobXlCeXRlcywgdG90YWxCeXRlc1JlYWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXlCeXRlcy5sZW5ndGggLSB0b3RhbEJ5dGVzUmVhZCk7CisgICAgICAgICAgICAgICAgICAgIHRvdGFsQnl0ZXNSZWFkID0gdG90YWxCeXRlc1JlYWQgKyBieXRlc1JlYWQ7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcmVjZWl2ZWRTdHJpbmcgPSBuZXcgU3RyaW5nKG15Qnl0ZXMsIDAsIHRvdGFsQnl0ZXNSZWFkKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJVcmdlbnQgRGF0YSB3YXMgbm90IHJlY2VpdmVkIHdpdGggb25lIHVyZ2VudCBieXRlOiIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgcmVjZWl2ZWRTdHJpbmcgKyAiOiIgKyBzZW5kU3RyaW5nICsgdXJnZW50RGF0YQorICAgICAgICAgICAgICAgICAgICAgICAgKyBzZW5kU3RyaW5nLCByZWNlaXZlZFN0cmluZy5lcXVhbHMoc2VuZFN0cmluZworICAgICAgICAgICAgICAgICAgICAgICAgKyB1cmdlbnREYXRhICsgc2VuZFN0cmluZykpOworCisgICAgICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0LmNsb3NlKCk7CisKKyAgICAgICAgICAgICAgICAvLyBub3cgdGVzdCBjYXNlIHdoZXJlIHdlIHRyeSB0byBzZW5kIHR3byB1cmdlbnQgYnl0ZXMuCisgICAgICAgICAgICAgICAgdGhlQWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKSk7CisgICAgICAgICAgICAgICAgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICAgICAgICAgIHNlcnZlclNvY2tldCA9IG5ldyBTZXJ2ZXJTb2NrZXQoKTsKKyAgICAgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQuYmluZCh0aGVBZGRyZXNzKTsKKyAgICAgICAgICAgICAgICB0aGVTb2NrZXQuY29ubmVjdCh0aGVBZGRyZXNzKTsKKyAgICAgICAgICAgICAgICBzZXJ2U29jayA9IHNlcnZlclNvY2tldC5hY2NlcHQoKTsKKyAgICAgICAgICAgICAgICB0aGVJbnB1dCA9IHRoZVNvY2tldC5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgIHRoZU91dHB1dCA9IHNlcnZTb2NrLmdldE91dHB1dFN0cmVhbSgpOworCisgICAgICAgICAgICAgICAgLy8gc2VuZCB0aGUgcmVndWxhciBkYXRhCisgICAgICAgICAgICAgICAgc2VuZFN0cmluZyA9IG5ldyBTdHJpbmcoIlRlc3QgLSBVcmdlbnQgRGF0YSIpOworICAgICAgICAgICAgICAgIHRoZU91dHB1dC53cml0ZShzZW5kU3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICAgICAgICAgIHRoZU91dHB1dC5mbHVzaCgpOworCisgICAgICAgICAgICAgICAgLy8gc2VuZCB0aGUgdXJnZW50IGRhdGEgd2hpY2ggc2hvdWxkIG5vdCBiZSByZWNlaXZlZAorICAgICAgICAgICAgICAgIHRoZVNvY2tldC5zZXRPT0JJbmxpbmUodHJ1ZSk7CisgICAgICAgICAgICAgICAgc2VydlNvY2suc2VuZFVyZ2VudERhdGEodXJnZW50RGF0YS5nZXRCeXRlcygpWzBdKTsKKyAgICAgICAgICAgICAgICBzZXJ2U29jay5zZW5kVXJnZW50RGF0YSh1cmdlbnREYXRhLmdldEJ5dGVzKClbMF0pOworCisgICAgICAgICAgICAgICAgdGhlT3V0cHV0LndyaXRlKHNlbmRTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICAgICAgdGhlT3V0cHV0LmZsdXNoKCk7CisKKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisKKyAgICAgICAgICAgICAgICB0b3RhbEJ5dGVzUmVhZCA9IDA7CisgICAgICAgICAgICAgICAgbXlCeXRlcyA9IG5ldyBieXRlWzEwMF07CisgICAgICAgICAgICAgICAgd2hpbGUgKHRoZUlucHV0LmF2YWlsYWJsZSgpID4gMCkgeworICAgICAgICAgICAgICAgICAgICBpbnQgYnl0ZXNSZWFkID0gdGhlSW5wdXQucmVhZChteUJ5dGVzLCB0b3RhbEJ5dGVzUmVhZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBteUJ5dGVzLmxlbmd0aCAtIHRvdGFsQnl0ZXNSZWFkKTsKKyAgICAgICAgICAgICAgICAgICAgdG90YWxCeXRlc1JlYWQgPSB0b3RhbEJ5dGVzUmVhZCArIGJ5dGVzUmVhZDsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICByZWNlaXZlZFN0cmluZyA9IG5ldyBTdHJpbmcobXlCeXRlcywgMCwgdG90YWxCeXRlc1JlYWQpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICAgICAiRGlkIG5vdCBnZXQgcmlnaHQgYnl0ZSBvZiB1cmdlbnQgZGF0YSB3aGVuIHR3byBzZW50OiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyByZWNlaXZlZFN0cmluZyArICI6IiArIHNlbmRTdHJpbmcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyB1cmdlbnREYXRhICsgdXJnZW50RGF0YSArIHNlbmRTdHJpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZlZFN0cmluZy5lcXVhbHMoc2VuZFN0cmluZyArIHVyZ2VudERhdGEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyB1cmdlbnREYXRhICsgc2VuZFN0cmluZykpOworCisgICAgICAgICAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0LmNsb3NlKCk7CisKKyAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAqIFRPRE8gOiBUaGVzZSBkbyBub3QgY3VycmVudGx5IHBhc3Mgb24gWFAgU1AyIGFuZCBTZXJ2ZXIgMjAwMworICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIGlmICghcGxhdGZvcm0uc3RhcnRzV2l0aCgiV2luZG93cyIpKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIG5vdyB0ZXN0IHRoZSBjYXNlIHdlcmUgd2Ugc2VuZCB0dXJuIHRoZSBPT0JJbmxpbmUgb24vb2ZmCisgICAgICAgICAgICAgICAgICAgIHRoZUFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TG9jYWxIb3N0KCksIFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKSk7CisgICAgICAgICAgICAgICAgICAgIHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0ID0gbmV3IFNlcnZlclNvY2tldCgpOworICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQuYmluZCh0aGVBZGRyZXNzKTsKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0LmNvbm5lY3QodGhlQWRkcmVzcyk7CisgICAgICAgICAgICAgICAgICAgIHNlcnZTb2NrID0gc2VydmVyU29ja2V0LmFjY2VwdCgpOworICAgICAgICAgICAgICAgICAgICB0aGVJbnB1dCA9IHRoZVNvY2tldC5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgICAgICB0aGVPdXRwdXQgPSBzZXJ2U29jay5nZXRPdXRwdXRTdHJlYW0oKTsKKworICAgICAgICAgICAgICAgICAgICAvLyBzZW5kIHRoZSByZWd1bGFyIGRhdGEKKyAgICAgICAgICAgICAgICAgICAgc2VuZFN0cmluZyA9IG5ldyBTdHJpbmcoIlRlc3QgLSBVcmdlbnQgRGF0YSIpOworICAgICAgICAgICAgICAgICAgICB0aGVPdXRwdXQud3JpdGUoc2VuZFN0cmluZy5nZXRCeXRlcygpKTsKKyAgICAgICAgICAgICAgICAgICAgdGhlT3V0cHV0LmZsdXNoKCk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gc2VuZCB0aGUgdXJnZW50IGRhdGEgd2hpY2ggc2hvdWxkIGJlIHJlY2VpdmVkCisgICAgICAgICAgICAgICAgICAgIHRoZVNvY2tldC5zZXRPT0JJbmxpbmUodHJ1ZSk7CisgICAgICAgICAgICAgICAgICAgIHNlcnZTb2NrLnNlbmRVcmdlbnREYXRhKHVyZ2VudERhdGEuZ2V0Qnl0ZXMoKVswXSk7CisKKyAgICAgICAgICAgICAgICAgICAgdGhlT3V0cHV0LndyaXRlKHNlbmRTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICAgICAgICAgIHRoZU91dHB1dC5mbHVzaCgpOworCisgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxMDAwKTsKKworICAgICAgICAgICAgICAgICAgICB0b3RhbEJ5dGVzUmVhZCA9IDA7CisgICAgICAgICAgICAgICAgICAgIG15Qnl0ZXMgPSBuZXcgYnl0ZVsxMDBdOworICAgICAgICAgICAgICAgICAgICB3aGlsZSAodGhlSW5wdXQuYXZhaWxhYmxlKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnl0ZXNSZWFkID0gdGhlSW5wdXQucmVhZChteUJ5dGVzLCB0b3RhbEJ5dGVzUmVhZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXlCeXRlcy5sZW5ndGggLSB0b3RhbEJ5dGVzUmVhZCk7CisgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbEJ5dGVzUmVhZCA9IHRvdGFsQnl0ZXNSZWFkICsgYnl0ZXNSZWFkOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZWRTdHJpbmcgPSBuZXcgU3RyaW5nKG15Qnl0ZXMsIDAsIHRvdGFsQnl0ZXNSZWFkKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlkIG5vdCBnZXQgdXJnZW50IGRhdGEgd2hlbiB0dXJuaW5nIG9uL29mZigxKToiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHJlY2VpdmVkU3RyaW5nICsgIjoiICsgc2VuZFN0cmluZworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyB1cmdlbnREYXRhICsgc2VuZFN0cmluZywgcmVjZWl2ZWRTdHJpbmcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoc2VuZFN0cmluZyArIHVyZ2VudERhdGEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzZW5kU3RyaW5nKSk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gc2VuZCB0aGUgcmVndWxhciBkYXRhCisgICAgICAgICAgICAgICAgICAgIHNlbmRTdHJpbmcgPSBuZXcgU3RyaW5nKCJUZXN0IC0gVXJnZW50IERhdGEiKTsKKyAgICAgICAgICAgICAgICAgICAgdGhlT3V0cHV0LndyaXRlKHNlbmRTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICAgICAgICAgIHRoZU91dHB1dC5mbHVzaCgpOworCisgICAgICAgICAgICAgICAgICAgIC8vIHNlbmQgdGhlIHVyZ2VudCBkYXRhIHdoaWNoIHNob3VsZCBub3QgYmUgcmVjZWl2ZWQKKyAgICAgICAgICAgICAgICAgICAgdGhlU29ja2V0LnNldE9PQklubGluZShmYWxzZSk7CisgICAgICAgICAgICAgICAgICAgIHNlcnZTb2NrLnNlbmRVcmdlbnREYXRhKHVyZ2VudERhdGEuZ2V0Qnl0ZXMoKVswXSk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gc2VuZCB0cmFpbGluZyBkYXRhCisgICAgICAgICAgICAgICAgICAgIHRoZU91dHB1dC53cml0ZShzZW5kU3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICAgICAgICAgICAgICB0aGVPdXRwdXQuZmx1c2goKTsKKworICAgICAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisKKyAgICAgICAgICAgICAgICAgICAgdG90YWxCeXRlc1JlYWQgPSAwOworICAgICAgICAgICAgICAgICAgICBteUJ5dGVzID0gbmV3IGJ5dGVbMTAwXTsKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHRoZUlucHV0LmF2YWlsYWJsZSgpID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ5dGVzUmVhZCA9IHRoZUlucHV0LnJlYWQobXlCeXRlcywgdG90YWxCeXRlc1JlYWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15Qnl0ZXMubGVuZ3RoIC0gdG90YWxCeXRlc1JlYWQpOworICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxCeXRlc1JlYWQgPSB0b3RhbEJ5dGVzUmVhZCArIGJ5dGVzUmVhZDsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHJlY2VpdmVkU3RyaW5nID0gbmV3IFN0cmluZyhteUJ5dGVzLCAwLCB0b3RhbEJ5dGVzUmVhZCk7CisgICAgICAgICAgICAgICAgICAgIC8vYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICJHb3QgdW5leHBlY3RlZCBkYXRhIGRhdGEgd2hlbiB0dXJuaW5nIG9uL29mZigyKToiCisgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICsgcmVjZWl2ZWRTdHJpbmcgKyAiOiIgKyBzZW5kU3RyaW5nCisgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgKyBzZW5kU3RyaW5nLCByZWNlaXZlZFN0cmluZworICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAuZXF1YWxzKHNlbmRTdHJpbmcgKyBzZW5kU3RyaW5nKSk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gbm93IHR1cm4gYmFjayBvbiBhbmQgZ2V0IGRhdGEuIEhlcmUgd2UgYWxzbworICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIHByZXZpb3VzbHkgc2VudCBieXRlIG9mIHVyZ2VudCBkYXRhIGFzIGl0IGlzCisgICAgICAgICAgICAgICAgICAgIC8vIHN0aWxsIGluIHRoZSB1cmdlbnQgYnVmZmVyCisKKyAgICAgICAgICAgICAgICAgICAgLy8gc2VuZCB0aGUgcmVndWxhciBkYXRhCisgICAgICAgICAgICAgICAgICAgIHNlbmRTdHJpbmcgPSBuZXcgU3RyaW5nKCJUZXN0IC0gVXJnZW50IERhdGEiKTsKKyAgICAgICAgICAgICAgICAgICAgdGhlT3V0cHV0LndyaXRlKHNlbmRTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICAgICAgICAgIHRoZU91dHB1dC5mbHVzaCgpOworCisgICAgICAgICAgICAgICAgICAgIC8vIHNlbmQgdGhlIHVyZ2VudCBkYXRhIHdoaWNoIHNob3VsZCBiZSByZWNlaXZlZCBhZ2FpbgorICAgICAgICAgICAgICAgICAgICB0aGVTb2NrZXQuc2V0T09CSW5saW5lKHRydWUpOworICAgICAgICAgICAgICAgICAgICBzZXJ2U29jay5zZW5kVXJnZW50RGF0YSh1cmdlbnREYXRhLmdldEJ5dGVzKClbMF0pOworCisgICAgICAgICAgICAgICAgICAgIHRoZU91dHB1dC53cml0ZShzZW5kU3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICAgICAgICAgICAgICB0aGVPdXRwdXQuZmx1c2goKTsKKworICAgICAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisKKyAgICAgICAgICAgICAgICAgICAgdG90YWxCeXRlc1JlYWQgPSAwOworICAgICAgICAgICAgICAgICAgICBteUJ5dGVzID0gbmV3IGJ5dGVbMTAwXTsKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHRoZUlucHV0LmF2YWlsYWJsZSgpID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ5dGVzUmVhZCA9IHRoZUlucHV0LnJlYWQobXlCeXRlcywgdG90YWxCeXRlc1JlYWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15Qnl0ZXMubGVuZ3RoIC0gdG90YWxCeXRlc1JlYWQpOworICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxCeXRlc1JlYWQgPSB0b3RhbEJ5dGVzUmVhZCArIGJ5dGVzUmVhZDsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHJlY2VpdmVkU3RyaW5nID0gbmV3IFN0cmluZyhteUJ5dGVzLCAwLCB0b3RhbEJ5dGVzUmVhZCk7CisgICAgICAgICAgICAgICAgICAgIC8vIGRlcGVuZGluZyBvbiB0aGUgcGxhdGZvcm0gd2UgbWF5IGdldCB0aGUgcHJldmlvdXNseSBzZW50CisgICAgICAgICAgICAgICAgICAgIC8vIHVyZ2VudCBkYXRhIG9yIG5vdCAoZXhhbXBsZXMgd2luZG93cy15ZXMsIExpbnV4LW5vKS4KKyAgICAgICAgICAgICAgICAgICAgLy8gU28gYWNjZXB0IGVpdGhlciBzbyBsb25nIGFzIHdlIGdldCB0aGUgdXJnZW50IGRhdGEgZnJvbQorICAgICAgICAgICAgICAgICAgICAvLyB3aGVuIGl0IHdhcyBvbi4KKyAgICAgICAgICAgICAgICAgICAgLy9hc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgIkRpZCBub3QgZ2V0IHVyZ2VudCBkYXRhIHdoZW4gdHVybmluZyBvbi9vZmYoMykgR09UOiIKKyAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgKyByZWNlaXZlZFN0cmluZyArICI6RXhwZWN0ZWQiICsgdXJnZW50RGF0YQorICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICArIHNlbmRTdHJpbmcgKyB1cmdlbnREYXRhICsgc2VuZFN0cmluZworICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICArICI6T1I6IiArIHNlbmRTdHJpbmcgKyB1cmdlbnREYXRhCisgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICsgc2VuZFN0cmluZywKKyAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgIChyZWNlaXZlZFN0cmluZy5lcXVhbHModXJnZW50RGF0YSArIHNlbmRTdHJpbmcKKyAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgKyB1cmdlbnREYXRhICsgc2VuZFN0cmluZykgfHwgcmVjZWl2ZWRTdHJpbmcKKyAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgLmVxdWFscyhzZW5kU3RyaW5nICsgdXJnZW50RGF0YQorICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICsgc2VuZFN0cmluZykpKTsKKworICAgICAgICAgICAgICAgICAgICB0aGVTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gbm93IHRlc3QgdGhlIGNhc2Ugd2hlcmUgdGhlcmUgaXMgb25seSB1cmdlbnQgZGF0YQorICAgICAgICAgICAgICAgIHRoZUFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgICAgICAgICBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCkpOworICAgICAgICAgICAgICAgIHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQgPSBuZXcgU2VydmVyU29ja2V0KCk7CisgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0LmJpbmQodGhlQWRkcmVzcyk7CisgICAgICAgICAgICAgICAgdGhlU29ja2V0LmNvbm5lY3QodGhlQWRkcmVzcyk7CisgICAgICAgICAgICAgICAgc2VydlNvY2sgPSBzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgICAgICAgICAgdGhlSW5wdXQgPSB0aGVTb2NrZXQuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgICAgICAgICB0aGVPdXRwdXQgPSBzZXJ2U29jay5nZXRPdXRwdXRTdHJlYW0oKTsKKworICAgICAgICAgICAgICAgIC8vIHNlbmQgdGhlIHVyZ2VudCBkYXRhIHdoaWNoIHNob3VsZCBub3QgYmUgcmVjZWl2ZWQuCisgICAgICAgICAgICAgICAgdGhlU29ja2V0LnNldE9PQklubGluZSh0cnVlKTsKKyAgICAgICAgICAgICAgICBzZXJ2U29jay5zZW5kVXJnZW50RGF0YSh1cmdlbnREYXRhLmdldEJ5dGVzKClbMF0pOworCisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworCisgICAgICAgICAgICAgICAgdG90YWxCeXRlc1JlYWQgPSAwOworICAgICAgICAgICAgICAgIG15Qnl0ZXMgPSBuZXcgYnl0ZVsxMDBdOworICAgICAgICAgICAgICAgIHdoaWxlICh0aGVJbnB1dC5hdmFpbGFibGUoKSA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGJ5dGVzUmVhZCA9IHRoZUlucHV0LnJlYWQobXlCeXRlcywgdG90YWxCeXRlc1JlYWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXlCeXRlcy5sZW5ndGggLSB0b3RhbEJ5dGVzUmVhZCk7CisgICAgICAgICAgICAgICAgICAgIHRvdGFsQnl0ZXNSZWFkID0gdG90YWxCeXRlc1JlYWQgKyBieXRlc1JlYWQ7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcmVjZWl2ZWRTdHJpbmcgPSBuZXcgU3RyaW5nKG15Qnl0ZXMsIDAsIHRvdGFsQnl0ZXNSZWFkKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJEaWQgbm90IGdldCB1cmdlbnQgZGF0YSBvbmx5IHVyZ2VudCBkYXRhIHNlbnQ6IgorICAgICAgICAgICAgICAgICAgICAgICAgKyByZWNlaXZlZFN0cmluZyArICI6IiArIHVyZ2VudERhdGEsIHJlY2VpdmVkU3RyaW5nCisgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKHVyZ2VudERhdGEpKTsKKworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBmb3IgcGxhdGZvcm1zIHRoYXQgZG8gbm90IHN1cHBvcnQgdXJnZW50IGRhdGEgd2UgZXhwZWN0IGFuCisgICAgICAgICAgICAgICAgLy8gZXhjZXB0aW9uLiBGb3IgdGhlIG90aGVycyByZXBvcnQgYW4gZXJyb3IuCisgICAgICAgICAgICAgICAgLy8gVE9ETyA6IE5lZWQgdG8gaW50cm9kdWNlIGEgYmV0dGVyIHRlc3QgZm9yIHRoZSBleGNlcHRpb24KKyAgICAgICAgICAgICAgICAvLyBzbyB0aGF0IHRoZSBmYWlsdXJlIG9ubHkgb2NjdXJzIG9uIHBsYXRmb3JtcyB0aGF0IHN1cHBvcnQKKyAgICAgICAgICAgICAgICAvLyB1cmdlbnQgZGF0YQorICAgICAgICAgICAgICAgIGZhaWwoIlBsYXRmb3JtOiIgKyBwbGF0Zm9ybQorICAgICAgICAgICAgICAgICAgICAgICAgKyAiOiBHb3QgZXhjZXB0aW9uIGR1cmluZyBzZW5kVXJnZW50IGRhdGEgdGVzdHMiCisgICAgICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU29ja2V0IHRoZVNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgICAgIHRoZVNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgdGhlU29ja2V0LnNlbmRVcmdlbnREYXRhKDApOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFBlcmZvcm1hbmNlUHJlZmVyZW5jZV9JbnRfSW50X0ludCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTb2NrZXQgdGhlU29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICB0aGVTb2NrZXQuc2V0UGVyZm9ybWFuY2VQcmVmZXJlbmNlcygxLCAxLCAxKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbmV0X1Byb3h5X0V4Y2VwdGlvbigpIHsKKworICAgICAgICBTb2NrZXRBZGRyZXNzIGFkZHIxID0gSW5ldFNvY2tldEFkZHJlc3MuY3JlYXRlVW5yZXNvbHZlZCgiMTI3LjAuMC4xIiwKKyAgICAgICAgICAgICAgICA4MCk7CisgICAgICAgIFNvY2tldEFkZHJlc3MgYWRkcjIgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoImxvY2FsaG9zdCIsIDgwKTsKKworICAgICAgICBQcm94eSBwcm94eTEgPSBuZXcgUHJveHkoUHJveHkuVHlwZS5IVFRQLCBhZGRyMSk7CisgICAgICAgIC8vIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB0ZXN0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU29ja2V0KHByb3h5MSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgUHJveHkgcHJveHkyID0gbmV3IFByb3h5KFByb3h5LlR5cGUuU09DS1MsIGFkZHIxKTsKKyAgICAgICAgLy8gc2hvdWxkIG5vdCB0aHJvdyBhbnkgZXhjZXB0aW9uCisgICAgICAgIG5ldyBTb2NrZXQocHJveHkyKTsKKyAgICAgICAgbmV3IFNvY2tldChQcm94eS5OT19QUk9YWSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTb2NrZXQoKFByb3h5KSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTFNvY2tldEltcGwoKSB7CisgICAgICAgIE1vY2tTb2NrZXRJbXBsIG1zaSA9IG5ldyBNb2NrU29ja2V0SW1wbCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFRlc3RTb2NrZXQobXNpKTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNvY2tldEV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25uZWN0X3Vua25vd25ob3N0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNvY2tldCBzb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIHNvY2tldEFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoInVua25vd25ob3N0IiwgMTIzNDUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc29ja2V0LmNvbm5lY3Qoc29ja2V0QWRkcmVzcyk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY29ubmVjdF91bnJlc29sdmVkX3Vua25vd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU29ja2V0IHNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgdW5yZXNvbHZlZCA9IEluZXRTb2NrZXRBZGRyZXNzLmNyZWF0ZVVucmVzb2x2ZWQoInVua25vd25ob3N0IiwgMTIzNDUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc29ja2V0LmNvbm5lY3QodW5yZXNvbHZlZCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY29ubmVjdF91bnJlc29sdmVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNvY2tldCBzb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIHVucmVzb2x2ZWRTb2NrZXRBZGRyZXNzID0gSW5ldFNvY2tldEFkZHJlc3MuY3JlYXRlVW5yZXNvbHZlZCgKKyAgICAgICAgICAgICAgICBTdXBwb3J0X0NvbmZpZ3VyYXRpb24uU29ja3NTZXJ2ZXJUZXN0SG9zdCwKKyAgICAgICAgICAgICAgICBTdXBwb3J0X0NvbmZpZ3VyYXRpb24uU29ja3NTZXJ2ZXJUZXN0UG9ydCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzb2NrZXQuY29ubmVjdCh1bnJlc29sdmVkU29ja2V0QWRkcmVzcyk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0T3V0cHV0U3RyZWFtX3NodXRkb3duT3V0cHV0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIHJlZ3Jlc3Npb24gdGVzdCBmb3IgSGFybW9ueS04NzMKKyAgICAgICAgU2VydmVyU29ja2V0IHNzID0gbmV3IFNlcnZlclNvY2tldCgwKTsKKyAgICAgICAgU29ja2V0IHMgPSBuZXcgU29ja2V0KCIxMjcuMC4wLjEiLCBzcy5nZXRMb2NhbFBvcnQoKSk7CisgICAgICAgIHNzLmFjY2VwdCgpOworICAgICAgICBzLnNodXRkb3duT3V0cHV0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmdldE91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IFNvY2tldEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgcy5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgU29ja2V0Q2hhbm5lbCBjaGFubmVsID0gU29ja2V0Q2hhbm5lbC5vcGVuKAorICAgICAgICAgICAgICAgIG5ldyBJbmV0U29ja2V0QWRkcmVzcyhzcy5nZXRJbmV0QWRkcmVzcygpLCBzcy5nZXRMb2NhbFBvcnQoKSkpOworICAgICAgICBjaGFubmVsLmNvbmZpZ3VyZUJsb2NraW5nKGZhbHNlKTsKKyAgICAgICAgc3MuYWNjZXB0KCk7CisgICAgICAgIFNvY2tldCBzb2NrZXQgPSBjaGFubmVsLnNvY2tldCgpOworCisgICAgICAgIE91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXQgPSBzb2NrZXQuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICBvdXQud3JpdGUoMSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb24gaWJtZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYob3V0ICE9IG51bGwpIG91dC5jbG9zZSgpOworICAgICAgICAgICAgc29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICBjaGFubmVsLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NodXRkb3duSW5wdXRPdXRwdXRfdHdpY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gcmVncmVzc2lvbiB0ZXN0IGZvciBIYXJtb255LTI5NDQKKyAgICAgICAgU29ja2V0IHMgPSBuZXcgU29ja2V0KCIwLjAuMC4wIiwgMCwgZmFsc2UpOworICAgICAgICBzLnNodXRkb3duSW5wdXQoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5zaHV0ZG93bklucHV0KCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgU29ja2V0RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBzZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBzLnNodXRkb3duT3V0cHV0KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMuc2h1dGRvd25PdXRwdXQoKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBTb2NrZXRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVhcnMgZG93biB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIGNsb3NlIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzCisgICAgICogbWV0aG9kIGlzIGNhbGxlZCBhZnRlciBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAocyAhPSBudWxsKQorICAgICAgICAgICAgICAgIHMuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKHNzICE9IG51bGwpCisgICAgICAgICAgICAgICAgc3MuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0LmludGVycnVwdCgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIE1vY2tTZWN1cml0eU1hbmFnZXIgZXh0ZW5kcyBTZWN1cml0eU1hbmFnZXIgeworCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrQ29ubmVjdChTdHJpbmcgaG9zdCwgaW50IHBvcnQpIHsKKyAgICAgICAgICAgIGlmICgiMTI3LjAuMC4xIi5lcXVhbHMoaG9zdCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oInBlcm1pc3Npb24gaXMgbm90IGFsbG93ZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihQZXJtaXNzaW9uIHBlcm1pc3Npb24pIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICoKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHN0YXJ0U2VydmVyKFN0cmluZyBuYW1lKSB7CisgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3MgPSBuZXcgU2VydmVyU29ja2V0KHBvcnROdW1iZXIsIDUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKG5hbWUgKyAiOiAiICsgZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNzLmdldExvY2FsUG9ydCgpOworICAgIH0KKworICAgIGNsYXNzIE1vY2tTb2NrZXRJbXBsIGV4dGVuZHMgU29ja2V0SW1wbCB7CisKKyAgICAgICAgcHVibGljIE1vY2tTb2NrZXRJbXBsKCkgeworICAgICAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBhY2NlcHQoU29ja2V0SW1wbCBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGJpbmQoSW5ldEFkZHJlc3MgYXJnMCwgaW50IGFyZzEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGNvbm5lY3QoU3RyaW5nIGFyZzAsIGludCBhcmcxKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGNvbm5lY3QoSW5ldEFkZHJlc3MgYXJnMCwgaW50IGFyZzEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgY29ubmVjdChTb2NrZXRBZGRyZXNzIGFyZzAsIGludCBhcmcxKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGNyZWF0ZShib29sZWFuIGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGxpc3RlbihpbnQgYXJnMCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBzZW5kVXJnZW50RGF0YShpbnQgYXJnMCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0T3B0aW9uKGludCBhcmcwKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0T3B0aW9uKGludCBhcmcwLCBPYmplY3QgYXJnMSkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRTb2NrZXRUZXN0Q2FzZS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkU29ja2V0VGVzdENhc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iY2I2YWY5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkU29ja2V0VGVzdENhc2UuamF2YQpAQCAtMCwwICsxLDE2MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmV0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgT2xkU29ja2V0VGVzdENhc2UgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT19NVUxUSUNBU1QgPSAwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fTVVMVElDQVNUX0lOVEVSRkFDRSA9IDE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT19MSU5HRVIgPSAyOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fUkNWQlVGID0gMzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNPX1RJTUVPVVQgPSA0OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fU05EQlVGID0gNTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRDUF9OT0RFTEFZID0gNjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNPX0tFRVBBTElWRSA9IDc7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT19SRVVTRUFERFIgPSA4OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fT09CSU5MSU5FID0gOTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElQX1RPUyA9IDEwOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09fQlJPQURDQVNUID0gMTE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT19VU0VMT09QQkFDSyA9IDEyOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIG9zRG9lc05vdFN1cHBvcnRPcGVyYXRpb25TdHJpbmcgPSAiVGhlIHNvY2tldCBkb2VzIG5vdCBzdXBwb3J0IHRoZSBvcGVyYXRpb24iOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIG9zRG9lc05vdFN1cHBvcnRPcHRpb25TdHJpbmcgPSAiVGhlIHNvY2tldCBvcHRpb24gaXMgbm90IHN1cHBvcnRlZCI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgb3NEb2VzTm90U3VwcG9ydE9wdGlvbkFyZ3VtZW50U3RyaW5nID0gIlRoZSBzb2NrZXQgb3B0aW9uIGFyZ3VtZW50cyBhcmUgaW52YWxpZCI7CisKKyAgICAvKioKKyAgICAgKiBBbnN3ZXIgd2hldGhlciB0aGUgT1Mgc3VwcG9ydHMgdGhlIGdpdmVuIHNvY2tldCBvcHRpb24uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0T3B0aW9uSXNTdXBwb3J0ZWQoaW50IG9wdGlvbikgeworICAgICAgICBzd2l0Y2ggKG9wdGlvbikgeworICAgICAgICBjYXNlIFNPX1JDVkJVRjoKKyAgICAgICAgY2FzZSBTT19TTkRCVUY6CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSBTT19NVUxUSUNBU1Q6CisgICAgICAgIGNhc2UgU09fTVVMVElDQVNUX0lOVEVSRkFDRToKKyAgICAgICAgY2FzZSBTT19MSU5HRVI6CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgY2FzZSBUQ1BfTk9ERUxBWToKKyAgICAgICAgY2FzZSBTT19USU1FT1VUOgorICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIGNhc2UgU09fS0VFUEFMSVZFOgorICAgICAgICBjYXNlIFNPX1JFVVNFQUREUjoKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlIFNPX09PQklOTElORToKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlIElQX1RPUzoKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlIFNPX0JST0FEQ0FTVDoKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICBjYXNlIFNPX1VTRUxPT1BCQUNLOgorICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHRoZSBleGNlcHRpb24gaXMgInNvY2tldCBkb2VzIG5vdCBzdXBwb3J0IHRoZSBvcGVyYXRpb24iIGV4Y2VwdGlvbiBhbmQKKyAgICAgKiBpdCBpcyBleHBlY3RlZCBvbiB0aGUgY3VycmVudCBwbGF0Zm9ybSwgZG8gbm90aGluZy4gT3RoZXJ3aXNlLCBmYWlsIHRoZQorICAgICAqIHRlc3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgaGFuZGxlRXhjZXB0aW9uKEV4Y2VwdGlvbiBlLCBpbnQgb3B0aW9uKSB7CisgICAgICAgIGlmICghZ2V0T3B0aW9uSXNTdXBwb3J0ZWQob3B0aW9uKSkgeworICAgICAgICAgICAgU3RyaW5nIG1lc3NhZ2UgPSBlLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGlmIChtZXNzYWdlICE9IG51bGwKKyAgICAgICAgICAgICAgICAgICAgJiYgKG1lc3NhZ2UuZXF1YWxzKG9zRG9lc05vdFN1cHBvcnRPcGVyYXRpb25TdHJpbmcpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgbWVzc2FnZS5lcXVhbHMob3NEb2VzTm90U3VwcG9ydE9wdGlvblN0cmluZykgfHwgbWVzc2FnZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMob3NEb2VzTm90U3VwcG9ydE9wdGlvbkFyZ3VtZW50U3RyaW5nKSkpIHsKKyAgICAgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAgICAqIFRoaXMgZXhjZXB0aW9uIGlzIHRoZSBjb3JyZWN0IGJlaGF2aW9yIGZvciBwbGF0Zm9ybXMgd2hpY2ggZG8KKyAgICAgICAgICAgICAgICAgKiBub3Qgc3VwcG9ydCB0aGUgb3B0aW9uCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZhaWwoIlRocmV3IFwiIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBlCisgICAgICAgICAgICAgICAgICAgICAgICArICJcIiBpbnN0ZWFkIG9mIGNvcnJlY3QgZXhjZXB0aW9uIGZvciB1bnN1cHBvcnRlZCBzb2NrZXQgb3B0aW9uOiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIGdldFNvY2tldE9wdGlvblN0cmluZyhvcHRpb24pKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBzaG91bGQgYmUgY2FsbGVkIGF0IHRoZSBlbmQgb2YgYSBzb2NrZXQgb3B0aW9uIHRlc3QncyBjb2RlCisgICAgICogYnV0IGJlZm9yZSB0aGUgZXhjZXB0aW9uIGNhdGNoIHN0YXRlbWVudHMuIEl0IHRocm93cyBhIGZhaWx1cmUgaWYgdGhlCisgICAgICogb3B0aW9uIGdpdmVuIGlzIG5vdCBzdXBwb3J0ZWQgb24gdGhlIGN1cnJlbnQgcGxhdGZvcm0gYnV0IHRoZSBWTSBmYWlsZWQKKyAgICAgKiB0byB0aHJvdyBhbiBleGNlcHRpb24uIFNvLCBvbiBwbGF0Zm9ybXMgd2hpY2ggZG8gbm90IHN1cHBvcnQgdGhlIG9wdGlvbiwKKyAgICAgKiB0aGUgZXhlY3V0aW9uIHNob3VsZCBuZXZlciBnZXQgdG8gdGhpcyBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZW5zdXJlRXhjZXB0aW9uVGhyb3duSWZPcHRpb25Jc1Vuc3VwcG9ydGVkT25PUyhpbnQgb3B0aW9uKSB7CisgICAgICAgIGlmICghZ2V0T3B0aW9uSXNTdXBwb3J0ZWQob3B0aW9uKSkgeworICAgICAgICAgICAgZmFpbCgiRmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiBmb3IgdW5zdXBwb3J0ZWQgc29ja2V0IG9wdGlvbjogIgorICAgICAgICAgICAgICAgICAgICArIGdldFNvY2tldE9wdGlvblN0cmluZyhvcHRpb24pKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFuc3dlciBhIHN0cmluZyBmb3IgdGhlIHNvY2tldCBvcHRpb24gZ2l2ZW4uCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0U29ja2V0T3B0aW9uU3RyaW5nKGludCBvcHRpb24pIHsKKyAgICAgICAgc3dpdGNoIChvcHRpb24pIHsKKyAgICAgICAgY2FzZSBTT19NVUxUSUNBU1Q6CisgICAgICAgICAgICByZXR1cm4gIk11bHRpY2FzdCI7CisgICAgICAgIGNhc2UgU09fTElOR0VSOgorICAgICAgICAgICAgcmV0dXJuICJMaW5nZXIiOworICAgICAgICBjYXNlIFNPX1JDVkJVRjoKKyAgICAgICAgICAgIHJldHVybiAiUmVjZWl2ZSBidWZmZXIgc2l6ZSI7CisgICAgICAgIGNhc2UgU09fVElNRU9VVDoKKyAgICAgICAgICAgIHJldHVybiAiU29ja2V0IHRpbWVvdXQiOworICAgICAgICBjYXNlIFNPX1NOREJVRjoKKyAgICAgICAgICAgIHJldHVybiAiU2VuZCBidWZmZXIgc2l6ZSI7CisgICAgICAgIGNhc2UgVENQX05PREVMQVk6CisgICAgICAgICAgICByZXR1cm4gIlRDUCBubyBkZWxheSI7CisgICAgICAgIGNhc2UgU09fS0VFUEFMSVZFOgorICAgICAgICAgICAgcmV0dXJuICJLZWVwYWxpdmUiOworICAgICAgICBjYXNlIFNPX1JFVVNFQUREUjoKKyAgICAgICAgICAgIHJldHVybiAiUmV1c2UgYWRkcmVzcyI7CisgICAgICAgIGNhc2UgU09fT09CSU5MSU5FOgorICAgICAgICAgICAgcmV0dXJuICJvdXQgb2YgYmFuZCBkYXRhIGlubGluZSI7CisgICAgICAgIGNhc2UgSVBfVE9TOgorICAgICAgICAgICAgcmV0dXJuICJUcmFmZmljIGNsYXNzIjsKKyAgICAgICAgY2FzZSBTT19CUk9BRENBU1Q6CisgICAgICAgICAgICByZXR1cm4gImJyb2FkY2FzdCI7CisgICAgICAgIGNhc2UgU09fVVNFTE9PUEJBQ0s6CisgICAgICAgICAgICByZXR1cm4gImxvb3BiYWNrIjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gIlVua25vd24gc29ja2V0IG9wdGlvbiI7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRVUklUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRVUklUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjFkMzQ0NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZFVSSVRlc3QuamF2YQpAQCAtMCwwICsxLDE1MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmV0OworCitpbXBvcnQgamF2YS5uZXQuVVJJOworaW1wb3J0IGphdmEubmV0LlVSSVN5bnRheEV4Y2VwdGlvbjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRVUklUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgU3RyaW5nW10gY29uc3RydWN0b3JUZXN0cyA9IG5ldyBTdHJpbmdbXSB7CisgICAgICAgICAgICAiaHR0cDovL3VzZXJAd3d3Lmdvb2dsZS5jb206NDUvc2VhcmNoP3E9aGVscGluZm8jc29tZWZyYWdtZW50IiwKKyAgICAgICAgICAgIC8vIGh0dHAgd2l0aCBhdXRob3JpdHksIHF1ZXJ5IGFuZCBmcmFnbWVudAorICAgICAgICAgICAgImZ0cDovL2Z0cC5pcy5jby56YS9yZmMvcmZjMTgwOC50eHQiLCAvLyBmdHAKKyAgICAgICAgICAgICJnb3BoZXI6Ly9zcGluYWx0YXAubWljcm8udW1uLmVkdS8wMC9XZWF0aGVyL0NhbGlmb3JuaWEvTG9zJTIwQW5nZWxlcyIsIC8vIGdvcGhlcgorICAgICAgICAgICAgIm1haWx0bzptZHVlcnN0QGlmaS51bml6aC5jaCIsIC8vIG1haWx0bworICAgICAgICAgICAgIm5ld3M6Y29tcC5pbmZvc3lzdGVtcy53d3cuc2VydmVycy51bml4IiwgLy8gbmV3cworICAgICAgICAgICAgInRlbG5ldDovL21lbHZ5bC51Y29wLmVkdS8iLCAvLyB0ZWxuZXQKKyAgICAgICAgICAgICJodHRwOi8vMTIzLjI0LjE3Ljk4L3Rlc3QiLCAvLyBJUHY0IGF1dGhvcml0eQorICAgICAgICAgICAgImh0dHA6Ly93d3cuZ29vZ2xlLmNvbTo4MC90ZXN0IiwvLyBkb21haW4gbmFtZSBhdXRob3JpdHkKKyAgICAgICAgICAgICJodHRwOi8vam9lQFszZmZlOjJhMDA6MTAwOjcwMzE6OjFdOjgwL3Rlc3QiLAorICAgICAgICAgICAgLy8gSVB2NiBhdXRob3JpdHksIHdpdGggdXNlcmluZm8gYW5kIHBvcnQKKyAgICAgICAgICAgICIvcmVsYXRpdmUiLCAvLyByZWxhdGl2ZSBzdGFydGluZyB3aXRoIC8KKyAgICAgICAgICAgICIvL3JlbGF0aXZlIiwgLy8gcmVsYXRpdmUgc3RhcnRpbmcgd2l0aCAvLworICAgICAgICAgICAgInJlbGF0aXZlIiwgLy8gcmVsYXRpdmUgd2l0aCBubyAvCisgICAgICAgICAgICAiI2ZyYWdtZW50IiwvLyByZWxhdGl2ZSBqdXN0IHdpdGggZnJhZ21lbnQKKyAgICAgICAgICAgICJodHRwOi8vdXNlckBob3N0OjgwIiwgLy8gVUksIGhvc3QscG9ydAorICAgICAgICAgICAgImh0dHA6Ly91c2VyQGhvc3QiLCAvLyB1aSwgaG9zdAorICAgICAgICAgICAgImh0dHA6Ly9ob3N0IiwgLy8gaG9zdAorICAgICAgICAgICAgImh0dHA6Ly9ob3N0OjgwIiwgLy8gaG9zdCxwb3J0CisgICAgICAgICAgICAiaHR0cDovL2pvZUA6ODAiLCAvLyB1aSwgcG9ydCAoYmVjb21lcyByZWdpc3RyeS1iYXNlZCkKKyAgICAgICAgICAgICJmaWxlOi8vL2Zvby9iYXIiLCAvLyBlbXB0eSBhdXRob3JpdHksIG5vbiBlbXB0eSBwYXRoCisgICAgICAgICAgICAiaHQ/dHA6Ly9ob2VAaG9zdDo4MCIsIC8vIG1pc2NlbGxhbmVvdXMgdGVzdHMKKyAgICAgICAgICAgICJtYWkvbHRvOmhleT9qb2UjbWFuIiwgImh0dHA6Ly9ob3N0L2ElMjBwYXRoI2ZyYWciLAorICAgICAgICAgICAgLy8gcGF0aCB3aXRoIGFuIGVzY2FwZWQgb2N0ZXQgZm9yIHNwYWNlIGNoYXIKKyAgICAgICAgICAgICJodHRwOi8vaG9zdC9hJUUyJTgyJUFDcGF0aCNmcmFnIiwKKyAgICAgICAgICAgIC8vIHBhdGggd2l0aCBlc2NhcGVkIG9jdGV0IGZvciB1bmljb2RlIGNoYXIsIG5vdCBVU0FTQ0lJCisgICAgICAgICAgICAiaHR0cDovL2hvc3QvYVx1MjBBQ3BhdGgjZnJhZyIsCisgICAgICAgICAgICAvLyBwYXRoIHdpdGggdW5pY29kZSBjaGFyLCBub3QgVVNBU0NJSSBlcXVpdmFsZW50IHRvCisgICAgICAgICAgICAvLyA9ICJodHRwOi8vaG9zdC9hXHUwMDgwcGF0aCNmcmFnIiwKKyAgICAgICAgICAgICJodHRwOi8vaG9zdCUyMG5hbWUvIiwgLy8gZXNjYXBlZCBvY3RldHMgaW4gaG9zdCAoYmVjb21lcworICAgICAgICAgICAgLy8gcmVnaXN0cnkgYmFzZWQpCisgICAgICAgICAgICAiaHR0cDovL2hvc3RcdTAwREZuYW1lLyIsIC8vIHVuaWNvZGVjaGFyIGluIGhvc3QgKGJlY29tZXMKKyAgICAgICAgICAgIC8vIHJlZ2lzdHJ5IGJhc2VkKQorICAgICAgICAgICAgLy8gZXF1aXZhbGVudCB0byA9ICJodHRwOi8vaG9zdFx1MDBkZm5hbWUvIiwKKyAgICAgICAgICAgICJodDEyMy0rdHA6Ly93d3cuZ29vZ2xlLmNvbTo4MC90ZXN0IiwgLy8gbGVnYWwgY2hhcnMgaW4gc2NoZW1lCisgICAgfTsKKworICAgIFN0cmluZ1tdIGNvbnN0cnVjdG9yVGVzdHNJbnZhbGlkID0gbmV3IFN0cmluZ1tdIHsKKyAgICAgICAgICAgICJodHRwOi8vL2EgcGF0aCNmcmFnIiwgLy8gc3BhY2UgY2hhciBpbiBwYXRoLCBub3QgaW4gZXNjYXBlZAorICAgICAgICAgICAgLy8gb2N0ZXQgZm9ybSwgd2l0aCBubyBob3N0CisgICAgICAgICAgICAiaHR0cDovL2hvc3QvYVtwYXRoI2ZyYWciLCAvLyBhbiBpbGxlZ2FsIGNoYXIsIG5vdCBpbiBlc2NhcGVkCisgICAgICAgICAgICAvLyBvY3RldCBmb3JtLCBzaG91bGQgdGhyb3cgYW4KKyAgICAgICAgICAgIC8vIGV4Y2VwdGlvbgorICAgICAgICAgICAgImh0dHA6Ly9ob3N0L2ElcGF0aCNmcmFnIiwgLy8gaW52YWxpZCBlc2NhcGUgc2VxdWVuY2UgaW4gcGF0aAorICAgICAgICAgICAgImh0dHA6Ly9ob3N0L2ElI2ZyYWciLCAvLyBpbmNvbXBsZXRlIGVzY2FwZSBzZXF1ZW5jZSBpbiBwYXRoCisKKyAgICAgICAgICAgICJodHRwOi8vaG9zdCNhIGZyYWciLCAvLyBzcGFjZSBjaGFyIGluIGZyYWdtZW50LCBub3QgaW4KKyAgICAgICAgICAgIC8vIGVzY2FwZWQgb2N0ZXQgZm9ybSwgbm8gcGF0aAorICAgICAgICAgICAgImh0dHA6Ly9ob3N0L2EjZnIjYWciLCAvLyBpbGxlZ2FsIGNoYXIgaW4gZnJhZ21lbnQKKyAgICAgICAgICAgICJodHRwOi8vL3BhdGgjZnIlYWciLCAvLyBpbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZSBpbiBmcmFnbWVudCwKKyAgICAgICAgICAgIC8vIHdpdGggbm8gaG9zdAorICAgICAgICAgICAgImh0dHA6Ly9ob3N0L3BhdGgjZnJhZyUiLCAvLyBpbmNvbXBsZXRlIGVzY2FwZSBzZXF1ZW5jZSBpbgorICAgICAgICAgICAgLy8gZnJhZ21lbnQKKworICAgICAgICAgICAgImh0dHA6Ly9ob3N0L3BhdGg/YSBxdWVyeSNmcmFnIiwgLy8gc3BhY2UgY2hhciBpbiBxdWVyeSwgbm90CisgICAgICAgICAgICAvLyBpbiBlc2NhcGVkIG9jdGV0IGZvcm0KKyAgICAgICAgICAgICJodHRwOi8vaG9zdD9xdWVyeSVhZyIsIC8vIGludmFsaWQgZXNjYXBlIHNlcXVlbmNlIGluIHF1ZXJ5LCBubworICAgICAgICAgICAgLy8gcGF0aAorICAgICAgICAgICAgImh0dHA6Ly8vcGF0aD9xdWVyeSUiLCAvLyBpbmNvbXBsZXRlIGVzY2FwZSBzZXF1ZW5jZSBpbiBxdWVyeSwKKyAgICAgICAgICAgIC8vIHdpdGggbm8gaG9zdAorCisgICAgICAgICAgICAibWFpbHRvOnVzZXJebmFtZUBma2xrZi5jb20iIC8vIGludmFsaWQgY2hhciBpbiBzY2hlbWUgc3BlY2lmaWMgcGFydAorICAgIH07CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NyZWF0ZUxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICBmb3IgKFN0cmluZyBzIDogY29uc3RydWN0b3JUZXN0cykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBuZXcgVVJJKHMpOworICAgICAgICAgICAgfSBjYXRjaCAoVVJJU3ludGF4RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJGYWlsZWQgdG8gY29uc3RydWN0IFVSSSBmb3I6ICIgKyBzICsgIiA6ICIgKyBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoU3RyaW5nIHMgOiBjb25zdHJ1Y3RvclRlc3RzSW52YWxpZCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBVUkkuY3JlYXRlKHMpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHJlY2VpdmVkLiIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlbGF0aXZpemVMamF2YV9uZXRfVVJJKCkgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkkgYiA9IG5ldyBVUkkoImh0dHA6Ly93d3cuZ29vZ2xlLmNvbS9kaXIxL2RpcjIiKTsKKyAgICAgICAgICAgIGIucmVsYXRpdml6ZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Jlc29sdmVMamF2YV9uZXRfVVJJKCkgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkkgYiA9IG5ldyBVUkkoImh0dHA6Ly93d3cudGVzdC5jb20vZGlyIik7CisgICAgICAgICAgICBiLnJlc29sdmUoKFVSSSkgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZXNvbHZlTGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFVSSSBiID0gbmV3IFVSSSgiaHR0cDovL3d3dy50ZXN0LmNvbS9kaXIiKTsKKyAgICAgICAgICAgIGIucmVzb2x2ZSgoU3RyaW5nKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgVVJJIGIgPSBuZXcgVVJJKCJodHRwOi8vd3d3LnRlc3QuY29tL2RpciIpOworICAgICAgICAgICAgYi5yZXNvbHZlKCJodHRwOi8vYS9iL2MvZz95Ly4veFxuIik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBVUkkobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkVVJMQ2xhc3NMb2FkZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRVUkxDbGFzc0xvYWRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNjQ2Zjk4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkVVJMQ2xhc3NMb2FkZXJUZXN0LmphdmEKQEAgLTAsMCArMSwzMDMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5ldDsKKworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLlNpZGVFZmZlY3Q7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLm5ldC5VUkxDbGFzc0xvYWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkNvZGVTb3VyY2U7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5qYXIuTWFuaWZlc3Q7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuVGVzdENlcnRVdGlsczsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfQ29uZmlndXJhdGlvbjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfUG9ydE1hbmFnZXI7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1Rlc3RXZWJEYXRhOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9UZXN0V2ViU2VydmVyOworaW1wb3J0IHRlc3RzLnN1cHBvcnQucmVzb3VyY2UuU3VwcG9ydF9SZXNvdXJjZXM7CisKK3B1YmxpYyBjbGFzcyBPbGRVUkxDbGFzc0xvYWRlclRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgVVJMQ2xhc3NMb2FkZXIgdWNsOworICAgIFNlY3VyaXR5TWFuYWdlciBzbSA9IG5ldyBTZWN1cml0eU1hbmFnZXIoKSB7CisKKyAgICAgICAgcHVibGljIHZvaWQgY2hlY2tQZXJtaXNzaW9uKFBlcm1pc3Npb24gcGVybSkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgY2hlY2tDcmVhdGVDbGFzc0xvYWRlcigpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfTsKKworICAgIC8qKgorICAgICAqIGphdmEubmV0LlVSTENsYXNzTG9hZGVyI1VSTENsYXNzTG9hZGVyKGphdmEubmV0LlVSTFtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IkTGphdmFfbmV0X1VSTCgpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgICAgICBVUkxbXSB1ID0gbmV3IFVSTFswXTsKKyAgICAgICAgdWNsID0gbmV3IFVSTENsYXNzTG9hZGVyKHUpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gc2V0IHBhcmVudCIsIHVjbCAhPSBudWxsCisgICAgICAgICAgICAgICAgJiYgdWNsLmdldFBhcmVudCgpID09IFVSTENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkpOworCisKKyAgICAgICAgVVJMIFtdIHVybHMgPSB7bmV3IFVSTCgiaHR0cDovL2Zvby5jb20vZm9vIiksCisgICAgICAgICAgICAgICAgICAgICAgIG5ldyBVUkwoImphcjpmaWxlOi8vZm9vLmphciEvZm9vLmMiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgbmV3IFVSTCgiZnRwOi8vZm9vMS9mb28yL2Zvby5jIil9OworCisgICAgICAgIFVSTENsYXNzTG9hZGVyIHVjbDEgPSBuZXcgVVJMQ2xhc3NMb2FkZXIodXJscyk7CisgICAgICAgIGFzc2VydFRydWUodXJscy5sZW5ndGggPT0gdWNsMS5nZXRVUkxzKCkubGVuZ3RoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3MuZm9yTmFtZSgidGVzdCIsIGZhbHNlLCB1Y2wpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IENsYXNzTm90Rm91bmRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBVUkxDbGFzc0xvYWRlcihuZXcgVVJMW10geyBudWxsIH0pOworICAgICAgICB9IGNhdGNoKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiB3YXMgdGhyb3duOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5uZXQuVVJMQ2xhc3NMb2FkZXIjZmluZFJlc291cmNlcyhqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmluZFJlc291cmNlc0xqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEVudW1lcmF0aW9uPFVSTD4gcmVzID0gbnVsbDsKKyAgICAgICAgU3RyaW5nW10gcmVzVmFsdWVzID0geyAiVGhpcyBpcyBhIHRlc3QgcmVzb3VyY2UgZmlsZS4iLAorICAgICAgICAgICAgICAgICJUaGlzIGlzIGEgcmVzb3VyY2UgZnJvbSBhIHN1YmRpciJ9OworCisgICAgICAgIFN0cmluZyB0bXAgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaW8udG1wZGlyIikgKyAiLyI7CisKKyAgICAgICAgRmlsZSB0bXBEaXIgPSBuZXcgRmlsZSh0bXApOworICAgICAgICBGaWxlIHRlc3QxID0gbmV3IEZpbGUodG1wICsgInRlc3QwIik7CisgICAgICAgIHRlc3QxLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKHRlc3QxKTsKKyAgICAgICAgb3V0LndyaXRlKHJlc1ZhbHVlc1swXS5nZXRCeXRlcygpKTsKKyAgICAgICAgb3V0LmZsdXNoKCk7CisgICAgICAgIG91dC5jbG9zZSgpOworCisgICAgICAgIEZpbGUgc3ViRGlyID0gbmV3IEZpbGUodG1wICsgInN1YmRpci8iKTsKKyAgICAgICAgc3ViRGlyLm1rZGlyKCk7CisgICAgICAgIEZpbGUgdGVzdDIgPSBuZXcgRmlsZSh0bXAgKyAic3ViZGlyL3Rlc3QwIik7CisgICAgICAgIHRlc3QyLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbSh0ZXN0Mik7CisgICAgICAgIG91dC53cml0ZShyZXNWYWx1ZXNbMV0uZ2V0Qnl0ZXMoKSk7CisgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICBvdXQuY2xvc2UoKTsKKworICAgICAgICBVUkxbXSB1cmxzID0gbmV3IFVSTFsyXTsKKyAgICAgICAgdXJsc1swXSA9IG5ldyBVUkwoImZpbGU6Ly8iICsgdG1wRGlyLmdldEFic29sdXRlUGF0aCgpICsgIi8iKTsKKyAgICAgICAgdXJsc1sxXSA9IG5ldyBVUkwoImZpbGU6Ly8iICsgc3ViRGlyLmdldEFic29sdXRlUGF0aCgpICsgIi8iKTsKKworICAgICAgICB1Y2wgPSBuZXcgVVJMQ2xhc3NMb2FkZXIodXJscyk7CisgICAgICAgIHJlcyA9IHVjbC5maW5kUmVzb3VyY2VzKCJ0ZXN0MCIpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJGYWlsZWQgdG8gbG9jYXRlIHJlc291cmNlcyIsIHJlcyk7CisKKyAgICAgICAgaW50IGkgPSAwOworICAgICAgICB3aGlsZSAocmVzLmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICBTdHJpbmdCdWZmZXIgc2IgPSBnZXRSZXNDb250ZW50KHJlcy5uZXh0RWxlbWVudCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHJlc291cmNlL29yIGluIHdyb25nIG9yZGVyIiwKKyAgICAgICAgICAgICAgICAgICAgcmVzVmFsdWVzW2krK10sIHNiLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IG51bWJlciBvZiByZXNvdXJjZXMgcmV0dXJuZWQiLCAyLCBpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZFVSTExqYXZhX25ldF9VUkwoKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMW10gdSA9IG5ldyBVUkxbMF07CisKKyAgICAgICAgVVJMIFtdIHVybHMgPSB7bmV3IFVSTCgiaHR0cDovL2Zvby5jb20vZm9vIiksCisgICAgICAgICAgICAgICAgICAgICAgIG5ldyBVUkwoImphcjpmaWxlOi8vZm9vLmphciEvZm9vLmMiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgbmV3IFVSTCgiZnRwOi8vZm9vMS9mb28yL2Zvby5jIiksIG51bGx9OworCisgICAgICAgIFRlc3RVUkxDbGFzc0xvYWRlciB0dWNsID0gbmV3IFRlc3RVUkxDbGFzc0xvYWRlcih1KTsKKworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgdXJscy5sZW5ndGg7KSB7CisgICAgICAgICAgICB0dWNsLmFkZFVSTCh1cmxzW2ldKTsKKyAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgIFVSTCBbXSByZXN1bHQgPSB0dWNsLmdldFVSTHMoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiUmVzdWx0IGFycmF5IGxlbmd0aCBpcyBpbmNvcnJlY3Q6ICIgKyBpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSwgcmVzdWx0Lmxlbmd0aCk7CisgICAgICAgICAgICBmb3IoaW50IGogPSAwOyBqIDwgcmVzdWx0Lmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXN1bHQgYXJyYXkgaXRlbSBpcyBpbmNvcnJlY3Q6ICIgKyBqLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsc1tqXSwgcmVzdWx0W2pdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZGVmaW5lUGFja2FnZSgpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgICAgICBNYW5pZmVzdCBtYW5pZmVzdCA9IG5ldyBNYW5pZmVzdCgpOworICAgICAgICBVUkxbXSB1ID0gbmV3IFVSTFswXTsKKyAgICAgICAgVGVzdFVSTENsYXNzTG9hZGVyIHR1Y2wgPSBuZXcgVGVzdFVSTENsYXNzTG9hZGVyKHUpOworCisgICAgICAgIFVSTCBbXSB1cmxzID0ge25ldyBVUkwoImh0dHA6Ly9mb28uY29tL2ZvbyIpLAorICAgICAgICAgICAgICAgIG5ldyBVUkwoImphcjpmaWxlOi8vZm9vLmphciEvZm9vLmMiKSwKKyAgICAgICAgICAgICAgICBuZXcgVVJMKCJmdHA6Ly9mb28xL2ZvbzIvZm9vLmMiKSwKKyAgICAgICAgICAgICAgICBuZXcgVVJMKCJmaWxlOi8vbmV3L3BhY2thZ2UvbmFtZS8iKSwKKyAgICAgICAgICAgICAgICBudWxsfTsKKworICAgICAgICBTdHJpbmcgcGFja2FnZU5hbWUgPSAibmV3LnBhY2thZ2UubmFtZSI7CisKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IHVybHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFBhY2thZ2UgcGFjayA9IHR1Y2wuZGVmaW5lUGFja2FnZShwYWNrYWdlTmFtZSArIGksIG1hbmlmZXN0LCB1cmxzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhwYWNrYWdlTmFtZSArIGksIHBhY2suZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoIkltcGxlbWVudGF0aW9uIFRpdGxlIGlzIG5vdCBudWxsIiwKKyAgICAgICAgICAgICAgICAgICAgcGFjay5nZXRJbXBsZW1lbnRhdGlvblRpdGxlKCkpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiSW1wbGVtZW50YXRpb24gVmVuZG9yIGlzIG5vdCBudWxsIiwKKyAgICAgICAgICAgICAgICAgICAgcGFjay5nZXRJbXBsZW1lbnRhdGlvblZlbmRvcigpKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoIkltcGxlbWVudGF0aW9uIFZlcnNpb24gaXMgbm90IG51bGwuIiwKKyAgICAgICAgICAgICAgICAgICAgcGFjay5nZXRJbXBsZW1lbnRhdGlvblZlcnNpb24oKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdHVjbC5kZWZpbmVQYWNrYWdlKHBhY2thZ2VOYW1lICsgIjAiLCBtYW5pZmVzdCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgVGVzdFVSTENsYXNzTG9hZGVyIGV4dGVuZHMgVVJMQ2xhc3NMb2FkZXIgeworICAgICAgICBwdWJsaWMgVGVzdFVSTENsYXNzTG9hZGVyKFVSTFtdIHVybHMpIHsKKyAgICAgICAgICAgIHN1cGVyKHVybHMpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgYWRkVVJMKFVSTCB1cmwpIHsKKyAgICAgICAgICAgIHN1cGVyLmFkZFVSTCh1cmwpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFBhY2thZ2UgZGVmaW5lUGFja2FnZShTdHJpbmcgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYW5pZmVzdCBtYW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJMIHVybCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5kZWZpbmVQYWNrYWdlKG5hbWUsIG1hbiwgdXJsKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBDbGFzczw/PiBmaW5kQ2xhc3MoU3RyaW5nIG5hbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmZpbmRDbGFzcyhuYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCBQZXJtaXNzaW9uQ29sbGVjdGlvbiBnZXRQZXJtaXNzaW9ucyhDb2RlU291cmNlIGNvZGVzb3VyY2UpIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRQZXJtaXNzaW9ucyhjb2Rlc291cmNlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBTaWRlRWZmZWN0KCJTdXBwb3J0X1Rlc3RXZWJTZXJ2ZXIgcmVxdWlyZXMgaXNvbGF0aW9uLiIpCisgICAgcHVibGljIHZvaWQgdGVzdF9maW5kUmVzb3VyY2VMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbnQgcG9ydCA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICAgICAgRmlsZSB0bXAgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZXN0IiwgIi50eHQiKTsKKworICAgICAgICBTdXBwb3J0X1Rlc3RXZWJTZXJ2ZXIgc2VydmVyID0gbmV3IFN1cHBvcnRfVGVzdFdlYlNlcnZlcigpOworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBzZXJ2ZXIuaW5pdFNlcnZlcihwb3J0LCB0bXAuZ2V0QWJzb2x1dGVQYXRoKCksICJ0ZXh0L2h0bWwiKTsKKworICAgICAgICAgICAgVVJMW10gdXJscyA9IHsgbmV3IFVSTCgiaHR0cDovL2xvY2FsaG9zdDoiICsgcG9ydCArICIvIikgfTsKKyAgICAgICAgICAgIHVjbCA9IG5ldyBVUkxDbGFzc0xvYWRlcih1cmxzKTsKKyAgICAgICAgICAgIFVSTCByZXMgPSB1Y2wuZmluZFJlc291cmNlKCJ0ZXN0MSIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiRmFpbGVkIHRvIGxvY2F0ZSByZXNvdXJjZSIsIHJlcyk7CisKKyAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBzYiA9IGdldFJlc0NvbnRlbnQocmVzKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHJlc291cmNlIiwgbmV3IFN0cmluZyhTdXBwb3J0X1Rlc3RXZWJEYXRhLnRlc3QxKSwKKyAgICAgICAgICAgICAgICAgICAgc2IudG9TdHJpbmcoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzZXJ2ZXIuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlZ3Jlc3Npb24gZm9yIEhhcm1vbnktMjIzNworICAgICAqLworICAgIEBTaWRlRWZmZWN0KCJTdXBwb3J0X1Rlc3RXZWJTZXJ2ZXIgcmVxdWlyZXMgaXNvbGF0aW9uLiIpCisgICAgcHVibGljIHZvaWQgdGVzdF9maW5kUmVzb3VyY2VfU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgdGVtcEZpbGUxID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgidGV4dEZpbGUiLCAiLnR4dCIpOworICAgICAgICB0ZW1wRmlsZTEuY3JlYXRlTmV3RmlsZSgpOworICAgICAgICB0ZW1wRmlsZTEuZGVsZXRlT25FeGl0KCk7CisgICAgICAgIEZpbGUgdGVtcEZpbGUyID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiamFyRmlsZSIsICIuamFyIik7CisgICAgICAgIHRlbXBGaWxlMi5kZWxldGUoKTsKKyAgICAgICAgdGVtcEZpbGUyLmRlbGV0ZU9uRXhpdCgpOworCisgICAgICAgIFN1cHBvcnRfVGVzdFdlYlNlcnZlciBzZXJ2ZXIgPSBuZXcgU3VwcG9ydF9UZXN0V2ViU2VydmVyKCk7CisgICAgICAgIGludCBwb3J0ID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VydmVyLmluaXRTZXJ2ZXIocG9ydCwgZmFsc2UpOworCisgICAgICAgICAgICBTdHJpbmcgdGVtcFBhdGgxID0gdGVtcEZpbGUxLmdldFBhcmVudEZpbGUoKS5nZXRBYnNvbHV0ZVBhdGgoKSArICIvIjsKKyAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKAorICAgICAgICAgICAgICAgICAgICAiL3Rlc3RzL3Jlc291cmNlcy9oeXRzX3BhdGNoLmphciIpOworICAgICAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUxvY2FsRmlsZXRvKHRlbXBGaWxlMiwgaXMpOworICAgICAgICAgICAgU3RyaW5nIHRlbXBQYXRoMiA9IHRlbXBGaWxlMi5nZXRBYnNvbHV0ZVBhdGgoKTsKKyAgICAgICAgICAgIFN0cmluZyB0ZW1wUGF0aDMgPSAiaHR0cDovL2xvY2FsaG9zdDoiICsgcG9ydCArICIvIjsKKyAgICAgICAgICAgIFVSTENsYXNzTG9hZGVyIHVybExvYWRlciA9IGdldFVSTENsYXNzTG9hZGVyKHRlbXBQYXRoMSwgdGVtcFBhdGgyKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoIkZvdW5kIGluZXhpc3RhbnQgcmVzb3VyY2UiLAorICAgICAgICAgICAgICAgICAgICB1cmxMb2FkZXIuZmluZFJlc291cmNlKCJYWFgiKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJDb3VsZG4ndCBmaW5kIHJlc291cmNlIGZyb20gZGlyZWN0b3J5IiwKKyAgICAgICAgICAgICAgICAgICAgdXJsTG9hZGVyLmZpbmRSZXNvdXJjZSh0ZW1wRmlsZTEuZ2V0TmFtZSgpKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJDb3VsZG4ndCBmaW5kIHJlc291cmNlIGZyb20gamFyIiwKKyAgICAgICAgICAgICAgICAgICAgdXJsTG9hZGVyLmZpbmRSZXNvdXJjZSgiQmxhaC50eHQiKSk7CisgICAgICAgICAgICB1cmxMb2FkZXIgPSBnZXRVUkxDbGFzc0xvYWRlcih0ZW1wUGF0aDEsIHRlbXBQYXRoMiwgdGVtcFBhdGgzKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIkNvdWxkbid0IGZpbmQgcmVzb3VyY2UgZnJvbSB3ZWIiLAorICAgICAgICAgICAgICAgICAgICB1cmxMb2FkZXIuZmluZFJlc291cmNlKCJ0ZXN0MSIpKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoIkZvdW5kIGluZXhpc3RhbnQgcmVzb3VyY2UgZnJvbSB3ZWIiLAorICAgICAgICAgICAgICAgICAgICB1cmxMb2FkZXIuZmluZFJlc291cmNlKCJ0ZXN0MyIpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHNlcnZlci5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgVVJMQ2xhc3NMb2FkZXIgZ2V0VVJMQ2xhc3NMb2FkZXIoU3RyaW5nLi4uIGNsYXNzUGF0aCkKKyAgICAgICAgICAgIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgICAgICBMaXN0PFVSTD4gdXJsTGlzdCA9IG5ldyBBcnJheUxpc3Q8VVJMPigpOworICAgICAgICBmb3IgKFN0cmluZyBwYXRoIDogY2xhc3NQYXRoKSB7CisgICAgICAgICAgICBTdHJpbmcgdXJsOworICAgICAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUocGF0aCk7CisgICAgICAgICAgICBpZiAoZi5pc0RpcmVjdG9yeSgpKSB7CisgICAgICAgICAgICAgICAgdXJsID0gImZpbGU6IiArIHBhdGg7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHBhdGguc3RhcnRzV2l0aCgiaHR0cCIpKSB7CisgICAgICAgICAgICAgICAgdXJsID0gcGF0aDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdXJsID0gImphcjpmaWxlOiIgKyBwYXRoICsgIiEvIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHVybExpc3QuYWRkKG5ldyBVUkwodXJsKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBVUkxDbGFzc0xvYWRlcih1cmxMaXN0LnRvQXJyYXkobmV3IFVSTFt1cmxMaXN0LnNpemUoKV0pKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZ0J1ZmZlciBnZXRSZXNDb250ZW50KFVSTCByZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSByZXMub3BlblN0cmVhbSgpOworCisgICAgICAgIGludCBjOworICAgICAgICB3aGlsZSAoKGMgPSBpcy5yZWFkKCkpICE9IC0xKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoKGNoYXIpIGMpOworICAgICAgICB9CisgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIHJldHVybiBzYjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRVUkxTdHJlYW1IYW5kbGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkVVJMU3RyZWFtSGFuZGxlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NzM4NDIwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkVVJMU3RyZWFtSGFuZGxlclRlc3QuamF2YQpAQCAtMCwwICsxLDIzOCBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0NkFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlByb3h5OworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTFN0cmVhbUhhbmRsZXI7CitpbXBvcnQgamF2YS5uZXQuVW5rbm93bkhvc3RFeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkVVJMU3RyZWFtSGFuZGxlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBNb2NrVVJMU3RyZWFtSGFuZGxlciBoYW5kbGVyID0gbnVsbDsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzTGphdmFfbmV0X1VSTExqYXZhX25ldF9VUkwoKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybDEgPSBuZXcgVVJMKCJmdHA6Ly90ZXN0X3VybC90ZXN0P2E9YiZjPSVEMCslRDEiKTsKKyAgICAgICAgVVJMIHVybDIgPSBuZXcgVVJMKCJodHRwOi8vdGVzdF91cmwvdGVzdD9hPWImYz0lRDArJUQxIik7CisgICAgICAgIGFzc2VydEZhbHNlKHVybDEuZXF1YWxzKHVybDIpKTsKKworICAgICAgICBuZXcgVVJMKCJodHRwOi8vdGVzdF91cmwrL3Rlc3Q/YT1iJmM9JUQwKyVEMSIpOworICAgICAgICBhc3NlcnRGYWxzZShoYW5kbGVyLmVxdWFscyh1cmwxLHVybDIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoaGFuZGxlci5lcXVhbHMobnVsbCwgdXJsMSkpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERlZmF1bHRQb3J0KCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGhhbmRsZXIuZ2V0RGVmYXVsdFBvcnQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRIb3N0QWRkcmVzcygpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24sIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybDEgPSBuZXcgVVJMKCJmdHA6Ly90ZXN0X3VybC90ZXN0P2E9YiZjPSVEMCslRDEiKTsKKyAgICAgICAgYXNzZXJ0TnVsbChoYW5kbGVyLmdldEhvc3RBZGRyZXNzKHVybDEpKTsKKworICAgICAgICBVUkwgdXJsMiA9IG5ldyBVUkwoImh0dHA6Ly90ZXN0OnB3ZEBmYWtlaG9zdG5hbWUuZmFrZWRvbWFpbi90ZXN0P2E9YiZjPSVEMCslRDEiKTsKKyAgICAgICAgYXNzZXJ0TnVsbChoYW5kbGVyLmdldEhvc3RBZGRyZXNzKHVybDIpKTsKKworICAgICAgICBVUkwgdXJsMyA9IG5ldyBVUkwoImh0dHA6Ly9sb2NhbGhvc3QvdGVzdCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoSW5ldEFkZHJlc3MuZ2V0QnlOYW1lKCJsb2NhbGhvc3QiKSwgaGFuZGxlci5nZXRIb3N0QWRkcmVzcyh1cmwzKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZUxqYXZhX25ldF9VUkwoKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybDEgPSBuZXcgVVJMKCJmdHA6Ly90ZXN0X3VybC90ZXN0P2E9YiZjPSVEMCslRDEiKTsKKyAgICAgICAgVVJMIHVybDIgPSBuZXcgVVJMKCJodHRwOi8vdGVzdF91cmwvdGVzdD9hPWImYz0lRDArJUQxIik7CisgICAgICAgIGFzc2VydFRydWUoaGFuZGxlci5oYXNoQ29kZSh1cmwxKSAhPSBoYW5kbGVyLmhhc2hDb2RlKHVybDIpKTsKKworICAgICAgICBuZXcgVVJMKCJodHRwOi8vdGVzdF91cmwrL3Rlc3Q/YT1iJmM9JUQwKyVEMSIpOworICAgICAgICBhc3NlcnRGYWxzZShoYW5kbGVyLmVxdWFscyh1cmwxLHVybDIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaGFuZGxlci5oYXNoQ29kZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hvc3RzRXF1YWxMamF2YV9uZXRfVVJMTGphdmFfbmV0X1VSTCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsMSA9IG5ldyBVUkwoImZ0cDovL2xvY2FsaG9zdDoyMS8qdGVzdCIpOworICAgICAgICBVUkwgdXJsMiA9IG5ldyBVUkwoImh0dHA6Ly9sb2NhbGhvc3QvX3Rlc3QiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShoYW5kbGVyLmhvc3RzRXF1YWwodXJsMSwgdXJsMikpOworCisgICAgICAgIFVSTCB1cmwzID0gbmV3IFVSTCgiaHR0cDovL2Zvby9fdGVzdF9nb28iKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoaGFuZGxlci5ob3N0c0VxdWFsKHVybDEsIHVybDMpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X29wZW5Db25uZWN0aW9uTGphdmFfbmV0X1VSTCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIGFic3RyYWN0IG1ldGhvZCwgaXQgZG9lc24ndCBjaGVjayBhbnl0aGluZworICAgICAgICBhc3NlcnROdWxsKGhhbmRsZXIub3BlbkNvbm5lY3Rpb24obnVsbCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfb3BlbkNvbm5lY3Rpb25MamF2YV9uZXRfVVJMTGphdmFfbmV0X1Byb3h5KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaGFuZGxlci5vcGVuQ29ubmVjdGlvbihudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uICB1b2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcGFyc2VVUkxMamF2YV9uZXRfVVJMTGphdmFfbGFuZ19TdHJpbmdJSSgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHN0ciAgPSAiaHR0cDovL3Rlc3Qub3JnL2Zvbz9hPTEyMyZiPSVENUQ2RDcmYz0rKyZkPSI7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vdGVzdC5vcmciKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaGFuZGxlci5wYXJzZVVSTCh1cmwsIHN0ciwgMCwgc3RyLmxlbmd0aCgpKTsKKyAgICAgICAgICAgIGZhaWwoIlNlY3VyaXR5RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goU2VjdXJpdHlFeGNlcHRpb24gc2UpIHsKKyAgICAgICAgICAgIC8vU2VjdXJpdHlFeGNlcHRpb24gaXMgZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2FtZUZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybDEgID0gbmV3IFVSTCgiaHR0cDovL3Rlc3Q6cHdkQGxvY2FsaG9zdDo4MC9mb28vZm9vMS5jIik7CisgICAgICAgIFVSTCB1cmwyICA9IG5ldyBVUkwoImh0dHA6Ly90ZXN0OnB3ZEBsb2NhbGhvc3Q6ODAvZm9vL2ZvbzEuYyIpOworICAgICAgICBVUkwgdXJsMyAgPSBuZXcgVVJMKCJodHRwOi8vdGVzdDpwd2RAbG9jYWxob3N0OjgwL2Zvby9mb28yLmMiKTsKKyAgICAgICAgVVJMIHVybDQgID0gbmV3IFVSTCgiZnRwOi8vdGVzdDpwd2RAbG9jYWxob3N0OjIxL2Zvby9mb28yLmMiKTsKKyAgICAgICAgVVJMIHVybDUgID0gbmV3IFVSTCgiZnRwOi8vdGVzdDpwd2RAbG9jYWxob3N0OjIxL2Zvby9mb28xL2ZvbzIuYyIpOworICAgICAgICBVUkwgdXJsNiAgPSBuZXcgVVJMKCJodHRwOi8vdGVzdC9mb28vZm9vMS5jIik7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCBjYXNlIDEiLCBoYW5kbGVyLnNhbWVGaWxlKHVybDEsIHVybDIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRlc3QgY2FzZSAyIiwgaGFuZGxlci5zYW1lRmlsZSh1cmwzLCB1cmwyKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUZXN0IGNhc2UgMyIsIGhhbmRsZXIuc2FtZUZpbGUodXJsMywgdXJsNCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiVGVzdCBjYXNlIDQiLCBoYW5kbGVyLnNhbWVGaWxlKHVybDQsIHVybDUpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRlc3QgY2FzZSA1IiwgaGFuZGxlci5zYW1lRmlsZSh1cmwxLCB1cmw2KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRVUkwxKCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vdGVzdC5vcmciKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaGFuZGxlci5zZXRVUkwodXJsLCAiaHR0cCIsICJsb2NhbGhvc3QiLCA4MCwgImZvby5jIiwgInJlZiIpOworICAgICAgICAgICAgZmFpbCgiU2VjdXJpdHlFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChTZWN1cml0eUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRVUkwyKCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vdGVzdC5vcmciKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaGFuZGxlci5zZXRVUkwodXJsLCAiaHR0cCIsICJsb2NhbGhvc3QiLCA4MCwgImF1dGhvcml0eSIsCisgICAgICAgICAgICAgICAgICAgICJ1c2VyIiwgImZvby5jIiwgInF1ZXJ5IiwgInJlZiIpOworICAgICAgICAgICAgZmFpbCgiU2VjdXJpdHlFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChTZWN1cml0eUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90b0V4dGVybmFsRm9ybSgpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgICAgICBVUkwgW10gdXJscyA9IHsgbmV3IFVSTCgiZnRwOi8vdGVzdF91cmwvdGVzdD9hPWImYz0lRDArJUQxIiksCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVVJMKCJodHRwOi8vdGVzdF91cmwvdGVzdD9hPWImYz0lRDArJUQxIiksCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVVJMKCJodHRwOi8vdGVzdDpwd2RAbG9jYWxob3N0OjgwL2Zvby9mb28xLmMiKX07CisKKyAgICAgICAgZm9yKFVSTCB1cmwgOiB1cmxzKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgY2FzZSBmb3IgIiArIHVybC50b1N0cmluZygpLAorICAgICAgICAgICAgICAgICAgICB1cmwudG9TdHJpbmcoKSwgaGFuZGxlci50b0V4dGVybmFsRm9ybSh1cmwpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB7CisgICAgICAgIE1vY2tVUkxTdHJlYW1IYW5kbGVyIG1zaCA9IG5ldyBNb2NrVVJMU3RyZWFtSGFuZGxlcigpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIG1zaC5nZXREZWZhdWx0UG9ydCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgaGFuZGxlciA9IG5ldyBNb2NrVVJMU3RyZWFtSGFuZGxlcigpOworICAgIH0KKworICAgIGNsYXNzIE1vY2tVUkxTdHJlYW1IYW5kbGVyIGV4dGVuZHMgVVJMU3RyZWFtSGFuZGxlciB7CisKKyAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBVUkxDb25uZWN0aW9uIG9wZW5Db25uZWN0aW9uKFVSTCBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKFVSTCBhLCBVUkwgYikgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhhLCBiKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IGdldERlZmF1bHRQb3J0KCkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldERlZmF1bHRQb3J0KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEluZXRBZGRyZXNzIGdldEhvc3RBZGRyZXNzKFVSTCB1KSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0SG9zdEFkZHJlc3ModSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZShVUkwgdSkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmhhc2hDb2RlKHUpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhvc3RzRXF1YWwoVVJMIGEsIFVSTCBiKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuaG9zdHNFcXVhbChhLCBiKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgVVJMQ29ubmVjdGlvbiBvcGVuQ29ubmVjdGlvbihVUkwgdSwgUHJveHkgcCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5vcGVuQ29ubmVjdGlvbih1LCBwKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBwYXJzZVVSTChVUkwgdXJsLCBTdHJpbmcgc3BlYywgaW50IHN0YXJ0LCBpbnQgbGltaXQpIHsKKyAgICAgICAgICAgIHN1cGVyLnBhcnNlVVJMKHVybCwgc3BlYywgc3RhcnQsIGxpbWl0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBzYW1lRmlsZShVUkwgYSwgVVJMIGIpIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5zYW1lRmlsZShhLCBiKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBzZXRVUkwoVVJMIHUsCisgICAgICAgICAgICAgICAgU3RyaW5nIHByb3RvY29sLAorICAgICAgICAgICAgICAgIFN0cmluZyBob3N0LAorICAgICAgICAgICAgICAgIGludCBwb3J0LAorICAgICAgICAgICAgICAgIFN0cmluZyBmaWxlLAorICAgICAgICAgICAgICAgIFN0cmluZyByZWYpIHsKKyAgICAgICAgICAgIHN1cGVyLnNldFVSTCh1LCBwcm90b2NvbCwgaG9zdCwgcG9ydCwgZmlsZSwgcmVmKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBzZXRVUkwoVVJMIHUsCisgICAgICAgICAgICAgICAgU3RyaW5nIHByb3RvY29sLAorICAgICAgICAgICAgICAgIFN0cmluZyBob3N0LAorICAgICAgICAgICAgICAgIGludCBwb3J0LAorICAgICAgICAgICAgICAgIFN0cmluZyBhdXRob3JpdHksCisgICAgICAgICAgICAgICAgU3RyaW5nIHVzZXJJbmZvLAorICAgICAgICAgICAgICAgIFN0cmluZyBwYXRoLAorICAgICAgICAgICAgICAgIFN0cmluZyBxdWVyeSwKKyAgICAgICAgICAgICAgICBTdHJpbmcgcmVmKSB7CisgICAgICAgICAgICBzdXBlci5zZXRVUkwodSwgcHJvdG9jb2wsIGhvc3QsIHBvcnQsIGF1dGhvcml0eSwKKyAgICAgICAgICAgICAgICAgICAgdXNlckluZm8sIHBhdGgsIHF1ZXJ5LCByZWYpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9FeHRlcm5hbEZvcm0oVVJMIHUpIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci50b0V4dGVybmFsRm9ybSh1KTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZFVSTFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZFVSTFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYTRmNGNiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvT2xkVVJMVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzk5IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyOworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRXcml0ZXI7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZVdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKK2ltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuUHJveHk7CitpbXBvcnQgamF2YS5uZXQuUHJveHlTZWxlY3RvcjsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlVSSTsKK2ltcG9ydCBqYXZhLm5ldC5VUklTeW50YXhFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEubmV0LlVSTENvbm5lY3Rpb247CitpbXBvcnQgamF2YS5uZXQuVVJMU3RyZWFtSGFuZGxlcjsKK2ltcG9ydCBqYXZhLm5ldC5VUkxTdHJlYW1IYW5kbGVyRmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZFVSTFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgaGVsbG9Xb3JsZFN0cmluZyA9ICJIZWxsbyBXb3JsZCI7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZ0lMamF2YV9sYW5nX1N0cmluZygpCisgICAgICAgICAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS04MworICAgICAgICBuZXcgVVJMKCJodHRwIiwgImFwYWNoZS5vcmciLCAxMjM0NTY3ODksICJmaWxlIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVVJMKCJodHRwIiwgImFwYWNoZS5vcmciLCAtMTIzLCAiZmlsZSIpOworICAgICAgICAgICAgZmFpbCgiQXNzZXJ0IDA6IE5lZ2F0aXZlIHBvcnQgc2hvdWxkIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gU3RyYW5nZSBiZWhhdmlvciBpbiByZWZlcmVuY2UsIHRoZSBob3N0bmFtZSBjb250YWlucyBhICc6JyBzbyBpdCBnZXRzIHdyYXBwZWQgaW4gJ1snLCAnXScKKyAgICAgICAgVVJMIHRlc3RVUkwgPSBuZXcgVVJMKCJodHRwIiwgInd3dy5hcGFjaGUub3JnOjgwODIiLCAidGVzdC5odG1sI2FuY2giKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBc3NlcnQgMDogd3JvbmcgcHJvdG9jb2wiLCAiaHR0cCIsIHRlc3RVUkwuZ2V0UHJvdG9jb2woKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQXNzZXJ0IDE6IHdyb25nIGhvc3QiLCAiW3d3dy5hcGFjaGUub3JnOjgwODJdIiwgdGVzdFVSTC5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFzc2VydCAyOiB3cm9uZyBwb3J0IiwgLTEsIHRlc3RVUkwuZ2V0UG9ydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBc3NlcnQgMzogd3JvbmcgZmlsZSIsICIvdGVzdC5odG1sIiwgdGVzdFVSTC5nZXRGaWxlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFzc2VydCA0OiB3cm9uZyBhbmNob3IiLCAiYW5jaCIsIHRlc3RVUkwuZ2V0UmVmKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVVJMKCJoZnRwIiwgImFwYWNoZS5vcmc6ODA4MiIsICJ0ZXN0Lmh0bWwjYW5jaCIpOworICAgICAgICAgICAgZmFpbCgiQXNzZXJ0IDA6IEludmFsaWQgcHJvdG9jb2wiKTsKKyAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2phdmFfcHJvdG9jb2xfaGFuZGxlcl9wa2dzX3Byb3AoKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gUmVncmVzc2lvbiB0ZXN0IGZvciBIYXJtb255LTMwOTQKKyAgICAgICAgZmluYWwgU3RyaW5nIEhBTkRMRVJfUEtHUyA9ICJqYXZhLnByb3RvY29sLmhhbmRsZXIucGtncyI7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eShIQU5ETEVSX1BLR1MsICJmYWtlfG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmphdmEubmV0Iik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBVUkwoInRlc3RfcHJvdG9jb2wiLCAiIiwgImZha2UuamFyIik7CisgICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEhhc2hDb2RlKCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB0ZXN0VVJMMSA9IG5ldyBVUkwoImh0dHAiLCAid3d3LmFwYWNoZS5vcmc6ODA4MCIsICJ0ZXN0Lmh0bWwjYW5jaCIpOworICAgICAgICBVUkwgdGVzdFVSTDIgPSBuZXcgVVJMKCJodHRwIiwgInd3dy5hcGFjaGUub3JnOjgwODAiLCAidGVzdC5odG1sI2FuY2giKTsKKyAgICAgICAgVVJMIGNoYW5nZWRVUkwgPSBuZXcgVVJMKCJodHRwIiwgInd3dy5hcGFjaGUub3JnOjgwODIiLAorICAgICAgICAgICAgICAgICJ0ZXN0Lmh0bWwjYW5jaCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFzc2VydCAwOiBlcnJvciBpbiBoYXNoQ29kZTogbm90IHNhbWUiLAorICAgICAgICAgICAgICAgIHRlc3RVUkwxLmhhc2hDb2RlKCksIHRlc3RVUkwyLmhhc2hDb2RlKCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiQXNzZXJ0IDA6IGVycm9yIGluIGhhc2hDb2RlOiBzaG91bGQgYmUgc2FtZSIsIHRlc3RVUkwxCisgICAgICAgICAgICAgICAgLmhhc2hDb2RlKCkgPT0gY2hhbmdlZFVSTC5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0VVJMU3RyZWFtSGFuZGxlckZhY3RvcnkoKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMU3RyZWFtSGFuZGxlckZhY3RvcnkgZmFjdG9yeSA9IG5ldyBNeVVSTFN0cmVhbUhhbmRsZXJGYWN0b3J5KCk7CisgICAgICAgIEZpZWxkIHN0cmVhbUhhbmRsZXJGYWN0b3J5RmllbGQgPSBudWxsOworICAgICAgICBpbnQgY291bnRlciA9IDA7CisgICAgICAgIEZpbGUgc2FtcGxlRmlsZSA9IGNyZWF0ZVRlbXBIZWxsb1dvcmxkRmlsZSgpOworCisgICAgICAgIFVSTCBmaWxlVVJMID0gc2FtcGxlRmlsZS50b1VSTCgpOworCisKKyAgICAgICAgRmllbGRbXSBmaWVsZHMgPSBVUkwuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZHMoKTsKKworCisgICAgICAgIGZvciAoRmllbGQgZiA6IGZpZWxkcykgeworICAgICAgICAgICAgaWYgKFVSTFN0cmVhbUhhbmRsZXJGYWN0b3J5LmNsYXNzLmVxdWFscyhmLmdldFR5cGUoKSkpIHsKKyAgICAgICAgICAgICAgICBjb3VudGVyKys7CisgICAgICAgICAgICAgICAgc3RyZWFtSGFuZGxlckZhY3RvcnlGaWVsZCA9IGY7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoY291bnRlciAhPSAxKSB7CisgICAgICAgICAgICBmYWlsKCJFcnJvciBpbiB0ZXN0IHNldHVwOiBub3QgRmFjdG9yeSBmb3VuZCIpOworICAgICAgICB9CisKKyAgICAgICAgc3RyZWFtSGFuZGxlckZhY3RvcnlGaWVsZC5zZXRBY2Nlc3NpYmxlKHRydWUpOworICAgICAgICBVUkxTdHJlYW1IYW5kbGVyRmFjdG9yeSBvbGQgPSAoVVJMU3RyZWFtSGFuZGxlckZhY3RvcnkpIHN0cmVhbUhhbmRsZXJGYWN0b3J5RmllbGQuZ2V0KG51bGwpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdHJlYW1IYW5kbGVyRmFjdG9yeUZpZWxkLnNldChudWxsLCBmYWN0b3J5KTsKKyAgICAgICAgICAgIEJ1ZmZlcmVkUmVhZGVyIGJ1ZiA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoCisgICAgICAgICAgICAgICAgICAgIGZpbGVVUkwub3BlblN0cmVhbSgpKSwgaGVsbG9Xb3JsZFN0cmluZy5nZXRCeXRlcygpLmxlbmd0aCk7CisgICAgICAgICAgICBTdHJpbmcgbmV4dGxpbmU7CisgICAgICAgICAgICB3aGlsZSAoKG5leHRsaW5lID0gYnVmLnJlYWRMaW5lKCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaGVsbG9Xb3JsZFN0cmluZywgbmV4dGxpbmUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBidWYuY2xvc2UoKTsKKworICAgICAgICB9IGZpbmFsbHkgeworCisgICAgICAgICAgICBzdHJlYW1IYW5kbGVyRmFjdG9yeUZpZWxkLnNldChudWxsLCBvbGQpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VVJMU3RyaW5nKCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB0ZXN0VVJMID0gbmV3IFVSTCgiZnRwOi8vbXluYW1lQGhvc3QuZG9tL2V0Yy9tb3RkIik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBc3NlcnQgMDogd3JvbmcgcHJvdG9jb2wiLCAiZnRwIiwgdGVzdFVSTC5nZXRQcm90b2NvbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBc3NlcnQgMTogd3JvbmcgaG9zdCIsICJob3N0LmRvbSIsIHRlc3RVUkwuZ2V0SG9zdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBc3NlcnQgMjogd3JvbmcgcG9ydCIsIC0xLCB0ZXN0VVJMLmdldFBvcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQXNzZXJ0IDM6IHdyb25nIHVzZXJJbmZvIiwgIm15bmFtZSIsIHRlc3RVUkwKKyAgICAgICAgICAgICAgICAuZ2V0VXNlckluZm8oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQXNzZXJ0IDQ6IHdyb25nIHBhdGgiLCAiL2V0Yy9tb3RkIiwgdGVzdFVSTC5nZXRQYXRoKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVVJMKCJmdHBteW5hbWVAaG9zdC5kb20vZXRjL21vdGQiKTsKKyAgICAgICAgICAgIGZhaWwoIkFzc2VydCAwOiBtYWxmb3JtZWQgVVJMIHNob3VsZCB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVUkxVUkxTdHJpbmcoKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKworICAgICAgICBVUkwgZ2FtZWxhbiA9IG5ldyBVUkwoImh0dHA6Ly93d3cuZ2FtZWxhbi5jb20vcGFnZXMvIik7CisKKyAgICAgICAgVVJMIGdhbWVsYW5OZXR3b3JrID0gbmV3IFVSTChnYW1lbGFuLCAiR2FtZWxhbi5uZXQuaHRtbCIpOworICAgICAgICBVUkwgZ2FtZWxhbk5ldHdvcmtCb3R0b20gPSBuZXcgVVJMKGdhbWVsYW5OZXR3b3JrLCAiI0JPVFRPTSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFzc2VydCAwOiB3cm9uZyBhbmNob3IiLCAiQk9UVE9NIiwgZ2FtZWxhbk5ldHdvcmtCb3R0b20KKyAgICAgICAgICAgICAgICAuZ2V0UmVmKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFzc2VydCAxOiB3cm9uZyBwcm90b2NvbCIsICJodHRwIiwgZ2FtZWxhbk5ldHdvcmtCb3R0b20KKyAgICAgICAgICAgICAgICAuZ2V0UHJvdG9jb2woKSk7CisKKyAgICAgICAgLy8gc2FtZSBwcm90b2NvbAorICAgICAgICBVUkwgZ2FtZWxhbk5ldHdvckJvdHRvbTIgPSBuZXcgVVJMKGdhbWVsYW5OZXR3b3JrLAorICAgICAgICAgICAgICAgICJodHRwOi8vd3d3LmdhbWVsYW4uY29tL3BhZ2VzL0dhbWVsYW4ubmV0Lmh0bWwjQk9UVE9NIik7CisgICAgICAgIGFzc2VydEVxdWFscyhnYW1lbGFuTmV0d29yay5nZXRQcm90b2NvbCgpLCBnYW1lbGFuTmV0d29yQm90dG9tMi5nZXRQcm90b2NvbCgpKTsKKworICAgICAgICAvLyBjaGFuZ2VkIHByb3RvY29sCisgICAgICAgIFVSTCBnYW1lbGFuTmV0d29ya0JvdHRvbTMgPSBuZXcgVVJMKGdhbWVsYW5OZXR3b3JrLAorICAgICAgICAgICAgICAgICJmdHA6Ly93d3cuZ2FtZWxhbjIuY29tL3BhZ2VzL0dhbWVsYW4ubmV0Lmh0bWwjQk9UVE9NIik7CisgICAgICAgIFVSTCBhYnNvbHV0ZU5ldyA9IG5ldyBVUkwoCisgICAgICAgICAgICAgICAgImZ0cDovL3d3dy5nYW1lbGFuMi5jb20vcGFnZXMvR2FtZWxhbi5uZXQuaHRtbCNCT1RUT00iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJIb3N0IG9mIGNvbnRleHQgVVJMIGluc3RlYWQgb2YgbmV3IFVSTCIsICJmdHAiLAorICAgICAgICAgICAgICAgIGdhbWVsYW5OZXR3b3JrQm90dG9tMy5nZXRQcm90b2NvbCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVVJMIGlzIGNvbnRleHQgVVJMIGluc3RlYWQgb2YgbmV3IFVSTCIsCisgICAgICAgICAgICAgICAgZ2FtZWxhbk5ldHdvcmtCb3R0b20zLnNhbWVGaWxlKGFic29sdXRlTmV3KSk7CisKKyAgICAgICAgLy8gZXhjZXB0aW9uIHRlc3RpbmcKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHUgPSBudWxsOworICAgICAgICAgICAgdTEgPSBuZXcgVVJMKHUsICJzb21lZmlsZS5qYXZhIik7CisgICAgICAgICAgICBmYWlsKCJkaWRuJ3QgdGhyb3cgdGhlIGV4cGVjdGVkIE1hbEZvcm1lZFVSTEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgICAgIC8vIE5vbiBleGlzdGluZyBwcm90b2NvbAorICAgICAvLyBleGNlcHRpb24gdGVzdGluZworICAgICAgICB0cnkgeworICAgICAgICB1ICA9ICBuZXcgVVJMKGdhbWVsYW5OZXR3b3JrLAorICAgICAgICAgICAgICAgICAgICAic29tZUZhbmN5TmV3UHJvdDovL3d3dy5nYW1lbGFuMi5jb20vcGFnZXMvR2FtZWxhbi5uZXQuaHRtbCNCT1RUT00iKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgic29tZUZhbmN5TmV3UHJvdCIuZXF1YWxzSWdub3JlQ2FzZSh1LmdldFByb3RvY29sKCkpKTsKKyAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXF1YWxzT2JqZWN0KCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB0ZXN0VVJMMSA9IG5ldyBVUkwoImh0dHAiLCAid3d3LmFwYWNoZS5vcmciLCA4MDgwLCAidGVzdC5odG1sIik7CisgICAgICAgIFVSTCB3cm9uZ1Byb3RvID0gbmV3IFVSTCgiZnRwIiwgInd3dy5hcGFjaGUub3JnIiwgODA4MCwgInRlc3QuaHRtbCIpOworICAgICAgICBVUkwgd3JvbmdQb3J0ID0gbmV3IFVSTCgiaHR0cCIsICJ3d3cuYXBhY2hlLm9yZyIsIDgwODIsICJ0ZXN0Lmh0bWwiKTsKKyAgICAgICAgVVJMIHdyb25nSG9zdCA9IG5ldyBVUkwoImh0dHAiLCAid3d3LmFwYWNoZTIub3JnIiwgODA4MCwgInRlc3QuaHRtbCIpOworICAgICAgICBVUkwgd3JvbmdSZWYgPSBuZXcgVVJMKCJodHRwIiwgInd3dy5hcGFjaGUub3JnIiwgODA4MCwgInRlc3QyLmh0bWwjQk9UVE9NIik7CisgICAgICAgIFVSTCB0ZXN0VVJMMiA9IG5ldyBVUkwoImh0dHA6Ly93d3cuYXBhY2hlLm9yZzo4MDgwL3Rlc3QuaHRtbCIpOworCisgICAgICAgIGFzc2VydEZhbHNlKCJBc3NlcnQgMDogZXJyb3IgaW4gZXF1YWxzOiBub3Qgc2FtZSIsIHRlc3RVUkwxLmVxdWFscyh3cm9uZ1Byb3RvKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJBc3NlcnQgMTogZXJyb3IgaW4gZXF1YWxzOiBub3Qgc2FtZSIsIHRlc3RVUkwxLmVxdWFscyh3cm9uZ1BvcnQpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkFzc2VydCAyOiBlcnJvciBpbiBlcXVhbHM6IG5vdCBzYW1lIiwgdGVzdFVSTDEuZXF1YWxzKHdyb25nSG9zdCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiQXNzZXJ0IDM6IGVycm9yIGluIGVxdWFsczogbm90IHNhbWUiLCB0ZXN0VVJMMS5lcXVhbHMod3JvbmdSZWYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRlc3RVUkwxLCB0ZXN0VVJMMik7CisKKyAgICAgICAgVVJMIHRlc3RVUkwzID0gbmV3IFVSTCgiaHR0cCIsICJ3d3cuYXBhY2hlLm9yZyIsICIvdGVzdC5odG1sIik7CisgICAgICAgIFVSTCB0ZXN0VVJMNCA9IG5ldyBVUkwoImh0dHA6Ly93d3cuYXBhY2hlLm9yZy90ZXN0Lmh0bWwiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQXNzZXJ0IDQ6IGVycm9yIGluIGVxdWFsczogc2FtZSIsIHRlc3RVUkwzLmVxdWFscyh0ZXN0VVJMNCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTYW1lRmlsZSgpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgICAgICBVUkwgZ2FtZWxhbiA9IG5ldyBVUkwoImZpbGU6Ly8vcGFnZXMvaW5kZXguaHRtbCIpOworICAgICAgICBVUkwgZ2FtZWxhbkZhbHNlID0gbmV3IFVSTCgiZmlsZTovLy9wYWdlcy9vdXQvaW5kZXguaHRtbCIpOworCisgICAgICAgIFVSTCBnYW1lbGFuTmV0d29yayA9IG5ldyBVUkwoZ2FtZWxhbiwgIiNCT1RUT00iKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShnYW1lbGFuTmV0d29yay5zYW1lRmlsZShnYW1lbGFuKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoZ2FtZWxhbk5ldHdvcmsuc2FtZUZpbGUoZ2FtZWxhbkZhbHNlKSk7CisKKyAgICAgICAgLy8gbm9uIHRyaXZpYWwgdGVzdAorICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovL3dlYjIuamF2YXNvZnQuY29tL3NvbWUrZmlsZS5odG1sIik7CisgICAgICAgIFVSTCB1cmwxID0gbmV3IFVSTCgiaHR0cDovL3dlYjIuamF2YXNvZnQuY29tL3NvbWUlMjBmaWxlLmh0bWwiKTsKKworICAgICAgICBhc3NlcnRGYWxzZSh1cmwuc2FtZUZpbGUodXJsMSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDb250ZW50KCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisKKyAgICAgICAgRmlsZSBzYW1wbGVGaWxlID0gY3JlYXRlVGVtcEhlbGxvV29ybGRGaWxlKCk7CisKKyAgICAgICAgLy8gcmVhZCBjb250ZW50IGZyb20gZmlsZQorICAgICAgICBVUkwgZmlsZVVSTCA9IHNhbXBsZUZpbGUudG9VUkwoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW5wdXRTdHJlYW0gb3V0cHV0ID0gKElucHV0U3RyZWFtKSBmaWxlVVJMLmdldENvbnRlbnQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUob3V0cHV0LmF2YWlsYWJsZSgpID4gMCk7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRGlkIG5vdCBnZXQgb3V0cHV0IHR5cGUgZnJvbSBGaWxlIFVSTCIpOworICAgICAgICB9CisKKyAgICAgICAgLy9FeGNlcHRpb24gdGVzdAorICAgICAgICBVUkwgaW52YWxpZEZpbGUgPSBuZXcgVVJMKCJmaWxlOi8vL25vbmV4aXN0ZW50dGVzdGRpci90c3RmaWxlIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludmFsaWRGaWxlLmdldENvbnRlbnQoKTsKKyAgICAgICAgICAgIGZhaWwoIkFjY2VzcyB0byBpbnZhbGlkIGZpbGUgd29ya2VkIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE9wZW5TdHJlYW0oKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgRmlsZSBzYW1wbGVGaWxlID0gY3JlYXRlVGVtcEhlbGxvV29ybGRGaWxlKCk7CisKKyAgICAgICAgLy8gcmVhZCBjb250ZW50IGZyb20gZmlsZQorICAgICAgICBVUkwgZmlsZVVSTCA9IHNhbXBsZUZpbGUudG9VUkwoKTsKKyAgICAgICAgQnVmZmVyZWRSZWFkZXIgZGlzID0gbnVsbDsKKyAgICAgICAgU3RyaW5nIGlucHV0TGluZTsKKyAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoMzIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGlzID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKAorICAgICAgICAgICAgICAgICAgICBuZXcgSW5wdXRTdHJlYW1SZWFkZXIoZmlsZVVSTC5vcGVuU3RyZWFtKCkpLCAzMik7CisgICAgICAgICAgICB3aGlsZSAoKGlucHV0TGluZSA9IGRpcy5yZWFkTGluZSgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChpbnB1dExpbmUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZGlzLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXJyb3IgaW4gdGVzdCBzZXR1cDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydFRydWUoIkFzc2VydCAwOiBOb3RoaW5nIHdhcyByZWFkIGZyb20gZmlsZSAiLCBidWYubGVuZ3RoKCkgPiAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBc3NlcnQgMTogV3Jvbmcgc3RyZWFtIGNvbnRlbnQiLCAiSGVsbG8gV29ybGQiLCBidWYKKyAgICAgICAgICAgICAgICAudG9TdHJpbmcoKSk7CisKKyAgICAgICAgLy8gZXhjZXB0aW9uIHRlc3QKKworICAgICAgICBVUkwgaW52YWxpZEZpbGUgPSBuZXcgVVJMKCJmaWxlOi8vL25vbmV4aXN0ZW50dGVzdGRpci90c3RmaWxlIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRpcyA9IG5ldyBCdWZmZXJlZFJlYWRlcigKKyAgICAgICAgICAgICAgICAgICAgbmV3IElucHV0U3RyZWFtUmVhZGVyKGludmFsaWRGaWxlLm9wZW5TdHJlYW0oKSksIDMyKTsKKyAgICAgICAgICAgIHdoaWxlICgoaW5wdXRMaW5lID0gZGlzLnJlYWRMaW5lKCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGlucHV0TGluZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmYWlsKCJBY2Nlc3MgdG8gaW52YWxpZCBmaWxlIHdvcmtlZCIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZGlzLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T3BlbkNvbm5lY3Rpb24oKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgRmlsZSBzYW1wbGVGaWxlID0gY3JlYXRlVGVtcEhlbGxvV29ybGRGaWxlKCk7CisKKyAgICAgICAgYnl0ZVtdIGJhOworICAgICAgICBJbnB1dFN0cmVhbSBpczsKKyAgICAgICAgU3RyaW5nIHM7CisgICAgICAgIHUgPSBzYW1wbGVGaWxlLnRvVVJMKCk7CisgICAgICAgIHUub3BlbkNvbm5lY3Rpb24oKTsKKworICAgICAgICBpcyA9IChJbnB1dFN0cmVhbSkgdS5nZXRDb250ZW50KG5ldyBDbGFzc1tdIHsgT2JqZWN0LmNsYXNzIH0pOworICAgICAgICBpcy5yZWFkKGJhID0gbmV3IGJ5dGVbNDA5Nl0pOworICAgICAgICBzID0gbmV3IFN0cmluZyhiYSk7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBjb250ZW50ICIgKyB1CisgICAgICAgICAgICAgICAgKyAiIGRvZXMgbm90IGNvbnRhaW46IFwiSGVsbG8gV29ybGRcIiIsCisgICAgICAgICAgICAgICAgcy5pbmRleE9mKCJIZWxsbyBXb3JsZCIpID49IDApOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkwgdSA9IG5ldyBVUkwoImh0dHBzOi8vYS54eS5jb20vaW5kZXguaHRtbCIpOworICAgICAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uID0gdS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICAgICAgY29ubi5jb25uZWN0KCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgbm90IGJlIGFibGUgdG8gcmVhZCBmcm9tIHRoaXMgc2l0ZS4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRvVVJJKCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHRlc3RIVFRQVVJMU3RyaW5nID0gImh0dHA6Ly93d3cuZ2FtZWxhbi5jb20vcGFnZXMvIjsKKyAgICAgICAgU3RyaW5nIHRlc3RGVFBVUkxTdHJpbmcgPSAiZnRwOi8vbXluYW1lQGhvc3QuZG9tL2V0Yy9tb3RkIjsKKyAgICAgICAgVVJMIHRlc3RIVFRQVVJMID0gbmV3IFVSTCh0ZXN0SFRUUFVSTFN0cmluZyk7CisgICAgICAgIFVSTCB0ZXN0RlRQVVJMID0gbmV3IFVSTCh0ZXN0RlRQVVJMU3RyaW5nKTsKKworICAgICAgICBVUkkgdGVzdEhUVFBVUkkgPSB0ZXN0SFRUUFVSTC50b1VSSSgpOworICAgICAgICBVUkkgdGVzdEZUUFVSSSA9IHRlc3RGVFBVUkwudG9VUkkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRlc3RIVFRQVVJJLnRvU3RyaW5nKCksdGVzdEhUVFBVUkxTdHJpbmcpOworICAgICAgICBhc3NlcnRFcXVhbHModGVzdEZUUFVSSS50b1N0cmluZygpLHRlc3RGVFBVUkxTdHJpbmcpOworCisgICAgICAgIC8vRXhjZXB0aW9uIHRlc3QKKyAgICAgICAgU3RyaW5nW10gY29uc3RydWN0b3JUZXN0c0ludmFsaWQgPSBuZXcgU3RyaW5nW10geworICAgICAgICAgICAgICAgICJodHRwOi8vL2EgcGF0aCNmcmFnIiwgLy8gc3BhY2UgY2hhciBpbiBwYXRoLCBub3QgaW4gZXNjYXBlZAorICAgICAgICAgICAgICAgIC8vIG9jdGV0IGZvcm0sIHdpdGggbm8gaG9zdAorICAgICAgICAgICAgICAgICJodHRwOi8vaG9zdC9hW3BhdGgjZnJhZyIsIC8vIGFuIGlsbGVnYWwgY2hhciwgbm90IGluIGVzY2FwZWQKKyAgICAgICAgICAgICAgICAvLyBvY3RldCBmb3JtLCBzaG91bGQgdGhyb3cgYW4KKyAgICAgICAgICAgICAgICAvLyBleGNlcHRpb24KKyAgICAgICAgICAgICAgICAiaHR0cDovL2hvc3QvYSVwYXRoI2ZyYWciLCAvLyBpbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZSBpbiBwYXRoCisgICAgICAgICAgICAgICAgImh0dHA6Ly9ob3N0L2ElI2ZyYWciLCAvLyBpbmNvbXBsZXRlIGVzY2FwZSBzZXF1ZW5jZSBpbiBwYXRoCisKKyAgICAgICAgICAgICAgICAiaHR0cDovL2hvc3QjYSBmcmFnIiwgLy8gc3BhY2UgY2hhciBpbiBmcmFnbWVudCwgbm90IGluCisgICAgICAgICAgICAgICAgLy8gZXNjYXBlZCBvY3RldCBmb3JtLCBubyBwYXRoCisgICAgICAgICAgICAgICAgImh0dHA6Ly9ob3N0L2EjZnIjYWciLCAvLyBpbGxlZ2FsIGNoYXIgaW4gZnJhZ21lbnQKKyAgICAgICAgICAgICAgICAiaHR0cDovLy9wYXRoI2ZyJWFnIiwgLy8gaW52YWxpZCBlc2NhcGUgc2VxdWVuY2UgaW4gZnJhZ21lbnQsCisgICAgICAgICAgICAgICAgLy8gd2l0aCBubyBob3N0CisgICAgICAgICAgICAgICAgImh0dHA6Ly9ob3N0L3BhdGgjZnJhZyUiLCAvLyBpbmNvbXBsZXRlIGVzY2FwZSBzZXF1ZW5jZSBpbgorICAgICAgICAgICAgICAgIC8vIGZyYWdtZW50CisKKyAgICAgICAgICAgICAgICAiaHR0cDovL2hvc3QvcGF0aD9hIHF1ZXJ5I2ZyYWciLCAvLyBzcGFjZSBjaGFyIGluIHF1ZXJ5LCBub3QKKyAgICAgICAgICAgICAgICAvLyBpbiBlc2NhcGVkIG9jdGV0IGZvcm0KKyAgICAgICAgICAgICAgICAiaHR0cDovL2hvc3Q/cXVlcnklYWciLCAvLyBpbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZSBpbiBxdWVyeSwgbm8KKyAgICAgICAgICAgICAgICAvLyBwYXRoCisgICAgICAgICAgICAgICAgImh0dHA6Ly8vcGF0aD9xdWVyeSUiLCAvLyBpbmNvbXBsZXRlIGVzY2FwZSBzZXF1ZW5jZSBpbiBxdWVyeSwKKyAgICAgICAgICAgICAgICAvLyB3aXRoIG5vIGhvc3QKKworICAgICAgICAgICAgICAgICJtYWlsdG86dXNlcl5uYW1lQGZrbGtmLmNvbSIgLy8gaW52YWxpZCBjaGFyIGluIHNjaGVtZQorICAgICAgICB9OworCisgICAgICAgIGZvciAoU3RyaW5nIG1hbGZvcm1lZFVSSSA6IEFycmF5cy5hc0xpc3QoY29uc3RydWN0b3JUZXN0c0ludmFsaWQpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFVSTCB1cmxRdWVyeSA9IG5ldyBVUkwoImh0dHA6Ly9ob3N0L2ElcGF0aCNmcmFnIik7CisgICAgICAgICAgICAgICAgdXJsUXVlcnkudG9VUkkoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFVSSVN5bnRheEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUb1N0cmluZygpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgICAgICBVUkwgdGVzdEhUVFBVUkwgPSBuZXcgVVJMKCJodHRwOi8vd3d3LmdhbWVsYW4uY29tL3BhZ2VzLyIpOworICAgICAgICBVUkwgdGVzdEZUUFVSTCA9IG5ldyBVUkwoImZ0cDovL215bmFtZUBob3N0LmRvbS9ldGMvbW90ZCIpOworCisgICAgICAgIGFzc2VydEVxdWFscyh0ZXN0SFRUUFVSTC50b1N0cmluZygpLHRlc3RIVFRQVVJMLnRvRXh0ZXJuYWxGb3JtKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModGVzdEZUUFVSTC50b1N0cmluZygpLHRlc3RGVFBVUkwudG9FeHRlcm5hbEZvcm0oKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vd3d3LmdhbWVsYW4uY29tL3BhZ2VzLyIsIHRlc3RIVFRQVVJMLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUb0V4dGVybmFsRm9ybSgpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgICAgICBVUkwgdGVzdEhUVFBVUkwgPSBuZXcgVVJMKCJodHRwOi8vd3d3LmdhbWVsYW4uY29tL3BhZ2VzLyIpOworICAgICAgICBVUkwgdGVzdEZUUFVSTCA9IG5ldyBVUkwoImZ0cDovL215bmFtZUBob3N0LmRvbS9ldGMvbW90ZCIpOworCisgICAgICAgIGFzc2VydEVxdWFscyh0ZXN0SFRUUFVSTC50b1N0cmluZygpLHRlc3RIVFRQVVJMLnRvRXh0ZXJuYWxGb3JtKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModGVzdEZUUFVSTC50b1N0cmluZygpLHRlc3RGVFBVUkwudG9FeHRlcm5hbEZvcm0oKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vd3d3LmdhbWVsYW4uY29tL3BhZ2VzLyIsIHRlc3RIVFRQVVJMLnRvRXh0ZXJuYWxGb3JtKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRGaWxlKCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisKKyAgICAgICAgRmlsZSBzYW1wbGVGaWxlID0gY3JlYXRlVGVtcEhlbGxvV29ybGRGaWxlKCk7CisKKyAgICAgICAgLy8gcmVhZCBjb250ZW50IGZyb20gZmlsZQorICAgICAgICBVUkwgZmlsZVVSTCA9IHNhbXBsZUZpbGUudG9VUkwoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChmaWxlVVJMKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNhbXBsZUZpbGUuZ2V0UGF0aCgpLGZpbGVVUkwuZ2V0RmlsZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UG9ydCgpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgICAgICBVUkwgdGVzdEhUVFBVUkwgPSBuZXcgVVJMKCJodHRwOi8vd3d3LmdhbWVsYW4uY29tL3BhZ2VzLyIpOworICAgICAgICBVUkwgdGVzdEZUUFVSTCA9IG5ldyBVUkwoImZ0cDovL215bmFtZUBob3N0LmRvbS9ldGMvbW90ZCIpOworCisgICAgICAgIGFzc2VydEVxdWFscygtMSx0ZXN0RlRQVVJMLmdldFBvcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSx0ZXN0SFRUUFVSTC5nZXRQb3J0KCkpOworCisgICAgICAgIFVSTCB0ZXN0SFRUUFVSTDgwODIgPSBuZXcgVVJMKCJodHRwOi8vd3d3LmdhbWVsYW4uY29tOjgwODIvcGFnZXMvIik7CisgICAgICAgIGFzc2VydEVxdWFscyg4MDgyLCB0ZXN0SFRUUFVSTDgwODIuZ2V0UG9ydCgpKTsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQcm90b2NvbCgpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgICAgICBVUkwgdGVzdEhUVFBVUkwgPSBuZXcgVVJMKCJodHRwOi8vd3d3LmdhbWVsYW4uY29tL3BhZ2VzLyIpOworICAgICAgICBVUkwgdGVzdEhUVFBTVVJMID0gbmV3IFVSTCgiaHR0cHM6Ly93d3cuZ2FtZWxhbi5jb20vcGFnZXMvIik7CisgICAgICAgIFVSTCB0ZXN0RlRQVVJMID0gbmV3IFVSTCgiZnRwOi8vbXluYW1lQGhvc3QuZG9tL2V0Yy9tb3RkIik7CisgICAgICAgIFVSTCB0ZXN0RmlsZSA9IG5ldyBVUkwoImZpbGU6Ly8vcGFnZXMvaW5kZXguaHRtbCIpOworICAgICAgICBVUkwgdGVzdEphclVSTCA9IG5ldyBVUkwoImphcjpmaWxlOi8vL2Jhci5qYXIhL2Zvby5qYXIhL0J1Z3MvSGVsbG9Xb3JsZC5jbGFzcyIpOworCisgICAgICAgIGFzc2VydFRydWUoImh0dHAiLmVxdWFsc0lnbm9yZUNhc2UodGVzdEhUVFBVUkwuZ2V0UHJvdG9jb2woKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJodHRwcyIuZXF1YWxzSWdub3JlQ2FzZSh0ZXN0SFRUUFNVUkwuZ2V0UHJvdG9jb2woKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJmdHAiLmVxdWFsc0lnbm9yZUNhc2UodGVzdEZUUFVSTC5nZXRQcm90b2NvbCgpKSk7CisgICAgICAgIGFzc2VydFRydWUoImZpbGUiLmVxdWFsc0lnbm9yZUNhc2UodGVzdEZpbGUuZ2V0UHJvdG9jb2woKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJqYXIiLmVxdWFsc0lnbm9yZUNhc2UodGVzdEphclVSTC5nZXRQcm90b2NvbCgpKSk7CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UmVmKCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCBnYW1lbGFuID0gbmV3IFVSTCgiaHR0cDovL3d3dy5nYW1lbGFuLmNvbS9wYWdlcy8iKTsKKworICAgICAgICBTdHJpbmcgb3V0cHV0ID0gZ2FtZWxhbi5nZXRSZWYoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShvdXRwdXQgPT0gbnVsbCB8fCBvdXRwdXQuZXF1YWxzKCIiKSk7CisKKyAgICAgICAgVVJMIGdhbWVsYW5OZXR3b3JrID0gbmV3IFVSTChnYW1lbGFuLCAiR2FtZWxhbi5uZXQuaHRtbCNCT1RUT00iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCT1RUT00iLCBnYW1lbGFuTmV0d29yay5nZXRSZWYoKSk7CisKKyAgICAgICAgVVJMIGdhbWVsYW5OZXR3b3JrMiA9IG5ldyBVUkwoImh0dHAiLCAid3d3LmdhbWVsYW4uY29tIiwKKyAgICAgICAgICAgICAgICAiR2FtZWxhbi5uZXR3b3JrLmh0bWwjQk9UVE9NIik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCT1RUT00iLCBnYW1lbGFuTmV0d29yazIuZ2V0UmVmKCkpOworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFF1ZXJ5KCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmxRdWVyeSA9IG5ldyBVUkwoCisgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cuZXhhbXBsZS5jb20vaW5kZXguaHRtbD9hdHRyaWIxPXZhbHVlMSZhdHRyaWIyPXZhbHVlJmF0dHJpYjMjYW5jaG9yIik7CisgICAgICAgIFVSTCB1cmxOb1F1ZXJ5ID0gbmV3IFVSTCgKKyAgICAgICAgImh0dHA6Ly93d3cuZXhhbXBsZS5jb20vaW5kZXguaHRtbCNhbmNob3IiKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoImF0dHJpYjE9dmFsdWUxJmF0dHJpYjI9dmFsdWUmYXR0cmliMyIsIHVybFF1ZXJ5LmdldFF1ZXJ5KCkpOworCisgICAgICAgIFN0cmluZyBvdXRwdXQgPSB1cmxOb1F1ZXJ5LmdldFF1ZXJ5KCk7CisgICAgICAgIGFzc2VydFRydWUob3V0cHV0ID09IG51bGwgfHwgIiIuZXF1YWxzKG91dHB1dCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQYXRoKCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vd3d3LmV4YW1wbGUuY29tIik7CisgICAgICAgIFN0cmluZyBvdXRwdXQgPSB1cmwuZ2V0UGF0aCgpOworCisgICAgICAgIGFzc2VydFRydWUoIiIuZXF1YWxzKG91dHB1dCkgfHwgb3V0cHV0ID09IG51bGwpOworCisgICAgICAgIFVSTCB1cmwyID0gbmV3IFVSTCh1cmwsIi9mb28vaW5kZXguaHRtbCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9mb28vaW5kZXguaHRtbCIsdXJsMi5nZXRQYXRoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRVc2VySW5mbygpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsTm9Vc2VySW5mbyA9IG5ldyBVUkwoImh0dHA6Ly93d3cuamF2YTJzLmNvbTo4MDgwIik7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJmdHA6Ly9teVVzZXI6cGFzc3dvcmRAaG9zdC5kb20vZXRjL21vdGQiKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkFzc2VydCAwOiBXcm9uZyB1c2VyIiwibXlVc2VyOnBhc3N3b3JkIix1cmwuZ2V0VXNlckluZm8oKSk7CisgICAgICAgIFN0cmluZyB1c2VySW5mbyA9IHVybE5vVXNlckluZm8uZ2V0VXNlckluZm8oKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiIi5lcXVhbHModXNlckluZm8pIHx8IG51bGwgPT0gdXNlckluZm8pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRBdXRob3JpdHkoKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBVUklTeW50YXhFeGNlcHRpb24geworICAgICAgICAvLyBsZWdhbCBhdXRob3JpdHkgaW5mb3JtYXRpb24gdXNlckluZm8gKHVzZXIscGFzc3dvcmQpLGRvbWFpbixwb3J0CisKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6Ly93d3cuamF2YTJzLmNvbTo4MDgwIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQXNzZXJ0IDA6IFdyb25nIGF1dGhvcml0eSAiLCAid3d3LmphdmEycy5jb206ODA4MCIsIHVybAorICAgICAgICAgICAgICAgIC5nZXRBdXRob3JpdHkoKSk7CisKKyAgICAgICAgVVJMIGZ0cFVSTCA9IG5ldyBVUkwoImZ0cDovL215bmFtZUBob3N0LmRvbS9ldGMvbW90ZCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFzc2VydCAxOiBXcm9uZyBhdXRob3JpdHkgIiwgIm15bmFtZUBob3N0LmRvbSIsIGZ0cFVSTAorICAgICAgICAgICAgICAgIC5nZXRBdXRob3JpdHkoKSk7CisKKyAgICAgICAgVVJJIHRlc3RVUkkgPSBuZXcgVVJJKCIvcmVsYXRpdmUvVVJJL3dpdGgvYWJzb2x1dGUvcGF0aC90by9yZXNvdXJjZS50eHQiKTsKKyAgICAgICAgU3RyaW5nIG91dHB1dCA9IHRlc3RVUkkuZ2V0QXV0aG9yaXR5KCk7CisgICAgICAgIGFzc2VydFRydWUoIiIuZXF1YWxzKG91dHB1dCkgfHwgbnVsbCA9PSBvdXRwdXQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXREZWZhdWx0UG9ydCgpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgICAgICBVUkwgdGVzdEhUVFBVUkwgPSBuZXcgVVJMKCJodHRwOi8vd3d3LmdhbWVsYW4uY29tL3BhZ2VzLyIpOworICAgICAgICBVUkwgdGVzdEZUUFVSTCA9IG5ldyBVUkwoImZ0cDovL215bmFtZUBob3N0LmRvbS9ldGMvbW90ZCIpOworCisgICAgICAgIGFzc2VydEVxdWFscygyMSx0ZXN0RlRQVVJMLmdldERlZmF1bHRQb3J0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoODAsdGVzdEhUVFBVUkwuZ2V0RGVmYXVsdFBvcnQoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBGaWxlIGNyZWF0ZVRlbXBIZWxsb1dvcmxkRmlsZSgpIHsKKyAgICAgICAgLy8gY3JlYXRlIGNvbnRlbnQgdG8gcmVhZAorICAgICAgICBGaWxlIHRtcERpciA9IG5ldyBGaWxlKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKSk7CisgICAgICAgIEZpbGUgc2FtcGxlRmlsZSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAodG1wRGlyLmlzRGlyZWN0b3J5KCkpIHsKKyAgICAgICAgICAgICAgICBzYW1wbGVGaWxlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgib3BlblN0cmVhbVRlc3QiLCAiLnR4dCIsCisgICAgICAgICAgICAgICAgICAgICAgICB0bXBEaXIpOworICAgICAgICAgICAgICAgIHNhbXBsZUZpbGUuZGVsZXRlT25FeGl0KCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZhaWwoIkVycm9yIGluIHRlc3Qgc2V0dXAgamF2YS5pby50bXBkaXIgZG9lcyBub3QgZXhpc3QiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgRmlsZVdyaXRlciBmc3RyZWFtID0gbmV3IEZpbGVXcml0ZXIoc2FtcGxlRmlsZSk7CisgICAgICAgICAgICBCdWZmZXJlZFdyaXRlciBvdXQgPSBuZXcgQnVmZmVyZWRXcml0ZXIoZnN0cmVhbSwgMzIpOworICAgICAgICAgICAgb3V0LndyaXRlKGhlbGxvV29ybGRTdHJpbmcpOworICAgICAgICAgICAgLy8gQ2xvc2UgdGhlIG91dHB1dCBzdHJlYW0KKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgey8vIENhdGNoIGV4Y2VwdGlvbiBpZiBhbnkKKyAgICAgICAgICAgIGZhaWwoIkVycm9yOiBpbiB0ZXN0IHNldHVwIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBzYW1wbGVGaWxlOworICAgIH0KKworICAgIC8vIHN0YXJ0IEhBUk1PTlkgYnJhbmNoCisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE15SGFuZGxlciBleHRlbmRzIFVSTFN0cmVhbUhhbmRsZXIgeworICAgICAgICBwcm90ZWN0ZWQgVVJMQ29ubmVjdGlvbiBvcGVuQ29ubmVjdGlvbihVUkwgdSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBVUkwgdTsKKworICAgIFVSTCB1MTsKKworICAgIFVSTCB1MjsKKworICAgIGJvb2xlYW4gY2F1Z2h0ID0gZmFsc2U7CisKKyAgICBzdGF0aWMgYm9vbGVhbiBpc1NlbGVjdENhbGxlZDsKKworCisKKyAgICBzdGF0aWMgY2xhc3MgTW9ja1Byb3h5U2VsZWN0b3IgZXh0ZW5kcyBQcm94eVNlbGVjdG9yIHsKKworICAgICAgICBwdWJsaWMgdm9pZCBjb25uZWN0RmFpbGVkKFVSSSB1cmksIFNvY2tldEFkZHJlc3Mgc2EsIElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJjb25uZWN0aW9uIGZhaWxlZCIpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIExpc3Q8UHJveHk+IHNlbGVjdChVUkkgdXJpKSB7CisgICAgICAgICAgICBpc1NlbGVjdENhbGxlZCA9IHRydWU7CisgICAgICAgICAgICBBcnJheUxpc3Q8UHJveHk+IHByb3h5TGlzdCA9IG5ldyBBcnJheUxpc3Q8UHJveHk+KDEpOworICAgICAgICAgICAgcHJveHlMaXN0LmFkZChQcm94eS5OT19QUk9YWSk7CisgICAgICAgICAgICByZXR1cm4gcHJveHlMaXN0OworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIE1vY2tTZWN1cml0eU1hbmFnZXIgZXh0ZW5kcyBTZWN1cml0eU1hbmFnZXIgeworCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrQ29ubmVjdChTdHJpbmcgaG9zdCwgaW50IHBvcnQpIHsKKyAgICAgICAgICAgIGlmICgiMTI3LjAuMC4xIi5lcXVhbHMoaG9zdCkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oInBlcm1pc3Npb24gaXMgbm90IGFsbG93ZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihQZXJtaXNzaW9uIHBlcm1pc3Npb24pIHsKKyAgICAgICAgICAgIGlmICgic2V0U2VjdXJpdHlNYW5hZ2VyIi5lcXVhbHMocGVybWlzc2lvbi5nZXROYW1lKCkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3VwZXIuY2hlY2tQZXJtaXNzaW9uKHBlcm1pc3Npb24pOworICAgICAgICB9CisKKyAgICB9CisKKworICAgIHN0YXRpYyBjbGFzcyBNeVVSTFN0cmVhbUhhbmRsZXIgZXh0ZW5kcyBVUkxTdHJlYW1IYW5kbGVyIHsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIFVSTENvbm5lY3Rpb24gb3BlbkNvbm5lY3Rpb24oVVJMIGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFVSTENvbm5lY3Rpb24gY29uID0gYXJnMC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICAgICAgICAgIGNvbi5zZXREb0lucHV0KHRydWUpOworICAgICAgICAgICAgICAgIGNvbi5jb25uZWN0KCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNvbjsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBwYXJzZShVUkwgdXJsLCBTdHJpbmcgc3BlYywgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgICAgICAgICAgICBwYXJzZVVSTCh1cmwsIHNwZWMsIHN0YXJ0LCBlbmQpOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIE15VVJMU3RyZWFtSGFuZGxlckZhY3RvcnkgaW1wbGVtZW50cyBVUkxTdHJlYW1IYW5kbGVyRmFjdG9yeSB7CisKKyAgICAgICAgcHVibGljIHN0YXRpYyBNeVVSTFN0cmVhbUhhbmRsZXIgaGFuZGxlciA9IG5ldyBNeVVSTFN0cmVhbUhhbmRsZXIoKTsKKworICAgICAgICBwdWJsaWMgVVJMU3RyZWFtSGFuZGxlciBjcmVhdGVVUkxTdHJlYW1IYW5kbGVyKFN0cmluZyBhcmcwKSB7CisgICAgICAgICAgICBoYW5kbGVyID0gbmV3IE15VVJMU3RyZWFtSGFuZGxlcigpOworICAgICAgICAgICAgcmV0dXJuIGhhbmRsZXI7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIFVSTFN0cmVhbUhhbmRsZXIgaW1wbGVtZW50YXRpb24gY2xhc3MgbmVjZXNzYXJ5IGZvciB0ZXN0cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGNsYXNzIFRlc3RVUkxTdHJlYW1IYW5kbGVyIGV4dGVuZHMgVVJMU3RyZWFtSGFuZGxlciB7CisgICAgICAgIHB1YmxpYyBVUkxDb25uZWN0aW9uIG9wZW5Db25uZWN0aW9uKFVSTCBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBVUkxDb25uZWN0aW9uIGNvbiA9IGFyZzAub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgICAgICBjb24uc2V0RG9JbnB1dCh0cnVlKTsKKyAgICAgICAgICAgICAgICBjb24uY29ubmVjdCgpOworICAgICAgICAgICAgICAgIHJldHVybiBjb247CisgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFVSTENvbm5lY3Rpb24gb3BlbkNvbm5lY3Rpb24oVVJMIGFyZzAsIFByb3h5IHByb3h5KQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIub3BlbkNvbm5lY3Rpb24odSwgcHJveHkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdJTGphdmFfbGFuZ19TdHJpbmdMamF2YV9uZXRfVVJMU3RyZWFtSGFuZGxlcigpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdSA9IG5ldyBVUkwoImh0dHAiLCAid3d3LnlhaG9vLmNvbSIsIDgwODAsICJ0ZXN0Lmh0bWwjZm9vIiwgbnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU1NJU0gxIHJldHVybnMgYSB3cm9uZyBwcm90b2NvbCIsICJodHRwIiwgdS5nZXRQcm90b2NvbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTU0lTSDEgcmV0dXJucyBhIHdyb25nIGhvc3QiLCAid3d3LnlhaG9vLmNvbSIsIHUKKyAgICAgICAgICAgICAgICAuZ2V0SG9zdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTU0lTSDEgcmV0dXJucyBhIHdyb25nIHBvcnQiLCA4MDgwLCB1LmdldFBvcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU1NJU0gxIHJldHVybnMgYSB3cm9uZyBmaWxlIiwgIi90ZXN0Lmh0bWwiLCB1LmdldEZpbGUoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlNTSVNIMSByZXR1cm5zIGEgd3JvbmcgYW5jaG9yOiAiICsgdS5nZXRSZWYoKSwgdS5nZXRSZWYoKQorICAgICAgICAgICAgICAgIC5lcXVhbHMoImZvbyIpKTsKKworICAgICAgICB1ID0gbmV3IFVSTCgiaHR0cCIsICJ3d3cueWFob28uY29tIiwgODA4MCwgInRlc3QuaHRtbCNmb28iLAorICAgICAgICAgICAgICAgIG5ldyBNeUhhbmRsZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU1NJU0gyIHJldHVybnMgYSB3cm9uZyBwcm90b2NvbCIsICJodHRwIiwgdS5nZXRQcm90b2NvbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTU0lTSDIgcmV0dXJucyBhIHdyb25nIGhvc3QiLCAid3d3LnlhaG9vLmNvbSIsIHUKKyAgICAgICAgICAgICAgICAuZ2V0SG9zdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTU0lTSDIgcmV0dXJucyBhIHdyb25nIHBvcnQiLCA4MDgwLCB1LmdldFBvcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU1NJU0gyIHJldHVybnMgYSB3cm9uZyBmaWxlIiwgIi90ZXN0Lmh0bWwiLCB1LmdldEZpbGUoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlNTSVNIMiByZXR1cm5zIGEgd3JvbmcgYW5jaG9yOiAiICsgdS5nZXRSZWYoKSwgdS5nZXRSZWYoKQorICAgICAgICAgICAgICAgIC5lcXVhbHMoImZvbyIpKTsKKworICAgICAgICBUZXN0VVJMU3RyZWFtSGFuZGxlciBsaCA9IG5ldyBUZXN0VVJMU3RyZWFtSGFuZGxlcigpOworICAgICAgICB1ID0gbmV3IFVSTCgiaHR0cCIsICJ3d3cueWFob28uY29tIiwgODA4MCwgInRlc3QuaHRtbCNmb28iLAorICAgICAgICAgICAgICAgIGxoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFVSTChudWxsLCAiMSIsIDAsICJmaWxlIiwgbGgpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkLCBidXQgbm90aGluZyB3YXMgdGhyb3duISIpOworICAgICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgICAgfQorCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDb250ZW50X0xKYXZhTGFuZ0NsYXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgRmlsZSBzYW1wbGVGaWxlID0gY3JlYXRlVGVtcEhlbGxvV29ybGRGaWxlKCk7CisKKyAgICAgICAgYnl0ZVtdIGJhOworICAgICAgICBTdHJpbmcgczsKKworICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG51bGw7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHUgPSBuZXcgVVJMKCJmaWxlOi8vL2RhdGEvdG1wL2h5dHNfaHRtbHRlc3QuaHRtbCIpOworICAgICAgICAgICAgaXMgPSAoSW5wdXRTdHJlYW0pIHUuZ2V0Q29udGVudChuZXcgQ2xhc3NbXSB7SW5wdXRTdHJlYW0uY2xhc3N9KTsKKyAgICAgICAgICAgIGlzLnJlYWQoYmEgPSBuZXcgYnl0ZVs0MDk2XSk7CisgICAgICAgICAgICBmYWlsKCJObyBlcnJvciBvY2N1cnJlZCByZWFkaW5nIGZyb20gbm9uZXhpc3RpbmcgZmlsZSIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHUgPSBuZXcgVVJMKCJmaWxlOi8vL2RhdGEvdG1wL2h5dHNfaHRtbHRlc3QuaHRtbCIpOworICAgICAgICAgICAgaXMgPSAoSW5wdXRTdHJlYW0pIHUuZ2V0Q29udGVudChuZXcgQ2xhc3NbXSB7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZy5jbGFzcywgSW5wdXRTdHJlYW0uY2xhc3N9KTsKKyAgICAgICAgICAgIGlzLnJlYWQoYmEgPSBuZXcgYnl0ZVs0MDk2XSk7CisgICAgICAgICAgICBmYWlsKCJObyBlcnJvciBvY2N1cnJlZCByZWFkaW5nIGZyb20gbm9uZXhpc3RpbmcgZmlsZSIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgLy8gQ2hlY2sgZm9yIG51bGwKKyAgICAgICAgdSA9IHNhbXBsZUZpbGUudG9VUkwoKTsKKyAgICAgICAgdS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBhc3NlcnROb3ROdWxsKHUpOworCisgICAgICAgIHMgPSAoU3RyaW5nKSB1LmdldENvbnRlbnQobmV3IENsYXNzW10ge1N0cmluZy5jbGFzc30pOworICAgICAgICBhc3NlcnROdWxsKHMpOworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFVSTFVSTFN0cmluZ1VSTFN0cmVhbUhhbmRsZXIoKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKyAgICAgICAgdSA9IG5ldyBVUkwoImh0dHA6Ly93d3cueWFob28uY29tIik7CisgICAgICAgIC8vIGJhc2ljIG9uZXMKKyAgICAgICAgdTEgPSBuZXcgVVJMKHUsICJmaWxlLmphdmEiLCBuZXcgTXlIYW5kbGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEgcmV0dXJucyBhIHdyb25nIHByb3RvY29sIiwgImh0dHAiLCB1MS5nZXRQcm90b2NvbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxIHJldHVybnMgYSB3cm9uZyBob3N0IiwgInd3dy55YWhvby5jb20iLCB1MS5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEgcmV0dXJucyBhIHdyb25nIHBvcnQiLCAtMSwgdTEuZ2V0UG9ydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxIHJldHVybnMgYSB3cm9uZyBmaWxlIiwgIi9maWxlLmphdmEiLCB1MS5nZXRGaWxlKCkpOworICAgICAgICBhc3NlcnROdWxsKCIxIHJldHVybnMgYSB3cm9uZyBhbmNob3IiLCB1MS5nZXRSZWYoKSk7CisKKyAgICAgICAgdTEgPSBuZXcgVVJMKHUsICJzeXN0ZW1yZXNvdXJjZTovKy9GSUxFMC90ZXN0LmphdmEiLCBuZXcgTXlIYW5kbGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjIgcmV0dXJucyBhIHdyb25nIHByb3RvY29sIiwgInN5c3RlbXJlc291cmNlIiwgdTEKKyAgICAgICAgICAgICAgICAuZ2V0UHJvdG9jb2woKSk7CisgICAgICAgIGFzc2VydFRydWUoIjIgcmV0dXJucyBhIHdyb25nIGhvc3QiLCB1MS5nZXRIb3N0KCkuZXF1YWxzKCIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMiByZXR1cm5zIGEgd3JvbmcgcG9ydCIsIC0xLCB1MS5nZXRQb3J0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjIgcmV0dXJucyBhIHdyb25nIGZpbGUiLCAiLysvRklMRTAvdGVzdC5qYXZhIiwgdTEKKyAgICAgICAgICAgICAgICAuZ2V0RmlsZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiMiByZXR1cm5zIGEgd3JvbmcgYW5jaG9yIiwgdTEuZ2V0UmVmKCkpOworCisgICAgICAgIHUxID0gbmV3IFVSTCh1LCAiZGlyMS9kaXIyLy4uL2ZpbGUuamF2YSIsIG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjMgcmV0dXJucyBhIHdyb25nIHByb3RvY29sIiwgImh0dHAiLCB1MS5nZXRQcm90b2NvbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIzIHJldHVybnMgYSB3cm9uZyBob3N0IiwgInd3dy55YWhvby5jb20iLCB1MS5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjMgcmV0dXJucyBhIHdyb25nIHBvcnQiLCAtMSwgdTEuZ2V0UG9ydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIzIHJldHVybnMgYSB3cm9uZyBmaWxlIiwgIi9kaXIxL2ZpbGUuamF2YSIsIHUxLmdldEZpbGUoKSk7CisgICAgICAgIGFzc2VydE51bGwoIjMgcmV0dXJucyBhIHdyb25nIGFuY2hvciIsIHUxLmdldFJlZigpKTsKKworICAgICAgICAvLyB0ZXN0IGZvciBxdWVzdGlvbiBtYXJrIHByb2Nlc3NpbmcKKyAgICAgICAgdSA9IG5ldyBVUkwoImh0dHA6Ly93d3cuZm9vLmNvbS9kMC9kMS9kMi9jZ2ktYmluP2Zvbz1iYXIvYmF6Iik7CisKKyAgICAgICAgLy8gdGVzdCBmb3IgcmVsYXRpdmUgZmlsZSBhbmQgb3V0IG9mIGJvdW5kICIvLi4vIiBwcm9jZXNzaW5nCisgICAgICAgIHUxID0gbmV3IFVSTCh1LCAiLi4vZGlyMS9kaXIyLy4uL2ZpbGUuamF2YSIsIG5ldyBNeUhhbmRsZXIoKSk7CisgICAgICAgIGFzc2VydFRydWUoIkEpIHJldHVybnMgYSB3cm9uZyBmaWxlOiAiICsgdTEuZ2V0RmlsZSgpLCB1MS5nZXRGaWxlKCkKKyAgICAgICAgICAgICAgICAuZXF1YWxzKCIvZDAvZDEvZGlyMS9maWxlLmphdmEiKSk7CisKKyAgICAgICAgLy8gdGVzdCBmb3IgYWJzb2x1dGUgYW5kIHJlbGF0aXZlIGZpbGUgcHJvY2Vzc2luZworICAgICAgICB1MSA9IG5ldyBVUkwodSwgIi8uLi9kaXIxL2RpcjIvLi4vZmlsZS5qYXZhIiwgbnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQikgcmV0dXJucyBhIHdyb25nIGZpbGUiLCAiL2RpcjEvZmlsZS5qYXZhIiwKKyAgICAgICAgICAgICAgICB1MS5nZXRGaWxlKCkpOworCisgICAgICAgIFVSTCBvbmU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvbmUgPSBuZXcgVVJMKCJodHRwOi8vd3d3LmlibS5jb20iKTsKKyAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAvLyBTaG91bGQgbm90IGhhcHBlbi4KKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBVUkwob25lLCAoU3RyaW5nKSBudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNwZWNpZnlpbmcgbnVsbCBzcGVjIG9uIFVSTCBjb25zdHJ1Y3RvciBzaG91bGQgdGhyb3cgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvRXh0ZXJuYWxGb3JtX1JlbGF0aXZlKCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzdHJVUkwgPSAiaHR0cDovL2EvYi9jL2Q7cD9xIjsKKyAgICAgICAgU3RyaW5nIHJlZiA9ICI/eSI7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKG5ldyBVUkwoc3RyVVJMKSwgcmVmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2MvZDtwP3kiLCB1cmwudG9FeHRlcm5hbEZvcm0oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90b0V4dGVybmFsRm9ybV9BYnNvbHV0ZSgpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc3RyVVJMID0gImh0dHA6Ly9sb2NhbGhvc3Q/bmFtZT12YWx1ZSI7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKHN0clVSTCk7CisgICAgICAgIGFzc2VydEVxdWFscyhzdHJVUkwsIHVybC50b0V4dGVybmFsRm9ybSgpKTsKKworICAgICAgICBzdHJVUkwgPSAiaHR0cDovL2xvY2FsaG9zdD9uYW1lPXZhbHVlL2FnZT0xMiI7CisgICAgICAgIHVybCA9IG5ldyBVUkwoc3RyVVJMKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHN0clVSTCwgdXJsLnRvRXh0ZXJuYWxGb3JtKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L09sZFVuaXhTb2NrZXRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRVbml4U29ja2V0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZkZmVkNTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9PbGRVbml4U29ja2V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTE2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuQ29ubmVjdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0U29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5TZXJ2ZXJTb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0OworaW1wb3J0IGphdmEubmV0LlNvY2tldEV4Y2VwdGlvbjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRVbml4U29ja2V0VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBTaW1wbGUgcmVhZC93cml0ZSB0ZXN0IG92ZXIgdGhlIElPIHN0cmVhbXMKKyAgICAgICAgZmluYWwgU2VydmVyU29ja2V0IHBpbmdTZXJ2ZXIgPSBuZXcgU2VydmVyU29ja2V0KDApOworICAgICAgICBTb2NrZXQgcGluZ0NsaWVudCA9IG5ldyBTb2NrZXQoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGluZ0NsaWVudC5jb25uZWN0KG5ldyBJbmV0U29ja2V0QWRkcmVzcygKKyAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHBpbmdTZXJ2ZXIuZ2V0TG9jYWxQb3J0KCkpKTsKKworICAgICAgICAgICAgU29ja2V0IHdvcmtlciA9IHBpbmdTZXJ2ZXIuYWNjZXB0KCk7CisgICAgICAgICAgICBwaW5nU2VydmVyLmNsb3NlKCk7CisKKyAgICAgICAgICAgIC8vIFdyaXRlIHNvbWUgZGF0YSB0byB0aGUgc2VydmVyIHRvIHByb3Zva2UgaXQKKyAgICAgICAgICAgIE91dHB1dFN0cmVhbSBjbGllbnRPdXQgPSBwaW5nQ2xpZW50LmdldE91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgY2xpZW50T3V0LndyaXRlKG5ldyBieXRlWzI1Nl0pOworICAgICAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSB3b3JrZXIuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGluLnJlYWQoKTsKKworICAgICAgICAgICAgT3V0cHV0U3RyZWFtIG91dCA9IHdvcmtlci5nZXRPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIG91dC53cml0ZShuZXcgYnl0ZVs0Ml0pOworICAgICAgICAgICAgd29ya2VyLmNsb3NlKCk7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBjbGllbnRJbiA9IHBpbmdDbGllbnQuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGNsaWVudEluLnJlYWQobmV3IGJ5dGVbNDJdKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpbnQgaSA9IGNsaWVudEluLnJlYWQoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgU29ja2V0RXhjZXB0aW9uOyBnb3QgaT0iICsgaSk7CisgICAgICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBjbGllbnRJbi5jbG9zZSgpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNsaWVudEluLnJlYWQoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgU29ja2V0RXhjZXB0aW9uIik7CisgICAgICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNsaWVudEluLnJlYWQobmV3IGJ5dGVbNV0pOworICAgICAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBTb2NrZXRFeGNlcHRpb24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHBpbmdDbGllbnQuY2xvc2UoKTsKKyAgICAgICAgICAgIHBpbmdTZXJ2ZXIuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY29ubmVjdExqYXZhX25ldF9Tb2NrZXRBZGRyZXNzSSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBOb3cgdmFsaWRhdGUgdGhhdCB3ZSBnZXQgYSBpbnRlcnJ1cHRlZCBleGNlcHRpb24gaWYgd2UgdHJ5IHRvIGNvbm5lY3QKKyAgICAgICAgLy8gdG8gYW4gYWRkcmVzcyBvbiB3aGljaCBub2JvZHkgaXMgYWNjZXB0aW5nIGNvbm5lY3Rpb25zIGFuZCB0aGUKKyAgICAgICAgLy8gdGltZW91dCBleHBpcmVkCisgICAgICAgIFNvY2tldCB0aGVTb2NrZXQgPSBuZXcgU29ja2V0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGVTb2NrZXQuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksCisgICAgICAgICAgICAgICAgICAgIDEpLCAyMDApOworICAgICAgICAgICAgZmFpbCgiTm8gaW50ZXJydXB0ZWQgZXhjZXB0aW9uIHdoZW4gY29ubmVjdGluZyB0byBhZGRyZXNzIG5vYm9keSBsaXN0ZW5pbmcgb24gd2l0aCBzaG9ydCB0aW1lb3V0IDIwMCIpOworICAgICAgICB9IGNhdGNoIChDb25uZWN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdGhlU29ja2V0LmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRPdXRwdXRTdHJlYW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gUmVncmVzc2lvbiB0ZXN0IGZvciBIQVJNT05ZLTI5MzQKKyAgICAgICAgLy8gUG9ydCAwIGlzIG5vdCBhbGxvd2VkIHRvIGJlIHVzZWQgaW4gY29ubmVjdCgpIG9uIHNvbWUgcGxhdGZvcm1zLAorICAgICAgICAvLyBnZXQgYSBmcmVlIHBvcnQgaGVyZQorICAgICAgICBTZXJ2ZXJTb2NrZXQgc3MgPSBuZXcgU2VydmVyU29ja2V0KDApOworICAgICAgICBpbnQgcG9ydCA9IHNzLmdldExvY2FsUG9ydCgpOworICAgICAgICBzcy5jbG9zZSgpOworCisgICAgICAgIFNvY2tldCBzb2NrZXQgPSBuZXcgU29ja2V0KCIxMjcuMC4wLjEiLCBwb3J0LCBmYWxzZSk7CisgICAgICAgIE91dHB1dFN0cmVhbSBvID0gc29ja2V0LmdldE91dHB1dFN0cmVhbSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgby53cml0ZSgxKTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L1Byb3h5U2VsZWN0b3JUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9Qcm94eVNlbGVjdG9yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ5MWNiOGQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9Qcm94eVNlbGVjdG9yVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjA3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmV0OworCitpbXBvcnQgc3RhdGljIGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzLmNyZWF0ZVVucmVzb2x2ZWQ7CitpbXBvcnQgamF2YS5uZXQuUHJveHk7CitpbXBvcnQgamF2YS5uZXQuUHJveHlTZWxlY3RvcjsKK2ltcG9ydCBqYXZhLm5ldC5VUkk7CitpbXBvcnQgamF2YS5uZXQuVVJJU3ludGF4RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgUHJveHlTZWxlY3RvclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIFByb3h5U2VsZWN0b3IgcHJveHlTZWxlY3RvcjsKKworICAgIHByaXZhdGUgVVJJIGh0dHBVcmk7CisgICAgcHJpdmF0ZSBVUkkgZnRwVXJpOworICAgIHByaXZhdGUgVVJJIGh0dHBzVXJpOworICAgIHByaXZhdGUgVVJJIHNvY2tldFVyaTsKKyAgICBwcml2YXRlIFVSSSBvdGhlclVyaTsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHByb3h5U2VsZWN0b3IgPSBQcm94eVNlbGVjdG9yLmdldERlZmF1bHQoKTsKKyAgICAgICAgaHR0cFVyaSA9IG5ldyBVUkkoImh0dHA6Ly9hbmRyb2lkLmNvbSIpOworICAgICAgICBmdHBVcmkgPSBuZXcgVVJJKCJmdHA6Ly9hbmRyb2lkLmNvbSIpOworICAgICAgICBodHRwc1VyaSA9IG5ldyBVUkkoImh0dHBzOi8vYW5kcm9pZC5jb20iKTsKKyAgICAgICAgc29ja2V0VXJpID0gbmV3IFVSSSgic29ja2V0Oi8vYW5kcm9pZC5jb20iKTsKKyAgICAgICAgb3RoZXJVcmkgPSBuZXcgVVJJKCJvdGhlcjovL2FuZHJvaWQuY29tIik7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN5c3RlbS5jbGVhclByb3BlcnR5KCJmdHAucHJveHlIb3N0Iik7CisgICAgICAgIFN5c3RlbS5jbGVhclByb3BlcnR5KCJmdHAucHJveHlQb3J0Iik7CisgICAgICAgIFN5c3RlbS5jbGVhclByb3BlcnR5KCJmdHAubm9uUHJveHlIb3N0cyIpOworICAgICAgICBTeXN0ZW0uY2xlYXJQcm9wZXJ0eSgiaHR0cC5wcm94eUhvc3QiKTsKKyAgICAgICAgU3lzdGVtLmNsZWFyUHJvcGVydHkoImh0dHAucHJveHlQb3J0Iik7CisgICAgICAgIFN5c3RlbS5jbGVhclByb3BlcnR5KCJodHRwLm5vblByb3h5SG9zdHMiKTsKKyAgICAgICAgU3lzdGVtLmNsZWFyUHJvcGVydHkoImh0dHBzLnByb3h5SG9zdCIpOworICAgICAgICBTeXN0ZW0uY2xlYXJQcm9wZXJ0eSgiaHR0cHMucHJveHlQb3J0Iik7CisgICAgICAgIFN5c3RlbS5jbGVhclByb3BlcnR5KCJodHRwcy5ub25Qcm94eUhvc3RzIik7CisgICAgICAgIFN5c3RlbS5jbGVhclByb3BlcnR5KCJvdGhlci5wcm94eUhvc3QiKTsKKyAgICAgICAgU3lzdGVtLmNsZWFyUHJvcGVydHkoIm90aGVyLnByb3h5UG9ydCIpOworICAgICAgICBTeXN0ZW0uY2xlYXJQcm9wZXJ0eSgic29ja2V0LnByb3h5SG9zdCIpOworICAgICAgICBTeXN0ZW0uY2xlYXJQcm9wZXJ0eSgic29ja2V0LnByb3h5UG9ydCIpOworICAgICAgICBTeXN0ZW0uY2xlYXJQcm9wZXJ0eSgicHJveHlIb3N0Iik7CisgICAgICAgIFN5c3RlbS5jbGVhclByb3BlcnR5KCJwcm94eVBvcnQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9Qcm94eVN5c3RlbVByb3BlcnR5KCkgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KFByb3h5Lk5PX1BST1hZKSwgcHJveHlTZWxlY3Rvci5zZWxlY3QoZnRwVXJpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KFByb3h5Lk5PX1BST1hZKSwgcHJveHlTZWxlY3Rvci5zZWxlY3QoaHR0cFVyaSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChQcm94eS5OT19QUk9YWSksIHByb3h5U2VsZWN0b3Iuc2VsZWN0KGh0dHBzVXJpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KFByb3h5Lk5PX1BST1hZKSwgcHJveHlTZWxlY3Rvci5zZWxlY3Qoc29ja2V0VXJpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KFByb3h5Lk5PX1BST1hZKSwgcHJveHlTZWxlY3Rvci5zZWxlY3Qob3RoZXJVcmkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJveHlIb3N0T25seSgpIHRocm93cyBVUklTeW50YXhFeGNlcHRpb24geworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoImZ0cC5wcm94eUhvc3QiLCAiYSIpOworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoImh0dHAucHJveHlIb3N0IiwgImIiKTsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJodHRwcy5wcm94eUhvc3QiLCAiYyIpOworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoIm90aGVyLnByb3h5SG9zdCIsICJkIik7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgic29ja2V0LnByb3h5SG9zdCIsICJkIik7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KG5ldyBQcm94eShQcm94eS5UeXBlLkhUVFAsIGNyZWF0ZVVucmVzb2x2ZWQoImEiLCA4MCkpKSwKKyAgICAgICAgICAgICAgICBwcm94eVNlbGVjdG9yLnNlbGVjdChmdHBVcmkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QobmV3IFByb3h5KFByb3h5LlR5cGUuSFRUUCwgY3JlYXRlVW5yZXNvbHZlZCgiYiIsIDgwKSkpLAorICAgICAgICAgICAgICAgIHByb3h5U2VsZWN0b3Iuc2VsZWN0KGh0dHBVcmkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QobmV3IFByb3h5KFByb3h5LlR5cGUuSFRUUCwgY3JlYXRlVW5yZXNvbHZlZCgiYyIsIDQ0MykpKSwKKyAgICAgICAgICAgICAgICBwcm94eVNlbGVjdG9yLnNlbGVjdChodHRwc1VyaSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChQcm94eS5OT19QUk9YWSksIHByb3h5U2VsZWN0b3Iuc2VsZWN0KG90aGVyVXJpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KFByb3h5Lk5PX1BST1hZKSwgcHJveHlTZWxlY3Rvci5zZWxlY3Qoc29ja2V0VXJpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFByb3h5SG9zdFBvcnQoKSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJmdHAucHJveHlIb3N0IiwgImEiKTsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJmdHAucHJveHlQb3J0IiwgIjEwMDEiKTsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJodHRwLnByb3h5SG9zdCIsICJiIik7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgiaHR0cC5wcm94eVBvcnQiLCAiMTAwMiIpOworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoImh0dHBzLnByb3h5SG9zdCIsICJjIik7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgiaHR0cHMucHJveHlQb3J0IiwgIjEwMDMiKTsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJvdGhlci5wcm94eUhvc3QiLCAiZCIpOworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoIm90aGVyLnByb3h5UG9ydCIsICIxMDA0Iik7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgic29ja2V0LnByb3h5SG9zdCIsICJlIik7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgic29ja2V0LnByb3h5UG9ydCIsICIxMDA1Iik7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KG5ldyBQcm94eShQcm94eS5UeXBlLkhUVFAsIGNyZWF0ZVVucmVzb2x2ZWQoImEiLCAxMDAxKSkpLAorICAgICAgICAgICAgICAgIHByb3h5U2VsZWN0b3Iuc2VsZWN0KGZ0cFVyaSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChuZXcgUHJveHkoUHJveHkuVHlwZS5IVFRQLCBjcmVhdGVVbnJlc29sdmVkKCJiIiwgMTAwMikpKSwKKyAgICAgICAgICAgICAgICBwcm94eVNlbGVjdG9yLnNlbGVjdChodHRwVXJpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KG5ldyBQcm94eShQcm94eS5UeXBlLkhUVFAsIGNyZWF0ZVVucmVzb2x2ZWQoImMiLCAxMDAzKSkpLAorICAgICAgICAgICAgICAgIHByb3h5U2VsZWN0b3Iuc2VsZWN0KGh0dHBzVXJpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KFByb3h5Lk5PX1BST1hZKSwgcHJveHlTZWxlY3Rvci5zZWxlY3Qoc29ja2V0VXJpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KFByb3h5Lk5PX1BST1hZKSwgcHJveHlTZWxlY3Rvci5zZWxlY3Qob3RoZXJVcmkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJveHlQb3J0T25seSgpIHRocm93cyBVUklTeW50YXhFeGNlcHRpb24geworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoImZ0cC5wcm94eVBvcnQiLCAiMTAwMSIpOworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoImh0dHAucHJveHlQb3J0IiwgIjEwMDIiKTsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJodHRwcy5wcm94eVBvcnQiLCAiMTAwMyIpOworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoIm90aGVyLnByb3h5UG9ydCIsICIxMDA0Iik7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgic29ja2V0LnByb3h5UG9ydCIsICIxMDA1Iik7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KFByb3h5Lk5PX1BST1hZKSwgcHJveHlTZWxlY3Rvci5zZWxlY3QoZnRwVXJpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KFByb3h5Lk5PX1BST1hZKSwgcHJveHlTZWxlY3Rvci5zZWxlY3QoaHR0cFVyaSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChQcm94eS5OT19QUk9YWSksIHByb3h5U2VsZWN0b3Iuc2VsZWN0KGh0dHBzVXJpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KFByb3h5Lk5PX1BST1hZKSwgcHJveHlTZWxlY3Rvci5zZWxlY3Qoc29ja2V0VXJpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KFByb3h5Lk5PX1BST1hZKSwgcHJveHlTZWxlY3Rvci5zZWxlY3Qob3RoZXJVcmkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SHR0cHNEb2VzTm90VXNlSHR0cFByb3BlcnRpZXMoKSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJodHRwLnByb3h5SG9zdCIsICJhIik7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgiaHR0cC5wcm94eVBvcnQiLCAiMTAwMSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChQcm94eS5OT19QUk9YWSksIHByb3h5U2VsZWN0b3Iuc2VsZWN0KGh0dHBzVXJpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFByb3h5SG9zdCgpIHRocm93cyBVUklTeW50YXhFeGNlcHRpb24geworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoInByb3h5SG9zdCIsICJhIik7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KG5ldyBQcm94eShQcm94eS5UeXBlLkhUVFAsIGNyZWF0ZVVucmVzb2x2ZWQoImEiLCA4MCkpKSwKKyAgICAgICAgICAgICAgICBwcm94eVNlbGVjdG9yLnNlbGVjdChmdHBVcmkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QobmV3IFByb3h5KFByb3h5LlR5cGUuSFRUUCwgY3JlYXRlVW5yZXNvbHZlZCgiYSIsIDgwKSkpLAorICAgICAgICAgICAgICAgIHByb3h5U2VsZWN0b3Iuc2VsZWN0KGh0dHBVcmkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QobmV3IFByb3h5KFByb3h5LlR5cGUuSFRUUCwgY3JlYXRlVW5yZXNvbHZlZCgiYSIsIDQ0MykpKSwKKyAgICAgICAgICAgICAgICBwcm94eVNlbGVjdG9yLnNlbGVjdChodHRwc1VyaSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChQcm94eS5OT19QUk9YWSksIHByb3h5U2VsZWN0b3Iuc2VsZWN0KHNvY2tldFVyaSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChQcm94eS5OT19QUk9YWSksIHByb3h5U2VsZWN0b3Iuc2VsZWN0KG90aGVyVXJpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEh0dHBQcm94eUhvc3RQcmVmZXJyZWRPdmVyUHJveHlIb3N0KCkgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgiaHR0cC5wcm94eUhvc3QiLCAiYSIpOworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoInByb3h5SG9zdCIsICJiIik7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KG5ldyBQcm94eShQcm94eS5UeXBlLkhUVFAsIGNyZWF0ZVVucmVzb2x2ZWQoImEiLCA4MCkpKSwKKyAgICAgICAgICAgICAgICBwcm94eVNlbGVjdG9yLnNlbGVjdChodHRwVXJpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNvY2tzUHJveHlIb3N0KCkgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgic29ja3NQcm94eUhvc3QiLCAiYSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChuZXcgUHJveHkoUHJveHkuVHlwZS5TT0NLUywgY3JlYXRlVW5yZXNvbHZlZCgiYSIsIDEwODApKSksCisgICAgICAgICAgICAgICAgcHJveHlTZWxlY3Rvci5zZWxlY3QoZnRwVXJpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KG5ldyBQcm94eShQcm94eS5UeXBlLlNPQ0tTLCBjcmVhdGVVbnJlc29sdmVkKCJhIiwgMTA4MCkpKSwKKyAgICAgICAgICAgICAgICBwcm94eVNlbGVjdG9yLnNlbGVjdChodHRwVXJpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KG5ldyBQcm94eShQcm94eS5UeXBlLlNPQ0tTLCBjcmVhdGVVbnJlc29sdmVkKCJhIiwgMTA4MCkpKSwKKyAgICAgICAgICAgICAgICBwcm94eVNlbGVjdG9yLnNlbGVjdChodHRwc1VyaSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChuZXcgUHJveHkoUHJveHkuVHlwZS5TT0NLUywgY3JlYXRlVW5yZXNvbHZlZCgiYSIsIDEwODApKSksCisgICAgICAgICAgICAgICAgcHJveHlTZWxlY3Rvci5zZWxlY3Qoc29ja2V0VXJpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KFByb3h5Lk5PX1BST1hZKSwgcHJveHlTZWxlY3Rvci5zZWxlY3Qob3RoZXJVcmkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U29ja3NQcm94eUhvc3RBbmRQb3J0KCkgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgic29ja3NQcm94eUhvc3QiLCAiYSIpOworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoInNvY2tzUHJveHlQb3J0IiwgIjEwMDEiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QobmV3IFByb3h5KFByb3h5LlR5cGUuU09DS1MsIGNyZWF0ZVVucmVzb2x2ZWQoImEiLCAxMDAxKSkpLAorICAgICAgICAgICAgICAgIHByb3h5U2VsZWN0b3Iuc2VsZWN0KGZ0cFVyaSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChuZXcgUHJveHkoUHJveHkuVHlwZS5TT0NLUywgY3JlYXRlVW5yZXNvbHZlZCgiYSIsIDEwMDEpKSksCisgICAgICAgICAgICAgICAgcHJveHlTZWxlY3Rvci5zZWxlY3QoaHR0cFVyaSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChuZXcgUHJveHkoUHJveHkuVHlwZS5TT0NLUywgY3JlYXRlVW5yZXNvbHZlZCgiYSIsIDEwMDEpKSksCisgICAgICAgICAgICAgICAgcHJveHlTZWxlY3Rvci5zZWxlY3QoaHR0cHNVcmkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QobmV3IFByb3h5KFByb3h5LlR5cGUuU09DS1MsIGNyZWF0ZVVucmVzb2x2ZWQoImEiLCAxMDAxKSkpLAorICAgICAgICAgICAgICAgIHByb3h5U2VsZWN0b3Iuc2VsZWN0KHNvY2tldFVyaSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChQcm94eS5OT19QUk9YWSksIHByb3h5U2VsZWN0b3Iuc2VsZWN0KG90aGVyVXJpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vblByb3h5SG9zdHNGdHAoKSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJmdHAubm9uUHJveHlIb3N0cyIsICIqLmNvbSIpOworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoImZ0cC5wcm94eUhvc3QiLCAiYSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChuZXcgUHJveHkoUHJveHkuVHlwZS5IVFRQLCBjcmVhdGVVbnJlc29sdmVkKCJhIiwgODApKSksCisgICAgICAgICAgICAgICAgcHJveHlTZWxlY3Rvci5zZWxlY3QobmV3IFVSSSgiZnRwOi8vZm9vLm5ldCIpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KFByb3h5Lk5PX1BST1hZKSwKKyAgICAgICAgICAgICAgICBwcm94eVNlbGVjdG9yLnNlbGVjdChuZXcgVVJJKCJmdHA6Ly9mb28uY29tIikpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9uUHJveHlIb3N0c0h0dHAoKSB0aHJvd3MgVVJJU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJodHRwLm5vblByb3h5SG9zdHMiLCAiKi5jb20iKTsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJodHRwLnByb3h5SG9zdCIsICJhIik7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KG5ldyBQcm94eShQcm94eS5UeXBlLkhUVFAsIGNyZWF0ZVVucmVzb2x2ZWQoImEiLCA4MCkpKSwKKyAgICAgICAgICAgICAgICBwcm94eVNlbGVjdG9yLnNlbGVjdChuZXcgVVJJKCJodHRwOi8vZm9vLm5ldCIpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KFByb3h5Lk5PX1BST1hZKSwKKyAgICAgICAgICAgICAgICBwcm94eVNlbGVjdG9yLnNlbGVjdChuZXcgVVJJKCJodHRwOi8vZm9vLmNvbSIpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vblByb3h5SG9zdHNIdHRwcygpIHRocm93cyBVUklTeW50YXhFeGNlcHRpb24geworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoImh0dHBzLm5vblByb3h5SG9zdHMiLCAiKi5jb20iKTsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJodHRwcy5wcm94eUhvc3QiLCAiYSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChuZXcgUHJveHkoUHJveHkuVHlwZS5IVFRQLCBjcmVhdGVVbnJlc29sdmVkKCJhIiwgNDQzKSkpLAorICAgICAgICAgICAgICAgIHByb3h5U2VsZWN0b3Iuc2VsZWN0KG5ldyBVUkkoImh0dHBzOi8vZm9vLm5ldCIpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KFByb3h5Lk5PX1BST1hZKSwKKyAgICAgICAgICAgICAgICBwcm94eVNlbGVjdG9yLnNlbGVjdChuZXcgVVJJKCJodHRwczovL2Zvby5jb20iKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTY2hlbWVDYXNlU2Vuc2l0aXZlKCkgdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgiaHR0cC5wcm94eUhvc3QiLCAiYSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChuZXcgUHJveHkoUHJveHkuVHlwZS5IVFRQLCBjcmVhdGVVbnJlc29sdmVkKCJhIiwgODApKSksCisgICAgICAgICAgICAgICAgcHJveHlTZWxlY3Rvci5zZWxlY3QobmV3IFVSSSgiSFRUUDovL2Zvby5uZXQiKSkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L1NlcnZlclNvY2tldFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L1NlcnZlclNvY2tldFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZTlkNDIzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvU2VydmVyU29ja2V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CisKK3B1YmxpYyBjbGFzcyBTZXJ2ZXJTb2NrZXRUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VGltZW91dEFmdGVyQWNjZXB0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFNlcnZlclNvY2tldCBzcyA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisgICAgICAgIHNzLnNldFJldXNlQWRkcmVzcyh0cnVlKTsKKyAgICAgICAgLy8gT24gVW5peCwgdGhlIHJlY2VpdmUgdGltZW91dCBpcyBpbmhlcml0ZWQgYnkgdGhlIHJlc3VsdCBvZiBhY2NlcHQoMikuCisgICAgICAgIC8vIEphdmEgc3BlY2lmaWVzIHRoYXQgaXQgc2hvdWxkIGFsd2F5cyBiZSAwIGluc3RlYWQuCisgICAgICAgIHNzLnNldFNvVGltZW91dCgxMjM0KTsKKyAgICAgICAgZmluYWwgU29ja2V0W10gcmVzdWx0ID0gbmV3IFNvY2tldFsxXTsKKyAgICAgICAgVGhyZWFkIHQgPSBuZXcgVGhyZWFkKG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICByZXN1bHRbMF0gPSBzcy5hY2NlcHQoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIHQuc3RhcnQoKTsKKyAgICAgICAgbmV3IFNvY2tldChzcy5nZXRJbmV0QWRkcmVzcygpLCBzcy5nZXRMb2NhbFBvcnQoKSk7CisgICAgICAgIHQuam9pbigpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgcmVzdWx0WzBdLmdldFNvVGltZW91dCgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9Tb2NrZXRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9Tb2NrZXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTc5NmUxZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L1NvY2tldFRlc3QuamF2YQpAQCAtMCwwICsxLDI4OCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5ldDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5Db25uZWN0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuU29ja2V0SW1wbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5TZXJ2ZXJTb2NrZXRDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNvY2tldENoYW5uZWw7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ2FsbGFibGU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JTZXJ2aWNlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yczsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5GdXR1cmU7CisKK3B1YmxpYyBjbGFzcyBTb2NrZXRUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICAvLyBTZWUgaHR0cDovL2IvMjk4MDU1OS4KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb3NlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNvY2tldCBzID0gbmV3IFNvY2tldCgpOworICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgIC8vIENsb3NpbmcgYSBjbG9zZWQgc29ja2V0IGRvZXMgbm90aGluZy4KKyAgICAgICAgcy5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE91ciBnZXRMb2NhbEFkZHJlc3MgYW5kIGdldExvY2FsUG9ydCBjdXJyZW50bHkgdXNlIGdldHNvY2tuYW1lKDMpLgorICAgICAqIFRoaXMgbWVhbnMgdGhleSBnaXZlIGluY29ycmVjdCByZXN1bHRzIG9uIGNsb3NlZCBzb2NrZXRzIChhcyB3ZWxsCisgICAgICogYXMgcmVxdWlyaW5nIGFuIHVubmVjZXNzYXJ5IGNhbGwgaW50byBuYXRpdmUgY29kZSkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRMb2NhbEFkZHJlc3NfYWZ0ZXJfY2xvc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU29ja2V0IHMgPSBuZXcgU29ja2V0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBCaW5kIHRvIGFuIGVwaGVtZXJhbCBsb2NhbCBwb3J0LgorICAgICAgICAgICAgcy5iaW5kKG5ldyBJbmV0U29ja2V0QWRkcmVzcygibG9jYWxob3N0IiwgMCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShzLmdldExvY2FsQWRkcmVzcygpLnRvU3RyaW5nKCksIHMuZ2V0TG9jYWxBZGRyZXNzKCkuaXNMb29wYmFja0FkZHJlc3MoKSk7CisgICAgICAgICAgICAvLyBXaGF0IGxvY2FsIHBvcnQgZGlkIHdlIGdldD8KKyAgICAgICAgICAgIGludCBsb2NhbFBvcnQgPSBzLmdldExvY2FsUG9ydCgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShsb2NhbFBvcnQgPiAwKTsKKyAgICAgICAgICAgIC8vIE5vdyBjbG9zZSB0aGUgc29ja2V0Li4uCisgICAgICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgICAgICAvLyBUaGUgUkkgcmV0dXJucyB0aGUgQU5ZIGFkZHJlc3MgYnV0IHRoZSBvcmlnaW5hbCBsb2NhbCBwb3J0IGFmdGVyIGNsb3NlLgorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShzLmdldExvY2FsQWRkcmVzcygpLmlzQW55TG9jYWxBZGRyZXNzKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGxvY2FsUG9ydCwgcy5nZXRMb2NhbFBvcnQoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTc5MzUKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X25ld1NvY2tldF9jb25uZWN0aW9uX3JlZnVzZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTb2NrZXQoImxvY2FsaG9zdCIsIDgwKTsKKyAgICAgICAgICAgIGZhaWwoImNvbm5lY3Rpb24gc2hvdWxkIGhhdmUgYmVlbiByZWZ1c2VkIik7CisgICAgICAgIH0gY2F0Y2ggKENvbm5lY3RFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9MzEyMworICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9MTkzMworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc29ja2V0TG9jYWxBbmRSZW1vdGVBZGRyZXNzZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tTb2NrZXRMb2NhbEFuZFJlbW90ZUFkZHJlc3NlcyhmYWxzZSk7CisgICAgICAgIGNoZWNrU29ja2V0TG9jYWxBbmRSZW1vdGVBZGRyZXNzZXModHJ1ZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY2hlY2tTb2NrZXRMb2NhbEFuZFJlbW90ZUFkZHJlc3Nlcyhib29sZWFuIHNldE9wdGlvbnMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBJbmV0QWRkcmVzcyBob3N0ID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCk7CisKKyAgICAgICAgLy8gT3BlbiBhIGxvY2FsIHNlcnZlciBwb3J0LgorICAgICAgICBTZXJ2ZXJTb2NrZXRDaGFubmVsIHNzYyA9IFNlcnZlclNvY2tldENoYW5uZWwub3BlbigpOworICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBsaXN0ZW5BZGRyID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKGhvc3QsIDApOworICAgICAgICBzc2Muc29ja2V0KCkuYmluZChsaXN0ZW5BZGRyLCAwKTsKKyAgICAgICAgU2VydmVyU29ja2V0IHNzID0gc3NjLnNvY2tldCgpOworCisgICAgICAgIC8vIE9wZW4gYSBzb2NrZXQgdG8gdGhlIGxvY2FsIHBvcnQuCisgICAgICAgIFNvY2tldENoYW5uZWwgb3V0ID0gU29ja2V0Q2hhbm5lbC5vcGVuKCk7CisgICAgICAgIG91dC5jb25maWd1cmVCbG9ja2luZyhmYWxzZSk7CisgICAgICAgIGlmIChzZXRPcHRpb25zKSB7CisgICAgICAgICAgICBvdXQuc29ja2V0KCkuc2V0VGNwTm9EZWxheShmYWxzZSk7CisgICAgICAgIH0KKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgYWRkciA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcyhob3N0LCBzc2Muc29ja2V0KCkuZ2V0TG9jYWxQb3J0KCkpOworICAgICAgICBvdXQuY29ubmVjdChhZGRyKTsKKyAgICAgICAgd2hpbGUgKCFvdXQuZmluaXNoQ29ubmVjdCgpKSB7CisgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMSk7CisgICAgICAgIH0KKworICAgICAgICBTb2NrZXRDaGFubmVsIGluID0gc3NjLmFjY2VwdCgpOworICAgICAgICBpZiAoc2V0T3B0aW9ucykgeworICAgICAgICAgICAgaW4uc29ja2V0KCkuc2V0VGNwTm9EZWxheShmYWxzZSk7CisgICAgICAgIH0KKworICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBvdXRSZW1vdGVBZGRyZXNzID0gKEluZXRTb2NrZXRBZGRyZXNzKSBvdXQuc29ja2V0KCkuZ2V0UmVtb3RlU29ja2V0QWRkcmVzcygpOworICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBvdXRMb2NhbEFkZHJlc3MgPSAoSW5ldFNvY2tldEFkZHJlc3MpIG91dC5zb2NrZXQoKS5nZXRMb2NhbFNvY2tldEFkZHJlc3MoKTsKKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgaW5Mb2NhbEFkZHJlc3MgPSAoSW5ldFNvY2tldEFkZHJlc3MpIGluLnNvY2tldCgpLmdldExvY2FsU29ja2V0QWRkcmVzcygpOworICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBpblJlbW90ZUFkZHJlc3MgPSAoSW5ldFNvY2tldEFkZHJlc3MpIGluLnNvY2tldCgpLmdldFJlbW90ZVNvY2tldEFkZHJlc3MoKTsKKyAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJpbkxvY2FsQWRkcmVzczogIiArIGluTG9jYWxBZGRyZXNzKTsKKyAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJpblJlbW90ZUFkZHJlc3M6ICIgKyBpblJlbW90ZUFkZHJlc3MpOworICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIm91dExvY2FsQWRkcmVzczogIiArIG91dExvY2FsQWRkcmVzcyk7CisgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigib3V0UmVtb3RlQWRkcmVzczogIiArIG91dFJlbW90ZUFkZHJlc3MpOworCisgICAgICAgIGFzc2VydEVxdWFscyhvdXRSZW1vdGVBZGRyZXNzLmdldFBvcnQoKSwgc3MuZ2V0TG9jYWxQb3J0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoaW5Mb2NhbEFkZHJlc3MuZ2V0UG9ydCgpLCBzcy5nZXRMb2NhbFBvcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhpblJlbW90ZUFkZHJlc3MuZ2V0UG9ydCgpLCBvdXRMb2NhbEFkZHJlc3MuZ2V0UG9ydCgpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoaW5Mb2NhbEFkZHJlc3MuZ2V0QWRkcmVzcygpLCBzcy5nZXRJbmV0QWRkcmVzcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGluUmVtb3RlQWRkcmVzcy5nZXRBZGRyZXNzKCksIHNzLmdldEluZXRBZGRyZXNzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMob3V0TG9jYWxBZGRyZXNzLmdldEFkZHJlc3MoKSwgc3MuZ2V0SW5ldEFkZHJlc3MoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhvdXRSZW1vdGVBZGRyZXNzLmdldEFkZHJlc3MoKSwgc3MuZ2V0SW5ldEFkZHJlc3MoKSk7CisKKyAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgIHNzYy5jbG9zZSgpOworCisgICAgICAgIGFzc2VydE51bGwoaW4uc29ja2V0KCkuZ2V0UmVtb3RlU29ja2V0QWRkcmVzcygpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChvdXQuc29ja2V0KCkuZ2V0UmVtb3RlU29ja2V0QWRkcmVzcygpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoaW4uc29ja2V0KCkuZ2V0TG9jYWxTb2NrZXRBZGRyZXNzKCksIHNzLmdldExvY2FsU29ja2V0QWRkcmVzcygpKTsKKyAgICB9CisKKyAgICAvLyBTb2NrZXRPcHRpb25zLnNldE9wdGlvbiBoYXMgd2VpcmQgYmVoYXZpb3IgZm9yIHNldFNvTGluZ2VyL1NPX0xJTkdFUi4KKyAgICAvLyBUaGlzIHRlc3QgZW5zdXJlcyB3ZSBkbyB3aGF0IHRoZSBSSSBkb2VzLgorICAgIHB1YmxpYyB2b2lkIHRlc3RfU29ja2V0T3B0aW9uc19zZXRPcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2xhc3MgTXlTb2NrZXRJbXBsIGV4dGVuZHMgU29ja2V0SW1wbCB7CisgICAgICAgICAgICBwdWJsaWMgaW50IG9wdGlvbjsKKyAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgdmFsdWU7CisKKyAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGNyZWF0ZUNhbGxlZDsKKyAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGNyZWF0ZVN0cmVhbTsKKworICAgICAgICAgICAgcHVibGljIE15U29ja2V0SW1wbCgpIHsgc3VwZXIoKTsgfQorICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGFjY2VwdChTb2NrZXRJbXBsIGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7IH0KKyAgICAgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7IHJldHVybiAwOyB9CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgYmluZChJbmV0QWRkcmVzcyBhcmcwLCBpbnQgYXJnMSkgdGhyb3dzIElPRXhjZXB0aW9uIHsgfQorICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsgfQorICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGNvbm5lY3QoU3RyaW5nIGFyZzAsIGludCBhcmcxKSB0aHJvd3MgSU9FeGNlcHRpb24geyB9CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgY29ubmVjdChJbmV0QWRkcmVzcyBhcmcwLCBpbnQgYXJnMSkgdGhyb3dzIElPRXhjZXB0aW9uIHsgfQorICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGNvbm5lY3QoU29ja2V0QWRkcmVzcyBhcmcwLCBpbnQgYXJnMSkgdGhyb3dzIElPRXhjZXB0aW9uIHsgfQorICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7IHJldHVybiBudWxsOyB9CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geyByZXR1cm4gbnVsbDsgfQorICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGxpc3RlbihpbnQgYXJnMCkgdGhyb3dzIElPRXhjZXB0aW9uIHsgfQorICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIHNlbmRVcmdlbnREYXRhKGludCBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24geyB9CisgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IGdldE9wdGlvbihpbnQgYXJnMCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7IHJldHVybiBudWxsOyB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoYm9vbGVhbiBpc1N0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZUNhbGxlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHJlYW0gPSBpc1N0cmVhbTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHZvaWQgc2V0T3B0aW9uKGludCBvcHRpb24sIE9iamVjdCB2YWx1ZSkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgdGhpcy5vcHRpb24gPSBvcHRpb247CisgICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgY2xhc3MgTXlTb2NrZXQgZXh0ZW5kcyBTb2NrZXQgeworICAgICAgICAgICAgcHVibGljIE15U29ja2V0KFNvY2tldEltcGwgaW1wbCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgc3VwZXIoaW1wbCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBNeVNvY2tldEltcGwgaW1wbCA9IG5ldyBNeVNvY2tldEltcGwoKTsKKyAgICAgICAgU29ja2V0IHMgPSBuZXcgTXlTb2NrZXQoaW1wbCk7CisKKyAgICAgICAgLy8gQ2hlY2sgdGhhdCwgYXMgcGVyIHRoZSBTb2NrZXRPcHRpb25zLnNldE9wdGlvbiBkb2N1bWVudGF0aW9uLCB3ZSBwYXNzIGZhbHNlIHJhdGhlcgorICAgICAgICAvLyB0aGFuIC0xIHRvIHRoZSBTb2NrZXRJbXBsIHdoZW4gc2V0U29MaW5nZXIgaXMgY2FsbGVkIHdpdGggdGhlIGZpcnN0IGFyZ3VtZW50IGZhbHNlLgorICAgICAgICBzLnNldFNvTGluZ2VyKGZhbHNlLCAtMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhCb29sZWFuLkZBTFNFLCAoQm9vbGVhbikgaW1wbC52YWx1ZSk7CisgICAgICAgIC8vIFdlIGFsc28gY2hlY2sgdGhhdCBTb2NrZXRJbXBsLmNyZWF0ZSB3YXMgY2FsbGVkLiBTb2NrZXRDaGFubmVsSW1wbC5Tb2NrZXRBZGFwdGVyCisgICAgICAgIC8vIHN1YmNsYXNzZXMgU29ja2V0LCBhbmQgd2hldGhlciBvciBub3QgdG8gY2FsbCBTb2NrZXRJbXBsLmNyZWF0ZSBpcyB0aGUgbWFpbiBiZWhhdmlvcmFsCisgICAgICAgIC8vIGRpZmZlcmVuY2UuCisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBpbXBsLmNyZWF0ZUNhbGxlZCk7CisgICAgICAgIHMuc2V0U29MaW5nZXIoZmFsc2UsIDApOworICAgICAgICBhc3NlcnRFcXVhbHMoQm9vbGVhbi5GQUxTRSwgKEJvb2xlYW4pIGltcGwudmFsdWUpOworICAgICAgICBzLnNldFNvTGluZ2VyKGZhbHNlLCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJvb2xlYW4uRkFMU0UsIChCb29sZWFuKSBpbXBsLnZhbHVlKTsKKworICAgICAgICAvLyBDaGVjayB0aGF0IG90aGVyd2lzZSwgd2UgcGFzcyBkb3duIGFuIEludGVnZXIuCisgICAgICAgIHMuc2V0U29MaW5nZXIodHJ1ZSwgMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLnZhbHVlT2YoMCksIChJbnRlZ2VyKSBpbXBsLnZhbHVlKTsKKyAgICAgICAgcy5zZXRTb0xpbmdlcih0cnVlLCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEludGVnZXIudmFsdWVPZigxKSwgKEludGVnZXIpIGltcGwudmFsdWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0VHJhZmZpY0NsYXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNvY2tldCBzID0gbmV3IFNvY2tldCgpOworICAgICAgICBzLnNldFRyYWZmaWNDbGFzcygxMjMpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTIzLCBzLmdldFRyYWZmaWNDbGFzcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZEFmdGVyQ2xvc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja1NlcnZlciBzZXJ2ZXIgPSBuZXcgTW9ja1NlcnZlcigpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgYnl0ZVtdezUsIDN9LCAwKTsKKyAgICAgICAgU29ja2V0IHNvY2tldCA9IG5ldyBTb2NrZXQoImxvY2FsaG9zdCIsIHNlcnZlci5wb3J0KTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBzb2NrZXQuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIGluLnJlYWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBpbi5yZWFkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgaW4ucmVhZCgpKTsKKyAgICAgICAgc29ja2V0LmNsb3NlKCk7CisgICAgICAgIGluLmNsb3NlKCk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogUmF0aGVyIGFzdG9uaXNoaW5nbHksIHJlYWQoKSBkb2Vzbid0IHRocm93IGV2ZW4gdGhvdWdoIHRoZSBzdHJlYW0gaXMKKyAgICAgICAgICogY2xvc2VkLiBUaGlzIGlzIGNvbnNpc3RlbnQgd2l0aCB0aGUgUkkncyBiZWhhdmlvci4KKyAgICAgICAgICovCisgICAgICAgIGFzc2VydEVxdWFscygtMSwgaW4ucmVhZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKCkpOworCisgICAgICAgIHNlcnZlci5zaHV0ZG93bigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZUFmdGVyQ2xvc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja1NlcnZlciBzZXJ2ZXIgPSBuZXcgTW9ja1NlcnZlcigpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgYnl0ZVswXSwgMyk7CisgICAgICAgIFNvY2tldCBzb2NrZXQgPSBuZXcgU29ja2V0KCJsb2NhbGhvc3QiLCBzZXJ2ZXIucG9ydCk7CisgICAgICAgIE91dHB1dFN0cmVhbSBvdXQgPSBzb2NrZXQuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIG91dC53cml0ZSg1KTsKKyAgICAgICAgb3V0LndyaXRlKDMpOworICAgICAgICBzb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG91dC53cml0ZSg5KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHNlcnZlci5zaHV0ZG93bigpOworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBNb2NrU2VydmVyIHsKKyAgICAgICAgcHJpdmF0ZSBFeGVjdXRvclNlcnZpY2UgZXhlY3V0b3I7CisgICAgICAgIHByaXZhdGUgU2VydmVyU29ja2V0IHNlcnZlclNvY2tldDsKKyAgICAgICAgcHJpdmF0ZSBpbnQgcG9ydCA9IC0xOworCisgICAgICAgIE1vY2tTZXJ2ZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgZXhlY3V0b3IgPSBFeGVjdXRvcnMubmV3Q2FjaGVkVGhyZWFkUG9vbCgpOworICAgICAgICAgICAgc2VydmVyU29ja2V0ID0gbmV3IFNlcnZlclNvY2tldCgwKTsKKyAgICAgICAgICAgIHNlcnZlclNvY2tldC5zZXRSZXVzZUFkZHJlc3ModHJ1ZSk7CisgICAgICAgICAgICBwb3J0ID0gc2VydmVyU29ja2V0LmdldExvY2FsUG9ydCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEZ1dHVyZTxieXRlW10+IGVucXVldWUoZmluYWwgYnl0ZVtdIHNlbmRCeXRlcywgZmluYWwgaW50IHJlY2VpdmVCeXRlQ291bnQpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBleGVjdXRvci5zdWJtaXQobmV3IENhbGxhYmxlPGJ5dGVbXT4oKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBieXRlW10gY2FsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICBTb2NrZXQgc29ja2V0ID0gc2VydmVyU29ja2V0LmFjY2VwdCgpOworICAgICAgICAgICAgICAgICAgICBPdXRwdXRTdHJlYW0gb3V0ID0gc29ja2V0LmdldE91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgICAgICBvdXQud3JpdGUoc2VuZEJ5dGVzKTsKKworICAgICAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IHNvY2tldC5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgICAgICBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbcmVjZWl2ZUJ5dGVDb3VudF07CisgICAgICAgICAgICAgICAgICAgIGludCB0b3RhbCA9IDA7CisgICAgICAgICAgICAgICAgICAgIHdoaWxlICh0b3RhbCA8IHJlY2VpdmVCeXRlQ291bnQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IGluLnJlYWQocmVzdWx0LCB0b3RhbCwgcmVzdWx0Lmxlbmd0aCAtIHRvdGFsKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBzb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNodXRkb3duKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHNlcnZlclNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgZXhlY3V0b3Iuc2h1dGRvd24oKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L1VSSVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L1VSSVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNDVmYWNjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvVVJJVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjI1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmV0OworCitpbXBvcnQgamF2YS5uZXQuVVJJOworaW1wb3J0IGphdmEubmV0LlVSSVN5bnRheEV4Y2VwdGlvbjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgbGliY29yZS5qYXZhLnV0aWwuU2VyaWFsaXphYmxlVGVzdGVyOworCitwdWJsaWMgZmluYWwgY2xhc3MgVVJJVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RVcmlQYXJ0cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cDovL3VzZXJuYW1lOnBhc3N3b3JkQGhvc3Q6ODA4MC9kaXJlY3RvcnkvZmlsZT9xdWVyeSNyZWYiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwIiwgdXJpLmdldFNjaGVtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1c2VybmFtZTpwYXNzd29yZEBob3N0OjgwODAiLCB1cmkuZ2V0QXV0aG9yaXR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInVzZXJuYW1lOnBhc3N3b3JkQGhvc3Q6ODA4MCIsIHVyaS5nZXRSYXdBdXRob3JpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidXNlcm5hbWU6cGFzc3dvcmQiLCB1cmkuZ2V0VXNlckluZm8oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidXNlcm5hbWU6cGFzc3dvcmQiLCB1cmkuZ2V0UmF3VXNlckluZm8oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaG9zdCIsIHVyaS5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoODA4MCwgdXJpLmdldFBvcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL2RpcmVjdG9yeS9maWxlIiwgdXJpLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL2RpcmVjdG9yeS9maWxlIiwgdXJpLmdldFJhd1BhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygicXVlcnkiLCB1cmkuZ2V0UXVlcnkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygicXVlcnkiLCB1cmkuZ2V0UmF3UXVlcnkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygicmVmIiwgdXJpLmdldEZyYWdtZW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInJlZiIsIHVyaS5nZXRSYXdGcmFnbWVudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvL3VzZXJuYW1lOnBhc3N3b3JkQGhvc3Q6ODA4MC9kaXJlY3RvcnkvZmlsZT9xdWVyeSIsCisgICAgICAgICAgICAgICAgdXJpLmdldFNjaGVtZVNwZWNpZmljUGFydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvL3VzZXJuYW1lOnBhc3N3b3JkQGhvc3Q6ODA4MC9kaXJlY3RvcnkvZmlsZT9xdWVyeSIsCisgICAgICAgICAgICAgICAgdXJpLmdldFJhd1NjaGVtZVNwZWNpZmljUGFydCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXF1YWxzQ2FzZU1hcHBpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBVUkkoIkhUVFA6Ly9sb2NhbGhvc3QvZm9vP2Jhcj1iYXojcXV1eCIpLAorICAgICAgICAgICAgICAgIG5ldyBVUkkoIkhUVFA6Ly9sb2NhbGhvc3QvZm9vP2Jhcj1iYXojcXV1eCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBVUkkoImh0dHA6Ly9sb2NhbGhvc3QvZm9vP2Jhcj1iYXojcXV1eCIpLAorICAgICAgICAgICAgICAgIG5ldyBVUkkoImh0dHA6Ly9MT0NBTEhPU1QvZm9vP2Jhcj1iYXojcXV1eCIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobmV3IFVSSSgiaHR0cDovL2xvY2FsaG9zdC9mb28/YmFyPWJheiNxdXV4IikKKyAgICAgICAgICAgICAgICAuZXF1YWxzKG5ldyBVUkkoImh0dHA6Ly9sb2NhbGhvc3QvRk9PP2Jhcj1iYXojcXV1eCIpKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG5ldyBVUkkoImh0dHA6Ly9sb2NhbGhvc3QvZm9vP2Jhcj1iYXojcXV1eCIpCisgICAgICAgICAgICAgICAgLmVxdWFscyhuZXcgVVJJKCJodHRwOi8vbG9jYWxob3N0L2Zvbz9CQVI9QkFaI3F1dXgiKSkpOworICAgICAgICBhc3NlcnRGYWxzZShuZXcgVVJJKCJodHRwOi8vbG9jYWxob3N0L2Zvbz9iYXI9YmF6I3F1dXgiKQorICAgICAgICAgICAgICAgIC5lcXVhbHMobmV3IFVSSSgiaHR0cDovL2xvY2FsaG9zdC9mb28/YmFyPWJheiNRVVVYIikpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmlsZUVxdWFsc1dpdGhFbXB0eUhvc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBVUkkoImZpbGUiLCAiIiwgIi9hLyIsIG51bGwpLCBuZXcgVVJJKCJmaWxlOi9hLyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBVUkkoImZpbGUiLCBudWxsLCAiL2EvIiwgbnVsbCksIG5ldyBVUkkoImZpbGU6L2EvIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVcmlTZXJpYWxpemF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzID0gImFjZWQwMDA1NzM3MjAwMGM2YTYxNzY2MTJlNmU2NTc0MmU1NTUyNDlhYzAxNzgyZTQzOWU0OWFiMDMwMDAxNGMwMDA2NzM3NDcyNjk2ZTYiCisgICAgICAgICAgICAgICAgKyAiNzc0MDAxMjRjNmE2MTc2NjEyZjZjNjE2ZTY3MmY1Mzc0NzI2OTZlNjczYjc4NzA3NDAwMmE2ODc0NzQ3MDNhMmYyZjc1NzM2NTcyM2E3MDYiCisgICAgICAgICAgICAgICAgKyAiMTczNzM0MDY4NmY3Mzc0MmY3MDYxNzQ2ODJmNjY2OTZjNjUzZjcxNzU2NTcyNzkyMzY4NjE3MzY4NzgiOworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cDovL3VzZXI6cGFzc0Bob3N0L3BhdGgvZmlsZT9xdWVyeSNoYXNoIik7CisgICAgICAgIG5ldyBTZXJpYWxpemFibGVUZXN0ZXI8VVJJPih1cmksIHMpLnRlc3QoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW1wdHlIb3N0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSB1cmkgPSBuZXcgVVJJKCJodHRwOi8vL3BhdGgiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVyaS5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9wYXRoIiwgdXJpLmdldFBhdGgoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vSG9zdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cDovcGF0aCIpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgdXJpLmdldEhvc3QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL3BhdGgiLCB1cmkuZ2V0UGF0aCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9QYXRoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSB1cmkgPSBuZXcgVVJJKCJodHRwOi8vaG9zdCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImhvc3QiLCB1cmkuZ2V0SG9zdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB1cmkuZ2V0UGF0aCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW1wdHlIb3N0QW5kTm9QYXRoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVVJJKCJodHRwOi8vIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFVSSVN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vSG9zdEFuZE5vUGF0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFVSSSgiaHR0cDoiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoVVJJU3ludGF4RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXRTaWduSW5Vc2VySW5mbygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cDovL3VzZXJAdXNlcmhvc3QuY29tOnBhc3N3b3JkQGhvc3QiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1c2VyQHVzZXJob3N0LmNvbTpwYXNzd29yZEBob3N0IiwgdXJpLmdldEF1dGhvcml0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVyaS5nZXRVc2VySW5mbygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVyaS5nZXRIb3N0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVc2VyTm9QYXNzd29yZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cDovL3VzZXJAaG9zdCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInVzZXJAaG9zdCIsIHVyaS5nZXRBdXRob3JpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidXNlciIsIHVyaS5nZXRVc2VySW5mbygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJob3N0IiwgdXJpLmdldEhvc3QoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFVzZXJOb1Bhc3N3b3JkRXhwbGljaXRQb3J0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSB1cmkgPSBuZXcgVVJJKCJodHRwOi8vdXNlckBob3N0OjgwODAiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1c2VyQGhvc3Q6ODA4MCIsIHVyaS5nZXRBdXRob3JpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidXNlciIsIHVyaS5nZXRVc2VySW5mbygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJob3N0IiwgdXJpLmdldEhvc3QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg4MDgwLCB1cmkuZ2V0UG9ydCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXNlclBhc3N3b3JkSG9zdFBvcnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIHVyaSA9IG5ldyBVUkkoImh0dHA6Ly91c2VyOnBhc3N3b3JkQGhvc3Q6ODA4MCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInVzZXI6cGFzc3dvcmRAaG9zdDo4MDgwIiwgdXJpLmdldEF1dGhvcml0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1c2VyOnBhc3N3b3JkIiwgdXJpLmdldFVzZXJJbmZvKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImhvc3QiLCB1cmkuZ2V0SG9zdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDgwODAsIHVyaS5nZXRQb3J0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVc2VyUGFzc3dvcmRFbXB0eUhvc3RQb3J0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSB1cmkgPSBuZXcgVVJJKCJodHRwOi8vdXNlcjpwYXNzd29yZEA6ODA4MCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInVzZXI6cGFzc3dvcmRAOjgwODAiLCB1cmkuZ2V0QXV0aG9yaXR5KCkpOworICAgICAgICAvLyBmcm9tIFJJLiB0aGlzIGlzIGN1cmlvdXMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVyaS5nZXRVc2VySW5mbygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVyaS5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIHVyaS5nZXRQb3J0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVc2VyUGFzc3dvcmRFbXB0eUhvc3RFbXB0eVBvcnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIHVyaSA9IG5ldyBVUkkoImh0dHA6Ly91c2VyOnBhc3N3b3JkQDoiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1c2VyOnBhc3N3b3JkQDoiLCB1cmkuZ2V0QXV0aG9yaXR5KCkpOworICAgICAgICAvLyBmcm9tIFJJLiB0aGlzIGlzIGN1cmlvdXMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVyaS5nZXRVc2VySW5mbygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVyaS5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIHVyaS5nZXRQb3J0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXRoT25seSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cDovL2hvc3QvcGF0aCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImhvc3QiLCB1cmkuZ2V0SG9zdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvcGF0aCIsIHVyaS5nZXRQYXRoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RRdWVyeU9ubHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIHVyaSA9IG5ldyBVUkkoImh0dHA6Ly9ob3N0P3F1ZXJ5Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiaG9zdCIsIHVyaS5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHVyaS5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInF1ZXJ5IiwgdXJpLmdldFF1ZXJ5KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGcmFnbWVudE9ubHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIHVyaSA9IG5ldyBVUkkoImh0dHA6Ly9ob3N0I2ZyYWdtZW50Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiaG9zdCIsIHVyaS5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHVyaS5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgdXJpLmdldFF1ZXJ5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZyYWdtZW50IiwgdXJpLmdldEZyYWdtZW50KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdFNpZ25JblBhdGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIHVyaSA9IG5ldyBVUkkoImh0dHA6Ly9ob3N0L2ZpbGVAZm9vIik7CisgICAgICAgIGFzc2VydEVxdWFscygiL2ZpbGVAZm9vIiwgdXJpLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCB1cmkuZ2V0VXNlckluZm8oKSk7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29sb25JblBhdGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIHVyaSA9IG5ldyBVUkkoImh0dHA6Ly9ob3N0L2ZpbGU6Y29sb24iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZmlsZTpjb2xvbiIsIHVyaS5nZXRQYXRoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTbGFzaEluUXVlcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIHVyaSA9IG5ldyBVUkkoImh0dHA6Ly9ob3N0L2ZpbGU/cXVlcnkvcGF0aCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9maWxlIiwgdXJpLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygicXVlcnkvcGF0aCIsIHVyaS5nZXRRdWVyeSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UXVlc3Rpb25NYXJrSW5RdWVyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cDovL2hvc3QvZmlsZT9xdWVyeT9hbm90aGVyIik7CisgICAgICAgIGFzc2VydEVxdWFscygiL2ZpbGUiLCB1cmkuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJxdWVyeT9hbm90aGVyIiwgdXJpLmdldFF1ZXJ5KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdFNpZ25JblF1ZXJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSB1cmkgPSBuZXcgVVJJKCJodHRwOi8vaG9zdC9maWxlP3F1ZXJ5QGF0Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiL2ZpbGUiLCB1cmkuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJxdWVyeUBhdCIsIHVyaS5nZXRRdWVyeSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29sb25JblF1ZXJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSB1cmkgPSBuZXcgVVJJKCJodHRwOi8vaG9zdC9maWxlP3F1ZXJ5OmNvbG9uIik7CisgICAgICAgIGFzc2VydEVxdWFscygiL2ZpbGUiLCB1cmkuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJxdWVyeTpjb2xvbiIsIHVyaS5nZXRRdWVyeSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UXVlc3Rpb25NYXJrSW5GcmFnbWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cDovL2hvc3QvZmlsZSNmcmFnbWVudD9xdWVyeSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9maWxlIiwgdXJpLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCB1cmkuZ2V0UXVlcnkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZnJhZ21lbnQ/cXVlcnkiLCB1cmkuZ2V0RnJhZ21lbnQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbG9uSW5GcmFnbWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cDovL2hvc3QvZmlsZSNmcmFnbWVudDo4MCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9maWxlIiwgdXJpLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgdXJpLmdldFBvcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZnJhZ21lbnQ6ODAiLCB1cmkuZ2V0RnJhZ21lbnQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNsYXNoSW5GcmFnbWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cDovL2hvc3QvZmlsZSNmcmFnbWVudC9wYXRoIik7CisgICAgICAgIGFzc2VydEVxdWFscygiL2ZpbGUiLCB1cmkuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmcmFnbWVudC9wYXRoIiwgdXJpLmdldEZyYWdtZW50KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RIYXNoSW5GcmFnbWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gVGhpcyBpcyBub3QgY29uc2lzdGVudCB3aXRoIGphdmEubmV0LlVSTAorICAgICAgICAgICAgbmV3IFVSSSgiaHR0cDovL2hvc3QvZmlsZSNmcmFnbWVudCNhbm90aGVyIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFVSSVN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVtcHR5UG9ydCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cDovL2hvc3Q6LyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIHVyaS5nZXRQb3J0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROb25OdW1lcmljUG9ydCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cDovL2hvc3Q6eC8iKTsKKyAgICAgICAgLy8gRnJvbSB0aGUgUkkuIFRoaXMgaXMgY3VyaW91cworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgdXJpLmdldEhvc3QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgdXJpLmdldFBvcnQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5lZ2F0aXZlUG9ydCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cDovL2hvc3Q6LTIvIik7CisgICAgICAgIC8vIEZyb20gdGhlIFJJLiBUaGlzIGlzIGN1cmlvdXMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVyaS5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIHVyaS5nZXRQb3J0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROZWdhdGl2ZVBvcnRFcXVhbHNQbGFjZWhvbGRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cDovL2hvc3Q6LTEvIik7CisgICAgICAgIC8vIEZyb20gdGhlIFJJLiBUaGlzIGlzIGN1cmlvdXMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVyaS5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIHVyaS5nZXRQb3J0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWxhdGl2ZVBhdGhPblF1ZXJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSBiYXNlID0gbmV3IFVSSSgiaHR0cDovL2hvc3QvZmlsZT9xdWVyeS94Iik7CisgICAgICAgIFVSSSB1cmkgPSBiYXNlLnJlc29sdmUoImFub3RoZXIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vaG9zdC9hbm90aGVyIiwgdXJpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9hbm90aGVyIiwgdXJpLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCB1cmkuZ2V0UXVlcnkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCB1cmkuZ2V0RnJhZ21lbnQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbGF0aXZlRnJhZ21lbnRPblF1ZXJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSBiYXNlID0gbmV3IFVSSSgiaHR0cDovL2hvc3QvZmlsZT9xdWVyeS94I2ZyYWdtZW50Iik7CisgICAgICAgIFVSSSB1cmkgPSBiYXNlLnJlc29sdmUoIiNhbm90aGVyIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2hvc3QvZmlsZT9xdWVyeS94I2Fub3RoZXIiLCB1cmkudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL2ZpbGUiLCB1cmkuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJxdWVyeS94IiwgdXJpLmdldFF1ZXJ5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFub3RoZXIiLCB1cmkuZ2V0RnJhZ21lbnQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhdGhDb250YWluc1JlbGF0aXZlUGFydHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIHVyaSA9IG5ldyBVUkkoImh0dHA6Ly9ob3N0L2EvYi8uLi9jIik7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vaG9zdC9hL2MiLCB1cmkudG9TdHJpbmcoKSk7IC8vIFJJIGRvZXNuJ3QgY2Fub25pY2FsaXplCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbGF0aXZlUGF0aEFuZEZyYWdtZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSBiYXNlID0gbmV3IFVSSSgiaHR0cDovL2hvc3QvZmlsZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9ob3N0L2Fub3RoZXIjZnJhZ21lbnQiLCBiYXNlLnJlc29sdmUoImFub3RoZXIjZnJhZ21lbnQiKS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVsYXRpdmVQYXJlbnREaXJlY3RvcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIGJhc2UgPSBuZXcgVVJJKCJodHRwOi8vaG9zdC9hL2IvYyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9ob3N0L2EvZCIsIGJhc2UucmVzb2x2ZSgiLi4vZCIpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWxhdGl2ZUNoaWxkRGlyZWN0b3J5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSBiYXNlID0gbmV3IFVSSSgiaHR0cDovL2hvc3QvYS9iL2MiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vaG9zdC9hL2IvZC9lIiwgYmFzZS5yZXNvbHZlKCJkL2UiKS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVsYXRpdmVSb290RGlyZWN0b3J5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSBiYXNlID0gbmV3IFVSSSgiaHR0cDovL2hvc3QvYS9iL2MiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vaG9zdC9kIiwgYmFzZS5yZXNvbHZlKCIvZCIpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWxhdGl2ZUZ1bGxVcmwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIGJhc2UgPSBuZXcgVVJJKCJodHRwOi8vaG9zdC9hL2IvYyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9ob3N0Mi9kL2UiLCBiYXNlLnJlc29sdmUoImh0dHA6Ly9ob3N0Mi9kL2UiKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwczovL2hvc3QyL2QvZSIsIGJhc2UucmVzb2x2ZSgiaHR0cHM6Ly9ob3N0Mi9kL2UiKS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVsYXRpdmVEaWZmZXJlbnRTY2hlbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIGJhc2UgPSBuZXcgVVJJKCJodHRwOi8vaG9zdC9hL2IvYyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHBzOi8vaG9zdDIvZC9lIiwgYmFzZS5yZXNvbHZlKCJodHRwczovL2hvc3QyL2QvZSIpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWxhdGl2ZURpZmZlcmVudEF1dGhvcml0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgYmFzZSA9IG5ldyBVUkkoImh0dHA6Ly9ob3N0L2EvYi9jIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2Fub3RoZXIvZC9lIiwgYmFzZS5yZXNvbHZlKCIvL2Fub3RoZXIvZC9lIikudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbGF0aXZlV2l0aFNjaGVtZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgYmFzZSA9IG5ldyBVUkkoImh0dHA6Ly9ob3N0L2EvYi9jIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiYXNlLnJlc29sdmUoImh0dHA6Iik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovIiwgYmFzZS5yZXNvbHZlKCJodHRwOi8iKS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFsZm9ybWVkVXJsc1JlZnVzZWRCeUZpcmVmb3hBbmRDaHJvbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIGJhc2UgPSBuZXcgVVJJKCJodHRwOi8vaG9zdC9hL2IvYyIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmFzZS5yZXNvbHZlKCJodHRwOi8vIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiYXNlLnJlc29sdmUoIi8vIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiYXNlLnJlc29sdmUoImh0dHBzOiIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHBzOi8iLCBiYXNlLnJlc29sdmUoImh0dHBzOi8iKS50b1N0cmluZygpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJhc2UucmVzb2x2ZSgiaHR0cHM6Ly8iKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmZjMTgwOE5vcm1hbEV4YW1wbGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSBiYXNlID0gbmV3IFVSSSgiaHR0cDovL2EvYi9jL2Q7cD9xIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cHM6aCIsIGJhc2UucmVzb2x2ZSgiaHR0cHM6aCIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy9nIiwgYmFzZS5yZXNvbHZlKCJnIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2ciLCBiYXNlLnJlc29sdmUoIi4vZyIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy9nLyIsIGJhc2UucmVzb2x2ZSgiZy8iKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9nIiwgYmFzZS5yZXNvbHZlKCIvZyIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9nIiwgYmFzZS5yZXNvbHZlKCIvL2ciKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2MvZDtwP3kiLCBiYXNlLnJlc29sdmUoIj95IikudG9TdHJpbmcoKSk7IC8vIFJJIGZhaWxzOyBsb3NlcyBmaWxlCisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2c/eSIsIGJhc2UucmVzb2x2ZSgiZz95IikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2Q7cD9xI3MiLCBiYXNlLnJlc29sdmUoIiNzIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2cjcyIsIGJhc2UucmVzb2x2ZSgiZyNzIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2c/eSNzIiwgYmFzZS5yZXNvbHZlKCJnP3kjcyIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy87eCIsIGJhc2UucmVzb2x2ZSgiO3giKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2MvZzt4IiwgYmFzZS5yZXNvbHZlKCJnO3giKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2MvZzt4P3kjcyIsIGJhc2UucmVzb2x2ZSgiZzt4P3kjcyIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy9kO3A/cSIsIGJhc2UucmVzb2x2ZSgiIikudG9TdHJpbmcoKSk7IC8vIFJJIHJldHVybnMgaHR0cDovL2EvYi9jLworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy8iLCBiYXNlLnJlc29sdmUoIi4iKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2MvIiwgYmFzZS5yZXNvbHZlKCIuLyIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvIiwgYmFzZS5yZXNvbHZlKCIuLiIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvIiwgYmFzZS5yZXNvbHZlKCIuLi8iKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2ciLCBiYXNlLnJlc29sdmUoIi4uL2ciKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS8iLCBiYXNlLnJlc29sdmUoIi4uLy4uIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvIiwgYmFzZS5yZXNvbHZlKCIuLi8uLi8iKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9nIiwgYmFzZS5yZXNvbHZlKCIuLi8uLi9nIikudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJmYzE4MDhBYm5vcm1hbEV4YW1wbGVUb29NYW55RG90RG90U2VxdWVuY2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSBiYXNlID0gbmV3IFVSSSgiaHR0cDovL2EvYi9jL2Q7cD9xIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvZyIsIGJhc2UucmVzb2x2ZSgiLi4vLi4vLi4vZyIpLnRvU3RyaW5nKCkpOyAvLyBSSSBkb2Vzbid0IG5vcm1hbGl6ZQorICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2ciLCBiYXNlLnJlc29sdmUoIi4uLy4uLy4uLy4uL2ciKS50b1N0cmluZygpKTsgLy8gZmFpbHMgb24gUkkKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmZjMTgwOEFibm9ybWFsRXhhbXBsZVJlbW92ZURvdFNlZ21lbnRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSBiYXNlID0gbmV3IFVSSSgiaHR0cDovL2EvYi9jL2Q7cD9xIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvZyIsIGJhc2UucmVzb2x2ZSgiLy4vZyIpLnRvU3RyaW5nKCkpOyAvLyBSSSBkb2Vzbid0IG5vcm1hbGl6ZQorICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2ciLCBiYXNlLnJlc29sdmUoIi8uLi9nIikudG9TdHJpbmcoKSk7IC8vIGZhaWxzIG9uIFJJCisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2cuIiwgYmFzZS5yZXNvbHZlKCJnLiIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy8uZyIsIGJhc2UucmVzb2x2ZSgiLmciKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2MvZy4uIiwgYmFzZS5yZXNvbHZlKCJnLi4iKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2MvLi5nIiwgYmFzZS5yZXNvbHZlKCIuLmciKS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmZjMTgwOEFibm9ybWFsRXhhbXBsZU5vbnNlbnNpY2FsRG90cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgYmFzZSA9IG5ldyBVUkkoImh0dHA6Ly9hL2IvYy9kO3A/cSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvZyIsIGJhc2UucmVzb2x2ZSgiLi8uLi9nIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2cvIiwgYmFzZS5yZXNvbHZlKCIuL2cvLiIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy9nL2giLCBiYXNlLnJlc29sdmUoImcvLi9oIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2giLCBiYXNlLnJlc29sdmUoImcvLi4vaCIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy9nO3g9MS95IiwgYmFzZS5yZXNvbHZlKCJnO3g9MS8uL3kiKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2MveSIsIGJhc2UucmVzb2x2ZSgiZzt4PTEvLi4veSIpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZmMxODA4QWJub3JtYWxFeGFtcGxlUmVsYXRpdmVTY2hlbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIGJhc2UgPSBuZXcgVVJJKCJodHRwOi8vYS9iL2MvZDtwP3EiKTsKKyAgICAgICAgVVJJIHVyaSA9IGJhc2UucmVzb2x2ZSgiaHR0cDpnIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDpnIiwgdXJpLnRvU3RyaW5nKCkpOyAvLyB0aGlzIGlzIGFuIG9wYXF1ZSBVUkkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIHVyaS5pc09wYXF1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIHVyaS5pc0Fic29sdXRlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZmMxODA4QWJub3JtYWxFeGFtcGxlUXVlcnlPckZyYWdtZW50RG90cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgYmFzZSA9IG5ldyBVUkkoImh0dHA6Ly9hL2IvYy9kO3A/cSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy9nP3kvLi94IiwgYmFzZS5yZXNvbHZlKCJnP3kvLi94IikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2c/eS8uLi94IiwgYmFzZS5yZXNvbHZlKCJnP3kvLi4veCIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy9nI3MvLi94IiwgYmFzZS5yZXNvbHZlKCJnI3MvLi94IikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2cjcy8uLi94IiwgYmFzZS5yZXNvbHZlKCJnI3MvLi4veCIpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTcXVhcmVCcmFja2V0c0luVXNlckluZm8oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBVUkkoImh0dHA6Ly91c2VyOls6OjFdQGhvc3QiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoVVJJU3ludGF4RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmlsZVVyaUV4dHJhTGVhZGluZ1NsYXNoZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIHVyaSA9IG5ldyBVUkkoImZpbGU6Ly8vL2ZvbyIpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgdXJpLmdldEF1dGhvcml0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvL2ZvbyIsIHVyaS5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZpbGU6Ly8vL2ZvbyIsIHVyaS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmlsZVVybFdpdGhBdXRob3JpdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIHVyaSA9IG5ldyBVUkkoImZpbGU6Ly94L2ZvbyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIngiLCB1cmkuZ2V0QXV0aG9yaXR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9mb28iLCB1cmkuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmaWxlOi8veC9mb28iLCB1cmkudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVtcHR5QXV0aG9yaXR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSB1cmkgPSBuZXcgVVJJKCJodHRwOi8vL2ZvbyIpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgdXJpLmdldEF1dGhvcml0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZm9vIiwgdXJpLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovLy9mb28iLCB1cmkudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEh0dHBVcmxFeHRyYUxlYWRpbmdTbGFzaGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSB1cmkgPSBuZXcgVVJJKCJodHRwOi8vLy9mb28iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVyaS5nZXRBdXRob3JpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLy9mb28iLCB1cmkuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vLy9mb28iLCB1cmkudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZpbGVVcmxSZWxhdGl2ZVBhdGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIGJhc2UgPSBuZXcgVVJJKCJmaWxlOi9hL2IvYyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZpbGU6L2EvYi9kIiwgYmFzZS5yZXNvbHZlKCJkIikudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZpbGVVcmxEb3R0ZWRQYXRoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSB1cmwgPSBuZXcgVVJJKCJmaWxlOi4uL2EvYiIpOworICAgICAgICBhc3NlcnRUcnVlKHVybC5pc09wYXF1ZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh1cmwuZ2V0UGF0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWdyZXNzaW9uIHRlc3QgZm9yIGh0dHA6Ly9iL2lzc3VlP2lkPTI2MDQwNjEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2luZ0RvdEFzSG9zdG5hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG5ldyBVUkkoImh0dHA6Ly8uLyIpLmdldEhvc3QoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNxdWFyZUJyYWNrZXRzV2l0aElQdjQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBVUkkoImh0dHA6Ly9bMTkyLjE2OC4wLjFdLyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChVUklTeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNxdWFyZUJyYWNrZXRzV2l0aEhvc3RuYW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVVJJKCJodHRwOi8vW2dvb2dsZS5jb21dLyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChVUklTeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdElQdjZXaXRob3V0U3F1YXJlQnJhY2tldHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG5ldyBVUkkoImh0dHA6Ly9mZTgwOjoxMjM0LyIpLmdldEhvc3QoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVxdWFsaXR5V2l0aE5vUGF0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShuZXcgVVJJKCJodHRwOi8vYW5kcm9pZC5jb20iKS5lcXVhbHMobmV3IFVSSSgiaHR0cDovL2FuZHJvaWQuY29tLyIpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbGF0aXZpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIGEgPSBuZXcgVVJJKCJodHRwOi8vaG9zdC9hL2IiKTsKKyAgICAgICAgVVJJIGIgPSBuZXcgVVJJKCJodHRwOi8vaG9zdC9hL2IvYyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImIvYyIsIGEucmVsYXRpdml6ZShiKS50b1N0cmluZygpKTsgLy8gUkkgYXNzdW1lcyBhIGRpcmVjdG9yeQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZVNlcnZlckF1dGhvcml0eUludmFsaWRBdXRob3JpdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIHVyaSA9IG5ldyBVUkkoImh0dHA6Ly9ob3N0Oi0yLyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImhvc3Q6LTIiLCB1cmkuZ2V0QXV0aG9yaXR5KCkpOworICAgICAgICBhc3NlcnROdWxsKHVyaS5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIHVyaS5nZXRQb3J0KCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdXJpLnBhcnNlU2VydmVyQXV0aG9yaXR5KCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFVSSVN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlU2VydmVyQXV0aG9yaXR5T21pdHRlZEF1dGhvcml0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cDpmaWxlIik7CisgICAgICAgIHVyaS5wYXJzZVNlcnZlckF1dGhvcml0eSgpOyAvLyBkb2VzIG5vdGhpbmchCisgICAgICAgIGFzc2VydE51bGwodXJpLmdldEF1dGhvcml0eSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh1cmkuZ2V0SG9zdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCB1cmkuZ2V0UG9ydCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5jb2RpbmdQYXJ0cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiaHR0cCIsICJ1c2VyOnBhNTV3P3JkIiwgImhvc3QiLCA4MCwgIi9kb2N8c2VhcmNoIiwKKyAgICAgICAgICAgICAgICAicT1ncmVlbiByb2JvdHMiLCAib3ZlciA2XCIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwIiwgdXJpLmdldFNjaGVtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1c2VyOnBhNTV3P3JkQGhvc3Q6ODAiLCB1cmkuZ2V0QXV0aG9yaXR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInVzZXI6cGE1NXclM0ZyZEBob3N0OjgwIiwgdXJpLmdldFJhd0F1dGhvcml0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1c2VyOnBhNTV3P3JkIiwgdXJpLmdldFVzZXJJbmZvKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInVzZXI6cGE1NXclM0ZyZCIsIHVyaS5nZXRSYXdVc2VySW5mbygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZG9jfHNlYXJjaCIsIHVyaS5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9kb2MlN0NzZWFyY2giLCB1cmkuZ2V0UmF3UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJxPWdyZWVuIHJvYm90cyIsIHVyaS5nZXRRdWVyeSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJxPWdyZWVuJTIwcm9ib3RzIiwgdXJpLmdldFJhd1F1ZXJ5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm92ZXIgNlwiIiwgdXJpLmdldEZyYWdtZW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm92ZXIlMjA2JTIyIiwgdXJpLmdldFJhd0ZyYWdtZW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi8vdXNlcjpwYTU1dz9yZEBob3N0OjgwL2RvY3xzZWFyY2g/cT1ncmVlbiByb2JvdHMiLAorICAgICAgICAgICAgICAgIHVyaS5nZXRTY2hlbWVTcGVjaWZpY1BhcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLy91c2VyOnBhNTV3JTNGcmRAaG9zdDo4MC9kb2MlN0NzZWFyY2g/cT1ncmVlbiUyMHJvYm90cyIsCisgICAgICAgICAgICAgICAgdXJpLmdldFJhd1NjaGVtZVNwZWNpZmljUGFydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vdXNlcjpwYTU1dyUzRnJkQGhvc3Q6ODAvZG9jJTdDc2VhcmNoP3E9Z3JlZW4lMjByb2JvdHMjb3ZlciUyMDYlMjIiLAorICAgICAgICAgICAgICAgIHVyaS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2NoZW1lQ2FzZUlzTm90Q2Fub25pY2FsaXplZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiSFRUUDovL2hvc3QvcGF0aCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkhUVFAiLCB1cmkuZ2V0U2NoZW1lKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eUF1dGhvcml0eVdpdGhQYXRoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSB1cmkgPSBuZXcgVVJJKCJodHRwOi8vL3BhdGgiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVyaS5nZXRBdXRob3JpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL3BhdGgiLCB1cmkuZ2V0UGF0aCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW1wdHlBdXRob3JpdHlXaXRoUXVlcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJJIHVyaSA9IG5ldyBVUkkoImh0dHA6Ly8/cXVlcnkiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVyaS5nZXRBdXRob3JpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgdXJpLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygicXVlcnkiLCB1cmkuZ2V0UXVlcnkoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVtcHR5QXV0aG9yaXR5V2l0aEZyYWdtZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSB1cmkgPSBuZXcgVVJJKCJodHRwOi8vI2ZyYWdtZW50Iik7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCB1cmkuZ2V0QXV0aG9yaXR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHVyaS5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZyYWdtZW50IiwgdXJpLmdldEZyYWdtZW50KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbmNvZGluZ0NvbnN0cnVjdG9yc1JlZnVzZVJlbGF0aXZlUGF0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFVSSSgiaHR0cCIsICJob3N0IiwgInJlbGF0aXZlIiwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFVSSVN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVVJJKCJodHRwIiwgImhvc3QiLCAicmVsYXRpdmUiLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoVVJJU3ludGF4RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBVUkkoImh0dHAiLCBudWxsLCAiaG9zdCIsIC0xLCAicmVsYXRpdmUiLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoVVJJU3ludGF4RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5jb2RpbmdDb25zdHJ1Y3RvcnNBY2NlcHRFbXB0eVBhdGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBuZXcgVVJJKCJodHRwIiwgImhvc3QiLCAiIiwgbnVsbCkuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBuZXcgVVJJKCJodHRwIiwgImhvc3QiLCAiIiwgbnVsbCwgbnVsbCkuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBuZXcgVVJJKCJodHRwIiwgbnVsbCwgImhvc3QiLCAtMSwgIiIsIG51bGwsIG51bGwpLmdldFBhdGgoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlc29sdmVSZWxhdGl2ZUFuZEFic29sdXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSSSBhYnNvbHV0ZSA9IG5ldyBVUkkoImh0dHA6Ly9hbmRyb2lkLmNvbS8iKTsKKyAgICAgICAgVVJJIHJlbGF0aXZlID0gbmV3IFVSSSgicm9ib3RzLnR4dCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoYWJzb2x1dGUsIGFic29sdXRlLnJlc29sdmUoYWJzb2x1dGUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBVUkkoImh0dHA6Ly9hbmRyb2lkLmNvbS9yb2JvdHMudHh0IiksIGFic29sdXRlLnJlc29sdmUocmVsYXRpdmUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGFic29sdXRlLCByZWxhdGl2ZS5yZXNvbHZlKGFic29sdXRlKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhyZWxhdGl2ZSwgcmVsYXRpdmUucmVzb2x2ZShyZWxhdGl2ZSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWxhdGl2aXplUmVsYXRpdmVBbmRBYnNvbHV0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkkgYWJzb2x1dGUgPSBuZXcgVVJJKCJodHRwOi8vYW5kcm9pZC5jb20vIik7CisgICAgICAgIFVSSSByZWxhdGl2ZSA9IG5ldyBVUkkoInJvYm90cy50eHQiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlbGF0aXZlLCBhYnNvbHV0ZS5yZWxhdGl2aXplKG5ldyBVUkkoImh0dHA6Ly9hbmRyb2lkLmNvbS9yb2JvdHMudHh0IikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBVUkkoIiIpLCBhYnNvbHV0ZS5yZWxhdGl2aXplKGFic29sdXRlKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhyZWxhdGl2ZSwgYWJzb2x1dGUucmVsYXRpdml6ZShyZWxhdGl2ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYWJzb2x1dGUsIHJlbGF0aXZlLnJlbGF0aXZpemUoYWJzb2x1dGUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBVUkkoIiIpLCByZWxhdGl2ZS5yZWxhdGl2aXplKHJlbGF0aXZlKSk7CisgICAgfQorCisgICAgLy8gQWRkaW5nIGEgbmV3IHRlc3Q/IENvbnNpZGVyIGFkZGluZyBhbiBlcXVpdmFsZW50IHRlc3QgdG8gVVJMVGVzdC5qYXZhCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9VUkxDb25uZWN0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvVVJMQ29ubmVjdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMzA1YTgxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvVVJMQ29ubmVjdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDIxMDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uZXQ7CisKK2ltcG9ydCBjb20uZ29vZ2xlLm1vY2t3ZWJzZXJ2ZXIuTW9ja1Jlc3BvbnNlOworaW1wb3J0IGNvbS5nb29nbGUubW9ja3dlYnNlcnZlci5Nb2NrV2ViU2VydmVyOworaW1wb3J0IGNvbS5nb29nbGUubW9ja3dlYnNlcnZlci5SZWNvcmRlZFJlcXVlc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5tb2Nrd2Vic2VydmVyLlNvY2tldFBvbGljeTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5tb2Nrd2Vic2VydmVyLlNvY2tldFBvbGljeS5ESVNDT05ORUNUX0FUX0VORDsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5tb2Nrd2Vic2VydmVyLlNvY2tldFBvbGljeS5ESVNDT05ORUNUX0FUX1NUQVJUOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLm1vY2t3ZWJzZXJ2ZXIuU29ja2V0UG9saWN5LlNIVVRET1dOX0lOUFVUX0FUX0VORDsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5tb2Nrd2Vic2VydmVyLlNvY2tldFBvbGljeS5TSFVURE9XTl9PVVRQVVRfQVRfRU5EOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5BdXRoZW50aWNhdG9yOworaW1wb3J0IGphdmEubmV0LkNhY2hlUmVxdWVzdDsKK2ltcG9ydCBqYXZhLm5ldC5DYWNoZVJlc3BvbnNlOworaW1wb3J0IGphdmEubmV0LkNvbm5lY3RFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSHR0cFJldHJ5RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0Lkh0dHBVUkxDb25uZWN0aW9uOworaW1wb3J0IGphdmEubmV0LlBhc3N3b3JkQXV0aGVudGljYXRpb247CitpbXBvcnQgamF2YS5uZXQuUHJvdG9jb2xFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuUHJveHk7CitpbXBvcnQgamF2YS5uZXQuUmVzcG9uc2VDYWNoZTsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRUaW1lb3V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVSSTsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5uZXQuVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0Jvb2xlYW47CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY1JlZmVyZW5jZTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkdaSVBJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkdaSVBPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YXgubmV0LnNzbC5Ib3N0bmFtZVZlcmlmaWVyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuSHR0cHNVUkxDb25uZWN0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMQ29udGV4dDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEhhbmRzaGFrZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTb2NrZXRGYWN0b3J5OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuVHJ1c3RNYW5hZ2VyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuWDUwOVRydXN0TWFuYWdlcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgbGliY29yZS5qYXZhLnNlY3VyaXR5LlRlc3RLZXlTdG9yZTsKK2ltcG9ydCBsaWJjb3JlLmphdmF4Lm5ldC5zc2wuVGVzdFNTTENvbnRleHQ7CitpbXBvcnQgdGVzdHMubmV0LlN0dWNrU2VydmVyOworCitwdWJsaWMgZmluYWwgY2xhc3MgVVJMQ29ubmVjdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBBdXRoZW50aWNhdG9yIFNJTVBMRV9BVVRIRU5USUNBVE9SID0gbmV3IEF1dGhlbnRpY2F0b3IoKSB7CisgICAgICAgIHByb3RlY3RlZCBQYXNzd29yZEF1dGhlbnRpY2F0aW9uIGdldFBhc3N3b3JkQXV0aGVudGljYXRpb24oKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFBhc3N3b3JkQXV0aGVudGljYXRpb24oInVzZXJuYW1lIiwgInBhc3N3b3JkIi50b0NoYXJBcnJheSgpKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICAvKiogYmFzZTY0KCJ1c2VybmFtZTpwYXNzd29yZCIpICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEJBU0VfNjRfQ1JFREVOVElBTFMgPSAiZFhObGNtNWhiV1U2Y0dGemMzZHZjbVE9IjsKKworICAgIHByaXZhdGUgTW9ja1dlYlNlcnZlciBzZXJ2ZXIgPSBuZXcgTW9ja1dlYlNlcnZlcigpOworICAgIHByaXZhdGUgU3RyaW5nIGhvc3ROYW1lOworCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIGhvc3ROYW1lID0gc2VydmVyLmdldEhvc3ROYW1lKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFJlc3BvbnNlQ2FjaGUuc2V0RGVmYXVsdChudWxsKTsKKyAgICAgICAgQXV0aGVudGljYXRvci5zZXREZWZhdWx0KG51bGwpOworICAgICAgICBTeXN0ZW0uY2xlYXJQcm9wZXJ0eSgicHJveHlIb3N0Iik7CisgICAgICAgIFN5c3RlbS5jbGVhclByb3BlcnR5KCJwcm94eVBvcnQiKTsKKyAgICAgICAgU3lzdGVtLmNsZWFyUHJvcGVydHkoImh0dHAucHJveHlIb3N0Iik7CisgICAgICAgIFN5c3RlbS5jbGVhclByb3BlcnR5KCJodHRwLnByb3h5UG9ydCIpOworICAgICAgICBTeXN0ZW0uY2xlYXJQcm9wZXJ0eSgiaHR0cHMucHJveHlIb3N0Iik7CisgICAgICAgIFN5c3RlbS5jbGVhclByb3BlcnR5KCJodHRwcy5wcm94eVBvcnQiKTsKKyAgICAgICAgc2VydmVyLnNodXRkb3duKCk7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlcXVlc3RIZWFkZXJzKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gdXJsQ29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIHVybENvbm5lY3Rpb24uYWRkUmVxdWVzdFByb3BlcnR5KCJEIiwgImUiKTsKKyAgICAgICAgdXJsQ29ubmVjdGlvbi5hZGRSZXF1ZXN0UHJvcGVydHkoIkQiLCAiZiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImYiLCB1cmxDb25uZWN0aW9uLmdldFJlcXVlc3RQcm9wZXJ0eSgiRCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmIiwgdXJsQ29ubmVjdGlvbi5nZXRSZXF1ZXN0UHJvcGVydHkoImQiKSk7CisgICAgICAgIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gcmVxdWVzdEhlYWRlcnMgPSB1cmxDb25uZWN0aW9uLmdldFJlcXVlc3RQcm9wZXJ0aWVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXdTZXQoImUiLCAiZiIpLCBuZXcgSGFzaFNldDxTdHJpbmc+KHJlcXVlc3RIZWFkZXJzLmdldCgiRCIpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXdTZXQoImUiLCAiZiIpLCBuZXcgSGFzaFNldDxTdHJpbmc+KHJlcXVlc3RIZWFkZXJzLmdldCgiZCIpKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXF1ZXN0SGVhZGVycy5wdXQoIkciLCBBcnJheXMuYXNMaXN0KCJoIikpOworICAgICAgICAgICAgZmFpbCgiTW9kaWZpZWQgYW4gdW5tb2RpZmlhYmxlIHZpZXcuIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcXVlc3RIZWFkZXJzLmdldCgiRCIpLmFkZCgiaSIpOworICAgICAgICAgICAgZmFpbCgiTW9kaWZpZWQgYW4gdW5tb2RpZmlhYmxlIHZpZXcuIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHVybENvbm5lY3Rpb24uc2V0UmVxdWVzdFByb3BlcnR5KG51bGwsICJqIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHVybENvbm5lY3Rpb24uYWRkUmVxdWVzdFByb3BlcnR5KG51bGwsICJrIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdXJsQ29ubmVjdGlvbi5zZXRSZXF1ZXN0UHJvcGVydHkoIk51bGxWYWx1ZSIsIG51bGwpOyAvLyBzaG91bGQgZmFpbCBzaWxlbnRseSEKKyAgICAgICAgYXNzZXJ0TnVsbCh1cmxDb25uZWN0aW9uLmdldFJlcXVlc3RQcm9wZXJ0eSgiTnVsbFZhbHVlIikpOworICAgICAgICB1cmxDb25uZWN0aW9uLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQW5vdGhlck51bGxWYWx1ZSIsIG51bGwpOyAgLy8gc2hvdWxkIGZhaWwgc2lsZW50bHkhCisgICAgICAgIGFzc2VydE51bGwodXJsQ29ubmVjdGlvbi5nZXRSZXF1ZXN0UHJvcGVydHkoIkFub3RoZXJOdWxsVmFsdWUiKSk7CisKKyAgICAgICAgdXJsQ29ubmVjdGlvbi5nZXRSZXNwb25zZUNvZGUoKTsKKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IHJlcXVlc3QgPSBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsKKyAgICAgICAgYXNzZXJ0Q29udGFpbnMocmVxdWVzdC5nZXRIZWFkZXJzKCksICJEOiBlIik7CisgICAgICAgIGFzc2VydENvbnRhaW5zKHJlcXVlc3QuZ2V0SGVhZGVycygpLCAiRDogZiIpOworICAgICAgICBhc3NlcnRDb250YWluc05vbmVNYXRjaGluZyhyZXF1ZXN0LmdldEhlYWRlcnMoKSwgIk51bGxWYWx1ZS4qIik7CisgICAgICAgIGFzc2VydENvbnRhaW5zTm9uZU1hdGNoaW5nKHJlcXVlc3QuZ2V0SGVhZGVycygpLCAiQW5vdGhlck51bGxWYWx1ZS4qIik7CisgICAgICAgIGFzc2VydENvbnRhaW5zTm9uZU1hdGNoaW5nKHJlcXVlc3QuZ2V0SGVhZGVycygpLCAiRzouKiIpOworICAgICAgICBhc3NlcnRDb250YWluc05vbmVNYXRjaGluZyhyZXF1ZXN0LmdldEhlYWRlcnMoKSwgIm51bGw6LioiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdXJsQ29ubmVjdGlvbi5hZGRSZXF1ZXN0UHJvcGVydHkoIk4iLCAibyIpOworICAgICAgICAgICAgZmFpbCgiU2V0IGhlYWRlciBhZnRlciBjb25uZWN0Iik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB1cmxDb25uZWN0aW9uLnNldFJlcXVlc3RQcm9wZXJ0eSgiUCIsICJxIik7CisgICAgICAgICAgICBmYWlsKCJTZXQgaGVhZGVyIGFmdGVyIGNvbm5lY3QiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHVybENvbm5lY3Rpb24uZ2V0UmVxdWVzdFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UmVxdWVzdFByb3BlcnR5UmV0dXJuc0xhc3RWYWx1ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIucGxheSgpOworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiB1cmxDb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgdXJsQ29ubmVjdGlvbi5hZGRSZXF1ZXN0UHJvcGVydHkoIkEiLCAidmFsdWUxIik7CisgICAgICAgIHVybENvbm5lY3Rpb24uYWRkUmVxdWVzdFByb3BlcnR5KCJBIiwgInZhbHVlMiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlMiIsIHVybENvbm5lY3Rpb24uZ2V0UmVxdWVzdFByb3BlcnR5KCJBIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXNwb25zZUhlYWRlcnMoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLnNldFN0YXR1cygiSFRUUC8xLjAgMjAwIEZhbnRhc3RpYyIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQTogYyIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQjogZCIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQTogZSIpCisgICAgICAgICAgICAgICAgLnNldENodW5rZWRCb2R5KCJBQkNERVxuRkdISUpcbktMTU5PXG5QUVIiLCA4KSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gdXJsQ29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyMDAsIHVybENvbm5lY3Rpb24uZ2V0UmVzcG9uc2VDb2RlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhbnRhc3RpYyIsIHVybENvbm5lY3Rpb24uZ2V0UmVzcG9uc2VNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkhUVFAvMS4wIDIwMCBGYW50YXN0aWMiLCB1cmxDb25uZWN0aW9uLmdldEhlYWRlckZpZWxkKG51bGwpKTsKKyAgICAgICAgTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PiByZXNwb25zZUhlYWRlcnMgPSB1cmxDb25uZWN0aW9uLmdldEhlYWRlckZpZWxkcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdCgiSFRUUC8xLjAgMjAwIEZhbnRhc3RpYyIpLCByZXNwb25zZUhlYWRlcnMuZ2V0KG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ld1NldCgiYyIsICJlIiksIG5ldyBIYXNoU2V0PFN0cmluZz4ocmVzcG9uc2VIZWFkZXJzLmdldCgiQSIpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXdTZXQoImMiLCAiZSIpLCBuZXcgSGFzaFNldDxTdHJpbmc+KHJlc3BvbnNlSGVhZGVycy5nZXQoImEiKSkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzcG9uc2VIZWFkZXJzLnB1dCgiTiIsIEFycmF5cy5hc0xpc3QoIm8iKSk7CisgICAgICAgICAgICBmYWlsKCJNb2RpZmllZCBhbiB1bm1vZGlmaWFibGUgdmlldy4iKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzcG9uc2VIZWFkZXJzLmdldCgiQSIpLmFkZCgiZiIpOworICAgICAgICAgICAgZmFpbCgiTW9kaWZpZWQgYW4gdW5tb2RpZmlhYmxlIHZpZXcuIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgdXJsQ29ubmVjdGlvbi5nZXRIZWFkZXJGaWVsZEtleSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYyIsIHVybENvbm5lY3Rpb24uZ2V0SGVhZGVyRmllbGQoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkIiLCB1cmxDb25uZWN0aW9uLmdldEhlYWRlckZpZWxkS2V5KDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkIiwgdXJsQ29ubmVjdGlvbi5nZXRIZWFkZXJGaWVsZCgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHVybENvbm5lY3Rpb24uZ2V0SGVhZGVyRmllbGRLZXkoMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImUiLCB1cmxDb25uZWN0aW9uLmdldEhlYWRlckZpZWxkKDIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RXJyb3JTdHJlYW1PblN1Y2Nlc3NmdWxSZXF1ZXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjb25uZWN0aW9uLmdldEVycm9yU3RyZWFtKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRFcnJvclN0cmVhbU9uVW5zdWNjZXNzZnVsUmVxdWVzdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0UmVzcG9uc2VDb2RlKDQwNCkuc2V0Qm9keSgiQSIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShjb25uZWN0aW9uLmdldEVycm9yU3RyZWFtKCksIEludGVnZXIuTUFYX1ZBTFVFKSk7CisgICAgfQorCisgICAgLy8gQ2hlY2sgdGhhdCBpZiB3ZSBkb24ndCByZWFkIHRvIHRoZSBlbmQgb2YgYSByZXNwb25zZSwgdGhlIG5leHQgcmVxdWVzdCBvbiB0aGUKKyAgICAvLyByZWN5Y2xlZCBjb25uZWN0aW9uIGRvZXNuJ3QgZ2V0IHRoZSB1bnJlYWQgdGFpbCBvZiB0aGUgZmlyc3QgcmVxdWVzdCdzIHJlc3BvbnNlLgorICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9MjkzOQorICAgIHB1YmxpYyB2b2lkIHRlc3RfMjkzOSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNb2NrUmVzcG9uc2UgcmVzcG9uc2UgPSBuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Q2h1bmtlZEJvZHkoIkFCQ0RFXG5GR0hJSlxuS0xNTk9cblBRUiIsIDgpOworCisgICAgICAgIHNlcnZlci5lbnF1ZXVlKHJlc3BvbnNlKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUocmVzcG9uc2UpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIGFzc2VydENvbnRlbnQoIkFCQ0RFIiwgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCksIDUpOworICAgICAgICBhc3NlcnRDb250ZW50KCJBQkNERSIsIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpLCA1KTsKKyAgICB9CisKKyAgICAvLyBDaGVjayB0aGF0IHdlIHJlY29nbml6ZSBhIGZldyBiYXNpYyBtaW1lIHR5cGVzIGJ5IGV4dGVuc2lvbi4KKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTEwMTAwCisgICAgcHVibGljIHZvaWQgdGVzdF8xMDEwMCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoImltYWdlL2pwZWciLCBVUkxDb25uZWN0aW9uLmd1ZXNzQ29udGVudFR5cGVGcm9tTmFtZSgic29tZUZpbGUuanBnIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFwcGxpY2F0aW9uL3BkZiIsIFVSTENvbm5lY3Rpb24uZ3Vlc3NDb250ZW50VHlwZUZyb21OYW1lKCJzdHVmZi5wZGYiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbm5lY3Rpb25zQXJlUG9vbGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1vY2tSZXNwb25zZSByZXNwb25zZSA9IG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJBQkNERUZHSElKS0xNTk9QUVIiKTsKKworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShyZXNwb25zZSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKHJlc3BvbnNlKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUocmVzcG9uc2UpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIGFzc2VydENvbnRlbnQoIkFCQ0RFRkdISUpLTE1OT1BRUiIsIHNlcnZlci5nZXRVcmwoIi9mb28iKS5vcGVuQ29ubmVjdGlvbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHNlcnZlci50YWtlUmVxdWVzdCgpLmdldFNlcXVlbmNlTnVtYmVyKCkpOworICAgICAgICBhc3NlcnRDb250ZW50KCJBQkNERUZHSElKS0xNTk9QUVIiLCBzZXJ2ZXIuZ2V0VXJsKCIvYmFyP2Jhej1xdXV4Iikub3BlbkNvbm5lY3Rpb24oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBzZXJ2ZXIudGFrZVJlcXVlc3QoKS5nZXRTZXF1ZW5jZU51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0Q29udGVudCgiQUJDREVGR0hJSktMTU5PUFFSIiwgc2VydmVyLmdldFVybCgiL3oiKS5vcGVuQ29ubmVjdGlvbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHNlcnZlci50YWtlUmVxdWVzdCgpLmdldFNlcXVlbmNlTnVtYmVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDaHVua2VkQ29ubmVjdGlvbnNBcmVQb29sZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja1Jlc3BvbnNlIHJlc3BvbnNlID0gbmV3IE1vY2tSZXNwb25zZSgpLnNldENodW5rZWRCb2R5KCJBQkNERUZHSElKS0xNTk9QUVIiLCA1KTsKKworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShyZXNwb25zZSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKHJlc3BvbnNlKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUocmVzcG9uc2UpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIGFzc2VydENvbnRlbnQoIkFCQ0RFRkdISUpLTE1OT1BRUiIsIHNlcnZlci5nZXRVcmwoIi9mb28iKS5vcGVuQ29ubmVjdGlvbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHNlcnZlci50YWtlUmVxdWVzdCgpLmdldFNlcXVlbmNlTnVtYmVyKCkpOworICAgICAgICBhc3NlcnRDb250ZW50KCJBQkNERUZHSElKS0xNTk9QUVIiLCBzZXJ2ZXIuZ2V0VXJsKCIvYmFyP2Jhej1xdXV4Iikub3BlbkNvbm5lY3Rpb24oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBzZXJ2ZXIudGFrZVJlcXVlc3QoKS5nZXRTZXF1ZW5jZU51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0Q29udGVudCgiQUJDREVGR0hJSktMTU5PUFFSIiwgc2VydmVyLmdldFVybCgiL3oiKS5vcGVuQ29ubmVjdGlvbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHNlcnZlci50YWtlUmVxdWVzdCgpLmdldFNlcXVlbmNlTnVtYmVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXJ2ZXJDbG9zZXNTb2NrZXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFNlcnZlckNsb3Nlc091dHB1dChESVNDT05ORUNUX0FUX0VORCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNlcnZlclNodXRkb3duSW5wdXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFNlcnZlckNsb3Nlc091dHB1dChTSFVURE9XTl9JTlBVVF9BVF9FTkQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXJ2ZXJTaHV0ZG93bk91dHB1dCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0U2VydmVyQ2xvc2VzT3V0cHV0KFNIVVRET1dOX09VVFBVVF9BVF9FTkQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0U2VydmVyQ2xvc2VzT3V0cHV0KFNvY2tldFBvbGljeSBzb2NrZXRQb2xpY3kpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuc2V0Qm9keSgiVGhpcyBjb25uZWN0aW9uIHdvbid0IHBvb2wgcHJvcGVybHkiKQorICAgICAgICAgICAgICAgIC5zZXRTb2NrZXRQb2xpY3koc29ja2V0UG9saWN5KSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJUaGlzIGNvbWVzIGFmdGVyIGEgYnVzdGVkIGNvbm5lY3Rpb24iKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgYXNzZXJ0Q29udGVudCgiVGhpcyBjb25uZWN0aW9uIHdvbid0IHBvb2wgcHJvcGVybHkiLCBzZXJ2ZXIuZ2V0VXJsKCIvYSIpLm9wZW5Db25uZWN0aW9uKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgc2VydmVyLnRha2VSZXF1ZXN0KCkuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7CisgICAgICAgIGFzc2VydENvbnRlbnQoIlRoaXMgY29tZXMgYWZ0ZXIgYSBidXN0ZWQgY29ubmVjdGlvbiIsIHNlcnZlci5nZXRVcmwoIi9iIikub3BlbkNvbm5lY3Rpb24oKSk7CisgICAgICAgIC8vIHNlcXVlbmNlIG51bWJlciAwIG1lYW5zIHRoZSBIVFRQIHNvY2tldCBjb25uZWN0aW9uIHdhcyBub3QgcmV1c2VkCisgICAgICAgIGFzc2VydEVxdWFscygwLCBzZXJ2ZXIudGFrZVJlcXVlc3QoKS5nZXRTZXF1ZW5jZU51bWJlcigpKTsKKyAgICB9CisKKyAgICBlbnVtIFdyaXRlS2luZCB7IEJZVEVfQllfQllURSwgU01BTExfQlVGRkVSUywgTEFSR0VfQlVGRkVSUyB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NodW5rZWRVcGxvYWRfYnl0ZUJ5Qnl0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkb1VwbG9hZChUcmFuc2ZlcktpbmQuQ0hVTktFRCwgV3JpdGVLaW5kLkJZVEVfQllfQllURSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jaHVua2VkVXBsb2FkX3NtYWxsQnVmZmVycygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkb1VwbG9hZChUcmFuc2ZlcktpbmQuQ0hVTktFRCwgV3JpdGVLaW5kLlNNQUxMX0JVRkZFUlMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2h1bmtlZFVwbG9hZF9sYXJnZUJ1ZmZlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZG9VcGxvYWQoVHJhbnNmZXJLaW5kLkNIVU5LRUQsIFdyaXRlS2luZC5MQVJHRV9CVUZGRVJTKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ZpeGVkTGVuZ3RoVXBsb2FkX2J5dGVCeUJ5dGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZG9VcGxvYWQoVHJhbnNmZXJLaW5kLkZJWEVEX0xFTkdUSCwgV3JpdGVLaW5kLkJZVEVfQllfQllURSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9maXhlZExlbmd0aFVwbG9hZF9zbWFsbEJ1ZmZlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZG9VcGxvYWQoVHJhbnNmZXJLaW5kLkZJWEVEX0xFTkdUSCwgV3JpdGVLaW5kLlNNQUxMX0JVRkZFUlMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZml4ZWRMZW5ndGhVcGxvYWRfbGFyZ2VCdWZmZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRvVXBsb2FkKFRyYW5zZmVyS2luZC5GSVhFRF9MRU5HVEgsIFdyaXRlS2luZC5MQVJHRV9CVUZGRVJTKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZG9VcGxvYWQoVHJhbnNmZXJLaW5kIHVwbG9hZEtpbmQsIFdyaXRlS2luZCB3cml0ZUtpbmQpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbnQgbiA9IDUxMioxMDI0OworICAgICAgICBzZXJ2ZXIuc2V0Qm9keUxpbWl0KDApOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm4gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uLnNldERvT3V0cHV0KHRydWUpOworICAgICAgICBjb25uLnNldFJlcXVlc3RNZXRob2QoIlBPU1QiKTsKKyAgICAgICAgaWYgKHVwbG9hZEtpbmQgPT0gVHJhbnNmZXJLaW5kLkNIVU5LRUQpIHsKKyAgICAgICAgICAgIGNvbm4uc2V0Q2h1bmtlZFN0cmVhbWluZ01vZGUoLTEpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY29ubi5zZXRGaXhlZExlbmd0aFN0cmVhbWluZ01vZGUobik7CisgICAgICAgIH0KKyAgICAgICAgT3V0cHV0U3RyZWFtIG91dCA9IGNvbm4uZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGlmICh3cml0ZUtpbmQgPT0gV3JpdGVLaW5kLkJZVEVfQllfQllURSkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyArK2kpIHsKKyAgICAgICAgICAgICAgICBvdXQud3JpdGUoJ3gnKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVt3cml0ZUtpbmQgPT0gV3JpdGVLaW5kLlNNQUxMX0JVRkZFUlMgPyAyNTYgOiA2NCoxMDI0XTsKKyAgICAgICAgICAgIEFycmF5cy5maWxsKGJ1ZiwgKGJ5dGUpICd4Jyk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkgKz0gYnVmLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIG91dC53cml0ZShidWYsIDAsIE1hdGgubWluKGJ1Zi5sZW5ndGgsIG4gLSBpKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyMDAsIGNvbm4uZ2V0UmVzcG9uc2VDb2RlKCkpOworICAgICAgICBSZWNvcmRlZFJlcXVlc3QgcmVxdWVzdCA9IHNlcnZlci50YWtlUmVxdWVzdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMobiwgcmVxdWVzdC5nZXRCb2R5U2l6ZSgpKTsKKyAgICAgICAgaWYgKHVwbG9hZEtpbmQgPT0gVHJhbnNmZXJLaW5kLkNIVU5LRUQpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUocmVxdWVzdC5nZXRDaHVua1NpemVzKCkuc2l6ZSgpID4gMCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHJlcXVlc3QuZ2V0Q2h1bmtTaXplcygpLmlzRW1wdHkoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UmVzcG9uc2VDb2RlTm9SZXNwb25zZUJvZHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiYWJjOiBkZWYiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMIHVybCA9IHNlcnZlci5nZXRVcmwoIi8iKTsKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubiA9IChIdHRwVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm4uc2V0RG9JbnB1dChmYWxzZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZGVmIiwgY29ubi5nZXRIZWFkZXJGaWVsZCgiYWJjIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMjAwLCBjb25uLmdldFJlc3BvbnNlQ29kZSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25uZWN0VmlhSHR0cHMoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgdGVzdFNTTENvbnRleHQgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKworICAgICAgICBzZXJ2ZXIudXNlSHR0cHModGVzdFNTTENvbnRleHQuc2VydmVyQ29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCksIGZhbHNlKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoInRoaXMgcmVzcG9uc2UgY29tZXMgdmlhIEhUVFBTIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiL2ZvbyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0U1NMU29ja2V0RmFjdG9yeSh0ZXN0U1NMQ29udGV4dC5jbGllbnRDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKSk7CisKKyAgICAgICAgYXNzZXJ0Q29udGVudCgidGhpcyByZXNwb25zZSBjb21lcyB2aWEgSFRUUFMiLCBjb25uZWN0aW9uKTsKKworICAgICAgICBSZWNvcmRlZFJlcXVlc3QgcmVxdWVzdCA9IHNlcnZlci50YWtlUmVxdWVzdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkdFVCAvZm9vIEhUVFAvMS4xIiwgcmVxdWVzdC5nZXRSZXF1ZXN0TGluZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29ubmVjdFZpYUh0dHBzUmV1c2luZ0Nvbm5lY3Rpb25zKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IHRlc3RTU0xDb250ZXh0ID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisKKyAgICAgICAgc2VydmVyLnVzZUh0dHBzKHRlc3RTU0xDb250ZXh0LnNlcnZlckNvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLCBmYWxzZSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJ0aGlzIHJlc3BvbnNlIGNvbWVzIHZpYSBIVFRQUyIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoImFub3RoZXIgcmVzcG9uc2UgdmlhIEhUVFBTIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0U1NMU29ja2V0RmFjdG9yeSh0ZXN0U1NMQ29udGV4dC5jbGllbnRDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKSk7CisgICAgICAgIGFzc2VydENvbnRlbnQoInRoaXMgcmVzcG9uc2UgY29tZXMgdmlhIEhUVFBTIiwgY29ubmVjdGlvbik7CisKKyAgICAgICAgY29ubmVjdGlvbiA9IChIdHRwc1VSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLnNldFNTTFNvY2tldEZhY3RvcnkodGVzdFNTTENvbnRleHQuY2xpZW50Q29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkpOworICAgICAgICBhc3NlcnRDb250ZW50KCJhbm90aGVyIHJlc3BvbnNlIHZpYSBIVFRQUyIsIGNvbm5lY3Rpb24pOworCisgICAgICAgIGFzc2VydEVxdWFscygwLCBzZXJ2ZXIudGFrZVJlcXVlc3QoKS5nZXRTZXF1ZW5jZU51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHNlcnZlci50YWtlUmVxdWVzdCgpLmdldFNlcXVlbmNlTnVtYmVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25uZWN0VmlhSHR0cHNSZXVzaW5nQ29ubmVjdGlvbnNEaWZmZXJlbnRGYWN0b3JpZXMoKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IHRlc3RTU0xDb250ZXh0ID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisKKyAgICAgICAgc2VydmVyLnVzZUh0dHBzKHRlc3RTU0xDb250ZXh0LnNlcnZlckNvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLCBmYWxzZSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJ0aGlzIHJlc3BvbnNlIGNvbWVzIHZpYSBIVFRQUyIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoImFub3RoZXIgcmVzcG9uc2UgdmlhIEhUVFBTIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIC8vIGluc3RhbGwgYSBjdXN0b20gU1NMIHNvY2tldCBmYWN0b3J5IHNvIHRoZSBzZXJ2ZXIgY2FuIGJlIGF1dGhvcml6ZWQKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXRTU0xTb2NrZXRGYWN0b3J5KHRlc3RTU0xDb250ZXh0LmNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpKTsKKyAgICAgICAgYXNzZXJ0Q29udGVudCgidGhpcyByZXNwb25zZSBjb21lcyB2aWEgSFRUUFMiLCBjb25uZWN0aW9uKTsKKworICAgICAgICBjb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkQXNjaWkoY29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJ3aXRob3V0IGFuIFNTTCBzb2NrZXQgZmFjdG9yeSwgdGhlIGNvbm5lY3Rpb24gc2hvdWxkIGZhaWwiKTsKKyAgICAgICAgfSBjYXRjaCAoU1NMRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29ubmVjdFZpYUh0dHBzV2l0aFNTTEZhbGxiYWNrKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IHRlc3RTU0xDb250ZXh0ID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisKKyAgICAgICAgc2VydmVyLnVzZUh0dHBzKHRlc3RTU0xDb250ZXh0LnNlcnZlckNvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLCBmYWxzZSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRTb2NrZXRQb2xpY3koRElTQ09OTkVDVF9BVF9TVEFSVCkpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgidGhpcyByZXNwb25zZSBjb21lcyB2aWEgU1NMIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiL2ZvbyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0U1NMU29ja2V0RmFjdG9yeSh0ZXN0U1NMQ29udGV4dC5jbGllbnRDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKSk7CisKKyAgICAgICAgYXNzZXJ0Q29udGVudCgidGhpcyByZXNwb25zZSBjb21lcyB2aWEgU1NMIiwgY29ubmVjdGlvbik7CisKKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IHJlcXVlc3QgPSBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHRVQgL2ZvbyBIVFRQLzEuMSIsIHJlcXVlc3QuZ2V0UmVxdWVzdExpbmUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVmVyaWZ5IHRoYXQgd2UgZG9uJ3QgcmV0cnkgY29ubmVjdGlvbnMgb24gY2VydGlmaWNhdGUgdmVyaWZpY2F0aW9uIGVycm9ycy4KKyAgICAgKgorICAgICAqIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9MTMxNzgKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29ubmVjdFZpYUh0dHBzVG9VbnRydXN0ZWRTZXJ2ZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgdGVzdFNTTENvbnRleHQgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoVGVzdEtleVN0b3JlLmdldENsaWVudENBMigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUZXN0S2V5U3RvcmUuZ2V0U2VydmVyKCkpOworCisgICAgICAgIHNlcnZlci51c2VIdHRwcyh0ZXN0U1NMQ29udGV4dC5zZXJ2ZXJDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKSwgZmFsc2UpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkpOyAvLyB1bnVzZWQKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwc1VSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi9mb28iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLnNldFNTTFNvY2tldEZhY3RvcnkodGVzdFNTTENvbnRleHQuY2xpZW50Q29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTU0xIYW5kc2hha2VFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZXhwZWN0ZWQuZ2V0Q2F1c2UoKSBpbnN0YW5jZW9mIENlcnRpZmljYXRlRXhjZXB0aW9uKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoMCwgc2VydmVyLmdldFJlcXVlc3RDb3VudCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29ubmVjdFZpYVByb3h5VXNpbmdQcm94eUFyZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Q29ubmVjdFZpYVByb3h5KFByb3h5Q29uZmlnLkNSRUFURV9BUkcpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25uZWN0VmlhUHJveHlVc2luZ1Byb3h5U3lzdGVtUHJvcGVydHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdENvbm5lY3RWaWFQcm94eShQcm94eUNvbmZpZy5QUk9YWV9TWVNURU1fUFJPUEVSVFkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25uZWN0VmlhUHJveHlVc2luZ0h0dHBQcm94eVN5c3RlbVByb3BlcnR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RDb25uZWN0VmlhUHJveHkoUHJveHlDb25maWcuSFRUUF9QUk9YWV9TWVNURU1fUFJPUEVSVFkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0Q29ubmVjdFZpYVByb3h5KFByb3h5Q29uZmlnIHByb3h5Q29uZmlnKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja1Jlc3BvbnNlIG1vY2tSZXNwb25zZSA9IG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJ0aGlzIHJlc3BvbnNlIGNvbWVzIHZpYSBhIHByb3h5Iik7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG1vY2tSZXNwb25zZSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6Ly9hbmRyb2lkLmNvbS9mb28iKTsKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IHByb3h5Q29uZmlnLmNvbm5lY3Qoc2VydmVyLCB1cmwpOworICAgICAgICBhc3NlcnRDb250ZW50KCJ0aGlzIHJlc3BvbnNlIGNvbWVzIHZpYSBhIHByb3h5IiwgY29ubmVjdGlvbik7CisKKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IHJlcXVlc3QgPSBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHRVQgaHR0cDovL2FuZHJvaWQuY29tL2ZvbyBIVFRQLzEuMSIsIHJlcXVlc3QuZ2V0UmVxdWVzdExpbmUoKSk7CisgICAgICAgIGFzc2VydENvbnRhaW5zKHJlcXVlc3QuZ2V0SGVhZGVycygpLCAiSG9zdDogYW5kcm9pZC5jb20iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29udGVudERpc2FncmVlc1dpdGhDb250ZW50TGVuZ3RoSGVhZGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoImFiY1xyXG5ZT1UgU0hPVUxEIE5PVCBTRUUgVEhJUyIpCisgICAgICAgICAgICAgICAgLmNsZWFySGVhZGVycygpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ29udGVudC1MZW5ndGg6IDMiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgYXNzZXJ0Q29udGVudCgiYWJjIiwgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb250ZW50RGlzYWdyZWVzV2l0aENodW5rZWRIZWFkZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBNb2NrUmVzcG9uc2UgbW9ja1Jlc3BvbnNlID0gbmV3IE1vY2tSZXNwb25zZSgpOworICAgICAgICBtb2NrUmVzcG9uc2Uuc2V0Q2h1bmtlZEJvZHkoImFiYyIsIDMpOworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZXNPdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGJ5dGVzT3V0LndyaXRlKG1vY2tSZXNwb25zZS5nZXRCb2R5KCkpOworICAgICAgICBieXRlc091dC53cml0ZSgiXHJcbllPVSBTSE9VTEQgTk9UIFNFRSBUSElTIi5nZXRCeXRlcygpKTsKKyAgICAgICAgbW9ja1Jlc3BvbnNlLnNldEJvZHkoYnl0ZXNPdXQudG9CeXRlQXJyYXkoKSk7CisgICAgICAgIG1vY2tSZXNwb25zZS5jbGVhckhlYWRlcnMoKTsKKyAgICAgICAgbW9ja1Jlc3BvbnNlLmFkZEhlYWRlcigiVHJhbnNmZXItZW5jb2Rpbmc6IGNodW5rZWQiKTsKKworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShtb2NrUmVzcG9uc2UpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIGFzc2VydENvbnRlbnQoImFiYyIsIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29ubmVjdFZpYUh0dHBQcm94eVRvSHR0cHNVc2luZ1Byb3h5QXJnV2l0aE5vUHJveHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdENvbm5lY3RWaWFEaXJlY3RQcm94eVRvSHR0cHMoUHJveHlDb25maWcuTk9fUFJPWFkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25uZWN0VmlhSHR0cFByb3h5VG9IdHRwc1VzaW5nSHR0cFByb3h5U3lzdGVtUHJvcGVydHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gaHR0cHMgc2hvdWxkIG5vdCB1c2UgaHR0cCBwcm94eQorICAgICAgICB0ZXN0Q29ubmVjdFZpYURpcmVjdFByb3h5VG9IdHRwcyhQcm94eUNvbmZpZy5IVFRQX1BST1hZX1NZU1RFTV9QUk9QRVJUWSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RDb25uZWN0VmlhRGlyZWN0UHJveHlUb0h0dHBzKFByb3h5Q29uZmlnIHByb3h5Q29uZmlnKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgdGVzdFNTTENvbnRleHQgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKworICAgICAgICBzZXJ2ZXIudXNlSHR0cHModGVzdFNTTENvbnRleHQuc2VydmVyQ29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCksIGZhbHNlKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoInRoaXMgcmVzcG9uc2UgY29tZXMgdmlhIEhUVFBTIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTCB1cmwgPSBzZXJ2ZXIuZ2V0VXJsKCIvZm9vIik7CisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgcHJveHlDb25maWcuY29ubmVjdChzZXJ2ZXIsIHVybCk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0U1NMU29ja2V0RmFjdG9yeSh0ZXN0U1NMQ29udGV4dC5jbGllbnRDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKSk7CisKKyAgICAgICAgYXNzZXJ0Q29udGVudCgidGhpcyByZXNwb25zZSBjb21lcyB2aWEgSFRUUFMiLCBjb25uZWN0aW9uKTsKKworICAgICAgICBSZWNvcmRlZFJlcXVlc3QgcmVxdWVzdCA9IHNlcnZlci50YWtlUmVxdWVzdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkdFVCAvZm9vIEhUVFAvMS4xIiwgcmVxdWVzdC5nZXRSZXF1ZXN0TGluZSgpKTsKKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25uZWN0VmlhSHR0cFByb3h5VG9IdHRwc1VzaW5nUHJveHlBcmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdENvbm5lY3RWaWFIdHRwUHJveHlUb0h0dHBzKFByb3h5Q29uZmlnLkNSRUFURV9BUkcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdlIHdlcmVuJ3QgaG9ub3JpbmcgYWxsIG9mIHRoZSBhcHByb3ByaWF0ZSBwcm94eSBzeXN0ZW0gcHJvcGVydGllcyB3aGVuCisgICAgICogY29ubmVjdGluZyB2aWEgSFRUUFMuIGh0dHA6Ly9iLzMwOTc1MTgKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29ubmVjdFZpYUh0dHBQcm94eVRvSHR0cHNVc2luZ1Byb3h5U3lzdGVtUHJvcGVydHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdENvbm5lY3RWaWFIdHRwUHJveHlUb0h0dHBzKFByb3h5Q29uZmlnLlBST1hZX1NZU1RFTV9QUk9QRVJUWSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbm5lY3RWaWFIdHRwUHJveHlUb0h0dHBzVXNpbmdIdHRwc1Byb3h5U3lzdGVtUHJvcGVydHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdENvbm5lY3RWaWFIdHRwUHJveHlUb0h0dHBzKFByb3h5Q29uZmlnLkhUVFBTX1BST1hZX1NZU1RFTV9QUk9QRVJUWSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2Ugd2VyZSB2ZXJpZnlpbmcgdGhlIHdyb25nIGhvc3RuYW1lIHdoZW4gY29ubmVjdGluZyB0byBhbiBIVFRQUyBzaXRlCisgICAgICogdGhyb3VnaCBhIHByb3h5LiBodHRwOi8vYi8zMDk3Mjc3CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RDb25uZWN0VmlhSHR0cFByb3h5VG9IdHRwcyhQcm94eUNvbmZpZyBwcm94eUNvbmZpZykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IHRlc3RTU0xDb250ZXh0ID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIFJlY29yZGluZ0hvc3RuYW1lVmVyaWZpZXIgaG9zdG5hbWVWZXJpZmllciA9IG5ldyBSZWNvcmRpbmdIb3N0bmFtZVZlcmlmaWVyKCk7CisKKyAgICAgICAgc2VydmVyLnVzZUh0dHBzKHRlc3RTU0xDb250ZXh0LnNlcnZlckNvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLCB0cnVlKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLnNldFNvY2tldFBvbGljeShTb2NrZXRQb2xpY3kuVVBHUkFERV9UT19TU0xfQVRfRU5EKQorICAgICAgICAgICAgICAgIC5jbGVhckhlYWRlcnMoKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJ0aGlzIHJlc3BvbnNlIGNvbWVzIHZpYSBhIHNlY3VyZSBwcm94eSIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cHM6Ly9hbmRyb2lkLmNvbS9mb28iKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKSBwcm94eUNvbmZpZy5jb25uZWN0KHNlcnZlciwgdXJsKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXRTU0xTb2NrZXRGYWN0b3J5KHRlc3RTU0xDb250ZXh0LmNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXRIb3N0bmFtZVZlcmlmaWVyKGhvc3RuYW1lVmVyaWZpZXIpOworCisgICAgICAgIGFzc2VydENvbnRlbnQoInRoaXMgcmVzcG9uc2UgY29tZXMgdmlhIGEgc2VjdXJlIHByb3h5IiwgY29ubmVjdGlvbik7CisKKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IGNvbm5lY3QgPSBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDb25uZWN0IGxpbmUgZmFpbHVyZSBvbiBwcm94eSIsCisgICAgICAgICAgICAgICAgIkNPTk5FQ1QgYW5kcm9pZC5jb206NDQzIEhUVFAvMS4xIiwgY29ubmVjdC5nZXRSZXF1ZXN0TGluZSgpKTsKKyAgICAgICAgYXNzZXJ0Q29udGFpbnMoY29ubmVjdC5nZXRIZWFkZXJzKCksICJIb3N0OiBhbmRyb2lkLmNvbSIpOworCisgICAgICAgIFJlY29yZGVkUmVxdWVzdCBnZXQgPSBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHRVQgL2ZvbyBIVFRQLzEuMSIsIGdldC5nZXRSZXF1ZXN0TGluZSgpKTsKKyAgICAgICAgYXNzZXJ0Q29udGFpbnMoZ2V0LmdldEhlYWRlcnMoKSwgIkhvc3Q6IGFuZHJvaWQuY29tIik7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KCJ2ZXJpZnkgYW5kcm9pZC5jb20iKSwgaG9zdG5hbWVWZXJpZmllci5jYWxscyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB3aGljaCBoZWFkZXJzIGFyZSBzZW50IHVuZW5jcnlwdGVkIHRvIHRoZSBIVFRQIHByb3h5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RQcm94eUNvbm5lY3RJbmNsdWRlc1Byb3h5SGVhZGVyc09ubHkoKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIFJlY29yZGluZ0hvc3RuYW1lVmVyaWZpZXIgaG9zdG5hbWVWZXJpZmllciA9IG5ldyBSZWNvcmRpbmdIb3N0bmFtZVZlcmlmaWVyKCk7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IHRlc3RTU0xDb250ZXh0ID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisKKyAgICAgICAgc2VydmVyLnVzZUh0dHBzKHRlc3RTU0xDb250ZXh0LnNlcnZlckNvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLCB0cnVlKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLnNldFNvY2tldFBvbGljeShTb2NrZXRQb2xpY3kuVVBHUkFERV9UT19TU0xfQVRfRU5EKQorICAgICAgICAgICAgICAgIC5jbGVhckhlYWRlcnMoKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJlbmNyeXB0ZWQgcmVzcG9uc2UgZnJvbSB0aGUgb3JpZ2luIHNlcnZlciIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cHM6Ly9hbmRyb2lkLmNvbS9mb28iKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKSB1cmwub3BlbkNvbm5lY3Rpb24oCisgICAgICAgICAgICAgICAgc2VydmVyLnRvUHJveHlBZGRyZXNzKCkpOworICAgICAgICBjb25uZWN0aW9uLmFkZFJlcXVlc3RQcm9wZXJ0eSgiUHJpdmF0ZSIsICJTZWNyZXQiKTsKKyAgICAgICAgY29ubmVjdGlvbi5hZGRSZXF1ZXN0UHJvcGVydHkoIlByb3h5LUF1dGhvcml6YXRpb24iLCAiYmFyIik7CisgICAgICAgIGNvbm5lY3Rpb24uYWRkUmVxdWVzdFByb3BlcnR5KCJVc2VyLUFnZW50IiwgImJheiIpOworICAgICAgICBjb25uZWN0aW9uLnNldFNTTFNvY2tldEZhY3RvcnkodGVzdFNTTENvbnRleHQuY2xpZW50Q29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkpOworICAgICAgICBjb25uZWN0aW9uLnNldEhvc3RuYW1lVmVyaWZpZXIoaG9zdG5hbWVWZXJpZmllcik7CisgICAgICAgIGFzc2VydENvbnRlbnQoImVuY3J5cHRlZCByZXNwb25zZSBmcm9tIHRoZSBvcmlnaW4gc2VydmVyIiwgY29ubmVjdGlvbik7CisKKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IGNvbm5lY3QgPSBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsKKyAgICAgICAgYXNzZXJ0Q29udGFpbnNOb25lTWF0Y2hpbmcoY29ubmVjdC5nZXRIZWFkZXJzKCksICJQcml2YXRlLioiKTsKKyAgICAgICAgYXNzZXJ0Q29udGFpbnMoY29ubmVjdC5nZXRIZWFkZXJzKCksICJQcm94eS1BdXRob3JpemF0aW9uOiBiYXIiKTsKKyAgICAgICAgYXNzZXJ0Q29udGFpbnMoY29ubmVjdC5nZXRIZWFkZXJzKCksICJVc2VyLUFnZW50OiBiYXoiKTsKKyAgICAgICAgYXNzZXJ0Q29udGFpbnMoY29ubmVjdC5nZXRIZWFkZXJzKCksICJIb3N0OiBhbmRyb2lkLmNvbSIpOworICAgICAgICBhc3NlcnRDb250YWlucyhjb25uZWN0LmdldEhlYWRlcnMoKSwgIlByb3h5LUNvbm5lY3Rpb246IEtlZXAtQWxpdmUiKTsKKworICAgICAgICBSZWNvcmRlZFJlcXVlc3QgZ2V0ID0gc2VydmVyLnRha2VSZXF1ZXN0KCk7CisgICAgICAgIGFzc2VydENvbnRhaW5zKGdldC5nZXRIZWFkZXJzKCksICJQcml2YXRlOiBTZWNyZXQiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoInZlcmlmeSBhbmRyb2lkLmNvbSIpLCBob3N0bmFtZVZlcmlmaWVyLmNhbGxzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJveHlBdXRoZW50aWNhdGVPbkNvbm5lY3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQXV0aGVudGljYXRvci5zZXREZWZhdWx0KFNJTVBMRV9BVVRIRU5USUNBVE9SKTsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgdGVzdFNTTENvbnRleHQgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgc2VydmVyLnVzZUh0dHBzKHRlc3RTU0xDb250ZXh0LnNlcnZlckNvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLCB0cnVlKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLnNldFJlc3BvbnNlQ29kZSg0MDcpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiUHJveHktQXV0aGVudGljYXRlOiBCYXNpYyByZWFsbT1cImxvY2FsaG9zdFwiIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuc2V0U29ja2V0UG9saWN5KFNvY2tldFBvbGljeS5VUEdSQURFX1RPX1NTTF9BVF9FTkQpCisgICAgICAgICAgICAgICAgLmNsZWFySGVhZGVycygpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkEiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHBzOi8vYW5kcm9pZC5jb20vZm9vIik7CisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKAorICAgICAgICAgICAgICAgIHNlcnZlci50b1Byb3h5QWRkcmVzcygpKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXRTU0xTb2NrZXRGYWN0b3J5KHRlc3RTU0xDb250ZXh0LmNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXRIb3N0bmFtZVZlcmlmaWVyKG5ldyBSZWNvcmRpbmdIb3N0bmFtZVZlcmlmaWVyKCkpOworICAgICAgICBhc3NlcnRDb250ZW50KCJBIiwgY29ubmVjdGlvbik7CisKKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IGNvbm5lY3QxID0gc2VydmVyLnRha2VSZXF1ZXN0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQ09OTkVDVCBhbmRyb2lkLmNvbTo0NDMgSFRUUC8xLjEiLCBjb25uZWN0MS5nZXRSZXF1ZXN0TGluZSgpKTsKKyAgICAgICAgYXNzZXJ0Q29udGFpbnNOb25lTWF0Y2hpbmcoY29ubmVjdDEuZ2V0SGVhZGVycygpLCAiUHJveHlcXC1BdXRob3JpemF0aW9uLioiKTsKKworICAgICAgICBSZWNvcmRlZFJlcXVlc3QgY29ubmVjdDIgPSBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDT05ORUNUIGFuZHJvaWQuY29tOjQ0MyBIVFRQLzEuMSIsIGNvbm5lY3QyLmdldFJlcXVlc3RMaW5lKCkpOworICAgICAgICBhc3NlcnRDb250YWlucyhjb25uZWN0Mi5nZXRIZWFkZXJzKCksICJQcm94eS1BdXRob3JpemF0aW9uOiBCYXNpYyAiICsgQkFTRV82NF9DUkVERU5USUFMUyk7CisKKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IGdldCA9IHNlcnZlci50YWtlUmVxdWVzdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkdFVCAvZm9vIEhUVFAvMS4xIiwgZ2V0LmdldFJlcXVlc3RMaW5lKCkpOworICAgICAgICBhc3NlcnRDb250YWluc05vbmVNYXRjaGluZyhnZXQuZ2V0SGVhZGVycygpLCAiUHJveHlcXC1BdXRob3JpemF0aW9uLioiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGlzY29ubmVjdGVkQ29ubmVjdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJBQkNERUZHSElKS0xNTk9QUVIiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gY29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ0EnLCAoY2hhcikgaW4ucmVhZCgpKTsKKyAgICAgICAgY29ubmVjdGlvbi5kaXNjb25uZWN0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbi5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBhIGNvbm5lY3Rpb24gY2xvc2VkIGV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERpc2Nvbm5lY3RCZWZvcmVDb25uZWN0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkEiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24uZGlzY29ubmVjdCgpOworCisgICAgICAgIGFzc2VydENvbnRlbnQoIkEiLCBjb25uZWN0aW9uKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIwMCwgY29ubmVjdGlvbi5nZXRSZXNwb25zZUNvZGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERlZmF1bHRSZXF1ZXN0UHJvcGVydHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMQ29ubmVjdGlvbi5zZXREZWZhdWx0UmVxdWVzdFByb3BlcnR5KCJYLXRlc3RTZXREZWZhdWx0UmVxdWVzdFByb3BlcnR5IiwgIkEiKTsKKyAgICAgICAgYXNzZXJ0TnVsbChVUkxDb25uZWN0aW9uLmdldERlZmF1bHRSZXF1ZXN0UHJvcGVydHkoIlgtc2V0RGVmYXVsdFJlcXVlc3RQcm9wZXJ0eSIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB7QGNvZGUgY291bnR9IGNoYXJhY3RlcnMgZnJvbSB0aGUgc3RyZWFtLiBJZiB0aGUgc3RyZWFtIGlzCisgICAgICogZXhoYXVzdGVkIGJlZm9yZSB7QGNvZGUgY291bnR9IGNoYXJhY3RlcnMgY2FuIGJlIHJlYWQsIHRoZSByZW1haW5pbmcKKyAgICAgKiBjaGFyYWN0ZXJzIGFyZSByZXR1cm5lZCBhbmQgdGhlIHN0cmVhbSBpcyBjbG9zZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgcmVhZEFzY2lpKElucHV0U3RyZWFtIGluLCBpbnQgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CisgICAgICAgICAgICBpbnQgdmFsdWUgPSBpbi5yZWFkKCk7CisgICAgICAgICAgICBpZiAodmFsdWUgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgoY2hhcikgdmFsdWUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFya0FuZFJlc2V0V2l0aENvbnRlbnRMZW5ndGhIZWFkZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0ZXN0TWFya0FuZFJlc2V0KFRyYW5zZmVyS2luZC5GSVhFRF9MRU5HVEgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYXJrQW5kUmVzZXRXaXRoQ2h1bmtlZEVuY29kaW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdE1hcmtBbmRSZXNldChUcmFuc2ZlcktpbmQuQ0hVTktFRCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1hcmtBbmRSZXNldFdpdGhOb0xlbmd0aEhlYWRlcnMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0ZXN0TWFya0FuZFJlc2V0KFRyYW5zZmVyS2luZC5FTkRfT0ZfU1RSRUFNKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdE1hcmtBbmRSZXNldChUcmFuc2ZlcktpbmQgdHJhbnNmZXJLaW5kKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBNb2NrUmVzcG9uc2UgcmVzcG9uc2UgPSBuZXcgTW9ja1Jlc3BvbnNlKCk7CisgICAgICAgIHRyYW5zZmVyS2luZC5zZXRCb2R5KHJlc3BvbnNlLCAiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoiLCAxMDI0KTsKKyAgICAgICAgc2VydmVyLmVucXVldWUocmVzcG9uc2UpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShyZXNwb25zZSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKS5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICBhc3NlcnRGYWxzZSgiVGhpcyBpbXBsZW1lbnRhdGlvbiBjbGFpbXMgdG8gc3VwcG9ydCBtYXJrKCkuIiwgaW4ubWFya1N1cHBvcnRlZCgpKTsKKyAgICAgICAgaW4ubWFyayg1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkNERSIsIHJlYWRBc2NpaShpbiwgNSkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4ucmVzZXQoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIkZHSElKS0xNTk9QUVJTVFVWV1hZWiIsIHJlYWRBc2NpaShpbiwgSW50ZWdlci5NQVhfVkFMVUUpKTsKKyAgICAgICAgYXNzZXJ0Q29udGVudCgiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoiLCBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2UndmUgaGFkIGEgYnVnIHdoZXJlIHdlIGZvcmdldCB0aGUgSFRUUCByZXNwb25zZSB3aGVuIHdlIHNlZSByZXNwb25zZQorICAgICAqIGNvZGUgNDAxLiBUaGlzIGNhdXNlcyBhIG5ldyBIVFRQIHJlcXVlc3QgdG8gYmUgaXNzdWVkIGZvciBldmVyeSBjYWxsIGludG8KKyAgICAgKiB0aGUgVVJMQ29ubmVjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VW5hdXRob3JpemVkUmVzcG9uc2VIYW5kbGluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIE1vY2tSZXNwb25zZSByZXNwb25zZSA9IG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIldXVy1BdXRoZW50aWNhdGU6IGNoYWxsZW5nZSIpCisgICAgICAgICAgICAgICAgLnNldFJlc3BvbnNlQ29kZSg0MDEpIC8vIFVOQVVUSE9SSVpFRAorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJVbmF1dGhvcml6ZWQiKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUocmVzcG9uc2UpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShyZXNwb25zZSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKHJlc3BvbnNlKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkwgdXJsID0gc2VydmVyLmdldFVybCgiLyIpOworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uID0gKEh0dHBVUkxDb25uZWN0aW9uKSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoNDAxLCBjb25uLmdldFJlc3BvbnNlQ29kZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQwMSwgY29ubi5nZXRSZXNwb25zZUNvZGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg0MDEsIGNvbm4uZ2V0UmVzcG9uc2VDb2RlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgc2VydmVyLmdldFJlcXVlc3RDb3VudCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9uSGV4Q2h1bmtTaXplKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIjVcclxuQUJDREVcclxuR1xyXG5GR0hJSktMTU5PUFFSU1RVXHJcbjBcclxuXHJcbiIpCisgICAgICAgICAgICAgICAgLmNsZWFySGVhZGVycygpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiVHJhbnNmZXItZW5jb2Rpbmc6IGNodW5rZWQiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkQXNjaWkoY29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNaXNzaW5nQ2h1bmtCb2R5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIjUiKQorICAgICAgICAgICAgICAgIC5jbGVhckhlYWRlcnMoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIlRyYW5zZmVyLWVuY29kaW5nOiBjaHVua2VkIikKKyAgICAgICAgICAgICAgICAuc2V0U29ja2V0UG9saWN5KERJU0NPTk5FQ1RfQVRfRU5EKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkQXNjaWkoY29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgdGVzdCBjaGVja3Mgd2hldGhlciBjb25uZWN0aW9ucyBhcmUgZ3ppcHBlZCBieSBkZWZhdWx0LiBUaGlzCisgICAgICogYmVoYXZpb3IgaW4gbm90IHJlcXVpcmVkIGJ5IHRoZSBBUEksIHNvIGEgZmFpbHVyZSBvZiB0aGlzIHRlc3QgZG9lcyBub3QKKyAgICAgKiBpbXBseSBhIGJ1ZyBpbiB0aGUgaW1wbGVtZW50YXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEd6aXBFbmNvZGluZ0VuYWJsZWRCeURlZmF1bHQoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoZ3ppcCgiQUJDQUJDQUJDIi5nZXRCeXRlcygiVVRGLTgiKSkpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ29udGVudC1FbmNvZGluZzogZ3ppcCIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkNBQkNBQkMiLCByZWFkQXNjaWkoY29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpLCBJbnRlZ2VyLk1BWF9WQUxVRSkpOworICAgICAgICBhc3NlcnROdWxsKGNvbm5lY3Rpb24uZ2V0Q29udGVudEVuY29kaW5nKCkpOworCisgICAgICAgIFJlY29yZGVkUmVxdWVzdCByZXF1ZXN0ID0gc2VydmVyLnRha2VSZXF1ZXN0KCk7CisgICAgICAgIGFzc2VydENvbnRhaW5zKHJlcXVlc3QuZ2V0SGVhZGVycygpLCAiQWNjZXB0LUVuY29kaW5nOiBnemlwIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENsaWVudENvbmZpZ3VyZWRHemlwQ29udGVudEVuY29kaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KGd6aXAoIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaIi5nZXRCeXRlcygiVVRGLTgiKSkpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ29udGVudC1FbmNvZGluZzogZ3ppcCIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5hZGRSZXF1ZXN0UHJvcGVydHkoIkFjY2VwdC1FbmNvZGluZyIsICJnemlwIik7CisgICAgICAgIElucHV0U3RyZWFtIGd1bnppcHBlZEluID0gbmV3IEdaSVBJbnB1dFN0cmVhbShjb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaIiwgcmVhZEFzY2lpKGd1bnppcHBlZEluLCBJbnRlZ2VyLk1BWF9WQUxVRSkpOworCisgICAgICAgIFJlY29yZGVkUmVxdWVzdCByZXF1ZXN0ID0gc2VydmVyLnRha2VSZXF1ZXN0KCk7CisgICAgICAgIGFzc2VydENvbnRhaW5zKHJlcXVlc3QuZ2V0SGVhZGVycygpLCAiQWNjZXB0LUVuY29kaW5nOiBnemlwIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEd6aXBBbmRDb25uZWN0aW9uUmV1c2VXaXRoRml4ZWRMZW5ndGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdENsaWVudENvbmZpZ3VyZWRHemlwQ29udGVudEVuY29kaW5nQW5kQ29ubmVjdGlvblJldXNlKFRyYW5zZmVyS2luZC5GSVhFRF9MRU5HVEgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHemlwQW5kQ29ubmVjdGlvblJldXNlV2l0aENodW5rZWRFbmNvZGluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Q2xpZW50Q29uZmlndXJlZEd6aXBDb250ZW50RW5jb2RpbmdBbmRDb25uZWN0aW9uUmV1c2UoVHJhbnNmZXJLaW5kLkNIVU5LRUQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDbGllbnRDb25maWd1cmVkQ3VzdG9tQ29udGVudEVuY29kaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBQkNERSIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ29udGVudC1FbmNvZGluZzogY3VzdG9tIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQWNjZXB0LUVuY29kaW5nIiwgImN1c3RvbSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFCQ0RFIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKSwgSW50ZWdlci5NQVhfVkFMVUUpKTsKKworICAgICAgICBSZWNvcmRlZFJlcXVlc3QgcmVxdWVzdCA9IHNlcnZlci50YWtlUmVxdWVzdCgpOworICAgICAgICBhc3NlcnRDb250YWlucyhyZXF1ZXN0LmdldEhlYWRlcnMoKSwgIkFjY2VwdC1FbmNvZGluZzogY3VzdG9tIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBhIGJ1ZyB3aGVyZSBnemlwIGlucHV0IHN0cmVhbXMgd2VyZW4ndCBleGhhdXN0aW5nIHRoZSBpbnB1dCBzdHJlYW0sCisgICAgICogd2hpY2ggY29ycnVwdGVkIHRoZSByZXF1ZXN0IHRoYXQgZm9sbG93ZWQuCisgICAgICogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD03MDU5CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RDbGllbnRDb25maWd1cmVkR3ppcENvbnRlbnRFbmNvZGluZ0FuZENvbm5lY3Rpb25SZXVzZSgKKyAgICAgICAgICAgIFRyYW5zZmVyS2luZCB0cmFuc2ZlcktpbmQpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNb2NrUmVzcG9uc2UgcmVzcG9uc2VPbmUgPSBuZXcgTW9ja1Jlc3BvbnNlKCk7CisgICAgICAgIHJlc3BvbnNlT25lLmFkZEhlYWRlcigiQ29udGVudC1FbmNvZGluZzogZ3ppcCIpOworICAgICAgICB0cmFuc2ZlcktpbmQuc2V0Qm9keShyZXNwb25zZU9uZSwgZ3ppcCgib25lIChnemlwcGVkKSIuZ2V0Qnl0ZXMoIlVURi04IikpLCA1KTsKKyAgICAgICAgc2VydmVyLmVucXVldWUocmVzcG9uc2VPbmUpOworICAgICAgICBNb2NrUmVzcG9uc2UgcmVzcG9uc2VUd28gPSBuZXcgTW9ja1Jlc3BvbnNlKCk7CisgICAgICAgIHRyYW5zZmVyS2luZC5zZXRCb2R5KHJlc3BvbnNlVHdvLCAidHdvIChpZGVudGl0eSkiLCA1KTsKKyAgICAgICAgc2VydmVyLmVucXVldWUocmVzcG9uc2VUd28pOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQWNjZXB0LUVuY29kaW5nIiwgImd6aXAiKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gZ3VuemlwcGVkSW4gPSBuZXcgR1pJUElucHV0U3RyZWFtKGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygib25lIChnemlwcGVkKSIsIHJlYWRBc2NpaShndW56aXBwZWRJbiwgSW50ZWdlci5NQVhfVkFMVUUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHNlcnZlci50YWtlUmVxdWVzdCgpLmdldFNlcXVlbmNlTnVtYmVyKCkpOworCisgICAgICAgIGNvbm5lY3Rpb24gPSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0d28gKGlkZW50aXR5KSIsIHJlYWRBc2NpaShjb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCksIEludGVnZXIuTUFYX1ZBTFVFKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBzZXJ2ZXIudGFrZVJlcXVlc3QoKS5nZXRTZXF1ZW5jZU51bWJlcigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPYm5veGlvdXNseSB0ZXN0IHRoYXQgdGhlIGNodW5rIHNpemVzIHRyYW5zbWl0dGVkIGV4YWN0bHkgZXF1YWwgdGhlCisgICAgICogcmVxdWVzdGVkIGRhdGErY2h1bmsgaGVhZGVyIHNpemUuIEFsdGhvdWdoIHNldENodW5rZWRTdHJlYW1pbmdNb2RlKCkKKyAgICAgKiBpc24ndCBzcGVjaWZpYyBhYm91dCB3aGV0aGVyIHRoZSBzaXplIGFwcGxpZXMgdG8gdGhlIGRhdGEgb3IgdGhlCisgICAgICogY29tcGxldGUgY2h1bmssIHRoZSBSSSBpbnRlcnByZXRzIGl0IGFzIGEgY29tcGxldGUgY2h1bmsuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNldENodW5rZWRTdHJlYW1pbmdNb2RlKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gdXJsQ29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIHVybENvbm5lY3Rpb24uc2V0Q2h1bmtlZFN0cmVhbWluZ01vZGUoOCk7CisgICAgICAgIHVybENvbm5lY3Rpb24uc2V0RG9PdXRwdXQodHJ1ZSk7CisgICAgICAgIE91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0gPSB1cmxDb25uZWN0aW9uLmdldE91dHB1dFN0cmVhbSgpOworICAgICAgICBvdXRwdXRTdHJlYW0ud3JpdGUoIkFCQ0RFRkdISUpLTE1OT1BRIi5nZXRCeXRlcygiVVMtQVNDSUkiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyMDAsIHVybENvbm5lY3Rpb24uZ2V0UmVzcG9uc2VDb2RlKCkpOworCisgICAgICAgIFJlY29yZGVkUmVxdWVzdCByZXF1ZXN0ID0gc2VydmVyLnRha2VSZXF1ZXN0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJDREVGR0hJSktMTU5PUFEiLCBuZXcgU3RyaW5nKHJlcXVlc3QuZ2V0Qm9keSgpLCAiVVMtQVNDSUkiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KDMsIDMsIDMsIDMsIDMsIDIpLCByZXF1ZXN0LmdldENodW5rU2l6ZXMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEF1dGhlbnRpY2F0ZVdpdGhGaXhlZExlbmd0aFN0cmVhbWluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0QXV0aGVudGljYXRlV2l0aFN0cmVhbWluZ1Bvc3QoU3RyZWFtaW5nTW9kZS5GSVhFRF9MRU5HVEgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdXRoZW50aWNhdGVXaXRoQ2h1bmtlZFN0cmVhbWluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0QXV0aGVudGljYXRlV2l0aFN0cmVhbWluZ1Bvc3QoU3RyZWFtaW5nTW9kZS5DSFVOS0VEKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdEF1dGhlbnRpY2F0ZVdpdGhTdHJlYW1pbmdQb3N0KFN0cmVhbWluZ01vZGUgc3RyZWFtaW5nTW9kZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1vY2tSZXNwb25zZSBwbGVhc2VBdXRoZW50aWNhdGUgPSBuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuc2V0UmVzcG9uc2VDb2RlKDQwMSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJXV1ctQXV0aGVudGljYXRlOiBCYXNpYyByZWFsbT1cInByb3RlY3RlZCBhcmVhXCIiKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJQbGVhc2UgYXV0aGVudGljYXRlLiIpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShwbGVhc2VBdXRoZW50aWNhdGUpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIEF1dGhlbnRpY2F0b3Iuc2V0RGVmYXVsdChTSU1QTEVfQVVUSEVOVElDQVRPUik7CisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLnNldERvT3V0cHV0KHRydWUpOworICAgICAgICBieXRlW10gcmVxdWVzdEJvZHkgPSB7ICdBJywgJ0InLCAnQycsICdEJyB9OworICAgICAgICBpZiAoc3RyZWFtaW5nTW9kZSA9PSBTdHJlYW1pbmdNb2RlLkZJWEVEX0xFTkdUSCkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5zZXRGaXhlZExlbmd0aFN0cmVhbWluZ01vZGUocmVxdWVzdEJvZHkubGVuZ3RoKTsKKyAgICAgICAgfSBlbHNlIGlmIChzdHJlYW1pbmdNb2RlID09IFN0cmVhbWluZ01vZGUuQ0hVTktFRCkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5zZXRDaHVua2VkU3RyZWFtaW5nTW9kZSgwKTsKKyAgICAgICAgfQorICAgICAgICBPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtID0gY29ubmVjdGlvbi5nZXRPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgb3V0cHV0U3RyZWFtLndyaXRlKHJlcXVlc3RCb2R5KTsKKyAgICAgICAgb3V0cHV0U3RyZWFtLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEh0dHBSZXRyeUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gbm8gYXV0aG9yaXphdGlvbiBoZWFkZXIgZm9yIHRoZSByZXF1ZXN0Li4uCisgICAgICAgIFJlY29yZGVkUmVxdWVzdCByZXF1ZXN0ID0gc2VydmVyLnRha2VSZXF1ZXN0KCk7CisgICAgICAgIGFzc2VydENvbnRhaW5zTm9uZU1hdGNoaW5nKHJlcXVlc3QuZ2V0SGVhZGVycygpLCAiQXV0aG9yaXphdGlvbjogQmFzaWMgLioiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy50b1N0cmluZyhyZXF1ZXN0Qm9keSksIEFycmF5cy50b1N0cmluZyhyZXF1ZXN0LmdldEJvZHkoKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRWYWxpZFJlcXVlc3RNZXRob2QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKyAgICAgICAgYXNzZXJ0VmFsaWRSZXF1ZXN0TWV0aG9kKCJHRVQiKTsKKyAgICAgICAgYXNzZXJ0VmFsaWRSZXF1ZXN0TWV0aG9kKCJERUxFVEUiKTsKKyAgICAgICAgYXNzZXJ0VmFsaWRSZXF1ZXN0TWV0aG9kKCJIRUFEIik7CisgICAgICAgIGFzc2VydFZhbGlkUmVxdWVzdE1ldGhvZCgiT1BUSU9OUyIpOworICAgICAgICBhc3NlcnRWYWxpZFJlcXVlc3RNZXRob2QoIlBPU1QiKTsKKyAgICAgICAgYXNzZXJ0VmFsaWRSZXF1ZXN0TWV0aG9kKCJQVVQiKTsKKyAgICAgICAgYXNzZXJ0VmFsaWRSZXF1ZXN0TWV0aG9kKCJUUkFDRSIpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRWYWxpZFJlcXVlc3RNZXRob2QoU3RyaW5nIHJlcXVlc3RNZXRob2QpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXRSZXF1ZXN0TWV0aG9kKHJlcXVlc3RNZXRob2QpOworICAgICAgICBhc3NlcnRFcXVhbHMocmVxdWVzdE1ldGhvZCwgY29ubmVjdGlvbi5nZXRSZXF1ZXN0TWV0aG9kKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRJbnZhbGlkUmVxdWVzdE1ldGhvZExvd2VyY2FzZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIucGxheSgpOworICAgICAgICBhc3NlcnRJbnZhbGlkUmVxdWVzdE1ldGhvZCgiZ2V0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldEludmFsaWRSZXF1ZXN0TWV0aG9kQ29ubmVjdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIucGxheSgpOworICAgICAgICBhc3NlcnRJbnZhbGlkUmVxdWVzdE1ldGhvZCgiQ09OTkVDVCIpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRJbnZhbGlkUmVxdWVzdE1ldGhvZChTdHJpbmcgcmVxdWVzdE1ldGhvZCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5zZXRSZXF1ZXN0TWV0aG9kKHJlcXVlc3RNZXRob2QpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENhbm5vdFNldE5lZ2F0aXZlRml4ZWRMZW5ndGhTdHJlYW1pbmdNb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5zZXRGaXhlZExlbmd0aFN0cmVhbWluZ01vZGUoLTIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDYW5TZXROZWdhdGl2ZUNodW5rZWRTdHJlYW1pbmdNb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLnNldENodW5rZWRTdHJlYW1pbmdNb2RlKC0yKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2Fubm90U2V0Rml4ZWRMZW5ndGhTdHJlYW1pbmdNb2RlQWZ0ZXJDb25uZWN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKSwgSW50ZWdlci5NQVhfVkFMVUUpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uc2V0Rml4ZWRMZW5ndGhTdHJlYW1pbmdNb2RlKDEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDYW5ub3RTZXRDaHVua2VkU3RyZWFtaW5nTW9kZUFmdGVyQ29ubmVjdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQSIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShjb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCksIEludGVnZXIuTUFYX1ZBTFVFKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uZWN0aW9uLnNldENodW5rZWRTdHJlYW1pbmdNb2RlKDEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDYW5ub3RTZXRGaXhlZExlbmd0aFN0cmVhbWluZ01vZGVBZnRlckNodW5rZWRTdHJlYW1pbmdNb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLnNldENodW5rZWRTdHJlYW1pbmdNb2RlKDEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5zZXRGaXhlZExlbmd0aFN0cmVhbWluZ01vZGUoMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENhbm5vdFNldENodW5rZWRTdHJlYW1pbmdNb2RlQWZ0ZXJGaXhlZExlbmd0aFN0cmVhbWluZ01vZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0Rml4ZWRMZW5ndGhTdHJlYW1pbmdNb2RlKDEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5zZXRDaHVua2VkU3RyZWFtaW5nTW9kZSgxKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VjdXJlRml4ZWRMZW5ndGhTdHJlYW1pbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFNlY3VyZVN0cmVhbWluZ1Bvc3QoU3RyZWFtaW5nTW9kZS5GSVhFRF9MRU5HVEgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZWN1cmVDaHVua2VkU3RyZWFtaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RTZWN1cmVTdHJlYW1pbmdQb3N0KFN0cmVhbWluZ01vZGUuQ0hVTktFRCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlcnMgaGF2ZSByZXBvcnRlZCBwcm9ibGVtcyB1c2luZyBIVFRQUyB3aXRoIHN0cmVhbWluZyByZXF1ZXN0IGJvZGllcy4KKyAgICAgKiBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTEyODYwCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RTZWN1cmVTdHJlYW1pbmdQb3N0KFN0cmVhbWluZ01vZGUgc3RyZWFtaW5nTW9kZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IHRlc3RTU0xDb250ZXh0ID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIHNlcnZlci51c2VIdHRwcyh0ZXN0U1NMQ29udGV4dC5zZXJ2ZXJDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKSwgZmFsc2UpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiU3VjY2VzcyEiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXRTU0xTb2NrZXRGYWN0b3J5KHRlc3RTU0xDb250ZXh0LmNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXREb091dHB1dCh0cnVlKTsKKyAgICAgICAgYnl0ZVtdIHJlcXVlc3RCb2R5ID0geyAnQScsICdCJywgJ0MnLCAnRCcgfTsKKyAgICAgICAgaWYgKHN0cmVhbWluZ01vZGUgPT0gU3RyZWFtaW5nTW9kZS5GSVhFRF9MRU5HVEgpIHsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uc2V0Rml4ZWRMZW5ndGhTdHJlYW1pbmdNb2RlKHJlcXVlc3RCb2R5Lmxlbmd0aCk7CisgICAgICAgIH0gZWxzZSBpZiAoc3RyZWFtaW5nTW9kZSA9PSBTdHJlYW1pbmdNb2RlLkNIVU5LRUQpIHsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uc2V0Q2h1bmtlZFN0cmVhbWluZ01vZGUoMCk7CisgICAgICAgIH0KKyAgICAgICAgT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSA9IGNvbm5lY3Rpb24uZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIG91dHB1dFN0cmVhbS53cml0ZShyZXF1ZXN0Qm9keSk7CisgICAgICAgIG91dHB1dFN0cmVhbS5jbG9zZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlN1Y2Nlc3MhIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKSwgSW50ZWdlci5NQVhfVkFMVUUpKTsKKworICAgICAgICBSZWNvcmRlZFJlcXVlc3QgcmVxdWVzdCA9IHNlcnZlci50YWtlUmVxdWVzdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlBPU1QgLyBIVFRQLzEuMSIsIHJlcXVlc3QuZ2V0UmVxdWVzdExpbmUoKSk7CisgICAgICAgIGlmIChzdHJlYW1pbmdNb2RlID09IFN0cmVhbWluZ01vZGUuRklYRURfTEVOR1RIKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoQ29sbGVjdGlvbnMuPEludGVnZXI+ZW1wdHlMaXN0KCksIHJlcXVlc3QuZ2V0Q2h1bmtTaXplcygpKTsKKyAgICAgICAgfSBlbHNlIGlmIChzdHJlYW1pbmdNb2RlID09IFN0cmVhbWluZ01vZGUuQ0hVTktFRCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoNCksIHJlcXVlc3QuZ2V0Q2h1bmtTaXplcygpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLnRvU3RyaW5nKHJlcXVlc3RCb2R5KSwgQXJyYXlzLnRvU3RyaW5nKHJlcXVlc3QuZ2V0Qm9keSgpKSk7CisgICAgfQorCisgICAgZW51bSBTdHJlYW1pbmdNb2RlIHsKKyAgICAgICAgRklYRURfTEVOR1RILCBDSFVOS0VECisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEF1dGhlbnRpY2F0ZVdpdGhQb3N0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1vY2tSZXNwb25zZSBwbGVhc2VBdXRoZW50aWNhdGUgPSBuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuc2V0UmVzcG9uc2VDb2RlKDQwMSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJXV1ctQXV0aGVudGljYXRlOiBCYXNpYyByZWFsbT1cInByb3RlY3RlZCBhcmVhXCIiKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJQbGVhc2UgYXV0aGVudGljYXRlLiIpOworICAgICAgICAvLyBmYWlsIGF1dGggdGhyZWUgdGltZXMuLi4KKyAgICAgICAgc2VydmVyLmVucXVldWUocGxlYXNlQXV0aGVudGljYXRlKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUocGxlYXNlQXV0aGVudGljYXRlKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUocGxlYXNlQXV0aGVudGljYXRlKTsKKyAgICAgICAgLy8gLi4udGhlbiBzdWNjZWVkIHRoZSBmb3VydGggdGltZQorICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiU3VjY2Vzc2Z1bCBhdXRoISIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBBdXRoZW50aWNhdG9yLnNldERlZmF1bHQoU0lNUExFX0FVVEhFTlRJQ0FUT1IpOworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXREb091dHB1dCh0cnVlKTsKKyAgICAgICAgYnl0ZVtdIHJlcXVlc3RCb2R5ID0geyAnQScsICdCJywgJ0MnLCAnRCcgfTsKKyAgICAgICAgT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSA9IGNvbm5lY3Rpb24uZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIG91dHB1dFN0cmVhbS53cml0ZShyZXF1ZXN0Qm9keSk7CisgICAgICAgIG91dHB1dFN0cmVhbS5jbG9zZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlN1Y2Nlc3NmdWwgYXV0aCEiLCByZWFkQXNjaWkoY29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpLCBJbnRlZ2VyLk1BWF9WQUxVRSkpOworCisgICAgICAgIC8vIG5vIGF1dGhvcml6YXRpb24gaGVhZGVyIGZvciB0aGUgZmlyc3QgcmVxdWVzdC4uLgorICAgICAgICBSZWNvcmRlZFJlcXVlc3QgcmVxdWVzdCA9IHNlcnZlci50YWtlUmVxdWVzdCgpOworICAgICAgICBhc3NlcnRDb250YWluc05vbmVNYXRjaGluZyhyZXF1ZXN0LmdldEhlYWRlcnMoKSwgIkF1dGhvcml6YXRpb246IEJhc2ljIC4qIik7CisKKyAgICAgICAgLy8gLi4uYnV0IHRoZSB0aHJlZSByZXF1ZXN0cyB0aGF0IGZvbGxvdyBpbmNsdWRlIGFuIGF1dGhvcml6YXRpb24gaGVhZGVyCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgaSsrKSB7CisgICAgICAgICAgICByZXF1ZXN0ID0gc2VydmVyLnRha2VSZXF1ZXN0KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlBPU1QgLyBIVFRQLzEuMSIsIHJlcXVlc3QuZ2V0UmVxdWVzdExpbmUoKSk7CisgICAgICAgICAgICBhc3NlcnRDb250YWlucyhyZXF1ZXN0LmdldEhlYWRlcnMoKSwgIkF1dGhvcml6YXRpb246IEJhc2ljICIgKyBCQVNFXzY0X0NSRURFTlRJQUxTKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMudG9TdHJpbmcocmVxdWVzdEJvZHkpLCBBcnJheXMudG9TdHJpbmcocmVxdWVzdC5nZXRCb2R5KCkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdXRoZW50aWNhdGVXaXRoR2V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1vY2tSZXNwb25zZSBwbGVhc2VBdXRoZW50aWNhdGUgPSBuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuc2V0UmVzcG9uc2VDb2RlKDQwMSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJXV1ctQXV0aGVudGljYXRlOiBCYXNpYyByZWFsbT1cInByb3RlY3RlZCBhcmVhXCIiKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJQbGVhc2UgYXV0aGVudGljYXRlLiIpOworICAgICAgICAvLyBmYWlsIGF1dGggdGhyZWUgdGltZXMuLi4KKyAgICAgICAgc2VydmVyLmVucXVldWUocGxlYXNlQXV0aGVudGljYXRlKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUocGxlYXNlQXV0aGVudGljYXRlKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUocGxlYXNlQXV0aGVudGljYXRlKTsKKyAgICAgICAgLy8gLi4udGhlbiBzdWNjZWVkIHRoZSBmb3VydGggdGltZQorICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiU3VjY2Vzc2Z1bCBhdXRoISIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBBdXRoZW50aWNhdG9yLnNldERlZmF1bHQoU0lNUExFX0FVVEhFTlRJQ0FUT1IpOworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTdWNjZXNzZnVsIGF1dGghIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKSwgSW50ZWdlci5NQVhfVkFMVUUpKTsKKworICAgICAgICAvLyBubyBhdXRob3JpemF0aW9uIGhlYWRlciBmb3IgdGhlIGZpcnN0IHJlcXVlc3QuLi4KKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IHJlcXVlc3QgPSBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsKKyAgICAgICAgYXNzZXJ0Q29udGFpbnNOb25lTWF0Y2hpbmcocmVxdWVzdC5nZXRIZWFkZXJzKCksICJBdXRob3JpemF0aW9uOiBCYXNpYyAuKiIpOworCisgICAgICAgIC8vIC4uLmJ1dCB0aGUgdGhyZWUgcmVxdWVzdHMgdGhhdCBmb2xsb3cgcmVxdWVzdHMgaW5jbHVkZSBhbiBhdXRob3JpemF0aW9uIGhlYWRlcgorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykgeworICAgICAgICAgICAgcmVxdWVzdCA9IHNlcnZlci50YWtlUmVxdWVzdCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJHRVQgLyBIVFRQLzEuMSIsIHJlcXVlc3QuZ2V0UmVxdWVzdExpbmUoKSk7CisgICAgICAgICAgICBhc3NlcnRDb250YWlucyhyZXF1ZXN0LmdldEhlYWRlcnMoKSwgIkF1dGhvcml6YXRpb246IEJhc2ljICIgKyBCQVNFXzY0X0NSRURFTlRJQUxTKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWRpcmVjdGVkV2l0aENodW5rZWRFbmNvZGluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0UmVkaXJlY3RlZChUcmFuc2ZlcktpbmQuQ0hVTktFRCwgdHJ1ZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlZGlyZWN0ZWRXaXRoQ29udGVudExlbmd0aEhlYWRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0UmVkaXJlY3RlZChUcmFuc2ZlcktpbmQuRklYRURfTEVOR1RILCB0cnVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVkaXJlY3RlZFdpdGhOb0xlbmd0aEhlYWRlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFJlZGlyZWN0ZWQoVHJhbnNmZXJLaW5kLkVORF9PRl9TVFJFQU0sIGZhbHNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdFJlZGlyZWN0ZWQoVHJhbnNmZXJLaW5kIHRyYW5zZmVyS2luZCwgYm9vbGVhbiByZXVzZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1vY2tSZXNwb25zZSByZXNwb25zZSA9IG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5zZXRSZXNwb25zZUNvZGUoSHR0cFVSTENvbm5lY3Rpb24uSFRUUF9NT1ZFRF9URU1QKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkxvY2F0aW9uOiAvZm9vIik7CisgICAgICAgIHRyYW5zZmVyS2luZC5zZXRCb2R5KHJlc3BvbnNlLCAiVGhpcyBwYWdlIGhhcyBtb3ZlZCEiLCAxMCk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKHJlc3BvbnNlKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIlRoaXMgaXMgdGhlIG5ldyBsb2NhdGlvbiEiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhpcyBpcyB0aGUgbmV3IGxvY2F0aW9uISIsCisgICAgICAgICAgICAgICAgcmVhZEFzY2lpKGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKSwgSW50ZWdlci5NQVhfVkFMVUUpKTsKKworICAgICAgICBSZWNvcmRlZFJlcXVlc3QgZmlyc3QgPSBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHRVQgLyBIVFRQLzEuMSIsIGZpcnN0LmdldFJlcXVlc3RMaW5lKCkpOworICAgICAgICBSZWNvcmRlZFJlcXVlc3QgcmV0cnkgPSBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHRVQgL2ZvbyBIVFRQLzEuMSIsIHJldHJ5LmdldFJlcXVlc3RMaW5lKCkpOworICAgICAgICBpZiAocmV1c2UpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiRXhwZWN0ZWQgY29ubmVjdGlvbiByZXVzZSIsIDEsIHJldHJ5LmdldFNlcXVlbmNlTnVtYmVyKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlZGlyZWN0ZWRPbkh0dHBzKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IHRlc3RTU0xDb250ZXh0ID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIHNlcnZlci51c2VIdHRwcyh0ZXN0U1NMQ29udGV4dC5zZXJ2ZXJDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKSwgZmFsc2UpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuc2V0UmVzcG9uc2VDb2RlKEh0dHBVUkxDb25uZWN0aW9uLkhUVFBfTU9WRURfVEVNUCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMb2NhdGlvbjogL2ZvbyIpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIlRoaXMgcGFnZSBoYXMgbW92ZWQhIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiVGhpcyBpcyB0aGUgbmV3IGxvY2F0aW9uISIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwc1VSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLnNldFNTTFNvY2tldEZhY3RvcnkodGVzdFNTTENvbnRleHQuY2xpZW50Q29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRoaXMgaXMgdGhlIG5ldyBsb2NhdGlvbiEiLAorICAgICAgICAgICAgICAgIHJlYWRBc2NpaShjb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCksIEludGVnZXIuTUFYX1ZBTFVFKSk7CisKKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IGZpcnN0ID0gc2VydmVyLnRha2VSZXF1ZXN0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiR0VUIC8gSFRUUC8xLjEiLCBmaXJzdC5nZXRSZXF1ZXN0TGluZSgpKTsKKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IHJldHJ5ID0gc2VydmVyLnRha2VSZXF1ZXN0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiR0VUIC9mb28gSFRUUC8xLjEiLCByZXRyeS5nZXRSZXF1ZXN0TGluZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJFeHBlY3RlZCBjb25uZWN0aW9uIHJldXNlIiwgMSwgcmV0cnkuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vdFJlZGlyZWN0ZWRGcm9tSHR0cHNUb0h0dHAoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgdGVzdFNTTENvbnRleHQgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgc2VydmVyLnVzZUh0dHBzKHRlc3RTU0xDb250ZXh0LnNlcnZlckNvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLCBmYWxzZSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5zZXRSZXNwb25zZUNvZGUoSHR0cFVSTENvbm5lY3Rpb24uSFRUUF9NT1ZFRF9URU1QKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkxvY2F0aW9uOiBodHRwOi8vYW55aG9zdC9mb28iKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJUaGlzIHBhZ2UgaGFzIG1vdmVkISIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwc1VSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLnNldFNTTFNvY2tldEZhY3RvcnkodGVzdFNTTENvbnRleHQuY2xpZW50Q29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRoaXMgcGFnZSBoYXMgbW92ZWQhIiwKKyAgICAgICAgICAgICAgICByZWFkQXNjaWkoY29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpLCBJbnRlZ2VyLk1BWF9WQUxVRSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROb3RSZWRpcmVjdGVkRnJvbUh0dHBUb0h0dHBzKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5zZXRSZXNwb25zZUNvZGUoSHR0cFVSTENvbm5lY3Rpb24uSFRUUF9NT1ZFRF9URU1QKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkxvY2F0aW9uOiBodHRwczovL2FueWhvc3QvZm9vIikKKyAgICAgICAgICAgICAgICAuc2V0Qm9keSgiVGhpcyBwYWdlIGhhcyBtb3ZlZCEiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhpcyBwYWdlIGhhcyBtb3ZlZCEiLAorICAgICAgICAgICAgICAgIHJlYWRBc2NpaShjb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCksIEludGVnZXIuTUFYX1ZBTFVFKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlZGlyZWN0VG9Bbm90aGVyT3JpZ2luU2VydmVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1vY2tXZWJTZXJ2ZXIgc2VydmVyMiA9IG5ldyBNb2NrV2ViU2VydmVyKCk7CisgICAgICAgIHNlcnZlcjIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiVGhpcyBpcyB0aGUgMm5kIHNlcnZlciEiKSk7CisgICAgICAgIHNlcnZlcjIucGxheSgpOworCisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5zZXRSZXNwb25zZUNvZGUoSHR0cFVSTENvbm5lY3Rpb24uSFRUUF9NT1ZFRF9URU1QKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkxvY2F0aW9uOiAiICsgc2VydmVyMi5nZXRVcmwoIi8iKS50b1N0cmluZygpKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJUaGlzIHBhZ2UgaGFzIG1vdmVkISIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIlRoaXMgaXMgdGhlIGZpcnN0IHNlcnZlciBhZ2FpbiEiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhpcyBpcyB0aGUgMm5kIHNlcnZlciEiLAorICAgICAgICAgICAgICAgIHJlYWRBc2NpaShjb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCksIEludGVnZXIuTUFYX1ZBTFVFKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzZXJ2ZXIyLmdldFVybCgiLyIpLCBjb25uZWN0aW9uLmdldFVSTCgpKTsKKworICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIGZpcnN0IHNlcnZlciB3YXMgY2FyZWZ1bCB0byByZWN5Y2xlIHRoZSBjb25uZWN0aW9uCisgICAgICAgIGFzc2VydEVxdWFscygiVGhpcyBpcyB0aGUgZmlyc3Qgc2VydmVyIGFnYWluISIsCisgICAgICAgICAgICAgICAgcmVhZEFzY2lpKHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuU3RyZWFtKCksIEludGVnZXIuTUFYX1ZBTFVFKSk7CisKKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IGZpcnN0ID0gc2VydmVyLnRha2VSZXF1ZXN0KCk7CisgICAgICAgIGFzc2VydENvbnRhaW5zKGZpcnN0LmdldEhlYWRlcnMoKSwgIkhvc3Q6ICIgKyBob3N0TmFtZSArICI6IiArIHNlcnZlci5nZXRQb3J0KCkpOworICAgICAgICBSZWNvcmRlZFJlcXVlc3Qgc2Vjb25kID0gc2VydmVyMi50YWtlUmVxdWVzdCgpOworICAgICAgICBhc3NlcnRDb250YWlucyhzZWNvbmQuZ2V0SGVhZGVycygpLCAiSG9zdDogIiArIGhvc3ROYW1lICsgIjoiICsgc2VydmVyMi5nZXRQb3J0KCkpOworICAgICAgICBSZWNvcmRlZFJlcXVlc3QgdGhpcmQgPSBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJFeHBlY3RlZCBjb25uZWN0aW9uIHJldXNlIiwgMSwgdGhpcmQuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7CisKKyAgICAgICAgc2VydmVyMi5zaHV0ZG93bigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXNwb25zZTMwME11bHRpcGxlQ2hvaWNlV2l0aFBvc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQ2hyb21lIGRvZXNuJ3QgZm9sbG93IHRoZSByZWRpcmVjdCwgYnV0IEZpcmVmb3ggYW5kIHRoZSBSSSBib3RoIGRvCisgICAgICAgIHRlc3RSZXNwb25zZVJlZGlyZWN0ZWRXaXRoUG9zdChIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX01VTFRfQ0hPSUNFKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVzcG9uc2UzMDFNb3ZlZFBlcm1hbmVudGx5V2l0aFBvc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFJlc3BvbnNlUmVkaXJlY3RlZFdpdGhQb3N0KEh0dHBVUkxDb25uZWN0aW9uLkhUVFBfTU9WRURfUEVSTSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlc3BvbnNlMzAyTW92ZWRUZW1wb3JhcmlseVdpdGhQb3N0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RSZXNwb25zZVJlZGlyZWN0ZWRXaXRoUG9zdChIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX01PVkVEX1RFTVApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXNwb25zZTMwM1NlZU90aGVyV2l0aFBvc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFJlc3BvbnNlUmVkaXJlY3RlZFdpdGhQb3N0KEh0dHBVUkxDb25uZWN0aW9uLkhUVFBfU0VFX09USEVSKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdFJlc3BvbnNlUmVkaXJlY3RlZFdpdGhQb3N0KGludCByZWRpcmVjdENvZGUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuc2V0UmVzcG9uc2VDb2RlKHJlZGlyZWN0Q29kZSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMb2NhdGlvbjogL3BhZ2UyIikKKyAgICAgICAgICAgICAgICAuc2V0Qm9keSgiVGhpcyBwYWdlIGhhcyBtb3ZlZCEiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJQYWdlIDIiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiL3BhZ2UxIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXREb091dHB1dCh0cnVlKTsKKyAgICAgICAgYnl0ZVtdIHJlcXVlc3RCb2R5ID0geyAnQScsICdCJywgJ0MnLCAnRCcgfTsKKyAgICAgICAgT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSA9IGNvbm5lY3Rpb24uZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIG91dHB1dFN0cmVhbS53cml0ZShyZXF1ZXN0Qm9keSk7CisgICAgICAgIG91dHB1dFN0cmVhbS5jbG9zZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlBhZ2UgMiIsIHJlYWRBc2NpaShjb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCksIEludGVnZXIuTUFYX1ZBTFVFKSk7CisgICAgICAgIGFzc2VydFRydWUoY29ubmVjdGlvbi5nZXREb091dHB1dCgpKTsKKworICAgICAgICBSZWNvcmRlZFJlcXVlc3QgcGFnZTEgPSBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJQT1NUIC9wYWdlMSBIVFRQLzEuMSIsIHBhZ2UxLmdldFJlcXVlc3RMaW5lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLnRvU3RyaW5nKHJlcXVlc3RCb2R5KSwgQXJyYXlzLnRvU3RyaW5nKHBhZ2UxLmdldEJvZHkoKSkpOworCisgICAgICAgIFJlY29yZGVkUmVxdWVzdCBwYWdlMiA9IHNlcnZlci50YWtlUmVxdWVzdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkdFVCAvcGFnZTIgSFRUUC8xLjEiLCBwYWdlMi5nZXRSZXF1ZXN0TGluZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVzcG9uc2UzMDVVc2VQcm94eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIucGxheSgpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuc2V0UmVzcG9uc2VDb2RlKEh0dHBVUkxDb25uZWN0aW9uLkhUVFBfVVNFX1BST1hZKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkxvY2F0aW9uOiAiICsgc2VydmVyLmdldFVybCgiLyIpKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJUaGlzIHBhZ2UgaGFzIG1vdmVkISIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIlByb3h5IFJlc3BvbnNlIikpOworCisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi9mb28iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICAvLyBGYWlscyBvbiB0aGUgUkksIHdoaWNoIGdldHMgIlByb3h5IFJlc3BvbnNlIgorICAgICAgICBhc3NlcnRFcXVhbHMoIlRoaXMgcGFnZSBoYXMgbW92ZWQhIiwKKyAgICAgICAgICAgICAgICByZWFkQXNjaWkoY29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpLCBJbnRlZ2VyLk1BWF9WQUxVRSkpOworCisgICAgICAgIFJlY29yZGVkUmVxdWVzdCBwYWdlMSA9IHNlcnZlci50YWtlUmVxdWVzdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkdFVCAvZm9vIEhUVFAvMS4xIiwgcGFnZTEuZ2V0UmVxdWVzdExpbmUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBzZXJ2ZXIuZ2V0UmVxdWVzdENvdW50KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RIdHRwc1dpdGhDdXN0b21UcnVzdE1hbmFnZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUmVjb3JkaW5nSG9zdG5hbWVWZXJpZmllciBob3N0bmFtZVZlcmlmaWVyID0gbmV3IFJlY29yZGluZ0hvc3RuYW1lVmVyaWZpZXIoKTsKKyAgICAgICAgUmVjb3JkaW5nVHJ1c3RNYW5hZ2VyIHRydXN0TWFuYWdlciA9IG5ldyBSZWNvcmRpbmdUcnVzdE1hbmFnZXIoKTsKKyAgICAgICAgU1NMQ29udGV4dCBzYyA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UoIlRMUyIpOworICAgICAgICBzYy5pbml0KG51bGwsIG5ldyBUcnVzdE1hbmFnZXJbXSB7IHRydXN0TWFuYWdlciB9LCBuZXcgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb20oKSk7CisKKyAgICAgICAgSG9zdG5hbWVWZXJpZmllciBkZWZhdWx0SG9zdG5hbWVWZXJpZmllciA9IEh0dHBzVVJMQ29ubmVjdGlvbi5nZXREZWZhdWx0SG9zdG5hbWVWZXJpZmllcigpOworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24uc2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoaG9zdG5hbWVWZXJpZmllcik7CisgICAgICAgIFNTTFNvY2tldEZhY3RvcnkgZGVmYXVsdFNTTFNvY2tldEZhY3RvcnkgPSBIdHRwc1VSTENvbm5lY3Rpb24uZ2V0RGVmYXVsdFNTTFNvY2tldEZhY3RvcnkoKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uLnNldERlZmF1bHRTU0xTb2NrZXRGYWN0b3J5KHNjLmdldFNvY2tldEZhY3RvcnkoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUZXN0U1NMQ29udGV4dCB0ZXN0U1NMQ29udGV4dCA9IFRlc3RTU0xDb250ZXh0LmNyZWF0ZSgpOworICAgICAgICAgICAgc2VydmVyLnVzZUh0dHBzKHRlc3RTU0xDb250ZXh0LnNlcnZlckNvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLCBmYWxzZSk7CisgICAgICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQUJDIikpOworICAgICAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkRFRiIpKTsKKyAgICAgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJHSEkiKSk7CisgICAgICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgICAgICBVUkwgdXJsID0gc2VydmVyLmdldFVybCgiLyIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkMiLCByZWFkQXNjaWkodXJsLm9wZW5TdHJlYW0oKSwgSW50ZWdlci5NQVhfVkFMVUUpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiREVGIiwgcmVhZEFzY2lpKHVybC5vcGVuU3RyZWFtKCksIEludGVnZXIuTUFYX1ZBTFVFKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkdISSIsIHJlYWRBc2NpaSh1cmwub3BlblN0cmVhbSgpLCBJbnRlZ2VyLk1BWF9WQUxVRSkpOworCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdCgidmVyaWZ5ICIgKyBob3N0TmFtZSksIGhvc3RuYW1lVmVyaWZpZXIuY2FsbHMpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoImNoZWNrU2VydmVyVHJ1c3RlZCBbIgorICAgICAgICAgICAgICAgICAgICArICJDTj0iICsgaG9zdE5hbWUgKyAiIDEsICIKKyAgICAgICAgICAgICAgICAgICAgKyAiQ049VGVzdCBJbnRlcm1lZGlhdGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDEsICIKKyAgICAgICAgICAgICAgICAgICAgKyAiQ049VGVzdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAxIgorICAgICAgICAgICAgICAgICAgICArICJdIFJTQSIpLAorICAgICAgICAgICAgICAgICAgICB0cnVzdE1hbmFnZXIuY2FsbHMpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uLnNldERlZmF1bHRIb3N0bmFtZVZlcmlmaWVyKGRlZmF1bHRIb3N0bmFtZVZlcmlmaWVyKTsKKyAgICAgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbi5zZXREZWZhdWx0U1NMU29ja2V0RmFjdG9yeShkZWZhdWx0U1NMU29ja2V0RmFjdG9yeSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29ubmVjdFRpbWVvdXRzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3R1Y2tTZXJ2ZXIgc3MgPSBuZXcgU3R1Y2tTZXJ2ZXIoKTsKKyAgICAgICAgaW50IHNlcnZlclBvcnQgPSBzcy5nZXRMb2NhbFBvcnQoKTsKKyAgICAgICAgVVJMQ29ubmVjdGlvbiB1cmxDb25uZWN0aW9uID0gbmV3IFVSTCgiaHR0cDovL2xvY2FsaG9zdDoiICsgc2VydmVyUG9ydCkub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgaW50IHRpbWVvdXQgPSAxMDAwOworICAgICAgICB1cmxDb25uZWN0aW9uLnNldENvbm5lY3RUaW1lb3V0KHRpbWVvdXQpOworICAgICAgICBsb25nIHN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB1cmxDb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldFRpbWVvdXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGxvbmcgYWN0dWFsID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydDsKKyAgICAgICAgICAgIGFzc2VydFRydWUoTWF0aC5hYnModGltZW91dCAtIGFjdHVhbCkgPCA1MDApOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc3MuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkVGltZW91dHMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvKgorICAgICAgICAgKiBUaGlzIHJlbGllcyBvbiB0aGUgZmFjdCB0aGF0IE1vY2tXZWJTZXJ2ZXIgZG9lc24ndCBjbG9zZSB0aGUKKyAgICAgICAgICogY29ubmVjdGlvbiBhZnRlciBhIHJlc3BvbnNlIGhhcyBiZWVuIHNlbnQuIFRoaXMgY2F1c2VzIHRoZSBjbGllbnQgdG8KKyAgICAgICAgICogdHJ5IHRvIHJlYWQgbW9yZSBieXRlcyB0aGFuIGFyZSBzZW50LCB3aGljaCByZXN1bHRzIGluIGEgdGltZW91dC4KKyAgICAgICAgICovCisgICAgICAgIE1vY2tSZXNwb25zZSB0aW1lb3V0ID0gbmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIkFCQyIpCisgICAgICAgICAgICAgICAgLmNsZWFySGVhZGVycygpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ29udGVudC1MZW5ndGg6IDQiKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUodGltZW91dCk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJ1bnVzZWQiKSk7IC8vIHRvIGtlZXAgdGhlIHNlcnZlciBhbGl2ZQorICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTENvbm5lY3Rpb24gdXJsQ29ubmVjdGlvbiA9IHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICB1cmxDb25uZWN0aW9uLnNldFJlYWRUaW1lb3V0KDEwMDApOworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IHVybENvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdBJywgaW4ucmVhZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdCJywgaW4ucmVhZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdDJywgaW4ucmVhZCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluLnJlYWQoKTsgLy8gaWYgQ29udGVudC1MZW5ndGggd2FzIGFjY3VyYXRlLCB0aGlzIHdvdWxkIHJldHVybiAtMSBpbW1lZGlhdGVseQorICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTb2NrZXRUaW1lb3V0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0Q2h1bmtlZEVuY29kaW5nQXNSZXF1ZXN0UHJvcGVydHkoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiB1cmxDb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgdXJsQ29ubmVjdGlvbi5zZXRSZXF1ZXN0UHJvcGVydHkoIlRyYW5zZmVyLWVuY29kaW5nIiwgImNodW5rZWQiKTsKKyAgICAgICAgdXJsQ29ubmVjdGlvbi5zZXREb091dHB1dCh0cnVlKTsKKyAgICAgICAgdXJsQ29ubmVjdGlvbi5nZXRPdXRwdXRTdHJlYW0oKS53cml0ZSgiQUJDIi5nZXRCeXRlcygiVVRGLTgiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyMDAsIHVybENvbm5lY3Rpb24uZ2V0UmVzcG9uc2VDb2RlKCkpOworCisgICAgICAgIFJlY29yZGVkUmVxdWVzdCByZXF1ZXN0ID0gc2VydmVyLnRha2VSZXF1ZXN0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJDIiwgbmV3IFN0cmluZyhyZXF1ZXN0LmdldEJvZHkoKSwgIlVURi04IikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25uZWN0aW9uQ2xvc2VJblJlcXVlc3QoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpKTsgLy8gc2VydmVyIGRvZXNuJ3QgaG9ub3IgdGhlIGNvbm5lY3Rpb246IGNsb3NlIGhlYWRlciEKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBhID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYS5zZXRSZXF1ZXN0UHJvcGVydHkoIkNvbm5lY3Rpb24iLCAiY2xvc2UiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIwMCwgYS5nZXRSZXNwb25zZUNvZGUoKSk7CisKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gYiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyMDAsIGIuZ2V0UmVzcG9uc2VDb2RlKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygwLCBzZXJ2ZXIudGFrZVJlcXVlc3QoKS5nZXRTZXF1ZW5jZU51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXaGVuIGNvbm5lY3Rpb246IGNsb3NlIGlzIHVzZWQsIGVhY2ggcmVxdWVzdCBzaG91bGQgZ2V0IGl0cyBvd24gY29ubmVjdGlvbiIsCisgICAgICAgICAgICAgICAgMCwgc2VydmVyLnRha2VSZXF1ZXN0KCkuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbm5lY3Rpb25DbG9zZUluUmVzcG9uc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLmFkZEhlYWRlcigiQ29ubmVjdGlvbjogY2xvc2UiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gYSA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyMDAsIGEuZ2V0UmVzcG9uc2VDb2RlKCkpOworCisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGIgPSAoSHR0cFVSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBhc3NlcnRFcXVhbHMoMjAwLCBiLmdldFJlc3BvbnNlQ29kZSgpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgc2VydmVyLnRha2VSZXF1ZXN0KCkuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV2hlbiBjb25uZWN0aW9uOiBjbG9zZSBpcyB1c2VkLCBlYWNoIHJlcXVlc3Qgc2hvdWxkIGdldCBpdHMgb3duIGNvbm5lY3Rpb24iLAorICAgICAgICAgICAgICAgIDAsIHNlcnZlci50YWtlUmVxdWVzdCgpLmdldFNlcXVlbmNlTnVtYmVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25uZWN0aW9uQ2xvc2VXaXRoUmVkaXJlY3QoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja1Jlc3BvbnNlIHJlc3BvbnNlID0gbmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLnNldFJlc3BvbnNlQ29kZShIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX01PVkVEX1RFTVApCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTG9jYXRpb246IC9mb28iKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNvbm5lY3Rpb246IGNsb3NlIik7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKHJlc3BvbnNlKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIlRoaXMgaXMgdGhlIG5ldyBsb2NhdGlvbiEiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhpcyBpcyB0aGUgbmV3IGxvY2F0aW9uISIsCisgICAgICAgICAgICAgICAgcmVhZEFzY2lpKGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKSwgSW50ZWdlci5NQVhfVkFMVUUpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgc2VydmVyLnRha2VSZXF1ZXN0KCkuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV2hlbiBjb25uZWN0aW9uOiBjbG9zZSBpcyB1c2VkLCBlYWNoIHJlcXVlc3Qgc2hvdWxkIGdldCBpdHMgb3duIGNvbm5lY3Rpb24iLAorICAgICAgICAgICAgICAgIDAsIHNlcnZlci50YWtlUmVxdWVzdCgpLmdldFNlcXVlbmNlTnVtYmVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXNwb25zZUNvZGVEaXNhZ3JlZXNXaXRoSGVhZGVycygpIHRocm93cyBJT0V4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuc2V0UmVzcG9uc2VDb2RlKEh0dHBVUkxDb25uZWN0aW9uLkhUVFBfTk9fQ09OVEVOVCkKKyAgICAgICAgICAgICAgICAuc2V0Qm9keSgiVGhpcyBib2R5IGlzIG5vdCBhbGxvd2VkISIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGlzIGJvZHkgaXMgbm90IGFsbG93ZWQhIiwKKyAgICAgICAgICAgICAgICByZWFkQXNjaWkoY29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpLCBJbnRlZ2VyLk1BWF9WQUxVRSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTaW5nbGVCeXRlUmVhZElzU2lnbmVkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkobmV3IGJ5dGVbXSB7IC0yLCAtMSB9KSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gY29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMjU0LCBpbi5yZWFkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMjU1LCBpbi5yZWFkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZsdXNoQWZ0ZXJTdHJlYW1UcmFuc21pdHRlZFdpdGhDaHVua2VkRW5jb2RpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0ZXN0Rmx1c2hBZnRlclN0cmVhbVRyYW5zbWl0dGVkKFRyYW5zZmVyS2luZC5DSFVOS0VEKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rmx1c2hBZnRlclN0cmVhbVRyYW5zbWl0dGVkV2l0aEZpeGVkTGVuZ3RoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEZsdXNoQWZ0ZXJTdHJlYW1UcmFuc21pdHRlZChUcmFuc2ZlcktpbmQuRklYRURfTEVOR1RIKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rmx1c2hBZnRlclN0cmVhbVRyYW5zbWl0dGVkV2l0aE5vTGVuZ3RoSGVhZGVycygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RGbHVzaEFmdGVyU3RyZWFtVHJhbnNtaXR0ZWQoVHJhbnNmZXJLaW5kLkVORF9PRl9TVFJFQU0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdlIGV4cGxpY2l0bHkgcGVybWl0IGFwcHMgdG8gY2xvc2UgdGhlIHVwbG9hZCBzdHJlYW0gZXZlbiBhZnRlciBpdCBoYXMKKyAgICAgKiBiZWVuIHRyYW5zbWl0dGVkLiAgV2UgYWxzbyBwZXJtaXQgZmx1c2ggc28gdGhhdCBidWZmZXJlZCBzdHJlYW1zIGNhbgorICAgICAqIGRvIGEgbm8tb3AgZmx1c2ggd2hlbiB0aGV5IGFyZSBjbG9zZWQuIGh0dHA6Ly9iLzMwMzg0NzAKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgdGVzdEZsdXNoQWZ0ZXJTdHJlYW1UcmFuc21pdHRlZChUcmFuc2ZlcktpbmQgdHJhbnNmZXJLaW5kKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiYWJjIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLnNldERvT3V0cHV0KHRydWUpOworICAgICAgICBieXRlW10gdXBsb2FkID0gImRlZiIuZ2V0Qnl0ZXMoIlVURi04Iik7CisKKyAgICAgICAgaWYgKHRyYW5zZmVyS2luZCA9PSBUcmFuc2ZlcktpbmQuQ0hVTktFRCkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5zZXRDaHVua2VkU3RyZWFtaW5nTW9kZSgwKTsKKyAgICAgICAgfSBlbHNlIGlmICh0cmFuc2ZlcktpbmQgPT0gVHJhbnNmZXJLaW5kLkZJWEVEX0xFTkdUSCkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5zZXRGaXhlZExlbmd0aFN0cmVhbWluZ01vZGUodXBsb2FkLmxlbmd0aCk7CisgICAgICAgIH0KKworICAgICAgICBPdXRwdXRTdHJlYW0gb3V0ID0gY29ubmVjdGlvbi5nZXRPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgb3V0LndyaXRlKHVwbG9hZCk7CisgICAgICAgIGFzc2VydEVxdWFscygiYWJjIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKSwgSW50ZWdlci5NQVhfVkFMVUUpKTsKKworICAgICAgICBvdXQuZmx1c2goKTsgLy8gZHViaW91cyBidXQgcGVybWl0dGVkCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXQud3JpdGUoImdoaSIuZ2V0Qnl0ZXMoIlVURi04IikpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEhlYWRlcnNUaHJvd3MoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0U29ja2V0UG9saWN5KERJU0NPTk5FQ1RfQVRfU1RBUlQpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0S2VlcEFsaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1vY2tXZWJTZXJ2ZXIgc2VydmVyID0gbmV3IE1vY2tXZWJTZXJ2ZXIoKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkFCQyIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICAvLyBUaGUgcmVxdWVzdCBzaG91bGQgd29yayBvbmNlIGFuZCB0aGVuIGZhaWwKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gc2VydmVyLmdldFVybCgiIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW5wdXQgPSBjb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJDIiwgcmVhZEFzY2lpKGlucHV0LCBJbnRlZ2VyLk1BWF9WQUxVRSkpOworICAgICAgICBpbnB1dC5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VydmVyLmdldFVybCgiIikub3BlbkNvbm5lY3Rpb24oKS5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChDb25uZWN0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIHRlc3QgZ29lcyB0aHJvdWdoIHRoZSBleGhhdXN0aXZlIHNldCBvZiBpbnRlcmVzdGluZyBBU0NJSSBjaGFyYWN0ZXJzCisgICAgICogYmVjYXVzZSBtb3N0IG9mIHRob3NlIGNoYXJhY3RlcnMgYXJlIGludGVyZXN0aW5nIGluIHNvbWUgd2F5IGFjY29yZGluZyB0bworICAgICAqIFJGQyAyMzk2IGFuZCBSRkMgMjczMi4gaHR0cDovL2IvMTE1ODc4MAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RMZW5pZW50VXJsVG9VcmkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gYWxwaGFudW0KKyAgICAgICAgdGVzdFVybFRvVXJpTWFwcGluZygiYWJ6QUJaMDkiLCAiYWJ6QUJaMDkiLCAiYWJ6QUJaMDkiLCAiYWJ6QUJaMDkiLCAiYWJ6QUJaMDkiKTsKKworICAgICAgICAvLyBjb250cm9sIGNoYXJhY3RlcnMKKyAgICAgICAgdGVzdFVybFRvVXJpTWFwcGluZygiXHUwMDAxIiwgIiUwMSIsICIlMDEiLCAiJTAxIiwgIiUwMSIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCJcdTAwMWYiLCAiJTFGIiwgIiUxRiIsICIlMUYiLCAiJTFGIik7CisKKyAgICAgICAgLy8gYXNjaWkgY2hhcmFjdGVycworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCIlMjAiLCAiJTIwIiwgIiUyMCIsICIlMjAiLCAiJTIwIik7CisgICAgICAgIHRlc3RVcmxUb1VyaU1hcHBpbmcoIiUyMCIsICIlMjAiLCAiJTIwIiwgIiUyMCIsICIlMjAiKTsKKyAgICAgICAgdGVzdFVybFRvVXJpTWFwcGluZygiICIsICIlMjAiLCAiJTIwIiwgIiUyMCIsICIlMjAiKTsKKyAgICAgICAgdGVzdFVybFRvVXJpTWFwcGluZygiISIsICIhIiwgIiEiLCAiISIsICIhIik7CisgICAgICAgIHRlc3RVcmxUb1VyaU1hcHBpbmcoIlwiIiwgIiUyMiIsICIlMjIiLCAiJTIyIiwgIiUyMiIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCIjIiwgbnVsbCwgbnVsbCwgbnVsbCwgIiUyMyIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCIkIiwgIiQiLCAiJCIsICIkIiwgIiQiKTsKKyAgICAgICAgdGVzdFVybFRvVXJpTWFwcGluZygiJiIsICImIiwgIiYiLCAiJiIsICImIik7CisgICAgICAgIHRlc3RVcmxUb1VyaU1hcHBpbmcoIiciLCAiJyIsICInIiwgIiciLCAiJyIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCIoIiwgIigiLCAiKCIsICIoIiwgIigiKTsKKyAgICAgICAgdGVzdFVybFRvVXJpTWFwcGluZygiKSIsICIpIiwgIikiLCAiKSIsICIpIik7CisgICAgICAgIHRlc3RVcmxUb1VyaU1hcHBpbmcoIioiLCAiKiIsICIqIiwgIioiLCAiKiIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCIrIiwgIisiLCAiKyIsICIrIiwgIisiKTsKKyAgICAgICAgdGVzdFVybFRvVXJpTWFwcGluZygiLCIsICIsIiwgIiwiLCAiLCIsICIsIik7CisgICAgICAgIHRlc3RVcmxUb1VyaU1hcHBpbmcoIi0iLCAiLSIsICItIiwgIi0iLCAiLSIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCIuIiwgIi4iLCAiLiIsICIuIiwgIi4iKTsKKyAgICAgICAgdGVzdFVybFRvVXJpTWFwcGluZygiLyIsIG51bGwsICIvIiwgIi8iLCAiLyIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCI6IiwgbnVsbCwgIjoiLCAiOiIsICI6Iik7CisgICAgICAgIHRlc3RVcmxUb1VyaU1hcHBpbmcoIjsiLCAiOyIsICI7IiwgIjsiLCAiOyIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCI8IiwgIiUzQyIsICIlM0MiLCAiJTNDIiwgIiUzQyIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCI9IiwgIj0iLCAiPSIsICI9IiwgIj0iKTsKKyAgICAgICAgdGVzdFVybFRvVXJpTWFwcGluZygiPiIsICIlM0UiLCAiJTNFIiwgIiUzRSIsICIlM0UiKTsKKyAgICAgICAgdGVzdFVybFRvVXJpTWFwcGluZygiPyIsIG51bGwsIG51bGwsICI/IiwgIj8iKTsKKyAgICAgICAgdGVzdFVybFRvVXJpTWFwcGluZygiQCIsICJAIiwgIkAiLCAiQCIsICJAIik7CisgICAgICAgIHRlc3RVcmxUb1VyaU1hcHBpbmcoIlsiLCBudWxsLCAiJTVCIiwgbnVsbCwgIiU1QiIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCJcXCIsICIlNUMiLCAiJTVDIiwgIiU1QyIsICIlNUMiKTsKKyAgICAgICAgdGVzdFVybFRvVXJpTWFwcGluZygiXSIsIG51bGwsICIlNUQiLCBudWxsLCAiJTVEIik7CisgICAgICAgIHRlc3RVcmxUb1VyaU1hcHBpbmcoIl4iLCAiJTVFIiwgIiU1RSIsICIlNUUiLCAiJTVFIik7CisgICAgICAgIHRlc3RVcmxUb1VyaU1hcHBpbmcoIl8iLCAiXyIsICJfIiwgIl8iLCAiXyIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCJgIiwgIiU2MCIsICIlNjAiLCAiJTYwIiwgIiU2MCIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCJ7IiwgIiU3QiIsICIlN0IiLCAiJTdCIiwgIiU3QiIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCJ8IiwgIiU3QyIsICIlN0MiLCAiJTdDIiwgIiU3QyIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCJ9IiwgIiU3RCIsICIlN0QiLCAiJTdEIiwgIiU3RCIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCJ+IiwgIn4iLCAifiIsICJ+IiwgIn4iKTsKKyAgICAgICAgdGVzdFVybFRvVXJpTWFwcGluZygifiIsICJ+IiwgIn4iLCAifiIsICJ+Iik7CisgICAgICAgIHRlc3RVcmxUb1VyaU1hcHBpbmcoIlx1MDA3ZiIsICIlN0YiLCAiJTdGIiwgIiU3RiIsICIlN0YiKTsKKworICAgICAgICAvLyBiZXlvbmQgYXNjaWkKKyAgICAgICAgdGVzdFVybFRvVXJpTWFwcGluZygiXHUwMDgwIiwgIiVDMiU4MCIsICIlQzIlODAiLCAiJUMyJTgwIiwgIiVDMiU4MCIpOworICAgICAgICB0ZXN0VXJsVG9VcmlNYXBwaW5nKCJcdTIwYWMiLCAiXHUyMGFjIiwgIlx1MjBhYyIsICJcdTIwYWMiLCAiXHUyMGFjIik7CisgICAgICAgIHRlc3RVcmxUb1VyaU1hcHBpbmcoIlx1ZDg0Mlx1ZGY5ZiIsCisgICAgICAgICAgICAgICAgIlx1ZDg0Mlx1ZGY5ZiIsICJcdWQ4NDJcdWRmOWYiLCAiXHVkODQyXHVkZjlmIiwgIlx1ZDg0Mlx1ZGY5ZiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RMZW5pZW50VXJsVG9VcmlOdWwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFVybFRvVXJpTWFwcGluZygiXHUwMDAwIiwgIiUwMCIsICIlMDAiLCAiJTAwIiwgIiUwMCIpOyAvLyBSSSBmYWlscyB0aGlzCisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RVcmxUb1VyaU1hcHBpbmcoU3RyaW5nIHN0cmluZywgU3RyaW5nIGFzQXV0aG9yaXR5LCBTdHJpbmcgYXNGaWxlLAorICAgICAgICAgICAgU3RyaW5nIGFzUXVlcnksIFN0cmluZyBhc0ZyYWdtZW50KSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFzQXV0aG9yaXR5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2hvc3QiICsgYXNBdXRob3JpdHkgKyAiLnRsZC8iLAorICAgICAgICAgICAgICAgICAgICBiYWNrZG9vclVybFRvVXJpKG5ldyBVUkwoImh0dHA6Ly9ob3N0IiArIHN0cmluZyArICIudGxkLyIpKS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYXNGaWxlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2hvc3QudGxkL2ZpbGUiICsgYXNGaWxlICsgIi8iLAorICAgICAgICAgICAgICAgICAgICBiYWNrZG9vclVybFRvVXJpKG5ldyBVUkwoImh0dHA6Ly9ob3N0LnRsZC9maWxlIiArIHN0cmluZyArICIvIikpLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIGlmIChhc1F1ZXJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2hvc3QudGxkL2ZpbGU/cSIgKyBhc1F1ZXJ5ICsgIj14IiwKKyAgICAgICAgICAgICAgICAgICAgYmFja2Rvb3JVcmxUb1VyaShuZXcgVVJMKCJodHRwOi8vaG9zdC50bGQvZmlsZT9xIiArIHN0cmluZyArICI9eCIpKS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9ob3N0LnRsZC9maWxlIyIgKyBhc0ZyYWdtZW50ICsgIi14IiwKKyAgICAgICAgICAgICAgICBiYWNrZG9vclVybFRvVXJpKG5ldyBVUkwoImh0dHA6Ly9ob3N0LnRsZC9maWxlIyIgKyBhc0ZyYWdtZW50ICsgIi14IikpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4ZXJjaXNlcyBIdHRwVVJMQ29ubmVjdGlvbiB0byBjb252ZXJ0IFVSTCB0byBhIFVSSS4gVW5saWtlIFVSTCN0b1VSSSwKKyAgICAgKiBIdHRwVVJMQ29ubmVjdGlvbiByZWNvdmVycyBmcm9tIFVSTHMgd2l0aCB1bmVzY2FwZWQgYnV0IHVuc3VwcG9ydGVkIFVSSQorICAgICAqIGNoYXJhY3RlcnMgbGlrZSAneycgYW5kICd8JyBieSBlc2NhcGluZyB0aGVzZSBjaGFyYWN0ZXJzLgorICAgICAqLworICAgIHByaXZhdGUgVVJJIGJhY2tkb29yVXJsVG9VcmkoVVJMIHVybCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEF0b21pY1JlZmVyZW5jZTxVUkk+IHVyaVJlZmVyZW5jZSA9IG5ldyBBdG9taWNSZWZlcmVuY2U8VVJJPigpOworCisgICAgICAgIFJlc3BvbnNlQ2FjaGUuc2V0RGVmYXVsdChuZXcgUmVzcG9uc2VDYWNoZSgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgQ2FjaGVSZXF1ZXN0IHB1dChVUkkgdXJpLCBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIENhY2hlUmVzcG9uc2UgZ2V0KFVSSSB1cmksIFN0cmluZyByZXF1ZXN0TWV0aG9kLAorICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IHJlcXVlc3RIZWFkZXJzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHVyaVJlZmVyZW5jZS5zZXQodXJpKTsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICAgICAgY29ubmVjdGlvbi5nZXRSZXNwb25zZUNvZGUoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gdXJpUmVmZXJlbmNlLmdldCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERvbid0IGV4cGxvZGUgaWYgdGhlIGNhY2hlIHJldHVybnMgYSBudWxsIGJvZHkuIGh0dHA6Ly9iLzMzNzM2OTkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVzcG9uc2VDYWNoZVJldHVybnNOdWxsT3V0cHV0U3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEF0b21pY0Jvb2xlYW4gYWJvcnRlZCA9IG5ldyBBdG9taWNCb29sZWFuKCk7CisgICAgICAgIFJlc3BvbnNlQ2FjaGUuc2V0RGVmYXVsdChuZXcgUmVzcG9uc2VDYWNoZSgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgQ2FjaGVSZXNwb25zZSBnZXQoVVJJIHVyaSwgU3RyaW5nIHJlcXVlc3RNZXRob2QsCisgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gcmVxdWVzdEhlYWRlcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIENhY2hlUmVxdWVzdCBwdXQoVVJJIHVyaSwgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ2FjaGVSZXF1ZXN0KCkgeworICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgYWJvcnQoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydGVkLnNldCh0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIE91dHB1dFN0cmVhbSBnZXRCb2R5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoImFiY2RlZiIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBjb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiYWJjIiwgcmVhZEFzY2lpKGluLCAzKSk7CisgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIGFzc2VydEZhbHNlKGFib3J0ZWQuZ2V0KCkpOyAvLyBUaGUgYmVzdCBiZWhhdmlvciBpcyBhbWJpZ3VvdXMsIGJ1dCBSSSA2IGRvZXNuJ3QgYWJvcnQgaGVyZQorICAgIH0KKworCisgICAgLyoqCisgICAgICogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD0xNDU2MgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkQWZ0ZXJMYXN0Qnl0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuc2V0Qm9keSgiQUJDIikKKyAgICAgICAgICAgICAgICAuY2xlYXJIZWFkZXJzKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDb25uZWN0aW9uOiBjbG9zZSIpCisgICAgICAgICAgICAgICAgLnNldFNvY2tldFBvbGljeShTb2NrZXRQb2xpY3kuRElTQ09OTkVDVF9BVF9FTkQpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBjb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJDIiwgcmVhZEFzY2lpKGluLCAzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgaW4ucmVhZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKCkpOyAvLyB0aHJvd3MgSU9FeGNlcHRpb24gaW4gR2luZ2VyYnJlYWQKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q29udGVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQSIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gKElucHV0U3RyZWFtKSBjb25uZWN0aW9uLmdldENvbnRlbnQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKGluLCBJbnRlZ2VyLk1BWF9WQUxVRSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDb250ZW50T2ZUeXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uZ2V0Q29udGVudChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5nZXRDb250ZW50KG5ldyBDbGFzc1tdIHsgbnVsbCB9KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROdWxsKGNvbm5lY3Rpb24uZ2V0Q29udGVudChuZXcgQ2xhc3NbXSB7IGdldENsYXNzKCkgfSkpOworICAgICAgICBjb25uZWN0aW9uLmRpc2Nvbm5lY3QoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0T3V0cHV0U3RyZWFtT25HZXRGYWlscygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0T3V0cHV0QWZ0ZXJHZXRJbnB1dFN0cmVhbUZhaWxzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLnNldERvT3V0cHV0KHRydWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICAgICAgY29ubmVjdGlvbi5nZXRPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXREb091dHB1dE9yRG9JbnB1dEFmdGVyQ29ubmVjdEZhaWxzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLmNvbm5lY3QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uc2V0RG9PdXRwdXQodHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uZWN0aW9uLnNldERvSW5wdXQodHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGNvbm5lY3Rpb24uZGlzY29ubmVjdCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDbGllbnRTZW5kc0NvbnRlbnRMZW5ndGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkEiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLnNldERvT3V0cHV0KHRydWUpOworICAgICAgICBPdXRwdXRTdHJlYW0gb3V0ID0gY29ubmVjdGlvbi5nZXRPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgb3V0LndyaXRlKG5ldyBieXRlW10geyAnQScsICdCJywgJ0MnIH0pOworICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKSwgSW50ZWdlci5NQVhfVkFMVUUpKTsKKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IHJlcXVlc3QgPSBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsKKyAgICAgICAgYXNzZXJ0Q29udGFpbnMocmVxdWVzdC5nZXRIZWFkZXJzKCksICJDb250ZW50LUxlbmd0aDogMyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDb250ZW50TGVuZ3RoQ29ubmVjdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkFCQyIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBjb25uZWN0aW9uLmdldENvbnRlbnRMZW5ndGgoKSk7CisgICAgICAgIGNvbm5lY3Rpb24uZGlzY29ubmVjdCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDb250ZW50VHlwZUNvbm5lY3RzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbiIpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIkFCQyIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygidGV4dC9wbGFpbiIsIGNvbm5lY3Rpb24uZ2V0Q29udGVudFR5cGUoKSk7CisgICAgICAgIGNvbm5lY3Rpb24uZGlzY29ubmVjdCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDb250ZW50RW5jb2RpbmdDb25uZWN0cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDb250ZW50LUVuY29kaW5nOiBpZGVudGl0eSIpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIkFCQyIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiaWRlbnRpdHkiLCBjb25uZWN0aW9uLmdldENvbnRlbnRFbmNvZGluZygpKTsKKyAgICAgICAgY29ubmVjdGlvbi5kaXNjb25uZWN0KCk7CisgICAgfQorCisgICAgLy8gaHR0cDovL2IvNDM2MTY1NgorICAgIHB1YmxpYyB2b2lkIHRlc3RVcmxDb250YWluc1F1ZXJ5QnV0Tm9QYXRoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cCIsIHNlcnZlci5nZXRIb3N0TmFtZSgpLCBzZXJ2ZXIuZ2V0UG9ydCgpLCAiP3F1ZXJ5Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaSh1cmwub3BlbkNvbm5lY3Rpb24oKS5nZXRJbnB1dFN0cmVhbSgpLCBJbnRlZ2VyLk1BWF9WQUxVRSkpOworICAgICAgICBSZWNvcmRlZFJlcXVlc3QgcmVxdWVzdCA9IHNlcnZlci50YWtlUmVxdWVzdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkdFVCAvP3F1ZXJ5IEhUVFAvMS4xIiwgcmVxdWVzdC5nZXRSZXF1ZXN0TGluZSgpKTsKKyAgICB9CisKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTIwNDQyCisgICAgcHVibGljIHZvaWQgdGVzdElucHV0U3RyZWFtQXZhaWxhYmxlV2l0aENodW5rZWRFbmNvZGluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0SW5wdXRTdHJlYW1BdmFpbGFibGUoVHJhbnNmZXJLaW5kLkNIVU5LRUQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnB1dFN0cmVhbUF2YWlsYWJsZVdpdGhDb250ZW50TGVuZ3RoSGVhZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RJbnB1dFN0cmVhbUF2YWlsYWJsZShUcmFuc2ZlcktpbmQuRklYRURfTEVOR1RIKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5wdXRTdHJlYW1BdmFpbGFibGVXaXRoTm9MZW5ndGhIZWFkZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RJbnB1dFN0cmVhbUF2YWlsYWJsZShUcmFuc2ZlcktpbmQuRU5EX09GX1NUUkVBTSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RJbnB1dFN0cmVhbUF2YWlsYWJsZShUcmFuc2ZlcktpbmQgdHJhbnNmZXJLaW5kKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgYm9keSA9ICJBQkNERUZHSCI7CisgICAgICAgIE1vY2tSZXNwb25zZSByZXNwb25zZSA9IG5ldyBNb2NrUmVzcG9uc2UoKTsKKyAgICAgICAgdHJhbnNmZXJLaW5kLnNldEJvZHkocmVzcG9uc2UsIGJvZHksIDQpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShyZXNwb25zZSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBib2R5Lmxlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoaW4uYXZhaWxhYmxlKCkgPj0gMCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYm9keS5jaGFyQXQoaSksIGluLnJlYWQoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGluLmF2YWlsYWJsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBpbi5yZWFkKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnNwZWN0U3NsQmVmb3JlQ29ubmVjdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMQ29udGV4dCB0ZXN0U1NMQ29udGV4dCA9IFRlc3RTU0xDb250ZXh0LmNyZWF0ZSgpOworICAgICAgICBzZXJ2ZXIudXNlSHR0cHModGVzdFNTTENvbnRleHQuc2VydmVyQ29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCksIGZhbHNlKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwc1VSTENvbm5lY3Rpb24pIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLnNldFNTTFNvY2tldEZhY3RvcnkodGVzdFNTTENvbnRleHQuY2xpZW50Q29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKGNvbm5lY3Rpb24uZ2V0SG9zdG5hbWVWZXJpZmllcigpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uZ2V0U2VydmVyQ2VydGlmaWNhdGVzKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uZWN0aW9uLmdldENpcGhlclN1aXRlKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uZWN0aW9uLmdldFBlZXJQcmluY2lwYWwoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgd2UgY2FuIGluc3BlY3QgdGhlIFNTTCBzZXNzaW9uIGFmdGVyIGNvbm5lY3QoKS4KKyAgICAgKiBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTI0NDMxCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEluc3BlY3RTc2xBZnRlckNvbm5lY3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgdGVzdFNTTENvbnRleHQgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgc2VydmVyLnVzZUh0dHBzKHRlc3RTU0xDb250ZXh0LnNlcnZlckNvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLCBmYWxzZSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXRTU0xTb2NrZXRGYWN0b3J5KHRlc3RTU0xDb250ZXh0LmNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpKTsKKyAgICAgICAgY29ubmVjdGlvbi5jb25uZWN0KCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoY29ubmVjdGlvbi5nZXRIb3N0bmFtZVZlcmlmaWVyKCkpOworICAgICAgICBhc3NlcnROdWxsKGNvbm5lY3Rpb24uZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoY29ubmVjdGlvbi5nZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoY29ubmVjdGlvbi5nZXRDaXBoZXJTdWl0ZSgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjb25uZWN0aW9uLmdldFBlZXJQcmluY2lwYWwoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGd6aXBwZWQgY29weSBvZiB7QGNvZGUgYnl0ZXN9LgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ3ppcChieXRlW10gYnl0ZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBieXRlc091dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgT3V0cHV0U3RyZWFtIGd6aXBwZWRPdXQgPSBuZXcgR1pJUE91dHB1dFN0cmVhbShieXRlc091dCk7CisgICAgICAgIGd6aXBwZWRPdXQud3JpdGUoYnl0ZXMpOworICAgICAgICBnemlwcGVkT3V0LmNsb3NlKCk7CisgICAgICAgIHJldHVybiBieXRlc091dC50b0J5dGVBcnJheSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGF0IG1vc3Qge0Bjb2RlIGxpbWl0fSBjaGFyYWN0ZXJzIGZyb20ge0Bjb2RlIGlufSBhbmQgYXNzZXJ0cyB0aGF0CisgICAgICogY29udGVudCBlcXVhbHMge0Bjb2RlIGV4cGVjdGVkfS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0Q29udGVudChTdHJpbmcgZXhwZWN0ZWQsIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiwgaW50IGxpbWl0KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY29ubmVjdGlvbi5jb25uZWN0KCk7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwgcmVhZEFzY2lpKGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKSwgbGltaXQpKTsKKyAgICAgICAgKChIdHRwVVJMQ29ubmVjdGlvbikgY29ubmVjdGlvbikuZGlzY29ubmVjdCgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRDb250ZW50KFN0cmluZyBleHBlY3RlZCwgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBhc3NlcnRDb250ZW50KGV4cGVjdGVkLCBjb25uZWN0aW9uLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydENvbnRhaW5zKExpc3Q8U3RyaW5nPiBoZWFkZXJzLCBTdHJpbmcgaGVhZGVyKSB7CisgICAgICAgIGFzc2VydFRydWUoaGVhZGVycy50b1N0cmluZygpLCBoZWFkZXJzLmNvbnRhaW5zKGhlYWRlcikpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRDb250YWluc05vbmVNYXRjaGluZyhMaXN0PFN0cmluZz4gaGVhZGVycywgU3RyaW5nIHBhdHRlcm4pIHsKKyAgICAgICAgZm9yIChTdHJpbmcgaGVhZGVyIDogaGVhZGVycykgeworICAgICAgICAgICAgaWYgKGhlYWRlci5tYXRjaGVzKHBhdHRlcm4pKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiSGVhZGVyICIgKyBoZWFkZXIgKyAiIG1hdGNoZXMgIiArIHBhdHRlcm4pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBTZXQ8U3RyaW5nPiBuZXdTZXQoU3RyaW5nLi4uIGVsZW1lbnRzKSB7CisgICAgICAgIHJldHVybiBuZXcgSGFzaFNldDxTdHJpbmc+KEFycmF5cy5hc0xpc3QoZWxlbWVudHMpKTsKKyAgICB9CisKKyAgICBlbnVtIFRyYW5zZmVyS2luZCB7CisgICAgICAgIENIVU5LRUQoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgdm9pZCBzZXRCb2R5KE1vY2tSZXNwb25zZSByZXNwb25zZSwgYnl0ZVtdIGNvbnRlbnQsIGludCBjaHVua1NpemUpCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmVzcG9uc2Uuc2V0Q2h1bmtlZEJvZHkoY29udGVudCwgY2h1bmtTaXplKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSwKKyAgICAgICAgRklYRURfTEVOR1RIKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHZvaWQgc2V0Qm9keShNb2NrUmVzcG9uc2UgcmVzcG9uc2UsIGJ5dGVbXSBjb250ZW50LCBpbnQgY2h1bmtTaXplKSB7CisgICAgICAgICAgICAgICAgcmVzcG9uc2Uuc2V0Qm9keShjb250ZW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSwKKyAgICAgICAgRU5EX09GX1NUUkVBTSgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSB2b2lkIHNldEJvZHkoTW9ja1Jlc3BvbnNlIHJlc3BvbnNlLCBieXRlW10gY29udGVudCwgaW50IGNodW5rU2l6ZSkgeworICAgICAgICAgICAgICAgIHJlc3BvbnNlLnNldEJvZHkoY29udGVudCk7CisgICAgICAgICAgICAgICAgcmVzcG9uc2Uuc2V0U29ja2V0UG9saWN5KERJU0NPTk5FQ1RfQVRfRU5EKTsKKyAgICAgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yPFN0cmluZz4gaCA9IHJlc3BvbnNlLmdldEhlYWRlcnMoKS5pdGVyYXRvcigpOyBoLmhhc05leHQoKTsgKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChoLm5leHQoKS5zdGFydHNXaXRoKCJDb250ZW50LUxlbmd0aDoiKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaC5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIGFic3RyYWN0IHZvaWQgc2V0Qm9keShNb2NrUmVzcG9uc2UgcmVzcG9uc2UsIGJ5dGVbXSBjb250ZW50LCBpbnQgY2h1bmtTaXplKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgICAgICB2b2lkIHNldEJvZHkoTW9ja1Jlc3BvbnNlIHJlc3BvbnNlLCBTdHJpbmcgY29udGVudCwgaW50IGNodW5rU2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHNldEJvZHkocmVzcG9uc2UsIGNvbnRlbnQuZ2V0Qnl0ZXMoIlVURi04IiksIGNodW5rU2l6ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBlbnVtIFByb3h5Q29uZmlnIHsKKyAgICAgICAgTk9fUFJPWFkoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3QoTW9ja1dlYlNlcnZlciBzZXJ2ZXIsIFVSTCB1cmwpCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChIdHRwVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKFByb3h5Lk5PX1BST1hZKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSwKKworICAgICAgICBDUkVBVEVfQVJHKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0KE1vY2tXZWJTZXJ2ZXIgc2VydmVyLCBVUkwgdXJsKQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiAoSHR0cFVSTENvbm5lY3Rpb24pIHVybC5vcGVuQ29ubmVjdGlvbihzZXJ2ZXIudG9Qcm94eUFkZHJlc3MoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0sCisKKyAgICAgICAgUFJPWFlfU1lTVEVNX1BST1BFUlRZKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0KE1vY2tXZWJTZXJ2ZXIgc2VydmVyLCBVUkwgdXJsKQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgicHJveHlIb3N0IiwgImxvY2FsaG9zdCIpOworICAgICAgICAgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgicHJveHlQb3J0IiwgSW50ZWdlci50b1N0cmluZyhzZXJ2ZXIuZ2V0UG9ydCgpKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIChIdHRwVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0sCisKKyAgICAgICAgSFRUUF9QUk9YWV9TWVNURU1fUFJPUEVSVFkoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3QoTW9ja1dlYlNlcnZlciBzZXJ2ZXIsIFVSTCB1cmwpCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJodHRwLnByb3h5SG9zdCIsICJsb2NhbGhvc3QiKTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoImh0dHAucHJveHlQb3J0IiwgSW50ZWdlci50b1N0cmluZyhzZXJ2ZXIuZ2V0UG9ydCgpKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIChIdHRwVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0sCisKKyAgICAgICAgSFRUUFNfUFJPWFlfU1lTVEVNX1BST1BFUlRZKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0KE1vY2tXZWJTZXJ2ZXIgc2VydmVyLCBVUkwgdXJsKQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgiaHR0cHMucHJveHlIb3N0IiwgImxvY2FsaG9zdCIpOworICAgICAgICAgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgiaHR0cHMucHJveHlQb3J0IiwgSW50ZWdlci50b1N0cmluZyhzZXJ2ZXIuZ2V0UG9ydCgpKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIChIdHRwVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgcHVibGljIGFic3RyYWN0IEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3QoTW9ja1dlYlNlcnZlciBzZXJ2ZXIsIFVSTCB1cmwpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBSZWNvcmRpbmdUcnVzdE1hbmFnZXIgaW1wbGVtZW50cyBYNTA5VHJ1c3RNYW5hZ2VyIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PFN0cmluZz4gY2FsbHMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKworICAgICAgICBwdWJsaWMgWDUwOUNlcnRpZmljYXRlW10gZ2V0QWNjZXB0ZWRJc3N1ZXJzKCkgeworICAgICAgICAgICAgY2FsbHMuYWRkKCJnZXRBY2NlcHRlZElzc3VlcnMiKTsKKyAgICAgICAgICAgIHJldHVybiBuZXcgWDUwOUNlcnRpZmljYXRlW10ge307CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBjaGVja0NsaWVudFRydXN0ZWQoWDUwOUNlcnRpZmljYXRlW10gY2hhaW4sIFN0cmluZyBhdXRoVHlwZSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICAgICAgY2FsbHMuYWRkKCJjaGVja0NsaWVudFRydXN0ZWQgIiArIGNlcnRpZmljYXRlc1RvU3RyaW5nKGNoYWluKSArICIgIiArIGF1dGhUeXBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrU2VydmVyVHJ1c3RlZChYNTA5Q2VydGlmaWNhdGVbXSBjaGFpbiwgU3RyaW5nIGF1dGhUeXBlKQorICAgICAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBjYWxscy5hZGQoImNoZWNrU2VydmVyVHJ1c3RlZCAiICsgY2VydGlmaWNhdGVzVG9TdHJpbmcoY2hhaW4pICsgIiAiICsgYXV0aFR5cGUpOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgY2VydGlmaWNhdGVzVG9TdHJpbmcoWDUwOUNlcnRpZmljYXRlW10gY2VydGlmaWNhdGVzKSB7CisgICAgICAgICAgICBMaXN0PFN0cmluZz4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgICAgICBmb3IgKFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0aWZpY2F0ZSA6IGNlcnRpZmljYXRlcykgeworICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQoY2VydGlmaWNhdGUuZ2V0U3ViamVjdEROKCkgKyAiICIgKyBjZXJ0aWZpY2F0ZS5nZXRTZXJpYWxOdW1iZXIoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBSZWNvcmRpbmdIb3N0bmFtZVZlcmlmaWVyIGltcGxlbWVudHMgSG9zdG5hbWVWZXJpZmllciB7CisgICAgICAgIHByaXZhdGUgZmluYWwgTGlzdDxTdHJpbmc+IGNhbGxzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gdmVyaWZ5KFN0cmluZyBob3N0bmFtZSwgU1NMU2Vzc2lvbiBzZXNzaW9uKSB7CisgICAgICAgICAgICBjYWxscy5hZGQoInZlcmlmeSAiICsgaG9zdG5hbWUpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9VUkxTdHJlYW1IYW5kbGVyRmFjdG9yeVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L1VSTFN0cmVhbUhhbmRsZXJGYWN0b3J5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlNTBlMTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9VUkxTdHJlYW1IYW5kbGVyRmFjdG9yeVRlc3QuamF2YQpAQCAtMCwwICsxLDExOCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5ldDsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkZpZWxkOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTFN0cmVhbUhhbmRsZXI7CitpbXBvcnQgamF2YS5uZXQuVVJMU3RyZWFtSGFuZGxlckZhY3Rvcnk7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGxpYmNvcmUuamF2YS5uZXQuY3VzdG9tc3RyZWFtaGFuZGxlci5odHRwLkhhbmRsZXI7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBVUkxTdHJlYW1IYW5kbGVyRmFjdG9yeVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHJpdmF0ZSBVUkxTdHJlYW1IYW5kbGVyRmFjdG9yeSBvbGRGYWN0b3J5OworICAgIHByaXZhdGUgRmllbGQgZmFjdG9yeUZpZWxkOworICAgIHByaXZhdGUgYm9vbGVhbiBpc0NyZWF0ZVVSTFN0cmVhbUhhbmRsZXJDYWxsZWQ7CisKKyAgICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChGaWVsZCBmaWVsZCA6IFVSTC5jbGFzcy5nZXREZWNsYXJlZEZpZWxkcygpKSB7CisgICAgICAgICAgICBpZiAoVVJMU3RyZWFtSGFuZGxlckZhY3RvcnkuY2xhc3MuZXF1YWxzKGZpZWxkLmdldFR5cGUoKSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKCJVUkwgZGVjbGFyZXMgbXVsdGlwbGUgVVJMU3RyZWFtSGFuZGxlckZhY3RvcnkgZmllbGRzIiwgZmFjdG9yeUZpZWxkKTsKKyAgICAgICAgICAgICAgICBmYWN0b3J5RmllbGQgPSBmaWVsZDsKKyAgICAgICAgICAgICAgICBmYWN0b3J5RmllbGQuc2V0QWNjZXNzaWJsZSh0cnVlKTsKKyAgICAgICAgICAgICAgICBvbGRGYWN0b3J5ID0gKFVSTFN0cmVhbUhhbmRsZXJGYWN0b3J5KSBmYWN0b3J5RmllbGQuZ2V0KG51bGwpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZhaWwoIlVSTCBkb2VzIG5vdCBkZWNsYXJlIGEgVVJMU3RyZWFtSGFuZGxlckZhY3RvcnkgZmllbGQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeUZpZWxkLnNldChudWxsLCBudWxsKTsKKyAgICAgICAgVVJMLnNldFVSTFN0cmVhbUhhbmRsZXJGYWN0b3J5KG9sZEZhY3RvcnkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVVUkxTdHJlYW1IYW5kbGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RVUkxTdHJlYW1IYW5kbGVyRmFjdG9yeSBzaGYgPSBuZXcgVGVzdFVSTFN0cmVhbUhhbmRsZXJGYWN0b3J5KCk7CisgICAgICAgIGFzc2VydEZhbHNlKGlzQ3JlYXRlVVJMU3RyZWFtSGFuZGxlckNhbGxlZCk7CisKKyAgICAgICAgVVJMLnNldFVSTFN0cmVhbUhhbmRsZXJGYWN0b3J5KHNoZik7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vYW5kcm9pZC5jb20vIik7CisKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydFRydWUoY29ubmVjdGlvbiBpbnN0YW5jZW9mIEhhbmRsZXIuSGFuZGxlclVSTENvbm5lY3Rpb24pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkwuc2V0VVJMU3RyZWFtSGFuZGxlckZhY3Rvcnkoc2hmKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoRXJyb3IgZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkwuc2V0VVJMU3RyZWFtSGFuZGxlckZhY3RvcnkobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEVycm9yIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5zdGFsbEN1c3RvbVByb3RvY29sSGFuZGxlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBjbGVhciBjYWNoZWQgcHJvdG9jb2wgaGFuZGxlcnMgaWYgdGhleSBleGlzdAorICAgICAgICBmYWN0b3J5RmllbGQuc2V0KG51bGwsIG51bGwpOworICAgICAgICBVUkwuc2V0VVJMU3RyZWFtSGFuZGxlckZhY3Rvcnkob2xkRmFjdG9yeSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgiamF2YS5wcm90b2NvbC5oYW5kbGVyLnBrZ3MiLCBnZXRIYW5kbGVyUGFja2FnZU5hbWUoKSk7CisgICAgICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSBuZXcgVVJMKCJodHRwOi8vYW5kcm9pZC5jb20vIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoY29ubmVjdGlvbiBpbnN0YW5jZW9mIEhhbmRsZXIuSGFuZGxlclVSTENvbm5lY3Rpb24pOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgU3lzdGVtLmNsZWFyUHJvcGVydHkoImphdmEucHJvdG9jb2wuaGFuZGxlci5wa2dzIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rmlyc3RVc2VJc0NhY2hlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBjbGVhciBjYWNoZWQgcHJvdG9jb2wgaGFuZGxlcnMgaWYgdGhleSBleGlzdAorICAgICAgICBmYWN0b3J5RmllbGQuc2V0KG51bGwsIG51bGwpOworICAgICAgICBVUkwuc2V0VVJMU3RyZWFtSGFuZGxlckZhY3Rvcnkob2xkRmFjdG9yeSk7CisKKyAgICAgICAgLy8gY3JlYXRpbmcgYSBjb25uZWN0aW9uIHNob3VsZCB1c2UgdGhlIHBsYXRmb3JtJ3MgZGVmYXVsdCBzdHJlYW0gaGFuZGxlcgorICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24xID0gbmV3IFVSTCgiaHR0cDovL2FuZHJvaWQuY29tLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEZhbHNlKGNvbm5lY3Rpb24xIGluc3RhbmNlb2YgSGFuZGxlci5IYW5kbGVyVVJMQ29ubmVjdGlvbik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIHNldCB0aGUgcHJvcGVydHkgYW5kIGdldCBhbm90aGVyIGNvbm5lY3Rpb24uIFRoZSBwcm9wZXJ0eSBzaG91bGQgbm90IGJlIGhvbm9yZWQKKyAgICAgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgiamF2YS5wcm90b2NvbC5oYW5kbGVyLnBrZ3MiLCBnZXRIYW5kbGVyUGFja2FnZU5hbWUoKSk7CisgICAgICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24yID0gbmV3IFVSTCgiaHR0cDovL2FuZHJvaWQuY29tLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShjb25uZWN0aW9uMiBpbnN0YW5jZW9mIEhhbmRsZXIuSGFuZGxlclVSTENvbm5lY3Rpb24pOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgU3lzdGVtLmNsZWFyUHJvcGVydHkoImphdmEucHJvdG9jb2wuaGFuZGxlci5wa2dzIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyBnZXRIYW5kbGVyUGFja2FnZU5hbWUoKSB7CisgICAgICAgIFN0cmluZyBjbGFzc05hbWUgPSBIYW5kbGVyLmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgcmV0dXJuIGNsYXNzTmFtZS5zdWJzdHJpbmcoMCwgY2xhc3NOYW1lLmluZGV4T2YoIi5odHRwLkhhbmRsZXIiKSk7CisgICAgfQorCisgICAgY2xhc3MgVGVzdFVSTFN0cmVhbUhhbmRsZXJGYWN0b3J5IGltcGxlbWVudHMgVVJMU3RyZWFtSGFuZGxlckZhY3RvcnkgeworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFVSTFN0cmVhbUhhbmRsZXIgY3JlYXRlVVJMU3RyZWFtSGFuZGxlcihTdHJpbmcgcHJvdG9jb2wpIHsKKyAgICAgICAgICAgIGlzQ3JlYXRlVVJMU3RyZWFtSGFuZGxlckNhbGxlZCA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gbmV3IEhhbmRsZXIoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L1VSTFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L1VSTFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZjU5MTVhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvVVJMVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjcyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmV0OworCitpbXBvcnQgamF2YS5uZXQuSW5ldDZBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGxpYmNvcmUuamF2YS51dGlsLlNlcmlhbGl6YWJsZVRlc3RlcjsKKworcHVibGljIGZpbmFsIGNsYXNzIFVSTFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXJsUGFydHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6Ly91c2VybmFtZTpwYXNzd29yZEBob3N0OjgwODAvZGlyZWN0b3J5L2ZpbGU/cXVlcnkjcmVmIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cCIsIHVybC5nZXRQcm90b2NvbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1c2VybmFtZTpwYXNzd29yZEBob3N0OjgwODAiLCB1cmwuZ2V0QXV0aG9yaXR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInVzZXJuYW1lOnBhc3N3b3JkIiwgdXJsLmdldFVzZXJJbmZvKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImhvc3QiLCB1cmwuZ2V0SG9zdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDgwODAsIHVybC5nZXRQb3J0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoODAsIHVybC5nZXREZWZhdWx0UG9ydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZGlyZWN0b3J5L2ZpbGU/cXVlcnkiLCB1cmwuZ2V0RmlsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZGlyZWN0b3J5L2ZpbGUiLCB1cmwuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJxdWVyeSIsIHVybC5nZXRRdWVyeSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJyZWYiLCB1cmwuZ2V0UmVmKCkpOworICAgIH0KKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTEyNzI0CisgICAgcHVibGljIHZvaWQgdGVzdEV4cGxpY2l0UG9ydCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovL3d3dy5nb29nbGUuY29tOjgwL2V4YW1wbGU/bGFuZ3VhZ2VbaWRdPTIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ3d3cuZ29vZ2xlLmNvbSIsIHVybC5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoODAsIHVybC5nZXRQb3J0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFuZHJvaWQncyBVUkwuZXF1YWxzKCkgd29ya3MgYXMgaWYgdGhlIG5ldHdvcmsgaXMgZG93bi4gVGhpcyBpcyBkaWZmZXJlbnQKKyAgICAgKiBmcm9tIHRoZSBSSSwgd2hpY2ggZG9lcyBwb3RlbnRpYWxseSBzbG93IGFuZCBpbmNvbnNpc3RlbnQgRE5TIGxvb2t1cHMgaW4KKyAgICAgKiBVUkwuZXF1YWxzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHNEb2VzTm90RG9Ib3N0bmFtZVJlc29sdXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChJbmV0QWRkcmVzcyBpbmV0QWRkcmVzcyA6IEluZXRBZGRyZXNzLmdldEFsbEJ5TmFtZSgibG9jYWxob3N0IikpIHsKKyAgICAgICAgICAgIFN0cmluZyBhZGRyZXNzID0gaW5ldEFkZHJlc3MuZ2V0SG9zdEFkZHJlc3MoKTsKKyAgICAgICAgICAgIGlmIChpbmV0QWRkcmVzcyBpbnN0YW5jZW9mIEluZXQ2QWRkcmVzcykgeworICAgICAgICAgICAgICAgIGFkZHJlc3MgPSAiWyIgKyBhZGRyZXNzICsgIl0iOworICAgICAgICAgICAgfQorICAgICAgICAgICAgVVJMIHVybEJ5SG9zdE5hbWUgPSBuZXcgVVJMKCJodHRwOi8vbG9jYWxob3N0L2Zvbz9iYXI9YmF6I3F1dXgiKTsKKyAgICAgICAgICAgIFVSTCB1cmxCeUFkZHJlc3MgPSBuZXcgVVJMKCJodHRwOi8vIiArIGFkZHJlc3MgKyAiL2Zvbz9iYXI9YmF6I3F1dXgiKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJFeHBlY3RlZCAiICsgdXJsQnlIb3N0TmFtZSArICIgdG8gbm90IGVxdWFsICIgKyB1cmxCeUFkZHJlc3MsCisgICAgICAgICAgICAgICAgICAgIHVybEJ5SG9zdE5hbWUuZXF1YWxzKHVybEJ5QWRkcmVzcykpOyAvLyBmYWlscyBvbiBSSSwgd2hpY2ggZG9lcyBETlMKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHNDYXNlTWFwcGluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IFVSTCgiSFRUUDovL2xvY2FsaG9zdC9mb28/YmFyPWJheiNxdXV4IiksCisgICAgICAgICAgICAgICAgbmV3IFVSTCgiSFRUUDovL2xvY2FsaG9zdC9mb28/YmFyPWJheiNxdXV4IikpOworICAgICAgICBhc3NlcnRUcnVlKG5ldyBVUkwoImh0dHA6Ly9sb2NhbGhvc3QvZm9vP2Jhcj1iYXojcXV1eCIpLmVxdWFscygKKyAgICAgICAgICAgICAgICBuZXcgVVJMKCJodHRwOi8vTE9DQUxIT1NUL2Zvbz9iYXI9YmF6I3F1dXgiKSkpOworICAgICAgICBhc3NlcnRGYWxzZShuZXcgVVJMKCJodHRwOi8vbG9jYWxob3N0L2Zvbz9iYXI9YmF6I3F1dXgiKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgbmV3IFVSTCgiaHR0cDovL2xvY2FsaG9zdC9GT08/YmFyPWJheiNxdXV4IikpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobmV3IFVSTCgiaHR0cDovL2xvY2FsaG9zdC9mb28/YmFyPWJheiNxdXV4IikuZXF1YWxzKAorICAgICAgICAgICAgICAgIG5ldyBVUkwoImh0dHA6Ly9sb2NhbGhvc3QvZm9vP0JBUj1CQVojcXV1eCIpKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG5ldyBVUkwoImh0dHA6Ly9sb2NhbGhvc3QvZm9vP2Jhcj1iYXojcXV1eCIpLmVxdWFscygKKyAgICAgICAgICAgICAgICBuZXcgVVJMKCJodHRwOi8vbG9jYWxob3N0L2Zvbz9iYXI9YmF6I1FVVVgiKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGaWxlRXF1YWxzV2l0aEVtcHR5SG9zdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IFVSTCgiZmlsZSIsICIiLCAtMSwgIi9hLyIpLCBuZXcgVVJMKCJmaWxlOi9hLyIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SHR0cEVxdWFsc1dpdGhFbXB0eUhvc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBVUkwoImh0dHAiLCAiIiwgODAsICIvYS8iKSwgbmV3IFVSTCgiaHR0cDovYS8iKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG5ldyBVUkwoImh0dHAiLCAiIiwgODAsICIvYS8iKS5lcXVhbHMobmV3IFVSTCgiaHR0cDovL2hvc3QvYS8iKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGaWxlRXF1YWxzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgVVJMKCJmaWxlIiwgbnVsbCwgLTEsICIvYSIpLCBuZXcgVVJMKCJmaWxlIiwgbnVsbCwgLTEsICIvYSIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobmV3IFVSTCgiZmlsZSIsIG51bGwsIC0xLCAiL2EiKS5lcXVhbHMobmV3IFVSTCgiZmlsZSIsIG51bGwsIC0xLCAiL0EiKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RKYXJFcXVhbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBVUkwoImphciIsIG51bGwsIC0xLCAiL2EhYiIpLCBuZXcgVVJMKCJqYXIiLCBudWxsLCAtMSwgIi9hIWIiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG5ldyBVUkwoImphciIsIG51bGwsIC0xLCAiL2EhYiIpLmVxdWFscyhuZXcgVVJMKCJqYXIiLCBudWxsLCAtMSwgIi9hIUIiKSkpOworICAgICAgICBhc3NlcnRGYWxzZShuZXcgVVJMKCJqYXIiLCBudWxsLCAtMSwgIi9hIWIiKS5lcXVhbHMobmV3IFVSTCgiamFyIiwgbnVsbCwgLTEsICIvQSFiIikpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXJsU2VyaWFsaXphdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgcyA9ICJhY2VkMDAwNTczNzIwMDBjNmE2MTc2NjEyZTZlNjU3NDJlNTU1MjRjOTYyNTM3MzYxYWZjZTQ3MjAzMDAwNjQ5MDAwNDcwNmY3Mjc0NGMwIgorICAgICAgICAgICAgICAgICsgIjAwOTYxNzU3NDY4NmY3MjY5NzQ3OTc0MDAxMjRjNmE2MTc2NjEyZjZjNjE2ZTY3MmY1Mzc0NzI2OTZlNjczYjRjMDAwNDY2Njk2YzY1NzEwIgorICAgICAgICAgICAgICAgICsgIjA3ZTAwMDE0YzAwMDQ2ODZmNzM3NDcxMDA3ZTAwMDE0YzAwMDg3MDcyNmY3NDZmNjM2ZjZjNzEwMDdlMDAwMTRjMDAwMzcyNjU2NjcxMDA3IgorICAgICAgICAgICAgICAgICsgImUwMDAxNzg3MGZmZmZmZmZmNzQwMDBlNzU3MzY1NzIzYTcwNjE3MzczNDA2ODZmNzM3NDc0MDAxMDJmNzA2MTc0NjgyZjY2Njk2YzY1M2Y3IgorICAgICAgICAgICAgICAgICsgIjE3NTY1NzI3OTc0MDAwNDY4NmY3Mzc0NzQwMDA0Njg3NDc0NzA3NDAwMDQ2ODYxNzM2ODc4IjsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6Ly91c2VyOnBhc3NAaG9zdC9wYXRoL2ZpbGU/cXVlcnkjaGFzaCIpOworICAgICAgICBuZXcgU2VyaWFsaXphYmxlVGVzdGVyPFVSTD4odXJsLCBzKS50ZXN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIHNlcmlhbGl6ZWQgZm9ybSBvZiBhIFVSTCBpbmNsdWRlcyBpdHMgaGFzaCBjb2RlLiBCdXQgdGhlIGhhc2ggY29kZQorICAgICAqIGlzIG5vdCBkb2N1bWVudGVkLiBDaGVjayB0aGF0IHdlIGRvbid0IHJldHVybiBhIGRlc2VyaWFsaXplZCBoYXNoIGNvZGUKKyAgICAgKiBmcm9tIGEgZGVzZXJpYWxpemVkIHZhbHVlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVcmxTZXJpYWxpemF0aW9uV2l0aEhhc2hDb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzID0gImFjZWQwMDA1NzM3MjAwMGM2YTYxNzY2MTJlNmU2NTc0MmU1NTUyNGM5NjI1MzczNjFhZmNlNDcyMDMwMDA3NDkwMDA4Njg2MTczNjg0MzYiCisgICAgICAgICAgICAgICAgKyAiZjY0NjU0OTAwMDQ3MDZmNzI3NDRjMDAwOTYxNzU3NDY4NmY3MjY5NzQ3OTc0MDAxMjRjNmE2MTc2NjEyZjZjNjE2ZTY3MmY1Mzc0NzI2OTYiCisgICAgICAgICAgICAgICAgKyAiZTY3M2I0YzAwMDQ2NjY5NmM2NTcxMDA3ZTAwMDE0YzAwMDQ2ODZmNzM3NDcxMDA3ZTAwMDE0YzAwMDg3MDcyNmY3NDZmNjM2ZjZjNzEwMDciCisgICAgICAgICAgICAgICAgKyAiZTAwMDE0YzAwMDM3MjY1NjY3MTAwN2UwMDAxNzg3MGNkZjBlZmFjZmZmZmZmZmY3NDAwMGU3NTczNjU3MjNhNzA2MTczNzM0MDY4NmY3MzciCisgICAgICAgICAgICAgICAgKyAiNDc0MDAxMDJmNzA2MTc0NjgyZjY2Njk2YzY1M2Y3MTc1NjU3Mjc5NzQwMDA0Njg2ZjczNzQ3NDAwMDQ2ODc0NzQ3MDc0MDAwNDY4NjE3MzYiCisgICAgICAgICAgICAgICAgKyAiODc4IjsKKyAgICAgICAgZmluYWwgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6Ly91c2VyOnBhc3NAaG9zdC9wYXRoL2ZpbGU/cXVlcnkjaGFzaCIpOworICAgICAgICBuZXcgU2VyaWFsaXphYmxlVGVzdGVyPFVSTD4odXJsLCBzKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgdmVyaWZ5KFVSTCBkZXNlcmlhbGl6ZWQpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHModXJsLmhhc2hDb2RlKCksIGRlc2VyaWFsaXplZC5oYXNoQ29kZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfS50ZXN0KCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE9ubHlTdXBwb3J0ZWRQcm90b2NvbHMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVVJMKCJhYmNkOi8vaG9zdCIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RPbWl0dGVkSG9zdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovLy9wYXRoIik7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgdXJsLmdldEhvc3QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL3BhdGgiLCB1cmwuZ2V0RmlsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvcGF0aCIsIHVybC5nZXRQYXRoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROb0hvc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6L3BhdGgiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwIiwgdXJsLmdldFByb3RvY29sKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgdXJsLmdldEF1dGhvcml0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVybC5nZXRVc2VySW5mbygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB1cmwuZ2V0SG9zdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCB1cmwuZ2V0UG9ydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDgwLCB1cmwuZ2V0RGVmYXVsdFBvcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL3BhdGgiLCB1cmwuZ2V0RmlsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvcGF0aCIsIHVybC5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgdXJsLmdldFF1ZXJ5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgdXJsLmdldFJlZigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9QYXRoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vaG9zdCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImhvc3QiLCB1cmwuZ2V0SG9zdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB1cmwuZ2V0RmlsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB1cmwuZ2V0UGF0aCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW1wdHlIb3N0QW5kTm9QYXRoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cCIsIHVybC5nZXRQcm90b2NvbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB1cmwuZ2V0QXV0aG9yaXR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgdXJsLmdldFVzZXJJbmZvKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHVybC5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIHVybC5nZXRQb3J0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoODAsIHVybC5nZXREZWZhdWx0UG9ydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB1cmwuZ2V0RmlsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB1cmwuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVybC5nZXRRdWVyeSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVybC5nZXRSZWYoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vSG9zdEFuZE5vUGF0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDoiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwIiwgdXJsLmdldFByb3RvY29sKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgdXJsLmdldEF1dGhvcml0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVybC5nZXRVc2VySW5mbygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB1cmwuZ2V0SG9zdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCB1cmwuZ2V0UG9ydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDgwLCB1cmwuZ2V0RGVmYXVsdFBvcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgdXJsLmdldEZpbGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgdXJsLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCB1cmwuZ2V0UXVlcnkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCB1cmwuZ2V0UmVmKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdFNpZ25JblVzZXJJbmZvKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVVJMKCJodHRwOi8vdXNlckB1c2VyaG9zdC5jb206cGFzc3dvcmRAaG9zdCIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVc2VyTm9QYXNzd29yZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovL3VzZXJAaG9zdCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInVzZXJAaG9zdCIsIHVybC5nZXRBdXRob3JpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidXNlciIsIHVybC5nZXRVc2VySW5mbygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJob3N0IiwgdXJsLmdldEhvc3QoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFVzZXJOb1Bhc3N3b3JkRXhwbGljaXRQb3J0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vdXNlckBob3N0OjgwODAiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1c2VyQGhvc3Q6ODA4MCIsIHVybC5nZXRBdXRob3JpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidXNlciIsIHVybC5nZXRVc2VySW5mbygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJob3N0IiwgdXJsLmdldEhvc3QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg4MDgwLCB1cmwuZ2V0UG9ydCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXNlclBhc3N3b3JkSG9zdFBvcnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6Ly91c2VyOnBhc3N3b3JkQGhvc3Q6ODA4MCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInVzZXI6cGFzc3dvcmRAaG9zdDo4MDgwIiwgdXJsLmdldEF1dGhvcml0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1c2VyOnBhc3N3b3JkIiwgdXJsLmdldFVzZXJJbmZvKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImhvc3QiLCB1cmwuZ2V0SG9zdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDgwODAsIHVybC5nZXRQb3J0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVc2VyUGFzc3dvcmRFbXB0eUhvc3RQb3J0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vdXNlcjpwYXNzd29yZEA6ODA4MCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInVzZXI6cGFzc3dvcmRAOjgwODAiLCB1cmwuZ2V0QXV0aG9yaXR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInVzZXI6cGFzc3dvcmQiLCB1cmwuZ2V0VXNlckluZm8oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgdXJsLmdldEhvc3QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg4MDgwLCB1cmwuZ2V0UG9ydCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXNlclBhc3N3b3JkRW1wdHlIb3N0RW1wdHlQb3J0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vdXNlcjpwYXNzd29yZEAiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1c2VyOnBhc3N3b3JkQCIsIHVybC5nZXRBdXRob3JpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidXNlcjpwYXNzd29yZCIsIHVybC5nZXRVc2VySW5mbygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB1cmwuZ2V0SG9zdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCB1cmwuZ2V0UG9ydCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGF0aE9ubHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6Ly9ob3N0L3BhdGgiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvcGF0aCIsIHVybC5nZXRGaWxlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9wYXRoIiwgdXJsLmdldFBhdGgoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFF1ZXJ5T25seSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovL2hvc3Q/cXVlcnkiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI/cXVlcnkiLCB1cmwuZ2V0RmlsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB1cmwuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJxdWVyeSIsIHVybC5nZXRRdWVyeSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RnJhZ21lbnRPbmx5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vaG9zdCNmcmFnbWVudCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHVybC5nZXRGaWxlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHVybC5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZyYWdtZW50IiwgdXJsLmdldFJlZigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXRTaWduSW5QYXRoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vaG9zdC9maWxlQGZvbyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9maWxlQGZvbyIsIHVybC5nZXRGaWxlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9maWxlQGZvbyIsIHVybC5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgdXJsLmdldFVzZXJJbmZvKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb2xvbkluUGF0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovL2hvc3QvZmlsZTpjb2xvbiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9maWxlOmNvbG9uIiwgdXJsLmdldEZpbGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL2ZpbGU6Y29sb24iLCB1cmwuZ2V0UGF0aCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2xhc2hJblF1ZXJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vaG9zdC9maWxlP3F1ZXJ5L3BhdGgiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZmlsZT9xdWVyeS9wYXRoIiwgdXJsLmdldEZpbGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL2ZpbGUiLCB1cmwuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJxdWVyeS9wYXRoIiwgdXJsLmdldFF1ZXJ5KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RRdWVzdGlvbk1hcmtJblF1ZXJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vaG9zdC9maWxlP3F1ZXJ5P2Fub3RoZXIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZmlsZT9xdWVyeT9hbm90aGVyIiwgdXJsLmdldEZpbGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL2ZpbGUiLCB1cmwuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJxdWVyeT9hbm90aGVyIiwgdXJsLmdldFF1ZXJ5KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdFNpZ25JblF1ZXJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vaG9zdC9maWxlP3F1ZXJ5QGF0Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiL2ZpbGU/cXVlcnlAYXQiLCB1cmwuZ2V0RmlsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZmlsZSIsIHVybC5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInF1ZXJ5QGF0IiwgdXJsLmdldFF1ZXJ5KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb2xvbkluUXVlcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6Ly9ob3N0L2ZpbGU/cXVlcnk6Y29sb24iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZmlsZT9xdWVyeTpjb2xvbiIsIHVybC5nZXRGaWxlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9maWxlIiwgdXJsLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygicXVlcnk6Y29sb24iLCB1cmwuZ2V0UXVlcnkoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFF1ZXN0aW9uTWFya0luRnJhZ21lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6Ly9ob3N0L2ZpbGUjZnJhZ21lbnQ/cXVlcnkiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZmlsZSIsIHVybC5nZXRGaWxlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9maWxlIiwgdXJsLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCB1cmwuZ2V0UXVlcnkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZnJhZ21lbnQ/cXVlcnkiLCB1cmwuZ2V0UmVmKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb2xvbkluRnJhZ21lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6Ly9ob3N0L2ZpbGUjZnJhZ21lbnQ6ODAiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZmlsZSIsIHVybC5nZXRGaWxlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9maWxlIiwgdXJsLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgdXJsLmdldFBvcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZnJhZ21lbnQ6ODAiLCB1cmwuZ2V0UmVmKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTbGFzaEluRnJhZ21lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6Ly9ob3N0L2ZpbGUjZnJhZ21lbnQvcGF0aCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9maWxlIiwgdXJsLmdldEZpbGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL2ZpbGUiLCB1cmwuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmcmFnbWVudC9wYXRoIiwgdXJsLmdldFJlZigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2xhc2hJbkZyYWdtZW50Q29tYmluaW5nQ29uc3RydWN0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHAiLCAiaG9zdCIsICIvZmlsZSNmcmFnbWVudC9wYXRoIik7CisgICAgICAgIGFzc2VydEVxdWFscygiL2ZpbGUiLCB1cmwuZ2V0RmlsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZmlsZSIsIHVybC5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZyYWdtZW50L3BhdGgiLCB1cmwuZ2V0UmVmKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RIYXNoSW5GcmFnbWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovL2hvc3QvZmlsZSNmcmFnbWVudCNhbm90aGVyIik7CisgICAgICAgIGFzc2VydEVxdWFscygiL2ZpbGUiLCB1cmwuZ2V0RmlsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZmlsZSIsIHVybC5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZyYWdtZW50I2Fub3RoZXIiLCB1cmwuZ2V0UmVmKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eVBvcnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6Ly9ob3N0Oi8iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCB1cmwuZ2V0UG9ydCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9uTnVtZXJpY1BvcnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBVUkwoImh0dHA6Ly9ob3N0OngvIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5lZ2F0aXZlUG9ydCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFVSTCgiaHR0cDovL2hvc3Q6LTIvIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5lZ2F0aXZlUG9ydEVxdWFsc1BsYWNlaG9sZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVVJMKCJodHRwOi8vaG9zdDotMS8iKTsKKyAgICAgICAgICAgIGZhaWwoKTsgLy8gUkkgZmFpbHMgdGhpcworICAgICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWxhdGl2ZVBhdGhPblF1ZXJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCBiYXNlID0gbmV3IFVSTCgiaHR0cDovL2hvc3QvZmlsZT9xdWVyeS94Iik7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKGJhc2UsICJhbm90aGVyIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2hvc3QvYW5vdGhlciIsIHVybC50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvYW5vdGhlciIsIHVybC5nZXRGaWxlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9hbm90aGVyIiwgdXJsLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCB1cmwuZ2V0UXVlcnkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCB1cmwuZ2V0UmVmKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWxhdGl2ZUZyYWdtZW50T25RdWVyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgYmFzZSA9IG5ldyBVUkwoImh0dHA6Ly9ob3N0L2ZpbGU/cXVlcnkveCNmcmFnbWVudCIpOworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTChiYXNlLCAiI2Fub3RoZXIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vaG9zdC9maWxlP3F1ZXJ5L3gjYW5vdGhlciIsIHVybC50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZmlsZT9xdWVyeS94IiwgdXJsLmdldEZpbGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL2ZpbGUiLCB1cmwuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJxdWVyeS94IiwgdXJsLmdldFF1ZXJ5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFub3RoZXIiLCB1cmwuZ2V0UmVmKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXRoQ29udGFpbnNSZWxhdGl2ZVBhcnRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vaG9zdC9hL2IvLi4vYyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9ob3N0L2EvYyIsIHVybC50b1N0cmluZygpKTsgLy8gUkkgZG9lc24ndCBjYW5vbmljYWxpemUKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVsYXRpdmVQYXRoQW5kRnJhZ21lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIGJhc2UgPSBuZXcgVVJMKCJodHRwOi8vaG9zdC9maWxlIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2hvc3QvYW5vdGhlciNmcmFnbWVudCIsIG5ldyBVUkwoYmFzZSwgImFub3RoZXIjZnJhZ21lbnQiKS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVsYXRpdmVQYXJlbnREaXJlY3RvcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIGJhc2UgPSBuZXcgVVJMKCJodHRwOi8vaG9zdC9hL2IvYyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9ob3N0L2EvZCIsIG5ldyBVUkwoYmFzZSwgIi4uL2QiKS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVsYXRpdmVDaGlsZERpcmVjdG9yeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgYmFzZSA9IG5ldyBVUkwoImh0dHA6Ly9ob3N0L2EvYi9jIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2hvc3QvYS9iL2QvZSIsIG5ldyBVUkwoYmFzZSwgImQvZSIpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWxhdGl2ZVJvb3REaXJlY3RvcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIGJhc2UgPSBuZXcgVVJMKCJodHRwOi8vaG9zdC9hL2IvYyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9ob3N0L2QiLCBuZXcgVVJMKGJhc2UsICIvZCIpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWxhdGl2ZUZ1bGxVcmwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIGJhc2UgPSBuZXcgVVJMKCJodHRwOi8vaG9zdC9hL2IvYyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9ob3N0Mi9kL2UiLCBuZXcgVVJMKGJhc2UsICJodHRwOi8vaG9zdDIvZC9lIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cHM6Ly9ob3N0Mi9kL2UiLCBuZXcgVVJMKGJhc2UsICJodHRwczovL2hvc3QyL2QvZSIpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWxhdGl2ZURpZmZlcmVudFNjaGVtZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgYmFzZSA9IG5ldyBVUkwoImh0dHA6Ly9ob3N0L2EvYi9jIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cHM6Ly9ob3N0Mi9kL2UiLCBuZXcgVVJMKGJhc2UsICJodHRwczovL2hvc3QyL2QvZSIpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWxhdGl2ZURpZmZlcmVudEF1dGhvcml0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgYmFzZSA9IG5ldyBVUkwoImh0dHA6Ly9ob3N0L2EvYi9jIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2Fub3RoZXIvZC9lIiwgbmV3IFVSTChiYXNlLCAiLy9hbm90aGVyL2QvZSIpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWxhdGl2ZVdpdGhTY2hlbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIGJhc2UgPSBuZXcgVVJMKCJodHRwOi8vaG9zdC9hL2IvYyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9ob3N0L2EvYi9jIiwgbmV3IFVSTChiYXNlLCAiaHR0cDoiKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vaG9zdC8iLCBuZXcgVVJMKGJhc2UsICJodHRwOi8iKS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFsZm9ybWVkVXJsc1JlZnVzZWRCeUZpcmVmb3hBbmRDaHJvbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIGJhc2UgPSBuZXcgVVJMKCJodHRwOi8vaG9zdC9hL2IvYyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly8iLCBuZXcgVVJMKGJhc2UsICJodHRwOi8vIikudG9TdHJpbmcoKSk7IC8vIGZhaWxzIG9uIFJJOyBwYXRoIHJldGFpbmVkCisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovLyIsIG5ldyBVUkwoYmFzZSwgIi8vIikudG9TdHJpbmcoKSk7IC8vIGZhaWxzIG9uIFJJCisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cHM6IiwgbmV3IFVSTChiYXNlLCAiaHR0cHM6IikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cHM6LyIsIG5ldyBVUkwoYmFzZSwgImh0dHBzOi8iKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwczovLyIsIG5ldyBVUkwoYmFzZSwgImh0dHBzOi8vIikudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJmYzE4MDhOb3JtYWxFeGFtcGxlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgYmFzZSA9IG5ldyBVUkwoImh0dHA6Ly9hL2IvYy9kO3A/cSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHBzOmgiLCBuZXcgVVJMKGJhc2UsICJodHRwczpoIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2ciLCBuZXcgVVJMKGJhc2UsICJnIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2ciLCBuZXcgVVJMKGJhc2UsICIuL2ciKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2MvZy8iLCBuZXcgVVJMKGJhc2UsICJnLyIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2ciLCBuZXcgVVJMKGJhc2UsICIvZyIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9nIiwgbmV3IFVSTChiYXNlLCAiLy9nIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2Q7cD95IiwgbmV3IFVSTChiYXNlLCAiP3kiKS50b1N0cmluZygpKTsgLy8gUkkgZmFpbHM7IGZpbGUgbG9zdAorICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy9nP3kiLCBuZXcgVVJMKGJhc2UsICJnP3kiKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2MvZDtwP3EjcyIsIG5ldyBVUkwoYmFzZSwgIiNzIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2cjcyIsIG5ldyBVUkwoYmFzZSwgImcjcyIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy9nP3kjcyIsIG5ldyBVUkwoYmFzZSwgImc/eSNzIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jLzt4IiwgbmV3IFVSTChiYXNlLCAiO3giKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2MvZzt4IiwgbmV3IFVSTChiYXNlLCAiZzt4IikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2c7eD95I3MiLCBuZXcgVVJMKGJhc2UsICJnO3g/eSNzIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2Q7cD9xIiwgbmV3IFVSTChiYXNlLCAiIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jLyIsIG5ldyBVUkwoYmFzZSwgIi4iKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2MvIiwgbmV3IFVSTChiYXNlLCAiLi8iKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iLyIsIG5ldyBVUkwoYmFzZSwgIi4uIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi8iLCBuZXcgVVJMKGJhc2UsICIuLi8iKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2ciLCBuZXcgVVJMKGJhc2UsICIuLi9nIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvIiwgbmV3IFVSTChiYXNlLCAiLi4vLi4iKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS8iLCBuZXcgVVJMKGJhc2UsICIuLi8uLi8iKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9nIiwgbmV3IFVSTChiYXNlLCAiLi4vLi4vZyIpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZmMxODA4QWJub3JtYWxFeGFtcGxlVG9vTWFueURvdERvdFNlcXVlbmNlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgYmFzZSA9IG5ldyBVUkwoImh0dHA6Ly9hL2IvYy9kO3A/cSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2ciLCBuZXcgVVJMKGJhc2UsICIuLi8uLi8uLi9nIikudG9TdHJpbmcoKSk7IC8vIFJJIGRvZXNuJ3Qgbm9ybWFsaXplCisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvZyIsIG5ldyBVUkwoYmFzZSwgIi4uLy4uLy4uLy4uL2ciKS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmZjMTgwOEFibm9ybWFsRXhhbXBsZVJlbW92ZURvdFNlZ21lbnRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCBiYXNlID0gbmV3IFVSTCgiaHR0cDovL2EvYi9jL2Q7cD9xIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvZyIsIG5ldyBVUkwoYmFzZSwgIi8uL2ciKS50b1N0cmluZygpKTsgLy8gUkkgZG9lc24ndCBub3JtYWxpemUKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9nIiwgbmV3IFVSTChiYXNlLCAiLy4uL2ciKS50b1N0cmluZygpKTsgLy8gUkkgZG9lc24ndCBub3JtYWxpemUKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2MvZy4iLCBuZXcgVVJMKGJhc2UsICJnLiIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy8uZyIsIG5ldyBVUkwoYmFzZSwgIi5nIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2cuLiIsIG5ldyBVUkwoYmFzZSwgImcuLiIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy8uLmciLCBuZXcgVVJMKGJhc2UsICIuLmciKS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmZjMTgwOEFibm9ybWFsRXhhbXBsZU5vbnNlbnNpY2FsRG90cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgYmFzZSA9IG5ldyBVUkwoImh0dHA6Ly9hL2IvYy9kO3A/cSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvZyIsIG5ldyBVUkwoYmFzZSwgIi4vLi4vZyIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy9nLyIsIG5ldyBVUkwoYmFzZSwgIi4vZy8uIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2cvaCIsIG5ldyBVUkwoYmFzZSwgImcvLi9oIikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2giLCBuZXcgVVJMKGJhc2UsICJnLy4uL2giKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2MvZzt4PTEveSIsIG5ldyBVUkwoYmFzZSwgImc7eD0xLy4veSIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy95IiwgbmV3IFVSTChiYXNlLCAiZzt4PTEvLi4veSIpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZmMxODA4QWJub3JtYWxFeGFtcGxlUmVsYXRpdmVTY2hlbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIGJhc2UgPSBuZXcgVVJMKCJodHRwOi8vYS9iL2MvZDtwP3EiKTsKKyAgICAgICAgLy8gdGhpcyByZXN1bHQgaXMgcGVybWl0dGVkOyBzdHJpY3QgcGFyc2VycyBwcmVmZXIgImh0dHA6ZyIKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYS9iL2MvZyIsIG5ldyBVUkwoYmFzZSwgImh0dHA6ZyIpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZmMxODA4QWJub3JtYWxFeGFtcGxlUXVlcnlPckZyYWdtZW50RG90cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgYmFzZSA9IG5ldyBVUkwoImh0dHA6Ly9hL2IvYy9kO3A/cSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy9nP3kvLi94IiwgbmV3IFVSTChiYXNlLCAiZz95Ly4veCIpLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hL2IvYy9nP3kvLi4veCIsIG5ldyBVUkwoYmFzZSwgImc/eS8uLi94IikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2cjcy8uL3giLCBuZXcgVVJMKGJhc2UsICJnI3MvLi94IikudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2EvYi9jL2cjcy8uLi94IiwgbmV3IFVSTChiYXNlLCAiZyNzLy4uL3giKS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3F1YXJlQnJhY2tldHNJblVzZXJJbmZvKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vdXNlcjpbOjoxXUBob3N0Iik7CisgICAgICAgIGFzc2VydEVxdWFscygidXNlcjpbOjoxXSIsIHVybC5nZXRVc2VySW5mbygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJob3N0IiwgdXJsLmdldEhvc3QoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbXBvc2VVcmwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHAiLCAiaG9zdCIsICJhIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cCIsIHVybC5nZXRQcm90b2NvbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJob3N0IiwgdXJsLmdldEF1dGhvcml0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJob3N0IiwgdXJsLmdldEhvc3QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL2EiLCB1cmwuZ2V0RmlsZSgpKTsgLy8gUkkgZmFpbHM7IGRvZXNuJ3QgaW5zZXJ0ICcvJyBzZXBhcmF0b3IKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vaG9zdC9hIiwgdXJsLnRvU3RyaW5nKCkpOyAvLyBmYWlscyBvbiBSSQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb21wb3NlVXJsV2l0aE51bGxIb3N0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwIiwgbnVsbCwgImEiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwIiwgdXJsLmdldFByb3RvY29sKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgdXJsLmdldEF1dGhvcml0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHVybC5nZXRIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCB1cmwuZ2V0RmlsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOmEiLCB1cmwudG9TdHJpbmcoKSk7IC8vIGZhaWxzIG9uIFJJCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZpbGVVcmxFeHRyYUxlYWRpbmdTbGFzaGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJmaWxlOi8vLy9mb28iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB1cmwuZ2V0QXV0aG9yaXR5KCkpOyAvLyBSSSByZXR1cm5zIG51bGwKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvL2ZvbyIsIHVybC5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZpbGU6Ly8vL2ZvbyIsIHVybC50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmlsZVVybFdpdGhBdXRob3JpdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImZpbGU6Ly94L2ZvbyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIngiLCB1cmwuZ2V0QXV0aG9yaXR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9mb28iLCB1cmwuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmaWxlOi8veC9mb28iLCB1cmwudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIFJJIGlzIG5vdCBzZWxmLWNvbnNpc3RlbnQgb24gbWlzc2luZyBhdXRob3JpdGllcywgcmV0dXJuaW5nIGVpdGhlcgorICAgICAqIG51bGwgb3IgdGhlIGVtcHR5IHN0cmluZyBkZXBlbmRpbmcgb24gdGhlIG51bWJlciBvZiBzbGFzaGVzIGluIHRoZSBwYXRoLgorICAgICAqIFdlIGFsd2F5cyB0cmVhdCAnLy8nIGFzIHRoZSBiZWdpbm5pbmcgb2YgYW4gYXV0aG9yaXR5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eUF1dGhvcml0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovLy9mb28iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB1cmwuZ2V0QXV0aG9yaXR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9mb28iLCB1cmwuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vL2ZvbyIsIHVybC50b1N0cmluZygpKTsgLy8gUkkgZHJvcHMgJy8vJworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RIdHRwVXJsRXh0cmFMZWFkaW5nU2xhc2hlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovLy8vZm9vIik7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgdXJsLmdldEF1dGhvcml0eSgpKTsgLy8gUkkgcmV0dXJucyBudWxsCisgICAgICAgIGFzc2VydEVxdWFscygiLy9mb28iLCB1cmwuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vLy9mb28iLCB1cmwudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZpbGVVcmxSZWxhdGl2ZVBhdGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIGJhc2UgPSBuZXcgVVJMKCJmaWxlOmEvYi9jIik7CisgICAgICAgIGFzc2VydEVxdWFscygiZmlsZTphL2IvZCIsIG5ldyBVUkwoYmFzZSwgImQiKS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmlsZVVybERvdHRlZFBhdGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImZpbGU6Li4vYS9iIik7CisgICAgICAgIGFzc2VydEVxdWFscygiLi4vYS9iIiwgdXJsLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZmlsZTouLi9hL2IiLCB1cmwudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNpbmdEb3RBc0hvc3RuYW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vLi8iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIuIiwgdXJsLmdldEF1dGhvcml0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIuIiwgdXJsLmdldEhvc3QoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNxdWFyZUJyYWNrZXRzV2l0aElQdjQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBVUkwoImh0dHA6Ly9bMTkyLjE2OC4wLjFdLyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cCIsICJbMTkyLjE2OC4wLjFdIiwgIi8iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbMTkyLjE2OC4wLjFdIiwgdXJsLmdldEhvc3QoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNxdWFyZUJyYWNrZXRzV2l0aEhvc3RuYW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVVJMKCJodHRwOi8vW3d3dy5hbmRyb2lkLmNvbV0vIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwIiwgIlt3d3cuYW5kcm9pZC5jb21dIiwgIi8iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbd3d3LmFuZHJvaWQuY29tXSIsIHVybC5nZXRIb3N0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJUHY2V2l0aG91dFNxdWFyZUJyYWNrZXRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVVJMKCJodHRwOi8vZmU4MDo6MTIzNC8iKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHAiLCAiZmU4MDo6MTIzNCIsICIvIik7CisgICAgICAgIGFzc2VydEVxdWFscygiW2ZlODA6OjEyMzRdIiwgdXJsLmdldEhvc3QoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdElwdjZXaXRoU3F1YXJlQnJhY2tldHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6Ly9bOjoxXToyLyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIls6OjFdIiwgdXJsLmdldEhvc3QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCB1cmwuZ2V0UG9ydCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXF1YWxpdHlXaXRoTm9QYXRoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG5ldyBVUkwoImh0dHA6Ly9hbmRyb2lkLmNvbSIpLmVxdWFscyhuZXcgVVJMKCJodHRwOi8vYW5kcm9pZC5jb20vIikpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXJsRG9lc05vdEVuY29kZVBhcnRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwIiwgImhvc3QiLCA4MCwgIi9kb2N8c2VhcmNoP3E9Z3JlZW4gcm9ib3RzI292ZXIgNlwiIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cCIsIHVybC5nZXRQcm90b2NvbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJob3N0OjgwIiwgdXJsLmdldEF1dGhvcml0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvZG9jfHNlYXJjaCIsIHVybC5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInE9Z3JlZW4gcm9ib3RzIiwgdXJsLmdldFF1ZXJ5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm92ZXIgNlwiIiwgdXJsLmdldFJlZigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vaG9zdDo4MC9kb2N8c2VhcmNoP3E9Z3JlZW4gcm9ib3RzI292ZXIgNlwiIiwgdXJsLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTY2hlbWVDYXNlSXNDYW5vbmljYWxpemVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJIVFRQOi8vaG9zdC9wYXRoIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cCIsIHVybC5nZXRQcm90b2NvbCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW1wdHlBdXRob3JpdHlXaXRoUGF0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovLy9wYXRoIik7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgdXJsLmdldEF1dGhvcml0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvcGF0aCIsIHVybC5nZXRQYXRoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eUF1dGhvcml0eVdpdGhRdWVyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovLz9xdWVyeSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHVybC5nZXRBdXRob3JpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgdXJsLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygicXVlcnkiLCB1cmwuZ2V0UXVlcnkoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVtcHR5QXV0aG9yaXR5V2l0aEZyYWdtZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vI2ZyYWdtZW50Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgdXJsLmdldEF1dGhvcml0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB1cmwuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmcmFnbWVudCIsIHVybC5nZXRSZWYoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbWJpbmluZ0NvbnN0cnVjdG9yc01ha2VSZWxhdGl2ZVBhdGhzQWJzb2x1dGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvcmVsYXRpdmUiLCBuZXcgVVJMKCJodHRwIiwgImhvc3QiLCAicmVsYXRpdmUiKS5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9yZWxhdGl2ZSIsIG5ldyBVUkwoImh0dHAiLCAiaG9zdCIsIC0xLCAicmVsYXRpdmUiKS5nZXRQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9yZWxhdGl2ZSIsIG5ldyBVUkwoImh0dHAiLCAiaG9zdCIsIC0xLCAicmVsYXRpdmUiLCBudWxsKS5nZXRQYXRoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb21iaW5pbmdDb25zdHJ1Y3RvcnNEb05vdE1ha2VFbXB0eVBhdGhzQWJzb2x1dGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBuZXcgVVJMKCJodHRwIiwgImhvc3QiLCAiIikuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBuZXcgVVJMKCJodHRwIiwgImhvc3QiLCAtMSwgIiIpLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgbmV3IFVSTCgiaHR0cCIsICJob3N0IiwgLTEsICIiLCBudWxsKS5nZXRQYXRoKCkpOworICAgIH0KKworICAgIC8vIEFkZGluZyBhIG5ldyB0ZXN0PyBDb25zaWRlciBhZGRpbmcgYW4gZXF1aXZhbGVudCB0ZXN0IHRvIFVSSVRlc3QuamF2YQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvVXJsRW5jb2RpbmdUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25ldC9VcmxFbmNvZGluZ1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MzE4ODM2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvVXJsRW5jb2RpbmdUZXN0LmphdmEKQEAgLTAsMCArMSwyNjMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJJOworaW1wb3J0IGphdmEubmV0LlVSSVN5bnRheEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkxEZWNvZGVyOworaW1wb3J0IGphdmEubmV0LlVSTEVuY29kZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5JbGxlZ2FsQ2hhcnNldE5hbWVFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5VbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgVXJsRW5jb2RpbmdUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdFVyaVJldGFpbnNPcmlnaW5hbEVuY29kaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiJTYxIiwgbmV3IFVSSSgiaHR0cDovL2ZvbyMlNjEiKS5nZXRSYXdGcmFnbWVudCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVUkxEZWNvZGVyIGFuZCBVUkkgZGlzYWdyZWUgb24gd2hhdCAnKycgc2hvdWxkIGRlY29kZSB0by4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVjb2RpbmdQbHVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiYSBiIiwgVVJMRGVjb2Rlci5kZWNvZGUoImErYiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIGIiLCBVUkxEZWNvZGVyLmRlY29kZSgiYStiIiwgIlVURi04IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImErYiIsIG5ldyBVUkkoImh0dHA6Ly9mb28jYStiIikuZ2V0RnJhZ21lbnQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVuY29kaW5nUGx1cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoImElMkJiIiwgVVJMRW5jb2Rlci5lbmNvZGUoImErYiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhJTJCYiIsIFVSTEVuY29kZXIuZW5jb2RlKCJhK2IiLCAiVVRGLTgiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYStiIiwgbmV3IFVSSSgiaHR0cCIsICJmb28iLCAiLyIsICJhK2IiKS5nZXRSYXdGcmFnbWVudCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVjb2RpbmdTcGFjZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoImEgYiIsIFVSTERlY29kZXIuZGVjb2RlKCJhIGIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSBiIiwgVVJMRGVjb2Rlci5kZWNvZGUoImEgYiIsICJVVEYtOCIpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBVUkkoImh0dHA6Ly9mb28jYSBiIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFVSSVN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVuY29kaW5nU3BhY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhK2IiLCBVUkxFbmNvZGVyLmVuY29kZSgiYSBiIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImErYiIsIFVSTEVuY29kZXIuZW5jb2RlKCJhIGIiLCAiVVRGLTgiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSUyMGIiLCBuZXcgVVJJKCJodHRwIiwgImZvbyIsICIvIiwgImEgYiIpLmdldFJhd0ZyYWdtZW50KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVcmlEZWNvZGluZ1BhcnRpYWwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBVUkkoImh0dHA6Ly9mb28jJSIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChVUklTeW50YXhFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFVSSSgiaHR0cDovL2ZvbyMlMCIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChVUklTeW50YXhFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVcmxEZWNvZGVyRGVjb2RpbmdQYXJ0aWFsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkxEZWNvZGVyLmRlY29kZSgiJSIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgVVJMRGVjb2Rlci5kZWNvZGUoIiUwIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFVyaURlY29kaW5nSW52YWxpZCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBVUkkoImh0dHA6Ly9mb28jJTBnIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFVSSVN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFVybERlY29kZXJEZWNvZGluZ0ludmFsaWQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkxEZWNvZGVyLmRlY29kZSgiJTBnIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFVybERlY29kZXJGYWlsc09uTnVsbENoYXJzZXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFVSTERlY29kZXIuZGVjb2RlKCJhYiIsIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQ2hhcnNldE5hbWVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVcmxEZWNvZGVyRmFpbHNPbkVtcHR5Q2hhcnNldCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFVSTERlY29kZXIuZGVjb2RlKCJhYiIsICIiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbENoYXJzZXROYW1lRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVcmxFbmNvZGVyRmFpbHNPbk51bGxDaGFyc2V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkxFbmNvZGVyLmVuY29kZSgiYWIiLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbENoYXJzZXROYW1lRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXJsRW5jb2RlckZhaWxzT25FbXB0eUNoYXJzZXQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkxFbmNvZGVyLmVuY29kZSgiYWIiLCAiIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxDaGFyc2V0TmFtZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgUkkgbG9va3MgdXAgdGhlIGNoYXJzZXQgbGF6aWx5OyBBbmRyb2lkIGxvb2tzIGl0IHVwIGVhZ2VybHkuIEVpdGhlcgorICAgICAqIGJlaGF2aW9yIGlzIGFjY2VwdGFibGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVybERlY29kZXJJZ25vcmVzVW5uZWNlc3NhcnlDaGFyc2V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImFiIiwgVVJMRGVjb2Rlci5kZWNvZGUoImFiIiwgIm5vLXN1Y2gtY2hhcnNldCIpKTsKKyAgICAgICAgICAgIC8vIG5vIGZhaWwoKQorICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVcmxFbmNvZGVyRmFpbHNPbkludmFsaWRDaGFyc2V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkxFbmNvZGVyLmVuY29kZSgiYWIiLCAibm8tc3VjaC1jaGFyc2V0Iik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkQ2hhcnNldEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVjb2RpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RGVjb2RlZCgiYVx1MDAwMGIiLCAiYSUwMGIiKTsKKyAgICAgICAgYXNzZXJ0RGVjb2RlZCgiYSBiIiwgImElMjBiIik7CisgICAgICAgIGFzc2VydERlY29kZWQoImErYiIsICJhJTJiYiIpOworICAgICAgICBhc3NlcnREZWNvZGVkKCJhJWIiLCAiYSUyNWIiKTsKKyAgICAgICAgYXNzZXJ0RGVjb2RlZCgiYVx1MDA3ZmIiLCAiYSU3ZmIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5jb2RpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RW5jb2RlZCgiYSUyNWIiLCAiYSViIik7CisgICAgICAgIGFzc2VydEVuY29kZWQoImElN0ZiIiwgImFcdTAwN2ZiIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERlY29kaW5nTGl0ZXJhbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RGVjb2RlZCgiXHVkODQyXHVkZjlmIiwgIlx1ZDg0Mlx1ZGY5ZiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REZWNvZGluZ0Jyb2tlblV0ZjhTZXF1ZW5jZVlpZWxkc1JlcGxhY2VtZW50Q2hhcmFjdGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydERlY29kZWQoImFcdWZmZmRiIiwgImElZmZiIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERlY29kaW5nVXRmOE9jdGV0cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnREZWNvZGVkKCJcdTIwQUMiLCAiJWUyJTgyJWFjIik7CisgICAgICAgIGFzc2VydERlY29kZWQoIlx1ZDg0Mlx1ZGY5ZiIsICIlZjAlYTAlYWUlOWYiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVjb2RpbmdOb25Vc0RpZ2l0cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFVSSSgiaHR0cDovL2ZvbyMiICsgIiVcdTA2NjRcdTA2NjEiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoVVJJU3ludGF4RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFVSTERlY29kZXIuZGVjb2RlKCIlXHUwNjY0XHUwNjYxIik7CisgICAgICAgICAgICBmYWlsKCk7IC8vIFJJIGZhaWxzIHRoaXMgdGVzdCByZXR1cm5pbmcgIkEiCisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQW5kcm9pZCdzIFVSTEVuY29kZXIuZW5jb2RlKCkgZmFpbGVkIGZvciBzdXJyb2dhdGUgcGFpcnMsIGVuY29kaW5nIHRoZW0KKyAgICAgKiBhcyB0d28gcmVwbGFjZW1lbnQgY2hhcmFjdGVycyAoIj8/IikuIGh0dHA6Ly9iLzM0MzYwNTEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXJsRW5jb2RlckVuY29kZXNOb25QcmludGFibGVOb25Bc2NpaUNoYXJhY3RlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIlMDAiLCBVUkxFbmNvZGVyLmVuY29kZSgiXHUwMDAwIiwgIlVURi04IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiUwMCIsIFVSTEVuY29kZXIuZW5jb2RlKCJcdTAwMDAiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiJUUyJTgyJUFDIiwgVVJMRW5jb2Rlci5lbmNvZGUoIlx1MjBBQyIsICJVVEYtOCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIlRTIlODIlQUMiLCBVUkxFbmNvZGVyLmVuY29kZSgiXHUyMEFDIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiVGMCVBMCVBRSU5RiIsIFVSTEVuY29kZXIuZW5jb2RlKCJcdWQ4NDJcdWRmOWYiLCAiVVRGLTgiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiJUYwJUEwJUFFJTlGIiwgVVJMRW5jb2Rlci5lbmNvZGUoIlx1ZDg0Mlx1ZGY5ZiIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXJpRG9lc05vdEVuY29kZU5vblByaW50YWJsZU5vbkFzY2lpQ2hhcmFjdGVycygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoIlx1MjBBQyIsIG5ldyBVUkkoImh0dHAiLCAiZm9vIiwgIi8iLCAiXHUyMEFDIikuZ2V0UmF3RnJhZ21lbnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiXHVkODQyXHVkZjlmIiwgbmV3IFVSSSgiaHR0cCIsICJmb28iLCAiLyIsICJcdWQ4NDJcdWRmOWYiKS5nZXRSYXdGcmFnbWVudCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXJpRW5jb2Rlc0NvbnRyb2xDaGFyYWN0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiJTAxIiwgbmV3IFVSSSgiaHR0cCIsICJmb28iLCAiLyIsICJcdTAwMDEiKS5nZXRSYXdGcmFnbWVudCgpKTsKKworICAgICAgICAvLyBUaGUgUkkgZmFpbHMgdGhpcywgZW5jb2RpbmcgXHUwMDAxIGJ1dCBub3QgXHUwMDAwCisgICAgICAgIGFzc2VydEVxdWFscygiJTAwIiwgbmV3IFVSSSgiaHR0cCIsICJmb28iLCAiLyIsICJcdTAwMDAiKS5nZXRSYXdGcmFnbWVudCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5jb2RlQW5kRGVjb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFJvdW5kVHJpcCgiaHR0cDovL2pjbHRlc3QuYXBhY2hlLm9yZy90ZXN0P2hsPWVuJnE9dGUgc3QiLAorICAgICAgICAgICAgICAgICJodHRwJTNBJTJGJTJGamNsdGVzdC5hcGFjaGUub3JnJTJGdGVzdCUzRmhsJTNEZW4lMjZxJTNEdGUrc3QiKTsKKyAgICAgICAgYXNzZXJ0Um91bmRUcmlwICgiZmlsZTovL2EgYi9jL2QuZS1mKmdfIGwiLAorICAgICAgICAgICAgICAgICJmaWxlJTNBJTJGJTJGYStiJTJGYyUyRmQuZS1mKmdfK2wiKTsKKyAgICAgICAgYXNzZXJ0Um91bmRUcmlwKCJqYXI6ZmlsZTovL2EuamFyICEvYi5jL1x1MTA1MiIsCisgICAgICAgICAgICAgICAgImphciUzQWZpbGUlM0ElMkYlMkZhLmphcislMjElMkZiLmMlMkYlRTElODElOTIiKTsKKyAgICAgICAgYXNzZXJ0Um91bmRUcmlwKCJmdHA6Ly90ZXN0OnB3ZEBsb2NhbGhvc3Q6MjEyMS8lRDAlOUMiLAorICAgICAgICAgICAgICAgICJmdHAlM0ElMkYlMkZ0ZXN0JTNBcHdkJTQwbG9jYWxob3N0JTNBMjEyMSUyRiUyNUQwJTI1OUMiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBc3NlcnRzIHRoYXQge0Bjb2RlIG9yaWdpbmFsfSBkZWNvZGVzIHRvIHtAY29kZSBkZWNvZGVkfSB1c2luZyBib3RoIFVSSQorICAgICAqIGFuZCBVcmxEZWNvZGVyLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhc3NlcnREZWNvZGVkKFN0cmluZyBkZWNvZGVkLCBTdHJpbmcgb3JpZ2luYWwpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoZGVjb2RlZCwgbmV3IFVSSSgiaHR0cDovL2ZvbyMiICsgb3JpZ2luYWwpLmdldEZyYWdtZW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZGVjb2RlZCwgVVJMRGVjb2Rlci5kZWNvZGUob3JpZ2luYWwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGRlY29kZWQsIFVSTERlY29kZXIuZGVjb2RlKG9yaWdpbmFsLCAiVVRGLTgiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzZXJ0cyB0aGF0IHtAY29kZSBvcmlnaW5hbH0gZW5jb2RlcyB0byB7QGNvZGUgZW5jb2RlZH0gdXNpbmcgYm90aCBVUkkKKyAgICAgKiBhbmQgVVJMRW5jb2Rlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0RW5jb2RlZChTdHJpbmcgZW5jb2RlZCwgU3RyaW5nIG9yaWdpbmFsKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGVuY29kZWQsIFVSTEVuY29kZXIuZW5jb2RlKG9yaWdpbmFsLCAiVVRGLTgiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhlbmNvZGVkLCBVUkxFbmNvZGVyLmVuY29kZShvcmlnaW5hbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZW5jb2RlZCwgbmV3IFVSSSgiaHR0cCIsICJmb28iLCAiLyIsIG9yaWdpbmFsKS5nZXRSYXdGcmFnbWVudCgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0Um91bmRUcmlwKFN0cmluZyBvcmlnaW5hbCwgU3RyaW5nIGVuY29kZWQpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoZW5jb2RlZCwgVVJMRW5jb2Rlci5lbmNvZGUob3JpZ2luYWwsICJVVEYtOCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG9yaWdpbmFsLCBVUkxEZWNvZGVyLmRlY29kZShlbmNvZGVkLCAiVVRGLTgiKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uZXQvY3VzdG9tc3RyZWFtaGFuZGxlci9odHRwL0hhbmRsZXIuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L2N1c3RvbXN0cmVhbWhhbmRsZXIvaHR0cC9IYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDBjMWIwOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmV0L2N1c3RvbXN0cmVhbWhhbmRsZXIvaHR0cC9IYW5kbGVyLmphdmEKQEAgLTAsMCArMSw0MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5ldC5jdXN0b21zdHJlYW1oYW5kbGVyLmh0dHA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTFN0cmVhbUhhbmRsZXI7CisKKy8qKgorICogVGhpcyBzcGVjaWFsbHktbmFtZWQgY2xhc3MgaXMgY3JlYXRlZCByZWZsZWN0aXZlbHkgYnkge0BsaW5rIFVSTH0uIEZvciB0aGUKKyAqIHRlc3QgdG8gYmUgZWZmZWN0aXZlLCBpdHMgbmFtZSBtdXN0IGJlICJIYW5kbGVyIiBhbmQgcGFyZW50IHBhY2thZ2UgbmFtZSBtdXN0CisgKiBiZSAiaHR0cCIuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBIYW5kbGVyIGV4dGVuZHMgVVJMU3RyZWFtSGFuZGxlciB7CisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBVUkxDb25uZWN0aW9uIG9wZW5Db25uZWN0aW9uKFVSTCB1cmwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgSGFuZGxlclVSTENvbm5lY3Rpb24odXJsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEhhbmRsZXJVUkxDb25uZWN0aW9uIGV4dGVuZHMgVVJMQ29ubmVjdGlvbiB7CisgICAgICAgIHByb3RlY3RlZCBIYW5kbGVyVVJMQ29ubmVjdGlvbihVUkwgdXJsKSB7CisgICAgICAgICAgICBzdXBlcih1cmwpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNvbm5lY3QoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vQnVmZmVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vQnVmZmVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI1NWRiMzYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9CdWZmZXJUZXN0LmphdmEKQEAgLTAsMCArMSw2NTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW87CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS5uaW8uKjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy4qOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgQnVmZmVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBCeXRlQnVmZmVyIGFsbG9jYXRlTWFwcGVkKGludCBzaXplKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZSBmID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgibWFwcGVkIiwgInRtcCIpOworICAgICAgICBmLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICBSYW5kb21BY2Nlc3NGaWxlIHJhZiA9IG5ldyBSYW5kb21BY2Nlc3NGaWxlKGYsICJydyIpOworICAgICAgICByYWYuc2V0TGVuZ3RoKHNpemUpOworICAgICAgICBGaWxlQ2hhbm5lbCBjaCA9IHJhZi5nZXRDaGFubmVsKCk7CisgICAgICAgIE1hcHBlZEJ5dGVCdWZmZXIgcmVzdWx0ID0gY2gubWFwKEZpbGVDaGFubmVsLk1hcE1vZGUuUkVBRF9XUklURSwgMCwgc2l6ZSk7CisgICAgICAgIGNoLmNsb3NlKCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEJ5dGVTd2FwcGVkQnVsa0dldERpcmVjdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Qnl0ZVN3YXBwZWRCdWxrR2V0KEJ5dGVCdWZmZXIuYWxsb2NhdGVEaXJlY3QoMTApKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qnl0ZVN3YXBwZWRCdWxrR2V0SGVhcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Qnl0ZVN3YXBwZWRCdWxrR2V0KEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qnl0ZVN3YXBwZWRCdWxrR2V0TWFwcGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RCeXRlU3dhcHBlZEJ1bGtHZXQoYWxsb2NhdGVNYXBwZWQoMTApKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdEJ5dGVTd2FwcGVkQnVsa0dldChCeXRlQnVmZmVyIGIpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGIubGltaXQoKTsgKytpKSB7CisgICAgICAgICAgICBiLnB1dChpLCAoYnl0ZSkgaSk7CisgICAgICAgIH0KKyAgICAgICAgYi5wb3NpdGlvbigxKTsKKworICAgICAgICBjaGFyW10gY2hhcnMgPSBuZXcgY2hhcls2XTsKKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuQklHX0VORElBTikuYXNDaGFyQnVmZmVyKCkuZ2V0KGNoYXJzLCAxLCA0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbXHUwMDAwLCBcdTAxMDIsIFx1MDMwNCwgXHUwNTA2LCBcdTA3MDgsIFx1MDAwMF0iLCBBcnJheXMudG9TdHJpbmcoY2hhcnMpKTsKKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuTElUVExFX0VORElBTikuYXNDaGFyQnVmZmVyKCkuZ2V0KGNoYXJzLCAxLCA0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbXHUwMDAwLCBcdTAyMDEsIFx1MDQwMywgXHUwNjA1LCBcdTA4MDcsIFx1MDAwMF0iLCBBcnJheXMudG9TdHJpbmcoY2hhcnMpKTsKKworICAgICAgICBkb3VibGVbXSBkb3VibGVzID0gbmV3IGRvdWJsZVszXTsKKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuQklHX0VORElBTikuYXNEb3VibGVCdWZmZXIoKS5nZXQoZG91YmxlcywgMSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBEb3VibGUuZG91YmxlVG9SYXdMb25nQml0cyhkb3VibGVzWzBdKSk7CisgICAgICAgIGFzc2VydEVxdWFscygweDAxMDIwMzA0MDUwNjA3MDhMLCBEb3VibGUuZG91YmxlVG9SYXdMb25nQml0cyhkb3VibGVzWzFdKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBEb3VibGUuZG91YmxlVG9SYXdMb25nQml0cyhkb3VibGVzWzJdKSk7CisgICAgICAgIGIub3JkZXIoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pLmFzRG91YmxlQnVmZmVyKCkuZ2V0KGRvdWJsZXMsIDEsIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgRG91YmxlLmRvdWJsZVRvUmF3TG9uZ0JpdHMoZG91Ymxlc1swXSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHgwODA3MDYwNTA0MDMwMjAxTCwgRG91YmxlLmRvdWJsZVRvUmF3TG9uZ0JpdHMoZG91Ymxlc1sxXSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgRG91YmxlLmRvdWJsZVRvUmF3TG9uZ0JpdHMoZG91Ymxlc1syXSkpOworCisgICAgICAgIGZsb2F0W10gZmxvYXRzID0gbmV3IGZsb2F0WzRdOworICAgICAgICBiLm9yZGVyKEJ5dGVPcmRlci5CSUdfRU5ESUFOKS5hc0Zsb2F0QnVmZmVyKCkuZ2V0KGZsb2F0cywgMSwgMik7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBGbG9hdC5mbG9hdFRvUmF3SW50Qml0cyhmbG9hdHNbMF0pKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MDEwMjAzMDQsIEZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKGZsb2F0c1sxXSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHgwNTA2MDcwOCwgRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMoZmxvYXRzWzJdKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBGbG9hdC5mbG9hdFRvUmF3SW50Qml0cyhmbG9hdHNbM10pKTsKKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuTElUVExFX0VORElBTikuYXNGbG9hdEJ1ZmZlcigpLmdldChmbG9hdHMsIDEsIDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMoZmxvYXRzWzBdKSk7CisgICAgICAgIGFzc2VydEVxdWFscygweDA0MDMwMjAxLCBGbG9hdC5mbG9hdFRvUmF3SW50Qml0cyhmbG9hdHNbMV0pKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MDgwNzA2MDUsIEZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKGZsb2F0c1syXSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMoZmxvYXRzWzNdKSk7CisKKyAgICAgICAgaW50W10gaW50cyA9IG5ldyBpbnRbNF07CisgICAgICAgIGIub3JkZXIoQnl0ZU9yZGVyLkJJR19FTkRJQU4pLmFzSW50QnVmZmVyKCkuZ2V0KGludHMsIDEsIDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaW50c1swXSk7CisgICAgICAgIGFzc2VydEVxdWFscygweDAxMDIwMzA0LCBpbnRzWzFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MDUwNjA3MDgsIGludHNbMl0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaW50c1szXSk7CisgICAgICAgIGIub3JkZXIoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pLmFzSW50QnVmZmVyKCkuZ2V0KGludHMsIDEsIDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaW50c1swXSk7CisgICAgICAgIGFzc2VydEVxdWFscygweDA0MDMwMjAxLCBpbnRzWzFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4MDgwNzA2MDUsIGludHNbMl0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaW50c1szXSk7CisKKyAgICAgICAgbG9uZ1tdIGxvbmdzID0gbmV3IGxvbmdbM107CisgICAgICAgIGIub3JkZXIoQnl0ZU9yZGVyLkJJR19FTkRJQU4pLmFzTG9uZ0J1ZmZlcigpLmdldChsb25ncywgMSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBsb25nc1swXSk7CisgICAgICAgIGFzc2VydEVxdWFscygweDAxMDIwMzA0MDUwNjA3MDhMLCBsb25nc1sxXSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBsb25nc1syXSk7CisgICAgICAgIGIub3JkZXIoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pLmFzTG9uZ0J1ZmZlcigpLmdldChsb25ncywgMSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBsb25nc1swXSk7CisgICAgICAgIGFzc2VydEVxdWFscygweDA4MDcwNjA1MDQwMzAyMDFMLCBsb25nc1sxXSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBsb25nc1syXSk7CisKKyAgICAgICAgc2hvcnRbXSBzaG9ydHMgPSBuZXcgc2hvcnRbNl07CisgICAgICAgIGIub3JkZXIoQnl0ZU9yZGVyLkJJR19FTkRJQU4pLmFzU2hvcnRCdWZmZXIoKS5nZXQoc2hvcnRzLCAxLCA0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHNob3J0c1swXSk7CisgICAgICAgIGFzc2VydEVxdWFscygweDAxMDIsIHNob3J0c1sxXSk7CisgICAgICAgIGFzc2VydEVxdWFscygweDAzMDQsIHNob3J0c1syXSk7CisgICAgICAgIGFzc2VydEVxdWFscygweDA1MDYsIHNob3J0c1szXSk7CisgICAgICAgIGFzc2VydEVxdWFscygweDA3MDgsIHNob3J0c1s0XSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBzaG9ydHNbNV0pOworICAgICAgICBiLm9yZGVyKEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKS5hc1Nob3J0QnVmZmVyKCkuZ2V0KHNob3J0cywgMSwgNCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBzaG9ydHNbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMHgwMjAxLCBzaG9ydHNbMV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMHgwNDAzLCBzaG9ydHNbMl0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMHgwNjA1LCBzaG9ydHNbM10pOworICAgICAgICBhc3NlcnRFcXVhbHMoMHgwODA3LCBzaG9ydHNbNF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgc2hvcnRzWzVdKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoQnl0ZUJ1ZmZlciBiKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBiLmxpbWl0KCk7ICsraSkgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChTdHJpbmcuZm9ybWF0KCIlMDJ4IiwgKGludCkgYi5nZXQoaSkpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEJ5dGVTd2FwcGVkQnVsa1B1dERpcmVjdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Qnl0ZVN3YXBwZWRCdWxrUHV0KEJ5dGVCdWZmZXIuYWxsb2NhdGVEaXJlY3QoMTApKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qnl0ZVN3YXBwZWRCdWxrUHV0SGVhcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Qnl0ZVN3YXBwZWRCdWxrUHV0KEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qnl0ZVN3YXBwZWRCdWxrUHV0TWFwcGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RCeXRlU3dhcHBlZEJ1bGtQdXQoYWxsb2NhdGVNYXBwZWQoMTApKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdEJ5dGVTd2FwcGVkQnVsa1B1dChCeXRlQnVmZmVyIGIpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBiLnBvc2l0aW9uKDEpOworCisgICAgICAgIGNoYXJbXSBjaGFycyA9IG5ldyBjaGFyW10geyAnXHUyMjIyJywgJ1x1MDEwMicsICdcdTAzMDQnLCAnXHUwNTA2JywgJ1x1MDcwOCcsICdcdTIyMjInIH07CisgICAgICAgIGIub3JkZXIoQnl0ZU9yZGVyLkJJR19FTkRJQU4pLmFzQ2hhckJ1ZmZlcigpLnB1dChjaGFycywgMSwgNCk7CisgICAgICAgIGFzc2VydEVxdWFscygiMDAwMTAyMDMwNDA1MDYwNzA4MDAiLCB0b1N0cmluZyhiKSk7CisgICAgICAgIGIub3JkZXIoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pLmFzQ2hhckJ1ZmZlcigpLnB1dChjaGFycywgMSwgNCk7CisgICAgICAgIGFzc2VydEVxdWFscygiMDAwMjAxMDQwMzA2MDUwODA3MDAiLCB0b1N0cmluZyhiKSk7CisKKyAgICAgICAgZG91YmxlW10gZG91YmxlcyA9IG5ldyBkb3VibGVbXSB7IDAsIERvdWJsZS5sb25nQml0c1RvRG91YmxlKDB4MDEwMjAzMDQwNTA2MDcwOEwpLCAwIH07CisgICAgICAgIGIub3JkZXIoQnl0ZU9yZGVyLkJJR19FTkRJQU4pLmFzRG91YmxlQnVmZmVyKCkucHV0KGRvdWJsZXMsIDEsIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjAwMDEwMjAzMDQwNTA2MDcwODAwIiwgdG9TdHJpbmcoYikpOworICAgICAgICBiLm9yZGVyKEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKS5hc0RvdWJsZUJ1ZmZlcigpLnB1dChkb3VibGVzLCAxLCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIwMDA4MDcwNjA1MDQwMzAyMDEwMCIsIHRvU3RyaW5nKGIpKTsKKworICAgICAgICBmbG9hdFtdIGZsb2F0cyA9IG5ldyBmbG9hdFtdIHsgMCwgRmxvYXQuaW50Qml0c1RvRmxvYXQoMHgwMTAyMDMwNCksCisgICAgICAgICAgICAgICAgRmxvYXQuaW50Qml0c1RvRmxvYXQoMHgwNTA2MDcwOCksIDAgfTsKKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuQklHX0VORElBTikuYXNGbG9hdEJ1ZmZlcigpLnB1dChmbG9hdHMsIDEsIDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjAwMDEwMjAzMDQwNTA2MDcwODAwIiwgdG9TdHJpbmcoYikpOworICAgICAgICBiLm9yZGVyKEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKS5hc0Zsb2F0QnVmZmVyKCkucHV0KGZsb2F0cywgMSwgMik7CisgICAgICAgIGFzc2VydEVxdWFscygiMDAwNDAzMDIwMTA4MDcwNjA1MDAiLCB0b1N0cmluZyhiKSk7CisKKyAgICAgICAgaW50W10gaW50cyA9IG5ldyBpbnRbXSB7IDAsIDB4MDEwMjAzMDQsIDB4MDUwNjA3MDgsIDAgfTsKKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuQklHX0VORElBTikuYXNJbnRCdWZmZXIoKS5wdXQoaW50cywgMSwgMik7CisgICAgICAgIGFzc2VydEVxdWFscygiMDAwMTAyMDMwNDA1MDYwNzA4MDAiLCB0b1N0cmluZyhiKSk7CisgICAgICAgIGIub3JkZXIoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pLmFzSW50QnVmZmVyKCkucHV0KGludHMsIDEsIDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjAwMDQwMzAyMDEwODA3MDYwNTAwIiwgdG9TdHJpbmcoYikpOworCisgICAgICAgIGxvbmdbXSBsb25ncyA9IG5ldyBsb25nW10geyAwLCAweDAxMDIwMzA0MDUwNjA3MDhMLCAwIH07CisgICAgICAgIGIub3JkZXIoQnl0ZU9yZGVyLkJJR19FTkRJQU4pLmFzTG9uZ0J1ZmZlcigpLnB1dChsb25ncywgMSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMDAwMTAyMDMwNDA1MDYwNzA4MDAiLCB0b1N0cmluZyhiKSk7CisgICAgICAgIGIub3JkZXIoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pLmFzTG9uZ0J1ZmZlcigpLnB1dChsb25ncywgMSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMDAwODA3MDYwNTA0MDMwMjAxMDAiLCB0b1N0cmluZyhiKSk7CisKKyAgICAgICAgc2hvcnRbXSBzaG9ydHMgPSBuZXcgc2hvcnRbXSB7IDAsIDB4MDEwMiwgMHgwMzA0LCAweDA1MDYsIDB4MDcwOCwgMCB9OworICAgICAgICBiLm9yZGVyKEJ5dGVPcmRlci5CSUdfRU5ESUFOKS5hc1Nob3J0QnVmZmVyKCkucHV0KHNob3J0cywgMSwgNCk7CisgICAgICAgIGFzc2VydEVxdWFscygiMDAwMTAyMDMwNDA1MDYwNzA4MDAiLCB0b1N0cmluZyhiKSk7CisgICAgICAgIGIub3JkZXIoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pLmFzU2hvcnRCdWZmZXIoKS5wdXQoc2hvcnRzLCAxLCA0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIwMDAyMDEwNDAzMDYwNTA4MDcwMCIsIHRvU3RyaW5nKGIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qnl0ZUJ1ZmZlckJ5dGVPcmRlckRpcmVjdFJXKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RCeXRlQnVmZmVyQnl0ZU9yZGVyKEJ5dGVCdWZmZXIuYWxsb2NhdGVEaXJlY3QoMTApLCBmYWxzZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEJ5dGVCdWZmZXJCeXRlT3JkZXJIZWFwUlcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEJ5dGVCdWZmZXJCeXRlT3JkZXIoQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCksIGZhbHNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qnl0ZUJ1ZmZlckJ5dGVPcmRlck1hcHBlZFJXKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RCeXRlQnVmZmVyQnl0ZU9yZGVyKGFsbG9jYXRlTWFwcGVkKDEwKSwgZmFsc2UpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCeXRlQnVmZmVyQnl0ZU9yZGVyRGlyZWN0Uk8oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEJ5dGVCdWZmZXJCeXRlT3JkZXIoQnl0ZUJ1ZmZlci5hbGxvY2F0ZURpcmVjdCgxMCksIHRydWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCeXRlQnVmZmVyQnl0ZU9yZGVySGVhcFJPKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RCeXRlQnVmZmVyQnl0ZU9yZGVyKEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApLCB0cnVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qnl0ZUJ1ZmZlckJ5dGVPcmRlck1hcHBlZFJPKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RCeXRlQnVmZmVyQnl0ZU9yZGVyKGFsbG9jYXRlTWFwcGVkKDEwKSwgdHJ1ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RCeXRlQnVmZmVyQnl0ZU9yZGVyKEJ5dGVCdWZmZXIgYiwgYm9vbGVhbiByZWFkT25seSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChyZWFkT25seSkgeworICAgICAgICAgICAgYiA9IGIuYXNSZWFkT25seUJ1ZmZlcigpOworICAgICAgICB9CisgICAgICAgIC8vIGFsbG9jYXRlL2FsbG9jYXRlRGlyZWN0L21hcCBhbHdheXMgcmV0dXJucyBhIGJpZy1lbmRpYW4gYnVmZmVyLgorICAgICAgICBhc3NlcnRFcXVhbHMoQnl0ZU9yZGVyLkJJR19FTkRJQU4sIGIub3JkZXIoKSk7CisKKyAgICAgICAgLy8gd3JhcCBhbHdheXMgcmV0dXJucyBhIGJpZy1lbmRpYW4gYnVmZmVyLgorICAgICAgICBhc3NlcnRFcXVhbHMoQnl0ZU9yZGVyLkJJR19FTkRJQU4sIGIud3JhcChuZXcgYnl0ZVsxMF0pLm9yZGVyKCkpOworCisgICAgICAgIC8vIGR1cGxpY2F0ZSBhbHdheXMgcmV0dXJucyBhIGJpZy1lbmRpYW4gYnVmZmVyLgorICAgICAgICBiLm9yZGVyKEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJ5dGVPcmRlci5CSUdfRU5ESUFOLCBiLmR1cGxpY2F0ZSgpLm9yZGVyKCkpOworICAgICAgICBiLm9yZGVyKEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJ5dGVPcmRlci5CSUdfRU5ESUFOLCBiLmR1cGxpY2F0ZSgpLm9yZGVyKCkpOworCisgICAgICAgIC8vIHNsaWNlIGFsd2F5cyByZXR1cm5zIGEgYmlnLWVuZGlhbiBidWZmZXIuCisgICAgICAgIGIub3JkZXIoQnl0ZU9yZGVyLkJJR19FTkRJQU4pOworICAgICAgICBhc3NlcnRFcXVhbHMoQnl0ZU9yZGVyLkJJR19FTkRJQU4sIGIuc2xpY2UoKS5vcmRlcigpKTsKKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisgICAgICAgIGFzc2VydEVxdWFscyhCeXRlT3JkZXIuQklHX0VORElBTiwgYi5zbGljZSgpLm9yZGVyKCkpOworCisgICAgICAgIC8vIGFzWEJ1ZmZlciBhbHdheXMgcmV0dXJucyBhIGN1cnJlbnQtZW5kaWFuIGJ1ZmZlci4KKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuQklHX0VORElBTik7CisgICAgICAgIGFzc2VydEVxdWFscyhCeXRlT3JkZXIuQklHX0VORElBTiwgYi5hc0NoYXJCdWZmZXIoKS5vcmRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJ5dGVPcmRlci5CSUdfRU5ESUFOLCBiLmFzRG91YmxlQnVmZmVyKCkub3JkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhCeXRlT3JkZXIuQklHX0VORElBTiwgYi5hc0Zsb2F0QnVmZmVyKCkub3JkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhCeXRlT3JkZXIuQklHX0VORElBTiwgYi5hc0ludEJ1ZmZlcigpLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQnl0ZU9yZGVyLkJJR19FTkRJQU4sIGIuYXNMb25nQnVmZmVyKCkub3JkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhCeXRlT3JkZXIuQklHX0VORElBTiwgYi5hc1Nob3J0QnVmZmVyKCkub3JkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhCeXRlT3JkZXIuQklHX0VORElBTiwgYi5hc1JlYWRPbmx5QnVmZmVyKCkub3JkZXIoKSk7CisgICAgICAgIGIub3JkZXIoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pOworICAgICAgICBhc3NlcnRFcXVhbHMoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4sIGIuYXNDaGFyQnVmZmVyKCkub3JkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhCeXRlT3JkZXIuTElUVExFX0VORElBTiwgYi5hc0RvdWJsZUJ1ZmZlcigpLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4sIGIuYXNGbG9hdEJ1ZmZlcigpLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4sIGIuYXNJbnRCdWZmZXIoKS5vcmRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOLCBiLmFzTG9uZ0J1ZmZlcigpLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4sIGIuYXNTaG9ydEJ1ZmZlcigpLm9yZGVyKCkpOworICAgICAgICAvLyAuLi5leGNlcHQgZm9yIGFzUmVhZE9ubHlCdWZmZXIsIHdoaWNoIGFsd2F5cyByZXR1cm5zIGEgYmlnLWVuZGlhbiBidWZmZXIuCisgICAgICAgIGFzc2VydEVxdWFscyhCeXRlT3JkZXIuQklHX0VORElBTiwgYi5hc1JlYWRPbmx5QnVmZmVyKCkub3JkZXIoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENoYXJCdWZmZXJCeXRlT3JkZXJXcmFwcGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyhCeXRlT3JkZXIubmF0aXZlT3JkZXIoKSwgQ2hhckJ1ZmZlci53cmFwKG5ldyBjaGFyWzEwXSkub3JkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhCeXRlT3JkZXIubmF0aXZlT3JkZXIoKSwgQ2hhckJ1ZmZlci53cmFwKG5ldyBjaGFyWzEwXSkuYXNSZWFkT25seUJ1ZmZlcigpLm9yZGVyKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0Q2hhckJ1ZmZlckJ5dGVPcmRlcihDaGFyQnVmZmVyIGIsIEJ5dGVPcmRlciBibykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyhibywgYi5vcmRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJvLCBiLmR1cGxpY2F0ZSgpLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYm8sIGIuc2xpY2UoKS5vcmRlcigpKTsKKyAgICAgICAgYiA9IGIuYXNSZWFkT25seUJ1ZmZlcigpOworICAgICAgICBhc3NlcnRFcXVhbHMoYm8sIGIub3JkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhibywgYi5kdXBsaWNhdGUoKS5vcmRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJvLCBiLnNsaWNlKCkub3JkZXIoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBDaGFyQnVmZmVyIGFsbG9jYXRlQ2hhckJ1ZmZlcihCeXRlT3JkZXIgb3JkZXIpIHsKKyAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApLm9yZGVyKG9yZGVyKS5hc0NoYXJCdWZmZXIoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2hhckJ1ZmZlckJ5dGVPcmRlckFycmF5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RDaGFyQnVmZmVyQnl0ZU9yZGVyKENoYXJCdWZmZXIuYWxsb2NhdGUoMTApLCBCeXRlT3JkZXIubmF0aXZlT3JkZXIoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENoYXJCdWZmZXJCeXRlT3JkZXJCRSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Q2hhckJ1ZmZlckJ5dGVPcmRlcihhbGxvY2F0ZUNoYXJCdWZmZXIoQnl0ZU9yZGVyLkJJR19FTkRJQU4pLCBCeXRlT3JkZXIuQklHX0VORElBTik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENoYXJCdWZmZXJCeXRlT3JkZXJMRSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Q2hhckJ1ZmZlckJ5dGVPcmRlcihhbGxvY2F0ZUNoYXJCdWZmZXIoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pLCBCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERvdWJsZUJ1ZmZlckJ5dGVPcmRlcldyYXBwZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJ5dGVPcmRlci5uYXRpdmVPcmRlcigpLCBEb3VibGVCdWZmZXIud3JhcChuZXcgZG91YmxlWzEwXSkub3JkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhCeXRlT3JkZXIubmF0aXZlT3JkZXIoKSwgRG91YmxlQnVmZmVyLndyYXAobmV3IGRvdWJsZVsxMF0pLmFzUmVhZE9ubHlCdWZmZXIoKS5vcmRlcigpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdERvdWJsZUJ1ZmZlckJ5dGVPcmRlcihEb3VibGVCdWZmZXIgYiwgQnl0ZU9yZGVyIGJvKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJvLCBiLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYm8sIGIuZHVwbGljYXRlKCkub3JkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhibywgYi5zbGljZSgpLm9yZGVyKCkpOworICAgICAgICBiID0gYi5hc1JlYWRPbmx5QnVmZmVyKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhibywgYi5vcmRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJvLCBiLmR1cGxpY2F0ZSgpLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYm8sIGIuc2xpY2UoKS5vcmRlcigpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIERvdWJsZUJ1ZmZlciBhbGxvY2F0ZURvdWJsZUJ1ZmZlcihCeXRlT3JkZXIgb3JkZXIpIHsKKyAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTAqOCkub3JkZXIob3JkZXIpLmFzRG91YmxlQnVmZmVyKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERvdWJsZUJ1ZmZlckJ5dGVPcmRlckFycmF5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3REb3VibGVCdWZmZXJCeXRlT3JkZXIoRG91YmxlQnVmZmVyLmFsbG9jYXRlKDEwKSwgQnl0ZU9yZGVyLm5hdGl2ZU9yZGVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REb3VibGVCdWZmZXJCeXRlT3JkZXJCRSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0RG91YmxlQnVmZmVyQnl0ZU9yZGVyKGFsbG9jYXRlRG91YmxlQnVmZmVyKEJ5dGVPcmRlci5CSUdfRU5ESUFOKSwgQnl0ZU9yZGVyLkJJR19FTkRJQU4pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REb3VibGVCdWZmZXJCeXRlT3JkZXJMRSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0RG91YmxlQnVmZmVyQnl0ZU9yZGVyKGFsbG9jYXRlRG91YmxlQnVmZmVyKEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSwgQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGbG9hdEJ1ZmZlckJ5dGVPcmRlcldyYXBwZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJ5dGVPcmRlci5uYXRpdmVPcmRlcigpLCBGbG9hdEJ1ZmZlci53cmFwKG5ldyBmbG9hdFsxMF0pLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQnl0ZU9yZGVyLm5hdGl2ZU9yZGVyKCksIEZsb2F0QnVmZmVyLndyYXAobmV3IGZsb2F0WzEwXSkuYXNSZWFkT25seUJ1ZmZlcigpLm9yZGVyKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0RmxvYXRCdWZmZXJCeXRlT3JkZXIoRmxvYXRCdWZmZXIgYiwgQnl0ZU9yZGVyIGJvKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJvLCBiLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYm8sIGIuZHVwbGljYXRlKCkub3JkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhibywgYi5zbGljZSgpLm9yZGVyKCkpOworICAgICAgICBiID0gYi5hc1JlYWRPbmx5QnVmZmVyKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhibywgYi5vcmRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJvLCBiLmR1cGxpY2F0ZSgpLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYm8sIGIuc2xpY2UoKS5vcmRlcigpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIEZsb2F0QnVmZmVyIGFsbG9jYXRlRmxvYXRCdWZmZXIoQnl0ZU9yZGVyIG9yZGVyKSB7CisgICAgICAgIHJldHVybiBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKjgpLm9yZGVyKG9yZGVyKS5hc0Zsb2F0QnVmZmVyKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZsb2F0QnVmZmVyQnl0ZU9yZGVyQXJyYXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEZsb2F0QnVmZmVyQnl0ZU9yZGVyKEZsb2F0QnVmZmVyLmFsbG9jYXRlKDEwKSwgQnl0ZU9yZGVyLm5hdGl2ZU9yZGVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGbG9hdEJ1ZmZlckJ5dGVPcmRlckJFKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RGbG9hdEJ1ZmZlckJ5dGVPcmRlcihhbGxvY2F0ZUZsb2F0QnVmZmVyKEJ5dGVPcmRlci5CSUdfRU5ESUFOKSwgQnl0ZU9yZGVyLkJJR19FTkRJQU4pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGbG9hdEJ1ZmZlckJ5dGVPcmRlckxFKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RGbG9hdEJ1ZmZlckJ5dGVPcmRlcihhbGxvY2F0ZUZsb2F0QnVmZmVyKEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSwgQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnRCdWZmZXJCeXRlT3JkZXJXcmFwcGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyhCeXRlT3JkZXIubmF0aXZlT3JkZXIoKSwgSW50QnVmZmVyLndyYXAobmV3IGludFsxMF0pLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQnl0ZU9yZGVyLm5hdGl2ZU9yZGVyKCksIEludEJ1ZmZlci53cmFwKG5ldyBpbnRbMTBdKS5hc1JlYWRPbmx5QnVmZmVyKCkub3JkZXIoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RJbnRCdWZmZXJCeXRlT3JkZXIoSW50QnVmZmVyIGIsIEJ5dGVPcmRlciBibykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyhibywgYi5vcmRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJvLCBiLmR1cGxpY2F0ZSgpLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYm8sIGIuc2xpY2UoKS5vcmRlcigpKTsKKyAgICAgICAgYiA9IGIuYXNSZWFkT25seUJ1ZmZlcigpOworICAgICAgICBhc3NlcnRFcXVhbHMoYm8sIGIub3JkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhibywgYi5kdXBsaWNhdGUoKS5vcmRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJvLCBiLnNsaWNlKCkub3JkZXIoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBJbnRCdWZmZXIgYWxsb2NhdGVJbnRCdWZmZXIoQnl0ZU9yZGVyIG9yZGVyKSB7CisgICAgICAgIHJldHVybiBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKjgpLm9yZGVyKG9yZGVyKS5hc0ludEJ1ZmZlcigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnRCdWZmZXJCeXRlT3JkZXJBcnJheSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0SW50QnVmZmVyQnl0ZU9yZGVyKEludEJ1ZmZlci5hbGxvY2F0ZSgxMCksIEJ5dGVPcmRlci5uYXRpdmVPcmRlcigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW50QnVmZmVyQnl0ZU9yZGVyQkUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEludEJ1ZmZlckJ5dGVPcmRlcihhbGxvY2F0ZUludEJ1ZmZlcihCeXRlT3JkZXIuQklHX0VORElBTiksIEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW50QnVmZmVyQnl0ZU9yZGVyTEUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEludEJ1ZmZlckJ5dGVPcmRlcihhbGxvY2F0ZUludEJ1ZmZlcihCeXRlT3JkZXIuTElUVExFX0VORElBTiksIEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9uZ0J1ZmZlckJ5dGVPcmRlcldyYXBwZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJ5dGVPcmRlci5uYXRpdmVPcmRlcigpLCBMb25nQnVmZmVyLndyYXAobmV3IGxvbmdbMTBdKS5vcmRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJ5dGVPcmRlci5uYXRpdmVPcmRlcigpLCBMb25nQnVmZmVyLndyYXAobmV3IGxvbmdbMTBdKS5hc1JlYWRPbmx5QnVmZmVyKCkub3JkZXIoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RMb25nQnVmZmVyQnl0ZU9yZGVyKExvbmdCdWZmZXIgYiwgQnl0ZU9yZGVyIGJvKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJvLCBiLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYm8sIGIuZHVwbGljYXRlKCkub3JkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhibywgYi5zbGljZSgpLm9yZGVyKCkpOworICAgICAgICBiID0gYi5hc1JlYWRPbmx5QnVmZmVyKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhibywgYi5vcmRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJvLCBiLmR1cGxpY2F0ZSgpLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYm8sIGIuc2xpY2UoKS5vcmRlcigpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIExvbmdCdWZmZXIgYWxsb2NhdGVMb25nQnVmZmVyKEJ5dGVPcmRlciBvcmRlcikgeworICAgICAgICByZXR1cm4gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCo4KS5vcmRlcihvcmRlcikuYXNMb25nQnVmZmVyKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdExvbmdCdWZmZXJCeXRlT3JkZXJBcnJheSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0TG9uZ0J1ZmZlckJ5dGVPcmRlcihMb25nQnVmZmVyLmFsbG9jYXRlKDEwKSwgQnl0ZU9yZGVyLm5hdGl2ZU9yZGVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RMb25nQnVmZmVyQnl0ZU9yZGVyQkUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdExvbmdCdWZmZXJCeXRlT3JkZXIoYWxsb2NhdGVMb25nQnVmZmVyKEJ5dGVPcmRlci5CSUdfRU5ESUFOKSwgQnl0ZU9yZGVyLkJJR19FTkRJQU4pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RMb25nQnVmZmVyQnl0ZU9yZGVyTEUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdExvbmdCdWZmZXJCeXRlT3JkZXIoYWxsb2NhdGVMb25nQnVmZmVyKEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSwgQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTaG9ydEJ1ZmZlckJ5dGVPcmRlcldyYXBwZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJ5dGVPcmRlci5uYXRpdmVPcmRlcigpLCBTaG9ydEJ1ZmZlci53cmFwKG5ldyBzaG9ydFsxMF0pLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQnl0ZU9yZGVyLm5hdGl2ZU9yZGVyKCksIFNob3J0QnVmZmVyLndyYXAobmV3IHNob3J0WzEwXSkuYXNSZWFkT25seUJ1ZmZlcigpLm9yZGVyKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0U2hvcnRCdWZmZXJCeXRlT3JkZXIoU2hvcnRCdWZmZXIgYiwgQnl0ZU9yZGVyIGJvKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJvLCBiLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYm8sIGIuZHVwbGljYXRlKCkub3JkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhibywgYi5zbGljZSgpLm9yZGVyKCkpOworICAgICAgICBiID0gYi5hc1JlYWRPbmx5QnVmZmVyKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhibywgYi5vcmRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJvLCBiLmR1cGxpY2F0ZSgpLm9yZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYm8sIGIuc2xpY2UoKS5vcmRlcigpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFNob3J0QnVmZmVyIGFsbG9jYXRlU2hvcnRCdWZmZXIoQnl0ZU9yZGVyIG9yZGVyKSB7CisgICAgICAgIHJldHVybiBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKjgpLm9yZGVyKG9yZGVyKS5hc1Nob3J0QnVmZmVyKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNob3J0QnVmZmVyQnl0ZU9yZGVyQXJyYXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFNob3J0QnVmZmVyQnl0ZU9yZGVyKFNob3J0QnVmZmVyLmFsbG9jYXRlKDEwKSwgQnl0ZU9yZGVyLm5hdGl2ZU9yZGVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTaG9ydEJ1ZmZlckJ5dGVPcmRlckJFKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RTaG9ydEJ1ZmZlckJ5dGVPcmRlcihhbGxvY2F0ZVNob3J0QnVmZmVyKEJ5dGVPcmRlci5CSUdfRU5ESUFOKSwgQnl0ZU9yZGVyLkJJR19FTkRJQU4pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTaG9ydEJ1ZmZlckJ5dGVPcmRlckxFKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RTaG9ydEJ1ZmZlckJ5dGVPcmRlcihhbGxvY2F0ZVNob3J0QnVmZmVyKEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKSwgQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWxhdGl2ZVBvc2l0aW9uc0hlYXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFJlbGF0aXZlUG9zaXRpb25zKEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVsYXRpdmVQb3NpdGlvbnNEaXJlY3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFJlbGF0aXZlUG9zaXRpb25zKEJ5dGVCdWZmZXIuYWxsb2NhdGVEaXJlY3QoMTApKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVsYXRpdmVQb3NpdGlvbnNNYXBwZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFJlbGF0aXZlUG9zaXRpb25zKGFsbG9jYXRlTWFwcGVkKDEwKSk7CisgICAgfQorCisgICAgLy8gaHR0cDovL2IvMzI5MTkyNyAtIGVuc3VyZSB0aGF0IHRoZSByZWxhdGl2ZSBnZXQgYW5kIHB1dCBtZXRob2RzIGFkdmFuY2UgJ3Bvc2l0aW9uJy4KKyAgICBwcml2YXRlIHZvaWQgdGVzdFJlbGF0aXZlUG9zaXRpb25zKEJ5dGVCdWZmZXIgYikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIGdldHMKKyAgICAgICAgYi5wb3NpdGlvbigwKTsKKyAgICAgICAgYi5nZXQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGIucG9zaXRpb24oKSk7CisKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzVdOworICAgICAgICBiLnBvc2l0aW9uKDApOworICAgICAgICBiLmdldChidWYpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgYi5wb3NpdGlvbigpKTsKKworICAgICAgICBiLnBvc2l0aW9uKDApOworICAgICAgICBiLmdldChidWYsIDEsIDMpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgYi5wb3NpdGlvbigpKTsKKworICAgICAgICBiLnBvc2l0aW9uKDApOworICAgICAgICBiLmdldENoYXIoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGIucG9zaXRpb24oKSk7CisKKyAgICAgICAgYi5wb3NpdGlvbigwKTsKKyAgICAgICAgYi5nZXREb3VibGUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDgsIGIucG9zaXRpb24oKSk7CisKKyAgICAgICAgYi5wb3NpdGlvbigwKTsKKyAgICAgICAgYi5nZXRGbG9hdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgYi5wb3NpdGlvbigpKTsKKworICAgICAgICBiLnBvc2l0aW9uKDApOworICAgICAgICBiLmdldEludCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgYi5wb3NpdGlvbigpKTsKKworICAgICAgICBiLnBvc2l0aW9uKDApOworICAgICAgICBiLmdldExvbmcoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDgsIGIucG9zaXRpb24oKSk7CisKKyAgICAgICAgYi5wb3NpdGlvbigwKTsKKyAgICAgICAgYi5nZXRTaG9ydCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgYi5wb3NpdGlvbigpKTsKKworICAgICAgICAvLyBwdXRzCisgICAgICAgIGIucG9zaXRpb24oMCk7CisgICAgICAgIGIucHV0KChieXRlKSAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGIucG9zaXRpb24oKSk7CisKKyAgICAgICAgYi5wb3NpdGlvbigwKTsKKyAgICAgICAgYi5wdXQoYnVmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIGIucG9zaXRpb24oKSk7CisKKyAgICAgICAgYi5wb3NpdGlvbigwKTsKKyAgICAgICAgYi5wdXQoYnVmLCAxLCAzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGIucG9zaXRpb24oKSk7CisKKyAgICAgICAgYi5wb3NpdGlvbigwKTsKKyAgICAgICAgYi5wdXRDaGFyKCd4Jyk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBiLnBvc2l0aW9uKCkpOworCisgICAgICAgIGIucG9zaXRpb24oMCk7CisgICAgICAgIGIucHV0RG91YmxlKDApOworICAgICAgICBhc3NlcnRFcXVhbHMoOCwgYi5wb3NpdGlvbigpKTsKKworICAgICAgICBiLnBvc2l0aW9uKDApOworICAgICAgICBiLnB1dEZsb2F0KDApOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgYi5wb3NpdGlvbigpKTsKKworICAgICAgICBiLnBvc2l0aW9uKDApOworICAgICAgICBiLnB1dEludCgwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGIucG9zaXRpb24oKSk7CisKKyAgICAgICAgYi5wb3NpdGlvbigwKTsKKyAgICAgICAgYi5wdXRMb25nKDApOworICAgICAgICBhc3NlcnRFcXVhbHMoOCwgYi5wb3NpdGlvbigpKTsKKworICAgICAgICBiLnBvc2l0aW9uKDApOworICAgICAgICBiLnB1dFNob3J0KChzaG9ydCkgMCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBiLnBvc2l0aW9uKCkpOworICAgIH0KKworICAgIC8vIFRoaXMgdGVzdCB3aWxsIGZhaWwgb24gdGhlIFJJLiBPdXIgZGlyZWN0IGJ1ZmZlcnMgYXJlIGNvb2xlciB0aGFuIHRoZWlycy4KKyAgICAvLyBodHRwOi8vYi8zMzg0NDMxCisgICAgcHVibGljIHZvaWQgdGVzdERpcmVjdEJ5dGVCdWZmZXJIYXNBcnJheSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBCeXRlQnVmZmVyIGIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlRGlyZWN0KDEwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShiLmlzRGlyZWN0KCkpOworICAgICAgICAvLyBDaGVjayB0aGUgYnVmZmVyIGhhcyBhbiBhcnJheSBvZiB0aGUgcmlnaHQgc2l6ZS4KKyAgICAgICAgYXNzZXJ0VHJ1ZShiLmhhc0FycmF5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYi5hcnJheU9mZnNldCgpKTsKKyAgICAgICAgYnl0ZVtdIGFycmF5ID0gYi5hcnJheSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTAsIGFycmF5Lmxlbmd0aCk7CisgICAgICAgIC8vIENoZWNrIHRoYXQgd3JpdGVzIHRvIHRoZSBhcnJheSBzaG93IHVwIGluIHRoZSBidWZmZXIuCisgICAgICAgIGFzc2VydEVxdWFscygwLCBiLmdldCgwKSk7CisgICAgICAgIGFycmF5WzBdID0gMTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGIuZ2V0KDApKTsKKyAgICAgICAgLy8gQ2hlY2sgdGhhdCB3cml0ZXMgdG8gdGhlIGJ1ZmZlciBzaG93IHVwIGluIHRoZSBhcnJheS4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGFycmF5WzBdKTsKKyAgICAgICAgYi5wdXQoMCwgKGJ5dGUpIDApOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYXJyYXlbMF0pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTbGljZU9mZnNldCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBTbGljaW5nIGNoYW5nZXMgdGhlIGFycmF5IG9mZnNldC4KKyAgICAgICAgQnl0ZUJ1ZmZlciBidWZmZXIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKTsKKyAgICAgICAgYnVmZmVyLmdldCgpOworICAgICAgICBCeXRlQnVmZmVyIHNsaWNlID0gYnVmZmVyLnNsaWNlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBidWZmZXIuYXJyYXlPZmZzZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBzbGljZS5hcnJheU9mZnNldCgpKTsKKworICAgICAgICBCeXRlQnVmZmVyIGRpcmVjdEJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGVEaXJlY3QoMTApOworICAgICAgICBkaXJlY3RCdWZmZXIuZ2V0KCk7CisgICAgICAgIEJ5dGVCdWZmZXIgZGlyZWN0U2xpY2UgPSBkaXJlY3RCdWZmZXIuc2xpY2UoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGRpcmVjdEJ1ZmZlci5hcnJheU9mZnNldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGRpcmVjdFNsaWNlLmFycmF5T2Zmc2V0KCkpOworICAgIH0KKworICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9MTYxODQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHV0Qnl0ZUJ1ZmZlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBCeXRlQnVmZmVyIGRzdCA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApLmFzUmVhZE9ubHlCdWZmZXIoKTsKKworICAgICAgICAvLyBDYW4ndCBwdXQgaW50byBhIHJlYWQtb25seSBidWZmZXIuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkc3QucHV0KEJ5dGVCdWZmZXIuYWxsb2NhdGUoNSkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gQ2FuJ3QgcHV0IGEgYnVmZmVyIGludG8gaXRzZWxmLgorICAgICAgICBkc3QgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRzdC5wdXQoZHN0KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICAvLyBDYW4ndCBwdXQgdGhlIG51bGwgQnl0ZUJ1ZmZlci4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRzdC5wdXQoKEJ5dGVCdWZmZXIpIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gQ2FuJ3QgcHV0IGEgbGFyZ2VyIHNvdXJjZSBpbnRvIGEgc21hbGxlciBkZXN0aW5hdGlvbi4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRzdC5wdXQoQnl0ZUJ1ZmZlci5hbGxvY2F0ZShkc3QuY2FwYWNpdHkoKSArIDEpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydFB1dEJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCksIEJ5dGVCdWZmZXIuYWxsb2NhdGUoOCksIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0UHV0Qnl0ZUJ1ZmZlcihCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZURpcmVjdCg4KSwgZmFsc2UpOworICAgICAgICBhc3NlcnRQdXRCeXRlQnVmZmVyKEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApLCBhbGxvY2F0ZU1hcHBlZCg4KSwgZmFsc2UpOworICAgICAgICBhc3NlcnRQdXRCeXRlQnVmZmVyKEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApLCBCeXRlQnVmZmVyLmFsbG9jYXRlKDgpLCB0cnVlKTsKKyAgICAgICAgYXNzZXJ0UHV0Qnl0ZUJ1ZmZlcihCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZURpcmVjdCg4KSwgdHJ1ZSk7CisgICAgICAgIGFzc2VydFB1dEJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCksIGFsbG9jYXRlTWFwcGVkKDgpLCB0cnVlKTsKKworICAgICAgICBhc3NlcnRQdXRCeXRlQnVmZmVyKEJ5dGVCdWZmZXIuYWxsb2NhdGVEaXJlY3QoMTApLCBCeXRlQnVmZmVyLmFsbG9jYXRlKDgpLCBmYWxzZSk7CisgICAgICAgIGFzc2VydFB1dEJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlci5hbGxvY2F0ZURpcmVjdCgxMCksIEJ5dGVCdWZmZXIuYWxsb2NhdGVEaXJlY3QoOCksIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0UHV0Qnl0ZUJ1ZmZlcihCeXRlQnVmZmVyLmFsbG9jYXRlRGlyZWN0KDEwKSwgYWxsb2NhdGVNYXBwZWQoOCksIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0UHV0Qnl0ZUJ1ZmZlcihCeXRlQnVmZmVyLmFsbG9jYXRlRGlyZWN0KDEwKSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSg4KSwgdHJ1ZSk7CisgICAgICAgIGFzc2VydFB1dEJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlci5hbGxvY2F0ZURpcmVjdCgxMCksIEJ5dGVCdWZmZXIuYWxsb2NhdGVEaXJlY3QoOCksIHRydWUpOworICAgICAgICBhc3NlcnRQdXRCeXRlQnVmZmVyKEJ5dGVCdWZmZXIuYWxsb2NhdGVEaXJlY3QoMTApLCBhbGxvY2F0ZU1hcHBlZCg4KSwgdHJ1ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydFB1dEJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlciBkc3QsIEJ5dGVCdWZmZXIgc3JjLCBib29sZWFuIHJlYWRPbmx5KSB7CisgICAgICAgIC8vIFN0YXJ0ICdkc3QnIG9mZiBhcyB0aGUgaW5kZXgtaWRlbnRpdHkgcGF0dGVybi4KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkc3QuY2FwYWNpdHkoKTsgKytpKSB7CisgICAgICAgICAgICBkc3QucHV0KGksIChieXRlKSBpKTsKKyAgICAgICAgfQorICAgICAgICAvLyBEZWxpYmVyYXRlbHkgb2Zmc2V0IHRoZSBwb3NpdGlvbiB3ZSdsbCB3cml0ZSB0byBieSAxLgorICAgICAgICBkc3QucG9zaXRpb24oMSk7CisKKyAgICAgICAgLy8gTWFrZSB0aGUgc291cmNlIG1vcmUgaW50ZXJlc3RpbmcuCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3JjLmNhcGFjaXR5KCk7ICsraSkgeworICAgICAgICAgICAgc3JjLnB1dChpLCAoYnl0ZSkgKDE2ICsgaSkpOworICAgICAgICB9CisgICAgICAgIGlmIChyZWFkT25seSkgeworICAgICAgICAgICAgc3JjID0gc3JjLmFzUmVhZE9ubHlCdWZmZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIEJ5dGVCdWZmZXIgZHN0MiA9IGRzdC5wdXQoc3JjKTsKKyAgICAgICAgYXNzZXJ0U2FtZShkc3QsIGRzdDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgc3JjLnJlbWFpbmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNyYy5wb3NpdGlvbigpLCBzcmMuY2FwYWNpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhkc3QucG9zaXRpb24oKSwgc3JjLmNhcGFjaXR5KCkgKyAxKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzcmMuY2FwYWNpdHkoKTsgKytpKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoc3JjLmdldChpKSwgZHN0LmdldChpICsgMSkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gTm8gcm9vbSBmb3IgYW5vdGhlci4KKyAgICAgICAgc3JjLnBvc2l0aW9uKDApOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZHN0LnB1dChzcmMpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENoYXJCdWZmZXJTdWJTZXF1ZW5jZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBCeXRlQnVmZmVyIGIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlRGlyZWN0KDEwKS5vcmRlcihCeXRlT3JkZXIubmF0aXZlT3JkZXIoKSk7CisgICAgICAgIGIucHV0Q2hhcignSCcpOworICAgICAgICBiLnB1dENoYXIoJ2UnKTsKKyAgICAgICAgYi5wdXRDaGFyKCdsJyk7CisgICAgICAgIGIucHV0Q2hhcignbCcpOworICAgICAgICBiLnB1dENoYXIoJ28nKTsKKyAgICAgICAgYi5mbGlwKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJIZWxsbyIsIGIuYXNDaGFyQnVmZmVyKCkudG9TdHJpbmcoKSk7CisKKyAgICAgICAgQ2hhckJ1ZmZlciBjYiA9IGIuYXNDaGFyQnVmZmVyKCk7CisgICAgICAgIENoYXJTZXF1ZW5jZSBjcyA9IGNiLnN1YlNlcXVlbmNlKDAsIGNiLmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJIZWxsbyIsIGNzLnRvU3RyaW5nKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL05vQXJyYXlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9Ob0FycmF5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2NTQ2MDQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9Ob0FycmF5VGVzdC5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pbzsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uUmVhZE9ubHlCdWZmZXJFeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgTm9BcnJheVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRPbmx5KCkgeworICAgICAgICAvLyBBIHJlYWQtb25seSBidWZmZXIgbXVzdCBub3QgZXhwb3NlIGl0cyBhcnJheS4KKyAgICAgICAgYXNzZXJ0Tm9BcnJheShCeXRlQnVmZmVyLndyYXAobmV3IGJ5dGVbMzJdKS5hc1JlYWRPbmx5QnVmZmVyKCkpOworICAgICAgICBhc3NlcnROb0FycmF5KEJ5dGVCdWZmZXIuYWxsb2NhdGUoMzIpLmFzUmVhZE9ubHlCdWZmZXIoKSk7CisgICAgICAgIGFzc2VydE5vQXJyYXkoQnl0ZUJ1ZmZlci5hbGxvY2F0ZURpcmVjdCgzMikuYXNSZWFkT25seUJ1ZmZlcigpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0Tm9BcnJheShCeXRlQnVmZmVyIGJ1ZikgeworICAgICAgICBhc3NlcnRGYWxzZShidWYuaGFzQXJyYXkoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidWYuYXJyYXkoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYnVmLmFycmF5T2Zmc2V0KCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9PbGRBbmRyb2lkTklPVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vT2xkQW5kcm9pZE5JT1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZWVhNjNmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vT2xkQW5kcm9pZE5JT1Rlc3QuamF2YQpAQCAtMCwwICsxLDcwNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pbzsKKworaW1wb3J0IGphdmEubmlvLkJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5CdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CdWZmZXJVbmRlcmZsb3dFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlT3JkZXI7CitpbXBvcnQgamF2YS5uaW8uRmxvYXRCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uSW50QnVmZmVyOworaW1wb3J0IGphdmEubmlvLlNob3J0QnVmZmVyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3Igc29tZSBidWZmZXJzIGZyb20gdGhlIGphdmEubmlvIHBhY2thZ2UuCisgKi8KK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkTklPVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHZvaWQgY2hlY2tCdWZmZXIoQnVmZmVyIGIpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgwIDw9IGIucG9zaXRpb24oKSk7CisgICAgICAgIGFzc2VydFRydWUoYi5wb3NpdGlvbigpIDw9IGIubGltaXQoKSk7CisgICAgICAgIGFzc2VydFRydWUoYi5saW1pdCgpIDw9IGIuY2FwYWNpdHkoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5JT19ieXRlX2FycmF5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgYnl0ZSBhcnJheS1iYXNlZCBidWZmZXIKKyAgICAgICAgYnl0ZUJ1ZmZlclRlc3QoQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROSU9fZGlyZWN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgbmF0aXZlIGhlYXAtYWxsb2NhdGVkIGJ1ZmZlcgorICAgICAgICBieXRlQnVmZmVyVGVzdChCeXRlQnVmZmVyLmFsbG9jYXRlRGlyZWN0KDEyKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5JT19zaG9ydF9hcnJheSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IHNob3J0IGFycmF5LWJhc2VkIGJ1ZmZlcgorICAgICAgICBzaG9ydFtdIHNob3J0QXJyYXkgPSBuZXcgc2hvcnRbOF07CisgICAgICAgIFNob3J0QnVmZmVyIHNiID0gU2hvcnRCdWZmZXIud3JhcChzaG9ydEFycmF5KTsKKyAgICAgICAgc2hvcnRCdWZmZXJUZXN0KHNiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TklPX2ludF9hcnJheSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGludCBhcnJheS1iYXNlZCBidWZmZXIKKyAgICAgICAgaW50W10gaW50QXJyYXkgPSBuZXcgaW50WzhdOworICAgICAgICBJbnRCdWZmZXIgaWIgPSBJbnRCdWZmZXIud3JhcChpbnRBcnJheSk7CisgICAgICAgIGludEJ1ZmZlclRlc3QoaWIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROSU9fZmxvYXRfYXJyYXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmbG9hdCBhcnJheS1iYXNlZCBidWZmZXIKKyAgICAgICAgZmxvYXRbXSBmbG9hdEFycmF5ID0gbmV3IGZsb2F0WzhdOworICAgICAgICBGbG9hdEJ1ZmZlciBmYiA9IEZsb2F0QnVmZmVyLndyYXAoZmxvYXRBcnJheSk7CisgICAgICAgIGZsb2F0QnVmZmVyVGVzdChmYik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGJ5dGVCdWZmZXJUZXN0KEJ5dGVCdWZmZXIgYikgeworICAgICAgICBjaGVja0J1ZmZlcihiKTsKKworICAgICAgICAvLyBEdXBsaWNhdGUgYnVmZmVycyByZXZlcnQgdG8gYmlnLWVuZGlhbi4KKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisgICAgICAgIEJ5dGVCdWZmZXIgZHVwZSA9IGIuZHVwbGljYXRlKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhCeXRlT3JkZXIuQklHX0VORElBTiwgZHVwZS5vcmRlcigpKTsKKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuQklHX0VORElBTik7CisKKyAgICAgICAgLy8gQm91bmRzIGNoZWNrcworICAgICAgICB0cnkgeworICAgICAgICAgICAgYi5wdXQoLTEsIChieXRlKSAwKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiLnB1dChiLmxpbWl0KCksIChieXRlKSAwKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb246IG9mZnNldCA8IDAKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbOF07CisgICAgICAgICAgICBiLnBvc2l0aW9uKDApOworICAgICAgICAgICAgYi5wdXQoZGF0YSwgLTEsIDIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbjogbGVuZ3RoID4gYXJyYXkubGVuZ3RoIC0gb2Zmc2V0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlWzhdOworICAgICAgICAgICAgYi5wb3NpdGlvbigwKTsKKyAgICAgICAgICAgIGIucHV0KGRhdGEsIDEsIDgpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb246IGxlbmd0aCA+IHJlbWFpbmluZygpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlWzhdOworICAgICAgICAgICAgYi5wb3NpdGlvbihiLmxpbWl0KCkgLSAyKTsKKyAgICAgICAgICAgIGIucHV0KGRhdGEsIDAsIDMpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIEZpbGwgYnVmZmVyIHdpdGggYnl0ZXMgQTAgQTEgQTIgQTMgLi4uCisgICAgICAgIGIucG9zaXRpb24oMCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYi5jYXBhY2l0eSgpOyBpKyspIHsKKyAgICAgICAgICAgIGIucHV0KChieXRlKSAoMHhBMCArIGkpKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYi5wdXQoKGJ5dGUpIDB4RkYpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGIucG9zaXRpb24oMCk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHhBNywgYi5nZXQoNykpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYi5nZXQoMTIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiLmdldCgtMTApOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYi5wb3NpdGlvbigwKTsKKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHhBMCwgYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHhBMSwgYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHhBMiwgYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHhBMywgYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHhBNCwgYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHhBNSwgYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHhBNiwgYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHhBNywgYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHhBOCwgYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHhBOSwgYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHhBQSwgYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHhBQiwgYi5nZXQoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiLmdldCgpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBiLnBvc2l0aW9uKDApOworICAgICAgICBiLm9yZGVyKEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweEEwLCBiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweEExLCBiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweEEyLCBiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweEEzLCBiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweEE0LCBiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweEE1LCBiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweEE2LCBiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweEE3LCBiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweEE4LCBiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweEE5LCBiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweEFBLCBiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweEFCLCBiLmdldCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGIuZ2V0KCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGIucG9zaXRpb24oNik7CisgICAgICAgIGIubGltaXQoMTApOworICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDB4QTYsIGIuZ2V0KCkpOworCisgICAgICAgIC8vIENoZWNrIHNsaWNlZCBidWZmZXIKKyAgICAgICAgYi5wb3NpdGlvbig2KTsKKworICAgICAgICBCeXRlQnVmZmVyIGJiID0gYi5zbGljZSgpOworICAgICAgICBjaGVja0J1ZmZlcihiYik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGJiLnBvc2l0aW9uKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgYmIubGltaXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg0LCBiYi5jYXBhY2l0eSgpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDB4QTYsIGJiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweEE3LCBiYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHhBOCwgYmIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDB4QTksIGJiLmdldCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJiLmdldCgpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBSZXNldCBwb3NpdGlvbiBhbmQgbGltaXQKKyAgICAgICAgYi5wb3NpdGlvbigwKTsKKyAgICAgICAgYi5saW1pdChiLmNhcGFjaXR5KCkpOworCisgICAgICAgIC8vIENoZWNrICdnZXRTaG9ydCcKKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisgICAgICAgIGIucG9zaXRpb24oMCk7CisgICAgICAgIGFzc2VydEVxdWFscygoc2hvcnQpIDB4QTFBMCwgYi5nZXRTaG9ydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgMHhBM0EyLCBiLmdldFNob3J0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKHNob3J0KSAweEE1QTQsIGIuZ2V0U2hvcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoc2hvcnQpIDB4QTdBNiwgYi5nZXRTaG9ydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgMHhBOUE4LCBiLmdldFNob3J0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKHNob3J0KSAweEFCQUEsIGIuZ2V0U2hvcnQoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiYi5nZXRTaG9ydCgpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBiLm9yZGVyKEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICAgICAgYi5wb3NpdGlvbigwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgMHhBMEExLCBiLmdldFNob3J0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKHNob3J0KSAweEEyQTMsIGIuZ2V0U2hvcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoc2hvcnQpIDB4QTRBNSwgYi5nZXRTaG9ydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgMHhBNkE3LCBiLmdldFNob3J0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKHNob3J0KSAweEE4QTksIGIuZ2V0U2hvcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoc2hvcnQpIDB4QUFBQiwgYi5nZXRTaG9ydCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJiLmdldFNob3J0KCk7CisgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gQ2hlY2sgJ2dldEludCcKKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisgICAgICAgIGIucG9zaXRpb24oMCk7CisgICAgICAgIGFzc2VydEVxdWFscygweEEzQTJBMUEwLCBiLmdldEludCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4QTdBNkE1QTQsIGIuZ2V0SW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHhBQkFBQTlBOCwgYi5nZXRJbnQoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiYi5nZXRJbnQoKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuQklHX0VORElBTik7CisgICAgICAgIGIucG9zaXRpb24oMCk7CisgICAgICAgIGFzc2VydEVxdWFscygweEEwQTFBMkEzLCBiLmdldEludCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4QTRBNUE2QTcsIGIuZ2V0SW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHhBOEE5QUFBQiwgYi5nZXRJbnQoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiYi5nZXRJbnQoKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gQ2hlY2sgJ2dldEZsb2F0JworICAgICAgICBiLm9yZGVyKEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKTsKKyAgICAgICAgYi5wb3NpdGlvbigwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4QTNBMkExQTAsIEZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKGIuZ2V0RmxvYXQoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHhBN0E2QTVBNCwgRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMoYi5nZXRGbG9hdCgpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygweEFCQUFBOUE4LCBGbG9hdC5mbG9hdFRvUmF3SW50Qml0cyhiLmdldEZsb2F0KCkpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGIuZ2V0RmxvYXQoKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuQklHX0VORElBTik7CisgICAgICAgIGIucG9zaXRpb24oMCk7CisgICAgICAgIGFzc2VydEVxdWFscygweEEwQTFBMkEzLCBGbG9hdC5mbG9hdFRvUmF3SW50Qml0cyhiLmdldEZsb2F0KCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4QTRBNUE2QTcsIEZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKGIuZ2V0RmxvYXQoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHhBOEE5QUFBQiwgRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMoYi5nZXRGbG9hdCgpKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiLmdldEZsb2F0KCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIENoZWNrICdnZXREb3VibGUoaW50IHBvc2l0aW9uKScKKyAgICAgICAgYi5vcmRlcihCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisgICAgICAgIGFzc2VydEVxdWFscygweEE3QTZBNUE0QTNBMkExQTBMLCBEb3VibGUuZG91YmxlVG9SYXdMb25nQml0cyhiLmdldERvdWJsZSgwKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHhBOEE3QTZBNUE0QTNBMkExTCwgRG91YmxlLmRvdWJsZVRvUmF3TG9uZ0JpdHMoYi5nZXREb3VibGUoMSkpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGIuZ2V0RG91YmxlKC0xKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYi5nZXREb3VibGUoNSk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBiLm9yZGVyKEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4QTBBMUEyQTNBNEE1QTZBN0wsIERvdWJsZS5kb3VibGVUb1Jhd0xvbmdCaXRzKGIuZ2V0RG91YmxlKDApKSk7CisgICAgICAgIGFzc2VydEVxdWFscygweEExQTJBM0E0QTVBNkE3QThMLCBEb3VibGUuZG91YmxlVG9SYXdMb25nQml0cyhiLmdldERvdWJsZSgxKSkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYi5nZXREb3VibGUoLTEpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiLmdldERvdWJsZSg1KTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIFNsaWNlIGFuZCBjaGVjayAnZ2V0SW50JworICAgICAgICBiLnBvc2l0aW9uKDEpOworICAgICAgICBiLmxpbWl0KDUpOworICAgICAgICBiLm9yZGVyKEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKTsKKyAgICAgICAgYmIgPSBiLnNsaWNlKCk7CisgICAgICAgIGFzc2VydEVxdWFscyg0LCBiYi5jYXBhY2l0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJ5dGVPcmRlci5CSUdfRU5ESUFOLCBiYi5vcmRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4QTFBMkEzQTQsIGJiLmdldEludCgwKSk7CisgICAgICAgIGJiLm9yZGVyKEJ5dGVPcmRlci5MSVRUTEVfRU5ESUFOKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4QTRBM0EyQTEsIGJiLmdldEludCgwKSk7CisKKyAgICAgICAgYmIub3JkZXIoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pOworICAgICAgICBTaG9ydEJ1ZmZlciBzYiA9IGJiLmFzU2hvcnRCdWZmZXIoKTsKKworICAgICAgICBjaGVja0J1ZmZlcihzYik7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBzYi5jYXBhY2l0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgMHhBMkExLCBzYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoc2hvcnQpIDB4QTRBMywgc2IuZ2V0KCkpOworCisgICAgICAgIGJiLm9yZGVyKEJ5dGVPcmRlci5CSUdfRU5ESUFOKTsKKyAgICAgICAgc2IgPSBiYi5hc1Nob3J0QnVmZmVyKCk7CisKKyAgICAgICAgY2hlY2tCdWZmZXIoc2IpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgc2IuY2FwYWNpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoc2hvcnQpIDB4QTFBMiwgc2IuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKHNob3J0KSAweEEzQTQsIHNiLmdldCgpKTsKKworICAgICAgICBiYi5vcmRlcihCeXRlT3JkZXIuTElUVExFX0VORElBTik7CisgICAgICAgIEludEJ1ZmZlciBpYiA9IGJiLmFzSW50QnVmZmVyKCk7CisKKyAgICAgICAgY2hlY2tCdWZmZXIoaWIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaWIuY2FwYWNpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygweEE0QTNBMkExLCBpYi5nZXQoKSk7CisKKyAgICAgICAgYmIub3JkZXIoQnl0ZU9yZGVyLkJJR19FTkRJQU4pOworICAgICAgICBpYiA9IGJiLmFzSW50QnVmZmVyKCk7CisKKyAgICAgICAgY2hlY2tCdWZmZXIoaWIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaWIuY2FwYWNpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygweEExQTJBM0E0LCBpYi5nZXQoKSk7CisKKyAgICAgICAgYmIub3JkZXIoQnl0ZU9yZGVyLkxJVFRMRV9FTkRJQU4pOworICAgICAgICBGbG9hdEJ1ZmZlciBmYiA9IGJiLmFzRmxvYXRCdWZmZXIoKTsKKworICAgICAgICBjaGVja0J1ZmZlcihmYik7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBmYi5jYXBhY2l0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4QTRBM0EyQTEsIEZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKGZiLmdldCgpKSk7CisKKyAgICAgICAgYmIub3JkZXIoQnl0ZU9yZGVyLkJJR19FTkRJQU4pOworICAgICAgICBmYiA9IGJiLmFzRmxvYXRCdWZmZXIoKTsKKworICAgICAgICBjaGVja0J1ZmZlcihmYik7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBmYi5jYXBhY2l0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDB4QTFBMkEzQTQsIEZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKGZiLmdldCgpKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNob3J0QnVmZmVyVGVzdChTaG9ydEJ1ZmZlciBzYikgeworICAgICAgICBjaGVja0J1ZmZlcihzYik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNiLnB1dCgtMSwgKHNob3J0KSAwKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzYi5wdXQoc2IubGltaXQoKSwgKHNob3J0KSAwKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb246IG9mZnNldCA8IDAKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNob3J0W10gZGF0YSA9IG5ldyBzaG9ydFs4XTsKKyAgICAgICAgICAgIHNiLnBvc2l0aW9uKDApOworICAgICAgICAgICAgc2IucHV0KGRhdGEsIC0xLCAyKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb246IGxlbmd0aCA+IGFycmF5Lmxlbmd0aCAtIG9mZnNldAorICAgICAgICB0cnkgeworICAgICAgICAgICAgc2hvcnRbXSBkYXRhID0gbmV3IHNob3J0WzhdOworICAgICAgICAgICAgc2IucG9zaXRpb24oMCk7CisgICAgICAgICAgICBzYi5wdXQoZGF0YSwgMSwgOCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBCdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbjogbGVuZ3RoID4gcmVtYWluaW5nKCkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNob3J0W10gZGF0YSA9IG5ldyBzaG9ydFs4XTsKKyAgICAgICAgICAgIHNiLnBvc2l0aW9uKHNiLmxpbWl0KCkgLSAyKTsKKyAgICAgICAgICAgIHNiLnB1dChkYXRhLCAwLCAzKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBzaG9ydFtdIGRhdGEgPSB7MCwgMTAsIDIwLCAzMCwgNDAsIDUwLCA2MCwgNzB9OworICAgICAgICBzYi5wb3NpdGlvbigwKTsKKyAgICAgICAgc2IucHV0KGRhdGEpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzYi5nZXQoKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEJ1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgc2IucG9zaXRpb24oMCk7CisgICAgICAgIGFzc2VydEVxdWFscygoc2hvcnQpIDAsIHNiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgMTAsIHNiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgMjAsIHNiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgMzAsIHNiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgNDAsIHNiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgNTAsIHNiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgNjAsIHNiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgNzAsIHNiLmdldCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNiLmdldCgpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgc2IucG9zaXRpb24oMSk7CisgICAgICAgIHNiLnB1dCgoc2hvcnQpIDExKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgMTEsIHNiLmdldCgxKSk7CisKKyAgICAgICAgc2hvcnRbXSBzczEgPSB7MzMsIDQ0LCA1NSwgNjZ9OworICAgICAgICBzYi5wb3NpdGlvbigzKTsKKyAgICAgICAgc2IucHV0KHNzMSk7CisgICAgICAgIHNiLnBvc2l0aW9uKDApOworICAgICAgICBhc3NlcnRFcXVhbHMoKHNob3J0KSAwLCBzYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoc2hvcnQpIDExLCBzYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoc2hvcnQpIDIwLCBzYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoc2hvcnQpIDMzLCBzYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoc2hvcnQpIDQ0LCBzYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoc2hvcnQpIDU1LCBzYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoc2hvcnQpIDY2LCBzYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoc2hvcnQpIDcwLCBzYi5nZXQoKSk7CisKKyAgICAgICAgc2hvcnRbXSBzczIgPSB7MTAsIDIyLCAzMH07CisgICAgICAgIHNiLnBvc2l0aW9uKDIpOworICAgICAgICBzYi5wdXQoc3MyLCAxLCAxKTsKKyAgICAgICAgc2IucG9zaXRpb24oMCk7CisgICAgICAgIGFzc2VydEVxdWFscygoc2hvcnQpIDAsIHNiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgMTEsIHNiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgMjIsIHNiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgMzMsIHNiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgNDQsIHNiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgNTUsIHNiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgNjYsIHNiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChzaG9ydCkgNzAsIHNiLmdldCgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgaW50QnVmZmVyVGVzdChJbnRCdWZmZXIgaWIpIHsKKyAgICAgICAgY2hlY2tCdWZmZXIoaWIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpYi5wdXQoLTEsIChpbnQpIDApOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGliLnB1dChpYi5saW1pdCgpLCAoaW50KSAwKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb246IG9mZnNldCA8IDAKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludFtdIGRhdGEgPSBuZXcgaW50WzhdOworICAgICAgICAgICAgaWIucG9zaXRpb24oMCk7CisgICAgICAgICAgICBpYi5wdXQoZGF0YSwgLTEsIDIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbjogbGVuZ3RoID4gYXJyYXkubGVuZ3RoIC0gb2Zmc2V0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnRbXSBkYXRhID0gbmV3IGludFs4XTsKKyAgICAgICAgICAgIGliLnBvc2l0aW9uKDApOworICAgICAgICAgICAgaWIucHV0KGRhdGEsIDEsIDgpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb246IGxlbmd0aCA+IHJlbWFpbmluZygpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnRbXSBkYXRhID0gbmV3IGludFs4XTsKKyAgICAgICAgICAgIGliLnBvc2l0aW9uKGliLmxpbWl0KCkgLSAyKTsKKyAgICAgICAgICAgIGliLnB1dChkYXRhLCAwLCAzKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBpbnRbXSBkYXRhID0gezAsIDEwLCAyMCwgMzAsIDQwLCA1MCwgNjAsIDcwfTsKKyAgICAgICAgaWIucG9zaXRpb24oMCk7CisgICAgICAgIGliLnB1dChkYXRhKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWIuZ2V0KCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGliLnBvc2l0aW9uKDApOworICAgICAgICBhc3NlcnRFcXVhbHMoKGludCkgMCwgaWIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGludCkgMTAsIGliLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChpbnQpIDIwLCBpYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoaW50KSAzMCwgaWIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGludCkgNDAsIGliLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChpbnQpIDUwLCBpYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoaW50KSA2MCwgaWIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGludCkgNzAsIGliLmdldCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGliLmdldCgpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgaWIucG9zaXRpb24oMSk7CisgICAgICAgIGliLnB1dCgoaW50KSAxMSk7CisgICAgICAgIGFzc2VydEVxdWFscygoaW50KSAxMSwgaWIuZ2V0KDEpKTsKKworICAgICAgICBpbnRbXSBzczEgPSB7MzMsIDQ0LCA1NSwgNjZ9OworICAgICAgICBpYi5wb3NpdGlvbigzKTsKKyAgICAgICAgaWIucHV0KHNzMSk7CisgICAgICAgIGliLnBvc2l0aW9uKDApOworICAgICAgICBhc3NlcnRFcXVhbHMoKGludCkgMCwgaWIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGludCkgMTEsIGliLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChpbnQpIDIwLCBpYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoaW50KSAzMywgaWIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGludCkgNDQsIGliLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChpbnQpIDU1LCBpYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoaW50KSA2NiwgaWIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGludCkgNzAsIGliLmdldCgpKTsKKworICAgICAgICBpbnRbXSBzczIgPSB7MTAsIDIyLCAzMH07CisgICAgICAgIGliLnBvc2l0aW9uKDIpOworICAgICAgICBpYi5wdXQoc3MyLCAxLCAxKTsKKyAgICAgICAgaWIucG9zaXRpb24oMCk7CisgICAgICAgIGFzc2VydEVxdWFscygoaW50KSAwLCBpYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoaW50KSAxMSwgaWIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGludCkgMjIsIGliLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChpbnQpIDMzLCBpYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoaW50KSA0NCwgaWIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGludCkgNTUsIGliLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChpbnQpIDY2LCBpYi5nZXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoaW50KSA3MCwgaWIuZ2V0KCkpOworICAgIH0KKworICAgIHZvaWQgZmxvYXRCdWZmZXJUZXN0KEZsb2F0QnVmZmVyIGZiKSB7CisgICAgICAgIGNoZWNrQnVmZmVyKGZiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmIucHV0KC0xLCAoZmxvYXQpIDApOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZiLnB1dChmYi5saW1pdCgpLCAoZmxvYXQpIDApOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbjogb2Zmc2V0IDwgMAorICAgICAgICB0cnkgeworICAgICAgICAgICAgZmxvYXRbXSBkYXRhID0gbmV3IGZsb2F0WzhdOworICAgICAgICAgICAgZmIucG9zaXRpb24oMCk7CisgICAgICAgICAgICBmYi5wdXQoZGF0YSwgLTEsIDIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbjogbGVuZ3RoID4gYXJyYXkubGVuZ3RoIC0gb2Zmc2V0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmbG9hdFtdIGRhdGEgPSBuZXcgZmxvYXRbOF07CisgICAgICAgICAgICBmYi5wb3NpdGlvbigwKTsKKyAgICAgICAgICAgIGZiLnB1dChkYXRhLCAxLCA4KTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uOiBsZW5ndGggPiByZW1haW5pbmcoKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZmxvYXRbXSBkYXRhID0gbmV3IGZsb2F0WzhdOworICAgICAgICAgICAgZmIucG9zaXRpb24oZmIubGltaXQoKSAtIDIpOworICAgICAgICAgICAgZmIucHV0KGRhdGEsIDAsIDMpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGZsb2F0W10gZGF0YSA9IHswLCAxMCwgMjAsIDMwLCA0MCwgNTAsIDYwLCA3MH07CisgICAgICAgIGZiLnBvc2l0aW9uKDApOworICAgICAgICBmYi5wdXQoZGF0YSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZiLmdldCgpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBmYi5wb3NpdGlvbigwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChmbG9hdCkgMCwgZmIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGZsb2F0KSAxMCwgZmIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGZsb2F0KSAyMCwgZmIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGZsb2F0KSAzMCwgZmIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGZsb2F0KSA0MCwgZmIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGZsb2F0KSA1MCwgZmIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGZsb2F0KSA2MCwgZmIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGZsb2F0KSA3MCwgZmIuZ2V0KCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmIuZ2V0KCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBmYi5wb3NpdGlvbigxKTsKKyAgICAgICAgZmIucHV0KChmbG9hdCkgMTEpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGZsb2F0KSAxMSwgZmIuZ2V0KDEpKTsKKworICAgICAgICBmbG9hdFtdIHNzMSA9IHszMywgNDQsIDU1LCA2Nn07CisgICAgICAgIGZiLnBvc2l0aW9uKDMpOworICAgICAgICBmYi5wdXQoc3MxKTsKKyAgICAgICAgZmIucG9zaXRpb24oMCk7CisgICAgICAgIGFzc2VydEVxdWFscygoZmxvYXQpIDAsIGZiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChmbG9hdCkgMTEsIGZiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChmbG9hdCkgMjAsIGZiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChmbG9hdCkgMzMsIGZiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChmbG9hdCkgNDQsIGZiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChmbG9hdCkgNTUsIGZiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChmbG9hdCkgNjYsIGZiLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChmbG9hdCkgNzAsIGZiLmdldCgpKTsKKworICAgICAgICBmbG9hdFtdIHNzMiA9IHsxMCwgMjIsIDMwfTsKKyAgICAgICAgZmIucG9zaXRpb24oMik7CisgICAgICAgIGZiLnB1dChzczIsIDEsIDEpOworICAgICAgICBmYi5wb3NpdGlvbigwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChmbG9hdCkgMCwgZmIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGZsb2F0KSAxMSwgZmIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGZsb2F0KSAyMiwgZmIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGZsb2F0KSAzMywgZmIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGZsb2F0KSA0NCwgZmIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGZsb2F0KSA1NSwgZmIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGZsb2F0KSA2NiwgZmIuZ2V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGZsb2F0KSA3MCwgZmIuZ2V0KCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL09sZERpcmVjdEludEJ1ZmZlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL09sZERpcmVjdEludEJ1ZmZlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40Mjc0ZjQyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vT2xkRGlyZWN0SW50QnVmZmVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW87CisKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLkJ5dGVPcmRlcjsKK2ltcG9ydCBqYXZhLm5pby5JbnRCdWZmZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgT2xkRGlyZWN0SW50QnVmZmVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFJlZ3Jlc3Npb24gZm9yIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9MzI3OQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RQdXRXaGVuT2Zmc2V0SXNOb25aZXJvKCkgeworICAgICAgICBCeXRlQnVmZmVyIGJ5dGVCdWZmZXIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlRGlyZWN0KDQwKTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5vcmRlcihCeXRlT3JkZXIubmF0aXZlT3JkZXIoKSk7CisgICAgICAgIEludEJ1ZmZlciBpbnRCdWZmZXIgPSBieXRlQnVmZmVyLmFzSW50QnVmZmVyKCk7CisKKyAgICAgICAgaW50W10gc291cmNlID0geyAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LCAxNiB9OworCisgICAgICAgIGludEJ1ZmZlci5wdXQoc291cmNlLCAyLCAyKTsKKyAgICAgICAgaW50QnVmZmVyLnB1dChzb3VyY2UsIDQsIDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgaW50QnVmZmVyLmdldCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBpbnRCdWZmZXIuZ2V0KDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDYsIGludEJ1ZmZlci5nZXQoMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoNywgaW50QnVmZmVyLmdldCgzKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vT2xkRGlyZWN0U2hvcnRCdWZmZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9PbGREaXJlY3RTaG9ydEJ1ZmZlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YTkzODU3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vT2xkRGlyZWN0U2hvcnRCdWZmZXJUZXN0LmphdmEKQEAgLTAsMCArMSw0MiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pbzsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uQnl0ZU9yZGVyOworaW1wb3J0IGphdmEubmlvLlNob3J0QnVmZmVyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIE9sZERpcmVjdFNob3J0QnVmZmVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFJlZ3Jlc3Npb24gZm9yIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9MzI3OQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RQdXRXaGVuT2Zmc2V0SXNOb25aZXJvKCkgeworICAgICAgICBCeXRlQnVmZmVyIGJ5dGVCdWZmZXIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlRGlyZWN0KDQwKTsKKyAgICAgICAgYnl0ZUJ1ZmZlci5vcmRlcihCeXRlT3JkZXIubmF0aXZlT3JkZXIoKSk7CisgICAgICAgIFNob3J0QnVmZmVyIHNob3J0QnVmZmVyID0gYnl0ZUJ1ZmZlci5hc1Nob3J0QnVmZmVyKCk7CisKKyAgICAgICAgc2hvcnRbXSBzb3VyY2UgPSB7IDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsIDE2IH07CisKKyAgICAgICAgc2hvcnRCdWZmZXIucHV0KHNvdXJjZSwgMiwgMik7CisgICAgICAgIHNob3J0QnVmZmVyLnB1dChzb3VyY2UsIDQsIDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgc2hvcnRCdWZmZXIuZ2V0KDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIHNob3J0QnVmZmVyLmdldCgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg2LCBzaG9ydEJ1ZmZlci5nZXQoMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoNywgc2hvcnRCdWZmZXIuZ2V0KDMpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFubmVscy9DaGFubmVsc1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYW5uZWxzL0NoYW5uZWxzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRiYmYzYTkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFubmVscy9DaGFubmVsc1Rlc3QuamF2YQpAQCAtMCwwICsxLDYwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYW5uZWxzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkNoYW5uZWxzOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLklsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuUGlwZTsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5Xcml0YWJsZUJ5dGVDaGFubmVsOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIENoYW5uZWxzVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdHJlYW1Ob25CbG9ja2luZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFBpcGUuU291cmNlQ2hhbm5lbCBzb3VyY2VDaGFubmVsID0gY3JlYXRlTm9uQmxvY2tpbmdDaGFubmVsKCJhYmMiLmdldEJ5dGVzKCJVVEYtOCIpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENoYW5uZWxzLm5ld0lucHV0U3RyZWFtKHNvdXJjZUNoYW5uZWwpLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBmYWlscyBvbiB0aGUgUkkgd2hpY2ggdmlvbGF0ZXMgaXRzIG93biBwcm9taXNlIHRvIHRocm93IHdoZW4KKyAgICAgKiByZWFkIGluIG5vbi1ibG9ja2luZyBtb2RlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkZXJOb25CbG9ja2luZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFBpcGUuU291cmNlQ2hhbm5lbCBzb3VyY2VDaGFubmVsID0gY3JlYXRlTm9uQmxvY2tpbmdDaGFubmVsKCJhYmMiLmdldEJ5dGVzKCJVVEYtOCIpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENoYW5uZWxzLm5ld1JlYWRlcihzb3VyY2VDaGFubmVsLCAiVVRGLTgiKS5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxCbG9ja2luZ01vZGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgUGlwZS5Tb3VyY2VDaGFubmVsIGNyZWF0ZU5vbkJsb2NraW5nQ2hhbm5lbChieXRlW10gY29udGVudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUGlwZSBwaXBlID0gUGlwZS5vcGVuKCk7CisgICAgICAgIFdyaXRhYmxlQnl0ZUNoYW5uZWwgc2lua0NoYW5uZWwgPSBwaXBlLnNpbmsoKTsKKyAgICAgICAgc2lua0NoYW5uZWwud3JpdGUoQnl0ZUJ1ZmZlci53cmFwKGNvbnRlbnQpKTsKKyAgICAgICAgUGlwZS5Tb3VyY2VDaGFubmVsIHNvdXJjZUNoYW5uZWwgPSBwaXBlLnNvdXJjZSgpOworICAgICAgICBzb3VyY2VDaGFubmVsLmNvbmZpZ3VyZUJsb2NraW5nKGZhbHNlKTsKKyAgICAgICAgcmV0dXJuIHNvdXJjZUNoYW5uZWw7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFubmVscy9EYXRhZ3JhbUNoYW5uZWxUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFubmVscy9EYXRhZ3JhbUNoYW5uZWxUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTM3NTdkMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYW5uZWxzL0RhdGFncmFtQ2hhbm5lbFRlc3QuamF2YQpAQCAtMCwwICsxLDU4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYW5uZWxzOworCitpbXBvcnQgamF2YS5uZXQuRGF0YWdyYW1Tb2NrZXQ7CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5EYXRhZ3JhbUNoYW5uZWw7CisKK3B1YmxpYyBjbGFzcyBEYXRhZ3JhbUNoYW5uZWxUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfaW50b1JlYWRPbmx5Qnl0ZUFycmF5cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBCeXRlQnVmZmVyIHJlYWRPbmx5ID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxKS5hc1JlYWRPbmx5QnVmZmVyKCk7CisgICAgICAgIERhdGFncmFtU29ja2V0IGRzID0gbmV3IERhdGFncmFtU29ja2V0KDApOworICAgICAgICBEYXRhZ3JhbUNoYW5uZWwgZGMgPSBEYXRhZ3JhbUNoYW5uZWwub3BlbigpOworICAgICAgICBkYy5jb25uZWN0KGRzLmdldExvY2FsU29ja2V0QWRkcmVzcygpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRjLnJlYWQocmVhZE9ubHkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZGMucmVhZChuZXcgQnl0ZUJ1ZmZlcltdIHsgcmVhZE9ubHkgfSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkYy5yZWFkKG5ldyBCeXRlQnVmZmVyW10geyByZWFkT25seSB9LCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTE2NTc5CisgICAgcHVibGljIHZvaWQgdGVzdE5vbkJsb2NraW5nUmVjdigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEYXRhZ3JhbUNoYW5uZWwgZGMgPSBEYXRhZ3JhbUNoYW5uZWwub3BlbigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGMuY29uZmlndXJlQmxvY2tpbmcoZmFsc2UpOworICAgICAgICAgICAgZGMuc29ja2V0KCkuYmluZChudWxsKTsKKyAgICAgICAgICAgIC8vIFNob3VsZCByZXR1cm4gaW1tZWRpYXRlbHksIHNpbmNlIHdlJ3JlIG5vbi1ibG9ja2luZy4KKyAgICAgICAgICAgIGFzc2VydE51bGwoZGMucmVjZWl2ZShCeXRlQnVmZmVyLmFsbG9jYXRlKDIwNDgpKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBkYy5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhbm5lbHMvRmlsZUNoYW5uZWxUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFubmVscy9GaWxlQ2hhbm5lbFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MTVhZTBhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhbm5lbHMvRmlsZUNoYW5uZWxUZXN0LmphdmEKQEAgLTAsMCArMSwxMTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhbm5lbHM7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWw7CitpbXBvcnQgbGliY29yZS5pby5Jb1V0aWxzOworCitwdWJsaWMgY2xhc3MgRmlsZUNoYW5uZWxUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZE9ubHlCeXRlQXJyYXlzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVCdWZmZXIgcmVhZE9ubHkgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEpLmFzUmVhZE9ubHlCdWZmZXIoKTsKKyAgICAgICAgRmlsZSB0bXAgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJGaWxlQ2hhbm5lbFRlc3QiLCAidG1wIik7CisKKyAgICAgICAgLy8gWW91IGNhbid0IHJlYWQgaW50byBhIHJlYWQtb25seSBidWZmZXIuLi4KKyAgICAgICAgRmlsZUNoYW5uZWwgZmMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKHRtcCkuZ2V0Q2hhbm5lbCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmMucmVhZChyZWFkT25seSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYy5yZWFkKG5ldyBCeXRlQnVmZmVyW10geyByZWFkT25seSB9KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZjLnJlYWQobmV3IEJ5dGVCdWZmZXJbXSB7IHJlYWRPbmx5IH0sIDAsIDEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZmMucmVhZChyZWFkT25seSwgMEwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBmYy5jbG9zZSgpOworCisKKyAgICAgICAgLy8gQnV0IHlvdSBjYW4gd3JpdGUgZnJvbSBhIHJlYWQtb25seSBidWZmZXIuLi4KKyAgICAgICAgZmMgPSBuZXcgRmlsZU91dHB1dFN0cmVhbSh0bXApLmdldENoYW5uZWwoKTsKKyAgICAgICAgZmMud3JpdGUocmVhZE9ubHkpOworICAgICAgICBmYy53cml0ZShuZXcgQnl0ZUJ1ZmZlcltdIHsgcmVhZE9ubHkgfSk7CisgICAgICAgIGZjLndyaXRlKG5ldyBCeXRlQnVmZmVyW10geyByZWFkT25seSB9LCAwLCAxKTsKKyAgICAgICAgZmMud3JpdGUocmVhZE9ubHksIDBMKTsKKyAgICAgICAgZmMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWR2KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgdG1wID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiRmlsZUNoYW5uZWxUZXN0IiwgInRtcCIpOworICAgICAgICBGaWxlQ2hhbm5lbCBmYyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKHRtcCkuZ2V0Q2hhbm5lbCgpOworICAgICAgICBmYy53cml0ZShCeXRlQnVmZmVyLndyYXAoImFiY2RBQkNEIi5nZXRCeXRlcygiVVMtQVNDSUkiKSkpOworICAgICAgICBmYy5jbG9zZSgpOworICAgICAgICAvLyBDaGVjayB0aGF0IGJvdGggZGlyZWN0IGFuZCBub24tZGlyZWN0IGJ1ZmZlcnMgd29yay4KKyAgICAgICAgZmMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKHRtcCkuZ2V0Q2hhbm5lbCgpOworICAgICAgICBCeXRlQnVmZmVyW10gYnVmZmVycyA9IG5ldyBCeXRlQnVmZmVyW10geyBCeXRlQnVmZmVyLmFsbG9jYXRlRGlyZWN0KDQpLCBCeXRlQnVmZmVyLmFsbG9jYXRlKDQpIH07CisgICAgICAgIGFzc2VydEVxdWFscyg4LCBmYy5yZWFkKGJ1ZmZlcnMpKTsKKyAgICAgICAgZmMuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDgsIGJ1ZmZlcnNbMF0ubGltaXQoKSArIGJ1ZmZlcnNbMV0ubGltaXQoKSk7CisgICAgICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlWzRdOworICAgICAgICBidWZmZXJzWzBdLmZsaXAoKTsKKyAgICAgICAgYnVmZmVyc1swXS5nZXQoYnl0ZXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFiY2QiLCBuZXcgU3RyaW5nKGJ5dGVzLCAiVVMtQVNDSUkiKSk7CisgICAgICAgIGJ1ZmZlcnNbMV0uZmxpcCgpOworICAgICAgICBidWZmZXJzWzFdLmdldChieXRlcyk7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJDRCIsIG5ldyBTdHJpbmcoYnl0ZXMsICJVUy1BU0NJSSIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRldigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGaWxlIHRtcCA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoIkZpbGVDaGFubmVsVGVzdCIsICJ0bXAiKTsKKyAgICAgICAgRmlsZUNoYW5uZWwgZmMgPSBuZXcgRmlsZU91dHB1dFN0cmVhbSh0bXApLmdldENoYW5uZWwoKTsKKyAgICAgICAgLy8gQ2hlY2sgdGhhdCBib3RoIGRpcmVjdCBhbmQgbm9uLWRpcmVjdCBidWZmZXJzIHdvcmsuCisgICAgICAgIEJ5dGVCdWZmZXJbXSBidWZmZXJzID0gbmV3IEJ5dGVCdWZmZXJbXSB7IEJ5dGVCdWZmZXIuYWxsb2NhdGVEaXJlY3QoNCksIEJ5dGVCdWZmZXIuYWxsb2NhdGUoNCkgfTsKKyAgICAgICAgYnVmZmVyc1swXS5wdXQoImFiY2QiLmdldEJ5dGVzKCJVUy1BU0NJSSIpKS5mbGlwKCk7CisgICAgICAgIGJ1ZmZlcnNbMV0ucHV0KCJBQkNEIi5nZXRCeXRlcygiVVMtQVNDSUkiKSkuZmxpcCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoOCwgZmMud3JpdGUoYnVmZmVycykpOworICAgICAgICBmYy5jbG9zZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoOCwgdG1wLmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhYmNkQUJDRCIsIG5ldyBTdHJpbmcoSW9VdGlscy5yZWFkRmlsZUFzU3RyaW5nKHRtcC5nZXRQYXRoKCkpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9hcHBlbmQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZSB0bXAgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJGaWxlQ2hhbm5lbFRlc3QiLCAidG1wIik7CisgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gZm9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0odG1wLCB0cnVlKTsKKyAgICAgICAgRmlsZUNoYW5uZWwgZmMgPSBmb3MuZ2V0Q2hhbm5lbCgpOworCisgICAgICAgIGZjLndyaXRlKEJ5dGVCdWZmZXIud3JhcCgiaGVsbG8iLmdldEJ5dGVzKCJVUy1BU0NJSSIpKSk7CisgICAgICAgIGZjLnBvc2l0aW9uKDApOworICAgICAgICAvLyBUaGUgUkkgcmVwb3J0cyB3aGF0ZXZlciBwb3NpdGlvbiB5b3Ugc2V0Li4uCisgICAgICAgIGFzc2VydEVxdWFscygwLCBmYy5wb3NpdGlvbigpKTsKKyAgICAgICAgLy8gLi4uYnV0IHdyaXRlcyB0byB0aGUgZW5kIG9mIHRoZSBmaWxlLgorICAgICAgICBmYy53cml0ZShCeXRlQnVmZmVyLndyYXAoIiB3b3JsZCIuZ2V0Qnl0ZXMoIlVTLUFTQ0lJIikpKTsKKyAgICAgICAgZm9zLmNsb3NlKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJoZWxsbyB3b3JsZCIsIG5ldyBTdHJpbmcoSW9VdGlscy5yZWFkRmlsZUFzU3RyaW5nKHRtcC5nZXRQYXRoKCkpKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhbm5lbHMvT2xkRmlsZUNoYW5uZWxUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFubmVscy9PbGRGaWxlQ2hhbm5lbFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZTYxNmIxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhbm5lbHMvT2xkRmlsZUNoYW5uZWxUZXN0LmphdmEKQEAgLTAsMCArMSwxMDc4IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhbm5lbHM7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLk1hcHBlZEJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5EYXRhZ3JhbUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUxvY2s7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuTm9uV3JpdGFibGVDaGFubmVsRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLk92ZXJsYXBwaW5nRmlsZUxvY2tFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuUmVhZGFibGVCeXRlQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5Xcml0YWJsZUJ5dGVDaGFubmVsOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgT2xkRmlsZUNoYW5uZWxUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENBUEFDSVRZID0gMTAwOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENPTlRFTlQgPSAiTVlURVNUU1RSSU5HIG5lZWRzIHRvIGJlIGEgbGl0dGxlIGxvbmciOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIFRFU1RfQllURVM7CisKKyAgICBzdGF0aWMgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgVEVTVF9CWVRFUyA9ICJ0ZXN0Ii5nZXRCeXRlcygiaXNvODg1OS0xIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENPTlRFTlRfTEVOR1RIID0gQ09OVEVOVC5sZW5ndGgoKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT05URU5UX0FTX0JZVEVTID0gQ09OVEVOVC5nZXRCeXRlcygpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENPTlRFTlRfQVNfQllURVNfTEVOR1RIID0gQ09OVEVOVF9BU19CWVRFUy5sZW5ndGg7CisKKyAgICBwcml2YXRlIEZpbGVDaGFubmVsIHJlYWRPbmx5RmlsZUNoYW5uZWw7CisKKyAgICBwcml2YXRlIEZpbGVDaGFubmVsIHdyaXRlT25seUZpbGVDaGFubmVsOworCisgICAgcHJpdmF0ZSBGaWxlQ2hhbm5lbCByZWFkV3JpdGVGaWxlQ2hhbm5lbDsKKworICAgIHByaXZhdGUgRmlsZSBmaWxlT2ZSZWFkT25seUZpbGVDaGFubmVsOworCisgICAgcHJpdmF0ZSBGaWxlIGZpbGVPZldyaXRlT25seUZpbGVDaGFubmVsOworCisgICAgcHJpdmF0ZSBGaWxlIGZpbGVPZlJlYWRXcml0ZUZpbGVDaGFubmVsOworCisgICAgLy8gdG8gcmVhZCBjb250ZW50IGZyb20gRmlsZUNoYW5uZWwKKyAgICBwcml2YXRlIEZpbGVJbnB1dFN0cmVhbSBmaXM7CisKKyAgICBwcml2YXRlIEZpbGVMb2NrIGZpbGVMb2NrOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmlsZU9mUmVhZE9ubHlGaWxlQ2hhbm5lbCA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoCisgICAgICAgICAgICAgICAgIkZpbGVfb2ZfcmVhZE9ubHlGaWxlQ2hhbm5lbCIsICJ0bXAiKTsKKyAgICAgICAgZmlsZU9mUmVhZE9ubHlGaWxlQ2hhbm5lbC5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgZmlsZU9mV3JpdGVPbmx5RmlsZUNoYW5uZWwgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKAorICAgICAgICAgICAgICAgICJGaWxlX29mX3dyaXRlT25seUZpbGVDaGFubmVsIiwgInRtcCIpOworICAgICAgICBmaWxlT2ZXcml0ZU9ubHlGaWxlQ2hhbm5lbC5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgZmlsZU9mUmVhZFdyaXRlRmlsZUNoYW5uZWwgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKAorICAgICAgICAgICAgICAgICJGaWxlX29mX3JlYWRXcml0ZUZpbGVDaGFubmVsIiwgInRtcCIpOworICAgICAgICBmaWxlT2ZSZWFkV3JpdGVGaWxlQ2hhbm5lbC5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgZmlzID0gbnVsbDsKKyAgICAgICAgZmlsZUxvY2sgPSBudWxsOworICAgICAgICByZWFkT25seUZpbGVDaGFubmVsID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlT2ZSZWFkT25seUZpbGVDaGFubmVsKQorICAgICAgICAgICAgICAgIC5nZXRDaGFubmVsKCk7CisgICAgICAgIHdyaXRlT25seUZpbGVDaGFubmVsID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZU9mV3JpdGVPbmx5RmlsZUNoYW5uZWwpCisgICAgICAgICAgICAgICAgLmdldENoYW5uZWwoKTsKKyAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwgPSBuZXcgUmFuZG9tQWNjZXNzRmlsZShmaWxlT2ZSZWFkV3JpdGVGaWxlQ2hhbm5lbCwKKyAgICAgICAgICAgICAgICAicnciKS5nZXRDaGFubmVsKCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIGlmIChudWxsICE9IHJlYWRPbmx5RmlsZUNoYW5uZWwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmVhZE9ubHlGaWxlQ2hhbm5lbC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAobnVsbCAhPSB3cml0ZU9ubHlGaWxlQ2hhbm5lbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAobnVsbCAhPSByZWFkV3JpdGVGaWxlQ2hhbm5lbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAobnVsbCAhPSBmaXMpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZmlzLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gZG8gbm90aGluZworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKG51bGwgIT0gZmlsZUxvY2spIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZmlsZUxvY2sucmVsZWFzZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChudWxsICE9IGZpbGVPZlJlYWRPbmx5RmlsZUNoYW5uZWwpIHsKKyAgICAgICAgICAgIGZpbGVPZlJlYWRPbmx5RmlsZUNoYW5uZWwuZGVsZXRlKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG51bGwgIT0gZmlsZU9mV3JpdGVPbmx5RmlsZUNoYW5uZWwpIHsKKyAgICAgICAgICAgIGZpbGVPZldyaXRlT25seUZpbGVDaGFubmVsLmRlbGV0ZSgpOworICAgICAgICB9CisgICAgICAgIGlmIChudWxsICE9IGZpbGVPZlJlYWRXcml0ZUZpbGVDaGFubmVsKSB7CisgICAgICAgICAgICBmaWxlT2ZSZWFkV3JpdGVGaWxlQ2hhbm5lbC5kZWxldGUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZm9yY2VaKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVCdWZmZXIgd3JpdGVCdWZmZXIgPSBCeXRlQnVmZmVyLndyYXAoQ09OVEVOVF9BU19CWVRFUyk7CisgICAgICAgIHdyaXRlT25seUZpbGVDaGFubmVsLndyaXRlKHdyaXRlQnVmZmVyKTsKKyAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwuZm9yY2UodHJ1ZSk7CisKKyAgICAgICAgYnl0ZVtdIHJlYWRCdWZmZXIgPSBuZXcgYnl0ZVtDT05URU5UX0FTX0JZVEVTX0xFTkdUSF07CisgICAgICAgIGZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZU9mV3JpdGVPbmx5RmlsZUNoYW5uZWwpOworICAgICAgICBmaXMucmVhZChyZWFkQnVmZmVyKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKENPTlRFTlRfQVNfQllURVMsIHJlYWRCdWZmZXIpKTsKKworICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlcik7CisgICAgICAgIHdyaXRlT25seUZpbGVDaGFubmVsLmZvcmNlKGZhbHNlKTsKKyAgICAgICAgZmlzLmNsb3NlKCk7CisKKyAgICAgICAgcmVhZEJ1ZmZlciA9IG5ldyBieXRlW0NPTlRFTlRfQVNfQllURVNfTEVOR1RIXTsKKyAgICAgICAgZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlT2ZXcml0ZU9ubHlGaWxlQ2hhbm5lbCk7CisgICAgICAgIGZpcy5yZWFkKHJlYWRCdWZmZXIpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoQ09OVEVOVF9BU19CWVRFUywgcmVhZEJ1ZmZlcikpOworICAgICAgICBmaXMuY2xvc2UoKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIHRlc3QgZmlsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlCisgICAgICogQHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlRGF0YVRvRmlsZShGaWxlIGZpbGUpIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24sCisgICAgICAgICAgICBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gZm9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3Mud3JpdGUoQ09OVEVOVF9BU19CWVRFUyk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBmb3MuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIGxhcmdlIHRlc3QgZmlsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlIHRoZSBmaWxlIHRvIGJlIHdyaXR0ZW4KKyAgICAgKiBAcGFyYW0gc2l6ZSB0aGUgY29udGVudCBzaXplIHRvIGJlIHdyaXR0ZW4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVMYXJnZURhdGFUb0ZpbGUoRmlsZSBmaWxlLCBpbnQgc2l6ZSkKKyAgICAgICAgICAgIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBmb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlKTsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlW3NpemVdOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyB3ZSBkb24ndCBjYXJlIGFib3V0IGNvbnRlbnQgLSBqdXN0IG5lZWQgYSBwYXJ0aWN1bGFyIGZpbGUgc2l6ZQorICAgICAgICAgICAgZm9zLndyaXRlKGJ1Zik7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBmb3MuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdHJ5TG9ja0pKWl9JbGxlZ2FsQXJndW1lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlT25seUZpbGVDaGFubmVsLnRyeUxvY2soMCwgLTEsIGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwudHJ5TG9jaygtMSwgMCwgZmFsc2UpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC50cnlMb2NrKC0xLCAtMSwgZmFsc2UpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC50cnlMb2NrKExvbmcuTUFYX1ZBTFVFLCAxLCBmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRyeUxvY2tWZXJ5TGFyZ2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBsb25nIHRvb0JpZyA9IEludGVnZXIuTUFYX1ZBTFVFICsgMUw7CisgICAgICAgIEZpbGVMb2NrIGxvY2sgPSByZWFkV3JpdGVGaWxlQ2hhbm5lbC50cnlMb2NrKHRvb0JpZywgMSwgZmFsc2UpOworICAgICAgICBhc3NlcnRMb2NrRmFpbHModG9vQmlnLCAxKTsKKyAgICAgICAgbG9jay5yZWxlYXNlKCk7CisKKyAgICAgICAgbG9jayA9IHJlYWRXcml0ZUZpbGVDaGFubmVsLnRyeUxvY2soMCwgdG9vQmlnLCBmYWxzZSk7CisgICAgICAgIGFzc2VydExvY2tGYWlscygwLCAxKTsKKyAgICAgICAgbG9jay5yZWxlYXNlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRyeUxvY2tPdmVybGFwcGluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEZpbGVMb2NrIGxvY2tPbmUgPSByZWFkV3JpdGVGaWxlQ2hhbm5lbC50cnlMb2NrKDAsIDEwLCBmYWxzZSk7CisgICAgICAgIEZpbGVMb2NrIGxvY2tUd28gPSByZWFkV3JpdGVGaWxlQ2hhbm5lbC50cnlMb2NrKDEwLCAyMCwgZmFsc2UpOworICAgICAgICBhc3NlcnRMb2NrRmFpbHMoMCwgMTApOworICAgICAgICBsb2NrT25lLnJlbGVhc2UoKTsKKyAgICAgICAgYXNzZXJ0TG9ja0ZhaWxzKDUsIDEwKTsKKyAgICAgICAgbG9ja09uZSA9IHJlYWRXcml0ZUZpbGVDaGFubmVsLnRyeUxvY2soMCwgMTAsIGZhbHNlKTsKKyAgICAgICAgbG9ja1R3by5yZWxlYXNlKCk7CisgICAgICAgIGxvY2tPbmUucmVsZWFzZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZExCeXRlQnVmZmVySl9JbGxlZ2FsQXJndW1lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUJ1ZmZlciByZWFkQnVmZmVyID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShDQVBBQ0lUWSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRPbmx5RmlsZUNoYW5uZWwucmVhZChyZWFkQnVmZmVyLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlT25seUZpbGVDaGFubmVsLnJlYWQocmVhZEJ1ZmZlciwgLTEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC5yZWFkKHJlYWRCdWZmZXIsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGZpcnN0LgorICAgICAgICByZWFkT25seUZpbGVDaGFubmVsLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkT25seUZpbGVDaGFubmVsLnJlYWQocmVhZEJ1ZmZlciwgLTEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHdyaXRlT25seUZpbGVDaGFubmVsLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC5yZWFkKHJlYWRCdWZmZXIsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwucmVhZChyZWFkQnVmZmVyLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkJExCeXRlQnVmZmVySUlfTnVsbCgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkT25seUZpbGVDaGFubmVsLnJlYWQobnVsbCwgMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZE9ubHlGaWxlQ2hhbm5lbC5yZWFkKG51bGwsIDAsIDMpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRPbmx5RmlsZUNoYW5uZWwucmVhZChudWxsLCAxLCAyKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkT25seUZpbGVDaGFubmVsLnJlYWQobnVsbCwgMiwgMSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZE9ubHlGaWxlQ2hhbm5lbC5yZWFkKG51bGwsIDMsIDApOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwucmVhZChudWxsLCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC5yZWFkKG51bGwsIDAsIDMpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlT25seUZpbGVDaGFubmVsLnJlYWQobnVsbCwgMSwgMik7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwucmVhZChudWxsLCAyLCAxKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC5yZWFkKG51bGwsIDMsIDApOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwucmVhZChudWxsLCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC5yZWFkKG51bGwsIDAsIDMpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRXcml0ZUZpbGVDaGFubmVsLnJlYWQobnVsbCwgMSwgMik7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwucmVhZChudWxsLCAyLCAxKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC5yZWFkKG51bGwsIDMsIDApOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBmaXJzdCB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgICAgcmVhZE9ubHlGaWxlQ2hhbm5lbC5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZE9ubHlGaWxlQ2hhbm5lbC5yZWFkKG51bGwsIDAsIDEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRPbmx5RmlsZUNoYW5uZWwucmVhZChudWxsLCAwLCAzKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkT25seUZpbGVDaGFubmVsLnJlYWQobnVsbCwgMSwgMik7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZE9ubHlGaWxlQ2hhbm5lbC5yZWFkKG51bGwsIDIsIDEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRPbmx5RmlsZUNoYW5uZWwucmVhZChudWxsLCAzLCAwKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRXcml0ZUZpbGVDaGFubmVsLnJlYWQobnVsbCwgMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwucmVhZChudWxsLCAwLCAzKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC5yZWFkKG51bGwsIDEsIDIpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRXcml0ZUZpbGVDaGFubmVsLnJlYWQobnVsbCwgMiwgMSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwucmVhZChudWxsLCAzLCAwKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlT25seUZpbGVDaGFubmVsLnJlYWQobnVsbCwgMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwucmVhZChudWxsLCAwLCAzKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC5yZWFkKG51bGwsIDEsIDIpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlT25seUZpbGVDaGFubmVsLnJlYWQobnVsbCwgMiwgMSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwucmVhZChudWxsLCAzLCAwKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisKKyAgICBwcml2YXRlIHZvaWQgZG9UZXN0Rm9ySU9PQkV4Y2VwdGlvbihGaWxlQ2hhbm5lbCBjaGFubmVsLAorICAgICAgICAgICAgQnl0ZUJ1ZmZlcltdIGJ1ZmZlcikgdGhyb3dzIElPRXhjZXB0aW9ueworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2hhbm5lbC5yZWFkKGJ1ZmZlciwgLTEsIDApOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNoYW5uZWwucmVhZChidWZmZXIsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGFubmVsLnJlYWQoYnVmZmVyLCAwLCAzKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGFubmVsLnJlYWQoYnVmZmVyLCAxLCAyKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGFubmVsLnJlYWQoYnVmZmVyLCAyLCAxKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGFubmVsLnJlYWQoYnVmZmVyLCAzLCAwKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkJExCeXRlQnVmZmVySUlfSW5kZXhPdXRPZkJvdW5kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVCdWZmZXJbXSByZWFkQnVmZmVycyA9IG5ldyBCeXRlQnVmZmVyWzJdOworICAgICAgICByZWFkQnVmZmVyc1swXSA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoQ0FQQUNJVFkpOworICAgICAgICByZWFkQnVmZmVyc1sxXSA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoQ0FQQUNJVFkpOworICAgICAgICBCeXRlQnVmZmVyW10gcmVhZEJ1ZmZlcnNOdWxsID0gbmV3IEJ5dGVCdWZmZXJbMl07CisKKyAgICAgICAgZG9UZXN0Rm9ySU9PQkV4Y2VwdGlvbihyZWFkT25seUZpbGVDaGFubmVsLCByZWFkQnVmZmVycyk7CisgICAgICAgIGRvVGVzdEZvcklPT0JFeGNlcHRpb24ocmVhZFdyaXRlRmlsZUNoYW5uZWwsIHJlYWRCdWZmZXJzKTsKKyAgICAgICAgZG9UZXN0Rm9ySU9PQkV4Y2VwdGlvbih3cml0ZU9ubHlGaWxlQ2hhbm5lbCwgcmVhZEJ1ZmZlcnMpOworCisgICAgICAgIGRvVGVzdEZvcklPT0JFeGNlcHRpb24ocmVhZE9ubHlGaWxlQ2hhbm5lbCwgcmVhZEJ1ZmZlcnNOdWxsKTsKKyAgICAgICAgZG9UZXN0Rm9ySU9PQkV4Y2VwdGlvbihyZWFkV3JpdGVGaWxlQ2hhbm5lbCwgcmVhZEJ1ZmZlcnNOdWxsKTsKKyAgICAgICAgZG9UZXN0Rm9ySU9PQkV4Y2VwdGlvbih3cml0ZU9ubHlGaWxlQ2hhbm5lbCwgcmVhZEJ1ZmZlcnNOdWxsKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRPbmx5RmlsZUNoYW5uZWwucmVhZChudWxsLCAtMSwgMCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSW5kZXhPdXRPZkJvdW5kRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZE9ubHlGaWxlQ2hhbm5lbC5yZWFkKG51bGwsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRXcml0ZUZpbGVDaGFubmVsLnJlYWQobnVsbCwgLTEsIDApOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRXcml0ZUZpbGVDaGFubmVsLnJlYWQobnVsbCwgMCwgLTEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwucmVhZChudWxsLCAtMSwgMCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSW5kZXhPdXRPZkJvdW5kRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwucmVhZChudWxsLCAwLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSW5kZXhPdXRPZkJvdW5kRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHJlYWRPbmx5RmlsZUNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgZG9UZXN0Rm9ySU9PQkV4Y2VwdGlvbihyZWFkT25seUZpbGVDaGFubmVsLCByZWFkQnVmZmVycyk7CisgICAgICAgIGRvVGVzdEZvcklPT0JFeGNlcHRpb24ocmVhZE9ubHlGaWxlQ2hhbm5lbCwgcmVhZEJ1ZmZlcnNOdWxsKTsKKworICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC5jbG9zZSgpOworICAgICAgICBkb1Rlc3RGb3JJT09CRXhjZXB0aW9uKHJlYWRXcml0ZUZpbGVDaGFubmVsLCByZWFkQnVmZmVycyk7CisgICAgICAgIGRvVGVzdEZvcklPT0JFeGNlcHRpb24ocmVhZFdyaXRlRmlsZUNoYW5uZWwsIHJlYWRCdWZmZXJzTnVsbCk7CisKKyAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgZG9UZXN0Rm9ySU9PQkV4Y2VwdGlvbih3cml0ZU9ubHlGaWxlQ2hhbm5lbCwgcmVhZEJ1ZmZlcnMpOworICAgICAgICBkb1Rlc3RGb3JJT09CRXhjZXB0aW9uKHdyaXRlT25seUZpbGVDaGFubmVsLCByZWFkQnVmZmVyc051bGwpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCRMQnl0ZUJ1ZmZlcklJX0VtcHR5RmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBCeXRlQnVmZmVyW10gcmVhZEJ1ZmZlcnMgPSBuZXcgQnl0ZUJ1ZmZlclsyXTsKKyAgICAgICAgcmVhZEJ1ZmZlcnNbMF0gPSBCeXRlQnVmZmVyLmFsbG9jYXRlKENBUEFDSVRZKTsKKyAgICAgICAgcmVhZEJ1ZmZlcnNbMV0gPSBCeXRlQnVmZmVyLmFsbG9jYXRlKENBUEFDSVRZKTsKKyAgICAgICAgbG9uZyByZXN1bHQgPSByZWFkT25seUZpbGVDaGFubmVsLnJlYWQocmVhZEJ1ZmZlcnMsIDAsIDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCByZWFkQnVmZmVyc1swXS5wb3NpdGlvbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHJlYWRCdWZmZXJzWzFdLnBvc2l0aW9uKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCRMQnl0ZUJ1ZmZlcklJX0VtcHR5QnVmZmVycygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBCeXRlQnVmZmVyW10gcmVhZEJ1ZmZlcnMgPSBuZXcgQnl0ZUJ1ZmZlclsyXTsKKyAgICAgICAgcmVhZEJ1ZmZlcnNbMF0gPSBCeXRlQnVmZmVyLmFsbG9jYXRlKENBUEFDSVRZKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZE9ubHlGaWxlQ2hhbm5lbC5yZWFkKHJlYWRCdWZmZXJzLCAwLCAyKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHdyaXRlRGF0YVRvRmlsZShmaWxlT2ZSZWFkT25seUZpbGVDaGFubmVsKTsKKyAgICAgICAgcmVhZEJ1ZmZlcnNbMF0gPSBCeXRlQnVmZmVyLmFsbG9jYXRlKENBUEFDSVRZKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRPbmx5RmlsZUNoYW5uZWwucmVhZChyZWFkQnVmZmVycywgMCwgMik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBsb25nIHJlc3VsdCA9IHJlYWRPbmx5RmlsZUNoYW5uZWwucmVhZChyZWFkQnVmZmVycywgMCwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDT05URU5UX0FTX0JZVEVTX0xFTkdUSCwgcmVzdWx0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzT3BlbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTQwCisgICAgICAgIEZpbGUgbG9nRmlsZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoIm91dCIsICJ0bXAiKTsKKyAgICAgICAgbG9nRmlsZS5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShsb2dGaWxlLCB0cnVlKTsKKyAgICAgICAgRmlsZUNoYW5uZWwgY2hhbm5lbCA9IG91dC5nZXRDaGFubmVsKCk7CisgICAgICAgIG91dC53cml0ZSgxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQXNzZXJ0IDA6IENoYW5uZWwgaXMgbm90IG9wZW4iLCBjaGFubmVsLmlzT3BlbigpKTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJBc3NlcnQgMDogQ2hhbm5lbCBpcyBzdGlsbCBvcGVuIiwgY2hhbm5lbC5pc09wZW4oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZUxCeXRlQnVmZmVyX0Nsb3NlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBCeXRlQnVmZmVyIHdyaXRlQnVmZmVyID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShDQVBBQ0lUWSk7CisKKyAgICAgICAgcmVhZE9ubHlGaWxlQ2hhbm5lbC5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZE9ubHlGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlcik7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChDbG9zZWRDaGFubmVsRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXIpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IENsb3NlZENoYW5uZWxFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRXcml0ZUZpbGVDaGFubmVsLndyaXRlKHdyaXRlQnVmZmVyKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKENsb3NlZENoYW5uZWxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIHNob3VsZCB0aHJvdyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uIGZpcnN0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC5yZWFkKChCeXRlQnVmZmVyKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZE9ubHlGaWxlQ2hhbm5lbC53cml0ZSgoQnl0ZUJ1ZmZlcikgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKENsb3NlZENoYW5uZWxFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlT25seUZpbGVDaGFubmVsLndyaXRlKChCeXRlQnVmZmVyKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlTEJ5dGVCdWZmZXJKX1Bvc3Rpb25fQXNfTG9uZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBCeXRlQnVmZmVyIHdyaXRlQnVmZmVyID0gQnl0ZUJ1ZmZlci53cmFwKFRFU1RfQllURVMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXIsIExvbmcuTUFYX1ZBTFVFKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGVMQnl0ZUJ1ZmZlckpfSWxsZWdhbEFyZ3VtZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVCdWZmZXIgd3JpdGVCdWZmZXIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKENBUEFDSVRZKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZE9ubHlGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlciwgLTEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlciwgLTEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlciwgLTEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZmlyc3QuCisgICAgICAgIHJlYWRPbmx5RmlsZUNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRPbmx5RmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXIsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXIsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXIsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlTEJ5dGVCdWZmZXJKX05vblplcm9Qb3NpdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBpbnQgcG9zID0gNTsKKyAgICAgICAgQnl0ZUJ1ZmZlciB3cml0ZUJ1ZmZlciA9IEJ5dGVCdWZmZXIud3JhcChDT05URU5UX0FTX0JZVEVTKTsKKyAgICAgICAgd3JpdGVCdWZmZXIucG9zaXRpb24ocG9zKTsKKyAgICAgICAgaW50IHJlc3VsdCA9IHdyaXRlT25seUZpbGVDaGFubmVsLndyaXRlKHdyaXRlQnVmZmVyLCBwb3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ09OVEVOVF9BU19CWVRFU19MRU5HVEggLSBwb3MsIHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscyhDT05URU5UX0FTX0JZVEVTX0xFTkdUSCwgd3JpdGVCdWZmZXIucG9zaXRpb24oKSk7CisgICAgICAgIHdyaXRlT25seUZpbGVDaGFubmVsLmNsb3NlKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENPTlRFTlRfQVNfQllURVNfTEVOR1RILCBmaWxlT2ZXcml0ZU9ubHlGaWxlQ2hhbm5lbAorICAgICAgICAgICAgICAgIC5sZW5ndGgoKSk7CisKKyAgICAgICAgZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlT2ZXcml0ZU9ubHlGaWxlQ2hhbm5lbCk7CisgICAgICAgIGJ5dGVbXSBpbnB1dEJ1ZmZlciA9IG5ldyBieXRlW0NPTlRFTlRfQVNfQllURVNfTEVOR1RIIC0gcG9zXTsKKyAgICAgICAgZmlzLnNraXAocG9zKTsKKyAgICAgICAgZmlzLnJlYWQoaW5wdXRCdWZmZXIpOworICAgICAgICBTdHJpbmcgdGVzdCA9IENPTlRFTlQuc3Vic3RyaW5nKHBvcyk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyh0ZXN0LmdldEJ5dGVzKCksIGlucHV0QnVmZmVyKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZSRMQnl0ZUJ1ZmZlcl9DbG9zZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUJ1ZmZlcltdIHdyaXRlQnVmZmVycyA9IG5ldyBCeXRlQnVmZmVyWzJdOworICAgICAgICB3cml0ZUJ1ZmZlcnNbMF0gPSBCeXRlQnVmZmVyLmFsbG9jYXRlKENBUEFDSVRZKTsKKyAgICAgICAgd3JpdGVCdWZmZXJzWzFdID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShDQVBBQ0lUWSk7CisKKyAgICAgICAgcmVhZE9ubHlGaWxlQ2hhbm5lbC5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZE9ubHlGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlcnMpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IENsb3NlZENoYW5uZWxFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlT25seUZpbGVDaGFubmVsLndyaXRlKHdyaXRlQnVmZmVycyk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChDbG9zZWRDaGFubmVsRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXJzKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBDbG9zZWRDaGFubmVsRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKENsb3NlZENoYW5uZWxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGUkTEJ5dGVCdWZmZXJfUmVhZE9ubHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUJ1ZmZlcltdIHdyaXRlQnVmZmVycyA9IG5ldyBCeXRlQnVmZmVyWzJdOworICAgICAgICB3cml0ZUJ1ZmZlcnNbMF0gPSBCeXRlQnVmZmVyLmFsbG9jYXRlKENBUEFDSVRZKTsKKyAgICAgICAgd3JpdGVCdWZmZXJzWzFdID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShDQVBBQ0lUWSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRPbmx5RmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXJzKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOb25Xcml0YWJsZUNoYW5uZWxFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTm9uV3JpdGFibGVDaGFubmVsRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlJExCeXRlQnVmZmVyX0VtcHR5QnVmZmVycygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBCeXRlQnVmZmVyW10gd3JpdGVCdWZmZXJzID0gbmV3IEJ5dGVCdWZmZXJbMl07CisgICAgICAgIHdyaXRlQnVmZmVyc1swXSA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUodGhpcy5DT05URU5UX0xFTkdUSCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlcnMpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXJzKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZSRMQnl0ZUJ1ZmZlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBCeXRlQnVmZmVyW10gd3JpdGVCdWZmZXJzID0gbmV3IEJ5dGVCdWZmZXJbMl07CisgICAgICAgIHdyaXRlQnVmZmVyc1swXSA9IEJ5dGVCdWZmZXIud3JhcChDT05URU5UX0FTX0JZVEVTKTsKKyAgICAgICAgd3JpdGVCdWZmZXJzWzFdID0gQnl0ZUJ1ZmZlci53cmFwKENPTlRFTlRfQVNfQllURVMpOworCisgICAgICAgIGxvbmcgcmVzdWx0ID0gd3JpdGVPbmx5RmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXJzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENPTlRFTlRfQVNfQllURVNfTEVOR1RIICogMiwgcmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENPTlRFTlRfQVNfQllURVNfTEVOR1RILCB3cml0ZUJ1ZmZlcnNbMF0ucG9zaXRpb24oKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDT05URU5UX0FTX0JZVEVTX0xFTkdUSCwgd3JpdGVCdWZmZXJzWzFdLnBvc2l0aW9uKCkpOworICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC5jbG9zZSgpOworCisgICAgICAgIGFzc2VydEVxdWFscyhDT05URU5UX0FTX0JZVEVTX0xFTkdUSCAqIDIsIGZpbGVPZldyaXRlT25seUZpbGVDaGFubmVsCisgICAgICAgICAgICAgICAgLmxlbmd0aCgpKTsKKworICAgICAgICBmaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGVPZldyaXRlT25seUZpbGVDaGFubmVsKTsKKyAgICAgICAgYnl0ZVtdIGlucHV0QnVmZmVyID0gbmV3IGJ5dGVbQ09OVEVOVF9BU19CWVRFU19MRU5HVEhdOworICAgICAgICBmaXMucmVhZChpbnB1dEJ1ZmZlcik7CisgICAgICAgIGJ5dGVbXSBleHBlY3RlZFJlc3VsdCA9IG5ldyBieXRlW0NPTlRFTlRfQVNfQllURVNfTEVOR1RIICogMl07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoQ09OVEVOVF9BU19CWVRFUywgMCwgZXhwZWN0ZWRSZXN1bHQsIDAsCisgICAgICAgICAgICAgICAgQ09OVEVOVF9BU19CWVRFU19MRU5HVEgpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KENPTlRFTlRfQVNfQllURVMsIDAsIGV4cGVjdGVkUmVzdWx0LAorICAgICAgICAgICAgICAgIENPTlRFTlRfQVNfQllURVNfTEVOR1RILCBDT05URU5UX0FTX0JZVEVTX0xFTkdUSCk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhDT05URU5UX0FTX0JZVEVTLCBpbnB1dEJ1ZmZlcikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGUkTEJ5dGVCdWZmZXJJSV9OdWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVCdWZmZXJbXSB3cml0ZUJ1ZmZlcnMgPSBudWxsOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkT25seUZpbGVDaGFubmVsLndyaXRlKHdyaXRlQnVmZmVycywgMSwgMik7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlcnMsIDEsIDIpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXJzLCAxLCAyKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gZmlyc3QgdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICAgIHJlYWRPbmx5RmlsZUNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRPbmx5RmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXJzLCAxLCAyKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlT25seUZpbGVDaGFubmVsLndyaXRlKHdyaXRlQnVmZmVycywgMSwgMik7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHJlYWRXcml0ZUZpbGVDaGFubmVsLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlcnMsIDEsIDIpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlJExCeXRlQnVmZmVySUlfSW5kZXhPdXRPZkJvdW5kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVCdWZmZXJbXSB3cml0ZUJ1ZmZlcnMgPSBuZXcgQnl0ZUJ1ZmZlclsyXTsKKyAgICAgICAgd3JpdGVCdWZmZXJzWzBdID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSh0aGlzLkNPTlRFTlRfTEVOR1RIKTsKKyAgICAgICAgd3JpdGVCdWZmZXJzWzFdID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSh0aGlzLkNPTlRFTlRfTEVOR1RIKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVPbmx5RmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXJzLCAtMSwgMCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlT25seUZpbGVDaGFubmVsLndyaXRlKHdyaXRlQnVmZmVycywgMCwgLTEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlcnMsIDAsIDMpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlcnMsIDEsIDIpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlcnMsIDIsIDEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3cml0ZU9ubHlGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlcnMsIDMsIDApOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRXcml0ZUZpbGVDaGFubmVsLndyaXRlKHdyaXRlQnVmZmVycywgLTEsIDApOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlcnMsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXJzLCAwLCAzKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXJzLCAxLCAyKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXJzLCAyLCAxKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXJzLCAzLCAwKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkT25seUZpbGVDaGFubmVsLndyaXRlKHdyaXRlQnVmZmVycywgLTEsIDApOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkT25seUZpbGVDaGFubmVsLndyaXRlKHdyaXRlQnVmZmVycywgMCwgLTEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkT25seUZpbGVDaGFubmVsLndyaXRlKHdyaXRlQnVmZmVycywgMCwgMyk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRPbmx5RmlsZUNoYW5uZWwud3JpdGUod3JpdGVCdWZmZXJzLCAxLCAyKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZE9ubHlGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlcnMsIDIsIDEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkT25seUZpbGVDaGFubmVsLndyaXRlKHdyaXRlQnVmZmVycywgMywgMCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlJExCeXRlQnVmZmVySUlfRW1wdHlCdWZmZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVCdWZmZXJbXSB3cml0ZUJ1ZmZlcnMgPSBuZXcgQnl0ZUJ1ZmZlclsyXTsKKyAgICAgICAgd3JpdGVCdWZmZXJzWzBdID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSh0aGlzLkNPTlRFTlRfTEVOR1RIKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdyaXRlT25seUZpbGVDaGFubmVsLndyaXRlKHdyaXRlQnVmZmVycywgMCwgMik7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkV3JpdGVGaWxlQ2hhbm5lbC53cml0ZSh3cml0ZUJ1ZmZlcnMsIDAsIDIpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RyYW5zZmVyVG9KSkxXcml0YWJsZUJ5dGVDaGFubmVsX0lsbGVnYWxBcmd1bWVudCgpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgV3JpdGFibGVCeXRlQ2hhbm5lbCB3cml0YWJsZUJ5dGVDaGFubmVsID0gRGF0YWdyYW1DaGFubmVsLm9wZW4oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRPbmx5RmlsZUNoYW5uZWwudHJhbnNmZXJUbygxMCwgLTEsIHdyaXRhYmxlQnl0ZUNoYW5uZWwpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZFdyaXRlRmlsZUNoYW5uZWwudHJhbnNmZXJUbygtMSwgMTAsIHdyaXRhYmxlQnl0ZUNoYW5uZWwpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0TG9ja0ZhaWxzKGxvbmcgcG9zaXRpb24sIGxvbmcgc2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRXcml0ZUZpbGVDaGFubmVsLnRyeUxvY2socG9zaXRpb24sIHNpemUsIGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoT3ZlcmxhcHBpbmdGaWxlTG9ja0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhbm5lbHMvT2xkU2VydmVyU29ja2V0Q2hhbm5lbFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYW5uZWxzL09sZFNlcnZlclNvY2tldENoYW5uZWxUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmI2MzUxMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYW5uZWxzL09sZFNlcnZlclNvY2tldENoYW5uZWxUZXN0LmphdmEKQEAgLTAsMCArMSwxMTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFubmVsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU2VydmVyU29ja2V0OworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkNsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlcnZlclNvY2tldENoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU29ja2V0Q2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5zcGkuU2VsZWN0b3JQcm92aWRlcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1BvcnRNYW5hZ2VyOworCisvKgorICogdGVzdCBmb3IgU2VydmVyU29ja2V0Q2hhbm5lbAorICovCitwdWJsaWMgY2xhc3MgT2xkU2VydmVyU29ja2V0Q2hhbm5lbFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVElNRV9VTklUID0gMjAwOworCisgICAgcHJpdmF0ZSBJbmV0U29ja2V0QWRkcmVzcyBsb2NhbEFkZHIxOworCisgICAgcHJpdmF0ZSBTZXJ2ZXJTb2NrZXRDaGFubmVsIHNlcnZlckNoYW5uZWw7CisKKyAgICBwcml2YXRlIFNvY2tldENoYW5uZWwgY2xpZW50Q2hhbm5lbDsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRoaXMubG9jYWxBZGRyMSA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcygKKyAgICAgICAgICAgICAgICAiMTI3LjAuMC4xIiwgU3VwcG9ydF9Qb3J0TWFuYWdlcgorICAgICAgICAgICAgICAgICAgICAgICAgLmdldE5leHRQb3J0KCkpOworICAgICAgICB0aGlzLnNlcnZlckNoYW5uZWwgPSBTZXJ2ZXJTb2NrZXRDaGFubmVsLm9wZW4oKTsKKyAgICAgICAgdGhpcy5jbGllbnRDaGFubmVsID0gU29ja2V0Q2hhbm5lbC5vcGVuKCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG51bGwgIT0gdGhpcy5zZXJ2ZXJDaGFubmVsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRoaXMuc2VydmVyQ2hhbm5lbC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvL2lnbm9yZQorICAgICAgICAgICAgfQorCisgICAgICAgIH0KKyAgICAgICAgaWYgKG51bGwgIT0gdGhpcy5jbGllbnRDaGFubmVsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRoaXMuY2xpZW50Q2hhbm5lbC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvL2lnbm9yZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIC8vIFRlc3QgZm9yIG1ldGhvZHMgaW4gYWJzdHJhY3QgY2xhc3MuCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIHB1YmxpYyB2b2lkIHRlc3RDb25zdHJ1Y3RvcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFNlcnZlclNvY2tldENoYW5uZWwgY2hhbm5lbCA9CisgICAgICAgICAgICAgICAgU2VsZWN0b3JQcm92aWRlci5wcm92aWRlcigpLm9wZW5TZXJ2ZXJTb2NrZXRDaGFubmVsKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoY2hhbm5lbCk7CisgICAgICAgIGFzc2VydFNhbWUoU2VsZWN0b3JQcm92aWRlci5wcm92aWRlcigpLGNoYW5uZWwucHJvdmlkZXIoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdElzT3BlbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKHRoaXMuc2VydmVyQ2hhbm5lbC5pc09wZW4oKSk7CisgICAgICAgIHRoaXMuc2VydmVyQ2hhbm5lbC5jbG9zZSgpOworICAgICAgICBhc3NlcnRGYWxzZSh0aGlzLnNlcnZlckNoYW5uZWwuaXNPcGVuKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWNjZXB0X0Jsb2NrX05vQ29ubmVjdF9pbnRlcnJ1cHQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKHRoaXMuc2VydmVyQ2hhbm5lbC5pc0Jsb2NraW5nKCkpOworICAgICAgICBTZXJ2ZXJTb2NrZXQgZ290U29ja2V0ID0gdGhpcy5zZXJ2ZXJDaGFubmVsLnNvY2tldCgpOworICAgICAgICBnb3RTb2NrZXQuYmluZChsb2NhbEFkZHIxKTsKKworICAgICAgICBjbGFzcyBNeVRocmVhZCBleHRlbmRzIFRocmVhZCB7CisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGVyck1zZyA9IG51bGw7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc2VydmVyQ2hhbm5lbC5hY2NlcHQoKTsKKyAgICAgICAgICAgICAgICAgICAgZXJyTXNnID0gInNob3VsZCB0aHJvdyBDbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvbiI7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGVyck1zZyA9ICJjYXVnaHQgd3JvbmcgRXhjZXB0aW9uOiAiICsgZS5nZXRDbGFzcygpICsgIjogIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIE15VGhyZWFkIHRocmVhZCA9IG5ldyBNeVRocmVhZCgpOworICAgICAgICB0aHJlYWQuc3RhcnQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuc2xlZXAoVElNRV9VTklUKTsKKyAgICAgICAgICAgIHRocmVhZC5pbnRlcnJ1cHQoKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIG5vdCB0aHJvdyBhIEludGVycnVwdGVkRXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRocmVhZC5lcnJNc2cgIT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbCh0aHJlYWQuZXJyTXNnKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYW5uZWxzL09sZFNvY2tldENoYW5uZWxUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFubmVscy9PbGRTb2NrZXRDaGFubmVsVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYxODIzNzUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFubmVscy9PbGRTb2NrZXRDaGFubmVsVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDMzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhbm5lbHM7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5Ccm9rZW5UZXN0OworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU2VydmVyU29ja2V0OworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNvY2tldEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLk5vQ29ubmVjdGlvblBlbmRpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuTm90WWV0Q29ubmVjdGVkRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlbGVjdGlvbktleTsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5TZXJ2ZXJTb2NrZXRDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNvY2tldENoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuVW5yZXNvbHZlZEFkZHJlc3NFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuVW5zdXBwb3J0ZWRBZGRyZXNzVHlwZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5zcGkuU2VsZWN0b3JQcm92aWRlcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1BvcnRNYW5hZ2VyOworCisvKioKKyAqIFRlc3RzIGZvciBTb2NrZXRDaGFubmVsIGFuZCBpdHMgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbi4KKyAqLworcHVibGljIGNsYXNzIE9sZFNvY2tldENoYW5uZWxUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENBUEFDSVRZX05PUk1BTCA9IDIwMDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDQVBBQ0lUWV9IVUdFID0gNTEyICogMTAyNDsKKworICAgIHByaXZhdGUgSW5ldFNvY2tldEFkZHJlc3MgbG9jYWxBZGRyMTsKKworICAgIHByaXZhdGUgU29ja2V0Q2hhbm5lbCBjaGFubmVsMTsKKworICAgIHByaXZhdGUgU29ja2V0Q2hhbm5lbCBjaGFubmVsMjsKKworICAgIHByaXZhdGUgU2VydmVyU29ja2V0IHNlcnZlcjE7CisKKyAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBpbnQgVElNRU9VVCA9IDYwMDAwOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdGhpcy5sb2NhbEFkZHIxID0gbmV3IEluZXRTb2NrZXRBZGRyZXNzKCIxMjcuMC4wLjEiLAorICAgICAgICAgICAgICAgIFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKSk7CisgICAgICAgIHRoaXMuY2hhbm5lbDEgPSBTb2NrZXRDaGFubmVsLm9wZW4oKTsKKyAgICAgICAgdGhpcy5jaGFubmVsMiA9IFNvY2tldENoYW5uZWwub3BlbigpOworICAgICAgICB0aGlzLnNlcnZlcjEgPSBuZXcgU2VydmVyU29ja2V0KGxvY2FsQWRkcjEuZ2V0UG9ydCgpKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgICAgICBpZiAobnVsbCAhPSB0aGlzLmNoYW5uZWwxKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRoaXMuY2hhbm5lbDEuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gaWdub3JlCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKG51bGwgIT0gdGhpcy5jaGFubmVsMikgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0aGlzLmNoYW5uZWwyLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGlnbm9yZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChudWxsICE9IHRoaXMuc2VydmVyMSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0aGlzLnNlcnZlcjEuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gaWdub3JlCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gVGVzdCBmb3IgbWV0aG9kcyBpbiBhYnN0cmFjdCBjbGFzcy4KKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdG9yKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU29ja2V0Q2hhbm5lbCBjaGFubmVsID0KKyAgICAgICAgICAgICAgICBTZWxlY3RvclByb3ZpZGVyLnByb3ZpZGVyKCkub3BlblNvY2tldENoYW5uZWwoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjaGFubmVsKTsKKyAgICAgICAgYXNzZXJ0U2FtZShTZWxlY3RvclByb3ZpZGVyLnByb3ZpZGVyKCksIGNoYW5uZWwucHJvdmlkZXIoKSk7CisgICAgICAgIGNoYW5uZWwgPSBTb2NrZXRDaGFubmVsLm9wZW4oKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjaGFubmVsKTsKKyAgICAgICAgYXNzZXJ0U2FtZShTZWxlY3RvclByb3ZpZGVyLnByb3ZpZGVyKCksIGNoYW5uZWwucHJvdmlkZXIoKSk7CisgICAgICAgIE1vY2tTb2NrZXRDaGFubmVsIGNoYW4gPSBuZXcgTW9ja1NvY2tldENoYW5uZWwoCisgICAgICAgICAgICAgICAgU2VsZWN0b3JQcm92aWRlci5wcm92aWRlcigpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjaGFuLmlzQ29uc3RydWN0b3JDYWxsZWQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RWYWxpZE9wcygpIHsKKyAgICAgICAgTW9ja1NvY2tldENoYW5uZWwgdGVzdE1TQ2hhbm5lbCA9IG5ldyBNb2NrU29ja2V0Q2hhbm5lbChudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEzLCB0aGlzLmNoYW5uZWwxLnZhbGlkT3BzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTMsIHRlc3RNU0NoYW5uZWwudmFsaWRPcHMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE9wZW4oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyW10gYnVmID0gbmV3IGphdmEubmlvLkJ5dGVCdWZmZXJbMV07CisgICAgICAgIGJ1ZlswXSA9IGphdmEubmlvLkJ5dGVCdWZmZXIuYWxsb2NhdGVEaXJlY3QoQ0FQQUNJVFlfTk9STUFMKTsKKyAgICAgICAgTW9ja1NvY2tldENoYW5uZWwgdGVzdE1TQ2hhbm5lbCA9IG5ldyBNb2NrU29ja2V0Q2hhbm5lbChudWxsKTsKKyAgICAgICAgTW9ja1NvY2tldENoYW5uZWwgdGVzdE1TQ2hhbm5lbG5vdG51bGwgPSBuZXcgTW9ja1NvY2tldENoYW5uZWwoCisgICAgICAgICAgICAgICAgU2VsZWN0b3JQcm92aWRlci5wcm92aWRlcigpKTsKKyAgICAgICAgU29ja2V0Q2hhbm5lbCB0ZXN0U0NoYW5uZWwgPSBNb2NrU29ja2V0Q2hhbm5lbC5vcGVuKCk7CisgICAgICAgIGFzc2VydFRydWUodGVzdFNDaGFubmVsLmlzT3BlbigpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh0ZXN0TVNDaGFubmVsLnByb3ZpZGVyKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRlc3RTQ2hhbm5lbC5wcm92aWRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFNlbGVjdG9yUHJvdmlkZXIucHJvdmlkZXIoKSwgdGVzdFNDaGFubmVsLnByb3ZpZGVyKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRlc3RNU0NoYW5uZWxub3RudWxsLnByb3ZpZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModGhpcy5jaGFubmVsMS5wcm92aWRlcigpLCB0ZXN0TVNDaGFubmVsbm90bnVsbC5wcm92aWRlcigpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoaXMuY2hhbm5lbDEud3JpdGUoYnVmKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOb3RZZXRDb25uZWN0ZWRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTm90WWV0Q29ubmVjdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGNvcnJlY3QKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJc09wZW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0aGlzLmNoYW5uZWwxLmlzT3BlbigpKTsKKyAgICAgICAgdGhpcy5jaGFubmVsMS5jbG9zZSgpOworICAgICAgICBhc3NlcnRGYWxzZSh0aGlzLmNoYW5uZWwxLmlzT3BlbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNDb25uZWN0ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UodGhpcy5jaGFubmVsMS5pc0Nvbm5lY3RlZCgpKTsvLyBub3QgY29ubmVjdGVkCisgICAgICAgIHRoaXMuY2hhbm5lbDEuY29uZmlndXJlQmxvY2tpbmcoZmFsc2UpOworICAgICAgICBhc3NlcnRGYWxzZSh0aGlzLmNoYW5uZWwxLmNvbm5lY3QobG9jYWxBZGRyMSkpOworICAgICAgICBhc3NlcnRGYWxzZSh0aGlzLmNoYW5uZWwxLmlzQ29ubmVjdGVkKCkpOworICAgICAgICBhc3NlcnRUcnVlKHRoaXMuY2hhbm5lbDEuaXNDb25uZWN0aW9uUGVuZGluZygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0cnlGaW5pc2goKSk7CisgICAgICAgIGFzc2VydFRydWUodGhpcy5jaGFubmVsMS5pc0Nvbm5lY3RlZCgpKTsKKyAgICAgICAgdGhpcy5jaGFubmVsMS5jbG9zZSgpOworICAgICAgICBhc3NlcnRGYWxzZSh0aGlzLmNoYW5uZWwxLmlzQ29ubmVjdGVkKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJc0Nvbm5lY3Rpb25QZW5kaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIGVuc3VyZQorICAgICAgICBlbnN1cmVTZXJ2ZXJDbG9zZWQoKTsKKyAgICAgICAgdGhpcy5jaGFubmVsMS5jb25maWd1cmVCbG9ja2luZyhmYWxzZSk7CisgICAgICAgIGFzc2VydEZhbHNlKHRoaXMuY2hhbm5lbDEuaXNDb25uZWN0aW9uUGVuZGluZygpKTsKKyAgICAgICAgLy8gZmluaXNoCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGlzLmNoYW5uZWwxLmZpbmlzaENvbm5lY3QoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOb0Nvbm5lY3Rpb25QZW5kaW5nRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vQ29ubmVjdGlvblBlbmRpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gT0suCisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UodGhpcy5jaGFubmVsMS5pc0Nvbm5lY3Rpb25QZW5kaW5nKCkpOworICAgICAgICAvLyBjb25uZWN0CisgICAgICAgIGFzc2VydEZhbHNlKHRoaXMuY2hhbm5lbDEuY29ubmVjdChsb2NhbEFkZHIxKSk7CisgICAgICAgIGFzc2VydFRydWUodGhpcy5jaGFubmVsMS5pc0Nvbm5lY3Rpb25QZW5kaW5nKCkpOworICAgICAgICB0aGlzLmNoYW5uZWwxLmNsb3NlKCk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UodGhpcy5jaGFubmVsMS5pc0Nvbm5lY3Rpb25QZW5kaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDaGFubmVsQmFzaWNTdGF0dXMoKSB7CisgICAgICAgIFNvY2tldCBnb3RTb2NrZXQgPSB0aGlzLmNoYW5uZWwxLnNvY2tldCgpOworICAgICAgICBhc3NlcnRGYWxzZShnb3RTb2NrZXQuaXNDbG9zZWQoKSk7CisgICAgICAgIGFzc2VydFRydWUodGhpcy5jaGFubmVsMS5pc0Jsb2NraW5nKCkpOworICAgICAgICBhc3NlcnRGYWxzZSh0aGlzLmNoYW5uZWwxLmlzUmVnaXN0ZXJlZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChTZWxlY3Rpb25LZXkuT1BfQ09OTkVDVCB8IFNlbGVjdGlvbktleS5PUF9SRUFEIHwKKyAgICAgICAgICAgICAgICBTZWxlY3Rpb25LZXkuT1BfV1JJVEUpLCB0aGlzLmNoYW5uZWwxLnZhbGlkT3BzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoU2VsZWN0b3JQcm92aWRlci5wcm92aWRlcigpLCB0aGlzLmNoYW5uZWwxLnByb3ZpZGVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RPcGVuU29ja2V0QWRkcmVzcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMuY2hhbm5lbDEgPSBTb2NrZXRDaGFubmVsLm9wZW4obG9jYWxBZGRyMSk7CisgICAgICAgIGFzc2VydFRydWUodGhpcy5jaGFubmVsMS5pc0Nvbm5lY3RlZCgpKTsKKworICAgICAgICBTb2NrZXRBZGRyZXNzIG5ld1R5cGVBZGRyZXNzID0gbmV3IFN1YlNvY2tldEFkZHJlc3MoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoaXMuY2hhbm5lbDEgPSBTb2NrZXRDaGFubmVsLm9wZW4obmV3VHlwZUFkZHJlc3MpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IFVuZXhwZWN0ZWRBZGRyZXNzVHlwZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEFkZHJlc3NUeXBlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBTb2NrZXRBZGRyZXNzIHVucmVzb2x2ZWRBZGRyZXNzID0KKyAgICAgICAgICAgICAgICBJbmV0U29ja2V0QWRkcmVzcy5jcmVhdGVVbnJlc29sdmVkKCIxMjcuMC4wLjEiLCA4MDgwKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoaXMuY2hhbm5lbDEgPSBTb2NrZXRDaGFubmVsLm9wZW4odW5yZXNvbHZlZEFkZHJlc3MpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IFVucmVzb2x2ZWRBZGRyZXNzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFVucmVzb2x2ZWRBZGRyZXNzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBTb2NrZXRDaGFubmVsIGNoYW5uZWwxSVAgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2hhbm5lbDFJUCA9IFNvY2tldENoYW5uZWwub3BlbihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGNvcnJlY3QKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROdWxsKGNoYW5uZWwxSVApOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBlbnN1cmVTZXJ2ZXJDbG9zZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAobnVsbCAhPSB0aGlzLnNlcnZlcjEpIHsKKyAgICAgICAgICAgIHRoaXMuc2VydmVyMS5jbG9zZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSh0aGlzLnNlcnZlcjEuaXNDbG9zZWQoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc3RhdHVzQ29ubmVjdGVkX05vdFBlbmRpbmcoKSB7CisgICAgICAgIGFzc2VydFRydWUodGhpcy5jaGFubmVsMS5pc0Nvbm5lY3RlZCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UodGhpcy5jaGFubmVsMS5pc0Nvbm5lY3Rpb25QZW5kaW5nKCkpOworICAgICAgICBhc3NlcnRUcnVlKHRoaXMuY2hhbm5lbDEuaXNPcGVuKCkpOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiB0cnlGaW5pc2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvKgorICAgICAgICAgKiB0aGUgcmVzdWx0IG9mIGZpbmlzaCB3aWxsIGJlIGFzc2VydGVkIGluIG11bHRpLXRocmVhZCB0ZXN0cy4KKyAgICAgICAgICovCisgICAgICAgIGJvb2xlYW4gY29ubmVjdGVkID0gZmFsc2U7CisgICAgICAgIGFzc2VydFRydWUodGhpcy5jaGFubmVsMS5pc09wZW4oKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uZWN0ZWQgPSB0aGlzLmNoYW5uZWwxLmZpbmlzaENvbm5lY3QoKTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEZpbmlzaCBjb25uZWN0aW9uIGZhaWxlZCwgcHJvYmFibHkgZHVlIHRvIHJlc2V0IGJ5IHBlZXIgZXJyb3IuCisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvbm5lY3RlZCkgeworICAgICAgICAgICAgc3RhdHVzQ29ubmVjdGVkX05vdFBlbmRpbmcoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29ubmVjdGVkOworICAgIH0KKworICAgIEBCcm9rZW5UZXN0KCJPY2Nhc2lvbmFsbHkgZmFpbCBpbiBDVFMsIGJ1dCB3b3JrcyBpbiBDb3JlVGVzdFJ1bm5lciIpCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZUxqYXZhX25pb19CeXRlQnVmZmVyX05vbmJsb2NraW5nX0h1Z2VEYXRhKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gaW5pdGlhbGl6ZSB3cml0ZSBjb250ZW50CisgICAgICAgIEJ5dGVCdWZmZXIgd3JpdGVDb250ZW50ID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShDQVBBQ0lUWV9IVUdFKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBDQVBBQ0lUWV9IVUdFOyBpKyspIHsKKyAgICAgICAgICAgIHdyaXRlQ29udGVudC5wdXQoKGJ5dGUpIGkpOworICAgICAgICB9CisgICAgICAgIHdyaXRlQ29udGVudC5mbGlwKCk7CisKKyAgICAgICAgLy8gZXN0YWJsaXNoIGNvbm5lY3Rpb24KKyAgICAgICAgY2hhbm5lbDEuY29ubmVjdChsb2NhbEFkZHIxKTsKKyAgICAgICAgU29ja2V0IGFjY2VwdGVkU29ja2V0ID0gc2VydmVyMS5hY2NlcHQoKTsKKworICAgICAgICBjaGFubmVsMS5jb25maWd1cmVCbG9ja2luZyhmYWxzZSk7CisgICAgICAgIGludCB3cml0dGVuVG90YWxDb3VudCA9IDA7CisgICAgICAgIGludCB3cml0dGVuQ291bnQgPSAxOworICAgICAgICBsb25nIHN0YXJ0VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICAvLyB1c2UgU29ja2V0Q2hhbm5lbC53cml0ZShCeXRlQnVmZmVyKSB0byB0cnkgdG8gd3JpdGUgQ0FQQUNJVFlfSFVHRSBieXRlcworICAgICAgICB3aGlsZSAod3JpdHRlblRvdGFsQ291bnQgPCBDQVBBQ0lUWV9IVUdFICYmIHdyaXR0ZW5Db3VudCA+IDApIHsKKyAgICAgICAgICAgIHdyaXR0ZW5Db3VudCA9IGNoYW5uZWwxLndyaXRlKHdyaXRlQ29udGVudCk7CisgICAgICAgICAgICBpZiAod3JpdHRlbkNvdW50ID09IDAgJiYgd3JpdHRlblRvdGFsQ291bnQgPCBDQVBBQ0lUWV9IVUdFKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGNoYW5uZWwxLndyaXRlKHdyaXRlQ29udGVudCkpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgd3JpdHRlblRvdGFsQ291bnQgKz0gd3JpdHRlbkNvdW50OworICAgICAgICAgICAgLy8gaWYgdGhlIGNoYW5uZWwgY291bGQgbm90IGZpbmlzaCB3cml0aW5nIGluIFRJTUVPVVQgbXMsIHRoZQorICAgICAgICAgICAgLy8gdGVzdCBmYWlscy4gSXQgaXMgdXNlZCB0byBndWFyYW50ZWUgdGhlIHRlc3QgbmV2ZXIgaGFuZ3MgZXZlbgorICAgICAgICAgICAgLy8gaWYgdGhlcmUgYXJlIGJ1Z3Mgb2YgU29ja2V0Q2hhbm5lbCBpbXBsZW1lbnRhdGlvbi4KKyAgICAgICAgICAgIGFzc2VydFRpbWVvdXQoc3RhcnRUaW1lLCBUSU1FT1VUKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogRmFpbHMgaWYgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBjdXJyZW50IHRpbWUgYW5kIHN0YXJ0IHRpbWUgaXMgZ3JlYXRlcgorICAgICAqIHRoYW4gdGltZW91dC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0VGltZW91dChsb25nIHN0YXJ0VGltZSwgbG9uZyB0aW1lb3V0KSB7CisgICAgICAgIGxvbmcgY3VycmVudFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgaWYgKChjdXJyZW50VGltZSAtIHN0YXJ0VGltZSkgPiB0aW1lb3V0KSB7CisgICAgICAgICAgICBmYWlsKCJUaW1lb3V0Iik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NvY2tldENoYW5uZWxfcmVhZF9EaXJlY3RCeXRlQnVmZmVyKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgU2VydmVyVGhyZWFkIHNlcnZlciA9IG5ldyBTZXJ2ZXJUaHJlYWQoKTsKKyAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuc2xlZXAoMTAwMCk7CisKKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgYWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcyhJbmV0QWRkcmVzcworICAgICAgICAgICAgICAgIC5nZXRCeU5hbWUoImxvY2FsaG9zdCIpLCBwb3J0KTsKKworICAgICAgICAvLyBGaXJzdCB0ZXN0IHdpdGggYXJyYXkgYmFzZWQgYnl0ZSBidWZmZXIKKyAgICAgICAgU29ja2V0Q2hhbm5lbCBzYyA9IFNvY2tldENoYW5uZWwub3BlbigpOworICAgICAgICBzYy5jb25uZWN0KGFkZHJlc3MpOworCisgICAgICAgIEJ5dGVCdWZmZXIgYnVmID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShkYXRhLmxlbmd0aCk7CisgICAgICAgIGJ1Zi5saW1pdChkYXRhLmxlbmd0aCAvIDIpOworICAgICAgICBzYy5yZWFkKGJ1Zik7CisKKyAgICAgICAgYnVmLmxpbWl0KGJ1Zi5jYXBhY2l0eSgpKTsKKyAgICAgICAgc2MucmVhZChidWYpOworICAgICAgICBzYy5jbG9zZSgpOworCisgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGUgYnVmZmVyIGlzIGZpbGxlZCBjb3JyZWN0bHkKKyAgICAgICAgYnVmLnJld2luZCgpOworICAgICAgICBhc3NlcnRTYW1lQ29udGVudChkYXRhLCBidWYpOworCisgICAgICAgIC8vIE5vdyB0ZXN0IHdpdGggZGlyZWN0IGJ5dGUgYnVmZmVyCisgICAgICAgIHNjID0gU29ja2V0Q2hhbm5lbC5vcGVuKCk7CisgICAgICAgIHNjLmNvbm5lY3QoYWRkcmVzcyk7CisKKyAgICAgICAgYnVmID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZURpcmVjdChkYXRhLmxlbmd0aCk7CisgICAgICAgIGJ1Zi5saW1pdChkYXRhLmxlbmd0aCAvIDIpOworICAgICAgICBzYy5yZWFkKGJ1Zik7CisKKyAgICAgICAgYnVmLmxpbWl0KGJ1Zi5jYXBhY2l0eSgpKTsKKyAgICAgICAgc2MucmVhZChidWYpOworICAgICAgICBzYy5jbG9zZSgpOworCisgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGUgYnVmZmVyIGlzIGZpbGxlZCBjb3JyZWN0bHkKKyAgICAgICAgYnVmLnJld2luZCgpOworICAgICAgICBhc3NlcnRTYW1lQ29udGVudChkYXRhLCBidWYpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRTYW1lQ29udGVudChieXRlW10gZGF0YSwgQnl0ZUJ1ZmZlciBidWYpIHsKKyAgICAgICAgZm9yIChieXRlIGIgOiBkYXRhKSB7CisgICAgICAgICAgICBpZiAoYiAhPSBidWYuZ2V0KCkpIHsKKyAgICAgICAgICAgICAgICBpbnQgcG9zID0gYnVmLnBvc2l0aW9uKCkgLSAxOworICAgICAgICAgICAgICAgIGZhaWwoIkNvbnRlbnQgbm90IGVxdWFsLiBCdWZmZXIgcG9zaXRpb246ICIgKworICAgICAgICAgICAgICAgICAgICAgICAgKHBvcykgKyAiIGV4cGVjdGVkOiAiICsgYiArICIgd2FzOiAiICsgYnVmLmdldChwb3MpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBkb25lID0gZmFsc2U7CisgICAgcHVibGljIHN0YXRpYyBpbnQgcG9ydCA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBkYXRhID0gezEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwfTsKKworICAgIHN0YXRpYyBjbGFzcyBTZXJ2ZXJUaHJlYWQgZXh0ZW5kcyBUaHJlYWQgeworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTZXJ2ZXJTb2NrZXRDaGFubmVsIHNzYyA9IFNlcnZlclNvY2tldENoYW5uZWwub3BlbigpOworICAgICAgICAgICAgICAgIEluZXRTb2NrZXRBZGRyZXNzIGFkZHIgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoSW5ldEFkZHJlc3MKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRCeUFkZHJlc3MobmV3IGJ5dGVbXSB7MCwgMCwgMCwgMH0pLCBwb3J0KTsKKyAgICAgICAgICAgICAgICBzc2Muc29ja2V0KCkuYmluZChhZGRyLCAwKTsKKworICAgICAgICAgICAgICAgIEJ5dGVCdWZmZXIgYnVmID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCk7CisgICAgICAgICAgICAgICAgYnVmLnB1dChkYXRhKTsKKworICAgICAgICAgICAgICAgIHdoaWxlICghZG9uZSkgeworICAgICAgICAgICAgICAgICAgICBTb2NrZXRDaGFubmVsIHNjID0gc3NjLmFjY2VwdCgpOworICAgICAgICAgICAgICAgICAgICBidWYucmV3aW5kKCk7CisgICAgICAgICAgICAgICAgICAgIHNjLndyaXRlKGJ1Zik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBpZ25vcmUKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIE1vY2tTb2NrZXRDaGFubmVsIGV4dGVuZHMgU29ja2V0Q2hhbm5lbCB7CisKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzQ29uc3RydWN0b3JDYWxsZWQgPSBmYWxzZTsKKworICAgICAgICBwdWJsaWMgTW9ja1NvY2tldENoYW5uZWwoU2VsZWN0b3JQcm92aWRlciBwcm92aWRlcikgeworICAgICAgICAgICAgc3VwZXIocHJvdmlkZXIpOworICAgICAgICAgICAgaXNDb25zdHJ1Y3RvckNhbGxlZCA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU29ja2V0IHNvY2tldCgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNDb25uZWN0ZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0Nvbm5lY3Rpb25QZW5kaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gY29ubmVjdChTb2NrZXRBZGRyZXNzIGFkZHJlc3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBmaW5pc2hDb25uZWN0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgcmVhZChCeXRlQnVmZmVyIHRhcmdldCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGxvbmcgcmVhZChCeXRlQnVmZmVyW10gdGFyZ2V0cywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IHdyaXRlKEJ5dGVCdWZmZXIgc291cmNlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgbG9uZyB3cml0ZShCeXRlQnVmZmVyW10gc291cmNlcywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgdm9pZCBpbXBsQ2xvc2VTZWxlY3RhYmxlQ2hhbm5lbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBlbXB0eQorICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgaW1wbENvbmZpZ3VyZUJsb2NraW5nKGJvb2xlYW4gYmxvY2tpbmdNb2RlKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBlbXB0eQorICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgU3ViU29ja2V0QWRkcmVzcyBleHRlbmRzIFNvY2tldEFkZHJlc3MgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKworICAgICAgICAvLyBlbXB0eQorICAgICAgICBwdWJsaWMgU3ViU29ja2V0QWRkcmVzcygpIHsKKyAgICAgICAgICAgIHN1cGVyKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFubmVscy9QaXBlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhbm5lbHMvUGlwZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNzY4ZGU3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhbm5lbHMvUGlwZVRlc3QuamF2YQpAQCAtMCwwICsxLDI4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYW5uZWxzOworCitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5QaXBlOworCitwdWJsaWMgY2xhc3MgUGlwZVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZEVtcHR5UGlwZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQaXBlIHAgPSBQaXBlLm9wZW4oKTsKKyAgICAgICAgcC5zb3VyY2UoKS5jb25maWd1cmVCbG9ja2luZyhmYWxzZSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBwLnNvdXJjZSgpLnJlYWQoQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxKSkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYW5uZWxzL1NlbGVjdG9yVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhbm5lbHMvU2VsZWN0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWE5NThhZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYW5uZWxzL1NlbGVjdG9yVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTI0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFubmVsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU2VydmVyU29ja2V0OworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLk5vQ29ubmVjdGlvblBlbmRpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU2VsZWN0aW9uS2V5OworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlbGVjdG9yOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlcnZlclNvY2tldENoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU29ja2V0Q2hhbm5lbDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db3VudERvd25MYXRjaDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgdGVzdHMubmV0LlN0dWNrU2VydmVyOworCitwdWJsaWMgY2xhc3MgU2VsZWN0b3JUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3ROb25CbG9ja2luZ0Nvbm5lY3RfaW1tZWRpYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgdGhlIGNhc2Ugd2hlcmUgd2UgW3Byb2JhYmx5XSBjb25uZWN0IGltbWVkaWF0ZWx5LgorICAgICAgICBTZWxlY3RvciBzZWxlY3RvciA9IFNlbGVjdG9yLm9wZW4oKTsKKyAgICAgICAgU2VydmVyU29ja2V0Q2hhbm5lbCBzc2MgPSBTZXJ2ZXJTb2NrZXRDaGFubmVsLm9wZW4oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzYy5jb25maWd1cmVCbG9ja2luZyhmYWxzZSk7CisgICAgICAgICAgICBzc2Muc29ja2V0KCkuYmluZChudWxsKTsKKworICAgICAgICAgICAgU29ja2V0Q2hhbm5lbCBzYyA9IFNvY2tldENoYW5uZWwub3BlbigpOworICAgICAgICAgICAgc2MuY29uZmlndXJlQmxvY2tpbmcoZmFsc2UpOworICAgICAgICAgICAgc2MuY29ubmVjdChzc2Muc29ja2V0KCkuZ2V0TG9jYWxTb2NrZXRBZGRyZXNzKCkpOworICAgICAgICAgICAgU2VsZWN0aW9uS2V5IGtleSA9IHNjLnJlZ2lzdGVyKHNlbGVjdG9yLCBTZWxlY3Rpb25LZXkuT1BfQ09OTkVDVCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgc2VsZWN0b3Iuc2VsZWN0KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFNlbGVjdGlvbktleS5PUF9DT05ORUNULCBrZXkucmVhZHlPcHMoKSk7CisgICAgICAgICAgICBzYy5maW5pc2hDb25uZWN0KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzZWxlY3Rvci5jbG9zZSgpOworICAgICAgICAgICAgc3NjLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9uQmxvY2tpbmdDb25uZWN0X3Nsb3coKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCB0aGUgY2FzZSB3aGVyZSB3ZSBoYXZlIHRvIHdhaXQgZm9yIHRoZSBjb25uZWN0aW9uLgorICAgICAgICBTZWxlY3RvciBzZWxlY3RvciA9IFNlbGVjdG9yLm9wZW4oKTsKKyAgICAgICAgU3R1Y2tTZXJ2ZXIgc3MgPSBuZXcgU3R1Y2tTZXJ2ZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldENoYW5uZWwgc2MgPSBTb2NrZXRDaGFubmVsLm9wZW4oKTsKKyAgICAgICAgICAgIHNjLmNvbmZpZ3VyZUJsb2NraW5nKGZhbHNlKTsKKyAgICAgICAgICAgIHNzLnVuYmxvY2tBZnRlck1zKDIwMDApOworICAgICAgICAgICAgc2MuY29ubmVjdChzcy5nZXRMb2NhbFNvY2tldEFkZHJlc3MoKSk7CisgICAgICAgICAgICBTZWxlY3Rpb25LZXkga2V5ID0gc2MucmVnaXN0ZXIoc2VsZWN0b3IsIFNlbGVjdGlvbktleS5PUF9DT05ORUNUKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBzZWxlY3Rvci5zZWxlY3QoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoU2VsZWN0aW9uS2V5Lk9QX0NPTk5FQ1QsIGtleS5yZWFkeU9wcygpKTsKKyAgICAgICAgICAgIHNjLmZpbmlzaENvbm5lY3QoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHNlbGVjdG9yLmNsb3NlKCk7CisgICAgICAgICAgICBzcy5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD0xNTM4OAorICAgIHB1YmxpYyB2b2lkIHRlc3RJbnRlcnJ1cHRlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFNlbGVjdG9yIHNlbGVjdG9yID0gU2VsZWN0b3Iub3BlbigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5pbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgIGludCBjb3VudCA9IHNlbGVjdG9yLnNlbGVjdCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGNvdW50KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHNlbGVjdG9yLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFueVdha2V1cENhbGxzVHJpZ2dlck9ubHlPbmVXYWtldXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU2VsZWN0b3Igc2VsZWN0b3IgPSBTZWxlY3Rvci5vcGVuKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZWxlY3Rvci53YWtldXAoKTsKKyAgICAgICAgICAgIHNlbGVjdG9yLndha2V1cCgpOworICAgICAgICAgICAgc2VsZWN0b3Iud2FrZXVwKCk7CisgICAgICAgICAgICBzZWxlY3Rvci5zZWxlY3QoKTsKKworICAgICAgICAgICAgLy8gY3JlYXRlIGEgbGF0Y2ggdGhhdCB3aWxsIHJlYWNoIDAgd2hlbiBzZWxlY3QgcmV0dXJucworICAgICAgICAgICAgZmluYWwgQ291bnREb3duTGF0Y2ggc2VsZWN0UmV0dXJuZWQgPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisgICAgICAgICAgICBUaHJlYWQgdGhyZWFkID0gbmV3IFRocmVhZChuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yLnNlbGVjdCgpOworICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0UmV0dXJuZWQuY291bnREb3duKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICAgICAgICAgICAgdGhyZWFkLnN0YXJ0KCk7CisKKyAgICAgICAgICAgIC8vIHNlbGVjdCBkb2Vzbid0IGV2ZXIgcmV0dXJuLCBzbyBhd2FpdCgpIHRpbWVzIG91dCBhbmQgcmV0dXJucyBmYWxzZQorICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc2VsZWN0UmV0dXJuZWQuYXdhaXQoNTAwLCBUaW1lVW5pdC5NSUxMSVNFQ09ORFMpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHNlbGVjdG9yLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXZSBwcmV2aW91c2x5IGxlYWtlZCBhIGZpbGUgZGVzY3JpcHRvciBmb3IgZWFjaCBzZWxlY3RvciBpbnN0YW5jZSBjcmVhdGVkLgorICAgICAqCisgICAgICogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD01OTkzCisgICAgICogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD00ODI1CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdExlYWtpbmdQaXBlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjAwMDsgaSsrKSB7CisgICAgICAgICAgICBTZWxlY3RvciBzZWxlY3RvciA9IFNlbGVjdG9yLm9wZW4oKTsKKyAgICAgICAgICAgIHNlbGVjdG9yLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFubmVscy9TZXJ2ZXJTb2NrZXRDaGFubmVsVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhbm5lbHMvU2VydmVyU29ja2V0Q2hhbm5lbFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjYwOTZjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhbm5lbHMvU2VydmVyU29ja2V0Q2hhbm5lbFRlc3QuamF2YQpAQCAtMCwwICsxLDM0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYW5uZWxzOworCitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU2VydmVyU29ja2V0Q2hhbm5lbDsKKworcHVibGljIGNsYXNzIFNlcnZlclNvY2tldENoYW5uZWxUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTE2NTc5CisgICAgcHVibGljIHZvaWQgdGVzdE5vbkJsb2NraW5nQWNjZXB0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNlcnZlclNvY2tldENoYW5uZWwgc3NjID0gU2VydmVyU29ja2V0Q2hhbm5lbC5vcGVuKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2MuY29uZmlndXJlQmxvY2tpbmcoZmFsc2UpOworICAgICAgICAgICAgc3NjLnNvY2tldCgpLmJpbmQobnVsbCk7CisgICAgICAgICAgICAvLyBTaG91bGQgcmV0dXJuIGltbWVkaWF0ZWx5LCBzaW5jZSB3ZSdyZSBub24tYmxvY2tpbmcuCisgICAgICAgICAgICBhc3NlcnROdWxsKHNzYy5hY2NlcHQoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzc2MuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYW5uZWxzL1NvY2tldENoYW5uZWxUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFubmVscy9Tb2NrZXRDaGFubmVsVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlY2UzMDYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFubmVscy9Tb2NrZXRDaGFubmVsVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhbm5lbHM7CisKK2ltcG9ydCBqYXZhLm5ldC5TZXJ2ZXJTb2NrZXQ7CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5Tb2NrZXRDaGFubmVsOworCitwdWJsaWMgY2xhc3MgU29ja2V0Q2hhbm5lbFRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZF9pbnRvUmVhZE9ubHlCeXRlQXJyYXlzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVCdWZmZXIgcmVhZE9ubHkgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEpLmFzUmVhZE9ubHlCdWZmZXIoKTsKKyAgICAgICAgU2VydmVyU29ja2V0IHNzID0gbmV3IFNlcnZlclNvY2tldCgwKTsKKyAgICAgICAgc3Muc2V0UmV1c2VBZGRyZXNzKHRydWUpOworICAgICAgICBTb2NrZXRDaGFubmVsIHNjID0gU29ja2V0Q2hhbm5lbC5vcGVuKHNzLmdldExvY2FsU29ja2V0QWRkcmVzcygpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNjLnJlYWQocmVhZE9ubHkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc2MucmVhZChuZXcgQnl0ZUJ1ZmZlcltdIHsgcmVhZE9ubHkgfSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzYy5yZWFkKG5ldyBCeXRlQnVmZmVyW10geyByZWFkT25seSB9LCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L0NoYXJzZXREZWNvZGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0RGVjb2RlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lODc0YTFiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0RGVjb2RlclRlc3QuamF2YQpAQCAtMCwwICsxLDEwOCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFyc2V0OworCitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5DaGFyQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXREZWNvZGVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldEVuY29kZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5Db2RlclJlc3VsdDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNvZGluZ0Vycm9yQWN0aW9uOworCitwdWJsaWMgY2xhc3MgQ2hhcnNldERlY29kZXJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICAvLyBOb25lIG9mIHRoZSBoYXJtb255IG9yIGp0cmVnIHRlc3RzIGFjdHVhbGx5IGNoZWNrIHRoYXQgcmVwbGFjZVdpdGggZG9lcyB0aGUgcmlnaHQgdGhpbmchCisgICAgcHVibGljIHZvaWQgdGVzdF9yZXBsYWNlV2l0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaGFyc2V0RGVjb2RlciBkID0gQ2hhcnNldC5mb3JOYW1lKCJVVEYtMTYiKS5uZXdEZWNvZGVyKCk7CisgICAgICAgIGQucmVwbGFjZVdpdGgoIngiKTsKKyAgICAgICAgZC5vbk1hbGZvcm1lZElucHV0KENvZGluZ0Vycm9yQWN0aW9uLlJFUExBQ0UpOworICAgICAgICBkLm9uVW5tYXBwYWJsZUNoYXJhY3RlcihDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBpbiA9IEJ5dGVCdWZmZXIud3JhcChuZXcgYnl0ZVtdIHsgMTA5LCA5NywgMTA5IH0pOworICAgICAgICBhc3NlcnRFcXVhbHMoIlx1NmQ2MXgiLCBkLmRlY29kZShpbikudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD00MjM3CisgICAgcHVibGljIHZvaWQgdGVzdF9CeXRlQXJyYXlfZGVjb2RlX25vX29mZnNldCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaGFyc2V0RGVjb2RlciBkZWNvZGVyID0gQ2hhcnNldC5mb3JOYW1lKCJVVEYtMTYiKS5uZXdEZWNvZGVyKCk7CisgICAgICAgIGJ5dGVbXSBhcnIgPSBlbmNvZGUoIlVURi0xNiIsICJBbmRyb2lkIik7CisgICAgICAgIEJ5dGVCdWZmZXIgaW5CdWZmZXIgPSBCeXRlQnVmZmVyLndyYXAoYXJyLCAwLCBhcnIubGVuZ3RoKS5zbGljZSgpOworICAgICAgICBDaGFyQnVmZmVyIG91dEJ1ZmZlciA9IENoYXJCdWZmZXIuYWxsb2NhdGUoYXJyLmxlbmd0aCk7CisgICAgICAgIGRlY29kZXIucmVzZXQoKTsKKyAgICAgICAgQ29kZXJSZXN1bHQgY29kZXJSZXN1bHQgPSBkZWNvZGVyLmRlY29kZShpbkJ1ZmZlciwgb3V0QnVmZmVyLCB0cnVlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoY29kZXJSZXN1bHQudG9TdHJpbmcoKSwgY29kZXJSZXN1bHQuaXNFcnJvcigpKTsKKyAgICAgICAgZGVjb2Rlci5mbHVzaChvdXRCdWZmZXIpOworICAgICAgICBvdXRCdWZmZXIuZmxpcCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFuZHJvaWQiLCBvdXRCdWZmZXIudG9TdHJpbmcoKS50cmltKCkpOworICAgIH0KKworICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9NDIzNworICAgIHB1YmxpYyB2b2lkIHRlc3RfQnl0ZUFycmF5X2RlY29kZV93aXRoX29mZnNldCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaGFyc2V0RGVjb2RlciBkZWNvZGVyID0gQ2hhcnNldC5mb3JOYW1lKCJVVEYtMTYiKS5uZXdEZWNvZGVyKCk7CisgICAgICAgIGJ5dGVbXSBhcnIgPSBlbmNvZGUoIlVURi0xNiIsICJBbmRyb2lkIik7CisgICAgICAgIGFyciA9IHByZXBlbmRCeXRlVG9CeXRlQXJyYXkoYXJyLCBuZXcgSW50ZWdlcigxKS5ieXRlVmFsdWUoKSk7CisgICAgICAgIGludCBvZmZzZXQgPSAxOworICAgICAgICBCeXRlQnVmZmVyIGluQnVmZmVyID0gQnl0ZUJ1ZmZlci53cmFwKGFyciwgb2Zmc2V0LCBhcnIubGVuZ3RoIC0gb2Zmc2V0KS5zbGljZSgpOworICAgICAgICBDaGFyQnVmZmVyIG91dEJ1ZmZlciA9IENoYXJCdWZmZXIuYWxsb2NhdGUoYXJyLmxlbmd0aCAtIG9mZnNldCk7CisgICAgICAgIGRlY29kZXIucmVzZXQoKTsKKyAgICAgICAgQ29kZXJSZXN1bHQgY29kZXJSZXN1bHQgPSBkZWNvZGVyLmRlY29kZShpbkJ1ZmZlciwgb3V0QnVmZmVyLCB0cnVlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoY29kZXJSZXN1bHQudG9TdHJpbmcoKSwgY29kZXJSZXN1bHQuaXNFcnJvcigpKTsKKyAgICAgICAgZGVjb2Rlci5mbHVzaChvdXRCdWZmZXIpOworICAgICAgICBvdXRCdWZmZXIuZmxpcCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFuZHJvaWQiLCBvdXRCdWZmZXIudG9TdHJpbmcoKS50cmltKCkpOworICAgIH0KKworICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9NDIzNworICAgIHB1YmxpYyB2b2lkIHRlc3RfQnl0ZUFycmF5X2RlY29kZV93aXRoX29mZnNldF91c2luZ19mYWNhZGVfbWV0aG9kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENoYXJzZXREZWNvZGVyIGRlY29kZXIgPSBDaGFyc2V0LmZvck5hbWUoIlVURi0xNiIpLm5ld0RlY29kZXIoKTsKKyAgICAgICAgYnl0ZVtdIGFyciA9IGVuY29kZSgiVVRGLTE2IiwgIkFuZHJvaWQiKTsKKyAgICAgICAgYXJyID0gcHJlcGVuZEJ5dGVUb0J5dGVBcnJheShhcnIsIG5ldyBJbnRlZ2VyKDEpLmJ5dGVWYWx1ZSgpKTsKKyAgICAgICAgaW50IG9mZnNldCA9IDE7CisgICAgICAgIENoYXJCdWZmZXIgb3V0QnVmZmVyID0gZGVjb2Rlci5kZWNvZGUoQnl0ZUJ1ZmZlci53cmFwKGFyciwgb2Zmc2V0LCBhcnIubGVuZ3RoIC0gb2Zmc2V0KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQW5kcm9pZCIsIG91dEJ1ZmZlci50b1N0cmluZygpLnRyaW0oKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdIHByZXBlbmRCeXRlVG9CeXRlQXJyYXkoYnl0ZVtdIGFyciwgYnl0ZSBiKSB7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVthcnIubGVuZ3RoICsgMV07CisgICAgICAgIHJlc3VsdFswXSA9IGI7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYXJyLCAwLCByZXN1bHQsIDEsIGFyci5sZW5ndGgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBlbmNvZGUoU3RyaW5nIGNoYXJzZXROYW1lLCBTdHJpbmcgcykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENoYXJzZXRFbmNvZGVyIGVuY29kZXIgPSBDaGFyc2V0LmZvck5hbWUoY2hhcnNldE5hbWUpLm5ld0VuY29kZXIoKTsKKyAgICAgICAgcmV0dXJuIGVuY29kZXIuZW5jb2RlKENoYXJCdWZmZXIud3JhcChzKSkuYXJyYXkoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXRmOEJ5dGVzU3BsaXRBY3Jvc3NNdWx0aXBsZVdyaXRlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaGFyc2V0RGVjb2RlciBkZWNvZGVyID0gQ2hhcnNldC5mb3JOYW1lKCJVVEYtOCIpLm5ld0RlY29kZXIoKTsKKyAgICAgICAgQ2hhckJ1ZmZlciBjYiA9IENoYXJCdWZmZXIuYWxsb2NhdGUoMTI4KTsKKyAgICAgICAgQ29kZXJSZXN1bHQgY3I7CisgICAgICAgIGNyID0gZGVjb2Rlci5kZWNvZGUoQnl0ZUJ1ZmZlci53cmFwKG5ldyBieXRlW10geyAoYnl0ZSkgMHhlMiB9KSwgY2IsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENvZGVyUmVzdWx0LlVOREVSRkxPVywgY3IpOworICAgICAgICBjciA9IGRlY29kZXIuZGVjb2RlKEJ5dGVCdWZmZXIud3JhcChuZXcgYnl0ZVtdIHsgKGJ5dGUpIDB4OTggfSksIGNiLCBmYWxzZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb2RlclJlc3VsdC5VTkRFUkZMT1csIGNyKTsKKyAgICAgICAgY3IgPSBkZWNvZGVyLmRlY29kZShCeXRlQnVmZmVyLndyYXAobmV3IGJ5dGVbXSB7IChieXRlKSAweDgzIH0pLCBjYiwgZmFsc2UpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29kZXJSZXN1bHQuVU5ERVJGTE9XLCBjcik7CisgICAgICAgIGNyID0gZGVjb2Rlci5kZWNvZGUoQnl0ZUJ1ZmZlci53cmFwKG5ldyBieXRlWzBdKSwgY2IsIHRydWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29kZXJSZXN1bHQuVU5ERVJGTE9XLCBjcik7CisgICAgICAgIGNyID0gZGVjb2Rlci5mbHVzaChjYik7CisgICAgICAgIGFzc2VydEVxdWFscyhDb2RlclJlc3VsdC5VTkRFUkZMT1csIGNyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNiLnBvc2l0aW9uKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ1x1MjYwMycsIGNiLmdldCgwKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0RW5jb2RlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldEVuY29kZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDczM2E5ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldEVuY29kZXJUZXN0LmphdmEKQEAgLTAsMCArMSwyMDcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uQ2hhckJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0RW5jb2RlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNvZGVyUmVzdWx0OworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ29kaW5nRXJyb3JBY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworcHVibGljIGNsYXNzIENoYXJzZXRFbmNvZGVyVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgLy8gTm9uZSBvZiB0aGUgaGFybW9ueSBvciBqdHJlZyB0ZXN0cyBhY3R1YWxseSBjaGVjayB0aGF0IHJlcGxhY2VXaXRoIGRvZXMgdGhlIHJpZ2h0IHRoaW5nIQorICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVwbGFjZVdpdGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2hhcnNldCBhc2NpaSA9IENoYXJzZXQuZm9yTmFtZSgiVVMtQVNDSUkiKTsKKyAgICAgICAgQ2hhcnNldEVuY29kZXIgZSA9IGFzY2lpLm5ld0VuY29kZXIoKTsKKyAgICAgICAgZS5vbk1hbGZvcm1lZElucHV0KENvZGluZ0Vycm9yQWN0aW9uLlJFUExBQ0UpOworICAgICAgICBlLm9uVW5tYXBwYWJsZUNoYXJhY3RlcihDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFKTsKKyAgICAgICAgZS5yZXBsYWNlV2l0aCgiPSIuZ2V0Qnl0ZXMoIlVTLUFTQ0lJIikpOworICAgICAgICBTdHJpbmcgaW5wdXQgPSAiaGVsbG9cdTA2NjZ3b3JsZCI7CisgICAgICAgIFN0cmluZyBvdXRwdXQgPSBhc2NpaS5kZWNvZGUoZS5lbmNvZGUoQ2hhckJ1ZmZlci53cmFwKGlucHV0KSkpLnRvU3RyaW5nKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiaGVsbG89d29ybGQiLCBvdXRwdXQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRSZXBsYWNlbWVudEJ5dGVzRm9yRW5jb2RlcihTdHJpbmcgY2hhcnNldCwgYnl0ZVtdIGJ5dGVzKSB7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBDaGFyc2V0LmZvck5hbWUoY2hhcnNldCkubmV3RW5jb2RlcigpLnJlcGxhY2VtZW50KCk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMudG9TdHJpbmcoYnl0ZXMpLCBBcnJheXMudG9TdHJpbmcocmVzdWx0KSk7CisgICAgfQorCisgICAgLy8gRm9yIGFsbCB0aGUgZ3VhcmFudGVlZCBidWlsdC1pbiBjaGFyc2V0cywgY2hlY2sgdGhhdCB3ZSBoYXZlIHRoZSByaWdodCBkZWZhdWx0IHJlcGxhY2VtZW50cy4KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RlZmF1bHRSZXBsYWNlbWVudEJ5dGVzSXNvXzg4NTlfMSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRSZXBsYWNlbWVudEJ5dGVzRm9yRW5jb2RlcigiSVNPLTg4NTktMSIsIG5ldyBieXRlW10geyAoYnl0ZSkgJz8nIH0pOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RlZmF1bHRSZXBsYWNlbWVudEJ5dGVzVXNfQXNjaWkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UmVwbGFjZW1lbnRCeXRlc0ZvckVuY29kZXIoIlVTLUFTQ0lJIiwgbmV3IGJ5dGVbXSB7IChieXRlKSAnPycgfSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZGVmYXVsdFJlcGxhY2VtZW50Qnl0ZXNVdGZfMTYoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UmVwbGFjZW1lbnRCeXRlc0ZvckVuY29kZXIoIlVURi0xNiIsIG5ldyBieXRlW10geyAoYnl0ZSkgMHhmZiwgKGJ5dGUpIDB4ZmQgfSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZGVmYXVsdFJlcGxhY2VtZW50Qnl0ZXNVdGZfMTZiZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRSZXBsYWNlbWVudEJ5dGVzRm9yRW5jb2RlcigiVVRGLTE2QkUiLCBuZXcgYnl0ZVtdIHsgKGJ5dGUpIDB4ZmYsIChieXRlKSAweGZkIH0pOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RlZmF1bHRSZXBsYWNlbWVudEJ5dGVzVXRmXzE2bGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UmVwbGFjZW1lbnRCeXRlc0ZvckVuY29kZXIoIlVURi0xNkxFIiwgbmV3IGJ5dGVbXSB7IChieXRlKSAweGZkLCAoYnl0ZSkgMHhmZiB9KTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdF9kZWZhdWx0UmVwbGFjZW1lbnRCeXRlc1V0Zl84KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFJlcGxhY2VtZW50Qnl0ZXNGb3JFbmNvZGVyKCJVVEYtOCIsIG5ldyBieXRlW10geyAoYnl0ZSkgJz8nIH0pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdXJyb2dhdGVQYWlyQWxsQXRPbmNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIG9rYXk6IHN1cnJvZ2F0ZSBwYWlyIHNlZW4gYWxsIGF0IG9uY2UgaXMgZGVjb2RlZCB0byBVKzIwYjlmLgorICAgICAgICBDaGFyc2V0IGNzID0gQ2hhcnNldC5mb3JOYW1lKCJVVEYtMzJCRSIpOworICAgICAgICBDaGFyc2V0RW5jb2RlciBlID0gY3MubmV3RW5jb2RlcigpOworICAgICAgICBCeXRlQnVmZmVyIGJiID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMjgpOworICAgICAgICBDb2RlclJlc3VsdCBjciA9IGUuZW5jb2RlKENoYXJCdWZmZXIud3JhcChuZXcgY2hhcltdIHsgJ1x1ZDg0MicsICdcdWRmOWYnIH0pLCBiYiwgZmFsc2UpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29kZXJSZXN1bHQuVU5ERVJGTE9XLCBjcik7CisgICAgICAgIGFzc2VydEVxdWFscyg0LCBiYi5wb3NpdGlvbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweDAwLCBiYi5nZXQoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDB4MDIsIGJiLmdldCgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHgwYiwgYmIuZ2V0KDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweDlmLCBiYi5nZXQoMykpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYWxmb3JtZWRTdXJyb2dhdGVQYWlyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIG1hbGZvcm1lZDogbG93IHN1cnJvZ2F0ZSBmaXJzdCBpcyBkZXRlY3RlZCBhcyBhbiBlcnJvci4KKyAgICAgICAgQ2hhcnNldCBjcyA9IENoYXJzZXQuZm9yTmFtZSgiVVRGLTMyQkUiKTsKKyAgICAgICAgQ2hhcnNldEVuY29kZXIgZSA9IGNzLm5ld0VuY29kZXIoKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYiA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTI4KTsKKyAgICAgICAgQ29kZXJSZXN1bHQgY3IgPSBlLmVuY29kZShDaGFyQnVmZmVyLndyYXAobmV3IGNoYXJbXSB7ICdcdWRmOWYnIH0pLCBiYiwgZmFsc2UpOworICAgICAgICBhc3NlcnRUcnVlKGNyLnRvU3RyaW5nKCksIGNyLmlzTWFsZm9ybWVkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY3IubGVuZ3RoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDaGFyc2V0RW5jb2RlclN1cnJvZ2F0ZXNCcm9rZW5CeURlc2lnbl9JR05PUkVfUkkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdENoYXJzZXRFbmNvZGVyU3Vycm9nYXRlc0Jyb2tlbkJ5RGVzaWduX1JJKENvZGluZ0Vycm9yQWN0aW9uLklHTk9SRSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENoYXJzZXRFbmNvZGVyU3Vycm9nYXRlc0Jyb2tlbkJ5RGVzaWduX1JFUE9SVF9SSSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Q2hhcnNldEVuY29kZXJTdXJyb2dhdGVzQnJva2VuQnlEZXNpZ25fUkkoQ29kaW5nRXJyb3JBY3Rpb24uUkVQT1JUKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2hhcnNldEVuY29kZXJTdXJyb2dhdGVzQnJva2VuQnlEZXNpZ25fUkVQTEFDRV9SSSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Q2hhcnNldEVuY29kZXJTdXJyb2dhdGVzQnJva2VuQnlEZXNpZ25fUkkoQ29kaW5nRXJyb3JBY3Rpb24uUkVQTEFDRSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RDaGFyc2V0RW5jb2RlclN1cnJvZ2F0ZXNCcm9rZW5CeURlc2lnbl9SSShDb2RpbmdFcnJvckFjdGlvbiBjZWEpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBzdHVwaWQ6IG9uIHRoZSBSSSwgd3JpdGluZyB0aGUgdHdvIGhhbHZlcyBvZiB0aGUgc3Vycm9nYXRlIHBhaXIgaW4gc2VwYXJhdGUgd3JpdGVzCisgICAgICAgIC8vIGlzIGFuIGVycm9yIGJlY2F1c2UgdGhlIENoYXJzZXRFbmNvZGVyIGRvZXNuJ3QgcmVtZW1iZXIgaXQncyBoYWxmLXdheSB0aHJvdWdoIGEKKyAgICAgICAgLy8gc3Vycm9nYXRlIHBhaXIgYWNyb3NzIHRoZSB0d28gY2FsbHMhCisKKyAgICAgICAgLy8gSUdOT1JFIGp1c3QgaWdub3JlcyBib3RoIGNoYXJhY3RlcnMsIFJFUE9SVCBjb21wbGFpbnMgdGhhdCB0aGUgc2Vjb25kIGlzCisgICAgICAgIC8vIGludmFsaWQgKGJlY2F1c2UgaXQgZG9lc24ndCByZW1lbWJlciBzZWVpbmcgdGhlIGZpcnN0KSwgYW5kIFJFUExBQ0UgaW5zZXJ0cyBhCisgICAgICAgIC8vIHJlcGxhY2VtZW50IGNoYXJhY3RlciBVK2ZmZmQgd2hlbiBpdCBzZWVzIHRoZSBzZWNvbmQgY2hhcmFjdGVyIChiZWNhdXNlIGl0IHRvbworICAgICAgICAvLyBkb2Vzbid0IHJlbWVtYmVyIHNlZWluZyB0aGUgZmlyc3QpLgorCisgICAgICAgIENoYXJzZXQgY3MgPSBDaGFyc2V0LmZvck5hbWUoIlVURi0zMkJFIik7CisgICAgICAgIENoYXJzZXRFbmNvZGVyIGUgPSBjcy5uZXdFbmNvZGVyKCk7CisgICAgICAgIGUub25NYWxmb3JtZWRJbnB1dChjZWEpOworICAgICAgICBlLm9uVW5tYXBwYWJsZUNoYXJhY3RlcihjZWEpOworICAgICAgICBCeXRlQnVmZmVyIGJiID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMjgpOworICAgICAgICBDb2RlclJlc3VsdCBjciA9IGUuZW5jb2RlKENoYXJCdWZmZXIud3JhcChuZXcgY2hhcltdIHsgJ1x1ZDg0MicgfSksIGJiLCBmYWxzZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb2RlclJlc3VsdC5VTkRFUkZMT1csIGNyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGJiLnBvc2l0aW9uKCkpOworICAgICAgICBjciA9IGUuZW5jb2RlKENoYXJCdWZmZXIud3JhcChuZXcgY2hhcltdIHsgJ1x1ZGY5ZicgfSksIGJiLCBmYWxzZSk7CisgICAgICAgIGlmIChjZWEgPT0gQ29kaW5nRXJyb3JBY3Rpb24uUkVQT1JUKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGNyLnRvU3RyaW5nKCksIGNyLmlzTWFsZm9ybWVkKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNyLmxlbmd0aCgpKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoQ29kZXJSZXN1bHQuVU5ERVJGTE9XLCBjcik7CisgICAgICAgIGludCBleHBlY3RlZFBvc2l0aW9uID0gMDsKKyAgICAgICAgaWYgKGNlYSA9PSBDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFKSB7CisgICAgICAgICAgICBleHBlY3RlZFBvc2l0aW9uID0gNDsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZFBvc2l0aW9uLCBiYi5wb3NpdGlvbigpKTsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihBcnJheXMudG9TdHJpbmcoQXJyYXlzLmNvcHlPZlJhbmdlKGJiLmFycmF5KCksIDAsIGJiLnBvc2l0aW9uKCkpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDB4MDAsIGJiLmdldCgwKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDB4MDAsIGJiLmdldCgxKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDB4ZmYsIGJiLmdldCgyKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDB4ZmQsIGJiLmdldCgzKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkUG9zaXRpb24sIGJiLnBvc2l0aW9uKCkpOworICAgICAgICBjciA9IGUuZW5jb2RlKENoYXJCdWZmZXIud3JhcChuZXcgY2hhcltdIHsgfSksIGJiLCB0cnVlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENvZGVyUmVzdWx0LlVOREVSRkxPVywgY3IpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRQb3NpdGlvbiwgYmIucG9zaXRpb24oKSk7CisgICAgICAgIGNyID0gZS5mbHVzaChiYik7CisgICAgICAgIGFzc2VydEVxdWFscyhDb2RlclJlc3VsdC5VTkRFUkZMT1csIGNyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkUG9zaXRpb24sIGJiLnBvc2l0aW9uKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDaGFyc2V0RW5jb2RlclN1cnJvZ2F0ZXNCcm9rZW5CeURlc2lnbl9JR05PUkUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdENoYXJzZXRFbmNvZGVyU3Vycm9nYXRlc0Jyb2tlbkJ5RGVzaWduKENvZGluZ0Vycm9yQWN0aW9uLklHTk9SRSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENoYXJzZXRFbmNvZGVyU3Vycm9nYXRlc0Jyb2tlbkJ5RGVzaWduX1JFUE9SVCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Q2hhcnNldEVuY29kZXJTdXJyb2dhdGVzQnJva2VuQnlEZXNpZ24oQ29kaW5nRXJyb3JBY3Rpb24uUkVQT1JUKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2hhcnNldEVuY29kZXJTdXJyb2dhdGVzQnJva2VuQnlEZXNpZ25fUkVQTEFDRSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Q2hhcnNldEVuY29kZXJTdXJyb2dhdGVzQnJva2VuQnlEZXNpZ24oQ29kaW5nRXJyb3JBY3Rpb24uUkVQTEFDRSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RDaGFyc2V0RW5jb2RlclN1cnJvZ2F0ZXNCcm9rZW5CeURlc2lnbihDb2RpbmdFcnJvckFjdGlvbiBjZWEpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBXcml0aW5nIHRoZSB0d28gaGFsdmVzIG9mIHRoZSBzdXJyb2dhdGUgcGFpciBpbiBzZXBhcmF0ZSB3cml0ZXMgd29ya3MganVzdCBmaW5lLgorICAgICAgICAvLyBUaGlzIGlzIHRydWUgb2YgQW5kcm9pZCBhbmQgSUNVLCBidXQgbm90IG9mIHRoZSBSSS4KKyAgICAgICAgQ2hhcnNldCBjcyA9IENoYXJzZXQuZm9yTmFtZSgiVVRGLTMyQkUiKTsKKyAgICAgICAgQ2hhcnNldEVuY29kZXIgZSA9IGNzLm5ld0VuY29kZXIoKTsKKyAgICAgICAgZS5vbk1hbGZvcm1lZElucHV0KGNlYSk7CisgICAgICAgIGUub25Vbm1hcHBhYmxlQ2hhcmFjdGVyKGNlYSk7CisgICAgICAgIEJ5dGVCdWZmZXIgYmIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEyOCk7CisgICAgICAgIENvZGVyUmVzdWx0IGNyID0gZS5lbmNvZGUoQ2hhckJ1ZmZlci53cmFwKG5ldyBjaGFyW10geyAnXHVkODQyJyB9KSwgYmIsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENvZGVyUmVzdWx0LlVOREVSRkxPVywgY3IpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYmIucG9zaXRpb24oKSk7CisgICAgICAgIGNyID0gZS5lbmNvZGUoQ2hhckJ1ZmZlci53cmFwKG5ldyBjaGFyW10geyAnXHVkZjlmJyB9KSwgYmIsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENvZGVyUmVzdWx0LlVOREVSRkxPVywgY3IpOworICAgICAgICBpbnQgZXhwZWN0ZWRQb3NpdGlvbiA9IDQ7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZFBvc2l0aW9uLCBiYi5wb3NpdGlvbigpKTsKKyAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKEFycmF5cy50b1N0cmluZyhBcnJheXMuY29weU9mUmFuZ2UoYmIuYXJyYXkoKSwgMCwgYmIucG9zaXRpb24oKSkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweDAwLCBiYi5nZXQoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoKGJ5dGUpIDB4MDIsIGJiLmdldCgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkgMHgwYiwgYmIuZ2V0KDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKChieXRlKSAweDlmLCBiYi5nZXQoMykpOworICAgICAgICBjciA9IGUuZW5jb2RlKENoYXJCdWZmZXIud3JhcChuZXcgY2hhcltdIHsgfSksIGJiLCB0cnVlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENvZGVyUmVzdWx0LlVOREVSRkxPVywgY3IpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRQb3NpdGlvbiwgYmIucG9zaXRpb24oKSk7CisgICAgICAgIGNyID0gZS5mbHVzaChiYik7CisgICAgICAgIGFzc2VydEVxdWFscyhDb2RlclJlc3VsdC5VTkRFUkZMT1csIGNyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkUG9zaXRpb24sIGJiLnBvc2l0aW9uKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGbHVzaFdpdGhvdXRFbmRPZklucHV0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENoYXJzZXQgY3MgPSBDaGFyc2V0LmZvck5hbWUoIlVURi0zMkJFIik7CisgICAgICAgIENoYXJzZXRFbmNvZGVyIGUgPSBjcy5uZXdFbmNvZGVyKCk7CisgICAgICAgIEJ5dGVCdWZmZXIgYmIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEyOCk7CisgICAgICAgIENvZGVyUmVzdWx0IGNyID0gZS5lbmNvZGUoQ2hhckJ1ZmZlci53cmFwKG5ldyBjaGFyW10geyAneCcgfSksIGJiLCBmYWxzZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb2RlclJlc3VsdC5VTkRFUkZMT1csIGNyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGJiLnBvc2l0aW9uKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY3IgPSBlLmZsdXNoKGJiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAvLyB5b3UgbXVzdCBjYWxsIGVuY29kZSB3aXRoIGVuZE9mSW5wdXQgdHJ1ZSBiZWZvcmUgeW91IGNhbiBmbHVzaC4KKyAgICAgICAgfQorCisgICAgICAgIC8vIFdlIGhhZCBhIGJ1ZyB3aGVyZSB3ZSB3b3VsZG4ndCByZXNldCBpbkVuZCBiZWZvcmUgY2FsbGluZyBlbmNvZGUgaW4gaW1wbEZsdXNoLgorICAgICAgICAvLyBUaGF0IHdvdWxkIHJlc3VsdCBpbiBmbHVzaCBvdXRwdXR0aW5nIGdhcmJhZ2UuCisgICAgICAgIGNyID0gZS5lbmNvZGUoQ2hhckJ1ZmZlci53cmFwKG5ldyBjaGFyW10geyAneCcgfSksIGJiLCB0cnVlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENvZGVyUmVzdWx0LlVOREVSRkxPVywgY3IpOworICAgICAgICBhc3NlcnRFcXVhbHMoOCwgYmIucG9zaXRpb24oKSk7CisgICAgICAgIGNyID0gZS5mbHVzaChiYik7CisgICAgICAgIGFzc2VydEVxdWFscyhDb2RlclJlc3VsdC5VTkRFUkZMT1csIGNyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDgsIGJiLnBvc2l0aW9uKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZjliYzU5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjEwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLkNoYXJCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldEVuY29kZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworcHVibGljIGNsYXNzIENoYXJzZXRUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2d1YXJhbnRlZWRDaGFyc2V0c0F2YWlsYWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBBbGwgSmF2YSBpbXBsZW1lbnRhdGlvbnMgbXVzdCBzdXBwb3J0IHRoZXNlIGNoYXJzZXRzLgorICAgICAgICBhc3NlcnROb3ROdWxsKENoYXJzZXQuZm9yTmFtZSgiSVNPLTg4NTktMSIpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChDaGFyc2V0LmZvck5hbWUoIlVTLUFTQ0lJIikpOworICAgICAgICBhc3NlcnROb3ROdWxsKENoYXJzZXQuZm9yTmFtZSgiVVRGLTE2IikpOworICAgICAgICBhc3NlcnROb3ROdWxsKENoYXJzZXQuZm9yTmFtZSgiVVRGLTE2QkUiKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoQ2hhcnNldC5mb3JOYW1lKCJVVEYtMTZMRSIpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChDaGFyc2V0LmZvck5hbWUoIlVURi04IikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWxsQXZhaWxhYmxlQ2hhcnNldHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQ2hlY2sgdGhhdCB3ZSBjYW4gaW5zdGFudGlhdGUgZXZlcnkgQ2hhcnNldCwgQ2hhcnNldERlY29kZXIsIGFuZCBDaGFyc2V0RW5jb2Rlci4KKyAgICAgICAgZm9yIChTdHJpbmcgY2hhcnNldE5hbWUgOiBDaGFyc2V0LmF2YWlsYWJsZUNoYXJzZXRzKCkua2V5U2V0KCkpIHsKKyAgICAgICAgICAgIGlmIChjaGFyc2V0TmFtZS5lcXVhbHMoIlVURi0zMiIpKSB7CisgICAgICAgICAgICAgICAgLy8gT3VyIFVURi0zMiBpcyBicm9rZW4uIGh0dHA6Ly9iLzI3MDI0MTEKKyAgICAgICAgICAgICAgICAvLyBUT0RPOiByZW1vdmUgdGhpcyBoYWNrIHdoZW4gVVRGLTMyIGlzIGZpeGVkLgorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBDaGFyc2V0IGNzID0gQ2hhcnNldC5mb3JOYW1lKGNoYXJzZXROYW1lKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoY3MubmV3RGVjb2RlcigpKTsKKyAgICAgICAgICAgIGlmIChjcy5jYW5FbmNvZGUoKSkgeworICAgICAgICAgICAgICAgIENoYXJzZXRFbmNvZGVyIGVuYyA9IGNzLm5ld0VuY29kZXIoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGVuYyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChlbmMucmVwbGFjZW1lbnQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0VVQ19KUCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFbmNvZGVzKENoYXJzZXQuZm9yTmFtZSgiRVVDLUpQIiksICJcdWZmZmQiLCAweGY0LCAweGZlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NDU1UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RW5jb2RlcyhDaGFyc2V0LmZvck5hbWUoIlNDU1UiKSwgIlx1ZmZmZCIsIDE0LCAweGZmLCAweGZkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NoaWZ0X0pJUygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFbmNvZGVzKENoYXJzZXQuZm9yTmFtZSgiU2hpZnRfSklTIiksICJcdWZmZmQiLCAweGZjLCAweGZjKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1VURl8xNigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaGFyc2V0IGNzID0gQ2hhcnNldC5mb3JOYW1lKCJVVEYtMTYiKTsKKyAgICAgICAgLy8gV3JpdGVzIGJpZy1lbmRpYW4sIHdpdGggYSBiaWctZW5kaWFuIEJPTS4KKyAgICAgICAgYXNzZXJ0RW5jb2RlcyhjcywgImFcdTA2NjYiLCAweGZlLCAweGZmLCAwLCAnYScsIDB4MDYsIDB4NjYpOworICAgICAgICAvLyBSZWFkcyB3aGF0ZXZlciB0aGUgQk9NIHRlbGxzIGl0IHRvIHJlYWQuLi4KKyAgICAgICAgYXNzZXJ0RGVjb2RlcyhjcywgImFcdTA2NjYiLCAweGZlLCAweGZmLCAwLCAnYScsIDB4MDYsIDB4NjYpOworICAgICAgICBhc3NlcnREZWNvZGVzKGNzLCAiYVx1MDY2NiIsIDB4ZmYsIDB4ZmUsICdhJywgMCwgMHg2NiwgMHgwNik7CisgICAgICAgIC8vIC4uLmFuZCBkZWZhdWx0cyB0byByZWFkaW5nIGJpZy1lbmRpYW4gaWYgdGhlcmUncyBubyBCT00uCisgICAgICAgIGFzc2VydERlY29kZXMoY3MsICJhXHUwNjY2IiwgMCwgJ2EnLCAweDA2LCAweDY2KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1VURl8xNkJFKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENoYXJzZXQgY3MgPSBDaGFyc2V0LmZvck5hbWUoIlVURi0xNkJFIik7CisgICAgICAgIC8vIFdyaXRlcyBiaWctZW5kaWFuLCB3aXRoIG5vIEJPTS4KKyAgICAgICAgYXNzZXJ0RW5jb2RlcyhjcywgImFcdTA2NjYiLCAwLCAnYScsIDB4MDYsIDB4NjYpOworICAgICAgICAvLyBUcmVhdHMgYSBsaXR0bGUtZW5kaWFuIEJPTSBhcyBhbiBlcnJvciBhbmQgY29udGludWVzIHRvIHJlYWQgYmlnLWVuZGlhbi4KKyAgICAgICAgLy8gVGhpcyB0ZXN0IHVzZXMgUkVQTEFDRSBtb2RlLCBzbyB3ZSBnZXQgdGhlIFUrRkZGRCByZXBsYWNlbWVudCBjaGFyYWN0ZXIgaW4gdGhlIHJlc3VsdC4KKyAgICAgICAgYXNzZXJ0RGVjb2RlcyhjcywgIlx1ZmZmZGFcdTA2NjYiLCAweGZmLCAweGZlLCAwLCAnYScsIDB4MDYsIDB4NjYpOworICAgICAgICAvLyBBY2NlcHRzIGEgYmlnLWVuZGlhbiBCT00gYW5kIGluY2x1ZGVzIFUrRkVGRiBpbiB0aGUgZGVjb2RlZCBvdXRwdXQuCisgICAgICAgIGFzc2VydERlY29kZXMoY3MsICJcdWZlZmZhXHUwNjY2IiwgMHhmZSwgMHhmZiwgMCwgJ2EnLCAweDA2LCAweDY2KTsKKyAgICAgICAgLy8gRGVmYXVsdHMgdG8gcmVhZGluZyBiaWctZW5kaWFuLgorICAgICAgICBhc3NlcnREZWNvZGVzKGNzLCAiYVx1MDY2NiIsIDAsICdhJywgMHgwNiwgMHg2Nik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9VVEZfMTZMRSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaGFyc2V0IGNzID0gQ2hhcnNldC5mb3JOYW1lKCJVVEYtMTZMRSIpOworICAgICAgICAvLyBXcml0ZXMgbGl0dGxlLWVuZGlhbiwgd2l0aCBubyBCT00uCisgICAgICAgIGFzc2VydEVuY29kZXMoY3MsICJhXHUwNjY2IiwgJ2EnLCAwLCAweDY2LCAweDA2KTsKKyAgICAgICAgLy8gQWNjZXB0cyBhIGxpdHRsZS1lbmRpYW4gQk9NIGFuZCBpbmNsdWRlcyBVK0ZFRkYgaW4gdGhlIGRlY29kZWQgb3V0cHV0LgorICAgICAgICBhc3NlcnREZWNvZGVzKGNzLCAiXHVmZWZmYVx1MDY2NiIsIDB4ZmYsIDB4ZmUsICdhJywgMCwgMHg2NiwgMHgwNik7CisgICAgICAgIC8vIFRyZWF0cyBhIGJpZy1lbmRpYW4gQk9NIGFzIGFuIGVycm9yIGFuZCBjb250aW51ZXMgdG8gcmVhZCBsaXR0bGUtZW5kaWFuLgorICAgICAgICAvLyBUaGlzIHRlc3QgdXNlcyBSRVBMQUNFIG1vZGUsIHNvIHdlIGdldCB0aGUgVStGRkZEIHJlcGxhY2VtZW50IGNoYXJhY3RlciBpbiB0aGUgcmVzdWx0LgorICAgICAgICBhc3NlcnREZWNvZGVzKGNzLCAiXHVmZmZkYVx1MDY2NiIsIDB4ZmUsIDB4ZmYsICdhJywgMCwgMHg2NiwgMHgwNik7CisgICAgICAgIC8vIERlZmF1bHRzIHRvIHJlYWRpbmcgbGl0dGxlLWVuZGlhbi4KKyAgICAgICAgYXNzZXJ0RGVjb2RlcyhjcywgImFcdTA2NjYiLCAnYScsIDAsIDB4NjYsIDB4MDYpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfeF9VVEZfMTZMRV9CT00oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2hhcnNldCBjcyA9IENoYXJzZXQuZm9yTmFtZSgieC1VVEYtMTZMRS1CT00iKTsKKyAgICAgICAgLy8gV3JpdGVzIGxpdHRsZS1lbmRpYW4sIHdpdGggYSBCT00uCisgICAgICAgIGFzc2VydEVuY29kZXMoY3MsICJhXHUwNjY2IiwgMHhmZiwgMHhmZSwgJ2EnLCAwLCAweDY2LCAweDA2KTsKKyAgICAgICAgLy8gQWNjZXB0cyBhIGxpdHRsZS1lbmRpYW4gQk9NIGFuZCBzd2FsbG93cyB0aGUgQk9NLgorICAgICAgICBhc3NlcnREZWNvZGVzKGNzLCAiYVx1MDY2NiIsIDB4ZmYsIDB4ZmUsICdhJywgMCwgMHg2NiwgMHgwNik7CisgICAgICAgIC8vIFN3YWxsb3dzIGEgYmlnLWVuZGlhbiBCT00sIGJ1dCBjb250aW51ZXMgdG8gcmVhZCBsaXR0bGUtZW5kaWFuIQorICAgICAgICBhc3NlcnREZWNvZGVzKGNzLCAiXHU2MTAwXHU2NjA2IiwgMHhmZSwgMHhmZiwgJ2EnLCAwLCAweDY2LCAweDA2KTsKKyAgICAgICAgLy8gRGVmYXVsdHMgdG8gcmVhZGluZyBsaXR0bGUtZW5kaWFuLgorICAgICAgICBhc3NlcnREZWNvZGVzKGNzLCAiYVx1MDY2NiIsICdhJywgMCwgMHg2NiwgMHgwNik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9VVEZfMzIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2hhcnNldCBjcyA9IENoYXJzZXQuZm9yTmFtZSgiVVRGLTMyIik7CisgICAgICAgIC8vIFdyaXRlcyBiaWctZW5kaWFuLCB3aXRoIG5vIEJPTS4KKyAgICAgICAgYXNzZXJ0RW5jb2RlcyhjcywgImFcdTA2NjYiLCAwLCAwLCAwLCAnYScsIDAsIDAsIDB4MDYsIDB4NjYpOworICAgICAgICAvLyBSZWFkcyB3aGF0ZXZlciB0aGUgQk9NIHRlbGxzIGl0IHRvIHJlYWQuLi4KKyAgICAgICAgYXNzZXJ0RGVjb2RlcyhjcywgImFcdTA2NjYiLCAwLCAwLCAweGZlLCAweGZmLCAwLCAwLCAwLCAnYScsIDAsIDAsIDB4MDYsIDB4NjYpOworICAgICAgICBhc3NlcnREZWNvZGVzKGNzLCAiYVx1MDY2NiIsIDB4ZmYsIDB4ZmUsIDAsIDAsICdhJywgMCwgMCwgMCwgMHg2NiwgMHgwNiwgMCwgMCk7CisgICAgICAgIC8vIC4uLmFuZCBkZWZhdWx0cyB0byByZWFkaW5nIGJpZy1lbmRpYW4gaWYgdGhlcmUncyBubyBCT00uCisgICAgICAgIGFzc2VydERlY29kZXMoY3MsICJhXHUwNjY2IiwgMCwgMCwgMCwgJ2EnLCAwLCAwLCAweDA2LCAweDY2KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1VURl8zMkJFKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENoYXJzZXQgY3MgPSBDaGFyc2V0LmZvck5hbWUoIlVURi0zMkJFIik7CisgICAgICAgIC8vIFdyaXRlcyBiaWctZW5kaWFuLCB3aXRoIG5vIEJPTS4KKyAgICAgICAgYXNzZXJ0RW5jb2RlcyhjcywgImFcdTA2NjYiLCAwLCAwLCAwLCAnYScsIDAsIDAsIDB4MDYsIDB4NjYpOworICAgICAgICAvLyBUcmVhdHMgYSBsaXR0bGUtZW5kaWFuIEJPTSBhcyBhbiBlcnJvciBhbmQgY29udGludWVzIHRvIHJlYWQgYmlnLWVuZGlhbi4KKyAgICAgICAgLy8gVGhpcyB0ZXN0IHVzZXMgUkVQTEFDRSBtb2RlLCBzbyB3ZSBnZXQgdGhlIFUrRkZGRCByZXBsYWNlbWVudCBjaGFyYWN0ZXIgaW4gdGhlIHJlc3VsdC4KKyAgICAgICAgYXNzZXJ0RGVjb2RlcyhjcywgIlx1ZmZmZGFcdTA2NjYiLCAweGZmLCAweGZlLCAwLCAwLCAwLCAwLCAwLCAnYScsIDAsIDAsIDB4MDYsIDB4NjYpOworICAgICAgICAvLyBBY2NlcHRzIGEgYmlnLWVuZGlhbiBCT00gYW5kIHN3YWxsb3dzIHRoZSBCT00uCisgICAgICAgIGFzc2VydERlY29kZXMoY3MsICJhXHUwNjY2IiwgMCwgMCwgMHhmZSwgMHhmZiwgMCwgMCwgMCwgJ2EnLCAwLCAwLCAweDA2LCAweDY2KTsKKyAgICAgICAgLy8gRGVmYXVsdHMgdG8gcmVhZGluZyBiaWctZW5kaWFuLgorICAgICAgICBhc3NlcnREZWNvZGVzKGNzLCAiYVx1MDY2NiIsIDAsIDAsIDAsICdhJywgMCwgMCwgMHgwNiwgMHg2Nik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9VVEZfMzJMRSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaGFyc2V0IGNzID0gQ2hhcnNldC5mb3JOYW1lKCJVVEYtMzJMRSIpOworICAgICAgICAvLyBXcml0ZXMgbGl0dGxlLWVuZGlhbiwgd2l0aCBubyBCT00uCisgICAgICAgIGFzc2VydEVuY29kZXMoY3MsICJhXHUwNjY2IiwgJ2EnLCAwLCAwLCAwLCAweDY2LCAweDA2LCAwLCAwKTsKKyAgICAgICAgLy8gQWNjZXB0cyBhIGxpdHRsZS1lbmRpYW4gQk9NIGFuZCBzd2FsbG93cyB0aGUgQk9NLgorICAgICAgICBhc3NlcnREZWNvZGVzKGNzLCAiYVx1MDY2NiIsIDB4ZmYsIDB4ZmUsIDAsIDAsICdhJywgMCwgMCwgMCwgMHg2NiwgMHgwNiwgMCwgMCk7CisgICAgICAgIC8vIFRyZWF0cyBhIGJpZy1lbmRpYW4gQk9NIGFzIGFuIGVycm9yIGFuZCBjb250aW51ZXMgdG8gcmVhZCBsaXR0bGUtZW5kaWFuLgorICAgICAgICAvLyBUaGlzIHRlc3QgdXNlcyBSRVBMQUNFIG1vZGUsIHNvIHdlIGdldCB0aGUgVStGRkZEIHJlcGxhY2VtZW50IGNoYXJhY3RlciBpbiB0aGUgcmVzdWx0LgorICAgICAgICBhc3NlcnREZWNvZGVzKGNzLCAiXHVmZmZkYVx1MDY2NiIsIDAsIDAsIDB4ZmUsIDB4ZmYsICdhJywgMCwgMCwgMCwgMHg2NiwgMHgwNiwgMCwgMCk7CisgICAgICAgIC8vIERlZmF1bHRzIHRvIHJlYWRpbmcgbGl0dGxlLWVuZGlhbi4KKyAgICAgICAgYXNzZXJ0RGVjb2RlcyhjcywgImFcdTA2NjYiLCAnYScsIDAsIDAsIDAsIDB4NjYsIDB4MDYsIDAsIDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfWF9VVEZfMzJCRV9CT00oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2hhcnNldCBjcyA9IENoYXJzZXQuZm9yTmFtZSgiWC1VVEYtMzJCRS1CT00iKTsKKyAgICAgICAgLy8gV3JpdGVzIGJpZy1lbmRpYW4sIHdpdGggYSBiaWctZW5kaWFuIEJPTS4KKyAgICAgICAgYXNzZXJ0RW5jb2RlcyhjcywgImFcdTA2NjYiLCAwLCAwLCAweGZlLCAweGZmLCAwLCAwLCAwLCAnYScsIDAsIDAsIDB4MDYsIDB4NjYpOworICAgICAgICAvLyBUcmVhdHMgYSBsaXR0bGUtZW5kaWFuIEJPTSBhcyBhbiBlcnJvciBhbmQgY29udGludWVzIHRvIHJlYWQgYmlnLWVuZGlhbi4KKyAgICAgICAgLy8gVGhpcyB0ZXN0IHVzZXMgUkVQTEFDRSBtb2RlLCBzbyB3ZSBnZXQgdGhlIFUrRkZGRCByZXBsYWNlbWVudCBjaGFyYWN0ZXIgaW4gdGhlIHJlc3VsdC4KKyAgICAgICAgYXNzZXJ0RGVjb2RlcyhjcywgIlx1ZmZmZGFcdTA2NjYiLCAweGZmLCAweGZlLCAwLCAwLCAwLCAwLCAwLCAnYScsIDAsIDAsIDB4MDYsIDB4NjYpOworICAgICAgICAvLyBTd2FsbG93cyBhIGJpZy1lbmRpYW4gQk9NLCBhbmQgY29udGludWVzIHRvIHJlYWQgYmlnLWVuZGlhbi4KKyAgICAgICAgYXNzZXJ0RGVjb2RlcyhjcywgImFcdTA2NjYiLCAwLCAwLCAweGZlLCAweGZmLCAwLCAwLCAwLCAnYScsIDAsIDAsIDB4MDYsIDB4NjYpOworICAgICAgICAvLyBEZWZhdWx0cyB0byByZWFkaW5nIGJpZy1lbmRpYW4uCisgICAgICAgIGFzc2VydERlY29kZXMoY3MsICJhXHUwNjY2IiwgMCwgMCwgMCwgJ2EnLCAwLCAwLCAweDA2LCAweDY2KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1hfVVRGXzMyTEVfQk9NKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENoYXJzZXQgY3MgPSBDaGFyc2V0LmZvck5hbWUoIlgtVVRGLTMyTEUtQk9NIik7CisgICAgICAgIC8vIFdyaXRlcyBsaXR0bGUtZW5kaWFuLCB3aXRoIGEgbGl0dGxlLWVuZGlhbiBCT00uCisgICAgICAgIGFzc2VydEVuY29kZXMoY3MsICJhXHUwNjY2IiwgMHhmZiwgMHhmZSwgMCwgMCwgJ2EnLCAwLCAwLCAwLCAweDY2LCAweDA2LCAwLCAwKTsKKyAgICAgICAgLy8gQWNjZXB0cyBhIGxpdHRsZS1lbmRpYW4gQk9NIGFuZCBzd2FsbG93cyB0aGUgQk9NLgorICAgICAgICBhc3NlcnREZWNvZGVzKGNzLCAiYVx1MDY2NiIsIDB4ZmYsIDB4ZmUsIDAsIDAsICdhJywgMCwgMCwgMCwgMHg2NiwgMHgwNiwgMCwgMCk7CisgICAgICAgIC8vIFRyZWF0cyBhIGJpZy1lbmRpYW4gQk9NIGFzIGFuIGVycm9yIGFuZCBjb250aW51ZXMgdG8gcmVhZCBsaXR0bGUtZW5kaWFuLgorICAgICAgICAvLyBUaGlzIHRlc3QgdXNlcyBSRVBMQUNFIG1vZGUsIHNvIHdlIGdldCB0aGUgVStGRkZEIHJlcGxhY2VtZW50IGNoYXJhY3RlciBpbiB0aGUgcmVzdWx0LgorICAgICAgICBhc3NlcnREZWNvZGVzKGNzLCAiXHVmZmZkYVx1MDY2NiIsIDAsIDAsIDB4ZmUsIDB4ZmYsICdhJywgMCwgMCwgMCwgMHg2NiwgMHgwNiwgMCwgMCk7CisgICAgICAgIC8vIERlZmF1bHRzIHRvIHJlYWRpbmcgbGl0dGxlLWVuZGlhbi4KKyAgICAgICAgYXNzZXJ0RGVjb2RlcyhjcywgImFcdTA2NjYiLCAnYScsIDAsIDAsIDAsIDB4NjYsIDB4MDYsIDAsIDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcHJlTmlvQWxpYXNlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBWYXJpb3VzIHByZS1uaW8gamF2YS5sYW5nL2phdmEuaW8gZW5jb2RpbmcgbmFtZXMgYXJlIHRyYW5zbGF0ZWQgdG8gbmlvIGNoYXJzZXRzLgorICAgICAgICBhc3NlcnRFcXVhbHMoIlVURi0xNkJFIiwgQ2hhcnNldC5mb3JOYW1lKCJVbmljb2RlQmlnVW5tYXJrZWQiKS5uYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlVURi0xNkxFIiwgQ2hhcnNldC5mb3JOYW1lKCJVbmljb2RlTGl0dGxlVW5tYXJrZWQiKS5uYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlVURi0xNiIsIENoYXJzZXQuZm9yTmFtZSgiVW5pY29kZSIpLm5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVVRGLTE2IiwgQ2hhcnNldC5mb3JOYW1lKCJVbmljb2RlQmlnIikubmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4LVVURi0xNkxFLUJPTSIsIENoYXJzZXQuZm9yTmFtZSgiVW5pY29kZUxpdHRsZSIpLm5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWC1VVEYtMzJCRS1CT00iLCBDaGFyc2V0LmZvck5hbWUoIlVURl8zMkJFX0JPTSIpLm5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWC1VVEYtMzJMRS1CT00iLCBDaGFyc2V0LmZvck5hbWUoIlVURl8zMkxFX0JPTSIpLm5hbWUoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBieXRlW10gdG9CeXRlQXJyYXkoaW50W10gaW50cykgeworICAgICAgICBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbaW50cy5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludHMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIHJlc3VsdFtpXSA9IChieXRlKSBpbnRzW2ldOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydEVuY29kZXMoQ2hhcnNldCBjcywgU3RyaW5nIHMsIGludC4uLiBleHBlY3RlZEJ5dGVJbnRzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUJ1ZmZlciBvdXQgPSBjcy5lbmNvZGUocyk7CisgICAgICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlW291dC5yZW1haW5pbmcoKV07CisgICAgICAgIG91dC5nZXQoYnl0ZXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLnRvU3RyaW5nKHRvQnl0ZUFycmF5KGV4cGVjdGVkQnl0ZUludHMpKSwgQXJyYXlzLnRvU3RyaW5nKGJ5dGVzKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydERlY29kZXMoQ2hhcnNldCBjcywgU3RyaW5nIHMsIGludC4uLiBieXRlSW50cykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVCdWZmZXIgaW4gPSBCeXRlQnVmZmVyLndyYXAodG9CeXRlQXJyYXkoYnl0ZUludHMpKTsKKyAgICAgICAgQ2hhckJ1ZmZlciBvdXQgPSBjcy5kZWNvZGUoaW4pOworICAgICAgICBhc3NlcnRFcXVhbHMocywgb3V0LnRvU3RyaW5nKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvQ2hhcnNldF9UZXN0R2VuZXJhdG9yLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L0NoYXJzZXRfVGVzdEdlbmVyYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxODkzODIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L0NoYXJzZXRfVGVzdEdlbmVyYXRvci5qYXZhCkBAIC0wLDAgKzEsMjYxIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLkNoYXJCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldERlY29kZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0RW5jb2RlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNvZGluZ0Vycm9yQWN0aW9uOworCisvKioKKyAqIFN1cGVyIGNsYXNzIGZvciBjb25jcmV0ZSBjaGFyc2V0IHRlc3Qgc3VpdGVzLgorICovCitwdWJsaWMgY2xhc3MgQ2hhcnNldF9UZXN0R2VuZXJhdG9yIHsKKworICAgIENoYXJzZXQgY2hhcnNldDsKKyAgICBDaGFyc2V0RGVjb2RlciBkZWNvZGVyOworICAgIENoYXJzZXRFbmNvZGVyIGVuY29kZXI7CisKKworICAgIHN0YXRpYyBmaW5hbCBpbnRbXSBjb2RlcyA9IHsKKyAgICAgICAgOSwgMTIsIDI4LCAzMSwgNDgsIDUxLCA1NCwgNTcsIDY1LCA2OCwgNzEsIDc0LCA3NywgODAsIDgzLCA4NiwKKyAgICAgICAgODksIDk3LCAxMDAsIDEwMywgMTA2LCAxMDksIDExMiwgMTE1LCAxMTgsIDEyMSwgMTcwLCAxODEsIDE4NiwgMTkyLCAxOTUsIDE5OCwKKyAgICAgICAgMjAxLCAyMDQsIDIwNywgMjEwLCAyMTMsIDIxNiwgMjE5LCAyMjIsIDIyNSwgMjI4LCAyMzEsIDIzNCwgMjM3LCAyNDAsIDI0MywgMjQ2LAorICAgICAgICAyNDksIDI1MiwgMjU1LCAyNTgsIDI2MSwgMjY0LCAyNjcsIDI3MCwgMjczLCAyNzYsIDI3OSwgMjgyLCAyODUsIDI4OCwgMjkxLCAyOTQsCisgICAgICAgIDI5NywgMzAwLCAzMDMsIDMwNiwgMzA5LCAzMTIsIDMxNSwgMzE4LCAzMjEsIDMyNCwgMzI3LCAzMzAsIDMzMywgMzM2LCAzMzksIDM0MiwKKyAgICAgICAgMzQ1LCAzNDgsIDM1MSwgMzU0LCAzNTcsIDM2MCwgMzYzLCAzNjYsIDM2OSwgMzcyLCAzNzUsIDM3OCwgMzgxLCAzODQsIDM4NywgMzkwLAorICAgICAgICAzOTMsIDM5NiwgMzk5LCA0MDIsIDQwNSwgNDA4LCA0MTEsIDQxNCwgNDE3LCA0MjAsIDQyMywgNDI2LCA0MjksIDQzMiwgNDM1LCA0MzgsCisgICAgICAgIDQ0MSwgNDQ0LCA0NDcsIDQ1MCwgNDUzLCA0NTYsIDQ1OSwgNDYyLCA0NjUsIDQ2OCwgNDcxLCA0NzQsIDQ3NywgNDgwLCA0ODMsIDQ4NiwKKyAgICAgICAgNDg5LCA0OTIsIDQ5NSwgNDk4LCA1MDEsIDUwNCwgNTA3LCA1MTAsIDUxMywgNTE2LCA1MTksIDUyMiwgNTI1LCA1MjgsIDUzMSwgNTM0LAorICAgICAgICA1MzcsIDU0MCwgNTQzLCA1NDYsIDU0OSwgNTUyLCA1NTUsIDU1OCwgNTYxLCA1NjQsIDU5MiwgNTk1LCA1OTgsIDYwMSwgNjA0LCA2MDcsCisgICAgICAgIDYxMCwgNjEzLCA2MTYsIDYxOSwgNjIyLCA2MjUsIDYyOCwgNjMxLCA2MzQsIDYzNywgNjQwLCA2NDMsIDY0NiwgNjQ5LCA2NTIsIDY1NSwKKyAgICAgICAgNjU4LCA2NjEsIDY2NCwgNjY3LCA2NzAsIDY3MywgNjc2LCA2NzksIDY4MiwgNjg1LCA2ODgsIDY5MSwgNjk0LCA2OTcsIDcwMCwgNzAzLAorICAgICAgICA3MTAsIDcxMywgNzE2LCA3MTksIDczNiwgNzM5LCA3NTAsIDg5MCwgOTAyLCA5MDUsIDkwOCwgOTExLCA5MTQsIDkxNywgOTIwLCA5MjMsCisgICAgICAgIDkyNiwgOTI5LCA5MzIsIDkzNSwgOTM4LCA5NDEsIDk0NCwgOTQ3LCA5NTAsIDk1MywgOTU2LCA5NTksIDk2MiwgOTY1LCA5NjgsIDk3MSwKKyAgICAgICAgOTc0LCA5NzcsIDk4MCwgOTgzLCA5ODYsIDk4OSwgOTkyLCA5OTUsIDk5OCwgMTAwMSwgMTAwNCwgMTAwNywgMTAxMCwgMTAxMywgMTAxNiwgMTAxOSwKKyAgICAgICAgMTAyNCwgMTAyNywgMTA2MCwgMTA5MywgMTEyNiwgMTE2MiwgMTE5NSwgMTIyOCwgMTI2MSwgMTI5NCwgMTMyOSwgMTM2MiwgMTM5NSwgMTQ4OCwgMTUyMSwgMTU2OSwKKyAgICAgICAgMTYwMiwgMTYzNSwgMTY2OCwgMTcwMSwgMTczNCwgMTc3NCwgMTgwOCwgMTg2OSwgMTkyMCwgMTk1MywgMjMwOCwgMjM0MSwgMjM4NCwgMjQzNywgMjQ3MCwgMjUyNCwKKyAgICAgICAgMjU2NSwgMjU5OCwgMjY0OSwgMjY5MywgMjcyNiwgMjc2OCwgMjgyMSwgMjg1NCwgMjkwOCwgMjk0NywgMjk4MCwgMzA0NywgMzA4MCwgMzExNCwgMzE2OCwgMzIwNSwKKyAgICAgICAgMzIzOCwgMzI5NCwgMzMzMywgMzM2NiwgMzQyNCwgMzQ2MSwgMzQ5NCwgMzU4NSwgMzYxOCwgMzY1MSwgMzcxMywgMzc0NiwgMzc3OSwgMzg0MCwgMzg3MywgMzkwNiwKKyAgICAgICAgMzkzOSwgMzk3NiwgNDA5NiwgNDEyOSwgNDE2MiwgNDI1NiwgNDI4OSwgNDMyMiwgNDM1NSwgNDM4OCwgNDQyMSwgNDQ1NCwgNDQ4NywgNDUyMCwgNDU1MywgNDU4NiwKKyAgICAgICAgNDYxOSwgNDY1MiwgNDY4NSwgNDcxOCwgNDc1MiwgNDc4NiwgNDgxOSwgNDg1MiwgNDg4NSwgNDkxOCwgNDk1MSwgNTAyNCwgNTA1NywgNTA5MCwgNTEyMywgNTE1NiwKKyAgICAgICAgNTE4OSwgNTIyMiwgNTI1NSwgNTI4OCwgNTMyMSwgNTM1NCwgNTM4NywgNTQyMCwgNTQ1MywgNTQ4NiwgNTUxOSwgNTU1MiwgNTU4NSwgNTYxOCwgNTY1MSwgNTY4NCwKKyAgICAgICAgNTcxNywgNTc1MCwgNTc4MywgNTgxNiwgNTg0OSwgNTg4OCwgNTkyMSwgNTk1NCwgNTk4NywgNjAyMCwgNjA1MywgNjEwMywgNjE1OCwgNjE5MSwgNjIyNCwgNjI1NywKKyAgICAgICAgNjI5MCwgNjQwMCwgNjQ3MCwgNjUwMywgNzQyNCwgNzQ1NywgNzQ5MCwgNzUyMywgNzY4MCwgNzcxMywgNzc0NiwgNzc3OSwgNzgxMiwgNzg0NSwgNzg3OCwgNzkxMSwKKyAgICAgICAgNzk0NCwgNzk3NywgODAxMCwgODA0MywgODA3NiwgODEwOSwgODE0NCwgODE3OCwgODIzMiwgODI4NywgODQ1MCwgODQ4NCwgODUxNywgMTIyODgsIDEyMzM3LCAxMjM3MCwKKyAgICAgICAgMTI0MDMsIDEyNDM2LCAxMjQ2OSwgMTI1MDIsIDEyNTM1LCAxMjU2OCwgMTI2MDEsIDEyNjM0LCAxMjY2NywgMTI3MDQsIDEyNzg0LCAxMzMxMiwgMTMzNDUsIDEzMzc4LCAxMzQxMSwgMTM0NDQsCisgICAgICAgIDEzNDc3LCAxMzUxMCwgMTM1NDMsIDEzNTc2LCAxMzYwOSwgMTM2NDIsIDEzNjc1LCAxMzcwOCwgMTM3NDEsIDEzNzc0LCAxMzgwNywgMTM4NDAsIDEzODczLCAxMzkwNiwgMTM5MzksIDEzOTcyLAorICAgICAgICAxNDAwNSwgMTQwMzgsIDE0MDcxLCAxNDEwNCwgMTQxMzcsIDE0MTcwLCAxNDIwMywgMTQyMzYsIDE0MjY5LCAxNDMwMiwgMTQzMzUsIDE0MzY4LCAxNDQwMSwgMTQ0MzQsIDE0NDY3LCAxNDUwMCwKKyAgICAgICAgMTQ1MzMsIDE0NTY2LCAxNDU5OSwgMTQ2MzIsIDE0NjY1LCAxNDY5OCwgMTQ3MzEsIDE0NzY0LCAxNDc5NywgMTQ4MzAsIDE0ODYzLCAxNDg5NiwgMTQ5MjksIDE0OTYyLCAxNDk5NSwgMTUwMjgsCisgICAgICAgIDE1MDYxLCAxNTA5NCwgMTUxMjcsIDE1MTYwLCAxNTE5MywgMTUyMjYsIDE1MjU5LCAxNTI5MiwgMTUzMjUsIDE1MzU4LCAxNTM5MSwgMTU0MjQsIDE1NDU3LCAxNTQ5MCwgMTU1MjMsIDE1NTU2LAorICAgICAgICAxNTU4OSwgMTU2MjIsIDE1NjU1LCAxNTY4OCwgMTU3MjEsIDE1NzU0LCAxNTc4NywgMTU4MjAsIDE1ODUzLCAxNTg4NiwgMTU5MTksIDE1OTUyLCAxNTk4NSwgMTYwMTgsIDE2MDUxLCAxNjA4NCwKKyAgICAgICAgMTYxMTcsIDE2MTUwLCAxNjE4MywgMTYyMTYsIDE2MjQ5LCAxNjI4MiwgMTYzMTUsIDE2MzQ4LCAxNjM4MSwgMTY0MTQsIDE2NDQ3LCAxNjQ4MCwgMTY1MTMsIDE2NTQ2LCAxNjU3OSwgMTY2MTIsCisgICAgICAgIDE2NjQ1LCAxNjY3OCwgMTY3MTEsIDE2NzQ0LCAxNjc3NywgMTY4MTAsIDE2ODQzLCAxNjg3NiwgMTY5MDksIDE2OTQyLCAxNjk3NSwgMTcwMDgsIDE3MDQxLCAxNzA3NCwgMTcxMDcsIDE3MTQwLAorICAgICAgICAxNzE3MywgMTcyMDYsIDE3MjM5LCAxNzI3MiwgMTczMDUsIDE3MzM4LCAxNzM3MSwgMTc0MDQsIDE3NDM3LCAxNzQ3MCwgMTc1MDMsIDE3NTM2LCAxNzU2OSwgMTc2MDIsIDE3NjM1LCAxNzY2OCwKKyAgICAgICAgMTc3MDEsIDE3NzM0LCAxNzc2NywgMTc4MDAsIDE3ODMzLCAxNzg2NiwgMTc4OTksIDE3OTMyLCAxNzk2NSwgMTc5OTgsIDE4MDMxLCAxODA2NCwgMTgwOTcsIDE4MTMwLCAxODE2MywgMTgxOTYsCisgICAgICAgIDE4MjI5LCAxODI2MiwgMTgyOTUsIDE4MzI4LCAxODM2MSwgMTgzOTQsIDE4NDI3LCAxODQ2MCwgMTg0OTMsIDE4NTI2LCAxODU1OSwgMTg1OTIsIDE4NjI1LCAxODY1OCwgMTg2OTEsIDE4NzI0LAorICAgICAgICAxODc1NywgMTg3OTAsIDE4ODIzLCAxODg1NiwgMTg4ODksIDE4OTIyLCAxODk1NSwgMTg5ODgsIDE5MDIxLCAxOTA1NCwgMTkwODcsIDE5MTIwLCAxOTE1MywgMTkxODYsIDE5MjE5LCAxOTI1MiwKKyAgICAgICAgMTkyODUsIDE5MzE4LCAxOTM1MSwgMTkzODQsIDE5NDE3LCAxOTQ1MCwgMTk0ODMsIDE5NTE2LCAxOTU0OSwgMTk1ODIsIDE5NjE1LCAxOTY0OCwgMTk2ODEsIDE5NzE0LCAxOTc0NywgMTk3ODAsCisgICAgICAgIDE5ODEzLCAxOTg0NiwgMTk4NzksIDE5OTY4LCAyMDAwMSwgMjAwMzQsIDIwMDY3LCAyMDEwMCwgMjAxMzMsIDIwMTY2LCAyMDE5OSwgMjAyMzIsIDIwMjY1LCAyMDI5OCwgMjAzMzEsIDIwMzY0LAorICAgICAgICAyMDM5NywgMjA0MzAsIDIwNDYzLCAyMDQ5NiwgMjA1MjksIDIwNTYyLCAyMDU5NSwgMjA2MjgsIDIwNjYxLCAyMDY5NCwgMjA3MjcsIDIwNzYwLCAyMDc5MywgMjA4MjYsIDIwODU5LCAyMDg5MiwKKyAgICAgICAgMjA5MjUsIDIwOTU4LCAyMDk5MSwgMjEwMjQsIDIxMDU3LCAyMTA5MCwgMjExMjMsIDIxMTU2LCAyMTE4OSwgMjEyMjIsIDIxMjU1LCAyMTI4OCwgMjEzMjEsIDIxMzU0LCAyMTM4NywgMjE0MjAsCisgICAgICAgIDIxNDUzLCAyMTQ4NiwgMjE1MTksIDIxNTUyLCAyMTU4NSwgMjE2MTgsIDIxNjUxLCAyMTY4NCwgMjE3MTcsIDIxNzUwLCAyMTc4MywgMjE4MTYsIDIxODQ5LCAyMTg4MiwgMjE5MTUsIDIxOTQ4LAorICAgICAgICAyMTk4MSwgMjIwMTQsIDIyMDQ3LCAyMjA4MCwgMjIxMTMsIDIyMTQ2LCAyMjE3OSwgMjIyMTIsIDIyMjQ1LCAyMjI3OCwgMjIzMTEsIDIyMzQ0LCAyMjM3NywgMjI0MTAsIDIyNDQzLCAyMjQ3NiwKKyAgICAgICAgMjI1MDksIDIyNTQyLCAyMjU3NSwgMjI2MDgsIDIyNjQxLCAyMjY3NCwgMjI3MDcsIDIyNzQwLCAyMjc3MywgMjI4MDYsIDIyODM5LCAyMjg3MiwgMjI5MDUsIDIyOTM4LCAyMjk3MSwgMjMwMDQsCisgICAgICAgIDIzMDM3LCAyMzA3MCwgMjMxMDMsIDIzMTM2LCAyMzE2OSwgMjMyMDIsIDIzMjM1LCAyMzI2OCwgMjMzMDEsIDIzMzM0LCAyMzM2NywgMjM0MDAsIDIzNDMzLCAyMzQ2NiwgMjM0OTksIDIzNTMyLAorICAgICAgICAyMzU2NSwgMjM1OTgsIDIzNjMxLCAyMzY2NCwgMjM2OTcsIDIzNzMwLCAyMzc2MywgMjM3OTYsIDIzODI5LCAyMzg2MiwgMjM4OTUsIDIzOTI4LCAyMzk2MSwgMjM5OTQsIDI0MDI3LCAyNDA2MCwKKyAgICAgICAgMjQwOTMsIDI0MTI2LCAyNDE1OSwgMjQxOTIsIDI0MjI1LCAyNDI1OCwgMjQyOTEsIDI0MzI0LCAyNDM1NywgMjQzOTAsIDI0NDIzLCAyNDQ1NiwgMjQ0ODksIDI0NTIyLCAyNDU1NSwgMjQ1ODgsCisgICAgICAgIDI0NjIxLCAyNDY1NCwgMjQ2ODcsIDI0NzIwLCAyNDc1MywgMjQ3ODYsIDI0ODE5LCAyNDg1MiwgMjQ4ODUsIDI0OTE4LCAyNDk1MSwgMjQ5ODQsIDI1MDE3LCAyNTA1MCwgMjUwODMsIDI1MTE2LAorICAgICAgICAyNTE0OSwgMjUxODIsIDI1MjE1LCAyNTI0OCwgMjUyODEsIDI1MzE0LCAyNTM0NywgMjUzODAsIDI1NDEzLCAyNTQ0NiwgMjU0NzksIDI1NTEyLCAyNTU0NSwgMjU1NzgsIDI1NjExLCAyNTY0NCwKKyAgICAgICAgMjU2NzcsIDI1NzEwLCAyNTc0MywgMjU3NzYsIDI1ODA5LCAyNTg0MiwgMjU4NzUsIDI1OTA4LCAyNTk0MSwgMjU5NzQsIDI2MDA3LCAyNjA0MCwgMjYwNzMsIDI2MTA2LCAyNjEzOSwgMjYxNzIsCisgICAgICAgIDI2MjA1LCAyNjIzOCwgMjYyNzEsIDI2MzA0LCAyNjMzNywgMjYzNzAsIDI2NDAzLCAyNjQzNiwgMjY0NjksIDI2NTAyLCAyNjUzNSwgMjY1NjgsIDI2NjAxLCAyNjYzNCwgMjY2NjcsIDI2NzAwLAorICAgICAgICAyNjczMywgMjY3NjYsIDI2Nzk5LCAyNjgzMiwgMjY4NjUsIDI2ODk4LCAyNjkzMSwgMjY5NjQsIDI2OTk3LCAyNzAzMCwgMjcwNjMsIDI3MDk2LCAyNzEyOSwgMjcxNjIsIDI3MTk1LCAyNzIyOCwKKyAgICAgICAgMjcyNjEsIDI3Mjk0LCAyNzMyNywgMjczNjAsIDI3MzkzLCAyNzQyNiwgMjc0NTksIDI3NDkyLCAyNzUyNSwgMjc1NTgsIDI3NTkxLCAyNzYyNCwgMjc2NTcsIDI3NjkwLCAyNzcyMywgMjc3NTYsCisgICAgICAgIDI3Nzg5LCAyNzgyMiwgMjc4NTUsIDI3ODg4LCAyNzkyMSwgMjc5NTQsIDI3OTg3LCAyODAyMCwgMjgwNTMsIDI4MDg2LCAyODExOSwgMjgxNTIsIDI4MTg1LCAyODIxOCwgMjgyNTEsIDI4Mjg0LAorICAgICAgICAyODMxNywgMjgzNTAsIDI4MzgzLCAyODQxNiwgMjg0NDksIDI4NDgyLCAyODUxNSwgMjg1NDgsIDI4NTgxLCAyODYxNCwgMjg2NDcsIDI4NjgwLCAyODcxMywgMjg3NDYsIDI4Nzc5LCAyODgxMiwKKyAgICAgICAgMjg4NDUsIDI4ODc4LCAyODkxMSwgMjg5NDQsIDI4OTc3LCAyOTAxMCwgMjkwNDMsIDI5MDc2LCAyOTEwOSwgMjkxNDIsIDI5MTc1LCAyOTIwOCwgMjkyNDEsIDI5Mjc0LCAyOTMwNywgMjkzNDAsCisgICAgICAgIDI5MzczLCAyOTQwNiwgMjk0MzksIDI5NDcyLCAyOTUwNSwgMjk1MzgsIDI5NTcxLCAyOTYwNCwgMjk2MzcsIDI5NjcwLCAyOTcwMywgMjk3MzYsIDI5NzY5LCAyOTgwMiwgMjk4MzUsIDI5ODY4LAorICAgICAgICAyOTkwMSwgMjk5MzQsIDI5OTY3LCAzMDAwMCwgMzAwMzMsIDMwMDY2LCAzMDA5OSwgMzAxMzIsIDMwMTY1LCAzMDE5OCwgMzAyMzEsIDMwMjY0LCAzMDI5NywgMzAzMzAsIDMwMzYzLCAzMDM5NiwKKyAgICAgICAgMzA0MjksIDMwNDYyLCAzMDQ5NSwgMzA1MjgsIDMwNTYxLCAzMDU5NCwgMzA2MjcsIDMwNjYwLCAzMDY5MywgMzA3MjYsIDMwNzU5LCAzMDc5MiwgMzA4MjUsIDMwODU4LCAzMDg5MSwgMzA5MjQsCisgICAgICAgIDMwOTU3LCAzMDk5MCwgMzEwMjMsIDMxMDU2LCAzMTA4OSwgMzExMjIsIDMxMTU1LCAzMTE4OCwgMzEyMjEsIDMxMjU0LCAzMTI4NywgMzEzMjAsIDMxMzUzLCAzMTM4NiwgMzE0MTksIDMxNDUyLAorICAgICAgICAzMTQ4NSwgMzE1MTgsIDMxNTUxLCAzMTU4NCwgMzE2MTcsIDMxNjUwLCAzMTY4MywgMzE3MTYsIDMxNzQ5LCAzMTc4MiwgMzE4MTUsIDMxODQ4LCAzMTg4MSwgMzE5MTQsIDMxOTQ3LCAzMTk4MCwKKyAgICAgICAgMzIwMTMsIDMyMDQ2LCAzMjA3OSwgMzIxMTIsIDMyMTQ1LCAzMjE3OCwgMzIyMTEsIDMyMjQ0LCAzMjI3NywgMzIzMTAsIDMyMzQzLCAzMjM3NiwgMzI0MDksIDMyNDQyLCAzMjQ3NSwgMzI1MDgsCisgICAgICAgIDMyNTQxLCAzMjU3NCwgMzI2MDcsIDMyNjQwLCAzMjY3MywgMzI3MDYsIDMyNzM5CisgICAgfTsKKyAgICBzdGF0aWMgZmluYWwgY2hhcltdIGNoYXJzID0gT2xkQ2hhcnNldF9BYnN0cmFjdFRlc3QudGhlc2VDaGFycyhjb2Rlcyk7CisKKyAgICBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgQ29kZXNHZW5lcmF0b3IgeworICAgICAgICBpbnQgcm93ID0gMCwgY29sID0gMDsKKyAgICAgICAgYWJzdHJhY3Qgdm9pZCBjb25zdW1lIChpbnQgY29kZSk7CisKKyAgICAgICAgYm9vbGVhbiBpc0FjY2VwdGVkIChpbnQgY29kZSkKKyAgICAgICAgeworICAgICAgICAgICAgcmV0dXJuIENoYXJhY3Rlci5pc0xldHRlck9yRGlnaXQoY29kZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgQ29kZXNHZW5lcmF0b3IxIGV4dGVuZHMgQ29kZXNHZW5lcmF0b3IgeworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgdm9pZCBjb25zdW1lIChpbnQgY29kZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChjb2RlKTsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiwgIik7CisgICAgICAgICAgICBjb2wrKzsKKyAgICAgICAgICAgIGlmIChjb2wgPT0gMTYpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKKyAgICAgICAgICAgICAgICByb3crKzsKKyAgICAgICAgICAgICAgICBjb2wgPSAwOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIGJvb2xlYW4gaXNBY2NlcHRlZCAoaW50IGNvZGUpCisgICAgICAgIHsKKyAgICAgICAgICAgIHJldHVybiBDaGFyYWN0ZXIuaXNMZXR0ZXJPckRpZ2l0KGNvZGUpIHx8IENoYXJhY3Rlci5pc1doaXRlc3BhY2UoY29kZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgQ29kZXNHZW5lcmF0b3IyIGV4dGVuZHMgQ29kZXNHZW5lcmF0b3IgeworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgdm9pZCBjb25zdW1lIChpbnQgY29kZSkgeworLy8gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGNvZGUpOworLy8gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIsICIpOworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgoY2hhcikgY29kZSk7CisgICAgICAgICAgICBjb2wrKzsKKyAgICAgICAgICAgIGlmIChjb2wgPT0gODApIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKKyAgICAgICAgICAgICAgICByb3crKzsKKyAgICAgICAgICAgICAgICBjb2wgPSAwOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIENvZGVzR2VuZXJhdG9yMyBleHRlbmRzIENvZGVzR2VuZXJhdG9yIHsKKyAgICAgICAgY2hhcltdIGJ1ZiA9IG5ldyBjaGFyWzhdOworCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICB2b2lkIGNvbnN1bWUgKGludCBjb2RlKSB7CisgICAgICAgICAgICBidWZbY29sXSA9IChjaGFyKSBjb2RlOworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChjb2RlKTsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiwgIik7CisgICAgICAgICAgICBjb2wrKzsKKyAgICAgICAgICAgIGlmIChjb2wgPT0gOCkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiAvLyAiKTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oYnVmKTsKKyAgICAgICAgICAgICAgICByb3crKzsKKyAgICAgICAgICAgICAgICBjb2wgPSAwOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIGJvb2xlYW4gaXNBY2NlcHRlZCAoaW50IGNvZGUpCisgICAgICAgIHsKKyAgICAgICAgICAgIHJldHVybiBDaGFyYWN0ZXIuaXNMZXR0ZXJPckRpZ2l0KGNvZGUpOworLy8gICAgICAgICAgICAgICAgICAgIHx8IENoYXJhY3Rlci5pc1doaXRlc3BhY2UoY29kZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBnZW5Db2RlcyAoKSB7CisgICAgICAgIENvZGVzR2VuZXJhdG9yIGdlbiA9IG5ldyBDb2Rlc0dlbmVyYXRvcjEoKTsKKyAgICAgICAgaW50IGNvZGUgPSAwOworICAgICAgICB3aGlsZSAoY29kZSA8ICgxIDw8IDEwKSkgeworICAgICAgICAgICAgd2hpbGUgKCFnZW4uaXNBY2NlcHRlZChjb2RlKSkgY29kZSArKzsKKyAgICAgICAgICAgIGdlbi5jb25zdW1lKGNvZGUpOworICAgICAgICAgICAgY29kZSArPSAzOworICAgICAgICB9CisgICAgICAgIHdoaWxlIChjb2RlIDwgKDEgPDwgMTUpKSB7CisgICAgICAgICAgICB3aGlsZSAoIWdlbi5pc0FjY2VwdGVkKGNvZGUpKSBjb2RlICsrOworICAgICAgICAgICAgZ2VuLmNvbnN1bWUoY29kZSk7CisgICAgICAgICAgICBjb2RlICs9IDMzOworICAgICAgICB9CisgICAgfQorCisKKyAgICBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgRHVtcGVyIHsKKyAgICAgICAgaW50IHJvdyA9IDAsIGNvbCA9IDA7CisgICAgICAgIGFic3RyYWN0IHZvaWQgY29uc3VtZSAoaW50IGNvZGUpOworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBEdW1wZXIxIGV4dGVuZHMgRHVtcGVyIHsKKyAgICAgICAgaW50IGNvbE1heDsKKworICAgICAgICBEdW1wZXIxICgpIHsKKyAgICAgICAgICAgIGNvbE1heCA9IDE2OworICAgICAgICB9CisKKyAgICAgICAgRHVtcGVyMSAoaW50IGNvbHVtcykgeworICAgICAgICAgICAgY29sTWF4ID0gY29sdW1zOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHZvaWQgY29uc3VtZSAoaW50IGNvZGUpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoY29kZSk7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIsICIpOworICAgICAgICAgICAgY29sKys7CisgICAgICAgICAgICBpZiAoY29sID09IGNvbE1heCkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOworICAgICAgICAgICAgICAgIHJvdysrOworICAgICAgICAgICAgICAgIGNvbCA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBnZW5FbmNvZGVkIChDaGFyc2V0IGNoYXJzZXQsIENoYXJCdWZmZXIgY2IpIHsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGNoYXJzZXQubmFtZSgpKTsKKyAgICAgICAgRHVtcGVyIG91dCA9IG5ldyBEdW1wZXIxKCk7CisgICAgICAgIENoYXJzZXRFbmNvZGVyIGVuY29kZXIgPSBjaGFyc2V0Lm5ld0VuY29kZXIoKTsKKyAgICAgICAgZW5jb2Rlci5vblVubWFwcGFibGVDaGFyYWN0ZXIoQ29kaW5nRXJyb3JBY3Rpb24uUkVQTEFDRSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBCeXRlQnVmZmVyIGJiID0gZW5jb2Rlci5lbmNvZGUoY2IpOworLy8gICAgICAgICAgICBiYi5yZXdpbmQoKTsKKyAgICAgICAgICAgIHdoaWxlIChiYi5oYXNSZW1haW5pbmcoKSkgeworICAgICAgICAgICAgICAgIG91dC5jb25zdW1lKGJiLmdldCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihlKTsKKy8vICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBnZW5EZWNvZGVkIChDaGFyc2V0IGNoYXJzZXQsIEJ5dGVCdWZmZXIgYmIpIHsKKyAgICAgICAgQ2hhcnNldERlY29kZXIgZGVjb2RlciA9IGNoYXJzZXQubmV3RGVjb2RlcigpOworLy8gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihjb2RlKTsKKy8vICAgICAgICBieXRlc1swXSA9IChieXRlKSBjb2RlOworLy8gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihieXRlc1swXSk7CisvLyAgICAgICAgQnl0ZUJ1ZmZlciBpbnB1dEJCID0gQnl0ZUJ1ZmZlci53cmFwKGJ5dGVzKTsKKy8vICAgICAgICBDaGFyQnVmZmVyIG91dHB1dENCOworLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIG91dHB1dENCID0gZGVjb2Rlci5kZWNvZGUoaW5wdXRCQik7CisvLyAgICAgICAgICAgIG91dHB1dENCLnJld2luZCgpOworLy8gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4ob3V0cHV0Q0IpOworLy8gICAgICAgIH0gY2F0Y2ggKENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiBlKSB7CisvLyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihlKTsKKy8vLy8gICAgICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKy8vICAgICAgICB9CisgICAgfQorCisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CisvLyAgICAgICAgY2hhcnNldCA9IENoYXJzZXQuZGVmYXVsdENoYXJzZXQoKTsKKy8vICAgICAgICBkZWNvZGVyID0gY2hhcnNldC5uZXdEZWNvZGVyKCk7CisvLyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGNoYXJzZXQubmFtZSgpKTsKKyAgICAgICAgZ2VuRW5jb2RlZChDaGFyc2V0LmZvck5hbWUoIk1hY1JvbWFuIiksIENoYXJCdWZmZXIud3JhcChjaGFycykpOworLy8gICAgICAgIGdlbkVuY29kZWQoQ2hhcnNldC5mb3JOYW1lKGNoYXJzZXROYW1lc1szN10pLCBDaGFyQnVmZmVyLndyYXAoY2hhcnMpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldEVuY29kZXJEZWNvZGVyQnVmZmVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0RW5jb2RlckRlY29kZXJCdWZmZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjQ2NWQ5ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldEVuY29kZXJEZWNvZGVyQnVmZmVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTQ3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLkNoYXJCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldERlY29kZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0RW5jb2RlcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKworLyogU2VlIGJ1ZyBodHRwOi8vYi8xODQ0MTA0LgorICogQ2hlY2tzIGZvciBJQ1UgZW5jb2Rlci9kZWNvZGVyIGJ1ZmZlciBjb3JydXB0aW9uLgorICovCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldEVuY29kZXJEZWNvZGVyQnVmZmVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qIENoZWNrcyBmb3IgYSBidWZmZXIgY29ycnVwdGlvbiB0aGF0IGhhcHBlbnMgaW4gSUNVCisgICAgICogKENoYXJzZXREZWNvZGVySUNVKSB3aGVuIGEgZGVjb2RlIG9wZXJhdGlvbgorICAgICAqIGlzIGRvbmUgZmlyc3Qgd2l0aCBhbiBvdXQtYnVmZmVyIHdpdGggaGFzQXJyYXkoKT09dHJ1ZSwgYW5kIG5leHQgd2l0aCBhbiBvdXQtYnVmZmVyIHdpdGgKKyAgICAgKiBoYXNBcnJheSgpPT1mYWxzZS4gSW4gdGhhdCBzaXR1YXRpb24gSUNVIG1heSBvdmVyd3JpdGUgdGhlIGZpcnN0IG91dC1idWZmZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdERlY29kZXJPdXRwdXRCdWZmZXIoKSB7CisgICAgICAgIENoYXJzZXREZWNvZGVyIGRlY29kZXIgPSBDaGFyc2V0LmZvck5hbWUoIlVURi04IikubmV3RGVjb2RlcigpOworCisgICAgICAgIGNoYXJbXSBjQnVmID0gbmV3IGNoYXJbMTBdOworICAgICAgICBDaGFyQnVmZmVyIG91dCA9IENoYXJCdWZmZXIud3JhcChjQnVmKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShvdXQuaGFzQXJyYXkoKSk7CisgICAgICAgIGRlY29kZXIuZGVjb2RlKEJ5dGVCdWZmZXIud3JhcChuZXcgYnl0ZVtdeyhieXRlKSdhJywgKGJ5dGUpJ2InLCAoYnl0ZSknYycsIChieXRlKSdkJ30pLAorICAgICAgICAgICAgICAgICAgICAgICBvdXQsIGZhbHNlKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoImFiY2QiLCBuZXcgU3RyaW5nKGNCdWYsIDAsIDQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGNCdWZbNF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgY0J1Zls1XSk7CisKKyAgICAgICAgYnl0ZVtdIGJCdWYgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgIG91dCA9IEJ5dGVCdWZmZXIud3JhcChiQnVmKS5hc0NoYXJCdWZmZXIoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uob3V0Lmhhc0FycmF5KCkpOworICAgICAgICBkZWNvZGVyLmRlY29kZShCeXRlQnVmZmVyLndyYXAobmV3IGJ5dGVbXXsoYnl0ZSkneCd9KSwgb3V0LCB0cnVlKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoJ3gnLCBiQnVmWzFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGJCdWZbM10pOworCisgICAgICAgIC8vIGNoZWNrIGlmIHRoZSBmaXJzdCBidWZmZXIgd2FzIGNvcnJ1cHRlZCBieSB0aGUgc2Vjb25kIGRlY29kZQorICAgICAgICBhc3NlcnRFcXVhbHMoImFiY2QiLCBuZXcgU3RyaW5nKGNCdWYsIDAsIDQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGNCdWZbNF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgY0J1Zls1XSk7CisgICAgfQorCisgICAgLyogQ2hlY2tzIGZvciBhIGJ1ZmZlciBjb3JydXB0aW9uIHRoYXQgaGFwcGVucyBpbiBJQ1UKKyAgICAgKiAoQ2hhcnNldERlY29kZXJJQ1UpIHdoZW4gYSBkZWNvZGUgb3BlcmF0aW9uCisgICAgICogaXMgZG9uZSBmaXJzdCB3aXRoIGFuIGluLWJ1ZmZlciB3aXRoIGhhc0FycmF5KCk9PXRydWUsIGFuZCBuZXh0IHdpdGggYW4gaW4tYnVmZmVyIHdpdGgKKyAgICAgKiBoYXNBcnJheSgpPT1mYWxzZS4gSW4gdGhhdCBzaXR1YXRpb24gSUNVIG1heSBvdmVyd3JpdGUgdGhlIGFycmF5IG9mIHRoZSBmaXJzdCBpbi1idWZmZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdERlY29kZXJJbnB1dEJ1ZmZlcigpIHsKKyAgICAgICAgQ2hhcnNldERlY29kZXIgZGVjb2RlciA9IENoYXJzZXQuZm9yTmFtZSgiVVRGLTgiKS5uZXdEZWNvZGVyKCk7CisgICAgICAgIENoYXJCdWZmZXIgb3V0ID0gQ2hhckJ1ZmZlci53cmFwKG5ldyBjaGFyWzEwXSk7CisKKyAgICAgICAgYnl0ZVtdIGluQXJyYXkgPSB7KGJ5dGUpJ2EnLCAoYnl0ZSknYid9OworICAgICAgICBCeXRlQnVmZmVyIGluV2l0aEFycmF5ID0gQnl0ZUJ1ZmZlci53cmFwKGluQXJyYXkpOworICAgICAgICBhc3NlcnRUcnVlKGluV2l0aEFycmF5Lmhhc0FycmF5KCkpOworICAgICAgICBkZWNvZGVyLmRlY29kZShpbldpdGhBcnJheSwgb3V0LCBmYWxzZSk7CisgICAgICAgIGFzc2VydEVxdWFscygnYScsIGluQXJyYXlbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoJ2InLCBpbkFycmF5WzFdKTsKKworICAgICAgICAvLyBBIHJlYWQtb25seSBCeXRlQnVmZmVyIG11c3Qgbm90IGV4cG9zZSBpdHMgYXJyYXkuCisgICAgICAgIEJ5dGVCdWZmZXIgaW5XaXRob3V0QXJyYXkgPSBCeXRlQnVmZmVyLndyYXAobmV3IGJ5dGVbXSB7IChieXRlKSAneCcgfSkuYXNSZWFkT25seUJ1ZmZlcigpOworICAgICAgICBhc3NlcnRGYWxzZShpbldpdGhvdXRBcnJheS5oYXNBcnJheSgpKTsKKyAgICAgICAgZGVjb2Rlci5kZWNvZGUoaW5XaXRob3V0QXJyYXksIG91dCwgdHJ1ZSk7CisKKyAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgZmlyc3QgYnVmZmVyIHdhcyBjb3JydXB0ZWQgYnkgdGhlIHNlY29uZCBkZWNvZGUKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdhJywgaW5BcnJheVswXSk7CisgICAgICAgIGFzc2VydEVxdWFscygnYicsIGluQXJyYXlbMV0pOworICAgIH0KKworICAgIC8qIENoZWNrcyBmb3IgYSBidWZmZXIgY29ycnVwdGlvbiB0aGF0IGhhcHBlbnMgaW4gSUNVCisgICAgICogKENoYXJzZXRFbmNvZGVySUNVKSB3aGVuIGFuIGVuY29kZSBvcGVyYXRpb24KKyAgICAgKiBpcyBkb25lIGZpcnN0IHdpdGggYW4gb3V0LWJ1ZmZlciB3aXRoIGhhc0FycmF5KCk9PXRydWUsIGFuZCBuZXh0IHdpdGggYW4gb3V0LWJ1ZmZlciB3aXRoCisgICAgICogaGFzQXJyYXkoKT09ZmFsc2UuIEluIHRoYXQgc2l0dWF0aW9uIElDVSBtYXkgb3ZlcndyaXRlIHRoZSBmaXJzdCBvdXQtYnVmZmVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFbmNvZGVyT3V0cHV0QnVmZmVyKCkgeworICAgICAgICBDaGFyc2V0RW5jb2RlciBlbmNvZGVyID0gQ2hhcnNldC5mb3JOYW1lKCJVVEYtOCIpLm5ld0VuY29kZXIoKTsKKworICAgICAgICBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbMTBdOworICAgICAgICBCeXRlQnVmZmVyIG91dCA9IEJ5dGVCdWZmZXIud3JhcChidWZmZXIpOworCisgICAgICAgIGFzc2VydFRydWUob3V0Lmhhc0FycmF5KCkpOworICAgICAgICBlbmNvZGVyLmVuY29kZShDaGFyQnVmZmVyLndyYXAoImFiIiksIG91dCwgZmFsc2UpOworCisgICAgICAgIGFzc2VydEVxdWFscygnYScsIGJ1ZmZlclswXSk7CisgICAgICAgIGFzc2VydEVxdWFscygnYicsIGJ1ZmZlclsxXSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBidWZmZXJbMl0pOworCisgICAgICAgIG91dCA9IEJ5dGVCdWZmZXIuYWxsb2NhdGVEaXJlY3QoMTApOworICAgICAgICAvLyBJdCdzIG5vIGxvbmdlciBwb3NzaWJsZSB0byBnZXQgYSBieXRlIGJ1ZmZlciB3aXRob3V0IGEgYmFja2luZyBieXRlW10gb24gQW5kcm9pZC4KKyAgICAgICAgLy8gVGhpcyB0ZXN0IGlzIHVzZWxlc3Mgb24gQW5kcm9pZCwgdW5sZXNzIHRoYXQgY2hhbmdlcyBhZ2Fpbi4gKFlvdSBjYW4ndCBldmVuCisgICAgICAgIC8vIHN1YmNsYXNzIEJ5dGVCdWZmZXIgYmVjYXVzZSAtLSBhbHRob3VnaCBpdCdzIG5vbi1maW5hbCAtLSBib3RoIHRoZSBSSSBhbmQgQW5kcm9pZAorICAgICAgICAvLyBoYXZlIFtkaWZmZXJlbnRdIHBhY2thZ2UtcHJpdmF0ZSBhYnN0cmFjdCBtZXRob2RzIHlvdSdkIG5lZWQgdG8gaW1wbGVtZW50IGJ1dCBjYW4ndC4pCisgICAgICAgIC8vYXNzZXJ0RmFsc2Uob3V0Lmhhc0FycmF5KCkpOworICAgICAgICBlbmNvZGVyLmVuY29kZShDaGFyQnVmZmVyLndyYXAoIngiKSwgb3V0LCB0cnVlKTsKKworICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoZSBzZWNvbmQgZGVjb2RlIGNvcnJ1cHRlZCB0aGUgZmlyc3QgYnVmZmVyCisgICAgICAgIGFzc2VydEVxdWFscygnYScsIGJ1ZmZlclswXSk7CisgICAgICAgIGFzc2VydEVxdWFscygnYicsIGJ1ZmZlclsxXSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBidWZmZXJbMl0pOworICAgIH0KKworICAgIC8qIENoZWNrcyBmb3IgYSBidWZmZXIgY29ycnVwdGlvbiB0aGF0IGhhcHBlbnMgaW4gSUNVCisgICAgICogKENoYXJzZXRFbmNvZGVySUNVKSB3aGVuIGFuIGVuY29kZSBvcGVyYXRpb24KKyAgICAgKiBpcyBkb25lIGZpcnN0IHdpdGggYW4gaW4tYnVmZmVyIHdpdGggaGFzQXJyYXkoKT09dHJ1ZSwgYW5kIG5leHQgd2l0aCBhbiBpbi1idWZmZXIgd2l0aAorICAgICAqIGhhc0FycmF5KCk9PWZhbHNlLiBJbiB0aGF0IHNpdHVhdGlvbiBJQ1UgbWF5IG92ZXJ3cml0ZSB0aGUgYXJyYXkgb2YgdGhlIGZpcnN0IGluLWJ1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5jb2RlcklucHV0QnVmZmVyKCkgeworICAgICAgICBDaGFyc2V0RW5jb2RlciBlbmNvZGVyID0gQ2hhcnNldC5mb3JOYW1lKCJVVEYtOCIpLm5ld0VuY29kZXIoKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBvdXQgPSBCeXRlQnVmZmVyLndyYXAobmV3IGJ5dGVbMTBdKTsKKworICAgICAgICBjaGFyW10gaW5BcnJheSA9IHsnYScsICdiJ307CisgICAgICAgIENoYXJCdWZmZXIgaW5XaXRoQXJyYXkgPSBDaGFyQnVmZmVyLndyYXAoaW5BcnJheSk7CisgICAgICAgIGFzc2VydFRydWUoaW5XaXRoQXJyYXkuaGFzQXJyYXkoKSk7CisgICAgICAgIGVuY29kZXIuZW5jb2RlKGluV2l0aEFycmF5LCBvdXQsIGZhbHNlKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoJ2EnLCBpbkFycmF5WzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdiJywgaW5BcnJheVsxXSk7CisKKyAgICAgICAgQ2hhckJ1ZmZlciBpbldpdGhvdXRBcnJheSA9IENoYXJCdWZmZXIud3JhcCgieCIpOworICAgICAgICBhc3NlcnRGYWxzZShpbldpdGhvdXRBcnJheS5oYXNBcnJheSgpKTsKKyAgICAgICAgZW5jb2Rlci5lbmNvZGUoaW5XaXRob3V0QXJyYXksIG91dCwgdHJ1ZSk7CisKKyAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgc2Vjb25kIGRlY29kZSBjb3JydXB0ZWQgdGhlIGZpcnN0IGJ1ZmZlcgorICAgICAgICBhc3NlcnRFcXVhbHMoJ2EnLCBpbkFycmF5WzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdiJywgaW5BcnJheVsxXSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X0Fic3RyYWN0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X0Fic3RyYWN0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ2YTYzNWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfQWJzdHJhY3RUZXN0LmphdmEKQEAgLTAsMCArMSwzMDYgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFyc2V0OworCitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5DaGFyQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXREZWNvZGVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldEVuY29kZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5Db2RpbmdFcnJvckFjdGlvbjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogU3VwZXIgY2xhc3MgZm9yIGNvbmNyZXRlIGNoYXJzZXQgdGVzdCBzdWl0ZXMuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBPbGRDaGFyc2V0X0Fic3RyYWN0VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBTdHJpbmcgY2hhcnNldE5hbWU7CisgICAgc3RhdGljIHByaXZhdGUgQ2hhcnNldCBjaGFyc2V0OworICAgIHN0YXRpYyBDaGFyc2V0RGVjb2RlciBkZWNvZGVyOworICAgIHN0YXRpYyBDaGFyc2V0RW5jb2RlciBlbmNvZGVyOworCisgICAgc3RhdGljIGZpbmFsIGludFtdIGNvZGVzID0gQ2hhcnNldF9UZXN0R2VuZXJhdG9yLmNvZGVzOworCisgICAgc3RhdGljIGZpbmFsIGNoYXJbXSBjaGFycyA9IG5ldyBjaGFyW2NvZGVzLmxlbmd0aF07IC8vIElzIGZpbGxlZCB3aXRoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnRlbnRzIG9mIGNvZGVzLgorCisgICAgc3RhdGljIGNoYXJbXSB0ZXN0Q2hhcnM7CisgICAgc3RhdGljIGJ5dGVbXSB0ZXN0Qnl0ZXM7CisKKyAgICBzdGF0aWMgY2hhcltdIHRoZXNlQ2hhcnMgKGludFtdIGNvZGVzKSB7CisgICAgICAgIGNoYXJbXSBjaGFycyA9IG5ldyBjaGFyW2NvZGVzLmxlbmd0aF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY29kZXMubGVuZ3RoOyBpKyspIGNoYXJzW2ldID0gKGNoYXIpIGNvZGVzW2ldOworICAgICAgICByZXR1cm4gY2hhcnM7CisgICAgfQorCisgICAgc3RhdGljIGJ5dGVbXSB0aGVzZUJ5dGVzIChpbnRbXSBjb2RlcykgeworICAgICAgICBieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVtjb2Rlcy5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvZGVzLmxlbmd0aDsgaSsrKSBieXRlc1tpXSA9IChieXRlKSBjb2Rlc1tpXTsKKyAgICAgICAgcmV0dXJuIGJ5dGVzOworICAgIH0KKworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcnNldCA9IGNoYXJzZXQuZm9yTmFtZShjaGFyc2V0TmFtZSk7CisgICAgICAgIGRlY29kZXIgPSBjaGFyc2V0Lm5ld0RlY29kZXIoKTsKKyAgICAgICAgZW5jb2RlciA9IGNoYXJzZXQubmV3RW5jb2RlcigpOworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9uYW1lTWF0Y2ggKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIk5hbWUgb2YgY2hhcnNldCBtdXN0IG1hdGNoISIsIGNoYXJzZXROYW1lLCBjaGFyc2V0Lm5hbWUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9kdW1wRW5jb2RhYmxlQ2hhcnMgKCkgeworICAgICAgICBpZiAodGVzdENoYXJzID09IG51bGwpIHJldHVybjsKKyAgICAgICAgaWYgKHRlc3RDaGFycy5sZW5ndGggPiAwKSByZXR1cm47CisgICAgICAgIFN5c3RlbS5vdXQuZm9ybWF0KCJcbnRlc3RfZHVtcEVuY29kYWJsZUNoYXJzKCkgZm9yIG5hbWUgJXMgPT4gJXMgKGNsYXNzID0gJXMpXG4iLAorICAgICAgICAgICAgICAgIGNoYXJzZXROYW1lLCBjaGFyc2V0Lm5hbWUoKSwgZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworICAgICAgICBDaGFyc2V0X1Rlc3RHZW5lcmF0b3IuRHVtcGVyIG91dCA9IG5ldyBDaGFyc2V0X1Rlc3RHZW5lcmF0b3IuRHVtcGVyMSgxNik7CisgICAgICAgIGludCBjb2RlID0gMDsKKyAgICAgICAgd2hpbGUgKGNvZGUgPCAyNTYpIHsKKyAgICAgICAgICAgIHdoaWxlICghZW5jb2Rlci5jYW5FbmNvZGUoKGNoYXIpIGNvZGUpKSBjb2RlICsrOworICAgICAgICAgICAgaWYgKGNvZGUgPCA2NTUzNikgeworICAgICAgICAgICAgICAgIG91dC5jb25zdW1lKGNvZGUpOworICAgICAgICAgICAgICAgIGNvZGUgKz0gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB3aGlsZSAoY29kZSA8IDY1NTM2KSB7CisgICAgICAgICAgICB3aGlsZSAoIWVuY29kZXIuY2FuRW5jb2RlKChjaGFyKSBjb2RlKSkgY29kZSArKzsKKyAgICAgICAgICAgIGlmIChjb2RlIDwgNjU1MzYpIHsKKyAgICAgICAgICAgICAgICBvdXQuY29uc3VtZShjb2RlKTsKKyAgICAgICAgICAgICAgICBjb2RlICs9IDIwOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVuY29kYWJsZSBDaGFycyBkdW1wZWQgZm9yIFRlc3QgQ2xhc3MgIiArIGdldENsYXNzKCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgZmFpbCgiRW5jb2RhYmxlIENoYXJzIGR1bXBlZCBmb3IgVGVzdCBDbGFzcyAiICsgZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZHVtcEVuY29kZWQgKCkgdGhyb3dzIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0ZXN0Q2hhcnMgPT0gbnVsbCkgcmV0dXJuOworICAgICAgICBpZiAodGVzdENoYXJzLmxlbmd0aCA9PSAwKSByZXR1cm47CisgICAgICAgIGlmICh0ZXN0Qnl0ZXMubGVuZ3RoID4gMCkgcmV0dXJuOworICAgICAgICBTeXN0ZW0ub3V0LmZvcm1hdCgiXG50ZXN0X2R1bXBFbmNvZGVkKCkgZm9yIG5hbWUgJXMgPT4gJXMgKGNsYXNzID0gJXMpXG4iLAorICAgICAgICAgICAgICAgIGNoYXJzZXROYW1lLCBjaGFyc2V0Lm5hbWUoKSwgZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworICAgICAgICBDaGFyc2V0X1Rlc3RHZW5lcmF0b3IuRHVtcGVyIG91dCA9IG5ldyBDaGFyc2V0X1Rlc3RHZW5lcmF0b3IuRHVtcGVyMSgpOworICAgICAgICBDaGFyQnVmZmVyIGlucHV0Q0IgPSBDaGFyQnVmZmVyLndyYXAodGVzdENoYXJzKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBvdXRwdXRCQjsKKyAgICAgICAgZW5jb2Rlci5vblVubWFwcGFibGVDaGFyYWN0ZXIoQ29kaW5nRXJyb3JBY3Rpb24uUkVQT1JUKTsKKyAgICAgICAgb3V0cHV0QkIgPSBlbmNvZGVyLmVuY29kZShpbnB1dENCKTsKKyAgICAgICAgb3V0cHV0QkIucmV3aW5kKCk7CisgICAgICAgIHdoaWxlIChvdXRwdXRCQi5oYXNSZW1haW5pbmcoKSkgeworICAgICAgICAgICAgb3V0LmNvbnN1bWUob3V0cHV0QkIuZ2V0KCkgJiAweGZmKTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFbmNvZGVkIEJ5dGVzIGR1bXBlZCBmb3IgVGVzdCBDbGFzcyAiICsgZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworICAgICAgICBmYWlsKCJFbmNvZGVkIEJ5dGVzIGR1bXBlZCBmb3IgVGVzdCBDbGFzcyAiICsgZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworICAgIH0KKworCisgICAgc3RhdGljIHZvaWQgZGVjb2RlIChieXRlW10gaW5wdXQsIGNoYXJbXSBleHBlY3RlZE91dHB1dCkgdGhyb3dzIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVCdWZmZXIgaW5wdXRCQiA9IEJ5dGVCdWZmZXIud3JhcChpbnB1dCk7CisgICAgICAgIENoYXJCdWZmZXIgb3V0cHV0Q0I7CisgICAgICAgIGRlY29kZXIub25NYWxmb3JtZWRJbnB1dChDb2RpbmdFcnJvckFjdGlvbi5SRVBPUlQpOworICAgICAgICBvdXRwdXRDQiA9IGRlY29kZXIuZGVjb2RlKGlucHV0QkIpOworICAgICAgICBvdXRwdXRDQi5yZXdpbmQoKTsKKworLy8gICAgICAgIGFzc2VydFRydWUoIkRlY29kZWQgY2hhcmFjdGVzIG11c3QgbWF0Y2ghIiwKKy8vICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMoZXhwZWN0ZWRPdXRwdXQsIG91dHB1dENCLmFycmF5KCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxDaGFycygiRGVjb2RlZCBjaGFyYWN0ZXMgbXVzdCBtYXRjaCEiLAorICAgICAgICAgICAgICAgIGV4cGVjdGVkT3V0cHV0LCBvdXRwdXRDQik7CisKKy8vICAgICAgICBhc3NlcnRFcXVhbENoYXJzMigiRGVjb2RlZCBjaGFyYWN0ZXMgbXVzdCBtYXRjaCEiLAorLy8gICAgICAgICAgICAgICAgZXhwZWN0ZWRPdXRwdXQsCisvLyAgICAgICAgICAgICAgICBvdXRwdXRDQi5hcnJheSgpLAorLy8gICAgICAgICAgICAgICAgaW5wdXQpOworLy8gICAgICAgIGFzc2VydFRydWUoIkRlY29kZWQgY2hhcmFjdGVzIChSRVBMQUNFZWQgb25lcyBJTkNMVVNJVkUpIG11c3QgbWF0Y2ghIiwKKy8vICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMoZXhwZWN0ZWRPdXRwdXQsIG91dHB1dENCLmFycmF5KCkpKTsKKworLy8gICAgICAgIGFzc2VydEVxdWFsQ2hhcnMoIkRlY29kZWQgY2hhcmFjdGVzIChSRVBMQUNFZWQgb25lcyBJTkNMVVNJVkUpIG11c3QgbWF0Y2ghIiwKKy8vICAgICAgICAgICAgICAgIGV4cGVjdGVkT3V0cHV0LAorLy8gICAgICAgICAgICAgICAgb3V0cHV0Q0IuYXJyYXkoKSk7CisKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoIkRlY29kZWQgY2hhcmFjdGVzIG11c3QgbWF0Y2ghIiwKKy8vICAgICAgICAgICAgICAgIFN0cmluZy52YWx1ZU9mKGFsbENoYXJzKSwKKy8vICAgICAgICAgICAgICAgIG91dHB1dENCLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfRGVjb2RlICgpIHRocm93cyBDaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb24geworICAgICAgICBkZWNvZGUodGVzdEJ5dGVzLCB0ZXN0Q2hhcnMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfRW5jb2RlICgpIHRocm93cyBDaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb24geworICAgICAgICBDaGFyQnVmZmVyIGlucHV0Q0IgPSBDaGFyQnVmZmVyLndyYXAodGVzdENoYXJzKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBvdXRwdXRCQjsKKyAgICAgICAgZW5jb2Rlci5vblVubWFwcGFibGVDaGFyYWN0ZXIoQ29kaW5nRXJyb3JBY3Rpb24uUkVQT1JUKTsKKyAgICAgICAgb3V0cHV0QkIgPSBlbmNvZGVyLmVuY29kZShpbnB1dENCKTsKKyAgICAgICAgb3V0cHV0QkIucmV3aW5kKCk7CisvLyAgICAgICAgYXNzZXJ0VHJ1ZSgiRW5jb2RlZCBieXRlcyBtdXN0IG1hdGNoISIsCisvLyAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKHRlc3RCeXRlcywgb3V0cHV0QkIuYXJyYXkoKSkpOworICAgICAgICBhc3NlcnRFcXVhbEJ5dGVzKCJFbmNvZGVkIGJ5dGVzIG11c3QgbWF0Y2ghIiwgdGVzdEJ5dGVzLCBvdXRwdXRCQik7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCBOTnRlc3RfQ29kZWNEeW5hbWljSW5kaXZpZHVhbHMgKCkgdGhyb3dzIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGVuY29kZXIub25Vbm1hcHBhYmxlQ2hhcmFjdGVyKENvZGluZ0Vycm9yQWN0aW9uLlJFUE9SVCk7CisgICAgICAgIGRlY29kZXIub25NYWxmb3JtZWRJbnB1dChDb2RpbmdFcnJvckFjdGlvbi5SRVBPUlQpOworCisgICAgICAgIGZvciAoaW50IGNvZGUgPSAzMjsgY29kZSA8PSA2NTUzMzsgY29kZSArKykgeworICAgICAgICAgICAgaWYgKGVuY29kZXIuY2FuRW5jb2RlKChjaGFyKSBjb2RlKSkgeworLy8gICAgICAgICAgICAgICAgaW5wdXRDQi5yZXdpbmQoKTsKKyAgICAgICAgICAgICAgICBDaGFyQnVmZmVyIGlucHV0Q0IgPSBDaGFyQnVmZmVyLmFsbG9jYXRlKDEpOworICAgICAgICAgICAgICAgIGlucHV0Q0IucHV0KChjaGFyKSBjb2RlKTsKKyAgICAgICAgICAgICAgICBpbnB1dENCLnJld2luZCgpOworICAgICAgICAgICAgICAgIEJ5dGVCdWZmZXIgaW50ZXJtZWRpYXRlQkIgPSBlbmNvZGVyLmVuY29kZShpbnB1dENCKTsKKyAgICAgICAgICAgICAgICBpbnB1dENCLnJld2luZCgpOworICAgICAgICAgICAgICAgIGludGVybWVkaWF0ZUJCLnJld2luZCgpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIENoYXJCdWZmZXIgb3V0cHV0Q0IgPSBkZWNvZGVyLmRlY29kZShpbnRlcm1lZGlhdGVCQik7CisgICAgICAgICAgICAgICAgICAgIG91dHB1dENCLnJld2luZCgpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbENCcygiZGVjb2RlKGVuY29kZShBKSkgbXVzdCBiZSBpZGVudGljYWwgd2l0aCBBID0gIiArIGNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRDQiwgb3V0cHV0Q0IpOworICAgICAgICAgICAgICAgICAgICBpZiAoY29kZSA9PSAxNjUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dENCLnJld2luZCgpOworICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJXT1c6IiArIG91dHB1dENCLmdldCgpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoImZhaWxlZCB0byBkZWNvZGUoZW5jb2RlKCIgKyBjb2RlICsgIikpIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db2RlY0R5bmFtaWMgKCkgdGhyb3dzIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGVuY29kZXIub25Vbm1hcHBhYmxlQ2hhcmFjdGVyKENvZGluZ0Vycm9yQWN0aW9uLlJFUE9SVCk7CisgICAgICAgIGRlY29kZXIub25NYWxmb3JtZWRJbnB1dChDb2RpbmdFcnJvckFjdGlvbi5SRVBPUlQpOworICAgICAgICBDaGFyQnVmZmVyIGlucHV0Q0IgPSBDaGFyQnVmZmVyLmFsbG9jYXRlKDY1NTM2KTsKKyAgICAgICAgZm9yIChpbnQgY29kZSA9IDMyOyBjb2RlIDw9IDY1NTMzOyBjb2RlICsrKSB7CisgICAgICAgICAgICBpZiAoZW5jb2Rlci5jYW5FbmNvZGUoKGNoYXIpIGNvZGUpKSB7CisgICAgICAgICAgICAgICAgaW5wdXRDQi5wdXQoKGNoYXIpIGNvZGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlucHV0Q0IucmV3aW5kKCk7CisgICAgICAgIEJ5dGVCdWZmZXIgaW50ZXJtZWRpYXRlQkIgPSBlbmNvZGVyLmVuY29kZShpbnB1dENCKTsKKyAgICAgICAgaW5wdXRDQi5yZXdpbmQoKTsKKyAgICAgICAgaW50ZXJtZWRpYXRlQkIucmV3aW5kKCk7CisgICAgICAgIENoYXJCdWZmZXIgb3V0cHV0Q0IgPSBkZWNvZGVyLmRlY29kZShpbnRlcm1lZGlhdGVCQik7CisgICAgICAgIG91dHB1dENCLnJld2luZCgpOworICAgICAgICBhc3NlcnRFcXVhbENCcygiZGVjb2RlKGVuY29kZShBKSkgbXVzdCBiZSBpZGVudGljYWwgd2l0aCBBISIsCisgICAgICAgICAgICAgICAgaW5wdXRDQiwgb3V0cHV0Q0IpOworICAgIH0KKworICAgIHN0YXRpYyB2b2lkIGFzc2VydEVxdWFsQ0JzIChTdHJpbmcgbXNnLCBDaGFyQnVmZmVyIGV4cGVjdGVkQ0IsIENoYXJCdWZmZXIgYWN0dWFsQ0IpIHsKKyAgICAgICAgYm9vbGVhbiBtYXRjaCA9IHRydWU7CisgICAgICAgIGJvb2xlYW4gbGVuTWF0Y2ggPSB0cnVlOworICAgICAgICBjaGFyIGV4cGVjdGVkLCBhY3R1YWw7CisgICAgICAgIGludCBsZW4gPSBhY3R1YWxDQi5sZW5ndGgoKTsKKyAgICAgICAgaWYgKGV4cGVjdGVkQ0IubGVuZ3RoKCkgIT0gbGVuKSB7CisgICAgICAgICAgICBsZW5NYXRjaCA9IGZhbHNlOworICAgICAgICAgICAgaWYgKGV4cGVjdGVkQ0IubGVuZ3RoKCkgPCBsZW4pIGxlbiA9IGV4cGVjdGVkQ0IubGVuZ3RoKCk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgICAgICAgZXhwZWN0ZWQgPSBleHBlY3RlZENCLmdldCgpOworICAgICAgICAgICAgYWN0dWFsID0gYWN0dWFsQ0IuZ2V0KCk7CisgICAgICAgICAgICBpZiAoYWN0dWFsICE9IGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIGRldGFpbCA9IFN0cmluZy5mb3JtYXQoCisgICAgICAgICAgICAgICAgICAgICAgICAiTWlzbWF0Y2ggYXQgaW5kZXggJWQ6ICVkIGluc3RlYWQgb2YgZXhwZWN0ZWQgJWQuXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgaSwgKGludCkgYWN0dWFsLCAoaW50KSBleHBlY3RlZCk7CisgICAgICAgICAgICAgICAgbWF0Y2ggPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBmYWlsKG1zZyArICI6ICIgKyBkZXRhaWwpOworICAgICAgICAgICAgfQorLy8gICAgICAgICAgICBlbHNlIHsKKy8vICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQuZm9ybWF0KCJNYXRjaCBpbmRleCAlZDogJWQgPSAlZFxuIiwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgaSwgKGludCkgYWN0dWFsW2ldLCAoaW50KSBleHBlY3RlZFtpXSk7CisvLyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKG1zZywgbWF0Y2gpOworICAgICAgICBhc3NlcnRUcnVlKG1zZyArICIoSU4gTEVOR1RIIEFMU08hKSIsIGxlbk1hdGNoKTsKKy8vICAgICAgICBhc3NlcnRUcnVlKG1zZywgQXJyYXlzLmVxdWFscyhhY3R1YWwsIGV4cGVjdGVkKSk7CisgICAgfQorCisgICAgc3RhdGljIHZvaWQgYXNzZXJ0RXF1YWxDaGFycyAoU3RyaW5nIG1zZywgY2hhcltdIGV4cGVjdGVkLCBDaGFyQnVmZmVyIGFjdHVhbENCKSB7CisgICAgICAgIGJvb2xlYW4gbWF0Y2ggPSB0cnVlOworICAgICAgICBib29sZWFuIGxlbk1hdGNoID0gdHJ1ZTsKKyAgICAgICAgY2hhciBhY3R1YWw7CisgICAgICAgIGludCBsZW4gPSBhY3R1YWxDQi5sZW5ndGgoKTsKKyAgICAgICAgaWYgKGV4cGVjdGVkLmxlbmd0aCAhPSBsZW4pIHsKKyAgICAgICAgICAgIGxlbk1hdGNoID0gZmFsc2U7CisgICAgICAgICAgICBpZiAoZXhwZWN0ZWQubGVuZ3RoIDwgbGVuKSBsZW4gPSBleHBlY3RlZC5sZW5ndGg7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgICAgICAgYWN0dWFsID0gYWN0dWFsQ0IuZ2V0KCk7CisgICAgICAgICAgICBpZiAoYWN0dWFsICE9IGV4cGVjdGVkW2ldKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIGRldGFpbCA9IFN0cmluZy5mb3JtYXQoCisgICAgICAgICAgICAgICAgICAgICAgICAiTWlzbWF0Y2ggYXQgaW5kZXggJWQ6ICVkIGluc3RlYWQgb2YgZXhwZWN0ZWQgJWQuXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgaSwgKGludCkgYWN0dWFsLCAoaW50KSBleHBlY3RlZFtpXSk7CisgICAgICAgICAgICAgICAgbWF0Y2ggPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBmYWlsKG1zZyArICI6ICIgKyBkZXRhaWwpOworICAgICAgICAgICAgfQorLy8gICAgICAgICAgICBlbHNlIHsKKy8vICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQuZm9ybWF0KCJNYXRjaCBpbmRleCAlZDogJWQgPSAlZFxuIiwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgaSwgKGludCkgYWN0dWFsW2ldLCAoaW50KSBleHBlY3RlZFtpXSk7CisvLyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKG1zZywgbWF0Y2gpOworICAgICAgICBhc3NlcnRUcnVlKG1zZyArICIoSU4gTEVOR1RIIEFMU08hKSIsIGxlbk1hdGNoKTsKKy8vICAgICAgICBhc3NlcnRUcnVlKG1zZywgQXJyYXlzLmVxdWFscyhhY3R1YWwsIGV4cGVjdGVkKSk7CisgICAgfQorCisgICAgc3RhdGljIHZvaWQgYXNzZXJ0RXF1YWxCeXRlcyAoU3RyaW5nIG1zZywgYnl0ZVtdIGV4cGVjdGVkLCBCeXRlQnVmZmVyIGFjdHVhbEJCKSB7CisgICAgICAgIGJvb2xlYW4gbWF0Y2ggPSB0cnVlOworICAgICAgICBib29sZWFuIGxlbk1hdGNoID0gdHJ1ZTsKKyAgICAgICAgYnl0ZSBhY3R1YWw7CisgICAgICAgIGludCBsZW4gPSBhY3R1YWxCQi5yZW1haW5pbmcoKTsKKyAgICAgICAgaWYgKGV4cGVjdGVkLmxlbmd0aCAhPSBsZW4pIHsKKyAgICAgICAgICAgIGxlbk1hdGNoID0gZmFsc2U7CisgICAgICAgICAgICBpZiAoZXhwZWN0ZWQubGVuZ3RoIDwgbGVuKSBsZW4gPSBleHBlY3RlZC5sZW5ndGg7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgICAgICAgYWN0dWFsID0gYWN0dWFsQkIuZ2V0KCk7CisgICAgICAgICAgICBpZiAoYWN0dWFsICE9IGV4cGVjdGVkW2ldKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIGRldGFpbCA9IFN0cmluZy5mb3JtYXQoCisgICAgICAgICAgICAgICAgICAgICAgICAiTWlzbWF0Y2ggYXQgaW5kZXggJWQ6ICVkIGluc3RlYWQgb2YgZXhwZWN0ZWQgJWQuXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgaSwgYWN0dWFsICYgMHhmZiwgZXhwZWN0ZWRbaV0gJiAweGZmKTsKKyAgICAgICAgICAgICAgICBtYXRjaCA9IGZhbHNlOworICAgICAgICAgICAgICAgIGZhaWwobXNnICsgIjogIiArIGRldGFpbCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZShtc2csIG1hdGNoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtc2cgKyAiKElOIExFTkdUSCBBTFNPISkiLCBsZW5NYXRjaCk7CisgICAgfQorCisKKyAgICBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgQ29kZXNHZW5lcmF0b3IgeworICAgICAgICBpbnQgcm93ID0gMCwgY29sID0gMDsKKworICAgICAgICBhYnN0cmFjdCB2b2lkIGNvbnN1bWUoaW50IGNvZGUpOworCisgICAgICAgIGJvb2xlYW4gaXNBY2NlcHRlZChpbnQgY29kZSkgeworICAgICAgICAgICAgcmV0dXJuIENoYXJhY3Rlci5pc0xldHRlck9yRGlnaXQoY29kZSk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9HU00wMzM4LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfR1NNMDMzOC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE4ZDI2NjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfR1NNMDMzOC5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uOworCisvKiogTm90ZTogdGhpcyB0ZXN0IGlzIEdTTSBzcGVjaWZpYyAqLworcHVibGljIGNsYXNzIE9sZENoYXJzZXRfR1NNMDMzOCBleHRlbmRzIE9sZENoYXJzZXRfQWJzdHJhY3RUZXN0IHsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisvLyAgICAgICAgY2hhcnNldE5hbWUgPSAiR1NNMDMzOCI7CisgICAgICAgIGNoYXJzZXROYW1lID0gIngtZ3NtLTAzLjM4LTIwMDAiOworCisgICAgICAgIHRlc3RDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworMTAsIDEzLCAzMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsCis0NiwgNDcsIDQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwKKzYyLCA2MywgNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LAorNzgsIDc5LCA4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDk1LCA5NywgOTgsCis5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwgMTEyLCAxMTMsIDExNCwKKzExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxNjEsIDE2MywgMTY0LCAxNjUsIDE2NywgMTkxLCAxOTYsIDE5NywKKzE5OCwgMjAxLCAyMDksIDIxNCwgMjE2LCAyMjAsIDIyMywgMjI0LCAyMjgsIDIyOSwgMjMwLCAyMzEsIDIzMiwgMjMzLCAyMzYsIDI0MSwKKzI0MiwgMjQ2LCAyNDgsIDI0OSwgMjUyLCA5MTUsIDkxNgorICAgICAgICAgICAgfSk7CisKKyAgICAgICAgdGVzdEJ5dGVzID0gdGhlc2VCeXRlcyhuZXcgaW50W117CisxMCwgMTMsIDMyLCAzMywgMzQsIDM1LCAyLCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LAorNDYsIDQ3LCA0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsCis2MiwgNjMsIDAsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LAorNzgsIDc5LCA4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDE3LCA5NywgOTgsCis5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwgMTEyLCAxMTMsIDExNCwKKzExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCA2NCwgMSwgMzYsIDMsIDk1LCA5NiwgOTEsIDE0LAorMjgsIDMxLCA5MywgOTIsIDExLCA5NCwgMzAsIDEyNywgMTIzLCAxNSwgMjksIDksIDQsIDUsIDcsIDEyNSwKKzgsIDEyNCwgMTIsIDYsIDEyNiwgMTksIDE2CisgICAgICAgICAgICB9KTsKKworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29kZWNEeW5hbWljICgpIHRocm93cyBDaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb24geworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X0lTT184ODU5XzEwLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfSVNPXzg4NTlfMTAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jN2JiYzk0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X0lTT184ODU5XzEwLmphdmEKQEAgLTAsMCArMSw2MiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFyc2V0OworCisvKiogTm90ZTogSUNVIG9ubHkgKi8KK3B1YmxpYyBjbGFzcyBPbGRDaGFyc2V0X0lTT184ODU5XzEwIGV4dGVuZHMgT2xkQ2hhcnNldF9BYnN0cmFjdFRlc3QgeworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcnNldE5hbWUgPSAiSVNPLTg4NTktMTAiOworCisgICAgICAgIHRlc3RDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKzE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCis0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKzY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCis5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKzExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKzEyOCwgMTI5LCAxMzAsIDEzMSwgMTMyLCAxMzMsIDEzNCwgMTM1LCAxMzYsIDEzNywgMTM4LCAxMzksIDE0MCwgMTQxLCAxNDIsIDE0MywKKzE0NCwgMTQ1LCAxNDYsIDE0NywgMTQ4LCAxNDksIDE1MCwgMTUxLCAxNTIsIDE1MywgMTU0LCAxNTUsIDE1NiwgMTU3LCAxNTgsIDE1OSwKKzE2MCwgMTY3LCAxNzMsIDE3NiwgMTgzLCAxOTMsIDE5NCwgMTk1LCAxOTYsIDE5NywgMTk4LCAyMDEsIDIwMywgMjA1LCAyMDYsIDIwNywKKzIwOCwgMjExLCAyMTIsIDIxMywgMjE0LCAyMTYsIDIxOCwgMjE5LCAyMjAsIDIyMSwgMjIyLCAyMjMsIDIyNSwgMjI2LCAyMjcsIDIyOCwKKzIyOSwgMjMwLCAyMzMsIDIzNSwgMjM3LCAyMzgsIDIzOSwgMjQwLCAyNDMsIDI0NCwgMjQ1LCAyNDYsIDI0OCwgMjUwLCAyNTEsIDI1MiwKKzI1MywgMjU0LCAyNTYsIDI1NywgMjkwLCAzMjUsIDM1OCwgODIxMworICAgICAgICAgICAgfSk7CisKKyAgICAgICAgdGVzdEJ5dGVzID0gdGhlc2VCeXRlcyhuZXcgaW50W117CiswLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAorMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCiszMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKzQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCis4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKzk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorMTI4LCAxMjksIDEzMCwgMTMxLCAxMzIsIDEzMywgMTM0LCAxMzUsIDEzNiwgMTM3LCAxMzgsIDEzOSwgMTQwLCAxNDEsIDE0MiwgMTQzLAorMTQ0LCAxNDUsIDE0NiwgMTQ3LCAxNDgsIDE0OSwgMTUwLCAxNTEsIDE1MiwgMTUzLCAxNTQsIDE1NSwgMTU2LCAxNTcsIDE1OCwgMTU5LAorMTYwLCAxNjcsIDE3MywgMTc2LCAxODMsIDE5MywgMTk0LCAxOTUsIDE5NiwgMTk3LCAxOTgsIDIwMSwgMjAzLCAyMDUsIDIwNiwgMjA3LAorMjA4LCAyMTEsIDIxMiwgMjEzLCAyMTQsIDIxNiwgMjE4LCAyMTksIDIyMCwgMjIxLCAyMjIsIDIyMywgMjI1LCAyMjYsIDIyNywgMjI4LAorMjI5LCAyMzAsIDIzMywgMjM1LCAyMzcsIDIzOCwgMjM5LCAyNDAsIDI0MywgMjQ0LCAyNDUsIDI0NiwgMjQ4LCAyNTAsIDI1MSwgMjUyLAorMjUzLCAyNTQsIDE5MiwgMjI0LCAxNjMsIDIwOSwgMTcxLCAxODkKKyAgICAgICAgICAgIH0pOworCisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfSVNPXzg4NTlfMTQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9JU09fODg1OV8xNC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFkYWVkZjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfSVNPXzg4NTlfMTQuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKKy8qKiBOb3RlOiBJQ1Ugb25seSAqLworcHVibGljIGNsYXNzIE9sZENoYXJzZXRfSVNPXzg4NTlfMTQgZXh0ZW5kcyBPbGRDaGFyc2V0X0Fic3RyYWN0VGVzdCB7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyc2V0TmFtZSA9ICJJU08tODg1OS0xNCI7CisKKyAgICAgICAgdGVzdENoYXJzID0gdGhlc2VDaGFycyhuZXcgaW50W117CiswLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAorMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCiszMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKzQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCis4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKzk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorMTI4LCAxMjksIDEzMCwgMTMxLCAxMzIsIDEzMywgMTM0LCAxMzUsIDEzNiwgMTM3LCAxMzgsIDEzOSwgMTQwLCAxNDEsIDE0MiwgMTQzLAorMTQ0LCAxNDUsIDE0NiwgMTQ3LCAxNDgsIDE0OSwgMTUwLCAxNTEsIDE1MiwgMTUzLCAxNTQsIDE1NSwgMTU2LCAxNTcsIDE1OCwgMTU5LAorMTYwLCAxNjMsIDE2NywgMTY5LCAxNzMsIDE3NCwgMTgyLCAxOTIsIDE5MywgMTk0LCAxOTUsIDE5NiwgMTk3LCAxOTgsIDE5OSwgMjAwLAorMjAxLCAyMDIsIDIwMywgMjA0LCAyMDUsIDIwNiwgMjA3LCAyMDksIDIxMCwgMjExLCAyMTIsIDIxMywgMjE0LCAyMTYsIDIxNywgMjE4LAorMjE5LCAyMjAsIDIyMSwgMjIzLCAyMjQsIDIyNSwgMjI2LCAyMjcsIDIyOCwgMjI5LCAyMzAsIDIzMSwgMjMyLCAyMzMsIDIzNCwgMjM1LAorMjM2LCAyMzcsIDIzOCwgMjM5LCAyNDEsIDI0MiwgMjQzLCAyNDQsIDI0NSwgMjQ2LCAyNDgsIDI0OSwgMjUwLCAyNTEsIDI1MiwgMjUzLAorMjU1LCAyNjYsIDM3MiwgNzY4MiwgNzc0NCwgNzc3NiwgNzgwOCwgNzkyMgorICAgICAgICAgICAgfSk7CisKKyAgICAgICAgdGVzdEJ5dGVzID0gdGhlc2VCeXRlcyhuZXcgaW50W117CiswLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAorMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCiszMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKzQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCis4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKzk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorMTI4LCAxMjksIDEzMCwgMTMxLCAxMzIsIDEzMywgMTM0LCAxMzUsIDEzNiwgMTM3LCAxMzgsIDEzOSwgMTQwLCAxNDEsIDE0MiwgMTQzLAorMTQ0LCAxNDUsIDE0NiwgMTQ3LCAxNDgsIDE0OSwgMTUwLCAxNTEsIDE1MiwgMTUzLCAxNTQsIDE1NSwgMTU2LCAxNTcsIDE1OCwgMTU5LAorMTYwLCAxNjMsIDE2NywgMTY5LCAxNzMsIDE3NCwgMTgyLCAxOTIsIDE5MywgMTk0LCAxOTUsIDE5NiwgMTk3LCAxOTgsIDE5OSwgMjAwLAorMjAxLCAyMDIsIDIwMywgMjA0LCAyMDUsIDIwNiwgMjA3LCAyMDksIDIxMCwgMjExLCAyMTIsIDIxMywgMjE0LCAyMTYsIDIxNywgMjE4LAorMjE5LCAyMjAsIDIyMSwgMjIzLCAyMjQsIDIyNSwgMjI2LCAyMjcsIDIyOCwgMjI5LCAyMzAsIDIzMSwgMjMyLCAyMzMsIDIzNCwgMjM1LAorMjM2LCAyMzcsIDIzOCwgMjM5LCAyNDEsIDI0MiwgMjQzLCAyNDQsIDI0NSwgMjQ2LCAyNDgsIDI0OSwgMjUwLCAyNTEsIDI1MiwgMjUzLAorMjU1LCAxNjQsIDIwOCwgMTYxLCAxODAsIDE4NywgMTY4LCAxNzIKKyAgICAgICAgICAgIH0pOworCisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfSVNPXzg4NTlfMTYuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9JU09fODg1OV8xNi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVkYjIxOWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfSVNPXzg4NTlfMTYuamF2YQpAQCAtMCwwICsxLDYyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKKy8qKiBOb3RlOiBJQ1Ugb25seSAqLworcHVibGljIGNsYXNzIE9sZENoYXJzZXRfSVNPXzg4NTlfMTYgZXh0ZW5kcyBPbGRDaGFyc2V0X0Fic3RyYWN0VGVzdCB7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyc2V0TmFtZSA9ICJJU08tODg1OS0xNiI7CisKKyAgICAgICAgdGVzdENoYXJzID0gdGhlc2VDaGFycyhuZXcgaW50W117CiswLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAorMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCiszMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKzQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCis4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKzk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorMTI4LCAxMjksIDEzMCwgMTMxLCAxMzIsIDEzMywgMTM0LCAxMzUsIDEzNiwgMTM3LCAxMzgsIDEzOSwgMTQwLCAxNDEsIDE0MiwgMTQzLAorMTQ0LCAxNDUsIDE0NiwgMTQ3LCAxNDgsIDE0OSwgMTUwLCAxNTEsIDE1MiwgMTUzLCAxNTQsIDE1NSwgMTU2LCAxNTcsIDE1OCwgMTU5LAorMTYwLCAxNjcsIDE2OSwgMTcxLCAxNzMsIDE3NiwgMTc3LCAxODIsIDE4MywgMTg3LCAxOTIsIDE5MywgMTk0LCAxOTYsIDE5OCwgMTk5LAorMjAwLCAyMDEsIDIwMiwgMjAzLCAyMDQsIDIwNSwgMjA2LCAyMDcsIDIxMCwgMjExLCAyMTIsIDIxNCwgMjE3LCAyMTgsIDIxOSwgMjIwLAorMjIzLCAyMjQsIDIyNSwgMjI2LCAyMjgsIDIzMCwgMjMxLCAyMzIsIDIzMywgMjM0LCAyMzUsIDIzNiwgMjM3LCAyMzgsIDIzOSwgMjQyLAorMjQzLCAyNDQsIDI0NiwgMjQ5LCAyNTAsIDI1MSwgMjUyLCAyNTUsIDI1OCwgMzIxLCAzNTIsIDM4MiwgNTM2LCA4MjIxLCA4MzY0CisgICAgICAgICAgICB9KTsKKworICAgICAgICB0ZXN0Qnl0ZXMgPSB0aGVzZUJ5dGVzKG5ldyBpbnRbXXsKKzAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKzMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCis2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKzgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisxMjgsIDEyOSwgMTMwLCAxMzEsIDEzMiwgMTMzLCAxMzQsIDEzNSwgMTM2LCAxMzcsIDEzOCwgMTM5LCAxNDAsIDE0MSwgMTQyLCAxNDMsCisxNDQsIDE0NSwgMTQ2LCAxNDcsIDE0OCwgMTQ5LCAxNTAsIDE1MSwgMTUyLCAxNTMsIDE1NCwgMTU1LCAxNTYsIDE1NywgMTU4LCAxNTksCisxNjAsIDE2NywgMTY5LCAxNzEsIDE3MywgMTc2LCAxNzcsIDE4MiwgMTgzLCAxODcsIDE5MiwgMTkzLCAxOTQsIDE5NiwgMTk4LCAxOTksCisyMDAsIDIwMSwgMjAyLCAyMDMsIDIwNCwgMjA1LCAyMDYsIDIwNywgMjEwLCAyMTEsIDIxMiwgMjE0LCAyMTcsIDIxOCwgMjE5LCAyMjAsCisyMjMsIDIyNCwgMjI1LCAyMjYsIDIyOCwgMjMwLCAyMzEsIDIzMiwgMjMzLCAyMzQsIDIzNSwgMjM2LCAyMzcsIDIzOCwgMjM5LCAyNDIsCisyNDMsIDI0NCwgMjQ2LCAyNDksIDI1MCwgMjUxLCAyNTIsIDI1NSwgMTk1LCAxNjMsIDE2NiwgMTg0LCAxNzAsIDE4MSwgMTY0CisgICAgICAgICAgICB9KTsKKworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X011bHRpQnl0ZV9CaWc1LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX0JpZzUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMzMwY2Q1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X011bHRpQnl0ZV9CaWc1LmphdmEKQEAgLTAsMCArMSw0MjEgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworLyoqIEBoaWRlCisgKiBTRUUgY29ycmVzcG9uZGlnX0FuZHJvaWQgdGVzdCBjbGFzczoKKyAqLworCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9NdWx0aUJ5dGVfQmlnNSBleHRlbmRzIE9sZENoYXJzZXRfQWJzdHJhY3RUZXN0IHsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJzZXROYW1lID0gIkJpZzUiOworCisgICAgICAgIHRlc3RDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKzE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCis0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKzY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCis5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKzExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKzE2MiwgMTYzLCAxNjUsIDE2NywgMTc2LCAxNzcsIDE4MywgMjE1LCAyNDcsIDcxMSwgNzEzLCA3MjksIDkxMywgOTIzLCA5MzMsIDk0NSwKKzk1NSwgOTY1LCAxMDI1LCAxMDQ0LCAxMDU5LCAxMDY5LCAxMDc5LCAxMDg5LCAxMDk5LCA4MjExLCA4MjIxLCA4MjQyLCA4MjU0LCA4NDUxLCA4NTQ0LCA4NTkyLAorODczMCwgODc0MSwgODc1NiwgODc4NiwgODgwMCwgODg2OSwgODg5NSwgOTMxMiwgOTMzMiwgOTQ3MiwgOTQ4NCwgOTQ5NiwgOTUwOCwgOTUyNCwgOTU1MiwgOTU2NiwKKzk1NzgsIDk2MDEsIDk2MTEsIDk2MjEsIDk2MzIsIDk2NTAsIDk2NjAsIDk2NzAsIDk2OTgsIDk3MzMsIDk3OTIsIDEyMjg4LCAxMjI5OCwgMTIzMDgsIDEyMzE4LCAxMjMyOCwKKzEyMzUzLCAxMjM2MywgMTIzNzMsIDEyMzgzLCAxMjM5MywgMTI0MDMsIDEyNDEzLCAxMjQyMywgMTI0MzMsIDEyNDQ1LCAxMjQ1NSwgMTI0NjUsIDEyNDc1LCAxMjQ4NSwgMTI0OTUsIDEyNTA1LAorMTI1MTUsIDEyNTI1LCAxMjU0MiwgMTI1NTIsIDEyNTYyLCAxMjU3MiwgMTI1ODIsIDEyOTYzLCAxMzE5OCwgMTMyMTIsIDEzMjUyLCAxMzI2MiwgMTk5NjgsIDE5OTc4LCAxOTk4OCwgMTk5OTgsCisyMDAxMSwgMjAwMjQsIDIwMDM0LCAyMDA0NSwgMjAwNTYsIDIwMDczLCAyMDA4MywgMjAwOTQsIDIwMTA0LCAyMDExNCwgMjAxMjYsIDIwMTM2LCAyMDE0NywgMjAxNjAsIDIwMTcwLCAyMDE4MCwKKzIwMTkwLCAyMDIwMCwgMjAyMTAsIDIwMjIxLCAyMDIzMiwgMjAyNDIsIDIwMjUzLCAyMDI2OCwgMjAyNzgsIDIwMjg5LCAyMDMwMCwgMjAzMTAsIDIwMzIwLCAyMDMzMCwgMjAzNDAsIDIwMzUwLAorMjAzNjAsIDIwMzcwLCAyMDM4MCwgMjAzOTgsIDIwNDA5LCAyMDQxOSwgMjA0MjksIDIwNDM5LCAyMDQ0OSwgMjA0NjAsIDIwNDcwLCAyMDQ4MCwgMjA0OTEsIDIwNTAxLCAyMDUxMSwgMjA1MjEsCisyMDUzMSwgMjA1NDQsIDIwNTU0LCAyMDU2NSwgMjA1NzUsIDIwNTg1LCAyMDU5NSwgMjA2MDUsIDIwNjE1LCAyMDYyNSwgMjA2MzUsIDIwNjUyLCAyMDY2MiwgMjA2NzMsIDIwNjgzLCAyMDY5MywKKzIwNzA0LCAyMDcxNCwgMjA3MjUsIDIwNzM1LCAyMDc0NSwgMjA3NTUsIDIwNzY3LCAyMDc3NywgMjA3ODcsIDIwNzk3LCAyMDgwNywgMjA4MTgsIDIwODI4LCAyMDgzOSwgMjA4NDksIDIwODYwLAorMjA4NzEsIDIwODgxLCAyMDg5NCwgMjA5MDYsIDIwOTE4LCAyMDkzMiwgMjA5NDIsIDIwOTUyLCAyMDk3NiwgMjA5ODYsIDIwOTk4LCAyMTAwOCwgMjEwMjAsIDIxMDMyLCAyMTA0MiwgMjEwNTcsCisyMTA2NywgMjEwNzcsIDIxMDg3LCAyMTA5NywgMjExMDgsIDIxMTE5LCAyMTEyOSwgMjExMzksIDIxMTUxLCAyMTE2MSwgMjExNzksIDIxMTkxLCAyMTIwMiwgMjEyMTMsIDIxMjI1LCAyMTIzNSwKKzIxMjQ2LCAyMTI1NiwgMjEyNjYsIDIxMjc2LCAyMTI5MCwgMjEzMDAsIDIxMzEwLCAyMTMyMCwgMjEzMzAsIDIxMzQwLCAyMTM1MCwgMjEzNjAsIDIxMzcxLCAyMTM4NiwgMjEzOTYsIDIxNDA2LAorMjE0MjAsIDIxNDMzLCAyMTQ0MywgMjE0NTMsIDIxNDYzLCAyMTQ3MywgMjE0ODMsIDIxNDkzLCAyMTUwNSwgMjE1MTUsIDIxNTI4LCAyMTU0MCwgMjE1NTAsIDIxNTYwLCAyMTU3MCwgMjE1ODIsCisyMTYwMCwgMjE2MTEsIDIxNjIxLCAyMTYzMSwgMjE2NDMsIDIxNjUzLCAyMTY2NCwgMjE2NzQsIDIxNjg2LCAyMTY5NiwgMjE3MTAsIDIxNzI2LCAyMTczNiwgMjE3NDYsIDIxNzU2LCAyMTc2NiwKKzIxNzc2LCAyMTc4NiwgMjE3OTgsIDIxODA4LCAyMTgxOSwgMjE4MjksIDIxODM5LCAyMTg1MiwgMjE4NjIsIDIxODc3LCAyMTg4NywgMjE4OTcsIDIxOTA3LCAyMTkxNywgMjE5MjcsIDIxOTM3LAorMjE5NDcsIDIxOTU3LCAyMTk2NywgMjE5NzcsIDIxOTg3LCAyMTk5OSwgMjIwMDksIDIyMDIwLCAyMjAzMCwgMjIwNDMsIDIyMDU1LCAyMjA2NiwgMjIwNzcsIDIyMDg4LCAyMjA5OSwgMjIxMTAsCisyMjEyMCwgMjIxMzAsIDIyMTQyLCAyMjE1NiwgMjIxNjcsIDIyMTgxLCAyMjE5NCwgMjIyMDQsIDIyMjE0LCAyMjIyNSwgMjIyMzUsIDIyMjQ1LCAyMjI1NiwgMjIyNjYsIDIyMjc2LCAyMjI5MCwKKzIyMzAwLCAyMjMxMiwgMjIzMjMsIDIyMzM0LCAyMjM0NSwgMjIzNjksIDIyMzc5LCAyMjM4OSwgMjI0MDAsIDIyNDExLCAyMjQyMSwgMjI0MzEsIDIyNDQ2LCAyMjQ1NiwgMjI0NjYsIDIyNDc2LAorMjI0OTIsIDIyNTAzLCAyMjUxMywgMjI1MjMsIDIyNTMzLCAyMjU0NCwgMjI1NTUsIDIyNTY1LCAyMjU3NSwgMjI1ODUsIDIyNjAwLCAyMjYxMCwgMjI2MjEsIDIyNjMyLCAyMjY0NCwgMjI2NTQsCisyMjY2NCwgMjI2NzUsIDIyNjg1LCAyMjY5NiwgMjI3MDcsIDIyNzE3LCAyMjcyNywgMjI3MzcsIDIyNzQ3LCAyMjc1OSwgMjI3NzIsIDIyNzgyLCAyMjc5NiwgMjI4MDYsIDIyODE2LCAyMjgyNiwKKzIyODM5LCAyMjg1MiwgMjI4NjIsIDIyODcyLCAyMjg4MiwgMjI4OTMsIDIyOTAzLCAyMjkxMywgMjI5MjUsIDIyOTM1LCAyMjk0NSwgMjI5NTgsIDIyOTY5LCAyMjk3OSwgMjI5ODksIDIzMDAwLAorMjMwMTEsIDIzMDIxLCAyMzAzMSwgMjMwNDEsIDIzMDUyLCAyMzA2MiwgMjMwNzIsIDIzMDg1LCAyMzA5NSwgMjMxMDUsIDIzMTE2LCAyMzEyNiwgMjMxMzYsIDIzMTQ2LCAyMzE1OSwgMjMxNzEsCisyMzE4MiwgMjMxOTQsIDIzMjA1LCAyMzIxNSwgMjMyMjUsIDIzMjM2LCAyMzI1MywgMjMyNjMsIDIzMjczLCAyMzI4MywgMjMyOTMsIDIzMzAzLCAyMzMxNSwgMjMzMjUsIDIzMzM1LCAyMzM0NiwKKzIzMzU2LCAyMzM2NywgMjMzNzcsIDIzMzg3LCAyMzM5NywgMjM0MDgsIDIzNDE4LCAyMzQyOCwgMjM0MzgsIDIzNDQ4LCAyMzQ1OCwgMjM0NjgsIDIzNDc4LCAyMzQ4OCwgMjM0OTgsIDIzNTA4LAorMjM1MTgsIDIzNTI4LCAyMzUzOCwgMjM1NTMsIDIzNTYzLCAyMzU3MywgMjM1ODMsIDIzNTk0LCAyMzYwNywgMjM2MTcsIDIzNjI3LCAyMzYzNywgMjM2NDgsIDIzNjU4LCAyMzY2OCwgMjM2NzgsCisyMzY4OCwgMjM2OTgsIDIzNzA5LCAyMzcxOSwgMjM3MjksIDIzNzUwLCAyMzc2MCwgMjM3NzAsIDIzNzg0LCAyMzc5NiwgMjM4MDcsIDIzODE5LCAyMzgzMCwgMjM4NDAsIDIzODU0LCAyMzg2NCwKKzIzODc0LCAyMzg4NCwgMjM4OTcsIDIzOTA3LCAyMzkxOSwgMjM5MjksIDIzOTQwLCAyMzk1NCwgMjM5NjQsIDIzOTc1LCAyMzk4NSwgMjM5OTYsIDI0MDA2LCAyNDAxNywgMjQwMjksIDI0MDM5LAorMjQwNDksIDI0MDYxLCAyNDA3NCwgMjQwODQsIDI0MDk1LCAyNDEwNSwgMjQxMTUsIDI0MTI1LCAyNDEzOCwgMjQxNDgsIDI0MTU5LCAyNDE2OSwgMjQxNzksIDI0MTg5LCAyNDE5OSwgMjQyMTMsCisyNDIyNCwgMjQyMzQsIDI0MjQ0LCAyNDI1NCwgMjQyNjQsIDI0Mjc0LCAyNDI4NCwgMjQyOTQsIDI0MzA1LCAyNDMxOCwgMjQzMjgsIDI0MzM4LCAyNDM0OSwgMjQzNTksIDI0MzY5LCAyNDM4MCwKKzI0MzkwLCAyNDQwNCwgMjQ0MTgsIDI0NDI4LCAyNDQzOCwgMjQ0NDgsIDI0NDU4LCAyNDQ3MCwgMjQ0ODAsIDI0NDkwLCAyNDUwMSwgMjQ1MTEsIDI0NTIxLCAyNDUzMiwgMjQ1NDIsIDI0NTUyLAorMjQ1NjMsIDI0NTczLCAyNDU4NSwgMjQ1OTUsIDI0NjA1LCAyNDYxNSwgMjQ2MjYsIDI0NjQwLCAyNDY1MiwgMjQ2NjQsIDI0Njc0LCAyNDY4NCwgMjQ3MDMsIDI0NzEzLCAyNDcyNCwgMjQ3MzUsCisyNDc1MiwgMjQ3NjIsIDI0NzcyLCAyNDc4MiwgMjQ3OTIsIDI0ODAyLCAyNDgxNiwgMjQ4MjYsIDI0ODM2LCAyNDg0NiwgMjQ4NTYsIDI0ODY3LCAyNDg3OCwgMjQ4OTEsIDI0OTAxLCAyNDkxMSwKKzI0OTIyLCAyNDkzMywgMjQ5NDQsIDI0OTU0LCAyNDk2OSwgMjQ5NzksIDI0OTg5LCAyNDk5OSwgMjUwMDksIDI1MDIwLCAyNTAzMCwgMjUwNDYsIDI1MDU2LCAyNTA2NiwgMjUwNzcsIDI1MDg3LAorMjUwOTcsIDI1MTA4LCAyNTExOSwgMjUxMjksIDI1MTM5LCAyNTE0OSwgMjUxNTksIDI1MTY5LCAyNTE3OSwgMjUxODksIDI1MTk5LCAyNTIwOSwgMjUyMTksIDI1MjMwLCAyNTI0MCwgMjUyNTYsCisyNTI2NywgMjUyNzcsIDI1Mjg3LCAyNTI5NywgMjUzMDcsIDI1MzIzLCAyNTMzMywgMjUzNDMsIDI1MzUzLCAyNTM2MywgMjUzODQsIDI1Mzk0LCAyNTQwNCwgMjU0MTQsIDI1NDI0LCAyNTQzNCwKKzI1NDQ1LCAyNTQ1NSwgMjU0NjYsIDI1NDc2LCAyNTQ4NiwgMjU0OTYsIDI1NTA2LCAyNTUxNiwgMjU1MzMsIDI1NTQzLCAyNTU1NCwgMjU1NjQsIDI1NTc1LCAyNTU4NSwgMjU2MDYsIDI1NjE2LAorMjU2MjYsIDI1NjM2LCAyNTY0NiwgMjU2NTcsIDI1NjY3LCAyNTY3NywgMjU2ODgsIDI1NzAxLCAyNTcxMSwgMjU3MjEsIDI1NzMzLCAyNTc0MywgMjU3NTMsIDI1NzYzLCAyNTc3MywgMjU3ODcsCisyNTc5NywgMjU4MDcsIDI1ODE3LCAyNTgyNywgMjU4MzcsIDI1ODQ3LCAyNTg1NywgMjU4NjgsIDI1ODc4LCAyNTg4OCwgMjU4OTgsIDI1OTEwLCAyNTkyMSwgMjU5MzUsIDI1OTQ1LCAyNTk1NSwKKzI1OTY3LCAyNTk3NywgMjU5ODcsIDI2MDAwLCAyNjAxMSwgMjYwMjEsIDI2MDMxLCAyNjA0MSwgMjYwNTEsIDI2MDYxLCAyNjA3MSwgMjYwODEsIDI2MDkyLCAyNjEwNiwgMjYxMTYsIDI2MTI2LAorMjYxNDAsIDI2MTUwLCAyNjE2MSwgMjYxNzcsIDI2MTg4LCAyNjIwMSwgMjYyMTIsIDI2MjIyLCAyNjIzMiwgMjYyNDQsIDI2MjU2LCAyNjI2OSwgMjYyODAsIDI2MjkwLCAyNjMwMSwgMjYzMTEsCisyNjMyMiwgMjYzMzIsIDI2MzQyLCAyNjM1MiwgMjYzNjQsIDI2Mzc2LCAyNjM4NiwgMjYzOTcsIDI2NDA3LCAyNjQxNywgMjY0MjcsIDI2NDM3LCAyNjQ0NywgMjY0NTcsIDI2NDc0LCAyNjQ4NCwKKzI2NDk0LCAyNjUwNSwgMjY1MTUsIDI2NTI1LCAyNjU0MiwgMjY1NTIsIDI2NTYyLCAyNjU3MiwgMjY1ODQsIDI2NTk0LCAyNjYwNCwgMjY2MTQsIDI2NjQyLCAyNjY1MiwgMjY2NjIsIDI2NjczLAorMjY2ODMsIDI2NjkzLCAyNjcwMywgMjY3MzEsIDI2NzQxLCAyNjc1MSwgMjY3NjEsIDI2NzcxLCAyNjc4MSwgMjY3OTEsIDI2ODAxLCAyNjgyMCwgMjY4MzAsIDI2ODQwLCAyNjg1MSwgMjY4NjIsCisyNjg3MiwgMjY4ODQsIDI2ODk0LCAyNjkxNywgMjY5MjcsIDI2OTM3LCAyNjk0OCwgMjY5NTgsIDI2OTY4LCAyNjk3OCwgMjY5ODgsIDI2OTk4LCAyNzAxMCwgMjcwMjEsIDI3MDMxLCAyNzA0MSwKKzI3MDUxLCAyNzA2MSwgMjcwNzEsIDI3MDgxLCAyNzA5MSwgMjcxMDYsIDI3MTE2LCAyNzEyNiwgMjcxMzYsIDI3MTQ2LCAyNzE1NiwgMjcxNjYsIDI3MTc2LCAyNzE4NiwgMjcxOTYsIDI3MjA2LAorMjcyMTYsIDI3MjI2LCAyNzIzNiwgMjcyNDcsIDI3MjYyLCAyNzI3MywgMjcyODMsIDI3Mjk0LCAyNzMwNCwgMjczMTUsIDI3MzI1LCAyNzMzNSwgMjczNDUsIDI3MzU1LCAyNzM2NSwgMjczNzUsCisyNzM4NSwgMjczOTUsIDI3NDA3LCAyNzQxNywgMjc0MjcsIDI3NDM3LCAyNzQ0NywgMjc0NTcsIDI3NDY3LCAyNzQ3NywgMjc0ODcsIDI3NDk4LCAyNzUxMCwgMjc1MjAsIDI3NTMwLCAyNzU0MCwKKzI3NTUwLCAyNzU2MiwgMjc1NzMsIDI3NTgzLCAyNzU5MywgMjc2MDMsIDI3NjE0LCAyNzYyNCwgMjc2MzQsIDI3NjQ0LCAyNzY1NCwgMjc2NjQsIDI3Njc0LCAyNzY4NCwgMjc2OTQsIDI3NzA0LAorMjc3MTQsIDI3NzI0LCAyNzczNSwgMjc3NDUsIDI3NzU1LCAyNzc2NiwgMjc3NzYsIDI3Nzg2LCAyNzc5NiwgMjc4MTksIDI3ODMwLCAyNzg0MCwgMjc4NTAsIDI3ODYwLCAyNzg3MCwgMjc4ODAsCisyNzg5MCwgMjc5MDQsIDI3OTE0LCAyNzkyNiwgMjc5MzYsIDI3OTQ2LCAyNzk1NiwgMjc5NjYsIDI3OTkyLCAyODAwMiwgMjgwMTIsIDI4MDIyLCAyODAzMiwgMjgwNDIsIDI4MDUyLCAyODA3NCwKKzI4MDg0LCAyODA5NCwgMjgxMDQsIDI4MTE0LCAyODEyNCwgMjgxMzQsIDI4MTQ0LCAyODE1NCwgMjgxNjUsIDI4MTg1LCAyODE5NSwgMjgyMDUsIDI4MjE2LCAyODIyNywgMjgyMzcsIDI4MjQ4LAorMjgyNTgsIDI4MjcwLCAyODI4MCwgMjgyOTYsIDI4MzA2LCAyODMxNiwgMjgzMjYsIDI4MzM2LCAyODM0NiwgMjgzNTYsIDI4MzY2LCAyODM3NiwgMjgzOTUsIDI4NDA1LCAyODQxNSwgMjg0MjUsCisyODQzNSwgMjg0NDYsIDI4NDU3LCAyODQ2NywgMjg0NzgsIDI4NDk0LCAyODUwNCwgMjg1MTQsIDI4NTI0LCAyODUzNCwgMjg1NDQsIDI4NTU1LCAyODU2NSwgMjg1NzYsIDI4NTg2LCAyODU5NiwKKzI4NjA3LCAyODYxNywgMjg2MjgsIDI4NjM4LCAyODY0OCwgMjg2NTgsIDI4NjY4LCAyODY3OCwgMjg2ODksIDI4Njk5LCAyODcxMCwgMjg3MjAsIDI4NzMwLCAyODc0MCwgMjg3NTMsIDI4NzYzLAorMjg3NzMsIDI4Nzg0LCAyODc5NCwgMjg4MDQsIDI4ODE0LCAyODgyNCwgMjg4MzYsIDI4ODQ2LCAyODg1NiwgMjg4NjksIDI4ODc5LCAyODg4OSwgMjg5MDAsIDI4OTExLCAyODkyMSwgMjg5MzIsCisyODk0MiwgMjg5NTMsIDI4OTYzLCAyODk3NCwgMjg5ODYsIDI4OTk2LCAyOTAwNiwgMjkwMTYsIDI5MDI2LCAyOTAzNiwgMjkwNDgsIDI5MDU4LCAyOTA3MSwgMjkwODEsIDI5MDkyLCAyOTEwMywKKzI5MTEzLCAyOTEyMywgMjkxMzQsIDI5MTQ0LCAyOTE1NCwgMjkxNjQsIDI5MTc2LCAyOTE4NiwgMjkxOTYsIDI5MjA5LCAyOTIxOSwgMjkyMjksIDI5MjQwLCAyOTI1MCwgMjkyNjAsIDI5MjcwLAorMjkyODAsIDI5MjkwLCAyOTMwMCwgMjkzMTAsIDI5MzIwLCAyOTMzMCwgMjkzNDEsIDI5MzUxLCAyOTM2NCwgMjkzNzUsIDI5Mzg1LCAyOTM5NiwgMjk0MDcsIDI5NDE3LCAyOTQyNywgMjk0MzcsCisyOTQ0NywgMjk0NTcsIDI5NDY3LCAyOTQ3NywgMjk0ODgsIDI5NDk4LCAyOTUwOCwgMjk1MTgsIDI5NTI4LCAyOTUzOCwgMjk1NDgsIDI5NTU4LCAyOTU2OCwgMjk1NzgsIDI5NTg4LCAyOTU5OSwKKzI5NjA5LCAyOTYxOSwgMjk2MzAsIDI5NjQwLCAyOTY1MCwgMjk2NjAsIDI5NjcxLCAyOTY4NCwgMjk2OTQsIDI5NzA0LCAyOTcxOCwgMjk3MjgsIDI5NzM4LCAyOTc0OCwgMjk3NTksIDI5NzcwLAorMjk3ODAsIDI5NzkwLCAyOTgwMSwgMjk4MTEsIDI5ODIxLCAyOTgzMSwgMjk4NDIsIDI5ODUyLCAyOTg2MiwgMjk4NzIsIDI5ODgyLCAyOTg5MywgMjk5MDMsIDI5OTEzLCAyOTkyMywgMjk5MzQsCisyOTk0NywgMjk5NTksIDI5OTY5LCAyOTk4MCwgMjk5OTAsIDMwMDAwLCAzMDAxMCwgMzAwMjMsIDMwMDM2LCAzMDA0NywgMzAwNTgsIDMwMDcwLCAzMDA4MCwgMzAwOTAsIDMwMTAwLCAzMDExNCwKKzMwMTI4LCAzMDEzOCwgMzAxNDgsIDMwMTU4LCAzMDE2OCwgMzAxNzgsIDMwMTg5LCAzMDE5OSwgMzAyMDksIDMwMjE5LCAzMDIyOSwgMzAyMzksIDMwMjQ5LCAzMDI1OSwgMzAyNjksIDMwMjc5LAorMzAyOTAsIDMwMzAwLCAzMDMxMywgMzAzMjUsIDMwMzM1LCAzMDM0NSwgMzAzNTUsIDMwMzY1LCAzMDM3OCwgMzAzODgsIDMwMzk4LCAzMDQwOCwgMzA0MTgsIDMwNDI4LCAzMDQzOCwgMzA0NDgsCiszMDQ1OCwgMzA0NjgsIDMwNDgwLCAzMDQ5MCwgMzA1MDEsIDMwNTExLCAzMDUyMSwgMzA1MzIsIDMwNTQyLCAzMDU1MywgMzA1NjMsIDMwNTczLCAzMDU4NSwgMzA1OTUsIDMwNjA1LCAzMDYxNSwKKzMwNjI1LCAzMDYzNSwgMzA2NDUsIDMwNjU1LCAzMDY2NSwgMzA2NzUsIDMwNjg2LCAzMDY5NiwgMzA3MDYsIDMwNzE2LCAzMDcyNiwgMzA3MzYsIDMwNzQ5LCAzMDc1OSwgMzA3NjksIDMwNzg3LAorMzA3OTcsIDMwODEyLCAzMDgyNCwgMzA4NDEsIDMwODUxLCAzMDg2MiwgMzA4NzIsIDMwODgyLCAzMDg5MiwgMzA5MDYsIDMwOTE2LCAzMDkyNiwgMzA5MzgsIDMwOTQ5LCAzMDk1OSwgMzA5NjksCiszMDk4MCwgMzA5OTAsIDMxMDAxLCAzMTAxMSwgMzEwMjEsIDMxMDMyLCAzMTA0MiwgMzEwNTIsIDMxMDYyLCAzMTA3MiwgMzEwODIsIDMxMDkyLCAzMTEwMywgMzExMTQsIDMxMTI0LCAzMTEzNiwKKzMxMTQ2LCAzMTE1NiwgMzExNjYsIDMxMTc2LCAzMTE4NiwgMzExOTYsIDMxMjA2LCAzMTIyMiwgMzEyMzIsIDMxMjQyLCAzMTI1MiwgMzEyNjIsIDMxMjcyLCAzMTI4NywgMzEzMDAsIDMxMzEwLAorMzEzMjAsIDMxMzMwLCAzMTM0MCwgMzEzNTAsIDMxMzYwLCAzMTM3MCwgMzEzODAsIDMxMzkwLCAzMTQwMCwgMzE0MTAsIDMxNDIyLCAzMTQzNCwgMzE0NDgsIDMxNDU5LCAzMTQ2OSwgMzE0NzksCiszMTQ4OSwgMzE1MDIsIDMxNTEyLCAzMTUyMiwgMzE1MzIsIDMxNTQ0LCAzMTU1NiwgMzE1NjYsIDMxNTc2LCAzMTU4NywgMzE1OTcsIDMxNjA3LCAzMTYxOCwgMzE2MjgsIDMxNjM4LCAzMTY0OCwKKzMxNjYwLCAzMTY3MSwgMzE2ODEsIDMxNjkxLCAzMTcwMSwgMzE3MTEsIDMxNzIxLCAzMTczMSwgMzE3NDEsIDMxNzUxLCAzMTc2MSwgMzE3NzIsIDMxNzgyLCAzMTc5MiwgMzE4MDMsIDMxODEzLAorMzE4MjQsIDMxODM0LCAzMTg0NCwgMzE4NTQsIDMxODY0LCAzMTg3NiwgMzE4ODksIDMxOTAyLCAzMTkxMiwgMzE5MjIsIDMxOTMyLCAzMTk0NCwgMzE5NTQsIDMxOTY0LCAzMTk3NSwgMzE5ODUsCiszMTk5NSwgMzIwMDUsIDMyMDE1LCAzMjAyNSwgMzIwNDAsIDMyMDUwLCAzMjA2MCwgMzIwNzAsIDMyMDgwLCAzMjA5MSwgMzIxMDIsIDMyMTEyLCAzMjEyMiwgMzIxMzIsIDMyMTQyLCAzMjE1NiwKKzMyMTY2LCAzMjE3NiwgMzIxODYsIDMyMTk2LCAzMjIwNiwgMzIyMTYsIDMyMjI3LCAzMjIzOCwgMzIyNDksIDMyMjU5LCAzMjI2OSwgMzIyNzksIDMyMjg5LCAzMjI5OSwgMzIzMDksIDMyMzE5LAorMzIzMjksIDMyMzM5LCAzMjM1MCwgMzIzNjAsIDMyMzcwLCAzMjM4MCwgMzIzOTAsIDMyNDAxLCAzMjQxMSwgMzI1NjYsIDMyNTc5LCAzMjU4OSwgMzI2MDAsIDMyNjExLCAzMjYyMSwgMzI2MzEsCiszMjY0MywgMzI2NTMsIDMyNjY2LCAzMjY3NiwgMzI2ODcsIDMyNjk3LCAzMjcwNywgMzI3MTcsIDMyNzI3LCAzMjczNywgMzI3NDcsIDMyNzU3LCAzMjc2NywgMzI3NzksIDMyNzg5LCAzMjc5OSwKKzMyODA5LCAzMjgxOSwgMzI4MjksIDMyODM5LCAzMjg0OSwgMzI4NjAsIDMyODcxLCAzMjg4MSwgMzI4OTMsIDMyOTAzLCAzMjkxNCwgMzI5MjQsIDMyOTM3LCAzMjk0OCwgMzI5NjIsIDMyOTcyLAorMzI5ODIsIDMyOTkyLCAzMzAwNSwgMzMwMTYsIDMzMDI2LCAzMzA0NSwgMzMwNTUsIDMzMDY1LCAzMzA4MSwgMzMwOTEsIDMzMTAxLCAzMzExNSwgMzMxMjUsIDMzMTM1LCAzMzE0NSwgMzMxNTUsCiszMzE2NSwgMzMxNzUsIDMzMTg2LCAzMzE5NiwgMzMyMDcsIDMzMjE4LCAzMzIyOCwgMzMyMzksIDMzMjQ5LCAzMzI2MCwgMzMyNzEsIDMzMjgxLCAzMzI5MSwgMzMzMDEsIDMzMzExLCAzMzMyMiwKKzMzMzMyLCAzMzM0MywgMzMzNTMsIDMzMzYzLCAzMzM3NCwgMzMzODQsIDMzMzk0LCAzMzQwNCwgMzM0MTgsIDMzNDI4LCAzMzQzOCwgMzM0NDgsIDMzNDU5LCAzMzQ2OSwgMzM0ODksIDMzNDk5LAorMzM1MDksIDMzNTE5LCAzMzUyOSwgMzM1MzksIDMzNTQ5LCAzMzU1OSwgMzM1NzAsIDMzNTgwLCAzMzU5MCwgMzM2MDAsIDMzNjEwLCAzMzYyMCwgMzM2NTEsIDMzNjYxLCAzMzY3MSwgMzM2ODIsCiszMzY5MywgMzM3MDMsIDMzNzI1LCAzMzczNSwgMzM3NDUsIDMzNzU1LCAzMzc2NSwgMzM3NzUsIDMzNzg1LCAzMzc5NSwgMzM4MDUsIDMzODE5LCAzMzgzMywgMzM4NDMsIDMzODUzLCAzMzg2MywKKzMzODczLCAzMzg4MywgMzM4OTMsIDMzOTAzLCAzMzkxMywgMzM5MjYsIDMzOTM2LCAzMzk0NiwgMzM5NTYsIDMzOTY2LCAzMzk3NiwgMzM5ODYsIDMzOTk2LCAzNDAwNiwgMzQwMjMsIDM0MDMzLAorMzQwNDMsIDM0MDU0LCAzNDA2NSwgMzQwNzYsIDM0MDg2LCAzNDA5NiwgMzQxMDcsIDM0MTE3LCAzNDEyOSwgMzQxMzksIDM0MTQ5LCAzNDE2MSwgMzQxNzEsIDM0MTgxLCAzNDE5MSwgMzQyMDEsCiszNDIxMSwgMzQyMjMsIDM0MjMzLCAzNDI0MywgMzQyNTMsIDM0MjYzLCAzNDI3MywgMzQyODMsIDM0Mjk0LCAzNDMwNCwgMzQzMTQsIDM0MzI3LCAzNDMzNywgMzQzNDgsIDM0MzU4LCAzNDM2OCwKKzM0Mzc5LCAzNDM4OSwgMzQzOTksIDM0NDA5LCAzNDQxOSwgMzQ0MzcsIDM0NDQ4LCAzNDQ1OCwgMzQ0NjgsIDM0NDc5LCAzNDQ4OSwgMzQ0OTksIDM0NTEyLCAzNDUyMiwgMzQ1MzIsIDM0NTQ5LAorMzQ1NjAsIDM0NTcwLCAzNDU4NCwgMzQ1OTQsIDM0NjA0LCAzNDYxNSwgMzQ2MjUsIDM0NjM2LCAzNDY0NiwgMzQ2NTYsIDM0NjY2LCAzNDY3NiwgMzQ2ODksIDM0NzAxLCAzNDcxMSwgMzQ3MjIsCiszNDczMiwgMzQ3NDIsIDM0NzUyLCAzNDc2MiwgMzQ3NzIsIDM0NzgyLCAzNDc5MiwgMzQ4MDIsIDM0ODEyLCAzNDgyMiwgMzQ4MzIsIDM0ODQzLCAzNDg1MywgMzQ4NjMsIDM0ODczLCAzNDg4MywKKzM0ODkzLCAzNDkwMywgMzQ5MTMsIDM0OTIzLCAzNDkzMywgMzQ5NDMsIDM0OTUzLCAzNDk2MywgMzQ5NzQsIDM0OTg0LCAzNDk5NCwgMzUwMDQsIDM1MDE3LCAzNTAyOCwgMzUwMzgsIDM1MDQ4LAorMzUwNTgsIDM1MDY4LCAzNTA3OCwgMzUwODgsIDM1MDk4LCAzNTEwOSwgMzUxMTksIDM1MTMxLCAzNTE0MiwgMzUxNTIsIDM1MTYyLCAzNTE3MiwgMzUxODIsIDM1MTkzLCAzNTIwMywgMzUyMTUsCiszNTIyNywgMzUyMzgsIDM1MjUwLCAzNTI2MSwgMzUyODIsIDM1MjkyLCAzNTMwMiwgMzUzMTIsIDM1MzIyLCAzNTMzMiwgMzUzNDIsIDM1MzUyLCAzNTM2MiwgMzUzNzIsIDM1MzgyLCAzNTM5MiwKKzM1NDAyLCAzNTQxMiwgMzU0MjIsIDM1NDMyLCAzNTQ0MiwgMzU0NTIsIDM1NDYyLCAzNTQ3MywgMzU0ODYsIDM1NDk2LCAzNTUwNiwgMzU1MTYsIDM1NTI2LCAzNTUzNywgMzU1NDcsIDM1NTU4LAorMzU1NjgsIDM1NTc4LCAzNTU4OCwgMzU1OTgsIDM1NjA4LCAzNTYxOCwgMzU2MjgsIDM1NjM4LCAzNTY0OCwgMzU2NTgsIDM1NjY4LCAzNTY3OSwgMzU2OTAsIDM1NzAwLCAzNTcxMCwgMzU3MjAsCiszNTczMCwgMzU3NDAsIDM1ODk1LCAzNTkwNSwgMzU5MTUsIDM1OTI1LCAzNTkzNSwgMzU5NDUsIDM1OTU1LCAzNTk2NSwgMzU5NzcsIDM1OTg3LCAzNTk5NywgMzYwMDcsIDM2MDE4LCAzNjAyOCwKKzM2MDM5LCAzNjA0OSwgMzYwNjAsIDM2MDcwLCAzNjA4MCwgMzYwOTAsIDM2MTAwLCAzNjExMSwgMzYxMjEsIDM2MTk2LCAzNjIwNiwgMzYyMTYsIDM2MjI4LCAzNjIzOCwgMzYyNDksIDM2MjU5LAorMzYyNjksIDM2Mjc5LCAzNjI4OSwgMzYyOTksIDM2MzA5LCAzNjMxOSwgMzYzMjksIDM2MzM5LCAzNjM0OSwgMzYzNTksIDM2MzY5LCAzNjM3OSwgMzYzODksIDM2NDAwLCAzNjQxMiwgMzY0MjMsCiszNjQzNSwgMzY0NDUsIDM2NDU1LCAzNjQ2NiwgMzY0NzYsIDM2NDg2LCAzNjQ5NiwgMzY1MDYsIDM2NTE2LCAzNjUzMCwgMzY1NDEsIDM2NTUzLCAzNjU2MywgMzY1NzMsIDM2NTgzLCAzNjU5MywKKzM2NjAzLCAzNjYxMywgMzY2MjQsIDM2NjM0LCAzNjY0NCwgMzY2NTQsIDM2NjY0LCAzNjY3NCwgMzY2ODUsIDM2Njk1LCAzNjcwNSwgMzY3NjMsIDM2Nzc0LCAzNjc4NCwgMzY3OTksIDM2ODA5LAorMzY4MTksIDM2ODMyLCAzNjg0MiwgMzY4NTIsIDM2ODYyLCAzNjg3NSwgMzY4ODUsIDM2ODk1LCAzNjkwOSwgMzY5MjAsIDM2OTMwLCAzNjk0MSwgMzY5NTIsIDM2OTYyLCAzNjk3MywgMzY5ODMsCiszNjk5MywgMzcwMDMsIDM3MDEzLCAzNzAyMywgMzcwMzQsIDM3MDQ0LCAzNzA1NCwgMzcwNjQsIDM3MDc2LCAzNzA4NywgMzcwOTcsIDM3MTA3LCAzNzExNywgMzcxMjcsIDM3MTM3LCAzNzE0NywKKzM3MTU4LCAzNzE2OCwgMzcxNzgsIDM3MTg4LCAzNzE5OCwgMzcyMDgsIDM3MjE4LCAzNzIyOCwgMzcyMzksIDM3MjQ5LCAzNzI1OSwgMzcyNzMsIDM3MjgzLCAzNzI5MywgMzczMDMsIDM3MzEzLAorMzczMjMsIDM3MzMzLCAzNzM0NiwgMzczNTYsIDM3MzY3LCAzNzM3NywgMzczODgsIDM3Mzk4LCAzNzQxMSwgMzc0MjEsIDM3NDMxLCAzNzQ0NSwgMzc0NTUsIDM3NDY2LCAzNzQ3NiwgMzc0ODcsCiszNzQ5NywgMzc1MDcsIDM3NTE3LCAzNzUyNywgMzc1MzcsIDM3NTQ3LCAzNzU1NywgMzc1NjgsIDM3NTc4LCAzNzU4OSwgMzc1OTksIDM3NjA5LCAzNzYyMywgMzc2MzMsIDM3NjQzLCAzNzY1MywKKzM3NjYzLCAzNzY3MywgMzc2ODMsIDM3NzAyLCAzNzcxMiwgMzc3MjIsIDM3NzMyLCAzNzc0NCwgMzc3NTQsIDM3NzY4LCAzNzc3OCwgMzc3ODksIDM3Nzk5LCAzNzgwOSwgMzc4MjQsIDM3ODM0LAorMzc4NDQsIDM3ODU0LCAzNzg2NCwgMzc4NzcsIDM3ODg3LCAzNzg5NywgMzc5MDcsIDM3OTIwLCAzNzkzMCwgMzc5NDEsIDM3OTUxLCAzNzk2MSwgMzc5NzMsIDM3OTg0LCAzNzk5NCwgMzgwMDQsCiszODAxNCwgMzgyNjMsIDM4Mjc0LCAzODI4NCwgMzgyOTYsIDM4MzA3LCAzODMxNywgMzgzMjcsIDM4MzM5LCAzODM0OSwgMzgzNjIsIDM4MzcyLCAzODQyOCwgMzg0NDAsIDM4NDUwLCAzODQ2MCwKKzM4NDc0LCAzODQ4NCwgMzg0OTQsIDM4NTA2LCAzODUxNiwgMzg1MjYsIDM4NTM2LCAzODU0NiwgMzg1NTYsIDM4NTY3LCAzODU3NywgMzg1ODcsIDM4NTk3LCAzODYxMCwgMzg2MjAsIDM4NjMyLAorMzg2NDIsIDM4NjUzLCAzODY2MywgMzg2NzMsIDM4Njg0LCAzODY5NCwgMzg3MDQsIDM4NzE0LCAzODcyNCwgMzg3MzgsIDM4NzQ4LCAzODc1OCwgMzg3NjgsIDM4Nzc4LCAzODc4OCwgMzg3OTgsCiszODgwOCwgMzg4MTgsIDM4ODI4LCAzODgzOCwgMzg4NDksIDM4ODU5LCAzODg2OSwgMzg4NzksIDM4ODkzLCAzODkwNCwgMzg5MTQsIDM4OTI0LCAzODkzNCwgMzg5NDQsIDM4OTU1LCAzODk2NSwKKzM4OTc3LCAzODk4OCwgMzg5OTksIDM5MDEwLCAzOTAyMywgMzkwODAsIDM5MDkwLCAzOTEwMCwgMzkxMTAsIDM5MTMxLCAzOTE0MSwgMzkxNTEsIDM5MTYxLCAzOTE3MSwgMzkxODQsIDM5MTk0LAorMzkyMDQsIDM5MjE0LCAzOTIyNiwgMzkyMzcsIDM5MjQ4LCAzOTI1OSwgMzkzMTgsIDM5MzI5LCAzOTMzOSwgMzkzNDksIDM5MzYxLCAzOTM3MSwgMzkzODEsIDM5MzkxLCAzOTQwMSwgMzk0MTIsCiszOTQyMiwgMzk0MzMsIDM5NDQ0LCAzOTQ1NCwgMzk0NjUsIDM5NDc2LCAzOTQ4NiwgMzk0OTYsIDM5NTA2LCAzOTUxOCwgMzk1MjgsIDM5NTkyLCAzOTYwMywgMzk2MTQsIDM5NjI2LCAzOTYzNiwKKzM5NjQ3LCAzOTY1OSwgMzk2NzAsIDM5NjgxLCAzOTY5MSwgMzk3MDEsIDM5NzExLCAzOTcyMSwgMzk3MzEsIDM5NzQyLCAzOTc1MiwgMzk3NjIsIDM5Nzc1LCAzOTc4OCwgMzk3OTgsIDM5ODA4LAorMzk4MjQsIDM5ODM0LCAzOTg0NCwgMzk4NTQsIDM5ODY0LCAzOTg3NSwgMzk4OTEsIDM5OTAyLCAzOTkxMiwgMzk5MjcsIDM5OTQxLCAzOTk1NCwgMzk5NjQsIDM5OTc2LCAzOTk4NiwgMzk5OTYsCis0MDAwNiwgNDAwMTYsIDQwMDMwLCA0MDA0MCwgNDAwNTEsIDQwMTY1LCA0MDE3NywgNDAxODcsIDQwMTk3LCA0MDIwOCwgNDAyMTksIDQwMjI5LCA0MDIzOSwgNDAyNTEsIDQwMjYxLCA0MDI3MSwKKzQwMjgxLCA0MDI5NSwgNDAzMDUsIDQwMzE1LCA0MDMyNSwgNDAzMzYsIDQwMzQ2LCA0MDM1NiwgNDAzNjcsIDQwMzc3LCA0MDM4NywgNDAzOTcsIDQwNDA3LCA0MDQxNywgNDA0MjcsIDQwNDM3LAorNDA0NDcsIDQwNDU3LCA0MDQ2NywgNDA0NzcsIDQwNTY1LCA0MDU3NSwgNDA1ODUsIDQwNTk1LCA0MDYwNSwgNDA2MTUsIDQwNjI4LCA0MDYzOCwgNDA2NDgsIDQwNjU5LCA0MDY2OSwgNDA2NzksCis0MDY5MCwgNDA3MDAsIDQwNzEwLCA0MDcyMCwgNDA3MzAsIDQwNzQwLCA0MDc1MCwgNDA3NjAsIDQwNzcwLCA0MDc4MCwgNDA3OTAsIDQwODAwLCA0MDgxMCwgNDA4MjAsIDQwODMwLCA0MDg0NSwKKzQwODU2LCA0MDg2NiwgNjQwMTIsIDY1MDcyLCA2NTA4MiwgNjUwOTIsIDY1MTAyLCA2NTExMywgNjUxMjMsIDY1MjgxLCA2NTI5MSwgNjUzMDEsIDY1MzExLCA2NTMyMSwgNjUzMzEsIDY1MzQzLAorNjUzNTMsIDY1MzYzLCA2NTM3MywgNjU1MzYKKyAgICAgICAgICAgIH0pOworCisgICAgICAgIHRlc3RCeXRlcyA9IHRoZXNlQnl0ZXMobmV3IGludFtdeworMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKzE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCis0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKzY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCis5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKzExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKzE2MiwgNzAsIDE2MiwgNzEsIDE2MiwgNjgsIDE2MSwgMTc3LCAxNjIsIDg4LCAxNjEsIDIxMSwgMTYxLCA4MCwgMTYxLCAyMDksCisxNjEsIDIxMCwgMTYzLCAxOTAsIDE2MywgMTg4LCAxNjMsIDE4NywgMTYzLCA2OCwgMTYzLCA3OCwgMTYzLCA4NywgMTYzLCA5MiwKKzE2MywgMTAyLCAxNjMsIDExMSwgMTk5LCAxNzksIDE5OSwgMTc3LCAxOTksIDE4NywgMTk5LCAxOTcsIDE5OSwgMjA4LCAxOTksIDIxOCwKKzE5OSwgMjI4LCAxNjEsIDg2LCAxNjEsIDE2OCwgMTYxLCAxNzIsIDE2MSwgMTk0LCAxNjIsIDc0LCAxNjIsIDE4NSwgMTYxLCAyNDYsCisxNjEsIDIxMiwgMTYxLCAyNTIsIDE2MSwgMjM5LCAxNjEsIDIyMCwgMTYxLCAyMTgsIDE2MSwgMjMwLCAxNjEsIDIzMywgMTk5LCAyMzMsCisxOTksIDI0MywgMTYyLCAxMTksIDE2MiwgMTIyLCAxNjIsIDEyNSwgMTYyLCAxMTYsIDE2MiwgMTE0LCAxNjIsIDE2NCwgMTYyLCAxNjUsCisxNjIsIDE2NiwgMTYyLCA5OCwgMTYyLCAxMTAsIDE2MiwgMTIxLCAxNjEsIDE4OSwgMTYxLCAxODIsIDE2MSwgMTkxLCAxNjEsIDE4NywKKzE2MiwgMTY4LCAxNjEsIDE4NSwgMTYxLCAyNDAsIDE2MSwgNjQsIDE2MSwgMTA5LCAxNjEsIDEwMSwgMTYxLCAxNzAsIDE2MiwgMjAyLAorMTk4LCAxNjUsIDE5OCwgMTc1LCAxOTgsIDE4NSwgMTk4LCAxOTUsIDE5OCwgMjA1LCAxOTgsIDIxNSwgMTk4LCAyMjUsIDE5OCwgMjM1LAorMTk4LCAyNDUsIDE5OCwgMTYyLCAxOTgsIDI1NCwgMTk5LCA3MywgMTk5LCA4MywgMTk5LCA5MywgMTk5LCAxMDMsIDE5OSwgMTEzLAorMTk5LCAxMjMsIDE5OSwgMTY3LCAxOTgsIDE2MSwgMTYzLCAxMTksIDE2MywgMTYzLCAxNjMsIDE3MywgMTYzLCAxODMsIDE2MSwgMTkyLAorMTYyLCA4NSwgMTYyLCA4MCwgMTYyLCA4NywgMTYyLCA4MywgMTY0LCA2NCwgMTY0LCA4NywgMTY1LCA2NiwgMTY1LCAyMjQsCisxNjQsIDg4LCAxNjQsIDg5LCAyMDEsIDY0LCAxNjUsIDY5LCAxNzMsIDE4OCwgMTY1LCAyMjgsIDE2OCwgMTk3LCAxNzYsIDE3NCwKKzE2NCwgMTY5LCAxNjQsIDE3MiwgMTY4LCAyMDAsIDE2NiwgMjM1LCAxNzMsIDE4OSwgMTY0LCAxNzYsIDE2NCwgMTgxLCAxNjUsIDc0LAorMTY1LCA4MSwgMjAxLCAxMDEsIDE2NSwgMjQyLCAxNjUsIDI0NywgMjAxLCAxNzksIDIwMSwgMTg3LCAyMDEsIDE4MCwgMjAxLCAxNzMsCisxNjcsIDY4LCAyMDIsIDEwMCwgMjAzLCAxODksIDIwMiwgOTAsIDE2NywgNjUsIDIwMywgMTkxLCAyMDMsIDE4NSwgMTY4LCAyMTksCisxNjgsIDIxNSwgMjAzLCAyMDAsIDIwMywgMTk3LCAxNzEsIDg2LCAyMDUsIDIzOCwgMTcxLCA4MCwgMjA1LCAyMjEsIDE3MSwgODUsCisxNzEsIDcyLCAyMDUsIDIzOSwgMjA4LCAyMTIsIDE3MywgMjA2LCAxNzMsIDIxMSwgMjEyLCA5MSwgMTczLCAyMDEsIDE3MywgMTk3LAorMjA4LCAyMDksIDIxMiwgOTksIDIxMiwgODksIDE3NiwgMTg2LCAyMTIsIDkzLCAyMTIsIDk0LCAyMTIsIDEwMSwgMTc2LCAxNzYsCisyMTYsIDk1LCAxNzksIDE5OSwgMjE2LCA4MSwgMTgyLCAyMDIsIDIyMCwgMTk1LCAyMjAsIDE5MCwgMjIwLCAxOTMsIDE4NSwgMTc4LAorMjI0LCAyNTQsIDIyNCwgMjQ2LCAxODcsIDI0OCwgMjI4LCAyMzAsIDE4NywgMjUyLCAyMzIsIDI0NSwgMTkyLCAxMTgsIDIzNiwgMTkwLAorMTk1LCA5NSwgMjQ3LCAyMDgsIDE2NSwgMjUxLCAxNjgsIDIyNCwgMTc2LCAxOTQsIDE2NCwgMTg2LCAxNjYsIDY0LCAxNzMsIDIyMSwKKzIwMSwgNzgsIDE3MSwgOTYsIDIwMywgMjA1LCAxOTAsIDE3MywgMTY3LCA3NywgMjA4LCAyMjYsIDIwOCwgMjI5LCAyMjUsIDY0LAorMTc2LCAxOTYsIDE2NSwgODgsIDE2NCwgMTkyLCAyMDEsIDE5MSwgMjAyLCAxMDgsIDE2NywgODMsIDIwMywgMjA5LCAxNjgsIDIzOSwKKzE3MSwgMTAzLCAyMDgsIDIzNSwgMjA4LCAyMzQsIDE3OSwgMjA5LCAxNzksIDIwNywgMTgyLCAyMDcsIDE4OCwgNjYsIDE5MCwgMTc2LAorMTY1LCA5MiwgMTY3LCA4NSwgMTY4LCAyNDEsIDE3MSwgMTA1LCAxNzYsIDE5OSwgMTc5LCAyMTEsIDIyNSwgNjcsIDE5MCwgMTc3LAorMTY0LCAxOTYsIDE2NiwgNzMsIDIxNiwgOTgsIDIwMSwgMTA4LCAxNzMsIDIzNCwgMjMyLCAyNTAsIDE3NiwgMjA4LCAxNjQsIDIwMCwKKzE2OCwgMjQyLCAxNjQsIDgyLCAxNjgsIDI0NiwgMTY2LCA3NiwgMTcxLCAxMTEsIDIwMSwgMTk2LCAyMDMsIDIxOCwgMjA4LCAyMzksCisyMjUsIDcwLCAyMDEsIDg4LCAxNzYsIDIwOSwgMTY0LCAyMDcsIDE2OCwgMjUyLCAyMzIsIDI1MSwgMTY1LCAxMTUsIDE2NSwgMTE0LAorMTY2LCA4MywgMTY2LCA4NCwgMjAyLCAxMjYsIDIwMiwgMTY1LCAxNjcsIDEwOSwgMTY3LCAxMDgsIDE2NywgMTAyLCAxNjcsIDk2LAorMjAzLCAyMzUsIDIwMywgMjI1LCAxNjgsIDI1NCwgMjAzLCAyMjAsIDE2OSwgODEsIDE2OSwgNjYsIDIwNiwgNzIsIDE3MSwgMTI1LAorMjA2LCA2OSwgMTcxLCAxMTUsIDE3MSwgMTE3LCAyMDYsIDc4LCAxNzMsIDIzOSwgMTczLCAyNDUsIDE3MywgMjQzLCAxNzMsIDI0NiwKKzE3MywgMjQwLCAyMDgsIDI0NywgMjA4LCAyNDAsIDIxMiwgMTI0LCAyMTIsIDE2OCwgMjEyLCAxMjYsIDE3NiwgMjIxLCAxNzYsIDIyNywKKzE3NiwgMjEzLCAyMTIsIDExMywgMjE2LCAxMjAsIDE3OSwgMjM5LCAyMTYsIDEwOSwgMTc5LCAyMjAsIDE3OSwgMjE3LCAxNzksIDIzNywKKzE3OSwgMjM1LCAxODIsIDIyOSwgMjIwLCAyMTYsIDIyMCwgMjIzLCAxODIsIDIyNCwgMTgyLCAyMjYsIDIyNSwgODUsIDIyNSwgODMsCisxODUsIDE5OSwgMTg1LCAxOTIsIDIyNSwgNzEsIDE4OCwgNzQsIDIyOSwgNjcsIDIyOCwgMjQ2LCAxODgsIDc4LCAyMzMsIDY5LAorMTkwLCAxODUsIDIzMywgNjgsIDIzNiwgMTk4LCAyMzYsIDE5MywgMjM5LCAxODgsIDE5NSwgOTYsIDI0MywgMjU0LCAxOTYsIDkwLAorMjQ2LCAyMTUsIDE5NywgMjQxLCAxNjUsIDEyNCwgMjAyLCAxNjksIDE2NywgMTIwLCAxNjksIDg0LCAxNzQsIDcwLCAxODIsIDIzMywKKzIzMywgNzEsIDE2NiwgOTgsIDE2NiwgOTYsIDE2NywgMTYzLCAyMDIsIDE3MywgMTY5LCA4OSwgMjAzLCAyNDUsIDIwMywgMjUwLAorMjAzLCAyNDksIDE3MSwgMTcyLCAyMDYsIDk0LCAyMDYsIDgyLCAxNzEsIDE3NywgMjA5LCA4MiwgMTc0LCA3MSwgMjA5LCA3NCwKKzIxMiwgMTc3LCAyMTIsIDE5NywgMjEyLCAyMDAsIDIxMiwgMTczLCAxNzYsIDIzNywgMjEyLCAxOTYsIDIxNiwgMTcwLCAyMTYsIDE2OCwKKzE3OSwgMjQzLCAyMTYsIDE3NSwgMjE2LCAxNjcsIDE4MiwgMjQ2LCAyMjAsIDIzNSwgMjIwLCAyMjcsIDIyNSwgOTMsIDE4NSwgMjA5LAorMjI1LCAxMDEsIDE4NSwgMjExLCAyMjksIDc1LCAxOTAsIDE2NSwgMTg4LCA4OCwgMjMzLCA3NCwgMTkwLCAxOTQsIDE5MiwgMTY0LAorMjQxLCAyNDgsIDI0NywgMjExLCAyMDYsIDk1LCAyMjUsIDEwNSwgMjA0LCA2NiwgMTY1LCAxMjYsIDE3NiwgMjQ3LCAxNjQsIDIxMSwKKzE2NiwgMTA1LCAxNjksIDk3LCAxNzEsIDE4MiwgMTc0LCA3OCwgMTc2LCAyNDgsIDE4OCwgOTMsIDIwMSwgMjA5LCAxNjYsIDExMywKKzE2NywgMTc2LCAyMDIsIDE4MSwgMjAyLCAxODcsIDE2OSwgMTAzLCAxNjksIDEwMiwgMjA0LCA3NywgMTY5LCAxMDcsIDE3MSwgMTg1LAorMTcxLCAxODcsIDIwNiwgMTE4LCAyMDYsIDExMCwgMTcxLCAxOTQsIDE3NCwgOTEsIDIwOSwgOTIsIDE3NCwgODcsIDIwOSwgOTMsCisyMTYsIDE5NCwgMTc2LCAyNTAsIDIxMiwgMjMxLCAyMTIsIDIzNiwgMjEyLCAyMDYsIDE3NiwgMjUzLCAxODAsIDY0LCAyMTYsIDE5OCwKKzIxMiwgMjI3LCAxODAsIDY1LCAyMTYsIDE5MCwgMjE2LCAxODEsIDIyMSwgNzAsIDIyMCwgMjQ0LCAyMjUsIDExMCwgMjI1LCAxMjQsCisxODUsIDIyNCwgMjI1LCAxMTUsIDIyOSwgODYsIDIyOSwgOTQsIDIzMywgODYsIDE5MCwgMTk3LCAyMzYsIDIxMSwgMjM2LCAyMDgsCisyMzksIDE5MywgMjQ1LCAyMDAsIDE2NCwgMTA5LCAxNjcsIDE4NCwgMjA0LCA4NiwgMTc3LCA2OSwgMTkyLCAxNjksIDIwMSwgMTE1LAorMjAyLCAxODgsIDE2OSwgMTIwLCAxNzEsIDIwMCwgMjA5LCAxMDQsIDE3NCwgOTcsIDIxMiwgMjQyLCAyMTYsIDIxMywgMjE2LCAyMTEsCisxODUsIDIzMCwgMTg1LCAyMzUsIDIzNiwgMjE3LCAxNzEsIDIwMiwgMTgwLCA3NywgMjAxLCAyMTIsIDIyMSwgNzUsIDIwMiwgMTkxLAorMTkyLCAxNzAsIDE2NywgMTkwLCAxNzEsIDIwNiwgMTc0LCAxMDUsIDE3NywgNzksIDIzOSwgMTk1LCAyMDEsIDExOCwgMjAxLCAyMTcsCisyMDIsIDE5NCwgMjAyLCAxOTcsIDIwNCwgMTA0LCAyMDQsIDEwMywgMTY5LCAxNjcsIDIwNiwgMTcxLCAyMDYsIDEyMSwgMjA2LCAxNjIsCisxNzQsIDExMSwgMTc0LCAxMTUsIDIwOSwgMTA5LCAyMTIsIDI0NSwgMTc3LCA4NiwgMjEyLCAyNDgsIDIxMywgNjgsIDIxNiwgMjM2LAorMjE2LCAyMzMsIDE4MCwgNzksIDIxNiwgMjMyLCAyMjEsIDc4LCAxODMsIDY4LCAyMjUsIDE3NiwgMTg1LCAyNDEsIDIyOSwgMTAxLAorMjI5LCAxMDYsIDIzMywgOTcsIDIzMywgOTUsIDE5MiwgMTcyLCAyNDQsIDY4LCAyNDYsIDIyMiwgMTY0LCAxMTYsIDE2NSwgMTY5LAorMTY0LCAxMTgsIDE4MCwgODMsIDIwMiwgMjAzLCAyMDQsIDExMCwgMTcxLCAyMTIsIDIwOSwgMTE1LCAxNzcsIDk4LCAxODAsIDg1LAorMjIxLCA5MCwgMTg1LCAyNDcsIDE4OCwgMTA5LCAyMjksIDExMCwgMTY1LCAxNzMsIDE3MSwgMjEzLCAxNjcsIDIwMCwgMTY5LCAxNzksCisxNzEsIDIxNCwgMjA5LCAxMTksIDIxMywgNzIsIDE3NywgMTA0LCAxODMsIDcyLCAyMjUsIDE4OCwgMjI1LCAxODUsIDIzMywgMTEzLAorMjQ1LCAyMDMsIDE2NCwgMTIzLCAxNzEsIDIxNywgMTgzLCA3MywgMjAyLCAyMTEsIDE2OSwgMTgzLCAxNzQsIDEyMiwgMTgwLCA5MywKKzE4NSwgMjUxLCAyMDQsIDExNiwgMTY3LCAyMDYsIDE3NywgMTA4LCAyMDIsIDIxMywgMTY5LCAxODUsIDE3MSwgMjIyLCAyMTMsIDc5LAorMTc3LCAxMTYsIDE4MCwgOTYsIDE4OCwgMTIwLCAyNDIsIDY0LCAyMDEsIDEyMywgMjAxLCAyMjUsIDIwNCwgMTIwLCAyMDIsIDIxOCwKKzIwMiwgMjIwLCAxNjksIDE5MSwgMjA0LCAxNzUsIDIwNCwgMTcyLCAxNzEsIDIyOCwgMTY5LCAyMDIsIDIwNCwgMTI1LCAyMDYsIDIwMiwKKzIwNiwgMjAxLCAyMDYsIDIwNywgMTcxLCAyMzYsIDE3MSwgMjM5LCAxNzcsIDExOCwgMTc3LCAxMjAsIDE3NCwgMTcyLCAxNzQsIDE2OSwKKzIxMywgODUsIDIxMywgODYsIDIxNiwgMjUzLCAyMTYsIDI1MiwgMTc3LCAxNjYsIDIxNiwgMjUxLCAxODAsIDEwNywgMTgwLCAxMDUsCisyMTcsIDc5LCAxODAsIDExMiwgMjE3LCA3NSwgMTgwLCAxMDQsIDIyMSwgMTA4LCAyMjUsIDIxMCwgMjIxLCAxMDUsIDIyMSwgMTExLAorMTg2LCA3MCwgMjI1LCAyMDksIDE4OCwgMTYyLCAyMjUsIDIwNywgMjI5LCAxMjYsIDIyOSwgMTYyLCAyMzMsIDExOCwgMTg4LCAxNjUsCisyMjksIDEyMywgMjM2LCAyMjUsIDIzMywgMTIzLCAyMzksIDIwNywgMjM2LCAyMjcsIDIzOSwgMjA0LCAxOTUsIDEwNiwgMTk3LCAxMTYsCisyMDEsIDEyNCwgMjA0LCAxNzcsIDE4MCwgMTE3LCAyMjUsIDIxNCwgMTk0LCA4NywgMjA0LCAxNzgsIDE3NCwgMTc2LCAxNjUsIDE4MywKKzE2NiwgMTcwLCAyMDEsIDIzNiwgMTY3LCAyMzIsIDE2NywgMjI5LCAyMDIsIDIzMSwgMjAyLCAyMzMsIDE2NywgMjMzLCAxNjksIDIyNSwKKzIwNCwgMTg3LCAxNjksIDIyNiwgMTY5LCAyMzAsIDIwNCwgMTgxLCAxNjksIDIxOSwgMjA2LCAyMTgsIDIwNiwgMjE1LCAxNzQsIDE3OSwKKzE3MSwgMjQ2LCAyMDYsIDIyNSwgMTc0LCAxOTMsIDIxMywgMTAyLCAyMDksIDE4OSwgMTc0LCAxODUsIDE3NCwgMTg5LCAyMDksIDE5OSwKKzIxMywgMTAzLCAyMTMsIDExNCwgMTc3LCAyMDQsIDE3NywgMTkzLCAyMTMsIDExMywgMTc3LCAxODQsIDE3NywgMTgwLCAxNzcsIDE5NywKKzIxMywgMTA3LCAyMTcsIDEwNywgMTgwLCAxNjEsIDIxNywgMTAyLCAyMjEsIDE4MywgMjIxLCAxMjAsIDE4MywgMTEyLCAyMjEsIDEyMiwKKzIyMSwgMTc4LCAyMjEsIDEyNiwgMjIxLCAxODUsIDIyMSwgMTY2LCAyMjEsIDE2MiwgMjI1LCAyMTgsIDE4NiwgNzUsIDIyNSwgMjQyLAorMTg4LCAxNzYsIDE4OCwgMTc3LCAyMjksIDE3NywgMjI5LCAxODAsIDE4OCwgMTkzLCAyMjksIDE4NCwgMTg4LCAxODksIDE5MCwgMjE2LAorMTkwLCAyMTMsIDIzMywgMTY3LCAyMzMsIDE3NCwgMjM2LCAyMzQsIDE5MiwgMTk1LCAxOTQsIDk0LCAyMzksIDIxMywgMjQyLCA3MCwKKzI0NCwgNzYsIDI0NiwgMjI1LCAxOTcsIDIwNSwgMTY2LCAxNzIsIDIwNiwgMjMxLCAxNzcsIDIxMSwgMTc3LCAyMDgsIDE4MCwgMTc4LAorMjIxLCAxODgsIDIyOSwgMTkxLCAxOTIsIDE5NywgMTgwLCAxODAsIDE3NywgMjE2LCAxNjUsIDE4NCwgMTgwLCAxODEsIDE2NCwgMjMyLAorMjA5LCAyMDgsIDIxMywgMTY4LCAxODYsIDg4LCAyMDEsIDk0LCAxNjYsIDE3NSwgMTY5LCAyNDQsIDIwNCwgMTk4LCAxNjksIDI1MCwKKzIwNiwgMjM5LCAyMDYsIDI0MCwgMTcyLCA4MiwgMTc0LCAyMDgsIDE3NCwgMjA2LCAyMTMsIDE3MiwgMTc3LCAyMjQsIDE4MCwgMTgyLAorMjIxLCAxOTksIDE4MywgMTIxLCAyMjEsIDE5NCwgMTg2LCA5MiwgMTg2LCA5MSwgMjI5LCAxOTgsIDIzMywgMTg1LCAxOTAsIDIzMiwKKzIzNiwgMjQyLCAxOTQsIDk2LCAxOTYsIDEwMiwgMTY0LCAyMzQsIDE3NiwgMjEwLCAxNjQsIDIzNSwgMjA5LCAyMTUsIDE4MCwgMTk0LAorMTk2LCAxMDMsIDE2NiwgMTgyLCAyMDEsIDI0MiwgMjAyLCAyNTMsIDE2NywgMjQ2LCAyMDMsIDY0LCAxNzAsIDg3LCAyMDQsIDIyMCwKKzE3MCwgODEsIDE3MCwgODAsIDE3MCwgODUsIDE3MCwgNzUsIDIwNywgOTEsIDE3MiwgMTAxLCAyMDcsIDgxLCAyMDcsIDkwLAorMjA3LCA2NywgMTcyLCAxMDcsIDE3MiwgOTAsIDIwNywgNzgsIDIwOSwgMjM2LCAyMDksIDIyNywgMjA5LCAyMzgsIDIwOSwgMjI2LAorMjA5LCAyMjIsIDE3NCwgMjMzLCAyMDksIDIyNCwgMjEzLCAxOTYsIDIxMywgMTg5LCAxNzcsIDIzNiwgMjEzLCAyMDYsIDE3NywgMjM0LAorMTc3LCAyNDgsIDE3NywgMjM5LCAxNzcsIDIzOCwgMTc3LCAyNDMsIDIxNywgMjA1LCAxODAsIDE5OCwgMTgwLCAyMDgsIDE4MCwgMjAzLAorMjE3LCAxOTcsIDIxNywgMTcyLCAxODAsIDIxMywgMjE3LCAyMTYsIDIyMSwgMjQyLCAyMjEsIDIxMCwgMjIxLCAyMjgsIDIyMSwgMjA0LAorMjIxLCAyMzAsIDIyMSwgMjA1LCAyMjEsIDIxOCwgMjIxLCAyMjksIDE4MywgMTY3LCAyMjYsIDc0LCAyMjYsIDkzLCAyMjYsIDkwLAorMTg2LCAxMDMsIDIyNiwgOTYsIDIyNiwgNzgsIDIyNSwgMjU0LCAxODYsIDk4LCAyMjksIDIxMywgMjI5LCAyMTIsIDIyOSwgMjM1LAorMjI5LCAyMDIsIDE4OCwgMjEyLCAyMjksIDIyMCwgMTg4LCAyMDcsIDIzMywgMjAyLCAyMzMsIDE5NCwgMjMzLCAyMTUsIDIzMywgMjIxLAorMjMzLCAyMDksIDIzMywgMjAzLCAyMzMsIDIwOCwgMjMzLCAyMTIsIDE5MiwgMjA3LCAyMzYsIDI0NywgMjM2LCAyNTMsIDIzNiwgMjUxLAorMjM3LCA2NiwgMTk0LCA5OCwgMjM5LCAyMjMsIDIzOSwgMjI5LCAyNDIsIDc5LCAxOTIsIDIwNSwgMTk1LCAxMTEsIDI0NCwgOTAsCisyNDQsIDg3LCAyNDUsIDIwOCwgMjQ3LCAyMjYsIDI0OCwgMjQyLCAxNzAsIDg5LCAyMDksIDI0NywgMjEzLCAyMTYsIDIyMSwgMjUwLAorMjI2LCAxMDEsIDIzMywgMjIyLCAxOTQsIDEwNiwgMTcyLCAxMTAsIDIzMCwgMjA5LCAyMDQsIDIzNCwgMTc0LCAyMzcsIDIxNywgMjIyLAorMjI2LCAxMDIsIDIzMywgMjI2LCAxNzIsIDExMywgMTgzLCAxODEsIDIzOSwgMjMzLCAxODMsIDE4MiwgMjA0LCAyMzYsIDIxMCwgNjQsCisyMTcsIDIyOCwgMjIxLCAyNTQsIDIzMywgMjMyLCAxNjUsIDE5NCwgMjAzLCA3NCwgMTc0LCAyNDQsIDE4MCwgMjI1LCAxNjUsIDE5NSwKKzE2OCwgNjgsIDIwMiwgNjQsIDE2NiwgMTg5LCAxNjYsIDE5NSwgMjAzLCA3NywgMTY4LCA5MCwgMjA1LCA2OSwgMjA1LCA2NywKKzE2OCwgOTIsIDE3MCwgMTA2LCAyMDQsIDI0MywgMjA1LCA3MSwgMTcwLCAxMjEsIDIwNCwgMjQ0LCAyMDUsIDcwLCAxNzAsIDk2LAorMjA0LCAyNTQsIDIwNywgMTI0LCAyMDcsIDExNiwgMjEwLCAxMDAsIDIwNywgMTY4LCAxNzIsIDEyMCwgMjA3LCAxMTAsIDE3MiwgMTYzLAorMjEwLCA3NiwgMjEwLCA3NywgMTc1LCA2NCwgMjEwLCA3MiwgMjEwLCA5OCwgMTc1LCA3MSwgMTc1LCA3NSwgMTc4LCAxMDEsCisyMTMsIDIyNiwgMjEzLCAyNDAsIDIxMywgMjM2LCAxNzgsIDg5LCAyMTMsIDI0MiwgMTc4LCAxMDQsIDIxMywgMjQ5LCAxNzgsIDc2LAorMTc4LCA3NywgMTgxLCA2NSwgMTgwLCAyMzcsIDE4MCwgMjQ0LCAxODAsIDIyOSwgMTgwLCAyNTEsIDE4MCwgMjQ4LCAxODAsIDI0MCwKKzIxNywgMjQwLCAxODAsIDI0MywgMjE4LCA3OCwgMjE3LCAyMzYsIDIyMiwgOTUsIDE4MywgMjAwLCAyMjIsIDg3LCAyMjIsIDg1LAorMTgzLCAxOTYsIDE4MywgMjAxLCAyMjYsIDEwOCwgMjIyLCA5MywgMjI2LCAxNzAsIDIyNiwgMTA5LCAxODYsIDE2MSwgMjI2LCAxMTcsCisxODYsIDExOCwgMjI2LCAxODMsIDE4NiwgMTIwLCAxODYsIDExNSwgMTg2LCAxMjEsIDIyNiwgMTE4LCAxODgsIDIzOSwgMjMwLCA2NywKKzIzMCwgNzMsIDIzMCwgNzIsIDE5MiwgMjIzLCAyMzAsIDkwLCAyMzAsIDkzLCAxOTEsIDczLCAyMzMsIDI1MSwgMTkxLCA3NCwKKzIzMywgMjUzLCAyMzQsIDY1LCAyMzcsIDgxLCAyMzcsIDg3LCAyMzcsIDkxLCAyMzcsIDg4LCAyMzksIDI0NiwgMTk0LCAxMTIsCisxOTQsIDExNCwgMTk1LCAxMTUsIDIzOSwgMjQ1LCAxOTYsIDEwNiwgMjQ0LCAxMDAsIDI0NSwgMjEyLCAxOTcsIDEyMCwgMjQ3LCAyMjgsCisyNDksIDE2MywgMTY2LCAxOTksIDIwMywgOTUsIDIwNSwgODUsIDE3MCwgMTYyLCAyMDUsIDgxLCAxNzIsIDE4MywgMTcyLCAxODIsCisxNzIsIDE4MSwgMjEwLCAxMTksIDE3NSwgODEsIDE3NSwgNzksIDE3NSwgNzgsIDE3OCwgMTA5LCAxNzgsIDEwNSwgMjE0LCA3OSwKKzIxNCwgOTEsIDE4MSwgNzIsIDIxOCwgOTQsIDIxOCwgOTIsIDIxOCwgMTAwLCAyMjIsIDE2MSwgMTgzLCAyMDYsIDIyMiwgMTIwLAorMjIyLCAxMTQsIDE4MywgMjEzLCAyMjIsIDExNiwgMjI2LCAxOTEsIDIyNiwgMTkyLCAxODYsIDE3OSwgMjMwLCAxMDksIDIzMCwgOTksCisxOTEsIDgxLCAxOTEsIDg1LCAxOTEsIDgyLCAyMzQsIDg0LCAyMzcsIDk4LCAxOTIsIDIzNiwgMTk0LCAxMTksIDI0MiwgMTA4LAorMjQyLCAxMDUsIDI0NSwgMjIwLCAyNDgsIDE3NywgMTcwLCAxNjcsIDE3MCwgMTY4LCAyMTAsIDEyNSwgMTgxLCA4MCwgMTg4LCAyNDgsCisxNjgsIDEwMSwgMjA1LCA5MSwgMTcyLCAxODcsIDIxNCwgOTIsIDIxOCwgMTA0LCAxODYsIDE4NSwgMjM0LCA4OSwgMTk2LCAyMzUsCisyMDIsIDY3LCAyMDMsIDk3LCAyMDUsIDk1LCAyMDUsIDk4LCAyMDcsIDE5NCwgMTcyLCAxODgsIDIxMCwgMTY4LCAxNzUsIDg2LAorMjE0LCA5OCwgMjE0LCA5OSwgMTc4LCAxMTQsIDE4MSwgODQsIDIxOCwgMTExLCAyMjIsIDE3MywgMTg2LCAxODcsIDE4OCwgMjUwLAorMjMwLCAxMTcsIDIzMCwgMTYxLCAyMzQsIDk0LCAyMzksIDI1NCwgMTk3LCAxMjIsIDIwMSwgMTY3LCAyMDMsIDEwNywgMTcwLCAxNzksCisxNzAsIDE3NywgMTcyLCAxOTcsIDIwNywgMjEwLCAyMDcsIDIwMSwgMjEwLCAxODAsIDIxMCwgMTc5LCAyMTAsIDE3NiwgMjE0LCAxMjAsCisxNzgsIDEyMywgMjE0LCAxMjEsIDIxOCwgMTI2LCAyMTgsIDE2OSwgMTgxLCA4OCwgMTgxLCA5NCwgMTgzLCAyMzMsIDIyMiwgMTc4LAorMjIyLCAxOTAsIDE4MywgMjMxLCAxODgsIDI1MiwgMjI2LCAyMDcsIDIzMCwgMTY3LCAyMzAsIDE2MiwgMjM0LCAxMDIsIDE5MSwgODgsCisxOTIsIDI0NSwgMTkyLCAyNDQsIDI0NCwgMTExLCAyNDIsIDExNiwgMTk2LCAxMTAsIDI0NiwgMjQyLCAxOTUsIDE2NCwgMjA3LCAyMTYsCisyMTgsIDE3MSwgMjMwLCAxNzMsIDIzNywgMTEyLCAxNzgsIDE2MiwgMTgxLCAxMDAsIDE2NSwgMjA4LCAyMDMsIDEwOSwgMjA3LCAyMTgsCisxNzUsIDk2LCAyMTAsIDE5NCwgMTgxLCAxMDIsIDE4MywgMjM3LCAyMzQsIDEwNiwgMTk3LCAxMjQsIDIwMywgMTExLCAxNzIsIDIwNywKKzIxMCwgMTk1LCAyMTAsIDIwMiwgMjEwLCAxOTgsIDIxNCwgMTI0LCAxODEsIDEwNywgMTgxLCAxMDMsIDIyMiwgMjEwLCAyMjIsIDIwMiwKKzE4MywgMjQxLCAxODYsIDE5OCwgMjI2LCAyMjEsIDE4OSwgNjksIDE4OSwgNjgsIDIzNCwgMTExLCAyMzQsIDExMCwgMjM3LCAxMTksCisxOTQsIDE2MSwgMjQwLCA3NCwgMTk2LCAyMzgsIDI0OSwgMjA0LCAyMDIsIDcxLCAyMTQsIDE2NiwgMTgxLCAxMTMsIDIzMCwgMTg1LAorMjQ0LCAxMTMsIDE4MSwgMTE0LCAyNDQsIDExNCwgMTcyLCAyMTMsIDE3OCwgMTc2LCAxODEsIDExNSwgMjM0LCAxMTcsIDIwNSwgMTIwLAorMjA3LCAyMzEsIDIwNywgMjI2LCAyMTAsIDIwNywgMjEwLCAyMTQsIDIxNCwgMTc2LCAyMTQsIDE2OSwgMjE0LCAxNjgsIDIxOCwgMTg4LAorMjE4LCAxOTIsIDIyMiwgMjI1LCAxODMsIDI1NCwgMjIyLCAyMjYsIDE4NCwgNjQsIDIyNiwgMjM0LCAyMzAsIDE4OCwgMjM0LCAxNjEsCisyMzQsIDEyMCwgMjM3LCAxMjMsIDIzNywgMTIyLCAxOTQsIDE2MywgMjQyLCAxMjEsIDE5NiwgMjM5LCAyMTgsIDE5NSwgMjA3LCAyMzMsCisyNDQsIDEyMCwgMjA1LCAxMjMsIDIwNywgMjM0LCAyMDcsIDIzOCwgMTc1LCAxMjQsIDE3NSwgMTIyLCAyMTAsIDIyOSwgMTc4LCAxODUsCisyMTQsIDE4MiwgMjE4LCAyMDAsIDIxOCwgMjA3LCAyMjIsIDIzOCwgMjIyLCAyMzcsIDE4NCwgNzIsIDE4NCwgNzUsIDIyNiwgMjQ2LAorMjI2LCAyNDUsIDE4OSwgODQsIDIzMCwgMjAxLCAyMzAsIDE5NywgMTkxLCAxMDYsIDIzNCwgMTY0LCAxOTMsIDcwLCAyMzcsIDE3MiwKKzIzNywgMTc0LCAxOTQsIDE2NiwgMTk1LCAxNzAsIDI0NCwgMTIyLCAyNDUsIDIyNSwgMjQ4LCAxODEsIDIwNSwgMTYyLCAyMDcsIDI0NSwKKzE3NSwgMTcwLCAxNzUsIDE2OCwgMjE0LCAxOTEsIDIxOCwgMjEwLCAxODQsIDgzLCAyMjYsIDI0OSwgMjI2LCAyNTMsIDIzMCwgMjA1LAorMTkzLCA3MywgMjQ2LCAyNDcsIDE2NSwgMjIxLCAxNzAsIDE5NiwgMTcyLCAyMzcsIDIxMCwgMjQzLCAxNzUsIDE3OSwgMjE0LCAxOTgsCisxODEsIDEyNSwgMjE4LCAyMTUsIDE4NCwgOTAsIDE4NCwgOTIsIDIyNywgNzIsIDE4OSwgOTQsIDIzNCwgMTc1LCAxOTEsIDExMSwKKzIzNywgMTgwLCAxOTQsIDE2OSwgMjQ0LCAxNjMsIDE2OCwgMTE1LCAyMDcsIDI1NCwgMjEwLCAyNTEsIDIxNCwgMjAxLCAyMjMsIDY4LAorMjI3LCA3NCwgMjMwLCAyMTEsIDIzNywgMTgzLCAxOTcsIDIwOSwgMjEwLCAyNTMsIDE4MSwgMTY0LCAxODYsIDIyMCwgMjQ0LCAxNjUsCisyMDgsIDY3LCAyMTEsIDcwLCAyMTQsIDIxMSwgMjE0LCAyMDgsIDE3OCwgMTk2LCAyMTQsIDIxOSwgMjE4LCAyMjQsIDIxOCwgMjI3LAorMjE4LCAyMjksIDIyMywgODMsIDIyMywgNzIsIDE4NCwgOTUsIDIyNywgOTMsIDIyNywgODUsIDIyNywgODMsIDE4OSwgMTA1LAorMjMwLCAyMTcsIDIzMCwgMjE0LCAxODksIDEwNCwgMjMwLCAyMTUsIDIzNCwgMTg3LCAyMzQsIDE5OCwgMTkxLCAxMjIsIDIzNywgMTk1LAorMjM3LCAyMDEsIDE5MywgNzYsIDE5MSwgMTE3LCAyNDAsIDk3LCAyNDAsIDEwNCwgMjQwLCAxMDgsIDI0MiwgMTcyLCAyNDQsIDE3MCwKKzE5NiwgMjQwLCAyNDYsIDI1NCwgMTk3LCAyMTAsIDE5OCwgODksIDIwOCwgNjksIDIxMSwgNzMsIDIxMSwgNzQsIDIxOCwgMjMyLAorMjE4LCAyMzMsIDIyMywgODQsIDIyNywgOTYsIDIzMCwgMjI0LCAyMzQsIDE5OSwgMTkzLCA4MywgMTk0LCAxNzksIDI0NywgNjUsCisxNjgsIDExNiwgMTcyLCAyNDUsIDIxMSwgODksIDE3NSwgMjAwLCAyMTQsIDI0MCwgMTc4LCAyMTYsIDE3OCwgMjA5LCAxNzgsIDIwNCwKKzE4MSwgMTc4LCAxODQsIDEwOCwgMTgxLCAxODUsIDE4MSwgMTg3LCAyMjMsIDkzLCAyMjMsIDEwMCwgMjIzLCA5NCwgMTg2LCAyMzgsCisyMjcsIDExNywgMTg2LCAyMzcsIDE4NiwgMjQ2LCAyMjcsIDEwOCwgMjI3LCAxMDcsIDE4OSwgMTEyLCAxODksIDExNiwgMjMwLCAyMzksCisxODksIDEyMywgMjMwLCAyMzMsIDIzNCwgMjE5LCAyMzQsIDIwNiwgMjM0LCAyMDUsIDE5MywgOTUsIDE5MywgMTAzLCAxOTMsIDEwNCwKKzIzNywgMjE1LCAyNDAsIDExOSwgMTk0LCAxODIsIDI0MiwgMTg0LCAyNDIsIDE4MiwgMTk2LCAxMjYsIDI0NSwgMjM1LCAyNDcsIDY2LAorMjQ5LCA2NSwgMTY2LCAyMDYsIDIzNCwgMjIzLCAyNDUsIDIzNywgMjA4LCA3NywgMjE0LCAyNDEsIDIyMywgMTAzLCAxODksIDEyNSwKKzI0MiwgMTg3LCAyMDgsIDc5LCAxNzgsIDIyMCwgMTg0LCAxMTUsIDE4OSwgMTI2LCAxOTUsIDE4OCwgMjExLCA5OSwgMjE0LCAyNDgsCisyMTksIDY4LCAxODcsIDY2LCAyMzAsIDI0NiwgMjM5LCAxNjgsIDI0NCwgMTc3LCAxODEsIDE5MiwgMTc1LCAyMDksIDIxNCwgMjU0LAorMjM0LCAyMzAsIDE2NiwgMjEzLCAxNzUsIDIxMiwgMjE1LCA2NiwgMjE5LCA2OSwgMjI3LCAxNjMsIDIzMCwgMjUyLCAxOTMsIDEwOSwKKzE5NywgMTY1LCAxODcsIDcwLCAyMDMsIDExOSwgMjAzLCAxMjAsIDE3MCwgMjExLCAxNzAsIDIxMiwgMjA4LCA5MSwgMTczLCA3MywKKzE3MywgNjgsIDIwOCwgODgsIDE3NSwgMjE4LCAxNzUsIDIyMSwgMTc1LCAyMTUsIDIxNSwgNzgsIDIxNSwgNzQsIDE3OCwgMjMxLAorMTgxLCAyMDAsIDIxOSwgNzQsIDIxOSwgODAsIDIyMywgMTE5LCAxODQsIDEyMywgMjIzLCAxMjYsIDE4NCwgMTYxLCAyMjcsIDE2NiwKKzIyNywgMTY4LCAyMzEsIDY4LCAyMzEsIDY2LCAyMzQsIDIzOSwgMjM0LCAyNDIsIDE5MywgMTE3LCAyMzcsIDIzNCwgMjQyLCAxOTMsCisyNDksIDY4LCAxNzUsIDIyOSwgMjE5LCA4NCwgMjExLCAxMTIsIDI0NCwgMTgxLCAyMjcsIDE3MSwgMTY2LCAyMjQsIDE3NSwgMjMyLAorMjE1LCA4NiwgMjE5LCA5MCwgMjIzLCAxNjQsIDIzMSwgNzEsIDI0MCwgMTYzLCAyNDQsIDE4MiwgMTY2LCAyMjYsIDIwMiwgNzUsCisyMDMsIDE2MSwgMjA4LCAxMDYsIDIwNSwgMTg4LCAyMDUsIDE5MSwgMTcwLCAyMTgsIDE3MCwgMjIyLCAxNzMsIDk4LCAxNzMsIDg2LAorMTczLCA4OSwgMTczLCAxMDIsIDIwOCwgMTA5LCAxNzMsIDgzLCAyMDYsIDY1LCAxNzUsIDI1MCwgMjExLCAxMjYsIDIxMSwgMTc5LAorMTc1LCAyNDksIDE3NSwgMjUxLCAxNzUsIDI0MCwgMTc1LCAyMzksIDIxNSwgOTQsIDIxNSwgMTA0LCAyMTUsIDExOSwgMTc4LCAyNDcsCisyMTUsIDEwNywgMTc5LCA2NSwgMTc4LCAyNDUsIDIxOSwgMTYzLCAyMTksIDE2NCwgMjE5LCAxNzUsIDIxOSwgMTExLCAxODEsIDIxNiwKKzIxOSwgOTQsIDE4MSwgMjA5LCAxODEsIDIxMSwgMjE5LCAxNzQsIDIyMywgMTk5LCAyMjMsIDIxNywgMTg0LCAxNjgsIDIyMywgMjE1LAorMjIzLCAxNzcsIDE4NCwgMTc1LCAyMjMsIDE3NiwgMjIzLCAyMTEsIDIyMywgMTczLCAyMjMsIDE3OSwgMTg3LCA5NiwgMjI3LCAxODcsCisyMjcsIDE3MywgMjI3LCAxODAsIDE4NywgOTMsIDIyNywgMTc4LCAyMjcsIDE5NiwgMjI3LCAyMDEsIDIzMSwgMTE1LCAyMjMsIDE2OSwKKzIzMSwgODgsIDE4OSwgMTgzLCAxODksIDE3NiwgMjMxLCA4NywgMjMxLCAxMTQsIDIzMSwgMTIyLCAyMzEsIDc3LCAyMzQsIDI0OSwKKzIzNSwgNzAsIDIzNSwgNzQsIDIzNSwgODYsIDIzNSwgNzUsIDIzNywgMjUxLCAyMzgsIDgxLCAyMzcsIDI0NSwgMjM4LCA3NSwKKzIzNywgMjUwLCAxOTMsIDE2NiwgMTk0LCAyMDIsIDI0MCwgMTY3LCAxOTQsIDE5NywgMjQyLCAyMDUsIDI0MiwgMjAyLCAyNDIsIDE5OCwKKzI0NCwgMTkwLCAyNDQsIDE4OSwgMTk2LCAxNzMsIDE5NiwgMjQ0LCAyNDUsIDI1MCwgMjQ3LCA3NCwgMjQ3LCA3NiwgMjQ3LCAyNDEsCisyNDksIDE5OSwgMTc5LCA2NiwgMTg0LCAxODUsIDI0MCwgMTg2LCAyMDgsIDE2OSwgMjExLCAxOTYsIDIxMSwgMjA1LCAyMTEsIDE5NSwKKzE3NiwgNjgsIDE3OSwgNzYsIDIxNSwgMTY3LCAyMTUsIDE3NCwgMTgxLCAyNDEsIDIxOSwgMTgyLCAxODEsIDI0MCwgMjIzLCAyMzIsCisxODQsIDE5MCwgMTg0LCAxOTYsIDE4NywgMTA2LCAxODcsIDEwMywgMjI3LCAyMjQsIDE4NywgMTA4LCAyMjcsIDIyNSwgMTg5LCAxOTMsCisyMzEsIDE2MSwgMTg5LCAxODcsIDIzMSwgMTc2LCAxODksIDE4NSwgMjM1LCA5NywgMTkxLCAxOTYsIDIzNSwgOTMsIDE5MSwgMTk1LAorMjM4LCA5MywgMjM4LCAxMDcsIDE5MywgMTcyLCAyMzgsIDEwNSwgMjQwLCAxOTcsIDIzOCwgMTExLCAyNDAsIDIwOCwgMTk0LCAyMDYsCisyNDIsIDIyOCwgMjQyLCAyMjcsIDI0NCwgMTk3LCAyNDYsIDY2LCAyNDcsIDgxLCAyNDcsIDIxNSwgMTk3LCAyNTEsIDIxMSwgMjA3LAorMTczLCAxMDgsIDE4MSwgMjQzLCAxOTEsIDE5NywgMTczLCAxMDksIDIxMSwgMjEwLCAyMTEsIDIxNSwgMjE1LCAxNzgsIDIxNSwgMTk1LAorMTc5LCA3OSwgMjE1LCAxODAsIDIxOSwgMjA1LCAyMTksIDIwMiwgMjE5LCAyMDcsIDE4NCwgMTk5LCAyMjMsIDI0NSwgMTg3LCAxMTYsCisyMjcsIDI0OCwgMjI3LCAyNTIsIDIzMSwgMjAxLCAxODksIDE5NywgMTg3LCAxMTcsIDE5MSwgMjAwLCAyMzUsIDEyMiwgMTkzLCAxODIsCisyNDAsIDIxNCwgMjQwLCAyMTUsIDI0MiwgMjM0LCAxOTYsIDE3NiwgMjQ2LCA3NCwgMjQ5LCA3MiwgMTgxLCAyNDcsIDE3OSwgODcsCisyMjMsIDI1MSwgMTkxLCAyMDQsIDE5NCwgMjA5LCAxOTYsIDI1MywgMTY4LCAxNjQsIDIyNCwgNjcsIDIyNCwgNjgsIDIzMSwgMjEwLAorMjQ2LCA3NiwgMjA4LCAxNzYsIDE3NiwgODEsIDE3NiwgNzksIDE3OSwgOTYsIDIxNSwgMjAzLCAxODIsIDcwLCAyMTksIDIxOCwKKzIxOSwgMjI2LCAxODIsIDY0LCAxODEsIDI1MiwgMTg0LCAyMjksIDE4NCwgMjExLCAxODQsIDIxNywgMjI0LCA3MCwgMTg3LCAxNjUsCisxODcsIDEyMSwgMTg3LCAxNjMsIDE4OSwgMjEwLCAxODksIDIwMywgMjMxLCAyMTMsIDIzMSwgMjE2LCAxODksIDIxOSwgMTkxLCAyMDUsCisyMzUsIDE2OSwgMTkxLCAyMDYsIDE5MywgMTk1LCAxOTMsIDE4OCwgMjM4LCAxNjEsIDIzOCwgMTY2LCAxOTQsIDIxMywgMjQwLCAyMzIsCisyNDIsIDI0OSwgMjQyLCAyNDgsIDI0MiwgMjUyLCAxOTYsIDE4MywgMjQ0LCAyMDcsIDE5NiwgMjU0LCAyNDcsIDg2LCAyNDgsIDY3LAorMTk3LCAyNTQsIDE5OCwgMTA5LCAxNjgsIDE2NiwgMTkzLCAxOTcsIDIyNCwgODMsIDE2OCwgMTY4LCAyMTksIDIyOSwgMjI4LCA4MiwKKzE5MywgMTk5LCAyMTUsIDIwOSwgMTg0LCAyMzIsIDE5MSwgMjIzLCAxNjgsIDE2OSwgMTc5LCAxMDQsIDE4NCwgMjM3LCAxODIsIDc1LAorMTg0LCAyMzQsIDE4NywgMTcyLCAxODksIDIzMSwgMTg5LCAyMjUsIDIzNSwgMTgzLCAxOTMsIDIwMCwgMjQwLCAyNDQsIDE5NiwgMTg1LAorMjQ4LCA2OSwgMTY4LCAxNzAsIDIzNSwgMTg2LCAyMTEsIDIyOCwgMjE5LCAyMzcsIDIyNCwgOTYsIDE4NywgMTc1LCAxODksIDIzNiwKKzI0MywgNzcsIDIxMSwgMjMwLCAyMTUsIDIxOCwgMTgyLCA5MSwgMjE5LCAyNDcsIDE4NCwgMjQyLCAyMjQsIDEwOSwgMTg0LCAyNDUsCisyMjgsIDkxLCAyMjgsIDk0LCAyMzEsIDI1MSwgMjMxLCAyNDksIDIzMSwgMjQ1LCAyMzUsIDE5OCwgMjM1LCAxOTUsIDIzOCwgMTkxLAorMjM4LCAxODgsIDI0MSwgNjcsIDI0MCwgMjU0LCAxOTUsIDIxOSwgMTk1LCAyMTgsIDI0NCwgMjE1LCAyNDcsIDk3LCAyNDcsIDk1LAorMjQ5LCA4MCwgMTg0LCAyNTAsIDIzNSwgMjAwLCAyNDksIDE3MiwgMjExLCAyMzMsIDIxNSwgMjIxLCAyMjAsIDY5LCAyMjAsIDczLAorMTgyLCA5NywgMjI0LCAxMjAsIDIyOCwgMTAwLCAyMzIsIDc0LCAyMzIsIDcyLCAyMzUsIDIwMiwgMTkxLCAyMzMsIDE5MywgMjEyLAorMTk0LCAyMjUsIDI0NCwgMjIwLCAxOTcsIDE3NSwgMTY4LCAxNzUsIDE5MSwgMjM2LCAxNjgsIDE3NiwgMjAzLCAxNjYsIDIwMywgMTY1LAorMjA1LCAyMDYsIDIwOCwgMTgyLCAxNzMsIDEyNSwgMTc2LCAxMDYsIDIxMSwgMjM0LCAyMTUsIDIyNywgMTc5LCAxMTksIDE3OSwgMTE2LAorMjIwLCA3NywgMTgyLCAxMDQsIDE4NSwgNjksIDE4NSwgNzcsIDE4NywgMTg0LCAxODcsIDE4OSwgMTkwLCA2OCwgMTkwLCA2OSwKKzE5MywgMjE4LCAxOTUsIDIyOSwgMTc2LCAxMTEsIDIwMywgMTY3LCAxNjgsIDE4NCwgMjA1LCAyMTIsIDIwOCwgMTg4LCAyMDgsIDE5MSwKKzIxNSwgMjM4LCAyMTEsIDI0NywgMjE1LCAyNDEsIDIxNSwgMjM3LCAxNzksIDE2MywgMjIwLCA5MCwgMjI0LCAxNjcsIDIyOCwgMTEzLAorMjMyLCA4OSwgMTkwLCA3MCwgMjQxLCA3NSwgMjQ2LCA5MSwgMjEyLCA2NCwgMjE1LCAyNDMsIDIyMCwgOTYsIDE4NSwgODMsCisxODcsIDE5NywgMjMyLCA5NCwgMTkwLCA3NiwgMjM4LCAyMDAsIDE5MywgMjIyLCAyNDMsIDk1LCAyNDQsIDIyNywgMTk4LCA5MywKKzE5NiwgMTkyLCAyMTIsIDY2LCAyMTIsIDY3LCAyMTUsIDI0NywgMjE2LCA2NSwgMjIwLCA5OCwgMjIwLCAxMDUsIDIyMCwgMTE5LAorMTgyLCAxMTYsIDIyOCwgMTg2LCAxODUsIDg3LCAxODUsIDEwMCwgMjI0LCAxODgsIDE4NSwgMTAzLCAxODUsIDk1LCAyMjQsIDE5MSwKKzIyOCwgMTY0LCAyMjQsIDE4MiwgMjI4LCAxMjYsIDIyOCwgMTY1LCAyMjgsIDE3NSwgMjI4LCAxNjMsIDIzMiwgMTYxLCAyMzIsIDEwMSwKKzIzMiwgMTE1LCAyMzIsIDEyMCwgMjMyLCAxMDYsIDIzMiwgMTA4LCAyMzUsIDI0NCwgMjM1LCAyMzMsIDIzNiwgNjQsIDE5MiwgNjcsCisyMzUsIDIyNCwgMjM1LCAyNDksIDE5MSwgMjQ4LCAyMzUsIDIzNCwgMjM4LCAyMTYsIDE5MywgMjM3LCAyMzgsIDIwOCwgMTkzLCAyMzYsCisyMzUsIDIyNywgMjQxLCA5NiwgMjQxLCA4NSwgMjQxLCA4OCwgMjQxLCA5MCwgMjQxLCAxMDAsIDI0MywgMTE1LCAyNDMsIDEwOCwKKzI0MywgMTA5LCAyNDMsIDk2LCAxOTUsIDI0NSwgMjQ0LCAyNDMsIDI0NCwgMjU0LCAyNDQsIDI1MSwgMjQ0LCAyMzIsIDI0NCwgMjM0LAorMjQ2LCAxMDIsIDE5NywgNzUsIDI0NiwgOTQsIDI0NywgMTExLCAyNDgsIDc1LCAxOTcsIDIyNCwgMTk4LCA2OCwgMjQ5LCAxMTQsCisxOTgsIDExMywgMTcwLCAyNDgsIDE3MywgMTcyLCAyMjAsIDEyMiwgMTg1LCAxMDQsIDE4NywgMjEzLCAxOTAsIDkxLCAyMzgsIDI0MywKKzIzOCwgMjQxLCAyMzYsIDcxLCAyNDMsIDExOSwgMjQ2LCAxMDgsIDE3MCwgMjUwLCAyMDMsIDE3NCwgMTY4LCAxOTAsIDIwNSwgMjE4LAorMjA4LCAxOTgsIDIwOCwgMTk0LCAxNzYsIDE2NSwgMTc5LCAxNzMsIDE3OSwgMTc4LCAyMjAsIDEyNSwgMjIwLCAxMjYsIDIyNCwgMjA5LAorMTg3LCAyMTcsIDE5MiwgNzEsIDE5MywgMjQ0LCAxNzYsIDE2NiwgMTgyLCAxNzQsIDE4NywgMjIwLCAxOTQsIDI0OCwgMTcxLCA2NiwKKzE4MiwgMTc5LCAyMjQsIDIxNSwgMTkwLCA5NSwgMTkyLCA3NiwgMTkzLCAyNDcsIDI0MywgMTI2LCAxOTYsIDE5NywgMjQ2LCAxMTEsCisxOTgsIDcxLCAxNzEsIDY3LCAxOTIsIDgyLCAxOTIsIDgzLCAyMjAsIDE3MCwgMjI4LCAxOTIsIDIyOCwgMTk4LCAyMzIsIDE3OCwKKzE5MiwgODQsIDI0MSwgMTYxLCAyNDEsIDEyMSwgMjQzLCAxNjMsIDE5NywgMTgzLCAxNzMsIDE3OSwgMjM5LCA2NiwgMjQzLCAxNjYsCisxNzMsIDE4MCwgMjM2LCA4OCwgMTc5LCAxODcsIDE4NSwgMTI0LCAyMjgsIDIwMywgMjMyLCAxODcsIDE5MCwgMTAyLCAyMzYsIDg5LAorMjM5LCA2OSwgMTk1LCA2OCwgMjQzLCAxNzAsIDI0NSwgNzksIDE5NywgMjI3LCAxNzMsIDE4MywgMjMyLCAxOTAsIDE5NiwgNjYsCisyNDYsIDExNiwgMTczLCAxODQsIDIxNiwgNzksIDE4MiwgMTg2LCAyMjQsIDIyNywgMTg3LCAyMjksIDE5MiwgOTIsIDE5MiwgOTcsCisyMzYsIDkyLCAxOTUsIDc1LCAyNDEsIDE3NCwgMTk2LCA2NywgMjQ1LCA4NCwgMjQ3LCAxMTksIDE3MywgMTg2LCAyMzksIDg3LAorMjQ5LCAxNzgsIDIyNCwgMjMxLCAxODcsIDIzMywgMjMyLCAyMDcsIDE5MCwgMTE0LCAxOTAsIDExMSwgMjM2LCAxMDQsIDIzOSwgOTAsCisyMzksIDk3LCAyNDEsIDE3NywgMjQzLCAxOTIsIDI0MywgMTkwLCAyNDUsIDk2LCAyNDUsIDkxLCAxOTcsIDkxLCAyNDcsIDEyNSwKKzI0NywgMTYyLCAyNDgsIDIxMSwgMjQ5LCAxOTUsIDE3NiwgMTY5LCAyMzIsIDIxMCwgMjM5LCAxMDAsIDI0NSwgMTAxLCAxOTcsIDIzMywKKzIxMiwgNzMsIDIzMiwgMjEyLCAyMzYsIDExMCwgMjM5LCAxMDMsIDI0MywgMTk0LCAyNDYsIDE2MywgMjQ4LCA4NSwgMjQxLCAxOTAsCisyMzYsIDExNCwgMjI4LCAyMjEsIDIzOSwgMTA1LCAyNDYsIDE2OCwgMjI4LCAyMjUsIDIzMiwgMjI3LCAyMzIsIDIyMiwgMjM2LCAxMTUsCisyMzYsIDEyNCwgMjM5LCAxMDYsIDIzOSwgMTEzLCAxOTQsIDY1LCAyNDEsIDIwMSwgMjQxLCAxOTcsIDI0MSwgMjAyLCAyNDMsIDIwMiwKKzE5NiwgNzIsIDI0NSwgMTA4LCAyNDUsIDEwOSwgMjQ1LCAxMTAsIDI0NiwgMTcxLCAyNDYsIDE3NCwgMjQ3LCAxODAsIDI0NywgMTc3LAorMjQ3LCAxNzAsIDI0OCwgODksIDI0OCwgMjE4LCAyNDksIDkwLCAyNDksIDEyMCwgMTc5LCAxOTAsIDIyOCwgMjI2LCAyMzIsIDIzNiwKKzIzMiwgMjM4LCAyMzYsIDE3MiwgMTkyLCAxMTIsIDIzNiwgMTYzLCAyMzksIDEyMywgMTk0LCA2OSwgMjM5LCAxNjEsIDI0MSwgMjA5LAorMjQxLCAyMTMsIDIzOSwgMTIwLCAyNDMsIDIyMSwgMjQzLCAyMzUsIDI0MywgMjMzLCAyNDUsIDEyNSwgMjQ1LCAxNjcsIDI0NSwgMTIxLAorMTk3LCA5NywgMjQ2LCAxOTEsIDI0NiwgMTg3LCAyNDYsIDE5OSwgMTk3LCAxOTUsIDI0OCwgMTA1LCAyNDgsIDEwMSwgMjQ3LCAxOTYsCisyNDgsIDIyOSwgMjQ4LCAyMjgsIDI0OSwgMTI0LCAyNDksIDIwNywgMTc5LCAxOTEsIDE3OSwgMTkyLCAyMzksIDE3MSwgMTk2LCA4MywKKzE5NywgMTAxLCAyMjgsIDIyOSwgMTk2LCA4NCwgMTkwLCAxNjMsIDIzOSwgMTc0LCAyMzIsIDI0MSwgMTk0LCA3NSwgMjQ1LCAxODIsCisyNDgsIDExOCwgMjQzLCAyNDUsIDI0OCwgMTIwLCAyMzIsIDI0MywgMjQ2LCAyMDgsIDIzOSwgMTc4LCAyNDUsIDE4NSwgMjQ4LCAxMjIsCisyNDcsIDIwNCwgMjQxLCAyMzMsIDI0MywgMjUwLCAyNDUsIDE4NywgMTk3LCAxOTgsIDI0OCwgMjM1LCAyNDksIDIxMSwgMTkyLCAxMTUsCisyNDksIDIxMywgMjQ3LCAyMDcsIDIwMSwgNzQsIDE2MSwgNzQsIDE2MSwgMTA0LCAxNjEsIDEyNCwgMTYxLCAyMDEsIDE2MSwgMTI1LAorMTYxLCAyMjMsIDE2MSwgNzMsIDE2MSwgMjA3LCAxNjIsIDE4MCwgMTYxLCA3MiwgMTYyLCAyMTUsIDE2MiwgMjI1LCAxNjEsIDE5NiwKKzE2MiwgMjQxLCAxNjIsIDI1MSwgMTYxLCA5OCwgMAorICAgICAgICAgICAgfSk7CisKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9NdWx0aUJ5dGVfQmlnNV9BbmRyb2lkLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX0JpZzVfQW5kcm9pZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxYTcxZjAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX0JpZzVfQW5kcm9pZC5qYXZhCkBAIC0wLDAgKzEsMzAxIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKKy8qKiBOb3RlOiBJQ1UgYmVoYXZlcyBkaWZmZXJlbnRseSBmcm9tIHRoZSBSSSAqLworCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9NdWx0aUJ5dGVfQmlnNV9BbmRyb2lkIGV4dGVuZHMgT2xkQ2hhcnNldF9BYnN0cmFjdFRlc3QgeworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcnNldE5hbWUgPSAiQmlnNSI7CisKKyAgICAgICAgdGVzdENoYXJzID0gdGhlc2VDaGFycyhuZXcgaW50W117CiswLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAorMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCiszMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKzQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCis4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKzk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorMTI4LCAxNjcsIDE3NSwgMTc2LCAxNzcsIDE4MywgMjE1LCAyNDcsIDcxMSwgNzEzLCA5MTMsIDkzMywgOTUzLCA4MjExLCA4MjMxLCA4MjUxLAorODM2NCwgODQ1MSwgODU0NCwgODU5MiwgODcyNSwgODc0NSwgODc4NiwgODgwNiwgODg1MywgODg5NSwgOTQ3MiwgOTQ5MiwgOTUxNiwgOTU1MiwgOTU3MiwgOTYwMSwKKzk2MjEsIDk2NTAsIDk2NzAsIDk2OTgsIDk3MzMsIDk3OTIsIDEyMjg4LCAxMjMwOCwgMTIzMjgsIDEyNTQ5LCAxMjU2OSwgMTI5NjMsIDEzMTk4LCAxMzI1MiwgMTk5NjgsIDE5OTg4LAorMjAwMTEsIDIwMDM0LCAyMDA1NCwgMjAwODMsIDIwMTA0LCAyMDEyNiwgMjAxNDcsIDIwMTY3LCAyMDE4OCwgMjAyMDgsIDIwMjI4LCAyMDI0OCwgMjAyNjgsIDIwMjg5LCAyMDMwOSwgMjAzMjksCisyMDM0OSwgMjAzNjksIDIwMzk4LCAyMDQxOCwgMjA0MzgsIDIwNDYwLCAyMDQ4MCwgMjA1MDAsIDIwNTIwLCAyMDU0MCwgMjA1NjEsIDIwNTgxLCAyMDYwMiwgMjA2MjIsIDIwNjQyLCAyMDY2MiwKKzIwNjgyLCAyMDcwNCwgMjA3MjUsIDIwNzQ1LCAyMDc2NywgMjA3ODcsIDIwODA3LCAyMDgyNywgMjA4NDksIDIwODcxLCAyMDg5NCwgMjA5MTgsIDIwOTM4LCAyMDk1OCwgMjA5NzksIDIwOTk5LAorMjEwMjAsIDIxMDQwLCAyMTA2MCwgMjEwODIsIDIxMTAyLCAyMTEyMiwgMjExNDIsIDIxMTYyLCAyMTE4MiwgMjEyMDIsIDIxMjIyLCAyMTI0MiwgMjEyNjIsIDIxMjgyLCAyMTMwMywgMjEzMjQsCisyMTM0NCwgMjEzNjUsIDIxMzg2LCAyMTQwNiwgMjE0MjYsIDIxNDQ4LCAyMTQ3MSwgMjE0OTEsIDIxNTExLCAyMTUzMSwgMjE1NTIsIDIxNTczLCAyMTYwMCwgMjE2MjAsIDIxNjQwLCAyMTY2NCwKKzIxNjg2LCAyMTcxMCwgMjE3MzAsIDIxNzUxLCAyMTc3MSwgMjE3OTgsIDIxODE5LCAyMTgzOSwgMjE4NTksIDIxODc5LCAyMTg5OSwgMjE5MTksIDIxOTM5LCAyMTk1OSwgMjE5NzksIDIxOTk5LAorMjIwMjAsIDIyMDQzLCAyMjA2MywgMjIwODUsIDIyMTA1LCAyMjEyNSwgMjIxNDUsIDIyMTY1LCAyMjE4NiwgMjIyMDYsIDIyMjI3LCAyMjI0NywgMjIyNzEsIDIyMjkxLCAyMjMxMiwgMjIzMzQsCisyMjM1NCwgMjIzNzQsIDIyMzk1LCAyMjQxNSwgMjI0MzUsIDIyNDU2LCAyMjQ3NiwgMjI0OTYsIDIyNTE2LCAyMjUzNiwgMjI1NTYsIDIyNTc2LCAyMjYwMCwgMjI2MjEsIDIyNjQxLCAyMjY2MSwKKzIyNjg0LCAyMjcwNSwgMjI3MjUsIDIyNzQ1LCAyMjc2NywgMjI3ODcsIDIyODA3LCAyMjgyNywgMjI4NDgsIDIyODY4LCAyMjg4OSwgMjI5MDksIDIyOTMwLCAyMjk1MCwgMjI5NzAsIDIyOTkwLAorMjMwMTEsIDIzMDMxLCAyMzA1MiwgMjMwNzIsIDIzMDkzLCAyMzExMywgMjMxMzMsIDIzMTU5LCAyMzE3OSwgMjMxOTksIDIzMjE5LCAyMzIzOSwgMjMyNTksIDIzMjgzLCAyMzMwMywgMjMzMjMsCisyMzM0MywgMjMzNjMsIDIzMzgzLCAyMzQwMywgMjM0MjMsIDIzNDQzLCAyMzQ2MywgMjM0ODcsIDIzNTA3LCAyMzUyNywgMjM1NTMsIDIzNTczLCAyMzU5NCwgMjM2MTQsIDIzNjM2LCAyMzY1NiwKKzIzNjc2LCAyMzY5NiwgMjM3MTYsIDIzNzM2LCAyMzc1NiwgMjM3ODQsIDIzODA1LCAyMzgyNSwgMjM4NDUsIDIzODY1LCAyMzg4NiwgMjM5MDYsIDIzOTI3LCAyMzk0OSwgMjM5NjksIDIzOTg5LAorMjQwMDksIDI0MDI5LCAyNDA0OSwgMjQwNzAsIDI0MDkwLCAyNDExNSwgMjQxMzgsIDI0MTU5LCAyNDE3OSwgMjQxOTksIDI0MjE5LCAyNDI0MCwgMjQyNjAsIDI0MjgwLCAyNDMwMCwgMjQzMjEsCisyNDM0MSwgMjQzNjEsIDI0Mzg0LCAyNDQwNCwgMjQ0MjUsIDI0NDQ1LCAyNDQ2NSwgMjQ0ODUsIDI0NTA1LCAyNDUyNSwgMjQ1NDUsIDI0NTY1LCAyNDU4NSwgMjQ2MDUsIDI0NjI2LCAyNDY0NiwKKzI0NjY2LCAyNDY4NiwgMjQ3MDcsIDI0NzI3LCAyNDc1MiwgMjQ3NzIsIDI0NzkyLCAyNDgxNiwgMjQ4MzYsIDI0ODU2LCAyNDg3NiwgMjQ4OTYsIDI0OTE2LCAyNDkzNiwgMjQ5NTYsIDI0OTc2LAorMjQ5OTYsIDI1MDE2LCAyNTAzNiwgMjUwNTYsIDI1MDc3LCAyNTA5NywgMjUxMTksIDI1MTM5LCAyNTE1OSwgMjUxNzksIDI1MTk5LCAyNTIxOSwgMjUyMzksIDI1MjU5LCAyNTI3OSwgMjUyOTksCisyNTMyMywgMjUzNDMsIDI1MzYzLCAyNTM4NCwgMjU0MDQsIDI1NDI0LCAyNTQ0NSwgMjU0NjYsIDI1NDg2LCAyNTUwNiwgMjU1MzMsIDI1NTU0LCAyNTU3NSwgMjU2MDYsIDI1NjI2LCAyNTY0NiwKKzI1NjY3LCAyNTY4OCwgMjU3MDgsIDI1NzMwLCAyNTc1MCwgMjU3NzEsIDI1NzkxLCAyNTgxMiwgMjU4MzIsIDI1ODUyLCAyNTg3MiwgMjU4OTIsIDI1OTEyLCAyNTkzNSwgMjU5NTUsIDI1OTc1LAorMjU5OTYsIDI2MDE2LCAyNjAzOCwgMjYwNTksIDI2MDc5LCAyNjA5OSwgMjYxMTksIDI2MTQwLCAyNjE2MSwgMjYxODEsIDI2MjAxLCAyNjIyMiwgMjYyNDQsIDI2MjY0LCAyNjI4NiwgMjYzMDgsCisyNjMyOCwgMjYzNDgsIDI2MzY4LCAyNjM4OCwgMjY0MDgsIDI2NDI4LCAyNjQ0OCwgMjY0NzQsIDI2NDk0LCAyNjUxNCwgMjY1NDIsIDI2NTYyLCAyNjU4NCwgMjY2MDQsIDI2NjQyLCAyNjY2MiwKKzI2NjgyLCAyNjcwMiwgMjY3MzEsIDI2NzUxLCAyNjc3MSwgMjY3OTEsIDI2ODIwLCAyNjg0MCwgMjY4NjAsIDI2ODg0LCAyNjkxNywgMjY5MzcsIDI2OTU4LCAyNjk3OCwgMjY5OTgsIDI3MDIxLAorMjcwNDEsIDI3MDYxLCAyNzA4MSwgMjcxMDYsIDI3MTI2LCAyNzE0NiwgMjcxNjYsIDI3MTg2LCAyNzIwNiwgMjcyMjYsIDI3MjQ3LCAyNzI2NywgMjcyODcsIDI3MzA4LCAyNzMzMCwgMjczNTMsCisyNzM3NCwgMjczOTQsIDI3NDE0LCAyNzQzNiwgMjc0NTcsIDI3NDc3LCAyNzQ5OCwgMjc1MTgsIDI3NTQwLCAyNzU2MiwgMjc1ODMsIDI3NjAzLCAyNzYyMywgMjc2NDMsIDI3NjYzLCAyNzY4MywKKzI3NzA0LCAyNzcyNCwgMjc3NDQsIDI3NzY0LCAyNzc4NCwgMjc4MDQsIDI3ODI0LCAyNzg0NCwgMjc4NjUsIDI3ODg1LCAyNzkwNSwgMjc5MjYsIDI3OTQ2LCAyNzk2NiwgMjc5OTIsIDI4MDEyLAorMjgwMzIsIDI4MDUyLCAyODA3NCwgMjgwOTQsIDI4MTE0LCAyODEzNCwgMjgxNTQsIDI4MTg1LCAyODIwNSwgMjgyMjUsIDI4MjQ1LCAyODI2NSwgMjgyOTYsIDI4MzE2LCAyODMzNiwgMjgzNTYsCisyODM3NiwgMjgzOTYsIDI4NDE2LCAyODQzNiwgMjg0NTcsIDI4NDc4LCAyODQ5OCwgMjg1MTgsIDI4NTM4LCAyODU1OCwgMjg1NzgsIDI4NTk4LCAyODYxOCwgMjg2MzgsIDI4NjU4LCAyODY3OCwKKzI4Njk4LCAyODcxOSwgMjg3MzksIDI4NzU5LCAyODc3OSwgMjg4MDIsIDI4ODIyLCAyODg0MywgMjg4NjksIDI4ODg5LCAyODkxMSwgMjg5MzIsIDI4OTUzLCAyODk3NCwgMjg5OTQsIDI5MDE0LAorMjkwMzQsIDI5MDU2LCAyOTA3NiwgMjkwOTYsIDI5MTE2LCAyOTEzNiwgMjkxNTYsIDI5MTc2LCAyOTE5NiwgMjkyMTgsIDI5MjM4LCAyOTI1OCwgMjkyNzgsIDI5Mjk4LCAyOTMxOCwgMjkzMzgsCisyOTM1OCwgMjkzNzgsIDI5Mzk4LCAyOTQxOCwgMjk0MzgsIDI5NDU4LCAyOTQ3OCwgMjk0OTgsIDI5NTE4LCAyOTUzOCwgMjk1NTgsIDI5NTc4LCAyOTU5OSwgMjk2MTksIDI5NjM5LCAyOTY1OSwKKzI5Njg0LCAyOTcwNCwgMjk3MjUsIDI5NzQ1LCAyOTc2NiwgMjk3ODYsIDI5ODA2LCAyOTgyNywgMjk4NDcsIDI5ODY3LCAyOTg4NywgMjk5MDgsIDI5OTI4LCAyOTk0OSwgMjk5NjksIDI5OTg5LAorMzAwMDksIDMwMDMwLCAzMDA1MCwgMzAwNzAsIDMwMDkwLCAzMDExNCwgMzAxMzQsIDMwMTU0LCAzMDE3NCwgMzAxOTQsIDMwMjE2LCAzMDIzNiwgMzAyNTYsIDMwMjc4LCAzMDI5OCwgMzAzMTgsCiszMDMzOCwgMzAzNTgsIDMwMzc4LCAzMDM5OCwgMzA0MTgsIDMwNDM4LCAzMDQ1OCwgMzA0ODAsIDMwNTAxLCAzMDUyMSwgMzA1NDEsIDMwNTYxLCAzMDU4NSwgMzA2MDUsIDMwNjI1LCAzMDY0NSwKKzMwNjY1LCAzMDY4NiwgMzA3MDYsIDMwNzI2LCAzMDc0OSwgMzA3NjksIDMwNzg5LCAzMDgxMiwgMzA4MzIsIDMwODUyLCAzMDg3MiwgMzA4OTIsIDMwOTEzLCAzMDkzMywgMzA5NTMsIDMwOTczLAorMzA5OTMsIDMxMDEzLCAzMTAzMywgMzEwNTUsIDMxMDc1LCAzMTA5NywgMzExMTcsIDMxMTM3LCAzMTE1OCwgMzExNzksIDMxMTk5LCAzMTIyMiwgMzEyNDIsIDMxMjYyLCAzMTI4NywgMzEzMDcsCiszMTMyNywgMzEzNDgsIDMxMzY4LCAzMTM5MCwgMzE0MTAsIDMxNDMxLCAzMTQ1NSwgMzE0NzgsIDMxNDk4LCAzMTUxOCwgMzE1MzgsIDMxNTU4LCAzMTU4NCwgMzE2MDQsIDMxNjI0LCAzMTY0NCwKKzMxNjY1LCAzMTY4NiwgMzE3MDYsIDMxNzI4LCAzMTc0OSwgMzE3NjksIDMxNzg5LCAzMTgxMSwgMzE4MzEsIDMxODUxLCAzMTg3MSwgMzE4OTIsIDMxOTEyLCAzMTkzMiwgMzE5NTIsIDMxOTc1LAorMzE5OTUsIDMyMDE1LCAzMjA0MCwgMzIwNjAsIDMyMDgwLCAzMjEwMiwgMzIxMjIsIDMyMTQyLCAzMjE2MiwgMzIxODMsIDMyMjAzLCAzMjIyMywgMzIyNDMsIDMyMjY0LCAzMjI4NCwgMzIzMDQsCiszMjMyNCwgMzIzNDQsIDMyMzY1LCAzMjM4NSwgMzI0MDUsIDMyNTY2LCAzMjU4NiwgMzI2MDYsIDMyNjI2LCAzMjY0NiwgMzI2NjYsIDMyNjg3LCAzMjcwNywgMzI3MjcsIDMyNzQ3LCAzMjc2NywKKzMyNzg4LCAzMjgwOCwgMzI4MjksIDMyODQ5LCAzMjg3MSwgMzI4OTMsIDMyOTE0LCAzMjkzNywgMzI5NjIsIDMyOTgyLCAzMzAwNSwgMzMwMjUsIDMzMDQ1LCAzMzA2NSwgMzMwODUsIDMzMTA1LAorMzMxMjUsIDMzMTQ1LCAzMzE2NSwgMzMxODYsIDMzMjA3LCAzMzIyOCwgMzMyNDgsIDMzMjY4LCAzMzI4OCwgMzMzMDgsIDMzMzMwLCAzMzM1MSwgMzMzNzEsIDMzMzkxLCAzMzQxMSwgMzM0MzIsCiszMzQ1MiwgMzM0NzIsIDMzNDkyLCAzMzUxMiwgMzM1MzQsIDMzNTU4LCAzMzU3OCwgMzM1OTksIDMzNjE5LCAzMzY1MSwgMzM2NzEsIDMzNjkxLCAzMzcxMSwgMzM3MzEsIDMzNzUxLCAzMzc3MSwKKzMzNzkxLCAzMzgxMSwgMzM4MzMsIDMzODUzLCAzMzg3MywgMzM4OTMsIDMzOTEzLCAzMzkzMywgMzM5NTMsIDMzOTc0LCAzMzk5NCwgMzQwMjMsIDM0MDQzLCAzNDA2MywgMzQwODMsIDM0MTA3LAorMzQxMjksIDM0MTQ5LCAzNDE2OSwgMzQxODksIDM0MjA5LCAzNDIyOSwgMzQyNDksIDM0MjY5LCAzNDI4OSwgMzQzMDksIDM0MzI5LCAzNDM0OSwgMzQzNzEsIDM0MzkzLCAzNDQxMywgMzQ0MzcsCiszNDQ1NywgMzQ0NzksIDM0NDk5LCAzNDUxOSwgMzQ1MzksIDM0NTYwLCAzNDU4NCwgMzQ2MDQsIDM0NjI0LCAzNDY0NCwgMzQ2NjQsIDM0Njg5LCAzNDcxMCwgMzQ3MzAsIDM0NzUwLCAzNDc3MCwKKzM0NzkwLCAzNDgxMCwgMzQ4MzIsIDM0ODUyLCAzNDg3MiwgMzQ4OTIsIDM0OTEzLCAzNDkzMywgMzQ5NTMsIDM0OTc0LCAzNDk5NCwgMzUwMTcsIDM1MDM3LCAzNTA1NywgMzUwNzcsIDM1MDk3LAorMzUxMTcsIDM1MTM3LCAzNTE1OCwgMzUxNzgsIDM1MTk4LCAzNTIxOSwgMzUyNDIsIDM1MjYyLCAzNTI4MiwgMzUzMDIsIDM1MzIyLCAzNTM0MiwgMzUzNjIsIDM1MzgyLCAzNTQwMiwgMzU0MjIsCiszNTQ0MiwgMzU0NjIsIDM1NDgyLCAzNTUwNCwgMzU1MjQsIDM1NTQ0LCAzNTU2NSwgMzU1ODUsIDM1NjA1LCAzNTYyNiwgMzU2NDYsIDM1NjY2LCAzNTY4NiwgMzU3MDYsIDM1NzI2LCAzNTg5NSwKKzM1OTE1LCAzNTkzNSwgMzU5NTUsIDM1OTc3LCAzNTk5NywgMzYwMTgsIDM2MDM5LCAzNjA2MCwgMzYwODAsIDM2MTAwLCAzNjEyMSwgMzYxOTYsIDM2MjE2LCAzNjIzNiwgMzYyNTYsIDM2Mjc2LAorMzYyOTYsIDM2MzE2LCAzNjMzNiwgMzYzNTYsIDM2Mzc2LCAzNjM5OCwgMzY0MTgsIDM2NDM4LCAzNjQ1OCwgMzY0ODEsIDM2NTAxLCAzNjUyMSwgMzY1NDEsIDM2NTYxLCAzNjU4MSwgMzY2MDEsCiszNjYyMSwgMzY2NDMsIDM2NjYzLCAzNjY4MywgMzY3MDMsIDM2NzYzLCAzNjc4MywgMzY4MDQsIDM2ODMyLCAzNjg1MiwgMzY4NzUsIDM2ODk1LCAzNjkxNiwgMzY5MzcsIDM2OTU3LCAzNjk3OCwKKzM2OTk4LCAzNzAxOSwgMzcwMzksIDM3MDU5LCAzNzA3OSwgMzcwOTksIDM3MTE5LCAzNzE0MCwgMzcxNjAsIDM3MTgyLCAzNzIwMiwgMzcyMjQsIDM3MjQ4LCAzNzI3MywgMzcyOTMsIDM3MzEzLAorMzczMzMsIDM3MzUzLCAzNzM3MywgMzczOTMsIDM3NDEzLCAzNzQzMywgMzc0NTMsIDM3NDczLCAzNzQ5NCwgMzc1MTQsIDM3NTM2LCAzNzU1NiwgMzc1NzYsIDM3NTk3LCAzNzYxNywgMzc2MzgsCiszNzY1OCwgMzc2NzgsIDM3NzAyLCAzNzcyMiwgMzc3NDQsIDM3NzY4LCAzNzc4OSwgMzc4MDksIDM3ODMxLCAzNzg1MiwgMzc4NzcsIDM3ODk3LCAzNzkyMCwgMzc5NDEsIDM3OTYxLCAzNzk4MSwKKzM4MDAxLCAzODI2MywgMzgyODMsIDM4MzAzLCAzODMyNSwgMzgzNDUsIDM4MzY2LCAzODQyOCwgMzg0NDgsIDM4NDY4LCAzODQ4OCwgMzg1MDgsIDM4NTI4LCAzODU0OCwgMzg1NjgsIDM4NTg4LAorMzg2MTAsIDM4NjMyLCAzODY1MywgMzg2NzMsIDM4NjkzLCAzODcxMywgMzg3MzgsIDM4NzU4LCAzODc3OCwgMzg3OTgsIDM4ODE4LCAzODgzOCwgMzg4NTksIDM4ODc5LCAzODg5OSwgMzg5MTksCiszODkzOSwgMzg5NTksIDM4OTc5LCAzODk5OSwgMzkwMTksIDM5MDgwLCAzOTEwMCwgMzkxMzEsIDM5MTUxLCAzOTE3MSwgMzkxOTEsIDM5MjExLCAzOTIzMSwgMzkyNTEsIDM5MzE4LCAzOTMzOSwKKzM5MzYxLCAzOTM4MSwgMzk0MDEsIDM5NDIxLCAzOTQ0MSwgMzk0NjEsIDM5NDgxLCAzOTUwMSwgMzk1MjIsIDM5NTkyLCAzOTYxMiwgMzk2MzIsIDM5NjU0LCAzOTY3NCwgMzk2OTQsIDM5NzE0LAorMzk3MzUsIDM5NzU1LCAzOTc3NSwgMzk3OTYsIDM5ODE2LCAzOTgzOCwgMzk4NjEsIDM5ODgxLCAzOTkwMiwgMzk5MjcsIDM5OTQ3LCAzOTk2OSwgMzk5OTAsIDQwMDEwLCA0MDAzMCwgNDAwNTEsCis0MDE2NSwgNDAxODUsIDQwMjA4LCA0MDIyOSwgNDAyNTEsIDQwMjcxLCA0MDI5NSwgNDAzMTUsIDQwMzM2LCA0MDM1NiwgNDAzNzYsIDQwMzk2LCA0MDQxNywgNDA0MzcsIDQwNDU3LCA0MDQ3NywKKzQwNTY1LCA0MDU4NSwgNDA2MDUsIDQwNjI4LCA0MDY0OCwgNDA2NjgsIDQwNjg4LCA0MDcxMCwgNDA3MzAsIDQwNzUwLCA0MDc3MCwgNDA3OTAsIDQwODEwLCA0MDgzMCwgNDA4NTAsIDU3MzQ0LAorNTczNjQsIDU3Mzg0LCA1NzQwNCwgNTc0MjQsIDU3NDQ0LCA1NzQ2NCwgNTc0ODQsIDU3NTA0LCA1NzUyNCwgNTc1NDQsIDU3NTY0LCA1NzU4NCwgNTc2MDQsIDU3NjI0LCA1NzY0NCwgNTc2NjQsCis1NzY4NCwgNTc3MDQsIDU3NzI0LCA1Nzc0NCwgNTc3NjQsIDU3Nzg0LCA1NzgwNCwgNTc4MjQsIDU3ODQ0LCA1Nzg2NCwgNTc4ODQsIDU3OTA0LCA1NzkyNCwgNTc5NDQsIDU3OTY0LCA1Nzk4NCwKKzU4MDA0LCA1ODAyNCwgNTgwNDQsIDU4MDY0LCA1ODA4NCwgNTgxMDQsIDU4MTI0LCA1ODE0NCwgNTgxNjQsIDU4MTg0LCA1ODIwNCwgNTgyMjQsIDU4MjQ0LCA1ODI2NCwgNTgyODQsIDU4MzA0LAorNTgzMjQsIDU4MzQ0LCA1ODM2NCwgNTgzODQsIDU4NDA0LCA1ODQyNCwgNTg0NDQsIDU4NDY0LCA1ODQ4NCwgNTg1MDQsIDU4NTI0LCA1ODU0NCwgNTg1NjQsIDU4NTg0LCA1ODYwNCwgNTg2MjQsCis1ODY0NCwgNTg2NjQsIDU4Njg0LCA1ODcwNCwgNTg3MjQsIDU4NzQ0LCA1ODc2NCwgNTg3ODQsIDU4ODA0LCA1ODgyNCwgNTg4NDQsIDU4ODY0LCA1ODg4NCwgNTg5MDQsIDU4OTI0LCA1ODk0NCwKKzU4OTY0LCA1ODk4NCwgNTkwMDQsIDU5MDI0LCA1OTA0NCwgNTkwNjQsIDU5MDg0LCA1OTEwNCwgNTkxMjQsIDU5MTQ0LCA1OTE2NCwgNTkxODQsIDU5MjA0LCA1OTIyNCwgNTkyNDQsIDU5MjY0LAorNTkyODQsIDU5MzA0LCA1OTMyNCwgNTkzNDQsIDU5MzY0LCA1OTM4NCwgNTk0MDQsIDU5NDI0LCA1OTQ0NCwgNTk0NjQsIDU5NDg0LCA1OTUwNCwgNTk1MjQsIDU5NTQ0LCA1OTU2NCwgNTk1ODQsCis1OTYwNCwgNTk2MjQsIDU5NjQ0LCA1OTY2NCwgNTk2ODQsIDU5NzA0LCA1OTcyNCwgNTk3NDQsIDU5NzY0LCA1OTc4NCwgNTk4MDQsIDU5ODI0LCA1OTg0NCwgNTk4NjQsIDU5ODg0LCA1OTkwNCwKKzU5OTI0LCA1OTk0NCwgNTk5NjQsIDU5OTg0LCA2MDAwNCwgNjAwMjQsIDYwMDQ0LCA2MDA2NCwgNjAwODQsIDYwMTA0LCA2MDEyNCwgNjAxNDQsIDYwMTY0LCA2MDE4NCwgNjAyMDQsIDYwMjI0LAorNjAyNDQsIDYwMjY0LCA2MDI4NCwgNjAzMDQsIDYwMzI0LCA2MDM0NCwgNjAzNjQsIDYwMzg0LCA2MDQwNCwgNjA0MjQsIDYwNDQ0LCA2MDQ2NCwgNjA0ODQsIDYwNTA0LCA2MDUyNCwgNjA1NDQsCis2MDU2NCwgNjA1ODQsIDYwNjA0LCA2MDYyNCwgNjA2NDQsIDYwNjY0LCA2MDY4NCwgNjA3MDQsIDYwNzI0LCA2MDc0NCwgNjA3NjQsIDYwNzg0LCA2MDgwNCwgNjA4MjQsIDYwODQ0LCA2MDg2NCwKKzYwODg0LCA2MDkwNCwgNjA5MjQsIDYwOTQ0LCA2MDk2NCwgNjA5ODQsIDYxMDA0LCA2MTAyNCwgNjEwNDQsIDYxMDY0LCA2MTA4NCwgNjExMDQsIDYxMTI0LCA2MTE0NCwgNjExNjQsIDYxMTg0LAorNjEyMDQsIDYxMjI0LCA2MTI0NCwgNjEyNjQsIDYxMjg0LCA2MTMwNCwgNjEzMjQsIDYxMzQ0LCA2MTM2NCwgNjEzODQsIDYxNDA0LCA2MTQyNCwgNjE0NDQsIDYxNDY0LCA2MTQ4NCwgNjE1MDQsCis2MTUyNCwgNjE1NDQsIDYxNTY0LCA2MTU4NCwgNjE2MDQsIDYxNjI0LCA2MTY0NCwgNjE2NjQsIDYxNjg0LCA2MTcwNCwgNjE3MjQsIDYxNzQ0LCA2MTc2NCwgNjE3ODQsIDYxODA0LCA2MTgyNCwKKzYxODQ0LCA2MTg2NCwgNjE4ODQsIDYxOTA0LCA2MTkyNCwgNjE5NDQsIDYxOTY0LCA2MTk4NCwgNjIwMDQsIDYyMDI0LCA2MjA0NCwgNjIwNjQsIDYyMDg0LCA2MjEwNCwgNjIxMjQsIDYyMTQ0LAorNjIxNjQsIDYyMTg0LCA2MjIwNCwgNjIyMjQsIDYyMjQ0LCA2MjI2NCwgNjIyODQsIDYyMzA0LCA2MjMyNCwgNjIzNDQsIDYyMzY0LCA2MjM4NCwgNjI0MDQsIDYyNDI0LCA2MjQ0NCwgNjI0NjQsCis2MjQ4NCwgNjI1MDQsIDYyNTI0LCA2MjU0NCwgNjI1NjQsIDYyNTg0LCA2MjYwNCwgNjI2MjQsIDYyNjQ0LCA2MjY2NCwgNjI2ODQsIDYyNzA0LCA2MjcyNCwgNjI3NDQsIDYyNzY0LCA2Mjc4NCwKKzYyODA0LCA2MjgyNCwgNjI4NDQsIDYyODY0LCA2Mjg4NCwgNjI5MDQsIDYyOTI0LCA2Mjk0NCwgNjI5NjQsIDYyOTg0LCA2MzAwNCwgNjMwMjQsIDYzMDQ0LCA2MzA2NCwgNjMwODQsIDYzMTA0LAorNjMxMjQsIDYzMTQ0LCA2MzE2NCwgNjMxODQsIDYzMjA0LCA2MzIyNCwgNjMyNDQsIDYzMjY0LCA2MzI4NCwgNjMzMDQsIDYzMzI0LCA2MzM0NCwgNjMzNjQsIDYzMzg0LCA2MzQwNCwgNjM0MjQsCis2MzQ0NCwgNjM0NjQsIDYzNDg0LCA2MzUwNCwgNjM1MjQsIDYzNTQ0LCA2MzczNiwgNjQwMTIsIDY1MDcyLCA2NTA5MiwgNjUxMTMsIDY1MjgxLCA2NTMwMSwgNjUzMjEsIDY1MzQzLCA2NTM2MywKKzY1NTA0CisgICAgICAgICAgICB9KTsKKworICAgICAgICB0ZXN0Qnl0ZXMgPSB0aGVzZUJ5dGVzKG5ldyBpbnRbXXsKKzAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKzMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCis2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKzgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisxMjgsIDE2MSwgMTc3LCAxNjEsIDE5NCwgMTYyLCA4OCwgMTYxLCAyMTEsIDE2MSwgODAsIDE2MSwgMjA5LCAxNjEsIDIxMCwgMTYzLAorMTkwLCAxNjMsIDE4OCwgMTYzLCA2OCwgMTYzLCA4NywgMTYzLCAxMDAsIDE2MSwgODYsIDE2MSwgNjksIDE2MSwgMTc2LCAxNjMsCisyMjUsIDE2MiwgNzQsIDE2MiwgMTg1LCAxNjEsIDI0NiwgMTYyLCA2NSwgMTYxLCAyMjgsIDE2MSwgMjIwLCAxNjEsIDIxNiwgMTYxLAorMjQyLCAxNjEsIDIzMywgMTYyLCAxMTksIDE2MiwgMTI0LCAxNjIsIDExNSwgMjQ5LCAyNDksIDI0OSwgMjMxLCAxNjIsIDk4LCAxNjIsCisxMjEsIDE2MSwgMTgyLCAxNjEsIDE4NywgMTYyLCAxNjgsIDE2MSwgMTg1LCAxNjEsIDI0MCwgMTYxLCA2NCwgMTYxLCAxMDEsIDE2MiwKKzIwMiwgMTYzLCAxMTYsIDE2MywgMTcwLCAxNjEsIDE5MiwgMTYyLCA4NSwgMTYyLCA4NywgMTY0LCA2NCwgMTY1LCA2NiwgMTY0LAorODgsIDIwMSwgNjQsIDE2OCwgMTk2LCAxNjgsIDE5NywgMTY0LCAxNjksIDE2OCwgMjAwLCAxNzMsIDE4OSwgMTY0LCAxNzksIDIwMSwKKzEwMiwgMTY1LCAyNDUsIDIwMSwgMTg1LCAyMDEsIDE3MiwgMjAxLCAxNzMsIDIwMiwgMTAwLCAxNjYsIDI0MywgMTY4LCAyMTYsIDIwMywKKzE4MSwgMTY4LCAyMjEsIDE3MSwgODYsIDE3MSwgODksIDIwNSwgMjM1LCAyMDUsIDIzOSwgMTczLCAyMDYsIDE3MywgMjA3LCAxNzMsCisyMDgsIDE3MywgMjAwLCAyMTIsIDEwMywgMTc2LCAxODMsIDE3NiwgMTc1LCAyMTYsIDg5LCAxNzksIDE5NSwgMjIwLCAxOTUsIDIyMCwKKzE4NSwgMjI0LCAyNTQsIDE4NywgMjQ4LCAxODcsIDI1MiwgMTkyLCAxMTgsIDE5NSwgOTUsIDE2NSwgMjUxLCAxNjIsIDkwLCAxNjYsCis2NCwgMjAxLCA3OCwgMjAzLCAyMDUsIDE2NywgNzcsIDIwOCwgMjI1LCAyMzIsIDI0OSwgMTg1LCAxODUsIDE2NCwgMTkzLCAyMDIsCisxMDgsIDE2OCwgMjM2LCAyMDUsIDI0MCwgMjA4LCAyMzEsIDIxMiwgMTA4LCAxODUsIDE4NywgMjQxLCAyMzcsIDE2NywgODYsIDE2OCwKKzI0MCwgMTc2LCAxOTksIDE4MiwgMjExLCAxNjQsIDk5LCAyMDgsIDIzOCwgMjAxLCAxOTMsIDI0MywgMjUzLCAyMDEsIDEwOSwgMTY1LAorMTAxLCAxNjcsIDkwLCAyMDEsIDE5NiwgMjA4LCAyMzksIDE4OCwgNzAsIDE2NCwgODMsIDE3MywgMjM4LCAxNjUsIDEwNywgMjAxLAorMTk3LCAxNjcsIDEwMywgMjAyLCAxMTgsIDIwMiwgMTIyLCAyMDMsIDIzNSwgMjAzLCAyMzAsIDIwMywgMjI0LCAyMDYsIDcyLCAyMDYsCis2OSwgMTcxLCAxMTcsIDIwOCwgMjQxLCAyMDksIDY2LCAyMDksIDcxLCAyMDgsIDI0MCwgMjEyLCAxNjgsIDE3NiwgMjIxLCAxNzYsCisyMjksIDIxNiwgMTA2LCAxNzksIDIyNywgMTc5LCAyMzEsIDE3OSwgMjI5LCAxODIsIDIyMiwgMjIwLCAyMDMsIDE4MiwgMjI2LCAyMjUsCis4MywgMTg1LCAxOTIsIDE4OCwgODMsIDIxNiwgMTA3LCAxOTAsIDE3OCwgMjMzLCA2NywgMjM2LCAyMDEsIDE5NCwgODAsIDI0MSwKKzI0NCwgMjQ1LCAxOTgsIDI0OCwgMTY1LCAyMDIsIDE2OCwgMTcxLCAxNzAsIDE4MiwgMjM0LCAxNjYsIDk4LCAxNjcsIDE2MywgMjAyLAorMTc1LCAxNjksIDkwLCAyMDMsIDI1MSwgMjA2LCA5MCwgMTcxLCAxNzQsIDIwOSwgODIsIDIwOSwgNzQsIDE3NiwgMjQwLCAyMTIsCisxNzgsIDIxMiwgMTgyLCAyMTYsIDE2OSwgMTc5LCAyNDcsIDIxNiwgMTY3LCAyMjAsIDIzNSwgMjIwLCAyNDEsIDE4NSwgMjE0LCAxODgsCis4OSwgMjI5LCA3NiwgMTkwLCAxOTUsIDE5NCwgODIsIDE2NywgMTY3LCAyMDEsIDkwLCAyMDEsIDExMiwgMTY0LCAyMTAsIDIwMiwKKzE3NywgMTY5LCA5OCwgMTg1LCAyMjEsIDE2NiwgMTEwLCAxNjcsIDE3MCwgMjAyLCAxNzgsIDIwNCwgNjksIDIwNCwgNzEsIDE3MSwKKzE4NywgMjA2LCAxMTAsIDE3NCwgOTEsIDE3NCwgODcsIDIxMiwgMjEyLCAxNzYsIDI1MSwgMjEyLCAyMjIsIDE4MCwgNjQsIDIxNiwKKzE5OSwgMjE2LCAxODMsIDE4MywgNjQsIDIyMCwgMjQzLCAyMjUsIDExOCwgMjI1LCAxMTUsIDIyOSwgOTQsIDIzMywgODMsIDIzNiwKKzIxMywgMTk2LCA5MywgMTY2LCAxMTQsIDE3NCwgOTMsIDE5NywgMTEyLCAyMDQsIDg3LCAyMDksIDEwMiwgMTc3LCA3NCwgMTgwLAorNzQsIDE4NSwgMjMxLCAxNzEsIDIwMiwgMjAxLCAyMTIsIDIwMiwgMTkxLCAxNjcsIDE5MiwgMjA5LCAxMDcsIDE5MiwgMTcxLCAyMDEsCisyMTQsIDE2NywgMTkzLCAyMDQsIDkyLCAxNjksIDE2NCwgMjA2LCAxMjMsIDE3NCwgMTExLCAxNzQsIDEwOCwgMTc3LCA4OCwgMjEyLAorMjUzLCAyMTYsIDIzNCwgMjE2LCAyMjUsIDIyMSwgODYsIDIyNSwgMTY5LCAyMjUsIDE3NSwgMjI5LCAxMDcsIDIzMywgOTgsIDE5NiwKKzk2LCAxNjQsIDExNiwgMTY0LCAxMTgsIDE2NiwgMTI0LCAxNjksIDE3MCwgMTc3LCA5OCwgMjIxLCA5MCwgMTg4LCAxMDksIDE2NSwKKzE3MywgMTY3LCAyMDAsIDIwNiwgMTg0LCAyMDYsIDE4MSwgMTgwLCA5MiwgMjI1LCAxODEsIDE5NSwgMTAyLCAxNjUsIDE3NSwgMTY0LAorMjIyLCAxNjksIDE4NCwgMjIxLCA5OCwgMjA0LCAxMTYsIDE3NywgMTA5LCAyMDQsIDExOSwgMTc0LCAxMjQsIDIxNiwgMjQ2LCAxODUsCisyNTMsIDE2NywgMjEyLCAyMDIsIDIyMSwgMTY5LCAxOTIsIDIwNCwgMTc1LCAxNzEsIDIyOCwgMjA0LCAxMjUsIDE3MSwgMjM3LCAyMDksCisxMjUsIDIwNiwgMjA5LCAyMDksIDE2OCwgMjA5LCAxNzEsIDIxMywgODUsIDIxNiwgMjUzLCAxNzcsIDE2NiwgMTgwLCAxMDcsIDIxNywKKzc5LCAyMTcsIDc1LCAyMjUsIDE5NCwgMjIxLCAxMTMsIDIyNSwgMjA2LCAxODAsIDExMCwgMTg4LCAxNjEsIDE4OCwgMTY2LCAxODgsCisxNzEsIDIzMywgMTYyLCAyMzMsIDEyNSwgMjM2LCAyMjcsIDE5NSwgMTA2LCAyMDEsIDEyNCwgMTgwLCAxMTcsIDE5NCwgODcsIDE3NCwKKzE3NiwgMTY2LCAxNzAsIDE2NywgMjMyLCAyMDIsIDIzMSwgMTY3LCAyMjAsIDE2OSwgMjIwLCAxNjksIDIxNSwgMTY5LCAyMjEsIDIwNiwKKzIxOCwgMTc0LCAxNzksIDIwNiwgMjI1LCAxNzQsIDE5MywgMjA5LCAxODksIDE3NCwgMTg5LCAyMTMsIDEwMywgMTc3LCAyMDQsIDIxMywKKzExMywgMTc3LCAxODAsIDIxMywgMTA3LCAxODAsIDE2MSwgMjIxLCAxODMsIDE4MywgMTEyLCAyMjEsIDE3OCwgMjIxLCAxODUsIDIyMSwKKzE2MiwgMTg2LCA3NSwgMjI1LCAyMzksIDIyNSwgMjMwLCAyMjksIDE3NSwgMTg4LCAxOTAsIDE5MCwgMjIzLCAxOTAsIDIyNSwgMjM2LAorMjM3LCAyMzksIDIxNSwgMjQyLCA2NywgMTk3LCAxMTcsIDE2NywgMjQxLCAxNzcsIDIxMSwgMTgwLCAxNzgsIDE4OCwgMTk3LCAyMTcsCisxMjEsIDIyNSwgMjQ1LCAyMzYsIDI0MCwgMTc3LCAyMTksIDI0NCwgNzksIDIwMiwgMjUwLCAxNzAsIDY0LCAyMDYsIDIzOSwgMTcyLAorODIsIDE3NCwgMjA3LCAyMTMsIDE3MiwgMTgwLCAxODIsIDE4MywgMTIxLCAxODMsIDEyMiwgMTg4LCAxOTksIDE5MCwgMjMxLCAyMzksCisyMjAsIDE5NywgMjA2LCAxNzksIDIwNCwgMTc0LCAyMTAsIDE2NCwgMjM2LCAyMDEsIDI0NSwgMTY3LCAyNDcsIDE3MCwgODcsIDE3MCwKKzgxLCAyMDQsIDIxNCwgMjA3LCA5MSwgMjA3LCA4MSwgMjA3LCA2NywgMTcyLCA5MCwgMjA5LCAyMzYsIDIwOSwgMjM4LCAyMDksCisyNDIsIDIwOSwgMjMyLCAyMTMsIDE5NiwgMTc3LCAyMzYsIDE3NywgMjM0LCAxNzcsIDIzOSwgMTc3LCAyNDMsIDE4MCwgMTk4LCAyMTcsCisxNzUsIDIxNywgMTcyLCAyMTcsIDIxNiwgMjIxLCAyMTAsIDIyMSwgMjA0LCAyMjEsIDIwNSwgMjIxLCAyMjksIDIyNiwgNzQsIDIyNiwKKzkwLCAyMjYsIDk2LCAyMjUsIDI1NCwgMjI5LCAyMTMsIDIyOSwgMjM1LCAxODgsIDIxMiwgMTg4LCAyMDcsIDIzMywgMTk0LCAyMzMsCisyMjEsIDIzMywgMjAzLCAyMzMsIDIxMiwgMjM3LCA2NSwgMTkyLCAyMDgsIDE5NCwgOTksIDE5NCwgMTAzLCAyNDIsIDgwLCAyNDQsCis4OSwgMjQ1LCAyMDYsIDE5OCwgODYsIDIwOSwgMjQ1LCAyMjEsIDI1MCwgMjMzLCAyMjIsIDE3MiwgMTEwLCAyMDQsIDIzNSwgMjE3LAorMjIyLCAyMzMsIDIyNiwgMTgzLCAxODEsIDE4MywgMTgyLCAyMTAsIDY3LCAyMjEsIDI1MywgMTY0LCAyNDMsIDE3NCwgMjQwLCAxNjUsCisxOTUsIDIwMiwgNjQsIDE2NiwgMTkyLCAxNjgsIDg4LCAxNjgsIDcyLCAyMDMsIDg4LCAyMDUsIDc1LCAxNzAsIDExMCwgMjA0LAorMjQyLCAyMDQsIDI1MywgMjA3LCAxNjEsIDIxMCwgMTAwLCAxNzIsIDEyMCwgMTcyLCAxNjMsIDIxMCwgNzYsIDE3NSwgNjQsIDIxMCwKKzk4LCAxNzUsIDc1LCAxNzgsIDEwMSwgMjEzLCAyNDAsIDE3OCwgODksIDE3OCwgMTA0LCAxNzgsIDc2LCAxODEsIDY1LCAxODAsCisyNDQsIDIxNywgMjQzLCAyMTgsIDgxLCAxODEsIDcwLCAyMTcsIDIzNiwgMTgzLCAyMDAsIDIyMiwgODUsIDE4MywgMjAxLCAyMjIsCis5MywgMTg2LCAxNzMsIDIzMCwgODMsIDE4NiwgMTE2LCAxODYsIDEyMCwgMTg2LCAxMjEsIDIzMCwgNzcsIDE4OCwgMjI3LCAxODgsCisyMzUsIDE4OCwgMjM0LCAyMzQsIDY0LCAxOTEsIDcxLCAyMzMsIDI0NCwgMjM3LCA4NywgMjM3LCA4OCwgMTk0LCAxMTIsIDE5NSwKKzExOCwgMjQ0LCA5MywgMjQ1LCAyMTEsIDI0NiwgMjM0LCAxNjQsIDI0NSwgMjA1LCA4OCwgMjA1LCA4NywgMTcyLCAxNzUsIDIxMCwKKzExOSwgMTc1LCA3OSwgMTc4LCAxMDksIDIxNCwgNzksIDE4MSwgNzIsIDIxOCwgOTIsIDIyMiwgMTE5LCAxODMsIDIyMCwgMjIyLAorMTE3LCAyMjYsIDE4OSwgMTg2LCAxNzgsIDE4OCwgMjQ3LCAyMzQsIDg1LCAxOTEsIDc3LCAyMzcsIDk2LCAxOTQsIDExOSwgMjQyLAorMTA1LCAyNDcsIDIzMCwgMTY0LCAyNDcsIDIwNywgMTg1LCAyMDIsIDY2LCAxNzIsIDE4NSwgMjE4LCAxMDYsIDIzMCwgMTE2LCAyMDEsCisxNjUsIDE2OCwgMTAzLCAyMDUsIDkyLCAyMDcsIDE5NSwgMjEwLCAxNjYsIDIxOCwgMTA5LCAyMTgsIDExOCwgMjIyLCAxNzMsIDE4OCwKKzI1MCwgMjMwLCAxNjEsIDIzOSwgMjU0LCAyMDEsIDE2NywgMTcwLCAxNzksIDE3MiwgMTk3LCAyMDcsIDIwOSwgMjEwLCAxODEsIDIxNCwKKzEyMCwgMjE0LCAxMjEsIDIxOCwgMTY3LCAyMTgsIDE2NCwgMjIyLCAxODgsIDE4MywgMjI4LCAyMjYsIDIxMiwgMTg4LCAyNTQsIDIzNywKKzEwMiwgMjM3LCAxMDQsIDE5NCwgMTIzLCAxOTYsIDIzNywgMjA1LCAxMTEsIDIyMiwgMTk0LCAyMzcsIDExMiwgMTgxLCA5OSwgMjAzLAorMTEwLCAxNzIsIDIwMiwgMTc4LCAxNjYsIDE4MywgMjM3LCAxOTcsIDEyNCwgMTcyLCAyMDcsIDIxMCwgMjAxLCAxNzgsIDE3MiwgMTgxLAorMTA4LCAxODMsIDI0MiwgMjI2LCAyMTksIDIzMCwgMTc5LCAyMzQsIDExNSwgMTkyLCAyNDcsIDI0MCwgODAsIDE5NywgMTI1LCAxNjgsCisxMDksIDE4MSwgMTEyLCAyNDQsIDExMywgMjQ0LCAxMTQsIDE3OCwgMTc2LCAyMzQsIDExNywgMjA3LCAyMzEsIDIxMCwgMjA3LCAyMTQsCisxNzYsIDIxNCwgMTY4LCAyMTgsIDE4OSwgMTg2LCAyMDYsIDE4NCwgNjQsIDIzMCwgMTg4LCAyMzQsIDEyMCwgMjM3LCAxMjIsIDI0MiwKKzEyMSwgMjE4LCAxOTUsIDI0NCwgMTIwLCAyMDcsIDIzNCwgMTc1LCAxMjQsIDIxMCwgMjI5LCAyMTQsIDE4NiwgMjE4LCAyMDAsIDIxOCwKKzIwNSwgMjIyLCAyMzIsIDE4NCwgNzUsIDIyNiwgMjQ1LCAxODYsIDIwNywgMTg5LCA4NywgMjM0LCAxNjMsIDIzNywgMTY2LCAyNDAsCis5MywgMjQ0LCAxMjEsIDI0OCwgMjUwLCAyMTAsIDIzMiwgMjE0LCAxOTIsIDIyMiwgMjQ2LCAxODYsIDIxNSwgMjMwLCAyMDQsIDI0OCwKKzE4MywgMTcyLCAyMzgsIDE3NSwgMTc4LCAyMTQsIDE5OCwgMjE4LCAyMTUsIDE4NCwgOTIsIDE4OSwgOTQsIDE5MSwgMTE0LCAyNDAsCis5NiwgMTY1LCAyMjIsIDE3NSwgMTgzLCAyMjMsIDY4LCAyMzAsIDIxMSwgMTk2LCAxMTcsIDE3OSwgMTg2LCAxOTYsIDExOCwgMjExLAorNjksIDE3OCwgMTk5LCAyMTQsIDIxOCwgMTgxLCAxNjcsIDE4NCwgOTcsIDIyMywgNzMsIDIyNywgNzgsIDIyNywgNzksIDE4OSwKKzk5LCAxODksIDEwMiwgMjM0LCAxODksIDIzNywgMjAzLCAyMzcsIDE4NiwgMjQwLCA5OSwgMjQwLCAxMDIsIDE5NiwgMTIwLCAyNDYsCisyNTAsIDI0OCwgMjUyLCAyMDgsIDcxLCAyMTQsIDIyMiwgMjE4LCAyMzMsIDIyNywgOTYsIDIzNCwgMjAyLCAxOTQsIDE3OSwgMTY4LAorMTE2LCAyMTEsIDg5LCAyMTQsIDI0MCwgMTc4LCAyMDksIDE4MSwgMTc4LCAxODEsIDE4NSwgMjIzLCA5MywgMjIzLCA5NCwgMTg2LAorMjQ3LCAyMjcsIDk5LCAyMjcsIDExMCwgMjMwLCAyNDAsIDIyOSwgMTE0LCAxOTEsIDE2MiwgMjM0LCAyMTIsIDIzNywgMjIwLCAyMzcsCisyMjMsIDI0MCwgMTEzLCAxOTUsIDE4MSwgMjQ0LCAxNzQsIDI0NywgMjM4LCAxNjYsIDIwNiwgMjQyLCAxODYsIDIxMSwgOTMsIDE4NCwKKzExMiwgMjQyLCAxODgsIDE3OCwgMjIwLCAxODksIDEyNiwgMjExLCA5OSwgMjE5LCA2OCwgMjMwLCAyNDYsIDI0NCwgMTc3LCAyMDgsCis4NCwgMTkxLCAxNzQsIDE3NSwgMjEyLCAyMTksIDY5LCAyMzAsIDI1MiwgMTk3LCAxNjUsIDIwMywgMTE5LCAxNzAsIDIxMSwgMjA4LAorOTEsIDE3MywgNjgsIDE3NSwgMjE4LCAyMTEsIDEwOSwgMjE1LCA3OCwgMTc4LCAyMzEsIDIxOSwgNzksIDE4MSwgMTk4LCAxODQsCisxMjMsIDE4NCwgMTYxLCAyMjcsIDE2OCwgMjMxLCA2NiwgMjM0LCAyNDIsIDIzNywgMjM0LCAyNDksIDY3LCAxNzMsIDgwLCAxOTEsCisxNzksIDE4MSwgMjA3LCAyMTUsIDg3LCAxODQsIDE2NSwgMjM3LCAyNDAsIDE2OCwgMTI1LCAyMDMsIDE2MiwgMjA1LCAxODIsIDE3MCwKKzIyNiwgMjA1LCAxNzksIDE3MywgOTcsIDIwOCwgMTExLCAyMDgsIDEwOCwgMjExLCAxNjgsIDIxMSwgMTY0LCAyMTEsIDEyMiwgMjExLAorMTc3LCAyMTUsIDk0LCAyMTUsIDExOSwgMjE1LCAxMDgsIDIxNSwgMTEzLCAyMTksIDE2NywgMjE5LCAxNzIsIDIxOSwgMTA2LCAyMTksCisxMTMsIDIxOSwgMTY2LCAyMjMsIDE5OSwgMTg0LCAxNjgsIDIyMywgMTc3LCAyMjMsIDE3NiwgMjIzLCAxNzMsIDIyMywgMTc1LCAyMjcsCisxNzQsIDIyNywgMjAzLCAxODcsIDk5LCAyMzEsIDExNSwgMjMxLCA4OCwgMjMxLCA3OCwgMTg5LCAxNzcsIDIzMSwgNzcsIDIzNSwKKzcwLCAyMzUsIDg2LCAyMzgsIDgyLCAyMzgsIDc0LCAyMzgsIDY3LCAyNDAsIDE3MCwgMTk0LCAxOTksIDE5NSwgMTkyLCAyNDIsCisxOTksIDI0NCwgMTkzLCAyNDUsIDI0NywgMTk2LCAyNDUsIDI0OCwgMTg4LCAyMTUsIDEyMywgMjA1LCAyMDEsIDIxMSwgMTk2LCAyMTEsCisxOTgsIDE3OSwgNzYsIDIxNSwgMTc0LCAyMTksIDE4OSwgMjE5LCAxODUsIDE4NCwgMTkwLCAxODcsIDEwNiwgMjI3LCAyMjQsIDIyNywKKzIxNywgMjMxLCAxNjgsIDE4OSwgMTkwLCAyMzUsIDk3LCAyMzUsIDk4LCAyMzgsIDg5LCAyMzgsIDg4LCAxOTMsIDE3NSwgMjQwLAorMTg4LCAyNDIsIDIyMCwgMjQ0LCAxOTcsIDI0NiwgNjgsIDI0OCwgMTg5LCAxNjYsIDIzMCwgMTkxLCAxOTcsIDIxMSwgMjEwLCAyMTUsCisxNzgsIDE3OSwgNzksIDIxOSwgMjA1LCAyMTksIDIwNywgMTg0LCAyMDMsIDIyNywgMjQ3LCAyMzEsIDE5NCwgMjMxLCAyMDAsIDIzNSwKKzExNSwgMjM4LCAxMTcsIDE5NSwgMjA1LCAxOTYsIDI1MSwgMjAyLCA4MCwgMTc5LCA4NiwgMTkxLCAyMDMsIDI0NywgODQsIDE2OCwKKzE2NCwgMjI0LCA2OCwgMjQ2LCA3NiwgMTc2LCA4MSwgMTc5LCA5NiwgMTgyLCA3MCwgMjE5LCAyMjYsIDE4MSwgMjUyLCAxODQsCisyMTEsIDIyNCwgNzAsIDE4NywgMTY2LCAxODksIDIxNCwgMTg5LCAyMDYsIDIzMSwgMjI0LCAxOTEsIDIxNywgMTkxLCAyMTQsIDIzOCwKKzE2OSwgMjQwLCAyMTgsIDI0MCwgMjI3LCAyNDMsIDY2LCAxOTYsIDE4MSwgMjQ2LCA4MCwgMjQ4LCA2NSwgMTY4LCAxNjYsIDIyNCwKKzgzLCAyMTksIDIyOSwgMTkzLCAxOTksIDE4NCwgMjMyLCAxNjgsIDE2OSwgMTg0LCAyMzcsIDE4NCwgMjM0LCAxODksIDIzMSwgMjM1LAorMTgzLCAyNDAsIDI0NCwgMjQ4LCA2OSwgMTY4LCAxNzAsIDIxMSwgMjI4LCAyMjQsIDk1LCAyMzEsIDIzOSwgMTczLCAxMTksIDIxOSwKKzI0OSwgMjE5LCAyNDUsIDIyNCwgMTAzLCAyMjgsIDk5LCAyMzIsIDY2LCAyMzEsIDI0NywgMTkxLCAyMjgsIDI0MCwgMjUxLCAyNDMsCis4MiwgMTk2LCAxODgsIDI0NywgOTMsIDI0OSwgMTcxLCAyMzUsIDIwMCwgMjExLCAyMzIsIDIyMCwgNjcsIDIyMCwgNjQsIDIyOCwKKzEwMywgMjMyLCA3NiwgMjM1LCAyMDYsIDI0MSwgNzMsIDE5NywgNzAsIDE2OCwgMTc1LCAxOTcsIDcxLCAxNjgsIDE4MCwgMjA4LAorMTgyLCAxNzYsIDEwNiwgMjE1LCAyMjcsIDE3OSwgMTE2LCAyMjAsIDc4LCAyMjQsIDE2MiwgMTg3LCAxOTAsIDE5MSwgMjQwLCAyMzUsCisyMTEsIDIwMiwgODQsIDIwNSwgMjEzLCAxNzMsIDE2OCwgMjExLCAyNTEsIDIxNSwgMjM5LCAyMjAsIDgzLCAyMjQsIDE2OSwgMjQxLAorNzQsIDI0MSwgNzcsIDE3NiwgMTE1LCAyMjEsIDExNSwgMjMyLCA5NywgMjM4LCAyMDAsIDI0MywgOTUsIDE5OCwgOTMsIDIxMiwKKzY2LCAxNzksIDE3MSwgMjIwLCAxMDksIDE4MiwgMTIyLCAyMjAsIDEwMCwgMTg1LCAxMDEsIDE4NSwgOTksIDIyNCwgMTkzLCAyMjgsCisxMjAsIDIyOCwgMTc2LCAyMjgsIDEyMywgMjMyLCAxNjQsIDIzMiwgMTE2LCAyMzIsIDExMCwgMjMyLCAxMDUsIDIzNSwgMjI1LCAxOTEsCisyNTQsIDE5MiwgNjgsIDIzNSwgMjM0LCAxOTMsIDIzNywgMTkzLCAyMzYsIDI0MSwgOTYsIDI0MSwgODgsIDI0MSwgMTAwLCAyNDMsCis5NywgMTk1LCAyMzcsIDI0NCwgMjQzLCAyNDQsIDI1MSwgMjQ0LCAyMzQsIDE5NywgNzUsIDI0NywgMTExLCAyNDgsIDc2LCAyNDksCis4NSwgMTcwLCAyNDgsIDE4MiwgMTI1LCAyMjQsIDIwNSwgMjM2LCA3NywgMjM4LCAyNDAsIDI0NSwgNjksIDE3MCwgMjUwLCAyMDMsCisxNzMsIDE3MCwgMjU0LCAxNzYsIDE2NCwgMTc5LCAxODEsIDIyMCwgMTYzLCAxODUsIDEwNiwgMTkyLCA3MiwgMjEyLCA3MSwgMTg3LAorMjIwLCAxNzEsIDY2LCAyMjQsIDIxNSwgMTkyLCA3NiwgMjQxLCAxMjAsIDE5NywgODIsIDE3MSwgNjcsIDE5MiwgODMsIDIyOCwKKzE5MiwgMjMyLCAxNzgsIDI0MSwgMTYxLCAyNDMsIDE2MywgMTczLCAxNzksIDI0MywgMTY2LCAxNzMsIDE4MSwgMjIwLCAxNzIsIDIzMiwKKzE4OCwgMjM2LCA5MCwgMjM5LCA3NCwgMjQzLCAxNzAsIDE5NywgMTg0LCAxNzMsIDE4MywgMTk2LCA2NiwgMTczLCAxODQsIDE4MiwKKzE4NiwgMTg3LCAyMjksIDIzMiwgMTk2LCAyMzksIDc2LCAxOTUsIDczLCAyNDUsIDg5LCAxNzMsIDE4NiwgMjQ5LCAxNzgsIDE4NywKKzIzMywgMTkwLCAxMTQsIDIzNiwgMTA0LCAyMzksIDk2LCAyNDEsIDE4MCwgMjQzLCAxODIsIDI0NiwgMTIwLCAxOTcsIDE4NywgMTk4LAorMTA2LCAxNzYsIDE2OSwgMTkyLCAxMDIsIDI0NywgMTY0LCAxODcsIDIzNiwgMjM2LCAxMTEsIDI0MywgMTk2LCAxOTgsIDc1LCAyNDMsCisxOTgsIDI0MSwgMTk0LCAyMjgsIDIyNSwgMjMyLCAyMTksIDIzNiwgMTYyLCAyMzksIDEwOCwgMjQxLCAyMDAsIDE5NSwgODUsIDI0MywKKzIwMiwgMjQ1LCAxMDgsIDI0NSwgMTA2LCAyNDYsIDE3NywgMjQ3LCAxODIsIDI0OCwgOTAsIDI0OCwgMjE4LCAyNDksIDEyMCwgMTc5LAorMTkwLCAyMzIsIDIzNSwgMjM2LCAxNzIsIDIzNiwgMTYzLCAxOTQsIDY5LCAyNDEsIDIwOSwgMjM5LCAxMjAsIDI0MywgMjM1LCAyNDUsCisxMjUsIDI0NSwgMTIxLCAxOTcsIDEwMCwgMjQ2LCAxOTcsIDI0OCwgMTA1LCAyNDcsIDE5NiwgMjQ4LCAyMjgsIDI0OSwgMjA3LCAxNzksCisxOTEsIDIzOSwgMTcxLCAxOTcsIDEwMSwgMTk2LCA4NCwgMjM5LCAxNzQsIDE5NCwgNzQsIDI0NywgMjAwLCAyNDgsIDEyMCwgMjQ2LAorMjA4LCAyNDUsIDE4NSwgMjQ3LCAyMDQsIDI0MywgMjUwLCAxOTcsIDE5OCwgMjQ5LCAyMTEsIDI0NiwgMjEzLCAyNTAsIDY0LCAyNTAsCis4NCwgMjUwLCAxMDQsIDI1MCwgMTI0LCAyNTAsIDE3OCwgMjUwLCAxOTgsIDI1MCwgMjE4LCAyNTAsIDIzOCwgMjUxLCA2NywgMjUxLAorODcsIDI1MSwgMTA3LCAyNTEsIDE2MSwgMjUxLCAxODEsIDI1MSwgMjAxLCAyNTEsIDIyMSwgMjUxLCAyNDEsIDI1MiwgNzAsIDI1MiwKKzkwLCAyNTIsIDExMCwgMjUyLCAxNjQsIDI1MiwgMTg0LCAyNTIsIDIwNCwgMjUyLCAyMjQsIDI1MiwgMjQ0LCAyNTMsIDczLCAyNTMsCis5MywgMjUzLCAxMTMsIDI1MywgMTY3LCAyNTMsIDE4NywgMjUzLCAyMDcsIDI1MywgMjI3LCAyNTMsIDI0NywgMjU0LCA3NiwgMjU0LAorOTYsIDI1NCwgMTE2LCAyNTQsIDE3MCwgMjU0LCAxOTAsIDI1NCwgMjEwLCAyNTQsIDIzMCwgMjU0LCAyNTAsIDE0MiwgNzksIDE0MiwKKzk5LCAxNDIsIDExOSwgMTQyLCAxNzMsIDE0MiwgMTkzLCAxNDIsIDIxMywgMTQyLCAyMzMsIDE0MiwgMjUzLCAxNDMsIDgyLCAxNDMsCisxMDIsIDE0MywgMTIyLCAxNDMsIDE3NiwgMTQzLCAxOTYsIDE0MywgMjE2LCAxNDMsIDIzNiwgMTQ0LCA2NSwgMTQ0LCA4NSwgMTQ0LAorMTA1LCAxNDQsIDEyNSwgMTQ0LCAxNzksIDE0NCwgMTk5LCAxNDQsIDIxOSwgMTQ0LCAyMzksIDE0NSwgNjgsIDE0NSwgODgsIDE0NSwKKzEwOCwgMTQ1LCAxNjIsIDE0NSwgMTgyLCAxNDUsIDIwMiwgMTQ1LCAyMjIsIDE0NSwgMjQyLCAxNDYsIDcxLCAxNDYsIDkxLCAxNDYsCisxMTEsIDE0NiwgMTY1LCAxNDYsIDE4NSwgMTQ2LCAyMDUsIDE0NiwgMjI1LCAxNDYsIDI0NSwgMTQ3LCA3NCwgMTQ3LCA5NCwgMTQ3LAorMTE0LCAxNDcsIDE2OCwgMTQ3LCAxODgsIDE0NywgMjA4LCAxNDcsIDIyOCwgMTQ3LCAyNDgsIDE0OCwgNzcsIDE0OCwgOTcsIDE0OCwKKzExNywgMTQ4LCAxNzEsIDE0OCwgMTkxLCAxNDgsIDIxMSwgMTQ4LCAyMzEsIDE0OCwgMjUxLCAxNDksIDgwLCAxNDksIDEwMCwgMTQ5LAorMTIwLCAxNDksIDE3NCwgMTQ5LCAxOTQsIDE0OSwgMjE0LCAxNDksIDIzNCwgMTQ5LCAyNTQsIDE1MCwgODMsIDE1MCwgMTAzLCAxNTAsCisxMjMsIDE1MCwgMTc3LCAxNTAsIDE5NywgMTUwLCAyMTcsIDE1MCwgMjM3LCAxNTEsIDY2LCAxNTEsIDg2LCAxNTEsIDEwNiwgMTUxLAorMTI2LCAxNTEsIDE4MCwgMTUxLCAyMDAsIDE1MSwgMjIwLCAxNTEsIDI0MCwgMTUyLCA2OSwgMTUyLCA4OSwgMTUyLCAxMDksIDE1MiwKKzE2MywgMTUyLCAxODMsIDE1MiwgMjAzLCAxNTIsIDIyMywgMTUyLCAyNDMsIDE1MywgNzIsIDE1MywgOTIsIDE1MywgMTEyLCAxNTMsCisxNjYsIDE1MywgMTg2LCAxNTMsIDIwNiwgMTUzLCAyMjYsIDE1MywgMjQ2LCAxNTQsIDc1LCAxNTQsIDk1LCAxNTQsIDExNSwgMTU0LAorMTY5LCAxNTQsIDE4OSwgMTU0LCAyMDksIDE1NCwgMjI5LCAxNTQsIDI0OSwgMTU1LCA3OCwgMTU1LCA5OCwgMTU1LCAxMTgsIDE1NSwKKzE3MiwgMTU1LCAxOTIsIDE1NSwgMjEyLCAxNTUsIDIzMiwgMTU1LCAyNTIsIDE1NiwgODEsIDE1NiwgMTAxLCAxNTYsIDEyMSwgMTU2LAorMTc1LCAxNTYsIDE5NSwgMTU2LCAyMTUsIDE1NiwgMjM1LCAxNTcsIDY0LCAxNTcsIDg0LCAxNTcsIDEwNCwgMTU3LCAxMjQsIDE1NywKKzE3OCwgMTU3LCAxOTgsIDE1NywgMjE4LCAxNTcsIDIzOCwgMTU4LCA2NywgMTU4LCA4NywgMTU4LCAxMDcsIDE1OCwgMTYxLCAxNTgsCisxODEsIDE1OCwgMjAxLCAxNTgsIDIyMSwgMTU4LCAyNDEsIDE1OSwgNzAsIDE1OSwgOTAsIDE1OSwgMTEwLCAxNTksIDE2NCwgMTU5LAorMTg0LCAxNTksIDIwNCwgMTU5LCAyMjQsIDE1OSwgMjQ0LCAxNjAsIDczLCAxNjAsIDkzLCAxNjAsIDExMywgMTYwLCAxNjcsIDE2MCwKKzE4NywgMTYwLCAyMDcsIDE2MCwgMjI3LCAxNjAsIDI0NywgMTI5LCA3NiwgMTI5LCA5NiwgMTI5LCAxMTYsIDEyOSwgMTcwLCAxMjksCisxOTAsIDEyOSwgMjEwLCAxMjksIDIzMCwgMTI5LCAyNTAsIDEzMCwgNzksIDEzMCwgOTksIDEzMCwgMTE5LCAxMzAsIDE3MywgMTMwLAorMTkzLCAxMzAsIDIxMywgMTMwLCAyMzMsIDEzMCwgMjUzLCAxMzEsIDgyLCAxMzEsIDEwMiwgMTMxLCAxMjIsIDEzMSwgMTc2LCAxMzEsCisxOTYsIDEzMSwgMjE2LCAxMzEsIDIzNiwgMTMyLCA2NSwgMTMyLCA4NSwgMTMyLCAxMDUsIDEzMiwgMTI1LCAxMzIsIDE3OSwgMTMyLAorMTk5LCAxMzIsIDIxOSwgMTMyLCAyMzksIDEzMywgNjgsIDEzMywgODgsIDEzMywgMTA4LCAxMzMsIDE2MiwgMTMzLCAxODIsIDEzMywKKzIwMiwgMTMzLCAyMjIsIDEzMywgMjQyLCAxMzQsIDcxLCAxMzQsIDkxLCAxMzQsIDExMSwgMTM0LCAxNjUsIDEzNCwgMTg1LCAxMzQsCisyMDUsIDEzNCwgMjI1LCAxMzQsIDI0NSwgMTM1LCA3NCwgMTM1LCA5NCwgMTM1LCAxMTQsIDEzNSwgMTY4LCAxMzUsIDE4OCwgMTM1LAorMjA4LCAxMzUsIDIyOCwgMTM1LCAyNDgsIDEzNiwgNzcsIDEzNiwgOTcsIDEzNiwgMTE3LCAxMzYsIDE3MSwgMTM2LCAxOTEsIDEzNiwKKzIxMSwgMTM2LCAyMzEsIDEzNiwgMjUxLCAxMzcsIDgwLCAxMzcsIDEwMCwgMTM3LCAxMjAsIDEzNywgMTc0LCAxMzcsIDE5NCwgMTM3LAorMjE0LCAxMzcsIDIzNCwgMTM3LCAyNTQsIDEzOCwgODMsIDEzOCwgMTAzLCAxMzgsIDEyMywgMTM4LCAxNzcsIDEzOCwgMTk3LCAxMzgsCisyMTcsIDEzOCwgMjM3LCAxMzksIDY2LCAxMzksIDg2LCAxMzksIDEwNiwgMTM5LCAxMjYsIDEzOSwgMTgwLCAxMzksIDIwMCwgMTM5LAorMjIwLCAxMzksIDI0MCwgMTQwLCA2OSwgMTQwLCA4OSwgMTQwLCAxMDksIDE0MCwgMTYzLCAxNDAsIDE4MywgMTQwLCAyMDMsIDE0MCwKKzIyMywgMTQwLCAyNDMsIDE0MSwgNzIsIDE0MSwgOTIsIDE0MSwgMTEyLCAxNDEsIDE2NiwgMTQxLCAxODYsIDE0MSwgMjA2LCAxNDEsCisyMjYsIDE0MSwgMjQ2LCAxOTgsIDE3MiwgMTk4LCAxOTIsIDE5OCwgMjEyLCAxOTgsIDIzMiwgMTk4LCAyNTIsIDE5OSwgODEsIDE5OSwKKzEwMSwgMTk5LCAxMjEsIDE5OSwgMTc1LCAxOTksIDE5NSwgMTk5LCAyMTUsIDE5OSwgMjM1LCAyMDAsIDY0LCAyMDAsIDg0LCAyMDAsCisxMDQsIDIwMCwgMTI0LCAyMDAsIDE3OCwgMjAwLCAxOTgsIDIwMCwgMjE4LCAyMDAsIDIzOCwgMjU1LCAyMDEsIDc0LCAxNjEsIDc0LAorMTYxLCAxMjQsIDE2MSwgMTI1LCAxNjEsIDczLCAxNjIsIDE4MCwgMTYyLCAyMTUsIDE2MSwgMTk2LCAxNjIsIDI1MSwgMTYyLCA3MAorICAgICAgICAgICAgfSk7CisKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9NdWx0aUJ5dGVfRVVDX0pQLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX0VVQ19KUC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlN2ZjYzIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX0VVQ19KUC5qYXZhCkBAIC0wLDAgKzEsNTI1IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLkNoYXJCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5Db2RpbmdFcnJvckFjdGlvbjsKKworLyoqIEBoaWRlCisgKiBTRUUgY29ycmVzcG9uZGlnX0FuZHJvaWQgdGVzdCBjbGFzczoKKyAqLworCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9NdWx0aUJ5dGVfRVVDX0pQIGV4dGVuZHMgT2xkQ2hhcnNldF9BYnN0cmFjdFRlc3QgeworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcnNldE5hbWUgPSAiRVVDLUpQIjsKKworICAgICAgICB0ZXN0Q2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKzAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKzMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCis2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKzgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisxNjEsIDE2MiwgMTYzLCAxNjQsIC8qMTY1LCovIDE2NiwgMTY3LCAxNjgsIDE2OSwgMTcwLCAxNzIsIDE3NCwgMTc1LCAxNzYsIDE3NywgMTgwLAorMTgyLCAxODQsIDE4NiwgMTkxLCAxOTIsIDE5MywgMTk0LCAxOTUsIDE5NiwgMTk3LCAxOTgsIDE5OSwgMjAwLCAyMDEsIDIwMiwgMjAzLAorMjA0LCAyMDUsIDIwNiwgMjA3LCAyMDksIDIxMCwgMjExLCAyMTIsIDIxMywgMjE0LCAyMTUsIDIxNiwgMjE3LCAyMTgsIDIxOSwgMjIwLAorMjIxLCAyMjIsIDIyMywgMjI0LCAyMjUsIDIyNiwgMjI3LCAyMjgsIDIyOSwgMjMwLCAyMzEsIDIzMiwgMjMzLCAyMzQsIDIzNSwgMjM2LAorMjM3LCAyMzgsIDIzOSwgMjQwLCAyNDEsIDI0MiwgMjQzLCAyNDQsIDI0NSwgMjQ2LCAyNDcsIDI0OCwgMjQ5LCAyNTAsIDI1MSwgMjUyLAorMjUzLCAyNTQsIDI1NSwgMjU2LCAyNjYsIDI3OCwgMjg4LCAyOTgsIDMwOCwgMzE4LCAzMjgsIDMzOCwgMzQ4LCAzNTgsIDM2OCwgMzc4LAorNDYxLCA0NzEsIDUwMSwgNzExLCA3MjgsIDkwMCwgOTEwLCA5MjAsIDkzMSwgOTQxLCA5NTEsIDk2MSwgOTcxLCAxMDI1LCAxMDM1LCAxMDQ1LAorMTA1NSwgMTA2NSwgMTA3NSwgMTA4NSwgMTA5NSwgMTEwNSwgMTExNSwgODIwOCwgODIyMCwgODIzMCwgODI0MCwgODI1MSwgODQ1MSwgODQ3MCwgODQ4MiwgODU5MiwKKzg2NTgsIDg3MDQsIDg3MTUsIDg3MzAsIDg3NDMsIDg3NTYsIDg3ODYsIDg4MDAsIDg4MTAsIDg4MzQsIDg4NjksIDg5NzgsIDk0NzIsIDk0ODQsIDk0OTUsIDk1MDcsCis5NTE5LCA5NTMxLCA5NTQ3LCA5NjMyLCA5NjUwLCA5NjYwLCA5NjcwLCA5NzExLCA5NzMzLCA5NzkyLCA5ODM0LCAxMjI4OCwgMTIyOTgsIDEyMzA4LCAxMjM1MywgMTIzNjMsCisxMjM3MywgMTIzODMsIDEyMzkzLCAxMjQwMywgMTI0MTMsIDEyNDIzLCAxMjQzMywgMTI0NDMsIDEyNDUzLCAxMjQ2MywgMTI0NzMsIDEyNDgzLCAxMjQ5MywgMTI1MDMsIDEyNTEzLCAxMjUyMywKKzEyNTMzLCAxOTk2OCwgMTk5NzgsIDE5OTg4LCAxOTk5OCwgMjAwMDgsIDIwMDE4LCAyMDAyOCwgMjAwMzksIDIwMDQ5LCAyMDA2MCwgMjAwNzIsIDIwMDgzLCAyMDA5NCwgMjAxMDQsIDIwMTE0LAorMjAxMjQsIDIwMTM0LCAyMDE0NCwgMjAxNTQsIDIwMTY0LCAyMDE3NCwgMjAxODQsIDIwMTk0LCAyMDIwNSwgMjAyMTUsIDIwMjI1LCAyMDIzNSwgMjAyNDUsIDIwMjcwLCAyMDI4MCwgMjAyOTAsCisyMDMwMCwgMjAzMTAsIDIwMzIwLCAyMDMzMCwgMjAzNDEsIDIwMzUxLCAyMDM2MSwgMjAzNzEsIDIwMzgxLCAyMDM5NSwgMjA0MDUsIDIwNDE1LCAyMDQyNSwgMjA0MzYsIDIwNDQ3LCAyMDQ2MiwKKzIwNDcyLCAyMDQ4NCwgMjA0OTQsIDIwNTA0LCAyMDUxNCwgMjA1MjQsIDIwNTM0LCAyMDU0NCwgMjA1NTQsIDIwNTY1LCAyMDU3NSwgMjA1ODYsIDIwNTk2LCAyMDYwOCwgMjA2MTgsIDIwNjI4LAorMjA2MzgsIDIwNjUwLCAyMDY2MCwgMjA2NzAsIDIwNjgxLCAyMDY5MSwgMjA3MDEsIDIwNzExLCAyMDcyMSwgMjA3MzEsIDIwNzQyLCAyMDc1MiwgMjA3NjIsIDIwNzc1LCAyMDc4NSwgMjA3OTUsCisyMDgwNSwgMjA4MTUsIDIwODI2LCAyMDgzNiwgMjA4NDYsIDIwODU2LCAyMDg2NiwgMjA4NzYsIDIwODg2LCAyMDg5NiwgMjA5MDYsIDIwOTE2LCAyMDkyNiwgMjA5MzYsIDIwOTQ2LCAyMDk1NiwKKzIwOTY2LCAyMDk3NiwgMjA5ODYsIDIwOTk2LCAyMTAwNiwgMjEwMTYsIDIxMDI2LCAyMTAzOCwgMjEwNDgsIDIxMDU5LCAyMTA2OSwgMjEwNzksIDIxMDg5LCAyMTEwMiwgMjExMTIsIDIxMTIyLAorMjExMzIsIDIxMTQyLCAyMTE1MiwgMjExNjIsIDIxMTcyLCAyMTE4MiwgMjExOTIsIDIxMjAyLCAyMTIxMiwgMjEyMjIsIDIxMjMyLCAyMTI0MiwgMjEyNTMsIDIxMjYzLCAyMTI3MywgMjEyODMsCisyMTI5MywgMjEzMDQsIDIxMzE0LCAyMTMyNCwgMjEzMzUsIDIxMzQ1LCAyMTM1NiwgMjEzNjcsIDIxMzc4LCAyMTM5MCwgMjE0MDAsIDIxNDEyLCAyMTQyMiwgMjE0MzIsIDIxNDQyLCAyMTQ1MiwKKzIxNDYyLCAyMTQ3MiwgMjE0ODIsIDIxNDkzLCAyMTUwNSwgMjE1MTUsIDIxNTMwLCAyMTU0MiwgMjE1NTMsIDIxNTYzLCAyMTU3NCwgMjE1ODUsIDIxNTk4LCAyMTYwOCwgMjE2MTksIDIxNjI5LAorMjE2NDAsIDIxNjUwLCAyMTY2MCwgMjE2NzAsIDIxNjgxLCAyMTY5MSwgMjE3MDIsIDIxNzIwLCAyMTczMCwgMjE3NDAsIDIxNzUwLCAyMTc2MCwgMjE3NzIsIDIxNzgyLCAyMTgwMiwgMjE4MTMsCisyMTgyNCwgMjE4MzQsIDIxODQ2LCAyMTg1NiwgMjE4ODMsIDIxODk0LCAyMTkwNSwgMjE5MTYsIDIxOTI3LCAyMTkzOCwgMjE5NTEsIDIxOTYxLCAyMTk3MSwgMjE5ODIsIDIxOTkzLCAyMjAwNiwKKzIyMDIxLCAyMjAzMSwgMjIwNDEsIDIyMDU3LCAyMjA2NywgMjIwNzcsIDIyMDg5LCAyMjEwMCwgMjIxMTAsIDIyMTIwLCAyMjEzMCwgMjIxNDQsIDIyMTU0LCAyMjE2NCwgMjIxNzQsIDIyMTg0LAorMjIxOTUsIDIyMjA2LCAyMjIxNiwgMjIyMjcsIDIyMjM3LCAyMjI0NywgMjIyNTcsIDIyMjY5LCAyMjI3OSwgMjIyODksIDIyMjk5LCAyMjMwOSwgMjIzMTksIDIyMzMxLCAyMjM0MSwgMjIzNTEsCisyMjM2OSwgMjIzNzksIDIyMzg5LCAyMjM5OSwgMjI0MDksIDIyNDE5LCAyMjQyOSwgMjI0MzksIDIyNDUxLCAyMjQ2MSwgMjI0NzEsIDIyNDgyLCAyMjQ5MiwgMjI1MDIsIDIyNTEyLCAyMjUyMiwKKzIyNTMyLCAyMjU0OSwgMjI1NTksIDIyNTcwLCAyMjU4MCwgMjI1OTEsIDIyNjAxLCAyMjYxMiwgMjI2MjIsIDIyNjMyLCAyMjY0MiwgMjI2NTIsIDIyNjYzLCAyMjY3NSwgMjI2ODUsIDIyNjk2LAorMjI3MDYsIDIyNzE2LCAyMjcyNywgMjI3MzcsIDIyNzQ4LCAyMjc2MSwgMjI3NzEsIDIyNzgxLCAyMjc5MywgMjI4MDMsIDIyODEzLCAyMjgyMywgMjI4MzMsIDIyODQ2LCAyMjg1NiwgMjI4NjYsCisyMjg3NywgMjI4ODcsIDIyODk4LCAyMjkwOCwgMjI5MjIsIDIyOTMzLCAyMjk0MywgMjI5NTYsIDIyOTY3LCAyMjk3NywgMjI5ODcsIDIzMDAxLCAyMzAxMSwgMjMwMjIsIDIzMDM1LCAyMzA0OSwKKzIzMDU5LCAyMzA3MCwgMjMwODAsIDIzMDkzLCAyMzEwNCwgMjMxMTYsIDIzMTMwLCAyMzE0MSwgMjMxNTksIDIzMTc5LCAyMzE5MCwgMjMyMDAsIDIzMjEyLCAyMzIyNCwgMjMyMzQsIDIzMjQ0LAorMjMyNTQsIDIzMjY0LCAyMzI3NCwgMjMyODUsIDIzMjk2LCAyMzMwNywgMjMzMTgsIDIzMzI5LCAyMzM0MCwgMjMzNTAsIDIzMzYwLCAyMzM3MSwgMjMzODEsIDIzMzkxLCAyMzQwMSwgMjM0MTEsCisyMzQyMSwgMjM0MzEsIDIzNDQxLCAyMzQ1MSwgMjM0NjEsIDIzNDcxLCAyMzQ4MSwgMjM0OTEsIDIzNTAxLCAyMzUxMSwgMjM1MjEsIDIzNTMxLCAyMzU0MSwgMjM1NTEsIDIzNTYxLCAyMzU3MSwKKzIzNTgyLCAyMzU5MiwgMjM2MDIsIDIzNjEyLCAyMzYyMiwgMjM2MzIsIDIzNjQyLCAyMzY1MiwgMjM2NjIsIDIzNjczLCAyMzY4NywgMjM2OTcsIDIzNzA5LCAyMzcyMCwgMjM3MzAsIDIzNzQwLAorMjM3NTEsIDIzNzYyLCAyMzc3MywgMjM3ODQsIDIzNzk0LCAyMzgwNSwgMjM4MTUsIDIzODI1LCAyMzgzNSwgMjM4NDYsIDIzODU3LCAyMzg2OSwgMjM4ODAsIDIzODkwLCAyMzkwMCwgMjM5MTMsCisyMzkyMywgMjM5MzQsIDIzOTQ0LCAyMzk1NCwgMjM5NjUsIDIzOTc1LCAyMzk4NiwgMjM5OTYsIDI0MDA3LCAyNDAxOCwgMjQwMjksIDI0MDM5LCAyNDA0OSwgMjQwNTksIDI0MDcwLCAyNDA4MSwKKzI0MDkxLCAyNDEwMSwgMjQxMTEsIDI0MTI1LCAyNDEzNSwgMjQxNDUsIDI0MTU1LCAyNDE2OCwgMjQxNzgsIDI0MTg4LCAyNDE5OSwgMjQyMTMsIDI0MjI0LCAyNDIzNCwgMjQyNDUsIDI0MjU1LAorMjQyNjUsIDI0Mjc1LCAyNDI4NSwgMjQyOTYsIDI0MzA3LCAyNDMxOCwgMjQzMjgsIDI0MzM5LCAyNDM0OSwgMjQzNTksIDI0MzY5LCAyNDM3OSwgMjQzODksIDI0NDAwLCAyNDQxMSwgMjQ0MjIsCisyNDQzMiwgMjQ0NDIsIDI0NDUyLCAyNDQ2MywgMjQ0NzMsIDI0NDg0LCAyNDQ5NCwgMjQ1MDQsIDI0NTE1LCAyNDUyNSwgMjQ1MzUsIDI0NTQ1LCAyNDU1NSwgMjQ1NjUsIDI0NTc1LCAyNDU4NiwKKzI0NTk2LCAyNDYwNywgMjQ2MTcsIDI0NjI3LCAyNDY0MCwgMjQ2NTAsIDI0NjYwLCAyNDY3MSwgMjQ2ODEsIDI0NjkzLCAyNDcwMywgMjQ3MTMsIDI0NzIzLCAyNDczMywgMjQ3NDMsIDI0NzUzLAorMjQ3NjMsIDI0NzczLCAyNDc4MywgMjQ3OTMsIDI0ODAzLCAyNDgxNiwgMjQ4MjYsIDI0ODM4LCAyNDg0OCwgMjQ4NTgsIDI0ODcxLCAyNDg4MSwgMjQ4OTIsIDI0OTAyLCAyNDkxNSwgMjQ5MjUsCisyNDkzNSwgMjQ5NDUsIDI0OTU1LCAyNDk2NywgMjQ5NzcsIDI0OTg4LCAyNDk5OSwgMjUwMTAsIDI1MDIwLCAyNTAzMCwgMjUwNDAsIDI1MDUyLCAyNTA2MiwgMjUwNzQsIDI1MDg0LCAyNTA5NSwKKzI1MTA1LCAyNTExNSwgMjUxMjYsIDI1MTM2LCAyNTE0NywgMjUxNTgsIDI1MTY4LCAyNTE3OCwgMjUxODgsIDI1MTk4LCAyNTIwOSwgMjUyMTksIDI1MjI5LCAyNTIzOSwgMjUyNTQsIDI1MjY1LAorMjUyNzUsIDI1Mjg1LCAyNTI5NSwgMjUzMDUsIDI1MzIyLCAyNTMzMiwgMjUzNDIsIDI1MzUyLCAyNTM2MywgMjUzNzUsIDI1Mzg1LCAyNTM5NywgMjU0MDcsIDI1NDE3LCAyNTQyNywgMjU0NDUsCisyNTQ1NywgMjU0NjcsIDI1NDc5LCAyNTQ5MCwgMjU1MDIsIDI1NTEyLCAyNTUyMiwgMjU1MzMsIDI1NTQ0LCAyNTU1NCwgMjU1NjQsIDI1NTc3LCAyNTU4NywgMjU2MDYsIDI1NjE2LCAyNTYyOCwKKzI1NjM4LCAyNTY0OCwgMjU2NTgsIDI1Njc1LCAyNTY4OCwgMjU2OTksIDI1NzA5LCAyNTcyMCwgMjU3MzEsIDI1NzQzLCAyNTc1MywgMjU3NjMsIDI1NzczLCAyNTc4NSwgMjU3OTYsIDI1ODA2LAorMjU4MTYsIDI1ODI2LCAyNTgzNiwgMjU4NDYsIDI1ODU2LCAyNTg2NiwgMjU4NzYsIDI1ODg2LCAyNTg5NywgMjU5MDgsIDI1OTE4LCAyNTkyOCwgMjU5MzgsIDI1OTQ5LCAyNTk1OSwgMjU5NzAsCisyNTk4MSwgMjU5OTEsIDI2MDAxLCAyNjAxMSwgMjYwMjEsIDI2MDMxLCAyNjA0MSwgMjYwNTEsIDI2MDYyLCAyNjA3MiwgMjYwODIsIDI2MDkyLCAyNjEwNSwgMjYxMTUsIDI2MTI1LCAyNjE0MCwKKzI2MTUwLCAyNjE2MCwgMjYxNzIsIDI2MTgyLCAyNjE5MywgMjYyMDMsIDI2MjE0LCAyNjIyNCwgMjYyMzQsIDI2MjQ0LCAyNjI1NCwgMjYyNjQsIDI2Mjc0LCAyNjI4NSwgMjYyOTYsIDI2MzA2LAorMjYzMTYsIDI2MzI2LCAyNjMzNiwgMjYzNDcsIDI2MzU3LCAyNjM2NywgMjYzNzcsIDI2Mzg3LCAyNjM5NywgMjY0MDcsIDI2NDE3LCAyNjQyOSwgMjY0MzksIDI2NDQ5LCAyNjQ2MCwgMjY0NzAsCisyNjQ4MCwgMjY0OTEsIDI2NTAxLCAyNjUxMSwgMjY1MjEsIDI2NTM0LCAyNjU0NCwgMjY1NTUsIDI2NTY1LCAyNjU3NSwgMjY1ODUsIDI2NTk2LCAyNjYwNiwgMjY2MTcsIDI2NjI3LCAyNjY0MywKKzI2NjUzLCAyNjY2MywgMjY2NzMsIDI2NjgzLCAyNjY5MywgMjY3MDQsIDI2NzE1LCAyNjcyNywgMjY3MzcsIDI2NzQ3LCAyNjc1NywgMjY3NjcsIDI2Nzc4LCAyNjc4OSwgMjY3OTksIDI2ODA5LAorMjY4MjAsIDI2ODMxLCAyNjg0MSwgMjY4NTEsIDI2ODYxLCAyNjg3MywgMjY4ODQsIDI2ODk0LCAyNjkwNSwgMjY5MTUsIDI2OTI4LCAyNjkzOSwgMjY5NDksIDI2OTYzLCAyNjk3MywgMjY5ODQsCisyNjk5NCwgMjcwMDQsIDI3MDE4LCAyNzAyOCwgMjcwNDAsIDI3MDUxLCAyNzA2MywgMjcwNzMsIDI3MDgzLCAyNzA5NCwgMjcxMDYsIDI3MTE3LCAyNzEyOSwgMjcxMzksIDI3MTUxLCAyNzE2MSwKKzI3MTcxLCAyNzE4MiwgMjcxOTIsIDI3MjA0LCAyNzIxNCwgMjcyMjQsIDI3MjM0LCAyNzI0OSwgMjcyNjIsIDI3MjczLCAyNzI4NywgMjcyOTgsIDI3MzA4LCAyNzMyMCwgMjczMzAsIDI3MzQwLAorMjczNTAsIDI3MzY0LCAyNzM3NiwgMjczODYsIDI3Mzk2LCAyNzQwNywgMjc0MTksIDI3NDMxLCAyNzQ0MiwgMjc0NTMsIDI3NDYzLCAyNzQ3NCwgMjc0ODUsIDI3NDk1LCAyNzUwNywgMjc1MTcsCisyNzUyOSwgMjc1NDEsIDI3NTUxLCAyNzU2MSwgMjc1NzEsIDI3NTgxLCAyNzU5MywgMjc2MDMsIDI3NjE1LCAyNzYyNywgMjc2MzksIDI3NjUwLCAyNzY2MSwgMjc2NzEsIDI3NjgzLCAyNzY5NCwKKzI3NzA0LCAyNzcxNCwgMjc3MjUsIDI3NzM1LCAyNzc0NiwgMjc3NTcsIDI3NzY4LCAyNzc3OCwgMjc3ODgsIDI3Nzk4LCAyNzgwOSwgMjc4MTksIDI3ODMyLCAyNzg0MiwgMjc4NTIsIDI3ODYyLAorMjc4NzIsIDI3ODgyLCAyNzg5MiwgMjc5MDgsIDI3OTE4LCAyNzkyOSwgMjc5NDEsIDI3OTUxLCAyNzk2MSwgMjc5NzIsIDI3OTkxLCAyODAwMSwgMjgwMTIsIDI4MDIzLCAyODAzNCwgMjgwNDQsCisyODA1NCwgMjgwNzQsIDI4MDg0LCAyODA5NSwgMjgxMDYsIDI4MTE3LCAyODEyNywgMjgxMzcsIDI4MTQ3LCAyODE2MCwgMjgxNzAsIDI4MTgxLCAyODE5MSwgMjgyMDEsIDI4MjE0LCAyODIyNywKKzI4MjM3LCAyODI0NywgMjgyNTgsIDI4MjcwLCAyODI4MywgMjgzMDAsIDI4MzEwLCAyODMyMCwgMjgzMzAsIDI4MzQyLCAyODM1MiwgMjgzNjIsIDI4MzcyLCAyODM4MiwgMjgzOTUsIDI4NDA3LAorMjg0MTcsIDI4NDI4LCAyODQzOCwgMjg0NDgsIDI4NDU4LCAyODQ3MCwgMjg0ODEsIDI4NDk1LCAyODUwNSwgMjg1MTYsIDI4NTI2LCAyODUzNiwgMjg1NDYsIDI4NTU2LCAyODU2NiwgMjg1NzYsCisyODU4NiwgMjg1OTcsIDI4NjA4LCAyODYxOCwgMjg2MjgsIDI4NjM4LCAyODY0OCwgMjg2NTksIDI4NjY5LCAyODY3OSwgMjg2ODksIDI4Njk5LCAyODcxMCwgMjg3MjAsIDI4NzMyLCAyODc0NCwKKzI4NzU2LCAyODc2NiwgMjg3NzksIDI4Nzg5LCAyODgwMSwgMjg4MTQsIDI4ODI0LCAyODgzNiwgMjg4NDYsIDI4ODU2LCAyODg3MiwgMjg4ODMsIDI4ODkzLCAyODkxMywgMjg5MjUsIDI4OTM1LAorMjg5NDgsIDI4OTU4LCAyODk3MSwgMjg5ODIsIDI4OTkzLCAyOTAwMywgMjkwMTMsIDI5MDI0LCAyOTAzNiwgMjkwNDksIDI5MDYwLCAyOTA3MSwgMjkwODEsIDI5MDk2LCAyOTEwNiwgMjkxMTgsCisyOTEyOCwgMjkxMzgsIDI5MTQ4LCAyOTE1OCwgMjkxNzMsIDI5MTgzLCAyOTE5MywgMjkyMDMsIDI5MjEzLCAyOTIyNCwgMjkyMzQsIDI5MjQ0LCAyOTI1NCwgMjkyNjQsIDI5Mjc0LCAyOTI4NywKKzI5Mjk3LCAyOTMwNywgMjkzMTksIDI5MzMwLCAyOTM0NCwgMjkzNTYsIDI5MzY2LCAyOTM3NywgMjkzODgsIDI5Mzk4LCAyOTQwOCwgMjk0MjAsIDI5NDMxLCAyOTQ0MiwgMjk0NTMsIDI5NDYzLAorMjk0NzQsIDI5NDg0LCAyOTQ5NCwgMjk1MDcsIDI5NTE3LCAyOTUyNywgMjk1MzksIDI5NTUwLCAyOTU2MCwgMjk1NzEsIDI5NTgyLCAyOTU5MiwgMjk2MDIsIDI5NjEzLCAyOTYyMywgMjk2MzQsCisyOTY0NCwgMjk2NTQsIDI5NjY0LCAyOTY3NCwgMjk2ODQsIDI5Njk0LCAyOTcwNSwgMjk3MjIsIDI5NzMyLCAyOTc0MiwgMjk3NTMsIDI5NzYzLCAyOTc3MywgMjk3ODMsIDI5Nzk0LCAyOTgwNSwKKzI5ODIyLCAyOTgzMywgMjk4NDgsIDI5ODU4LCAyOTg3MCwgMjk4ODEsIDI5ODk2LCAyOTkwNywgMjk5MTgsIDI5OTI4LCAyOTkzOCwgMjk5NDgsIDI5OTU4LCAyOTk2OSwgMjk5ODAsIDI5OTkwLAorMzAwMDAsIDMwMDEwLCAzMDAyMCwgMzAwMzAsIDMwMDQxLCAzMDA1MiwgMzAwNjMsIDMwMDczLCAzMDA4NSwgMzAwOTUsIDMwMTA1LCAzMDExNSwgMzAxMjksIDMwMTQwLCAzMDE1MCwgMzAxNjIsCiszMDE3MiwgMzAxODMsIDMwMTkzLCAzMDIwNCwgMzAyMTUsIDMwMjI2LCAzMDIzNiwgMzAyNDYsIDMwMjU2LCAzMDI2NiwgMzAyNzYsIDMwMjkwLCAzMDMwMCwgMzAzMTEsIDMwMzIxLCAzMDMzMSwKKzMwMzQxLCAzMDM1MiwgMzAzNjIsIDMwMzcyLCAzMDM4MiwgMzAzOTIsIDMwNDAyLCAzMDQxMiwgMzA0MjIsIDMwNDMyLCAzMDQ0MiwgMzA0NTIsIDMwNDYyLCAzMDQ3MiwgMzA0ODIsIDMwNDkyLAorMzA1MDIsIDMwNTE2LCAzMDUyNiwgMzA1MzgsIDMwNTUwLCAzMDU2MCwgMzA1NzAsIDMwNTgwLCAzMDU5MCwgMzA2MDMsIDMwNjEzLCAzMDYyMywgMzA2MzQsIDMwNjQ1LCAzMDY1NSwgMzA2NjUsCiszMDY3NywgMzA2ODcsIDMwNjk3LCAzMDcwNywgMzA3MjIsIDMwNzMyLCAzMDc0OSwgMzA3NTksIDMwNzcwLCAzMDc4MywgMzA3OTYsIDMwODEyLCAzMDgyNCwgMzA4MzQsIDMwODQ0LCAzMDg1NCwKKzMwODY1LCAzMDg3NywgMzA4ODcsIDMwODk3LCAzMDkwNywgMzA5MTcsIDMwOTI4LCAzMDkzOCwgMzA5NDgsIDMwOTU5LCAzMDk3MCwgMzA5ODIsIDMwOTkyLCAzMTAwMiwgMzEwMTMsIDMxMDI1LAorMzEwMzUsIDMxMDQ1LCAzMTA1NSwgMzEwNjYsIDMxMDc3LCAzMTA5MCwgMzExMDAsIDMxMTE0LCAzMTEyNCwgMzExMzcsIDMxMTQ3LCAzMTE2MCwgMzExNzAsIDMxMTgzLCAzMTE5NCwgMzEyMDQsCiszMTIxNiwgMzEyMjcsIDMxMjM5LCAzMTI0OSwgMzEyNTksIDMxMjcxLCAzMTI4MSwgMzEyOTEsIDMxMzAxLCAzMTMxMSwgMzEzMjEsIDMxMzMxLCAzMTM0MSwgMzEzNTIsIDMxMzYyLCAzMTM3NiwKKzMxMzkwLCAzMTQwMSwgMzE0MTEsIDMxNDIzLCAzMTQzMywgMzE0NDMsIDMxNDUzLCAzMTQ2NCwgMzE0NzYsIDMxNDg2LCAzMTQ5NiwgMzE1MDgsIDMxNTE4LCAzMTUyOCwgMzE1MzksIDMxNTQ5LAorMzE1NTksIDMxNTY5LCAzMTU4MSwgMzE1OTEsIDMxNjAxLCAzMTYyMCwgMzE2MzAsIDMxNjQwLCAzMTY1MywgMzE2NjMsIDMxNjc0LCAzMTY4NCwgMzE2OTUsIDMxNzA1LCAzMTcxNiwgMzE3MzAsCiszMTc0MCwgMzE3NTAsIDMxNzYxLCAzMTc3MSwgMzE3ODEsIDMxNzkzLCAzMTgwNSwgMzE4MTgsIDMxODI4LCAzMTgzOCwgMzE4NDksIDMxODU5LCAzMTg2OSwgMzE4NzksIDMxODkwLCAzMTkwMiwKKzMxOTEyLCAzMTkyMiwgMzE5MzIsIDMxOTQzLCAzMTk1NCwgMzE5NjQsIDMxOTc0LCAzMTk4NiwgMzE5OTgsIDMyMDA4LCAzMjAxOCwgMzIwMjgsIDMyMDM4LCAzMjA0OCwgMzIwNTgsIDMyMDY4LAorMzIwNzgsIDMyMDg5LCAzMjA5OSwgMzIxMTAsIDMyMTIwLCAzMjEzMCwgMzIxNDAsIDMyMTUwLCAzMjE2MiwgMzIxNzIsIDMyMTgyLCAzMjE5NCwgMzIyMDQsIDMyMjE1LCAzMjIyNSwgMzIyMzUsCiszMjI0NSwgMzIyNTYsIDMyMjY2LCAzMjI3NywgMzIyODcsIDMyMjk5LCAzMjMwOSwgMzIzMTksIDMyMzMwLCAzMjM0MCwgMzIzNTAsIDMyMzYxLCAzMjM3MSwgMzIzODEsIDMyMzkxLCAzMjQwMSwKKzMyNDExLCAzMjU2NiwgMzI1NzksIDMyNTg5LCAzMjYwMCwgMzI2MTEsIDMyNjIxLCAzMjYzMSwgMzI2NDIsIDMyNjUyLCAzMjY2MiwgMzI2NzMsIDMyNjg1LCAzMjY5NiwgMzI3MDcsIDMyNzE4LAorMzI3MzEsIDMyNzQxLCAzMjc1MSwgMzI3NjEsIDMyNzcxLCAzMjc4MSwgMzI3OTEsIDMyODAxLCAzMjgxMiwgMzI4MjIsIDMyODMyLCAzMjg0MiwgMzI4NTQsIDMyODY0LCAzMjg3NywgMzI4ODcsCiszMjg5NywgMzI5MDcsIDMyOTE4LCAzMjkyOSwgMzI5MzksIDMyOTUyLCAzMjk2MywgMzI5NzMsIDMyOTgzLCAzMjk5MywgMzMwMDUsIDMzMDE2LCAzMzAyNiwgMzMwNDYsIDMzMDU2LCAzMzA2OCwKKzMzMDgxLCAzMzA5MywgMzMxMDQsIDMzMTE5LCAzMzEyOSwgMzMxNDAsIDMzMTUxLCAzMzE2MiwgMzMxNzMsIDMzMTg0LCAzMzE5OCwgMzMyMDgsIDMzMjE4LCAzMzIyOSwgMzMyMzksIDMzMjQ5LAorMzMyNTksIDMzMjY5LCAzMzI3OSwgMzMyODksIDMzMjk5LCAzMzMwOSwgMzMzMjAsIDMzMzMwLCAzMzM0NCwgMzMzNTUsIDMzMzY2LCAzMzM3NiwgMzMzODYsIDMzMzk2LCAzMzQwNiwgMzM0MTcsCiszMzQyOCwgMzM0MzksIDMzNDQ5LCAzMzQ1OSwgMzM0NjksIDMzNDg4LCAzMzQ5OCwgMzM1MDgsIDMzNTE5LCAzMzUyOSwgMzM1MzksIDMzNTUwLCAzMzU2MCwgMzM1NzAsIDMzNTgwLCAzMzU5MCwKKzMzNjAwLCAzMzYxMCwgMzM2MjAsIDMzNjQ4LCAzMzY1OSwgMzM2NjksIDMzNjgyLCAzMzY5MiwgMzM3MDIsIDMzNzEzLCAzMzcyNSwgMzM3MzUsIDMzNzQ1LCAzMzc1NiwgMzM3NjgsIDMzNzc4LAorMzM3ODgsIDMzNzk4LCAzMzgwOSwgMzM4MjQsIDMzODM0LCAzMzg0NSwgMzM4NjEsIDMzODcxLCAzMzg4MSwgMzM4OTEsIDMzOTAxLCAzMzkxMSwgMzM5MjEsIDMzOTMxLCAzMzk0MSwgMzM5NTEsCiszMzk2MSwgMzM5NzIsIDMzOTgyLCAzMzk5MiwgMzQwMDMsIDM0MDIzLCAzNDAzMywgMzQwNDMsIDM0MDU0LCAzNDA2NCwgMzQwNzQsIDM0MDg0LCAzNDA5NSwgMzQxMDksIDM0MTIwLCAzNDEzMCwKKzM0MTQwLCAzNDE1MiwgMzQxNjcsIDM0MTc3LCAzNDE4NywgMzQxOTksIDM0MjEwLCAzNDIyMCwgMzQyMzAsIDM0MjQxLCAzNDI1MSwgMzQyNjEsIDM0MjcxLCAzNDI4MSwgMzQyOTEsIDM0MzAyLAorMzQzMTQsIDM0MzI2LCAzNDMzNywgMzQzNDksIDM0MzYwLCAzNDM3MCwgMzQzODEsIDM0MzkxLCAzNDQwMSwgMzQ0MTEsIDM0NDIxLCAzNDQ0MCwgMzQ0NTEsIDM0NDY1LCAzNDQ3NSwgMzQ0ODUsCiszNDQ5NSwgMzQ1MDUsIDM0NTE2LCAzNDUyNiwgMzQ1MzcsIDM0NTUyLCAzNDU2MiwgMzQ1NzMsIDM0NTg0LCAzNDU5NSwgMzQ2MDYsIDM0NjE3LCAzNDYyNywgMzQ2MzcsIDM0NjQ3LCAzNDY1NywKKzM0NjcwLCAzNDY4MCwgMzQ2OTAsIDM0NzAwLCAzNDcxMSwgMzQ3MjIsIDM0NzMyLCAzNDc0NiwgMzQ3NTYsIDM0NzY2LCAzNDc3NywgMzQ3ODcsIDM0Nzk3LCAzNDgwNywgMzQ4MTcsIDM0ODI3LAorMzQ4MzcsIDM0ODQ3LCAzNDg2MSwgMzQ4NzMsIDM0ODgzLCAzNDg5MywgMzQ5MDMsIDM0OTEzLCAzNDkyMywgMzQ5MzMsIDM0OTQzLCAzNDk1NSwgMzQ5NjYsIDM0OTc2LCAzNDk4NiwgMzQ5OTYsCiszNTAwNiwgMzUwMTgsIDM1MDI4LCAzNTAzOCwgMzUwNDgsIDM1MDU4LCAzNTA2OCwgMzUwNzgsIDM1MDg4LCAzNTA5OCwgMzUxMDksIDM1MTIwLCAzNTEzMCwgMzUxNDAsIDM1MTUxLCAzNTE2MiwKKzM1MTcyLCAzNTE4MiwgMzUxOTQsIDM1MjA2LCAzNTIxNiwgMzUyMjYsIDM1MjM3LCAzNTI0NywgMzUyNTgsIDM1MjgyLCAzNTI5MiwgMzUzMDIsIDM1MzEzLCAzNTMyNSwgMzUzMzUsIDM1MzQ1LAorMzUzNTUsIDM1MzY1LCAzNTM3NSwgMzUzODYsIDM1Mzk3LCAzNTQwOCwgMzU0MTksIDM1NDI5LCAzNTQ0MCwgMzU0NTAsIDM1NDYwLCAzNTQ3MSwgMzU0ODEsIDM1NDkxLCAzNTUwMSwgMzU1MTEsCiszNTUyMiwgMzU1MzIsIDM1NTQyLCAzNTU1MiwgMzU1NjMsIDM1NTczLCAzNTU4MywgMzU1OTQsIDM1NjA0LCAzNTYxNCwgMzU2MjQsIDM1NjM1LCAzNTY0NiwgMzU2NTYsIDM1NjY2LCAzNTY3NiwKKzM1Njg2LCAzNTY5NiwgMzU3MDgsIDM1NzIyLCAzNTczMiwgMzU3NDIsIDM1ODk1LCAzNTkwNSwgMzU5MTUsIDM1OTI1LCAzNTkzNywgMzU5NDcsIDM1OTU3LCAzNTk3MCwgMzU5ODAsIDM1OTkyLAorMzYwMDIsIDM2MDEyLCAzNjAyMiwgMzYwMzIsIDM2MDQyLCAzNjA1MywgMzYwNjQsIDM2MDc0LCAzNjA4NSwgMzYwOTUsIDM2MTA1LCAzNjExNSwgMzYxOTYsIDM2MjA2LCAzNjIyMywgMzYyMzQsCiszNjI0NSwgMzYyNTUsIDM2MjY3LCAzNjI3NywgMzYyODgsIDM2Mjk4LCAzNjMwOCwgMzYzMTksIDM2MzMwLCAzNjM0MCwgMzYzNTEsIDM2MzYxLCAzNjM3MiwgMzYzODIsIDM2Mzk0LCAzNjQwNCwKKzM2NDE2LCAzNjQyNiwgMzY0MzYsIDM2NDQ2LCAzNjQ1NywgMzY0NjgsIDM2NDgxLCAzNjQ5MSwgMzY1MDEsIDM2NTEzLCAzNjUyMywgMzY1MzMsIDM2NTQ0LCAzNjU1NCwgMzY1NjQsIDM2NTc1LAorMzY1ODcsIDM2NTk5LCAzNjYxMCwgMzY2MjAsIDM2NjMwLCAzNjY0MCwgMzY2NTAsIDM2NjYwLCAzNjY3MCwgMzY2ODEsIDM2NjkxLCAzNjcwMSwgMzY3NjMsIDM2NzczLCAzNjc4MywgMzY3OTQsCiszNjgwNCwgMzY4MTQsIDM2ODI2LCAzNjgzNiwgMzY4NDYsIDM2ODU2LCAzNjg2NiwgMzY4NzYsIDM2ODg2LCAzNjg5NiwgMzY5MDYsIDM2OTE2LCAzNjkyNiwgMzY5MzcsIDM2OTQ3LCAzNjk1NywKKzM2OTY3LCAzNjk3OCwgMzY5ODgsIDM2OTk5LCAzNzAwOSwgMzcwMTksIDM3MDI5LCAzNzAzOSwgMzcwNTMsIDM3MDYzLCAzNzA3NCwgMzcwODQsIDM3MDk2LCAzNzEwOCwgMzcxMTgsIDM3MTI4LAorMzcxMzgsIDM3MTQ4LCAzNzE1OSwgMzcxNjksIDM3MTgwLCAzNzE5MSwgMzcyMDIsIDM3MjE3LCAzNzIyOCwgMzcyMzksIDM3MjQ5LCAzNzI1OSwgMzcyNjksIDM3MjgxLCAzNzI5MSwgMzczMDEsCiszNzMxMSwgMzczMjEsIDM3MzMxLCAzNzM0MSwgMzczNTEsIDM3MzYxLCAzNzM3MSwgMzczODEsIDM3MzkyLCAzNzQwNCwgMzc0MTQsIDM3NDI0LCAzNzQzNCwgMzc0NDQsIDM3NDU0LCAzNzQ2NCwKKzM3NDc0LCAzNzQ4NiwgMzc0OTYsIDM3NTA3LCAzNzUxNywgMzc1MjcsIDM3NTQwLCAzNzU1MSwgMzc1NjEsIDM3NTcxLCAzNzU4MSwgMzc1OTEsIDM3NjAxLCAzNzYxMiwgMzc2MjQsIDM3NjM0LAorMzc2NDUsIDM3NjU2LCAzNzY2NiwgMzc2NzYsIDM3Njg2LCAzNzcwMCwgMzc3MTIsIDM3NzIyLCAzNzczMiwgMzc3NDIsIDM3NzU0LCAzNzc2OCwgMzc3NzgsIDM3NzkwLCAzNzgwMCwgMzc4MTIsCiszNzgyNSwgMzc4MzUsIDM3ODQ2LCAzNzg1NywgMzc4NzksIDM3ODg5LCAzNzkwMSwgMzc5MTEsIDM3OTIxLCAzNzkzMSwgMzc5NDEsIDM3OTUxLCAzNzk2MiwgMzc5NzMsIDM3OTgzLCAzNzk5NCwKKzM4MDA1LCAzODAxNSwgMzgyNjMsIDM4Mjc0LCAzODI4NCwgMzgyOTQsIDM4MzA0LCAzODMxNSwgMzgzMjYsIDM4MzM5LCAzODM0OSwgMzgzNjAsIDM4MzcwLCAzODQyOCwgMzg0MzgsIDM4NDQ5LAorMzg0NTksIDM4NDc1LCAzODQ4NiwgMzg0OTcsIDM4NTA4LCAzODUxOCwgMzg1MjksIDM4NTM5LCAzODU0OSwgMzg1NTksIDM4NTY5LCAzODU3OSwgMzg1OTIsIDM4NjAyLCAzODYxMywgMzg2MjMsCiszODYzMywgMzg2NDYsIDM4NjU2LCAzODY2NiwgMzg2NzgsIDM4Njg5LCAzODcwNCwgMzg3MTcsIDM4NzI4LCAzODczOCwgMzg3NDgsIDM4NzU4LCAzODc2OSwgMzg3NzksIDM4Nzg5LCAzODc5OSwKKzM4ODA5LCAzODgxOSwgMzg4MjksIDM4ODQwLCAzODg1MSwgMzg4NjEsIDM4ODcxLCAzODg4MSwgMzg4OTMsIDM4OTAzLCAzODkxMywgMzg5MjQsIDM4OTM0LCAzODk0NCwgMzg5NTUsIDM4OTY1LAorMzg5ODAsIDM4OTkwLCAzOTAwMCwgMzkwMTAsIDM5MDIwLCAzOTA4MCwgMzkwOTIsIDM5MTAzLCAzOTExNiwgMzkxMzEsIDM5MTQxLCAzOTE1MSwgMzkxNjQsIDM5MTc1LCAzOTE4NSwgMzkxOTUsCiszOTIwNiwgMzkyMTcsIDM5MjI3LCAzOTIzNywgMzkyNDgsIDM5MjU5LCAzOTMxOCwgMzkzMzMsIDM5MzQ0LCAzOTM1NCwgMzkzNjQsIDM5Mzc2LCAzOTM4NiwgMzkzOTksIDM5NDA5LCAzOTQxOSwKKzM5NDI5LCAzOTQzOSwgMzk0NDksIDM5NDU5LCAzOTQ2OSwgMzk0NzksIDM5NDg5LCAzOTQ5OSwgMzk1MDksIDM5NTE5LCAzOTUyOSwgMzk1OTIsIDM5NjAyLCAzOTYxMiwgMzk2MjIsIDM5NjMyLAorMzk2NDMsIDM5NjUzLCAzOTY2MywgMzk2NzMsIDM5NjgzLCAzOTY5MywgMzk3MDQsIDM5NzE0LCAzOTcyNSwgMzk3MzUsIDM5NzQ1LCAzOTc1NSwgMzk3NjUsIDM5Nzc3LCAzOTc4NywgMzk3OTcsCiszOTgwNywgMzk4MTcsIDM5ODI3LCAzOTgzNywgMzk4NDcsIDM5ODU3LCAzOTg2NywgMzk4NzgsIDM5ODg4LCAzOTg5OSwgMzk5MDksIDM5OTE5LCAzOTkyOSwgMzk5NDAsIDM5OTUxLCAzOTk2MSwKKzM5OTcxLCAzOTk4MSwgMzk5OTEsIDQwMDAxLCA0MDAxNCwgNDAwMjQsIDQwMDM1LCA0MDA0NiwgNDAwNTYsIDQwMTY1LCA0MDE3NiwgNDAxOTQsIDQwMjA2LCA0MDIxNiwgNDAyMjcsIDQwMjM5LAorNDAyNTAsIDQwMjYwLCA0MDI3MiwgNDAyODQsIDQwMjk3LCA0MDMxMCwgNDAzMjMsIDQwMzMzLCA0MDM0MywgNDAzNTMsIDQwMzYzLCA0MDM3MywgNDAzODMsIDQwMzkzLCA0MDQwMywgNDA0MTQsCis0MDQyNSwgNDA0MzUsIDQwNDQ1LCA0MDQ1NSwgNDA0NjUsIDQwNDc1LCA0MDU2NSwgNDA1NzUsIDQwNTg3LCA0MDU5NywgNDA2MDcsIDQwNjE3LCA0MDYyNywgNDA2MzgsIDQwNjQ4LCA0MDY1OCwKKzQwNjY4LCA0MDY3OSwgNDA2ODksIDQwNjk5LCA0MDcxMSwgNDA3MjEsIDQwNzMxLCA0MDc0MiwgNDA3NTMsIDQwNzYzLCA0MDc3MywgNDA3ODMsIDQwNzk0LCA0MDgwNiwgNDA4MTYsIDQwODI2LAorNDA4NDUsIDQwODU1LCA0MDg2NSwgNjUyODEsIDY1MjkxLCA2NTMwMSwgNjUzMTEsIDY1MzIxLCA2NTMzMSwgNjUzNDEsIDY1MzUxLCA2NTM2MSwgNjUzNzEsIDY1MzgxLCA2NTM5MSwgNjU0MDEsCis2NTQxMSwgNjU0MjEsIDY1NDMxLCA2NTUwNworICAgICAgICAgICAgfSk7CisKKyAgICAgICAgdGVzdEJ5dGVzID0gdGhlc2VCeXRlcyhuZXcgaW50W117CiswLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAorMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCiszMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKzQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCis4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKzk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorMTQzLCAxNjIsIDE5NCwgMTYxLCAyNDEsIDE2MSwgMjQyLCAxNDMsIDE2MiwgMjQwLCAvKjkyLCovIDE0MywgMTYyLCAxOTUsIDE2MSwgMjQ4LAorMTYxLCAxNzUsIDE0MywgMTYyLCAyMzcsIDE0MywgMTYyLCAyMzYsIDE2MiwgMjA0LCAxNDMsIDE2MiwgMjM4LCAxNDMsIDE2MiwgMTgwLAorMTYxLCAyMzUsIDE2MSwgMjIyLCAxNjEsIDE3MywgMTYyLCAyNDksIDE0MywgMTYyLCAxNzcsIDE0MywgMTYyLCAyMzUsIDE0MywgMTYyLAorMTk2LCAxNDMsIDE3MCwgMTYyLCAxNDMsIDE3MCwgMTYxLCAxNDMsIDE3MCwgMTY0LCAxNDMsIDE3MCwgMTcwLCAxNDMsIDE3MCwgMTYzLAorMTQzLCAxNzAsIDE2OSwgMTQzLCAxNjksIDE2MSwgMTQzLCAxNzAsIDE3NCwgMTQzLCAxNzAsIDE3OCwgMTQzLCAxNzAsIDE3NywgMTQzLAorMTcwLCAxODAsIDE0MywgMTcwLCAxNzksIDE0MywgMTcwLCAxOTIsIDE0MywgMTcwLCAxOTEsIDE0MywgMTcwLCAxOTQsIDE0MywgMTcwLAorMTkzLCAxNDMsIDE3MCwgMjA4LCAxNDMsIDE3MCwgMjEwLCAxNDMsIDE3MCwgMjA5LCAxNDMsIDE3MCwgMjEyLCAxNDMsIDE3MCwgMjE2LAorMTQzLCAxNzAsIDIxMSwgMTYxLCAyMjMsIDE0MywgMTY5LCAxNzIsIDE0MywgMTcwLCAyMjcsIDE0MywgMTcwLCAyMjYsIDE0MywgMTcwLAorMjI5LCAxNDMsIDE3MCwgMjI4LCAxNDMsIDE3MCwgMjQyLCAxNDMsIDE2OSwgMTc2LCAxNDMsIDE2OSwgMjA2LCAxNDMsIDE3MSwgMTYyLAorMTQzLCAxNzEsIDE2MSwgMTQzLCAxNzEsIDE2NCwgMTQzLCAxNzEsIDE3MCwgMTQzLCAxNzEsIDE2MywgMTQzLCAxNzEsIDE2OSwgMTQzLAorMTY5LCAxOTMsIDE0MywgMTcxLCAxNzQsIDE0MywgMTcxLCAxNzgsIDE0MywgMTcxLCAxNzcsIDE0MywgMTcxLCAxODAsIDE0MywgMTcxLAorMTc5LCAxNDMsIDE3MSwgMTkyLCAxNDMsIDE3MSwgMTkxLCAxNDMsIDE3MSwgMTk0LCAxNDMsIDE3MSwgMTkzLCAxNDMsIDE2OSwgMTk1LAorMTQzLCAxNzEsIDIwOCwgMTQzLCAxNzEsIDIxMCwgMTQzLCAxNzEsIDIwOSwgMTQzLCAxNzEsIDIxMiwgMTQzLCAxNzEsIDIxNiwgMTQzLAorMTcxLCAyMTEsIDE2MSwgMjI0LCAxNDMsIDE2OSwgMjA0LCAxNDMsIDE3MSwgMjI3LCAxNDMsIDE3MSwgMjI2LCAxNDMsIDE3MSwgMjI5LAorMTQzLCAxNzEsIDIyOCwgMTQzLCAxNzEsIDI0MiwgMTQzLCAxNjksIDIwOCwgMTQzLCAxNzEsIDI0MywgMTQzLCAxNzAsIDE2NywgMTQzLAorMTcwLCAxNzUsIDE0MywgMTcwLCAxODIsIDE0MywgMTcwLCAxODksIDE0MywgMTcwLCAxOTcsIDE0MywgMTcwLCAyMDAsIDE0MywgMTcxLAorMjAzLCAxNDMsIDE3MSwgMjA2LCAxNDMsIDE2OSwgMTczLCAxNDMsIDE3MCwgMjIxLCAxNDMsIDE2OSwgMTc1LCAxNDMsIDE3MCwgMjMyLAorMTQzLCAxNzEsIDI0NSwgMTQzLCAxNzAsIDE2NiwgMTQzLCAxNzAsIDIzNywgMTQzLCAxNzEsIDE4NSwgMTQzLCAxNjIsIDE3NiwgMTQzLAorMTYyLCAxNzUsIDE0MywgMTYyLCAxODQsIDE0MywgMTY2LCAyMzMsIDE2NiwgMTY4LCAxNjYsIDE3OCwgMTQzLCAxNjYsIDI0MiwgMTY2LAorMTk5LCAxNjYsIDIwOSwgMTQzLCAxNjYsIDI1MCwgMTY3LCAxNjcsIDE0MywgMTY3LCAyMDMsIDE2NywgMTY2LCAxNjcsIDE3NywgMTY3LAorMTg3LCAxNjcsIDIxMiwgMTY3LCAyMjMsIDE2NywgMjMzLCAxNjcsIDIxNSwgMTQzLCAxNjcsIDI1MSwgMTYxLCAxOTAsIDE2MSwgMjAwLAorMTYxLCAxOTYsIDE2MiwgMjQzLCAxNjIsIDE2OCwgMTYxLCAyMzgsIDE0MywgMTYyLCAyNDEsIDE0MywgMTYyLCAyMzksIDE2MiwgMTcxLAorMTYyLCAyMDUsIDE2MiwgMjA3LCAxNjIsIDE4NywgMTYyLCAyMjksIDE2MiwgMjAyLCAxNjEsIDIzMiwgMTYyLCAyMjYsIDE2MSwgMjI2LAorMTYyLCAyMjcsIDE2MiwgMTkwLCAxNjIsIDIyMSwgMTYyLCAyMjIsIDE2OCwgMTYxLCAxNjgsIDE2MywgMTY4LCAxNzcsIDE2OCwgMTc4LAorMTY4LCAxODQsIDE2OCwgMTgxLCAxNjgsIDE4MiwgMTYyLCAxNjMsIDE2MiwgMTY1LCAxNjIsIDE2NywgMTYyLCAxNjEsIDE2MiwgMjU0LAorMTYxLCAyNTAsIDE2MSwgMjM0LCAxNjIsIDI0NiwgMTYxLCAxNjEsIDE2MSwgMjEyLCAxNjEsIDIwNCwgMTY0LCAxNjEsIDE2NCwgMTcxLAorMTY0LCAxODEsIDE2NCwgMTkxLCAxNjQsIDIwMSwgMTY0LCAyMTEsIDE2NCwgMjIxLCAxNjQsIDIzMSwgMTY0LCAyNDEsIDE2MSwgMTcxLAorMTY1LCAxNjUsIDE2NSwgMTc1LCAxNjUsIDE4NSwgMTY1LCAxOTUsIDE2NSwgMjA1LCAxNjUsIDIxNSwgMTY1LCAyMjUsIDE2NSwgMjM1LAorMTY1LCAyNDUsIDE3NiwgMjM2LCAxOTAsIDIyOSwgMTc5LCAyMzgsIDE5MCwgMjMxLCAxNDMsIDE3NiwgMTY5LCAxODIsIDI1MCwgMjA4LAorMTY3LCAxNDMsIDE3NiwgMTc4LCAxNDMsIDE3NiwgMTc5LCAxNDMsIDE3NiwgMTgxLCAxNDMsIDE3NiwgMTgzLCAxOTgsIDI1MywgMTgwLAorMTY1LCAyMDUsIDE4OSwgMTg0LCAyMjMsIDE3NiwgMTYxLCAyMDMsIDI0MiwgMjA4LCAxODMsIDE5MSwgMjA1LCAyMDgsIDE4OCwgMjA4LAorMTg2LCAyMDEsIDIxMywgMTQzLCAxNzYsIDIwMSwgMjA4LCAxOTMsIDIwOCwgMTk1LCAxODAsIDIzNSwgMTQzLCAxNzYsIDIxNCwgMTQzLAorMTc2LCAyMTcsIDE0MywgMTc2LCAyMjEsIDE5MSwgMTczLCAxNDMsIDE3NiwgMjMxLCAxNDMsIDE3NiwgMjM1LCAxNDMsIDE3NiwgMjM4LAorMTQzLCAxNzYsIDIyMywgMTQzLCAxNzYsIDI0MiwgMjAyLCAxODcsIDE4NywgMjAwLCAxNDMsIDE3NywgMTYyLCAxNDMsIDE3NywgMTY4LAorMTc2LCAyMDUsIDIxMywgMTY1LCAxOTEsIDE3NSwgMjAyLCAyMTYsIDE0MywgMTc3LCAxODcsIDIwOCwgMjE1LCAyMDgsIDIxNiwgMTg5LAorMTY0LCAyMDIsIDI0MCwgMTQzLCAxNzcsIDIwMywgMTQzLCAxNzcsIDIwNywgMTQzLCAxNzcsIDIxMSwgMTQzLCAxNzcsIDIxNiwgMjA4LAorMjM1LCAxODIsIDIzMCwgMTQzLCAxNzcsIDIyMywgMTQzLCAxNzcsIDIyOCwgMjA4LCAyNDMsIDE0MywgMTc3LCAyMzYsIDE0MywgMTc3LAorMjQyLCAxOTQsIDE2NiwgMjA4LCAyNTAsIDE0MywgMTc3LCAyNTEsIDE0MywgMTc4LCAxNjMsIDE0MywgMTc4LCAxNjcsIDE0MywgMTc4LAorMTcyLCAyMDgsIDI1MywgMTgzLCAxODUsIDIwOSwgMTYxLCAxNDMsIDE3OCwgMTg1LCAxNDMsIDE3OCwgMTg5LCAxOTMsIDIwNiwgMTQzLAorMTc4LCAxOTcsIDIwMiwgMjAwLCAxNDMsIDE3OCwgMjAyLCAxNDMsIDE3OCwgMjEwLCAyMDksIDE3OSwgMTQzLCAxNzgsIDIxOCwgMTQzLAorMTc4LCAyMjMsIDIwOSwgMTg0LCAxODksIDE4OCwgMTQzLCAxNzgsIDIzMSwgMTk3LCAyMjIsIDE0MywgMTc4LCAyMzcsIDIwOSwgMTk0LAorMTk3LCAxODEsIDIwOSwgMTk2LCAyMDksIDE5OCwgMjA5LCAyMDQsIDE4MCwgMTY3LCAyMDksIDIwOSwgMTg2LCAyMjcsIDE0MywgMTc4LAorMjUyLCAxNDMsIDE3OSwgMTYxLCAxNDMsIDE3OSwgMTY0LCAyNDQsIDE2NSwgMTg5LCAyMzIsIDIwOSwgMjI0LCAxODksIDIwOCwgMjA5LAorMjI3LCAyMDksIDIzMCwgMTQzLCAxNzksIDE4MywgMTQzLCAxNzksIDE4NCwgMjA5LCAyMzMsIDE4MywgMjQ0LCAxOTYsIDIzMCwgMTkzLAorMTc2LCAxNDMsIDE3OSwgMTkzLCAxNDMsIDE3OSwgMTk5LCAxNDMsIDE3OSwgMjAxLCAxNDMsIDE3OSwgMjAzLCAxNDMsIDE3OSwgMjA2LAorMTQzLCAxNzksIDIwOSwgMTQzLCAxNzksIDIxMiwgMTc4LCAxOTUsIDE5NywgMjE2LCAyMDcsIDE3MSwgMTc5LCAxNzUsIDE0MywgMTc5LAorMjMyLCAyNDAsIDIxMywgMTQzLCAxNzksIDIzOSwgMjEwLCAxNzEsIDE0MywgMTc5LCAyNDYsIDE4OCwgMjE5LCAyMDIsIDI0MSwgMjEwLAorMTgzLCAxODYsIDI1MiwgMjEwLCAxODYsIDE0MywgMTgwLCAxNzUsIDIxMCwgMTkwLCAxNDMsIDE4MCwgMTgyLCAxNDMsIDE4MCwgMTgzLAorMTk4LCAyMzgsIDE0MywgMTgwLCAxODcsIDE0MywgMTgwLCAxOTAsIDIxMCwgMjAzLCAyMTAsIDIwNCwgMTQzLCAxODAsIDE5OCwgMjA2LAorMjEwLCAxNDMsIDE4MCwgMjA0LCAyMTAsIDIwOSwgMTQzLCAxODAsIDIxMiwgMTg3LCAxNzgsIDE5MywgMjA4LCAxODgsIDIzMiwgMTQzLAorMTgwLCAyMjQsIDE5NCwgMjU0LCAxNDMsIDE4MCwgMjI3LCAyMTAsIDIyMiwgMTc3LCAxNjUsIDE0MywgMTgwLCAyMzAsIDIwMCwgMjIxLAorMTQzLCAxODAsIDIzNiwgMjAyLCAxNzMsIDIwMiwgMjQyLCAxOTgsIDIyMSwgMTQzLCAxODAsIDI0NCwgMTg4LCAyNTQsIDIwNCwgMTYzLAorMjA0LCAxOTEsIDE0MywgMTgxLCAxNjQsIDIxMCwgMjQwLCAxNDMsIDE4MSwgMTcwLCAxNDMsIDE4MSwgMTczLCAxNDMsIDE4MSwgMTc5LAorMTQzLCAxODEsIDE4MywgMTQzLCAxODEsIDE4NSwgMjExLCAxNjYsIDIxMSwgMTc1LCAxNDMsIDE4MSwgMTkxLCAxNDMsIDE4MSwgMTkzLAorMTQzLCAxODEsIDE5NywgMTQzLCAxODEsIDIwMiwgMTc2LCAxNjIsIDE0MywgMTgxLCAyMDYsIDE0MywgMTgxLCAyMDksIDIxMSwgMTc3LAorMTQzLCAxODEsIDIxNywgMjExLCAxODMsIDE0MywgMTgxLCAyMjUsIDIxMSwgMTkzLCAxNDMsIDE4MSwgMjMyLCAxNDMsIDE4MSwgMjM2LAorMTgwLCAyMzgsIDE4MywgMjQ2LCAxNDMsIDE4MSwgMjQ0LCAxNDMsIDE4MSwgMjQ1LCAxNDMsIDE4MSwgMjQ5LCAxNDMsIDE4MiwgMTYxLAorMTQzLCAxODIsIDE2NSwgMTQzLCAxODIsIDE2NywgMTQzLCAxODIsIDE2OCwgMTQzLCAxODIsIDE3MCwgMTQzLCAxODIsIDE3NSwgMTQzLAorMTgyLCAxNzksIDE3OCwgMjIyLCAxNDMsIDE4MiwgMTgyLCAxNDMsIDE4MiwgMTg4LCAxNDMsIDE4MiwgMTk1LCAxNDMsIDE4MiwgMTk5LAorMTQzLCAxODIsIDIwMCwgMTgwLCAyMzksIDE0MywgMTgyLCAyMTAsIDIxMSwgMjMwLCAyMTEsIDIzMSwgMjExLCAyMzMsIDE0MywgMTgyLAorMjIxLCAxNDMsIDE4MiwgMjI1LCAxNDMsIDE4MiwgMjMxLCAxNDMsIDE4MiwgMjMzLCAyMTEsIDI0NCwgMjExLCAyNDcsIDE0MywgMTgyLAorMjQ0LCAxNDMsIDE4MiwgMjUwLCAxNDMsIDE4MiwgMjUyLCAxODUsIDI0MSwgMTQzLCAxODMsIDE2NSwgMTQzLCAxODMsIDE2OCwgMTQzLAorMTgzLCAxNzEsIDE0MywgMTgzLCAxNzcsIDE0MywgMTgzLCAxODIsIDIxMiwgMTczLCAxNDMsIDE4MywgMTg4LCAyMTIsIDE3NSwgMjEyLAorMTc5LCAxNDMsIDE4MywgMTk3LCAxNDMsIDE4MywgMjA1LCAyMTIsIDE4MCwgMjEyLCAxODEsIDIxMiwgMTgyLCAxNDMsIDE4MywgMjIwLAorMTQzLCAxODMsIDIyNSwgMjEyLCAxODQsIDE0MywgMTgzLCAyMzAsIDE0MywgMTgzLCAyMzEsIDIxMiwgMTkxLCAxOTksIDE4NCwgMTQzLAorMTgzLCAyMzksIDE0MywgMTgzLCAyNDMsIDE4MCwgMjQwLCAxNDMsIDE4MywgMjUxLCAxOTQsIDE5NiwgMTQzLCAxODQsIDE2NSwgMTgwLAorMTc0LCAxOTAsIDIzNiwgMTQzLCAxODQsIDE3MiwgMTQzLCAxODQsIDE3MywgMTk3LCAyMjcsIDE4NiwgMjAxLCAxNDMsIDE4NCwgMTgzLAorMjEyLCAxOTksIDE0MywgMTg0LCAxODUsIDE0MywgMTg0LCAxODksIDIwMiwgMjMyLCAxNDMsIDE4NCwgMTk5LCAyMDMsIDIwNywgMTQzLAorMTg0LCAyMDYsIDE0MywgMTg0LCAyMDgsIDE5NSwgMTk3LCAyMTIsIDIxOSwgMjEyLCAyMjQsIDE0MywgMTg0LCAyMjEsIDE0MywgMTg0LAorMjIyLCAyMTIsIDIzMiwgMjAyLCAyMDksIDE0MywgMTg0LCAyMjgsIDE0MywgMTg0LCAyMzEsIDE5NCwgMjMxLCAxODgsIDE4NiwgMjEyLAorMjQzLCAxOTgsIDIyNCwgMTQzLCAxODQsIDI0NCwgMTQzLCAxODQsIDI0OCwgMjEyLCAyNTIsIDE0MywgMTg1LCAxNjIsIDE0MywgMTg1LAorMTY3LCAxOTksIDE2NSwgMTQzLCAxODUsIDE3MiwgMTQzLCAxODUsIDE3NCwgMTk3LCAyMDIsIDE0MywgMTg1LCAxODIsIDE0MywgMTg1LAorMTg1LCAxODcsIDIwNywgMjEzLCAxNzIsIDE0MywgMTg1LCAxOTUsIDE0MywgMTg1LCAxOTgsIDE3NiwgMjQ5LCAyMTMsIDE3OCwgMTQzLAorMTg1LCAyMTAsIDE0MywgMTg1LCAyMTEsIDE0MywgMTg1LCAyMTUsIDIxMywgMTgzLCAyMTMsIDE4MCwgMTQzLCAxODUsIDIyMywgMTg2LAorMTY3LCAxNDMsIDE4NSwgMjI4LCAxNDMsIDE4NSwgMjMxLCAxNDMsIDE4NSwgMjM1LCAxNDMsIDE4NSwgMjM4LCAxNDMsIDE4NSwgMjQzLAorMTQzLCAxODUsIDI0NiwgMTQzLCAxODUsIDI1MSwgMjEzLCAxOTEsIDE4MywgMjQ5LCAyMTMsIDE5NywgMTQzLCAxODYsIDE2NywgMTQzLAorMTg2LCAxNjksIDE0MywgMTg2LCAxNzEsIDE0MywgMTg2LCAxNzQsIDIxMywgMjAxLCAyMTMsIDIwMiwgMTQzLCAxODYsIDE4MiwgMTk2LAorMjIwLCAyMTMsIDIwNiwgMjEzLCAyMTAsIDE0MywgMTg2LCAxODcsIDIxMywgMjEyLCAyMDQsIDIxMCwgMjEzLCAyMTYsIDIxMywgMjE4LAorMTQzLCAxODYsIDE5NiwgMTc3LCAxNjcsIDE0MywgMTg2LCAyMDUsIDE3NiwgMTg0LCAyMDUsIDE2OCwgMTQzLCAxODYsIDIxMywgMjA1LAorMTk4LCAyMTMsIDIyNywgMTQzLCAxODYsIDIyMSwgMTQzLCAxODYsIDIyNCwgMTc4LCAyMDEsIDIxMywgMjM3LCAxOTUsIDI1NCwgMTg4LAorMjQ3LCAxNzYsIDIxMSwgMjEzLCAyNDUsIDE0MywgMTg2LCAyMzUsIDIxMywgMjQ4LCAxNDMsIDE4NiwgMjQ0LCAxOTgsIDI0NCwgMjEzLAorMjUyLCAyMTQsIDE2MSwgMTQzLCAxODYsIDI0OCwgMTkzLCAyMTYsIDIxNCwgMTY1LCAyMTQsIDE2OCwgMTQzLCAxODcsIDE2OSwgMjE0LAorMTcwLCAxNDMsIDE4NywgMTc0LCAxOTMsIDE4NywgMTQzLCAxODcsIDE4MSwgMjE0LCAxNzYsIDIxNCwgMTgwLCAxNDMsIDE4NywgMTg3LAorMTQzLCAxODcsIDE4OCwgMTc4LCAyMjksIDE0MywgMTg3LCAxOTIsIDIxNCwgMTgzLCAxOTEsIDI0MiwgMjE0LCAxOTQsIDIxNCwgMTkzLAorMTQzLCAxODcsIDIwMSwgMTQzLCAxODcsIDIwMywgMTQzLCAxODcsIDIwNiwgMTQzLCAxODcsIDIxMSwgMjE0LCAyMDEsIDIxNCwgMTkxLAorMTkxLCAyNDMsIDIxNCwgMjA1LCAxNDMsIDE4NywgMjI2LCAxNDMsIDE4NywgMjMwLCAxNDMsIDE4NywgMjMyLCAyMTQsIDIxMSwgMTQzLAorMTg3LCAyNDAsIDE0MywgMjMwLCAyNDQsIDIxNCwgMjE3LCAxNDMsIDE4NywgMjQ3LCAyMTQsIDIyMSwgMTkyLCAyMzgsIDE4NSwgMTcwLAorMTg0LCAyMDIsIDE4MCwgMTcyLCAyMDAsIDE5MywgMjE0LCAyMzAsIDIxNCwgMjMxLCAxOTEsIDIyNywgMTk0LCAyMTEsIDIwMywgMTg1LAorMjE0LCAyNDMsIDE0MywgMTg4LCAxODEsIDE0MywgMTg4LCAxODQsIDE0MywgMTg4LCAxODcsIDE4MCwgMTc5LCAyMDUsIDE5NiwgMjAwLAorMjIzLCAxOTYsIDIzNiwgMjE0LCAyNDksIDE0MywgMTg4LCAyMDEsIDE3NiwgMTk1LCAxNDMsIDE4OCwgMjA3LCAyMDYsIDI0NywgMTc5LAorMTk5LCAyMTUsIDE2MywgMjE1LCAxNjgsIDIxNSwgMTcyLCAyMTUsIDE3NiwgMTQzLCAxODgsIDIyMywgMTgxLCAyMjEsIDE0MywgMTg4LAorMjI3LCAxODQsIDIwNCwgMTg4LCAyMjksIDE0MywgMTg4LCAyMzksIDE0MywgMTg4LCAyNDQsIDE0MywgMTg4LCAyNDcsIDE0MywgMTg4LAorMjUwLCAyMDEsIDE2NywgMTkwLCAxODAsIDE0MywgMTg5LCAxNjYsIDE4MywgMTk0LCAxNDMsIDE4OSwgMTcxLCAyMTUsIDIwOCwgMTQzLAorMTg5LCAxNzgsIDIwMCwgMjQ5LCAxNDMsIDE4OSwgMTgzLCAxOTEsIDE4MCwgMTk5LCAxNjYsIDE4NywgMjE0LCAxNDMsIDE4OSwgMTk1LAorMTc4LCAyNDcsIDE5OSwgMTc2LCAyMTUsIDIyMSwgMTQzLCAxODksIDIxMCwgMTQzLCAxODksIDIxMywgMTQzLCAxODksIDIxNywgMjE1LAorMjI2LCAxNDMsIDE4OSwgMjIwLCAxNDMsIDE4OSwgMjIyLCAyMTUsIDI0MCwgMTQzLCAxODksIDIyOCwgMjE1LCAyMzksIDE3OCwgMTg0LAorMTgzLCAxOTUsIDE0MywgMTg5LCAyMzYsIDE4OCwgMTg5LCAxNDMsIDE4OSwgMjQzLCAxNDMsIDE4OSwgMjQ2LCAyMTYsIDE2NiwgMTQzLAorMTg5LCAyNTMsIDE0MywgMTkwLCAxNjEsIDE5MCwgMjQwLCAxNDMsIDE5MCwgMTcwLCAxNDMsIDE5MCwgMTczLCAxOTMsIDIxOCwgMTk0LAorMTk4LCAyMTYsIDE4NSwgMjE2LCAxODAsIDE0MywgMTkwLCAxODgsIDE4MiwgMjQyLCAyMTYsIDE5NSwgMTQzLCAxOTAsIDIwMiwgMjE2LAorMTk4LCAxNDMsIDE5MCwgMjA5LCAyMTYsIDIxNiwgMjE2LCAyMTUsIDE4MywgMTk3LCAyMTYsIDIxMywgMTQzLCAxOTAsIDIxNiwgMjE2LAorMjIwLCAyMTYsIDIyNSwgMTQzLCAxOTAsIDIyOSwgMTk4LCAxODAsIDE4MywgMjUxLCAxNDMsIDE5MCwgMjM5LCAyMTYsIDIzNCwgMTc4LAorMjUxLCAxNDMsIDE5MCwgMjQ2LCAyMTYsIDIzOSwgMTk2LCAxNjgsIDIxNiwgMjQ2LCAxNDMsIDE5MSwgMTY3LCAxNzgsIDIzMCwgMjE2LAorMjU0LCAxOTIsIDIzOSwgMjE3LCAxNjUsIDIwNCwgMjI1LCAxNDMsIDE5MSwgMTgyLCAxNDMsIDE5MSwgMTg0LCAxNDMsIDE5MSwgMTg5LAorMTQzLCAxOTEsIDE5MSwgMjAyLCAxNzcsIDIwMCwgMjI3LCAyMTcsIDE4MywgMTQzLCAxOTEsIDE5NywgMTg1LCAxNzksIDE0MywgMTkxLAorMjAxLCAyMDIsIDI1MCwgMjE3LCAxODcsIDE5NSwgMTgwLCAyMTcsIDE4OCwgMTkyLCAyMTksIDE0MywgMTkxLCAyMTQsIDE0MywgMTkxLAorMjE2LCAxODksIDE2NiwgMjE3LCAyMDUsIDE0MywgMTkxLCAyMjUsIDE4MiwgMTgwLCAxNDMsIDE5MSwgMjI4LCAxNDMsIDE5MSwgMjMxLAorMTkzLCAyMjIsIDE5NCwgMTcwLCAxNDMsIDE5MSwgMjQ0LCAxNDMsIDE5MSwgMjQ4LCAxNDMsIDE5MSwgMjUyLCAxOTksIDE3NywgMTQzLAorMTkyLCAxNjcsIDE5OSwgMjExLCAxNDMsIDE5MiwgMTc0LCAxOTEsIDIyOCwgMTgzLCAxOTksIDE0MywgMTkyLCAxODAsIDE0MywgMTkyLAorMTgzLCAyMTcsIDIzMSwgMTQzLCAxOTIsIDE4OSwgMjE3LCAyMjYsIDE0MywgMTkyLCAxOTUsIDIxNywgMjM2LCAxNDMsIDE5MiwgMjAxLAorMjE3LCAyMTEsIDIxNywgMjM4LCAxNDMsIDE5MiwgMjEzLCAxODMsIDIwMCwgMTQzLCAxOTIsIDIxNywgMTk3LCAxNjYsIDE0MywgMTkyLAorMjMwLCAxNDMsIDE5MiwgMjMxLCAyMDQsIDIwNiwgMTgzLCAyMjYsIDE0MywgMTkyLCAyMzgsIDE0MywgMTkyLCAyNDIsIDE0MywgMTkyLAorMjQ3LCAxOTksIDE5NywgMTc5LCAyMDEsIDE0MywgMTkzLCAxNjEsIDE0MywgMTkzLCAxNjYsIDIxOCwgMTY2LCAxOTcsIDE2NywgMTgxLAorMTg4LCAyMTgsIDE3NywgMjE4LCAxODEsIDE0MywgMTkzLCAxODUsIDE0MywgMTkzLCAxODgsIDE0MywgMTkzLCAxOTIsIDE0MywgMTkzLAorMTk2LCAyMTgsIDE4OSwgMjAyLCAyNTIsIDIxOCwgMTk1LCAxNDMsIDE5MywgMjA2LCAyMTgsIDIwMSwgMTQzLCAxOTMsIDIxMCwgMjE4LAorMjAyLCAxNDMsIDE5MywgMjEzLCAyMDIsIDE4NCwgMjAwLCAxOTUsIDIxOCwgMjA3LCAxOTIsIDIwNSwgMTg3LCAyMTksIDIwMiwgMjUzLAorMjE4LCAyMTEsIDE0MywgMTkzLCAyMzIsIDE0MywgMTkzLCAyMzYsIDE4MCwgMjUxLCAxODksIDIyMCwgMTQzLCAxOTMsIDI0MiwgMjE4LAorMjI0LCAxNDMsIDE5MywgMjQ5LCAyMTgsIDIzMCwgMTQzLCAxOTQsIDE2NiwgMTQzLCAxOTQsIDE3MiwgMTk1LCAyMzUsIDE0MywgMTk0LAorMTc5LCAxNDMsIDE5NCwgMTgyLCAxNDMsIDE5NCwgMTg3LCAxNzksIDE2MiwgMjE4LCAyNDIsIDE5NSwgMjEwLCAyMTgsIDI0NywgMjE4LAorMjQ1LCAyMTgsIDI0OCwgMTk2LCAxNzAsIDE0MywgMTk0LCAyMTcsIDIxOSwgMTYyLCAxNDMsIDE5NCwgMjI0LCAxNDMsIDE5NCwgMjI3LAorMjE5LCAxNjMsIDIxOSwgMTY1LCAxNDMsIDE5NCwgMjM0LCAyMTksIDE3MCwgMTk0LCAyMTYsIDIwNSwgMTczLCAxNDMsIDE5NCwgMjQxLAorMTk2LCAxNzEsIDIxOSwgMTc2LCAxODgsIDIzNSwgMTgxLCAyMjQsIDE0MywgMTk0LCAyNDksIDE5NCwgMTg4LCAxOTcsIDIwNiwgMTQzLAorMTk1LCAxNjEsIDIxOSwgMTkxLCAxNDMsIDE5NSwgMTY2LCAyMTksIDE5OSwgMTQzLCAxOTUsIDE3MCwgMTQzLCAxOTUsIDE3NSwgMjE5LAorMTk3LCAxNDMsIDE5NSwgMTc3LCAxNDMsIDE5NSwgMTgxLCAxNDMsIDE5NSwgMTg4LCAxOTksIDI0MCwgMTQzLCAxOTUsIDE5MywgMjE5LAorMjA3LCAyMTksIDIxMSwgMTQzLCAxOTUsIDE4NCwgMTk4LCAyMDIsIDE5MiwgMjQyLCAxNDMsIDE5NSwgMjA0LCAxNDMsIDE5NSwgMjA3LAorMTQzLCAxOTUsIDIxMiwgMTQzLCAxOTUsIDIxNCwgMTQzLCAxOTUsIDIxNywgMTgyLCAyMDUsIDE0MywgMTk1LCAyMjMsIDIwMSwgMTc2LAorMTQzLCAxOTUsIDIyOCwgMTQzLCAxOTUsIDIzMywgMTk5LCAyMjMsIDIxOSwgMjMxLCAxNDMsIDE5NSwgMjQxLCAxNDMsIDE5NSwgMjQ1LAorMTk2LCAyNDQsIDIxOSwgMjM4LCAxODAsIDI1NCwgMTQzLCAxOTUsIDI1NCwgMTQzLCAxOTYsIDE2NSwgMjIwLCAxNjgsIDE0MywgMTk2LAorMTczLCAyMjAsIDE3MCwgMjIwLCAxNjYsIDE5NiwgMTk5LCAxOTEsIDI1MCwgMjIwLCAxNzYsIDIyMCwgMTkxLCAxNDMsIDE5NiwgMTkzLAorMTQzLCAxOTYsIDE5NSwgMjAxLCAyNDYsIDIyMCwgMTk0LCAxNDMsIDE5NiwgMjA0LCAxNDMsIDE5NiwgMjA5LCAyMDcsIDE3NiwgMTg2LAorMjMxLCAyMDcsIDE3NywgMjIwLCAyMTMsIDE0MywgMTk2LCAyMjIsIDE0MywgMTk2LCAyMjUsIDIyMCwgMjAxLCAxODUsIDE4OSwgMTQzLAorMTk2LCAyMzIsIDE0MywgMTk2LCAyMzQsIDIyMCwgMjI5LCAyMjAsIDIyMywgMTQzLCAxOTYsIDI0NCwgMTQzLCAxOTYsIDI0NSwgMjAxLAorMTg0LCAyMjAsIDIzNSwgMjIwLCAyMTEsIDIyMCwgMjQ3LCAyMjAsIDIzNywgMTQzLCAxOTcsIDE3MCwgMTgxLCAyMDQsIDIyMCwgMjQzLAorMTQzLCAxOTcsIDE4MCwgMTQzLCAxOTcsIDE4MiwgMTQzLCAxOTcsIDE4NywgMjIxLCAxNjEsIDIyMCwgMjUzLCAyMjEsIDE2OCwgMjIxLAorMTY2LCAyMjEsIDE2NSwgMTQzLCAxOTcsIDIwNiwgMTQzLCAxOTcsIDIxMCwgMTQzLCAxOTcsIDIxMywgMTQzLCAxOTcsIDIxNiwgMjIxLAorMTc4LCAyMDUsIDI0MywgMTQzLCAxOTcsIDIyNiwgMTQzLCAxOTcsIDIzMCwgMTc4LCAxNjQsIDIwNSwgMjIzLCAxODIsIDIxNCwgMjIxLAorMTg4LCAxNDMsIDE5NywgMjQ0LCAxNDMsIDE5NywgMjQ3LCAxNDMsIDE5NywgMjQ5LCAxODYsIDIwOCwgMTQzLCAxOTcsIDI1NCwgMTg5LAorMjIyLCAyMjEsIDIwNSwgMTQzLCAxOTgsIDE2NiwgMTQzLCAxOTgsIDE3MSwgMjIxLCAyMTMsIDE0MywgMTk4LCAxNzgsIDE0MywgMTk4LAorMTgyLCAyMjEsIDIxOCwgMjIxLCAyMTksIDIyMSwgMjIxLCAxNDMsIDE5OCwgMTkyLCAxNDMsIDE5OCwgMTk1LCAxNDMsIDE5OCwgMTk5LAorMTgxLCAxNjQsIDIyMSwgMjMwLCAxNDMsIDE5OCwgMjA5LCAxNzcsIDIwMiwgMTgxLCAyMjUsIDE0MywgMTk4LCAyMTgsIDE4MCwgMTkyLAorMjIxLCAyMzMsIDE0MywgMTk4LCAyMjYsIDE0MywgMTk4LCAyMzAsIDIyMSwgMjM1LCAxOTgsIDIxNywgMTc4LCAxNzMsIDIwMywgMjE1LAorMjAzLCAyNDcsIDIwMiwgMTY4LCAxNDMsIDE5OCwgMjQ2LCAyMDAsIDIzMSwgMTQzLCAxOTgsIDI1NCwgMTQzLCAxOTksIDE2MywgMjIyLAorMTY1LCAxNDMsIDE5OSwgMTcwLCAxNDMsIDE5OSwgMTcxLCAxNDMsIDE5OSwgMTc0LCAyMjIsIDE3MiwgMTk2LCAxOTcsIDE0MywgMTk5LAorMTg0LCAxNDMsIDE5OSwgMTg2LCAxOTAsIDI0NCwgMTQzLCAxOTksIDE4OSwgMTQzLCAxOTksIDE5MiwgMTc5LCAxODksIDE3OSwgMTY0LAorMTQzLCAxOTksIDE5OCwgMjA1LCAxNzYsIDE0MywgMTk5LCAyMDMsIDE0MywgMTk5LCAyMDYsIDE0MywgMTk5LCAyMDgsIDE0MywgMTk5LAorMjEyLCAxNDMsIDE5OSwgMjE1LCAyMjIsIDIwNCwgMTQzLCAxOTksIDIyMSwgMTQzLCAxOTksIDIyNSwgMTg5LCAyMjMsIDE0MywgMTk5LAorMjMxLCAyMjIsIDE4OSwgMjIyLCAxODgsIDIyMiwgMjE5LCAxNzgsIDE4NSwgMTQzLCAxOTksIDIzNywgMjIyLCAyMjAsIDIyMiwgMjE4LAorMTQzLCAxOTksIDI1MSwgMTQzLCAyMDAsIDE2MSwgMjIyLCAyMDgsIDE0MywgMjAwLCAxNjUsIDIwMCwgMTc0LCAxODksIDIyNCwgMTQzLAorMjAwLCAxNzAsIDIyMiwgMjI4LCAyMDUsIDIwNywgMTQzLCAyMDAsIDE3OCwgMTQzLCAyMDAsIDE4MywgMjIyLCAyMzcsIDE5NCwgMjE4LAorMTQzLCAyMDAsIDE4NywgMjIzLCAxNjMsIDE4MSwgMjQ5LCAxNDMsIDIwMCwgMTk2LCAxNDMsIDIwMCwgMTk4LCAxOTksIDI0OSwgMTQzLAorMjAwLCAyMDQsIDE0MywgMjAwLCAyMDgsIDIyMiwgMjQzLCAxNDMsIDIwMCwgMjEyLCAxNDMsIDIwMCwgMjE3LCAxODksIDIyNSwgMTk2LAorMTcyLCAyMjMsIDE2NiwgMjIzLCAxNzMsIDE0MywgMjAwLCAyMzEsIDE0MywgMjAwLCAyMzcsIDE0MywgMjAwLCAyNDAsIDIyMywgMTg2LAorMTQzLCAyMDAsIDI0OCwgMTgzLCAyMjcsIDE0MywgMjAwLCAyNTQsIDIyMywgMTkwLCAxNDMsIDIwMSwgMTYyLCAxNDMsIDIwMSwgMTYzLAorMjIzLCAxNzEsIDE0MywgMjAxLCAxNjksIDE0MywgMjAxLCAxNzMsIDIyMywgMTk4LCAyMjMsIDIwMiwgMTk1LCAyNDUsIDIyMywgMjA4LAorMTQzLCAyMDEsIDE4MiwgMTQzLCAyMDEsIDE4NSwgMTQzLCAyMDEsIDE4OSwgMTQzLCAyMDEsIDE5MiwgMTc4LCAyMDgsIDE0MywgMjAxLAorMTk4LCAxNDMsIDIwMSwgMjAxLCAxNzcsIDIzNCwgMTQzLCAyMDEsIDIwOCwgMTQzLCAyMDEsIDIxMCwgMjIzLCAyMjAsIDIyMywgMjE4LAorMjA2LCAyNDUsIDE0MywgMjAxLCAyMTgsIDIyMywgMjIzLCAyMjMsIDIxNiwgMjIzLCAyMjYsIDE0MywgMjAxLCAyMzAsIDE3NywgMjM1LAorMTQzLCAyMDEsIDIzNCwgMTQzLCAyMDEsIDIzNiwgMTkzLCAxNzksIDE0MywgMjAxLCAyNDIsIDE0MywgMjAxLCAyNDcsIDIyMywgMjMwLAorMTQzLCAyMDEsIDI1NCwgMjIzLCAyMzYsIDE0MywgMjAyLCAxNjIsIDIyMywgMjM5LCAyMjMsIDIzNywgMjQ0LCAxNjYsIDIyMywgMjQxLAorMTQzLCAyMDIsIDE3NCwgMjIzLCAyNDUsIDE5NywgMjQ1LCAyMjMsIDI0NiwgMTQzLCAyMDIsIDE4NywgMTg3LCAxODQsIDIyMywgMjUzLAorMjI0LCAxNjIsIDE0MywgMjAyLCAxOTMsIDE0MywgMjAyLCAxOTQsIDE0MywgMjAyLCAxOTcsIDIyNCwgMTY2LCAyMjQsIDE3MCwgMjI0LAorMTcyLCAyMjQsIDE3NSwgMTQzLCAyMDIsIDIxMSwgMTQzLCAyMDIsIDIxNSwgMjAzLCAyMTAsIDE0MywgMjAyLCAyMjQsIDE0MywgMjAyLAorMjI3LCAyMjQsIDE4MiwgMjI0LCAxODMsIDE4MSwgMTkwLCAxODQsIDE2NCwgMTkwLCAyNDUsIDE0MywgMjAyLCAyNDIsIDE0MywgMjAyLAorMjQ1LCAxNDMsIDIwMiwgMjQ3LCAyMjQsIDE5NSwgMTk4LCAyMDAsIDIyNCwgMTk4LCAxNDMsIDIwMywgMTYyLCAxNDMsIDIwMywgMTY3LAorMjI0LCAyMDAsIDE0MywgMjAzLCAxNzMsIDE0MywgMjAzLCAxNzcsIDIwNSwgMTc3LCAxNDMsIDIwMywgMTg0LCAxNDMsIDIwMywgMTg1LAorMjI0LCAyMTMsIDE4OSwgMTk1LCAxNDMsIDIwMywgMTk5LCAyMjQsIDIxNywgMTQzLCAyMDMsIDIwNywgMTQzLCAyMDMsIDIxMCwgMTQzLAorMjAzLCAyMTUsIDE0MywgMjAzLCAyMjAsIDE0MywgMjAzLCAyMjUsIDE0MywgMjAzLCAyMjcsIDE3OCwgMjA5LCAxNDMsIDIwMywgMjM2LAorMTQzLCAyMDMsIDI0MCwgMTg4LCAyMzgsIDE4MywgMTkwLCAxNDMsIDIwMywgMjQ4LCAxODQsIDE4OSwgMjA2LCAxNzYsIDE0MywgMjA0LAorMTY4LCAxNDMsIDIwNCwgMTcwLCAxNDMsIDIwNCwgMTc4LCAxNDMsIDIwNCwgMTgyLCAxNDMsIDIwNCwgMTg0LCAxNDMsIDIwNCwgMTg5LAorMTQzLCAyMDQsIDE5MiwgMTQzLCAyMDQsIDE5NCwgMTQzLCAyMDQsIDE5OSwgMjI0LCAyNDcsIDE0MywgMjA0LCAyMDgsIDE0MywgMjA0LAorMjEzLCAyMjQsIDIyOSwgMTQzLCAyMDQsIDIyNiwgMTQzLCAyMDQsIDIzMSwgMTQzLCAyMDQsIDIzNCwgMTQzLCAyMDQsIDIzOCwgMTQzLAorMjA0LCAyNDIsIDE0MywgMjA0LCAyNDUsIDIyNSwgMTY2LCAxNDMsIDIwNCwgMjUyLCAxNDMsIDIwNCwgMjU0LCAxODUsIDI0OSwgMTk3LAorMTg4LCAyMjUsIDE4MCwgMTk3LCAxOTYsIDE5NiwgMTc0LCAyMjUsIDE4MywgMTQzLCAyMDUsIDE4MCwgMjA2LCAxNzcsIDIyNSwgMTkxLAorMTQzLCAyMDUsIDE4NywgMTQzLCAyMDUsIDE4OSwgMTQzLCAyMDUsIDE5NiwgMTkzLCAxOTMsIDE0MywgMjA1LCAyMDEsIDIyNSwgMjA3LAorMjI1LCAyMTUsIDIyNSwgMjE0LCAxNDMsIDIwNSwgMjExLCAyMjUsIDIxOCwgMTQzLCAyMDUsIDIxNiwgMTQzLCAyMDUsIDIyMSwgMTQzLAorMjA1LCAyMjUsIDIyNSwgMjI0LCAxNDMsIDIwNSwgMjMxLCAxNDMsIDIwNSwgMjM2LCAxNDMsIDIwNSwgMjQyLCAxNDMsIDIwNSwgMjQ3LAorMjI1LCAyNDAsIDE0MywgMjA2LCAxNjEsIDE0MywgMjA2LCAxNjcsIDIwNCwgMjU0LCAyMjUsIDI0NSwgMjI1LCAyNTIsIDE0MywgMjA2LAorMTc5LCAxOTcsIDIwOCwgMTQzLCAyMDYsIDE4MiwgMTg3LCAxNjksIDIyNiwgMTczLCAxNDMsIDIwNiwgMTkzLCAyMDAsIDIzMywgMjI2LAorMTc2LCAyMjYsIDE3OSwgMTQzLCAyMDYsIDIwNSwgMjI2LCAxODEsIDE0MywgMjA2LCAyMDksIDIyNiwgMTg3LCAxOTYsIDE5MCwgMTg5LAorMjI2LCAyMjYsIDE5MCwgMTQzLCAyMDYsIDIyMiwgMTQzLCAyMDYsIDIyOCwgMjI2LCAxOTcsIDE0MywgMjA2LCAyMzQsIDE0MywgMjA2LAorMjM5LCAxNDMsIDIwNiwgMjQzLCAxNDMsIDIwNiwgMjQ4LCAxNDMsIDIwNiwgMjUzLCAxNDMsIDIwNywgMTYzLCAxNDMsIDIwNywgMTY4LAorMjI2LCAyMDgsIDIyNiwgMjExLCAxNDMsIDIwNywgMTc2LCAxNDMsIDIwNywgMTc5LCAxNDMsIDIwNywgMTgyLCAxNDMsIDIwNywgMTg2LAorMjI2LCAyMTgsIDE0MywgMjA3LCAxODksIDE0MywgMjA3LCAxOTIsIDE0MywgMjA3LCAxOTUsIDE4MiwgMjM1LCAxOTIsIDIwOCwgMTg2LAorMTg5LCAyMjYsIDIzMCwgMTQzLCAyMDcsIDIxMiwgMTgxLCAyMDYsIDIwMywgMTY0LCAxODUsIDIyMCwgMTQzLCAyMDcsIDIyNSwgMTQzLAorMjA3LCAyMjgsIDE0MywgMjA3LCAyMzQsIDIwMCwgMTYzLCAyMjYsIDIzOSwgMjI2LCAyMzgsIDIwMCwgMjM0LCAxNDMsIDIwNywgMjQ0LAorMjAyLCAyMDMsIDE0MywgMjA3LCAyNTIsIDE0MywgMjA4LCAxNjEsIDIyNiwgMjUyLCAyMDAsIDIxNiwgMjI3LCAxNjIsIDE0MywgMjA4LAorMTczLCAxNzYsIDIzNSwgMTQzLCAyMDgsIDE4NSwgMTQzLCAyMDgsIDE4OCwgMTQzLCAyMDgsIDE5MCwgMTQzLCAyMDgsIDE5MSwgMTQzLAorMjA4LCAxOTYsIDE0MywgMjA4LCAyMDAsIDE0MywgMjA4LCAyMDMsIDE0MywgMjA4LCAyMDcsIDE0MywgMjA4LCAyMTEsIDIyNywgMTc1LAorMTkwLCAyMDUsIDE0MywgMjA4LCAyMjAsIDE0MywgMjA4LCAyMjMsIDIyNywgMTgwLCAxNDMsIDIwOCwgMjI5LCAxNDMsIDIwOCwgMjM1LAorMTQzLCAyMDgsIDIzOCwgMTQzLCAyMDgsIDI0MiwgMTQzLCAyMDgsIDI0NCwgMTQzLCAyMDgsIDI0OSwgMTQzLCAyMDgsIDI1MiwgMTk5LAorMjMzLCAxOTAsIDIwNiwgMTc2LCAyMjAsIDE0MywgMjA5LCAxNzIsIDE0MywgMjA5LCAxNzYsIDE0MywgMjA5LCAxNzgsIDE0MywgMjA5LAorMTgxLCAyMjcsIDIwMiwgMjI3LCAyMDMsIDE0MywgMjA5LCAxOTIsIDE3OCwgMTg2LCAxNDMsIDIwOSwgMTk4LCAxOTAsIDI0NywgMTQzLAorMjA5LCAyMDYsIDE0MywgMjA5LCAyMDgsIDE0MywgMjA5LCAyMTEsIDE0MywgMjA5LCAyMTYsIDE0MywgMjA5LCAyMTksIDIyNywgMjIxLAorMTQzLCAyMDksIDIyMywgMjI3LCAyMjcsIDE0MywgMjA5LCAyMjksIDIyNywgMjM0LCAyMjcsIDIzNywgMTQzLCAyMDksIDIzNCwgMTQzLAorMjA5LCAyMzksIDE0MywgMjA5LCAyNDIsIDE4MSwgMjMyLCAxNDMsIDIwOSwgMjQ0LCAyMjcsIDI1MCwgMjI3LCAyNTIsIDIyNywgMjQ3LAorMTQzLCAyMTAsIDE2MywgMTQzLCAyMTAsIDE2NywgMTk1LCAyMjIsIDIyOCwgMTg0LCAyMjgsIDE3MCwgMjI4LCAxNzIsIDE0MywgMjEwLAorMTgwLCAxNDMsIDIxMCwgMTgyLCAyMjgsIDE3NiwgMTQzLCAyMTAsIDE4OSwgMTQzLCAyMTAsIDE5MSwgMTQzLCAyMTAsIDE5NiwgMjAwLAorMjA3LCAyMjgsIDE4OSwgMTQzLCAyMTAsIDIwNywgMTk4LCAxOTgsIDE0MywgMjEwLCAyMTIsIDE0MywgMjEwLCAyMTgsIDE0MywgMjEwLAorMjI0LCAyMjgsIDE5NCwgMTQzLCAyMTAsIDIzMSwgMTQzLCAyMTAsIDIzMywgMTQzLCAyMTAsIDIzNywgMjI4LCAyMTMsIDE0MywgMjEwLAorMjQ0LCAyMjgsIDIxNiwgMTQzLCAyMTAsIDI1NCwgMTQzLCAyMTEsIDE2NCwgMjAyLCAxOTgsIDE0MywgMjExLCAxNzEsIDE0MywgMjExLAorMTczLCAyMDYsIDE3OSwgMTQzLCAyMTEsIDE3NiwgMjI4LCAyMzQsIDIyOCwgMjM2LCAxNDMsIDIxMSwgMTg0LCAxNDMsIDIxMSwgMTg3LAorMjI4LCAyNDUsIDIyOCwgMjQ2LCAxNDMsIDIxMSwgMTk5LCAyMjgsIDI1MCwgMTgxLCAyMzQsIDE0MywgMjExLCAyMDUsIDE0MywgMjExLAorMjA5LCAyMjksIDE2MiwgMTQzLCAyMTEsIDIxNSwgMTg2LCAyMTcsIDE4NiwgMTc2LCAxOTMsIDIwMCwgMjI5LCAxNzQsIDE0MywgMjExLAorMjMwLCAyMjksIDE3OSwgMjI5LCAxNzcsIDE0MywgMjExLCAyMzgsIDE0MywgMjExLCAyNDMsIDE0MywgMjExLCAyNDksIDE0MywgMjExLAorMjUyLCAyMjksIDE5NCwgMTg4LCAyNTAsIDE0MywgMjEyLCAxNjYsIDE0MywgMjEyLCAxNjksIDE0MywgMjEyLCAxNzQsIDE0MywgMjEyLAorMTc3LCAyMjksIDIwNiwgMTQzLCAyMTIsIDE4NCwgMTQzLCAyMTIsIDE4NywgMTQzLCAyMTIsIDE3OSwgMjI5LCAyMDgsIDE0MywgMjEyLAorMTk0LCAyMjksIDIxMywgMjAzLCAxNjUsIDIyOSwgMjIwLCAxNDMsIDIxMiwgMjA2LCAxOTMsIDE2MSwgMTkxLCAxNjUsIDIyOSwgMjI5LAorMjI5LCAyMzQsIDE0MywgMjEyLCAyMjEsIDIyOSwgMjM5LCAxNDMsIDIxMiwgMjI2LCAxNDMsIDIxMiwgMjI5LCAyMjksIDI1MSwgMTgwLAorMjA0LCAxNDMsIDIxMiwgMjQwLCAyMzAsIDE2MywgMjMwLCAxNjksIDE0MywgMjEyLCAyNTAsIDE0MywgMjEyLCAyNTQsIDIwMCwgMjM3LAorMjMwLCAxNzYsIDIzMCwgMTgxLCAxNDMsIDIxMywgMTcxLCAxNDMsIDIxMywgMTc0LCAxNDMsIDIxMywgMTc4LCAyMzAsIDE5MiwgMTQzLAorMjEzLCAxODMsIDE0MywgMjEzLCAxODUsIDE0MywgMjEzLCAxODcsIDE0MywgMjEzLCAxOTAsIDE0MywgMjEzLCAxOTQsIDIzMCwgMjAzLAorMTg1LCAyMDUsIDE0MywgMjEzLCAyMDMsIDIwNCwgMjE1LCAyMzAsIDIxMiwgMTQzLCAyMTMsIDIxNiwgMjA0LCAyMzcsIDE0MywgMjEzLAorMjI2LCAyMzAsIDIxNiwgMTkyLCAxODcsIDE0MywgMjEzLCAyMjgsIDE0MywgMjEzLCAyMzEsIDE5MSwgMTY2LCAxNDMsIDIxMywgMjM0LAorMjA3LCAxOTAsIDE5MCwgMjExLCAxODQsIDIxMiwgMTQzLCAyMTMsIDI0MSwgMTQzLCAyMTMsIDI0MiwgMTc2LCAyMjMsIDE0MywgMjEzLAorMjQ1LCAxNDMsIDIxMywgMjUwLCAxODQsIDIxMywgMTQzLCAyMTMsIDI1MywgMTgyLCAxODcsIDE4NywgMjMzLCAxNDMsIDIxNCwgMTcwLAorMTQzLCAyMTQsIDE3NSwgMTQzLCAyMTQsIDE3OCwgMTk2LCAxNzcsIDE0MywgMjE0LCAxODMsIDIwMSwgMjI5LCAyMzEsIDE4MSwgMTQzLAorMjE0LCAxOTMsIDIzMSwgMTcxLCAxOTQsIDIyMCwgMjMxLCAxNzQsIDIzMSwgMTc4LCAyMzEsIDE3NywgMTQzLCAyMTQsIDIwOSwgMjMxLAorMTg3LCAyMzEsIDE5MCwgMjMxLCAxOTMsIDE0MywgMjE0LCAyMjAsIDE0MywgMjE0LCAyMjQsIDE0MywgMjE0LCAyMjYsIDE0MywgMjE0LAorMjMxLCAxNDMsIDIxNCwgMjM2LCAyMTgsIDE3MCwgMTQzLCAyMTQsIDI0MCwgMTQzLCAyMTQsIDI0NCwgMTQzLCAyMTQsIDI0NywgMTQzLAorMjE0LCAyNDgsIDIzMSwgMjE3LCAxNDMsIDIxNSwgMTYxLCAxNDMsIDIxNSwgMTY1LCAxNDMsIDIxNSwgMTY3LCAyMzEsIDIyNiwgMTQzLAorMjE1LCAxNzEsIDIzMSwgMjMyLCAxNDMsIDIxNSwgMTgwLCAxNDMsIDIxNSwgMTg0LCAyMzEsIDIzNiwgMTQzLCAyMTUsIDE5NSwgMjAzLAorMTY3LCAxNzgsIDIzNCwgMTQzLCAyMTUsIDIwNywgMTQzLCAyMTUsIDIwOSwgMTQzLCAyMTUsIDIxMiwgMTQzLCAyMTUsIDIxNiwgMjMxLAorMjQ5LCAyMzEsIDI0NywgMTgzLCAyMTIsIDIzMiwgMTczLCAxNDMsIDIxNSwgMjMzLCAxNDMsIDIxNSwgMjM0LCAxOTUsIDIyNywgMjMyLAorMTY2LCAxODMsIDIxMywgMTQzLCAyMTUsIDIyNywgMTQzLCAyMTUsIDI1MywgMTc4LCAxNzQsIDIzMiwgMTc0LCAxNDMsIDIxNiwgMTY4LAorMTQzLCAyMTYsIDE3NCwgMTQzLCAyMTYsIDE3NiwgMjA1LCAyMzMsIDIzMiwgMjA3LCAxNDMsIDIxNiwgMTgzLCAxNDMsIDIxNiwgMTg3LAorMTg2LCAyMTgsIDE0MywgMjE2LCAxOTEsIDIzMiwgMjAzLCAxNDMsIDIxNiwgMTk2LCAxNDMsIDIxNiwgMTk4LCAxNDMsIDIxNiwgMjAxLAorMjMyLCAyMDYsIDIzMiwgMjEyLCAyMzIsIDIyNiwgMTQzLCAyMTYsIDIwNywgMTQzLCAyMTYsIDIxMiwgMTQzLCAyMTYsIDIxNywgMTk4LAorMTYxLCAyMzIsIDIxMSwgMjMyLCAyMTYsIDE0MywgMjE2LCAyMzIsIDE5MCwgMjEzLCAxNDMsIDIxNiwgMjM2LCAyMzIsIDIzMSwgMTQzLAorMjE2LCAyNDAsIDE0MywgMjE2LCAyNDQsIDE0MywgMjE2LCAyNDcsIDE0MywgMjE2LCAyNTEsIDE0MywgMjE2LCAyNTQsIDE0MywgMjE3LAorMTYyLCAxNDMsIDIxNywgMTY2LCAxNDMsIDIxNywgMTcxLCAyMzIsIDIwOSwgMTQzLCAyMTcsIDE3OCwgMTc3LCAxODIsIDE0MywgMjE3LAorMTgzLCAxNDMsIDIxNywgMTg4LCAyMDIsIDE5NSwgMjMyLCAyNTQsIDE0MywgMjE3LCAxOTcsIDE0MywgMjE3LCAyMDEsIDIwNywgMjA3LAorMjMzLCAxNzcsIDE0MywgMjE3LCAyMTYsIDE0MywgMjE3LCAyMjAsIDE3NywgMjQyLCAxNDMsIDIxNywgMjI4LCAyMDQsIDI0NCwgMTQzLAorMjE3LCAyMzIsIDIwNywgMjA2LCAxNDMsIDIxNywgMjQyLCAyMzMsIDE4NSwgMTQzLCAyMTcsIDI0NywgMjAwLCAyMDUsIDE0MywgMjE3LAorMjUyLCAyMzMsIDE5MywgMjMzLCAxOTAsIDIyMSwgMTc3LCAxNDMsIDIxOCwgMTc0LCAyMDUsIDI0NiwgMTQzLCAyMTgsIDE3OCwgMTQzLAorMjE4LCAxODMsIDIzMywgMjAwLCAxNDMsIDIxOCwgMTg4LCAxNDMsIDIxOCwgMTkzLCAxOTUsIDIzOCwgMTQzLCAyMTgsIDIwMCwgMTQzLAorMjE4LCAyMzcsIDIzMywgMjA2LCAxNDMsIDIxOCwgMjEwLCAyMzMsIDIxOSwgMTQzLCAyMTgsIDIxOCwgMTQzLCAyMTgsIDIyMiwgMjMzLAorMjE3LCAyMzMsIDIyMCwgMjMzLCAyMjEsIDIzMywgMjIyLCAxOTQsIDI1MywgMjAzLCAxNzAsIDIzMywgMjM1LCAxOTUsIDIxNiwgMTQzLAorMjE4LCAyNTQsIDE0MywgMjE5LCAxNjIsIDE0MywgMjE5LCAxNjYsIDE0MywgMjE5LCAxNzIsIDE0MywgMjE5LCAxNzQsIDIzMywgMjUxLAorMTQzLCAyMTksIDE3NywgMjMzLCAyNTMsIDIzMywgMjQ3LCAyMzQsIDE2NywgMTQzLCAyMTksIDE5MiwgMTQzLCAyMTksIDE5NiwgMjM0LAorMTY1LCAxNDMsIDIxOSwgMjAzLCAyMDUsIDIzMCwgMjM0LCAxNzUsIDE0MywgMjE5LCAyMTQsIDE0MywgMjE5LCAyMTcsIDE0MywgMjE5LAorMjIyLCAxNDMsIDIxOSwgMjI2LCAyMzQsIDE4NywgMTQzLCAyMTksIDIzMiwgMTQzLCAyMTksIDIzNywgMjM0LCAxOTIsIDE0MywgMjE5LAorMjQ4LCAxNDMsIDIxOSwgMjUwLCAyMzQsIDE5NywgMTQzLCAyMjAsIDE2NCwgMjIyLCAxNjcsIDE3OSwgMTg1LCAxODUsIDIxMywgMjM0LAorMjA2LCAyMzQsIDIxMCwgMTgyLCAyMjIsIDE5NCwgMjIyLCAxOTQsIDE4MSwgMTQzLCAyMjAsIDE5MCwgMTQzLCAyMjAsIDE5MiwgMTg0LAorMjExLCAxNDMsIDIyMCwgMTk1LCAxNDMsIDIyMCwgMTk3LCAyMzQsIDIyNywgMTQzLCAyMjAsIDIwNiwgMjM0LCAyMzUsIDIzNCwgMjM2LAorMjM0LCAyMzMsIDE0MywgMjIwLCAyMTQsIDE3OSwgMjM2LCAxNDMsIDIyMCwgMjIyLCAyMzQsIDI0MywgMTQzLCAyMjAsIDIyOCwgMTQzLAorMjIwLCAyMzMsIDIzNCwgMjQ3LCAxNDMsIDIyMCwgMjQwLCAxNDMsIDIyMCwgMjQzLCAyMzUsIDE2MiwgMTQzLCAyMjAsIDI1MCwgMTQzLAorMjIwLCAyNTQsIDIwMiwgMTY0LCAxNDMsIDIyMSwgMTY2LCAxNzksIDIwOCwgMTQzLCAyMjEsIDE3MywgMjM1LCAxNzgsIDIzNSwgMTgwLAorMTc5LCAyMDksIDIzNSwgMTg1LCAxOTEsIDE2OCwgMTQzLCAyMjEsIDE4OSwgMTQzLCAyMjEsIDE5MywgMTQzLCAyMjEsIDE5NywgMTQzLAorMjIxLCAxOTksIDIzNSwgMTk0LCAyMzUsIDE5NiwgMTQzLCAyMjEsIDIxMCwgMTkxLCAxOTksIDE0MywgMjIxLCAyMTcsIDE4NiwgMTkwLAorMjM1LCAxOTksIDE0MywgMjIxLCAyMjksIDE4MSwgMjA1LCAxNDMsIDIyMSwgMjM1LCAyMzUsIDIwOSwgMTQzLCAyMjEsIDI0MywgMTQzLAorMjIxLCAyNDgsIDIzNSwgMjE2LCAxOTgsIDIwMSwgMTQzLCAyMjIsIDE2MiwgMjM1LCAyMTksIDE4MCwgMjEwLCAyMDcsIDE5MiwgMjM1LAorMjI3LCAyMzUsIDIyMSwgMTQzLCAyMjIsIDE4MCwgMTQzLCAyMjIsIDE4MywgMTQzLCAyMjIsIDE5MSwgMjM1LCAyMjYsIDE0MywgMjIyLAorMTg5LCAyMzUsIDI0NSwgMjM1LCAyNDAsIDIzNSwgMjQ0LCAxNDMsIDIyMiwgMjAxLCAxNDMsIDIyMiwgMjAyLCAyMDEsIDIzMiwgMTgzLAorMjE3LCAxODEsIDE5NiwgMTQzLCAyMjIsIDIxMywgMjE4LCAyMDYsIDE0MywgMjIyLCAyMjEsIDE0MywgMjIyLCAyMjQsIDE5NSwgMTcxLAorMjM2LCAxNzUsIDE0MywgMjIyLCAyMzMsIDIzNiwgMTgxLCAxOTAsIDIyMSwgMjA4LCAxNzQsIDE0MywgMjIyLCAyNTAsIDIzNiwgMTg2LAorMjAzLCAxOTgsIDIzNiwgMTk0LCAxODUsIDIxNSwgMTkyLCAyMTMsIDIzNiwgMjAyLCAxNzgsIDIzNiwgMTk0LCAxNzcsIDE0MywgMjIzLAorMTc4LCAxOTksIDIyOSwgMTg4LCAxOTMsIDE0MywgMjIzLCAxODcsIDE0MywgMjIzLCAxOTEsIDE0MywgMjIzLCAxOTQsIDIzNiwgMjE5LAorMTkyLCAyMTQsIDE0MywgMjIzLCAyMDEsIDE0MywgMjIzLCAyMDIsIDE3NywgMjE5LCAxNDMsIDIyMywgMjA5LCAxNDMsIDIyMywgMjExLAorMTQzLCAyMjMsIDIxNCwgMTQzLCAyMjMsIDIxOCwgMTQzLCAyMjMsIDIyMiwgMTQzLCAyMjMsIDIyNywgMTQzLCAyMjMsIDIzMCwgMjM2LAorMjQwLCAyMzYsIDIzOCwgMTQzLCAyMjMsIDI0MiwgMjM2LCAyNDUsIDIzNiwgMjQ0LCAxNDMsIDIyMywgMjUwLCAyMzYsIDI0NywgMjM3LAorMTY5LCAyMzYsIDI1MywgMTQzLCAyMjQsIDE3MSwgMjM2LCAyNTQsIDE0MywgMjI0LCAxNzcsIDE0MywgMjI0LCAxODEsIDE0MywgMjI0LAorMTg0LCAxODksIDE3OSwgMjM3LCAxNzUsIDIzNywgMTc5LCAxNDMsIDIyNCwgMTk4LCAyMzcsIDE4NiwgMTkxLCAyMDAsIDE0MywgMjI0LAorMjA5LCAxNDMsIDIyNCwgMjEyLCAxODgsIDIxNCwgMTQzLCAyMjQsIDIxOSwgMTk4LCAyNDAsIDIzNywgMTk5LCAxNDMsIDIyNCwgMjI1LAorMTQzLCAyMjQsIDIzMCwgMjM3LCAyMTAsIDE0MywgMjI0LCAyMzUsIDE0MywgMjI0LCAyMzksIDIwNiwgMjE2LCAxNDMsIDIyNCwgMjQ4LAorMjM3LCAyMTcsIDIzNywgMjE5LCAxNDMsIDIyNSwgMTY2LCAxNDMsIDIyNSwgMTcwLCAxOTEsIDIwMSwgMTQzLCAyMjUsIDE3NywgMjM3LAorMjMxLCAyMDIsIDIxMywgMjAzLCAyNDgsIDE4MywgMjIyLCAyMzcsIDIzMywgMTQzLCAyMjUsIDE5NSwgMTQzLCAyMjUsIDE5NywgMjM3LAorMjU0LCAxNDMsIDIyNSwgMjAzLCAxNDMsIDIyNSwgMjA2LCAyMzcsIDI0OCwgMTk0LCAxNjQsIDE0MywgMjI1LCAyMTIsIDE0MywgMjI1LAorMjE2LCAyMzgsIDE2NywgMjM4LCAxNjYsIDE5OCwgMTg3LCAxNDMsIDIyNSwgMjIzLCAxNDMsIDIyNSwgMjI2LCAyMzgsIDE3NSwgMjA2LAorMjAzLCAyMzcsIDIzOCwgMjA1LCAxODQsIDE0MywgMjI1LCAyNDEsIDE0MywgMjI1LCAyNDUsIDIzOCwgMTg0LCAxNDMsIDIyNSwgMjUxLAorMTQzLCAyMjYsIDE2MywgMTQzLCAyMjYsIDE3MywgMTQzLCAyMjYsIDE2OSwgMjAxLCAyNDQsIDE0MywgMjI2LCAxNzgsIDE0MywgMjI2LAorMTc5LCAxNDMsIDIyNiwgMTg1LCAyMzgsIDE5MiwgMTQzLCAyMjYsIDE5MywgMTQzLCAyMjYsIDE5OSwgMTQzLCAyMjYsIDIwMywgMTQzLAorMjI2LCAyMDksIDE0MywgMjI2LCAyMTIsIDE4OCwgMjQyLCAxNDMsIDIyNiwgMjIwLCAxODksIDE4MywgMTg1LCAyNDMsIDE0MywgMjI2LAorMjI4LCAyMzgsIDIwNCwgMTQzLCAyMjYsIDIzNywgMTQzLCAyMjYsIDI0MCwgMjM4LCAyMDgsIDIzOCwgMjExLCAxNDMsIDIyNiwgMjU0LAorMjM4LCAyMTYsIDE0MywgMjI3LCAxNjQsIDE5MSwgMjAzLCAxODIsIDI1MiwgMTQzLCAyMjcsIDE3OSwgMTQzLCAyMjcsIDE4MiwgMTQzLAorMjI3LCAxODcsIDE0MywgMjI3LCAxOTMsIDE0MywgMjI3LCAxOTgsIDE0MywgMjI3LCAyMDMsIDE0MywgMjI3LCAyMDcsIDE0MywgMjI3LAorMjEzLCAxOTcsIDE4MCwgMTQzLCAyMjcsIDIyMywgMTQzLCAyMjcsIDIyNiwgMjAwLCAxNzMsIDE0MywgMjI3LCAyMzYsIDE0MywgMjI3LAorMjQyLCAxODksIDE5OCwgMTQzLCAyMjcsIDI1MSwgMTQzLCAyMjcsIDI1NCwgMTQzLCAyMjgsIDE2NCwgMTQzLCAyMjgsIDE2OSwgMjM4LAorMjQ4LCAxNDMsIDIyOCwgMTgxLCAxNDMsIDIyOCwgMTg4LCAxNDMsIDIyOCwgMTkzLCAxNDMsIDIyOCwgMjAwLCAxNDMsIDIyOCwgMjA1LAorMTgxLCAyNDgsIDE0MywgMjI4LCAyMTIsIDE0MywgMjI4LCAyMTQsIDE5MSwgMjM4LCAyMzksIDE2MiwgMjA3LCAxNjMsIDE0MywgMjI4LAorMjMwLCAyMzgsIDI1MywgMTQzLCAyMjgsIDIzNSwgMTQzLCAyMjgsIDI0MSwgMTQzLCAyMjgsIDI0MywgMjM5LCAxNzEsIDE0MywgMjI5LAorMTYxLCAxNDMsIDIyOSwgMTY3LCAxNDMsIDIyOSwgMTcyLCAxNDMsIDIyOSwgMTc2LCAxNDMsIDIyOSwgMTgxLCAxNDMsIDIyOSwgMTgzLAorMTQzLCAyMjksIDE4OCwgMTQzLCAyMjksIDE5NSwgMjM5LCAxNzgsIDE4MiwgMTkyLCAxNDMsIDIyOSwgMjA3LCAxNDMsIDIyOSwgMjEyLAorMTQzLCAyMjksIDIxNywgMTQzLCAyMjksIDIyMiwgMjM5LCAxOTcsIDIzOSwgMTk1LCAyMzksIDE5NiwgMTQzLCAyMjksIDIzMSwgMTQzLAorMjI5LCAyMzYsIDE0MywgMjI5LCAyMzgsIDE0MywgMjI5LCAyNDEsIDIzOSwgMjA2LCAyMzksIDIwOSwgMjM5LCAyMTYsIDE5NiwgMTg1LAorMjM5LCAyMTcsIDE0MywgMjMwLCAxNjQsIDIzOSwgMjIxLCAyMzksIDIyNCwgMTQzLCAyMzAsIDE3MywgMTQzLCAyMzAsIDE3NiwgMjM5LAorMjM0LCAyMzksIDIzNSwgMTk4LCAxNzQsIDIzOSwgMjQzLCAyMDEsIDIzNiwgMTQzLCAyMzAsIDIwMSwgMTQzLCAyMzAsIDIwMywgMTkzLAorMjAzLCAyMzksIDI1MSwgMTQzLCAyMzAsIDIxNCwgMTQzLCAyMzAsIDIxNywgMjQwLCAxNjUsIDE5OCwgMTcxLCAxNDMsIDIzMCwgMjI0LAorMjMxLCAxNjEsIDI0MCwgMTY4LCAxNDMsIDIzMCwgMjMzLCAxNDMsIDIzMCwgMjM3LCAxNDMsIDIzMCwgMjQwLCAxOTEsIDI1MywgMTQzLAorMjMwLCAyNDIsIDI0MCwgMTg2LCAxNDMsIDIzMCwgMjQ5LCAxNDMsIDIzMCwgMjUwLCAyMDYsIDIzNywgMTg4LCAyNTEsIDIwNiwgMjM4LAorMjQwLCAxOTUsIDE0MywgMjMxLCAxNjcsIDI0MCwgMTk5LCAyNDAsIDIwMSwgMjQwLCAyMDUsIDE5MiwgMTk2LCAyNDAsIDIwOCwgMjQwLAorMjExLCAyNDAsIDIxNSwgMTQzLCAyMzEsIDE5MSwgMjQwLCAyMTcsIDI0MCwgMjIzLCAxNDMsIDIzMSwgMTk5LCAyNDAsIDIyOCwgMjAyLAorMjIwLCAxNDMsIDIzMSwgMjEwLCAyNDAsIDIzMSwgMTQzLCAyMzEsIDIyMywgMTQzLCAyMzEsIDIyOCwgMTQzLCAyMzEsIDIzNSwgMjQwLAorMjM2LCAxNDMsIDIzMSwgMjQwLCAyMDIsIDE5OSwgMjQwLCAyNDMsIDE0MywgMjMxLCAyNDksIDE0MywgMjMxLCAyNTIsIDE0MywgMjMyLAorMTYxLCAxNDMsIDIzMiwgMTY3LCAxNDMsIDIzMiwgMTcwLCAxNzksIDIyMCwgMTgwLCAyMzQsIDE0MywgMjMyLCAxODAsIDE0MywgMjMyLAorMTg1LCAyMDEsIDI0NywgMTQzLCAyMzIsIDE5MCwgMTQzLCAyMzIsIDE5NSwgMTQzLCAyMzIsIDE5OSwgMjAwLCAyNDQsIDE0MywgMjMyLAorMjAyLCAyMDAsIDIxMSwgMTg3LCAyNDQsIDE0MywgMjMyLCAyMDksIDE0MywgMjMyLCAyMTEsIDE0MywgMjMyLCAyMTYsIDE0MywgMjMyLAorMjIwLCAxNDMsIDIzMiwgMjIzLCAxNDMsIDIzMiwgMjMwLCAyNDEsIDE4OSwgMjQxLCAxOTAsIDE0MywgMjMyLCAyNDIsIDE4OCwgMjQzLAorMjQxLCAxOTgsIDE0MywgMjMyLCAyNTEsIDE0MywgMjMzLCAxNjIsIDE5NCwgMjA0LCAxOTUsIDI0MywgMTQzLCAyMzMsIDE3MCwgMTQzLAorMjMzLCAxNzMsIDI0MSwgMjA5LCAyNDEsIDIxMSwgMjQxLCAyMTUsIDI0MSwgMjE0LCAyNDEsIDIxNywgMTQzLCAyMzMsIDE5NCwgMTQzLAorMjMzLCAxOTcsIDI0MSwgMjE5LCAxNDMsIDIzMywgMjA0LCAxNDMsIDIzMywgMjA3LCAyNDEsIDIyNSwgMjQxLCAyMjksIDI0MSwgMjMzLAorMTg1LCAyNTIsIDE0MywgMjMzLCAyMTgsIDI0MSwgMjM4LCAxNDMsIDIzMywgMjI4LCAxNDMsIDIzMywgMjMxLCAxNDMsIDIzMywgMjM2LAorMTQzLCAyMzMsIDI0MCwgMjQxLCAyNDksIDE0MywgMjMzLCAyNDcsIDE0MywgMjMzLCAyNTQsIDE0MywgMjM0LCAxNjcsIDI0MiwgMTYzLAorMjQyLCAxNjYsIDE0MywgMjM0LCAxNzgsIDE0MywgMjM0LCAxODIsIDE3OSwgMTYxLCAxNDMsIDIzNCwgMTg3LCAxNDMsIDIzNCwgMTg5LAorMTQzLCAyMzQsIDE5NCwgMTQzLCAyMzQsIDIwMCwgMTQzLCAyMzQsIDIwNSwgMTQzLCAyMzQsIDIwOSwgMTQzLCAyMzQsIDIxNSwgMjQyLAorMTg0LCAxNDMsIDIzNCwgMjIzLCAxNDMsIDIzNCwgMjI2LCAxNDMsIDIzNCwgMjMwLCAxNDMsIDIzNCwgMjM0LCAyNDIsIDE5NiwgMTQzLAorMjM0LCAyNDIsIDE5NCwgMjI4LCAxNDMsIDIzNCwgMjQ3LCAxNDMsIDIzNCwgMjUxLCAxNDMsIDIzNSwgMTYxLCAyNDIsIDIxOCwgMTQzLAorMjM1LCAxNjgsIDE0MywgMjM1LCAxNzIsIDE0MywgMjM1LCAxNzcsIDIwMSwgMjAxLCAxNDMsIDIzNSwgMTg2LCAxNDMsIDIzNSwgMTg4LAorMTQzLCAyMzUsIDE5NCwgMTQzLCAyMzUsIDIwMCwgMTQzLCAyMzUsIDIwNSwgMTQzLCAyMzUsIDIxMSwgMjQyLCAyMzMsIDE5NiwgMTg3LAorMjQyLCAyMzYsIDE0MywgMjM1LCAyMjIsIDE3OCwgMTcwLCAxNDMsIDIzNSwgMjI1LCAyNDIsIDI0NSwgMTQzLCAyMzUsIDIyOSwgMTQzLAorMjM1LCAyMzQsIDI0MiwgMjQ3LCAyNDMsIDE2NSwgMTc3LCAxNzMsIDE0MywgMjM1LCAyNDgsIDE0MywgMjM1LCAyNTIsIDE0MywgMjM2LAorMTYzLCAxNDMsIDIzNiwgMTY3LCAxNDMsIDIzNiwgMTczLCAxNDMsIDIzNiwgMTc1LCAyNDMsIDE3MCwgMTQzLCAyMzYsIDE4MCwgMTQzLAorMjM2LCAxODMsIDE0MywgMjM2LCAxODYsIDI0MywgMTg2LCAxNDMsIDIzNiwgMTkzLCAxNDMsIDIzNiwgMTk4LCAxNDMsIDIzNiwgMjAyLAorMjQzLCAxOTEsIDE0MywgMjM2LCAyMDcsIDE0MywgMjM2LCAyMTAsIDI0MywgMTkzLCAyNDMsIDE5NSwgMTg4LCAxNzUsIDI0MywgMjAwLAorMjQzLCAyMDMsIDIwNiwgMjE5LCAyNDMsIDIwNywgMTQzLCAyMzYsIDIzOCwgMjIxLCAyMjQsIDE0MywgMjM2LCAyNDIsIDE4NSwgMjQ1LAorMjQzLCAyMTcsIDE0MywgMjM2LCAyNDcsIDE0MywgMjM2LCAyNTIsIDI0MywgMjI4LCAyNDMsIDIzMSwgMTQzLCAyMzcsIDE2OCwgMTQzLAorMjM3LCAxNzUsIDE0MywgMjM3LCAxNzgsIDE0MywgMjM3LCAxODIsIDIwMSwgMTYxLCAxNDMsIDIzNywgMTk0LCAyNDAsIDIzNywgMTQzLAorMjM3LCAyMDIsIDI0MywgMjQ1LCAxNDMsIDIzNywgMjEwLCAxNDMsIDIzNywgMjE0LCAyMDYsIDE4MiwgMTQzLCAyMzcsIDIyMiwgMTQzLAorMjM3LCAyMjQsIDE2MSwgMTcwLCAxNjEsIDIyMCwgMTYzLCAxODEsIDE2MSwgMTY5LCAxNjMsIDIwMSwgMTYzLCAyMTEsIDE2MSwgMjA3LAorMTYzLCAyMzEsIDE2MywgMjQxLCAxNjEsIDIwOCwgMTQyLCAxNjUsIDE0MiwgMTc1LCAxNDIsIDE4NSwgMTQyLCAxOTUsIDE0MiwgMjA1LAorMTQyLCAyMTUsIDE2MSwgMTc3CisgICAgICAgICAgICB9KTsKKworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29kZWNEeW5hbWljICgpIHRocm93cyBDaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb24geworICAgICAgICBlbmNvZGVyLm9uVW5tYXBwYWJsZUNoYXJhY3RlcihDb2RpbmdFcnJvckFjdGlvbi5SRVBPUlQpOworICAgICAgICBkZWNvZGVyLm9uTWFsZm9ybWVkSW5wdXQoQ29kaW5nRXJyb3JBY3Rpb24uUkVQT1JUKTsKKyAgICAgICAgQ2hhckJ1ZmZlciBpbnB1dENCID0gQ2hhckJ1ZmZlci5hbGxvY2F0ZSg2NTUzNik7CisgICAgICAgIGZvciAoaW50IGNvZGUgPSAzMjsgY29kZSA8PSA2NTUzMzsgY29kZSArKykgeworICAgICAgICAgICAgaWYgKChlbmNvZGVyLmNhbkVuY29kZSgoY2hhcikgY29kZSkpCisgICAgICAgICAgICAgICAgICAgICYmIChjb2RlICE9IDE2NSkgJiYgKGNvZGUgIT0gODI1NCkpIHsKKyAgICAgICAgICAgICAgICBpbnB1dENCLnB1dCgoY2hhcikgY29kZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaW5wdXRDQi5yZXdpbmQoKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBpbnRlcm1lZGlhdGVCQiA9IGVuY29kZXIuZW5jb2RlKGlucHV0Q0IpOworICAgICAgICBpbnB1dENCLnJld2luZCgpOworICAgICAgICBpbnRlcm1lZGlhdGVCQi5yZXdpbmQoKTsKKyAgICAgICAgQ2hhckJ1ZmZlciBvdXRwdXRDQiA9IGRlY29kZXIuZGVjb2RlKGludGVybWVkaWF0ZUJCKTsKKyAgICAgICAgb3V0cHV0Q0IucmV3aW5kKCk7CisgICAgICAgIGFzc2VydEVxdWFsQ0JzKCJkZWNvZGUoZW5jb2RlKEEpKSBtdXN0IGJlIGlkZW50aWNhbCB3aXRoIEEhIiwKKyAgICAgICAgICAgICAgICBpbnB1dENCLCBvdXRwdXRDQik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX0VVQ19KUF9BbmRyb2lkLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX0VVQ19KUF9BbmRyb2lkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzczYzk3ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9NdWx0aUJ5dGVfRVVDX0pQX0FuZHJvaWQuamF2YQpAQCAtMCwwICsxLDUyMyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFyc2V0OworCitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5DaGFyQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ29kaW5nRXJyb3JBY3Rpb247CisKKy8qKiBOb3RlOiBJQ1UgYmVoYXZlcyBkaWZmZXJlbnRseSBmcm9tIHRoZSBSSSAqLworCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9NdWx0aUJ5dGVfRVVDX0pQX0FuZHJvaWQgZXh0ZW5kcyBPbGRDaGFyc2V0X0Fic3RyYWN0VGVzdCB7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyc2V0TmFtZSA9ICJFVUMtSlAiOworCisgICAgICAgIHRlc3RDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKzE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCis0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKzY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCis5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKzExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKzE2MSwgMTYyLCAxNjMsIDE2NCwgLyoxNjUsKi8gMTY2LCAxNjcsIDE2OCwgMTY5LCAxNzAsIDE3MiwgMTc0LCAxNzUsIDE3NiwgMTc3LCAxODAsCisxODIsIDE4NCwgMTg2LCAxOTEsIDE5MiwgMTkzLCAxOTQsIDE5NSwgMTk2LCAxOTcsIDE5OCwgMTk5LCAyMDAsIDIwMSwgMjAyLCAyMDMsCisyMDQsIDIwNSwgMjA2LCAyMDcsIDIwOSwgMjEwLCAyMTEsIDIxMiwgMjEzLCAyMTQsIDIxNSwgMjE2LCAyMTcsIDIxOCwgMjE5LCAyMjAsCisyMjEsIDIyMiwgMjIzLCAyMjQsIDIyNSwgMjI2LCAyMjcsIDIyOCwgMjI5LCAyMzAsIDIzMSwgMjMyLCAyMzMsIDIzNCwgMjM1LCAyMzYsCisyMzcsIDIzOCwgMjM5LCAyNDAsIDI0MSwgMjQyLCAyNDMsIDI0NCwgMjQ1LCAyNDYsIDI0NywgMjQ4LCAyNDksIDI1MCwgMjUxLCAyNTIsCisyNTMsIDI1NCwgMjU1LCAyNTYsIDI2NiwgMjc4LCAyODgsIDI5OCwgMzA4LCAzMTgsIDMyOCwgMzM4LCAzNDgsIDM1OCwgMzY4LCAzNzgsCis0NjEsIDQ3MSwgNTAxLCA3MTEsIDcyOCwgOTAwLCA5MTAsIDkyMCwgOTMxLCA5NDEsIDk1MSwgOTYxLCA5NzEsIDEwMjUsIDEwMzUsIDEwNDUsCisxMDU1LCAxMDY1LCAxMDc1LCAxMDg1LCAxMDk1LCAxMTA1LCAxMTE1LCA4MjA4LCA4MjIwLCA4MjMwLCA4MjQwLCA4MjUxLCA4NDUxLCA4NDcwLCA4NDgyLCA4NTkyLAorODY1OCwgODcwNCwgODcxNSwgODczMCwgODc0MywgODc1NiwgODc4NiwgODgwMCwgODgxMCwgODgzNCwgODg2OSwgODk3OCwgOTQ3MiwgOTQ4NCwgOTQ5NSwgOTUwNywKKzk1MTksIDk1MzEsIDk1NDcsIDk2MzIsIDk2NTAsIDk2NjAsIDk2NzAsIDk3MTEsIDk3MzMsIDk3OTIsIDk4MzQsIDEyMjg4LCAxMjI5OCwgMTIzMDgsIDEyMzUzLCAxMjM2MywKKzEyMzczLCAxMjM4MywgMTIzOTMsIDEyNDAzLCAxMjQxMywgMTI0MjMsIDEyNDMzLCAxMjQ0MywgMTI0NTMsIDEyNDYzLCAxMjQ3MywgMTI0ODMsIDEyNDkzLCAxMjUwMywgMTI1MTMsIDEyNTIzLAorMTI1MzMsIDE5OTY4LCAxOTk3OCwgMTk5ODgsIDE5OTk4LCAyMDAwOCwgMjAwMTgsIDIwMDI4LCAyMDAzOSwgMjAwNDksIDIwMDYwLCAyMDA3MiwgMjAwODMsIDIwMDk0LCAyMDEwNCwgMjAxMTQsCisyMDEyNCwgMjAxMzQsIDIwMTQ0LCAyMDE1NCwgMjAxNjQsIDIwMTc0LCAyMDE4NCwgMjAxOTQsIDIwMjA1LCAyMDIxNSwgMjAyMjUsIDIwMjM1LCAyMDI0NSwgMjAyNzAsIDIwMjgwLCAyMDI5MCwKKzIwMzAwLCAyMDMxMCwgMjAzMjAsIDIwMzMwLCAyMDM0MSwgMjAzNTEsIDIwMzYxLCAyMDM3MSwgMjAzODEsIDIwMzk1LCAyMDQwNSwgMjA0MTUsIDIwNDI1LCAyMDQzNiwgMjA0NDcsIDIwNDYyLAorMjA0NzIsIDIwNDg0LCAyMDQ5NCwgMjA1MDQsIDIwNTE0LCAyMDUyNCwgMjA1MzQsIDIwNTQ0LCAyMDU1NCwgMjA1NjUsIDIwNTc1LCAyMDU4NiwgMjA1OTYsIDIwNjA4LCAyMDYxOCwgMjA2MjgsCisyMDYzOCwgMjA2NTAsIDIwNjYwLCAyMDY3MCwgMjA2ODEsIDIwNjkxLCAyMDcwMSwgMjA3MTEsIDIwNzIxLCAyMDczMSwgMjA3NDIsIDIwNzUyLCAyMDc2MiwgMjA3NzUsIDIwNzg1LCAyMDc5NSwKKzIwODA1LCAyMDgxNSwgMjA4MjYsIDIwODM2LCAyMDg0NiwgMjA4NTYsIDIwODY2LCAyMDg3NiwgMjA4ODYsIDIwODk2LCAyMDkwNiwgMjA5MTYsIDIwOTI2LCAyMDkzNiwgMjA5NDYsIDIwOTU2LAorMjA5NjYsIDIwOTc2LCAyMDk4NiwgMjA5OTYsIDIxMDA2LCAyMTAxNiwgMjEwMjYsIDIxMDM4LCAyMTA0OCwgMjEwNTksIDIxMDY5LCAyMTA3OSwgMjEwODksIDIxMTAyLCAyMTExMiwgMjExMjIsCisyMTEzMiwgMjExNDIsIDIxMTUyLCAyMTE2MiwgMjExNzIsIDIxMTgyLCAyMTE5MiwgMjEyMDIsIDIxMjEyLCAyMTIyMiwgMjEyMzIsIDIxMjQyLCAyMTI1MywgMjEyNjMsIDIxMjczLCAyMTI4MywKKzIxMjkzLCAyMTMwNCwgMjEzMTQsIDIxMzI0LCAyMTMzNSwgMjEzNDUsIDIxMzU2LCAyMTM2NywgMjEzNzgsIDIxMzkwLCAyMTQwMCwgMjE0MTIsIDIxNDIyLCAyMTQzMiwgMjE0NDIsIDIxNDUyLAorMjE0NjIsIDIxNDcyLCAyMTQ4MiwgMjE0OTMsIDIxNTA1LCAyMTUxNSwgMjE1MzAsIDIxNTQyLCAyMTU1MywgMjE1NjMsIDIxNTc0LCAyMTU4NSwgMjE1OTgsIDIxNjA4LCAyMTYxOSwgMjE2MjksCisyMTY0MCwgMjE2NTAsIDIxNjYwLCAyMTY3MCwgMjE2ODEsIDIxNjkxLCAyMTcwMiwgMjE3MjAsIDIxNzMwLCAyMTc0MCwgMjE3NTAsIDIxNzYwLCAyMTc3MiwgMjE3ODIsIDIxODAyLCAyMTgxMywKKzIxODI0LCAyMTgzNCwgMjE4NDYsIDIxODU2LCAyMTg4MywgMjE4OTQsIDIxOTA1LCAyMTkxNiwgMjE5MjcsIDIxOTM4LCAyMTk1MSwgMjE5NjEsIDIxOTcxLCAyMTk4MiwgMjE5OTMsIDIyMDA2LAorMjIwMjEsIDIyMDMxLCAyMjA0MSwgMjIwNTcsIDIyMDY3LCAyMjA3NywgMjIwODksIDIyMTAwLCAyMjExMCwgMjIxMjAsIDIyMTMwLCAyMjE0NCwgMjIxNTQsIDIyMTY0LCAyMjE3NCwgMjIxODQsCisyMjE5NSwgMjIyMDYsIDIyMjE2LCAyMjIyNywgMjIyMzcsIDIyMjQ3LCAyMjI1NywgMjIyNjksIDIyMjc5LCAyMjI4OSwgMjIyOTksIDIyMzA5LCAyMjMxOSwgMjIzMzEsIDIyMzQxLCAyMjM1MSwKKzIyMzY5LCAyMjM3OSwgMjIzODksIDIyMzk5LCAyMjQwOSwgMjI0MTksIDIyNDI5LCAyMjQzOSwgMjI0NTEsIDIyNDYxLCAyMjQ3MSwgMjI0ODIsIDIyNDkyLCAyMjUwMiwgMjI1MTIsIDIyNTIyLAorMjI1MzIsIDIyNTQ5LCAyMjU1OSwgMjI1NzAsIDIyNTgwLCAyMjU5MSwgMjI2MDEsIDIyNjEyLCAyMjYyMiwgMjI2MzIsIDIyNjQyLCAyMjY1MiwgMjI2NjMsIDIyNjc1LCAyMjY4NSwgMjI2OTYsCisyMjcwNiwgMjI3MTYsIDIyNzI3LCAyMjczNywgMjI3NDgsIDIyNzYxLCAyMjc3MSwgMjI3ODEsIDIyNzkzLCAyMjgwMywgMjI4MTMsIDIyODIzLCAyMjgzMywgMjI4NDYsIDIyODU2LCAyMjg2NiwKKzIyODc3LCAyMjg4NywgMjI4OTgsIDIyOTA4LCAyMjkyMiwgMjI5MzMsIDIyOTQzLCAyMjk1NiwgMjI5NjcsIDIyOTc3LCAyMjk4NywgMjMwMDEsIDIzMDExLCAyMzAyMiwgMjMwMzUsIDIzMDQ5LAorMjMwNTksIDIzMDcwLCAyMzA4MCwgMjMwOTMsIDIzMTA0LCAyMzExNiwgMjMxMzAsIDIzMTQxLCAyMzE1OSwgMjMxNzksIDIzMTkwLCAyMzIwMCwgMjMyMTIsIDIzMjI0LCAyMzIzNCwgMjMyNDQsCisyMzI1NCwgMjMyNjQsIDIzMjc0LCAyMzI4NSwgMjMyOTYsIDIzMzA3LCAyMzMxOCwgMjMzMjksIDIzMzQwLCAyMzM1MCwgMjMzNjAsIDIzMzcxLCAyMzM4MSwgMjMzOTEsIDIzNDAxLCAyMzQxMSwKKzIzNDIxLCAyMzQzMSwgMjM0NDEsIDIzNDUxLCAyMzQ2MSwgMjM0NzEsIDIzNDgxLCAyMzQ5MSwgMjM1MDEsIDIzNTExLCAyMzUyMSwgMjM1MzEsIDIzNTQxLCAyMzU1MSwgMjM1NjEsIDIzNTcxLAorMjM1ODIsIDIzNTkyLCAyMzYwMiwgMjM2MTIsIDIzNjIyLCAyMzYzMiwgMjM2NDIsIDIzNjUyLCAyMzY2MiwgMjM2NzMsIDIzNjg3LCAyMzY5NywgMjM3MDksIDIzNzIwLCAyMzczMCwgMjM3NDAsCisyMzc1MSwgMjM3NjIsIDIzNzczLCAyMzc4NCwgMjM3OTQsIDIzODA1LCAyMzgxNSwgMjM4MjUsIDIzODM1LCAyMzg0NiwgMjM4NTcsIDIzODY5LCAyMzg4MCwgMjM4OTAsIDIzOTAwLCAyMzkxMywKKzIzOTIzLCAyMzkzNCwgMjM5NDQsIDIzOTU0LCAyMzk2NSwgMjM5NzUsIDIzOTg2LCAyMzk5NiwgMjQwMDcsIDI0MDE4LCAyNDAyOSwgMjQwMzksIDI0MDQ5LCAyNDA1OSwgMjQwNzAsIDI0MDgxLAorMjQwOTEsIDI0MTAxLCAyNDExMSwgMjQxMjUsIDI0MTM1LCAyNDE0NSwgMjQxNTUsIDI0MTY4LCAyNDE3OCwgMjQxODgsIDI0MTk5LCAyNDIxMywgMjQyMjQsIDI0MjM0LCAyNDI0NSwgMjQyNTUsCisyNDI2NSwgMjQyNzUsIDI0Mjg1LCAyNDI5NiwgMjQzMDcsIDI0MzE4LCAyNDMyOCwgMjQzMzksIDI0MzQ5LCAyNDM1OSwgMjQzNjksIDI0Mzc5LCAyNDM4OSwgMjQ0MDAsIDI0NDExLCAyNDQyMiwKKzI0NDMyLCAyNDQ0MiwgMjQ0NTIsIDI0NDYzLCAyNDQ3MywgMjQ0ODQsIDI0NDk0LCAyNDUwNCwgMjQ1MTUsIDI0NTI1LCAyNDUzNSwgMjQ1NDUsIDI0NTU1LCAyNDU2NSwgMjQ1NzUsIDI0NTg2LAorMjQ1OTYsIDI0NjA3LCAyNDYxNywgMjQ2MjcsIDI0NjQwLCAyNDY1MCwgMjQ2NjAsIDI0NjcxLCAyNDY4MSwgMjQ2OTMsIDI0NzAzLCAyNDcxMywgMjQ3MjMsIDI0NzMzLCAyNDc0MywgMjQ3NTMsCisyNDc2MywgMjQ3NzMsIDI0NzgzLCAyNDc5MywgMjQ4MDMsIDI0ODE2LCAyNDgyNiwgMjQ4MzgsIDI0ODQ4LCAyNDg1OCwgMjQ4NzEsIDI0ODgxLCAyNDg5MiwgMjQ5MDIsIDI0OTE1LCAyNDkyNSwKKzI0OTM1LCAyNDk0NSwgMjQ5NTUsIDI0OTY3LCAyNDk3NywgMjQ5ODgsIDI0OTk5LCAyNTAxMCwgMjUwMjAsIDI1MDMwLCAyNTA0MCwgMjUwNTIsIDI1MDYyLCAyNTA3NCwgMjUwODQsIDI1MDk1LAorMjUxMDUsIDI1MTE1LCAyNTEyNiwgMjUxMzYsIDI1MTQ3LCAyNTE1OCwgMjUxNjgsIDI1MTc4LCAyNTE4OCwgMjUxOTgsIDI1MjA5LCAyNTIxOSwgMjUyMjksIDI1MjM5LCAyNTI1NCwgMjUyNjUsCisyNTI3NSwgMjUyODUsIDI1Mjk1LCAyNTMwNSwgMjUzMjIsIDI1MzMyLCAyNTM0MiwgMjUzNTIsIDI1MzYzLCAyNTM3NSwgMjUzODUsIDI1Mzk3LCAyNTQwNywgMjU0MTcsIDI1NDI3LCAyNTQ0NSwKKzI1NDU3LCAyNTQ2NywgMjU0NzksIDI1NDkwLCAyNTUwMiwgMjU1MTIsIDI1NTIyLCAyNTUzMywgMjU1NDQsIDI1NTU0LCAyNTU2NCwgMjU1NzcsIDI1NTg3LCAyNTYwNiwgMjU2MTYsIDI1NjI4LAorMjU2MzgsIDI1NjQ4LCAyNTY1OCwgMjU2NzUsIDI1Njg4LCAyNTY5OSwgMjU3MDksIDI1NzIwLCAyNTczMSwgMjU3NDMsIDI1NzUzLCAyNTc2MywgMjU3NzMsIDI1Nzg1LCAyNTc5NiwgMjU4MDYsCisyNTgxNiwgMjU4MjYsIDI1ODM2LCAyNTg0NiwgMjU4NTYsIDI1ODY2LCAyNTg3NiwgMjU4ODYsIDI1ODk3LCAyNTkwOCwgMjU5MTgsIDI1OTI4LCAyNTkzOCwgMjU5NDksIDI1OTU5LCAyNTk3MCwKKzI1OTgxLCAyNTk5MSwgMjYwMDEsIDI2MDExLCAyNjAyMSwgMjYwMzEsIDI2MDQxLCAyNjA1MSwgMjYwNjIsIDI2MDcyLCAyNjA4MiwgMjYwOTIsIDI2MTA1LCAyNjExNSwgMjYxMjUsIDI2MTQwLAorMjYxNTAsIDI2MTYwLCAyNjE3MiwgMjYxODIsIDI2MTkzLCAyNjIwMywgMjYyMTQsIDI2MjI0LCAyNjIzNCwgMjYyNDQsIDI2MjU0LCAyNjI2NCwgMjYyNzQsIDI2Mjg1LCAyNjI5NiwgMjYzMDYsCisyNjMxNiwgMjYzMjYsIDI2MzM2LCAyNjM0NywgMjYzNTcsIDI2MzY3LCAyNjM3NywgMjYzODcsIDI2Mzk3LCAyNjQwNywgMjY0MTcsIDI2NDI5LCAyNjQzOSwgMjY0NDksIDI2NDYwLCAyNjQ3MCwKKzI2NDgwLCAyNjQ5MSwgMjY1MDEsIDI2NTExLCAyNjUyMSwgMjY1MzQsIDI2NTQ0LCAyNjU1NSwgMjY1NjUsIDI2NTc1LCAyNjU4NSwgMjY1OTYsIDI2NjA2LCAyNjYxNywgMjY2MjcsIDI2NjQzLAorMjY2NTMsIDI2NjYzLCAyNjY3MywgMjY2ODMsIDI2NjkzLCAyNjcwNCwgMjY3MTUsIDI2NzI3LCAyNjczNywgMjY3NDcsIDI2NzU3LCAyNjc2NywgMjY3NzgsIDI2Nzg5LCAyNjc5OSwgMjY4MDksCisyNjgyMCwgMjY4MzEsIDI2ODQxLCAyNjg1MSwgMjY4NjEsIDI2ODczLCAyNjg4NCwgMjY4OTQsIDI2OTA1LCAyNjkxNSwgMjY5MjgsIDI2OTM5LCAyNjk0OSwgMjY5NjMsIDI2OTczLCAyNjk4NCwKKzI2OTk0LCAyNzAwNCwgMjcwMTgsIDI3MDI4LCAyNzA0MCwgMjcwNTEsIDI3MDYzLCAyNzA3MywgMjcwODMsIDI3MDk0LCAyNzEwNiwgMjcxMTcsIDI3MTI5LCAyNzEzOSwgMjcxNTEsIDI3MTYxLAorMjcxNzEsIDI3MTgyLCAyNzE5MiwgMjcyMDQsIDI3MjE0LCAyNzIyNCwgMjcyMzQsIDI3MjQ5LCAyNzI2MiwgMjcyNzMsIDI3Mjg3LCAyNzI5OCwgMjczMDgsIDI3MzIwLCAyNzMzMCwgMjczNDAsCisyNzM1MCwgMjczNjQsIDI3Mzc2LCAyNzM4NiwgMjczOTYsIDI3NDA3LCAyNzQxOSwgMjc0MzEsIDI3NDQyLCAyNzQ1MywgMjc0NjMsIDI3NDc0LCAyNzQ4NSwgMjc0OTUsIDI3NTA3LCAyNzUxNywKKzI3NTI5LCAyNzU0MSwgMjc1NTEsIDI3NTYxLCAyNzU3MSwgMjc1ODEsIDI3NTkzLCAyNzYwMywgMjc2MTUsIDI3NjI3LCAyNzYzOSwgMjc2NTAsIDI3NjYxLCAyNzY3MSwgMjc2ODMsIDI3Njk0LAorMjc3MDQsIDI3NzE0LCAyNzcyNSwgMjc3MzUsIDI3NzQ2LCAyNzc1NywgMjc3NjgsIDI3Nzc4LCAyNzc4OCwgMjc3OTgsIDI3ODA5LCAyNzgxOSwgMjc4MzIsIDI3ODQyLCAyNzg1MiwgMjc4NjIsCisyNzg3MiwgMjc4ODIsIDI3ODkyLCAyNzkwOCwgMjc5MTgsIDI3OTI5LCAyNzk0MSwgMjc5NTEsIDI3OTYxLCAyNzk3MiwgMjc5OTEsIDI4MDAxLCAyODAxMiwgMjgwMjMsIDI4MDM0LCAyODA0NCwKKzI4MDU0LCAyODA3NCwgMjgwODQsIDI4MDk1LCAyODEwNiwgMjgxMTcsIDI4MTI3LCAyODEzNywgMjgxNDcsIDI4MTYwLCAyODE3MCwgMjgxODEsIDI4MTkxLCAyODIwMSwgMjgyMTQsIDI4MjI3LAorMjgyMzcsIDI4MjQ3LCAyODI1OCwgMjgyNzAsIDI4MjgzLCAyODMwMCwgMjgzMTAsIDI4MzIwLCAyODMzMCwgMjgzNDIsIDI4MzUyLCAyODM2MiwgMjgzNzIsIDI4MzgyLCAyODM5NSwgMjg0MDcsCisyODQxNywgMjg0MjgsIDI4NDM4LCAyODQ0OCwgMjg0NTgsIDI4NDcwLCAyODQ4MSwgMjg0OTUsIDI4NTA1LCAyODUxNiwgMjg1MjYsIDI4NTM2LCAyODU0NiwgMjg1NTYsIDI4NTY2LCAyODU3NiwKKzI4NTg2LCAyODU5NywgMjg2MDgsIDI4NjE4LCAyODYyOCwgMjg2MzgsIDI4NjQ4LCAyODY1OSwgMjg2NjksIDI4Njc5LCAyODY4OSwgMjg2OTksIDI4NzEwLCAyODcyMCwgMjg3MzIsIDI4NzQ0LAorMjg3NTYsIDI4NzY2LCAyODc3OSwgMjg3ODksIDI4ODAxLCAyODgxNCwgMjg4MjQsIDI4ODM2LCAyODg0NiwgMjg4NTYsIDI4ODcyLCAyODg4MywgMjg4OTMsIDI4OTEzLCAyODkyNSwgMjg5MzUsCisyODk0OCwgMjg5NTgsIDI4OTcxLCAyODk4MiwgMjg5OTMsIDI5MDAzLCAyOTAxMywgMjkwMjQsIDI5MDM2LCAyOTA0OSwgMjkwNjAsIDI5MDcxLCAyOTA4MSwgMjkwOTYsIDI5MTA2LCAyOTExOCwKKzI5MTI4LCAyOTEzOCwgMjkxNDgsIDI5MTU4LCAyOTE3MywgMjkxODMsIDI5MTkzLCAyOTIwMywgMjkyMTMsIDI5MjI0LCAyOTIzNCwgMjkyNDQsIDI5MjU0LCAyOTI2NCwgMjkyNzQsIDI5Mjg3LAorMjkyOTcsIDI5MzA3LCAyOTMxOSwgMjkzMzAsIDI5MzQ0LCAyOTM1NiwgMjkzNjYsIDI5Mzc3LCAyOTM4OCwgMjkzOTgsIDI5NDA4LCAyOTQyMCwgMjk0MzEsIDI5NDQyLCAyOTQ1MywgMjk0NjMsCisyOTQ3NCwgMjk0ODQsIDI5NDk0LCAyOTUwNywgMjk1MTcsIDI5NTI3LCAyOTUzOSwgMjk1NTAsIDI5NTYwLCAyOTU3MSwgMjk1ODIsIDI5NTkyLCAyOTYwMiwgMjk2MTMsIDI5NjIzLCAyOTYzNCwKKzI5NjQ0LCAyOTY1NCwgMjk2NjQsIDI5Njc0LCAyOTY4NCwgMjk2OTQsIDI5NzA1LCAyOTcyMiwgMjk3MzIsIDI5NzQyLCAyOTc1MywgMjk3NjMsIDI5NzczLCAyOTc4MywgMjk3OTQsIDI5ODA1LAorMjk4MjIsIDI5ODMzLCAyOTg0OCwgMjk4NTgsIDI5ODcwLCAyOTg4MSwgMjk4OTYsIDI5OTA3LCAyOTkxOCwgMjk5MjgsIDI5OTM4LCAyOTk0OCwgMjk5NTgsIDI5OTY5LCAyOTk4MCwgMjk5OTAsCiszMDAwMCwgMzAwMTAsIDMwMDIwLCAzMDAzMCwgMzAwNDEsIDMwMDUyLCAzMDA2MywgMzAwNzMsIDMwMDg1LCAzMDA5NSwgMzAxMDUsIDMwMTE1LCAzMDEyOSwgMzAxNDAsIDMwMTUwLCAzMDE2MiwKKzMwMTcyLCAzMDE4MywgMzAxOTMsIDMwMjA0LCAzMDIxNSwgMzAyMjYsIDMwMjM2LCAzMDI0NiwgMzAyNTYsIDMwMjY2LCAzMDI3NiwgMzAyOTAsIDMwMzAwLCAzMDMxMSwgMzAzMjEsIDMwMzMxLAorMzAzNDEsIDMwMzUyLCAzMDM2MiwgMzAzNzIsIDMwMzgyLCAzMDM5MiwgMzA0MDIsIDMwNDEyLCAzMDQyMiwgMzA0MzIsIDMwNDQyLCAzMDQ1MiwgMzA0NjIsIDMwNDcyLCAzMDQ4MiwgMzA0OTIsCiszMDUwMiwgMzA1MTYsIDMwNTI2LCAzMDUzOCwgMzA1NTAsIDMwNTYwLCAzMDU3MCwgMzA1ODAsIDMwNTkwLCAzMDYwMywgMzA2MTMsIDMwNjIzLCAzMDYzNCwgMzA2NDUsIDMwNjU1LCAzMDY2NSwKKzMwNjc3LCAzMDY4NywgMzA2OTcsIDMwNzA3LCAzMDcyMiwgMzA3MzIsIDMwNzQ5LCAzMDc1OSwgMzA3NzAsIDMwNzgzLCAzMDc5NiwgMzA4MTIsIDMwODI0LCAzMDgzNCwgMzA4NDQsIDMwODU0LAorMzA4NjUsIDMwODc3LCAzMDg4NywgMzA4OTcsIDMwOTA3LCAzMDkxNywgMzA5MjgsIDMwOTM4LCAzMDk0OCwgMzA5NTksIDMwOTcwLCAzMDk4MiwgMzA5OTIsIDMxMDAyLCAzMTAxMywgMzEwMjUsCiszMTAzNSwgMzEwNDUsIDMxMDU1LCAzMTA2NiwgMzEwNzcsIDMxMDkwLCAzMTEwMCwgMzExMTQsIDMxMTI0LCAzMTEzNywgMzExNDcsIDMxMTYwLCAzMTE3MCwgMzExODMsIDMxMTk0LCAzMTIwNCwKKzMxMjE2LCAzMTIyNywgMzEyMzksIDMxMjQ5LCAzMTI1OSwgMzEyNzEsIDMxMjgxLCAzMTI5MSwgMzEzMDEsIDMxMzExLCAzMTMyMSwgMzEzMzEsIDMxMzQxLCAzMTM1MiwgMzEzNjIsIDMxMzc2LAorMzEzOTAsIDMxNDAxLCAzMTQxMSwgMzE0MjMsIDMxNDMzLCAzMTQ0MywgMzE0NTMsIDMxNDY0LCAzMTQ3NiwgMzE0ODYsIDMxNDk2LCAzMTUwOCwgMzE1MTgsIDMxNTI4LCAzMTUzOSwgMzE1NDksCiszMTU1OSwgMzE1NjksIDMxNTgxLCAzMTU5MSwgMzE2MDEsIDMxNjIwLCAzMTYzMCwgMzE2NDAsIDMxNjUzLCAzMTY2MywgMzE2NzQsIDMxNjg0LCAzMTY5NSwgMzE3MDUsIDMxNzE2LCAzMTczMCwKKzMxNzQwLCAzMTc1MCwgMzE3NjEsIDMxNzcxLCAzMTc4MSwgMzE3OTMsIDMxODA1LCAzMTgxOCwgMzE4MjgsIDMxODM4LCAzMTg0OSwgMzE4NTksIDMxODY5LCAzMTg3OSwgMzE4OTAsIDMxOTAyLAorMzE5MTIsIDMxOTIyLCAzMTkzMiwgMzE5NDMsIDMxOTU0LCAzMTk2NCwgMzE5NzQsIDMxOTg2LCAzMTk5OCwgMzIwMDgsIDMyMDE4LCAzMjAyOCwgMzIwMzgsIDMyMDQ4LCAzMjA1OCwgMzIwNjgsCiszMjA3OCwgMzIwODksIDMyMDk5LCAzMjExMCwgMzIxMjAsIDMyMTMwLCAzMjE0MCwgMzIxNTAsIDMyMTYyLCAzMjE3MiwgMzIxODIsIDMyMTk0LCAzMjIwNCwgMzIyMTUsIDMyMjI1LCAzMjIzNSwKKzMyMjQ1LCAzMjI1NiwgMzIyNjYsIDMyMjc3LCAzMjI4NywgMzIyOTksIDMyMzA5LCAzMjMxOSwgMzIzMzAsIDMyMzQwLCAzMjM1MCwgMzIzNjEsIDMyMzcxLCAzMjM4MSwgMzIzOTEsIDMyNDAxLAorMzI0MTEsIDMyNTY2LCAzMjU3OSwgMzI1ODksIDMyNjAwLCAzMjYxMSwgMzI2MjEsIDMyNjMxLCAzMjY0MiwgMzI2NTIsIDMyNjYyLCAzMjY3MywgMzI2ODUsIDMyNjk2LCAzMjcwNywgMzI3MTgsCiszMjczMSwgMzI3NDEsIDMyNzUxLCAzMjc2MSwgMzI3NzEsIDMyNzgxLCAzMjc5MSwgMzI4MDEsIDMyODEyLCAzMjgyMiwgMzI4MzIsIDMyODQyLCAzMjg1NCwgMzI4NjQsIDMyODc3LCAzMjg4NywKKzMyODk3LCAzMjkwNywgMzI5MTgsIDMyOTI5LCAzMjkzOSwgMzI5NTIsIDMyOTYzLCAzMjk3MywgMzI5ODMsIDMyOTkzLCAzMzAwNSwgMzMwMTYsIDMzMDI2LCAzMzA0NiwgMzMwNTYsIDMzMDY4LAorMzMwODEsIDMzMDkzLCAzMzEwNCwgMzMxMTksIDMzMTI5LCAzMzE0MCwgMzMxNTEsIDMzMTYyLCAzMzE3MywgMzMxODQsIDMzMTk4LCAzMzIwOCwgMzMyMTgsIDMzMjI5LCAzMzIzOSwgMzMyNDksCiszMzI1OSwgMzMyNjksIDMzMjc5LCAzMzI4OSwgMzMyOTksIDMzMzA5LCAzMzMyMCwgMzMzMzAsIDMzMzQ0LCAzMzM1NSwgMzMzNjYsIDMzMzc2LCAzMzM4NiwgMzMzOTYsIDMzNDA2LCAzMzQxNywKKzMzNDI4LCAzMzQzOSwgMzM0NDksIDMzNDU5LCAzMzQ2OSwgMzM0ODgsIDMzNDk4LCAzMzUwOCwgMzM1MTksIDMzNTI5LCAzMzUzOSwgMzM1NTAsIDMzNTYwLCAzMzU3MCwgMzM1ODAsIDMzNTkwLAorMzM2MDAsIDMzNjEwLCAzMzYyMCwgMzM2NDgsIDMzNjU5LCAzMzY2OSwgMzM2ODIsIDMzNjkyLCAzMzcwMiwgMzM3MTMsIDMzNzI1LCAzMzczNSwgMzM3NDUsIDMzNzU2LCAzMzc2OCwgMzM3NzgsCiszMzc4OCwgMzM3OTgsIDMzODA5LCAzMzgyNCwgMzM4MzQsIDMzODQ1LCAzMzg2MSwgMzM4NzEsIDMzODgxLCAzMzg5MSwgMzM5MDEsIDMzOTExLCAzMzkyMSwgMzM5MzEsIDMzOTQxLCAzMzk1MSwKKzMzOTYxLCAzMzk3MiwgMzM5ODIsIDMzOTkyLCAzNDAwMywgMzQwMjMsIDM0MDMzLCAzNDA0MywgMzQwNTQsIDM0MDY0LCAzNDA3NCwgMzQwODQsIDM0MDk1LCAzNDEwOSwgMzQxMjAsIDM0MTMwLAorMzQxNDAsIDM0MTUyLCAzNDE2NywgMzQxNzcsIDM0MTg3LCAzNDE5OSwgMzQyMTAsIDM0MjIwLCAzNDIzMCwgMzQyNDEsIDM0MjUxLCAzNDI2MSwgMzQyNzEsIDM0MjgxLCAzNDI5MSwgMzQzMDIsCiszNDMxNCwgMzQzMjYsIDM0MzM3LCAzNDM0OSwgMzQzNjAsIDM0MzcwLCAzNDM4MSwgMzQzOTEsIDM0NDAxLCAzNDQxMSwgMzQ0MjEsIDM0NDQwLCAzNDQ1MSwgMzQ0NjUsIDM0NDc1LCAzNDQ4NSwKKzM0NDk1LCAzNDUwNSwgMzQ1MTYsIDM0NTI2LCAzNDUzNywgMzQ1NTIsIDM0NTYyLCAzNDU3MywgMzQ1ODQsIDM0NTk1LCAzNDYwNiwgMzQ2MTcsIDM0NjI3LCAzNDYzNywgMzQ2NDcsIDM0NjU3LAorMzQ2NzAsIDM0NjgwLCAzNDY5MCwgMzQ3MDAsIDM0NzExLCAzNDcyMiwgMzQ3MzIsIDM0NzQ2LCAzNDc1NiwgMzQ3NjYsIDM0Nzc3LCAzNDc4NywgMzQ3OTcsIDM0ODA3LCAzNDgxNywgMzQ4MjcsCiszNDgzNywgMzQ4NDcsIDM0ODYxLCAzNDg3MywgMzQ4ODMsIDM0ODkzLCAzNDkwMywgMzQ5MTMsIDM0OTIzLCAzNDkzMywgMzQ5NDMsIDM0OTU1LCAzNDk2NiwgMzQ5NzYsIDM0OTg2LCAzNDk5NiwKKzM1MDA2LCAzNTAxOCwgMzUwMjgsIDM1MDM4LCAzNTA0OCwgMzUwNTgsIDM1MDY4LCAzNTA3OCwgMzUwODgsIDM1MDk4LCAzNTEwOSwgMzUxMjAsIDM1MTMwLCAzNTE0MCwgMzUxNTEsIDM1MTYyLAorMzUxNzIsIDM1MTgyLCAzNTE5NCwgMzUyMDYsIDM1MjE2LCAzNTIyNiwgMzUyMzcsIDM1MjQ3LCAzNTI1OCwgMzUyODIsIDM1MjkyLCAzNTMwMiwgMzUzMTMsIDM1MzI1LCAzNTMzNSwgMzUzNDUsCiszNTM1NSwgMzUzNjUsIDM1Mzc1LCAzNTM4NiwgMzUzOTcsIDM1NDA4LCAzNTQxOSwgMzU0MjksIDM1NDQwLCAzNTQ1MCwgMzU0NjAsIDM1NDcxLCAzNTQ4MSwgMzU0OTEsIDM1NTAxLCAzNTUxMSwKKzM1NTIyLCAzNTUzMiwgMzU1NDIsIDM1NTUyLCAzNTU2MywgMzU1NzMsIDM1NTgzLCAzNTU5NCwgMzU2MDQsIDM1NjE0LCAzNTYyNCwgMzU2MzUsIDM1NjQ2LCAzNTY1NiwgMzU2NjYsIDM1Njc2LAorMzU2ODYsIDM1Njk2LCAzNTcwOCwgMzU3MjIsIDM1NzMyLCAzNTc0MiwgMzU4OTUsIDM1OTA1LCAzNTkxNSwgMzU5MjUsIDM1OTM3LCAzNTk0NywgMzU5NTcsIDM1OTcwLCAzNTk4MCwgMzU5OTIsCiszNjAwMiwgMzYwMTIsIDM2MDIyLCAzNjAzMiwgMzYwNDIsIDM2MDUzLCAzNjA2NCwgMzYwNzQsIDM2MDg1LCAzNjA5NSwgMzYxMDUsIDM2MTE1LCAzNjE5NiwgMzYyMDYsIDM2MjIzLCAzNjIzNCwKKzM2MjQ1LCAzNjI1NSwgMzYyNjcsIDM2Mjc3LCAzNjI4OCwgMzYyOTgsIDM2MzA4LCAzNjMxOSwgMzYzMzAsIDM2MzQwLCAzNjM1MSwgMzYzNjEsIDM2MzcyLCAzNjM4MiwgMzYzOTQsIDM2NDA0LAorMzY0MTYsIDM2NDI2LCAzNjQzNiwgMzY0NDYsIDM2NDU3LCAzNjQ2OCwgMzY0ODEsIDM2NDkxLCAzNjUwMSwgMzY1MTMsIDM2NTIzLCAzNjUzMywgMzY1NDQsIDM2NTU0LCAzNjU2NCwgMzY1NzUsCiszNjU4NywgMzY1OTksIDM2NjEwLCAzNjYyMCwgMzY2MzAsIDM2NjQwLCAzNjY1MCwgMzY2NjAsIDM2NjcwLCAzNjY4MSwgMzY2OTEsIDM2NzAxLCAzNjc2MywgMzY3NzMsIDM2NzgzLCAzNjc5NCwKKzM2ODA0LCAzNjgxNCwgMzY4MjYsIDM2ODM2LCAzNjg0NiwgMzY4NTYsIDM2ODY2LCAzNjg3NiwgMzY4ODYsIDM2ODk2LCAzNjkwNiwgMzY5MTYsIDM2OTI2LCAzNjkzNywgMzY5NDcsIDM2OTU3LAorMzY5NjcsIDM2OTc4LCAzNjk4OCwgMzY5OTksIDM3MDA5LCAzNzAxOSwgMzcwMjksIDM3MDM5LCAzNzA1MywgMzcwNjMsIDM3MDc0LCAzNzA4NCwgMzcwOTYsIDM3MTA4LCAzNzExOCwgMzcxMjgsCiszNzEzOCwgMzcxNDgsIDM3MTU5LCAzNzE2OSwgMzcxODAsIDM3MTkxLCAzNzIwMiwgMzcyMTcsIDM3MjI4LCAzNzIzOSwgMzcyNDksIDM3MjU5LCAzNzI2OSwgMzcyODEsIDM3MjkxLCAzNzMwMSwKKzM3MzExLCAzNzMyMSwgMzczMzEsIDM3MzQxLCAzNzM1MSwgMzczNjEsIDM3MzcxLCAzNzM4MSwgMzczOTIsIDM3NDA0LCAzNzQxNCwgMzc0MjQsIDM3NDM0LCAzNzQ0NCwgMzc0NTQsIDM3NDY0LAorMzc0NzQsIDM3NDg2LCAzNzQ5NiwgMzc1MDcsIDM3NTE3LCAzNzUyNywgMzc1NDAsIDM3NTUxLCAzNzU2MSwgMzc1NzEsIDM3NTgxLCAzNzU5MSwgMzc2MDEsIDM3NjEyLCAzNzYyNCwgMzc2MzQsCiszNzY0NSwgMzc2NTYsIDM3NjY2LCAzNzY3NiwgMzc2ODYsIDM3NzAwLCAzNzcxMiwgMzc3MjIsIDM3NzMyLCAzNzc0MiwgMzc3NTQsIDM3NzY4LCAzNzc3OCwgMzc3OTAsIDM3ODAwLCAzNzgxMiwKKzM3ODI1LCAzNzgzNSwgMzc4NDYsIDM3ODU3LCAzNzg3OSwgMzc4ODksIDM3OTAxLCAzNzkxMSwgMzc5MjEsIDM3OTMxLCAzNzk0MSwgMzc5NTEsIDM3OTYyLCAzNzk3MywgMzc5ODMsIDM3OTk0LAorMzgwMDUsIDM4MDE1LCAzODI2MywgMzgyNzQsIDM4Mjg0LCAzODI5NCwgMzgzMDQsIDM4MzE1LCAzODMyNiwgMzgzMzksIDM4MzQ5LCAzODM2MCwgMzgzNzAsIDM4NDI4LCAzODQzOCwgMzg0NDksCiszODQ1OSwgMzg0NzUsIDM4NDg2LCAzODQ5NywgMzg1MDgsIDM4NTE4LCAzODUyOSwgMzg1MzksIDM4NTQ5LCAzODU1OSwgMzg1NjksIDM4NTc5LCAzODU5MiwgMzg2MDIsIDM4NjEzLCAzODYyMywKKzM4NjMzLCAzODY0NiwgMzg2NTYsIDM4NjY2LCAzODY3OCwgMzg2ODksIDM4NzA0LCAzODcxNywgMzg3MjgsIDM4NzM4LCAzODc0OCwgMzg3NTgsIDM4NzY5LCAzODc3OSwgMzg3ODksIDM4Nzk5LAorMzg4MDksIDM4ODE5LCAzODgyOSwgMzg4NDAsIDM4ODUxLCAzODg2MSwgMzg4NzEsIDM4ODgxLCAzODg5MywgMzg5MDMsIDM4OTEzLCAzODkyNCwgMzg5MzQsIDM4OTQ0LCAzODk1NSwgMzg5NjUsCiszODk4MCwgMzg5OTAsIDM5MDAwLCAzOTAxMCwgMzkwMjAsIDM5MDgwLCAzOTA5MiwgMzkxMDMsIDM5MTE2LCAzOTEzMSwgMzkxNDEsIDM5MTUxLCAzOTE2NCwgMzkxNzUsIDM5MTg1LCAzOTE5NSwKKzM5MjA2LCAzOTIxNywgMzkyMjcsIDM5MjM3LCAzOTI0OCwgMzkyNTksIDM5MzE4LCAzOTMzMywgMzkzNDQsIDM5MzU0LCAzOTM2NCwgMzkzNzYsIDM5Mzg2LCAzOTM5OSwgMzk0MDksIDM5NDE5LAorMzk0MjksIDM5NDM5LCAzOTQ0OSwgMzk0NTksIDM5NDY5LCAzOTQ3OSwgMzk0ODksIDM5NDk5LCAzOTUwOSwgMzk1MTksIDM5NTI5LCAzOTU5MiwgMzk2MDIsIDM5NjEyLCAzOTYyMiwgMzk2MzIsCiszOTY0MywgMzk2NTMsIDM5NjYzLCAzOTY3MywgMzk2ODMsIDM5NjkzLCAzOTcwNCwgMzk3MTQsIDM5NzI1LCAzOTczNSwgMzk3NDUsIDM5NzU1LCAzOTc2NSwgMzk3NzcsIDM5Nzg3LCAzOTc5NywKKzM5ODA3LCAzOTgxNywgMzk4MjcsIDM5ODM3LCAzOTg0NywgMzk4NTcsIDM5ODY3LCAzOTg3OCwgMzk4ODgsIDM5ODk5LCAzOTkwOSwgMzk5MTksIDM5OTI5LCAzOTk0MCwgMzk5NTEsIDM5OTYxLAorMzk5NzEsIDM5OTgxLCAzOTk5MSwgNDAwMDEsIDQwMDE0LCA0MDAyNCwgNDAwMzUsIDQwMDQ2LCA0MDA1NiwgNDAxNjUsIDQwMTc2LCA0MDE5NCwgNDAyMDYsIDQwMjE2LCA0MDIyNywgNDAyMzksCis0MDI1MCwgNDAyNjAsIDQwMjcyLCA0MDI4NCwgNDAyOTcsIDQwMzEwLCA0MDMyMywgNDAzMzMsIDQwMzQzLCA0MDM1MywgNDAzNjMsIDQwMzczLCA0MDM4MywgNDAzOTMsIDQwNDAzLCA0MDQxNCwKKzQwNDI1LCA0MDQzNSwgNDA0NDUsIDQwNDU1LCA0MDQ2NSwgNDA0NzUsIDQwNTY1LCA0MDU3NSwgNDA1ODcsIDQwNTk3LCA0MDYwNywgNDA2MTcsIDQwNjI3LCA0MDYzOCwgNDA2NDgsIDQwNjU4LAorNDA2NjgsIDQwNjc5LCA0MDY4OSwgNDA2OTksIDQwNzExLCA0MDcyMSwgNDA3MzEsIDQwNzQyLCA0MDc1MywgNDA3NjMsIDQwNzczLCA0MDc4MywgNDA3OTQsIDQwODA2LCA0MDgxNiwgNDA4MjYsCis0MDg0NSwgNDA4NTUsIDQwODY1LCA2NTI4MSwgNjUyOTEsIDY1MzAxLCA2NTMxMSwgNjUzMjEsIDY1MzMxLCA2NTM0MSwgNjUzNTEsIDY1MzYxLCA2NTM3MSwgNjUzODEsIDY1MzkxLCA2NTQwMSwKKzY1NDExLCA2NTQyMSwgNjU0MzEsIDY1NTA3CisgICAgICAgICAgICB9KTsKKworICAgICAgICB0ZXN0Qnl0ZXMgPSB0aGVzZUJ5dGVzKG5ldyBpbnRbXXsKKzAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKzMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCis2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKzgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisxNDMsIDE2MiwgMTk0LCAxNDIsIDIyNCwgMTQyLCAyMjUsIDE0MywgMTYyLCAyNDAsIDE0MywgMTYyLCAxOTUsIDE2MSwgMjQ4LCAxNjEsCisxNzUsIDE0MywgMTYyLCAyMzcsIDE0MywgMTYyLCAyMzYsIDE0MiwgMjI2LCAxNDMsIDE2MiwgMjM4LCAxNDMsIDE2MiwgMTgwLCAxNjEsCisyMzUsIDE2MSwgMjIyLCAxNjEsIDE3MywgMTYyLCAyNDksIDE0MywgMTYyLCAxNzcsIDE0MywgMTYyLCAyMzUsIDE0MywgMTYyLCAxOTYsCisxNDMsIDE3MCwgMTYyLCAxNDMsIDE3MCwgMTYxLCAxNDMsIDE3MCwgMTY0LCAxNDMsIDE3MCwgMTcwLCAxNDMsIDE3MCwgMTYzLCAxNDMsCisxNzAsIDE2OSwgMTQzLCAxNjksIDE2MSwgMTQzLCAxNzAsIDE3NCwgMTQzLCAxNzAsIDE3OCwgMTQzLCAxNzAsIDE3NywgMTQzLCAxNzAsCisxODAsIDE0MywgMTcwLCAxNzksIDE0MywgMTcwLCAxOTIsIDE0MywgMTcwLCAxOTEsIDE0MywgMTcwLCAxOTQsIDE0MywgMTcwLCAxOTMsCisxNDMsIDE3MCwgMjA4LCAxNDMsIDE3MCwgMjEwLCAxNDMsIDE3MCwgMjA5LCAxNDMsIDE3MCwgMjEyLCAxNDMsIDE3MCwgMjE2LCAxNDMsCisxNzAsIDIxMSwgMTYxLCAyMjMsIDE0MywgMTY5LCAxNzIsIDE0MywgMTcwLCAyMjcsIDE0MywgMTcwLCAyMjYsIDE0MywgMTcwLCAyMjksCisxNDMsIDE3MCwgMjI4LCAxNDMsIDE3MCwgMjQyLCAxNDMsIDE2OSwgMTc2LCAxNDMsIDE2OSwgMjA2LCAxNDMsIDE3MSwgMTYyLCAxNDMsCisxNzEsIDE2MSwgMTQzLCAxNzEsIDE2NCwgMTQzLCAxNzEsIDE3MCwgMTQzLCAxNzEsIDE2MywgMTQzLCAxNzEsIDE2OSwgMTQzLCAxNjksCisxOTMsIDE0MywgMTcxLCAxNzQsIDE0MywgMTcxLCAxNzgsIDE0MywgMTcxLCAxNzcsIDE0MywgMTcxLCAxODAsIDE0MywgMTcxLCAxNzksCisxNDMsIDE3MSwgMTkyLCAxNDMsIDE3MSwgMTkxLCAxNDMsIDE3MSwgMTk0LCAxNDMsIDE3MSwgMTkzLCAxNDMsIDE2OSwgMTk1LCAxNDMsCisxNzEsIDIwOCwgMTQzLCAxNzEsIDIxMCwgMTQzLCAxNzEsIDIwOSwgMTQzLCAxNzEsIDIxMiwgMTQzLCAxNzEsIDIxNiwgMTQzLCAxNzEsCisyMTEsIDE2MSwgMjI0LCAxNDMsIDE2OSwgMjA0LCAxNDMsIDE3MSwgMjI3LCAxNDMsIDE3MSwgMjI2LCAxNDMsIDE3MSwgMjI5LCAxNDMsCisxNzEsIDIyOCwgMTQzLCAxNzEsIDI0MiwgMTQzLCAxNjksIDIwOCwgMTQzLCAxNzEsIDI0MywgMTQzLCAxNzAsIDE2NywgMTQzLCAxNzAsCisxNzUsIDE0MywgMTcwLCAxODIsIDE0MywgMTcwLCAxODksIDE0MywgMTcwLCAxOTcsIDE0MywgMTcwLCAyMDAsIDE0MywgMTcxLCAyMDMsCisxNDMsIDE3MSwgMjA2LCAxNDMsIDE2OSwgMTczLCAxNDMsIDE3MCwgMjIxLCAxNDMsIDE2OSwgMTc1LCAxNDMsIDE3MCwgMjMyLCAxNDMsCisxNzEsIDI0NSwgMTQzLCAxNzAsIDE2NiwgMTQzLCAxNzAsIDIzNywgMTQzLCAxNzEsIDE4NSwgMTQzLCAxNjIsIDE3NiwgMTQzLCAxNjIsCisxNzUsIDE0MywgMTYyLCAxODQsIDE0MywgMTY2LCAyMzMsIDE2NiwgMTY4LCAxNjYsIDE3OCwgMTQzLCAxNjYsIDI0MiwgMTY2LCAxOTksCisxNjYsIDIwOSwgMTQzLCAxNjYsIDI1MCwgMTY3LCAxNjcsIDE0MywgMTY3LCAyMDMsIDE2NywgMTY2LCAxNjcsIDE3NywgMTY3LCAxODcsCisxNjcsIDIxMiwgMTY3LCAyMjMsIDE2NywgMjMzLCAxNjcsIDIxNSwgMTQzLCAxNjcsIDI1MSwgMTYxLCAxOTAsIDE2MSwgMjAwLCAxNjEsCisxOTYsIDE2MiwgMjQzLCAxNjIsIDE2OCwgMTYxLCAyMzgsIDE0MywgMTYyLCAyNDEsIDE0MywgMTYyLCAyMzksIDE2MiwgMTcxLCAxNjIsCisyMDUsIDE2MiwgMjA3LCAxNjIsIDE4NywgMTYyLCAyMjksIDE2MiwgMjAyLCAxNjEsIDIzMiwgMTYyLCAyMjYsIDE2MSwgMjI2LCAxNjIsCisyMjcsIDE2MiwgMTkwLCAxNjIsIDIyMSwgMTYyLCAyMjIsIDE2OCwgMTYxLCAxNjgsIDE2MywgMTY4LCAxNzcsIDE2OCwgMTc4LCAxNjgsCisxODQsIDE2OCwgMTgxLCAxNjgsIDE4MiwgMTYyLCAxNjMsIDE2MiwgMTY1LCAxNjIsIDE2NywgMTYyLCAxNjEsIDE2MiwgMjU0LCAxNjEsCisyNTAsIDE2MSwgMjM0LCAxNjIsIDI0NiwgMTYxLCAxNjEsIDE2MSwgMjEyLCAxNjEsIDIwNCwgMTY0LCAxNjEsIDE2NCwgMTcxLCAxNjQsCisxODEsIDE2NCwgMTkxLCAxNjQsIDIwMSwgMTY0LCAyMTEsIDE2NCwgMjIxLCAxNjQsIDIzMSwgMTY0LCAyNDEsIDE2MSwgMTcxLCAxNjUsCisxNjUsIDE2NSwgMTc1LCAxNjUsIDE4NSwgMTY1LCAxOTUsIDE2NSwgMjA1LCAxNjUsIDIxNSwgMTY1LCAyMjUsIDE2NSwgMjM1LCAxNjUsCisyNDUsIDE3NiwgMjM2LCAxOTAsIDIyOSwgMTc5LCAyMzgsIDE5MCwgMjMxLCAxNDMsIDE3NiwgMTY5LCAxODIsIDI1MCwgMjA4LCAxNjcsCisxNDMsIDE3NiwgMTc4LCAxNDMsIDE3NiwgMTc5LCAxNDMsIDE3NiwgMTgxLCAxNDMsIDE3NiwgMTgzLCAxOTgsIDI1MywgMTgwLCAxNjUsCisyMDUsIDE4OSwgMTg0LCAyMjMsIDE3NiwgMTYxLCAyMDMsIDI0MiwgMjA4LCAxODMsIDE5MSwgMjA1LCAyMDgsIDE4OCwgMjA4LCAxODYsCisyMDEsIDIxMywgMTQzLCAxNzYsIDIwMSwgMjA4LCAxOTMsIDIwOCwgMTk1LCAxODAsIDIzNSwgMTQzLCAxNzYsIDIxNCwgMTQzLCAxNzYsCisyMTcsIDE0MywgMTc2LCAyMjEsIDE5MSwgMTczLCAxNDMsIDE3NiwgMjMxLCAxNDMsIDE3NiwgMjM1LCAxNDMsIDE3NiwgMjM4LCAxNDMsCisxNzYsIDIyMywgMTQzLCAxNzYsIDI0MiwgMjAyLCAxODcsIDE4NywgMjAwLCAxNDMsIDE3NywgMTYyLCAxNDMsIDE3NywgMTY4LCAxNzYsCisyMDUsIDIxMywgMTY1LCAxOTEsIDE3NSwgMjAyLCAyMTYsIDE0MywgMTc3LCAxODcsIDIwOCwgMjE1LCAyMDgsIDIxNiwgMTg5LCAxNjQsCisyMDIsIDI0MCwgMTQzLCAxNzcsIDIwMywgMTQzLCAxNzcsIDIwNywgMTQzLCAxNzcsIDIxMSwgMTQzLCAxNzcsIDIxNiwgMjA4LCAyMzUsCisxODIsIDIzMCwgMTQzLCAxNzcsIDIyMywgMTQzLCAxNzcsIDIyOCwgMjA4LCAyNDMsIDE0MywgMTc3LCAyMzYsIDE0MywgMTc3LCAyNDIsCisxOTQsIDE2NiwgMjA4LCAyNTAsIDE0MywgMTc3LCAyNTEsIDE0MywgMTc4LCAxNjMsIDE0MywgMTc4LCAxNjcsIDE0MywgMTc4LCAxNzIsCisyMDgsIDI1MywgMTgzLCAxODUsIDIwOSwgMTYxLCAxNDMsIDE3OCwgMTg1LCAxNDMsIDE3OCwgMTg5LCAxOTMsIDIwNiwgMTQzLCAxNzgsCisxOTcsIDIwMiwgMjAwLCAxNDMsIDE3OCwgMjAyLCAxNDMsIDE3OCwgMjEwLCAyMDksIDE3OSwgMTQzLCAxNzgsIDIxOCwgMTQzLCAxNzgsCisyMjMsIDIwOSwgMTg0LCAxODksIDE4OCwgMTQzLCAxNzgsIDIzMSwgMTk3LCAyMjIsIDE0MywgMTc4LCAyMzcsIDIwOSwgMTk0LCAxOTcsCisxODEsIDIwOSwgMTk2LCAyMDksIDE5OCwgMjA5LCAyMDQsIDE4MCwgMTY3LCAyMDksIDIwOSwgMTg2LCAyMjcsIDE0MywgMTc4LCAyNTIsCisxNDMsIDE3OSwgMTYxLCAxNDMsIDE3OSwgMTY0LCAyNDQsIDE2NSwgMTg5LCAyMzIsIDIwOSwgMjI0LCAxODksIDIwOCwgMjA5LCAyMjcsCisyMDksIDIzMCwgMTQzLCAxNzksIDE4MywgMTQzLCAxNzksIDE4NCwgMjA5LCAyMzMsIDE4MywgMjQ0LCAxOTYsIDIzMCwgMTkzLCAxNzYsCisxNDMsIDE3OSwgMTkzLCAxNDMsIDE3OSwgMTk5LCAxNDMsIDE3OSwgMjAxLCAxNDMsIDE3OSwgMjAzLCAxNDMsIDE3OSwgMjA2LCAxNDMsCisxNzksIDIwOSwgMTQzLCAxNzksIDIxMiwgMTc4LCAxOTUsIDE5NywgMjE2LCAyMDcsIDE3MSwgMTc5LCAxNzUsIDE0MywgMTc5LCAyMzIsCisyNDAsIDIxMywgMTQzLCAxNzksIDIzOSwgMjEwLCAxNzEsIDE0MywgMTc5LCAyNDYsIDE4OCwgMjE5LCAyMDIsIDI0MSwgMjEwLCAxODMsCisxODYsIDI1MiwgMjEwLCAxODYsIDE0MywgMTgwLCAxNzUsIDIxMCwgMTkwLCAxNDMsIDE4MCwgMTgyLCAxNDMsIDE4MCwgMTgzLCAxOTgsCisyMzgsIDE0MywgMTgwLCAxODcsIDE0MywgMTgwLCAxOTAsIDIxMCwgMjAzLCAyMTAsIDIwNCwgMTQzLCAxODAsIDE5OCwgMjA2LCAyMTAsCisxNDMsIDE4MCwgMjA0LCAyMTAsIDIwOSwgMTQzLCAxODAsIDIxMiwgMTg3LCAxNzgsIDE5MywgMjA4LCAxODgsIDIzMiwgMTQzLCAxODAsCisyMjQsIDE5NCwgMjU0LCAxNDMsIDE4MCwgMjI3LCAyMTAsIDIyMiwgMTc3LCAxNjUsIDE0MywgMTgwLCAyMzAsIDIwMCwgMjIxLCAxNDMsCisxODAsIDIzNiwgMjAyLCAxNzMsIDIwMiwgMjQyLCAxOTgsIDIyMSwgMTQzLCAxODAsIDI0NCwgMTg4LCAyNTQsIDIwNCwgMTYzLCAyMDQsCisxOTEsIDE0MywgMTgxLCAxNjQsIDIxMCwgMjQwLCAxNDMsIDE4MSwgMTcwLCAxNDMsIDE4MSwgMTczLCAxNDMsIDE4MSwgMTc5LCAxNDMsCisxODEsIDE4MywgMTQzLCAxODEsIDE4NSwgMjExLCAxNjYsIDIxMSwgMTc1LCAxNDMsIDE4MSwgMTkxLCAxNDMsIDE4MSwgMTkzLCAxNDMsCisxODEsIDE5NywgMTQzLCAxODEsIDIwMiwgMTc2LCAxNjIsIDE0MywgMTgxLCAyMDYsIDE0MywgMTgxLCAyMDksIDIxMSwgMTc3LCAxNDMsCisxODEsIDIxNywgMjExLCAxODMsIDE0MywgMTgxLCAyMjUsIDIxMSwgMTkzLCAxNDMsIDE4MSwgMjMyLCAxNDMsIDE4MSwgMjM2LCAxODAsCisyMzgsIDE4MywgMjQ2LCAxNDMsIDE4MSwgMjQ0LCAxNDMsIDE4MSwgMjQ1LCAxNDMsIDE4MSwgMjQ5LCAxNDMsIDE4MiwgMTYxLCAxNDMsCisxODIsIDE2NSwgMTQzLCAxODIsIDE2NywgMTQzLCAxODIsIDE2OCwgMTQzLCAxODIsIDE3MCwgMTQzLCAxODIsIDE3NSwgMTQzLCAxODIsCisxNzksIDE3OCwgMjIyLCAxNDMsIDE4MiwgMTgyLCAxNDMsIDE4MiwgMTg4LCAxNDMsIDE4MiwgMTk1LCAxNDMsIDE4MiwgMTk5LCAxNDMsCisxODIsIDIwMCwgMTgwLCAyMzksIDE0MywgMTgyLCAyMTAsIDIxMSwgMjMwLCAyMTEsIDIzMSwgMjExLCAyMzMsIDE0MywgMTgyLCAyMjEsCisxNDMsIDE4MiwgMjI1LCAxNDMsIDE4MiwgMjMxLCAxNDMsIDE4MiwgMjMzLCAyMTEsIDI0NCwgMjExLCAyNDcsIDE0MywgMTgyLCAyNDQsCisxNDMsIDE4MiwgMjUwLCAxNDMsIDE4MiwgMjUyLCAxODUsIDI0MSwgMTQzLCAxODMsIDE2NSwgMTQzLCAxODMsIDE2OCwgMTQzLCAxODMsCisxNzEsIDE0MywgMTgzLCAxNzcsIDE0MywgMTgzLCAxODIsIDIxMiwgMTczLCAxNDMsIDE4MywgMTg4LCAyMTIsIDE3NSwgMjEyLCAxNzksCisxNDMsIDE4MywgMTk3LCAxNDMsIDE4MywgMjA1LCAyMTIsIDE4MCwgMjEyLCAxODEsIDIxMiwgMTgyLCAxNDMsIDE4MywgMjIwLCAxNDMsCisxODMsIDIyNSwgMjEyLCAxODQsIDE0MywgMTgzLCAyMzAsIDE0MywgMTgzLCAyMzEsIDIxMiwgMTkxLCAxOTksIDE4NCwgMTQzLCAxODMsCisyMzksIDE0MywgMTgzLCAyNDMsIDE4MCwgMjQwLCAxNDMsIDE4MywgMjUxLCAxOTQsIDE5NiwgMTQzLCAxODQsIDE2NSwgMTgwLCAxNzQsCisxOTAsIDIzNiwgMTQzLCAxODQsIDE3MiwgMTQzLCAxODQsIDE3MywgMTk3LCAyMjcsIDE4NiwgMjAxLCAxNDMsIDE4NCwgMTgzLCAyMTIsCisxOTksIDE0MywgMTg0LCAxODUsIDE0MywgMTg0LCAxODksIDIwMiwgMjMyLCAxNDMsIDE4NCwgMTk5LCAyMDMsIDIwNywgMTQzLCAxODQsCisyMDYsIDE0MywgMTg0LCAyMDgsIDE5NSwgMTk3LCAyMTIsIDIxOSwgMjEyLCAyMjQsIDE0MywgMTg0LCAyMjEsIDE0MywgMTg0LCAyMjIsCisyMTIsIDIzMiwgMjAyLCAyMDksIDE0MywgMTg0LCAyMjgsIDE0MywgMTg0LCAyMzEsIDE5NCwgMjMxLCAxODgsIDE4NiwgMjEyLCAyNDMsCisxOTgsIDIyNCwgMTQzLCAxODQsIDI0NCwgMTQzLCAxODQsIDI0OCwgMjEyLCAyNTIsIDE0MywgMTg1LCAxNjIsIDE0MywgMTg1LCAxNjcsCisxOTksIDE2NSwgMTQzLCAxODUsIDE3MiwgMTQzLCAxODUsIDE3NCwgMTk3LCAyMDIsIDE0MywgMTg1LCAxODIsIDE0MywgMTg1LCAxODUsCisxODcsIDIwNywgMjEzLCAxNzIsIDE0MywgMTg1LCAxOTUsIDE0MywgMTg1LCAxOTgsIDE3NiwgMjQ5LCAyMTMsIDE3OCwgMTQzLCAxODUsCisyMTAsIDE0MywgMTg1LCAyMTEsIDE0MywgMTg1LCAyMTUsIDIxMywgMTgzLCAyMTMsIDE4MCwgMTQzLCAxODUsIDIyMywgMTg2LCAxNjcsCisxNDMsIDE4NSwgMjI4LCAxNDMsIDE4NSwgMjMxLCAxNDMsIDE4NSwgMjM1LCAxNDMsIDE4NSwgMjM4LCAxNDMsIDE4NSwgMjQzLCAxNDMsCisxODUsIDI0NiwgMTQzLCAxODUsIDI1MSwgMjEzLCAxOTEsIDE4MywgMjQ5LCAyMTMsIDE5NywgMTQzLCAxODYsIDE2NywgMTQzLCAxODYsCisxNjksIDE0MywgMTg2LCAxNzEsIDE0MywgMTg2LCAxNzQsIDIxMywgMjAxLCAyMTMsIDIwMiwgMTQzLCAxODYsIDE4MiwgMTk2LCAyMjAsCisyMTMsIDIwNiwgMjEzLCAyMTAsIDE0MywgMTg2LCAxODcsIDIxMywgMjEyLCAyMDQsIDIxMCwgMjEzLCAyMTYsIDIxMywgMjE4LCAxNDMsCisxODYsIDE5NiwgMTc3LCAxNjcsIDE0MywgMTg2LCAyMDUsIDE3NiwgMTg0LCAyMDUsIDE2OCwgMTQzLCAxODYsIDIxMywgMjA1LCAxOTgsCisyMTMsIDIyNywgMTQzLCAxODYsIDIyMSwgMTQzLCAxODYsIDIyNCwgMTc4LCAyMDEsIDIxMywgMjM3LCAxOTUsIDI1NCwgMTg4LCAyNDcsCisxNzYsIDIxMSwgMjEzLCAyNDUsIDE0MywgMTg2LCAyMzUsIDIxMywgMjQ4LCAxNDMsIDE4NiwgMjQ0LCAxOTgsIDI0NCwgMjEzLCAyNTIsCisyMTQsIDE2MSwgMTQzLCAxODYsIDI0OCwgMTkzLCAyMTYsIDIxNCwgMTY1LCAyMTQsIDE2OCwgMTQzLCAxODcsIDE2OSwgMjE0LCAxNzAsCisxNDMsIDE4NywgMTc0LCAxOTMsIDE4NywgMTQzLCAxODcsIDE4MSwgMjE0LCAxNzYsIDIxNCwgMTgwLCAxNDMsIDE4NywgMTg3LCAxNDMsCisxODcsIDE4OCwgMTc4LCAyMjksIDE0MywgMTg3LCAxOTIsIDIxNCwgMTgzLCAxOTEsIDI0MiwgMjE0LCAxOTQsIDIxNCwgMTkzLCAxNDMsCisxODcsIDIwMSwgMTQzLCAxODcsIDIwMywgMTQzLCAxODcsIDIwNiwgMTQzLCAxODcsIDIxMSwgMjE0LCAyMDEsIDIxNCwgMTkxLCAxOTEsCisyNDMsIDIxNCwgMjA1LCAxNDMsIDE4NywgMjI2LCAxNDMsIDE4NywgMjMwLCAxNDMsIDE4NywgMjMyLCAyMTQsIDIxMSwgMTQzLCAxODcsCisyNDAsIDE0MywgMjMwLCAyNDQsIDIxNCwgMjE3LCAxNDMsIDE4NywgMjQ3LCAyMTQsIDIyMSwgMTkyLCAyMzgsIDE4NSwgMTcwLCAxODQsCisyMDIsIDE4MCwgMTcyLCAyMDAsIDE5MywgMjE0LCAyMzAsIDIxNCwgMjMxLCAxOTEsIDIyNywgMTk0LCAyMTEsIDIwMywgMTg1LCAyMTQsCisyNDMsIDE0MywgMTg4LCAxODEsIDE0MywgMTg4LCAxODQsIDE0MywgMTg4LCAxODcsIDE4MCwgMTc5LCAyMDUsIDE5NiwgMjAwLCAyMjMsCisxOTYsIDIzNiwgMjE0LCAyNDksIDE0MywgMTg4LCAyMDEsIDE3NiwgMTk1LCAxNDMsIDE4OCwgMjA3LCAyMDYsIDI0NywgMTc5LCAxOTksCisyMTUsIDE2MywgMjE1LCAxNjgsIDIxNSwgMTcyLCAyMTUsIDE3NiwgMTQzLCAxODgsIDIyMywgMTgxLCAyMjEsIDE0MywgMTg4LCAyMjcsCisxODQsIDIwNCwgMTg4LCAyMjksIDE0MywgMTg4LCAyMzksIDE0MywgMTg4LCAyNDQsIDE0MywgMTg4LCAyNDcsIDE0MywgMTg4LCAyNTAsCisyMDEsIDE2NywgMTkwLCAxODAsIDE0MywgMTg5LCAxNjYsIDE4MywgMTk0LCAxNDMsIDE4OSwgMTcxLCAyMTUsIDIwOCwgMTQzLCAxODksCisxNzgsIDIwMCwgMjQ5LCAxNDMsIDE4OSwgMTgzLCAxOTEsIDE4MCwgMTk5LCAxNjYsIDE4NywgMjE0LCAxNDMsIDE4OSwgMTk1LCAxNzgsCisyNDcsIDE5OSwgMTc2LCAyMTUsIDIyMSwgMTQzLCAxODksIDIxMCwgMTQzLCAxODksIDIxMywgMTQzLCAxODksIDIxNywgMjE1LCAyMjYsCisxNDMsIDE4OSwgMjIwLCAxNDMsIDE4OSwgMjIyLCAyMTUsIDI0MCwgMTQzLCAxODksIDIyOCwgMjE1LCAyMzksIDE3OCwgMTg0LCAxODMsCisxOTUsIDE0MywgMTg5LCAyMzYsIDE4OCwgMTg5LCAxNDMsIDE4OSwgMjQzLCAxNDMsIDE4OSwgMjQ2LCAyMTYsIDE2NiwgMTQzLCAxODksCisyNTMsIDE0MywgMTkwLCAxNjEsIDE5MCwgMjQwLCAxNDMsIDE5MCwgMTcwLCAxNDMsIDE5MCwgMTczLCAxOTMsIDIxOCwgMTk0LCAxOTgsCisyMTYsIDE4NSwgMjE2LCAxODAsIDE0MywgMTkwLCAxODgsIDE4MiwgMjQyLCAyMTYsIDE5NSwgMTQzLCAxOTAsIDIwMiwgMjE2LCAxOTgsCisxNDMsIDE5MCwgMjA5LCAyMTYsIDIxNiwgMjE2LCAyMTUsIDE4MywgMTk3LCAyMTYsIDIxMywgMTQzLCAxOTAsIDIxNiwgMjE2LCAyMjAsCisyMTYsIDIyNSwgMTQzLCAxOTAsIDIyOSwgMTk4LCAxODAsIDE4MywgMjUxLCAxNDMsIDE5MCwgMjM5LCAyMTYsIDIzNCwgMTc4LCAyNTEsCisxNDMsIDE5MCwgMjQ2LCAyMTYsIDIzOSwgMTk2LCAxNjgsIDIxNiwgMjQ2LCAxNDMsIDE5MSwgMTY3LCAxNzgsIDIzMCwgMjE2LCAyNTQsCisxOTIsIDIzOSwgMjE3LCAxNjUsIDIwNCwgMjI1LCAxNDMsIDE5MSwgMTgyLCAxNDMsIDE5MSwgMTg0LCAxNDMsIDE5MSwgMTg5LCAxNDMsCisxOTEsIDE5MSwgMjAyLCAxNzcsIDIwMCwgMjI3LCAyMTcsIDE4MywgMTQzLCAxOTEsIDE5NywgMTg1LCAxNzksIDE0MywgMTkxLCAyMDEsCisyMDIsIDI1MCwgMjE3LCAxODcsIDE5NSwgMTgwLCAyMTcsIDE4OCwgMTkyLCAyMTksIDE0MywgMTkxLCAyMTQsIDE0MywgMTkxLCAyMTYsCisxODksIDE2NiwgMjE3LCAyMDUsIDE0MywgMTkxLCAyMjUsIDE4MiwgMTgwLCAxNDMsIDE5MSwgMjI4LCAxNDMsIDE5MSwgMjMxLCAxOTMsCisyMjIsIDE5NCwgMTcwLCAxNDMsIDE5MSwgMjQ0LCAxNDMsIDE5MSwgMjQ4LCAxNDMsIDE5MSwgMjUyLCAxOTksIDE3NywgMTQzLCAxOTIsCisxNjcsIDE5OSwgMjExLCAxNDMsIDE5MiwgMTc0LCAxOTEsIDIyOCwgMTgzLCAxOTksIDE0MywgMTkyLCAxODAsIDE0MywgMTkyLCAxODMsCisyMTcsIDIzMSwgMTQzLCAxOTIsIDE4OSwgMjE3LCAyMjYsIDE0MywgMTkyLCAxOTUsIDIxNywgMjM2LCAxNDMsIDE5MiwgMjAxLCAyMTcsCisyMTEsIDIxNywgMjM4LCAxNDMsIDE5MiwgMjEzLCAxODMsIDIwMCwgMTQzLCAxOTIsIDIxNywgMTk3LCAxNjYsIDE0MywgMTkyLCAyMzAsCisxNDMsIDE5MiwgMjMxLCAyMDQsIDIwNiwgMTgzLCAyMjYsIDE0MywgMTkyLCAyMzgsIDE0MywgMTkyLCAyNDIsIDE0MywgMTkyLCAyNDcsCisxOTksIDE5NywgMTc5LCAyMDEsIDE0MywgMTkzLCAxNjEsIDE0MywgMTkzLCAxNjYsIDIxOCwgMTY2LCAxOTcsIDE2NywgMTgxLCAxODgsCisyMTgsIDE3NywgMjE4LCAxODEsIDE0MywgMTkzLCAxODUsIDE0MywgMTkzLCAxODgsIDE0MywgMTkzLCAxOTIsIDE0MywgMTkzLCAxOTYsCisyMTgsIDE4OSwgMjAyLCAyNTIsIDIxOCwgMTk1LCAxNDMsIDE5MywgMjA2LCAyMTgsIDIwMSwgMTQzLCAxOTMsIDIxMCwgMjE4LCAyMDIsCisxNDMsIDE5MywgMjEzLCAyMDIsIDE4NCwgMjAwLCAxOTUsIDIxOCwgMjA3LCAxOTIsIDIwNSwgMTg3LCAyMTksIDIwMiwgMjUzLCAyMTgsCisyMTEsIDE0MywgMTkzLCAyMzIsIDE0MywgMTkzLCAyMzYsIDE4MCwgMjUxLCAxODksIDIyMCwgMTQzLCAxOTMsIDI0MiwgMjE4LCAyMjQsCisxNDMsIDE5MywgMjQ5LCAyMTgsIDIzMCwgMTQzLCAxOTQsIDE2NiwgMTQzLCAxOTQsIDE3MiwgMTk1LCAyMzUsIDE0MywgMTk0LCAxNzksCisxNDMsIDE5NCwgMTgyLCAxNDMsIDE5NCwgMTg3LCAxNzksIDE2MiwgMjE4LCAyNDIsIDE5NSwgMjEwLCAyMTgsIDI0NywgMjE4LCAyNDUsCisyMTgsIDI0OCwgMTk2LCAxNzAsIDE0MywgMTk0LCAyMTcsIDIxOSwgMTYyLCAxNDMsIDE5NCwgMjI0LCAxNDMsIDE5NCwgMjI3LCAyMTksCisxNjMsIDIxOSwgMTY1LCAxNDMsIDE5NCwgMjM0LCAyMTksIDE3MCwgMTk0LCAyMTYsIDIwNSwgMTczLCAxNDMsIDE5NCwgMjQxLCAxOTYsCisxNzEsIDIxOSwgMTc2LCAxODgsIDIzNSwgMTgxLCAyMjQsIDE0MywgMTk0LCAyNDksIDE5NCwgMTg4LCAxOTcsIDIwNiwgMTQzLCAxOTUsCisxNjEsIDIxOSwgMTkxLCAxNDMsIDE5NSwgMTY2LCAyMTksIDE5OSwgMTQzLCAxOTUsIDE3MCwgMTQzLCAxOTUsIDE3NSwgMjE5LCAxOTcsCisxNDMsIDE5NSwgMTc3LCAxNDMsIDE5NSwgMTgxLCAxNDMsIDE5NSwgMTg4LCAxOTksIDI0MCwgMTQzLCAxOTUsIDE5MywgMjE5LCAyMDcsCisyMTksIDIxMSwgMTQzLCAxOTUsIDE4NCwgMTk4LCAyMDIsIDE5MiwgMjQyLCAxNDMsIDE5NSwgMjA0LCAxNDMsIDE5NSwgMjA3LCAxNDMsCisxOTUsIDIxMiwgMTQzLCAxOTUsIDIxNCwgMTQzLCAxOTUsIDIxNywgMTgyLCAyMDUsIDE0MywgMTk1LCAyMjMsIDIwMSwgMTc2LCAxNDMsCisxOTUsIDIyOCwgMTQzLCAxOTUsIDIzMywgMTk5LCAyMjMsIDIxOSwgMjMxLCAxNDMsIDE5NSwgMjQxLCAxNDMsIDE5NSwgMjQ1LCAxOTYsCisyNDQsIDIxOSwgMjM4LCAxODAsIDI1NCwgMTQzLCAxOTUsIDI1NCwgMTQzLCAxOTYsIDE2NSwgMjIwLCAxNjgsIDE0MywgMTk2LCAxNzMsCisyMjAsIDE3MCwgMjIwLCAxNjYsIDE5NiwgMTk5LCAxOTEsIDI1MCwgMjIwLCAxNzYsIDIyMCwgMTkxLCAxNDMsIDE5NiwgMTkzLCAxNDMsCisxOTYsIDE5NSwgMjAxLCAyNDYsIDIyMCwgMTk0LCAxNDMsIDE5NiwgMjA0LCAxNDMsIDE5NiwgMjA5LCAyMDcsIDE3NiwgMTg2LCAyMzEsCisyMDcsIDE3NywgMjIwLCAyMTMsIDE0MywgMTk2LCAyMjIsIDE0MywgMTk2LCAyMjUsIDIyMCwgMjAxLCAxODUsIDE4OSwgMTQzLCAxOTYsCisyMzIsIDE0MywgMTk2LCAyMzQsIDIyMCwgMjI5LCAyMjAsIDIyMywgMTQzLCAxOTYsIDI0NCwgMTQzLCAxOTYsIDI0NSwgMjAxLCAxODQsCisyMjAsIDIzNSwgMjIwLCAyMTEsIDIyMCwgMjQ3LCAyMjAsIDIzNywgMTQzLCAxOTcsIDE3MCwgMTgxLCAyMDQsIDIyMCwgMjQzLCAxNDMsCisxOTcsIDE4MCwgMTQzLCAxOTcsIDE4MiwgMTQzLCAxOTcsIDE4NywgMjIxLCAxNjEsIDIyMCwgMjUzLCAyMjEsIDE2OCwgMjIxLCAxNjYsCisyMjEsIDE2NSwgMTQzLCAxOTcsIDIwNiwgMTQzLCAxOTcsIDIxMCwgMTQzLCAxOTcsIDIxMywgMTQzLCAxOTcsIDIxNiwgMjIxLCAxNzgsCisyMDUsIDI0MywgMTQzLCAxOTcsIDIyNiwgMTQzLCAxOTcsIDIzMCwgMTc4LCAxNjQsIDIwNSwgMjIzLCAxODIsIDIxNCwgMjIxLCAxODgsCisxNDMsIDE5NywgMjQ0LCAxNDMsIDE5NywgMjQ3LCAxNDMsIDE5NywgMjQ5LCAxODYsIDIwOCwgMTQzLCAxOTcsIDI1NCwgMTg5LCAyMjIsCisyMjEsIDIwNSwgMTQzLCAxOTgsIDE2NiwgMTQzLCAxOTgsIDE3MSwgMjIxLCAyMTMsIDE0MywgMTk4LCAxNzgsIDE0MywgMTk4LCAxODIsCisyMjEsIDIxOCwgMjIxLCAyMTksIDIyMSwgMjIxLCAxNDMsIDE5OCwgMTkyLCAxNDMsIDE5OCwgMTk1LCAxNDMsIDE5OCwgMTk5LCAxODEsCisxNjQsIDIyMSwgMjMwLCAxNDMsIDE5OCwgMjA5LCAxNzcsIDIwMiwgMTgxLCAyMjUsIDE0MywgMTk4LCAyMTgsIDE4MCwgMTkyLCAyMjEsCisyMzMsIDE0MywgMTk4LCAyMjYsIDE0MywgMTk4LCAyMzAsIDIyMSwgMjM1LCAxOTgsIDIxNywgMTc4LCAxNzMsIDIwMywgMjE1LCAyMDMsCisyNDcsIDIwMiwgMTY4LCAxNDMsIDE5OCwgMjQ2LCAyMDAsIDIzMSwgMTQzLCAxOTgsIDI1NCwgMTQzLCAxOTksIDE2MywgMjIyLCAxNjUsCisxNDMsIDE5OSwgMTcwLCAxNDMsIDE5OSwgMTcxLCAxNDMsIDE5OSwgMTc0LCAyMjIsIDE3MiwgMTk2LCAxOTcsIDE0MywgMTk5LCAxODQsCisxNDMsIDE5OSwgMTg2LCAxOTAsIDI0NCwgMTQzLCAxOTksIDE4OSwgMTQzLCAxOTksIDE5MiwgMTc5LCAxODksIDE3OSwgMTY0LCAxNDMsCisxOTksIDE5OCwgMjA1LCAxNzYsIDE0MywgMTk5LCAyMDMsIDE0MywgMTk5LCAyMDYsIDE0MywgMTk5LCAyMDgsIDE0MywgMTk5LCAyMTIsCisxNDMsIDE5OSwgMjE1LCAyMjIsIDIwNCwgMTQzLCAxOTksIDIyMSwgMTQzLCAxOTksIDIyNSwgMTg5LCAyMjMsIDE0MywgMTk5LCAyMzEsCisyMjIsIDE4OSwgMjIyLCAxODgsIDIyMiwgMjE5LCAxNzgsIDE4NSwgMTQzLCAxOTksIDIzNywgMjIyLCAyMjAsIDIyMiwgMjE4LCAxNDMsCisxOTksIDI1MSwgMTQzLCAyMDAsIDE2MSwgMjIyLCAyMDgsIDE0MywgMjAwLCAxNjUsIDIwMCwgMTc0LCAxODksIDIyNCwgMTQzLCAyMDAsCisxNzAsIDIyMiwgMjI4LCAyMDUsIDIwNywgMTQzLCAyMDAsIDE3OCwgMTQzLCAyMDAsIDE4MywgMjIyLCAyMzcsIDE5NCwgMjE4LCAxNDMsCisyMDAsIDE4NywgMjIzLCAxNjMsIDE4MSwgMjQ5LCAxNDMsIDIwMCwgMTk2LCAxNDMsIDIwMCwgMTk4LCAxOTksIDI0OSwgMTQzLCAyMDAsCisyMDQsIDE0MywgMjAwLCAyMDgsIDIyMiwgMjQzLCAxNDMsIDIwMCwgMjEyLCAxNDMsIDIwMCwgMjE3LCAxODksIDIyNSwgMTk2LCAxNzIsCisyMjMsIDE2NiwgMjIzLCAxNzMsIDE0MywgMjAwLCAyMzEsIDE0MywgMjAwLCAyMzcsIDE0MywgMjAwLCAyNDAsIDIyMywgMTg2LCAxNDMsCisyMDAsIDI0OCwgMTgzLCAyMjcsIDE0MywgMjAwLCAyNTQsIDIyMywgMTkwLCAxNDMsIDIwMSwgMTYyLCAxNDMsIDIwMSwgMTYzLCAyMjMsCisxNzEsIDE0MywgMjAxLCAxNjksIDE0MywgMjAxLCAxNzMsIDIyMywgMTk4LCAyMjMsIDIwMiwgMTk1LCAyNDUsIDIyMywgMjA4LCAxNDMsCisyMDEsIDE4MiwgMTQzLCAyMDEsIDE4NSwgMTQzLCAyMDEsIDE4OSwgMTQzLCAyMDEsIDE5MiwgMTc4LCAyMDgsIDE0MywgMjAxLCAxOTgsCisxNDMsIDIwMSwgMjAxLCAxNzcsIDIzNCwgMTQzLCAyMDEsIDIwOCwgMTQzLCAyMDEsIDIxMCwgMjIzLCAyMjAsIDIyMywgMjE4LCAyMDYsCisyNDUsIDE0MywgMjAxLCAyMTgsIDIyMywgMjIzLCAyMjMsIDIxNiwgMjIzLCAyMjYsIDE0MywgMjAxLCAyMzAsIDE3NywgMjM1LCAxNDMsCisyMDEsIDIzNCwgMTQzLCAyMDEsIDIzNiwgMTkzLCAxNzksIDE0MywgMjAxLCAyNDIsIDE0MywgMjAxLCAyNDcsIDIyMywgMjMwLCAxNDMsCisyMDEsIDI1NCwgMjIzLCAyMzYsIDE0MywgMjAyLCAxNjIsIDIyMywgMjM5LCAyMjMsIDIzNywgMjQ0LCAxNjYsIDIyMywgMjQxLCAxNDMsCisyMDIsIDE3NCwgMjIzLCAyNDUsIDE5NywgMjQ1LCAyMjMsIDI0NiwgMTQzLCAyMDIsIDE4NywgMTg3LCAxODQsIDIyMywgMjUzLCAyMjQsCisxNjIsIDE0MywgMjAyLCAxOTMsIDE0MywgMjAyLCAxOTQsIDE0MywgMjAyLCAxOTcsIDIyNCwgMTY2LCAyMjQsIDE3MCwgMjI0LCAxNzIsCisyMjQsIDE3NSwgMTQzLCAyMDIsIDIxMSwgMTQzLCAyMDIsIDIxNSwgMjAzLCAyMTAsIDE0MywgMjAyLCAyMjQsIDE0MywgMjAyLCAyMjcsCisyMjQsIDE4MiwgMjI0LCAxODMsIDE4MSwgMTkwLCAxODQsIDE2NCwgMTkwLCAyNDUsIDE0MywgMjAyLCAyNDIsIDE0MywgMjAyLCAyNDUsCisxNDMsIDIwMiwgMjQ3LCAyMjQsIDE5NSwgMTk4LCAyMDAsIDIyNCwgMTk4LCAxNDMsIDIwMywgMTYyLCAxNDMsIDIwMywgMTY3LCAyMjQsCisyMDAsIDE0MywgMjAzLCAxNzMsIDE0MywgMjAzLCAxNzcsIDIwNSwgMTc3LCAxNDMsIDIwMywgMTg0LCAxNDMsIDIwMywgMTg1LCAyMjQsCisyMTMsIDE4OSwgMTk1LCAxNDMsIDIwMywgMTk5LCAyMjQsIDIxNywgMTQzLCAyMDMsIDIwNywgMTQzLCAyMDMsIDIxMCwgMTQzLCAyMDMsCisyMTUsIDE0MywgMjAzLCAyMjAsIDE0MywgMjAzLCAyMjUsIDE0MywgMjAzLCAyMjcsIDE3OCwgMjA5LCAxNDMsIDIwMywgMjM2LCAxNDMsCisyMDMsIDI0MCwgMTg4LCAyMzgsIDE4MywgMTkwLCAxNDMsIDIwMywgMjQ4LCAxODQsIDE4OSwgMjA2LCAxNzYsIDE0MywgMjA0LCAxNjgsCisxNDMsIDIwNCwgMTcwLCAxNDMsIDIwNCwgMTc4LCAxNDMsIDIwNCwgMTgyLCAxNDMsIDIwNCwgMTg0LCAxNDMsIDIwNCwgMTg5LCAxNDMsCisyMDQsIDE5MiwgMTQzLCAyMDQsIDE5NCwgMTQzLCAyMDQsIDE5OSwgMjI0LCAyNDcsIDE0MywgMjA0LCAyMDgsIDE0MywgMjA0LCAyMTMsCisyMjQsIDIyOSwgMTQzLCAyMDQsIDIyNiwgMTQzLCAyMDQsIDIzMSwgMTQzLCAyMDQsIDIzNCwgMTQzLCAyMDQsIDIzOCwgMTQzLCAyMDQsCisyNDIsIDE0MywgMjA0LCAyNDUsIDIyNSwgMTY2LCAxNDMsIDIwNCwgMjUyLCAxNDMsIDIwNCwgMjU0LCAxODUsIDI0OSwgMTk3LCAxODgsCisyMjUsIDE4MCwgMTk3LCAxOTYsIDE5NiwgMTc0LCAyMjUsIDE4MywgMTQzLCAyMDUsIDE4MCwgMjA2LCAxNzcsIDIyNSwgMTkxLCAxNDMsCisyMDUsIDE4NywgMTQzLCAyMDUsIDE4OSwgMTQzLCAyMDUsIDE5NiwgMTkzLCAxOTMsIDE0MywgMjA1LCAyMDEsIDIyNSwgMjA3LCAyMjUsCisyMTUsIDIyNSwgMjE0LCAxNDMsIDIwNSwgMjExLCAyMjUsIDIxOCwgMTQzLCAyMDUsIDIxNiwgMTQzLCAyMDUsIDIyMSwgMTQzLCAyMDUsCisyMjUsIDIyNSwgMjI0LCAxNDMsIDIwNSwgMjMxLCAxNDMsIDIwNSwgMjM2LCAxNDMsIDIwNSwgMjQyLCAxNDMsIDIwNSwgMjQ3LCAyMjUsCisyNDAsIDE0MywgMjA2LCAxNjEsIDE0MywgMjA2LCAxNjcsIDIwNCwgMjU0LCAyMjUsIDI0NSwgMjI1LCAyNTIsIDE0MywgMjA2LCAxNzksCisxOTcsIDIwOCwgMTQzLCAyMDYsIDE4MiwgMTg3LCAxNjksIDIyNiwgMTczLCAxNDMsIDIwNiwgMTkzLCAyMDAsIDIzMywgMjI2LCAxNzYsCisyMjYsIDE3OSwgMTQzLCAyMDYsIDIwNSwgMjI2LCAxODEsIDE0MywgMjA2LCAyMDksIDIyNiwgMTg3LCAxOTYsIDE5MCwgMTg5LCAyMjYsCisyMjYsIDE5MCwgMTQzLCAyMDYsIDIyMiwgMTQzLCAyMDYsIDIyOCwgMjI2LCAxOTcsIDE0MywgMjA2LCAyMzQsIDE0MywgMjA2LCAyMzksCisxNDMsIDIwNiwgMjQzLCAxNDMsIDIwNiwgMjQ4LCAxNDMsIDIwNiwgMjUzLCAxNDMsIDIwNywgMTYzLCAxNDMsIDIwNywgMTY4LCAyMjYsCisyMDgsIDIyNiwgMjExLCAxNDMsIDIwNywgMTc2LCAxNDMsIDIwNywgMTc5LCAxNDMsIDIwNywgMTgyLCAxNDMsIDIwNywgMTg2LCAyMjYsCisyMTgsIDE0MywgMjA3LCAxODksIDE0MywgMjA3LCAxOTIsIDE0MywgMjA3LCAxOTUsIDE4MiwgMjM1LCAxOTIsIDIwOCwgMTg2LCAxODksCisyMjYsIDIzMCwgMTQzLCAyMDcsIDIxMiwgMTgxLCAyMDYsIDIwMywgMTY0LCAxODUsIDIyMCwgMTQzLCAyMDcsIDIyNSwgMTQzLCAyMDcsCisyMjgsIDE0MywgMjA3LCAyMzQsIDIwMCwgMTYzLCAyMjYsIDIzOSwgMjI2LCAyMzgsIDIwMCwgMjM0LCAxNDMsIDIwNywgMjQ0LCAyMDIsCisyMDMsIDE0MywgMjA3LCAyNTIsIDE0MywgMjA4LCAxNjEsIDIyNiwgMjUyLCAyMDAsIDIxNiwgMjI3LCAxNjIsIDE0MywgMjA4LCAxNzMsCisxNzYsIDIzNSwgMTQzLCAyMDgsIDE4NSwgMTQzLCAyMDgsIDE4OCwgMTQzLCAyMDgsIDE5MCwgMTQzLCAyMDgsIDE5MSwgMTQzLCAyMDgsCisxOTYsIDE0MywgMjA4LCAyMDAsIDE0MywgMjA4LCAyMDMsIDE0MywgMjA4LCAyMDcsIDE0MywgMjA4LCAyMTEsIDIyNywgMTc1LCAxOTAsCisyMDUsIDE0MywgMjA4LCAyMjAsIDE0MywgMjA4LCAyMjMsIDIyNywgMTgwLCAxNDMsIDIwOCwgMjI5LCAxNDMsIDIwOCwgMjM1LCAxNDMsCisyMDgsIDIzOCwgMTQzLCAyMDgsIDI0MiwgMTQzLCAyMDgsIDI0NCwgMTQzLCAyMDgsIDI0OSwgMTQzLCAyMDgsIDI1MiwgMTk5LCAyMzMsCisxOTAsIDIwNiwgMTc2LCAyMjAsIDE0MywgMjA5LCAxNzIsIDE0MywgMjA5LCAxNzYsIDE0MywgMjA5LCAxNzgsIDE0MywgMjA5LCAxODEsCisyMjcsIDIwMiwgMjI3LCAyMDMsIDE0MywgMjA5LCAxOTIsIDE3OCwgMTg2LCAxNDMsIDIwOSwgMTk4LCAxOTAsIDI0NywgMTQzLCAyMDksCisyMDYsIDE0MywgMjA5LCAyMDgsIDE0MywgMjA5LCAyMTEsIDE0MywgMjA5LCAyMTYsIDE0MywgMjA5LCAyMTksIDIyNywgMjIxLCAxNDMsCisyMDksIDIyMywgMjI3LCAyMjcsIDE0MywgMjA5LCAyMjksIDIyNywgMjM0LCAyMjcsIDIzNywgMTQzLCAyMDksIDIzNCwgMTQzLCAyMDksCisyMzksIDE0MywgMjA5LCAyNDIsIDE4MSwgMjMyLCAxNDMsIDIwOSwgMjQ0LCAyMjcsIDI1MCwgMjI3LCAyNTIsIDIyNywgMjQ3LCAxNDMsCisyMTAsIDE2MywgMTQzLCAyMTAsIDE2NywgMTk1LCAyMjIsIDIyOCwgMTg0LCAyMjgsIDE3MCwgMjI4LCAxNzIsIDE0MywgMjEwLCAxODAsCisxNDMsIDIxMCwgMTgyLCAyMjgsIDE3NiwgMTQzLCAyMTAsIDE4OSwgMTQzLCAyMTAsIDE5MSwgMTQzLCAyMTAsIDE5NiwgMjAwLCAyMDcsCisyMjgsIDE4OSwgMTQzLCAyMTAsIDIwNywgMTk4LCAxOTgsIDE0MywgMjEwLCAyMTIsIDE0MywgMjEwLCAyMTgsIDE0MywgMjEwLCAyMjQsCisyMjgsIDE5NCwgMTQzLCAyMTAsIDIzMSwgMTQzLCAyMTAsIDIzMywgMTQzLCAyMTAsIDIzNywgMjI4LCAyMTMsIDE0MywgMjEwLCAyNDQsCisyMjgsIDIxNiwgMTQzLCAyMTAsIDI1NCwgMTQzLCAyMTEsIDE2NCwgMjAyLCAxOTgsIDE0MywgMjExLCAxNzEsIDE0MywgMjExLCAxNzMsCisyMDYsIDE3OSwgMTQzLCAyMTEsIDE3NiwgMjI4LCAyMzQsIDIyOCwgMjM2LCAxNDMsIDIxMSwgMTg0LCAxNDMsIDIxMSwgMTg3LCAyMjgsCisyNDUsIDIyOCwgMjQ2LCAxNDMsIDIxMSwgMTk5LCAyMjgsIDI1MCwgMTgxLCAyMzQsIDE0MywgMjExLCAyMDUsIDE0MywgMjExLCAyMDksCisyMjksIDE2MiwgMTQzLCAyMTEsIDIxNSwgMTg2LCAyMTcsIDE4NiwgMTc2LCAxOTMsIDIwMCwgMjI5LCAxNzQsIDE0MywgMjExLCAyMzAsCisyMjksIDE3OSwgMjI5LCAxNzcsIDE0MywgMjExLCAyMzgsIDE0MywgMjExLCAyNDMsIDE0MywgMjExLCAyNDksIDE0MywgMjExLCAyNTIsCisyMjksIDE5NCwgMTg4LCAyNTAsIDE0MywgMjEyLCAxNjYsIDE0MywgMjEyLCAxNjksIDE0MywgMjEyLCAxNzQsIDE0MywgMjEyLCAxNzcsCisyMjksIDIwNiwgMTQzLCAyMTIsIDE4NCwgMTQzLCAyMTIsIDE4NywgMTQzLCAyMTIsIDE3OSwgMjI5LCAyMDgsIDE0MywgMjEyLCAxOTQsCisyMjksIDIxMywgMjAzLCAxNjUsIDIyOSwgMjIwLCAxNDMsIDIxMiwgMjA2LCAxOTMsIDE2MSwgMTkxLCAxNjUsIDIyOSwgMjI5LCAyMjksCisyMzQsIDE0MywgMjEyLCAyMjEsIDIyOSwgMjM5LCAxNDMsIDIxMiwgMjI2LCAxNDMsIDIxMiwgMjI5LCAyMjksIDI1MSwgMTgwLCAyMDQsCisxNDMsIDIxMiwgMjQwLCAyMzAsIDE2MywgMjMwLCAxNjksIDE0MywgMjEyLCAyNTAsIDE0MywgMjEyLCAyNTQsIDIwMCwgMjM3LCAyMzAsCisxNzYsIDIzMCwgMTgxLCAxNDMsIDIxMywgMTcxLCAxNDMsIDIxMywgMTc0LCAxNDMsIDIxMywgMTc4LCAyMzAsIDE5MiwgMTQzLCAyMTMsCisxODMsIDE0MywgMjEzLCAxODUsIDE0MywgMjEzLCAxODcsIDE0MywgMjEzLCAxOTAsIDE0MywgMjEzLCAxOTQsIDIzMCwgMjAzLCAxODUsCisyMDUsIDE0MywgMjEzLCAyMDMsIDIwNCwgMjE1LCAyMzAsIDIxMiwgMTQzLCAyMTMsIDIxNiwgMjA0LCAyMzcsIDE0MywgMjEzLCAyMjYsCisyMzAsIDIxNiwgMTkyLCAxODcsIDE0MywgMjEzLCAyMjgsIDE0MywgMjEzLCAyMzEsIDE5MSwgMTY2LCAxNDMsIDIxMywgMjM0LCAyMDcsCisxOTAsIDE5MCwgMjExLCAxODQsIDIxMiwgMTQzLCAyMTMsIDI0MSwgMTQzLCAyMTMsIDI0MiwgMTc2LCAyMjMsIDE0MywgMjEzLCAyNDUsCisxNDMsIDIxMywgMjUwLCAxODQsIDIxMywgMTQzLCAyMTMsIDI1MywgMTgyLCAxODcsIDE4NywgMjMzLCAxNDMsIDIxNCwgMTcwLCAxNDMsCisyMTQsIDE3NSwgMTQzLCAyMTQsIDE3OCwgMTk2LCAxNzcsIDE0MywgMjE0LCAxODMsIDIwMSwgMjI5LCAyMzEsIDE4MSwgMTQzLCAyMTQsCisxOTMsIDIzMSwgMTcxLCAxOTQsIDIyMCwgMjMxLCAxNzQsIDIzMSwgMTc4LCAyMzEsIDE3NywgMTQzLCAyMTQsIDIwOSwgMjMxLCAxODcsCisyMzEsIDE5MCwgMjMxLCAxOTMsIDE0MywgMjE0LCAyMjAsIDE0MywgMjE0LCAyMjQsIDE0MywgMjE0LCAyMjYsIDE0MywgMjE0LCAyMzEsCisxNDMsIDIxNCwgMjM2LCAyMTgsIDE3MCwgMTQzLCAyMTQsIDI0MCwgMTQzLCAyMTQsIDI0NCwgMTQzLCAyMTQsIDI0NywgMTQzLCAyMTQsCisyNDgsIDIzMSwgMjE3LCAxNDMsIDIxNSwgMTYxLCAxNDMsIDIxNSwgMTY1LCAxNDMsIDIxNSwgMTY3LCAyMzEsIDIyNiwgMTQzLCAyMTUsCisxNzEsIDIzMSwgMjMyLCAxNDMsIDIxNSwgMTgwLCAxNDMsIDIxNSwgMTg0LCAyMzEsIDIzNiwgMTQzLCAyMTUsIDE5NSwgMjAzLCAxNjcsCisxNzgsIDIzNCwgMTQzLCAyMTUsIDIwNywgMTQzLCAyMTUsIDIwOSwgMTQzLCAyMTUsIDIxMiwgMTQzLCAyMTUsIDIxNiwgMjMxLCAyNDksCisyMzEsIDI0NywgMTgzLCAyMTIsIDIzMiwgMTczLCAxNDMsIDIxNSwgMjMzLCAxNDMsIDIxNSwgMjM0LCAxOTUsIDIyNywgMjMyLCAxNjYsCisxODMsIDIxMywgMTQzLCAyMTUsIDIyNywgMTQzLCAyMTUsIDI1MywgMTc4LCAxNzQsIDIzMiwgMTc0LCAxNDMsIDIxNiwgMTY4LCAxNDMsCisyMTYsIDE3NCwgMTQzLCAyMTYsIDE3NiwgMjA1LCAyMzMsIDIzMiwgMjA3LCAxNDMsIDIxNiwgMTgzLCAxNDMsIDIxNiwgMTg3LCAxODYsCisyMTgsIDE0MywgMjE2LCAxOTEsIDIzMiwgMjAzLCAxNDMsIDIxNiwgMTk2LCAxNDMsIDIxNiwgMTk4LCAxNDMsIDIxNiwgMjAxLCAyMzIsCisyMDYsIDIzMiwgMjEyLCAyMzIsIDIyNiwgMTQzLCAyMTYsIDIwNywgMTQzLCAyMTYsIDIxMiwgMTQzLCAyMTYsIDIxNywgMTk4LCAxNjEsCisyMzIsIDIxMSwgMjMyLCAyMTYsIDE0MywgMjE2LCAyMzIsIDE5MCwgMjEzLCAxNDMsIDIxNiwgMjM2LCAyMzIsIDIzMSwgMTQzLCAyMTYsCisyNDAsIDE0MywgMjE2LCAyNDQsIDE0MywgMjE2LCAyNDcsIDE0MywgMjE2LCAyNTEsIDE0MywgMjE2LCAyNTQsIDE0MywgMjE3LCAxNjIsCisxNDMsIDIxNywgMTY2LCAxNDMsIDIxNywgMTcxLCAyMzIsIDIwOSwgMTQzLCAyMTcsIDE3OCwgMTc3LCAxODIsIDE0MywgMjE3LCAxODMsCisxNDMsIDIxNywgMTg4LCAyMDIsIDE5NSwgMjMyLCAyNTQsIDE0MywgMjE3LCAxOTcsIDE0MywgMjE3LCAyMDEsIDIwNywgMjA3LCAyMzMsCisxNzcsIDE0MywgMjE3LCAyMTYsIDE0MywgMjE3LCAyMjAsIDE3NywgMjQyLCAxNDMsIDIxNywgMjI4LCAyMDQsIDI0NCwgMTQzLCAyMTcsCisyMzIsIDIwNywgMjA2LCAxNDMsIDIxNywgMjQyLCAyMzMsIDE4NSwgMTQzLCAyMTcsIDI0NywgMjAwLCAyMDUsIDE0MywgMjE3LCAyNTIsCisyMzMsIDE5MywgMjMzLCAxOTAsIDIyMSwgMTc3LCAxNDMsIDIxOCwgMTc0LCAyMDUsIDI0NiwgMTQzLCAyMTgsIDE3OCwgMTQzLCAyMTgsCisxODMsIDIzMywgMjAwLCAxNDMsIDIxOCwgMTg4LCAxNDMsIDIxOCwgMTkzLCAxOTUsIDIzOCwgMTQzLCAyMTgsIDIwMCwgMTQzLCAyMTgsCisyMzcsIDIzMywgMjA2LCAxNDMsIDIxOCwgMjEwLCAyMzMsIDIxOSwgMTQzLCAyMTgsIDIxOCwgMTQzLCAyMTgsIDIyMiwgMjMzLCAyMTcsCisyMzMsIDIyMCwgMjMzLCAyMjEsIDIzMywgMjIyLCAxOTQsIDI1MywgMjAzLCAxNzAsIDIzMywgMjM1LCAxOTUsIDIxNiwgMTQzLCAyMTgsCisyNTQsIDE0MywgMjE5LCAxNjIsIDE0MywgMjE5LCAxNjYsIDE0MywgMjE5LCAxNzIsIDE0MywgMjE5LCAxNzQsIDIzMywgMjUxLCAxNDMsCisyMTksIDE3NywgMjMzLCAyNTMsIDIzMywgMjQ3LCAyMzQsIDE2NywgMTQzLCAyMTksIDE5MiwgMTQzLCAyMTksIDE5NiwgMjM0LCAxNjUsCisxNDMsIDIxOSwgMjAzLCAyMDUsIDIzMCwgMjM0LCAxNzUsIDE0MywgMjE5LCAyMTQsIDE0MywgMjE5LCAyMTcsIDE0MywgMjE5LCAyMjIsCisxNDMsIDIxOSwgMjI2LCAyMzQsIDE4NywgMTQzLCAyMTksIDIzMiwgMTQzLCAyMTksIDIzNywgMjM0LCAxOTIsIDE0MywgMjE5LCAyNDgsCisxNDMsIDIxOSwgMjUwLCAyMzQsIDE5NywgMTQzLCAyMjAsIDE2NCwgMjIyLCAxNjcsIDE3OSwgMTg1LCAxODUsIDIxMywgMjM0LCAyMDYsCisyMzQsIDIxMCwgMTgyLCAyMjIsIDE5NCwgMjIyLCAxOTQsIDE4MSwgMTQzLCAyMjAsIDE5MCwgMTQzLCAyMjAsIDE5MiwgMTg0LCAyMTEsCisxNDMsIDIyMCwgMTk1LCAxNDMsIDIyMCwgMTk3LCAyMzQsIDIyNywgMTQzLCAyMjAsIDIwNiwgMjM0LCAyMzUsIDIzNCwgMjM2LCAyMzQsCisyMzMsIDE0MywgMjIwLCAyMTQsIDE3OSwgMjM2LCAxNDMsIDIyMCwgMjIyLCAyMzQsIDI0MywgMTQzLCAyMjAsIDIyOCwgMTQzLCAyMjAsCisyMzMsIDIzNCwgMjQ3LCAxNDMsIDIyMCwgMjQwLCAxNDMsIDIyMCwgMjQzLCAyMzUsIDE2MiwgMTQzLCAyMjAsIDI1MCwgMTQzLCAyMjAsCisyNTQsIDIwMiwgMTY0LCAxNDMsIDIyMSwgMTY2LCAxNzksIDIwOCwgMTQzLCAyMjEsIDE3MywgMjM1LCAxNzgsIDIzNSwgMTgwLCAxNzksCisyMDksIDIzNSwgMTg1LCAxOTEsIDE2OCwgMTQzLCAyMjEsIDE4OSwgMTQzLCAyMjEsIDE5MywgMTQzLCAyMjEsIDE5NywgMTQzLCAyMjEsCisxOTksIDIzNSwgMTk0LCAyMzUsIDE5NiwgMTQzLCAyMjEsIDIxMCwgMTkxLCAxOTksIDE0MywgMjIxLCAyMTcsIDE4NiwgMTkwLCAyMzUsCisxOTksIDE0MywgMjIxLCAyMjksIDE4MSwgMjA1LCAxNDMsIDIyMSwgMjM1LCAyMzUsIDIwOSwgMTQzLCAyMjEsIDI0MywgMTQzLCAyMjEsCisyNDgsIDIzNSwgMjE2LCAxOTgsIDIwMSwgMTQzLCAyMjIsIDE2MiwgMjM1LCAyMTksIDE4MCwgMjEwLCAyMDcsIDE5MiwgMjM1LCAyMjcsCisyMzUsIDIyMSwgMTQzLCAyMjIsIDE4MCwgMTQzLCAyMjIsIDE4MywgMTQzLCAyMjIsIDE5MSwgMjM1LCAyMjYsIDE0MywgMjIyLCAxODksCisyMzUsIDI0NSwgMjM1LCAyNDAsIDIzNSwgMjQ0LCAxNDMsIDIyMiwgMjAxLCAxNDMsIDIyMiwgMjAyLCAyMDEsIDIzMiwgMTgzLCAyMTcsCisxODEsIDE5NiwgMTQzLCAyMjIsIDIxMywgMjE4LCAyMDYsIDE0MywgMjIyLCAyMjEsIDE0MywgMjIyLCAyMjQsIDE5NSwgMTcxLCAyMzYsCisxNzUsIDE0MywgMjIyLCAyMzMsIDIzNiwgMTgxLCAxOTAsIDIyMSwgMjA4LCAxNzQsIDE0MywgMjIyLCAyNTAsIDIzNiwgMTg2LCAyMDMsCisxOTgsIDIzNiwgMTk0LCAxODUsIDIxNSwgMTkyLCAyMTMsIDIzNiwgMjAyLCAxNzgsIDIzNiwgMTk0LCAxNzcsIDE0MywgMjIzLCAxNzgsCisxOTksIDIyOSwgMTg4LCAxOTMsIDE0MywgMjIzLCAxODcsIDE0MywgMjIzLCAxOTEsIDE0MywgMjIzLCAxOTQsIDIzNiwgMjE5LCAxOTIsCisyMTQsIDE0MywgMjIzLCAyMDEsIDE0MywgMjIzLCAyMDIsIDE3NywgMjE5LCAxNDMsIDIyMywgMjA5LCAxNDMsIDIyMywgMjExLCAxNDMsCisyMjMsIDIxNCwgMTQzLCAyMjMsIDIxOCwgMTQzLCAyMjMsIDIyMiwgMTQzLCAyMjMsIDIyNywgMTQzLCAyMjMsIDIzMCwgMjM2LCAyNDAsCisyMzYsIDIzOCwgMTQzLCAyMjMsIDI0MiwgMjM2LCAyNDUsIDIzNiwgMjQ0LCAxNDMsIDIyMywgMjUwLCAyMzYsIDI0NywgMjM3LCAxNjksCisyMzYsIDI1MywgMTQzLCAyMjQsIDE3MSwgMjM2LCAyNTQsIDE0MywgMjI0LCAxNzcsIDE0MywgMjI0LCAxODEsIDE0MywgMjI0LCAxODQsCisxODksIDE3OSwgMjM3LCAxNzUsIDIzNywgMTc5LCAxNDMsIDIyNCwgMTk4LCAyMzcsIDE4NiwgMTkxLCAyMDAsIDE0MywgMjI0LCAyMDksCisxNDMsIDIyNCwgMjEyLCAxODgsIDIxNCwgMTQzLCAyMjQsIDIxOSwgMTk4LCAyNDAsIDIzNywgMTk5LCAxNDMsIDIyNCwgMjI1LCAxNDMsCisyMjQsIDIzMCwgMjM3LCAyMTAsIDE0MywgMjI0LCAyMzUsIDE0MywgMjI0LCAyMzksIDIwNiwgMjE2LCAxNDMsIDIyNCwgMjQ4LCAyMzcsCisyMTcsIDIzNywgMjE5LCAxNDMsIDIyNSwgMTY2LCAxNDMsIDIyNSwgMTcwLCAxOTEsIDIwMSwgMTQzLCAyMjUsIDE3NywgMjM3LCAyMzEsCisyMDIsIDIxMywgMjAzLCAyNDgsIDE4MywgMjIyLCAyMzcsIDIzMywgMTQzLCAyMjUsIDE5NSwgMTQzLCAyMjUsIDE5NywgMjM3LCAyNTQsCisxNDMsIDIyNSwgMjAzLCAxNDMsIDIyNSwgMjA2LCAyMzcsIDI0OCwgMTk0LCAxNjQsIDE0MywgMjI1LCAyMTIsIDE0MywgMjI1LCAyMTYsCisyMzgsIDE2NywgMjM4LCAxNjYsIDE5OCwgMTg3LCAxNDMsIDIyNSwgMjIzLCAxNDMsIDIyNSwgMjI2LCAyMzgsIDE3NSwgMjA2LCAyMDMsCisyMzcsIDIzOCwgMjA1LCAxODQsIDE0MywgMjI1LCAyNDEsIDE0MywgMjI1LCAyNDUsIDIzOCwgMTg0LCAxNDMsIDIyNSwgMjUxLCAxNDMsCisyMjYsIDE2MywgMTQzLCAyMjYsIDE3MywgMTQzLCAyMjYsIDE2OSwgMjAxLCAyNDQsIDE0MywgMjI2LCAxNzgsIDE0MywgMjI2LCAxNzksCisxNDMsIDIyNiwgMTg1LCAyMzgsIDE5MiwgMTQzLCAyMjYsIDE5MywgMTQzLCAyMjYsIDE5OSwgMTQzLCAyMjYsIDIwMywgMTQzLCAyMjYsCisyMDksIDE0MywgMjI2LCAyMTIsIDE4OCwgMjQyLCAxNDMsIDIyNiwgMjIwLCAxODksIDE4MywgMTg1LCAyNDMsIDE0MywgMjI2LCAyMjgsCisyMzgsIDIwNCwgMTQzLCAyMjYsIDIzNywgMTQzLCAyMjYsIDI0MCwgMjM4LCAyMDgsIDIzOCwgMjExLCAxNDMsIDIyNiwgMjU0LCAyMzgsCisyMTYsIDE0MywgMjI3LCAxNjQsIDE5MSwgMjAzLCAxODIsIDI1MiwgMTQzLCAyMjcsIDE3OSwgMTQzLCAyMjcsIDE4MiwgMTQzLCAyMjcsCisxODcsIDE0MywgMjI3LCAxOTMsIDE0MywgMjI3LCAxOTgsIDE0MywgMjI3LCAyMDMsIDE0MywgMjI3LCAyMDcsIDE0MywgMjI3LCAyMTMsCisxOTcsIDE4MCwgMTQzLCAyMjcsIDIyMywgMTQzLCAyMjcsIDIyNiwgMjAwLCAxNzMsIDE0MywgMjI3LCAyMzYsIDE0MywgMjI3LCAyNDIsCisxODksIDE5OCwgMTQzLCAyMjcsIDI1MSwgMTQzLCAyMjcsIDI1NCwgMTQzLCAyMjgsIDE2NCwgMTQzLCAyMjgsIDE2OSwgMjM4LCAyNDgsCisxNDMsIDIyOCwgMTgxLCAxNDMsIDIyOCwgMTg4LCAxNDMsIDIyOCwgMTkzLCAxNDMsIDIyOCwgMjAwLCAxNDMsIDIyOCwgMjA1LCAxODEsCisyNDgsIDE0MywgMjI4LCAyMTIsIDE0MywgMjI4LCAyMTQsIDE5MSwgMjM4LCAyMzksIDE2MiwgMjA3LCAxNjMsIDE0MywgMjI4LCAyMzAsCisyMzgsIDI1MywgMTQzLCAyMjgsIDIzNSwgMTQzLCAyMjgsIDI0MSwgMTQzLCAyMjgsIDI0MywgMjM5LCAxNzEsIDE0MywgMjI5LCAxNjEsCisxNDMsIDIyOSwgMTY3LCAxNDMsIDIyOSwgMTcyLCAxNDMsIDIyOSwgMTc2LCAxNDMsIDIyOSwgMTgxLCAxNDMsIDIyOSwgMTgzLCAxNDMsCisyMjksIDE4OCwgMTQzLCAyMjksIDE5NSwgMjM5LCAxNzgsIDE4MiwgMTkyLCAxNDMsIDIyOSwgMjA3LCAxNDMsIDIyOSwgMjEyLCAxNDMsCisyMjksIDIxNywgMTQzLCAyMjksIDIyMiwgMjM5LCAxOTcsIDIzOSwgMTk1LCAyMzksIDE5NiwgMTQzLCAyMjksIDIzMSwgMTQzLCAyMjksCisyMzYsIDE0MywgMjI5LCAyMzgsIDE0MywgMjI5LCAyNDEsIDIzOSwgMjA2LCAyMzksIDIwOSwgMjM5LCAyMTYsIDE5NiwgMTg1LCAyMzksCisyMTcsIDE0MywgMjMwLCAxNjQsIDIzOSwgMjIxLCAyMzksIDIyNCwgMTQzLCAyMzAsIDE3MywgMTQzLCAyMzAsIDE3NiwgMjM5LCAyMzQsCisyMzksIDIzNSwgMTk4LCAxNzQsIDIzOSwgMjQzLCAyMDEsIDIzNiwgMTQzLCAyMzAsIDIwMSwgMTQzLCAyMzAsIDIwMywgMTkzLCAyMDMsCisyMzksIDI1MSwgMTQzLCAyMzAsIDIxNCwgMTQzLCAyMzAsIDIxNywgMjQwLCAxNjUsIDE5OCwgMTcxLCAxNDMsIDIzMCwgMjI0LCAyMzEsCisxNjEsIDI0MCwgMTY4LCAxNDMsIDIzMCwgMjMzLCAxNDMsIDIzMCwgMjM3LCAxNDMsIDIzMCwgMjQwLCAxOTEsIDI1MywgMTQzLCAyMzAsCisyNDIsIDI0MCwgMTg2LCAxNDMsIDIzMCwgMjQ5LCAxNDMsIDIzMCwgMjUwLCAyMDYsIDIzNywgMTg4LCAyNTEsIDIwNiwgMjM4LCAyNDAsCisxOTUsIDE0MywgMjMxLCAxNjcsIDI0MCwgMTk5LCAyNDAsIDIwMSwgMjQwLCAyMDUsIDE5MiwgMTk2LCAyNDAsIDIwOCwgMjQwLCAyMTEsCisyNDAsIDIxNSwgMTQzLCAyMzEsIDE5MSwgMjQwLCAyMTcsIDI0MCwgMjIzLCAxNDMsIDIzMSwgMTk5LCAyNDAsIDIyOCwgMjAyLCAyMjAsCisxNDMsIDIzMSwgMjEwLCAyNDAsIDIzMSwgMTQzLCAyMzEsIDIyMywgMTQzLCAyMzEsIDIyOCwgMTQzLCAyMzEsIDIzNSwgMjQwLCAyMzYsCisxNDMsIDIzMSwgMjQwLCAyMDIsIDE5OSwgMjQwLCAyNDMsIDE0MywgMjMxLCAyNDksIDE0MywgMjMxLCAyNTIsIDE0MywgMjMyLCAxNjEsCisxNDMsIDIzMiwgMTY3LCAxNDMsIDIzMiwgMTcwLCAxNzksIDIyMCwgMTgwLCAyMzQsIDE0MywgMjMyLCAxODAsIDE0MywgMjMyLCAxODUsCisyMDEsIDI0NywgMTQzLCAyMzIsIDE5MCwgMTQzLCAyMzIsIDE5NSwgMTQzLCAyMzIsIDE5OSwgMjAwLCAyNDQsIDE0MywgMjMyLCAyMDIsCisyMDAsIDIxMSwgMTg3LCAyNDQsIDE0MywgMjMyLCAyMDksIDE0MywgMjMyLCAyMTEsIDE0MywgMjMyLCAyMTYsIDE0MywgMjMyLCAyMjAsCisxNDMsIDIzMiwgMjIzLCAxNDMsIDIzMiwgMjMwLCAyNDEsIDE4OSwgMjQxLCAxOTAsIDE0MywgMjMyLCAyNDIsIDE4OCwgMjQzLCAyNDEsCisxOTgsIDE0MywgMjMyLCAyNTEsIDE0MywgMjMzLCAxNjIsIDE5NCwgMjA0LCAxOTUsIDI0MywgMTQzLCAyMzMsIDE3MCwgMTQzLCAyMzMsCisxNzMsIDI0MSwgMjA5LCAyNDEsIDIxMSwgMjQxLCAyMTUsIDI0MSwgMjE0LCAyNDEsIDIxNywgMTQzLCAyMzMsIDE5NCwgMTQzLCAyMzMsCisxOTcsIDI0MSwgMjE5LCAxNDMsIDIzMywgMjA0LCAxNDMsIDIzMywgMjA3LCAyNDEsIDIyNSwgMjQxLCAyMjksIDI0MSwgMjMzLCAxODUsCisyNTIsIDE0MywgMjMzLCAyMTgsIDI0MSwgMjM4LCAxNDMsIDIzMywgMjI4LCAxNDMsIDIzMywgMjMxLCAxNDMsIDIzMywgMjM2LCAxNDMsCisyMzMsIDI0MCwgMjQxLCAyNDksIDE0MywgMjMzLCAyNDcsIDE0MywgMjMzLCAyNTQsIDE0MywgMjM0LCAxNjcsIDI0MiwgMTYzLCAyNDIsCisxNjYsIDE0MywgMjM0LCAxNzgsIDE0MywgMjM0LCAxODIsIDE3OSwgMTYxLCAxNDMsIDIzNCwgMTg3LCAxNDMsIDIzNCwgMTg5LCAxNDMsCisyMzQsIDE5NCwgMTQzLCAyMzQsIDIwMCwgMTQzLCAyMzQsIDIwNSwgMTQzLCAyMzQsIDIwOSwgMTQzLCAyMzQsIDIxNSwgMjQyLCAxODQsCisxNDMsIDIzNCwgMjIzLCAxNDMsIDIzNCwgMjI2LCAxNDMsIDIzNCwgMjMwLCAxNDMsIDIzNCwgMjM0LCAyNDIsIDE5NiwgMTQzLCAyMzQsCisyNDIsIDE5NCwgMjI4LCAxNDMsIDIzNCwgMjQ3LCAxNDMsIDIzNCwgMjUxLCAxNDMsIDIzNSwgMTYxLCAyNDIsIDIxOCwgMTQzLCAyMzUsCisxNjgsIDE0MywgMjM1LCAxNzIsIDE0MywgMjM1LCAxNzcsIDIwMSwgMjAxLCAxNDMsIDIzNSwgMTg2LCAxNDMsIDIzNSwgMTg4LCAxNDMsCisyMzUsIDE5NCwgMTQzLCAyMzUsIDIwMCwgMTQzLCAyMzUsIDIwNSwgMTQzLCAyMzUsIDIxMSwgMjQyLCAyMzMsIDE5NiwgMTg3LCAyNDIsCisyMzYsIDE0MywgMjM1LCAyMjIsIDE3OCwgMTcwLCAxNDMsIDIzNSwgMjI1LCAyNDIsIDI0NSwgMTQzLCAyMzUsIDIyOSwgMTQzLCAyMzUsCisyMzQsIDI0MiwgMjQ3LCAyNDMsIDE2NSwgMTc3LCAxNzMsIDE0MywgMjM1LCAyNDgsIDE0MywgMjM1LCAyNTIsIDE0MywgMjM2LCAxNjMsCisxNDMsIDIzNiwgMTY3LCAxNDMsIDIzNiwgMTczLCAxNDMsIDIzNiwgMTc1LCAyNDMsIDE3MCwgMTQzLCAyMzYsIDE4MCwgMTQzLCAyMzYsCisxODMsIDE0MywgMjM2LCAxODYsIDI0MywgMTg2LCAxNDMsIDIzNiwgMTkzLCAxNDMsIDIzNiwgMTk4LCAxNDMsIDIzNiwgMjAyLCAyNDMsCisxOTEsIDE0MywgMjM2LCAyMDcsIDE0MywgMjM2LCAyMTAsIDI0MywgMTkzLCAyNDMsIDE5NSwgMTg4LCAxNzUsIDI0MywgMjAwLCAyNDMsCisyMDMsIDIwNiwgMjE5LCAyNDMsIDIwNywgMTQzLCAyMzYsIDIzOCwgMjIxLCAyMjQsIDE0MywgMjM2LCAyNDIsIDE4NSwgMjQ1LCAyNDMsCisyMTcsIDE0MywgMjM2LCAyNDcsIDE0MywgMjM2LCAyNTIsIDI0MywgMjI4LCAyNDMsIDIzMSwgMTQzLCAyMzcsIDE2OCwgMTQzLCAyMzcsCisxNzUsIDE0MywgMjM3LCAxNzgsIDE0MywgMjM3LCAxODIsIDIwMSwgMTYxLCAxNDMsIDIzNywgMTk0LCAyNDAsIDIzNywgMTQzLCAyMzcsCisyMDIsIDI0MywgMjQ1LCAxNDMsIDIzNywgMjEwLCAxNDMsIDIzNywgMjE0LCAyMDYsIDE4MiwgMTQzLCAyMzcsIDIyMiwgMTQzLCAyMzcsCisyMjQsIDE2MSwgMTcwLCAxNjEsIDIyMCwgMTYzLCAxODEsIDE2MSwgMTY5LCAxNjMsIDIwMSwgMTYzLCAyMTEsIDE2MSwgMjA3LCAxNjMsCisyMzEsIDE2MywgMjQxLCAxNjEsIDIwOCwgMTQyLCAxNjUsIDE0MiwgMTc1LCAxNDIsIDE4NSwgMTQyLCAxOTUsIDE0MiwgMjA1LCAxNDIsCisyMTUsIDE2MSwgMTc3CisgICAgICAgICAgICB9KTsKKworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29kZWNEeW5hbWljICgpIHRocm93cyBDaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb24geworICAgICAgICBlbmNvZGVyLm9uVW5tYXBwYWJsZUNoYXJhY3RlcihDb2RpbmdFcnJvckFjdGlvbi5SRVBPUlQpOworICAgICAgICBkZWNvZGVyLm9uTWFsZm9ybWVkSW5wdXQoQ29kaW5nRXJyb3JBY3Rpb24uUkVQT1JUKTsKKyAgICAgICAgQ2hhckJ1ZmZlciBpbnB1dENCID0gQ2hhckJ1ZmZlci5hbGxvY2F0ZSg2NTUzNik7CisgICAgICAgIGZvciAoaW50IGNvZGUgPSAzMjsgY29kZSA8PSA2NTUzMzsgY29kZSArKykgeworICAgICAgICAgICAgaWYgKChlbmNvZGVyLmNhbkVuY29kZSgoY2hhcikgY29kZSkpCisgICAgICAgICAgICAgICAgICAgICYmIChjb2RlICE9IDE2NSkgJiYgKGNvZGUgIT0gODI1NCkgJiYgKGNvZGUgIT0gNjM1OTkpKSB7CisgICAgICAgICAgICAgICAgaW5wdXRDQi5wdXQoKGNoYXIpIGNvZGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlucHV0Q0IucmV3aW5kKCk7CisgICAgICAgIEJ5dGVCdWZmZXIgaW50ZXJtZWRpYXRlQkIgPSBlbmNvZGVyLmVuY29kZShpbnB1dENCKTsKKyAgICAgICAgaW5wdXRDQi5yZXdpbmQoKTsKKyAgICAgICAgaW50ZXJtZWRpYXRlQkIucmV3aW5kKCk7CisgICAgICAgIENoYXJCdWZmZXIgb3V0cHV0Q0IgPSBkZWNvZGVyLmRlY29kZShpbnRlcm1lZGlhdGVCQik7CisgICAgICAgIG91dHB1dENCLnJld2luZCgpOworICAgICAgICBhc3NlcnRFcXVhbENCcygiZGVjb2RlKGVuY29kZShBKSkgbXVzdCBiZSBpZGVudGljYWwgd2l0aCBBISIsCisgICAgICAgICAgICAgICAgaW5wdXRDQiwgb3V0cHV0Q0IpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X011bHRpQnl0ZV9FVUNfS1IuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9NdWx0aUJ5dGVfRVVDX0tSLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzY0ZTBiOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9NdWx0aUJ5dGVfRVVDX0tSLmphdmEKQEAgLTAsMCArMSw0NzcgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworcHVibGljIGNsYXNzIE9sZENoYXJzZXRfTXVsdGlCeXRlX0VVQ19LUiBleHRlbmRzIE9sZENoYXJzZXRfQWJzdHJhY3RUZXN0IHsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJzZXROYW1lID0gIkVVQy1LUiI7CisKKyAgICAgICAgdGVzdENoYXJzID0gdGhlc2VDaGFycyhuZXcgaW50W117CiswLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAorMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCiszMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKzQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCis4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKzk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorMTYxLCAxNjQsIDE2NywgMTY4LCAxNzAsIDE3MywgMTc2LCAxNzcsIDE3OCwgMTc5LCAxODAsIDE4MiwgMTgzLCAxODQsIDE4NSwgMTg2LAorMTg4LCAxODksIDE5MCwgMTkxLCAxOTgsIDIwOCwgMjE1LCAyMTYsIDIyMiwgMjIzLCAyMzAsIDI0MCwgMjQ3LCAyNDgsIDI1NCwgMjczLAorMjk0LCAzMDUsIDMxOSwgMzI5LCAzMzksIDM1OCwgNzExLCA3MjgsIDkxMywgOTIzLCA5MzMsIDk0NSwgOTU1LCA5NjUsIDEwMjUsIDEwNDAsCisxMDUwLCAxMDYwLCAxMDcwLCAxMDgwLCAxMDkwLCAxMTAwLCA4MjEzLCA4MjI0LCA4MjQwLCA4MjUxLCA4MzA4LCA4MzE5LCA4NDUxLCA4NDY3LCA4NDgxLCA4NDkxLAorODUzMSwgODU0MSwgODU1MSwgODU2MSwgODU5MiwgODY1OCwgODcwNCwgODcxNSwgODczMCwgODc0MSwgODc1NiwgODc4NiwgODgwMCwgODgxMCwgODgzNCwgODg1NywKKzg4NjksIDg5NzgsIDkzMTIsIDkzMjIsIDkzMzIsIDkzNDIsIDkzNzIsIDkzODIsIDkzOTIsIDk0MjQsIDk0MzQsIDk0NDQsIDk0NzIsIDk0ODQsIDk0OTQsIDk1MDQsCis5NTE0LCA5NTI0LCA5NTM0LCA5NTQ0LCA5NjE4LCA5NjMyLCA5NjUwLCA5NjYwLCA5NjcwLCA5NjgwLCA5NzMzLCA5NzQzLCA5NzU2LCA5NzkyLCA5ODI0LCA5ODM0LAorMTIyODgsIDEyMjk4LCAxMjMwOCwgMTIzNTMsIDEyMzYzLCAxMjM3MywgMTIzODMsIDEyMzkzLCAxMjQwMywgMTI0MTMsIDEyNDIzLCAxMjQzMywgMTI0NDksIDEyNDU5LCAxMjQ2OSwgMTI0NzksCisxMjQ4OSwgMTI0OTksIDEyNTA5LCAxMjUxOSwgMTI1MjksIDEyNTkzLCAxMjYwMywgMTI2MTMsIDEyNjIzLCAxMjYzMywgMTI2NDMsIDEyNjUzLCAxMjY2MywgMTI2NzMsIDEyNjgzLCAxMjgwMCwKKzEyODEwLCAxMjgyMCwgMTI4OTYsIDEyOTA2LCAxMjkxNiwgMTI5MjcsIDEzMTg0LCAxMzE5NCwgMTMyMDQsIDEzMjE0LCAxMzIyNCwgMTMyMzQsIDEzMjQ0LCAxMzI1NCwgMTMyNjQsIDEzMjc1LAorMTk5NjgsIDE5OTc4LCAxOTk4OCwgMTk5OTgsIDIwMDEzLCAyMDAyNCwgMjAwMzQsIDIwMDQ1LCAyMDA1NiwgMjAwNzUsIDIwMDg2LCAyMDA5OCwgMjAxMDgsIDIwMTIwLCAyMDEzMCwgMjAxNDAsCisyMDE1MCwgMjAxNjAsIDIwMTcwLCAyMDE4MCwgMjAxOTEsIDIwMjA4LCAyMDIxOSwgMjAyMzMsIDIwMjcxLCAyMDI4MiwgMjAyOTQsIDIwMzA0LCAyMDMxNCwgMjAzMjksIDIwMzM5LCAyMDM1MCwKKzIwMzYwLCAyMDM3NCwgMjAzOTgsIDIwNDE1LCAyMDQyNSwgMjA0MzUsIDIwNDQ1LCAyMDQ2MiwgMjA0NzIsIDIwNDgyLCAyMDQ5MywgMjA1MDUsIDIwNTE1LCAyMDUyNSwgMjA1MzksIDIwNTUxLAorMjA1NjUsIDIwNTgxLCAyMDU5NiwgMjA2MDgsIDIwNjIxLCAyMDYzMiwgMjA2NTIsIDIwNjYzLCAyMDY3NywgMjA2ODcsIDIwNjk4LCAyMDcwOSwgMjA3MjksIDIwNzQwLCAyMDc1NCwgMjA3NjcsCisyMDc3OCwgMjA3OTEsIDIwODAxLCAyMDgxMSwgMjA4MjgsIDIwODM5LCAyMDg0OSwgMjA4NjAsIDIwODcwLCAyMDg4MiwgMjA4OTYsIDIwOTA2LCAyMDkxOCwgMjA5MzIsIDIwOTU2LCAyMDk3NiwKKzIwOTg2LCAyMDk5OCwgMjEwMDksIDIxMDIxLCAyMTAzMywgMjEwNDYsIDIxMDU5LCAyMTA2OSwgMjEwODMsIDIxMDk3LCAyMTEwOSwgMjExMTksIDIxMTI5LCAyMTE0NywgMjExNjEsIDIxMTgyLAorMjExOTMsIDIxMjA1LCAyMTIxNSwgMjEyMzUsIDIxMjQ2LCAyMTI1NiwgMjEyNjksIDIxMjgwLCAyMTI5MCwgMjEzMDUsIDIxMzE1LCAyMTMyNSwgMjEzMzUsIDIxMzUwLCAyMTM2MCwgMjEzNzMsCisyMTM5NSwgMjE0MDcsIDIxNDIxLCAyMTQzNSwgMjE0NDgsIDIxNDYwLCAyMTQ3MywgMjE0ODMsIDIxNDk2LCAyMTUwNywgMjE1MTcsIDIxNTMxLCAyMTU0MiwgMjE1NTUsIDIxNTY2LCAyMTU3NiwKKzIxNjA4LCAyMTYxOSwgMjE2MjksIDIxNjQ0LCAyMTY2OCwgMjE2ODMsIDIxNjkzLCAyMTcwNCwgMjE3MjksIDIxNzQxLCAyMTc1NCwgMjE3NjQsIDIxNzc0LCAyMTc4OCwgMjE4MDcsIDIxODIyLAorMjE4MzksIDIxODU0LCAyMTg4NCwgMjE4OTQsIDIxOTEyLCAyMTkyNywgMjE5NTcsIDIxOTcyLCAyMTk4MywgMjIwMTMsIDIyMDI1LCAyMjAzNiwgMjIwNjMsIDIyMDk5LCAyMjEyMCwgMjIxMzIsCisyMjE1MCwgMjIxODEsIDIyMTk2LCAyMjIxOCwgMjIyMzQsIDIyMjU2LCAyMjI2NiwgMjIyNzYsIDIyMjkwLCAyMjMwMywgMjIzMTcsIDIyMzMxLCAyMjM0MywgMjIzNTMsIDIyMzY5LCAyMjM4MiwKKzIyMzk2LCAyMjQwOCwgMjI0MTksIDIyNDMyLCAyMjQ2NywgMjI0NzgsIDIyNDk1LCAyMjUxMiwgMjI1MjIsIDIyNTMzLCAyMjU1OCwgMjI1NzAsIDIyNTgwLCAyMjYwMiwgMjI2MTIsIDIyNjIyLAorMjI2NDUsIDIyNjU5LCAyMjY3NSwgMjI2ODYsIDIyNjk2LCAyMjcwNywgMjI3MTgsIDIyNzM0LCAyMjc0NCwgMjI3NTYsIDIyNzY3LCAyMjc3NywgMjI3OTksIDIyODA5LCAyMjgyMywgMjI4MzMsCisyMjg0NiwgMjI4NTYsIDIyODY4LCAyMjg4MCwgMjI4OTAsIDIyOTAwLCAyMjkxNCwgMjI5MzEsIDIyOTQ5LCAyMjk2OSwgMjI5NzksIDIyOTkyLCAyMzAwMiwgMjMwMTQsIDIzMDMyLCAyMzA0MywKKzIzMDU3LCAyMzA2NywgMjMwNzcsIDIzMDk0LCAyMzEwNSwgMjMxMzAsIDIzMTQyLCAyMzE4NiwgMjMyMDQsIDIzMjMzLCAyMzI0NCwgMjMyNjUsIDIzMzAxLCAyMzMxOCwgMjMzMzgsIDIzMzYwLAorMjMzNzYsIDIzMzg2LCAyMzM5NiwgMjM0MDgsIDIzNDE4LCAyMzQyOSwgMjM0MzksIDIzNDQ5LCAyMzQ1OSwgMjM0NzAsIDIzNDgwLCAyMzQ5MCwgMjM1MDAsIDIzNTExLCAyMzUyMSwgMjM1MzEsCisyMzU0MSwgMjM1NTMsIDIzNTYzLCAyMzU3NCwgMjM1ODgsIDIzNjAxLCAyMzYxMSwgMjM2MjEsIDIzNjMzLCAyMzY0MywgMjM2NTMsIDIzNjYzLCAyMzY3MywgMjM2OTYsIDIzNzEzLCAyMzcyMywKKzIzNzMzLCAyMzc0NCwgMjM3NjksIDIzNzg0LCAyMzc5NiwgMjM4MTUsIDIzODI1LCAyMzg0NywgMjM4ODMsIDIzOTEzLCAyMzk0MywgMjM5NjUsIDIzOTc4LCAyMzk5MiwgMjQwMTMsIDI0MDI5LAorMjQwMzksIDI0MDQ5LCAyNDA2MSwgMjQwNzYsIDI0MDg2LCAyNDEwMSwgMjQxMTUsIDI0MTI1LCAyNDEzNSwgMjQxNDksIDI0MTU5LCAyNDE3OCwgMjQxODgsIDI0MTk5LCAyNDIxMywgMjQyMjQsCisyNDIzNSwgMjQyNDUsIDI0MjU4LCAyNDI3MiwgMjQyODIsIDI0MzAwLCAyNDMxMCwgMjQzMjEsIDI0MzM1LCAyNDM0NywgMjQzNTgsIDI0MzY5LCAyNDM4MCwgMjQzOTIsIDI0NDA2LCAyNDQxOCwKKzI0NDI4LCAyNDQzOSwgMjQ0NDksIDI0NDU5LCAyNDQ3MSwgMjQ0ODEsIDI0NDk0LCAyNDUwNSwgMjQ1MTUsIDI0NTI1LCAyNDUzNSwgMjQ1NTUsIDI0NTY1LCAyNDU3NSwgMjQ1OTEsIDI0NjA0LAorMjQ2MTUsIDI0NjQxLCAyNDY1MywgMjQ2NjUsIDI0Njc1LCAyNDY4NSwgMjQ3MDksIDI0NzI0LCAyNDczNSwgMjQ3NTIsIDI0NzY0LCAyNDc3NSwgMjQ3ODUsIDI0Nzk2LCAyNDgxNiwgMjQ4MjYsCisyNDgzOCwgMjQ4NTMsIDI0ODYzLCAyNDg4MCwgMjQ4OTIsIDI0OTAzLCAyNDkxNSwgMjQ5MjUsIDI0OTM1LCAyNDk1MCwgMjQ5NjEsIDI0OTc0LCAyNDk4NCwgMjQ5OTYsIDI1MDA2LCAyNTAxOCwKKzI1MDMxLCAyNTA2MiwgMjUwNzQsIDI1MDg0LCAyNTA5NSwgMjUxMDUsIDI1MTE5LCAyNTEzMCwgMjUxNDAsIDI1MTUwLCAyNTE2MCwgMjUxNzEsIDI1MTk4LCAyNTIwOSwgMjUyMjAsIDI1MjMzLAorMjUyNDMsIDI1MjU5LCAyNTI2OSwgMjUyODIsIDI1MjkyLCAyNTMwMiwgMjUzMjQsIDI1MzM1LCAyNTM0NSwgMjUzNjEsIDI1Mzg3LCAyNTQwMiwgMjU0MTcsIDI1NDI5LCAyNTQ0NywgMjU0NTgsCisyNTQ3MSwgMjU0ODEsIDI1NDk0LCAyNTUwNCwgMjU1MTQsIDI1NTM2LCAyNTU1MSwgMjU1NjIsIDI1NTgxLCAyNTU5MSwgMjU2MTMsIDI1NjIzLCAyNTYzNCwgMjU2NDQsIDI1NjU4LCAyNTY4OCwKKzI1NzA1LCAyNTcyMCwgMjU3MzYsIDI1NzQ2LCAyNTc1OCwgMjU3NzEsIDI1Nzg3LCAyNTc5NywgMjU4MTAsIDI1ODI1LCAyNTgzNiwgMjU4NTAsIDI1ODYwLCAyNTg4MCwgMjU4OTEsIDI1OTAzLAorMjU5MTMsIDI1OTI1LCAyNTkzNSwgMjU5NTAsIDI1OTY0LCAyNTk3NSwgMjU5ODYsIDI1OTk2LCAyNjAwNywgMjYwMTcsIDI2MDI3LCAyNjAzOSwgMjYwNDksIDI2MDU5LCAyNjA3MSwgMjYwODMsCisyNjA5MywgMjYxMDYsIDI2MTE4LCAyNjEyOCwgMjYxNDIsIDI2MTUyLCAyNjE2NCwgMjYxNzcsIDI2MTg3LCAyNjIwMSwgMjYyMTIsIDI2MjIyLCAyNjIzMiwgMjYyNDQsIDI2MjU0LCAyNjI2NCwKKzI2Mjc0LCAyNjI4NiwgMjYyOTcsIDI2MzA4LCAyNjMyNiwgMjYzMzYsIDI2MzUyLCAyNjM2MiwgMjYzNzYsIDI2Mzg4LCAyNjM5OCwgMjY0MDgsIDI2NDIwLCAyNjQzOCwgMjY0NDgsIDI2NDYwLAorMjY0NzcsIDI2NDg3LCAyNjUwMywgMjY1MTUsIDI2NTI1LCAyNjU0MywgMjY1NTgsIDI2NTc1LCAyNjU4NiwgMjY2MDEsIDI2NjExLCAyNjYyMiwgMjY2NDIsIDI2NjU3LCAyNjY3MSwgMjY2ODEsCisyNjY5MSwgMjY3MDIsIDI2NzMzLCAyNjc1MSwgMjY3NjcsIDI2NzgxLCAyNjc5MSwgMjY4MDEsIDI2ODIwLCAyNjgzNCwgMjY4NDcsIDI2ODYyLCAyNjg3MywgMjY4ODUsIDI2ODk4LCAyNjkxOSwKKzI2OTQxLCAyNjk1NCwgMjY5NjQsIDI2OTc0LCAyNjk4NCwgMjY5OTcsIDI3MDI5LCAyNzA0NSwgMjcwNjAsIDI3MDczLCAyNzA4MywgMjcxMTIsIDI3MTMxLCAyNzE0NiwgMjcxNTksIDI3MTY5LAorMjcxODksIDI3MjA0LCAyNzIxOCwgMjcyMzEsIDI3MjQzLCAyNzI2NCwgMjcyNzcsIDI3Mjg3LCAyNzI5OCwgMjczMTUsIDI3MzMwLCAyNzM0NywgMjczODIsIDI3Mzk2LCAyNzQxMCwgMjc0MjQsCisyNzQ0MiwgMjc0NTMsIDI3NDYzLCAyNzQ4NywgMjc0OTgsIDI3NTExLCAyNzUyMywgMjc1NDIsIDI3NTY2LCAyNzU3OCwgMjc1ODksIDI3NTk5LCAyNzYxMSwgMjc2MjcsIDI3NjU2LCAyNzY2NywKKzI3NjgzLCAyNzcwMCwgMjc3MTAsIDI3NzI2LCAyNzczOCwgMjc3NTIsIDI3NzYyLCAyNzc3MywgMjc3ODMsIDI3Nzk0LCAyNzgxOSwgMjc4MzIsIDI3ODQyLCAyNzg1MiwgMjc4NjMsIDI3ODczLAorMjc4ODMsIDI3OTE1LCAyNzkyNywgMjc5NDEsIDI3OTU0LCAyNzk2NSwgMjc5OTMsIDI4MDAzLCAyODAxNCwgMjgwMjQsIDI4MDM3LCAyODA0OSwgMjgwNzksIDI4MDk2LCAyODEwNywgMjgxMjAsCisyODEzNiwgMjgxNDcsIDI4MTgzLCAyODE5MywgMjgyMDMsIDI4MjE0LCAyODIyNywgMjgyMzcsIDI4MjQ4LCAyODI2MywgMjgyNzQsIDI4MzA0LCAyODMxNiwgMjgzMzAsIDI4MzQyLCAyODM1NCwKKzI4MzY0LCAyODM5OSwgMjg0MTQsIDI4NDMxLCAyODQ0OCwgMjg0NTksIDI4NDcyLCAyODQ5NywgMjg1MDcsIDI4NTI1LCAyODUzOCwgMjg1NDgsIDI4NTU4LCAyODU3OSwgMjg1OTAsIDI4NjAxLAorMjg2MTEsIDI4NjI5LCAyODYzOSwgMjg2NDksIDI4NjcwLCAyODY4MSwgMjg2OTMsIDI4NzAzLCAyODcxOSwgMjg3MzQsIDI4NzQ4LCAyODc2MCwgMjg3NzEsIDI4Nzg0LCAyODc5NiwgMjg4MTAsCisyODgyNCwgMjg4MzYsIDI4ODQ3LCAyODg1NywgMjg4NzIsIDI4ODg4LCAyODkxMywgMjg5MjUsIDI4OTM3LCAyODk1MywgMjg5NjYsIDI4OTc2LCAyODk5OSwgMjkwMTQsIDI5MDI4LCAyOTAzOCwKKzI5MDUzLCAyOTA2NSwgMjkwNzYsIDI5MDg3LCAyOTEwMCwgMjkxMTMsIDI5MTIzLCAyOTEzNCwgMjkxNTEsIDI5MTY1LCAyOTE3OSwgMjkxOTAsIDI5MjAwLCAyOTIxMSwgMjkyMjYsIDI5MjM3LAorMjkyNDgsIDI5MjYwLCAyOTI3MiwgMjkyODIsIDI5Mjk4LCAyOTMwOSwgMjkzNDYsIDI5MzU2LCAyOTM3NiwgMjkzOTAsIDI5NDAxLCAyOTQxNywgMjk0MzIsIDI5NDUwLCAyOTQ2MiwgMjk0NzcsCisyOTQ5NCwgMjk1MDgsIDI5NTIwLCAyOTU0NCwgMjk1NTQsIDI5NTcyLCAyOTU4MiwgMjk1OTIsIDI5NjA3LCAyOTYxOCwgMjk2MzIsIDI5NjQyLCAyOTY1NCwgMjk2NjQsIDI5Njc0LCAyOTY4NywKKzI5Njk3LCAyOTcxNSwgMjk3MjgsIDI5NzM4LCAyOTc0OCwgMjk3NTksIDI5NzcxLCAyOTc4MSwgMjk3OTEsIDI5ODAxLCAyOTgyMiwgMjk4MzMsIDI5ODQ4LCAyOTg1OSwgMjk4NzIsIDI5ODg1LAorMjk4OTgsIDI5OTA4LCAyOTkyMCwgMjk5MzQsIDI5OTUzLCAyOTk2OSwgMjk5NzksIDI5OTg5LCAzMDAwMCwgMzAwMTAsIDMwMDIzLCAzMDAzMywgMzAwNDMsIDMwMDUzLCAzMDA2MywgMzAwNzQsCiszMDA4NiwgMzAwOTcsIDMwMTA5LCAzMDEyMywgMzAxMzMsIDMwMTQ2LCAzMDE1NywgMzAxNjgsIDMwMTc4LCAzMDE5MiwgMzAyMDIsIDMwMjIxLCAzMDIzMywgMzAyNDQsIDMwMjY3LCAzMDI4NCwKKzMwMjk0LCAzMDMwNSwgMzAzMTYsIDMwMzI4LCAzMDM0MCwgMzAzNTAsIDMwMzgyLCAzMDM5NCwgMzA0MDYsIDMwNDE4LCAzMDQyOCwgMzA0MzksIDMwNDUwLCAzMDQ2MCwgMzA0NzIsIDMwNDk0LAorMzA1MDUsIDMwNTE5LCAzMDU0MSwgMzA1NTUsIDMwNTY2LCAzMDU4NSwgMzA2MDMsIDMwNjIyLCAzMDYzNiwgMzA2NTEsIDMwNjc5LCAzMDY5MCwgMzA3MDEsIDMwNzIyLCAzMDczOCwgMzA3NTcsCiszMDc3MCwgMzA3ODksIDMwNzk5LCAzMDgxMywgMzA4MjcsIDMwODQ0LCAzMDg1NSwgMzA4NjUsIDMwODgzLCAzMDkwNiwgMzA5MTcsIDMwOTI4LCAzMDk1MiwgMzA5NjUsIDMwOTc3LCAzMDk5MCwKKzMxMDE4LCAzMTAzNCwgMzEwNDcsIDMxMDYyLCAzMTA3MiwgMzEwODUsIDMxMDk4LCAzMTExNywgMzExNDIsIDMxMTUzLCAzMTE2NSwgMzExNzcsIDMxMTg5LCAzMTE5OSwgMzEyMDksIDMxMjI3LAorMzEyMzcsIDMxMjUyLCAzMTI2MywgMzEyNzgsIDMxMjkxLCAzMTMwMiwgMzEzMTksIDMxMzI5LCAzMTMzOSwgMzEzNTAsIDMxMzYxLCAzMTM3OCwgMzEzOTEsIDMxNDAxLCAzMTQxOCwgMzE0MjgsCiszMTQ0NywgMzE0NTksIDMxNDY5LCAzMTQ4MSwgMzE1MDMsIDMxNTEzLCAzMTUyNiwgMzE1NDUsIDMxNTU4LCAzMTU2OCwgMzE1ODQsIDMxNTk2LCAzMTYxMywgMzE2MjMsIDMxNjM2LCAzMTY0OSwKKzMxNjYxLCAzMTY3MiwgMzE2ODQsIDMxNjk4LCAzMTcxMiwgMzE3NTEsIDMxNzYyLCAzMTc3NCwgMzE3ODYsIDMxODA1LCAzMTgyMCwgMzE4NDAsIDMxODUyLCAzMTg3NSwgMzE4OTAsIDMxOTAzLAorMzE5MTgsIDMxOTI5LCAzMTk0NiwgMzE5NTgsIDMxOTY4LCAzMTk5NSwgMzIwMDUsIDMyMDE2LCAzMjAyNiwgMzIwNDMsIDMyMDUzLCAzMjA2NiwgMzIwODAsIDMyMDk0LCAzMjEwNCwgMzIxMTQsCiszMjEyNywgMzIxNDIsIDMyMTU2LCAzMjE3MiwgMzIxODQsIDMyMTk5LCAzMjIxNCwgMzIyMjQsIDMyMjM2LCAzMjI1MSwgMzIyNjUsIDMyMjc3LCAzMjI4NywgMzIyOTksIDMyMzExLCAzMjMyMSwKKzMyMzM4LCAzMjM1MCwgMzIzNjEsIDMyMzc3LCAzMjM5NiwgMzI0MDYsIDMyNTY2LCAzMjU4OCwgMzI2MTgsIDMyNjI5LCAzMjY0NSwgMzI2NjAsIDMyNjcwLCAzMjY4MCwgMzI2OTAsIDMyNzAxLAorMzI3MTQsIDMyNzI0LCAzMjczNSwgMzI3NDUsIDMyNzYxLCAzMjc3MSwgMzI3ODQsIDMyODEzLCAzMjgyOSwgMzI4NDIsIDMyODU0LCAzMjg3OSwgMzI4OTMsIDMyOTAzLCAzMjkxOCwgMzI5MjksCiszMjk0MywgMzI5NTQsIDMyOTY0LCAzMjk3NCwgMzI5ODYsIDMyOTk2LCAzMzAwOSwgMzMwMjEsIDMzMDMxLCAzMzA0OCwgMzMwNTksIDMzMDcxLCAzMzA4MSwgMzMwOTksIDMzMTA5LCAzMzEyNSwKKzMzMTM2LCAzMzE0NiwgMzMxNjAsIDMzMTc4LCAzMzE5MiwgMzMyMDMsIDMzMjEzLCAzMzIyOSwgMzMyNDAsIDMzMjUxLCAzMzI2MSwgMzMyNzQsIDMzMjg1LCAzMzI5OCwgMzMzMDgsIDMzMzIyLAorMzMzMzMsIDMzMzQ0LCAzMzM2OSwgMzMzODAsIDMzMzkwLCAzMzQwMCwgMzM0MTksIDMzNDMzLCAzMzQ0NSwgMzM0NTUsIDMzNDY1LCAzMzQ4OSwgMzM0OTksIDMzNTA5LCAzMzUyMSwgMzM1MzMsCiszMzU0NSwgMzM1NTksIDMzNTc2LCAzMzU4OCwgMzM2MDAsIDMzNjEwLCAzMzY1MSwgMzM2NzMsIDMzNjg2LCAzMzY5OCwgMzM3MjUsIDMzNzM3LCAzMzc0NywgMzM3NjksIDMzNzgwLCAzMzc5NSwKKzMzODA1LCAzMzgzMywgMzM4NDgsIDMzODY1LCAzMzg3OSwgMzM4ODksIDMzODk5LCAzMzkwOSwgMzM5MzYsIDMzOTQ4LCAzMzk3MCwgMzM5ODAsIDMzOTkwLCAzNDAwMSwgMzQwMjgsIDM0MDQ0LAorMzQwNjUsIDM0MDc4LCAzNDA5MiwgMzQxMDksIDM0MTIxLCAzNDEzMSwgMzQxNDcsIDM0MTU3LCAzNDE4MCwgMzQxOTEsIDM0MjAzLCAzNDIxNCwgMzQyMjQsIDM0MjM0LCAzNDI0OSwgMzQyNjEsCiszNDI3NiwgMzQyOTUsIDM0MzA2LCAzNDMyNiwgMzQzNDksIDM0MzY3LCAzNDM4MiwgMzQzOTUsIDM0NDA3LCAzNDQyNSwgMzQ0NDIsIDM0NDY3LCAzNDUwMywgMzQ1MTYsIDM0NTI3LCAzNDU0MSwKKzM0NTU4LCAzNDU2OCwgMzQ1ODQsIDM0NjM4LCAzNDY1NSwgMzQ2NzYsIDM0NjkwLCAzNDcwMSwgMzQ3MTksIDM0NzM5LCAzNDc1NiwgMzQ3ODQsIDM0Nzk2LCAzNDgwOSwgMzQ4MjEsIDM0ODQ3LAorMzQ4NjUsIDM0ODc1LCAzNDg4NiwgMzQ4OTgsIDM0OTA5LCAzNDkyMCwgMzQ5MzAsIDM0OTQyLCAzNDk1MiwgMzQ5NjIsIDM0OTc0LCAzNDk4NywgMzUwMDksIDM1MDIzLCAzNTAzMywgMzUwNDgsCiszNTA1OSwgMzUwNjksIDM1MDc5LCAzNTA5MCwgMzUxMDksIDM1MTI2LCAzNTEzNywgMzUxNjcsIDM1MTc4LCAzNTE5OSwgMzUyMTEsIDM1MjIyLCAzNTIzMywgMzUyNTAsIDM1MjYxLCAzNTI4MiwKKzM1Mjk5LCAzNTMxNiwgMzUzMjgsIDM1MzM4LCAzNTM1MCwgMzUzNjMsIDM1MzczLCAzNTM4NiwgMzU0MDgsIDM1NDE5LCAzNTQzMCwgMzU0NDAsIDM1NDYxLCAzNTQ3NSwgMzU0ODYsIDM1NDk2LAorMzU1MDYsIDM1NTE2LCAzNTUyNywgMzU1MzgsIDM1NTQ4LCAzNTU1OCwgMzU1NjksIDM1NTgyLCAzNTU5OCwgMzU2MDksIDM1NjI0LCAzNTYzNSwgMzU2NDksIDM1NjYyLCAzNTY3MiwgMzU2ODYsCiszNTY5NiwgMzU3MDksIDM1NzIyLCAzNTczNCwgMzU4OTUsIDM1OTA1LCAzNTkxNiwgMzU5MzAsIDM1OTQ2LCAzNTk2MSwgMzU5NzgsIDM1OTk3LCAzNjAwNywgMzYwMTksIDM2MDI5LCAzNjAzOSwKKzM2MDQ5LCAzNjA2MCwgMzYwNzAsIDM2MDg0LCAzNjEwMCwgMzYxMTUsIDM2MTk2LCAzNjIwOCwgMzYyMjksIDM2MjQ5LCAzNjI1OSwgMzYyNzUsIDM2Mjg2LCAzNjI5OSwgMzYzMTUsIDM2MzI4LAorMzYzMzksIDM2MzYyLCAzNjM4MiwgMzYzOTQsIDM2NDA1LCAzNjQxOCwgMzY0NDEsIDM2NDY4LCAzNjQ4MSwgMzY0OTMsIDM2NTIyLCAzNjU0NCwgMzY1NTQsIDM2NTc1LCAzNjU4NywgMzY2MDAsCiszNjYxMSwgMzY2MjYsIDM2NjM2LCAzNjY0NiwgMzY2NTksIDM2NjcwLCAzNjY4MSwgMzY3MDEsIDM2NzYzLCAzNjc3NCwgMzY3ODQsIDM2ODAyLCAzNjgxNCwgMzY4MzgsIDM2ODQ4LCAzNjg2MSwKKzM2ODcyLCAzNjg4NCwgMzY4OTQsIDM2OTEwLCAzNjkyMCwgMzY5MzAsIDM2OTQxLCAzNjk1MywgMzY5NjMsIDM2OTczLCAzNjk4MywgMzY5OTMsIDM3MDA3LCAzNzAxNywgMzcwMjcsIDM3MDM5LAorMzcwNTcsIDM3MDg2LCAzNzA5NiwgMzcxMDksIDM3MTIyLCAzNzEzOCwgMzcxNTksIDM3MTcwLCAzNzE5MywgMzcyMTgsIDM3MjI4LCAzNzIzOSwgMzcyNTUsIDM3MjY2LCAzNzI3NiwgMzcyOTEsCiszNzMwMSwgMzczMTIsIDM3MzIzLCAzNzMzNSwgMzczNDcsIDM3MzY1LCAzNzM4OSwgMzczOTksIDM3NDI4LCAzNzQzOSwgMzc0NDksIDM3NDYzLCAzNzQ3NCwgMzc1MDQsIDM3NTIxLCAzNzUzMiwKKzM3NTU1LCAzNzU4MCwgMzc2MDQsIDM3NjI0LCAzNzYzNiwgMzc2NDgsIDM3NjU4LCAzNzY2OCwgMzc2NzgsIDM3NzA0LCAzNzcxNiwgMzc3NDIsIDM3NzU2LCAzNzc3MiwgMzc3ODIsIDM3Nzk1LAorMzc4MDUsIDM3ODI3LCAzNzg0MSwgMzc4NTQsIDM3ODc4LCAzNzg5MiwgMzc5MTIsIDM3OTI1LCAzNzk0MSwgMzc5NTYsIDM3OTY5LCAzNzk3OSwgMzgwMTMsIDM4MjYzLCAzODI3NSwgMzgyODcsCiszODMwNywgMzgzMTcsIDM4MzMxLCAzODM0MywgMzgzNTYsIDM4MzY5LCAzODQyOCwgMzg0NDIsIDM4NDU5LCAzODQ3NSwgMzg0OTEsIDM4NTA2LCAzODUxNywgMzg1MzMsIDM4NTQ4LCAzODU2MywKKzM4NTc3LCAzODU4NywgMzg1OTcsIDM4NjEzLCAzODYyNiwgMzg2MzksIDM4NjQ5LCAzODY2MiwgMzg2NzMsIDM4Njg0LCAzODY5NSwgMzg3MDYsIDM4NzE3LCAzODcyOCwgMzg3NDIsIDM4NzUzLAorMzg3NjUsIDM4Nzc1LCAzODc5NSwgMzg4MTYsIDM4ODI3LCAzODg1NCwgMzg4NjcsIDM4ODk5LCAzODkxMSwgMzg5MjIsIDM4OTM1LCAzODk1NywgMzg5NjgsIDM4OTgyLCAzODk5NiwgMzkwMDYsCiszOTAxOSwgMzkwODAsIDM5MTA4LCAzOTEzMSwgMzkxNDksIDM5MTY0LCAzOTE3NywgMzkxODcsIDM5MTk4LCAzOTIwOCwgMzkyMzcsIDM5MjQ5LCAzOTMxOCwgMzkzMzMsIDM5MzQ1LCAzOTM2MSwKKzM5Mzc2LCAzOTM4OSwgMzk0MDUsIDM5NDIzLCAzOTQzOCwgMzk0NDksIDM5NDY3LCAzOTQ3OCwgMzk0ODgsIDM5NTAxLCAzOTUxMSwgMzk1MjIsIDM5NTkyLCAzOTYwOCwgMzk2MzUsIDM5NjUzLAorMzk3MDYsIDM5NzE5LCAzOTcyOSwgMzk3NDAsIDM5NzU5LCAzOTc3MCwgMzk3OTEsIDM5ODIyLCAzOTgzOSwgMzk4NTEsIDM5ODgxLCAzOTg5NCwgMzk5MDgsIDM5OTQ5LCAzOTk3MywgMzk5ODYsCis0MDAwNywgNDAwMjMsIDQwMTY1LCA0MDE3OSwgNDAyMDEsIDQwMjE5LCA0MDIzMCwgNDAyNTEsIDQwMjczLCA0MDI4NSwgNDAzMDAsIDQwMzYxLCA0MDM3MiwgNDAzODgsIDQwNDA3LCA0MDQzNCwKKzQwNDc0LCA0MDU2NSwgNDA1NzUsIDQwNTk0LCA0MDYwNSwgNDA2MjgsIDQwNjM4LCA0MDY1MywgNDA2NjQsIDQwNjgwLCA0MDY5MiwgNDA3MTEsIDQwNzIzLCA0MDczNiwgNDA3NjMsIDQwNzc4LAorNDA3OTksIDQwODEwLCA0MDgyMywgNDA4NDUsIDQwODYwLCA0NDAzMiwgNDQwNDIsIDQ0MDUyLCA0NDA2NCwgNDQwNzYsIDQ0MDg4LCA0NDEwNywgNDQxMjAsIDQ0MTQ0LCA0NDE1NCwgNDQxNjQsCis0NDE3NiwgNDQxODgsIDQ0MjAwLCA0NDIxNiwgNDQyMjgsIDQ0MjQ1LCA0NDI1NiwgNDQyNjYsIDQ0Mjc3LCA0NDI4OCwgNDQzMDAsIDQ0MzEyLCA0NDMyOSwgNDQzNDAsIDQ0MzU2LCA0NDM2OCwKKzQ0Mzg1LCA0NDM5NiwgNDQ0MDYsIDQ0NDE3LCA0NDQyOCwgNDQ0NDQsIDQ0NDcxLCA0NDQ4MSwgNDQ0OTYsIDQ0NTA4LCA0NDUzNiwgNDQ1NTIsIDQ0NTY0LCA0NDU5MiwgNDQ2MDIsIDQ0NjEzLAorNDQ2MjQsIDQ0NjM2LCA0NDY0OCwgNDQ2NjQsIDQ0Njc2LCA0NDczMiwgNDQ3NDgsIDQ0NzYwLCA0NDc3NiwgNDQ3ODgsIDQ0ODA3LCA0NDg0NCwgNDQ4NjAsIDQ0ODcyLCA0NDg5MiwgNDQ5MjEsCis0NDkzMiwgNDQ5NDQsIDQ0OTU2LCA0NDk4NCwgNDQ5OTksIDQ1MDEyLCA0NTAzMiwgNDUwNDQsIDQ1MDU2LCA0NTA2OCwgNDUwODQsIDQ1MDk2LCA0NTEyNCwgNDUxMzQsIDQ1MTQ1LCA0NTE4MCwKKzQ1MTk2LCA0NTIwOCwgNDUyMTgsIDQ1MjI4LCA0NTI0MCwgNDUyNTIsIDQ1MjY0LCA0NTI4MCwgNDUzMjAsIDQ1MzMwLCA0NTM0MCwgNDUzNTIsIDQ1MzY0LCA0NTM3NiwgNDUzOTIsIDQ1NDA0LAorNDU0MzIsIDQ1NDQyLCA0NTQ1MywgNDU0NjQsIDQ1NDgwLCA0NTUxNiwgNDU1MzIsIDQ1NTQ0LCA0NTU2MSwgNDU1NzIsIDQ1NTg4LCA0NTYwMCwgNDU2MjAsIDQ1NjU2LCA0NTY3MiwgNDU2ODQsCis0NTcwMCwgNDU3MTIsIDQ1NzIyLCA0NTczMywgNDU3NDQsIDQ1NzY4LCA0NTc3OCwgNDU3ODksIDQ1ODAwLCA0NTgxMSwgNDU4MjMsIDQ1ODQwLCA0NTg1MiwgNDU5MDgsIDQ1OTE4LCA0NTkyOSwKKzQ1OTQwLCA0NTk1MiwgNDU5NjQsIDQ1OTg0LCA0NTk5NiwgNDYwMjAsIDQ2MDMwLCA0NjA0MSwgNDYwNTIsIDQ2MDc2LCA0NjA5NiwgNDYxMDgsIDQ2MTIwLCA0NjEzMiwgNDYxNjAsIDQ2MTc2LAorNDYxODgsIDQ2MjA4LCA0NjIzNywgNDYyNDgsIDQ2MjYxLCA0NjI3MiwgNDYyODgsIDQ2MzAwLCA0NjMxMCwgNDYzMjEsIDQ2MzU2LCA0NjM3MiwgNDYzODQsIDQ2NDAwLCA0NjQxMSwgNDY0MjgsCis0NjQ5NiwgNDY1MDYsIDQ2NTE2LCA0NjUyOCwgNDY1NDAsIDQ2NTUyLCA0NjU3MiwgNDY2MDgsIDQ2NjI5LCA0NjY0NCwgNDY2NjQsIDQ2NjkyLCA0Njc0OCwgNDY3NjMsIDQ2ODA0LCA0NjgzMiwKKzQ2ODQ4LCA0Njg4OCwgNDY5MDQsIDQ2OTE2LCA0NjkzMiwgNDY5NDQsIDQ2OTYwLCA0Njk3MiwgNDY5ODgsIDQ2OTk4LCA0NzAwOCwgNDcwMTksIDQ3MDI5LCA0NzA0NywgNDcwODQsIDQ3MTAwLAorNDcxMTEsIDQ3MTI4LCA0NzE0MCwgNDcxNTYsIDQ3MTY4LCA0NzE4NSwgNDcxOTYsIDQ3MjEyLCA0NzIyNCwgNDcyNDUsIDQ3MjcyLCA0NzI4NCwgNDcyOTYsIDQ3MzA4LCA0NzMyNSwgNDczMzYsCis0NzM1MiwgNDczNjQsIDQ3Mzg0LCA0NzQyMCwgNDc0MzYsIDQ3NDQ4LCA0NzQ2NCwgNDc0NzYsIDQ3NDkyLCA0NzUwMiwgNDc1MzIsIDQ3NTQ4LCA0NzU2MCwgNDc1NzAsIDQ3NTgxLCA0NzU5MiwKKzQ3NjA0LCA0NzYxNiwgNDc2MzcsIDQ3NjcyLCA0NzY4MiwgNDc2OTMsIDQ3NzA0LCA0NzcxNiwgNDc3MjgsIDQ3NzQ3LCA0Nzc4NCwgNDc3OTQsIDQ3ODA1LCA0NzgxNiwgNDc4MzIsIDQ3ODY4LAorNDc4ODUsIDQ3ODk2LCA0NzkxMywgNDc5MjQsIDQ3OTM0LCA0Nzk0NSwgNDc5NTYsIDQ3OTY5LCA0Nzk4MCwgNDgwMDgsIDQ4MDM2LCA0ODA1MiwgNDgwNjQsIDQ4MDgwLCA0ODEyMCwgNDgxMzAsCis0ODE0MCwgNDgxNTAsIDQ4MTY0LCA0ODE3NiwgNDgxOTIsIDQ4MjA0LCA0ODIyMSwgNDgyNjAsIDQ4MjcwLCA0ODI4MSwgNDgyOTIsIDQ4MzA0LCA0ODMxNiwgNDgzMzMsIDQ4MzQ0LCA0ODM3MiwKKzQ4Mzg4LCA0ODQwMCwgNDg0MjAsIDQ4NDQ4LCA0ODQ2MCwgNDg0NzIsIDQ4NDg0LCA0ODUxMiwgNDg1MjIsIDQ4NTMzLCA0ODU0OCwgNDg1NjAsIDQ4NTk2LCA0ODYxNywgNDg2MjgsIDQ4NjQwLAorNDg2NTIsIDQ4NjY4LCA0ODcwOCwgNDg3MTgsIDQ4NzI5LCA0ODc0MCwgNDg3NTIsIDQ4NzYzLCA0ODc4MCwgNDg3OTIsIDQ4ODA4LCA0ODg0OCwgNDg4NjQsIDQ4ODc2LCA0ODg5NywgNDg5MjAsCis0ODk2MCwgNDg5NzYsIDQ5MDQ0LCA0OTA3MiwgNDkwOTMsIDQ5MTA0LCA0OTExNiwgNDkyMTIsIDQ5MjMzLCA0OTI0NCwgNDkyNTYsIDQ5Mjk2LCA0OTMxMiwgNDkzMjQsIDQ5MzM0LCA0OTM0NCwKKzQ5MzU2LCA0OTM2OCwgNDkzODAsIDQ5Mzk2LCA0OTQwOCwgNDk0MjQsIDQ5NDM2LCA0OTQ0NiwgNDk0NTYsIDQ5NDY4LCA0OTQ4MCwgNDk0OTIsIDQ5NTA4LCA0OTUyMCwgNDk1NDEsIDQ5NTUyLAorNDk1NjQsIDQ5NTc2LCA0OTU5NywgNDk2MDgsIDQ5NjIwLCA0OTYzMiwgNDk2NDgsIDQ5NjYwLCA0OTY3NiwgNDk2ODgsIDQ5NzA0LCA0OTcxNCwgNDk3MzYsIDQ5NzQ4LCA0OTc2MCwgNDk3NzIsCis0OTc4OCwgNDk4MDAsIDQ5ODE2LCA0OTgyOCwgNDk4NDQsIDQ5ODg0LCA0OTg5OSwgNDk5MTAsIDQ5OTIwLCA0OTkzMiwgNDk5NDQsIDQ5OTU2LCA0OTk4OSwgNTAwMjQsIDUwMDM0LCA1MDA0NCwKKzUwMDU2LCA1MDExMiwgNTAxMzYsIDUwMTQ2LCA1MDE1NywgNTAxNjgsIDUwMTg0LCA1MDIxMiwgNTAyMjQsIDUwMjM2LCA1MDI0OCwgNTAyNzYsIDUwMjkyLCA1MDMwNCwgNTAzMjQsIDUwMzYwLAorNTA0MDksIDUwNDIwLCA1MDQzMSwgNTA0NDQsIDUwNDYwLCA1MDQ3MiwgNTA0ODgsIDUwNTAwLCA1MDUxMCwgNTA1MjAsIDUwNTMyLCA1MDU0NCwgNTA1NTYsIDUwNTY3LCA1MDU3NywgNTA1ODgsCis1MDYwMSwgNTA2MTIsIDUwNjIyLCA1MDYzMiwgNTA2NDQsIDUwNjU2LCA1MDY2OCwgNTA2NzgsIDUwNjg4LCA1MDcwMCwgNTA3MTIsIDUwNzI0LCA1MDczNCwgNTA3NDUsIDUwNzU2LCA1MDc2OCwKKzUwNzgwLCA1MDc5NiwgNTA4MDgsIDUwODI0LCA1MDgzNiwgNTA4NTIsIDUwODY0LCA1MDg3NCwgNTA4ODUsIDUwODk2LCA1MDkwOCwgNTA5MjAsIDUwOTM2LCA1MDk0OCwgNTA5NjQsIDUwOTc2LAorNTA5OTIsIDUxMDA0LCA1MTAxOCwgNTEwMjgsIDUxMDQwLCA1MTA1MSwgNTEwNjEsIDUxMDc1LCA1MTA4NiwgNTEwOTYsIDUxMTA3LCA1MTExNywgNTExMzIsIDUxMTQ0LCA1MTE2MCwgNTExNzIsCis1MTIwMCwgNTEyMTAsIDUxMjIxLCA1MTIzMiwgNTEyNDQsIDUxMjU2LCA1MTI3MiwgNTEyODQsIDUxMzEyLCA1MTMyMiwgNTEzMzMsIDUxMzQ4LCA1MTM1OSwgNTEzODgsIDUxNDAwLCA1MTQxMiwKKzUxNDI0LCA1MTQ0NSwgNTE0NTYsIDUxNDY4LCA1MTQ4MCwgNTE1MDAsIDUxNTM2LCA1MTU1MiwgNTE1NjQsIDUxNTgwLCA1MTU5MiwgNTE2MDgsIDUxNjQ4LCA1MTY1OCwgNTE2NjksIDUxNjgwLAorNTE2OTIsIDUxNzA0LCA1MTcyMCwgNTE3MzIsIDUxNzUzLCA1MTc4OCwgNTE4MDQsIDUxODE2LCA1MTgzNywgNTE4NjQsIDUxOTAwLCA1MTkxNiwgNTE5MjgsIDUxOTQ4LCA1MTk3NiwgNTE5ODgsCis1MjAwMCwgNTIwMzMsIDUyMDQ0LCA1MjA1NiwgNTIwNjgsIDUyMDg4LCA1MjEyNCwgNTIxNTIsIDUyMTgwLCA1MjE5NiwgNTIyMzYsIDUyMjUyLCA1MjI2MywgNTIyODAsIDUyMjkyLCA1MjMwOCwKKzUyMzIwLCA1MjMzNiwgNTIzNzYsIDUyMzkyLCA1MjQwNCwgNTI0MjAsIDUyNDMyLCA1MjQ1MiwgNTI0NjQsIDUyNDgxLCA1MjQ5MiwgNTI1MDQsIDUyNTE2LCA1MjUzNywgNTI1NzIsIDUyNTg4LAorNTI2MDAsIDUyNjE2LCA1MjYyOCwgNTI2NDQsIDUyNjU2LCA1MjY3NiwgNTI2ODgsIDUyNzEyLCA1MjcyOCwgNTI3NDAsIDUyNzU2LCA1Mjc2OCwgNTI3ODQsIDUyODI0LCA1Mjg0MCwgNTI4NTIsCis1Mjg2OCwgNTI4ODAsIDUyODk2LCA1MjkwOCwgNTI5MjksIDUyOTY0LCA1Mjk4MCwgNTI5OTIsIDUzMDA4LCA1MzAyMCwgNTMwMzYsIDUzMDQ4LCA1MzA3NiwgNTMwOTIsIDUzMTA0LCA1MzEyMCwKKzUzMTMyLCA1MzE1MywgNTMxNjgsIDUzMTg4LCA1MzIxNiwgNTMyMzIsIDUzMjQ0LCA1MzI2NSwgNTMyOTMsIDUzMzA0LCA1MzMxNiwgNTMzMjgsIDUzMzQ0LCA1MzM1NiwgNTMzNzIsIDUzNDEyLAorNTM0MjgsIDUzNDQwLCA1MzQ1NiwgNTM0NjgsIDUzNDg0LCA1MzQ5NiwgNTM1MTcsIDUzNTUyLCA1MzU2MiwgNTM1NzIsIDUzNTg0LCA1MzU5NiwgNTM2MDgsIDUzNjI4LCA1MzY0MCwgNTM2NjQsCis1MzY4MCwgNTM2OTAsIDUzNzIwLCA1Mzc0OCwgNTM3NjcsIDUzODA0LCA1MzgyMCwgNTM4MzIsIDUzODUyLCA1Mzg4OCwgNTM5MDQsIDUzOTE2LCA1MzkzMiwgNTM5NDQsIDUzOTU0LCA1Mzk3MiwKKzUzOTg4LCA1NDAwMCwgNTQwMTYsIDU0MDI4LCA1NDAzOCwgNTQwNDgsIDU0MDYwLCA1NDA3MiwgNTQwODQsIDU0MTQwLCA1NDE1NiwgNTQxNjgsIDU0MTg0LCA1NDE5NiwgNTQyMTIsIDU0MjI0LAorNTQyNDEsIDU0MjUyLCA1NDI2OCwgNTQyODAsIDU0MzAxLCA1NDMzNiwgNTQzNjQsIDU0MzgxLCA1NDM5MiwgNTQ0MDIsIDU0NDEzLCA1NDQ0MSwgNTQ0NzYsIDU0NDkyLCA1NDUwNCwgNTQ1MjAsCis1NDUzMiwgNTQ1NDgsIDU0NTg4LCA1NDYwNCwgNTQ2MTYsIDU0NjI5LCA1NDY0NCwgNTQ2NjAsIDU0NjcyLCA1NDY5MywgNTQ3MjgsIDU0NzM4LCA1NDc0OSwgNTQ3NjAsIDU0NzcyLCA1NDc4NCwKKzU0ODAwLCA1NDgxMiwgNTQ4MjksIDU0ODQwLCA1NDg1MywgNTQ4NjUsIDU0ODc2LCA1NDg4NywgNTQ4OTcsIDU0OTE1LCA1NDkyNSwgNTQ5NDEsIDU0OTUyLCA1NDk2OSwgNTQ5ODAsIDU0OTkzLAorNTUwMDgsIDU1MDI0LCA1NTAzNiwgNTUwNTcsIDU1MDY4LCA1NTA4MCwgNTUwOTIsIDU1MTA4LCA1NTEyMCwgNTUxMzYsIDU1MTQ4LCA1NTE2NCwgNTUxNzYsIDU1MTkyLCA2Mzc0NCwgNjM3NTQsCis2Mzc2NCwgNjM3NzQsIDYzNzg0LCA2Mzc5NCwgNjM4MDQsIDYzODE0LCA2MzgyNCwgNjM4MzQsIDYzODQ0LCA2Mzg1NCwgNjM4NjQsIDYzODc0LCA2Mzg4NCwgNjM4OTQsIDYzOTA0LCA2MzkxNCwKKzYzOTI0LCA2MzkzNCwgNjM5NDQsIDYzOTU0LCA2Mzk2NCwgNjM5NzQsIDYzOTg0LCA2Mzk5NCwgNjQwMDQsIDY1MjgxLCA2NTI5MSwgNjUzMDEsIDY1MzExLCA2NTMyMSwgNjUzMzEsIDY1MzQxLAorNjUzNTEsIDY1MzYxLCA2NTM3MSwgNjU1MDQsIDY1NTM2CisgICAgICAgICAgICB9KTsKKworICAgICAgICB0ZXN0Qnl0ZXMgPSB0aGVzZUJ5dGVzKG5ldyBpbnRbXXsKKzAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKzMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCis2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKzgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisxNjIsIDE3NCwgMTYyLCAxODAsIDE2MSwgMjE1LCAxNjEsIDE2NywgMTY4LCAxNjMsIDE2MSwgMTY5LCAxNjEsIDE5OCwgMTYxLCAxOTAsCisxNjksIDI0NywgMTY5LCAyNDgsIDE2MiwgMTY1LCAxNjIsIDIxMCwgMTYxLCAxNjQsIDE2MiwgMTcyLCAxNjksIDI0NiwgMTY4LCAxNzIsCisxNjgsIDI0OSwgMTY4LCAyNDYsIDE2OCwgMjUwLCAxNjIsIDE3NSwgMTY4LCAxNjEsIDE2OCwgMTYyLCAxNjEsIDE5MSwgMTY4LCAxNzAsCisxNjgsIDE3MywgMTY5LCAxNzIsIDE2OSwgMTYxLCAxNjksIDE2MywgMTYxLCAxOTIsIDE2OSwgMTcwLCAxNjksIDE3MywgMTY5LCAxNjIsCisxNjgsIDE2NCwgMTY5LCAxNjUsIDE2OCwgMTY4LCAxNjksIDE3NiwgMTY5LCAxNzEsIDE2OCwgMTc0LCAxNjIsIDE2NywgMTYyLCAxNjgsCisxNjUsIDE5MywgMTY1LCAyMDMsIDE2NSwgMjEyLCAxNjUsIDIyNSwgMTY1LCAyMzUsIDE2NSwgMjQ0LCAxNzIsIDE2NywgMTcyLCAxNjEsCisxNzIsIDE3MiwgMTcyLCAxODIsIDE3MiwgMTkyLCAxNzIsIDIxOCwgMTcyLCAyMjgsIDE3MiwgMjM4LCAxNjEsIDE3MCwgMTYyLCAyMTEsCisxNjIsIDE4MiwgMTYxLCAyMTYsIDE2OSwgMjQ5LCAxNjksIDI1MCwgMTYxLCAyMDEsIDE2NywgMTY0LCAxNjIsIDIyOSwgMTYxLCAyMDIsCisxNjgsIDI0NywgMTY4LCAyNTMsIDE2NSwgMTgzLCAxNjUsIDE2MiwgMTYxLCAyMzEsIDE2MiwgMTYxLCAxNjIsIDE2MywgMTYxLCAyNDUsCisxNjEsIDIzOCwgMTYxLCAxNzEsIDE2MSwgMTk3LCAxNjEsIDIxNCwgMTYxLCAxOTMsIDE2MSwgMjM2LCAxNjEsIDI0OCwgMTYyLCAxOTMsCisxNjEsIDIwOSwgMTYxLCAyMTAsIDE2OCwgMjMxLCAxNjgsIDI0MSwgMTY5LCAyMzEsIDE2OSwgMjQxLCAxNjksIDIwNSwgMTY5LCAyMTUsCisxNjksIDIyNSwgMTY4LCAyMDUsIDE2OCwgMjE1LCAxNjgsIDIyNSwgMTY2LCAxNjEsIDE2NiwgMTYzLCAxNjYsIDE5NywgMTY2LCAxODMsCisxNjYsIDIwOCwgMTY2LCAxNzAsIDE2NiwgMjE4LCAxNjYsIDIyNiwgMTYyLCAxOTgsIDE2MSwgMjI1LCAxNjEsIDIyNywgMTYxLCAyMjksCisxNjEsIDIyMywgMTYyLCAxOTYsIDE2MSwgMjE4LCAxNjIsIDIwNiwgMTYyLCAyMDgsIDE2MSwgMjA3LCAxNjIsIDE4OCwgMTYyLCAyMjAsCisxNjEsIDE2MSwgMTYxLCAxODIsIDE2MSwgMTc4LCAxNzAsIDE2MSwgMTcwLCAxNzEsIDE3MCwgMTgxLCAxNzAsIDE5MSwgMTcwLCAyMDEsCisxNzAsIDIxMSwgMTcwLCAyMjEsIDE3MCwgMjMxLCAxNzAsIDI0MSwgMTcxLCAxNjEsIDE3MSwgMTcxLCAxNzEsIDE4MSwgMTcxLCAxOTEsCisxNzEsIDIwMSwgMTcxLCAyMTEsIDE3MSwgMjIxLCAxNzEsIDIzMSwgMTcxLCAyNDEsIDE2NCwgMTYxLCAxNjQsIDE3MSwgMTY0LCAxODEsCisxNjQsIDE5MSwgMTY0LCAyMDEsIDE2NCwgMjExLCAxNjQsIDIyMSwgMTY0LCAyMzEsIDE2NCwgMjQxLCAxNjQsIDI1MSwgMTY5LCAxNzcsCisxNjksIDE4NywgMTY5LCAxOTcsIDE2OCwgMTc3LCAxNjgsIDE4NywgMTY4LCAxOTcsIDE2MiwgMjIyLCAxNjcsIDIwMSwgMTY3LCAyMjAsCisxNjcsIDIxNiwgMTY3LCAxNzYsIDE2NywgMTkwLCAxNjcsIDE5MywgMTY3LCAyMDgsIDE2NywgMjM5LCAxNjcsIDIzNCwgMTY3LCAyMjgsCisyMzYsIDIzMywgMjIzLCAxOTAsIDI0MywgMTY2LCAyMjcsIDE3MCwgMjQxLCAyMzMsIDI1MiwgMTc1LCAyMzEsIDIwOSwgMjIyLCAxOTEsCisyMjcsIDE3MSwgMjAyLCAyMjUsIDIyMCwgMjI3LCAyMTMsIDE3NSwgMjM2LCAxNjMsIDIwOCwgMjMwLCAyNDksIDI0MSwgMjA0LCAyMDAsCisyMTEsIDE2MiwgMjI4LCAxNjcsIDIwOCwgMjA5LCAyMzcsIDE2OCwgMjQ0LCAxODEsIDIyOCwgMjMwLCAyMzYsIDI0MiwgMjQ5LCAyNDIsCisyMTksIDIxNSwgMjIyLCAxOTUsIDIxMSwgMTYzLCAyNDEsIDE2NSwgMjM2LCAyMzQsIDI0OCwgMTY1LCAyMDIsIDE2MiwgMjM2LCAyMzUsCisyNDYsIDE4MiwgMjE1LCAxOTQsIDIxNywgMTc4LCAyNDgsIDE4MSwgMjMxLCAyMzUsIDIwNCwgMjAxLCAyMjAsIDE5MywgMjI1LCAyNDMsCisyMjAsIDIyOCwgMjIwLCAxNzcsIDIxOSwgMTk1LCAyNTMsIDE2NiwgMjE5LCAxNjcsIDIzMiwgMjIyLCAyMjksIDE2NiwgMjAyLCAxNjMsCisyNTAsIDE2NSwgMjAzLCAyMzcsIDI0NiwgMTc2LCAyMDYsIDIxMSwgMjE5LCAxNjgsIDIyMywgMTYxLCAyNDUsIDIwMiwgMjIzLCAxOTEsCisyMDgsIDE5MywgMjIzLCAxOTIsIDIxNCwgMjQ2LCAyMzIsIDIzMywgMjAyLCAxNjQsIDIyOSwgMjI2LCAyMzQsIDIyNywgMjIzLCAxOTMsCisyMzMsIDIwOCwgMjEzLCAyMjcsIDIzNSwgMTk1LCAyMDgsIDE4NiwgMjEyLCAyMjMsIDIxMCwgMTc0LCAyMDUsIDIzNiwgMjA0LCAxOTQsCisyMjksIDI0NywgMjE3LCAxNzksIDIwNiwgMTc0LCAyMTYsIDI0MSwgMjI5LCAxNjcsIDI0NCwgMTYyLCAyMTUsIDIwNywgMjUyLCAxOTcsCisyNDUsIDI0MywgMjIxLCAxOTQsIDI1MCwgMjUzLCAyNDQsIDI0OCwgMjE1LCAyMTUsIDI0MCwgMTY0LCAyNDQsIDIzOSwgMjM4LCAyNDEsCisyMDMsIDE2NywgMjM3LCAxNjUsIDI0MywgMjIwLCAyNDQsIDI0OSwgMjE1LCAxNzcsIDIxMywgMjQ0LCAyNDAsIDE5MCwgMjUwLCAxODIsCisyMTYsIDI0NSwgMjEyLCAyMDksIDIxNywgMTgwLCAyNTMsIDE3OSwgMjA2LCAyNTQsIDI1MywgMjE0LCAyMjEsIDIyNiwgMjM3LCAyMjEsCisyMjEsIDIyNywgMjQ5LCAxNzUsIDI0NCwgMTgyLCAyMTYsIDE3OSwgMjA5LCAyNDUsIDIwNiwgMjA3LCAyMzYsIDIxMiwgMjQxLCAyMzcsCisyMjgsIDIzNywgMjM0LCAxNzEsIDIzMCwgMjQ0LCAyMDMsIDIxOSwgMjMzLCAyMDksIDIyNiwgMjEwLCAyMzEsIDIxMywgMjA4LCAxNjMsCisyMjIsIDIwMSwgMjUzLCAyMjIsIDIxNywgMTYzLCAyMDcsIDIxNCwgMjIwLCAyNTAsIDIzMSwgMjM5LCAyMzEsIDIzOCwgMjM5LCAyMDgsCisyNDEsIDE3OCwgMjE4LCAxNzEsIDIxNywgMTY0LCAyNTEsIDI1MCwgMjQ2LCAyMjcsIDI1MCwgMTY2LCAyMzYsIDIxNCwgMjQ5LCAyMzUsCisyMzQsIDE3MiwgMjA1LCAyMTQsIDI0OCwgMjEyLCAyNDgsIDE2NiwgMjE1LCAyMTgsIDIxNiwgMTk3LCAyMzQsIDIzMCwgMjQ2LCAyMjgsCisyMTcsIDI1MywgMjI4LCAxNzUsIDI0MCwgMTY2LCAyNDQsIDIwMiwgMjQ0LCAxODMsIDI1MywgMTg5LCAyNTMsIDE3MSwgMjQyLCAxOTksCisyNDMsIDE3MCwgMjI1LCAyNDUsIDIwMiwgMTY5LCAyMDcsIDE2NSwgMjI1LCAxNzYsIDI1MCwgMTk4LCAyMDgsIDIzOSwgMjIxLCAxOTYsCisyNTIsIDI0NywgMjMwLCAxOTEsIDIyOSwgMjQxLCAyMTAsIDE2NSwgMjI1LCAyNDYsIDIwNSwgMjIxLCAyMDUsIDE3OSwgMjI5LCAyMTYsCisyMzQsIDE3NCwgMjQ3LCAyMDcsIDIwOCwgMTY0LCAyMDgsIDI0MCwgMjA4LCAxNzksIDIwMywgMjEzLCAyNDcsIDIzMSwgMjExLCAyMjEsCisyNDYsIDI0MywgMjExLCAyMjAsIDI1MCwgMTY3LCAyMzUsIDIxNywgMjI4LCAyMzksIDIyNCwgMjQyLCAyMzAsIDE4MCwgMjQzLCAyNDEsCisyMDgsIDI0MSwgMjA0LCAxNzcsIDI0NCwgMjIwLCAyMDIsIDIzNywgMjM3LCAyMjIsIDIwNiwgMjEyLCAyNDcsIDE3OCwgMjIzLCAyMjEsCisyNDIsIDIwMCwgMjA0LCAyMDksIDIxNywgMjE1LCAyNDEsIDI0MiwgMjE3LCAyNDgsIDIyMSwgMTk3LCAyMDIsIDIwMywgMjUzLCAxODEsCisyMTUsIDE2NCwgMjI5LCAxODksIDIzNywgMjI0LCAyMzYsIDIzNiwgMjQ5LCAxOTAsIDIyNiwgMjEyLCAyMTEsIDIyMiwgMjI3LCAyNDcsCisyNTAsIDI0MSwgMjEwLCAxNzUsIDIyMSwgMTk4LCAyMzgsIDI0NSwgMjQ3LCAxNzIsIDIxMCwgMTkxLCAyMjksIDI1MywgMjA4LCAyNDUsCisyNDYsIDIzMCwgMjE2LCAyMTcsIDIzOSwgMjA5LCAyMzgsIDE4NywgMjMyLCAyMzgsIDIwMiwgMjA1LCAyMzAsIDE5MywgMjMyLCAyMjMsCisyMjIsIDIwNywgMjMxLCAyNDQsIDIyOCwgMTc2LCAyNDYsIDE2NSwgMjE1LCAxNjUsIDI1MSwgMjMwLCAyMjAsIDI1NCwgMjE2LCAyMTgsCisyMjcsIDE4NCwgMjAyLCAxNzAsIDI1MCwgMjM4LCAyMzgsIDIxMywgMjUxLCAyNTEsIDI0OCwgMTk4LCAyMjIsIDE3NCwgMjIzLCAxOTcsCisyMzcsIDE3MywgMjIxLCAxNjEsIDIwNSwgMTgxLCAyMjYsIDIxMywgMjM0LCAyMzIsIDIxMSwgMjM1LCAyMDYsIDIxOSwgMjQxLCAxODEsCisyMjQsIDE5MCwgMjA3LCAyMjQsIDIyNywgMjI4LCAyMzgsIDIxNCwgMjIxLCAxNjMsIDIxMCwgMTg4LCAyMDUsIDI1MSwgMjIyLCAyMDgsCisyNDUsIDE5MywgMjIwLCAyMzAsIDIyNywgMjUyLCAyNDQsIDIxMSwgMjMzLCAyMTQsIDI0NiwgMTY2LCAyMDUsIDE4MiwgMjAzLCAyMjAsCisyMjQsIDIxOCwgMjIwLCAxNzksIDIxNSwgMjE5LCAyMTIsIDIzNCwgMjUzLCAyMjMsIDIwOCwgMjQ3LCAyMDMsIDE3MCwgMjI1LCAyNTEsCisyNTEsIDE5MiwgMjI1LCAyNTIsIDI0NiwgMTg1LCAyMjgsIDE3NywgMjUwLCAyMTQsIDIyNiwgMjUzLCAyMDUsIDIyMywgMjI2LCAyNTQsCisyMTgsIDE3NCwgMjI3LCAxNjEsIDIwNywgMTY5LCAyMTIsIDI0MSwgMjI5LCAyNDUsIDIzMSwgMTc0LCAyMzIsIDIyOCwgMjQ0LCAxODUsCisyMDYsIDIyOSwgMjA4LCAyNDksIDIyNSwgMjIyLCAyNTMsIDI0MSwgMjQ0LCAyMjIsIDIyNSwgMjUzLCAyMzcsIDIyNywgMjE3LCAxODIsCisyMTksIDE3MiwgMjE2LCAxNzMsIDI0NiwgMTg2LCAyMDIsIDIwNiwgMjM0LCAyMzQsIDIyMSwgMjMxLCAyMzgsIDE4OCwgMjIzLCAyMDIsCisyMDUsIDE4MywgMjI4LCAyMjEsIDIyMywgMjAzLCAyMDcsIDE3MCwgMjQxLCAxODMsIDIxMywgMjMwLCAyMzAsIDE5NywgMjIwLCAxNjcsCisyMjcsIDIxMCwgMjM2LCAxNzIsIDI1MCwgMjE1LCAyMjksIDE3NiwgMjQ5LCAxNzYsIDI0NywgMTY1LCAyMTEsIDE2NywgMjUxLCAxNjEsCisyMjIsIDE3NSwgMjE5LCAxNzMsIDIzOSwgMjE0LCAyMTUsIDIwMCwgMjEyLCAyNDAsIDIyOSwgMjE3LCAyMTgsIDE3NiwgMjQ0LCAyMDMsCisyMjcsIDI1MywgMjM2LCAyMTksIDI0MiwgMTY0LCAyNDYsIDIyNSwgMjEwLCAxODMsIDIyMSwgMjAwLCAyMjgsIDIzMiwgMjE0LCAxODcsCisyMjQsIDI0NSwgMjM2LCAyNDYsIDI1MiwgMjAwLCAyMjksIDE5MSwgMjM3LCAxNzYsIDIwNSwgMjQxLCAyMzAsIDIzNywgMjUyLCAyMjYsCisyMzEsIDI0NiwgMjQwLCAyNDUsIDIxMSwgMjUwLCAyMTIsIDE5NSwgMjUxLCAyMjcsIDIyNCwgMTczLCAyNDYsIDIzMSwgMjI0LCAyNDYsCisyMDMsIDI0MCwgMjI4LCAxOTUsIDIwMiwgMjM5LCAyNTIsIDIwMiwgMjI3LCAyMjksIDIzNSwgMjE5LCAyNDgsIDI0NCwgMjQ3LCAyMjgsCisyNTEsIDE4MCwgMjA0LCAyMTIsIDI0NSwgMTk1LCAyNDEsIDI0MywgMjUzLCAyNDMsIDIyMSwgMjAxLCAyMTcsIDIyOCwgMjExLCAxODgsCisyMDIsIDIwOCwgMjA5LCAyMTUsIDI0MywgMTY0LCAyMDcsIDE3MSwgMjExLCAyMTIsIDIyOCwgMTc4LCAyMDgsIDE4OSwgMjM5LCAxODQsCisyMTEsIDIyNywgMjEzLCAyMzIsIDI1MSwgMTk1LCAyNDYsIDIzMiwgMjIxLCAyMDIsIDIyMSwgMjM1LCAyNDQsIDI1MiwgMjI5LCAyMjgsCisyNDgsIDIxNiwgMjQ5LCAxNjksIDIzOCwgMTg5LCAyMjEsIDIxNywgMjE4LCAyMjksIDI0NiwgMjMzLCAyMDYsIDE5MiwgMjA1LCAxODQsCisyNDIsIDE2NSwgMjExLCAyNTEsIDI0MSwgMTY5LCAyMzksIDIxNiwgMjQzLCAxODEsIDI0OCwgMjE4LCAyMjAsIDIzMywgMjA3LCAyMzYsCisyMjMsIDI0MiwgMjExLCAyNTIsIDIyOCwgMjUwLCAyMTMsIDIxMSwgMjQwLCAxOTQsIDIwMiwgMjA5LCAyMTcsIDIxOCwgMjI5LCAxOTIsCisyMDQsIDE2OSwgMjIzLCAxODYsIDIyNSwgMjIzLCAyMTEsIDI1MywgMjQyLCAyMDIsIDIxOCwgMjMwLCAyNTMsIDIwNSwgMjM4LCAyMTUsCisyMTYsIDE2NCwgMjE3LCAxODQsIDIxNCwgMjA2LCAyMjMsIDE3NCwgMjExLCAyMTMsIDIxNywgMjMyLCAyMTEsIDE4MSwgMjQ0LCAxODYsCisyMDgsIDIxMSwgMjExLCAyMjgsIDIzNSwgMjQ0LCAyNDcsIDIzNiwgMjQ3LCAyMDQsIDIyOSwgMTkzLCAyMTMsIDI1MywgMjQyLCAxNjgsCisyMDMsIDE5OSwgMjA1LCAxODYsIDIxOCwgMTk0LCAyNDMsIDIyNiwgMjA0LCAyMTUsIDIyMSwgMTY3LCAyMTQsIDE3NiwgMjIyLCAxNzYsCisyMTIsIDIyNCwgMjI4LCAyMTQsIDIzNywgMTk3LCAyMTEsIDE2OCwgMjE5LCAxNzcsIDIyNCwgMTkzLCAyMDgsIDI1MywgMjA4LCAyNTQsCisyMzMsIDIzOSwgMjMyLCAyMTgsIDIwNSwgMjI0LCAyMjEsIDIwMywgMjIwLCAxODEsIDIzNywgMTk4LCAyMTcsIDIxOSwgMjQwLCAxOTcsCisyNDIsIDIwNCwgMjQxLCAyMTksIDIzMSwgMjUxLCAyMjAsIDE5NywgMjM5LCAyMjEsIDI1MywgMTkwLCAyMzEsIDE3OCwgMjI5LCAxOTUsCisyNDMsIDIyOSwgMjE3LCAxODYsIDIyNCwgMjMxLCAyMzEsIDE2NSwgMjI4LCAyNDIsIDIwNiwgMTk5LCAyMzIsIDIxNiwgMjQwLCAxOTgsCisyMzQsIDE5NywgMjIyLCAyNTMsIDIwOSwgMTYxLCAyMTcsIDIwMiwgMjE4LCAyMTEsIDIwMiwgMjEwLCAyMzgsIDE2NywgMjEyLCAyMjUsCisyNDksIDI0OCwgMjQ3LCAyMzcsIDIyMSwgMjM3LCAyMTIsIDIyNiwgMjQyLCAxNzEsIDIwNSwgMTg5LCAyMjcsIDE5NCwgMjE5LCAyMTgsCisyMzQsIDI0NiwgMjA3LCAxNzUsIDIxNSwgMTc5LCAyMzksIDIyMiwgMjI2LCAyMjcsIDIwNiwgMjMyLCAyMzMsIDI0MSwgMjA4LCAxOTgsCisyMTEsIDI1NCwgMjQyLCAyMzgsIDI0MiwgMjA1LCAyMDIsIDIxMiwgMjA1LCAyMTcsIDI0MCwgMjAxLCAyMzEsIDI1MiwgMjA1LCAyMjUsCisyMDksIDE2NSwgMjIwLCAyMzQsIDIxMiwgMjE0LCAyMjMsIDE4MSwgMjEyLCAxNjEsIDIzNSwgMjQ1LCAyNDUsIDE2MSwgMjE3LCAxNjcsCisyMzAsIDIwMywgMjI5LCAxOTcsIDIyNCwgMjE5LCAyMTUsIDIwOSwgMjM5LCAyMjMsIDIwOCwgMTkxLCAyMzMsIDE5MCwgMjUyLCAyMDYsCisyMTUsIDE4MCwgMjA1LCAxOTAsIDIwNywgMTc2LCAyMDYsIDE3MCwgMjA4LCAxNjcsIDIxOSwgMjI0LCAyMzgsIDE5MiwgMjE3LCAxODgsCisyNDUsIDE2MywgMjAyLCAyNDQsIDIzMywgMjQ4LCAyMDksIDE2NiwgMjUyLCAyNDQsIDIxMSwgMTcwLCAyMjksIDIyOSwgMjE5LCAyNTIsCisyMDMsIDI1NCwgMjIyLCAxNzcsIDIxMiwgMTYyLCAyMTQsIDIwOCwgMjUwLCAyMDMsIDIxMywgMTc3LCAyMTMsIDE3OCwgMjUzLCAyMjYsCisyMzMsIDE3NiwgMjUzLCAyMjcsIDI1MCwgMjA2LCAyMzAsIDE2MiwgMjMyLCAyMjQsIDIxMywgMjQ2LCAyMjgsIDIzNCwgMjI3LCAyMTQsCisyMTQsIDE3NywgMjIzLCAxNzUsIDIzNSwgMjQ2LCAyMTYsIDIyMywgMjE3LCAxOTAsIDI1MSwgMTk4LCAyMzgsIDI1MywgMjE2LCAyMzYsCisyMDksIDE2OCwgMjI2LCAxNjksIDIxOSwgMjQwLCAyMTksIDI0MSwgMjMxLCAyNTMsIDIwNSwgMjMxLCAyMDgsIDIyNywgMjA5LCAxNjksCisyMzAsIDIwNCwgMjE3LCAyMTAsIDIxNiwgMjAwLCAyMjEsIDI0MywgMjUxLCAxNjIsIDI0OSwgMTc4LCAyMjIsIDIyMywgMjQ4LCAyMjAsCisyNTAsIDIxOCwgMjI5LCAxOTksIDIyNSwgMTY5LCAyNDIsIDIwOCwgMjQxLCAxODksIDI1MywgMjMxLCAyMzksIDE4NiwgMjMyLCAyMDMsCisyMjEsIDE2OSwgMjQ2LCAyMTcsIDIzMCwgMjM4LCAyMjUsIDIxNSwgMjI4LCAyNDMsIDIzOSwgMjI3LCAyMTUsIDI1MCwgMjEyLCAxNjMsCisyMzksIDIyOCwgMjI2LCAyMzIsIDIyMywgMTgyLCAyMTIsIDE2NCwgMjI0LCAyMjIsIDIzMSwgMTgzLCAyMTksIDIwMywgMjExLCAxNzIsCisyMjMsIDIwNywgMjMzLCAxOTIsIDIzNCwgMTg0LCAyMzQsIDE4NSwgMjE1LCAxODIsIDIwNSwgMTYyLCAyMzMsIDE5MywgMjE5LCAxODEsCisyNDQsIDE3NSwgMjQ0LCAyNDIsIDIwNSwgMjI3LCAyMTUsIDE2OSwgMjE2LCAxNzQsIDIxNiwgMTg4LCAyMzksIDE5NCwgMjE4LCAyNTQsCisyMzcsIDIxNCwgMjExLCAxOTMsIDIzNywgMjEwLCAyNDMsIDE2NSwgMjQ4LCAxNzcsIDI0OSwgMjEyLCAyNTIsIDIzMiwgMjExLCAxOTQsCisyMTAsIDIxNiwgMjI3LCAxNjUsIDI0MCwgMTczLCAyNTEsIDIwNSwgMjEzLCAyMzUsIDIyMiwgMjI1LCAyMjIsIDE4MSwgMjI1LCAxOTAsCisyMzEsIDE4NywgMjEzLCAxNzksIDIwNiwgMTgwLCAyNDcsIDE2OCwgMjE2LCAxODksIDI1MiwgMjMzLCAyMzcsIDE5OSwgMjQ2LCAxNjcsCisyNTMsIDIyMCwgMjI1LCAxOTEsIDI1MSwgMTY2LCAyMzksIDE5NSwgMjE0LCAxNzMsIDI1MSwgMjQ0LCAyMDQsIDIyMiwgMjIwLCAyMzUsCisyMjksIDIzNCwgMjE5LCAyMDQsIDI0NSwgMTY1LCAyMzAsIDI1MSwgMjUzLCAyMDAsIDIwOSwgMjM4LCAyMTYsIDIyNCwgMjM3LCAxODAsCisyMjQsIDE5NSwgMjMzLCAyNTEsIDIzMywgMTk0LCAyMjYsIDIxNywgMjMyLCAxNjIsIDI1MywgMjQ4LCAyMzAsIDIxNSwgMjE0LCAyNTAsCisyMzEsIDE4OSwgMjQ1LCAxODMsIDI1MywgMTg0LCAyNDgsIDIzOSwgMjE0LCAyMTEsIDIxMywgMTgwLCAyNDAsIDIwOCwgMjM3LCAyMDEsCisyMjMsIDIwOSwgMjQ4LCAxNzEsIDIxMiwgMTg2LCAyMTQsIDIzOSwgMjIzLCAyMjksIDIwNCwgMTc4LCAyMTIsIDE4NywgMjA0LCAxNzksCisyMjMsIDIxMCwgMjI4LCAyMjgsIDIzOCwgMTk1LCAyMjYsIDE3MywgMjE1LCAyMjUsIDIzMSwgMjE3LCAyNDMsIDIzMywgMjMyLCAyMjksCisyMzUsIDE2MiwgMjMyLCAxNzEsIDIzNywgMjM5LCAyMTIsIDE4OCwgMjUyLCAyNDIsIDI1MCwgMjIwLCAyMzksIDIzMywgMjA5LCAxNzIsCisyMzUsIDIwMSwgMjE0LCAxODgsIDIxOCwgMjE0LCAyMjMsIDE2NiwgMjA2LCAyMDMsIDI0MSwgMTkzLCAyMDgsIDE2OCwgMjE3LCAyMzgsCisyMjQsIDE5NiwgMjMyLCAyMDUsIDIzOSwgMTYyLCAyMDksIDE3NCwgMjA4LCAyMTQsIDI1MSwgMjM0LCAyMzQsIDIxMiwgMjQ5LCAxOTQsCisyMjcsIDE2MiwgMjUxLCAxNjksIDIwOCwgMjAwLCAyMTQsIDE2MiwgMjE1LCAyNDMsIDIwOSwgMTc2LCAyNTIsIDE4NywgMjIzLCAyMjIsCisyMDQsIDIyNSwgMjMxLCAxOTQsIDI1MSwgMjEwLCAyMzIsIDE4MywgMjIwLCAxODYsIDI0MSwgMjQ3LCAyNDQsIDIxNCwgMjIzLCAyMzEsCisyMzksIDE2MywgMjM5LCAyMzUsIDIwOCwgMTgwLCAyMzksIDE2NSwgMjQyLCAyMTMsIDIxMywgMjEyLCAyNDEsIDIyNSwgMjAzLCAxNzcsCisyMDMsIDE3OCwgMjM1LCAyNDcsIDIyMywgMTY4LCAyMzAsIDE4NSwgMjM3LCAxODMsIDIwMiwgMTc4LCAyMzYsIDE4MywgMjEyLCAyMjcsCisyMTUsIDIyOSwgMjExLCAxOTUsIDIyMSwgMjQ2LCAyMjksIDIwMywgMjI1LCAxOTYsIDIxNSwgMTg3LCAyMTUsIDE3MCwgMjI4LCAyMjMsCisyMTksIDI1NCwgMjQ2LCAxOTQsIDIyNCwgMjAwLCAyMDUsIDE2NCwgMjM4LCAyMjAsIDIwNiwgMjM1LCAyNDksIDE3MSwgMjQ1LCAyMTIsCisyMjEsIDIwNiwgMjQ5LCAyMzYsIDIxMiwgMTY4LCAyMTQsIDIxMiwgMjE2LCAyMzgsIDIxOCwgMjQwLCAyNDcsIDE3NSwgMjQyLCAyMTYsCisyNTAsIDIyMywgMjA3LCAyMzksIDI1MCwgMjI0LCAyMzksIDIzNiwgMjE3LCAyMDYsIDIxMiwgMTY5LCAyNDIsIDIxNywgMjE2LCAxOTAsCisyMjYsIDIzNSwgMjQ0LCAyMTUsIDI0NSwgMTg0LCAyMjcsIDE5NywgMjExLCAxNzMsIDIyMiwgMjI3LCAyMjEsIDI0NywgMjQyLCAxNzgsCisyNDgsIDIyMywgMjA4LCAxNjksIDIzMCwgMjE4LCAyNDUsIDE2NiwgMjE1LCAxODgsIDIyMSwgMjIxLCAyMzksIDIzNywgMjIxLCAyNDgsCisyMDIsIDIyOSwgMjUyLCAxNzIsIDIxOSwgMTgyLCAyMTgsIDI0MSwgMjE2LCAxNjgsIDIwMiwgMjE2LCAyNDUsIDE2NywgMjQ1LCAxNjgsCisyMTMsIDIzNiwgMjI3LCAxOTgsIDIwOSwgMTgyLCAyNDAsIDIxMSwgMjIyLCAyMzAsIDI0MCwgMTc0LCAyMDksIDE4NCwgMjUyLCAxNjEsCisyMjksIDIyMSwgMjEyLCAxNzAsIDIwOCwgMjE2LCAyMjAsIDE4OCwgMjIxLCAyNDksIDI0MCwgMjEzLCAyNDIsIDI0MSwgMjM2LCAxODUsCisyMjUsIDE3MCwgMjM2LCAyNDksIDI0OSwgMTYyLCAyNDAsIDI1MCwgMjEyLCAxNzEsIDIxNywgMjA3LCAyMjYsIDE4MCwgMjIzLCAyMjYsCisyNTIsIDE3NCwgMjA3LCAxODgsIDIxMiwgMjA1LCAyNDIsIDI0MiwgMjA3LCAyMjMsIDIzMiwgMTkyLCAyMDgsIDE3MCwgMjQzLCAxOTMsCisyMTcsIDIyMywgMjQxLCAyMjYsIDIwMiwgMjMwLCAyNDEsIDIxMSwgMjUxLCAyMzgsIDIyMywgMjMzLCAyMjEsIDE3MiwgMjI1LCAxNzEsCisyNDksIDE4MiwgMjA2LCAyMDQsIDIwOCwgMTgxLCAyMjQsIDI1NCwgMjMyLCAxNjQsIDIwMywgMjA1LCAyMTgsIDIxNiwgMjA2LCAxODMsCisyMzksIDE2OSwgMjM4LCAxOTgsIDIxOSwgMjQ0LCAyMjcsIDIxNywgMjI1LCAxOTgsIDI0MCwgMjM0LCAyNDMsIDE5NCwgMjExLCAxNzUsCisyMzcsIDIxNiwgMjQ0LCAyMTYsIDI0MSwgMTk1LCAyMTQsIDIzNSwgMjE1LCAyMzAsIDIyMSwgMjUxLCAyMTYsIDE2MywgMjI1LCAyMTYsCisyMTMsIDIxOSwgMjI2LCAxODIsIDI1MSwgMjEzLCAyMTEsIDIxNiwgMjAzLCAxNzksIDIwNSwgMTY3LCAyNTEsIDI0NSwgMjEwLCAyMzksCisyMDgsIDIyOCwgMjM3LCAxODUsIDIzOCwgMTk5LCAyNDAsIDI1MSwgMjA0LCAxOTEsIDIwNiwgMjM3LCAyMzUsIDIxNCwgMjIyLCAyMzQsCisyMDcsIDE4OSwgMjM5LCAyNDIsIDI0MCwgMjUyLCAyMjYsIDE4NCwgMjE1LCAxOTgsIDI0NiwgMTk3LCAyMjMsIDI1MywgMjQ0LCAyNDMsCisyMTYsIDI1MSwgMjQ2LCAxOTgsIDI0MiwgMjE5LCAyMzIsIDE3OCwgMjMzLCAxNzgsIDIyMCwgMjM4LCAyMTUsIDE3MiwgMjE5LCAyMjksCisyNDEsIDI0OSwgMjMzLCAxNjQsIDIyNywgMTc3LCAyMzAsIDE4NiwgMjI1LCAyMTcsIDIyNCwgMjMzLCAyMjEsIDE3NCwgMjI5LCAxNjIsCisyNDEsIDE3MCwgMjE2LCAyMjUsIDIxMiwgMjU0LCAyMDUsIDE5NiwgMjI2LCAxODYsIDIyNCwgMjA0LCAyNTMsIDI1MywgMjMzLCAyMjYsCisyMzYsIDIwNSwgMjIzLCAyMTQsIDIzOCwgMjI1LCAyNDgsIDE4NywgMjA2LCAyMzgsIDIwNSwgMTk3LCAyMTAsIDE3NywgMjA5LCAxOTAsCisyNDcsIDE3NiwgMjE0LCAyNTMsIDIyNSwgMTYxLCAyMTQsIDE2NCwgMjQ0LCAyMzMsIDI0MCwgMjIwLCAyNDUsIDE3MSwgMjA1LCAxOTgsCisyMDgsIDIzMywgMjQ4LCAyMDMsIDI0MSwgMTc2LCAyNDcsIDE5NSwgMjE5LCAyMDcsIDIzNSwgMjAyLCAyMDYsIDIwNSwgMjEwLCAyNDYsCisyNTAsIDI0NywgMjMyLCAyMTAsIDIyNiwgMjM4LCAyNDgsIDIyNSwgMjQzLCAyMzYsIDIyOCwgMjUzLCAyMzIsIDIxMSwgMjI1LCAxNjMsCisyMzMsIDE2NiwgMjI0LCAyMDUsIDIwNCwgMTc0LCAyMjEsIDE3NywgMjQ4LCAxNzksIDIyNCwgMjA2LCAyMTEsIDE5NywgMjQwLCAxNzYsCisyMTMsIDE5NiwgMjI3LCAyMzcsIDI0NiwgMTcxLCAyMTEsIDIzMCwgMjA3LCAxOTIsIDIyNCwgMTYyLCAyMjYsIDIzOSwgMjQ5LCAyNTQsCisyNDYsIDIzNiwgMjIxLCAxNzgsIDI0MywgMjM3LCAyMzUsIDI1MCwgMjAyLCAyMjEsIDI0NSwgMTcyLCAyMzMsIDIyNywgMjIxLCAxNzksCisyMDMsIDIwNiwgMjI4LCAxNjUsIDIwOCwgMjAyLCAyMzQsIDE4OSwgMjAyLCAxODAsIDIyOSwgMTgwLCAyMzEsIDIwMCwgMjA1LCAyMDEsCisyMTYsIDIwMSwgMjE3LCAxNzEsIDIzNywgMTg4LCAyNTIsIDIzNywgMjI2LCAyNDAsIDI1MSwgMTcwLCAyMTIsIDIyOSwgMjE1LCAyMzMsCisyMDQsIDIzNiwgMjUwLCAyNDgsIDIxNiwgMjEzLCAyMTQsIDIyNSwgMjA2LCAxNjIsIDIyMCwgMjA0LCAyMjgsIDIyNCwgMjQ1LCAyNTQsCisyNDgsIDE5NSwgMjQ1LCAyMTUsIDIzNSwgMTczLCAyMzEsIDE2OCwgMjM4LCAyMDIsIDI0OCwgMjI3LCAyNTEsIDIxNywgMjA4LCAxNzMsCisyMjYsIDE4OSwgMjIzLCAxNzAsIDI0OCwgMjI4LCAyNDMsIDIzOSwgMjI0LCAxODIsIDIyMiwgMjM4LCAyMjAsIDIzOSwgMjE0LCAyNTQsCisyMTcsIDE2MSwgMjE1LCAxNzMsIDIyNSwgMjAyLCAyNDgsIDIwNCwgMjQ1LCAxNzUsIDIzMywgMjU0LCAyMjYsIDI0MiwgMjI1LCAyMDMsCisyMTgsIDIyMSwgMjM1LCAyNTEsIDIyNCwgMjI0LCAyNDQsIDE5MiwgMjUzLCAxODUsIDI0MCwgMTc3LCAyMzcsIDE5MCwgMjMzLCAyMjgsCisyMTIsIDI0NiwgMjM4LCAyMDMsIDIzMSwgMjIyLCAyMjksIDIzOCwgMjEzLCAxODEsIDIxMywgMTYxLCAyNTEsIDIxOSwgMjUwLCAyMDAsCisyNTMsIDIwOCwgMjUxLCAyNDYsIDIxOCwgMTY1LCAyMDUsIDI0NywgMjIyLCAyMzksIDI1MiwgMjM4LCAyMDYsIDI0MSwgMjQyLCAyNDQsCisyMjgsIDE4MiwgMjMyLCAxNjUsIDI0MiwgMTg3LCAyMDIsIDIzMywgMjM0LCAyMTgsIDI1MSwgMjIxLCAyMTMsIDIwNCwgMjM1LCAyMTUsCisyMTcsIDE3MywgMjExLCAyMTcsIDI0NiwgMjIyLCAyMTgsIDI0NiwgMjI0LCAyMDksIDI1MCwgMTc1LCAyMjcsIDE3OCwgMjEzLCAxOTcsCisyMDUsIDIwNCwgMjE2LCAxOTMsIDI0MSwgMjM1LCAyNTAsIDIyOSwgMjQ1LCAyNTAsIDI0OCwgMjUwLCAyMTAsIDE2NCwgMjA4LCAyMTgsCisyMDIsIDE4MywgMjExLCAxNzgsIDIwNSwgMjI5LCAyNDksIDE3MiwgMjM4LCAxNzQsIDIxNSwgMjM0LCAyMDcsIDIxNywgMjIyLCAxNjUsCisyMjMsIDIxNSwgMjQwLCAxNzgsIDIyMCwgMjIwLCAyNDgsIDIzMCwgMjMzLCAxNzksIDIyNywgMTY4LCAyMDMsIDE4NiwgMjA4LCAyMjAsCisyMTYsIDIwMiwgMjI0LCAxNjQsIDIwNCwgMTg0LCAyMjcsIDIwMiwgMjA0LCAxNzUsIDIwOCwgMjA0LCAyMTMsIDE5NCwgMjAyLCAxOTksCisyNTAsIDE3NiwgMjIzLCAyMTYsIDIyOSwgMjM1LCAyMjcsIDI0MiwgMjUzLCAyMjUsIDIwNCwgMTkzLCAyMjQsIDIyNiwgMjQyLCAyMjQsCisyMjIsIDI0MSwgMjM4LCAyMDQsIDIyNywgMjAzLCAyNTMsIDI1NCwgMjQxLCAyMDIsIDIyNCwgMTY1LCAyMjksIDIyMiwgMjUyLCAyMzksCisyMDYsIDE2NCwgMjM1LCAyNTQsIDIxMSwgMjAwLCAyMTMsIDIyMywgMjQ0LCAyMjcsIDI0NCwgMjQ0LCAyNTMsIDIwMSwgMjA5LCAyMzEsCisyMTgsIDE4NiwgMjA0LCAxOTcsIDIxNywgMjAwLCAyMDcsIDE5NiwgMjUyLCAxNjYsIDI1MywgMjEwLCAyMjcsIDIxOSwgMjA0LCAyMzcsCisyMzYsIDE2MSwgMjMxLCAyMjYsIDIyMCwgMTY4LCAyNDMsIDIxNywgMjA1LCAyMTksIDI1MiwgMTk1LCAyMzIsIDIxMywgMjEyLCAyMDIsCisyNTEsIDIyMywgMjQ4LCAyNTEsIDIxNiwgMjMxLCAyNDgsIDE3NSwgMjIyLCAxODQsIDIzNiwgMTk1LCAyMzYsIDE5NCwgMjM3LCAxOTIsCisyNDIsIDIyNSwgMjIyLCAyNDQsIDIyMSwgMTgzLCAyMTQsIDI0MywgMjQyLCAxOTAsIDIzNywgMjUyLCAyMzgsIDIyOSwgMjQxLCAyMDMsCisyNDUsIDE3NywgMjQwLCAyMjUsIDI0NiwgMTcyLCAyNDAsIDIzNSwgMjQyLCAxOTEsIDIxOSwgMTYyLCAyNDcsIDI0NSwgMjA2LCAxNjUsCisyMTIsIDE3NSwgMjMzLCAyMDEsIDIwMywgMjMwLCAyNDEsIDE2MSwgMjQxLCAxNjIsIDIzNSwgMTc5LCAyNDUsIDIzNiwgMjQ1LCAyMzcsCisyNDAsIDIyNiwgMjI5LCAxODQsIDIxNSwgMjQ1LCAyMDcsIDE5OCwgMjQzLCAxNzksIDIzMCwgMjI3LCAyNDIsIDIyNiwgMjQ1LCAyMzgsCisyMDYsIDI0MiwgMjQ0LCAyMjksIDI0NiwgMjAyLCAyMTQsIDE2NiwgMjQxLCAyMDUsIDIzOSwgMTczLCAyMzksIDE3NCwgMjMwLCAxNzIsCisyMjcsIDI0NCwgMjQ3LCAyNTMsIDI0MiwgMjI3LCAyMzMsIDIzMCwgMjMxLCAyMDIsIDIwMiwgMTg4LCAyMjYsIDI1MSwgMjQ1LCAyMTgsCisyNTEsIDE3MywgMjEyLCAxNzgsIDIxNCwgMTkzLCAyNDQsIDI0NSwgMjM2LCAyMzksIDIyNiwgMTk2LCAyNDgsIDE4OCwgMjMzLCAxNzEsCisyMDQsIDE4NiwgMjQwLCAyMjgsIDI0NCwgMTk1LCAyMTYsIDIyOCwgMjEzLCAxNjQsIDIxNiwgMjE1LCAyMDksIDIyNSwgMjAyLCAyNTEsCisyMzMsIDI0NCwgMjEzLCAyMDUsIDIyMSwgMTg3LCAyMzMsIDIzMiwgMjI4LCAxOTksIDI0NSwgMjE5LCAyMTIsIDI0OCwgMjExLCAxNzksCisyMzUsIDE4MywgMjQ1LCAxNzgsIDIyNiwgMTk4LCAyNTEsIDIyOSwgMjI2LCAyNDUsIDIyNSwgMTY1LCAyNDUsIDIyMSwgMjM2LCAxNjIsCisyMDMsIDIxNywgMjI5LCAyMTIsIDIyNCwgMTgzLCAyMjUsIDI0MiwgMjQwLCAyMjksIDI0MywgMjUxLCAyMTIsIDIzOSwgMjM1LCAyMDUsCisyMTQsIDE5NCwgMjM5LCAxNzUsIDI1MCwgMjMyLCAyMDQsIDE5OCwgMjE5LCAxNjQsIDIzNSwgMjIyLCAyMjQsIDIxMywgMjQ5LCAyMzEsCisyMzEsIDIyOSwgMjM5LCAyNTEsIDIyNCwgMTY3LCAyMDMsIDIzNCwgMjE0LCAyMjYsIDI0NSwgMjIyLCAyMzgsIDE4MiwgMjA5LCAxOTcsCisyMDUsIDIwOSwgMjMxLCAyMDQsIDIyOCwgMjAwLCAyMzUsIDE4NSwgMjQ2LCAyMjEsIDIwNCwgMTk5LCAyMjUsIDI0MCwgMjUxLCAxNzUsCisyNDIsIDIyOSwgMjQwLCAyMzYsIDIzOCwgMjM1LCAyMzMsIDIwMywgMjQzLCAxNjEsIDI1MiwgMjQ1LCAyNDEsIDE2NCwgMjI0LCAyMTQsCisyNDQsIDIwOSwgMjQxLCAyMDksIDIwMiwgMjUyLCAyMDYsIDIwNiwgMjQzLCAyMDAsIDIzNywgMjU0LCAyMjQsIDIzNiwgMjM1LCAyMDYsCisyMDIsIDIwMCwgMjEzLCAyMzksIDIzMSwgMTYyLCAyMjgsIDIyNSwgMjQ5LCAyMzksIDI0NCwgMTk3LCAyMjEsIDE4OSwgMjQ4LCAxNjEsCisyNDAsIDIzMCwgMjE1LCAxNzYsIDI0OCwgMjA2LCAyMTksIDIxNCwgMjE1LCAyMTMsIDIzMywgMjM0LCAyMDQsIDE3NiwgMjE1LCAyNDYsCisyMzUsIDIyMywgMjQ0LCAxODAsIDIyOCwgMTg2LCAyNDAsIDIzMSwgMjE1LCAyMzgsIDIxOCwgMTY3LCAyMTgsIDIyMywgMjM5LCAyNTMsCisyMzksIDE5NywgMjIzLCAyMjAsIDIxNywgMjQ2LCAyMTQsIDIxOCwgMjQwLCAxODQsIDIxNCwgMTk2LCAyMzksIDI1NCwgMjE4LCAxODgsCisyMzYsIDIyOSwgMjM2LCAyMzAsIDI1MSwgMTg1LCAyMDcsIDIxMSwgMjA3LCAyMTIsIDI0NCwgMTk5LCAyNDksIDIxOSwgMjM1LCAyMjksCisyNTAsIDE5NCwgMjMzLCAyNDUsIDI0NywgMjQ2LCAyMTIsIDIzMywgMjA0LCAyNDIsIDIwNiwgMTY4LCAyMjgsIDIxMiwgMjE1LCAxOTAsCisyMzksIDE4MSwgMjQ5LCAxNjYsIDI0OCwgMjUzLCAyMjIsIDE3MSwgMjQ2LCAyMDgsIDIyMiwgMjQ4LCAyNTAsIDE5NSwgMjI4LCAxODcsCisyMzksIDE4MiwgMjA2LCAxODksIDIxNiwgMTk1LCAyMDksIDE5OSwgMjI2LCAyMDcsIDIyMCwgMjI0LCAyNDYsIDIzOCwgMjE4LCAyMjQsCisyNDEsIDIxMCwgMjQ2LCAyMzksIDI1MCwgMTgwLCAyNDEsIDIzMSwgMjA5LCAyMDAsIDI0OCwgMTkwLCAyMDMsIDI0NiwgMjQ1LCAyMjYsCisyMTYsIDIzMywgMjUzLCAxNjQsIDI1MCwgMjA4LCAyMTMsIDI0MCwgMjA1LCAyMzMsIDI1MCwgMTgxLCAyMjYsIDIwOCwgMjMxLCAxNjMsCisyMjYsIDIwOSwgMjE1LCAxNjIsIDIzNCwgMTY2LCAyMDgsIDE2MSwgMjM0LCAyMjQsIDIyOSwgMjI0LCAyMTQsIDIxOSwgMjM5LCAxOTgsCisyMjgsIDIxMywgMjA2LCAyNDcsIDIxNSwgMjM5LCAyNDQsIDIzNywgMjA1LCAyMzAsIDI0NSwgMjI3LCAyNTIsIDE5MSwgMjMyLCAxNjcsCisyMDMsIDE5MCwgMjE1LCAyNDcsIDI0MCwgMjMyLCAyMjAsIDI0MywgMjI4LCAxODgsIDIzNCwgMTk2LCAyMjgsIDIzNiwgMjUxLCAyNDgsCisyMDQsIDE4NywgMjI4LCAxODksIDIyMSwgMjIzLCAyMTcsIDIwOCwgMjQ5LCAyMDUsIDIwNSwgMTc0LCAyMDcsIDIwNiwgMjQ2LCAxNzUsCisyMjksIDE2NCwgMjE0LCAyMjEsIDIxNCwgMjI3LCAyMDksIDIwMywgMjIyLCAyNTAsIDIwNywgMjEzLCAyNTMsIDIwMywgMjI0LCAxNjgsCisyMTcsIDI0OSwgMjExLCAyMTgsIDIxOCwgMTg5LCAyMzIsIDE2OCwgMjA1LCAyMTMsIDIyNCwgMTY5LCAyMjIsIDE3MiwgMjQwLCAxODYsCisyMzgsIDIxMCwgMjQzLCAxODcsIDIyOCwgMjAzLCAyMTUsIDE2MywgMjA3LCAyMDcsIDE3NiwgMTYxLCAxNzYsIDE2NywgMTc2LCAxNzIsCisxNzYsIDE4MSwgMTc2LCAxODMsIDE3NiwgMTg4LCAxNzYsIDE5MiwgMTc2LCAxOTUsIDE3NiwgMTk3LCAxNzYsIDIwMiwgMTc2LCAyMDYsCisxNzYsIDIxMywgMTc2LCAyMTUsIDE3NiwgMjIwLCAxNzYsIDIyNiwgMTc2LCAyMzIsIDE3NiwgMjM1LCAxNzYsIDIzNywgMTc2LCAyNDIsCisxNzYsIDI0OCwgMTc2LCAyNTIsIDE3NywgMTYxLCAxNzcsIDE2NSwgMTc3LCAxNjgsIDE3NywgMTcxLCAxNzcsIDE3NSwgMTc3LCAxNzksCisxNzcsIDE4MiwgMTc3LCAxODQsIDE3NywgMTkwLCAxNzcsIDE5NSwgMTc3LCAxOTksIDE3NywgMjAxLCAxNzcsIDIwNCwgMTc3LCAyMDYsCisxNzcsIDIwOSwgMTc3LCAyMTIsIDE3NywgMjE1LCAxNzcsIDIyMSwgMTc3LCAyMjUsIDE3NywgMjI2LCAxNzcsIDIzMSwgMTc3LCAyMzUsCisxNzcsIDI0MSwgMTc3LCAyNDQsIDE3NywgMjUwLCAxNzcsIDI1NCwgMTc4LCAxNjUsIDE3OCwgMTY4LCAxNzgsIDE3MywgMTc4LCAxNzgsCisxNzgsIDE4MSwgMTc4LCAxODQsIDE3OCwgMTg3LCAxNzgsIDE5MSwgMTc4LCAxOTYsIDE3OCwgMjAyLCAxNzgsIDIwNSwgMTc4LCAyMDksCisxNzgsIDIxMSwgMTc4LCAyMTMsIDE3OCwgMjE2LCAxNzgsIDIxNywgMTc4LCAyMjEsIDE3OCwgMjI3LCAxNzgsIDIyOSwgMTc4LCAyMzMsCisxNzgsIDIzNSwgMTc4LCAyMzgsIDE3OCwgMjQxLCAxNzgsIDI0MywgMTc4LCAyNDQsIDE3OCwgMjQ5LCAxNzgsIDI1NCwgMTc5LCAxNjIsCisxNzksIDE2NiwgMTc5LCAxNzAsIDE3OSwgMTc3LCAxNzksIDE4MSwgMTc5LCAxODksIDE3OSwgMTkxLCAxNzksIDE5NiwgMTc5LCAyMDAsCisxNzksIDIwMiwgMTc5LCAyMDcsIDE3OSwgMjEyLCAxNzksIDIxNywgMTc5LCAyMTksIDE3OSwgMjI0LCAxNzksIDIyOCwgMTc5LCAyMzMsCisxNzksIDIzNSwgMTc5LCAyMzksIDE3OSwgMjQzLCAxNzksIDI0NywgMTc5LCAyNDksIDE3OSwgMjUwLCAxNzksIDI1MywgMTgwLCAxNjIsCisxODAsIDE2NiwgMTgwLCAxNjksIDE4MCwgMTc0LCAxODAsIDE3OCwgMTgwLCAxNzksIDE4MCwgMTgxLCAxODAsIDE4NCwgMTgwLCAxODYsCisxODAsIDE4OSwgMTgwLCAxOTIsIDE4MCwgMTk3LCAxODAsIDIwMSwgMTgwLCAyMDUsIDE4MCwgMjA3LCAxODAsIDIxMSwgMTgwLCAyMTUsCisxODAsIDIyMCwgMTgwLCAyMjYsIDE4MCwgMjM0LCAxODAsIDIzOSwgMTgwLCAyNDQsIDE4MCwgMjQ1LCAxODAsIDI1MSwgMTgxLCAxNjIsCisxODEsIDE2NywgMTgxLCAxNjksIDE4MSwgMTc0LCAxODEsIDE3NywgMTgxLCAxODAsIDE4MSwgMTgxLCAxODEsIDE4NiwgMTgxLCAxOTEsCisxODEsIDE5NSwgMTgxLCAxOTcsIDE4MSwgMTk4LCAxODEsIDIwMCwgMTgxLCAyMDIsIDE4MSwgMjA1LCAxODEsIDIwNiwgMTgxLCAyMTAsCisxODEsIDIxNCwgMTgxLCAyMTUsIDE4MSwgMjE3LCAxODEsIDIxOSwgMTgxLCAyMjEsIDE4MSwgMjI0LCAxODEsIDIyNywgMTgxLCAyMjksCisxODEsIDIzNCwgMTgxLCAyMzgsIDE4MSwgMjQwLCAxODEsIDI0NSwgMTgxLCAyNTEsIDE4MiwgMTYxLCAxODIsIDE2NiwgMTgyLCAxNzEsCisxODIsIDE3NiwgMTgyLCAxODAsIDE4MiwgMTg1LCAxODIsIDE5MCwgMTgyLCAxOTIsIDE4MiwgMTk3LCAxODIsIDE5OCwgMTgyLCAxOTksCisxODIsIDIwMywgMTgyLCAyMDUsIDE4MiwgMjA2LCAxODIsIDIwNywgMTgyLCAyMDksIDE4MiwgMjEzLCAxODIsIDIxNiwgMTgyLCAyMTcsCisxODIsIDIyMCwgMTgyLCAyMjMsIDE4MiwgMjI4LCAxODIsIDIzMSwgMTgyLCAyMzQsIDE4MiwgMjM2LCAxODIsIDIzOSwgMTgyLCAyNDMsCisxODIsIDI0NywgMTgyLCAyNTMsIDE4MywgMTY0LCAxODMsIDE2NywgMTgzLCAxNzEsIDE4MywgMTczLCAxODMsIDE3NSwgMTgzLCAxNzksCisxODMsIDE4NCwgMTgzLCAxODksIDE4MywgMTkzLCAxODMsIDE5NywgMTgzLCAyMDIsIDE4MywgMjA0LCAxODMsIDIwNiwgMTgzLCAyMTAsCisxODMsIDIxNCwgMTgzLCAyMTYsIDE4MywgMjE3LCAxODMsIDIxOSwgMTgzLCAyMjEsIDE4MywgMjI1LCAxODMsIDIyOCwgMTgzLCAyMzEsCisxODMsIDIzNSwgMTgzLCAyMzksIDE4MywgMjQwLCAxODMsIDI0MiwgMTgzLCAyNDYsIDE4MywgMjQ5LCAxODMsIDI1MywgMTg0LCAxNjMsCisxODQsIDE2NywgMTg0LCAxNzMsIDE4NCwgMTc0LCAxODQsIDE3OCwgMTg0LCAxODIsIDE4NCwgMTg5LCAxODQsIDE5MywgMTg0LCAxOTksCisxODQsIDIwMSwgMTg0LCAyMDcsIDE4NCwgMjEwLCAxODQsIDIxMSwgMTg0LCAyMTUsIDE4NCwgMjE5LCAxODQsIDIyNCwgMTg0LCAyMjYsCisxODQsIDIzMSwgMTg0LCAyMzUsIDE4NCwgMjQwLCAxODQsIDI0NSwgMTg0LCAyNDksIDE4NCwgMjUxLCAxODQsIDI1MiwgMTg0LCAyNTQsCisxODUsIDE2MywgMTg1LCAxNjYsIDE4NSwgMTY5LCAxODUsIDE3MSwgMTg1LCAxNzgsIDE4NSwgMTgyLCAxODUsIDE4NiwgMTg1LCAxODgsCisxODUsIDE5MCwgMTg1LCAxOTEsIDE4NSwgMTk0LCAxODUsIDE5NywgMTg1LCAxOTksIDE4NSwgMjAyLCAxODUsIDIwNCwgMTg1LCAyMDksCisxODUsIDIxMywgMTg1LCAyMTksIDE4NSwgMjI3LCAxODUsIDIzMiwgMTg1LCAyMzYsIDE4NSwgMjQyLCAxODUsIDI0NSwgMTg1LCAyNDYsCisxODUsIDI1MSwgMTg2LCAxNjEsIDE4NiwgMTY1LCAxODYsIDE2OCwgMTg2LCAxNzMsIDE4NiwgMTc3LCAxODYsIDE4MiwgMTg2LCAxODQsCisxODYsIDE4OSwgMTg2LCAxOTMsIDE4NiwgMTk1LCAxODYsIDE5NywgMTg2LCAyMDAsIDE4NiwgMjAyLCAxODYsIDIwNCwgMTg2LCAyMDYsCisxODYsIDIxMiwgMTg2LCAyMTYsIDE4NiwgMjIwLCAxODYsIDIyMSwgMTg2LCAyMjMsIDE4NiwgMjI3LCAxODYsIDIyOSwgMTg2LCAyMzEsCisxODYsIDIzNCwgMTg2LCAyMzgsIDE4NiwgMjQxLCAxODYsIDI0NSwgMTg2LCAyNDksIDE4NiwgMjU0LCAxODcsIDE2MywgMTg3LCAxNjgsCisxODcsIDE3MywgMTg3LCAxNzgsIDE4NywgMTgwLCAxODcsIDE4MSwgMTg3LCAxODYsIDE4NywgMTkwLCAxODcsIDE5MSwgMTg3LCAxOTQsCisxODcsIDE5OSwgMTg3LCAyMDMsIDE4NywgMjA2LCAxODcsIDIwNywgMTg3LCAyMDgsIDE4NywgMjExLCAxODcsIDIxMywgMTg3LCAyMTYsCisxODcsIDIxNywgMTg3LCAyMTksIDE4NywgMjIxLCAxODcsIDIyMywgMTg3LCAyMjcsIDE4NywgMjMxLCAxODcsIDIzOCwgMTg3LCAyNDIsCisxODcsIDI0NywgMTg3LCAyNDksIDE4NywgMjU0LCAxODgsIDE2NCwgMTg4LCAxNjgsIDE4OCwgMTcxLCAxODgsIDE3MywgMTg4LCAxODAsCisxODgsIDE4NSwgMTg4LCAxOTAsIDE4OCwgMTkyLCAxODgsIDE5NywgMTg4LCAyMDEsIDE4OCwgMjA2LCAxODgsIDIwOSwgMTg4LCAyMTMsCisxODgsIDIxNiwgMTg4LCAyMjEsIDE4OCwgMjI1LCAxODgsIDIyNywgMTg4LCAyMjksIDE4OCwgMjMyLCAxODgsIDIzNSwgMTg4LCAyMzgsCisxODgsIDI0MiwgMTg4LCAyNDYsIDE4OCwgMjUxLCAxODksIDE2MywgMTg5LCAxNjUsIDE4OSwgMTY4LCAxODksIDE3MCwgMTg5LCAxNzIsCisxODksIDE3NiwgMTg5LCAxODAsIDE4OSwgMTgzLCAxODksIDE4NiwgMTg5LCAxOTEsIDE4OSwgMTk1LCAxODksIDIwMCwgMTg5LCAyMDUsCisxODksIDIxMCwgMTg5LCAyMTMsIDE4OSwgMjE4LCAxODksIDIyMCwgMTg5LCAyMjQsIDE4OSwgMjI1LCAxODksIDIyOSwgMTg5LCAyMzIsCisxODksIDIzNSwgMTg5LCAyMzcsIDE4OSwgMjM4LCAxODksIDI0MywgMTg5LCAyNDYsIDE4OSwgMjQ5LCAxODksIDI1MCwgMTg5LCAyNTIsCisxODksIDI1NCwgMTkwLCAxNjIsIDE5MCwgMTY0LCAxOTAsIDE2NSwgMTkwLCAxNjksIDE5MCwgMTcyLCAxOTAsIDE3MywgMTkwLCAxNzUsCisxOTAsIDE3NywgMTkwLCAxODAsIDE5MCwgMTgzLCAxOTAsIDE4NiwgMTkwLCAxODksIDE5MCwgMTkwLCAxOTAsIDE5NCwgMTkwLCAxOTgsCisxOTAsIDIwNSwgMTkwLCAyMTAsIDE5MCwgMjE2LCAxOTAsIDIxOCwgMTkwLCAyMjMsIDE5MCwgMjI3LCAxOTAsIDIzMSwgMTkwLCAyMzUsCisxOTAsIDIzNywgMTkwLCAyMzgsIDE5MCwgMjQ1LCAxOTAsIDI1MCwgMTkxLCAxNjMsIDE5MSwgMTY1LCAxOTEsIDE2OSwgMTkxLCAxNzQsCisxOTEsIDE4MCwgMTkxLCAxODYsIDE5MSwgMTg4LCAxOTEsIDE5MiwgMTkxLCAxOTcsIDE5MSwgMjAzLCAxOTEsIDIwNywgMTkxLCAyMDksCisxOTEsIDIxNCwgMTkxLCAyMTcsIDE5MSwgMjIwLCAxOTEsIDIyNCwgMTkxLCAyMjgsIDE5MSwgMjMyLCAxOTEsIDIzNiwgMTkxLCAyNDEsCisxOTEsIDI0NSwgMTkxLCAyNDgsIDE5MSwgMjUwLCAxOTEsIDI1NCwgMTkyLCAxNjQsIDE5MiwgMTY3LCAxOTIsIDE3MSwgMTkyLCAxNzUsCisxOTIsIDE3OSwgMTkyLCAxODQsIDE5MiwgMTg4LCAxOTIsIDE5NSwgMTkyLCAyMDEsIDE5MiwgMjAzLCAxOTIsIDIwNSwgMTkyLCAyMTAsCisxOTIsIDIxNywgMTkyLCAyMjMsIDE5MiwgMjI3LCAxOTIsIDIzMiwgMTkyLCAyMzUsIDE5MiwgMjQwLCAxOTIsIDI0NSwgMTkyLCAyNDcsCisxOTIsIDI1MCwgMTkyLCAyNTQsIDE5MywgMTY0LCAxOTMsIDE2OCwgMTkzLCAxNzAsIDE5MywgMTc0LCAxOTMsIDE3NywgMTkzLCAxODEsCisxOTMsIDE4MiwgMTkzLCAxODYsIDE5MywgMTkwLCAxOTMsIDE5NiwgMTkzLCAxOTgsIDE5MywgMjAxLCAxOTMsIDIwNCwgMTkzLCAyMDYsCisxOTMsIDIxMCwgMTkzLCAyMTMsIDE5MywgMjE2LCAxOTMsIDIyMCwgMTkzLCAyMjQsIDE5MywgMjI1LCAxOTMsIDIyNywgMTkzLCAyMzEsCisxOTMsIDIzNCwgMTkzLCAyMzcsIDE5MywgMjM4LCAxOTMsIDI0MiwgMTkzLCAyNDYsIDE5MywgMjUxLCAxOTQsIDE2MSwgMTk0LCAxNjcsCisxOTQsIDE3MSwgMTk0LCAxNzYsIDE5NCwgMTgwLCAxOTQsIDE4NSwgMTk0LCAxODcsIDE5NCwgMTg4LCAxOTQsIDE5MiwgMTk0LCAxOTcsCisxOTQsIDE5OCwgMTk0LCAyMDAsIDE5NCwgMjAxLCAxOTQsIDIwNSwgMTk0LCAyMTAsIDE5NCwgMjEzLCAxOTQsIDIxNSwgMTk0LCAyMTcsCisxOTQsIDIxOSwgMTk0LCAyMjEsIDE5NCwgMjI0LCAxOTQsIDIyNiwgMTk0LCAyMjksIDE5NCwgMjMwLCAxOTQsIDIzMiwgMTk0LCAyMzMsCisxOTQsIDIzNCwgMTk0LCAyMzUsIDE5NCwgMjM4LCAxOTQsIDI0MiwgMTk0LCAyNDYsIDE5NCwgMjUyLCAxOTUsIDE2NCwgMTk1LCAxNjgsCisxOTUsIDE3MywgMTk1LCAxNzcsIDE5NSwgMTc5LCAxOTUsIDE4MywgMTk1LCAxODgsIDE5NSwgMTkyLCAxOTUsIDE5NiwgMTk1LCAxOTgsCisxOTUsIDIwMCwgMTk1LCAyMDEsIDE5NSwgMjA0LCAxOTUsIDIwNiwgMTk1LCAyMTAsIDE5NSwgMjEzLCAxOTUsIDIxNCwgMTk1LCAyMTcsCisxOTUsIDIyMSwgMTk1LCAyMjIsIDE5NSwgMjIzLCAxOTUsIDIyNywgMTk1LCAyMzEsIDE5NSwgMjMyLCAxOTUsIDIzNCwgMTk1LCAyMzUsCisxOTUsIDIzOCwgMTk1LCAyNDIsIDE5NSwgMjQ1LCAxOTUsIDI0NywgMTk1LCAyNTEsIDE5NiwgMTYxLCAxOTYsIDE2NywgMTk2LCAxNzEsCisxOTYsIDE3NSwgMTk2LCAxNzksIDE5NiwgMTgzLCAxOTYsIDE4OCwgMTk2LCAxOTAsIDE5NiwgMTkxLCAxOTYsIDE5NiwgMTk2LCAyMDEsCisxOTYsIDIwNSwgMTk2LCAyMDksIDE5NiwgMjEyLCAxOTYsIDIxNywgMTk2LCAyMTgsIDE5NiwgMjIyLCAxOTYsIDIyNiwgMTk2LCAyMzAsCisxOTYsIDIzMiwgMTk2LCAyMzMsIDE5NiwgMjM1LCAxOTYsIDIzNiwgMTk2LCAyMzcsIDE5NiwgMjQxLCAxOTYsIDI0NSwgMTk2LCAyNDgsCisxOTYsIDI1MCwgMTk2LCAyNTMsIDE5NywgMTYxLCAxOTcsIDE2NSwgMTk3LCAxNjgsIDE5NywgMTY5LCAxOTcsIDE3MywgMTk3LCAxNzYsCisxOTcsIDE4MCwgMTk3LCAxODQsIDE5NywgMTg5LCAxOTcsIDE5NCwgMTk3LCAxOTgsIDE5NywgMjAzLCAxOTcsIDIwNCwgMTk3LCAyMDUsCisxOTcsIDIwOSwgMTk3LCAyMTMsIDE5NywgMjE3LCAxOTcsIDIxOSwgMTk3LCAyMjMsIDE5NywgMjI1LCAxOTcsIDIyNywgMTk3LCAyMjgsCisxOTcsIDIzMiwgMTk3LCAyMzYsIDE5NywgMjM5LCAxOTcsIDI0MCwgMTk3LCAyNDIsIDE5NywgMjQ1LCAxOTcsIDI0OSwgMTk3LCAyNTMsCisxOTcsIDI1NCwgMTk4LCAxNjIsIDE5OCwgMTY2LCAxOTgsIDE2OSwgMTk4LCAxNzIsIDE5OCwgMTc0LCAxOTgsIDE3OSwgMTk4LCAxODMsCisxOTgsIDE4NiwgMTk4LCAxODgsIDE5OCwgMTkyLCAxOTgsIDE5NiwgMTk4LCAyMDEsIDE5OCwgMjA1LCAxOTgsIDIxMCwgMTk4LCAyMTIsCisxOTgsIDIxNywgMTk4LCAyMTksIDE5OCwgMjIzLCAxOTgsIDIyOCwgMTk4LCAyMzIsIDE5OCwgMjM2LCAxOTgsIDIzOSwgMTk4LCAyNDMsCisxOTgsIDI0NSwgMTk4LCAyNDcsIDE5OCwgMjUxLCAxOTksIDE2MSwgMTk5LCAxNjIsIDE5OSwgMTYzLCAxOTksIDE2NSwgMTk5LCAxNjgsCisxOTksIDE3MCwgMTk5LCAxNzUsIDE5OSwgMTc5LCAxOTksIDE4MSwgMTk5LCAxODIsIDE5OSwgMTg1LCAxOTksIDE4NywgMTk5LCAxOTAsCisxOTksIDE5MywgMTk5LCAxOTYsIDE5OSwgMTk5LCAxOTksIDIwMywgMTk5LCAyMDcsIDE5OSwgMjExLCAxOTksIDIxNiwgMTk5LCAyMjAsCisxOTksIDIyNSwgMTk5LCAyMjYsIDE5OSwgMjI3LCAxOTksIDIzMSwgMTk5LCAyMzUsIDE5OSwgMjM4LCAxOTksIDI0MCwgMTk5LCAyNDQsCisxOTksIDI0OCwgMTk5LCAyNTMsIDIwMCwgMTYyLCAyMDAsIDE2MywgMjAwLCAxNjcsIDIwMCwgMTcyLCAyMDAsIDE3NiwgMjAwLCAxNzcsCisyMDAsIDE4MCwgMjAwLCAxODIsIDIwMCwgMTg1LCAyMDAsIDE4OCwgMjAwLCAxOTEsIDIwMCwgMTk0LCAyMDAsIDE5NiwgMjAwLCAyMDAsCisyMDAsIDIwNCwgMjAwLCAyMDcsIDIwMCwgMjA5LCAyMDAsIDIxMywgMjAwLCAyMTYsIDIwMCwgMjE4LCAyMDAsIDIyMiwgMjAwLCAyMjYsCisyMDAsIDIyOSwgMjAwLCAyMzYsIDIwMCwgMjQxLCAyMDAsIDI0NCwgMjAwLCAyNDcsIDIwMCwgMjUxLCAyMDMsIDIwOCwgMjA4LCAyMjEsCisyMDksIDIyNiwgMjA5LCAyMzksIDIxMCwgMTY3LCAyMTAsIDE5NiwgMjEwLCAyMDgsIDIxMCwgMjIyLCAyMTAsIDIzNCwgMjEyLCAyMzAsCisyMTksIDIyOCwgMjI0LCAyNDEsIDIyOSwgMTg3LCAyMjksIDI1NCwgMjMwLCAxODQsIDIzMCwgMjIzLCAyMzAsIDI0MSwgMjMxLCAxNzIsCisyMzEsIDIwOCwgMjMyLCAyNDcsIDIzNCwgMjQ0LCAyMzUsIDE4OSwgMjM1LCAyMTYsIDIzNiwgMTg2LCAyMzYsIDIyNSwgMjM3LCAyMzgsCisyNDcsIDIwMCwgMTYzLCAxNjEsIDE2MywgMTcxLCAxNjMsIDE4MSwgMTYzLCAxOTEsIDE2MywgMjAxLCAxNjMsIDIxMSwgMTYzLCAyMjEsCisxNjMsIDIzMSwgMTYzLCAyNDEsIDE2MywgMjUxLCAxNjEsIDIwMywgMAorICAgICAgICAgICAgfSk7CisKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9NdWx0aUJ5dGVfR0IyMzEyLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX0dCMjMxMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRmNjEyM2EKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX0dCMjMxMi5qYXZhCkBAIC0wLDAgKzEsMTkzIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbjsKKworcHVibGljIGNsYXNzIE9sZENoYXJzZXRfTXVsdGlCeXRlX0dCMjMxMiBleHRlbmRzIE9sZENoYXJzZXRfQWJzdHJhY3RUZXN0IHsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJzZXROYW1lID0gIkdCMjMxMiI7CisKKyAgICAgICAgdGVzdENoYXJzID0gdGhlc2VDaGFycyhuZXcgaW50W117CiswLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAorMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCiszMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKzQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCis4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKzk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorMTY0LCAxNjcsIDE2OCwgMTc2LCAxNzcsIDIxNSwgMjI0LCAyMjUsIDIzMiwgMjMzLCAyMzQsIDIzNiwgMjM3LCAyNDIsIDI0MywgMjQ3LAorMjQ5LCAyNTAsIDI1MiwgMjU3LCAyNzUsIDMzMywgMzYzLCA0NjIsIDcxMSwgOTEzLCA5NDUsIDEwMjUsIDEwNTUsIDEwODUsIDgyMTMsIDgyNDMsCis4NDUxLCA4NTQ0LCA4NTkyLCA4NzEyLCA4NzQzLCA4Nzc2LCA4ODE0LCA4ODU3LCA4OTc4LCA5MzEyLCA5MzQyLCA5NDcyLCA5NTAyLCA5NTMyLCA5NjMyLCA5NjcwLAorOTczMywgOTc5MiwgMTIyODgsIDEyMzUzLCAxMjM4MywgMTI0MTMsIDEyNDQ5LCAxMjQ3OSwgMTI1MDksIDEyNTM5LCAxMjU2OSwgMTI4MzIsIDE5OTY4LCAxOTk5OCwgMjAwMjksIDIwMDYwLAorMjAwOTQsIDIwMTI3LCAyMDE1OSwgMjAxODksIDIwMjE5LCAyMDI0OSwgMjAyODAsIDIwMzExLCAyMDM0MiwgMjAzNzIsIDIwNDA1LCAyMDQzOSwgMjA0NzIsIDIwNTA0LCAyMDUzOCwgMjA1NzAsCisyMDYwMywgMjA2NDMsIDIwNjg3LCAyMDcxNywgMjA3NDcsIDIwNzk5LCAyMDgzNCwgMjA4NjQsIDIwODk2LCAyMDkyOCwgMjA5NjAsIDIwOTkxLCAyMTAyMSwgMjEwNTEsIDIxMDg0LCAyMTExNywKKzIxMTQ3LCAyMTE4MiwgMjEyMTUsIDIxMjQ2LCAyMTI3NywgMjEzMDcsIDIxMzM4LCAyMTM2OCwgMjE0MDAsIDIxNDMwLCAyMTQ2MCwgMjE0OTAsIDIxNTIwLCAyMTU1MCwgMjE1ODQsIDIxNjE3LAorMjE2NDcsIDIxNjc3LCAyMTcwOCwgMjE3MzgsIDIxNzY5LCAyMTc5OSwgMjE4MzAsIDIxODYwLCAyMTg5MCwgMjE5MjcsIDIxOTU3LCAyMTk4NywgMjIwMTcsIDIyMDQ3LCAyMjA3OSwgMjIxMTQsCisyMjE0OSwgMjIxNzksIDIyMjE4LCAyMjI1MSwgMjIyODEsIDIyMzEyLCAyMjM0MywgMjIzNzQsIDIyNDA0LCAyMjQzNCwgMjI0NjYsIDIyNDk2LCAyMjUyOCwgMjI1NTgsIDIyNTk2LCAyMjYyOSwKKzIyNjU5LCAyMjY5NiwgMjI3MzcsIDIyNzY4LCAyMjc5OSwgMjI4MjksIDIyODU5LCAyMjg5OSwgMjI5MzAsIDIyOTYyLCAyMjk5MiwgMjMwMzMsIDIzMDY0LCAyMzA5NCwgMjMxMjUsIDIzMTU2LAorMjMxODYsIDIzMjE4LCAyMzI1MCwgMjMyODEsIDIzMzE4LCAyMzM0OCwgMjMzNzksIDIzNDA5LCAyMzQzOSwgMjM0NzIsIDIzNTA0LCAyMzUzNCwgMjM1NjcsIDIzNjAxLCAyMzYzMSwgMjM2NjIsCisyMzY5MiwgMjM3MjMsIDIzNzU1LCAyMzc4NiwgMjM4MjIsIDIzODUzLCAyMzg4MywgMjM5MTMsIDIzOTYxLCAyMzk5MSwgMjQwMjcsIDI0MDYxLCAyNDA5MSwgMjQxMjMsIDI0MTU1LCAyNDE4NiwKKzI0MjE3LCAyNDI0NywgMjQyNzgsIDI0MzA4LCAyNDMzOSwgMjQzNjksIDI0NDAwLCAyNDQzMiwgMjQ0NjQsIDI0NDk0LCAyNDUyNCwgMjQ1NTQsIDI0NTg2LCAyNDYxNiwgMjQ2NTEsIDI0NjgxLAorMjQ3MTMsIDI0NzQ0LCAyNDc3NCwgMjQ4MDYsIDI0ODM4LCAyNDg2OCwgMjQ5MDQsIDI0OTM1LCAyNDk3MSwgMjUwMDEsIDI1MDMyLCAyNTA2MiwgMjUwOTQsIDI1MTI0LCAyNTE1NSwgMjUxODcsCisyNTIyMCwgMjUyNTAsIDI1MjgyLCAyNTMxNCwgMjUzNDUsIDI1Mzc1LCAyNTQwNSwgMjU0MzgsIDI1NDcyLCAyNTUwNCwgMjU1MzQsIDI1NTY2LCAyNTU5NywgMjU2MjcsIDI1NjU4LCAyNTY4OCwKKzI1NzIwLCAyNTc1MCwgMjU3ODEsIDI1ODE1LCAyNTg1NiwgMjU4OTMsIDI1OTI1LCAyNTk1NSwgMjU5OTEsIDI2MDIxLCAyNjA1MSwgMjYwODIsIDI2MTEyLCAyNjE0MywgMjYxNzQsIDI2MjA3LAorMjYyMzgsIDI2MjY5LCAyNjMwMiwgMjYzMzIsIDI2MzY0LCAyNjM5NSwgMjY0MjYsIDI2NDYwLCAyNjQ5MiwgMjY1MjIsIDI2NTUyLCAyNjU4NCwgMjY2MjEsIDI2NjUzLCAyNjY4NCwgMjY3MjAsCisyNjc1MywgMjY3ODYsIDI2ODE2LCAyNjg0OCwgMjY4ODEsIDI2OTExLCAyNjk0MSwgMjY5NzMsIDI3MDA0LCAyNzAzNSwgMjcwNjcsIDI3MDk5LCAyNzEzMywgMjcxNjcsIDI3MTk3LCAyNzIyNywKKzI3MjU3LCAyNzI4NywgMjc0MjQsIDI3NDU0LCAyNzQ5MCwgMjc1MjEsIDI3NTUzLCAyNzU4MywgMjc2MTcsIDI3NjUzLCAyNzY4NCwgMjc3MTQsIDI3NzQ0LCAyNzc3NCwgMjc4MDcsIDI3ODM3LAorMjc4NjcsIDI3ODk4LCAyNzkyOSwgMjc5NjEsIDI3OTkzLCAyODAyMywgMjgwNTMsIDI4MDg1LCAyODExOCwgMjgxNTEsIDI4MTgyLCAyODIxMiwgMjgyNDMsIDI4Mjg2LCAyODMxNiwgMjgzNDYsCisyODM3OCwgMjg0MDksIDI4NDQ4LCAyODQ3OCwgMjg1MDgsIDI4NTM4LCAyODU3MiwgMjg2MDgsIDI4NjM4LCAyODY4OSwgMjg3MjUsIDI4NzY2LCAyODc5NiwgMjg4MjgsIDI4ODU5LCAyODg4OSwKKzI4OTE5LCAyODk0OSwgMjg5ODIsIDI5MDIwLCAyOTA1MCwgMjkwODAsIDI5MTEzLCAyOTE1MiwgMjkxOTAsIDI5MjI0LCAyOTI1NSwgMjkyODYsIDI5MzE2LCAyOTM1NiwgMjkzODksIDI5NDIwLAorMjk0NTAsIDI5NDgxLCAyOTUxNywgMjk1NDgsIDI5NTc5LCAyOTYwOSwgMjk2NDAsIDI5NjcxLCAyOTcwMSwgMjk3MzMsIDI5NzgxLCAyOTgxNCwgMjk4NTIsIDI5ODgyLCAyOTkxNiwgMjk5NTEsCisyOTk4MywgMzAwMTQsIDMwMDQ0LCAzMDA3OSwgMzAxMDksIDMwMTQwLCAzMDE3MSwgMzAyMDEsIDMwMjMxLCAzMDI2MSwgMzAyOTIsIDMwMzI4LCAzMDM1OCwgMzAzODgsIDMwNDE4LCAzMDQ0OSwKKzMwNDg5LCAzMDUxOSwgMzA1NTQsIDMwNTg1LCAzMDYyMywgMzA2NTMsIDMwNjgzLCAzMDcxNywgMzA3NDgsIDMwNzc4LCAzMDgxMywgMzA4NDQsIDMwODc0LCAzMDkwNSwgMzA5MzcsIDMwOTY3LAorMzEwMDYsIDMxMDM2LCAzMTA2NiwgMzEwOTYsIDMxMTMwLCAzMTE2MSwgMzExOTIsIDMxMjI0LCAzMTI1NSwgMzEyODcsIDMxMzE5LCAzMTM1MCwgMzEzODEsIDMxNDExLCAzMTQ0NiwgMzE0ODEsCiszMTUxMywgMzE1NDQsIDMxNTc0LCAzMTYwNSwgMzE2MzYsIDMxNjY4LCAzMTY5OSwgMzE3MjksIDMxNzU5LCAzMTgwMCwgMzE4NTksIDMxODg5LCAzMTkyMSwgMzE5NTcsIDMxOTkyLCAzMjAzMiwKKzMyMTEwLCAzMjE2NiwgMzIzMTUsIDMyMzg2LCAzMjQxNiwgMzI0NDYsIDMyNDc2LCAzMjUwNiwgMzI1MzYsIDMyNTY2LCAzMjU5NiwgMzI2MjYsIDMyNjYwLCAzMjY5MCwgMzI3MjQsIDMyNzU1LAorMzI3ODYsIDMyODE3LCAzMjg1MCwgMzI4ODEsIDMyOTE1LCAzMjk0NSwgMzI5ODIsIDMzMDEyLCAzMzA0MiwgMzMwNzMsIDMzMTA0LCAzMzEzNCwgMzMxNjcsIDMzMjAzLCAzMzI1MSwgMzMyODEsCiszMzMxMSwgMzMzNDIsIDMzMzc1LCAzMzQwNSwgMzM0MzYsIDMzNDY5LCAzMzQ5OSwgMzM1MjksIDMzNTU5LCAzMzU4OSwgMzM2MjAsIDMzNjU1LCAzMzY4OCwgMzM3MTgsIDMzNzQ4LCAzMzc3OCwKKzMzODA5LCAzMzg0MSwgMzM4NzMsIDMzOTA1LCAzMzk0MywgMzM5NzYsIDM0MDA2LCAzNDA0NCwgMzQwNzQsIDM0MTA0LCAzNDEzNCwgMzQxNjQsIDM0MjAzLCAzNDIzMywgMzQyNjgsIDM0Mjk5LAorMzQzNDMsIDM0MzgxLCAzNDQxMSwgMzQ0NDIsIDM0NDcyLCAzNDUwMiwgMzQ1MzIsIDM0NTYyLCAzNDU5MywgMzQ2MjMsIDM0NjU2LCAzNDY4NiwgMzQ3MTksIDM0NzQ5LCAzNDc3OSwgMzQ4MDksCiszNDg0MywgMzQ4NzMsIDM0OTAzLCAzNDkzNSwgMzQ5NjYsIDM0OTk5LCAzNTAyOSwgMzUwNTksIDM1MDkwLCAzNTEyMCwgMzUxNjYsIDM1MTk5LCAzNTI2NSwgMzUyOTksIDM1MzM1LCAzNTM5MCwKKzM1NDQ5LCAzNTU5MSwgMzU2MjIsIDM1Njg2LCAzNTc0NCwgMzU3NzQsIDM1ODA0LCAzNTgzNCwgMzU4NjQsIDM1ODk0LCAzNTkyNSwgMzU5NTUsIDM1OTg4LCAzNjEyNSwgMzYxNTUsIDM2MTg1LAorMzYyMTUsIDM2MjU1LCAzNjI4NiwgMzYzMTcsIDM2MzQ3LCAzNjM4MSwgMzY0MTMsIDM2NDU0LCAzNjQ4NSwgMzY1MjMsIDM2NTU4LCAzNjcxMCwgMzY3NDAsIDM2NzcxLCAzNjgwMSwgMzY4MzEsCiszNjg2MSwgMzY4OTEsIDM2OTIzLCAzNjk1NSwgMzY5ODksIDM3MDE5LCAzNzA0OSwgMzcwNzksIDM3MTEyLCAzNzE0NSwgMzcxNzcsIDM3MjA3LCAzNzIzNywgMzcyNzQsIDM3MzA2LCAzNzM0MCwKKzM3NDkyLCAzNzU1MCwgMzc2OTQsIDM3NzM4LCAzNzc3NSwgMzc4MzQsIDM3OTUwLCAzNzk5NSwgMzgwMjUsIDM4MDU1LCAzODA4NSwgMzgxMTUsIDM4MTQ1LCAzODE3NSwgMzgyMDYsIDM4MjM2LAorMzgyNzEsIDM4Mzc2LCAzODQwNiwgMzg0NDIsIDM4NDcyLCAzODUwMywgMzg1MzMsIDM4NTY3LCAzODU5NywgMzg2MzIsIDM4NjYyLCAzODY5OCwgMzg3MzgsIDM4NzcxLCAzODgwMSwgMzg4MzEsCiszODg4NiwgMzkwMjksIDM5MDU5LCAzOTExOCwgMzkxODEsIDM5MjE0LCAzOTI1MiwgMzkyODIsIDM5MzEyLCAzOTUzMiwgMzk1NjIsIDM5NTkyLCAzOTYyNywgMzk2NTksIDM5Njk1LCAzOTcyNywKKzM5NzU3LCA0MDA2MCwgNDAwOTAsIDQwMTIwLCA0MDE1MCwgNDA0NzksIDQwNTA5LCA0MDUzOSwgNDA1NzQsIDQwNjA1LCA0MDYzNSwgNDA2NjcsIDQwNjk3LCA0MDcyNywgNDA3NTksIDQwODMxLAorNDA4NjMsIDY1MjgxLCA2NTMxMSwgNjUzNDEsIDY1MzcxLCA2NTUwNAorICAgICAgICAgICAgfSk7CisKKyAgICAgICAgdGVzdEJ5dGVzID0gdGhlc2VCeXRlcyhuZXcgaW50W117CiswLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAorMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCiszMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKzQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCis4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKzk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorMTYxLCAyMzIsIDE2MSwgMjM2LCAxNjEsIDE2NywgMTYxLCAyMjcsIDE2MSwgMTkyLCAxNjEsIDE5MywgMTY4LCAxNjQsIDE2OCwgMTYyLAorMTY4LCAxNjgsIDE2OCwgMTY2LCAxNjgsIDE4NiwgMTY4LCAxNzIsIDE2OCwgMTcwLCAxNjgsIDE3NiwgMTY4LCAxNzQsIDE2MSwgMTk0LAorMTY4LCAxODAsIDE2OCwgMTc4LCAxNjgsIDE4NSwgMTY4LCAxNjEsIDE2OCwgMTY1LCAxNjgsIDE3MywgMTY4LCAxNzcsIDE2OCwgMTYzLAorMTYxLCAxNjYsIDE2NiwgMTYxLCAxNjYsIDE5MywgMTY3LCAxNjcsIDE2NywgMTc3LCAxNjcsIDIyMywgMTYxLCAxNzAsIDE2MSwgMjI5LAorMTYxLCAyMzAsIDE2MiwgMjQxLCAxNjEsIDI1MSwgMTYxLCAyMDIsIDE2MSwgMTk2LCAxNjEsIDIxNCwgMTYxLCAyMTgsIDE2MSwgMjA5LAorMTYxLCAyMDgsIDE2MiwgMjE3LCAxNjIsIDIwNywgMTY5LCAxNjQsIDE2OSwgMTk0LCAxNjksIDIyNCwgMTYxLCAyNDYsIDE2MSwgMjQ0LAorMTYxLCAyMzksIDE2MSwgMjI2LCAxNjEsIDE2MSwgMTY0LCAxNjEsIDE2NCwgMTkxLCAxNjQsIDIyMSwgMTY1LCAxNjEsIDE2NSwgMTkxLAorMTY1LCAyMjEsIDE2MSwgMTY0LCAxNjgsIDIxNywgMTYyLCAyMjksIDIxMCwgMTg3LCAyMTYsIDE2OSwgMTkyLCAyNDYsIDIxNiwgMTkxLAorMTk5LCAxNzIsIDIxNiwgMTg5LCAyMTAsIDIxOCwgMjE3LCAyMTgsIDIwMCwgMjA2LCAxODcsIDIzOSwgMjAxLCAyMzYsIDIxNywgMTYyLAorMjE3LCAxNjUsIDIxNywgMTc2LCAxOTksIDIxNCwgMjAzLCAyMTUsIDIxNywgMTg2LCAyMDQsIDIwMCwgMjEzLCAxNzQsIDIxNSwgMjQ2LAorMjE3LCAyMDUsIDE4MCwgMjQ2LCAyMDcsIDI0MSwgMjE3LCAyMTIsIDIxNywgMjE3LCAxODIsIDI0OSwgMTkwLCAxNjQsIDE4OCwgMTg5LAorMTg1LCAyMTgsIDE5MCwgMTg3LCAxODgsIDE4NCwgMjEyLCAyMjgsIDE3OSwgMjQ1LCAxOTEsIDIwNCwgMjE2LCAyMjQsIDIxNiwgMjI2LAorMTkzLCAxNjYsIDIxOSwgMTkyLCAxOTYsIDE4OCwgMTg1LCAxODAsIDIxMiwgMjA5LCAyMTAsIDE4OSwgMTc4LCAxNjksIDIwOCwgMTgyLAorMTkyLCAyMjksIDIxOSwgMjA0LCAyMDIsIDIyOSwgMjAyLCAxODMsIDIwNSwgMTk0LCAyMDMsIDE3NywgMTk2LCAxOTcsIDIyMywgMjAxLAorMjExLCAxODksIDIyMywgMjEwLCAyMjMsIDIyMywgMTk2LCAxOTYsIDE3NiwgMTY2LCAyMjMsIDI0MywgMjAxLCAyMDQsIDE5OCwgMTYxLAorMjA2LCAxODUsIDIwOCwgMjUwLCAyMDgsIDIyNSwgMjAzLCAxOTUsIDIyNCwgMjEwLCAyMjQsIDE4OSwgMTg2LCAyMTcsIDIyNCwgMjIyLAorMjI0LCAyMzMsIDIwNywgMjQ5LCAxOTYsIDIxMCwgMjI0LCAyNDEsIDIyNCwgMjQ2LCAyMTIsIDIxOCwgMTkwLCAyNDksIDIwNCwgMTg1LAorMTk0LCAxNjIsIDE4NSwgMTg0LCAxODUsIDE2MSwgMTc4LCAxODYsIDIyMCwgMTY1LCAyMjAsIDE2NiwgMjIwLCAxNjgsIDIyMCwgMTcwLAorMTkwLCAxNzksIDE5NiwgMTcxLCAyMTksIDIxNCwgMjAxLCAyNDksIDIwNywgMTk2LCAyMTYsIDE3OCwgMTgzLCAyMjAsIDE5NywgMTc0LAorMTgyLCAyMDIsIDIzMCwgMTY3LCAxODksIDIyNywgMjMwLCAxNzcsIDE5NiwgMjM5LCAyMDAsIDE2MiwgMjMwLCAxODgsIDIxMSwgMTY0LAorMTk1LCAxODksIDIzMCwgMTk5LCAyMzAsIDIwMCwgMjMwLCAyMDUsIDIzMCwgMjEyLCAyMTcsIDI0OCwgMjMwLCAyMjIsIDIyOSwgMjM4LAorMTg2LCAyMzQsIDIxMiwgMjE1LCAxOTUsIDE5NCwgMjI5LCAxODgsIDIwOCwgMTYxLCAxOTAsIDIwNSwgMTk4LCAxOTMsIDIyOSwgMjQ4LAorMjI1LCAxNjcsIDIyNSwgMTgyLCAyMjUsIDE5MCwgMjExLCAyNDgsIDE5OCwgMjMzLCAyMTMsIDE4NCwgMjI1LCAyMTAsIDIyNSwgMjEyLAorMjI1LCAyMTUsIDIyNSwgMjE4LCAyMzEsIDIyMSwgMjE3LCAyMjcsIDE3OCwgMTc1LCAyMjQsIDI1MywgMjI1LCAxNjQsIDIzMSwgMjE5LAorMTk1LCAyMzcsIDE5MSwgMTgxLCAxOTMsIDIwNiwgMjE5LCAyMDAsIDE4NSwgMTczLCAyMDAsIDI0NSwgMjI5LCAyMzAsIDIxMywgMTk1LAorMjA4LCAyMzYsIDIwNiwgMTYyLCAxODgsIDIwMSwgMjI2LCAyMzYsIDIyNiwgMjQ3LCAyMTIsIDE4NSwgMTkzLCAxODEsIDE4MiwgMjQ3LAorMjA3LCAxNjQsIDE5NiwgMjUwLCAyMjcsIDE3NiwgMTgxLCAyMzUsIDIzNywgMTY5LCAxODMsIDIyMywgMTgwLCAyMDAsIDE4NywgMjE5LAorMTc3LCAyMzksIDIzNywgMTcyLCAyMDgsIDE4NCwgMTk3LCAxNzksIDIzNywgMTc2LCAyMzQsIDE3NCwgMjM2LCAyMzEsIDE5MSwgMjE5LAorMTc5LCAxNzMsIDE5OSwgMTkyLCAxODMsIDI0NywgMTk0LCAxNjMsIDE3OSwgMjE0LCAyMDgsIDE3NCwgMjA1LCAyMzYsIDE5MiwgMjA0LAorMjA3LCAxOTgsIDE5NCwgMjExLCAyMjIsIDI0MiwgMjIyLCAyMzgsIDE5MiwgMTkxLCAyMjIsIDI0NiwgMjA4LCAxNzUsIDIxMywgMTcwLAorMTk1LCAyNTQsIDIyMiwgMjU0LCAxOTYsIDIzNiwgMjIzLCAxNjgsIDE5NywgMjAyLCAyMjMsIDE3MiwgMTg1LCAyMDIsIDIwMSwgMTYyLAorMjA2LCAxOTYsIDE3OSwgMjI2LCAyMzYsIDE4NSwgMTg4LCAyMDAsIDIzNCwgMTkyLCAyMDgsIDE5OSwgMjA3LCAyMTIsIDIzNCwgMjAxLAorMTkzLCAxOTIsIDIzNCwgMjEyLCAyMzQsIDIxMywgMjM0LCAyMTUsIDE5NCwgMjUyLCAyMDUsIDI1MSwgMTg3LCAyNTAsIDE4MiwgMTk3LAorMjMyLCAyMDQsIDE5NSwgMTgyLCAyMzIsIDIxOSwgMjMyLCAyMDcsIDIzMiwgMjIzLCAyMzIsIDIzMywgMTg0LCAyNDEsIDIzMiwgMjI2LAorMTkzLCAxODYsIDIwMSwgMjEwLCAxODgsIDIzNiwgMjA0LCAxOTYsIDIzMywgMTY0LCAyMzIsIDI1MiwgMTgwLCAxNzAsIDIzMywgMTcyLAorMTk0LCAxNjUsIDIzMywgMTg3LCAyMzMsIDE4OSwgMTg4LCAyNDcsIDE3OCwgMjE5LCAyMTMsIDE5MywgMjMzLCAyMTUsIDIzMywgMjExLAorMjMzLCAyMTQsIDIzMywgMjIyLCAxOTksIDE4MywgMTkxLCAyMzgsIDIxNCwgMTg1LCAyMzMsIDIyNiwgMjMzLCAyMzUsIDE4MSwgMjM4LAorMjEzLCAxNzcsIDIzNSwgMTY5LCAyMzUsIDE3OSwgMTk5LCAyNDMsIDE3OSwgMjE2LCAxODMsIDIxOCwgMTg1LCAxODEsIDE4NSwgMTkzLAorMTgzLCAxODYsIDIyNywgMjQ4LCAyMjgsIDE2OCwgMjI4LCAxNjEsIDIxMywgMjI3LCAxODYsIDE2MywgMjA0LCAyMzMsIDE4NiwgMTczLAorMTk2LCAyMTUsIDE4NywgMjM2LCAyMjgsIDIwMSwgMTkxLCAyMDIsIDIyOCwgMjEyLCAyMDUsIDIyOSwgMTkzLCAyMzksIDE5NiwgMjMxLAorMTg1LCAyNDYsIDIyOCwgMjM5LCAxOTYsIDE3NCwgMjA5LCAyNTAsIDE5OSwgMTc3LCAyMjgsIDI1MywgMTkyLCAxODksIDE4OCwgMTY0LAorMjI5LCAxNjgsIDE5OCwgMjE3LCAyMjksIDE3NSwgMjI5LCAxNzcsIDIxNSwgMTk4LCAyMzYsIDE5MSwgMjM2LCAxOTQsIDE5MiwgMjExLAorMjA1LCAyMzMsIDE4NywgMTkyLCAyMDAsIDE4NywgMjM2LCAyMDcsIDIzNiwgMjEzLCAyMzYsIDIxNCwgMjM2LCAyMjgsIDIzNiwgMjE5LAorMTc3LCAxNzIsIDIzNiwgMjI0LCAxOTgsIDE3MiwgMjM0LCAyNDMsIDIzNCwgMjQ3LCAyMDAsIDE3NCwgMjI1LCAyNDMsIDE4MiwgMTkyLAorMjI2LCAxNjUsIDIwOCwgMjAxLCAyMjYsIDE3NiwgMjI2LCAxNzksIDIwNSwgMjQ1LCAyMDUsIDIzMCwgMjMxLCAyMzYsIDIzMSwgMjQyLAorMTkyLCAxOTcsIDIzMSwgMjUwLCAyMzIsIDE2NiwgMjA5LCAyNTQsIDIzMiwgMTcxLCAyMzIsIDE4MywgMTg1LCAyMDcsIDIzNCwgMTc5LAorMjAxLCAyNTAsIDIzMSwgMjIyLCAyMDgsIDI0MywgMjMxLCAyMjAsIDI0MCwgMjIyLCAyMDQsIDIxOSwgMjA1LCAxODAsIDE3NywgMjEyLAorMjQwLCAyNDksIDI0MSwgMTY5LCAyNDEsIDE3NSwgMTg1LCAyMzksIDIwNSwgMjM4LCAyNDEsIDIyOSwgMTg2LCAyMDgsIDIzNywgMjM2LAorMjM3LCAyNDQsIDE5MCwgMjM2LCAyMzcsIDI1MywgMTgyLCAxOTUsIDIzOCwgMTY5LCAyMzgsIDE3MywgMTk1LCAxNzIsIDIwNiwgMjQ5LAorMjM3LCAxOTEsIDIzNywgMTk0LCAyMDcsIDI0NSwgMTk3LCAyNDAsIDIzNywgMjEzLCAyMzcsIDIxOSwgMjM3LCAyMjIsIDE5MywgMjE1LAorMjM3LCAyMzAsIDE5MiwgMjQxLCAyMzYsIDI0MSwgMTg3LCAyNDYsIDIzNiwgMjUwLCAyMTEsIDIzNywgMTk1LCAyMTYsIDE4OSwgMjEzLAorMTc2LCAyMjIsIDI0MCwgMTYyLCAyMDMsIDIzNSwgMTkwLCAxOTEsIDI0MSwgMTg3LCAyNDEsIDE5MywgMjAyLCAyNTAsIDIxNCwgMjQxLAorMjQzLCAyMDcsIDI0MywgMjA1LCAxNzgsIDIyMywgMjQzLCAyMTksIDE3OCwgMTczLCAyNDMsIDI0MCwgMTk0LCAxNjgsIDE5MiwgMjMzLAorMjQzLCAyNTIsIDI0NCwgMTY0LCAxOTUsIDIxNSwgMjQ0LCAyMDYsIDE5MywgMTg3LCAxODQsIDIyNiwgMjQ0LCAyMzMsIDIwMywgMjE2LAorMjA4LCAyNDUsIDI0NCwgMjM1LCAyNDcsIDIyNywgMjE1LCAyMzUsIDE5MCwgMTkyLCAyMzEsIDE2MywgMTk0LCAyMzEsIDIzMSwgMTg0LAorMjEyLCAxODEsIDI0MywgMTkwLCAyMTYsIDIzMiwgMjAyLCAyNDAsIDE4NCwgMjI1LCAyNDQsIDIwMywgMjA3LCAyMzIsIDI0NCwgMjMyLAorMjQxLCAyMzEsIDI0MSwgMjQyLCAyNDEsIDI0OCwgMjQxLCAyNTAsIDIzNSwgMTkzLCAyMzUsIDE5NywgMTk3LCAyMTQsIDIzNSwgMjE2LAorMjM1LCAyMjMsIDIwNSwgMjA5LCAxODQsIDE3NSwgMjAwLCAyNDksIDE4NCwgMjI0LCAyMDEsIDE5NywgMTc5LCAxODgsIDI0NCwgMTY4LAorMjE0LCAyMTksIDI0NCwgMTg0LCAyNDQsIDE5MCwgMjIwLCAxODAsIDIwNiwgMjIzLCAyMDksIDE5MSwgMTkxLCAxOTMsIDE5OCwgMTg3LAorMjIwLCAyNDgsIDIxMCwgMjQwLCAxOTIsIDI0MywgMTg2LCAyMDEsIDIyMSwgMTgzLCAyMjEsIDE3OCwgMjIxLCAyMDIsIDE4MywgMTk4LAorMjIxLCAyMDAsIDIyMSwgMjMwLCAyMjEsIDIxNSwgMTgwLCAyMDgsIDIyMSwgMjQ1LCAyMTMsIDI0NCwgMTc3LCAyMDUsIDIyMiwgMTY0LAorMjA2LCAxODEsIDIyMSwgMjUwLCAyMjIsIDE2MSwgMjEyLCAyMDQsIDIwOSwgMTY2LCAyMjIsIDE4MywgMjIyLCAxODgsIDIxMiwgMjI5LAorMjIyLCAxOTAsIDI0MiwgMTc0LCAxNzksIDIzMCwgMjA2LCAxOTUsIDI0MiwgMTgyLCAxOTksIDI0OSwgMTg0LCAyNDIsIDE4MywgMjI4LAorMTkyLCAxNzUsIDI0MiwgMjM0LCAyNDIsIDI0MCwgMjQyLCAyMzgsIDE5NSwgMjQ4LCAyNDMsIDE3NCwgMjQzLCAxNzgsIDIwOCwgMTgzLAorMjQzLCAxODYsIDI0MywgMTg4LCAxODksIDIxNCwgMjE0LCAyMTIsIDIwOCwgMjI4LCAyNDEsIDIwMiwgMjEyLCAxNjMsIDIwMSwgMjA5LAorMTc2LCAyNTMsIDIyOSwgMTg5LCAyNDQsIDE5NywgMjA2LCAyNDcsIDE4OCwgMjUxLCAxODksIDIyNiwgMjE3LCAyMzQsIDI0NiwgMTY0LAorMjEzLCAxNzgsIDIyOSwgMTkyLCAyNDYsIDE2NSwgMTkwLCAxNzUsIDIxOCwgMTY1LCAyMDEsIDIzMiwgMjE4LCAxODMsIDE5NywgMTgxLAorMjE4LCAyMDksIDIxOCwgMjIzLCAyNDUsIDE4NSwgMjI1LCAyMTcsIDI0NSwgMjQ5LCAxNzcsIDE4MCwgMjM0LCAyMjEsIDIzNCwgMjMxLAorMTk4LCAyNDAsIDIwNCwgMjAzLCAyMTQsIDE4NiwgMTkwLCAyMjQsIDI0NSwgMjEwLCAyNDUsIDIxNSwgMjQ1LCAyMjUsIDE3NywgMTk2LAorMjQ1LCAyMzgsIDIwMSwgMjM3LCAyMzQsIDE2NiwgMTc5LCAxODEsIDIzMywgMjUyLCAxOTIsIDE3NywgMTk5LCAxNjgsIDE3OSwgMjE3LAorMjE1LCAxODMsIDE4NSwgMjI4LCAxOTQsIDIyMywgMjI5LCAyMjIsIDIyOSwgMjI1LCAyMTgsIDI0NiwgMjE1LCAyMjIsIDIxOSwgMTczLAorMTgxLCAxNjYsIDE3NywgMjAxLCAyMTksIDE4NCwgMjA4LCAyMzksIDE4OSwgMjA1LCAxOTUsIDIwOSwgMjQ1LCAxODQsIDE4NCwgMTcwLAorMTg4LCAyNDgsIDI0NiwgMTk5LCAyNDYsIDIwMSwgMjQ2LCAyMDIsIDI0NiwgMjA0LCAyNDYsIDIwMywgMjQ2LCAyMDUsIDI0NiwgMjA2LAorMTgyLCAxNjQsIDE5MCwgMjUxLCAxOTksIDE2NiwgMjA3LCAxNzksIDIwMywgMjQ4LCAyMzksIDE5MSwgMjM5LCAyMDQsIDE5MCwgMTgxLAorMTc5LCAxNjQsIDE5NSwgMTk3LCAyMjcsIDIwNywgMjE4LCAyMzAsIDE3OSwgMTk0LCAyMTgsIDIzNywgMjExLCAyMzEsIDIwMywgMjM3LAorMjA5LCAxOTcsIDIxMSwgMjM0LCAyNDYsIDE3MCwgMjQ2LCAxNzUsIDE5OSwgMjI0LCAxODksIDI0OSwgMjQ3LCAxNzgsIDI0NywgMTgxLAorMjA2LCAxNjQsIDIxMCwgMTc5LCAyMDUsIDE5OSwgMTgzLCAyMzEsIDI0NywgMjA4LCAyNDcsIDIwOSwgMjQ3LCAyMTEsIDIwMywgMTk5LAorMjI2LCAyMDIsIDE5NCwgMjM3LCAyMzAsIDIzNCwgMTg1LCAxOTksIDI0NywgMTk3LCAyNDcsIDIxNiwgMjQ3LCAyMjEsIDIxOSwgMjAzLAorMjQ3LCAyMDUsIDIxMSwgMjI3LCAyNDYsIDIyMSwgMTkwLCAxNjgsIDE3NywgMjM4LCAxOTYsIDI0MSwgMTg0LCAyMzUsIDI0MCwgMjA0LAorMjQ1LCAxODYsIDI0NywgMjM0LCAxOTQsIDIzMywgMjQ3LCAyMzYsIDIzNywgMjMzLCAyMTYsIDE4NywgMjQ3LCAyNTEsIDE3OSwgMjIxLAorMTg1LCAyMzQsIDE2MywgMTYxLCAxNjMsIDE5MSwgMTYzLCAyMjEsIDE2MywgMjUxLCAxNjEsIDIzMworICAgICAgICAgICAgfSk7CisKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvZGVjRHluYW1pYygpIHRocm93cyBDaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb24geworICAgICAgICBzdXBlci50ZXN0X0NvZGVjRHluYW1pYygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHRlc3RfRGVjb2RlKCkgdGhyb3dzIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlc3RfRGVjb2RlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgdGVzdF9FbmNvZGUoKSB0aHJvd3MgQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVzdF9FbmNvZGUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X25hbWVNYXRjaCgpIHsKKyAgICAgICAgc3VwZXIudGVzdF9uYW1lTWF0Y2goKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9NdWx0aUJ5dGVfR0JLLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX0dCSy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhkZTE4MWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX0dCSy5qYXZhCkBAIC0wLDAgKzEsNTExIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKKy8qKiBAaGlkZQorICogU0VFIGNvcnJlc3BvbmRpZ19BbmRyb2lkIHRlc3QgY2xhc3M6CisgKi8KKworcHVibGljIGNsYXNzIE9sZENoYXJzZXRfTXVsdGlCeXRlX0dCSyBleHRlbmRzIE9sZENoYXJzZXRfQWJzdHJhY3RUZXN0IHsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJzZXROYW1lID0gIkdCSyI7CisgICAgICAgIHRlc3RDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKzE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCis0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKzY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCis5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKzExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKzE2NCwgMTY3LCAxNjgsIDE3NiwgMTc3LCAxODMsIDIxNSwgMjI0LCAyMjUsIDIzMiwgMjMzLCAyMzQsIDIzNiwgMjM3LCAyNDIsIDI0MywKKzI0NywgMjQ5LCAyNTAsIDI1MiwgMjU3LCAyNzUsIDI5OSwgMzI0LCAzNjMsIDQ2MiwgNDcyLCA1OTMsIDYwOSwgNzExLCA3MjksIDkxMywKKzkyMywgOTMzLCA5NDUsIDk1NSwgOTY1LCAxMDI1LCAxMDQwLCAxMDUwLCAxMDYwLCAxMDcwLCAxMDgwLCAxMDkwLCAxMTAwLCA4MjA4LCA4MjIwLCA4MjMwLAorODI0MCwgODI1MSwgODQ1MSwgODQ3MCwgODQ4MSwgODU0NCwgODU1NCwgODU2NCwgODU5MiwgODcxMiwgODcyNSwgODczNSwgODc0NSwgODc1NiwgODc3NiwgODc4NiwKKzg4MDAsIDg4MTQsIDg4NTcsIDg4NjksIDg4OTUsIDg5NzgsIDkzMTIsIDkzMzIsIDkzNDIsIDkzNTIsIDkzNjIsIDk0NzIsIDk0ODIsIDk0OTIsIDk1MDIsIDk1MTIsCis5NTIyLCA5NTMyLCA5NTQyLCA5NTUyLCA5NTYyLCA5NTcyLCA5NTgyLCA5NjAxLCA5NjExLCA5NjIxLCA5NjMyLCA5NjUwLCA5NjYwLCA5NjcwLCA5Njk4LCA5NzMzLAorOTc5MiwgMTIyODgsIDEyMjk4LCAxMjMwOCwgMTIzMTgsIDEyMzI4LCAxMjM1MywgMTIzNjMsIDEyMzczLCAxMjM4MywgMTIzOTMsIDEyNDAzLCAxMjQxMywgMTI0MjMsIDEyNDMzLCAxMjQ0MywKKzEyNDUzLCAxMjQ2MywgMTI0NzMsIDEyNDgzLCAxMjQ5MywgMTI1MDMsIDEyNTEzLCAxMjUyMywgMTI1MzMsIDEyNTQ5LCAxMjU1OSwgMTI1NjksIDEyNTc5LCAxMjgzMiwgMTI4NDksIDEyOTYzLAorMTMxOTgsIDEzMjEyLCAxMzI1MiwgMTMyNjIsIDE5OTY4LCAxOTk3OCwgMTk5ODgsIDE5OTk4LCAyMDAwOCwgMjAwMTgsIDIwMDI4LCAyMDAzOCwgMjAwNDgsIDIwMDU4LCAyMDA2OCwgMjAwNzgsCisyMDA4OCwgMjAwOTgsIDIwMTA4LCAyMDExOCwgMjAxMjgsIDIwMTM4LCAyMDE0OCwgMjAxNTgsIDIwMTY4LCAyMDE3OCwgMjAxODgsIDIwMTk4LCAyMDIwOCwgMjAyMTgsIDIwMjI4LCAyMDIzOCwKKzIwMjQ4LCAyMDI1OCwgMjAyNjgsIDIwMjc4LCAyMDI4OCwgMjAyOTgsIDIwMzA4LCAyMDMxOCwgMjAzMjgsIDIwMzM4LCAyMDM0OCwgMjAzNTgsIDIwMzY4LCAyMDM3OCwgMjAzODgsIDIwMzk4LAorMjA0MDgsIDIwNDE4LCAyMDQyOCwgMjA0MzgsIDIwNDQ4LCAyMDQ1OCwgMjA0NjgsIDIwNDc4LCAyMDQ4OCwgMjA0OTgsIDIwNTA4LCAyMDUxOCwgMjA1MjgsIDIwNTM4LCAyMDU0OCwgMjA1NTgsCisyMDU2OCwgMjA1NzgsIDIwNTg4LCAyMDU5OCwgMjA2MDgsIDIwNjE4LCAyMDYyOCwgMjA2MzgsIDIwNjQ4LCAyMDY1OCwgMjA2NjgsIDIwNjc4LCAyMDY4OCwgMjA2OTgsIDIwNzA4LCAyMDcxOCwKKzIwNzI4LCAyMDczOCwgMjA3NDgsIDIwNzU4LCAyMDc2OCwgMjA3NzgsIDIwNzg4LCAyMDc5OCwgMjA4MDgsIDIwODE4LCAyMDgyOCwgMjA4MzgsIDIwODQ4LCAyMDg1OCwgMjA4NjgsIDIwODc4LAorMjA4ODgsIDIwODk4LCAyMDkwOCwgMjA5MTgsIDIwOTI4LCAyMDkzOCwgMjA5NDgsIDIwOTU4LCAyMDk2OCwgMjA5NzgsIDIwOTg4LCAyMDk5OCwgMjEwMDgsIDIxMDE4LCAyMTAyOCwgMjEwMzgsCisyMTA0OCwgMjEwNTgsIDIxMDY4LCAyMTA3OCwgMjEwODgsIDIxMDk4LCAyMTEwOCwgMjExMTgsIDIxMTI4LCAyMTEzOCwgMjExNDgsIDIxMTU4LCAyMTE2OCwgMjExNzgsIDIxMTg4LCAyMTE5OCwKKzIxMjA4LCAyMTIxOCwgMjEyMjgsIDIxMjM4LCAyMTI0OCwgMjEyNTgsIDIxMjY4LCAyMTI3OCwgMjEyODgsIDIxMjk4LCAyMTMwOCwgMjEzMTgsIDIxMzI4LCAyMTMzOCwgMjEzNDgsIDIxMzU4LAorMjEzNjgsIDIxMzc4LCAyMTM4OCwgMjEzOTgsIDIxNDA4LCAyMTQxOCwgMjE0MjgsIDIxNDM4LCAyMTQ0OCwgMjE0NTgsIDIxNDY4LCAyMTQ3OCwgMjE0ODgsIDIxNDk4LCAyMTUwOCwgMjE1MTgsCisyMTUyOCwgMjE1MzgsIDIxNTQ4LCAyMTU1OCwgMjE1NjgsIDIxNTc4LCAyMTU4OCwgMjE1OTgsIDIxNjA4LCAyMTYxOCwgMjE2MjgsIDIxNjM4LCAyMTY0OCwgMjE2NTgsIDIxNjY4LCAyMTY3OCwKKzIxNjg4LCAyMTY5OCwgMjE3MDgsIDIxNzE4LCAyMTcyOCwgMjE3MzgsIDIxNzQ4LCAyMTc1OCwgMjE3NjgsIDIxNzc4LCAyMTc4OCwgMjE3OTgsIDIxODA4LCAyMTgxOCwgMjE4MjgsIDIxODM4LAorMjE4NDgsIDIxODU4LCAyMTg2OCwgMjE4NzgsIDIxODg4LCAyMTg5OCwgMjE5MDgsIDIxOTE4LCAyMTkyOCwgMjE5MzgsIDIxOTQ4LCAyMTk1OCwgMjE5NjgsIDIxOTc4LCAyMTk4OCwgMjE5OTgsCisyMjAwOCwgMjIwMTgsIDIyMDI4LCAyMjAzOCwgMjIwNDgsIDIyMDU4LCAyMjA2OCwgMjIwNzgsIDIyMDg4LCAyMjA5OCwgMjIxMDgsIDIyMTE4LCAyMjEyOCwgMjIxMzgsIDIyMTQ4LCAyMjE1OCwKKzIyMTY4LCAyMjE3OCwgMjIxODgsIDIyMTk4LCAyMjIwOCwgMjIyMTgsIDIyMjI4LCAyMjIzOCwgMjIyNDgsIDIyMjU4LCAyMjI2OCwgMjIyNzgsIDIyMjg4LCAyMjI5OCwgMjIzMDgsIDIyMzE4LAorMjIzMjgsIDIyMzM4LCAyMjM0OCwgMjIzNTgsIDIyMzY4LCAyMjM3OCwgMjIzODgsIDIyMzk4LCAyMjQwOCwgMjI0MTgsIDIyNDI4LCAyMjQzOCwgMjI0NDgsIDIyNDU4LCAyMjQ2OCwgMjI0NzgsCisyMjQ4OCwgMjI0OTgsIDIyNTA4LCAyMjUxOCwgMjI1MjgsIDIyNTM4LCAyMjU0OCwgMjI1NTgsIDIyNTY4LCAyMjU3OCwgMjI1ODgsIDIyNTk4LCAyMjYwOCwgMjI2MTgsIDIyNjI4LCAyMjYzOCwKKzIyNjQ4LCAyMjY1OCwgMjI2NjgsIDIyNjc4LCAyMjY4OCwgMjI2OTgsIDIyNzA4LCAyMjcxOCwgMjI3MjgsIDIyNzM4LCAyMjc0OCwgMjI3NTgsIDIyNzY4LCAyMjc3OCwgMjI3ODgsIDIyNzk4LAorMjI4MDgsIDIyODE4LCAyMjgyOCwgMjI4MzgsIDIyODQ4LCAyMjg1OCwgMjI4NjgsIDIyODc4LCAyMjg4OCwgMjI4OTgsIDIyOTA4LCAyMjkxOCwgMjI5MjgsIDIyOTM4LCAyMjk0OCwgMjI5NTgsCisyMjk2OCwgMjI5NzgsIDIyOTg4LCAyMjk5OCwgMjMwMDgsIDIzMDE4LCAyMzAyOCwgMjMwMzgsIDIzMDQ4LCAyMzA1OCwgMjMwNjgsIDIzMDc4LCAyMzA4OCwgMjMwOTgsIDIzMTA4LCAyMzExOCwKKzIzMTI4LCAyMzEzOCwgMjMxNDgsIDIzMTU4LCAyMzE2OCwgMjMxNzgsIDIzMTg4LCAyMzE5OCwgMjMyMDgsIDIzMjE4LCAyMzIyOCwgMjMyMzgsIDIzMjQ4LCAyMzI1OCwgMjMyNjgsIDIzMjc4LAorMjMyODgsIDIzMjk4LCAyMzMwOCwgMjMzMTgsIDIzMzI4LCAyMzMzOCwgMjMzNDgsIDIzMzU4LCAyMzM2OCwgMjMzNzgsIDIzMzg4LCAyMzM5OCwgMjM0MDgsIDIzNDE4LCAyMzQyOCwgMjM0MzgsCisyMzQ0OCwgMjM0NTgsIDIzNDY4LCAyMzQ3OCwgMjM0ODgsIDIzNDk4LCAyMzUwOCwgMjM1MTgsIDIzNTI4LCAyMzUzOCwgMjM1NDgsIDIzNTU4LCAyMzU2OCwgMjM1NzgsIDIzNTg4LCAyMzU5OCwKKzIzNjA4LCAyMzYxOCwgMjM2MjgsIDIzNjM4LCAyMzY0OCwgMjM2NTgsIDIzNjY4LCAyMzY3OCwgMjM2ODgsIDIzNjk4LCAyMzcwOCwgMjM3MTgsIDIzNzI4LCAyMzczOCwgMjM3NDgsIDIzNzU4LAorMjM3NjgsIDIzNzc4LCAyMzc4OCwgMjM3OTgsIDIzODA4LCAyMzgxOCwgMjM4MjgsIDIzODM4LCAyMzg0OCwgMjM4NTgsIDIzODY4LCAyMzg3OCwgMjM4ODgsIDIzODk4LCAyMzkwOCwgMjM5MTgsCisyMzkyOCwgMjM5MzgsIDIzOTQ4LCAyMzk1OCwgMjM5NjgsIDIzOTc4LCAyMzk4OCwgMjM5OTgsIDI0MDA4LCAyNDAxOCwgMjQwMjgsIDI0MDM4LCAyNDA0OCwgMjQwNTgsIDI0MDY4LCAyNDA3OCwKKzI0MDg4LCAyNDA5OCwgMjQxMDgsIDI0MTE4LCAyNDEyOCwgMjQxMzgsIDI0MTQ4LCAyNDE1OCwgMjQxNjgsIDI0MTc4LCAyNDE4OCwgMjQxOTgsIDI0MjA4LCAyNDIxOCwgMjQyMjgsIDI0MjM4LAorMjQyNDgsIDI0MjU4LCAyNDI2OCwgMjQyNzgsIDI0Mjg4LCAyNDI5OCwgMjQzMDgsIDI0MzE4LCAyNDMyOCwgMjQzMzgsIDI0MzQ4LCAyNDM1OCwgMjQzNjgsIDI0Mzc4LCAyNDM4OCwgMjQzOTgsCisyNDQwOCwgMjQ0MTgsIDI0NDI4LCAyNDQzOCwgMjQ0NDgsIDI0NDU4LCAyNDQ2OCwgMjQ0NzgsIDI0NDg4LCAyNDQ5OCwgMjQ1MDgsIDI0NTE4LCAyNDUyOCwgMjQ1MzgsIDI0NTQ4LCAyNDU1OCwKKzI0NTY4LCAyNDU3OCwgMjQ1ODgsIDI0NTk4LCAyNDYwOCwgMjQ2MTgsIDI0NjI4LCAyNDYzOCwgMjQ2NDgsIDI0NjU4LCAyNDY2OCwgMjQ2NzgsIDI0Njg4LCAyNDY5OCwgMjQ3MDgsIDI0NzE4LAorMjQ3MjgsIDI0NzM4LCAyNDc0OCwgMjQ3NTgsIDI0NzY4LCAyNDc3OCwgMjQ3ODgsIDI0Nzk4LCAyNDgwOCwgMjQ4MTgsIDI0ODI4LCAyNDgzOCwgMjQ4NDgsIDI0ODU4LCAyNDg2OCwgMjQ4NzgsCisyNDg4OCwgMjQ4OTgsIDI0OTA4LCAyNDkxOCwgMjQ5MjgsIDI0OTM4LCAyNDk0OCwgMjQ5NTgsIDI0OTY4LCAyNDk3OCwgMjQ5ODgsIDI0OTk4LCAyNTAwOCwgMjUwMTgsIDI1MDI4LCAyNTAzOCwKKzI1MDQ4LCAyNTA1OCwgMjUwNjgsIDI1MDc4LCAyNTA4OCwgMjUwOTgsIDI1MTA4LCAyNTExOCwgMjUxMjgsIDI1MTM4LCAyNTE0OCwgMjUxNTgsIDI1MTY4LCAyNTE3OCwgMjUxODgsIDI1MTk4LAorMjUyMDgsIDI1MjE4LCAyNTIyOCwgMjUyMzgsIDI1MjQ4LCAyNTI1OCwgMjUyNjgsIDI1Mjc4LCAyNTI4OCwgMjUyOTgsIDI1MzA4LCAyNTMxOCwgMjUzMjgsIDI1MzM4LCAyNTM0OCwgMjUzNTgsCisyNTM2OCwgMjUzNzgsIDI1Mzg4LCAyNTM5OCwgMjU0MDgsIDI1NDE4LCAyNTQyOCwgMjU0MzgsIDI1NDQ4LCAyNTQ1OCwgMjU0NjgsIDI1NDc4LCAyNTQ4OCwgMjU0OTgsIDI1NTA4LCAyNTUxOCwKKzI1NTI4LCAyNTUzOCwgMjU1NDgsIDI1NTU4LCAyNTU2OCwgMjU1NzgsIDI1NTg4LCAyNTU5OCwgMjU2MDgsIDI1NjE4LCAyNTYyOCwgMjU2MzgsIDI1NjQ4LCAyNTY1OCwgMjU2NjgsIDI1Njc4LAorMjU2ODgsIDI1Njk4LCAyNTcwOCwgMjU3MTgsIDI1NzI4LCAyNTczOCwgMjU3NDgsIDI1NzU4LCAyNTc2OCwgMjU3NzgsIDI1Nzg4LCAyNTc5OCwgMjU4MDgsIDI1ODE4LCAyNTgyOCwgMjU4MzgsCisyNTg0OCwgMjU4NTgsIDI1ODY4LCAyNTg3OCwgMjU4ODgsIDI1ODk4LCAyNTkwOCwgMjU5MTgsIDI1OTI4LCAyNTkzOCwgMjU5NDgsIDI1OTU4LCAyNTk2OCwgMjU5NzgsIDI1OTg4LCAyNTk5OCwKKzI2MDA4LCAyNjAxOCwgMjYwMjgsIDI2MDM4LCAyNjA0OCwgMjYwNTgsIDI2MDY4LCAyNjA3OCwgMjYwODgsIDI2MDk4LCAyNjEwOCwgMjYxMTgsIDI2MTI4LCAyNjEzOCwgMjYxNDgsIDI2MTU4LAorMjYxNjgsIDI2MTc4LCAyNjE4OCwgMjYxOTgsIDI2MjA4LCAyNjIxOCwgMjYyMjgsIDI2MjM4LCAyNjI0OCwgMjYyNTgsIDI2MjY4LCAyNjI3OCwgMjYyODgsIDI2Mjk4LCAyNjMwOCwgMjYzMTgsCisyNjMyOCwgMjYzMzgsIDI2MzQ4LCAyNjM1OCwgMjYzNjgsIDI2Mzc4LCAyNjM4OCwgMjYzOTgsIDI2NDA4LCAyNjQxOCwgMjY0MjgsIDI2NDM4LCAyNjQ0OCwgMjY0NTgsIDI2NDY4LCAyNjQ3OCwKKzI2NDg4LCAyNjQ5OCwgMjY1MDgsIDI2NTE4LCAyNjUyOCwgMjY1MzgsIDI2NTQ4LCAyNjU1OCwgMjY1NjgsIDI2NTc4LCAyNjU4OCwgMjY1OTgsIDI2NjA4LCAyNjYxOCwgMjY2MjgsIDI2NjM4LAorMjY2NDgsIDI2NjU4LCAyNjY2OCwgMjY2NzgsIDI2Njg4LCAyNjY5OCwgMjY3MDgsIDI2NzE4LCAyNjcyOCwgMjY3MzgsIDI2NzQ4LCAyNjc1OCwgMjY3NjgsIDI2Nzc4LCAyNjc4OCwgMjY3OTgsCisyNjgwOCwgMjY4MTgsIDI2ODI4LCAyNjgzOCwgMjY4NDgsIDI2ODU4LCAyNjg2OCwgMjY4NzgsIDI2ODg4LCAyNjg5OCwgMjY5MDgsIDI2OTE4LCAyNjkyOCwgMjY5MzgsIDI2OTQ4LCAyNjk1OCwKKzI2OTY4LCAyNjk3OCwgMjY5ODgsIDI2OTk4LCAyNzAwOCwgMjcwMTgsIDI3MDI4LCAyNzAzOCwgMjcwNDgsIDI3MDU4LCAyNzA2OCwgMjcwNzgsIDI3MDg4LCAyNzA5OCwgMjcxMDgsIDI3MTE4LAorMjcxMjgsIDI3MTM4LCAyNzE0OCwgMjcxNTgsIDI3MTY4LCAyNzE3OCwgMjcxODgsIDI3MTk4LCAyNzIwOCwgMjcyMTgsIDI3MjI4LCAyNzIzOCwgMjcyNDgsIDI3MjU4LCAyNzI2OCwgMjcyNzgsCisyNzI4OCwgMjcyOTgsIDI3MzA4LCAyNzMxOCwgMjczMjgsIDI3MzM4LCAyNzM0OCwgMjczNTgsIDI3MzY4LCAyNzM3OCwgMjczODgsIDI3Mzk4LCAyNzQwOCwgMjc0MTgsIDI3NDI4LCAyNzQzOCwKKzI3NDQ4LCAyNzQ1OCwgMjc0NjgsIDI3NDc4LCAyNzQ4OCwgMjc0OTgsIDI3NTA4LCAyNzUxOCwgMjc1MjgsIDI3NTM4LCAyNzU0OCwgMjc1NTgsIDI3NTY4LCAyNzU3OCwgMjc1ODgsIDI3NTk4LAorMjc2MDgsIDI3NjE4LCAyNzYyOCwgMjc2MzgsIDI3NjQ4LCAyNzY1OCwgMjc2NjgsIDI3Njc4LCAyNzY4OCwgMjc2OTgsIDI3NzA4LCAyNzcxOCwgMjc3MjgsIDI3NzM4LCAyNzc0OCwgMjc3NTgsCisyNzc2OCwgMjc3NzgsIDI3Nzg4LCAyNzc5OCwgMjc4MDgsIDI3ODE4LCAyNzgyOCwgMjc4MzgsIDI3ODQ4LCAyNzg1OCwgMjc4NjgsIDI3ODc4LCAyNzg4OCwgMjc4OTgsIDI3OTA4LCAyNzkxOCwKKzI3OTI4LCAyNzkzOCwgMjc5NDgsIDI3OTU4LCAyNzk2OCwgMjc5NzgsIDI3OTg4LCAyNzk5OCwgMjgwMDgsIDI4MDE4LCAyODAyOCwgMjgwMzgsIDI4MDQ4LCAyODA1OCwgMjgwNjgsIDI4MDc4LAorMjgwODgsIDI4MDk4LCAyODEwOCwgMjgxMTgsIDI4MTI4LCAyODEzOCwgMjgxNDgsIDI4MTU4LCAyODE2OCwgMjgxNzgsIDI4MTg4LCAyODE5OCwgMjgyMDgsIDI4MjE4LCAyODIyOCwgMjgyMzgsCisyODI0OCwgMjgyNTgsIDI4MjY4LCAyODI3OCwgMjgyODgsIDI4Mjk4LCAyODMwOCwgMjgzMTgsIDI4MzI4LCAyODMzOCwgMjgzNDgsIDI4MzU4LCAyODM2OCwgMjgzNzgsIDI4Mzg4LCAyODM5OCwKKzI4NDA4LCAyODQxOCwgMjg0MjgsIDI4NDM4LCAyODQ0OCwgMjg0NTgsIDI4NDY4LCAyODQ3OCwgMjg0ODgsIDI4NDk4LCAyODUwOCwgMjg1MTgsIDI4NTI4LCAyODUzOCwgMjg1NDgsIDI4NTU4LAorMjg1NjgsIDI4NTc4LCAyODU4OCwgMjg1OTgsIDI4NjA4LCAyODYxOCwgMjg2MjgsIDI4NjM4LCAyODY0OCwgMjg2NTgsIDI4NjY4LCAyODY3OCwgMjg2ODgsIDI4Njk4LCAyODcwOCwgMjg3MTgsCisyODcyOCwgMjg3MzgsIDI4NzQ4LCAyODc1OCwgMjg3NjgsIDI4Nzc4LCAyODc4OCwgMjg3OTgsIDI4ODA4LCAyODgxOCwgMjg4MjgsIDI4ODM4LCAyODg0OCwgMjg4NTgsIDI4ODY4LCAyODg3OCwKKzI4ODg4LCAyODg5OCwgMjg5MDgsIDI4OTE4LCAyODkyOCwgMjg5MzgsIDI4OTQ4LCAyODk1OCwgMjg5NjgsIDI4OTc4LCAyODk4OCwgMjg5OTgsIDI5MDA4LCAyOTAxOCwgMjkwMjgsIDI5MDM4LAorMjkwNDgsIDI5MDU4LCAyOTA2OCwgMjkwNzgsIDI5MDg4LCAyOTA5OCwgMjkxMDgsIDI5MTE4LCAyOTEyOCwgMjkxMzgsIDI5MTQ4LCAyOTE1OCwgMjkxNjgsIDI5MTc4LCAyOTE4OCwgMjkxOTgsCisyOTIwOCwgMjkyMTgsIDI5MjI4LCAyOTIzOCwgMjkyNDgsIDI5MjU4LCAyOTI2OCwgMjkyNzgsIDI5Mjg4LCAyOTI5OCwgMjkzMDgsIDI5MzE4LCAyOTMyOCwgMjkzMzgsIDI5MzQ4LCAyOTM1OCwKKzI5MzY4LCAyOTM3OCwgMjkzODgsIDI5Mzk4LCAyOTQwOCwgMjk0MTgsIDI5NDI4LCAyOTQzOCwgMjk0NDgsIDI5NDU4LCAyOTQ2OCwgMjk0NzgsIDI5NDg4LCAyOTQ5OCwgMjk1MDgsIDI5NTE4LAorMjk1MjgsIDI5NTM4LCAyOTU0OCwgMjk1NTgsIDI5NTY4LCAyOTU3OCwgMjk1ODgsIDI5NTk4LCAyOTYwOCwgMjk2MTgsIDI5NjI4LCAyOTYzOCwgMjk2NDgsIDI5NjU4LCAyOTY2OCwgMjk2NzgsCisyOTY4OCwgMjk2OTgsIDI5NzA4LCAyOTcxOCwgMjk3MjgsIDI5NzM4LCAyOTc0OCwgMjk3NTgsIDI5NzY4LCAyOTc3OCwgMjk3ODgsIDI5Nzk4LCAyOTgwOCwgMjk4MTgsIDI5ODI4LCAyOTgzOCwKKzI5ODQ4LCAyOTg1OCwgMjk4NjgsIDI5ODc4LCAyOTg4OCwgMjk4OTgsIDI5OTA4LCAyOTkxOCwgMjk5MjgsIDI5OTM4LCAyOTk0OCwgMjk5NTgsIDI5OTY4LCAyOTk3OCwgMjk5ODgsIDI5OTk4LAorMzAwMDgsIDMwMDE4LCAzMDAyOCwgMzAwMzgsIDMwMDQ4LCAzMDA1OCwgMzAwNjgsIDMwMDc4LCAzMDA4OCwgMzAwOTgsIDMwMTA4LCAzMDExOCwgMzAxMjgsIDMwMTM4LCAzMDE0OCwgMzAxNTgsCiszMDE2OCwgMzAxNzgsIDMwMTg4LCAzMDE5OCwgMzAyMDgsIDMwMjE4LCAzMDIyOCwgMzAyMzgsIDMwMjQ4LCAzMDI1OCwgMzAyNjgsIDMwMjc4LCAzMDI4OCwgMzAyOTgsIDMwMzA4LCAzMDMxOCwKKzMwMzI4LCAzMDMzOCwgMzAzNDgsIDMwMzU4LCAzMDM2OCwgMzAzNzgsIDMwMzg4LCAzMDM5OCwgMzA0MDgsIDMwNDE4LCAzMDQyOCwgMzA0MzgsIDMwNDQ4LCAzMDQ1OCwgMzA0NjgsIDMwNDc4LAorMzA0ODgsIDMwNDk4LCAzMDUwOCwgMzA1MTgsIDMwNTI4LCAzMDUzOCwgMzA1NDgsIDMwNTU4LCAzMDU2OCwgMzA1NzgsIDMwNTg4LCAzMDU5OCwgMzA2MDgsIDMwNjE4LCAzMDYyOCwgMzA2MzgsCiszMDY0OCwgMzA2NTgsIDMwNjY4LCAzMDY3OCwgMzA2ODgsIDMwNjk4LCAzMDcwOCwgMzA3MTgsIDMwNzI4LCAzMDczOCwgMzA3NDgsIDMwNzU4LCAzMDc2OCwgMzA3NzgsIDMwNzg4LCAzMDc5OCwKKzMwODA4LCAzMDgxOCwgMzA4MjgsIDMwODM4LCAzMDg0OCwgMzA4NTgsIDMwODY4LCAzMDg3OCwgMzA4ODgsIDMwODk4LCAzMDkwOCwgMzA5MTgsIDMwOTI4LCAzMDkzOCwgMzA5NDgsIDMwOTU4LAorMzA5NjgsIDMwOTc4LCAzMDk4OCwgMzA5OTgsIDMxMDA4LCAzMTAxOCwgMzEwMjgsIDMxMDM4LCAzMTA0OCwgMzEwNTgsIDMxMDY4LCAzMTA3OCwgMzEwODgsIDMxMDk4LCAzMTEwOCwgMzExMTgsCiszMTEyOCwgMzExMzgsIDMxMTQ4LCAzMTE1OCwgMzExNjgsIDMxMTc4LCAzMTE4OCwgMzExOTgsIDMxMjA4LCAzMTIxOCwgMzEyMjgsIDMxMjM4LCAzMTI0OCwgMzEyNTgsIDMxMjY4LCAzMTI3OCwKKzMxMjg4LCAzMTI5OCwgMzEzMDgsIDMxMzE4LCAzMTMyOCwgMzEzMzgsIDMxMzQ4LCAzMTM1OCwgMzEzNjgsIDMxMzc4LCAzMTM4OCwgMzEzOTgsIDMxNDA4LCAzMTQxOCwgMzE0MjgsIDMxNDM4LAorMzE0NDgsIDMxNDU4LCAzMTQ2OCwgMzE0NzgsIDMxNDg4LCAzMTQ5OCwgMzE1MDgsIDMxNTE4LCAzMTUyOCwgMzE1MzgsIDMxNTQ4LCAzMTU1OCwgMzE1NjgsIDMxNTc4LCAzMTU4OCwgMzE1OTgsCiszMTYwOCwgMzE2MTgsIDMxNjI4LCAzMTYzOCwgMzE2NDgsIDMxNjU4LCAzMTY2OCwgMzE2NzgsIDMxNjg4LCAzMTY5OCwgMzE3MDgsIDMxNzE4LCAzMTcyOCwgMzE3MzgsIDMxNzQ4LCAzMTc1OCwKKzMxNzY4LCAzMTc3OCwgMzE3ODgsIDMxNzk4LCAzMTgwOCwgMzE4MTgsIDMxODI4LCAzMTgzOCwgMzE4NDgsIDMxODU4LCAzMTg2OCwgMzE4NzgsIDMxODg4LCAzMTg5OCwgMzE5MDgsIDMxOTE4LAorMzE5MjgsIDMxOTM4LCAzMTk0OCwgMzE5NTgsIDMxOTY4LCAzMTk3OCwgMzE5ODgsIDMxOTk4LCAzMjAwOCwgMzIwMTgsIDMyMDI4LCAzMjAzOCwgMzIwNDgsIDMyMDU4LCAzMjA2OCwgMzIwNzgsCiszMjA4OCwgMzIwOTgsIDMyMTA4LCAzMjExOCwgMzIxMjgsIDMyMTM4LCAzMjE0OCwgMzIxNTgsIDMyMTY4LCAzMjE3OCwgMzIxODgsIDMyMTk4LCAzMjIwOCwgMzIyMTgsIDMyMjI4LCAzMjIzOCwKKzMyMjQ4LCAzMjI1OCwgMzIyNjgsIDMyMjc4LCAzMjI4OCwgMzIyOTgsIDMyMzA4LCAzMjMxOCwgMzIzMjgsIDMyMzM4LCAzMjM0OCwgMzIzNTgsIDMyMzY4LCAzMjM3OCwgMzIzODgsIDMyMzk4LAorMzI0MDgsIDMyNDE4LCAzMjQyOCwgMzI0MzgsIDMyNDQ4LCAzMjQ1OCwgMzI0NjgsIDMyNDc4LCAzMjQ4OCwgMzI0OTgsIDMyNTA4LCAzMjUxOCwgMzI1MjgsIDMyNTM4LCAzMjU0OCwgMzI1NTgsCiszMjU2OCwgMzI1NzgsIDMyNTg4LCAzMjU5OCwgMzI2MDgsIDMyNjE4LCAzMjYyOCwgMzI2MzgsIDMyNjQ4LCAzMjY1OCwgMzI2NjgsIDMyNjc4LCAzMjY4OCwgMzI2OTgsIDMyNzA4LCAzMjcxOCwKKzMyNzI4LCAzMjczOCwgMzI3NDgsIDMyNzU4LCAzMjc2OCwgMzI3NzgsIDMyNzg4LCAzMjc5OCwgMzI4MDgsIDMyODE4LCAzMjgyOCwgMzI4MzgsIDMyODQ4LCAzMjg1OCwgMzI4NjgsIDMyODc4LAorMzI4ODgsIDMyODk4LCAzMjkwOCwgMzI5MTgsIDMyOTI4LCAzMjkzOCwgMzI5NDgsIDMyOTU4LCAzMjk2OCwgMzI5NzgsIDMyOTg4LCAzMjk5OCwgMzMwMDgsIDMzMDE4LCAzMzAyOCwgMzMwMzgsCiszMzA0OCwgMzMwNTgsIDMzMDY4LCAzMzA3OCwgMzMwODgsIDMzMDk4LCAzMzEwOCwgMzMxMTgsIDMzMTI4LCAzMzEzOCwgMzMxNDgsIDMzMTU4LCAzMzE2OCwgMzMxNzgsIDMzMTg4LCAzMzE5OCwKKzMzMjA4LCAzMzIxOCwgMzMyMjgsIDMzMjM4LCAzMzI0OCwgMzMyNTgsIDMzMjY4LCAzMzI3OCwgMzMyODgsIDMzMjk4LCAzMzMwOCwgMzMzMTgsIDMzMzI4LCAzMzMzOCwgMzMzNDgsIDMzMzU4LAorMzMzNjgsIDMzMzc4LCAzMzM4OCwgMzMzOTgsIDMzNDA4LCAzMzQxOCwgMzM0MjgsIDMzNDM4LCAzMzQ0OCwgMzM0NTgsIDMzNDY4LCAzMzQ3OCwgMzM0ODgsIDMzNDk4LCAzMzUwOCwgMzM1MTgsCiszMzUyOCwgMzM1MzgsIDMzNTQ4LCAzMzU1OCwgMzM1NjgsIDMzNTc4LCAzMzU4OCwgMzM1OTgsIDMzNjA4LCAzMzYxOCwgMzM2MjgsIDMzNjM4LCAzMzY0OCwgMzM2NTgsIDMzNjY4LCAzMzY3OCwKKzMzNjg4LCAzMzY5OCwgMzM3MDgsIDMzNzE4LCAzMzcyOCwgMzM3MzgsIDMzNzQ4LCAzMzc1OCwgMzM3NjgsIDMzNzc4LCAzMzc4OCwgMzM3OTgsIDMzODA4LCAzMzgxOCwgMzM4MjgsIDMzODM4LAorMzM4NDgsIDMzODU4LCAzMzg2OCwgMzM4NzgsIDMzODg4LCAzMzg5OCwgMzM5MDgsIDMzOTE4LCAzMzkyOCwgMzM5MzgsIDMzOTQ4LCAzMzk1OCwgMzM5NjgsIDMzOTc4LCAzMzk4OCwgMzM5OTgsCiszNDAwOCwgMzQwMTgsIDM0MDI4LCAzNDAzOCwgMzQwNDgsIDM0MDU4LCAzNDA2OCwgMzQwNzgsIDM0MDg4LCAzNDA5OCwgMzQxMDgsIDM0MTE4LCAzNDEyOCwgMzQxMzgsIDM0MTQ4LCAzNDE1OCwKKzM0MTY4LCAzNDE3OCwgMzQxODgsIDM0MTk4LCAzNDIwOCwgMzQyMTgsIDM0MjI4LCAzNDIzOCwgMzQyNDgsIDM0MjU4LCAzNDI2OCwgMzQyNzgsIDM0Mjg4LCAzNDI5OCwgMzQzMDgsIDM0MzE4LAorMzQzMjgsIDM0MzM4LCAzNDM0OCwgMzQzNTgsIDM0MzY4LCAzNDM3OCwgMzQzODgsIDM0Mzk4LCAzNDQwOCwgMzQ0MTgsIDM0NDI4LCAzNDQzOCwgMzQ0NDgsIDM0NDU4LCAzNDQ2OCwgMzQ0NzgsCiszNDQ4OCwgMzQ0OTgsIDM0NTA4LCAzNDUxOCwgMzQ1MjgsIDM0NTM4LCAzNDU0OCwgMzQ1NTgsIDM0NTY4LCAzNDU3OCwgMzQ1ODgsIDM0NTk4LCAzNDYwOCwgMzQ2MTgsIDM0NjI4LCAzNDYzOCwKKzM0NjQ4LCAzNDY1OCwgMzQ2NjgsIDM0Njc4LCAzNDY4OCwgMzQ2OTgsIDM0NzA4LCAzNDcxOCwgMzQ3MjgsIDM0NzM4LCAzNDc0OCwgMzQ3NTgsIDM0NzY4LCAzNDc3OCwgMzQ3ODgsIDM0Nzk4LAorMzQ4MDgsIDM0ODE4LCAzNDgyOCwgMzQ4MzgsIDM0ODQ4LCAzNDg1OCwgMzQ4NjgsIDM0ODc4LCAzNDg4OCwgMzQ4OTgsIDM0OTA4LCAzNDkxOCwgMzQ5MjgsIDM0OTM4LCAzNDk0OCwgMzQ5NTgsCiszNDk2OCwgMzQ5NzgsIDM0OTg4LCAzNDk5OCwgMzUwMDgsIDM1MDE4LCAzNTAyOCwgMzUwMzgsIDM1MDQ4LCAzNTA1OCwgMzUwNjgsIDM1MDc4LCAzNTA4OCwgMzUwOTgsIDM1MTA4LCAzNTExOCwKKzM1MTI4LCAzNTEzOCwgMzUxNDgsIDM1MTU4LCAzNTE2OCwgMzUxNzgsIDM1MTg4LCAzNTE5OCwgMzUyMDgsIDM1MjE4LCAzNTIyOCwgMzUyMzgsIDM1MjQ4LCAzNTI1OCwgMzUyNjgsIDM1Mjc4LAorMzUyODgsIDM1Mjk4LCAzNTMwOCwgMzUzMTgsIDM1MzI4LCAzNTMzOCwgMzUzNDgsIDM1MzU4LCAzNTM2OCwgMzUzNzgsIDM1Mzg4LCAzNTM5OCwgMzU0MDgsIDM1NDE4LCAzNTQyOCwgMzU0MzgsCiszNTQ0OCwgMzU0NTgsIDM1NDY4LCAzNTQ3OCwgMzU0ODgsIDM1NDk4LCAzNTUwOCwgMzU1MTgsIDM1NTI4LCAzNTUzOCwgMzU1NDgsIDM1NTU4LCAzNTU2OCwgMzU1NzgsIDM1NTg4LCAzNTU5OCwKKzM1NjA4LCAzNTYxOCwgMzU2MjgsIDM1NjM4LCAzNTY0OCwgMzU2NTgsIDM1NjY4LCAzNTY3OCwgMzU2ODgsIDM1Njk4LCAzNTcwOCwgMzU3MTgsIDM1NzI4LCAzNTczOCwgMzU3NDgsIDM1NzU4LAorMzU3NjgsIDM1Nzc4LCAzNTc4OCwgMzU3OTgsIDM1ODA4LCAzNTgxOCwgMzU4MjgsIDM1ODM4LCAzNTg0OCwgMzU4NTgsIDM1ODY4LCAzNTg3OCwgMzU4ODgsIDM1ODk4LCAzNTkwOCwgMzU5MTgsCiszNTkyOCwgMzU5MzgsIDM1OTQ4LCAzNTk1OCwgMzU5NjgsIDM1OTc4LCAzNTk4OCwgMzU5OTgsIDM2MDA4LCAzNjAxOCwgMzYwMjgsIDM2MDM4LCAzNjA0OCwgMzYwNTgsIDM2MDY4LCAzNjA3OCwKKzM2MDg4LCAzNjA5OCwgMzYxMDgsIDM2MTE4LCAzNjEyOCwgMzYxMzgsIDM2MTQ4LCAzNjE1OCwgMzYxNjgsIDM2MTc4LCAzNjE4OCwgMzYxOTgsIDM2MjA4LCAzNjIxOCwgMzYyMjgsIDM2MjM4LAorMzYyNDgsIDM2MjU4LCAzNjI2OCwgMzYyNzgsIDM2Mjg4LCAzNjI5OCwgMzYzMDgsIDM2MzE4LCAzNjMyOCwgMzYzMzgsIDM2MzQ4LCAzNjM1OCwgMzYzNjgsIDM2Mzc4LCAzNjM4OCwgMzYzOTgsCiszNjQwOCwgMzY0MTgsIDM2NDI4LCAzNjQzOCwgMzY0NDgsIDM2NDU4LCAzNjQ2OCwgMzY0NzgsIDM2NDg4LCAzNjQ5OCwgMzY1MDgsIDM2NTE4LCAzNjUyOCwgMzY1MzgsIDM2NTQ4LCAzNjU1OCwKKzM2NTY4LCAzNjU3OCwgMzY1ODgsIDM2NTk4LCAzNjYwOCwgMzY2MTgsIDM2NjI4LCAzNjYzOCwgMzY2NDgsIDM2NjU4LCAzNjY2OCwgMzY2NzgsIDM2Njg4LCAzNjY5OCwgMzY3MDgsIDM2NzE4LAorMzY3MjgsIDM2NzM4LCAzNjc0OCwgMzY3NTgsIDM2NzY4LCAzNjc3OCwgMzY3ODgsIDM2Nzk4LCAzNjgwOCwgMzY4MTgsIDM2ODI4LCAzNjgzOCwgMzY4NDgsIDM2ODU4LCAzNjg2OCwgMzY4NzgsCiszNjg4OCwgMzY4OTgsIDM2OTA4LCAzNjkxOCwgMzY5MjgsIDM2OTM4LCAzNjk0OCwgMzY5NTgsIDM2OTY4LCAzNjk3OCwgMzY5ODgsIDM2OTk4LCAzNzAwOCwgMzcwMTgsIDM3MDI4LCAzNzAzOCwKKzM3MDQ4LCAzNzA1OCwgMzcwNjgsIDM3MDc4LCAzNzA4OCwgMzcwOTgsIDM3MTA4LCAzNzExOCwgMzcxMjgsIDM3MTM4LCAzNzE0OCwgMzcxNTgsIDM3MTY4LCAzNzE3OCwgMzcxODgsIDM3MTk4LAorMzcyMDgsIDM3MjE4LCAzNzIyOCwgMzcyMzgsIDM3MjQ4LCAzNzI1OCwgMzcyNjgsIDM3Mjc4LCAzNzI4OCwgMzcyOTgsIDM3MzA4LCAzNzMxOCwgMzczMjgsIDM3MzM4LCAzNzM0OCwgMzczNTgsCiszNzM2OCwgMzczNzgsIDM3Mzg4LCAzNzM5OCwgMzc0MDgsIDM3NDE4LCAzNzQyOCwgMzc0MzgsIDM3NDQ4LCAzNzQ1OCwgMzc0NjgsIDM3NDc4LCAzNzQ4OCwgMzc0OTgsIDM3NTA4LCAzNzUxOCwKKzM3NTI4LCAzNzUzOCwgMzc1NDgsIDM3NTU4LCAzNzU2OCwgMzc1NzgsIDM3NTg4LCAzNzU5OCwgMzc2MDgsIDM3NjE4LCAzNzYyOCwgMzc2MzgsIDM3NjQ4LCAzNzY1OCwgMzc2NjgsIDM3Njc4LAorMzc2ODgsIDM3Njk4LCAzNzcwOCwgMzc3MTgsIDM3NzI4LCAzNzczOCwgMzc3NDgsIDM3NzU4LCAzNzc2OCwgMzc3NzgsIDM3Nzg4LCAzNzc5OCwgMzc4MDgsIDM3ODE4LCAzNzgyOCwgMzc4MzgsCiszNzg0OCwgMzc4NTgsIDM3ODY4LCAzNzg3OCwgMzc4ODgsIDM3ODk4LCAzNzkwOCwgMzc5MTgsIDM3OTI4LCAzNzkzOCwgMzc5NDgsIDM3OTU4LCAzNzk2OCwgMzc5NzgsIDM3OTg4LCAzNzk5OCwKKzM4MDA4LCAzODAxOCwgMzgwMjgsIDM4MDM4LCAzODA0OCwgMzgwNTgsIDM4MDY4LCAzODA3OCwgMzgwODgsIDM4MDk4LCAzODEwOCwgMzgxMTgsIDM4MTI4LCAzODEzOCwgMzgxNDgsIDM4MTU4LAorMzgxNjgsIDM4MTc4LCAzODE4OCwgMzgxOTgsIDM4MjA4LCAzODIxOCwgMzgyMjgsIDM4MjM4LCAzODI0OCwgMzgyNTgsIDM4MjY4LCAzODI3OCwgMzgyODgsIDM4Mjk4LCAzODMwOCwgMzgzMTgsCiszODMyOCwgMzgzMzgsIDM4MzQ4LCAzODM1OCwgMzgzNjgsIDM4Mzc4LCAzODM4OCwgMzgzOTgsIDM4NDA4LCAzODQxOCwgMzg0MjgsIDM4NDM4LCAzODQ0OCwgMzg0NTgsIDM4NDY4LCAzODQ3OCwKKzM4NDg4LCAzODQ5OCwgMzg1MDgsIDM4NTE4LCAzODUyOCwgMzg1MzgsIDM4NTQ4LCAzODU1OCwgMzg1NjgsIDM4NTc4LCAzODU4OCwgMzg1OTgsIDM4NjA4LCAzODYxOCwgMzg2MjgsIDM4NjM4LAorMzg2NDgsIDM4NjU4LCAzODY2OCwgMzg2NzgsIDM4Njg4LCAzODY5OCwgMzg3MDgsIDM4NzE4LCAzODcyOCwgMzg3MzgsIDM4NzQ4LCAzODc1OCwgMzg3NjgsIDM4Nzc4LCAzODc4OCwgMzg3OTgsCiszODgwOCwgMzg4MTgsIDM4ODI4LCAzODgzOCwgMzg4NDgsIDM4ODU4LCAzODg2OCwgMzg4NzgsIDM4ODg4LCAzODg5OCwgMzg5MDgsIDM4OTE4LCAzODkyOCwgMzg5MzgsIDM4OTQ4LCAzODk1OCwKKzM4OTY4LCAzODk3OCwgMzg5ODgsIDM4OTk4LCAzOTAwOCwgMzkwMTgsIDM5MDI4LCAzOTAzOCwgMzkwNDgsIDM5MDU4LCAzOTA2OCwgMzkwNzgsIDM5MDg4LCAzOTA5OCwgMzkxMDgsIDM5MTE4LAorMzkxMjgsIDM5MTM4LCAzOTE0OCwgMzkxNTgsIDM5MTY4LCAzOTE3OCwgMzkxODgsIDM5MTk4LCAzOTIwOCwgMzkyMTgsIDM5MjI4LCAzOTIzOCwgMzkyNDgsIDM5MjU4LCAzOTI2OCwgMzkyNzgsCiszOTI4OCwgMzkyOTgsIDM5MzA4LCAzOTMxOCwgMzkzMjgsIDM5MzM4LCAzOTM0OCwgMzkzNTgsIDM5MzY4LCAzOTM3OCwgMzkzODgsIDM5Mzk4LCAzOTQwOCwgMzk0MTgsIDM5NDI4LCAzOTQzOCwKKzM5NDQ4LCAzOTQ1OCwgMzk0NjgsIDM5NDc4LCAzOTQ4OCwgMzk0OTgsIDM5NTA4LCAzOTUxOCwgMzk1MjgsIDM5NTM4LCAzOTU0OCwgMzk1NTgsIDM5NTY4LCAzOTU3OCwgMzk1ODgsIDM5NTk4LAorMzk2MDgsIDM5NjE4LCAzOTYyOCwgMzk2MzgsIDM5NjQ4LCAzOTY1OCwgMzk2NjgsIDM5Njc4LCAzOTY4OCwgMzk2OTgsIDM5NzA4LCAzOTcxOCwgMzk3MjgsIDM5NzM4LCAzOTc0OCwgMzk3NTgsCiszOTc2OCwgMzk3NzgsIDM5Nzg4LCAzOTc5OCwgMzk4MDgsIDM5ODE4LCAzOTgyOCwgMzk4MzgsIDM5ODQ4LCAzOTg1OCwgMzk4NjgsIDM5ODc4LCAzOTg4OCwgMzk4OTgsIDM5OTA4LCAzOTkxOCwKKzM5OTI4LCAzOTkzOCwgMzk5NDgsIDM5OTU4LCAzOTk2OCwgMzk5NzgsIDM5OTg4LCAzOTk5OCwgNDAwMDgsIDQwMDE4LCA0MDAyOCwgNDAwMzgsIDQwMDQ4LCA0MDA1OCwgNDAwNjgsIDQwMDc4LAorNDAwODgsIDQwMDk4LCA0MDEwOCwgNDAxMTgsIDQwMTI4LCA0MDEzOCwgNDAxNDgsIDQwMTU4LCA0MDE2OCwgNDAxNzgsIDQwMTg4LCA0MDE5OCwgNDAyMDgsIDQwMjE4LCA0MDIyOCwgNDAyMzgsCis0MDI0OCwgNDAyNTgsIDQwMjY4LCA0MDI3OCwgNDAyODgsIDQwMjk4LCA0MDMwOCwgNDAzMTgsIDQwMzI4LCA0MDMzOCwgNDAzNDgsIDQwMzU4LCA0MDM2OCwgNDAzNzgsIDQwMzg4LCA0MDM5OCwKKzQwNDA4LCA0MDQxOCwgNDA0MjgsIDQwNDM4LCA0MDQ0OCwgNDA0NTgsIDQwNDY4LCA0MDQ3OCwgNDA0ODgsIDQwNDk4LCA0MDUwOCwgNDA1MTgsIDQwNTI4LCA0MDUzOCwgNDA1NDgsIDQwNTU4LAorNDA1NjgsIDQwNTc4LCA0MDU4OCwgNDA1OTgsIDQwNjA4LCA0MDYxOCwgNDA2MjgsIDQwNjM4LCA0MDY0OCwgNDA2NTgsIDQwNjY4LCA0MDY3OCwgNDA2ODgsIDQwNjk4LCA0MDcwOCwgNDA3MTgsCis0MDcyOCwgNDA3MzgsIDQwNzQ4LCA0MDc1OCwgNDA3NjgsIDQwNzc4LCA0MDc4OCwgNDA3OTgsIDQwODA4LCA0MDgxOCwgNDA4MjgsIDQwODM4LCA0MDg0OCwgNDA4NTgsIDQwODY4LCA1NzM0NCwKKzU3MzU0LCA1NzM2NCwgNTczNzQsIDU3Mzg0LCA1NzM5NCwgNTc0MDQsIDU3NDE0LCA1NzQyNCwgNTc0MzQsIDU3NDQ0LCA1NzQ1NCwgNTc0NjQsIDU3NDc0LCA1NzQ4NCwgNTc0OTQsIDU3NTA0LAorNTc1MTQsIDU3NTI0LCA1NzUzNCwgNTc1NDQsIDU3NTU0LCA1NzU2NCwgNTc1NzQsIDU3NTg0LCA1NzU5NCwgNTc2MDQsIDU3NjE0LCA1NzYyNCwgNTc2MzQsIDU3NjQ0LCA1NzY1NCwgNTc2NjQsCis1NzY3NCwgNTc2ODQsIDU3Njk0LCA1NzcwNCwgNTc3MTQsIDU3NzI0LCA1NzczNCwgNTc3NDQsIDU3NzU0LCA1Nzc2NCwgNTc3NzQsIDU3Nzg0LCA1Nzc5NCwgNTc4MDQsIDU3ODE0LCA1NzgyNCwKKzU3ODM0LCA1Nzg0NCwgNTc4NTQsIDU3ODY0LCA1Nzg3NCwgNTc4ODQsIDU3ODk0LCA1NzkwNCwgNTc5MTQsIDU3OTI0LCA1NzkzNCwgNTc5NDQsIDU3OTU0LCA1Nzk2NCwgNTc5NzQsIDU3OTg0LAorNTc5OTQsIDU4MDA0LCA1ODAxNCwgNTgwMjQsIDU4MDM0LCA1ODA0NCwgNTgwNTQsIDU4MDY0LCA1ODA3NCwgNTgwODQsIDU4MDk0LCA1ODEwNCwgNTgxMTQsIDU4MTI0LCA1ODEzNCwgNTgxNDQsCis1ODE1NCwgNTgxNjQsIDU4MTc0LCA1ODE4NCwgNTgxOTQsIDU4MjA0LCA1ODIxNCwgNTgyMjQsIDU4MjM0LCA1ODI0NCwgNTgyNTQsIDU4MjY0LCA1ODI3NCwgNTgyODQsIDU4Mjk0LCA1ODMwNCwKKzU4MzE0LCA1ODMyNCwgNTgzMzQsIDU4MzQ0LCA1ODM1NCwgNTgzNjQsIDU4Mzc0LCA1ODM4NCwgNTgzOTQsIDU4NDA0LCA1ODQxNCwgNTg0MjQsIDU4NDM0LCA1ODQ0NCwgNTg0NTQsIDU4NDY0LAorNTg0NzQsIDU4NDg0LCA1ODQ5NCwgNTg1MDQsIDU4NTE0LCA1ODUyNCwgNTg1MzQsIDU4NTQ0LCA1ODU1NCwgNTg1NjQsIDU4NTc0LCA1ODU4NCwgNTg1OTQsIDU4NjA0LCA1ODYxNCwgNTg2MjQsCis1ODYzNCwgNTg2NDQsIDU4NjU0LCA1ODY2NCwgNTg2NzQsIDU4Njg0LCA1ODY5NCwgNTg3MDQsIDU4NzE0LCA1ODcyNCwgNTg3MzQsIDU4NzQ0LCA1ODc1NCwgNTg3NjQsIDU4Nzc0LCA1ODc4NCwKKzU4Nzk0LCA1ODgwNCwgNTg4MTQsIDU4ODI0LCA1ODgzNCwgNTg4NDQsIDU4ODU0LCA1ODg2NCwgNTg4NzQsIDU4ODg0LCA1ODg5NCwgNTg5MDQsIDU4OTE0LCA1ODkyNCwgNTg5MzQsIDU4OTQ0LAorNTg5NTQsIDU4OTY0LCA1ODk3NCwgNTg5ODQsIDU4OTk0LCA1OTAwNCwgNTkwMTQsIDU5MDI0LCA1OTAzNCwgNTkwNDQsIDU5MDU0LCA1OTA2NCwgNTkwNzQsIDU5MDg0LCA1OTA5NCwgNTkxMDQsCis1OTExNCwgNTkxMjQsIDU5MTM0LCA1OTE0NCwgNTkxNTQsIDU5MTY0LCA1OTE3NCwgNTkxODQsIDU5MTk0LCA1OTIwNCwgNTkyMTQsIDU5MjI0LCA1OTIzNCwgNTkyNDQsIDU5MjU0LCA1OTI2NCwKKzU5Mjc0LCA1OTI4NCwgNTkyOTQsIDU5MzA0LCA1OTMxNCwgNTkzMjQsIDU5MzM0LCA1OTM0NCwgNTkzNTQsIDU5MzY0LCA1OTM3NCwgNTkzODQsIDU5Mzk0LCA1OTQwNCwgNTk0MTQsIDU5NDI0LAorNTk0MzQsIDU5NDQ0LCA1OTQ1NCwgNTk0NjQsIDU5NDc0LCA1OTQ4NCwgNjM3ODgsIDYzODY1LCA2Mzg5MywgNjM5NzUsIDYzOTg1LCA2NDAxMiwgNjQwMjQsIDY0MDM1LCA2NTA3MiwgNjUwODIsCis2NTA5MiwgNjUxMDIsIDY1MTEzLCA2NTEyMywgNjUyODEsIDY1MjkxLCA2NTMwMSwgNjUzMTEsIDY1MzIxLCA2NTMzMSwgNjUzNDEsIDY1MzUxLCA2NTM2MSwgNjUzNzEsIDY1NTA0LCA2NTUzNgorICAgICAgICAgICAgfSk7CisgICAgICAgIHRlc3RCeXRlcyA9IHRoZXNlQnl0ZXMobmV3IGludFtdeworMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKzE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCis0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKzY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCis5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKzExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKzE2MSwgMjMyLCAxNjEsIDIzNiwgMTYxLCAxNjcsIDE2MSwgMjI3LCAxNjEsIDE5MiwgMTYxLCAxNjQsIDE2MSwgMTkzLCAxNjgsIDE2NCwKKzE2OCwgMTYyLCAxNjgsIDE2OCwgMTY4LCAxNjYsIDE2OCwgMTg2LCAxNjgsIDE3MiwgMTY4LCAxNzAsIDE2OCwgMTc2LCAxNjgsIDE3NCwKKzE2MSwgMTk0LCAxNjgsIDE4MCwgMTY4LCAxNzgsIDE2OCwgMTg1LCAxNjgsIDE2MSwgMTY4LCAxNjUsIDE2OCwgMTY5LCAxNjgsIDE4OSwKKzE2OCwgMTc3LCAxNjgsIDE2MywgMTY4LCAxODIsIDE2OCwgMTg3LCAxNjgsIDE5MiwgMTYxLCAxNjYsIDE2OCwgNjYsIDE2NiwgMTYxLAorMTY2LCAxNzEsIDE2NiwgMTgwLCAxNjYsIDE5MywgMTY2LCAyMDMsIDE2NiwgMjEyLCAxNjcsIDE2NywgMTY3LCAxNjEsIDE2NywgMTcyLAorMTY3LCAxODIsIDE2NywgMTkyLCAxNjcsIDIxOCwgMTY3LCAyMjgsIDE2NywgMjM4LCAxNjksIDkyLCAxNjEsIDE3NiwgMTYxLCAxNzMsCisxNjEsIDIzNSwgMTYxLCAyNDksIDE2MSwgMjMwLCAxNjEsIDIzNywgMTY5LCA4OSwgMTYyLCAyNDEsIDE2MiwgMjUxLCAxNjIsIDE2NSwKKzE2MSwgMjUxLCAxNjEsIDIwMiwgMTY4LCA3NywgMTY4LCA3OCwgMTYxLCAyMDEsIDE2MSwgMjI0LCAxNjEsIDIxNCwgMTY4LCA4MCwKKzE2MSwgMjE3LCAxNjEsIDIxOCwgMTYxLCAyMDksIDE2MSwgMjA1LCAxNjgsIDgzLCAxNjEsIDIwOCwgMTYyLCAyMTcsIDE2MiwgMTk3LAorMTYyLCAyMDcsIDE2MiwgMTc3LCAxNjIsIDE4NywgMTY5LCAxNjQsIDE2OSwgMTc0LCAxNjksIDE4NCwgMTY5LCAxOTQsIDE2OSwgMjA0LAorMTY5LCAyMTQsIDE2OSwgMjI0LCAxNjksIDIzNCwgMTY4LCA4NCwgMTY4LCA5NCwgMTY4LCAxMDQsIDE2OCwgMTE0LCAxNjgsIDEyMCwKKzE2OCwgMTMxLCAxNjgsIDEzOCwgMTYxLCAyNDYsIDE2MSwgMjQ4LCAxNjgsIDEzOSwgMTYxLCAyNDQsIDE2OCwgMTQxLCAxNjEsIDIzOSwKKzE2MSwgMjI2LCAxNjEsIDE2MSwgMTYxLCAxODIsIDE2MSwgMTc4LCAxNjgsIDE0OSwgMTY5LCA3MSwgMTY0LCAxNjEsIDE2NCwgMTcxLAorMTY0LCAxODEsIDE2NCwgMTkxLCAxNjQsIDIwMSwgMTY0LCAyMTEsIDE2NCwgMjIxLCAxNjQsIDIzMSwgMTY0LCAyNDEsIDE2OSwgOTcsCisxNjUsIDE2NSwgMTY1LCAxNzUsIDE2NSwgMTg1LCAxNjUsIDE5NSwgMTY1LCAyMDUsIDE2NSwgMjE1LCAxNjUsIDIyNSwgMTY1LCAyMzUsCisxNjUsIDI0NSwgMTY4LCAxOTcsIDE2OCwgMjA3LCAxNjgsIDIxNywgMTY4LCAyMjcsIDE2MiwgMjI5LCAxNjksIDkwLCAxNjksIDczLAorMTY5LCA3NCwgMTY5LCA3NiwgMTY5LCA4MCwgMTY5LCA4MSwgMjEwLCAxODcsIDIwMSwgMjA3LCAxOTksIDIxMCwgMjE2LCAxNjksCisyMTYsIDE3MywgMTgwLCAxNzQsIDEyOSwgODMsIDEyOSwgODgsIDE5MiwgMjE0LCAxMjksIDkzLCAxMjksIDk3LCAxMjksIDEwNSwKKzEyOSwgMTEyLCAxMjksIDEyMSwgMTgyLCAyNTQsIDEyOSwgMTI5LCAyMTcsIDIzOSwgMTI5LCAxMzYsIDEyOSwgMTQwLCAxMjksIDE0NywKKzEyOSwgMTQ4LCAxMjksIDE1MiwgMTI5LCAxNTUsIDEyOSwgMTU4LCAyMDksIDI0NiwgMTI5LCAxNjgsIDEyOSwgMTc0LCAxODgsIDE5MSwKKzIxMSwgMTk3LCAyMTYsIDI0MywgMTI5LCAxOTIsIDE5MywgMjMwLCAxMjksIDIwMywgMTI5LCAyMTEsIDEyOSwgMjE1LCAyMTYsIDI1MCwKKzEyOSwgMjIwLCAxMjksIDIyNiwgMjE3LCAxNzQsIDEyOSwgMjM3LCAxMjksIDI0MiwgMTI5LCAyNDksIDEzMCwgNjQsIDIwNiwgMjM0LAorMTMwLCA3NCwgMTMwLCA4MywgMTMwLCA4OSwgMTMwLCA5NSwgMTMwLCA5OCwgMjE3LCAxNzksIDEzMCwgMTA3LCAyMTcsIDE5NCwKKzEzMCwgMTI0LCAxODEsIDE4NSwgMjE3LCAxOTUsIDE5MCwgMjM1LCAxMzAsIDE0NiwgMjEzLCAxNzQsIDEzMCwgMTYyLCAyMTcsIDIwMywKKzEzMCwgMTc2LCAxMzAsIDE4NCwgMjE3LCAyMDQsIDE5NywgMTg4LCAxOTEsIDI1NCwgMTMwLCAyMTQsIDEzMCwgMjIzLCAxMzAsIDIzMywKKzE4MCwgMTYyLCAxNzYsIDE5MywgMTMwLCAyNTQsIDEzMSwgNzMsIDEzMSwgODIsIDE5MywgMTk3LCAxMzEsIDEwMCwgMjE3LCAyMTUsCisxMzEsIDExMywgMTMxLCAxMjIsIDEzMSwgMTMwLCAxMzEsIDEzOSwgMTMxLCAxNDksIDEzMSwgMTU4LCAxMzEsIDE2OCwgMTMxLCAxNzgsCisyMDcsIDIwMCwgMTMxLCAxODYsIDE4MiwgMTgxLCAxMzEsIDE5OSwgMTkyLCAxODgsIDEzMSwgMjA1LCAxMzEsIDIwOSwgMTMxLCAyMTQsCisxMzEsIDIyMCwgMjE4LCAxNjMsIDE4MiwgMTcyLCAyMTAsIDE3NywgMTkwLCAxODcsIDEzMSwgMjQ1LCAxMzEsIDI1MSwgMTMyLCA2OCwKKzEzMiwgNzUsIDEzMiwgODEsIDIxOSwgMjAyLCAxODMsIDIxNCwgMTMyLCA5MSwgMTg0LCAyMTMsIDE5NywgMjA4LCAxODUsIDIwNiwKKzIwMCwgMTc1LCAxODgsIDE5MywgMjE2LCAyMjEsIDE5OCwgMjAyLCAxMzIsIDEzMywgMTg4LCAyNDQsIDEzMiwgMTQ2LCAxMzIsIDE1NSwKKzE5NywgMjUyLCAxMzIsIDE3MCwgMTMyLCAxNzgsIDEzMiwgMTgxLCAxMzIsIDE4NSwgMTMyLCAxOTIsIDEzMiwgMTk5LCAxMzIsIDIwNiwKKzE5MSwgMTc3LCAxMzIsIDIyMSwgMTMyLCAyMzAsIDEzMiwgMjM5LCAyMTIsIDIwMCwgMTMyLCAyNTEsIDEzMywgNjcsIDEzMywgNzEsCisxMzMsIDc3LCAxMzMsIDg1LCAxMzMsIDkyLCAxMzMsIDk3LCAxMzMsIDEwMSwgMTc4LCAxNjksIDE5NCwgMTc3LCAyMTYsIDE4MCwKKzIwOCwgMTgyLCAxNzksIDE2NywgMjA5LCAyMjUsIDEzMywgMTMzLCAxMzMsIDEzOSwgMTMzLCAxNDMsIDEzMywgMTUyLCAxMzMsIDE2MCwKKzIxMSwgMjE0LCAxMzMsIDE3MCwgMTMzLCAxNzQsIDE5MywgMjM3LCAyMDQsIDE2OCwgMTMzLCAxODEsIDE4NCwgMjQ3LCAxODYsIDI0MywKKzEzMywgMTkwLCAxMzMsIDE5NCwgMjA0LCAyNTMsIDEzMywgMjAwLCAyMDksIDE4OSwgMTg0LCAyMzAsIDIyMywgMTkwLCAxMzMsIDIxOCwKKzIxNCwgMjIwLCAyMjMsIDIxOCwgMTg2LCAyNDQsIDE5NywgMjE2LCAxODQsIDE5MiwgMjIzLCAyMDMsIDIyMywgMjI5LCAxMzQsIDY2LAorMjA3LCAyMDQsIDIyMywgMjExLCAyMjMsIDIyMywgMTM0LCA4MCwgMTM0LCA4MywgMTk2LCAxOTYsIDEzNCwgOTMsIDEzNCwgMTAwLAorMTM0LCAxMDYsIDEzNCwgMTEyLCAxMzQsIDEyMCwgMTM0LCAxMjYsIDIyNCwgMTY3LCAxMzQsIDEzOCwgMjE1LCAxOTYsIDEzNCwgMTQ5LAorMTM0LCAxNTYsIDEzNCwgMTY0LCAyMTYsIDE5NiwgMjI0LCAxNjQsIDE5MSwgMTY2LCAxODYsIDE3NiwgMjI0LCAxODQsIDEzNCwgMTkyLAorMTM0LCAyMDAsIDEzNCwgMjA5LCAxMzQsIDIxNCwgMTM0LCAyMjAsIDEzNCwgMjI3LCAxMzQsIDIzMiwgMjI0LCAyMDUsIDEzNCwgMjQwLAorMTM0LCAyNDUsIDEzNCwgMjUxLCAyMjQsIDIwOSwgMTM1LCA3NSwgMTM1LCA4MSwgMTM1LCA4OCwgMjE1LCAyMzYsIDEzNSwgMTAwLAorMTM1LCAxMDksIDEzNSwgMTE2LCAyMjQsIDIyNCwgMTM1LCAxMzAsIDEzNSwgMTM1LCAxMzUsIDE0MywgMTM1LCAxNTEsIDE4NiwgMTkxLAorMTM1LCAxNjYsIDEzNSwgMTc2LCAxMzUsIDE4NSwgMTM1LCAxOTQsIDEzNSwgMjAyLCAxOTYsIDIxMCwgMjI0LCAyMzYsIDE4NywgMjE2LAorMTM1LCAyMzAsIDEzNSwgMjM2LCAxMzUsIDI0MiwgMjEyLCAxNzgsIDEzNSwgMjUzLCAxMzYsIDcyLCAxMzYsIDc5LCAyMTksIDIyMCwKKzEzNiwgOTAsIDIxOSwgMjI0LCAyMTksIDIwOCwgMTM2LCAxMDYsIDIxNSwgMTg1LCAxOTgsIDE4NiwgMTM2LCAxMTgsIDEzNiwgMTI0LAorMTM2LCAxMzAsIDE5MiwgMjIxLCAxMzYsIDE0NSwgMTkxLCAyMDksIDEzNiwgMTU0LCAxMzYsIDE2MSwgMTM2LCAxNjksIDE3OSwgMTk5LAorMjE5LCAyNDUsIDEzNiwgMTg3LCAxMzYsIDE5NiwgMTM2LCAyMDMsIDIyMCwgMTY1LCAxMzYsIDIxNSwgMTM2LCAyMjIsIDIyMCwgMTY2LAorMTM2LCAyMzYsIDEzNiwgMjQ0LCAxMzYsIDI1MywgMTM3LCA3MSwgMTM3LCA3OSwgMTM3LCA4NiwgMTM3LCA5NSwgMTM3LCAxMDIsCisxMzcsIDExMiwgMTM3LCAxMTksIDEzNywgMTI2LCAxMzcsIDEzNSwgMTM3LCAxNDEsIDEzNywgMTQ5LCAxMzcsIDE1OSwgMTM3LCAxNjgsCisxMzcsIDE3NiwgMTM3LCAxODUsIDEzNywgMTk0LCAxMzcsIDIwMywgMjAxLCAyNDksIDEzNywgMjE2LCAxODAsIDE2NiwgMTM3LCAyMzIsCisxMzcsIDIzOCwgMTM3LCAyNDQsIDEzNywgMjQ4LCAxMzcsIDI1MywgMTM4LCA2NywgMTM4LCA3MSwgMTc3LCAxODgsIDEzOCwgODEsCisxMzgsIDg4LCAxMzgsIDk4LCAxMzgsIDEwMywgMjE1LCAxNzcsIDEzOCwgMTEzLCAxMzgsIDExOCwgMjMwLCAxNjUsIDE5NiwgMjIxLAorMTM4LCAxMzgsIDEzOCwgMTQ1LCAxMzgsIDE1MiwgMTM4LCAxNTcsIDEzOCwgMTYyLCAxMzgsIDE2OSwgMTM4LCAxNzgsIDEzOCwgMTg2LAorMjMwLCAxNzQsIDEzOCwgMTk1LCAxOTYsIDIwMCwgMTM4LCAyMDgsIDEzOCwgMjE3LCAxMzgsIDIyMywgMTM4LCAyMzEsIDEzOCwgMjM4LAorMTM4LCAyNDcsIDIzMCwgMTkwLCAxMzksIDcyLCAyMDEsIDI0NCwgMTM5LCA4NiwgMTM5LCA5NiwgMTM5LCAxMDUsIDEzOSwgMTEzLAorMTM5LCAxMjMsIDIzMCwgMTk5LCAxMzksIDEzOSwgMTM5LCAxNDYsIDEzOSwgMTU0LCAxMzksIDE2MCwgMTM5LCAxNjYsIDEzOSwgMTczLAorMTM5LCAxODIsIDEzOSwgMTkyLCAxMzksIDIwMSwgMjMwLCAyMTIsIDEzOSwgMjE5LCAxMzksIDIyOSwgMjE3LCAyNDgsIDEzOSwgMjQ2LAorMTQwLCA2NCwgMTQwLCA3MiwgMjE1LCAyMDYsIDIwOSwgMTY3LCAyMDIsIDIzNSwgMjAwLCAyMzAsIDIyOSwgMTc5LCAxNDAsIDk3LAorMTg1LCAyMTcsIDE5MSwgMjA1LCAxNDAsIDEwNywgMTg4LCAyMTAsIDE0MCwgMTE3LCAxNDAsIDEyMiwgMTQwLCAxMjksIDE5NiwgMTc1LAorMjEzLCAxNzUsIDE0MCwgMTUwLCAxODEsIDE4OCwgMTg5LCAxNzEsIDE0MCwgMTY4LCAyMDEsIDIwOCwgMjExLCAyMDAsIDE0MCwgMTg1LAorMjAyLCAxNzIsIDE3OCwgMjI3LCAxNDAsIDE5NywgMTQwLCAyMDIsIDIwNSwgMTkyLCAxNDAsIDIxNSwgMTQwLCAyMjIsIDE0MCwgMjMwLAorMjI1LCAxNzIsIDE0MCwgMjQyLCAyMjUsIDE3NywgMTQwLCAyNTIsIDE0MSwgNjcsIDE0MSwgNzIsIDIyNSwgMTg3LCAxNDEsIDg3LAorMTQxLCA5NiwgMTQxLCAxMDQsIDE0MSwgMTA5LCAxNDEsIDExNywgMTQxLCAxMjYsIDE0MSwgMTMzLCAxODAsIDIyMiwgMjI1LCAxOTgsCisxNDEsIDE1NSwgMTQxLCAxNjIsIDE0MSwgMTcxLCAxNDEsIDE3OSwgMTQxLCAxODUsIDE0MSwgMTk0LCAxNDEsIDIwMiwgMTQxLCAyMDksCisxNDEsIDIxNywgMjI1LCAyMTQsIDE0MSwgMjM2LCAxNDEsIDI0NiwgMTQxLCAyNTQsIDE0MiwgNzMsIDE0MiwgODMsIDE0MiwgOTIsCisxNDIsIDEwMSwgMTQyLCAxMTAsIDE0MiwgMTE5LCAyMTUsIDI0MywgMTQyLCAxMjgsIDE0MiwgMTMzLCAxNDIsIDEzOCwgMTQyLCAxNDQsCisxOTMsIDE3NywgMTQyLCAxNTIsIDE0MiwgMTYwLCAxNDIsIDE2NywgMTQyLCAxNzIsIDE0MiwgMTc5LCAyMjUsIDE2MywgMjI1LCAxNjUsCisxNDIsIDIwMiwgMTg0LCAyMDEsIDIxMSwgMjE1LCAxOTksIDIzNiwgMTk0LCAxNzQsIDE4NCwgMjUzLCAxNDIsIDIzMiwgMTQyLCAyMzgsCisyMTEsIDE4NSwgMTQyLCAyNTEsIDE0MywgNjgsIDE5MywgMjA2LCAxNDMsIDgzLCAyMjYsIDIyMiwgMjE5LCAyMDAsIDIyMiwgMTk1LAorMjIyLCAxOTYsIDE0MywgMTE1LCAxNDMsIDEyMCwgMjA3LCAyMTAsIDE0MywgMTMyLCAxOTksIDE5MSwgMTQzLCAxNDcsIDE0MywgMTU3LAorMjI5LCAyMzMsIDIwOCwgMjA2LCAxNzcsIDI0MiwgMTQzLCAxNzgsIDIwNSwgMjQ5LCAxODcsIDE3OCwgMTQzLCAxOTEsIDE0MywgMTk2LAorMjI1LCAyMjksIDE0MywgMjExLCAyMjUsIDIzMiwgMjEwLCAyMjgsIDIzNiwgMjU0LCAxNDMsIDIzMiwgMjI2LCAyMzIsIDIyNiwgMjI5LAorMjI2LCAyMzgsIDIwMywgMjAzLCAxNDQsIDY3LCAxNzgsIDE5MiwgMTgxLCAxNjEsIDE4NSwgMjE0LCAxNDQsIDg2LCAxNDQsIDkzLAorMTQ0LCA5OSwgMTg2LCAyMjcsIDE0NCwgMTEyLCAxNDQsIDExOCwgMTk5LCAxNjEsIDIyNiwgMjUzLCAxOTksIDE5NiwgMTQ0LCAxMzYsCisxNDQsIDE0MywgMTQ0LCAxNDgsIDIwOCwgMjUyLCAxNDQsIDE1OCwgMTQ0LCAxNjUsIDE5MCwgMTcwLCAxNDQsIDE4MCwgMTQ0LCAxODUsCisxNzgsIDIxMCwgMTQ0LCAxOTMsIDE0NCwgMTk4LCAyMzcsIDE2OSwgMTQ0LCAyMTAsIDIxMSwgMjIyLCAxODMsIDIyMywgMTQ0LCAyMzEsCisxNDQsIDI0MSwgMTQ0LCAyNTAsIDE4NywgMTk3LCAxNDUsIDczLCAxNDUsIDgyLCAxNDUsIDg5LCAxNDUsIDk4LCAxNDUsIDEwNiwKKzE0NSwgMTE2LCAxNDUsIDEyNCwgMTQ1LCAxMzQsIDE0NSwgMTQzLCAxNDUsIDE0OSwgMTQ1LCAxNTgsIDE0NSwgMTY2LCAxNDUsIDE3MywKKzE0NSwgMTgwLCAxNDUsIDE5MCwgMTQ1LCAxOTksIDE0NSwgMjA4LCAxNDUsIDIxNywgMjA2LCAyMzYsIDE0NSwgMjI2LCAxNDUsIDIzMCwKKzE0NSwgMjM1LCAxNDUsIDI0MiwgMTQ1LCAyNDksIDE0NSwgMjUzLCAxNDYsIDY1LCAxNDYsIDcwLCAxNDYsIDc4LCAxNzYsIDIzMSwKKzE0NiwgODYsIDE0NiwgOTEsIDE0NiwgOTgsIDE4MiwgMTgyLCAxOTEsIDIxNywgMTQ2LCAxMTIsIDE0NiwgMTE5LCAxNDYsIDEyNCwKKzE5NiwgMjMzLCAxOTAsIDIyMCwgMTc2LCAyMjEsIDE5MiwgMTg1LCAxNDYsIDE0MCwgMTQ2LCAxNDUsIDE0NiwgMTQ5LCAxOTEsIDIzMCwKKzE0NiwgMTYzLCAyMjIsIDIxNiwgMTQ2LCAxNjksIDE0NiwgMTc3LCAxNDYsIDE4NCwgMTQ2LCAxODksIDE0NiwgMTkzLCAxOTIsIDIwNCwKKzE0NiwgMjA2LCAxNDYsIDIxMiwgMTQ2LCAyMTgsIDE0NiwgMjI2LCAxOTgsIDI1NCwgMTQ2LCAyMzUsIDE0NiwgMjQyLCAyMjIsIDIzMSwKKzE4MSwgMTY3LCAxNDcsIDY1LCAxNDcsIDcyLCAyMTAsIDE5MCwgMjIyLCAyMzUsIDE5MCwgMTkwLCAyMTIsIDE3NCwgMTQ3LCAxMDQsCisxNDcsIDEwOSwgMTQ3LCAxMTUsIDIwMywgMjA5LCAyMjIsIDI0OSwgMTQ3LCAxMzUsIDIwOCwgMTc1LCAyMDEsIDIyNywgMTQ3LCAxNTQsCisyMTMsIDE3MCwgMTQ3LCAxNzAsIDE0NywgMTc4LCAxNDcsIDE4NywgMTQ3LCAxOTQsIDE0NywgMjAwLCAxNDcsIDIwOCwgMjE1LCAxNzgsCisxNDcsIDIyMywgMTQ3LCAyMjgsIDE4NiwgMTc5LCAxNDcsIDI0MCwgMjIzLCAxNjcsIDE0NywgMjU0LCAyMjMsIDE2OSwgMTQ4LCA3OSwKKzE0OCwgODksIDE0OCwgOTgsIDE0OCwgMTA3LCAxNDgsIDExNiwgMTQ4LCAxMjUsIDE0OCwgMTM1LCAyMzQsIDE4MywgMTgzLCAxOTcsCisyMDgsIDE2NywgMTQ4LCAxNTgsIDE0OCwgMTY0LCAxODIsIDIxNiwgMjAyLCAyNTMsIDE0OCwgMTgzLCAxNDgsIDE5MywgMTQ4LCAyMDAsCisxNDgsIDIwNiwgMTQ4LCAyMTEsIDE0OCwgMjE2LCAxNDgsIDIyMywgMTQ4LCAyMzAsIDE0OCwgMjM1LCAxNDgsIDI0MCwgMTQ4LCAyNDgsCisyMTQsIDE4OCwgMTQ5LCA2NCwgMTQ5LCA3MSwgMTkyLCAxNjUsIDE0OSwgODMsIDE0OSwgODksIDE0OSwgOTYsIDE0OSwgMTAyLAorMTQ5LCAxMDcsIDE0OSwgMTE0LCAyMDEsIDIwNiwgMjM0LCAyMDUsIDE0OSwgMTMzLCAxNDksIDEzOSwgMTk5LCAyMzEsIDE5MywgMTkyLAorMTQ5LCAxNTgsIDE0OSwgMTY2LCAxNDksIDE3NCwgMTQ5LCAxODMsIDE0OSwgMTkwLCAxNDksIDE5OCwgMTQ5LCAyMDcsIDE0OSwgMjE3LAorMTQ5LCAyMjcsIDE0OSwgMjMzLCAxNDksIDI0MSwgMTQ5LCAyNDcsIDIxNSwgMjM4LCAyMzUsIDE5NSwgMjAzLCAxODMsIDE1MCwgNzksCisxOTYsIDE5MCwgMTUwLCA5MCwgMTUwLCA5NywgMTg0LCAyMDMsIDE3OCwgMTk2LCAxNTAsIDExMywgMTUwLCAxMTgsIDE1MCwgMTIzLAorMTUwLCAxMjgsIDE1MCwgMTM0LCAxNTAsIDE0MCwgMTUwLCAxNDgsIDE1MCwgMTUyLCAxOTksIDE4NSwgMTUwLCAxNjEsIDE1MCwgMTY3LAorMTUwLCAxNzQsIDE5OCwgMjI2LCAxODUsIDI0MSwgMTUwLCAxODksIDIzMiwgMjA1LCAxNTAsIDIwMiwgMTUwLCAyMDksIDIzMiwgMjIxLAorMTUwLCAyMTYsIDE1MCwgMjI0LCAxNTAsIDIzMiwgMTUwLCAyNDAsIDIzMiwgMjM4LCAyMzIsIDI0MCwgMTg5LCAyMTksIDE1MSwgNjYsCisxODksIDE3NiwgMTUxLCA3NSwgMTUxLCA4MiwgMTc2LCAyNDAsIDE1MSwgOTcsIDE1MSwgMTA1LCAxNTEsIDExNCwgMTUxLCAxMjAsCisxNTEsIDEyNiwgMjMyLCAyNDksIDE1MSwgMTQzLCAxNTEsIDE1MCwgMjA0LCAxOTYsIDE1MSwgMTY2LCAxNTEsIDE3MywgMTUxLCAxNzksCisxNTEsIDE4NywgMTg5LCAxODMsIDE1MSwgMjAyLCAxNTEsIDIwOSwgMjEwLCAxNzIsIDE1MSwgMjI1LCAxNTEsIDIzMiwgMTUxLCAyNDIsCisxNTEsIDI1MCwgMTUyLCA2NSwgMTUyLCA3MiwgMTUyLCA4MCwgMjMzLCAxNzUsIDE1MiwgODksIDE5MiwgMTk4LCAxNTIsIDEwMywKKzIxMywgMTY1LCAxNTIsIDExOCwgMTUyLCAxMjUsIDE1MiwgMTM1LCAxODcsIDE3NywgMTUyLCAxNTAsIDE1MiwgMTU3LCAxNTIsIDE2NiwKKzE1MiwgMTc1LCAxNTIsIDE4MywgMTUyLCAxOTIsIDE1MiwgMjAyLCAxNTIsIDIwOSwgMTg2LCAyMjUsIDE1MiwgMjI0LCAyMzMsIDIwOCwKKzE1MiwgMjM5LCAxNTIsIDI0OCwgMTUzLCA2NCwgMTUzLCA3MiwgMTUzLCA4MiwgMTUzLCA5MCwgMjA3LCAxNzMsIDIzMywgMjEzLAorMTUzLCAxMTMsIDE1MywgMTIyLCAxOTUsIDIwMiwgMTUzLCAxNDAsIDE1MywgMTUwLCAxNTMsIDE2MCwgMTUzLCAxNzAsIDE1MywgMTgwLAorMTUzLCAxOTAsIDE1MywgMjAwLCAxNTMsIDIxMCwgMTUzLCAyMjAsIDE1MywgMjMwLCAxNTMsIDI0MCwgMjM2LCAxNjMsIDE1MywgMjU0LAorMTU0LCA3MSwgMTU0LCA3OCwgMTg0LCAyMzIsIDE1NCwgOTMsIDE1NCwgMTAyLCAyMDUsIDIyNSwgMTU0LCAxMTUsIDE1NCwgMTIyLAorMTU0LCAxMjYsIDIzMywgMjMwLCAxNTQsIDEzOCwgMTU0LCAxNDcsIDE1NCwgMTU2LCAxNTQsIDE2MiwgMTU0LCAxNjksIDE1NCwgMTc2LAorMTU0LCAxNzksIDE1NCwgMTg2LCAxNTQsIDE5NCwgMTU0LCAyMDEsIDE1NCwgMjA5LCAxNTQsIDIxNiwgMTk4LCAyNDgsIDE1NCwgMjI0LAorMTc2LCAxNzcsIDIzNSwgMTgxLCAxNTQsIDIzOCwgMjE3LCAyMjQsIDIwNywgMTcxLCAxNTUsIDY1LCAyMDQsIDE5MiwgMTU1LCA3NCwKKzE1NSwgODAsIDIxMCwgMjAyLCAyMjcsIDIzMSwgMTU1LCA5NSwgMTU1LCAxMDIsIDE4NywgMTY2LCAxNTUsIDEwOCwgMjEzLCAxODAsCisxNTUsIDExOSwgMTU1LCAxMjUsIDE1NSwgMTMwLCAxNTUsIDEzNCwgMjA0LCAxNjksIDIyNywgMjQ4LCAyMjgsIDE2NywgMjI4LCAxNjksCisxNTUsIDE1OSwgMTU1LCAxNjUsIDE1NSwgMTcxLCAxNTUsIDE3NiwgMTU1LCAxODEsIDIxNSwgMTk5LCAyMjgsIDE3NywgMjI4LCAxODMsCisxNTUsIDE5OSwgMTU1LCAyMDUsIDIyOCwgMTg4LCAxNTUsIDIxOSwgMTU1LCAyMjUsIDE1NSwgMjMxLCAxODEsIDIxMSwgMjI4LCAyMDQsCisxODYsIDIxMiwgMTU1LCAyNTAsIDIwNCwgMjAyLCAxOTYsIDIxNSwgMjI4LCAxOTYsIDE1NiwgODMsIDE1NiwgODgsIDE1NiwgOTQsCisxNTYsIDEwMywgMTU2LCAxMDcsIDE1NiwgMTEzLCAxNTYsIDExNywgMTU2LCAxMjMsIDE5NSwgMjM2LCAyMjgsIDIxNiwgMjI4LCAyMDcsCisyMDcsIDIzMCwgMTU2LCAxNjAsIDE1NiwgMTY5LCAxNTYsIDE3OCwgMTU2LCAxODYsIDE1NiwgMTkyLCAxNTYsIDIwMCwgMTU2LCAyMDgsCisxNTYsIDIxNCwgMjI4LCAyMDksIDE1NiwgMjI1LCAxNTYsIDIzMiwgMTU2LCAyMzksIDE4NSwgMjQ2LCAxOTQsIDIwMywgMTU2LCAyNTMsCisxNTcsIDcxLCAxOTgsIDE3NSwgMTU3LCA4NywgMTU3LCA5MywgMTk2LCAxNzQsIDIyOCwgMjQ0LCAxNTcsIDExNCwgMjA5LCAyNTAsCisxNTcsIDEzMSwgMTU3LCAxMzksIDE5OSwgMTc3LCAxOTMsIDIwMiwgMTU3LCAxNjIsIDIyOCwgMjUzLCAxNzksIDIwNiwgMTk3LCAyMzYsCisxNTcsIDE5MSwgMTU3LCAxOTksIDE1NywgMjA4LCAyMjksIDE2NCwgMTg4LCAxNjQsIDE1NywgMjMyLCAxNTcsIDI0MCwgMjI5LCAxNjgsCisxNTgsIDY2LCAxNTgsIDc0LCAxNTgsIDg0LCAxNTgsIDk0LCAxNTgsIDEwNCwgMjI5LCAxNzEsIDE1OCwgMTIwLCAxNTgsIDEzMSwKKzE1OCwgMTQwLCAxNTgsIDE0OSwgMTg1LCAyMjQsIDE1OCwgMTY3LCAxNTgsIDE3NiwgMTU4LCAxODYsIDE1OCwgMTkxLCAyMTIsIDIxNCwKKzE1OCwgMjAzLCAxNzksIDE4MCwgMjM2LCAxOTEsIDE1OCwgMjIzLCAxNTgsIDIyOCwgMTU4LCAyMzMsIDE1OCwgMjM2LCAxNTgsIDI0NCwKKzE4NiwgMjMwLCAxNTksIDY5LCAxODksIDI1MywgMTU5LCA4MCwgMTU5LCA4NywgMTg2LCAxODQsIDE1OSwgMTAzLCAxNTksIDEwOCwKKzE1OSwgMTE3LCAxNTksIDEyNCwgMTU5LCAxMzQsIDE1OSwgMTQzLCAxNTksIDE1MCwgMTU5LCAxNjAsIDE5NSwgMTg2LCAyMTQsIDI0MywKKzIzNiwgMjEyLCAxNTksIDE4OCwgMTU5LCAxOTYsIDE1OSwgMjA0LCAyMzYsIDIxOCwgMTU5LCAyMTksIDE1OSwgMjI3LCAxNTksIDIzNSwKKzE1OSwgMjQ0LCAxNTksIDI1MywgMTYwLCA3MCwgMTYwLCA3OCwgMTYwLCA4NiwgMTYwLCA5NSwgMTYwLCAxMDUsIDE2MCwgMTE0LAorMTYwLCAxMjQsIDE2MCwgMTM0LCAxOTcsIDE5MiwgMTg0LCAxODQsIDE2MCwgMTUxLCAxNjAsIDE1OSwgMTYwLCAxNjYsIDE2MCwgMTcyLAorMTYwLCAxNzcsIDIwMSwgMjUyLCAxNjAsIDE5MCwgMTYwLCAxOTUsIDE2MCwgMjAxLCAxNjAsIDIxMCwgMTYwLCAyMTksIDE2MCwgMjI3LAorMjI1LCAyMzksIDE5MSwgMjQxLCAxNjAsIDI0NSwgMTYwLCAyNTEsIDE4NiwgMjIxLCAxNzAsIDczLCAyMjUsIDI0OSwgMTcwLCA3OSwKKzE3MCwgODcsIDE3MCwgOTUsIDE3OCwgMTk0LCAxNzAsIDEwNCwgMTcwLCAxMDksIDE3MCwgMTE0LCAxNzAsIDEyMiwgMTcwLCAxMzIsCisxNzAsIDEzOSwgMTcwLCAxNDgsIDIyNiwgMTc5LCAxNzEsIDY4LCAxNzEsIDc3LCAxNzEsIDg0LCAxNzEsIDkxLCAxNzEsIDk5LAorMTcxLCAxMDcsIDE5MywgMjI1LCAxNzEsIDExNywgMTcxLCAxMjUsIDE4MywgMTY5LCAxNzEsIDEzOCwgMTcxLCAxNDYsIDE3MSwgMTUyLAorMTcyLCA2NCwgMTcyLCA3NCwgMTcyLCA3OSwgMTcyLCA4NywgMTcyLCA5NSwgMjMxLCAyNDcsIDE5OSwgMjE3LCAxNzIsIDExMiwKKzE3MiwgMTIxLCAxNzIsIDEzMiwgMjMyLCAxNjQsIDE3MiwgMTQ0LCAxODUsIDIyOSwgMTcyLCAxNjAsIDE3MywgNjksIDIzMiwgMTcyLAorMTczLCA4NSwgMTczLCA5MywgMTczLCAxMDAsIDE3MywgMTEwLCAxNzMsIDExOSwgMTczLCAxMzAsIDE3MywgMTM5LCAyNDAsIDE3MiwKKzE3MywgMTUyLCAxNzMsIDE2MCwgMTc0LCA3MCwgMTc0LCA3OCwgMTc0LCA4NiwgMjAxLCAyNDUsIDE3NCwgOTksIDE3NCwgMTAzLAorMTgxLCAyMzMsIDE3NCwgMTExLCAxODksIDIzMSwgMTc0LCAxMjQsIDE3NCwgMTMxLCAxODMsIDE3MiwgMTc5LCAyMzUsIDE3NCwgMTU0LAorMTc1LCA2NCwgMjQwLCAyMTgsIDE3NSwgNzUsIDE3NSwgNzgsIDI0MCwgMjMwLCAxNzUsIDg2LCAyNDAsIDIyOCwgMTc1LCA5NCwKKzE4MiwgMTg3LCAxOTMsIDE2MSwgMTc1LCAxMDksIDE3NSwgMTE2LCAyNDAsIDI0NiwgMjQwLCAyNTAsIDE3NSwgMTM3LCAxNzUsIDE0MiwKKzE3NSwgMTQ2LCAxNzUsIDE1MSwgMjQxLCAxNjIsIDE3NiwgNjUsIDE3NiwgNzMsIDE3NiwgODEsIDE3NiwgODgsIDE3NiwgOTcsCisxODUsIDIzOSwgMjEyLCAyMzcsIDE3NiwgMTE2LCAyMDUsIDIzOCwgMTc2LCAxMzIsIDE3NiwgMTQxLCAyNDEsIDIyOSwgMTc2LCAxNTcsCisyMTEsIDE3NSwgMTg2LCAyMDgsIDE3NywgNzMsIDE3NywgODEsIDE3NywgODksIDE3NywgOTQsIDIzNywgMjM3LCAxNzcsIDEwNSwKKzE3NywgMTE1LCAyMzcsIDI0MywgMTc3LCAxMjgsIDE5MSwgMjQ0LCAyMTUsIDE5NywgMTc3LCAxNDYsIDE3NywgMTU0LCAxNzgsIDY1LAorMjM3LCAyNTQsIDE3OCwgNzcsIDE3OCwgODYsIDE3OCwgOTAsIDE3OCwgOTcsIDE3OCwgMTA1LCAxNzgsIDExMiwgMTc4LCAxMTcsCisxNzgsIDEyNCwgMTc4LCAxMzIsIDE3OCwgMTQyLCAxNzgsIDE1MSwgMTc4LCAxNTgsIDE3OSwgNjYsIDE3OSwgNzEsIDE4MywgMTc1LAorMTc5LCA4MywgMTk3LCAyNDgsIDIzNywgMTkxLCAyMzcsIDIwNiwgMTk3LCAyMzMsIDIzNywgMTk0LCAxNzksIDExMywgMjM3LCAyMDIsCisxNzksIDEyNCwgMTc5LCAxMzQsIDIxMSwgMTc4LCAxNzksIDE0OSwgMTc5LCAxNTcsIDE4MCwgNjgsIDE4MCwgNzMsIDE4MCwgNzgsCisxODAsIDgzLCAyMzcsIDIxOCwgMTgwLCA5NywgMTgwLCAxMDQsIDE5NywgMjA1LCAxODAsIDExNywgMTgwLCAxMjgsIDE4MCwgMTM2LAorMTgwLCAxNDMsIDE4MCwgMTUxLCAxODAsIDE2MCwgMTgxLCA3MiwgMTgxLCA4MSwgMTgxLCA5MCwgMjM3LCAyMzEsIDIwMSwgMjMxLAorMTk4LCAyMzcsIDE4MSwgMTIwLCAyMzYsIDIzOSwgMTgxLCAxMjksIDE4MSwgMTM1LCAyMzYsIDI0NywgMTk0LCAxODcsIDE4MSwgMTU3LAorMTgyLCA2OSwgMTgyLCA3OCwgMTgyLCA4NywgMTgyLCA5NiwgMjA4LCAyMjcsIDE4MiwgMTA2LCAxODIsIDExMiwgMTgyLCAxMjAsCisxODIsIDEyNSwgMTgyLCAxMzEsIDE4MiwgMTM5LCAyMzksIDI0OSwgMTgyLCAxNTEsIDIxNCwgMjAxLCAxODMsIDY4LCAxODMsIDc4LAorMTgzLCA4NiwgMTgzLCA5MSwgMTgzLCAxMDAsIDE4MywgMTA5LCAxODMsIDExOCwgMTgzLCAxMjksIDIwOSwgMTY4LCAxODMsIDE0MiwKKzI0MSwgMTg2LCAyMTQsIDIwNywgMTgwLCAyMjAsIDI0MSwgMTg4LCAxODQsIDcyLCAxODQsIDgxLCAxODQsIDkwLCAxODQsIDk5LAorMTg0LCAxMDgsIDE4NCwgMTE0LCAxODQsIDEyMSwgMTg0LCAxMzAsIDE4NCwgMTM2LCAyNDMsIDIwMSwgMTc3LCAyMDIsIDI0MywgMjE1LAorMTc3LCAxOTEsIDE4NSwgNjYsIDE5MywgMjUzLCAxODUsIDgwLCAxOTEsIDI0MCwgMjQzLCAyMTcsIDE4NSwgOTQsIDI0MywgMjIzLAorMTg1LCAxMDksIDE4NSwgMTE1LCAxODUsIDEyNCwgMTg1LCAxMzEsIDE4NSwgMTM4LCAyNDMsIDIzNiwgMjQzLCAyNDAsIDE4NSwgMTU1LAorMTg2LCA2NSwgMTg2LCA3MywgMTg2LCA4MCwgMjQzLCAyNDcsIDE4NiwgOTQsIDE4NiwgMTAyLCAxODYsIDExMCwgMTg2LCAxMTcsCisxODYsIDEyNSwgMTg2LCAxMzUsIDE4NiwgMTQyLCAxODYsIDE1MiwgMjQ0LCAxNjYsIDE4NywgNzEsIDE4NywgODAsIDE4NywgOTAsCisxODcsIDEwMCwgMTg3LCAxMTAsIDI0NCwgMjA0LCAxODcsIDEyNSwgMTg3LCAxMzUsIDE4NywgMTQwLCAyMTIsIDE5MywgMTkzLCAxODQsCisxODcsIDE1OCwgMTg4LCA2NiwgMjQ0LCAyMTYsIDIwNCwgMTk5LCAxOTEsIDE4MywgMTg4LCA5MiwgMTg4LCAxMDEsIDE4OCwgMTA5LAorMTg4LCAxMTksIDE4OCwgMTI5LCAxODgsIDEzOSwgMTg4LCAxNDcsIDE4OCwgMTU0LCAxODksIDY3LCAxODksIDc3LCAxODksIDg3LAorMTg5LCA5NywgMTg5LCAxMDcsIDE4OSwgMTE3LCAxODksIDEyNiwgMTg5LCAxMzYsIDE4OSwgMTQ2LCAxODksIDE1NiwgMTkwLCA2OSwKKzE5MCwgNzgsIDE5MCwgODcsIDE5MCwgOTcsIDE5MCwgMTA3LCAxOTAsIDExNywgMTkwLCAxMjgsIDE5MCwgMTM4LCAxOTAsIDE0OCwKKzE5MCwgMTU4LCAxOTEsIDcxLCAxOTEsIDgxLCAxOTEsIDkxLCAxOTEsIDEwMSwgMTkxLCAxMTEsIDE5MSwgMTIxLCAxOTEsIDEzMSwKKzE5MSwgMTM5LCAxOTEsIDE0OSwgMTkxLCAxNTksIDE5MiwgNzIsIDE5MiwgODIsIDE5MiwgOTIsIDE5MiwgMTAxLCAxOTIsIDExMSwKKzE5MiwgMTIxLCAxODYsIDIzNiwgMjA2LCAxNzksIDE5NCwgMjE4LCAyMzEsIDE2NCwgMTc2LCAyMzcsIDIzMSwgMTcxLCAxODksIDIwMiwKKzIzMSwgMTc2LCAyMzEsIDE4MSwgMjE1LCAyMTksIDE5MiwgMTk0LCAxOTIsIDEzNywgMTg0LCAxOTEsIDIzMSwgMjA1LCAyMDEsIDIwMSwKKzE4NCwgMjE1LCAyNDMsIDE5MSwgMTkyLCAxNTUsIDE5MywgNjQsIDE5MywgNzAsIDIxNSwgMjM5LCAyMzgsIDE4OCwgMjM4LCAxOTIsCisxOTMsIDk4LCAxOTMsIDEwNSwgMTkzLCAxMTMsIDE5MywgMTE4LCAyNDQsIDIwMiwgMTkzLCAxMzMsIDE5MywgMTM5LCAyNDQsIDIyNSwKKzE5OSwgMjA0LCAxOTMsIDE1OSwgMTk0LCA2OSwgMTk0LCA3NSwgMjEwLCAxNzEsIDE5NCwgODcsIDI0MSwgMjMyLCAxOTQsIDk1LAorMjQxLCAyNDEsIDE5NCwgMTA2LCAxOTQsIDExMCwgMjQxLCAyNDYsIDE5NCwgMTIxLCAxOTAsIDIxOSwgMTk0LCAxMzgsIDE5NCwgMTQ2LAorMTk0LCAxNTUsIDE5NSwgNjYsIDE4OCwgMTYxLCAyMDgsIDE2NCwgMTc5LCAxNjYsIDE4MywgMTkwLCAyMzUsIDIwMCwgMjAxLCAyNDYsCisxOTUsIDk1LCAxOTUsIDEwMiwgMjAyLCAxNjQsIDE5NSwgMTExLCAyMTAsIDIwMCwgMTc2LCAxODMsIDE5NSwgMTIyLCAyMzUsIDIxOSwKKzIzNSwgMjI4LCAxOTUsIDEzOCwgMjM1LCAyMjcsIDIzNSwgMjI1LCAxOTYsIDY0LCAxOTIsIDE3NiwgMTk5LCAxODcsIDE5NiwgODIsCisxOTYsIDg5LCAxOTYsIDk0LCAyMzUsIDIzOSwgMTk2LCAxMDQsIDE5NiwgMTExLCAxOTYsIDExOSwgMTk2LCAxMjUsIDE5NiwgMTMzLAorMTk2LCAxNDIsIDE3NywgMjE5LCAyMzUsIDI1MSwgMTk3LCA2NiwgMTk3LCA3NiwgMjE1LCAyMTIsIDIxNCwgMTk0LCAyNDQsIDE2NywKKzE5NywgMTAwLCAyMDIsIDIzMCwgMjAzLCAxODAsIDE5NywgMTE4LCAxODksIDE2MiwgMTk3LCAxMjMsIDI0NCwgMTg1LCAxOTcsIDEzOCwKKzIwMywgMjEwLCAxOTcsIDE1NCwgMTk4LCA2NiwgMTk4LCA3MCwgMTk4LCA3NSwgMjIwLCAxODMsIDE5OCwgODUsIDE5OCwgOTAsCisyMjAsIDE4NCwgMTk4LCA5NSwgMTk4LCAxMDAsIDE5OCwgMTA2LCAxOTgsIDEwOCwgMTk4LCAxMTEsIDIyMCwgMjE0LCAxOTgsIDEyMCwKKzE5OCwgMTI2LCAxOTUsIDE3NSwgMjIwLCAyMjEsIDE5OCwgMTQwLCAxOTgsIDE0NiwgMTk4LCAxNTQsIDIyMCwgMjM4LCAxOTksIDY0LAorMTk5LCA3MCwgMTg3LCAxOTYsIDIyMCwgMjM0LCAyMjAsIDI1MywgMTk5LCA4NCwgMTk5LCA5MiwgMTk5LCA5OSwgMjAxLCAxNzUsCisyMjEsIDE4MywgMTk5LCAxMTgsIDE5OSwgMTI0LCAyMjEsIDE3OCwgMjIxLCAyMTAsIDE5MCwgMjEzLCAyMjEsIDIwMiwgMTk5LCAxNTEsCisxOTksIDE1NywgMTgzLCAxOTgsIDIwMCwgNzMsIDIyMSwgMjAxLCAyMDAsIDgzLCAyMDAsIDkxLCAyMTEsIDE2OSwgMjAwLCAxMDQsCisyMjEsIDE5OSwgMjAwLCAxMjAsIDIwMCwgMTMwLCAyMDAsIDEzOSwgMjAwLCAxNDQsIDIwMCwgMTUxLCAyMDAsIDE1NiwgMjAxLCA2NSwKKzIyMSwgMjIwLCAyMDEsIDc4LCAyMDMsIDIyNiwgMjAxLCA5NCwgMjAxLCAxMDMsIDIyMSwgMjQwLCAyMDgsIDIzOCwgMjAxLCAxMjEsCisyMDEsIDEyOCwgMjAxLCAxMzUsIDE5NywgMjM4LCAyMDEsIDE1MCwgMjAxLCAxNTgsIDIwMiwgNzEsIDIwMiwgNzgsIDIwMiwgODYsCisyMDIsIDk0LCAyMDIsIDEwMiwgMTc2LCAxNzAsIDIwMiwgMTE0LCAyMDIsIDEyMSwgMjAyLCAxMzAsIDIyMiwgMTY4LCAyMDIsIDE0NywKKzIwMiwgMTU1LCAyMDMsIDY0LCAyMDMsIDcxLCAyMDMsIDgwLCAyMDMsIDg4LCAyMDgsIDE4OSwgMjAzLCAxMDIsIDIwMywgMTEwLAorMjAzLCAxMTksIDIwMywgMTI2LCAyMjIsIDE4OCwgMjAzLCAxNDMsIDIwMywgMTUyLCAyMDQsIDY1LCAyMDQsIDczLCAyMDQsIDgyLAorMjA0LCA5MCwgMjA0LCAxMDAsIDIwNCwgMTA4LCAyMDQsIDExOCwgMjA0LCAxMjYsIDIwNCwgMTM3LCAyNDIsIDE3NSwgMjExLCAyMjEsCisyMDQsIDE1OCwgMjA1LCA2NywgMjQyLCAxODAsIDIwNSwgNzcsIDIwNSwgODMsIDIwNSwgOTEsIDIxMiwgMjMzLCAyMDUsIDEwMiwKKzIwNSwgMTA2LCAyMDUsIDExNCwgMjA1LCAxMTgsIDIwNSwgMTIzLCAyMDUsIDEyOSwgMjA1LCAxMzcsIDI0MiwgMjExLCAxODIsIDIzNCwKKzI0MiwgMjE4LCAyMDksIDIwOSwgMTk1LCAyMTksIDIwNiwgNzAsIDIwNiwgNzgsIDIwNiwgODUsIDIwNiwgOTIsIDIwOCwgMTcxLAorMjA2LCAxMDUsIDIwNiwgMTEzLCAyMDYsIDEyMCwgMTgxLCAyNTEsIDIwNiwgMTMzLCAyMDYsIDEzOSwgMjA2LCAxNDYsIDIwNiwgMTU1LAorMjQyLCAyNTMsIDIwNywgNzIsIDIwNywgNzksIDI0MywgMTYxLCAyMDcsIDk0LCAyMDcsIDEwMSwgMjA3LCAxMDksIDI0MywgMTgxLAorMjA3LCAxMjYsIDIwNywgMTM1LCAyMDcsIDE0MywgMjQzLCAxODIsIDIwNywgMTU5LCAyMDgsIDcwLCAyMDgsIDc5LCAyMDgsIDg3LAorMjA4LCA5NCwgMjA4LCAxMDIsIDIwOCwgMTA5LCAyMDgsIDExNCwgMjAzLCAxNjUsIDIwOCwgMTI2LCAxNzYsIDE5MiwgMjA4LCAxMzcsCisyMDgsIDE0NSwgMjQxLCAyMDAsIDIwOSwgNjQsIDIwOSwgNzIsIDIwOSwgODAsIDIwOSwgODUsIDIxMCwgMjI1LCAyMDksIDk5LAorMjQxLCAyMTIsIDIwOSwgMTExLCAyNDEsIDIxMSwgMjA5LCAxMjQsIDE4NiwgMjE0LCAyNDEsIDIxMCwgMjA5LCAxNDcsIDIwOSwgMTU0LAorMjEwLCA2NCwgMjEwLCA3MywgMjEwLCA4MiwgMjEwLCA5MiwgMjEwLCAxMDAsIDIxMCwgMTA5LCAyMTAsIDExOSwgMjEwLCAxMjksCisyMTAsIDEzNSwgMjEwLCAxNDUsIDIxMCwgMTU1LCAyMTEsIDY4LCAyMTEsIDc4LCAyMTEsIDg4LCAxODUsIDIzMCwgMjM0LCAyMzYsCisyMTEsIDEwMSwgMjExLCAxMDgsIDIxMSwgMTE0LCAyMTEsIDEyMiwgMjA5LCAyMTIsIDIxMSwgMTQxLCAyMTEsIDE1MSwgMjEyLCA2NCwKKzIxMiwgNzQsIDIxMiwgODQsIDIxMiwgOTQsIDIxMiwgMTAzLCAyMTIsIDExMiwgMjEyLCAxMjIsIDIxMiwgMTMzLCAyMTIsIDE0MywKKzIxMiwgMTUzLCAyMTMsIDY1LCAyMTMsIDczLCAyMTMsIDgyLCAyMTMsIDkyLCAyMTMsIDEwMiwgMjEzLCAxMTIsIDIxMywgMTIyLAorMjEzLCAxMzMsIDIxMywgMTQzLCAyMTMsIDE1MywgMjE0LCA2NiwgMjE0LCA3NiwgMjE0LCA4NiwgMjE0LCA5NiwgMjE0LCAxMDUsCisyMTQsIDExNSwgMjE0LCAxMjUsIDIxNCwgMTM1LCAyMTQsIDE0NSwgMjE0LCAxNTUsIDIxNSwgNjgsIDIxNSwgNzgsIDIxNSwgODgsCisyMTUsIDk3LCAyMTUsIDEwNiwgMjE1LCAxMTYsIDIxNSwgMTI2LCAyMTUsIDEzNywgMjE1LCAxNDcsIDIwMCwgMjA3LCAyMTAsIDIzMywKKzIwOCwgMjM3LCAyMTgsIDE3MiwgMjE0LCAyMjMsIDIxOCwgMTgwLCAyMTgsIDE4NSwgMjE1LCAxNTgsIDIwMywgMTgxLCAxOTEsIDIwNiwKKzIwNCwgMTg0LCAyMTgsIDIwMywgMTk1LCAyMTMsIDE5OSwgMTcxLCAxOTIsIDE5MCwgMjE2LCA2NiwgMjE2LCA3NSwgMjE2LCA4MSwKKzIxNiwgOTAsIDE4NywgMTkxLCAyMTYsIDEwNSwgMjE2LCAxMTQsIDIxNiwgMTIxLCAyNDUsIDI0NiwgMjQ1LCAyNDksIDIxNiwgMTQ1LAorMjE2LCAxNTUsIDIxNywgNjgsIDIxNywgNzgsIDIxNywgODgsIDIxNywgOTgsIDIxNywgMTA4LCAyMTcsIDExOCwgMjE3LCAxMjksCisyMTcsIDEzOSwgMjE3LCAxNDksIDIxNywgMTU5LCAyMTgsIDcyLCAyMTgsIDc5LCAyMDQsIDE3NiwgMjA0LCAyNDksIDE4OCwgMjE0LAorMjM0LCAyMjYsIDIxOCwgODEsIDIxNiwgMjExLCAyMDEsIDIyNiwgMjE1LCAyMjMsIDIxOCwgOTUsIDI0NCwgMjQyLCAyMTgsIDExMCwKKzIxOCwgMTE4LCAyMTgsIDEyOCwgMjE4LCAxMzcsIDIxOCwgMTQzLCAyMTgsIDE0OCwgMjE4LCAxNTUsIDIxOCwgMTYwLCAyNDUsIDIwMCwKKzE5MSwgMjMxLCAyMTksIDc5LCAyMTksIDgyLCAyMTksIDkwLCAyMTksIDk2LCAyMTksIDEwNSwgMjE5LCAxMTAsIDI0NSwgMjE4LAorMjE5LCAxMjMsIDI0NSwgMjI5LCAyMTksIDEzMiwgMjE5LCAxNDAsIDIxOSwgMTQ5LCAyMTksIDE1NywgMjQ1LCAyMzcsIDIyMCwgNzIsCisyMjAsIDc4LCAyMjAsIDg2LCAyNDUsIDI0MiwgMjIwLCAxMDMsIDIyMCwgMTEwLCAyMDQsIDIwMSwgMjIwLCAxMjksIDIzNCwgMTY2LAorMjIwLCAxNDgsIDIyMCwgMTU4LCAyMjEsIDcxLCAyMjEsIDgxLCAyMjEsIDkxLCAyMjEsIDEwMSwgMjIxLCAxMTEsIDIyMSwgMTIxLAorMjIxLCAxMzIsIDIyMSwgMTQyLCAyMjEsIDE1MiwgMjIyLCA2NSwgMjIyLCA3NSwgMjIyLCA4NSwgMjIyLCA5NSwgMTk0LCAyMTQsCisyMzMsIDI0NCwgMjMzLCAyNTEsIDIyMiwgOTksIDIwNywgMTg5LCAyMjIsIDEwMiwgMjIyLCAxMDksIDIyMiwgMTE2LCAxODAsIDIzOSwKKzE5NCwgMjQ1LCAyMjIsIDEzNCwgMjEyLCAxODIsIDIyOSwgMjAwLCAyMDIsIDI0NiwgMjIyLCAxNDksIDIyOSwgMjA0LCAyMjIsIDE1NywKKzIyMiwgMTYwLCAxODMsIDIzNCwgMjIzLCA3NCwgMjI5LCAyMTIsIDIyMywgODUsIDIyMywgOTEsIDIyMywgOTUsIDIyMywgMTAyLAorMjI5LCAyMTksIDIyMywgMTE2LCAyMjMsIDEyNCwgMjIzLCAxMzAsIDIyMywgMTM4LCAyMjMsIDE0MywgMjIzLCAxNDgsIDIxMSwgMjAyLAorMjE5LCAxNjEsIDIyNCwgNjQsIDIyNCwgNzAsIDIyNCwgNzUsIDIyNCwgODEsIDIyNCwgODYsIDE3OSwgMTg3LCAyMTksIDE3NywKKzIyNCwgMTA3LCAyMjQsIDExNywgMjI0LCAxMjYsIDIyNCwgMTM0LCAyMjQsIDE0MywgMjI0LCAxNTEsIDIyNCwgMTYwLCAyNDQsIDI1MiwKKzIyNSwgNzIsIDI0NSwgMTYxLCAxNzksIDIzNCwgMTk1LCAxODQsIDIyNSwgODcsIDIyNSwgOTQsIDIyNSwgOTgsIDIyNSwgMTA2LAorMjI1LCAxMTQsIDIyNSwgMTIwLCAyMjUsIDEyOCwgMjI1LCAxMzgsIDIyNSwgMTQxLCAyMjUsIDE1MCwgMjI1LCAxNTksIDIyNiwgNzIsCisyMjYsIDgyLCAyMjYsIDkyLCAyMjYsIDEwMiwgMjI2LCAxMTIsIDIyNiwgMTIyLCAyMjYsIDEzMywgMjI2LCAxNDMsIDIyNiwgMTUzLAorMjI3LCA2NiwgMjI3LCA3NiwgMjI3LCA4NiwgMjI3LCA5NiwgMjI3LCAxMDYsIDIyNywgMTE1LCAyMjcsIDEyNSwgMjQ2LCAxOTgsCisyMjcsIDE0NSwgMjI3LCAxNTUsIDIyOCwgNjgsIDIyOCwgNzcsIDIyOCwgODcsIDIyOCwgOTYsIDIyOCwgMTA2LCAyMjgsIDExNiwKKzIyOCwgMTI2LCAyMjgsIDEzNywgMjI4LCAxNDcsIDIyOCwgMTU3LCAyMjksIDcwLCAyMjksIDgwLCAyMjksIDkwLCAyMjksIDEwMCwKKzIyOSwgMTEwLCAyMjksIDExOSwgMjI5LCAxMzAsIDIyOSwgMTQwLCAyMjksIDE1MCwgMjQ2LCAyMDIsIDIzMCwgNzIsIDIzMCwgODIsCisyMzAsIDkyLCAyMzAsIDEwMSwgMjMwLCAxMTEsIDIzMCwgMTIxLCAyMzAsIDEzMiwgMjMwLCAxNDIsIDIzMCwgMTUyLCAyMzEsIDY0LAorMjMxLCA3MywgMjMxLCA4MywgMjMxLCA5MywgMjMxLCAxMDMsIDIzMSwgMTEzLCAyMzEsIDEyMywgMjMxLCAxMzQsIDIzMSwgMTQ0LAorMjMxLCAxNTQsIDIzMiwgNjcsIDIzMiwgNzcsIDIzMiwgODYsIDIzMiwgOTYsIDIzMiwgMTA2LCAyMzIsIDExNiwgMjMyLCAxMjUsCisyMzIsIDEzNiwgMjMyLCAxNDYsIDIzOCwgMjAxLCAyMzIsIDE1MCwgMTk2LCAxOTgsIDIzOCwgMjE0LCAyMzgsIDIyMCwgMTg4LCAyMTYsCisyMzgsIDIzMCwgMjM4LCAyMzksIDIwNSwgMTczLCAyMzIsIDE1NywgMTg5LCAxOTQsIDE5OCwgMjA0LCAxNzksIDI1MCwgMjM5LCAxODAsCisyMzksIDE4NywgMjM5LCAxOTIsIDIzOSwgMTk2LCAyMzksIDIwMCwgMTgyLCAxOTgsIDE5NiwgMjQ3LCAyMzksIDIxNywgMjM5LCAyMjMsCisyMzksIDIzMiwgMjM5LCAyMzksIDIzMywgODEsIDIzMywgOTAsIDIzMywgMTAwLCAyMzMsIDExMCwgMjMzLCAxMjAsIDIzMywgMTMxLAorMjMzLCAxNDEsIDIzMywgMTUxLCAyMzQsIDY0LCAyMzQsIDc0LCAyMzQsIDg0LCAyMDEsIDE5MywgMTg4LCAyMjgsIDIyNywgMjA0LAorMjI3LCAyMDgsIDIyNywgMjE0LCAxODQsIDE4MywgMjM0LCAxMDMsIDIzNCwgMTExLCAyMzQsIDExNSwgMTg0LCAxODksIDIzNCwgMTIwLAorMjM0LCAxMjgsIDIxMiwgMTg2LCAyMTgsIDIzOCwgMjA0LCAyMTMsIDIzNCwgMTUzLCAyMzQsIDE2MCwgMTg0LCAyNDQsIDIzNSwgNzQsCisyMzUsIDgzLCAyMzUsIDkyLCAyNDYsIDE5MiwgMTg4LCAxNzUsIDIzNSwgMTA1LCAyMzUsIDExMywgMjM1LCAxMjIsIDIzNSwgMTMwLAorMjM1LCAxMzYsIDIzNSwgMTQyLCAyMzUsIDE0NywgMTkzLCAyMTYsIDIzNSwgMTYwLCAyNDYsIDE3NSwgMjM2LCA3OSwgMjQ2LCAxNzgsCisyMzYsIDk2LCAxOTksIDIyNCwgMjM2LCAxMTEsIDIzNiwgMTE2LCAyMzYsIDEyNSwgMjM2LCAxMzMsIDIzNiwgMTQyLCAyMzYsIDE0OSwKKzE5OSwgMjAyLCAyMzcsIDY3LCAyMzcsIDc1LCAyMzcsIDgxLCAyMzcsIDkxLCAyMzcsIDEwMSwgMjM3LCAxMTEsIDIzNywgMTIxLAorMjM3LCAxMzAsIDIzNywgMTM1LCAyMzcsIDE0MiwgMjM3LCAxNTIsIDIzOCwgNjUsIDIzOCwgNzUsIDIzOCwgODUsIDIzOCwgOTUsCisyMzgsIDEwNSwgMjM4LCAxMTUsIDIzOCwgMTI1LCAyMzgsIDEzNiwgMjM4LCAxNDYsIDIzOCwgMTU2LCAyMzksIDY5LCAxODUsIDIwMywKKzE5MCwgMTc3LCAyMzksIDcyLCAyMDksIDIxMywgMjQyLCAxNzMsIDIzOSwgODQsIDIzOSwgOTQsIDIzOSwgMTA0LCAxODMsIDIzMSwKKzE5OCwgMTc0LCAyMzksIDEyNCwgMjM5LCAxMzMsIDIzOSwgMTQzLCAyMzksIDE1MywgMjQwLCA2NiwgMjQwLCA3NCwgMjQwLCA4NCwKKzI0MCwgOTQsIDI0MCwgMTAzLCAyNDAsIDExMywgMjQwLCAxMjMsIDI0MCwgMTM0LCAyNDAsIDE0MiwgMjQwLCAxNTEsIDIxMCwgMjUxLAorMjQwLCAxNTQsIDI0MCwgMTU4LCAyNDEsIDY0LCAyMDIsIDIxNSwgMjQxLCA3MiwgMjQxLCA4MCwgMjQxLCA5MCwgMjQxLCAxMDAsCisyNDEsIDExMCwgMjQxLCAxMjAsIDI0MSwgMTMxLCAyNDEsIDE0MSwgMjQxLCAxNTEsIDI0MiwgNjQsIDI0MiwgNzQsIDI0MiwgODQsCisyNDIsIDk0LCAyNDIsIDEwNCwgMjQyLCAxMTQsIDI0MiwgMTI0LCAyNDIsIDEzNSwgMjQyLCAxNDUsIDI0MiwgMTU1LCAyNDMsIDY4LAorMjQzLCA3OCwgMjQzLCA4MiwgMjA1LCAyMTMsIDE5NCwgMjMwLCAyMzAsIDIzNSwgMjAxLCAxNjcsIDIxNCwgMjMyLCAyNDMsIDk2LAorMTg2LCAxNjEsIDI0NywgMTk2LCAyNDcsIDE5OCwgMjQzLCAxMjEsIDI0MywgMTMwLCAyNDMsIDEzOCwgMjQzLCAxNDUsIDI0MywgMTUzLAorMjQ3LCAyMjAsIDI0NCwgNzMsIDI0NCwgODIsIDI0NCwgOTAsIDI0NCwgOTksIDI0NCwgMTA4LCAxOTgsIDE5OSwgMjQ0LCAxMTcsCisyNDQsIDEyNCwgMjQ0LCAxMzUsIDI0NCwgMTQ1LCAyNDQsIDE1NSwgMjQ1LCA2OCwgMjQ1LCA3OCwgMjQ1LCA4OCwgMjQ1LCA5OCwKKzI0NSwgMTA4LCAyNDUsIDExOCwgMjQ1LCAxMjksIDI0NSwgMTM5LCAyNDUsIDE0OSwgMjQ1LCAxNTksIDI0NiwgNzIsIDI0NiwgODIsCisyNDYsIDkyLCAyNDYsIDEwMiwgMjQ2LCAxMTIsIDI0NiwgMTIyLCAyNDYsIDEzMywgMjQ2LCAxNDMsIDI0NiwgMTUzLCAyNDcsIDY2LAorMjQ3LCA3NiwgMjQ3LCA4NiwgMjQ3LCA5NiwgMjQ3LCAxMDYsIDI0NywgMTE2LCAyNDcsIDEyNiwgMjQ3LCAxMzMsIDI0NiwgMjE1LAorMjQ3LCAxNDEsIDI0NiwgMjI3LCAyNDcsIDE0NSwgMjQ2LCAyNDMsIDI0NywgMTUwLCAyNDYsIDI1MywgMjQ3LCAxNjcsIDE5MywgMjE5LAorMjQ4LCA2OSwgMjQ4LCA3OSwgMjQ4LCA4OSwgMjQ4LCA5OSwgMjQ4LCAxMDksIDI0OCwgMTE5LCAyNDgsIDEzMCwgMjQ4LCAxNDAsCisyNDgsIDE1MCwgMjQ4LCAxNjAsIDI0OSwgNzMsIDI0OSwgODMsIDI0OSwgOTMsIDI0OSwgMTAzLCAyNDksIDExMywgMjQ5LCAxMjMsCisyNDksIDEzNCwgMjQ5LCAxNDQsIDI0OSwgMTU0LCAyNTAsIDY3LCAyNTAsIDc3LCAyNTAsIDg3LCAyNTAsIDk3LCAyNTAsIDEwNywKKzI1MCwgMTE3LCAyNTAsIDEyOCwgMjUwLCAxMzgsIDI1MCwgMTQ4LCAyNTAsIDE1OCwgMjUxLCA3MSwgMjUxLCA4MSwgMjUxLCA5MSwKKzI0MCwgMTc3LCAyNDAsIDE4MiwgMjUxLCA5OCwgMjQwLCAxOTMsIDI1MSwgMTAxLCAyNDAsIDIwMywgMTg2LCAyMTUsIDI1MSwgMTEzLAorMjUxLCAxMjAsIDI0NywgMjI4LCAyNTEsIDEzNSwgMjUxLCAxNDMsIDI1MSwgMTUxLCAyNTEsIDE2MCwgMjQ0LCAyNDAsIDI0NywgMjI2LAorMjUyLCA4NywgMjUyLCA5MiwgMjQ3LCAyMzcsIDI1MiwgMTAzLCAyNTIsIDEwOSwgMjUyLCAxMTgsIDI1MiwgMTI1LCAxODIsIDE2NiwKKzI1MiwgMTQwLCAyNDcsIDI0NywgMjQ3LCAyNDgsIDI1MywgNjgsIDI1MywgNzMsIDI1MywgODIsIDI1MywgOTAsIDI1MywgMTAwLAorMjUzLCAxMTAsIDI1MywgMTIwLCAyNTMsIDEzMSwgMjQ2LCAxODIsIDI1MywgMTM5LCAxODUsIDE2OCwgMjUzLCAxNTQsIDE3MCwgMTYxLAorMTcwLCAxNzEsIDE3MCwgMTgxLCAxNzAsIDE5MSwgMTcwLCAyMDEsIDE3MCwgMjExLCAxNzAsIDIyMSwgMTcwLCAyMzEsIDE3MCwgMjQxLAorMTcwLCAyNTEsIDE3MSwgMTY3LCAxNzEsIDE3NywgMTcxLCAxODcsIDE3MSwgMTk3LCAxNzEsIDIwNywgMTcxLCAyMTcsIDE3MSwgMjI3LAorMTcxLCAyMzcsIDE3MSwgMjQ3LCAxNzIsIDE2MywgMTcyLCAxNzMsIDE3MiwgMTgzLCAxNzIsIDE5MywgMTcyLCAyMDMsIDE3MiwgMjEzLAorMTcyLCAyMjMsIDE3MiwgMjMzLCAxNzIsIDI0MywgMTcyLCAyNTMsIDE3MywgMTY5LCAxNzMsIDE3OSwgMTczLCAxODksIDE3MywgMTk5LAorMTczLCAyMDksIDE3MywgMjE5LCAxNzMsIDIyOSwgMTczLCAyMzksIDE3MywgMjQ5LCAxNzQsIDE2NSwgMTc0LCAxNzUsIDE3NCwgMTg1LAorMTc0LCAxOTUsIDE3NCwgMjA1LCAxNzQsIDIxNSwgMTc0LCAyMjUsIDE3NCwgMjM1LCAxNzQsIDI0NSwgMTc1LCAxNjEsIDE3NSwgMTcxLAorMTc1LCAxODEsIDE3NSwgMTkxLCAxNzUsIDIwMSwgMTc1LCAyMTEsIDE3NSwgMjIxLCAxNzUsIDIzMSwgMTc1LCAyNDEsIDE3NSwgMjUxLAorMjQ4LCAxNjcsIDI0OCwgMTc3LCAyNDgsIDE4NywgMjQ4LCAxOTcsIDI0OCwgMjA3LCAyNDgsIDIxNywgMjQ4LCAyMjcsIDI0OCwgMjM3LAorMjQ4LCAyNDcsIDI0OSwgMTYzLCAyNDksIDE3MywgMjQ5LCAxODMsIDI0OSwgMTkzLCAyNDksIDIwMywgMjQ5LCAyMTMsIDI0OSwgMjIzLAorMjQ5LCAyMzMsIDI0OSwgMjQzLCAyNDksIDI1MywgMjUwLCAxNjksIDI1MCwgMTc5LCAyNTAsIDE4OSwgMjUwLCAxOTksIDI1MCwgMjA5LAorMjUwLCAyMTksIDI1MCwgMjI5LCAyNTAsIDIzOSwgMjUwLCAyNDksIDI1MSwgMTY1LCAyNTEsIDE3NSwgMjUxLCAxODUsIDI1MSwgMTk1LAorMjUxLCAyMDUsIDI1MSwgMjE1LCAyNTEsIDIyNSwgMjUxLCAyMzUsIDI1MSwgMjQ1LCAyNTIsIDE2MSwgMjUyLCAxNzEsIDI1MiwgMTgxLAorMjUyLCAxOTEsIDI1MiwgMjAxLCAyNTIsIDIxMSwgMjUyLCAyMjEsIDI1MiwgMjMxLCAyNTIsIDI0MSwgMjUyLCAyNTEsIDI1MywgMTY3LAorMjUzLCAxNzcsIDI1MywgMTg3LCAyNTMsIDE5NywgMjUzLCAyMDcsIDI1MywgMjE3LCAyNTMsIDIyNywgMjUzLCAyMzcsIDI1MywgMjQ3LAorMjU0LCAxNjMsIDI1NCwgMTczLCAyNTQsIDE4MywgMjU0LCAxOTMsIDI1NCwgMjAzLCAyNTQsIDIxMywgMjU0LCAyMjMsIDI1NCwgMjMzLAorMjU0LCAyNDMsIDI1NCwgMjUzLCAxNjEsIDcyLCAxNjEsIDgyLCAxNjEsIDkyLCAxNjEsIDEwMiwgMTYxLCAxMTIsIDE2MSwgMTIyLAorMTYxLCAxMzMsIDE2MSwgMTQzLCAxNjEsIDE1MywgMTYyLCA2NiwgMTYyLCA3NiwgMTYyLCA4NiwgMTYyLCA5NiwgMTYyLCAxMDYsCisxNjIsIDExNiwgMTYyLCAxMjYsIDE2MiwgMTM3LCAxNjIsIDE0NywgMTYyLCAxNTcsIDE2MiwgMjI3LCAxNjMsIDY4LCAxNjMsIDc4LAorMTYzLCA4OCwgMTYzLCA5OCwgMTYzLCAxMDgsIDE2MywgMTE4LCAxNjMsIDEyOSwgMTYzLCAxMzksIDE2MywgMTQ5LCAxNjMsIDE1OSwKKzE2NCwgNzIsIDE2NCwgODIsIDE2NCwgOTIsIDE2NCwgMTAyLCAxNjQsIDExMiwgMTY0LCAxMjIsIDE2NCwgMTMzLCAxNjQsIDE0MywKKzE2NCwgMTUzLCAxNjQsIDI0NiwgMTY1LCA2NSwgMTY1LCA3NSwgMTY1LCA4NSwgMTY1LCA5NSwgMTY1LCAxMDUsIDE2NSwgMTE1LAorMTY1LCAxMjUsIDE2NSwgMTM2LCAxNjUsIDE0NiwgMTY1LCAxNTYsIDE2NSwgMjUyLCAxNjYsIDcxLCAxNjYsIDgxLCAxNjYsIDkxLAorMTY2LCAxMDEsIDE2NiwgMTExLCAxNjYsIDEyMSwgMTY2LCAxMzIsIDE2NiwgMTQyLCAxNjYsIDE1MiwgMTY2LCAxODYsIDE2NiwgMjIwLAorMTY2LCAyNDksIDE2NywgNjgsIDE2NywgNzgsIDE2NywgODgsIDE2NywgOTgsIDE2NywgMTA4LCAxNjcsIDExOCwgMTY3LCAxMjksCisxNjcsIDEzOSwgMTY3LCAxNDksIDE2NywgMTU5LCAxNjcsIDIwMiwgMTY3LCAyNDUsIDE2OCwgMTUwLCAxNjgsIDE2MCwgMTY4LCAyMzcsCisxNjgsIDI0NywgMTY5LCA5MywgMTY5LCAxNDQsIDE2OSwgMTU1LCAxNjksIDI0MSwgMTY5LCAyNTEsIDI1NCwgODEsIDI1NCwgOTEsCisyNTQsIDEwMSwgMjU0LCAxMTEsIDI1NCwgMTIxLCAyNTQsIDEzMiwgMjU0LCAxNDIsIDI1NCwgMTUyLCAyNTMsIDE1NiwgMjUzLCAxNTcsCisyNTMsIDE1OCwgMjUzLCAxNTksIDI1MywgMTYwLCAyNTQsIDY0LCAyNTQsIDcxLCAyNTQsIDc1LCAxNjksIDg1LCAxNjYsIDIyNywKKzE2NiwgMjM1LCAxNjksIDEwOSwgMTY5LCAxMTgsIDE2OSwgMTI5LCAxNjMsIDE2MSwgMTYzLCAxNzEsIDE2MywgMTgxLCAxNjMsIDE5MSwKKzE2MywgMjAxLCAxNjMsIDIxMSwgMTYzLCAyMjEsIDE2MywgMjMxLCAxNjMsIDI0MSwgMTYzLCAyNTEsIDE2MSwgMjMzLCAwICAgICAgICAgICAgfSk7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX0dCS19BbmRyb2lkLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX0dCS19BbmRyb2lkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2MwYzYwYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9NdWx0aUJ5dGVfR0JLX0FuZHJvaWQuamF2YQpAQCAtMCwwICsxLDUxMyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFyc2V0OworCisvKiogTm90ZTogSUNVIGJlaGF2ZXMgZGlmZmVyZW50bHkgZnJvbSB0aGUgUkkgKi8KKworcHVibGljIGNsYXNzIE9sZENoYXJzZXRfTXVsdGlCeXRlX0dCS19BbmRyb2lkIGV4dGVuZHMgT2xkQ2hhcnNldF9BYnN0cmFjdFRlc3QgeworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcnNldE5hbWUgPSAiR0JLIjsKKworICAgICAgICB0ZXN0Q2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKzAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKzMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCis2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKzgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisxNjQsIDE2NywgMTY4LCAxNzYsIDE3NywgMTgzLCAyMTUsIDIyNCwgMjI1LCAyMzIsIDIzMywgMjM0LCAyMzYsIDIzNywgMjQyLCAyNDMsCisyNDcsIDI0OSwgMjUwLCAyNTIsIDI1NywgMjc1LCAyOTksIDMyNCwgMzYzLCA0NjIsIDQ3MiwgNTkzLCA2MDksIDcxMSwgNzI5LCA5MTMsCis5MjMsIDkzMywgOTQ1LCA5NTUsIDk2NSwgMTAyNSwgMTA0MCwgMTA1MCwgMTA2MCwgMTA3MCwgMTA4MCwgMTA5MCwgMTEwMCwgODIwOCwgODIyMCwgODIzMCwKKzgyNDAsIDgyNTEsIDg0NTEsIDg0NzAsIDg0ODEsIDg1NDQsIDg1NTQsIDg1NjQsIDg1OTIsIDg3MTIsIDg3MjUsIDg3MzUsIDg3NDUsIDg3NTYsIDg3NzYsIDg3ODYsCis4ODAwLCA4ODE0LCA4ODU3LCA4ODY5LCA4ODk1LCA4OTc4LCA5MzEyLCA5MzMyLCA5MzQyLCA5MzUyLCA5MzYyLCA5NDcyLCA5NDgyLCA5NDkyLCA5NTAyLCA5NTEyLAorOTUyMiwgOTUzMiwgOTU0MiwgOTU1MiwgOTU2MiwgOTU3MiwgOTU4MiwgOTYwMSwgOTYxMSwgOTYyMSwgOTYzMiwgOTY1MCwgOTY2MCwgOTY3MCwgOTY5OCwgOTczMywKKzk3OTIsIDEyMjg4LCAxMjI5OCwgMTIzMDgsIDEyMzE4LCAxMjMyOCwgMTIzNTMsIDEyMzYzLCAxMjM3MywgMTIzODMsIDEyMzkzLCAxMjQwMywgMTI0MTMsIDEyNDIzLCAxMjQzMywgMTI0NDMsCisxMjQ1MywgMTI0NjMsIDEyNDczLCAxMjQ4MywgMTI0OTMsIDEyNTAzLCAxMjUxMywgMTI1MjMsIDEyNTMzLCAxMjU0OSwgMTI1NTksIDEyNTY5LCAxMjU3OSwgMTI4MzIsIDEyODQ5LCAxMjk2MywKKzEzMTk4LCAxMzIxMiwgMTMyNTIsIDEzMjYyLCAxOTk2OCwgMTk5NzgsIDE5OTg4LCAxOTk5OCwgMjAwMDgsIDIwMDE4LCAyMDAyOCwgMjAwMzgsIDIwMDQ4LCAyMDA1OCwgMjAwNjgsIDIwMDc4LAorMjAwODgsIDIwMDk4LCAyMDEwOCwgMjAxMTgsIDIwMTI4LCAyMDEzOCwgMjAxNDgsIDIwMTU4LCAyMDE2OCwgMjAxNzgsIDIwMTg4LCAyMDE5OCwgMjAyMDgsIDIwMjE4LCAyMDIyOCwgMjAyMzgsCisyMDI0OCwgMjAyNTgsIDIwMjY4LCAyMDI3OCwgMjAyODgsIDIwMjk4LCAyMDMwOCwgMjAzMTgsIDIwMzI4LCAyMDMzOCwgMjAzNDgsIDIwMzU4LCAyMDM2OCwgMjAzNzgsIDIwMzg4LCAyMDM5OCwKKzIwNDA4LCAyMDQxOCwgMjA0MjgsIDIwNDM4LCAyMDQ0OCwgMjA0NTgsIDIwNDY4LCAyMDQ3OCwgMjA0ODgsIDIwNDk4LCAyMDUwOCwgMjA1MTgsIDIwNTI4LCAyMDUzOCwgMjA1NDgsIDIwNTU4LAorMjA1NjgsIDIwNTc4LCAyMDU4OCwgMjA1OTgsIDIwNjA4LCAyMDYxOCwgMjA2MjgsIDIwNjM4LCAyMDY0OCwgMjA2NTgsIDIwNjY4LCAyMDY3OCwgMjA2ODgsIDIwNjk4LCAyMDcwOCwgMjA3MTgsCisyMDcyOCwgMjA3MzgsIDIwNzQ4LCAyMDc1OCwgMjA3NjgsIDIwNzc4LCAyMDc4OCwgMjA3OTgsIDIwODA4LCAyMDgxOCwgMjA4MjgsIDIwODM4LCAyMDg0OCwgMjA4NTgsIDIwODY4LCAyMDg3OCwKKzIwODg4LCAyMDg5OCwgMjA5MDgsIDIwOTE4LCAyMDkyOCwgMjA5MzgsIDIwOTQ4LCAyMDk1OCwgMjA5NjgsIDIwOTc4LCAyMDk4OCwgMjA5OTgsIDIxMDA4LCAyMTAxOCwgMjEwMjgsIDIxMDM4LAorMjEwNDgsIDIxMDU4LCAyMTA2OCwgMjEwNzgsIDIxMDg4LCAyMTA5OCwgMjExMDgsIDIxMTE4LCAyMTEyOCwgMjExMzgsIDIxMTQ4LCAyMTE1OCwgMjExNjgsIDIxMTc4LCAyMTE4OCwgMjExOTgsCisyMTIwOCwgMjEyMTgsIDIxMjI4LCAyMTIzOCwgMjEyNDgsIDIxMjU4LCAyMTI2OCwgMjEyNzgsIDIxMjg4LCAyMTI5OCwgMjEzMDgsIDIxMzE4LCAyMTMyOCwgMjEzMzgsIDIxMzQ4LCAyMTM1OCwKKzIxMzY4LCAyMTM3OCwgMjEzODgsIDIxMzk4LCAyMTQwOCwgMjE0MTgsIDIxNDI4LCAyMTQzOCwgMjE0NDgsIDIxNDU4LCAyMTQ2OCwgMjE0NzgsIDIxNDg4LCAyMTQ5OCwgMjE1MDgsIDIxNTE4LAorMjE1MjgsIDIxNTM4LCAyMTU0OCwgMjE1NTgsIDIxNTY4LCAyMTU3OCwgMjE1ODgsIDIxNTk4LCAyMTYwOCwgMjE2MTgsIDIxNjI4LCAyMTYzOCwgMjE2NDgsIDIxNjU4LCAyMTY2OCwgMjE2NzgsCisyMTY4OCwgMjE2OTgsIDIxNzA4LCAyMTcxOCwgMjE3MjgsIDIxNzM4LCAyMTc0OCwgMjE3NTgsIDIxNzY4LCAyMTc3OCwgMjE3ODgsIDIxNzk4LCAyMTgwOCwgMjE4MTgsIDIxODI4LCAyMTgzOCwKKzIxODQ4LCAyMTg1OCwgMjE4NjgsIDIxODc4LCAyMTg4OCwgMjE4OTgsIDIxOTA4LCAyMTkxOCwgMjE5MjgsIDIxOTM4LCAyMTk0OCwgMjE5NTgsIDIxOTY4LCAyMTk3OCwgMjE5ODgsIDIxOTk4LAorMjIwMDgsIDIyMDE4LCAyMjAyOCwgMjIwMzgsIDIyMDQ4LCAyMjA1OCwgMjIwNjgsIDIyMDc4LCAyMjA4OCwgMjIwOTgsIDIyMTA4LCAyMjExOCwgMjIxMjgsIDIyMTM4LCAyMjE0OCwgMjIxNTgsCisyMjE2OCwgMjIxNzgsIDIyMTg4LCAyMjE5OCwgMjIyMDgsIDIyMjE4LCAyMjIyOCwgMjIyMzgsIDIyMjQ4LCAyMjI1OCwgMjIyNjgsIDIyMjc4LCAyMjI4OCwgMjIyOTgsIDIyMzA4LCAyMjMxOCwKKzIyMzI4LCAyMjMzOCwgMjIzNDgsIDIyMzU4LCAyMjM2OCwgMjIzNzgsIDIyMzg4LCAyMjM5OCwgMjI0MDgsIDIyNDE4LCAyMjQyOCwgMjI0MzgsIDIyNDQ4LCAyMjQ1OCwgMjI0NjgsIDIyNDc4LAorMjI0ODgsIDIyNDk4LCAyMjUwOCwgMjI1MTgsIDIyNTI4LCAyMjUzOCwgMjI1NDgsIDIyNTU4LCAyMjU2OCwgMjI1NzgsIDIyNTg4LCAyMjU5OCwgMjI2MDgsIDIyNjE4LCAyMjYyOCwgMjI2MzgsCisyMjY0OCwgMjI2NTgsIDIyNjY4LCAyMjY3OCwgMjI2ODgsIDIyNjk4LCAyMjcwOCwgMjI3MTgsIDIyNzI4LCAyMjczOCwgMjI3NDgsIDIyNzU4LCAyMjc2OCwgMjI3NzgsIDIyNzg4LCAyMjc5OCwKKzIyODA4LCAyMjgxOCwgMjI4MjgsIDIyODM4LCAyMjg0OCwgMjI4NTgsIDIyODY4LCAyMjg3OCwgMjI4ODgsIDIyODk4LCAyMjkwOCwgMjI5MTgsIDIyOTI4LCAyMjkzOCwgMjI5NDgsIDIyOTU4LAorMjI5NjgsIDIyOTc4LCAyMjk4OCwgMjI5OTgsIDIzMDA4LCAyMzAxOCwgMjMwMjgsIDIzMDM4LCAyMzA0OCwgMjMwNTgsIDIzMDY4LCAyMzA3OCwgMjMwODgsIDIzMDk4LCAyMzEwOCwgMjMxMTgsCisyMzEyOCwgMjMxMzgsIDIzMTQ4LCAyMzE1OCwgMjMxNjgsIDIzMTc4LCAyMzE4OCwgMjMxOTgsIDIzMjA4LCAyMzIxOCwgMjMyMjgsIDIzMjM4LCAyMzI0OCwgMjMyNTgsIDIzMjY4LCAyMzI3OCwKKzIzMjg4LCAyMzI5OCwgMjMzMDgsIDIzMzE4LCAyMzMyOCwgMjMzMzgsIDIzMzQ4LCAyMzM1OCwgMjMzNjgsIDIzMzc4LCAyMzM4OCwgMjMzOTgsIDIzNDA4LCAyMzQxOCwgMjM0MjgsIDIzNDM4LAorMjM0NDgsIDIzNDU4LCAyMzQ2OCwgMjM0NzgsIDIzNDg4LCAyMzQ5OCwgMjM1MDgsIDIzNTE4LCAyMzUyOCwgMjM1MzgsIDIzNTQ4LCAyMzU1OCwgMjM1NjgsIDIzNTc4LCAyMzU4OCwgMjM1OTgsCisyMzYwOCwgMjM2MTgsIDIzNjI4LCAyMzYzOCwgMjM2NDgsIDIzNjU4LCAyMzY2OCwgMjM2NzgsIDIzNjg4LCAyMzY5OCwgMjM3MDgsIDIzNzE4LCAyMzcyOCwgMjM3MzgsIDIzNzQ4LCAyMzc1OCwKKzIzNzY4LCAyMzc3OCwgMjM3ODgsIDIzNzk4LCAyMzgwOCwgMjM4MTgsIDIzODI4LCAyMzgzOCwgMjM4NDgsIDIzODU4LCAyMzg2OCwgMjM4NzgsIDIzODg4LCAyMzg5OCwgMjM5MDgsIDIzOTE4LAorMjM5MjgsIDIzOTM4LCAyMzk0OCwgMjM5NTgsIDIzOTY4LCAyMzk3OCwgMjM5ODgsIDIzOTk4LCAyNDAwOCwgMjQwMTgsIDI0MDI4LCAyNDAzOCwgMjQwNDgsIDI0MDU4LCAyNDA2OCwgMjQwNzgsCisyNDA4OCwgMjQwOTgsIDI0MTA4LCAyNDExOCwgMjQxMjgsIDI0MTM4LCAyNDE0OCwgMjQxNTgsIDI0MTY4LCAyNDE3OCwgMjQxODgsIDI0MTk4LCAyNDIwOCwgMjQyMTgsIDI0MjI4LCAyNDIzOCwKKzI0MjQ4LCAyNDI1OCwgMjQyNjgsIDI0Mjc4LCAyNDI4OCwgMjQyOTgsIDI0MzA4LCAyNDMxOCwgMjQzMjgsIDI0MzM4LCAyNDM0OCwgMjQzNTgsIDI0MzY4LCAyNDM3OCwgMjQzODgsIDI0Mzk4LAorMjQ0MDgsIDI0NDE4LCAyNDQyOCwgMjQ0MzgsIDI0NDQ4LCAyNDQ1OCwgMjQ0NjgsIDI0NDc4LCAyNDQ4OCwgMjQ0OTgsIDI0NTA4LCAyNDUxOCwgMjQ1MjgsIDI0NTM4LCAyNDU0OCwgMjQ1NTgsCisyNDU2OCwgMjQ1NzgsIDI0NTg4LCAyNDU5OCwgMjQ2MDgsIDI0NjE4LCAyNDYyOCwgMjQ2MzgsIDI0NjQ4LCAyNDY1OCwgMjQ2NjgsIDI0Njc4LCAyNDY4OCwgMjQ2OTgsIDI0NzA4LCAyNDcxOCwKKzI0NzI4LCAyNDczOCwgMjQ3NDgsIDI0NzU4LCAyNDc2OCwgMjQ3NzgsIDI0Nzg4LCAyNDc5OCwgMjQ4MDgsIDI0ODE4LCAyNDgyOCwgMjQ4MzgsIDI0ODQ4LCAyNDg1OCwgMjQ4NjgsIDI0ODc4LAorMjQ4ODgsIDI0ODk4LCAyNDkwOCwgMjQ5MTgsIDI0OTI4LCAyNDkzOCwgMjQ5NDgsIDI0OTU4LCAyNDk2OCwgMjQ5NzgsIDI0OTg4LCAyNDk5OCwgMjUwMDgsIDI1MDE4LCAyNTAyOCwgMjUwMzgsCisyNTA0OCwgMjUwNTgsIDI1MDY4LCAyNTA3OCwgMjUwODgsIDI1MDk4LCAyNTEwOCwgMjUxMTgsIDI1MTI4LCAyNTEzOCwgMjUxNDgsIDI1MTU4LCAyNTE2OCwgMjUxNzgsIDI1MTg4LCAyNTE5OCwKKzI1MjA4LCAyNTIxOCwgMjUyMjgsIDI1MjM4LCAyNTI0OCwgMjUyNTgsIDI1MjY4LCAyNTI3OCwgMjUyODgsIDI1Mjk4LCAyNTMwOCwgMjUzMTgsIDI1MzI4LCAyNTMzOCwgMjUzNDgsIDI1MzU4LAorMjUzNjgsIDI1Mzc4LCAyNTM4OCwgMjUzOTgsIDI1NDA4LCAyNTQxOCwgMjU0MjgsIDI1NDM4LCAyNTQ0OCwgMjU0NTgsIDI1NDY4LCAyNTQ3OCwgMjU0ODgsIDI1NDk4LCAyNTUwOCwgMjU1MTgsCisyNTUyOCwgMjU1MzgsIDI1NTQ4LCAyNTU1OCwgMjU1NjgsIDI1NTc4LCAyNTU4OCwgMjU1OTgsIDI1NjA4LCAyNTYxOCwgMjU2MjgsIDI1NjM4LCAyNTY0OCwgMjU2NTgsIDI1NjY4LCAyNTY3OCwKKzI1Njg4LCAyNTY5OCwgMjU3MDgsIDI1NzE4LCAyNTcyOCwgMjU3MzgsIDI1NzQ4LCAyNTc1OCwgMjU3NjgsIDI1Nzc4LCAyNTc4OCwgMjU3OTgsIDI1ODA4LCAyNTgxOCwgMjU4MjgsIDI1ODM4LAorMjU4NDgsIDI1ODU4LCAyNTg2OCwgMjU4NzgsIDI1ODg4LCAyNTg5OCwgMjU5MDgsIDI1OTE4LCAyNTkyOCwgMjU5MzgsIDI1OTQ4LCAyNTk1OCwgMjU5NjgsIDI1OTc4LCAyNTk4OCwgMjU5OTgsCisyNjAwOCwgMjYwMTgsIDI2MDI4LCAyNjAzOCwgMjYwNDgsIDI2MDU4LCAyNjA2OCwgMjYwNzgsIDI2MDg4LCAyNjA5OCwgMjYxMDgsIDI2MTE4LCAyNjEyOCwgMjYxMzgsIDI2MTQ4LCAyNjE1OCwKKzI2MTY4LCAyNjE3OCwgMjYxODgsIDI2MTk4LCAyNjIwOCwgMjYyMTgsIDI2MjI4LCAyNjIzOCwgMjYyNDgsIDI2MjU4LCAyNjI2OCwgMjYyNzgsIDI2Mjg4LCAyNjI5OCwgMjYzMDgsIDI2MzE4LAorMjYzMjgsIDI2MzM4LCAyNjM0OCwgMjYzNTgsIDI2MzY4LCAyNjM3OCwgMjYzODgsIDI2Mzk4LCAyNjQwOCwgMjY0MTgsIDI2NDI4LCAyNjQzOCwgMjY0NDgsIDI2NDU4LCAyNjQ2OCwgMjY0NzgsCisyNjQ4OCwgMjY0OTgsIDI2NTA4LCAyNjUxOCwgMjY1MjgsIDI2NTM4LCAyNjU0OCwgMjY1NTgsIDI2NTY4LCAyNjU3OCwgMjY1ODgsIDI2NTk4LCAyNjYwOCwgMjY2MTgsIDI2NjI4LCAyNjYzOCwKKzI2NjQ4LCAyNjY1OCwgMjY2NjgsIDI2Njc4LCAyNjY4OCwgMjY2OTgsIDI2NzA4LCAyNjcxOCwgMjY3MjgsIDI2NzM4LCAyNjc0OCwgMjY3NTgsIDI2NzY4LCAyNjc3OCwgMjY3ODgsIDI2Nzk4LAorMjY4MDgsIDI2ODE4LCAyNjgyOCwgMjY4MzgsIDI2ODQ4LCAyNjg1OCwgMjY4NjgsIDI2ODc4LCAyNjg4OCwgMjY4OTgsIDI2OTA4LCAyNjkxOCwgMjY5MjgsIDI2OTM4LCAyNjk0OCwgMjY5NTgsCisyNjk2OCwgMjY5NzgsIDI2OTg4LCAyNjk5OCwgMjcwMDgsIDI3MDE4LCAyNzAyOCwgMjcwMzgsIDI3MDQ4LCAyNzA1OCwgMjcwNjgsIDI3MDc4LCAyNzA4OCwgMjcwOTgsIDI3MTA4LCAyNzExOCwKKzI3MTI4LCAyNzEzOCwgMjcxNDgsIDI3MTU4LCAyNzE2OCwgMjcxNzgsIDI3MTg4LCAyNzE5OCwgMjcyMDgsIDI3MjE4LCAyNzIyOCwgMjcyMzgsIDI3MjQ4LCAyNzI1OCwgMjcyNjgsIDI3Mjc4LAorMjcyODgsIDI3Mjk4LCAyNzMwOCwgMjczMTgsIDI3MzI4LCAyNzMzOCwgMjczNDgsIDI3MzU4LCAyNzM2OCwgMjczNzgsIDI3Mzg4LCAyNzM5OCwgMjc0MDgsIDI3NDE4LCAyNzQyOCwgMjc0MzgsCisyNzQ0OCwgMjc0NTgsIDI3NDY4LCAyNzQ3OCwgMjc0ODgsIDI3NDk4LCAyNzUwOCwgMjc1MTgsIDI3NTI4LCAyNzUzOCwgMjc1NDgsIDI3NTU4LCAyNzU2OCwgMjc1NzgsIDI3NTg4LCAyNzU5OCwKKzI3NjA4LCAyNzYxOCwgMjc2MjgsIDI3NjM4LCAyNzY0OCwgMjc2NTgsIDI3NjY4LCAyNzY3OCwgMjc2ODgsIDI3Njk4LCAyNzcwOCwgMjc3MTgsIDI3NzI4LCAyNzczOCwgMjc3NDgsIDI3NzU4LAorMjc3NjgsIDI3Nzc4LCAyNzc4OCwgMjc3OTgsIDI3ODA4LCAyNzgxOCwgMjc4MjgsIDI3ODM4LCAyNzg0OCwgMjc4NTgsIDI3ODY4LCAyNzg3OCwgMjc4ODgsIDI3ODk4LCAyNzkwOCwgMjc5MTgsCisyNzkyOCwgMjc5MzgsIDI3OTQ4LCAyNzk1OCwgMjc5NjgsIDI3OTc4LCAyNzk4OCwgMjc5OTgsIDI4MDA4LCAyODAxOCwgMjgwMjgsIDI4MDM4LCAyODA0OCwgMjgwNTgsIDI4MDY4LCAyODA3OCwKKzI4MDg4LCAyODA5OCwgMjgxMDgsIDI4MTE4LCAyODEyOCwgMjgxMzgsIDI4MTQ4LCAyODE1OCwgMjgxNjgsIDI4MTc4LCAyODE4OCwgMjgxOTgsIDI4MjA4LCAyODIxOCwgMjgyMjgsIDI4MjM4LAorMjgyNDgsIDI4MjU4LCAyODI2OCwgMjgyNzgsIDI4Mjg4LCAyODI5OCwgMjgzMDgsIDI4MzE4LCAyODMyOCwgMjgzMzgsIDI4MzQ4LCAyODM1OCwgMjgzNjgsIDI4Mzc4LCAyODM4OCwgMjgzOTgsCisyODQwOCwgMjg0MTgsIDI4NDI4LCAyODQzOCwgMjg0NDgsIDI4NDU4LCAyODQ2OCwgMjg0NzgsIDI4NDg4LCAyODQ5OCwgMjg1MDgsIDI4NTE4LCAyODUyOCwgMjg1MzgsIDI4NTQ4LCAyODU1OCwKKzI4NTY4LCAyODU3OCwgMjg1ODgsIDI4NTk4LCAyODYwOCwgMjg2MTgsIDI4NjI4LCAyODYzOCwgMjg2NDgsIDI4NjU4LCAyODY2OCwgMjg2NzgsIDI4Njg4LCAyODY5OCwgMjg3MDgsIDI4NzE4LAorMjg3MjgsIDI4NzM4LCAyODc0OCwgMjg3NTgsIDI4NzY4LCAyODc3OCwgMjg3ODgsIDI4Nzk4LCAyODgwOCwgMjg4MTgsIDI4ODI4LCAyODgzOCwgMjg4NDgsIDI4ODU4LCAyODg2OCwgMjg4NzgsCisyODg4OCwgMjg4OTgsIDI4OTA4LCAyODkxOCwgMjg5MjgsIDI4OTM4LCAyODk0OCwgMjg5NTgsIDI4OTY4LCAyODk3OCwgMjg5ODgsIDI4OTk4LCAyOTAwOCwgMjkwMTgsIDI5MDI4LCAyOTAzOCwKKzI5MDQ4LCAyOTA1OCwgMjkwNjgsIDI5MDc4LCAyOTA4OCwgMjkwOTgsIDI5MTA4LCAyOTExOCwgMjkxMjgsIDI5MTM4LCAyOTE0OCwgMjkxNTgsIDI5MTY4LCAyOTE3OCwgMjkxODgsIDI5MTk4LAorMjkyMDgsIDI5MjE4LCAyOTIyOCwgMjkyMzgsIDI5MjQ4LCAyOTI1OCwgMjkyNjgsIDI5Mjc4LCAyOTI4OCwgMjkyOTgsIDI5MzA4LCAyOTMxOCwgMjkzMjgsIDI5MzM4LCAyOTM0OCwgMjkzNTgsCisyOTM2OCwgMjkzNzgsIDI5Mzg4LCAyOTM5OCwgMjk0MDgsIDI5NDE4LCAyOTQyOCwgMjk0MzgsIDI5NDQ4LCAyOTQ1OCwgMjk0NjgsIDI5NDc4LCAyOTQ4OCwgMjk0OTgsIDI5NTA4LCAyOTUxOCwKKzI5NTI4LCAyOTUzOCwgMjk1NDgsIDI5NTU4LCAyOTU2OCwgMjk1NzgsIDI5NTg4LCAyOTU5OCwgMjk2MDgsIDI5NjE4LCAyOTYyOCwgMjk2MzgsIDI5NjQ4LCAyOTY1OCwgMjk2NjgsIDI5Njc4LAorMjk2ODgsIDI5Njk4LCAyOTcwOCwgMjk3MTgsIDI5NzI4LCAyOTczOCwgMjk3NDgsIDI5NzU4LCAyOTc2OCwgMjk3NzgsIDI5Nzg4LCAyOTc5OCwgMjk4MDgsIDI5ODE4LCAyOTgyOCwgMjk4MzgsCisyOTg0OCwgMjk4NTgsIDI5ODY4LCAyOTg3OCwgMjk4ODgsIDI5ODk4LCAyOTkwOCwgMjk5MTgsIDI5OTI4LCAyOTkzOCwgMjk5NDgsIDI5OTU4LCAyOTk2OCwgMjk5NzgsIDI5OTg4LCAyOTk5OCwKKzMwMDA4LCAzMDAxOCwgMzAwMjgsIDMwMDM4LCAzMDA0OCwgMzAwNTgsIDMwMDY4LCAzMDA3OCwgMzAwODgsIDMwMDk4LCAzMDEwOCwgMzAxMTgsIDMwMTI4LCAzMDEzOCwgMzAxNDgsIDMwMTU4LAorMzAxNjgsIDMwMTc4LCAzMDE4OCwgMzAxOTgsIDMwMjA4LCAzMDIxOCwgMzAyMjgsIDMwMjM4LCAzMDI0OCwgMzAyNTgsIDMwMjY4LCAzMDI3OCwgMzAyODgsIDMwMjk4LCAzMDMwOCwgMzAzMTgsCiszMDMyOCwgMzAzMzgsIDMwMzQ4LCAzMDM1OCwgMzAzNjgsIDMwMzc4LCAzMDM4OCwgMzAzOTgsIDMwNDA4LCAzMDQxOCwgMzA0MjgsIDMwNDM4LCAzMDQ0OCwgMzA0NTgsIDMwNDY4LCAzMDQ3OCwKKzMwNDg4LCAzMDQ5OCwgMzA1MDgsIDMwNTE4LCAzMDUyOCwgMzA1MzgsIDMwNTQ4LCAzMDU1OCwgMzA1NjgsIDMwNTc4LCAzMDU4OCwgMzA1OTgsIDMwNjA4LCAzMDYxOCwgMzA2MjgsIDMwNjM4LAorMzA2NDgsIDMwNjU4LCAzMDY2OCwgMzA2NzgsIDMwNjg4LCAzMDY5OCwgMzA3MDgsIDMwNzE4LCAzMDcyOCwgMzA3MzgsIDMwNzQ4LCAzMDc1OCwgMzA3NjgsIDMwNzc4LCAzMDc4OCwgMzA3OTgsCiszMDgwOCwgMzA4MTgsIDMwODI4LCAzMDgzOCwgMzA4NDgsIDMwODU4LCAzMDg2OCwgMzA4NzgsIDMwODg4LCAzMDg5OCwgMzA5MDgsIDMwOTE4LCAzMDkyOCwgMzA5MzgsIDMwOTQ4LCAzMDk1OCwKKzMwOTY4LCAzMDk3OCwgMzA5ODgsIDMwOTk4LCAzMTAwOCwgMzEwMTgsIDMxMDI4LCAzMTAzOCwgMzEwNDgsIDMxMDU4LCAzMTA2OCwgMzEwNzgsIDMxMDg4LCAzMTA5OCwgMzExMDgsIDMxMTE4LAorMzExMjgsIDMxMTM4LCAzMTE0OCwgMzExNTgsIDMxMTY4LCAzMTE3OCwgMzExODgsIDMxMTk4LCAzMTIwOCwgMzEyMTgsIDMxMjI4LCAzMTIzOCwgMzEyNDgsIDMxMjU4LCAzMTI2OCwgMzEyNzgsCiszMTI4OCwgMzEyOTgsIDMxMzA4LCAzMTMxOCwgMzEzMjgsIDMxMzM4LCAzMTM0OCwgMzEzNTgsIDMxMzY4LCAzMTM3OCwgMzEzODgsIDMxMzk4LCAzMTQwOCwgMzE0MTgsIDMxNDI4LCAzMTQzOCwKKzMxNDQ4LCAzMTQ1OCwgMzE0NjgsIDMxNDc4LCAzMTQ4OCwgMzE0OTgsIDMxNTA4LCAzMTUxOCwgMzE1MjgsIDMxNTM4LCAzMTU0OCwgMzE1NTgsIDMxNTY4LCAzMTU3OCwgMzE1ODgsIDMxNTk4LAorMzE2MDgsIDMxNjE4LCAzMTYyOCwgMzE2MzgsIDMxNjQ4LCAzMTY1OCwgMzE2NjgsIDMxNjc4LCAzMTY4OCwgMzE2OTgsIDMxNzA4LCAzMTcxOCwgMzE3MjgsIDMxNzM4LCAzMTc0OCwgMzE3NTgsCiszMTc2OCwgMzE3NzgsIDMxNzg4LCAzMTc5OCwgMzE4MDgsIDMxODE4LCAzMTgyOCwgMzE4MzgsIDMxODQ4LCAzMTg1OCwgMzE4NjgsIDMxODc4LCAzMTg4OCwgMzE4OTgsIDMxOTA4LCAzMTkxOCwKKzMxOTI4LCAzMTkzOCwgMzE5NDgsIDMxOTU4LCAzMTk2OCwgMzE5NzgsIDMxOTg4LCAzMTk5OCwgMzIwMDgsIDMyMDE4LCAzMjAyOCwgMzIwMzgsIDMyMDQ4LCAzMjA1OCwgMzIwNjgsIDMyMDc4LAorMzIwODgsIDMyMDk4LCAzMjEwOCwgMzIxMTgsIDMyMTI4LCAzMjEzOCwgMzIxNDgsIDMyMTU4LCAzMjE2OCwgMzIxNzgsIDMyMTg4LCAzMjE5OCwgMzIyMDgsIDMyMjE4LCAzMjIyOCwgMzIyMzgsCiszMjI0OCwgMzIyNTgsIDMyMjY4LCAzMjI3OCwgMzIyODgsIDMyMjk4LCAzMjMwOCwgMzIzMTgsIDMyMzI4LCAzMjMzOCwgMzIzNDgsIDMyMzU4LCAzMjM2OCwgMzIzNzgsIDMyMzg4LCAzMjM5OCwKKzMyNDA4LCAzMjQxOCwgMzI0MjgsIDMyNDM4LCAzMjQ0OCwgMzI0NTgsIDMyNDY4LCAzMjQ3OCwgMzI0ODgsIDMyNDk4LCAzMjUwOCwgMzI1MTgsIDMyNTI4LCAzMjUzOCwgMzI1NDgsIDMyNTU4LAorMzI1NjgsIDMyNTc4LCAzMjU4OCwgMzI1OTgsIDMyNjA4LCAzMjYxOCwgMzI2MjgsIDMyNjM4LCAzMjY0OCwgMzI2NTgsIDMyNjY4LCAzMjY3OCwgMzI2ODgsIDMyNjk4LCAzMjcwOCwgMzI3MTgsCiszMjcyOCwgMzI3MzgsIDMyNzQ4LCAzMjc1OCwgMzI3NjgsIDMyNzc4LCAzMjc4OCwgMzI3OTgsIDMyODA4LCAzMjgxOCwgMzI4MjgsIDMyODM4LCAzMjg0OCwgMzI4NTgsIDMyODY4LCAzMjg3OCwKKzMyODg4LCAzMjg5OCwgMzI5MDgsIDMyOTE4LCAzMjkyOCwgMzI5MzgsIDMyOTQ4LCAzMjk1OCwgMzI5NjgsIDMyOTc4LCAzMjk4OCwgMzI5OTgsIDMzMDA4LCAzMzAxOCwgMzMwMjgsIDMzMDM4LAorMzMwNDgsIDMzMDU4LCAzMzA2OCwgMzMwNzgsIDMzMDg4LCAzMzA5OCwgMzMxMDgsIDMzMTE4LCAzMzEyOCwgMzMxMzgsIDMzMTQ4LCAzMzE1OCwgMzMxNjgsIDMzMTc4LCAzMzE4OCwgMzMxOTgsCiszMzIwOCwgMzMyMTgsIDMzMjI4LCAzMzIzOCwgMzMyNDgsIDMzMjU4LCAzMzI2OCwgMzMyNzgsIDMzMjg4LCAzMzI5OCwgMzMzMDgsIDMzMzE4LCAzMzMyOCwgMzMzMzgsIDMzMzQ4LCAzMzM1OCwKKzMzMzY4LCAzMzM3OCwgMzMzODgsIDMzMzk4LCAzMzQwOCwgMzM0MTgsIDMzNDI4LCAzMzQzOCwgMzM0NDgsIDMzNDU4LCAzMzQ2OCwgMzM0NzgsIDMzNDg4LCAzMzQ5OCwgMzM1MDgsIDMzNTE4LAorMzM1MjgsIDMzNTM4LCAzMzU0OCwgMzM1NTgsIDMzNTY4LCAzMzU3OCwgMzM1ODgsIDMzNTk4LCAzMzYwOCwgMzM2MTgsIDMzNjI4LCAzMzYzOCwgMzM2NDgsIDMzNjU4LCAzMzY2OCwgMzM2NzgsCiszMzY4OCwgMzM2OTgsIDMzNzA4LCAzMzcxOCwgMzM3MjgsIDMzNzM4LCAzMzc0OCwgMzM3NTgsIDMzNzY4LCAzMzc3OCwgMzM3ODgsIDMzNzk4LCAzMzgwOCwgMzM4MTgsIDMzODI4LCAzMzgzOCwKKzMzODQ4LCAzMzg1OCwgMzM4NjgsIDMzODc4LCAzMzg4OCwgMzM4OTgsIDMzOTA4LCAzMzkxOCwgMzM5MjgsIDMzOTM4LCAzMzk0OCwgMzM5NTgsIDMzOTY4LCAzMzk3OCwgMzM5ODgsIDMzOTk4LAorMzQwMDgsIDM0MDE4LCAzNDAyOCwgMzQwMzgsIDM0MDQ4LCAzNDA1OCwgMzQwNjgsIDM0MDc4LCAzNDA4OCwgMzQwOTgsIDM0MTA4LCAzNDExOCwgMzQxMjgsIDM0MTM4LCAzNDE0OCwgMzQxNTgsCiszNDE2OCwgMzQxNzgsIDM0MTg4LCAzNDE5OCwgMzQyMDgsIDM0MjE4LCAzNDIyOCwgMzQyMzgsIDM0MjQ4LCAzNDI1OCwgMzQyNjgsIDM0Mjc4LCAzNDI4OCwgMzQyOTgsIDM0MzA4LCAzNDMxOCwKKzM0MzI4LCAzNDMzOCwgMzQzNDgsIDM0MzU4LCAzNDM2OCwgMzQzNzgsIDM0Mzg4LCAzNDM5OCwgMzQ0MDgsIDM0NDE4LCAzNDQyOCwgMzQ0MzgsIDM0NDQ4LCAzNDQ1OCwgMzQ0NjgsIDM0NDc4LAorMzQ0ODgsIDM0NDk4LCAzNDUwOCwgMzQ1MTgsIDM0NTI4LCAzNDUzOCwgMzQ1NDgsIDM0NTU4LCAzNDU2OCwgMzQ1NzgsIDM0NTg4LCAzNDU5OCwgMzQ2MDgsIDM0NjE4LCAzNDYyOCwgMzQ2MzgsCiszNDY0OCwgMzQ2NTgsIDM0NjY4LCAzNDY3OCwgMzQ2ODgsIDM0Njk4LCAzNDcwOCwgMzQ3MTgsIDM0NzI4LCAzNDczOCwgMzQ3NDgsIDM0NzU4LCAzNDc2OCwgMzQ3NzgsIDM0Nzg4LCAzNDc5OCwKKzM0ODA4LCAzNDgxOCwgMzQ4MjgsIDM0ODM4LCAzNDg0OCwgMzQ4NTgsIDM0ODY4LCAzNDg3OCwgMzQ4ODgsIDM0ODk4LCAzNDkwOCwgMzQ5MTgsIDM0OTI4LCAzNDkzOCwgMzQ5NDgsIDM0OTU4LAorMzQ5NjgsIDM0OTc4LCAzNDk4OCwgMzQ5OTgsIDM1MDA4LCAzNTAxOCwgMzUwMjgsIDM1MDM4LCAzNTA0OCwgMzUwNTgsIDM1MDY4LCAzNTA3OCwgMzUwODgsIDM1MDk4LCAzNTEwOCwgMzUxMTgsCiszNTEyOCwgMzUxMzgsIDM1MTQ4LCAzNTE1OCwgMzUxNjgsIDM1MTc4LCAzNTE4OCwgMzUxOTgsIDM1MjA4LCAzNTIxOCwgMzUyMjgsIDM1MjM4LCAzNTI0OCwgMzUyNTgsIDM1MjY4LCAzNTI3OCwKKzM1Mjg4LCAzNTI5OCwgMzUzMDgsIDM1MzE4LCAzNTMyOCwgMzUzMzgsIDM1MzQ4LCAzNTM1OCwgMzUzNjgsIDM1Mzc4LCAzNTM4OCwgMzUzOTgsIDM1NDA4LCAzNTQxOCwgMzU0MjgsIDM1NDM4LAorMzU0NDgsIDM1NDU4LCAzNTQ2OCwgMzU0NzgsIDM1NDg4LCAzNTQ5OCwgMzU1MDgsIDM1NTE4LCAzNTUyOCwgMzU1MzgsIDM1NTQ4LCAzNTU1OCwgMzU1NjgsIDM1NTc4LCAzNTU4OCwgMzU1OTgsCiszNTYwOCwgMzU2MTgsIDM1NjI4LCAzNTYzOCwgMzU2NDgsIDM1NjU4LCAzNTY2OCwgMzU2NzgsIDM1Njg4LCAzNTY5OCwgMzU3MDgsIDM1NzE4LCAzNTcyOCwgMzU3MzgsIDM1NzQ4LCAzNTc1OCwKKzM1NzY4LCAzNTc3OCwgMzU3ODgsIDM1Nzk4LCAzNTgwOCwgMzU4MTgsIDM1ODI4LCAzNTgzOCwgMzU4NDgsIDM1ODU4LCAzNTg2OCwgMzU4NzgsIDM1ODg4LCAzNTg5OCwgMzU5MDgsIDM1OTE4LAorMzU5MjgsIDM1OTM4LCAzNTk0OCwgMzU5NTgsIDM1OTY4LCAzNTk3OCwgMzU5ODgsIDM1OTk4LCAzNjAwOCwgMzYwMTgsIDM2MDI4LCAzNjAzOCwgMzYwNDgsIDM2MDU4LCAzNjA2OCwgMzYwNzgsCiszNjA4OCwgMzYwOTgsIDM2MTA4LCAzNjExOCwgMzYxMjgsIDM2MTM4LCAzNjE0OCwgMzYxNTgsIDM2MTY4LCAzNjE3OCwgMzYxODgsIDM2MTk4LCAzNjIwOCwgMzYyMTgsIDM2MjI4LCAzNjIzOCwKKzM2MjQ4LCAzNjI1OCwgMzYyNjgsIDM2Mjc4LCAzNjI4OCwgMzYyOTgsIDM2MzA4LCAzNjMxOCwgMzYzMjgsIDM2MzM4LCAzNjM0OCwgMzYzNTgsIDM2MzY4LCAzNjM3OCwgMzYzODgsIDM2Mzk4LAorMzY0MDgsIDM2NDE4LCAzNjQyOCwgMzY0MzgsIDM2NDQ4LCAzNjQ1OCwgMzY0NjgsIDM2NDc4LCAzNjQ4OCwgMzY0OTgsIDM2NTA4LCAzNjUxOCwgMzY1MjgsIDM2NTM4LCAzNjU0OCwgMzY1NTgsCiszNjU2OCwgMzY1NzgsIDM2NTg4LCAzNjU5OCwgMzY2MDgsIDM2NjE4LCAzNjYyOCwgMzY2MzgsIDM2NjQ4LCAzNjY1OCwgMzY2NjgsIDM2Njc4LCAzNjY4OCwgMzY2OTgsIDM2NzA4LCAzNjcxOCwKKzM2NzI4LCAzNjczOCwgMzY3NDgsIDM2NzU4LCAzNjc2OCwgMzY3NzgsIDM2Nzg4LCAzNjc5OCwgMzY4MDgsIDM2ODE4LCAzNjgyOCwgMzY4MzgsIDM2ODQ4LCAzNjg1OCwgMzY4NjgsIDM2ODc4LAorMzY4ODgsIDM2ODk4LCAzNjkwOCwgMzY5MTgsIDM2OTI4LCAzNjkzOCwgMzY5NDgsIDM2OTU4LCAzNjk2OCwgMzY5NzgsIDM2OTg4LCAzNjk5OCwgMzcwMDgsIDM3MDE4LCAzNzAyOCwgMzcwMzgsCiszNzA0OCwgMzcwNTgsIDM3MDY4LCAzNzA3OCwgMzcwODgsIDM3MDk4LCAzNzEwOCwgMzcxMTgsIDM3MTI4LCAzNzEzOCwgMzcxNDgsIDM3MTU4LCAzNzE2OCwgMzcxNzgsIDM3MTg4LCAzNzE5OCwKKzM3MjA4LCAzNzIxOCwgMzcyMjgsIDM3MjM4LCAzNzI0OCwgMzcyNTgsIDM3MjY4LCAzNzI3OCwgMzcyODgsIDM3Mjk4LCAzNzMwOCwgMzczMTgsIDM3MzI4LCAzNzMzOCwgMzczNDgsIDM3MzU4LAorMzczNjgsIDM3Mzc4LCAzNzM4OCwgMzczOTgsIDM3NDA4LCAzNzQxOCwgMzc0MjgsIDM3NDM4LCAzNzQ0OCwgMzc0NTgsIDM3NDY4LCAzNzQ3OCwgMzc0ODgsIDM3NDk4LCAzNzUwOCwgMzc1MTgsCiszNzUyOCwgMzc1MzgsIDM3NTQ4LCAzNzU1OCwgMzc1NjgsIDM3NTc4LCAzNzU4OCwgMzc1OTgsIDM3NjA4LCAzNzYxOCwgMzc2MjgsIDM3NjM4LCAzNzY0OCwgMzc2NTgsIDM3NjY4LCAzNzY3OCwKKzM3Njg4LCAzNzY5OCwgMzc3MDgsIDM3NzE4LCAzNzcyOCwgMzc3MzgsIDM3NzQ4LCAzNzc1OCwgMzc3NjgsIDM3Nzc4LCAzNzc4OCwgMzc3OTgsIDM3ODA4LCAzNzgxOCwgMzc4MjgsIDM3ODM4LAorMzc4NDgsIDM3ODU4LCAzNzg2OCwgMzc4NzgsIDM3ODg4LCAzNzg5OCwgMzc5MDgsIDM3OTE4LCAzNzkyOCwgMzc5MzgsIDM3OTQ4LCAzNzk1OCwgMzc5NjgsIDM3OTc4LCAzNzk4OCwgMzc5OTgsCiszODAwOCwgMzgwMTgsIDM4MDI4LCAzODAzOCwgMzgwNDgsIDM4MDU4LCAzODA2OCwgMzgwNzgsIDM4MDg4LCAzODA5OCwgMzgxMDgsIDM4MTE4LCAzODEyOCwgMzgxMzgsIDM4MTQ4LCAzODE1OCwKKzM4MTY4LCAzODE3OCwgMzgxODgsIDM4MTk4LCAzODIwOCwgMzgyMTgsIDM4MjI4LCAzODIzOCwgMzgyNDgsIDM4MjU4LCAzODI2OCwgMzgyNzgsIDM4Mjg4LCAzODI5OCwgMzgzMDgsIDM4MzE4LAorMzgzMjgsIDM4MzM4LCAzODM0OCwgMzgzNTgsIDM4MzY4LCAzODM3OCwgMzgzODgsIDM4Mzk4LCAzODQwOCwgMzg0MTgsIDM4NDI4LCAzODQzOCwgMzg0NDgsIDM4NDU4LCAzODQ2OCwgMzg0NzgsCiszODQ4OCwgMzg0OTgsIDM4NTA4LCAzODUxOCwgMzg1MjgsIDM4NTM4LCAzODU0OCwgMzg1NTgsIDM4NTY4LCAzODU3OCwgMzg1ODgsIDM4NTk4LCAzODYwOCwgMzg2MTgsIDM4NjI4LCAzODYzOCwKKzM4NjQ4LCAzODY1OCwgMzg2NjgsIDM4Njc4LCAzODY4OCwgMzg2OTgsIDM4NzA4LCAzODcxOCwgMzg3MjgsIDM4NzM4LCAzODc0OCwgMzg3NTgsIDM4NzY4LCAzODc3OCwgMzg3ODgsIDM4Nzk4LAorMzg4MDgsIDM4ODE4LCAzODgyOCwgMzg4MzgsIDM4ODQ4LCAzODg1OCwgMzg4NjgsIDM4ODc4LCAzODg4OCwgMzg4OTgsIDM4OTA4LCAzODkxOCwgMzg5MjgsIDM4OTM4LCAzODk0OCwgMzg5NTgsCiszODk2OCwgMzg5NzgsIDM4OTg4LCAzODk5OCwgMzkwMDgsIDM5MDE4LCAzOTAyOCwgMzkwMzgsIDM5MDQ4LCAzOTA1OCwgMzkwNjgsIDM5MDc4LCAzOTA4OCwgMzkwOTgsIDM5MTA4LCAzOTExOCwKKzM5MTI4LCAzOTEzOCwgMzkxNDgsIDM5MTU4LCAzOTE2OCwgMzkxNzgsIDM5MTg4LCAzOTE5OCwgMzkyMDgsIDM5MjE4LCAzOTIyOCwgMzkyMzgsIDM5MjQ4LCAzOTI1OCwgMzkyNjgsIDM5Mjc4LAorMzkyODgsIDM5Mjk4LCAzOTMwOCwgMzkzMTgsIDM5MzI4LCAzOTMzOCwgMzkzNDgsIDM5MzU4LCAzOTM2OCwgMzkzNzgsIDM5Mzg4LCAzOTM5OCwgMzk0MDgsIDM5NDE4LCAzOTQyOCwgMzk0MzgsCiszOTQ0OCwgMzk0NTgsIDM5NDY4LCAzOTQ3OCwgMzk0ODgsIDM5NDk4LCAzOTUwOCwgMzk1MTgsIDM5NTI4LCAzOTUzOCwgMzk1NDgsIDM5NTU4LCAzOTU2OCwgMzk1NzgsIDM5NTg4LCAzOTU5OCwKKzM5NjA4LCAzOTYxOCwgMzk2MjgsIDM5NjM4LCAzOTY0OCwgMzk2NTgsIDM5NjY4LCAzOTY3OCwgMzk2ODgsIDM5Njk4LCAzOTcwOCwgMzk3MTgsIDM5NzI4LCAzOTczOCwgMzk3NDgsIDM5NzU4LAorMzk3NjgsIDM5Nzc4LCAzOTc4OCwgMzk3OTgsIDM5ODA4LCAzOTgxOCwgMzk4MjgsIDM5ODM4LCAzOTg0OCwgMzk4NTgsIDM5ODY4LCAzOTg3OCwgMzk4ODgsIDM5ODk4LCAzOTkwOCwgMzk5MTgsCiszOTkyOCwgMzk5MzgsIDM5OTQ4LCAzOTk1OCwgMzk5NjgsIDM5OTc4LCAzOTk4OCwgMzk5OTgsIDQwMDA4LCA0MDAxOCwgNDAwMjgsIDQwMDM4LCA0MDA0OCwgNDAwNTgsIDQwMDY4LCA0MDA3OCwKKzQwMDg4LCA0MDA5OCwgNDAxMDgsIDQwMTE4LCA0MDEyOCwgNDAxMzgsIDQwMTQ4LCA0MDE1OCwgNDAxNjgsIDQwMTc4LCA0MDE4OCwgNDAxOTgsIDQwMjA4LCA0MDIxOCwgNDAyMjgsIDQwMjM4LAorNDAyNDgsIDQwMjU4LCA0MDI2OCwgNDAyNzgsIDQwMjg4LCA0MDI5OCwgNDAzMDgsIDQwMzE4LCA0MDMyOCwgNDAzMzgsIDQwMzQ4LCA0MDM1OCwgNDAzNjgsIDQwMzc4LCA0MDM4OCwgNDAzOTgsCis0MDQwOCwgNDA0MTgsIDQwNDI4LCA0MDQzOCwgNDA0NDgsIDQwNDU4LCA0MDQ2OCwgNDA0NzgsIDQwNDg4LCA0MDQ5OCwgNDA1MDgsIDQwNTE4LCA0MDUyOCwgNDA1MzgsIDQwNTQ4LCA0MDU1OCwKKzQwNTY4LCA0MDU3OCwgNDA1ODgsIDQwNTk4LCA0MDYwOCwgNDA2MTgsIDQwNjI4LCA0MDYzOCwgNDA2NDgsIDQwNjU4LCA0MDY2OCwgNDA2NzgsIDQwNjg4LCA0MDY5OCwgNDA3MDgsIDQwNzE4LAorNDA3MjgsIDQwNzM4LCA0MDc0OCwgNDA3NTgsIDQwNzY4LCA0MDc3OCwgNDA3ODgsIDQwNzk4LCA0MDgwOCwgNDA4MTgsIDQwODI4LCA0MDgzOCwgNDA4NDgsIDQwODU4LCA0MDg2OCwgNTczNDQsCis1NzM1NCwgNTczNjQsIDU3Mzc0LCA1NzM4NCwgNTczOTQsIDU3NDA0LCA1NzQxNCwgNTc0MjQsIDU3NDM0LCA1NzQ0NCwgNTc0NTQsIDU3NDY0LCA1NzQ3NCwgNTc0ODQsIDU3NDk0LCA1NzUwNCwKKzU3NTE0LCA1NzUyNCwgNTc1MzQsIDU3NTQ0LCA1NzU1NCwgNTc1NjQsIDU3NTc0LCA1NzU4NCwgNTc1OTQsIDU3NjA0LCA1NzYxNCwgNTc2MjQsIDU3NjM0LCA1NzY0NCwgNTc2NTQsIDU3NjY0LAorNTc2NzQsIDU3Njg0LCA1NzY5NCwgNTc3MDQsIDU3NzE0LCA1NzcyNCwgNTc3MzQsIDU3NzQ0LCA1Nzc1NCwgNTc3NjQsIDU3Nzc0LCA1Nzc4NCwgNTc3OTQsIDU3ODA0LCA1NzgxNCwgNTc4MjQsCis1NzgzNCwgNTc4NDQsIDU3ODU0LCA1Nzg2NCwgNTc4NzQsIDU3ODg0LCA1Nzg5NCwgNTc5MDQsIDU3OTE0LCA1NzkyNCwgNTc5MzQsIDU3OTQ0LCA1Nzk1NCwgNTc5NjQsIDU3OTc0LCA1Nzk4NCwKKzU3OTk0LCA1ODAwNCwgNTgwMTQsIDU4MDI0LCA1ODAzNCwgNTgwNDQsIDU4MDU0LCA1ODA2NCwgNTgwNzQsIDU4MDg0LCA1ODA5NCwgNTgxMDQsIDU4MTE0LCA1ODEyNCwgNTgxMzQsIDU4MTQ0LAorNTgxNTQsIDU4MTY0LCA1ODE3NCwgNTgxODQsIDU4MTk0LCA1ODIwNCwgNTgyMTQsIDU4MjI0LCA1ODIzNCwgNTgyNDQsIDU4MjU0LCA1ODI2NCwgNTgyNzQsIDU4Mjg0LCA1ODI5NCwgNTgzMDQsCis1ODMxNCwgNTgzMjQsIDU4MzM0LCA1ODM0NCwgNTgzNTQsIDU4MzY0LCA1ODM3NCwgNTgzODQsIDU4Mzk0LCA1ODQwNCwgNTg0MTQsIDU4NDI0LCA1ODQzNCwgNTg0NDQsIDU4NDU0LCA1ODQ2NCwKKzU4NDc0LCA1ODQ4NCwgNTg0OTQsIDU4NTA0LCA1ODUxNCwgNTg1MjQsIDU4NTM0LCA1ODU0NCwgNTg1NTQsIDU4NTY0LCA1ODU3NCwgNTg1ODQsIDU4NTk0LCA1ODYwNCwgNTg2MTQsIDU4NjI0LAorNTg2MzQsIDU4NjQ0LCA1ODY1NCwgNTg2NjQsIDU4Njc0LCA1ODY4NCwgNTg2OTQsIDU4NzA0LCA1ODcxNCwgNTg3MjQsIDU4NzM0LCA1ODc0NCwgNTg3NTQsIDU4NzY0LCA1ODc3NCwgNTg3ODQsCis1ODc5NCwgNTg4MDQsIDU4ODE0LCA1ODgyNCwgNTg4MzQsIDU4ODQ0LCA1ODg1NCwgNTg4NjQsIDU4ODc0LCA1ODg4NCwgNTg4OTQsIDU4OTA0LCA1ODkxNCwgNTg5MjQsIDU4OTM0LCA1ODk0NCwKKzU4OTU0LCA1ODk2NCwgNTg5NzQsIDU4OTg0LCA1ODk5NCwgNTkwMDQsIDU5MDE0LCA1OTAyNCwgNTkwMzQsIDU5MDQ0LCA1OTA1NCwgNTkwNjQsIDU5MDc0LCA1OTA4NCwgNTkwOTQsIDU5MTA0LAorNTkxMTQsIDU5MTI0LCA1OTEzNCwgNTkxNDQsIDU5MTU0LCA1OTE2NCwgNTkxNzQsIDU5MTg0LCA1OTE5NCwgNTkyMDQsIDU5MjE0LCA1OTIyNCwgNTkyMzQsIDU5MjQ0LCA1OTI1NCwgNTkyNjQsCis1OTI3NCwgNTkyODQsIDU5Mjk0LCA1OTMwNCwgNTkzMTQsIDU5MzI0LCA1OTMzNCwgNTkzNDQsIDU5MzU0LCA1OTM2NCwgNTkzNzQsIDU5Mzg0LCA1OTM5NCwgNTk0MDQsIDU5NDE0LCA1OTQyNCwKKzU5NDM0LCA1OTQ0NCwgNTk0NTQsIDU5NDY0LCA1OTQ3NCwgNTk0ODQsIDYzNzg4LCA2Mzg2NSwgNjM4OTMsIDYzOTc1LCA2Mzk4NSwgNjQwMTIsIDY0MDI0LCA2NDAzNSwgNjUwNzIsIDY1MDgyLAorNjUwOTIsIDY1MTAyLCA2NTExMywgNjUxMjMsIDY1MjgxLCA2NTI5MSwgNjUzMDEsIDY1MzExLCA2NTMyMSwgNjUzMzEsIDY1MzQxLCA2NTM1MSwgNjUzNjEsIDY1MzcxLCA2NTUwNCwgNjU1MzYKKyAgICAgICAgICAgIH0pOworCisgICAgICAgIHRlc3RCeXRlcyA9IHRoZXNlQnl0ZXMobmV3IGludFtdeworMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKzE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCis0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKzY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCis5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKzExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKzE2MSwgMjMyLCAxNjEsIDIzNiwgMTYxLCAxNjcsIDE2MSwgMjI3LCAxNjEsIDE5MiwgMTYxLCAxNjQsIDE2MSwgMTkzLCAxNjgsIDE2NCwKKzE2OCwgMTYyLCAxNjgsIDE2OCwgMTY4LCAxNjYsIDE2OCwgMTg2LCAxNjgsIDE3MiwgMTY4LCAxNzAsIDE2OCwgMTc2LCAxNjgsIDE3NCwKKzE2MSwgMTk0LCAxNjgsIDE4MCwgMTY4LCAxNzgsIDE2OCwgMTg1LCAxNjgsIDE2MSwgMTY4LCAxNjUsIDE2OCwgMTY5LCAxNjgsIDE4OSwKKzE2OCwgMTc3LCAxNjgsIDE2MywgMTY4LCAxODIsIDE2OCwgMTg3LCAxNjgsIDE5MiwgMTYxLCAxNjYsIDE2OCwgNjYsIDE2NiwgMTYxLAorMTY2LCAxNzEsIDE2NiwgMTgwLCAxNjYsIDE5MywgMTY2LCAyMDMsIDE2NiwgMjEyLCAxNjcsIDE2NywgMTY3LCAxNjEsIDE2NywgMTcyLAorMTY3LCAxODIsIDE2NywgMTkyLCAxNjcsIDIxOCwgMTY3LCAyMjgsIDE2NywgMjM4LCAxNjksIDkyLCAxNjEsIDE3NiwgMTYxLCAxNzMsCisxNjEsIDIzNSwgMTYxLCAyNDksIDE2MSwgMjMwLCAxNjEsIDIzNywgMTY5LCA4OSwgMTYyLCAyNDEsIDE2MiwgMjUxLCAxNjIsIDE2NSwKKzE2MSwgMjUxLCAxNjEsIDIwMiwgMTY4LCA3NywgMTY4LCA3OCwgMTYxLCAyMDEsIDE2MSwgMjI0LCAxNjEsIDIxNCwgMTY4LCA4MCwKKzE2MSwgMjE3LCAxNjEsIDIxOCwgMTYxLCAyMDksIDE2MSwgMjA1LCAxNjgsIDgzLCAxNjEsIDIwOCwgMTYyLCAyMTcsIDE2MiwgMTk3LAorMTYyLCAyMDcsIDE2MiwgMTc3LCAxNjIsIDE4NywgMTY5LCAxNjQsIDE2OSwgMTc0LCAxNjksIDE4NCwgMTY5LCAxOTQsIDE2OSwgMjA0LAorMTY5LCAyMTQsIDE2OSwgMjI0LCAxNjksIDIzNCwgMTY4LCA4NCwgMTY4LCA5NCwgMTY4LCAxMDQsIDE2OCwgMTE0LCAxNjgsIDEyMCwKKzE2OCwgMTMxLCAxNjgsIDEzOCwgMTYxLCAyNDYsIDE2MSwgMjQ4LCAxNjgsIDEzOSwgMTYxLCAyNDQsIDE2OCwgMTQxLCAxNjEsIDIzOSwKKzE2MSwgMjI2LCAxNjEsIDE2MSwgMTYxLCAxODIsIDE2MSwgMTc4LCAxNjgsIDE0OSwgMTY5LCA3MSwgMTY0LCAxNjEsIDE2NCwgMTcxLAorMTY0LCAxODEsIDE2NCwgMTkxLCAxNjQsIDIwMSwgMTY0LCAyMTEsIDE2NCwgMjIxLCAxNjQsIDIzMSwgMTY0LCAyNDEsIDE2OSwgOTcsCisxNjUsIDE2NSwgMTY1LCAxNzUsIDE2NSwgMTg1LCAxNjUsIDE5NSwgMTY1LCAyMDUsIDE2NSwgMjE1LCAxNjUsIDIyNSwgMTY1LCAyMzUsCisxNjUsIDI0NSwgMTY4LCAxOTcsIDE2OCwgMjA3LCAxNjgsIDIxNywgMTY4LCAyMjcsIDE2MiwgMjI5LCAxNjksIDkwLCAxNjksIDczLAorMTY5LCA3NCwgMTY5LCA3NiwgMTY5LCA4MCwgMTY5LCA4MSwgMjEwLCAxODcsIDIwMSwgMjA3LCAxOTksIDIxMCwgMjE2LCAxNjksCisyMTYsIDE3MywgMTgwLCAxNzQsIDEyOSwgODMsIDEyOSwgODgsIDE5MiwgMjE0LCAxMjksIDkzLCAxMjksIDk3LCAxMjksIDEwNSwKKzEyOSwgMTEyLCAxMjksIDEyMSwgMTgyLCAyNTQsIDEyOSwgMTI5LCAyMTcsIDIzOSwgMTI5LCAxMzYsIDEyOSwgMTQwLCAxMjksIDE0NywKKzEyOSwgMTQ4LCAxMjksIDE1MiwgMTI5LCAxNTUsIDEyOSwgMTU4LCAyMDksIDI0NiwgMTI5LCAxNjgsIDEyOSwgMTc0LCAxODgsIDE5MSwKKzIxMSwgMTk3LCAyMTYsIDI0MywgMTI5LCAxOTIsIDE5MywgMjMwLCAxMjksIDIwMywgMTI5LCAyMTEsIDEyOSwgMjE1LCAyMTYsIDI1MCwKKzEyOSwgMjIwLCAxMjksIDIyNiwgMjE3LCAxNzQsIDEyOSwgMjM3LCAxMjksIDI0MiwgMTI5LCAyNDksIDEzMCwgNjQsIDIwNiwgMjM0LAorMTMwLCA3NCwgMTMwLCA4MywgMTMwLCA4OSwgMTMwLCA5NSwgMTMwLCA5OCwgMjE3LCAxNzksIDEzMCwgMTA3LCAyMTcsIDE5NCwKKzEzMCwgMTI0LCAxODEsIDE4NSwgMjE3LCAxOTUsIDE5MCwgMjM1LCAxMzAsIDE0NiwgMjEzLCAxNzQsIDEzMCwgMTYyLCAyMTcsIDIwMywKKzEzMCwgMTc2LCAxMzAsIDE4NCwgMjE3LCAyMDQsIDE5NywgMTg4LCAxOTEsIDI1NCwgMTMwLCAyMTQsIDEzMCwgMjIzLCAxMzAsIDIzMywKKzE4MCwgMTYyLCAxNzYsIDE5MywgMTMwLCAyNTQsIDEzMSwgNzMsIDEzMSwgODIsIDE5MywgMTk3LCAxMzEsIDEwMCwgMjE3LCAyMTUsCisxMzEsIDExMywgMTMxLCAxMjIsIDEzMSwgMTMwLCAxMzEsIDEzOSwgMTMxLCAxNDksIDEzMSwgMTU4LCAxMzEsIDE2OCwgMTMxLCAxNzgsCisyMDcsIDIwMCwgMTMxLCAxODYsIDE4MiwgMTgxLCAxMzEsIDE5OSwgMTkyLCAxODgsIDEzMSwgMjA1LCAxMzEsIDIwOSwgMTMxLCAyMTQsCisxMzEsIDIyMCwgMjE4LCAxNjMsIDE4MiwgMTcyLCAyMTAsIDE3NywgMTkwLCAxODcsIDEzMSwgMjQ1LCAxMzEsIDI1MSwgMTMyLCA2OCwKKzEzMiwgNzUsIDEzMiwgODEsIDIxOSwgMjAyLCAxODMsIDIxNCwgMTMyLCA5MSwgMTg0LCAyMTMsIDE5NywgMjA4LCAxODUsIDIwNiwKKzIwMCwgMTc1LCAxODgsIDE5MywgMjE2LCAyMjEsIDE5OCwgMjAyLCAxMzIsIDEzMywgMTg4LCAyNDQsIDEzMiwgMTQ2LCAxMzIsIDE1NSwKKzE5NywgMjUyLCAxMzIsIDE3MCwgMTMyLCAxNzgsIDEzMiwgMTgxLCAxMzIsIDE4NSwgMTMyLCAxOTIsIDEzMiwgMTk5LCAxMzIsIDIwNiwKKzE5MSwgMTc3LCAxMzIsIDIyMSwgMTMyLCAyMzAsIDEzMiwgMjM5LCAyMTIsIDIwMCwgMTMyLCAyNTEsIDEzMywgNjcsIDEzMywgNzEsCisxMzMsIDc3LCAxMzMsIDg1LCAxMzMsIDkyLCAxMzMsIDk3LCAxMzMsIDEwMSwgMTc4LCAxNjksIDE5NCwgMTc3LCAyMTYsIDE4MCwKKzIwOCwgMTgyLCAxNzksIDE2NywgMjA5LCAyMjUsIDEzMywgMTMzLCAxMzMsIDEzOSwgMTMzLCAxNDMsIDEzMywgMTUyLCAxMzMsIDE2MCwKKzIxMSwgMjE0LCAxMzMsIDE3MCwgMTMzLCAxNzQsIDE5MywgMjM3LCAyMDQsIDE2OCwgMTMzLCAxODEsIDE4NCwgMjQ3LCAxODYsIDI0MywKKzEzMywgMTkwLCAxMzMsIDE5NCwgMjA0LCAyNTMsIDEzMywgMjAwLCAyMDksIDE4OSwgMTg0LCAyMzAsIDIyMywgMTkwLCAxMzMsIDIxOCwKKzIxNCwgMjIwLCAyMjMsIDIxOCwgMTg2LCAyNDQsIDE5NywgMjE2LCAxODQsIDE5MiwgMjIzLCAyMDMsIDIyMywgMjI5LCAxMzQsIDY2LAorMjA3LCAyMDQsIDIyMywgMjExLCAyMjMsIDIyMywgMTM0LCA4MCwgMTM0LCA4MywgMTk2LCAxOTYsIDEzNCwgOTMsIDEzNCwgMTAwLAorMTM0LCAxMDYsIDEzNCwgMTEyLCAxMzQsIDEyMCwgMTM0LCAxMjYsIDIyNCwgMTY3LCAxMzQsIDEzOCwgMjE1LCAxOTYsIDEzNCwgMTQ5LAorMTM0LCAxNTYsIDEzNCwgMTY0LCAyMTYsIDE5NiwgMjI0LCAxNjQsIDE5MSwgMTY2LCAxODYsIDE3NiwgMjI0LCAxODQsIDEzNCwgMTkyLAorMTM0LCAyMDAsIDEzNCwgMjA5LCAxMzQsIDIxNCwgMTM0LCAyMjAsIDEzNCwgMjI3LCAxMzQsIDIzMiwgMjI0LCAyMDUsIDEzNCwgMjQwLAorMTM0LCAyNDUsIDEzNCwgMjUxLCAyMjQsIDIwOSwgMTM1LCA3NSwgMTM1LCA4MSwgMTM1LCA4OCwgMjE1LCAyMzYsIDEzNSwgMTAwLAorMTM1LCAxMDksIDEzNSwgMTE2LCAyMjQsIDIyNCwgMTM1LCAxMzAsIDEzNSwgMTM1LCAxMzUsIDE0MywgMTM1LCAxNTEsIDE4NiwgMTkxLAorMTM1LCAxNjYsIDEzNSwgMTc2LCAxMzUsIDE4NSwgMTM1LCAxOTQsIDEzNSwgMjAyLCAxOTYsIDIxMCwgMjI0LCAyMzYsIDE4NywgMjE2LAorMTM1LCAyMzAsIDEzNSwgMjM2LCAxMzUsIDI0MiwgMjEyLCAxNzgsIDEzNSwgMjUzLCAxMzYsIDcyLCAxMzYsIDc5LCAyMTksIDIyMCwKKzEzNiwgOTAsIDIxOSwgMjI0LCAyMTksIDIwOCwgMTM2LCAxMDYsIDIxNSwgMTg1LCAxOTgsIDE4NiwgMTM2LCAxMTgsIDEzNiwgMTI0LAorMTM2LCAxMzAsIDE5MiwgMjIxLCAxMzYsIDE0NSwgMTkxLCAyMDksIDEzNiwgMTU0LCAxMzYsIDE2MSwgMTM2LCAxNjksIDE3OSwgMTk5LAorMjE5LCAyNDUsIDEzNiwgMTg3LCAxMzYsIDE5NiwgMTM2LCAyMDMsIDIyMCwgMTY1LCAxMzYsIDIxNSwgMTM2LCAyMjIsIDIyMCwgMTY2LAorMTM2LCAyMzYsIDEzNiwgMjQ0LCAxMzYsIDI1MywgMTM3LCA3MSwgMTM3LCA3OSwgMTM3LCA4NiwgMTM3LCA5NSwgMTM3LCAxMDIsCisxMzcsIDExMiwgMTM3LCAxMTksIDEzNywgMTI2LCAxMzcsIDEzNSwgMTM3LCAxNDEsIDEzNywgMTQ5LCAxMzcsIDE1OSwgMTM3LCAxNjgsCisxMzcsIDE3NiwgMTM3LCAxODUsIDEzNywgMTk0LCAxMzcsIDIwMywgMjAxLCAyNDksIDEzNywgMjE2LCAxODAsIDE2NiwgMTM3LCAyMzIsCisxMzcsIDIzOCwgMTM3LCAyNDQsIDEzNywgMjQ4LCAxMzcsIDI1MywgMTM4LCA2NywgMTM4LCA3MSwgMTc3LCAxODgsIDEzOCwgODEsCisxMzgsIDg4LCAxMzgsIDk4LCAxMzgsIDEwMywgMjE1LCAxNzcsIDEzOCwgMTEzLCAxMzgsIDExOCwgMjMwLCAxNjUsIDE5NiwgMjIxLAorMTM4LCAxMzgsIDEzOCwgMTQ1LCAxMzgsIDE1MiwgMTM4LCAxNTcsIDEzOCwgMTYyLCAxMzgsIDE2OSwgMTM4LCAxNzgsIDEzOCwgMTg2LAorMjMwLCAxNzQsIDEzOCwgMTk1LCAxOTYsIDIwMCwgMTM4LCAyMDgsIDEzOCwgMjE3LCAxMzgsIDIyMywgMTM4LCAyMzEsIDEzOCwgMjM4LAorMTM4LCAyNDcsIDIzMCwgMTkwLCAxMzksIDcyLCAyMDEsIDI0NCwgMTM5LCA4NiwgMTM5LCA5NiwgMTM5LCAxMDUsIDEzOSwgMTEzLAorMTM5LCAxMjMsIDIzMCwgMTk5LCAxMzksIDEzOSwgMTM5LCAxNDYsIDEzOSwgMTU0LCAxMzksIDE2MCwgMTM5LCAxNjYsIDEzOSwgMTczLAorMTM5LCAxODIsIDEzOSwgMTkyLCAxMzksIDIwMSwgMjMwLCAyMTIsIDEzOSwgMjE5LCAxMzksIDIyOSwgMjE3LCAyNDgsIDEzOSwgMjQ2LAorMTQwLCA2NCwgMTQwLCA3MiwgMjE1LCAyMDYsIDIwOSwgMTY3LCAyMDIsIDIzNSwgMjAwLCAyMzAsIDIyOSwgMTc5LCAxNDAsIDk3LAorMTg1LCAyMTcsIDE5MSwgMjA1LCAxNDAsIDEwNywgMTg4LCAyMTAsIDE0MCwgMTE3LCAxNDAsIDEyMiwgMTQwLCAxMjksIDE5NiwgMTc1LAorMjEzLCAxNzUsIDE0MCwgMTUwLCAxODEsIDE4OCwgMTg5LCAxNzEsIDE0MCwgMTY4LCAyMDEsIDIwOCwgMjExLCAyMDAsIDE0MCwgMTg1LAorMjAyLCAxNzIsIDE3OCwgMjI3LCAxNDAsIDE5NywgMTQwLCAyMDIsIDIwNSwgMTkyLCAxNDAsIDIxNSwgMTQwLCAyMjIsIDE0MCwgMjMwLAorMjI1LCAxNzIsIDE0MCwgMjQyLCAyMjUsIDE3NywgMTQwLCAyNTIsIDE0MSwgNjcsIDE0MSwgNzIsIDIyNSwgMTg3LCAxNDEsIDg3LAorMTQxLCA5NiwgMTQxLCAxMDQsIDE0MSwgMTA5LCAxNDEsIDExNywgMTQxLCAxMjYsIDE0MSwgMTMzLCAxODAsIDIyMiwgMjI1LCAxOTgsCisxNDEsIDE1NSwgMTQxLCAxNjIsIDE0MSwgMTcxLCAxNDEsIDE3OSwgMTQxLCAxODUsIDE0MSwgMTk0LCAxNDEsIDIwMiwgMTQxLCAyMDksCisxNDEsIDIxNywgMjI1LCAyMTQsIDE0MSwgMjM2LCAxNDEsIDI0NiwgMTQxLCAyNTQsIDE0MiwgNzMsIDE0MiwgODMsIDE0MiwgOTIsCisxNDIsIDEwMSwgMTQyLCAxMTAsIDE0MiwgMTE5LCAyMTUsIDI0MywgMTQyLCAxMjgsIDE0MiwgMTMzLCAxNDIsIDEzOCwgMTQyLCAxNDQsCisxOTMsIDE3NywgMTQyLCAxNTIsIDE0MiwgMTYwLCAxNDIsIDE2NywgMTQyLCAxNzIsIDE0MiwgMTc5LCAyMjUsIDE2MywgMjI1LCAxNjUsCisxNDIsIDIwMiwgMTg0LCAyMDEsIDIxMSwgMjE1LCAxOTksIDIzNiwgMTk0LCAxNzQsIDE4NCwgMjUzLCAxNDIsIDIzMiwgMTQyLCAyMzgsCisyMTEsIDE4NSwgMTQyLCAyNTEsIDE0MywgNjgsIDE5MywgMjA2LCAxNDMsIDgzLCAyMjYsIDIyMiwgMjE5LCAyMDAsIDIyMiwgMTk1LAorMjIyLCAxOTYsIDE0MywgMTE1LCAxNDMsIDEyMCwgMjA3LCAyMTAsIDE0MywgMTMyLCAxOTksIDE5MSwgMTQzLCAxNDcsIDE0MywgMTU3LAorMjI5LCAyMzMsIDIwOCwgMjA2LCAxNzcsIDI0MiwgMTQzLCAxNzgsIDIwNSwgMjQ5LCAxODcsIDE3OCwgMTQzLCAxOTEsIDE0MywgMTk2LAorMjI1LCAyMjksIDE0MywgMjExLCAyMjUsIDIzMiwgMjEwLCAyMjgsIDIzNiwgMjU0LCAxNDMsIDIzMiwgMjI2LCAyMzIsIDIyNiwgMjI5LAorMjI2LCAyMzgsIDIwMywgMjAzLCAxNDQsIDY3LCAxNzgsIDE5MiwgMTgxLCAxNjEsIDE4NSwgMjE0LCAxNDQsIDg2LCAxNDQsIDkzLAorMTQ0LCA5OSwgMTg2LCAyMjcsIDE0NCwgMTEyLCAxNDQsIDExOCwgMTk5LCAxNjEsIDIyNiwgMjUzLCAxOTksIDE5NiwgMTQ0LCAxMzYsCisxNDQsIDE0MywgMTQ0LCAxNDgsIDIwOCwgMjUyLCAxNDQsIDE1OCwgMTQ0LCAxNjUsIDE5MCwgMTcwLCAxNDQsIDE4MCwgMTQ0LCAxODUsCisxNzgsIDIxMCwgMTQ0LCAxOTMsIDE0NCwgMTk4LCAyMzcsIDE2OSwgMTQ0LCAyMTAsIDIxMSwgMjIyLCAxODMsIDIyMywgMTQ0LCAyMzEsCisxNDQsIDI0MSwgMTQ0LCAyNTAsIDE4NywgMTk3LCAxNDUsIDczLCAxNDUsIDgyLCAxNDUsIDg5LCAxNDUsIDk4LCAxNDUsIDEwNiwKKzE0NSwgMTE2LCAxNDUsIDEyNCwgMTQ1LCAxMzQsIDE0NSwgMTQzLCAxNDUsIDE0OSwgMTQ1LCAxNTgsIDE0NSwgMTY2LCAxNDUsIDE3MywKKzE0NSwgMTgwLCAxNDUsIDE5MCwgMTQ1LCAxOTksIDE0NSwgMjA4LCAxNDUsIDIxNywgMjA2LCAyMzYsIDE0NSwgMjI2LCAxNDUsIDIzMCwKKzE0NSwgMjM1LCAxNDUsIDI0MiwgMTQ1LCAyNDksIDE0NSwgMjUzLCAxNDYsIDY1LCAxNDYsIDcwLCAxNDYsIDc4LCAxNzYsIDIzMSwKKzE0NiwgODYsIDE0NiwgOTEsIDE0NiwgOTgsIDE4MiwgMTgyLCAxOTEsIDIxNywgMTQ2LCAxMTIsIDE0NiwgMTE5LCAxNDYsIDEyNCwKKzE5NiwgMjMzLCAxOTAsIDIyMCwgMTc2LCAyMjEsIDE5MiwgMTg1LCAxNDYsIDE0MCwgMTQ2LCAxNDUsIDE0NiwgMTQ5LCAxOTEsIDIzMCwKKzE0NiwgMTYzLCAyMjIsIDIxNiwgMTQ2LCAxNjksIDE0NiwgMTc3LCAxNDYsIDE4NCwgMTQ2LCAxODksIDE0NiwgMTkzLCAxOTIsIDIwNCwKKzE0NiwgMjA2LCAxNDYsIDIxMiwgMTQ2LCAyMTgsIDE0NiwgMjI2LCAxOTgsIDI1NCwgMTQ2LCAyMzUsIDE0NiwgMjQyLCAyMjIsIDIzMSwKKzE4MSwgMTY3LCAxNDcsIDY1LCAxNDcsIDcyLCAyMTAsIDE5MCwgMjIyLCAyMzUsIDE5MCwgMTkwLCAyMTIsIDE3NCwgMTQ3LCAxMDQsCisxNDcsIDEwOSwgMTQ3LCAxMTUsIDIwMywgMjA5LCAyMjIsIDI0OSwgMTQ3LCAxMzUsIDIwOCwgMTc1LCAyMDEsIDIyNywgMTQ3LCAxNTQsCisyMTMsIDE3MCwgMTQ3LCAxNzAsIDE0NywgMTc4LCAxNDcsIDE4NywgMTQ3LCAxOTQsIDE0NywgMjAwLCAxNDcsIDIwOCwgMjE1LCAxNzgsCisxNDcsIDIyMywgMTQ3LCAyMjgsIDE4NiwgMTc5LCAxNDcsIDI0MCwgMjIzLCAxNjcsIDE0NywgMjU0LCAyMjMsIDE2OSwgMTQ4LCA3OSwKKzE0OCwgODksIDE0OCwgOTgsIDE0OCwgMTA3LCAxNDgsIDExNiwgMTQ4LCAxMjUsIDE0OCwgMTM1LCAyMzQsIDE4MywgMTgzLCAxOTcsCisyMDgsIDE2NywgMTQ4LCAxNTgsIDE0OCwgMTY0LCAxODIsIDIxNiwgMjAyLCAyNTMsIDE0OCwgMTgzLCAxNDgsIDE5MywgMTQ4LCAyMDAsCisxNDgsIDIwNiwgMTQ4LCAyMTEsIDE0OCwgMjE2LCAxNDgsIDIyMywgMTQ4LCAyMzAsIDE0OCwgMjM1LCAxNDgsIDI0MCwgMTQ4LCAyNDgsCisyMTQsIDE4OCwgMTQ5LCA2NCwgMTQ5LCA3MSwgMTkyLCAxNjUsIDE0OSwgODMsIDE0OSwgODksIDE0OSwgOTYsIDE0OSwgMTAyLAorMTQ5LCAxMDcsIDE0OSwgMTE0LCAyMDEsIDIwNiwgMjM0LCAyMDUsIDE0OSwgMTMzLCAxNDksIDEzOSwgMTk5LCAyMzEsIDE5MywgMTkyLAorMTQ5LCAxNTgsIDE0OSwgMTY2LCAxNDksIDE3NCwgMTQ5LCAxODMsIDE0OSwgMTkwLCAxNDksIDE5OCwgMTQ5LCAyMDcsIDE0OSwgMjE3LAorMTQ5LCAyMjcsIDE0OSwgMjMzLCAxNDksIDI0MSwgMTQ5LCAyNDcsIDIxNSwgMjM4LCAyMzUsIDE5NSwgMjAzLCAxODMsIDE1MCwgNzksCisxOTYsIDE5MCwgMTUwLCA5MCwgMTUwLCA5NywgMTg0LCAyMDMsIDE3OCwgMTk2LCAxNTAsIDExMywgMTUwLCAxMTgsIDE1MCwgMTIzLAorMTUwLCAxMjgsIDE1MCwgMTM0LCAxNTAsIDE0MCwgMTUwLCAxNDgsIDE1MCwgMTUyLCAxOTksIDE4NSwgMTUwLCAxNjEsIDE1MCwgMTY3LAorMTUwLCAxNzQsIDE5OCwgMjI2LCAxODUsIDI0MSwgMTUwLCAxODksIDIzMiwgMjA1LCAxNTAsIDIwMiwgMTUwLCAyMDksIDIzMiwgMjIxLAorMTUwLCAyMTYsIDE1MCwgMjI0LCAxNTAsIDIzMiwgMTUwLCAyNDAsIDIzMiwgMjM4LCAyMzIsIDI0MCwgMTg5LCAyMTksIDE1MSwgNjYsCisxODksIDE3NiwgMTUxLCA3NSwgMTUxLCA4MiwgMTc2LCAyNDAsIDE1MSwgOTcsIDE1MSwgMTA1LCAxNTEsIDExNCwgMTUxLCAxMjAsCisxNTEsIDEyNiwgMjMyLCAyNDksIDE1MSwgMTQzLCAxNTEsIDE1MCwgMjA0LCAxOTYsIDE1MSwgMTY2LCAxNTEsIDE3MywgMTUxLCAxNzksCisxNTEsIDE4NywgMTg5LCAxODMsIDE1MSwgMjAyLCAxNTEsIDIwOSwgMjEwLCAxNzIsIDE1MSwgMjI1LCAxNTEsIDIzMiwgMTUxLCAyNDIsCisxNTEsIDI1MCwgMTUyLCA2NSwgMTUyLCA3MiwgMTUyLCA4MCwgMjMzLCAxNzUsIDE1MiwgODksIDE5MiwgMTk4LCAxNTIsIDEwMywKKzIxMywgMTY1LCAxNTIsIDExOCwgMTUyLCAxMjUsIDE1MiwgMTM1LCAxODcsIDE3NywgMTUyLCAxNTAsIDE1MiwgMTU3LCAxNTIsIDE2NiwKKzE1MiwgMTc1LCAxNTIsIDE4MywgMTUyLCAxOTIsIDE1MiwgMjAyLCAxNTIsIDIwOSwgMTg2LCAyMjUsIDE1MiwgMjI0LCAyMzMsIDIwOCwKKzE1MiwgMjM5LCAxNTIsIDI0OCwgMTUzLCA2NCwgMTUzLCA3MiwgMTUzLCA4MiwgMTUzLCA5MCwgMjA3LCAxNzMsIDIzMywgMjEzLAorMTUzLCAxMTMsIDE1MywgMTIyLCAxOTUsIDIwMiwgMTUzLCAxNDAsIDE1MywgMTUwLCAxNTMsIDE2MCwgMTUzLCAxNzAsIDE1MywgMTgwLAorMTUzLCAxOTAsIDE1MywgMjAwLCAxNTMsIDIxMCwgMTUzLCAyMjAsIDE1MywgMjMwLCAxNTMsIDI0MCwgMjM2LCAxNjMsIDE1MywgMjU0LAorMTU0LCA3MSwgMTU0LCA3OCwgMTg0LCAyMzIsIDE1NCwgOTMsIDE1NCwgMTAyLCAyMDUsIDIyNSwgMTU0LCAxMTUsIDE1NCwgMTIyLAorMTU0LCAxMjYsIDIzMywgMjMwLCAxNTQsIDEzOCwgMTU0LCAxNDcsIDE1NCwgMTU2LCAxNTQsIDE2MiwgMTU0LCAxNjksIDE1NCwgMTc2LAorMTU0LCAxNzksIDE1NCwgMTg2LCAxNTQsIDE5NCwgMTU0LCAyMDEsIDE1NCwgMjA5LCAxNTQsIDIxNiwgMTk4LCAyNDgsIDE1NCwgMjI0LAorMTc2LCAxNzcsIDIzNSwgMTgxLCAxNTQsIDIzOCwgMjE3LCAyMjQsIDIwNywgMTcxLCAxNTUsIDY1LCAyMDQsIDE5MiwgMTU1LCA3NCwKKzE1NSwgODAsIDIxMCwgMjAyLCAyMjcsIDIzMSwgMTU1LCA5NSwgMTU1LCAxMDIsIDE4NywgMTY2LCAxNTUsIDEwOCwgMjEzLCAxODAsCisxNTUsIDExOSwgMTU1LCAxMjUsIDE1NSwgMTMwLCAxNTUsIDEzNCwgMjA0LCAxNjksIDIyNywgMjQ4LCAyMjgsIDE2NywgMjI4LCAxNjksCisxNTUsIDE1OSwgMTU1LCAxNjUsIDE1NSwgMTcxLCAxNTUsIDE3NiwgMTU1LCAxODEsIDIxNSwgMTk5LCAyMjgsIDE3NywgMjI4LCAxODMsCisxNTUsIDE5OSwgMTU1LCAyMDUsIDIyOCwgMTg4LCAxNTUsIDIxOSwgMTU1LCAyMjUsIDE1NSwgMjMxLCAxODEsIDIxMSwgMjI4LCAyMDQsCisxODYsIDIxMiwgMTU1LCAyNTAsIDIwNCwgMjAyLCAxOTYsIDIxNSwgMjI4LCAxOTYsIDE1NiwgODMsIDE1NiwgODgsIDE1NiwgOTQsCisxNTYsIDEwMywgMTU2LCAxMDcsIDE1NiwgMTEzLCAxNTYsIDExNywgMTU2LCAxMjMsIDE5NSwgMjM2LCAyMjgsIDIxNiwgMjI4LCAyMDcsCisyMDcsIDIzMCwgMTU2LCAxNjAsIDE1NiwgMTY5LCAxNTYsIDE3OCwgMTU2LCAxODYsIDE1NiwgMTkyLCAxNTYsIDIwMCwgMTU2LCAyMDgsCisxNTYsIDIxNCwgMjI4LCAyMDksIDE1NiwgMjI1LCAxNTYsIDIzMiwgMTU2LCAyMzksIDE4NSwgMjQ2LCAxOTQsIDIwMywgMTU2LCAyNTMsCisxNTcsIDcxLCAxOTgsIDE3NSwgMTU3LCA4NywgMTU3LCA5MywgMTk2LCAxNzQsIDIyOCwgMjQ0LCAxNTcsIDExNCwgMjA5LCAyNTAsCisxNTcsIDEzMSwgMTU3LCAxMzksIDE5OSwgMTc3LCAxOTMsIDIwMiwgMTU3LCAxNjIsIDIyOCwgMjUzLCAxNzksIDIwNiwgMTk3LCAyMzYsCisxNTcsIDE5MSwgMTU3LCAxOTksIDE1NywgMjA4LCAyMjksIDE2NCwgMTg4LCAxNjQsIDE1NywgMjMyLCAxNTcsIDI0MCwgMjI5LCAxNjgsCisxNTgsIDY2LCAxNTgsIDc0LCAxNTgsIDg0LCAxNTgsIDk0LCAxNTgsIDEwNCwgMjI5LCAxNzEsIDE1OCwgMTIwLCAxNTgsIDEzMSwKKzE1OCwgMTQwLCAxNTgsIDE0OSwgMTg1LCAyMjQsIDE1OCwgMTY3LCAxNTgsIDE3NiwgMTU4LCAxODYsIDE1OCwgMTkxLCAyMTIsIDIxNCwKKzE1OCwgMjAzLCAxNzksIDE4MCwgMjM2LCAxOTEsIDE1OCwgMjIzLCAxNTgsIDIyOCwgMTU4LCAyMzMsIDE1OCwgMjM2LCAxNTgsIDI0NCwKKzE4NiwgMjMwLCAxNTksIDY5LCAxODksIDI1MywgMTU5LCA4MCwgMTU5LCA4NywgMTg2LCAxODQsIDE1OSwgMTAzLCAxNTksIDEwOCwKKzE1OSwgMTE3LCAxNTksIDEyNCwgMTU5LCAxMzQsIDE1OSwgMTQzLCAxNTksIDE1MCwgMTU5LCAxNjAsIDE5NSwgMTg2LCAyMTQsIDI0MywKKzIzNiwgMjEyLCAxNTksIDE4OCwgMTU5LCAxOTYsIDE1OSwgMjA0LCAyMzYsIDIxOCwgMTU5LCAyMTksIDE1OSwgMjI3LCAxNTksIDIzNSwKKzE1OSwgMjQ0LCAxNTksIDI1MywgMTYwLCA3MCwgMTYwLCA3OCwgMTYwLCA4NiwgMTYwLCA5NSwgMTYwLCAxMDUsIDE2MCwgMTE0LAorMTYwLCAxMjQsIDE2MCwgMTM0LCAxOTcsIDE5MiwgMTg0LCAxODQsIDE2MCwgMTUxLCAxNjAsIDE1OSwgMTYwLCAxNjYsIDE2MCwgMTcyLAorMTYwLCAxNzcsIDIwMSwgMjUyLCAxNjAsIDE5MCwgMTYwLCAxOTUsIDE2MCwgMjAxLCAxNjAsIDIxMCwgMTYwLCAyMTksIDE2MCwgMjI3LAorMjI1LCAyMzksIDE5MSwgMjQxLCAxNjAsIDI0NSwgMTYwLCAyNTEsIDE4NiwgMjIxLCAxNzAsIDczLCAyMjUsIDI0OSwgMTcwLCA3OSwKKzE3MCwgODcsIDE3MCwgOTUsIDE3OCwgMTk0LCAxNzAsIDEwNCwgMTcwLCAxMDksIDE3MCwgMTE0LCAxNzAsIDEyMiwgMTcwLCAxMzIsCisxNzAsIDEzOSwgMTcwLCAxNDgsIDIyNiwgMTc5LCAxNzEsIDY4LCAxNzEsIDc3LCAxNzEsIDg0LCAxNzEsIDkxLCAxNzEsIDk5LAorMTcxLCAxMDcsIDE5MywgMjI1LCAxNzEsIDExNywgMTcxLCAxMjUsIDE4MywgMTY5LCAxNzEsIDEzOCwgMTcxLCAxNDYsIDE3MSwgMTUyLAorMTcyLCA2NCwgMTcyLCA3NCwgMTcyLCA3OSwgMTcyLCA4NywgMTcyLCA5NSwgMjMxLCAyNDcsIDE5OSwgMjE3LCAxNzIsIDExMiwKKzE3MiwgMTIxLCAxNzIsIDEzMiwgMjMyLCAxNjQsIDE3MiwgMTQ0LCAxODUsIDIyOSwgMTcyLCAxNjAsIDE3MywgNjksIDIzMiwgMTcyLAorMTczLCA4NSwgMTczLCA5MywgMTczLCAxMDAsIDE3MywgMTEwLCAxNzMsIDExOSwgMTczLCAxMzAsIDE3MywgMTM5LCAyNDAsIDE3MiwKKzE3MywgMTUyLCAxNzMsIDE2MCwgMTc0LCA3MCwgMTc0LCA3OCwgMTc0LCA4NiwgMjAxLCAyNDUsIDE3NCwgOTksIDE3NCwgMTAzLAorMTgxLCAyMzMsIDE3NCwgMTExLCAxODksIDIzMSwgMTc0LCAxMjQsIDE3NCwgMTMxLCAxODMsIDE3MiwgMTc5LCAyMzUsIDE3NCwgMTU0LAorMTc1LCA2NCwgMjQwLCAyMTgsIDE3NSwgNzUsIDE3NSwgNzgsIDI0MCwgMjMwLCAxNzUsIDg2LCAyNDAsIDIyOCwgMTc1LCA5NCwKKzE4MiwgMTg3LCAxOTMsIDE2MSwgMTc1LCAxMDksIDE3NSwgMTE2LCAyNDAsIDI0NiwgMjQwLCAyNTAsIDE3NSwgMTM3LCAxNzUsIDE0MiwKKzE3NSwgMTQ2LCAxNzUsIDE1MSwgMjQxLCAxNjIsIDE3NiwgNjUsIDE3NiwgNzMsIDE3NiwgODEsIDE3NiwgODgsIDE3NiwgOTcsCisxODUsIDIzOSwgMjEyLCAyMzcsIDE3NiwgMTE2LCAyMDUsIDIzOCwgMTc2LCAxMzIsIDE3NiwgMTQxLCAyNDEsIDIyOSwgMTc2LCAxNTcsCisyMTEsIDE3NSwgMTg2LCAyMDgsIDE3NywgNzMsIDE3NywgODEsIDE3NywgODksIDE3NywgOTQsIDIzNywgMjM3LCAxNzcsIDEwNSwKKzE3NywgMTE1LCAyMzcsIDI0MywgMTc3LCAxMjgsIDE5MSwgMjQ0LCAyMTUsIDE5NywgMTc3LCAxNDYsIDE3NywgMTU0LCAxNzgsIDY1LAorMjM3LCAyNTQsIDE3OCwgNzcsIDE3OCwgODYsIDE3OCwgOTAsIDE3OCwgOTcsIDE3OCwgMTA1LCAxNzgsIDExMiwgMTc4LCAxMTcsCisxNzgsIDEyNCwgMTc4LCAxMzIsIDE3OCwgMTQyLCAxNzgsIDE1MSwgMTc4LCAxNTgsIDE3OSwgNjYsIDE3OSwgNzEsIDE4MywgMTc1LAorMTc5LCA4MywgMTk3LCAyNDgsIDIzNywgMTkxLCAyMzcsIDIwNiwgMTk3LCAyMzMsIDIzNywgMTk0LCAxNzksIDExMywgMjM3LCAyMDIsCisxNzksIDEyNCwgMTc5LCAxMzQsIDIxMSwgMTc4LCAxNzksIDE0OSwgMTc5LCAxNTcsIDE4MCwgNjgsIDE4MCwgNzMsIDE4MCwgNzgsCisxODAsIDgzLCAyMzcsIDIxOCwgMTgwLCA5NywgMTgwLCAxMDQsIDE5NywgMjA1LCAxODAsIDExNywgMTgwLCAxMjgsIDE4MCwgMTM2LAorMTgwLCAxNDMsIDE4MCwgMTUxLCAxODAsIDE2MCwgMTgxLCA3MiwgMTgxLCA4MSwgMTgxLCA5MCwgMjM3LCAyMzEsIDIwMSwgMjMxLAorMTk4LCAyMzcsIDE4MSwgMTIwLCAyMzYsIDIzOSwgMTgxLCAxMjksIDE4MSwgMTM1LCAyMzYsIDI0NywgMTk0LCAxODcsIDE4MSwgMTU3LAorMTgyLCA2OSwgMTgyLCA3OCwgMTgyLCA4NywgMTgyLCA5NiwgMjA4LCAyMjcsIDE4MiwgMTA2LCAxODIsIDExMiwgMTgyLCAxMjAsCisxODIsIDEyNSwgMTgyLCAxMzEsIDE4MiwgMTM5LCAyMzksIDI0OSwgMTgyLCAxNTEsIDIxNCwgMjAxLCAxODMsIDY4LCAxODMsIDc4LAorMTgzLCA4NiwgMTgzLCA5MSwgMTgzLCAxMDAsIDE4MywgMTA5LCAxODMsIDExOCwgMTgzLCAxMjksIDIwOSwgMTY4LCAxODMsIDE0MiwKKzI0MSwgMTg2LCAyMTQsIDIwNywgMTgwLCAyMjAsIDI0MSwgMTg4LCAxODQsIDcyLCAxODQsIDgxLCAxODQsIDkwLCAxODQsIDk5LAorMTg0LCAxMDgsIDE4NCwgMTE0LCAxODQsIDEyMSwgMTg0LCAxMzAsIDE4NCwgMTM2LCAyNDMsIDIwMSwgMTc3LCAyMDIsIDI0MywgMjE1LAorMTc3LCAxOTEsIDE4NSwgNjYsIDE5MywgMjUzLCAxODUsIDgwLCAxOTEsIDI0MCwgMjQzLCAyMTcsIDE4NSwgOTQsIDI0MywgMjIzLAorMTg1LCAxMDksIDE4NSwgMTE1LCAxODUsIDEyNCwgMTg1LCAxMzEsIDE4NSwgMTM4LCAyNDMsIDIzNiwgMjQzLCAyNDAsIDE4NSwgMTU1LAorMTg2LCA2NSwgMTg2LCA3MywgMTg2LCA4MCwgMjQzLCAyNDcsIDE4NiwgOTQsIDE4NiwgMTAyLCAxODYsIDExMCwgMTg2LCAxMTcsCisxODYsIDEyNSwgMTg2LCAxMzUsIDE4NiwgMTQyLCAxODYsIDE1MiwgMjQ0LCAxNjYsIDE4NywgNzEsIDE4NywgODAsIDE4NywgOTAsCisxODcsIDEwMCwgMTg3LCAxMTAsIDI0NCwgMjA0LCAxODcsIDEyNSwgMTg3LCAxMzUsIDE4NywgMTQwLCAyMTIsIDE5MywgMTkzLCAxODQsCisxODcsIDE1OCwgMTg4LCA2NiwgMjQ0LCAyMTYsIDIwNCwgMTk5LCAxOTEsIDE4MywgMTg4LCA5MiwgMTg4LCAxMDEsIDE4OCwgMTA5LAorMTg4LCAxMTksIDE4OCwgMTI5LCAxODgsIDEzOSwgMTg4LCAxNDcsIDE4OCwgMTU0LCAxODksIDY3LCAxODksIDc3LCAxODksIDg3LAorMTg5LCA5NywgMTg5LCAxMDcsIDE4OSwgMTE3LCAxODksIDEyNiwgMTg5LCAxMzYsIDE4OSwgMTQ2LCAxODksIDE1NiwgMTkwLCA2OSwKKzE5MCwgNzgsIDE5MCwgODcsIDE5MCwgOTcsIDE5MCwgMTA3LCAxOTAsIDExNywgMTkwLCAxMjgsIDE5MCwgMTM4LCAxOTAsIDE0OCwKKzE5MCwgMTU4LCAxOTEsIDcxLCAxOTEsIDgxLCAxOTEsIDkxLCAxOTEsIDEwMSwgMTkxLCAxMTEsIDE5MSwgMTIxLCAxOTEsIDEzMSwKKzE5MSwgMTM5LCAxOTEsIDE0OSwgMTkxLCAxNTksIDE5MiwgNzIsIDE5MiwgODIsIDE5MiwgOTIsIDE5MiwgMTAxLCAxOTIsIDExMSwKKzE5MiwgMTIxLCAxODYsIDIzNiwgMjA2LCAxNzksIDE5NCwgMjE4LCAyMzEsIDE2NCwgMTc2LCAyMzcsIDIzMSwgMTcxLCAxODksIDIwMiwKKzIzMSwgMTc2LCAyMzEsIDE4MSwgMjE1LCAyMTksIDE5MiwgMTk0LCAxOTIsIDEzNywgMTg0LCAxOTEsIDIzMSwgMjA1LCAyMDEsIDIwMSwKKzE4NCwgMjE1LCAyNDMsIDE5MSwgMTkyLCAxNTUsIDE5MywgNjQsIDE5MywgNzAsIDIxNSwgMjM5LCAyMzgsIDE4OCwgMjM4LCAxOTIsCisxOTMsIDk4LCAxOTMsIDEwNSwgMTkzLCAxMTMsIDE5MywgMTE4LCAyNDQsIDIwMiwgMTkzLCAxMzMsIDE5MywgMTM5LCAyNDQsIDIyNSwKKzE5OSwgMjA0LCAxOTMsIDE1OSwgMTk0LCA2OSwgMTk0LCA3NSwgMjEwLCAxNzEsIDE5NCwgODcsIDI0MSwgMjMyLCAxOTQsIDk1LAorMjQxLCAyNDEsIDE5NCwgMTA2LCAxOTQsIDExMCwgMjQxLCAyNDYsIDE5NCwgMTIxLCAxOTAsIDIxOSwgMTk0LCAxMzgsIDE5NCwgMTQ2LAorMTk0LCAxNTUsIDE5NSwgNjYsIDE4OCwgMTYxLCAyMDgsIDE2NCwgMTc5LCAxNjYsIDE4MywgMTkwLCAyMzUsIDIwMCwgMjAxLCAyNDYsCisxOTUsIDk1LCAxOTUsIDEwMiwgMjAyLCAxNjQsIDE5NSwgMTExLCAyMTAsIDIwMCwgMTc2LCAxODMsIDE5NSwgMTIyLCAyMzUsIDIxOSwKKzIzNSwgMjI4LCAxOTUsIDEzOCwgMjM1LCAyMjcsIDIzNSwgMjI1LCAxOTYsIDY0LCAxOTIsIDE3NiwgMTk5LCAxODcsIDE5NiwgODIsCisxOTYsIDg5LCAxOTYsIDk0LCAyMzUsIDIzOSwgMTk2LCAxMDQsIDE5NiwgMTExLCAxOTYsIDExOSwgMTk2LCAxMjUsIDE5NiwgMTMzLAorMTk2LCAxNDIsIDE3NywgMjE5LCAyMzUsIDI1MSwgMTk3LCA2NiwgMTk3LCA3NiwgMjE1LCAyMTIsIDIxNCwgMTk0LCAyNDQsIDE2NywKKzE5NywgMTAwLCAyMDIsIDIzMCwgMjAzLCAxODAsIDE5NywgMTE4LCAxODksIDE2MiwgMTk3LCAxMjMsIDI0NCwgMTg1LCAxOTcsIDEzOCwKKzIwMywgMjEwLCAxOTcsIDE1NCwgMTk4LCA2NiwgMTk4LCA3MCwgMTk4LCA3NSwgMjIwLCAxODMsIDE5OCwgODUsIDE5OCwgOTAsCisyMjAsIDE4NCwgMTk4LCA5NSwgMTk4LCAxMDAsIDE5OCwgMTA2LCAxOTgsIDEwOCwgMTk4LCAxMTEsIDIyMCwgMjE0LCAxOTgsIDEyMCwKKzE5OCwgMTI2LCAxOTUsIDE3NSwgMjIwLCAyMjEsIDE5OCwgMTQwLCAxOTgsIDE0NiwgMTk4LCAxNTQsIDIyMCwgMjM4LCAxOTksIDY0LAorMTk5LCA3MCwgMTg3LCAxOTYsIDIyMCwgMjM0LCAyMjAsIDI1MywgMTk5LCA4NCwgMTk5LCA5MiwgMTk5LCA5OSwgMjAxLCAxNzUsCisyMjEsIDE4MywgMTk5LCAxMTgsIDE5OSwgMTI0LCAyMjEsIDE3OCwgMjIxLCAyMTAsIDE5MCwgMjEzLCAyMjEsIDIwMiwgMTk5LCAxNTEsCisxOTksIDE1NywgMTgzLCAxOTgsIDIwMCwgNzMsIDIyMSwgMjAxLCAyMDAsIDgzLCAyMDAsIDkxLCAyMTEsIDE2OSwgMjAwLCAxMDQsCisyMjEsIDE5OSwgMjAwLCAxMjAsIDIwMCwgMTMwLCAyMDAsIDEzOSwgMjAwLCAxNDQsIDIwMCwgMTUxLCAyMDAsIDE1NiwgMjAxLCA2NSwKKzIyMSwgMjIwLCAyMDEsIDc4LCAyMDMsIDIyNiwgMjAxLCA5NCwgMjAxLCAxMDMsIDIyMSwgMjQwLCAyMDgsIDIzOCwgMjAxLCAxMjEsCisyMDEsIDEyOCwgMjAxLCAxMzUsIDE5NywgMjM4LCAyMDEsIDE1MCwgMjAxLCAxNTgsIDIwMiwgNzEsIDIwMiwgNzgsIDIwMiwgODYsCisyMDIsIDk0LCAyMDIsIDEwMiwgMTc2LCAxNzAsIDIwMiwgMTE0LCAyMDIsIDEyMSwgMjAyLCAxMzAsIDIyMiwgMTY4LCAyMDIsIDE0NywKKzIwMiwgMTU1LCAyMDMsIDY0LCAyMDMsIDcxLCAyMDMsIDgwLCAyMDMsIDg4LCAyMDgsIDE4OSwgMjAzLCAxMDIsIDIwMywgMTEwLAorMjAzLCAxMTksIDIwMywgMTI2LCAyMjIsIDE4OCwgMjAzLCAxNDMsIDIwMywgMTUyLCAyMDQsIDY1LCAyMDQsIDczLCAyMDQsIDgyLAorMjA0LCA5MCwgMjA0LCAxMDAsIDIwNCwgMTA4LCAyMDQsIDExOCwgMjA0LCAxMjYsIDIwNCwgMTM3LCAyNDIsIDE3NSwgMjExLCAyMjEsCisyMDQsIDE1OCwgMjA1LCA2NywgMjQyLCAxODAsIDIwNSwgNzcsIDIwNSwgODMsIDIwNSwgOTEsIDIxMiwgMjMzLCAyMDUsIDEwMiwKKzIwNSwgMTA2LCAyMDUsIDExNCwgMjA1LCAxMTgsIDIwNSwgMTIzLCAyMDUsIDEyOSwgMjA1LCAxMzcsIDI0MiwgMjExLCAxODIsIDIzNCwKKzI0MiwgMjE4LCAyMDksIDIwOSwgMTk1LCAyMTksIDIwNiwgNzAsIDIwNiwgNzgsIDIwNiwgODUsIDIwNiwgOTIsIDIwOCwgMTcxLAorMjA2LCAxMDUsIDIwNiwgMTEzLCAyMDYsIDEyMCwgMTgxLCAyNTEsIDIwNiwgMTMzLCAyMDYsIDEzOSwgMjA2LCAxNDYsIDIwNiwgMTU1LAorMjQyLCAyNTMsIDIwNywgNzIsIDIwNywgNzksIDI0MywgMTYxLCAyMDcsIDk0LCAyMDcsIDEwMSwgMjA3LCAxMDksIDI0MywgMTgxLAorMjA3LCAxMjYsIDIwNywgMTM1LCAyMDcsIDE0MywgMjQzLCAxODIsIDIwNywgMTU5LCAyMDgsIDcwLCAyMDgsIDc5LCAyMDgsIDg3LAorMjA4LCA5NCwgMjA4LCAxMDIsIDIwOCwgMTA5LCAyMDgsIDExNCwgMjAzLCAxNjUsIDIwOCwgMTI2LCAxNzYsIDE5MiwgMjA4LCAxMzcsCisyMDgsIDE0NSwgMjQxLCAyMDAsIDIwOSwgNjQsIDIwOSwgNzIsIDIwOSwgODAsIDIwOSwgODUsIDIxMCwgMjI1LCAyMDksIDk5LAorMjQxLCAyMTIsIDIwOSwgMTExLCAyNDEsIDIxMSwgMjA5LCAxMjQsIDE4NiwgMjE0LCAyNDEsIDIxMCwgMjA5LCAxNDcsIDIwOSwgMTU0LAorMjEwLCA2NCwgMjEwLCA3MywgMjEwLCA4MiwgMjEwLCA5MiwgMjEwLCAxMDAsIDIxMCwgMTA5LCAyMTAsIDExOSwgMjEwLCAxMjksCisyMTAsIDEzNSwgMjEwLCAxNDUsIDIxMCwgMTU1LCAyMTEsIDY4LCAyMTEsIDc4LCAyMTEsIDg4LCAxODUsIDIzMCwgMjM0LCAyMzYsCisyMTEsIDEwMSwgMjExLCAxMDgsIDIxMSwgMTE0LCAyMTEsIDEyMiwgMjA5LCAyMTIsIDIxMSwgMTQxLCAyMTEsIDE1MSwgMjEyLCA2NCwKKzIxMiwgNzQsIDIxMiwgODQsIDIxMiwgOTQsIDIxMiwgMTAzLCAyMTIsIDExMiwgMjEyLCAxMjIsIDIxMiwgMTMzLCAyMTIsIDE0MywKKzIxMiwgMTUzLCAyMTMsIDY1LCAyMTMsIDczLCAyMTMsIDgyLCAyMTMsIDkyLCAyMTMsIDEwMiwgMjEzLCAxMTIsIDIxMywgMTIyLAorMjEzLCAxMzMsIDIxMywgMTQzLCAyMTMsIDE1MywgMjE0LCA2NiwgMjE0LCA3NiwgMjE0LCA4NiwgMjE0LCA5NiwgMjE0LCAxMDUsCisyMTQsIDExNSwgMjE0LCAxMjUsIDIxNCwgMTM1LCAyMTQsIDE0NSwgMjE0LCAxNTUsIDIxNSwgNjgsIDIxNSwgNzgsIDIxNSwgODgsCisyMTUsIDk3LCAyMTUsIDEwNiwgMjE1LCAxMTYsIDIxNSwgMTI2LCAyMTUsIDEzNywgMjE1LCAxNDcsIDIwMCwgMjA3LCAyMTAsIDIzMywKKzIwOCwgMjM3LCAyMTgsIDE3MiwgMjE0LCAyMjMsIDIxOCwgMTgwLCAyMTgsIDE4NSwgMjE1LCAxNTgsIDIwMywgMTgxLCAxOTEsIDIwNiwKKzIwNCwgMTg0LCAyMTgsIDIwMywgMTk1LCAyMTMsIDE5OSwgMTcxLCAxOTIsIDE5MCwgMjE2LCA2NiwgMjE2LCA3NSwgMjE2LCA4MSwKKzIxNiwgOTAsIDE4NywgMTkxLCAyMTYsIDEwNSwgMjE2LCAxMTQsIDIxNiwgMTIxLCAyNDUsIDI0NiwgMjQ1LCAyNDksIDIxNiwgMTQ1LAorMjE2LCAxNTUsIDIxNywgNjgsIDIxNywgNzgsIDIxNywgODgsIDIxNywgOTgsIDIxNywgMTA4LCAyMTcsIDExOCwgMjE3LCAxMjksCisyMTcsIDEzOSwgMjE3LCAxNDksIDIxNywgMTU5LCAyMTgsIDcyLCAyMTgsIDc5LCAyMDQsIDE3NiwgMjA0LCAyNDksIDE4OCwgMjE0LAorMjM0LCAyMjYsIDIxOCwgODEsIDIxNiwgMjExLCAyMDEsIDIyNiwgMjE1LCAyMjMsIDIxOCwgOTUsIDI0NCwgMjQyLCAyMTgsIDExMCwKKzIxOCwgMTE4LCAyMTgsIDEyOCwgMjE4LCAxMzcsIDIxOCwgMTQzLCAyMTgsIDE0OCwgMjE4LCAxNTUsIDIxOCwgMTYwLCAyNDUsIDIwMCwKKzE5MSwgMjMxLCAyMTksIDc5LCAyMTksIDgyLCAyMTksIDkwLCAyMTksIDk2LCAyMTksIDEwNSwgMjE5LCAxMTAsIDI0NSwgMjE4LAorMjE5LCAxMjMsIDI0NSwgMjI5LCAyMTksIDEzMiwgMjE5LCAxNDAsIDIxOSwgMTQ5LCAyMTksIDE1NywgMjQ1LCAyMzcsIDIyMCwgNzIsCisyMjAsIDc4LCAyMjAsIDg2LCAyNDUsIDI0MiwgMjIwLCAxMDMsIDIyMCwgMTEwLCAyMDQsIDIwMSwgMjIwLCAxMjksIDIzNCwgMTY2LAorMjIwLCAxNDgsIDIyMCwgMTU4LCAyMjEsIDcxLCAyMjEsIDgxLCAyMjEsIDkxLCAyMjEsIDEwMSwgMjIxLCAxMTEsIDIyMSwgMTIxLAorMjIxLCAxMzIsIDIyMSwgMTQyLCAyMjEsIDE1MiwgMjIyLCA2NSwgMjIyLCA3NSwgMjIyLCA4NSwgMjIyLCA5NSwgMTk0LCAyMTQsCisyMzMsIDI0NCwgMjMzLCAyNTEsIDIyMiwgOTksIDIwNywgMTg5LCAyMjIsIDEwMiwgMjIyLCAxMDksIDIyMiwgMTE2LCAxODAsIDIzOSwKKzE5NCwgMjQ1LCAyMjIsIDEzNCwgMjEyLCAxODIsIDIyOSwgMjAwLCAyMDIsIDI0NiwgMjIyLCAxNDksIDIyOSwgMjA0LCAyMjIsIDE1NywKKzIyMiwgMTYwLCAxODMsIDIzNCwgMjIzLCA3NCwgMjI5LCAyMTIsIDIyMywgODUsIDIyMywgOTEsIDIyMywgOTUsIDIyMywgMTAyLAorMjI5LCAyMTksIDIyMywgMTE2LCAyMjMsIDEyNCwgMjIzLCAxMzAsIDIyMywgMTM4LCAyMjMsIDE0MywgMjIzLCAxNDgsIDIxMSwgMjAyLAorMjE5LCAxNjEsIDIyNCwgNjQsIDIyNCwgNzAsIDIyNCwgNzUsIDIyNCwgODEsIDIyNCwgODYsIDE3OSwgMTg3LCAyMTksIDE3NywKKzIyNCwgMTA3LCAyMjQsIDExNywgMjI0LCAxMjYsIDIyNCwgMTM0LCAyMjQsIDE0MywgMjI0LCAxNTEsIDIyNCwgMTYwLCAyNDQsIDI1MiwKKzIyNSwgNzIsIDI0NSwgMTYxLCAxNzksIDIzNCwgMTk1LCAxODQsIDIyNSwgODcsIDIyNSwgOTQsIDIyNSwgOTgsIDIyNSwgMTA2LAorMjI1LCAxMTQsIDIyNSwgMTIwLCAyMjUsIDEyOCwgMjI1LCAxMzgsIDIyNSwgMTQxLCAyMjUsIDE1MCwgMjI1LCAxNTksIDIyNiwgNzIsCisyMjYsIDgyLCAyMjYsIDkyLCAyMjYsIDEwMiwgMjI2LCAxMTIsIDIyNiwgMTIyLCAyMjYsIDEzMywgMjI2LCAxNDMsIDIyNiwgMTUzLAorMjI3LCA2NiwgMjI3LCA3NiwgMjI3LCA4NiwgMjI3LCA5NiwgMjI3LCAxMDYsIDIyNywgMTE1LCAyMjcsIDEyNSwgMjQ2LCAxOTgsCisyMjcsIDE0NSwgMjI3LCAxNTUsIDIyOCwgNjgsIDIyOCwgNzcsIDIyOCwgODcsIDIyOCwgOTYsIDIyOCwgMTA2LCAyMjgsIDExNiwKKzIyOCwgMTI2LCAyMjgsIDEzNywgMjI4LCAxNDcsIDIyOCwgMTU3LCAyMjksIDcwLCAyMjksIDgwLCAyMjksIDkwLCAyMjksIDEwMCwKKzIyOSwgMTEwLCAyMjksIDExOSwgMjI5LCAxMzAsIDIyOSwgMTQwLCAyMjksIDE1MCwgMjQ2LCAyMDIsIDIzMCwgNzIsIDIzMCwgODIsCisyMzAsIDkyLCAyMzAsIDEwMSwgMjMwLCAxMTEsIDIzMCwgMTIxLCAyMzAsIDEzMiwgMjMwLCAxNDIsIDIzMCwgMTUyLCAyMzEsIDY0LAorMjMxLCA3MywgMjMxLCA4MywgMjMxLCA5MywgMjMxLCAxMDMsIDIzMSwgMTEzLCAyMzEsIDEyMywgMjMxLCAxMzQsIDIzMSwgMTQ0LAorMjMxLCAxNTQsIDIzMiwgNjcsIDIzMiwgNzcsIDIzMiwgODYsIDIzMiwgOTYsIDIzMiwgMTA2LCAyMzIsIDExNiwgMjMyLCAxMjUsCisyMzIsIDEzNiwgMjMyLCAxNDYsIDIzOCwgMjAxLCAyMzIsIDE1MCwgMTk2LCAxOTgsIDIzOCwgMjE0LCAyMzgsIDIyMCwgMTg4LCAyMTYsCisyMzgsIDIzMCwgMjM4LCAyMzksIDIwNSwgMTczLCAyMzIsIDE1NywgMTg5LCAxOTQsIDE5OCwgMjA0LCAxNzksIDI1MCwgMjM5LCAxODAsCisyMzksIDE4NywgMjM5LCAxOTIsIDIzOSwgMTk2LCAyMzksIDIwMCwgMTgyLCAxOTgsIDE5NiwgMjQ3LCAyMzksIDIxNywgMjM5LCAyMjMsCisyMzksIDIzMiwgMjM5LCAyMzksIDIzMywgODEsIDIzMywgOTAsIDIzMywgMTAwLCAyMzMsIDExMCwgMjMzLCAxMjAsIDIzMywgMTMxLAorMjMzLCAxNDEsIDIzMywgMTUxLCAyMzQsIDY0LCAyMzQsIDc0LCAyMzQsIDg0LCAyMDEsIDE5MywgMTg4LCAyMjgsIDIyNywgMjA0LAorMjI3LCAyMDgsIDIyNywgMjE0LCAxODQsIDE4MywgMjM0LCAxMDMsIDIzNCwgMTExLCAyMzQsIDExNSwgMTg0LCAxODksIDIzNCwgMTIwLAorMjM0LCAxMjgsIDIxMiwgMTg2LCAyMTgsIDIzOCwgMjA0LCAyMTMsIDIzNCwgMTUzLCAyMzQsIDE2MCwgMTg0LCAyNDQsIDIzNSwgNzQsCisyMzUsIDgzLCAyMzUsIDkyLCAyNDYsIDE5MiwgMTg4LCAxNzUsIDIzNSwgMTA1LCAyMzUsIDExMywgMjM1LCAxMjIsIDIzNSwgMTMwLAorMjM1LCAxMzYsIDIzNSwgMTQyLCAyMzUsIDE0NywgMTkzLCAyMTYsIDIzNSwgMTYwLCAyNDYsIDE3NSwgMjM2LCA3OSwgMjQ2LCAxNzgsCisyMzYsIDk2LCAxOTksIDIyNCwgMjM2LCAxMTEsIDIzNiwgMTE2LCAyMzYsIDEyNSwgMjM2LCAxMzMsIDIzNiwgMTQyLCAyMzYsIDE0OSwKKzE5OSwgMjAyLCAyMzcsIDY3LCAyMzcsIDc1LCAyMzcsIDgxLCAyMzcsIDkxLCAyMzcsIDEwMSwgMjM3LCAxMTEsIDIzNywgMTIxLAorMjM3LCAxMzAsIDIzNywgMTM1LCAyMzcsIDE0MiwgMjM3LCAxNTIsIDIzOCwgNjUsIDIzOCwgNzUsIDIzOCwgODUsIDIzOCwgOTUsCisyMzgsIDEwNSwgMjM4LCAxMTUsIDIzOCwgMTI1LCAyMzgsIDEzNiwgMjM4LCAxNDYsIDIzOCwgMTU2LCAyMzksIDY5LCAxODUsIDIwMywKKzE5MCwgMTc3LCAyMzksIDcyLCAyMDksIDIxMywgMjQyLCAxNzMsIDIzOSwgODQsIDIzOSwgOTQsIDIzOSwgMTA0LCAxODMsIDIzMSwKKzE5OCwgMTc0LCAyMzksIDEyNCwgMjM5LCAxMzMsIDIzOSwgMTQzLCAyMzksIDE1MywgMjQwLCA2NiwgMjQwLCA3NCwgMjQwLCA4NCwKKzI0MCwgOTQsIDI0MCwgMTAzLCAyNDAsIDExMywgMjQwLCAxMjMsIDI0MCwgMTM0LCAyNDAsIDE0MiwgMjQwLCAxNTEsIDIxMCwgMjUxLAorMjQwLCAxNTQsIDI0MCwgMTU4LCAyNDEsIDY0LCAyMDIsIDIxNSwgMjQxLCA3MiwgMjQxLCA4MCwgMjQxLCA5MCwgMjQxLCAxMDAsCisyNDEsIDExMCwgMjQxLCAxMjAsIDI0MSwgMTMxLCAyNDEsIDE0MSwgMjQxLCAxNTEsIDI0MiwgNjQsIDI0MiwgNzQsIDI0MiwgODQsCisyNDIsIDk0LCAyNDIsIDEwNCwgMjQyLCAxMTQsIDI0MiwgMTI0LCAyNDIsIDEzNSwgMjQyLCAxNDUsIDI0MiwgMTU1LCAyNDMsIDY4LAorMjQzLCA3OCwgMjQzLCA4MiwgMjA1LCAyMTMsIDE5NCwgMjMwLCAyMzAsIDIzNSwgMjAxLCAxNjcsIDIxNCwgMjMyLCAyNDMsIDk2LAorMTg2LCAxNjEsIDI0NywgMTk2LCAyNDcsIDE5OCwgMjQzLCAxMjEsIDI0MywgMTMwLCAyNDMsIDEzOCwgMjQzLCAxNDUsIDI0MywgMTUzLAorMjQ3LCAyMjAsIDI0NCwgNzMsIDI0NCwgODIsIDI0NCwgOTAsIDI0NCwgOTksIDI0NCwgMTA4LCAxOTgsIDE5OSwgMjQ0LCAxMTcsCisyNDQsIDEyNCwgMjQ0LCAxMzUsIDI0NCwgMTQ1LCAyNDQsIDE1NSwgMjQ1LCA2OCwgMjQ1LCA3OCwgMjQ1LCA4OCwgMjQ1LCA5OCwKKzI0NSwgMTA4LCAyNDUsIDExOCwgMjQ1LCAxMjksIDI0NSwgMTM5LCAyNDUsIDE0OSwgMjQ1LCAxNTksIDI0NiwgNzIsIDI0NiwgODIsCisyNDYsIDkyLCAyNDYsIDEwMiwgMjQ2LCAxMTIsIDI0NiwgMTIyLCAyNDYsIDEzMywgMjQ2LCAxNDMsIDI0NiwgMTUzLCAyNDcsIDY2LAorMjQ3LCA3NiwgMjQ3LCA4NiwgMjQ3LCA5NiwgMjQ3LCAxMDYsIDI0NywgMTE2LCAyNDcsIDEyNiwgMjQ3LCAxMzMsIDI0NiwgMjE1LAorMjQ3LCAxNDEsIDI0NiwgMjI3LCAyNDcsIDE0NSwgMjQ2LCAyNDMsIDI0NywgMTUwLCAyNDYsIDI1MywgMjQ3LCAxNjcsIDE5MywgMjE5LAorMjQ4LCA2OSwgMjQ4LCA3OSwgMjQ4LCA4OSwgMjQ4LCA5OSwgMjQ4LCAxMDksIDI0OCwgMTE5LCAyNDgsIDEzMCwgMjQ4LCAxNDAsCisyNDgsIDE1MCwgMjQ4LCAxNjAsIDI0OSwgNzMsIDI0OSwgODMsIDI0OSwgOTMsIDI0OSwgMTAzLCAyNDksIDExMywgMjQ5LCAxMjMsCisyNDksIDEzNCwgMjQ5LCAxNDQsIDI0OSwgMTU0LCAyNTAsIDY3LCAyNTAsIDc3LCAyNTAsIDg3LCAyNTAsIDk3LCAyNTAsIDEwNywKKzI1MCwgMTE3LCAyNTAsIDEyOCwgMjUwLCAxMzgsIDI1MCwgMTQ4LCAyNTAsIDE1OCwgMjUxLCA3MSwgMjUxLCA4MSwgMjUxLCA5MSwKKzI0MCwgMTc3LCAyNDAsIDE4MiwgMjUxLCA5OCwgMjQwLCAxOTMsIDI1MSwgMTAxLCAyNDAsIDIwMywgMTg2LCAyMTUsIDI1MSwgMTEzLAorMjUxLCAxMjAsIDI0NywgMjI4LCAyNTEsIDEzNSwgMjUxLCAxNDMsIDI1MSwgMTUxLCAyNTEsIDE2MCwgMjQ0LCAyNDAsIDI0NywgMjI2LAorMjUyLCA4NywgMjUyLCA5MiwgMjQ3LCAyMzcsIDI1MiwgMTAzLCAyNTIsIDEwOSwgMjUyLCAxMTgsIDI1MiwgMTI1LCAxODIsIDE2NiwKKzI1MiwgMTQwLCAyNDcsIDI0NywgMjQ3LCAyNDgsIDI1MywgNjgsIDI1MywgNzMsIDI1MywgODIsIDI1MywgOTAsIDI1MywgMTAwLAorMjUzLCAxMTAsIDI1MywgMTIwLCAyNTMsIDEzMSwgMjQ2LCAxODIsIDI1MywgMTM5LCAxODUsIDE2OCwgMjUzLCAxNTQsIDE3MCwgMTYxLAorMTcwLCAxNzEsIDE3MCwgMTgxLCAxNzAsIDE5MSwgMTcwLCAyMDEsIDE3MCwgMjExLCAxNzAsIDIyMSwgMTcwLCAyMzEsIDE3MCwgMjQxLAorMTcwLCAyNTEsIDE3MSwgMTY3LCAxNzEsIDE3NywgMTcxLCAxODcsIDE3MSwgMTk3LCAxNzEsIDIwNywgMTcxLCAyMTcsIDE3MSwgMjI3LAorMTcxLCAyMzcsIDE3MSwgMjQ3LCAxNzIsIDE2MywgMTcyLCAxNzMsIDE3MiwgMTgzLCAxNzIsIDE5MywgMTcyLCAyMDMsIDE3MiwgMjEzLAorMTcyLCAyMjMsIDE3MiwgMjMzLCAxNzIsIDI0MywgMTcyLCAyNTMsIDE3MywgMTY5LCAxNzMsIDE3OSwgMTczLCAxODksIDE3MywgMTk5LAorMTczLCAyMDksIDE3MywgMjE5LCAxNzMsIDIyOSwgMTczLCAyMzksIDE3MywgMjQ5LCAxNzQsIDE2NSwgMTc0LCAxNzUsIDE3NCwgMTg1LAorMTc0LCAxOTUsIDE3NCwgMjA1LCAxNzQsIDIxNSwgMTc0LCAyMjUsIDE3NCwgMjM1LCAxNzQsIDI0NSwgMTc1LCAxNjEsIDE3NSwgMTcxLAorMTc1LCAxODEsIDE3NSwgMTkxLCAxNzUsIDIwMSwgMTc1LCAyMTEsIDE3NSwgMjIxLCAxNzUsIDIzMSwgMTc1LCAyNDEsIDE3NSwgMjUxLAorMjQ4LCAxNjcsIDI0OCwgMTc3LCAyNDgsIDE4NywgMjQ4LCAxOTcsIDI0OCwgMjA3LCAyNDgsIDIxNywgMjQ4LCAyMjcsIDI0OCwgMjM3LAorMjQ4LCAyNDcsIDI0OSwgMTYzLCAyNDksIDE3MywgMjQ5LCAxODMsIDI0OSwgMTkzLCAyNDksIDIwMywgMjQ5LCAyMTMsIDI0OSwgMjIzLAorMjQ5LCAyMzMsIDI0OSwgMjQzLCAyNDksIDI1MywgMjUwLCAxNjksIDI1MCwgMTc5LCAyNTAsIDE4OSwgMjUwLCAxOTksIDI1MCwgMjA5LAorMjUwLCAyMTksIDI1MCwgMjI5LCAyNTAsIDIzOSwgMjUwLCAyNDksIDI1MSwgMTY1LCAyNTEsIDE3NSwgMjUxLCAxODUsIDI1MSwgMTk1LAorMjUxLCAyMDUsIDI1MSwgMjE1LCAyNTEsIDIyNSwgMjUxLCAyMzUsIDI1MSwgMjQ1LCAyNTIsIDE2MSwgMjUyLCAxNzEsIDI1MiwgMTgxLAorMjUyLCAxOTEsIDI1MiwgMjAxLCAyNTIsIDIxMSwgMjUyLCAyMjEsIDI1MiwgMjMxLCAyNTIsIDI0MSwgMjUyLCAyNTEsIDI1MywgMTY3LAorMjUzLCAxNzcsIDI1MywgMTg3LCAyNTMsIDE5NywgMjUzLCAyMDcsIDI1MywgMjE3LCAyNTMsIDIyNywgMjUzLCAyMzcsIDI1MywgMjQ3LAorMjU0LCAxNjMsIDI1NCwgMTczLCAyNTQsIDE4MywgMjU0LCAxOTMsIDI1NCwgMjAzLCAyNTQsIDIxMywgMjU0LCAyMjMsIDI1NCwgMjMzLAorMjU0LCAyNDMsIDI1NCwgMjUzLCAxNjEsIDcyLCAxNjEsIDgyLCAxNjEsIDkyLCAxNjEsIDEwMiwgMTYxLCAxMTIsIDE2MSwgMTIyLAorMTYxLCAxMzMsIDE2MSwgMTQzLCAxNjEsIDE1MywgMTYyLCA2NiwgMTYyLCA3NiwgMTYyLCA4NiwgMTYyLCA5NiwgMTYyLCAxMDYsCisxNjIsIDExNiwgMTYyLCAxMjYsIDE2MiwgMTM3LCAxNjIsIDE0NywgMTYyLCAxNTcsIDE2MywgNzAsIDE2MywgODAsIDE2MywgOTAsCisxNjMsIDEwMCwgMTYzLCAxMTAsIDE2MywgMTIwLCAxNjMsIDEzMSwgMTYzLCAxNDEsIDE2MywgMTUxLCAxNjQsIDY0LCAxNjQsIDc0LAorMTY0LCA4NCwgMTY0LCA5NCwgMTY0LCAxMDQsIDE2NCwgMTE0LCAxNjQsIDEyNCwgMTY0LCAxMzUsIDE2NCwgMTQ1LCAxNjQsIDE1NSwKKzE2NSwgNjgsIDE2NSwgNzgsIDE2NSwgODgsIDE2NSwgOTgsIDE2NSwgMTA4LCAxNjUsIDExOCwgMTY1LCAxMjksIDE2NSwgMTM5LAorMTY1LCAxNDksIDE2NSwgMTU5LCAxNjYsIDcyLCAxNjYsIDgyLCAxNjYsIDkyLCAxNjYsIDEwMiwgMTY2LCAxMTIsIDE2NiwgMTIyLAorMTY2LCAxMzMsIDE2NiwgMTQzLCAxNjYsIDE1MywgMTY3LCA2NiwgMTY3LCA3NiwgMTY3LCA4NiwgMTY3LCA5NiwgMTY3LCAxMDYsCisxNjcsIDExNiwgMTY3LCAxMjYsIDE2NywgMTM3LCAxNjcsIDE0NywgMTY3LCAxNTcsIDE2MiwgMjI3LCAxNjQsIDI0OCwgMTY1LCAyNTAsCisxNjYsIDE5MCwgMTY2LCAyMzYsIDE2NiwgMjUzLCAxNjcsIDIwMiwgMTY3LCAyNDUsIDE2OCwgMTUwLCAxNjgsIDE2MCwgMTY4LCAyMzcsCisxNjgsIDI0NywgMTY5LCA5MywgMTY5LCAxNDQsIDE2OSwgMTU1LCAxNjksIDI0MSwgMTY5LCAyNTEsIDI1NCwgODEsIDI1NCwgOTEsCisyNTQsIDEwMSwgMjU0LCAxMTEsIDI1NCwgMTIxLCAyNTQsIDEzMiwgMjU0LCAxNDIsIDI1NCwgMTUyLCAyNTMsIDE1NiwgMjUzLCAxNTcsCisyNTMsIDE1OCwgMjUzLCAxNTksIDI1MywgMTYwLCAyNTQsIDY0LCAyNTQsIDcxLCAyNTQsIDc1LCAxNjksIDg1LCAxNjYsIDIyNywKKzE2NiwgMjM1LCAxNjksIDEwOSwgMTY5LCAxMTgsIDE2OSwgMTI5LCAxNjMsIDE2MSwgMTYzLCAxNzEsIDE2MywgMTgxLCAxNjMsIDE5MSwKKzE2MywgMjAxLCAxNjMsIDIxMSwgMTYzLCAyMjEsIDE2MywgMjMxLCAxNjMsIDI0MSwgMTYzLCAyNTEsIDE2MSwgMjMzLCAwCisgICAgICAgICAgICB9KTsKKworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X011bHRpQnl0ZV9JU09fMjAyMl9KUC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X011bHRpQnl0ZV9JU09fMjAyMl9KUC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI3ODljZTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX0lTT18yMDIyX0pQLmphdmEKQEAgLTAsMCArMSwzODEgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9NdWx0aUJ5dGVfSVNPXzIwMjJfSlAgZXh0ZW5kcyBPbGRDaGFyc2V0X0Fic3RyYWN0VGVzdCB7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyc2V0TmFtZSA9ICJJU08tMjAyMi1KUCI7CisKKyAgICAgICAgdGVzdENoYXJzID0gdGhlc2VDaGFycyhuZXcgaW50W117CiszMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKzQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCis4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKzk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorMTYyLCAxNjMsIDE2NSwgMTY3LCAxNjgsIDE3MiwgMTc2LCAxNzcsIDE4MCwgMTgyLCAyMTUsIDI0NywgOTEzLCA5MTQsIDkyNCwgOTM0LAorOTQ1LCA5NTUsIDk2NSwgMTAyNSwgMTA0MCwgMTA1MCwgMTA2MCwgMTA3MCwgMTA4MCwgMTA5MCwgMTEwMCwgODIwOCwgODIyMCwgODIzMCwgODI0MCwgODI1MSwKKzg0NTEsIDg0OTEsIDg1OTIsIDg2NTgsIDg3MDQsIDg3MTUsIDg3MzAsIDg3NDMsIDg3NTYsIDg3ODYsIDg4MDAsIDg4MTAsIDg4MzQsIDg4NjksIDg5NzgsIDk0NzIsCis5NDg0LCA5NDk1LCA5NTA3LCA5NTE5LCA5NTMxLCA5NTQ3LCA5NjMyLCA5NjUwLCA5NjYwLCA5NjcwLCA5NzExLCA5NzMzLCA5NzkyLCA5ODM0LCAxMjI4OCwgMTIyOTgsCisxMjMwOCwgMTIzNTMsIDEyMzYzLCAxMjM3MywgMTIzODMsIDEyMzkzLCAxMjQwMywgMTI0MTMsIDEyNDIzLCAxMjQzMywgMTI0NDMsIDEyNDUzLCAxMjQ2MywgMTI0NzMsIDEyNDgzLCAxMjQ5MywKKzEyNTAzLCAxMjUxMywgMTI1MjMsIDEyNTMzLCAxOTk2OCwgMTk5NzgsIDE5OTg4LCAxOTk5OCwgMjAwMTAsIDIwMDIyLCAyMDAzNCwgMjAwNDUsIDIwMDU1LCAyMDA2NiwgMjAwODEsIDIwMDk0LAorMjAxMDQsIDIwMTE0LCAyMDEyNCwgMjAxMzQsIDIwMTQ0LCAyMDE1NCwgMjAxNjQsIDIwMTc0LCAyMDE4NCwgMjAxOTUsIDIwMjA1LCAyMDIxNSwgMjAyMjUsIDIwMjM3LCAyMDI1MCwgMjAyNzEsCisyMDI4MiwgMjAyOTQsIDIwMzA0LCAyMDMxNCwgMjAzMjksIDIwMzM5LCAyMDM1MSwgMjAzNjMsIDIwMzc0LCAyMDM4NCwgMjAzOTUsIDIwNDA1LCAyMDQxNSwgMjA0MjYsIDIwNDM2LCAyMDQ0NywKKzIwNDYyLCAyMDQ3MiwgMjA0ODUsIDIwNDk1LCAyMDUwNSwgMjA1MTUsIDIwNTI1LCAyMDUzNywgMjA1NDcsIDIwNTU5LCAyMDU3MCwgMjA1ODEsIDIwNTk0LCAyMDYwNSwgMjA2MjEsIDIwNjMyLAorMjA2NTIsIDIwNjYzLCAyMDY3NCwgMjA2ODUsIDIwNjk4LCAyMDcwOSwgMjA3MjUsIDIwNzM2LCAyMDc1NCwgMjA3NjcsIDIwNzc4LCAyMDc5MSwgMjA4MDEsIDIwODExLCAyMDgyNiwgMjA4MzcsCisyMDg0OSwgMjA4NjAsIDIwODcwLCAyMDg4MCwgMjA4OTYsIDIwOTA2LCAyMDkxNiwgMjA5MzIsIDIwOTUwLCAyMDk2MCwgMjA5NzAsIDIwOTgxLCAyMDk5MiwgMjEwMDIsIDIxMDEyLCAyMTAyOCwKKzIxMDM4LCAyMTA0OCwgMjEwNTksIDIxMDY5LCAyMTA4MywgMjEwOTMsIDIxMTAzLCAyMTExNywgMjExMjcsIDIxMTM3LCAyMTE0NywgMjExNjEsIDIxMTcyLCAyMTE4MiwgMjExOTMsIDIxMjA1LAorMjEyMTUsIDIxMjM0LCAyMTI0NiwgMjEyNTYsIDIxMjY5LCAyMTI4MCwgMjEyOTAsIDIxMzA0LCAyMTMxNSwgMjEzMjUsIDIxMzM1LCAyMTM1MCwgMjEzNjAsIDIxMzcxLCAyMTM5OCwgMjE0MDgsCisyMTQyMSwgMjE0MzUsIDIxNDQ4LCAyMTQ2MCwgMjE0NzEsIDIxNDgxLCAyMTQ5MSwgMjE1MDUsIDIxNTE1LCAyMTUzMSwgMjE1NDIsIDIxNTU4LCAyMTU2OCwgMjE1NzgsIDIxNTk5LCAyMTYxMCwKKzIxNjIxLCAyMTYzMiwgMjE2NDMsIDIxNjY2LCAyMTY3NiwgMjE2ODgsIDIxNjk4LCAyMTcyMCwgMjE3MzAsIDIxNzQxLCAyMTc1NCwgMjE3NjQsIDIxNzc1LCAyMTgwNiwgMjE4MTYsIDIxODI4LAorMjE4MzksIDIxODUyLCAyMTg4MywgMjE4OTUsIDIxOTEyLCAyMTkyNywgMjE5NDIsIDIxOTU2LCAyMTk3MiwgMjE5ODMsIDIyMDA3LCAyMjAyMiwgMjIwMzYsIDIyMDU3LCAyMjA2OCwgMjIwODIsCisyMjA5MiwgMjIxMDcsIDIyMTIwLCAyMjEzMiwgMjIxNDQsIDIyMTU0LCAyMjE2NCwgMjIxNzYsIDIyMTkwLCAyMjIwNCwgMjIyMTYsIDIyMjI3LCAyMjIzOCwgMjIyNTQsIDIyMjY1LCAyMjI3NSwKKzIyMjg1LCAyMjI5NiwgMjIzMTAsIDIyMzIwLCAyMjMzMSwgMjIzNDMsIDIyMzUzLCAyMjM2OSwgMjIzOTksIDIyNDA5LCAyMjQxOSwgMjI0MzIsIDIyNDQyLCAyMjQ2NCwgMjI0NzUsIDIyNDg2LAorMjI0OTYsIDIyNTE2LCAyMjUyOCwgMjI1MzgsIDIyNTQ5LCAyMjU2MSwgMjI1NzUsIDIyNTg2LCAyMjYwMiwgMjI2MTIsIDIyNjIyLCAyMjYzMywgMjI2NDUsIDIyNjU5LCAyMjY3NSwgMjI2ODcsCisyMjY5OSwgMjI3MTIsIDIyNzI1LCAyMjczNywgMjI3NDgsIDIyNzYzLCAyMjc3NSwgMjI3ODYsIDIyNzk5LCAyMjgwOSwgMjI4MjEsIDIyODMzLCAyMjg0NiwgMjI4NTYsIDIyODY4LCAyMjg4MCwKKzIyODkwLCAyMjkwMCwgMjI5MTMsIDIyOTI1LCAyMjkzNywgMjI5NDcsIDIyOTYyLCAyMjk3NCwgMjI5ODUsIDIyOTk1LCAyMzAxMywgMjMwMzAsIDIzMDQxLCAyMzA1NywgMjMwNjgsIDIzMDgxLAorMjMwOTMsIDIzMTA0LCAyMzEzMCwgMjMxNDIsIDIzMTY3LCAyMzE4NiwgMjMyMjgsIDIzMjQxLCAyMzI1NCwgMjMyNjUsIDIzMjkwLCAyMzMwNSwgMjMzMTgsIDIzMzMwLCAyMzM0MCwgMjMzNTAsCisyMzM2MCwgMjMzNzYsIDIzMzg2LCAyMzM5NiwgMjM0MDgsIDIzNDE4LCAyMzQyOSwgMjM0MzksIDIzNDQ5LCAyMzQ1OSwgMjM0NzAsIDIzNDgwLCAyMzQ5MCwgMjM1MDAsIDIzNTE1LCAyMzUyNSwKKzIzNTM2LCAyMzU0NiwgMjM1NTYsIDIzNTY2LCAyMzU3OCwgMjM1ODgsIDIzNjAxLCAyMzYxMSwgMjM2MjEsIDIzNjMxLCAyMzY0NiwgMjM2NjAsIDIzNjcwLCAyMzY5MiwgMjM3MTMsIDIzNzIzLAorMjM3MzQsIDIzNzQ5LCAyMzc2OSwgMjM3ODQsIDIzNzk4LCAyMzgxNSwgMjM4MjUsIDIzODM1LCAyMzg0OSwgMjM4ODMsIDIzOTAwLCAyMzkxMywgMjM5MjMsIDIzOTM4LCAyMzk0OCwgMjM5NjUsCisyMzk4MCwgMjM5OTEsIDI0MDA5LCAyNDAxOSwgMjQwMjksIDI0MDM5LCAyNDA0OSwgMjQwNTksIDI0MDcwLCAyNDA4MSwgMjQwOTEsIDI0MTAxLCAyNDExMSwgMjQxMjUsIDI0MTM1LCAyNDE0OCwKKzI0MTU5LCAyNDE3OCwgMjQxODgsIDI0MTk5LCAyNDIxMywgMjQyMjQsIDI0MjM1LCAyNDI0NSwgMjQyNTcsIDI0MjcxLCAyNDI4MiwgMjQyOTYsIDI0MzA3LCAyNDMxOCwgMjQzMjksIDI0MzM5LAorMjQzNTEsIDI0MzYxLCAyNDM3MywgMjQzODUsIDI0Mzk2LCAyNDQwNiwgMjQ0MTcsIDI0NDI3LCAyNDQzOSwgMjQ0NDksIDI0NDU5LCAyNDQ3MSwgMjQ0ODEsIDI0NDkzLCAyNDUwNSwgMjQ1MTUsCisyNDUyNSwgMjQ1MzUsIDI0NTQ4LCAyNDU2MCwgMjQ1NzEsIDI0NTkwLCAyNDYwMSwgMjQ2MTMsIDI0NjIzLCAyNDYzNCwgMjQ2NDYsIDI0NjU2LCAyNDY2NiwgMjQ2NzYsIDI0Njg3LCAyNDcwNSwKKzI0NzE1LCAyNDcyNiwgMjQ3MzYsIDI0NzQ2LCAyNDc1NiwgMjQ3NzMsIDI0Nzg1LCAyNDc5NiwgMjQ4MDcsIDI0ODE3LCAyNDgyNywgMjQ4MzgsIDI0ODUzLCAyNDg2MywgMjQ4NzYsIDI0ODkyLAorMjQ5MDMsIDI0OTE1LCAyNDkyNSwgMjQ5MzUsIDI0OTQ1LCAyNDk1OCwgMjQ5NzAsIDI0OTgwLCAyNDk5NiwgMjUwMDYsIDI1MDE4LCAyNTAzMCwgMjUwNDAsIDI1MDU5LCAyNTA3NCwgMjUwODQsCisyNTA5NiwgMjUxMDYsIDI1MTE3LCAyNTEzMCwgMjUxNDAsIDI1MTUxLCAyNTE2MSwgMjUxNzEsIDI1MTgyLCAyNTE5MiwgMjUyMDYsIDI1MjE2LCAyNTIyNiwgMjUyMzYsIDI1MjQ2LCAyNTI1OSwKKzI1MjY5LCAyNTI4MiwgMjUyOTIsIDI1MzAzLCAyNTMxMywgMjUzMjQsIDI1MzM0LCAyNTM0NSwgMjUzNTYsIDI1MzY5LCAyNTM4MywgMjU0MDIsIDI1NDE3LCAyNTQyOSwgMjU0NDcsIDI1NDU4LAorMjU0NzIsIDI1NDg0LCAyNTQ5NCwgMjU1MDQsIDI1NTE0LCAyNTUyNCwgMjU1MzQsIDI1NTQ1LCAyNTU1OCwgMjU1NjksIDI1NTgyLCAyNTU5NCwgMjU2MDYsIDI1NjE5LCAyNTYzOCwgMjU2NTIsCisyNTY2MiwgMjU2NzgsIDI1Njg4LCAyNTcwMywgMjU3MTgsIDI1NzMxLCAyNTc0NiwgMjU3NTgsIDI1NzY5LCAyNTc4NSwgMjU3OTcsIDI1ODEwLCAyNTgyNCwgMjU4MzYsIDI1ODQ2LCAyNTg1NiwKKzI1ODgwLCAyNTg5MSwgMjU5MDMsIDI1OTEzLCAyNTkyNSwgMjU5MzUsIDI1OTQ1LCAyNTk1NSwgMjU5NjgsIDI1OTg2LCAyNTk5NiwgMjYwMDcsIDI2MDE3LCAyNjAyNywgMjYwMzksIDI2MDQ5LAorMjYwNTksIDI2MDcxLCAyNjA4MSwgMjYwOTIsIDI2MTA2LCAyNjExOCwgMjYxMzEsIDI2MTQzLCAyNjE1NywgMjYxNzIsIDI2MTg1LCAyNjIwNSwgMjYyMTUsIDI2MjI4LCAyNjI0MSwgMjYyNTQsCisyNjI2NCwgMjYyNzQsIDI2Mjg2LCAyNjI5NiwgMjYzMDgsIDI2MzI2LCAyNjMzNiwgMjYzNTIsIDI2MzY0LCAyNjM3NiwgMjYzODgsIDI2Mzk4LCAyNjQwOCwgMjY0MjAsIDI2NDMxLCAyNjQ0MSwKKzI2NDUxLCAyNjQ2MiwgMjY0NzQsIDI2NDg1LCAyNjQ5NSwgMjY1MDUsIDI2NTE3LCAyNjUyOCwgMjY1NDMsIDI2NTUzLCAyNjU2NCwgMjY1NzQsIDI2NTg0LCAyNjU5NCwgMjY2MDQsIDI2NjE5LAorMjY2NDMsIDI2NjU0LCAyNjY2NSwgMjY2NzYsIDI2Njg4LCAyNjcwMSwgMjY3MTMsIDI2NzIzLCAyNjc0MCwgMjY3NTAsIDI2NzY1LCAyNjc3NSwgMjY3ODYsIDI2Nzk3LCAyNjgwOSwgMjY4MjAsCisyNjgzNCwgMjY4NDcsIDI2ODYyLCAyNjg3MywgMjY4ODQsIDI2ODk0LCAyNjkwNSwgMjY5MTUsIDI2OTI4LCAyNjk0MSwgMjY5NTQsIDI2OTY0LCAyNjk3NCwgMjY5ODYsIDI2OTk2LCAyNzAwNiwKKzI3MDE4LCAyNzAyOCwgMjcwNDAsIDI3MDU0LCAyNzA2NywgMjcwNzksIDI3MDkxLCAyNzEwMSwgMjcxMTEsIDI3MTIyLCAyNzEzMywgMjcxNDYsIDI3MTU2LCAyNzE2NiwgMjcxNzcsIDI3MTg5LAorMjcyMDQsIDI3MjI0LCAyNzIzNCwgMjcyNTAsIDI3MjYzLCAyNzI3NywgMjcyODcsIDI3Mjk4LCAyNzMwOCwgMjczMjAsIDI3MzMwLCAyNzM0NSwgMjczNTUsIDI3MzY4LCAyNzM4NiwgMjczOTYsCisyNzQxMCwgMjc0MjEsIDI3NDMxLCAyNzQ0MiwgMjc0NTMsIDI3NDYzLCAyNzQ3NSwgMjc0ODcsIDI3NDk3LCAyNzUwNywgMjc1MTksIDI3NTI5LCAyNzU0MSwgMjc1NTYsIDI3NTY3LCAyNzU3OCwKKzI3NTg5LCAyNzYwMiwgMjc2MTUsIDI3NjI3LCAyNzY1NiwgMjc2NjcsIDI3NjgzLCAyNzcwMCwgMjc3MTAsIDI3NzI2LCAyNzczOCwgMjc3NTIsIDI3NzYyLCAyNzc3MywgMjc3ODQsIDI3Nzk0LAorMjc4MDksIDI3ODE5LCAyNzgzMiwgMjc4NDQsIDI3ODU5LCAyNzg2OSwgMjc4ODAsIDI3ODkxLCAyNzkxNSwgMjc5MjcsIDI3OTQxLCAyNzk1NCwgMjc5NjUsIDI3OTkzLCAyODAwMywgMjgwMTQsCisyODAyNCwgMjgwMzcsIDI4MDUxLCAyODA3OSwgMjgwOTIsIDI4MTAyLCAyODExMywgMjgxMjYsIDI4MTM2LCAyODE0NywgMjgxNjUsIDI4MTc5LCAyODE4OSwgMjgyMDEsIDI4MjE2LCAyODIyNywKKzI4MjM3LCAyODI0OCwgMjgyNjMsIDI4Mjc0LCAyODI4NiwgMjgzMDAsIDI4MzEwLCAyODMyMiwgMjgzMzUsIDI4MzQ2LCAyODM1NiwgMjgzNjksIDI4MzgxLCAyODM5NiwgMjg0MDcsIDI4NDE3LAorMjg0MzEsIDI4NDQ4LCAyODQ1OSwgMjg0NzIsIDI4NDg1LCAyODUwMCwgMjg1MTEsIDI4NTI1LCAyODUzNiwgMjg1NDYsIDI4NTU4LCAyODU3NywgMjg1OTMsIDI4NjA4LCAyODYyOCwgMjg2MzksCisyODY1MSwgMjg2NjIsIDI4NjczLCAyODY4MywgMjg2OTMsIDI4NzAzLCAyODcxNiwgMjg3MzQsIDI4NzQ4LCAyODc2MCwgMjg3NzEsIDI4NzgzLCAyODc5NiwgMjg4MDksIDI4ODI1LCAyODg0NCwKKzI4ODU2LCAyODg3MiwgMjg4ODksIDI4OTEzLCAyODkyNSwgMjg5MzcsIDI4OTQ4LCAyODk2MSwgMjg5ODIsIDI5MDAxLCAyOTAxMywgMjkwMjYsIDI5MDM2LCAyOTA1MywgMjkwNjQsIDI5MDc2LAorMjkwODcsIDI5MTAwLCAyOTExMywgMjkxMjMsIDI5MTM0LCAyOTE1MSwgMjkxNjQsIDI5MTc3LCAyOTE5MCwgMjkyMDAsIDI5MjExLCAyOTIyNCwgMjkyMzQsIDI5MjQ0LCAyOTI1NCwgMjkyNjYsCisyOTI3NywgMjkyODcsIDI5Mjk4LCAyOTMwOSwgMjkzMTksIDI5MzMwLCAyOTM0NCwgMjkzNTYsIDI5MzY2LCAyOTM3OCwgMjkzOTAsIDI5NDAxLCAyOTQxNywgMjk0MzEsIDI5NDUwLCAyOTQ2MiwKKzI5NDc3LCAyOTQ4NywgMjk1MDIsIDI5NTE4LCAyOTUzOSwgMjk1NTIsIDI5NTYyLCAyOTU3MiwgMjk1OTAsIDI5NjA5LCAyOTYxOSwgMjk2MzIsIDI5NjQyLCAyOTY2MiwgMjk2NzQsIDI5Njg4LAorMjk2OTksIDI5NzMwLCAyOTc0NiwgMjk3NTksIDI5NzgxLCAyOTc5MSwgMjk4MDEsIDI5ODExLCAyOTgyMiwgMjk4MzUsIDI5ODU0LCAyOTg3MiwgMjk4ODUsIDI5ODk4LCAyOTkwOCwgMjk5MjAsCisyOTkzNCwgMjk5NDQsIDI5OTU1LCAyOTk2NSwgMjk5NzYsIDI5OTg3LCAzMDAwMCwgMzAwMTAsIDMwMDIwLCAzMDAzMSwgMzAwNDEsIDMwMDUyLCAzMDA2NCwgMzAwNzksIDMwMDg5LCAzMDEwMCwKKzMwMTE1LCAzMDEyOSwgMzAxNDAsIDMwMTUxLCAzMDE2MiwgMzAxNzQsIDMwMTg1LCAzMDE5NSwgMzAyMDYsIDMwMjE3LCAzMDIzOSwgMzAyNTYsIDMwMjY3LCAzMDI3OCwgMzAyOTAsIDMwMzAwLAorMzAzMTEsIDMwMzIyLCAzMDMzMiwgMzAzNDIsIDMwMzUyLCAzMDM2MiwgMzAzODIsIDMwMzkyLCAzMDQwMiwgMzA0MTMsIDMwNDIzLCAzMDQzMywgMzA0NDYsIDMwNDU2LCAzMDQ2OCwgMzA0OTEsCiszMDUwMSwgMzA1MTksIDMwNTM1LCAzMDU1NCwgMzA1NjUsIDMwNTg1LCAzMDYwMywgMzA2MjIsIDMwNjM2LCAzMDY0NiwgMzA2NjMsIDMwNjc5LCAzMDY5MCwgMzA3MDEsIDMwNzE2LCAzMDczMiwKKzMwNzUyLCAzMDc3MCwgMzA3ODMsIDMwODEzLCAzMDgyNywgMzA4NDQsIDMwODU0LCAzMDg2NSwgMzA4ODMsIDMwODk1LCAzMDkwNiwgMzA5MTcsIDMwOTI4LCAzMDkzOCwgMzA5NTEsIDMwOTY0LAorMzA5NzcsIDMwOTkwLCAzMTAwMSwgMzEwMTQsIDMxMDM0LCAzMTA0NywgMzEwNTksIDMxMDY5LCAzMTA4MCwgMzEwOTUsIDMxMTA1LCAzMTExNywgMzExMzMsIDMxMTQzLCAzMTE1NSwgMzExNjUsCiszMTE3NywgMzExODksIDMxMTk5LCAzMTIwOSwgMzEyMjcsIDMxMjQwLCAzMTI1MiwgMzEyNjMsIDMxMjc4LCAzMTI5MSwgMzEzMDIsIDMxMzEyLCAzMTMyOSwgMzEzMzksIDMxMzUwLCAzMTM2MSwKKzMxMzc4LCAzMTM5MSwgMzE0MDEsIDMxNDE0LCAzMTQyNywgMzE0MzcsIDMxNDQ5LCAzMTQ1OSwgMzE0NjksIDMxNDgwLCAzMTQ5MCwgMzE1MDMsIDMxNTEzLCAzMTUyNSwgMzE1MzksIDMxNTU3LAorMzE1NjcsIDMxNTgxLCAzMTU5MSwgMzE2MDEsIDMxNjIyLCAzMTYzNCwgMzE2NDQsIDMxNjU4LCAzMTY2OCwgMzE2ODAsIDMxNjkxLCAzMTcwOSwgMzE3MjEsIDMxNzMxLCAzMTc0NCwgMzE3NTcsCiszMTc2NywgMzE3NzcsIDMxNzg3LCAzMTc5OSwgMzE4MTEsIDMxODIxLCAzMTgzMiwgMzE4NDQsIDMxODU5LCAzMTg3MCwgMzE4ODEsIDMxODkzLCAzMTkwMywgMzE5MTUsIDMxOTI5LCAzMTk0MSwKKzMxOTU0LCAzMTk2NCwgMzE5NzUsIDMxOTg2LCAzMTk5OCwgMzIwMTAsIDMyMDIwLCAzMjAzMiwgMzIwNDMsIDMyMDUzLCAzMjA2MywgMzIwNzUsIDMyMDg2LCAzMjA5NywgMzIxMTAsIDMyMTIxLAorMzIxMzcsIDMyMTQ3LCAzMjE1OSwgMzIxNzEsIDMyMTgxLCAzMjE5MSwgMzIyMDIsIDMyMjEzLCAzMjIyNCwgMzIyMzYsIDMyMjUxLCAzMjI2MSwgMzIyNzQsIDMyMjg2LCAzMjI5OSwgMzIzMDksCiszMjMyMSwgMzIzMzEsIDMyMzQxLCAzMjM1OCwgMzIzNjgsIDMyMzc5LCAzMjM5MiwgMzI0MDIsIDMyNDEyLCAzMjU2NiwgMzI1ODEsIDMyNTkyLCAzMjYwNywgMzI2MTcsIDMyNjI5LCAzMjY0MiwKKzMyNjUyLCAzMjY2NiwgMzI2NzYsIDMyNjg2LCAzMjY5NiwgMzI3MDksIDMyNzIyLCAzMjczNiwgMzI3NDcsIDMyNzYxLCAzMjc3MSwgMzI3ODQsIDMyNzk2LCAzMjgwOCwgMzI4MTksIDMyODI5LAorMzI4NDIsIDMyODU0LCAzMjg2NSwgMzI4NzksIDMyODg5LCAzMjkwMCwgMzI5MTUsIDMyOTI1LCAzMjkzNywgMzI5NDgsIDMyOTYzLCAzMjk3NCwgMzI5ODUsIDMyOTk2LCAzMzAwNywgMzMwMjAsCiszMzAzMCwgMzMwNTAsIDMzMDY1LCAzMzA3NSwgMzMwODYsIDMzMDk5LCAzMzEwOSwgMzMxMTksIDMzMTMxLCAzMzE0NCwgMzMxNTQsIDMzMTY3LCAzMzE3OCwgMzMxODgsIDMzMjAwLCAzMzIxMCwKKzMzMjIyLCAzMzIzMywgMzMyNDcsIDMzMjU4LCAzMzI2OCwgMzMyNzgsIDMzMjg4LCAzMzI5OCwgMzMzMDgsIDMzMzIxLCAzMzMzMSwgMzMzNDQsIDMzMzY4LCAzMzM3OCwgMzMzOTAsIDMzNDAwLAorMzM0MTksIDMzNDMzLCAzMzQ0NSwgMzM0NTUsIDMzNDY1LCAzMzQ3NywgMzM0ODksIDMzNDk5LCAzMzUwOSwgMzM1MjEsIDMzNTMxLCAzMzU0MSwgMzM1NTgsIDMzNTcxLCAzMzU4MywgMzM1OTMsCiszMzYwNSwgMzM2MTUsIDMzNjUxLCAzMzY2OSwgMzM2ODMsIDMzNjk0LCAzMzcwNCwgMzM3MTcsIDMzNzI5LCAzMzc0MCwgMzM3NTAsIDMzNzYwLCAzMzc3MSwgMzM3ODMsIDMzNzk1LCAzMzgwNSwKKzMzODI0LCAzMzgzNCwgMzM4NDUsIDMzODYyLCAzMzg3OSwgMzM4ODksIDMzODk5LCAzMzkwOSwgMzM5MjIsIDMzOTM2LCAzMzk0OCwgMzM5NjUsIDMzOTc2LCAzMzk4OCwgMzQwMDAsIDM0MDEwLAorMzQwMjgsIDM0MDQ0LCAzNDA1NCwgMzQwNjUsIDM0MDc5LCAzNDA5MiwgMzQxMDksIDM0MTIwLCAzNDEzMywgMzQxNDcsIDM0MTU3LCAzNDE2NywgMzQxODAsIDM0MTkyLCAzNDIwMywgMzQyMTQsCiszNDIzMywgMzQyNDksIDM0MjYxLCAzNDI3NiwgMzQyOTUsIDM0MzA2LCAzNDMyMywgMzQzMzgsIDM0MzQ5LCAzNDM2NywgMzQzODEsIDM0Mzk0LCAzNDQwNywgMzQ0MTcsIDM0NDI3LCAzNDQ0MiwKKzM0NDUzLCAzNDQ2NywgMzQ0NzksIDM0NTAwLCAzNDUxMCwgMzQ1MjEsIDM0NTMyLCAzNDU0MiwgMzQ1NTIsIDM0NTYyLCAzNDU3MywgMzQ1ODQsIDM0NTk3LCAzNDYxMiwgMzQ2MjMsIDM0NjMzLAorMzQ2NDMsIDM0NjU1LCAzNDY2NiwgMzQ2NzYsIDM0Njg3LCAzNDcwMSwgMzQ3MTksIDM0NzMxLCAzNDc0NiwgMzQ3NTYsIDM0NzY4LCAzNDc4NCwgMzQ3OTksIDM0ODA5LCAzNDgyMSwgMzQ4MzEsCiszNDg0OSwgMzQ4NjUsIDM0ODc1LCAzNDg4NiwgMzQ4OTgsIDM0OTA5LCAzNDkyMCwgMzQ5MzAsIDM0OTQxLCAzNDk1MiwgMzQ5NjIsIDM0OTc0LCAzNDk4NywgMzQ5OTcsIDM1MDA3LCAzNTAyMywKKzM1MDMzLCAzNTA0OCwgMzUwNTgsIDM1MDY4LCAzNTA3OSwgMzUwOTAsIDM1MTAxLCAzNTExNCwgMzUxMjYsIDM1MTM3LCAzNTE0OCwgMzUxNTgsIDM1MTY4LCAzNTE3OCwgMzUxODgsIDM1MTk4LAorMzUyMDgsIDM1MjE5LCAzNTIzMywgMzUyNDQsIDM1MjU4LCAzNTI4MiwgMzUyOTIsIDM1MzAyLCAzNTMxNiwgMzUzMjgsIDM1MzM4LCAzNTM1MCwgMzUzNjMsIDM1MzczLCAzNTM4NiwgMzUzOTgsCiszNTQwOCwgMzU0MTksIDM1NDMwLCAzNTQ0MCwgMzU0NTIsIDM1NDYzLCAzNTQ3MywgMzU0ODYsIDM1NDk2LCAzNTUwNiwgMzU1MTYsIDM1NTI3LCAzNTUzOCwgMzU1NDgsIDM1NTU4LCAzNTU2OSwKKzM1NTgyLCAzNTU5NiwgMzU2MDYsIDM1NjE2LCAzNTYyNywgMzU2NDEsIDM1NjU3LCAzNTY3MCwgMzU2ODYsIDM1Njk2LCAzNTcwOSwgMzU3MjIsIDM1NzM0LCAzNTg5NSwgMzU5MDUsIDM1OTE2LAorMzU5MzAsIDM1OTQ2LCAzNTk2MCwgMzU5NzAsIDM1OTgwLCAzNTk5MiwgMzYwMDIsIDM2MDEyLCAzNjAyMiwgMzYwMzIsIDM2MDQyLCAzNjA1OCwgMzYwNjgsIDM2MDkwLCAzNjEwMCwgMzYxMTEsCiszNjE5NiwgMzYyMDgsIDM2MjI1LCAzNjI0OSwgMzYyNTksIDM2Mjc1LCAzNjI4NiwgMzYyOTksIDM2MzEwLCAzNjMyMSwgMzYzMzEsIDM2MzQxLCAzNjM1MSwgMzYzNjEsIDM2MzgxLCAzNjM5NCwKKzM2NDA0LCAzNjQxOCwgMzY0MjgsIDM2NDQxLCAzNjQ1MSwgMzY0NjYsIDM2NDc2LCAzNjQ4NywgMzY0OTcsIDM2NTEzLCAzNjUyMywgMzY1NDIsIDM2NTUyLCAzNjU2MiwgMzY1NzUsIDM2NTg3LAorMzY2MDAsIDM2NjExLCAzNjYyNiwgMzY2MzYsIDM2NjQ2LCAzNjY1OSwgMzY2NzAsIDM2NjgxLCAzNjY5NSwgMzY3MDUsIDM2NzYzLCAzNjc3NSwgMzY3ODUsIDM2Nzk1LCAzNjgwNSwgMzY4MTcsCiszNjgzNCwgMzY4NDUsIDM2ODU1LCAzNjg2NSwgMzY4NzUsIDM2ODg1LCAzNjg5NSwgMzY5MTAsIDM2OTIwLCAzNjkzMCwgMzY5NDEsIDM2OTUyLCAzNjk2MywgMzY5NzMsIDM2OTgzLCAzNjk5MywKKzM3MDA3LCAzNzAyNywgMzcwMzksIDM3MDU3LCAzNzA3MCwgMzcwODMsIDM3MDk2LCAzNzEwOSwgMzcxMjIsIDM3MTM4LCAzNzE2NSwgMzcxOTMsIDM3MjA0LCAzNzIxOCwgMzcyMjgsIDM3MjM5LAorMzcyNTAsIDM3MjYxLCAzNzI3MSwgMzcyODIsIDM3Mjk1LCAzNzMwNiwgMzczMTgsIDM3MzI4LCAzNzMzOSwgMzczNTAsIDM3MzY1LCAzNzM3NSwgMzczODksIDM3NDA2LCAzNzQxNywgMzc0MjgsCiszNzQzOSwgMzc0NDksIDM3NDYzLCAzNzQ3NCwgMzc0ODksIDM3NTAyLCAzNzUyMSwgMzc1MzEsIDM3NTQ5LCAzNzU1OSwgMzc1ODMsIDM3NjA0LCAzNzYxOCwgMzc2MjgsIDM3NjM4LCAzNzY0OCwKKzM3NjU4LCAzNzY3MCwgMzc2ODIsIDM3NzAwLCAzNzcxNiwgMzc3MjgsIDM3NzQwLCAzNzc1NiwgMzc3NzIsIDM3NzgyLCAzNzc5OSwgMzc4MTcsIDM3ODI3LCAzNzg0MCwgMzc4NTMsIDM3ODY0LAorMzc4OTEsIDM3OTA0LCAzNzkxNCwgMzc5MzEsIDM3OTQxLCAzNzk1MywgMzc5NjksIDM3OTc5LCAzNzk5NCwgMzgwMDUsIDM4MDE1LCAzODI2MywgMzgyNzQsIDM4Mjg3LCAzODI5NywgMzgzMDcsCiszODMxNywgMzgzMjksIDM4MzM5LCAzODM0OSwgMzgzNjAsIDM4MzcwLCAzODQyOCwgMzg0NDAsIDM4NDUwLCAzODQ2MywgMzg0NzUsIDM4NDkxLCAzODUwMSwgMzg1MTIsIDM4NTIyLCAzODUzMywKKzM4NTQzLCAzODU1MywgMzg1NjMsIDM4NTc2LCAzODU4NywgMzg1OTcsIDM4NjA5LCAzODYxOSwgMzg2MzIsIDM4NjQyLCAzODY1NiwgMzg2NjYsIDM4Njc4LCAzODY5MiwgMzg3MDQsIDM4NzE3LAorMzg3MjgsIDM4NzM4LCAzODc0OCwgMzg3NTgsIDM4NzY5LCAzODc4MCwgMzg3OTAsIDM4ODAwLCAzODgxMiwgMzg4MjIsIDM4ODM1LCAzODg1MSwgMzg4NjcsIDM4ODkzLCAzODkwNywgMzg5MTcsCiszODkyNywgMzg5MzgsIDM4OTQ4LCAzODk2NCwgMzg5ODIsIDM4OTk2LCAzOTAwNiwgMzkwMTksIDM5MDgwLCAzOTA5NCwgMzkxMDcsIDM5MTMxLCAzOTE0NSwgMzkxNTYsIDM5MTY2LCAzOTE3NywKKzM5MTg3LCAzOTE5NywgMzkyMDgsIDM5MjI5LCAzOTI0MSwgMzkyNTMsIDM5MzE4LCAzOTMzMywgMzkzNDcsIDM5MzYxLCAzOTM3NiwgMzkzODcsIDM5NDA1LCAzOTQxNiwgMzk0MjksIDM5NDM5LAorMzk0NDksIDM5NDY0LCAzOTQ3OSwgMzk0OTAsIDM5NTAxLCAzOTUxMSwgMzk1MjIsIDM5NTkyLCAzOTYwOCwgMzk2MjAsIDM5NjMxLCAzOTY0NiwgMzk2NTgsIDM5NjY4LCAzOTY4NiwgMzk3MDQsCiszOTcxNCwgMzk3MjYsIDM5NzM5LCAzOTc0OSwgMzk3NTksIDM5NzcwLCAzOTc5MSwgMzk4MTEsIDM5ODIyLCAzOTgzOSwgMzk4NTAsIDM5ODYwLCAzOTg3MiwgMzk4ODIsIDM5ODkyLCAzOTkwNSwKKzM5OTIwLCAzOTk0MCwgMzk5NTIsIDM5OTYzLCAzOTk3MywgMzk5ODMsIDM5OTkzLCA0MDAwNiwgNDAwMTgsIDQwMDMyLCA0MDA1NCwgNDAxNjUsIDQwMTc2LCA0MDE5NSwgNDAyMDYsIDQwMjE5LAorNDAyMzAsIDQwMjUxLCA0MDI2MiwgNDAyNzIsIDQwMjg0LCA0MDMwMCwgNDAzMTQsIDQwMzI3LCA0MDM0NiwgNDAzNTYsIDQwMzY3LCA0MDM3OCwgNDAzODgsIDQwMzk5LCA0MDQwOSwgNDA0MjIsCis0MDQzNCwgNDA0NDUsIDQwNDc0LCA0MDU2NSwgNDA1NzUsIDQwNTg3LCA0MDU5NywgNDA2MDcsIDQwNjE3LCA0MDYzMiwgNDA2NDQsIDQwNjU0LCA0MDY2NCwgNDA2NzcsIDQwNjg3LCA0MDY5NywKKzQwNzExLCA0MDcyMywgNDA3MzYsIDQwNzQ4LCA0MDc2MywgNDA3NzgsIDQwNzg4LCA0MDc5OSwgNDA4MTAsIDQwODIyLCA0MDg0NSwgNDA4NjAsIDY1MjgxLCA2NTI5MSwgNjUzMDEsIDY1MzExLAorNjUzMjEsIDY1MzMxLCA2NTM0MSwgNjUzNTEsIDY1MzYxLCA2NTM3MSwgNjUzODEsIDY1MzkxLCA2NTQwMSwgNjU0MTEsIDY1NDIxLCA2NTQzMSwgNjU1MDcKKyAgICAgICAgICAgIH0pOworCisgICAgICAgIHRlc3RCeXRlcyA9IHRoZXNlQnl0ZXMobmV3IGludFtdeworMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCis0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKzY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCis5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKzExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKzI3LCAzNiwgNjYsIDMzLCAxMTMsIDMzLCAxMTQsIDI3LCA0MCwgNzQsIDkyLCAyNywgMzYsIDY2LCAzMywgMTIwLAorMzMsIDQ3LCAzNCwgNzYsIDMzLCAxMDcsIDMzLCA5NCwgMzMsIDQ1LCAzNCwgMTIxLCAzMywgOTUsIDMzLCA5NiwKKzM4LCAzMywgMzgsIDM0LCAzOCwgNDQsIDM4LCA1MywgMzgsIDY1LCAzOCwgNzUsIDM4LCA4NCwgMzksIDM5LAorMzksIDMzLCAzOSwgNDQsIDM5LCA1NCwgMzksIDY0LCAzOSwgOTAsIDM5LCAxMDAsIDM5LCAxMTAsIDMzLCA2MiwKKzMzLCA3MiwgMzMsIDY4LCAzNCwgMTE1LCAzNCwgNDAsIDMzLCAxMTAsIDM0LCAxMTQsIDM0LCA0MywgMzQsIDc3LAorMzQsIDc5LCAzNCwgNTksIDM0LCAxMDEsIDM0LCA3NCwgMzMsIDEwNCwgMzQsIDk4LCAzMywgOTgsIDM0LCA5OSwKKzM0LCA2MiwgMzQsIDkzLCAzNCwgOTQsIDQwLCAzMywgNDAsIDM1LCA0MCwgNDksIDQwLCA1MCwgNDAsIDU2LAorNDAsIDUzLCA0MCwgNTQsIDM0LCAzNSwgMzQsIDM3LCAzNCwgMzksIDM0LCAzMywgMzQsIDEyNiwgMzMsIDEyMiwKKzMzLCAxMDYsIDM0LCAxMTgsIDMzLCAzMywgMzMsIDg0LCAzMywgNzYsIDM2LCAzMywgMzYsIDQzLCAzNiwgNTMsCiszNiwgNjMsIDM2LCA3MywgMzYsIDgzLCAzNiwgOTMsIDM2LCAxMDMsIDM2LCAxMTMsIDMzLCA0MywgMzcsIDM3LAorMzcsIDQ3LCAzNywgNTcsIDM3LCA2NywgMzcsIDc3LCAzNywgODcsIDM3LCA5NywgMzcsIDEwNywgMzcsIDExNywKKzQ4LCAxMDgsIDYyLCAxMDEsIDUxLCAxMTAsIDYyLCAxMDMsIDgwLCAzNiwgODAsIDM4LCA4MCwgNDEsIDcwLCA5OSwKKzYyLCAxMDQsIDg2LCAzOCwgNzcsIDExMiwgNTIsIDM3LCA3NywgNjEsIDU2LCA5NSwgNDgsIDMzLCA3NSwgMTE0LAorODAsIDU1LCA2MywgNzcsIDgwLCA2MCwgODAsIDU4LCA3MywgODUsIDY2LCAxMDEsIDgwLCA2NSwgODAsIDY3LAorNTIsIDEwNywgNTYsIDk2LCA1MCwgMTEzLCA3MSwgMTA4LCA1OSwgNzEsIDY3LCAzNCwgNTgsIDUyLCA4MCwgNjksCis4MCwgODAsIDUwLCA2NiwgNTksIDcyLCA3OCwgOTksIDgwLCA4NSwgNTQsIDM0LCA4NSwgMzcsIDYzLCA0NywKKzc0LCA4OCwgNjEsIDgzLCA4MCwgODcsIDgwLCA4OCwgNjEsIDM2LCA3NCwgMTEyLCA4MCwgMTAyLCA5NiwgNzEsCis1NiwgMTE3LCA3NCwgMTExLCA3OSwgNjUsIDU1LCAxMTIsIDgwLCAxMTIsIDc0LCA4MCwgODAsIDExOCwgNTUsIDExNCwKKzYwLCA2OSwgNTMsIDU0LCA3NSwgNTMsIDU5LCA0OSwgNTgsIDY5LCA2MSwgMTI1LCA4MSwgMzYsIDcwLCA0NywKKzc4LCA2MSwgODEsIDM5LCA4MSwgNDQsIDUzLCA1NSwgNjAsIDExNiwgNjEsIDEyNiwgNzcsIDM3LCA4MSwgNTQsCis0OCwgMTE2LCA1NywgMTEwLCA2OSwgOTQsIDcwLCAxMjYsIDU0LCAzOCwgNTUsIDExNSwgNDksIDk1LCAxMDIsIDExMCwKKzUyLCAzOSwgODEsIDgxLCA1OCwgOTksIDY0LCA0MCwgODIsIDY5LCA4MSwgOTIsIDcwLCAxMDAsIDgxLCA5NywKKzY5LCA5NywgNTIsIDQxLCA4MSwgMTAxLCA3MiwgNjEsIDgxLCAxMDUsIDU1LCAxMTYsIDY4LCAxMDIsIDY1LCA0OCwKKzU3LCAxMDAsIDcxLCAxMDksIDczLCAxMjMsIDgxLCAxMTksIDU1LCA5NiwgODEsIDEyNSwgNzgsIDc5LCA2MSwgMTE3LAorNzksIDQzLCA1MSwgNDcsIDc0LCA4OSwgNzAsIDQ4LCA3NCwgMTAzLCA1NSwgNDYsIDU2LCAxMjMsIDgyLCA1MSwKKzgyLCA1NiwgNjIsIDM0LCA3MiwgOTEsIDgyLCA2MiwgNjQsIDEwNSwgODIsIDY4LCA3MCwgMTEwLCA1NSwgNTMsCis0OCwgMTE3LCA4MiwgNzQsIDgyLCA3NywgODIsIDc4LCA0OSwgOTQsIDUzLCAxMTAsIDc1LCAxMTYsIDYxLCA3MSwKKzgyLCA4NywgNjcsIDMzLCA0OSwgMzgsIDgyLCA5NCwgNDksIDM3LCA1NSwgNDcsIDcyLCA5MywgODIsIDEwMSwKKzgyLCA5NiwgNTcsIDExMiwgODIsIDEwOCwgNjAsIDExOCwgODIsIDEwNiwgODIsIDExNCwgNTgsIDExMiwgODIsIDEyMCwKKzgyLCAxMjMsIDgyLCAxMjEsIDgzLCAzNCwgODMsIDM4LCA4MywgNDcsIDgzLCA0NSwgODMsIDQ2LCA0OSwgNTIsCis4MywgNDEsIDgzLCA1MiwgODMsIDU3LCA2NiwgMTExLCA3NiwgMTAwLCA4MywgNTMsIDgzLCA2NSwgODMsIDczLAorODMsIDY3LCA1NSwgMTE4LCA0OSwgNjgsIDgzLCA3OCwgODMsIDgxLCA4MywgNzcsIDgzLCA4MywgNjcsIDUwLAorODMsIDgyLCA1MCwgOTQsIDgzLCA5MiwgNDksIDYxLCA2NSwgNTcsIDUxLCAxMjIsIDUyLCAxMTEsIDc0LCA0NiwKKzgzLCAxMDIsIDgzLCAxMDMsIDgzLCAxMDUsIDgzLCAxMDQsIDgzLCAxMDgsIDgzLCAxMTIsIDgzLCAxMTYsIDgzLCAxMTksCis1MCwgMTE1LCA4MywgMTIxLCA4MywgMTIyLCA3NCwgOTYsIDg0LCAzNSwgODQsIDM3LCA4NCwgNDEsIDY3LCA3OSwKKzg0LCA0NSwgNTQsIDgxLCA1NywgMzUsIDg0LCA1MSwgODQsIDUyLCA4NCwgNTMsIDg0LCA1NCwgODQsIDU1LAorODQsIDU4LCA4NCwgNDksIDc1LCAxMDAsIDg0LCA2NiwgNzMsIDg2LCA2MiwgMTI1LCA3NSwgODksIDg0LCA2NSwKKzY2LCA2OCwgODQsIDcyLCAxMTYsIDMzLCA1OCwgMTAyLCA1MCwgMTE2LCA2OSwgOTksIDU4LCA3MywgNDksIDExOCwKKzYzLCA4MCwgNTQsIDQ1LCA3NCwgMTA0LCA4NCwgODIsIDg0LCA4MywgODQsIDg3LCA4NCwgODksIDg0LCA5MSwKKzg0LCA5NiwgNTksIDc4LCA2OCwgOTEsIDg0LCAxMDUsIDUwLCA3MCwgNjEsIDcyLCA4NCwgMTEwLCA2MCwgNTgsCis4NCwgMTE1LCA3MCwgOTYsIDc1LCA5MSwgODQsIDEyMywgNjcsIDM3LCA2OSwgOTEsIDg1LCAzNCwgODUsIDQzLAorNzYsIDQ3LCA4NSwgMzgsIDg1LCAzOSwgNjIsIDQyLCA1OSwgODAsIDY0LCA0MywgNDksIDU2LCA0OCwgNDAsCis0OCwgODIsIDg1LCA0OCwgODUsIDQ5LCA3NCwgOTAsIDg1LCA1NSwgODUsIDUyLCA1OCwgMzksIDczLCA4OCwKKzc2LCA1OSwgNzEsIDk0LCA4NSwgNjAsIDYwLCA1OSwgODUsIDY5LCA2NywgMTAwLCA4NSwgNzAsIDUyLCAxMTQsCis4NSwgNzQsIDYyLCAxMTAsIDY4LCA5MiwgODUsIDc4LCA4NSwgODIsIDU5LCA4MiwgODUsIDg1LCA1NiwgNzMsCis4NSwgODksIDg1LCA5NCwgNjYsIDExMiwgNTcsIDQwLCA2NywgMTA0LCA2NCwgMTA3LCA1MywgOTIsIDg1LCA5OCwKKzYwLCAxMDAsIDczLCA4OSwgNTIsIDUwLCA4NSwgMTA4LCA4NSwgMTEwLCA1OSwgMTIzLCA2MCwgNzcsIDcwLCA1MSwKKzYyLCA0OCwgNzYsIDk2LCA2MSwgMzQsIDYzLCA0NCwgNTMsIDExMSwgODYsIDM0LCA2NiwgNDgsIDg2LCAzNiwKKzg2LCAzOSwgODYsIDQxLCA1MCwgNDQsIDg2LCA0NSwgODYsIDQ3LCA4NiwgNTAsIDg2LCA1MywgNTAsIDEwMSwKKzY5LCAxMDMsIDYzLCAxMTQsIDg2LCA2NiwgODYsIDY1LCA3NCwgMTIwLCA4NiwgNzUsIDg2LCA2MywgNjMsIDExNSwKKzg2LCA3NywgODYsIDgxLCA4NiwgNTgsIDg2LCA4MywgODYsIDg0LCA4NiwgODgsIDg2LCA5MCwgODYsIDkyLAorNjQsIDExMCwgNTcsIDQyLCA1NiwgNzQsIDUyLCA0NCwgNzIsIDY1LCA4NiwgMTAyLCA4NiwgMTAzLCA2MywgOTksCis2NiwgODMsIDc1LCA1NywgODYsIDExNSwgODYsIDExMSwgODYsIDExMiwgNTIsIDUxLCA3NywgNjgsIDcyLCA5NSwKKzY4LCAxMDgsIDg2LCAxMjEsIDU2LCA3NSwgNDgsIDY3LCA4NiwgMTIyLCA4NiwgMTI2LCA4NywgMzYsIDg3LCA0MCwKKzg3LCA0NCwgODcsIDQ4LCA4NywgNTAsIDUzLCA5MywgNjgsIDExMSwgODcsIDU2LCA2OCwgMzcsIDg3LCA1OSwKKzg3LCA2MSwgODcsIDY1LCA4NywgNjgsIDY4LCAzOCwgODcsIDcxLCA2NCwgNDQsIDc4LCAzOSwgNzAsIDY0LAorNTYsIDEwMiwgODcsIDg0LCA2OSwgNDgsIDYzLCA1MiwgNzEsIDM4LCA1OSwgODYsIDg3LCA4OCwgODgsIDQ1LAorODcsIDg3LCA4NywgOTksIDg3LCA5NiwgNTMsIDk0LCA1NCwgNDksIDg3LCAxMDYsIDg3LCAxMTMsIDU0LCA1MCwKKzg3LCAxMDcsIDg3LCAxMTcsIDY2LCA0MSwgODcsIDEyMiwgODgsIDM5LCA4OCwgMzUsIDc3LCA0MiwgNDgsIDQ1LAorODgsIDQ0LCA2MiwgMTEyLCA3OSwgNzEsIDY0LCA3NSwgODcsIDEyNCwgODgsIDYxLCA4OCwgNjAsIDg4LCA1MiwKKzg4LCA1MSwgNTIsIDU0LCA4OCwgNzEsIDg4LCA3MCwgODgsIDY0LCA4OCwgODgsIDg4LCA4NywgNTUsIDY5LAorODgsIDg1LCA3NywgOTMsIDg4LCA5NiwgODgsIDk0LCA3NCwgNDgsIDg4LCA5OSwgODgsIDEwNywgODgsIDEwNiwKKzUwLCAxMjMsIDg4LCAxMTIsIDY4LCA0MCwgODgsIDExOCwgODgsIDEyMSwgNTAsIDEyNCwgMTA4LCA2NywgODksIDM1LAorNjYsIDg3LCA3NSwgNjAsIDcyLCA5OCwgNjYsIDcxLCA4OSwgNDIsIDg5LCA0NiwgNzMsIDk0LCA1MywgNTksCis3MSwgNjgsIDg5LCA1NiwgNjYsIDExNCwgNzIsIDEwMCwgNjgsIDExMywgODksIDY4LCA4OSwgNjYsIDg5LCA1NywKKzUxLCA3MiwgNTEsIDEwMywgNTksIDM0LCA1OSwgMTI1LCA4OSwgNzIsIDUzLCAxMTUsIDg5LCA3NSwgNjgsIDExNCwKKzY2LCA0MiwgNzQsIDk3LCA3NCwgMTIzLCA1NSwgMTI2LCA4OSwgODcsIDYyLCA1NiwgODksIDg1LCA3OCwgNDMsCis2NSwgNjAsIDY4LCA3OSwgODksIDk3LCA4OSwgMTAyLCA3NywgNDQsIDQ4LCA0NiwgNTIsIDEyMCwgNzcsIDczLAorODksIDEwOCwgODksIDEwOSwgODksIDExMCwgODksIDEwNywgNTgsIDExMywgODksIDExOSwgNjksIDM4LCA4OSwgMTE2LAorODksIDExOCwgNTUsIDk4LCA1OSwgNTMsIDcwLCA1MywgODksIDEyNCwgNTEsIDczLCA5MCwgMzUsIDkwLCAzNCwKKzkwLCA0MywgNTMsIDYwLCA5MCwgNDksIDkwLCA1MywgOTAsIDU1LCA5MCwgNTksIDU5LCA4OSwgNTAsIDEyNiwKKzU2LCA3OCwgNzMsIDgyLCA1NCwgNTMsIDU5LCA1NCwgNjMsIDExNiwgOTAsIDc2LCA3MywgNzYsIDY5LCA3NywKKzQ4LCA1NCwgOTAsIDgxLCA5MCwgODIsIDkwLCA4NSwgNjQsIDEyMywgNTIsIDEyMiwgOTAsIDkyLCA2MSwgOTIsCis1MCwgMzQsIDU4LCA0MywgNDgsIDg3LCA2NCwgNDksIDYyLCA2MCwgNjcsIDEwNywgOTAsIDEwNSwgOTAsIDEwOCwKKzkwLCAxMTAsIDY0LCA1MCwgNTQsIDcxLCA5MCwgMTE3LCA5MCwgMTIwLCA2OCwgNDIsIDc0LCAxMDcsIDkxLCAzNCwKKzkxLCAzMywgOTEsIDM1LCA5MSwgMzcsIDkxLCA0MSwgODIsIDg4LCA1NSwgMTEwLCA1OCwgMTE1LCA5MSwgNDYsCis3NiwgOTAsIDc1LCA4MSwgOTEsIDUxLCA2MywgMTIxLCA2MCwgOTMsIDkxLCA1NywgOTEsIDY2LCA1MywgNzksCis3MiwgNjgsIDkxLCA2MiwgNzUsIDEwOSwgNzksIDcyLCA1NiwgNzksIDkxLCA4NCwgNzQsIDY1LCA5MSwgODUsCis2OCwgODMsIDkxLCA4MiwgOTEsIDc1LCA1OCwgNTgsIDY0LCAxMTQsIDkxLCA4OSwgOTEsIDkxLCA2NCwgMTE1LAorOTEsIDkyLCA5MSwgOTMsIDkxLCA5OCwgOTEsIDk5LCA5MSwgMTExLCA5MSwgMTE3LCA5MSwgMTE2LCA1NywgNjAsCis2MiwgNjMsIDkxLCAxMDQsIDkxLCAxMTAsIDUyLCAxMjYsIDc1LCA2NCwgNjksIDExMSwgNjMsIDU3LCA5MiwgNDIsCis5MiwgMzgsIDY4LCA3MSwgNjMsIDEyMiwgOTIsIDQ4LCA5MiwgNjMsIDkyLCA2MSwgNzcsIDc2LCA5MiwgNTYsCis5MiwgNjUsIDkyLCA2OCwgOTIsIDYwLCA5MiwgNTcsIDU4LCAxMDMsIDc5LCA0OSwgOTIsIDg1LCA5MiwgNzAsCis5MiwgODAsIDExNiwgMzQsIDkyLCA3NCwgOTIsIDc5LCA5MiwgOTcsIDkyLCA5NiwgNjUsIDEwMSwgOTIsIDEwNCwKKzkyLCAxMDIsIDkyLCAxMDAsIDU2LCAzNCwgNjIsIDY1LCA5MiwgMTA5LCA1MywgNzYsIDkyLCAxMTUsIDkyLCAxMTEsCis1MSwgOTYsIDkyLCAxMjIsIDkzLCAzMywgOTIsIDEyNSwgOTMsIDQwLCA5MywgMzgsIDkzLCAzNywgOTMsIDQyLAorNTQsIDEyMywgNzIsIDM5LCA5MywgNTAsIDc3LCAxMTUsIDkzLCA1MSwgNDksIDUzLCA1MCwgMzYsIDc3LCA5NSwKKzU0LCA4NiwgOTMsIDYwLCA1MiwgNjMsIDkzLCA2NywgNzQsIDk4LCA1OCwgODAsIDkzLCA3MSwgNjEsIDk0LAorOTMsIDc3LCA5MywgNzksIDkzLCA4MiwgNTksIDM4LCA1MywgMzUsIDcwLCA3MSwgOTMsIDkxLCA5MywgOTMsCis5MywgOTcsIDkzLCA5OCwgOTMsIDEwMiwgNjMsIDEwMSwgNzIsIDY5LCA3MiwgNzAsIDQ5LCAxMjAsIDkzLCAxMTMsCis1MywgOTgsIDUzLCAzNywgNjgsIDY0LCA5MywgMTE1LCA3NSwgODcsIDc1LCAxMTksIDc0LCA0MCwgOTMsIDExNywKKzkzLCAxMTksIDkzLCAxMjMsIDY3LCAxMDksIDQ5LCA3NSwgNzcsIDc4LCA2NCwgMTE4LCA2OCwgNjksIDYxLCAzOSwKKzk0LCA0MiwgOTQsIDU0LCA5NCwgNDksIDczLCA5OCwgNjMsIDU5LCA5NCwgNTgsIDk0LCA1MCwgNTEsIDU0LAorNzgsIDY3LCA5NCwgNjYsIDYxLCA3NCwgOTQsIDY4LCA5NCwgNzAsIDYxLCA5NSwgNjQsIDU0LCA1NSwgNzYsCis5NCwgOTcsIDUwLCA1NywgOTQsIDk4LCA5NCwgOTIsIDk0LCA5MCwgNjIsIDY5LCA3NywgNDcsIDk0LCA4MywKKzc5LCA4MSwgNzIsIDQ2LCA2MSwgOTYsIDQ4LCAxMTAsIDk0LCAxMDYsIDY5LCA0NiwgOTQsIDEwNywgNTEsIDEwNiwKKzY2LCAxMDgsIDk0LCAxMTgsIDk1LCAzNSwgNTMsIDEyMSwgNzksIDUxLCA3MSwgMTIxLCA3NiwgMzMsIDY1LCA1MCwKKzUyLCA2NywgNTUsIDEwNSwgNTEsIDk5LCA5NSwgNDQsIDk1LCAzOCwgOTUsIDQ1LCA5NSwgNDgsIDk1LCA1NCwKKzY5LCA2NywgNTUsIDk5LCA5NSwgNjIsIDk1LCA1OSwgNzcsIDExNiwgMTExLCAxMDUsIDk1LCA3MSwgOTUsIDY4LAorNzMsIDc4LCA5NSwgNzksIDY0LCAzNywgOTUsIDgxLCA5NCwgMTE3LCA3MCwgMTAzLCA5NSwgODQsIDY5LCAxMTYsCis2MCwgOTQsIDc5LCAzOSwgOTUsIDg1LCA5NSwgODksIDk1LCA5MCwgNzgsIDExNywgOTUsIDk2LCA5NSwgODgsCis5NSwgOTgsIDk1LCA5NywgNDksIDEwNywgNzYsIDUzLCA2NSwgNTEsIDc4LCAxMjMsIDk1LCAxMDIsIDk1LCAxMDUsCis5NSwgMTA4LCA2NCwgMTIyLCA5NSwgMTAzLCA3NywgODAsIDYxLCA3OSwgOTUsIDExNCwgOTUsIDExNiwgNzEsIDUxLAorOTUsIDEyMSwgODMsIDkxLCA5NSwgMTIzLCA5NiwgMzMsIDcxLCAxMjIsIDk2LCAzNiwgOTYsIDM3LCA5NiwgMzgsCis5NiwgNDIsIDk2LCA0NCwgOTYsIDQ3LCA2OCwgNDUsIDc2LCA3MCwgNzUsIDgyLCA2NCwgNTUsIDU2LCAzNSwKKzk2LCA1NCwgOTYsIDU1LCA1MywgNjIsIDU2LCAzNiwgNjIsIDExNywgNTQsIDU2LCA5NiwgNjQsIDY1LCA2NCwKKzYwLCAxMDksIDk2LCA3MCwgOTYsIDczLCA5NiwgNzUsIDk2LCA4MCwgOTYsIDc4LCA5NiwgODEsIDk2LCA4MiwKKzYxLCA2NywgOTYsIDg4LCA5NiwgOTIsIDU2LCA2MCwgNTQsIDEwNiwgNTIsIDk3LCA5NiwgOTQsIDk2LCA5NywKKzU5LCA1NywgOTYsIDEwMCwgNTUsIDYyLCA5NiwgMTA1LCA1MywgMTAxLCA2NiwgMTE4LCA5NiwgMTA2LCA5NiwgMTA5LAorOTYsIDEwOCwgOTYsIDExMCwgOTYsIDExNCwgNTgsIDYwLCA5NiwgMTE5LCA5NiwgMTIwLCA5NiwgMTIxLCA1MiwgNjgsCis2MCwgMzcsIDk2LCAxMjMsIDk2LCAxMjUsIDk3LCAzMywgOTcsIDM3LCA5NywgNDEsIDk3LCA0NCwgOTcsIDQ4LAorNTIsIDY5LCA1OSwgNTgsIDY5LCA2OCwgNjgsIDQ2LCA5NywgNTUsIDQ4LCA5MCwgNzgsIDQ5LCA5NywgNjMsCis0OCwgOTEsIDUzLCAzOCwgOTcsIDczLCA5NywgNzUsIDk3LCA3OSwgOTcsIDg3LCA5NywgODYsIDYyLCA3MywKKzk3LCA5MCwgOTcsIDkzLCA2NSwgMTA1LCA5NywgMTAxLCA5NywgOTQsIDk3LCAxMDQsIDk3LCAxMDUsIDk3LCAxMTIsCis5NywgMTEzLCA5NywgMTE2LCA3NiwgMTI2LCA5NywgMTE3LCA5NywgMTI0LCA5OCwgMzMsIDk4LCAzNiwgNTEsIDM5LAorNTksIDQxLCA5OCwgNDUsIDcyLCAxMDUsIDk4LCA0OCwgOTgsIDUxLCA5OCwgNTIsIDY5LCAxMTIsIDk4LCA1NiwKKzc2LCA5MiwgNjUsIDEwNiwgOTgsIDY0LCA5OCwgNzAsIDk4LCA2OCwgOTgsIDcxLCA5OCwgNzMsIDk4LCA3NCwKKzk4LCA3OCwgOTgsIDgxLCA5OCwgODMsIDk4LCA4NiwgNjEsIDg2LCA5OCwgODgsIDk4LCA5NCwgOTgsIDk2LAorNzYsIDExMiwgNjcsIDU5LCA5OCwgMTAxLCA5OCwgMTAyLCA5OCwgMTA1LCA3NSwgMzYsIDU3LCA5MiwgNjIsIDc1LAorNzgsIDUwLCA5OCwgMTExLCA5OCwgMTEwLCA3MiwgMTA2LCA5OCwgMTE0LCA5OCwgMTE3LCA1MSwgNzgsIDk4LCAxMjQsCis3MiwgODgsIDk5LCAzNCwgOTksIDMzLCA5OSwgMzYsIDYyLCA3NiwgNjUsIDY3LCA5OSwgNDAsIDk4LCAxMDQsCis2MCwgNDAsIDUzLCA2NCwgOTksIDQ5LCA2MSwgNzUsIDczLCA2MCwgNjksIDEyMCwgNTQsIDg4LCA1MCwgODIsCis5OSwgNTMsIDk5LCA1NCwgOTksIDU4LCA1NCwgODksIDk5LCA2MSwgOTksIDYyLCA2NSwgNjksIDY3LCA5NywKKzQ4LCA5MiwgOTksIDY3LCA3NiwgNDUsIDk5LCA3MiwgNjAsIDExMSwgOTksIDc1LCA3NSwgODQsIDQ4LCA0NCwKKzk5LCA4MSwgNTEsIDc5LCA1MywgMTAyLCA3MCwgNzcsIDY3LCA5OCwgNTUsIDM0LCA5OSwgOTMsIDk5LCA5NiwKKzUxLCAxMTgsIDk5LCAxMDMsIDk5LCAxMDcsIDYxLCA4NywgOTksIDExMywgODEsIDYzLCA5OSwgMTE1LCA5OSwgMTE2LAorOTksIDEyMSwgNjMsIDkwLCA5OSwgMTE5LCAxMDAsIDM4LCA3MiwgNTMsIDEwMCwgNTYsIDEwMCwgNDIsIDEwMCwgNDQsCis3NCwgNzksIDEwMCwgNTQsIDEwMCwgNTEsIDY3LCA2MSwgMTAwLCA2MiwgNjQsIDk3LCAxMDAsIDU4LCAxMDAsIDY0LAorMTAwLCA2NSwgMTAwLCA3NCwgMTAwLCA3MSwgMTAwLCA3NywgMTAwLCA3NiwgNTIsIDc0LCAxMDAsIDg0LCAxMDAsIDgzLAorMTAwLCA4NywgNjQsIDgyLCAxMDAsIDkyLCAxMDAsIDk0LCA3NCwgNzAsIDc2LCA5OCwgNzQsIDUyLCA3MSwgMTE2LAorNDgsIDY0LCAxMDAsIDEwNCwgMTAwLCAxMTEsIDEwMCwgMTE0LCAxMDAsIDExNywgMTAwLCAxMTgsIDc4LCA3MiwgMTAwLCAxMjIsCis1MywgMTA2LCAxMDEsIDM2LCA2MSwgOTksIDY1LCA3MSwgNTksIDEwMywgMTAxLCA0MiwgMTAxLCA0MSwgMTAxLCAzOCwKKzEwMSwgNDUsIDc3LCAxMDksIDEwMSwgNDksIDU2LCA0MCwgMTAxLCA1MywgMTAxLCA1MiwgMTAxLCA3MCwgMTAxLCA2NCwKKzEwMSwgNjEsIDc2LCA3NCwgNTQsIDkxLCAxMDEsIDExMCwgNjgsIDEyMSwgNzYsIDc1LCAxMDEsIDc2LCAxMDEsIDc5LAorMTAxLCA4MywgNjAsIDc0LCA3NSwgMzcsIDEwMSwgOTIsIDcyLCA3NSwgNTUsIDgyLCA2NSwgNTQsIDEwMSwgOTAsCis1NSwgNDMsIDEwMSwgMTA4LCAxMDEsIDExNCwgMTAxLCAxMTcsIDEwMSwgMTI0LCA1MiwgNzYsIDEwMiwgMzMsIDEwMiwgMzcsCisxMDIsIDQyLCAxMDIsIDQ1LCA3MSwgNzcsIDEwMiwgNDgsIDEwMiwgNTMsIDEwMiwgNTcsIDU1LCA1MCwgMTAyLCA2MiwKKzEwMiwgNjQsIDEwMiwgNjYsIDYxLCA0NCwgNjMsIDEwNSwgNTIsIDEwMSwgMTAyLCA3NSwgNTcsIDc3LCA2NiwgODEsCisxMDIsIDgzLCAxMDIsIDg1LCA2MCwgNDIsIDY3LCA2MywgMTAyLCA4OCwgNjQsIDU5LCA2NSwgMTExLCA3OCwgMTI2LAorMTAyLCAxMDAsIDEwMiwgMTAzLCAxMDIsIDEwNywgNTIsIDc4LCA1NiwgNDIsIDU4LCAxMDQsIDQ4LCA5NSwgNjYsIDkxLAorMTAyLCAxMTQsIDQ4LCAxMjUsIDEwMiwgMTIwLCAxMDMsIDM4LCA2NCwgNzIsIDUzLCA4MywgMTAyLCAxMjMsIDcxLCA2MiwKKzEwMywgMzUsIDEwMiwgMTI2LCA3OSwgODMsIDEwMywgNTMsIDYwLCAxMTIsIDY4LCA1MCwgMTAzLCA0OCwgNTcsIDgxLAorNzMsIDEwMiwgMTAzLCA1MSwgMTAzLCA1NiwgMTAzLCA2MywgNTAsIDUwLCAxMDMsIDY2LCAxMDMsIDcxLCA2MCwgNDMsCis2NywgODcsIDEwMywgNzYsIDU0LCA2MSwgODAsIDQ4LCA2MSwgODgsIDEwMywgODUsIDEwMywgODgsIDEwMywgODksCisxMDMsIDkxLCAxMDMsIDk2LCA1OCwgNDksIDEwMywgMTAzLCA0OCwgMTE0LCA3MywgMTAzLCA1MSwgNDEsIDYzLCA2OCwKKzU0LCA5MiwgNTIsIDM1LCA0OSwgMTEzLCA1MCwgODcsIDYwLCA5OSwgNDksIDgxLCAxMDMsIDEyMCwgNTEsIDEyNSwKKzEwNCwgMzUsIDEwNCwgNTIsIDEwNCwgNDIsIDEwNCwgMzksIDEwNCwgNDEsIDQ5LCA2NSwgMTA0LCA1OCwgMTA0LCA0NiwKKzEwMywgMTE4LCA1MiwgODAsIDEwNCwgNjIsIDEwNCwgNTcsIDEwNCwgNzEsIDU0LCA5MywgNjIsIDg0LCAxMDQsIDc0LAorMTA0LCA2NSwgMTA0LCA3MiwgMTA0LCA2OCwgMTA0LCA3NiwgMTA0LCA3OCwgMTA0LCA4NCwgMTA0LCA5OCwgMTA0LCA5NCwKKzY3LCAxMjAsIDczLCAxMTQsIDEwNCwgODksIDQ4LCA0MiwgMTA0LCA5MiwgNjEsIDQ3LCA3MywgNzEsIDEwNCwgOTAsCis2MiwgMTIwLCA2NywgOTUsIDEwNCwgMTA4LCAxMDQsIDEwNywgNzUsIDQxLCAxMDQsIDEyMiwgMTA0LCA4MSwgNzQsIDc4LAorMTA0LCAxMTksIDEwNCwgMTE4LCA3NCwgNjcsIDEwNCwgMTI2LCAxMDUsIDM2LCAxMDQsIDEyNCwgMTA1LCA0MywgMTA1LCA0OSwKKzcxLCAxMTgsIDEwNSwgNTEsIDEwNSwgNDUsIDY1LCAzOCwgMTA1LCA1NSwgMTA1LCA1MiwgMTA1LCA1NywgNzAsIDM1LAorNjEsIDExNSwgMTA1LCAzNCwgMTA1LCA2MywgMTA1LCA2OCwgNzcsIDExOCwgMTA1LCA3MSwgMTA1LCA3MiwgNTMsIDExNywKKzEwNSwgNzYsIDEwNSwgNzcsIDQ4LCA1OCwgNTAsIDk5LCA1OSwgNjEsIDEwNSwgNzksIDEwNSwgODUsIDEwNSwgODYsCis1MSwgNjYsIDUxLCA2MywgNzIsIDU4LCA3MiwgOTAsIDY2LCAxMjUsIDc1LCA0MiwgMTA1LCAxMDcsIDY3LCA4OCwKKzEwNSwgMTE0LCAxMDUsIDExMCwgMTA1LCAxMTEsIDY0LCAxMDIsIDEwNiwgMzMsIDEwNSwgMTE4LCAxMDYsIDM1LCAxMDUsIDEyMiwKKzcxLCAxMDQsIDc3LCA1OSwgMTA2LCAzOCwgMTA2LCA0NiwgNzcsIDEwMiwgMTA2LCA0NywgMTA2LCA0NCwgMTA2LCA1NCwKKzEwNiwgNTIsIDUxLCA0MiwgMTA2LCAzNiwgMTA2LCA1NSwgMTA2LCA2NiwgMTA2LCA2NywgMTA2LCA3MSwgNjEsIDQ4LAorMTA2LCA3NCwgNjIsIDg3LCA3MywgNjEsIDEwNiwgODUsIDEwNiwgODMsIDU1LCA1NCwgMTA2LCA4OCwgMTA2LCA4MSwKKzcyLCAxMTEsIDEwNiwgODQsIDEwNiwgOTUsIDc4LCAzNCwgMTA2LCAxMDEsIDEwNiwgMTA3LCAxMDYsIDEwOCwgMTA2LCAxMDUsCis3NCwgMzUsIDc1LCA0MywgMTA2LCAxMjQsIDEwNiwgMTE2LCAxMDYsIDEyMSwgMTA2LCAxMTgsIDEwNiwgMTIzLCA1MCwgNDAsCisxMDYsIDEyNSwgMTA3LCAzNiwgMTA3LCAzOCwgMTA3LCA0MCwgMTA3LCA0MiwgMTA3LCA0NCwgMTA3LCA0NiwgMTA3LCA0OSwKKzEwNywgNTIsIDUxLCA4MSwgMTA3LCA1NywgNjMsIDQwLCAxMDcsIDYwLCA1NiwgNjQsIDYzLCA4NiwgMTA3LCA2MywKKzU1LCAxMDksIDY0LCA5NSwgNjMsIDcxLCAxMDcsIDczLCA1OCwgNjIsIDEwNywgNzEsIDU5LCAxMTAsIDUzLCA3NywKKzEwNywgNzUsIDU2LCA4OCwgMTA3LCA4NCwgNTYsIDEwOCwgMTA3LCA4MiwgNTAsIDkzLCA1MywgNjcsIDY3LCA3NiwKKzc4LCA3NCwgNjgsIDUzLCA2OCwgMTI0LCAxMDcsIDk3LCA2NiwgMTIyLCAxMDcsIDEwNCwgMTA3LCAxMDgsIDEwNywgMTExLAorMTA3LCAxMTUsIDU0LCA5NiwgMTA3LCAxMjIsIDEwNywgMTIzLCA1NSwgODksIDUzLCA2OCwgMTA4LCAzNywgOTAsIDc4LAorMTA4LCA0MywgNjcsIDQzLCAxMDgsIDQ3LCAxMDgsIDUwLCA3MCwgOTAsIDU3LCAxMDcsIDEwOCwgNTYsIDEwOCwgNTgsCis3NSwgNzAsIDEwOCwgNjYsIDU3LCA4NywgNjQsIDg1LCAxMDgsIDc0LCA1MCwgMTA4LCA2NiwgNDksIDEwOCwgNzksCisxMDgsIDc3LCAxMDgsIDgxLCAxMDgsIDgzLCAxMDgsIDg3LCA2NCwgODYsIDY1LCAxMTgsIDEwOCwgOTksIDEwOCwgMTAwLAorNjAsIDExMywgNjYsIDQ1LCAxMDgsIDEwMiwgMTA4LCAxMDksIDEwOCwgMTA2LCA2NCwgODcsIDEwOCwgMTExLCA2NSwgNDEsCisxMDgsIDExNywgMTA4LCAxMTYsIDEwOCwgMTE4LCAxMDksIDQxLCAxMDgsIDEyNSwgMTA4LCAxMjIsIDEwOSwgMzUsIDEwOSwgMzgsCisxMDksIDQyLCAxMDksIDQ1LCAxMDksIDQ2LCAxMDksIDQ4LCAxMDksIDU0LCAxMDksIDU4LCA2MywgNzIsIDEwOSwgNjMsCisxMDksIDY1LCA1NiwgNDYsIDcwLCAxMTIsIDEwOSwgNzEsIDYwLCA1MiwgNTEsIDgzLCAxMDksIDc2LCAxMDksIDc5LAorMTA5LCA4MywgMTA5LCA4NCwgMTA5LCA4OSwgMTA5LCA5MSwgMTA5LCA5NCwgNTUsIDM3LCA2MywgNzMsIDgyLCAzMywKKzYzLCA0MywgNjgsIDg0LCA2MywgODcsIDU0LCA5NywgMTA5LCAxMDcsIDY5LCA1MSwgNzYsIDY2LCA2NSwgMTE5LAorMTA5LCAxMjEsIDEwOSwgMTE2LCA2NiwgNDYsIDY2LCA5NywgNDgsIDExMSwgNjMsIDEwNywgNzQsIDg3LCAxMTAsIDQxLAorNTYsIDQ3LCA2NSwgMTIwLCA2NSwgNDMsIDExMCwgNTAsIDExMCwgNTQsIDcwLCA5NywgMTEwLCA1NiwgNDgsIDEwNiwKKzc5LCA1OCwgMTEwLCA2MiwgNzMsIDExNiwgNzcsIDU3LCAxMTAsIDYzLCAxMTAsIDY0LCA2OSwgMzQsIDcwLCA4MywKKzYzLCAxMDgsIDYzLCA5MywgNjEsIDU1LCA1NywgMTE1LCAxMTAsIDc4LCA2NiwgMTA1LCA3MiwgNDgsIDExMCwgNzksCisxMTAsIDgxLCAxMTAsIDg1LCA3MiwgODAsIDExMCwgOTAsIDExMCwgOTQsIDc1LCA4NSwgMTEwLCA5NiwgMTEwLCA5OSwKKzcwLCA5NSwgMTEwLCA5OCwgMTExLCA3OSwgNzgsIDEwNywgMTEwLCAxMTEsIDExMCwgMTA3LCAxMTAsIDEwNSwgNzIsIDQ1LAorNTcsIDkxLCA3NSwgNzIsIDY1LCA0NSwgMTEwLCAxMTcsIDY1LCA0NCwgMTEwLCAxMjEsIDExMCwgMTE5LCA2MSwgMTIzLAorNzMsIDcwLCA1NywgOTMsIDU5LCA0NCwgNjMsIDEwOSwgMTExLCAzNSwgNTQsIDgzLCA3OSwgNjMsIDExMCwgMTI1LAorNjgsIDg3LCAxMTEsIDQxLCA1NSwgNDUsIDExMSwgNDIsIDUxLCAxMjEsIDU4LCA2MywgNTEsIDU5LCAxMTEsIDQ5LAorMTExLCA1NSwgMTExLCA1NywgMTExLCA1NiwgMTExLCA1MiwgMTExLCA2MywgMTExLCA2NSwgMTExLCA2MCwgMTExLCA2NywKKzExMSwgNjgsIDExMSwgNzEsIDUyLCA4NSwgMTExLCA3NCwgMTExLCA3OCwgMTExLCA4MSwgMTExLCA4OCwgNjgsIDU3LAorMTExLCA4OSwgNDksIDYwLCAxMTEsIDk1LCA1MSwgODUsIDExMSwgOTksIDExMSwgMTAyLCAxMTEsIDEwNiwgMTExLCAxMDcsCis3MCwgNDYsIDExMSwgMTE1LCA3MywgMTA4LCAxMTEsIDExNywgNzUsIDczLCA0OCwgMzYsIDExMSwgMTIzLCA3NCwgNjksCis1MiwgODksIDQ5LCAzNCwgNTYsIDQ5LCA1NCwgMTIxLCA2MywgMTExLCA1NSwgMTAwLCA3OCwgODksIDExMiwgNDYsCis2NCwgNzMsIDUwLCAxMDksIDU5LCA0MCwgNjMsIDExOSwgNDksIDQzLCA0OSwgNjQsIDYwLCAxMjMsIDc4LCAxMTAsCisxMTIsIDY3LCAxMTIsIDY5LCAxMTIsIDcxLCAxMTIsIDczLCAxMTIsIDc3LCA2NCwgNjgsIDExMiwgODAsIDExMiwgODMsCisxMTIsIDg3LCAxMTIsIDkwLCAxMTIsIDkzLCAxMTIsIDk2LCAxMTIsIDk3LCAxMTIsIDk5LCAxMTIsIDEwMSwgMTEyLCAxMDMsCis1MiwgOTAsIDExMiwgMTA4LCA0OSwgMzYsIDU3LCA5NiwgMTEyLCAxMTQsIDU1LCA5MSwgMTEyLCAxMTcsIDQ5LCA4MCwKKzExMiwgMTIxLCA1MiwgMTA1LCA3OCwgOTYsIDExMiwgMTI0LCA3MywgMTE5LCAxMTMsIDM5LCAxMTMsIDQxLCA3MiwgMTE2LAorMTEzLCA0MywgNDgsIDU5LCA2MiwgMTI2LCAxMTMsIDQ2LCA1MCwgMTEwLCAxMTMsIDUxLCA1MiwgOTEsIDExMywgNTcsCisxMTMsIDYwLCAxMTMsIDY3LCA2MCwgMTE1LCAxMTMsIDcwLCA2NywgOTAsIDcxLCAxMjUsIDY3LCAxMTUsIDExMywgNzUsCisxMTMsIDc5LCAxMTMsIDg0LCAxMTMsIDg3LCAxMTMsIDg2LCAxMTMsIDg5LCA2NiwgNzcsIDExMywgOTEsIDExMywgOTMsCisxMTMsIDk4LCAxMTMsIDEwMCwgMTEzLCAxMDIsIDU3LCAxMjQsIDUxLCA2MCwgNjMsIDExMywgMTEzLCAxMTIsIDExMywgMTE2LAorNzIsIDQ5LCAxMTMsIDEyNCwgMTE0LCAzNCwgMTE0LCAzNSwgMTE0LCAzOCwgMTE0LCA0NSwgMTAwLCAxMjAsIDc2LCAzNywKKzExNCwgNTAsIDUzLCAxMjMsIDc5LCAzNywgMTE0LCA1NywgNDgsIDYyLCAxMTQsIDYxLCA3NSwgMTEwLCAxMTQsIDY0LAorMTE0LCA2NSwgMTE0LCA2NiwgMTE0LCA3NSwgMTE0LCA3NiwgMTE0LCA4MCwgMTE0LCA5MCwgNzksIDc2LCAxMTQsIDkyLAorMTE0LCA5MywgNDgsIDExNSwgNTEsIDExMSwgMTE0LCA5OSwgNzUsIDExMiwgMTE0LCAxMDIsIDExNCwgMTA0LCA2OCwgNTksCisxMTQsIDEwOCwgMTE0LCAxMTIsIDUwLCA0MiwgNDksIDExNywgMTE0LCAxMTUsIDU3LCA5OSwgMTE0LCAxMjUsIDExNSwgMzcsCis0OSwgNDUsIDc1LCA1MCwgMTE1LCA0NCwgMTE1LCA0MSwgMTE1LCA0NSwgMTE1LCA0NiwgMTE0LCAxMTYsIDExNSwgNTMsCisxMTUsIDQ5LCAxMTUsIDU1LCAxMTUsIDU3LCAxMTUsIDYwLCA3OSwgNzMsIDExNSwgNjMsIDExNSwgNjQsIDExNSwgNjcsCis2MCwgNDcsIDExNSwgNzIsIDExNSwgNzUsIDc4LCA5MSwgMTE1LCA3OSwgMTE1LCA4MCwgNTAsIDQzLCAxMTUsIDg1LAorOTYsIDg0LCAxMTUsIDkzLCAxMTUsIDk1LCAxMTUsIDk5LCAxMTUsIDEwMywgNTYsIDkzLCA2NSwgNzcsIDExNSwgMTA4LAorNzMsIDMzLCAxMTUsIDExMCwgMTE1LCAxMTIsIDExNSwgMTE0LCAxMTUsIDEyMCwgMTE1LCAxMjMsIDc4LCA1NCwgMTE1LCAxMjUsCiszMywgNDIsIDMzLCA5MiwgMzUsIDUzLCAzMywgNDEsIDM1LCA3MywgMzUsIDgzLCAzMywgNzksIDM1LCAxMDMsCiszNSwgMTEzLCAzMywgODAsIDI3LCA0MCwgNzMsIDM3LCA0NywgNTcsIDY3LCA3NywgODcsIDI3LCAzNiwgNjYsCiszMywgNDkKKyAgICAgICAgICAgIH0pOworCisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgdGVzdF9Db2RlY0R5bmFtaWMoKSB0aHJvd3MgQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVzdF9Db2RlY0R5bmFtaWMoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0RlY29kZSgpIHRocm93cyBDaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb24geworICAgICAgICBzdXBlci50ZXN0X0RlY29kZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHRlc3RfRW5jb2RlKCkgdGhyb3dzIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlc3RfRW5jb2RlKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX1VURl8xNi5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X011bHRpQnl0ZV9VVEZfMTYuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOWM0MmEzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X011bHRpQnl0ZV9VVEZfMTYuamF2YQpAQCAtMCwwICsxLDM4MiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFyc2V0OworCisvKiogQGhpZGUKKyAqIFNFRSBjb3JyZXNwb25kaWdfQW5kcm9pZCB0ZXN0IGNsYXNzOgorICovCisKK3B1YmxpYyBjbGFzcyBPbGRDaGFyc2V0X011bHRpQnl0ZV9VVEZfMTYgZXh0ZW5kcyBPbGRDaGFyc2V0X0Fic3RyYWN0VGVzdCB7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyc2V0TmFtZSA9ICJVVEYtMTYiOworCisgICAgICAgIHRlc3RDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKzE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCis0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKzY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCis5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKzExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKzEyOCwgMTI5LCAxMzAsIDEzMSwgMTMyLCAxMzMsIDEzNCwgMTM1LCAxMzYsIDEzNywgMTM4LCAxMzksIDE0MCwgMTQxLCAxNDIsIDE0MywKKzE0NCwgMTQ1LCAxNDYsIDE0NywgMTQ4LCAxNDksIDE1MCwgMTUxLCAxNTIsIDE1MywgMTU0LCAxNTUsIDE1NiwgMTU3LCAxNTgsIDE1OSwKKzE2MCwgMTYxLCAxNjIsIDE2MywgMTY0LCAxNjUsIDE2NiwgMTY3LCAxNjgsIDE2OSwgMTcwLCAxNzEsIDE3MiwgMTczLCAxNzQsIDE3NSwKKzE3NiwgMTc3LCAxNzgsIDE3OSwgMTgwLCAxODEsIDE4MiwgMTgzLCAxODQsIDE4NSwgMTg2LCAxODcsIDE4OCwgMTg5LCAxOTAsIDE5MSwKKzE5MiwgMTkzLCAxOTQsIDE5NSwgMTk2LCAxOTcsIDE5OCwgMTk5LCAyMDAsIDIwMSwgMjAyLCAyMDMsIDIwNCwgMjA1LCAyMDYsIDIwNywKKzIwOCwgMjA5LCAyMTAsIDIxMSwgMjEyLCAyMTMsIDIxNCwgMjE1LCAyMTYsIDIxNywgMjE4LCAyMTksIDIyMCwgMjIxLCAyMjIsIDIyMywKKzIyNCwgMjI1LCAyMjYsIDIyNywgMjI4LCAyMjksIDIzMCwgMjMxLCAyMzIsIDIzMywgMjM0LCAyMzUsIDIzNiwgMjM3LCAyMzgsIDIzOSwKKzI0MCwgMjQxLCAyNDIsIDI0MywgMjQ0LCAyNDUsIDI0NiwgMjQ3LCAyNDgsIDI0OSwgMjUwLCAyNTEsIDI1MiwgMjUzLCAyNTQsIDI1NSwKKzI1NiwgMjk2LCAzMzYsIDM3NiwgNDE2LCA0NTYsIDQ5NiwgNTM2LCA1NzYsIDYxNiwgNjU2LCA2OTYsIDczNiwgNzc2LCA4MTYsIDg1NiwKKzg5NiwgOTM2LCA5NzYsIDEwMTYsIDEwNTYsIDEwOTYsIDExMzYsIDExNzYsIDEyMTYsIDEyNTYsIDEyOTYsIDEzMzYsIDEzNzYsIDE0MTYsIDE0NTYsIDE0OTYsCisxNTM2LCAxNTc2LCAxNjE2LCAxNjU2LCAxNjk2LCAxNzM2LCAxNzc2LCAxODE2LCAxODU2LCAxODk2LCAxOTM2LCAxOTc2LCAyMDE2LCAyMDU2LCAyMDk2LCAyMTM2LAorMjE3NiwgMjIxNiwgMjI1NiwgMjI5NiwgMjMzNiwgMjM3NiwgMjQxNiwgMjQ1NiwgMjQ5NiwgMjUzNiwgMjU3NiwgMjYxNiwgMjY1NiwgMjY5NiwgMjczNiwgMjc3NiwKKzI4MTYsIDI4NTYsIDI4OTYsIDI5MzYsIDI5NzYsIDMwMTYsIDMwNTYsIDMwOTYsIDMxMzYsIDMxNzYsIDMyMTYsIDMyNTYsIDMyOTYsIDMzMzYsIDMzNzYsIDM0MTYsCiszNDU2LCAzNDk2LCAzNTM2LCAzNTc2LCAzNjE2LCAzNjU2LCAzNjk2LCAzNzM2LCAzNzc2LCAzODE2LCAzODU2LCAzODk2LCAzOTM2LCAzOTc2LCA0MDE2LCA0MDU2LAorNDA5NiwgNDEzNiwgNDE3NiwgNDIxNiwgNDI1NiwgNDI5NiwgNDMzNiwgNDM3NiwgNDQxNiwgNDQ1NiwgNDQ5NiwgNDUzNiwgNDU3NiwgNDYxNiwgNDY1NiwgNDY5NiwKKzQ3MzYsIDQ3NzYsIDQ4MTYsIDQ4NTYsIDQ4OTYsIDQ5MzYsIDQ5NzYsIDUwMTYsIDUwNTYsIDUwOTYsIDUxMzYsIDUxNzYsIDUyMTYsIDUyNTYsIDUyOTYsIDUzMzYsCis1Mzc2LCA1NDE2LCA1NDU2LCA1NDk2LCA1NTM2LCA1NTc2LCA1NjE2LCA1NjU2LCA1Njk2LCA1NzM2LCA1Nzc2LCA1ODE2LCA1ODU2LCA1ODk2LCA1OTM2LCA1OTc2LAorNjAxNiwgNjA1NiwgNjA5NiwgNjEzNiwgNjE3NiwgNjIxNiwgNjI1NiwgNjI5NiwgNjMzNiwgNjM3NiwgNjQxNiwgNjQ1NiwgNjQ5NiwgNjUzNiwgNjU3NiwgNjYxNiwKKzY2NTYsIDY2OTYsIDY3MzYsIDY3NzYsIDY4MTYsIDY4NTYsIDY4OTYsIDY5MzYsIDY5NzYsIDcwMTYsIDcwNTYsIDcwOTYsIDcxMzYsIDcxNzYsIDcyMTYsIDcyNTYsCis3Mjk2LCA3MzM2LCA3Mzc2LCA3NDE2LCA3NDU2LCA3NDk2LCA3NTM2LCA3NTc2LCA3NjE2LCA3NjU2LCA3Njk2LCA3NzM2LCA3Nzc2LCA3ODE2LCA3ODU2LCA3ODk2LAorNzkzNiwgNzk3NiwgODAxNiwgODA1NiwgODA5NiwgODEzNiwgODE3NiwgODIxNiwgODI1NiwgODI5NiwgODMzNiwgODM3NiwgODQxNiwgODQ1NiwgODQ5NiwgODUzNiwKKzg1NzYsIDg2MTYsIDg2NTYsIDg2OTYsIDg3MzYsIDg3NzYsIDg4MTYsIDg4NTYsIDg4OTYsIDg5MzYsIDg5NzYsIDkwMTYsIDkwNTYsIDkwOTYsIDkxMzYsIDkxNzYsCis5MjE2LCA5MjU2LCA5Mjk2LCA5MzM2LCA5Mzc2LCA5NDE2LCA5NDU2LCA5NDk2LCA5NTM2LCA5NTc2LCA5NjE2LCA5NjU2LCA5Njk2LCA5NzM2LCA5Nzc2LCA5ODE2LAorOTg1NiwgOTg5NiwgOTkzNiwgOTk3NiwgMTAwMTYsIDEwMDU2LCAxMDA5NiwgMTAxMzYsIDEwMTc2LCAxMDIxNiwgMTAyNTYsIDEwMjk2LCAxMDMzNiwgMTAzNzYsIDEwNDE2LCAxMDQ1NiwKKzEwNDk2LCAxMDUzNiwgMTA1NzYsIDEwNjE2LCAxMDY1NiwgMTA2OTYsIDEwNzM2LCAxMDc3NiwgMTA4MTYsIDEwODU2LCAxMDg5NiwgMTA5MzYsIDEwOTc2LCAxMTAxNiwgMTEwNTYsIDExMDk2LAorMTExMzYsIDExMTc2LCAxMTIxNiwgMTEyNTYsIDExMjk2LCAxMTMzNiwgMTEzNzYsIDExNDE2LCAxMTQ1NiwgMTE0OTYsIDExNTM2LCAxMTU3NiwgMTE2MTYsIDExNjU2LCAxMTY5NiwgMTE3MzYsCisxMTc3NiwgMTE4MTYsIDExODU2LCAxMTg5NiwgMTE5MzYsIDExOTc2LCAxMjAxNiwgMTIwNTYsIDEyMDk2LCAxMjEzNiwgMTIxNzYsIDEyMjE2LCAxMjI1NiwgMTIyOTYsIDEyMzM2LCAxMjM3NiwKKzEyNDE2LCAxMjQ1NiwgMTI0OTYsIDEyNTM2LCAxMjU3NiwgMTI2MTYsIDEyNjU2LCAxMjY5NiwgMTI3MzYsIDEyNzc2LCAxMjgxNiwgMTI4NTYsIDEyODk2LCAxMjkzNiwgMTI5NzYsIDEzMDE2LAorMTMwNTYsIDEzMDk2LCAxMzEzNiwgMTMxNzYsIDEzMjE2LCAxMzI1NiwgMTMyOTYsIDEzMzM2LCAxMzM3NiwgMTM0MTYsIDEzNDU2LCAxMzQ5NiwgMTM1MzYsIDEzNTc2LCAxMzYxNiwgMTM2NTYsCisxMzY5NiwgMTM3MzYsIDEzNzc2LCAxMzgxNiwgMTM4NTYsIDEzODk2LCAxMzkzNiwgMTM5NzYsIDE0MDE2LCAxNDA1NiwgMTQwOTYsIDE0MTM2LCAxNDE3NiwgMTQyMTYsIDE0MjU2LCAxNDI5NiwKKzE0MzM2LCAxNDM3NiwgMTQ0MTYsIDE0NDU2LCAxNDQ5NiwgMTQ1MzYsIDE0NTc2LCAxNDYxNiwgMTQ2NTYsIDE0Njk2LCAxNDczNiwgMTQ3NzYsIDE0ODE2LCAxNDg1NiwgMTQ4OTYsIDE0OTM2LAorMTQ5NzYsIDE1MDE2LCAxNTA1NiwgMTUwOTYsIDE1MTM2LCAxNTE3NiwgMTUyMTYsIDE1MjU2LCAxNTI5NiwgMTUzMzYsIDE1Mzc2LCAxNTQxNiwgMTU0NTYsIDE1NDk2LCAxNTUzNiwgMTU1NzYsCisxNTYxNiwgMTU2NTYsIDE1Njk2LCAxNTczNiwgMTU3NzYsIDE1ODE2LCAxNTg1NiwgMTU4OTYsIDE1OTM2LCAxNTk3NiwgMTYwMTYsIDE2MDU2LCAxNjA5NiwgMTYxMzYsIDE2MTc2LCAxNjIxNiwKKzE2MjU2LCAxNjI5NiwgMTYzMzYsIDE2Mzc2LCAxNjQxNiwgMTY0NTYsIDE2NDk2LCAxNjUzNiwgMTY1NzYsIDE2NjE2LCAxNjY1NiwgMTY2OTYsIDE2NzM2LCAxNjc3NiwgMTY4MTYsIDE2ODU2LAorMTY4OTYsIDE2OTM2LCAxNjk3NiwgMTcwMTYsIDE3MDU2LCAxNzA5NiwgMTcxMzYsIDE3MTc2LCAxNzIxNiwgMTcyNTYsIDE3Mjk2LCAxNzMzNiwgMTczNzYsIDE3NDE2LCAxNzQ1NiwgMTc0OTYsCisxNzUzNiwgMTc1NzYsIDE3NjE2LCAxNzY1NiwgMTc2OTYsIDE3NzM2LCAxNzc3NiwgMTc4MTYsIDE3ODU2LCAxNzg5NiwgMTc5MzYsIDE3OTc2LCAxODAxNiwgMTgwNTYsIDE4MDk2LCAxODEzNiwKKzE4MTc2LCAxODIxNiwgMTgyNTYsIDE4Mjk2LCAxODMzNiwgMTgzNzYsIDE4NDE2LCAxODQ1NiwgMTg0OTYsIDE4NTM2LCAxODU3NiwgMTg2MTYsIDE4NjU2LCAxODY5NiwgMTg3MzYsIDE4Nzc2LAorMTg4MTYsIDE4ODU2LCAxODg5NiwgMTg5MzYsIDE4OTc2LCAxOTAxNiwgMTkwNTYsIDE5MDk2LCAxOTEzNiwgMTkxNzYsIDE5MjE2LCAxOTI1NiwgMTkyOTYsIDE5MzM2LCAxOTM3NiwgMTk0MTYsCisxOTQ1NiwgMTk0OTYsIDE5NTM2LCAxOTU3NiwgMTk2MTYsIDE5NjU2LCAxOTY5NiwgMTk3MzYsIDE5Nzc2LCAxOTgxNiwgMTk4NTYsIDE5ODk2LCAxOTkzNiwgMTk5NzYsIDIwMDE2LCAyMDA1NiwKKzIwMDk2LCAyMDEzNiwgMjAxNzYsIDIwMjE2LCAyMDI1NiwgMjAyOTYsIDIwMzM2LCAyMDM3NiwgMjA0MTYsIDIwNDU2LCAyMDQ5NiwgMjA1MzYsIDIwNTc2LCAyMDYxNiwgMjA2NTYsIDIwNjk2LAorMjA3MzYsIDIwNzc2LCAyMDgxNiwgMjA4NTYsIDIwODk2LCAyMDkzNiwgMjA5NzYsIDIxMDE2LCAyMTA1NiwgMjEwOTYsIDIxMTM2LCAyMTE3NiwgMjEyMTYsIDIxMjU2LCAyMTI5NiwgMjEzMzYsCisyMTM3NiwgMjE0MTYsIDIxNDU2LCAyMTQ5NiwgMjE1MzYsIDIxNTc2LCAyMTYxNiwgMjE2NTYsIDIxNjk2LCAyMTczNiwgMjE3NzYsIDIxODE2LCAyMTg1NiwgMjE4OTYsIDIxOTM2LCAyMTk3NiwKKzIyMDE2LCAyMjA1NiwgMjIwOTYsIDIyMTM2LCAyMjE3NiwgMjIyMTYsIDIyMjU2LCAyMjI5NiwgMjIzMzYsIDIyMzc2LCAyMjQxNiwgMjI0NTYsIDIyNDk2LCAyMjUzNiwgMjI1NzYsIDIyNjE2LAorMjI2NTYsIDIyNjk2LCAyMjczNiwgMjI3NzYsIDIyODE2LCAyMjg1NiwgMjI4OTYsIDIyOTM2LCAyMjk3NiwgMjMwMTYsIDIzMDU2LCAyMzA5NiwgMjMxMzYsIDIzMTc2LCAyMzIxNiwgMjMyNTYsCisyMzI5NiwgMjMzMzYsIDIzMzc2LCAyMzQxNiwgMjM0NTYsIDIzNDk2LCAyMzUzNiwgMjM1NzYsIDIzNjE2LCAyMzY1NiwgMjM2OTYsIDIzNzM2LCAyMzc3NiwgMjM4MTYsIDIzODU2LCAyMzg5NiwKKzIzOTM2LCAyMzk3NiwgMjQwMTYsIDI0MDU2LCAyNDA5NiwgMjQxMzYsIDI0MTc2LCAyNDIxNiwgMjQyNTYsIDI0Mjk2LCAyNDMzNiwgMjQzNzYsIDI0NDE2LCAyNDQ1NiwgMjQ0OTYsIDI0NTM2LAorMjQ1NzYsIDI0NjE2LCAyNDY1NiwgMjQ2OTYsIDI0NzM2LCAyNDc3NiwgMjQ4MTYsIDI0ODU2LCAyNDg5NiwgMjQ5MzYsIDI0OTc2LCAyNTAxNiwgMjUwNTYsIDI1MDk2LCAyNTEzNiwgMjUxNzYsCisyNTIxNiwgMjUyNTYsIDI1Mjk2LCAyNTMzNiwgMjUzNzYsIDI1NDE2LCAyNTQ1NiwgMjU0OTYsIDI1NTM2LCAyNTU3NiwgMjU2MTYsIDI1NjU2LCAyNTY5NiwgMjU3MzYsIDI1Nzc2LCAyNTgxNiwKKzI1ODU2LCAyNTg5NiwgMjU5MzYsIDI1OTc2LCAyNjAxNiwgMjYwNTYsIDI2MDk2LCAyNjEzNiwgMjYxNzYsIDI2MjE2LCAyNjI1NiwgMjYyOTYsIDI2MzM2LCAyNjM3NiwgMjY0MTYsIDI2NDU2LAorMjY0OTYsIDI2NTM2LCAyNjU3NiwgMjY2MTYsIDI2NjU2LCAyNjY5NiwgMjY3MzYsIDI2Nzc2LCAyNjgxNiwgMjY4NTYsIDI2ODk2LCAyNjkzNiwgMjY5NzYsIDI3MDE2LCAyNzA1NiwgMjcwOTYsCisyNzEzNiwgMjcxNzYsIDI3MjE2LCAyNzI1NiwgMjcyOTYsIDI3MzM2LCAyNzM3NiwgMjc0MTYsIDI3NDU2LCAyNzQ5NiwgMjc1MzYsIDI3NTc2LCAyNzYxNiwgMjc2NTYsIDI3Njk2LCAyNzczNiwKKzI3Nzc2LCAyNzgxNiwgMjc4NTYsIDI3ODk2LCAyNzkzNiwgMjc5NzYsIDI4MDE2LCAyODA1NiwgMjgwOTYsIDI4MTM2LCAyODE3NiwgMjgyMTYsIDI4MjU2LCAyODI5NiwgMjgzMzYsIDI4Mzc2LAorMjg0MTYsIDI4NDU2LCAyODQ5NiwgMjg1MzYsIDI4NTc2LCAyODYxNiwgMjg2NTYsIDI4Njk2LCAyODczNiwgMjg3NzYsIDI4ODE2LCAyODg1NiwgMjg4OTYsIDI4OTM2LCAyODk3NiwgMjkwMTYsCisyOTA1NiwgMjkwOTYsIDI5MTM2LCAyOTE3NiwgMjkyMTYsIDI5MjU2LCAyOTI5NiwgMjkzMzYsIDI5Mzc2LCAyOTQxNiwgMjk0NTYsIDI5NDk2LCAyOTUzNiwgMjk1NzYsIDI5NjE2LCAyOTY1NiwKKzI5Njk2LCAyOTczNiwgMjk3NzYsIDI5ODE2LCAyOTg1NiwgMjk4OTYsIDI5OTM2LCAyOTk3NiwgMzAwMTYsIDMwMDU2LCAzMDA5NiwgMzAxMzYsIDMwMTc2LCAzMDIxNiwgMzAyNTYsIDMwMjk2LAorMzAzMzYsIDMwMzc2LCAzMDQxNiwgMzA0NTYsIDMwNDk2LCAzMDUzNiwgMzA1NzYsIDMwNjE2LCAzMDY1NiwgMzA2OTYsIDMwNzM2LCAzMDc3NiwgMzA4MTYsIDMwODU2LCAzMDg5NiwgMzA5MzYsCiszMDk3NiwgMzEwMTYsIDMxMDU2LCAzMTA5NiwgMzExMzYsIDMxMTc2LCAzMTIxNiwgMzEyNTYsIDMxMjk2LCAzMTMzNiwgMzEzNzYsIDMxNDE2LCAzMTQ1NiwgMzE0OTYsIDMxNTM2LCAzMTU3NiwKKzMxNjE2LCAzMTY1NiwgMzE2OTYsIDMxNzM2LCAzMTc3NiwgMzE4MTYsIDMxODU2LCAzMTg5NiwgMzE5MzYsIDMxOTc2LCAzMjAxNiwgMzIwNTYsIDMyMDk2LCAzMjEzNiwgMzIxNzYsIDMyMjE2LAorMzIyNTYsIDMyMjk2LCAzMjMzNiwgMzIzNzYsIDMyNDE2LCAzMjQ1NiwgMzI0OTYsIDMyNTM2LCAzMjU3NiwgMzI2MTYsIDMyNjU2LCAzMjY5NiwgMzI3MzYsIDMyNzc2LCAzMjgxNiwgMzI4NTYsCiszMjg5NiwgMzI5MzYsIDMyOTc2LCAzMzAxNiwgMzMwNTYsIDMzMDk2LCAzMzEzNiwgMzMxNzYsIDMzMjE2LCAzMzI1NiwgMzMyOTYsIDMzMzM2LCAzMzM3NiwgMzM0MTYsIDMzNDU2LCAzMzQ5NiwKKzMzNTM2LCAzMzU3NiwgMzM2MTYsIDMzNjU2LCAzMzY5NiwgMzM3MzYsIDMzNzc2LCAzMzgxNiwgMzM4NTYsIDMzODk2LCAzMzkzNiwgMzM5NzYsIDM0MDE2LCAzNDA1NiwgMzQwOTYsIDM0MTM2LAorMzQxNzYsIDM0MjE2LCAzNDI1NiwgMzQyOTYsIDM0MzM2LCAzNDM3NiwgMzQ0MTYsIDM0NDU2LCAzNDQ5NiwgMzQ1MzYsIDM0NTc2LCAzNDYxNiwgMzQ2NTYsIDM0Njk2LCAzNDczNiwgMzQ3NzYsCiszNDgxNiwgMzQ4NTYsIDM0ODk2LCAzNDkzNiwgMzQ5NzYsIDM1MDE2LCAzNTA1NiwgMzUwOTYsIDM1MTM2LCAzNTE3NiwgMzUyMTYsIDM1MjU2LCAzNTI5NiwgMzUzMzYsIDM1Mzc2LCAzNTQxNiwKKzM1NDU2LCAzNTQ5NiwgMzU1MzYsIDM1NTc2LCAzNTYxNiwgMzU2NTYsIDM1Njk2LCAzNTczNiwgMzU3NzYsIDM1ODE2LCAzNTg1NiwgMzU4OTYsIDM1OTM2LCAzNTk3NiwgMzYwMTYsIDM2MDU2LAorMzYwOTYsIDM2MTM2LCAzNjE3NiwgMzYyMTYsIDM2MjU2LCAzNjI5NiwgMzYzMzYsIDM2Mzc2LCAzNjQxNiwgMzY0NTYsIDM2NDk2LCAzNjUzNiwgMzY1NzYsIDM2NjE2LCAzNjY1NiwgMzY2OTYsCiszNjczNiwgMzY3NzYsIDM2ODE2LCAzNjg1NiwgMzY4OTYsIDM2OTM2LCAzNjk3NiwgMzcwMTYsIDM3MDU2LCAzNzA5NiwgMzcxMzYsIDM3MTc2LCAzNzIxNiwgMzcyNTYsIDM3Mjk2LCAzNzMzNiwKKzM3Mzc2LCAzNzQxNiwgMzc0NTYsIDM3NDk2LCAzNzUzNiwgMzc1NzYsIDM3NjE2LCAzNzY1NiwgMzc2OTYsIDM3NzM2LCAzNzc3NiwgMzc4MTYsIDM3ODU2LCAzNzg5NiwgMzc5MzYsIDM3OTc2LAorMzgwMTYsIDM4MDU2LCAzODA5NiwgMzgxMzYsIDM4MTc2LCAzODIxNiwgMzgyNTYsIDM4Mjk2LCAzODMzNiwgMzgzNzYsIDM4NDE2LCAzODQ1NiwgMzg0OTYsIDM4NTM2LCAzODU3NiwgMzg2MTYsCiszODY1NiwgMzg2OTYsIDM4NzM2LCAzODc3NiwgMzg4MTYsIDM4ODU2LCAzODg5NiwgMzg5MzYsIDM4OTc2LCAzOTAxNiwgMzkwNTYsIDM5MDk2LCAzOTEzNiwgMzkxNzYsIDM5MjE2LCAzOTI1NiwKKzM5Mjk2LCAzOTMzNiwgMzkzNzYsIDM5NDE2LCAzOTQ1NiwgMzk0OTYsIDM5NTM2LCAzOTU3NiwgMzk2MTYsIDM5NjU2LCAzOTY5NiwgMzk3MzYsIDM5Nzc2LCAzOTgxNiwgMzk4NTYsIDM5ODk2LAorMzk5MzYsIDM5OTc2LCA0MDAxNiwgNDAwNTYsIDQwMDk2LCA0MDEzNiwgNDAxNzYsIDQwMjE2LCA0MDI1NiwgNDAyOTYsIDQwMzM2LCA0MDM3NiwgNDA0MTYsIDQwNDU2LCA0MDQ5NiwgNDA1MzYsCis0MDU3NiwgNDA2MTYsIDQwNjU2LCA0MDY5NiwgNDA3MzYsIDQwNzc2LCA0MDgxNiwgNDA4NTYsIDQwODk2LCA0MDkzNiwgNDA5NzYsIDQxMDE2LCA0MTA1NiwgNDEwOTYsIDQxMTM2LCA0MTE3NiwKKzQxMjE2LCA0MTI1NiwgNDEyOTYsIDQxMzM2LCA0MTM3NiwgNDE0MTYsIDQxNDU2LCA0MTQ5NiwgNDE1MzYsIDQxNTc2LCA0MTYxNiwgNDE2NTYsIDQxNjk2LCA0MTczNiwgNDE3NzYsIDQxODE2LAorNDE4NTYsIDQxODk2LCA0MTkzNiwgNDE5NzYsIDQyMDE2LCA0MjA1NiwgNDIwOTYsIDQyMTM2LCA0MjE3NiwgNDIyMTYsIDQyMjU2LCA0MjI5NiwgNDIzMzYsIDQyMzc2LCA0MjQxNiwgNDI0NTYsCis0MjQ5NiwgNDI1MzYsIDQyNTc2LCA0MjYxNiwgNDI2NTYsIDQyNjk2LCA0MjczNiwgNDI3NzYsIDQyODE2LCA0Mjg1NiwgNDI4OTYsIDQyOTM2LCA0Mjk3NiwgNDMwMTYsIDQzMDU2LCA0MzA5NiwKKzQzMTM2LCA0MzE3NiwgNDMyMTYsIDQzMjU2LCA0MzI5NiwgNDMzMzYsIDQzMzc2LCA0MzQxNiwgNDM0NTYsIDQzNDk2LCA0MzUzNiwgNDM1NzYsIDQzNjE2LCA0MzY1NiwgNDM2OTYsIDQzNzM2LAorNDM3NzYsIDQzODE2LCA0Mzg1NiwgNDM4OTYsIDQzOTM2LCA0Mzk3NiwgNDQwMTYsIDQ0MDU2LCA0NDA5NiwgNDQxMzYsIDQ0MTc2LCA0NDIxNiwgNDQyNTYsIDQ0Mjk2LCA0NDMzNiwgNDQzNzYsCis0NDQxNiwgNDQ0NTYsIDQ0NDk2LCA0NDUzNiwgNDQ1NzYsIDQ0NjE2LCA0NDY1NiwgNDQ2OTYsIDQ0NzM2LCA0NDc3NiwgNDQ4MTYsIDQ0ODU2LCA0NDg5NiwgNDQ5MzYsIDQ0OTc2LCA0NTAxNiwKKzQ1MDU2LCA0NTA5NiwgNDUxMzYsIDQ1MTc2LCA0NTIxNiwgNDUyNTYsIDQ1Mjk2LCA0NTMzNiwgNDUzNzYsIDQ1NDE2LCA0NTQ1NiwgNDU0OTYsIDQ1NTM2LCA0NTU3NiwgNDU2MTYsIDQ1NjU2LAorNDU2OTYsIDQ1NzM2LCA0NTc3NiwgNDU4MTYsIDQ1ODU2LCA0NTg5NiwgNDU5MzYsIDQ1OTc2LCA0NjAxNiwgNDYwNTYsIDQ2MDk2LCA0NjEzNiwgNDYxNzYsIDQ2MjE2LCA0NjI1NiwgNDYyOTYsCis0NjMzNiwgNDYzNzYsIDQ2NDE2LCA0NjQ1NiwgNDY0OTYsIDQ2NTM2LCA0NjU3NiwgNDY2MTYsIDQ2NjU2LCA0NjY5NiwgNDY3MzYsIDQ2Nzc2LCA0NjgxNiwgNDY4NTYsIDQ2ODk2LCA0NjkzNiwKKzQ2OTc2LCA0NzAxNiwgNDcwNTYsIDQ3MDk2LCA0NzEzNiwgNDcxNzYsIDQ3MjE2LCA0NzI1NiwgNDcyOTYsIDQ3MzM2LCA0NzM3NiwgNDc0MTYsIDQ3NDU2LCA0NzQ5NiwgNDc1MzYsIDQ3NTc2LAorNDc2MTYsIDQ3NjU2LCA0NzY5NiwgNDc3MzYsIDQ3Nzc2LCA0NzgxNiwgNDc4NTYsIDQ3ODk2LCA0NzkzNiwgNDc5NzYsIDQ4MDE2LCA0ODA1NiwgNDgwOTYsIDQ4MTM2LCA0ODE3NiwgNDgyMTYsCis0ODI1NiwgNDgyOTYsIDQ4MzM2LCA0ODM3NiwgNDg0MTYsIDQ4NDU2LCA0ODQ5NiwgNDg1MzYsIDQ4NTc2LCA0ODYxNiwgNDg2NTYsIDQ4Njk2LCA0ODczNiwgNDg3NzYsIDQ4ODE2LCA0ODg1NiwKKzQ4ODk2LCA0ODkzNiwgNDg5NzYsIDQ5MDE2LCA0OTA1NiwgNDkwOTYsIDQ5MTM2LCA0OTE3NiwgNDkyMTYsIDQ5MjU2LCA0OTI5NiwgNDkzMzYsIDQ5Mzc2LCA0OTQxNiwgNDk0NTYsIDQ5NDk2LAorNDk1MzYsIDQ5NTc2LCA0OTYxNiwgNDk2NTYsIDQ5Njk2LCA0OTczNiwgNDk3NzYsIDQ5ODE2LCA0OTg1NiwgNDk4OTYsIDQ5OTM2LCA0OTk3NiwgNTAwMTYsIDUwMDU2LCA1MDA5NiwgNTAxMzYsCis1MDE3NiwgNTAyMTYsIDUwMjU2LCA1MDI5NiwgNTAzMzYsIDUwMzc2LCA1MDQxNiwgNTA0NTYsIDUwNDk2LCA1MDUzNiwgNTA1NzYsIDUwNjE2LCA1MDY1NiwgNTA2OTYsIDUwNzM2LCA1MDc3NiwKKzUwODE2LCA1MDg1NiwgNTA4OTYsIDUwOTM2LCA1MDk3NiwgNTEwMTYsIDUxMDU2LCA1MTA5NiwgNTExMzYsIDUxMTc2LCA1MTIxNiwgNTEyNTYsIDUxMjk2LCA1MTMzNiwgNTEzNzYsIDUxNDE2LAorNTE0NTYsIDUxNDk2LCA1MTUzNiwgNTE1NzYsIDUxNjE2LCA1MTY1NiwgNTE2OTYsIDUxNzM2LCA1MTc3NiwgNTE4MTYsIDUxODU2LCA1MTg5NiwgNTE5MzYsIDUxOTc2LCA1MjAxNiwgNTIwNTYsCis1MjA5NiwgNTIxMzYsIDUyMTc2LCA1MjIxNiwgNTIyNTYsIDUyMjk2LCA1MjMzNiwgNTIzNzYsIDUyNDE2LCA1MjQ1NiwgNTI0OTYsIDUyNTM2LCA1MjU3NiwgNTI2MTYsIDUyNjU2LCA1MjY5NiwKKzUyNzM2LCA1Mjc3NiwgNTI4MTYsIDUyODU2LCA1Mjg5NiwgNTI5MzYsIDUyOTc2LCA1MzAxNiwgNTMwNTYsIDUzMDk2LCA1MzEzNiwgNTMxNzYsIDUzMjE2LCA1MzI1NiwgNTMyOTYsIDUzMzM2LAorNTMzNzYsIDUzNDE2LCA1MzQ1NiwgNTM0OTYsIDUzNTM2LCA1MzU3NiwgNTM2MTYsIDUzNjU2LCA1MzY5NiwgNTM3MzYsIDUzNzc2LCA1MzgxNiwgNTM4NTYsIDUzODk2LCA1MzkzNiwgNTM5NzYsCis1NDAxNiwgNTQwNTYsIDU0MDk2LCA1NDEzNiwgNTQxNzYsIDU0MjE2LCA1NDI1NiwgNTQyOTYsIDU0MzM2LCA1NDM3NiwgNTQ0MTYsIDU0NDU2LCA1NDQ5NiwgNTQ1MzYsIDU0NTc2LCA1NDYxNiwKKzU0NjU2LCA1NDY5NiwgNTQ3MzYsIDU0Nzc2LCA1NDgxNiwgNTQ4NTYsIDU0ODk2LCA1NDkzNiwgNTQ5NzYsIDU1MDE2LCA1NTA1NiwgNTUwOTYsIDU1MTM2LCA1NTE3NiwgNTUyMTYsIDU1MjU2LAorNTczNDQsIDU3Mzg0LCA1NzQyNCwgNTc0NjQsIDU3NTA0LCA1NzU0NCwgNTc1ODQsIDU3NjI0LCA1NzY2NCwgNTc3MDQsIDU3NzQ0LCA1Nzc4NCwgNTc4MjQsIDU3ODY0LCA1NzkwNCwgNTc5NDQsCis1Nzk4NCwgNTgwMjQsIDU4MDY0LCA1ODEwNCwgNTgxNDQsIDU4MTg0LCA1ODIyNCwgNTgyNjQsIDU4MzA0LCA1ODM0NCwgNTgzODQsIDU4NDI0LCA1ODQ2NCwgNTg1MDQsIDU4NTQ0LCA1ODU4NCwKKzU4NjI0LCA1ODY2NCwgNTg3MDQsIDU4NzQ0LCA1ODc4NCwgNTg4MjQsIDU4ODY0LCA1ODkwNCwgNTg5NDQsIDU4OTg0LCA1OTAyNCwgNTkwNjQsIDU5MTA0LCA1OTE0NCwgNTkxODQsIDU5MjI0LAorNTkyNjQsIDU5MzA0LCA1OTM0NCwgNTkzODQsIDU5NDI0LCA1OTQ2NCwgNTk1MDQsIDU5NTQ0LCA1OTU4NCwgNTk2MjQsIDU5NjY0LCA1OTcwNCwgNTk3NDQsIDU5Nzg0LCA1OTgyNCwgNTk4NjQsCis1OTkwNCwgNTk5NDQsIDU5OTg0LCA2MDAyNCwgNjAwNjQsIDYwMTA0LCA2MDE0NCwgNjAxODQsIDYwMjI0LCA2MDI2NCwgNjAzMDQsIDYwMzQ0LCA2MDM4NCwgNjA0MjQsIDYwNDY0LCA2MDUwNCwKKzYwNTQ0LCA2MDU4NCwgNjA2MjQsIDYwNjY0LCA2MDcwNCwgNjA3NDQsIDYwNzg0LCA2MDgyNCwgNjA4NjQsIDYwOTA0LCA2MDk0NCwgNjA5ODQsIDYxMDI0LCA2MTA2NCwgNjExMDQsIDYxMTQ0LAorNjExODQsIDYxMjI0LCA2MTI2NCwgNjEzMDQsIDYxMzQ0LCA2MTM4NCwgNjE0MjQsIDYxNDY0LCA2MTUwNCwgNjE1NDQsIDYxNTg0LCA2MTYyNCwgNjE2NjQsIDYxNzA0LCA2MTc0NCwgNjE3ODQsCis2MTgyNCwgNjE4NjQsIDYxOTA0LCA2MTk0NCwgNjE5ODQsIDYyMDI0LCA2MjA2NCwgNjIxMDQsIDYyMTQ0LCA2MjE4NCwgNjIyMjQsIDYyMjY0LCA2MjMwNCwgNjIzNDQsIDYyMzg0LCA2MjQyNCwKKzYyNDY0LCA2MjUwNCwgNjI1NDQsIDYyNTg0LCA2MjYyNCwgNjI2NjQsIDYyNzA0LCA2Mjc0NCwgNjI3ODQsIDYyODI0LCA2Mjg2NCwgNjI5MDQsIDYyOTQ0LCA2Mjk4NCwgNjMwMjQsIDYzMDY0LAorNjMxMDQsIDYzMTQ0LCA2MzE4NCwgNjMyMjQsIDYzMjY0LCA2MzMwNCwgNjMzNDQsIDYzMzg0LCA2MzQyNCwgNjM0NjQsIDYzNTA0LCA2MzU0NCwgNjM1ODQsIDYzNjI0LCA2MzY2NCwgNjM3MDQsCis2Mzc0NCwgNjM3ODQsIDYzODI0LCA2Mzg2NCwgNjM5MDQsIDYzOTQ0LCA2Mzk4NCwgNjQwMjQsIDY0MDY0LCA2NDEwNCwgNjQxNDQsIDY0MTg0LCA2NDIyNCwgNjQyNjQsIDY0MzA0LCA2NDM0NCwKKzY0Mzg0LCA2NDQyNCwgNjQ0NjQsIDY0NTA0LCA2NDU0NCwgNjQ1ODQsIDY0NjI0LCA2NDY2NCwgNjQ3MDQsIDY0NzQ0LCA2NDc4NCwgNjQ4MjQsIDY0ODY0LCA2NDkwNCwgNjQ5NDQsIDY0OTg0LAorNjUwMjQsIDY1MDY0LCA2NTEwNCwgNjUxNDQsIDY1MTg0LCA2NTIyNCwgNjUyNjQsIDY1MzA0LCA2NTM0NCwgNjUzODQsIDY1NDI0LCA2NTQ2NCwgNjU1MDQKKyAgICAgICAgICAgIH0pOworCisgICAgICAgIHRlc3RCeXRlcyA9IHRoZXNlQnl0ZXMobmV3IGludFtdeworMjU0LCAyNTUsIDAsIDAsIDAsIDEsIDAsIDIsIDAsIDMsIDAsIDQsIDAsIDUsIDAsIDYsCiswLCA3LCAwLCA4LCAwLCA5LCAwLCAxMCwgMCwgMTEsIDAsIDEyLCAwLCAxMywgMCwgMTQsCiswLCAxNSwgMCwgMTYsIDAsIDE3LCAwLCAxOCwgMCwgMTksIDAsIDIwLCAwLCAyMSwgMCwgMjIsCiswLCAyMywgMCwgMjQsIDAsIDI1LCAwLCAyNiwgMCwgMjcsIDAsIDI4LCAwLCAyOSwgMCwgMzAsCiswLCAzMSwgMCwgMzIsIDAsIDMzLCAwLCAzNCwgMCwgMzUsIDAsIDM2LCAwLCAzNywgMCwgMzgsCiswLCAzOSwgMCwgNDAsIDAsIDQxLCAwLCA0MiwgMCwgNDMsIDAsIDQ0LCAwLCA0NSwgMCwgNDYsCiswLCA0NywgMCwgNDgsIDAsIDQ5LCAwLCA1MCwgMCwgNTEsIDAsIDUyLCAwLCA1MywgMCwgNTQsCiswLCA1NSwgMCwgNTYsIDAsIDU3LCAwLCA1OCwgMCwgNTksIDAsIDYwLCAwLCA2MSwgMCwgNjIsCiswLCA2MywgMCwgNjQsIDAsIDY1LCAwLCA2NiwgMCwgNjcsIDAsIDY4LCAwLCA2OSwgMCwgNzAsCiswLCA3MSwgMCwgNzIsIDAsIDczLCAwLCA3NCwgMCwgNzUsIDAsIDc2LCAwLCA3NywgMCwgNzgsCiswLCA3OSwgMCwgODAsIDAsIDgxLCAwLCA4MiwgMCwgODMsIDAsIDg0LCAwLCA4NSwgMCwgODYsCiswLCA4NywgMCwgODgsIDAsIDg5LCAwLCA5MCwgMCwgOTEsIDAsIDkyLCAwLCA5MywgMCwgOTQsCiswLCA5NSwgMCwgOTYsIDAsIDk3LCAwLCA5OCwgMCwgOTksIDAsIDEwMCwgMCwgMTAxLCAwLCAxMDIsCiswLCAxMDMsIDAsIDEwNCwgMCwgMTA1LCAwLCAxMDYsIDAsIDEwNywgMCwgMTA4LCAwLCAxMDksIDAsIDExMCwKKzAsIDExMSwgMCwgMTEyLCAwLCAxMTMsIDAsIDExNCwgMCwgMTE1LCAwLCAxMTYsIDAsIDExNywgMCwgMTE4LAorMCwgMTE5LCAwLCAxMjAsIDAsIDEyMSwgMCwgMTIyLCAwLCAxMjMsIDAsIDEyNCwgMCwgMTI1LCAwLCAxMjYsCiswLCAxMjcsIDAsIDEyOCwgMCwgMTI5LCAwLCAxMzAsIDAsIDEzMSwgMCwgMTMyLCAwLCAxMzMsIDAsIDEzNCwKKzAsIDEzNSwgMCwgMTM2LCAwLCAxMzcsIDAsIDEzOCwgMCwgMTM5LCAwLCAxNDAsIDAsIDE0MSwgMCwgMTQyLAorMCwgMTQzLCAwLCAxNDQsIDAsIDE0NSwgMCwgMTQ2LCAwLCAxNDcsIDAsIDE0OCwgMCwgMTQ5LCAwLCAxNTAsCiswLCAxNTEsIDAsIDE1MiwgMCwgMTUzLCAwLCAxNTQsIDAsIDE1NSwgMCwgMTU2LCAwLCAxNTcsIDAsIDE1OCwKKzAsIDE1OSwgMCwgMTYwLCAwLCAxNjEsIDAsIDE2MiwgMCwgMTYzLCAwLCAxNjQsIDAsIDE2NSwgMCwgMTY2LAorMCwgMTY3LCAwLCAxNjgsIDAsIDE2OSwgMCwgMTcwLCAwLCAxNzEsIDAsIDE3MiwgMCwgMTczLCAwLCAxNzQsCiswLCAxNzUsIDAsIDE3NiwgMCwgMTc3LCAwLCAxNzgsIDAsIDE3OSwgMCwgMTgwLCAwLCAxODEsIDAsIDE4MiwKKzAsIDE4MywgMCwgMTg0LCAwLCAxODUsIDAsIDE4NiwgMCwgMTg3LCAwLCAxODgsIDAsIDE4OSwgMCwgMTkwLAorMCwgMTkxLCAwLCAxOTIsIDAsIDE5MywgMCwgMTk0LCAwLCAxOTUsIDAsIDE5NiwgMCwgMTk3LCAwLCAxOTgsCiswLCAxOTksIDAsIDIwMCwgMCwgMjAxLCAwLCAyMDIsIDAsIDIwMywgMCwgMjA0LCAwLCAyMDUsIDAsIDIwNiwKKzAsIDIwNywgMCwgMjA4LCAwLCAyMDksIDAsIDIxMCwgMCwgMjExLCAwLCAyMTIsIDAsIDIxMywgMCwgMjE0LAorMCwgMjE1LCAwLCAyMTYsIDAsIDIxNywgMCwgMjE4LCAwLCAyMTksIDAsIDIyMCwgMCwgMjIxLCAwLCAyMjIsCiswLCAyMjMsIDAsIDIyNCwgMCwgMjI1LCAwLCAyMjYsIDAsIDIyNywgMCwgMjI4LCAwLCAyMjksIDAsIDIzMCwKKzAsIDIzMSwgMCwgMjMyLCAwLCAyMzMsIDAsIDIzNCwgMCwgMjM1LCAwLCAyMzYsIDAsIDIzNywgMCwgMjM4LAorMCwgMjM5LCAwLCAyNDAsIDAsIDI0MSwgMCwgMjQyLCAwLCAyNDMsIDAsIDI0NCwgMCwgMjQ1LCAwLCAyNDYsCiswLCAyNDcsIDAsIDI0OCwgMCwgMjQ5LCAwLCAyNTAsIDAsIDI1MSwgMCwgMjUyLCAwLCAyNTMsIDAsIDI1NCwKKzAsIDI1NSwgMSwgMCwgMSwgNDAsIDEsIDgwLCAxLCAxMjAsIDEsIDE2MCwgMSwgMjAwLCAxLCAyNDAsCisyLCAyNCwgMiwgNjQsIDIsIDEwNCwgMiwgMTQ0LCAyLCAxODQsIDIsIDIyNCwgMywgOCwgMywgNDgsCiszLCA4OCwgMywgMTI4LCAzLCAxNjgsIDMsIDIwOCwgMywgMjQ4LCA0LCAzMiwgNCwgNzIsIDQsIDExMiwKKzQsIDE1MiwgNCwgMTkyLCA0LCAyMzIsIDUsIDE2LCA1LCA1NiwgNSwgOTYsIDUsIDEzNiwgNSwgMTc2LAorNSwgMjE2LCA2LCAwLCA2LCA0MCwgNiwgODAsIDYsIDEyMCwgNiwgMTYwLCA2LCAyMDAsIDYsIDI0MCwKKzcsIDI0LCA3LCA2NCwgNywgMTA0LCA3LCAxNDQsIDcsIDE4NCwgNywgMjI0LCA4LCA4LCA4LCA0OCwKKzgsIDg4LCA4LCAxMjgsIDgsIDE2OCwgOCwgMjA4LCA4LCAyNDgsIDksIDMyLCA5LCA3MiwgOSwgMTEyLAorOSwgMTUyLCA5LCAxOTIsIDksIDIzMiwgMTAsIDE2LCAxMCwgNTYsIDEwLCA5NiwgMTAsIDEzNiwgMTAsIDE3NiwKKzEwLCAyMTYsIDExLCAwLCAxMSwgNDAsIDExLCA4MCwgMTEsIDEyMCwgMTEsIDE2MCwgMTEsIDIwMCwgMTEsIDI0MCwKKzEyLCAyNCwgMTIsIDY0LCAxMiwgMTA0LCAxMiwgMTQ0LCAxMiwgMTg0LCAxMiwgMjI0LCAxMywgOCwgMTMsIDQ4LAorMTMsIDg4LCAxMywgMTI4LCAxMywgMTY4LCAxMywgMjA4LCAxMywgMjQ4LCAxNCwgMzIsIDE0LCA3MiwgMTQsIDExMiwKKzE0LCAxNTIsIDE0LCAxOTIsIDE0LCAyMzIsIDE1LCAxNiwgMTUsIDU2LCAxNSwgOTYsIDE1LCAxMzYsIDE1LCAxNzYsCisxNSwgMjE2LCAxNiwgMCwgMTYsIDQwLCAxNiwgODAsIDE2LCAxMjAsIDE2LCAxNjAsIDE2LCAyMDAsIDE2LCAyNDAsCisxNywgMjQsIDE3LCA2NCwgMTcsIDEwNCwgMTcsIDE0NCwgMTcsIDE4NCwgMTcsIDIyNCwgMTgsIDgsIDE4LCA0OCwKKzE4LCA4OCwgMTgsIDEyOCwgMTgsIDE2OCwgMTgsIDIwOCwgMTgsIDI0OCwgMTksIDMyLCAxOSwgNzIsIDE5LCAxMTIsCisxOSwgMTUyLCAxOSwgMTkyLCAxOSwgMjMyLCAyMCwgMTYsIDIwLCA1NiwgMjAsIDk2LCAyMCwgMTM2LCAyMCwgMTc2LAorMjAsIDIxNiwgMjEsIDAsIDIxLCA0MCwgMjEsIDgwLCAyMSwgMTIwLCAyMSwgMTYwLCAyMSwgMjAwLCAyMSwgMjQwLAorMjIsIDI0LCAyMiwgNjQsIDIyLCAxMDQsIDIyLCAxNDQsIDIyLCAxODQsIDIyLCAyMjQsIDIzLCA4LCAyMywgNDgsCisyMywgODgsIDIzLCAxMjgsIDIzLCAxNjgsIDIzLCAyMDgsIDIzLCAyNDgsIDI0LCAzMiwgMjQsIDcyLCAyNCwgMTEyLAorMjQsIDE1MiwgMjQsIDE5MiwgMjQsIDIzMiwgMjUsIDE2LCAyNSwgNTYsIDI1LCA5NiwgMjUsIDEzNiwgMjUsIDE3NiwKKzI1LCAyMTYsIDI2LCAwLCAyNiwgNDAsIDI2LCA4MCwgMjYsIDEyMCwgMjYsIDE2MCwgMjYsIDIwMCwgMjYsIDI0MCwKKzI3LCAyNCwgMjcsIDY0LCAyNywgMTA0LCAyNywgMTQ0LCAyNywgMTg0LCAyNywgMjI0LCAyOCwgOCwgMjgsIDQ4LAorMjgsIDg4LCAyOCwgMTI4LCAyOCwgMTY4LCAyOCwgMjA4LCAyOCwgMjQ4LCAyOSwgMzIsIDI5LCA3MiwgMjksIDExMiwKKzI5LCAxNTIsIDI5LCAxOTIsIDI5LCAyMzIsIDMwLCAxNiwgMzAsIDU2LCAzMCwgOTYsIDMwLCAxMzYsIDMwLCAxNzYsCiszMCwgMjE2LCAzMSwgMCwgMzEsIDQwLCAzMSwgODAsIDMxLCAxMjAsIDMxLCAxNjAsIDMxLCAyMDAsIDMxLCAyNDAsCiszMiwgMjQsIDMyLCA2NCwgMzIsIDEwNCwgMzIsIDE0NCwgMzIsIDE4NCwgMzIsIDIyNCwgMzMsIDgsIDMzLCA0OCwKKzMzLCA4OCwgMzMsIDEyOCwgMzMsIDE2OCwgMzMsIDIwOCwgMzMsIDI0OCwgMzQsIDMyLCAzNCwgNzIsIDM0LCAxMTIsCiszNCwgMTUyLCAzNCwgMTkyLCAzNCwgMjMyLCAzNSwgMTYsIDM1LCA1NiwgMzUsIDk2LCAzNSwgMTM2LCAzNSwgMTc2LAorMzUsIDIxNiwgMzYsIDAsIDM2LCA0MCwgMzYsIDgwLCAzNiwgMTIwLCAzNiwgMTYwLCAzNiwgMjAwLCAzNiwgMjQwLAorMzcsIDI0LCAzNywgNjQsIDM3LCAxMDQsIDM3LCAxNDQsIDM3LCAxODQsIDM3LCAyMjQsIDM4LCA4LCAzOCwgNDgsCiszOCwgODgsIDM4LCAxMjgsIDM4LCAxNjgsIDM4LCAyMDgsIDM4LCAyNDgsIDM5LCAzMiwgMzksIDcyLCAzOSwgMTEyLAorMzksIDE1MiwgMzksIDE5MiwgMzksIDIzMiwgNDAsIDE2LCA0MCwgNTYsIDQwLCA5NiwgNDAsIDEzNiwgNDAsIDE3NiwKKzQwLCAyMTYsIDQxLCAwLCA0MSwgNDAsIDQxLCA4MCwgNDEsIDEyMCwgNDEsIDE2MCwgNDEsIDIwMCwgNDEsIDI0MCwKKzQyLCAyNCwgNDIsIDY0LCA0MiwgMTA0LCA0MiwgMTQ0LCA0MiwgMTg0LCA0MiwgMjI0LCA0MywgOCwgNDMsIDQ4LAorNDMsIDg4LCA0MywgMTI4LCA0MywgMTY4LCA0MywgMjA4LCA0MywgMjQ4LCA0NCwgMzIsIDQ0LCA3MiwgNDQsIDExMiwKKzQ0LCAxNTIsIDQ0LCAxOTIsIDQ0LCAyMzIsIDQ1LCAxNiwgNDUsIDU2LCA0NSwgOTYsIDQ1LCAxMzYsIDQ1LCAxNzYsCis0NSwgMjE2LCA0NiwgMCwgNDYsIDQwLCA0NiwgODAsIDQ2LCAxMjAsIDQ2LCAxNjAsIDQ2LCAyMDAsIDQ2LCAyNDAsCis0NywgMjQsIDQ3LCA2NCwgNDcsIDEwNCwgNDcsIDE0NCwgNDcsIDE4NCwgNDcsIDIyNCwgNDgsIDgsIDQ4LCA0OCwKKzQ4LCA4OCwgNDgsIDEyOCwgNDgsIDE2OCwgNDgsIDIwOCwgNDgsIDI0OCwgNDksIDMyLCA0OSwgNzIsIDQ5LCAxMTIsCis0OSwgMTUyLCA0OSwgMTkyLCA0OSwgMjMyLCA1MCwgMTYsIDUwLCA1NiwgNTAsIDk2LCA1MCwgMTM2LCA1MCwgMTc2LAorNTAsIDIxNiwgNTEsIDAsIDUxLCA0MCwgNTEsIDgwLCA1MSwgMTIwLCA1MSwgMTYwLCA1MSwgMjAwLCA1MSwgMjQwLAorNTIsIDI0LCA1MiwgNjQsIDUyLCAxMDQsIDUyLCAxNDQsIDUyLCAxODQsIDUyLCAyMjQsIDUzLCA4LCA1MywgNDgsCis1MywgODgsIDUzLCAxMjgsIDUzLCAxNjgsIDUzLCAyMDgsIDUzLCAyNDgsIDU0LCAzMiwgNTQsIDcyLCA1NCwgMTEyLAorNTQsIDE1MiwgNTQsIDE5MiwgNTQsIDIzMiwgNTUsIDE2LCA1NSwgNTYsIDU1LCA5NiwgNTUsIDEzNiwgNTUsIDE3NiwKKzU1LCAyMTYsIDU2LCAwLCA1NiwgNDAsIDU2LCA4MCwgNTYsIDEyMCwgNTYsIDE2MCwgNTYsIDIwMCwgNTYsIDI0MCwKKzU3LCAyNCwgNTcsIDY0LCA1NywgMTA0LCA1NywgMTQ0LCA1NywgMTg0LCA1NywgMjI0LCA1OCwgOCwgNTgsIDQ4LAorNTgsIDg4LCA1OCwgMTI4LCA1OCwgMTY4LCA1OCwgMjA4LCA1OCwgMjQ4LCA1OSwgMzIsIDU5LCA3MiwgNTksIDExMiwKKzU5LCAxNTIsIDU5LCAxOTIsIDU5LCAyMzIsIDYwLCAxNiwgNjAsIDU2LCA2MCwgOTYsIDYwLCAxMzYsIDYwLCAxNzYsCis2MCwgMjE2LCA2MSwgMCwgNjEsIDQwLCA2MSwgODAsIDYxLCAxMjAsIDYxLCAxNjAsIDYxLCAyMDAsIDYxLCAyNDAsCis2MiwgMjQsIDYyLCA2NCwgNjIsIDEwNCwgNjIsIDE0NCwgNjIsIDE4NCwgNjIsIDIyNCwgNjMsIDgsIDYzLCA0OCwKKzYzLCA4OCwgNjMsIDEyOCwgNjMsIDE2OCwgNjMsIDIwOCwgNjMsIDI0OCwgNjQsIDMyLCA2NCwgNzIsIDY0LCAxMTIsCis2NCwgMTUyLCA2NCwgMTkyLCA2NCwgMjMyLCA2NSwgMTYsIDY1LCA1NiwgNjUsIDk2LCA2NSwgMTM2LCA2NSwgMTc2LAorNjUsIDIxNiwgNjYsIDAsIDY2LCA0MCwgNjYsIDgwLCA2NiwgMTIwLCA2NiwgMTYwLCA2NiwgMjAwLCA2NiwgMjQwLAorNjcsIDI0LCA2NywgNjQsIDY3LCAxMDQsIDY3LCAxNDQsIDY3LCAxODQsIDY3LCAyMjQsIDY4LCA4LCA2OCwgNDgsCis2OCwgODgsIDY4LCAxMjgsIDY4LCAxNjgsIDY4LCAyMDgsIDY4LCAyNDgsIDY5LCAzMiwgNjksIDcyLCA2OSwgMTEyLAorNjksIDE1MiwgNjksIDE5MiwgNjksIDIzMiwgNzAsIDE2LCA3MCwgNTYsIDcwLCA5NiwgNzAsIDEzNiwgNzAsIDE3NiwKKzcwLCAyMTYsIDcxLCAwLCA3MSwgNDAsIDcxLCA4MCwgNzEsIDEyMCwgNzEsIDE2MCwgNzEsIDIwMCwgNzEsIDI0MCwKKzcyLCAyNCwgNzIsIDY0LCA3MiwgMTA0LCA3MiwgMTQ0LCA3MiwgMTg0LCA3MiwgMjI0LCA3MywgOCwgNzMsIDQ4LAorNzMsIDg4LCA3MywgMTI4LCA3MywgMTY4LCA3MywgMjA4LCA3MywgMjQ4LCA3NCwgMzIsIDc0LCA3MiwgNzQsIDExMiwKKzc0LCAxNTIsIDc0LCAxOTIsIDc0LCAyMzIsIDc1LCAxNiwgNzUsIDU2LCA3NSwgOTYsIDc1LCAxMzYsIDc1LCAxNzYsCis3NSwgMjE2LCA3NiwgMCwgNzYsIDQwLCA3NiwgODAsIDc2LCAxMjAsIDc2LCAxNjAsIDc2LCAyMDAsIDc2LCAyNDAsCis3NywgMjQsIDc3LCA2NCwgNzcsIDEwNCwgNzcsIDE0NCwgNzcsIDE4NCwgNzcsIDIyNCwgNzgsIDgsIDc4LCA0OCwKKzc4LCA4OCwgNzgsIDEyOCwgNzgsIDE2OCwgNzgsIDIwOCwgNzgsIDI0OCwgNzksIDMyLCA3OSwgNzIsIDc5LCAxMTIsCis3OSwgMTUyLCA3OSwgMTkyLCA3OSwgMjMyLCA4MCwgMTYsIDgwLCA1NiwgODAsIDk2LCA4MCwgMTM2LCA4MCwgMTc2LAorODAsIDIxNiwgODEsIDAsIDgxLCA0MCwgODEsIDgwLCA4MSwgMTIwLCA4MSwgMTYwLCA4MSwgMjAwLCA4MSwgMjQwLAorODIsIDI0LCA4MiwgNjQsIDgyLCAxMDQsIDgyLCAxNDQsIDgyLCAxODQsIDgyLCAyMjQsIDgzLCA4LCA4MywgNDgsCis4MywgODgsIDgzLCAxMjgsIDgzLCAxNjgsIDgzLCAyMDgsIDgzLCAyNDgsIDg0LCAzMiwgODQsIDcyLCA4NCwgMTEyLAorODQsIDE1MiwgODQsIDE5MiwgODQsIDIzMiwgODUsIDE2LCA4NSwgNTYsIDg1LCA5NiwgODUsIDEzNiwgODUsIDE3NiwKKzg1LCAyMTYsIDg2LCAwLCA4NiwgNDAsIDg2LCA4MCwgODYsIDEyMCwgODYsIDE2MCwgODYsIDIwMCwgODYsIDI0MCwKKzg3LCAyNCwgODcsIDY0LCA4NywgMTA0LCA4NywgMTQ0LCA4NywgMTg0LCA4NywgMjI0LCA4OCwgOCwgODgsIDQ4LAorODgsIDg4LCA4OCwgMTI4LCA4OCwgMTY4LCA4OCwgMjA4LCA4OCwgMjQ4LCA4OSwgMzIsIDg5LCA3MiwgODksIDExMiwKKzg5LCAxNTIsIDg5LCAxOTIsIDg5LCAyMzIsIDkwLCAxNiwgOTAsIDU2LCA5MCwgOTYsIDkwLCAxMzYsIDkwLCAxNzYsCis5MCwgMjE2LCA5MSwgMCwgOTEsIDQwLCA5MSwgODAsIDkxLCAxMjAsIDkxLCAxNjAsIDkxLCAyMDAsIDkxLCAyNDAsCis5MiwgMjQsIDkyLCA2NCwgOTIsIDEwNCwgOTIsIDE0NCwgOTIsIDE4NCwgOTIsIDIyNCwgOTMsIDgsIDkzLCA0OCwKKzkzLCA4OCwgOTMsIDEyOCwgOTMsIDE2OCwgOTMsIDIwOCwgOTMsIDI0OCwgOTQsIDMyLCA5NCwgNzIsIDk0LCAxMTIsCis5NCwgMTUyLCA5NCwgMTkyLCA5NCwgMjMyLCA5NSwgMTYsIDk1LCA1NiwgOTUsIDk2LCA5NSwgMTM2LCA5NSwgMTc2LAorOTUsIDIxNiwgOTYsIDAsIDk2LCA0MCwgOTYsIDgwLCA5NiwgMTIwLCA5NiwgMTYwLCA5NiwgMjAwLCA5NiwgMjQwLAorOTcsIDI0LCA5NywgNjQsIDk3LCAxMDQsIDk3LCAxNDQsIDk3LCAxODQsIDk3LCAyMjQsIDk4LCA4LCA5OCwgNDgsCis5OCwgODgsIDk4LCAxMjgsIDk4LCAxNjgsIDk4LCAyMDgsIDk4LCAyNDgsIDk5LCAzMiwgOTksIDcyLCA5OSwgMTEyLAorOTksIDE1MiwgOTksIDE5MiwgOTksIDIzMiwgMTAwLCAxNiwgMTAwLCA1NiwgMTAwLCA5NiwgMTAwLCAxMzYsIDEwMCwgMTc2LAorMTAwLCAyMTYsIDEwMSwgMCwgMTAxLCA0MCwgMTAxLCA4MCwgMTAxLCAxMjAsIDEwMSwgMTYwLCAxMDEsIDIwMCwgMTAxLCAyNDAsCisxMDIsIDI0LCAxMDIsIDY0LCAxMDIsIDEwNCwgMTAyLCAxNDQsIDEwMiwgMTg0LCAxMDIsIDIyNCwgMTAzLCA4LCAxMDMsIDQ4LAorMTAzLCA4OCwgMTAzLCAxMjgsIDEwMywgMTY4LCAxMDMsIDIwOCwgMTAzLCAyNDgsIDEwNCwgMzIsIDEwNCwgNzIsIDEwNCwgMTEyLAorMTA0LCAxNTIsIDEwNCwgMTkyLCAxMDQsIDIzMiwgMTA1LCAxNiwgMTA1LCA1NiwgMTA1LCA5NiwgMTA1LCAxMzYsIDEwNSwgMTc2LAorMTA1LCAyMTYsIDEwNiwgMCwgMTA2LCA0MCwgMTA2LCA4MCwgMTA2LCAxMjAsIDEwNiwgMTYwLCAxMDYsIDIwMCwgMTA2LCAyNDAsCisxMDcsIDI0LCAxMDcsIDY0LCAxMDcsIDEwNCwgMTA3LCAxNDQsIDEwNywgMTg0LCAxMDcsIDIyNCwgMTA4LCA4LCAxMDgsIDQ4LAorMTA4LCA4OCwgMTA4LCAxMjgsIDEwOCwgMTY4LCAxMDgsIDIwOCwgMTA4LCAyNDgsIDEwOSwgMzIsIDEwOSwgNzIsIDEwOSwgMTEyLAorMTA5LCAxNTIsIDEwOSwgMTkyLCAxMDksIDIzMiwgMTEwLCAxNiwgMTEwLCA1NiwgMTEwLCA5NiwgMTEwLCAxMzYsIDExMCwgMTc2LAorMTEwLCAyMTYsIDExMSwgMCwgMTExLCA0MCwgMTExLCA4MCwgMTExLCAxMjAsIDExMSwgMTYwLCAxMTEsIDIwMCwgMTExLCAyNDAsCisxMTIsIDI0LCAxMTIsIDY0LCAxMTIsIDEwNCwgMTEyLCAxNDQsIDExMiwgMTg0LCAxMTIsIDIyNCwgMTEzLCA4LCAxMTMsIDQ4LAorMTEzLCA4OCwgMTEzLCAxMjgsIDExMywgMTY4LCAxMTMsIDIwOCwgMTEzLCAyNDgsIDExNCwgMzIsIDExNCwgNzIsIDExNCwgMTEyLAorMTE0LCAxNTIsIDExNCwgMTkyLCAxMTQsIDIzMiwgMTE1LCAxNiwgMTE1LCA1NiwgMTE1LCA5NiwgMTE1LCAxMzYsIDExNSwgMTc2LAorMTE1LCAyMTYsIDExNiwgMCwgMTE2LCA0MCwgMTE2LCA4MCwgMTE2LCAxMjAsIDExNiwgMTYwLCAxMTYsIDIwMCwgMTE2LCAyNDAsCisxMTcsIDI0LCAxMTcsIDY0LCAxMTcsIDEwNCwgMTE3LCAxNDQsIDExNywgMTg0LCAxMTcsIDIyNCwgMTE4LCA4LCAxMTgsIDQ4LAorMTE4LCA4OCwgMTE4LCAxMjgsIDExOCwgMTY4LCAxMTgsIDIwOCwgMTE4LCAyNDgsIDExOSwgMzIsIDExOSwgNzIsIDExOSwgMTEyLAorMTE5LCAxNTIsIDExOSwgMTkyLCAxMTksIDIzMiwgMTIwLCAxNiwgMTIwLCA1NiwgMTIwLCA5NiwgMTIwLCAxMzYsIDEyMCwgMTc2LAorMTIwLCAyMTYsIDEyMSwgMCwgMTIxLCA0MCwgMTIxLCA4MCwgMTIxLCAxMjAsIDEyMSwgMTYwLCAxMjEsIDIwMCwgMTIxLCAyNDAsCisxMjIsIDI0LCAxMjIsIDY0LCAxMjIsIDEwNCwgMTIyLCAxNDQsIDEyMiwgMTg0LCAxMjIsIDIyNCwgMTIzLCA4LCAxMjMsIDQ4LAorMTIzLCA4OCwgMTIzLCAxMjgsIDEyMywgMTY4LCAxMjMsIDIwOCwgMTIzLCAyNDgsIDEyNCwgMzIsIDEyNCwgNzIsIDEyNCwgMTEyLAorMTI0LCAxNTIsIDEyNCwgMTkyLCAxMjQsIDIzMiwgMTI1LCAxNiwgMTI1LCA1NiwgMTI1LCA5NiwgMTI1LCAxMzYsIDEyNSwgMTc2LAorMTI1LCAyMTYsIDEyNiwgMCwgMTI2LCA0MCwgMTI2LCA4MCwgMTI2LCAxMjAsIDEyNiwgMTYwLCAxMjYsIDIwMCwgMTI2LCAyNDAsCisxMjcsIDI0LCAxMjcsIDY0LCAxMjcsIDEwNCwgMTI3LCAxNDQsIDEyNywgMTg0LCAxMjcsIDIyNCwgMTI4LCA4LCAxMjgsIDQ4LAorMTI4LCA4OCwgMTI4LCAxMjgsIDEyOCwgMTY4LCAxMjgsIDIwOCwgMTI4LCAyNDgsIDEyOSwgMzIsIDEyOSwgNzIsIDEyOSwgMTEyLAorMTI5LCAxNTIsIDEyOSwgMTkyLCAxMjksIDIzMiwgMTMwLCAxNiwgMTMwLCA1NiwgMTMwLCA5NiwgMTMwLCAxMzYsIDEzMCwgMTc2LAorMTMwLCAyMTYsIDEzMSwgMCwgMTMxLCA0MCwgMTMxLCA4MCwgMTMxLCAxMjAsIDEzMSwgMTYwLCAxMzEsIDIwMCwgMTMxLCAyNDAsCisxMzIsIDI0LCAxMzIsIDY0LCAxMzIsIDEwNCwgMTMyLCAxNDQsIDEzMiwgMTg0LCAxMzIsIDIyNCwgMTMzLCA4LCAxMzMsIDQ4LAorMTMzLCA4OCwgMTMzLCAxMjgsIDEzMywgMTY4LCAxMzMsIDIwOCwgMTMzLCAyNDgsIDEzNCwgMzIsIDEzNCwgNzIsIDEzNCwgMTEyLAorMTM0LCAxNTIsIDEzNCwgMTkyLCAxMzQsIDIzMiwgMTM1LCAxNiwgMTM1LCA1NiwgMTM1LCA5NiwgMTM1LCAxMzYsIDEzNSwgMTc2LAorMTM1LCAyMTYsIDEzNiwgMCwgMTM2LCA0MCwgMTM2LCA4MCwgMTM2LCAxMjAsIDEzNiwgMTYwLCAxMzYsIDIwMCwgMTM2LCAyNDAsCisxMzcsIDI0LCAxMzcsIDY0LCAxMzcsIDEwNCwgMTM3LCAxNDQsIDEzNywgMTg0LCAxMzcsIDIyNCwgMTM4LCA4LCAxMzgsIDQ4LAorMTM4LCA4OCwgMTM4LCAxMjgsIDEzOCwgMTY4LCAxMzgsIDIwOCwgMTM4LCAyNDgsIDEzOSwgMzIsIDEzOSwgNzIsIDEzOSwgMTEyLAorMTM5LCAxNTIsIDEzOSwgMTkyLCAxMzksIDIzMiwgMTQwLCAxNiwgMTQwLCA1NiwgMTQwLCA5NiwgMTQwLCAxMzYsIDE0MCwgMTc2LAorMTQwLCAyMTYsIDE0MSwgMCwgMTQxLCA0MCwgMTQxLCA4MCwgMTQxLCAxMjAsIDE0MSwgMTYwLCAxNDEsIDIwMCwgMTQxLCAyNDAsCisxNDIsIDI0LCAxNDIsIDY0LCAxNDIsIDEwNCwgMTQyLCAxNDQsIDE0MiwgMTg0LCAxNDIsIDIyNCwgMTQzLCA4LCAxNDMsIDQ4LAorMTQzLCA4OCwgMTQzLCAxMjgsIDE0MywgMTY4LCAxNDMsIDIwOCwgMTQzLCAyNDgsIDE0NCwgMzIsIDE0NCwgNzIsIDE0NCwgMTEyLAorMTQ0LCAxNTIsIDE0NCwgMTkyLCAxNDQsIDIzMiwgMTQ1LCAxNiwgMTQ1LCA1NiwgMTQ1LCA5NiwgMTQ1LCAxMzYsIDE0NSwgMTc2LAorMTQ1LCAyMTYsIDE0NiwgMCwgMTQ2LCA0MCwgMTQ2LCA4MCwgMTQ2LCAxMjAsIDE0NiwgMTYwLCAxNDYsIDIwMCwgMTQ2LCAyNDAsCisxNDcsIDI0LCAxNDcsIDY0LCAxNDcsIDEwNCwgMTQ3LCAxNDQsIDE0NywgMTg0LCAxNDcsIDIyNCwgMTQ4LCA4LCAxNDgsIDQ4LAorMTQ4LCA4OCwgMTQ4LCAxMjgsIDE0OCwgMTY4LCAxNDgsIDIwOCwgMTQ4LCAyNDgsIDE0OSwgMzIsIDE0OSwgNzIsIDE0OSwgMTEyLAorMTQ5LCAxNTIsIDE0OSwgMTkyLCAxNDksIDIzMiwgMTUwLCAxNiwgMTUwLCA1NiwgMTUwLCA5NiwgMTUwLCAxMzYsIDE1MCwgMTc2LAorMTUwLCAyMTYsIDE1MSwgMCwgMTUxLCA0MCwgMTUxLCA4MCwgMTUxLCAxMjAsIDE1MSwgMTYwLCAxNTEsIDIwMCwgMTUxLCAyNDAsCisxNTIsIDI0LCAxNTIsIDY0LCAxNTIsIDEwNCwgMTUyLCAxNDQsIDE1MiwgMTg0LCAxNTIsIDIyNCwgMTUzLCA4LCAxNTMsIDQ4LAorMTUzLCA4OCwgMTUzLCAxMjgsIDE1MywgMTY4LCAxNTMsIDIwOCwgMTUzLCAyNDgsIDE1NCwgMzIsIDE1NCwgNzIsIDE1NCwgMTEyLAorMTU0LCAxNTIsIDE1NCwgMTkyLCAxNTQsIDIzMiwgMTU1LCAxNiwgMTU1LCA1NiwgMTU1LCA5NiwgMTU1LCAxMzYsIDE1NSwgMTc2LAorMTU1LCAyMTYsIDE1NiwgMCwgMTU2LCA0MCwgMTU2LCA4MCwgMTU2LCAxMjAsIDE1NiwgMTYwLCAxNTYsIDIwMCwgMTU2LCAyNDAsCisxNTcsIDI0LCAxNTcsIDY0LCAxNTcsIDEwNCwgMTU3LCAxNDQsIDE1NywgMTg0LCAxNTcsIDIyNCwgMTU4LCA4LCAxNTgsIDQ4LAorMTU4LCA4OCwgMTU4LCAxMjgsIDE1OCwgMTY4LCAxNTgsIDIwOCwgMTU4LCAyNDgsIDE1OSwgMzIsIDE1OSwgNzIsIDE1OSwgMTEyLAorMTU5LCAxNTIsIDE1OSwgMTkyLCAxNTksIDIzMiwgMTYwLCAxNiwgMTYwLCA1NiwgMTYwLCA5NiwgMTYwLCAxMzYsIDE2MCwgMTc2LAorMTYwLCAyMTYsIDE2MSwgMCwgMTYxLCA0MCwgMTYxLCA4MCwgMTYxLCAxMjAsIDE2MSwgMTYwLCAxNjEsIDIwMCwgMTYxLCAyNDAsCisxNjIsIDI0LCAxNjIsIDY0LCAxNjIsIDEwNCwgMTYyLCAxNDQsIDE2MiwgMTg0LCAxNjIsIDIyNCwgMTYzLCA4LCAxNjMsIDQ4LAorMTYzLCA4OCwgMTYzLCAxMjgsIDE2MywgMTY4LCAxNjMsIDIwOCwgMTYzLCAyNDgsIDE2NCwgMzIsIDE2NCwgNzIsIDE2NCwgMTEyLAorMTY0LCAxNTIsIDE2NCwgMTkyLCAxNjQsIDIzMiwgMTY1LCAxNiwgMTY1LCA1NiwgMTY1LCA5NiwgMTY1LCAxMzYsIDE2NSwgMTc2LAorMTY1LCAyMTYsIDE2NiwgMCwgMTY2LCA0MCwgMTY2LCA4MCwgMTY2LCAxMjAsIDE2NiwgMTYwLCAxNjYsIDIwMCwgMTY2LCAyNDAsCisxNjcsIDI0LCAxNjcsIDY0LCAxNjcsIDEwNCwgMTY3LCAxNDQsIDE2NywgMTg0LCAxNjcsIDIyNCwgMTY4LCA4LCAxNjgsIDQ4LAorMTY4LCA4OCwgMTY4LCAxMjgsIDE2OCwgMTY4LCAxNjgsIDIwOCwgMTY4LCAyNDgsIDE2OSwgMzIsIDE2OSwgNzIsIDE2OSwgMTEyLAorMTY5LCAxNTIsIDE2OSwgMTkyLCAxNjksIDIzMiwgMTcwLCAxNiwgMTcwLCA1NiwgMTcwLCA5NiwgMTcwLCAxMzYsIDE3MCwgMTc2LAorMTcwLCAyMTYsIDE3MSwgMCwgMTcxLCA0MCwgMTcxLCA4MCwgMTcxLCAxMjAsIDE3MSwgMTYwLCAxNzEsIDIwMCwgMTcxLCAyNDAsCisxNzIsIDI0LCAxNzIsIDY0LCAxNzIsIDEwNCwgMTcyLCAxNDQsIDE3MiwgMTg0LCAxNzIsIDIyNCwgMTczLCA4LCAxNzMsIDQ4LAorMTczLCA4OCwgMTczLCAxMjgsIDE3MywgMTY4LCAxNzMsIDIwOCwgMTczLCAyNDgsIDE3NCwgMzIsIDE3NCwgNzIsIDE3NCwgMTEyLAorMTc0LCAxNTIsIDE3NCwgMTkyLCAxNzQsIDIzMiwgMTc1LCAxNiwgMTc1LCA1NiwgMTc1LCA5NiwgMTc1LCAxMzYsIDE3NSwgMTc2LAorMTc1LCAyMTYsIDE3NiwgMCwgMTc2LCA0MCwgMTc2LCA4MCwgMTc2LCAxMjAsIDE3NiwgMTYwLCAxNzYsIDIwMCwgMTc2LCAyNDAsCisxNzcsIDI0LCAxNzcsIDY0LCAxNzcsIDEwNCwgMTc3LCAxNDQsIDE3NywgMTg0LCAxNzcsIDIyNCwgMTc4LCA4LCAxNzgsIDQ4LAorMTc4LCA4OCwgMTc4LCAxMjgsIDE3OCwgMTY4LCAxNzgsIDIwOCwgMTc4LCAyNDgsIDE3OSwgMzIsIDE3OSwgNzIsIDE3OSwgMTEyLAorMTc5LCAxNTIsIDE3OSwgMTkyLCAxNzksIDIzMiwgMTgwLCAxNiwgMTgwLCA1NiwgMTgwLCA5NiwgMTgwLCAxMzYsIDE4MCwgMTc2LAorMTgwLCAyMTYsIDE4MSwgMCwgMTgxLCA0MCwgMTgxLCA4MCwgMTgxLCAxMjAsIDE4MSwgMTYwLCAxODEsIDIwMCwgMTgxLCAyNDAsCisxODIsIDI0LCAxODIsIDY0LCAxODIsIDEwNCwgMTgyLCAxNDQsIDE4MiwgMTg0LCAxODIsIDIyNCwgMTgzLCA4LCAxODMsIDQ4LAorMTgzLCA4OCwgMTgzLCAxMjgsIDE4MywgMTY4LCAxODMsIDIwOCwgMTgzLCAyNDgsIDE4NCwgMzIsIDE4NCwgNzIsIDE4NCwgMTEyLAorMTg0LCAxNTIsIDE4NCwgMTkyLCAxODQsIDIzMiwgMTg1LCAxNiwgMTg1LCA1NiwgMTg1LCA5NiwgMTg1LCAxMzYsIDE4NSwgMTc2LAorMTg1LCAyMTYsIDE4NiwgMCwgMTg2LCA0MCwgMTg2LCA4MCwgMTg2LCAxMjAsIDE4NiwgMTYwLCAxODYsIDIwMCwgMTg2LCAyNDAsCisxODcsIDI0LCAxODcsIDY0LCAxODcsIDEwNCwgMTg3LCAxNDQsIDE4NywgMTg0LCAxODcsIDIyNCwgMTg4LCA4LCAxODgsIDQ4LAorMTg4LCA4OCwgMTg4LCAxMjgsIDE4OCwgMTY4LCAxODgsIDIwOCwgMTg4LCAyNDgsIDE4OSwgMzIsIDE4OSwgNzIsIDE4OSwgMTEyLAorMTg5LCAxNTIsIDE4OSwgMTkyLCAxODksIDIzMiwgMTkwLCAxNiwgMTkwLCA1NiwgMTkwLCA5NiwgMTkwLCAxMzYsIDE5MCwgMTc2LAorMTkwLCAyMTYsIDE5MSwgMCwgMTkxLCA0MCwgMTkxLCA4MCwgMTkxLCAxMjAsIDE5MSwgMTYwLCAxOTEsIDIwMCwgMTkxLCAyNDAsCisxOTIsIDI0LCAxOTIsIDY0LCAxOTIsIDEwNCwgMTkyLCAxNDQsIDE5MiwgMTg0LCAxOTIsIDIyNCwgMTkzLCA4LCAxOTMsIDQ4LAorMTkzLCA4OCwgMTkzLCAxMjgsIDE5MywgMTY4LCAxOTMsIDIwOCwgMTkzLCAyNDgsIDE5NCwgMzIsIDE5NCwgNzIsIDE5NCwgMTEyLAorMTk0LCAxNTIsIDE5NCwgMTkyLCAxOTQsIDIzMiwgMTk1LCAxNiwgMTk1LCA1NiwgMTk1LCA5NiwgMTk1LCAxMzYsIDE5NSwgMTc2LAorMTk1LCAyMTYsIDE5NiwgMCwgMTk2LCA0MCwgMTk2LCA4MCwgMTk2LCAxMjAsIDE5NiwgMTYwLCAxOTYsIDIwMCwgMTk2LCAyNDAsCisxOTcsIDI0LCAxOTcsIDY0LCAxOTcsIDEwNCwgMTk3LCAxNDQsIDE5NywgMTg0LCAxOTcsIDIyNCwgMTk4LCA4LCAxOTgsIDQ4LAorMTk4LCA4OCwgMTk4LCAxMjgsIDE5OCwgMTY4LCAxOTgsIDIwOCwgMTk4LCAyNDgsIDE5OSwgMzIsIDE5OSwgNzIsIDE5OSwgMTEyLAorMTk5LCAxNTIsIDE5OSwgMTkyLCAxOTksIDIzMiwgMjAwLCAxNiwgMjAwLCA1NiwgMjAwLCA5NiwgMjAwLCAxMzYsIDIwMCwgMTc2LAorMjAwLCAyMTYsIDIwMSwgMCwgMjAxLCA0MCwgMjAxLCA4MCwgMjAxLCAxMjAsIDIwMSwgMTYwLCAyMDEsIDIwMCwgMjAxLCAyNDAsCisyMDIsIDI0LCAyMDIsIDY0LCAyMDIsIDEwNCwgMjAyLCAxNDQsIDIwMiwgMTg0LCAyMDIsIDIyNCwgMjAzLCA4LCAyMDMsIDQ4LAorMjAzLCA4OCwgMjAzLCAxMjgsIDIwMywgMTY4LCAyMDMsIDIwOCwgMjAzLCAyNDgsIDIwNCwgMzIsIDIwNCwgNzIsIDIwNCwgMTEyLAorMjA0LCAxNTIsIDIwNCwgMTkyLCAyMDQsIDIzMiwgMjA1LCAxNiwgMjA1LCA1NiwgMjA1LCA5NiwgMjA1LCAxMzYsIDIwNSwgMTc2LAorMjA1LCAyMTYsIDIwNiwgMCwgMjA2LCA0MCwgMjA2LCA4MCwgMjA2LCAxMjAsIDIwNiwgMTYwLCAyMDYsIDIwMCwgMjA2LCAyNDAsCisyMDcsIDI0LCAyMDcsIDY0LCAyMDcsIDEwNCwgMjA3LCAxNDQsIDIwNywgMTg0LCAyMDcsIDIyNCwgMjA4LCA4LCAyMDgsIDQ4LAorMjA4LCA4OCwgMjA4LCAxMjgsIDIwOCwgMTY4LCAyMDgsIDIwOCwgMjA4LCAyNDgsIDIwOSwgMzIsIDIwOSwgNzIsIDIwOSwgMTEyLAorMjA5LCAxNTIsIDIwOSwgMTkyLCAyMDksIDIzMiwgMjEwLCAxNiwgMjEwLCA1NiwgMjEwLCA5NiwgMjEwLCAxMzYsIDIxMCwgMTc2LAorMjEwLCAyMTYsIDIxMSwgMCwgMjExLCA0MCwgMjExLCA4MCwgMjExLCAxMjAsIDIxMSwgMTYwLCAyMTEsIDIwMCwgMjExLCAyNDAsCisyMTIsIDI0LCAyMTIsIDY0LCAyMTIsIDEwNCwgMjEyLCAxNDQsIDIxMiwgMTg0LCAyMTIsIDIyNCwgMjEzLCA4LCAyMTMsIDQ4LAorMjEzLCA4OCwgMjEzLCAxMjgsIDIxMywgMTY4LCAyMTMsIDIwOCwgMjEzLCAyNDgsIDIxNCwgMzIsIDIxNCwgNzIsIDIxNCwgMTEyLAorMjE0LCAxNTIsIDIxNCwgMTkyLCAyMTQsIDIzMiwgMjE1LCAxNiwgMjE1LCA1NiwgMjE1LCA5NiwgMjE1LCAxMzYsIDIxNSwgMTc2LAorMjE1LCAyMTYsIDIyNCwgMCwgMjI0LCA0MCwgMjI0LCA4MCwgMjI0LCAxMjAsIDIyNCwgMTYwLCAyMjQsIDIwMCwgMjI0LCAyNDAsCisyMjUsIDI0LCAyMjUsIDY0LCAyMjUsIDEwNCwgMjI1LCAxNDQsIDIyNSwgMTg0LCAyMjUsIDIyNCwgMjI2LCA4LCAyMjYsIDQ4LAorMjI2LCA4OCwgMjI2LCAxMjgsIDIyNiwgMTY4LCAyMjYsIDIwOCwgMjI2LCAyNDgsIDIyNywgMzIsIDIyNywgNzIsIDIyNywgMTEyLAorMjI3LCAxNTIsIDIyNywgMTkyLCAyMjcsIDIzMiwgMjI4LCAxNiwgMjI4LCA1NiwgMjI4LCA5NiwgMjI4LCAxMzYsIDIyOCwgMTc2LAorMjI4LCAyMTYsIDIyOSwgMCwgMjI5LCA0MCwgMjI5LCA4MCwgMjI5LCAxMjAsIDIyOSwgMTYwLCAyMjksIDIwMCwgMjI5LCAyNDAsCisyMzAsIDI0LCAyMzAsIDY0LCAyMzAsIDEwNCwgMjMwLCAxNDQsIDIzMCwgMTg0LCAyMzAsIDIyNCwgMjMxLCA4LCAyMzEsIDQ4LAorMjMxLCA4OCwgMjMxLCAxMjgsIDIzMSwgMTY4LCAyMzEsIDIwOCwgMjMxLCAyNDgsIDIzMiwgMzIsIDIzMiwgNzIsIDIzMiwgMTEyLAorMjMyLCAxNTIsIDIzMiwgMTkyLCAyMzIsIDIzMiwgMjMzLCAxNiwgMjMzLCA1NiwgMjMzLCA5NiwgMjMzLCAxMzYsIDIzMywgMTc2LAorMjMzLCAyMTYsIDIzNCwgMCwgMjM0LCA0MCwgMjM0LCA4MCwgMjM0LCAxMjAsIDIzNCwgMTYwLCAyMzQsIDIwMCwgMjM0LCAyNDAsCisyMzUsIDI0LCAyMzUsIDY0LCAyMzUsIDEwNCwgMjM1LCAxNDQsIDIzNSwgMTg0LCAyMzUsIDIyNCwgMjM2LCA4LCAyMzYsIDQ4LAorMjM2LCA4OCwgMjM2LCAxMjgsIDIzNiwgMTY4LCAyMzYsIDIwOCwgMjM2LCAyNDgsIDIzNywgMzIsIDIzNywgNzIsIDIzNywgMTEyLAorMjM3LCAxNTIsIDIzNywgMTkyLCAyMzcsIDIzMiwgMjM4LCAxNiwgMjM4LCA1NiwgMjM4LCA5NiwgMjM4LCAxMzYsIDIzOCwgMTc2LAorMjM4LCAyMTYsIDIzOSwgMCwgMjM5LCA0MCwgMjM5LCA4MCwgMjM5LCAxMjAsIDIzOSwgMTYwLCAyMzksIDIwMCwgMjM5LCAyNDAsCisyNDAsIDI0LCAyNDAsIDY0LCAyNDAsIDEwNCwgMjQwLCAxNDQsIDI0MCwgMTg0LCAyNDAsIDIyNCwgMjQxLCA4LCAyNDEsIDQ4LAorMjQxLCA4OCwgMjQxLCAxMjgsIDI0MSwgMTY4LCAyNDEsIDIwOCwgMjQxLCAyNDgsIDI0MiwgMzIsIDI0MiwgNzIsIDI0MiwgMTEyLAorMjQyLCAxNTIsIDI0MiwgMTkyLCAyNDIsIDIzMiwgMjQzLCAxNiwgMjQzLCA1NiwgMjQzLCA5NiwgMjQzLCAxMzYsIDI0MywgMTc2LAorMjQzLCAyMTYsIDI0NCwgMCwgMjQ0LCA0MCwgMjQ0LCA4MCwgMjQ0LCAxMjAsIDI0NCwgMTYwLCAyNDQsIDIwMCwgMjQ0LCAyNDAsCisyNDUsIDI0LCAyNDUsIDY0LCAyNDUsIDEwNCwgMjQ1LCAxNDQsIDI0NSwgMTg0LCAyNDUsIDIyNCwgMjQ2LCA4LCAyNDYsIDQ4LAorMjQ2LCA4OCwgMjQ2LCAxMjgsIDI0NiwgMTY4LCAyNDYsIDIwOCwgMjQ2LCAyNDgsIDI0NywgMzIsIDI0NywgNzIsIDI0NywgMTEyLAorMjQ3LCAxNTIsIDI0NywgMTkyLCAyNDcsIDIzMiwgMjQ4LCAxNiwgMjQ4LCA1NiwgMjQ4LCA5NiwgMjQ4LCAxMzYsIDI0OCwgMTc2LAorMjQ4LCAyMTYsIDI0OSwgMCwgMjQ5LCA0MCwgMjQ5LCA4MCwgMjQ5LCAxMjAsIDI0OSwgMTYwLCAyNDksIDIwMCwgMjQ5LCAyNDAsCisyNTAsIDI0LCAyNTAsIDY0LCAyNTAsIDEwNCwgMjUwLCAxNDQsIDI1MCwgMTg0LCAyNTAsIDIyNCwgMjUxLCA4LCAyNTEsIDQ4LAorMjUxLCA4OCwgMjUxLCAxMjgsIDI1MSwgMTY4LCAyNTEsIDIwOCwgMjUxLCAyNDgsIDI1MiwgMzIsIDI1MiwgNzIsIDI1MiwgMTEyLAorMjUyLCAxNTIsIDI1MiwgMTkyLCAyNTIsIDIzMiwgMjUzLCAxNiwgMjUzLCA1NiwgMjUzLCA5NiwgMjUzLCAxMzYsIDI1MywgMTc2LAorMjUzLCAyMTYsIDI1NCwgMCwgMjU0LCA0MCwgMjU0LCA4MCwgMjU0LCAxMjAsIDI1NCwgMTYwLCAyNTQsIDIwMCwgMjU0LCAyNDAsCisyNTUsIDI0LCAyNTUsIDY0LCAyNTUsIDEwNCwgMjU1LCAxNDQsIDI1NSwgMTg0LCAyNTUsIDIyNAorICAgICAgICAgICAgfSk7CisKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9NdWx0aUJ5dGVfVVRGXzE2QkUuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9NdWx0aUJ5dGVfVVRGXzE2QkUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMjAwNzE4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X011bHRpQnl0ZV9VVEZfMTZCRS5qYXZhCkBAIC0wLDAgKzEsMzc4IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKK3B1YmxpYyBjbGFzcyBPbGRDaGFyc2V0X011bHRpQnl0ZV9VVEZfMTZCRSBleHRlbmRzIE9sZENoYXJzZXRfQWJzdHJhY3RUZXN0IHsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJzZXROYW1lID0gIlVURi0xNkJFIjsKKworICAgICAgICB0ZXN0Q2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKzAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKzMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCis2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKzgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisxMjgsIDEyOSwgMTMwLCAxMzEsIDEzMiwgMTMzLCAxMzQsIDEzNSwgMTM2LCAxMzcsIDEzOCwgMTM5LCAxNDAsIDE0MSwgMTQyLCAxNDMsCisxNDQsIDE0NSwgMTQ2LCAxNDcsIDE0OCwgMTQ5LCAxNTAsIDE1MSwgMTUyLCAxNTMsIDE1NCwgMTU1LCAxNTYsIDE1NywgMTU4LCAxNTksCisxNjAsIDE2MSwgMTYyLCAxNjMsIDE2NCwgMTY1LCAxNjYsIDE2NywgMTY4LCAxNjksIDE3MCwgMTcxLCAxNzIsIDE3MywgMTc0LCAxNzUsCisxNzYsIDE3NywgMTc4LCAxNzksIDE4MCwgMTgxLCAxODIsIDE4MywgMTg0LCAxODUsIDE4NiwgMTg3LCAxODgsIDE4OSwgMTkwLCAxOTEsCisxOTIsIDE5MywgMTk0LCAxOTUsIDE5NiwgMTk3LCAxOTgsIDE5OSwgMjAwLCAyMDEsIDIwMiwgMjAzLCAyMDQsIDIwNSwgMjA2LCAyMDcsCisyMDgsIDIwOSwgMjEwLCAyMTEsIDIxMiwgMjEzLCAyMTQsIDIxNSwgMjE2LCAyMTcsIDIxOCwgMjE5LCAyMjAsIDIyMSwgMjIyLCAyMjMsCisyMjQsIDIyNSwgMjI2LCAyMjcsIDIyOCwgMjI5LCAyMzAsIDIzMSwgMjMyLCAyMzMsIDIzNCwgMjM1LCAyMzYsIDIzNywgMjM4LCAyMzksCisyNDAsIDI0MSwgMjQyLCAyNDMsIDI0NCwgMjQ1LCAyNDYsIDI0NywgMjQ4LCAyNDksIDI1MCwgMjUxLCAyNTIsIDI1MywgMjU0LCAyNTUsCisyNTYsIDI5NiwgMzM2LCAzNzYsIDQxNiwgNDU2LCA0OTYsIDUzNiwgNTc2LCA2MTYsIDY1NiwgNjk2LCA3MzYsIDc3NiwgODE2LCA4NTYsCis4OTYsIDkzNiwgOTc2LCAxMDE2LCAxMDU2LCAxMDk2LCAxMTM2LCAxMTc2LCAxMjE2LCAxMjU2LCAxMjk2LCAxMzM2LCAxMzc2LCAxNDE2LCAxNDU2LCAxNDk2LAorMTUzNiwgMTU3NiwgMTYxNiwgMTY1NiwgMTY5NiwgMTczNiwgMTc3NiwgMTgxNiwgMTg1NiwgMTg5NiwgMTkzNiwgMTk3NiwgMjAxNiwgMjA1NiwgMjA5NiwgMjEzNiwKKzIxNzYsIDIyMTYsIDIyNTYsIDIyOTYsIDIzMzYsIDIzNzYsIDI0MTYsIDI0NTYsIDI0OTYsIDI1MzYsIDI1NzYsIDI2MTYsIDI2NTYsIDI2OTYsIDI3MzYsIDI3NzYsCisyODE2LCAyODU2LCAyODk2LCAyOTM2LCAyOTc2LCAzMDE2LCAzMDU2LCAzMDk2LCAzMTM2LCAzMTc2LCAzMjE2LCAzMjU2LCAzMjk2LCAzMzM2LCAzMzc2LCAzNDE2LAorMzQ1NiwgMzQ5NiwgMzUzNiwgMzU3NiwgMzYxNiwgMzY1NiwgMzY5NiwgMzczNiwgMzc3NiwgMzgxNiwgMzg1NiwgMzg5NiwgMzkzNiwgMzk3NiwgNDAxNiwgNDA1NiwKKzQwOTYsIDQxMzYsIDQxNzYsIDQyMTYsIDQyNTYsIDQyOTYsIDQzMzYsIDQzNzYsIDQ0MTYsIDQ0NTYsIDQ0OTYsIDQ1MzYsIDQ1NzYsIDQ2MTYsIDQ2NTYsIDQ2OTYsCis0NzM2LCA0Nzc2LCA0ODE2LCA0ODU2LCA0ODk2LCA0OTM2LCA0OTc2LCA1MDE2LCA1MDU2LCA1MDk2LCA1MTM2LCA1MTc2LCA1MjE2LCA1MjU2LCA1Mjk2LCA1MzM2LAorNTM3NiwgNTQxNiwgNTQ1NiwgNTQ5NiwgNTUzNiwgNTU3NiwgNTYxNiwgNTY1NiwgNTY5NiwgNTczNiwgNTc3NiwgNTgxNiwgNTg1NiwgNTg5NiwgNTkzNiwgNTk3NiwKKzYwMTYsIDYwNTYsIDYwOTYsIDYxMzYsIDYxNzYsIDYyMTYsIDYyNTYsIDYyOTYsIDYzMzYsIDYzNzYsIDY0MTYsIDY0NTYsIDY0OTYsIDY1MzYsIDY1NzYsIDY2MTYsCis2NjU2LCA2Njk2LCA2NzM2LCA2Nzc2LCA2ODE2LCA2ODU2LCA2ODk2LCA2OTM2LCA2OTc2LCA3MDE2LCA3MDU2LCA3MDk2LCA3MTM2LCA3MTc2LCA3MjE2LCA3MjU2LAorNzI5NiwgNzMzNiwgNzM3NiwgNzQxNiwgNzQ1NiwgNzQ5NiwgNzUzNiwgNzU3NiwgNzYxNiwgNzY1NiwgNzY5NiwgNzczNiwgNzc3NiwgNzgxNiwgNzg1NiwgNzg5NiwKKzc5MzYsIDc5NzYsIDgwMTYsIDgwNTYsIDgwOTYsIDgxMzYsIDgxNzYsIDgyMTYsIDgyNTYsIDgyOTYsIDgzMzYsIDgzNzYsIDg0MTYsIDg0NTYsIDg0OTYsIDg1MzYsCis4NTc2LCA4NjE2LCA4NjU2LCA4Njk2LCA4NzM2LCA4Nzc2LCA4ODE2LCA4ODU2LCA4ODk2LCA4OTM2LCA4OTc2LCA5MDE2LCA5MDU2LCA5MDk2LCA5MTM2LCA5MTc2LAorOTIxNiwgOTI1NiwgOTI5NiwgOTMzNiwgOTM3NiwgOTQxNiwgOTQ1NiwgOTQ5NiwgOTUzNiwgOTU3NiwgOTYxNiwgOTY1NiwgOTY5NiwgOTczNiwgOTc3NiwgOTgxNiwKKzk4NTYsIDk4OTYsIDk5MzYsIDk5NzYsIDEwMDE2LCAxMDA1NiwgMTAwOTYsIDEwMTM2LCAxMDE3NiwgMTAyMTYsIDEwMjU2LCAxMDI5NiwgMTAzMzYsIDEwMzc2LCAxMDQxNiwgMTA0NTYsCisxMDQ5NiwgMTA1MzYsIDEwNTc2LCAxMDYxNiwgMTA2NTYsIDEwNjk2LCAxMDczNiwgMTA3NzYsIDEwODE2LCAxMDg1NiwgMTA4OTYsIDEwOTM2LCAxMDk3NiwgMTEwMTYsIDExMDU2LCAxMTA5NiwKKzExMTM2LCAxMTE3NiwgMTEyMTYsIDExMjU2LCAxMTI5NiwgMTEzMzYsIDExMzc2LCAxMTQxNiwgMTE0NTYsIDExNDk2LCAxMTUzNiwgMTE1NzYsIDExNjE2LCAxMTY1NiwgMTE2OTYsIDExNzM2LAorMTE3NzYsIDExODE2LCAxMTg1NiwgMTE4OTYsIDExOTM2LCAxMTk3NiwgMTIwMTYsIDEyMDU2LCAxMjA5NiwgMTIxMzYsIDEyMTc2LCAxMjIxNiwgMTIyNTYsIDEyMjk2LCAxMjMzNiwgMTIzNzYsCisxMjQxNiwgMTI0NTYsIDEyNDk2LCAxMjUzNiwgMTI1NzYsIDEyNjE2LCAxMjY1NiwgMTI2OTYsIDEyNzM2LCAxMjc3NiwgMTI4MTYsIDEyODU2LCAxMjg5NiwgMTI5MzYsIDEyOTc2LCAxMzAxNiwKKzEzMDU2LCAxMzA5NiwgMTMxMzYsIDEzMTc2LCAxMzIxNiwgMTMyNTYsIDEzMjk2LCAxMzMzNiwgMTMzNzYsIDEzNDE2LCAxMzQ1NiwgMTM0OTYsIDEzNTM2LCAxMzU3NiwgMTM2MTYsIDEzNjU2LAorMTM2OTYsIDEzNzM2LCAxMzc3NiwgMTM4MTYsIDEzODU2LCAxMzg5NiwgMTM5MzYsIDEzOTc2LCAxNDAxNiwgMTQwNTYsIDE0MDk2LCAxNDEzNiwgMTQxNzYsIDE0MjE2LCAxNDI1NiwgMTQyOTYsCisxNDMzNiwgMTQzNzYsIDE0NDE2LCAxNDQ1NiwgMTQ0OTYsIDE0NTM2LCAxNDU3NiwgMTQ2MTYsIDE0NjU2LCAxNDY5NiwgMTQ3MzYsIDE0Nzc2LCAxNDgxNiwgMTQ4NTYsIDE0ODk2LCAxNDkzNiwKKzE0OTc2LCAxNTAxNiwgMTUwNTYsIDE1MDk2LCAxNTEzNiwgMTUxNzYsIDE1MjE2LCAxNTI1NiwgMTUyOTYsIDE1MzM2LCAxNTM3NiwgMTU0MTYsIDE1NDU2LCAxNTQ5NiwgMTU1MzYsIDE1NTc2LAorMTU2MTYsIDE1NjU2LCAxNTY5NiwgMTU3MzYsIDE1Nzc2LCAxNTgxNiwgMTU4NTYsIDE1ODk2LCAxNTkzNiwgMTU5NzYsIDE2MDE2LCAxNjA1NiwgMTYwOTYsIDE2MTM2LCAxNjE3NiwgMTYyMTYsCisxNjI1NiwgMTYyOTYsIDE2MzM2LCAxNjM3NiwgMTY0MTYsIDE2NDU2LCAxNjQ5NiwgMTY1MzYsIDE2NTc2LCAxNjYxNiwgMTY2NTYsIDE2Njk2LCAxNjczNiwgMTY3NzYsIDE2ODE2LCAxNjg1NiwKKzE2ODk2LCAxNjkzNiwgMTY5NzYsIDE3MDE2LCAxNzA1NiwgMTcwOTYsIDE3MTM2LCAxNzE3NiwgMTcyMTYsIDE3MjU2LCAxNzI5NiwgMTczMzYsIDE3Mzc2LCAxNzQxNiwgMTc0NTYsIDE3NDk2LAorMTc1MzYsIDE3NTc2LCAxNzYxNiwgMTc2NTYsIDE3Njk2LCAxNzczNiwgMTc3NzYsIDE3ODE2LCAxNzg1NiwgMTc4OTYsIDE3OTM2LCAxNzk3NiwgMTgwMTYsIDE4MDU2LCAxODA5NiwgMTgxMzYsCisxODE3NiwgMTgyMTYsIDE4MjU2LCAxODI5NiwgMTgzMzYsIDE4Mzc2LCAxODQxNiwgMTg0NTYsIDE4NDk2LCAxODUzNiwgMTg1NzYsIDE4NjE2LCAxODY1NiwgMTg2OTYsIDE4NzM2LCAxODc3NiwKKzE4ODE2LCAxODg1NiwgMTg4OTYsIDE4OTM2LCAxODk3NiwgMTkwMTYsIDE5MDU2LCAxOTA5NiwgMTkxMzYsIDE5MTc2LCAxOTIxNiwgMTkyNTYsIDE5Mjk2LCAxOTMzNiwgMTkzNzYsIDE5NDE2LAorMTk0NTYsIDE5NDk2LCAxOTUzNiwgMTk1NzYsIDE5NjE2LCAxOTY1NiwgMTk2OTYsIDE5NzM2LCAxOTc3NiwgMTk4MTYsIDE5ODU2LCAxOTg5NiwgMTk5MzYsIDE5OTc2LCAyMDAxNiwgMjAwNTYsCisyMDA5NiwgMjAxMzYsIDIwMTc2LCAyMDIxNiwgMjAyNTYsIDIwMjk2LCAyMDMzNiwgMjAzNzYsIDIwNDE2LCAyMDQ1NiwgMjA0OTYsIDIwNTM2LCAyMDU3NiwgMjA2MTYsIDIwNjU2LCAyMDY5NiwKKzIwNzM2LCAyMDc3NiwgMjA4MTYsIDIwODU2LCAyMDg5NiwgMjA5MzYsIDIwOTc2LCAyMTAxNiwgMjEwNTYsIDIxMDk2LCAyMTEzNiwgMjExNzYsIDIxMjE2LCAyMTI1NiwgMjEyOTYsIDIxMzM2LAorMjEzNzYsIDIxNDE2LCAyMTQ1NiwgMjE0OTYsIDIxNTM2LCAyMTU3NiwgMjE2MTYsIDIxNjU2LCAyMTY5NiwgMjE3MzYsIDIxNzc2LCAyMTgxNiwgMjE4NTYsIDIxODk2LCAyMTkzNiwgMjE5NzYsCisyMjAxNiwgMjIwNTYsIDIyMDk2LCAyMjEzNiwgMjIxNzYsIDIyMjE2LCAyMjI1NiwgMjIyOTYsIDIyMzM2LCAyMjM3NiwgMjI0MTYsIDIyNDU2LCAyMjQ5NiwgMjI1MzYsIDIyNTc2LCAyMjYxNiwKKzIyNjU2LCAyMjY5NiwgMjI3MzYsIDIyNzc2LCAyMjgxNiwgMjI4NTYsIDIyODk2LCAyMjkzNiwgMjI5NzYsIDIzMDE2LCAyMzA1NiwgMjMwOTYsIDIzMTM2LCAyMzE3NiwgMjMyMTYsIDIzMjU2LAorMjMyOTYsIDIzMzM2LCAyMzM3NiwgMjM0MTYsIDIzNDU2LCAyMzQ5NiwgMjM1MzYsIDIzNTc2LCAyMzYxNiwgMjM2NTYsIDIzNjk2LCAyMzczNiwgMjM3NzYsIDIzODE2LCAyMzg1NiwgMjM4OTYsCisyMzkzNiwgMjM5NzYsIDI0MDE2LCAyNDA1NiwgMjQwOTYsIDI0MTM2LCAyNDE3NiwgMjQyMTYsIDI0MjU2LCAyNDI5NiwgMjQzMzYsIDI0Mzc2LCAyNDQxNiwgMjQ0NTYsIDI0NDk2LCAyNDUzNiwKKzI0NTc2LCAyNDYxNiwgMjQ2NTYsIDI0Njk2LCAyNDczNiwgMjQ3NzYsIDI0ODE2LCAyNDg1NiwgMjQ4OTYsIDI0OTM2LCAyNDk3NiwgMjUwMTYsIDI1MDU2LCAyNTA5NiwgMjUxMzYsIDI1MTc2LAorMjUyMTYsIDI1MjU2LCAyNTI5NiwgMjUzMzYsIDI1Mzc2LCAyNTQxNiwgMjU0NTYsIDI1NDk2LCAyNTUzNiwgMjU1NzYsIDI1NjE2LCAyNTY1NiwgMjU2OTYsIDI1NzM2LCAyNTc3NiwgMjU4MTYsCisyNTg1NiwgMjU4OTYsIDI1OTM2LCAyNTk3NiwgMjYwMTYsIDI2MDU2LCAyNjA5NiwgMjYxMzYsIDI2MTc2LCAyNjIxNiwgMjYyNTYsIDI2Mjk2LCAyNjMzNiwgMjYzNzYsIDI2NDE2LCAyNjQ1NiwKKzI2NDk2LCAyNjUzNiwgMjY1NzYsIDI2NjE2LCAyNjY1NiwgMjY2OTYsIDI2NzM2LCAyNjc3NiwgMjY4MTYsIDI2ODU2LCAyNjg5NiwgMjY5MzYsIDI2OTc2LCAyNzAxNiwgMjcwNTYsIDI3MDk2LAorMjcxMzYsIDI3MTc2LCAyNzIxNiwgMjcyNTYsIDI3Mjk2LCAyNzMzNiwgMjczNzYsIDI3NDE2LCAyNzQ1NiwgMjc0OTYsIDI3NTM2LCAyNzU3NiwgMjc2MTYsIDI3NjU2LCAyNzY5NiwgMjc3MzYsCisyNzc3NiwgMjc4MTYsIDI3ODU2LCAyNzg5NiwgMjc5MzYsIDI3OTc2LCAyODAxNiwgMjgwNTYsIDI4MDk2LCAyODEzNiwgMjgxNzYsIDI4MjE2LCAyODI1NiwgMjgyOTYsIDI4MzM2LCAyODM3NiwKKzI4NDE2LCAyODQ1NiwgMjg0OTYsIDI4NTM2LCAyODU3NiwgMjg2MTYsIDI4NjU2LCAyODY5NiwgMjg3MzYsIDI4Nzc2LCAyODgxNiwgMjg4NTYsIDI4ODk2LCAyODkzNiwgMjg5NzYsIDI5MDE2LAorMjkwNTYsIDI5MDk2LCAyOTEzNiwgMjkxNzYsIDI5MjE2LCAyOTI1NiwgMjkyOTYsIDI5MzM2LCAyOTM3NiwgMjk0MTYsIDI5NDU2LCAyOTQ5NiwgMjk1MzYsIDI5NTc2LCAyOTYxNiwgMjk2NTYsCisyOTY5NiwgMjk3MzYsIDI5Nzc2LCAyOTgxNiwgMjk4NTYsIDI5ODk2LCAyOTkzNiwgMjk5NzYsIDMwMDE2LCAzMDA1NiwgMzAwOTYsIDMwMTM2LCAzMDE3NiwgMzAyMTYsIDMwMjU2LCAzMDI5NiwKKzMwMzM2LCAzMDM3NiwgMzA0MTYsIDMwNDU2LCAzMDQ5NiwgMzA1MzYsIDMwNTc2LCAzMDYxNiwgMzA2NTYsIDMwNjk2LCAzMDczNiwgMzA3NzYsIDMwODE2LCAzMDg1NiwgMzA4OTYsIDMwOTM2LAorMzA5NzYsIDMxMDE2LCAzMTA1NiwgMzEwOTYsIDMxMTM2LCAzMTE3NiwgMzEyMTYsIDMxMjU2LCAzMTI5NiwgMzEzMzYsIDMxMzc2LCAzMTQxNiwgMzE0NTYsIDMxNDk2LCAzMTUzNiwgMzE1NzYsCiszMTYxNiwgMzE2NTYsIDMxNjk2LCAzMTczNiwgMzE3NzYsIDMxODE2LCAzMTg1NiwgMzE4OTYsIDMxOTM2LCAzMTk3NiwgMzIwMTYsIDMyMDU2LCAzMjA5NiwgMzIxMzYsIDMyMTc2LCAzMjIxNiwKKzMyMjU2LCAzMjI5NiwgMzIzMzYsIDMyMzc2LCAzMjQxNiwgMzI0NTYsIDMyNDk2LCAzMjUzNiwgMzI1NzYsIDMyNjE2LCAzMjY1NiwgMzI2OTYsIDMyNzM2LCAzMjc3NiwgMzI4MTYsIDMyODU2LAorMzI4OTYsIDMyOTM2LCAzMjk3NiwgMzMwMTYsIDMzMDU2LCAzMzA5NiwgMzMxMzYsIDMzMTc2LCAzMzIxNiwgMzMyNTYsIDMzMjk2LCAzMzMzNiwgMzMzNzYsIDMzNDE2LCAzMzQ1NiwgMzM0OTYsCiszMzUzNiwgMzM1NzYsIDMzNjE2LCAzMzY1NiwgMzM2OTYsIDMzNzM2LCAzMzc3NiwgMzM4MTYsIDMzODU2LCAzMzg5NiwgMzM5MzYsIDMzOTc2LCAzNDAxNiwgMzQwNTYsIDM0MDk2LCAzNDEzNiwKKzM0MTc2LCAzNDIxNiwgMzQyNTYsIDM0Mjk2LCAzNDMzNiwgMzQzNzYsIDM0NDE2LCAzNDQ1NiwgMzQ0OTYsIDM0NTM2LCAzNDU3NiwgMzQ2MTYsIDM0NjU2LCAzNDY5NiwgMzQ3MzYsIDM0Nzc2LAorMzQ4MTYsIDM0ODU2LCAzNDg5NiwgMzQ5MzYsIDM0OTc2LCAzNTAxNiwgMzUwNTYsIDM1MDk2LCAzNTEzNiwgMzUxNzYsIDM1MjE2LCAzNTI1NiwgMzUyOTYsIDM1MzM2LCAzNTM3NiwgMzU0MTYsCiszNTQ1NiwgMzU0OTYsIDM1NTM2LCAzNTU3NiwgMzU2MTYsIDM1NjU2LCAzNTY5NiwgMzU3MzYsIDM1Nzc2LCAzNTgxNiwgMzU4NTYsIDM1ODk2LCAzNTkzNiwgMzU5NzYsIDM2MDE2LCAzNjA1NiwKKzM2MDk2LCAzNjEzNiwgMzYxNzYsIDM2MjE2LCAzNjI1NiwgMzYyOTYsIDM2MzM2LCAzNjM3NiwgMzY0MTYsIDM2NDU2LCAzNjQ5NiwgMzY1MzYsIDM2NTc2LCAzNjYxNiwgMzY2NTYsIDM2Njk2LAorMzY3MzYsIDM2Nzc2LCAzNjgxNiwgMzY4NTYsIDM2ODk2LCAzNjkzNiwgMzY5NzYsIDM3MDE2LCAzNzA1NiwgMzcwOTYsIDM3MTM2LCAzNzE3NiwgMzcyMTYsIDM3MjU2LCAzNzI5NiwgMzczMzYsCiszNzM3NiwgMzc0MTYsIDM3NDU2LCAzNzQ5NiwgMzc1MzYsIDM3NTc2LCAzNzYxNiwgMzc2NTYsIDM3Njk2LCAzNzczNiwgMzc3NzYsIDM3ODE2LCAzNzg1NiwgMzc4OTYsIDM3OTM2LCAzNzk3NiwKKzM4MDE2LCAzODA1NiwgMzgwOTYsIDM4MTM2LCAzODE3NiwgMzgyMTYsIDM4MjU2LCAzODI5NiwgMzgzMzYsIDM4Mzc2LCAzODQxNiwgMzg0NTYsIDM4NDk2LCAzODUzNiwgMzg1NzYsIDM4NjE2LAorMzg2NTYsIDM4Njk2LCAzODczNiwgMzg3NzYsIDM4ODE2LCAzODg1NiwgMzg4OTYsIDM4OTM2LCAzODk3NiwgMzkwMTYsIDM5MDU2LCAzOTA5NiwgMzkxMzYsIDM5MTc2LCAzOTIxNiwgMzkyNTYsCiszOTI5NiwgMzkzMzYsIDM5Mzc2LCAzOTQxNiwgMzk0NTYsIDM5NDk2LCAzOTUzNiwgMzk1NzYsIDM5NjE2LCAzOTY1NiwgMzk2OTYsIDM5NzM2LCAzOTc3NiwgMzk4MTYsIDM5ODU2LCAzOTg5NiwKKzM5OTM2LCAzOTk3NiwgNDAwMTYsIDQwMDU2LCA0MDA5NiwgNDAxMzYsIDQwMTc2LCA0MDIxNiwgNDAyNTYsIDQwMjk2LCA0MDMzNiwgNDAzNzYsIDQwNDE2LCA0MDQ1NiwgNDA0OTYsIDQwNTM2LAorNDA1NzYsIDQwNjE2LCA0MDY1NiwgNDA2OTYsIDQwNzM2LCA0MDc3NiwgNDA4MTYsIDQwODU2LCA0MDg5NiwgNDA5MzYsIDQwOTc2LCA0MTAxNiwgNDEwNTYsIDQxMDk2LCA0MTEzNiwgNDExNzYsCis0MTIxNiwgNDEyNTYsIDQxMjk2LCA0MTMzNiwgNDEzNzYsIDQxNDE2LCA0MTQ1NiwgNDE0OTYsIDQxNTM2LCA0MTU3NiwgNDE2MTYsIDQxNjU2LCA0MTY5NiwgNDE3MzYsIDQxNzc2LCA0MTgxNiwKKzQxODU2LCA0MTg5NiwgNDE5MzYsIDQxOTc2LCA0MjAxNiwgNDIwNTYsIDQyMDk2LCA0MjEzNiwgNDIxNzYsIDQyMjE2LCA0MjI1NiwgNDIyOTYsIDQyMzM2LCA0MjM3NiwgNDI0MTYsIDQyNDU2LAorNDI0OTYsIDQyNTM2LCA0MjU3NiwgNDI2MTYsIDQyNjU2LCA0MjY5NiwgNDI3MzYsIDQyNzc2LCA0MjgxNiwgNDI4NTYsIDQyODk2LCA0MjkzNiwgNDI5NzYsIDQzMDE2LCA0MzA1NiwgNDMwOTYsCis0MzEzNiwgNDMxNzYsIDQzMjE2LCA0MzI1NiwgNDMyOTYsIDQzMzM2LCA0MzM3NiwgNDM0MTYsIDQzNDU2LCA0MzQ5NiwgNDM1MzYsIDQzNTc2LCA0MzYxNiwgNDM2NTYsIDQzNjk2LCA0MzczNiwKKzQzNzc2LCA0MzgxNiwgNDM4NTYsIDQzODk2LCA0MzkzNiwgNDM5NzYsIDQ0MDE2LCA0NDA1NiwgNDQwOTYsIDQ0MTM2LCA0NDE3NiwgNDQyMTYsIDQ0MjU2LCA0NDI5NiwgNDQzMzYsIDQ0Mzc2LAorNDQ0MTYsIDQ0NDU2LCA0NDQ5NiwgNDQ1MzYsIDQ0NTc2LCA0NDYxNiwgNDQ2NTYsIDQ0Njk2LCA0NDczNiwgNDQ3NzYsIDQ0ODE2LCA0NDg1NiwgNDQ4OTYsIDQ0OTM2LCA0NDk3NiwgNDUwMTYsCis0NTA1NiwgNDUwOTYsIDQ1MTM2LCA0NTE3NiwgNDUyMTYsIDQ1MjU2LCA0NTI5NiwgNDUzMzYsIDQ1Mzc2LCA0NTQxNiwgNDU0NTYsIDQ1NDk2LCA0NTUzNiwgNDU1NzYsIDQ1NjE2LCA0NTY1NiwKKzQ1Njk2LCA0NTczNiwgNDU3NzYsIDQ1ODE2LCA0NTg1NiwgNDU4OTYsIDQ1OTM2LCA0NTk3NiwgNDYwMTYsIDQ2MDU2LCA0NjA5NiwgNDYxMzYsIDQ2MTc2LCA0NjIxNiwgNDYyNTYsIDQ2Mjk2LAorNDYzMzYsIDQ2Mzc2LCA0NjQxNiwgNDY0NTYsIDQ2NDk2LCA0NjUzNiwgNDY1NzYsIDQ2NjE2LCA0NjY1NiwgNDY2OTYsIDQ2NzM2LCA0Njc3NiwgNDY4MTYsIDQ2ODU2LCA0Njg5NiwgNDY5MzYsCis0Njk3NiwgNDcwMTYsIDQ3MDU2LCA0NzA5NiwgNDcxMzYsIDQ3MTc2LCA0NzIxNiwgNDcyNTYsIDQ3Mjk2LCA0NzMzNiwgNDczNzYsIDQ3NDE2LCA0NzQ1NiwgNDc0OTYsIDQ3NTM2LCA0NzU3NiwKKzQ3NjE2LCA0NzY1NiwgNDc2OTYsIDQ3NzM2LCA0Nzc3NiwgNDc4MTYsIDQ3ODU2LCA0Nzg5NiwgNDc5MzYsIDQ3OTc2LCA0ODAxNiwgNDgwNTYsIDQ4MDk2LCA0ODEzNiwgNDgxNzYsIDQ4MjE2LAorNDgyNTYsIDQ4Mjk2LCA0ODMzNiwgNDgzNzYsIDQ4NDE2LCA0ODQ1NiwgNDg0OTYsIDQ4NTM2LCA0ODU3NiwgNDg2MTYsIDQ4NjU2LCA0ODY5NiwgNDg3MzYsIDQ4Nzc2LCA0ODgxNiwgNDg4NTYsCis0ODg5NiwgNDg5MzYsIDQ4OTc2LCA0OTAxNiwgNDkwNTYsIDQ5MDk2LCA0OTEzNiwgNDkxNzYsIDQ5MjE2LCA0OTI1NiwgNDkyOTYsIDQ5MzM2LCA0OTM3NiwgNDk0MTYsIDQ5NDU2LCA0OTQ5NiwKKzQ5NTM2LCA0OTU3NiwgNDk2MTYsIDQ5NjU2LCA0OTY5NiwgNDk3MzYsIDQ5Nzc2LCA0OTgxNiwgNDk4NTYsIDQ5ODk2LCA0OTkzNiwgNDk5NzYsIDUwMDE2LCA1MDA1NiwgNTAwOTYsIDUwMTM2LAorNTAxNzYsIDUwMjE2LCA1MDI1NiwgNTAyOTYsIDUwMzM2LCA1MDM3NiwgNTA0MTYsIDUwNDU2LCA1MDQ5NiwgNTA1MzYsIDUwNTc2LCA1MDYxNiwgNTA2NTYsIDUwNjk2LCA1MDczNiwgNTA3NzYsCis1MDgxNiwgNTA4NTYsIDUwODk2LCA1MDkzNiwgNTA5NzYsIDUxMDE2LCA1MTA1NiwgNTEwOTYsIDUxMTM2LCA1MTE3NiwgNTEyMTYsIDUxMjU2LCA1MTI5NiwgNTEzMzYsIDUxMzc2LCA1MTQxNiwKKzUxNDU2LCA1MTQ5NiwgNTE1MzYsIDUxNTc2LCA1MTYxNiwgNTE2NTYsIDUxNjk2LCA1MTczNiwgNTE3NzYsIDUxODE2LCA1MTg1NiwgNTE4OTYsIDUxOTM2LCA1MTk3NiwgNTIwMTYsIDUyMDU2LAorNTIwOTYsIDUyMTM2LCA1MjE3NiwgNTIyMTYsIDUyMjU2LCA1MjI5NiwgNTIzMzYsIDUyMzc2LCA1MjQxNiwgNTI0NTYsIDUyNDk2LCA1MjUzNiwgNTI1NzYsIDUyNjE2LCA1MjY1NiwgNTI2OTYsCis1MjczNiwgNTI3NzYsIDUyODE2LCA1Mjg1NiwgNTI4OTYsIDUyOTM2LCA1Mjk3NiwgNTMwMTYsIDUzMDU2LCA1MzA5NiwgNTMxMzYsIDUzMTc2LCA1MzIxNiwgNTMyNTYsIDUzMjk2LCA1MzMzNiwKKzUzMzc2LCA1MzQxNiwgNTM0NTYsIDUzNDk2LCA1MzUzNiwgNTM1NzYsIDUzNjE2LCA1MzY1NiwgNTM2OTYsIDUzNzM2LCA1Mzc3NiwgNTM4MTYsIDUzODU2LCA1Mzg5NiwgNTM5MzYsIDUzOTc2LAorNTQwMTYsIDU0MDU2LCA1NDA5NiwgNTQxMzYsIDU0MTc2LCA1NDIxNiwgNTQyNTYsIDU0Mjk2LCA1NDMzNiwgNTQzNzYsIDU0NDE2LCA1NDQ1NiwgNTQ0OTYsIDU0NTM2LCA1NDU3NiwgNTQ2MTYsCis1NDY1NiwgNTQ2OTYsIDU0NzM2LCA1NDc3NiwgNTQ4MTYsIDU0ODU2LCA1NDg5NiwgNTQ5MzYsIDU0OTc2LCA1NTAxNiwgNTUwNTYsIDU1MDk2LCA1NTEzNiwgNTUxNzYsIDU1MjE2LCA1NTI1NiwKKzU3MzQ0LCA1NzM4NCwgNTc0MjQsIDU3NDY0LCA1NzUwNCwgNTc1NDQsIDU3NTg0LCA1NzYyNCwgNTc2NjQsIDU3NzA0LCA1Nzc0NCwgNTc3ODQsIDU3ODI0LCA1Nzg2NCwgNTc5MDQsIDU3OTQ0LAorNTc5ODQsIDU4MDI0LCA1ODA2NCwgNTgxMDQsIDU4MTQ0LCA1ODE4NCwgNTgyMjQsIDU4MjY0LCA1ODMwNCwgNTgzNDQsIDU4Mzg0LCA1ODQyNCwgNTg0NjQsIDU4NTA0LCA1ODU0NCwgNTg1ODQsCis1ODYyNCwgNTg2NjQsIDU4NzA0LCA1ODc0NCwgNTg3ODQsIDU4ODI0LCA1ODg2NCwgNTg5MDQsIDU4OTQ0LCA1ODk4NCwgNTkwMjQsIDU5MDY0LCA1OTEwNCwgNTkxNDQsIDU5MTg0LCA1OTIyNCwKKzU5MjY0LCA1OTMwNCwgNTkzNDQsIDU5Mzg0LCA1OTQyNCwgNTk0NjQsIDU5NTA0LCA1OTU0NCwgNTk1ODQsIDU5NjI0LCA1OTY2NCwgNTk3MDQsIDU5NzQ0LCA1OTc4NCwgNTk4MjQsIDU5ODY0LAorNTk5MDQsIDU5OTQ0LCA1OTk4NCwgNjAwMjQsIDYwMDY0LCA2MDEwNCwgNjAxNDQsIDYwMTg0LCA2MDIyNCwgNjAyNjQsIDYwMzA0LCA2MDM0NCwgNjAzODQsIDYwNDI0LCA2MDQ2NCwgNjA1MDQsCis2MDU0NCwgNjA1ODQsIDYwNjI0LCA2MDY2NCwgNjA3MDQsIDYwNzQ0LCA2MDc4NCwgNjA4MjQsIDYwODY0LCA2MDkwNCwgNjA5NDQsIDYwOTg0LCA2MTAyNCwgNjEwNjQsIDYxMTA0LCA2MTE0NCwKKzYxMTg0LCA2MTIyNCwgNjEyNjQsIDYxMzA0LCA2MTM0NCwgNjEzODQsIDYxNDI0LCA2MTQ2NCwgNjE1MDQsIDYxNTQ0LCA2MTU4NCwgNjE2MjQsIDYxNjY0LCA2MTcwNCwgNjE3NDQsIDYxNzg0LAorNjE4MjQsIDYxODY0LCA2MTkwNCwgNjE5NDQsIDYxOTg0LCA2MjAyNCwgNjIwNjQsIDYyMTA0LCA2MjE0NCwgNjIxODQsIDYyMjI0LCA2MjI2NCwgNjIzMDQsIDYyMzQ0LCA2MjM4NCwgNjI0MjQsCis2MjQ2NCwgNjI1MDQsIDYyNTQ0LCA2MjU4NCwgNjI2MjQsIDYyNjY0LCA2MjcwNCwgNjI3NDQsIDYyNzg0LCA2MjgyNCwgNjI4NjQsIDYyOTA0LCA2Mjk0NCwgNjI5ODQsIDYzMDI0LCA2MzA2NCwKKzYzMTA0LCA2MzE0NCwgNjMxODQsIDYzMjI0LCA2MzI2NCwgNjMzMDQsIDYzMzQ0LCA2MzM4NCwgNjM0MjQsIDYzNDY0LCA2MzUwNCwgNjM1NDQsIDYzNTg0LCA2MzYyNCwgNjM2NjQsIDYzNzA0LAorNjM3NDQsIDYzNzg0LCA2MzgyNCwgNjM4NjQsIDYzOTA0LCA2Mzk0NCwgNjM5ODQsIDY0MDI0LCA2NDA2NCwgNjQxMDQsIDY0MTQ0LCA2NDE4NCwgNjQyMjQsIDY0MjY0LCA2NDMwNCwgNjQzNDQsCis2NDM4NCwgNjQ0MjQsIDY0NDY0LCA2NDUwNCwgNjQ1NDQsIDY0NTg0LCA2NDYyNCwgNjQ2NjQsIDY0NzA0LCA2NDc0NCwgNjQ3ODQsIDY0ODI0LCA2NDg2NCwgNjQ5MDQsIDY0OTQ0LCA2NDk4NCwKKzY1MDI0LCA2NTA2NCwgNjUxMDQsIDY1MTQ0LCA2NTE4NCwgNjUyMjQsIDY1MjY0LCA2NTMwNCwgNjUzNDQsIDY1Mzg0LCA2NTQyNCwgNjU0NjQsIDY1NTA0CisgICAgICAgICAgICB9KTsKKworICAgICAgICB0ZXN0Qnl0ZXMgPSB0aGVzZUJ5dGVzKG5ldyBpbnRbXXsKKzAsIDAsIDAsIDEsIDAsIDIsIDAsIDMsIDAsIDQsIDAsIDUsIDAsIDYsIDAsIDcsCiswLCA4LCAwLCA5LCAwLCAxMCwgMCwgMTEsIDAsIDEyLCAwLCAxMywgMCwgMTQsIDAsIDE1LAorMCwgMTYsIDAsIDE3LCAwLCAxOCwgMCwgMTksIDAsIDIwLCAwLCAyMSwgMCwgMjIsIDAsIDIzLAorMCwgMjQsIDAsIDI1LCAwLCAyNiwgMCwgMjcsIDAsIDI4LCAwLCAyOSwgMCwgMzAsIDAsIDMxLAorMCwgMzIsIDAsIDMzLCAwLCAzNCwgMCwgMzUsIDAsIDM2LCAwLCAzNywgMCwgMzgsIDAsIDM5LAorMCwgNDAsIDAsIDQxLCAwLCA0MiwgMCwgNDMsIDAsIDQ0LCAwLCA0NSwgMCwgNDYsIDAsIDQ3LAorMCwgNDgsIDAsIDQ5LCAwLCA1MCwgMCwgNTEsIDAsIDUyLCAwLCA1MywgMCwgNTQsIDAsIDU1LAorMCwgNTYsIDAsIDU3LCAwLCA1OCwgMCwgNTksIDAsIDYwLCAwLCA2MSwgMCwgNjIsIDAsIDYzLAorMCwgNjQsIDAsIDY1LCAwLCA2NiwgMCwgNjcsIDAsIDY4LCAwLCA2OSwgMCwgNzAsIDAsIDcxLAorMCwgNzIsIDAsIDczLCAwLCA3NCwgMCwgNzUsIDAsIDc2LCAwLCA3NywgMCwgNzgsIDAsIDc5LAorMCwgODAsIDAsIDgxLCAwLCA4MiwgMCwgODMsIDAsIDg0LCAwLCA4NSwgMCwgODYsIDAsIDg3LAorMCwgODgsIDAsIDg5LCAwLCA5MCwgMCwgOTEsIDAsIDkyLCAwLCA5MywgMCwgOTQsIDAsIDk1LAorMCwgOTYsIDAsIDk3LCAwLCA5OCwgMCwgOTksIDAsIDEwMCwgMCwgMTAxLCAwLCAxMDIsIDAsIDEwMywKKzAsIDEwNCwgMCwgMTA1LCAwLCAxMDYsIDAsIDEwNywgMCwgMTA4LCAwLCAxMDksIDAsIDExMCwgMCwgMTExLAorMCwgMTEyLCAwLCAxMTMsIDAsIDExNCwgMCwgMTE1LCAwLCAxMTYsIDAsIDExNywgMCwgMTE4LCAwLCAxMTksCiswLCAxMjAsIDAsIDEyMSwgMCwgMTIyLCAwLCAxMjMsIDAsIDEyNCwgMCwgMTI1LCAwLCAxMjYsIDAsIDEyNywKKzAsIDEyOCwgMCwgMTI5LCAwLCAxMzAsIDAsIDEzMSwgMCwgMTMyLCAwLCAxMzMsIDAsIDEzNCwgMCwgMTM1LAorMCwgMTM2LCAwLCAxMzcsIDAsIDEzOCwgMCwgMTM5LCAwLCAxNDAsIDAsIDE0MSwgMCwgMTQyLCAwLCAxNDMsCiswLCAxNDQsIDAsIDE0NSwgMCwgMTQ2LCAwLCAxNDcsIDAsIDE0OCwgMCwgMTQ5LCAwLCAxNTAsIDAsIDE1MSwKKzAsIDE1MiwgMCwgMTUzLCAwLCAxNTQsIDAsIDE1NSwgMCwgMTU2LCAwLCAxNTcsIDAsIDE1OCwgMCwgMTU5LAorMCwgMTYwLCAwLCAxNjEsIDAsIDE2MiwgMCwgMTYzLCAwLCAxNjQsIDAsIDE2NSwgMCwgMTY2LCAwLCAxNjcsCiswLCAxNjgsIDAsIDE2OSwgMCwgMTcwLCAwLCAxNzEsIDAsIDE3MiwgMCwgMTczLCAwLCAxNzQsIDAsIDE3NSwKKzAsIDE3NiwgMCwgMTc3LCAwLCAxNzgsIDAsIDE3OSwgMCwgMTgwLCAwLCAxODEsIDAsIDE4MiwgMCwgMTgzLAorMCwgMTg0LCAwLCAxODUsIDAsIDE4NiwgMCwgMTg3LCAwLCAxODgsIDAsIDE4OSwgMCwgMTkwLCAwLCAxOTEsCiswLCAxOTIsIDAsIDE5MywgMCwgMTk0LCAwLCAxOTUsIDAsIDE5NiwgMCwgMTk3LCAwLCAxOTgsIDAsIDE5OSwKKzAsIDIwMCwgMCwgMjAxLCAwLCAyMDIsIDAsIDIwMywgMCwgMjA0LCAwLCAyMDUsIDAsIDIwNiwgMCwgMjA3LAorMCwgMjA4LCAwLCAyMDksIDAsIDIxMCwgMCwgMjExLCAwLCAyMTIsIDAsIDIxMywgMCwgMjE0LCAwLCAyMTUsCiswLCAyMTYsIDAsIDIxNywgMCwgMjE4LCAwLCAyMTksIDAsIDIyMCwgMCwgMjIxLCAwLCAyMjIsIDAsIDIyMywKKzAsIDIyNCwgMCwgMjI1LCAwLCAyMjYsIDAsIDIyNywgMCwgMjI4LCAwLCAyMjksIDAsIDIzMCwgMCwgMjMxLAorMCwgMjMyLCAwLCAyMzMsIDAsIDIzNCwgMCwgMjM1LCAwLCAyMzYsIDAsIDIzNywgMCwgMjM4LCAwLCAyMzksCiswLCAyNDAsIDAsIDI0MSwgMCwgMjQyLCAwLCAyNDMsIDAsIDI0NCwgMCwgMjQ1LCAwLCAyNDYsIDAsIDI0NywKKzAsIDI0OCwgMCwgMjQ5LCAwLCAyNTAsIDAsIDI1MSwgMCwgMjUyLCAwLCAyNTMsIDAsIDI1NCwgMCwgMjU1LAorMSwgMCwgMSwgNDAsIDEsIDgwLCAxLCAxMjAsIDEsIDE2MCwgMSwgMjAwLCAxLCAyNDAsIDIsIDI0LAorMiwgNjQsIDIsIDEwNCwgMiwgMTQ0LCAyLCAxODQsIDIsIDIyNCwgMywgOCwgMywgNDgsIDMsIDg4LAorMywgMTI4LCAzLCAxNjgsIDMsIDIwOCwgMywgMjQ4LCA0LCAzMiwgNCwgNzIsIDQsIDExMiwgNCwgMTUyLAorNCwgMTkyLCA0LCAyMzIsIDUsIDE2LCA1LCA1NiwgNSwgOTYsIDUsIDEzNiwgNSwgMTc2LCA1LCAyMTYsCis2LCAwLCA2LCA0MCwgNiwgODAsIDYsIDEyMCwgNiwgMTYwLCA2LCAyMDAsIDYsIDI0MCwgNywgMjQsCis3LCA2NCwgNywgMTA0LCA3LCAxNDQsIDcsIDE4NCwgNywgMjI0LCA4LCA4LCA4LCA0OCwgOCwgODgsCis4LCAxMjgsIDgsIDE2OCwgOCwgMjA4LCA4LCAyNDgsIDksIDMyLCA5LCA3MiwgOSwgMTEyLCA5LCAxNTIsCis5LCAxOTIsIDksIDIzMiwgMTAsIDE2LCAxMCwgNTYsIDEwLCA5NiwgMTAsIDEzNiwgMTAsIDE3NiwgMTAsIDIxNiwKKzExLCAwLCAxMSwgNDAsIDExLCA4MCwgMTEsIDEyMCwgMTEsIDE2MCwgMTEsIDIwMCwgMTEsIDI0MCwgMTIsIDI0LAorMTIsIDY0LCAxMiwgMTA0LCAxMiwgMTQ0LCAxMiwgMTg0LCAxMiwgMjI0LCAxMywgOCwgMTMsIDQ4LCAxMywgODgsCisxMywgMTI4LCAxMywgMTY4LCAxMywgMjA4LCAxMywgMjQ4LCAxNCwgMzIsIDE0LCA3MiwgMTQsIDExMiwgMTQsIDE1MiwKKzE0LCAxOTIsIDE0LCAyMzIsIDE1LCAxNiwgMTUsIDU2LCAxNSwgOTYsIDE1LCAxMzYsIDE1LCAxNzYsIDE1LCAyMTYsCisxNiwgMCwgMTYsIDQwLCAxNiwgODAsIDE2LCAxMjAsIDE2LCAxNjAsIDE2LCAyMDAsIDE2LCAyNDAsIDE3LCAyNCwKKzE3LCA2NCwgMTcsIDEwNCwgMTcsIDE0NCwgMTcsIDE4NCwgMTcsIDIyNCwgMTgsIDgsIDE4LCA0OCwgMTgsIDg4LAorMTgsIDEyOCwgMTgsIDE2OCwgMTgsIDIwOCwgMTgsIDI0OCwgMTksIDMyLCAxOSwgNzIsIDE5LCAxMTIsIDE5LCAxNTIsCisxOSwgMTkyLCAxOSwgMjMyLCAyMCwgMTYsIDIwLCA1NiwgMjAsIDk2LCAyMCwgMTM2LCAyMCwgMTc2LCAyMCwgMjE2LAorMjEsIDAsIDIxLCA0MCwgMjEsIDgwLCAyMSwgMTIwLCAyMSwgMTYwLCAyMSwgMjAwLCAyMSwgMjQwLCAyMiwgMjQsCisyMiwgNjQsIDIyLCAxMDQsIDIyLCAxNDQsIDIyLCAxODQsIDIyLCAyMjQsIDIzLCA4LCAyMywgNDgsIDIzLCA4OCwKKzIzLCAxMjgsIDIzLCAxNjgsIDIzLCAyMDgsIDIzLCAyNDgsIDI0LCAzMiwgMjQsIDcyLCAyNCwgMTEyLCAyNCwgMTUyLAorMjQsIDE5MiwgMjQsIDIzMiwgMjUsIDE2LCAyNSwgNTYsIDI1LCA5NiwgMjUsIDEzNiwgMjUsIDE3NiwgMjUsIDIxNiwKKzI2LCAwLCAyNiwgNDAsIDI2LCA4MCwgMjYsIDEyMCwgMjYsIDE2MCwgMjYsIDIwMCwgMjYsIDI0MCwgMjcsIDI0LAorMjcsIDY0LCAyNywgMTA0LCAyNywgMTQ0LCAyNywgMTg0LCAyNywgMjI0LCAyOCwgOCwgMjgsIDQ4LCAyOCwgODgsCisyOCwgMTI4LCAyOCwgMTY4LCAyOCwgMjA4LCAyOCwgMjQ4LCAyOSwgMzIsIDI5LCA3MiwgMjksIDExMiwgMjksIDE1MiwKKzI5LCAxOTIsIDI5LCAyMzIsIDMwLCAxNiwgMzAsIDU2LCAzMCwgOTYsIDMwLCAxMzYsIDMwLCAxNzYsIDMwLCAyMTYsCiszMSwgMCwgMzEsIDQwLCAzMSwgODAsIDMxLCAxMjAsIDMxLCAxNjAsIDMxLCAyMDAsIDMxLCAyNDAsIDMyLCAyNCwKKzMyLCA2NCwgMzIsIDEwNCwgMzIsIDE0NCwgMzIsIDE4NCwgMzIsIDIyNCwgMzMsIDgsIDMzLCA0OCwgMzMsIDg4LAorMzMsIDEyOCwgMzMsIDE2OCwgMzMsIDIwOCwgMzMsIDI0OCwgMzQsIDMyLCAzNCwgNzIsIDM0LCAxMTIsIDM0LCAxNTIsCiszNCwgMTkyLCAzNCwgMjMyLCAzNSwgMTYsIDM1LCA1NiwgMzUsIDk2LCAzNSwgMTM2LCAzNSwgMTc2LCAzNSwgMjE2LAorMzYsIDAsIDM2LCA0MCwgMzYsIDgwLCAzNiwgMTIwLCAzNiwgMTYwLCAzNiwgMjAwLCAzNiwgMjQwLCAzNywgMjQsCiszNywgNjQsIDM3LCAxMDQsIDM3LCAxNDQsIDM3LCAxODQsIDM3LCAyMjQsIDM4LCA4LCAzOCwgNDgsIDM4LCA4OCwKKzM4LCAxMjgsIDM4LCAxNjgsIDM4LCAyMDgsIDM4LCAyNDgsIDM5LCAzMiwgMzksIDcyLCAzOSwgMTEyLCAzOSwgMTUyLAorMzksIDE5MiwgMzksIDIzMiwgNDAsIDE2LCA0MCwgNTYsIDQwLCA5NiwgNDAsIDEzNiwgNDAsIDE3NiwgNDAsIDIxNiwKKzQxLCAwLCA0MSwgNDAsIDQxLCA4MCwgNDEsIDEyMCwgNDEsIDE2MCwgNDEsIDIwMCwgNDEsIDI0MCwgNDIsIDI0LAorNDIsIDY0LCA0MiwgMTA0LCA0MiwgMTQ0LCA0MiwgMTg0LCA0MiwgMjI0LCA0MywgOCwgNDMsIDQ4LCA0MywgODgsCis0MywgMTI4LCA0MywgMTY4LCA0MywgMjA4LCA0MywgMjQ4LCA0NCwgMzIsIDQ0LCA3MiwgNDQsIDExMiwgNDQsIDE1MiwKKzQ0LCAxOTIsIDQ0LCAyMzIsIDQ1LCAxNiwgNDUsIDU2LCA0NSwgOTYsIDQ1LCAxMzYsIDQ1LCAxNzYsIDQ1LCAyMTYsCis0NiwgMCwgNDYsIDQwLCA0NiwgODAsIDQ2LCAxMjAsIDQ2LCAxNjAsIDQ2LCAyMDAsIDQ2LCAyNDAsIDQ3LCAyNCwKKzQ3LCA2NCwgNDcsIDEwNCwgNDcsIDE0NCwgNDcsIDE4NCwgNDcsIDIyNCwgNDgsIDgsIDQ4LCA0OCwgNDgsIDg4LAorNDgsIDEyOCwgNDgsIDE2OCwgNDgsIDIwOCwgNDgsIDI0OCwgNDksIDMyLCA0OSwgNzIsIDQ5LCAxMTIsIDQ5LCAxNTIsCis0OSwgMTkyLCA0OSwgMjMyLCA1MCwgMTYsIDUwLCA1NiwgNTAsIDk2LCA1MCwgMTM2LCA1MCwgMTc2LCA1MCwgMjE2LAorNTEsIDAsIDUxLCA0MCwgNTEsIDgwLCA1MSwgMTIwLCA1MSwgMTYwLCA1MSwgMjAwLCA1MSwgMjQwLCA1MiwgMjQsCis1MiwgNjQsIDUyLCAxMDQsIDUyLCAxNDQsIDUyLCAxODQsIDUyLCAyMjQsIDUzLCA4LCA1MywgNDgsIDUzLCA4OCwKKzUzLCAxMjgsIDUzLCAxNjgsIDUzLCAyMDgsIDUzLCAyNDgsIDU0LCAzMiwgNTQsIDcyLCA1NCwgMTEyLCA1NCwgMTUyLAorNTQsIDE5MiwgNTQsIDIzMiwgNTUsIDE2LCA1NSwgNTYsIDU1LCA5NiwgNTUsIDEzNiwgNTUsIDE3NiwgNTUsIDIxNiwKKzU2LCAwLCA1NiwgNDAsIDU2LCA4MCwgNTYsIDEyMCwgNTYsIDE2MCwgNTYsIDIwMCwgNTYsIDI0MCwgNTcsIDI0LAorNTcsIDY0LCA1NywgMTA0LCA1NywgMTQ0LCA1NywgMTg0LCA1NywgMjI0LCA1OCwgOCwgNTgsIDQ4LCA1OCwgODgsCis1OCwgMTI4LCA1OCwgMTY4LCA1OCwgMjA4LCA1OCwgMjQ4LCA1OSwgMzIsIDU5LCA3MiwgNTksIDExMiwgNTksIDE1MiwKKzU5LCAxOTIsIDU5LCAyMzIsIDYwLCAxNiwgNjAsIDU2LCA2MCwgOTYsIDYwLCAxMzYsIDYwLCAxNzYsIDYwLCAyMTYsCis2MSwgMCwgNjEsIDQwLCA2MSwgODAsIDYxLCAxMjAsIDYxLCAxNjAsIDYxLCAyMDAsIDYxLCAyNDAsIDYyLCAyNCwKKzYyLCA2NCwgNjIsIDEwNCwgNjIsIDE0NCwgNjIsIDE4NCwgNjIsIDIyNCwgNjMsIDgsIDYzLCA0OCwgNjMsIDg4LAorNjMsIDEyOCwgNjMsIDE2OCwgNjMsIDIwOCwgNjMsIDI0OCwgNjQsIDMyLCA2NCwgNzIsIDY0LCAxMTIsIDY0LCAxNTIsCis2NCwgMTkyLCA2NCwgMjMyLCA2NSwgMTYsIDY1LCA1NiwgNjUsIDk2LCA2NSwgMTM2LCA2NSwgMTc2LCA2NSwgMjE2LAorNjYsIDAsIDY2LCA0MCwgNjYsIDgwLCA2NiwgMTIwLCA2NiwgMTYwLCA2NiwgMjAwLCA2NiwgMjQwLCA2NywgMjQsCis2NywgNjQsIDY3LCAxMDQsIDY3LCAxNDQsIDY3LCAxODQsIDY3LCAyMjQsIDY4LCA4LCA2OCwgNDgsIDY4LCA4OCwKKzY4LCAxMjgsIDY4LCAxNjgsIDY4LCAyMDgsIDY4LCAyNDgsIDY5LCAzMiwgNjksIDcyLCA2OSwgMTEyLCA2OSwgMTUyLAorNjksIDE5MiwgNjksIDIzMiwgNzAsIDE2LCA3MCwgNTYsIDcwLCA5NiwgNzAsIDEzNiwgNzAsIDE3NiwgNzAsIDIxNiwKKzcxLCAwLCA3MSwgNDAsIDcxLCA4MCwgNzEsIDEyMCwgNzEsIDE2MCwgNzEsIDIwMCwgNzEsIDI0MCwgNzIsIDI0LAorNzIsIDY0LCA3MiwgMTA0LCA3MiwgMTQ0LCA3MiwgMTg0LCA3MiwgMjI0LCA3MywgOCwgNzMsIDQ4LCA3MywgODgsCis3MywgMTI4LCA3MywgMTY4LCA3MywgMjA4LCA3MywgMjQ4LCA3NCwgMzIsIDc0LCA3MiwgNzQsIDExMiwgNzQsIDE1MiwKKzc0LCAxOTIsIDc0LCAyMzIsIDc1LCAxNiwgNzUsIDU2LCA3NSwgOTYsIDc1LCAxMzYsIDc1LCAxNzYsIDc1LCAyMTYsCis3NiwgMCwgNzYsIDQwLCA3NiwgODAsIDc2LCAxMjAsIDc2LCAxNjAsIDc2LCAyMDAsIDc2LCAyNDAsIDc3LCAyNCwKKzc3LCA2NCwgNzcsIDEwNCwgNzcsIDE0NCwgNzcsIDE4NCwgNzcsIDIyNCwgNzgsIDgsIDc4LCA0OCwgNzgsIDg4LAorNzgsIDEyOCwgNzgsIDE2OCwgNzgsIDIwOCwgNzgsIDI0OCwgNzksIDMyLCA3OSwgNzIsIDc5LCAxMTIsIDc5LCAxNTIsCis3OSwgMTkyLCA3OSwgMjMyLCA4MCwgMTYsIDgwLCA1NiwgODAsIDk2LCA4MCwgMTM2LCA4MCwgMTc2LCA4MCwgMjE2LAorODEsIDAsIDgxLCA0MCwgODEsIDgwLCA4MSwgMTIwLCA4MSwgMTYwLCA4MSwgMjAwLCA4MSwgMjQwLCA4MiwgMjQsCis4MiwgNjQsIDgyLCAxMDQsIDgyLCAxNDQsIDgyLCAxODQsIDgyLCAyMjQsIDgzLCA4LCA4MywgNDgsIDgzLCA4OCwKKzgzLCAxMjgsIDgzLCAxNjgsIDgzLCAyMDgsIDgzLCAyNDgsIDg0LCAzMiwgODQsIDcyLCA4NCwgMTEyLCA4NCwgMTUyLAorODQsIDE5MiwgODQsIDIzMiwgODUsIDE2LCA4NSwgNTYsIDg1LCA5NiwgODUsIDEzNiwgODUsIDE3NiwgODUsIDIxNiwKKzg2LCAwLCA4NiwgNDAsIDg2LCA4MCwgODYsIDEyMCwgODYsIDE2MCwgODYsIDIwMCwgODYsIDI0MCwgODcsIDI0LAorODcsIDY0LCA4NywgMTA0LCA4NywgMTQ0LCA4NywgMTg0LCA4NywgMjI0LCA4OCwgOCwgODgsIDQ4LCA4OCwgODgsCis4OCwgMTI4LCA4OCwgMTY4LCA4OCwgMjA4LCA4OCwgMjQ4LCA4OSwgMzIsIDg5LCA3MiwgODksIDExMiwgODksIDE1MiwKKzg5LCAxOTIsIDg5LCAyMzIsIDkwLCAxNiwgOTAsIDU2LCA5MCwgOTYsIDkwLCAxMzYsIDkwLCAxNzYsIDkwLCAyMTYsCis5MSwgMCwgOTEsIDQwLCA5MSwgODAsIDkxLCAxMjAsIDkxLCAxNjAsIDkxLCAyMDAsIDkxLCAyNDAsIDkyLCAyNCwKKzkyLCA2NCwgOTIsIDEwNCwgOTIsIDE0NCwgOTIsIDE4NCwgOTIsIDIyNCwgOTMsIDgsIDkzLCA0OCwgOTMsIDg4LAorOTMsIDEyOCwgOTMsIDE2OCwgOTMsIDIwOCwgOTMsIDI0OCwgOTQsIDMyLCA5NCwgNzIsIDk0LCAxMTIsIDk0LCAxNTIsCis5NCwgMTkyLCA5NCwgMjMyLCA5NSwgMTYsIDk1LCA1NiwgOTUsIDk2LCA5NSwgMTM2LCA5NSwgMTc2LCA5NSwgMjE2LAorOTYsIDAsIDk2LCA0MCwgOTYsIDgwLCA5NiwgMTIwLCA5NiwgMTYwLCA5NiwgMjAwLCA5NiwgMjQwLCA5NywgMjQsCis5NywgNjQsIDk3LCAxMDQsIDk3LCAxNDQsIDk3LCAxODQsIDk3LCAyMjQsIDk4LCA4LCA5OCwgNDgsIDk4LCA4OCwKKzk4LCAxMjgsIDk4LCAxNjgsIDk4LCAyMDgsIDk4LCAyNDgsIDk5LCAzMiwgOTksIDcyLCA5OSwgMTEyLCA5OSwgMTUyLAorOTksIDE5MiwgOTksIDIzMiwgMTAwLCAxNiwgMTAwLCA1NiwgMTAwLCA5NiwgMTAwLCAxMzYsIDEwMCwgMTc2LCAxMDAsIDIxNiwKKzEwMSwgMCwgMTAxLCA0MCwgMTAxLCA4MCwgMTAxLCAxMjAsIDEwMSwgMTYwLCAxMDEsIDIwMCwgMTAxLCAyNDAsIDEwMiwgMjQsCisxMDIsIDY0LCAxMDIsIDEwNCwgMTAyLCAxNDQsIDEwMiwgMTg0LCAxMDIsIDIyNCwgMTAzLCA4LCAxMDMsIDQ4LCAxMDMsIDg4LAorMTAzLCAxMjgsIDEwMywgMTY4LCAxMDMsIDIwOCwgMTAzLCAyNDgsIDEwNCwgMzIsIDEwNCwgNzIsIDEwNCwgMTEyLCAxMDQsIDE1MiwKKzEwNCwgMTkyLCAxMDQsIDIzMiwgMTA1LCAxNiwgMTA1LCA1NiwgMTA1LCA5NiwgMTA1LCAxMzYsIDEwNSwgMTc2LCAxMDUsIDIxNiwKKzEwNiwgMCwgMTA2LCA0MCwgMTA2LCA4MCwgMTA2LCAxMjAsIDEwNiwgMTYwLCAxMDYsIDIwMCwgMTA2LCAyNDAsIDEwNywgMjQsCisxMDcsIDY0LCAxMDcsIDEwNCwgMTA3LCAxNDQsIDEwNywgMTg0LCAxMDcsIDIyNCwgMTA4LCA4LCAxMDgsIDQ4LCAxMDgsIDg4LAorMTA4LCAxMjgsIDEwOCwgMTY4LCAxMDgsIDIwOCwgMTA4LCAyNDgsIDEwOSwgMzIsIDEwOSwgNzIsIDEwOSwgMTEyLCAxMDksIDE1MiwKKzEwOSwgMTkyLCAxMDksIDIzMiwgMTEwLCAxNiwgMTEwLCA1NiwgMTEwLCA5NiwgMTEwLCAxMzYsIDExMCwgMTc2LCAxMTAsIDIxNiwKKzExMSwgMCwgMTExLCA0MCwgMTExLCA4MCwgMTExLCAxMjAsIDExMSwgMTYwLCAxMTEsIDIwMCwgMTExLCAyNDAsIDExMiwgMjQsCisxMTIsIDY0LCAxMTIsIDEwNCwgMTEyLCAxNDQsIDExMiwgMTg0LCAxMTIsIDIyNCwgMTEzLCA4LCAxMTMsIDQ4LCAxMTMsIDg4LAorMTEzLCAxMjgsIDExMywgMTY4LCAxMTMsIDIwOCwgMTEzLCAyNDgsIDExNCwgMzIsIDExNCwgNzIsIDExNCwgMTEyLCAxMTQsIDE1MiwKKzExNCwgMTkyLCAxMTQsIDIzMiwgMTE1LCAxNiwgMTE1LCA1NiwgMTE1LCA5NiwgMTE1LCAxMzYsIDExNSwgMTc2LCAxMTUsIDIxNiwKKzExNiwgMCwgMTE2LCA0MCwgMTE2LCA4MCwgMTE2LCAxMjAsIDExNiwgMTYwLCAxMTYsIDIwMCwgMTE2LCAyNDAsIDExNywgMjQsCisxMTcsIDY0LCAxMTcsIDEwNCwgMTE3LCAxNDQsIDExNywgMTg0LCAxMTcsIDIyNCwgMTE4LCA4LCAxMTgsIDQ4LCAxMTgsIDg4LAorMTE4LCAxMjgsIDExOCwgMTY4LCAxMTgsIDIwOCwgMTE4LCAyNDgsIDExOSwgMzIsIDExOSwgNzIsIDExOSwgMTEyLCAxMTksIDE1MiwKKzExOSwgMTkyLCAxMTksIDIzMiwgMTIwLCAxNiwgMTIwLCA1NiwgMTIwLCA5NiwgMTIwLCAxMzYsIDEyMCwgMTc2LCAxMjAsIDIxNiwKKzEyMSwgMCwgMTIxLCA0MCwgMTIxLCA4MCwgMTIxLCAxMjAsIDEyMSwgMTYwLCAxMjEsIDIwMCwgMTIxLCAyNDAsIDEyMiwgMjQsCisxMjIsIDY0LCAxMjIsIDEwNCwgMTIyLCAxNDQsIDEyMiwgMTg0LCAxMjIsIDIyNCwgMTIzLCA4LCAxMjMsIDQ4LCAxMjMsIDg4LAorMTIzLCAxMjgsIDEyMywgMTY4LCAxMjMsIDIwOCwgMTIzLCAyNDgsIDEyNCwgMzIsIDEyNCwgNzIsIDEyNCwgMTEyLCAxMjQsIDE1MiwKKzEyNCwgMTkyLCAxMjQsIDIzMiwgMTI1LCAxNiwgMTI1LCA1NiwgMTI1LCA5NiwgMTI1LCAxMzYsIDEyNSwgMTc2LCAxMjUsIDIxNiwKKzEyNiwgMCwgMTI2LCA0MCwgMTI2LCA4MCwgMTI2LCAxMjAsIDEyNiwgMTYwLCAxMjYsIDIwMCwgMTI2LCAyNDAsIDEyNywgMjQsCisxMjcsIDY0LCAxMjcsIDEwNCwgMTI3LCAxNDQsIDEyNywgMTg0LCAxMjcsIDIyNCwgMTI4LCA4LCAxMjgsIDQ4LCAxMjgsIDg4LAorMTI4LCAxMjgsIDEyOCwgMTY4LCAxMjgsIDIwOCwgMTI4LCAyNDgsIDEyOSwgMzIsIDEyOSwgNzIsIDEyOSwgMTEyLCAxMjksIDE1MiwKKzEyOSwgMTkyLCAxMjksIDIzMiwgMTMwLCAxNiwgMTMwLCA1NiwgMTMwLCA5NiwgMTMwLCAxMzYsIDEzMCwgMTc2LCAxMzAsIDIxNiwKKzEzMSwgMCwgMTMxLCA0MCwgMTMxLCA4MCwgMTMxLCAxMjAsIDEzMSwgMTYwLCAxMzEsIDIwMCwgMTMxLCAyNDAsIDEzMiwgMjQsCisxMzIsIDY0LCAxMzIsIDEwNCwgMTMyLCAxNDQsIDEzMiwgMTg0LCAxMzIsIDIyNCwgMTMzLCA4LCAxMzMsIDQ4LCAxMzMsIDg4LAorMTMzLCAxMjgsIDEzMywgMTY4LCAxMzMsIDIwOCwgMTMzLCAyNDgsIDEzNCwgMzIsIDEzNCwgNzIsIDEzNCwgMTEyLCAxMzQsIDE1MiwKKzEzNCwgMTkyLCAxMzQsIDIzMiwgMTM1LCAxNiwgMTM1LCA1NiwgMTM1LCA5NiwgMTM1LCAxMzYsIDEzNSwgMTc2LCAxMzUsIDIxNiwKKzEzNiwgMCwgMTM2LCA0MCwgMTM2LCA4MCwgMTM2LCAxMjAsIDEzNiwgMTYwLCAxMzYsIDIwMCwgMTM2LCAyNDAsIDEzNywgMjQsCisxMzcsIDY0LCAxMzcsIDEwNCwgMTM3LCAxNDQsIDEzNywgMTg0LCAxMzcsIDIyNCwgMTM4LCA4LCAxMzgsIDQ4LCAxMzgsIDg4LAorMTM4LCAxMjgsIDEzOCwgMTY4LCAxMzgsIDIwOCwgMTM4LCAyNDgsIDEzOSwgMzIsIDEzOSwgNzIsIDEzOSwgMTEyLCAxMzksIDE1MiwKKzEzOSwgMTkyLCAxMzksIDIzMiwgMTQwLCAxNiwgMTQwLCA1NiwgMTQwLCA5NiwgMTQwLCAxMzYsIDE0MCwgMTc2LCAxNDAsIDIxNiwKKzE0MSwgMCwgMTQxLCA0MCwgMTQxLCA4MCwgMTQxLCAxMjAsIDE0MSwgMTYwLCAxNDEsIDIwMCwgMTQxLCAyNDAsIDE0MiwgMjQsCisxNDIsIDY0LCAxNDIsIDEwNCwgMTQyLCAxNDQsIDE0MiwgMTg0LCAxNDIsIDIyNCwgMTQzLCA4LCAxNDMsIDQ4LCAxNDMsIDg4LAorMTQzLCAxMjgsIDE0MywgMTY4LCAxNDMsIDIwOCwgMTQzLCAyNDgsIDE0NCwgMzIsIDE0NCwgNzIsIDE0NCwgMTEyLCAxNDQsIDE1MiwKKzE0NCwgMTkyLCAxNDQsIDIzMiwgMTQ1LCAxNiwgMTQ1LCA1NiwgMTQ1LCA5NiwgMTQ1LCAxMzYsIDE0NSwgMTc2LCAxNDUsIDIxNiwKKzE0NiwgMCwgMTQ2LCA0MCwgMTQ2LCA4MCwgMTQ2LCAxMjAsIDE0NiwgMTYwLCAxNDYsIDIwMCwgMTQ2LCAyNDAsIDE0NywgMjQsCisxNDcsIDY0LCAxNDcsIDEwNCwgMTQ3LCAxNDQsIDE0NywgMTg0LCAxNDcsIDIyNCwgMTQ4LCA4LCAxNDgsIDQ4LCAxNDgsIDg4LAorMTQ4LCAxMjgsIDE0OCwgMTY4LCAxNDgsIDIwOCwgMTQ4LCAyNDgsIDE0OSwgMzIsIDE0OSwgNzIsIDE0OSwgMTEyLCAxNDksIDE1MiwKKzE0OSwgMTkyLCAxNDksIDIzMiwgMTUwLCAxNiwgMTUwLCA1NiwgMTUwLCA5NiwgMTUwLCAxMzYsIDE1MCwgMTc2LCAxNTAsIDIxNiwKKzE1MSwgMCwgMTUxLCA0MCwgMTUxLCA4MCwgMTUxLCAxMjAsIDE1MSwgMTYwLCAxNTEsIDIwMCwgMTUxLCAyNDAsIDE1MiwgMjQsCisxNTIsIDY0LCAxNTIsIDEwNCwgMTUyLCAxNDQsIDE1MiwgMTg0LCAxNTIsIDIyNCwgMTUzLCA4LCAxNTMsIDQ4LCAxNTMsIDg4LAorMTUzLCAxMjgsIDE1MywgMTY4LCAxNTMsIDIwOCwgMTUzLCAyNDgsIDE1NCwgMzIsIDE1NCwgNzIsIDE1NCwgMTEyLCAxNTQsIDE1MiwKKzE1NCwgMTkyLCAxNTQsIDIzMiwgMTU1LCAxNiwgMTU1LCA1NiwgMTU1LCA5NiwgMTU1LCAxMzYsIDE1NSwgMTc2LCAxNTUsIDIxNiwKKzE1NiwgMCwgMTU2LCA0MCwgMTU2LCA4MCwgMTU2LCAxMjAsIDE1NiwgMTYwLCAxNTYsIDIwMCwgMTU2LCAyNDAsIDE1NywgMjQsCisxNTcsIDY0LCAxNTcsIDEwNCwgMTU3LCAxNDQsIDE1NywgMTg0LCAxNTcsIDIyNCwgMTU4LCA4LCAxNTgsIDQ4LCAxNTgsIDg4LAorMTU4LCAxMjgsIDE1OCwgMTY4LCAxNTgsIDIwOCwgMTU4LCAyNDgsIDE1OSwgMzIsIDE1OSwgNzIsIDE1OSwgMTEyLCAxNTksIDE1MiwKKzE1OSwgMTkyLCAxNTksIDIzMiwgMTYwLCAxNiwgMTYwLCA1NiwgMTYwLCA5NiwgMTYwLCAxMzYsIDE2MCwgMTc2LCAxNjAsIDIxNiwKKzE2MSwgMCwgMTYxLCA0MCwgMTYxLCA4MCwgMTYxLCAxMjAsIDE2MSwgMTYwLCAxNjEsIDIwMCwgMTYxLCAyNDAsIDE2MiwgMjQsCisxNjIsIDY0LCAxNjIsIDEwNCwgMTYyLCAxNDQsIDE2MiwgMTg0LCAxNjIsIDIyNCwgMTYzLCA4LCAxNjMsIDQ4LCAxNjMsIDg4LAorMTYzLCAxMjgsIDE2MywgMTY4LCAxNjMsIDIwOCwgMTYzLCAyNDgsIDE2NCwgMzIsIDE2NCwgNzIsIDE2NCwgMTEyLCAxNjQsIDE1MiwKKzE2NCwgMTkyLCAxNjQsIDIzMiwgMTY1LCAxNiwgMTY1LCA1NiwgMTY1LCA5NiwgMTY1LCAxMzYsIDE2NSwgMTc2LCAxNjUsIDIxNiwKKzE2NiwgMCwgMTY2LCA0MCwgMTY2LCA4MCwgMTY2LCAxMjAsIDE2NiwgMTYwLCAxNjYsIDIwMCwgMTY2LCAyNDAsIDE2NywgMjQsCisxNjcsIDY0LCAxNjcsIDEwNCwgMTY3LCAxNDQsIDE2NywgMTg0LCAxNjcsIDIyNCwgMTY4LCA4LCAxNjgsIDQ4LCAxNjgsIDg4LAorMTY4LCAxMjgsIDE2OCwgMTY4LCAxNjgsIDIwOCwgMTY4LCAyNDgsIDE2OSwgMzIsIDE2OSwgNzIsIDE2OSwgMTEyLCAxNjksIDE1MiwKKzE2OSwgMTkyLCAxNjksIDIzMiwgMTcwLCAxNiwgMTcwLCA1NiwgMTcwLCA5NiwgMTcwLCAxMzYsIDE3MCwgMTc2LCAxNzAsIDIxNiwKKzE3MSwgMCwgMTcxLCA0MCwgMTcxLCA4MCwgMTcxLCAxMjAsIDE3MSwgMTYwLCAxNzEsIDIwMCwgMTcxLCAyNDAsIDE3MiwgMjQsCisxNzIsIDY0LCAxNzIsIDEwNCwgMTcyLCAxNDQsIDE3MiwgMTg0LCAxNzIsIDIyNCwgMTczLCA4LCAxNzMsIDQ4LCAxNzMsIDg4LAorMTczLCAxMjgsIDE3MywgMTY4LCAxNzMsIDIwOCwgMTczLCAyNDgsIDE3NCwgMzIsIDE3NCwgNzIsIDE3NCwgMTEyLCAxNzQsIDE1MiwKKzE3NCwgMTkyLCAxNzQsIDIzMiwgMTc1LCAxNiwgMTc1LCA1NiwgMTc1LCA5NiwgMTc1LCAxMzYsIDE3NSwgMTc2LCAxNzUsIDIxNiwKKzE3NiwgMCwgMTc2LCA0MCwgMTc2LCA4MCwgMTc2LCAxMjAsIDE3NiwgMTYwLCAxNzYsIDIwMCwgMTc2LCAyNDAsIDE3NywgMjQsCisxNzcsIDY0LCAxNzcsIDEwNCwgMTc3LCAxNDQsIDE3NywgMTg0LCAxNzcsIDIyNCwgMTc4LCA4LCAxNzgsIDQ4LCAxNzgsIDg4LAorMTc4LCAxMjgsIDE3OCwgMTY4LCAxNzgsIDIwOCwgMTc4LCAyNDgsIDE3OSwgMzIsIDE3OSwgNzIsIDE3OSwgMTEyLCAxNzksIDE1MiwKKzE3OSwgMTkyLCAxNzksIDIzMiwgMTgwLCAxNiwgMTgwLCA1NiwgMTgwLCA5NiwgMTgwLCAxMzYsIDE4MCwgMTc2LCAxODAsIDIxNiwKKzE4MSwgMCwgMTgxLCA0MCwgMTgxLCA4MCwgMTgxLCAxMjAsIDE4MSwgMTYwLCAxODEsIDIwMCwgMTgxLCAyNDAsIDE4MiwgMjQsCisxODIsIDY0LCAxODIsIDEwNCwgMTgyLCAxNDQsIDE4MiwgMTg0LCAxODIsIDIyNCwgMTgzLCA4LCAxODMsIDQ4LCAxODMsIDg4LAorMTgzLCAxMjgsIDE4MywgMTY4LCAxODMsIDIwOCwgMTgzLCAyNDgsIDE4NCwgMzIsIDE4NCwgNzIsIDE4NCwgMTEyLCAxODQsIDE1MiwKKzE4NCwgMTkyLCAxODQsIDIzMiwgMTg1LCAxNiwgMTg1LCA1NiwgMTg1LCA5NiwgMTg1LCAxMzYsIDE4NSwgMTc2LCAxODUsIDIxNiwKKzE4NiwgMCwgMTg2LCA0MCwgMTg2LCA4MCwgMTg2LCAxMjAsIDE4NiwgMTYwLCAxODYsIDIwMCwgMTg2LCAyNDAsIDE4NywgMjQsCisxODcsIDY0LCAxODcsIDEwNCwgMTg3LCAxNDQsIDE4NywgMTg0LCAxODcsIDIyNCwgMTg4LCA4LCAxODgsIDQ4LCAxODgsIDg4LAorMTg4LCAxMjgsIDE4OCwgMTY4LCAxODgsIDIwOCwgMTg4LCAyNDgsIDE4OSwgMzIsIDE4OSwgNzIsIDE4OSwgMTEyLCAxODksIDE1MiwKKzE4OSwgMTkyLCAxODksIDIzMiwgMTkwLCAxNiwgMTkwLCA1NiwgMTkwLCA5NiwgMTkwLCAxMzYsIDE5MCwgMTc2LCAxOTAsIDIxNiwKKzE5MSwgMCwgMTkxLCA0MCwgMTkxLCA4MCwgMTkxLCAxMjAsIDE5MSwgMTYwLCAxOTEsIDIwMCwgMTkxLCAyNDAsIDE5MiwgMjQsCisxOTIsIDY0LCAxOTIsIDEwNCwgMTkyLCAxNDQsIDE5MiwgMTg0LCAxOTIsIDIyNCwgMTkzLCA4LCAxOTMsIDQ4LCAxOTMsIDg4LAorMTkzLCAxMjgsIDE5MywgMTY4LCAxOTMsIDIwOCwgMTkzLCAyNDgsIDE5NCwgMzIsIDE5NCwgNzIsIDE5NCwgMTEyLCAxOTQsIDE1MiwKKzE5NCwgMTkyLCAxOTQsIDIzMiwgMTk1LCAxNiwgMTk1LCA1NiwgMTk1LCA5NiwgMTk1LCAxMzYsIDE5NSwgMTc2LCAxOTUsIDIxNiwKKzE5NiwgMCwgMTk2LCA0MCwgMTk2LCA4MCwgMTk2LCAxMjAsIDE5NiwgMTYwLCAxOTYsIDIwMCwgMTk2LCAyNDAsIDE5NywgMjQsCisxOTcsIDY0LCAxOTcsIDEwNCwgMTk3LCAxNDQsIDE5NywgMTg0LCAxOTcsIDIyNCwgMTk4LCA4LCAxOTgsIDQ4LCAxOTgsIDg4LAorMTk4LCAxMjgsIDE5OCwgMTY4LCAxOTgsIDIwOCwgMTk4LCAyNDgsIDE5OSwgMzIsIDE5OSwgNzIsIDE5OSwgMTEyLCAxOTksIDE1MiwKKzE5OSwgMTkyLCAxOTksIDIzMiwgMjAwLCAxNiwgMjAwLCA1NiwgMjAwLCA5NiwgMjAwLCAxMzYsIDIwMCwgMTc2LCAyMDAsIDIxNiwKKzIwMSwgMCwgMjAxLCA0MCwgMjAxLCA4MCwgMjAxLCAxMjAsIDIwMSwgMTYwLCAyMDEsIDIwMCwgMjAxLCAyNDAsIDIwMiwgMjQsCisyMDIsIDY0LCAyMDIsIDEwNCwgMjAyLCAxNDQsIDIwMiwgMTg0LCAyMDIsIDIyNCwgMjAzLCA4LCAyMDMsIDQ4LCAyMDMsIDg4LAorMjAzLCAxMjgsIDIwMywgMTY4LCAyMDMsIDIwOCwgMjAzLCAyNDgsIDIwNCwgMzIsIDIwNCwgNzIsIDIwNCwgMTEyLCAyMDQsIDE1MiwKKzIwNCwgMTkyLCAyMDQsIDIzMiwgMjA1LCAxNiwgMjA1LCA1NiwgMjA1LCA5NiwgMjA1LCAxMzYsIDIwNSwgMTc2LCAyMDUsIDIxNiwKKzIwNiwgMCwgMjA2LCA0MCwgMjA2LCA4MCwgMjA2LCAxMjAsIDIwNiwgMTYwLCAyMDYsIDIwMCwgMjA2LCAyNDAsIDIwNywgMjQsCisyMDcsIDY0LCAyMDcsIDEwNCwgMjA3LCAxNDQsIDIwNywgMTg0LCAyMDcsIDIyNCwgMjA4LCA4LCAyMDgsIDQ4LCAyMDgsIDg4LAorMjA4LCAxMjgsIDIwOCwgMTY4LCAyMDgsIDIwOCwgMjA4LCAyNDgsIDIwOSwgMzIsIDIwOSwgNzIsIDIwOSwgMTEyLCAyMDksIDE1MiwKKzIwOSwgMTkyLCAyMDksIDIzMiwgMjEwLCAxNiwgMjEwLCA1NiwgMjEwLCA5NiwgMjEwLCAxMzYsIDIxMCwgMTc2LCAyMTAsIDIxNiwKKzIxMSwgMCwgMjExLCA0MCwgMjExLCA4MCwgMjExLCAxMjAsIDIxMSwgMTYwLCAyMTEsIDIwMCwgMjExLCAyNDAsIDIxMiwgMjQsCisyMTIsIDY0LCAyMTIsIDEwNCwgMjEyLCAxNDQsIDIxMiwgMTg0LCAyMTIsIDIyNCwgMjEzLCA4LCAyMTMsIDQ4LCAyMTMsIDg4LAorMjEzLCAxMjgsIDIxMywgMTY4LCAyMTMsIDIwOCwgMjEzLCAyNDgsIDIxNCwgMzIsIDIxNCwgNzIsIDIxNCwgMTEyLCAyMTQsIDE1MiwKKzIxNCwgMTkyLCAyMTQsIDIzMiwgMjE1LCAxNiwgMjE1LCA1NiwgMjE1LCA5NiwgMjE1LCAxMzYsIDIxNSwgMTc2LCAyMTUsIDIxNiwKKzIyNCwgMCwgMjI0LCA0MCwgMjI0LCA4MCwgMjI0LCAxMjAsIDIyNCwgMTYwLCAyMjQsIDIwMCwgMjI0LCAyNDAsIDIyNSwgMjQsCisyMjUsIDY0LCAyMjUsIDEwNCwgMjI1LCAxNDQsIDIyNSwgMTg0LCAyMjUsIDIyNCwgMjI2LCA4LCAyMjYsIDQ4LCAyMjYsIDg4LAorMjI2LCAxMjgsIDIyNiwgMTY4LCAyMjYsIDIwOCwgMjI2LCAyNDgsIDIyNywgMzIsIDIyNywgNzIsIDIyNywgMTEyLCAyMjcsIDE1MiwKKzIyNywgMTkyLCAyMjcsIDIzMiwgMjI4LCAxNiwgMjI4LCA1NiwgMjI4LCA5NiwgMjI4LCAxMzYsIDIyOCwgMTc2LCAyMjgsIDIxNiwKKzIyOSwgMCwgMjI5LCA0MCwgMjI5LCA4MCwgMjI5LCAxMjAsIDIyOSwgMTYwLCAyMjksIDIwMCwgMjI5LCAyNDAsIDIzMCwgMjQsCisyMzAsIDY0LCAyMzAsIDEwNCwgMjMwLCAxNDQsIDIzMCwgMTg0LCAyMzAsIDIyNCwgMjMxLCA4LCAyMzEsIDQ4LCAyMzEsIDg4LAorMjMxLCAxMjgsIDIzMSwgMTY4LCAyMzEsIDIwOCwgMjMxLCAyNDgsIDIzMiwgMzIsIDIzMiwgNzIsIDIzMiwgMTEyLCAyMzIsIDE1MiwKKzIzMiwgMTkyLCAyMzIsIDIzMiwgMjMzLCAxNiwgMjMzLCA1NiwgMjMzLCA5NiwgMjMzLCAxMzYsIDIzMywgMTc2LCAyMzMsIDIxNiwKKzIzNCwgMCwgMjM0LCA0MCwgMjM0LCA4MCwgMjM0LCAxMjAsIDIzNCwgMTYwLCAyMzQsIDIwMCwgMjM0LCAyNDAsIDIzNSwgMjQsCisyMzUsIDY0LCAyMzUsIDEwNCwgMjM1LCAxNDQsIDIzNSwgMTg0LCAyMzUsIDIyNCwgMjM2LCA4LCAyMzYsIDQ4LCAyMzYsIDg4LAorMjM2LCAxMjgsIDIzNiwgMTY4LCAyMzYsIDIwOCwgMjM2LCAyNDgsIDIzNywgMzIsIDIzNywgNzIsIDIzNywgMTEyLCAyMzcsIDE1MiwKKzIzNywgMTkyLCAyMzcsIDIzMiwgMjM4LCAxNiwgMjM4LCA1NiwgMjM4LCA5NiwgMjM4LCAxMzYsIDIzOCwgMTc2LCAyMzgsIDIxNiwKKzIzOSwgMCwgMjM5LCA0MCwgMjM5LCA4MCwgMjM5LCAxMjAsIDIzOSwgMTYwLCAyMzksIDIwMCwgMjM5LCAyNDAsIDI0MCwgMjQsCisyNDAsIDY0LCAyNDAsIDEwNCwgMjQwLCAxNDQsIDI0MCwgMTg0LCAyNDAsIDIyNCwgMjQxLCA4LCAyNDEsIDQ4LCAyNDEsIDg4LAorMjQxLCAxMjgsIDI0MSwgMTY4LCAyNDEsIDIwOCwgMjQxLCAyNDgsIDI0MiwgMzIsIDI0MiwgNzIsIDI0MiwgMTEyLCAyNDIsIDE1MiwKKzI0MiwgMTkyLCAyNDIsIDIzMiwgMjQzLCAxNiwgMjQzLCA1NiwgMjQzLCA5NiwgMjQzLCAxMzYsIDI0MywgMTc2LCAyNDMsIDIxNiwKKzI0NCwgMCwgMjQ0LCA0MCwgMjQ0LCA4MCwgMjQ0LCAxMjAsIDI0NCwgMTYwLCAyNDQsIDIwMCwgMjQ0LCAyNDAsIDI0NSwgMjQsCisyNDUsIDY0LCAyNDUsIDEwNCwgMjQ1LCAxNDQsIDI0NSwgMTg0LCAyNDUsIDIyNCwgMjQ2LCA4LCAyNDYsIDQ4LCAyNDYsIDg4LAorMjQ2LCAxMjgsIDI0NiwgMTY4LCAyNDYsIDIwOCwgMjQ2LCAyNDgsIDI0NywgMzIsIDI0NywgNzIsIDI0NywgMTEyLCAyNDcsIDE1MiwKKzI0NywgMTkyLCAyNDcsIDIzMiwgMjQ4LCAxNiwgMjQ4LCA1NiwgMjQ4LCA5NiwgMjQ4LCAxMzYsIDI0OCwgMTc2LCAyNDgsIDIxNiwKKzI0OSwgMCwgMjQ5LCA0MCwgMjQ5LCA4MCwgMjQ5LCAxMjAsIDI0OSwgMTYwLCAyNDksIDIwMCwgMjQ5LCAyNDAsIDI1MCwgMjQsCisyNTAsIDY0LCAyNTAsIDEwNCwgMjUwLCAxNDQsIDI1MCwgMTg0LCAyNTAsIDIyNCwgMjUxLCA4LCAyNTEsIDQ4LCAyNTEsIDg4LAorMjUxLCAxMjgsIDI1MSwgMTY4LCAyNTEsIDIwOCwgMjUxLCAyNDgsIDI1MiwgMzIsIDI1MiwgNzIsIDI1MiwgMTEyLCAyNTIsIDE1MiwKKzI1MiwgMTkyLCAyNTIsIDIzMiwgMjUzLCAxNiwgMjUzLCA1NiwgMjUzLCA5NiwgMjUzLCAxMzYsIDI1MywgMTc2LCAyNTMsIDIxNiwKKzI1NCwgMCwgMjU0LCA0MCwgMjU0LCA4MCwgMjU0LCAxMjAsIDI1NCwgMTYwLCAyNTQsIDIwMCwgMjU0LCAyNDAsIDI1NSwgMjQsCisyNTUsIDY0LCAyNTUsIDEwNCwgMjU1LCAxNDQsIDI1NSwgMTg0LCAyNTUsIDIyNAorICAgICAgICAgICAgfSk7CisKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9NdWx0aUJ5dGVfVVRGXzE2TEUuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9NdWx0aUJ5dGVfVVRGXzE2TEUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kODNkNzlkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X011bHRpQnl0ZV9VVEZfMTZMRS5qYXZhCkBAIC0wLDAgKzEsMzc4IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKK3B1YmxpYyBjbGFzcyBPbGRDaGFyc2V0X011bHRpQnl0ZV9VVEZfMTZMRSBleHRlbmRzIE9sZENoYXJzZXRfQWJzdHJhY3RUZXN0IHsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJzZXROYW1lID0gIlVURi0xNkxFIjsKKworICAgICAgICB0ZXN0Q2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKzAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKzMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCis2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKzgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisxMjgsIDEyOSwgMTMwLCAxMzEsIDEzMiwgMTMzLCAxMzQsIDEzNSwgMTM2LCAxMzcsIDEzOCwgMTM5LCAxNDAsIDE0MSwgMTQyLCAxNDMsCisxNDQsIDE0NSwgMTQ2LCAxNDcsIDE0OCwgMTQ5LCAxNTAsIDE1MSwgMTUyLCAxNTMsIDE1NCwgMTU1LCAxNTYsIDE1NywgMTU4LCAxNTksCisxNjAsIDE2MSwgMTYyLCAxNjMsIDE2NCwgMTY1LCAxNjYsIDE2NywgMTY4LCAxNjksIDE3MCwgMTcxLCAxNzIsIDE3MywgMTc0LCAxNzUsCisxNzYsIDE3NywgMTc4LCAxNzksIDE4MCwgMTgxLCAxODIsIDE4MywgMTg0LCAxODUsIDE4NiwgMTg3LCAxODgsIDE4OSwgMTkwLCAxOTEsCisxOTIsIDE5MywgMTk0LCAxOTUsIDE5NiwgMTk3LCAxOTgsIDE5OSwgMjAwLCAyMDEsIDIwMiwgMjAzLCAyMDQsIDIwNSwgMjA2LCAyMDcsCisyMDgsIDIwOSwgMjEwLCAyMTEsIDIxMiwgMjEzLCAyMTQsIDIxNSwgMjE2LCAyMTcsIDIxOCwgMjE5LCAyMjAsIDIyMSwgMjIyLCAyMjMsCisyMjQsIDIyNSwgMjI2LCAyMjcsIDIyOCwgMjI5LCAyMzAsIDIzMSwgMjMyLCAyMzMsIDIzNCwgMjM1LCAyMzYsIDIzNywgMjM4LCAyMzksCisyNDAsIDI0MSwgMjQyLCAyNDMsIDI0NCwgMjQ1LCAyNDYsIDI0NywgMjQ4LCAyNDksIDI1MCwgMjUxLCAyNTIsIDI1MywgMjU0LCAyNTUsCisyNTYsIDI5NiwgMzM2LCAzNzYsIDQxNiwgNDU2LCA0OTYsIDUzNiwgNTc2LCA2MTYsIDY1NiwgNjk2LCA3MzYsIDc3NiwgODE2LCA4NTYsCis4OTYsIDkzNiwgOTc2LCAxMDE2LCAxMDU2LCAxMDk2LCAxMTM2LCAxMTc2LCAxMjE2LCAxMjU2LCAxMjk2LCAxMzM2LCAxMzc2LCAxNDE2LCAxNDU2LCAxNDk2LAorMTUzNiwgMTU3NiwgMTYxNiwgMTY1NiwgMTY5NiwgMTczNiwgMTc3NiwgMTgxNiwgMTg1NiwgMTg5NiwgMTkzNiwgMTk3NiwgMjAxNiwgMjA1NiwgMjA5NiwgMjEzNiwKKzIxNzYsIDIyMTYsIDIyNTYsIDIyOTYsIDIzMzYsIDIzNzYsIDI0MTYsIDI0NTYsIDI0OTYsIDI1MzYsIDI1NzYsIDI2MTYsIDI2NTYsIDI2OTYsIDI3MzYsIDI3NzYsCisyODE2LCAyODU2LCAyODk2LCAyOTM2LCAyOTc2LCAzMDE2LCAzMDU2LCAzMDk2LCAzMTM2LCAzMTc2LCAzMjE2LCAzMjU2LCAzMjk2LCAzMzM2LCAzMzc2LCAzNDE2LAorMzQ1NiwgMzQ5NiwgMzUzNiwgMzU3NiwgMzYxNiwgMzY1NiwgMzY5NiwgMzczNiwgMzc3NiwgMzgxNiwgMzg1NiwgMzg5NiwgMzkzNiwgMzk3NiwgNDAxNiwgNDA1NiwKKzQwOTYsIDQxMzYsIDQxNzYsIDQyMTYsIDQyNTYsIDQyOTYsIDQzMzYsIDQzNzYsIDQ0MTYsIDQ0NTYsIDQ0OTYsIDQ1MzYsIDQ1NzYsIDQ2MTYsIDQ2NTYsIDQ2OTYsCis0NzM2LCA0Nzc2LCA0ODE2LCA0ODU2LCA0ODk2LCA0OTM2LCA0OTc2LCA1MDE2LCA1MDU2LCA1MDk2LCA1MTM2LCA1MTc2LCA1MjE2LCA1MjU2LCA1Mjk2LCA1MzM2LAorNTM3NiwgNTQxNiwgNTQ1NiwgNTQ5NiwgNTUzNiwgNTU3NiwgNTYxNiwgNTY1NiwgNTY5NiwgNTczNiwgNTc3NiwgNTgxNiwgNTg1NiwgNTg5NiwgNTkzNiwgNTk3NiwKKzYwMTYsIDYwNTYsIDYwOTYsIDYxMzYsIDYxNzYsIDYyMTYsIDYyNTYsIDYyOTYsIDYzMzYsIDYzNzYsIDY0MTYsIDY0NTYsIDY0OTYsIDY1MzYsIDY1NzYsIDY2MTYsCis2NjU2LCA2Njk2LCA2NzM2LCA2Nzc2LCA2ODE2LCA2ODU2LCA2ODk2LCA2OTM2LCA2OTc2LCA3MDE2LCA3MDU2LCA3MDk2LCA3MTM2LCA3MTc2LCA3MjE2LCA3MjU2LAorNzI5NiwgNzMzNiwgNzM3NiwgNzQxNiwgNzQ1NiwgNzQ5NiwgNzUzNiwgNzU3NiwgNzYxNiwgNzY1NiwgNzY5NiwgNzczNiwgNzc3NiwgNzgxNiwgNzg1NiwgNzg5NiwKKzc5MzYsIDc5NzYsIDgwMTYsIDgwNTYsIDgwOTYsIDgxMzYsIDgxNzYsIDgyMTYsIDgyNTYsIDgyOTYsIDgzMzYsIDgzNzYsIDg0MTYsIDg0NTYsIDg0OTYsIDg1MzYsCis4NTc2LCA4NjE2LCA4NjU2LCA4Njk2LCA4NzM2LCA4Nzc2LCA4ODE2LCA4ODU2LCA4ODk2LCA4OTM2LCA4OTc2LCA5MDE2LCA5MDU2LCA5MDk2LCA5MTM2LCA5MTc2LAorOTIxNiwgOTI1NiwgOTI5NiwgOTMzNiwgOTM3NiwgOTQxNiwgOTQ1NiwgOTQ5NiwgOTUzNiwgOTU3NiwgOTYxNiwgOTY1NiwgOTY5NiwgOTczNiwgOTc3NiwgOTgxNiwKKzk4NTYsIDk4OTYsIDk5MzYsIDk5NzYsIDEwMDE2LCAxMDA1NiwgMTAwOTYsIDEwMTM2LCAxMDE3NiwgMTAyMTYsIDEwMjU2LCAxMDI5NiwgMTAzMzYsIDEwMzc2LCAxMDQxNiwgMTA0NTYsCisxMDQ5NiwgMTA1MzYsIDEwNTc2LCAxMDYxNiwgMTA2NTYsIDEwNjk2LCAxMDczNiwgMTA3NzYsIDEwODE2LCAxMDg1NiwgMTA4OTYsIDEwOTM2LCAxMDk3NiwgMTEwMTYsIDExMDU2LCAxMTA5NiwKKzExMTM2LCAxMTE3NiwgMTEyMTYsIDExMjU2LCAxMTI5NiwgMTEzMzYsIDExMzc2LCAxMTQxNiwgMTE0NTYsIDExNDk2LCAxMTUzNiwgMTE1NzYsIDExNjE2LCAxMTY1NiwgMTE2OTYsIDExNzM2LAorMTE3NzYsIDExODE2LCAxMTg1NiwgMTE4OTYsIDExOTM2LCAxMTk3NiwgMTIwMTYsIDEyMDU2LCAxMjA5NiwgMTIxMzYsIDEyMTc2LCAxMjIxNiwgMTIyNTYsIDEyMjk2LCAxMjMzNiwgMTIzNzYsCisxMjQxNiwgMTI0NTYsIDEyNDk2LCAxMjUzNiwgMTI1NzYsIDEyNjE2LCAxMjY1NiwgMTI2OTYsIDEyNzM2LCAxMjc3NiwgMTI4MTYsIDEyODU2LCAxMjg5NiwgMTI5MzYsIDEyOTc2LCAxMzAxNiwKKzEzMDU2LCAxMzA5NiwgMTMxMzYsIDEzMTc2LCAxMzIxNiwgMTMyNTYsIDEzMjk2LCAxMzMzNiwgMTMzNzYsIDEzNDE2LCAxMzQ1NiwgMTM0OTYsIDEzNTM2LCAxMzU3NiwgMTM2MTYsIDEzNjU2LAorMTM2OTYsIDEzNzM2LCAxMzc3NiwgMTM4MTYsIDEzODU2LCAxMzg5NiwgMTM5MzYsIDEzOTc2LCAxNDAxNiwgMTQwNTYsIDE0MDk2LCAxNDEzNiwgMTQxNzYsIDE0MjE2LCAxNDI1NiwgMTQyOTYsCisxNDMzNiwgMTQzNzYsIDE0NDE2LCAxNDQ1NiwgMTQ0OTYsIDE0NTM2LCAxNDU3NiwgMTQ2MTYsIDE0NjU2LCAxNDY5NiwgMTQ3MzYsIDE0Nzc2LCAxNDgxNiwgMTQ4NTYsIDE0ODk2LCAxNDkzNiwKKzE0OTc2LCAxNTAxNiwgMTUwNTYsIDE1MDk2LCAxNTEzNiwgMTUxNzYsIDE1MjE2LCAxNTI1NiwgMTUyOTYsIDE1MzM2LCAxNTM3NiwgMTU0MTYsIDE1NDU2LCAxNTQ5NiwgMTU1MzYsIDE1NTc2LAorMTU2MTYsIDE1NjU2LCAxNTY5NiwgMTU3MzYsIDE1Nzc2LCAxNTgxNiwgMTU4NTYsIDE1ODk2LCAxNTkzNiwgMTU5NzYsIDE2MDE2LCAxNjA1NiwgMTYwOTYsIDE2MTM2LCAxNjE3NiwgMTYyMTYsCisxNjI1NiwgMTYyOTYsIDE2MzM2LCAxNjM3NiwgMTY0MTYsIDE2NDU2LCAxNjQ5NiwgMTY1MzYsIDE2NTc2LCAxNjYxNiwgMTY2NTYsIDE2Njk2LCAxNjczNiwgMTY3NzYsIDE2ODE2LCAxNjg1NiwKKzE2ODk2LCAxNjkzNiwgMTY5NzYsIDE3MDE2LCAxNzA1NiwgMTcwOTYsIDE3MTM2LCAxNzE3NiwgMTcyMTYsIDE3MjU2LCAxNzI5NiwgMTczMzYsIDE3Mzc2LCAxNzQxNiwgMTc0NTYsIDE3NDk2LAorMTc1MzYsIDE3NTc2LCAxNzYxNiwgMTc2NTYsIDE3Njk2LCAxNzczNiwgMTc3NzYsIDE3ODE2LCAxNzg1NiwgMTc4OTYsIDE3OTM2LCAxNzk3NiwgMTgwMTYsIDE4MDU2LCAxODA5NiwgMTgxMzYsCisxODE3NiwgMTgyMTYsIDE4MjU2LCAxODI5NiwgMTgzMzYsIDE4Mzc2LCAxODQxNiwgMTg0NTYsIDE4NDk2LCAxODUzNiwgMTg1NzYsIDE4NjE2LCAxODY1NiwgMTg2OTYsIDE4NzM2LCAxODc3NiwKKzE4ODE2LCAxODg1NiwgMTg4OTYsIDE4OTM2LCAxODk3NiwgMTkwMTYsIDE5MDU2LCAxOTA5NiwgMTkxMzYsIDE5MTc2LCAxOTIxNiwgMTkyNTYsIDE5Mjk2LCAxOTMzNiwgMTkzNzYsIDE5NDE2LAorMTk0NTYsIDE5NDk2LCAxOTUzNiwgMTk1NzYsIDE5NjE2LCAxOTY1NiwgMTk2OTYsIDE5NzM2LCAxOTc3NiwgMTk4MTYsIDE5ODU2LCAxOTg5NiwgMTk5MzYsIDE5OTc2LCAyMDAxNiwgMjAwNTYsCisyMDA5NiwgMjAxMzYsIDIwMTc2LCAyMDIxNiwgMjAyNTYsIDIwMjk2LCAyMDMzNiwgMjAzNzYsIDIwNDE2LCAyMDQ1NiwgMjA0OTYsIDIwNTM2LCAyMDU3NiwgMjA2MTYsIDIwNjU2LCAyMDY5NiwKKzIwNzM2LCAyMDc3NiwgMjA4MTYsIDIwODU2LCAyMDg5NiwgMjA5MzYsIDIwOTc2LCAyMTAxNiwgMjEwNTYsIDIxMDk2LCAyMTEzNiwgMjExNzYsIDIxMjE2LCAyMTI1NiwgMjEyOTYsIDIxMzM2LAorMjEzNzYsIDIxNDE2LCAyMTQ1NiwgMjE0OTYsIDIxNTM2LCAyMTU3NiwgMjE2MTYsIDIxNjU2LCAyMTY5NiwgMjE3MzYsIDIxNzc2LCAyMTgxNiwgMjE4NTYsIDIxODk2LCAyMTkzNiwgMjE5NzYsCisyMjAxNiwgMjIwNTYsIDIyMDk2LCAyMjEzNiwgMjIxNzYsIDIyMjE2LCAyMjI1NiwgMjIyOTYsIDIyMzM2LCAyMjM3NiwgMjI0MTYsIDIyNDU2LCAyMjQ5NiwgMjI1MzYsIDIyNTc2LCAyMjYxNiwKKzIyNjU2LCAyMjY5NiwgMjI3MzYsIDIyNzc2LCAyMjgxNiwgMjI4NTYsIDIyODk2LCAyMjkzNiwgMjI5NzYsIDIzMDE2LCAyMzA1NiwgMjMwOTYsIDIzMTM2LCAyMzE3NiwgMjMyMTYsIDIzMjU2LAorMjMyOTYsIDIzMzM2LCAyMzM3NiwgMjM0MTYsIDIzNDU2LCAyMzQ5NiwgMjM1MzYsIDIzNTc2LCAyMzYxNiwgMjM2NTYsIDIzNjk2LCAyMzczNiwgMjM3NzYsIDIzODE2LCAyMzg1NiwgMjM4OTYsCisyMzkzNiwgMjM5NzYsIDI0MDE2LCAyNDA1NiwgMjQwOTYsIDI0MTM2LCAyNDE3NiwgMjQyMTYsIDI0MjU2LCAyNDI5NiwgMjQzMzYsIDI0Mzc2LCAyNDQxNiwgMjQ0NTYsIDI0NDk2LCAyNDUzNiwKKzI0NTc2LCAyNDYxNiwgMjQ2NTYsIDI0Njk2LCAyNDczNiwgMjQ3NzYsIDI0ODE2LCAyNDg1NiwgMjQ4OTYsIDI0OTM2LCAyNDk3NiwgMjUwMTYsIDI1MDU2LCAyNTA5NiwgMjUxMzYsIDI1MTc2LAorMjUyMTYsIDI1MjU2LCAyNTI5NiwgMjUzMzYsIDI1Mzc2LCAyNTQxNiwgMjU0NTYsIDI1NDk2LCAyNTUzNiwgMjU1NzYsIDI1NjE2LCAyNTY1NiwgMjU2OTYsIDI1NzM2LCAyNTc3NiwgMjU4MTYsCisyNTg1NiwgMjU4OTYsIDI1OTM2LCAyNTk3NiwgMjYwMTYsIDI2MDU2LCAyNjA5NiwgMjYxMzYsIDI2MTc2LCAyNjIxNiwgMjYyNTYsIDI2Mjk2LCAyNjMzNiwgMjYzNzYsIDI2NDE2LCAyNjQ1NiwKKzI2NDk2LCAyNjUzNiwgMjY1NzYsIDI2NjE2LCAyNjY1NiwgMjY2OTYsIDI2NzM2LCAyNjc3NiwgMjY4MTYsIDI2ODU2LCAyNjg5NiwgMjY5MzYsIDI2OTc2LCAyNzAxNiwgMjcwNTYsIDI3MDk2LAorMjcxMzYsIDI3MTc2LCAyNzIxNiwgMjcyNTYsIDI3Mjk2LCAyNzMzNiwgMjczNzYsIDI3NDE2LCAyNzQ1NiwgMjc0OTYsIDI3NTM2LCAyNzU3NiwgMjc2MTYsIDI3NjU2LCAyNzY5NiwgMjc3MzYsCisyNzc3NiwgMjc4MTYsIDI3ODU2LCAyNzg5NiwgMjc5MzYsIDI3OTc2LCAyODAxNiwgMjgwNTYsIDI4MDk2LCAyODEzNiwgMjgxNzYsIDI4MjE2LCAyODI1NiwgMjgyOTYsIDI4MzM2LCAyODM3NiwKKzI4NDE2LCAyODQ1NiwgMjg0OTYsIDI4NTM2LCAyODU3NiwgMjg2MTYsIDI4NjU2LCAyODY5NiwgMjg3MzYsIDI4Nzc2LCAyODgxNiwgMjg4NTYsIDI4ODk2LCAyODkzNiwgMjg5NzYsIDI5MDE2LAorMjkwNTYsIDI5MDk2LCAyOTEzNiwgMjkxNzYsIDI5MjE2LCAyOTI1NiwgMjkyOTYsIDI5MzM2LCAyOTM3NiwgMjk0MTYsIDI5NDU2LCAyOTQ5NiwgMjk1MzYsIDI5NTc2LCAyOTYxNiwgMjk2NTYsCisyOTY5NiwgMjk3MzYsIDI5Nzc2LCAyOTgxNiwgMjk4NTYsIDI5ODk2LCAyOTkzNiwgMjk5NzYsIDMwMDE2LCAzMDA1NiwgMzAwOTYsIDMwMTM2LCAzMDE3NiwgMzAyMTYsIDMwMjU2LCAzMDI5NiwKKzMwMzM2LCAzMDM3NiwgMzA0MTYsIDMwNDU2LCAzMDQ5NiwgMzA1MzYsIDMwNTc2LCAzMDYxNiwgMzA2NTYsIDMwNjk2LCAzMDczNiwgMzA3NzYsIDMwODE2LCAzMDg1NiwgMzA4OTYsIDMwOTM2LAorMzA5NzYsIDMxMDE2LCAzMTA1NiwgMzEwOTYsIDMxMTM2LCAzMTE3NiwgMzEyMTYsIDMxMjU2LCAzMTI5NiwgMzEzMzYsIDMxMzc2LCAzMTQxNiwgMzE0NTYsIDMxNDk2LCAzMTUzNiwgMzE1NzYsCiszMTYxNiwgMzE2NTYsIDMxNjk2LCAzMTczNiwgMzE3NzYsIDMxODE2LCAzMTg1NiwgMzE4OTYsIDMxOTM2LCAzMTk3NiwgMzIwMTYsIDMyMDU2LCAzMjA5NiwgMzIxMzYsIDMyMTc2LCAzMjIxNiwKKzMyMjU2LCAzMjI5NiwgMzIzMzYsIDMyMzc2LCAzMjQxNiwgMzI0NTYsIDMyNDk2LCAzMjUzNiwgMzI1NzYsIDMyNjE2LCAzMjY1NiwgMzI2OTYsIDMyNzM2LCAzMjc3NiwgMzI4MTYsIDMyODU2LAorMzI4OTYsIDMyOTM2LCAzMjk3NiwgMzMwMTYsIDMzMDU2LCAzMzA5NiwgMzMxMzYsIDMzMTc2LCAzMzIxNiwgMzMyNTYsIDMzMjk2LCAzMzMzNiwgMzMzNzYsIDMzNDE2LCAzMzQ1NiwgMzM0OTYsCiszMzUzNiwgMzM1NzYsIDMzNjE2LCAzMzY1NiwgMzM2OTYsIDMzNzM2LCAzMzc3NiwgMzM4MTYsIDMzODU2LCAzMzg5NiwgMzM5MzYsIDMzOTc2LCAzNDAxNiwgMzQwNTYsIDM0MDk2LCAzNDEzNiwKKzM0MTc2LCAzNDIxNiwgMzQyNTYsIDM0Mjk2LCAzNDMzNiwgMzQzNzYsIDM0NDE2LCAzNDQ1NiwgMzQ0OTYsIDM0NTM2LCAzNDU3NiwgMzQ2MTYsIDM0NjU2LCAzNDY5NiwgMzQ3MzYsIDM0Nzc2LAorMzQ4MTYsIDM0ODU2LCAzNDg5NiwgMzQ5MzYsIDM0OTc2LCAzNTAxNiwgMzUwNTYsIDM1MDk2LCAzNTEzNiwgMzUxNzYsIDM1MjE2LCAzNTI1NiwgMzUyOTYsIDM1MzM2LCAzNTM3NiwgMzU0MTYsCiszNTQ1NiwgMzU0OTYsIDM1NTM2LCAzNTU3NiwgMzU2MTYsIDM1NjU2LCAzNTY5NiwgMzU3MzYsIDM1Nzc2LCAzNTgxNiwgMzU4NTYsIDM1ODk2LCAzNTkzNiwgMzU5NzYsIDM2MDE2LCAzNjA1NiwKKzM2MDk2LCAzNjEzNiwgMzYxNzYsIDM2MjE2LCAzNjI1NiwgMzYyOTYsIDM2MzM2LCAzNjM3NiwgMzY0MTYsIDM2NDU2LCAzNjQ5NiwgMzY1MzYsIDM2NTc2LCAzNjYxNiwgMzY2NTYsIDM2Njk2LAorMzY3MzYsIDM2Nzc2LCAzNjgxNiwgMzY4NTYsIDM2ODk2LCAzNjkzNiwgMzY5NzYsIDM3MDE2LCAzNzA1NiwgMzcwOTYsIDM3MTM2LCAzNzE3NiwgMzcyMTYsIDM3MjU2LCAzNzI5NiwgMzczMzYsCiszNzM3NiwgMzc0MTYsIDM3NDU2LCAzNzQ5NiwgMzc1MzYsIDM3NTc2LCAzNzYxNiwgMzc2NTYsIDM3Njk2LCAzNzczNiwgMzc3NzYsIDM3ODE2LCAzNzg1NiwgMzc4OTYsIDM3OTM2LCAzNzk3NiwKKzM4MDE2LCAzODA1NiwgMzgwOTYsIDM4MTM2LCAzODE3NiwgMzgyMTYsIDM4MjU2LCAzODI5NiwgMzgzMzYsIDM4Mzc2LCAzODQxNiwgMzg0NTYsIDM4NDk2LCAzODUzNiwgMzg1NzYsIDM4NjE2LAorMzg2NTYsIDM4Njk2LCAzODczNiwgMzg3NzYsIDM4ODE2LCAzODg1NiwgMzg4OTYsIDM4OTM2LCAzODk3NiwgMzkwMTYsIDM5MDU2LCAzOTA5NiwgMzkxMzYsIDM5MTc2LCAzOTIxNiwgMzkyNTYsCiszOTI5NiwgMzkzMzYsIDM5Mzc2LCAzOTQxNiwgMzk0NTYsIDM5NDk2LCAzOTUzNiwgMzk1NzYsIDM5NjE2LCAzOTY1NiwgMzk2OTYsIDM5NzM2LCAzOTc3NiwgMzk4MTYsIDM5ODU2LCAzOTg5NiwKKzM5OTM2LCAzOTk3NiwgNDAwMTYsIDQwMDU2LCA0MDA5NiwgNDAxMzYsIDQwMTc2LCA0MDIxNiwgNDAyNTYsIDQwMjk2LCA0MDMzNiwgNDAzNzYsIDQwNDE2LCA0MDQ1NiwgNDA0OTYsIDQwNTM2LAorNDA1NzYsIDQwNjE2LCA0MDY1NiwgNDA2OTYsIDQwNzM2LCA0MDc3NiwgNDA4MTYsIDQwODU2LCA0MDg5NiwgNDA5MzYsIDQwOTc2LCA0MTAxNiwgNDEwNTYsIDQxMDk2LCA0MTEzNiwgNDExNzYsCis0MTIxNiwgNDEyNTYsIDQxMjk2LCA0MTMzNiwgNDEzNzYsIDQxNDE2LCA0MTQ1NiwgNDE0OTYsIDQxNTM2LCA0MTU3NiwgNDE2MTYsIDQxNjU2LCA0MTY5NiwgNDE3MzYsIDQxNzc2LCA0MTgxNiwKKzQxODU2LCA0MTg5NiwgNDE5MzYsIDQxOTc2LCA0MjAxNiwgNDIwNTYsIDQyMDk2LCA0MjEzNiwgNDIxNzYsIDQyMjE2LCA0MjI1NiwgNDIyOTYsIDQyMzM2LCA0MjM3NiwgNDI0MTYsIDQyNDU2LAorNDI0OTYsIDQyNTM2LCA0MjU3NiwgNDI2MTYsIDQyNjU2LCA0MjY5NiwgNDI3MzYsIDQyNzc2LCA0MjgxNiwgNDI4NTYsIDQyODk2LCA0MjkzNiwgNDI5NzYsIDQzMDE2LCA0MzA1NiwgNDMwOTYsCis0MzEzNiwgNDMxNzYsIDQzMjE2LCA0MzI1NiwgNDMyOTYsIDQzMzM2LCA0MzM3NiwgNDM0MTYsIDQzNDU2LCA0MzQ5NiwgNDM1MzYsIDQzNTc2LCA0MzYxNiwgNDM2NTYsIDQzNjk2LCA0MzczNiwKKzQzNzc2LCA0MzgxNiwgNDM4NTYsIDQzODk2LCA0MzkzNiwgNDM5NzYsIDQ0MDE2LCA0NDA1NiwgNDQwOTYsIDQ0MTM2LCA0NDE3NiwgNDQyMTYsIDQ0MjU2LCA0NDI5NiwgNDQzMzYsIDQ0Mzc2LAorNDQ0MTYsIDQ0NDU2LCA0NDQ5NiwgNDQ1MzYsIDQ0NTc2LCA0NDYxNiwgNDQ2NTYsIDQ0Njk2LCA0NDczNiwgNDQ3NzYsIDQ0ODE2LCA0NDg1NiwgNDQ4OTYsIDQ0OTM2LCA0NDk3NiwgNDUwMTYsCis0NTA1NiwgNDUwOTYsIDQ1MTM2LCA0NTE3NiwgNDUyMTYsIDQ1MjU2LCA0NTI5NiwgNDUzMzYsIDQ1Mzc2LCA0NTQxNiwgNDU0NTYsIDQ1NDk2LCA0NTUzNiwgNDU1NzYsIDQ1NjE2LCA0NTY1NiwKKzQ1Njk2LCA0NTczNiwgNDU3NzYsIDQ1ODE2LCA0NTg1NiwgNDU4OTYsIDQ1OTM2LCA0NTk3NiwgNDYwMTYsIDQ2MDU2LCA0NjA5NiwgNDYxMzYsIDQ2MTc2LCA0NjIxNiwgNDYyNTYsIDQ2Mjk2LAorNDYzMzYsIDQ2Mzc2LCA0NjQxNiwgNDY0NTYsIDQ2NDk2LCA0NjUzNiwgNDY1NzYsIDQ2NjE2LCA0NjY1NiwgNDY2OTYsIDQ2NzM2LCA0Njc3NiwgNDY4MTYsIDQ2ODU2LCA0Njg5NiwgNDY5MzYsCis0Njk3NiwgNDcwMTYsIDQ3MDU2LCA0NzA5NiwgNDcxMzYsIDQ3MTc2LCA0NzIxNiwgNDcyNTYsIDQ3Mjk2LCA0NzMzNiwgNDczNzYsIDQ3NDE2LCA0NzQ1NiwgNDc0OTYsIDQ3NTM2LCA0NzU3NiwKKzQ3NjE2LCA0NzY1NiwgNDc2OTYsIDQ3NzM2LCA0Nzc3NiwgNDc4MTYsIDQ3ODU2LCA0Nzg5NiwgNDc5MzYsIDQ3OTc2LCA0ODAxNiwgNDgwNTYsIDQ4MDk2LCA0ODEzNiwgNDgxNzYsIDQ4MjE2LAorNDgyNTYsIDQ4Mjk2LCA0ODMzNiwgNDgzNzYsIDQ4NDE2LCA0ODQ1NiwgNDg0OTYsIDQ4NTM2LCA0ODU3NiwgNDg2MTYsIDQ4NjU2LCA0ODY5NiwgNDg3MzYsIDQ4Nzc2LCA0ODgxNiwgNDg4NTYsCis0ODg5NiwgNDg5MzYsIDQ4OTc2LCA0OTAxNiwgNDkwNTYsIDQ5MDk2LCA0OTEzNiwgNDkxNzYsIDQ5MjE2LCA0OTI1NiwgNDkyOTYsIDQ5MzM2LCA0OTM3NiwgNDk0MTYsIDQ5NDU2LCA0OTQ5NiwKKzQ5NTM2LCA0OTU3NiwgNDk2MTYsIDQ5NjU2LCA0OTY5NiwgNDk3MzYsIDQ5Nzc2LCA0OTgxNiwgNDk4NTYsIDQ5ODk2LCA0OTkzNiwgNDk5NzYsIDUwMDE2LCA1MDA1NiwgNTAwOTYsIDUwMTM2LAorNTAxNzYsIDUwMjE2LCA1MDI1NiwgNTAyOTYsIDUwMzM2LCA1MDM3NiwgNTA0MTYsIDUwNDU2LCA1MDQ5NiwgNTA1MzYsIDUwNTc2LCA1MDYxNiwgNTA2NTYsIDUwNjk2LCA1MDczNiwgNTA3NzYsCis1MDgxNiwgNTA4NTYsIDUwODk2LCA1MDkzNiwgNTA5NzYsIDUxMDE2LCA1MTA1NiwgNTEwOTYsIDUxMTM2LCA1MTE3NiwgNTEyMTYsIDUxMjU2LCA1MTI5NiwgNTEzMzYsIDUxMzc2LCA1MTQxNiwKKzUxNDU2LCA1MTQ5NiwgNTE1MzYsIDUxNTc2LCA1MTYxNiwgNTE2NTYsIDUxNjk2LCA1MTczNiwgNTE3NzYsIDUxODE2LCA1MTg1NiwgNTE4OTYsIDUxOTM2LCA1MTk3NiwgNTIwMTYsIDUyMDU2LAorNTIwOTYsIDUyMTM2LCA1MjE3NiwgNTIyMTYsIDUyMjU2LCA1MjI5NiwgNTIzMzYsIDUyMzc2LCA1MjQxNiwgNTI0NTYsIDUyNDk2LCA1MjUzNiwgNTI1NzYsIDUyNjE2LCA1MjY1NiwgNTI2OTYsCis1MjczNiwgNTI3NzYsIDUyODE2LCA1Mjg1NiwgNTI4OTYsIDUyOTM2LCA1Mjk3NiwgNTMwMTYsIDUzMDU2LCA1MzA5NiwgNTMxMzYsIDUzMTc2LCA1MzIxNiwgNTMyNTYsIDUzMjk2LCA1MzMzNiwKKzUzMzc2LCA1MzQxNiwgNTM0NTYsIDUzNDk2LCA1MzUzNiwgNTM1NzYsIDUzNjE2LCA1MzY1NiwgNTM2OTYsIDUzNzM2LCA1Mzc3NiwgNTM4MTYsIDUzODU2LCA1Mzg5NiwgNTM5MzYsIDUzOTc2LAorNTQwMTYsIDU0MDU2LCA1NDA5NiwgNTQxMzYsIDU0MTc2LCA1NDIxNiwgNTQyNTYsIDU0Mjk2LCA1NDMzNiwgNTQzNzYsIDU0NDE2LCA1NDQ1NiwgNTQ0OTYsIDU0NTM2LCA1NDU3NiwgNTQ2MTYsCis1NDY1NiwgNTQ2OTYsIDU0NzM2LCA1NDc3NiwgNTQ4MTYsIDU0ODU2LCA1NDg5NiwgNTQ5MzYsIDU0OTc2LCA1NTAxNiwgNTUwNTYsIDU1MDk2LCA1NTEzNiwgNTUxNzYsIDU1MjE2LCA1NTI1NiwKKzU3MzQ0LCA1NzM4NCwgNTc0MjQsIDU3NDY0LCA1NzUwNCwgNTc1NDQsIDU3NTg0LCA1NzYyNCwgNTc2NjQsIDU3NzA0LCA1Nzc0NCwgNTc3ODQsIDU3ODI0LCA1Nzg2NCwgNTc5MDQsIDU3OTQ0LAorNTc5ODQsIDU4MDI0LCA1ODA2NCwgNTgxMDQsIDU4MTQ0LCA1ODE4NCwgNTgyMjQsIDU4MjY0LCA1ODMwNCwgNTgzNDQsIDU4Mzg0LCA1ODQyNCwgNTg0NjQsIDU4NTA0LCA1ODU0NCwgNTg1ODQsCis1ODYyNCwgNTg2NjQsIDU4NzA0LCA1ODc0NCwgNTg3ODQsIDU4ODI0LCA1ODg2NCwgNTg5MDQsIDU4OTQ0LCA1ODk4NCwgNTkwMjQsIDU5MDY0LCA1OTEwNCwgNTkxNDQsIDU5MTg0LCA1OTIyNCwKKzU5MjY0LCA1OTMwNCwgNTkzNDQsIDU5Mzg0LCA1OTQyNCwgNTk0NjQsIDU5NTA0LCA1OTU0NCwgNTk1ODQsIDU5NjI0LCA1OTY2NCwgNTk3MDQsIDU5NzQ0LCA1OTc4NCwgNTk4MjQsIDU5ODY0LAorNTk5MDQsIDU5OTQ0LCA1OTk4NCwgNjAwMjQsIDYwMDY0LCA2MDEwNCwgNjAxNDQsIDYwMTg0LCA2MDIyNCwgNjAyNjQsIDYwMzA0LCA2MDM0NCwgNjAzODQsIDYwNDI0LCA2MDQ2NCwgNjA1MDQsCis2MDU0NCwgNjA1ODQsIDYwNjI0LCA2MDY2NCwgNjA3MDQsIDYwNzQ0LCA2MDc4NCwgNjA4MjQsIDYwODY0LCA2MDkwNCwgNjA5NDQsIDYwOTg0LCA2MTAyNCwgNjEwNjQsIDYxMTA0LCA2MTE0NCwKKzYxMTg0LCA2MTIyNCwgNjEyNjQsIDYxMzA0LCA2MTM0NCwgNjEzODQsIDYxNDI0LCA2MTQ2NCwgNjE1MDQsIDYxNTQ0LCA2MTU4NCwgNjE2MjQsIDYxNjY0LCA2MTcwNCwgNjE3NDQsIDYxNzg0LAorNjE4MjQsIDYxODY0LCA2MTkwNCwgNjE5NDQsIDYxOTg0LCA2MjAyNCwgNjIwNjQsIDYyMTA0LCA2MjE0NCwgNjIxODQsIDYyMjI0LCA2MjI2NCwgNjIzMDQsIDYyMzQ0LCA2MjM4NCwgNjI0MjQsCis2MjQ2NCwgNjI1MDQsIDYyNTQ0LCA2MjU4NCwgNjI2MjQsIDYyNjY0LCA2MjcwNCwgNjI3NDQsIDYyNzg0LCA2MjgyNCwgNjI4NjQsIDYyOTA0LCA2Mjk0NCwgNjI5ODQsIDYzMDI0LCA2MzA2NCwKKzYzMTA0LCA2MzE0NCwgNjMxODQsIDYzMjI0LCA2MzI2NCwgNjMzMDQsIDYzMzQ0LCA2MzM4NCwgNjM0MjQsIDYzNDY0LCA2MzUwNCwgNjM1NDQsIDYzNTg0LCA2MzYyNCwgNjM2NjQsIDYzNzA0LAorNjM3NDQsIDYzNzg0LCA2MzgyNCwgNjM4NjQsIDYzOTA0LCA2Mzk0NCwgNjM5ODQsIDY0MDI0LCA2NDA2NCwgNjQxMDQsIDY0MTQ0LCA2NDE4NCwgNjQyMjQsIDY0MjY0LCA2NDMwNCwgNjQzNDQsCis2NDM4NCwgNjQ0MjQsIDY0NDY0LCA2NDUwNCwgNjQ1NDQsIDY0NTg0LCA2NDYyNCwgNjQ2NjQsIDY0NzA0LCA2NDc0NCwgNjQ3ODQsIDY0ODI0LCA2NDg2NCwgNjQ5MDQsIDY0OTQ0LCA2NDk4NCwKKzY1MDI0LCA2NTA2NCwgNjUxMDQsIDY1MTQ0LCA2NTE4NCwgNjUyMjQsIDY1MjY0LCA2NTMwNCwgNjUzNDQsIDY1Mzg0LCA2NTQyNCwgNjU0NjQsIDY1NTA0CisgICAgICAgICAgICB9KTsKKworICAgICAgICB0ZXN0Qnl0ZXMgPSB0aGVzZUJ5dGVzKG5ldyBpbnRbXXsKKzAsIDAsIDEsIDAsIDIsIDAsIDMsIDAsIDQsIDAsIDUsIDAsIDYsIDAsIDcsIDAsCis4LCAwLCA5LCAwLCAxMCwgMCwgMTEsIDAsIDEyLCAwLCAxMywgMCwgMTQsIDAsIDE1LCAwLAorMTYsIDAsIDE3LCAwLCAxOCwgMCwgMTksIDAsIDIwLCAwLCAyMSwgMCwgMjIsIDAsIDIzLCAwLAorMjQsIDAsIDI1LCAwLCAyNiwgMCwgMjcsIDAsIDI4LCAwLCAyOSwgMCwgMzAsIDAsIDMxLCAwLAorMzIsIDAsIDMzLCAwLCAzNCwgMCwgMzUsIDAsIDM2LCAwLCAzNywgMCwgMzgsIDAsIDM5LCAwLAorNDAsIDAsIDQxLCAwLCA0MiwgMCwgNDMsIDAsIDQ0LCAwLCA0NSwgMCwgNDYsIDAsIDQ3LCAwLAorNDgsIDAsIDQ5LCAwLCA1MCwgMCwgNTEsIDAsIDUyLCAwLCA1MywgMCwgNTQsIDAsIDU1LCAwLAorNTYsIDAsIDU3LCAwLCA1OCwgMCwgNTksIDAsIDYwLCAwLCA2MSwgMCwgNjIsIDAsIDYzLCAwLAorNjQsIDAsIDY1LCAwLCA2NiwgMCwgNjcsIDAsIDY4LCAwLCA2OSwgMCwgNzAsIDAsIDcxLCAwLAorNzIsIDAsIDczLCAwLCA3NCwgMCwgNzUsIDAsIDc2LCAwLCA3NywgMCwgNzgsIDAsIDc5LCAwLAorODAsIDAsIDgxLCAwLCA4MiwgMCwgODMsIDAsIDg0LCAwLCA4NSwgMCwgODYsIDAsIDg3LCAwLAorODgsIDAsIDg5LCAwLCA5MCwgMCwgOTEsIDAsIDkyLCAwLCA5MywgMCwgOTQsIDAsIDk1LCAwLAorOTYsIDAsIDk3LCAwLCA5OCwgMCwgOTksIDAsIDEwMCwgMCwgMTAxLCAwLCAxMDIsIDAsIDEwMywgMCwKKzEwNCwgMCwgMTA1LCAwLCAxMDYsIDAsIDEwNywgMCwgMTA4LCAwLCAxMDksIDAsIDExMCwgMCwgMTExLCAwLAorMTEyLCAwLCAxMTMsIDAsIDExNCwgMCwgMTE1LCAwLCAxMTYsIDAsIDExNywgMCwgMTE4LCAwLCAxMTksIDAsCisxMjAsIDAsIDEyMSwgMCwgMTIyLCAwLCAxMjMsIDAsIDEyNCwgMCwgMTI1LCAwLCAxMjYsIDAsIDEyNywgMCwKKzEyOCwgMCwgMTI5LCAwLCAxMzAsIDAsIDEzMSwgMCwgMTMyLCAwLCAxMzMsIDAsIDEzNCwgMCwgMTM1LCAwLAorMTM2LCAwLCAxMzcsIDAsIDEzOCwgMCwgMTM5LCAwLCAxNDAsIDAsIDE0MSwgMCwgMTQyLCAwLCAxNDMsIDAsCisxNDQsIDAsIDE0NSwgMCwgMTQ2LCAwLCAxNDcsIDAsIDE0OCwgMCwgMTQ5LCAwLCAxNTAsIDAsIDE1MSwgMCwKKzE1MiwgMCwgMTUzLCAwLCAxNTQsIDAsIDE1NSwgMCwgMTU2LCAwLCAxNTcsIDAsIDE1OCwgMCwgMTU5LCAwLAorMTYwLCAwLCAxNjEsIDAsIDE2MiwgMCwgMTYzLCAwLCAxNjQsIDAsIDE2NSwgMCwgMTY2LCAwLCAxNjcsIDAsCisxNjgsIDAsIDE2OSwgMCwgMTcwLCAwLCAxNzEsIDAsIDE3MiwgMCwgMTczLCAwLCAxNzQsIDAsIDE3NSwgMCwKKzE3NiwgMCwgMTc3LCAwLCAxNzgsIDAsIDE3OSwgMCwgMTgwLCAwLCAxODEsIDAsIDE4MiwgMCwgMTgzLCAwLAorMTg0LCAwLCAxODUsIDAsIDE4NiwgMCwgMTg3LCAwLCAxODgsIDAsIDE4OSwgMCwgMTkwLCAwLCAxOTEsIDAsCisxOTIsIDAsIDE5MywgMCwgMTk0LCAwLCAxOTUsIDAsIDE5NiwgMCwgMTk3LCAwLCAxOTgsIDAsIDE5OSwgMCwKKzIwMCwgMCwgMjAxLCAwLCAyMDIsIDAsIDIwMywgMCwgMjA0LCAwLCAyMDUsIDAsIDIwNiwgMCwgMjA3LCAwLAorMjA4LCAwLCAyMDksIDAsIDIxMCwgMCwgMjExLCAwLCAyMTIsIDAsIDIxMywgMCwgMjE0LCAwLCAyMTUsIDAsCisyMTYsIDAsIDIxNywgMCwgMjE4LCAwLCAyMTksIDAsIDIyMCwgMCwgMjIxLCAwLCAyMjIsIDAsIDIyMywgMCwKKzIyNCwgMCwgMjI1LCAwLCAyMjYsIDAsIDIyNywgMCwgMjI4LCAwLCAyMjksIDAsIDIzMCwgMCwgMjMxLCAwLAorMjMyLCAwLCAyMzMsIDAsIDIzNCwgMCwgMjM1LCAwLCAyMzYsIDAsIDIzNywgMCwgMjM4LCAwLCAyMzksIDAsCisyNDAsIDAsIDI0MSwgMCwgMjQyLCAwLCAyNDMsIDAsIDI0NCwgMCwgMjQ1LCAwLCAyNDYsIDAsIDI0NywgMCwKKzI0OCwgMCwgMjQ5LCAwLCAyNTAsIDAsIDI1MSwgMCwgMjUyLCAwLCAyNTMsIDAsIDI1NCwgMCwgMjU1LCAwLAorMCwgMSwgNDAsIDEsIDgwLCAxLCAxMjAsIDEsIDE2MCwgMSwgMjAwLCAxLCAyNDAsIDEsIDI0LCAyLAorNjQsIDIsIDEwNCwgMiwgMTQ0LCAyLCAxODQsIDIsIDIyNCwgMiwgOCwgMywgNDgsIDMsIDg4LCAzLAorMTI4LCAzLCAxNjgsIDMsIDIwOCwgMywgMjQ4LCAzLCAzMiwgNCwgNzIsIDQsIDExMiwgNCwgMTUyLCA0LAorMTkyLCA0LCAyMzIsIDQsIDE2LCA1LCA1NiwgNSwgOTYsIDUsIDEzNiwgNSwgMTc2LCA1LCAyMTYsIDUsCiswLCA2LCA0MCwgNiwgODAsIDYsIDEyMCwgNiwgMTYwLCA2LCAyMDAsIDYsIDI0MCwgNiwgMjQsIDcsCis2NCwgNywgMTA0LCA3LCAxNDQsIDcsIDE4NCwgNywgMjI0LCA3LCA4LCA4LCA0OCwgOCwgODgsIDgsCisxMjgsIDgsIDE2OCwgOCwgMjA4LCA4LCAyNDgsIDgsIDMyLCA5LCA3MiwgOSwgMTEyLCA5LCAxNTIsIDksCisxOTIsIDksIDIzMiwgOSwgMTYsIDEwLCA1NiwgMTAsIDk2LCAxMCwgMTM2LCAxMCwgMTc2LCAxMCwgMjE2LCAxMCwKKzAsIDExLCA0MCwgMTEsIDgwLCAxMSwgMTIwLCAxMSwgMTYwLCAxMSwgMjAwLCAxMSwgMjQwLCAxMSwgMjQsIDEyLAorNjQsIDEyLCAxMDQsIDEyLCAxNDQsIDEyLCAxODQsIDEyLCAyMjQsIDEyLCA4LCAxMywgNDgsIDEzLCA4OCwgMTMsCisxMjgsIDEzLCAxNjgsIDEzLCAyMDgsIDEzLCAyNDgsIDEzLCAzMiwgMTQsIDcyLCAxNCwgMTEyLCAxNCwgMTUyLCAxNCwKKzE5MiwgMTQsIDIzMiwgMTQsIDE2LCAxNSwgNTYsIDE1LCA5NiwgMTUsIDEzNiwgMTUsIDE3NiwgMTUsIDIxNiwgMTUsCiswLCAxNiwgNDAsIDE2LCA4MCwgMTYsIDEyMCwgMTYsIDE2MCwgMTYsIDIwMCwgMTYsIDI0MCwgMTYsIDI0LCAxNywKKzY0LCAxNywgMTA0LCAxNywgMTQ0LCAxNywgMTg0LCAxNywgMjI0LCAxNywgOCwgMTgsIDQ4LCAxOCwgODgsIDE4LAorMTI4LCAxOCwgMTY4LCAxOCwgMjA4LCAxOCwgMjQ4LCAxOCwgMzIsIDE5LCA3MiwgMTksIDExMiwgMTksIDE1MiwgMTksCisxOTIsIDE5LCAyMzIsIDE5LCAxNiwgMjAsIDU2LCAyMCwgOTYsIDIwLCAxMzYsIDIwLCAxNzYsIDIwLCAyMTYsIDIwLAorMCwgMjEsIDQwLCAyMSwgODAsIDIxLCAxMjAsIDIxLCAxNjAsIDIxLCAyMDAsIDIxLCAyNDAsIDIxLCAyNCwgMjIsCis2NCwgMjIsIDEwNCwgMjIsIDE0NCwgMjIsIDE4NCwgMjIsIDIyNCwgMjIsIDgsIDIzLCA0OCwgMjMsIDg4LCAyMywKKzEyOCwgMjMsIDE2OCwgMjMsIDIwOCwgMjMsIDI0OCwgMjMsIDMyLCAyNCwgNzIsIDI0LCAxMTIsIDI0LCAxNTIsIDI0LAorMTkyLCAyNCwgMjMyLCAyNCwgMTYsIDI1LCA1NiwgMjUsIDk2LCAyNSwgMTM2LCAyNSwgMTc2LCAyNSwgMjE2LCAyNSwKKzAsIDI2LCA0MCwgMjYsIDgwLCAyNiwgMTIwLCAyNiwgMTYwLCAyNiwgMjAwLCAyNiwgMjQwLCAyNiwgMjQsIDI3LAorNjQsIDI3LCAxMDQsIDI3LCAxNDQsIDI3LCAxODQsIDI3LCAyMjQsIDI3LCA4LCAyOCwgNDgsIDI4LCA4OCwgMjgsCisxMjgsIDI4LCAxNjgsIDI4LCAyMDgsIDI4LCAyNDgsIDI4LCAzMiwgMjksIDcyLCAyOSwgMTEyLCAyOSwgMTUyLCAyOSwKKzE5MiwgMjksIDIzMiwgMjksIDE2LCAzMCwgNTYsIDMwLCA5NiwgMzAsIDEzNiwgMzAsIDE3NiwgMzAsIDIxNiwgMzAsCiswLCAzMSwgNDAsIDMxLCA4MCwgMzEsIDEyMCwgMzEsIDE2MCwgMzEsIDIwMCwgMzEsIDI0MCwgMzEsIDI0LCAzMiwKKzY0LCAzMiwgMTA0LCAzMiwgMTQ0LCAzMiwgMTg0LCAzMiwgMjI0LCAzMiwgOCwgMzMsIDQ4LCAzMywgODgsIDMzLAorMTI4LCAzMywgMTY4LCAzMywgMjA4LCAzMywgMjQ4LCAzMywgMzIsIDM0LCA3MiwgMzQsIDExMiwgMzQsIDE1MiwgMzQsCisxOTIsIDM0LCAyMzIsIDM0LCAxNiwgMzUsIDU2LCAzNSwgOTYsIDM1LCAxMzYsIDM1LCAxNzYsIDM1LCAyMTYsIDM1LAorMCwgMzYsIDQwLCAzNiwgODAsIDM2LCAxMjAsIDM2LCAxNjAsIDM2LCAyMDAsIDM2LCAyNDAsIDM2LCAyNCwgMzcsCis2NCwgMzcsIDEwNCwgMzcsIDE0NCwgMzcsIDE4NCwgMzcsIDIyNCwgMzcsIDgsIDM4LCA0OCwgMzgsIDg4LCAzOCwKKzEyOCwgMzgsIDE2OCwgMzgsIDIwOCwgMzgsIDI0OCwgMzgsIDMyLCAzOSwgNzIsIDM5LCAxMTIsIDM5LCAxNTIsIDM5LAorMTkyLCAzOSwgMjMyLCAzOSwgMTYsIDQwLCA1NiwgNDAsIDk2LCA0MCwgMTM2LCA0MCwgMTc2LCA0MCwgMjE2LCA0MCwKKzAsIDQxLCA0MCwgNDEsIDgwLCA0MSwgMTIwLCA0MSwgMTYwLCA0MSwgMjAwLCA0MSwgMjQwLCA0MSwgMjQsIDQyLAorNjQsIDQyLCAxMDQsIDQyLCAxNDQsIDQyLCAxODQsIDQyLCAyMjQsIDQyLCA4LCA0MywgNDgsIDQzLCA4OCwgNDMsCisxMjgsIDQzLCAxNjgsIDQzLCAyMDgsIDQzLCAyNDgsIDQzLCAzMiwgNDQsIDcyLCA0NCwgMTEyLCA0NCwgMTUyLCA0NCwKKzE5MiwgNDQsIDIzMiwgNDQsIDE2LCA0NSwgNTYsIDQ1LCA5NiwgNDUsIDEzNiwgNDUsIDE3NiwgNDUsIDIxNiwgNDUsCiswLCA0NiwgNDAsIDQ2LCA4MCwgNDYsIDEyMCwgNDYsIDE2MCwgNDYsIDIwMCwgNDYsIDI0MCwgNDYsIDI0LCA0NywKKzY0LCA0NywgMTA0LCA0NywgMTQ0LCA0NywgMTg0LCA0NywgMjI0LCA0NywgOCwgNDgsIDQ4LCA0OCwgODgsIDQ4LAorMTI4LCA0OCwgMTY4LCA0OCwgMjA4LCA0OCwgMjQ4LCA0OCwgMzIsIDQ5LCA3MiwgNDksIDExMiwgNDksIDE1MiwgNDksCisxOTIsIDQ5LCAyMzIsIDQ5LCAxNiwgNTAsIDU2LCA1MCwgOTYsIDUwLCAxMzYsIDUwLCAxNzYsIDUwLCAyMTYsIDUwLAorMCwgNTEsIDQwLCA1MSwgODAsIDUxLCAxMjAsIDUxLCAxNjAsIDUxLCAyMDAsIDUxLCAyNDAsIDUxLCAyNCwgNTIsCis2NCwgNTIsIDEwNCwgNTIsIDE0NCwgNTIsIDE4NCwgNTIsIDIyNCwgNTIsIDgsIDUzLCA0OCwgNTMsIDg4LCA1MywKKzEyOCwgNTMsIDE2OCwgNTMsIDIwOCwgNTMsIDI0OCwgNTMsIDMyLCA1NCwgNzIsIDU0LCAxMTIsIDU0LCAxNTIsIDU0LAorMTkyLCA1NCwgMjMyLCA1NCwgMTYsIDU1LCA1NiwgNTUsIDk2LCA1NSwgMTM2LCA1NSwgMTc2LCA1NSwgMjE2LCA1NSwKKzAsIDU2LCA0MCwgNTYsIDgwLCA1NiwgMTIwLCA1NiwgMTYwLCA1NiwgMjAwLCA1NiwgMjQwLCA1NiwgMjQsIDU3LAorNjQsIDU3LCAxMDQsIDU3LCAxNDQsIDU3LCAxODQsIDU3LCAyMjQsIDU3LCA4LCA1OCwgNDgsIDU4LCA4OCwgNTgsCisxMjgsIDU4LCAxNjgsIDU4LCAyMDgsIDU4LCAyNDgsIDU4LCAzMiwgNTksIDcyLCA1OSwgMTEyLCA1OSwgMTUyLCA1OSwKKzE5MiwgNTksIDIzMiwgNTksIDE2LCA2MCwgNTYsIDYwLCA5NiwgNjAsIDEzNiwgNjAsIDE3NiwgNjAsIDIxNiwgNjAsCiswLCA2MSwgNDAsIDYxLCA4MCwgNjEsIDEyMCwgNjEsIDE2MCwgNjEsIDIwMCwgNjEsIDI0MCwgNjEsIDI0LCA2MiwKKzY0LCA2MiwgMTA0LCA2MiwgMTQ0LCA2MiwgMTg0LCA2MiwgMjI0LCA2MiwgOCwgNjMsIDQ4LCA2MywgODgsIDYzLAorMTI4LCA2MywgMTY4LCA2MywgMjA4LCA2MywgMjQ4LCA2MywgMzIsIDY0LCA3MiwgNjQsIDExMiwgNjQsIDE1MiwgNjQsCisxOTIsIDY0LCAyMzIsIDY0LCAxNiwgNjUsIDU2LCA2NSwgOTYsIDY1LCAxMzYsIDY1LCAxNzYsIDY1LCAyMTYsIDY1LAorMCwgNjYsIDQwLCA2NiwgODAsIDY2LCAxMjAsIDY2LCAxNjAsIDY2LCAyMDAsIDY2LCAyNDAsIDY2LCAyNCwgNjcsCis2NCwgNjcsIDEwNCwgNjcsIDE0NCwgNjcsIDE4NCwgNjcsIDIyNCwgNjcsIDgsIDY4LCA0OCwgNjgsIDg4LCA2OCwKKzEyOCwgNjgsIDE2OCwgNjgsIDIwOCwgNjgsIDI0OCwgNjgsIDMyLCA2OSwgNzIsIDY5LCAxMTIsIDY5LCAxNTIsIDY5LAorMTkyLCA2OSwgMjMyLCA2OSwgMTYsIDcwLCA1NiwgNzAsIDk2LCA3MCwgMTM2LCA3MCwgMTc2LCA3MCwgMjE2LCA3MCwKKzAsIDcxLCA0MCwgNzEsIDgwLCA3MSwgMTIwLCA3MSwgMTYwLCA3MSwgMjAwLCA3MSwgMjQwLCA3MSwgMjQsIDcyLAorNjQsIDcyLCAxMDQsIDcyLCAxNDQsIDcyLCAxODQsIDcyLCAyMjQsIDcyLCA4LCA3MywgNDgsIDczLCA4OCwgNzMsCisxMjgsIDczLCAxNjgsIDczLCAyMDgsIDczLCAyNDgsIDczLCAzMiwgNzQsIDcyLCA3NCwgMTEyLCA3NCwgMTUyLCA3NCwKKzE5MiwgNzQsIDIzMiwgNzQsIDE2LCA3NSwgNTYsIDc1LCA5NiwgNzUsIDEzNiwgNzUsIDE3NiwgNzUsIDIxNiwgNzUsCiswLCA3NiwgNDAsIDc2LCA4MCwgNzYsIDEyMCwgNzYsIDE2MCwgNzYsIDIwMCwgNzYsIDI0MCwgNzYsIDI0LCA3NywKKzY0LCA3NywgMTA0LCA3NywgMTQ0LCA3NywgMTg0LCA3NywgMjI0LCA3NywgOCwgNzgsIDQ4LCA3OCwgODgsIDc4LAorMTI4LCA3OCwgMTY4LCA3OCwgMjA4LCA3OCwgMjQ4LCA3OCwgMzIsIDc5LCA3MiwgNzksIDExMiwgNzksIDE1MiwgNzksCisxOTIsIDc5LCAyMzIsIDc5LCAxNiwgODAsIDU2LCA4MCwgOTYsIDgwLCAxMzYsIDgwLCAxNzYsIDgwLCAyMTYsIDgwLAorMCwgODEsIDQwLCA4MSwgODAsIDgxLCAxMjAsIDgxLCAxNjAsIDgxLCAyMDAsIDgxLCAyNDAsIDgxLCAyNCwgODIsCis2NCwgODIsIDEwNCwgODIsIDE0NCwgODIsIDE4NCwgODIsIDIyNCwgODIsIDgsIDgzLCA0OCwgODMsIDg4LCA4MywKKzEyOCwgODMsIDE2OCwgODMsIDIwOCwgODMsIDI0OCwgODMsIDMyLCA4NCwgNzIsIDg0LCAxMTIsIDg0LCAxNTIsIDg0LAorMTkyLCA4NCwgMjMyLCA4NCwgMTYsIDg1LCA1NiwgODUsIDk2LCA4NSwgMTM2LCA4NSwgMTc2LCA4NSwgMjE2LCA4NSwKKzAsIDg2LCA0MCwgODYsIDgwLCA4NiwgMTIwLCA4NiwgMTYwLCA4NiwgMjAwLCA4NiwgMjQwLCA4NiwgMjQsIDg3LAorNjQsIDg3LCAxMDQsIDg3LCAxNDQsIDg3LCAxODQsIDg3LCAyMjQsIDg3LCA4LCA4OCwgNDgsIDg4LCA4OCwgODgsCisxMjgsIDg4LCAxNjgsIDg4LCAyMDgsIDg4LCAyNDgsIDg4LCAzMiwgODksIDcyLCA4OSwgMTEyLCA4OSwgMTUyLCA4OSwKKzE5MiwgODksIDIzMiwgODksIDE2LCA5MCwgNTYsIDkwLCA5NiwgOTAsIDEzNiwgOTAsIDE3NiwgOTAsIDIxNiwgOTAsCiswLCA5MSwgNDAsIDkxLCA4MCwgOTEsIDEyMCwgOTEsIDE2MCwgOTEsIDIwMCwgOTEsIDI0MCwgOTEsIDI0LCA5MiwKKzY0LCA5MiwgMTA0LCA5MiwgMTQ0LCA5MiwgMTg0LCA5MiwgMjI0LCA5MiwgOCwgOTMsIDQ4LCA5MywgODgsIDkzLAorMTI4LCA5MywgMTY4LCA5MywgMjA4LCA5MywgMjQ4LCA5MywgMzIsIDk0LCA3MiwgOTQsIDExMiwgOTQsIDE1MiwgOTQsCisxOTIsIDk0LCAyMzIsIDk0LCAxNiwgOTUsIDU2LCA5NSwgOTYsIDk1LCAxMzYsIDk1LCAxNzYsIDk1LCAyMTYsIDk1LAorMCwgOTYsIDQwLCA5NiwgODAsIDk2LCAxMjAsIDk2LCAxNjAsIDk2LCAyMDAsIDk2LCAyNDAsIDk2LCAyNCwgOTcsCis2NCwgOTcsIDEwNCwgOTcsIDE0NCwgOTcsIDE4NCwgOTcsIDIyNCwgOTcsIDgsIDk4LCA0OCwgOTgsIDg4LCA5OCwKKzEyOCwgOTgsIDE2OCwgOTgsIDIwOCwgOTgsIDI0OCwgOTgsIDMyLCA5OSwgNzIsIDk5LCAxMTIsIDk5LCAxNTIsIDk5LAorMTkyLCA5OSwgMjMyLCA5OSwgMTYsIDEwMCwgNTYsIDEwMCwgOTYsIDEwMCwgMTM2LCAxMDAsIDE3NiwgMTAwLCAyMTYsIDEwMCwKKzAsIDEwMSwgNDAsIDEwMSwgODAsIDEwMSwgMTIwLCAxMDEsIDE2MCwgMTAxLCAyMDAsIDEwMSwgMjQwLCAxMDEsIDI0LCAxMDIsCis2NCwgMTAyLCAxMDQsIDEwMiwgMTQ0LCAxMDIsIDE4NCwgMTAyLCAyMjQsIDEwMiwgOCwgMTAzLCA0OCwgMTAzLCA4OCwgMTAzLAorMTI4LCAxMDMsIDE2OCwgMTAzLCAyMDgsIDEwMywgMjQ4LCAxMDMsIDMyLCAxMDQsIDcyLCAxMDQsIDExMiwgMTA0LCAxNTIsIDEwNCwKKzE5MiwgMTA0LCAyMzIsIDEwNCwgMTYsIDEwNSwgNTYsIDEwNSwgOTYsIDEwNSwgMTM2LCAxMDUsIDE3NiwgMTA1LCAyMTYsIDEwNSwKKzAsIDEwNiwgNDAsIDEwNiwgODAsIDEwNiwgMTIwLCAxMDYsIDE2MCwgMTA2LCAyMDAsIDEwNiwgMjQwLCAxMDYsIDI0LCAxMDcsCis2NCwgMTA3LCAxMDQsIDEwNywgMTQ0LCAxMDcsIDE4NCwgMTA3LCAyMjQsIDEwNywgOCwgMTA4LCA0OCwgMTA4LCA4OCwgMTA4LAorMTI4LCAxMDgsIDE2OCwgMTA4LCAyMDgsIDEwOCwgMjQ4LCAxMDgsIDMyLCAxMDksIDcyLCAxMDksIDExMiwgMTA5LCAxNTIsIDEwOSwKKzE5MiwgMTA5LCAyMzIsIDEwOSwgMTYsIDExMCwgNTYsIDExMCwgOTYsIDExMCwgMTM2LCAxMTAsIDE3NiwgMTEwLCAyMTYsIDExMCwKKzAsIDExMSwgNDAsIDExMSwgODAsIDExMSwgMTIwLCAxMTEsIDE2MCwgMTExLCAyMDAsIDExMSwgMjQwLCAxMTEsIDI0LCAxMTIsCis2NCwgMTEyLCAxMDQsIDExMiwgMTQ0LCAxMTIsIDE4NCwgMTEyLCAyMjQsIDExMiwgOCwgMTEzLCA0OCwgMTEzLCA4OCwgMTEzLAorMTI4LCAxMTMsIDE2OCwgMTEzLCAyMDgsIDExMywgMjQ4LCAxMTMsIDMyLCAxMTQsIDcyLCAxMTQsIDExMiwgMTE0LCAxNTIsIDExNCwKKzE5MiwgMTE0LCAyMzIsIDExNCwgMTYsIDExNSwgNTYsIDExNSwgOTYsIDExNSwgMTM2LCAxMTUsIDE3NiwgMTE1LCAyMTYsIDExNSwKKzAsIDExNiwgNDAsIDExNiwgODAsIDExNiwgMTIwLCAxMTYsIDE2MCwgMTE2LCAyMDAsIDExNiwgMjQwLCAxMTYsIDI0LCAxMTcsCis2NCwgMTE3LCAxMDQsIDExNywgMTQ0LCAxMTcsIDE4NCwgMTE3LCAyMjQsIDExNywgOCwgMTE4LCA0OCwgMTE4LCA4OCwgMTE4LAorMTI4LCAxMTgsIDE2OCwgMTE4LCAyMDgsIDExOCwgMjQ4LCAxMTgsIDMyLCAxMTksIDcyLCAxMTksIDExMiwgMTE5LCAxNTIsIDExOSwKKzE5MiwgMTE5LCAyMzIsIDExOSwgMTYsIDEyMCwgNTYsIDEyMCwgOTYsIDEyMCwgMTM2LCAxMjAsIDE3NiwgMTIwLCAyMTYsIDEyMCwKKzAsIDEyMSwgNDAsIDEyMSwgODAsIDEyMSwgMTIwLCAxMjEsIDE2MCwgMTIxLCAyMDAsIDEyMSwgMjQwLCAxMjEsIDI0LCAxMjIsCis2NCwgMTIyLCAxMDQsIDEyMiwgMTQ0LCAxMjIsIDE4NCwgMTIyLCAyMjQsIDEyMiwgOCwgMTIzLCA0OCwgMTIzLCA4OCwgMTIzLAorMTI4LCAxMjMsIDE2OCwgMTIzLCAyMDgsIDEyMywgMjQ4LCAxMjMsIDMyLCAxMjQsIDcyLCAxMjQsIDExMiwgMTI0LCAxNTIsIDEyNCwKKzE5MiwgMTI0LCAyMzIsIDEyNCwgMTYsIDEyNSwgNTYsIDEyNSwgOTYsIDEyNSwgMTM2LCAxMjUsIDE3NiwgMTI1LCAyMTYsIDEyNSwKKzAsIDEyNiwgNDAsIDEyNiwgODAsIDEyNiwgMTIwLCAxMjYsIDE2MCwgMTI2LCAyMDAsIDEyNiwgMjQwLCAxMjYsIDI0LCAxMjcsCis2NCwgMTI3LCAxMDQsIDEyNywgMTQ0LCAxMjcsIDE4NCwgMTI3LCAyMjQsIDEyNywgOCwgMTI4LCA0OCwgMTI4LCA4OCwgMTI4LAorMTI4LCAxMjgsIDE2OCwgMTI4LCAyMDgsIDEyOCwgMjQ4LCAxMjgsIDMyLCAxMjksIDcyLCAxMjksIDExMiwgMTI5LCAxNTIsIDEyOSwKKzE5MiwgMTI5LCAyMzIsIDEyOSwgMTYsIDEzMCwgNTYsIDEzMCwgOTYsIDEzMCwgMTM2LCAxMzAsIDE3NiwgMTMwLCAyMTYsIDEzMCwKKzAsIDEzMSwgNDAsIDEzMSwgODAsIDEzMSwgMTIwLCAxMzEsIDE2MCwgMTMxLCAyMDAsIDEzMSwgMjQwLCAxMzEsIDI0LCAxMzIsCis2NCwgMTMyLCAxMDQsIDEzMiwgMTQ0LCAxMzIsIDE4NCwgMTMyLCAyMjQsIDEzMiwgOCwgMTMzLCA0OCwgMTMzLCA4OCwgMTMzLAorMTI4LCAxMzMsIDE2OCwgMTMzLCAyMDgsIDEzMywgMjQ4LCAxMzMsIDMyLCAxMzQsIDcyLCAxMzQsIDExMiwgMTM0LCAxNTIsIDEzNCwKKzE5MiwgMTM0LCAyMzIsIDEzNCwgMTYsIDEzNSwgNTYsIDEzNSwgOTYsIDEzNSwgMTM2LCAxMzUsIDE3NiwgMTM1LCAyMTYsIDEzNSwKKzAsIDEzNiwgNDAsIDEzNiwgODAsIDEzNiwgMTIwLCAxMzYsIDE2MCwgMTM2LCAyMDAsIDEzNiwgMjQwLCAxMzYsIDI0LCAxMzcsCis2NCwgMTM3LCAxMDQsIDEzNywgMTQ0LCAxMzcsIDE4NCwgMTM3LCAyMjQsIDEzNywgOCwgMTM4LCA0OCwgMTM4LCA4OCwgMTM4LAorMTI4LCAxMzgsIDE2OCwgMTM4LCAyMDgsIDEzOCwgMjQ4LCAxMzgsIDMyLCAxMzksIDcyLCAxMzksIDExMiwgMTM5LCAxNTIsIDEzOSwKKzE5MiwgMTM5LCAyMzIsIDEzOSwgMTYsIDE0MCwgNTYsIDE0MCwgOTYsIDE0MCwgMTM2LCAxNDAsIDE3NiwgMTQwLCAyMTYsIDE0MCwKKzAsIDE0MSwgNDAsIDE0MSwgODAsIDE0MSwgMTIwLCAxNDEsIDE2MCwgMTQxLCAyMDAsIDE0MSwgMjQwLCAxNDEsIDI0LCAxNDIsCis2NCwgMTQyLCAxMDQsIDE0MiwgMTQ0LCAxNDIsIDE4NCwgMTQyLCAyMjQsIDE0MiwgOCwgMTQzLCA0OCwgMTQzLCA4OCwgMTQzLAorMTI4LCAxNDMsIDE2OCwgMTQzLCAyMDgsIDE0MywgMjQ4LCAxNDMsIDMyLCAxNDQsIDcyLCAxNDQsIDExMiwgMTQ0LCAxNTIsIDE0NCwKKzE5MiwgMTQ0LCAyMzIsIDE0NCwgMTYsIDE0NSwgNTYsIDE0NSwgOTYsIDE0NSwgMTM2LCAxNDUsIDE3NiwgMTQ1LCAyMTYsIDE0NSwKKzAsIDE0NiwgNDAsIDE0NiwgODAsIDE0NiwgMTIwLCAxNDYsIDE2MCwgMTQ2LCAyMDAsIDE0NiwgMjQwLCAxNDYsIDI0LCAxNDcsCis2NCwgMTQ3LCAxMDQsIDE0NywgMTQ0LCAxNDcsIDE4NCwgMTQ3LCAyMjQsIDE0NywgOCwgMTQ4LCA0OCwgMTQ4LCA4OCwgMTQ4LAorMTI4LCAxNDgsIDE2OCwgMTQ4LCAyMDgsIDE0OCwgMjQ4LCAxNDgsIDMyLCAxNDksIDcyLCAxNDksIDExMiwgMTQ5LCAxNTIsIDE0OSwKKzE5MiwgMTQ5LCAyMzIsIDE0OSwgMTYsIDE1MCwgNTYsIDE1MCwgOTYsIDE1MCwgMTM2LCAxNTAsIDE3NiwgMTUwLCAyMTYsIDE1MCwKKzAsIDE1MSwgNDAsIDE1MSwgODAsIDE1MSwgMTIwLCAxNTEsIDE2MCwgMTUxLCAyMDAsIDE1MSwgMjQwLCAxNTEsIDI0LCAxNTIsCis2NCwgMTUyLCAxMDQsIDE1MiwgMTQ0LCAxNTIsIDE4NCwgMTUyLCAyMjQsIDE1MiwgOCwgMTUzLCA0OCwgMTUzLCA4OCwgMTUzLAorMTI4LCAxNTMsIDE2OCwgMTUzLCAyMDgsIDE1MywgMjQ4LCAxNTMsIDMyLCAxNTQsIDcyLCAxNTQsIDExMiwgMTU0LCAxNTIsIDE1NCwKKzE5MiwgMTU0LCAyMzIsIDE1NCwgMTYsIDE1NSwgNTYsIDE1NSwgOTYsIDE1NSwgMTM2LCAxNTUsIDE3NiwgMTU1LCAyMTYsIDE1NSwKKzAsIDE1NiwgNDAsIDE1NiwgODAsIDE1NiwgMTIwLCAxNTYsIDE2MCwgMTU2LCAyMDAsIDE1NiwgMjQwLCAxNTYsIDI0LCAxNTcsCis2NCwgMTU3LCAxMDQsIDE1NywgMTQ0LCAxNTcsIDE4NCwgMTU3LCAyMjQsIDE1NywgOCwgMTU4LCA0OCwgMTU4LCA4OCwgMTU4LAorMTI4LCAxNTgsIDE2OCwgMTU4LCAyMDgsIDE1OCwgMjQ4LCAxNTgsIDMyLCAxNTksIDcyLCAxNTksIDExMiwgMTU5LCAxNTIsIDE1OSwKKzE5MiwgMTU5LCAyMzIsIDE1OSwgMTYsIDE2MCwgNTYsIDE2MCwgOTYsIDE2MCwgMTM2LCAxNjAsIDE3NiwgMTYwLCAyMTYsIDE2MCwKKzAsIDE2MSwgNDAsIDE2MSwgODAsIDE2MSwgMTIwLCAxNjEsIDE2MCwgMTYxLCAyMDAsIDE2MSwgMjQwLCAxNjEsIDI0LCAxNjIsCis2NCwgMTYyLCAxMDQsIDE2MiwgMTQ0LCAxNjIsIDE4NCwgMTYyLCAyMjQsIDE2MiwgOCwgMTYzLCA0OCwgMTYzLCA4OCwgMTYzLAorMTI4LCAxNjMsIDE2OCwgMTYzLCAyMDgsIDE2MywgMjQ4LCAxNjMsIDMyLCAxNjQsIDcyLCAxNjQsIDExMiwgMTY0LCAxNTIsIDE2NCwKKzE5MiwgMTY0LCAyMzIsIDE2NCwgMTYsIDE2NSwgNTYsIDE2NSwgOTYsIDE2NSwgMTM2LCAxNjUsIDE3NiwgMTY1LCAyMTYsIDE2NSwKKzAsIDE2NiwgNDAsIDE2NiwgODAsIDE2NiwgMTIwLCAxNjYsIDE2MCwgMTY2LCAyMDAsIDE2NiwgMjQwLCAxNjYsIDI0LCAxNjcsCis2NCwgMTY3LCAxMDQsIDE2NywgMTQ0LCAxNjcsIDE4NCwgMTY3LCAyMjQsIDE2NywgOCwgMTY4LCA0OCwgMTY4LCA4OCwgMTY4LAorMTI4LCAxNjgsIDE2OCwgMTY4LCAyMDgsIDE2OCwgMjQ4LCAxNjgsIDMyLCAxNjksIDcyLCAxNjksIDExMiwgMTY5LCAxNTIsIDE2OSwKKzE5MiwgMTY5LCAyMzIsIDE2OSwgMTYsIDE3MCwgNTYsIDE3MCwgOTYsIDE3MCwgMTM2LCAxNzAsIDE3NiwgMTcwLCAyMTYsIDE3MCwKKzAsIDE3MSwgNDAsIDE3MSwgODAsIDE3MSwgMTIwLCAxNzEsIDE2MCwgMTcxLCAyMDAsIDE3MSwgMjQwLCAxNzEsIDI0LCAxNzIsCis2NCwgMTcyLCAxMDQsIDE3MiwgMTQ0LCAxNzIsIDE4NCwgMTcyLCAyMjQsIDE3MiwgOCwgMTczLCA0OCwgMTczLCA4OCwgMTczLAorMTI4LCAxNzMsIDE2OCwgMTczLCAyMDgsIDE3MywgMjQ4LCAxNzMsIDMyLCAxNzQsIDcyLCAxNzQsIDExMiwgMTc0LCAxNTIsIDE3NCwKKzE5MiwgMTc0LCAyMzIsIDE3NCwgMTYsIDE3NSwgNTYsIDE3NSwgOTYsIDE3NSwgMTM2LCAxNzUsIDE3NiwgMTc1LCAyMTYsIDE3NSwKKzAsIDE3NiwgNDAsIDE3NiwgODAsIDE3NiwgMTIwLCAxNzYsIDE2MCwgMTc2LCAyMDAsIDE3NiwgMjQwLCAxNzYsIDI0LCAxNzcsCis2NCwgMTc3LCAxMDQsIDE3NywgMTQ0LCAxNzcsIDE4NCwgMTc3LCAyMjQsIDE3NywgOCwgMTc4LCA0OCwgMTc4LCA4OCwgMTc4LAorMTI4LCAxNzgsIDE2OCwgMTc4LCAyMDgsIDE3OCwgMjQ4LCAxNzgsIDMyLCAxNzksIDcyLCAxNzksIDExMiwgMTc5LCAxNTIsIDE3OSwKKzE5MiwgMTc5LCAyMzIsIDE3OSwgMTYsIDE4MCwgNTYsIDE4MCwgOTYsIDE4MCwgMTM2LCAxODAsIDE3NiwgMTgwLCAyMTYsIDE4MCwKKzAsIDE4MSwgNDAsIDE4MSwgODAsIDE4MSwgMTIwLCAxODEsIDE2MCwgMTgxLCAyMDAsIDE4MSwgMjQwLCAxODEsIDI0LCAxODIsCis2NCwgMTgyLCAxMDQsIDE4MiwgMTQ0LCAxODIsIDE4NCwgMTgyLCAyMjQsIDE4MiwgOCwgMTgzLCA0OCwgMTgzLCA4OCwgMTgzLAorMTI4LCAxODMsIDE2OCwgMTgzLCAyMDgsIDE4MywgMjQ4LCAxODMsIDMyLCAxODQsIDcyLCAxODQsIDExMiwgMTg0LCAxNTIsIDE4NCwKKzE5MiwgMTg0LCAyMzIsIDE4NCwgMTYsIDE4NSwgNTYsIDE4NSwgOTYsIDE4NSwgMTM2LCAxODUsIDE3NiwgMTg1LCAyMTYsIDE4NSwKKzAsIDE4NiwgNDAsIDE4NiwgODAsIDE4NiwgMTIwLCAxODYsIDE2MCwgMTg2LCAyMDAsIDE4NiwgMjQwLCAxODYsIDI0LCAxODcsCis2NCwgMTg3LCAxMDQsIDE4NywgMTQ0LCAxODcsIDE4NCwgMTg3LCAyMjQsIDE4NywgOCwgMTg4LCA0OCwgMTg4LCA4OCwgMTg4LAorMTI4LCAxODgsIDE2OCwgMTg4LCAyMDgsIDE4OCwgMjQ4LCAxODgsIDMyLCAxODksIDcyLCAxODksIDExMiwgMTg5LCAxNTIsIDE4OSwKKzE5MiwgMTg5LCAyMzIsIDE4OSwgMTYsIDE5MCwgNTYsIDE5MCwgOTYsIDE5MCwgMTM2LCAxOTAsIDE3NiwgMTkwLCAyMTYsIDE5MCwKKzAsIDE5MSwgNDAsIDE5MSwgODAsIDE5MSwgMTIwLCAxOTEsIDE2MCwgMTkxLCAyMDAsIDE5MSwgMjQwLCAxOTEsIDI0LCAxOTIsCis2NCwgMTkyLCAxMDQsIDE5MiwgMTQ0LCAxOTIsIDE4NCwgMTkyLCAyMjQsIDE5MiwgOCwgMTkzLCA0OCwgMTkzLCA4OCwgMTkzLAorMTI4LCAxOTMsIDE2OCwgMTkzLCAyMDgsIDE5MywgMjQ4LCAxOTMsIDMyLCAxOTQsIDcyLCAxOTQsIDExMiwgMTk0LCAxNTIsIDE5NCwKKzE5MiwgMTk0LCAyMzIsIDE5NCwgMTYsIDE5NSwgNTYsIDE5NSwgOTYsIDE5NSwgMTM2LCAxOTUsIDE3NiwgMTk1LCAyMTYsIDE5NSwKKzAsIDE5NiwgNDAsIDE5NiwgODAsIDE5NiwgMTIwLCAxOTYsIDE2MCwgMTk2LCAyMDAsIDE5NiwgMjQwLCAxOTYsIDI0LCAxOTcsCis2NCwgMTk3LCAxMDQsIDE5NywgMTQ0LCAxOTcsIDE4NCwgMTk3LCAyMjQsIDE5NywgOCwgMTk4LCA0OCwgMTk4LCA4OCwgMTk4LAorMTI4LCAxOTgsIDE2OCwgMTk4LCAyMDgsIDE5OCwgMjQ4LCAxOTgsIDMyLCAxOTksIDcyLCAxOTksIDExMiwgMTk5LCAxNTIsIDE5OSwKKzE5MiwgMTk5LCAyMzIsIDE5OSwgMTYsIDIwMCwgNTYsIDIwMCwgOTYsIDIwMCwgMTM2LCAyMDAsIDE3NiwgMjAwLCAyMTYsIDIwMCwKKzAsIDIwMSwgNDAsIDIwMSwgODAsIDIwMSwgMTIwLCAyMDEsIDE2MCwgMjAxLCAyMDAsIDIwMSwgMjQwLCAyMDEsIDI0LCAyMDIsCis2NCwgMjAyLCAxMDQsIDIwMiwgMTQ0LCAyMDIsIDE4NCwgMjAyLCAyMjQsIDIwMiwgOCwgMjAzLCA0OCwgMjAzLCA4OCwgMjAzLAorMTI4LCAyMDMsIDE2OCwgMjAzLCAyMDgsIDIwMywgMjQ4LCAyMDMsIDMyLCAyMDQsIDcyLCAyMDQsIDExMiwgMjA0LCAxNTIsIDIwNCwKKzE5MiwgMjA0LCAyMzIsIDIwNCwgMTYsIDIwNSwgNTYsIDIwNSwgOTYsIDIwNSwgMTM2LCAyMDUsIDE3NiwgMjA1LCAyMTYsIDIwNSwKKzAsIDIwNiwgNDAsIDIwNiwgODAsIDIwNiwgMTIwLCAyMDYsIDE2MCwgMjA2LCAyMDAsIDIwNiwgMjQwLCAyMDYsIDI0LCAyMDcsCis2NCwgMjA3LCAxMDQsIDIwNywgMTQ0LCAyMDcsIDE4NCwgMjA3LCAyMjQsIDIwNywgOCwgMjA4LCA0OCwgMjA4LCA4OCwgMjA4LAorMTI4LCAyMDgsIDE2OCwgMjA4LCAyMDgsIDIwOCwgMjQ4LCAyMDgsIDMyLCAyMDksIDcyLCAyMDksIDExMiwgMjA5LCAxNTIsIDIwOSwKKzE5MiwgMjA5LCAyMzIsIDIwOSwgMTYsIDIxMCwgNTYsIDIxMCwgOTYsIDIxMCwgMTM2LCAyMTAsIDE3NiwgMjEwLCAyMTYsIDIxMCwKKzAsIDIxMSwgNDAsIDIxMSwgODAsIDIxMSwgMTIwLCAyMTEsIDE2MCwgMjExLCAyMDAsIDIxMSwgMjQwLCAyMTEsIDI0LCAyMTIsCis2NCwgMjEyLCAxMDQsIDIxMiwgMTQ0LCAyMTIsIDE4NCwgMjEyLCAyMjQsIDIxMiwgOCwgMjEzLCA0OCwgMjEzLCA4OCwgMjEzLAorMTI4LCAyMTMsIDE2OCwgMjEzLCAyMDgsIDIxMywgMjQ4LCAyMTMsIDMyLCAyMTQsIDcyLCAyMTQsIDExMiwgMjE0LCAxNTIsIDIxNCwKKzE5MiwgMjE0LCAyMzIsIDIxNCwgMTYsIDIxNSwgNTYsIDIxNSwgOTYsIDIxNSwgMTM2LCAyMTUsIDE3NiwgMjE1LCAyMTYsIDIxNSwKKzAsIDIyNCwgNDAsIDIyNCwgODAsIDIyNCwgMTIwLCAyMjQsIDE2MCwgMjI0LCAyMDAsIDIyNCwgMjQwLCAyMjQsIDI0LCAyMjUsCis2NCwgMjI1LCAxMDQsIDIyNSwgMTQ0LCAyMjUsIDE4NCwgMjI1LCAyMjQsIDIyNSwgOCwgMjI2LCA0OCwgMjI2LCA4OCwgMjI2LAorMTI4LCAyMjYsIDE2OCwgMjI2LCAyMDgsIDIyNiwgMjQ4LCAyMjYsIDMyLCAyMjcsIDcyLCAyMjcsIDExMiwgMjI3LCAxNTIsIDIyNywKKzE5MiwgMjI3LCAyMzIsIDIyNywgMTYsIDIyOCwgNTYsIDIyOCwgOTYsIDIyOCwgMTM2LCAyMjgsIDE3NiwgMjI4LCAyMTYsIDIyOCwKKzAsIDIyOSwgNDAsIDIyOSwgODAsIDIyOSwgMTIwLCAyMjksIDE2MCwgMjI5LCAyMDAsIDIyOSwgMjQwLCAyMjksIDI0LCAyMzAsCis2NCwgMjMwLCAxMDQsIDIzMCwgMTQ0LCAyMzAsIDE4NCwgMjMwLCAyMjQsIDIzMCwgOCwgMjMxLCA0OCwgMjMxLCA4OCwgMjMxLAorMTI4LCAyMzEsIDE2OCwgMjMxLCAyMDgsIDIzMSwgMjQ4LCAyMzEsIDMyLCAyMzIsIDcyLCAyMzIsIDExMiwgMjMyLCAxNTIsIDIzMiwKKzE5MiwgMjMyLCAyMzIsIDIzMiwgMTYsIDIzMywgNTYsIDIzMywgOTYsIDIzMywgMTM2LCAyMzMsIDE3NiwgMjMzLCAyMTYsIDIzMywKKzAsIDIzNCwgNDAsIDIzNCwgODAsIDIzNCwgMTIwLCAyMzQsIDE2MCwgMjM0LCAyMDAsIDIzNCwgMjQwLCAyMzQsIDI0LCAyMzUsCis2NCwgMjM1LCAxMDQsIDIzNSwgMTQ0LCAyMzUsIDE4NCwgMjM1LCAyMjQsIDIzNSwgOCwgMjM2LCA0OCwgMjM2LCA4OCwgMjM2LAorMTI4LCAyMzYsIDE2OCwgMjM2LCAyMDgsIDIzNiwgMjQ4LCAyMzYsIDMyLCAyMzcsIDcyLCAyMzcsIDExMiwgMjM3LCAxNTIsIDIzNywKKzE5MiwgMjM3LCAyMzIsIDIzNywgMTYsIDIzOCwgNTYsIDIzOCwgOTYsIDIzOCwgMTM2LCAyMzgsIDE3NiwgMjM4LCAyMTYsIDIzOCwKKzAsIDIzOSwgNDAsIDIzOSwgODAsIDIzOSwgMTIwLCAyMzksIDE2MCwgMjM5LCAyMDAsIDIzOSwgMjQwLCAyMzksIDI0LCAyNDAsCis2NCwgMjQwLCAxMDQsIDI0MCwgMTQ0LCAyNDAsIDE4NCwgMjQwLCAyMjQsIDI0MCwgOCwgMjQxLCA0OCwgMjQxLCA4OCwgMjQxLAorMTI4LCAyNDEsIDE2OCwgMjQxLCAyMDgsIDI0MSwgMjQ4LCAyNDEsIDMyLCAyNDIsIDcyLCAyNDIsIDExMiwgMjQyLCAxNTIsIDI0MiwKKzE5MiwgMjQyLCAyMzIsIDI0MiwgMTYsIDI0MywgNTYsIDI0MywgOTYsIDI0MywgMTM2LCAyNDMsIDE3NiwgMjQzLCAyMTYsIDI0MywKKzAsIDI0NCwgNDAsIDI0NCwgODAsIDI0NCwgMTIwLCAyNDQsIDE2MCwgMjQ0LCAyMDAsIDI0NCwgMjQwLCAyNDQsIDI0LCAyNDUsCis2NCwgMjQ1LCAxMDQsIDI0NSwgMTQ0LCAyNDUsIDE4NCwgMjQ1LCAyMjQsIDI0NSwgOCwgMjQ2LCA0OCwgMjQ2LCA4OCwgMjQ2LAorMTI4LCAyNDYsIDE2OCwgMjQ2LCAyMDgsIDI0NiwgMjQ4LCAyNDYsIDMyLCAyNDcsIDcyLCAyNDcsIDExMiwgMjQ3LCAxNTIsIDI0NywKKzE5MiwgMjQ3LCAyMzIsIDI0NywgMTYsIDI0OCwgNTYsIDI0OCwgOTYsIDI0OCwgMTM2LCAyNDgsIDE3NiwgMjQ4LCAyMTYsIDI0OCwKKzAsIDI0OSwgNDAsIDI0OSwgODAsIDI0OSwgMTIwLCAyNDksIDE2MCwgMjQ5LCAyMDAsIDI0OSwgMjQwLCAyNDksIDI0LCAyNTAsCis2NCwgMjUwLCAxMDQsIDI1MCwgMTQ0LCAyNTAsIDE4NCwgMjUwLCAyMjQsIDI1MCwgOCwgMjUxLCA0OCwgMjUxLCA4OCwgMjUxLAorMTI4LCAyNTEsIDE2OCwgMjUxLCAyMDgsIDI1MSwgMjQ4LCAyNTEsIDMyLCAyNTIsIDcyLCAyNTIsIDExMiwgMjUyLCAxNTIsIDI1MiwKKzE5MiwgMjUyLCAyMzIsIDI1MiwgMTYsIDI1MywgNTYsIDI1MywgOTYsIDI1MywgMTM2LCAyNTMsIDE3NiwgMjUzLCAyMTYsIDI1MywKKzAsIDI1NCwgNDAsIDI1NCwgODAsIDI1NCwgMTIwLCAyNTQsIDE2MCwgMjU0LCAyMDAsIDI1NCwgMjQwLCAyNTQsIDI0LCAyNTUsCis2NCwgMjU1LCAxMDQsIDI1NSwgMTQ0LCAyNTUsIDE4NCwgMjU1LCAyMjQsIDI1NQorICAgICAgICAgICAgfSk7CisKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9NdWx0aUJ5dGVfVVRGXzE2X0FuZHJvaWQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9NdWx0aUJ5dGVfVVRGXzE2X0FuZHJvaWQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOWM3YzAzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X011bHRpQnl0ZV9VVEZfMTZfQW5kcm9pZC5qYXZhCkBAIC0wLDAgKzEsMzc0IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKKy8qKiBOb3RlOiBJQ1UgYmVoYXZlcyBkaWZmZXJlbnRseSBmcm9tIHRoZSBSSSAqLworCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9NdWx0aUJ5dGVfVVRGXzE2X0FuZHJvaWQgZXh0ZW5kcyBPbGRDaGFyc2V0X0Fic3RyYWN0VGVzdCB7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyc2V0TmFtZSA9ICJVVEYtMTYiOworCisgICAgICAgIHRlc3RDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCis0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKzY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCis5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKzExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKzEyOCwgMTI5LCAxMzAsIDEzMSwgMTMyLCAxMzMsIDEzNCwgMTM1LCAxMzYsIDEzNywgMTM4LCAxMzksIDE0MCwgMTQxLCAxNDIsIDE0MywKKzE0NCwgMTQ1LCAxNDYsIDE0NywgMTQ4LCAxNDksIDE1MCwgMTUxLCAxNTIsIDE1MywgMTU0LCAxNTUsIDE1NiwgMTU3LCAxNTgsIDE1OSwKKzE2MCwgMTYxLCAxNjIsIDE2MywgMTY0LCAxNjUsIDE2NiwgMTY3LCAxNjgsIDE2OSwgMTcwLCAxNzEsIDE3MiwgMTczLCAxNzQsIDE3NSwKKzE3NiwgMTc3LCAxNzgsIDE3OSwgMTgwLCAxODEsIDE4MiwgMTgzLCAxODQsIDE4NSwgMTg2LCAxODcsIDE4OCwgMTg5LCAxOTAsIDE5MSwKKzE5MiwgMTkzLCAxOTQsIDE5NSwgMTk2LCAxOTcsIDE5OCwgMTk5LCAyMDAsIDIwMSwgMjAyLCAyMDMsIDIwNCwgMjA1LCAyMDYsIDIwNywKKzIwOCwgMjA5LCAyMTAsIDIxMSwgMjEyLCAyMTMsIDIxNCwgMjE1LCAyMTYsIDIxNywgMjE4LCAyMTksIDIyMCwgMjIxLCAyMjIsIDIyMywKKzIyNCwgMjI1LCAyMjYsIDIyNywgMjI4LCAyMjksIDIzMCwgMjMxLCAyMzIsIDIzMywgMjM0LCAyMzUsIDIzNiwgMjM3LCAyMzgsIDIzOSwKKzI0MCwgMjQxLCAyNDIsIDI0MywgMjQ0LCAyNDUsIDI0NiwgMjQ3LCAyNDgsIDI0OSwgMjUwLCAyNTEsIDI1MiwgMjUzLCAyNTQsIDI1NSwKKzI1NiwgMjk2LCAzMzYsIDM3NiwgNDE2LCA0NTYsIDQ5NiwgNTM2LCA1NzYsIDYxNiwgNjU2LCA2OTYsIDczNiwgNzc2LCA4MTYsIDg1NiwKKzg5NiwgOTM2LCA5NzYsIDEwMTYsIDEwNTYsIDEwOTYsIDExMzYsIDExNzYsIDEyMTYsIDEyNTYsIDEyOTYsIDEzMzYsIDEzNzYsIDE0MTYsIDE0NTYsIDE0OTYsCisxNTM2LCAxNTc2LCAxNjE2LCAxNjU2LCAxNjk2LCAxNzM2LCAxNzc2LCAxODE2LCAxODU2LCAxODk2LCAxOTM2LCAxOTc2LCAyMDE2LCAyMDU2LCAyMDk2LCAyMTM2LAorMjE3NiwgMjIxNiwgMjI1NiwgMjI5NiwgMjMzNiwgMjM3NiwgMjQxNiwgMjQ1NiwgMjQ5NiwgMjUzNiwgMjU3NiwgMjYxNiwgMjY1NiwgMjY5NiwgMjczNiwgMjc3NiwKKzI4MTYsIDI4NTYsIDI4OTYsIDI5MzYsIDI5NzYsIDMwMTYsIDMwNTYsIDMwOTYsIDMxMzYsIDMxNzYsIDMyMTYsIDMyNTYsIDMyOTYsIDMzMzYsIDMzNzYsIDM0MTYsCiszNDU2LCAzNDk2LCAzNTM2LCAzNTc2LCAzNjE2LCAzNjU2LCAzNjk2LCAzNzM2LCAzNzc2LCAzODE2LCAzODU2LCAzODk2LCAzOTM2LCAzOTc2LCA0MDE2LCA0MDU2LAorNDA5NiwgNDEzNiwgNDE3NiwgNDIxNiwgNDI1NiwgNDI5NiwgNDMzNiwgNDM3NiwgNDQxNiwgNDQ1NiwgNDQ5NiwgNDUzNiwgNDU3NiwgNDYxNiwgNDY1NiwgNDY5NiwKKzQ3MzYsIDQ3NzYsIDQ4MTYsIDQ4NTYsIDQ4OTYsIDQ5MzYsIDQ5NzYsIDUwMTYsIDUwNTYsIDUwOTYsIDUxMzYsIDUxNzYsIDUyMTYsIDUyNTYsIDUyOTYsIDUzMzYsCis1Mzc2LCA1NDE2LCA1NDU2LCA1NDk2LCA1NTM2LCA1NTc2LCA1NjE2LCA1NjU2LCA1Njk2LCA1NzM2LCA1Nzc2LCA1ODE2LCA1ODU2LCA1ODk2LCA1OTM2LCA1OTc2LAorNjAxNiwgNjA1NiwgNjA5NiwgNjEzNiwgNjE3NiwgNjIxNiwgNjI1NiwgNjI5NiwgNjMzNiwgNjM3NiwgNjQxNiwgNjQ1NiwgNjQ5NiwgNjUzNiwgNjU3NiwgNjYxNiwKKzY2NTYsIDY2OTYsIDY3MzYsIDY3NzYsIDY4MTYsIDY4NTYsIDY4OTYsIDY5MzYsIDY5NzYsIDcwMTYsIDcwNTYsIDcwOTYsIDcxMzYsIDcxNzYsIDcyMTYsIDcyNTYsCis3Mjk2LCA3MzM2LCA3Mzc2LCA3NDE2LCA3NDU2LCA3NDk2LCA3NTM2LCA3NTc2LCA3NjE2LCA3NjU2LCA3Njk2LCA3NzM2LCA3Nzc2LCA3ODE2LCA3ODU2LCA3ODk2LAorNzkzNiwgNzk3NiwgODAxNiwgODA1NiwgODA5NiwgODEzNiwgODE3NiwgODIxNiwgODI1NiwgODI5NiwgODMzNiwgODM3NiwgODQxNiwgODQ1NiwgODQ5NiwgODUzNiwKKzg1NzYsIDg2MTYsIDg2NTYsIDg2OTYsIDg3MzYsIDg3NzYsIDg4MTYsIDg4NTYsIDg4OTYsIDg5MzYsIDg5NzYsIDkwMTYsIDkwNTYsIDkwOTYsIDkxMzYsIDkxNzYsCis5MjE2LCA5MjU2LCA5Mjk2LCA5MzM2LCA5Mzc2LCA5NDE2LCA5NDU2LCA5NDk2LCA5NTM2LCA5NTc2LCA5NjE2LCA5NjU2LCA5Njk2LCA5NzM2LCA5Nzc2LCA5ODE2LAorOTg1NiwgOTg5NiwgOTkzNiwgOTk3NiwgMTAwMTYsIDEwMDU2LCAxMDA5NiwgMTAxMzYsIDEwMTc2LCAxMDIxNiwgMTAyNTYsIDEwMjk2LCAxMDMzNiwgMTAzNzYsIDEwNDE2LCAxMDQ1NiwKKzEwNDk2LCAxMDUzNiwgMTA1NzYsIDEwNjE2LCAxMDY1NiwgMTA2OTYsIDEwNzM2LCAxMDc3NiwgMTA4MTYsIDEwODU2LCAxMDg5NiwgMTA5MzYsIDEwOTc2LCAxMTAxNiwgMTEwNTYsIDExMDk2LAorMTExMzYsIDExMTc2LCAxMTIxNiwgMTEyNTYsIDExMjk2LCAxMTMzNiwgMTEzNzYsIDExNDE2LCAxMTQ1NiwgMTE0OTYsIDExNTM2LCAxMTU3NiwgMTE2MTYsIDExNjU2LCAxMTY5NiwgMTE3MzYsCisxMTc3NiwgMTE4MTYsIDExODU2LCAxMTg5NiwgMTE5MzYsIDExOTc2LCAxMjAxNiwgMTIwNTYsIDEyMDk2LCAxMjEzNiwgMTIxNzYsIDEyMjE2LCAxMjI1NiwgMTIyOTYsIDEyMzM2LCAxMjM3NiwKKzEyNDE2LCAxMjQ1NiwgMTI0OTYsIDEyNTM2LCAxMjU3NiwgMTI2MTYsIDEyNjU2LCAxMjY5NiwgMTI3MzYsIDEyNzc2LCAxMjgxNiwgMTI4NTYsIDEyODk2LCAxMjkzNiwgMTI5NzYsIDEzMDE2LAorMTMwNTYsIDEzMDk2LCAxMzEzNiwgMTMxNzYsIDEzMjE2LCAxMzI1NiwgMTMyOTYsIDEzMzM2LCAxMzM3NiwgMTM0MTYsIDEzNDU2LCAxMzQ5NiwgMTM1MzYsIDEzNTc2LCAxMzYxNiwgMTM2NTYsCisxMzY5NiwgMTM3MzYsIDEzNzc2LCAxMzgxNiwgMTM4NTYsIDEzODk2LCAxMzkzNiwgMTM5NzYsIDE0MDE2LCAxNDA1NiwgMTQwOTYsIDE0MTM2LCAxNDE3NiwgMTQyMTYsIDE0MjU2LCAxNDI5NiwKKzE0MzM2LCAxNDM3NiwgMTQ0MTYsIDE0NDU2LCAxNDQ5NiwgMTQ1MzYsIDE0NTc2LCAxNDYxNiwgMTQ2NTYsIDE0Njk2LCAxNDczNiwgMTQ3NzYsIDE0ODE2LCAxNDg1NiwgMTQ4OTYsIDE0OTM2LAorMTQ5NzYsIDE1MDE2LCAxNTA1NiwgMTUwOTYsIDE1MTM2LCAxNTE3NiwgMTUyMTYsIDE1MjU2LCAxNTI5NiwgMTUzMzYsIDE1Mzc2LCAxNTQxNiwgMTU0NTYsIDE1NDk2LCAxNTUzNiwgMTU1NzYsCisxNTYxNiwgMTU2NTYsIDE1Njk2LCAxNTczNiwgMTU3NzYsIDE1ODE2LCAxNTg1NiwgMTU4OTYsIDE1OTM2LCAxNTk3NiwgMTYwMTYsIDE2MDU2LCAxNjA5NiwgMTYxMzYsIDE2MTc2LCAxNjIxNiwKKzE2MjU2LCAxNjI5NiwgMTYzMzYsIDE2Mzc2LCAxNjQxNiwgMTY0NTYsIDE2NDk2LCAxNjUzNiwgMTY1NzYsIDE2NjE2LCAxNjY1NiwgMTY2OTYsIDE2NzM2LCAxNjc3NiwgMTY4MTYsIDE2ODU2LAorMTY4OTYsIDE2OTM2LCAxNjk3NiwgMTcwMTYsIDE3MDU2LCAxNzA5NiwgMTcxMzYsIDE3MTc2LCAxNzIxNiwgMTcyNTYsIDE3Mjk2LCAxNzMzNiwgMTczNzYsIDE3NDE2LCAxNzQ1NiwgMTc0OTYsCisxNzUzNiwgMTc1NzYsIDE3NjE2LCAxNzY1NiwgMTc2OTYsIDE3NzM2LCAxNzc3NiwgMTc4MTYsIDE3ODU2LCAxNzg5NiwgMTc5MzYsIDE3OTc2LCAxODAxNiwgMTgwNTYsIDE4MDk2LCAxODEzNiwKKzE4MTc2LCAxODIxNiwgMTgyNTYsIDE4Mjk2LCAxODMzNiwgMTgzNzYsIDE4NDE2LCAxODQ1NiwgMTg0OTYsIDE4NTM2LCAxODU3NiwgMTg2MTYsIDE4NjU2LCAxODY5NiwgMTg3MzYsIDE4Nzc2LAorMTg4MTYsIDE4ODU2LCAxODg5NiwgMTg5MzYsIDE4OTc2LCAxOTAxNiwgMTkwNTYsIDE5MDk2LCAxOTEzNiwgMTkxNzYsIDE5MjE2LCAxOTI1NiwgMTkyOTYsIDE5MzM2LCAxOTM3NiwgMTk0MTYsCisxOTQ1NiwgMTk0OTYsIDE5NTM2LCAxOTU3NiwgMTk2MTYsIDE5NjU2LCAxOTY5NiwgMTk3MzYsIDE5Nzc2LCAxOTgxNiwgMTk4NTYsIDE5ODk2LCAxOTkzNiwgMTk5NzYsIDIwMDE2LCAyMDA1NiwKKzIwMDk2LCAyMDEzNiwgMjAxNzYsIDIwMjE2LCAyMDI1NiwgMjAyOTYsIDIwMzM2LCAyMDM3NiwgMjA0MTYsIDIwNDU2LCAyMDQ5NiwgMjA1MzYsIDIwNTc2LCAyMDYxNiwgMjA2NTYsIDIwNjk2LAorMjA3MzYsIDIwNzc2LCAyMDgxNiwgMjA4NTYsIDIwODk2LCAyMDkzNiwgMjA5NzYsIDIxMDE2LCAyMTA1NiwgMjEwOTYsIDIxMTM2LCAyMTE3NiwgMjEyMTYsIDIxMjU2LCAyMTI5NiwgMjEzMzYsCisyMTM3NiwgMjE0MTYsIDIxNDU2LCAyMTQ5NiwgMjE1MzYsIDIxNTc2LCAyMTYxNiwgMjE2NTYsIDIxNjk2LCAyMTczNiwgMjE3NzYsIDIxODE2LCAyMTg1NiwgMjE4OTYsIDIxOTM2LCAyMTk3NiwKKzIyMDE2LCAyMjA1NiwgMjIwOTYsIDIyMTM2LCAyMjE3NiwgMjIyMTYsIDIyMjU2LCAyMjI5NiwgMjIzMzYsIDIyMzc2LCAyMjQxNiwgMjI0NTYsIDIyNDk2LCAyMjUzNiwgMjI1NzYsIDIyNjE2LAorMjI2NTYsIDIyNjk2LCAyMjczNiwgMjI3NzYsIDIyODE2LCAyMjg1NiwgMjI4OTYsIDIyOTM2LCAyMjk3NiwgMjMwMTYsIDIzMDU2LCAyMzA5NiwgMjMxMzYsIDIzMTc2LCAyMzIxNiwgMjMyNTYsCisyMzI5NiwgMjMzMzYsIDIzMzc2LCAyMzQxNiwgMjM0NTYsIDIzNDk2LCAyMzUzNiwgMjM1NzYsIDIzNjE2LCAyMzY1NiwgMjM2OTYsIDIzNzM2LCAyMzc3NiwgMjM4MTYsIDIzODU2LCAyMzg5NiwKKzIzOTM2LCAyMzk3NiwgMjQwMTYsIDI0MDU2LCAyNDA5NiwgMjQxMzYsIDI0MTc2LCAyNDIxNiwgMjQyNTYsIDI0Mjk2LCAyNDMzNiwgMjQzNzYsIDI0NDE2LCAyNDQ1NiwgMjQ0OTYsIDI0NTM2LAorMjQ1NzYsIDI0NjE2LCAyNDY1NiwgMjQ2OTYsIDI0NzM2LCAyNDc3NiwgMjQ4MTYsIDI0ODU2LCAyNDg5NiwgMjQ5MzYsIDI0OTc2LCAyNTAxNiwgMjUwNTYsIDI1MDk2LCAyNTEzNiwgMjUxNzYsCisyNTIxNiwgMjUyNTYsIDI1Mjk2LCAyNTMzNiwgMjUzNzYsIDI1NDE2LCAyNTQ1NiwgMjU0OTYsIDI1NTM2LCAyNTU3NiwgMjU2MTYsIDI1NjU2LCAyNTY5NiwgMjU3MzYsIDI1Nzc2LCAyNTgxNiwKKzI1ODU2LCAyNTg5NiwgMjU5MzYsIDI1OTc2LCAyNjAxNiwgMjYwNTYsIDI2MDk2LCAyNjEzNiwgMjYxNzYsIDI2MjE2LCAyNjI1NiwgMjYyOTYsIDI2MzM2LCAyNjM3NiwgMjY0MTYsIDI2NDU2LAorMjY0OTYsIDI2NTM2LCAyNjU3NiwgMjY2MTYsIDI2NjU2LCAyNjY5NiwgMjY3MzYsIDI2Nzc2LCAyNjgxNiwgMjY4NTYsIDI2ODk2LCAyNjkzNiwgMjY5NzYsIDI3MDE2LCAyNzA1NiwgMjcwOTYsCisyNzEzNiwgMjcxNzYsIDI3MjE2LCAyNzI1NiwgMjcyOTYsIDI3MzM2LCAyNzM3NiwgMjc0MTYsIDI3NDU2LCAyNzQ5NiwgMjc1MzYsIDI3NTc2LCAyNzYxNiwgMjc2NTYsIDI3Njk2LCAyNzczNiwKKzI3Nzc2LCAyNzgxNiwgMjc4NTYsIDI3ODk2LCAyNzkzNiwgMjc5NzYsIDI4MDE2LCAyODA1NiwgMjgwOTYsIDI4MTM2LCAyODE3NiwgMjgyMTYsIDI4MjU2LCAyODI5NiwgMjgzMzYsIDI4Mzc2LAorMjg0MTYsIDI4NDU2LCAyODQ5NiwgMjg1MzYsIDI4NTc2LCAyODYxNiwgMjg2NTYsIDI4Njk2LCAyODczNiwgMjg3NzYsIDI4ODE2LCAyODg1NiwgMjg4OTYsIDI4OTM2LCAyODk3NiwgMjkwMTYsCisyOTA1NiwgMjkwOTYsIDI5MTM2LCAyOTE3NiwgMjkyMTYsIDI5MjU2LCAyOTI5NiwgMjkzMzYsIDI5Mzc2LCAyOTQxNiwgMjk0NTYsIDI5NDk2LCAyOTUzNiwgMjk1NzYsIDI5NjE2LCAyOTY1NiwKKzI5Njk2LCAyOTczNiwgMjk3NzYsIDI5ODE2LCAyOTg1NiwgMjk4OTYsIDI5OTM2LCAyOTk3NiwgMzAwMTYsIDMwMDU2LCAzMDA5NiwgMzAxMzYsIDMwMTc2LCAzMDIxNiwgMzAyNTYsIDMwMjk2LAorMzAzMzYsIDMwMzc2LCAzMDQxNiwgMzA0NTYsIDMwNDk2LCAzMDUzNiwgMzA1NzYsIDMwNjE2LCAzMDY1NiwgMzA2OTYsIDMwNzM2LCAzMDc3NiwgMzA4MTYsIDMwODU2LCAzMDg5NiwgMzA5MzYsCiszMDk3NiwgMzEwMTYsIDMxMDU2LCAzMTA5NiwgMzExMzYsIDMxMTc2LCAzMTIxNiwgMzEyNTYsIDMxMjk2LCAzMTMzNiwgMzEzNzYsIDMxNDE2LCAzMTQ1NiwgMzE0OTYsIDMxNTM2LCAzMTU3NiwKKzMxNjE2LCAzMTY1NiwgMzE2OTYsIDMxNzM2LCAzMTc3NiwgMzE4MTYsIDMxODU2LCAzMTg5NiwgMzE5MzYsIDMxOTc2LCAzMjAxNiwgMzIwNTYsIDMyMDk2LCAzMjEzNiwgMzIxNzYsIDMyMjE2LAorMzIyNTYsIDMyMjk2LCAzMjMzNiwgMzIzNzYsIDMyNDE2LCAzMjQ1NiwgMzI0OTYsIDMyNTM2LCAzMjU3NiwgMzI2MTYsIDMyNjU2LCAzMjY5NiwgMzI3MzYsIDMyNzc2LCAzMjgxNiwgMzI4NTYsCiszMjg5NiwgMzI5MzYsIDMyOTc2LCAzMzAxNiwgMzMwNTYsIDMzMDk2LCAzMzEzNiwgMzMxNzYsIDMzMjE2LCAzMzI1NiwgMzMyOTYsIDMzMzM2LCAzMzM3NiwgMzM0MTYsIDMzNDU2LCAzMzQ5NiwKKzMzNTM2LCAzMzU3NiwgMzM2MTYsIDMzNjU2LCAzMzY5NiwgMzM3MzYsIDMzNzc2LCAzMzgxNiwgMzM4NTYsIDMzODk2LCAzMzkzNiwgMzM5NzYsIDM0MDE2LCAzNDA1NiwgMzQwOTYsIDM0MTM2LAorMzQxNzYsIDM0MjE2LCAzNDI1NiwgMzQyOTYsIDM0MzM2LCAzNDM3NiwgMzQ0MTYsIDM0NDU2LCAzNDQ5NiwgMzQ1MzYsIDM0NTc2LCAzNDYxNiwgMzQ2NTYsIDM0Njk2LCAzNDczNiwgMzQ3NzYsCiszNDgxNiwgMzQ4NTYsIDM0ODk2LCAzNDkzNiwgMzQ5NzYsIDM1MDE2LCAzNTA1NiwgMzUwOTYsIDM1MTM2LCAzNTE3NiwgMzUyMTYsIDM1MjU2LCAzNTI5NiwgMzUzMzYsIDM1Mzc2LCAzNTQxNiwKKzM1NDU2LCAzNTQ5NiwgMzU1MzYsIDM1NTc2LCAzNTYxNiwgMzU2NTYsIDM1Njk2LCAzNTczNiwgMzU3NzYsIDM1ODE2LCAzNTg1NiwgMzU4OTYsIDM1OTM2LCAzNTk3NiwgMzYwMTYsIDM2MDU2LAorMzYwOTYsIDM2MTM2LCAzNjE3NiwgMzYyMTYsIDM2MjU2LCAzNjI5NiwgMzYzMzYsIDM2Mzc2LCAzNjQxNiwgMzY0NTYsIDM2NDk2LCAzNjUzNiwgMzY1NzYsIDM2NjE2LCAzNjY1NiwgMzY2OTYsCiszNjczNiwgMzY3NzYsIDM2ODE2LCAzNjg1NiwgMzY4OTYsIDM2OTM2LCAzNjk3NiwgMzcwMTYsIDM3MDU2LCAzNzA5NiwgMzcxMzYsIDM3MTc2LCAzNzIxNiwgMzcyNTYsIDM3Mjk2LCAzNzMzNiwKKzM3Mzc2LCAzNzQxNiwgMzc0NTYsIDM3NDk2LCAzNzUzNiwgMzc1NzYsIDM3NjE2LCAzNzY1NiwgMzc2OTYsIDM3NzM2LCAzNzc3NiwgMzc4MTYsIDM3ODU2LCAzNzg5NiwgMzc5MzYsIDM3OTc2LAorMzgwMTYsIDM4MDU2LCAzODA5NiwgMzgxMzYsIDM4MTc2LCAzODIxNiwgMzgyNTYsIDM4Mjk2LCAzODMzNiwgMzgzNzYsIDM4NDE2LCAzODQ1NiwgMzg0OTYsIDM4NTM2LCAzODU3NiwgMzg2MTYsCiszODY1NiwgMzg2OTYsIDM4NzM2LCAzODc3NiwgMzg4MTYsIDM4ODU2LCAzODg5NiwgMzg5MzYsIDM4OTc2LCAzOTAxNiwgMzkwNTYsIDM5MDk2LCAzOTEzNiwgMzkxNzYsIDM5MjE2LCAzOTI1NiwKKzM5Mjk2LCAzOTMzNiwgMzkzNzYsIDM5NDE2LCAzOTQ1NiwgMzk0OTYsIDM5NTM2LCAzOTU3NiwgMzk2MTYsIDM5NjU2LCAzOTY5NiwgMzk3MzYsIDM5Nzc2LCAzOTgxNiwgMzk4NTYsIDM5ODk2LAorMzk5MzYsIDM5OTc2LCA0MDAxNiwgNDAwNTYsIDQwMDk2LCA0MDEzNiwgNDAxNzYsIDQwMjE2LCA0MDI1NiwgNDAyOTYsIDQwMzM2LCA0MDM3NiwgNDA0MTYsIDQwNDU2LCA0MDQ5NiwgNDA1MzYsCis0MDU3NiwgNDA2MTYsIDQwNjU2LCA0MDY5NiwgNDA3MzYsIDQwNzc2LCA0MDgxNiwgNDA4NTYsIDQwODk2LCA0MDkzNiwgNDA5NzYsIDQxMDE2LCA0MTA1NiwgNDEwOTYsIDQxMTM2LCA0MTE3NiwKKzQxMjE2LCA0MTI1NiwgNDEyOTYsIDQxMzM2LCA0MTM3NiwgNDE0MTYsIDQxNDU2LCA0MTQ5NiwgNDE1MzYsIDQxNTc2LCA0MTYxNiwgNDE2NTYsIDQxNjk2LCA0MTczNiwgNDE3NzYsIDQxODE2LAorNDE4NTYsIDQxODk2LCA0MTkzNiwgNDE5NzYsIDQyMDE2LCA0MjA1NiwgNDIwOTYsIDQyMTM2LCA0MjE3NiwgNDIyMTYsIDQyMjU2LCA0MjI5NiwgNDIzMzYsIDQyMzc2LCA0MjQxNiwgNDI0NTYsCis0MjQ5NiwgNDI1MzYsIDQyNTc2LCA0MjYxNiwgNDI2NTYsIDQyNjk2LCA0MjczNiwgNDI3NzYsIDQyODE2LCA0Mjg1NiwgNDI4OTYsIDQyOTM2LCA0Mjk3NiwgNDMwMTYsIDQzMDU2LCA0MzA5NiwKKzQzMTM2LCA0MzE3NiwgNDMyMTYsIDQzMjU2LCA0MzI5NiwgNDMzMzYsIDQzMzc2LCA0MzQxNiwgNDM0NTYsIDQzNDk2LCA0MzUzNiwgNDM1NzYsIDQzNjE2LCA0MzY1NiwgNDM2OTYsIDQzNzM2LAorNDM3NzYsIDQzODE2LCA0Mzg1NiwgNDM4OTYsIDQzOTM2LCA0Mzk3NiwgNDQwMTYsIDQ0MDU2LCA0NDA5NiwgNDQxMzYsIDQ0MTc2LCA0NDIxNiwgNDQyNTYsIDQ0Mjk2LCA0NDMzNiwgNDQzNzYsCis0NDQxNiwgNDQ0NTYsIDQ0NDk2LCA0NDUzNiwgNDQ1NzYsIDQ0NjE2LCA0NDY1NiwgNDQ2OTYsIDQ0NzM2LCA0NDc3NiwgNDQ4MTYsIDQ0ODU2LCA0NDg5NiwgNDQ5MzYsIDQ0OTc2LCA0NTAxNiwKKzQ1MDU2LCA0NTA5NiwgNDUxMzYsIDQ1MTc2LCA0NTIxNiwgNDUyNTYsIDQ1Mjk2LCA0NTMzNiwgNDUzNzYsIDQ1NDE2LCA0NTQ1NiwgNDU0OTYsIDQ1NTM2LCA0NTU3NiwgNDU2MTYsIDQ1NjU2LAorNDU2OTYsIDQ1NzM2LCA0NTc3NiwgNDU4MTYsIDQ1ODU2LCA0NTg5NiwgNDU5MzYsIDQ1OTc2LCA0NjAxNiwgNDYwNTYsIDQ2MDk2LCA0NjEzNiwgNDYxNzYsIDQ2MjE2LCA0NjI1NiwgNDYyOTYsCis0NjMzNiwgNDYzNzYsIDQ2NDE2LCA0NjQ1NiwgNDY0OTYsIDQ2NTM2LCA0NjU3NiwgNDY2MTYsIDQ2NjU2LCA0NjY5NiwgNDY3MzYsIDQ2Nzc2LCA0NjgxNiwgNDY4NTYsIDQ2ODk2LCA0NjkzNiwKKzQ2OTc2LCA0NzAxNiwgNDcwNTYsIDQ3MDk2LCA0NzEzNiwgNDcxNzYsIDQ3MjE2LCA0NzI1NiwgNDcyOTYsIDQ3MzM2LCA0NzM3NiwgNDc0MTYsIDQ3NDU2LCA0NzQ5NiwgNDc1MzYsIDQ3NTc2LAorNDc2MTYsIDQ3NjU2LCA0NzY5NiwgNDc3MzYsIDQ3Nzc2LCA0NzgxNiwgNDc4NTYsIDQ3ODk2LCA0NzkzNiwgNDc5NzYsIDQ4MDE2LCA0ODA1NiwgNDgwOTYsIDQ4MTM2LCA0ODE3NiwgNDgyMTYsCis0ODI1NiwgNDgyOTYsIDQ4MzM2LCA0ODM3NiwgNDg0MTYsIDQ4NDU2LCA0ODQ5NiwgNDg1MzYsIDQ4NTc2LCA0ODYxNiwgNDg2NTYsIDQ4Njk2LCA0ODczNiwgNDg3NzYsIDQ4ODE2LCA0ODg1NiwKKzQ4ODk2LCA0ODkzNiwgNDg5NzYsIDQ5MDE2LCA0OTA1NiwgNDkwOTYsIDQ5MTM2LCA0OTE3NiwgNDkyMTYsIDQ5MjU2LCA0OTI5NiwgNDkzMzYsIDQ5Mzc2LCA0OTQxNiwgNDk0NTYsIDQ5NDk2LAorNDk1MzYsIDQ5NTc2LCA0OTYxNiwgNDk2NTYsIDQ5Njk2LCA0OTczNiwgNDk3NzYsIDQ5ODE2LCA0OTg1NiwgNDk4OTYsIDQ5OTM2LCA0OTk3NiwgNTAwMTYsIDUwMDU2LCA1MDA5NiwgNTAxMzYsCis1MDE3NiwgNTAyMTYsIDUwMjU2LCA1MDI5NiwgNTAzMzYsIDUwMzc2LCA1MDQxNiwgNTA0NTYsIDUwNDk2LCA1MDUzNiwgNTA1NzYsIDUwNjE2LCA1MDY1NiwgNTA2OTYsIDUwNzM2LCA1MDc3NiwKKzUwODE2LCA1MDg1NiwgNTA4OTYsIDUwOTM2LCA1MDk3NiwgNTEwMTYsIDUxMDU2LCA1MTA5NiwgNTExMzYsIDUxMTc2LCA1MTIxNiwgNTEyNTYsIDUxMjk2LCA1MTMzNiwgNTEzNzYsIDUxNDE2LAorNTE0NTYsIDUxNDk2LCA1MTUzNiwgNTE1NzYsIDUxNjE2LCA1MTY1NiwgNTE2OTYsIDUxNzM2LCA1MTc3NiwgNTE4MTYsIDUxODU2LCA1MTg5NiwgNTE5MzYsIDUxOTc2LCA1MjAxNiwgNTIwNTYsCis1MjA5NiwgNTIxMzYsIDUyMTc2LCA1MjIxNiwgNTIyNTYsIDUyMjk2LCA1MjMzNiwgNTIzNzYsIDUyNDE2LCA1MjQ1NiwgNTI0OTYsIDUyNTM2LCA1MjU3NiwgNTI2MTYsIDUyNjU2LCA1MjY5NiwKKzUyNzM2LCA1Mjc3NiwgNTI4MTYsIDUyODU2LCA1Mjg5NiwgNTI5MzYsIDUyOTc2LCA1MzAxNiwgNTMwNTYsIDUzMDk2LCA1MzEzNiwgNTMxNzYsIDUzMjE2LCA1MzI1NiwgNTMyOTYsIDUzMzM2LAorNTMzNzYsIDUzNDE2LCA1MzQ1NiwgNTM0OTYsIDUzNTM2LCA1MzU3NiwgNTM2MTYsIDUzNjU2LCA1MzY5NiwgNTM3MzYsIDUzNzc2LCA1MzgxNiwgNTM4NTYsIDUzODk2LCA1MzkzNiwgNTM5NzYsCis1NDAxNiwgNTQwNTYsIDU0MDk2LCA1NDEzNiwgNTQxNzYsIDU0MjE2LCA1NDI1NiwgNTQyOTYsIDU0MzM2LCA1NDM3NiwgNTQ0MTYsIDU0NDU2LCA1NDQ5NiwgNTQ1MzYsIDU0NTc2LCA1NDYxNiwKKzU0NjU2LCA1NDY5NiwgNTQ3MzYsIDU0Nzc2LCA1NDgxNiwgNTQ4NTYsIDU0ODk2LCA1NDkzNiwgNTQ5NzYsIDU1MDE2LCA1NTA1NiwgNTUwOTYsIDU1MTM2LCA1NTE3NiwgNTUyMTYsIDU1MjU2LAorNTczNDQsIDU3Mzg0LCA1NzQyNCwgNTc0NjQsIDU3NTA0LCA1NzU0NCwgNTc1ODQsIDU3NjI0LCA1NzY2NCwgNTc3MDQsIDU3NzQ0LCA1Nzc4NCwgNTc4MjQsIDU3ODY0LCA1NzkwNCwgNTc5NDQsCis1Nzk4NCwgNTgwMjQsIDU4MDY0LCA1ODEwNCwgNTgxNDQsIDU4MTg0LCA1ODIyNCwgNTgyNjQsIDU4MzA0LCA1ODM0NCwgNTgzODQsIDU4NDI0LCA1ODQ2NCwgNTg1MDQsIDU4NTQ0LCA1ODU4NCwKKzU4NjI0LCA1ODY2NCwgNTg3MDQsIDU4NzQ0LCA1ODc4NCwgNTg4MjQsIDU4ODY0LCA1ODkwNCwgNTg5NDQsIDU4OTg0LCA1OTAyNCwgNTkwNjQsIDU5MTA0LCA1OTE0NCwgNTkxODQsIDU5MjI0LAorNTkyNjQsIDU5MzA0LCA1OTM0NCwgNTkzODQsIDU5NDI0LCA1OTQ2NCwgNTk1MDQsIDU5NTQ0LCA1OTU4NCwgNTk2MjQsIDU5NjY0LCA1OTcwNCwgNTk3NDQsIDU5Nzg0LCA1OTgyNCwgNTk4NjQsCis1OTkwNCwgNTk5NDQsIDU5OTg0LCA2MDAyNCwgNjAwNjQsIDYwMTA0LCA2MDE0NCwgNjAxODQsIDYwMjI0LCA2MDI2NCwgNjAzMDQsIDYwMzQ0LCA2MDM4NCwgNjA0MjQsIDYwNDY0LCA2MDUwNCwKKzYwNTQ0LCA2MDU4NCwgNjA2MjQsIDYwNjY0LCA2MDcwNCwgNjA3NDQsIDYwNzg0LCA2MDgyNCwgNjA4NjQsIDYwOTA0LCA2MDk0NCwgNjA5ODQsIDYxMDI0LCA2MTA2NCwgNjExMDQsIDYxMTQ0LAorNjExODQsIDYxMjI0LCA2MTI2NCwgNjEzMDQsIDYxMzQ0LCA2MTM4NCwgNjE0MjQsIDYxNDY0LCA2MTUwNCwgNjE1NDQsIDYxNTg0LCA2MTYyNCwgNjE2NjQsIDYxNzA0LCA2MTc0NCwgNjE3ODQsCis2MTgyNCwgNjE4NjQsIDYxOTA0LCA2MTk0NCwgNjE5ODQsIDYyMDI0LCA2MjA2NCwgNjIxMDQsIDYyMTQ0LCA2MjE4NCwgNjIyMjQsIDYyMjY0LCA2MjMwNCwgNjIzNDQsIDYyMzg0LCA2MjQyNCwKKzYyNDY0LCA2MjUwNCwgNjI1NDQsIDYyNTg0LCA2MjYyNCwgNjI2NjQsIDYyNzA0LCA2Mjc0NCwgNjI3ODQsIDYyODI0LCA2Mjg2NCwgNjI5MDQsIDYyOTQ0LCA2Mjk4NCwgNjMwMjQsIDYzMDY0LAorNjMxMDQsIDYzMTQ0LCA2MzE4NCwgNjMyMjQsIDYzMjY0LCA2MzMwNCwgNjMzNDQsIDYzMzg0LCA2MzQyNCwgNjM0NjQsIDYzNTA0LCA2MzU0NCwgNjM1ODQsIDYzNjI0LCA2MzY2NCwgNjM3MDQsCis2Mzc0NCwgNjM3ODQsIDYzODI0LCA2Mzg2NCwgNjM5MDQsIDYzOTQ0LCA2Mzk4NCwgNjQwMjQsIDY0MDY0LCA2NDEwNCwgNjQxNDQsIDY0MTg0LCA2NDIyNCwgNjQyNjQsIDY0MzA0LCA2NDM0NCwKKzY0Mzg0LCA2NDQyNCwgNjQ0NjQsIDY0NTA0LCA2NDU0NCwgNjQ1ODQsIDY0NjI0LCA2NDY2NCwgNjQ3MDQsIDY0NzQ0LCA2NDc4NCwgNjQ4MjQsIDY0ODY0LCA2NDkwNCwgNjQ5NDQsIDY0OTg0LAorNjUwMjQsIDY1MDY0LCA2NTEwNCwgNjUxNDQsIDY1MTg0LCA2NTIyNCwgNjUyNjQsIDY1MzA0LCA2NTM0NCwgNjUzODQsIDY1NDI0LCA2NTQ2NCwgNjU1MDQKKyAgICAgICAgICAgIH0pOworCisgICAgICAgIHRlc3RCeXRlcyA9IHRoZXNlQnl0ZXMobmV3IGludFtdeworMjU1LCAyNTQsIDMyLCAwLCAzMywgMCwgMzQsIDAsIDM1LCAwLCAzNiwgMCwgMzcsIDAsIDM4LCAwLAorMzksIDAsIDQwLCAwLCA0MSwgMCwgNDIsIDAsIDQzLCAwLCA0NCwgMCwgNDUsIDAsIDQ2LCAwLAorNDcsIDAsIDQ4LCAwLCA0OSwgMCwgNTAsIDAsIDUxLCAwLCA1MiwgMCwgNTMsIDAsIDU0LCAwLAorNTUsIDAsIDU2LCAwLCA1NywgMCwgNTgsIDAsIDU5LCAwLCA2MCwgMCwgNjEsIDAsIDYyLCAwLAorNjMsIDAsIDY0LCAwLCA2NSwgMCwgNjYsIDAsIDY3LCAwLCA2OCwgMCwgNjksIDAsIDcwLCAwLAorNzEsIDAsIDcyLCAwLCA3MywgMCwgNzQsIDAsIDc1LCAwLCA3NiwgMCwgNzcsIDAsIDc4LCAwLAorNzksIDAsIDgwLCAwLCA4MSwgMCwgODIsIDAsIDgzLCAwLCA4NCwgMCwgODUsIDAsIDg2LCAwLAorODcsIDAsIDg4LCAwLCA4OSwgMCwgOTAsIDAsIDkxLCAwLCA5MiwgMCwgOTMsIDAsIDk0LCAwLAorOTUsIDAsIDk2LCAwLCA5NywgMCwgOTgsIDAsIDk5LCAwLCAxMDAsIDAsIDEwMSwgMCwgMTAyLCAwLAorMTAzLCAwLCAxMDQsIDAsIDEwNSwgMCwgMTA2LCAwLCAxMDcsIDAsIDEwOCwgMCwgMTA5LCAwLCAxMTAsIDAsCisxMTEsIDAsIDExMiwgMCwgMTEzLCAwLCAxMTQsIDAsIDExNSwgMCwgMTE2LCAwLCAxMTcsIDAsIDExOCwgMCwKKzExOSwgMCwgMTIwLCAwLCAxMjEsIDAsIDEyMiwgMCwgMTIzLCAwLCAxMjQsIDAsIDEyNSwgMCwgMTI2LCAwLAorMTI3LCAwLCAxMjgsIDAsIDEyOSwgMCwgMTMwLCAwLCAxMzEsIDAsIDEzMiwgMCwgMTMzLCAwLCAxMzQsIDAsCisxMzUsIDAsIDEzNiwgMCwgMTM3LCAwLCAxMzgsIDAsIDEzOSwgMCwgMTQwLCAwLCAxNDEsIDAsIDE0MiwgMCwKKzE0MywgMCwgMTQ0LCAwLCAxNDUsIDAsIDE0NiwgMCwgMTQ3LCAwLCAxNDgsIDAsIDE0OSwgMCwgMTUwLCAwLAorMTUxLCAwLCAxNTIsIDAsIDE1MywgMCwgMTU0LCAwLCAxNTUsIDAsIDE1NiwgMCwgMTU3LCAwLCAxNTgsIDAsCisxNTksIDAsIDE2MCwgMCwgMTYxLCAwLCAxNjIsIDAsIDE2MywgMCwgMTY0LCAwLCAxNjUsIDAsIDE2NiwgMCwKKzE2NywgMCwgMTY4LCAwLCAxNjksIDAsIDE3MCwgMCwgMTcxLCAwLCAxNzIsIDAsIDE3MywgMCwgMTc0LCAwLAorMTc1LCAwLCAxNzYsIDAsIDE3NywgMCwgMTc4LCAwLCAxNzksIDAsIDE4MCwgMCwgMTgxLCAwLCAxODIsIDAsCisxODMsIDAsIDE4NCwgMCwgMTg1LCAwLCAxODYsIDAsIDE4NywgMCwgMTg4LCAwLCAxODksIDAsIDE5MCwgMCwKKzE5MSwgMCwgMTkyLCAwLCAxOTMsIDAsIDE5NCwgMCwgMTk1LCAwLCAxOTYsIDAsIDE5NywgMCwgMTk4LCAwLAorMTk5LCAwLCAyMDAsIDAsIDIwMSwgMCwgMjAyLCAwLCAyMDMsIDAsIDIwNCwgMCwgMjA1LCAwLCAyMDYsIDAsCisyMDcsIDAsIDIwOCwgMCwgMjA5LCAwLCAyMTAsIDAsIDIxMSwgMCwgMjEyLCAwLCAyMTMsIDAsIDIxNCwgMCwKKzIxNSwgMCwgMjE2LCAwLCAyMTcsIDAsIDIxOCwgMCwgMjE5LCAwLCAyMjAsIDAsIDIyMSwgMCwgMjIyLCAwLAorMjIzLCAwLCAyMjQsIDAsIDIyNSwgMCwgMjI2LCAwLCAyMjcsIDAsIDIyOCwgMCwgMjI5LCAwLCAyMzAsIDAsCisyMzEsIDAsIDIzMiwgMCwgMjMzLCAwLCAyMzQsIDAsIDIzNSwgMCwgMjM2LCAwLCAyMzcsIDAsIDIzOCwgMCwKKzIzOSwgMCwgMjQwLCAwLCAyNDEsIDAsIDI0MiwgMCwgMjQzLCAwLCAyNDQsIDAsIDI0NSwgMCwgMjQ2LCAwLAorMjQ3LCAwLCAyNDgsIDAsIDI0OSwgMCwgMjUwLCAwLCAyNTEsIDAsIDI1MiwgMCwgMjUzLCAwLCAyNTQsIDAsCisyNTUsIDAsIDAsIDEsIDQwLCAxLCA4MCwgMSwgMTIwLCAxLCAxNjAsIDEsIDIwMCwgMSwgMjQwLCAxLAorMjQsIDIsIDY0LCAyLCAxMDQsIDIsIDE0NCwgMiwgMTg0LCAyLCAyMjQsIDIsIDgsIDMsIDQ4LCAzLAorODgsIDMsIDEyOCwgMywgMTY4LCAzLCAyMDgsIDMsIDI0OCwgMywgMzIsIDQsIDcyLCA0LCAxMTIsIDQsCisxNTIsIDQsIDE5MiwgNCwgMjMyLCA0LCAxNiwgNSwgNTYsIDUsIDk2LCA1LCAxMzYsIDUsIDE3NiwgNSwKKzIxNiwgNSwgMCwgNiwgNDAsIDYsIDgwLCA2LCAxMjAsIDYsIDE2MCwgNiwgMjAwLCA2LCAyNDAsIDYsCisyNCwgNywgNjQsIDcsIDEwNCwgNywgMTQ0LCA3LCAxODQsIDcsIDIyNCwgNywgOCwgOCwgNDgsIDgsCis4OCwgOCwgMTI4LCA4LCAxNjgsIDgsIDIwOCwgOCwgMjQ4LCA4LCAzMiwgOSwgNzIsIDksIDExMiwgOSwKKzE1MiwgOSwgMTkyLCA5LCAyMzIsIDksIDE2LCAxMCwgNTYsIDEwLCA5NiwgMTAsIDEzNiwgMTAsIDE3NiwgMTAsCisyMTYsIDEwLCAwLCAxMSwgNDAsIDExLCA4MCwgMTEsIDEyMCwgMTEsIDE2MCwgMTEsIDIwMCwgMTEsIDI0MCwgMTEsCisyNCwgMTIsIDY0LCAxMiwgMTA0LCAxMiwgMTQ0LCAxMiwgMTg0LCAxMiwgMjI0LCAxMiwgOCwgMTMsIDQ4LCAxMywKKzg4LCAxMywgMTI4LCAxMywgMTY4LCAxMywgMjA4LCAxMywgMjQ4LCAxMywgMzIsIDE0LCA3MiwgMTQsIDExMiwgMTQsCisxNTIsIDE0LCAxOTIsIDE0LCAyMzIsIDE0LCAxNiwgMTUsIDU2LCAxNSwgOTYsIDE1LCAxMzYsIDE1LCAxNzYsIDE1LAorMjE2LCAxNSwgMCwgMTYsIDQwLCAxNiwgODAsIDE2LCAxMjAsIDE2LCAxNjAsIDE2LCAyMDAsIDE2LCAyNDAsIDE2LAorMjQsIDE3LCA2NCwgMTcsIDEwNCwgMTcsIDE0NCwgMTcsIDE4NCwgMTcsIDIyNCwgMTcsIDgsIDE4LCA0OCwgMTgsCis4OCwgMTgsIDEyOCwgMTgsIDE2OCwgMTgsIDIwOCwgMTgsIDI0OCwgMTgsIDMyLCAxOSwgNzIsIDE5LCAxMTIsIDE5LAorMTUyLCAxOSwgMTkyLCAxOSwgMjMyLCAxOSwgMTYsIDIwLCA1NiwgMjAsIDk2LCAyMCwgMTM2LCAyMCwgMTc2LCAyMCwKKzIxNiwgMjAsIDAsIDIxLCA0MCwgMjEsIDgwLCAyMSwgMTIwLCAyMSwgMTYwLCAyMSwgMjAwLCAyMSwgMjQwLCAyMSwKKzI0LCAyMiwgNjQsIDIyLCAxMDQsIDIyLCAxNDQsIDIyLCAxODQsIDIyLCAyMjQsIDIyLCA4LCAyMywgNDgsIDIzLAorODgsIDIzLCAxMjgsIDIzLCAxNjgsIDIzLCAyMDgsIDIzLCAyNDgsIDIzLCAzMiwgMjQsIDcyLCAyNCwgMTEyLCAyNCwKKzE1MiwgMjQsIDE5MiwgMjQsIDIzMiwgMjQsIDE2LCAyNSwgNTYsIDI1LCA5NiwgMjUsIDEzNiwgMjUsIDE3NiwgMjUsCisyMTYsIDI1LCAwLCAyNiwgNDAsIDI2LCA4MCwgMjYsIDEyMCwgMjYsIDE2MCwgMjYsIDIwMCwgMjYsIDI0MCwgMjYsCisyNCwgMjcsIDY0LCAyNywgMTA0LCAyNywgMTQ0LCAyNywgMTg0LCAyNywgMjI0LCAyNywgOCwgMjgsIDQ4LCAyOCwKKzg4LCAyOCwgMTI4LCAyOCwgMTY4LCAyOCwgMjA4LCAyOCwgMjQ4LCAyOCwgMzIsIDI5LCA3MiwgMjksIDExMiwgMjksCisxNTIsIDI5LCAxOTIsIDI5LCAyMzIsIDI5LCAxNiwgMzAsIDU2LCAzMCwgOTYsIDMwLCAxMzYsIDMwLCAxNzYsIDMwLAorMjE2LCAzMCwgMCwgMzEsIDQwLCAzMSwgODAsIDMxLCAxMjAsIDMxLCAxNjAsIDMxLCAyMDAsIDMxLCAyNDAsIDMxLAorMjQsIDMyLCA2NCwgMzIsIDEwNCwgMzIsIDE0NCwgMzIsIDE4NCwgMzIsIDIyNCwgMzIsIDgsIDMzLCA0OCwgMzMsCis4OCwgMzMsIDEyOCwgMzMsIDE2OCwgMzMsIDIwOCwgMzMsIDI0OCwgMzMsIDMyLCAzNCwgNzIsIDM0LCAxMTIsIDM0LAorMTUyLCAzNCwgMTkyLCAzNCwgMjMyLCAzNCwgMTYsIDM1LCA1NiwgMzUsIDk2LCAzNSwgMTM2LCAzNSwgMTc2LCAzNSwKKzIxNiwgMzUsIDAsIDM2LCA0MCwgMzYsIDgwLCAzNiwgMTIwLCAzNiwgMTYwLCAzNiwgMjAwLCAzNiwgMjQwLCAzNiwKKzI0LCAzNywgNjQsIDM3LCAxMDQsIDM3LCAxNDQsIDM3LCAxODQsIDM3LCAyMjQsIDM3LCA4LCAzOCwgNDgsIDM4LAorODgsIDM4LCAxMjgsIDM4LCAxNjgsIDM4LCAyMDgsIDM4LCAyNDgsIDM4LCAzMiwgMzksIDcyLCAzOSwgMTEyLCAzOSwKKzE1MiwgMzksIDE5MiwgMzksIDIzMiwgMzksIDE2LCA0MCwgNTYsIDQwLCA5NiwgNDAsIDEzNiwgNDAsIDE3NiwgNDAsCisyMTYsIDQwLCAwLCA0MSwgNDAsIDQxLCA4MCwgNDEsIDEyMCwgNDEsIDE2MCwgNDEsIDIwMCwgNDEsIDI0MCwgNDEsCisyNCwgNDIsIDY0LCA0MiwgMTA0LCA0MiwgMTQ0LCA0MiwgMTg0LCA0MiwgMjI0LCA0MiwgOCwgNDMsIDQ4LCA0MywKKzg4LCA0MywgMTI4LCA0MywgMTY4LCA0MywgMjA4LCA0MywgMjQ4LCA0MywgMzIsIDQ0LCA3MiwgNDQsIDExMiwgNDQsCisxNTIsIDQ0LCAxOTIsIDQ0LCAyMzIsIDQ0LCAxNiwgNDUsIDU2LCA0NSwgOTYsIDQ1LCAxMzYsIDQ1LCAxNzYsIDQ1LAorMjE2LCA0NSwgMCwgNDYsIDQwLCA0NiwgODAsIDQ2LCAxMjAsIDQ2LCAxNjAsIDQ2LCAyMDAsIDQ2LCAyNDAsIDQ2LAorMjQsIDQ3LCA2NCwgNDcsIDEwNCwgNDcsIDE0NCwgNDcsIDE4NCwgNDcsIDIyNCwgNDcsIDgsIDQ4LCA0OCwgNDgsCis4OCwgNDgsIDEyOCwgNDgsIDE2OCwgNDgsIDIwOCwgNDgsIDI0OCwgNDgsIDMyLCA0OSwgNzIsIDQ5LCAxMTIsIDQ5LAorMTUyLCA0OSwgMTkyLCA0OSwgMjMyLCA0OSwgMTYsIDUwLCA1NiwgNTAsIDk2LCA1MCwgMTM2LCA1MCwgMTc2LCA1MCwKKzIxNiwgNTAsIDAsIDUxLCA0MCwgNTEsIDgwLCA1MSwgMTIwLCA1MSwgMTYwLCA1MSwgMjAwLCA1MSwgMjQwLCA1MSwKKzI0LCA1MiwgNjQsIDUyLCAxMDQsIDUyLCAxNDQsIDUyLCAxODQsIDUyLCAyMjQsIDUyLCA4LCA1MywgNDgsIDUzLAorODgsIDUzLCAxMjgsIDUzLCAxNjgsIDUzLCAyMDgsIDUzLCAyNDgsIDUzLCAzMiwgNTQsIDcyLCA1NCwgMTEyLCA1NCwKKzE1MiwgNTQsIDE5MiwgNTQsIDIzMiwgNTQsIDE2LCA1NSwgNTYsIDU1LCA5NiwgNTUsIDEzNiwgNTUsIDE3NiwgNTUsCisyMTYsIDU1LCAwLCA1NiwgNDAsIDU2LCA4MCwgNTYsIDEyMCwgNTYsIDE2MCwgNTYsIDIwMCwgNTYsIDI0MCwgNTYsCisyNCwgNTcsIDY0LCA1NywgMTA0LCA1NywgMTQ0LCA1NywgMTg0LCA1NywgMjI0LCA1NywgOCwgNTgsIDQ4LCA1OCwKKzg4LCA1OCwgMTI4LCA1OCwgMTY4LCA1OCwgMjA4LCA1OCwgMjQ4LCA1OCwgMzIsIDU5LCA3MiwgNTksIDExMiwgNTksCisxNTIsIDU5LCAxOTIsIDU5LCAyMzIsIDU5LCAxNiwgNjAsIDU2LCA2MCwgOTYsIDYwLCAxMzYsIDYwLCAxNzYsIDYwLAorMjE2LCA2MCwgMCwgNjEsIDQwLCA2MSwgODAsIDYxLCAxMjAsIDYxLCAxNjAsIDYxLCAyMDAsIDYxLCAyNDAsIDYxLAorMjQsIDYyLCA2NCwgNjIsIDEwNCwgNjIsIDE0NCwgNjIsIDE4NCwgNjIsIDIyNCwgNjIsIDgsIDYzLCA0OCwgNjMsCis4OCwgNjMsIDEyOCwgNjMsIDE2OCwgNjMsIDIwOCwgNjMsIDI0OCwgNjMsIDMyLCA2NCwgNzIsIDY0LCAxMTIsIDY0LAorMTUyLCA2NCwgMTkyLCA2NCwgMjMyLCA2NCwgMTYsIDY1LCA1NiwgNjUsIDk2LCA2NSwgMTM2LCA2NSwgMTc2LCA2NSwKKzIxNiwgNjUsIDAsIDY2LCA0MCwgNjYsIDgwLCA2NiwgMTIwLCA2NiwgMTYwLCA2NiwgMjAwLCA2NiwgMjQwLCA2NiwKKzI0LCA2NywgNjQsIDY3LCAxMDQsIDY3LCAxNDQsIDY3LCAxODQsIDY3LCAyMjQsIDY3LCA4LCA2OCwgNDgsIDY4LAorODgsIDY4LCAxMjgsIDY4LCAxNjgsIDY4LCAyMDgsIDY4LCAyNDgsIDY4LCAzMiwgNjksIDcyLCA2OSwgMTEyLCA2OSwKKzE1MiwgNjksIDE5MiwgNjksIDIzMiwgNjksIDE2LCA3MCwgNTYsIDcwLCA5NiwgNzAsIDEzNiwgNzAsIDE3NiwgNzAsCisyMTYsIDcwLCAwLCA3MSwgNDAsIDcxLCA4MCwgNzEsIDEyMCwgNzEsIDE2MCwgNzEsIDIwMCwgNzEsIDI0MCwgNzEsCisyNCwgNzIsIDY0LCA3MiwgMTA0LCA3MiwgMTQ0LCA3MiwgMTg0LCA3MiwgMjI0LCA3MiwgOCwgNzMsIDQ4LCA3MywKKzg4LCA3MywgMTI4LCA3MywgMTY4LCA3MywgMjA4LCA3MywgMjQ4LCA3MywgMzIsIDc0LCA3MiwgNzQsIDExMiwgNzQsCisxNTIsIDc0LCAxOTIsIDc0LCAyMzIsIDc0LCAxNiwgNzUsIDU2LCA3NSwgOTYsIDc1LCAxMzYsIDc1LCAxNzYsIDc1LAorMjE2LCA3NSwgMCwgNzYsIDQwLCA3NiwgODAsIDc2LCAxMjAsIDc2LCAxNjAsIDc2LCAyMDAsIDc2LCAyNDAsIDc2LAorMjQsIDc3LCA2NCwgNzcsIDEwNCwgNzcsIDE0NCwgNzcsIDE4NCwgNzcsIDIyNCwgNzcsIDgsIDc4LCA0OCwgNzgsCis4OCwgNzgsIDEyOCwgNzgsIDE2OCwgNzgsIDIwOCwgNzgsIDI0OCwgNzgsIDMyLCA3OSwgNzIsIDc5LCAxMTIsIDc5LAorMTUyLCA3OSwgMTkyLCA3OSwgMjMyLCA3OSwgMTYsIDgwLCA1NiwgODAsIDk2LCA4MCwgMTM2LCA4MCwgMTc2LCA4MCwKKzIxNiwgODAsIDAsIDgxLCA0MCwgODEsIDgwLCA4MSwgMTIwLCA4MSwgMTYwLCA4MSwgMjAwLCA4MSwgMjQwLCA4MSwKKzI0LCA4MiwgNjQsIDgyLCAxMDQsIDgyLCAxNDQsIDgyLCAxODQsIDgyLCAyMjQsIDgyLCA4LCA4MywgNDgsIDgzLAorODgsIDgzLCAxMjgsIDgzLCAxNjgsIDgzLCAyMDgsIDgzLCAyNDgsIDgzLCAzMiwgODQsIDcyLCA4NCwgMTEyLCA4NCwKKzE1MiwgODQsIDE5MiwgODQsIDIzMiwgODQsIDE2LCA4NSwgNTYsIDg1LCA5NiwgODUsIDEzNiwgODUsIDE3NiwgODUsCisyMTYsIDg1LCAwLCA4NiwgNDAsIDg2LCA4MCwgODYsIDEyMCwgODYsIDE2MCwgODYsIDIwMCwgODYsIDI0MCwgODYsCisyNCwgODcsIDY0LCA4NywgMTA0LCA4NywgMTQ0LCA4NywgMTg0LCA4NywgMjI0LCA4NywgOCwgODgsIDQ4LCA4OCwKKzg4LCA4OCwgMTI4LCA4OCwgMTY4LCA4OCwgMjA4LCA4OCwgMjQ4LCA4OCwgMzIsIDg5LCA3MiwgODksIDExMiwgODksCisxNTIsIDg5LCAxOTIsIDg5LCAyMzIsIDg5LCAxNiwgOTAsIDU2LCA5MCwgOTYsIDkwLCAxMzYsIDkwLCAxNzYsIDkwLAorMjE2LCA5MCwgMCwgOTEsIDQwLCA5MSwgODAsIDkxLCAxMjAsIDkxLCAxNjAsIDkxLCAyMDAsIDkxLCAyNDAsIDkxLAorMjQsIDkyLCA2NCwgOTIsIDEwNCwgOTIsIDE0NCwgOTIsIDE4NCwgOTIsIDIyNCwgOTIsIDgsIDkzLCA0OCwgOTMsCis4OCwgOTMsIDEyOCwgOTMsIDE2OCwgOTMsIDIwOCwgOTMsIDI0OCwgOTMsIDMyLCA5NCwgNzIsIDk0LCAxMTIsIDk0LAorMTUyLCA5NCwgMTkyLCA5NCwgMjMyLCA5NCwgMTYsIDk1LCA1NiwgOTUsIDk2LCA5NSwgMTM2LCA5NSwgMTc2LCA5NSwKKzIxNiwgOTUsIDAsIDk2LCA0MCwgOTYsIDgwLCA5NiwgMTIwLCA5NiwgMTYwLCA5NiwgMjAwLCA5NiwgMjQwLCA5NiwKKzI0LCA5NywgNjQsIDk3LCAxMDQsIDk3LCAxNDQsIDk3LCAxODQsIDk3LCAyMjQsIDk3LCA4LCA5OCwgNDgsIDk4LAorODgsIDk4LCAxMjgsIDk4LCAxNjgsIDk4LCAyMDgsIDk4LCAyNDgsIDk4LCAzMiwgOTksIDcyLCA5OSwgMTEyLCA5OSwKKzE1MiwgOTksIDE5MiwgOTksIDIzMiwgOTksIDE2LCAxMDAsIDU2LCAxMDAsIDk2LCAxMDAsIDEzNiwgMTAwLCAxNzYsIDEwMCwKKzIxNiwgMTAwLCAwLCAxMDEsIDQwLCAxMDEsIDgwLCAxMDEsIDEyMCwgMTAxLCAxNjAsIDEwMSwgMjAwLCAxMDEsIDI0MCwgMTAxLAorMjQsIDEwMiwgNjQsIDEwMiwgMTA0LCAxMDIsIDE0NCwgMTAyLCAxODQsIDEwMiwgMjI0LCAxMDIsIDgsIDEwMywgNDgsIDEwMywKKzg4LCAxMDMsIDEyOCwgMTAzLCAxNjgsIDEwMywgMjA4LCAxMDMsIDI0OCwgMTAzLCAzMiwgMTA0LCA3MiwgMTA0LCAxMTIsIDEwNCwKKzE1MiwgMTA0LCAxOTIsIDEwNCwgMjMyLCAxMDQsIDE2LCAxMDUsIDU2LCAxMDUsIDk2LCAxMDUsIDEzNiwgMTA1LCAxNzYsIDEwNSwKKzIxNiwgMTA1LCAwLCAxMDYsIDQwLCAxMDYsIDgwLCAxMDYsIDEyMCwgMTA2LCAxNjAsIDEwNiwgMjAwLCAxMDYsIDI0MCwgMTA2LAorMjQsIDEwNywgNjQsIDEwNywgMTA0LCAxMDcsIDE0NCwgMTA3LCAxODQsIDEwNywgMjI0LCAxMDcsIDgsIDEwOCwgNDgsIDEwOCwKKzg4LCAxMDgsIDEyOCwgMTA4LCAxNjgsIDEwOCwgMjA4LCAxMDgsIDI0OCwgMTA4LCAzMiwgMTA5LCA3MiwgMTA5LCAxMTIsIDEwOSwKKzE1MiwgMTA5LCAxOTIsIDEwOSwgMjMyLCAxMDksIDE2LCAxMTAsIDU2LCAxMTAsIDk2LCAxMTAsIDEzNiwgMTEwLCAxNzYsIDExMCwKKzIxNiwgMTEwLCAwLCAxMTEsIDQwLCAxMTEsIDgwLCAxMTEsIDEyMCwgMTExLCAxNjAsIDExMSwgMjAwLCAxMTEsIDI0MCwgMTExLAorMjQsIDExMiwgNjQsIDExMiwgMTA0LCAxMTIsIDE0NCwgMTEyLCAxODQsIDExMiwgMjI0LCAxMTIsIDgsIDExMywgNDgsIDExMywKKzg4LCAxMTMsIDEyOCwgMTEzLCAxNjgsIDExMywgMjA4LCAxMTMsIDI0OCwgMTEzLCAzMiwgMTE0LCA3MiwgMTE0LCAxMTIsIDExNCwKKzE1MiwgMTE0LCAxOTIsIDExNCwgMjMyLCAxMTQsIDE2LCAxMTUsIDU2LCAxMTUsIDk2LCAxMTUsIDEzNiwgMTE1LCAxNzYsIDExNSwKKzIxNiwgMTE1LCAwLCAxMTYsIDQwLCAxMTYsIDgwLCAxMTYsIDEyMCwgMTE2LCAxNjAsIDExNiwgMjAwLCAxMTYsIDI0MCwgMTE2LAorMjQsIDExNywgNjQsIDExNywgMTA0LCAxMTcsIDE0NCwgMTE3LCAxODQsIDExNywgMjI0LCAxMTcsIDgsIDExOCwgNDgsIDExOCwKKzg4LCAxMTgsIDEyOCwgMTE4LCAxNjgsIDExOCwgMjA4LCAxMTgsIDI0OCwgMTE4LCAzMiwgMTE5LCA3MiwgMTE5LCAxMTIsIDExOSwKKzE1MiwgMTE5LCAxOTIsIDExOSwgMjMyLCAxMTksIDE2LCAxMjAsIDU2LCAxMjAsIDk2LCAxMjAsIDEzNiwgMTIwLCAxNzYsIDEyMCwKKzIxNiwgMTIwLCAwLCAxMjEsIDQwLCAxMjEsIDgwLCAxMjEsIDEyMCwgMTIxLCAxNjAsIDEyMSwgMjAwLCAxMjEsIDI0MCwgMTIxLAorMjQsIDEyMiwgNjQsIDEyMiwgMTA0LCAxMjIsIDE0NCwgMTIyLCAxODQsIDEyMiwgMjI0LCAxMjIsIDgsIDEyMywgNDgsIDEyMywKKzg4LCAxMjMsIDEyOCwgMTIzLCAxNjgsIDEyMywgMjA4LCAxMjMsIDI0OCwgMTIzLCAzMiwgMTI0LCA3MiwgMTI0LCAxMTIsIDEyNCwKKzE1MiwgMTI0LCAxOTIsIDEyNCwgMjMyLCAxMjQsIDE2LCAxMjUsIDU2LCAxMjUsIDk2LCAxMjUsIDEzNiwgMTI1LCAxNzYsIDEyNSwKKzIxNiwgMTI1LCAwLCAxMjYsIDQwLCAxMjYsIDgwLCAxMjYsIDEyMCwgMTI2LCAxNjAsIDEyNiwgMjAwLCAxMjYsIDI0MCwgMTI2LAorMjQsIDEyNywgNjQsIDEyNywgMTA0LCAxMjcsIDE0NCwgMTI3LCAxODQsIDEyNywgMjI0LCAxMjcsIDgsIDEyOCwgNDgsIDEyOCwKKzg4LCAxMjgsIDEyOCwgMTI4LCAxNjgsIDEyOCwgMjA4LCAxMjgsIDI0OCwgMTI4LCAzMiwgMTI5LCA3MiwgMTI5LCAxMTIsIDEyOSwKKzE1MiwgMTI5LCAxOTIsIDEyOSwgMjMyLCAxMjksIDE2LCAxMzAsIDU2LCAxMzAsIDk2LCAxMzAsIDEzNiwgMTMwLCAxNzYsIDEzMCwKKzIxNiwgMTMwLCAwLCAxMzEsIDQwLCAxMzEsIDgwLCAxMzEsIDEyMCwgMTMxLCAxNjAsIDEzMSwgMjAwLCAxMzEsIDI0MCwgMTMxLAorMjQsIDEzMiwgNjQsIDEzMiwgMTA0LCAxMzIsIDE0NCwgMTMyLCAxODQsIDEzMiwgMjI0LCAxMzIsIDgsIDEzMywgNDgsIDEzMywKKzg4LCAxMzMsIDEyOCwgMTMzLCAxNjgsIDEzMywgMjA4LCAxMzMsIDI0OCwgMTMzLCAzMiwgMTM0LCA3MiwgMTM0LCAxMTIsIDEzNCwKKzE1MiwgMTM0LCAxOTIsIDEzNCwgMjMyLCAxMzQsIDE2LCAxMzUsIDU2LCAxMzUsIDk2LCAxMzUsIDEzNiwgMTM1LCAxNzYsIDEzNSwKKzIxNiwgMTM1LCAwLCAxMzYsIDQwLCAxMzYsIDgwLCAxMzYsIDEyMCwgMTM2LCAxNjAsIDEzNiwgMjAwLCAxMzYsIDI0MCwgMTM2LAorMjQsIDEzNywgNjQsIDEzNywgMTA0LCAxMzcsIDE0NCwgMTM3LCAxODQsIDEzNywgMjI0LCAxMzcsIDgsIDEzOCwgNDgsIDEzOCwKKzg4LCAxMzgsIDEyOCwgMTM4LCAxNjgsIDEzOCwgMjA4LCAxMzgsIDI0OCwgMTM4LCAzMiwgMTM5LCA3MiwgMTM5LCAxMTIsIDEzOSwKKzE1MiwgMTM5LCAxOTIsIDEzOSwgMjMyLCAxMzksIDE2LCAxNDAsIDU2LCAxNDAsIDk2LCAxNDAsIDEzNiwgMTQwLCAxNzYsIDE0MCwKKzIxNiwgMTQwLCAwLCAxNDEsIDQwLCAxNDEsIDgwLCAxNDEsIDEyMCwgMTQxLCAxNjAsIDE0MSwgMjAwLCAxNDEsIDI0MCwgMTQxLAorMjQsIDE0MiwgNjQsIDE0MiwgMTA0LCAxNDIsIDE0NCwgMTQyLCAxODQsIDE0MiwgMjI0LCAxNDIsIDgsIDE0MywgNDgsIDE0MywKKzg4LCAxNDMsIDEyOCwgMTQzLCAxNjgsIDE0MywgMjA4LCAxNDMsIDI0OCwgMTQzLCAzMiwgMTQ0LCA3MiwgMTQ0LCAxMTIsIDE0NCwKKzE1MiwgMTQ0LCAxOTIsIDE0NCwgMjMyLCAxNDQsIDE2LCAxNDUsIDU2LCAxNDUsIDk2LCAxNDUsIDEzNiwgMTQ1LCAxNzYsIDE0NSwKKzIxNiwgMTQ1LCAwLCAxNDYsIDQwLCAxNDYsIDgwLCAxNDYsIDEyMCwgMTQ2LCAxNjAsIDE0NiwgMjAwLCAxNDYsIDI0MCwgMTQ2LAorMjQsIDE0NywgNjQsIDE0NywgMTA0LCAxNDcsIDE0NCwgMTQ3LCAxODQsIDE0NywgMjI0LCAxNDcsIDgsIDE0OCwgNDgsIDE0OCwKKzg4LCAxNDgsIDEyOCwgMTQ4LCAxNjgsIDE0OCwgMjA4LCAxNDgsIDI0OCwgMTQ4LCAzMiwgMTQ5LCA3MiwgMTQ5LCAxMTIsIDE0OSwKKzE1MiwgMTQ5LCAxOTIsIDE0OSwgMjMyLCAxNDksIDE2LCAxNTAsIDU2LCAxNTAsIDk2LCAxNTAsIDEzNiwgMTUwLCAxNzYsIDE1MCwKKzIxNiwgMTUwLCAwLCAxNTEsIDQwLCAxNTEsIDgwLCAxNTEsIDEyMCwgMTUxLCAxNjAsIDE1MSwgMjAwLCAxNTEsIDI0MCwgMTUxLAorMjQsIDE1MiwgNjQsIDE1MiwgMTA0LCAxNTIsIDE0NCwgMTUyLCAxODQsIDE1MiwgMjI0LCAxNTIsIDgsIDE1MywgNDgsIDE1MywKKzg4LCAxNTMsIDEyOCwgMTUzLCAxNjgsIDE1MywgMjA4LCAxNTMsIDI0OCwgMTUzLCAzMiwgMTU0LCA3MiwgMTU0LCAxMTIsIDE1NCwKKzE1MiwgMTU0LCAxOTIsIDE1NCwgMjMyLCAxNTQsIDE2LCAxNTUsIDU2LCAxNTUsIDk2LCAxNTUsIDEzNiwgMTU1LCAxNzYsIDE1NSwKKzIxNiwgMTU1LCAwLCAxNTYsIDQwLCAxNTYsIDgwLCAxNTYsIDEyMCwgMTU2LCAxNjAsIDE1NiwgMjAwLCAxNTYsIDI0MCwgMTU2LAorMjQsIDE1NywgNjQsIDE1NywgMTA0LCAxNTcsIDE0NCwgMTU3LCAxODQsIDE1NywgMjI0LCAxNTcsIDgsIDE1OCwgNDgsIDE1OCwKKzg4LCAxNTgsIDEyOCwgMTU4LCAxNjgsIDE1OCwgMjA4LCAxNTgsIDI0OCwgMTU4LCAzMiwgMTU5LCA3MiwgMTU5LCAxMTIsIDE1OSwKKzE1MiwgMTU5LCAxOTIsIDE1OSwgMjMyLCAxNTksIDE2LCAxNjAsIDU2LCAxNjAsIDk2LCAxNjAsIDEzNiwgMTYwLCAxNzYsIDE2MCwKKzIxNiwgMTYwLCAwLCAxNjEsIDQwLCAxNjEsIDgwLCAxNjEsIDEyMCwgMTYxLCAxNjAsIDE2MSwgMjAwLCAxNjEsIDI0MCwgMTYxLAorMjQsIDE2MiwgNjQsIDE2MiwgMTA0LCAxNjIsIDE0NCwgMTYyLCAxODQsIDE2MiwgMjI0LCAxNjIsIDgsIDE2MywgNDgsIDE2MywKKzg4LCAxNjMsIDEyOCwgMTYzLCAxNjgsIDE2MywgMjA4LCAxNjMsIDI0OCwgMTYzLCAzMiwgMTY0LCA3MiwgMTY0LCAxMTIsIDE2NCwKKzE1MiwgMTY0LCAxOTIsIDE2NCwgMjMyLCAxNjQsIDE2LCAxNjUsIDU2LCAxNjUsIDk2LCAxNjUsIDEzNiwgMTY1LCAxNzYsIDE2NSwKKzIxNiwgMTY1LCAwLCAxNjYsIDQwLCAxNjYsIDgwLCAxNjYsIDEyMCwgMTY2LCAxNjAsIDE2NiwgMjAwLCAxNjYsIDI0MCwgMTY2LAorMjQsIDE2NywgNjQsIDE2NywgMTA0LCAxNjcsIDE0NCwgMTY3LCAxODQsIDE2NywgMjI0LCAxNjcsIDgsIDE2OCwgNDgsIDE2OCwKKzg4LCAxNjgsIDEyOCwgMTY4LCAxNjgsIDE2OCwgMjA4LCAxNjgsIDI0OCwgMTY4LCAzMiwgMTY5LCA3MiwgMTY5LCAxMTIsIDE2OSwKKzE1MiwgMTY5LCAxOTIsIDE2OSwgMjMyLCAxNjksIDE2LCAxNzAsIDU2LCAxNzAsIDk2LCAxNzAsIDEzNiwgMTcwLCAxNzYsIDE3MCwKKzIxNiwgMTcwLCAwLCAxNzEsIDQwLCAxNzEsIDgwLCAxNzEsIDEyMCwgMTcxLCAxNjAsIDE3MSwgMjAwLCAxNzEsIDI0MCwgMTcxLAorMjQsIDE3MiwgNjQsIDE3MiwgMTA0LCAxNzIsIDE0NCwgMTcyLCAxODQsIDE3MiwgMjI0LCAxNzIsIDgsIDE3MywgNDgsIDE3MywKKzg4LCAxNzMsIDEyOCwgMTczLCAxNjgsIDE3MywgMjA4LCAxNzMsIDI0OCwgMTczLCAzMiwgMTc0LCA3MiwgMTc0LCAxMTIsIDE3NCwKKzE1MiwgMTc0LCAxOTIsIDE3NCwgMjMyLCAxNzQsIDE2LCAxNzUsIDU2LCAxNzUsIDk2LCAxNzUsIDEzNiwgMTc1LCAxNzYsIDE3NSwKKzIxNiwgMTc1LCAwLCAxNzYsIDQwLCAxNzYsIDgwLCAxNzYsIDEyMCwgMTc2LCAxNjAsIDE3NiwgMjAwLCAxNzYsIDI0MCwgMTc2LAorMjQsIDE3NywgNjQsIDE3NywgMTA0LCAxNzcsIDE0NCwgMTc3LCAxODQsIDE3NywgMjI0LCAxNzcsIDgsIDE3OCwgNDgsIDE3OCwKKzg4LCAxNzgsIDEyOCwgMTc4LCAxNjgsIDE3OCwgMjA4LCAxNzgsIDI0OCwgMTc4LCAzMiwgMTc5LCA3MiwgMTc5LCAxMTIsIDE3OSwKKzE1MiwgMTc5LCAxOTIsIDE3OSwgMjMyLCAxNzksIDE2LCAxODAsIDU2LCAxODAsIDk2LCAxODAsIDEzNiwgMTgwLCAxNzYsIDE4MCwKKzIxNiwgMTgwLCAwLCAxODEsIDQwLCAxODEsIDgwLCAxODEsIDEyMCwgMTgxLCAxNjAsIDE4MSwgMjAwLCAxODEsIDI0MCwgMTgxLAorMjQsIDE4MiwgNjQsIDE4MiwgMTA0LCAxODIsIDE0NCwgMTgyLCAxODQsIDE4MiwgMjI0LCAxODIsIDgsIDE4MywgNDgsIDE4MywKKzg4LCAxODMsIDEyOCwgMTgzLCAxNjgsIDE4MywgMjA4LCAxODMsIDI0OCwgMTgzLCAzMiwgMTg0LCA3MiwgMTg0LCAxMTIsIDE4NCwKKzE1MiwgMTg0LCAxOTIsIDE4NCwgMjMyLCAxODQsIDE2LCAxODUsIDU2LCAxODUsIDk2LCAxODUsIDEzNiwgMTg1LCAxNzYsIDE4NSwKKzIxNiwgMTg1LCAwLCAxODYsIDQwLCAxODYsIDgwLCAxODYsIDEyMCwgMTg2LCAxNjAsIDE4NiwgMjAwLCAxODYsIDI0MCwgMTg2LAorMjQsIDE4NywgNjQsIDE4NywgMTA0LCAxODcsIDE0NCwgMTg3LCAxODQsIDE4NywgMjI0LCAxODcsIDgsIDE4OCwgNDgsIDE4OCwKKzg4LCAxODgsIDEyOCwgMTg4LCAxNjgsIDE4OCwgMjA4LCAxODgsIDI0OCwgMTg4LCAzMiwgMTg5LCA3MiwgMTg5LCAxMTIsIDE4OSwKKzE1MiwgMTg5LCAxOTIsIDE4OSwgMjMyLCAxODksIDE2LCAxOTAsIDU2LCAxOTAsIDk2LCAxOTAsIDEzNiwgMTkwLCAxNzYsIDE5MCwKKzIxNiwgMTkwLCAwLCAxOTEsIDQwLCAxOTEsIDgwLCAxOTEsIDEyMCwgMTkxLCAxNjAsIDE5MSwgMjAwLCAxOTEsIDI0MCwgMTkxLAorMjQsIDE5MiwgNjQsIDE5MiwgMTA0LCAxOTIsIDE0NCwgMTkyLCAxODQsIDE5MiwgMjI0LCAxOTIsIDgsIDE5MywgNDgsIDE5MywKKzg4LCAxOTMsIDEyOCwgMTkzLCAxNjgsIDE5MywgMjA4LCAxOTMsIDI0OCwgMTkzLCAzMiwgMTk0LCA3MiwgMTk0LCAxMTIsIDE5NCwKKzE1MiwgMTk0LCAxOTIsIDE5NCwgMjMyLCAxOTQsIDE2LCAxOTUsIDU2LCAxOTUsIDk2LCAxOTUsIDEzNiwgMTk1LCAxNzYsIDE5NSwKKzIxNiwgMTk1LCAwLCAxOTYsIDQwLCAxOTYsIDgwLCAxOTYsIDEyMCwgMTk2LCAxNjAsIDE5NiwgMjAwLCAxOTYsIDI0MCwgMTk2LAorMjQsIDE5NywgNjQsIDE5NywgMTA0LCAxOTcsIDE0NCwgMTk3LCAxODQsIDE5NywgMjI0LCAxOTcsIDgsIDE5OCwgNDgsIDE5OCwKKzg4LCAxOTgsIDEyOCwgMTk4LCAxNjgsIDE5OCwgMjA4LCAxOTgsIDI0OCwgMTk4LCAzMiwgMTk5LCA3MiwgMTk5LCAxMTIsIDE5OSwKKzE1MiwgMTk5LCAxOTIsIDE5OSwgMjMyLCAxOTksIDE2LCAyMDAsIDU2LCAyMDAsIDk2LCAyMDAsIDEzNiwgMjAwLCAxNzYsIDIwMCwKKzIxNiwgMjAwLCAwLCAyMDEsIDQwLCAyMDEsIDgwLCAyMDEsIDEyMCwgMjAxLCAxNjAsIDIwMSwgMjAwLCAyMDEsIDI0MCwgMjAxLAorMjQsIDIwMiwgNjQsIDIwMiwgMTA0LCAyMDIsIDE0NCwgMjAyLCAxODQsIDIwMiwgMjI0LCAyMDIsIDgsIDIwMywgNDgsIDIwMywKKzg4LCAyMDMsIDEyOCwgMjAzLCAxNjgsIDIwMywgMjA4LCAyMDMsIDI0OCwgMjAzLCAzMiwgMjA0LCA3MiwgMjA0LCAxMTIsIDIwNCwKKzE1MiwgMjA0LCAxOTIsIDIwNCwgMjMyLCAyMDQsIDE2LCAyMDUsIDU2LCAyMDUsIDk2LCAyMDUsIDEzNiwgMjA1LCAxNzYsIDIwNSwKKzIxNiwgMjA1LCAwLCAyMDYsIDQwLCAyMDYsIDgwLCAyMDYsIDEyMCwgMjA2LCAxNjAsIDIwNiwgMjAwLCAyMDYsIDI0MCwgMjA2LAorMjQsIDIwNywgNjQsIDIwNywgMTA0LCAyMDcsIDE0NCwgMjA3LCAxODQsIDIwNywgMjI0LCAyMDcsIDgsIDIwOCwgNDgsIDIwOCwKKzg4LCAyMDgsIDEyOCwgMjA4LCAxNjgsIDIwOCwgMjA4LCAyMDgsIDI0OCwgMjA4LCAzMiwgMjA5LCA3MiwgMjA5LCAxMTIsIDIwOSwKKzE1MiwgMjA5LCAxOTIsIDIwOSwgMjMyLCAyMDksIDE2LCAyMTAsIDU2LCAyMTAsIDk2LCAyMTAsIDEzNiwgMjEwLCAxNzYsIDIxMCwKKzIxNiwgMjEwLCAwLCAyMTEsIDQwLCAyMTEsIDgwLCAyMTEsIDEyMCwgMjExLCAxNjAsIDIxMSwgMjAwLCAyMTEsIDI0MCwgMjExLAorMjQsIDIxMiwgNjQsIDIxMiwgMTA0LCAyMTIsIDE0NCwgMjEyLCAxODQsIDIxMiwgMjI0LCAyMTIsIDgsIDIxMywgNDgsIDIxMywKKzg4LCAyMTMsIDEyOCwgMjEzLCAxNjgsIDIxMywgMjA4LCAyMTMsIDI0OCwgMjEzLCAzMiwgMjE0LCA3MiwgMjE0LCAxMTIsIDIxNCwKKzE1MiwgMjE0LCAxOTIsIDIxNCwgMjMyLCAyMTQsIDE2LCAyMTUsIDU2LCAyMTUsIDk2LCAyMTUsIDEzNiwgMjE1LCAxNzYsIDIxNSwKKzIxNiwgMjE1LCAwLCAyMjQsIDQwLCAyMjQsIDgwLCAyMjQsIDEyMCwgMjI0LCAxNjAsIDIyNCwgMjAwLCAyMjQsIDI0MCwgMjI0LAorMjQsIDIyNSwgNjQsIDIyNSwgMTA0LCAyMjUsIDE0NCwgMjI1LCAxODQsIDIyNSwgMjI0LCAyMjUsIDgsIDIyNiwgNDgsIDIyNiwKKzg4LCAyMjYsIDEyOCwgMjI2LCAxNjgsIDIyNiwgMjA4LCAyMjYsIDI0OCwgMjI2LCAzMiwgMjI3LCA3MiwgMjI3LCAxMTIsIDIyNywKKzE1MiwgMjI3LCAxOTIsIDIyNywgMjMyLCAyMjcsIDE2LCAyMjgsIDU2LCAyMjgsIDk2LCAyMjgsIDEzNiwgMjI4LCAxNzYsIDIyOCwKKzIxNiwgMjI4LCAwLCAyMjksIDQwLCAyMjksIDgwLCAyMjksIDEyMCwgMjI5LCAxNjAsIDIyOSwgMjAwLCAyMjksIDI0MCwgMjI5LAorMjQsIDIzMCwgNjQsIDIzMCwgMTA0LCAyMzAsIDE0NCwgMjMwLCAxODQsIDIzMCwgMjI0LCAyMzAsIDgsIDIzMSwgNDgsIDIzMSwKKzg4LCAyMzEsIDEyOCwgMjMxLCAxNjgsIDIzMSwgMjA4LCAyMzEsIDI0OCwgMjMxLCAzMiwgMjMyLCA3MiwgMjMyLCAxMTIsIDIzMiwKKzE1MiwgMjMyLCAxOTIsIDIzMiwgMjMyLCAyMzIsIDE2LCAyMzMsIDU2LCAyMzMsIDk2LCAyMzMsIDEzNiwgMjMzLCAxNzYsIDIzMywKKzIxNiwgMjMzLCAwLCAyMzQsIDQwLCAyMzQsIDgwLCAyMzQsIDEyMCwgMjM0LCAxNjAsIDIzNCwgMjAwLCAyMzQsIDI0MCwgMjM0LAorMjQsIDIzNSwgNjQsIDIzNSwgMTA0LCAyMzUsIDE0NCwgMjM1LCAxODQsIDIzNSwgMjI0LCAyMzUsIDgsIDIzNiwgNDgsIDIzNiwKKzg4LCAyMzYsIDEyOCwgMjM2LCAxNjgsIDIzNiwgMjA4LCAyMzYsIDI0OCwgMjM2LCAzMiwgMjM3LCA3MiwgMjM3LCAxMTIsIDIzNywKKzE1MiwgMjM3LCAxOTIsIDIzNywgMjMyLCAyMzcsIDE2LCAyMzgsIDU2LCAyMzgsIDk2LCAyMzgsIDEzNiwgMjM4LCAxNzYsIDIzOCwKKzIxNiwgMjM4LCAwLCAyMzksIDQwLCAyMzksIDgwLCAyMzksIDEyMCwgMjM5LCAxNjAsIDIzOSwgMjAwLCAyMzksIDI0MCwgMjM5LAorMjQsIDI0MCwgNjQsIDI0MCwgMTA0LCAyNDAsIDE0NCwgMjQwLCAxODQsIDI0MCwgMjI0LCAyNDAsIDgsIDI0MSwgNDgsIDI0MSwKKzg4LCAyNDEsIDEyOCwgMjQxLCAxNjgsIDI0MSwgMjA4LCAyNDEsIDI0OCwgMjQxLCAzMiwgMjQyLCA3MiwgMjQyLCAxMTIsIDI0MiwKKzE1MiwgMjQyLCAxOTIsIDI0MiwgMjMyLCAyNDIsIDE2LCAyNDMsIDU2LCAyNDMsIDk2LCAyNDMsIDEzNiwgMjQzLCAxNzYsIDI0MywKKzIxNiwgMjQzLCAwLCAyNDQsIDQwLCAyNDQsIDgwLCAyNDQsIDEyMCwgMjQ0LCAxNjAsIDI0NCwgMjAwLCAyNDQsIDI0MCwgMjQ0LAorMjQsIDI0NSwgNjQsIDI0NSwgMTA0LCAyNDUsIDE0NCwgMjQ1LCAxODQsIDI0NSwgMjI0LCAyNDUsIDgsIDI0NiwgNDgsIDI0NiwKKzg4LCAyNDYsIDEyOCwgMjQ2LCAxNjgsIDI0NiwgMjA4LCAyNDYsIDI0OCwgMjQ2LCAzMiwgMjQ3LCA3MiwgMjQ3LCAxMTIsIDI0NywKKzE1MiwgMjQ3LCAxOTIsIDI0NywgMjMyLCAyNDcsIDE2LCAyNDgsIDU2LCAyNDgsIDk2LCAyNDgsIDEzNiwgMjQ4LCAxNzYsIDI0OCwKKzIxNiwgMjQ4LCAwLCAyNDksIDQwLCAyNDksIDgwLCAyNDksIDEyMCwgMjQ5LCAxNjAsIDI0OSwgMjAwLCAyNDksIDI0MCwgMjQ5LAorMjQsIDI1MCwgNjQsIDI1MCwgMTA0LCAyNTAsIDE0NCwgMjUwLCAxODQsIDI1MCwgMjI0LCAyNTAsIDgsIDI1MSwgNDgsIDI1MSwKKzg4LCAyNTEsIDEyOCwgMjUxLCAxNjgsIDI1MSwgMjA4LCAyNTEsIDI0OCwgMjUxLCAzMiwgMjUyLCA3MiwgMjUyLCAxMTIsIDI1MiwKKzE1MiwgMjUyLCAxOTIsIDI1MiwgMjMyLCAyNTIsIDE2LCAyNTMsIDU2LCAyNTMsIDk2LCAyNTMsIDEzNiwgMjUzLCAxNzYsIDI1MywKKzIxNiwgMjUzLCAwLCAyNTQsIDQwLCAyNTQsIDgwLCAyNTQsIDEyMCwgMjU0LCAxNjAsIDI1NCwgMjAwLCAyNTQsIDI0MCwgMjU0LAorMjQsIDI1NSwgNjQsIDI1NSwgMTA0LCAyNTUsIDE0NCwgMjU1LCAxODQsIDI1NSwgMjI0LCAyNTUKKyAgICAgICAgICAgIH0pOworCisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX1VURl84LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX1VURl84LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDg5OTA1NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9NdWx0aUJ5dGVfVVRGXzguamF2YQpAQCAtMCwwICsxLDQ2NiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFyc2V0OworCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9NdWx0aUJ5dGVfVVRGXzggZXh0ZW5kcyBPbGRDaGFyc2V0X0Fic3RyYWN0VGVzdCB7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyc2V0TmFtZSA9ICJVVEYtOCI7CisKKyAgICAgICAgdGVzdENoYXJzID0gdGhlc2VDaGFycyhuZXcgaW50W117CiswLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAorMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCiszMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKzQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCis4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKzk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorMTI4LCAxMjksIDEzMCwgMTMxLCAxMzIsIDEzMywgMTM0LCAxMzUsIDEzNiwgMTM3LCAxMzgsIDEzOSwgMTQwLCAxNDEsIDE0MiwgMTQzLAorMTQ0LCAxNDUsIDE0NiwgMTQ3LCAxNDgsIDE0OSwgMTUwLCAxNTEsIDE1MiwgMTUzLCAxNTQsIDE1NSwgMTU2LCAxNTcsIDE1OCwgMTU5LAorMTYwLCAxNjEsIDE2MiwgMTYzLCAxNjQsIDE2NSwgMTY2LCAxNjcsIDE2OCwgMTY5LCAxNzAsIDE3MSwgMTcyLCAxNzMsIDE3NCwgMTc1LAorMTc2LCAxNzcsIDE3OCwgMTc5LCAxODAsIDE4MSwgMTgyLCAxODMsIDE4NCwgMTg1LCAxODYsIDE4NywgMTg4LCAxODksIDE5MCwgMTkxLAorMTkyLCAxOTMsIDE5NCwgMTk1LCAxOTYsIDE5NywgMTk4LCAxOTksIDIwMCwgMjAxLCAyMDIsIDIwMywgMjA0LCAyMDUsIDIwNiwgMjA3LAorMjA4LCAyMDksIDIxMCwgMjExLCAyMTIsIDIxMywgMjE0LCAyMTUsIDIxNiwgMjE3LCAyMTgsIDIxOSwgMjIwLCAyMjEsIDIyMiwgMjIzLAorMjI0LCAyMjUsIDIyNiwgMjI3LCAyMjgsIDIyOSwgMjMwLCAyMzEsIDIzMiwgMjMzLCAyMzQsIDIzNSwgMjM2LCAyMzcsIDIzOCwgMjM5LAorMjQwLCAyNDEsIDI0MiwgMjQzLCAyNDQsIDI0NSwgMjQ2LCAyNDcsIDI0OCwgMjQ5LCAyNTAsIDI1MSwgMjUyLCAyNTMsIDI1NCwgMjU1LAorMjU2LCAyOTYsIDMzNiwgMzc2LCA0MTYsIDQ1NiwgNDk2LCA1MzYsIDU3NiwgNjE2LCA2NTYsIDY5NiwgNzM2LCA3NzYsIDgxNiwgODU2LAorODk2LCA5MzYsIDk3NiwgMTAxNiwgMTA1NiwgMTA5NiwgMTEzNiwgMTE3NiwgMTIxNiwgMTI1NiwgMTI5NiwgMTMzNiwgMTM3NiwgMTQxNiwgMTQ1NiwgMTQ5NiwKKzE1MzYsIDE1NzYsIDE2MTYsIDE2NTYsIDE2OTYsIDE3MzYsIDE3NzYsIDE4MTYsIDE4NTYsIDE4OTYsIDE5MzYsIDE5NzYsIDIwMTYsIDIwNTYsIDIwOTYsIDIxMzYsCisyMTc2LCAyMjE2LCAyMjU2LCAyMjk2LCAyMzM2LCAyMzc2LCAyNDE2LCAyNDU2LCAyNDk2LCAyNTM2LCAyNTc2LCAyNjE2LCAyNjU2LCAyNjk2LCAyNzM2LCAyNzc2LAorMjgxNiwgMjg1NiwgMjg5NiwgMjkzNiwgMjk3NiwgMzAxNiwgMzA1NiwgMzA5NiwgMzEzNiwgMzE3NiwgMzIxNiwgMzI1NiwgMzI5NiwgMzMzNiwgMzM3NiwgMzQxNiwKKzM0NTYsIDM0OTYsIDM1MzYsIDM1NzYsIDM2MTYsIDM2NTYsIDM2OTYsIDM3MzYsIDM3NzYsIDM4MTYsIDM4NTYsIDM4OTYsIDM5MzYsIDM5NzYsIDQwMTYsIDQwNTYsCis0MDk2LCA0MTM2LCA0MTc2LCA0MjE2LCA0MjU2LCA0Mjk2LCA0MzM2LCA0Mzc2LCA0NDE2LCA0NDU2LCA0NDk2LCA0NTM2LCA0NTc2LCA0NjE2LCA0NjU2LCA0Njk2LAorNDczNiwgNDc3NiwgNDgxNiwgNDg1NiwgNDg5NiwgNDkzNiwgNDk3NiwgNTAxNiwgNTA1NiwgNTA5NiwgNTEzNiwgNTE3NiwgNTIxNiwgNTI1NiwgNTI5NiwgNTMzNiwKKzUzNzYsIDU0MTYsIDU0NTYsIDU0OTYsIDU1MzYsIDU1NzYsIDU2MTYsIDU2NTYsIDU2OTYsIDU3MzYsIDU3NzYsIDU4MTYsIDU4NTYsIDU4OTYsIDU5MzYsIDU5NzYsCis2MDE2LCA2MDU2LCA2MDk2LCA2MTM2LCA2MTc2LCA2MjE2LCA2MjU2LCA2Mjk2LCA2MzM2LCA2Mzc2LCA2NDE2LCA2NDU2LCA2NDk2LCA2NTM2LCA2NTc2LCA2NjE2LAorNjY1NiwgNjY5NiwgNjczNiwgNjc3NiwgNjgxNiwgNjg1NiwgNjg5NiwgNjkzNiwgNjk3NiwgNzAxNiwgNzA1NiwgNzA5NiwgNzEzNiwgNzE3NiwgNzIxNiwgNzI1NiwKKzcyOTYsIDczMzYsIDczNzYsIDc0MTYsIDc0NTYsIDc0OTYsIDc1MzYsIDc1NzYsIDc2MTYsIDc2NTYsIDc2OTYsIDc3MzYsIDc3NzYsIDc4MTYsIDc4NTYsIDc4OTYsCis3OTM2LCA3OTc2LCA4MDE2LCA4MDU2LCA4MDk2LCA4MTM2LCA4MTc2LCA4MjE2LCA4MjU2LCA4Mjk2LCA4MzM2LCA4Mzc2LCA4NDE2LCA4NDU2LCA4NDk2LCA4NTM2LAorODU3NiwgODYxNiwgODY1NiwgODY5NiwgODczNiwgODc3NiwgODgxNiwgODg1NiwgODg5NiwgODkzNiwgODk3NiwgOTAxNiwgOTA1NiwgOTA5NiwgOTEzNiwgOTE3NiwKKzkyMTYsIDkyNTYsIDkyOTYsIDkzMzYsIDkzNzYsIDk0MTYsIDk0NTYsIDk0OTYsIDk1MzYsIDk1NzYsIDk2MTYsIDk2NTYsIDk2OTYsIDk3MzYsIDk3NzYsIDk4MTYsCis5ODU2LCA5ODk2LCA5OTM2LCA5OTc2LCAxMDAxNiwgMTAwNTYsIDEwMDk2LCAxMDEzNiwgMTAxNzYsIDEwMjE2LCAxMDI1NiwgMTAyOTYsIDEwMzM2LCAxMDM3NiwgMTA0MTYsIDEwNDU2LAorMTA0OTYsIDEwNTM2LCAxMDU3NiwgMTA2MTYsIDEwNjU2LCAxMDY5NiwgMTA3MzYsIDEwNzc2LCAxMDgxNiwgMTA4NTYsIDEwODk2LCAxMDkzNiwgMTA5NzYsIDExMDE2LCAxMTA1NiwgMTEwOTYsCisxMTEzNiwgMTExNzYsIDExMjE2LCAxMTI1NiwgMTEyOTYsIDExMzM2LCAxMTM3NiwgMTE0MTYsIDExNDU2LCAxMTQ5NiwgMTE1MzYsIDExNTc2LCAxMTYxNiwgMTE2NTYsIDExNjk2LCAxMTczNiwKKzExNzc2LCAxMTgxNiwgMTE4NTYsIDExODk2LCAxMTkzNiwgMTE5NzYsIDEyMDE2LCAxMjA1NiwgMTIwOTYsIDEyMTM2LCAxMjE3NiwgMTIyMTYsIDEyMjU2LCAxMjI5NiwgMTIzMzYsIDEyMzc2LAorMTI0MTYsIDEyNDU2LCAxMjQ5NiwgMTI1MzYsIDEyNTc2LCAxMjYxNiwgMTI2NTYsIDEyNjk2LCAxMjczNiwgMTI3NzYsIDEyODE2LCAxMjg1NiwgMTI4OTYsIDEyOTM2LCAxMjk3NiwgMTMwMTYsCisxMzA1NiwgMTMwOTYsIDEzMTM2LCAxMzE3NiwgMTMyMTYsIDEzMjU2LCAxMzI5NiwgMTMzMzYsIDEzMzc2LCAxMzQxNiwgMTM0NTYsIDEzNDk2LCAxMzUzNiwgMTM1NzYsIDEzNjE2LCAxMzY1NiwKKzEzNjk2LCAxMzczNiwgMTM3NzYsIDEzODE2LCAxMzg1NiwgMTM4OTYsIDEzOTM2LCAxMzk3NiwgMTQwMTYsIDE0MDU2LCAxNDA5NiwgMTQxMzYsIDE0MTc2LCAxNDIxNiwgMTQyNTYsIDE0Mjk2LAorMTQzMzYsIDE0Mzc2LCAxNDQxNiwgMTQ0NTYsIDE0NDk2LCAxNDUzNiwgMTQ1NzYsIDE0NjE2LCAxNDY1NiwgMTQ2OTYsIDE0NzM2LCAxNDc3NiwgMTQ4MTYsIDE0ODU2LCAxNDg5NiwgMTQ5MzYsCisxNDk3NiwgMTUwMTYsIDE1MDU2LCAxNTA5NiwgMTUxMzYsIDE1MTc2LCAxNTIxNiwgMTUyNTYsIDE1Mjk2LCAxNTMzNiwgMTUzNzYsIDE1NDE2LCAxNTQ1NiwgMTU0OTYsIDE1NTM2LCAxNTU3NiwKKzE1NjE2LCAxNTY1NiwgMTU2OTYsIDE1NzM2LCAxNTc3NiwgMTU4MTYsIDE1ODU2LCAxNTg5NiwgMTU5MzYsIDE1OTc2LCAxNjAxNiwgMTYwNTYsIDE2MDk2LCAxNjEzNiwgMTYxNzYsIDE2MjE2LAorMTYyNTYsIDE2Mjk2LCAxNjMzNiwgMTYzNzYsIDE2NDE2LCAxNjQ1NiwgMTY0OTYsIDE2NTM2LCAxNjU3NiwgMTY2MTYsIDE2NjU2LCAxNjY5NiwgMTY3MzYsIDE2Nzc2LCAxNjgxNiwgMTY4NTYsCisxNjg5NiwgMTY5MzYsIDE2OTc2LCAxNzAxNiwgMTcwNTYsIDE3MDk2LCAxNzEzNiwgMTcxNzYsIDE3MjE2LCAxNzI1NiwgMTcyOTYsIDE3MzM2LCAxNzM3NiwgMTc0MTYsIDE3NDU2LCAxNzQ5NiwKKzE3NTM2LCAxNzU3NiwgMTc2MTYsIDE3NjU2LCAxNzY5NiwgMTc3MzYsIDE3Nzc2LCAxNzgxNiwgMTc4NTYsIDE3ODk2LCAxNzkzNiwgMTc5NzYsIDE4MDE2LCAxODA1NiwgMTgwOTYsIDE4MTM2LAorMTgxNzYsIDE4MjE2LCAxODI1NiwgMTgyOTYsIDE4MzM2LCAxODM3NiwgMTg0MTYsIDE4NDU2LCAxODQ5NiwgMTg1MzYsIDE4NTc2LCAxODYxNiwgMTg2NTYsIDE4Njk2LCAxODczNiwgMTg3NzYsCisxODgxNiwgMTg4NTYsIDE4ODk2LCAxODkzNiwgMTg5NzYsIDE5MDE2LCAxOTA1NiwgMTkwOTYsIDE5MTM2LCAxOTE3NiwgMTkyMTYsIDE5MjU2LCAxOTI5NiwgMTkzMzYsIDE5Mzc2LCAxOTQxNiwKKzE5NDU2LCAxOTQ5NiwgMTk1MzYsIDE5NTc2LCAxOTYxNiwgMTk2NTYsIDE5Njk2LCAxOTczNiwgMTk3NzYsIDE5ODE2LCAxOTg1NiwgMTk4OTYsIDE5OTM2LCAxOTk3NiwgMjAwMTYsIDIwMDU2LAorMjAwOTYsIDIwMTM2LCAyMDE3NiwgMjAyMTYsIDIwMjU2LCAyMDI5NiwgMjAzMzYsIDIwMzc2LCAyMDQxNiwgMjA0NTYsIDIwNDk2LCAyMDUzNiwgMjA1NzYsIDIwNjE2LCAyMDY1NiwgMjA2OTYsCisyMDczNiwgMjA3NzYsIDIwODE2LCAyMDg1NiwgMjA4OTYsIDIwOTM2LCAyMDk3NiwgMjEwMTYsIDIxMDU2LCAyMTA5NiwgMjExMzYsIDIxMTc2LCAyMTIxNiwgMjEyNTYsIDIxMjk2LCAyMTMzNiwKKzIxMzc2LCAyMTQxNiwgMjE0NTYsIDIxNDk2LCAyMTUzNiwgMjE1NzYsIDIxNjE2LCAyMTY1NiwgMjE2OTYsIDIxNzM2LCAyMTc3NiwgMjE4MTYsIDIxODU2LCAyMTg5NiwgMjE5MzYsIDIxOTc2LAorMjIwMTYsIDIyMDU2LCAyMjA5NiwgMjIxMzYsIDIyMTc2LCAyMjIxNiwgMjIyNTYsIDIyMjk2LCAyMjMzNiwgMjIzNzYsIDIyNDE2LCAyMjQ1NiwgMjI0OTYsIDIyNTM2LCAyMjU3NiwgMjI2MTYsCisyMjY1NiwgMjI2OTYsIDIyNzM2LCAyMjc3NiwgMjI4MTYsIDIyODU2LCAyMjg5NiwgMjI5MzYsIDIyOTc2LCAyMzAxNiwgMjMwNTYsIDIzMDk2LCAyMzEzNiwgMjMxNzYsIDIzMjE2LCAyMzI1NiwKKzIzMjk2LCAyMzMzNiwgMjMzNzYsIDIzNDE2LCAyMzQ1NiwgMjM0OTYsIDIzNTM2LCAyMzU3NiwgMjM2MTYsIDIzNjU2LCAyMzY5NiwgMjM3MzYsIDIzNzc2LCAyMzgxNiwgMjM4NTYsIDIzODk2LAorMjM5MzYsIDIzOTc2LCAyNDAxNiwgMjQwNTYsIDI0MDk2LCAyNDEzNiwgMjQxNzYsIDI0MjE2LCAyNDI1NiwgMjQyOTYsIDI0MzM2LCAyNDM3NiwgMjQ0MTYsIDI0NDU2LCAyNDQ5NiwgMjQ1MzYsCisyNDU3NiwgMjQ2MTYsIDI0NjU2LCAyNDY5NiwgMjQ3MzYsIDI0Nzc2LCAyNDgxNiwgMjQ4NTYsIDI0ODk2LCAyNDkzNiwgMjQ5NzYsIDI1MDE2LCAyNTA1NiwgMjUwOTYsIDI1MTM2LCAyNTE3NiwKKzI1MjE2LCAyNTI1NiwgMjUyOTYsIDI1MzM2LCAyNTM3NiwgMjU0MTYsIDI1NDU2LCAyNTQ5NiwgMjU1MzYsIDI1NTc2LCAyNTYxNiwgMjU2NTYsIDI1Njk2LCAyNTczNiwgMjU3NzYsIDI1ODE2LAorMjU4NTYsIDI1ODk2LCAyNTkzNiwgMjU5NzYsIDI2MDE2LCAyNjA1NiwgMjYwOTYsIDI2MTM2LCAyNjE3NiwgMjYyMTYsIDI2MjU2LCAyNjI5NiwgMjYzMzYsIDI2Mzc2LCAyNjQxNiwgMjY0NTYsCisyNjQ5NiwgMjY1MzYsIDI2NTc2LCAyNjYxNiwgMjY2NTYsIDI2Njk2LCAyNjczNiwgMjY3NzYsIDI2ODE2LCAyNjg1NiwgMjY4OTYsIDI2OTM2LCAyNjk3NiwgMjcwMTYsIDI3MDU2LCAyNzA5NiwKKzI3MTM2LCAyNzE3NiwgMjcyMTYsIDI3MjU2LCAyNzI5NiwgMjczMzYsIDI3Mzc2LCAyNzQxNiwgMjc0NTYsIDI3NDk2LCAyNzUzNiwgMjc1NzYsIDI3NjE2LCAyNzY1NiwgMjc2OTYsIDI3NzM2LAorMjc3NzYsIDI3ODE2LCAyNzg1NiwgMjc4OTYsIDI3OTM2LCAyNzk3NiwgMjgwMTYsIDI4MDU2LCAyODA5NiwgMjgxMzYsIDI4MTc2LCAyODIxNiwgMjgyNTYsIDI4Mjk2LCAyODMzNiwgMjgzNzYsCisyODQxNiwgMjg0NTYsIDI4NDk2LCAyODUzNiwgMjg1NzYsIDI4NjE2LCAyODY1NiwgMjg2OTYsIDI4NzM2LCAyODc3NiwgMjg4MTYsIDI4ODU2LCAyODg5NiwgMjg5MzYsIDI4OTc2LCAyOTAxNiwKKzI5MDU2LCAyOTA5NiwgMjkxMzYsIDI5MTc2LCAyOTIxNiwgMjkyNTYsIDI5Mjk2LCAyOTMzNiwgMjkzNzYsIDI5NDE2LCAyOTQ1NiwgMjk0OTYsIDI5NTM2LCAyOTU3NiwgMjk2MTYsIDI5NjU2LAorMjk2OTYsIDI5NzM2LCAyOTc3NiwgMjk4MTYsIDI5ODU2LCAyOTg5NiwgMjk5MzYsIDI5OTc2LCAzMDAxNiwgMzAwNTYsIDMwMDk2LCAzMDEzNiwgMzAxNzYsIDMwMjE2LCAzMDI1NiwgMzAyOTYsCiszMDMzNiwgMzAzNzYsIDMwNDE2LCAzMDQ1NiwgMzA0OTYsIDMwNTM2LCAzMDU3NiwgMzA2MTYsIDMwNjU2LCAzMDY5NiwgMzA3MzYsIDMwNzc2LCAzMDgxNiwgMzA4NTYsIDMwODk2LCAzMDkzNiwKKzMwOTc2LCAzMTAxNiwgMzEwNTYsIDMxMDk2LCAzMTEzNiwgMzExNzYsIDMxMjE2LCAzMTI1NiwgMzEyOTYsIDMxMzM2LCAzMTM3NiwgMzE0MTYsIDMxNDU2LCAzMTQ5NiwgMzE1MzYsIDMxNTc2LAorMzE2MTYsIDMxNjU2LCAzMTY5NiwgMzE3MzYsIDMxNzc2LCAzMTgxNiwgMzE4NTYsIDMxODk2LCAzMTkzNiwgMzE5NzYsIDMyMDE2LCAzMjA1NiwgMzIwOTYsIDMyMTM2LCAzMjE3NiwgMzIyMTYsCiszMjI1NiwgMzIyOTYsIDMyMzM2LCAzMjM3NiwgMzI0MTYsIDMyNDU2LCAzMjQ5NiwgMzI1MzYsIDMyNTc2LCAzMjYxNiwgMzI2NTYsIDMyNjk2LCAzMjczNiwgMzI3NzYsIDMyODE2LCAzMjg1NiwKKzMyODk2LCAzMjkzNiwgMzI5NzYsIDMzMDE2LCAzMzA1NiwgMzMwOTYsIDMzMTM2LCAzMzE3NiwgMzMyMTYsIDMzMjU2LCAzMzI5NiwgMzMzMzYsIDMzMzc2LCAzMzQxNiwgMzM0NTYsIDMzNDk2LAorMzM1MzYsIDMzNTc2LCAzMzYxNiwgMzM2NTYsIDMzNjk2LCAzMzczNiwgMzM3NzYsIDMzODE2LCAzMzg1NiwgMzM4OTYsIDMzOTM2LCAzMzk3NiwgMzQwMTYsIDM0MDU2LCAzNDA5NiwgMzQxMzYsCiszNDE3NiwgMzQyMTYsIDM0MjU2LCAzNDI5NiwgMzQzMzYsIDM0Mzc2LCAzNDQxNiwgMzQ0NTYsIDM0NDk2LCAzNDUzNiwgMzQ1NzYsIDM0NjE2LCAzNDY1NiwgMzQ2OTYsIDM0NzM2LCAzNDc3NiwKKzM0ODE2LCAzNDg1NiwgMzQ4OTYsIDM0OTM2LCAzNDk3NiwgMzUwMTYsIDM1MDU2LCAzNTA5NiwgMzUxMzYsIDM1MTc2LCAzNTIxNiwgMzUyNTYsIDM1Mjk2LCAzNTMzNiwgMzUzNzYsIDM1NDE2LAorMzU0NTYsIDM1NDk2LCAzNTUzNiwgMzU1NzYsIDM1NjE2LCAzNTY1NiwgMzU2OTYsIDM1NzM2LCAzNTc3NiwgMzU4MTYsIDM1ODU2LCAzNTg5NiwgMzU5MzYsIDM1OTc2LCAzNjAxNiwgMzYwNTYsCiszNjA5NiwgMzYxMzYsIDM2MTc2LCAzNjIxNiwgMzYyNTYsIDM2Mjk2LCAzNjMzNiwgMzYzNzYsIDM2NDE2LCAzNjQ1NiwgMzY0OTYsIDM2NTM2LCAzNjU3NiwgMzY2MTYsIDM2NjU2LCAzNjY5NiwKKzM2NzM2LCAzNjc3NiwgMzY4MTYsIDM2ODU2LCAzNjg5NiwgMzY5MzYsIDM2OTc2LCAzNzAxNiwgMzcwNTYsIDM3MDk2LCAzNzEzNiwgMzcxNzYsIDM3MjE2LCAzNzI1NiwgMzcyOTYsIDM3MzM2LAorMzczNzYsIDM3NDE2LCAzNzQ1NiwgMzc0OTYsIDM3NTM2LCAzNzU3NiwgMzc2MTYsIDM3NjU2LCAzNzY5NiwgMzc3MzYsIDM3Nzc2LCAzNzgxNiwgMzc4NTYsIDM3ODk2LCAzNzkzNiwgMzc5NzYsCiszODAxNiwgMzgwNTYsIDM4MDk2LCAzODEzNiwgMzgxNzYsIDM4MjE2LCAzODI1NiwgMzgyOTYsIDM4MzM2LCAzODM3NiwgMzg0MTYsIDM4NDU2LCAzODQ5NiwgMzg1MzYsIDM4NTc2LCAzODYxNiwKKzM4NjU2LCAzODY5NiwgMzg3MzYsIDM4Nzc2LCAzODgxNiwgMzg4NTYsIDM4ODk2LCAzODkzNiwgMzg5NzYsIDM5MDE2LCAzOTA1NiwgMzkwOTYsIDM5MTM2LCAzOTE3NiwgMzkyMTYsIDM5MjU2LAorMzkyOTYsIDM5MzM2LCAzOTM3NiwgMzk0MTYsIDM5NDU2LCAzOTQ5NiwgMzk1MzYsIDM5NTc2LCAzOTYxNiwgMzk2NTYsIDM5Njk2LCAzOTczNiwgMzk3NzYsIDM5ODE2LCAzOTg1NiwgMzk4OTYsCiszOTkzNiwgMzk5NzYsIDQwMDE2LCA0MDA1NiwgNDAwOTYsIDQwMTM2LCA0MDE3NiwgNDAyMTYsIDQwMjU2LCA0MDI5NiwgNDAzMzYsIDQwMzc2LCA0MDQxNiwgNDA0NTYsIDQwNDk2LCA0MDUzNiwKKzQwNTc2LCA0MDYxNiwgNDA2NTYsIDQwNjk2LCA0MDczNiwgNDA3NzYsIDQwODE2LCA0MDg1NiwgNDA4OTYsIDQwOTM2LCA0MDk3NiwgNDEwMTYsIDQxMDU2LCA0MTA5NiwgNDExMzYsIDQxMTc2LAorNDEyMTYsIDQxMjU2LCA0MTI5NiwgNDEzMzYsIDQxMzc2LCA0MTQxNiwgNDE0NTYsIDQxNDk2LCA0MTUzNiwgNDE1NzYsIDQxNjE2LCA0MTY1NiwgNDE2OTYsIDQxNzM2LCA0MTc3NiwgNDE4MTYsCis0MTg1NiwgNDE4OTYsIDQxOTM2LCA0MTk3NiwgNDIwMTYsIDQyMDU2LCA0MjA5NiwgNDIxMzYsIDQyMTc2LCA0MjIxNiwgNDIyNTYsIDQyMjk2LCA0MjMzNiwgNDIzNzYsIDQyNDE2LCA0MjQ1NiwKKzQyNDk2LCA0MjUzNiwgNDI1NzYsIDQyNjE2LCA0MjY1NiwgNDI2OTYsIDQyNzM2LCA0Mjc3NiwgNDI4MTYsIDQyODU2LCA0Mjg5NiwgNDI5MzYsIDQyOTc2LCA0MzAxNiwgNDMwNTYsIDQzMDk2LAorNDMxMzYsIDQzMTc2LCA0MzIxNiwgNDMyNTYsIDQzMjk2LCA0MzMzNiwgNDMzNzYsIDQzNDE2LCA0MzQ1NiwgNDM0OTYsIDQzNTM2LCA0MzU3NiwgNDM2MTYsIDQzNjU2LCA0MzY5NiwgNDM3MzYsCis0Mzc3NiwgNDM4MTYsIDQzODU2LCA0Mzg5NiwgNDM5MzYsIDQzOTc2LCA0NDAxNiwgNDQwNTYsIDQ0MDk2LCA0NDEzNiwgNDQxNzYsIDQ0MjE2LCA0NDI1NiwgNDQyOTYsIDQ0MzM2LCA0NDM3NiwKKzQ0NDE2LCA0NDQ1NiwgNDQ0OTYsIDQ0NTM2LCA0NDU3NiwgNDQ2MTYsIDQ0NjU2LCA0NDY5NiwgNDQ3MzYsIDQ0Nzc2LCA0NDgxNiwgNDQ4NTYsIDQ0ODk2LCA0NDkzNiwgNDQ5NzYsIDQ1MDE2LAorNDUwNTYsIDQ1MDk2LCA0NTEzNiwgNDUxNzYsIDQ1MjE2LCA0NTI1NiwgNDUyOTYsIDQ1MzM2LCA0NTM3NiwgNDU0MTYsIDQ1NDU2LCA0NTQ5NiwgNDU1MzYsIDQ1NTc2LCA0NTYxNiwgNDU2NTYsCis0NTY5NiwgNDU3MzYsIDQ1Nzc2LCA0NTgxNiwgNDU4NTYsIDQ1ODk2LCA0NTkzNiwgNDU5NzYsIDQ2MDE2LCA0NjA1NiwgNDYwOTYsIDQ2MTM2LCA0NjE3NiwgNDYyMTYsIDQ2MjU2LCA0NjI5NiwKKzQ2MzM2LCA0NjM3NiwgNDY0MTYsIDQ2NDU2LCA0NjQ5NiwgNDY1MzYsIDQ2NTc2LCA0NjYxNiwgNDY2NTYsIDQ2Njk2LCA0NjczNiwgNDY3NzYsIDQ2ODE2LCA0Njg1NiwgNDY4OTYsIDQ2OTM2LAorNDY5NzYsIDQ3MDE2LCA0NzA1NiwgNDcwOTYsIDQ3MTM2LCA0NzE3NiwgNDcyMTYsIDQ3MjU2LCA0NzI5NiwgNDczMzYsIDQ3Mzc2LCA0NzQxNiwgNDc0NTYsIDQ3NDk2LCA0NzUzNiwgNDc1NzYsCis0NzYxNiwgNDc2NTYsIDQ3Njk2LCA0NzczNiwgNDc3NzYsIDQ3ODE2LCA0Nzg1NiwgNDc4OTYsIDQ3OTM2LCA0Nzk3NiwgNDgwMTYsIDQ4MDU2LCA0ODA5NiwgNDgxMzYsIDQ4MTc2LCA0ODIxNiwKKzQ4MjU2LCA0ODI5NiwgNDgzMzYsIDQ4Mzc2LCA0ODQxNiwgNDg0NTYsIDQ4NDk2LCA0ODUzNiwgNDg1NzYsIDQ4NjE2LCA0ODY1NiwgNDg2OTYsIDQ4NzM2LCA0ODc3NiwgNDg4MTYsIDQ4ODU2LAorNDg4OTYsIDQ4OTM2LCA0ODk3NiwgNDkwMTYsIDQ5MDU2LCA0OTA5NiwgNDkxMzYsIDQ5MTc2LCA0OTIxNiwgNDkyNTYsIDQ5Mjk2LCA0OTMzNiwgNDkzNzYsIDQ5NDE2LCA0OTQ1NiwgNDk0OTYsCis0OTUzNiwgNDk1NzYsIDQ5NjE2LCA0OTY1NiwgNDk2OTYsIDQ5NzM2LCA0OTc3NiwgNDk4MTYsIDQ5ODU2LCA0OTg5NiwgNDk5MzYsIDQ5OTc2LCA1MDAxNiwgNTAwNTYsIDUwMDk2LCA1MDEzNiwKKzUwMTc2LCA1MDIxNiwgNTAyNTYsIDUwMjk2LCA1MDMzNiwgNTAzNzYsIDUwNDE2LCA1MDQ1NiwgNTA0OTYsIDUwNTM2LCA1MDU3NiwgNTA2MTYsIDUwNjU2LCA1MDY5NiwgNTA3MzYsIDUwNzc2LAorNTA4MTYsIDUwODU2LCA1MDg5NiwgNTA5MzYsIDUwOTc2LCA1MTAxNiwgNTEwNTYsIDUxMDk2LCA1MTEzNiwgNTExNzYsIDUxMjE2LCA1MTI1NiwgNTEyOTYsIDUxMzM2LCA1MTM3NiwgNTE0MTYsCis1MTQ1NiwgNTE0OTYsIDUxNTM2LCA1MTU3NiwgNTE2MTYsIDUxNjU2LCA1MTY5NiwgNTE3MzYsIDUxNzc2LCA1MTgxNiwgNTE4NTYsIDUxODk2LCA1MTkzNiwgNTE5NzYsIDUyMDE2LCA1MjA1NiwKKzUyMDk2LCA1MjEzNiwgNTIxNzYsIDUyMjE2LCA1MjI1NiwgNTIyOTYsIDUyMzM2LCA1MjM3NiwgNTI0MTYsIDUyNDU2LCA1MjQ5NiwgNTI1MzYsIDUyNTc2LCA1MjYxNiwgNTI2NTYsIDUyNjk2LAorNTI3MzYsIDUyNzc2LCA1MjgxNiwgNTI4NTYsIDUyODk2LCA1MjkzNiwgNTI5NzYsIDUzMDE2LCA1MzA1NiwgNTMwOTYsIDUzMTM2LCA1MzE3NiwgNTMyMTYsIDUzMjU2LCA1MzI5NiwgNTMzMzYsCis1MzM3NiwgNTM0MTYsIDUzNDU2LCA1MzQ5NiwgNTM1MzYsIDUzNTc2LCA1MzYxNiwgNTM2NTYsIDUzNjk2LCA1MzczNiwgNTM3NzYsIDUzODE2LCA1Mzg1NiwgNTM4OTYsIDUzOTM2LCA1Mzk3NiwKKzU0MDE2LCA1NDA1NiwgNTQwOTYsIDU0MTM2LCA1NDE3NiwgNTQyMTYsIDU0MjU2LCA1NDI5NiwgNTQzMzYsIDU0Mzc2LCA1NDQxNiwgNTQ0NTYsIDU0NDk2LCA1NDUzNiwgNTQ1NzYsIDU0NjE2LAorNTQ2NTYsIDU0Njk2LCA1NDczNiwgNTQ3NzYsIDU0ODE2LCA1NDg1NiwgNTQ4OTYsIDU0OTM2LCA1NDk3NiwgNTUwMTYsIDU1MDU2LCA1NTA5NiwgNTUxMzYsIDU1MTc2LCA1NTIxNiwgNTUyNTYsCis1NzM0NCwgNTczODQsIDU3NDI0LCA1NzQ2NCwgNTc1MDQsIDU3NTQ0LCA1NzU4NCwgNTc2MjQsIDU3NjY0LCA1NzcwNCwgNTc3NDQsIDU3Nzg0LCA1NzgyNCwgNTc4NjQsIDU3OTA0LCA1Nzk0NCwKKzU3OTg0LCA1ODAyNCwgNTgwNjQsIDU4MTA0LCA1ODE0NCwgNTgxODQsIDU4MjI0LCA1ODI2NCwgNTgzMDQsIDU4MzQ0LCA1ODM4NCwgNTg0MjQsIDU4NDY0LCA1ODUwNCwgNTg1NDQsIDU4NTg0LAorNTg2MjQsIDU4NjY0LCA1ODcwNCwgNTg3NDQsIDU4Nzg0LCA1ODgyNCwgNTg4NjQsIDU4OTA0LCA1ODk0NCwgNTg5ODQsIDU5MDI0LCA1OTA2NCwgNTkxMDQsIDU5MTQ0LCA1OTE4NCwgNTkyMjQsCis1OTI2NCwgNTkzMDQsIDU5MzQ0LCA1OTM4NCwgNTk0MjQsIDU5NDY0LCA1OTUwNCwgNTk1NDQsIDU5NTg0LCA1OTYyNCwgNTk2NjQsIDU5NzA0LCA1OTc0NCwgNTk3ODQsIDU5ODI0LCA1OTg2NCwKKzU5OTA0LCA1OTk0NCwgNTk5ODQsIDYwMDI0LCA2MDA2NCwgNjAxMDQsIDYwMTQ0LCA2MDE4NCwgNjAyMjQsIDYwMjY0LCA2MDMwNCwgNjAzNDQsIDYwMzg0LCA2MDQyNCwgNjA0NjQsIDYwNTA0LAorNjA1NDQsIDYwNTg0LCA2MDYyNCwgNjA2NjQsIDYwNzA0LCA2MDc0NCwgNjA3ODQsIDYwODI0LCA2MDg2NCwgNjA5MDQsIDYwOTQ0LCA2MDk4NCwgNjEwMjQsIDYxMDY0LCA2MTEwNCwgNjExNDQsCis2MTE4NCwgNjEyMjQsIDYxMjY0LCA2MTMwNCwgNjEzNDQsIDYxMzg0LCA2MTQyNCwgNjE0NjQsIDYxNTA0LCA2MTU0NCwgNjE1ODQsIDYxNjI0LCA2MTY2NCwgNjE3MDQsIDYxNzQ0LCA2MTc4NCwKKzYxODI0LCA2MTg2NCwgNjE5MDQsIDYxOTQ0LCA2MTk4NCwgNjIwMjQsIDYyMDY0LCA2MjEwNCwgNjIxNDQsIDYyMTg0LCA2MjIyNCwgNjIyNjQsIDYyMzA0LCA2MjM0NCwgNjIzODQsIDYyNDI0LAorNjI0NjQsIDYyNTA0LCA2MjU0NCwgNjI1ODQsIDYyNjI0LCA2MjY2NCwgNjI3MDQsIDYyNzQ0LCA2Mjc4NCwgNjI4MjQsIDYyODY0LCA2MjkwNCwgNjI5NDQsIDYyOTg0LCA2MzAyNCwgNjMwNjQsCis2MzEwNCwgNjMxNDQsIDYzMTg0LCA2MzIyNCwgNjMyNjQsIDYzMzA0LCA2MzM0NCwgNjMzODQsIDYzNDI0LCA2MzQ2NCwgNjM1MDQsIDYzNTQ0LCA2MzU4NCwgNjM2MjQsIDYzNjY0LCA2MzcwNCwKKzYzNzQ0LCA2Mzc4NCwgNjM4MjQsIDYzODY0LCA2MzkwNCwgNjM5NDQsIDYzOTg0LCA2NDAyNCwgNjQwNjQsIDY0MTA0LCA2NDE0NCwgNjQxODQsIDY0MjI0LCA2NDI2NCwgNjQzMDQsIDY0MzQ0LAorNjQzODQsIDY0NDI0LCA2NDQ2NCwgNjQ1MDQsIDY0NTQ0LCA2NDU4NCwgNjQ2MjQsIDY0NjY0LCA2NDcwNCwgNjQ3NDQsIDY0Nzg0LCA2NDgyNCwgNjQ4NjQsIDY0OTA0LCA2NDk0NCwgNjQ5ODQsCis2NTAyNCwgNjUwNjQsIDY1MTA0LCA2NTE0NCwgNjUxODQsIDY1MjI0LCA2NTI2NCwgNjUzMDQsIDY1MzQ0LCA2NTM4NCwgNjU0MjQsIDY1NDY0LCA2NTUwNAorICAgICAgICAgICAgfSk7CisKKyAgICAgICAgdGVzdEJ5dGVzID0gdGhlc2VCeXRlcyhuZXcgaW50W117CiswLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAorMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCiszMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKzQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCis4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKzk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorMTk0LCAxMjgsIDE5NCwgMTI5LCAxOTQsIDEzMCwgMTk0LCAxMzEsIDE5NCwgMTMyLCAxOTQsIDEzMywgMTk0LCAxMzQsIDE5NCwgMTM1LAorMTk0LCAxMzYsIDE5NCwgMTM3LCAxOTQsIDEzOCwgMTk0LCAxMzksIDE5NCwgMTQwLCAxOTQsIDE0MSwgMTk0LCAxNDIsIDE5NCwgMTQzLAorMTk0LCAxNDQsIDE5NCwgMTQ1LCAxOTQsIDE0NiwgMTk0LCAxNDcsIDE5NCwgMTQ4LCAxOTQsIDE0OSwgMTk0LCAxNTAsIDE5NCwgMTUxLAorMTk0LCAxNTIsIDE5NCwgMTUzLCAxOTQsIDE1NCwgMTk0LCAxNTUsIDE5NCwgMTU2LCAxOTQsIDE1NywgMTk0LCAxNTgsIDE5NCwgMTU5LAorMTk0LCAxNjAsIDE5NCwgMTYxLCAxOTQsIDE2MiwgMTk0LCAxNjMsIDE5NCwgMTY0LCAxOTQsIDE2NSwgMTk0LCAxNjYsIDE5NCwgMTY3LAorMTk0LCAxNjgsIDE5NCwgMTY5LCAxOTQsIDE3MCwgMTk0LCAxNzEsIDE5NCwgMTcyLCAxOTQsIDE3MywgMTk0LCAxNzQsIDE5NCwgMTc1LAorMTk0LCAxNzYsIDE5NCwgMTc3LCAxOTQsIDE3OCwgMTk0LCAxNzksIDE5NCwgMTgwLCAxOTQsIDE4MSwgMTk0LCAxODIsIDE5NCwgMTgzLAorMTk0LCAxODQsIDE5NCwgMTg1LCAxOTQsIDE4NiwgMTk0LCAxODcsIDE5NCwgMTg4LCAxOTQsIDE4OSwgMTk0LCAxOTAsIDE5NCwgMTkxLAorMTk1LCAxMjgsIDE5NSwgMTI5LCAxOTUsIDEzMCwgMTk1LCAxMzEsIDE5NSwgMTMyLCAxOTUsIDEzMywgMTk1LCAxMzQsIDE5NSwgMTM1LAorMTk1LCAxMzYsIDE5NSwgMTM3LCAxOTUsIDEzOCwgMTk1LCAxMzksIDE5NSwgMTQwLCAxOTUsIDE0MSwgMTk1LCAxNDIsIDE5NSwgMTQzLAorMTk1LCAxNDQsIDE5NSwgMTQ1LCAxOTUsIDE0NiwgMTk1LCAxNDcsIDE5NSwgMTQ4LCAxOTUsIDE0OSwgMTk1LCAxNTAsIDE5NSwgMTUxLAorMTk1LCAxNTIsIDE5NSwgMTUzLCAxOTUsIDE1NCwgMTk1LCAxNTUsIDE5NSwgMTU2LCAxOTUsIDE1NywgMTk1LCAxNTgsIDE5NSwgMTU5LAorMTk1LCAxNjAsIDE5NSwgMTYxLCAxOTUsIDE2MiwgMTk1LCAxNjMsIDE5NSwgMTY0LCAxOTUsIDE2NSwgMTk1LCAxNjYsIDE5NSwgMTY3LAorMTk1LCAxNjgsIDE5NSwgMTY5LCAxOTUsIDE3MCwgMTk1LCAxNzEsIDE5NSwgMTcyLCAxOTUsIDE3MywgMTk1LCAxNzQsIDE5NSwgMTc1LAorMTk1LCAxNzYsIDE5NSwgMTc3LCAxOTUsIDE3OCwgMTk1LCAxNzksIDE5NSwgMTgwLCAxOTUsIDE4MSwgMTk1LCAxODIsIDE5NSwgMTgzLAorMTk1LCAxODQsIDE5NSwgMTg1LCAxOTUsIDE4NiwgMTk1LCAxODcsIDE5NSwgMTg4LCAxOTUsIDE4OSwgMTk1LCAxOTAsIDE5NSwgMTkxLAorMTk2LCAxMjgsIDE5NiwgMTY4LCAxOTcsIDE0NCwgMTk3LCAxODQsIDE5OCwgMTYwLCAxOTksIDEzNiwgMTk5LCAxNzYsIDIwMCwgMTUyLAorMjAxLCAxMjgsIDIwMSwgMTY4LCAyMDIsIDE0NCwgMjAyLCAxODQsIDIwMywgMTYwLCAyMDQsIDEzNiwgMjA0LCAxNzYsIDIwNSwgMTUyLAorMjA2LCAxMjgsIDIwNiwgMTY4LCAyMDcsIDE0NCwgMjA3LCAxODQsIDIwOCwgMTYwLCAyMDksIDEzNiwgMjA5LCAxNzYsIDIxMCwgMTUyLAorMjExLCAxMjgsIDIxMSwgMTY4LCAyMTIsIDE0NCwgMjEyLCAxODQsIDIxMywgMTYwLCAyMTQsIDEzNiwgMjE0LCAxNzYsIDIxNSwgMTUyLAorMjE2LCAxMjgsIDIxNiwgMTY4LCAyMTcsIDE0NCwgMjE3LCAxODQsIDIxOCwgMTYwLCAyMTksIDEzNiwgMjE5LCAxNzYsIDIyMCwgMTUyLAorMjIxLCAxMjgsIDIyMSwgMTY4LCAyMjIsIDE0NCwgMjIyLCAxODQsIDIyMywgMTYwLCAyMjQsIDE2MCwgMTM2LCAyMjQsIDE2MCwgMTc2LAorMjI0LCAxNjEsIDE1MiwgMjI0LCAxNjIsIDEyOCwgMjI0LCAxNjIsIDE2OCwgMjI0LCAxNjMsIDE0NCwgMjI0LCAxNjMsIDE4NCwgMjI0LAorMTY0LCAxNjAsIDIyNCwgMTY1LCAxMzYsIDIyNCwgMTY1LCAxNzYsIDIyNCwgMTY2LCAxNTIsIDIyNCwgMTY3LCAxMjgsIDIyNCwgMTY3LAorMTY4LCAyMjQsIDE2OCwgMTQ0LCAyMjQsIDE2OCwgMTg0LCAyMjQsIDE2OSwgMTYwLCAyMjQsIDE3MCwgMTM2LCAyMjQsIDE3MCwgMTc2LAorMjI0LCAxNzEsIDE1MiwgMjI0LCAxNzIsIDEyOCwgMjI0LCAxNzIsIDE2OCwgMjI0LCAxNzMsIDE0NCwgMjI0LCAxNzMsIDE4NCwgMjI0LAorMTc0LCAxNjAsIDIyNCwgMTc1LCAxMzYsIDIyNCwgMTc1LCAxNzYsIDIyNCwgMTc2LCAxNTIsIDIyNCwgMTc3LCAxMjgsIDIyNCwgMTc3LAorMTY4LCAyMjQsIDE3OCwgMTQ0LCAyMjQsIDE3OCwgMTg0LCAyMjQsIDE3OSwgMTYwLCAyMjQsIDE4MCwgMTM2LCAyMjQsIDE4MCwgMTc2LAorMjI0LCAxODEsIDE1MiwgMjI0LCAxODIsIDEyOCwgMjI0LCAxODIsIDE2OCwgMjI0LCAxODMsIDE0NCwgMjI0LCAxODMsIDE4NCwgMjI0LAorMTg0LCAxNjAsIDIyNCwgMTg1LCAxMzYsIDIyNCwgMTg1LCAxNzYsIDIyNCwgMTg2LCAxNTIsIDIyNCwgMTg3LCAxMjgsIDIyNCwgMTg3LAorMTY4LCAyMjQsIDE4OCwgMTQ0LCAyMjQsIDE4OCwgMTg0LCAyMjQsIDE4OSwgMTYwLCAyMjQsIDE5MCwgMTM2LCAyMjQsIDE5MCwgMTc2LAorMjI0LCAxOTEsIDE1MiwgMjI1LCAxMjgsIDEyOCwgMjI1LCAxMjgsIDE2OCwgMjI1LCAxMjksIDE0NCwgMjI1LCAxMjksIDE4NCwgMjI1LAorMTMwLCAxNjAsIDIyNSwgMTMxLCAxMzYsIDIyNSwgMTMxLCAxNzYsIDIyNSwgMTMyLCAxNTIsIDIyNSwgMTMzLCAxMjgsIDIyNSwgMTMzLAorMTY4LCAyMjUsIDEzNCwgMTQ0LCAyMjUsIDEzNCwgMTg0LCAyMjUsIDEzNSwgMTYwLCAyMjUsIDEzNiwgMTM2LCAyMjUsIDEzNiwgMTc2LAorMjI1LCAxMzcsIDE1MiwgMjI1LCAxMzgsIDEyOCwgMjI1LCAxMzgsIDE2OCwgMjI1LCAxMzksIDE0NCwgMjI1LCAxMzksIDE4NCwgMjI1LAorMTQwLCAxNjAsIDIyNSwgMTQxLCAxMzYsIDIyNSwgMTQxLCAxNzYsIDIyNSwgMTQyLCAxNTIsIDIyNSwgMTQzLCAxMjgsIDIyNSwgMTQzLAorMTY4LCAyMjUsIDE0NCwgMTQ0LCAyMjUsIDE0NCwgMTg0LCAyMjUsIDE0NSwgMTYwLCAyMjUsIDE0NiwgMTM2LCAyMjUsIDE0NiwgMTc2LAorMjI1LCAxNDcsIDE1MiwgMjI1LCAxNDgsIDEyOCwgMjI1LCAxNDgsIDE2OCwgMjI1LCAxNDksIDE0NCwgMjI1LCAxNDksIDE4NCwgMjI1LAorMTUwLCAxNjAsIDIyNSwgMTUxLCAxMzYsIDIyNSwgMTUxLCAxNzYsIDIyNSwgMTUyLCAxNTIsIDIyNSwgMTUzLCAxMjgsIDIyNSwgMTUzLAorMTY4LCAyMjUsIDE1NCwgMTQ0LCAyMjUsIDE1NCwgMTg0LCAyMjUsIDE1NSwgMTYwLCAyMjUsIDE1NiwgMTM2LCAyMjUsIDE1NiwgMTc2LAorMjI1LCAxNTcsIDE1MiwgMjI1LCAxNTgsIDEyOCwgMjI1LCAxNTgsIDE2OCwgMjI1LCAxNTksIDE0NCwgMjI1LCAxNTksIDE4NCwgMjI1LAorMTYwLCAxNjAsIDIyNSwgMTYxLCAxMzYsIDIyNSwgMTYxLCAxNzYsIDIyNSwgMTYyLCAxNTIsIDIyNSwgMTYzLCAxMjgsIDIyNSwgMTYzLAorMTY4LCAyMjUsIDE2NCwgMTQ0LCAyMjUsIDE2NCwgMTg0LCAyMjUsIDE2NSwgMTYwLCAyMjUsIDE2NiwgMTM2LCAyMjUsIDE2NiwgMTc2LAorMjI1LCAxNjcsIDE1MiwgMjI1LCAxNjgsIDEyOCwgMjI1LCAxNjgsIDE2OCwgMjI1LCAxNjksIDE0NCwgMjI1LCAxNjksIDE4NCwgMjI1LAorMTcwLCAxNjAsIDIyNSwgMTcxLCAxMzYsIDIyNSwgMTcxLCAxNzYsIDIyNSwgMTcyLCAxNTIsIDIyNSwgMTczLCAxMjgsIDIyNSwgMTczLAorMTY4LCAyMjUsIDE3NCwgMTQ0LCAyMjUsIDE3NCwgMTg0LCAyMjUsIDE3NSwgMTYwLCAyMjUsIDE3NiwgMTM2LCAyMjUsIDE3NiwgMTc2LAorMjI1LCAxNzcsIDE1MiwgMjI1LCAxNzgsIDEyOCwgMjI1LCAxNzgsIDE2OCwgMjI1LCAxNzksIDE0NCwgMjI1LCAxNzksIDE4NCwgMjI1LAorMTgwLCAxNjAsIDIyNSwgMTgxLCAxMzYsIDIyNSwgMTgxLCAxNzYsIDIyNSwgMTgyLCAxNTIsIDIyNSwgMTgzLCAxMjgsIDIyNSwgMTgzLAorMTY4LCAyMjUsIDE4NCwgMTQ0LCAyMjUsIDE4NCwgMTg0LCAyMjUsIDE4NSwgMTYwLCAyMjUsIDE4NiwgMTM2LCAyMjUsIDE4NiwgMTc2LAorMjI1LCAxODcsIDE1MiwgMjI1LCAxODgsIDEyOCwgMjI1LCAxODgsIDE2OCwgMjI1LCAxODksIDE0NCwgMjI1LCAxODksIDE4NCwgMjI1LAorMTkwLCAxNjAsIDIyNSwgMTkxLCAxMzYsIDIyNSwgMTkxLCAxNzYsIDIyNiwgMTI4LCAxNTIsIDIyNiwgMTI5LCAxMjgsIDIyNiwgMTI5LAorMTY4LCAyMjYsIDEzMCwgMTQ0LCAyMjYsIDEzMCwgMTg0LCAyMjYsIDEzMSwgMTYwLCAyMjYsIDEzMiwgMTM2LCAyMjYsIDEzMiwgMTc2LAorMjI2LCAxMzMsIDE1MiwgMjI2LCAxMzQsIDEyOCwgMjI2LCAxMzQsIDE2OCwgMjI2LCAxMzUsIDE0NCwgMjI2LCAxMzUsIDE4NCwgMjI2LAorMTM2LCAxNjAsIDIyNiwgMTM3LCAxMzYsIDIyNiwgMTM3LCAxNzYsIDIyNiwgMTM4LCAxNTIsIDIyNiwgMTM5LCAxMjgsIDIyNiwgMTM5LAorMTY4LCAyMjYsIDE0MCwgMTQ0LCAyMjYsIDE0MCwgMTg0LCAyMjYsIDE0MSwgMTYwLCAyMjYsIDE0MiwgMTM2LCAyMjYsIDE0MiwgMTc2LAorMjI2LCAxNDMsIDE1MiwgMjI2LCAxNDQsIDEyOCwgMjI2LCAxNDQsIDE2OCwgMjI2LCAxNDUsIDE0NCwgMjI2LCAxNDUsIDE4NCwgMjI2LAorMTQ2LCAxNjAsIDIyNiwgMTQ3LCAxMzYsIDIyNiwgMTQ3LCAxNzYsIDIyNiwgMTQ4LCAxNTIsIDIyNiwgMTQ5LCAxMjgsIDIyNiwgMTQ5LAorMTY4LCAyMjYsIDE1MCwgMTQ0LCAyMjYsIDE1MCwgMTg0LCAyMjYsIDE1MSwgMTYwLCAyMjYsIDE1MiwgMTM2LCAyMjYsIDE1MiwgMTc2LAorMjI2LCAxNTMsIDE1MiwgMjI2LCAxNTQsIDEyOCwgMjI2LCAxNTQsIDE2OCwgMjI2LCAxNTUsIDE0NCwgMjI2LCAxNTUsIDE4NCwgMjI2LAorMTU2LCAxNjAsIDIyNiwgMTU3LCAxMzYsIDIyNiwgMTU3LCAxNzYsIDIyNiwgMTU4LCAxNTIsIDIyNiwgMTU5LCAxMjgsIDIyNiwgMTU5LAorMTY4LCAyMjYsIDE2MCwgMTQ0LCAyMjYsIDE2MCwgMTg0LCAyMjYsIDE2MSwgMTYwLCAyMjYsIDE2MiwgMTM2LCAyMjYsIDE2MiwgMTc2LAorMjI2LCAxNjMsIDE1MiwgMjI2LCAxNjQsIDEyOCwgMjI2LCAxNjQsIDE2OCwgMjI2LCAxNjUsIDE0NCwgMjI2LCAxNjUsIDE4NCwgMjI2LAorMTY2LCAxNjAsIDIyNiwgMTY3LCAxMzYsIDIyNiwgMTY3LCAxNzYsIDIyNiwgMTY4LCAxNTIsIDIyNiwgMTY5LCAxMjgsIDIyNiwgMTY5LAorMTY4LCAyMjYsIDE3MCwgMTQ0LCAyMjYsIDE3MCwgMTg0LCAyMjYsIDE3MSwgMTYwLCAyMjYsIDE3MiwgMTM2LCAyMjYsIDE3MiwgMTc2LAorMjI2LCAxNzMsIDE1MiwgMjI2LCAxNzQsIDEyOCwgMjI2LCAxNzQsIDE2OCwgMjI2LCAxNzUsIDE0NCwgMjI2LCAxNzUsIDE4NCwgMjI2LAorMTc2LCAxNjAsIDIyNiwgMTc3LCAxMzYsIDIyNiwgMTc3LCAxNzYsIDIyNiwgMTc4LCAxNTIsIDIyNiwgMTc5LCAxMjgsIDIyNiwgMTc5LAorMTY4LCAyMjYsIDE4MCwgMTQ0LCAyMjYsIDE4MCwgMTg0LCAyMjYsIDE4MSwgMTYwLCAyMjYsIDE4MiwgMTM2LCAyMjYsIDE4MiwgMTc2LAorMjI2LCAxODMsIDE1MiwgMjI2LCAxODQsIDEyOCwgMjI2LCAxODQsIDE2OCwgMjI2LCAxODUsIDE0NCwgMjI2LCAxODUsIDE4NCwgMjI2LAorMTg2LCAxNjAsIDIyNiwgMTg3LCAxMzYsIDIyNiwgMTg3LCAxNzYsIDIyNiwgMTg4LCAxNTIsIDIyNiwgMTg5LCAxMjgsIDIyNiwgMTg5LAorMTY4LCAyMjYsIDE5MCwgMTQ0LCAyMjYsIDE5MCwgMTg0LCAyMjYsIDE5MSwgMTYwLCAyMjcsIDEyOCwgMTM2LCAyMjcsIDEyOCwgMTc2LAorMjI3LCAxMjksIDE1MiwgMjI3LCAxMzAsIDEyOCwgMjI3LCAxMzAsIDE2OCwgMjI3LCAxMzEsIDE0NCwgMjI3LCAxMzEsIDE4NCwgMjI3LAorMTMyLCAxNjAsIDIyNywgMTMzLCAxMzYsIDIyNywgMTMzLCAxNzYsIDIyNywgMTM0LCAxNTIsIDIyNywgMTM1LCAxMjgsIDIyNywgMTM1LAorMTY4LCAyMjcsIDEzNiwgMTQ0LCAyMjcsIDEzNiwgMTg0LCAyMjcsIDEzNywgMTYwLCAyMjcsIDEzOCwgMTM2LCAyMjcsIDEzOCwgMTc2LAorMjI3LCAxMzksIDE1MiwgMjI3LCAxNDAsIDEyOCwgMjI3LCAxNDAsIDE2OCwgMjI3LCAxNDEsIDE0NCwgMjI3LCAxNDEsIDE4NCwgMjI3LAorMTQyLCAxNjAsIDIyNywgMTQzLCAxMzYsIDIyNywgMTQzLCAxNzYsIDIyNywgMTQ0LCAxNTIsIDIyNywgMTQ1LCAxMjgsIDIyNywgMTQ1LAorMTY4LCAyMjcsIDE0NiwgMTQ0LCAyMjcsIDE0NiwgMTg0LCAyMjcsIDE0NywgMTYwLCAyMjcsIDE0OCwgMTM2LCAyMjcsIDE0OCwgMTc2LAorMjI3LCAxNDksIDE1MiwgMjI3LCAxNTAsIDEyOCwgMjI3LCAxNTAsIDE2OCwgMjI3LCAxNTEsIDE0NCwgMjI3LCAxNTEsIDE4NCwgMjI3LAorMTUyLCAxNjAsIDIyNywgMTUzLCAxMzYsIDIyNywgMTUzLCAxNzYsIDIyNywgMTU0LCAxNTIsIDIyNywgMTU1LCAxMjgsIDIyNywgMTU1LAorMTY4LCAyMjcsIDE1NiwgMTQ0LCAyMjcsIDE1NiwgMTg0LCAyMjcsIDE1NywgMTYwLCAyMjcsIDE1OCwgMTM2LCAyMjcsIDE1OCwgMTc2LAorMjI3LCAxNTksIDE1MiwgMjI3LCAxNjAsIDEyOCwgMjI3LCAxNjAsIDE2OCwgMjI3LCAxNjEsIDE0NCwgMjI3LCAxNjEsIDE4NCwgMjI3LAorMTYyLCAxNjAsIDIyNywgMTYzLCAxMzYsIDIyNywgMTYzLCAxNzYsIDIyNywgMTY0LCAxNTIsIDIyNywgMTY1LCAxMjgsIDIyNywgMTY1LAorMTY4LCAyMjcsIDE2NiwgMTQ0LCAyMjcsIDE2NiwgMTg0LCAyMjcsIDE2NywgMTYwLCAyMjcsIDE2OCwgMTM2LCAyMjcsIDE2OCwgMTc2LAorMjI3LCAxNjksIDE1MiwgMjI3LCAxNzAsIDEyOCwgMjI3LCAxNzAsIDE2OCwgMjI3LCAxNzEsIDE0NCwgMjI3LCAxNzEsIDE4NCwgMjI3LAorMTcyLCAxNjAsIDIyNywgMTczLCAxMzYsIDIyNywgMTczLCAxNzYsIDIyNywgMTc0LCAxNTIsIDIyNywgMTc1LCAxMjgsIDIyNywgMTc1LAorMTY4LCAyMjcsIDE3NiwgMTQ0LCAyMjcsIDE3NiwgMTg0LCAyMjcsIDE3NywgMTYwLCAyMjcsIDE3OCwgMTM2LCAyMjcsIDE3OCwgMTc2LAorMjI3LCAxNzksIDE1MiwgMjI3LCAxODAsIDEyOCwgMjI3LCAxODAsIDE2OCwgMjI3LCAxODEsIDE0NCwgMjI3LCAxODEsIDE4NCwgMjI3LAorMTgyLCAxNjAsIDIyNywgMTgzLCAxMzYsIDIyNywgMTgzLCAxNzYsIDIyNywgMTg0LCAxNTIsIDIyNywgMTg1LCAxMjgsIDIyNywgMTg1LAorMTY4LCAyMjcsIDE4NiwgMTQ0LCAyMjcsIDE4NiwgMTg0LCAyMjcsIDE4NywgMTYwLCAyMjcsIDE4OCwgMTM2LCAyMjcsIDE4OCwgMTc2LAorMjI3LCAxODksIDE1MiwgMjI3LCAxOTAsIDEyOCwgMjI3LCAxOTAsIDE2OCwgMjI3LCAxOTEsIDE0NCwgMjI3LCAxOTEsIDE4NCwgMjI4LAorMTI4LCAxNjAsIDIyOCwgMTI5LCAxMzYsIDIyOCwgMTI5LCAxNzYsIDIyOCwgMTMwLCAxNTIsIDIyOCwgMTMxLCAxMjgsIDIyOCwgMTMxLAorMTY4LCAyMjgsIDEzMiwgMTQ0LCAyMjgsIDEzMiwgMTg0LCAyMjgsIDEzMywgMTYwLCAyMjgsIDEzNCwgMTM2LCAyMjgsIDEzNCwgMTc2LAorMjI4LCAxMzUsIDE1MiwgMjI4LCAxMzYsIDEyOCwgMjI4LCAxMzYsIDE2OCwgMjI4LCAxMzcsIDE0NCwgMjI4LCAxMzcsIDE4NCwgMjI4LAorMTM4LCAxNjAsIDIyOCwgMTM5LCAxMzYsIDIyOCwgMTM5LCAxNzYsIDIyOCwgMTQwLCAxNTIsIDIyOCwgMTQxLCAxMjgsIDIyOCwgMTQxLAorMTY4LCAyMjgsIDE0MiwgMTQ0LCAyMjgsIDE0MiwgMTg0LCAyMjgsIDE0MywgMTYwLCAyMjgsIDE0NCwgMTM2LCAyMjgsIDE0NCwgMTc2LAorMjI4LCAxNDUsIDE1MiwgMjI4LCAxNDYsIDEyOCwgMjI4LCAxNDYsIDE2OCwgMjI4LCAxNDcsIDE0NCwgMjI4LCAxNDcsIDE4NCwgMjI4LAorMTQ4LCAxNjAsIDIyOCwgMTQ5LCAxMzYsIDIyOCwgMTQ5LCAxNzYsIDIyOCwgMTUwLCAxNTIsIDIyOCwgMTUxLCAxMjgsIDIyOCwgMTUxLAorMTY4LCAyMjgsIDE1MiwgMTQ0LCAyMjgsIDE1MiwgMTg0LCAyMjgsIDE1MywgMTYwLCAyMjgsIDE1NCwgMTM2LCAyMjgsIDE1NCwgMTc2LAorMjI4LCAxNTUsIDE1MiwgMjI4LCAxNTYsIDEyOCwgMjI4LCAxNTYsIDE2OCwgMjI4LCAxNTcsIDE0NCwgMjI4LCAxNTcsIDE4NCwgMjI4LAorMTU4LCAxNjAsIDIyOCwgMTU5LCAxMzYsIDIyOCwgMTU5LCAxNzYsIDIyOCwgMTYwLCAxNTIsIDIyOCwgMTYxLCAxMjgsIDIyOCwgMTYxLAorMTY4LCAyMjgsIDE2MiwgMTQ0LCAyMjgsIDE2MiwgMTg0LCAyMjgsIDE2MywgMTYwLCAyMjgsIDE2NCwgMTM2LCAyMjgsIDE2NCwgMTc2LAorMjI4LCAxNjUsIDE1MiwgMjI4LCAxNjYsIDEyOCwgMjI4LCAxNjYsIDE2OCwgMjI4LCAxNjcsIDE0NCwgMjI4LCAxNjcsIDE4NCwgMjI4LAorMTY4LCAxNjAsIDIyOCwgMTY5LCAxMzYsIDIyOCwgMTY5LCAxNzYsIDIyOCwgMTcwLCAxNTIsIDIyOCwgMTcxLCAxMjgsIDIyOCwgMTcxLAorMTY4LCAyMjgsIDE3MiwgMTQ0LCAyMjgsIDE3MiwgMTg0LCAyMjgsIDE3MywgMTYwLCAyMjgsIDE3NCwgMTM2LCAyMjgsIDE3NCwgMTc2LAorMjI4LCAxNzUsIDE1MiwgMjI4LCAxNzYsIDEyOCwgMjI4LCAxNzYsIDE2OCwgMjI4LCAxNzcsIDE0NCwgMjI4LCAxNzcsIDE4NCwgMjI4LAorMTc4LCAxNjAsIDIyOCwgMTc5LCAxMzYsIDIyOCwgMTc5LCAxNzYsIDIyOCwgMTgwLCAxNTIsIDIyOCwgMTgxLCAxMjgsIDIyOCwgMTgxLAorMTY4LCAyMjgsIDE4MiwgMTQ0LCAyMjgsIDE4MiwgMTg0LCAyMjgsIDE4MywgMTYwLCAyMjgsIDE4NCwgMTM2LCAyMjgsIDE4NCwgMTc2LAorMjI4LCAxODUsIDE1MiwgMjI4LCAxODYsIDEyOCwgMjI4LCAxODYsIDE2OCwgMjI4LCAxODcsIDE0NCwgMjI4LCAxODcsIDE4NCwgMjI4LAorMTg4LCAxNjAsIDIyOCwgMTg5LCAxMzYsIDIyOCwgMTg5LCAxNzYsIDIyOCwgMTkwLCAxNTIsIDIyOCwgMTkxLCAxMjgsIDIyOCwgMTkxLAorMTY4LCAyMjksIDEyOCwgMTQ0LCAyMjksIDEyOCwgMTg0LCAyMjksIDEyOSwgMTYwLCAyMjksIDEzMCwgMTM2LCAyMjksIDEzMCwgMTc2LAorMjI5LCAxMzEsIDE1MiwgMjI5LCAxMzIsIDEyOCwgMjI5LCAxMzIsIDE2OCwgMjI5LCAxMzMsIDE0NCwgMjI5LCAxMzMsIDE4NCwgMjI5LAorMTM0LCAxNjAsIDIyOSwgMTM1LCAxMzYsIDIyOSwgMTM1LCAxNzYsIDIyOSwgMTM2LCAxNTIsIDIyOSwgMTM3LCAxMjgsIDIyOSwgMTM3LAorMTY4LCAyMjksIDEzOCwgMTQ0LCAyMjksIDEzOCwgMTg0LCAyMjksIDEzOSwgMTYwLCAyMjksIDE0MCwgMTM2LCAyMjksIDE0MCwgMTc2LAorMjI5LCAxNDEsIDE1MiwgMjI5LCAxNDIsIDEyOCwgMjI5LCAxNDIsIDE2OCwgMjI5LCAxNDMsIDE0NCwgMjI5LCAxNDMsIDE4NCwgMjI5LAorMTQ0LCAxNjAsIDIyOSwgMTQ1LCAxMzYsIDIyOSwgMTQ1LCAxNzYsIDIyOSwgMTQ2LCAxNTIsIDIyOSwgMTQ3LCAxMjgsIDIyOSwgMTQ3LAorMTY4LCAyMjksIDE0OCwgMTQ0LCAyMjksIDE0OCwgMTg0LCAyMjksIDE0OSwgMTYwLCAyMjksIDE1MCwgMTM2LCAyMjksIDE1MCwgMTc2LAorMjI5LCAxNTEsIDE1MiwgMjI5LCAxNTIsIDEyOCwgMjI5LCAxNTIsIDE2OCwgMjI5LCAxNTMsIDE0NCwgMjI5LCAxNTMsIDE4NCwgMjI5LAorMTU0LCAxNjAsIDIyOSwgMTU1LCAxMzYsIDIyOSwgMTU1LCAxNzYsIDIyOSwgMTU2LCAxNTIsIDIyOSwgMTU3LCAxMjgsIDIyOSwgMTU3LAorMTY4LCAyMjksIDE1OCwgMTQ0LCAyMjksIDE1OCwgMTg0LCAyMjksIDE1OSwgMTYwLCAyMjksIDE2MCwgMTM2LCAyMjksIDE2MCwgMTc2LAorMjI5LCAxNjEsIDE1MiwgMjI5LCAxNjIsIDEyOCwgMjI5LCAxNjIsIDE2OCwgMjI5LCAxNjMsIDE0NCwgMjI5LCAxNjMsIDE4NCwgMjI5LAorMTY0LCAxNjAsIDIyOSwgMTY1LCAxMzYsIDIyOSwgMTY1LCAxNzYsIDIyOSwgMTY2LCAxNTIsIDIyOSwgMTY3LCAxMjgsIDIyOSwgMTY3LAorMTY4LCAyMjksIDE2OCwgMTQ0LCAyMjksIDE2OCwgMTg0LCAyMjksIDE2OSwgMTYwLCAyMjksIDE3MCwgMTM2LCAyMjksIDE3MCwgMTc2LAorMjI5LCAxNzEsIDE1MiwgMjI5LCAxNzIsIDEyOCwgMjI5LCAxNzIsIDE2OCwgMjI5LCAxNzMsIDE0NCwgMjI5LCAxNzMsIDE4NCwgMjI5LAorMTc0LCAxNjAsIDIyOSwgMTc1LCAxMzYsIDIyOSwgMTc1LCAxNzYsIDIyOSwgMTc2LCAxNTIsIDIyOSwgMTc3LCAxMjgsIDIyOSwgMTc3LAorMTY4LCAyMjksIDE3OCwgMTQ0LCAyMjksIDE3OCwgMTg0LCAyMjksIDE3OSwgMTYwLCAyMjksIDE4MCwgMTM2LCAyMjksIDE4MCwgMTc2LAorMjI5LCAxODEsIDE1MiwgMjI5LCAxODIsIDEyOCwgMjI5LCAxODIsIDE2OCwgMjI5LCAxODMsIDE0NCwgMjI5LCAxODMsIDE4NCwgMjI5LAorMTg0LCAxNjAsIDIyOSwgMTg1LCAxMzYsIDIyOSwgMTg1LCAxNzYsIDIyOSwgMTg2LCAxNTIsIDIyOSwgMTg3LCAxMjgsIDIyOSwgMTg3LAorMTY4LCAyMjksIDE4OCwgMTQ0LCAyMjksIDE4OCwgMTg0LCAyMjksIDE4OSwgMTYwLCAyMjksIDE5MCwgMTM2LCAyMjksIDE5MCwgMTc2LAorMjI5LCAxOTEsIDE1MiwgMjMwLCAxMjgsIDEyOCwgMjMwLCAxMjgsIDE2OCwgMjMwLCAxMjksIDE0NCwgMjMwLCAxMjksIDE4NCwgMjMwLAorMTMwLCAxNjAsIDIzMCwgMTMxLCAxMzYsIDIzMCwgMTMxLCAxNzYsIDIzMCwgMTMyLCAxNTIsIDIzMCwgMTMzLCAxMjgsIDIzMCwgMTMzLAorMTY4LCAyMzAsIDEzNCwgMTQ0LCAyMzAsIDEzNCwgMTg0LCAyMzAsIDEzNSwgMTYwLCAyMzAsIDEzNiwgMTM2LCAyMzAsIDEzNiwgMTc2LAorMjMwLCAxMzcsIDE1MiwgMjMwLCAxMzgsIDEyOCwgMjMwLCAxMzgsIDE2OCwgMjMwLCAxMzksIDE0NCwgMjMwLCAxMzksIDE4NCwgMjMwLAorMTQwLCAxNjAsIDIzMCwgMTQxLCAxMzYsIDIzMCwgMTQxLCAxNzYsIDIzMCwgMTQyLCAxNTIsIDIzMCwgMTQzLCAxMjgsIDIzMCwgMTQzLAorMTY4LCAyMzAsIDE0NCwgMTQ0LCAyMzAsIDE0NCwgMTg0LCAyMzAsIDE0NSwgMTYwLCAyMzAsIDE0NiwgMTM2LCAyMzAsIDE0NiwgMTc2LAorMjMwLCAxNDcsIDE1MiwgMjMwLCAxNDgsIDEyOCwgMjMwLCAxNDgsIDE2OCwgMjMwLCAxNDksIDE0NCwgMjMwLCAxNDksIDE4NCwgMjMwLAorMTUwLCAxNjAsIDIzMCwgMTUxLCAxMzYsIDIzMCwgMTUxLCAxNzYsIDIzMCwgMTUyLCAxNTIsIDIzMCwgMTUzLCAxMjgsIDIzMCwgMTUzLAorMTY4LCAyMzAsIDE1NCwgMTQ0LCAyMzAsIDE1NCwgMTg0LCAyMzAsIDE1NSwgMTYwLCAyMzAsIDE1NiwgMTM2LCAyMzAsIDE1NiwgMTc2LAorMjMwLCAxNTcsIDE1MiwgMjMwLCAxNTgsIDEyOCwgMjMwLCAxNTgsIDE2OCwgMjMwLCAxNTksIDE0NCwgMjMwLCAxNTksIDE4NCwgMjMwLAorMTYwLCAxNjAsIDIzMCwgMTYxLCAxMzYsIDIzMCwgMTYxLCAxNzYsIDIzMCwgMTYyLCAxNTIsIDIzMCwgMTYzLCAxMjgsIDIzMCwgMTYzLAorMTY4LCAyMzAsIDE2NCwgMTQ0LCAyMzAsIDE2NCwgMTg0LCAyMzAsIDE2NSwgMTYwLCAyMzAsIDE2NiwgMTM2LCAyMzAsIDE2NiwgMTc2LAorMjMwLCAxNjcsIDE1MiwgMjMwLCAxNjgsIDEyOCwgMjMwLCAxNjgsIDE2OCwgMjMwLCAxNjksIDE0NCwgMjMwLCAxNjksIDE4NCwgMjMwLAorMTcwLCAxNjAsIDIzMCwgMTcxLCAxMzYsIDIzMCwgMTcxLCAxNzYsIDIzMCwgMTcyLCAxNTIsIDIzMCwgMTczLCAxMjgsIDIzMCwgMTczLAorMTY4LCAyMzAsIDE3NCwgMTQ0LCAyMzAsIDE3NCwgMTg0LCAyMzAsIDE3NSwgMTYwLCAyMzAsIDE3NiwgMTM2LCAyMzAsIDE3NiwgMTc2LAorMjMwLCAxNzcsIDE1MiwgMjMwLCAxNzgsIDEyOCwgMjMwLCAxNzgsIDE2OCwgMjMwLCAxNzksIDE0NCwgMjMwLCAxNzksIDE4NCwgMjMwLAorMTgwLCAxNjAsIDIzMCwgMTgxLCAxMzYsIDIzMCwgMTgxLCAxNzYsIDIzMCwgMTgyLCAxNTIsIDIzMCwgMTgzLCAxMjgsIDIzMCwgMTgzLAorMTY4LCAyMzAsIDE4NCwgMTQ0LCAyMzAsIDE4NCwgMTg0LCAyMzAsIDE4NSwgMTYwLCAyMzAsIDE4NiwgMTM2LCAyMzAsIDE4NiwgMTc2LAorMjMwLCAxODcsIDE1MiwgMjMwLCAxODgsIDEyOCwgMjMwLCAxODgsIDE2OCwgMjMwLCAxODksIDE0NCwgMjMwLCAxODksIDE4NCwgMjMwLAorMTkwLCAxNjAsIDIzMCwgMTkxLCAxMzYsIDIzMCwgMTkxLCAxNzYsIDIzMSwgMTI4LCAxNTIsIDIzMSwgMTI5LCAxMjgsIDIzMSwgMTI5LAorMTY4LCAyMzEsIDEzMCwgMTQ0LCAyMzEsIDEzMCwgMTg0LCAyMzEsIDEzMSwgMTYwLCAyMzEsIDEzMiwgMTM2LCAyMzEsIDEzMiwgMTc2LAorMjMxLCAxMzMsIDE1MiwgMjMxLCAxMzQsIDEyOCwgMjMxLCAxMzQsIDE2OCwgMjMxLCAxMzUsIDE0NCwgMjMxLCAxMzUsIDE4NCwgMjMxLAorMTM2LCAxNjAsIDIzMSwgMTM3LCAxMzYsIDIzMSwgMTM3LCAxNzYsIDIzMSwgMTM4LCAxNTIsIDIzMSwgMTM5LCAxMjgsIDIzMSwgMTM5LAorMTY4LCAyMzEsIDE0MCwgMTQ0LCAyMzEsIDE0MCwgMTg0LCAyMzEsIDE0MSwgMTYwLCAyMzEsIDE0MiwgMTM2LCAyMzEsIDE0MiwgMTc2LAorMjMxLCAxNDMsIDE1MiwgMjMxLCAxNDQsIDEyOCwgMjMxLCAxNDQsIDE2OCwgMjMxLCAxNDUsIDE0NCwgMjMxLCAxNDUsIDE4NCwgMjMxLAorMTQ2LCAxNjAsIDIzMSwgMTQ3LCAxMzYsIDIzMSwgMTQ3LCAxNzYsIDIzMSwgMTQ4LCAxNTIsIDIzMSwgMTQ5LCAxMjgsIDIzMSwgMTQ5LAorMTY4LCAyMzEsIDE1MCwgMTQ0LCAyMzEsIDE1MCwgMTg0LCAyMzEsIDE1MSwgMTYwLCAyMzEsIDE1MiwgMTM2LCAyMzEsIDE1MiwgMTc2LAorMjMxLCAxNTMsIDE1MiwgMjMxLCAxNTQsIDEyOCwgMjMxLCAxNTQsIDE2OCwgMjMxLCAxNTUsIDE0NCwgMjMxLCAxNTUsIDE4NCwgMjMxLAorMTU2LCAxNjAsIDIzMSwgMTU3LCAxMzYsIDIzMSwgMTU3LCAxNzYsIDIzMSwgMTU4LCAxNTIsIDIzMSwgMTU5LCAxMjgsIDIzMSwgMTU5LAorMTY4LCAyMzEsIDE2MCwgMTQ0LCAyMzEsIDE2MCwgMTg0LCAyMzEsIDE2MSwgMTYwLCAyMzEsIDE2MiwgMTM2LCAyMzEsIDE2MiwgMTc2LAorMjMxLCAxNjMsIDE1MiwgMjMxLCAxNjQsIDEyOCwgMjMxLCAxNjQsIDE2OCwgMjMxLCAxNjUsIDE0NCwgMjMxLCAxNjUsIDE4NCwgMjMxLAorMTY2LCAxNjAsIDIzMSwgMTY3LCAxMzYsIDIzMSwgMTY3LCAxNzYsIDIzMSwgMTY4LCAxNTIsIDIzMSwgMTY5LCAxMjgsIDIzMSwgMTY5LAorMTY4LCAyMzEsIDE3MCwgMTQ0LCAyMzEsIDE3MCwgMTg0LCAyMzEsIDE3MSwgMTYwLCAyMzEsIDE3MiwgMTM2LCAyMzEsIDE3MiwgMTc2LAorMjMxLCAxNzMsIDE1MiwgMjMxLCAxNzQsIDEyOCwgMjMxLCAxNzQsIDE2OCwgMjMxLCAxNzUsIDE0NCwgMjMxLCAxNzUsIDE4NCwgMjMxLAorMTc2LCAxNjAsIDIzMSwgMTc3LCAxMzYsIDIzMSwgMTc3LCAxNzYsIDIzMSwgMTc4LCAxNTIsIDIzMSwgMTc5LCAxMjgsIDIzMSwgMTc5LAorMTY4LCAyMzEsIDE4MCwgMTQ0LCAyMzEsIDE4MCwgMTg0LCAyMzEsIDE4MSwgMTYwLCAyMzEsIDE4MiwgMTM2LCAyMzEsIDE4MiwgMTc2LAorMjMxLCAxODMsIDE1MiwgMjMxLCAxODQsIDEyOCwgMjMxLCAxODQsIDE2OCwgMjMxLCAxODUsIDE0NCwgMjMxLCAxODUsIDE4NCwgMjMxLAorMTg2LCAxNjAsIDIzMSwgMTg3LCAxMzYsIDIzMSwgMTg3LCAxNzYsIDIzMSwgMTg4LCAxNTIsIDIzMSwgMTg5LCAxMjgsIDIzMSwgMTg5LAorMTY4LCAyMzEsIDE5MCwgMTQ0LCAyMzEsIDE5MCwgMTg0LCAyMzEsIDE5MSwgMTYwLCAyMzIsIDEyOCwgMTM2LCAyMzIsIDEyOCwgMTc2LAorMjMyLCAxMjksIDE1MiwgMjMyLCAxMzAsIDEyOCwgMjMyLCAxMzAsIDE2OCwgMjMyLCAxMzEsIDE0NCwgMjMyLCAxMzEsIDE4NCwgMjMyLAorMTMyLCAxNjAsIDIzMiwgMTMzLCAxMzYsIDIzMiwgMTMzLCAxNzYsIDIzMiwgMTM0LCAxNTIsIDIzMiwgMTM1LCAxMjgsIDIzMiwgMTM1LAorMTY4LCAyMzIsIDEzNiwgMTQ0LCAyMzIsIDEzNiwgMTg0LCAyMzIsIDEzNywgMTYwLCAyMzIsIDEzOCwgMTM2LCAyMzIsIDEzOCwgMTc2LAorMjMyLCAxMzksIDE1MiwgMjMyLCAxNDAsIDEyOCwgMjMyLCAxNDAsIDE2OCwgMjMyLCAxNDEsIDE0NCwgMjMyLCAxNDEsIDE4NCwgMjMyLAorMTQyLCAxNjAsIDIzMiwgMTQzLCAxMzYsIDIzMiwgMTQzLCAxNzYsIDIzMiwgMTQ0LCAxNTIsIDIzMiwgMTQ1LCAxMjgsIDIzMiwgMTQ1LAorMTY4LCAyMzIsIDE0NiwgMTQ0LCAyMzIsIDE0NiwgMTg0LCAyMzIsIDE0NywgMTYwLCAyMzIsIDE0OCwgMTM2LCAyMzIsIDE0OCwgMTc2LAorMjMyLCAxNDksIDE1MiwgMjMyLCAxNTAsIDEyOCwgMjMyLCAxNTAsIDE2OCwgMjMyLCAxNTEsIDE0NCwgMjMyLCAxNTEsIDE4NCwgMjMyLAorMTUyLCAxNjAsIDIzMiwgMTUzLCAxMzYsIDIzMiwgMTUzLCAxNzYsIDIzMiwgMTU0LCAxNTIsIDIzMiwgMTU1LCAxMjgsIDIzMiwgMTU1LAorMTY4LCAyMzIsIDE1NiwgMTQ0LCAyMzIsIDE1NiwgMTg0LCAyMzIsIDE1NywgMTYwLCAyMzIsIDE1OCwgMTM2LCAyMzIsIDE1OCwgMTc2LAorMjMyLCAxNTksIDE1MiwgMjMyLCAxNjAsIDEyOCwgMjMyLCAxNjAsIDE2OCwgMjMyLCAxNjEsIDE0NCwgMjMyLCAxNjEsIDE4NCwgMjMyLAorMTYyLCAxNjAsIDIzMiwgMTYzLCAxMzYsIDIzMiwgMTYzLCAxNzYsIDIzMiwgMTY0LCAxNTIsIDIzMiwgMTY1LCAxMjgsIDIzMiwgMTY1LAorMTY4LCAyMzIsIDE2NiwgMTQ0LCAyMzIsIDE2NiwgMTg0LCAyMzIsIDE2NywgMTYwLCAyMzIsIDE2OCwgMTM2LCAyMzIsIDE2OCwgMTc2LAorMjMyLCAxNjksIDE1MiwgMjMyLCAxNzAsIDEyOCwgMjMyLCAxNzAsIDE2OCwgMjMyLCAxNzEsIDE0NCwgMjMyLCAxNzEsIDE4NCwgMjMyLAorMTcyLCAxNjAsIDIzMiwgMTczLCAxMzYsIDIzMiwgMTczLCAxNzYsIDIzMiwgMTc0LCAxNTIsIDIzMiwgMTc1LCAxMjgsIDIzMiwgMTc1LAorMTY4LCAyMzIsIDE3NiwgMTQ0LCAyMzIsIDE3NiwgMTg0LCAyMzIsIDE3NywgMTYwLCAyMzIsIDE3OCwgMTM2LCAyMzIsIDE3OCwgMTc2LAorMjMyLCAxNzksIDE1MiwgMjMyLCAxODAsIDEyOCwgMjMyLCAxODAsIDE2OCwgMjMyLCAxODEsIDE0NCwgMjMyLCAxODEsIDE4NCwgMjMyLAorMTgyLCAxNjAsIDIzMiwgMTgzLCAxMzYsIDIzMiwgMTgzLCAxNzYsIDIzMiwgMTg0LCAxNTIsIDIzMiwgMTg1LCAxMjgsIDIzMiwgMTg1LAorMTY4LCAyMzIsIDE4NiwgMTQ0LCAyMzIsIDE4NiwgMTg0LCAyMzIsIDE4NywgMTYwLCAyMzIsIDE4OCwgMTM2LCAyMzIsIDE4OCwgMTc2LAorMjMyLCAxODksIDE1MiwgMjMyLCAxOTAsIDEyOCwgMjMyLCAxOTAsIDE2OCwgMjMyLCAxOTEsIDE0NCwgMjMyLCAxOTEsIDE4NCwgMjMzLAorMTI4LCAxNjAsIDIzMywgMTI5LCAxMzYsIDIzMywgMTI5LCAxNzYsIDIzMywgMTMwLCAxNTIsIDIzMywgMTMxLCAxMjgsIDIzMywgMTMxLAorMTY4LCAyMzMsIDEzMiwgMTQ0LCAyMzMsIDEzMiwgMTg0LCAyMzMsIDEzMywgMTYwLCAyMzMsIDEzNCwgMTM2LCAyMzMsIDEzNCwgMTc2LAorMjMzLCAxMzUsIDE1MiwgMjMzLCAxMzYsIDEyOCwgMjMzLCAxMzYsIDE2OCwgMjMzLCAxMzcsIDE0NCwgMjMzLCAxMzcsIDE4NCwgMjMzLAorMTM4LCAxNjAsIDIzMywgMTM5LCAxMzYsIDIzMywgMTM5LCAxNzYsIDIzMywgMTQwLCAxNTIsIDIzMywgMTQxLCAxMjgsIDIzMywgMTQxLAorMTY4LCAyMzMsIDE0MiwgMTQ0LCAyMzMsIDE0MiwgMTg0LCAyMzMsIDE0MywgMTYwLCAyMzMsIDE0NCwgMTM2LCAyMzMsIDE0NCwgMTc2LAorMjMzLCAxNDUsIDE1MiwgMjMzLCAxNDYsIDEyOCwgMjMzLCAxNDYsIDE2OCwgMjMzLCAxNDcsIDE0NCwgMjMzLCAxNDcsIDE4NCwgMjMzLAorMTQ4LCAxNjAsIDIzMywgMTQ5LCAxMzYsIDIzMywgMTQ5LCAxNzYsIDIzMywgMTUwLCAxNTIsIDIzMywgMTUxLCAxMjgsIDIzMywgMTUxLAorMTY4LCAyMzMsIDE1MiwgMTQ0LCAyMzMsIDE1MiwgMTg0LCAyMzMsIDE1MywgMTYwLCAyMzMsIDE1NCwgMTM2LCAyMzMsIDE1NCwgMTc2LAorMjMzLCAxNTUsIDE1MiwgMjMzLCAxNTYsIDEyOCwgMjMzLCAxNTYsIDE2OCwgMjMzLCAxNTcsIDE0NCwgMjMzLCAxNTcsIDE4NCwgMjMzLAorMTU4LCAxNjAsIDIzMywgMTU5LCAxMzYsIDIzMywgMTU5LCAxNzYsIDIzMywgMTYwLCAxNTIsIDIzMywgMTYxLCAxMjgsIDIzMywgMTYxLAorMTY4LCAyMzMsIDE2MiwgMTQ0LCAyMzMsIDE2MiwgMTg0LCAyMzMsIDE2MywgMTYwLCAyMzMsIDE2NCwgMTM2LCAyMzMsIDE2NCwgMTc2LAorMjMzLCAxNjUsIDE1MiwgMjMzLCAxNjYsIDEyOCwgMjMzLCAxNjYsIDE2OCwgMjMzLCAxNjcsIDE0NCwgMjMzLCAxNjcsIDE4NCwgMjMzLAorMTY4LCAxNjAsIDIzMywgMTY5LCAxMzYsIDIzMywgMTY5LCAxNzYsIDIzMywgMTcwLCAxNTIsIDIzMywgMTcxLCAxMjgsIDIzMywgMTcxLAorMTY4LCAyMzMsIDE3MiwgMTQ0LCAyMzMsIDE3MiwgMTg0LCAyMzMsIDE3MywgMTYwLCAyMzMsIDE3NCwgMTM2LCAyMzMsIDE3NCwgMTc2LAorMjMzLCAxNzUsIDE1MiwgMjMzLCAxNzYsIDEyOCwgMjMzLCAxNzYsIDE2OCwgMjMzLCAxNzcsIDE0NCwgMjMzLCAxNzcsIDE4NCwgMjMzLAorMTc4LCAxNjAsIDIzMywgMTc5LCAxMzYsIDIzMywgMTc5LCAxNzYsIDIzMywgMTgwLCAxNTIsIDIzMywgMTgxLCAxMjgsIDIzMywgMTgxLAorMTY4LCAyMzMsIDE4MiwgMTQ0LCAyMzMsIDE4MiwgMTg0LCAyMzMsIDE4MywgMTYwLCAyMzMsIDE4NCwgMTM2LCAyMzMsIDE4NCwgMTc2LAorMjMzLCAxODUsIDE1MiwgMjMzLCAxODYsIDEyOCwgMjMzLCAxODYsIDE2OCwgMjMzLCAxODcsIDE0NCwgMjMzLCAxODcsIDE4NCwgMjMzLAorMTg4LCAxNjAsIDIzMywgMTg5LCAxMzYsIDIzMywgMTg5LCAxNzYsIDIzMywgMTkwLCAxNTIsIDIzMywgMTkxLCAxMjgsIDIzMywgMTkxLAorMTY4LCAyMzQsIDEyOCwgMTQ0LCAyMzQsIDEyOCwgMTg0LCAyMzQsIDEyOSwgMTYwLCAyMzQsIDEzMCwgMTM2LCAyMzQsIDEzMCwgMTc2LAorMjM0LCAxMzEsIDE1MiwgMjM0LCAxMzIsIDEyOCwgMjM0LCAxMzIsIDE2OCwgMjM0LCAxMzMsIDE0NCwgMjM0LCAxMzMsIDE4NCwgMjM0LAorMTM0LCAxNjAsIDIzNCwgMTM1LCAxMzYsIDIzNCwgMTM1LCAxNzYsIDIzNCwgMTM2LCAxNTIsIDIzNCwgMTM3LCAxMjgsIDIzNCwgMTM3LAorMTY4LCAyMzQsIDEzOCwgMTQ0LCAyMzQsIDEzOCwgMTg0LCAyMzQsIDEzOSwgMTYwLCAyMzQsIDE0MCwgMTM2LCAyMzQsIDE0MCwgMTc2LAorMjM0LCAxNDEsIDE1MiwgMjM0LCAxNDIsIDEyOCwgMjM0LCAxNDIsIDE2OCwgMjM0LCAxNDMsIDE0NCwgMjM0LCAxNDMsIDE4NCwgMjM0LAorMTQ0LCAxNjAsIDIzNCwgMTQ1LCAxMzYsIDIzNCwgMTQ1LCAxNzYsIDIzNCwgMTQ2LCAxNTIsIDIzNCwgMTQ3LCAxMjgsIDIzNCwgMTQ3LAorMTY4LCAyMzQsIDE0OCwgMTQ0LCAyMzQsIDE0OCwgMTg0LCAyMzQsIDE0OSwgMTYwLCAyMzQsIDE1MCwgMTM2LCAyMzQsIDE1MCwgMTc2LAorMjM0LCAxNTEsIDE1MiwgMjM0LCAxNTIsIDEyOCwgMjM0LCAxNTIsIDE2OCwgMjM0LCAxNTMsIDE0NCwgMjM0LCAxNTMsIDE4NCwgMjM0LAorMTU0LCAxNjAsIDIzNCwgMTU1LCAxMzYsIDIzNCwgMTU1LCAxNzYsIDIzNCwgMTU2LCAxNTIsIDIzNCwgMTU3LCAxMjgsIDIzNCwgMTU3LAorMTY4LCAyMzQsIDE1OCwgMTQ0LCAyMzQsIDE1OCwgMTg0LCAyMzQsIDE1OSwgMTYwLCAyMzQsIDE2MCwgMTM2LCAyMzQsIDE2MCwgMTc2LAorMjM0LCAxNjEsIDE1MiwgMjM0LCAxNjIsIDEyOCwgMjM0LCAxNjIsIDE2OCwgMjM0LCAxNjMsIDE0NCwgMjM0LCAxNjMsIDE4NCwgMjM0LAorMTY0LCAxNjAsIDIzNCwgMTY1LCAxMzYsIDIzNCwgMTY1LCAxNzYsIDIzNCwgMTY2LCAxNTIsIDIzNCwgMTY3LCAxMjgsIDIzNCwgMTY3LAorMTY4LCAyMzQsIDE2OCwgMTQ0LCAyMzQsIDE2OCwgMTg0LCAyMzQsIDE2OSwgMTYwLCAyMzQsIDE3MCwgMTM2LCAyMzQsIDE3MCwgMTc2LAorMjM0LCAxNzEsIDE1MiwgMjM0LCAxNzIsIDEyOCwgMjM0LCAxNzIsIDE2OCwgMjM0LCAxNzMsIDE0NCwgMjM0LCAxNzMsIDE4NCwgMjM0LAorMTc0LCAxNjAsIDIzNCwgMTc1LCAxMzYsIDIzNCwgMTc1LCAxNzYsIDIzNCwgMTc2LCAxNTIsIDIzNCwgMTc3LCAxMjgsIDIzNCwgMTc3LAorMTY4LCAyMzQsIDE3OCwgMTQ0LCAyMzQsIDE3OCwgMTg0LCAyMzQsIDE3OSwgMTYwLCAyMzQsIDE4MCwgMTM2LCAyMzQsIDE4MCwgMTc2LAorMjM0LCAxODEsIDE1MiwgMjM0LCAxODIsIDEyOCwgMjM0LCAxODIsIDE2OCwgMjM0LCAxODMsIDE0NCwgMjM0LCAxODMsIDE4NCwgMjM0LAorMTg0LCAxNjAsIDIzNCwgMTg1LCAxMzYsIDIzNCwgMTg1LCAxNzYsIDIzNCwgMTg2LCAxNTIsIDIzNCwgMTg3LCAxMjgsIDIzNCwgMTg3LAorMTY4LCAyMzQsIDE4OCwgMTQ0LCAyMzQsIDE4OCwgMTg0LCAyMzQsIDE4OSwgMTYwLCAyMzQsIDE5MCwgMTM2LCAyMzQsIDE5MCwgMTc2LAorMjM0LCAxOTEsIDE1MiwgMjM1LCAxMjgsIDEyOCwgMjM1LCAxMjgsIDE2OCwgMjM1LCAxMjksIDE0NCwgMjM1LCAxMjksIDE4NCwgMjM1LAorMTMwLCAxNjAsIDIzNSwgMTMxLCAxMzYsIDIzNSwgMTMxLCAxNzYsIDIzNSwgMTMyLCAxNTIsIDIzNSwgMTMzLCAxMjgsIDIzNSwgMTMzLAorMTY4LCAyMzUsIDEzNCwgMTQ0LCAyMzUsIDEzNCwgMTg0LCAyMzUsIDEzNSwgMTYwLCAyMzUsIDEzNiwgMTM2LCAyMzUsIDEzNiwgMTc2LAorMjM1LCAxMzcsIDE1MiwgMjM1LCAxMzgsIDEyOCwgMjM1LCAxMzgsIDE2OCwgMjM1LCAxMzksIDE0NCwgMjM1LCAxMzksIDE4NCwgMjM1LAorMTQwLCAxNjAsIDIzNSwgMTQxLCAxMzYsIDIzNSwgMTQxLCAxNzYsIDIzNSwgMTQyLCAxNTIsIDIzNSwgMTQzLCAxMjgsIDIzNSwgMTQzLAorMTY4LCAyMzUsIDE0NCwgMTQ0LCAyMzUsIDE0NCwgMTg0LCAyMzUsIDE0NSwgMTYwLCAyMzUsIDE0NiwgMTM2LCAyMzUsIDE0NiwgMTc2LAorMjM1LCAxNDcsIDE1MiwgMjM1LCAxNDgsIDEyOCwgMjM1LCAxNDgsIDE2OCwgMjM1LCAxNDksIDE0NCwgMjM1LCAxNDksIDE4NCwgMjM1LAorMTUwLCAxNjAsIDIzNSwgMTUxLCAxMzYsIDIzNSwgMTUxLCAxNzYsIDIzNSwgMTUyLCAxNTIsIDIzNSwgMTUzLCAxMjgsIDIzNSwgMTUzLAorMTY4LCAyMzUsIDE1NCwgMTQ0LCAyMzUsIDE1NCwgMTg0LCAyMzUsIDE1NSwgMTYwLCAyMzUsIDE1NiwgMTM2LCAyMzUsIDE1NiwgMTc2LAorMjM1LCAxNTcsIDE1MiwgMjM1LCAxNTgsIDEyOCwgMjM1LCAxNTgsIDE2OCwgMjM1LCAxNTksIDE0NCwgMjM1LCAxNTksIDE4NCwgMjM1LAorMTYwLCAxNjAsIDIzNSwgMTYxLCAxMzYsIDIzNSwgMTYxLCAxNzYsIDIzNSwgMTYyLCAxNTIsIDIzNSwgMTYzLCAxMjgsIDIzNSwgMTYzLAorMTY4LCAyMzUsIDE2NCwgMTQ0LCAyMzUsIDE2NCwgMTg0LCAyMzUsIDE2NSwgMTYwLCAyMzUsIDE2NiwgMTM2LCAyMzUsIDE2NiwgMTc2LAorMjM1LCAxNjcsIDE1MiwgMjM1LCAxNjgsIDEyOCwgMjM1LCAxNjgsIDE2OCwgMjM1LCAxNjksIDE0NCwgMjM1LCAxNjksIDE4NCwgMjM1LAorMTcwLCAxNjAsIDIzNSwgMTcxLCAxMzYsIDIzNSwgMTcxLCAxNzYsIDIzNSwgMTcyLCAxNTIsIDIzNSwgMTczLCAxMjgsIDIzNSwgMTczLAorMTY4LCAyMzUsIDE3NCwgMTQ0LCAyMzUsIDE3NCwgMTg0LCAyMzUsIDE3NSwgMTYwLCAyMzUsIDE3NiwgMTM2LCAyMzUsIDE3NiwgMTc2LAorMjM1LCAxNzcsIDE1MiwgMjM1LCAxNzgsIDEyOCwgMjM1LCAxNzgsIDE2OCwgMjM1LCAxNzksIDE0NCwgMjM1LCAxNzksIDE4NCwgMjM1LAorMTgwLCAxNjAsIDIzNSwgMTgxLCAxMzYsIDIzNSwgMTgxLCAxNzYsIDIzNSwgMTgyLCAxNTIsIDIzNSwgMTgzLCAxMjgsIDIzNSwgMTgzLAorMTY4LCAyMzUsIDE4NCwgMTQ0LCAyMzUsIDE4NCwgMTg0LCAyMzUsIDE4NSwgMTYwLCAyMzUsIDE4NiwgMTM2LCAyMzUsIDE4NiwgMTc2LAorMjM1LCAxODcsIDE1MiwgMjM1LCAxODgsIDEyOCwgMjM1LCAxODgsIDE2OCwgMjM1LCAxODksIDE0NCwgMjM1LCAxODksIDE4NCwgMjM1LAorMTkwLCAxNjAsIDIzNSwgMTkxLCAxMzYsIDIzNSwgMTkxLCAxNzYsIDIzNiwgMTI4LCAxNTIsIDIzNiwgMTI5LCAxMjgsIDIzNiwgMTI5LAorMTY4LCAyMzYsIDEzMCwgMTQ0LCAyMzYsIDEzMCwgMTg0LCAyMzYsIDEzMSwgMTYwLCAyMzYsIDEzMiwgMTM2LCAyMzYsIDEzMiwgMTc2LAorMjM2LCAxMzMsIDE1MiwgMjM2LCAxMzQsIDEyOCwgMjM2LCAxMzQsIDE2OCwgMjM2LCAxMzUsIDE0NCwgMjM2LCAxMzUsIDE4NCwgMjM2LAorMTM2LCAxNjAsIDIzNiwgMTM3LCAxMzYsIDIzNiwgMTM3LCAxNzYsIDIzNiwgMTM4LCAxNTIsIDIzNiwgMTM5LCAxMjgsIDIzNiwgMTM5LAorMTY4LCAyMzYsIDE0MCwgMTQ0LCAyMzYsIDE0MCwgMTg0LCAyMzYsIDE0MSwgMTYwLCAyMzYsIDE0MiwgMTM2LCAyMzYsIDE0MiwgMTc2LAorMjM2LCAxNDMsIDE1MiwgMjM2LCAxNDQsIDEyOCwgMjM2LCAxNDQsIDE2OCwgMjM2LCAxNDUsIDE0NCwgMjM2LCAxNDUsIDE4NCwgMjM2LAorMTQ2LCAxNjAsIDIzNiwgMTQ3LCAxMzYsIDIzNiwgMTQ3LCAxNzYsIDIzNiwgMTQ4LCAxNTIsIDIzNiwgMTQ5LCAxMjgsIDIzNiwgMTQ5LAorMTY4LCAyMzYsIDE1MCwgMTQ0LCAyMzYsIDE1MCwgMTg0LCAyMzYsIDE1MSwgMTYwLCAyMzYsIDE1MiwgMTM2LCAyMzYsIDE1MiwgMTc2LAorMjM2LCAxNTMsIDE1MiwgMjM2LCAxNTQsIDEyOCwgMjM2LCAxNTQsIDE2OCwgMjM2LCAxNTUsIDE0NCwgMjM2LCAxNTUsIDE4NCwgMjM2LAorMTU2LCAxNjAsIDIzNiwgMTU3LCAxMzYsIDIzNiwgMTU3LCAxNzYsIDIzNiwgMTU4LCAxNTIsIDIzNiwgMTU5LCAxMjgsIDIzNiwgMTU5LAorMTY4LCAyMzYsIDE2MCwgMTQ0LCAyMzYsIDE2MCwgMTg0LCAyMzYsIDE2MSwgMTYwLCAyMzYsIDE2MiwgMTM2LCAyMzYsIDE2MiwgMTc2LAorMjM2LCAxNjMsIDE1MiwgMjM2LCAxNjQsIDEyOCwgMjM2LCAxNjQsIDE2OCwgMjM2LCAxNjUsIDE0NCwgMjM2LCAxNjUsIDE4NCwgMjM2LAorMTY2LCAxNjAsIDIzNiwgMTY3LCAxMzYsIDIzNiwgMTY3LCAxNzYsIDIzNiwgMTY4LCAxNTIsIDIzNiwgMTY5LCAxMjgsIDIzNiwgMTY5LAorMTY4LCAyMzYsIDE3MCwgMTQ0LCAyMzYsIDE3MCwgMTg0LCAyMzYsIDE3MSwgMTYwLCAyMzYsIDE3MiwgMTM2LCAyMzYsIDE3MiwgMTc2LAorMjM2LCAxNzMsIDE1MiwgMjM2LCAxNzQsIDEyOCwgMjM2LCAxNzQsIDE2OCwgMjM2LCAxNzUsIDE0NCwgMjM2LCAxNzUsIDE4NCwgMjM2LAorMTc2LCAxNjAsIDIzNiwgMTc3LCAxMzYsIDIzNiwgMTc3LCAxNzYsIDIzNiwgMTc4LCAxNTIsIDIzNiwgMTc5LCAxMjgsIDIzNiwgMTc5LAorMTY4LCAyMzYsIDE4MCwgMTQ0LCAyMzYsIDE4MCwgMTg0LCAyMzYsIDE4MSwgMTYwLCAyMzYsIDE4MiwgMTM2LCAyMzYsIDE4MiwgMTc2LAorMjM2LCAxODMsIDE1MiwgMjM2LCAxODQsIDEyOCwgMjM2LCAxODQsIDE2OCwgMjM2LCAxODUsIDE0NCwgMjM2LCAxODUsIDE4NCwgMjM2LAorMTg2LCAxNjAsIDIzNiwgMTg3LCAxMzYsIDIzNiwgMTg3LCAxNzYsIDIzNiwgMTg4LCAxNTIsIDIzNiwgMTg5LCAxMjgsIDIzNiwgMTg5LAorMTY4LCAyMzYsIDE5MCwgMTQ0LCAyMzYsIDE5MCwgMTg0LCAyMzYsIDE5MSwgMTYwLCAyMzcsIDEyOCwgMTM2LCAyMzcsIDEyOCwgMTc2LAorMjM3LCAxMjksIDE1MiwgMjM3LCAxMzAsIDEyOCwgMjM3LCAxMzAsIDE2OCwgMjM3LCAxMzEsIDE0NCwgMjM3LCAxMzEsIDE4NCwgMjM3LAorMTMyLCAxNjAsIDIzNywgMTMzLCAxMzYsIDIzNywgMTMzLCAxNzYsIDIzNywgMTM0LCAxNTIsIDIzNywgMTM1LCAxMjgsIDIzNywgMTM1LAorMTY4LCAyMzcsIDEzNiwgMTQ0LCAyMzcsIDEzNiwgMTg0LCAyMzcsIDEzNywgMTYwLCAyMzcsIDEzOCwgMTM2LCAyMzcsIDEzOCwgMTc2LAorMjM3LCAxMzksIDE1MiwgMjM3LCAxNDAsIDEyOCwgMjM3LCAxNDAsIDE2OCwgMjM3LCAxNDEsIDE0NCwgMjM3LCAxNDEsIDE4NCwgMjM3LAorMTQyLCAxNjAsIDIzNywgMTQzLCAxMzYsIDIzNywgMTQzLCAxNzYsIDIzNywgMTQ0LCAxNTIsIDIzNywgMTQ1LCAxMjgsIDIzNywgMTQ1LAorMTY4LCAyMzcsIDE0NiwgMTQ0LCAyMzcsIDE0NiwgMTg0LCAyMzcsIDE0NywgMTYwLCAyMzcsIDE0OCwgMTM2LCAyMzcsIDE0OCwgMTc2LAorMjM3LCAxNDksIDE1MiwgMjM3LCAxNTAsIDEyOCwgMjM3LCAxNTAsIDE2OCwgMjM3LCAxNTEsIDE0NCwgMjM3LCAxNTEsIDE4NCwgMjM3LAorMTUyLCAxNjAsIDIzNywgMTUzLCAxMzYsIDIzNywgMTUzLCAxNzYsIDIzNywgMTU0LCAxNTIsIDIzNywgMTU1LCAxMjgsIDIzNywgMTU1LAorMTY4LCAyMzcsIDE1NiwgMTQ0LCAyMzcsIDE1NiwgMTg0LCAyMzcsIDE1NywgMTYwLCAyMzcsIDE1OCwgMTM2LCAyMzcsIDE1OCwgMTc2LAorMjM3LCAxNTksIDE1MiwgMjM4LCAxMjgsIDEyOCwgMjM4LCAxMjgsIDE2OCwgMjM4LCAxMjksIDE0NCwgMjM4LCAxMjksIDE4NCwgMjM4LAorMTMwLCAxNjAsIDIzOCwgMTMxLCAxMzYsIDIzOCwgMTMxLCAxNzYsIDIzOCwgMTMyLCAxNTIsIDIzOCwgMTMzLCAxMjgsIDIzOCwgMTMzLAorMTY4LCAyMzgsIDEzNCwgMTQ0LCAyMzgsIDEzNCwgMTg0LCAyMzgsIDEzNSwgMTYwLCAyMzgsIDEzNiwgMTM2LCAyMzgsIDEzNiwgMTc2LAorMjM4LCAxMzcsIDE1MiwgMjM4LCAxMzgsIDEyOCwgMjM4LCAxMzgsIDE2OCwgMjM4LCAxMzksIDE0NCwgMjM4LCAxMzksIDE4NCwgMjM4LAorMTQwLCAxNjAsIDIzOCwgMTQxLCAxMzYsIDIzOCwgMTQxLCAxNzYsIDIzOCwgMTQyLCAxNTIsIDIzOCwgMTQzLCAxMjgsIDIzOCwgMTQzLAorMTY4LCAyMzgsIDE0NCwgMTQ0LCAyMzgsIDE0NCwgMTg0LCAyMzgsIDE0NSwgMTYwLCAyMzgsIDE0NiwgMTM2LCAyMzgsIDE0NiwgMTc2LAorMjM4LCAxNDcsIDE1MiwgMjM4LCAxNDgsIDEyOCwgMjM4LCAxNDgsIDE2OCwgMjM4LCAxNDksIDE0NCwgMjM4LCAxNDksIDE4NCwgMjM4LAorMTUwLCAxNjAsIDIzOCwgMTUxLCAxMzYsIDIzOCwgMTUxLCAxNzYsIDIzOCwgMTUyLCAxNTIsIDIzOCwgMTUzLCAxMjgsIDIzOCwgMTUzLAorMTY4LCAyMzgsIDE1NCwgMTQ0LCAyMzgsIDE1NCwgMTg0LCAyMzgsIDE1NSwgMTYwLCAyMzgsIDE1NiwgMTM2LCAyMzgsIDE1NiwgMTc2LAorMjM4LCAxNTcsIDE1MiwgMjM4LCAxNTgsIDEyOCwgMjM4LCAxNTgsIDE2OCwgMjM4LCAxNTksIDE0NCwgMjM4LCAxNTksIDE4NCwgMjM4LAorMTYwLCAxNjAsIDIzOCwgMTYxLCAxMzYsIDIzOCwgMTYxLCAxNzYsIDIzOCwgMTYyLCAxNTIsIDIzOCwgMTYzLCAxMjgsIDIzOCwgMTYzLAorMTY4LCAyMzgsIDE2NCwgMTQ0LCAyMzgsIDE2NCwgMTg0LCAyMzgsIDE2NSwgMTYwLCAyMzgsIDE2NiwgMTM2LCAyMzgsIDE2NiwgMTc2LAorMjM4LCAxNjcsIDE1MiwgMjM4LCAxNjgsIDEyOCwgMjM4LCAxNjgsIDE2OCwgMjM4LCAxNjksIDE0NCwgMjM4LCAxNjksIDE4NCwgMjM4LAorMTcwLCAxNjAsIDIzOCwgMTcxLCAxMzYsIDIzOCwgMTcxLCAxNzYsIDIzOCwgMTcyLCAxNTIsIDIzOCwgMTczLCAxMjgsIDIzOCwgMTczLAorMTY4LCAyMzgsIDE3NCwgMTQ0LCAyMzgsIDE3NCwgMTg0LCAyMzgsIDE3NSwgMTYwLCAyMzgsIDE3NiwgMTM2LCAyMzgsIDE3NiwgMTc2LAorMjM4LCAxNzcsIDE1MiwgMjM4LCAxNzgsIDEyOCwgMjM4LCAxNzgsIDE2OCwgMjM4LCAxNzksIDE0NCwgMjM4LCAxNzksIDE4NCwgMjM4LAorMTgwLCAxNjAsIDIzOCwgMTgxLCAxMzYsIDIzOCwgMTgxLCAxNzYsIDIzOCwgMTgyLCAxNTIsIDIzOCwgMTgzLCAxMjgsIDIzOCwgMTgzLAorMTY4LCAyMzgsIDE4NCwgMTQ0LCAyMzgsIDE4NCwgMTg0LCAyMzgsIDE4NSwgMTYwLCAyMzgsIDE4NiwgMTM2LCAyMzgsIDE4NiwgMTc2LAorMjM4LCAxODcsIDE1MiwgMjM4LCAxODgsIDEyOCwgMjM4LCAxODgsIDE2OCwgMjM4LCAxODksIDE0NCwgMjM4LCAxODksIDE4NCwgMjM4LAorMTkwLCAxNjAsIDIzOCwgMTkxLCAxMzYsIDIzOCwgMTkxLCAxNzYsIDIzOSwgMTI4LCAxNTIsIDIzOSwgMTI5LCAxMjgsIDIzOSwgMTI5LAorMTY4LCAyMzksIDEzMCwgMTQ0LCAyMzksIDEzMCwgMTg0LCAyMzksIDEzMSwgMTYwLCAyMzksIDEzMiwgMTM2LCAyMzksIDEzMiwgMTc2LAorMjM5LCAxMzMsIDE1MiwgMjM5LCAxMzQsIDEyOCwgMjM5LCAxMzQsIDE2OCwgMjM5LCAxMzUsIDE0NCwgMjM5LCAxMzUsIDE4NCwgMjM5LAorMTM2LCAxNjAsIDIzOSwgMTM3LCAxMzYsIDIzOSwgMTM3LCAxNzYsIDIzOSwgMTM4LCAxNTIsIDIzOSwgMTM5LCAxMjgsIDIzOSwgMTM5LAorMTY4LCAyMzksIDE0MCwgMTQ0LCAyMzksIDE0MCwgMTg0LCAyMzksIDE0MSwgMTYwLCAyMzksIDE0MiwgMTM2LCAyMzksIDE0MiwgMTc2LAorMjM5LCAxNDMsIDE1MiwgMjM5LCAxNDQsIDEyOCwgMjM5LCAxNDQsIDE2OCwgMjM5LCAxNDUsIDE0NCwgMjM5LCAxNDUsIDE4NCwgMjM5LAorMTQ2LCAxNjAsIDIzOSwgMTQ3LCAxMzYsIDIzOSwgMTQ3LCAxNzYsIDIzOSwgMTQ4LCAxNTIsIDIzOSwgMTQ5LCAxMjgsIDIzOSwgMTQ5LAorMTY4LCAyMzksIDE1MCwgMTQ0LCAyMzksIDE1MCwgMTg0LCAyMzksIDE1MSwgMTYwLCAyMzksIDE1MiwgMTM2LCAyMzksIDE1MiwgMTc2LAorMjM5LCAxNTMsIDE1MiwgMjM5LCAxNTQsIDEyOCwgMjM5LCAxNTQsIDE2OCwgMjM5LCAxNTUsIDE0NCwgMjM5LCAxNTUsIDE4NCwgMjM5LAorMTU2LCAxNjAsIDIzOSwgMTU3LCAxMzYsIDIzOSwgMTU3LCAxNzYsIDIzOSwgMTU4LCAxNTIsIDIzOSwgMTU5LCAxMjgsIDIzOSwgMTU5LAorMTY4LCAyMzksIDE2MCwgMTQ0LCAyMzksIDE2MCwgMTg0LCAyMzksIDE2MSwgMTYwLCAyMzksIDE2MiwgMTM2LCAyMzksIDE2MiwgMTc2LAorMjM5LCAxNjMsIDE1MiwgMjM5LCAxNjQsIDEyOCwgMjM5LCAxNjQsIDE2OCwgMjM5LCAxNjUsIDE0NCwgMjM5LCAxNjUsIDE4NCwgMjM5LAorMTY2LCAxNjAsIDIzOSwgMTY3LCAxMzYsIDIzOSwgMTY3LCAxNzYsIDIzOSwgMTY4LCAxNTIsIDIzOSwgMTY5LCAxMjgsIDIzOSwgMTY5LAorMTY4LCAyMzksIDE3MCwgMTQ0LCAyMzksIDE3MCwgMTg0LCAyMzksIDE3MSwgMTYwLCAyMzksIDE3MiwgMTM2LCAyMzksIDE3MiwgMTc2LAorMjM5LCAxNzMsIDE1MiwgMjM5LCAxNzQsIDEyOCwgMjM5LCAxNzQsIDE2OCwgMjM5LCAxNzUsIDE0NCwgMjM5LCAxNzUsIDE4NCwgMjM5LAorMTc2LCAxNjAsIDIzOSwgMTc3LCAxMzYsIDIzOSwgMTc3LCAxNzYsIDIzOSwgMTc4LCAxNTIsIDIzOSwgMTc5LCAxMjgsIDIzOSwgMTc5LAorMTY4LCAyMzksIDE4MCwgMTQ0LCAyMzksIDE4MCwgMTg0LCAyMzksIDE4MSwgMTYwLCAyMzksIDE4MiwgMTM2LCAyMzksIDE4MiwgMTc2LAorMjM5LCAxODMsIDE1MiwgMjM5LCAxODQsIDEyOCwgMjM5LCAxODQsIDE2OCwgMjM5LCAxODUsIDE0NCwgMjM5LCAxODUsIDE4NCwgMjM5LAorMTg2LCAxNjAsIDIzOSwgMTg3LCAxMzYsIDIzOSwgMTg3LCAxNzYsIDIzOSwgMTg4LCAxNTIsIDIzOSwgMTg5LCAxMjgsIDIzOSwgMTg5LAorMTY4LCAyMzksIDE5MCwgMTQ0LCAyMzksIDE5MCwgMTg0LCAyMzksIDE5MSwgMTYwCisgICAgICAgICAgICB9KTsKKworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X011bHRpQnl0ZV94X3dpbmRvd3NfOTUwLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfTXVsdGlCeXRlX3hfd2luZG93c185NTAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NTI1NDc0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X011bHRpQnl0ZV94X3dpbmRvd3NfOTUwLmphdmEKQEAgLTAsMCArMSwyNDIgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9NdWx0aUJ5dGVfeF93aW5kb3dzXzk1MCBleHRlbmRzIE9sZENoYXJzZXRfQWJzdHJhY3RUZXN0IHsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJzZXROYW1lID0gIngtd2luZG93cy05NTAiOworCisgICAgICAgIHRlc3RDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKzE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCis0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKzY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCis5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKzExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKzE2NywgMTc1LCAxNzYsIDE3NywgMTgzLCAyMTUsIDI0NywgNzExLCA3MTMsIDkxMywgOTQ1LCA4MjExLCA4MjQyLCA4MzY0LCA4NDUxLCA4NTQ0LAorODU5MiwgODcyNSwgODc1NiwgODc4NiwgODg1MywgODg5NSwgOTQ3MiwgOTUwOCwgOTU1MiwgOTU4MiwgOTYxMiwgOTY1MCwgOTY5OCwgOTczMywgOTc5MiwgMTIyODgsCisxMjMxOCwgMTI1NDksIDEyNTc5LCAxMjk2MywgMTMxOTgsIDEzMjUyLCAxOTk2OCwgMTk5OTgsIDIwMDI4LCAyMDA2MCwgMjAwOTQsIDIwMTI2LCAyMDE2MCwgMjAxOTAsIDIwMjIxLCAyMDI1MywKKzIwMjgzLCAyMDMxMywgMjAzNDMsIDIwMzczLCAyMDQwMywgMjA0MzMsIDIwNDYzLCAyMDQ5MywgMjA1MjMsIDIwNTUzLCAyMDU4NCwgMjA2MTUsIDIwNjUyLCAyMDY4MiwgMjA3MTIsIDIwNzQyLAorMjA3NzIsIDIwODAzLCAyMDgzMywgMjA4NjQsIDIwODk0LCAyMDkyNCwgMjA5NTYsIDIwOTg2LCAyMTAyMCwgMjEwNTAsIDIxMDgyLCAyMTExMiwgMjExNDIsIDIxMTc5LCAyMTIwOSwgMjEyMzksCisyMTI2OSwgMjEzMDAsIDIxMzMwLCAyMTM2MCwgMjEzOTAsIDIxNDIwLCAyMTQ1MCwgMjE0ODAsIDIxNTEwLCAyMTU0MCwgMjE1NzAsIDIxNjAwLCAyMTYzMCwgMjE2NjQsIDIxNjk0LCAyMTcyNiwKKzIxNzU2LCAyMTc4NiwgMjE4MTYsIDIxODQ2LCAyMTg3NywgMjE5MDcsIDIxOTM3LCAyMTk2NywgMjE5OTksIDIyMDI5LCAyMjA2MCwgMjIwOTAsIDIyMTIwLCAyMjE1MCwgMjIxODEsIDIyMjExLAorMjIyNDEsIDIyMjcxLCAyMjMwMiwgMjIzMzQsIDIyMzY5LCAyMjQwMCwgMjI0MzAsIDIyNDYwLCAyMjQ5MiwgMjI1MjIsIDIyNTUzLCAyMjU4MywgMjI2MTMsIDIyNjQ0LCAyMjY3NSwgMjI3MDUsCisyMjczNSwgMjI3NjcsIDIyNzk3LCAyMjgyNywgMjI4NTcsIDIyODg3LCAyMjkxNywgMjI5NDcsIDIyOTc3LCAyMzAwOCwgMjMwMzgsIDIzMDY4LCAyMzEwMCwgMjMxMzAsIDIzMTYwLCAyMzE5MSwKKzIzMjIxLCAyMzI1MywgMjMyODMsIDIzMzE1LCAyMzM0NiwgMjMzNzYsIDIzNDA2LCAyMzQzNiwgMjM0NjgsIDIzNDk4LCAyMzUyOCwgMjM1NTksIDIzNTg5LCAyMzYyMCwgMjM2NTAsIDIzNjg2LAorMjM3MTYsIDIzNzUwLCAyMzc4NCwgMjM4MTQsIDIzODQ0LCAyMzg3NCwgMjM5MDYsIDIzOTM2LCAyMzk2NiwgMjM5OTYsIDI0MDI5LCAyNDA2MSwgMjQwOTEsIDI0MTI1LCAyNDE1NSwgMjQxODUsCisyNDIxNSwgMjQyNDUsIDI0Mjc1LCAyNDMwNSwgMjQzMzUsIDI0MzY1LCAyNDM5NSwgMjQ0MjUsIDI0NDU1LCAyNDQ4NSwgMjQ1MTUsIDI0NTQ1LCAyNDU3NSwgMjQ2MDUsIDI0NjQwLCAyNDY3MCwKKzI0NzAzLCAyNDczMywgMjQ3NjMsIDI0NzkzLCAyNDgyMywgMjQ4NTMsIDI0ODg0LCAyNDkxNCwgMjQ5NDQsIDI0OTc0LCAyNTAwNCwgMjUwMzQsIDI1MDY0LCAyNTA5NSwgMjUxMjUsIDI1MTU1LAorMjUxODUsIDI1MjE1LCAyNTI1NiwgMjUyODYsIDI1MzIzLCAyNTM1MywgMjUzODQsIDI1NDE0LCAyNTQ0NSwgMjU0NzUsIDI1NTA1LCAyNTUzNiwgMjU1NjcsIDI1NjA2LCAyNTYzNiwgMjU2NjcsCisyNTY5NywgMjU3MjcsIDI1NzU3LCAyNTc4NywgMjU4MTcsIDI1ODQ3LCAyNTg3NywgMjU5MDcsIDI1OTM3LCAyNTk2NywgMjYwMDAsIDI2MDMwLCAyNjA2MCwgMjYwOTIsIDI2MTIyLCAyNjE1MiwKKzI2MTgzLCAyNjIxMywgMjYyNDQsIDI2Mjc0LCAyNjMwNCwgMjYzMzQsIDI2MzY0LCAyNjM5NSwgMjY0MjUsIDI2NDU1LCAyNjQ4NSwgMjY1MTUsIDI2NTQ2LCAyNjU3NiwgMjY2MDYsIDI2NjQyLAorMjY2NzMsIDI2NzAzLCAyNjczMywgMjY3NjMsIDI2NzkzLCAyNjgyMywgMjY4NTQsIDI2ODg0LCAyNjkxNywgMjY5NDgsIDI2OTc4LCAyNzAxMCwgMjcwNDAsIDI3MDcwLCAyNzEwNiwgMjcxMzYsCisyNzE2NiwgMjcxOTYsIDI3MjI2LCAyNzI2MiwgMjcyOTIsIDI3MzIyLCAyNzM1MywgMjczODQsIDI3NDE0LCAyNzQ0NCwgMjc0NzYsIDI3NTA2LCAyNzUzNywgMjc1NjcsIDI3NTk3LCAyNzYyNywKKzI3NjU3LCAyNzY4NywgMjc3MTgsIDI3NzQ5LCAyNzc3OSwgMjc4MTksIDI3ODQ5LCAyNzg3OSwgMjc5MTEsIDI3OTQxLCAyNzk5MiwgMjgwMjIsIDI4MDUyLCAyODA4MiwgMjgxMTIsIDI4MTQyLAorMjgxODUsIDI4MjE2LCAyODI0NiwgMjgyNzYsIDI4MzA2LCAyODMzNiwgMjgzNjYsIDI4Mzk2LCAyODQyNiwgMjg0NTcsIDI4NDk0LCAyODUyNCwgMjg1NTUsIDI4NTg1LCAyODYxNSwgMjg2NDYsCisyODY3NiwgMjg3MDYsIDI4NzM2LCAyODc2NiwgMjg3OTYsIDI4ODI2LCAyODg1NiwgMjg4ODcsIDI4OTE4LCAyODk1MSwgMjg5ODIsIDI5MDEyLCAyOTA0MiwgMjkwNzIsIDI5MTAzLCAyOTEzNCwKKzI5MTY0LCAyOTE5NCwgMjkyMjQsIDI5MjU0LCAyOTI4NywgMjkzMTcsIDI5MzQ3LCAyOTM3NywgMjk0MDcsIDI5NDM3LCAyOTQ2NywgMjk0OTgsIDI5NTI4LCAyOTU1OCwgMjk1ODgsIDI5NjE4LAorMjk2NTAsIDI5Njg0LCAyOTcxOCwgMjk3NDgsIDI5Nzc4LCAyOTgwOCwgMjk4NDAsIDI5ODcxLCAyOTkwMywgMjk5MzQsIDI5OTY0LCAyOTk5NCwgMzAwMjQsIDMwMDU0LCAzMDA4NCwgMzAxMTQsCiszMDE0NCwgMzAxNzQsIDMwMjA0LCAzMDIzNCwgMzAyNjQsIDMwMjk0LCAzMDMyNSwgMzAzNTUsIDMwMzg4LCAzMDQxOCwgMzA0NDgsIDMwNDgwLCAzMDUxMSwgMzA1NDEsIDMwNTcxLCAzMDYwMSwKKzMwNjMxLCAzMDY2MywgMzA2OTMsIDMwNzIzLCAzMDc1MywgMzA3ODcsIDMwODE4LCAzMDg0OCwgMzA4NzgsIDMwOTA4LCAzMDkzOCwgMzA5NjksIDMwOTk5LCAzMTAyOSwgMzEwNTksIDMxMDkwLAorMzExMjAsIDMxMTUwLCAzMTE4MSwgMzEyMTEsIDMxMjQyLCAzMTI3MiwgMzEzMDIsIDMxMzM1LCAzMTM2NSwgMzEzOTUsIDMxNDI1LCAzMTQ1NSwgMzE0ODUsIDMxNTE1LCAzMTU0NywgMzE1ODQsCiszMTYxOCwgMzE2NDgsIDMxNjc4LCAzMTcwOCwgMzE3MzksIDMxNzY5LCAzMTc5OSwgMzE4MzEsIDMxODYxLCAzMTg5MiwgMzE5MjIsIDMxOTUyLCAzMTk4MiwgMzIwMTIsIDMyMDQzLCAzMjA3NCwKKzMyMTA0LCAzMjEzNCwgMzIxNjYsIDMyMTk2LCAzMjIyNywgMzIyNTksIDMyMjg5LCAzMjMxOSwgMzIzNTAsIDMyMzgwLCAzMjQxMCwgMzI1NjYsIDMyNTk2LCAzMjYyNiwgMzI2NTcsIDMyNjg3LAorMzI3MTcsIDMyNzQ3LCAzMjc3OSwgMzI4MDksIDMyODM5LCAzMjg3MSwgMzI5MDEsIDMyOTMxLCAzMjk2MiwgMzI5OTIsIDMzMDIyLCAzMzA1MywgMzMwODUsIDMzMTE1LCAzMzE0NSwgMzMxNzUsCiszMzIwNSwgMzMyMzcsIDMzMjY3LCAzMzI5NywgMzMzMjcsIDMzMzU4LCAzMzM4OCwgMzM0MTgsIDMzNDQ4LCAzMzQ4OSwgMzM1MTksIDMzNTQ5LCAzMzU3OSwgMzM2MDksIDMzNjUxLCAzMzY4MiwKKzMzNzEyLCAzMzc0MiwgMzM3NzIsIDMzODAyLCAzMzgzMywgMzM4NjMsIDMzODkzLCAzMzkyNiwgMzM5NTYsIDMzOTg2LCAzNDAyMywgMzQwNTQsIDM0MDg0LCAzNDExNSwgMzQxNDUsIDM0MTc2LAorMzQyMDYsIDM0MjM3LCAzNDI2OCwgMzQyOTgsIDM0MzI4LCAzNDM1OCwgMzQzODgsIDM0NDE5LCAzNDQ0OSwgMzQ0NzksIDM0NTEyLCAzNDU0OSwgMzQ1NzksIDM0NjA5LCAzNDYzOSwgMzQ2NjksCiszNDcwMSwgMzQ3MzEsIDM0NzYxLCAzNDc5MSwgMzQ4MjEsIDM0ODUxLCAzNDg4MSwgMzQ5MTMsIDM0OTQzLCAzNDk3NCwgMzUwMDQsIDM1MDM0LCAzNTA2NCwgMzUwOTQsIDM1MTI1LCAzNTE1NSwKKzM1MTg1LCAzNTIxNSwgMzUyNDUsIDM1MjgyLCAzNTMxMiwgMzUzNDIsIDM1MzcyLCAzNTQwMiwgMzU0MzIsIDM1NDYyLCAzNTQ5MiwgMzU1MjIsIDM1NTUyLCAzNTU4MiwgMzU2MTIsIDM1NjQyLAorMzU2NzIsIDM1NzAzLCAzNTczMywgMzU4OTUsIDM1OTI1LCAzNTk1NSwgMzU5ODUsIDM2MDE1LCAzNjA0NywgMzYwNzcsIDM2MTA5LCAzNjE5NiwgMzYyMjgsIDM2MjU5LCAzNjI4OSwgMzYzMTksCiszNjM0OSwgMzYzNzksIDM2NDA5LCAzNjQzOSwgMzY0NzAsIDM2NTAwLCAzNjUzMCwgMzY1NjEsIDM2NTkxLCAzNjYyMSwgMzY2NTIsIDM2NjgzLCAzNjc2MywgMzY3OTksIDM2ODMyLCAzNjg2MiwKKzM2ODkyLCAzNjkyNCwgMzY5NTUsIDM2OTg1LCAzNzAxNSwgMzcwNDUsIDM3MDc2LCAzNzEwNiwgMzcxMzYsIDM3MTY2LCAzNzE5NiwgMzcyMjYsIDM3MjU3LCAzNzI4NywgMzczMTcsIDM3MzQ3LAorMzczNzcsIDM3NDExLCAzNzQ0NSwgMzc0NzUsIDM3NTA2LCAzNzUzNiwgMzc1NjgsIDM3NTk4LCAzNzYyOCwgMzc2NTgsIDM3Njg4LCAzNzcxOCwgMzc3NDksIDM3NzgwLCAzNzgxMCwgMzc4NDAsCiszNzg3MCwgMzc5MDAsIDM3OTMwLCAzNzk2MCwgMzc5OTIsIDM4MjYzLCAzODI5NiwgMzgzMjYsIDM4MzU2LCAzODQyOCwgMzg0NTgsIDM4NDg4LCAzODUxOCwgMzg1NDgsIDM4NTc5LCAzODYxMCwKKzM4NjQwLCAzODY3MCwgMzg3MDAsIDM4NzMxLCAzODc2MSwgMzg3OTIsIDM4ODIyLCAzODg1MiwgMzg4ODMsIDM4OTEzLCAzODk0NCwgMzg5NzcsIDM5MDA3LCAzOTA4MCwgMzkxMTAsIDM5MTQxLAorMzkxNzEsIDM5MjAxLCAzOTIzMSwgMzkyNjIsIDM5MzE4LCAzOTM0OCwgMzkzNzgsIDM5NDA4LCAzOTQzOCwgMzk0NjgsIDM5NDk4LCAzOTUyOCwgMzk1OTIsIDM5NjIyLCAzOTY1NCwgMzk2ODQsCiszOTcxNCwgMzk3NDUsIDM5Nzc1LCAzOTgwNSwgMzk4MzUsIDM5ODY1LCAzOTg5NSwgMzk5MjcsIDM5OTU5LCAzOTk5MCwgNDAwMjAsIDQwMDUxLCA0MDE2NSwgNDAxOTUsIDQwMjI2LCA0MDI1NiwKKzQwMjg3LCA0MDMxNywgNDAzNDcsIDQwMzc3LCA0MDQwNywgNDA0MzcsIDQwNDY3LCA0MDU2NSwgNDA1OTUsIDQwNjI4LCA0MDY1OSwgNDA2OTAsIDQwNzIwLCA0MDc1MCwgNDA3ODAsIDQwODEwLAorNDA4NDUsIDU3MzQ0LCA1NzM3NCwgNTc0MDQsIDU3NDM0LCA1NzQ2NCwgNTc0OTQsIDU3NTI0LCA1NzU1NCwgNTc1ODQsIDU3NjE0LCA1NzY0NCwgNTc2NzQsIDU3NzA0LCA1NzczNCwgNTc3NjQsCis1Nzc5NCwgNTc4MjQsIDU3ODU0LCA1Nzg4NCwgNTc5MTQsIDU3OTQ0LCA1Nzk3NCwgNTgwMDQsIDU4MDM0LCA1ODA2NCwgNTgwOTQsIDU4MTI0LCA1ODE1NCwgNTgxODQsIDU4MjE0LCA1ODI0NCwKKzU4Mjc0LCA1ODMwNCwgNTgzMzQsIDU4MzY0LCA1ODM5NCwgNTg0MjQsIDU4NDU0LCA1ODQ4NCwgNTg1MTQsIDU4NTQ0LCA1ODU3NCwgNTg2MDQsIDU4NjM0LCA1ODY2NCwgNTg2OTQsIDU4NzI0LAorNTg3NTQsIDU4Nzg0LCA1ODgxNCwgNTg4NDQsIDU4ODc0LCA1ODkwNCwgNTg5MzQsIDU4OTY0LCA1ODk5NCwgNTkwMjQsIDU5MDU0LCA1OTA4NCwgNTkxMTQsIDU5MTQ0LCA1OTE3NCwgNTkyMDQsCis1OTIzNCwgNTkyNjQsIDU5Mjk0LCA1OTMyNCwgNTkzNTQsIDU5Mzg0LCA1OTQxNCwgNTk0NDQsIDU5NDc0LCA1OTUwNCwgNTk1MzQsIDU5NTY0LCA1OTU5NCwgNTk2MjQsIDU5NjU0LCA1OTY4NCwKKzU5NzE0LCA1OTc0NCwgNTk3NzQsIDU5ODA0LCA1OTgzNCwgNTk4NjQsIDU5ODk0LCA1OTkyNCwgNTk5NTQsIDU5OTg0LCA2MDAxNCwgNjAwNDQsIDYwMDc0LCA2MDEwNCwgNjAxMzQsIDYwMTY0LAorNjAxOTQsIDYwMjI0LCA2MDI1NCwgNjAyODQsIDYwMzE0LCA2MDM0NCwgNjAzNzQsIDYwNDA0LCA2MDQzNCwgNjA0NjQsIDYwNDk0LCA2MDUyNCwgNjA1NTQsIDYwNTg0LCA2MDYxNCwgNjA2NDQsCis2MDY3NCwgNjA3MDQsIDYwNzM0LCA2MDc2NCwgNjA3OTQsIDYwODI0LCA2MDg1NCwgNjA4ODQsIDYwOTE0LCA2MDk0NCwgNjA5NzQsIDYxMDA0LCA2MTAzNCwgNjEwNjQsIDYxMDk0LCA2MTEyNCwKKzYxMTU0LCA2MTE4NCwgNjEyMTQsIDYxMjQ0LCA2MTI3NCwgNjEzMDQsIDYxMzM0LCA2MTM2NCwgNjEzOTQsIDYxNDI0LCA2MTQ1NCwgNjE0ODQsIDYxNTE0LCA2MTU0NCwgNjE1NzQsIDYxNjA0LAorNjE2MzQsIDYxNjY0LCA2MTY5NCwgNjE3MjQsIDYxNzU0LCA2MTc4NCwgNjE4MTQsIDYxODQ0LCA2MTg3NCwgNjE5MDQsIDYxOTM0LCA2MTk2NCwgNjE5OTQsIDYyMDI0LCA2MjA1NCwgNjIwODQsCis2MjExNCwgNjIxNDQsIDYyMTc0LCA2MjIwNCwgNjIyMzQsIDYyMjY0LCA2MjI5NCwgNjIzMjQsIDYyMzU0LCA2MjM4NCwgNjI0MTQsIDYyNDQ0LCA2MjQ3NCwgNjI1MDQsIDYyNTM0LCA2MjU2NCwKKzYyNTk0LCA2MjYyNCwgNjI2NTQsIDYyNjg0LCA2MjcxNCwgNjI3NDQsIDYyNzc0LCA2MjgwNCwgNjI4MzQsIDYyODY0LCA2Mjg5NCwgNjI5MjQsIDYyOTU0LCA2Mjk4NCwgNjMwMTQsIDYzMDQ0LAorNjMwNzQsIDYzMTA0LCA2MzEzNCwgNjMxNjQsIDYzMTk0LCA2MzIyNCwgNjMyNTQsIDYzMjg0LCA2MzMxNCwgNjMzNDQsIDYzMzc0LCA2MzQwNCwgNjM0MzQsIDYzNDY0LCA2MzQ5NCwgNjM1MjQsCis2MzU1NCwgNjQwMTIsIDY1MDcyLCA2NTEwMiwgNjUyODEsIDY1MzExLCA2NTM0MywgNjUzNzMsIDY1NTA0CisgICAgICAgICAgICB9KTsKKworICAgICAgICB0ZXN0Qnl0ZXMgPSB0aGVzZUJ5dGVzKG5ldyBpbnRbXXsKKzAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKzMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCis2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKzgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisxNjEsIDE3NywgMTYxLCAxOTQsIDE2MiwgODgsIDE2MSwgMjExLCAxNjEsIDgwLCAxNjEsIDIwOSwgMTYxLCAyMTAsIDE2MywgMTkwLAorMTYzLCAxODgsIDE2MywgNjgsIDE2MywgOTIsIDE2MSwgODYsIDE2MSwgMTcyLCAxNjMsIDIyNSwgMTYyLCA3NCwgMTYyLCAxODUsCisxNjEsIDI0NiwgMTYyLCA2NSwgMTYxLCAyMzksIDE2MSwgMjIwLCAxNjEsIDI0MiwgMTYxLCAyMzMsIDE2MiwgMTE5LCAxNjIsIDExNiwKKzE2MiwgMTY0LCAxNjIsIDE2MSwgMTYyLCAxMDksIDE2MSwgMTgyLCAxNjIsIDE2OCwgMTYxLCAxODUsIDE2MSwgMjQwLCAxNjEsIDY0LAorMTYxLCAxNzAsIDE2MywgMTE2LCAxNjMsIDE4MCwgMTYxLCAxOTIsIDE2MiwgODUsIDE2MiwgODcsIDE2NCwgNjQsIDE2NSwgMjI0LAorMjAxLCAxMDAsIDIwMSwgNjUsIDE3NiwgMTc0LCAxNjgsIDIwMCwgMTY0LCAxNzYsIDE2NSwgODEsIDE2NSwgMjQ3LCAyMDEsIDE4MCwKKzIwMiwgOTEsIDE2NywgNjksIDIwMywgMTg4LCAyMDMsIDIwMiwgMjA1LCAyMzIsIDE3MSwgNzcsIDE3MywgMTkzLCAxNzMsIDE5MSwKKzE3MywgMjE5LCAxNzYsIDE4MiwgMjE2LCA5MSwgMjE2LCA5NSwgMTgyLCAyMDIsIDIyMCwgMTg1LCAyMjQsIDI0MywgMjI4LCAyMzQsCisyMzYsIDE4OCwgMTY0LCAxODQsIDE2MiwgOTMsIDE5MCwgMTcyLCAyMDMsIDIwNSwgMjAzLCAyMDYsIDE4NywgMjU0LCAxNjUsIDg4LAorMjAyLCAxMDgsIDE2OCwgMjM1LCAyMDgsIDIzMSwgMjIwLCAxOTksIDI0MSwgMjM3LCAxNjgsIDI0MSwgMTc2LCAyMDAsIDI0MSwgMjM4LAorMTY0LCA4MCwgMjMyLCAyNTAsIDE2OCwgMjQyLCAxNjYsIDc2LCAyMDIsIDExNiwgMjI1LCA3MCwgMTY0LCAyMDYsIDE2NSwgMTExLAorMTY2LCA5MSwgMjAyLCAxNjUsIDE2NywgMTAyLCAyMDMsIDIzNSwgMjAzLCAyMjcsIDIwNiwgNzIsIDIwNiwgNzYsIDIwNiwgNzgsCisxNzMsIDI0MywgMjA4LCAyNDcsIDE3NiwgMjI1LCAxNzYsIDIyMCwgMjEyLCAxMTMsIDIxNiwgMTA5LCAxNzksIDIzNywgMjIwLCAyMTYsCisxODIsIDIyNiwgMTg1LCAxOTgsIDIyOSwgNjgsIDIyOCwgMjUxLCAxOTAsIDE4NSwgMjM2LCAxOTUsIDE5NSwgOTYsIDI0NSwgMTk2LAorMjAxLCAxOTgsIDE3MSwgMTcwLCAyNDksIDEwNywgMTY3LCAxNjMsIDE2OSwgODksIDIwMywgMjQ5LCAyMDYsIDgxLCAyMDksIDgxLAorMjEyLCAxNzcsIDE3NiwgMjQyLCAyMTYsIDE2MSwgMjE2LCAxMjYsIDIyMCwgMjMzLCAyMjUsIDkzLCAxODUsIDIxMSwgMjI5LCA3NiwKKzIzNiwgMjA0LCAxNjcsIDE2NywgMjA2LCA5NiwgMTY0LCAyMTAsIDE2OSwgOTQsIDE4MiwgMjQ4LCAyMDEsIDIwNiwgMTY3LCAxNzMsCisyMDQsIDc0LCAyMDYsIDExNSwgMjA2LCAxMTYsIDE3NCwgODIsIDE3NywgNjQsIDE3NywgNjYsIDIxNiwgMTg3LCAyMTYsIDE5NywKKzIyMCwgMjQ5LCAyMjUsIDExMCwgMjI1LCAxMTUsIDIzMywgODYsIDIzNiwgMjA4LCAxNjQsIDEwOCwgMjEyLCAyNDAsIDE2NywgMTg1LAorMjA5LCAxMDQsIDIxNiwgMjEzLCAxODUsIDIzNSwgMTc3LCA3OCwgMjAxLCAyMTMsIDIwNCwgODksIDE4NSwgMjQwLCAyMDIsIDE5OSwKKzIwNCwgOTIsIDIwNiwgMTcxLCAxNzQsIDExMSwgMTc3LCA4MywgMTc3LCA5MiwgMjE2LCAyMzMsIDIyMSwgODYsIDIyNSwgMTY0LAorMjI5LCAxMDksIDE5MiwgMTcyLCAxNjQsIDExNiwgMTgwLCA4MywgMTY5LCAxNzMsIDE4MCwgODUsIDE4NSwgMjQzLCAxODMsIDcwLAorMTY5LCAxNzcsIDE3NywgMTAzLCAxODUsIDI0OCwgMjQ1LCAyMDMsIDE2NiwgMTYxLCAxNzEsIDIxOCwgMjMzLCAxMTYsIDE3NywgMTA5LAorMTcxLCAyMjQsIDIxNiwgMjQ2LCAxNjQsIDIyMywgMjAyLCAyMjEsIDE2OSwgMTkzLCAxNzEsIDIyOCwgMjA2LCAyMDIsIDIwNiwgMTk1LAorMTc3LCAxMTgsIDIwOSwgMTY3LCAxNzcsIDE2MiwgMjEzLCA5MSwgMjIxLCAxMDEsIDE4MCwgMTA2LCAxODMsIDkxLCAyMjUsIDIwMCwKKzE4OCwgMTYyLCAxODgsIDE2OCwgMTg4LCAxNjksIDE5MCwgMjEwLCAyMzYsIDIzMCwgMjQ5LCAxODYsIDIyMSwgMTE3LCAyMDYsIDIxMSwKKzIwMSwgMjMwLCAxNjksIDIxMSwgMTY5LCAyMjUsIDE2OSwgMjM4LCAyMDYsIDIxOCwgMTcxLCAyNDYsIDE3NCwgMTkzLCAxNzQsIDE4NSwKKzIxMywgMTAzLCAxNzcsIDE4OSwgMTc3LCAxOTYsIDE4MCwgMTIyLCAyMTcsIDk5LCAxODMsIDExMiwgMjIxLCAxMjYsIDIyMSwgMTYyLAorMjE3LCA5OCwgMjI1LCAyMzcsIDIxNywgOTAsIDE5MCwgMjE2LCAyMzMsIDE3NCwgMTk0LCA5NCwgMjQ0LCA3NywgMjMzLCAxNzUsCisxNzcsIDIwNywgMjIxLCAxODgsIDE4MCwgMTgwLCAyMTcsIDEyNCwgMTc3LCAyMjAsIDE2NiwgMTc1LCAxNjksIDI1NCwgMTcyLCA4MSwKKzIwOSwgMjEzLCAyMTMsIDE2OSwgMTgzLCAxMjEsIDE4NiwgOTAsIDIzMywgMTgxLCAyNDIsIDc1LCAxNzYsIDIxMCwgMTc3LCAyMzAsCisyMDEsIDI0MCwgMTY4LCA2NSwgMTcwLCA4MywgMTcwLCA4NSwgMjA3LCA4NiwgMTcyLCA4OSwgMjA3LCA3OSwgMjA5LCAyMzYsCisyMDksIDIyNiwgMjA5LCAyMjQsIDIxMywgMTgwLCAyMTMsIDIwNCwgMjEzLCAxODgsIDIxNywgMjE3LCAyMTcsIDIwOSwgMjE3LCAxNzIsCisyMTcsIDIxNiwgMjIxLCAyMjgsIDIyMSwgMjA1LCAxODMsIDE2NywgMjI2LCA2NCwgMjI2LCA3NiwgMjI5LCAyMTMsIDIyOSwgMjAyLAorMTg4LCAyMDcsIDIzMywgMjE1LCAyMzMsIDIwMywgMTkyLCAyMDcsIDE5MiwgMjA0LCAyMzksIDIyNiwgMjQyLCA4MCwgMjQ1LCAyMDksCisxOTgsIDg2LCAyMDksIDI0OSwgMjMzLCAyMjMsIDE4MywgMTc5LCAyMTMsIDIxOCwgMTk0LCAxMDgsIDE2NSwgMTkyLCAxNzgsIDY0LAorMjM3LCA3NywgMTc0LCAyNDEsIDIwMSwgMjQ4LCAyMDMsIDkxLCAxNjgsIDg1LCAxNzAsIDEwNiwgMTcyLCAxMTcsIDIwNCwgMjQ2LAorMjA3LCAxNjcsIDE3MiwgMTIyLCAyMTAsIDc2LCAyMTAsIDcyLCAxNzUsIDc1LCAxNzgsIDcxLCAyMTQsIDY0LCAxNzgsIDk3LAorMTgxLCA2NSwgMTgwLCAyMjksIDE4MCwgMjQyLCAyMTMsIDIyOCwgMjIyLCA5NSwgMjIyLCA4NSwgMjI2LCAxMDgsIDE4NiwgMTczLAorMjI2LCAxMjYsIDE4NiwgMTIwLCAyMjYsIDExOCwgMjMwLCA3MywgMjMwLCA5MCwgMjM3LCA3OSwgMjMzLCAyMzYsIDIzNywgODYsCisyMzMsIDI0NiwgMjQyLCA5OCwgMjQ0LCAxMDIsIDE5NywgMjQ0LCAxNjgsIDk2LCAyMDUsIDg5LCAxNzIsIDE4MSwgMjEwLCAxMTMsCisyMTQsIDg4LCAyMTQsIDc1LCAxODEsIDc3LCAyMjIsIDEwOCwgMjIyLCAxMTUsIDIyNiwgMTg3LCAyMzAsIDk5LCAxOTEsIDgyLAorMTkyLCAyMzYsIDI0MiwgMTA2LCAxOTgsIDEyMSwgMTkyLCAyNDAsIDE3MCwgMTcwLCAyMTgsIDEwNywgMjQyLCAxMTMsIDIwMywgMTAxLAorMjA3LCAxOTQsIDE3NSwgODYsIDE3OCwgMTE0LCAyMjIsIDE3MywgMjMwLCAxMTcsIDIzOSwgMjU0LCAyMDMsIDEwNywgMTcyLCAxOTQsCisyMTAsIDE4MCwgMjE0LCAxMjAsIDIxOCwgMTI2LCAxODEsIDk0LCAyMjIsIDE4MCwgMTg2LCAxOTIsIDIzNywgMTA1LCAyMzcsIDExMCwKKzE5NiwgMTEwLCAyMDcsIDIxNiwgMTkxLCA5NCwgMjAyLCA3MCwgMjA3LCAyMTksIDE3OCwgMTY1LCAyMzcsIDExNSwgMTcyLCAyMDcsCisyMTAsIDE5OSwgMTgxLCAxMDgsIDIyMiwgMjA0LCAyMzAsIDE4MSwgMTkxLCA5NywgMTk0LCAxMjUsIDI0OSwgMjA0LCAxODEsIDExMywKKzE4MSwgMTE0LCAxNzgsIDE3NiwgMjA1LCAxMjAsIDIxMCwgMjA3LCAyMTQsIDE2OSwgMjE4LCAxODksIDE4MywgMjUxLCAyMzAsIDE5MCwKKzE5MywgNjQsIDE5NSwgMTY5LCAxNzAsIDE5MCwgMjA3LCAyNDIsIDIxMCwgMjI1LCAxNzgsIDE4NSwgMjE4LCAyMDksIDIyMiwgMjQwLAorMjI2LCAyNDIsIDE4OSwgODgsIDE5MSwgMTA2LCAyMzcsIDE3MiwgMjQyLCAxNjMsIDI0NiwgMjQ2LCAyMTAsIDIzNCwgMjE4LCAyMTIsCisyMjcsIDY3LCAxOTQsIDE2NywgMjA3LCAyNTAsIDIxMCwgMjM3LCAyMTgsIDIxNSwgMjI3LCA3MiwgMTkxLCAxMTIsIDI0MiwgMTY2LAorMjEwLCAyNDgsIDIyMywgNjYsIDIzNywgMTg1LCAxNzksIDE4NiwgMTcyLCAyNDIsIDE3OCwgMTk1LCAyMTgsIDIyMywgMTg0LCA5NywKKzIyNywgOTMsIDE4OSwgMTA1LCAyMzAsIDIxNiwgMjM0LCAxOTUsIDIzNywgMTkxLCAyNDAsIDk5LCAxOTUsIDE3OCwgMjQ2LCAyNTAsCisyMDUsIDE2OCwgMjE0LCAyMjIsIDIyMywgODQsIDIzNCwgMjAyLCAyNDQsIDE3MSwgMjExLCA5MCwgMTgxLCAxODEsIDIxNCwgMjM4LAorMTgxLCAxNzksIDIyMywgODgsIDIyNywgMTE3LCAyMjcsIDEwOCwgMTg5LCAxMTYsIDIzMCwgMjMzLCAyMzQsIDIwNSwgMTkzLCAxMDQsCisxOTQsIDE4MiwgMTk2LCAxMjYsIDI0OCwgMjU0LCAxNjYsIDIwNiwgMTcwLCAyMDEsIDE4NCwgMTEyLCAyMDgsIDc4LCAxODksIDEyNiwKKzIxNCwgMjQ4LCAyMzAsIDI0NiwgMTgxLCAxOTIsIDIzNCwgMjMwLCAyMTUsIDY2LCAyMzAsIDI1MiwgMTgxLCAxOTQsIDIwNSwgMTczLAorMjA4LCA5MSwgMjA4LCA4OCwgMjE5LCA3MiwgMjE1LCA4MCwgMjE5LCA3OSwgMjIzLCAxMTksIDE4NCwgMTYxLCAyMzEsIDY4LAorMjM0LCAyMzYsIDI0MiwgMTk0LCAxNjYsIDIyMCwgMjE1LCA4MiwgMjExLCAxMTMsIDIzMSwgNzQsIDI0NywgMjM5LCAyMDMsIDE2MSwKKzIwNSwgMTkxLCAxNzMsIDk4LCAxNzMsIDEwMiwgMjA2LCA2NSwgMTc1LCAyMzcsIDE3NSwgMjQzLCAyMTUsIDk0LCAxNzgsIDI0NywKKzIxNSwgMTE2LCAyMTksIDExNiwgMjE5LCAxNjgsIDE4MSwgMjIwLCAyMjMsIDE5OSwgMjIzLCAyMTUsIDIyMywgMTc2LCAyMjMsIDE3OSwKKzIyNywgMTczLCAyMjcsIDE3OCwgMjMxLCAxMTUsIDE4OSwgMTgzLCAyMzEsIDc2LCAxOTEsIDE4NywgMjM0LCAyNTMsIDIzNywgMjQ0LAorMjM3LCAyNTQsIDI0MCwgMTcxLCAyNDIsIDIxMiwgMTk2LCAxNjksIDI0NSwgMjQxLCAyNDcsIDc2LCAxNzYsIDY0LCAyMDgsIDE2OSwKKzIxMSwgMTg5LCAxNzksIDc2LCAxODEsIDI0MSwgMjIzLCAyMzIsIDE4NCwgMTg3LCAyMjcsIDIzNSwgMjMxLCAxODcsIDIzMSwgMTc1LAorMTkxLCAxOTYsIDE5MywgMTc3LCAyMzgsIDk4LCAyNDAsIDE4NywgMTk1LCAxOTksIDE5NiwgMjQ3LCAyMDgsIDE3MCwgMTkxLCAxOTcsCisyMTEsIDIxNSwgMTc5LCA3OSwgMjE5LCAyMDIsIDIyMywgMjQ3LCAxODcsIDExNCwgMjMxLCAyMDIsIDIzOCwgMTEzLCAyNDAsIDIxMCwKKzI0NywgODIsIDE3OSwgODcsIDIzOCwgMTIxLCAxNjgsIDE2NCwgMjMxLCAyMTAsIDE3NiwgODEsIDIxNSwgMjAzLCAyMTksIDIyNiwKKzE4NCwgMjI5LCAyMjQsIDcwLCAxODcsIDEyNiwgMTg5LCAyMTIsIDIzNSwgMTI2LCAxOTEsIDIxMywgMjM4LCAxNzQsIDI0MCwgMjM3LAorMTk1LCAyMDksIDE5NywgNjQsIDI0OCwgMTk0LCAxNjgsIDE2NiwgMTY4LCAxNjgsIDE5MywgMTk5LCAyMzUsIDE3NywgMTgyLCA3NCwKKzIyOCwgODQsIDE4OSwgMjI4LCAxOTYsIDE4NiwgMTY4LCAxNzAsIDIxOSwgMjM3LCAxODksIDIzNiwgMjE1LCAyMTgsIDE4NCwgMjQyLAorMjI4LCA5MSwgMjMxLCAyNDksIDE5MSwgMjI5LCAyNDAsIDI1MCwgMTk1LCAyMjEsIDI0NywgOTQsIDE4NCwgMjUwLCAyMTEsIDIzMiwKKzIxOSwgMjUyLCAyMjgsIDEwMywgMjMyLCA3MSwgMjQxLCA3MywgMTY4LCAxNzUsIDIwMywgMTY2LCAyMDgsIDE4MiwgMjExLCAyMzQsCisyMTUsIDIyOSwgMTg1LCA3MSwgMTg3LCAxOTEsIDIzNSwgMjA5LCAyMDIsIDgyLCAxNzAsIDI0MiwgMjE1LCAyMzgsIDIxNSwgMjM2LAorMjI0LCAxNjQsIDIzMiwgOTAsIDE3NiwgMTE3LCAxODUsIDg0LCAxOTAsIDc1LCAyNDEsIDgwLCAxOTgsIDExMSwgMTc5LCAxNjgsCisyMjAsIDk4LCAxODIsIDExNiwgMTg1LCAxMDAsIDIyNCwgMTk3LCAyMjgsIDE3MCwgMjI4LCAxMjMsIDIzMiwgMTAxLCAyMzIsIDEyMywKKzE5MSwgMjUxLCAxOTEsIDI1NCwgMjM1LCAyMjgsIDIzOCwgMjA5LCAxOTMsIDIyOCwgMTk0LCAyMzIsIDI0MSwgMTAyLCAyNDMsIDEwMSwKKzI0MywgMTEwLCAyNDUsIDY1LCAyNDYsIDEwMiwgMjQ3LCAxMTAsIDI0OCwgMjAzLCAxNzAsIDI0OCwgMTg1LCAxMDQsIDIzNiwgNzUsCisxOTQsIDI0MywgMTcwLCAyNTAsIDIwNSwgMjE5LCAxNzYsIDE2NCwgMTc5LCAxNzksIDE4NSwgMTA2LCAyNDEsIDExMSwgMTg3LCAyMjAsCisyMjAsIDE2OCwgMTkyLCA3NSwgMjQzLCAxMjQsIDI0OSwgMTczLCAxNzMsIDE3OCwgMjMyLCAxNzksIDE5NCwgMjU0LCAyNDgsIDc5LAorMjQ3LCAxMTQsIDE3MywgMTgyLCAyMzIsIDE4NywgMjM5LCA2OSwgMjQ1LCA4MSwgMTczLCAxODMsIDI0NiwgMTE2LCAyMTYsIDc5LAorMTg3LCAyMjksIDE5MiwgOTYsIDE5NSwgNzMsIDE5OCwgOTcsIDE3MywgMTg2LCAxODUsIDE2NSwgMTkwLCAxMTUsIDIzNiwgMTAxLAorMTk1LCA3NywgMjQ1LCA5MywgMjQ3LCAxMjYsIDI0OSwgMTk1LCAxNzYsIDE2OSwgMjQ1LCAxMDIsIDE4NywgMjM2LCAyNDEsIDE4OCwKKzE5OCwgNzUsIDE4NywgMjM3LCAyMjgsIDIyNSwgMjM2LCAxNjEsIDIzOSwgMTA5LCAyNDEsIDIwNSwgMjQzLCAyMDgsIDI0NSwgMTA4LAorMjQ1LCAxMTYsIDI0NywgMTgyLCAxOTcsIDIzNSwgMjQ5LCAxMjAsIDE3OSwgMTkwLCAxOTAsIDE2MSwgMjM2LCAxNzEsIDIzOSwgMTY2LAorMjQxLCAyMTksIDI0MywgMjI3LCAyNDUsIDEyNiwgMjQ2LCAxOTEsIDE5NywgMTk1LCAyNDcsIDE5NiwgMjQ5LCAxMjQsIDE3OSwgMTkxLAorMTk2LCA4MywgMTk2LCA4NCwgMjMyLCAyNDEsIDI0OCwgMTE4LCAyMzIsIDI0MywgMjQ1LCAxODUsIDI0MSwgMjMzLCAxOTcsIDE5OCwKKzE5MiwgMTE1LCAyNTAsIDY0LCAyNTAsIDk0LCAyNTAsIDEyNCwgMjUwLCAxODgsIDI1MCwgMjE4LCAyNTAsIDI0OCwgMjUxLCA4NywKKzI1MSwgMTE3LCAyNTEsIDE4MSwgMjUxLCAyMTEsIDI1MSwgMjQxLCAyNTIsIDgwLCAyNTIsIDExMCwgMjUyLCAxNzQsIDI1MiwgMjA0LAorMjUyLCAyMzQsIDI1MywgNzMsIDI1MywgMTAzLCAyNTMsIDE2NywgMjUzLCAxOTcsIDI1MywgMjI3LCAyNTQsIDY2LCAyNTQsIDk2LAorMjU0LCAxMjYsIDI1NCwgMTkwLCAyNTQsIDIyMCwgMjU0LCAyNTAsIDE0MiwgODksIDE0MiwgMTE5LCAxNDIsIDE4MywgMTQyLCAyMTMsCisxNDIsIDI0MywgMTQzLCA4MiwgMTQzLCAxMTIsIDE0MywgMTc2LCAxNDMsIDIwNiwgMTQzLCAyMzYsIDE0NCwgNzUsIDE0NCwgMTA1LAorMTQ0LCAxNjksIDE0NCwgMTk5LCAxNDQsIDIyOSwgMTQ1LCA2OCwgMTQ1LCA5OCwgMTQ1LCAxNjIsIDE0NSwgMTkyLCAxNDUsIDIyMiwKKzE0NSwgMjUyLCAxNDYsIDkxLCAxNDYsIDEyMSwgMTQ2LCAxODUsIDE0NiwgMjE1LCAxNDYsIDI0NSwgMTQ3LCA4NCwgMTQ3LCAxMTQsCisxNDcsIDE3OCwgMTQ3LCAyMDgsIDE0NywgMjM4LCAxNDgsIDc3LCAxNDgsIDEwNywgMTQ4LCAxNzEsIDE0OCwgMjAxLCAxNDgsIDIzMSwKKzE0OSwgNzAsIDE0OSwgMTAwLCAxNDksIDE2NCwgMTQ5LCAxOTQsIDE0OSwgMjI0LCAxNDksIDI1NCwgMTUwLCA5MywgMTUwLCAxMjMsCisxNTAsIDE4NywgMTUwLCAyMTcsIDE1MCwgMjQ3LCAxNTEsIDg2LCAxNTEsIDExNiwgMTUxLCAxODAsIDE1MSwgMjEwLCAxNTEsIDI0MCwKKzE1MiwgNzksIDE1MiwgMTA5LCAxNTIsIDE3MywgMTUyLCAyMDMsIDE1MiwgMjMzLCAxNTMsIDcyLCAxNTMsIDEwMiwgMTUzLCAxNjYsCisxNTMsIDE5NiwgMTUzLCAyMjYsIDE1NCwgNjUsIDE1NCwgOTUsIDE1NCwgMTI1LCAxNTQsIDE4OSwgMTU0LCAyMTksIDE1NCwgMjQ5LAorMTU1LCA4OCwgMTU1LCAxMTgsIDE1NSwgMTgyLCAxNTUsIDIxMiwgMTU1LCAyNDIsIDE1NiwgODEsIDE1NiwgMTExLCAxNTYsIDE3NSwKKzE1NiwgMjA1LCAxNTYsIDIzNSwgMTU3LCA3NCwgMTU3LCAxMDQsIDE1NywgMTY4LCAxNTcsIDE5OCwgMTU3LCAyMjgsIDE1OCwgNjcsCisxNTgsIDk3LCAxNTgsIDE2MSwgMTU4LCAxOTEsIDE1OCwgMjIxLCAxNTgsIDI1MSwgMTU5LCA5MCwgMTU5LCAxMjAsIDE1OSwgMTg0LAorMTU5LCAyMTQsIDE1OSwgMjQ0LCAxNjAsIDgzLCAxNjAsIDExMywgMTYwLCAxNzcsIDE2MCwgMjA3LCAxNjAsIDIzNywgMTI5LCA3NiwKKzEyOSwgMTA2LCAxMjksIDE3MCwgMTI5LCAyMDAsIDEyOSwgMjMwLCAxMzAsIDY5LCAxMzAsIDk5LCAxMzAsIDE2MywgMTMwLCAxOTMsCisxMzAsIDIyMywgMTMwLCAyNTMsIDEzMSwgOTIsIDEzMSwgMTIyLCAxMzEsIDE4NiwgMTMxLCAyMTYsIDEzMSwgMjQ2LCAxMzIsIDg1LAorMTMyLCAxMTUsIDEzMiwgMTc5LCAxMzIsIDIwOSwgMTMyLCAyMzksIDEzMywgNzgsIDEzMywgMTA4LCAxMzMsIDE3MiwgMTMzLCAyMDIsCisxMzMsIDIzMiwgMTM0LCA3MSwgMTM0LCAxMDEsIDEzNCwgMTY1LCAxMzQsIDE5NSwgMTM0LCAyMjUsIDEzNSwgNjQsIDEzNSwgOTQsCisxMzUsIDEyNCwgMTM1LCAxODgsIDEzNSwgMjE4LCAxMzUsIDI0OCwgMTM2LCA4NywgMTM2LCAxMTcsIDEzNiwgMTgxLCAxMzYsIDIxMSwKKzEzNiwgMjQxLCAxMzcsIDgwLCAxMzcsIDExMCwgMTM3LCAxNzQsIDEzNywgMjA0LCAxMzcsIDIzNCwgMTM4LCA3MywgMTM4LCAxMDMsCisxMzgsIDE2NywgMTM4LCAxOTcsIDEzOCwgMjI3LCAxMzksIDY2LCAxMzksIDk2LCAxMzksIDEyNiwgMTM5LCAxOTAsIDEzOSwgMjIwLAorMTM5LCAyNTAsIDE0MCwgODksIDE0MCwgMTE5LCAxNDAsIDE4MywgMTQwLCAyMTMsIDE0MCwgMjQzLCAxNDEsIDgyLCAxNDEsIDExMiwKKzE0MSwgMTc2LCAxNDEsIDIwNiwgMTQxLCAyMzYsIDE5OCwgMTcyLCAxOTgsIDIwMiwgMTk4LCAyMzIsIDE5OSwgNzEsIDE5OSwgMTAxLAorMTk5LCAxNjUsIDE5OSwgMTk1LCAxOTksIDIyNSwgMjAwLCA2NCwgMjAwLCA5NCwgMjAwLCAxMjQsIDIwMCwgMTg4LCAyMDAsIDIxOCwKKzIwMCwgMjQ4LCAyMDEsIDc0LCAxNjEsIDc0LCAxNjEsIDIwMSwgMTYxLCA3MywgMTYxLCA3MiwgMTYxLCAxOTYsIDE2MSwgOTgsCisxNjIsIDcwCisgICAgICAgICAgICB9KTsKKworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29kZWNEeW5hbWljKCkgdGhyb3dzIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlc3RfQ29kZWNEeW5hbWljKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgdGVzdF9EZWNvZGUoKSB0aHJvd3MgQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVzdF9EZWNvZGUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0VuY29kZSgpIHRocm93cyBDaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb24geworICAgICAgICBzdXBlci50ZXN0X0VuY29kZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHRlc3RfbmFtZU1hdGNoKCkgeworICAgICAgICBzdXBlci50ZXN0X25hbWVNYXRjaCgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVBYnN0cmFjdFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlQWJzdHJhY3RUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGFjNmViNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlQWJzdHJhY3RUZXN0LmphdmEKQEAgLTAsMCArMSwxOTMgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uQ2hhckJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNvZGluZ0Vycm9yQWN0aW9uOworCisvKioKKyAqIFN1cGVyIGNsYXNzIGZvciBjb25jcmV0ZSBjaGFyc2V0IHRlc3Qgc3VpdGVzLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgT2xkQ2hhcnNldF9TaW5nbGVCeXRlQWJzdHJhY3RUZXN0IGV4dGVuZHMgT2xkQ2hhcnNldF9BYnN0cmFjdFRlc3QgeworCisgICAgc3RhdGljIGJ5dGVbXSBhbGxCeXRlczsKKyAgICBzdGF0aWMgY2hhcltdIGFsbENoYXJzOworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYWxsQnl0ZXMgPSBuZXcgYnl0ZVsyNTZdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDI1NjsgaSsrKSB7CisgICAgICAgICAgICBhbGxCeXRlc1tpXSA9IChieXRlKSBpOworICAgICAgICB9CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKworCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGR1bXBEZWNvZGVkICgpIHsKKyAgICAgICAgQ2hhcnNldF9UZXN0R2VuZXJhdG9yLkR1bXBlciBvdXQgPSBuZXcgQ2hhcnNldF9UZXN0R2VuZXJhdG9yLkR1bXBlcjEoKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBpbnB1dEJCID0gQnl0ZUJ1ZmZlci53cmFwKGFsbEJ5dGVzKTsKKyAgICAgICAgQ2hhckJ1ZmZlciBvdXRwdXRDQjsKKyAgICAgICAgZGVjb2Rlci5vbk1hbGZvcm1lZElucHV0KENvZGluZ0Vycm9yQWN0aW9uLlJFUExBQ0UpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb3V0cHV0Q0IgPSBkZWNvZGVyLmRlY29kZShpbnB1dEJCKTsKKyAgICAgICAgICAgIG91dHB1dENCLnJld2luZCgpOworICAgICAgICAgICAgd2hpbGUgKG91dHB1dENCLmhhc1JlbWFpbmluZygpKSB7CisgICAgICAgICAgICAgICAgb3V0LmNvbnN1bWUob3V0cHV0Q0IuZ2V0KCkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChDaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGUpOworLy8gICAgICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBkZWNvZGVSZXBsYWNlIChieXRlW10gaW5wdXQsIGNoYXJbXSBleHBlY3RlZE91dHB1dCkgdGhyb3dzIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVCdWZmZXIgaW5wdXRCQiA9IEJ5dGVCdWZmZXIud3JhcChpbnB1dCk7CisgICAgICAgIENoYXJCdWZmZXIgb3V0cHV0Q0I7CisgICAgICAgIGRlY29kZXIub25NYWxmb3JtZWRJbnB1dChDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFKTsKKyAgICAgICAgZGVjb2Rlci5vblVubWFwcGFibGVDaGFyYWN0ZXIoQ29kaW5nRXJyb3JBY3Rpb24uUkVQTEFDRSk7CisgICAgICAgIG91dHB1dENCID0gZGVjb2Rlci5kZWNvZGUoaW5wdXRCQik7CisgICAgICAgIG91dHB1dENCLnJld2luZCgpOworICAgICAgICBhc3NlcnRFcXVhbENoYXJzMigiRGVjb2RlZCBjaGFyYWN0ZXMgbXVzdCBtYXRjaCEiLAorICAgICAgICAgICAgICAgIGV4cGVjdGVkT3V0cHV0LAorICAgICAgICAgICAgICAgIG91dHB1dENCLmFycmF5KCksCisgICAgICAgICAgICAgICAgaW5wdXQpOworLy8gICAgICAgIGFzc2VydFRydWUoIkRlY29kZWQgY2hhcmFjdGVzIChSRVBMQUNFZWQgb25lcyBJTkNMVVNJVkUpIG11c3QgbWF0Y2ghIiwKKy8vICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMoZXhwZWN0ZWRPdXRwdXQsIG91dHB1dENCLmFycmF5KCkpKTsKKworLy8gICAgICAgIGFzc2VydEVxdWFsQ2hhcnMoIkRlY29kZWQgY2hhcmFjdGVzIChSRVBMQUNFZWQgb25lcyBJTkNMVVNJVkUpIG11c3QgbWF0Y2ghIiwKKy8vICAgICAgICAgICAgICAgIGV4cGVjdGVkT3V0cHV0LAorLy8gICAgICAgICAgICAgICAgb3V0cHV0Q0IuYXJyYXkoKSk7CisKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoIkRlY29kZWQgY2hhcmFjdGVzIG11c3QgbWF0Y2ghIiwKKy8vICAgICAgICAgICAgICAgIFN0cmluZy52YWx1ZU9mKGFsbENoYXJzKSwKKy8vICAgICAgICAgICAgICAgIG91dHB1dENCLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHRlc3RfRGVjb2RlICgpIHRocm93cyBDaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb24geworICAgICAgICBkZWNvZGVSZXBsYWNlKGFsbEJ5dGVzLCBhbGxDaGFycyk7CisvLyAgICAgICAgQnl0ZUJ1ZmZlciBpbnB1dEJCID0gQnl0ZUJ1ZmZlci53cmFwKGFsbEJ5dGVzKTsKKy8vICAgICAgICBDaGFyQnVmZmVyIG91dHB1dENCOworLy8gICAgICAgIGRlY29kZXIub25NYWxmb3JtZWRJbnB1dChDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFKTsKKy8vICAgICAgICBvdXRwdXRDQiA9IGRlY29kZXIuZGVjb2RlKGlucHV0QkIpOworLy8gICAgICAgIG91dHB1dENCLnJld2luZCgpOworLy8gICAgICAgIGFzc2VydEVxdWFsQ2hhcnMoIkRlY29kZWQgY2hhcmFjdGVzIG11c3QgbWF0Y2ghIiwKKy8vICAgICAgICAgICAgICAgIGFsbENoYXJzLAorLy8gICAgICAgICAgICAgICAgb3V0cHV0Q0IuYXJyYXkoKSk7CisvLy8vICAgICAgICBhc3NlcnRFcXVhbHMoIkRlY29kZWQgY2hhcmFjdGVzIG11c3QgbWF0Y2ghIiwKKy8vLy8gICAgICAgICAgICAgICAgU3RyaW5nLnZhbHVlT2YoYWxsQ2hhcnMpLAorLy8vLyAgICAgICAgICAgICAgICBvdXRwdXRDQi50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0VuY29kZSAoKSB0aHJvd3MgQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgQ2hhckJ1ZmZlciBpbnB1dENCID0gQ2hhckJ1ZmZlci53cmFwKGFsbENoYXJzKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBvdXRwdXRCQjsKKyAgICAgICAgZW5jb2Rlci5vblVubWFwcGFibGVDaGFyYWN0ZXIoQ29kaW5nRXJyb3JBY3Rpb24uUkVQTEFDRSk7CisgICAgICAgIG91dHB1dEJCID0gZW5jb2Rlci5lbmNvZGUoaW5wdXRDQik7CisgICAgICAgIG91dHB1dEJCLnJld2luZCgpOworICAgICAgICBhc3NlcnRFcXVhbEJ5dGVzMigiRW5jb2RlZCBieXRlcyBtdXN0IG1hdGNoISIsIGFsbEJ5dGVzLCBvdXRwdXRCQi5hcnJheSgpLCBhbGxDaGFycyk7CisgICAgfQorCisvLyAgICBzdGF0aWMgdm9pZCBhc3NlcnRFcXVhbENoYXJzIChTdHJpbmcgbXNnLCBjaGFyW10gZXhwZWN0ZWQsIGNoYXJbXSBhY3R1YWwpIHsKKy8vICAgICAgICBpbnQgbGVuID0gZXhwZWN0ZWQubGVuZ3RoOworLy8gICAgICAgIGlmIChhY3R1YWwubGVuZ3RoIDwgbGVuKSBsZW4gPSBhY3R1YWwubGVuZ3RoOworLy8gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKy8vICAgICAgICAgICAgaWYgKGFjdHVhbFtpXSAhPSBleHBlY3RlZFtpXSkgeworLy8gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5mb3JtYXQoIk1pc21hdGNoIGF0IGluZGV4ICVkOiAlZCBpbnN0ZWFkIG9mIGV4cGVjdGVkICVkLlxuIiwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgaSwgKGludCkgYWN0dWFsW2ldLCAoaW50KSBleHBlY3RlZFtpXSk7CisvLyAgICAgICAgICAgIH0KKy8vLy8gICAgICAgICAgICBlbHNlIHsKKy8vLy8gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5mb3JtYXQoIk1hdGNoIGluZGV4ICVkOiAlZCA9ICVkXG4iLAorLy8vLyAgICAgICAgICAgICAgICAgICAgICAgIGksIChpbnQpIGFjdHVhbFtpXSwgKGludCkgZXhwZWN0ZWRbaV0pOworLy8vLyAgICAgICAgICAgIH0KKy8vICAgICAgICB9CisvLyAgICAgICAgYXNzZXJ0VHJ1ZShtc2csIEFycmF5cy5lcXVhbHMoYWN0dWFsLCBleHBlY3RlZCkpOworLy8gICAgfQorCisgICAgc3RhdGljIHZvaWQgYXNzZXJ0RXF1YWxDaGFyczIgKFN0cmluZyBtc2csIGNoYXJbXSBleHBlY3RlZCwgY2hhcltdIGFjdHVhbCwgYnl0ZVtdIGJ5dGVzKSB7CisgICAgICAgIGJvb2xlYW4gbWF0Y2ggPSB0cnVlOworICAgICAgICBib29sZWFuIHJlcGxhY2VNYXRjaCA9IHRydWU7CisgICAgICAgIGludCBsZW4gPSBleHBlY3RlZC5sZW5ndGg7CisgICAgICAgIGlmIChhY3R1YWwubGVuZ3RoIDwgbGVuKSBsZW4gPSBhY3R1YWwubGVuZ3RoOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYWN0dWFsW2ldID09IGV4cGVjdGVkW2ldKSB7CisgICAgICAgICAgICAgICAgLy8gRmluZSEKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIGlmIChleHBlY3RlZFtpXSA9PSA2NTUzMykgeworICAgICAgICAgICAgICAgICAgICBpZiAoYWN0dWFsW2ldID09IChieXRlc1tpXSAmIDB4ZmYpKSB7CisvLyAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQuZm9ybWF0KCJSRVBMQUNFIG1pc21hdGNoIGF0IGluZGV4ICVkIChieXRlICVkKTogJWQgaW5zdGVhZCBvZiBleHBlY3RlZCAlZC5cbiIsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSwgYnl0ZXNbaV0gJiAweGZmLCAoaW50KSBhY3R1YWxbaV0sIChpbnQpIGV4cGVjdGVkW2ldKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKy8vICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5mb3JtYXQoIlJFUExBQ0UgbWlzbWF0Y2ggYXQgaW5kZXggJWQgKGJ5dGUgJWQpOiAlZCBpbnN0ZWFkIG9mIGV4cGVjdGVkICVkLlxuIiwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpLCBieXRlc1tpXSAmIDB4ZmYsIChpbnQpIGFjdHVhbFtpXSwgKGludCkgZXhwZWN0ZWRbaV0pOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VNYXRjaCA9IGZhbHNlOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisvLyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5mb3JtYXQoIk1JU01BVENIIGF0IGluZGV4ICVkIChieXRlICVkKTogJWQgaW5zdGVhZCBvZiBleHBlY3RlZCAlZC5cbiIsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpLCBieXRlc1tpXSAmIDB4ZmYsIChpbnQpIGFjdHVhbFtpXSwgKGludCkgZXhwZWN0ZWRbaV0pOworICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgaWYgKChhY3R1YWxbaV0gIT0gZXhwZWN0ZWRbaV0pICYmCisvLyAgICAgICAgICAgICAgICAgICAgISgoYWN0dWFsW2ldID09IGJ5dGVzW2ldKSAmJiAoZXhwZWN0ZWRbaV0gPT0gNjU1MzMpKSkgeworLy8KKy8vICAgICAgICAgICAgICAgIG1hdGNoID0gZmFsc2U7CisvLyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKG1zZywgbWF0Y2gpOworICAgICAgICBpZiAoIXJlcGxhY2VNYXRjaCkgeworLy8gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZvciBjaGFyc2V0ICIgKyBjaGFyc2V0TmFtZSk7CisgICAgICAgIH0KKyAgICB9CisKKy8vICAgIHN0YXRpYyB2b2lkIGFzc2VydEVxdWFsQnl0ZXMgKFN0cmluZyBtc2csIGJ5dGVbXSBleHBlY3RlZCwgYnl0ZVtdIGFjdHVhbCkgeworLy8gICAgICAgIGludCBsZW4gPSBleHBlY3RlZC5sZW5ndGg7CisvLyAgICAgICAgaWYgKGFjdHVhbC5sZW5ndGggPCBsZW4pIGxlbiA9IGFjdHVhbC5sZW5ndGg7CisvLyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworLy8gICAgICAgICAgICBpZiAoYWN0dWFsW2ldICE9IGV4cGVjdGVkW2ldKSB7CisvLyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LmZvcm1hdCgiTUlTTUFUQ0ggYXQgaW5kZXggJWQ6ICVkIGluc3RlYWQgb2YgZXhwZWN0ZWQgJWQuXG4iLAorLy8gICAgICAgICAgICAgICAgICAgICAgICBpLCBhY3R1YWxbaV0sIGV4cGVjdGVkW2ldKTsKKy8vICAgICAgICAgICAgfQorLy8gICAgICAgIH0KKy8vICAgICAgICBhc3NlcnRUcnVlKG1zZywgQXJyYXlzLmVxdWFscyhhY3R1YWwsIGV4cGVjdGVkKSk7CisvLyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBhc3NlcnRFcXVhbEJ5dGVzMiAoU3RyaW5nIG1zZywgYnl0ZVtdIGV4cGVjdGVkLCBieXRlW10gYWN0dWFsLCBjaGFyW10gY2hhcnMpIHsKKyAgICAgICAgYm9vbGVhbiBtYXRjaCA9IHRydWU7CisgICAgICAgIGludCBsZW4gPSBleHBlY3RlZC5sZW5ndGg7CisgICAgICAgIGlmIChhY3R1YWwubGVuZ3RoIDwgbGVuKSBsZW4gPSBhY3R1YWwubGVuZ3RoOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisgICAgICAgICAgICBpZiAoKGFjdHVhbFtpXSAhPSBleHBlY3RlZFtpXSkgJiYKKyAgICAgICAgICAgICAgICAgICAgISgoY2hhcnNbaV0gPT0gNjU1MzMpKSAmJiAoYWN0dWFsW2ldID09IDYzKSkgeworLy8gICAgICAgICAgICAgIFN5c3RlbS5vdXQuZm9ybWF0KCJNSVNNQVRDSCBhdCBpbmRleCAlZDogJWQgaW5zdGVhZCBvZiBleHBlY3RlZCAlZC5cbiIsCisvLyAgICAgICAgICAgICAgICAgICAgICBpLCBhY3R1YWxbaV0sIGV4cGVjdGVkW2ldKTsKKyAgICAgICAgICAgICAgICBtYXRjaCA9IGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUobXNnLCBtYXRjaCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV9JQk04NjQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lCTTg2NC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg2OThkNjgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV9JQk04NjQuamF2YQpAQCAtMCwwICsxLDc5IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbjsKKworLyoqIE5vdGU6IElDVSBiZWhhdmVzIGRpZmZlcmVudGx5IGZyb20gdGhlIFJJICovCisKK3B1YmxpYyBjbGFzcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSUJNODY0IGV4dGVuZHMgT2xkQ2hhcnNldF9TaW5nbGVCeXRlQWJzdHJhY3RUZXN0IHsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisvLyAgICAgICAgY2hhcnNldE5hbWUgPSAiSUJNODY0IjsgLy8gSUNVIG5hbWUgImNwODY0Iiwgd2FudGVkIEFuZHJvaWQgbmFtZSAiQ1A4NjQiCisgICAgICAgIGNoYXJzZXROYW1lID0gImNwODY0IjsgLy8gSUNVIG5hbWUgImNwODY0Iiwgd2FudGVkIEFuZHJvaWQgbmFtZSAiQ1A4NjQiCisKKyAgICAgICAgYWxsQ2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKyAgICAgICAgICAgIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisgICAgICAgICAgICAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjgvKjI2Ki8sIDI3LCAxMjcvKjI4Ki8sIDI5LCAzMCwgMzEsCisgICAgICAgICAgICAzMiwgMzMsIDM0LCAzNSwgMzYsIDM3LyoxNjQyKi8sIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorICAgICAgICAgICAgNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCisgICAgICAgICAgICA2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKyAgICAgICAgICAgIDgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorICAgICAgICAgICAgOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisgICAgICAgICAgICAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAyNi8qMTI3Ki8sCisgICAgICAgICAgICAxNzYsIDE4MywgODcyOSwgODczMCwgOTYxOCwgOTQ3MiwgOTQ3NCwgOTUzMiwgOTUwOCwgOTUxNiwgOTUwMCwgOTUyNCwgOTQ4OCwgOTQ4NCwgOTQ5MiwgOTQ5NiwKKyAgICAgICAgICAgIDk0NiwgODczNCwgOTY2LCAxNzcsIDE4OSwgMTg4LCA4Nzc2LCAxNzEsIDE4NywgNjUyNzEsIDY1MjcyLCA2NTUzMywgNjU1MzMsIDY1Mjc1LCA2NTI3NiwgODIwMy8qNjU1MzMqLywKKyAgICAgICAgICAgIDE2MCwgMTczLCA2NTE1NCwgMTYzLCAxNjQsIDY1MTU2LCA2NTUzMywgNjU1MzMsIDY1MTY2LCA2NTE2NywgNjUxNzMsIDY1MTc3LCAxNTQ4LCA2NTE4MSwgNjUxODUsIDY1MTg5LAorICAgICAgICAgICAgMTYzMiwgMTYzMywgMTYzNCwgMTYzNSwgMTYzNiwgMTYzNywgMTYzOCwgMTYzOSwgMTY0MCwgMTY0MSwgNjUyMzMsIDE1NjMsIDY1MjAxLCA2NTIwNSwgNjUyMDksIDE1NjcsCisgICAgICAgICAgICAxNjIsIDY1MTUyLCA2NTE1MywgNjUxNTUsIDY1MTU3LCA2NTIyNiwgNjUxNjMsIDY1MTY1LCA2NTE2OSwgNjUxNzEsIDY1MTc1LCA2NTE3OSwgNjUxODMsIDY1MTg3LCA2NTE5MSwgNjUxOTMsCisgICAgICAgICAgICA2NTE5NSwgNjUxOTcsIDY1MTk5LCA2NTIwMywgNjUyMDcsIDY1MjExLCA2NTIxNSwgNjUyMTkvKjY1MjE3Ki8sIDY1MjIzLyo2NTIyMSovLCA2NTIyNywgNjUyMzEsIDE2NiwgMTcyLCAyNDcsIDIxNSwgNjUyMjUsCisgICAgICAgICAgICAxNjAwLCA2NTIzNSwgNjUyMzksIDY1MjQzLCA2NTI0NywgNjUyNTEsIDY1MjU1LCA2NTI1OSwgNjUyNjEsIDY1MjYzLCA2NTI2NywgNjUyMTMsIDY1MjI4LCA2NTIzMCwgNjUyMjksIDY1MjQ5LAorICAgICAgICAgICAgNjUxNDksIDY1MTQ4LyoxNjE3Ki8sIDY1MjUzLCA2NTI1NywgNjUyNjAsIDY1MjY0LCA2NTI2NiwgNjUyMzIsIDY1MjM3LCA2NTI2OSwgNjUyNzAsIDY1MjQ1LCA2NTI0MSwgNjUyNjUsIDk2MzIsIDY1NTMzfSk7CisvLyAgICAgICAgYWxsQ2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKy8vICAgICAgICAgICAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKy8vICAgICAgICAgICAgMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCisvLyAgICAgICAgICAgIDMyLCAzMywgMzQsIDM1LCAzNiwgMTY0MiwgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCisvLyAgICAgICAgICAgIDQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorLy8gICAgICAgICAgICA2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKy8vICAgICAgICAgICAgODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCisvLyAgICAgICAgICAgIDk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorLy8gICAgICAgICAgICAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisvLyAgICAgICAgICAgIDE3NiwgMTgzLCA4NzI5LCA4NzMwLCA5NjE4LCA5NDcyLCA5NDc0LCA5NTMyLCA5NTA4LCA5NTE2LCA5NTAwLCA5NTI0LCA5NDg4LCA5NDg0LCA5NDkyLCA5NDk2LAorLy8gICAgICAgICAgICA5NDYsIDg3MzQsIDk2NiwgMTc3LCAxODksIDE4OCwgODc3NiwgMTcxLCAxODcsIDY1MjcxLCA2NTI3MiwgNjU1MzMsIDY1NTMzLCA2NTI3NSwgNjUyNzYsIDY1NTMzLAorLy8gICAgICAgICAgICAxNjAsIDE3MywgNjUxNTQsIDE2MywgMTY0LCA2NTE1NiwgNjU1MzMsIDY1NTMzLCA2NTE2NiwgNjUxNjcsIDY1MTczLCA2NTE3NywgMTU0OCwgNjUxODEsIDY1MTg1LCA2NTE4OSwKKy8vICAgICAgICAgICAgMTYzMiwgMTYzMywgMTYzNCwgMTYzNSwgMTYzNiwgMTYzNywgMTYzOCwgMTYzOSwgMTY0MCwgMTY0MSwgNjUyMzMsIDE1NjMsIDY1MjAxLCA2NTIwNSwgNjUyMDksIDE1NjcsCisvLyAgICAgICAgICAgIDE2MiwgNjUxNTIsIDY1MTUzLCA2NTE1NSwgNjUxNTcsIDY1MjI2LCA2NTE2MywgNjUxNjUsIDY1MTY5LCA2NTE3MSwgNjUxNzUsIDY1MTc5LCA2NTE4MywgNjUxODcsIDY1MTkxLCA2NTE5MywKKy8vICAgICAgICAgICAgNjUxOTUsIDY1MTk3LCA2NTE5OSwgNjUyMDMsIDY1MjA3LCA2NTIxMSwgNjUyMTUsIDY1MjE3LCA2NTIyMSwgNjUyMjcsIDY1MjMxLCAxNjYsIDE3MiwgMjQ3LCAyMTUsIDY1MjI1LAorLy8gICAgICAgICAgICAxNjAwLCA2NTIzNSwgNjUyMzksIDY1MjQzLCA2NTI0NywgNjUyNTEsIDY1MjU1LCA2NTI1OSwgNjUyNjEsIDY1MjYzLCA2NTI2NywgNjUyMTMsIDY1MjI4LCA2NTIzMCwgNjUyMjksIDY1MjQ5LAorLy8gICAgICAgICAgICA2NTE0OSwgMTYxNywgNjUyNTMsIDY1MjU3LCA2NTI2MCwgNjUyNjQsIDY1MjY2LCA2NTIzMiwgNjUyMzcsIDY1MjY5LCA2NTI3MCwgNjUyNDUsIDY1MjQxLCA2NTI2NSwgOTYzMiwgNjU1MzN9KTsKKworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworLy8gICAgcHVibGljIHN0YXRpYyB2b2lkIF90ZXN0X0J5dGVzX0RpZmZlcmVudE9uZXNfUkkoKSB0aHJvd3MgQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uIHsKKy8vICAgICAgICBkZWNvZGVSZXBsYWNlKAorLy8gICAgICAgICAgICAgICAgdGhlc2VCeXRlcyhuZXcgaW50W117MjYsIDI4LCAzNywgMTI3LCAxNTksIDIxNSwgMjE2LCAyNDF9KSwKKy8vICAgICAgICAgICAgICAgIG5ldyBjaGFyW10gezI2LCAyOCwgMTY0MiwgMTI3LCA2NTUzMywgNjUyMTcsIDY1MjIxLCAxNjE3fSApOworLy8gICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHRlc3RfQnl0ZXNfRGlmZmVyZW50T25lc19BbmRyb2lkKCkgdGhyb3dzIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIEFuZHJvaWQ6CisgICAgICAgIGRlY29kZVJlcGxhY2UoCisgICAgICAgICAgICAgICAgdGhlc2VCeXRlcyhuZXcgaW50W117MjYsIDI4LCAzNywgMTI3LCAxNTksIDIxNSwgMjE2LCAyNDF9KSwKKyAgICAgICAgICAgICAgICBuZXcgY2hhcltdIHsyOCwgMTI3LCAzNywgMjYsIDgyMDMsIDY1MjE5LCA2NTIyMywgNjUxNDh9ICk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV9JU09fODg1OV8xLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV9JU09fODg1OV8xLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzFjZWRlNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lTT184ODU5XzEuamF2YQpAQCAtMCwwICsxLDQyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKK3B1YmxpYyBjbGFzcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfMSBleHRlbmRzIE9sZENoYXJzZXRfU2luZ2xlQnl0ZUFic3RyYWN0VGVzdCB7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyc2V0TmFtZSA9ICJJU08tODg1OS0xIjsKKyAgICAgICAgYWxsQ2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKyAgICAgICAgICAgIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisgICAgICAgICAgICAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKyAgICAgICAgICAgIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorICAgICAgICAgICAgNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCisgICAgICAgICAgICA2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKyAgICAgICAgICAgIDgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorICAgICAgICAgICAgOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisgICAgICAgICAgICAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisgICAgICAgICAgICAxMjgsIDEyOSwgMTMwLCAxMzEsIDEzMiwgMTMzLCAxMzQsIDEzNSwgMTM2LCAxMzcsIDEzOCwgMTM5LCAxNDAsIDE0MSwgMTQyLCAxNDMsCisgICAgICAgICAgICAxNDQsIDE0NSwgMTQ2LCAxNDcsIDE0OCwgMTQ5LCAxNTAsIDE1MSwgMTUyLCAxNTMsIDE1NCwgMTU1LCAxNTYsIDE1NywgMTU4LCAxNTksCisgICAgICAgICAgICAxNjAsIDE2MSwgMTYyLCAxNjMsIDE2NCwgMTY1LCAxNjYsIDE2NywgMTY4LCAxNjksIDE3MCwgMTcxLCAxNzIsIDE3MywgMTc0LCAxNzUsCisgICAgICAgICAgICAxNzYsIDE3NywgMTc4LCAxNzksIDE4MCwgMTgxLCAxODIsIDE4MywgMTg0LCAxODUsIDE4NiwgMTg3LCAxODgsIDE4OSwgMTkwLCAxOTEsCisgICAgICAgICAgICAxOTIsIDE5MywgMTk0LCAxOTUsIDE5NiwgMTk3LCAxOTgsIDE5OSwgMjAwLCAyMDEsIDIwMiwgMjAzLCAyMDQsIDIwNSwgMjA2LCAyMDcsCisgICAgICAgICAgICAyMDgsIDIwOSwgMjEwLCAyMTEsIDIxMiwgMjEzLCAyMTQsIDIxNSwgMjE2LCAyMTcsIDIxOCwgMjE5LCAyMjAsIDIyMSwgMjIyLCAyMjMsCisgICAgICAgICAgICAyMjQsIDIyNSwgMjI2LCAyMjcsIDIyOCwgMjI5LCAyMzAsIDIzMSwgMjMyLCAyMzMsIDIzNCwgMjM1LCAyMzYsIDIzNywgMjM4LCAyMzksCisgICAgICAgICAgICAyNDAsIDI0MSwgMjQyLCAyNDMsIDI0NCwgMjQ1LCAyNDYsIDI0NywgMjQ4LCAyNDksIDI1MCwgMjUxLCAyNTIsIDI1MywgMjU0LCAyNTV9KTsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lTT184ODU5XzExLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV9JU09fODg1OV8xMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyODMyMDcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV9JU09fODg1OV8xMS5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworLyogY2hhcnNldCB4LWlzby04ODU5XzExLTIwMDEgbm90IHN1cHBvcnRlZCBvbiB0aGUgUkkgKi8KK3B1YmxpYyBjbGFzcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfMTEgZXh0ZW5kcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVBYnN0cmFjdFRlc3QgeworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gIngtaXNvLTg4NTlfMTEtMjAwMSIgd2FzIHRoZSBjYW5vbmljYWwgbmFtZSBpbiBJQ1U0LjQgYnV0IG5vdCBpbiBJQ1U0LjYKKyAgICAgICAgLy8gIngtaXNvLTg4NTktMTEiIGlzIHRoZSBuZXcgY2Fub25pY2FsIG5hbWUuCisgICAgICAgIGNoYXJzZXROYW1lID0gIngtaXNvLTg4NTktMTEiOworICAgICAgICBhbGxDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworICAgICAgICAgICAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKyAgICAgICAgICAgIDE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorICAgICAgICAgICAgMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCisgICAgICAgICAgICA0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKyAgICAgICAgICAgIDY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorICAgICAgICAgICAgODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCisgICAgICAgICAgICA5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKyAgICAgICAgICAgIDExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKyAgICAgICAgICAgIDEyOCwgMTI5LCAxMzAsIDEzMSwgMTMyLCAxMzMsIDEzNCwgMTM1LCAxMzYsIDEzNywgMTM4LCAxMzksIDE0MCwgMTQxLCAxNDIsIDE0MywKKyAgICAgICAgICAgIDE0NCwgMTQ1LCAxNDYsIDE0NywgMTQ4LCAxNDksIDE1MCwgMTUxLCAxNTIsIDE1MywgMTU0LCAxNTUsIDE1NiwgMTU3LCAxNTgsIDE1OSwKKyAgICAgICAgICAgIDE2MCwgMzU4NSwgMzU4NiwgMzU4NywgMzU4OCwgMzU4OSwgMzU5MCwgMzU5MSwgMzU5MiwgMzU5MywgMzU5NCwgMzU5NSwgMzU5NiwgMzU5NywgMzU5OCwgMzU5OSwKKyAgICAgICAgICAgIDM2MDAsIDM2MDEsIDM2MDIsIDM2MDMsIDM2MDQsIDM2MDUsIDM2MDYsIDM2MDcsIDM2MDgsIDM2MDksIDM2MTAsIDM2MTEsIDM2MTIsIDM2MTMsIDM2MTQsIDM2MTUsCisgICAgICAgICAgICAzNjE2LCAzNjE3LCAzNjE4LCAzNjE5LCAzNjIwLCAzNjIxLCAzNjIyLCAzNjIzLCAzNjI0LCAzNjI1LCAzNjI2LCAzNjI3LCAzNjI4LCAzNjI5LCAzNjMwLCAzNjMxLAorICAgICAgICAgICAgMzYzMiwgMzYzMywgMzYzNCwgMzYzNSwgMzYzNiwgMzYzNywgMzYzOCwgMzYzOSwgMzY0MCwgMzY0MSwgMzY0MiwgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDM2NDcsCisgICAgICAgICAgICAzNjQ4LCAzNjQ5LCAzNjUwLCAzNjUxLCAzNjUyLCAzNjUzLCAzNjU0LCAzNjU1LCAzNjU2LCAzNjU3LCAzNjU4LCAzNjU5LCAzNjYwLCAzNjYxLCAzNjYyLCAzNjYzLAorICAgICAgICAgICAgMzY2NCwgMzY2NSwgMzY2NiwgMzY2NywgMzY2OCwgMzY2OSwgMzY3MCwgMzY3MSwgMzY3MiwgMzY3MywgMzY3NCwgMzY3NSwgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzN9KTsKKworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfMTMuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lTT184ODU5XzEzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjNlZmVkMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lTT184ODU5XzEzLmphdmEKQEAgLTAsMCArMSw0MiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFyc2V0OworCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lTT184ODU5XzEzIGV4dGVuZHMgT2xkQ2hhcnNldF9TaW5nbGVCeXRlQWJzdHJhY3RUZXN0IHsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJzZXROYW1lID0gIklTTy04ODU5LTEzIjsKKyAgICAgICAgYWxsQ2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKyAgICAgICAgICAgIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisgICAgICAgICAgICAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKyAgICAgICAgICAgIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorICAgICAgICAgICAgNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCisgICAgICAgICAgICA2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKyAgICAgICAgICAgIDgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorICAgICAgICAgICAgOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisgICAgICAgICAgICAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisgICAgICAgICAgICAxMjgsIDEyOSwgMTMwLCAxMzEsIDEzMiwgMTMzLCAxMzQsIDEzNSwgMTM2LCAxMzcsIDEzOCwgMTM5LCAxNDAsIDE0MSwgMTQyLCAxNDMsCisgICAgICAgICAgICAxNDQsIDE0NSwgMTQ2LCAxNDcsIDE0OCwgMTQ5LCAxNTAsIDE1MSwgMTUyLCAxNTMsIDE1NCwgMTU1LCAxNTYsIDE1NywgMTU4LCAxNTksCisgICAgICAgICAgICAxNjAsIDgyMjEsIDE2MiwgMTYzLCAxNjQsIDgyMjIsIDE2NiwgMTY3LCAyMTYsIDE2OSwgMzQyLCAxNzEsIDE3MiwgMTczLCAxNzQsIDE5OCwKKyAgICAgICAgICAgIDE3NiwgMTc3LCAxNzgsIDE3OSwgODIyMCwgMTgxLCAxODIsIDE4MywgMjQ4LCAxODUsIDM0MywgMTg3LCAxODgsIDE4OSwgMTkwLCAyMzAsCisgICAgICAgICAgICAyNjAsIDMwMiwgMjU2LCAyNjIsIDE5NiwgMTk3LCAyODAsIDI3NCwgMjY4LCAyMDEsIDM3NywgMjc4LCAyOTAsIDMxMCwgMjk4LCAzMTUsCisgICAgICAgICAgICAzNTIsIDMyMywgMzI1LCAyMTEsIDMzMiwgMjEzLCAyMTQsIDIxNSwgMzcwLCAzMjEsIDM0NiwgMzYyLCAyMjAsIDM3OSwgMzgxLCAyMjMsCisgICAgICAgICAgICAyNjEsIDMwMywgMjU3LCAyNjMsIDIyOCwgMjI5LCAyODEsIDI3NSwgMjY5LCAyMzMsIDM3OCwgMjc5LCAyOTEsIDMxMSwgMjk5LCAzMTYsCisgICAgICAgICAgICAzNTMsIDMyNCwgMzI2LCAyNDMsIDMzMywgMjQ1LCAyNDYsIDI0NywgMzcxLCAzMjIsIDM0NywgMzYzLCAyNTIsIDM4MCwgMzgyLCA4MjE3fSk7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV9JU09fODg1OV8xNS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfMTUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NmViNTU2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfMTUuamF2YQpAQCAtMCwwICsxLDQyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKK3B1YmxpYyBjbGFzcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfMTUgZXh0ZW5kcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVBYnN0cmFjdFRlc3QgeworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcnNldE5hbWUgPSAiSVNPLTg4NTktMTUiOworICAgICAgICBhbGxDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworICAgICAgICAgICAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKyAgICAgICAgICAgIDE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorICAgICAgICAgICAgMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCisgICAgICAgICAgICA0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKyAgICAgICAgICAgIDY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorICAgICAgICAgICAgODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCisgICAgICAgICAgICA5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKyAgICAgICAgICAgIDExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKyAgICAgICAgICAgIDEyOCwgMTI5LCAxMzAsIDEzMSwgMTMyLCAxMzMsIDEzNCwgMTM1LCAxMzYsIDEzNywgMTM4LCAxMzksIDE0MCwgMTQxLCAxNDIsIDE0MywKKyAgICAgICAgICAgIDE0NCwgMTQ1LCAxNDYsIDE0NywgMTQ4LCAxNDksIDE1MCwgMTUxLCAxNTIsIDE1MywgMTU0LCAxNTUsIDE1NiwgMTU3LCAxNTgsIDE1OSwKKyAgICAgICAgICAgIDE2MCwgMTYxLCAxNjIsIDE2MywgODM2NCwgMTY1LCAzNTIsIDE2NywgMzUzLCAxNjksIDE3MCwgMTcxLCAxNzIsIDE3MywgMTc0LCAxNzUsCisgICAgICAgICAgICAxNzYsIDE3NywgMTc4LCAxNzksIDM4MSwgMTgxLCAxODIsIDE4MywgMzgyLCAxODUsIDE4NiwgMTg3LCAzMzgsIDMzOSwgMzc2LCAxOTEsCisgICAgICAgICAgICAxOTIsIDE5MywgMTk0LCAxOTUsIDE5NiwgMTk3LCAxOTgsIDE5OSwgMjAwLCAyMDEsIDIwMiwgMjAzLCAyMDQsIDIwNSwgMjA2LCAyMDcsCisgICAgICAgICAgICAyMDgsIDIwOSwgMjEwLCAyMTEsIDIxMiwgMjEzLCAyMTQsIDIxNSwgMjE2LCAyMTcsIDIxOCwgMjE5LCAyMjAsIDIyMSwgMjIyLCAyMjMsCisgICAgICAgICAgICAyMjQsIDIyNSwgMjI2LCAyMjcsIDIyOCwgMjI5LCAyMzAsIDIzMSwgMjMyLCAyMzMsIDIzNCwgMjM1LCAyMzYsIDIzNywgMjM4LCAyMzksCisgICAgICAgICAgICAyNDAsIDI0MSwgMjQyLCAyNDMsIDI0NCwgMjQ1LCAyNDYsIDI0NywgMjQ4LCAyNDksIDI1MCwgMjUxLCAyNTIsIDI1MywgMjU0LCAyNTV9KTsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lTT184ODU5XzIuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lTT184ODU5XzIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNTFiMjAzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfMi5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworcHVibGljIGNsYXNzIE9sZENoYXJzZXRfU2luZ2xlQnl0ZV9JU09fODg1OV8yIGV4dGVuZHMgT2xkQ2hhcnNldF9TaW5nbGVCeXRlQWJzdHJhY3RUZXN0IHsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJzZXROYW1lID0gIklTTy04ODU5LTIiOworICAgICAgICBhbGxDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworICAgICAgICAgICAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKyAgICAgICAgICAgIDE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorICAgICAgICAgICAgMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCisgICAgICAgICAgICA0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKyAgICAgICAgICAgIDY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorICAgICAgICAgICAgODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCisgICAgICAgICAgICA5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKyAgICAgICAgICAgIDExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKyAgICAgICAgICAgIDEyOCwgMTI5LCAxMzAsIDEzMSwgMTMyLCAxMzMsIDEzNCwgMTM1LCAxMzYsIDEzNywgMTM4LCAxMzksIDE0MCwgMTQxLCAxNDIsIDE0MywKKyAgICAgICAgICAgIDE0NCwgMTQ1LCAxNDYsIDE0NywgMTQ4LCAxNDksIDE1MCwgMTUxLCAxNTIsIDE1MywgMTU0LCAxNTUsIDE1NiwgMTU3LCAxNTgsIDE1OSwKKyAgICAgICAgICAgIDE2MCwgMjYwLCA3MjgsIDMyMSwgMTY0LCAzMTcsIDM0NiwgMTY3LCAxNjgsIDM1MiwgMzUwLCAzNTYsIDM3NywgMTczLCAzODEsIDM3OSwKKyAgICAgICAgICAgIDE3NiwgMjYxLCA3MzEsIDMyMiwgMTgwLCAzMTgsIDM0NywgNzExLCAxODQsIDM1MywgMzUxLCAzNTcsIDM3OCwgNzMzLCAzODIsIDM4MCwKKyAgICAgICAgICAgIDM0MCwgMTkzLCAxOTQsIDI1OCwgMTk2LCAzMTMsIDI2MiwgMTk5LCAyNjgsIDIwMSwgMjgwLCAyMDMsIDI4MiwgMjA1LCAyMDYsIDI3MCwKKyAgICAgICAgICAgIDI3MiwgMzIzLCAzMjcsIDIxMSwgMjEyLCAzMzYsIDIxNCwgMjE1LCAzNDQsIDM2NiwgMjE4LCAzNjgsIDIyMCwgMjIxLCAzNTQsIDIyMywKKyAgICAgICAgICAgIDM0MSwgMjI1LCAyMjYsIDI1OSwgMjI4LCAzMTQsIDI2MywgMjMxLCAyNjksIDIzMywgMjgxLCAyMzUsIDI4MywgMjM3LCAyMzgsIDI3MSwKKyAgICAgICAgICAgIDI3MywgMzI0LCAzMjgsIDI0MywgMjQ0LCAzMzcsIDI0NiwgMjQ3LCAzNDUsIDM2NywgMjUwLCAzNjksIDI1MiwgMjUzLCAzNTUsIDcyOX0pOworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfMy5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfMy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZlNGZiZjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV9JU09fODg1OV8zLmphdmEKQEAgLTAsMCArMSw3NiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFyc2V0OworCitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb247CisKK3B1YmxpYyBjbGFzcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfMyBleHRlbmRzIE9sZENoYXJzZXRfU2luZ2xlQnl0ZUFic3RyYWN0VGVzdCB7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyc2V0TmFtZSA9ICJJU08tODg1OS0zIjsKKyAgICAgICAgYWxsQ2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKyAgICAgICAgICAgIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisgICAgICAgICAgICAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKyAgICAgICAgICAgIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorICAgICAgICAgICAgNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCisgICAgICAgICAgICA2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKyAgICAgICAgICAgIDgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorICAgICAgICAgICAgOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisgICAgICAgICAgICAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisgICAgICAgICAgICAxMjgsIDEyOSwgMTMwLCAxMzEsIDEzMiwgMTMzLCAxMzQsIDEzNSwgMTM2LCAxMzcsIDEzOCwgMTM5LCAxNDAsIDE0MSwgMTQyLCAxNDMsCisgICAgICAgICAgICAxNDQsIDE0NSwgMTQ2LCAxNDcsIDE0OCwgMTQ5LCAxNTAsIDE1MSwgMTUyLCAxNTMsIDE1NCwgMTU1LCAxNTYsIDE1NywgMTU4LCAxNTksCisgICAgICAgICAgICAxNjAsIDI5NCwgNzI4LCAxNjMsIDE2NCwgNjU1MzMsIDI5MiwgMTY3LCAxNjgsIDMwNCwgMzUwLCAyODYsIDMwOCwgMTczLCA2NTUzMywgMzc5LAorICAgICAgICAgICAgMTc2LCAyOTUsIDE3OCwgMTc5LCAxODAsIDE4MSwgMjkzLCAxODMsIDE4NCwgMzA1LCAzNTEsIDI4NywgMzA5LCAxODksIDY1NTMzLCAzODAsCisgICAgICAgICAgICAxOTIsIDE5MywgMTk0LCA2NTUzMywgMTk2LCAyNjYsIDI2NCwgMTk5LCAyMDAsIDIwMSwgMjAyLCAyMDMsIDIwNCwgMjA1LCAyMDYsIDIwNywKKyAgICAgICAgICAgIDY1NTMzLCAyMDksIDIxMCwgMjExLCAyMTIsIDI4OCwgMjE0LCAyMTUsIDI4NCwgMjE3LCAyMTgsIDIxOSwgMjIwLCAzNjQsIDM0OCwgMjIzLAorICAgICAgICAgICAgMjI0LCAyMjUsIDIyNiwgNjU1MzMsIDIyOCwgMjY3LCAyNjUsIDIzMSwgMjMyLCAyMzMsIDIzNCwgMjM1LCAyMzYsIDIzNywgMjM4LCAyMzksCisgICAgICAgICAgICA2NTUzMywgMjQxLCAyNDIsIDI0MywgMjQ0LCAyODksIDI0NiwgMjQ3LCAyODUsIDI0OSwgMjUwLCAyNTEsIDI1MiwgMzY1LCAzNDksIDcyOX0pOworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0ZXN0X0J5dGVzXzE2NigpIHRocm93cyBDaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb24geworICAgICAgICBkZWNvZGVSZXBsYWNlKAorICAgICAgICAgICAgICAgIG5ldyBieXRlW10geyhieXRlKTE2Nn0sCisgICAgICAgICAgICAgICAgbmV3IGNoYXJbXSB7MjkyfSApOworLy8gICAgICAgIEJ5dGVCdWZmZXIgaW5wdXRCQiA9IEJ5dGVCdWZmZXIud3JhcChuZXcgYnl0ZVtdIHsoYnl0ZSkxNjZ9KTsKKy8vICAgICAgICBDaGFyQnVmZmVyIG91dHB1dENCOworLy8gICAgICAgIGRlY29kZXIub25NYWxmb3JtZWRJbnB1dChDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFKTsKKy8vICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInRlc3RfQnl0ZXNfMTY2OiIpOworLy8gICAgICAgIG91dHB1dENCID0gZGVjb2Rlci5kZWNvZGUoaW5wdXRCQik7CisvLyAgICAgICAgb3V0cHV0Q0IucmV3aW5kKCk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxDaGFycygiRGVjb2RlZCBjaGFyYWN0ZXMgbXVzdCBtYXRjaCEiLAorLy8gICAgICAgICAgICAgICAgbmV3IGNoYXJbXSB7MjkyfSwKKy8vICAgICAgICAgICAgICAgIG91dHB1dENCLmFycmF5KCkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0ZXN0X0J5dGVzXzE5NSgpIHRocm93cyBDaGFyYWN0ZXJDb2RpbmdFeGNlcHRpb24geworICAgICAgICBkZWNvZGVSZXBsYWNlKAorICAgICAgICAgICAgICAgIG5ldyBieXRlW10geyhieXRlKTE5NX0sCisgICAgICAgICAgICAgICAgbmV3IGNoYXJbXSB7NjU1MzN9ICk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHRlc3RfQnl0ZXNfMTY1KCkgdGhyb3dzIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGRlY29kZVJlcGxhY2UoCisgICAgICAgICAgICAgICAgbmV3IGJ5dGVbXSB7KGJ5dGUpMTY1fSwKKyAgICAgICAgICAgICAgICBuZXcgY2hhcltdIHs2NTUzM30gKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdGVzdF9CeXRlc18xNjVfYW55KCkgdGhyb3dzIENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGRlY29kZVJlcGxhY2UoCisgICAgICAgICAgICAgICAgbmV3IGJ5dGVbXSB7KGJ5dGUpMTY1LCAzMn0sCisgICAgICAgICAgICAgICAgbmV3IGNoYXJbXSB7NjU1MzMsIDMyfSApOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lTT184ODU5XzQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lTT184ODU5XzQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYmRlNzdjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfNC5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworcHVibGljIGNsYXNzIE9sZENoYXJzZXRfU2luZ2xlQnl0ZV9JU09fODg1OV80IGV4dGVuZHMgT2xkQ2hhcnNldF9TaW5nbGVCeXRlQWJzdHJhY3RUZXN0IHsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJzZXROYW1lID0gIklTTy04ODU5LTQiOworICAgICAgICBhbGxDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworICAgICAgICAgICAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKyAgICAgICAgICAgIDE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorICAgICAgICAgICAgMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCisgICAgICAgICAgICA0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKyAgICAgICAgICAgIDY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorICAgICAgICAgICAgODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCisgICAgICAgICAgICA5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKyAgICAgICAgICAgIDExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKyAgICAgICAgICAgIDEyOCwgMTI5LCAxMzAsIDEzMSwgMTMyLCAxMzMsIDEzNCwgMTM1LCAxMzYsIDEzNywgMTM4LCAxMzksIDE0MCwgMTQxLCAxNDIsIDE0MywKKyAgICAgICAgICAgIDE0NCwgMTQ1LCAxNDYsIDE0NywgMTQ4LCAxNDksIDE1MCwgMTUxLCAxNTIsIDE1MywgMTU0LCAxNTUsIDE1NiwgMTU3LCAxNTgsIDE1OSwKKyAgICAgICAgICAgIDE2MCwgMjYwLCAzMTIsIDM0MiwgMTY0LCAyOTYsIDMxNSwgMTY3LCAxNjgsIDM1MiwgMjc0LCAyOTAsIDM1OCwgMTczLCAzODEsIDE3NSwKKyAgICAgICAgICAgIDE3NiwgMjYxLCA3MzEsIDM0MywgMTgwLCAyOTcsIDMxNiwgNzExLCAxODQsIDM1MywgMjc1LCAyOTEsIDM1OSwgMzMwLCAzODIsIDMzMSwKKyAgICAgICAgICAgIDI1NiwgMTkzLCAxOTQsIDE5NSwgMTk2LCAxOTcsIDE5OCwgMzAyLCAyNjgsIDIwMSwgMjgwLCAyMDMsIDI3OCwgMjA1LCAyMDYsIDI5OCwKKyAgICAgICAgICAgIDI3MiwgMzI1LCAzMzIsIDMxMCwgMjEyLCAyMTMsIDIxNCwgMjE1LCAyMTYsIDM3MCwgMjE4LCAyMTksIDIyMCwgMzYwLCAzNjIsIDIyMywKKyAgICAgICAgICAgIDI1NywgMjI1LCAyMjYsIDIyNywgMjI4LCAyMjksIDIzMCwgMzAzLCAyNjksIDIzMywgMjgxLCAyMzUsIDI3OSwgMjM3LCAyMzgsIDI5OSwKKyAgICAgICAgICAgIDI3MywgMzI2LCAzMzMsIDMxMSwgMjQ0LCAyNDUsIDI0NiwgMjQ3LCAyNDgsIDM3MSwgMjUwLCAyNTEsIDI1MiwgMzYxLCAzNjMsIDcyOX0pOworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfNS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfNS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIyOTEzN2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV9JU09fODg1OV81LmphdmEKQEAgLTAsMCArMSw0MiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFyc2V0OworCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lTT184ODU5XzUgZXh0ZW5kcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVBYnN0cmFjdFRlc3QgeworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcnNldE5hbWUgPSAiSVNPLTg4NTktNSI7CisgICAgICAgIGFsbENoYXJzID0gdGhlc2VDaGFycyhuZXcgaW50W117CisgICAgICAgICAgICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAorICAgICAgICAgICAgMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCisgICAgICAgICAgICAzMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKyAgICAgICAgICAgIDQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorICAgICAgICAgICAgNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCisgICAgICAgICAgICA4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKyAgICAgICAgICAgIDk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorICAgICAgICAgICAgMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorICAgICAgICAgICAgMTI4LCAxMjksIDEzMCwgMTMxLCAxMzIsIDEzMywgMTM0LCAxMzUsIDEzNiwgMTM3LCAxMzgsIDEzOSwgMTQwLCAxNDEsIDE0MiwgMTQzLAorICAgICAgICAgICAgMTQ0LCAxNDUsIDE0NiwgMTQ3LCAxNDgsIDE0OSwgMTUwLCAxNTEsIDE1MiwgMTUzLCAxNTQsIDE1NSwgMTU2LCAxNTcsIDE1OCwgMTU5LAorICAgICAgICAgICAgMTYwLCAxMDI1LCAxMDI2LCAxMDI3LCAxMDI4LCAxMDI5LCAxMDMwLCAxMDMxLCAxMDMyLCAxMDMzLCAxMDM0LCAxMDM1LCAxMDM2LCAxNzMsIDEwMzgsIDEwMzksCisgICAgICAgICAgICAxMDQwLCAxMDQxLCAxMDQyLCAxMDQzLCAxMDQ0LCAxMDQ1LCAxMDQ2LCAxMDQ3LCAxMDQ4LCAxMDQ5LCAxMDUwLCAxMDUxLCAxMDUyLCAxMDUzLCAxMDU0LCAxMDU1LAorICAgICAgICAgICAgMTA1NiwgMTA1NywgMTA1OCwgMTA1OSwgMTA2MCwgMTA2MSwgMTA2MiwgMTA2MywgMTA2NCwgMTA2NSwgMTA2NiwgMTA2NywgMTA2OCwgMTA2OSwgMTA3MCwgMTA3MSwKKyAgICAgICAgICAgIDEwNzIsIDEwNzMsIDEwNzQsIDEwNzUsIDEwNzYsIDEwNzcsIDEwNzgsIDEwNzksIDEwODAsIDEwODEsIDEwODIsIDEwODMsIDEwODQsIDEwODUsIDEwODYsIDEwODcsCisgICAgICAgICAgICAxMDg4LCAxMDg5LCAxMDkwLCAxMDkxLCAxMDkyLCAxMDkzLCAxMDk0LCAxMDk1LCAxMDk2LCAxMDk3LCAxMDk4LCAxMDk5LCAxMTAwLCAxMTAxLCAxMTAyLCAxMTAzLAorICAgICAgICAgICAgODQ3MCwgMTEwNSwgMTEwNiwgMTEwNywgMTEwOCwgMTEwOSwgMTExMCwgMTExMSwgMTExMiwgMTExMywgMTExNCwgMTExNSwgMTExNiwgMTY3LCAxMTE4LCAxMTE5fSk7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV9JU09fODg1OV82LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV9JU09fODg1OV82LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjk0YmVlNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lTT184ODU5XzYuamF2YQpAQCAtMCwwICsxLDQyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKK3B1YmxpYyBjbGFzcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfNiBleHRlbmRzIE9sZENoYXJzZXRfU2luZ2xlQnl0ZUFic3RyYWN0VGVzdCB7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyc2V0TmFtZSA9ICJJU08tODg1OS02IjsKKyAgICAgICAgYWxsQ2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKyAgICAgICAgICAgIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisgICAgICAgICAgICAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKyAgICAgICAgICAgIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorICAgICAgICAgICAgNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCisgICAgICAgICAgICA2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKyAgICAgICAgICAgIDgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorICAgICAgICAgICAgOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisgICAgICAgICAgICAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisgICAgICAgICAgICAxMjgsIDEyOSwgMTMwLCAxMzEsIDEzMiwgMTMzLCAxMzQsIDEzNSwgMTM2LCAxMzcsIDEzOCwgMTM5LCAxNDAsIDE0MSwgMTQyLCAxNDMsCisgICAgICAgICAgICAxNDQsIDE0NSwgMTQ2LCAxNDcsIDE0OCwgMTQ5LCAxNTAsIDE1MSwgMTUyLCAxNTMsIDE1NCwgMTU1LCAxNTYsIDE1NywgMTU4LCAxNTksCisgICAgICAgICAgICAxNjAsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDE2NCwgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDE1NDgsIDE3MywgNjU1MzMsIDY1NTMzLAorICAgICAgICAgICAgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCAxNTYzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCAxNTY3LAorICAgICAgICAgICAgNjU1MzMsIDE1NjksIDE1NzAsIDE1NzEsIDE1NzIsIDE1NzMsIDE1NzQsIDE1NzUsIDE1NzYsIDE1NzcsIDE1NzgsIDE1NzksIDE1ODAsIDE1ODEsIDE1ODIsIDE1ODMsCisgICAgICAgICAgICAxNTg0LCAxNTg1LCAxNTg2LCAxNTg3LCAxNTg4LCAxNTg5LCAxNTkwLCAxNTkxLCAxNTkyLCAxNTkzLCAxNTk0LCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsCisgICAgICAgICAgICAxNjAwLCAxNjAxLCAxNjAyLCAxNjAzLCAxNjA0LCAxNjA1LCAxNjA2LCAxNjA3LCAxNjA4LCAxNjA5LCAxNjEwLCAxNjExLCAxNjEyLCAxNjEzLCAxNjE0LCAxNjE1LAorICAgICAgICAgICAgMTYxNiwgMTYxNywgMTYxOCwgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzN9KTsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lTT184ODU5XzcuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lTT184ODU5XzcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MjQ5YjEwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfNy5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworcHVibGljIGNsYXNzIE9sZENoYXJzZXRfU2luZ2xlQnl0ZV9JU09fODg1OV83IGV4dGVuZHMgT2xkQ2hhcnNldF9TaW5nbGVCeXRlQWJzdHJhY3RUZXN0IHsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJzZXROYW1lID0gIklTTy04ODU5LTciOworICAgICAgICBhbGxDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworICAgICAgICAgICAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKyAgICAgICAgICAgIDE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorICAgICAgICAgICAgMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCisgICAgICAgICAgICA0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKyAgICAgICAgICAgIDY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorICAgICAgICAgICAgODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCisgICAgICAgICAgICA5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKyAgICAgICAgICAgIDExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDY1NTMzLAorICAgICAgICAgICAgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsCisgICAgICAgICAgICA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywKKyAgICAgICAgICAgIDE2MCwgODIxNiwgODIxNywgMTYzLCA2NTUzMywgNjU1MzMsIDE2NiwgMTY3LCAxNjgsIDE2OSwgNjU1MzMsIDE3MSwgMTcyLCAxNzMsIDY1NTMzLCA4MjEzLAorICAgICAgICAgICAgMTc2LCAxNzcsIDE3OCwgMTc5LCA5MDAsIDkwMSwgOTAyLCAxODMsIDkwNCwgOTA1LCA5MDYsIDE4NywgOTA4LCAxODksIDkxMCwgOTExLAorICAgICAgICAgICAgOTEyLCA5MTMsIDkxNCwgOTE1LCA5MTYsIDkxNywgOTE4LCA5MTksIDkyMCwgOTIxLCA5MjIsIDkyMywgOTI0LCA5MjUsIDkyNiwgOTI3LAorICAgICAgICAgICAgOTI4LCA5MjksIDY1NTMzLCA5MzEsIDkzMiwgOTMzLCA5MzQsIDkzNSwgOTM2LCA5MzcsIDkzOCwgOTM5LCA5NDAsIDk0MSwgOTQyLCA5NDMsCisgICAgICAgICAgICA5NDQsIDk0NSwgOTQ2LCA5NDcsIDk0OCwgOTQ5LCA5NTAsIDk1MSwgOTUyLCA5NTMsIDk1NCwgOTU1LCA5NTYsIDk1NywgOTU4LCA5NTksCisgICAgICAgICAgICA5NjAsIDk2MSwgOTYyLCA5NjMsIDk2NCwgOTY1LCA5NjYsIDk2NywgOTY4LCA5NjksIDk3MCwgOTcxLCA5NzIsIDk3MywgOTc0LCA2NTUzM30pOworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfOC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfOC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUzMDU0ZjcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV9JU09fODg1OV84LmphdmEKQEAgLTAsMCArMSw0MiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFyc2V0OworCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lTT184ODU5XzggZXh0ZW5kcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVBYnN0cmFjdFRlc3QgeworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcnNldE5hbWUgPSAiSVNPLTg4NTktOCI7CisgICAgICAgIGFsbENoYXJzID0gdGhlc2VDaGFycyhuZXcgaW50W117CisgICAgICAgICAgICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAorICAgICAgICAgICAgMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCisgICAgICAgICAgICAzMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKyAgICAgICAgICAgIDQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorICAgICAgICAgICAgNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCisgICAgICAgICAgICA4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKyAgICAgICAgICAgIDk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorICAgICAgICAgICAgMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorICAgICAgICAgICAgMTI4LCAxMjksIDEzMCwgMTMxLCAxMzIsIDEzMywgMTM0LCAxMzUsIDEzNiwgMTM3LCAxMzgsIDEzOSwgMTQwLCAxNDEsIDE0MiwgMTQzLAorICAgICAgICAgICAgMTQ0LCAxNDUsIDE0NiwgMTQ3LCAxNDgsIDE0OSwgMTUwLCAxNTEsIDE1MiwgMTUzLCAxNTQsIDE1NSwgMTU2LCAxNTcsIDE1OCwgMTU5LAorICAgICAgICAgICAgMTYwLCA2NTUzMywgMTYyLCAxNjMsIDE2NCwgMTY1LCAxNjYsIDE2NywgMTY4LCAxNjksIDIxNSwgMTcxLCAxNzIsIDE3MywgMTc0LCAxNzUsCisgICAgICAgICAgICAxNzYsIDE3NywgMTc4LCAxNzksIDE4MCwgMTgxLCAxODIsIDE4MywgMTg0LCAxODUsIDI0NywgMTg3LCAxODgsIDE4OSwgMTkwLCA2NTUzMywKKyAgICAgICAgICAgIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLAorICAgICAgICAgICAgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgODIxNSwKKyAgICAgICAgICAgIDE0ODgsIDE0ODksIDE0OTAsIDE0OTEsIDE0OTIsIDE0OTMsIDE0OTQsIDE0OTUsIDE0OTYsIDE0OTcsIDE0OTgsIDE0OTksIDE1MDAsIDE1MDEsIDE1MDIsIDE1MDMsCisgICAgICAgICAgICAxNTA0LCAxNTA1LCAxNTA2LCAxNTA3LCAxNTA4LCAxNTA5LCAxNTEwLCAxNTExLCAxNTEyLCAxNTEzLCAxNTE0LCA2NTUzMywgNjU1MzMsIDgyMDYsIDgyMDcsIDY1NTMzfSk7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV9JU09fODg1OV85LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV9JU09fODg1OV85LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzYyM2UyMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0lTT184ODU5XzkuamF2YQpAQCAtMCwwICsxLDQyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKK3B1YmxpYyBjbGFzcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVfSVNPXzg4NTlfOSBleHRlbmRzIE9sZENoYXJzZXRfU2luZ2xlQnl0ZUFic3RyYWN0VGVzdCB7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyc2V0TmFtZSA9ICJJU08tODg1OS05IjsKKyAgICAgICAgYWxsQ2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKyAgICAgICAgICAgIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisgICAgICAgICAgICAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKyAgICAgICAgICAgIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorICAgICAgICAgICAgNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCisgICAgICAgICAgICA2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKyAgICAgICAgICAgIDgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorICAgICAgICAgICAgOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisgICAgICAgICAgICAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisgICAgICAgICAgICAxMjgsIDEyOSwgMTMwLCAxMzEsIDEzMiwgMTMzLCAxMzQsIDEzNSwgMTM2LCAxMzcsIDEzOCwgMTM5LCAxNDAsIDE0MSwgMTQyLCAxNDMsCisgICAgICAgICAgICAxNDQsIDE0NSwgMTQ2LCAxNDcsIDE0OCwgMTQ5LCAxNTAsIDE1MSwgMTUyLCAxNTMsIDE1NCwgMTU1LCAxNTYsIDE1NywgMTU4LCAxNTksCisgICAgICAgICAgICAxNjAsIDE2MSwgMTYyLCAxNjMsIDE2NCwgMTY1LCAxNjYsIDE2NywgMTY4LCAxNjksIDE3MCwgMTcxLCAxNzIsIDE3MywgMTc0LCAxNzUsCisgICAgICAgICAgICAxNzYsIDE3NywgMTc4LCAxNzksIDE4MCwgMTgxLCAxODIsIDE4MywgMTg0LCAxODUsIDE4NiwgMTg3LCAxODgsIDE4OSwgMTkwLCAxOTEsCisgICAgICAgICAgICAxOTIsIDE5MywgMTk0LCAxOTUsIDE5NiwgMTk3LCAxOTgsIDE5OSwgMjAwLCAyMDEsIDIwMiwgMjAzLCAyMDQsIDIwNSwgMjA2LCAyMDcsCisgICAgICAgICAgICAyODYsIDIwOSwgMjEwLCAyMTEsIDIxMiwgMjEzLCAyMTQsIDIxNSwgMjE2LCAyMTcsIDIxOCwgMjE5LCAyMjAsIDMwNCwgMzUwLCAyMjMsCisgICAgICAgICAgICAyMjQsIDIyNSwgMjI2LCAyMjcsIDIyOCwgMjI5LCAyMzAsIDIzMSwgMjMyLCAyMzMsIDIzNCwgMjM1LCAyMzYsIDIzNywgMjM4LCAyMzksCisgICAgICAgICAgICAyODcsIDI0MSwgMjQyLCAyNDMsIDI0NCwgMjQ1LCAyNDYsIDI0NywgMjQ4LCAyNDksIDI1MCwgMjUxLCAyNTIsIDMwNSwgMzUxLCAyNTV9KTsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0tPSThfUi5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfS09JOF9SLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2I2NTMyZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX0tPSThfUi5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworcHVibGljIGNsYXNzIE9sZENoYXJzZXRfU2luZ2xlQnl0ZV9LT0k4X1IgZXh0ZW5kcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVBYnN0cmFjdFRlc3QgeworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcnNldE5hbWUgPSAiS09JOC1SIjsKKyAgICAgICAgYWxsQ2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKyAgICAgICAgICAgIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisgICAgICAgICAgICAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKyAgICAgICAgICAgIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorICAgICAgICAgICAgNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCisgICAgICAgICAgICA2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKyAgICAgICAgICAgIDgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorICAgICAgICAgICAgOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisgICAgICAgICAgICAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisgICAgICAgICAgICA5NDcyLCA5NDc0LCA5NDg0LCA5NDg4LCA5NDkyLCA5NDk2LCA5NTAwLCA5NTA4LCA5NTE2LCA5NTI0LCA5NTMyLCA5NjAwLCA5NjA0LCA5NjA4LCA5NjEyLCA5NjE2LAorICAgICAgICAgICAgOTYxNywgOTYxOCwgOTYxOSwgODk5MiwgOTYzMiwgODcyOSwgODczMCwgODc3NiwgODgwNCwgODgwNSwgMTYwLCA4OTkzLCAxNzYsIDE3OCwgMTgzLCAyNDcsCisgICAgICAgICAgICA5NTUyLCA5NTUzLCA5NTU0LCAxMTA1LCA5NTU1LCA5NTU2LCA5NTU3LCA5NTU4LCA5NTU5LCA5NTYwLCA5NTYxLCA5NTYyLCA5NTYzLCA5NTY0LCA5NTY1LCA5NTY2LAorICAgICAgICAgICAgOTU2NywgOTU2OCwgOTU2OSwgMTAyNSwgOTU3MCwgOTU3MSwgOTU3MiwgOTU3MywgOTU3NCwgOTU3NSwgOTU3NiwgOTU3NywgOTU3OCwgOTU3OSwgOTU4MCwgMTY5LAorICAgICAgICAgICAgMTEwMiwgMTA3MiwgMTA3MywgMTA5NCwgMTA3NiwgMTA3NywgMTA5MiwgMTA3NSwgMTA5MywgMTA4MCwgMTA4MSwgMTA4MiwgMTA4MywgMTA4NCwgMTA4NSwgMTA4NiwKKyAgICAgICAgICAgIDEwODcsIDExMDMsIDEwODgsIDEwODksIDEwOTAsIDEwOTEsIDEwNzgsIDEwNzQsIDExMDAsIDEwOTksIDEwNzksIDEwOTYsIDExMDEsIDEwOTcsIDEwOTUsIDEwOTgsCisgICAgICAgICAgICAxMDcwLCAxMDQwLCAxMDQxLCAxMDYyLCAxMDQ0LCAxMDQ1LCAxMDYwLCAxMDQzLCAxMDYxLCAxMDQ4LCAxMDQ5LCAxMDUwLCAxMDUxLCAxMDUyLCAxMDUzLCAxMDU0LAorICAgICAgICAxMDU1LCAxMDcxLCAxMDU2LCAxMDU3LCAxMDU4LCAxMDU5LCAxMDQ2LCAxMDQyLCAxMDY4LCAxMDY3LCAxMDQ3LCAxMDY0LCAxMDY5LCAxMDY1LCAxMDYzLCAxMDY2fSk7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV9VU19BU0NJSS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfVVNfQVNDSUkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZTE1YTYwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfVVNfQVNDSUkuamF2YQpAQCAtMCwwICsxLDQyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKK3B1YmxpYyBjbGFzcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVfVVNfQVNDSUkgZXh0ZW5kcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVBYnN0cmFjdFRlc3QgeworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcnNldE5hbWUgPSAiVVMtQVNDSUkiOworICAgICAgICBhbGxDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworICAgICAgICAgICAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKyAgICAgICAgICAgIDE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorICAgICAgICAgICAgMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCisgICAgICAgICAgICA0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKyAgICAgICAgICAgIDY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorICAgICAgICAgICAgODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCisgICAgICAgICAgICA5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKyAgICAgICAgICAgIDExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKyAgICAgICAgICAgIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLAorICAgICAgICAgICAgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsCisgICAgICAgICAgICA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywKKyAgICAgICAgICAgIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLAorICAgICAgICAgICAgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsCisgICAgICAgICAgICA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywKKyAgICAgICAgICAgIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLAorICAgICAgICAgICAgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzN9KTsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX3dpbmRvd3NfMTI1MC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfd2luZG93c18xMjUwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2JiNTM0ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX3dpbmRvd3NfMTI1MC5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworcHVibGljIGNsYXNzIE9sZENoYXJzZXRfU2luZ2xlQnl0ZV93aW5kb3dzXzEyNTAgZXh0ZW5kcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVBYnN0cmFjdFRlc3QgeworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcnNldE5hbWUgPSAid2luZG93cy0xMjUwIjsKKyAgICAgICAgYWxsQ2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKyAgICAgICAgICAgIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisgICAgICAgICAgICAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKyAgICAgICAgICAgIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorICAgICAgICAgICAgNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCisgICAgICAgICAgICA2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKyAgICAgICAgICAgIDgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorICAgICAgICAgICAgOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisgICAgICAgICAgICAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisgICAgICAgICAgICA4MzY0LCA2NTUzMywgODIxOCwgNjU1MzMsIDgyMjIsIDgyMzAsIDgyMjQsIDgyMjUsIDY1NTMzLCA4MjQwLCAzNTIsIDgyNDksIDM0NiwgMzU2LCAzODEsIDM3NywKKyAgICAgICAgICAgIDY1NTMzLCA4MjE2LCA4MjE3LCA4MjIwLCA4MjIxLCA4MjI2LCA4MjExLCA4MjEyLCA2NTUzMywgODQ4MiwgMzUzLCA4MjUwLCAzNDcsIDM1NywgMzgyLCAzNzgsCisgICAgICAgICAgICAxNjAsIDcxMSwgNzI4LCAzMjEsIDE2NCwgMjYwLCAxNjYsIDE2NywgMTY4LCAxNjksIDM1MCwgMTcxLCAxNzIsIDE3MywgMTc0LCAzNzksCisgICAgICAgICAgICAxNzYsIDE3NywgNzMxLCAzMjIsIDE4MCwgMTgxLCAxODIsIDE4MywgMTg0LCAyNjEsIDM1MSwgMTg3LCAzMTcsIDczMywgMzE4LCAzODAsCisgICAgICAgICAgICAzNDAsIDE5MywgMTk0LCAyNTgsIDE5NiwgMzEzLCAyNjIsIDE5OSwgMjY4LCAyMDEsIDI4MCwgMjAzLCAyODIsIDIwNSwgMjA2LCAyNzAsCisgICAgICAgICAgICAyNzIsIDMyMywgMzI3LCAyMTEsIDIxMiwgMzM2LCAyMTQsIDIxNSwgMzQ0LCAzNjYsIDIxOCwgMzY4LCAyMjAsIDIyMSwgMzU0LCAyMjMsCisgICAgICAgICAgICAzNDEsIDIyNSwgMjI2LCAyNTksIDIyOCwgMzE0LCAyNjMsIDIzMSwgMjY5LCAyMzMsIDI4MSwgMjM1LCAyODMsIDIzNywgMjM4LCAyNzEsCisgICAgICAgICAgICAyNzMsIDMyNCwgMzI4LCAyNDMsIDI0NCwgMzM3LCAyNDYsIDI0NywgMzQ1LCAzNjcsIDI1MCwgMzY5LCAyNTIsIDI1MywgMzU1LCA3Mjl9KTsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX3dpbmRvd3NfMTI1MS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfd2luZG93c18xMjUxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjNmNWEzMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX3dpbmRvd3NfMTI1MS5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworcHVibGljIGNsYXNzIE9sZENoYXJzZXRfU2luZ2xlQnl0ZV93aW5kb3dzXzEyNTEgZXh0ZW5kcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVBYnN0cmFjdFRlc3QgeworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcnNldE5hbWUgPSAid2luZG93cy0xMjUxIjsKKyAgICAgICAgYWxsQ2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKyAgICAgICAgICAgIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisgICAgICAgICAgICAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKyAgICAgICAgICAgIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorICAgICAgICAgICAgNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCisgICAgICAgICAgICA2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKyAgICAgICAgICAgIDgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorICAgICAgICAgICAgOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisgICAgICAgICAgICAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisgICAgICAgICAgICAxMDI2LCAxMDI3LCA4MjE4LCAxMTA3LCA4MjIyLCA4MjMwLCA4MjI0LCA4MjI1LCA4MzY0LCA4MjQwLCAxMDMzLCA4MjQ5LCAxMDM0LCAxMDM2LCAxMDM1LCAxMDM5LAorICAgICAgICAgICAgMTEwNiwgODIxNiwgODIxNywgODIyMCwgODIyMSwgODIyNiwgODIxMSwgODIxMiwgNjU1MzMsIDg0ODIsIDExMTMsIDgyNTAsIDExMTQsIDExMTYsIDExMTUsIDExMTksCisgICAgICAgICAgICAxNjAsIDEwMzgsIDExMTgsIDEwMzIsIDE2NCwgMTE2OCwgMTY2LCAxNjcsIDEwMjUsIDE2OSwgMTAyOCwgMTcxLCAxNzIsIDE3MywgMTc0LCAxMDMxLAorICAgICAgICAgICAgMTc2LCAxNzcsIDEwMzAsIDExMTAsIDExNjksIDE4MSwgMTgyLCAxODMsIDExMDUsIDg0NzAsIDExMDgsIDE4NywgMTExMiwgMTAyOSwgMTEwOSwgMTExMSwKKyAgICAgICAgICAgIDEwNDAsIDEwNDEsIDEwNDIsIDEwNDMsIDEwNDQsIDEwNDUsIDEwNDYsIDEwNDcsIDEwNDgsIDEwNDksIDEwNTAsIDEwNTEsIDEwNTIsIDEwNTMsIDEwNTQsIDEwNTUsCisgICAgICAgICAgICAxMDU2LCAxMDU3LCAxMDU4LCAxMDU5LCAxMDYwLCAxMDYxLCAxMDYyLCAxMDYzLCAxMDY0LCAxMDY1LCAxMDY2LCAxMDY3LCAxMDY4LCAxMDY5LCAxMDcwLCAxMDcxLAorICAgICAgICAgICAgMTA3MiwgMTA3MywgMTA3NCwgMTA3NSwgMTA3NiwgMTA3NywgMTA3OCwgMTA3OSwgMTA4MCwgMTA4MSwgMTA4MiwgMTA4MywgMTA4NCwgMTA4NSwgMTA4NiwgMTA4NywKKyAgICAgICAgICAgIDEwODgsIDEwODksIDEwOTAsIDEwOTEsIDEwOTIsIDEwOTMsIDEwOTQsIDEwOTUsIDEwOTYsIDEwOTcsIDEwOTgsIDEwOTksIDExMDAsIDExMDEsIDExMDIsIDExMDN9KTsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX3dpbmRvd3NfMTI1Mi5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfd2luZG93c18xMjUyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODEzMjE5YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX3dpbmRvd3NfMTI1Mi5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworcHVibGljIGNsYXNzIE9sZENoYXJzZXRfU2luZ2xlQnl0ZV93aW5kb3dzXzEyNTIgZXh0ZW5kcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVBYnN0cmFjdFRlc3QgeworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcnNldE5hbWUgPSAid2luZG93cy0xMjUyIjsKKyAgICAgICAgYWxsQ2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKyAgICAgICAgICAgIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisgICAgICAgICAgICAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKyAgICAgICAgICAgIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorICAgICAgICAgICAgNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCisgICAgICAgICAgICA2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKyAgICAgICAgICAgIDgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorICAgICAgICAgICAgOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisgICAgICAgICAgICAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisgICAgICAgICAgICA4MzY0LCA2NTUzMywgODIxOCwgNDAyLCA4MjIyLCA4MjMwLCA4MjI0LCA4MjI1LCA3MTAsIDgyNDAsIDM1MiwgODI0OSwgMzM4LCA2NTUzMywgMzgxLCA2NTUzMywKKyAgICAgICAgICAgIDY1NTMzLCA4MjE2LCA4MjE3LCA4MjIwLCA4MjIxLCA4MjI2LCA4MjExLCA4MjEyLCA3MzIsIDg0ODIsIDM1MywgODI1MCwgMzM5LCA2NTUzMywgMzgyLCAzNzYsCisgICAgICAgICAgICAxNjAsIDE2MSwgMTYyLCAxNjMsIDE2NCwgMTY1LCAxNjYsIDE2NywgMTY4LCAxNjksIDE3MCwgMTcxLCAxNzIsIDE3MywgMTc0LCAxNzUsCisgICAgICAgICAgICAxNzYsIDE3NywgMTc4LCAxNzksIDE4MCwgMTgxLCAxODIsIDE4MywgMTg0LCAxODUsIDE4NiwgMTg3LCAxODgsIDE4OSwgMTkwLCAxOTEsCisgICAgICAgICAgICAxOTIsIDE5MywgMTk0LCAxOTUsIDE5NiwgMTk3LCAxOTgsIDE5OSwgMjAwLCAyMDEsIDIwMiwgMjAzLCAyMDQsIDIwNSwgMjA2LCAyMDcsCisgICAgICAgICAgICAyMDgsIDIwOSwgMjEwLCAyMTEsIDIxMiwgMjEzLCAyMTQsIDIxNSwgMjE2LCAyMTcsIDIxOCwgMjE5LCAyMjAsIDIyMSwgMjIyLCAyMjMsCisgICAgICAgICAgICAyMjQsIDIyNSwgMjI2LCAyMjcsIDIyOCwgMjI5LCAyMzAsIDIzMSwgMjMyLCAyMzMsIDIzNCwgMjM1LCAyMzYsIDIzNywgMjM4LCAyMzksCisgICAgICAgICAgICAyNDAsIDI0MSwgMjQyLCAyNDMsIDI0NCwgMjQ1LCAyNDYsIDI0NywgMjQ4LCAyNDksIDI1MCwgMjUxLCAyNTIsIDI1MywgMjU0LCAyNTV9KTsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX3dpbmRvd3NfMTI1My5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfd2luZG93c18xMjUzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzY1N2E4ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX3dpbmRvd3NfMTI1My5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworcHVibGljIGNsYXNzIE9sZENoYXJzZXRfU2luZ2xlQnl0ZV93aW5kb3dzXzEyNTMgZXh0ZW5kcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVBYnN0cmFjdFRlc3QgeworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcnNldE5hbWUgPSAid2luZG93cy0xMjUzIjsKKyAgICAgICAgYWxsQ2hhcnMgPSB0aGVzZUNoYXJzKG5ldyBpbnRbXXsKKyAgICAgICAgICAgIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsCisgICAgICAgICAgICAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgMjYsIDI3LCAyOCwgMjksIDMwLCAzMSwKKyAgICAgICAgICAgIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LAorICAgICAgICAgICAgNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsCisgICAgICAgICAgICA2NCwgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwKKyAgICAgICAgICAgIDgwLCA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5MywgOTQsIDk1LAorICAgICAgICAgICAgOTYsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsCisgICAgICAgICAgICAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMiwgMTIzLCAxMjQsIDEyNSwgMTI2LCAxMjcsCisgICAgICAgICAgICA4MzY0LCA2NTUzMywgODIxOCwgNDAyLCA4MjIyLCA4MjMwLCA4MjI0LCA4MjI1LCA2NTUzMywgODI0MCwgNjU1MzMsIDgyNDksIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLAorICAgICAgICAgICAgNjU1MzMsIDgyMTYsIDgyMTcsIDgyMjAsIDgyMjEsIDgyMjYsIDgyMTEsIDgyMTIsIDY1NTMzLCA4NDgyLCA2NTUzMywgODI1MCwgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsCisgICAgICAgICAgICAxNjAsIDkwMSwgOTAyLCAxNjMsIDE2NCwgMTY1LCAxNjYsIDE2NywgMTY4LCAxNjksIDY1NTMzLCAxNzEsIDE3MiwgMTczLCAxNzQsIDgyMTMsCisgICAgICAgICAgICAxNzYsIDE3NywgMTc4LCAxNzksIDkwMCwgMTgxLCAxODIsIDE4MywgOTA0LCA5MDUsIDkwNiwgMTg3LCA5MDgsIDE4OSwgOTEwLCA5MTEsCisgICAgICAgICAgICA5MTIsIDkxMywgOTE0LCA5MTUsIDkxNiwgOTE3LCA5MTgsIDkxOSwgOTIwLCA5MjEsIDkyMiwgOTIzLCA5MjQsIDkyNSwgOTI2LCA5MjcsCisgICAgICAgICAgICA5MjgsIDkyOSwgNjU1MzMsIDkzMSwgOTMyLCA5MzMsIDkzNCwgOTM1LCA5MzYsIDkzNywgOTM4LCA5MzksIDk0MCwgOTQxLCA5NDIsIDk0MywKKyAgICAgICAgICAgIDk0NCwgOTQ1LCA5NDYsIDk0NywgOTQ4LCA5NDksIDk1MCwgOTUxLCA5NTIsIDk1MywgOTU0LCA5NTUsIDk1NiwgOTU3LCA5NTgsIDk1OSwKKyAgICAgICAgICAgIDk2MCwgOTYxLCA5NjIsIDk2MywgOTY0LCA5NjUsIDk2NiwgOTY3LCA5NjgsIDk2OSwgOTcwLCA5NzEsIDk3MiwgOTczLCA5NzQsIDY1NTMzfSk7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV93aW5kb3dzXzEyNTQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX3dpbmRvd3NfMTI1NC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2NjFmMWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV93aW5kb3dzXzEyNTQuamF2YQpAQCAtMCwwICsxLDQyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKK3B1YmxpYyBjbGFzcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVfd2luZG93c18xMjU0IGV4dGVuZHMgT2xkQ2hhcnNldF9TaW5nbGVCeXRlQWJzdHJhY3RUZXN0IHsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJzZXROYW1lID0gIndpbmRvd3MtMTI1NCI7CisgICAgICAgIGFsbENoYXJzID0gdGhlc2VDaGFycyhuZXcgaW50W117CisgICAgICAgICAgICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAorICAgICAgICAgICAgMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCisgICAgICAgICAgICAzMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKyAgICAgICAgICAgIDQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorICAgICAgICAgICAgNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCisgICAgICAgICAgICA4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKyAgICAgICAgICAgIDk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorICAgICAgICAgICAgMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorICAgICAgICAgICAgODM2NCwgNjU1MzMsIDgyMTgsIDQwMiwgODIyMiwgODIzMCwgODIyNCwgODIyNSwgNzEwLCA4MjQwLCAzNTIsIDgyNDksIDMzOCwgNjU1MzMsIDY1NTMzLCA2NTUzMywKKyAgICAgICAgICAgIDY1NTMzLCA4MjE2LCA4MjE3LCA4MjIwLCA4MjIxLCA4MjI2LCA4MjExLCA4MjEyLCA3MzIsIDg0ODIsIDM1MywgODI1MCwgMzM5LCA2NTUzMywgNjU1MzMsIDM3NiwKKyAgICAgICAgICAgIDE2MCwgMTYxLCAxNjIsIDE2MywgMTY0LCAxNjUsIDE2NiwgMTY3LCAxNjgsIDE2OSwgMTcwLCAxNzEsIDE3MiwgMTczLCAxNzQsIDE3NSwKKyAgICAgICAgICAgIDE3NiwgMTc3LCAxNzgsIDE3OSwgMTgwLCAxODEsIDE4MiwgMTgzLCAxODQsIDE4NSwgMTg2LCAxODcsIDE4OCwgMTg5LCAxOTAsIDE5MSwKKyAgICAgICAgICAgIDE5MiwgMTkzLCAxOTQsIDE5NSwgMTk2LCAxOTcsIDE5OCwgMTk5LCAyMDAsIDIwMSwgMjAyLCAyMDMsIDIwNCwgMjA1LCAyMDYsIDIwNywKKyAgICAgICAgICAgIDI4NiwgMjA5LCAyMTAsIDIxMSwgMjEyLCAyMTMsIDIxNCwgMjE1LCAyMTYsIDIxNywgMjE4LCAyMTksIDIyMCwgMzA0LCAzNTAsIDIyMywKKyAgICAgICAgICAgIDIyNCwgMjI1LCAyMjYsIDIyNywgMjI4LCAyMjksIDIzMCwgMjMxLCAyMzIsIDIzMywgMjM0LCAyMzUsIDIzNiwgMjM3LCAyMzgsIDIzOSwKKyAgICAgICAgICAgIDI4NywgMjQxLCAyNDIsIDI0MywgMjQ0LCAyNDUsIDI0NiwgMjQ3LCAyNDgsIDI0OSwgMjUwLCAyNTEsIDI1MiwgMzA1LCAzNTEsIDI1NX0pOworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfd2luZG93c18xMjU1LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV93aW5kb3dzXzEyNTUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYjI3OWQ1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfd2luZG93c18xMjU1LmphdmEKQEAgLTAsMCArMSw0MiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFyc2V0OworCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9TaW5nbGVCeXRlX3dpbmRvd3NfMTI1NSBleHRlbmRzIE9sZENoYXJzZXRfU2luZ2xlQnl0ZUFic3RyYWN0VGVzdCB7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyc2V0TmFtZSA9ICJ3aW5kb3dzLTEyNTUiOworICAgICAgICBhbGxDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworICAgICAgICAgICAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKyAgICAgICAgICAgIDE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorICAgICAgICAgICAgMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCisgICAgICAgICAgICA0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKyAgICAgICAgICAgIDY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorICAgICAgICAgICAgODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCisgICAgICAgICAgICA5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKyAgICAgICAgICAgIDExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKyAgICAgICAgICAgIDgzNjQsIDY1NTMzLCA4MjE4LCA0MDIsIDgyMjIsIDgyMzAsIDgyMjQsIDgyMjUsIDcxMCwgODI0MCwgNjU1MzMsIDgyNDksIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLAorICAgICAgICAgICAgNjU1MzMsIDgyMTYsIDgyMTcsIDgyMjAsIDgyMjEsIDgyMjYsIDgyMTEsIDgyMTIsIDczMiwgODQ4MiwgNjU1MzMsIDgyNTAsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLAorICAgICAgICAgICAgMTYwLCAxNjEsIDE2MiwgMTYzLCA4MzYyLCAxNjUsIDE2NiwgMTY3LCAxNjgsIDE2OSwgMjE1LCAxNzEsIDE3MiwgMTczLCAxNzQsIDE3NSwKKyAgICAgICAgICAgIDE3NiwgMTc3LCAxNzgsIDE3OSwgMTgwLCAxODEsIDE4MiwgMTgzLCAxODQsIDE4NSwgMjQ3LCAxODcsIDE4OCwgMTg5LCAxOTAsIDE5MSwKKyAgICAgICAgICAgIDE0NTYsIDE0NTcsIDE0NTgsIDE0NTksIDE0NjAsIDE0NjEsIDE0NjIsIDE0NjMsIDE0NjQsIDE0NjUsIDY1NTMzLCAxNDY3LCAxNDY4LCAxNDY5LCAxNDcwLCAxNDcxLAorICAgICAgICAgICAgMTQ3MiwgMTQ3MywgMTQ3NCwgMTQ3NSwgMTUyMCwgMTUyMSwgMTUyMiwgMTUyMywgMTUyNCwgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsIDY1NTMzLCA2NTUzMywgNjU1MzMsCisgICAgICAgICAgICAxNDg4LCAxNDg5LCAxNDkwLCAxNDkxLCAxNDkyLCAxNDkzLCAxNDk0LCAxNDk1LCAxNDk2LCAxNDk3LCAxNDk4LCAxNDk5LCAxNTAwLCAxNTAxLCAxNTAyLCAxNTAzLAorICAgICAgICAgICAgMTUwNCwgMTUwNSwgMTUwNiwgMTUwNywgMTUwOCwgMTUwOSwgMTUxMCwgMTUxMSwgMTUxMiwgMTUxMywgMTUxNCwgNjU1MzMsIDY1NTMzLCA4MjA2LCA4MjA3LCA2NTUzM30pOworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfd2luZG93c18xMjU2LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV93aW5kb3dzXzEyNTYuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45OTk3NmI5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfd2luZG93c18xMjU2LmphdmEKQEAgLTAsMCArMSw0MiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFyc2V0OworCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9TaW5nbGVCeXRlX3dpbmRvd3NfMTI1NiBleHRlbmRzIE9sZENoYXJzZXRfU2luZ2xlQnl0ZUFic3RyYWN0VGVzdCB7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyc2V0TmFtZSA9ICJ3aW5kb3dzLTEyNTYiOworICAgICAgICBhbGxDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworICAgICAgICAgICAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKyAgICAgICAgICAgIDE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorICAgICAgICAgICAgMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCisgICAgICAgICAgICA0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKyAgICAgICAgICAgIDY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorICAgICAgICAgICAgODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCisgICAgICAgICAgICA5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKyAgICAgICAgICAgIDExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKyAgICAgICAgICAgIDgzNjQsIDE2NjIsIDgyMTgsIDQwMiwgODIyMiwgODIzMCwgODIyNCwgODIyNSwgNzEwLCA4MjQwLCAxNjU3LCA4MjQ5LCAzMzgsIDE2NzAsIDE2ODgsIDE2NzIsCisgICAgICAgICAgICAxNzExLCA4MjE2LCA4MjE3LCA4MjIwLCA4MjIxLCA4MjI2LCA4MjExLCA4MjEyLCAxNzA1LCA4NDgyLCAxNjgxLCA4MjUwLCAzMzksIDgyMDQsIDgyMDUsIDE3MjIsCisgICAgICAgICAgICAxNjAsIDE1NDgsIDE2MiwgMTYzLCAxNjQsIDE2NSwgMTY2LCAxNjcsIDE2OCwgMTY5LCAxNzI2LCAxNzEsIDE3MiwgMTczLCAxNzQsIDE3NSwKKyAgICAgICAgICAgIDE3NiwgMTc3LCAxNzgsIDE3OSwgMTgwLCAxODEsIDE4MiwgMTgzLCAxODQsIDE4NSwgMTU2MywgMTg3LCAxODgsIDE4OSwgMTkwLCAxNTY3LAorICAgICAgICAgICAgMTcyOSwgMTU2OSwgMTU3MCwgMTU3MSwgMTU3MiwgMTU3MywgMTU3NCwgMTU3NSwgMTU3NiwgMTU3NywgMTU3OCwgMTU3OSwgMTU4MCwgMTU4MSwgMTU4MiwgMTU4MywKKyAgICAgICAgICAgIDE1ODQsIDE1ODUsIDE1ODYsIDE1ODcsIDE1ODgsIDE1ODksIDE1OTAsIDIxNSwgMTU5MSwgMTU5MiwgMTU5MywgMTU5NCwgMTYwMCwgMTYwMSwgMTYwMiwgMTYwMywKKyAgICAgICAgICAgIDIyNCwgMTYwNCwgMjI2LCAxNjA1LCAxNjA2LCAxNjA3LCAxNjA4LCAyMzEsIDIzMiwgMjMzLCAyMzQsIDIzNSwgMTYwOSwgMTYxMCwgMjM4LCAyMzksCisgICAgICAgICAgICAxNjExLCAxNjEyLCAxNjEzLCAxNjE0LCAyNDQsIDE2MTUsIDE2MTYsIDI0NywgMTYxNywgMjQ5LCAxNjE4LCAyNTEsIDI1MiwgODIwNiwgODIwNywgMTc0Nn0pOworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfd2luZG93c18xMjU3LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV93aW5kb3dzXzEyNTcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZjYwNTg3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfd2luZG93c18xMjU3LmphdmEKQEAgLTAsMCArMSw0MiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLm5pby5jaGFyc2V0OworCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9TaW5nbGVCeXRlX3dpbmRvd3NfMTI1NyBleHRlbmRzIE9sZENoYXJzZXRfU2luZ2xlQnl0ZUFic3RyYWN0VGVzdCB7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyc2V0TmFtZSA9ICJ3aW5kb3dzLTEyNTciOworICAgICAgICBhbGxDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworICAgICAgICAgICAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKyAgICAgICAgICAgIDE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorICAgICAgICAgICAgMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCisgICAgICAgICAgICA0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKyAgICAgICAgICAgIDY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorICAgICAgICAgICAgODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCisgICAgICAgICAgICA5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKyAgICAgICAgICAgIDExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKyAgICAgICAgICAgIDgzNjQsIDY1NTMzLCA4MjE4LCA2NTUzMywgODIyMiwgODIzMCwgODIyNCwgODIyNSwgNjU1MzMsIDgyNDAsIDY1NTMzLCA4MjQ5LCA2NTUzMywgMTY4LCA3MTEsIDE4NCwKKyAgICAgICAgICAgIDY1NTMzLCA4MjE2LCA4MjE3LCA4MjIwLCA4MjIxLCA4MjI2LCA4MjExLCA4MjEyLCA2NTUzMywgODQ4MiwgNjU1MzMsIDgyNTAsIDY1NTMzLCAxNzUsIDczMSwgNjU1MzMsCisgICAgICAgICAgICAxNjAsIDY1NTMzLCAxNjIsIDE2MywgMTY0LCA2NTUzMywgMTY2LCAxNjcsIDIxNiwgMTY5LCAzNDIsIDE3MSwgMTcyLCAxNzMsIDE3NCwgMTk4LAorICAgICAgICAgICAgMTc2LCAxNzcsIDE3OCwgMTc5LCAxODAsIDE4MSwgMTgyLCAxODMsIDI0OCwgMTg1LCAzNDMsIDE4NywgMTg4LCAxODksIDE5MCwgMjMwLAorICAgICAgICAgICAgMjYwLCAzMDIsIDI1NiwgMjYyLCAxOTYsIDE5NywgMjgwLCAyNzQsIDI2OCwgMjAxLCAzNzcsIDI3OCwgMjkwLCAzMTAsIDI5OCwgMzE1LAorICAgICAgICAgICAgMzUyLCAzMjMsIDMyNSwgMjExLCAzMzIsIDIxMywgMjE0LCAyMTUsIDM3MCwgMzIxLCAzNDYsIDM2MiwgMjIwLCAzNzksIDM4MSwgMjIzLAorICAgICAgICAgICAgMjYxLCAzMDMsIDI1NywgMjYzLCAyMjgsIDIyOSwgMjgxLCAyNzUsIDI2OSwgMjMzLCAzNzgsIDI3OSwgMjkxLCAzMTEsIDI5OSwgMzE2LAorICAgICAgICAgICAgMzUzLCAzMjQsIDMyNiwgMjQzLCAzMzMsIDI0NSwgMjQ2LCAyNDcsIDM3MSwgMzIyLCAzNDcsIDM2MywgMjUyLCAzODAsIDM4MiwgNzI5fSk7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV93aW5kb3dzXzEyNTguamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9TaW5nbGVCeXRlX3dpbmRvd3NfMTI1OC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY0MGU1ZmYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV93aW5kb3dzXzEyNTguamF2YQpAQCAtMCwwICsxLDQyIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKK3B1YmxpYyBjbGFzcyBPbGRDaGFyc2V0X1NpbmdsZUJ5dGVfd2luZG93c18xMjU4IGV4dGVuZHMgT2xkQ2hhcnNldF9TaW5nbGVCeXRlQWJzdHJhY3RUZXN0IHsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJzZXROYW1lID0gIndpbmRvd3MtMTI1OCI7CisgICAgICAgIGFsbENoYXJzID0gdGhlc2VDaGFycyhuZXcgaW50W117CisgICAgICAgICAgICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAorICAgICAgICAgICAgMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsCisgICAgICAgICAgICAzMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywKKyAgICAgICAgICAgIDQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzLAorICAgICAgICAgICAgNjQsIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksCisgICAgICAgICAgICA4MCwgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MiwgOTMsIDk0LCA5NSwKKyAgICAgICAgICAgIDk2LCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLAorICAgICAgICAgICAgMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjIsIDEyMywgMTI0LCAxMjUsIDEyNiwgMTI3LAorICAgICAgICAgICAgODM2NCwgNjU1MzMsIDgyMTgsIDQwMiwgODIyMiwgODIzMCwgODIyNCwgODIyNSwgNzEwLCA4MjQwLCA2NTUzMywgODI0OSwgMzM4LCA2NTUzMywgNjU1MzMsIDY1NTMzLAorICAgICAgICAgICAgNjU1MzMsIDgyMTYsIDgyMTcsIDgyMjAsIDgyMjEsIDgyMjYsIDgyMTEsIDgyMTIsIDczMiwgODQ4MiwgNjU1MzMsIDgyNTAsIDMzOSwgNjU1MzMsIDY1NTMzLCAzNzYsCisgICAgICAgICAgICAxNjAsIDE2MSwgMTYyLCAxNjMsIDE2NCwgMTY1LCAxNjYsIDE2NywgMTY4LCAxNjksIDE3MCwgMTcxLCAxNzIsIDE3MywgMTc0LCAxNzUsCisgICAgICAgICAgICAxNzYsIDE3NywgMTc4LCAxNzksIDE4MCwgMTgxLCAxODIsIDE4MywgMTg0LCAxODUsIDE4NiwgMTg3LCAxODgsIDE4OSwgMTkwLCAxOTEsCisgICAgICAgICAgICAxOTIsIDE5MywgMTk0LCAyNTgsIDE5NiwgMTk3LCAxOTgsIDE5OSwgMjAwLCAyMDEsIDIwMiwgMjAzLCA3NjgsIDIwNSwgMjA2LCAyMDcsCisgICAgICAgICAgICAyNzIsIDIwOSwgNzc3LCAyMTEsIDIxMiwgNDE2LCAyMTQsIDIxNSwgMjE2LCAyMTcsIDIxOCwgMjE5LCAyMjAsIDQzMSwgNzcxLCAyMjMsCisgICAgICAgICAgICAyMjQsIDIyNSwgMjI2LCAyNTksIDIyOCwgMjI5LCAyMzAsIDIzMSwgMjMyLCAyMzMsIDIzNCwgMjM1LCA3NjksIDIzNywgMjM4LCAyMzksCisgICAgICAgICAgICAyNzMsIDI0MSwgODAzLCAyNDMsIDI0NCwgNDE3LCAyNDYsIDI0NywgMjQ4LCAyNDksIDI1MCwgMjUxLCAyNTIsIDQzMiwgODM2MywgMjU1fSk7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL25pby9jaGFyc2V0L09sZENoYXJzZXRfU2luZ2xlQnl0ZV94X0lCTTg3NC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfeF9JQk04NzQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNmZkODY5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X1NpbmdsZUJ5dGVfeF9JQk04NzQuamF2YQpAQCAtMCwwICsxLDQ2IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEubmlvLmNoYXJzZXQ7CisKKy8qKiBOb3RlOiBJQ1UgYmVoYXZlcyBkaWZmZXJlbnRseSBmcm9tIHRoZSBSSSAqLworCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9TaW5nbGVCeXRlX3hfSUJNODc0IGV4dGVuZHMgT2xkQ2hhcnNldF9TaW5nbGVCeXRlQWJzdHJhY3RUZXN0IHsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisvLyAgICAgICAgY2hhcnNldE5hbWUgPSAieC1JQk04NzQiOyAvLyBJQ1UgbmFtZSAiVElTLTYyMCIsIHdhbnRlZCBBbmRyb2lkIG5hbWUgIkNQODc0IgorICAgICAgICBjaGFyc2V0TmFtZSA9ICJUSVMtNjIwIjsgLy8gSUNVIG5hbWUgIlRJUy02MjAiLCB3YW50ZWQgQW5kcm9pZCBuYW1lICJDUDg3NCIKKworICAgICAgICBhbGxDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworICAgICAgICAgICAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKyAgICAgICAgICAgIDE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorICAgICAgICAgICAgMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCisgICAgICAgICAgICA0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKyAgICAgICAgICAgIDY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorICAgICAgICAgICAgODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCisgICAgICAgICAgICA5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKyAgICAgICAgICAgIDExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKyAgICAgICAgICAgIDgzNjQsIDEyOSwgMTMwLCAxMzEsIDEzMiwgODIzMCwgMTM0LCAxMzUsIDEzNiwgMTM3LCAxMzgsIDEzOSwgMTQwLCAxNDEsIDE0MiwgMTQzLAorICAgICAgICAgICAgMTQ0LCA4MjE2LCA4MjE3LCA4MjIwLCA4MjIxLCA4MjI2LCA4MjExLCA4MjEyLCAxNTIsIDE1MywgMTU0LCAxNTUsIDE1NiwgMTU3LCAxNTgsIDE1OSwKKyAgICAgICAgICAgIDE2MCwgMzU4NSwgMzU4NiwgMzU4NywgMzU4OCwgMzU4OSwgMzU5MCwgMzU5MSwgMzU5MiwgMzU5MywgMzU5NCwgMzU5NSwgMzU5NiwgMzU5NywgMzU5OCwgMzU5OSwKKyAgICAgICAgICAgIDM2MDAsIDM2MDEsIDM2MDIsIDM2MDMsIDM2MDQsIDM2MDUsIDM2MDYsIDM2MDcsIDM2MDgsIDM2MDksIDM2MTAsIDM2MTEsIDM2MTIsIDM2MTMsIDM2MTQsIDM2MTUsCisgICAgICAgICAgICAzNjE2LCAzNjE3LCAzNjE4LCAzNjE5LCAzNjIwLCAzNjIxLCAzNjIyLCAzNjIzLCAzNjI0LCAzNjI1LCAzNjI2LCAzNjI3LCAzNjI4LCAzNjI5LCAzNjMwLCAzNjMxLAorICAgICAgICAgICAgMzYzMiwgMzYzMywgMzYzNCwgMzYzNSwgMzYzNiwgMzYzNywgMzYzOCwgMzYzOSwgMzY0MCwgMzY0MSwgMzY0MiwgNjM2ODEsIDYzNjgyLCA2MzY4MywgNjM2ODQsIDM2NDcsCisgICAgICAgICAgICAzNjQ4LCAzNjQ5LCAzNjUwLCAzNjUxLCAzNjUyLCAzNjUzLCAzNjU0LCAzNjU1LCAzNjU2LCAzNjU3LCAzNjU4LCAzNjU5LCAzNjYwLCAzNjYxLCAzNjYyLCAzNjYzLAorICAgICAgICAgICAgMzY2NCwgMzY2NSwgMzY2NiwgMzY2NywgMzY2OCwgMzY2OSwgMzY3MCwgMzY3MSwgMzY3MiwgMzY3MywgMzY3NCwgMzY3NSwgNjM2ODUsIDYzNjg2LCA2MzY4NywgNjM2ODh9KTsKKworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9tYWNpbnRvc2guamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvbmlvL2NoYXJzZXQvT2xkQ2hhcnNldF9tYWNpbnRvc2guamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45M2YwZDFmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9uaW8vY2hhcnNldC9PbGRDaGFyc2V0X21hY2ludG9zaC5qYXZhCkBAIC0wLDAgKzEsNjIgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5uaW8uY2hhcnNldDsKKworLyoqIE5vdGU6IElDVSBvbmx5ICovCitwdWJsaWMgY2xhc3MgT2xkQ2hhcnNldF9tYWNpbnRvc2ggZXh0ZW5kcyBPbGRDaGFyc2V0X0Fic3RyYWN0VGVzdCB7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyc2V0TmFtZSA9ICJtYWNpbnRvc2giOworCisgICAgICAgIHRlc3RDaGFycyA9IHRoZXNlQ2hhcnMobmV3IGludFtdeworMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKzE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCis0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKzY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCis5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKzExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKzE2MCwgMTYxLCAxNjIsIDE2MywgMTY1LCAxNjcsIDE2OCwgMTY5LCAxNzAsIDE3MSwgMTcyLCAxNzQsIDE3NSwgMTc2LCAxNzcsIDE4MCwKKzE4MSwgMTgyLCAxODMsIDE4NCwgMTg2LCAxODcsIDE5MSwgMTkyLCAxOTMsIDE5NCwgMTk1LCAxOTYsIDE5NywgMTk4LCAxOTksIDIwMCwKKzIwMSwgMjAyLCAyMDMsIDIwNCwgMjA1LCAyMDYsIDIwNywgMjA5LCAyMTAsIDIxMSwgMjEyLCAyMTMsIDIxNCwgMjE2LCAyMTcsIDIxOCwKKzIxOSwgMjIwLCAyMjMsIDIyNCwgMjI1LCAyMjYsIDIyNywgMjI4LCAyMjksIDIzMCwgMjMxLCAyMzIsIDIzMywgMjM0LCAyMzUsIDIzNiwKKzIzNywgMjM4LCAyMzksIDI0MSwgMjQyLCAyNDMsIDI0NCwgMjQ1LCAyNDYsIDI0NywgMjQ4LCAyNDksIDI1MCwgMjUxLCAyNTIsIDI1NSwKKzMwNSwgMzM4LCAzNzYsIDcxMCwgOTM3LCA4MjExLCA4MjQ5LCA4MzY0LCA4NDgyLCA4NzA2LCA4NzQ3LCA4ODAwLCA5Njc0LCA2Mzc0MywgNjQyNTcKKyAgICAgICAgICAgIH0pOworCisgICAgICAgIHRlc3RCeXRlcyA9IHRoZXNlQnl0ZXMobmV3IGludFtdeworMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwKKzE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLAorMzIsIDMzLCAzNCwgMzUsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsCis0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywKKzY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LAorODAsIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDkzLCA5NCwgOTUsCis5NiwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMiwgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwKKzExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCAxMjMsIDEyNCwgMTI1LCAxMjYsIDEyNywKKzIwMiwgMTkzLCAxNjIsIDE2MywgMTgwLCAxNjQsIDE3MiwgMTY5LCAxODcsIDE5OSwgMTk0LCAxNjgsIDI0OCwgMTYxLCAxNzcsIDE3MSwKKzE4MSwgMTY2LCAyMjUsIDI1MiwgMTg4LCAyMDAsIDE5MiwgMjAzLCAyMzEsIDIyOSwgMjA0LCAxMjgsIDEyOSwgMTc0LCAxMzAsIDIzMywKKzEzMSwgMjMwLCAyMzIsIDIzNywgMjM0LCAyMzUsIDIzNiwgMTMyLCAyNDEsIDIzOCwgMjM5LCAyMDUsIDEzMywgMTc1LCAyNDQsIDI0MiwKKzI0MywgMTM0LCAxNjcsIDEzNiwgMTM1LCAxMzcsIDEzOSwgMTM4LCAxNDAsIDE5MCwgMTQxLCAxNDMsIDE0MiwgMTQ0LCAxNDUsIDE0NywKKzE0NiwgMTQ4LCAxNDksIDE1MCwgMTUyLCAxNTEsIDE1MywgMTU1LCAxNTQsIDIxNCwgMTkxLCAxNTcsIDE1NiwgMTU4LCAxNTksIDIxNiwKKzI0NSwgMjA2LCAyMTcsIDI0NiwgMTg5LCAyMDgsIDIyMCwgMjE5LCAxNzAsIDE4MiwgMTg2LCAxNzMsIDIxNSwgMjQwLCAyMjIKKyAgICAgICAgICAgIH0pOworCisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L0FjY2Vzc0NvbnRyb2xsZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L0FjY2Vzc0NvbnRyb2xsZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWY3ZGE5MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvQWNjZXNzQ29udHJvbGxlclRlc3QuamF2YQpAQCAtMCwwICsxLDcxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xDb250ZXh0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkRvbWFpbkNvbWJpbmVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb25zOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3RlY3Rpb25Eb21haW47CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0ludGVnZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydGlvbkZhaWxlZEVycm9yOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBBbmRyb2lkIGRvZXNuJ3QgZnVsbHkgc3VwcG9ydCBhY2Nlc3MgY29udHJvbGxlci4gVGhpcyB0ZXN0cyB0aGF0IGFjdGlvbnMgYXJlCisgKiBwYXNzZWQgdGhyb3VnaCB3aXRob3V0IHBlcm1pc3Npb24gZW5mb3JjZW1lbnQuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBBY2Nlc3NDb250cm9sbGVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3REb1ByaXZpbGVnZWRXaXRoQ29tYmluZXIoKSB7CisgICAgICAgIGZpbmFsIFBlcm1pc3Npb24gcGVybWlzc2lvbiA9IG5ldyBSdW50aW1lUGVybWlzc2lvbigiZG8gc3R1ZmYiKTsKKyAgICAgICAgZmluYWwgRG9tYWluQ29tYmluZXIgdW5pb24gPSBuZXcgRG9tYWluQ29tYmluZXIoKSB7CisgICAgICAgICAgICBwdWJsaWMgUHJvdGVjdGlvbkRvbWFpbltdIGNvbWJpbmUoUHJvdGVjdGlvbkRvbWFpbltdIGEsIFByb3RlY3Rpb25Eb21haW5bXSBiKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkZhaWxlZEVycm9yKCJFeHBlY3RlZCBjb21iaW5lciB0byBiZSB1bnVzZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBQcm90ZWN0aW9uRG9tYWluIHByb3RlY3Rpb25Eb21haW4gPSBuZXcgUHJvdGVjdGlvbkRvbWFpbihudWxsLCBuZXcgUGVybWlzc2lvbnMoKSk7CisgICAgICAgIEFjY2Vzc0NvbnRyb2xDb250ZXh0IGFjY2Vzc0NvbnRyb2xDb250ZXh0ID0gbmV3IEFjY2Vzc0NvbnRyb2xDb250ZXh0KAorICAgICAgICAgICAgICAgIG5ldyBBY2Nlc3NDb250cm9sQ29udGV4dChuZXcgUHJvdGVjdGlvbkRvbWFpbltdIHsgcHJvdGVjdGlvbkRvbWFpbiB9KSwgdW5pb24pOworCisgICAgICAgIGZpbmFsIEF0b21pY0ludGVnZXIgYWN0aW9uQ291bnQgPSBuZXcgQXRvbWljSW50ZWdlcigpOworCisgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uPFZvaWQ+KCkgeworICAgICAgICAgICAgcHVibGljIFZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBBY2Nlc3NDb250cm9sbGVyLmdldENvbnRleHQoKS5nZXREb21haW5Db21iaW5lcigpKTsKKyAgICAgICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmdldENvbnRleHQoKS5jaGVja1Blcm1pc3Npb24ocGVybWlzc2lvbik7CisKKyAgICAgICAgICAgICAgICAvLyBDYWxsaW5nIGRvUHJpdmlsZWdlZCBhZ2FpbiB3b3VsZCBoYXZlIGV4ZXJjaXNlZCB0aGUgY29tYmluZXIKKyAgICAgICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbjxWb2lkPigpIHsKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIFZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uQ291bnQuaW5jcmVtZW50QW5kR2V0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgQWNjZXNzQ29udHJvbGxlci5nZXRDb250ZXh0KCkuZ2V0RG9tYWluQ29tYmluZXIoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmdldENvbnRleHQoKS5jaGVja1Blcm1pc3Npb24ocGVybWlzc2lvbik7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0pOworCisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0sIGFjY2Vzc0NvbnRyb2xDb250ZXh0KTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgYWN0aW9uQ291bnQuZ2V0KCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvS2V5UGFpckdlbmVyYXRvclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvS2V5UGFpckdlbmVyYXRvclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZTM1M2NjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zZWN1cml0eS9LZXlQYWlyR2VuZXJhdG9yVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTM5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBLZXlQYWlyR2VuZXJhdG9yVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvdmlkZXJbXSBwcm92aWRlcnMgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoKTsKKyAgICAgICAgZm9yIChQcm92aWRlciBwcm92aWRlciA6IHByb3ZpZGVycykgeworICAgICAgICAgICAgU2V0PFByb3ZpZGVyLlNlcnZpY2U+IHNlcnZpY2VzID0gcHJvdmlkZXIuZ2V0U2VydmljZXMoKTsKKyAgICAgICAgICAgIGZvciAoUHJvdmlkZXIuU2VydmljZSBzZXJ2aWNlIDogc2VydmljZXMpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgdHlwZSA9IHNlcnZpY2UuZ2V0VHlwZSgpOworICAgICAgICAgICAgICAgIGlmICghdHlwZS5lcXVhbHMoIktleVBhaXJHZW5lcmF0b3IiKSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgU3RyaW5nIGFsZ29yaXRobSA9IHNlcnZpY2UuZ2V0QWxnb3JpdGhtKCk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgLy8gS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZShTdHJpbmcpCisgICAgICAgICAgICAgICAgICAgIEtleVBhaXJHZW5lcmF0b3Iga3BnMSA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFsZ29yaXRobSwga3BnMS5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgICAgICAgICAgICAgIHRlc3RfS2V5UGFpckdlbmVyYXRvcihrcGcxKTsKKworICAgICAgICAgICAgICAgICAgICAvLyBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKFN0cmluZywgUHJvdmlkZXIpCisgICAgICAgICAgICAgICAgICAgIEtleVBhaXJHZW5lcmF0b3Iga3BnMiA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBwcm92aWRlcik7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhhbGdvcml0aG0sIGtwZzIuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMocHJvdmlkZXIsIGtwZzIuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgICAgICAgICAgICAgIHRlc3RfS2V5UGFpckdlbmVyYXRvcihrcGcyKTsKKworICAgICAgICAgICAgICAgICAgICAvLyBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKFN0cmluZywgU3RyaW5nKQorICAgICAgICAgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGtwZzMgPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKGFsZ29yaXRobSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhhbGdvcml0aG0sIGtwZzMuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMocHJvdmlkZXIsIGtwZzMuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgICAgICAgICAgICAgIHRlc3RfS2V5UGFpckdlbmVyYXRvcihrcGczKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJQcm9ibGVtIHRlc3RpbmcgS2V5UGFpckdlbmVyYXRvci4iICsgYWxnb3JpdGhtLCBlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8U3RyaW5nLCBMaXN0PEludGVnZXI+PiBLRVlfU0laRVMKKyAgICAgICAgICAgID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBMaXN0PEludGVnZXI+PigpOworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcHV0S2V5U2l6ZShTdHJpbmcgYWxnb3JpdGhtLCBpbnQga2V5U2l6ZSkgeworICAgICAgICBhbGdvcml0aG0gPSBhbGdvcml0aG0udG9VcHBlckNhc2UoKTsKKyAgICAgICAgTGlzdDxJbnRlZ2VyPiBrZXlTaXplcyA9IEtFWV9TSVpFUy5nZXQoYWxnb3JpdGhtKTsKKyAgICAgICAgaWYgKGtleVNpemVzID09IG51bGwpIHsKKyAgICAgICAgICAgIGtleVNpemVzID0gbmV3IEFycmF5TGlzdDxJbnRlZ2VyPigpOworICAgICAgICAgICAgS0VZX1NJWkVTLnB1dChhbGdvcml0aG0sIGtleVNpemVzKTsKKyAgICAgICAgfQorICAgICAgICBrZXlTaXplcy5hZGQoa2V5U2l6ZSk7CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIExpc3Q8SW50ZWdlcj4gZ2V0S2V5U2l6ZXMoU3RyaW5nIGFsZ29yaXRobSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFsZ29yaXRobSA9IGFsZ29yaXRobS50b1VwcGVyQ2FzZSgpOworICAgICAgICBMaXN0PEludGVnZXI+IGtleVNpemVzID0gS0VZX1NJWkVTLmdldChhbGdvcml0aG0pOworICAgICAgICBpZiAoa2V5U2l6ZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVW5rbm93biBrZXkgc2l6ZXMgZm9yIEtleVBhaXJHZW5lcmF0b3IuIiArIGFsZ29yaXRobSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGtleVNpemVzOworICAgIH0KKyAgICBzdGF0aWMgeworICAgICAgICBwdXRLZXlTaXplKCJEU0EiLCA1MTIpOworICAgICAgICBwdXRLZXlTaXplKCJEU0EiLCA1MTIrNjQpOworICAgICAgICBwdXRLZXlTaXplKCJEU0EiLCAxMDI0KTsKKyAgICAgICAgcHV0S2V5U2l6ZSgiUlNBIiwgNTEyKTsKKyAgICAgICAgcHV0S2V5U2l6ZSgiREgiLCA1MTIpOworICAgICAgICBwdXRLZXlTaXplKCJESCIsIDUxMis2NCk7CisgICAgICAgIHB1dEtleVNpemUoIkRIIiwgMTAyNCk7CisgICAgICAgIHB1dEtleVNpemUoIkRpZmZpZUhlbGxtYW4iLCA1MTIpOworICAgICAgICBwdXRLZXlTaXplKCJEaWZmaWVIZWxsbWFuIiwgNTEyKzY0KTsKKyAgICAgICAgcHV0S2V5U2l6ZSgiRGlmZmllSGVsbG1hbiIsIDEwMjQpOworICAgICAgICBwdXRLZXlTaXplKCJFQyIsIDI1Nik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RfS2V5UGFpckdlbmVyYXRvcihLZXlQYWlyR2VuZXJhdG9yIGtwZykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIHdpdGhvdXQgYSBjYWxsIHRvIGluaXRpYWxpemUKKyAgICAgICAgdGVzdF9LZXlQYWlyKGtwZywga3BnLmdlbktleVBhaXIoKSk7CisgICAgICAgIHRlc3RfS2V5UGFpcihrcGcsIGtwZy5nZW5lcmF0ZUtleVBhaXIoKSk7CisKKyAgICAgICAgU3RyaW5nIGFsZ29yaXRobSA9IGtwZy5nZXRBbGdvcml0aG0oKTsKKyAgICAgICAgTGlzdDxJbnRlZ2VyPiBrZXlTaXplcyA9IGdldEtleVNpemVzKGFsZ29yaXRobSk7CisgICAgICAgIGZvciAoaW50IGtleVNpemUgOiBrZXlTaXplcykgeworICAgICAgICAgICAga3BnLmluaXRpYWxpemUoa2V5U2l6ZSk7CisgICAgICAgICAgICB0ZXN0X0tleVBhaXIoa3BnLCBrcGcuZ2VuS2V5UGFpcigpKTsKKyAgICAgICAgICAgIHRlc3RfS2V5UGFpcihrcGcsIGtwZy5nZW5lcmF0ZUtleVBhaXIoKSk7CisKKyAgICAgICAgICAgIGtwZy5pbml0aWFsaXplKGtleVNpemUsIChTZWN1cmVSYW5kb20pIG51bGwpOworICAgICAgICAgICAgdGVzdF9LZXlQYWlyKGtwZywga3BnLmdlbktleVBhaXIoKSk7CisgICAgICAgICAgICB0ZXN0X0tleVBhaXIoa3BnLCBrcGcuZ2VuZXJhdGVLZXlQYWlyKCkpOworCisgICAgICAgICAgICBrcGcuaW5pdGlhbGl6ZShrZXlTaXplLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAgdGVzdF9LZXlQYWlyKGtwZywga3BnLmdlbktleVBhaXIoKSk7CisgICAgICAgICAgICB0ZXN0X0tleVBhaXIoa3BnLCBrcGcuZ2VuZXJhdGVLZXlQYWlyKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RfS2V5UGFpcihLZXlQYWlyR2VuZXJhdG9yIGtwZywgS2V5UGFpciBrcCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydE5vdE51bGwoa3ApOworICAgICAgICB0ZXN0X0tleShrcGcsIGtwLmdldFByaXZhdGUoKSk7CisgICAgICAgIHRlc3RfS2V5KGtwZywga3AuZ2V0UHVibGljKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0X0tleShLZXlQYWlyR2VuZXJhdG9yIGtwZywgS2V5IGspIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgZXhwZWN0ZWRBbGdvcml0aG0gPSBrcGcuZ2V0QWxnb3JpdGhtKCkudG9VcHBlckNhc2UoKTsKKyAgICAgICAgaWYgKFN0YW5kYXJkTmFtZXMuSVNfUkkgJiYgZXhwZWN0ZWRBbGdvcml0aG0uZXF1YWxzKCJESUZGSUVIRUxMTUFOIikpIHsKKyAgICAgICAgICAgIGV4cGVjdGVkQWxnb3JpdGhtID0gIkRIIjsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRBbGdvcml0aG0sIGsuZ2V0QWxnb3JpdGhtKCkudG9VcHBlckNhc2UoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoay5nZXRFbmNvZGVkKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKGsuZ2V0Rm9ybWF0KCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvS2V5U3RvcmVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L0tleVN0b3JlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBhNGQ5NjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L0tleVN0b3JlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjE4NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlLkJ1aWxkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZS5FbnRyeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlLkxvYWRTdG9yZVBhcmFtZXRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlLlBhc3N3b3JkUHJvdGVjdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlLlByaXZhdGVLZXlFbnRyeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlLlByb3RlY3Rpb25QYXJhbWV0ZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZS5TZWNyZXRLZXlFbnRyeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlLlRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YXguY3J5cHRvLktleUdlbmVyYXRvcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2VjcmV0S2V5OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBsaWJjb3JlLmlvLklvVXRpbHM7CisKK3B1YmxpYyBjbGFzcyBLZXlTdG9yZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBQcml2YXRlS2V5RW50cnkgUFJJVkFURV9LRVk7CisgICAgcHJpdmF0ZSBzdGF0aWMgUHJpdmF0ZUtleUVudHJ5IFBSSVZBVEVfS0VZXzI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTZWNyZXRLZXkgU0VDUkVUX0tFWTsKKyAgICBwcml2YXRlIHN0YXRpYyBTZWNyZXRLZXkgU0VDUkVUX0tFWV8yOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFMSUFTX1BSSVZBVEUgPSAicHJpdmF0ZSI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFMSUFTX0NFUlRJRklDQVRFID0gImNlcnRpZmljYXRlIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUxJQVNfU0VDUkVUID0gInNlY3JldCI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUxJQVNfQUxUX0NBU0VfUFJJVkFURSA9ICJwUmlWYVRlIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUxJQVNfQUxUX0NBU0VfQ0VSVElGSUNBVEUgPSAiY0VyVGlGaUNhVGUiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBTElBU19BTFRfQ0FTRV9TRUNSRVQgPSAic0VjUmV0IjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBTElBU19OT19QQVNTV09SRF9QUklWQVRFID0gInByaXZhdGUtbm8tcGFzc3dvcmQiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBTElBU19OT19QQVNTV09SRF9TRUNSRVQgPSAic2VjcmV0LW5vLXBhc3N3b3JkIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBQQVNTV09SRF9TVE9SRSA9ICJzdG9yZSBwYXNzd29yZCIudG9DaGFyQXJyYXkoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gUEFTU1dPUkRfS0VZID0gImtleSBwYXNzd29yZCIudG9DaGFyQXJyYXkoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gUEFTU1dPUkRfQkFEID0gImR1bW15Ii50b0NoYXJBcnJheSgpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUHJvdGVjdGlvblBhcmFtZXRlciBQQVJBTV9TVE9SRSA9IG5ldyBQYXNzd29yZFByb3RlY3Rpb24oUEFTU1dPUkRfU1RPUkUpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFByb3RlY3Rpb25QYXJhbWV0ZXIgUEFSQU1fS0VZID0gbmV3IFBhc3N3b3JkUHJvdGVjdGlvbihQQVNTV09SRF9LRVkpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFByb3RlY3Rpb25QYXJhbWV0ZXIgUEFSQU1fQkFEID0gbmV3IFBhc3N3b3JkUHJvdGVjdGlvbihQQVNTV09SRF9CQUQpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgUHJpdmF0ZUtleUVudHJ5IGdldFByaXZhdGVLZXkoKSB7CisgICAgICAgIGlmIChQUklWQVRFX0tFWSA9PSBudWxsKSB7CisgICAgICAgICAgICBQUklWQVRFX0tFWSA9IFRlc3RLZXlTdG9yZS5nZXRTZXJ2ZXIoKS5nZXRQcml2YXRlS2V5KCJSU0EiLCAiUlNBIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIFBSSVZBVEVfS0VZOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFByaXZhdGVLZXlFbnRyeSBnZXRQcml2YXRlS2V5MigpIHsKKyAgICAgICAgaWYgKFBSSVZBVEVfS0VZXzIgPT0gbnVsbCkgeworICAgICAgICAgICAgUFJJVkFURV9LRVlfMiA9IFRlc3RLZXlTdG9yZS5nZXRDbGllbnRDZXJ0aWZpY2F0ZSgpLmdldFByaXZhdGVLZXkoIlJTQSIsICJSU0EiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gUFJJVkFURV9LRVlfMjsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTZWNyZXRLZXkgZ2V0U2VjcmV0S2V5KCkgeworICAgICAgICBpZiAoU0VDUkVUX0tFWSA9PSBudWxsKSB7CisgICAgICAgICAgICBTRUNSRVRfS0VZID0gZ2VuZXJhdGVTZWNyZXRLZXkoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gU0VDUkVUX0tFWTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTZWNyZXRLZXkgZ2V0U2VjcmV0S2V5MigpIHsKKyAgICAgICAgaWYgKFNFQ1JFVF9LRVlfMiA9PSBudWxsKSB7CisgICAgICAgICAgICBTRUNSRVRfS0VZXzIgPSBnZW5lcmF0ZVNlY3JldEtleSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBTRUNSRVRfS0VZXzI7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU2VjcmV0S2V5IGdlbmVyYXRlU2VjcmV0S2V5KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5R2VuZXJhdG9yIGtnID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKCJERVMiKTsKKyAgICAgICAgICAgIHJldHVybiBrZy5nZW5lcmF0ZUtleSgpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIExpc3Q8S2V5U3RvcmU+IGtleVN0b3JlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBMaXN0PEtleVN0b3JlPiBrZXlTdG9yZXMgPSBuZXcgQXJyYXlMaXN0PEtleVN0b3JlPigpOworICAgICAgICBQcm92aWRlcltdIHByb3ZpZGVycyA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygpOworICAgICAgICBmb3IgKFByb3ZpZGVyIHByb3ZpZGVyIDogcHJvdmlkZXJzKSB7CisgICAgICAgICAgICBTZXQ8UHJvdmlkZXIuU2VydmljZT4gc2VydmljZXMgPSBwcm92aWRlci5nZXRTZXJ2aWNlcygpOworICAgICAgICAgICAgZm9yIChQcm92aWRlci5TZXJ2aWNlIHNlcnZpY2UgOiBzZXJ2aWNlcykgeworICAgICAgICAgICAgICAgIFN0cmluZyB0eXBlID0gc2VydmljZS5nZXRUeXBlKCk7CisgICAgICAgICAgICAgICAgaWYgKCF0eXBlLmVxdWFscygiS2V5U3RvcmUiKSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgU3RyaW5nIGFsZ29yaXRobSA9IHNlcnZpY2UuZ2V0QWxnb3JpdGhtKCk7CisgICAgICAgICAgICAgICAgS2V5U3RvcmUga3MgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShhbGdvcml0aG0sIHByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMocHJvdmlkZXIsIGtzLmdldFByb3ZpZGVyKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhhbGdvcml0aG0sIGtzLmdldFR5cGUoKSk7CisgICAgICAgICAgICAgICAgaWYgKCFpc1Vuc3VwcG9ydGVkKGtzKSkgeworICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZXMuYWRkKGtzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGtleVN0b3JlczsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzU2VjcmV0S2V5RW5hYmxlZChLZXlTdG9yZSBrcykgeworICAgICAgICAvLyBKS1Mga2V5IHN0b3JlcyBjYW5ub3Qgc3RvcmUgc2VjcmV0IGtleXMsIG5laXRoZXIgY2FuIHRoZSBSSSdzIFBLQ1MxMgorICAgICAgICByZXR1cm4gKCEoa3MuZ2V0VHlwZSgpLmVxdWFscygiSktTIikKKyAgICAgICAgICAgICAgICAgIHx8IGtzLmdldFR5cGUoKS5lcXVhbHMoIkNhc2VFeGFjdEpLUyIpCisgICAgICAgICAgICAgICAgICB8fCAoa3MuZ2V0VHlwZSgpLmVxdWFscygiUEtDUzEyIikpKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0NlcnRpZmljYXRlRW5hYmxlZChLZXlTdG9yZSBrcykgeworICAgICAgICAvLyBSSSBjYW4ndCBoYW5kbGUgY2VydGlmaWNhdGUgaW4gUEtDUzEyLCBidXQgQkMgY2FuCisgICAgICAgIHJldHVybiAoIShrcy5nZXRUeXBlKCkuZXF1YWxzKCJQS0NTMTIiKSAmJiBrcy5nZXRQcm92aWRlcigpLmdldE5hbWUoKS5lcXVhbHMoIlN1bkpTU0UiKSkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNDYXNlU2Vuc2l0aXZlKEtleVN0b3JlIGtzKSB7CisgICAgICAgIHJldHVybiAoa3MuZ2V0VHlwZSgpLmVxdWFscygiQ2FzZUV4YWN0SktTIikKKyAgICAgICAgICAgICAgICB8fCBrcy5nZXRUeXBlKCkuZXF1YWxzKCJCS1MiKQorICAgICAgICAgICAgICAgIHx8IGtzLmdldFR5cGUoKS5lcXVhbHMoIkJvdW5jeUNhc3RsZSIpKTsKKworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNVbnN1cHBvcnRlZChLZXlTdG9yZSBrcykgeworICAgICAgICAvLyBEb24ndCBib3RoZXIgdGVzdGluZyBCQyBvbiBSSQorICAgICAgICByZXR1cm4gKFN0YW5kYXJkTmFtZXMuSVNfUkkgJiYga3MuZ2V0UHJvdmlkZXIoKS5nZXROYW1lKCkuZXF1YWxzKCJCQyIpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzTnVsbFBhc3N3b3JkQWxsb3dlZChLZXlTdG9yZSBrcykgeworICAgICAgICByZXR1cm4gKCEoa3MuZ2V0VHlwZSgpLmVxdWFscygiSktTIikKKyAgICAgICAgICAgICAgICAgIHx8IGtzLmdldFR5cGUoKS5lcXVhbHMoIkNhc2VFeGFjdEpLUyIpCisgICAgICAgICAgICAgICAgICB8fCBrcy5nZXRUeXBlKCkuZXF1YWxzKCJKQ0VLUyIpCisgICAgICAgICAgICAgICAgICB8fCBrcy5nZXRUeXBlKCkuZXF1YWxzKCJQS0NTMTIiKSkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNLZXlQYXNzd29yZElnbm9yZWQoS2V5U3RvcmUga3MpIHsKKyAgICAgICAgLy8gQm91bmN5Q2FzdGxlJ3MgUEtDUzEyIGlnbm9yZXMgdGhlIGtleSBwYXNzd29yZCB1bmxpa2UgdGhlIFJJIHdoaWNoIHJlcXVpcmVzIGl0CisgICAgICAgIHJldHVybiAoa3MuZ2V0VHlwZSgpLmVxdWFscygiUEtDUzEyIikgJiYga3MuZ2V0UHJvdmlkZXIoKS5nZXROYW1lKCkuZXF1YWxzKCJCQyIpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzTG9hZFN0b3JlUGFyYW1ldGVyU3VwcG9ydGVkKEtleVN0b3JlIGtzKSB7CisgICAgICAgIC8vIEJvdW5jeUNhc3RsZSdzIFBLQ1MxMiBhbGxvd3MgYSBKREtQS0NTMTJTdG9yZVBhcmFtZXRlcgorICAgICAgICByZXR1cm4gKGtzLmdldFR5cGUoKS5lcXVhbHMoIlBLQ1MxMiIpICYmIGtzLmdldFByb3ZpZGVyKCkuZ2V0TmFtZSgpLmVxdWFscygiQkMiKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1NldEtleUJ5dGVBcnJheVVuaW1wbGVtZW50ZWQoS2V5U3RvcmUga3MpIHsKKyAgICAgICAgLy8gQWxsIG9mIEJvdW5jeUNhc3RsZSdzCisgICAgICAgIC8vIEtleVN0b3JlLnNldEtleUVudHJ5KFN0cmluZyxieXRlW10sY2hhcltdKSBpbXBsZW1lbnRhdGlvbnMKKyAgICAgICAgLy8gdGhyb3cgUnVudGltZUV4Y2VwdGlvbgorICAgICAgICByZXR1cm4gKGtzLmdldFByb3ZpZGVyKCkuZ2V0TmFtZSgpLmVxdWFscygiQkMiKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBoYXNEZWZhdWx0Q29udGVudHMoS2V5U3RvcmUga3MpIHsKKyAgICAgICAgLy8gQW5kcm9pZENBU3RvcmUgZXhwb3NlcyBDQSBjZXJ0IGZpbGVzIHZpYSB0aGUgS2V5U3RvcmUKKyAgICAgICAgLy8gaW50ZXJmYWNlLCBzbyBpdCBkb2VzIHN0YXJ0IG91dCBlbXB0eSBsaWtlIG90aGVyIEtleVN0b3JlcworICAgICAgICByZXR1cm4gKGtzLmdldFR5cGUoKS5lcXVhbHMoIkFuZHJvaWRDQVN0b3JlIikpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNSZWFkT25seShLZXlTdG9yZSBrcykgeworICAgICAgICAvLyBBbmRyb2lkQ0FTdG9yZSBpcyByZWFkIG9ubHksIHRocm93aW5nCisgICAgICAgIC8vIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIG9uIHdyaXRlIG9wZXJhdGlvbnMKKyAgICAgICAgcmV0dXJuIChrcy5nZXRUeXBlKCkuZXF1YWxzKCJBbmRyb2lkQ0FTdG9yZSIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcG9wdWxhdGUoS2V5U3RvcmUga3MpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBrcy5sb2FkKG51bGwsIG51bGwpOworICAgICAgICBpZiAoaXNSZWFkT25seShrcykpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2V0UHJpdmF0ZUtleShrcyk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHNldFByaXZhdGVLZXkoa3MpOworICAgICAgICBpZiAoaXNOdWxsUGFzc3dvcmRBbGxvd2VkKGtzKSkgeworICAgICAgICAgICAga3Muc2V0S2V5RW50cnkoQUxJQVNfTk9fUEFTU1dPUkRfUFJJVkFURSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFByaXZhdGVLZXkoKS5nZXRQcml2YXRlS2V5KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0UHJpdmF0ZUtleSgpLmdldENlcnRpZmljYXRlQ2hhaW4oKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlzQ2VydGlmaWNhdGVFbmFibGVkKGtzKSkgeworICAgICAgICAgICAga3Muc2V0Q2VydGlmaWNhdGVFbnRyeShBTElBU19DRVJUSUZJQ0FURSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0UHJpdmF0ZUtleSgpLmdldENlcnRpZmljYXRlKCkpOworICAgICAgICB9CisgICAgICAgIGlmIChpc1NlY3JldEtleUVuYWJsZWQoa3MpKSB7CisgICAgICAgICAgICBzZXRTZWNyZXRLZXkoa3MpOworICAgICAgICAgICAgaWYgKGlzTnVsbFBhc3N3b3JkQWxsb3dlZChrcykpIHsKKyAgICAgICAgICAgICAgICBrcy5zZXRLZXlFbnRyeShBTElBU19OT19QQVNTV09SRF9TRUNSRVQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0U2VjcmV0S2V5KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRQcml2YXRlS2V5KEtleVN0b3JlIGtzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2V0UHJpdmF0ZUtleShrcywgQUxJQVNfUFJJVkFURSk7CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRQcml2YXRlS2V5KEtleVN0b3JlIGtzLCBTdHJpbmcgYWxpYXMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXRQcml2YXRlS2V5KGtzLCBhbGlhcywgZ2V0UHJpdmF0ZUtleSgpKTsKKyAgICB9CisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldFByaXZhdGVLZXkoS2V5U3RvcmUga3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGFsaWFzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByaXZhdGVLZXlFbnRyeSBwcml2YXRlS2V5KQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGtzLnNldEtleUVudHJ5KGFsaWFzLAorICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlS2V5LmdldFByaXZhdGVLZXkoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgUEFTU1dPUkRfS0VZLAorICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlS2V5LmdldENlcnRpZmljYXRlQ2hhaW4oKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldFByaXZhdGVLZXlCeXRlcyhLZXlTdG9yZSBrcykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNldFByaXZhdGVLZXlCeXRlcyhrcywgQUxJQVNfUFJJVkFURSk7CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRQcml2YXRlS2V5Qnl0ZXMoS2V5U3RvcmUga3MsIFN0cmluZyBhbGlhcykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNldFByaXZhdGVLZXlCeXRlcyhrcywgYWxpYXMsIGdldFByaXZhdGVLZXkoKSk7CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRQcml2YXRlS2V5Qnl0ZXMoS2V5U3RvcmUga3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGFsaWFzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByaXZhdGVLZXlFbnRyeSBwcml2YXRlS2V5KQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGtzLnNldEtleUVudHJ5KGFsaWFzLAorICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlS2V5LmdldFByaXZhdGVLZXkoKS5nZXRFbmNvZGVkKCksCisgICAgICAgICAgICAgICAgICAgICAgIHByaXZhdGVLZXkuZ2V0Q2VydGlmaWNhdGVDaGFpbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0U2VjcmV0S2V5KEtleVN0b3JlIGtzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2V0U2VjcmV0S2V5KGtzLCBBTElBU19TRUNSRVQpOworICAgIH0KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0U2VjcmV0S2V5KEtleVN0b3JlIGtzLCBTdHJpbmcgYWxpYXMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXRTZWNyZXRLZXkoa3MsIGFsaWFzLCBnZXRTZWNyZXRLZXkoKSk7CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRTZWNyZXRLZXkoS2V5U3RvcmUga3MsIFN0cmluZyBhbGlhcywgU2VjcmV0S2V5IGtleSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGtzLnNldEtleUVudHJ5KGFsaWFzLAorICAgICAgICAgICAgICAgICAgICAgICBrZXksCisgICAgICAgICAgICAgICAgICAgICAgIFBBU1NXT1JEX0tFWSwKKyAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldFNlY3JldEtleUJ5dGVzKEtleVN0b3JlIGtzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2V0U2VjcmV0S2V5Qnl0ZXMoa3MsIEFMSUFTX1NFQ1JFVCk7CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRTZWNyZXRLZXlCeXRlcyhLZXlTdG9yZSBrcywgU3RyaW5nIGFsaWFzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2V0U2VjcmV0S2V5Qnl0ZXMoa3MsIGFsaWFzLCBnZXRTZWNyZXRLZXkoKSk7CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRTZWNyZXRLZXlCeXRlcyhLZXlTdG9yZSBrcywgU3RyaW5nIGFsaWFzLCBTZWNyZXRLZXkga2V5KQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGtzLnNldEtleUVudHJ5KGFsaWFzLAorICAgICAgICAgICAgICAgICAgICAgICBrZXkuZ2V0RW5jb2RlZCgpLAorICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0Q2VydGlmaWNhdGUoS2V5U3RvcmUga3MpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXRDZXJ0aWZpY2F0ZShrcywgQUxJQVNfQ0VSVElGSUNBVEUpOworICAgIH0KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0Q2VydGlmaWNhdGUoS2V5U3RvcmUga3MsIFN0cmluZyBhbGlhcykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNldENlcnRpZmljYXRlKGtzLCBhbGlhcywgZ2V0UHJpdmF0ZUtleSgpLmdldENlcnRpZmljYXRlKCkpOworICAgIH0KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0Q2VydGlmaWNhdGUoS2V5U3RvcmUga3MsIFN0cmluZyBhbGlhcywgQ2VydGlmaWNhdGUgY2VydGlmaWNhdGUpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAga3Muc2V0Q2VydGlmaWNhdGVFbnRyeShhbGlhcywgY2VydGlmaWNhdGUpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRQcml2YXRlS2V5KEtleSBhY3R1YWwpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGdldFByaXZhdGVLZXkoKS5nZXRQcml2YXRlS2V5KCksIGFjdHVhbCk7CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRQcml2YXRlS2V5MihLZXkgYWN0dWFsKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyhnZXRQcml2YXRlS2V5MigpLmdldFByaXZhdGVLZXkoKSwgYWN0dWFsKTsKKyAgICB9CisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydFByaXZhdGVLZXkoRW50cnkgYWN0dWFsKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydE5vdE51bGwoYWN0dWFsKTsKKyAgICAgICAgYXNzZXJ0U2FtZShQcml2YXRlS2V5RW50cnkuY2xhc3MsIGFjdHVhbC5nZXRDbGFzcygpKTsKKyAgICAgICAgUHJpdmF0ZUtleUVudHJ5IHByaXZhdGVLZXkgPSAoUHJpdmF0ZUtleUVudHJ5KSBhY3R1YWw7CisgICAgICAgIGFzc2VydEVxdWFscyhnZXRQcml2YXRlS2V5KCkuZ2V0UHJpdmF0ZUtleSgpLCBwcml2YXRlS2V5LmdldFByaXZhdGVLZXkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhnZXRQcml2YXRlS2V5KCkuZ2V0Q2VydGlmaWNhdGUoKSwgcHJpdmF0ZUtleS5nZXRDZXJ0aWZpY2F0ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoZ2V0UHJpdmF0ZUtleSgpLmdldENlcnRpZmljYXRlQ2hhaW4oKSksCisgICAgICAgICAgICAgICAgICAgICBBcnJheXMuYXNMaXN0KHByaXZhdGVLZXkuZ2V0Q2VydGlmaWNhdGVDaGFpbigpKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydFNlY3JldEtleShLZXkgYWN0dWFsKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyhnZXRTZWNyZXRLZXkoKSwgYWN0dWFsKTsKKyAgICB9CisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydFNlY3JldEtleTIoS2V5IGFjdHVhbCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoZ2V0U2VjcmV0S2V5MigpLCBhY3R1YWwpOworICAgIH0KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYXNzZXJ0U2VjcmV0S2V5KEVudHJ5IGFjdHVhbCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRTYW1lKFNlY3JldEtleUVudHJ5LmNsYXNzLCBhY3R1YWwuZ2V0Q2xhc3MoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhnZXRTZWNyZXRLZXkoKSwgKChTZWNyZXRLZXlFbnRyeSkgYWN0dWFsKS5nZXRTZWNyZXRLZXkoKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydENlcnRpZmljYXRlKENlcnRpZmljYXRlIGFjdHVhbCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoZ2V0UHJpdmF0ZUtleSgpLmdldENlcnRpZmljYXRlKCksIGFjdHVhbCk7CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRDZXJ0aWZpY2F0ZTIoQ2VydGlmaWNhdGUgYWN0dWFsKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyhnZXRQcml2YXRlS2V5MigpLmdldENlcnRpZmljYXRlKCksIGFjdHVhbCk7CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRDZXJ0aWZpY2F0ZShFbnRyeSBhY3R1YWwpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0U2FtZShUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeS5jbGFzcywgYWN0dWFsLmdldENsYXNzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZ2V0UHJpdmF0ZUtleSgpLmdldENlcnRpZmljYXRlKCksCisgICAgICAgICAgICAgICAgICAgICAoKFRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5KSBhY3R1YWwpLmdldFRydXN0ZWRDZXJ0aWZpY2F0ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYXNzZXJ0Q2VydGlmaWNhdGVDaGFpbihDZXJ0aWZpY2F0ZVtdIGFjdHVhbCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChnZXRQcml2YXRlS2V5KCkuZ2V0Q2VydGlmaWNhdGVDaGFpbigpKSwKKyAgICAgICAgICAgICAgICAgICAgIEFycmF5cy5hc0xpc3QoYWN0dWFsKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9LZXlTdG9yZV9jcmVhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvdmlkZXJbXSBwcm92aWRlcnMgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoKTsKKyAgICAgICAgZm9yIChQcm92aWRlciBwcm92aWRlciA6IHByb3ZpZGVycykgeworICAgICAgICAgICAgU2V0PFByb3ZpZGVyLlNlcnZpY2U+IHNlcnZpY2VzID0gcHJvdmlkZXIuZ2V0U2VydmljZXMoKTsKKyAgICAgICAgICAgIGZvciAoUHJvdmlkZXIuU2VydmljZSBzZXJ2aWNlIDogc2VydmljZXMpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgdHlwZSA9IHNlcnZpY2UuZ2V0VHlwZSgpOworICAgICAgICAgICAgICAgIGlmICghdHlwZS5lcXVhbHMoIktleVN0b3JlIikpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIFN0cmluZyBhbGdvcml0aG0gPSBzZXJ2aWNlLmdldEFsZ29yaXRobSgpOworICAgICAgICAgICAgICAgIEtleVN0b3JlIGtzID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBwcm92aWRlcik7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHByb3ZpZGVyLCBrcy5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYWxnb3JpdGhtLCBrcy5nZXRUeXBlKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9LZXlTdG9yZV9nZXRJbnN0YW5jZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgdHlwZSA9IEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZS5nZXRJbnN0YW5jZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydE5vdE51bGwoS2V5U3RvcmUuZ2V0SW5zdGFuY2UodHlwZSkpOworCisgICAgICAgIFN0cmluZyBwcm92aWRlck5hbWUgPSBTdGFuZGFyZE5hbWVzLlNFQ1VSSVRZX1BST1ZJREVSX05BTUU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZS5nZXRJbnN0YW5jZShudWxsLCAoU3RyaW5nKW51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5U3RvcmUuZ2V0SW5zdGFuY2UobnVsbCwgcHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGlmIChlLmdldENsYXNzKCkgIT0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MKKyAgICAgICAgICAgICAgICAmJiBlLmdldENsYXNzKCkgIT0gS2V5U3RvcmVFeGNlcHRpb24uY2xhc3MpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZS5nZXRJbnN0YW5jZSh0eXBlLCAoU3RyaW5nKW51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROb3ROdWxsKEtleVN0b3JlLmdldEluc3RhbmNlKHR5cGUsIHByb3ZpZGVyTmFtZSkpOworCisgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXIocHJvdmlkZXJOYW1lKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVN0b3JlLmdldEluc3RhbmNlKG51bGwsIChQcm92aWRlciludWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVN0b3JlLmdldEluc3RhbmNlKG51bGwsIHByb3ZpZGVyKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5U3RvcmUuZ2V0SW5zdGFuY2UodHlwZSwgKFByb3ZpZGVyKW51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROb3ROdWxsKEtleVN0b3JlLmdldEluc3RhbmNlKHR5cGUsIHByb3ZpZGVyKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9LZXlTdG9yZV9nZXREZWZhdWx0VHlwZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgdHlwZSA9IEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwodHlwZSk7CisgICAgICAgIEtleVN0b3JlIGtzID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UodHlwZSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoa3MpOworICAgICAgICBhc3NlcnRFcXVhbHModHlwZSwga3MuZ2V0VHlwZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0tleVN0b3JlX2dldFByb3ZpZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEtleVN0b3JlIGtzID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoa3MuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoU3RhbmRhcmROYW1lcy5TRUNVUklUWV9QUk9WSURFUl9OQU1FLCBrcy5nZXRQcm92aWRlcigpLmdldE5hbWUoKSk7CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGtleVN0b3JlLmdldFByb3ZpZGVyKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9LZXlTdG9yZV9nZXRUeXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB0eXBlID0gS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKTsKKyAgICAgICAgS2V5U3RvcmUga3MgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZSh0eXBlKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChrcy5nZXRUeXBlKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHR5cGUsIGtzLmdldFR5cGUoKSk7CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGtleVN0b3JlLmdldFR5cGUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0tleVN0b3JlX2dldEtleSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuZ2V0S2V5KG51bGwsIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIHBvcHVsYXRlKGtleVN0b3JlKTsKKworICAgICAgICAgICAgLy8gdGVzdCBvZGQgaW5wdXRzCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLmdldEtleShudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGlmIChlLmdldENsYXNzKCkgIT0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MKKyAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDbGFzcygpICE9IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuZ2V0S2V5KG51bGwsIFBBU1NXT1JEX0tFWSk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBpZiAoZS5nZXRDbGFzcygpICE9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzCisgICAgICAgICAgICAgICAgICAgICYmIGUuZ2V0Q2xhc3MoKSAhPSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MKKyAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDbGFzcygpICE9IEtleVN0b3JlRXhjZXB0aW9uLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRLZXkoIiIsIG51bGwpKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KCIiLCBQQVNTV09SRF9LRVkpKTsKKworICAgICAgICAgICAgLy8gdGVzdCBjYXNlIHNlbnNpdGl2ZQorICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRLZXkoQUxJQVNfUFJJVkFURSwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFzc2VydFByaXZhdGVLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIGlmIChpc1NlY3JldEtleUVuYWJsZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFNlY3JldEtleShrZXlTdG9yZS5nZXRLZXkoQUxJQVNfU0VDUkVULCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldEtleShBTElBU19TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gdGVzdCBjYXNlIGluc2Vuc2l0aXZlCisgICAgICAgICAgICBpZiAoaXNDYXNlU2Vuc2l0aXZlKGtleVN0b3JlKSB8fCBpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFzc2VydFByaXZhdGVLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIGlmIChpc1NlY3JldEtleUVuYWJsZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFNlY3JldEtleShrZXlTdG9yZS5nZXRLZXkoQUxJQVNfQUxUX0NBU0VfU0VDUkVULCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIHRlc3Qgd2l0aCBudWxsIHBhc3N3b3JkcworICAgICAgICAgICAgaWYgKGlzS2V5UGFzc3dvcmRJZ25vcmVkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydFByaXZhdGVLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1BSSVZBVEUsIG51bGwpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1BSSVZBVEUsIG51bGwpKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1BSSVZBVEUsIG51bGwpOworICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUuZ2V0Q2xhc3MoKSAhPSBVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uLmNsYXNzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDbGFzcygpICE9IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaXNSZWFkT25seShrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldEtleShBTElBU19TRUNSRVQsIG51bGwpKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNTZWNyZXRLZXlFbmFibGVkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLmdldEtleShBTElBU19TRUNSRVQsIG51bGwpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGUuZ2V0Q2xhc3MoKSAhPSBVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uLmNsYXNzCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBlLmdldENsYXNzKCkgIT0gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB0ZXN0IHdpdGggYmFkIHBhc3N3b3JkcworICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRLZXkoQUxJQVNfUFJJVkFURSwgbnVsbCkpOworICAgICAgICAgICAgfSBlbHNlIGlmIChpc0tleVBhc3N3b3JkSWdub3JlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRQcml2YXRlS2V5KGtleVN0b3JlLmdldEtleShBTElBU19QUklWQVRFLCBudWxsKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLmdldEtleShBTElBU19QUklWQVRFLCBQQVNTV09SRF9CQUQpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1NFQ1JFVCwgUEFTU1dPUkRfQkFEKSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGlzU2VjcmV0S2V5RW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5nZXRLZXkoQUxJQVNfU0VDUkVULCBQQVNTV09SRF9CQUQpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfS2V5U3RvcmVfZ2V0Q2VydGlmaWNhdGVDaGFpbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGVDaGFpbihudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgcG9wdWxhdGUoa2V5U3RvcmUpOworCisgICAgICAgICAgICAvLyB0ZXN0IG9kZCBpbnB1dHMKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGVDaGFpbihudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGlmIChlLmdldENsYXNzKCkgIT0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MKKyAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDbGFzcygpICE9IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGVDaGFpbigiIikpOworCisgICAgICAgICAgICAvLyB0ZXN0IGNhc2Ugc2Vuc2l0aXZlCisgICAgICAgICAgICBpZiAoaXNSZWFkT25seShrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldENlcnRpZmljYXRlQ2hhaW4oQUxJQVNfUFJJVkFURSkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRDZXJ0aWZpY2F0ZUNoYWluKGtleVN0b3JlLmdldENlcnRpZmljYXRlQ2hhaW4oQUxJQVNfUFJJVkFURSkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB0ZXN0IGNhc2UgaW5zZW5zaXRpdmUKKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSB8fCBpc0Nhc2VTZW5zaXRpdmUoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZUNoYWluKEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0Q2VydGlmaWNhdGVDaGFpbihrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZUNoYWluKEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfS2V5U3RvcmVfZ2V0Q2VydGlmaWNhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLmdldENlcnRpZmljYXRlKG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBwb3B1bGF0ZShrZXlTdG9yZSk7CisKKyAgICAgICAgICAgIC8vIHRlc3Qgb2RkIGlucHV0cworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZShudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGlmIChlLmdldENsYXNzKCkgIT0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MKKyAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDbGFzcygpICE9IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGUoIiIpKTsKKworICAgICAgICAgICAgLy8gdGVzdCBjYXNlIHNlbnNpdGl2ZQorICAgICAgICAgICAgaWYgKCFpc1JlYWRPbmx5KGtleVN0b3JlKSAmJiBpc0NlcnRpZmljYXRlRW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRDZXJ0aWZpY2F0ZShrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZShBTElBU19DRVJUSUZJQ0FURSkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldENlcnRpZmljYXRlKEFMSUFTX0NFUlRJRklDQVRFKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIHRlc3QgY2FzZSBpbnNlbnNpdGl2ZQorICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoa2V5U3RvcmUpIHx8IGlzQ2FzZVNlbnNpdGl2ZShrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldENlcnRpZmljYXRlKEFMSUFTX0FMVF9DQVNFX0NFUlRJRklDQVRFKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmIChpc0NlcnRpZmljYXRlRW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Q2VydGlmaWNhdGUoa2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGUoQUxJQVNfQUxUX0NBU0VfQ0VSVElGSUNBVEUpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0tleVN0b3JlX2dldENyZWF0aW9uRGF0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuZ2V0Q3JlYXRpb25EYXRlKG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgbG9uZyBiZWZvcmUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICAvLyBhZGQgMTAwMCBzaW5jZSBzb21lIGtleSBzdG9yZXMgcm91bmQgb2YgdGltZSB0byBuZWFyZXN0IHNlY29uZAorICAgICAgICAgICAgbG9uZyBhZnRlciA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpICsgMTAwMDsKKyAgICAgICAgICAgIHBvcHVsYXRlKGtleVN0b3JlKTsKKworICAgICAgICAgICAgLy8gdGVzdCBvZGQgaW5wdXRzCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLmdldENyZWF0aW9uRGF0ZShudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRDcmVhdGlvbkRhdGUoIiIpKTsKKworICAgICAgICAgICAgLy8gdGVzdCBjYXNlIHNlbnNpdGl2ZQorICAgICAgICAgICAgaWYgKCFpc1JlYWRPbmx5KGtleVN0b3JlKSAmJiBpc0NlcnRpZmljYXRlRW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBEYXRlIGRhdGUgPSBrZXlTdG9yZS5nZXRDcmVhdGlvbkRhdGUoQUxJQVNfQ0VSVElGSUNBVEUpOworICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZGF0ZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShiZWZvcmUgPD0gZGF0ZS5nZXRUaW1lKCkpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoZGF0ZS5nZXRUaW1lKCkgPD0gYWZ0ZXIpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldENyZWF0aW9uRGF0ZShBTElBU19DRVJUSUZJQ0FURSkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB0ZXN0IGNhc2UgaW5zZW5zaXRpdmUKKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSB8fCBpc0Nhc2VTZW5zaXRpdmUoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRDcmVhdGlvbkRhdGUoQUxJQVNfQUxUX0NBU0VfQ0VSVElGSUNBVEUpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKGlzQ2VydGlmaWNhdGVFbmFibGVkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgICAgICBEYXRlIGRhdGUgPSBrZXlTdG9yZS5nZXRDcmVhdGlvbkRhdGUoQUxJQVNfQUxUX0NBU0VfQ0VSVElGSUNBVEUpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGJlZm9yZSA8PSBkYXRlLmdldFRpbWUoKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoZGF0ZS5nZXRUaW1lKCkgPD0gYWZ0ZXIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfS2V5U3RvcmVfc2V0S2V5RW50cnlfS2V5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5zZXRLZXlFbnRyeShudWxsLCBudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBrZXlTdG9yZS5sb2FkKG51bGwsIG51bGwpOworICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0S2V5RW50cnkobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gdGVzdCBvZGQgaW5wdXRzCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLnNldEtleUVudHJ5KG51bGwsIG51bGwsIG51bGwsIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgaWYgKGUuZ2V0Q2xhc3MoKSAhPSBOdWxsUG9pbnRlckV4Y2VwdGlvbi5jbGFzcworICAgICAgICAgICAgICAgICAgICAmJiBlLmdldENsYXNzKCkgIT0gS2V5U3RvcmVFeGNlcHRpb24uY2xhc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLnNldEtleUVudHJ5KG51bGwsIG51bGwsIFBBU1NXT1JEX0tFWSwgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBpZiAoZS5nZXRDbGFzcygpICE9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzCisgICAgICAgICAgICAgICAgICAgICYmIGUuZ2V0Q2xhc3MoKSAhPSBLZXlTdG9yZUV4Y2VwdGlvbi5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0S2V5RW50cnkoQUxJQVNfUFJJVkFURSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRQcml2YXRlS2V5KCkuZ2V0UHJpdmF0ZUtleSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBU1NXT1JEX0tFWSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCBudWxsKTsKKworICAgICAgICAgICAgLy8gdGVzdCBjYXNlIHNlbnNpdGl2ZQorICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRLZXkoQUxJQVNfUFJJVkFURSwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICBpZiAoaXNSZWFkT25seShrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5zZXRLZXlFbnRyeShBTElBU19TRUNSRVQsIGdldFNlY3JldEtleSgpLCBQQVNTV09SRF9LRVksIG51bGwpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzZXRQcml2YXRlS2V5KGtleVN0b3JlKTsKKyAgICAgICAgICAgIGFzc2VydFByaXZhdGVLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgYXNzZXJ0Q2VydGlmaWNhdGVDaGFpbihrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZUNoYWluKEFMSUFTX1BSSVZBVEUpKTsKKyAgICAgICAgICAgIGlmIChpc1NlY3JldEtleUVuYWJsZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRLZXkoQUxJQVNfU0VDUkVULCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgICAgICBzZXRTZWNyZXRLZXkoa2V5U3RvcmUpOworICAgICAgICAgICAgICAgIGFzc2VydFNlY3JldEtleShrZXlTdG9yZS5nZXRLZXkoQUxJQVNfU0VDUkVULCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0S2V5RW50cnkoQUxJQVNfU0VDUkVULCBnZXRTZWNyZXRLZXkoKSwgUEFTU1dPUkRfS0VZLCBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChlLmdldENsYXNzKCkgIT0gS2V5U3RvcmVFeGNlcHRpb24uY2xhc3MKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIGUuZ2V0Q2xhc3MoKSAhPSBOdWxsUG9pbnRlckV4Y2VwdGlvbi5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgcG9wdWxhdGUoa2V5U3RvcmUpOworCisgICAgICAgICAgICBpZiAoaXNSZWFkT25seShrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldEtleShBTElBU19QUklWQVRFLCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldEtleShBTElBU19BTFRfQ0FTRV9QUklWQVRFLCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldEtleShBTElBU19TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGlzQ2FzZVNlbnNpdGl2ZShrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRQcml2YXRlS2V5KGtleVN0b3JlLmdldEtleShBTElBU19QUklWQVRFLCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldEtleShBTElBU19BTFRfQ0FTRV9QUklWQVRFLCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgICAgICBzZXRQcml2YXRlS2V5KGtleVN0b3JlLCBBTElBU19BTFRfQ0FTRV9QUklWQVRFLCBnZXRQcml2YXRlS2V5MigpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRQcml2YXRlS2V5KGtleVN0b3JlLmdldEtleShBTElBU19QUklWQVRFLCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRQcml2YXRlS2V5MihrZXlTdG9yZS5nZXRLZXkoQUxJQVNfQUxUX0NBU0VfUFJJVkFURSwgUEFTU1dPUkRfS0VZKSk7CisKKyAgICAgICAgICAgICAgICBpZiAoaXNTZWNyZXRLZXlFbmFibGVkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRTZWNyZXRLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgICAgIHNldFNlY3JldEtleShrZXlTdG9yZSwgQUxJQVNfQUxUX0NBU0VfU0VDUkVULCBnZXRTZWNyZXRLZXkyKCkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRTZWNyZXRLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFNlY3JldEtleTIoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRQcml2YXRlS2V5KGtleVN0b3JlLmdldEtleShBTElBU19QUklWQVRFLCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRQcml2YXRlS2V5KGtleVN0b3JlLmdldEtleShBTElBU19BTFRfQ0FTRV9QUklWQVRFLCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgICAgICBzZXRQcml2YXRlS2V5KGtleVN0b3JlLCBBTElBU19BTFRfQ0FTRV9QUklWQVRFLCBnZXRQcml2YXRlS2V5MigpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRQcml2YXRlS2V5MihrZXlTdG9yZS5nZXRLZXkoQUxJQVNfUFJJVkFURSwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0UHJpdmF0ZUtleTIoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIGlmIChpc1NlY3JldEtleUVuYWJsZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFNlY3JldEtleShrZXlTdG9yZS5nZXRLZXkoQUxJQVNfU0VDUkVULCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0U2VjcmV0S2V5KGtleVN0b3JlLmdldEtleShBTElBU19BTFRfQ0FTRV9TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgICAgICBzZXRTZWNyZXRLZXkoa2V5U3RvcmUsIEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIGdldFNlY3JldEtleTIoKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFNlY3JldEtleShrZXlTdG9yZS5nZXRLZXkoQUxJQVNfU0VDUkVULCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0U2VjcmV0S2V5KGtleVN0b3JlLmdldEtleShBTElBU19BTFRfQ0FTRV9TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLnNldEtleUVudHJ5KEFMSUFTX1BSSVZBVEUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFByaXZhdGVLZXkoKS5nZXRQcml2YXRlS2V5KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFByaXZhdGVLZXkoKS5nZXRDZXJ0aWZpY2F0ZUNoYWluKCkpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIHRlc3Qgd2l0aCBudWxsIHBhc3N3b3JkcworICAgICAgICAgICAgaWYgKGlzTnVsbFBhc3N3b3JkQWxsb3dlZChrZXlTdG9yZSkgfHwgaXNLZXlQYXNzd29yZElnbm9yZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0S2V5RW50cnkoQUxJQVNfUFJJVkFURSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRQcml2YXRlS2V5KCkuZ2V0UHJpdmF0ZUtleSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0UHJpdmF0ZUtleSgpLmdldENlcnRpZmljYXRlQ2hhaW4oKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0UHJpdmF0ZUtleShrZXlTdG9yZS5nZXRLZXkoQUxJQVNfUFJJVkFURSwgbnVsbCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5zZXRLZXlFbnRyeShBTElBU19QUklWQVRFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRQcml2YXRlS2V5KCkuZ2V0UHJpdmF0ZUtleSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRQcml2YXRlS2V5KCkuZ2V0Q2VydGlmaWNhdGVDaGFpbigpKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChlLmdldENsYXNzKCkgIT0gVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbi5jbGFzcworICAgICAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDbGFzcygpICE9IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcworICAgICAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDbGFzcygpICE9IEtleVN0b3JlRXhjZXB0aW9uLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGlzU2VjcmV0S2V5RW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBpZiAoaXNOdWxsUGFzc3dvcmRBbGxvd2VkKGtleVN0b3JlKSB8fCBpc0tleVBhc3N3b3JkSWdub3JlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0S2V5RW50cnkoQUxJQVNfU0VDUkVULCBnZXRTZWNyZXRLZXkoKSwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFNlY3JldEtleShrZXlTdG9yZS5nZXRLZXkoQUxJQVNfU0VDUkVULCBudWxsKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLnNldEtleUVudHJ5KEFMSUFTX1NFQ1JFVCwgZ2V0U2VjcmV0S2V5KCksIG51bGwsIG51bGwpOworICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUuZ2V0Q2xhc3MoKSAhPSBVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uLmNsYXNzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDbGFzcygpICE9IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcworICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGUuZ2V0Q2xhc3MoKSAhPSBLZXlTdG9yZUV4Y2VwdGlvbi5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0tleVN0b3JlX3NldEtleUVudHJ5X2FycmF5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5zZXRLZXlFbnRyeShudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBrZXlTdG9yZS5sb2FkKG51bGwsIG51bGwpOworCisgICAgICAgICAgICBpZiAoaXNSZWFkT25seShrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5zZXRLZXlFbnRyeShudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB0ZXN0IG9kZCBpbnB1dHMKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0S2V5RW50cnkobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBpZiAoZS5nZXRDbGFzcygpICE9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzCisgICAgICAgICAgICAgICAgICAgICYmIGUuZ2V0Q2xhc3MoKSAhPSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MKKyAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDbGFzcygpICE9IEtleVN0b3JlRXhjZXB0aW9uLmNsYXNzCisgICAgICAgICAgICAgICAgICAgICYmIGUuZ2V0Q2xhc3MoKSAhPSBSdW50aW1lRXhjZXB0aW9uLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBpZiAoIWlzTnVsbFBhc3N3b3JkQWxsb3dlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICAvLyBUT0RPIFVzZSBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyB0byBwcm90ZWN0IGtleXMgaWYKKyAgICAgICAgICAgICAgICAvLyBwYXNzd29yZCBpcyByZXF1aXJlZC4KKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpc1NldEtleUJ5dGVBcnJheVVuaW1wbGVtZW50ZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGtleVN0b3JlLmxvYWQobnVsbCwgbnVsbCk7CisKKyAgICAgICAgICAgIC8vIHRlc3QgY2FzZSBzZW5zaXRpdmUKKyAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc2V0UHJpdmF0ZUtleUJ5dGVzKGtleVN0b3JlKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2V0UHJpdmF0ZUtleUJ5dGVzKGtleVN0b3JlKTsKKyAgICAgICAgICAgIGFzc2VydFByaXZhdGVLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgYXNzZXJ0Q2VydGlmaWNhdGVDaGFpbihrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZUNoYWluKEFMSUFTX1BSSVZBVEUpKTsKKyAgICAgICAgICAgIGlmIChpc1NlY3JldEtleUVuYWJsZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRLZXkoQUxJQVNfU0VDUkVULCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgICAgICBzZXRTZWNyZXRLZXlCeXRlcyhrZXlTdG9yZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0U2VjcmV0S2V5KGtleVN0b3JlLmdldEtleShBTElBU19TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5zZXRLZXlFbnRyeShBTElBU19TRUNSRVQsIGdldFNlY3JldEtleSgpLmdldEVuY29kZWQoKSwgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgaWYgKCFpc051bGxQYXNzd29yZEFsbG93ZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgLy8gVE9ETyBVc2UgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gdG8gcHJvdGVjdCBrZXlzIGlmCisgICAgICAgICAgICAgICAgLy8gcGFzc3dvcmQgaXMgcmVxdWlyZWQuCisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaXNTZXRLZXlCeXRlQXJyYXlVbmltcGxlbWVudGVkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwb3B1bGF0ZShrZXlTdG9yZSk7CisKKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRLZXkoQUxJQVNfQUxUX0NBU0VfU0VDUkVULCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNDYXNlU2Vuc2l0aXZlKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydFByaXZhdGVLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIHNldFByaXZhdGVLZXlCeXRlcyhrZXlTdG9yZSwgQUxJQVNfQUxUX0NBU0VfUFJJVkFURSwgZ2V0UHJpdmF0ZUtleTIoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0UHJpdmF0ZUtleShrZXlTdG9yZS5nZXRLZXkoQUxJQVNfUFJJVkFURSwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0UHJpdmF0ZUtleTIoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworCisgICAgICAgICAgICAgICAgaWYgKGlzU2VjcmV0S2V5RW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0U2VjcmV0S2V5KGtleVN0b3JlLmdldEtleShBTElBU19TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldEtleShBTElBU19BTFRfQ0FTRV9TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgICAgICBzZXRTZWNyZXRLZXlCeXRlcyhrZXlTdG9yZSwgQUxJQVNfQUxUX0NBU0VfUFJJVkFURSwgZ2V0U2VjcmV0S2V5MigpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0U2VjcmV0S2V5KGtleVN0b3JlLmdldEtleShBTElBU19TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRTZWNyZXRLZXkyKGtleVN0b3JlLmdldEtleShBTElBU19BTFRfQ0FTRV9TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0UHJpdmF0ZUtleShrZXlTdG9yZS5nZXRLZXkoQUxJQVNfUFJJVkFURSwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0UHJpdmF0ZUtleShrZXlTdG9yZS5nZXRLZXkoQUxJQVNfQUxUX0NBU0VfUFJJVkFURSwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgc2V0UHJpdmF0ZUtleUJ5dGVzKGtleVN0b3JlLCBBTElBU19BTFRfQ0FTRV9QUklWQVRFLCBnZXRQcml2YXRlS2V5MigpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRQcml2YXRlS2V5MihrZXlTdG9yZS5nZXRLZXkoQUxJQVNfUFJJVkFURSwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0UHJpdmF0ZUtleTIoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworCisgICAgICAgICAgICAgICAgaWYgKGlzU2VjcmV0S2V5RW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0U2VjcmV0S2V5KGtleVN0b3JlLmdldEtleShBTElBU19TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRTZWNyZXRLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgICAgIHNldFNlY3JldEtleUJ5dGVzKGtleVN0b3JlLCBBTElBU19BTFRfQ0FTRV9QUklWQVRFLCBnZXRTZWNyZXRLZXkyKCkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRTZWNyZXRLZXkyKGtleVN0b3JlLmdldEtleShBTElBU19TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRTZWNyZXRLZXkyKGtleVN0b3JlLmdldEtleShBTElBU19BTFRfQ0FTRV9TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfS2V5U3RvcmVfc2V0Q2VydGlmaWNhdGVFbnRyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0Q2VydGlmaWNhdGVFbnRyeShudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBwb3B1bGF0ZShrZXlTdG9yZSk7CisKKyAgICAgICAgICAgIC8vIHRlc3Qgb2RkIGlucHV0cworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5zZXRDZXJ0aWZpY2F0ZUVudHJ5KG51bGwsIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgaWYgKGUuZ2V0Q2xhc3MoKSAhPSBOdWxsUG9pbnRlckV4Y2VwdGlvbi5jbGFzcworICAgICAgICAgICAgICAgICAgICAmJiBlLmdldENsYXNzKCkgIT0gS2V5U3RvcmVFeGNlcHRpb24uY2xhc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGUoQUxJQVNfQ0VSVElGSUNBVEUpKTsKKyAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0Q2VydGlmaWNhdGVFbnRyeShBTElBU19DRVJUSUZJQ0FURSwgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gU29ydCBvZiBkZWxldGUgYnkgc2V0dGluZyBudWxsLiAgTm90ZSB0aGF0IGV2ZW4gdGhvdWdoCisgICAgICAgICAgICAvLyBjZXJ0aWZpY2F0ZSBpcyBudWxsLCBzaXplIGRvZXNuJ3QgY2hhbmdlLAorICAgICAgICAgICAgLy8gaXNDZXJ0aWZpY2F0ZUVudHJ5IHJldHVybnMgdHJ1ZSwgYW5kIGl0IGlzIHN0aWxsIGxpc3RlZCBpbiBhbGlhc2VzLgorICAgICAgICAgICAgaWYgKGlzQ2VydGlmaWNhdGVFbmFibGVkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydENlcnRpZmljYXRlKGtleVN0b3JlLmdldENlcnRpZmljYXRlKEFMSUFTX0NFUlRJRklDQVRFKSk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgaW50IHNpemUgPSBrZXlTdG9yZS5zaXplKCk7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLnNldENlcnRpZmljYXRlRW50cnkoQUxJQVNfQ0VSVElGSUNBVEUsIG51bGwpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldENlcnRpZmljYXRlKEFMSUFTX0NFUlRJRklDQVRFKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhzaXplLCBrZXlTdG9yZS5zaXplKCkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGtleVN0b3JlLmlzQ2VydGlmaWNhdGVFbnRyeShBTElBU19DRVJUSUZJQ0FURSkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKENvbGxlY3Rpb25zLmxpc3Qoa2V5U3RvcmUuYWxpYXNlcygpKS5jb250YWlucyhBTElBU19DRVJUSUZJQ0FURSkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkU29tZXRpbWVzKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiUEtDUzEyIiwga2V5U3RvcmUuZ2V0VHlwZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJCQyIsIGtleVN0b3JlLmdldFByb3ZpZGVyKCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLnNldENlcnRpZmljYXRlRW50cnkoQUxJQVNfQ0VSVElGSUNBVEUsIG51bGwpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIGlmICghaXNDZXJ0aWZpY2F0ZUVuYWJsZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGtleVN0b3JlLmxvYWQobnVsbCwgbnVsbCk7CisKKyAgICAgICAgICAgIC8vIHRlc3QgY2FzZSBzZW5zaXRpdmUKKyAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGUoQUxJQVNfQ0VSVElGSUNBVEUpKTsKKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHNldENlcnRpZmljYXRlKGtleVN0b3JlKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2V0Q2VydGlmaWNhdGUoa2V5U3RvcmUpOworICAgICAgICAgICAgYXNzZXJ0Q2VydGlmaWNhdGUoa2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGUoQUxJQVNfQ0VSVElGSUNBVEUpKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgaWYgKCFpc0NlcnRpZmljYXRlRW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcG9wdWxhdGUoa2V5U3RvcmUpOworCisgICAgICAgICAgICBpZiAoaXNSZWFkT25seShrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldEtleShBTElBU19QUklWQVRFLCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldEtleShBTElBU19BTFRfQ0FTRV9QUklWQVRFLCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldEtleShBTElBU19TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGlzQ2FzZVNlbnNpdGl2ZShrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRDZXJ0aWZpY2F0ZShrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZShBTElBU19DRVJUSUZJQ0FURSkpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGUoQUxJQVNfQUxUX0NBU0VfQ0VSVElGSUNBVEUpKTsKKyAgICAgICAgICAgICAgICBzZXRDZXJ0aWZpY2F0ZShrZXlTdG9yZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBTElBU19BTFRfQ0FTRV9DRVJUSUZJQ0FURSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRQcml2YXRlS2V5MigpLmdldENlcnRpZmljYXRlKCkpOworICAgICAgICAgICAgICAgIGFzc2VydENlcnRpZmljYXRlKGtleVN0b3JlLmdldENlcnRpZmljYXRlKEFMSUFTX0NFUlRJRklDQVRFKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0Q2VydGlmaWNhdGUyKGtleVN0b3JlLmdldENlcnRpZmljYXRlKEFMSUFTX0FMVF9DQVNFX0NFUlRJRklDQVRFKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFzc2VydENlcnRpZmljYXRlKGtleVN0b3JlLmdldENlcnRpZmljYXRlKEFMSUFTX0NFUlRJRklDQVRFKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0Q2VydGlmaWNhdGUoa2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGUoQUxJQVNfQUxUX0NBU0VfQ0VSVElGSUNBVEUpKTsKKyAgICAgICAgICAgICAgICBzZXRDZXJ0aWZpY2F0ZShrZXlTdG9yZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBTElBU19BTFRfQ0FTRV9DRVJUSUZJQ0FURSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRQcml2YXRlS2V5MigpLmdldENlcnRpZmljYXRlKCkpOworICAgICAgICAgICAgICAgIGFzc2VydENlcnRpZmljYXRlMihrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZShBTElBU19DRVJUSUZJQ0FURSkpOworICAgICAgICAgICAgICAgIGFzc2VydENlcnRpZmljYXRlMihrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZShBTElBU19BTFRfQ0FTRV9DRVJUSUZJQ0FURSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RfS2V5U3RvcmVfZGVsZXRlRW50cnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLmRlbGV0ZUVudHJ5KG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIGtleVN0b3JlLmxvYWQobnVsbCwgbnVsbCk7CisKKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLmRlbGV0ZUVudHJ5KG51bGwpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIHRlc3Qgb2RkIGlucHV0cworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5kZWxldGVFbnRyeShudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGlmIChlLmdldENsYXNzKCkgIT0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MKKyAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDbGFzcygpICE9IEtleVN0b3JlRXhjZXB0aW9uLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAga2V5U3RvcmUuZGVsZXRlRW50cnkoIiIpOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBwb3B1bGF0ZShrZXlTdG9yZSk7CisKKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLmRlbGV0ZUVudHJ5KEFMSUFTX1BSSVZBVEUpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIHRlc3QgY2FzZSBzZW5zaXRpdmUKKyAgICAgICAgICAgIGFzc2VydFByaXZhdGVLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgYXNzZXJ0Q2VydGlmaWNhdGVDaGFpbihrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZUNoYWluKEFMSUFTX1BSSVZBVEUpKTsKKyAgICAgICAgICAgIGtleVN0b3JlLmRlbGV0ZUVudHJ5KEFMSUFTX1BSSVZBVEUpOworICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRLZXkoQUxJQVNfUFJJVkFURSwgUEFTU1dPUkRfS0VZKSk7CisKKyAgICAgICAgICAgIGlmIChpc1NlY3JldEtleUVuYWJsZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0U2VjcmV0S2V5KGtleVN0b3JlLmdldEtleShBTElBU19TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIGtleVN0b3JlLmRlbGV0ZUVudHJ5KEFMSUFTX1NFQ1JFVCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRLZXkoQUxJQVNfU0VDUkVULCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuZGVsZXRlRW50cnkoQUxJQVNfU0VDUkVUKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGlzQ2VydGlmaWNhdGVFbmFibGVkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydENlcnRpZmljYXRlKGtleVN0b3JlLmdldENlcnRpZmljYXRlKEFMSUFTX0NFUlRJRklDQVRFKSk7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuZGVsZXRlRW50cnkoQUxJQVNfQ0VSVElGSUNBVEUpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGUoQUxJQVNfQ0VSVElGSUNBVEUpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuZGVsZXRlRW50cnkoQUxJQVNfQ0VSVElGSUNBVEUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBwb3B1bGF0ZShrZXlTdG9yZSk7CisKKyAgICAgICAgICAgIC8vIHRlc3QgY2FzZSBpbnNlbnNpdGl2ZQorCisgICAgICAgICAgICBpZiAoaXNDYXNlU2Vuc2l0aXZlKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydFByaXZhdGVLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIGtleVN0b3JlLmRlbGV0ZUVudHJ5KEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUpOworICAgICAgICAgICAgICAgIGFzc2VydFByaXZhdGVLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworCisgICAgICAgICAgICAgICAgaWYgKGlzU2VjcmV0S2V5RW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0U2VjcmV0S2V5KGtleVN0b3JlLmdldEtleShBTElBU19TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5kZWxldGVFbnRyeShBTElBU19BTFRfQ0FTRV9TRUNSRVQpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRTZWNyZXRLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuZGVsZXRlRW50cnkoQUxJQVNfU0VDUkVUKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoaXNDZXJ0aWZpY2F0ZUVuYWJsZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydENlcnRpZmljYXRlKGtleVN0b3JlLmdldENlcnRpZmljYXRlKEFMSUFTX0NFUlRJRklDQVRFKSk7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLmRlbGV0ZUVudHJ5KEFMSUFTX0FMVF9DQVNFX0NFUlRJRklDQVRFKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Q2VydGlmaWNhdGUoa2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGUoQUxJQVNfQ0VSVElGSUNBVEUpKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5kZWxldGVFbnRyeShBTElBU19DRVJUSUZJQ0FURSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9LZXlTdG9yZV9hbGlhc2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5hbGlhc2VzKCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGlmIChoYXNEZWZhdWx0Q29udGVudHMoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShrZXlTdG9yZS5hbGlhc2VzKCkuaGFzTW9yZUVsZW1lbnRzKCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoQ29sbGVjdGlvbnMuRU1QVFlfU0VULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSGFzaFNldChDb2xsZWN0aW9ucy5saXN0KGtleVN0b3JlLmFsaWFzZXMoKSkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgcG9wdWxhdGUoa2V5U3RvcmUpOworCisgICAgICAgICAgICBTZXQ8U3RyaW5nPiBleHBlY3RlZCA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKyAgICAgICAgICAgIGV4cGVjdGVkLmFkZChBTElBU19QUklWQVRFKTsKKyAgICAgICAgICAgIGlmIChpc051bGxQYXNzd29yZEFsbG93ZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgZXhwZWN0ZWQuYWRkKEFMSUFTX05PX1BBU1NXT1JEX1BSSVZBVEUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGlzU2VjcmV0S2V5RW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBleHBlY3RlZC5hZGQoQUxJQVNfU0VDUkVUKTsKKyAgICAgICAgICAgICAgICBpZiAoaXNOdWxsUGFzc3dvcmRBbGxvd2VkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgICAgICBleHBlY3RlZC5hZGQoQUxJQVNfTk9fUEFTU1dPUkRfU0VDUkVUKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaXNDZXJ0aWZpY2F0ZUVuYWJsZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgZXhwZWN0ZWQuYWRkKEFMSUFTX0NFUlRJRklDQVRFKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChoYXNEZWZhdWx0Q29udGVudHMoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShrZXlTdG9yZS5hbGlhc2VzKCkuaGFzTW9yZUVsZW1lbnRzKCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIG5ldyBIYXNoU2V0PFN0cmluZz4oQ29sbGVjdGlvbnMubGlzdChrZXlTdG9yZS5hbGlhc2VzKCkpKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0tleVN0b3JlX2NvbnRhaW5zQWxpYXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLmNvbnRhaW5zQWxpYXMobnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCBudWxsKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5jb250YWluc0FsaWFzKG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGtleVN0b3JlLmNvbnRhaW5zQWxpYXMoIiIpKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgcG9wdWxhdGUoa2V5U3RvcmUpOworCisgICAgICAgICAgICBhc3NlcnRGYWxzZShrZXlTdG9yZS5jb250YWluc0FsaWFzKCIiKSk7CisKKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKGtleVN0b3JlLmNvbnRhaW5zQWxpYXMoQUxJQVNfUFJJVkFURSkpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShrZXlTdG9yZS5jb250YWluc0FsaWFzKEFMSUFTX1BSSVZBVEUpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpc1NlY3JldEtleUVuYWJsZWQoa2V5U3RvcmUpLCBrZXlTdG9yZS5jb250YWluc0FsaWFzKEFMSUFTX1NFQ1JFVCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGlzQ2VydGlmaWNhdGVFbmFibGVkKGtleVN0b3JlKSwga2V5U3RvcmUuY29udGFpbnNBbGlhcyhBTElBU19DRVJUSUZJQ0FURSkpOworCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIWlzQ2FzZVNlbnNpdGl2ZShrZXlTdG9yZSksCisgICAgICAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuY29udGFpbnNBbGlhcyhBTElBU19BTFRfQ0FTRV9QUklWQVRFKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIWlzQ2FzZVNlbnNpdGl2ZShrZXlTdG9yZSkgJiYgaXNTZWNyZXRLZXlFbmFibGVkKGtleVN0b3JlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5jb250YWluc0FsaWFzKEFMSUFTX0FMVF9DQVNFX1NFQ1JFVCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCFpc0Nhc2VTZW5zaXRpdmUoa2V5U3RvcmUpICYmIGlzQ2VydGlmaWNhdGVFbmFibGVkKGtleVN0b3JlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5jb250YWluc0FsaWFzKEFMSUFTX0FMVF9DQVNFX0NFUlRJRklDQVRFKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0tleVN0b3JlX3NpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLmFsaWFzZXMoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBrZXlTdG9yZS5sb2FkKG51bGwsIG51bGwpOworICAgICAgICAgICAgaWYgKGhhc0RlZmF1bHRDb250ZW50cyhrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGtleVN0b3JlLnNpemUoKSA+IDApOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwga2V5U3RvcmUuc2l6ZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgcG9wdWxhdGUoa2V5U3RvcmUpOworICAgICAgICAgICAgaWYgKGhhc0RlZmF1bHRDb250ZW50cyhrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGtleVN0b3JlLnNpemUoKSA+IDApOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgZXhwZWN0ZWQgPSAxOworICAgICAgICAgICAgaWYgKGlzTnVsbFBhc3N3b3JkQWxsb3dlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBleHBlY3RlZCsrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGlzU2VjcmV0S2V5RW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBleHBlY3RlZCsrOworICAgICAgICAgICAgICAgIGlmIChpc051bGxQYXNzd29yZEFsbG93ZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGlzQ2VydGlmaWNhdGVFbmFibGVkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGV4cGVjdGVkKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIGtleVN0b3JlLnNpemUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0tleVN0b3JlX2lzS2V5RW50cnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLmlzS2V5RW50cnkobnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCBudWxsKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5pc0tleUVudHJ5KG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGtleVN0b3JlLmlzS2V5RW50cnkoIiIpKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgcG9wdWxhdGUoa2V5U3RvcmUpOworCisgICAgICAgICAgICBhc3NlcnRGYWxzZShrZXlTdG9yZS5pc0tleUVudHJ5KCIiKSk7CisgICAgICAgICAgICBpZiAoaXNSZWFkT25seShrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShrZXlTdG9yZS5pc0tleUVudHJ5KEFMSUFTX1BSSVZBVEUpKTsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoa2V5U3RvcmUuaXNLZXlFbnRyeShBTElBU19QUklWQVRFKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaXNTZWNyZXRLZXlFbmFibGVkKGtleVN0b3JlKSwga2V5U3RvcmUuaXNLZXlFbnRyeShBTElBU19TRUNSRVQpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGtleVN0b3JlLmlzS2V5RW50cnkoQUxJQVNfQ0VSVElGSUNBVEUpKTsKKworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCFpc0Nhc2VTZW5zaXRpdmUoa2V5U3RvcmUpLAorICAgICAgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLmlzS2V5RW50cnkoQUxJQVNfQUxUX0NBU0VfUFJJVkFURSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCFpc0Nhc2VTZW5zaXRpdmUoa2V5U3RvcmUpICYmIGlzU2VjcmV0S2V5RW5hYmxlZChrZXlTdG9yZSksCisgICAgICAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuaXNLZXlFbnRyeShBTElBU19BTFRfQ0FTRV9TRUNSRVQpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGtleVN0b3JlLmlzS2V5RW50cnkoQUxJQVNfQUxUX0NBU0VfQ0VSVElGSUNBVEUpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfS2V5U3RvcmVfaXNDZXJ0aWZpY2F0ZUVudHJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5pc0NlcnRpZmljYXRlRW50cnkobnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCBudWxsKTsKKworICAgICAgICAgICAgaWYgKGlzQ2VydGlmaWNhdGVFbmFibGVkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLmlzQ2VydGlmaWNhdGVFbnRyeShudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShrZXlTdG9yZS5pc0NlcnRpZmljYXRlRW50cnkobnVsbCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBhc3NlcnRGYWxzZShrZXlTdG9yZS5pc0NlcnRpZmljYXRlRW50cnkoIiIpKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgcG9wdWxhdGUoa2V5U3RvcmUpOworCisgICAgICAgICAgICBhc3NlcnRGYWxzZShrZXlTdG9yZS5pc0NlcnRpZmljYXRlRW50cnkoIiIpKTsKKworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuaXNDZXJ0aWZpY2F0ZUVudHJ5KEFMSUFTX1BSSVZBVEUpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGtleVN0b3JlLmlzQ2VydGlmaWNhdGVFbnRyeShBTElBU19TRUNSRVQpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpc0NlcnRpZmljYXRlRW5hYmxlZChrZXlTdG9yZSkgJiYgIWlzUmVhZE9ubHkoa2V5U3RvcmUpLAorICAgICAgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLmlzQ2VydGlmaWNhdGVFbnRyeShBTElBU19DRVJUSUZJQ0FURSkpOworCisgICAgICAgICAgICBhc3NlcnRGYWxzZShrZXlTdG9yZS5pc0NlcnRpZmljYXRlRW50cnkoQUxJQVNfQUxUX0NBU0VfUFJJVkFURSkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuaXNDZXJ0aWZpY2F0ZUVudHJ5KEFMSUFTX0FMVF9DQVNFX1NFQ1JFVCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCFpc0Nhc2VTZW5zaXRpdmUoa2V5U3RvcmUpCisgICAgICAgICAgICAgICAgICAgICAgICAgJiYgaXNDZXJ0aWZpY2F0ZUVuYWJsZWQoa2V5U3RvcmUpCisgICAgICAgICAgICAgICAgICAgICAgICAgJiYgIWlzUmVhZE9ubHkoa2V5U3RvcmUpLAorICAgICAgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLmlzQ2VydGlmaWNhdGVFbnRyeShBTElBU19BTFRfQ0FTRV9DRVJUSUZJQ0FURSkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9LZXlTdG9yZV9nZXRDZXJ0aWZpY2F0ZUFsaWFzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZUFsaWFzKG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIGtleVN0b3JlLmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldENlcnRpZmljYXRlQWxpYXMobnVsbCkpOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBwb3B1bGF0ZShrZXlTdG9yZSk7CisKKyAgICAgICAgICAgIFNldDxTdHJpbmc+IGV4cGVjdGVkID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgICAgICAgZXhwZWN0ZWQuYWRkKEFMSUFTX1BSSVZBVEUpOworICAgICAgICAgICAgaWYgKGlzTnVsbFBhc3N3b3JkQWxsb3dlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBleHBlY3RlZC5hZGQoQUxJQVNfTk9fUEFTU1dPUkRfUFJJVkFURSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaXNDZXJ0aWZpY2F0ZUVuYWJsZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgZXhwZWN0ZWQuYWRkKEFMSUFTX0NFUlRJRklDQVRFKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN0cmluZyBhY3R1YWwgPSBrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZUFsaWFzKGdldFByaXZhdGVLZXkoKS5nZXRDZXJ0aWZpY2F0ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyghaXNSZWFkT25seShrZXlTdG9yZSksIGV4cGVjdGVkLmNvbnRhaW5zKGFjdHVhbCkpOworICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZUFsaWFzKGdldFByaXZhdGVLZXkyKCkuZ2V0Q2VydGlmaWNhdGUoKSkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzS2V5U3RvcmVzKEZpbGUgZXhwZWN0ZWQsIGNoYXJbXSBzdG9yZVBhc3N3b3JkLCBLZXlTdG9yZSBhY3R1YWwpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9ueworICAgICAgICBLZXlTdG9yZSBrcyA9IEtleVN0b3JlLmdldEluc3RhbmNlKGFjdHVhbC5nZXRUeXBlKCksIGFjdHVhbC5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGV4cGVjdGVkKTsKKyAgICAgICAga3MubG9hZChpcywgc3RvcmVQYXNzd29yZCk7CisgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIGFzc2VydEVxdWFsc0tleVN0b3JlcyhrcywgYWN0dWFsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHNLZXlTdG9yZXMoS2V5U3RvcmUgZXhwZWN0ZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBhY3R1YWwsIGNoYXJbXSBzdG9yZVBhc3N3b3JkKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICAgICAgS2V5U3RvcmUga3MgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShleHBlY3RlZC5nZXRUeXBlKCksIGV4cGVjdGVkLmdldFByb3ZpZGVyKCkpOworICAgICAgICBrcy5sb2FkKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShhY3R1YWwudG9CeXRlQXJyYXkoKSksIHN0b3JlUGFzc3dvcmQpOworICAgICAgICBhc3NlcnRFcXVhbHNLZXlTdG9yZXMoZXhwZWN0ZWQsIGtzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHNLZXlTdG9yZXMoS2V5U3RvcmUgZXhwZWN0ZWQsIEtleVN0b3JlIGFjdHVhbCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZC5zaXplKCksIGFjdHVhbC5zaXplKCkpOworICAgICAgICBmb3IgKFN0cmluZyBhbGlhcyA6IENvbGxlY3Rpb25zLmxpc3QoYWN0dWFsLmFsaWFzZXMoKSkpIHsKKyAgICAgICAgICAgIGlmIChhbGlhcy5lcXVhbHMoQUxJQVNfTk9fUEFTU1dPUkRfUFJJVkFURSkKKyAgICAgICAgICAgICAgICAgICAgfHwgYWxpYXMuZXF1YWxzKEFMSUFTX05PX1BBU1NXT1JEX1NFQ1JFVCkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQuZ2V0S2V5KGFsaWFzLCBudWxsKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0dWFsLmdldEtleShhbGlhcywgbnVsbCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQuZ2V0S2V5KGFsaWFzLCBQQVNTV09SRF9LRVkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3R1YWwuZ2V0S2V5KGFsaWFzLCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZC5nZXRDZXJ0aWZpY2F0ZShhbGlhcyksIGFjdHVhbC5nZXRDZXJ0aWZpY2F0ZShhbGlhcykpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9LZXlTdG9yZV9zdG9yZV9PdXRwdXRTdHJlYW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLnN0b3JlKG51bGwsIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIGtleVN0b3JlLmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuc3RvcmUob3V0LCBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoaXNOdWxsUGFzc3dvcmRBbGxvd2VkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLnN0b3JlKG91dCwgbnVsbCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzS2V5U3RvcmVzKGtleVN0b3JlLCBvdXQsIG51bGwpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLnN0b3JlKG91dCwgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBpZiAoZS5nZXRDbGFzcygpICE9IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcworICAgICAgICAgICAgICAgICAgICAmJiBlLmdldENsYXNzKCkgIT0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIHBvcHVsYXRlKGtleVN0b3JlKTsKKworICAgICAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLnN0b3JlKG91dCwgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmIChpc051bGxQYXNzd29yZEFsbG93ZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuc3RvcmUob3V0LCBudWxsKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHNLZXlTdG9yZXMoa2V5U3RvcmUsIG91dCwgbnVsbCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLnN0b3JlKG91dCwgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBpZiAoZS5nZXRDbGFzcygpICE9IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcworICAgICAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDbGFzcygpICE9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBrZXlTdG9yZS5sb2FkKG51bGwsIG51bGwpOworICAgICAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLnN0b3JlKG91dCwgUEFTU1dPUkRfU1RPUkUpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGtleVN0b3JlLnN0b3JlKG91dCwgUEFTU1dPUkRfU1RPUkUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzS2V5U3RvcmVzKGtleVN0b3JlLCBvdXQsIFBBU1NXT1JEX1NUT1JFKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgcG9wdWxhdGUoa2V5U3RvcmUpOworICAgICAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLnN0b3JlKG91dCwgUEFTU1dPUkRfU1RPUkUpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGtleVN0b3JlLnN0b3JlKG91dCwgUEFTU1dPUkRfU1RPUkUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzS2V5U3RvcmVzKGtleVN0b3JlLCBvdXQsIFBBU1NXT1JEX1NUT1JFKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfS2V5U3RvcmVfc3RvcmVfTG9hZFN0b3JlUGFyYW1ldGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5zdG9yZShudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBrZXlTdG9yZS5sb2FkKG51bGwsIG51bGwpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5zdG9yZShudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKGlzTG9hZFN0b3JlUGFyYW1ldGVyU3VwcG9ydGVkKGtleVN0b3JlKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICAvLyBpdHMgc3VwcG9ydGVkLCBidXQgbnVsbCBjYXVzZXMgYW4gZXhjZXB0aW9uCisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShpc0xvYWRTdG9yZVBhcmFtZXRlclN1cHBvcnRlZChrZXlTdG9yZSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9LZXlTdG9yZV9sb2FkX0lucHV0U3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGlmIChoYXNEZWZhdWx0Q29udGVudHMoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShrZXlTdG9yZS5zaXplKCkgPiAwKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGtleVN0b3JlLnNpemUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIGtleVN0b3JlLmxvYWQobnVsbCwgUEFTU1dPUkRfU1RPUkUpOworICAgICAgICAgICAgaWYgKGhhc0RlZmF1bHRDb250ZW50cyhrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGtleVN0b3JlLnNpemUoKSA+IDApOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwga2V5U3RvcmUuc2l6ZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3RfS2V5U3RvcmVfc3RvcmVfT3V0cHV0U3RyZWFtIGVmZmVjdGl2ZWx5IHRlc3RzIGxvYWQgYXMgd2VsbCBhcyBzdG9yZQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfS2V5U3RvcmVfbG9hZF9Mb2FkU3RvcmVQYXJhbWV0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBrZXlTdG9yZS5sb2FkKG51bGwpOworICAgICAgICAgICAgaWYgKGhhc0RlZmF1bHRDb250ZW50cyhrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGtleVN0b3JlLnNpemUoKSA+IDApOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwga2V5U3RvcmUuc2l6ZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5sb2FkKG5ldyBMb2FkU3RvcmVQYXJhbWV0ZXIoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgUHJvdGVjdGlvblBhcmFtZXRlciBnZXRQcm90ZWN0aW9uUGFyYW1ldGVyKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9LZXlTdG9yZV9nZXRFbnRyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuZ2V0RW50cnkobnVsbCwgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgcG9wdWxhdGUoa2V5U3RvcmUpOworCisgICAgICAgICAgICAvLyB0ZXN0IG9kZCBpbnB1dHMKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuZ2V0RW50cnkobnVsbCwgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuZ2V0RW50cnkobnVsbCwgUEFSQU1fS0VZKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRFbnRyeSgiIiwgbnVsbCkpOworICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRFbnRyeSgiIiwgUEFSQU1fS0VZKSk7CisKKyAgICAgICAgICAgIC8vIHRlc3QgY2FzZSBzZW5zaXRpdmUKKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0RW50cnkoQUxJQVNfUFJJVkFURSwgUEFSQU1fS0VZKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFzc2VydFByaXZhdGVLZXkoa2V5U3RvcmUuZ2V0RW50cnkoQUxJQVNfUFJJVkFURSwgUEFSQU1fS0VZKSk7CisgICAgICAgICAgICAgICAgaWYgKGlzU2VjcmV0S2V5RW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0U2VjcmV0S2V5KGtleVN0b3JlLmdldEVudHJ5KEFMSUFTX1NFQ1JFVCwgUEFSQU1fS0VZKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRFbnRyeShBTElBU19TRUNSRVQsIFBBUkFNX0tFWSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoaXNDZXJ0aWZpY2F0ZUVuYWJsZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydENlcnRpZmljYXRlKGtleVN0b3JlLmdldEVudHJ5KEFMSUFTX0NFUlRJRklDQVRFLCBudWxsKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRFbnRyeShBTElBU19DRVJUSUZJQ0FURSwgbnVsbCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gdGVzdCBjYXNlIGluc2Vuc2l0aXZlCisgICAgICAgICAgICBpZiAoaXNDYXNlU2Vuc2l0aXZlKGtleVN0b3JlKSB8fCBpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0RW50cnkoQUxJQVNfQUxUX0NBU0VfUFJJVkFURSwgUEFSQU1fS0VZKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRFbnRyeShBTElBU19BTFRfQ0FTRV9TRUNSRVQsIFBBUkFNX0tFWSkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRQcml2YXRlS2V5KGtleVN0b3JlLmdldEVudHJ5KEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIFBBUkFNX0tFWSkpOworICAgICAgICAgICAgICAgIGlmIChpc1NlY3JldEtleUVuYWJsZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFNlY3JldEtleShrZXlTdG9yZS5nZXRFbnRyeShBTElBU19BTFRfQ0FTRV9TRUNSRVQsIFBBUkFNX0tFWSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpc0Nhc2VTZW5zaXRpdmUoa2V5U3RvcmUpIHx8IGlzUmVhZE9ubHkoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRFbnRyeShBTElBU19BTFRfQ0FTRV9DRVJUSUZJQ0FURSwgbnVsbCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAoaXNDZXJ0aWZpY2F0ZUVuYWJsZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydENlcnRpZmljYXRlKGtleVN0b3JlLmdldEVudHJ5KEFMSUFTX0FMVF9DQVNFX0NFUlRJRklDQVRFLCBudWxsKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB0ZXN0IHdpdGggbnVsbCBwYXNzd29yZHMKKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0RW50cnkoQUxJQVNfTk9fUEFTU1dPUkRfUFJJVkFURSwgbnVsbCkpOworICAgICAgICAgICAgfSBlbHNlIGlmIChpc051bGxQYXNzd29yZEFsbG93ZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0UHJpdmF0ZUtleShrZXlTdG9yZS5nZXRFbnRyeShBTElBU19OT19QQVNTV09SRF9QUklWQVRFLCBudWxsKSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGlzS2V5UGFzc3dvcmRJZ25vcmVkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydFByaXZhdGVLZXkoa2V5U3RvcmUuZ2V0RW50cnkoQUxJQVNfUFJJVkFURSwgbnVsbCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5nZXRFbnRyeShBTElBU19QUklWQVRFLCBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChlLmdldENsYXNzKCkgIT0gVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbi5jbGFzcworICAgICAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDbGFzcygpICE9IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0RW50cnkoQUxJQVNfU0VDUkVULCBudWxsKSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGlzU2VjcmV0S2V5RW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5nZXRFbnRyeShBTElBU19TRUNSRVQsIG51bGwpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGUuZ2V0Q2xhc3MoKSAhPSBVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uLmNsYXNzCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBlLmdldENsYXNzKCkgIT0gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB0ZXN0IHdpdGggYmFkIHBhc3N3b3JkcworICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRFbnRyeShBTElBU19QUklWQVRFLCBQQVJBTV9CQUQpKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNLZXlQYXNzd29yZElnbm9yZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0UHJpdmF0ZUtleShrZXlTdG9yZS5nZXRFbnRyeShBTElBU19QUklWQVRFLCBQQVJBTV9CQUQpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuZ2V0RW50cnkoQUxJQVNfUFJJVkFURSwgUEFSQU1fQkFEKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaXNSZWFkT25seShrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldEVudHJ5KEFMSUFTX1NFQ1JFVCwgUEFSQU1fQkFEKSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGlzU2VjcmV0S2V5RW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5nZXRFbnRyeShBTElBU19TRUNSRVQsIFBBUkFNX0JBRCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9LZXlTdG9yZV9zZXRFbnRyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIGtleVN0b3JlLmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLnNldEVudHJ5KG51bGwsIG51bGwsIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIGtleVN0b3JlLmxvYWQobnVsbCwgbnVsbCk7CisKKyAgICAgICAgICAgIC8vIHRlc3Qgb2RkIGlucHV0cworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5zZXRFbnRyeShudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGlmIChlLmdldENsYXNzKCkgIT0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MKKyAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDbGFzcygpICE9IEtleVN0b3JlRXhjZXB0aW9uLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5zZXRFbnRyeShudWxsLCBudWxsLCBQQVJBTV9LRVkpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgaWYgKGUuZ2V0Q2xhc3MoKSAhPSBOdWxsUG9pbnRlckV4Y2VwdGlvbi5jbGFzcworICAgICAgICAgICAgICAgICAgICAmJiBlLmdldENsYXNzKCkgIT0gS2V5U3RvcmVFeGNlcHRpb24uY2xhc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLnNldEVudHJ5KCIiLCBudWxsLCBQQVJBTV9LRVkpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIGtleVN0b3JlLmxvYWQobnVsbCwgbnVsbCk7CisKKyAgICAgICAgICAgIC8vIHRlc3QgY2FzZSBzZW5zaXRpdmUKKyAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0RW50cnkoQUxJQVNfUFJJVkFURSwgZ2V0UHJpdmF0ZUtleSgpLCBQQVJBTV9LRVkpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBrZXlTdG9yZS5zZXRFbnRyeShBTElBU19QUklWQVRFLCBnZXRQcml2YXRlS2V5KCksIFBBUkFNX0tFWSk7CisgICAgICAgICAgICBhc3NlcnRQcml2YXRlS2V5KGtleVN0b3JlLmdldEtleShBTElBU19QUklWQVRFLCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgIGFzc2VydENlcnRpZmljYXRlQ2hhaW4oa2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGVDaGFpbihBTElBU19QUklWQVRFKSk7CisgICAgICAgICAgICBpZiAoaXNTZWNyZXRLZXlFbmFibGVkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0RW50cnkoQUxJQVNfU0VDUkVULCBuZXcgU2VjcmV0S2V5RW50cnkoZ2V0U2VjcmV0S2V5KCkpLCBQQVJBTV9LRVkpOworICAgICAgICAgICAgICAgIGFzc2VydFNlY3JldEtleShrZXlTdG9yZS5nZXRLZXkoQUxJQVNfU0VDUkVULCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0S2V5RW50cnkoQUxJQVNfU0VDUkVULCBnZXRTZWNyZXRLZXkoKSwgUEFTU1dPUkRfS0VZLCBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGlzQ2VydGlmaWNhdGVFbmFibGVkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGUoQUxJQVNfQ0VSVElGSUNBVEUpKTsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5zZXRFbnRyeShBTElBU19DRVJUSUZJQ0FURSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVHJ1c3RlZENlcnRpZmljYXRlRW50cnkoZ2V0UHJpdmF0ZUtleSgpLmdldENlcnRpZmljYXRlKCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOworICAgICAgICAgICAgICAgIGFzc2VydENlcnRpZmljYXRlKGtleVN0b3JlLmdldENlcnRpZmljYXRlKEFMSUFTX0NFUlRJRklDQVRFKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLnNldEVudHJ5KEFMSUFTX0NFUlRJRklDQVRFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVHJ1c3RlZENlcnRpZmljYXRlRW50cnkoZ2V0UHJpdmF0ZUtleSgpLmdldENlcnRpZmljYXRlKCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBwb3B1bGF0ZShrZXlTdG9yZSk7CisKKyAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlTdG9yZS5nZXRLZXkoQUxJQVNfQUxUX0NBU0VfU0VDUkVULCBQQVNTV09SRF9LRVkpKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNDYXNlU2Vuc2l0aXZlKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgIGFzc2VydFByaXZhdGVLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgIGtleVN0b3JlLnNldEVudHJ5KEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIGdldFByaXZhdGVLZXkyKCksIFBBUkFNX0tFWSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0UHJpdmF0ZUtleShrZXlTdG9yZS5nZXRLZXkoQUxJQVNfUFJJVkFURSwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0UHJpdmF0ZUtleTIoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworCisgICAgICAgICAgICAgICAgaWYgKGlzU2VjcmV0S2V5RW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0U2VjcmV0S2V5KGtleVN0b3JlLmdldEtleShBTElBU19TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldEtleShBTElBU19BTFRfQ0FTRV9TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5zZXRFbnRyeShBTElBU19BTFRfQ0FTRV9TRUNSRVQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTZWNyZXRLZXlFbnRyeShnZXRTZWNyZXRLZXkyKCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQVJBTV9LRVkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRTZWNyZXRLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFNlY3JldEtleTIoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGlzQ2VydGlmaWNhdGVFbmFibGVkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRDZXJ0aWZpY2F0ZShrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZShBTElBU19DRVJUSUZJQ0FURSkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVN0b3JlLmdldENlcnRpZmljYXRlKEFMSUFTX0FMVF9DQVNFX0NFUlRJRklDQVRFKSk7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLnNldEVudHJ5KEFMSUFTX0FMVF9DQVNFX0NFUlRJRklDQVRFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVHJ1c3RlZENlcnRpZmljYXRlRW50cnkoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0UHJpdmF0ZUtleTIoKS5nZXRDZXJ0aWZpY2F0ZSgpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydENlcnRpZmljYXRlKGtleVN0b3JlLmdldENlcnRpZmljYXRlKEFMSUFTX0NFUlRJRklDQVRFKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydENlcnRpZmljYXRlMihrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZShBTElBU19BTFRfQ0FTRV9DRVJUSUZJQ0FURSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0UHJpdmF0ZUtleShrZXlTdG9yZS5nZXRLZXkoQUxJQVNfUFJJVkFURSwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0UHJpdmF0ZUtleShrZXlTdG9yZS5nZXRLZXkoQUxJQVNfQUxUX0NBU0VfUFJJVkFURSwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0RW50cnkoQUxJQVNfQUxUX0NBU0VfUFJJVkFURSwgZ2V0UHJpdmF0ZUtleTIoKSwgUEFSQU1fS0VZKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRQcml2YXRlS2V5MihrZXlTdG9yZS5nZXRLZXkoQUxJQVNfUFJJVkFURSwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0UHJpdmF0ZUtleTIoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIFBBU1NXT1JEX0tFWSkpOworCisgICAgICAgICAgICAgICAgaWYgKGlzU2VjcmV0S2V5RW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0U2VjcmV0S2V5KGtleVN0b3JlLmdldEtleShBTElBU19TRUNSRVQsIFBBU1NXT1JEX0tFWSkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRTZWNyZXRLZXkoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLnNldEVudHJ5KEFMSUFTX0FMVF9DQVNFX1NFQ1JFVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFNlY3JldEtleUVudHJ5KGdldFNlY3JldEtleTIoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBUkFNX0tFWSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFNlY3JldEtleTIoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFNlY3JldEtleTIoa2V5U3RvcmUuZ2V0S2V5KEFMSUFTX0FMVF9DQVNFX1NFQ1JFVCwgUEFTU1dPUkRfS0VZKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGlzQ2VydGlmaWNhdGVFbmFibGVkKGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRDZXJ0aWZpY2F0ZShrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZShBTElBU19DRVJUSUZJQ0FURSkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRDZXJ0aWZpY2F0ZShrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZShBTElBU19BTFRfQ0FTRV9DRVJUSUZJQ0FURSkpOworICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5zZXRFbnRyeShBTElBU19BTFRfQ0FTRV9DRVJUSUZJQ0FURSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFByaXZhdGVLZXkyKCkuZ2V0Q2VydGlmaWNhdGUoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRDZXJ0aWZpY2F0ZTIoa2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGUoQUxJQVNfQ0VSVElGSUNBVEUpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Q2VydGlmaWNhdGUyKGtleVN0b3JlLmdldENlcnRpZmljYXRlKEFMSUFTX0FMVF9DQVNFX0NFUlRJRklDQVRFKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBrZXlTdG9yZS5sb2FkKG51bGwsIG51bGwpOworCisgICAgICAgICAgICAvLyB0ZXN0IHdpdGggbnVsbC9ub24tbnVsbCBwYXNzd29yZHMKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0RW50cnkoQUxJQVNfUFJJVkFURSwgZ2V0UHJpdmF0ZUtleSgpLCBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGlmIChlLmdldENsYXNzKCkgIT0gVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbi5jbGFzcworICAgICAgICAgICAgICAgICAgICAmJiBlLmdldENsYXNzKCkgIT0gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzCisgICAgICAgICAgICAgICAgICAgICYmIGUuZ2V0Q2xhc3MoKSAhPSBLZXlTdG9yZUV4Y2VwdGlvbi5jbGFzcykgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpc1NlY3JldEtleUVuYWJsZWQoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0RW50cnkoQUxJQVNfU0VDUkVULCBuZXcgU2VjcmV0S2V5RW50cnkoZ2V0U2VjcmV0S2V5KCkpLCBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChlLmdldENsYXNzKCkgIT0gVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbi5jbGFzcworICAgICAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDbGFzcygpICE9IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcworICAgICAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDbGFzcygpICE9IEtleVN0b3JlRXhjZXB0aW9uLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0RW50cnkoQUxJQVNfQ0VSVElGSUNBVEUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeShnZXRQcml2YXRlS2V5KCkuZ2V0Q2VydGlmaWNhdGUoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBUkFNX0tFWSk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpc0NlcnRpZmljYXRlRW5hYmxlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICBpZiAoaXNOdWxsUGFzc3dvcmRBbGxvd2VkKGtleVN0b3JlKSB8fCBpc0tleVBhc3N3b3JkSWdub3JlZChrZXlTdG9yZSkpIHsKKyAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuc2V0RW50cnkoQUxJQVNfQ0VSVElGSUNBVEUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeShnZXRQcml2YXRlS2V5KCkuZ2V0Q2VydGlmaWNhdGUoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBUkFNX0tFWSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydENlcnRpZmljYXRlKGtleVN0b3JlLmdldENlcnRpZmljYXRlKEFMSUFTX0NFUlRJRklDQVRFKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLnNldEVudHJ5KEFMSUFTX0NFUlRJRklDQVRFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRQcml2YXRlS2V5KCkuZ2V0Q2VydGlmaWNhdGUoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQVJBTV9LRVkpOworICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9LZXlTdG9yZV9lbnRyeUluc3RhbmNlT2YoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZihudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBrZXlTdG9yZS5sb2FkKG51bGwsIG51bGwpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZihudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5lbnRyeUluc3RhbmNlT2YobnVsbCwgRW50cnkuY2xhc3MpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZigiIiwgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKCIiLCBFbnRyeS5jbGFzcykpOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBwb3B1bGF0ZShrZXlTdG9yZSk7CisKKyAgICAgICAgICAgIC8vIHRlc3Qgb2RkIGlucHV0cworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKCIiLCBFbnRyeS5jbGFzcykpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKCIiLCBQcml2YXRlS2V5RW50cnkuY2xhc3MpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZigiIiwgU2VjcmV0S2V5RW50cnkuY2xhc3MpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZigiIiwgVHJ1c3RlZENlcnRpZmljYXRlRW50cnkuY2xhc3MpKTsKKworICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoa2V5U3RvcmUpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKEFMSUFTX1BSSVZBVEUsIFByaXZhdGVLZXlFbnRyeS5jbGFzcykpOworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZihBTElBU19QUklWQVRFLCBTZWNyZXRLZXlFbnRyeS5jbGFzcykpOworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZihBTElBU19QUklWQVRFLCBUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeS5jbGFzcykpOworCisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKEFMSUFTX1NFQ1JFVCwgU2VjcmV0S2V5RW50cnkuY2xhc3MpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShrZXlTdG9yZS5lbnRyeUluc3RhbmNlT2YoQUxJQVNfU0VDUkVULCBQcml2YXRlS2V5RW50cnkuY2xhc3MpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShrZXlTdG9yZS5lbnRyeUluc3RhbmNlT2YoQUxJQVNfU0VDUkVULCBUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeS5jbGFzcykpOworCisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKEFMSUFTX0NFUlRJRklDQVRFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeS5jbGFzcykpOworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZihBTElBU19DRVJUSUZJQ0FURSwgUHJpdmF0ZUtleUVudHJ5LmNsYXNzKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKEFMSUFTX0NFUlRJRklDQVRFLCBTZWNyZXRLZXlFbnRyeS5jbGFzcykpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB0ZXN0IGNhc2Ugc2Vuc2l0aXZlCisgICAgICAgICAgICBhc3NlcnRUcnVlKGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZihBTElBU19QUklWQVRFLCBQcml2YXRlS2V5RW50cnkuY2xhc3MpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZihBTElBU19QUklWQVRFLCBTZWNyZXRLZXlFbnRyeS5jbGFzcykpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKEFMSUFTX1BSSVZBVEUsIFRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5LmNsYXNzKSk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpc1NlY3JldEtleUVuYWJsZWQoa2V5U3RvcmUpLAorICAgICAgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZihBTElBU19TRUNSRVQsIFNlY3JldEtleUVudHJ5LmNsYXNzKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShrZXlTdG9yZS5lbnRyeUluc3RhbmNlT2YoQUxJQVNfU0VDUkVULCBQcml2YXRlS2V5RW50cnkuY2xhc3MpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZihBTElBU19TRUNSRVQsIFRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5LmNsYXNzKSk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpc0NlcnRpZmljYXRlRW5hYmxlZChrZXlTdG9yZSksCisgICAgICAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKEFMSUFTX0NFUlRJRklDQVRFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeS5jbGFzcykpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKEFMSUFTX0NFUlRJRklDQVRFLCBQcml2YXRlS2V5RW50cnkuY2xhc3MpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZihBTElBU19DRVJUSUZJQ0FURSwgU2VjcmV0S2V5RW50cnkuY2xhc3MpKTsKKworICAgICAgICAgICAgLy8gdGVzdCBjYXNlIGluc2Vuc2l0aXZlCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIWlzQ2FzZVNlbnNpdGl2ZShrZXlTdG9yZSksCisgICAgICAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIFByaXZhdGVLZXlFbnRyeS5jbGFzcykpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKEFMSUFTX0FMVF9DQVNFX1BSSVZBVEUsIFNlY3JldEtleUVudHJ5LmNsYXNzKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShrZXlTdG9yZS5lbnRyeUluc3RhbmNlT2YoQUxJQVNfQUxUX0NBU0VfUFJJVkFURSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeS5jbGFzcykpOworCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIWlzQ2FzZVNlbnNpdGl2ZShrZXlTdG9yZSkgJiYgaXNTZWNyZXRLZXlFbmFibGVkKGtleVN0b3JlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5lbnRyeUluc3RhbmNlT2YoQUxJQVNfQUxUX0NBU0VfU0VDUkVULCBTZWNyZXRLZXlFbnRyeS5jbGFzcykpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKEFMSUFTX0FMVF9DQVNFX1NFQ1JFVCwgUHJpdmF0ZUtleUVudHJ5LmNsYXNzKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShrZXlTdG9yZS5lbnRyeUluc3RhbmNlT2YoQUxJQVNfQUxUX0NBU0VfU0VDUkVULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5LmNsYXNzKSk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyghaXNDYXNlU2Vuc2l0aXZlKGtleVN0b3JlKSAmJiBpc0NlcnRpZmljYXRlRW5hYmxlZChrZXlTdG9yZSksCisgICAgICAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKEFMSUFTX0FMVF9DQVNFX0NFUlRJRklDQVRFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeS5jbGFzcykpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKEFMSUFTX0FMVF9DQVNFX0NFUlRJRklDQVRFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByaXZhdGVLZXlFbnRyeS5jbGFzcykpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKEFMSUFTX0FMVF9DQVNFX0NFUlRJRklDQVRFLCBTZWNyZXRLZXlFbnRyeS5jbGFzcykpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9LZXlTdG9yZV9CdWlsZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQnVpbGRlci5uZXdJbnN0YW5jZShrZXlTdG9yZSwgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoS2V5U3RvcmUga2V5U3RvcmUgOiBrZXlTdG9yZXMoKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBCdWlsZGVyLm5ld0luc3RhbmNlKGtleVN0b3JlLmdldFR5cGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleVN0b3JlLmdldFByb3ZpZGVyKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEJ1aWxkZXIubmV3SW5zdGFuY2UobnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQnVpbGRlci5uZXdJbnN0YW5jZShrZXlTdG9yZS5nZXRUeXBlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5nZXRQcm92aWRlcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIGtleVN0b3JlLmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBCdWlsZGVyLm5ld0luc3RhbmNlKGtleVN0b3JlLCBQQVJBTV9TVE9SRSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGJ1aWxkZXIuZ2V0UHJvdGVjdGlvblBhcmFtZXRlcihudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGtleVN0b3JlLCBidWlsZGVyLmdldEtleVN0b3JlKCkpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBidWlsZGVyLmdldFByb3RlY3Rpb25QYXJhbWV0ZXIobnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhQQVJBTV9TVE9SRSwgYnVpbGRlci5nZXRQcm90ZWN0aW9uUGFyYW1ldGVyKCIiKSk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEtleVN0b3JlIGtleVN0b3JlIDoga2V5U3RvcmVzKCkpIHsKKyAgICAgICAgICAgIHBvcHVsYXRlKGtleVN0b3JlKTsKKworICAgICAgICAgICAgRmlsZSBmaWxlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgia2V5c3RvcmUiLCBrZXlTdG9yZS5nZXRQcm92aWRlcigpLmdldE5hbWUoKSk7CisgICAgICAgICAgICBPdXRwdXRTdHJlYW0gb3MgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBvcyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZpbGUpOworICAgICAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KGtleVN0b3JlKSkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuc3RvcmUob3MsIFBBU1NXT1JEX1NUT1JFKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBrZXlTdG9yZS5zdG9yZShvcywgUEFTU1dPUkRfU1RPUkUpOworICAgICAgICAgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gQnVpbGRlci5uZXdJbnN0YW5jZShrZXlTdG9yZS5nZXRUeXBlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5nZXRQcm92aWRlcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBUkFNX1NUT1JFKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoa2V5U3RvcmUuZ2V0VHlwZSgpLCBidWlsZGVyLmdldEtleVN0b3JlKCkuZ2V0VHlwZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoa2V5U3RvcmUuZ2V0UHJvdmlkZXIoKSwgYnVpbGRlci5nZXRLZXlTdG9yZSgpLmdldFByb3ZpZGVyKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhQQVJBTV9TVE9SRSwgYnVpbGRlci5nZXRQcm90ZWN0aW9uUGFyYW1ldGVyKCIiKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzS2V5U3RvcmVzKGZpbGUsIFBBU1NXT1JEX1NUT1JFLCBrZXlTdG9yZSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIElvVXRpbHMuY2xvc2VRdWlldGx5KG9zKTsKKyAgICAgICAgICAgICAgICBmaWxlLmRlbGV0ZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChLZXlTdG9yZSBrZXlTdG9yZSA6IGtleVN0b3JlcygpKSB7CisgICAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBCdWlsZGVyLm5ld0luc3RhbmNlKGtleVN0b3JlLmdldFR5cGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5U3RvcmUuZ2V0UHJvdmlkZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFSQU1fU1RPUkUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGtleVN0b3JlLmdldFR5cGUoKSwgYnVpbGRlci5nZXRLZXlTdG9yZSgpLmdldFR5cGUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoa2V5U3RvcmUuZ2V0UHJvdmlkZXIoKSwgYnVpbGRlci5nZXRLZXlTdG9yZSgpLmdldFByb3ZpZGVyKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFBBUkFNX1NUT1JFLCBidWlsZGVyLmdldFByb3RlY3Rpb25QYXJhbWV0ZXIoIiIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfS2V5U3RvcmVfY2FjZXJ0cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpZiAoU3RhbmRhcmROYW1lcy5JU19SSSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIEtleVN0b3JlIGtzID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoIkFuZHJvaWRDQVN0b3JlIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQW5kcm9pZENBU3RvcmUiLCBrcy5nZXRUeXBlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkhhcm1vbnlKU1NFIiwga3MuZ2V0UHJvdmlkZXIoKS5nZXROYW1lKCkpOworCisgICAgICAgIGtzLmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgIGZvciAoU3RyaW5nIGFsaWFzIDogQ29sbGVjdGlvbnMubGlzdChrcy5hbGlhc2VzKCkpKSB7CisgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBjID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYyA9IGtzLmdldENlcnRpZmljYXRlKGFsaWFzKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGMpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoa3MuaXNDZXJ0aWZpY2F0ZUVudHJ5KGFsaWFzKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShrcy5lbnRyeUluc3RhbmNlT2YoYWxpYXMsIFRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5LmNsYXNzKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFsaWFzLCBrcy5nZXRDZXJ0aWZpY2F0ZUFsaWFzKGMpKTsKKworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoYyBpbnN0YW5jZW9mIFg1MDlDZXJ0aWZpY2F0ZSk7CisgICAgICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlIGNlcnQgPSAoWDUwOUNlcnRpZmljYXRlKSBjOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhjZXJ0LmdldFN1YmplY3RVbmlxdWVJRCgpLCBjZXJ0LmdldElzc3VlclVuaXF1ZUlEKCkpOworICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoY2VydC5nZXRQdWJsaWNLZXkoKSk7CisKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGtzLmNvbnRhaW5zQWxpYXMoYWxpYXMpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGtzLmdldENyZWF0aW9uRGF0ZShhbGlhcykpOworICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoa3MuZ2V0RW50cnkoYWxpYXMsIG51bGwpKTsKKworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKGtzLmlzS2V5RW50cnkoYWxpYXMpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtzLmdldEtleShhbGlhcywgbnVsbCkpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa3MuZ2V0Q2VydGlmaWNhdGVDaGFpbihhbGlhcykpOworCisgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oImFsaWFzPSIgKyBhbGlhcyArICIgY2VydD0iICsgYywgdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L01lc3NhZ2VEaWdlc3RUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L01lc3NhZ2VEaWdlc3RUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2Q3YjhkYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdFRlc3QuamF2YQpAQCAtMCwwICsxLDIzMyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBNZXNzYWdlRGlnZXN0VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIHNoYV80NTYgPSB7CisgICAgICAgICAgICAtMjQsICAgOSwgLTU5LCAtNDcsICAtNTAsICAtOTIsIDEyMywgNjksIC0yOSwgIDcxLAorICAgICAgICAgICAgICAxLCAtNDYsICA2MywgIDk2LCAtMTE4LCAtMTAyLCAgODgsICAzLCAgNzcsIC01NQorICAgIH07CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2hhUmVzZXQoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgTWVzc2FnZURpZ2VzdCBzaGEgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJTSEEiKTsKKyAgICAgICAgc2hhLnVwZGF0ZShuZXcgYnl0ZVtdIHsgMSwgMiwgMyB9KTsKKyAgICAgICAgc2hhLnJlc2V0KCk7CisgICAgICAgIHNoYS51cGRhdGUobmV3IGJ5dGVbXSB7IDQsIDUsIDYgfSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMudG9TdHJpbmcoc2hhXzQ1NiksIEFycmF5cy50b1N0cmluZyhzaGEuZGlnZXN0KCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFByb3ZpZGVyW10gcHJvdmlkZXJzID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKCk7CisgICAgICAgIGZvciAoUHJvdmlkZXIgcHJvdmlkZXIgOiBwcm92aWRlcnMpIHsKKyAgICAgICAgICAgIFNldDxQcm92aWRlci5TZXJ2aWNlPiBzZXJ2aWNlcyA9IHByb3ZpZGVyLmdldFNlcnZpY2VzKCk7CisgICAgICAgICAgICBmb3IgKFByb3ZpZGVyLlNlcnZpY2Ugc2VydmljZSA6IHNlcnZpY2VzKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHR5cGUgPSBzZXJ2aWNlLmdldFR5cGUoKTsKKyAgICAgICAgICAgICAgICBpZiAoIXR5cGUuZXF1YWxzKCJNZXNzYWdlRGlnZXN0IikpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIFN0cmluZyBhbGdvcml0aG0gPSBzZXJ2aWNlLmdldEFsZ29yaXRobSgpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIC8vIE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoU3RyaW5nKQorICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kMSA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFsZ29yaXRobSwgbWQxLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgICAgICAgICAgICAgdGVzdF9NZXNzYWdlRGlnZXN0KG1kMSk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShTdHJpbmcsIFByb3ZpZGVyKQorICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kMiA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBwcm92aWRlcik7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhhbGdvcml0aG0sIG1kMi5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhwcm92aWRlciwgbWQyLmdldFByb3ZpZGVyKCkpOworICAgICAgICAgICAgICAgICAgICB0ZXN0X01lc3NhZ2VEaWdlc3QobWQyKTsKKworICAgICAgICAgICAgICAgICAgICAvLyBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKFN0cmluZywgU3RyaW5nKQorICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kMyA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLCBwcm92aWRlci5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYWxnb3JpdGhtLCBtZDMuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMocHJvdmlkZXIsIG1kMy5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgICAgICAgICAgICAgdGVzdF9NZXNzYWdlRGlnZXN0KG1kMyk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiUHJvYmxlbSB0ZXN0aW5nIE1lc3NhZ2VEaWdlc3QuIiArIGFsZ29yaXRobSwgZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPFN0cmluZywgTWFwPFN0cmluZywgYnl0ZVtdPj4gRVhQRUNUQVRJT05TCisgICAgICAgICAgICA9IG5ldyBIYXNoTWFwPFN0cmluZywgTWFwPFN0cmluZywgYnl0ZVtdPj4oKTsKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHB1dEV4cGVjdGF0aW9uKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBpbnB1dE5hbWUsIGJ5dGVbXSBleHBlY3RlZCkgeworICAgICAgICBhbGdvcml0aG0gPSBhbGdvcml0aG0udG9VcHBlckNhc2UoKTsKKyAgICAgICAgTWFwPFN0cmluZywgYnl0ZVtdPiBleHBlY3RhdGlvbnMgPSBFWFBFQ1RBVElPTlMuZ2V0KGFsZ29yaXRobSk7CisgICAgICAgIGlmIChleHBlY3RhdGlvbnMgPT0gbnVsbCkgeworICAgICAgICAgICAgZXhwZWN0YXRpb25zID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBieXRlW10+KCk7CisgICAgICAgICAgICBFWFBFQ1RBVElPTlMucHV0KGFsZ29yaXRobSwgZXhwZWN0YXRpb25zKTsKKyAgICAgICAgfQorICAgICAgICBleHBlY3RhdGlvbnMucHV0KGlucHV0TmFtZSwgZXhwZWN0ZWQpOworICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBNYXA8U3RyaW5nLCBieXRlW10+IGdldEV4cGVjdGF0aW9ucyhTdHJpbmcgYWxnb3JpdGhtKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYWxnb3JpdGhtID0gYWxnb3JpdGhtLnRvVXBwZXJDYXNlKCk7CisgICAgICAgIE1hcDxTdHJpbmcsIGJ5dGVbXT4gZXhwZWN0YXRpb25zID0gRVhQRUNUQVRJT05TLmdldChhbGdvcml0aG0pOworICAgICAgICBpZiAoZXhwZWN0YXRpb25zID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIk5vIGV4cGVjdGF0aW9ucyBmb3IgTWVzc2FnZURpZ2VzdC4iICsgYWxnb3JpdGhtKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZXhwZWN0YXRpb25zOworICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5QVVRfRU1QVFkgPSAiZW1wdHkiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBJTlBVVF8yNTZNQiA9ICIyNTZtYiI7CisgICAgc3RhdGljIHsKKyAgICAgICAgLy8gSU5QVVRfRU1QVFkKKyAgICAgICAgcHV0RXhwZWN0YXRpb24oIk1EMiIsCisgICAgICAgICAgICAgICAgICAgICAgIElOUFVUX0VNUFRZLAorICAgICAgICAgICAgICAgICAgICAgICBuZXcgYnl0ZVtdIHsgLTEyNSwgODAsIC0yNywgLTkzLCAtMzAsIDc2LCAyMSwgNjEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtMTQsIDM5LCA5MiwgLTk3LCAtMTI4LCAxMDUsIDM5LCAxMTUgfSk7CisgICAgICAgIHB1dEV4cGVjdGF0aW9uKCJNRDUiLAorICAgICAgICAgICAgICAgICAgICAgICBJTlBVVF9FTVBUWSwKKyAgICAgICAgICAgICAgICAgICAgICAgbmV3IGJ5dGVbXSB7IC00NCwgMjksIC0xMTYsIC0zOSwgLTExMywgMCwgLTc4LCA0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLTIzLCAtMTI4LCA5LCAtMTA0LCAtMjAsIC04LCA2NiwgMTI2IH0pOworICAgICAgICBwdXRFeHBlY3RhdGlvbigiU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgSU5QVVRfRU1QVFksCisgICAgICAgICAgICAgICAgICAgICAgIG5ldyBieXRlW10geyAtMzgsIDU3LCAtOTMsIC0xOCwgOTQsIDEwNywgNzUsIDEzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNTAsIDg1LCAtNjUsIC0xNywgLTEwNywgOTYsIDI0LCAtMTEyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLTgxLCAtNDAsIDcsIDl9KTsKKyAgICAgICAgcHV0RXhwZWN0YXRpb24oIlNIQS0xIiwKKyAgICAgICAgICAgICAgICAgICAgICAgSU5QVVRfRU1QVFksCisgICAgICAgICAgICAgICAgICAgICAgIG5ldyBieXRlW10geyAtMzgsIDU3LCAtOTMsIC0xOCwgOTQsIDEwNywgNzUsIDEzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNTAsIDg1LCAtNjUsIC0xNywgLTEwNywgOTYsIDI0LCAtMTEyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLTgxLCAtNDAsIDcsIDl9KTsKKyAgICAgICAgcHV0RXhwZWN0YXRpb24oIlNIQS0yNTYiLAorICAgICAgICAgICAgICAgICAgICAgICBJTlBVVF9FTVBUWSwKKyAgICAgICAgICAgICAgICAgICAgICAgbmV3IGJ5dGVbXSB7IC0yOSwgLTgwLCAtNjAsIDY2LCAtMTA0LCAtNCwgMjgsIDIwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLTEwMiwgLTUsIC0xMiwgLTU2LCAtMTAzLCAxMTEsIC03MSwgMzYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAzOSwgLTgyLCA2NSwgLTI4LCAxMDAsIC0xMDEsIC0xMDksIDc2LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLTkyLCAtMTA3LCAtMTAzLCAyNywgMTIwLCA4MiwgLTcyLCA4NSB9KTsKKyAgICAgICAgcHV0RXhwZWN0YXRpb24oIlNIQS0zODQiLAorICAgICAgICAgICAgICAgICAgICAgICBJTlBVVF9FTVBUWSwKKyAgICAgICAgICAgICAgICAgICAgICAgbmV3IGJ5dGVbXSB7IDU2LCAtODAsIDk2LCAtODksIDgxLCAtODQsIC0xMDYsIDU2LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNzYsIC0zOSwgNTAsIDEyNiwgLTc5LCAtNzksIC0yOSwgMTA2LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMzMsIC0zLCAtNzMsIDE3LCAyMCwgLTY2LCA3LCA2NywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDc2LCAxMiwgLTU3LCAtNjUsIDk5LCAtMTAsIC0zMSwgLTM4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMzksIDc4LCAtMzQsIC02NSwgLTI1LCAxMTEsIDEwMSwgLTUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtNDMsIDI2LCAtNDYsIC0xNSwgNzIsIC0xMDQsIC03MSwgOTEgfSk7CisgICAgICAgIHB1dEV4cGVjdGF0aW9uKCJTSEEtNTEyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgSU5QVVRfRU1QVFksCisgICAgICAgICAgICAgICAgICAgICAgIG5ldyBieXRlW10geyAtNDksIC0xMjUsIC0zMSwgNTMsIDEyNiwgLTE3LCAtNzIsIC02NywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0xNSwgODQsIDQwLCA4MCwgLTQyLCAxMDksIC0xMjgsIDcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtNDIsIDMyLCAtMjgsIDUsIDExLCA4NywgMjEsIC0zNiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0xMjUsIC0xMiwgLTg3LCAzMywgLTQ1LCAxMDgsIC0yMywgLTUwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNzEsIC00OCwgLTQ3LCA2MCwgOTMsIC0xMjMsIC0xNCwgLTgwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLTEsIC0xMjUsIDI0LCAtNDYsIC0xMjEsIDEyNiwgLTIwLCA0NywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDk5LCAtNzEsIDQ5LCAtNjcsIDcxLCA2NSwgMTIyLCAtMTI3LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLTkxLCA1NiwgNTAsIDEyMiwgLTcsIDM5LCAtMzgsIDYyIH0pOworCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBpbnB1dCBmb3IgcHJvYmxlbSBTSEEtMSB3aXRoIGlucHV0IG9mCisgICAgICAgIC8vIDI1Nk1Ccy4gIEhvd2V2ZXIsIGl0cyBjdXJyZW50bHkgdG9vIHNsb3cgdG8gYmUgcHJhY3RpY2FsIG9uCisgICAgICAgIC8vIGRldmljZXMsIHNvIGl0cyBkaXNhYmxlZCBpbiB0aGF0IGNhc2UuIGh0dHA6Ly9iLzQ1MDE2MjAKKyAgICAgICAgYm9vbGVhbiBlbmFibGVkMjU2bWIgPSAoU3lzdGVtLmdldFByb3BlcnR5KCJvcy5hcmNoIikuY29udGFpbnMoIng4NiIpIC8vIGhvc3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgU3lzdGVtLmdldFByb3BlcnR5KCJvcy5hcmNoIikuY29udGFpbnMoImFtZDY0IikpOyAvLyBSSQorICAgICAgICBpZiAoZW5hYmxlZDI1Nm1iKSB7CisgICAgICAgICAgICAvLyBJTlBVVF8yNTZNQgorICAgICAgICAgICAgcHV0RXhwZWN0YXRpb24oIk1EMiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlBVVF8yNTZNQiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBieXRlW10geyAtNjMsIC0xMjAsIDYsIDY3LCAxMiwgLTg3LCAtMzksIC0xMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtNjcsIC0zLCAtMzEsIC00MSwgLTkxLCAxNiwgLTM1LCA5MSB9KTsKKyAgICAgICAgICAgIHB1dEV4cGVjdGF0aW9uKCJNRDUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5QVVRfMjU2TUIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgYnl0ZVtdIHsgMzEsIDgwLCA1NywgLTI3LCAxMSwgLTQyLCAxMDcsIDQxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEyLCA4NiwgMTA0LCA3NywgLTEyMywgODAsIC01OCwgLTYyIH0pOworICAgICAgICAgICAgcHV0RXhwZWN0YXRpb24oIlNIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlBVVF8yNTZNQiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBieXRlW10geyAxMjMsIC0xMTEsIC0zNywgLTM2LCA4NiwgLTU5LCAxMjAsIDMwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0zMywgMTA4LCAtMTIwLCA3MSwgLTc2LCAtODYsIDEwNSwgMTAxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDg2LCAxMDgsIDkyLCAxMTcgfSk7CisgICAgICAgICAgICBwdXRFeHBlY3RhdGlvbigiU0hBLTEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5QVVRfMjU2TUIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgYnl0ZVtdIHsgMTIzLCAtMTExLCAtMzcsIC0zNiwgODYsIC01OSwgMTIwLCAzMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtMzMsIDEwOCwgLTEyMCwgNzEsIC03NiwgLTg2LCAxMDUsIDEwMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA4NiwgMTA4LCA5MiwgMTE3IH0pOworICAgICAgICAgICAgcHV0RXhwZWN0YXRpb24oIlNIQS0yNTYiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5QVVRfMjU2TUIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgYnl0ZVtdIHsgLTkwLCAtNDEsIDQyLCAtNTcsIDEwNSwgMTUsIDgzLCAtNjYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTA2LCAtMjgsIDEwNywgLTg4LCAtMTIzLCA2LCAtNjcsIC0xMDUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNDgsIDQyLCA5LCA2MywgMTEzLCA4LCA3MSwgNDMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLTM5LCAtMTcsIC02MSwgLTUwLCAtMywgLTk2LCAxMDAsIC0xMjQgfSk7CisgICAgICAgICAgICBwdXRFeHBlY3RhdGlvbigiU0hBLTM4NCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlBVVF8yNTZNQiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBieXRlW10geyA3MSwgNzIsIDc3LCAtODMsIC0xMTAsIDIyLCAtMTE4LCAtMTgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLTU4LCAxMTksIDExNSwgNzQsIC02NywgLTM2LCA4NCwgMTIyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0xMDUsIC02NywgLTc1LCAxNSwgLTMzLCAzNywgNzgsIC05NSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0LCAxMTgsIC01MywgMTA2LCA2NSwgLTExNSwgLTE5LCAxMjEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLTU5LCAtOTQsIC00NSwgLTExMSwgLTEyNCwgMzUsIDM1LCA2MCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA2NywgLTM0LCA2MiwgMTA2LCAtMTYsIDEyMiwgLTExMCwgLTE0IH0pOworICAgICAgICAgICAgcHV0RXhwZWN0YXRpb24oIlNIQS01MTIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5QVVRfMjU2TUIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgYnl0ZVtdIHsgMzYsIDcsIC0xMjAsIDM5LCAtODcsIC04NywgODQsIC00MCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtNjYsIDExNCwgNjIsIC03MywgMTA3LCAxMDEsIC0xMTcsIC0xMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtMTI0LCAyMCwgMTA5LCAxMDMsIC05MiwgMTI1LCAxMTEsIDEwMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMiwgMTE0LCAtNjgsIDEwMCwgMzAsIDI1LCAtODgsIDYyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEwOCwgNTYsIDksIC0xMDcsIDg5LCAtMjUsIC01MCwgMTE4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC04NywgMTAwLCAxMywgMzcsIC0xNCwgNjYsIC00MCwgLTk3LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEwNSwgLTI3LCA3OSwgLTYyLCA1MywgLTMxLCA4MywgNDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNCwgNTcsIDkwLCAtODEsIDYzLCAtNzcsIC00MiwgMTEzIH0pOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RfTWVzc2FnZURpZ2VzdChNZXNzYWdlRGlnZXN0IG1kKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGFsZ29yaXRobSA9IG1kLmdldEFsZ29yaXRobSgpOworICAgICAgICBmb3IgKE1hcC5FbnRyeTxTdHJpbmcsIGJ5dGVbXT4gZXhwZWN0YXRpb24gOiBnZXRFeHBlY3RhdGlvbnMoYWxnb3JpdGhtKS5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICBTdHJpbmcgaW5wdXROYW1lID0gZXhwZWN0YXRpb24uZ2V0S2V5KCk7CisgICAgICAgICAgICBieXRlW10gZXhwZWN0ZWQgPSBleHBlY3RhdGlvbi5nZXRWYWx1ZSgpOworICAgICAgICAgICAgYnl0ZVtdIGFjdHVhbDsKKyAgICAgICAgICAgIGlmIChpbnB1dE5hbWUuZXF1YWxzKElOUFVUX0VNUFRZKSkgeworICAgICAgICAgICAgICAgIGFjdHVhbCA9IG1kLmRpZ2VzdCgpOworICAgICAgICAgICAgfSBlbHNlIGlmIChpbnB1dE5hbWUuZXF1YWxzKElOUFVUXzI1Nk1CKSkgeworICAgICAgICAgICAgICAgIGJ5dGVbXSBtYiA9IG5ldyBieXRlWzEgKiAxMDI0ICogMTAyNF07CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyNTY7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBtZC51cGRhdGUobWIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhY3R1YWwgPSBtZC5kaWdlc3QoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGlucHV0TmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnREaWdlc3QoYWxnb3JpdGhtLCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhhbGdvcml0aG0sIGV4cGVjdGVkLmxlbmd0aCwgbWQuZ2V0RGlnZXN0TGVuZ3RoKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydERpZ2VzdChTdHJpbmcgYWxnb3JpdGhtLCBieXRlW10gYWN0dWFsLCBieXRlW10gZXhwZWN0ZWQpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGFsZ29yaXRobSwgamF2YUJ5dGVzKGFjdHVhbCksIGphdmFCeXRlcyhleHBlY3RlZCkpOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGphdmFCeXRlcyhieXRlW10gYnl0ZXMpIHsKKyAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgYnVmLmFwcGVuZCgibmV3IGJ5dGVbXSB7ICIpOworICAgICAgICBmb3IgKGJ5dGUgYiA6IGJ5dGVzKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKGIpOworICAgICAgICAgICAgYnVmLmFwcGVuZCgiLCAiKTsKKyAgICAgICAgfQorICAgICAgICBidWYuYXBwZW5kKCIgfSIpOworICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L09sZEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvT2xkQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk2OGJkNTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L09sZEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclRlc3QuamF2YQpAQCAtMCwwICsxLDYwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKKworcHVibGljIGNsYXNzIE9sZEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF9pbml0SSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZAorICAgICAgICAvLyBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvci5pbml0KGludCkKKyAgICAgICAgICAgIC8vIGNoZWNrcyB0aGF0IG5vIGV4Y2VwdGlvbiBpcyB0aHJvd24KKyAgICAgICAgaW50W10gdmFsaWQgPSB7NTEyLCA1NzYsIDY0MCwgOTYwLCAxMDI0fTsKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yIGdlbiA9IEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcgorICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZSgiRFNBIik7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBnZW4uaW5pdCh2YWxpZFtpXSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBzaG91bGQgbm90IGJlIHRocm93biBmb3IgdmFsaWQgcGFyYW1ldGVyIiArIHZhbGlkW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5pdElMamF2YV9zZWN1cml0eV9TZWN1cmVSYW5kb20oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQKKyAgICAgICAgLy8gamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IuaW5pdChpbnQsCisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tKQorICAgICAgICAgICAgLy8gY2hlY2tzIHRoYXQgbm8gZXhjZXB0aW9uIGlzIHRocm93bgorICAgICAgICBpbnRbXSB2YWxpZCA9IHs1MTIsIDU3NiwgNjQwLCA5NjAsIDEwMjR9OworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IgZ2VuID0gQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yCisgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKCJEU0EiKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGdlbi5pbml0KHZhbGlkW2ldLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAgICAgIGdlbi5pbml0KHZhbGlkW2ldLCBudWxsKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIHNob3VsZCBub3QgYmUgdGhyb3duIGZvciB2YWxpZCBwYXJhbWV0ZXIiICsgdmFsaWRbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zZWN1cml0eS9PbGRESFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvT2xkREhUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDIxZDE1MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvT2xkREhUZXN0LmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uQnJva2VuVGVzdDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5ESFBhcmFtZXRlclNwZWM7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkREhUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgQEJyb2tlblRlc3QoIlN1ZmZlcnMgZnJvbSBESCBzbG93bmVzcywgZGlzYWJsaW5nIGZvciBub3ciKQorICAgIHB1YmxpYyB2b2lkIHRlc3RESEdlbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGdlbiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBnZW4gPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKCJESCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IgYWxnb3JpdGhtcGFyYW1ldGVyZ2VuZXJhdG9yID0gQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yLmdldEluc3RhbmNlKCJESCIpOworICAgICAgICBhbGdvcml0aG1wYXJhbWV0ZXJnZW5lcmF0b3IuaW5pdCgxMDI0LCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIGFsZ29yaXRobXBhcmFtZXRlcnMgPSBhbGdvcml0aG1wYXJhbWV0ZXJnZW5lcmF0b3IuZ2VuZXJhdGVQYXJhbWV0ZXJzKCk7CisgICAgICAgIERIUGFyYW1ldGVyU3BlYyBkaHBhcmFtZXRlcnNwZWMgPSBhbGdvcml0aG1wYXJhbWV0ZXJzLmdldFBhcmFtZXRlclNwZWMoREhQYXJhbWV0ZXJTcGVjLmNsYXNzKTsKKworCisgICAgICAgIC8vZ2VuLmluaXRpYWxpemUoMTAyNCk7CisgICAgICAgIGdlbi5pbml0aWFsaXplKGRocGFyYW1ldGVyc3BlYyk7CisgICAgICAgIEtleVBhaXIga2V5ID0gZ2VuLmdlbmVyYXRlS2V5UGFpcigpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvT2xkS2V5UGFpckdlbmVyYXRvclRlc3RESC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zZWN1cml0eS9PbGRLZXlQYWlyR2VuZXJhdG9yVGVzdERILmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjM5NzA1YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvT2xkS2V5UGFpckdlbmVyYXRvclRlc3RESC5qYXZhCkBAIC0wLDAgKzEsNDEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLkJyb2tlblRlc3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgdGVzdHMuc2VjdXJpdHkuS2V5QWdyZWVtZW50SGVscGVyOworCitwdWJsaWMgY2xhc3MgT2xkS2V5UGFpckdlbmVyYXRvclRlc3RESCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIEBCcm9rZW5UZXN0KCJUYWtlcyBhZ2VzIGR1ZSB0byBESCBjb21wdXRhdGlvbnMuIERpc2FibGluZyBmb3Igbm93LiIpCisgICAgcHVibGljIHZvaWQgdGVzdEtleVBhaXJHZW5lcmF0b3IoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvciBnZW5lcmF0b3IgPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKCJESCIpOworCisgICAgICAgIGdlbmVyYXRvci5pbml0aWFsaXplKDEwMjQpOworCisgICAgICAgIEtleVBhaXIga2V5UGFpciA9IGdlbmVyYXRvci5nZW5lcmF0ZUtleVBhaXIoKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKCJubyBrZXlwYWlyIGdlbmVyYXRlZCIsIGtleVBhaXIpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJubyBwdWJsaWMga2V5IGdlbmVyYXRlZCIsIGtleVBhaXIuZ2V0UHVibGljKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJubyBwcml2YXRlIGtleSBnZW5lcmF0ZWQiLCBrZXlQYWlyLmdldFByaXZhdGUoKSk7CisKKyAgICAgICAgbmV3IEtleUFncmVlbWVudEhlbHBlcigiREgiKS50ZXN0KGtleVBhaXIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvUHJvdmlkZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L1Byb3ZpZGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5NTkwOGIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L1Byb3ZpZGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTk4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwLkVudHJ5OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4Lk1hdGNoZXI7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm47CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgUHJvdmlkZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogTWFrZXMgc3VyZSBhbGwgYWxsIGV4cGVjdGVkIGltcGxlbWVudGF0aW9ucyAoYnV0IG5vdCBhbGlhc2VzKQorICAgICAqIGFuZCB0aGF0IHRoZXJlIGFyZSBubyBleHRyYXMsIGFjY29yZGluZyB0byB3aGF0IHdlIGV4cGVjdCBmcm9tCisgICAgICogU3RhbmRhcmROYW1lcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfUHJvdmlkZXJfZ2V0U2VydmljZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICAvLyBidWlsZCBzZXQgb2YgZXhwZWN0ZWQgYWxnb3JpdGhtcworICAgICAgICBNYXA8U3RyaW5nLFNldDxTdHJpbmc+PiByZW1haW5pbmcKKyAgICAgICAgICAgICAgICA9IG5ldyBIYXNoTWFwPFN0cmluZyxTZXQ8U3RyaW5nPj4oU3RhbmRhcmROYW1lcy5QUk9WSURFUl9BTEdPUklUSE1TKTsKKyAgICAgICAgZm9yIChFbnRyeTxTdHJpbmcsU2V0PFN0cmluZz4+IGVudHJ5IDogcmVtYWluaW5nLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIGVudHJ5LnNldFZhbHVlKG5ldyBIYXNoU2V0PFN0cmluZz4oZW50cnkuZ2V0VmFsdWUoKSkpOworICAgICAgICB9CisKKyAgICAgICAgTGlzdDxTdHJpbmc+IGV4dHJhID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBMaXN0PFN0cmluZz4gbWlzc2luZyA9IG5ldyBBcnJheUxpc3QoKTsKKworICAgICAgICBQcm92aWRlcltdIHByb3ZpZGVycyA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygpOworICAgICAgICBmb3IgKFByb3ZpZGVyIHByb3ZpZGVyIDogcHJvdmlkZXJzKSB7CisgICAgICAgICAgICBTdHJpbmcgcHJvdmlkZXJOYW1lID0gcHJvdmlkZXIuZ2V0TmFtZSgpOworICAgICAgICAgICAgLy8gaWdub3JlIEJvdW5jeUNhc3RsZSBwcm92aWRlciBpZiBpdCBpcyBpbnN0YWxsZWQgb24gdGhlIFJJCisgICAgICAgICAgICBpZiAoU3RhbmRhcmROYW1lcy5JU19SSSAmJiBwcm92aWRlck5hbWUuZXF1YWxzKCJCQyIpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTZXQ8UHJvdmlkZXIuU2VydmljZT4gc2VydmljZXMgPSBwcm92aWRlci5nZXRTZXJ2aWNlcygpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChzZXJ2aWNlcyk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShzZXJ2aWNlcy5pc0VtcHR5KCkpOworCisgICAgICAgICAgICBmb3IgKFByb3ZpZGVyLlNlcnZpY2Ugc2VydmljZSA6IHNlcnZpY2VzKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHR5cGUgPSBzZXJ2aWNlLmdldFR5cGUoKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcgYWxnb3JpdGhtID0gc2VydmljZS5nZXRBbGdvcml0aG0oKS50b1VwcGVyQ2FzZSgpOworICAgICAgICAgICAgICAgIFN0cmluZyBjbGFzc05hbWUgPSBzZXJ2aWNlLmdldENsYXNzTmFtZSgpOworICAgICAgICAgICAgICAgIGlmIChmYWxzZSkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4ocHJvdmlkZXJOYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgIiArIHR5cGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAiICsgYWxnb3JpdGhtCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgIiArIGNsYXNzTmFtZSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIGZyb20gcmVtYWluaW5nLCBhc3NlcnQgdW5rbm93biBpZiBtaXNzaW5nCisgICAgICAgICAgICAgICAgU2V0PFN0cmluZz4gYWxnb3JpdGhtcyA9IHJlbWFpbmluZy5nZXQodHlwZSk7CisgICAgICAgICAgICAgICAgaWYgKGFsZ29yaXRobXMgPT0gbnVsbCB8fCAhYWxnb3JpdGhtcy5yZW1vdmUoYWxnb3JpdGhtKSkgeworICAgICAgICAgICAgICAgICAgICAvLyBzZWVtcyB0byBiZSBtaXNzaW5nLCBidXQgc29tZXRpbWVzIHRoZSBzYW1lCisgICAgICAgICAgICAgICAgICAgIC8vIGFsZ29yaXRobSBpcyBhdmFpbGFibGUgZnJvbSBtdWx0aXBsZSBwcm92aWRlcnMKKyAgICAgICAgICAgICAgICAgICAgLy8gKGUuZy4gS2V5RmFjdG9yeSBSU0EgaXMgYXZhaWxhYmxlIGZyb20KKyAgICAgICAgICAgICAgICAgICAgLy8gU3VuUnNhU2lnbiBhbmQgU3VuSlNTRSksIHNvIGRvdWJsZSBjaGVjayBpbgorICAgICAgICAgICAgICAgICAgICAvLyBvcmlnaW5hbCBzb3VyY2UgYmVmb3JlIGdpdmluZyBlcnJvcgorICAgICAgICAgICAgICAgICAgICBpZiAoIShTdGFuZGFyZE5hbWVzLlBST1ZJREVSX0FMR09SSVRITVMuY29udGFpbnNLZXkodHlwZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBTdGFuZGFyZE5hbWVzLlBST1ZJREVSX0FMR09SSVRITVMuZ2V0KHR5cGUpLmNvbnRhaW5zKGFsZ29yaXRobSkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBleHRyYS5hZGQoIlVua25vd24gIiArIHR5cGUgKyAiICIgKyBhbGdvcml0aG0gKyAiICIgKyBwcm92aWRlck5hbWUgKyAiXG4iKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoYWxnb3JpdGhtcyAhPSBudWxsICYmIGFsZ29yaXRobXMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgICAgIHJlbWFpbmluZy5yZW1vdmUodHlwZSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIGNsYXNzIGV4aXN0cyBhbmQgY2FuIGJlIGluaXRpYWxpemVkCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChDbGFzcy5mb3JOYW1lKGNsYXNzTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm92aWRlci5nZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCkpKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gU3VuIGZvcmdvdCB0aGVpciBvd24gY2xhc3MKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFjbGFzc05hbWUuZXF1YWxzKCJzdW4uc2VjdXJpdHkucGtjczExLlAxMU1BQyIpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBtaXNzaW5nLmFkZChjbGFzc05hbWUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gYXNzZXJ0IHRoYXQgd2UgZG9uJ3QgaGF2ZSBhbnkgZXh0cmEgaW4gdGhlIGltcGxlbWVudGF0aW9uCisgICAgICAgIENvbGxlY3Rpb25zLnNvcnQoZXh0cmEpOyAvLyBzb3J0IHNvIHRoYXQgaXRzIGdyb3VwZWQgYnkgdHlwZQorICAgICAgICBhc3NlcnRFcXVhbHMoIkV4dHJhIGFsZ29yaXRobXMiLCBDb2xsZWN0aW9ucy5FTVBUWV9MSVNULCBleHRyYSk7CisKKyAgICAgICAgLy8gYXNzZXJ0IHRoYXQgd2UgZG9uJ3QgaGF2ZSBhbnkgbWlzc2luZyBpbiB0aGUgaW1wbGVtZW50YXRpb24KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJNaXNzaW5nIGFsZ29yaXRobXMiLCBDb2xsZWN0aW9ucy5FTVBUWV9NQVAsIHJlbWFpbmluZyk7CisKKyAgICAgICAgLy8gYXNzZXJ0IHRoYXQgd2UgZG9uJ3QgaGF2ZSBhbnkgbWlzc2luZyBjbGFzc2VzCisgICAgICAgIENvbGxlY3Rpb25zLnNvcnQobWlzc2luZyk7IC8vIHNvcnQgaXQgZm9yIHJlYWRhYmlsaXR5CisgICAgICAgIGFzc2VydEVxdWFscygiTWlzc2luZyBjbGFzc2VzIiwgQ29sbGVjdGlvbnMuRU1QVFlfTElTVCwgbWlzc2luZyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUGF0dGVybiBhbGlhcyA9IFBhdHRlcm4uY29tcGlsZSgiQWxnXFwuQWxpYXNcXC4oW14uXSopXFwuKC4qKSIpOworCisgICAgLyoqCisgICAgICogTWFrZXMgc3VyZSBhbGwgcHJvdmlkZXIgcHJvcGVydGllcyBlaXRoZXIgcG9pbnQgdG8gYSBjbGFzcworICAgICAqIGltcGxlbWVudGF0aW9uIHRoYXQgZXhpc3RzIG9yIGFyZSBhbGlhc2VzIHRvIGtub3duIGFsZ29yaXRobXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Qcm92aWRlcl9Qcm9wZXJ0aWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8qCisgICAgICAgICAqIEEgdXNlZnVsIHJlZmVyZW5jZSBvbiBQcm92aWRlciBwcm9wZXJ0aWVzCisgICAgICAgICAqIDxhIGhyZWY9Imh0dHA6Ly9qYXZhLnN1bi5jb20vamF2YXNlLzYvZG9jcy90ZWNobm90ZXMvZ3VpZGVzL3NlY3VyaXR5L2NyeXB0by9Ib3dUb0ltcGxBUHJvdmlkZXIuaHRtbD4KKyAgICAgICAgICogSG93IHRvIEltcGxlbWVudCBhIFByb3ZpZGVyIGluIHRoZSBKYXZhICZ0cmFkZTsgQ3J5cHRvZ3JhcGh5IEFyY2hpdGVjdHVyZQorICAgICAgICAgKiA8L2E+CisgICAgICAgICAqLworCisgICAgICAgIFByb3ZpZGVyW10gcHJvdmlkZXJzID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKCk7CisgICAgICAgIGZvciAoUHJvdmlkZXIgcHJvdmlkZXIgOiBwcm92aWRlcnMpIHsKKyAgICAgICAgICAgIC8vIGNoZWNrIFByb3ZpZGVyLmlkIHByb3ByaWV0aWVzCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMocHJvdmlkZXIuZ2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyLmdldCgiUHJvdmlkZXIuaWQgbmFtZSIpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhTdHJpbmcudmFsdWVPZihwcm92aWRlci5nZXRWZXJzaW9uKCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyLmdldCgiUHJvdmlkZXIuaWQgdmVyc2lvbiIpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhwcm92aWRlci5nZXRJbmZvKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXIuZ2V0KCJQcm92aWRlci5pZCBpbmZvIikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHByb3ZpZGVyLmdldENsYXNzKCkuZ2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyLmdldCgiUHJvdmlkZXIuaWQgY2xhc3NOYW1lIikpOworCisgICAgICAgICAgICAvLyBidWlsZCBtYXAgb2YgYWxsIGtub3duIGFsaWFzZXMgYW5kIGltcGxlbWVudGF0aW9ucworICAgICAgICAgICAgTWFwPFN0cmluZyxTdHJpbmc+IGFsaWFzZXMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsU3RyaW5nPigpOworICAgICAgICAgICAgTWFwPFN0cmluZyxTdHJpbmc+IGltcGxlbWVudGF0aW9ucyA9IG5ldyBIYXNoTWFwPFN0cmluZyxTdHJpbmc+KCk7CisgICAgICAgICAgICBmb3IgKEVudHJ5PE9iamVjdCxPYmplY3Q+IGVudHJ5IDogcHJvdmlkZXIuZW50cnlTZXQoKSkgeworICAgICAgICAgICAgICAgIE9iamVjdCBrID0gZW50cnkuZ2V0S2V5KCk7CisgICAgICAgICAgICAgICAgT2JqZWN0IHYgPSBlbnRyeS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhTdHJpbmcuY2xhc3MsIGsuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFN0cmluZy5jbGFzcywgdi5nZXRDbGFzcygpKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcga2V5ID0gKFN0cmluZylrOworICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IChTdHJpbmcpdjsKKworICAgICAgICAgICAgICAgIC8vIHNraXAgUHJvdmlkZXIuaWQga2V5cywgd2UgY2hlY2sgd2VsbCBrbm93biBvbmVzIHZhbHVlcyBhYm92ZQorICAgICAgICAgICAgICAgIGlmIChrZXkuc3RhcnRzV2l0aCgiUHJvdmlkZXIuaWQgIikpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gc2tpcCBwcm9wZXJ0eSBzZXR0aW5ncyBzdWNoIGFzOiAiU2lnbmF0dXJlLlNIQTF3aXRoRFNBIEltcGxlbWVudGVkSW4iICJTb2Z0d2FyZSIKKyAgICAgICAgICAgICAgICBpZiAoa2V5LmluZGV4T2YoJyAnKSAhPSAtMSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBNYXRjaGVyIG0gPSBhbGlhcy5tYXRjaGVyKGtleSk7CisgICAgICAgICAgICAgICAgaWYgKG0uZmluZCgpKSB7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyB0eXBlID0gbS5ncm91cCgxKTsKKyAgICAgICAgICAgICAgICAgICAgYWxpYXNlcy5wdXQoa2V5LCB0eXBlICsgIi4iICsgdmFsdWUpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGltcGxlbWVudGF0aW9ucy5wdXQoa2V5LCB2YWx1ZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB2ZXJpZnkgaW1wbGVtZW50YXRpb24gY2xhc3NlcyBhcmUgYXZhaWxhYmxlCisgICAgICAgICAgICBmb3IgKEVudHJ5PFN0cmluZyxTdHJpbmc+IGVudHJ5IDogaW1wbGVtZW50YXRpb25zLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgdHlwZUFuZEFsZ29yaXRobSA9IGVudHJ5LmdldEtleSgpOworICAgICAgICAgICAgICAgIFN0cmluZyBjbGFzc05hbWUgPSBlbnRyeS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXIuZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFN1biBmb3Jnb3QgdGhlaXIgb3duIGNsYXNzCisgICAgICAgICAgICAgICAgICAgIGlmICghY2xhc3NOYW1lLmVxdWFscygic3VuLnNlY3VyaXR5LnBrY3MxMS5QMTFNQUMiKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCgiQ291bGQgbm90IGZpbmQgY2xhc3MgIiArIGNsYXNzTmFtZSArICIgZm9yICIgKyB0eXBlQW5kQWxnb3JpdGhtKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gbWFrZSBzdXJlIGFsbCBhbGlhc2VzIHBvaW50IHRvIHNvbWUga25vd24gaW1wbGVtZW50YXRpb24KKyAgICAgICAgICAgIGZvciAoRW50cnk8U3RyaW5nLFN0cmluZz4gZW50cnkgOiBhbGlhc2VzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgYWxpYXMgID0gZW50cnkuZ2V0S2V5KCk7CisgICAgICAgICAgICAgICAgU3RyaW5nIGFjdHVhbCA9IGVudHJ5LmdldFZhbHVlKCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQ291bGQgbm90IGZpbmQgaW1wbGVtZW50YXRpb24gIiArIGFjdHVhbCArICIgZm9yIGFsaWFzICIgKyBhbGlhcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGltcGxlbWVudGF0aW9ucy5jb250YWluc0tleShhY3R1YWwpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvU2lnbmF0dXJlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zZWN1cml0eS9TaWduYXR1cmVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzVhYWRhMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvU2lnbmF0dXJlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTYyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLlg1MDlFbmNvZGVkS2V5U3BlYzsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgU2lnbmF0dXJlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8vIDIwIGJ5dGVzIGZvciBEU0EKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBEQVRBID0gbmV3IGJ5dGVbMjBdOworCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQcm92aWRlcltdIHByb3ZpZGVycyA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygpOworICAgICAgICBmb3IgKFByb3ZpZGVyIHByb3ZpZGVyIDogcHJvdmlkZXJzKSB7CisgICAgICAgICAgICBTZXQ8UHJvdmlkZXIuU2VydmljZT4gc2VydmljZXMgPSBwcm92aWRlci5nZXRTZXJ2aWNlcygpOworICAgICAgICAgICAgZm9yIChQcm92aWRlci5TZXJ2aWNlIHNlcnZpY2UgOiBzZXJ2aWNlcykgeworICAgICAgICAgICAgICAgIFN0cmluZyB0eXBlID0gc2VydmljZS5nZXRUeXBlKCk7CisgICAgICAgICAgICAgICAgaWYgKCF0eXBlLmVxdWFscygiU2lnbmF0dXJlIikpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIFN0cmluZyBhbGdvcml0aG0gPSBzZXJ2aWNlLmdldEFsZ29yaXRobSgpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIEtleVBhaXIga3AgPSBrZXlQYWlyKGFsZ29yaXRobSk7CisgICAgICAgICAgICAgICAgICAgIC8vIFNpZ25hdHVyZS5nZXRJbnN0YW5jZShTdHJpbmcpCisgICAgICAgICAgICAgICAgICAgIFNpZ25hdHVyZSBzaWcxID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhhbGdvcml0aG0sIHNpZzEuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICAgICAgICAgICAgICB0ZXN0X1NpZ25hdHVyZShzaWcxLCBrcCk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gU2lnbmF0dXJlLmdldEluc3RhbmNlKFN0cmluZywgUHJvdmlkZXIpCisgICAgICAgICAgICAgICAgICAgIFNpZ25hdHVyZSBzaWcyID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKGFsZ29yaXRobSwgcHJvdmlkZXIpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYWxnb3JpdGhtLCBzaWcyLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHByb3ZpZGVyLCBzaWcyLmdldFByb3ZpZGVyKCkpOworICAgICAgICAgICAgICAgICAgICB0ZXN0X1NpZ25hdHVyZShzaWcyLCBrcCk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gU2lnbmF0dXJlLmdldEluc3RhbmNlKFN0cmluZywgU3RyaW5nKQorICAgICAgICAgICAgICAgICAgICBTaWduYXR1cmUgc2lnMyA9IFNpZ25hdHVyZS5nZXRJbnN0YW5jZShhbGdvcml0aG0sIHByb3ZpZGVyLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhhbGdvcml0aG0sIHNpZzMuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMocHJvdmlkZXIsIHNpZzMuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgICAgICAgICAgICAgIHRlc3RfU2lnbmF0dXJlKHNpZzMsIGtwKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJQcm9ibGVtIHRlc3RpbmcgU2lnbmF0dXJlLiIgKyBhbGdvcml0aG0sIGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgS2V5UGFpcj4ga2V5cGFpckFsZ29yaXRobVRvSW5zdGFuY2UKKyAgICAgICAgICAgID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBLZXlQYWlyPigpOworCisgICAgcHJpdmF0ZSBLZXlQYWlyIGtleVBhaXIoU3RyaW5nIHNpZ0FsZ29yaXRobSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzaWdBbGdvcml0aG0uZW5kc1dpdGgoIkVuY3J5cHRpb24iKSkgeworICAgICAgICAgICAgc2lnQWxnb3JpdGhtID0gc2lnQWxnb3JpdGhtLnN1YnN0cmluZygwLCBzaWdBbGdvcml0aG0ubGVuZ3RoKCktIkVuY3J5cHRpb24iLmxlbmd0aCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBrcEFsZ29yaXRobTsKKyAgICAgICAgLy8gbm90ZSBFQ0RTQSBtdXN0IGJlIGJlZm9yZSBEU0EKKyAgICAgICAgaWYgKHNpZ0FsZ29yaXRobS5lbmRzV2l0aCgiRUNEU0EiKSkgeworICAgICAgICAgICAga3BBbGdvcml0aG0gPSAiRUMiOworICAgICAgICB9IGVsc2UgaWYgKHNpZ0FsZ29yaXRobS5lbmRzV2l0aCgiRFNBIikpIHsKKyAgICAgICAgICAgIGtwQWxnb3JpdGhtID0gIkRTQSI7CisgICAgICAgIH0gZWxzZSBpZiAoc2lnQWxnb3JpdGhtLmVuZHNXaXRoKCJSU0EiKSkgeworICAgICAgICAgICAga3BBbGdvcml0aG0gPSAiUlNBIjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlVua25vd24gS2V5UGFpciBhbGdvcml0aG0gZm9yIFNpZ25hdHVyZSBhbGdvcml0aG0gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHNpZ0FsZ29yaXRobSk7CisgICAgICAgIH0KKworICAgICAgICBLZXlQYWlyIGtwID0ga2V5cGFpckFsZ29yaXRobVRvSW5zdGFuY2UuZ2V0KGtwQWxnb3JpdGhtKTsKKyAgICAgICAgaWYgKGtwID09IG51bGwpIHsKKyAgICAgICAgICAgIGtwID0gS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZShrcEFsZ29yaXRobSkuZ2VuZXJhdGVLZXlQYWlyKCk7CisgICAgICAgICAgICBrZXlwYWlyQWxnb3JpdGhtVG9JbnN0YW5jZS5wdXQoc2lnQWxnb3JpdGhtLCBrcCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGtwOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0X1NpZ25hdHVyZShTaWduYXR1cmUgc2lnLCBLZXlQYWlyIGtleVBhaXIpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzaWcuaW5pdFNpZ24oa2V5UGFpci5nZXRQcml2YXRlKCkpOworICAgICAgICBzaWcudXBkYXRlKERBVEEpOworICAgICAgICBieXRlW10gc2lnbmF0dXJlID0gc2lnLnNpZ24oKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzaWduYXR1cmUpOworICAgICAgICBhc3NlcnRUcnVlKHNpZ25hdHVyZS5sZW5ndGggPiAwKTsKKworICAgICAgICBzaWcuaW5pdFZlcmlmeShrZXlQYWlyLmdldFB1YmxpYygpKTsKKyAgICAgICAgc2lnLnVwZGF0ZShEQVRBKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzaWcudmVyaWZ5KHNpZ25hdHVyZSkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBQS19CWVRFUyA9IGhleFRvQnl0ZXMoCisgICAgICAgICAgICAiMzA4MTlmMzAwZDA2MDkyYTg2NDg4NmY3MGQwMTAxMDEwNTAwMDM4MThkMDAzMDgxODkwMjgxODEwMGNkNzY5ZDE3OGY2MTQ3NWZjZTMwMDEiCisgICAgICAgICAgICArICIyNjA0MjE4MzIwYzc3YTQyNzEyMWQzYjQxZGQ3Njc1NmM4ZmMwYzQyOGNkMTVjYjc1NGFkYzg1NDY2ZjQ3NTQ3YjFjODU2MjNkOWMxN2ZjNiIKKyAgICAgICAgICAgICsgIjRmMjAyZmNhMjEwOTljYWY5OTQ2MGM4MjRhZDY1N2NhYThjMmRiMzQ5OTY4MzhkMzI2MjNjNGYyM2M4YjZhNGU2Njk4NjAzOTAxMjYyNjE5IgorICAgICAgICAgICAgKyAiNDg0MGUwODk2YjFhNmVjNGY2NjUyNDg0YWFkMDQ1NjliYjZhODg1YjgyMmExMGQ3MDAyMjQzNTljNjMyZGM3MzI0NTIwY2JiM2QwMjAzMDEiCisgICAgICAgICAgICArICIwMDAxIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIENPTlRFTlQgPSBoZXhUb0J5dGVzKAorICAgICAgICAgICAgImYyZmE5ZDczNjU2ZTAwZmEwMWVkYzEyZTczNjU2ZTJlNzY3MDYzMmU2NDMyMDA0ODY3MjY4YzQ2ZGQ5NTAzMGI5M2NlNzI2MDQyM2U1YzAwIgorICAgICAgICAgICAgKyAiZmFiZDRkNjU2ZDYyNjU3MjczMDBmYTAxOGRjMTJlNzM2NTZlMmU3NjcwNjMyZTY0MzEwMGQ3YzI1OGRjMDBmYWJkNDQ2NTc2Njk2MzY1NzMiCisgICAgICAgICAgICArICIwMGZhYTU0YjY1Nzk3MzAwZmEwMmI1YzEyZTRkMmU0YjAwOTQ3MTk2OGNjNjg4MzVmOGE2OGRkZTEwZjUzZDE5NjkzZDQ4MGRlNzY3ZTVmYiIKKyAgICAgICAgICAgICsgIjk3NmYzNTYyMzI0MDA2MzcyMzAwZmFiZGZkMDRlMWY1MWVmM2FhMDBmYThkMDAwMDAwMDFhMjAzZTIwMjg1OTQ3MTk2OGNjNjg4MzVmOGE2IgorICAgICAgICAgICAgKyAiOGRkZTEwZjUzZDE5NjkzZDQ4MGRlNzY3ZTVmYjk3NmYzNTYyMzI0MDA2MzcyMzAwMDJiYWI1MDRlMWY1MWVmNTgxMDAwMmMyOWQyODQ2M2YiCisgICAgICAgICAgICArICIwMDAzZGE4ZDAwMDAwMWUyMDFlYWYyZmE5ZDczNjU2ZTAwZmEwMWVkYzEyZTczNjU2ZTJlNzY3MDYzMmU2NDMyMDA0ODY3MjY4YzQ2ZGQ5NSIKKyAgICAgICAgICAgICsgIjAzMGI5M2NlNzI2MDQyM2U1YzAwZmFiZDRkNjU2ZDYyNjU3MjczMDBmYTAxOGRjMTJlNzM2NTZlMmU3NjcwNjMyZTY0MzEwMGQ3YzI1OGRjIgorICAgICAgICAgICAgKyAiMDBmYWJkNDQ2NTc2Njk2MzY1NzMwMGZhYTU0YjY1Nzk3MzAwZmEwMmI1YzEyZTRkMmU0YjAwOTQ3MTk2OGNjNjg4MzVmOGE2OGRkZTEwZjUiCisgICAgICAgICAgICArICIzZDE5NjkzZDQ4MGRlNzY3ZTVmYjk3NmYzNTYyMzI0MDA2MzcyMzAwZmFiZGZkMDRlMWY1MWVmM2FhMDAwMDAzZTIwMjg1OTQ3MTk2OGNjNiIKKyAgICAgICAgICAgICsgIjg4MzVmOGE2OGRkZTEwZjUzZDE5NjkzZDQ4MGRlNzY3ZTVmYjk3NmYzNTYyMzI0MDA2MzcyMzAwMDAwMDAwMDE5YTBhOTUzMDgxOWYzMDBkIgorICAgICAgICAgICAgKyAiMDYwOTJhODY0ODg2ZjcwZDAxMDEwMTA1MDAwMzgxOGQwMDMwODE4OTAyODE4MTAwY2Q3NjlkMTc4ZjYxNDc1ZmNlMzAwMTI2MDQyMTgzMjAiCisgICAgICAgICAgICArICJjNzdhNDI3MTIxZDNiNDFkZDc2NzU2YzhmYzBjNDI4Y2QxNWNiNzU0YWRjODU0NjZmNDc1NDdiMWM4NTYyM2Q5YzE3ZmM2NGYyMDJmY2EyMSIKKyAgICAgICAgICAgICsgIjA5OWNhZjk5NDYwYzgyNGFkNjU3Y2FhOGMyZGIzNDk5NjgzOGQzMjYyM2M0ZjIzYzhiNmE0ZTY2OTg2MDM5MDEyNjI2MTk0ODQwZTA4OTZiIgorICAgICAgICAgICAgKyAiMWE2ZWM0ZjY2NTI0ODRhYWQwNDU2OWJiNmE4ODViODIyYTEwZDcwMDIyNDM1OWM2MzJkYzczMjQ1MjBjYmIzZDAyMDMwMTAwMDEwMCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBTSUdOQVRVUkUgPSBoZXhUb0J5dGVzKAorICAgICAgICAgICAgImI0MDE2NDU2MTQ4Y2QyZTlmNTgwNDcwYWFkNjNkMTljMWZlZTUyYjM4YzlkY2I1YjRkNjFhN2NhMzY5YTcyNzc0OTc3NzVkMTA2ZDg2Mzk0IgorICAgICAgICAgICAgKyAiYTY5MjI5MTg0MzMzYjVhM2U2MjYxZDViY2ViZGIwMjUzMGNhOTkwOWY0ZDc5MDE5OWVhZTdjMTQwZjdkYjM5ZGVlMjIzMjE5MWJkZjBiZmIiCisgICAgICAgICAgICArICIzNGZkYWRjNDQzMjZiOWIzZjNmYTgyODY1MmJhYjA3ZjAzNjJhYzE0MWM4YzM3ODRlYmRlYzQ0ZTBiMTU2YTVlN2JjY2RjODFhNTZmZTk1NCIKKyAgICAgICAgICAgICsgIjU2YWM4YzBlNGFlMTJkOTciKTsKKworICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBoZXhUb0J5dGVzKFN0cmluZyBzKSB7CisgICAgICAgIGludCBsZW4gPSBzLmxlbmd0aCgpOworICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlW2xlbiAvIDJdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSArPSAyKSB7CisgICAgICAgICAgICBkYXRhW2kgLyAyXSA9IChieXRlKSAoKENoYXJhY3Rlci5kaWdpdChzLmNoYXJBdChpKSwgMTYpIDw8IDQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBDaGFyYWN0ZXIuZGlnaXQocy5jaGFyQXQoaSsxKSwgMTYpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZGF0YTsKKyAgICB9CisKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTE4NTY2CisgICAgLy8gaHR0cDovL2IvNTAzODU1NAorICAgIHB1YmxpYyB2b2lkIHRlc3QxODU2NigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYNTA5RW5jb2RlZEtleVNwZWMga2V5U3BlYyA9IG5ldyBYNTA5RW5jb2RlZEtleVNwZWMoUEtfQllURVMpOworICAgICAgICBLZXlGYWN0b3J5IGtleUZhY3RvcnkgPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKCJSU0EiKTsKKyAgICAgICAgUHVibGljS2V5IHBrID0ga2V5RmFjdG9yeS5nZW5lcmF0ZVB1YmxpYyhrZXlTcGVjKTsKKworICAgICAgICBTaWduYXR1cmUgc2lnID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCJTSEEyNTZ3aXRoUlNBIik7CisgICAgICAgIHNpZy5pbml0VmVyaWZ5KHBrKTsKKyAgICAgICAgc2lnLnVwZGF0ZShDT05URU5UKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzaWcudmVyaWZ5KFNJR05BVFVSRSkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUZhY3RvcnlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVGYWN0b3J5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU5YTkxZGQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVGYWN0b3J5VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIENlcnRpZmljYXRlRmFjdG9yeVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURfQ0VSVElGSUNBVEVfUEVNID0KKyAgICAgICAgICAgICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICsgIk1JSURJVENDQW9xZ0F3SUJBZ0lRTDkrODlxNlJVbTBQbXFQZlFEUSttakFOQmdrcWhraUc5dzBCQVFVRkFEQk1cbiIKKyAgICAgICAgICAgICsgIk1Rc3dDUVlEVlFRR0V3SmFRVEVsTUNNR0ExVUVDaE1jVkdoaGQzUmxJRU52Ym5OMWJIUnBibWNnS0ZCMGVTa2dcbiIKKyAgICAgICAgICAgICsgIlRIUmtMakVXTUJRR0ExVUVBeE1OVkdoaGQzUmxJRk5IUXlCRFFUQWVGdzB3T1RFeU1UZ3dNREF3TURCYUZ3MHhcbiIKKyAgICAgICAgICAgICsgIk1URXlNVGd5TXpVNU5UbGFNR2d4Q3pBSkJnTlZCQVlUQWxWVE1STXdFUVlEVlFRSUV3cERZV3hwWm05eWJtbGhcbiIKKyAgICAgICAgICAgICsgIk1SWXdGQVlEVlFRSEZBMU5iM1Z1ZEdGcGJpQldhV1YzTVJNd0VRWURWUVFLRkFwSGIyOW5iR1VnU1c1ak1SY3dcbiIKKyAgICAgICAgICAgICsgIkZRWURWUVFERkE1M2QzY3VaMjl2WjJ4bExtTnZiVENCbnpBTkJna3Foa2lHOXcwQkFRRUZBQU9CalFBd2dZa0NcbiIKKyAgICAgICAgICAgICsgImdZRUE2UG1HRDVENmh0ZmZ2WEltdHRkRUFvTjRjOWtDS08rSVJUbjdFT2g4cnFrNDFYWEdPT3NLRlFlYmcrak5cbiIKKyAgICAgICAgICAgICsgImd0WGo5eFZvUmFFTEdZVzg0dStFNTkzeTE3aVl3cUc3dGNGUjM5U0RBcWM5QmtKYjRTTEQzbXVGWHh6VzJrNkxcbiIKKyAgICAgICAgICAgICsgIjA1dnV1V2NpS2gwUjczbWtzemVLOVA0WS9iejVSaU5RbC9Pcy9DUkdLMXc3dDBVQ0F3RUFBYU9CNXpDQjVEQU1cbiIKKyAgICAgICAgICAgICsgIkJnTlZIUk1CQWY4RUFqQUFNRFlHQTFVZEh3UXZNQzB3SzZBcG9DZUdKV2gwZEhBNkx5OWpjbXd1ZEdoaGQzUmxcbiIKKyAgICAgICAgICAgICsgIkxtTnZiUzlVYUdGM2RHVlRSME5EUVM1amNtd3dLQVlEVlIwbEJDRXdId1lJS3dZQkJRVUhBd0VHQ0NzR0FRVUZcbiIKKyAgICAgICAgICAgICsgIkJ3TUNCZ2xnaGtnQmh2aENCQUV3Y2dZSUt3WUJCUVVIQVFFRVpqQmtNQ0lHQ0NzR0FRVUZCekFCaGhab2RIUndcbiIKKyAgICAgICAgICAgICsgIk9pOHZiMk56Y0M1MGFHRjNkR1V1WTI5dE1ENEdDQ3NHQVFVRkJ6QUNoakpvZEhSd09pOHZkM2QzTG5Sb1lYZDBcbiIKKyAgICAgICAgICAgICsgIlpTNWpiMjB2Y21Wd2IzTnBkRzl5ZVM5VWFHRjNkR1ZmVTBkRFgwTkJMbU55ZERBTkJna3Foa2lHOXcwQkFRVUZcbiIKKyAgICAgICAgICAgICsgIkFBT0JnUUNmUTg5YnhGQXBzYi9pc0pyL2FpRWRMUkxETEU1YStSTGl6cm1DVWkzbkhYNGFkcGFRZWRFa1VqaDVcbiIKKyAgICAgICAgICAgICsgInUyT05nSmQ4SXlBUGtVMFd1ZXJ1OUcySnlzYTl6Q1JvMWtOYnppcFl2endZNE9BOFlzK1dBaTBvUjFBMDRTZTZcbiIKKyAgICAgICAgICAgICsgIno1blJVUDhwSmNBMk5oVXpVbkMrTVkrZjZIL25FUXlOdjRTZ1FocUFpYkF4V0VFSFh3PT1cbiIKKyAgICAgICAgICAgICsgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cbiI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9DRVJUSUZJQ0FURV9QRU0gPQorICAgICAgICAgICAgIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVxuIgorICAgICAgICAgICAgKyAiQUFBQUFBQUFcbiIKKyAgICAgICAgICAgICsgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0iOworCisgICAgcHVibGljIHZvaWQgdGVzdF9nZW5lcmF0ZUNlcnRpZmljYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RfZ2VuZXJhdGVDZXJ0aWZpY2F0ZShDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlg1MDkiKSk7CisgICAgICAgIHRlc3RfZ2VuZXJhdGVDZXJ0aWZpY2F0ZShDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlg1MDkiLCAiQkMiKSk7CisgICAgICAgIHRlc3RfZ2VuZXJhdGVDZXJ0aWZpY2F0ZShDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlg1MDkiLCAiRFJMQ2VydEZhY3RvcnkiKSk7CisgICAgfQorICAgIHByaXZhdGUgdm9pZCB0ZXN0X2dlbmVyYXRlQ2VydGlmaWNhdGUoQ2VydGlmaWNhdGVGYWN0b3J5IGNmKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIHZhbGlkID0gVkFMSURfQ0VSVElGSUNBVEVfUEVNLmdldEJ5dGVzKCk7CisgICAgICAgIENlcnRpZmljYXRlIGMgPSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSh2YWxpZCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKGMpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBieXRlW10gaW52YWxpZCA9IElOVkFMSURfQ0VSVElGSUNBVEVfUEVNLmdldEJ5dGVzKCk7CisgICAgICAgICAgICBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShpbnZhbGlkKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvY2VydC9PbGRQS0lYUGFyYW1ldGVyc1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvY2VydC9PbGRQS0lYUGFyYW1ldGVyc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNjllMGUyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zZWN1cml0eS9jZXJ0L09sZFBLSVhQYXJhbWV0ZXJzVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjEyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyAqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uQnJva2VuVGVzdDsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuUEtJWFBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LlRydXN0QW5jaG9yOworaW1wb3J0IGphdmEudXRpbC5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5UZXN0VXRpbHM7CitpbXBvcnQgdGVzdHMudGFyZ2V0cy5zZWN1cml0eS5LZXlTdG9yZVRlc3RQS0NTMTI7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlBLSVhQYXJhbWV0ZXJzPC9jb2RlPiBmaWVsZHMgYW5kIG1ldGhvZHMKKyAqLworcHVibGljIGNsYXNzIE9sZFBLSVhQYXJhbWV0ZXJzVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RDbG9uZSgpIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgU2V0PFRydXN0QW5jaG9yPiB0YVNldCA9IFRlc3RVdGlscy5nZXRUcnVzdEFuY2hvclNldCgpOworICAgICAgICBpZiAodGFTZXQgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbChnZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgKyAiOiBub3QgcGVyZm9ybWVkIChjb3VsZCBub3QgY3JlYXRlIHRlc3QgVHJ1c3RBbmNob3Igc2V0KSIpOworICAgICAgICB9CisKKyAgICAgICAgUEtJWFBhcmFtZXRlcnMgY3BwID0gbmV3IFBLSVhQYXJhbWV0ZXJzKHRhU2V0KTsKKyAgICAgICAgUEtJWFBhcmFtZXRlcnMgY3BwYyA9IChQS0lYUGFyYW1ldGVycykgY3BwLmNsb25lKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNwcC5nZXRQb2xpY3lRdWFsaWZpZXJzUmVqZWN0ZWQoKSwgY3BwYworICAgICAgICAgICAgICAgIC5nZXRQb2xpY3lRdWFsaWZpZXJzUmVqZWN0ZWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjcHAuZ2V0Q2VydFBhdGhDaGVja2VycygpLCBjcHBjLmdldENlcnRQYXRoQ2hlY2tlcnMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjcHAuZ2V0Q2VydFN0b3JlcygpLCBjcHBjLmdldENlcnRTdG9yZXMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjcHAuZ2V0RGF0ZSgpLCBjcHBjLmdldERhdGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjcHAuZ2V0SW5pdGlhbFBvbGljaWVzKCksIGNwcGMuZ2V0SW5pdGlhbFBvbGljaWVzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoY3BwLmdldFNpZ1Byb3ZpZGVyKCksIGNwcGMuZ2V0U2lnUHJvdmlkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjcHAuZ2V0VGFyZ2V0Q2VydENvbnN0cmFpbnRzKCksIGNwcGMKKyAgICAgICAgICAgICAgICAuZ2V0VGFyZ2V0Q2VydENvbnN0cmFpbnRzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoY3BwLmdldFRydXN0QW5jaG9ycygpLCBjcHBjLmdldFRydXN0QW5jaG9ycygpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoY3BwLmlzQW55UG9saWN5SW5oaWJpdGVkKCksIGNwcGMuaXNBbnlQb2xpY3lJbmhpYml0ZWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjcHAuaXNFeHBsaWNpdFBvbGljeVJlcXVpcmVkKCksIGNwcGMKKyAgICAgICAgICAgICAgICAuaXNFeHBsaWNpdFBvbGljeVJlcXVpcmVkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoY3BwLmlzUG9saWN5TWFwcGluZ0luaGliaXRlZCgpLCBjcHBjCisgICAgICAgICAgICAgICAgLmlzUG9saWN5TWFwcGluZ0luaGliaXRlZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNwcC5pc1Jldm9jYXRpb25FbmFibGVkKCksIGNwcGMuaXNSZXZvY2F0aW9uRW5hYmxlZCgpKTsKKworICAgICAgICBjcHAuc2V0RGF0ZShDYWxlbmRhci5nZXRJbnN0YW5jZSgpLmdldFRpbWUoKSk7CisgICAgICAgIGNwcC5zZXRQb2xpY3lRdWFsaWZpZXJzUmVqZWN0ZWQoIWNwcGMuZ2V0UG9saWN5UXVhbGlmaWVyc1JlamVjdGVkKCkpOworICAgICAgICBhc3NlcnRGYWxzZShjcHAuZ2V0RGF0ZSgpLmVxdWFscyhjcHBjLmdldERhdGUoKSkpOworICAgICAgICBhc3NlcnRGYWxzZShjcHAuZ2V0UG9saWN5UXVhbGlmaWVyc1JlamVjdGVkKCkgPT0gY3BwYworICAgICAgICAgICAgICAgIC5nZXRQb2xpY3lRdWFsaWZpZXJzUmVqZWN0ZWQoKSk7CisKKyAgICAgICAgY3BwYy5zZXRFeHBsaWNpdFBvbGljeVJlcXVpcmVkKCFjcHAuaXNFeHBsaWNpdFBvbGljeVJlcXVpcmVkKCkpOworICAgICAgICBjcHBjLnNldFJldm9jYXRpb25FbmFibGVkKCFjcHAuaXNSZXZvY2F0aW9uRW5hYmxlZCgpKTsKKworICAgICAgICBhc3NlcnRGYWxzZShjcHAuaXNFeHBsaWNpdFBvbGljeVJlcXVpcmVkKCkgPT0gY3BwYworICAgICAgICAgICAgICAgIC5pc0V4cGxpY2l0UG9saWN5UmVxdWlyZWQoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGNwcC5pc1Jldm9jYXRpb25FbmFibGVkKCkgPT0gY3BwYy5pc1Jldm9jYXRpb25FbmFibGVkKCkpOworCisgICAgICAgIFBLSVhQYXJhbWV0ZXJzIGNwcDEgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY3BwMS5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+aXNQb2xpY3lNYXBwaW5nSW5oaWJpdGVkKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgdHJ1ZSBpZiBwb2xpY3kgbWFwcGluZyBpcyBpbmhpYml0ZWQsIGZhbHNlIG90aGVyd2lzZQorICAgICAqIEFzc2VydGlvbjogYnkgZGVmYXVsdCwgcG9saWN5IG1hcHBpbmcgaXMgbm90IGluaGliaXRlZCAodGhlIGZsYWcgaXMKKyAgICAgKiBmYWxzZSkKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RJc1BvbGljeU1hcHBpbmdJbmhpYml0ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2V0PFRydXN0QW5jaG9yPiB0YVNldCA9IFRlc3RVdGlscy5nZXRUcnVzdEFuY2hvclNldCgpOworICAgICAgICBpZiAodGFTZXQgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiOiBub3QgcGVyZm9ybWVkIChjb3VsZCBub3QgY3JlYXRlIHRlc3QgVHJ1c3RBbmNob3Igc2V0KSIpOworICAgICAgICB9CisKKyAgICAgICAgUEtJWFBhcmFtZXRlcnMgcCA9IG5ldyBQS0lYUGFyYW1ldGVycyh0YVNldCk7CisgICAgICAgIGFzc2VydEZhbHNlKHAuaXNQb2xpY3lNYXBwaW5nSW5oaWJpdGVkKCkpOworCisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgVGVzdFV0aWxzLmluaXRDZXJ0UGF0aFNTQ2VydENoYWluKCk7CisgICAgICAgIFNldDxUcnVzdEFuY2hvcj4gdGFTZXQyID0gQ29sbGVjdGlvbnMuc2luZ2xldG9uKG5ldyBUcnVzdEFuY2hvcigKKyAgICAgICAgICAgICAgIFRlc3RVdGlscy5yb290Q2VydGlmaWNhdGVTUywgbnVsbCkpOworICAgICAgICBwID0gbmV3IFBLSVhQYXJhbWV0ZXJzKHRhU2V0Mik7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UocC5pc1BvbGljeU1hcHBpbmdJbmhpYml0ZWQoKSk7CisgICAgICAgIHAuc2V0UG9saWN5TWFwcGluZ0luaGliaXRlZCh0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwLmlzUmV2b2NhdGlvbkVuYWJsZWQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+aXNQb2xpY3lNYXBwaW5nSW5oaWJpdGVkKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIFJldm9jYXRpb25FbmFibGVkIGZsYWcKKyAgICAgKiBBc3NlcnRpb246IHdoZW4gYSA8Y29kZT5QS0lYUGFyYW1ldGVyczwvY29kZT4gb2JqZWN0IGlzIGNyZWF0ZWQsIHRoaXMKKyAgICAgKiBmbGFnIGlzIHNldCB0byB0cnVlCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0SXNSZXZvY2F0aW9uRW5hYmxlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTZXQ8VHJ1c3RBbmNob3I+IHRhU2V0ID0gVGVzdFV0aWxzLmdldFRydXN0QW5jaG9yU2V0KCk7CisgICAgICAgIGlmICh0YVNldCA9PSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKQorICAgICAgICAgICAgICAgICAgICArICI6IG5vdCBwZXJmb3JtZWQgKGNvdWxkIG5vdCBjcmVhdGUgdGVzdCBUcnVzdEFuY2hvciBzZXQpIik7CisgICAgICAgIH0KKworICAgICAgICBQS0lYUGFyYW1ldGVycyBwID0gbmV3IFBLSVhQYXJhbWV0ZXJzKHRhU2V0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwLmlzUmV2b2NhdGlvbkVuYWJsZWQoKSk7CisKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgIFRlc3RVdGlscy5pbml0Q2VydFBhdGhTU0NlcnRDaGFpbigpOworICAgICAgIFNldDxUcnVzdEFuY2hvcj4gdGFTZXQyID0gQ29sbGVjdGlvbnMuc2luZ2xldG9uKG5ldyBUcnVzdEFuY2hvcigKKyAgICAgICAgICAgICAgVGVzdFV0aWxzLnJvb3RDZXJ0aWZpY2F0ZVNTLCBudWxsKSk7CisgICAgICAgcCA9IG5ldyBQS0lYUGFyYW1ldGVycyh0YVNldDIpOworCisgICAgICAgYXNzZXJ0VHJ1ZShwLmlzUmV2b2NhdGlvbkVuYWJsZWQoKSk7CisgICAgICAgcC5zZXRSZXZvY2F0aW9uRW5hYmxlZChmYWxzZSk7CisgICAgICAgYXNzZXJ0RmFsc2UocC5pc1Jldm9jYXRpb25FbmFibGVkKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnRvU3RyaW5nPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFRvU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNldDxUcnVzdEFuY2hvcj4gdGFTZXQgPSBUZXN0VXRpbHMuZ2V0VHJ1c3RBbmNob3JTZXQoKTsKKyAgICAgICAgaWYgKHRhU2V0ID09IG51bGwpIHsKKyAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgICAgICsgIjogbm90IHBlcmZvcm1lZCAoY291bGQgbm90IGNyZWF0ZSB0ZXN0IFRydXN0QW5jaG9yIHNldCkiKTsKKyAgICAgICAgfQorCisgICAgICAgIFBLSVhQYXJhbWV0ZXJzIHAgPSBuZXcgUEtJWFBhcmFtZXRlcnModGFTZXQpOworICAgICAgICBhc3NlcnROb3ROdWxsKHAudG9TdHJpbmcoKSk7CisKKyAgICAgICAgUEtJWFBhcmFtZXRlcnMgcDEgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcDEudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM0IGZvciA8Y29kZT5QS0lYUGFyYW1ldGVycyhLZXlTdG9yZSk8L2NvZGU+IGNvbnN0cnVjdG9yPGJyPgorICAgICAqCisgICAgICogQHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uCisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqLworICAgIEBCcm9rZW5UZXN0KCJGYWlscyBpbiBDVFMgZW52aXJvbm1lbnQsIGJ1dCBwYXNzZXMgaW4gQ29yZVRlc3RSdW5uZXIiKQorICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RQS0lYUGFyYW1ldGVyc0tleVN0b3JlMDQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworCisgICAgICAgIEtleVN0b3JlIHN0b3JlID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoIlBLQ1MxMiIpOworICAgICAgICBLZXlTdG9yZVRlc3RQS0NTMTIgayA9IG5ldyBLZXlTdG9yZVRlc3RQS0NTMTIoKTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gc3RyZWFtID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGsua2V5U3RvcmVEYXRhKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUEtJWFBhcmFtZXRlcnMgcCA9IG5ldyBQS0lYUGFyYW1ldGVycyhzdG9yZSk7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICBzdG9yZSA9IEtleVN0b3JlLmdldEluc3RhbmNlKCJQS0NTMTIiKTsKKyAgICAgICAgc3RvcmUubG9hZChzdHJlYW0sIG5ldyBTdHJpbmcoS2V5U3RvcmVUZXN0UEtDUzEyLmtleVN0b3JlUGFzc3dvcmQpCisgICAgICAgICAgICAgICAgLnRvQ2hhckFycmF5KCkpOworICAgICAgICBzdHJlYW0uY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgICBQS0lYUGFyYW1ldGVycyBwID0gbmV3IFBLSVhQYXJhbWV0ZXJzKHN0b3JlKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKworICAgICAgICBLZXlTdG9yZSBrZXlzdG9yZSA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICBrZXlzdG9yZS5sb2FkKG51bGwsbnVsbCk7CisgICAgICAgIGtleXN0b3JlLnNldENlcnRpZmljYXRlRW50cnkoInRlc3QiLCBUZXN0VXRpbHMucm9vdENlcnRpZmljYXRlU1MpOworCisKKyAgICAgICAgUEtJWFBhcmFtZXRlcnMgcCA9IG5ldyBQS0lYUGFyYW1ldGVycyhrZXlzdG9yZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zZWN1cml0eS9jZXJ0L1BLSVhQYXJhbWV0ZXJzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zZWN1cml0eS9jZXJ0L1BLSVhQYXJhbWV0ZXJzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQwY2RmNzMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L2NlcnQvUEtJWFBhcmFtZXRlcnNUZXN0LmphdmEKQEAgLTAsMCArMSw1NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LlBLSVhQYXJhbWV0ZXJzOworaW1wb3J0IGxpYmNvcmUuamF2YS5zZWN1cml0eS5UZXN0S2V5U3RvcmU7CisKK3B1YmxpYyBjbGFzcyBQS0lYUGFyYW1ldGVyc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5U3RvcmVDb25zdHJ1Y3RvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0S2V5U3RvcmUgc2VydmVyID0gVGVzdEtleVN0b3JlLmdldFNlcnZlcigpOworICAgICAgICBLZXlTdG9yZS5Qcml2YXRlS2V5RW50cnkgcGtlID0gc2VydmVyLmdldFByaXZhdGVLZXkoIlJTQSIsICJSU0EiKTsKKyAgICAgICAgY2hhcltdIHBhc3N3b3JkID0gInBhc3N3b3JkIi50b0NoYXJBcnJheSgpOworCisgICAgICAgIC8vIGNvbnRhaW5zIENBIGFuZCBzZXJ2ZXIgY2VydGlmaWNhdGVzCisgICAgICAgIGFzc2VydEVxdWFscygyLCBuZXcgUEtJWFBhcmFtZXRlcnMoc2VydmVyLmtleVN0b3JlKS5nZXRUcnVzdEFuY2hvcnMoKS5zaXplKCkpOworCisgICAgICAgIC8vIGp1c3QgY29weSBzZXJ2ZXIgY2VydGlmaWNhdGVzCisgICAgICAgIEtleVN0b3JlIGtzID0gVGVzdEtleVN0b3JlLmNyZWF0ZUtleVN0b3JlKCk7CisgICAgICAgIGtzLnNldEtleUVudHJ5KCJrZXkiLCBwa2UuZ2V0UHJpdmF0ZUtleSgpLCBwYXNzd29yZCwgcGtlLmdldENlcnRpZmljYXRlQ2hhaW4oKSk7CisgICAgICAgIGtzLnNldENlcnRpZmljYXRlRW50cnkoImNlcnQiLCBwa2UuZ2V0Q2VydGlmaWNhdGVDaGFpbigpWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG5ldyBQS0lYUGFyYW1ldGVycyhrcykuZ2V0VHJ1c3RBbmNob3JzKCkuc2l6ZSgpKTsKKworICAgICAgICAvLyBzaG91bGQgZmFpbCB3aXRoIGp1c3Qga2V5LCBldmVuIHRob3VnaCBjZXJ0IGlzIHByZXNlbnQgaW4ga2V5IGVudHJ5CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZSBrZXlPbmx5ID0gVGVzdEtleVN0b3JlLmNyZWF0ZUtleVN0b3JlKCk7CisgICAgICAgICAgICBrZXlPbmx5LnNldEtleUVudHJ5KCJrZXkiLCBwa2UuZ2V0UHJpdmF0ZUtleSgpLCBwYXNzd29yZCwgcGtlLmdldENlcnRpZmljYXRlQ2hhaW4oKSk7CisgICAgICAgICAgICBuZXcgUEtJWFBhcmFtZXRlcnMoa2V5T25seSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHNob3VsZCBmYWlsIHdpdGggZW1wdHkgS2V5U3RvcmUKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBQS0lYUGFyYW1ldGVycyhUZXN0S2V5U3RvcmUuY3JlYXRlS2V5U3RvcmUoKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvY2VydC9TdWJqZWN0QWx0ZXJuYXRpdmVOYW1lVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zZWN1cml0eS9jZXJ0L1N1YmplY3RBbHRlcm5hdGl2ZU5hbWVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODhkNTAxMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvY2VydC9TdWJqZWN0QWx0ZXJuYXRpdmVOYW1lVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgY29tLmFuZHJvaWQub3JnLmJvdW5jeWNhc3RsZS5hc24xLng1MDkuR2VuZXJhbE5hbWU7CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuVGVzdEtleVN0b3JlOworCitwdWJsaWMgZmluYWwgY2xhc3MgU3ViamVjdEFsdGVybmF0aXZlTmFtZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3BlYyBkb2Vzbid0IGNvdmVyIHRoaXMsIGJ1dCB3ZSByZXF1aXJlIHRoYXQgSVAgYWRkcmVzc2VzIGFyZQorICAgICAqIGZvcm1hdHRlZCBjb25zaXN0ZW50bHkgd2l0aCBJbmV0QWRkcmVzcy5nZXRIb3N0QWRkcmVzcygpLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRJcHY0QWRkcmVzcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoIjEyNy4wLjAuMSIsIGZvcm1hdElwQWRkcmVzcyhuZXcgYnl0ZVtdezEyNywgMCwgMCwgMX0pKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0SXB2NE1hcHBlZEFkZHJlc3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIG1hcHBlZEFkZHJlc3MgPSB7IDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIC0xLCAtMSwgMTI3LCAwLCAwLCAxIH07CisgICAgICAgIGFzc2VydEVxdWFscygiMTI3LjAuMC4xIiwgZm9ybWF0SXBBZGRyZXNzKG1hcHBlZEFkZHJlc3MpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0SXB2NkFkZHJlc3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGlwQWRkcmVzcyA9IHsgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSB9OworICAgICAgICBTdHJpbmcgZGVjb2RlZCA9IGZvcm1hdElwQWRkcmVzcyhpcEFkZHJlc3MpOworICAgICAgICBhc3NlcnRUcnVlKGRlY29kZWQsIGRlY29kZWQuZXF1YWxzKCI6OjEiKSB8fCBkZWNvZGVkLmVxdWFscygiMDowOjA6MDowOjA6MDoxIikpOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGZvcm1hdElwQWRkcmVzcyhieXRlW10gaXBBZGRyZXNzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2VydGlmaWNhdGUgcm9vdCA9IG5ldyBUZXN0S2V5U3RvcmUuQnVpbGRlcigpCisgICAgICAgICAgICAgICAgLmFkZFN1YmplY3RBbHROYW1lSXBBZGRyZXNzKGlwQWRkcmVzcykKKyAgICAgICAgICAgICAgICAuYnVpbGQoKQorICAgICAgICAgICAgICAgIC5nZXRSb290Q2VydGlmaWNhdGUoIlJTQSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgamF2YUNlcnRpZmljYXRlID0gYm91bmN5Y2FzdGxlVG9KYXZhKHJvb3QpOworICAgICAgICBDb2xsZWN0aW9uPExpc3Q8Pz4+IHN1YmplY3RBbHRlcm5hdGl2ZU5hbWVzID0gamF2YUNlcnRpZmljYXRlLmdldFN1YmplY3RBbHRlcm5hdGl2ZU5hbWVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBzdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcy5zaXplKCkpOworICAgICAgICBMaXN0PD8+IHN1YmplY3RBbHRlcm5hdGl2ZU5hbWUgPSBzdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcy5pdGVyYXRvcigpLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHN1YmplY3RBbHRlcm5hdGl2ZU5hbWUuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEdlbmVyYWxOYW1lLmlQQWRkcmVzcywgc3ViamVjdEFsdGVybmF0aXZlTmFtZS5nZXQoMCkpOworICAgICAgICByZXR1cm4gKFN0cmluZykgc3ViamVjdEFsdGVybmF0aXZlTmFtZS5nZXQoMSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBYNTA5Q2VydGlmaWNhdGUgYm91bmN5Y2FzdGxlVG9KYXZhKENlcnRpZmljYXRlIGNlcnRpZmljYXRlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGVuY29kZWQgPSBjZXJ0aWZpY2F0ZS5nZXRFbmNvZGVkKCk7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBmYWN0b3J5ID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICByZXR1cm4gKFg1MDlDZXJ0aWZpY2F0ZSkgZmFjdG9yeS5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShlbmNvZGVkKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zZWN1cml0eS9jZXJ0L1g1MDlDUkxTZWxlY3RvclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvY2VydC9YNTA5Q1JMU2VsZWN0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjRmMDhjYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvY2VydC9YNTA5Q1JMU2VsZWN0b3JUZXN0LmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNSTFNlbGVjdG9yOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIFg1MDlDUkxTZWxlY3RvclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJJTkNJUEFMX1NUUklORyA9CisgICAgICAgICAgICAiQz1VUywgU1Q9Q2FsaWZvcm5pYSwgTD1Nb3VudGFpbiBWaWV3LCBPPUdvb2dsZSBJbmMsIENOPXd3dy5nb29nbGUuY29tIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBYNTAwUHJpbmNpcGFsIFBSSU5DSVBBTCA9IG5ldyBYNTAwUHJpbmNpcGFsKFBSSU5DSVBBTF9TVFJJTkcpOworCisgICAgcHVibGljIHZvaWQgdGVzdEdldElzc3VlcnNJbW11dGFibGUoKSB7CisgICAgICAgIFg1MDlDUkxTZWxlY3RvciBjcmxTZWxlY3RvciA9IG5ldyBYNTA5Q1JMU2VsZWN0b3IoKTsKKyAgICAgICAgY3JsU2VsZWN0b3IuYWRkSXNzdWVyKFBSSU5DSVBBTCk7CisgICAgICAgIENvbGxlY3Rpb248WDUwMFByaW5jaXBhbD4gaXNzdWVycyA9IGNybFNlbGVjdG9yLmdldElzc3VlcnMoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzc3VlcnMuY2xlYXIoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJc3N1ZXJzTmFtZXNDb3B5KCkgeworICAgICAgICBYNTA5Q1JMU2VsZWN0b3IgY3JsU2VsZWN0b3IgPSBuZXcgWDUwOUNSTFNlbGVjdG9yKCk7CisgICAgICAgIGNybFNlbGVjdG9yLmFkZElzc3VlcihQUklOQ0lQQUwpOworICAgICAgICBDb2xsZWN0aW9uPE9iamVjdD4gaXNzdWVycyA9IGNybFNlbGVjdG9yLmdldElzc3Vlck5hbWVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBpc3N1ZXJzLnNpemUoKSk7CisgICAgICAgIGlzc3VlcnMuY2xlYXIoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGlzc3VlcnMuc2l6ZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L2NlcnQvWDUwOUNlcnRTZWxlY3RvclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvY2VydC9YNTA5Q2VydFNlbGVjdG9yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRhNTY1OGMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L2NlcnQvWDUwOUNlcnRTZWxlY3RvclRlc3QuamF2YQpAQCAtMCwwICsxLDEzOCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBjb20uYW5kcm9pZC5vcmcuYm91bmN5Y2FzdGxlLmFzbjEueDUwOS5HZW5lcmFsTmFtZTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgbGliY29yZS5qYXZhLnNlY3VyaXR5LlRlc3RLZXlTdG9yZTsKKworcHVibGljIGZpbmFsIGNsYXNzIFg1MDlDZXJ0U2VsZWN0b3JUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdE1hdGNoSXB2NFN1YmplY3RBbHRlcm5hdGl2ZU5hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWDUwOUNlcnRTZWxlY3RvciBjZXJ0U2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworICAgICAgICBjZXJ0U2VsZWN0b3IuYWRkU3ViamVjdEFsdGVybmF0aXZlTmFtZShHZW5lcmFsTmFtZS5pUEFkZHJlc3MsICIxMjcuMC4wLjEiKTsKKworICAgICAgICBieXRlW10gbWF0Y2ggPSB7IDEyNywgMCwgMCwgMSB9OworICAgICAgICBhc3NlcnRUcnVlKGNlcnRTZWxlY3Rvci5tYXRjaChuZXdDZXJ0V2l0aFN1YmplY3RBbHROYW1lSXBBZGRyZXNzKG1hdGNoKSkpOworCisgICAgICAgIGJ5dGVbXSBub01hdGNoID0geyAxMjcsIDAsIDAsIDIgfTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoY2VydFNlbGVjdG9yLm1hdGNoKG5ld0NlcnRXaXRoU3ViamVjdEFsdE5hbWVJcEFkZHJlc3Mobm9NYXRjaCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF0Y2hJcHY0TWFwcGVkU3ViamVjdEFsdGVybmF0aXZlTmFtZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIGNlcnRTZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisgICAgICAgIGNlcnRTZWxlY3Rvci5hZGRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lKEdlbmVyYWxOYW1lLmlQQWRkcmVzcywgIjo6ZmZmZjoxMjcuMC4wLjEiKTsKKworICAgICAgICBieXRlW10gbWF0Y2ggPSB7IDEyNywgMCwgMCwgMSB9OworICAgICAgICBhc3NlcnRUcnVlKGNlcnRTZWxlY3Rvci5tYXRjaChuZXdDZXJ0V2l0aFN1YmplY3RBbHROYW1lSXBBZGRyZXNzKG1hdGNoKSkpOworCisgICAgICAgIGJ5dGVbXSBub01hdGNoID0geyAxMjcsIDAsIDAsIDIgfTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoY2VydFNlbGVjdG9yLm1hdGNoKG5ld0NlcnRXaXRoU3ViamVjdEFsdE5hbWVJcEFkZHJlc3Mobm9NYXRjaCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF0Y2hJcHY2U3ViamVjdEFsdGVybmF0aXZlTmFtZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIGNlcnRTZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisgICAgICAgIGNlcnRTZWxlY3Rvci5zZXRNYXRjaEFsbFN1YmplY3RBbHROYW1lcyhmYWxzZSk7CisgICAgICAgIGNlcnRTZWxlY3Rvci5hZGRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lKEdlbmVyYWxOYW1lLmlQQWRkcmVzcywgIjo6MSIpOworCisgICAgICAgIGJ5dGVbXSBtYXRjaCA9IHsgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSB9OworICAgICAgICBhc3NlcnRUcnVlKGNlcnRTZWxlY3Rvci5tYXRjaChuZXdDZXJ0V2l0aFN1YmplY3RBbHROYW1lSXBBZGRyZXNzKG1hdGNoKSkpOworCisgICAgICAgIGJ5dGVbXSBub01hdGNoID0geyAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAyIH07CisgICAgICAgIGFzc2VydEZhbHNlKGNlcnRTZWxlY3Rvci5tYXRjaChuZXdDZXJ0V2l0aFN1YmplY3RBbHROYW1lSXBBZGRyZXNzKG5vTWF0Y2gpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1hdGNoTWFza2VkSXB2NE5hbWVDb25zdHJhaW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBleGNsdWRlZCA9IHsgKGJ5dGUpIDE5MiwgKGJ5dGUpIDE2OCwgMCwgMSB9OworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIGNlcnRTZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisgICAgICAgIGNlcnRTZWxlY3Rvci5hZGRQYXRoVG9OYW1lKEdlbmVyYWxOYW1lLmlQQWRkcmVzcywgIjEyNy4wLjAuMSIpOworCisgICAgICAgIGJ5dGVbXSBkaXJlY3RNYXRjaCA9IHsgMTI3LCAwLCAwLCAxLCAtMSwgLTEsIC0xLCAtMSB9OworICAgICAgICBhc3NlcnRUcnVlKGNlcnRTZWxlY3Rvci5tYXRjaChuZXdDZXJ0V2l0aE5hbWVDb25zdHJhaW50KGRpcmVjdE1hdGNoLCBleGNsdWRlZCkpKTsKKworICAgICAgICBieXRlW10gbm9NYXRjaCA9IHsgMTI3LCAwLCAwLCAyLCAtMSwgLTEsIC0xLCAxMjcgfTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoY2VydFNlbGVjdG9yLm1hdGNoKG5ld0NlcnRXaXRoTmFtZUNvbnN0cmFpbnQobm9NYXRjaCwgZXhjbHVkZWQpKSk7CisKKyAgICAgICAgLy8gVE9ETzogdGVzdCB0aGF0IHJlcXVpcmVzIG1hc2sgdG8gbWF0Y2gKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF0Y2hNYXNrZWRJcHY2TmFtZUNvbnN0cmFpbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGV4Y2x1ZGVkID0geworICAgICAgICAgICAgICAgIDAsIDIsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsCisgICAgICAgICAgICAgICAgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgMAorICAgICAgICB9OworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIGNlcnRTZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisgICAgICAgIGNlcnRTZWxlY3Rvci5hZGRQYXRoVG9OYW1lKEdlbmVyYWxOYW1lLmlQQWRkcmVzcywgIjE6OjEiKTsKKworICAgICAgICBieXRlW10gZGlyZWN0TWF0Y2ggPSB7CisgICAgICAgICAgICAgICAgMCwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwKKyAgICAgICAgICAgICAgICAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAxMjcKKyAgICAgICAgfTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjZXJ0U2VsZWN0b3IubWF0Y2gobmV3Q2VydFdpdGhOYW1lQ29uc3RyYWludChkaXJlY3RNYXRjaCwgZXhjbHVkZWQpKSk7CisKKyAgICAgICAgYnl0ZVtdIG5vTWF0Y2ggPSB7CisgICAgICAgICAgICAgICAgMCwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMiwKKyAgICAgICAgICAgICAgICAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAxMjcKKyAgICAgICAgfTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoY2VydFNlbGVjdG9yLm1hdGNoKG5ld0NlcnRXaXRoTmFtZUNvbnN0cmFpbnQobm9NYXRjaCwgZXhjbHVkZWQpKSk7CisKKyAgICAgICAgLy8gVE9ETzogdGVzdCB0aGF0IHJlcXVpcmVzIG1hc2sgdG8gbWF0Y2gKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF0Y2hNYWxmb3JtZWRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3IgY2VydFNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRTZWxlY3Rvci5hZGRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lKEdlbmVyYWxOYW1lLmlQQWRkcmVzcywgIjE6OngiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydFNlbGVjdG9yLmFkZFN1YmplY3RBbHRlcm5hdGl2ZU5hbWUoR2VuZXJhbE5hbWUuaVBBZGRyZXNzLCAiMTI3LjAuMC54Iik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIFg1MDlDZXJ0aWZpY2F0ZSBuZXdDZXJ0V2l0aFN1YmplY3RBbHROYW1lSXBBZGRyZXNzKGJ5dGVbXSBpcEFkZHJlc3MpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0S2V5U3RvcmUgdGVzdEtleVN0b3JlID0gbmV3IFRlc3RLZXlTdG9yZS5CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuYWRkU3ViamVjdEFsdE5hbWVJcEFkZHJlc3MoaXBBZGRyZXNzKQorICAgICAgICAgICAgICAgIC5idWlsZCgpOworICAgICAgICByZXR1cm4gYm91bmN5Y2FzdGxlVG9KYXZhKHRlc3RLZXlTdG9yZS5nZXRSb290Q2VydGlmaWNhdGUoIlJTQSIpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFg1MDlDZXJ0aWZpY2F0ZSBuZXdDZXJ0V2l0aE5hbWVDb25zdHJhaW50KGJ5dGVbXSBwZXJtaXR0ZWQsIGJ5dGVbXSBleGNsdWRlZCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0S2V5U3RvcmUgdGVzdEtleVN0b3JlID0gbmV3IFRlc3RLZXlTdG9yZS5CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuYWRkTmFtZUNvbnN0cmFpbnQodHJ1ZSwgcGVybWl0dGVkKQorICAgICAgICAgICAgICAgIC5hZGROYW1lQ29uc3RyYWludChmYWxzZSwgZXhjbHVkZWQpCisgICAgICAgICAgICAgICAgLmNhKHRydWUpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgICAgIHJldHVybiBib3VuY3ljYXN0bGVUb0phdmEodGVzdEtleVN0b3JlLmdldFJvb3RDZXJ0aWZpY2F0ZSgiUlNBIikpOworICAgIH0KKworICAgIHByaXZhdGUgWDUwOUNlcnRpZmljYXRlIGJvdW5jeWNhc3RsZVRvSmF2YShDZXJ0aWZpY2F0ZSBjZXJ0aWZpY2F0ZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBlbmNvZGVkID0gY2VydGlmaWNhdGUuZ2V0RW5jb2RlZCgpOworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgZmFjdG9yeSA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgcmV0dXJuIChYNTA5Q2VydGlmaWNhdGUpIGZhY3RvcnkuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZW5jb2RlZCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc3FsL09sZENvbm5lY3Rpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NxbC9PbGRDb25uZWN0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjBlZGVlMWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NxbC9PbGRDb25uZWN0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjE5MyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuc3FsOworCitpbXBvcnQgamF2YS5zcWwuQ2FsbGFibGVTdGF0ZW1lbnQ7CitpbXBvcnQgamF2YS5zcWwuQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhOworaW1wb3J0IGphdmEuc3FsLkRyaXZlck1hbmFnZXI7CitpbXBvcnQgamF2YS5zcWwuUHJlcGFyZWRTdGF0ZW1lbnQ7CitpbXBvcnQgamF2YS5zcWwuUmVzdWx0U2V0OworaW1wb3J0IGphdmEuc3FsLlNRTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5TUUxXYXJuaW5nOworaW1wb3J0IGphdmEuc3FsLlNhdmVwb2ludDsKK2ltcG9ydCBqYXZhLnNxbC5TdGF0ZW1lbnQ7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBPbGRDb25uZWN0aW9uVGVzdCBleHRlbmRzIE9sZFNRTFRlc3QgeworCisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZVN0YXRlbWVudCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdGF0ZW1lbnQgc3RhdGVtZW50ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzdGF0ZW1lbnQpOworICAgICAgICAvL2NoZWNrIGRlZmF1bHQgdmFsdWVzCisgICAgICAgIGFzc2VydEVxdWFscyhSZXN1bHRTZXQuRkVUQ0hfVU5LTk9XTiwgc3RhdGVtZW50LmdldEZldGNoRGlyZWN0aW9uKCkpOworICAgICAgICBhc3NlcnROdWxsKHN0YXRlbWVudC5nZXRXYXJuaW5ncygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzdGF0ZW1lbnQuZ2V0UXVlcnlUaW1lb3V0KCkgPiAwKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uY2xvc2UoKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlUXVlcnkoInNlbGVjdCAqIGZyb20gem9vIik7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biBhZnRlciBjbG9zZSIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFNjcm9sbGluZyBvbiBhIGZvcndhcmQgb25seSBSUyBub3QgYWxsb3dlZC4gY29ubi5jbG9zZSgpIGRvZXMgbm90IHdyYXAgdXAKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q3JlYXRlU3RhdGVtZW50X2ludF9pbnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzID0gbnVsbDsKKworICAgICAgICAvLyB0ZXN0IHJlYWQgb25seQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudChSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFksCisgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5DT05DVVJfUkVBRF9PTkxZKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCBpZCwgbmFtZSBmcm9tIHpvbyIpOworICAgICAgICAgICAgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcnMuZGVsZXRlUm93KCk7CisgICAgICAgICAgICAgICAgZmFpbCgiQ291bGQgZGVsZXRlIHJvdyBmb3IgUkVBRF9PTkxZIFJlc3VsdFNldCIpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBycy5jbG9zZSgpOworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3QgZm9yd2FyZCBvbmx5OiBzY3JvbGxpbmcgbm90IGFsbG93ZWQKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZLAorICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQuQ09OQ1VSX1JFQURfT05MWSk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgaWQsIG5hbWUgZnJvbSB6b28iKTsKKyAgICAgICAgICAgIHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJzLmFic29sdXRlKDEpOworICAgICAgICAgICAgICAgIHJzLnByZXZpb3VzKCk7CisgICAgICAgICAgICAgICAgZmFpbCgiQ291bGQgc2Nyb2xsIGJhY2t3YXJkcyIpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBycy5jbG9zZSgpOworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3QgZm9yd2FyZCBvbmx5CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KFJlc3VsdFNldC5UWVBFX0ZPUldBUkRfT05MWSwKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNPTkNVUl9SRUFEX09OTFkpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0IGlkLCBuYW1lIGZyb20gem9vIik7CisgICAgICAgICAgICBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBycy5sYXN0KCk7CisgICAgICAgICAgICAgICAgcnMuZmlyc3QoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJDb3VsZCBzY3JvbGwgYmFja3dhcmRzIik7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKworICAgICAgICAvLyB0ZXN0IHVwZGF0aW5nIFJlc3VsdFNldHMKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoUmVzdWx0U2V0LlRZUEVfU0NST0xMX0lOU0VOU0lUSVZFLAorICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQuQ09OQ1VSX1VQREFUQUJMRSk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgbmFtZSwgZmFtaWx5IGZyb20gem9vIik7CisgICAgICAgICAgICBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBycy5pbnNlcnRSb3coKTsKKyAgICAgICAgICAgICAgICBycy51cGRhdGVPYmplY3QoImZhbWlseSIsICJiaXJkIik7CisgICAgICAgICAgICAgICAgcnMubmV4dCgpOworICAgICAgICAgICAgICAgIHJzLnByZXZpb3VzKCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJwYXJyb3QiLCAocnMuZ2V0U3RyaW5nKDEpKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoUmVzdWx0U2V0LlRZUEVfU0NST0xMX1NFTlNJVElWRSwKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNPTkNVUl9VUERBVEFCTEUpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0IG5hbWUsIGZhbWlseSBmcm9tIHpvbyIpOworICAgICAgICAgICAgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcnMuaW5zZXJ0Um93KCk7CisgICAgICAgICAgICAgICAgcnMudXBkYXRlT2JqZWN0KCJmYW1pbHkiLCAiYmlyZCIpOworICAgICAgICAgICAgICAgIHJzLm5leHQoKTsKKyAgICAgICAgICAgICAgICBycy5wcmV2aW91cygpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiYmlyZCIsIChycy5nZXRTdHJpbmcoMSkpKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcnMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGV4Y2VwdGlvbiBpcyBub3Qgc3BlY2lmaWVkIGZvciB0aGlzIGNhc2UKKyAgICAgICAgICAgIGNvbm4uY3JlYXRlU3RhdGVtZW50KFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkUsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGlnYWwgYXJndW1lbnRzOiBzaG91bGQgcmV0dXJuIGV4Y2VwdGlvbi4iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAvLyBleGNlcHRpb24gaXMgbm90IHNwZWNpZmllZCBmb3IgdGhpcyBjYXNlCisgICAgICAgICAgICBjb25uLmNyZWF0ZVN0YXRlbWVudChJbnRlZ2VyLk1JTl9WQUxVRSwgUmVzdWx0U2V0LkNPTkNVUl9SRUFEX09OTFkpOworICAgICAgICAgICAgZmFpbCgiSWxsaWdhbCBhcmd1bWVudHM6IHNob3VsZCByZXR1cm4gZXhjZXB0aW9uLiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVTdGF0ZW1lbnRfaW50X2ludF9pbnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoY29ubik7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KFJlc3VsdFNldC5UWVBFX0ZPUldBUkRfT05MWSwKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNPTkNVUl9SRUFEX09OTFksCisgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5IT0xEX0NVUlNPUlNfT1ZFUl9DT01NSVQpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChzdCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgaWQsIG5hbWUgZnJvbSB6b28iKTsKKyAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgcnMubmV4dCgpOworICAgICAgICAgICAgaW50IHBvcyA9IHJzLmdldFJvdygpOworICAgICAgICAgICAgY29ubi5jb21taXQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiUmVzdWx0U2V0IGN1cnNvciBwb3NpdGlvbiBoYXMgY2hhbmdlZCIscG9zLCBycy5nZXRSb3coKSk7CisgICAgICAgICAgICBycy5jbG9zZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAoc3QgIT0gbnVsbCkgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uY3JlYXRlU3RhdGVtZW50KFJlc3VsdFNldC5UWVBFX0ZPUldBUkRfT05MWSwKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNPTkNVUl9SRUFEX09OTFksIC0xMDApOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBrbm93biBmYWlsdXJlOiBub3Qgc3VwcG9ydGVkCisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZVN0YXRlbWVudEludEludEludE5vdFN1cHBvcnRlZCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudChSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFksCisgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5DT05DVVJfUkVBRF9PTkxZLAorICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQuQ0xPU0VfQ1VSU09SU19BVF9DT01NSVQpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChzdCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgaWQsIG5hbWUgZnJvbSB6b28iKTsKKyAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoc3QgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gY29ubi5jbG9zZSgpIGRvZXMgbm90IHdyYXAgdXAKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TWV0YURhdGEoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgRGF0YWJhc2VNZXRhRGF0YSBtZCA9IGNvbm4uZ2V0TWV0YURhdGEoKTsKKyAgICAgICAgQ29ubmVjdGlvbiBjb24gPSBtZC5nZXRDb25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhjb25uLCBjb24pOworCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uZ2V0TWV0YURhdGEoKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgLy8gVE9ETyBjbGVhcldhcm5pbmdzIGlzIG5vdCBzdXBwb3J0ZWQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xlYXJXYXJuaW5ncygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTUUxXYXJuaW5nIHcgPSBjb25uLmdldFdhcm5pbmdzKCk7CisgICAgICAgIGFzc2VydE51bGwodyk7CisKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCBhbmltYWxzIGZyb20gem9vIik7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoY29ubi5nZXRXYXJuaW5ncygpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgY29ubi5jbGVhcldhcm5pbmdzKCk7CisgICAgICAgIHcgPSBjb25uLmdldFdhcm5pbmdzKCk7CisgICAgICAgIGFzc2VydE51bGwodyk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCBtb25rZXkgZnJvbSB6b28iKTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJTUUxpdGUuRXhjZXB0aW9uOiBlcnJvciBpbiBwcmVwYXJlL2NvbXBpbGUiLGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy9UZXN0IGZvciBjb3JyZWN0IGZ1bmN0aW9uYWxpdHkKKyAgICAgICAgdyA9IGNvbm4uZ2V0V2FybmluZ3MoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh3KTsKKworICAgICAgICBjb25uLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLmNsZWFyV2FybmluZ3MoKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisKKyAgICB9CisKKworICAgIC8vIFRPRE8gR2V0V2FybmluZ3MgaXMgbm90IHN1cHBvcnRlZDogcmV0dXJucyBudWxsCisgICAgcHVibGljIHZvaWQgdGVzdEdldFdhcm5pbmdzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgIGludCBlcnJvckNvZGUxID0gLTE7CisgICAgICAgIGludCBlcnJvckNvZGUyID0gLTE7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCBhbmltYWxzIGZyb20gem9vb28iKTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIGVycm9yQ29kZTEgPSBlLmdldEVycm9yQ29kZSgpOworICAgICAgICB9CisKKyAgICAgICAgU1FMV2FybmluZyB3cnMgPSBjb25uLmdldFdhcm5pbmdzKCk7CisgICAgICAgIGFzc2VydE51bGwod3JzKTsKKworICAgICAgICAvLyB0ZXN0cyBpbXBsZW1lbnRhdGlvbjogYnV0IGVycm9yY29kZXMgbmVlZCB0byBjaGFuZ2UgdG9vIC0+IGNoYW5nZSBpbXBsLgorICAgICAgICAvKgorICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICBpbnQgZXJyb3JDb2RlMSA9IC0xOworICAgICAgICBpbnQgZXJyb3JDb2RlMiA9IC0xOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgYW5pbWFscyBmcm9tIHpvb29vIik7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICBlcnJvckNvZGUxID0gZS5nZXRFcnJvckNvZGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTUUxXYXJuaW5nIHdycyA9IGNvbm4uZ2V0V2FybmluZ3MoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwod3JzKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhlcnJvckNvZGUxLCB3cnMuZ2V0RXJyb3JDb2RlKCkpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCh3cnMuZ2V0TmV4dFdhcm5pbmcoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIEV4Y2VwdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0IGhvcnNlIGZyb20gem9vb29vbyIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIGVycm9yQ29kZTIgPSBlLmdldEVycm9yQ29kZSgpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNRTFdhcm5pbmcgd3JzID0gY29ubi5nZXRXYXJuaW5ncygpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGVycm9yQ29kZTEsIHdycy5nZXRFcnJvckNvZGUoKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHdycy5nZXROZXh0V2FybmluZygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhlcnJvckNvZGUyLCB3cnMuZ2V0RXJyb3JDb2RlKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBFeGNlcHRpb246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgIH0KKworICAgICAgICAqLworCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uZ2V0V2FybmluZ3MoKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEF1dG9Db21taXQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgY29ubi5zZXRBdXRvQ29tbWl0KHRydWUpOworICAgICAgICBhc3NlcnRUcnVlKGNvbm4uZ2V0QXV0b0NvbW1pdCgpKTsKKyAgICAgICAgY29ubi5zZXRBdXRvQ29tbWl0KGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoY29ubi5nZXRBdXRvQ29tbWl0KCkpOworICAgICAgICBjb25uLnNldEF1dG9Db21taXQodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoY29ubi5nZXRBdXRvQ29tbWl0KCkpOworICAgIH0KKworICAgIC8vIGNvbm4uY2xvc2UoKSBkb2VzIG5vdCB3cmFwIHVwCisgICAgcHVibGljIHZvaWQgdGVzdFNldEF1dG9Db21taXQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzMSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnNldEF1dG9Db21taXQodHJ1ZSk7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoMywgJ0NoaWNoaWNoaScsICdtb25rZXknKTsiKTsKKyAgICAgICAgICAgIGNvbm4uY29tbWl0KCk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAgLy8gZXZlbiB0aG91Z2ggZXhjZXB0aW9uIHdhcyB0aHJvd24gdmFsdWUgaXMgY29tbWl0dGVkCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHpvbyIpOworICAgICAgICAgICAgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygzLCBnZXRDb3VudChycykpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnNldEF1dG9Db21taXQoZmFsc2UpOworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDQsICdCdXJlbmthJywgJ2NvdycpOyIpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28iKTsKKyAgICAgICAgICAgIHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIGNvbm4uY29tbWl0KCk7CisgICAgICAgICAgICAvLyBDaGVjayBjdXJzb3JzIGNsb3NlZCBhZnRlciBjb21taXQKKyAgICAgICAgICAgIHJzMSA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGdldENvdW50KHJzMSkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBycy5jbG9zZSgpOworICAgICAgICAgICAgICAgIHJzMS5jbG9zZSgpOworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5zZXRBdXRvQ29tbWl0KHRydWUpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBjb25uLmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cAorICAgIHB1YmxpYyB2b2lkIHRlc3RJc1JlYWRPbmx5KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGNvbm4uc2V0UmVhZE9ubHkodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoY29ubi5pc1JlYWRPbmx5KCkpOworICAgICAgICBjb25uLnNldFJlYWRPbmx5KGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoY29ubi5pc1JlYWRPbmx5KCkpOworCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uaXNSZWFkT25seSgpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBub3Qgc3VwcG9ydGVkCisgICAgcHVibGljIHZvaWQgdGVzdFNldFJlYWRPbmx5KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisKKyAgICAgICAgLy8gUHNldWRvIHRlc3Q6IG5vdCBzdXBwb3J0ZWQgdGVzdAorICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5zZXRSZWFkT25seSh0cnVlKTsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGUoImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICgzLCAnQ2hpQ2hpQ2hpJywgJ21vbmtleScpOyIpOworICAgICAgICAgICAvLyBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyB0ZXN0IGZvciBjb3JyZWN0IGltcGxlbWVudGF0aW9uCisgICAgICAgIHN0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uc2V0UmVhZE9ubHkodHJ1ZSk7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoMywgJ0NoaUNoaUNoaScsICdtb25rZXknKTsiKTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5zZXRSZWFkT25seSh0cnVlKTsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGVVcGRhdGUoImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICg0LCAnQ2hhQ2hhQ2hhJywgJ21vbmtleScpOyIpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnNldFJlYWRPbmx5KGZhbHNlKTsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGUoImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICg0LCAnQ2hpQ2hpQ2hpJywgJ21vbmtleScpOyIpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBjb25uLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnNldFJlYWRPbmx5KHRydWUpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBUT0RPIFJlc3VsdFNldC5DTE9TRV9DVVJTT1JTX0FUX0NPTU1JVCBpcyBub3Qgc3VwcG9ydGVkCisgICAgcHVibGljIHZvaWQgdGVzdEdldEhvbGRhYmlsaXR5KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGNvbm4uc2V0SG9sZGFiaWxpdHkoUmVzdWx0U2V0LkhPTERfQ1VSU09SU19PVkVSX0NPTU1JVCk7CisgICAgICAgIGFzc2VydEVxdWFscyhSZXN1bHRTZXQuSE9MRF9DVVJTT1JTX09WRVJfQ09NTUlULCBjb25uLmdldEhvbGRhYmlsaXR5KCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnNldEhvbGRhYmlsaXR5KFJlc3VsdFNldC5DTE9TRV9DVVJTT1JTX0FUX0NPTU1JVCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoUmVzdWx0U2V0LkNMT1NFX0NVUlNPUlNfQVRfQ09NTUlULCBjb25uCisgICAgICAgICAgICAgICAgICAgIC5nZXRIb2xkYWJpbGl0eSgpKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygibm90IHN1cHBvcnRlZCIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEV4Y2VwdGlvbiBjaGVja2luZworCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5nZXRIb2xkYWJpbGl0eSgpOworICAgICAgICAgICAgZmFpbCgiQ291bGQgZXhlY3V0ZSBzdGF0ZW1lbnQgb24gY2xvc2VkIGNvbm5lY3Rpb24uIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBUT0RPIFJlc3VsdFNldC5DTE9TRV9DVVJTT1JTX0FUX0NPTU1JVCBpcyBub3Qgc3VwcG9ydGVkCisgICAgcHVibGljIHZvaWQgdGVzdFNldEhvbGRhYmlsaXR5KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnNldEF1dG9Db21taXQoZmFsc2UpOworICAgICAgICAgICAgY29ubi5zZXRIb2xkYWJpbGl0eShSZXN1bHRTZXQuQ0xPU0VfQ1VSU09SU19BVF9DT01NSVQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFJlc3VsdFNldC5DTE9TRV9DVVJTT1JTX0FUX0NPTU1JVCwgY29ubgorICAgICAgICAgICAgICAgICAgLmdldEhvbGRhYmlsaXR5KCkpOworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDQsICdDaGlDaGlDaGknLCAnbW9ua2V5Jyk7Iik7CisgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgIGNvbm4uY29tbWl0KCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJzLm5leHQoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy9vaworICAgICAgICAgICAgfQorICAgICAgICAgICAgY29ubi5zZXRIb2xkYWJpbGl0eShSZXN1bHRTZXQuSE9MRF9DVVJTT1JTX09WRVJfQ09NTUlUKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhSZXN1bHRTZXQuSE9MRF9DVVJTT1JTX09WRVJfQ09NTUlULCBjb25uCisgICAgICAgICAgICAgICAgICAgIC5nZXRIb2xkYWJpbGl0eSgpKTsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGUoImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICg0LCAnQ2hpQ2hpQ2hpJywgJ21vbmtleScpOyIpOworICAgICAgICAgICAgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgIGNvbm4uY29tbWl0KCk7CisgICAgICAgICAgICBycy5uZXh0KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnNldEhvbGRhYmlsaXR5KC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLy8gVE9ETyBvbmx5IENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fU0VSSUFMSVpBQkxFIGlzIHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRUcmFuc2FjdGlvbklzb2xhdGlvbigpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBjb25uLnNldFRyYW5zYWN0aW9uSXNvbGF0aW9uKENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fUkVBRF9VTkNPTU1JVFRFRCk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1JFQURfVU5DT01NSVRURUQsIGNvbm4KKyAgICAgICAgICAgICAgICAuZ2V0VHJhbnNhY3Rpb25Jc29sYXRpb24oKSk7CisgICAgICAgIGNvbm4uc2V0VHJhbnNhY3Rpb25Jc29sYXRpb24oQ29ubmVjdGlvbi5UUkFOU0FDVElPTl9SRUFEX0NPTU1JVFRFRCk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1JFQURfQ09NTUlUVEVELCBjb25uCisgICAgICAgICAgICAgICAgLmdldFRyYW5zYWN0aW9uSXNvbGF0aW9uKCkpOworICAgICAgICBjb25uLnNldFRyYW5zYWN0aW9uSXNvbGF0aW9uKENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fUkVQRUFUQUJMRV9SRUFEKTsKKyAgICAgICBhc3NlcnRFcXVhbHMoQ29ubmVjdGlvbi5UUkFOU0FDVElPTl9SRVBFQVRBQkxFX1JFQUQsIGNvbm4KKyAgICAgICAgICAgICAgICAuZ2V0VHJhbnNhY3Rpb25Jc29sYXRpb24oKSk7CisgICAgICAgIGNvbm4uc2V0VHJhbnNhY3Rpb25Jc29sYXRpb24oQ29ubmVjdGlvbi5UUkFOU0FDVElPTl9TRVJJQUxJWkFCTEUpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29ubmVjdGlvbi5UUkFOU0FDVElPTl9TRVJJQUxJWkFCTEUsIGNvbm4KKyAgICAgICAgICAgICAgICAuZ2V0VHJhbnNhY3Rpb25Jc29sYXRpb24oKSk7CisKKyAgICAgICAgLy8gRXhjZXB0aW9uIGNoZWNraW5nCisKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLmdldFRyYW5zYWN0aW9uSXNvbGF0aW9uKCk7CisgICAgICAgICAgICBmYWlsKCJDb3VsZCBleGVjdXRlIHN0YXRlbWVudCBvbiBjbG9zZWQgY29ubmVjdGlvbi4iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRPRE8gb25seSBDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1NFUklBTElaQUJMRSBpcyBzdXBwb3J0ZWQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VHJhbnNhY3Rpb25Jc29sYXRpb25Ob3RTdXBwb3J0ZWQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgIC8qCisgICAgICB0cnkgeworICAgICAgICAgIGNvbm4KKyAgICAgICAgICAgICAgICAgIC5zZXRUcmFuc2FjdGlvbklzb2xhdGlvbihDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1JFQURfVU5DT01NSVRURUQpOworICAgICAgICAgIGFzc2VydEVxdWFscyhDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1JFQURfVU5DT01NSVRURUQsIGNvbm4KKyAgICAgICAgICAgICAgICAgIC5nZXRUcmFuc2FjdGlvbklzb2xhdGlvbigpKTsKKyAgICAgICAgICBjb25uLnNldFRyYW5zYWN0aW9uSXNvbGF0aW9uKENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fUkVBRF9DT01NSVRURUQpOworICAgICAgICAgIGFzc2VydEVxdWFscyhDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1JFQURfQ09NTUlUVEVELCBjb25uCisgICAgICAgICAgICAgICAgICAuZ2V0VHJhbnNhY3Rpb25Jc29sYXRpb24oKSk7CisgICAgICAgICAgY29ubgorICAgICAgICAgICAgICAgICAgLnNldFRyYW5zYWN0aW9uSXNvbGF0aW9uKENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fUkVQRUFUQUJMRV9SRUFEKTsKKyAgICAgICAgIGFzc2VydEVxdWFscyhDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1JFUEVBVEFCTEVfUkVBRCwgY29ubgorICAgICAgICAgICAgICAgICAgLmdldFRyYW5zYWN0aW9uSXNvbGF0aW9uKCkpOworICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgdGhyb3duOiAiICsgc3FsZS50b1N0cmluZygpKTsKKyAgICAgIH0KKyAgICAgICovCisgICAgfQorCisgICAgLy8gVE9ETyBvbmx5IENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fU0VSSUFMSVpBQkxFIGlzIHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRUcmFuc2FjdGlvbklzb2xhdGlvbigpIHRocm93cyBTUUxFeGNlcHRpb24geworLy8gICAgICAgICAgICBjb25uCisvLyAgICAgICAgICAgICAgICAgIC5zZXRUcmFuc2FjdGlvbklzb2xhdGlvbihDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1JFQURfVU5DT01NSVRURUQpOworLy8gICAgICAgICAgICBhc3NlcnRFcXVhbHMoQ29ubmVjdGlvbi5UUkFOU0FDVElPTl9SRUFEX1VOQ09NTUlUVEVELCBjb25uCisvLyAgICAgICAgICAgICAgICAgICAgLmdldFRyYW5zYWN0aW9uSXNvbGF0aW9uKCkpOworLy8gICAgICAgICAgICBjb25uLnNldFRyYW5zYWN0aW9uSXNvbGF0aW9uKENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fUkVBRF9DT01NSVRURUQpOworLy8gICAgICAgICAgICBhc3NlcnRFcXVhbHMoQ29ubmVjdGlvbi5UUkFOU0FDVElPTl9SRUFEX0NPTU1JVFRFRCwgY29ubgorLy8gICAgICAgICAgICAgICAgICAgIC5nZXRUcmFuc2FjdGlvbklzb2xhdGlvbigpKTsKKy8vICAgICAgICAgICAgY29ubgorLy8gICAgICAgICAgICAgICAgICAgIC5zZXRUcmFuc2FjdGlvbklzb2xhdGlvbihDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1JFUEVBVEFCTEVfUkVBRCk7CisvLyAgICAgICAgICAgIGFzc2VydEVxdWFscyhDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1JFUEVBVEFCTEVfUkVBRCwgY29ubgorLy8gICAgICAgICAgICAgICAgICAgIC5nZXRUcmFuc2FjdGlvbklzb2xhdGlvbigpKTsKKyAgICAgICAgY29ubi5zZXRUcmFuc2FjdGlvbklzb2xhdGlvbihDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1NFUklBTElaQUJMRSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1NFUklBTElaQUJMRSwgY29ubi5nZXRUcmFuc2FjdGlvbklzb2xhdGlvbigpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5zZXRUcmFuc2FjdGlvbklzb2xhdGlvbigwKTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLy8gVE9ETyBzZXRDYXRhbG9nIG1ldGhvZCBkb2VzIG5vdGhpbmc6IEhpbnQgZGVmYXVsdCBjYXRhbG9nIHNxbGl0ZV9tYXN0ZXIuCisgICAgcHVibGljIHZvaWQgdGVzdFNldENhdGFsb2coKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nW10gY2F0YWxvZ3MgPSB7ICJ0ZXN0IiwgInRlc3QxIiwgInRlc3QiIH07CisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNhdGFsb2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgY29ubi5zZXRDYXRhbG9nKGNhdGFsb2dzW2ldKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGNhdGFsb2dzW2ldLCBjb25uLmdldENhdGFsb2coKSk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0CisgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKCJjcmVhdGUgdGFibGUgdGVzdF90YWJsZSAoaWQgaW50ZWdlciBub3QgbnVsbCwgbmFtZSB2YXJjaGFyKDIwKSwgcHJpbWFyeSBrZXkoaWQpKTsiKTsKKyAgICAgICAgICAgICAgICBzdC5lcXVhbHMoImRyb3AgdGFibGUgdGVzdF90YWJsZTsiKTsKKworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICBTdHJpbmdbXSBjYXRhbG9ncyA9IHsgInRlc3QifTsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2F0YWxvZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBjb25uLnNldENhdGFsb2coY2F0YWxvZ3NbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoImlsbGVnYWwgY2F0YWxvZyBuYW1lIik7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGNhdGFsb2dzW2ldLCBjb25uLmdldENhdGFsb2coKSk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0CisgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKCJjcmVhdGUgdGFibGUgdGVzdF90YWJsZSAoaWQgaW50ZWdlciBub3QgbnVsbCwgbmFtZSB2YXJjaGFyKDIwKSwgcHJpbWFyeSBrZXkoaWQpKTsiKTsKKyAgICAgICAgICAgICAgICBzdC5lcXVhbHMoImRyb3AgdGFibGUgdGVzdF90YWJsZTsiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVE9ETzogVGVzdCBmb3IgY29ycmVjdCBlcnJvciBtZXNzYWdlOiBuYW1lIHdpdGggLFwic3FsaXRlX1wiIHByZWZpeCBleHBlY3RlZCIpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdbXSBjYXRhbG9ncyA9IHsgInNxbGl0ZV90ZXN0IiwgInNxbGl0ZV90ZXN0MSIsICJzcWxpdGVfdGVzdCIgfTsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2F0YWxvZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBjb25uLnNldENhdGFsb2coY2F0YWxvZ3NbaV0pOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhjYXRhbG9nc1tpXSwgY29ubi5nZXRDYXRhbG9nKCkpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdAorICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscygiY3JlYXRlIHRhYmxlIHRlc3RfdGFibGUgKGlkIGludGVnZXIgbm90IG51bGwsIG5hbWUgdmFyY2hhcigyMCksIHByaW1hcnkga2V5KGlkKSk7Iik7CisgICAgICAgICAgICAgICAgc3QuZXF1YWxzKCJkcm9wIHRhYmxlIHRlc3RfdGFibGU7Iik7CisKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd24iKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uc2V0Q2F0YWxvZyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uc2V0Q2F0YWxvZygibm90X2V4aXN0Iik7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICAqLworICAgIH0KKworICAgIC8vIG5vdCBzdXBwb3J0ZWQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q2F0YWxvZygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAvLyB0ZXN0IGRlZmF1bHQgY2F0YWxvZworICAgICAgICBhc3NlcnRFcXVhbHMoInNxbGl0ZV9tYXN0ZXIiLCBjb25uLmdldENhdGFsb2coKSk7CisKKyAgICAgICAgU3RyaW5nW10gY2F0YWxvZ3MgPSB7ICJzcWxpdGVfdGVzdCIsICJzcWxpdGVfdGVzdDEiLCAic3FsaXRlX3Rlc3QiIH07CisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2F0YWxvZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNvbm4uc2V0Q2F0YWxvZyhjYXRhbG9nc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKGNvbm4uZ2V0Q2F0YWxvZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEV4Y2VwdGlvbiBjaGVja2luZworCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5nZXRDYXRhbG9nKCk7CisgICAgICAgICAgICBmYWlsKCJDb3VsZCBleGVjdXRlIHN0YXRlbWVudCBvbiBjbG9zZWQgY29ubmVjdGlvbi4iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRPRE8gc2V0VHlwZU1hcCBpcyBub3Qgc3VwcG9ydGVkCisgICAgcHVibGljIHZvaWQgdGVzdFNldFR5cGVNYXAoKSB7CisgICAgICAgIC8qCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBqYXZhLnV0aWwuTWFwIG1hcCA9IGNvbm4uZ2V0VHlwZU1hcCgpOworICAgICAgICAgICAgbWFwCisgICAgICAgICAgICAgICAgICAgIC5wdXQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5zcWwudGVzdHMuamF2YS5zcWwuVGVzdEhlbHBlcl9Db25uZWN0aW9uMSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MuZm9yTmFtZSgiVGVzdEhlbHBlcl9Db25uZWN0aW9uMSIpKTsKKyAgICAgICAgICAgIGNvbm4uc2V0VHlwZU1hcChtYXApOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG1hcCwgY29ubi5nZXRUeXBlTWFwKCkpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBFeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnNldFR5cGVNYXAobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICAqLworICAgIH0KKworICAgIC8vIFRPRE8gZ2V0VHlwZU1hcCBpcyBub3Qgc3VwcG9ydGVkCisgICAgcHVibGljIHZvaWQgdGVzdEdldFR5cGVNYXAoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgLyoKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGphdmEudXRpbC5NYXAgbWFwID0gY29ubi5nZXRUeXBlTWFwKCk7CisgICAgICAgICAgICBtYXAKKyAgICAgICAgICAgICAgICAgICAgLnB1dCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3JnLmFwYWNoZS5oYXJtb255LnNxbC50ZXN0cy5qYXZhLnNxbC5UZXN0SGVscGVyX0Nvbm5lY3Rpb24xIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzcy5mb3JOYW1lKCJUZXN0SGVscGVyX0Nvbm5lY3Rpb24xIikpOworICAgICAgICAgICAgY29ubi5zZXRUeXBlTWFwKG1hcCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobWFwLCBjb25uLmdldFR5cGVNYXAoKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIEV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKy8vIEV4Y2VwdGlvbiBjaGVja2luZworCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5zZXRUeXBlTWFwKG51bGwpOworICAgICAgICAgICAgZmFpbCgiQ291bGQgZXhlY3V0ZSBzdGF0ZW1lbnQgb24gY2xvc2VkIGNvbm5lY3Rpb24uIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICAgICAgKi8KKyAgICB9CisKKyAgICAvLyBUT0RPIG5hdGl2ZVNRTCBpcyBub3Qgc3VwcG9ydGVkCisgICAgcHVibGljIHZvaWQgdGVzdE5hdGl2ZVNRTCgpIHRocm93cyBTUUxFeGNlcHRpb257CisgICAgICAgIFN0cmluZ1tdIHF1ZXJpZXMgPSB7CisgICAgICAgICAgICAgICAgInNlbGVjdCAqIGZyb20gem9vOyIsCisgICAgICAgICAgICAgICAgImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICgzLCAnQ2hpY2hpY2hpJywgJ21vbmtleScpOyIsCisgICAgICAgICAgICAgICAgImNyZWF0ZSB0YWJsZSB6b29fb2ZmaWNlKGlkIGludGVnZXIgbm90IG51bGwsIG5hbWUgdmFyY2hhcigyMCksIHByaW1hcnkga2V5KGlkKSk7IiwKKyAgICAgICAgICAgICAgICAiZHJvcCB0YWJsZSB6b29fb2ZmaWNlOyIgfTsKKyAgICAgICAgU3RyaW5nW10gbmF0aXZlX3F1ZXJpZXMgPSB7CisgICAgICAgICAgICAgICAgInNlbGVjdCAqIGZyb20gem9vOyIsCisgICAgICAgICAgICAgICAgImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICgzLCAnQ2hpY2hpY2hpJywgJ21vbmtleScpOyIsCisgICAgICAgICAgICAgICAgImNyZWF0ZSB0YWJsZSB6b29fb2ZmaWNlKGlkIGludGVnZXIgbm90IG51bGwsIG5hbWUgdmFyY2hhcigyMCksIHByaW1hcnkga2V5KGlkKSk7IiwKKyAgICAgICAgICAgICAgICAiZHJvcCB0YWJsZSB6b29fb2ZmaWNlOyIgfTsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgU3RyaW5nIG5hdGl2ZVF1ZXJ5ID0gIiI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHF1ZXJpZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBuYXRpdmVRdWVyeSA9IGNvbm4ubmF0aXZlU1FMKHF1ZXJpZXNbaV0pOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhuYXRpdmVfcXVlcmllc1tpXSwgbmF0aXZlUXVlcnkpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKG5hdGl2ZVF1ZXJ5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nW10gaW5jX3F1ZXJpZXMgPSB7ICIiLCAiICAiLCAibm90IHF1ZXJ5IiB9OworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGluY19xdWVyaWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG5hdGl2ZVF1ZXJ5ID0gY29ubi5uYXRpdmVTUUwoaW5jX3F1ZXJpZXNbaV0pOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhpbmNfcXVlcmllc1tpXSwgbmF0aXZlUXVlcnkpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIm5vdCBzdXBwb3J0ZWQiLGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIEV4Y2VwdGlvbiBjaGVja2luZworCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5uYXRpdmVTUUwoaW5jX3F1ZXJpZXNbMF0pOworICAgICAgICAgICAgZmFpbCgiQ291bGQgZXhlY3V0ZSBzdGF0ZW1lbnQgb24gY2xvc2VkIGNvbm5lY3Rpb24uIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBUT0RPIHByZXBhcmVDYWxsIGlzIG5vdCBzdXBwb3J0ZWQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJlcGFyZUNhbGwoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgQ2FsbGFibGVTdGF0ZW1lbnQgY3N0bXQgPSBudWxsOworICAgICAgICBSZXN1bHRTZXQgcnMgPSBudWxsOworICAgICAgICBSZXN1bHRTZXQgcnMxID0gbnVsbDsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgU3RhdGVtZW50IHN0MSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjc3RtdCA9IGNvbm4ucHJlcGFyZUNhbGwoImNhbGwgd2VsY29tZUFuaW1hbCgzLCAnUGV0eWEnLCAnQ29jaycpIik7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHpvbyIpOworICAgICAgICAgICAgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygyLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgY3N0bXQuZXhlY3V0ZSgpOworICAgICAgICAgICAgc3QxID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0MS5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHpvbyIpOworICAgICAgICAgICAgcnMxID0gc3QxLmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGdldENvdW50KHJzMSkpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vayBub3Qgc3VwcG9ydGVkCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgc3QxLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgcnMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICByczEuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBjc3RtdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnByZXBhcmVDYWxsKCJ3ZWxjb21lQW5pbWFsKDQsICdQZXR5YScsICdDb2NrJykiKTsKKyAgICAgICAgICAgIGZhaWwoIlNRTCBFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnByZXBhcmVDYWxsKG51bGwpOworICAgICAgICAgICAgZmFpbCgiU1FMIEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gRXhjZXB0aW9uIGNoZWNraW5nCisKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnByZXBhcmVDYWxsKCIiKTsKKyAgICAgICAgICAgIGZhaWwoIkNvdWxkIGV4ZWN1dGUgc3RhdGVtZW50IG9uIGNsb3NlZCBjb25uZWN0aW9uLiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvLyBUT0RPIHByZXBhcmVDYWxsIGlzIG5vdCBzdXBwb3J0ZWQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJlcGFyZUNhbGxfU3RyaW5nX2ludF9pbnQoKSB7CisgICAgICAgIENhbGxhYmxlU3RhdGVtZW50IGNzdG10ID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzID0gbnVsbDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImNhbGwgd2VsY29tZUFuaW1hbCgzLCAnUGV0eWEnLCAnQ29jaycpIjsKKyAgICAgICAgICAgIGNzdG10ID0gY29ubi5wcmVwYXJlQ2FsbChxdWVyeSwgUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZLAorICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQuQ09OQ1VSX1JFQURfT05MWSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImNhbGwgd2VsY29tZUFuaW1hbCgzLCAnUGV0eWEnLCAnRGlubycpIjsKKyAgICAgICAgICAgIGNzdG10ID0gY29ubi5wcmVwYXJlQ2FsbChxdWVyeSwgUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZLAorICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQuQ09OQ1VSX1JFQURfT05MWSk7CisgICAgICAgICAgICBjc3RtdC5leGVjdXRlKCJzZWxlY3QgaWQsIG5hbWUgZnJvbSB6b28iKTsKKyAgICAgICAgICAgIHJzID0gY3N0bXQuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJzLmRlbGV0ZVJvdygpOworICAgICAgICAgICAgICAgIGZhaWwoIkNhbiBkZWxldGUgcm93IGZvciBSRUFEX09OTFkgUmVzdWx0U2V0Iik7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcnMuYWJzb2x1dGUoMCk7CisgICAgICAgICAgICAgICAgZmFpbCgiQ2FuIG1vdmUgY3Vyc29yIHRvIHRoZSBsYXN0IHBvc2l0aW9uIGZvciBUWVBFX0ZPUldBUkRfT05MWSBSZXN1bHRTZXQiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIHdhcyB0aHJvd246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgY3N0bXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KFJlc3VsdFNldC5UWVBFX1NDUk9MTF9JTlNFTlNJVElWRSwKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNPTkNVUl9VUERBVEFCTEUpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0IG5hbWUsIGZhbWlseSBmcm9tIHpvbyIpOworICAgICAgICAgICAgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcnMuaW5zZXJ0Um93KCk7CisgICAgICAgICAgICAgICAgcnMudXBkYXRlT2JqZWN0KCJmYW1pbHkiLCAiYmlyZCIpOworICAgICAgICAgICAgICAgIHJzLm5leHQoKTsKKyAgICAgICAgICAgICAgICBycy5wcmV2aW91cygpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygicGFycm90IiwgKHJzLmdldFN0cmluZygxKSkpOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorCisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gd2FzIHRocm93bjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcnMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudChSZXN1bHRTZXQuVFlQRV9TQ1JPTExfU0VOU0lUSVZFLAorICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQuQ09OQ1VSX1VQREFUQUJMRSk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgbmFtZSwgZmFtaWx5IGZyb20gem9vIik7CisgICAgICAgICAgICBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBycy5pbnNlcnRSb3coKTsKKyAgICAgICAgICAgICAgICBycy51cGRhdGVPYmplY3QoImZhbWlseSIsICJiaXJkIik7CisgICAgICAgICAgICAgICAgcnMubmV4dCgpOworICAgICAgICAgICAgICAgIHJzLnByZXZpb3VzKCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJiaXJkIiwgKHJzLmdldFN0cmluZygxKSkpOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorCisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gd2FzIHRocm93bjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcnMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5jcmVhdGVTdGF0ZW1lbnQoUmVzdWx0U2V0LlRZUEVfU0NST0xMX1NFTlNJVElWRSwgLTEpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uY3JlYXRlU3RhdGVtZW50KEludGVnZXIuTUlOX1ZBTFVFLCBSZXN1bHRTZXQuQ09OQ1VSX1JFQURfT05MWSk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAqLworICAgIH0KKworICAgIC8vIFRPRE8gcHJlcGFyZUNhbGwgaXMgbm90IHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RQcmVwYXJlQ2FsbF9TdHJpbmdfaW50X2ludF9pbnQoKSB7CisgICAgICAgIENhbGxhYmxlU3RhdGVtZW50IGNzdG10ID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzID0gbnVsbDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImNhbGwgd2VsY29tZUFuaW1hbCg/LCA/LCA/KSI7CisgICAgICAgICAgICBjc3RtdCA9IGNvbm4ucHJlcGFyZUNhbGwocXVlcnksIFJlc3VsdFNldC5UWVBFX0ZPUldBUkRfT05MWSwKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNPTkNVUl9SRUFEX09OTFksCisgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5IT0xEX0NVUlNPUlNfT1ZFUl9DT01NSVQpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgICAgIC8qCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgcXVlcnkgPSAiY2FsbCB3ZWxjb21lQW5pbWFsKD8sID8sID8pIjsKKyAgICAgICAgICAgIGNzdG10ID0gY29ubi5wcmVwYXJlQ2FsbChxdWVyeSwgUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZLAorICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQuQ09OQ1VSX1JFQURfT05MWSwKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkhPTERfQ1VSU09SU19PVkVSX0NPTU1JVCk7CisgICAgICAgICAgICBjc3RtdC5zZXRJbnQoMSwgMyk7CisgICAgICAgICAgICBjc3RtdC5zZXRTdHJpbmcoMiwgIlBldHlhIik7CisgICAgICAgICAgICBjc3RtdC5zZXRTdHJpbmcoMywgIkNvY2siKTsKKyAgICAgICAgICAgIGNzdG10LmV4ZWN1dGUoInNlbGVjdCBpZCwgbmFtZSBmcm9tIHpvbyIpOworICAgICAgICAgICAgcnMgPSBjc3RtdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcnMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gd2FzIHRocm93biBkdXJpbmcgY2xvc2luZyBSZXN1bHRTZXQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiB3YXMgdGhyb3duOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBycy5jbG9zZSgpOworICAgICAgICAgICAgICAgIGNzdG10LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZLAorICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQuQ09OQ1VSX1JFQURfT05MWSwKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNMT1NFX0NVUlNPUlNfQVRfQ09NTUlUKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCBpZCwgbmFtZSBmcm9tIHpvbyIpOworICAgICAgICAgICAgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcnMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiB3YXMgdGhyb3duOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uY3JlYXRlU3RhdGVtZW50KFJlc3VsdFNldC5UWVBFX0ZPUldBUkRfT05MWSwKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNPTkNVUl9SRUFEX09OTFksIC0xMDApOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgICovCisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJlcGFyZVN0YXRlbWVudCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcnN0ID0gbnVsbDsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzMSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgdXBkYXRlID0gInVwZGF0ZSB6b28gc2V0IGZhbWlseSA9ID8gd2hlcmUgbmFtZSA9ID87IjsKKyAgICAgICAgICAgIHByc3QgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQodXBkYXRlKTsKKyAgICAgICAgICAgIHByc3Quc2V0U3RyaW5nKDEsICJjYXQiKTsKKyAgICAgICAgICAgIHByc3Quc2V0U3RyaW5nKDIsICJZYXNoYSIpOworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28gd2hlcmUgZmFtaWx5ID0gJ2NhdCciKTsKKyAgICAgICAgICAgIHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIHByc3QuZXhlY3V0ZVVwZGF0ZSgpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28gd2hlcmUgZmFtaWx5ID0gJ2NhdCciKTsKKyAgICAgICAgICAgIHJzMSA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdldENvdW50KHJzMSkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBycy5jbG9zZSgpOworICAgICAgICAgICAgICAgIHJzMS5jbG9zZSgpOworICAgICAgICAgICAgICAgIHByc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJzdCA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudCgiIik7CisgICAgICAgICAgICBwcnN0LmV4ZWN1dGUoKTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5wcmVwYXJlU3RhdGVtZW50KG51bGwpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRPRE8gQ3Jhc2hlcyBWTS4gRml4IGxhdGVyLgorICAgIHB1YmxpYyB2b2lkIHRlc3RQcmVwYXJlU3RhdGVtZW50X1N0cmluZ19pbnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHJzdCA9IG51bGw7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHByc3QxID0gbnVsbDsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzMSA9IG51bGw7CisgICAgICAgIFJlc3VsdFNldCByczQgPSBudWxsOworICAgICAgICBSZXN1bHRTZXQgcnM1ID0gbnVsbDsKKworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgaW5zZXJ0ID0gImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICg/LCA/LCA/KTsiOworICAgICAgICAgICAgcHJzdCA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChpbnNlcnQsCisgICAgICAgICAgICAgICAgICAgIFN0YXRlbWVudC5SRVRVUk5fR0VORVJBVEVEX0tFWVMpOworICAgICAgICAgICAgZmFpbCgiRmFpbDogcHJlcGFyZVN0YXRlbWVudCBkb2VzIG5vdCBmYWlsIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgLy9vayBub3Qgc3VwcG9ydGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIGluc2VydCA9ICJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoPywgPywgPyk7IjsKKworICAgICAgICAgICAgcHJzdCA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChpbnNlcnQsCisgICAgICAgICAgICAgICAgICAgIFN0YXRlbWVudC5OT19HRU5FUkFURURfS0VZUyk7CisgICAgICAgICAgICBwcnN0LnNldEludCgxLCA4KTsKKyAgICAgICAgICAgIHByc3Quc2V0U3RyaW5nKDIsICJUdXppayIpOworICAgICAgICAgICAgcHJzdC5zZXRTdHJpbmcoMywgImRvZyIpOworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28iKTsKKyAgICAgICAgICAgIHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMiwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIHByc3QuZXhlY3V0ZSgpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28gd2hlcmUgZmFtaWx5ID0gJ2RvZyciKTsKKyAgICAgICAgICAgIHJzMSA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdldENvdW50KHJzMSkpOworLy8gICAgICAgICAgVE9ETyBnZXRHZW5lcmF0ZWRLZXlzIGlzIG5vdCBzdXBwb3J0ZWQKKyAgICAgICAgICAgIHJzNCA9IHByc3QuZ2V0R2VuZXJhdGVkS2V5cygpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGdldENvdW50KHJzNCkpOworCisgICAgICAgICAgICBwcnN0MSA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChpbnNlcnQsIFN0YXRlbWVudC5SRVRVUk5fR0VORVJBVEVEX0tFWVMpOworICAgICAgICAgICAgcHJzdDEuc2V0SW50KDEsIDUpOworICAgICAgICAgICAgcHJzdDEuc2V0U3RyaW5nKDIsICJMYXlrYSIpOworICAgICAgICAgICAgcHJzdDEuc2V0U3RyaW5nKDMsICJkb2ciKTsKKworICAgICAgICAgICAgcHJzdDEuZXhlY3V0ZSgpOworCisgICAgICAgICAgICByczUgPSBwcnN0MS5nZXRHZW5lcmF0ZWRLZXlzKCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZ2V0Q291bnQocnM1KSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgcnMxLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgcHJzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb21taXQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgU3RhdGVtZW50IHN0MSA9IG51bGw7CisgICAgICAgIFN0YXRlbWVudCBzdDIgPSBudWxsOworICAgICAgICBTdGF0ZW1lbnQgc3QzID0gbnVsbDsKKyAgICAgICAgU3RhdGVtZW50IHN0NCA9IG51bGw7CisgICAgICAgIFJlc3VsdFNldCByczEgPSBudWxsOworICAgICAgICBSZXN1bHRTZXQgcnMyID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzMyA9IG51bGw7CisgICAgICAgIFJlc3VsdFNldCByczQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5zZXRBdXRvQ29tbWl0KGZhbHNlKTsKKworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDMsICdWb3JvYmV5JywgJ3NwYXJyb3cnKTsiKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGUoImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICg0LCAnT3JlbCcsICdlYWdsZScpOyIpOworCisgICAgICAgICAgICBzdDEgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgc3QxLmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gem9vIik7CisgICAgICAgICAgICByczEgPSBzdDEuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgZ2V0Q291bnQocnMxKSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNvbm4uY29tbWl0KCk7CisgICAgICAgICAgICAgICAgc3QyID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdDIuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28iKTsKKyAgICAgICAgICAgICAgICByczIgPSBzdDIuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGdldENvdW50KHJzMikpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICByczIuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgc3QyLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0MyA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KFJlc3VsdFNldC5UWVBFX0ZPUldBUkRfT05MWSwKKyAgICAgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5DT05DVVJfUkVBRF9PTkxZLAorICAgICAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkhPTERfQ1VSU09SU19PVkVSX0NPTU1JVCk7CisgICAgICAgICAgICAgICAgc3QzLmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gem9vIik7CisgICAgICAgICAgICAgICAgcnMzID0gc3QzLmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGNvbm4uY29tbWl0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGdldENvdW50KHJzMykpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBpZiAocnMzICE9IG51bGwpIHJzMy5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICBpZiAoc3QzICE9IG51bGwpIHN0My5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcnMxLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBzdDEuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJvbGxiYWNrKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgIFN0YXRlbWVudCBzdDEgPSBudWxsOworICAgICAgICBSZXN1bHRTZXQgcnMxID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzMiA9IG51bGw7CisgICAgICAgIFJlc3VsdFNldCByczMgPSBudWxsOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnNldEF1dG9Db21taXQoZmFsc2UpOworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDMsICdWb3JvYmV5JywgJ3NwYXJyb3cnKTsiKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGUoImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICg0LCAnT3JlbCcsICdlYWdsZScpOyIpOworICAgICAgICAgICAgY29ubi5yb2xsYmFjaygpOworICAgICAgICAgICAgc3QxID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0MS5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHpvbyIpOworICAgICAgICAgICAgcnMxID0gc3QxLmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJSb2xsYmFjayB3YXMgaW5lZmZlY3RpdmUiLDIsIGdldENvdW50KHJzMSkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgY29ubi5zZXRBdXRvQ29tbWl0KHRydWUpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIHN0MS5jbG9zZSgpOworICAgICAgICAgICAgICAgIHJzMS5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uc2V0QXV0b0NvbW1pdChmYWxzZSk7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoMywgJ1Zvcm9iZXknLCAnc3BhcnJvdycpOyIpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDQsICdPcmVsJywgJ2VhZ2xlJyk7Iik7CisKKyAgICAgICAgICAgIGlmICghY29ubi5nZXRBdXRvQ29tbWl0KCkpIHsKKyAgICAgICAgICAgICAgICBzdDEgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0MS5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHpvbyIpOworICAgICAgICAgICAgICAgIHJzMSA9IHN0MS5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgZ2V0Q291bnQocnMxKSk7CisgICAgICAgICAgICAgICAgU3RhdGVtZW50IHN0MiA9IG51bGw7CisgICAgICAgICAgICAgICAgU3RhdGVtZW50IHN0MyA9IG51bGw7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgY29ubi5jb21taXQoKTsKKyAgICAgICAgICAgICAgICAgICAgc3QyID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICAgICAgc3QyLmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gem9vIik7CisgICAgICAgICAgICAgICAgICAgIHJzMiA9IHN0Mi5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGdldENvdW50KHJzMikpOworICAgICAgICAgICAgICAgICAgICAvLyByb2xsYmFjayBhZnRlciBjb21taXQgaW5lZmZlY3RpdmUKKyAgICAgICAgICAgICAgICAgICAgY29ubi5yb2xsYmFjaygpOworICAgICAgICAgICAgICAgICAgICBzdDMgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgICAgICBzdDMuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28iKTsKKyAgICAgICAgICAgICAgICAgICAgcnMzID0gc3QzLmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgZ2V0Q291bnQocnMzKSk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgY29ubi5zZXRBdXRvQ29tbWl0KHRydWUpOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgcnMyLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICByczMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0Mi5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgc3QzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJFcnJvciBpbiB0ZXN0IHNldHVwOiBjYW5ub3QgdHVybiBhdXRvY29tbWl0IG9mZi4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBzdDEuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICByczEuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgY29ubi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5yb2xsYmFjaygpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgLy8gVE9ETyBzZXRTYXZlcG9pbnQgaXMgbm90IHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRTYXZlcG9pbnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgY29ubi5zZXRBdXRvQ29tbWl0KGZhbHNlKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2F2ZXBvaW50IHNwID0gY29ubi5zZXRTYXZlcG9pbnQoKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rIG5vdCBzdXBwb3J0ZWQKKyAgICAgICAgfQorCisKKyAgICAgICAgLy9Db21wbGV0ZSB0ZXN0IGJ1dDogbm90IHN1cHBvcnRlZCBleGNlcHRpb24gaXMgdGhyb3duCisgICAgICAgIC8qCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnNldEF1dG9Db21taXQoZmFsc2UpOworCisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdAorICAgICAgICAgICAgICAgICAgICAuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDMsICdWb3JvYmV5JywgJ3NwYXJyb3cnKTsiKTsKKyAgICAgICAgICAgIHN0CisgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoNCwgJ09yZWwnLCAnZWFnbGUnKTsiKTsKKworICAgICAgICAgICAgaWYgKCFjb25uLmdldEF1dG9Db21taXQoKSkgeworICAgICAgICAgICAgICAgIHN0MSA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgc3QxLmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gem9vIik7CisgICAgICAgICAgICAgICAgcnMxID0gc3QxLmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyg0LCBnZXRDb3VudChyczEpKTsKKyAgICAgICAgICAgICAgICBTdGF0ZW1lbnQgc3QyID0gbnVsbDsKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMyID0gbnVsbDsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBTYXZlcG9pbnQgc3AgPSBjb25uLnNldFNhdmVwb2ludCgpOworICAgICAgICAgICAgICAgICAgICBzdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoNSwgJ2NoYXlrYScsICdndWxsJyk7Iik7CisgICAgICAgICAgICAgICAgICAgIGNvbm4ucm9sbGJhY2soc3ApOworICAgICAgICAgICAgICAgICAgICBzdDIgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgICAgICBzdDIuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28iKTsKKyAgICAgICAgICAgICAgICAgICAgcnMyID0gc3QyLmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgZ2V0Q291bnQocnMyKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93bjogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJzMi5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgc3QyLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU2F2ZXBvaW50IHNwMSA9IGNvbm4uc2V0U2F2ZXBvaW50KCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc3AxKTsKKyAgICAgICAgICAgICAgICAgICAgc3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDUsICdjaGF5a2EnLCAnZ3VsbCcpOyIpOworICAgICAgICAgICAgICAgICAgICBTYXZlcG9pbnQgc3AyID0gY29ubi5zZXRTYXZlcG9pbnQoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChzcDIpOworICAgICAgICAgICAgICAgICAgICBzdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoNiwgJ2dyYWNoJywgJ3Jvb2snKTsiKTsKKyAgICAgICAgICAgICAgICAgICAgY29ubi5yb2xsYmFjayhzcDEpOworICAgICAgICAgICAgICAgICAgICBzdDIgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgICAgICBzdDIuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28iKTsKKyAgICAgICAgICAgICAgICAgICAgcnMyID0gc3QyLmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgZ2V0Q291bnQocnMyKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93bjogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJzMi5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgc3QyLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU2F2ZXBvaW50IHNwMSA9IGNvbm4uc2V0U2F2ZXBvaW50KCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc3AxKTsKKyAgICAgICAgICAgICAgICAgICAgc3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDUsICdjaGF5a2EnLCAnZ3VsbCcpOyIpOworICAgICAgICAgICAgICAgICAgICBTYXZlcG9pbnQgc3AyID0gY29ubi5zZXRTYXZlcG9pbnQoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChzcDIpOworICAgICAgICAgICAgICAgICAgICBzdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoNiwgJ2dyYWNoJywgJ3Jvb2snKTsiKTsKKyAgICAgICAgICAgICAgICAgICAgY29ubi5yb2xsYmFjaygpOworICAgICAgICAgICAgICAgICAgICBzdDIgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgICAgICBzdDIuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28iKTsKKyAgICAgICAgICAgICAgICAgICAgcnMyID0gc3QyLmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgZ2V0Q291bnQocnMyKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93bjogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJzMi5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgc3QyLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHN0MSA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgc3QxLmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gem9vIik7CisgICAgICAgICAgICAgICAgcnMxID0gc3QxLmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyg0LCBnZXRDb3VudChyczEpKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBTYXZlcG9pbnQgc3AgPSBjb25uLnNldFNhdmVwb2ludCgpOworICAgICAgICAgICAgICAgICAgICBzdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoNSwgJ2NoYXlrYScsICdndWxsJyk7Iik7CisgICAgICAgICAgICAgICAgICAgIGNvbm4ucm9sbGJhY2soc3ApOworICAgICAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93bjogIiArIHNxbGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJzMS5jbG9zZSgpOworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgc3QxLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAqLworICAgIH0KKworICAgIC8vIFRPRE8gc2V0U2F2ZXBvaW50IGlzIG5vdCBzdXBwb3J0ZWQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0U2F2ZXBvaW50X1N0cmluZygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgdGVzdFNhdmVwb2ludCA9ICJ0ZXN0U2F2ZXBvaW50IjsKKyAgICAgICAgY29ubi5zZXRBdXRvQ29tbWl0KGZhbHNlKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2F2ZXBvaW50IHNwID0gY29ubi5zZXRTYXZlcG9pbnQodGVzdFNhdmVwb2ludCk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvayBub3Qgc3VwcG9ydGVkCisgICAgICAgIH0KKworICAgIC8qCisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgIFN0YXRlbWVudCBzdDEgPSBudWxsOworICAgICAgICBSZXN1bHRTZXQgcnMxID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uc2V0QXV0b0NvbW1pdChmYWxzZSk7CisKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0CisgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoMywgJ1Zvcm9iZXknLCAnc3BhcnJvdycpOyIpOworICAgICAgICAgICAgc3QKKyAgICAgICAgICAgICAgICAgICAgLmV4ZWN1dGUoImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICg0LCAnT3JlbCcsICdlYWdsZScpOyIpOworCisgICAgICAgICAgICBpZiAoIWNvbm4uZ2V0QXV0b0NvbW1pdCgpKSB7CisgICAgICAgICAgICAgICAgc3QxID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdDEuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28iKTsKKyAgICAgICAgICAgICAgICByczEgPSBzdDEuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGdldENvdW50KHJzMSkpOworICAgICAgICAgICAgICAgIFN0YXRlbWVudCBzdDIgPSBudWxsOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCByczIgPSBudWxsOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFNhdmVwb2ludCBzcCA9IGNvbm4uc2V0U2F2ZXBvaW50KCJvbmUiKTsKKyAgICAgICAgICAgICAgICAgICAgc3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDUsICdjaGF5a2EnLCAnZ3VsbCcpOyIpOworICAgICAgICAgICAgICAgICAgICBjb25uLnJvbGxiYWNrKHNwKTsKKyAgICAgICAgICAgICAgICAgICAgc3QyID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICAgICAgc3QyLmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gem9vIik7CisgICAgICAgICAgICAgICAgICAgIHJzMiA9IHN0Mi5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGdldENvdW50KHJzMikpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd246ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICByczIuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0Mi5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFNhdmVwb2ludCBzcDEgPSBjb25uLnNldFNhdmVwb2ludCgib25lIik7CisgICAgICAgICAgICAgICAgICAgIHN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmV4ZWN1dGUoImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICg1LCAnY2hheWthJywgJ2d1bGwnKTsiKTsKKyAgICAgICAgICAgICAgICAgICAgU2F2ZXBvaW50IHNwMiA9IGNvbm4uc2V0U2F2ZXBvaW50KCJ0d28iKTsKKyAgICAgICAgICAgICAgICAgICAgc3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDYsICdncmFjaCcsICdyb29rJyk7Iik7CisgICAgICAgICAgICAgICAgICAgIGNvbm4ucm9sbGJhY2soc3AxKTsKKyAgICAgICAgICAgICAgICAgICAgc3QyID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICAgICAgc3QyLmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gem9vIik7CisgICAgICAgICAgICAgICAgICAgIHJzMiA9IHN0Mi5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGdldENvdW50KHJzMikpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd246ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICByczIuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0Mi5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFNhdmVwb2ludCBzcDEgPSBjb25uLnNldFNhdmVwb2ludCgidGhyZWUiKTsKKyAgICAgICAgICAgICAgICAgICAgc3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDUsICdjaGF5a2EnLCAnZ3VsbCcpOyIpOworICAgICAgICAgICAgICAgICAgICBTYXZlcG9pbnQgc3AyID0gY29ubi5zZXRTYXZlcG9pbnQoImZvdXIiKTsKKyAgICAgICAgICAgICAgICAgICAgc3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDYsICdncmFjaCcsICdyb29rJyk7Iik7CisgICAgICAgICAgICAgICAgICAgIGNvbm4ucm9sbGJhY2soKTsKKyAgICAgICAgICAgICAgICAgICAgc3QyID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICAgICAgc3QyLmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gem9vIik7CisgICAgICAgICAgICAgICAgICAgIHJzMiA9IHN0Mi5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGdldENvdW50KHJzMikpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd246ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICByczIuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0Mi5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzdDEgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0MS5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHpvbyIpOworICAgICAgICAgICAgICAgIHJzMSA9IHN0MS5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgZ2V0Q291bnQocnMxKSk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU2F2ZXBvaW50IHNwID0gY29ubi5zZXRTYXZlcG9pbnQoImZpdmUiKTsKKyAgICAgICAgICAgICAgICAgICAgc3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDUsICdjaGF5a2EnLCAnZ3VsbCcpOyIpOworICAgICAgICAgICAgICAgICAgICBjb25uLnJvbGxiYWNrKHNwKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd246ICIgKyBzcWxlLnRvU3RyaW5nKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByczEuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIHN0MS5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgKi8KKyAgICB9CisKKyAgICAvLyBUT0RPIFNhdmVwb2ludCBpcyBub3Qgc3VwcG9ydGVkCisgICAgcHVibGljIHZvaWQgdGVzdFJvbGxiYWNrX1NhdmVwb2ludCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTYXZlcG9pbnQgc3AgPSBuZXcgRHVtbXlTYXZlUG9pbnQoKTsKKyAgICAgICAgY29ubi5zZXRBdXRvQ29tbWl0KGZhbHNlKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5yb2xsYmFjayhzcCk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICAgICAgLyoKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgU3RhdGVtZW50IHN0MSA9IG51bGw7CisgICAgICAgIFJlc3VsdFNldCByczEgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5zZXRBdXRvQ29tbWl0KGZhbHNlKTsKKworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgc3QKKyAgICAgICAgICAgICAgICAgICAgLmV4ZWN1dGUoImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICgzLCAnVm9yb2JleScsICdzcGFycm93Jyk7Iik7CisgICAgICAgICAgICBzdAorICAgICAgICAgICAgICAgICAgICAuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDQsICdPcmVsJywgJ2VhZ2xlJyk7Iik7CisKKyAgICAgICAgICAgIGlmICghY29ubi5nZXRBdXRvQ29tbWl0KCkpIHsKKyAgICAgICAgICAgICAgICBzdDEgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0MS5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHpvbyIpOworICAgICAgICAgICAgICAgIHJzMSA9IHN0MS5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgZ2V0Q291bnQocnMxKSk7CisgICAgICAgICAgICAgICAgU3RhdGVtZW50IHN0MiA9IG51bGw7CisgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzMiA9IG51bGw7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU2F2ZXBvaW50IHNwID0gY29ubi5zZXRTYXZlcG9pbnQoIm9uZSIpOworICAgICAgICAgICAgICAgICAgICBzdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoNSwgJ2NoYXlrYScsICdndWxsJyk7Iik7CisgICAgICAgICAgICAgICAgICAgIGNvbm4ucm9sbGJhY2soc3ApOworICAgICAgICAgICAgICAgICAgICBzdDIgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgICAgICBzdDIuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28iKTsKKyAgICAgICAgICAgICAgICAgICAgcnMyID0gc3QyLmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgZ2V0Q291bnQocnMyKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93bjogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJzMi5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgc3QyLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU2F2ZXBvaW50IHNwMSA9IGNvbm4uc2V0U2F2ZXBvaW50KCJvbmUiKTsKKyAgICAgICAgICAgICAgICAgICAgc3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDUsICdjaGF5a2EnLCAnZ3VsbCcpOyIpOworICAgICAgICAgICAgICAgICAgICBTYXZlcG9pbnQgc3AyID0gY29ubi5zZXRTYXZlcG9pbnQoInR3byIpOworICAgICAgICAgICAgICAgICAgICBzdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoNiwgJ2dyYWNoJywgJ3Jvb2snKTsiKTsKKyAgICAgICAgICAgICAgICAgICAgY29ubi5yb2xsYmFjayhzcDEpOworICAgICAgICAgICAgICAgICAgICBzdDIgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgICAgICBzdDIuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28iKTsKKyAgICAgICAgICAgICAgICAgICAgcnMyID0gc3QyLmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgZ2V0Q291bnQocnMyKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93bjogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJzMi5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgc3QyLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU2F2ZXBvaW50IHNwMSA9IGNvbm4uc2V0U2F2ZXBvaW50KCJ0aHJlZSIpOworICAgICAgICAgICAgICAgICAgICBzdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoNSwgJ2NoYXlrYScsICdndWxsJyk7Iik7CisgICAgICAgICAgICAgICAgICAgIFNhdmVwb2ludCBzcDIgPSBjb25uLnNldFNhdmVwb2ludCgiZm91ciIpOworICAgICAgICAgICAgICAgICAgICBzdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoNiwgJ2dyYWNoJywgJ3Jvb2snKTsiKTsKKyAgICAgICAgICAgICAgICAgICAgY29ubi5yb2xsYmFjaygpOworICAgICAgICAgICAgICAgICAgICBzdDIgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgICAgICBzdDIuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28iKTsKKyAgICAgICAgICAgICAgICAgICAgcnMyID0gc3QyLmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwgZ2V0Q291bnQocnMyKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93bjogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJzMi5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgc3QyLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHN0MSA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgc3QxLmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gem9vIik7CisgICAgICAgICAgICAgICAgcnMxID0gc3QxLmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyg0LCBnZXRDb3VudChyczEpKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBTYXZlcG9pbnQgc3AgPSBjb25uLnNldFNhdmVwb2ludCgiZml2ZSIpOworICAgICAgICAgICAgICAgICAgICBzdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoNSwgJ2NoYXlrYScsICdndWxsJyk7Iik7CisgICAgICAgICAgICAgICAgICAgIGNvbm4ucm9sbGJhY2soc3ApOworICAgICAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93bjogIiArIHNxbGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJzMS5jbG9zZSgpOworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgc3QxLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAqLworICAgIH0KKworICAgIC8vIFRPRE8gU2F2ZXBvaW50IGlzIG5vdCBzdXBwb3J0ZWQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVsZWFzZVNhdmVwb2ludF9TYXZlcG9pbnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU2F2ZXBvaW50IHNwID0gbmV3IER1bW15U2F2ZVBvaW50KCk7CisgICAgICAgIGNvbm4uc2V0QXV0b0NvbW1pdChmYWxzZSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4ucmVsZWFzZVNhdmVwb2ludChzcCk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICAgICAgLyoKKworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICBTdGF0ZW1lbnQgc3QxID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzMSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnNldEF1dG9Db21taXQoZmFsc2UpOworCisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdAorICAgICAgICAgICAgICAgICAgICAuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDMsICdWb3JvYmV5JywgJ3NwYXJyb3cnKTsiKTsKKyAgICAgICAgICAgIHN0CisgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoNCwgJ09yZWwnLCAnZWFnbGUnKTsiKTsKKworICAgICAgICAgICAgaWYgKCFjb25uLmdldEF1dG9Db21taXQoKSkgeworICAgICAgICAgICAgICAgIHN0MSA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgc3QxLmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gem9vIik7CisgICAgICAgICAgICAgICAgcnMxID0gc3QxLmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyg0LCBnZXRDb3VudChyczEpKTsKKyAgICAgICAgICAgICAgICBTdGF0ZW1lbnQgc3QyID0gbnVsbDsKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMyID0gbnVsbDsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBTYXZlcG9pbnQgc3AgPSBjb25uLnNldFNhdmVwb2ludCgib25lIik7CisgICAgICAgICAgICAgICAgICAgIHN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmV4ZWN1dGUoImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICg1LCAnY2hheWthJywgJ2d1bGwnKTsiKTsKKyAgICAgICAgICAgICAgICAgICAgY29ubi5yb2xsYmFjayhzcCk7CisgICAgICAgICAgICAgICAgICAgIHN0MiA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgICAgIHN0Mi5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHpvbyIpOworICAgICAgICAgICAgICAgICAgICByczIgPSBzdDIuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyg0LCBnZXRDb3VudChyczIpKTsKKyAgICAgICAgICAgICAgICAgICAgc3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDUsICdjaGF5a2EnLCAnZ3VsbCcpOyIpOworICAgICAgICAgICAgICAgICAgICBjb25uLnJlbGVhc2VTYXZlcG9pbnQoc3ApOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgY29ubi5yb2xsYmFjayhzcCk7CisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBjb25uLnJvbGxiYWNrKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93bjogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJzMi5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgc3QyLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU2F2ZXBvaW50IHNwMSA9IGNvbm4uc2V0U2F2ZXBvaW50KCJvbmUiKTsKKyAgICAgICAgICAgICAgICAgICAgc3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXhlY3V0ZSgiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDUsICdjaGF5a2EnLCAnZ3VsbCcpOyIpOworICAgICAgICAgICAgICAgICAgICBTYXZlcG9pbnQgc3AyID0gY29ubi5zZXRTYXZlcG9pbnQoInR3byIpOworICAgICAgICAgICAgICAgICAgICBzdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoNiwgJ2dyYWNoJywgJ3Jvb2snKTsiKTsKKyAgICAgICAgICAgICAgICAgICAgY29ubi5yZWxlYXNlU2F2ZXBvaW50KHNwMSk7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb25uLnJvbGxiYWNrKHNwMSk7CisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBjb25uLmNvbW1pdCgpOworICAgICAgICAgICAgICAgICAgICBjb25uLnJvbGxiYWNrKHNwMik7CisgICAgICAgICAgICAgICAgICAgIHN0MiA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgICAgIHN0Mi5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHpvbyIpOworICAgICAgICAgICAgICAgICAgICByczIgPSBzdDIuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyg0LCBnZXRDb3VudChyczIpKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgdGhyb3duOiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgcnMyLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBzdDIuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc3QxID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdDEuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28iKTsKKyAgICAgICAgICAgICAgICByczEgPSBzdDEuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGdldENvdW50KHJzMSkpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFNhdmVwb2ludCBzcCA9IGNvbm4uc2V0U2F2ZXBvaW50KCJmaXZlIik7CisgICAgICAgICAgICAgICAgICAgIHN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmV4ZWN1dGUoImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICg1LCAnY2hheWthJywgJ2d1bGwnKTsiKTsKKyAgICAgICAgICAgICAgICAgICAgY29ubi5yZWxlYXNlU2F2ZXBvaW50KHNwKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd246ICIgKyBzcWxlLnRvU3RyaW5nKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByczEuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIHN0MS5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgKi8KKyAgICB9CisKKyAgICAvLyBUT0RPIHByZXBhcmVTdGF0ZW1lbnQoU3RyaW5nIHNxbCwgaW50W10gY29sdW1uSW5kZXhlcykgaXMgbm90IHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RQcmVwYXJlU3RhdGVtZW50X1N0cmluZ19pbnRBcnJheSgpIHsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHJzdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgaW5zZXJ0ID0gImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICg/LCA/LCA/KTsiOworICAgICAgICAgICAgcHJzdCA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChpbnNlcnQsIG5ldyBpbnRbXSB7IDAsIDEsIDIgfSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rIG5vdCBzdXBwb3J0ZWQKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHJzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLyoKKworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcnN0MSA9IG51bGw7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHByc3QgPSBudWxsOworICAgICAgICBSZXN1bHRTZXQgcnMgPSBudWxsOworICAgICAgICBSZXN1bHRTZXQgcnMxID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzNCA9IG51bGw7CisgICAgICAgIFJlc3VsdFNldCByczUgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIGluc2VydCA9ICJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoPywgPywgPyk7IjsKKyAgICAgICAgICAgIHByc3QgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQoaW5zZXJ0LCBuZXcgaW50W10geyAwLCAxLCAyIH0pOworICAgICAgICAgICAgcHJzdC5zZXRJbnQoMSwgOCk7CisgICAgICAgICAgICBwcnN0LnNldFN0cmluZygyLCAiVHV6aWsiKTsKKyAgICAgICAgICAgIHByc3Quc2V0U3RyaW5nKDMsICJkb2ciKTsKKworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28iKTsKKyAgICAgICAgICAgIHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMiwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIHByc3QuZXhlY3V0ZSgpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB6b28gd2hlcmUgZmFtaWx5ID0gJ2RvZyciKTsKKyAgICAgICAgICAgIHJzMSA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdldENvdW50KHJzMSkpOworCisgICAgICAgICAgICByczQgPSBwcnN0LmdldEdlbmVyYXRlZEtleXMoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBnZXRDb3VudChyczQpKTsKKworICAgICAgICAgICAgcHJzdDEgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQoaW5zZXJ0LCBuZXcgaW50W10geyAwLCAxLCAyLCAxMCB9KTsKKyAgICAgICAgICAgIHByc3QxLnNldEludCgxLCA1KTsKKyAgICAgICAgICAgIHByc3QxLnNldFN0cmluZygyLCAiTGF5a2EiKTsKKyAgICAgICAgICAgIHByc3QxLnNldFN0cmluZygzLCAiZG9nIik7CisKKyAgICAgICAgICAgIHByc3QxLmV4ZWN1dGUoKTsKKworICAgICAgICAgICAgcnM1ID0gcHJzdDEuZ2V0R2VuZXJhdGVkS2V5cygpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGdldENvdW50KHJzNSkpOworCisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgdGhyb3duOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBycy5jbG9zZSgpOworICAgICAgICAgICAgICAgIHJzMS5jbG9zZSgpOworICAgICAgICAgICAgICAgIHJzNC5jbG9zZSgpOworICAgICAgICAgICAgICAgIHJzNS5jbG9zZSgpOworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgcHJzdDEuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBwcnN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgaW5zZXJ0ID0gImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICg/LCA/LCA/KTsiOworICAgICAgICAgICAgY29ubi5wcmVwYXJlU3RhdGVtZW50KGluc2VydCwgbmV3IGludFtdIHt9KTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgaW5zZXJ0ID0gImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICg/LCA/LCA/KTsiOworICAgICAgICAgICAgY29ubi5wcmVwYXJlU3RhdGVtZW50KGluc2VydCwgKGludFtdKSBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd24iKTsKKyAgICAgICAgfQorICAgICAgICAqLworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQcmVwYXJlU3RhdGVtZW50X1N0cmluZ19pbnRfaW50KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBxdWVyeSA9ICJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoPywgPywgPyk7IjsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICBSZXN1bHRTZXQgcnMgPSBudWxsOworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBzdCA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSwgUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZLAorICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQuQ09OQ1VSX1JFQURfT05MWSk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgaWQsIG5hbWUgZnJvbSB6b28iKTsKKyAgICAgICAgICAgIHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJzLmRlbGV0ZVJvdygpOworICAgICAgICAgICAgICAgIGZhaWwoIkNhbiBkZWxldGUgcm93IGZvciBSRUFEX09OTFkgUmVzdWx0U2V0Iik7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmIChycyAhPSBudWxsKSBycy5jbG9zZSgpOworICAgICAgICAgICAgICAgIGlmIChzdCAhPSBudWxsKSBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnksIFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkUsCisgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5DT05DVVJfVVBEQVRBQkxFKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCBuYW1lLCBmYW1pbHkgZnJvbSB6b28iKTsKKyAgICAgICAgICAgIHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJzLmluc2VydFJvdygpOworICAgICAgICAgICAgICAgIHJzLnVwZGF0ZU9iamVjdCgiZmFtaWx5IiwgImJpcmQiKTsKKyAgICAgICAgICAgICAgICBycy5uZXh0KCk7CisgICAgICAgICAgICAgICAgcnMucHJldmlvdXMoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImJpcmQiLCAocnMuZ2V0U3RyaW5nKDEpKSk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSwgUmVzdWx0U2V0LlRZUEVfU0NST0xMX1NFTlNJVElWRSwgLTEpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnksIEludGVnZXIuTUlOX1ZBTFVFLAorICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQuQ09OQ1VSX1JFQURfT05MWSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLy8gbm90IHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RQcmVwYXJlU3RhdGVtZW50Tm90U3VwcG9ydGVkKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBxdWVyeSA9ICJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoPywgPywgPyk7IjsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICBSZXN1bHRTZXQgcnMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnksCisgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5UWVBFX1NDUk9MTF9JTlNFTlNJVElWRSwKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNPTkNVUl9VUERBVEFCTEUpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0IG5hbWUsIGZhbWlseSBmcm9tIHpvbyIpOworICAgICAgICAgICAgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgIHJzLmluc2VydFJvdygpOworICAgICAgICAgICAgcnMudXBkYXRlT2JqZWN0KCJmYW1pbHkiLCAiYmlyZCIpOworICAgICAgICAgICAgcnMubmV4dCgpOworICAgICAgICAgICAgcnMucHJldmlvdXMoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygicGFycm90IiwgKHJzLmdldFN0cmluZygxKSkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAocnMgIT0gbnVsbCkgcnMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBpZiAoc3QgIT0gbnVsbCkgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gIFRPRE8gQ3Jhc2hlcyBWTS4gRml4IGxhdGVyLgorICAgIHB1YmxpYyB2b2lkIHRlc3RQcmVwYXJlU3RhdGVtZW50X1N0cmluZ19pbnRfaW50X2ludCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgcXVlcnkgPSAiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKD8sID8sID8pOyI7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5LCBSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFksCisgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5DT05DVVJfUkVBRF9PTkxZLAorICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQuSE9MRF9DVVJTT1JTX09WRVJfQ09NTUlUKTsKKyAgICAgICAgICAgIHN0LnNldEludCgxLCAzKTsKKyAgICAgICAgICAgIHN0LnNldFN0cmluZygyLCAiUGV0eWEiKTsKKyAgICAgICAgICAgIHN0LnNldFN0cmluZygzLCAiQ29jayIpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0IGlkLCBuYW1lIGZyb20gem9vIik7CisgICAgICAgICAgICBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgcnMuY2xvc2UoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKHJzICE9IG51bGwpIHJzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgaWYgKHN0ICE9IG51bGwpIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvKgorICAgICAgICAvL1RPRE8gUmVzdWx0U2V0LkNMT1NFX0NVUlNPUlNfQVRfQ09NTUlUIGlzIG5vdCBzdXBwb3J0ZWQKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5LCBSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFksCisgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5DT05DVVJfUkVBRF9PTkxZLAorICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQuQ0xPU0VfQ1VSU09SU19BVF9DT01NSVQpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0IGlkLCBuYW1lIGZyb20gem9vIik7CisgICAgICAgICAgICBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBycy5jbG9zZSgpOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIHdhcyB0aHJvd246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgcnMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgICovCisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSwgUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZLAorICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQuQ09OQ1VSX1JFQURfT05MWSwgLTEwMCk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgIH0KKworICAgIC8vIFRPRE8gcHJlcGFyZVN0YXRlbWVudChTdHJpbmcgc3FsLCBTdHJpbmdbXSBjb2x1bW5OYW1lcykgbWV0aG9kIGlzIG5vdCBzdXBwb3J0ZWQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJlcGFyZVN0YXRlbWVudF9TdHJpbmdfU3RyaW5nQXJyYXkoKSB7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHByc3QgPSBudWxsOworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcnN0MSA9IG51bGw7CisgICAgICAgIFJlc3VsdFNldCBycyA9IG51bGw7CisgICAgICAgIFJlc3VsdFNldCByczEgPSBudWxsOworICAgICAgICBSZXN1bHRTZXQgcnM0ID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzNSA9IG51bGw7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBpbnNlcnQgPSAiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKD8sID8sID8pOyI7CisgICAgICAgICAgICBjb25uLnByZXBhcmVTdGF0ZW1lbnQoaW5zZXJ0LCBuZXcgU3RyaW5nW10geyAiaWQiLCAibmFtZSIsCisgICAgICAgICAgICAiZmFtaWx5IiB9KTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sgbm90IHN1cHBvcnRlZAorICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBpbnNlcnQgPSAiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKD8sID8sID8pOyI7CisgICAgICAgICAgICBjb25uLnByZXBhcmVTdGF0ZW1lbnQoaW5zZXJ0LCBuZXcgU3RyaW5nW10ge30pOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93biIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBpbnNlcnQgPSAiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKD8sID8sID8pOyI7CisgICAgICAgICAgICBjb25uLnByZXBhcmVTdGF0ZW1lbnQoaW5zZXJ0LCAoU3RyaW5nW10pIG51bGwpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93biIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBpbnNlcnQgPSAiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKD8sID8sID8pOyI7CisgICAgICAgICAgICBwcnN0ID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KGluc2VydCwgbmV3IFN0cmluZ1tdIHsgImlkIiwgIm5hbWUiLAorICAgICAgICAgICAgICAgICAgICAiZmFtaWx5IiB9KTsKKyAgICAgICAgICAgIHByc3Quc2V0SW50KDEsIDgpOworICAgICAgICAgICAgcHJzdC5zZXRTdHJpbmcoMiwgIlR1emlrIik7CisgICAgICAgICAgICBwcnN0LnNldFN0cmluZygzLCAiZG9nIik7CisKKyAgICAgICAgICAgIFN0YXRlbWVudCBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHpvbyIpOworICAgICAgICAgICAgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygyLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgcHJzdC5leGVjdXRlKCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHpvbyB3aGVyZSBmYW1pbHkgPSAnZG9nJyIpOworICAgICAgICAgICAgcnMxID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZ2V0Q291bnQocnMxKSk7CisKKyAgICAgICAgICAgIHJzNCA9IHByc3QuZ2V0R2VuZXJhdGVkS2V5cygpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGdldENvdW50KHJzNCkpOworCisgICAgICAgICAgICBwcnN0MSA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChpbnNlcnQsIG5ldyBTdHJpbmdbXSB7ICJpZCIsICJuYW1lIiwgIiIgfSk7CisgICAgICAgICAgICBwcnN0MS5zZXRJbnQoMSwgNSk7CisgICAgICAgICAgICBwcnN0MS5zZXRTdHJpbmcoMiwgIkxheWthIik7CisgICAgICAgICAgICBwcnN0MS5zZXRTdHJpbmcoMywgImRvZyIpOworCisgICAgICAgICAgICBwcnN0MS5leGVjdXRlKCk7CisKKyAgICAgICAgICAgIHJzNSA9IHByc3QxLmdldEdlbmVyYXRlZEtleXMoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBnZXRDb3VudChyczUpKTsKKworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93bjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcnMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICByczEuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICByczQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICByczUuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBwcnN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgcHJzdDEuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgICovCisKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDbG9zZSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBpZiAoISBjb25uLmlzQ2xvc2VkKCkpIHsKKyAgICAgICAgY29ubi5jbG9zZSgpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoY29ubi5pc0Nsb3NlZCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICBjb25uLnByZXBhcmVDYWxsKCJzZWxlY3QgKiBmcm9tIHpvbyIpOworICAgICAgICBmYWlsKCJTaG91bGQgbm90IGJlIGFibGUgdG8gcHJlcGFyZSBxdWVyeSBjbG9zZWQgY29ubmVjdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdElzQ2xvc2VkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKGNvbm4uaXNDbG9zZWQoKSk7CisgICAgICAgIGNvbm4uY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjb25uLmlzQ2xvc2VkKCkpOworCisgICAgICAgIGNvbm4gPSBEcml2ZXJNYW5hZ2VyLmdldENvbm5lY3Rpb24oImpkYmM6c3FsaXRlOi8iICsgZGJGaWxlLmdldFBhdGgoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGNvbm4uaXNDbG9zZWQoKSk7CisgICAgICAgIFN0YXRlbWVudCBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gem9vIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgRHVtbXlTYXZlUG9pbnQgaW1wbGVtZW50cyBTYXZlcG9pbnR7CisgICAgICAgIHB1YmxpYyBpbnQgZ2V0U2F2ZXBvaW50SWQoKSAgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFNhdmVwb2ludE5hbWUoKSB7CisgICAgICAgICAgICByZXR1cm4gIk5vTmFtZSI7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NxbC9PbGREcml2ZXJQcm9wZXJ0eUluZm9UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NxbC9PbGREcml2ZXJQcm9wZXJ0eUluZm9UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmZmOWZkNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc3FsL09sZERyaXZlclByb3BlcnR5SW5mb1Rlc3QuamF2YQpAQCAtMCwwICsxLDY2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuc3FsOworCitpbXBvcnQgamF2YS5zcWwuRHJpdmVyOworaW1wb3J0IGphdmEuc3FsLkRyaXZlck1hbmFnZXI7CitpbXBvcnQgamF2YS5zcWwuRHJpdmVyUHJvcGVydHlJbmZvOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIE9sZERyaXZlclByb3BlcnR5SW5mb1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIHZhbGlkTmFtZSA9ICJ0ZXN0bmFtZSI7CisgICAgc3RhdGljIGZpbmFsIFN0cmluZyB2YWxpZFZhbHVlID0gInRlc3R2YWx1ZSI7CisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBjb25uZWN0aW9uVVJMID0gImpkYmM6c3FsaXRlOi8iICsgIlRlc3QuZGIiOworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgY2xhc3NuYW1lID0gIlNRTGl0ZS5KREJDRHJpdmVyIjsKKworICAgIHB1YmxpYyB2b2lkIHRlc3REcml2ZXJQcm9wZXJ0eUluZm9TdHJpbmdTdHJpbmcoKSB7CisgICAgICAgIERyaXZlclByb3BlcnR5SW5mbyBhRHJpdmVyUHJvcGVydHlJbmZvID0gbmV3IERyaXZlclByb3BlcnR5SW5mbygKKyAgICAgICAgICAgICAgICB2YWxpZE5hbWUsIHZhbGlkVmFsdWUpOworCisgICAgICAgIGFzc2VydE5vdE51bGwoYURyaXZlclByb3BlcnR5SW5mbyk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGFEcml2ZXJQcm9wZXJ0eUluZm8ubmFtZSx2YWxpZE5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoYURyaXZlclByb3BlcnR5SW5mby52YWx1ZSx2YWxpZFZhbHVlKTsKKworICAgICAgICBhRHJpdmVyUHJvcGVydHlJbmZvID0gbmV3IERyaXZlclByb3BlcnR5SW5mbyhudWxsLCBudWxsKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKGFEcml2ZXJQcm9wZXJ0eUluZm8pOworICAgICAgICBhc3NlcnROdWxsKGFEcml2ZXJQcm9wZXJ0eUluZm8ubmFtZSk7CisgICAgICAgIGFzc2VydE51bGwoYURyaXZlclByb3BlcnR5SW5mby52YWx1ZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1YmxpY0ZpZWxkcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDbGFzcy5mb3JOYW1lKGNsYXNzbmFtZSkubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgIERyaXZlciBkID0gRHJpdmVyTWFuYWdlci5nZXREcml2ZXIoY29ubmVjdGlvblVSTCk7CisgICAgICAgIERyaXZlclByb3BlcnR5SW5mb1tdIGluZm8gPSBkLmdldFByb3BlcnR5SW5mbyhjb25uZWN0aW9uVVJMLAorICAgICAgICAgICAgICAgIHByb3BzKTsKKyAgICAgICAgLy8gZ2V0IHRoZSBwcm9wZXJ0eSBtZXRhZGF0YQorICAgICAgICBTdHJpbmcgbmFtZSA9IGluZm9bMF0ubmFtZTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5hbWUsICJlbmNvZGluZyIpOworICAgICAgICBTdHJpbmdbXSBjaG9pY2VzID0gaW5mb1swXS5jaG9pY2VzOworICAgICAgICBhc3NlcnROdWxsKGNob2ljZXMpOworICAgICAgICBib29sZWFuIHJlcXVpcmVkID0gaW5mb1swXS5yZXF1aXJlZDsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVxdWlyZWQpOworICAgICAgICBTdHJpbmcgZGVzY3JpcHRpb24gPSBpbmZvWzBdLmRlc2NyaXB0aW9uOworICAgICAgICBhc3NlcnROdWxsKGRlc2NyaXB0aW9uKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NxbC9PbGRQcmVwYXJlZFN0YXRlbWVudFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc3FsL09sZFByZXBhcmVkU3RhdGVtZW50VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjhmZDg2NjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NxbC9PbGRQcmVwYXJlZFN0YXRlbWVudFRlc3QuamF2YQpAQCAtMCwwICsxLDI0MjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgR29vZ2xlIEluYy4KKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5zcWw7CisKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CitpbXBvcnQgamF2YS5pby5Xcml0ZXI7CitpbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEuc3FsLkFycmF5OworaW1wb3J0IGphdmEuc3FsLkJsb2I7CitpbXBvcnQgamF2YS5zcWwuQ2xvYjsKK2ltcG9ydCBqYXZhLnNxbC5EYXRlOworaW1wb3J0IGphdmEuc3FsLlByZXBhcmVkU3RhdGVtZW50OworaW1wb3J0IGphdmEuc3FsLlJlZjsKK2ltcG9ydCBqYXZhLnNxbC5SZXN1bHRTZXQ7CitpbXBvcnQgamF2YS5zcWwuUmVzdWx0U2V0TWV0YURhdGE7CitpbXBvcnQgamF2YS5zcWwuU1FMRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc3FsLlN0YXRlbWVudDsKK2ltcG9ydCBqYXZhLnNxbC5UaW1lOworaW1wb3J0IGphdmEuc3FsLlRpbWVzdGFtcDsKK2ltcG9ydCBqYXZhLnNxbC5UeXBlczsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBPbGRQcmVwYXJlZFN0YXRlbWVudFRlc3QgZXh0ZW5kcyBPbGRTUUxUZXN0IHsKKworICAgIFN0cmluZyBxdWVyeUFsbFNlbGVjdCA9ICJzZWxlY3QgKiBmcm9tIHR5cGUiOworCisgICAgU3RyaW5nW10gcXVlcmllcyA9IHsKKyAgICAgICAgICAgICJjcmVhdGUgdGFibGUgdHlwZSAoIiArCisKKyAgICAgICAgICAgICIgQm9vbFZhbCBCT09MRUFOLCIgKyAiIEludFZhbCBJTlQsIiArICIgTG9uZ1ZhbCBMT05HLCIKKyAgICAgICAgICAgICAgICAgICAgKyAiIEJpbnQgQklHSU5ULCIgKyAiIFRpbnQgVElOWUlOVCwiICsgIiBTaW50IFNNQUxMSU5ULCIKKyAgICAgICAgICAgICAgICAgICAgKyAiIE1pbnQgTUVESVVNSU5ULCAiICsKKworICAgICAgICAgICAgICAgICAgICAiIEludGVnZXJWYWwgSU5URUdFUiwgIiArICIgUmVhbFZhbCBSRUFMLCAiCisgICAgICAgICAgICAgICAgICAgICsgIiBEb3VibGVWYWwgRE9VQkxFLCAiICsgIiBGbG9hdFZhbCBGTE9BVCwgIgorICAgICAgICAgICAgICAgICAgICArICIgRGVjVmFsIERFQ0lNQUwsICIgKworCisgICAgICAgICAgICAgICAgICAgICIgTnVtVmFsIE5VTUVSSUMsICIgKyAiIGNoYXJTdHIgQ0hBUigyMCksICIKKyAgICAgICAgICAgICAgICAgICAgKyAiIGRhdGVWYWwgREFURSwgIiArICIgdGltZVZhbCBUSU1FLCAiICsgIiBUUyBUSU1FU1RBTVAsICIKKyAgICAgICAgICAgICAgICAgICAgKworCisgICAgICAgICAgICAgICAgICAgICIgRFQgREFURVRJTUUsICIgKyAiIFRCbG9iIFRJTllCTE9CLCAiICsgIiBCbG9iVmFsIEJMT0IsICIKKyAgICAgICAgICAgICAgICAgICAgKyAiIE1CbG9iIE1FRElVTUJMT0IsICIgKyAiIExCbG9iIExPTkdCTE9CLCAiICsKKworICAgICAgICAgICAgICAgICAgICAiIFRUZXh0IFRJTllURVhULCAiICsgIiBUZXh0VmFsIFRFWFQsICIKKyAgICAgICAgICAgICAgICAgICAgKyAiIE1UZXh0IE1FRElVTVRFWFQsICIgKyAiIExUZXh0IExPTkdURVhUICIgKyAiKTsiLAorCisgICAgICAgICAgICAiaW5zZXJ0IGludG8gdHlwZSAoQm9vbFZhbCwgSW50VmFsLCBMb25nVmFsLCBCaW50LCBUaW50LCBTaW50LCBNaW50LCIKKyAgICAgICAgICAgICAgICAgICAgKyAiSW50ZWdlclZhbCwgUmVhbFZhbCwgRG91YmxlVmFsLCBGbG9hdFZhbCwgRGVjVmFsLCIKKyAgICAgICAgICAgICAgICAgICAgKyAiTnVtVmFsLCBjaGFyU3RyLCBkYXRlVmFsLCB0aW1lVmFsLCBUUywiCisgICAgICAgICAgICAgICAgICAgICsgIkRULCBUQmxvYiwgQmxvYlZhbCwgTUJsb2IsIExCbG9iLCIKKyAgICAgICAgICAgICAgICAgICAgKyAiVFRleHQsIFRleHRWYWwsIE1UZXh0LCBMVGV4dCIKKyAgICAgICAgICAgICAgICAgICAgKyAiKSAiCisgICAgICAgICAgICAgICAgICAgICsgInZhbHVlcyAoMSwgLTEsIDIyLCAyLCAzMywiCisgICAgICAgICAgICAgICAgICAgICsgIjMsIDEsIDIsIDMuOSwgMjMuMiwgMzMuMywgNDQsIgorICAgICAgICAgICAgICAgICAgICArICI1LCAndGVzdCBzdHJpbmcnLCAnMTc5OS0wNS0yNicsICcxMjozNTo0NScsICcyMDA3LTEwLTA5IDE0OjI4OjAyLjAnLCIKKyAgICAgICAgICAgICAgICAgICAgKyAiJzEyMjEtMDktMjIgMTA6MTE6NTUnLCAxLCAyLCAzLCA0LCIKKyAgICAgICAgICAgICAgICAgICAgKyAiJ1Rlc3QgdGV4dCBtZXNzYWdlIHRpbnknLCAnVGVzdCB0ZXh0IG1lc3NhZ2UnLCAnVGVzdCB0ZXh0IG1lc3NhZ2UgbWVkaXVtJywgJ1Rlc3QgdGV4dCBtZXNzYWdlIGxvbmcnKTsiIH07CisKKyAgICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBxdWVyaWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgc3QuZXhlY3V0ZShxdWVyaWVzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGUoImRyb3AgdGFibGUgaWYgZXhpc3RzIHR5cGUiKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFkZEJhdGNoKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBzID0gY29ubgorICAgICAgICAgICAgICAgICAgICAucHJlcGFyZVN0YXRlbWVudCgiSU5TRVJUIElOVE8gem9vIFZBTFVFUyAoMywnVHV6aWsnLCA/KTsiKTsKKyAgICAgICAgICAgIHBzLmFkZEJhdGNoKCJJTlNFUlQgSU5UTyB6b28gVkFMVUVTICg/LCdCdXJlbmthJywgPyk7ICIpOworICAgICAgICAgICAgcHMuYWRkQmF0Y2goIklOU0VSVCBJTlRPIHpvbyBWQUxVRVMgKD8sJ01hc2hrYScsJ2NhdCcpIik7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGVCYXRjaCgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgdGhyb3duIGZvciBleGVjdXRlQmF0Y2goKSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHMuc2V0U3RyaW5nKDEsICJkb2ciKTsKKyAgICAgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGVCYXRjaCgpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHpvbyIpOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygyLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgdGhyb3duIGZvciBleGVjdXRlQmF0Y2goKSIpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBzID0gY29ubgorICAgICAgICAgICAgICAgICAgICAucHJlcGFyZVN0YXRlbWVudCgiSU5TRVJUIElOVE8gem9vIFZBTFVFUyAoMywnVHV6aWsnLCA/KTsiKTsKKyAgICAgICAgICAgIHBzLmFkZEJhdGNoKCIiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcyA9IGNvbm4KKyAgICAgICAgICAgICAgICAgICAgLnByZXBhcmVTdGF0ZW1lbnQoIklOU0VSVCBJTlRPIHpvbyBWQUxVRVMgKDMsJ1R1emlrJywgPyk7Iik7CisgICAgICAgICAgICBwcy5hZGRCYXRjaChudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworCisgICAgLy8gcHJlcGFyZWRTdGF0ZW1lbnQuZXhlY3V0ZSgpIGRvZXMgbm90IHJldHVybiBmYWxzZSBvbiB1cGRhdGUuCisgICAgcHVibGljIHZvaWQgdGVzdEV4ZWN1dGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy91cGRhdGUKKyAgICAgICAgICAgIFN0cmluZyBxdWVyeSA9ICJpbnNlcnQgaW50byB6b28oaWQsIGZhbWlseSwgbmFtZSkgdmFsdWVzKD8sID8sICd1bmtub3duIGFuaW1hbCcpIjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKyAgICAgICAgICAgIHBzLnNldEludCgxLCAzKTsKKyAgICAgICAgICAgIHBzLnNldFN0cmluZygyLCAiTm8gbmFtZSIpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UocHMuZXhlY3V0ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLHBzLmdldFVwZGF0ZUNvdW50KCkpOworCisgICAgICAgICAgICAvLyBzZWxlY3QKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KCJzZWxlY3QgKiBmcm9tIHpvbyIpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShwcy5leGVjdXRlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGdldENvdW50KHBzLmdldFJlc3VsdFNldCgpKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgcXVlcnkgPSAidXBkYXRlIHpvbyBzZXQgbmFtZT0nTWFzaGEnLCBmYW1pbHk9PyB3aGVyZSBpZD0/OyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBwcy5zZXRTdHJpbmcoMSwgImNhdCIpOworICAgICAgICAgICAgcHMuc2V0SW50KDIsIDIpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UocHMuZXhlY3V0ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBwcy5nZXRVcGRhdGVDb3VudCgpKTsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCBmYW1pbHkgZnJvbSB6b28gd2hlcmUgaWQ9MiIpOworICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICBycy5uZXh0KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImNhdCIsIHJzLmdldFN0cmluZygxKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uY3JlYXRlU3RhdGVtZW50KCkuZXhlY3V0ZSgiZHJvcCB0YWJsZSBpZiBleGlzdHMgaHV0Y2giKTsKKyAgICAgICAgICAgIFN0cmluZyBxdWVyeSA9ICJjcmVhdGUgdGFibGUgaHV0Y2ggKGlkIGludGVnZXIgbm90IG51bGwsIGFuaW1hbF9pZCBpbnRlZ2VyLCBhZGRyZXNzIGNoYXIoMjApLCBwcmltYXJ5IGtleSAoaWQpKTsiOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UocHMuZXhlY3V0ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUocHMuZ2V0VXBkYXRlQ291bnQoKSA+IDApOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gInNlbGVjdCBuYW1lLCBmYW1pbHkgZnJvbSB6b28gd2hlcmUgaWQgPSA/IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKyAgICAgICAgICAgIHBzLnNldEludCgxLCAxKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUocHMuZXhlY3V0ZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBxdWVyeSA9ICJzZWxlY3QgbmFtZSwgZmFtaWx5IGZyb20gem9vIHdoZXJlIGlkID0gPyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvL0V4Y2VwdGlvbiB0ZXN0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgcXVlcnkgPSAidXBkYXRlIHpvbyBzZXQgbmFtZT0nTWFzaGEnLCBmYW1pbHk9PyB3aGVyZSBpZD0/OyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBwcy5zZXRTdHJpbmcoMSwgImNhdCIpOworICAgICAgICAgICAgcHMuc2V0SW50KDIsIDIpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShwcy5leGVjdXRlKCJ1cGRhdGUgem9vIHNldCBuYW1lPSdNYXNoYScsIGZhbWlseT0nY2F0JyB3aGVyZSBpZD0yOyIpKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rIFNob3VsZCBub3QgcHJvdmlkZSBzdHJpbmcgYXJndW1lbnQgZm9yIGEgcHJlcGFyZWQgU3RhdGVtZW50CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFeGVjdXRlUXVlcnkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nW10gcXVlcmllczIgPSB7CisgICAgICAgICAgICAgICAgInVwZGF0ZSB6b28gc2V0IG5hbWU9J01hc2hhJywgZmFtaWx5PSdjYXQnIHdoZXJlIGlkPTsiLAorICAgICAgICAgICAgICAgICJpbnNlcnQgaW50byBodXRjaCAoaWQsIGFuaW1hbF9pZCwgYWRkcmVzcykgdmFsdWVzICgxLCA/LCdCaXJkcy1ob3VzZSwgMScpOyIsCisgICAgICAgICAgICAgICAgImluc2VydCBpbnRvIGh1dGNoIChpZCwgYW5pbWFsX2lkLCBhZGRyZXNzKSB2YWx1ZXMgKD8sIDEsICdIb3JzZS1ob3VzZSwgNScpOyIsCisgICAgICAgICAgICAgICAgImNyZWF0ZSB2aWV3IGFkZHJlc3MgYXMgc2VsZWN0IGFkZHJlc3MgZnJvbSBodXRjaCB3aGVyZSBhbmltYWxfaWQ9PyJ9OworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcXVlcmllczIubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcmllczJbaV0pOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGVRdWVyeSgpOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIGZvciBxdWVyeTogIiArIHF1ZXJpZXMyW2ldKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcHMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgcXVlcnkgPSAic2VsZWN0ICogZnJvbSB6b28gd2hlcmUgaWQgPSA/IjsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworICAgICAgICAgICAgcHMuc2V0SW50KDEsIDEpOworICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gcHMuZXhlY3V0ZVF1ZXJ5KCk7CisgICAgICAgICAgICBycy5uZXh0KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgcnMuZ2V0SW50KDEpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiS2VzaGEiLCBycy5nZXRTdHJpbmcoMikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJwYXJyb3QiLCBycy5nZXRTdHJpbmcoMykpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworICAgICAgICAgICAgcHMuc2V0SW50KDEsIDUpOworICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gcHMuZXhlY3V0ZVF1ZXJ5KCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHJzKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHJzLm5leHQoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRPRE8gQ3Jhc2hlcyBWTS4gRml4IGxhdGVyLgorICAgIHB1YmxpYyB2b2lkIHRlc3RFeGVjdXRlVXBkYXRlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgICAgU3RyaW5nW10gcXVlcmllczEgPSB7ICJpbnNlcnQgaW50byBodXRjaCAoaWQsIGFuaW1hbF9pZCwgYWRkcmVzcykgdmFsdWVzICgxLCA/LCAnQmlyZHMtaG91c2UsIDEnKTsiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImluc2VydCBpbnRvIGh1dGNoIChpZCwgYW5pbWFsX2lkLCBhZGRyZXNzKSB2YWx1ZXMgKD8sIDEsICdIb3JzZS1ob3VzZSwgNScpOyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY3JlYXRlIHZpZXcgYWRkcmVzcyBhcyBzZWxlY3QgYWRkcmVzcyBmcm9tIGh1dGNoIHdoZXJlIGFuaW1hbF9pZD0yIiB9OworCisgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBxdWVyaWVzMS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcyA9IG51bGw7CisgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyaWVzMVtpXSk7CisgICAgICAgICAgICAgICAgICBwcy5leGVjdXRlVXBkYXRlKCk7CisgICAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biBmb3IgcXVlcnk6ICIgKyBxdWVyaWVzMVtpXSk7CisgICAgICAgICAgfSBjYXRjaChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgICB9IGNhdGNoKEV4Y2VwdGlvbiBlZSkge30KKyAgICAgICAgICB9CisgICAgICB9CisKKyAgICAgICAgICBTdHJpbmcgcXVlcnkgPSAidXBkYXRlIHpvbyBzZXQgbmFtZT0nTWFzaGEnLCBmYW1pbHk9J2NhdCcgd2hlcmUgaWQ9PzsiOworICAgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzID0gbnVsbDsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICAgIHBzLnNldEludCgxLCAyKTsKKyAgICAgICAgICAgICAgaW50IHVwZGF0ZUNvdW50ID0gcHMuZXhlY3V0ZVVwZGF0ZSgpOworICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgdXBkYXRlQ291bnQpOworICAgICAgICAgICAgICBwcy5zZXRJbnQoMSwgMSk7CisgICAgICAgICAgICAgIGludCB1cGRhdGVDb3VudDEgPSBwcy5leGVjdXRlVXBkYXRlKCk7CisgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCB1cGRhdGVDb3VudDEpOworICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgICB9IGNhdGNoKEV4Y2VwdGlvbiBlZSkge30KKyAgICAgICAgICB9CisgICAgICB9CisKKyAgICAvKioKKyAgICAgKiBUT0RPIERvZXNuJ3QgcGFzcy4gYWNjb3JkaW5nIHRvIHNwZWMsIGl0IGlzIHBvc3NpYmxlIHRvIGludm9rZSB0aGUKKyAgICAgKiBtZXRob2QgZ2V0TWV0YURhdGEgb24gYSBQcmVwYXJlZFN0YXRlbWVudCBvYmplY3QgYmVmb3JlIGl0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRNZXRhRGF0YSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcyA9IG51bGw7CisKKyAgICAgICAgLy8gU3BlY2lmaWNhdGlvbiB0ZXN0aW5nCisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBxdWVyeSA9ICJ1cGRhdGUgem9vIHNldCBuYW1lPSdNYXNoYScsIGZhbWlseT0nY2F0JyB3aGVyZSBpZD0/OyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHBzKTsKKyAgICAgICAgICAgIFJlc3VsdFNldE1ldGFEYXRhIG1ldGEgPSBwcy5nZXRNZXRhRGF0YSgpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChtZXRhKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBxdWVyeSA9ICJzZWxlY3QgKiBmcm9tIHpvbyB3aGVyZSBpZCA9ID8iOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworICAgICAgICAgICAgUmVzdWx0U2V0TWV0YURhdGEgcnNtZCA9IHBzLmdldE1ldGFEYXRhKCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHJzbWQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHJzbWQuZ2V0Q29sdW1uQ291bnQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImlkIiwgcnNtZC5nZXRDb2x1bW5OYW1lKDEpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gcHMgY2xvc2VkCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcy5nZXRNZXRhRGF0YSgpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFBhcmFtZXRlck1ldGFEYXRhKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzID0gbnVsbDsKKyAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gInNlbGVjdCAqIGZyb20gem9vIHdoZXJlIGlkID0gPyI7CisgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHMuZ2V0UGFyYW1ldGVyTWV0YURhdGEoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygibm90IHN1cHBvcnRlZCIsZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcy5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcy5nZXRQYXJhbWV0ZXJNZXRhRGF0YSgpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZhaWxzOiBjbGVhcnBhcmFtZXRlcnMgc2hvdWxkIGJlIGltcGxlbWVudGVkIHdpdGggU3RtdC5yZXNldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENsZWFyUGFyYW1ldGVycygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgcXVlcnkgPSAic2VsZWN0ICogZnJvbSB6b28gd2hlcmUgaWQgPSA/IGFuZCBmYW1pbHk9PyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBwcy5jbGVhclBhcmFtZXRlcnMoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIGR1cmluZyBleGVjdXRlIG1ldGhvZCBhZnRlciBjYWxsaW5nIGNsZWFyUGFyYW1ldGVycygpIik7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwcy5zZXRJbnQoMSwgMik7CisgICAgICAgICAgICBwcy5zZXRTdHJpbmcoMiwgImRvZyIpOworICAgICAgICAgICAgcHMuY2xlYXJQYXJhbWV0ZXJzKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biBkdXJpbmcgZXhlY3V0ZSBtZXRob2QgYWZ0ZXIgY2FsbGluZyBjbGVhclBhcmFtZXRlcnMoKSIpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICAgICAgcHMuc2V0SW50KDEsIDIpOworICAgICAgICAgICAgcHMuY2xlYXJQYXJhbWV0ZXJzKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biBkdXJpbmcgZXhlY3V0ZSBtZXRob2QgYWZ0ZXIgY2FsbGluZyBjbGVhclBhcmFtZXRlcnMoKSIpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICAgICAgcHMuc2V0SW50KDEsIDIpOworICAgICAgICAgICAgcHMuc2V0U3RyaW5nKDIsICJjYXQiKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd24gZHVyaW5nIGV4ZWN1dGUgbWV0aG9kIGFmdGVyIGNhbGxpbmcgY2xlYXJQYXJhbWV0ZXJzKCkgdHdpY2UiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gZXhjZXB0aW9uIHRlc3QgZmFpbHMKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0SW50KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMgPSBudWxsOworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKEludFZhbCkgdmFsdWVzICg/KTsiOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRJbnQoMSwgSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB0eXBlIHdoZXJlIEludFZhbD0iCisgICAgICAgICAgICAgICAgICAgICAgICArIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcHMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldEludCgxLCBJbnRlZ2VyLk1JTl9WQUxVRSk7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHR5cGUgd2hlcmUgSW50VmFsPSIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKyAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldEludCgxLCBJbnRlZ2VyLk1JTl9WQUxVRSk7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBleGNlcHRpb24gdGVzdCBmYWlscworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRMb25nKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKExvbmdWYWwpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKyAgICAgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldExvbmcoMSwgTG9uZy5NQVhfVkFMVUUpOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB0eXBlIHdoZXJlIExvbmdWYWw9IiArIExvbmcuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0TG9uZygxLCBMb25nLk1JTl9WQUxVRSk7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHR5cGUgd2hlcmUgTG9uZ1ZhbD0iICsgTG9uZy5NQVhfVkFMVUUpOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHMuY2xvc2UoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0TG9uZygxLCBMb25nLk1JTl9WQUxVRSk7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICB9CisKKyAgICAvLyBleGNlcHRpb24gdGVzdCBmYWlscworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRGbG9hdCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBmbG9hdCB2YWx1ZTEgPSAxMjM0NTY3OC4xMjM0NTY4OWY7CisgICAgICAgIGZsb2F0IHZhbHVlMiA9IC0xMjM0NTY3OC4xMjM0NTY4OWY7CisKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMgPSBudWxsOworICAgICAgICBTdHJpbmcgcXVlcnkgPSAiaW5zZXJ0IGludG8gdHlwZSAoRmxvYXRWYWwpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworCisgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldEZsb2F0KDEsIHZhbHVlMSk7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHR5cGUgd2hlcmUgRmxvYXRWYWw9IiArIHZhbHVlMSk7CisgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdldENvdW50KHJzKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldEZsb2F0KDEsIHZhbHVlMik7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHR5cGUgd2hlcmUgRmxvYXRWYWw9IiArIHZhbHVlMik7CisgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdldENvdW50KHJzKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRGbG9hdCgxLCBGbG9hdC5NSU5fVkFMVUUpOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworCisgICAgICAgICAgICAgICAgcHMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gZXhjZXB0aW9uIHRlc3QgZmFpbHMKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0RG91YmxlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzID0gbnVsbDsKKyAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKERvdWJsZVZhbCkgdmFsdWVzICg/KTsiOworICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisKKyAgICAgICAgdHJ5IHsKKworICAgICAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0RG91YmxlKDEsIERvdWJsZS5NQVhfVkFMVUUpOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB0eXBlIHdoZXJlIERvdWJsZVZhbD0iCisgICAgICAgICAgICAgICAgICAgICAgICArIERvdWJsZS5NQVhfVkFMVUUpOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXREb3VibGUoMSwgRG91YmxlLk1JTl9WQUxVRSk7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHR5cGUgd2hlcmUgRG91YmxlVmFsPSIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgRG91YmxlLk1JTl9WQUxVRSk7CisgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdldENvdW50KHJzKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXREb3VibGUoMSwgMi4wKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIGV4Y2VwdGlvbiB0ZXN0IGZhaWxzCisgICAgcHVibGljIHZvaWQgdGVzdFNldFN0cmluZ19jaGFyRmllbGQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKGNoYXJTdHIpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKworICAgICAgICAgICAgU3RyaW5nIHN0ciA9ICJ0ZXN0XnRleHQkdGVzdCUiOworICAgICAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0U3RyaW5nKDEsIHN0cik7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHR5cGUgd2hlcmUgY2hhclN0cj0nIiArIHN0ciArICInIik7CisgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdldENvdW50KHJzKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldFN0cmluZygxLCAiIik7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHR5cGUgd2hlcmUgY2hhclN0cj0nJyIpOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRTdHJpbmcoMSwgIiAgICAgICAgICAgICAgICAgICAiKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gdHlwZSB3aGVyZSBjaGFyU3RyPScgICAgICAgICAgICAgICAgICAgJyIpOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHMuc2V0U3RyaW5nKDEsICIgdGVzdCAmIHRleHQgKiB0ZXN0ICUgdGV4dCAqIHRlc3QgXiB0ZXh0ICIpOworICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgcHMuc2V0U3RyaW5nKDEsIG51bGwpOworICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgcHMuY2xvc2UoKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRTdHJpbmcoMSwgInRlc3QgdGV4dCIpOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIHN0YXRtZW50LmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRTdHJpbmdfdGlueVRleHRGaWVsZCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgc3RyID0gInRlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdH50ZXN0XnRleHQkdGVzdCV0ZXN0KHRleHQpdGVzdEB0ZXh0NXRlc3QvdGVzdF50ZXh0JHRlc3QldGVzdCh0ZXh0KXRlc3RAdGV4dDV0ZXN0fnRlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdCI7CisgICAgICAgICAgICBTdHJpbmcgcXVlcnkgPSAiaW5zZXJ0IGludG8gdHlwZSAoVFRleHQpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKyAgICAgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldFN0cmluZygxLCBzdHIpOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB0eXBlIHdoZXJlIFRUZXh0PSciICsgc3RyICsgIiciKTsKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0U3RyaW5nKDEsICIiKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gdHlwZSB3aGVyZSBUVGV4dD0nJyIpOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRTdHJpbmcoMSwgIiAgICAgICAgICAgICAgICAgICAiKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gdHlwZSB3aGVyZSBUVGV4dD0nICAgICAgICAgICAgICAgICAgICciKTsKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0U3RyaW5nKDEsCisgICAgICAgICAgICAgICAgICAgICAgICAidGVzdF50ZXh0JHRlc3QldGVzdCh0ZXh0KXRlc3RAdGV4dDV0ZXN0fnRlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdC90ZXN0XnRleHQkdGVzdCV0ZXN0KHRleHQpdGVzdEB0ZXh0NXRlc3R+dGVzdF50ZXh0JHRlc3QldGVzdCh0ZXh0KXRlc3RAdGV4dDV0ZXN0KnRlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdH50ZXN0XnRleHQkdGVzdCV0ZXN0KHRleHQpdGVzdEB0ZXh0NXRlc3QvdGVzdF50ZXh0JHRlc3QldGVzdCh0ZXh0KXRlc3RAdGV4dDV0ZXN0fnRlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdC10ZXN0XnRleHQkdGVzdCV0ZXN0KHRleHQpdGVzdEB0ZXh0NXRlc3R+dGVzdF50ZXh0JHRlc3QldGVzdCh0ZXh0KXRlc3RAdGV4dDV0ZXN0L3Rlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdH50ZXN0XnRleHQkdGVzdCV0ZXN0KHRleHQpdGVzdEB0ZXh0NXRlc3QgdGVzdF50ZXh0JHRlc3QldGVzdCh0ZXh0KXRlc3RAdGV4dDV0ZXN0fnRlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdC90ZXN0XnRleHQkdGVzdCV0ZXN0KHRleHQpdGVzdEB0ZXh0NXRlc3R+dGVzdF50ZXh0JHRlc3QldGVzdCh0ZXh0KXRlc3RAdGV4dDV0ZXN0K3Rlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdH50ZXN0XnRleHQkdGVzdCV0ZXN0KHRleHQpdGVzdEB0ZXh0NXRlc3QvdGVzdF50ZXh0JHRlc3QldGVzdCh0ZXh0KXRlc3RAdGV4dDV0ZXN0fnRlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdD90ZXN0XnRleHQkdGVzdCV0ZXN0KHRleHQpdGVzdEB0ZXh0NXRlc3R+dGVzdF50ZXh0JHRlc3QldGVzdCh0ZXh0KXRlc3RAdGV4dDV0ZXN0L3Rlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdH50ZXN0XnRleHQkdGVzdCV0ZXN0KHRleHQpdGVzdEB0ZXh0NXRlc3QjdGVzdF50ZXh0JHRlc3QldGVzdCh0ZXh0KXRlc3RAdGV4dDV0ZXN0fnRlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdC90ZXN0XnRleHQkdGVzdCV0ZXN0KHRleHQpdGVzdEB0ZXh0NXRlc3R+dGVzdF50ZXh0JHRlc3QldGVzdCh0ZXh0KXRlc3RAdGV4dDV0ZXN0ICIpOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93biIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldFN0cmluZygxLCBudWxsKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd246ICIgKyBzcWxlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHBzLmNsb3NlKCk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0U3RyaW5nKDEsICJ0ZXN0IHRleHQiKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0U3RyaW5nX3RleHRGaWVsZCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgc3RyID0gInRlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdH50ZXN0XnRleHQkdGVzdCV0ZXN0KHRleHQpdGVzdEB0ZXh0NXRlc3QvdGVzdF50ZXh0JHRlc3QldGVzdCh0ZXh0KXRlc3RAdGV4dDV0ZXN0fnRlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdCI7CisgICAgICAgICAgICBTdHJpbmcgcXVlcnkgPSAiaW5zZXJ0IGludG8gdHlwZSAoVGV4dFZhbCkgdmFsdWVzICg/KTsiOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworICAgICAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0U3RyaW5nKDEsIHN0cik7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHR5cGUgd2hlcmUgVGV4dFZhbD0nIiArIHN0ciArICInIik7CisgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdldENvdW50KHJzKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldFN0cmluZygxLCAiIik7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHR5cGUgd2hlcmUgVGV4dFZhbD0nJyIpOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRTdHJpbmcoMSwgIiAgICAgICAgICAgICAgICAgICAiKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gdHlwZSB3aGVyZSBUZXh0VmFsPScgICAgICAgICAgICAgICAgICAgJyIpOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU3RyaW5nIGxvbmdTdHJpbmcgPSAiIHRlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdH50ZXN0XnRleHQkdGVzdCV0ZXN0KHRleHQpdGVzdEB0ZXh0NXRlc3QvIjsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgICAgICAgICAgICAgIGxvbmdTdHJpbmcgKz0gbG9uZ1N0cmluZzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBzLnNldFN0cmluZygxLCBsb25nU3RyaW5nKTsKKyAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKworICAgICAgICAgICAgcHMuc2V0U3RyaW5nKDEsIG51bGwpOworICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworCisgICAgICAgICAgICBwcy5jbG9zZSgpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldFN0cmluZygyLCAidGVzdCB0ZXh0Iik7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldFN0cmluZ19tZWRpdW1UZXh0RmllbGQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHN0ciA9ICJ0ZXN0XnRleHQkdGVzdCV0ZXN0KHRleHQpdGVzdEB0ZXh0NXRlc3R+dGVzdF50ZXh0JHRlc3QldGVzdCh0ZXh0KXRlc3RAdGV4dDV0ZXN0L3Rlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdH50ZXN0XnRleHQkdGVzdCV0ZXN0KHRleHQpdGVzdEB0ZXh0NXRlc3QiOworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKE1UZXh0KSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRTdHJpbmcoMSwgc3RyKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gdHlwZSB3aGVyZSBNVGV4dD0nIiArIHN0ciArICInIik7CisgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdldENvdW50KHJzKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldFN0cmluZygxLCAiIik7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHR5cGUgd2hlcmUgTVRleHQ9JyciKTsKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0U3RyaW5nKDEsICIgICAgICAgICAgICAgICAgICAgIik7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdAorICAgICAgICAgICAgICAgICAgICAgICAgLmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gdHlwZSB3aGVyZSBNVGV4dD0nICAgICAgICAgICAgICAgICAgICciKTsKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHBzLnNldFN0cmluZygxLCBudWxsKTsKKyAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgIHBzLmNsb3NlKCk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0U3RyaW5nKDIsICJ0ZXN0IHRleHQiKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBleGNlcHRpb24gdGVzdCBmYWlscworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRTdHJpbmdfbG9uZ1RleHRGaWVsZCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgc3RyID0gInRlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdH50ZXN0XnRleHQkdGVzdCV0ZXN0KHRleHQpdGVzdEB0ZXh0NXRlc3QvdGVzdF50ZXh0JHRlc3QldGVzdCh0ZXh0KXRlc3RAdGV4dDV0ZXN0fnRlc3RedGV4dCR0ZXN0JXRlc3QodGV4dCl0ZXN0QHRleHQ1dGVzdCI7CisgICAgICAgICAgICBTdHJpbmcgcXVlcnkgPSAiaW5zZXJ0IGludG8gdHlwZSAoTFRleHQpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKyAgICAgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldFN0cmluZygxLCBzdHIpOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB0eXBlIHdoZXJlIExUZXh0PSciICsgc3RyICsgIiciKTsKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0U3RyaW5nKDEsICIiKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gdHlwZSB3aGVyZSBMVGV4dD0nJyIpOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRTdHJpbmcoMSwgIiAgICAgICAgICAgICAgICAgICAiKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gdHlwZSB3aGVyZSBMVGV4dD0nICAgICAgICAgICAgICAgICAgICciKTsKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHBzLnNldFN0cmluZygxLCBudWxsKTsKKyAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgIHBzLmNsb3NlKCk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0U3RyaW5nKDEsICJ0ZXN0IHRleHQiKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBleGNlcHRpb24gdGVzdCBmYWlscworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRTaG9ydCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcyA9IG51bGw7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzMSA9IG51bGw7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzMiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgcXVlcnkgPSAiaW5zZXJ0IGludG8gdHlwZSAoU2ludCkgdmFsdWVzICg/KTsiOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworICAgICAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0U2hvcnQoMSwgU2hvcnQuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gdHlwZSB3aGVyZSBTaW50PSIgKyBTaG9ydC5NQVhfVkFMVUUpOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRTaG9ydCgxLCBTaG9ydC5NSU5fVkFMVUUpOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB0eXBlIHdoZXJlIFNpbnQ9IiArIFNob3J0Lk1JTl9WQUxVRSk7CisgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdldENvdW50KHJzKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwcy5jbG9zZSgpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldFNob3J0KDEsIFNob3J0Lk1JTl9WQUxVRSk7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5MSA9ICJpbnNlcnQgaW50byB0eXBlIChUaW50KSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwczEgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkxKTsKKyAgICAgICAgICAgIHBzMS5zZXRTaG9ydCgxLCBTaG9ydC5NQVhfVkFMVUUpOworCisgICAgICAgICAgICBTdHJpbmcgcXVlcnkyID0gImluc2VydCBpbnRvIHR5cGUgKEludFZhbCkgdmFsdWVzICg/KTsiOworICAgICAgICAgICAgcHMyID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5Mik7CisgICAgICAgICAgICBwczIuc2V0U2hvcnQoMSwgU2hvcnQuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgIHBzMi5leGVjdXRlKCk7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHR5cGUgd2hlcmUgSW50VmFsPSIgKyBTaG9ydC5NQVhfVkFMVUUpOworICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgICAgIHBzMS5jbG9zZSgpOworICAgICAgICAgICAgICAgIHBzMi5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBleGNlcHRpb24gdGVzdCBmYWlscworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRCb29sZWFuKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzID0gbnVsbDsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMxID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBxdWVyeSA9ICJpbnNlcnQgaW50byB0eXBlIChCb29sVmFsKSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRCb29sZWFuKDEsIGZhbHNlKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gdHlwZSB3aGVyZSBCb29sVmFsID0gMCIpOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRCb29sZWFuKDEsIHRydWUpOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB0eXBlIHdoZXJlIEJvb2xWYWw9IDEiKTsKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMiwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHBzLmNsb3NlKCk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0Qm9vbGVhbigxLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5MSA9ICJpbnNlcnQgaW50byB0eXBlIChUaW50KSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwczEgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkxKTsKKyAgICAgICAgICAgIHBzMS5zZXRCb29sZWFuKDEsIHRydWUpOworICAgICAgICAgICAgcHMxLmV4ZWN1dGUoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgICAgIHBzMS5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBleGNlcHRpb24gdGVzdCBmYWlscworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRCeXRlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzID0gbnVsbDsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMxID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBxdWVyeSA9ICJpbnNlcnQgaW50byB0eXBlIChUaW50KSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRCeXRlKDEsIEJ5dGUuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gdHlwZSB3aGVyZSBUaW50PSIgKyBCeXRlLk1BWF9WQUxVRSk7CisgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdldENvdW50KHJzKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldEJ5dGUoMSwgQnl0ZS5NSU5fVkFMVUUpOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB0eXBlIHdoZXJlIFRpbnQ9IiArIEJ5dGUuTUlOX1ZBTFVFKTsKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0Qnl0ZSgyLCBCeXRlLk1BWF9WQUxVRSk7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHMuY2xvc2UoKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRCeXRlKDEsIEJ5dGUuTUlOX1ZBTFVFKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBTdHJpbmcgcXVlcnkxID0gImluc2VydCBpbnRvIHR5cGUgKEludFZhbCkgdmFsdWVzICg/KTsiOworICAgICAgICAgICAgcHMxID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5MSk7CisgICAgICAgICAgICBwczEuc2V0Qnl0ZSgxLCBCeXRlLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBwczEuZXhlY3V0ZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgcHMxLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIHByZXBhcmVkU3RhdGVtZW50LmV4ZWN1dGUoKSBkb2VzIG5vdCByZXR1cm4gZmFsc2Ugb24gdXBkYXRlLgorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRCeXRlcygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBieXRlW10gYnl0ZXNBcnJheSA9IHsxLCAwfTsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMgPSBudWxsOworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwczEgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKExCbG9iKSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0Qnl0ZXMoMSwgYnl0ZXNBcnJheSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UocHMuZXhlY3V0ZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKHBzLmdldFVwZGF0ZUNvdW50KCkgPiAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93bjogIiArIHNxbGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRCeXRlcygyLCBieXRlc0FycmF5KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZCBSdW50aW1lRXhjZXB0aW9uIG9yIFNRTEV4Y2VwdGlvbgorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwcy5jbG9zZSgpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldEJ5dGVzKDEsIGJ5dGVzQXJyYXkpOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBTdHJpbmcgcXVlcnkxID0gImluc2VydCBpbnRvIHR5cGUgKFRCbG9iKSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwczEgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkxKTsKKworICAgICAgICAgICAgcHMuc2V0Qnl0ZXMoMSwgYnl0ZXNBcnJheSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShwcy5leGVjdXRlKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShwcy5nZXRVcGRhdGVDb3VudCgpID4gMCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworCisgICAgICAgICAgICAgICAgaWYgKHBzICE9IG51bGwpIHBzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgaWYgKHBzMSAhPSBudWxsKSBwczEuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gcHJlcGFyZWRTdGF0ZW1lbnQuZXhlY3V0ZSgpIGRvZXMgbm90IHJldHVybiBmYWxzZSBvbiB1cGRhdGUuCisgICAgcHVibGljIHZvaWQgdGVzdFNldEJpZ0RlY2ltYWwoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgQmlnRGVjaW1hbCBiZCA9IG5ldyBCaWdEZWNpbWFsKCI1MCIpOworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcyA9IG51bGw7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzMSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgcXVlcnkgPSAiaW5zZXJ0IGludG8gdHlwZSAoRGVjVmFsKSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICAgICAgcHMuc2V0QmlnRGVjaW1hbCgxLCBiZCk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShwcy5leGVjdXRlKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShwcy5nZXRVcGRhdGVDb3VudCgpID4gMCk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0QmlnRGVjaW1hbCgyLCBiZCk7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImJhZCBwYXJhbWV0ZXIgaW5kZXgiLCBzcWxlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0QmlnRGVjaW1hbCgtMiwgYmQpOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJiYWQgcGFyYW1ldGVyIGluZGV4Iiwgc3FsZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5MSA9ICJpbnNlcnQgaW50byB0eXBlIChUaW50KSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwczEgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkxKTsKKworICAgICAgICAgICAgcHMxLnNldEJpZ0RlY2ltYWwoMSwgYmQpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAocHMgIT0gbnVsbCkgcHMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBpZiAocHMxICE9IG51bGwpIHBzMS5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBwcmVwYXJlZFN0YXRlbWVudC5leGVjdXRlKCkgZG9lcyBub3QgcmV0dXJuIGZhbHNlIG9uIHVwZGF0ZS4gU2V0dGluZyBhCisgICAgICogZGF0YSBmb3IgYSBkZWNsYXJlZCBJTlRFR0VSIHNob3VsZCB0aHJvdyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0RGF0ZV9pbnRfRGF0ZSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBDYWxlbmRhciBjYWwgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTc5OSwgNSwgMjYpOworICAgICAgICBEYXRlW10gZGF0ZXMgPSB7CisgICAgICAgICAgICAgICAgbmV3IERhdGUoY2FsLmdldFRpbWVJbk1pbGxpcygpKSwgbmV3IERhdGUoSW50ZWdlci5NQVhfVkFMVUUpLAorICAgICAgICAgICAgICAgIG5ldyBEYXRlKDEyMzQ1Njc4OSl9OworCisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzID0gbnVsbDsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMxID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBxdWVyeSA9ICJpbnNlcnQgaW50byB0eXBlIChkYXRlVmFsKSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGF0ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBwcy5zZXREYXRlKDEsIGRhdGVzW2ldKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShwcy5leGVjdXRlKCkpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUocHMuZ2V0VXBkYXRlQ291bnQoKSA+IDApOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldERhdGUoMiwgZGF0ZXNbMF0pOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHBzLmNsb3NlKCk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0RGF0ZSgxLCBkYXRlc1swXSk7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5MSA9ICJpbnNlcnQgaW50byB0eXBlIChUaW50KSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwczEgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkxKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwczEuc2V0RGF0ZSgxLCBkYXRlc1swXSk7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlNRTGl0ZS5FeGNlcHRpb246IGVycm9yIGluIHByZXBhcmUiLCBzcWxlCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKHBzICE9IG51bGwpIHBzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgaWYgKHBzMSAhPSBudWxsKSBwczEuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gcHJlcGFyZWRTdGF0ZW1lbnQuZXhlY3V0ZSgpIGRvZXMgbm90IHJldHVybiBmYWxzZSBvbiB1cGRhdGUuCisgICAgcHVibGljIHZvaWQgdGVzdFNldERhdGVfaW50X0RhdGVfQ2FsZW5kYXIoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgQ2FsZW5kYXJbXSBjYWxzID0geyBDYWxlbmRhci5nZXRJbnN0YW5jZSgpLAorICAgICAgICAgICAgICAgIENhbGVuZGFyLmdldEluc3RhbmNlKExvY2FsZS5HRVJNQU5ZKSwKKyAgICAgICAgICAgICAgICBDYWxlbmRhci5nZXRJbnN0YW5jZShUaW1lWm9uZS5nZXREZWZhdWx0KCkpIH07CisgICAgICAgIENhbGVuZGFyIGNhbCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxNzk5LDUsMjYpOworCisgICAgICAgIERhdGVbXSBkYXRlcyA9IHsgbmV3IERhdGUoY2FsLmdldFRpbWVJbk1pbGxpcygpKSwgbmV3IERhdGUoSW50ZWdlci5NQVhfVkFMVUUpLAorICAgICAgICAgICAgICAgIG5ldyBEYXRlKDEyMzQ1Njc4OSkgfTsKKworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcyA9IG51bGw7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzMSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgcXVlcnkgPSAiaW5zZXJ0IGludG8gdHlwZSAoZGF0ZVZhbCkgdmFsdWVzICg/KTsiOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgcHMuc2V0RGF0ZSgxLCBkYXRlc1tpXSwgY2Fsc1tpXSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UocHMuZXhlY3V0ZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKHBzLmdldFVwZGF0ZUNvdW50KCkgPiAwKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXREYXRlKDIsIGRhdGVzWzBdLCBjYWxzWzBdKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHMuY2xvc2UoKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXREYXRlKDEsIGRhdGVzWzBdLCBjYWxzWzFdKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5MSA9ICJpbnNlcnQgaW50byB0eXBlIChUaW50KSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwczEgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkxKTsKKworICAgICAgICAgICAgcHMxLnNldERhdGUoMSwgZGF0ZXNbMF0sIGNhbHNbMl0pOworICAgICAgICAgICAgcHMxLmV4ZWN1dGUoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKHBzICE9IG51bGwpIHBzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgaWYgKHBzMSAhPSBudWxsKSBwczEuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyB0ZXN0IGRvZXNuJ3QgcGFzcyBvbiBSSQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXROdWxsX2ludF9pbnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKEJvb2xWYWwsIEludFZhbCkgdmFsdWVzICgndHJ1ZScsID8pOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXROdWxsKDEsIFR5cGVzLklOVEVHRVIpOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcHMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKEJvb2xWYWwsIExvbmdWYWwpIHZhbHVlcyAoJ3RydWUnLCA/KTsiOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldE51bGwoMSwgVHlwZXMuQklHSU5UKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBxdWVyeSA9ICJpbnNlcnQgaW50byB0eXBlIChCb29sVmFsLCBEZWNWYWwpIHZhbHVlcyAoJ3RydWUnLCA/KSI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0TnVsbCgxLCBUeXBlcy5ERUNJTUFMKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBxdWVyeSA9ICJpbnNlcnQgaW50byB0eXBlIChCb29sVmFsLCBkYXRlVmFsKSB2YWx1ZXMgKCd0cnVlJywgPyk7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXROdWxsKDEsIFR5cGVzLkRBVEUpOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcHMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKEJvb2xWYWwsIEJsb2JWYWwpIHZhbHVlcyAoJ3RydWUnLCA/KTsiOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldE51bGwoMSwgVHlwZXMuQkxPQik7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcXVlcnkgPSAiaW5zZXJ0IGludG8gdHlwZSAoQm9vbFZhbCwgVGV4dFZhbCkgdmFsdWVzICgndHJ1ZScsID8pOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBwcy5zZXROdWxsKDEsIFR5cGVzLkNIQVIpOworICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVRFRzIGFuZCBSZWYgdHlwZXMgbm90IHN1cHBvcnRlZCBpbiBTUUxpdGUgdiAzCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNldE51bGxJbnRpbnRTdHJpbmcoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gdGVzdCBVRFQKKyAgICAgICAgU3RyaW5nIHR5cGVDcmVhdGlvblN0bXRVRFQgPSAiQ1JFQVRFIFRZUEUgYWRkcmVzc1R5cGUgQVMgIgorICAgICAgICAgICAgICAgICsgIiggc3RyZWV0IElOVEVHRVIsIHppcCBURVhUKTsiOworICAgICAgICBTdHJpbmcgcGVyc29uVGFibGVDcmVhdGVVRFQgPSAiQ1JFQVRFIFRBQkxFIHBlcnNvbiAobmFtZSBURVhULCBhZGRyZXNzIGFkZHJlc3NUeXBlKTsiOworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKHR5cGVDcmVhdGlvblN0bXRVRFQpOworICAgICAgICAgICAgc3QuZXhlY3V0ZShwZXJzb25UYWJsZUNyZWF0ZVVEVCk7CisgICAgICAgICAgICBmYWlsKCJVRFRzIGFuZCBSZWYgVHlwZXMgbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImluc2VydCBpbnRvIHBlcnNvbiAobmFtZSwgYWRkcmVzcykgdmFsdWVzICgnSGFucycsID8pOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldE51bGwoMSwgVHlwZXMuREFUQUxJTkspOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93bjogIiArIHNxbGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgICAgICBzcWxlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIFVEVHMgb3IgUmVmIHR5cGVzIG5vdCBzdXBwb3J0ZWQKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoImRyb3AgdGFibGUgaWYgZXhpc3RzIHBlcnNvbiIpOworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3Qgbm9uIFVEVCBSRUYgdHlwZSBFeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgU3RyaW5nIHBlcnNvblRhYmxlQ3JlYXRlID0gImNyZWF0ZSB0YWJsZSBwZXJzb24gKG5hbWUgVEVYVCwgQWRkcmVzcyBURVhUKSI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKHBlcnNvblRhYmxlQ3JlYXRlKTsKKyAgICAgICAgICAgIFN0cmluZyBpbnNlcnQKKyAgICAgICAgICAgICAgICAgICAgPSAiaW5zZXJ0IGludG8gcGVyc29uIChuYW1lLCBhZGRyZXNzKSB2YWx1ZXMgKD8sICcxNjAwIEFtcGhpdGhlYXRyZSBNb3VudGFpbiBWaWV3Jyk7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KGluc2VydCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldE51bGwoMSwgMSwgIiIpOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJTUUxpdGUuRXhjZXB0aW9uOiBlcnJvciBpbiBzdGVwIiwgc3FsZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuZXhlY3V0ZSgiZHJvcCB0YWJsZSBpZiBleGlzdHMgcGVyc29uIik7CisgICAgICAgICAgICAgICAgcHMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gdGVzdCBub24gVURUIFJFRiB0eXBlIE9LCisKKyAgICAgICAgcGVyc29uVGFibGVDcmVhdGUgPSAiY3JlYXRlIHRhYmxlIHBlcnNvbiAobmFtZSBURVhULCBBZGRyZXNzIFRFWFQpIjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGUoImRyb3AgdGFibGUgaWYgZXhpc3RzIHBlcnNvbiIpOworICAgICAgICAgICAgc3QuZXhlY3V0ZShwZXJzb25UYWJsZUNyZWF0ZSk7CisgICAgICAgICAgICBTdHJpbmcgaW5zZXJ0CisgICAgICAgICAgICAgICAgICAgID0gImluc2VydCBpbnRvIHBlcnNvbiAobmFtZSwgYWRkcmVzcykgdmFsdWVzICg/LCAnMTYwMCBBbXBoaXRoZWF0cmUgTW91bnRhaW4gVmlldycpOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChpbnNlcnQpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXROdWxsKDEsIDEsICIiKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJkcm9wIHRhYmxlIGlmIGV4aXN0cyBwZXJzb24iKTsKKyAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBleGNlcHRpb24gdGVzdCBmYWlscworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRPYmplY3RfaW50X09iamVjdCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgcXVlcnkgPSAiaW5zZXJ0IGludG8gdHlwZSAoSW50VmFsKSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRPYmplY3QoMSwgSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB0eXBlIHdoZXJlIEludFZhbD0iCisgICAgICAgICAgICAgICAgICAgICAgICArIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKExvbmdWYWwpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRPYmplY3QoMSwgInRlc3QgdGV4dCIpOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0ICogZnJvbSB0eXBlIHdoZXJlIExvbmdWYWw9J3Rlc3QgdGV4dCc7Iik7CisgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdldENvdW50KHJzKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBxdWVyeSA9ICJpbnNlcnQgaW50byB0eXBlIChEZWNWYWwpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRPYmplY3QoMSwgbmV3IE9iamVjdCgpKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd24iKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcXVlcnkgPSAiaW5zZXJ0IGludG8gdHlwZSAoZGF0ZVZhbCkgdmFsdWVzICg/KTsiOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworICAgICAgICAgICAgRGF0ZSBkID0gbmV3IERhdGUoMTIzNDU2Nzg5KTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRPYmplY3QoMSwgZCk7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHR5cGUgd2hlcmUgZGF0ZVZhbD0nIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBkLmdldFRpbWUoKSArICInOyIpOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gdGhpcyBzdWIgdGVzdCBkb2Vzbid0IHBhc3Mgb24gUkkKKyAgICAgICAgICAgIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKEJsb2JWYWwpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRPYmplY3QoMSwgbnVsbCk7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBzLnNldE9iamVjdCgxLCAidGVzdCB0ZXh0Iik7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgfQorCisgICAgIC8qKgorICAgICAgKiBUaGlzIHRlc3QgZG9lc24ndCBwYXNzIG9uIFJJCisgICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRPYmplY3RfaW50X09iamVjdF9pbnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKEludFZhbCkgdmFsdWVzICg/KTsiOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworICAgICAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0T2JqZWN0KDEsIEludGVnZXIuTUFYX1ZBTFVFLCBUeXBlcy5JTlRFR0VSKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gdHlwZSB3aGVyZSBJbnRWYWw9IgorICAgICAgICAgICAgICAgICAgICAgICAgKyBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdldENvdW50KHJzKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBxdWVyeSA9ICJpbnNlcnQgaW50byB0eXBlIChMb25nVmFsKSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0T2JqZWN0KDEsICJ0ZXN0IHRleHQiLCBUeXBlcy5DSEFSKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gdHlwZSB3aGVyZSBMb25nVmFsPSd0ZXN0IHRleHQnOyIpOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcXVlcnkgPSAiaW5zZXJ0IGludG8gdHlwZSAoRGVjVmFsKSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBwcy5zZXRPYmplY3QoMSwgbmV3IE9iamVjdCgpLCBUeXBlcy5ERUNJTUFMKTsKKyAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKworICAgICAgICAgICAgcXVlcnkgPSAiaW5zZXJ0IGludG8gdHlwZSAoZGF0ZVZhbCkgdmFsdWVzICg/KTsiOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworICAgICAgICAgICAgRGF0ZSBkID0gbmV3IERhdGUoMTIzNDU2Nzg5KTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRPYmplY3QoMSwgZCwgVHlwZXMuREFURSk7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHR5cGUgd2hlcmUgZGF0ZVZhbD0nIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBkLmdldFRpbWUoKSArICInOyIpOworICAgICAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gdGhpcyBzdWIgdGVzdCBkb2Vzbid0IHBhc3Mgb24gUkkKKyAgICAgICAgICAgIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKEJsb2JWYWwpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRPYmplY3QoMSwgIiIsIFR5cGVzLkJMT0IpOworICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcy5zZXRPYmplY3QoMSwgSW50ZWdlci5NQVhfVkFMVUUsIFR5cGVzLklOVEVHRVIpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIHRlc3QgZG9lc24ndCBwYXNzIG9uIFJJOyBGYWlscyBmb3IgVHlwZXMuREFURQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRPYmplY3RfaW50X09iamVjdF9pbnRfaW50KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBxdWVyeSA9ICJpbnNlcnQgaW50byB0eXBlIChJbnRWYWwpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKyAgICAgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldE9iamVjdCgxLCBJbnRlZ2VyLk1BWF9WQUxVRSwgVHlwZXMuSU5URUdFUiwKKyAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gdHlwZSB3aGVyZSBJbnRWYWw9IgorICAgICAgICAgICAgICAgICAgICAgICAgKyBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdldENvdW50KHJzKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBxdWVyeSA9ICJpbnNlcnQgaW50byB0eXBlIChMb25nVmFsKSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0T2JqZWN0KDEsICJ0ZXN0IHRleHQiLCBUeXBlcy5DSEFSLCBJbnRlZ2VyLk1JTl9WQUxVRSk7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHR5cGUgd2hlcmUgTG9uZ1ZhbD0ndGVzdCB0ZXh0JzsiKTsKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZ2V0Q291bnQocnMpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKERlY1ZhbCkgdmFsdWVzICg/KTsiOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworICAgICAgICAgICAgQmlnRGVjaW1hbCBiZDIgPSBuZXcgQmlnRGVjaW1hbCgiMTIuMjEiKTsKKyAgICAgICAgICAgIHBzLnNldE9iamVjdCgxLCBiZDIsIFR5cGVzLkRFQ0lNQUwsIDIpOworICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworCisgICAgICAgICAgICBxdWVyeSA9ICJpbnNlcnQgaW50byB0eXBlIChkYXRlVmFsKSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBEYXRlIGQgPSBuZXcgRGF0ZSgxMjM0NTY3ODkpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRPYmplY3QoMSwgZCAsIFR5cGVzLkRBVEUsIC0xKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoInNlbGVjdCAqIGZyb20gdHlwZSB3aGVyZSBkYXRlVmFsPSciCisgICAgICAgICAgICAgICAgICAgICAgICArIGQuZ2V0VGltZSgpICsgIic7Iik7CisgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdldENvdW50KHJzKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB0aGlzIHN1YiB0ZXN0IGRvZXNuJ3QgcGFzcyBvbiBSSQorICAgICAgICAgICAgcXVlcnkgPSAiaW5zZXJ0IGludG8gdHlwZShCbG9iVmFsKSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0T2JqZWN0KDEsICIiLCBUeXBlcy5CTE9CLCAwKTsKKyAgICAgICAgICAgICAgICBwcy5leGVjdXRlKCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHMuc2V0T2JqZWN0KDEsICJ0ZXN0IHRleHQiLCBUeXBlcy5DSEFSLCBJbnRlZ2VyLk1JTl9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIHN0YXRlbWVudC5jbG9zZSgpIGRvZXMgbm90IHdyYXAgdXAKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0VGltZWludF9UaW1lKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFRpbWVbXSB0aW1lcyA9IHsgbmV3IFRpbWUoMjQsIDI1LCAyNiksIG5ldyBUaW1lKEludGVnZXIuTUFYX1ZBTFVFKSwKKyAgICAgICAgICAgICAgICBuZXcgVGltZSgxMjM0NTY3ODkpIH07CisKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMgPSBudWxsOworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwczEgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKHRpbWVWYWwpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKyAgICAgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRpbWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcHMuc2V0VGltZSgxLCB0aW1lc1tpXSk7CisgICAgICAgICAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHR5cGUgd2hlcmUgdGltZVZhbD0nIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdGltZXNbaV0uZ2V0VGltZSgpICsgIiciKTsKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBnZXRDb3VudChycykpOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRUaW1lKDIsIHRpbWVzWzBdKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZCBpbmRleCBvdXQgb2YgYm91bmRzCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHBzLmNsb3NlKCk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHMuc2V0VGltZSgxLCB0aW1lc1swXSk7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN0cmluZyBxdWVyeTEgPSAiaW5zZXJ0IGludG8gdHlwZSAoVGludCkgdmFsdWVzICg/KSI7CisgICAgICAgICAgICBwczEgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkxKTsKKyAgICAgICAgICAgIHBzMS5zZXRUaW1lKDEsIHRpbWVzWzBdKTsKKyAgICAgICAgICAgIHBzMS5leGVjdXRlKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgcHMxLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIHByZXBhcmVkU3RhdGVtZW50LmV4ZWN1dGUoKSBkb2VzIG5vdCByZXR1cm4gRmFsc2Ugb24gdXBkYXRlLgorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRUaW1lX2ludF9UaW1lX0NhbGVuZGFyKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIENhbGVuZGFyW10gY2FscyA9IHsgQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKSwKKyAgICAgICAgICAgICAgICBDYWxlbmRhci5nZXRJbnN0YW5jZShMb2NhbGUuR0VSTUFOWSksCisgICAgICAgICAgICAgICAgQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoVGltZVpvbmUuZ2V0RGVmYXVsdCgpKSB9OworCisgICAgICAgIFRpbWVbXSB0aW1lcyA9IHsgbmV3IFRpbWUoMjQsIDI1LCAyNiksIG5ldyBUaW1lKEludGVnZXIuTUFYX1ZBTFVFKSwKKyAgICAgICAgICAgICAgICBuZXcgVGltZSgxMjM0NTY3ODkpIH07CisKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMgPSBudWxsOworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwczEgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKHRpbWVWYWwpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKyAgICAgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRpbWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcHMuc2V0VGltZSgxLCB0aW1lc1tpXSwgY2Fsc1tpXSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKHBzLmV4ZWN1dGUoKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUocHMuZ2V0VXBkYXRlQ291bnQoKSA+IDApOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRUaW1lKDIsIHRpbWVzWzBdLCBjYWxzWzBdKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwcy5jbG9zZSgpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLnNldFRpbWUoLTIsIHRpbWVzWzBdLCBjYWxzWzFdKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5MSA9ICJpbnNlcnQgaW50byB0eXBlIChUaW50KSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBwczEgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkxKTsKKyAgICAgICAgICAgIHBzMS5zZXRUaW1lKDEsIHRpbWVzWzBdLCBjYWxzWzJdKTsKKyAgICAgICAgICAgIHBzMS5leGVjdXRlKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgcHMxLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIHByZXBhcmVkU3RhdGVtZW50LmV4ZWN1dGUoKSBkb2VzIG5vdCByZXR1cm4gZmFsc2Ugb24gdXBkYXRlLgorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRUaW1lc3RhbXBfaW50X1RpbWVzdGFtcCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBUaW1lc3RhbXBbXSB0aW1lc3RhbXBzID0geyBuZXcgVGltZXN0YW1wKDIwMDcsIDEwLCAxNywgMTksIDA2LCA1MCwgMjMpLAorICAgICAgICAgICAgICAgIG5ldyBUaW1lc3RhbXAoMTIzKSB9OworCisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzID0gbnVsbDsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMxID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBxdWVyeSA9ICJpbnNlcnQgaW50byB0eXBlIChUUykgdmFsdWVzICg/KTsiOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRpbWVzdGFtcHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBwcy5zZXRUaW1lc3RhbXAoMSwgdGltZXN0YW1wc1tpXSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UocHMuZXhlY3V0ZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKHBzLmdldFVwZGF0ZUNvdW50KCkgPiAwKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRUaW1lc3RhbXAoMiwgdGltZXN0YW1wc1swXSk7CisgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRUaW1lc3RhbXAoLTIsIHRpbWVzdGFtcHNbMF0pOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBTdHJpbmcgcXVlcnkxID0gImluc2VydCBpbnRvIHR5cGUgKFRpbnQpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgICAgIHBzMSA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeTEpOworICAgICAgICAgICAgcHMxLnNldFRpbWVzdGFtcCgxLCB0aW1lc3RhbXBzWzBdKTsKKyAgICAgICAgICAgIHBzMS5leGVjdXRlKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgcHMxLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRCbG9iKCkgeworICAgICAgICBSZXN1bHRTZXQgcmVzID0gbnVsbDsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMgPSBudWxsOworICAgICAgICBCbG9iIG1vY2sgPSBuZXcgTW9ja0Jsb2IoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBuZXZlckV4ZWN1dGVkUXVlcnkgPSAic2VsZWN0IFRCbG9iIGZyb20gdHlwZTsiOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQobmV2ZXJFeGVjdXRlZFF1ZXJ5KTsKKyAgICAgICAgICAgIHBzLnNldEJsb2IoMSxtb2NrKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0Q2xvYigpIHsKKyAgICAgICAgUmVzdWx0U2V0IHJlcyA9IG51bGw7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzID0gbnVsbDsKKyAgICAgICAgQ2xvYiBtb2NrID0gbmV3IE1vY2tDbG9iKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgbmV2ZXJFeGVjdXRlZFF1ZXJ5ID0gInNlbGVjdCBUQmxvYiBmcm9tIHR5cGU7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KG5ldmVyRXhlY3V0ZWRRdWVyeSk7CisgICAgICAgICAgICBwcy5zZXRDbG9iKDEsbW9jayk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQgbm90IHN1cHBvcnRlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgLy8gcHJlcGFyZWRTdGF0ZW1lbnQuZXhlY3V0ZSgpIGRvZXMgbm90IHJldHVybiBmYWxzZSBvbiB1cGRhdGUuCisgICAgcHVibGljIHZvaWQgdGVzdFNldFRpbWVzdGFtcEludFRpbWVzdGFtcENhbGVuZGFyKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIENhbGVuZGFyW10gY2FscyA9IHsgQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKSwKKyAgICAgICAgICAgICAgICBDYWxlbmRhci5nZXRJbnN0YW5jZShMb2NhbGUuR0VSTUFOWSksCisgICAgICAgICAgICAgICAgQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoVGltZVpvbmUuZ2V0RGVmYXVsdCgpKSB9OworCisgICAgICAgIFRpbWVzdGFtcFtdIHRpbWVzdGFtcHMgPSB7IG5ldyBUaW1lc3RhbXAoMjAwNywgMTAsIDE3LCAxOSwgMDYsIDUwLCAyMyksCisgICAgICAgICAgICAgICAgbmV3IFRpbWVzdGFtcCgxMjMpIH07CisKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHMgPSBudWxsOworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwczEgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKHRpbWVWYWwpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKyAgICAgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRpbWVzdGFtcHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBwcy5zZXRUaW1lc3RhbXAoMSwgdGltZXN0YW1wc1tpXSwgY2Fsc1tpXSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKHBzLmV4ZWN1dGUoKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUocHMuZ2V0VXBkYXRlQ291bnQoKSA+IDApOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRUaW1lc3RhbXAoMiwgdGltZXN0YW1wc1swXSwgY2Fsc1swXSk7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBwcy5jbG9zZSgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcy5zZXRUaW1lc3RhbXAoMSwgdGltZXN0YW1wc1swXSwgY2Fsc1sxXSk7CisgICAgICAgICAgICAgICAgcHMuZXhlY3V0ZSgpOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgICAgICBTdHJpbmcgcXVlcnkxID0gImluc2VydCBpbnRvIHR5cGUgKFRpbnQpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgICAgIHBzMSA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeTEpOworICAgICAgICAgICAgcHMxLnNldFRpbWVzdGFtcCgxLCB0aW1lc3RhbXBzWzBdLCBjYWxzWzJdKTsKKyAgICAgICAgICAgIHBzMS5leGVjdXRlKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgcHMxLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRVUkwoKSB7CisgICAgICAgIFJlc3VsdFNldCByZXMgPSBudWxsOworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgcXVlcnkgPSAiaW5zZXJ0IGludG8gdHlwZSAoVFRleHQpIHZhbHVlcyAoPyk7IjsKKyAgICAgICAgICAgIHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKyAgICAgICAgICAgIHBzLnNldFVSTCgxLCBuZXcgVVJMKCJodHRwOi8vd3d3LmFuZHJvaWQuY29tIikpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgLy9vaworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXJyb3IgaW4gdGVzdCBzZXR1cCAiK2UuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRBcnJheSgpIHsKKyAgICAgICAgUmVzdWx0U2V0IHJlcyA9IG51bGw7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzID0gbnVsbDsKKyAgICAgICAgQXJyYXkgYSA9IG5ldyBNb2NrQXJyYXkoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBxdWVyeSA9ICJpbnNlcnQgaW50byB0eXBlIChUVGV4dCkgdmFsdWVzICg/KTsiOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworICAgICAgICAgICAgcHMuc2V0QXJyYXkoMSwgbmV3IE1vY2tBcnJheSgpKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFcnJvciBpbiB0ZXN0IHNldHVwICIrZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldFJlZigpIHsKKyAgICAgICAgUmVzdWx0U2V0IHJlcyA9IG51bGw7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzID0gbnVsbDsKKyAgICAgICAgUmVmIG1vY2sgPSBuZXcgTW9ja1JlZigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIG5ldmVyRXhlY3V0ZWRRdWVyeSA9ICJzZWxlY3QgVEJsb2IgZnJvbSB0eXBlOyI7CisgICAgICAgICAgICBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChuZXZlckV4ZWN1dGVkUXVlcnkpOworICAgICAgICAgICAgcHMuc2V0UmVmKDEsbW9jayk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQgbm90IHN1cHBvcnRlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0VW5pY29kZXN0cmVhbSgpIHsKKyAgICAgICAgUmVzdWx0U2V0IHJlcyA9IG51bGw7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBxdWVyeSA9ICJpbnNlcnQgaW50byB0eXBlIChUVGV4dCkgdmFsdWVzICg/KTsiOworICAgICAgICAgICAgcHMgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnkpOworICAgICAgICAgICAgSW5wdXRTdHJlYW0gZmlsZSA9IENsYXNzLmZvck5hbWUodGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSkKKyAgICAgICAgICAgIC5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvYmxvYi5jIik7CisgICAgICAgICAgICBwcy5zZXRVbmljb2RlU3RyZWFtKDAsIGZpbGUsIDEwMCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQgbm90IHN1cHBvcnRlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXJyb3IgaW4gdGVzdCBzZXR1cCAiK2UuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0Q2hhcmFjdGVyU3RlYW0oKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKFRUZXh0KSB2YWx1ZXMgKD8pOyI7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHBzID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KHF1ZXJ5KTsKKyAgICAgICAgSW5wdXRTdHJlYW0gZmlsZSA9IE9sZFByZXBhcmVkU3RhdGVtZW50VGVzdC5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvYmxvYi5jIik7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkVycm9yIGluIHRlc3Qgc2V0dXA6IGZpbGUgbm90IGZvdW5kIixmaWxlKTsKKyAgICAgICAgUmVhZGVyIHJlYWRlciA9IG5ldyBJbnB1dFN0cmVhbVJlYWRlcihmaWxlKTsKKyAgICAgICAgcHMuc2V0Q2hhcmFjdGVyU3RyZWFtKDEsIHJlYWRlciwgMTAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0QXNjaWlTdHJlYW0oKSB7CisgICAgICAgIFJlc3VsdFNldCByZXMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKFRUZXh0KSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBmaWxlID0gT2xkUHJlcGFyZWRTdGF0ZW1lbnRUZXN0LmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0oIi9ibG9iLmMiKTsKKyAgICAgICAgICAgIHBzLnNldEFzY2lpU3RyZWFtKDAsIGZpbGUsIDEwMCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQgbm90IHN1cHBvcnRlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkVycm9yIGluIHRlc3Qgc2V0dXAgIitlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldEJpbmFyeVN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gImluc2VydCBpbnRvIHR5cGUgKFRUZXh0KSB2YWx1ZXMgKD8pOyI7CisgICAgICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcyA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBmaWxlID0gT2xkUHJlcGFyZWRTdGF0ZW1lbnRUZXN0LmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0oIi9ibG9iLmMiKTsKKyAgICAgICAgICAgIHBzLnNldEJpbmFyeVN0cmVhbSgwLCBmaWxlLCAxMDApOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIE1vY2tSZWYgaW1wbGVtZW50cyBSZWYgeworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VUeXBlTmFtZSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IGdldE9iamVjdCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IGdldE9iamVjdChNYXA8U3RyaW5nLCBDbGFzczw/Pj4gbWFwKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0T2JqZWN0KE9iamVjdCB2YWx1ZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7fQorICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgTW9ja0FycmF5IGltcGxlbWVudHMgQXJyYXkgeworCisgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0QXJyYXkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBnZXRBcnJheShsb25nIGluZGV4LCBpbnQgY291bnQpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IGdldEFycmF5KGxvbmcgaW5kZXgsIGludCBjb3VudCwgTWFwPFN0cmluZywgQ2xhc3M8Pz4+IG1hcCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBnZXRBcnJheShNYXA8U3RyaW5nLCBDbGFzczw/Pj4gbWFwKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXRCYXNlVHlwZSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VUeXBlTmFtZSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUmVzdWx0U2V0IGdldFJlc3VsdFNldCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUmVzdWx0U2V0IGdldFJlc3VsdFNldChsb25nIGluZGV4LCBpbnQgY291bnQpCisgICAgICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBSZXN1bHRTZXQgZ2V0UmVzdWx0U2V0KGxvbmcgaW5kZXgsIGludCBjb3VudCwKKyAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBDbGFzczw/Pj4gbWFwKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFJlc3VsdFNldCBnZXRSZXN1bHRTZXQoTWFwPFN0cmluZywgQ2xhc3M8Pz4+IG1hcCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgZnJlZSgpIHRocm93cyBTUUxFeGNlcHRpb24ge30KKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIE1vY2tCbG9iIGltcGxlbWVudHMgQmxvYiB7CisKKyAgICAgICAgcHVibGljIElucHV0U3RyZWFtIGdldEJpbmFyeVN0cmVhbSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEJ5dGVzKGxvbmcgcG9zLCBpbnQgbGVuZ3RoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGxvbmcgbGVuZ3RoKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBsb25nIHBvc2l0aW9uKEJsb2IgcGF0dGVybiwgbG9uZyBzdGFydCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBsb25nIHBvc2l0aW9uKGJ5dGVbXSBwYXR0ZXJuLCBsb25nIHN0YXJ0KSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE91dHB1dFN0cmVhbSBzZXRCaW5hcnlTdHJlYW0obG9uZyBwb3MpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IHNldEJ5dGVzKGxvbmcgcG9zLCBieXRlW10gdGhlQnl0ZXMpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IHNldEJ5dGVzKGxvbmcgcG9zLCBieXRlW10gdGhlQnl0ZXMsIGludCBvZmZzZXQsIGludCBsZW4pCisgICAgICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHRydW5jYXRlKGxvbmcgbGVuKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgZnJlZSgpIHRocm93cyBTUUxFeGNlcHRpb24ge30KKworICAgICAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0QmluYXJ5U3RyZWFtKGxvbmcgcG9zLCBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgTW9ja0Nsb2IgaW1wbGVtZW50cyBDbG9iIHsKKworICAgICAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0QXNjaWlTdHJlYW0oKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFJlYWRlciBnZXRDaGFyYWN0ZXJTdHJlYW0oKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRTdWJTdHJpbmcobG9uZyBwb3MsIGludCBsZW5ndGgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgbG9uZyBsZW5ndGgoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGxvbmcgcG9zaXRpb24oQ2xvYiBzZWFyY2hzdHIsIGxvbmcgc3RhcnQpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgbG9uZyBwb3NpdGlvbihTdHJpbmcgc2VhcmNoc3RyLCBsb25nIHN0YXJ0KSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE91dHB1dFN0cmVhbSBzZXRBc2NpaVN0cmVhbShsb25nIHBvcykgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBXcml0ZXIgc2V0Q2hhcmFjdGVyU3RyZWFtKGxvbmcgcG9zKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBzZXRTdHJpbmcobG9uZyBwb3MsIFN0cmluZyBzdHIpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IHNldFN0cmluZyhsb25nIHBvcywgU3RyaW5nIHN0ciwgaW50IG9mZnNldCwgaW50IGxlbikKKyAgICAgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgdHJ1bmNhdGUobG9uZyBsZW4pIHRocm93cyBTUUxFeGNlcHRpb24ge30KKworICAgICAgICBwdWJsaWMgdm9pZCBmcmVlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7fQorCisgICAgICAgIHB1YmxpYyBSZWFkZXIgZ2V0Q2hhcmFjdGVyU3RyZWFtKGxvbmcgcG9zLCBsb25nIGxlbmd0aCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc3FsL09sZFJlc3VsdFNldEdldHRlclRlc3RzLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NxbC9PbGRSZXN1bHRTZXRHZXR0ZXJUZXN0cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFiOGIxNDAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NxbC9PbGRSZXN1bHRTZXRHZXR0ZXJUZXN0cy5qYXZhCkBAIC0wLDAgKzEsMTQ1OCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBHb29nbGUgSW5jLgorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnNxbDsKKworCitpbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhOworaW1wb3J0IGphdmEuc3FsLkRhdGU7CitpbXBvcnQgamF2YS5zcWwuUHJlcGFyZWRTdGF0ZW1lbnQ7CitpbXBvcnQgamF2YS5zcWwuUmVzdWx0U2V0OworaW1wb3J0IGphdmEuc3FsLlJlc3VsdFNldE1ldGFEYXRhOworaW1wb3J0IGphdmEuc3FsLlNRTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5TdGF0ZW1lbnQ7CitpbXBvcnQgamF2YS5zcWwuVGltZTsKK2ltcG9ydCBqYXZhLnNxbC5UaW1lc3RhbXA7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdEl0ZXJhdG9yOworCisvKioKKyAqIFRlc3RzIGJhc2VkIG9uCisgKiA8YSBocmVmPSJodHRwOi8vamF2YS5zdW4uY29tL3Byb2R1Y3RzL2pkYmMvZG93bmxvYWQuaHRtbCI+SkRCQyAxLjAgQVBJIHNwZWM8L2E+IFRhYmxlIDEuMAorICovCitwdWJsaWMgZmluYWwgY2xhc3MgT2xkUmVzdWx0U2V0R2V0dGVyVGVzdHMgZXh0ZW5kcyBPbGRTUUxUZXN0IHsKKworICAgIFN0cmluZyBxdWVyeUFsbFNlbGVjdCA9ICJzZWxlY3QgKiBmcm9tIHR5cGUiOworCisgICAgUmVzdWx0U2V0IHJlcyA9IG51bGw7CisKKyAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworCisgICAgLy8gSnVkZ2VtZW50IGNvbmNlcm5pbmcgc3VwcG9ydCBpcyBiYXNlZCBvbiB0aGUgcmVzdWx0IG9mIFJlc3VsdFNldC5nZXRPamVjdAorICAgIC8vIGFuZCBUYWJsZSAxIG9mIEpEQkMgMS4wIHNwZWMuCisgICAgc3RhdGljIGJvb2xlYW4gYm9vbGVhblN1cHBvcnRlZCA9IGZhbHNlOworICAgIHN0YXRpYyBib29sZWFuIGJsb2JTdXBwb3J0ZWQgPSBmYWxzZTsKKyAgICBzdGF0aWMgYm9vbGVhbiBiaWdJbnRTdXBwb3J0ZWQgPSBmYWxzZTsKKyAgICBzdGF0aWMgYm9vbGVhbiBzbWFsbEludFN1cHBvcnRlZCA9IGZhbHNlOworICAgIHN0YXRpYyBib29sZWFuIG1lZGl1bUludFN1cHBvcnRlZCA9IGZhbHNlOworICAgIHN0YXRpYyBib29sZWFuIHJlYWxTdXBwb3J0ZWQgPSBmYWxzZTsKKyAgICBzdGF0aWMgYm9vbGVhbiBmbG9hdFN1cHBvcnRlZCA9IGZhbHNlOworICAgIHN0YXRpYyBib29sZWFuIGRhdGVTdXBwb3J0ZWQgPSBmYWxzZTsKKyAgICBzdGF0aWMgYm9vbGVhbiB0aW1lU3VwcG9ydGVkID0gZmFsc2U7CisgICAgc3RhdGljIGJvb2xlYW4gdGltZVN0YW1wU3VwcG9ydGVkID0gZmFsc2U7CisgICAgc3RhdGljIGJvb2xlYW4gZGF0ZVRpbWVTdXBwb3J0ZWQgPSBmYWxzZTsKKyAgICBzdGF0aWMgYm9vbGVhbiB1cmxTdXBwb3J0ZWQ9IGZhbHNlOworICAgIHN0YXRpYyBib29sZWFuIHRpbnlJbnRTdXBwb3J0ZWQgPSBmYWxzZTsKKyAgICBzdGF0aWMgYm9vbGVhbiBkZWNpbWFsU3VwcG9ydGVkID0gZmFsc2U7CisgICAgc3RhdGljIGJvb2xlYW4gbnVtZXJpY1N1cHBvcnRlZCA9IGZhbHNlOworCisgICAgc3RhdGljIExpc3Q8U3RyaW5nPiBjb2xOYW1lcyA9IEFycmF5cy5hc0xpc3QoIkJvb2xWYWwiLCAiSW50VmFsIiwgIkxvbmdWYWwiLAorICAgICAgICAgICAgIkJpbnQiLCAiVGludCIsICJTaW50IiwgIk1pbnQiLCAiSW50ZWdlclZhbCIsICJSZWFsVmFsIiwKKyAgICAgICAgICAgICJEb3VibGVWYWwiLCAiRmxvYXRWYWwiLCAiRGVjVmFsIiwgIk51bVZhbCIsICJjaGFyU3RyIiwKKyAgICAgICAgICAgICJkYXRlVmFsIiwgInRpbWVWYWwiLCAiVFMiLCAiRFQiLCAiVEJsb2IiLCAiQmxvYlZhbCIsICJNQmxvYiIsCisgICAgICAgICAgICAiTEJsb2IiLCAiVFRleHQiLCAiVGV4dFZhbCIsICJNVGV4dCIsICJMVGV4dCIsICJNYXhMb25nVmFsIiwKKyAgICAgICAgICAgICJNaW5Mb25nVmFsIiwgInZhbGlkVVJMIiwgImludmFsaWRVUkwiKTsKKworICAgIHN0YXRpYyBMaXN0PFN0cmluZz4gdmFsdWVzID0gQXJyYXlzLmFzTGlzdCgiMSIsICItMSIsICIyMiIsICIyIiwgIjMzIiwKKyAgICAgICAgICIzIiwiMSIsIjIiLCIzLjkiLCIyMy4yIiwiMzMuMyIsIjQ0IiwKKyAgICAgICAgIjUiLCAidGVzdCBzdHJpbmciLCAiMTc5OS0wNS0yNiIsICIxMjozNTo0NSIsICIyMDA3LTEwLTA5IDE0OjI4OjAyLjAiLAorICAgICAgICAiMTIyMS0wOS0yMiAxMDoxMTo1NSIsIjEiLCIyIiwiMyIsIjQiLCJUZXN0IHRleHQgbWVzc2FnZSB0aW55IiwKKyAgICAgICAgIlRlc3QgdGV4dCIsICJUZXN0IHRleHQgbWVzc2FnZSBtZWRpdW0iLAorICAgICAgICAiVGVzdCB0ZXh0IG1lc3NhZ2UgbG9uZyIpOworCisgICAgc3RhdGljIGJvb2xlYW5bXSBzdXBwb3J0ZWQgPSBuZXcgYm9vbGVhbltdeworICAgICAgICBib29sZWFuU3VwcG9ydGVkLAorICAgICAgICB0cnVlLAorICAgICAgICB0cnVlLAorICAgICAgICBiaWdJbnRTdXBwb3J0ZWQsCisgICAgICAgIHRpbnlJbnRTdXBwb3J0ZWQsCisgICAgICAgIHNtYWxsSW50U3VwcG9ydGVkLAorICAgICAgICBtZWRpdW1JbnRTdXBwb3J0ZWQsCisgICAgICAgIHRydWUsCisgICAgICAgIHJlYWxTdXBwb3J0ZWQsCisgICAgICAgIHRydWUsCisgICAgICAgIGZsb2F0U3VwcG9ydGVkLAorICAgICAgICBkZWNpbWFsU3VwcG9ydGVkLAorICAgICAgICBudW1lcmljU3VwcG9ydGVkLAorICAgICAgICB0cnVlLAorICAgICAgICBkYXRlU3VwcG9ydGVkLAorICAgICAgICB0aW1lU3VwcG9ydGVkLAorICAgICAgICB0aW1lU3RhbXBTdXBwb3J0ZWQsCisgICAgICAgIGRhdGVUaW1lU3VwcG9ydGVkLAorICAgICAgICBibG9iU3VwcG9ydGVkLAorICAgICAgICBibG9iU3VwcG9ydGVkLAorICAgICAgICBibG9iU3VwcG9ydGVkLAorICAgICAgICBibG9iU3VwcG9ydGVkLAorICAgICAgICB0cnVlLAorICAgICAgICB0cnVlLAorICAgICAgICB0cnVlLAorICAgICAgICB0cnVlLAorICAgICAgICBiaWdJbnRTdXBwb3J0ZWQsCisgICAgICAgIGJpZ0ludFN1cHBvcnRlZCwKKyAgICAgICAgdXJsU3VwcG9ydGVkLAorICAgICAgICB1cmxTdXBwb3J0ZWQKKyAgICAgIH07CisKKyAgICAvLyBOb3Qgc3VwcG9ydGVkOiBCSVQsVkFSQklOQVJZLCBMT05HVkFSQklOQVJZLCBCSU5BUlksIFZBUkNIQVIsIExPTkdWQVJDSEFSCisgICAgc3RhdGljIENsYXNzW10gdHlwZU1hcCA9IG5ldyBDbGFzc1tdeworICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZy5jbGFzcywgLy8KKyAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLC8vVHlwZXMuSU5URUdFUiwKKyAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLCAvL1R5cGVzLkxPTkcsIG5vdCBhIEpEQkMgMS4wIHR5cGUKKyAgICAgICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLCAgLy8gVHlwZXMuQklHSU5ULAorICAgICAgICAgICAgamF2YS5sYW5nLkJ5dGUuY2xhc3MsICAgICAgICAgICAgLy8gVHlwZXMuVElOWUlOVCwKKyAgICAgICAgICAgIGphdmEubGFuZy5TaG9ydC5jbGFzcywgLy8gVHlwZXMuU01BTExJTlQsCisgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywgLy9UeXBlcy5NRURJVU1JTlQsICwgbm90IGEgSkRCQyAxLjAgdHlwZQorICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsIC8vIFR5cGVzLkludGVnZXIKKyAgICAgICAgICAgIGphdmEubGFuZy5GbG9hdC5jbGFzcywgICAvLyBUeXBlcy5SRUFMLAorICAgICAgICAgICAgamF2YS5sYW5nLkRvdWJsZS5jbGFzcywgIC8vIFR5cGVzLkZMT0FULAorICAgICAgICAgICAgamF2YS5sYW5nLkRvdWJsZS5jbGFzcywgLy8gVHlwZXMuRE9VQkxFLAorICAgICAgICAgICAgamF2YS5tYXRoLkJpZ0RlY2ltYWwuY2xhc3MsIC8vIFR5cGVzLkRFQ0lNQUwsCisgICAgICAgICAgICBqYXZhLm1hdGguQmlnRGVjaW1hbC5jbGFzcywgLy8gVHlwZXMuTlVNRVJJQywKKyAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcuY2xhc3MsICAgICAvLyBUeXBlcy5DSEFSCisgICAgICAgICAgICBqYXZhLnNxbC5EYXRlLmNsYXNzLCAgICAgICAgLy8gVHlwZXMuREFURSwKKyAgICAgICAgICAgIGphdmEuc3FsLlRpbWUuY2xhc3MsICAgICAgICAvLyBUeXBlcy5USU1FLAorICAgICAgICAgICAgamF2YS5zcWwuVGltZXN0YW1wLmNsYXNzLCAgLy8gVHlwZXMuVElNRVNUQU1QLAorICAgICAgICAgICAgamF2YS5zcWwuRGF0ZS5jbGFzcywgICAgICAgLy8gdHlwZXMgZGF0ZXRpbWUsIG5vdCBhIEpEQkMgMS4wIHR5cGUKKyAgICAgICAgICAgIGphdmEuc3FsLkJsb2IuY2xhc3MsICAgICAgIC8vIFR5cGVzLkJMT0IsIG5vdCBhIEpEQkMgMS4wIHR5cGUKKyAgICAgICAgICAgIGphdmEuc3FsLkJsb2IuY2xhc3MsICAgICAgIC8vIFR5cGVzLkJMT0IsIG5vdCBhIEpEQkMgMS4wIHR5cGUKKyAgICAgICAgICAgIGphdmEuc3FsLkJsb2IuY2xhc3MsICAgICAgIC8vIFR5cGVzLkJMT0IsIG5vdCBhIEpEQkMgMS4wIHR5cGUKKyAgICAgICAgICAgIGphdmEuc3FsLkJsb2IuY2xhc3MsICAgICAgIC8vIFR5cGVzLkJMT0IsIG5vdCBhIEpEQkMgMS4wIHR5cGUKKyAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcuY2xhc3MsICAgIC8vIG5vdCBhIEpEQkMgMS4wIHR5cGUKKyAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcuY2xhc3MsICAgIC8vIG5vdCBhIEpEQkMgMS4wIHR5cGUKKyAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcuY2xhc3MsICAgIC8vIG5vdCBhIEpEQkMgMS4wIHR5cGUKKyAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcuY2xhc3MsICAgIC8vIG5vdCBhIEpEQkMgMS4wIHR5cGUKKyAgICAgICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLCAgICAgIC8vIFR5cGVzLkJJR0lOVCwKKyAgICAgICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLCAgICAgIC8vIFR5cGVzLkJJR0lOVCwKKyAgICAgICAgICAgIGphdmEubmV0LlVSTC5jbGFzcywgICAgICAgIC8vIG5vdCBhIEpEQkMgMS4wIHR5cGUKKyAgICAgICAgICAgIGphdmEubmV0LlVSTC5jbGFzcyAgICAgICAgIC8vIG5vdCBhIEpEQkMgMS4wIHR5cGUKKworCisgICAgfTsKKworICAgIC8vIGZpcnN0IGluc2VydGVkIHJvdyA6IGFjdHVhbCB2YWx1ZXMKKyAgICAvLyBzZWNvbmQgaW5zZXJ0ZWQgcm93OiBudWxsIHZhbHVlcworICAgIFN0cmluZ1tdIHF1ZXJpZXMgPSB7CisgICAgICAgICAgICAiY3JlYXRlIHRhYmxlIHR5cGUgKCIgKworCisgICAgICAgICAgICAiIEJvb2xWYWwgQk9PTEVBTiwiICsgIiBJbnRWYWwgSU5ULCIgKyAiIExvbmdWYWwgTE9ORywiCisgICAgICAgICAgICAgICAgICAgICsgIiBCaW50IEJJR0lOVCwiICsgIiBUaW50IFRJTllJTlQsIiArICIgU2ludCBTTUFMTElOVCwiCisgICAgICAgICAgICAgICAgICAgICsgIiBNaW50IE1FRElVTUlOVCwgIiArCisKKyAgICAgICAgICAgICAgICAgICAgIiBJbnRlZ2VyVmFsIElOVEVHRVIsICIgKyAiIFJlYWxWYWwgUkVBTCwgIgorICAgICAgICAgICAgICAgICAgICArICIgRG91YmxlVmFsIERPVUJMRSwgIiArICIgRmxvYXRWYWwgRkxPQVQsICIKKyAgICAgICAgICAgICAgICAgICAgKyAiIERlY1ZhbCBERUNJTUFMLCAiICsKKworICAgICAgICAgICAgICAgICAgICAiIE51bVZhbCBOVU1FUklDLCAiICsgIiBjaGFyU3RyIENIQVIoMjApLCAiCisgICAgICAgICAgICAgICAgICAgICsgIiBkYXRlVmFsIERBVEUsICIgKyAiIHRpbWVWYWwgVElNRSwgIiArICIgVFMgVElNRVNUQU1QLCAiCisgICAgICAgICAgICAgICAgICAgICsKKworICAgICAgICAgICAgICAgICAgICAiIERUIERBVEVUSU1FLCAiICsgIiBUQmxvYiBUSU5ZQkxPQiwgIiArICIgQmxvYlZhbCBCTE9CLCAiCisgICAgICAgICAgICAgICAgICAgICsgIiBNQmxvYiBNRURJVU1CTE9CLCAiICsgIiBMQmxvYiBMT05HQkxPQiwgIiArCisKKyAgICAgICAgICAgICAgICAgICAgIiBUVGV4dCBUSU5ZVEVYVCwgIiArICIgVGV4dFZhbCBURVhULCAiCisgICAgICAgICAgICAgICAgICAgICsgIiBNVGV4dCBNRURJVU1URVhULCAiICsgIiBMVGV4dCBMT05HVEVYVCwgIiArCisKKyAgICAgICAgICAgICAgICAgICAgIiBNYXhMb25nVmFsIEJJR0lOVCwgTWluTG9uZ1ZhbCBCSUdJTlQsICIrCisKKyAgICAgICAgICAgICAgICAgICAgIiB2YWxpZFVSTCBVUkwsIGludmFsaWRVUkwgVVJMICIrCisKKyAgICAgICAgICAgICAgICAgICAgIik7IgorICAgICAgICAgICAgICwKKworICAgICAgICAgICAgImluc2VydCBpbnRvIHR5cGUgKEJvb2xWYWwsIEludFZhbCwgTG9uZ1ZhbCwgQmludCwgVGludCwgU2ludCwgTWludCwiCisgICAgICAgICAgICAgICAgICAgICsgIkludGVnZXJWYWwsIFJlYWxWYWwsIERvdWJsZVZhbCwgRmxvYXRWYWwsIERlY1ZhbCwiCisgICAgICAgICAgICAgICAgICAgICsgIk51bVZhbCwgY2hhclN0ciwgZGF0ZVZhbCwgdGltZVZhbCwgVFMsIgorICAgICAgICAgICAgICAgICAgICArICJEVCwgVEJsb2IsIEJsb2JWYWwsIE1CbG9iLCBMQmxvYiwiCisgICAgICAgICAgICAgICAgICAgICsgIlRUZXh0LCBUZXh0VmFsLCBNVGV4dCwgTFRleHQsIE1heExvbmdWYWwsIE1pbkxvbmdWYWwsIgorICAgICAgICAgICAgICAgICAgICArICIgdmFsaWRVUkwsIGludmFsaWRVUkwiCisgICAgICAgICAgICAgICAgICAgICsgIikgIgorICAgICAgICAgICAgICAgICAgICArICJ2YWx1ZXMgKDEsIC0xLCAyMiwgMiwgMzMsIgorICAgICAgICAgICAgICAgICAgICArICIzLCAxLCAyLCAzLjksIDIzLjIsIDMzLjMsIDQ0LCIKKyAgICAgICAgICAgICAgICAgICAgKyAiNSwgJ3Rlc3Qgc3RyaW5nJywgJzE3OTktMDUtMjYnLCAnMTI6MzU6NDUnLCAnMjAwNy0xMC0wOSAxNDoyODowMi4wJywiCisgICAgICAgICAgICAgICAgICAgICsgIicxMjIxLTA5LTIyIDEwOjExOjU1JywgMSwgMiwgMywgNCwiCisgICAgICAgICAgICAgICAgICAgICsgIidUZXN0IHRleHQgbWVzc2FnZSB0aW55JywgJ1Rlc3QgdGV4dCcsIgorICAgICAgICAgICAgICAgICAgICArICIgJ1Rlc3QgdGV4dCBtZXNzYWdlIG1lZGl1bScsICdUZXN0IHRleHQgbWVzc2FnZSBsb25nJywgIgorICAgICAgICAgICAgICAgICAgICArIExvbmcuTUFYX1ZBTFVFKyIsICIrTG9uZy5NSU5fVkFMVUUrIiwgIgorICAgICAgICAgICAgICAgICAgICArICInaHR0cDovL3d3dy5hbmRyb2lkLmNvbScsICdoZWxsb1dvcmxkJyAiKworICAgICAgICAgICAgICAgICAgICAiKTsiCisgICAgICAgICAgICAsCisKKyAgICAgICAgICAgImluc2VydCBpbnRvIHR5cGUgKEJvb2xWYWwsIEludFZhbCwgTG9uZ1ZhbCwgQmludCwgVGludCwgU2ludCwgTWludCwiCisgICAgICAgICAgICAgICAgICAgICsgIkludGVnZXJWYWwsIFJlYWxWYWwsIERvdWJsZVZhbCwgRmxvYXRWYWwsIERlY1ZhbCwiCisgICAgICAgICAgICAgICAgICAgICsgIk51bVZhbCwgY2hhclN0ciwgZGF0ZVZhbCwgdGltZVZhbCwgVFMsIgorICAgICAgICAgICAgICAgICAgICArICJEVCwgVEJsb2IsIEJsb2JWYWwsIE1CbG9iLCBMQmxvYiwiCisgICAgICAgICAgICAgICAgICAgICsgIlRUZXh0LCBUZXh0VmFsLCBNVGV4dCwgTFRleHQsIE1heExvbmdWYWwsIE1pbkxvbmdWYWwsIgorICAgICAgICAgICAgICAgICAgICArIiB2YWxpZFVSTCwgaW52YWxpZFVSTCIKKyAgICAgICAgICAgICAgICAgICAgKyAiKSAiCisgICAgICAgICAgICAgICAgICAgICsgInZhbHVlcyAobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwiCisgICAgICAgICAgICAgICAgICAgICsgIm51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwsIgorICAgICAgICAgICAgICAgICAgICArICJudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCIKKyAgICAgICAgICAgICAgICAgICAgKyAibnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwiCisgICAgICAgICAgICAgICAgICAgICsgIm51bGwsIG51bGwsIG51bGwsIG51bGwsbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7IgorICAgIH07CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBjb25uLnNldEF1dG9Db21taXQoZmFsc2UpOworICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcXVlcmllcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc3QuZXhlY3V0ZShxdWVyaWVzW2ldKTsKKyAgICAgICAgfQorICAgICAgICByZXMgPSBzdC5leGVjdXRlUXVlcnkocXVlcnlBbGxTZWxlY3QpOworICAgICAgICBhc3NlcnRUcnVlKHJlcy5uZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJkcm9wIHRhYmxlIGlmIGV4aXN0cyB0eXBlIik7CisgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgcmVzLmNsb3NlKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgcmVzLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRCeXRlc0ludCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBpbnQgaSA9IDE7CisgICAgICAgIC8vIG51bGwgdmFsdWUKKyAgICAgICAgaSA9IDE7CisgICAgICAgIHJlcy5uZXh0KCk7CisgICAgICAgIGZvciAoU3RyaW5nIHQgOiB2YWx1ZXMpIHsKKyAgICAgICAgICAgIGFzc2VydE51bGwocmVzLmdldEJ5dGVzKGkpKTsKKyAgICAgICAgICAgIGkrKzsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXMuY2xvc2UoKTsKKyAgICAgICAgICAgIHJlcy5nZXRCeXRlcygyNCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgZ2V0IEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Qnl0ZXNJbnRWYXJiaW5hcnkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgU3RhdGVtZW50IHN0UXVlcnkgPSBudWxsOworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBzdFByZXAgPSBudWxsOworICAgICAgICBSZXN1bHRTZXQgcmVzID0gbnVsbDsKKworICAgICAgICAvLyBzZXR1cAorICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHRlc3RTdHJpbmcgPSAiSGVsbG9Xb3JsZCI7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlVXBkYXRlKCJjcmVhdGUgdGFibGUgdGVzdEJpbmFyeSAoVkFSQklOQVJZIHZhbHVlKTsiKTsKKyAgICAgICAgICAgIHN0UHJlcCA9IGNvbm4KKyAgICAgICAgICAgICAgICAgICAgLnByZXBhcmVTdGF0ZW1lbnQoImluc2VydCBpbnRvIHRlc3RCaW5hcnkgdmFsdWVzICg/KTsiKTsKKyAgICAgICAgICAgIHN0UHJlcC5zZXRCeXRlcygxLCB0ZXN0U3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICAgICAgc3RQcmVwLmV4ZWN1dGUoKTsKKworICAgICAgICAgICAgc3RRdWVyeSA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICByZXMgPSBzdFF1ZXJ5LmV4ZWN1dGVRdWVyeSgic2VsZWN0ICogZnJvbSB0ZXN0QmluYXJ5Iik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHJlcy5uZXh0KCkpOworICAgICAgICAgICAgYnl0ZVtdIG91dHB1dCA9IHJlcy5nZXRCeXRlcygxKTsKKyAgICAgICAgICAgIFN0cmluZyBoZWxsb1Rlc3QgPSBuZXcgU3RyaW5nKG91dHB1dCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGhlbGxvVGVzdCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModGVzdFN0cmluZywgaGVsbG9UZXN0KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChyZXMgIT0gbnVsbCkgcmVzLmNsb3NlKCk7CisgICAgICAgICAgICBpZiAoc3RQcmVwICE9IG51bGwpIHN0UHJlcC5jbG9zZSgpOworICAgICAgICAgICAgaWYgKHN0ICE9IG51bGwpIHN0LmNsb3NlKCk7CisgICAgICAgICAgICBpZiAoc3RRdWVyeSAhPSBudWxsKSBzdFF1ZXJ5LmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Qnl0ZXNJbnRCaW5hcnkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICBTdGF0ZW1lbnQgc3RRdWVyeSA9IG51bGw7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHN0UHJlcCA9IG51bGw7CisgICAgICAgIFJlc3VsdFNldCByZXMgPSBudWxsOworCisKKyAgICAgICAgLy8gc2V0dXAKKworICAgICAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJIZWxsb1dvcmxkIjsKKyAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICBzdC5leGVjdXRlVXBkYXRlKCJjcmVhdGUgdGFibGUgdGVzdEJpbmFyeSAoQklOQVJZIHZhbHVlKTsiKTsKKyAgICAgICAgc3RQcmVwID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KCJpbnNlcnQgaW50byB0ZXN0QmluYXJ5IHZhbHVlcyAoPyk7Iik7CisgICAgICAgIHN0UHJlcC5zZXRCeXRlcygxLCB0ZXN0U3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICBzdFByZXAuZXhlY3V0ZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RRdWVyeSA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICByZXMgPSBzdFF1ZXJ5LmV4ZWN1dGVRdWVyeSgic2VsZWN0ICogZnJvbSB0ZXN0QmluYXJ5Iik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHJlcy5uZXh0KCkpOworICAgICAgICAgICAgYnl0ZVtdIG91dHB1dCA9IHJlcy5nZXRCeXRlcygxKTsKKyAgICAgICAgICAgIFN0cmluZyBoZWxsb1Rlc3QgPSBuZXcgU3RyaW5nKG91dHB1dCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGhlbGxvVGVzdCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModGVzdFN0cmluZywgaGVsbG9UZXN0KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChyZXMgIT0gbnVsbCkgcmVzLmNsb3NlKCk7CisgICAgICAgICAgICBpZiAoc3RQcmVwICE9IG51bGwpIHN0UHJlcC5jbG9zZSgpOworICAgICAgICAgICAgaWYgKHN0ICE9IG51bGwpIHN0LmNsb3NlKCk7CisgICAgICAgICAgICBpZiAoc3RRdWVyeSAhPSBudWxsKSBzdFF1ZXJ5LmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Qnl0ZXNTdHJpbmcoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGkgPSAxOworCisgICAgICAgIC8vIG51bGwgdmFsdWUKKyAgICAgICAgcmVzLm5leHQoKTsKKyAgICAgICAgZm9yIChTdHJpbmcgdCA6IGNvbE5hbWVzKSB7CisgICAgICAgICAgICBhc3NlcnROdWxsKHJlcy5nZXRCeXRlcyh0KSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzLmNsb3NlKCk7CisgICAgICAgICAgICByZXMuZ2V0Qnl0ZXMoY29sTmFtZXMuZ2V0KDI0KSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgZ2V0IEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgLy8gbGFzdCBhc3NlcnRpb24gZmFpbHM6IGludmFsaWQgY29udmVyc2lvbi4gVGVzdCBwYXNzZXMgb24gUkkKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Qnl0ZXNTdHJpbmdWYXJiaW5hcnkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgU3RhdGVtZW50IHN0UXVlcnkgPSBudWxsOworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBzdFByZXAgPSBudWxsOworICAgICAgICBSZXN1bHRTZXQgcmVzID0gbnVsbDsKKworICAgICAgICAvLyBzZXR1cAorICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHRlc3RTdHJpbmcgPSAiSGVsbG9Xb3JsZCI7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlVXBkYXRlKCJjcmVhdGUgdGFibGUgdGVzdEJpbmFyeSAoVkFSQklOQVJZIHZhbHVlKTsiKTsKKyAgICAgICAgICAgIHN0UHJlcCA9IGNvbm4KKyAgICAgICAgICAgICAgICAgICAgLnByZXBhcmVTdGF0ZW1lbnQoImluc2VydCBpbnRvIHRlc3RCaW5hcnkgdmFsdWVzICg/KTsiKTsKKyAgICAgICAgICAgIHN0UHJlcC5zZXRCeXRlcygxLCB0ZXN0U3RyaW5nLmdldEJ5dGVzKCkpOworICAgICAgICAgICAgc3RQcmVwLmV4ZWN1dGUoKTsKKworICAgICAgICAgICAgc3RRdWVyeSA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICByZXMgPSBzdFF1ZXJ5LmV4ZWN1dGVRdWVyeSgic2VsZWN0IHZhbHVlIGZyb20gdGVzdEJpbmFyeSIpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShyZXMubmV4dCgpKTsKKyAgICAgICAgICAgIGJ5dGVbXSBvdXRwdXQgPSByZXMuZ2V0Qnl0ZXMoInZhbHVlIik7CisgICAgICAgICAgICBTdHJpbmcgaGVsbG9UZXN0ID0gbmV3IFN0cmluZyhvdXRwdXQpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChoZWxsb1Rlc3QpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHRlc3RTdHJpbmcsIGhlbGxvVGVzdCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAocmVzICE9IG51bGwpIHJlcy5jbG9zZSgpOworICAgICAgICAgICAgaWYgKHN0UHJlcCAhPSBudWxsKSBzdFByZXAuY2xvc2UoKTsKKyAgICAgICAgICAgIGlmIChzdCAhPSBudWxsKSBzdC5jbG9zZSgpOworICAgICAgICAgICAgaWYgKHN0UXVlcnkgIT0gbnVsbCkgc3RRdWVyeS5jbG9zZSgpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAgLy8gbGFzdCBhc3NlcnRpb24gZmFpbHM6IGludmFsaWQgY29udmVyc2lvbi4gVGVzdCBwYXNzZXMgb24gUkkKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Qnl0ZXNTdHJpbmdCaW5hcnkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgU3RhdGVtZW50IHN0UXVlcnkgPSBudWxsOworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBzdFByZXAgPSBudWxsOworICAgICAgICBSZXN1bHRTZXQgcmVzID0gbnVsbDsKKworICAgICAgICAvLyBzZXR1cAorCisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gIkhlbGxvV29ybGQiOworICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgIHN0LmV4ZWN1dGVVcGRhdGUoImNyZWF0ZSB0YWJsZSB0ZXN0QmluYXJ5IChCSU5BUlkgdmFsdWUpOyIpOworICAgICAgICBzdFByZXAgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQoImluc2VydCBpbnRvIHRlc3RCaW5hcnkgdmFsdWVzICg/KTsiKTsKKyAgICAgICAgc3RQcmVwLnNldEJ5dGVzKDEsIHRlc3RTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIHN0UHJlcC5leGVjdXRlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdFF1ZXJ5ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHJlcyA9IHN0UXVlcnkuZXhlY3V0ZVF1ZXJ5KCJzZWxlY3QgdmFsdWUgZnJvbSB0ZXN0QmluYXJ5Iik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHJlcy5uZXh0KCkpOworICAgICAgICAgICAgYnl0ZVtdIG91dHB1dCA9IHJlcy5nZXRCeXRlcygidmFsdWUiKTsKKyAgICAgICAgICAgIFN0cmluZyBoZWxsb1Rlc3QgPSBuZXcgU3RyaW5nKG91dHB1dCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGhlbGxvVGVzdCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModGVzdFN0cmluZywgaGVsbG9UZXN0KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChyZXMgIT0gbnVsbCkgcmVzLmNsb3NlKCk7CisgICAgICAgICAgICBpZiAoc3RQcmVwICE9IG51bGwpIHN0UHJlcC5jbG9zZSgpOworICAgICAgICAgICAgaWYgKHN0ICE9IG51bGwpIHN0LmNsb3NlKCk7CisgICAgICAgICAgICBpZiAoc3RRdWVyeSAhPSBudWxsKSBzdFF1ZXJ5LmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q29uY3VycmVuY3koKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFJlc3VsdFNldC5DT05DVVJfVVBEQVRBQkxFLCByZXMuZ2V0Q29uY3VycmVuY3koKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldERhdGVJbnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgdGVzdENhbCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxNzk5LCBDYWxlbmRhci5NQVksIDI2LCAwLCAwKTsKKyAgICAgICAgRGF0ZSBpbnB1dCA9IG5ldyBEYXRlKHRlc3RDYWwuZ2V0VGltZUluTWlsbGlzKCkpOworICAgICAgICBEYXRlIGQgPSByZXMuZ2V0RGF0ZSgxNSk7CisgICAgICAgIGFzc2VydEVxdWFscyhpbnB1dC50b1N0cmluZygpLCIxNzk5LTA1LTI2Iik7CisgICAgICAgIGFzc2VydEVxdWFscyhpbnB1dCxkKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZCA9IHJlcy5nZXREYXRlKDUwMCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgZ2V0IGV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisKKyAgICAgICAgLy8gbnVsbCB2YWx1ZQorICAgICAgICBhc3NlcnRUcnVlKHJlcy5uZXh0KCkpOworICAgICAgICBkID0gcmVzLmdldERhdGUoMTUpOworICAgICAgICBhc3NlcnROdWxsKGQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXREYXRlSW50Q2FsZW5kYXIoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgdGVzdENhbCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxNzk5LCBDYWxlbmRhci5NQVksIDI2LCAwLCAwKTsKKyAgICAgICAgRGF0ZSBpbnB1dCA9IG5ldyBEYXRlKHRlc3RDYWwuZ2V0VGltZUluTWlsbGlzKCkpOworICAgICAgICBEYXRlIGQgPSByZXMuZ2V0RGF0ZSgxNSwgdGVzdENhbCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGlucHV0LnRvU3RyaW5nKCksIjE3OTktMDUtMjYiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGlucHV0LGQpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkID0gcmVzLmdldERhdGUoNTAwLCB0ZXN0Q2FsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCBnZXQgZXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKworCisgICAgICAgIC8vIG51bGwgdmFsdWUKKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXMubmV4dCgpKTsKKyAgICAgICAgZCA9IHJlcy5nZXREYXRlKDE1LHRlc3RDYWwpOworICAgICAgICBhc3NlcnROdWxsKGQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXREYXRlU3RyaW5nKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIEdyZWdvcmlhbkNhbGVuZGFyIHRlc3RDYWwgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTc5OSwgQ2FsZW5kYXIuTUFZLCAyNiwgMCwgMCk7CisgICAgICAgIERhdGUgaW5wdXQgPSBuZXcgRGF0ZSh0ZXN0Q2FsLmdldFRpbWVJbk1pbGxpcygpKTsKKyAgICAgICAgRGF0ZSBkID0gcmVzLmdldERhdGUoImRhdGVWYWwiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGlucHV0LnRvU3RyaW5nKCksIjE3OTktMDUtMjYiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGlucHV0LGQpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkID0gcmVzLmdldERhdGUoImJsYSIpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIGdldCBleGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorCisgICAgICAgIC8vIG51bGwgdmFsdWUKKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXMubmV4dCgpKTsKKyAgICAgICAgZCA9IHJlcy5nZXREYXRlKCJkYXRlVmFsIik7CisgICAgICAgIGFzc2VydE51bGwoZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldERhdGVTdHJpbmdDYWxlbmRhcigpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBHcmVnb3JpYW5DYWxlbmRhciB0ZXN0Q2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE3OTksIENhbGVuZGFyLk1BWSwgMjYsIDAsIDApOworICAgICAgICBEYXRlIGlucHV0ID0gbmV3IERhdGUodGVzdENhbC5nZXRUaW1lSW5NaWxsaXMoKSk7CisgICAgICAgIERhdGUgZCA9IHJlcy5nZXREYXRlKCJkYXRlVmFsIiwgdGVzdENhbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhpbnB1dC50b1N0cmluZygpLCIxNzk5LTA1LTI2Iik7CisgICAgICAgIGFzc2VydEVxdWFscyhpbnB1dCxkKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzLmdldERhdGUoImJsYSIsIHRlc3RDYWwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIGdldCBleGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorCisgICAgICAgIC8vIG51bGwgdmFsdWUKKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXMubmV4dCgpKTsKKyAgICAgICAgZCA9IHJlcy5nZXREYXRlKCJkYXRlVmFsIix0ZXN0Q2FsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RG91YmxlSW50KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGRvdWJsZSBvdXRwdXQgPSAwLjA7CisgICAgICAgIGRvdWJsZVtdIGlucHV0ID0gezIuMCwgMy45ICwgMjMuMn07CisKKyAgICAgICAgb3V0cHV0ID0gcmVzLmdldERvdWJsZSg4KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGlucHV0WzBdLG91dHB1dCk7CisKKyAgICAgICAgb3V0cHV0ID0gcmVzLmdldERvdWJsZSg5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGlucHV0WzFdLG91dHB1dCk7CisKKyAgICAgICAgb3V0cHV0ID0gcmVzLmdldERvdWJsZSgxMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhpbnB1dFsyXSxvdXRwdXQpOworCisgICAgICAgIHRyeSAgeworICAgICAgICAgICAgcmVzLmdldERvdWJsZSg1MDApOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisKKyAgICAgICAgLy8gbnVsbCB2YWx1ZQorICAgICAgICByZXMubmV4dCgpOworICAgICAgICBvdXRwdXQgPSByZXMuZ2V0RG91YmxlKDgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMC4wLG91dHB1dCk7CisKKyAgICAgICAgb3V0cHV0ID0gcmVzLmdldERvdWJsZSg5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAuMCxvdXRwdXQpOworCisgICAgICAgIG91dHB1dCA9IHJlcy5nZXREb3VibGUoMTApOworICAgICAgICBhc3NlcnRFcXVhbHMoMC4wLG91dHB1dCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldERvdWJsZVN0cmluZygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBkb3VibGUgaW5wdXQgPSAyMy4yOworICAgICAgICBkb3VibGUgb3V0cHV0ID0gMC4wOworCisgICAgICAgIG91dHB1dCA9IHJlcy5nZXREb3VibGUoIkRvdWJsZVZhbCIpOworICAgICAgICBhc3NlcnRFcXVhbHMgKGlucHV0LG91dHB1dCk7CisKKyAgICAgICAgdHJ5eworICAgICAgICAgICAgcmVzLmdldERvdWJsZSgiYmxhIik7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICAvLyBudWxsIHZhbHVlCisgICAgICAgIGFzc2VydFRydWUocmVzLm5leHQoKSk7CisgICAgICAgIG91dHB1dCA9IHJlcy5nZXREb3VibGUoIkRvdWJsZVZhbCIpOworICAgICAgICBhc3NlcnRFcXVhbHMgKDAuMCAsIG91dHB1dCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEZsb2F0SW50KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGZsb2F0IGRlZmF1bHRGID0gMC4wZjsKKyAgICAgICAgZmxvYXRbXSBpbnB1dCA9IHszLjlmLCAyMy4yZiwgMzMuM2Z9OworCisgICAgICAgIGZsb2F0IG91dHB1dCA9IHJlcy5nZXRGbG9hdCg5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGlucHV0WzBdLCBvdXRwdXQpOworCisgICAgICAgIG91dHB1dCA9IHJlcy5nZXRGbG9hdCgxMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhpbnB1dFsxXSwgb3V0cHV0KTsKKworICAgICAgICBvdXRwdXQgPSByZXMuZ2V0RmxvYXQoMTEpOworICAgICAgICBhc3NlcnRFcXVhbHMoaW5wdXRbMl0sIG91dHB1dCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcy5nZXRGbG9hdCg1MDApOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKworICAgICAgICByZXMubmV4dCgpOworICAgICAgICBvdXRwdXQgPSByZXMuZ2V0RmxvYXQoOCk7CisgICAgICAgIGFzc2VydEVxdWFscyhkZWZhdWx0Riwgb3V0cHV0KTsKKworICAgICAgICBvdXRwdXQgPSByZXMuZ2V0RmxvYXQoOSk7CisgICAgICAgIGFzc2VydEVxdWFscyhkZWZhdWx0Riwgb3V0cHV0KTsKKworICAgICAgICBvdXRwdXQgPSByZXMuZ2V0RmxvYXQoMTApOworICAgICAgICBhc3NlcnRFcXVhbHMoZGVmYXVsdEYsIG91dHB1dCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEZsb2F0U3RyaW5nKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGZsb2F0IGRlZmF1bHRGID0gMC4wZjsKKyAgICAgICAgU3RyaW5nW10gaW5wdXQgPSB7IlJlYWxWYWwiLCAiRG91YmxlVmFsIiwgIkZsb2F0VmFsIn07CisgICAgICAgIGZsb2F0W10gaW5wdXRGID0gezMuOWYsIDIzLjJmLCAzMy4zZn07CisKKyAgICAgICAgZmxvYXQgb3V0cHV0ID0gcmVzLmdldEZsb2F0KGlucHV0WzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGlucHV0RlswXSwgb3V0cHV0KTsKKworICAgICAgICBvdXRwdXQgPSByZXMuZ2V0RmxvYXQoaW5wdXRbMV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoaW5wdXRGWzFdLCBvdXRwdXQpOworCisgICAgICAgIG91dHB1dCA9IHJlcy5nZXRGbG9hdChpbnB1dFsyXSk7CisgICAgICAgIGFzc2VydEVxdWFscyhpbnB1dEZbMl0sIG91dHB1dCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcy5nZXRGbG9hdCg1MDApOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKworICAgICAgICByZXMubmV4dCgpOworICAgICAgICBvdXRwdXQgPSByZXMuZ2V0RmxvYXQoOCk7CisgICAgICAgIGFzc2VydEVxdWFscyhkZWZhdWx0Riwgb3V0cHV0KTsKKworICAgICAgICBvdXRwdXQgPSByZXMuZ2V0RmxvYXQoOSk7CisgICAgICAgIGFzc2VydEVxdWFscyhkZWZhdWx0Riwgb3V0cHV0KTsKKworICAgICAgICBvdXRwdXQgPSByZXMuZ2V0RmxvYXQoMTApOworICAgICAgICBhc3NlcnRFcXVhbHMoZGVmYXVsdEYsIG91dHB1dCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEludEludCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAvLyByZWFsIGlucHV0IHZhbCAtMSwgMjIsIDIsIDMzLDMsIDEsIDIKKyAgICAgICAgTGlzdDxJbnRlZ2VyPiBpbnB1dCA9IEFycmF5cy5hc0xpc3QoMSwgLTEsIDIyLCAyLCAzMywzLCAxLCAyKTsKKyAgICAgICAgTGlzdEl0ZXJhdG9yPEludGVnZXI+IGl0ID0gaW5wdXQubGlzdEl0ZXJhdG9yKCk7CisgICAgICAgIERvdWJsZSB0ZXN0MiA9IG5ldyBEb3VibGUoMjMuMik7CisgICAgICAgIGZvciAoaW50IGkgPSAxO2k8OTtpKysgKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaXQubmV4dCgpLmludFZhbHVlKCkscmVzLmdldEludChpKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzLmdldEludCg1MDApOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKworICAgICAgICByZXMubmV4dCgpOworICAgICAgICBmb3IgKGludCBpID0gMjtpPDExO2krKyApIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLHJlcy5nZXRJbnQoaSkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEludFN0cmluZygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBMaXN0PFN0cmluZz4gaW5wdXRTID0gQXJyYXlzLmFzTGlzdCgiQm9vbFZhbCIsICJJbnRWYWwiLCAiTG9uZ1ZhbCIsCisgICAgICAgICAgICAgICAgIkJpbnQiLCAiVGludCIsICJTaW50IiwgIk1pbnQiLCAiSW50ZWdlclZhbCIpOworICAgICAgICBMaXN0SXRlcmF0b3I8U3RyaW5nPiBpdFMgPSBpbnB1dFMubGlzdEl0ZXJhdG9yKCk7CisgICAgICAgIExpc3Q8SW50ZWdlcj4gaW5wdXQgPSBBcnJheXMuYXNMaXN0KDEsIC0xLCAyMiwgMiwgMzMsIDMsIDEsIDIpOworICAgICAgICBMaXN0SXRlcmF0b3I8SW50ZWdlcj4gaXQgPSBpbnB1dC5saXN0SXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGl0Lm5leHQoKS5pbnRWYWx1ZSgpLCByZXMuZ2V0SW50KGl0Uy5uZXh0KCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXMuZ2V0SW50KCJibGEiKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisKKyAgICAgICAgcmVzLm5leHQoKTsKKyAgICAgICAgZm9yIChTdHJpbmcgcyA6IGlucHV0UykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHJlcy5nZXRJbnQocykpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldExvbmdJbnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgbG9uZyBtYXhWYWwgPSBMb25nLk1BWF9WQUxVRTsKKyAgICAgICAgbG9uZyBtaW5WYWwgPSBMb25nLk1JTl9WQUxVRTsKKworICAgICAgICBhc3NlcnRFcXVhbHMobWF4VmFsLCByZXMuZ2V0TG9uZygyNykpOworICAgICAgICBhc3NlcnRFcXVhbHMobWluVmFsLCByZXMuZ2V0TG9uZygyOCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXMuZ2V0SW50KDUwMCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorCisgICAgICAgIHJlcy5uZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCByZXMuZ2V0TG9uZygyNykpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgcmVzLmdldExvbmcoMjgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TG9uZ1N0cmluZygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBsb25nIG1heFZhbCA9IExvbmcuTUFYX1ZBTFVFOworICAgICAgICBsb25nIG1pblZhbCA9IExvbmcuTUlOX1ZBTFVFOworICAgICAgICBhc3NlcnRFcXVhbHMobWF4VmFsLCByZXMuZ2V0TG9uZygiTWF4TG9uZ1ZhbCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1pblZhbCwgcmVzLmdldExvbmcoIk1pbkxvbmdWYWwiKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcy5nZXRJbnQoImJsYSIpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKworICAgICAgICByZXMubmV4dCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCxyZXMuZ2V0TG9uZygiTWF4TG9uZ1ZhbCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAscmVzLmdldExvbmcoIk1pbkxvbmdWYWwiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBtZXRob2QgZm9yIHtAbGluayBqYXZhLnNxbC5SZXN1bHRTZXQjZ2V0TWV0YURhdGEoKX0uCisgICAgICogdHlwZSBtYXBwaW5ncyBhY2NvcmRpbmcgdG8KKyAgICAgKiBodHRwOi8vamF2YS5zdW4uY29tL2oyc2UvMS4zL2RvY3MvZ3VpZGUvamRiYy9zcGVjL2pkYmMtc3BlYy5mcmFtZTguaHRtbAorICAgICAqIE5vdCBzdXBwb3J0ZWQgZGF0YXR5cGVzIGFyZSBub3QgY2hlY2tlZC4KKyAgICAgKgorICAgICAqIFdyb25nIHZhbHVlIHJldHVybmVkIGZvciBMb25nOiBqYXZhLmxhbmcuU3RyaW5nIChWQVJDSEFSKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRNZXRhRGF0YSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAvKgorICAgICAgICAgKiBMaXN0PFN0cmluZz4gdHlwZXMgPSBBcnJheXMuYXNMaXN0KCJCT09MRUFOIiwgIklOVCIsICJMT05HIiwKKyAgICAgICAgICogIkJJR0lOVCIsICJUSU5ZSU5UIiwgIlNNQUxMSU5UIiwgIk1FRElVTUlOVCIsICJJTlRFR0VSIiwgIlJFQUwiLAorICAgICAgICAgKiAiRE9VQkxFIiwgIkZMT0FUIiwgIkRFQ0lNQUwiLCAiTlVNRVJJQyIsICJDSEFSKDIwKSIsICJEQVRFIiwgIlRJTUUiLAorICAgICAgICAgKiAiVElNRVNUQU1QIiwgIkRBVEVUSU1FIiwgIlRJTllCTE9CIiwgIkJMT0IiLCAiTUVESVVNQkxPQiIsCisgICAgICAgICAqICJMT05HQkxPQiIsICJUSU5ZVEVYVCIsICJURVhUIiwgIk1FRElVTVRFWFQiLCAiTE9OR1RFWFQiLCAiQklHSU5UIiwKKyAgICAgICAgICogIkJJR0lOVCIsIlVSTCIsIlVSTCIpOworICAgICAgICAgKi8KKyAgICAgICAgTGlzdDxTdHJpbmc+IHR5cGVzID0gQXJyYXlzLmFzTGlzdCgiVkFSQ0hBUiIsICJJTlRFR0VSIiwgIklOVEVHRVIiLAorICAgICAgICAgICAgICAgICJCSUdJTlQiLCAiU01BTExJTlQiLCAiU0hPUlQiLCAiSU5URUdFUiIsICJJTlRFR0VSIiwgIkZMT0FUIiwKKyAgICAgICAgICAgICAgICAiRE9VQkxFIiwgIkRPVUJMRSIsICJERUNJTUFMIiwgIk5VTUVSSUMiLCAiVkFSQ0hBUiIsICJEQVRFIiwKKyAgICAgICAgICAgICAgICAiVElNRSIsICJUSU1FU1RBTVAiLCAiREFURVRJTUUiLCAiQkxPQiIsICJCTE9CIiwgIkJMT0IiLAorICAgICAgICAgICAgICAgICJCTE9CIiwgIlZBUkNIQVIiLCAiVkFSQ0hBUiIsICJWQVJDSEFSIiwgIlZBUkNIQVIiLCAiQklHSU5UIiwKKyAgICAgICAgICAgICAgICAiQklHSU5UIiwgIlVSTCIsICJVUkwiKTsKKworCisKKyAgICAgICAgTGlzdEl0ZXJhdG9yPFN0cmluZz4gaXQgPSB0eXBlcy5saXN0SXRlcmF0b3IoKTsKKyAgICAgICAgTGlzdEl0ZXJhdG9yPFN0cmluZz4gY29sTmFtZUl0ID0gY29sTmFtZXMubGlzdEl0ZXJhdG9yKCk7CisgICAgICAgIFJlc3VsdFNldE1ldGFEYXRhIG1ldGEgPSByZXMuZ2V0TWV0YURhdGEoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChtZXRhKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJFcnJvciBpbiB0ZXN0IHNldHVwLiBDb2x1bW5zIGRvIG5vdCBtYXRjaCIsIHR5cGVzCisgICAgICAgICAgICAgICAgLnNpemUoKSwgbWV0YS5nZXRDb2x1bW5Db3VudCgpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCAzMTsgaSsrKSB7CisgICAgICAgICAgICBTdHJpbmcgY29sTmFtZSA9IGNvbE5hbWVJdC5uZXh0KCk7CisgICAgICAgICAgICBTdHJpbmcgdHlwZSA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIGlmIChzdXBwb3J0ZWRbaSAtIDFdKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgY29sdW1uIG5hbWUgYXQgIiArIGksIGNvbE5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgIC5lcXVhbHNJZ25vcmVDYXNlKG1ldGEuZ2V0Q29sdW1uTmFtZShpKSkpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIldyb25nIHR5cGUgYXQgIiArIGkrIiByZXF1aXJlZCIgK3R5cGUrICIgYnV0IGlzICIrbWV0YS5nZXRDb2x1bW5UeXBlTmFtZShpKSwgdHlwZS5lcXVhbHNJZ25vcmVDYXNlKG1ldGEKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRDb2x1bW5UeXBlTmFtZShpKSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gV3JvbmcgdmFsdWUgcmV0dXJuZWQgZm9yIExvbmc6IGphdmEubGFuZy5TdHJpbmcKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0T2JqZWN0SW50KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IHR5cGVNYXAubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChzdXBwb3J0ZWRbaS0xXSkgeworICAgICAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IHJlcy5nZXRPYmplY3QoaSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidmFsdWUgIiArIHZhbHVlLmdldENsYXNzKCkuZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgICAgICAgICArICIgZG9lcyBub3QgY29ycmVzcG9uZCAiICsgdHlwZU1hcFtpLTFdICsgImF0ICIraSwgdmFsdWUKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRDbGFzcygpLmVxdWFscyh0eXBlTWFwW2ktMV0pKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXMuZ2V0T2JqZWN0KDUwMCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorCisgICAgICAgIHJlcy5uZXh0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IHR5cGVNYXAubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IHJlcy5nZXRPYmplY3QoaSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKHZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFdyb25nIHZhbHVlIHJldHVybmVkIGZvciBMb25nOiBqYXZhLmxhbmcuU3RyaW5nCisgICAgcHVibGljIHZvaWQgdGVzdEdldE9iamVjdFN0cmluZygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBMaXN0SXRlcmF0b3I8U3RyaW5nPiBjb2xOYW1lSXQgPSBjb2xOYW1lcy5saXN0SXRlcmF0b3IoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gdHlwZU1hcC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBjb2xOYW1lSXQubmV4dCgpOworICAgICAgICAgICAgaWYgKHN1cHBvcnRlZFtpLTFdKSB7CisgICAgICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gcmVzLmdldE9iamVjdChuYW1lKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJ2YWx1ZSAiICsgdmFsdWUuZ2V0Q2xhc3MoKS5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiBmb3IgIituYW1lKyIgZG9lcyBub3QgY29ycmVzcG9uZCAiICsgdHlwZU1hcFtpLTFdICsgImF0ICIraSwgdmFsdWUKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRDbGFzcygpLmVxdWFscyh0eXBlTWFwW2ktMV0pKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXMuZ2V0T2JqZWN0KCJibGEiKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisKKworICAgICAgICBjb2xOYW1lSXQgPSBjb2xOYW1lcy5saXN0SXRlcmF0b3IoKTsKKyAgICAgICAgcmVzLm5leHQoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gdHlwZU1hcC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IHJlcy5nZXRPYmplY3QoY29sTmFtZUl0Lm5leHQoKSk7CisgICAgICAgICAgICAgICBhc3NlcnROdWxsKHZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIElmIHRoZXJlIGlzIG5vIGN1cnJlbnQgcm93IDAgbXVzdCBiZSByZXR1cm5lZC4gcmVzLmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRSb3coKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHJlcy5nZXRSb3coKSk7CisgICAgICAgIGFzc2VydFRydWUocmVzLmlzRmlyc3QoKSk7CisgICAgICAgIHJlcy5uZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCByZXMuZ2V0Um93KCkpOworICAgICAgICBhc3NlcnRUcnVlKHJlcy5pc0xhc3QoKSk7CisgICAgICAgIHJlcy5uZXh0KCk7CisgICAgICAgIGFzc2VydFRydWUocmVzLmlzQWZ0ZXJMYXN0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgcmVzLmdldFJvdygpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzLmNsb3NlKCk7CisgICAgICAgICAgICByZXMuZ2V0Um93KCk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFNob3J0SW50KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIHNob3J0IHNob3J0eSA9IHJlcy5nZXRTaG9ydCg2KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsc2hvcnR5KTsKKworICAgICAgICByZXMubmV4dCgpOworICAgICAgICBzaG9ydHkgPSByZXMuZ2V0U2hvcnQoNik7CisgICAgICAgIGFzc2VydEVxdWFscygwLHNob3J0eSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcy5nZXRTaG9ydCg1MDApOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2hvcnRTdHJpbmcoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgc2hvcnQgc2hvcnR5ID0gcmVzLmdldFNob3J0KCJTaW50Iik7CisgICAgICAgIGFzc2VydEVxdWFscygzLHNob3J0eSk7CisKKyAgICAgICAgcmVzLm5leHQoKTsKKyAgICAgICAgc2hvcnR5ID0gcmVzLmdldFNob3J0KCJTaW50Iik7CisgICAgICAgIGFzc2VydEVxdWFscygwLHNob3J0eSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcy5nZXRTaG9ydCgiYmxhIik7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFjY29yZGluZyB0byBzcGVjIGluZm8uZ2V0U3RhdGVtZW50IHNob3VsZCByZXR1cm4gbnVsbCBidXQgYW4gZXhjZXB0aW9uCisgICAgICogaXMgdGhyb3duOiBzdGFsZSByZXN1bHQgc2V0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRTdGF0ZW1lbnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgRGF0YWJhc2VNZXRhRGF0YSBtZXRhID0gY29ubi5nZXRNZXRhRGF0YSgpOworICAgICAgICBSZXN1bHRTZXQgaW5mbyA9IG1ldGEuZ2V0VHlwZUluZm8oKTsKKyAgICAgICAgU3RhdGVtZW50IHN0YXRlbWVudDIgPSBpbmZvLmdldFN0YXRlbWVudCgpOworICAgICAgICBhc3NlcnROdWxsKHN0YXRlbWVudDIpOworCisgICAgICAgIHN0YXRlbWVudDIgPSByZXMuZ2V0U3RhdGVtZW50KCk7CisgICAgICAgIGFzc2VydEVxdWFscyhzdCwgc3RhdGVtZW50Mik7CisKKyAgICAgICAvLyBleGNlcHRpb24gdGVzdGluZworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzLmNsb3NlKCk7CisgICAgICAgICAgICByZXMuZ2V0U3RhdGVtZW50KCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRTdHJpbmdJbnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgTGlzdDxTdHJpbmc+IHRleHRzID0gQXJyYXlzLmFzTGlzdCgiVGVzdCB0ZXh0IG1lc3NhZ2UgdGlueSIsCisgICAgICAgICAgICAgICAgIlRlc3QgdGV4dCIsICJUZXN0IHRleHQgbWVzc2FnZSBtZWRpdW0iLAorICAgICAgICAgICAgICAgICJUZXN0IHRleHQgbWVzc2FnZSBsb25nIik7CisgICAgICAgIGludCBpID0gMjM7CisKKyAgICAgICAgLy90ZXh0IGFuZCBleGNlcHRpb24gdGVzdGluZworICAgICAgICBmb3IgKFN0cmluZyB0IDogdGV4dHMpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0LCByZXMuZ2V0U3RyaW5nKGkpKTsKKyAgICAgICAgICAgIGkrKzsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRoZSByZXN0OiBldmVyeXRoaW5nIHNob3VsZCB3b3JrIHdpdGggZ2V0U3RyaW5nCisKKyAgICAgICAgdGV4dHMgPSBBcnJheXMuYXNMaXN0KCIxIiwgIi0xIiwgIjIyIiwgIjIiLCAiMzMiLAorICAgICAgICAgIjMiLCIxIiwiMiIsIjMuOSIsIjIzLjIiLCIzMy4zIiwiNDQiLAorICAgICAgICAiNSIsICJ0ZXN0IHN0cmluZyIsICIxNzk5LTA1LTI2IiwgIjEyOjM1OjQ1IiwgIjIwMDctMTAtMDkgMTQ6Mjg6MDIuMCIsCisgICAgICAgICIxMjIxLTA5LTIyIDEwOjExOjU1IiwiMSIsIjIiLCIzIiwiNCIpOworICAgICAgICBpPSAxOworCisgICAgICAgIGZvciAoU3RyaW5nIHQgOiB0ZXh0cykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHQsIHJlcy5nZXRTdHJpbmcoaSkpOworICAgICAgICAgICAgaSsrOworICAgICAgICB9CisKKyAgICAgICAgLy9udWxsIHRlc3RpbmcKKyAgICAgICAgaSA9IDE7CisgICAgICAgIHJlcy5uZXh0KCk7CisgICAgICAgIGZvciAoU3RyaW5nIHQgOiB2YWx1ZXMpIHsKKyAgICAgICAgICAgIGFzc2VydE51bGwocmVzLmdldFN0cmluZyhpKSk7CisgICAgICAgICAgICBpKys7CisgICAgICAgIH0KKworICAgICAgICAvLyBleGNlcHRpb24gdGVzdGluZworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzLmdldFN0cmluZyg1MDApOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRTdHJpbmdTdHJpbmcoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgTGlzdEl0ZXJhdG9yPFN0cmluZz4gY29sTmFtZUl0ID0gY29sTmFtZXMubGlzdEl0ZXJhdG9yKCk7CisgICAgICAgIGZvciAoU3RyaW5nIHQgOiB2YWx1ZXMpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0LCByZXMuZ2V0U3RyaW5nKGNvbE5hbWVJdC5uZXh0KCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIHJlcy5uZXh0KCk7CisgICAgICAgIGZvciAoU3RyaW5nIG5hbWU6IGNvbE5hbWVzKSB7CisgICAgICAgICAgICBhc3NlcnROdWxsKHJlcy5nZXRTdHJpbmcobmFtZSkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcy5nZXRTdHJpbmcoImJsYSIpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBnZXRUaW1lIHNob3VsZCByZXR1cm4gVGltZSB2YWx1ZSBmb3IgYSBUSU1FU1RBTVAgdHlwZSBidXQgcmV0dXJucyBudWxsCisgICAgcHVibGljIHZvaWQgdGVzdEdldFRpbWVJbnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gdmFsdWVzICIxMjozNTo0NSIsICIyMDA3LTEwLTA5IDE0OjI4OjAyLjAiLCAiMTIyMS0wOS0yMiAxMDoxMTo1NSIKKworICAgICAgICBDYWxlbmRhciBjYWwgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoKTsKKyAgICAgICAgY2FsLmNsZWFyKCk7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVksIDEyKTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5NSU5VVEUsIDM1KTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5TRUNPTkQsIDQ1KTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5NSUxMSVNFQ09ORCwgMCk7CisgICAgICAgIC8vIHNldCB3aXRoIGNhbGVuZGFyIHZhbHVlIChjb3JyZWN0IGluaXQgdGltZTogc2luY2UgZXBvY2gpCisgICAgICAgIGxvbmcgbWlsbGlzID0gY2FsLmdldFRpbWUoKS5nZXRUaW1lKCk7CisgICAgICAgIFRpbWUgdDEgPSBuZXcgamF2YS5zcWwuVGltZShtaWxsaXMpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJ0MSIsIHQxKTsKKworCisgICAgICAgIENhbGVuZGFyIGNhbDIgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoKTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwNyk7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5PQ1RPQkVSKTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuREFURSwgOSk7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLkhPVVJfT0ZfREFZLCAxNCk7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLk1JTlVURSwgMjgpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5TRUNPTkQsIDAyKTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuTUlMTElTRUNPTkQsIDApOworCisgICAgICAgIGxvbmcgbWlsbGlzMiA9IGNhbDIuZ2V0VGltZSgpLmdldFRpbWUoKTsKKyAgICAgICAgVGltZSB0MiA9IG5ldyBqYXZhLnNxbC5UaW1lKG1pbGxpczIpOworCisgICAgICAgIGludCBpID0gMTY7CisKKyAgICAgICAgVGltZSByZXNUaW1lID0gcmVzLmdldFRpbWUoaSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIlBvcyAiICsgaSArICIgbnVsbCIsIHJlc1RpbWUpOworICAgICAgICBhc3NlcnRFcXVhbHModDEudG9TdHJpbmcoKSwgcmVzVGltZS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQxLmdldFRpbWUoKSwgcmVzVGltZS5nZXRUaW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModDEsIHJlc1RpbWUpOworICAgICAgICAvLyBDb21wYXRpYmlsaXR5IFRlc3Q6IFRJTUVTVEFNUCB2YWx1ZQorICAgICAgICBpID0gMTc7CisKKyAgICAgICAgcmVzVGltZSA9IHJlcy5nZXRUaW1lKGkpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJQb3MgIiArIGkgKyAiIG51bGwiLCByZXNUaW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQyLnRvU3RyaW5nKCksIHJlc1RpbWUudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0Mi5nZXRUaW1lKCksIHJlc1RpbWUuZ2V0VGltZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQyLCByZXNUaW1lKTsKKworICAgICAgICBpID0gMTY7CisgICAgICAgIHJlcy5uZXh0KCk7CisgICAgICAgIGFzc2VydE51bGwocmVzLmdldFRpbWUoaSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXMuZ2V0VGltZSg1MDApOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgIC8vIGdldFRpbWUgb24gVElNRVNUQU1QIHZhbHVlIGZhaWxzOiByZXR1cm5zIG51bGwKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VGltZUludENhbGVuZGFyKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIExpc3Q8VGltZT4gdGltZXMgPSBuZXcgTGlua2VkTGlzdDxUaW1lPigpOworICAgICAgICBMaXN0PENhbGVuZGFyPiBjYWxzID0gbmV3IExpbmtlZExpc3Q8Q2FsZW5kYXI+KCk7CisgICAgICAgIC8vIEFycmF5cy5hc0xpc3QoIjEyOjM1OjQ1IiwgIjIwMDctMTAtMDkgMTQ6Mjg6MDIuMCIsCisgICAgICAgIC8vICIxMjIxLTA5LTIyIDEwOjExOjU1Iik7CisKKyAgICAgICAgQ2FsZW5kYXIgY2FsMSA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigpOworICAgICAgICBjYWwxLmNsZWFyKCk7CisgICAgICAgIGNhbDEuc2V0KENhbGVuZGFyLkhPVVJfT0ZfREFZLCAxMik7CisgICAgICAgIGNhbDEuc2V0KENhbGVuZGFyLk1JTlVURSwgMzUpOworICAgICAgICBjYWwxLnNldChDYWxlbmRhci5TRUNPTkQsIDQ1KTsKKyAgICAgICAgY2FsMS5zZXQoQ2FsZW5kYXIuTUlMTElTRUNPTkQsIDApOworCisgICAgICAgIGxvbmcgbWlsbGlzID0gY2FsMS5nZXRUaW1lKCkuZ2V0VGltZSgpOworICAgICAgICBUaW1lIHQxID0gbmV3IGphdmEuc3FsLlRpbWUobWlsbGlzKTsKKworICAgICAgICBDYWxlbmRhciBjYWwyID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKCk7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLllFQVIsIDIwMDcpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuT0NUT0JFUik7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLkRBVEUsIDkpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5IT1VSX09GX0RBWSwgMTQpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5NSU5VVEUsIDI4KTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuU0VDT05ELCAwMik7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLk1JTExJU0VDT05ELCAwKTsKKworICAgICAgICBsb25nIG1pbGxpczIgPSBjYWwyLmdldFRpbWUoKS5nZXRUaW1lKCk7CisgICAgICAgIFRpbWUgdDIgPSBuZXcgamF2YS5zcWwuVGltZShtaWxsaXMyKTsKKworICAgICAgICAvLyBUSU1FIHZhbHVlCisKKyAgICAgICAgaW50IGkgPSAxNjsKKworICAgICAgICBUaW1lIHRpbWVSZXMgPSByZXMuZ2V0VGltZShpLG5ldyBHcmVnb3JpYW5DYWxlbmRhcigpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0aW1lUmVzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQxLnRvU3RyaW5nKCksIHRpbWVSZXMudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0MS5nZXRUaW1lKCksIHRpbWVSZXMuZ2V0VGltZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQxLCB0aW1lUmVzKTsKKworICAgICAgICAvLyBUSU1FU1RBTVAgdmFsdWUKKyAgICAgICAgaSA9IDE3OworCisgICAgICAgICB0aW1lUmVzID0gcmVzLmdldFRpbWUoaSxuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoKSk7CisgICAgICAgICBhc3NlcnROb3ROdWxsKHRpbWVSZXMpOworICAgICAgICAgYXNzZXJ0RXF1YWxzKHQyLnRvU3RyaW5nKCksIHRpbWVSZXMudG9TdHJpbmcoKSk7CisgICAgICAgICBhc3NlcnRFcXVhbHModDIuZ2V0VGltZSgpLCB0aW1lUmVzLmdldFRpbWUoKSk7CisgICAgICAgICBhc3NlcnRFcXVhbHModDIsIHRpbWVSZXMpOworCisgICAgICAgICByZXMubmV4dCgpOworICAgICAgICAgZm9yIChDYWxlbmRhciBjIDogY2FscykgeworICAgICAgICAgICAgIGFzc2VydE51bGwocmVzLmdldFRpbWUoMTYsYykpOworICAgICAgICAgICAgIGkrKzsKKyAgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzLmdldFRpbWUoNTAwLENhbGVuZGFyLmdldEluc3RhbmNlKCkpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBnZXRUaW1lIHNob3VsZCByZXR1cm4gYSBUaW1lIHZhbHVlIGZvciBhIFRJTUVTVEFNUCB0eXBlIGJ1dCByZXR1cm5zIG51bGwKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VGltZVN0cmluZygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBMaXN0PFRpbWU+IHRpbWVzID0gbmV3IExpbmtlZExpc3Q8VGltZT4oKTsKKworICAgICAgICBMaXN0PFN0cmluZz4gc3RyaW5nVGltZXMgPSBBcnJheXMuYXNMaXN0KCJ0aW1lVmFsIiwgIlRTIiwgIkRUIik7CisgICAgICAgIEl0ZXJhdG9yPFN0cmluZz4gaXQgPSBzdHJpbmdUaW1lcy5pdGVyYXRvcigpOworCisgICAgICAgIC8vIEFycmF5cy5hc0xpc3QoIjEyOjM1OjQ1IiwgIjIwMDctMTAtMDkgMTQ6Mjg6MDIuMCIsCisgICAgICAgIC8vICIxMjIxLTA5LTIyIDEwOjExOjU1Iik7CisKKyAgICAgICAgQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKCk7CisgICAgICAgIGNhbC5jbGVhcigpOworICAgICAgICBjYWwuc2V0KENhbGVuZGFyLkhPVVJfT0ZfREFZLCAxMik7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuTUlOVVRFLCAzNSk7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuU0VDT05ELCA0NSk7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuTUlMTElTRUNPTkQsIDApOworCisgICAgICAgIGxvbmcgbWlsbGlzID0gY2FsLmdldFRpbWUoKS5nZXRUaW1lKCk7CisgICAgICAgIFRpbWUgdDEgPSBuZXcgamF2YS5zcWwuVGltZShtaWxsaXMpOworCisgICAgICAgIFN0cmluZyBjb2wgPSBpdC5uZXh0KCk7CisKKyAgICAgICAgVGltZSB0aW1lUmVzID0gcmVzLmdldFRpbWUoY29sKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0aW1lUmVzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQxLnRvU3RyaW5nKCksIHRpbWVSZXMudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0MS5nZXRUaW1lKCksIHRpbWVSZXMuZ2V0VGltZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQxLCB0aW1lUmVzKTsKKworICAgICAgICBDYWxlbmRhciBjYWwyID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKCk7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLllFQVIsIDIwMDcpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuT0NUT0JFUik7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLkRBVEUsIDkpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5IT1VSX09GX0RBWSwgMTQpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5NSU5VVEUsIDI4KTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuU0VDT05ELCAwMik7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLk1JTExJU0VDT05ELCAwKTsKKworICAgICAgICBsb25nIG1pbGxpczIgPSBjYWwuZ2V0VGltZSgpLmdldFRpbWUoKTsKKyAgICAgICAgVGltZSB0MiA9IG5ldyBqYXZhLnNxbC5UaW1lKG1pbGxpczIpOworCisgICAgICAgIGNvbCA9IGl0Lm5leHQoKTsKKworICAgICAgICB0aW1lUmVzID0gcmVzLmdldFRpbWUoY29sKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0aW1lUmVzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQyLnRvU3RyaW5nKCksIHRpbWVSZXMudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0Mi5nZXRUaW1lKCksIHRpbWVSZXMuZ2V0VGltZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQyLCB0aW1lUmVzKTsKKworICAgICAgICByZXMubmV4dCgpOworICAgICAgICBhc3NlcnROdWxsKHJlcy5nZXRUaW1lKGNvbCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXMuZ2V0VGltZSgiYmxhIik7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIGdldFRpbWUgb24gVElNRVNUQU1QIHZhbHVlIGZhaWxzOiByZXR1cm5zIG51bGwKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VGltZVN0cmluZ0NhbGVuZGFyKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIExpc3Q8VGltZT4gdGltZXMgPSBuZXcgTGlua2VkTGlzdDxUaW1lPigpOworCisgICAgICAgIExpc3Q8U3RyaW5nPiBzdHJpbmdUaW1lcyA9IEFycmF5cy5hc0xpc3QoInRpbWVWYWwiLCAiVFMiLCAiRFQiKTsKKyAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBpdCA9IHN0cmluZ1RpbWVzLml0ZXJhdG9yKCk7CisgICAgICAgIExpc3Q8Q2FsZW5kYXI+IGNhbHMgPSBuZXcgTGlua2VkTGlzdDxDYWxlbmRhcj4oKTsKKworICAgICAgICAvLyBBcnJheXMuYXNMaXN0KCIxMjozNTo0NSIsICIyMDA3LTEwLTA5IDE0OjI4OjAyLjAiLAorICAgICAgICAvLyAiMTIyMS0wOS0yMiAxMDoxMTo1NSIpOworCisgICAgICAgIENhbGVuZGFyIGNhbDEgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoKTsKKyAgICAgICAgY2FsMS5jbGVhcigpOworICAgICAgICBjYWwxLnNldChDYWxlbmRhci5IT1VSX09GX0RBWSwgMTIpOworICAgICAgICBjYWwxLnNldChDYWxlbmRhci5NSU5VVEUsIDM1KTsKKyAgICAgICAgY2FsMS5zZXQoQ2FsZW5kYXIuU0VDT05ELCA0NSk7CisgICAgICAgIGNhbDEuc2V0KENhbGVuZGFyLk1JTExJU0VDT05ELCAwKTsKKworICAgICAgICBsb25nIG1pbGxpcyA9IGNhbDEuZ2V0VGltZSgpLmdldFRpbWUoKTsKKyAgICAgICAgVGltZSB0MSA9IG5ldyBqYXZhLnNxbC5UaW1lKG1pbGxpcyk7CisKKyAgICAgICAgQ2FsZW5kYXIgY2FsMiA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5ZRUFSLCAyMDA3KTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuTU9OVEgsIENhbGVuZGFyLk9DVE9CRVIpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5EQVRFLCA5KTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVksIDE0KTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuTUlOVVRFLCAyOCk7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLlNFQ09ORCwgMDIpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5NSUxMSVNFQ09ORCwgMCk7CisKKyAgICAgICAgbG9uZyBtaWxsaXMyID0gY2FsMi5nZXRUaW1lKCkuZ2V0VGltZSgpOworICAgICAgICBUaW1lIHQyID0gbmV3IGphdmEuc3FsLlRpbWUobWlsbGlzMik7CisKKyAgICAgICAgLy8gVElNRSB2YWx1ZQorICAgICAgICBTdHJpbmcgY29sID0gaXQubmV4dCgpOworCisgICAgICAgIFRpbWUgdGltZVJlcyA9IHJlcy5nZXRUaW1lKGNvbCwgbmV3IEdyZWdvcmlhbkNhbGVuZGFyKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRpbWVSZXMpOworICAgICAgICBhc3NlcnRFcXVhbHModDEudG9TdHJpbmcoKSwgdGltZVJlcy50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQxLmdldFRpbWUoKSwgdGltZVJlcy5nZXRUaW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModDEsIHJlcy5nZXRUaW1lKGNvbCkpOworICAgICAgICAvL1RJTUVTVEFNUCB2YWx1ZQorICAgICAgICBjb2wgPSBpdC5uZXh0KCk7CisKKyAgICAgICAgdGltZVJlcyA9IHJlcy5nZXRUaW1lKGNvbCwgbmV3IEdyZWdvcmlhbkNhbGVuZGFyKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRpbWVSZXMpOworICAgICAgICBhc3NlcnRFcXVhbHModDIudG9TdHJpbmcoKSwgdGltZVJlcy50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQyLmdldFRpbWUoKSwgdGltZVJlcy5nZXRUaW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModDIsIHJlcy5nZXRUaW1lKGNvbCkpOworCisgICAgICAgIHJlcy5uZXh0KCk7CisgICAgICAgIGFzc2VydE51bGwocmVzLmdldFRpbWUoc3RyaW5nVGltZXMuZ2V0KDApLCBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXMuZ2V0VGltZSgiYmxhIik7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VGltZXN0YW1wSW50KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIExpc3Q8VGltZXN0YW1wPiB0aW1lcyA9IG5ldyBMaW5rZWRMaXN0PFRpbWVzdGFtcD4oKTsKKworICAgICAgICBMaXN0PFN0cmluZz4gc3RyaW5nVGltZXMgPSBBcnJheXMuYXNMaXN0KCJ0aW1lVmFsIiwgIlRTIiwgIkRUIik7CisgICAgICAgIEl0ZXJhdG9yPFN0cmluZz4gaXQgPSBzdHJpbmdUaW1lcy5pdGVyYXRvcigpOworICAgICAgICBMaXN0PENhbGVuZGFyPiBjYWxzID0gbmV3IExpbmtlZExpc3Q8Q2FsZW5kYXI+KCk7CisKKyAgICAgICAgQ2FsZW5kYXIgY2FsMiA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5ZRUFSLCAyMDA3KTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuTU9OVEgsIENhbGVuZGFyLk9DVE9CRVIpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5EQVRFLCA5KTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVksIDE0KTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuTUlOVVRFLCAyOCk7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLlNFQ09ORCwgMDIpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5NSUxMSVNFQ09ORCwgMCk7CisKKyAgICAgICAgbG9uZyBtaWxsaXMgPSBjYWwyLmdldFRpbWUoKS5nZXRUaW1lKCk7CisgICAgICAgIFRpbWVzdGFtcCB0MiA9IG5ldyBUaW1lc3RhbXAobWlsbGlzKTsKKyAgICAgICAgdGltZXMuYWRkKHQyKTsKKworICAgICAgICBDYWxlbmRhciBjYWwzID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKCk7CisgICAgICAgIGNhbDMuc2V0KENhbGVuZGFyLllFQVIsIDEyMjEpOworICAgICAgICBjYWwzLnNldChDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuU0VQVEVNQkVSKTsKKyAgICAgICAgY2FsMy5zZXQoQ2FsZW5kYXIuREFURSwgMjIpOworICAgICAgICBjYWwzLnNldChDYWxlbmRhci5IT1VSX09GX0RBWSwgMTApOworICAgICAgICBjYWwzLnNldChDYWxlbmRhci5NSU5VVEUsIDExKTsKKyAgICAgICAgY2FsMy5zZXQoQ2FsZW5kYXIuU0VDT05ELCA1NSk7CisgICAgICAgIGNhbDMuc2V0KENhbGVuZGFyLk1JTExJU0VDT05ELCAwKTsKKworICAgICAgICBtaWxsaXMgPSBjYWwzLmdldFRpbWUoKS5nZXRUaW1lKCk7CisgICAgICAgIFRpbWVzdGFtcCB0MyA9IG5ldyBUaW1lc3RhbXAobWlsbGlzKTsKKyAgICAgICAgdGltZXMuYWRkKHQzKTsKKyAgICAgICAgLy8gVElNRVNUQU1QIHZhbHVlCisgICAgICAgIGludCBpID0gMTc7CisKKyAgICAgICAgVGltZXN0YW1wIHRpbWVSZXMgPSByZXMuZ2V0VGltZXN0YW1wKGkpOworICAgICAgICBhc3NlcnRFcXVhbHModDIudG9TdHJpbmcoKSwgdGltZVJlcy50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQyLmdldFRpbWUoKSwgdGltZVJlcy5nZXRUaW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModDIsIHRpbWVSZXMpOworICAgICAgICAvLyBEQVRFIHZhbHVlCisgICAgICAgIGkgPSAxODsKKyAgICAgICAgdGltZVJlcyA9IHJlcy5nZXRUaW1lc3RhbXAoaSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0My50b1N0cmluZygpLCB0aW1lUmVzLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModDMuZ2V0VGltZSgpLCB0aW1lUmVzLmdldFRpbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0MywgdGltZVJlcyk7CisKKyAgICAgICAgcmVzLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChyZXMuZ2V0VGltZShpKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcy5nZXRUaW1lKDUwMCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VGltZXN0YW1wSW50Q2FsZW5kYXIoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgTGlzdDxUaW1lc3RhbXA+IHRpbWVzID0gbmV3IExpbmtlZExpc3Q8VGltZXN0YW1wPigpOworCisgICAgICAgIExpc3Q8U3RyaW5nPiBzdHJpbmdUaW1lcyA9IEFycmF5cy5hc0xpc3QoInRpbWVWYWwiLCAiVFMiLCAiRFQiKTsKKyAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBpdCA9IHN0cmluZ1RpbWVzLml0ZXJhdG9yKCk7CisvLyAgICAgICAgTGlzdDxDYWxlbmRhcj4gY2FscyA9IG5ldyBMaW5rZWRMaXN0PENhbGVuZGFyPigpOworCisgICAgICAgIENhbGVuZGFyIGNhbDIgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoKTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwNyk7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5PQ1RPQkVSKTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuREFURSwgOSk7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLkhPVVJfT0ZfREFZLCAxNCk7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLk1JTlVURSwgMjgpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5TRUNPTkQsIDAyKTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuTUlMTElTRUNPTkQsIDApOworCisgICAgICAgIGxvbmcgbWlsbGlzID0gY2FsMi5nZXRUaW1lKCkuZ2V0VGltZSgpOworICAgICAgICBUaW1lc3RhbXAgdDIgPSBuZXcgVGltZXN0YW1wKG1pbGxpcyk7CisgICAgICAgIHRpbWVzLmFkZCh0Mik7CisgICAgICAgIC8vCisgICAgICAgICBDYWxlbmRhciBjYWwzID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKCk7CisgICAgICAgICAgY2FsMy5zZXQoQ2FsZW5kYXIuWUVBUiwgMTIyMSk7CisgICAgICAgICAgY2FsMy5zZXQoQ2FsZW5kYXIuTU9OVEgsIENhbGVuZGFyLlNFUFRFTUJFUik7CisgICAgICAgICAgY2FsMy5zZXQoQ2FsZW5kYXIuREFURSwgMjIpOworICAgICAgICAgY2FsMy5zZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVksIDEwKTsKKyAgICAgICAgIGNhbDMuc2V0KENhbGVuZGFyLk1JTlVURSwgMTEpOworICAgICAgICAgY2FsMy5zZXQoQ2FsZW5kYXIuU0VDT05ELCA1NSk7CisgICAgICAgICBjYWwzLnNldChDYWxlbmRhci5NSUxMSVNFQ09ORCwgMCk7CisKKyAgICAgICAgIG1pbGxpcyA9IGNhbDMuZ2V0VGltZSgpLmdldFRpbWUoKTsKKyAgICAgICAgIFRpbWVzdGFtcCB0MyA9IG5ldyBUaW1lc3RhbXAobWlsbGlzKTsKKyAgICAgICAgIHRpbWVzLmFkZCh0Myk7CisKKy8vICAgICAgICAgY2Fscy5hZGQoY2FsMSk7CisvLyAgICAgICAgIGNhbHMuYWRkKGNhbDIpOworLy8gICAgICAgICBjYWxzLmFkZChjYWwzKTsKKy8vCisvLyAgICAgICAgTGlzdEl0ZXJhdG9yPENhbGVuZGFyPiBjYWxJdCA9IGNhbHMubGlzdEl0ZXJhdG9yKCk7CisKKyAgICAgICAgaW50IGkgPSAxNzsKKworICAgICAgICBUaW1lc3RhbXAgdGltZVJlcyA9IHJlcy5nZXRUaW1lc3RhbXAoaSxuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0Mi50b1N0cmluZygpLCB0aW1lUmVzLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModDIsIHRpbWVSZXMpOworCisgICAgICAgIGkgPSAxODsKKworICAgICAgICB0aW1lUmVzID0gcmVzLmdldFRpbWVzdGFtcChpLG5ldyBHcmVnb3JpYW5DYWxlbmRhcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQzLnRvU3RyaW5nKCksIHRpbWVSZXMudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0MywgdGltZVJlcyk7CisKKyAgICAgICAgcmVzLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChyZXMuZ2V0VGltZSgxNyxjYWwyKSk7CisgICAgICAgIGFzc2VydE51bGwocmVzLmdldFRpbWUoMTgsY2FsMykpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXMuZ2V0VGltZSg1MDApOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFRpbWVzdGFtcFN0cmluZygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBMaXN0PFRpbWVzdGFtcD4gdGltZXMgPSBuZXcgTGlua2VkTGlzdDxUaW1lc3RhbXA+KCk7CisKKyAgICAgICAgTGlzdDxTdHJpbmc+IHN0cmluZ1RpbWVzID0gQXJyYXlzLmFzTGlzdCggIlRTIiwgIkRUIik7CisgICAgICAgIEl0ZXJhdG9yPFN0cmluZz4gaXQgPSBzdHJpbmdUaW1lcy5pdGVyYXRvcigpOworLy8gICAgICAgIExpc3Q8Q2FsZW5kYXI+IGNhbHMgPSBuZXcgTGlua2VkTGlzdDxDYWxlbmRhcj4oKTsKKworICAgICAgICBDYWxlbmRhciBjYWwyID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKCk7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLllFQVIsIDIwMDcpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuT0NUT0JFUik7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLkRBVEUsIDkpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5IT1VSX09GX0RBWSwgMTQpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5NSU5VVEUsIDI4KTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuU0VDT05ELCAwMik7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLk1JTExJU0VDT05ELCAwKTsKKworICAgICAgICBsb25nIG1pbGxpcyA9IGNhbDIuZ2V0VGltZSgpLmdldFRpbWUoKTsKKyAgICAgICAgVGltZXN0YW1wIHQyID0gbmV3IFRpbWVzdGFtcChtaWxsaXMpOworICAgICAgICB0aW1lcy5hZGQodDIpOworICAgICAgICAvLworICAgICAgICAgQ2FsZW5kYXIgY2FsMyA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigpOworICAgICAgICAgIGNhbDMuc2V0KENhbGVuZGFyLllFQVIsIDEyMjEpOworICAgICAgICAgIGNhbDMuc2V0KENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5TRVBURU1CRVIpOworICAgICAgICAgIGNhbDMuc2V0KENhbGVuZGFyLkRBVEUsIDIyKTsKKyAgICAgICAgIGNhbDMuc2V0KENhbGVuZGFyLkhPVVJfT0ZfREFZLCAxMCk7CisgICAgICAgICBjYWwzLnNldChDYWxlbmRhci5NSU5VVEUsIDExKTsKKyAgICAgICAgIGNhbDMuc2V0KENhbGVuZGFyLlNFQ09ORCwgNTUpOworICAgICAgICAgY2FsMy5zZXQoQ2FsZW5kYXIuTUlMTElTRUNPTkQsIDApOworCisgICAgICAgICBtaWxsaXMgPSBjYWwzLmdldFRpbWUoKS5nZXRUaW1lKCk7CisgICAgICAgICBUaW1lc3RhbXAgdDMgPSBuZXcgVGltZXN0YW1wKG1pbGxpcyk7CisgICAgICAgICB0aW1lcy5hZGQodDMpOworCisgICAgICAgIFN0cmluZyBjb2wgPSBpdC5uZXh0KCk7CisKKyAgICAgICAgVGltZXN0YW1wIHRpbWVSZXMgPSByZXMuZ2V0VGltZXN0YW1wKGNvbCk7CisgICAgICAgIGFzc2VydEVxdWFscyh0Mi50b1N0cmluZygpLCB0aW1lUmVzLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModDIudG9TdHJpbmcoKSwgdGltZVJlcy50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQyLmdldFRpbWUoKSwgdGltZVJlcy5nZXRUaW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModDIsIHRpbWVSZXMpOworICAgICAgICAvLyBEQVRFIHZhbHVlCisgICAgICAgIGNvbCA9IGl0Lm5leHQoKTsKKworICAgICAgICB0aW1lUmVzID0gcmVzLmdldFRpbWVzdGFtcChjb2wpOworICAgICAgICBhc3NlcnRFcXVhbHModDMudG9TdHJpbmcoKSwgdGltZVJlcy50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQzLnRvU3RyaW5nKCksIHRpbWVSZXMudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0My5nZXRUaW1lKCksIHRpbWVSZXMuZ2V0VGltZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQzLCB0aW1lUmVzKTsKKworICAgICAgICByZXMubmV4dCgpOworICAgICAgICBhc3NlcnROdWxsKHJlcy5nZXRUaW1lKHN0cmluZ1RpbWVzLmdldCgwKSkpOworICAgICAgICBhc3NlcnROdWxsKHJlcy5nZXRUaW1lKHN0cmluZ1RpbWVzLmdldCgxKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXMuZ2V0VGltZSg1MDApOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFRpbWVzdGFtcFN0cmluZ0NhbGVuZGFyKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIExpc3Q8VGltZXN0YW1wPiB0aW1lcyA9IG5ldyBMaW5rZWRMaXN0PFRpbWVzdGFtcD4oKTsKKworICAgICAgICBMaXN0PFN0cmluZz4gc3RyaW5nVGltZXMgPSBBcnJheXMuYXNMaXN0KCAiVFMiLCAiRFQiKTsKKyAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBpdCA9IHN0cmluZ1RpbWVzLml0ZXJhdG9yKCk7CisKKyAgICAgICAgQ2FsZW5kYXIgY2FsMiA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5ZRUFSLCAyMDA3KTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuTU9OVEgsIENhbGVuZGFyLk9DVE9CRVIpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5EQVRFLCA5KTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVksIDE0KTsKKyAgICAgICAgY2FsMi5zZXQoQ2FsZW5kYXIuTUlOVVRFLCAyOCk7CisgICAgICAgIGNhbDIuc2V0KENhbGVuZGFyLlNFQ09ORCwgMDIpOworICAgICAgICBjYWwyLnNldChDYWxlbmRhci5NSUxMSVNFQ09ORCwgMCk7CisKKyAgICAgICAgbG9uZyBtaWxsaXMgPSBjYWwyLmdldFRpbWUoKS5nZXRUaW1lKCk7CisgICAgICAgIFRpbWVzdGFtcCB0MiA9IG5ldyBUaW1lc3RhbXAobWlsbGlzKTsKKyAgICAgICAgdGltZXMuYWRkKHQyKTsKKyAgICAgICAgLy8KKyAgICAgICAgIENhbGVuZGFyIGNhbDMgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoKTsKKyAgICAgICAgICBjYWwzLnNldChDYWxlbmRhci5ZRUFSLCAxMjIxKTsKKyAgICAgICAgICBjYWwzLnNldChDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuU0VQVEVNQkVSKTsKKyAgICAgICAgICBjYWwzLnNldChDYWxlbmRhci5EQVRFLCAyMik7CisgICAgICAgICBjYWwzLnNldChDYWxlbmRhci5IT1VSX09GX0RBWSwgMTApOworICAgICAgICAgY2FsMy5zZXQoQ2FsZW5kYXIuTUlOVVRFLCAxMSk7CisgICAgICAgICBjYWwzLnNldChDYWxlbmRhci5TRUNPTkQsIDU1KTsKKyAgICAgICAgIGNhbDMuc2V0KENhbGVuZGFyLk1JTExJU0VDT05ELCAwKTsKKworICAgICAgICAgbWlsbGlzID0gY2FsMy5nZXRUaW1lKCkuZ2V0VGltZSgpOworICAgICAgICAgVGltZXN0YW1wIHQzID0gbmV3IFRpbWVzdGFtcChtaWxsaXMpOworICAgICAgICAgdGltZXMuYWRkKHQzKTsKKworICAgICAgICBUaW1lc3RhbXAgdGltZVJlcyA9IHJlcy5nZXRUaW1lc3RhbXAoc3RyaW5nVGltZXMuZ2V0KDApLGNhbDIpOworICAgICAgICBhc3NlcnRFcXVhbHModDIudG9TdHJpbmcoKSwgdGltZVJlcy50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQyLmdldFRpbWUoKSwgdGltZVJlcy5nZXRUaW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModDIsIHRpbWVSZXMpOworICAgICAgICAgICAgLy8gREFURSB2YWx1ZQorICAgICAgICB0aW1lUmVzID0gcmVzLmdldFRpbWVzdGFtcChzdHJpbmdUaW1lcy5nZXQoMSksY2FsMyk7CisgICAgICAgIGFzc2VydEVxdWFscyh0My50b1N0cmluZygpLCB0aW1lUmVzLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModDMuZ2V0VGltZSgpLCB0aW1lUmVzLmdldFRpbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0MywgdGltZVJlcyk7CisKKyAgICAgICAgLy8gY2FsSXQgPSBjYWxzLmxpc3RJdGVyYXRvcigpOworCisgICAgICAgIHJlcy5uZXh0KCk7CisgICAgICAgIGFzc2VydE51bGwocmVzLmdldFRpbWUoc3RyaW5nVGltZXMuZ2V0KDApLGNhbDIpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChyZXMuZ2V0VGltZShzdHJpbmdUaW1lcy5nZXQoMSksY2FsMykpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXMuZ2V0VGltZSg1MDApOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgLy8gcmVzLmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRUeXBlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyhSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFksIHJlcy5nZXRUeXBlKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgcmVzLmdldFR5cGUoKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VVJMSW50KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiwgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIGlucHV0ID0gbmV3IFVSTCgiaHR0cDovL3d3dy5hbmRyb2lkLmNvbSIpOworICAgICAgICBVUkwgdmFsaWRVUkwgPSByZXMuZ2V0VVJMKDI5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGlucHV0LCB2YWxpZFVSTCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFVSTCBpbnZhbGlkVVJMID0gcmVzLmdldFVSTCgzMCk7CisgICAgICAgICAgICBhc3NlcnROdWxsKGludmFsaWRVUkwpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgICAgIHJlcy5uZXh0KCk7CisgICAgICAgIGFzc2VydE51bGwocmVzLmdldFVSTCgyOSkpOworICAgICAgICBhc3NlcnROdWxsKHJlcy5nZXRVUkwoMzApKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzLmdldFVSTCg1MDApOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFVSTFN0cmluZygpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24sIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCBpbnB1dCA9IG5ldyBVUkwoImh0dHA6Ly93d3cuYW5kcm9pZC5jb20iKTsKKyAgICAgICAgVVJMIHZhbGlkVVJMID0gcmVzLmdldFVSTCgidmFsaWRVUkwiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGlucHV0LCB2YWxpZFVSTCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFVSTCBpbnZhbGlkVVJMID0gcmVzLmdldFVSTCgiaW52YWxpZFVSTCIpOworICAgICAgICAgICAgYXNzZXJ0TnVsbChpbnZhbGlkVVJMKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICByZXMubmV4dCgpOworICAgICAgICBhc3NlcnROdWxsKHJlcy5nZXRVUkwoInZhbGlkVVJMIikpOworICAgICAgICBhc3NlcnROdWxsKHJlcy5nZXRVUkwoImludmFsaWRVUkwiKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcy5nZXRVUkwoImJsYSIpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zcWwvT2xkUmVzdWx0U2V0TWV0YURhdGFUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NxbC9PbGRSZXN1bHRTZXRNZXRhRGF0YVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi40ZGJjZGZkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zcWwvT2xkUmVzdWx0U2V0TWV0YURhdGFUZXN0LmphdmEKQEAgLTAsMCArMSw3MjcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnNxbDsKKworaW1wb3J0IGphdmEuc3FsLlJlc3VsdFNldDsKK2ltcG9ydCBqYXZhLnNxbC5SZXN1bHRTZXRNZXRhRGF0YTsKK2ltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247CitpbXBvcnQgamF2YS5zcWwuU3RhdGVtZW50OworaW1wb3J0IGphdmEuc3FsLlR5cGVzOworCitwdWJsaWMgZmluYWwgY2xhc3MgT2xkUmVzdWx0U2V0TWV0YURhdGFUZXN0IGV4dGVuZHMgT2xkU1FMVGVzdCB7CisKKyAgICBSZXN1bHRTZXRNZXRhRGF0YSByc21kID0gbnVsbDsKKyAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgIFJlc3VsdFNldCBycyA9IG51bGw7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5zZXRBdXRvQ29tbWl0KGZhbHNlKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGNvbm4uZ2V0QXV0b0NvbW1pdCgpKTsKKyAgICAgICAgICAgIFN0cmluZyBxdWVyeSA9ICJzZWxlY3QgKiBmcm9tIHpvbyI7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKHF1ZXJ5KTsKKyAgICAgICAgICAgIHJzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICByc21kID0gcnMuZ2V0TWV0YURhdGEoKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkNvdWxkbid0IGdldCBSZXN1bHRTZXRNZXRhRGF0YSBvYmplY3QiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBycy5jbG9zZSgpOworICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkNvdWxkbid0IGNsb3NlIFN0YXRlbWVudCBvYmplY3QiKTsKKyAgICAgICAgfQorICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8vIG5vdCBzdXBwb3J0ZWQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q2F0YWxvZ05hbWUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocnNtZC5nZXRDYXRhbG9nTmFtZSgxKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgdGhyb3duOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uY2xvc2UoKTsKKyAgICAgICAgICAgIHJzbWQuZ2V0Q2F0YWxvZ05hbWUoMCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDb2x1bW5DbGFzc05hbWUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHJzbWQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFNob3J0LmNsYXNzLmdldE5hbWUoKSwgcnNtZC5nZXRDb2x1bW5DbGFzc05hbWUoMSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFN0cmluZy5jbGFzcy5nZXROYW1lKCksIHJzbWQuZ2V0Q29sdW1uQ2xhc3NOYW1lKDIpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhTdHJpbmcuY2xhc3MuZ2V0TmFtZSgpLCByc21kLmdldENvbHVtbkNsYXNzTmFtZSgzKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgdGhyb3duOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBuYW1lICA9IHJzbWQuZ2V0Q29sdW1uQ2xhc3NOYW1lKDApOworICAgICAgICAgICAgYXNzZXJ0TnVsbChuYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgbmFtZSAgPSByc21kLmdldENvbHVtbkNsYXNzTmFtZSg0KTsKKyAgICAgICAgICAgIGFzc2VydE51bGwobmFtZSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgdGhyb3duIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBTUUxFeGNlcHRpb24gY2hlY2tpbmcgdGVzdCBmYWlscworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDb2x1bW5Db3VudCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygzLCByc21kLmdldENvbHVtbkNvdW50KCkpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93bjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBycy5jbG9zZSgpOworICAgICAgICAgICAgcnNtZC5nZXRDb2x1bW5Db3VudCgpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKworICAgIH0KKworICAgIC8vIENvbHVtbiBsYWJlbCBoYXMgZm9ybWF0IFRBQkxFLkNPTFVNTiBleHBlY3RlZDogQ09MVU1OCisgICAgcHVibGljIHZvaWQgdGVzdEdldENvbHVtbkxhYmVsKCkgeworICAgICAgICBTdHJpbmdbXSBsYWJlbHMgPSB7ICJpZCIsICJuYW1lIiwgImZhbWlseSIgfTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcnNtZC5nZXRDb2x1bW5Db3VudCgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgbGFiZWwgPSByc21kLmdldENvbHVtbkxhYmVsKGkgKyAxKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJleHBlY3RlZCAiK2xhYmVsc1tpXSArICJnb3QgIitsYWJlbCxsYWJlbHNbaV0uY29udGFpbnMobGFiZWwpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIGxhYmVsID0gcnNtZC5nZXRDb2x1bW5MYWJlbCgwKTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBsYWJlbCA9IHJzbWQuZ2V0Q29sdW1uTGFiZWwoNSk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIENvbHVtbiBsYWJlbCBoYXMgZm9ybWF0IFRBQkxFLkNPTFVNTiBleHBlY3RlZDogQ09MVU1OCisgICAgcHVibGljIHZvaWQgdGVzdEdldENvbHVtbk5hbWUoKSB7CisgICAgICAgIFN0cmluZ1tdIGxhYmVscyA9IHsgImlkIiwgIm5hbWUiLCAiZmFtaWx5IiB9OworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByc21kLmdldENvbHVtbkNvdW50KCk7IGkrKykgeworICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gcnNtZC5nZXRDb2x1bW5OYW1lKGkgKyAxKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMobGFiZWxzW2ldLCBuYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIGxhYmVsID0gcnNtZC5nZXRDb2x1bW5OYW1lKDApOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgbGFiZWwgPSByc21kLmdldENvbHVtbk5hbWUoNSk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRm9yIGV4dGVuc2l2ZSB0ZXN0cyBzZWU6IFJlc3VsdFNldEdldHRlclRlc3QudGVzdEdldE1ldGFEYXRhCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldENvbHVtblR5cGUoKSB7CisgICAgICAgIGludFtdIHR5cGVzID0geyBUeXBlcy5TTUFMTElOVCwgVHlwZXMuVkFSQ0hBUiwgVHlwZXMuVkFSQ0hBUn07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJzbWQuZ2V0Q29sdW1uQ291bnQoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgaW50IHR5cGUgPSByc21kLmdldENvbHVtblR5cGUoaSArIDEpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyh0eXBlc1tpXSwgdHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgdGhyb3duOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJzbWQuZ2V0Q29sdW1uVHlwZSgwKTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByc21kLmdldENvbHVtblR5cGUoNSk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGZvciBleHRlbnNpdmUgdGVzdHMgc2VlOiBSZXN1bHRTZXRHZXR0ZXJUZXN0LnRlc3RHZXRNZXRhRGF0YQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDb2x1bW5UeXBlTmFtZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoInNtYWxsaW50Ii5lcXVhbHNJZ25vcmVDYXNlKHJzbWQuZ2V0Q29sdW1uVHlwZU5hbWUoMSkpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoInZhcmNoYXIiLmVxdWFsc0lnbm9yZUNhc2UocnNtZC5nZXRDb2x1bW5UeXBlTmFtZSgyKSkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidmFyY2hhciIuZXF1YWxzSWdub3JlQ2FzZShyc21kLmdldENvbHVtblR5cGVOYW1lKDMpKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgdGhyb3duOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJzbWQuZ2V0Q29sdW1uVHlwZU5hbWUoMCk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcnNtZC5nZXRDb2x1bW5UeXBlTmFtZSg1KTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLy8gRm9yIGludCA9IDAsIGV4Y2VwdGlvbiBleHBlY3RlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRUYWJsZU5hbWUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiem9vIiwgcnNtZC5nZXRUYWJsZU5hbWUoMSkpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93bjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBTdGF0ZW1lbnQgc3QxID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJzMSA9IG51bGw7CisgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgIFN0cmluZyBjcmVhdGUgPSAiY3JlYXRlIHRhYmxlIGh1dGNoIChpZCBpbnRlZ2VyIG5vdCBudWxsLCBhbmltYWxfaWQgaW50ZWdlciwgYWRkcmVzcyBjaGFyKDIwKSwgcHJpbWFyeSBrZXkgKGlkKSk7IjsKKyAgICAgICAgICAgIFN0cmluZyBpbnNlcnQxID0gImluc2VydCBpbnRvIGh1dGNoIChpZCwgYW5pbWFsX2lkLCBhZGRyZXNzKSB2YWx1ZXMgKDEsIDIsICdCaXJkcy1ob3VzZSwgMScpOyI7CisgICAgICAgICAgICBTdHJpbmcgaW5zZXJ0MiA9ICJpbnNlcnQgaW50byBodXRjaCAoaWQsIGFuaW1hbF9pZCwgYWRkcmVzcykgdmFsdWVzICgyLCAxLCAnSG9yc2UtaG91c2UsIDUnKTsiOworICAgICAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gInNlbGVjdCBuYW1lLCBhbmltYWxfaWQgZnJvbSBodXRjaCwgem9vIHdoZXJlIHpvby5pZCA9IDEiIDsKKyAgICAgICAgICAgIHN0MSA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdDEuZXhlY3V0ZVVwZGF0ZShjcmVhdGUpOworICAgICAgICAgICAgc3QxLmV4ZWN1dGVVcGRhdGUoaW5zZXJ0MSk7CisgICAgICAgICAgICBzdDEuZXhlY3V0ZVVwZGF0ZShpbnNlcnQyKTsKKworICAgICAgICAgICAgcnMxID0gc3QxLmV4ZWN1dGVRdWVyeShxdWVyeSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHJzMSk7CisgICAgICAgICAgICBSZXN1bHRTZXRNZXRhRGF0YSByc21kMSA9IHJzMS5nZXRNZXRhRGF0YSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ6b28iLCByc21kMS5nZXRUYWJsZU5hbWUoMSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJodXRjaCIsIHJzbWQxLmdldFRhYmxlTmFtZSgyKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgdGhyb3duOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAocnMxICE9IG51bGwpIHJzMS5jbG9zZSgpOworICAgICAgICAgICAgICAgIGlmIChzdDEgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBzdDEuZXhlY3V0ZVVwZGF0ZSgiZHJvcCB0YWJsZSBpZiBleGlzdHMgaHV0Y2giKTsKKyAgICAgICAgICAgICAgICAgICAgc3QxLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvL0V4Y2VwdGlvbiBUZXh0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IHJzbWQuZ2V0VGFibGVOYW1lKDApOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIEV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgLy8gbm90IHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQcmVjaXNpb24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0MiA9IG51bGw7CisgICAgICAgIFN0YXRlbWVudCBzdDMgPSBudWxsOworICAgICAgICBSZXN1bHRTZXRNZXRhRGF0YSByc21kMiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgIGludCBwcmVjaXNpb25OdW0gPSAxMDsKKyAgICAgICAgaW50IHNjYWxlID0gMzsKKyAgICAgICAgaW50IHByZWNpY2lzaW9uUmVhbCA9IDEwOworICAgICAgICBTdHJpbmcgY3JlYXRlVGFibGUgPSAiY3JlYXRlIHRhYmxlIERlY2ltYWxOdW1iZXJzICggdmFsdWVEb3VibGUgRE9VQkxFLCIrCisgICAgICAgICJ2YWx1ZUZsb2F0IEZMT0FUICwgc2NhbGVUZXN0IE5VTUVSSUMoIitwcmVjaXNpb25OdW0rIiwiK3NjYWxlKyIpLCIrCisgICAgICAgICIgdmFsdWVSZWFsIFJFQUwoIitwcmVjaWNpc2lvblJlYWwrIikgICk7IjsKKyAgICAgICAgU3RyaW5nIGluc2VydCA9ICJpbnNlcnQgaW50byBEZWNpbWFsTnVtYmVycyB2YWx1ZXMgKDEuNSwgMjAuNTUsIDMwLjY2NiwgMTAwMDAwKTsiOworICAgICAgICBTdHJpbmcgc2VsZWN0ID0gInNlbGVjdCAqIGZyb20gRGVjaW1hbE51bWJlcnM7IjsKKyAgICAgICAgc3QyID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgc3QyLmV4ZWN1dGVVcGRhdGUoY3JlYXRlVGFibGUpOworICAgICAgICBzdDIuZXhlY3V0ZVVwZGF0ZShpbnNlcnQpOworCisgICAgICAgIHN0Mi5jbG9zZSgpOworCisgICAgICAgIHN0MyA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgIHJzID0gc3QzLmV4ZWN1dGVRdWVyeShzZWxlY3QpOworICAgICAgICBhc3NlcnRUcnVlKHJzLm5leHQoKSk7CisgICAgICAgIHJzbWQyID0gcnMuZ2V0TWV0YURhdGEoKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKHJzbWQyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHByZWNpY2lzaW9uUmVhbCwgcnNtZDIuZ2V0UHJlY2lzaW9uKDQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHByZWNpc2lvbk51bSxyc21kMi5nZXRQcmVjaXNpb24oMykpOworICAgICAgICBhc3NlcnRUcnVlKHJzbWQyLmdldFByZWNpc2lvbigyKSA+IDApOworICAgICAgICBhc3NlcnRUcnVlKHJzbWQyLmdldFByZWNpc2lvbigxKSA+IDApOworCisgICAgICAgIC8vIG5vbiBudW1lcmljIGZpZWxkCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByc21kLmdldFByZWNpc2lvbigzKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUxKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlJlc3VsdFNldE1ldGFEYXRhVGVzdC50ZXN0R2V0UHJlY2lzaW9uKCkiK2UxLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICBlMS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorCisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJzbWQuZ2V0UHJlY2lzaW9uKDApOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJzbWQuZ2V0UHJlY2lzaW9uKDUpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcnMuY2xvc2UoKTsKKyAgICAgICAgICAgIHJzbWQuZ2V0UHJlY2lzaW9uKDEpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5ICB7CisgICAgICAgICAgICBpZiAoc3QyICE9IG51bGwpIHN0Mi5jbG9zZSgpOworICAgICAgICAgICAgaWYgKHN0MyAhPSBudWxsKSBzdDMuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFsd2F5cyByZXR1cm5zIDAsIGV4Y2VwdGlvbiB0ZXN0cyBmYWlsIG5vIHBvc2l0aXZlIHRlc3QgY2FzZSBmb3IKKyAgICAgKiBibGFjay1ib3ggdGVzdCBwb3NzaWJsZTogbm8gZGVmYXVsdCB2YWx1ZSBpbmRpY2F0ZWQuCisgICAgICoKKyAgICAgKiBOb3Qgc3VwcG9ydGVkCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldFNjYWxlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgIGludCBzY2FsZSA9IDM7CisgICAgICAgIFN0cmluZyBjcmVhdGVUYWJsZSA9ICJjcmVhdGUgdGFibGUgRGVjaW1hbE51bWJlcnMgKCB2YWx1ZURvdWJsZSBET1VCTEUsIisKKyAgICAgICAgInZhbHVlRmxvYXQgRkxPQVQgLCBzY2FsZVRlc3QgTlVNRVJJQygxMCwiK3NjYWxlKyIpICApOyI7CisgICAgICAgIFN0cmluZyBpbnNlcnQgPSAiaW5zZXJ0IGludG8gRGVjaW1hbE51bWJlcnMgdmFsdWVzICgxLjUsIDIwLjU1LCAzMC42NjYpOyI7CisgICAgICAgIFN0cmluZyBzZWxlY3QgPSAic2VsZWN0ICogZnJvbSBEZWNpbWFsTnVtYmVyczsiOworCisgICAgICAgIFN0YXRlbWVudCBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgIHN0LmV4ZWN1dGVVcGRhdGUoY3JlYXRlVGFibGUpOworICAgICAgICBzdC5leGVjdXRlVXBkYXRlKGluc2VydCk7CisKKyAgICAgICAgcnMgPSBzdC5leGVjdXRlUXVlcnkoc2VsZWN0KTsKKyAgICAgICAgUmVzdWx0U2V0TWV0YURhdGEgcnNtZDIgPSBycy5nZXRNZXRhRGF0YSgpOworCisgICAgICAgIGFzc2VydE5vdE51bGwocnNtZDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoc2NhbGUscnNtZDIuZ2V0U2NhbGUoMykpOworICAgICAgICBhc3NlcnRUcnVlKHJzbWQyLmdldFNjYWxlKDEpID4gMCk7CisgICAgICAgIGFzc2VydFRydWUocnNtZDIuZ2V0U2NhbGUoMikgPiAwKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcnNtZC5nZXRTY2FsZSgwKTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByc21kLmdldFNjYWxlKDUpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLmNsb3NlKCk7CisgICAgICAgICAgICByc21kLmdldFNjYWxlKDEpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5ICB7CisgICAgICAgICAgICBzdC5jYW5jZWwoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIG5vdCBzdXBwb3J0ZWQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2NoZW1hKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiRnVuY3Rpb25hbGl0eSBpcyBub3cgc3VwcG9ydGVkLiBDaGFuZ2UgdGVzdCIscnNtZC5nZXRTY2hlbWFOYW1lKDIpKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUxKSB7CisgICAgICAgICAgICBmYWlsKCJSZXN1bHRTZXRNZXRhRGF0YVRlc3QudGVzdEdldFNjYWxlKCkiK2UxLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICBlMS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByc21kLmdldFNjaGVtYU5hbWUoMCk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcnNtZC5nZXRTY2hlbWFOYW1lKDUpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5jbG9zZSgpOworICAgICAgICAgICAgcnNtZC5nZXRTY2hlbWFOYW1lKDIpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIGZhaWw6IGFsd2F5cyByZXR1cm5zIGZhbHNlLCBmYWlsaW5nIHN0YXRlbWVudHMgY29tbWVudGVkIG91dC4KKyAgICAgKiBGZWF0dXJlIG9ubHkgcGFydGlhbGx5IGltcGxlbWVudGVkLk1pc3Npbmc6IFRlc3QgcG9zaXRpdmUgY2FzZQorICAgICAqCisgICAgICogTm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0aXNBdXRvSW5jcmVtZW50KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UocnNtZC5pc0F1dG9JbmNyZW1lbnQoMSkpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZTEpIHsKKyAgICAgICAgICAgIGZhaWwoIlJlc3VsdFNldE1ldGFEYXRhVGVzdC50ZXN0R2V0U2NhbGUoKSIrZTEuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIGUxLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgLy8gRXhjZXB0aW9uIHRlc3RpbmcKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcnNtZC5pc0F1dG9JbmNyZW1lbnQoMCk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcnNtZC5pc0F1dG9JbmNyZW1lbnQoNSk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICAqLworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLmNsb3NlKCk7CisgICAgICAgICAgICByc21kLmdldFNjaGVtYU5hbWUoMik7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLy8gbm90IHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RJc0Nhc2VTZW5zaXRpdmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShyc21kLmlzQ2FzZVNlbnNpdGl2ZSgxKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShyc21kLmlzQ2FzZVNlbnNpdGl2ZSgyKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShyc21kLmlzQ2FzZVNlbnNpdGl2ZSgzKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlMSkgeworICAgICAgICAgICAgZmFpbCgiUmVzdWx0U2V0TWV0YURhdGFUZXN0LnRlc3RHZXRTY2FsZSgpIitlMS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgZTEucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAvLyBFeGNlcHRpb24gdGVzdGluZworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByc21kLmlzQ2FzZVNlbnNpdGl2ZSgwKTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByc21kLmlzQ2FzZVNlbnNpdGl2ZSg1KTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgICovCisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uY2xvc2UoKTsKKyAgICAgICAgICAgIHJzbWQuaXNDYXNlU2Vuc2l0aXZlKDEpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBmYWlsOiBhbHdheXMgcmV0dXJucyBmYWxzZS4gRXhjZXB0aW9ucyBhbmQgdGVzdHMgbm9uIE51bWVyaWMgZmllbGRzCisgICAgICogZmFpbCwgZmFpbGluZyBzdGF0ZW1lbnRzIGNvbW1lbnRlZCBvdXQuIEZlYXR1cmUgb25seSBwYXJ0aWFsbHkKKyAgICAgKiBpbXBsZW1lbnRlZC4gTWF5IGJlIGFuIG9wdGlvbmFsIGZlYXR1cmUuCisgICAgICoKKyAgICAgKiBOb3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJc0N1cnJlbmN5KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UocnNtZC5pc0N1cnJlbmN5KDEpKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUxKSB7CisgICAgICAgICAgICBmYWlsKCJSZXN1bHRTZXRNZXRhRGF0YVRlc3QudGVzdEdldFNjYWxlKCkiK2UxLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICBlMS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEV4Y2VwdGlvbiB0ZXN0aW5nCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByc21kLmlzQ3VycmVuY3koMCk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcnNtZC5pc0N1cnJlbmN5KDUpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcnMuY2xvc2UoKTsKKyAgICAgICAgICAgIHJzbWQuaXNDdXJyZW5jeSgxKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgLy8gbm90IHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RJc0RlZmluaXRseVdyaXRhYmxlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShyc21kLmlzRGVmaW5pdGVseVdyaXRhYmxlKDEpKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUxKSB7CisgICAgICAgICAgICBmYWlsKCJSZXN1bHRTZXRNZXRhRGF0YVRlc3QudGVzdGlzRGVmaW5pdGVseVdyaXRhYmxlKCkiCisgICAgICAgICAgICAgICAgICAgICsgZTEuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIGUxLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gRXhjZXB0aW9uIHRlc3RpbmcKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcnNtZC5pc0RlZmluaXRlbHlXcml0YWJsZSgwKTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByc21kLmlzRGVmaW5pdGVseVdyaXRhYmxlKDUpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBmYWlsOiBhbHdheXMgcmV0dXJucyBSZXN1bHRTZXRNZXRhRGF0YS5jb2x1bW5OdWxsYWJsZVVua25vd24uCisgICAgICogRXhjZXB0aW9ucyBmYWlsLCBmYWlsaW5nIHN0YXRlbWVudHMgY29tbWVudGVkIG91dC4gRmVhdHVyZSBvbmx5CisgICAgICogcGFydGlhbGx5IGltcGxlbWVudGVkLiBNYXkgYmUgYW4gb3B0aW9uYWwgZmVhdHVyZS4KKyAgICAgKgorICAgICAqIE5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdElzTnVsbGFibGUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoUmVzdWx0U2V0TWV0YURhdGEuY29sdW1uTnVsbGFibGUsIHJzbWQKKyAgICAgICAgICAgICAgICAgICAgLmlzTnVsbGFibGUoMSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFJlc3VsdFNldE1ldGFEYXRhLmNvbHVtbk51bGxhYmxlLCByc21kCisgICAgICAgICAgICAgICAgICAgIC5pc051bGxhYmxlKDIpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhSZXN1bHRTZXRNZXRhRGF0YS5jb2x1bW5OdWxsYWJsZSwgcnNtZAorICAgICAgICAgICAgICAgICAgICAuaXNOdWxsYWJsZSgzKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlMSkgeworICAgICAgICAgICAgZmFpbCgiUmVzdWx0U2V0TWV0YURhdGFUZXN0LmlzTnVsbGFibGUoKSIgKyBlMS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgZTEucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAvLyBFeGNlcHRpb24gdGVzdGluZworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByc21kLmlzTnVsbGFibGUoMCk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcnNtZC5pc051bGxhYmxlKDUpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgKi8KKworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbm5vdCBrbm93IGZyb20gYmxhY2tib3ggdGVzdCBpZiByZWFkb25seSBvciB3cml0YWJsZS4gRXhjZXB0aW9ucyBmYWlsLAorICAgICAqIEZlYXR1cmUgb25seSBwYXJ0aWFsbHkgaW1wbGVtZW50ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdElzUmVhZE9ubHkoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShyc21kLmlzUmVhZE9ubHkoMSkpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZTEpIHsKKyAgICAgICAgICAgIGZhaWwoIlJlc3VsdFNldE1ldGFEYXRhVGVzdC5pc1JlYWRPbmx5IiArIGUxLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICBlMS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEV4Y2VwdGlvbiB0ZXN0aW5nCisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJzbWQuaXNSZWFkT25seSgwKTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgZmFpbDogYWx3YXlzIHJldHVybnMgZmFsc2UuIEV4Y2VwdGlvbnMgZmFpbCwgRmVhdHVyZSBvbmx5IHBhcnRpYWxseQorICAgICAqIGltcGxlbWVudGVkLiBNaXNzaW5nOiB0ZXN0IGZvciBzZWFyY2hhYmxlIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJc1NlYXJjaGFibGUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHJzbWQuaXNTZWFyY2hhYmxlKDEpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUocnNtZC5pc1NlYXJjaGFibGUoMikpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShyc21kLmlzU2VhcmNoYWJsZSgzKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlMSkgeworICAgICAgICAgICAgZmFpbCgiUmVzdWx0U2V0TWV0YURhdGFUZXN0LmlzUmVhZE9ubHkiICsgZTEuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIGUxLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gRXhjZXB0aW9uIHRlc3RpbmcKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcnNtZC5pc1NlYXJjaGFibGUoMCk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIGZhaWw6IGFsd2F5cyByZXR1cm5zIGZhbHNlLiBFeGNlcHRpb25zIGFuZCB0ZXN0cyBvbiBub24gbnVtZXJpYworICAgICAqIGZpZWxkcyBmYWlsLCBGZWF0dXJlIG9ubHkgcGFydGlhbGx5IGltcGxlbWVudGVkLiBNaXNzaW5nOiB0ZXN0IHBvc2l0aXZlCisgICAgICogcmVzdWx0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdElzU2lnbmVkKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UocnNtZC5pc1NpZ25lZCgxKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlMSkgeworICAgICAgICAgICAgZmFpbCgiUmVzdWx0U2V0TWV0YURhdGFUZXN0LmlzU2lnbmVkIiArIGUxLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICBlMS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEV4Y2VwdGlvbiB0ZXN0aW5nCisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJzbWQuaXNTaWduZWQoMCk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFuYWxvZ291cyB0byBpcyBSZWFkb25seS4gIEV4Y2VwdGlvbnMgYW5kIHRlc3RzIG9uIG5vbiBudW1lcmljIGZpZWxkcworICAgICAqIGZhaWwsIEZhaWxpbmcgc3RhdGVtZW50cyBjb21tZW50ZWQgb3V0LiBGZWF0dXJlIG9ubHkgcGFydGlhbGx5CisgICAgICogaW1wbGVtZW50ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdElzV3JpdGFibGUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHJzbWQuaXNXcml0YWJsZSgxKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHJzbWQuaXNXcml0YWJsZSgyKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHJzbWQuaXNXcml0YWJsZSgzKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlMSkgeworICAgICAgICAgICAgZmFpbCgiUmVzdWx0U2V0TWV0YURhdGFUZXN0LmlzV3JpdGFibGUiICsgZTEuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIGUxLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gRXhjZXB0aW9uIHRlc3RpbmcKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcnNtZC5pc1dyaXRhYmxlKDApOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFRlc3RzIGZhaWwuIGFsd2F5cyByZXR1cm5zIDAuIE1pc3NpbmcgY2FzZSB3aGVyZSBkaXNwbGF5IHNpemUgZ3JlYXRlciB0aGFuIDAKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q29sdW1uRGlzcGxheVNpemUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJzbWQuZ2V0Q29sdW1uQ291bnQoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgaW50IHNpemUgPSByc21kLmdldENvbHVtbkRpc3BsYXlTaXplKGkgKyAxKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKHNpemUgPiAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBFeGNlcHRpb24gdGVzdGluZworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByc21kLmdldENvbHVtbkRpc3BsYXlTaXplKDApOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJzbWQuZ2V0Q29sdW1uRGlzcGxheVNpemUoNSk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zcWwvT2xkUmVzdWx0U2V0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zcWwvT2xkUmVzdWx0U2V0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVhMThkYjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NxbC9PbGRSZXN1bHRTZXRUZXN0LmphdmEKQEAgLTAsMCArMSw0ODIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnNxbDsKKworaW1wb3J0IGphdmEuc3FsLlByZXBhcmVkU3RhdGVtZW50OworaW1wb3J0IGphdmEuc3FsLlJlc3VsdFNldDsKK2ltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247CitpbXBvcnQgamF2YS5zcWwuU3RhdGVtZW50OworaW1wb3J0IHRlc3RzLnN1cHBvcnQuRGF0YWJhc2VDcmVhdG9yOworCitwdWJsaWMgZmluYWwgY2xhc3MgT2xkUmVzdWx0U2V0VGVzdCBleHRlbmRzIE9sZFNRTFRlc3QgeworCisgICAgUmVzdWx0U2V0IHRhcmdldCA9IG51bGw7CisgICAgUmVzdWx0U2V0IGVtcHR5VGFyZ2V0ID0gbnVsbDsKKyAgICBSZXN1bHRTZXQgc2Nyb2xsYWJsZVRhcmdldCA9IG51bGw7CisgICAgUmVzdWx0U2V0IHdyaXRhYmxlVGFyZ2V0ID0gbnVsbDsKKyAgICBTdGF0ZW1lbnQgc3RGb3J3YXJkID0gbnVsbDsKKyAgICBTdGF0ZW1lbnQgc3RTY3JvbGxhYmxlID0gbnVsbDsKKyAgICBTdGF0ZW1lbnQgc3RXcml0YWJsZSA9IG51bGw7CisgICAgZmluYWwgU3RyaW5nIHNlbGVjdEFsbEFuaW1hbHMgPSAic2VsZWN0IGlkLCBuYW1lIGZyb20gem9vIjsKKyAgICBmaW5hbCBTdHJpbmcgc2VsZWN0RW1wdHlUYWJsZSA9ICJzZWxlY3QgKiBmcm9tICIrRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTE7CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKworICAgICAgICBjb25uLnNldEF1dG9Db21taXQoZmFsc2UpOworICAgICAgICBzdEZvcndhcmQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudChSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFksCisgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNPTkNVUl9SRUFEX09OTFkpOworICAgICAgICBzdEZvcndhcmQuZXhlY3V0ZShzZWxlY3RBbGxBbmltYWxzKTsKKyAgICAgICAgdGFyZ2V0ID0gc3RGb3J3YXJkLmdldFJlc3VsdFNldCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRhcmdldCk7CisKKyAgICAgICAgLy8gZW1wdHkgdGFibGUKKyAgICAgICAgc3RGb3J3YXJkID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZLAorICAgICAgICAgICAgICAgIFJlc3VsdFNldC5DT05DVVJfUkVBRF9PTkxZKTsKKyAgICAgICAgc3RGb3J3YXJkLmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkNSRUFURV9UQUJMRV9TSU1QTEUxKTsKKyAgICAgICAgc3RGb3J3YXJkLmV4ZWN1dGUoc2VsZWN0RW1wdHlUYWJsZSk7CisgICAgICAgIGVtcHR5VGFyZ2V0ID0gc3RGb3J3YXJkLmdldFJlc3VsdFNldCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgICAgIHRhcmdldC5jbG9zZSgpOworICAgICAgICBzdEZvcndhcmQuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWJzb2x1dGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0YXJnZXQuaXNCZWZvcmVGaXJzdCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UodGFyZ2V0LmFic29sdXRlKDApKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0YXJnZXQuYWJzb2x1dGUoMSkpOworICAgICAgICBhc3NlcnRUcnVlKHRhcmdldC5pc0ZpcnN0KCkpOworICAgICAgICBhc3NlcnRUcnVlKHRhcmdldC5hYnNvbHV0ZSgtMSkpOworICAgICAgICBhc3NlcnRUcnVlKHRhcmdldC5pc0xhc3QoKSk7CisgICAgICAgIHRhcmdldC5uZXh0KCk7CisgICAgICAgIGFzc2VydFRydWUodGFyZ2V0LmlzQWZ0ZXJMYXN0KCkpOworICAgIH0KKworICAgIC8vIHJlcy5jbG9zZSgpIGRvZXMgbm90IHdyYXAgdXAKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWZ0ZXJMYXN0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIHRhcmdldC5hZnRlckxhc3QoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0YXJnZXQuaXNBZnRlckxhc3QoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHRhcmdldC5uZXh0KCkpOworCisgICAgICAgIGVtcHR5VGFyZ2V0LmFmdGVyTGFzdCgpOworICAgICAgICBhc3NlcnRGYWxzZShlbXB0eVRhcmdldC5pc0FmdGVyTGFzdCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGFyZ2V0LmNsb3NlKCk7CisgICAgICAgICAgICB0YXJnZXQuYmVmb3JlRmlyc3QoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCBnZXQgU1FMRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBzdGF0ZW1lbnQuY2xvc2UoKSBkb2VzIG5vdCB3cmFwIHVwCisgICAgcHVibGljIHZvaWQgdGVzdEJlZm9yZUZpcnN0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIHRhcmdldC5iZWZvcmVGaXJzdCgpOworICAgICAgICBhc3NlcnRUcnVlKHRhcmdldC5pc0JlZm9yZUZpcnN0KCkpOworICAgICAgICBhc3NlcnRUcnVlKHRhcmdldC5uZXh0KCkpOworICAgICAgICBhc3NlcnRGYWxzZSh0YXJnZXQuaXNCZWZvcmVGaXJzdCgpKTsKKworICAgICAgICBlbXB0eVRhcmdldC5iZWZvcmVGaXJzdCgpOworICAgICAgICBhc3NlcnRGYWxzZShlbXB0eVRhcmdldC5pc0JlZm9yZUZpcnN0KCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0YXJnZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIHRhcmdldC5iZWZvcmVGaXJzdCgpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIGdldCBTUUxFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFjY29yZGluZyB0byB0aGUgSkRCQyBzcGVjIGNsb3NlIGhhcyB0byAiUmVsZWFzZXMgdGhpcyBSZXN1bHRTZXQKKyAgICAgKiBvYmplY3QncyBkYXRhYmFzZSBhbmQgSkRCQyByZXNvdXJjZXMgaW1tZWRpYXRlbHkiLCBhbmQgdGhpcyBpbXBsaWVzCisgICAgICogdGhlIGZpZWxkcyBzaG91bGQgYmUgcmVsZWFzZWQgYXMgd2VsbCAoc28gdGhhdCBnYXJiYWdlIGNvbGxlY3Rpb24KKyAgICAgKiAgY2FuIHRha2UgcGxhY2UpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENsb3NlMSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRhcmdldC5jbG9zZSgpOworICAgICAgICAgICAgdGFyZ2V0Lm5leHQoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCBnZXQgU1FMRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgZXhjZXB0aW9uIGluIG9uZSBwcmVwYXJlZCBzdGF0ZW1lbnQgZG9lcyBub3QgYWZmZWN0IHNlY29uZAorICAgICAqIHN0YXRlbWVudC4gKEF0b21pY2l0eSBSdWxlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDbG9zZSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwczEgPSBudWxsOworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwczIgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RhdGVtZW50IHMgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgcy5hZGRCYXRjaCgiY3JlYXRlIHRhYmxlIHQxIChhIHRleHQpOyIpOworCisgICAgICAgICAgICBzLmFkZEJhdGNoKCJpbnNlcnQgaW50byB0MSB2YWx1ZXMoJ2FiYycpOyIpOworICAgICAgICAgICAgcy5hZGRCYXRjaCgiaW5zZXJ0IGludG8gdDEgdmFsdWVzKCdkZWYnKTsiKTsKKyAgICAgICAgICAgIHMuYWRkQmF0Y2goImluc2VydCBpbnRvIHQxIHZhbHVlcygnZ2hpJyk7Iik7CisgICAgICAgICAgICBzLmV4ZWN1dGVCYXRjaCgpOworICAgICAgICAgICAgcy5jbG9zZSgpOworCisgICAgICAgICAgICBjb25uLmNvbW1pdCgpOworICAgICAgICAgICAgcHMxID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KCJzZWxlY3QgKiBmcm9tIHQxIik7CisgICAgICAgICAgICBwczIgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQoInNlbGVjdCAqIGZyb20gdDEgd2hlIGEgbGlrZSAnPzAwMCciKTsKKworICAgICAgICAgICAgUmVzdWx0U2V0IHJzMSA9IHBzMS5leGVjdXRlUXVlcnkoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzMiA9IHBzMi5leGVjdXRlUXVlcnkoKTsKKyAgICAgICAgICAgICAgICB3aGlsZSAocnMyLm5leHQoKSl7CisgICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmFpbCgiU2hvdWxkIGdldCBTUUxFeGNlcHRpb24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gb2sgOiBEaXZpc2lvbiBieSB6ZXJvCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIEFsdGhvdWdoIGV4Y2VwdGlvbiBoYXBwZW5lZCBvbiBwczIgcnMxIHNob3VsZCBzdGlsbCB3b3JrCisgICAgICAgICAgICAvLyBJc29sYXRpb24gcHJvcGVydHkgaWYgQUNJRCBydWxlcworCisgICAgICAgICAgICB3aGlsZSAocnMxLm5leHQoKSkgeworICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmc6IHN3aXRjaGluZyBvZiByb3dzIHNob3VsZCBiZSBwb3NzaWJsZQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjb25uLmNvbW1pdCgpOworCisgICAgICAgICAgICByczEuY2xvc2UoKTsKKyAgICAgICAgICAgIHBzMS5jbG9zZSgpOworICAgICAgICAgICAgcHMyLmNsb3NlKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmIChwczEgIT0gbnVsbCkgcHMxLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgaWYgKHBzMiAhPSBudWxsKSBwczIuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBjb25uLnJvbGxiYWNrKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgY2F0Y2ggYmxvY2sKKyAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZpbmRDb2x1bW4oKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHRhcmdldC5maW5kQ29sdW1uKCJpZCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHRhcmdldC5maW5kQ29sdW1uKCJuYW1lIikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0YXJnZXQuZmluZENvbHVtbigiYmxhIik7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgZ2V0IFNRTEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIHN0YXRlbWVudC5jbG9zZSgpIGRvZXMgbm90IHdyYXAgdXAKKyAgICBwdWJsaWMgdm9pZCB0ZXN0dGVzdEZpcnN0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKGVtcHR5VGFyZ2V0LmZpcnN0KCkpOworICAgICAgICBhc3NlcnRUcnVlKHRhcmdldC5maXJzdCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGFyZ2V0LmNsb3NlKCk7CisgICAgICAgICAgICAvLyByZWxlYXNlcyBhbGwgcmVzb3VyY2VzIHN1Y2ggdGhhdCBpdCBjYW4gYmUgZmluYWxpemVkIQorICAgICAgICAgICAgdGFyZ2V0LmZpcnN0KCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgZ2V0IFNRTEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLy8gc3RhdGVtZW50LmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cAorICAgIHB1YmxpYyB2b2lkIHRlc3R0ZXN0SXNBZnRlckxhc3QoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UodGFyZ2V0LmlzQWZ0ZXJMYXN0KCkpOworICAgICAgICB0YXJnZXQuYWJzb2x1dGUoLTEpOyAvLyBsYXN0CisgICAgICAgIHRhcmdldC5uZXh0KCk7CisgICAgICAgIGFzc2VydFRydWUodGFyZ2V0LmlzQWZ0ZXJMYXN0KCkpOworICAgICAgICBhc3NlcnRGYWxzZShlbXB0eVRhcmdldC5pc0FmdGVyTGFzdCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGFyZ2V0LmNsb3NlKCk7CisgICAgICAgICAgICAvLyByZWxlYXNlcyBhbGwgcmVzb3VyY2VzIHN1Y2ggdGhhdCBpdCBjYW4gYmUgZmluYWxpemVkIQorICAgICAgICAgICAgdGFyZ2V0LmlzQWZ0ZXJMYXN0KCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgZ2V0IFNRTEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLy8gSW4gU2Vjb25kIGNvZGUgYmxvY2sgYXNzZXJ0aW9uIGZhaWxzLiBzdGF0ZW1lbnQuY2xvc2UoKSBkb2VzIG5vdCB3cmFwIHVwCisgICAgcHVibGljIHZvaWQgdGVzdHRlc3RJc0JlZm9yZUZpcnN0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUodGFyZ2V0LmlzQmVmb3JlRmlyc3QoKSk7CisgICAgICAgIGFzc2VydFRydWUodGFyZ2V0Lm5leHQoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHRhcmdldC5pc0JlZm9yZUZpcnN0KCkpOworICAgICAgICBhc3NlcnRUcnVlKHRhcmdldC5pc0ZpcnN0KCkpOworICAgICAgICBhc3NlcnRUcnVlKGVtcHR5VGFyZ2V0LmlzQmVmb3JlRmlyc3QoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRhcmdldC5jbG9zZSgpOworICAgICAgICAgICAgLy8gcmVsZWFzZXMgYWxsIHJlc291cmNlcyBzdWNoIHRoYXQgaXQgY2FuIGJlIGZpbmFsaXplZCEKKyAgICAgICAgICAgIHRhcmdldC5pc0JlZm9yZUZpcnN0KCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgZ2V0IFNRTEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgLy8gc3RhdGVtZW50LmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cAorICAgIHB1YmxpYyB2b2lkIHRlc3R0ZXN0SXNGaXJzdCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZSh0YXJnZXQuaXNGaXJzdCgpKTsKKyAgICAgICAgdGFyZ2V0LmZpcnN0KCk7CisgICAgICAgIGFzc2VydFRydWUodGFyZ2V0LmlzRmlyc3QoKSk7CisgICAgICAgIHRhcmdldC5uZXh0KCk7CisgICAgICAgIGFzc2VydEZhbHNlKHRhcmdldC5pc0ZpcnN0KCkpOworCisgICAgICAgIGFzc2VydEZhbHNlKGVtcHR5VGFyZ2V0LmlzRmlyc3QoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRhcmdldC5jbG9zZSgpOworICAgICAgICAgICAgLy8gcmVsZWFzZXMgYWxsIHJlc291cmNlcyBzdWNoIHRoYXQgaXQgY2FuIGJlIGZpbmFsaXplZCEKKyAgICAgICAgICAgIHRhcmdldC5pc0ZpcnN0KCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgZ2V0IFNRTEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2Vjb25kIGJsb2NrIGZpcnN0IGFzc2VydGlvbiBmYWlscy4gSXMgTGFzdCBzaG91bGQgZXZhbHVhdGUgdHJ1ZSBpZiB0aGUKKyAgICAgKiByb3cgb24gd2hpY2ggdGhlIGN1cnNvciBpcyBhY3R1YWxseSBwcm92aWRlcyBhIHJlc3VsdC5zdGF0bWVudC5jbG9zZSgpCisgICAgICogZG9lcyBub3Qgd3JhcCB1cAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3R0ZXN0SXNMYXN0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKHRhcmdldC5pc0xhc3QoKSk7CisgICAgICAgIHRhcmdldC5hYnNvbHV0ZSgtMSk7CisgICAgICAgIGFzc2VydFRydWUodGFyZ2V0LmlzTGFzdCgpKTsKKworICAgICAgICAvL2NoZWNrIGRlZmF1bHQgdmFsdWUgbm8gdmFsaWQgcm93CisgICAgICAgIGFzc2VydEZhbHNlKGVtcHR5VGFyZ2V0LmlzTGFzdCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZW1wdHlUYXJnZXQubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZW1wdHlUYXJnZXQuaXNMYXN0KCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0YXJnZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIHRhcmdldC5pc0xhc3QoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCBnZXQgU1FMRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgLy8gc3RhdGVtZW50LmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cAorICAgIHB1YmxpYyB2b2lkIHRlc3R0ZXN0TGFzdCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZSh0YXJnZXQuaXNMYXN0KCkpOworICAgICAgICB0YXJnZXQubGFzdCgpOworICAgICAgICBhc3NlcnRUcnVlKHRhcmdldC5pc0xhc3QoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRhcmdldC5jbG9zZSgpOworICAgICAgICAgICAgdGFyZ2V0Lmxhc3QoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCBnZXQgU1FMRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU1FMRXhjZXB0aW9uIGNoZWNraW5nIHRlc3QgZmFpbHMuIENsZWFyaW5nIG9mIHdhcm5pbmdzIGFuZCBjbG9zZWQgc3RyZWFtcworICAgICAqIG5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE5leHQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgLy9iZWZvcmUgZmlyc3QgLSBmaXJzdAorICAgICAgICBhc3NlcnRUcnVlKHRhcmdldC5uZXh0KCkpOworICAgICAgICAvL2ZpcnN0IC0gc2Vjb25kCisgICAgICAgIGFzc2VydFRydWUodGFyZ2V0Lm5leHQoKSk7CisgICAgICAgIC8vYWZ0ZXIgbGFzdAorICAgICAgICBhc3NlcnRGYWxzZSh0YXJnZXQubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0YXJnZXQuaXNBZnRlckxhc3QoKSk7CisgICAgICAgIC8vIG9uZSBtb3JlCisgICAgICAgIGFzc2VydEZhbHNlKHRhcmdldC5uZXh0KCkpOworCisgICAgICAgIGFzc2VydEZhbHNlKGVtcHR5VGFyZ2V0Lm5leHQoKSk7CisKKyAgICAgICAgdGFyZ2V0LmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0YXJnZXQubmV4dCgpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJldmlvdXMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgdGFyZ2V0LmZpcnN0KCk7CisgICAgICAgIHRhcmdldC5wcmV2aW91cygpOworICAgICAgICBhc3NlcnRUcnVlKHRhcmdldC5pc0JlZm9yZUZpcnN0KCkpOworCisgICAgICAgIHRhcmdldC5sYXN0KCk7CisgICAgICAgIHRhcmdldC5uZXh0KCk7CisgICAgICAgIHRhcmdldC5wcmV2aW91cygpOworICAgICAgICBhc3NlcnRGYWxzZSh0YXJnZXQuaXNBZnRlckxhc3QoKSk7CisKKyAgICAgICAgdGFyZ2V0LmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0YXJnZXQucHJldmlvdXMoKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgLy8gbm8gZXhjZXB0aW9uIGlzIHRocm93biB3aGVuIG1vdmluZyBjdXJzb3IgYmFja3dhcmRzIG9uIGZvcndhcmQgb25seSBzdGF0ZW1lbnQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVsYXRpdmUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKworICAgICAgICAvLyBmb3J3YXJkIG9ubHkKKyAgICAgICAgaW50IGluaXRpYWxSb3cgPSB0YXJnZXQuZ2V0Um93KCk7CisgICAgICAgIGFzc2VydEZhbHNlKHRhcmdldC5yZWxhdGl2ZSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhpbml0aWFsUm93LCB0YXJnZXQuZ2V0Um93KCkpOworCisgICAgICAgIGFzc2VydFRydWUodGFyZ2V0LnJlbGF0aXZlKDEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0YXJnZXQuaXNGaXJzdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHRhcmdldC5nZXRSb3coKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0YXJnZXQucmVsYXRpdmUoMSkpOworICAgICAgICBhc3NlcnRGYWxzZSh0YXJnZXQuaXNGaXJzdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHRhcmdldC5nZXRSb3coKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHRhcmdldC5yZWxhdGl2ZSgyKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIHNob3VsZCBub3QgYmUgYWJsZSB0byBzY3JvbGwgYmFja3dhcmRzIGluIGZvcndhcmQgb25seSBSUworICAgICAgICAgICAgdGFyZ2V0LnJlbGF0aXZlKC0yKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygyLHRhcmdldC5nZXRSb3coKSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgZ2V0IFNRTEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoZW1wdHlUYXJnZXQucmVsYXRpdmUoSW50ZWdlci5NQVhfVkFMVUUpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShlbXB0eVRhcmdldC5pc0FmdGVyTGFzdCgpKTsKKyAgICB9CisKKyAgICAvLyBTY3JvbGxhYmxlIHJlc3VsdFNldC4gTm90IHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZWxhdGl2ZVNjcm9sbGFibGVSZXN1bHRTZXQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgLy8gc2Nyb2xsYWJsZSByZXN1bHRTZXQKKyAgICAgICAgaW50IGluaXRpYWxSb3cgPSBzY3JvbGxhYmxlVGFyZ2V0LmdldFJvdygpOworICAgICAgICBhc3NlcnRGYWxzZShzY3JvbGxhYmxlVGFyZ2V0LnJlbGF0aXZlKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGluaXRpYWxSb3csIHNjcm9sbGFibGVUYXJnZXQuZ2V0Um93KCkpOworCisgICAgICAgIGFzc2VydFRydWUoc2Nyb2xsYWJsZVRhcmdldC5yZWxhdGl2ZSgxKSk7CisgICAgICAgIGFzc2VydFRydWUoc2Nyb2xsYWJsZVRhcmdldC5pc0ZpcnN0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgc2Nyb2xsYWJsZVRhcmdldC5nZXRSb3coKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShzY3JvbGxhYmxlVGFyZ2V0LnJlbGF0aXZlKDEpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2Nyb2xsYWJsZVRhcmdldC5pc0ZpcnN0KCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygyLCBzY3JvbGxhYmxlVGFyZ2V0LmdldFJvdygpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2Nyb2xsYWJsZVRhcmdldC5yZWxhdGl2ZSgyKSk7CisgICAgICAgIHNjcm9sbGFibGVUYXJnZXQucmVsYXRpdmUoLTIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMixzY3JvbGxhYmxlVGFyZ2V0LmdldFJvdygpKTsKKworICAgICAgICBhc3NlcnRGYWxzZShzY3JvbGxhYmxlVGFyZ2V0LnJlbGF0aXZlKEludGVnZXIuTUlOX1ZBTFVFKSk7CisgICAgICAgIGFzc2VydFRydWUoc2Nyb2xsYWJsZVRhcmdldC5pc0JlZm9yZUZpcnN0KCkpOworCisgICAgICAgIHN0U2Nyb2xsYWJsZS5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2Nyb2xsYWJsZVRhcmdldC5yZWxhdGl2ZSgxKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgLy8gbm90IHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RVcGRhdGVPYmplY3RTdHJpbmdPYmplY3QoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGFibGVUYXJnZXQubmV4dCgpOworICAgICAgICB3cml0YWJsZVRhcmdldC51cGRhdGVPYmplY3QoImZhbWlseSIsImJpcmQiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICB0YXJnZXQubmV4dCgpOworICAgICAgICAgICB0YXJnZXQudXBkYXRlT2JqZWN0KCJmYW1pbHkiLCJiaXJkIik7CisgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIE9ubHkgZXhjZXB0aW9uIHRlc3RpbmcuIE1pc3NpbmcgdGVzdGluZyBmb3Igd3JvbmcgdHlwZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVcGRhdGVTdHJpbmdTdHJpbmdTdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGFibGVUYXJnZXQubmV4dCgpOworICAgICAgICB3cml0YWJsZVRhcmdldC51cGRhdGVTdHJpbmcoImZhbWlseSIsImJpcmQiKTsKKworICAgICAgICAgLy8gbm9uIHdyaXRhYmxlIHRhcmdldC4KKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0YXJnZXQubmV4dCgpOworICAgICAgICAgICAgdGFyZ2V0LnVwZGF0ZVN0cmluZygiZmFtaWx5IiwiYmlyZCIpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICAgfQorCisKKyAgICAgICAgIC8vIHdyaXRhYmxlIGJ1dCB3cm9uZyB0eXBlCisgICAgICAgIHRhcmdldC51cGRhdGVTdHJpbmcoMSwidGVzdCIpOworCisgICAgICAgIHRhcmdldC5jbG9zZSgpOworCisgICAgICAgIC8vIEV4Y2VwdGlvbiB0ZXN0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0YXJnZXQudXBkYXRlU3RyaW5nKCJmYW1pbHkiLCAidGVzdCIpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IG1ldGhvZCBmb3Ige0BsaW5rIGphdmEuc3FsLlJlc3VsdFNldCN3YXNOdWxsKCl9LgorICAgICAqIFNwZWMgc2FpczogaWYgc29tZXRoaW5nIHdhcyByZWFkLi4uIC0+IGlmIG5vdGhpbmcgd2FzIHJlYWQgaXQgc2hvdWxkIGJlIGZhbHNlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFdhc051bGwoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQ2hlY2sgZGVmYXVsdDogc2VsZWN0IHN0YXRlbWVudCBleGVjdXRlZCBidXQgbm8gZ2V0IG9uIHRhcmdldCBjYWxsZWQgeWV0CisgICAgICAgIC8vIEVpdGhlciBmYWxzZSBvciB0aHJvdyBhbiBleGNlcHRpb24uCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSh0YXJnZXQud2FzTnVsbCgpKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorCisgICAgICAgIHN0Rm9yd2FyZC5leGVjdXRlKCJpbnNlcnQgaW50byB6b28gdmFsdWVzKDgsbnVsbCxudWxsKTsiKTsKKyAgICAgICAgc3RGb3J3YXJkLmV4ZWN1dGUoc2VsZWN0QWxsQW5pbWFscyk7CisgICAgICAgIHRhcmdldCA9IHN0Rm9yd2FyZC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0YXJnZXQpOworICAgICAgICBhc3NlcnRUcnVlKHRhcmdldC5sYXN0KCkpOworICAgICAgICBhc3NlcnROdWxsKHRhcmdldC5nZXRPYmplY3QoMikpOworICAgICAgICBhc3NlcnRUcnVlKHRhcmdldC53YXNOdWxsKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRhcmdldC5nZXRPYmplY3QoMSkpOworICAgICAgICBhc3NlcnRGYWxzZSh0YXJnZXQud2FzTnVsbCgpKTsKKworICAgICAgICB0YXJnZXQuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRhcmdldC53YXNOdWxsKCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc3FsL09sZFNRTFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc3FsL09sZFNRTFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi4wYTQ1NDQ3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zcWwvT2xkU1FMVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5zcWw7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5zcWwuQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5Ecml2ZXJNYW5hZ2VyOworaW1wb3J0IGphdmEuc3FsLlJlc3VsdFNldDsKK2ltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247CitpbXBvcnQgamF2YS5zcWwuU3RhdGVtZW50OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGFic3RyYWN0IGNsYXNzIE9sZFNRTFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgc3RhdGljIENvbm5lY3Rpb24gY29ubjsKKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBnZXRTUUxpdGVDb25uZWN0aW9uKCk7CisgICAgICAgIGNyZWF0ZVpvbygpOworICAgIH0KKworICAgIHByb3RlY3RlZCBGaWxlIGRiRmlsZTsKKworICAgIHByb3RlY3RlZCB2b2lkIGdldFNRTGl0ZUNvbm5lY3Rpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHRtcCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKTsKKyAgICAgICAgRmlsZSB0bXBEaXIgPSBuZXcgRmlsZSh0bXApOworICAgICAgICBpZiAodG1wRGlyLmlzRGlyZWN0b3J5KCkpIHsKKyAgICAgICAgICAgIGRiRmlsZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInNxbGl0ZVRlc3QiLCAiLmRiIiwgdG1wRGlyKTsKKyAgICAgICAgICAgIGRiRmlsZS5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiamF2YS5pby50bXBkaXIgZG9lcyBub3QgZXhpc3QiKTsKKyAgICAgICAgfQorCisgICAgICAgIENsYXNzLmZvck5hbWUoIlNRTGl0ZS5KREJDRHJpdmVyIikubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgY29ubiA9IERyaXZlck1hbmFnZXIuZ2V0Q29ubmVjdGlvbigiamRiYzpzcWxpdGU6LyIgKyBkYkZpbGUuZ2V0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ29ubmVjdGlvbiBjcmVhdGVkICIsIGNvbm4pOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKCEgY29ubi5pc0Nsb3NlZCgpKSB7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUoImRyb3AgdGFibGUgaWYgZXhpc3RzIHpvbyIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAoc3QgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICBjb25uLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICAvL2lnbm9yZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY3JlYXRlWm9vKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIHF1ZXJpZXMgPSB7CisgICAgICAgICAgICAgICAgImNyZWF0ZSB0YWJsZSB6b28oaWQgc21hbGxpbnQsICBuYW1lIHZhcmNoYXIoMTApLCBmYW1pbHkgdmFyY2hhcigxMCkpIiwKKyAgICAgICAgICAgICAgICAiaW5zZXJ0IGludG8gem9vIHZhbHVlcyAoMSwgJ0tlc2hhJywgJ3BhcnJvdCcpIiwKKyAgICAgICAgICAgICAgICAiaW5zZXJ0IGludG8gem9vIHZhbHVlcyAoMiwgJ1lhc2hhJywgJ3NwYXJyb3cnKSIgfTsKKworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBxdWVyaWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgc3QuZXhlY3V0ZShxdWVyaWVzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKHN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7fQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRDb3VudChSZXN1bHRTZXQgcnMpIHsKKyAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdoaWxlIChycy5uZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBjb3VudCsrOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93biIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb3VudDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NxbC9PbGRTdGF0ZW1lbnRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NxbC9PbGRTdGF0ZW1lbnRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uMDEzMGUzZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc3FsL09sZFN0YXRlbWVudFRlc3QuamF2YQpAQCAtMCwwICsxLDEzNTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnNxbDsKKworaW1wb3J0IGphdmEuc3FsLkJhdGNoVXBkYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc3FsLlByZXBhcmVkU3RhdGVtZW50OworaW1wb3J0IGphdmEuc3FsLlJlc3VsdFNldDsKK2ltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247CitpbXBvcnQgamF2YS5zcWwuU1FMRmVhdHVyZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5TUUxXYXJuaW5nOworaW1wb3J0IGphdmEuc3FsLlN0YXRlbWVudDsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ2dlcjsKKworcHVibGljIGZpbmFsIGNsYXNzIE9sZFN0YXRlbWVudFRlc3QgZXh0ZW5kcyBPbGRTUUxUZXN0IHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRCYXRjaCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgc3QuYWRkQmF0Y2goIklOU0VSVCBJTlRPIHpvbyBWQUxVRVMgKDMsJ1R1emlrJywnZG9nJykiKTsKKyAgICAgICAgICAgIHN0LmFkZEJhdGNoKCJJTlNFUlQgSU5UTyB6b28gVkFMVUVTICg0LCdNYXNoa2EnLCdjYXQnKSIpOworCisgICAgICAgICAgICBpbnRbXSB1cGRhdGVDb3VudHMgPSBzdC5leGVjdXRlQmF0Y2goKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygyLCB1cGRhdGVDb3VudHMubGVuZ3RoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCB1cGRhdGVDb3VudHNbMF0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHVwZGF0ZUNvdW50c1sxXSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5hZGRCYXRjaCgiIik7CisgICAgICAgICAgICBzdC5leGVjdXRlQmF0Y2goKTsKKyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgc3QuYWRkQmF0Y2gobnVsbCk7CisgICAgICAgICAgICBzdC5leGVjdXRlQmF0Y2goKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDbGVhcldhcm5pbmdzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgYW5pbWFscyBmcm9tIHpvbyIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5jbGVhcldhcm5pbmdzKCk7CisgICAgICAgICAgICBTUUxXYXJuaW5nIHcgPSBzdC5nZXRXYXJuaW5ncygpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCh3KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFdhcm5pbmdzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgaW50IGVycm9yQ29kZTEgPSAtMTsKKyAgICAgICAgaW50IGVycm9yQ29kZTIgPSAtMTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgc3QuZXhlY3V0ZSgic2VsZWN0IGFuaW1hbHMgZnJvbSB6b29vbyIpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgZXJyb3JDb2RlMSA9IGUuZ2V0RXJyb3JDb2RlKCk7CisgICAgICAgIH0KKworICAgICAgICBTUUxXYXJuaW5nIHdycyA9IHN0LmdldFdhcm5pbmdzKCk7CisgICAgICAgIGFzc2VydE51bGwod3JzKTsKKworICAgICAgICAvKgorICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICBpbnQgZXJyb3JDb2RlMSA9IC0xOworICAgICAgICBpbnQgZXJyb3JDb2RlMiA9IC0xOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgYW5pbWFscyBmcm9tIHpvb29vIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgZXJyb3JDb2RlMSA9IGUuZ2V0RXJyb3JDb2RlKCk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNRTFdhcm5pbmcgd3JzID0gc3QuZ2V0V2FybmluZ3MoKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwod3JzKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgRXhjZXB0aW9uOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgaG9yc2UgZnJvbSB6b29vb29vIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgZXJyb3JDb2RlMiA9IGUuZ2V0RXJyb3JDb2RlKCk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1FMV2FybmluZyB3cnMgPSBzdC5nZXRXYXJuaW5ncygpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGVycm9yQ29kZTEsIHdycy5nZXRFcnJvckNvZGUoKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHdycy5nZXROZXh0V2FybmluZygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhlcnJvckNvZGUyLCB3cnMuZ2V0RXJyb3JDb2RlKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBFeGNlcHRpb246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgIH0KKyAgICAgICAgKi8KKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDbGVhckJhdGNoKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmFkZEJhdGNoKCJJTlNFUlQgSU5UTyB6b28gVkFMVUVTICgzLCdUdXppaycsJ2RvZycpOyAiKTsKKyAgICAgICAgICAgIHN0LmFkZEJhdGNoKCJJTlNFUlQgSU5UTyB6b28gVkFMVUVTICg0LCdNYXNoa2EnLCdjYXQnKSIpOworCisgICAgICAgICAgICBzdC5jbGVhckJhdGNoKCk7CisKKyAgICAgICAgICAgIGludFtdIHVwZGF0ZUNvdW50cyA9IHN0LmV4ZWN1dGVCYXRjaCgpOworCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHVwZGF0ZUNvdW50cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCB1cGRhdGVDb3VudHNbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgc3QuYWRkQmF0Y2goIiIpOworICAgICAgICAgICAgc3QuZXhlY3V0ZUJhdGNoKCk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmFkZEJhdGNoKG51bGwpOworICAgICAgICAgICAgc3QuZXhlY3V0ZUJhdGNoKCk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBUT0RPIG5vdCBwYXNzIG9uIFNRTGl0ZSBhbmQgUkkuCisgICAgcHVibGljIHZvaWQgdGVzdEV4ZWN1dGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKworICAgICAgICBTdHJpbmdbXSBxdWVyaWVzID0geworICAgICAgICAgICAgICAgICJ1cGRhdGUgem9vIHNldCBuYW1lPSdNYXNoYScsIGZhbWlseT0nY2F0JyB3aGVyZSBpZD0yOyIsCisgICAgICAgICAgICAgICAgImRyb3AgdGFibGUgaWYgZXhpc3RzIGh1dGNoIiwKKyAgICAgICAgICAgICAgICAiY3JlYXRlIHRhYmxlIGh1dGNoIChpZCBpbnRlZ2VyIG5vdCBudWxsLCBhbmltYWxfaWQgaW50ZWdlciwgYWRkcmVzcyBjaGFyKDIwKSwgcHJpbWFyeSBrZXkgKGlkKSk7IiwKKyAgICAgICAgICAgICAgICAiaW5zZXJ0IGludG8gaHV0Y2ggKGlkLCBhbmltYWxfaWQsIGFkZHJlc3MpIHZhbHVlcyAoMSwgMiwgJ0JpcmRzLWhvdXNlLCAxJyk7IiwKKyAgICAgICAgICAgICAgICAiaW5zZXJ0IGludG8gaHV0Y2ggKGlkLCBhbmltYWxfaWQsIGFkZHJlc3MpIHZhbHVlcyAoMiwgMSwgJ0hvcnNlLWhvdXNlLCA1Jyk7IiwKKyAgICAgICAgICAgICAgICAic2VsZWN0IGFuaW1hbF9pZCwgYWRkcmVzcyBmcm9tIGh1dGNoIHdoZXJlIGFuaW1hbF9pZD0xOyIsCisgICAgICAgICAgICAgICAgImNyZWF0ZSB2aWV3IGFkZHJlc3MgYXMgc2VsZWN0IGFkZHJlc3MgZnJvbSBodXRjaCB3aGVyZSBhbmltYWxfaWQ9MiIsCisgICAgICAgICAgICAgICAgImRyb3AgdmlldyBhZGRyZXNzOyIsICJkcm9wIHRhYmxlIGh1dGNoOyIgfTsKKyAgICAgICAgYm9vbGVhbltdIHJlc3VsdHMgPSB7ZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCB0cnVlLCBmYWxzZSwKKyAgICAgICAgICAgICAgICBmYWxzZSwgZmFsc2V9OworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcXVlcmllcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIGJvb2xlYW4gcmVzID0gc3QuZXhlY3V0ZShxdWVyaWVzW2ldKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImRpZmZlcmVudCByZXN1bHQgZm9yIHN0YXRlbWVudCBuby4gIitpLCByZXN1bHRzW2ldLCByZXMpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgdGhyb3duOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ1tdIGluY19xdWVyaWVzID0geworICAgICAgICAgICAgICAgICJ1cGRhdGUgem9vX3pvbyBzZXQgbmFtZT0nTWFzaGEnLCBmYW1pbHk9J2NhdCcgd2hlcmUgaWQ9NTsiLAorICAgICAgICAgICAgICAgICJkcm9wIHRhYmxlIGh1dGNoTk8iLAorICAgICAgICAgICAgICAgICJpbnNlcnQgaW50byBodXRjaCAoaWQsIGFuaW1hbF9pZCwgYWRkcmVzcykgdmFsdWVzICgxLCAyLCAxMCk7IiwKKyAgICAgICAgICAgICAgICAic2VsZWN0IGFuaW1hbF9pZCwgZnJvbSBodXRjaCB3aGVyZSBhbmltYWxfaWQ9MTsiLAorICAgICAgICAgICAgICAgICJkcm9wIHZpZXcgYWRkcmVzczsiLCAiZHJvcCB0YWJsZSBodXRjaDsiLCAiIiwgbnVsbCB9OworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5jX3F1ZXJpZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKGluY19xdWVyaWVzW2ldKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gaXMgbm90IHRocm93biBmb3IgcXVlcnk6ICIgKyBpbmNfcXVlcmllc1tpXSk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gVE9ETyBub3Qgc3VwcG9ydGVkCisgICBwdWJsaWMgdm9pZCB0ZXN0RXhlY3V0ZV9TdHJpbmdfaW50KCkgeworICAgICAgICBTdHJpbmdbXSBxdWVyaWVzID0geworICAgICAgICAgICAgICAgICJ1cGRhdGUgem9vIHNldCBuYW1lPSdNYXNoYScsIGZhbWlseT0nY2F0JyB3aGVyZSBpZD0yOyIsCisgICAgICAgICAgICAgICAgImRyb3AgdGFibGUgaWYgZXhpc3RzIGh1dGNoIiwKKyAgICAgICAgICAgICAgICAiY3JlYXRlIHRhYmxlIGh1dGNoIChpZCBpbnRlZ2VyIG5vdCBudWxsLCBhbmltYWxfaWQgaW50ZWdlciwgYWRkcmVzcyBjaGFyKDIwKSwgcHJpbWFyeSBrZXkgKGlkKSk7IiwKKyAgICAgICAgICAgICAgICAiaW5zZXJ0IGludG8gaHV0Y2ggKGlkLCBhbmltYWxfaWQsIGFkZHJlc3MpIHZhbHVlcyAoMSwgMiwgJ0JpcmRzLWhvdXNlLCAxJyk7IiwKKyAgICAgICAgICAgICAgICAiaW5zZXJ0IGludG8gaHV0Y2ggKGlkLCBhbmltYWxfaWQsIGFkZHJlc3MpIHZhbHVlcyAoMiwgMSwgJ0hvcnNlLWhvdXNlLCA1Jyk7IiwKKyAgICAgICAgICAgICAgICAic2VsZWN0IGFuaW1hbF9pZCwgYWRkcmVzcyBmcm9tIGh1dGNoIHdoZXJlIGFuaW1hbF9pZD0xOyIsCisgICAgICAgICAgICAgICAgImNyZWF0ZSB2aWV3IGFkZHJlc3MgYXMgc2VsZWN0IGFkZHJlc3MgZnJvbSBodXRjaCB3aGVyZSBhbmltYWxfaWQ9MiIsCisgICAgICAgICAgICAgICAgImRyb3AgdmlldyBhZGRyZXNzOyIsICJkcm9wIHRhYmxlIGh1dGNoOyIgfTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHF1ZXJpZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKHF1ZXJpZXNbaV0sIFN0YXRlbWVudC5OT19HRU5FUkFURURfS0VZUyk7CisKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5nZXRHZW5lcmF0ZWRLZXlzKCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UocnMubmV4dCgpKTsKKworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBvaworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcXVlcmllcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUocXVlcmllc1tpXSwgU3RhdGVtZW50LlJFVFVSTl9HRU5FUkFURURfS0VZUyk7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkOiBOb3Qgc3VwcG9ydGVkIik7CisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5nZXRHZW5lcmF0ZWRLZXlzKCk7CisgICAgICAgICAgICAgICAgZmFpbCgiUmV2aXNlIHRlc3QgaW1wbGVtZW5hdGlvbiBmb3IgZmVhdHVyZSBpbXBsLiBoYXMgY2hhbmdlZCIpOworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKHJzLm5leHQoKSk7CisgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy9vaworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIHN0YXRlbWVudC5jbG9zZSgpIGRvZXMgbm90IHdyYXAgdXAKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q29ubmVjdGlvbigpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgYXNzZXJ0U2FtZShjb25uLCBzdC5nZXRDb25uZWN0aW9uKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIHN0LmdldENvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgLy8gc3RhdGVtZW50LmNsb3NlKCkgZG9lcyBub3Qgd3JhcCB1cAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRGZXRjaERpcmVjdGlvbigpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFJlc3VsdFNldC5GRVRDSF9VTktOT1dOLCBzdC5nZXRGZXRjaERpcmVjdGlvbigpKTsKKyAgICAgICAgfSAgZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5zZXRGZXRjaERpcmVjdGlvbihSZXN1bHRTZXQuRkVUQ0hfRk9SV0FSRCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoUmVzdWx0U2V0LkZFVENIX0ZPUldBUkQsIHN0LmdldEZldGNoRGlyZWN0aW9uKCkpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkOiBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9ICBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LmdldEZldGNoRGlyZWN0aW9uKCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRPRE8gbm90IHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRGZXRjaERpcmVjdGlvbigpIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LnNldEZldGNoRGlyZWN0aW9uKFJlc3VsdFNldC5GRVRDSF9GT1JXQVJEKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGVRdWVyeSgic2VsZWN0ICogZnJvbSB6b287Iik7CisgICAgICAgICAgICBmYWlsKCJSZXZpc2UgdGVzdCBpbXBsZW1lbmF0aW9uIGZvciBmZWF0dXJlIGltcGwuIGhhcyBjaGFuZ2VkIik7CisvLyAgICAgICAgICAgIGFzc2VydEVxdWFscyhSZXN1bHRTZXQuRkVUQ0hfRk9SV0FSRCwgc3QuZ2V0RmV0Y2hEaXJlY3Rpb24oKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisvLyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIHN0YXRlbWVudC5jbG9zZSgpIGRvZXMgbm90IHdyYXAgdXAKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RmV0Y2hTaXplKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlKCJzZWxlY3QgKiBmcm9tIHpvbzsiKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBzdC5nZXRGZXRjaFNpemUoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgc3QuZ2V0RmV0Y2hTaXplKCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRPRE8gbm90IHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRGZXRjaFNpemUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIGludCByb3dzID0gMTAwOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByb3dzOyBpKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdC5zZXRGZXRjaFNpemUoaSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhpLCBzdC5nZXRGZXRjaFNpemUoKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gZ2V0RmV0Y2hTaXplKCkgaGFyZGNvZGVkIHRvIDEuCisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiZmV0Y2ggc2l6ZSBub3QgMSIsIHNxbGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5zZXRGZXRjaFNpemUoLTEpOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgICAgICAqLworCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRPRE8gbm90IHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRNYXhGaWVsZFNpemUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzAwOyBpICs9IDUwKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3Quc2V0TWF4RmllbGRTaXplKGkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaSwgc3QuZ2V0TWF4RmllbGRTaXplKCkpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCJSZXZpc2UgdGVzdCBpbXBsZW1lbmF0aW9uIGZvciBmZWF0dXJlIGltcGwuIGhhcyBjaGFuZ2VkIik7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJub3Qgc3VwcG9ydGVkIiwgc3FsZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gVE9ETyBub3Qgc3VwcG9ydGVkCisgICAgcHVibGljIHZvaWQgdGVzdEdldE1heEZpZWxkU2l6ZSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDIwMDsgaSA8IDUwMDsgaSArPSA1MCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0LnNldE1heEZpZWxkU2l6ZShpKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiUmV2aXNlIHRlc3QgaW1wbGVtZW5hdGlvbiBmb3IgZmVhdHVyZSBpbXBsLiBoYXMgY2hhbmdlZCIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygibm90IHN1cHBvcnRlZCIsIHNxbGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYXhSb3dzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDMwMDsgaSArPSA1MCkgeworICAgICAgICAgICAgICAgIHN0LnNldE1heFJvd3MoaSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGksIHN0LmdldE1heFJvd3MoKSk7CisgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHIgPSBzdC5leGVjdXRlUXVlcnkoInNlbGVjdCAqIGZyb20gem9vOyIpOworICAgICAgICAgICAgICAgIGludCByb3dDb3VudCA9IDA7CisgICAgICAgICAgICAgICAgd2hpbGUgKHIubmV4dCgpKSB7CisgICAgICAgICAgICAgICAgICAgICsrcm93Q291bnQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChpID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gMCBtZWFucyB1bmxpbWl0ZWQuCisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoInJvd0NvdW50PSIgKyByb3dDb3VudCArICIgaT0iICsgaSwgcm93Q291bnQgPiBpKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJyb3dDb3VudD0iICsgcm93Q291bnQgKyAiIGk9IiArIGksIHJvd0NvdW50IDw9IGkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LnNldE1heFJvd3MoLTEpOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpc24ndCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWRzCisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKiBub3QgcGFzc2VkIGFjY29yZGluZyB0byBzcGVjOyBzaG91bGQgcmVsZWFzZSByZXNvdXJjZXMgaW1tZWRpYXRlbHkgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvc2UoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJlcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmdbXSBxdWVyaWVzID0geworICAgICAgICAgICAgICAgICAgICAidXBkYXRlIHpvbyBzZXQgbmFtZT0nTWFzaGEnLCBmYW1pbHk9J2NhdCcgd2hlcmUgaWQ9MjsiLAorICAgICAgICAgICAgICAgICAgICAiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDMsICdWb3JvYmV5JywgJ3NwYXJyb3cnKTsiLAorICAgICAgICAgICAgICAgICAgICAiaW5zZXJ0IGludG8gem9vIChpZCwgbmFtZSwgZmFtaWx5KSB2YWx1ZXMgKDQsICdTbG9uJywgJ2VsZXBoYW50Jyk7IiwKKyAgICAgICAgICAgICAgICAgICAgInNlbGVjdCAqIGZyb20gem9vIn07CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHF1ZXJpZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlKHF1ZXJpZXNbaV0pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHJlcyk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHJlcy5uZXh0KCkpOworICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gdGVzdCByZWxlYXNlIG9mIHJlc291cmNlczoKKyAgICAgICAgLy8gdGhpcyBjb2RlIHNob3VsZCB0aHJvdyBhbiBleGNlcHRpb24gYXMgdGhlIGRiIGlzIG5vdCBhdmFpbGFibGUKKyAgICAgICAgLy8gYW55bW9yZSBpbiBmYWN0IGV2ZXJ5IHJlc291cmNlIHdoaWNoIGlzIHVzZWQgYWZ0ZXJ3YXJkcyBzaG91bGQgdGhyb3cKKyAgICAgICAgLy8gYW4gU1FMRXhjZXB0aW9uLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzLm5leHQoKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRPRE8gbm90IHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RFeGVjdXRlX1N0cmluZ19pbnRBcnJheSgpIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZ1tdIHF1ZXJpZXMgPSB7CisgICAgICAgICAgICAgICAgICAgICJ1cGRhdGUgem9vIHNldCBuYW1lPSdNYXNoYScsIGZhbWlseT0nY2F0JyB3aGVyZSBpZD0yOyIsCisgICAgICAgICAgICAgICAgICAgICJpbnNlcnQgem9vKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoMywgJ1Zvcm9iZXknLCAnc3BhcnJvdycpOyIsCisgICAgICAgICAgICAgICAgICAgICJpbnNlcnQgem9vKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoNCwgJ1Nsb24nLCAnZWxlcGhhbnQnKTsiLAorICAgICAgICAgICAgICAgICAgICAic2VsZWN0ICogZnJvbSB6b28iIH07CisgICAgICAgICAgICBWZWN0b3I8aW50W10+IGFycmF5ID0gbmV3IFZlY3RvcjxpbnRbXT4oKTsKKyAgICAgICAgICAgIGFycmF5LmFkZEVsZW1lbnQobnVsbCk7CisgICAgICAgICAgICBhcnJheS5hZGRFbGVtZW50KG5ldyBpbnRbXSB7IDEsIDIsIDMgfSk7CisgICAgICAgICAgICBhcnJheS5hZGRFbGVtZW50KG5ldyBpbnRbXSB7IDEsIDIsIDEwLCAxMDAgfSk7CisgICAgICAgICAgICBhcnJheS5hZGRFbGVtZW50KG5ldyBpbnRbXSB7fSk7CisKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcXVlcmllcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUocXVlcmllc1tpXSwgKGludFtdKSBhcnJheS5lbGVtZW50QXQoaSkpOworICAgICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBleHBlY3RlZDogbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLyoKKyAgICAgICAgICAgIGZhaWwoIlJldmlzZSB0ZXN0IGltcGxlbWVuYXRpb24gZm9yIGZlYXR1cmUgaW1wbC4gaGFzIGNoYW5nZWQiKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc3QuZ2V0UmVzdWx0U2V0KCkpOworICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoc3QuZ2V0UmVzdWx0U2V0KCkpOworICAgICAgICAgICAgKi8KKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rOiBub3Qgc3VwcG9ydGVkCisvLyAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBpcyB0aHJvd246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFeGVjdXRlX1N0cmluZ19TdHJpbmdBcnJheSgpIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZ1tdIHF1ZXJpZXMgPSB7CisgICAgICAgICAgICAgICAgICAgICJ1cGRhdGUgem9vIHNldCBuYW1lPSdNYXNoYScsIGZhbWlseT0nY2F0JyB3aGVyZSBpZD0yOyIsCisgICAgICAgICAgICAgICAgICAgICJpbnNlcnQgem9vKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoMywgJ1Zvcm9iZXknLCAnc3BhcnJvdycpOyIsCisgICAgICAgICAgICAgICAgICAgICJpbnNlcnQgem9vKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoNCwgJ1Nsb24nLCAnZWxlcGhhbnQnKTsiLAorICAgICAgICAgICAgICAgICAgICAic2VsZWN0ICogZnJvbSB6b28iIH07CisgICAgICAgICAgICBWZWN0b3I8U3RyaW5nW10+IGFycmF5ID0gbmV3IFZlY3RvcjxTdHJpbmdbXT4oKTsKKyAgICAgICAgICAgIGFycmF5LmFkZEVsZW1lbnQobnVsbCk7CisgICAgICAgICAgICBhcnJheS5hZGRFbGVtZW50KG5ldyBTdHJpbmdbXSB7ICIiLCAiIiwgIiIsICIiLCAiIiwgIiIsICIiLCAiIiB9KTsKKyAgICAgICAgICAgIGFycmF5LmFkZEVsZW1lbnQobmV3IFN0cmluZ1tdIHsgImZpZWxkIDEiLCAiIiwgImZpZWxkMiIgfSk7CisgICAgICAgICAgICBhcnJheS5hZGRFbGVtZW50KG5ldyBTdHJpbmdbXSB7ICJpZCIsICJmYW1pbHkiLCAibmFtZSIgfSk7CisKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcXVlcmllcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIHN0LmV4ZWN1dGUocXVlcmllc1tpXSwgKFN0cmluZ1tdKSBhcnJheS5lbGVtZW50QXQoaSkpOworICAgICAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZDogbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmFpbCgiUmV2aXNlIHRlc3QgaW1wbGVtZW5hdGlvbiBmb3IgZmVhdHVyZSBpbXBsLiBoYXMgY2hhbmdlZCIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChzdC5nZXRSZXN1bHRTZXQoKSk7CisgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgYXNzZXJ0TnVsbChzdC5nZXRSZXN1bHRTZXQoKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvazogbm90IHN1cHBvcnRlZAorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBhbHdheXMgcmV0dXJucyAxIGZvciBuby4gb2YgdXBkYXRlcworICAgIHB1YmxpYyB2b2lkIHRlc3RFeGVjdXRlQmF0Y2goKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKworICAgICAgICBTdHJpbmdbXSBxdWVyaWVzID0geworICAgICAgICAgICAgICAgICJ1cGRhdGUgem9vIHNldCBuYW1lPSdNYXNoYScsIGZhbWlseT0nY2F0JyB3aGVyZSBpZD0yOyIsCisgICAgICAgICAgICAgICAgImRyb3AgdGFibGUgaWYgZXhpc3RzIGh1dGNoIiwKKyAgICAgICAgICAgICAgICAiY3JlYXRlIHRhYmxlIGh1dGNoIChpZCBpbnRlZ2VyIG5vdCBudWxsLCBhbmltYWxfaWQgaW50ZWdlciwgYWRkcmVzcyBjaGFyKDIwKSwgcHJpbWFyeSBrZXkgKGlkKSk7IiwKKyAgICAgICAgICAgICAgICAiaW5zZXJ0IGludG8gaHV0Y2ggKGlkLCBhbmltYWxfaWQsIGFkZHJlc3MpIHZhbHVlcyAoMSwgMiwgJ0JpcmRzLWhvdXNlLCAxJyk7IiwKKyAgICAgICAgICAgICAgICAiaW5zZXJ0IGludG8gaHV0Y2ggKGlkLCBhbmltYWxfaWQsIGFkZHJlc3MpIHZhbHVlcyAoMiwgMSwgJ0hvcnNlLWhvdXNlLCA1Jyk7IiwKKyAgICAgICAgICAgICAgICAiY3JlYXRlIHZpZXcgYWRkcmVzcyBhcyBzZWxlY3QgYWRkcmVzcyBmcm9tIGh1dGNoIHdoZXJlIGFuaW1hbF9pZD0yIiwKKyAgICAgICAgICAgICAgICAiZHJvcCB2aWV3IGFkZHJlc3M7IiwgImRyb3AgdGFibGUgaHV0Y2g7IiB9OworCisgICAgICAgIFN0cmluZ1tdIHdyb25nUXVlcmllcyA9IHsKKyAgICAgICAgICAgICAgICAidXBkYXRlIHpvbyBzZXQgbmFtZT0nTWFzaGEnLCBmYW1pbHk9J2NhdCcgd2hlcmU7IiwKKyAgICAgICAgICAgICAgICAiZHJvcCB0YWJsZSBpZiBleGlzdHMgaHV0Y2g7IiwKKyAgICAgICAgICAgICAgICAiY3JlYXRlIHZpZXcgYWRkcmVzcyBhcyBzZWxlY3QgYWRkcmVzcyBmcm9tIGh1dGNoIHdoZXJlIGFuaW1hbF9pZD0yOyIsCisgICAgICAgICAgICAgICAgImRyb3AgdmlldyBhZGRyZXNzOyIsICJkcm9wIHRhYmxlIGh1dGNoOyIgfTsKKworICAgICAgICBpbnRbXSByZXN1bHQgPSB7IDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEgfTsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKworICAgICAgICAvL0V4Y2VwdGlvbiB0ZXN0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgc3QuZXhlY3V0ZUJhdGNoKCkubGVuZ3RoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgd3JvbmdRdWVyaWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgc3QuYWRkQmF0Y2god3JvbmdRdWVyaWVzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHN0LmV4ZWN1dGVCYXRjaCgpOworICAgICAgICAgICAgZmFpbCgiQmF0Y2h1cGRhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQmF0Y2hVcGRhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHN0LmV4ZWN1dGVCYXRjaCgpLmxlbmd0aCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHF1ZXJpZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBzdC5hZGRCYXRjaChxdWVyaWVzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludFtdIHJlc0FycmF5ID0gc3QuZXhlY3V0ZUJhdGNoKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGphdmEudXRpbC5BcnJheXMuZXF1YWxzKHJlc3VsdCwgcmVzQXJyYXkpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmFkZEJhdGNoKCJzZWxlY3QgKiBmcm9tIHpvbyIpOworICAgICAgICAgICAgc3QuZXhlY3V0ZUJhdGNoKCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQmF0Y2hVcGRhdGVFeGNlcHRpb24gYnVlKSB7CisgICAgICAgICAgICAvLyBvayBzZWxlY3QgcmV0dXJucyBhIHJlc3VsdFNldAorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy9FeGNlcHRpb24gdGVzdAorICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGVCYXRjaCgpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIERvZXMgdGhyb3cgYW4gZXhjZXB0aW9uIG9uIG5vbiBzZWxlY3Qgc3RhdGVtZW50LgorICAgIHB1YmxpYyB2b2lkIHRlc3RFeGVjdXRlUXVlcnlfU3RyaW5nKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisKKyAgICAgICAgU3RyaW5nW10gcXVlcmllczEgPSB7ICJzZWxlY3QgKiBmcm9tIHpvbyIsCisgICAgICAgICAgICAgICAgInNlbGVjdCBuYW1lLCBmYW1pbHkgZnJvbSB6b28gd2hlcmUgaWQgPSAxIiB9OworCisgICAgICAgIFN0cmluZ1tdIHF1ZXJpZXMyID0geworICAgICAgICAgICAgICAgICJ1cGRhdGUgem9vIHNldCBuYW1lPSdNYXNoYScsIGZhbWlseT0nY2F0JyB3aGVyZSBpZD0yOyIsCisgICAgICAgICAgICAgICAgImRyb3AgdGFibGUgaWYgZXhpc3RzIGh1dGNoIiwKKyAgICAgICAgICAgICAgICAiY3JlYXRlIHRhYmxlIGh1dGNoIChpZCBpbnRlZ2VyIG5vdCBudWxsLCBhbmltYWxfaWQgaW50ZWdlciwgYWRkcmVzcyBjaGFyKDIwKSwgcHJpbWFyeSBrZXkgKGlkKSk7IiwKKyAgICAgICAgICAgICAgICAiaW5zZXJ0IGludG8gaHV0Y2ggKGlkLCBhbmltYWxfaWQsIGFkZHJlc3MpIHZhbHVlcyAoMSwgMiwgJ0JpcmRzLWhvdXNlLCAxJyk7IiwKKyAgICAgICAgICAgICAgICAiaW5zZXJ0IGludG8gaHV0Y2ggKGlkLCBhbmltYWxfaWQsIGFkZHJlc3MpIHZhbHVlcyAoMiwgMSwgJ0hvcnNlLWhvdXNlLCA1Jyk7IiwKKyAgICAgICAgICAgICAgICAiY3JlYXRlIHZpZXcgYWRkcmVzcyBhcyBzZWxlY3QgYWRkcmVzcyBmcm9tIGh1dGNoIHdoZXJlIGFuaW1hbF9pZD0yIiwKKyAgICAgICAgICAgICAgICAiZHJvcCB2aWV3IGFkZHJlc3M7IiwgImRyb3AgdGFibGUgaHV0Y2g7IiwgInNlbGVjdCBmcm9tIHpvbyIgfTsKKworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHF1ZXJpZXMxLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3QuZXhlY3V0ZVF1ZXJ5KHF1ZXJpZXMxW2ldKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChycyk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIHRocm93biBmb3IgcXVlcnk6ICIgKyBxdWVyaWVzMVtpXSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBxdWVyaWVzIHdoaWNoIGRvIG5vdCBwcm9kdWNlIGEgUmVzdWx0U2V0IC0+IGV4Y2VwdGlvbiB0ZXN0aW5nCisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcXVlcmllczIubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5leGVjdXRlUXVlcnkocXVlcmllczJbaV0pOworICAgICAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHJzKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24gZm9yIHF1ZXJ5OiAiICsgcXVlcmllczJbaV0pOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWxlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTcGVjIGlzIG5vdCBwcmVjaXNlIGVub3VnaDogc2hvdWxkIGJlOiBudW1iZXIgb2Ygcm93cyBhZmZlY3RlZC4gZWcuIHRvIGJlCisgICAgICogY29uc2lzdGVudCBmb3IgZGVsZXRlczogJ2RlbGV0ZSBmcm9tIHMxOycgc2hvdWxkIGJlIGRpZmZlcmVudCBmcm9tCisgICAgICogJ2RlbGV0ZSBmcm9tIHMxIHdoZXJlIGMxID0gMTsnCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEV4ZWN1dGVVcGRhdGVfU3RyaW5nKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisKKyAgICAgICAgU3RyaW5nW10gcXVlcmllczEgPSB7CisgICAgICAgICAgICAgICAgInVwZGF0ZSB6b28gc2V0IG5hbWU9J01hc2hhJywgZmFtaWx5PSdjYXQnIHdoZXJlIGlkPTI7IiwKKyAgICAgICAgICAgICAgICAiZHJvcCB0YWJsZSBpZiBleGlzdHMgaHV0Y2giLAorICAgICAgICAgICAgICAgICJjcmVhdGUgdGFibGUgaHV0Y2ggKGlkIGludGVnZXIgbm90IG51bGwsIGFuaW1hbF9pZCBpbnRlZ2VyLCBhZGRyZXNzIGNoYXIoMjApLCBwcmltYXJ5IGtleSAoaWQpKTsiLAorICAgICAgICAgICAgICAgICJpbnNlcnQgaW50byBodXRjaCAoaWQsIGFuaW1hbF9pZCwgYWRkcmVzcykgdmFsdWVzICgxLCAyLCAnQmlyZHMtaG91c2UsIDEnKTsiLAorICAgICAgICAgICAgICAgICJpbnNlcnQgaW50byBodXRjaCAoaWQsIGFuaW1hbF9pZCwgYWRkcmVzcykgdmFsdWVzICgyLCAxLCAnSG9yc2UtaG91c2UsIDUnKTsiLAorICAgICAgICAgICAgICAgICJjcmVhdGUgdmlldyBhZGRyZXNzIGFzIHNlbGVjdCBhZGRyZXNzIGZyb20gaHV0Y2ggd2hlcmUgYW5pbWFsX2lkPTI7IiwKKyAgICAgICAgICAgICAgICAiZHJvcCB2aWV3IGFkZHJlc3M7IiwgImRyb3AgdGFibGUgaHV0Y2g7In07CisKKyAgICAgICAgU3RyaW5nIHF1ZXJpZXMyID0gInNlbGVjdCAqIGZyb20gem9vOyI7CisKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcXVlcmllczEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpbnQgY291bnQgPSBzdC5leGVjdXRlVXBkYXRlKHF1ZXJpZXMxW2ldKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGNvdW50ID4gMCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBzdC5leGVjdXRlVXBkYXRlKHF1ZXJpZXMyKSk7CisKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gdGVzdCByZXR1cm4gdmFsdWUgZm9yIHNwZWNpZmljIG51bWJlcnMKKworICAgICAgICBTdGF0ZW1lbnQgc3RhdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisKKyAgICAgICAgLy8gdGhlcmUgYXJlIDAgcm93cyBjcmVhdGVkIHRoZXJlZm9yZSAwIHNob3VsZCBiZSByZXR1cm5lZC4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAgLHN0YXQuZXhlY3V0ZVVwZGF0ZSgiY3JlYXRlIHRhYmxlIHMxIChjMSk7IikpOworCisgICAgICAgIGFzc2VydEVxdWFscygxLCBzdGF0LmV4ZWN1dGVVcGRhdGUoImluc2VydCBpbnRvIHMxIHZhbHVlcyAoMCk7IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgc3RhdC5leGVjdXRlVXBkYXRlKCJpbnNlcnQgaW50byBzMSB2YWx1ZXMgKDEpOyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHN0YXQuZXhlY3V0ZVVwZGF0ZSgiaW5zZXJ0IGludG8gczEgdmFsdWVzICgyKTsiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLHN0YXQuZXhlY3V0ZVVwZGF0ZSgiZGVsZXRlIGZyb20gczEgd2hlcmUgYzEgPSAxOyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHN0YXQuZXhlY3V0ZVVwZGF0ZSgidXBkYXRlIHMxIHNldCBjMSA9IDU7IikpOworCisgICAgICAgIC8vIGFuYWxvZ291cyB0byBzdGF0ZW1lbnQgYmVmb3JlLCBkZWxldGUgYWxsIHNob3VsZCByZXR1cm4gMgorICAgICAgICBhc3NlcnRFcXVhbHMoMixzdGF0LmV4ZWN1dGVVcGRhdGUoImRlbGV0ZSBmcm9tIHMxOyIpKTsKKworICAgICAgICAvLyB0aGVyZSBhcmUgbm8gcm93cyBpbiB0YWJsZTogMCBzaG91bGQgYmUgcmV0dXJuZWQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHN0YXQuZXhlY3V0ZVVwZGF0ZSgiZHJvcCB0YWJsZSBzMTsiKSk7CisKKyAgICAgICAgc3RhdC5leGVjdXRlVXBkYXRlKCJjcmVhdGUgdGFibGUgczEgKGMxKTsiKTsKKyAgICAgICAgc3RhdC5leGVjdXRlVXBkYXRlKCJpbnNlcnQgaW50byBzMSB2YWx1ZXMgKDApOyIpOworICAgICAgICBzdGF0LmV4ZWN1dGVVcGRhdGUoImluc2VydCBpbnRvIHMxIHZhbHVlcyAoMSk7Iik7CisgICAgICAgIHN0YXQuZXhlY3V0ZVVwZGF0ZSgiaW5zZXJ0IGludG8gczEgdmFsdWVzICgyKTsiKTsKKworICAgICAgICAvLyB0aGVyZSBhcmUgMyByb3dzIGluIHRhYmxlOiAzIHNob3VsZCBiZSByZXR1cm5lZAorICAgICAgICBhc3NlcnRFcXVhbHMoMywgc3RhdC5leGVjdXRlVXBkYXRlKCJkcm9wIHRhYmxlIHMxOyIpKTsKKworICAgICAgICBzdGF0LmNsb3NlKCk7CisgICAgfQorCisgICAgLy8gVE9ETyBleGVjdXRlVXBkYXRlKFN0cmluZyBzcWwsIGludFtdIGNvbHVtbkluZGV4ZXMpIGlzIG5vdCBzdXBwb3J0ZWQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXhlY3V0ZVVwZGF0ZV9TdHJpbmdfaW50QXJyYXkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZ1tdIHF1ZXJpZXMxID0geworICAgICAgICAgICAgICAgICAgICAidXBkYXRlIHpvbyBzZXQgbmFtZT0nTWFzaGEnLCBmYW1pbHk9J2NhdCcgd2hlcmUgaWQ9MjsiLAorICAgICAgICAgICAgICAgICAgICAiZHJvcCB0YWJsZSBpZiBleGlzdHMgaHV0Y2giLAorICAgICAgICAgICAgICAgICAgICAiY3JlYXRlIHRhYmxlIGh1dGNoIChpZCBpbnRlZ2VyIG5vdCBudWxsLCBhbmltYWxfaWQgaW50ZWdlciwgYWRkcmVzcyBjaGFyKDIwKSwgcHJpbWFyeSBrZXkgKGlkKSk7IiwKKyAgICAgICAgICAgICAgICAgICAgImluc2VydCBpbnRvIGh1dGNoIChpZCwgYW5pbWFsX2lkLCBhZGRyZXNzKSB2YWx1ZXMgKDEsIDIsICdCaXJkcy1ob3VzZSwgMScpOyIsCisgICAgICAgICAgICAgICAgICAgICJpbnNlcnQgaW50byBodXRjaCAoaWQsIGFuaW1hbF9pZCwgYWRkcmVzcykgdmFsdWVzICgyLCAxLCAnSG9yc2UtaG91c2UsIDUnKTsiLAorICAgICAgICAgICAgICAgICAgICAiY3JlYXRlIHZpZXcgYWRkcmVzcyBhcyBzZWxlY3QgYWRkcmVzcyBmcm9tIGh1dGNoIHdoZXJlIGFuaW1hbF9pZD0yIiwKKyAgICAgICAgICAgICAgICAgICAgImRyb3AgdmlldyBhZGRyZXNzOyIsICJkcm9wIHRhYmxlIGh1dGNoOyIgfTsKKworICAgICAgICAgICAgVmVjdG9yPGludFtdPiBhcnJheSA9IG5ldyBWZWN0b3I8aW50W10+KCk7CisgICAgICAgICAgICBhcnJheS5hZGRFbGVtZW50KG51bGwpOworICAgICAgICAgICAgYXJyYXkuYWRkRWxlbWVudChuZXcgaW50W10geyAxLCAyLCAzIH0pOworICAgICAgICAgICAgYXJyYXkuYWRkRWxlbWVudChuZXcgaW50W10geyAxLCAyLCAxMCwgMTAwIH0pOworICAgICAgICAgICAgYXJyYXkuYWRkRWxlbWVudChuZXcgaW50W10ge30pOworICAgICAgICAgICAgYXJyYXkuYWRkRWxlbWVudChuZXcgaW50W10geyAxMDAsIDIwMCB9KTsKKyAgICAgICAgICAgIGFycmF5LmFkZEVsZW1lbnQobmV3IGludFtdIHsgLTEsIDAgfSk7CisgICAgICAgICAgICBhcnJheS5hZGRFbGVtZW50KG5ldyBpbnRbXSB7IDAsIDAsIDAsIDEsIDIsIDMgfSk7CisgICAgICAgICAgICBhcnJheS5hZGRFbGVtZW50KG5ldyBpbnRbXSB7IC0xMDAsIC0yMDAgfSk7CisKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcXVlcmllczEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlVXBkYXRlKHF1ZXJpZXMxW2ldLCAoaW50W10pIGFycmF5LmVsZW1lbnRBdChpKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFNRTEZlYXR1cmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gZXhlY3V0ZVVwZGF0ZShTdHJpbmcgc3FsLCBpbnQgYXV0b0dlbmVyYXRlZEtleXMpIGlzIG5vdCBzdXBwb3J0ZWQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXhlY3V0ZVVwZGF0ZV9TdHJpbmdfaW50KCkgeworICAgICAgICBTdHJpbmdbXSBxdWVyaWVzID0geworICAgICAgICAgICAgICAgICJ1cGRhdGUgem9vIHNldCBuYW1lPSdNYXNoYScsIGZhbWlseT0nY2F0JyB3aGVyZSBpZD0yOyIsCisgICAgICAgICAgICAgICAgImRyb3AgdGFibGUgaWYgZXhpc3RzIGh1dGNoIiwKKyAgICAgICAgICAgICAgICAiY3JlYXRlIHRhYmxlIGh1dGNoIChpZCBpbnRlZ2VyIG5vdCBudWxsLCBhbmltYWxfaWQgaW50ZWdlciwgYWRkcmVzcyBjaGFyKDIwKSwgcHJpbWFyeSBrZXkgKGlkKSk7IiwKKyAgICAgICAgICAgICAgICAiaW5zZXJ0IGludG8gaHV0Y2ggKGlkLCBhbmltYWxfaWQsIGFkZHJlc3MpIHZhbHVlcyAoMSwgMiwgJ0JpcmRzLWhvdXNlLCAxJyk7IiwKKyAgICAgICAgICAgICAgICAiaW5zZXJ0IGludG8gaHV0Y2ggKGlkLCBhbmltYWxfaWQsIGFkZHJlc3MpIHZhbHVlcyAoMiwgMSwgJ0hvcnNlLWhvdXNlLCA1Jyk7IiwKKyAgICAgICAgICAgICAgICAic2VsZWN0IGFuaW1hbF9pZCwgYWRkcmVzcyBmcm9tIGh1dGNoIHdoZXJlIGFuaW1hbF9pZD0xOyIsCisgICAgICAgICAgICAgICAgImNyZWF0ZSB2aWV3IGFkZHJlc3MgYXMgc2VsZWN0IGFkZHJlc3MgZnJvbSBodXRjaCB3aGVyZSBhbmltYWxfaWQ9MiIsCisgICAgICAgICAgICAgICAgImRyb3AgdmlldyBhZGRyZXNzOyIsICJkcm9wIHRhYmxlIGh1dGNoOyIgfTsKKworICAgICAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgICAgIFJlc3VsdFNldCBycyA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICBzdC5leGVjdXRlVXBkYXRlKHF1ZXJpZXNbMV0sIFN0YXRlbWVudC5OT19HRU5FUkFURURfS0VZUyk7CisgICAgICAgICAgICAgICAgcnMgPSBzdC5nZXRHZW5lcmF0ZWRLZXlzKCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UocnMubmV4dCgpKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQ6IG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy9vaworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBycy5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgc3QuZXhlY3V0ZVVwZGF0ZShxdWVyaWVzWzFdLCBTdGF0ZW1lbnQuUkVUVVJOX0dFTkVSQVRFRF9LRVlTKTsKKyAgICAgICAgICAgICAgICBycyA9IHN0LmdldEdlbmVyYXRlZEtleXMoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKHJzLm5leHQoKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkOiBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcnMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgfQorCisgICAgLy8gVE9ETyBleGVjdXRlVXBkYXRlKFN0cmluZyBzcWwsIFN0cmluZ1tdIGNvbHVtbk5hbWVzKSBpcyBub3Qgc3VwcG9ydGVkCisgICAgcHVibGljIHZvaWQgdGVzdEV4ZWN1dGVVcGRhdGVfU3RyaW5nX1N0cmluZ0FycmF5KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmdbXSBxdWVyaWVzID0geworICAgICAgICAgICAgICAgICAgICAidXBkYXRlIHpvbyBzZXQgbmFtZT0nTWFzaGEnLCBmYW1pbHk9J2NhdCcgd2hlcmUgaWQ9MjsiLAorICAgICAgICAgICAgICAgICAgICAiZHJvcCB0YWJsZSBpZiBleGlzdHMgaHV0Y2giLAorICAgICAgICAgICAgICAgICAgICAiY3JlYXRlIHRhYmxlIGh1dGNoIChpZCBpbnRlZ2VyIG5vdCBudWxsLCBhbmltYWxfaWQgaW50ZWdlciwgYWRkcmVzcyBjaGFyKDIwKSwgcHJpbWFyeSBrZXkgKGlkKSk7IiwKKyAgICAgICAgICAgICAgICAgICAgImluc2VydCBpbnRvIGh1dGNoIChpZCwgYW5pbWFsX2lkLCBhZGRyZXNzKSB2YWx1ZXMgKDEsIDIsICdCaXJkcy1ob3VzZSwgMScpOyIsCisgICAgICAgICAgICAgICAgICAgICJpbnNlcnQgaW50byBodXRjaCAoaWQsIGFuaW1hbF9pZCwgYWRkcmVzcykgdmFsdWVzICgyLCAxLCAnSG9yc2UtaG91c2UsIDUnKTsiLAorICAgICAgICAgICAgICAgICAgICAiY3JlYXRlIHZpZXcgYWRkcmVzcyBhcyBzZWxlY3QgYWRkcmVzcyBmcm9tIGh1dGNoIHdoZXJlIGFuaW1hbF9pZD0yIiwKKyAgICAgICAgICAgICAgICAgICAgImRyb3AgdmlldyBhZGRyZXNzOyIsICJkcm9wIHRhYmxlIGh1dGNoOyIgfTsKKworICAgICAgICAgICAgVmVjdG9yPFN0cmluZ1tdPiBhcnJheSA9IG5ldyBWZWN0b3I8U3RyaW5nW10+KCk7CisgICAgICAgICAgICBhcnJheS5hZGRFbGVtZW50KG51bGwpOworICAgICAgICAgICAgYXJyYXkuYWRkRWxlbWVudChuZXcgU3RyaW5nW10geyAiIiwgIiIsICIiLCAiIiwgIiIsICIiLCAiIiwgIiIgfSk7CisgICAgICAgICAgICBhcnJheS5hZGRFbGVtZW50KG5ldyBTdHJpbmdbXSB7ICJmaWVsZCAxIiwgIiIsICJmaWVsZDIiIH0pOworICAgICAgICAgICAgYXJyYXkuYWRkRWxlbWVudChuZXcgU3RyaW5nW10geyAiaWQiLCAiZmFtaWx5IiwgIm5hbWUiIH0pOworICAgICAgICAgICAgYXJyYXkKKyAgICAgICAgICAgICAgICAgICAgLmFkZEVsZW1lbnQobmV3IFN0cmluZ1tdIHsgImlkIiwgbnVsbCwgImZhbWlseSIsIG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5hbWUiIH0pOworICAgICAgICAgICAgYXJyYXkuYWRkRWxlbWVudChuZXcgU3RyaW5nW10geyAiaWQiLCAiICIsICJuYW1lIiB9KTsKKyAgICAgICAgICAgIGFycmF5LmFkZEVsZW1lbnQobmV3IFN0cmluZ1tdIHsgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCB9KTsKKyAgICAgICAgICAgIGFycmF5LmFkZEVsZW1lbnQobmV3IFN0cmluZ1tdIHsgIiAiLCAiMTIzIDIxIiwgIn4hQCMkJV4mKigpXysgIiwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCB9KTsKKworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBxdWVyaWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgc3QuZXhlY3V0ZVVwZGF0ZShxdWVyaWVzW2ldLCAoU3RyaW5nW10pIGFycmF5LmVsZW1lbnRBdChpKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiUmV2aXNlIHRlc3QgaW1wbGVtZW5hdGlvbiBmb3IgZmVhdHVyZSBpbXBsLiBoYXMgY2hhbmdlZCIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChTUUxGZWF0dXJlTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIHN0YXRlbWVudC5jbG9zZSgpIGRvZXMgbm90IHdyYXAgdXAKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VXBkYXRlQ291bnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBxdWVyeSA9ICJ1cGRhdGUgem9vIHNldCBuYW1lPSdNYXNoYScsIGZhbWlseT0nY2F0JyB3aGVyZSBpZD0yOyI7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5leGVjdXRlVXBkYXRlKHF1ZXJ5KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBzdC5nZXRVcGRhdGVDb3VudCgpKTsKKyAgICAgICAgICAgIHF1ZXJ5ID0gInVwZGF0ZSB6b28gc2V0IG5hbWU9J01hc2hhJywgZmFtaWx5PSdjYXQnIHdoZXJlIGlkPTU7IjsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGVVcGRhdGUocXVlcnkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHN0LmdldFVwZGF0ZUNvdW50KCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gc3RhdG1lbnQgY2xvc2VkIDogRXhjZXB0aW9uIHRlc3QKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LmdldFVwZGF0ZUNvdW50KCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmF0ZWRLZXlzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgaW5zZXJ0ID0gImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICg4LCAnVHV6aWsnLCAnZG9nJyk7IjsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoc3QuZ2V0R2VuZXJhdGVkS2V5cygpKTsKKyAgICAgICAgICAgIGZhaWwoIkZhaWw6IHN0YXRlbWVudCBkb2VzIG5vdCBmYWlsIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEZlYXR1cmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRPRE8gc2V0Q3Vyc29yTmFtZSgpIGlzIG5vdCBzdXBwb3J0ZWQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0Q3Vyc29yTmFtZSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHNlbGVjdCA9ICJzZWxlY3QgKiBmcm9tIHpvbyI7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5zZXRDdXJzb3JOYW1lKCJ0ZXN0Iik7CisgICAgICAgICAgICBmYWlsKCJGYWlsOiBzdGF0ZW1lbnQgZG9lcyBub3QgZmFpbCIpOworICAgICAgICB9IGNhdGNoIChTUUxGZWF0dXJlTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBUT0RPIHNldEVzY2FwZVByb2Nlc3NpbmcoKSBpcyBub3Qgc3VwcG9ydGVkCisgICAgcHVibGljIHZvaWQgdGVzdFNldEVzY2FwZVByb2Nlc3NpbmcoKSB7CisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgc2VsZWN0ID0gInNlbGVjdCAqIGZyb20gem9vIjsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LnNldEVzY2FwZVByb2Nlc3NpbmcodHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJGYWlsOiBzdGF0ZW1lbnQgZG9lcyBub3QgZmFpbCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgIGFzc2VydEVxdWFscygibm90IHN1cHBvcnRlZCIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRRdWVyeVRpbWVvdXQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgc3Quc2V0UXVlcnlUaW1lb3V0KDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgc3QuZ2V0UXVlcnlUaW1lb3V0KCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdC5zZXRRdWVyeVRpbWVvdXQoLTEpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICBzdC5zZXRRdWVyeVRpbWVvdXQoMyk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBub3QgZnVsbHkgc3VwcG9ydGVkCisgICAgcHVibGljIHZvaWQgdGVzdEdldFJlc3VsdFNldFR5cGUoKSB7CisgICAgICAgIFN0YXRlbWVudCBzdCA9IG51bGw7CisgICAgICAgIC8vIHRlc3QgZGVmYXVsdCB2YWx1ZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgc3QuZ2V0UmVzdWx0U2V0VHlwZSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFJlc3VsdFNldC5UWVBFX1NDUk9MTF9JTlNFTlNJVElWRSwgc3QKKyAgICAgICAgICAgICAgICAgICAgLmdldFJlc3VsdFNldFR5cGUoKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIm5vdCBzdXBwb3J0ZWQiLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBmYWlsaW5nIHRlc3RzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkUsCisgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5DT05DVVJfVVBEQVRBQkxFKTsKKyAgICAgICAgICAgIHN0LmdldFJlc3VsdFNldFR5cGUoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhSZXN1bHRTZXQuVFlQRV9TQ1JPTExfU0VOU0lUSVZFLCBzdC5nZXRSZXN1bHRTZXRUeXBlKCkpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJub3Qgc3VwcG9ydGVkIiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoUmVzdWx0U2V0LlRZUEVfU0NST0xMX1NFTlNJVElWRSwKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNPTkNVUl9VUERBVEFCTEUpOworICAgICAgICAgICAgc3QuZ2V0UmVzdWx0U2V0VHlwZSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkUsIHN0LmdldFJlc3VsdFNldFR5cGUoKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIm5vdCBzdXBwb3J0ZWQiLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudChSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFksCisgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5DT05DVVJfVVBEQVRBQkxFKTsKKyAgICAgICAgICAgIHN0LmdldFJlc3VsdFNldFR5cGUoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFksIHN0LmdldFJlc3VsdFNldFR5cGUoKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIm5vdCBzdXBwb3J0ZWQiLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBUZXN0IGZvciBkZWZhdWx0IHZhbHVlIGZhaWxzCisgICAgcHVibGljIHZvaWQgdGVzdEdldFJlc3VsdFNldEhvbGRhYmlsaXR5KCkgeworCisgICAgICAgIC8vIHRlc3QgZGVmYXVsdCB2YWx1ZQorICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFJlc3VsdFNldC5DTE9TRV9DVVJTT1JTX0FUX0NPTU1JVCwgc3QKKyAgICAgICAgICAgICAgICAgICAgLmdldFJlc3VsdFNldEhvbGRhYmlsaXR5KCkpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJub3Qgc3VwcG9ydGVkIiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gZmFpbGluZyB0ZXN0cworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5jcmVhdGVTdGF0ZW1lbnQoUmVzdWx0U2V0LlRZUEVfU0NST0xMX1NFTlNJVElWRSwKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNPTkNVUl9SRUFEX09OTFksCisgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5IT0xEX0NVUlNPUlNfT1ZFUl9DT01NSVQpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkOiBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvazogbm90IHN1cHBvcnRlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4uY3JlYXRlU3RhdGVtZW50KFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkUsCisgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5DT05DVVJfUkVBRF9PTkxZLAorICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQuQ0xPU0VfQ1VSU09SU19BVF9DT01NSVQpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkOiBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgc3QuZ2V0UmVzdWx0U2V0SG9sZGFiaWxpdHkoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhSZXN1bHRTZXQuQ0xPU0VfQ1VSU09SU19BVF9DT01NSVQsIHN0CisgICAgICAgICAgICAgICAgICAgIC5nZXRSZXN1bHRTZXRIb2xkYWJpbGl0eSgpKTsKKyAgICAgICAgICAgICovCisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLy8gTm90IHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRSZXN1bHRTZXRDb25jdXJyZW5jeSgpIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKworICAgICAgICAvLyB0ZXN0IGRlZmF1bHQgdmFsdWUKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmdldFJlc3VsdFNldENvbmN1cnJlbmN5KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoUmVzdWx0U2V0LkNPTkNVUl9SRUFEX09OTFksIHN0CisgICAgICAgICAgICAgICAgICAgIC5nZXRSZXN1bHRTZXRDb25jdXJyZW5jeSgpKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygibm90IHN1cHBvcnRlZCIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgIC8vIGZhaWxpbmcgdGVzdHMKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudChSZXN1bHRTZXQuVFlQRV9TQ1JPTExfSU5TRU5TSVRJVkUsCisgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5DT05DVVJfVVBEQVRBQkxFKTsKKyAgICAgICAgICAgIHN0LmdldFJlc3VsdFNldENvbmN1cnJlbmN5KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoUmVzdWx0U2V0LkNPTkNVUl9VUERBVEFCTEUsIHN0LmdldFJlc3VsdFNldENvbmN1cnJlbmN5KCkpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkOiBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KFJlc3VsdFNldC5UWVBFX1NDUk9MTF9JTlNFTlNJVElWRSwKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNPTkNVUl9SRUFEX09OTFkpOworICAgICAgICAgICAgc3QuZ2V0UmVzdWx0U2V0Q29uY3VycmVuY3koKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhSZXN1bHRTZXQuQ09OQ1VSX1JFQURfT05MWSwgc3QuZ2V0UmVzdWx0U2V0Q29uY3VycmVuY3koKSk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQ6IG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2s7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBEb2VzIG5vdCByZXR1cm4gbnVsbCBvbiB1cGRhdGUgY291bnQgPiAwIChub3QgYSBzZWxlY3Qgc3RhdGVtZW50KQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRSZXN1bHRTZXQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHJlcyA9IG51bGw7CisKKyAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudChSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFksCisgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNPTkNVUl9SRUFEX09OTFksCisgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNMT1NFX0NVUlNPUlNfQVRfQ09NTUlUKTsKKyAgICAgICAgc3QuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRlc3QgKGMxKTsiKTsKKyAgICAgICAgcmVzID0gc3QuZ2V0UmVzdWx0U2V0KCk7CisgICAgICAgIGFzc2VydE51bGwocmVzKTsKKworICAgICAgICBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgIFN0cmluZyBzZWxlY3QgPSAic2VsZWN0ICogZnJvbSB6b28gd2hlcmUgaWQgPT0gNDsiOworICAgICAgICBTdHJpbmcgaW5zZXJ0ID0gICJpbnNlcnQgaW50byB6b28gKGlkLCBuYW1lLCBmYW1pbHkpIHZhbHVlcyAoNCwgJ1Zvcm9idXknLCAnYmVhcicpOyI7CisgICAgICAgIHN0LmV4ZWN1dGUoaW5zZXJ0KTsKKyAgICAgICAgc3QuZXhlY3V0ZShzZWxlY3QpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIHN0LmdldFVwZGF0ZUNvdW50KCkpOworICAgICAgICByZXMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChyZXMpOworICAgICAgICByZXMubmV4dCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCxyZXMuZ2V0SW50KDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJWb3JvYnV5IixyZXMuZ2V0U3RyaW5nKDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiZWFyIixyZXMuZ2V0U3RyaW5nKDMpKTsKKy8vICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHN0LmdldFVwZGF0ZUNvdW50KCkpOyBub3Qgc3VwcG9ydGVkCisgICAgICAgIGFzc2VydEZhbHNlKHJlcy5uZXh0KCkpOworCisgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgaW5zZXJ0ID0gImluc2VydCBpbnRvIHpvbyAoaWQsIG5hbWUsIGZhbWlseSkgdmFsdWVzICgzLCAnVm9yb2JleScsICdzcGFycm93Jyk7IjsKKyAgICAgICAgc3QuZXhlY3V0ZShpbnNlcnQpOworICAgICAgICByZXMgPSBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgLy8gc3RhdGVtZW50IGlzIGFuIHVwZGF0ZSBhbmQgc2hvdWxkIHJldHVybiBudWxsIGFjY29yZGluZyB0byBzcGVjLgorICAgICAgICBpZiAoc3QuZ2V0VXBkYXRlQ291bnQoKSA+IDApICB7CisgICAgICAgICAgICBhc3NlcnROdWxsKHJlcyk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIHN0LmdldFJlc3VsdFNldCgpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBBbiBvdGhlciB2YWx1ZSBpcyByZXR1cm5lZCB0aGFuIHdhcyBzZXQgKFggKiAxMDAwKQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRRdWVyeVRpbWVvdXQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICBzdC5zZXRRdWVyeVRpbWVvdXQoMjAwMCk7CisgICAgICAgIGFzc2VydEVxdWFscygyMDAwLCBzdC5nZXRRdWVyeVRpbWVvdXQoKSk7CisKKyAgICAgICAgc3QgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCxzdC5nZXRRdWVyeVRpbWVvdXQoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICBzdC5nZXRRdWVyeVRpbWVvdXQoKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgLy8gbm90IHN1cHBvcnRlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRNb3JlUmVzdWx0cygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdGF0ZW1lbnQgc3QgPSBudWxsOworICAgICAgICBSZXN1bHRTZXQgcmVzMSA9IG51bGw7CisgICAgICAgIFJlc3VsdFNldCByZXMyID0gbnVsbDsKKyAgICAgICAgU3RyaW5nW10gcXVlcmllcyA9IHsKKyAgICAgICAgICAgICAgICAiaW5zZXJ0IGludG8gem9vIHZhbHVlcyAoMywnSm9obicsJ2JpcmQnKTsiLAorICAgICAgICAgICAgICAgICJ1cGRhdGUgem9vIHNldCBuYW1lPSdNYXNoYScsIGZhbWlseT0nY2F0JyB3aGVyZSBpZD0zOyIsCisgICAgICAgICAgICAgICAgInVwZGF0ZSB6b28gc2V0IG5hbWU9J01hc2hhJywgZmFtaWx5PSdiZWFyJyB3aGVyZSBpZD0zOyJ9OworCisgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0LmV4ZWN1dGUocXVlcmllc1swXSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShzdC5nZXRNb3JlUmVzdWx0cygpKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5nZXRSZXN1bHRTZXQoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy9vaworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QuZ2V0TW9yZVJlc3VsdHMoKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgLy8gQnVnIGluIGltcGxlbWVudGF0aW9uIG9mIGNhbmNlbDogRG9lcyBub3QgZnVsZmlsbCBzcGVjLgorICAgIHB1YmxpYyB2b2lkIHRlc3RDYW5jZWwoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0ID0gbnVsbDsKKyAgICAgICAgc3QgPSBjb25uLnByZXBhcmVTdGF0ZW1lbnQoImluc2VydCBpbnRvIHpvbyB2YWx1ZXMgKDcsJ1NwZWVkeSBHb256YWxlcycsJ01vdXNlJyk7Iik7CisKKyAgICAgICAgQ2FuY2VsVGhyZWFkIGMgPSBuZXcgQ2FuY2VsVGhyZWFkKHN0KTsKKyAgICAgICAgSW5zZXJ0VGhyZWFkIGlucyA9IG5ldyBJbnNlcnRUaHJlYWQoKFByZXBhcmVkU3RhdGVtZW50KXN0KTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zLnQuam9pbigpOworICAgICAgICAgICAgYy50LmpvaW4oKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXJyb3IgaW4gdGVzdCBzZXR1cDogIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKXsKKyAgICAgICAgICAgIC8vIEluc2VydCB0aHJlYWQgbWF5IHRocm93IGFuIGV4Y2VwdGlvbgorICAgICAgICAgICAgLy8gdGhhdCBpdCBjb3VsZCBub3QgY29tcGxldGUgc3RhdGVtZW50CisgICAgICAgIH0KKworICAgICAgICAvLyBib3RoIHRocmVhZHMgaGF2ZSB0ZXJtaW5hdGVkIGFuZCBjYW5jZWwgc2hvdWxkIGhhdmUgY2FuY2VsbGVkIHRoZSBpbnNlcnQgc3RhdGVtZW50LgorICAgICAgICBSZXN1bHRTZXQgcmVzID0gc3QuZXhlY3V0ZVF1ZXJ5KCJzZWxlY3QgKiBmcm9tIHpvbyB3aGVyZSBpZD03Iik7CisgICAgICAgIGFzc2VydEZhbHNlKHJlcy5uZXh0KCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgc3QuY2FuY2VsKCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIENhbmNlbFRocmVhZCBpbXBsZW1lbnRzIFJ1bm5hYmxleworICAgICAgICBUaHJlYWQgdDsKKyAgICAgICAgU3RhdGVtZW50IHN0bXQ7CisgICAgICAgIENhbmNlbFRocmVhZCAoU3RhdGVtZW50IGFTdCkgeworICAgICAgICAgICB0aGlzLnN0bXQgPSBhU3Q7CisgICAgICAgICAgIHQgPSBuZXcgVGhyZWFkKHRoaXMsIkNhbmNlbCB0aHJlYWQiKTsKKyAgICAgICAgICAgdC5zdGFydCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgTG9nZ2VyLmdsb2JhbC5pbmZvKCIqQ2FuY2VsKiB0aHJlYWQgc3RhcnRlZCIpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTUwMCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlMSkgeworICAgICAgICAgICAgICAgIGZhaWwoIkVycm9yIGluIHRlc3Qgc2V0dXAiKTsKKyAgICAgICAgICAgICAgICBlMS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTG9nZ2VyLmdsb2JhbC5pbmZvKCIqQ2FuY2VsKiB0aHJlYWQsIGFib3V0IHRvIGRvIHN0bXQuY2FuY2VsKCkiKTsKKyAgICAgICAgICAgICAgICBzdG10LmNhbmNlbCgpOworICAgICAgICAgICAgICAgIExvZ2dlci5nbG9iYWwuaW5mbygiKkNhbmNlbCogdGhyZWFkLCBzdG10LmNhbmNlbCgpIGRvbmUiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiRXJyb3IgaW4gdGVzdCBzZXR1cCIpOworICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBMb2dnZXIuZ2xvYmFsLmluZm8oIipDYW5jZWwqIHRocmVhZCB0ZXJtaW5hdGVkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBJbnNlcnRUaHJlYWQgaW1wbGVtZW50cyBSdW5uYWJsZXsKKyAgICAgICAgVGhyZWFkIHQ7CisgICAgICAgIFByZXBhcmVkU3RhdGVtZW50IHN0bXQ7CisgICAgICAgIEluc2VydFRocmVhZCAoUHJlcGFyZWRTdGF0ZW1lbnQgYVN0KSB7CisgICAgICAgICAgIHRoaXMuc3RtdCA9IGFTdDsKKyAgICAgICAgICAgdCA9IG5ldyBUaHJlYWQodGhpcywiSW5zZXJ0IHRocmVhZCIpOworICAgICAgICAgICB0LnN0YXJ0KCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICBMb2dnZXIuZ2xvYmFsLmluZm8oIipJbnNlcnQqIHRocmVhZCBzdGFydGVkIik7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxNTAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUxKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiRXJyb3IgaW4gdGVzdCBzZXR1cCIpOworICAgICAgICAgICAgICAgIGUxLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBMb2dnZXIuZ2xvYmFsLmluZm8oIipJbnNlcnQqIHRocmVhZCwgYWJvdXQgdG8gZG8gaW5zZXJ0aW9uIik7CisgICAgICAgICAgICAgICAgc3RtdC5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgc3RtdC5leGVjdXRlKCk7CisgICAgICAgICAgICAgICAgTG9nZ2VyLmdsb2JhbC5pbmZvKCIqSW5zZXJ0KiB0aHJlYWQgaW5zZXJ0ZWQiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiRXJyb3IgaW4gdGVzdCBzZXR1cCIpOworICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBMb2dnZXIuZ2xvYmFsLmluZm8oIipJbnNlcnQqIHRocmVhZCB0ZXJtaW5hdGVkIik7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NxbC9PbGRUaW1lc3RhbXBUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NxbC9PbGRUaW1lc3RhbXBUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWIyMDM0YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc3FsL09sZFRpbWVzdGFtcFRlc3QuamF2YQpAQCAtMCwwICsxLDQxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuc3FsOworCitpbXBvcnQgamF2YS5zcWwuVGltZXN0YW1wOworaW1wb3J0IGphdmEudXRpbC5UaW1lWm9uZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBPbGRUaW1lc3RhbXBUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF90b1N0cmluZygpIHsKKyAgICAgICAgVGltZVpvbmUuc2V0RGVmYXVsdChUaW1lWm9uZS5nZXRUaW1lWm9uZSgiVVRDIikpOworCisgICAgICAgIFRpbWVzdGFtcCB0MSA9IG5ldyBUaW1lc3RhbXAoTG9uZy5NSU5fVkFMVUUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjI5MjI3ODk5NC0wOC0xNyAwNzoxMjo1NS4xOTIiLCB0MS50b1N0cmluZygpKTsKKworICAgICAgICBUaW1lc3RhbXAgdDIgPSBuZXcgVGltZXN0YW1wKExvbmcuTUlOX1ZBTFVFICsgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMjkyMjc4OTk0LTA4LTE3IDA3OjEyOjU1LjE5MyIsIHQyLnRvU3RyaW5nKCkpOworCisgICAgICAgIFRpbWVzdGFtcCB0MyA9IG5ldyBUaW1lc3RhbXAoTG9uZy5NSU5fVkFMVUUgKyA4MDcpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjI5MjI3ODk5NC0wOC0xNyAwNzoxMjo1NS45OTkiLCB0My50b1N0cmluZygpKTsKKworICAgICAgICBUaW1lc3RhbXAgdDQgPSBuZXcgVGltZXN0YW1wKExvbmcuTUlOX1ZBTFVFICsgODA4KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIyOTIyNjkwNTUtMTItMDIgMTY6NDc6MDUuMCIsIHQ0LnRvU3RyaW5nKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9BdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JBdHRyaWJ1dGVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjYTAwZjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS50ZXh0OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnZhbGlkT2JqZWN0RXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS50ZXh0LkF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnRleHQuRGF0ZUZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuTnVtYmVyRm9ybWF0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCB0ZXN0cy51dGlsLlNlcmlhbGl6YXRpb25UZXN0ZXI7CisKKy8qKgorICogQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSBpcyB1c2VkIGxpa2UgdGhlIGJhc2UgZW51bSB0eXBlIGFuZAorICogc3ViY2xhc3NlZCBieSB1bnJlbGF0ZWQgY2xhc3Nlcy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXphdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFNhbWVSZXNlcmlhbGl6ZWQoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5MQU5HVUFHRSk7CisgICAgICAgIGFzc2VydFNhbWVSZXNlcmlhbGl6ZWQoRGF0ZUZvcm1hdC5GaWVsZC5FUkEpOworICAgICAgICBhc3NlcnRTYW1lUmVzZXJpYWxpemVkKERhdGVGb3JtYXQuRmllbGQuVElNRV9aT05FKTsKKyAgICAgICAgYXNzZXJ0U2FtZVJlc2VyaWFsaXplZChOdW1iZXJGb3JtYXQuRmllbGQuSU5URUdFUik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6aW5nU3ViY2xhc3MoKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlIGEgPSBuZXcgQ3VzdG9tQXR0cmlidXRlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTZXJpYWxpemF0aW9uVGVzdGVyLmdldERlc2VyaWFsaXplZE9iamVjdChhKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZE9iamVjdEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydFNhbWVSZXNlcmlhbGl6ZWQoT2JqZWN0IG8pIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFNhbWUobywgU2VyaWFsaXphdGlvblRlc3Rlci5nZXREZXNlcmlhbGl6ZWRPYmplY3QobykpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEN1c3RvbUF0dHJpYnV0ZSBleHRlbmRzIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUgeworICAgICAgICBwdWJsaWMgQ3VzdG9tQXR0cmlidXRlKCkgeworICAgICAgICAgICAgc3VwZXIoImEiKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9CcmVha0l0ZXJhdG9yVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L0JyZWFrSXRlcmF0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDVkMzFiNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9CcmVha0l0ZXJhdG9yVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTY2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudGV4dDsKKworaW1wb3J0IGphdmEudGV4dC5CcmVha0l0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CisKK3B1YmxpYyBjbGFzcyBCcmVha0l0ZXJhdG9yVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgQnJlYWtJdGVyYXRvciBpdGVyYXRvcjsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIGl0ZXJhdG9yID0gQnJlYWtJdGVyYXRvci5nZXRDaGFyYWN0ZXJJbnN0YW5jZShMb2NhbGUuVVMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRBdmFpbGFibGVMb2NhbGVzKCkgeworICAgICAgICBMb2NhbGVbXSBsb2NhbGVzID0gQnJlYWtJdGVyYXRvci5nZXRBdmFpbGFibGVMb2NhbGVzKCk7CisgICAgICAgIGFzc2VydFRydWUoIkFycmF5IGF2YWlsYWJsZSBsb2NhbGVzIGlzIG51bGwiLCBsb2NhbGVzICE9IG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJBcnJheSBhdmFpbGFibGUgbG9jYWxlcyBpcyAwLWxlbmd0aCIsCisgICAgICAgICAgICAgICAgKGxvY2FsZXMgIT0gbnVsbCAmJiBsb2NhbGVzLmxlbmd0aCAhPSAwKSk7CisgICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChMb2NhbGUgbCA6IGxvY2FsZXMpIHsKKyAgICAgICAgICAgIGlmIChsLmVxdWFscyhMb2NhbGUuVVMpKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQXQgbGVhc3QgbG9jYWxlICIgKyBMb2NhbGUuVVMgKyAiIG11c3QgYmUgcHJlc2VudGVkIiwgZm91bmQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRXb3JkSW5zdGFuY2VMb2NhbGUoKSB7CisgICAgICAgIEJyZWFrSXRlcmF0b3IgaXQxID0gQnJlYWtJdGVyYXRvci5nZXRXb3JkSW5zdGFuY2UoTG9jYWxlLkNBTkFEQV9GUkVOQ0gpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgQnJlYWtJdGVyYXRvciIsIGl0MSAhPSBCcmVha0l0ZXJhdG9yLmdldFdvcmRJbnN0YW5jZSgpKTsKKyAgICAgICAgQnJlYWtJdGVyYXRvciBpdDIgPSBCcmVha0l0ZXJhdG9yLmdldFdvcmRJbnN0YW5jZShuZXcgTG9jYWxlKCJiYWQgbG9jYWxlIikpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgQnJlYWtJdGVyYXRvciIsIGl0MiAhPSBCcmVha0l0ZXJhdG9yLmdldFdvcmRJbnN0YW5jZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V29yZEJvdW5kYXJpZXMoKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMjQ7ICsraSkgeworICAgICAgICAgICAgaWYgKGkgPiAwKSB7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCcgJyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzYi5hcHBlbmQoIjEyMzQ1Iik7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHMgPSBzYi50b1N0cmluZygpOworCisgICAgICAgIEJyZWFrSXRlcmF0b3IgaXQgPSBCcmVha0l0ZXJhdG9yLmdldFdvcmRJbnN0YW5jZShMb2NhbGUuVVMpOworICAgICAgICBpdC5zZXRUZXh0KHMpOworCisgICAgICAgIC8vIENoZWNrIHdlJ3JlIG5vdCBsZWFraW5nIGdsb2JhbCByZWZlcmVuY2VzLiAyMDQ4IHdvdWxkIGJ1c3QgdGhlIFZNJ3MgaGFyZC1jb2RlZCBsaW1pdC4KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDQ4OyArK2kpIHsKKyAgICAgICAgICAgIGl0LnNldFRleHQocyk7CisgICAgICAgIH0KKworICAgICAgICBCcmVha0l0ZXJhdG9yIGNsb25lID0gKEJyZWFrSXRlcmF0b3IpIGl0LmNsb25lKCk7CisKKyAgICAgICAgYXNzZXJ0RXhwZWN0ZWRXb3JkQm91bmRhcmllcyhpdCwgcyk7CisgICAgICAgIGFzc2VydEV4cGVjdGVkV29yZEJvdW5kYXJpZXMoY2xvbmUsIHMpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRFeHBlY3RlZFdvcmRCb3VuZGFyaWVzKEJyZWFrSXRlcmF0b3IgaXQsIFN0cmluZyBzKSB7CisgICAgICAgIGludCBleHBlY3RlZFBvcyA9IDA7CisgICAgICAgIGludCBwb3MgPSBpdC5maXJzdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRQb3MsIHBvcyk7CisgICAgICAgIHdoaWxlIChwb3MgIT0gQnJlYWtJdGVyYXRvci5ET05FKSB7CisgICAgICAgICAgICBleHBlY3RlZFBvcyArPSA1OyAvLyBUaGUgZml2ZSBjaGFyYWN0ZXJzIHVudGlsIHRoZSBlbmQgb2YgdGhpcyB3b3JkLgorICAgICAgICAgICAgcG9zID0gaXQubmV4dCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkUG9zLCBwb3MpOworCisgICAgICAgICAgICBleHBlY3RlZFBvcyArPSAxOyAvLyBUaGUgc3BhY2UgYmVmb3JlIHRoZSBzdGFydCBvZiB0aGUgbmV4dCB3b3JkLi4uCisgICAgICAgICAgICBpZiAoZXhwZWN0ZWRQb3MgPiBzLmxlbmd0aCgpKSB7CisgICAgICAgICAgICAgICAgZXhwZWN0ZWRQb3MgPSBCcmVha0l0ZXJhdG9yLkRPTkU7IC8vIC4uLnVubGVzcyB3ZSdyZSBkb25lLgorICAgICAgICAgICAgfQorICAgICAgICAgICAgcG9zID0gaXQubmV4dCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkUG9zLCBwb3MpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdElzQm91bmRhcnkoKSB7CisgICAgICAgIEJyZWFrSXRlcmF0b3IgaXQgPSBCcmVha0l0ZXJhdG9yLmdldENoYXJhY3Rlckluc3RhbmNlKExvY2FsZS5VUyk7CisgICAgICAgIGl0LnNldFRleHQoImhlbGxvIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGl0LmlzQm91bmRhcnkoLTEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIC8vIE5vdGUgdGhhdCB0aGlzIGV4Y2VwdGlvbiBpcyBub3QgbGlzdGVkIGluIHRoZSBKYXZhIEFQSSBkb2N1bWVudGF0aW9uCisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRUcnVlKGl0LmlzQm91bmRhcnkoMCkpOworICAgICAgICBhc3NlcnRUcnVlKGl0LmlzQm91bmRhcnkoMSkpOworICAgICAgICBhc3NlcnRUcnVlKGl0LmlzQm91bmRhcnkoNCkpOworICAgICAgICBhc3NlcnRUcnVlKGl0LmlzQm91bmRhcnkoNSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpdC5pc0JvdW5kYXJ5KDYpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIC8vIE5vdGUgdGhhdCB0aGlzIGV4Y2VwdGlvbiBpcyBub3QgbGlzdGVkIGluIHRoZSBKYXZhIEFQSSBkb2N1bWVudGF0aW9uCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9sbG93aW5nKCkgeworICAgICAgICBCcmVha0l0ZXJhdG9yIGl0ID0gQnJlYWtJdGVyYXRvci5nZXRDaGFyYWN0ZXJJbnN0YW5jZShMb2NhbGUuVVMpOworICAgICAgICBpdC5zZXRUZXh0KCJoZWxsbyIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpdC5mb2xsb3dpbmcoLTEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkIGV4Y2VwdGlvbgorICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGl0LmZvbGxvd2luZygwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBpdC5mb2xsb3dpbmcoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgaXQuZm9sbG93aW5nKDQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJyZWFrSXRlcmF0b3IuRE9ORSwgaXQuZm9sbG93aW5nKDUpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXQuZm9sbG93aW5nKDYpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkIGV4Y2VwdGlvbgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFByZWNlZGluZygpIHsKKyAgICAgICAgQnJlYWtJdGVyYXRvciBpdCA9IEJyZWFrSXRlcmF0b3IuZ2V0Q2hhcmFjdGVySW5zdGFuY2UoTG9jYWxlLlVTKTsKKyAgICAgICAgaXQuc2V0VGV4dCgiaGVsbG8iKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXQucHJlY2VkaW5nKC0xKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZCBleGNlcHRpb24KKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscyhCcmVha0l0ZXJhdG9yLkRPTkUsIGl0LnByZWNlZGluZygwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBpdC5wcmVjZWRpbmcoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgaXQucHJlY2VkaW5nKDUpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXQucHJlY2VkaW5nKDYpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkIGV4Y2VwdGlvbgorICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvQ29sbGF0b3JUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvQ29sbGF0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGM3MThjOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9Db2xsYXRvclRlc3QuamF2YQpAQCAtMCwwICsxLDE0OCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLnRleHQuQ2hhcmFjdGVySXRlcmF0b3I7CitpbXBvcnQgamF2YS50ZXh0LkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnRleHQuQ29sbGF0b3I7CitpbXBvcnQgamF2YS50ZXh0LlBhcnNlRXhjZXB0aW9uOworaW1wb3J0IGphdmEudGV4dC5SdWxlQmFzZWRDb2xsYXRvcjsKK2ltcG9ydCBqYXZhLnRleHQuU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworcHVibGljIGNsYXNzIENvbGxhdG9yVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRTdHJlbmd0aEkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ29sbGF0b3IgY29sbGF0b3IgPSBDb2xsYXRvci5nZXRJbnN0YW5jZSgpOworICAgICAgICBjb2xsYXRvci5zZXRTdHJlbmd0aChDb2xsYXRvci5QUklNQVJZKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENvbGxhdG9yLlBSSU1BUlksIGNvbGxhdG9yLmdldFN0cmVuZ3RoKCkpOworICAgICAgICBjb2xsYXRvci5zZXRTdHJlbmd0aChDb2xsYXRvci5TRUNPTkRBUlkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29sbGF0b3IuU0VDT05EQVJZLCBjb2xsYXRvci5nZXRTdHJlbmd0aCgpKTsKKyAgICAgICAgY29sbGF0b3Iuc2V0U3RyZW5ndGgoQ29sbGF0b3IuVEVSVElBUlkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29sbGF0b3IuVEVSVElBUlksIGNvbGxhdG9yLmdldFN0cmVuZ3RoKCkpOworICAgICAgICBjb2xsYXRvci5zZXRTdHJlbmd0aChDb2xsYXRvci5JREVOVElDQUwpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29sbGF0b3IuSURFTlRJQ0FMLCBjb2xsYXRvci5nZXRTdHJlbmd0aCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbGxhdG9yLnNldFN0cmVuZ3RoKC0xKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N0YWNrQ29ycnVwdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUaGlzIHVzZWQgdG8gY3Jhc2ggQW5kcm9pZC4KKyAgICAgICAgQ29sbGF0b3IgbUNvbGwgPSBDb2xsYXRvci5nZXRJbnN0YW5jZSgpOworICAgICAgICBtQ29sbC5zZXRTdHJlbmd0aChDb2xsYXRvci5QUklNQVJZKTsKKyAgICAgICAgbUNvbGwuZ2V0Q29sbGF0aW9uS2V5KCIyZDI5NGYyZDM3Mzk0MzM1NjUxNDc2NTUzOTRmMzc2MmYzMTQ3MzEyZDM3MzE2NDE0NTJmMzEwIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb2xsYXRpb25LZXlTaXplKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgdG8gdmVyaWZ5IHRoYXQgdmVyeSBsYXJnZSBjb2xsYXRpb24ga2V5cyBhcmUgbm90IHRydW5jYXRlZC4KKyAgICAgICAgU3RyaW5nQnVpbGRlciBiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDI0OyBpKyspIHsKKyAgICAgICAgICAgIGIuYXBwZW5kKCIwMTIzNDU2Nzg5QUJDREVGIik7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHNpeHRlZW4gPSBiLnRvU3RyaW5nKCk7CisgICAgICAgIGIuYXBwZW5kKCJfVEhFX0VORCIpOworICAgICAgICBTdHJpbmcgc2l4dGVlbnBsdXMgPSBiLnRvU3RyaW5nKCk7CisKKyAgICAgICAgQ29sbGF0b3IgbUNvbGwgPSBDb2xsYXRvci5nZXRJbnN0YW5jZSgpOworICAgICAgICBtQ29sbC5zZXRTdHJlbmd0aChDb2xsYXRvci5QUklNQVJZKTsKKworICAgICAgICBieXRlIFtdIGFyciA9IG1Db2xsLmdldENvbGxhdGlvbktleShzaXh0ZWVuKS50b0J5dGVBcnJheSgpOworICAgICAgICBpbnQgbGVuID0gYXJyLmxlbmd0aDsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29sbGF0aW9uIGtleSBub3QgMCB0ZXJtaW5hdGVkIiwgYXJyW2Fyci5sZW5ndGggLSAxXSA9PSAwKTsKKyAgICAgICAgbGVuLS07CisgICAgICAgIFN0cmluZyBmb28gPSBuZXcgU3RyaW5nKGFyciwgMCwgbGVuLCAiaXNvODg1OS0xIik7CisKKyAgICAgICAgYXJyID0gbUNvbGwuZ2V0Q29sbGF0aW9uS2V5KHNpeHRlZW4pLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIGxlbiA9IGFyci5sZW5ndGg7CisgICAgICAgIGFzc2VydFRydWUoIkNvbGxhdGlvbiBrZXkgbm90IDAgdGVybWluYXRlZCIsIGFyclthcnIubGVuZ3RoIC0gMV0gPT0gMCk7CisgICAgICAgIGxlbi0tOworICAgICAgICBTdHJpbmcgYmFyID0gbmV3IFN0cmluZyhhcnIsIDAsIGxlbiwgImlzbzg4NTktMSIpOworCisgICAgICAgIGFzc2VydFRydWUoIkNvbGxhdGlvbiBrZXlzIHNob3VsZCBkaWZmZXIiLCBmb28uZXF1YWxzKGJhcikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZGVjb21wb3NpdGlvbkNvbXBhdGliaWxpdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ29sbGF0b3IgbXlDb2xsYXRvciA9IENvbGxhdG9yLmdldEluc3RhbmNlKCk7CisgICAgICAgIG15Q29sbGF0b3Iuc2V0RGVjb21wb3NpdGlvbihDb2xsYXRvci5OT19ERUNPTVBPU0lUSU9OKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkVycm9yOiBcdTAwZTBcdTAzMjUgc2hvdWxkIG5vdCBlcXVhbCB0byBhXHUwMzI1XHUwMzAwIHdpdGhvdXQgZGVjb21wb3NpdGlvbiIsCisgICAgICAgICAgICAgICAgbXlDb2xsYXRvci5jb21wYXJlKCJcdTAwZTBcdTAzMjUiLCAiYVx1MDMyNVx1MDMwMCIpID09IDApOworICAgICAgICBteUNvbGxhdG9yLnNldERlY29tcG9zaXRpb24oQ29sbGF0b3IuQ0FOT05JQ0FMX0RFQ09NUE9TSVRJT04pOworICAgICAgICBhc3NlcnRUcnVlKCJFcnJvcjogXHUwMGUwXHUwMzI1IHNob3VsZCBlcXVhbCB0byBhXHUwMzI1XHUwMzAwIHdpdGggZGVjb21wb3NpdGlvbiIsCisgICAgICAgICAgICAgICAgbXlDb2xsYXRvci5jb21wYXJlKCJcdTAwZTBcdTAzMjUiLCAiYVx1MDMyNVx1MDMwMCIpID09IDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHNPYmplY3QoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgcnVsZSA9ICI8IGEgPCBiIDwgYyA8IGQgPCBlIjsKKyAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgY29sbCA9IG5ldyBSdWxlQmFzZWRDb2xsYXRvcihydWxlKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoQ29sbGF0b3IuVEVSVElBUlksIGNvbGwuZ2V0U3RyZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb2xsYXRvci5OT19ERUNPTVBPU0lUSU9OLCBjb2xsLmdldERlY29tcG9zaXRpb24oKSk7CisgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yIG90aGVyID0gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKHJ1bGUpOworICAgICAgICBhc3NlcnRUcnVlKGNvbGwuZXF1YWxzKG90aGVyKSk7CisKKyAgICAgICAgY29sbC5zZXRTdHJlbmd0aChDb2xsYXRvci5QUklNQVJZKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoY29sbC5lcXVhbHMob3RoZXIpKTsKKworICAgICAgICBjb2xsLnNldFN0cmVuZ3RoKENvbGxhdG9yLlRFUlRJQVJZKTsKKyAgICAgICAgY29sbC5zZXREZWNvbXBvc2l0aW9uKENvbGxhdG9yLkNBTk9OSUNBTF9ERUNPTVBPU0lUSU9OKTsKKyAgICAgICAgb3RoZXIuc2V0RGVjb21wb3NpdGlvbihDb2xsYXRvci5OT19ERUNPTVBPU0lUSU9OKTsgLy8gU2VlIGNvbW1lbnQgYWJvdmUuCisgICAgICAgIGFzc2VydEZhbHNlKGNvbGwuZXF1YWxzKG90aGVyKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9IYXJtb255XzEzNTIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gUmVncmVzc2lvbiB0ZXN0IGZvciBIQVJNT05ZLTEzNTIsIHRoYXQgZG9lc24ndCBnZXQgcnVuIGluIHRoZSBoYXJtb255IHRlc3Qgc3VpdGUgYmVjYXVzZQorICAgICAgICAvLyBvZiBhbiBlYXJsaWVyIGZhaWx1cmUuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoIjwgYTwgYjwgYzwgZCIpLmdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcigoQ2hhcmFjdGVySXRlcmF0b3IpIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGl0LCBJbnRlZ2VyLi4uIG9mZnNldHMpIHsKKyAgICAgICAgZm9yIChpbnQgb2Zmc2V0IDogb2Zmc2V0cykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG9mZnNldCwgaXQuZ2V0T2Zmc2V0KCkpOworICAgICAgICAgICAgaXQubmV4dCgpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyhDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSLCBpdC5uZXh0KCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRHZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3JTdHJpbmcoTG9jYWxlIGwsIFN0cmluZyBzLCBJbnRlZ2VyLi4uIG9mZnNldHMpIHsKKyAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgY29sbCA9IChSdWxlQmFzZWRDb2xsYXRvcikgQ29sbGF0b3IuZ2V0SW5zdGFuY2UobCk7CisgICAgICAgIGFzc2VydENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb2xsLmdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihzKSwgb2Zmc2V0cyk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydEdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvckNoYXJhY3Rlckl0ZXJhdG9yKExvY2FsZSBsLCBTdHJpbmcgcywgSW50ZWdlci4uLiBvZmZzZXRzKSB7CisgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yIGNvbGwgPSAoUnVsZUJhc2VkQ29sbGF0b3IpIENvbGxhdG9yLmdldEluc3RhbmNlKGwpOworICAgICAgICBDaGFyYWN0ZXJJdGVyYXRvciBpdCA9IG5ldyBTdHJpbmdDaGFyYWN0ZXJJdGVyYXRvcihzKTsKKyAgICAgICAgYXNzZXJ0Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGNvbGwuZ2V0Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGl0KSwgb2Zmc2V0cyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvclN0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRHZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3JTdHJpbmcobmV3IExvY2FsZSgiZXMiLCAiIiwgIlRSQURJVElPTkFMIiksICJjaGEiLCAwLCAyLCAzKTsKKyAgICAgICAgYXNzZXJ0R2V0Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yU3RyaW5nKG5ldyBMb2NhbGUoImVzIiwgIiIsICIiKSwgImNoYSIsIDAsIDEsIDIsIDMpOworICAgICAgICBhc3NlcnRHZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3JTdHJpbmcobmV3IExvY2FsZSgiZGUiLCAiREUiLCAiIiksICJcdTAwZTZiIiwgMCwgMSwgMSwgMSwgMSwgMik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvckNoYXJhY3Rlckl0ZXJhdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvckNoYXJhY3Rlckl0ZXJhdG9yKG5ldyBMb2NhbGUoImVzIiwgIiIsICJUUkFESVRJT05BTCIpLCAiY2hhIiwgMCwgMiwgMyk7CisgICAgICAgIGFzc2VydEdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvckNoYXJhY3Rlckl0ZXJhdG9yKG5ldyBMb2NhbGUoImVzIiwgIiIsICIiKSwgImNoYSIsIDAsIDEsIDIsIDMpOworICAgICAgICBhc3NlcnRHZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3JDaGFyYWN0ZXJJdGVyYXRvcihuZXcgTG9jYWxlKCJkZSIsICJERSIsICIiKSwgIlx1MDBlNmIiLCAwLCAxLCAxLCAxLCAxLCAyKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvRGF0ZUZvcm1hdFN5bWJvbHNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvRGF0ZUZvcm1hdFN5bWJvbHNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzE5YTc2ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9EYXRlRm9ybWF0U3ltYm9sc1Rlc3QuamF2YQpAQCAtMCwwICsxLDEyNiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS50ZXh0LkRhdGVGb3JtYXRTeW1ib2xzOworaW1wb3J0IGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CisKK3B1YmxpYyBjbGFzcyBEYXRlRm9ybWF0U3ltYm9sc1Rlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRMb2NhbGVJc0VxdWl2YWxlbnRUb1Jvb3QoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBEYXRlRm9ybWF0U3ltYm9scyBkZnMgPSBEYXRlRm9ybWF0U3ltYm9scy5nZXRJbnN0YW5jZShsb2NhbGUpOworICAgICAgICBhc3NlcnRFcXVhbHMoRGF0ZUZvcm1hdFN5bWJvbHMuZ2V0SW5zdGFuY2UoTG9jYWxlLlJPT1QpLCBkZnMpOworICAgIH0KKworICAgIC8qKiBodHRwOi8vYi8zMDU2NTg2ICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZV91bmtub3duX2xvY2FsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUT0RPOiB3ZSBmYWlsIHRoaXMgdGVzdC4gb24gQW5kcm9pZCwgdGhlIHJvb3QgbG9jYWxlIHVzZXMgR01UIG9mZnNldHMgYXMgbmFtZXMuCisgICAgICAgIC8vIHNlZSB0aGUgaW52YWxpZCBsb2NhbGUgdGVzdCBiZWxvdy4gb24gdGhlIFJJLCB0aGUgcm9vdCBsb2NhbGUgdXNlcyBFbmdsaXNoIG5hbWVzLgorICAgICAgICBhc3NlcnRMb2NhbGVJc0VxdWl2YWxlbnRUb1Jvb3QobmV3IExvY2FsZSgieHgiLCAiWFgiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZV9pbnZhbGlkX2xvY2FsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRMb2NhbGVJc0VxdWl2YWxlbnRUb1Jvb3QobmV3IExvY2FsZSgibm90IGV4aXN0IGxhbmd1YWdlIiwgIm5vdCBleGlzdCBjb3VudHJ5IikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRoZSBQb2xpc2ggbGFuZ3VhZ2UgbmVlZHMgc3RhbmQtYWxvbmUgbW9udGggYW5kIHdlZWtkYXkgbmFtZXMuCisgICAgICAgIExvY2FsZSBwbCA9IG5ldyBMb2NhbGUoInBsIik7CisgICAgICAgIERhdGVGb3JtYXRTeW1ib2xzIG9yaWdpbmFsRGZzID0gbmV3IERhdGVGb3JtYXRTeW1ib2xzKHBsKTsKKworICAgICAgICAvLyBTZXJpYWxpemUuLi4KKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgbmV3IE9iamVjdE91dHB1dFN0cmVhbShvdXQpLndyaXRlT2JqZWN0KG9yaWdpbmFsRGZzKTsKKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0gb3V0LnRvQnl0ZUFycmF5KCk7CisKKyAgICAgICAgLy8gRGVzZXJpYWxpemUuLi4KKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0gaW4gPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzKSk7CisgICAgICAgIERhdGVGb3JtYXRTeW1ib2xzIGRlc2VyaWFsaXplZERmcyA9IChEYXRlRm9ybWF0U3ltYm9scykgaW4ucmVhZE9iamVjdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisKKyAgICAgICAgLy8gVGhlIHR3byBvYmplY3RzIHNob3VsZCBjbGFpbSB0byBiZSBlcXVhbCwgZXZlbiB0aG91Z2ggdGhleSBhcmVuJ3QgcmVhbGx5LgorICAgICAgICBhc3NlcnRFcXVhbHMob3JpZ2luYWxEZnMsIGRlc2VyaWFsaXplZERmcyk7CisKKyAgICAgICAgLy8gVGhlIG9yaWdpbmFsIGRpZmZlcmVudGlhdGVzIGJldHdlZW4gcmVndWxhciBtb250aCBuYW1lcyBhbmQgc3RhbmQtYWxvbmUgbW9udGggbmFtZXMuLi4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdHljem5pYSIsIGZvcm1hdERhdGUocGwsICJNTU1NIiwgb3JpZ2luYWxEZnMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdHljemVcdTAxNDQiLCBmb3JtYXREYXRlKHBsLCAiTExMTCIsIG9yaWdpbmFsRGZzKSk7CisKKyAgICAgICAgLy8gV2hlcmVhcyB0aGUgZGVzZXJpYWxpemVkIG9iamVjdCBjYW4ndCwgYmVjYXVzZSBpdCBsb3N0IHRoZSBzdHJpbmdzLi4uCisgICAgICAgIGFzc2VydEVxdWFscygic3R5Y3puaWEiLCBmb3JtYXREYXRlKHBsLCAiTU1NTSIsIGRlc2VyaWFsaXplZERmcykpOworICAgICAgICBhc3NlcnRFcXVhbHMoInN0eWN6bmlhIiwgZm9ybWF0RGF0ZShwbCwgIkxMTEwiLCBkZXNlcmlhbGl6ZWREZnMpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyBmb3JtYXREYXRlKExvY2FsZSBsLCBTdHJpbmcgZm10LCBEYXRlRm9ybWF0U3ltYm9scyBkZnMpIHsKKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBzZGYgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdChmbXQsIGwpOworICAgICAgICBzZGYuc2V0RGF0ZUZvcm1hdFN5bWJvbHMoZGZzKTsKKyAgICAgICAgc2RmLnNldFRpbWVab25lKFRpbWVab25lLmdldFRpbWVab25lKCJVVEMiKSk7CisgICAgICAgIHJldHVybiBzZGYuZm9ybWF0KG5ldyBEYXRlKDApKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFpvbmVTdHJpbmdzX2Nsb25pbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQ2hlY2sgdGhhdCBjb3JydXB0aW5nIG91ciBhcnJheSBkb2Vzbid0IGFmZmVjdCBvdGhlciBjYWxsZXJzLgorCisgICAgICAgIC8vIEtpbGwgYSByb3cuCisgICAgICAgIHsKKyAgICAgICAgICAgIFN0cmluZ1tdW10gb3JpZ2luYWxab25lU3RyaW5ncyA9IERhdGVGb3JtYXRTeW1ib2xzLmdldEluc3RhbmNlKExvY2FsZS5VUykuZ2V0Wm9uZVN0cmluZ3MoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwob3JpZ2luYWxab25lU3RyaW5nc1swXSk7CisgICAgICAgICAgICBvcmlnaW5hbFpvbmVTdHJpbmdzWzBdID0gbnVsbDsKKyAgICAgICAgICAgIFN0cmluZ1tdW10gY3VycmVudFpvbmVTdHJpbmdzID0gRGF0ZUZvcm1hdFN5bWJvbHMuZ2V0SW5zdGFuY2UoTG9jYWxlLlVTKS5nZXRab25lU3RyaW5ncygpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChjdXJyZW50Wm9uZVN0cmluZ3NbMF0pOworICAgICAgICB9CisKKyAgICAgICAgLy8gS2lsbCBhbiBlbGVtZW50LgorICAgICAgICB7CisgICAgICAgICAgICBTdHJpbmdbXVtdIG9yaWdpbmFsWm9uZVN0cmluZ3MgPSBEYXRlRm9ybWF0U3ltYm9scy5nZXRJbnN0YW5jZShMb2NhbGUuVVMpLmdldFpvbmVTdHJpbmdzKCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG9yaWdpbmFsWm9uZVN0cmluZ3NbMF1bMF0pOworICAgICAgICAgICAgb3JpZ2luYWxab25lU3RyaW5nc1swXVswXSA9IG51bGw7CisgICAgICAgICAgICBTdHJpbmdbXVtdIGN1cnJlbnRab25lU3RyaW5ncyA9IERhdGVGb3JtYXRTeW1ib2xzLmdldEluc3RhbmNlKExvY2FsZS5VUykuZ2V0Wm9uZVN0cmluZ3MoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoY3VycmVudFpvbmVTdHJpbmdzWzBdWzBdKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Wm9uZVN0cmluZ3NfVVRDKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEhhc2hNYXA8U3RyaW5nLCBTdHJpbmdbXT4gem9uZVN0cmluZ3MgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZ1tdPigpOworICAgICAgICBmb3IgKFN0cmluZ1tdIHJvdyA6IERhdGVGb3JtYXRTeW1ib2xzLmdldEluc3RhbmNlKExvY2FsZS5VUykuZ2V0Wm9uZVN0cmluZ3MoKSkgeworICAgICAgICAgICAgem9uZVN0cmluZ3MucHV0KHJvd1swXSwgcm93KTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydFV0Yyh6b25lU3RyaW5ncy5nZXQoIkV0Yy9VQ1QiKSk7CisgICAgICAgIGFzc2VydFV0Yyh6b25lU3RyaW5ncy5nZXQoIkV0Yy9VVEMiKSk7CisgICAgICAgIGFzc2VydFV0Yyh6b25lU3RyaW5ncy5nZXQoIkV0Yy9Vbml2ZXJzYWwiKSk7CisgICAgICAgIGFzc2VydFV0Yyh6b25lU3RyaW5ncy5nZXQoIkV0Yy9adWx1IikpOworCisgICAgICAgIGFzc2VydFV0Yyh6b25lU3RyaW5ncy5nZXQoIlVDVCIpKTsKKyAgICAgICAgYXNzZXJ0VXRjKHpvbmVTdHJpbmdzLmdldCgiVVRDIikpOworICAgICAgICBhc3NlcnRVdGMoem9uZVN0cmluZ3MuZ2V0KCJVbml2ZXJzYWwiKSk7CisgICAgICAgIGFzc2VydFV0Yyh6b25lU3RyaW5ncy5nZXQoIlp1bHUiKSk7CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYXNzZXJ0VXRjKFN0cmluZ1tdIHJvdykgeworICAgICAgICAvLyBFbGVtZW50IDAgaXMgdGhlIE9sc29uIGlkLiBUaGUgc2hvcnQgbmFtZXMgc2hvdWxkIGJlICJVVEMiLgorICAgICAgICAvLyBPbiB0aGUgUkksIHRoZSBsb25nIG5hbWVzIGFyZSBsb2NhbGl6ZWQuIElDVSBkb2Vzbid0IGhhdmUgdGhvc2UsIHNvIHdlIGp1c3QgdXNlIFVUQy4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy50b1N0cmluZyhyb3cpLCAiVVRDIiwgcm93WzJdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy50b1N0cmluZyhyb3cpLCAiVVRDIiwgcm93WzRdKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvRGVjaW1hbEZvcm1hdFN5bWJvbHNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvRGVjaW1hbEZvcm1hdFN5bWJvbHNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGIyNGM2ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9EZWNpbWFsRm9ybWF0U3ltYm9sc1Rlc3QuamF2YQpAQCAtMCwwICsxLDU3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudGV4dDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdFN5bWJvbHM7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworcHVibGljIGNsYXNzIERlY2ltYWxGb3JtYXRTeW1ib2xzVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrTG9jYWxlSXNFcXVpdmFsZW50VG9Sb290KExvY2FsZSBsb2NhbGUpIHsKKyAgICAgICAgRGVjaW1hbEZvcm1hdFN5bWJvbHMgZGZzID0gRGVjaW1hbEZvcm1hdFN5bWJvbHMuZ2V0SW5zdGFuY2UobG9jYWxlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERlY2ltYWxGb3JtYXRTeW1ib2xzLmdldEluc3RhbmNlKExvY2FsZS5ST09UKSwgZGZzKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZV91bmtub3duX29yX2ludmFsaWRfbG9jYWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRPRE86IHdlIGZhaWwgdGhlc2UgdGVzdHMgYmVjYXVzZSBST09UIGhhcyAiSU5GIiBmb3IgaW5maW5pdHkgYnV0ICdkZnMnIGhhcyAiXHUyMjFlIi4KKyAgICAgICAgLy8gT24gdGhlIFJJLCBST09UIGhhcyAiXHUyMjFlIiB0b28sIGJ1dCBEZWNpbWFsRm9ybWF0U3ltYm9scy5lcXVhbHMgYXBwZWFycyB0byBiZSBicm9rZW47CisgICAgICAgIC8vIGl0IHJldHVybnMgZmFsc2UgZm9yIG9iamVjdHMgdGhhdCAtLSBpZiB5b3UgY29tcGFyZSB0aGVpciBleHRlcm5hbGx5IHZpc2libGUgc3RhdGUgLS0KKyAgICAgICAgLy8gYXJlIGVxdWFsLiBJdCBjb3VsZCBiZSB0aGF0IHRoZXkncmUgYWNjaWRlbnRhbGx5IGNoZWNraW5nIHRoZSBMb2NhbGUuCisgICAgICAgIGNoZWNrTG9jYWxlSXNFcXVpdmFsZW50VG9Sb290KG5ldyBMb2NhbGUoInh4IiwgIlhYIikpOworICAgICAgICBjaGVja0xvY2FsZUlzRXF1aXZhbGVudFRvUm9vdChuZXcgTG9jYWxlKCJub3QgZXhpc3QgbGFuZ3VhZ2UiLCAibm90IGV4aXN0IGNvdW50cnkiKSk7CisgICAgfQorCisgICAgLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD0xNDQ5NQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIERlY2ltYWxGb3JtYXRTeW1ib2xzIG9yaWdpbmFsRGZzID0gRGVjaW1hbEZvcm1hdFN5bWJvbHMuZ2V0SW5zdGFuY2UoTG9jYWxlLkdFUk1BTlkpOworCisgICAgICAgIC8vIFNlcmlhbGl6ZS4uLgorICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKG91dCkud3JpdGVPYmplY3Qob3JpZ2luYWxEZnMpOworICAgICAgICBieXRlW10gYnl0ZXMgPSBvdXQudG9CeXRlQXJyYXkoKTsKKworICAgICAgICAvLyBEZXNlcmlhbGl6ZS4uLgorICAgICAgICBPYmplY3RJbnB1dFN0cmVhbSBpbiA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZXMpKTsKKyAgICAgICAgRGVjaW1hbEZvcm1hdFN5bWJvbHMgZGVzZXJpYWxpemVkRGZzID0gKERlY2ltYWxGb3JtYXRTeW1ib2xzKSBpbi5yZWFkT2JqZWN0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgaW4ucmVhZCgpKTsKKworICAgICAgICAvLyBUaGUgdHdvIG9iamVjdHMgc2hvdWxkIGNsYWltIHRvIGJlIGVxdWFsLgorICAgICAgICBhc3NlcnRFcXVhbHMob3JpZ2luYWxEZnMsIGRlc2VyaWFsaXplZERmcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L0RlY2ltYWxGb3JtYXRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvRGVjaW1hbEZvcm1hdFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NmIwNTdiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L0RlY2ltYWxGb3JtYXRUZXN0LmphdmEKQEAgLTAsMCArMSwxNDYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS50ZXh0OworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7CitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5tYXRoLlJvdW5kaW5nTW9kZTsKK2ltcG9ydCBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdFN5bWJvbHM7CitpbXBvcnQgamF2YS50ZXh0Lk51bWJlckZvcm1hdDsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCitwdWJsaWMgY2xhc3MgRGVjaW1hbEZvcm1hdFRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXhwb25lbnRTZXBhcmF0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRGVjaW1hbEZvcm1hdCBkZiA9IG5ldyBEZWNpbWFsRm9ybWF0KCIwRTAiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxRTQiLCBkZi5mb3JtYXQoMTIzNDUuKSk7CisKKyAgICAgICAgRGVjaW1hbEZvcm1hdFN5bWJvbHMgZGZzID0gZGYuZ2V0RGVjaW1hbEZvcm1hdFN5bWJvbHMoKTsKKyAgICAgICAgZGZzLnNldEV4cG9uZW50U2VwYXJhdG9yKCItdXNlbGVzcy1hcGktIik7CisgICAgICAgIGRmLnNldERlY2ltYWxGb3JtYXRTeW1ib2xzKGRmcyk7CisgICAgICAgIGFzc2VydEVxdWFscygiMS11c2VsZXNzLWFwaS00IiwgZGYuZm9ybWF0KDEyMzQ1LikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzQWZmZWN0c1JvdW5kaW5nTW9kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEZWNpbWFsRm9ybWF0IGRmID0gKERlY2ltYWxGb3JtYXQpIERlY2ltYWxGb3JtYXQuZ2V0SW5zdGFuY2UoTG9jYWxlLlVTKTsKKyAgICAgICAgZGYuc2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKDApOworICAgICAgICBkZi5zZXRSb3VuZGluZ01vZGUoUm91bmRpbmdNb2RlLkhBTEZfVVApOworICAgICAgICBhc3NlcnRFcXVhbHMoIi0wIiwgZGYuZm9ybWF0KC0wLjIpKTsKKyAgICAgICAgZGYuc2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi0wLjIiLCBkZi5mb3JtYXQoLTAuMikpOworICAgIH0KKworICAgIC8vIEFuZHJvaWQgZmFpbHMgdGhpcyB0ZXN0LCB0cnVuY2F0aW5nIHRvIDEyNyBkaWdpdHMuCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRNYXhpbXVtSW50ZWdlckRpZ2l0cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBOdW1iZXJGb3JtYXQgbnVtYmVyRm9ybWF0ID0gTnVtYmVyRm9ybWF0LmdldE51bWJlckluc3RhbmNlKExvY2FsZS5VUyk7CisgICAgICAgIG51bWJlckZvcm1hdC5zZXRHcm91cGluZ1VzZWQoZmFsc2UpOworICAgICAgICBudW1iZXJGb3JtYXQuc2V0TWluaW11bUludGVnZXJEaWdpdHMoNDAwKTsKKyAgICAgICAgLy8gVGhlIFJJJ3MgZG9jdW1lbnRhdGlvbiBzdWdnZXN0cyB0aGF0IHRoZSBpbnQgc2hvdWxkIGJlIGZvcm1hdHRlZCB0byAzMDkgY2hhcmFjdGVycyAtLQorICAgICAgICAvLyBhIG1hZ2ljIG51bWJlciB0aGV5IGRvbid0IGV4cGxhaW4gLS0gYnV0IHRoZSBCaWdJbnRlZ2VyIHNob3VsZCBiZSBmb3JtYXR0ZWQgdG8gdGhlIDQwMAorICAgICAgICAvLyBjaGFyYWN0ZXJzIHdlIGFza2VkIGZvci4gSW4gcHJhY3RpY2UsIHRoZSBSSSB1c2VzIDMwOSBpbiBib3RoIGNhc2VzLgorICAgICAgICBhc3NlcnRFcXVhbHMoMzA5LCBudW1iZXJGb3JtYXQuZm9ybWF0KDEyMykubGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMzA5LCBudW1iZXJGb3JtYXQuZm9ybWF0KEJpZ0ludGVnZXIudmFsdWVPZigxMjMpKS5sZW5ndGgoKSk7CisgICAgfQorCisgICAgLy8gUmVncmVzc2lvbiB0ZXN0IGZvciBodHRwOi8vYi8xODk3OTE3OiBCaWdEZWNpbWFsIGRvZXMgbm90IHRha2UgaW50byBhY2NvdW50IG11bHRpcGxpZXIuCisgICAgcHVibGljIHZvaWQgdGVzdEJpZ0RlY2ltYWxCdWcxODk3OTE3KCkgeworICAgICAgICAvLyBGb3IgZXhhbXBsZS4gdGhlIEJpZ0RlY2ltYWwgMC4xNyBmb3JtYXR0ZWQgaW4gUGVyY2VudEluc3RhbmNlIGlzIDAlIGluc3RlYWQgb2YgMTclOgorICAgICAgICBOdW1iZXJGb3JtYXQgcGYgPSBOdW1iZXJGb3JtYXQuZ2V0UGVyY2VudEluc3RhbmNlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTclIiwgcGYuZm9ybWF0KEJpZ0RlY2ltYWwudmFsdWVPZigwLjE3KSkpOworCisgICAgICAgIC8vIFRlc3QgbG9uZyBkZWNpbWFsIGZvcm1hdHRlZCBpbiBQZXJjZW50SW5zdGFuY2Ugd2l0aCB2YXJpb3VzIGZyYWN0aW9ucy4KKyAgICAgICAgU3RyaW5nIGxvbmdEZWMgPSAiMTEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCI7CisgICAgICAgIEJpZ0RlY2ltYWwgYmQgPSBuZXcgQmlnRGVjaW1hbChsb25nRGVjKTsKKyAgICAgICAgYXNzZXJ0QmlnRGVjaW1hbFdpdGhGcmFjdGlvbihiZCwgIjEsMTIzLjQ2JSIsIDIpOworICAgICAgICBhc3NlcnRCaWdEZWNpbWFsV2l0aEZyYWN0aW9uKGJkLCAiMSwxMjMuNDU2Nzg5MDElIiwgOCk7CisgICAgICAgIGFzc2VydEJpZ0RlY2ltYWxXaXRoRnJhY3Rpb24oYmQsICIxLDEyMy40NTY3ODkwMTIzJSIsIDEwKTsKKyAgICAgICAgYXNzZXJ0QmlnRGVjaW1hbFdpdGhGcmFjdGlvbihiZCwgIjEsMTIzLjQ1Njc4OTAxMjM0NTY3ODkwMTIzJSIsIDIwKTsKKyAgICAgICAgYXNzZXJ0QmlnRGVjaW1hbFdpdGhGcmFjdGlvbihiZCwgIjEsMTIzLjQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMyUiLCAzMCk7CisKKyAgICAgICAgLy8gVGVzdCB0cmFpbGluZyB6ZXJvcy4KKyAgICAgICAgYXNzZXJ0RGVjRm10V2l0aE11bHRpcGxpZXJBbmRGcmFjdGlvbigiMzMzMy4zMzMzMzMzMyIsIDMsIDQsICIxMCwwMDAiKTsKKyAgICAgICAgYXNzZXJ0RGVjRm10V2l0aE11bHRpcGxpZXJBbmRGcmFjdGlvbigiMzMzMy4zMzMzMzMzMyIsIC0zLCA0LCAiLTEwLDAwMCIpOworICAgICAgICBhc3NlcnREZWNGbXRXaXRoTXVsdGlwbGllckFuZEZyYWN0aW9uKCIwLjAwMzMzMzMzIiwgMywgNCwgIjAuMDEiKTsKKyAgICAgICAgYXNzZXJ0RGVjRm10V2l0aE11bHRpcGxpZXJBbmRGcmFjdGlvbigiMzMzMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCIsIDMsIDQsCisgICAgICAgICAgICAgICAgIjksOTkwLDAwMCwwMDAsMDAwLDAwMCwwMDAsMDAwLDAwMCwwMDAsMDAwLDAwMCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCaWdEZWNpbWFsVGVzdEJpZ0ludFdpdGhNdWx0aXBsaWVyKCkgeworICAgICAgICAvLyBCaWcgaW50ZWdlciB0ZXN0cy4KKyAgICAgICAgYXNzZXJ0RGVjRm10V2l0aE11bHRpcGxpZXJBbmRGcmFjdGlvbigiMTIzNDU2Nzg5MDEyMzQ1IiwgMTAsIDAsCisgICAgICAgICAgICAgICAgIjEsMjM0LDU2Nyw4OTAsMTIzLDQ1MCIpOworICAgICAgICBhc3NlcnREZWNGbXRXaXRoTXVsdGlwbGllckFuZEZyYWN0aW9uKCIxMjM0NTY3ODkwMTIzNDU2Nzg5MCIsIDEwLCAwLAorICAgICAgICAgICAgICAgICIxMjMsNDU2LDc4OSwwMTIsMzQ1LDY3OCw5MDAiKTsKKyAgICAgICAgYXNzZXJ0RGVjRm10V2l0aE11bHRpcGxpZXJBbmRGcmFjdGlvbigiOTg3NjU0MzIxMDk4NzY1NDMyMTA5ODc2NTQzMjEiLCAxMCwgMCwKKyAgICAgICAgICAgICAgICAiOTg3LDY1NCwzMjEsMDk4LDc2NSw0MzIsMTA5LDg3Niw1NDMsMjEwIik7CisKKyAgICAgICAgYXNzZXJ0RGVjRm10V2l0aE11bHRpcGxpZXJBbmRGcmFjdGlvbigiMTIzNDU2Nzg5MDEyMzQ1IiwgLTEwLCAwLAorICAgICAgICAgICAgICAgICItMSwyMzQsNTY3LDg5MCwxMjMsNDUwIik7CisgICAgICAgIGFzc2VydERlY0ZtdFdpdGhNdWx0aXBsaWVyQW5kRnJhY3Rpb24oIjEyMzQ1Njc4OTAxMjM0NTY3ODkwIiwgLTEwLCAwLAorICAgICAgICAgICAgICAgICItMTIzLDQ1Niw3ODksMDEyLDM0NSw2NzgsOTAwIik7CisgICAgICAgIGFzc2VydERlY0ZtdFdpdGhNdWx0aXBsaWVyQW5kRnJhY3Rpb24oIjk4NzY1NDMyMTA5ODc2NTQzMjEwOTg3NjU0MzIxIiwgLTEwLCAwLAorICAgICAgICAgICAgICAgICItOTg3LDY1NCwzMjEsMDk4LDc2NSw0MzIsMTA5LDg3Niw1NDMsMjEwIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEJpZ0RlY2ltYWxJQ1VDb25zaXN0ZW5jeSgpIHsKKyAgICAgICAgRGVjaW1hbEZvcm1hdCBkZiA9IChEZWNpbWFsRm9ybWF0KSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgZGYuc2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKDIpOworICAgICAgICBkZi5zZXRNdWx0aXBsaWVyKDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoZGYuZm9ybWF0KEJpZ0RlY2ltYWwudmFsdWVPZigwLjE2KSksCisgICAgICAgIGRmLmZvcm1hdChCaWdEZWNpbWFsLnZhbHVlT2YoMC4xNikuZG91YmxlVmFsdWUoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZGYuZm9ybWF0KEJpZ0RlY2ltYWwudmFsdWVPZigwLjAyOTMpKSwKKyAgICAgICAgZGYuZm9ybWF0KEJpZ0RlY2ltYWwudmFsdWVPZigwLjAyOTMpLmRvdWJsZVZhbHVlKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGRmLmZvcm1hdChCaWdEZWNpbWFsLnZhbHVlT2YoMC4wMDYpKSwKKyAgICAgICAgZGYuZm9ybWF0KEJpZ0RlY2ltYWwudmFsdWVPZigwLjAwNikuZG91YmxlVmFsdWUoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZGYuZm9ybWF0KEJpZ0RlY2ltYWwudmFsdWVPZigwLjAwMjgzKSksCisgICAgICAgIGRmLmZvcm1hdChCaWdEZWNpbWFsLnZhbHVlT2YoMC4wMDI4MykuZG91YmxlVmFsdWUoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZGYuZm9ybWF0KEJpZ0RlY2ltYWwudmFsdWVPZigxLjYwKSksCisgICAgICAgIGRmLmZvcm1hdChCaWdEZWNpbWFsLnZhbHVlT2YoMS42MCkuZG91YmxlVmFsdWUoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZGYuZm9ybWF0KEJpZ0RlY2ltYWwudmFsdWVPZigxNSkpLAorICAgICAgICBkZi5mb3JtYXQoQmlnRGVjaW1hbC52YWx1ZU9mKDE1KS5kb3VibGVWYWx1ZSgpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhkZi5mb3JtYXQoQmlnRGVjaW1hbC52YWx1ZU9mKDE3MCkpLAorICAgICAgICBkZi5mb3JtYXQoQmlnRGVjaW1hbC52YWx1ZU9mKDE3MCkuZG91YmxlVmFsdWUoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZGYuZm9ybWF0KEJpZ0RlY2ltYWwudmFsdWVPZigyMzQuNTYpKSwKKyAgICAgICAgZGYuZm9ybWF0KEJpZ0RlY2ltYWwudmFsdWVPZigyMzQuNTYpLmRvdWJsZVZhbHVlKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGRmLmZvcm1hdChCaWdEZWNpbWFsLnZhbHVlT2YoMCkpLAorICAgICAgICBkZi5mb3JtYXQoQmlnRGVjaW1hbC52YWx1ZU9mKDApLmRvdWJsZVZhbHVlKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGRmLmZvcm1hdChCaWdEZWNpbWFsLnZhbHVlT2YoLTEpKSwKKyAgICAgICAgZGYuZm9ybWF0KEJpZ0RlY2ltYWwudmFsdWVPZigtMSkuZG91YmxlVmFsdWUoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZGYuZm9ybWF0KEJpZ0RlY2ltYWwudmFsdWVPZigtMTAwMDApKSwKKyAgICAgICAgZGYuZm9ybWF0KEJpZ0RlY2ltYWwudmFsdWVPZigtMTAwMDApLmRvdWJsZVZhbHVlKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGRmLmZvcm1hdChCaWdEZWNpbWFsLnZhbHVlT2YoLTAuMDAxKSksCisgICAgICAgIGRmLmZvcm1hdChCaWdEZWNpbWFsLnZhbHVlT2YoLTAuMDAxKS5kb3VibGVWYWx1ZSgpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhkZi5mb3JtYXQoQmlnRGVjaW1hbC52YWx1ZU9mKDEyMzQ1Njc4OTAuMTIzNDU2NykpLAorICAgICAgICBkZi5mb3JtYXQoQmlnRGVjaW1hbC52YWx1ZU9mKDEyMzQ1Njc4OTAuMTIzNDU2NykuZG91YmxlVmFsdWUoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZGYuZm9ybWF0KEJpZ0RlY2ltYWwudmFsdWVPZigxLjIzNDU2N0UxMDApKSwKKyAgICAgICAgZGYuZm9ybWF0KEJpZ0RlY2ltYWwudmFsdWVPZigxLjIzNDU2N0UxMDApLmRvdWJsZVZhbHVlKCkpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0QmlnRGVjaW1hbFdpdGhGcmFjdGlvbihCaWdEZWNpbWFsIGJkLCBTdHJpbmcgZXhwZWN0ZWRSZXN1bHQsIGludCBmcmFjdGlvbikgeworICAgICAgICBOdW1iZXJGb3JtYXQgcGYgPSBOdW1iZXJGb3JtYXQuZ2V0UGVyY2VudEluc3RhbmNlKCk7CisgICAgICAgIHBmLnNldE1heGltdW1GcmFjdGlvbkRpZ2l0cyhmcmFjdGlvbik7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZFJlc3VsdCwgcGYuZm9ybWF0KGJkKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydERlY0ZtdFdpdGhNdWx0aXBsaWVyQW5kRnJhY3Rpb24oU3RyaW5nIHZhbHVlLCBpbnQgbXVsdGlwbGllciwgaW50IGZyYWN0aW9uLCBTdHJpbmcgZXhwZWN0ZWRSZXN1bHQpIHsKKyAgICAgICAgRGVjaW1hbEZvcm1hdCBkZiA9IChEZWNpbWFsRm9ybWF0KU51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpOworICAgICAgICBkZi5zZXRNdWx0aXBsaWVyKG11bHRpcGxpZXIpOworICAgICAgICBkZi5zZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoZnJhY3Rpb24pOworICAgICAgICBCaWdEZWNpbWFsIGQgPSBuZXcgQmlnRGVjaW1hbCh2YWx1ZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZFJlc3VsdCwgZGYuZm9ybWF0KGQpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvTm9ybWFsaXplclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9Ob3JtYWxpemVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVjNzkxNzMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvTm9ybWFsaXplclRlc3QuamF2YQpAQCAtMCwwICsxLDg3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudGV4dDsKKworaW1wb3J0IGphdmEudGV4dC5Ob3JtYWxpemVyOworCitwdWJsaWMgY2xhc3MgTm9ybWFsaXplclRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3ROb3JtYWxpemUoKSB7CisgICAgICAgIGZpbmFsIFN0cmluZyBzcmMgPSAiXHUwM2QzXHUwM0Q0XHUxRTlCIjsKKworICAgICAgICAvLyBTaG91bGQgYWxyZWFkeSBiZSBjYW5vbmljYWwgY29tcG9zZWQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNyYywgTm9ybWFsaXplci5ub3JtYWxpemUoc3JjLCBOb3JtYWxpemVyLkZvcm0uTkZDKSk7CisKKyAgICAgICAgLy8gQ29tcG9zZWQgdG8gY2Fub25pY2FsIGRlY29tcG9zZWQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJcdTAzZDJcdTAzMDFcdTAzZDJcdTAzMDhcdTAxN2ZcdTAzMDciLAorICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXIubm9ybWFsaXplKHNyYywgTm9ybWFsaXplci5Gb3JtLk5GRCkpOworCisgICAgICAgIC8vIENvbXBvc2VkIHRvIGNvbXBhdGliaWxpdHkgY29tcG9zZWQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJcdTAzOGVcdTAzYWJcdTFlNjEiLCBOb3JtYWxpemVyLm5vcm1hbGl6ZShzcmMsIE5vcm1hbGl6ZXIuRm9ybS5ORktDKSk7CisKKyAgICAgICAgLy8gQ29tcG9zZWQgdG8gY29tcGF0aWJpbGl0eSBkZWNvbXBvc2VkCisgICAgICAgIGFzc2VydEVxdWFscygiXHUwM2E1XHUwMzAxXHUwM2E1XHUwMzA4XHUwMDczXHUwMzA3IiwKKyAgICAgICAgICAgICAgICBOb3JtYWxpemVyLm5vcm1hbGl6ZShzcmMsIE5vcm1hbGl6ZXIuRm9ybS5ORktEKSk7CisKKyAgICAgICAgLy8gRGVjb21wb3NlZCB0byBjYW5vbmljYWwgY29tcG9zZWQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJcdTAwZTkiLCBOb3JtYWxpemVyLm5vcm1hbGl6ZSgiXHUwMDY1XHUwMzAxIiwgTm9ybWFsaXplci5Gb3JtLk5GQykpOworCisgICAgICAgIC8vIERlY29tcG9zZWQgdG8gY29tcGF0aWJpbGl0eSBjb21wb3NlZAorICAgICAgICBhc3NlcnRFcXVhbHMoIlx1MWU2OSIsIE5vcm1hbGl6ZXIubm9ybWFsaXplKCJcdTFlOWJcdTAzMjMiLCBOb3JtYWxpemVyLkZvcm0uTkZLQykpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOb3JtYWxpemVyLm5vcm1hbGl6ZShudWxsLCBOb3JtYWxpemVyLkZvcm0uTkZDKTsKKyAgICAgICAgICAgIGZhaWwoIkRpZCBub3QgdGhyb3cgZXJyb3Igb24gbnVsbCBhcmd1bWVudCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBwYXNzCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNOb3JtYWxpemVkKCkgeworICAgICAgICBTdHJpbmcgdGFyZ2V0OworCisgICAgICAgIHRhcmdldCA9IG5ldyBTdHJpbmcobmV3IGNoYXJbXSB7MHgwM0QzLCAweDAzRDQsIDB4MUU5Qn0pOworICAgICAgICBhc3NlcnRUcnVlKE5vcm1hbGl6ZXIuaXNOb3JtYWxpemVkKHRhcmdldCwgTm9ybWFsaXplci5Gb3JtLk5GQykpOworICAgICAgICBhc3NlcnRGYWxzZShOb3JtYWxpemVyLmlzTm9ybWFsaXplZCh0YXJnZXQsIE5vcm1hbGl6ZXIuRm9ybS5ORkQpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoTm9ybWFsaXplci5pc05vcm1hbGl6ZWQodGFyZ2V0LCBOb3JtYWxpemVyLkZvcm0uTkZLQykpOworICAgICAgICBhc3NlcnRGYWxzZShOb3JtYWxpemVyLmlzTm9ybWFsaXplZCh0YXJnZXQsIE5vcm1hbGl6ZXIuRm9ybS5ORktEKSk7CisKKyAgICAgICAgdGFyZ2V0ID0gbmV3IFN0cmluZyhuZXcgY2hhcltdIHsweDAzRDIsIDB4MDMwMSwgMHgwM0QyLCAweDAzMDgsIDB4MDE3RiwgMHgwMzA3fSk7CisgICAgICAgIGFzc2VydEZhbHNlKE5vcm1hbGl6ZXIuaXNOb3JtYWxpemVkKHRhcmdldCwgTm9ybWFsaXplci5Gb3JtLk5GQykpOworICAgICAgICBhc3NlcnRUcnVlKE5vcm1hbGl6ZXIuaXNOb3JtYWxpemVkKHRhcmdldCwgTm9ybWFsaXplci5Gb3JtLk5GRCkpOworICAgICAgICBhc3NlcnRGYWxzZShOb3JtYWxpemVyLmlzTm9ybWFsaXplZCh0YXJnZXQsIE5vcm1hbGl6ZXIuRm9ybS5ORktDKSk7CisgICAgICAgIGFzc2VydEZhbHNlKE5vcm1hbGl6ZXIuaXNOb3JtYWxpemVkKHRhcmdldCwgTm9ybWFsaXplci5Gb3JtLk5GS0QpKTsKKworICAgICAgICB0YXJnZXQgPSBuZXcgU3RyaW5nKG5ldyBjaGFyW10gezB4MDM4RSwgMHgwM0FCLCAweDFFNjF9KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShOb3JtYWxpemVyLmlzTm9ybWFsaXplZCh0YXJnZXQsIE5vcm1hbGl6ZXIuRm9ybS5ORkMpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoTm9ybWFsaXplci5pc05vcm1hbGl6ZWQodGFyZ2V0LCBOb3JtYWxpemVyLkZvcm0uTkZEKSk7CisgICAgICAgIGFzc2VydFRydWUoTm9ybWFsaXplci5pc05vcm1hbGl6ZWQodGFyZ2V0LCBOb3JtYWxpemVyLkZvcm0uTkZLQykpOworICAgICAgICBhc3NlcnRGYWxzZShOb3JtYWxpemVyLmlzTm9ybWFsaXplZCh0YXJnZXQsIE5vcm1hbGl6ZXIuRm9ybS5ORktEKSk7CisKKyAgICAgICAgdGFyZ2V0ID0gbmV3IFN0cmluZyhuZXcgY2hhcltdIHsweDAzQTUsIDB4MDMwMSwgMHgwM0E1LCAweDAzMDgsIDB4MDA3MywgMHgwMzA3fSk7CisgICAgICAgIGFzc2VydEZhbHNlKE5vcm1hbGl6ZXIuaXNOb3JtYWxpemVkKHRhcmdldCwgTm9ybWFsaXplci5Gb3JtLk5GQykpOworICAgICAgICBhc3NlcnRUcnVlKE5vcm1hbGl6ZXIuaXNOb3JtYWxpemVkKHRhcmdldCwgTm9ybWFsaXplci5Gb3JtLk5GRCkpOworICAgICAgICBhc3NlcnRGYWxzZShOb3JtYWxpemVyLmlzTm9ybWFsaXplZCh0YXJnZXQsIE5vcm1hbGl6ZXIuRm9ybS5ORktDKSk7CisgICAgICAgIGFzc2VydFRydWUoTm9ybWFsaXplci5pc05vcm1hbGl6ZWQodGFyZ2V0LCBOb3JtYWxpemVyLkZvcm0uTkZLRCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOb3JtYWxpemVyLmlzTm9ybWFsaXplZChudWxsLCBOb3JtYWxpemVyLkZvcm0uTkZDKTsKKyAgICAgICAgICAgIGZhaWwoIkRpZCBub3QgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24gb24gbnVsbCBhcmd1bWVudCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBwYXNzCisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvTnVtYmVyRm9ybWF0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L051bWJlckZvcm1hdFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMjYyMWI0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L051bWJlckZvcm1hdFRlc3QuamF2YQpAQCAtMCwwICsxLDEwMSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdFN5bWJvbHM7CitpbXBvcnQgamF2YS50ZXh0LkZpZWxkUG9zaXRpb247CitpbXBvcnQgamF2YS50ZXh0Lk51bWJlckZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuUGFyc2VQb3NpdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Mb2NhbGU7CisKK3B1YmxpYyBjbGFzcyBOdW1iZXJGb3JtYXRUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICAvLyBOdW1iZXJGb3JtYXQuZm9ybWF0KE9iamVjdCwgU3RyaW5nQnVmZmVyLCBGaWVsZFBvc2l0aW9uKSBndWFyYW50ZWVzIGl0IGNhbGxzIGRvdWJsZVZhbHVlIGZvcgorICAgIC8vIGN1c3RvbSBOdW1iZXIgc3ViY2xhc3Nlcy4KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2N1c3RvbV9OdW1iZXJfZ2V0c19sb25nVmFsdWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2xhc3MgTXlOdW1iZXIgZXh0ZW5kcyBOdW1iZXIgeworICAgICAgICAgICAgcHVibGljIGJ5dGUgYnl0ZVZhbHVlKCkgeyB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsgfQorICAgICAgICAgICAgcHVibGljIGRvdWJsZSBkb3VibGVWYWx1ZSgpIHsgcmV0dXJuIDEyMzsgfQorICAgICAgICAgICAgcHVibGljIGZsb2F0IGZsb2F0VmFsdWUoKSB7IHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOyB9CisgICAgICAgICAgICBwdWJsaWMgaW50IGludFZhbHVlKCkgeyB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsgfQorICAgICAgICAgICAgcHVibGljIGxvbmcgbG9uZ1ZhbHVlKCkgeyB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsgfQorICAgICAgICAgICAgcHVibGljIHNob3J0IHNob3J0VmFsdWUoKSB7IHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOyB9CisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeyB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsgfQorICAgICAgICB9CisgICAgICAgIE51bWJlckZvcm1hdCBuZiA9IE51bWJlckZvcm1hdC5nZXROdW1iZXJJbnN0YW5jZShMb2NhbGUuVVMpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEyMyIsIG5mLmZvcm1hdChuZXcgTXlOdW1iZXIoKSkpOworICAgIH0KKworICAgIC8vIE51bWJlckZvcm1hdC5mb3JtYXQoT2JqZWN0LCBTdHJpbmdCdWZmZXIsIEZpZWxkUG9zaXRpb24pIGd1YXJhbnRlZXMgaXQgY2FsbHMgbG9uZ1ZhbHVlIGZvcgorICAgIC8vIGFueSBCaWdJbnRlZ2VyIHdpdGggYSBiaXRMZW5ndGggc3RyaWN0bHkgbGVzcyB0aGFuIDY0LgorICAgIHB1YmxpYyB2b2lkIHRlc3Rfc21hbGxfQmlnSW50ZWdlcl9nZXRzX2xvbmdWYWx1ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjbGFzcyBNeU51bWJlckZvcm1hdCBleHRlbmRzIE51bWJlckZvcm1hdCB7CisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGZvcm1hdChkb3VibGUgdmFsdWUsIFN0cmluZ0J1ZmZlciBiLCBGaWVsZFBvc2l0aW9uIGYpIHsKKyAgICAgICAgICAgICAgICBiLmFwcGVuZCgiZG91YmxlIik7CisgICAgICAgICAgICAgICAgcmV0dXJuIGI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGZvcm1hdChsb25nIHZhbHVlLCBTdHJpbmdCdWZmZXIgYiwgRmllbGRQb3NpdGlvbiBmKSB7CisgICAgICAgICAgICAgICAgYi5hcHBlbmQoImxvbmciKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gYjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyBOdW1iZXIgcGFyc2UoU3RyaW5nIHN0cmluZywgUGFyc2VQb3NpdGlvbiBwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgTnVtYmVyRm9ybWF0IG5mID0gbmV3IE15TnVtYmVyRm9ybWF0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygibG9uZyIsIG5mLmZvcm1hdChCaWdJbnRlZ2VyLnZhbHVlT2YoTG9uZy5NQVhfVkFMVUUpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZG91YmxlIiwgbmYuZm9ybWF0KEJpZ0ludGVnZXIudmFsdWVPZihMb25nLk1BWF9WQUxVRSkuYWRkKEJpZ0ludGVnZXIuT05FKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImxvbmciLCBuZi5mb3JtYXQoQmlnSW50ZWdlci52YWx1ZU9mKExvbmcuTUlOX1ZBTFVFKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvdWJsZSIsIG5mLmZvcm1hdChCaWdJbnRlZ2VyLnZhbHVlT2YoTG9uZy5NSU5fVkFMVUUpLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW50ZWdlckluc3RhbmNlX2FyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghU3VwcG9ydF9Mb2NhbGUuaXNMb2NhbGVBdmFpbGFibGUobmV3IExvY2FsZSgiYXIiKSkpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBOdW1iZXJGb3JtYXQgbnVtYmVyRm9ybWF0ID0gTnVtYmVyRm9ybWF0LmdldE51bWJlckluc3RhbmNlKG5ldyBMb2NhbGUoImFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiMsIyMwLiMjIzsjLCMjMC4jIyMtIiwgKChEZWNpbWFsRm9ybWF0KSBudW1iZXJGb3JtYXQpLnRvUGF0dGVybigpKTsKKyAgICAgICAgTnVtYmVyRm9ybWF0IGludGVnZXJGb3JtYXQgPSBOdW1iZXJGb3JtYXQuZ2V0SW50ZWdlckluc3RhbmNlKG5ldyBMb2NhbGUoImFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiMsIyMwOyMsIyMwLSIsICgoRGVjaW1hbEZvcm1hdCkgaW50ZWdlckZvcm1hdCkudG9QYXR0ZXJuKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbnVtYmVyTG9jYWxpemF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIExvY2FsZSBhcmFiaWMgPSBuZXcgTG9jYWxlKCJhciIpOworICAgICAgICBpZiAoIVN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKGFyYWJpYykpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBOdW1iZXJGb3JtYXQgbmYgPSBOdW1iZXJGb3JtYXQuZ2V0TnVtYmVySW5zdGFuY2UoYXJhYmljKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdcdTA2NjAnLCBuZXcgRGVjaW1hbEZvcm1hdFN5bWJvbHMoYXJhYmljKS5nZXRaZXJvRGlnaXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiXHUwNjYxXHUwNjZjXHUwNjYyXHUwNjYzXHUwNjY0XHUwNjZjXHUwNjY1XHUwNjY2XHUwNjY3XHUwNjZjXHUwNjY4XHUwNjY5XHUwNjYwIiwKKyAgICAgICAgICAgICAgICBuZi5mb3JtYXQoMTIzNDU2Nzg5MCkpOworICAgIH0KKworICAgIC8vIEZvcm1hdHRpbmcgcGVyY2VudGFnZXMgaXMgY29uZnVzaW5nIGJ1dCBkZWxpYmVyYXRlLgorICAgIC8vIEVuc3VyZSB3ZSBkb24ndCBhY2NpZGVudGFsbHkgImZpeCIgdGhpcy4KKyAgICBwdWJsaWMgdm9pZCB0ZXN0XzEwMzMzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE51bWJlckZvcm1hdCBuZiA9IE51bWJlckZvcm1hdC5nZXRQZXJjZW50SW5zdGFuY2UoTG9jYWxlLlVTKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxNSUiLCBuZi5mb3JtYXQoMC4xNSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEsNTAwJSIsIG5mLmZvcm1hdCgxNSkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmYuZm9ybWF0KCIxNSIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGRBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JBdHRyaWJ1dGVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1NTBmNDkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjEwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnZhbGlkT2JqZWN0RXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS50ZXh0LkF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcjsKKworCitwdWJsaWMgY2xhc3MgT2xkQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlVGVzdCBleHRlbmRzCisgICAgICAgIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIGNsYXNzIE1vY2tBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JBdHRyaWJ1dGUgZXh0ZW5kcworICAgICAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAgICAgcHVibGljIE1vY2tBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgIHN1cGVyKG5hbWUpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXROYW1lKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIE9iamVjdCByZWFkUmVzb2x2ZSgpIHRocm93cyBJbnZhbGlkT2JqZWN0RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5yZWFkUmVzb2x2ZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBUZXN0QXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlIGV4dGVuZHMKKyAgICAgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjkxNzYxMzM3MzkzNTc4NTE3OUw7CisKKyAgICAgICAgcHVibGljIFRlc3RBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgIHN1cGVyKG5hbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS50ZXh0LkF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUjQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqICAgICAgICBUZXN0IG9mIG1ldGhvZAorICAgICAqICAgICAgICBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSNBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlKGphdmEubGFuZy5TdHJpbmcpLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgTW9ja0F0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSgidGVzdCIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSNlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKiAgICAgICAgVGVzdCBvZiBtZXRob2QKKyAgICAgKiAgICAgICAgamF2YS50ZXh0LkF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUjZXF1YWxzKGphdmEubGFuZy5PYmplY3QpLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNb2NrQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlIG1hYzEgPSBuZXcgTW9ja0F0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSgKKyAgICAgICAgICAgICAgICAgICAgInRlc3QxIik7CisgICAgICAgICAgICBNb2NrQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlIG1hYzIgPSBuZXcgTW9ja0F0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSgKKyAgICAgICAgICAgICAgICAgICAgInRlc3QyIik7CisKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJBdHRyaWJ1dGVzIGFyZSBlcXVhbCIsIG1hYzIuZXF1YWxzKG1hYzEpKTsKKworICAgICAgICAgICAgVGVzdEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSBtYWMzID0gbmV3IFRlc3RBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JBdHRyaWJ1dGUoCisgICAgICAgICAgICAgICAgICAgICJ0ZXN0MSIpOworCisgICAgICAgICAgICBhc3NlcnRGYWxzZSgiQXR0cmlidXRlcyBhcmUgZXF1YWwiLCBtYWMzLmVxdWFscyhtYWMxKSk7CisKKyAgICAgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUgbWFjNCA9IG1hYzE7CisKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkF0dHJpYnV0ZXMgYXJlIG5vbi1lcXVhbCIsIG1hYzQuZXF1YWxzKG1hYzEpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS50ZXh0LkF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUjZ2V0TmFtZSgpIFRlc3Qgb2YKKyAgICAgKiAgICAgICAgbWV0aG9kIGphdmEudGV4dC5BdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlI2dldE5hbWUoKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE5hbWUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNb2NrQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlIG1hYzEgPSBuZXcgTW9ja0F0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSgKKyAgICAgICAgICAgICAgICAgICAgInRlc3QxIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhdHRyaWJ1dGUgbmFtZSIsICJ0ZXN0MSIsIG1hYzEuZ2V0TmFtZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS50ZXh0LkF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUjaGFzaENvZGUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGFzaENvZGUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNb2NrQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlIG1hYzEgPSBuZXcgTW9ja0F0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSgKKyAgICAgICAgICAgICAgICAgICAgInRlc3QxIik7CisgICAgICAgICAgICBUZXN0QXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlIG1hYzIgPSBuZXcgVGVzdEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSgKKyAgICAgICAgICAgICAgICAgICAgInRlc3QxIik7CisKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlRoZSBoYXNoIGNvZGVzIG9mIHNhbWUgYXR0cmlidXRlcyBhcmUgbm90IGVxdWFsIiwgbWFjMQorICAgICAgICAgICAgICAgICAgICAuaGFzaENvZGUoKSAhPSBtYWMyLmhhc2hDb2RlKCkpOworCisgICAgICAgICAgICBNb2NrQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlIG1hYzMgPSBuZXcgTW9ja0F0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSgKKyAgICAgICAgICAgICAgICAgICAgInRlc3QyIik7CisKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlRoZSBoYXNoIGNvZGVzIG9mIGRpZmZlcmVudCBhdHRyaWJ1dGVzIGFyZSBlcXVhbCIsIG1hYzEKKyAgICAgICAgICAgICAgICAgICAgLmhhc2hDb2RlKCkgIT0gbWFjMy5oYXNoQ29kZSgpKTsKKworICAgICAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSBtYWM0ID0gbWFjMTsKKworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGhhc2ggY29kZXMgb2Ygc2FtZSBhdHRyaWJ1dGVzIGJ1dCBkaWZmZXJlbnQgaGllcmFyY2h5IGNsYXNzZXMgYXJlIG5vdCBlcXVhbCIsCisgICAgICAgICAgICAgICAgICAgIG1hYzEuaGFzaENvZGUoKSA9PSBtYWM0Lmhhc2hDb2RlKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSNyZWFkUmVzb2x2ZSgpIFRlc3QKKyAgICAgKiAgICAgICAgb2YgbWV0aG9kCisgICAgICogICAgICAgIGphdmEudGV4dC5BdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlI3JlYWRSZXNvbHZlKCkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkUmVzb2x2ZSgpIHsKKyAgICAgICAgTW9ja0F0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSBtYWMxID0gbmV3IE1vY2tBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JBdHRyaWJ1dGUoCisgICAgICAgICAgICAgICAgInRlc3QiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1hYzEucmVhZFJlc29sdmUoKTsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWRPYmplY3RFeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkT2JqZWN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0gaW4gPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVzID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgb3V0ID0gbmV3IE9iamVjdE91dHB1dFN0cmVhbShieXRlcyk7CisKKyAgICAgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUgYXR0cjEsIGF0dHIyOworCisgICAgICAgICAgICBhdHRyMSA9IEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUuTEFOR1VBR0U7CisKKyAgICAgICAgICAgIG91dC53cml0ZU9iamVjdChhdHRyMSk7CisKKyAgICAgICAgICAgIGluID0gbmV3IE9iamVjdElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcworICAgICAgICAgICAgICAgICAgICAudG9CeXRlQXJyYXkoKSkpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGF0dHIyID0gKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUpIGluLnJlYWRPYmplY3QoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRTYW1lKCJyZXNvbHZlZCBpbmNvcnJlY3RseSIsIGF0dHIxLCBhdHRyMik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBJT0V4Y2VwdGlvbiIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIENsYXNzTm90Rm91bmRFeGNlcHRpb24iICsgZSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgaWYgKGluICE9IG51bGwpCisgICAgICAgICAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSN0b1N0cmluZygpIFRlc3Qgb2YKKyAgICAgKiAgICAgICAgbWV0aG9kIGphdmEudGV4dC5BdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlI3RvU3RyaW5nKCkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF90b1N0cmluZygpIHsKKyAgICAgICAgTW9ja0F0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSBtYWMxID0gbmV3IE1vY2tBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JBdHRyaWJ1dGUoCisgICAgICAgICAgICAgICAgbnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVW5leHBlY3RlZCBjbGFzcyByZXByZXNlbnRhdGlvbiBzdHJpbmciLCBtYWMxLnRvU3RyaW5nKCksCisgICAgICAgICAgICAgICAgZ2V0Q2xhc3MoKS5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiRNb2NrQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlKG51bGwpIik7CisgICAgICAgIFRlc3RBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JBdHRyaWJ1dGUgbWFjMiA9IG5ldyBUZXN0QXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlKAorICAgICAgICAgICAgICAgICJ0ZXN0MSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlVuZXhwZWN0ZWQgY2xhc3MgcmVwcmVzZW50YXRpb24gc3RyaW5nIiwgbWFjMi50b1N0cmluZygpLAorICAgICAgICAgICAgICAgIGdldENsYXNzKCkuZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgICAgICAgICArICIkVGVzdEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSh0ZXN0MSkiKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NDI0NjhiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvclRlc3QuamF2YQpAQCAtMCwwICsxLDIwOSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yOworaW1wb3J0IGphdmEudGV4dC5BdHRyaWJ1dGVkU3RyaW5nOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGl0OworICAgIFN0cmluZyBzdHJpbmcgPSAidGVzdCB0ZXN0IjsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UnVuTGltaXRMU2V0KCkgeworICAgICAgICBBdHRyaWJ1dGVkU3RyaW5nIGFzID0gbmV3IEF0dHJpYnV0ZWRTdHJpbmcoInRlc3QiKTsKKyAgICAgICAgYXMuYWRkQXR0cmlidXRlKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUuTEFOR1VBR0UsICJhIiwgMiwKKyAgICAgICAgICAgICAgICAzKTsKKyAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGl0ID0gYXMuZ2V0SXRlcmF0b3IoKTsKKyAgICAgICAgSGFzaFNldDxBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlPiAgYXR0ciA9CisgICAgICAgICAgICBuZXcgSGFzaFNldDxBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlPigpOworICAgICAgICBhdHRyLmFkZChBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlLkxBTkdVQUdFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub24tbnVsbCB2YWx1ZSBsaW1pdCIsCisgICAgICAgICAgICAgICAgMiwgaXQuZ2V0UnVuTGltaXQoYXR0cikpOworCisgICAgICAgIGFzID0gbmV3IEF0dHJpYnV0ZWRTdHJpbmcoInRlc3QiKTsKKyAgICAgICAgYXMuYWRkQXR0cmlidXRlKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUuTEFOR1VBR0UsIG51bGwsCisgICAgICAgICAgICAgICAgMiwgMyk7CisgICAgICAgIGl0ID0gYXMuZ2V0SXRlcmF0b3IoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJudWxsIHZhbHVlIGxpbWl0IiwKKyAgICAgICAgICAgICAgICA0LCBpdC5nZXRSdW5MaW1pdChhdHRyKSk7CisKKyAgICAgICAgYXR0ci5hZGQoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5SRUFESU5HKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJudWxsIHZhbHVlIGxpbWl0IiwKKyAgICAgICAgICAgICAgICA0LCBpdC5nZXRSdW5MaW1pdChhdHRyKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBbGxBdHRyaWJ1dGVLZXlzKCkgeworICAgICAgICBBdHRyaWJ1dGVkU3RyaW5nIGFzID0gbmV3IEF0dHJpYnV0ZWRTdHJpbmcoInRlc3QiKTsKKyAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGl0ID0gYXMuZ2V0SXRlcmF0b3IoKTsKKyAgICAgICAgU2V0PEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGU+IGVtcHR5QXR0cmlidXRlcyA9CisgICAgICAgICAgICBpdC5nZXRBbGxBdHRyaWJ1dGVLZXlzKCk7CisgICAgICAgIGFzc2VydFRydWUoZW1wdHlBdHRyaWJ1dGVzLmlzRW1wdHkoKSk7CisKKyAgICAgICAgaW50IGF0dHJDb3VudCA9IDEwOworICAgICAgICBmb3IoaW50IGkgPSAwIDsgaSA8IGF0dHJDb3VudDsgaSsrKSB7CisgICAgICAgICAgICBhcy5hZGRBdHRyaWJ1dGUoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5MQU5HVUFHRSwKKyAgICAgICAgICAgICAgICAgICAgImEiKTsKKyAgICAgICAgfQorICAgICAgICBpdCA9IGFzLmdldEl0ZXJhdG9yKCk7CisgICAgICAgIFNldDxBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlPiBhdHRyaWJ1dGVzID0KKyAgICAgICAgICAgIGl0LmdldEFsbEF0dHJpYnV0ZUtleXMoKTsKKyAgICAgICAgZm9yKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUgYXR0cjphdHRyaWJ1dGVzKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5MQU5HVUFHRSwgYXR0cik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEF0dHJpYnV0ZUxBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JfQXR0cmlidXRlKCkgeworCisgICAgICAgIE9iamVjdCBhdHRyaWJ1dGUgPQorICAgICAgICAgICAgaXQuZ2V0QXR0cmlidXRlKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUuTEFOR1VBR0UpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkVOR0xJU0giLCBhdHRyaWJ1dGUpOworCisgICAgICAgIGF0dHJpYnV0ZSA9CisgICAgICAgICAgICBpdC5nZXRBdHRyaWJ1dGUoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5SRUFESU5HKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSRUFEIiwgYXR0cmlidXRlKTsKKworICAgICAgICBhc3NlcnROdWxsKGl0LmdldEF0dHJpYnV0ZShBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuCisgICAgICAgICAgICAgICAgQXR0cmlidXRlLklOUFVUX01FVEhPRF9TRUdNRU5UKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBdHRyaWJ1dGVzKCkgeworICAgICAgICBNYXA8QXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSwgT2JqZWN0PiBhdHRyaWJ1dGVzID0KKyAgICAgICAgICAgIGl0LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGF0dHJpYnV0ZXMuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJFTkdMSVNIIiwKKyAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLmdldChBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlLkxBTkdVQUdFKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUkVBRCIsCisgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXQoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5SRUFESU5HKSk7CisKKyAgICAgICAgQXR0cmlidXRlZFN0cmluZyBhcyA9IG5ldyBBdHRyaWJ1dGVkU3RyaW5nKCJ0ZXN0Iik7CisgICAgICAgIGFzc2VydFRydWUoYXMuZ2V0SXRlcmF0b3IoKS5nZXRBdHRyaWJ1dGVzKCkuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFJ1bkxpbWl0KCkgeworICAgICAgICBpbnQgbGltaXQgPSBpdC5nZXRSdW5MaW1pdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoc3RyaW5nLmxlbmd0aCgpLCBsaW1pdCk7CisKKyAgICAgICAgQXR0cmlidXRlZFN0cmluZyBhcyA9IG5ldyBBdHRyaWJ1dGVkU3RyaW5nKCIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGFzLmdldEl0ZXJhdG9yKCkuZ2V0UnVuTGltaXQoKSk7CisKKyAgICAgICAgYXMgPSBuZXcgQXR0cmlidXRlZFN0cmluZyhuZXcgQXR0cmlidXRlZFN0cmluZygidGVzdCB0ZXh0IikuCisgICAgICAgICAgICAgICAgZ2V0SXRlcmF0b3IoKSwgMiwgNyk7CisKKyAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGl0ID0gYXMuZ2V0SXRlcmF0b3IoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIGl0LmdldFJ1bkxpbWl0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UnVuTGltaXRMQXR0cmlidXRlKCkgeworICAgICAgICBBdHRyaWJ1dGVkU3RyaW5nIGFzID0gbmV3IEF0dHJpYnV0ZWRTdHJpbmcoIiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYXMuZ2V0SXRlcmF0b3IoKS5nZXRSdW5MaW1pdCgKKyAgICAgICAgICAgICAgICBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlLkxBTkdVQUdFKSk7CisKKyAgICAgICAgYXMgPSBuZXcgQXR0cmlidXRlZFN0cmluZygidGV4dCIpOworICAgICAgICBhcy5hZGRBdHRyaWJ1dGUoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5MQU5HVUFHRSwKKyAgICAgICAgICAgICAgICAiRU5HTElTSCIpOworCisgICAgICAgIGFzLmFkZEF0dHJpYnV0ZShBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlLlJFQURJTkcsCisgICAgICAgICJSRUFEIiwgMSwgMyk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGFzLmdldEl0ZXJhdG9yKCkuZ2V0UnVuTGltaXQoCisgICAgICAgICAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5MQU5HVUFHRSkpOworCisgICAgICAgIGFzc2VydEVxdWFscygxLCBhcy5nZXRJdGVyYXRvcigpLmdldFJ1bkxpbWl0KAorICAgICAgICAgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUuUkVBRElORykpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UnVuU3RhcnQoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBpdC5nZXRSdW5TdGFydCgpKTsKKworICAgICAgICBBdHRyaWJ1dGVkU3RyaW5nIGFzID0gbmV3IEF0dHJpYnV0ZWRTdHJpbmcoIiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYXMuZ2V0SXRlcmF0b3IoKS5nZXRSdW5TdGFydCgpKTsKKworICAgICAgICBhcyA9IG5ldyBBdHRyaWJ1dGVkU3RyaW5nKG5ldyBBdHRyaWJ1dGVkU3RyaW5nKCJ0ZXN0IHRleHQiKS4KKyAgICAgICAgICAgICAgICBnZXRJdGVyYXRvcigpLCAyLCA3KTsKKworICAgICAgICBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgaXQgPSBhcy5nZXRJdGVyYXRvcigpOworCisgICAgICAgIGFzc2VydEVxdWFscygwLCBpdC5nZXRSdW5TdGFydCgpKTsKKworICAgICAgICBhcy5hZGRBdHRyaWJ1dGUoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5MQU5HVUFHRSwKKyAgICAgICAgICAgICAgICAiR0VSTUFOIiwgMSwgMik7CisgICAgICAgIGFzLmFkZEF0dHJpYnV0ZShBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlLlJFQURJTkcsCisgICAgICAgICAgICAgICAgIlJFQUQiLCAxLCAzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGFzLmdldEl0ZXJhdG9yKCkuZ2V0UnVuU3RhcnQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRSdW5TdGFydExBdHRyaWJ1dGUoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBpdC5nZXRSdW5TdGFydCgKKyAgICAgICAgICAgICAgICBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlLkxBTkdVQUdFKSk7CisKKyAgICAgICAgQXR0cmlidXRlZFN0cmluZyBhcyA9IG5ldyBBdHRyaWJ1dGVkU3RyaW5nKCJ0ZXN0IHRleHQiKTsKKyAgICAgICAgYXMuYWRkQXR0cmlidXRlKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUuTEFOR1VBR0UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdFUk1BTiIsIDIsIDUpOworICAgICAgICBhcy5hZGRBdHRyaWJ1dGUoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5SRUFESU5HLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSRUFEIiwgMiwgNyk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGFzLmdldEl0ZXJhdG9yKCkuZ2V0UnVuU3RhcnQoCisgICAgICAgICAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5MQU5HVUFHRSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYXMuZ2V0SXRlcmF0b3IoKS5nZXRSdW5TdGFydCgKKyAgICAgICAgICAgICAgICBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlLlJFQURJTkcpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFJ1blN0YXJ0TGphdmFfdXRpbF9TZXQoKSB7CisgICAgICAgIEF0dHJpYnV0ZWRTdHJpbmcgYXMgPSBuZXcgQXR0cmlidXRlZFN0cmluZygidGVzdCIpOworICAgICAgICBhcy5hZGRBdHRyaWJ1dGUoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5MQU5HVUFHRSwgImEiLCAyLAorICAgICAgICAgICAgICAgIDMpOworICAgICAgICBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgaXQgPSBhcy5nZXRJdGVyYXRvcigpOworICAgICAgICBIYXNoU2V0PEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGU+ICBhdHRyID0KKyAgICAgICAgICAgIG5ldyBIYXNoU2V0PEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGU+KCk7CisgICAgICAgIGF0dHIuYWRkKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUuTEFOR1VBR0UpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaXQuZ2V0UnVuU3RhcnQoYXR0cikpOworCisgICAgICAgIGFzID0gbmV3IEF0dHJpYnV0ZWRTdHJpbmcoInRlc3QiKTsKKyAgICAgICAgYXMuYWRkQXR0cmlidXRlKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUuTEFOR1VBR0UsCisgICAgICAgICAgICAgICAgIkVOR0xJU0giLDEsIDMpOworICAgICAgICBpdCA9IGFzLmdldEl0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBpdC5nZXRSdW5TdGFydChhdHRyKSk7CisKKyAgICAgICAgYXR0ci5hZGQoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5SRUFESU5HKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGl0LmdldFJ1blN0YXJ0KGF0dHIpKTsKKworCisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisKKyAgICAgICAgQXR0cmlidXRlZFN0cmluZyBhcyA9IG5ldyBBdHRyaWJ1dGVkU3RyaW5nKHN0cmluZyk7CisKKyAgICAgICAgYXMuYWRkQXR0cmlidXRlKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUuTEFOR1VBR0UsCisgICAgICAgICAgICAgICAgIkdFUk1BTiIpOworICAgICAgICBhcy5hZGRBdHRyaWJ1dGUoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5SRUFESU5HLAorICAgICAgICAgICAgICAgICJSRUFEIik7CisgICAgICAgIGFzLmFkZEF0dHJpYnV0ZShBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlLkxBTkdVQUdFLAorICAgICAgICAgICAgICAgICJFTkdMSVNIIik7CisKKyAgICAgICAgaXQgPSBhcy5nZXRJdGVyYXRvcigpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGRBdHRyaWJ1dGVkU3RyaW5nVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZEF0dHJpYnV0ZWRTdHJpbmdUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODlmNmYxMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGRBdHRyaWJ1dGVkU3RyaW5nVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTAyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yOworaW1wb3J0IGphdmEudGV4dC5BdHRyaWJ1dGVkU3RyaW5nOworaW1wb3J0IGphdmEudGV4dC5DaGFyYWN0ZXJJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7CitpbXBvcnQgamF2YS51dGlsLldlYWtIYXNoTWFwOworCitwdWJsaWMgY2xhc3MgT2xkQXR0cmlidXRlZFN0cmluZ1Rlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgc3RhdGljIHZvaWQgYXNzZXJ0RXF1YWxTdHJpbmcgKFN0cmluZyBtc2csIFN0cmluZyBleHBlY3RlZCwgQXR0cmlidXRlZFN0cmluZyBhdHRyU3RyaW5nKSB7CisgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBpdCA9IGF0dHJTdHJpbmcuZ2V0SXRlcmF0b3IoKTsKKyAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgYnVmLmFwcGVuZChpdC5maXJzdCgpKTsKKyAgICAgICAgY2hhciBjaDsKKyAgICAgICAgd2hpbGUgKChjaCA9IGl0Lm5leHQoKSkgIT0gQ2hhcmFjdGVySXRlcmF0b3IuRE9ORSkKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoY2gpOworICAgICAgICBhc3NlcnRFcXVhbHMobXNnLCBleHBlY3RlZCwgYnVmLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yXzEoKSB7CisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gIlRlc3Qgc3RyaW5nIjsKKyAgICAgICAgQXR0cmlidXRlZFN0cmluZyBhdHRyU3RyaW5nID0gbmV3IEF0dHJpYnV0ZWRTdHJpbmcodGVzdFN0cmluZyk7CisgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBpdGVyID0gYXR0clN0cmluZy5nZXRJdGVyYXRvcigpOworICAgICAgICBBdHRyaWJ1dGVkU3RyaW5nIGF0dHJTdHJpbmcyID0gbmV3IEF0dHJpYnV0ZWRTdHJpbmcoaXRlcik7CisgICAgICAgIGFzc2VydEVxdWFsU3RyaW5nKCJTdHJpbmcgbXVzdCBtYXRjaCEiLCB0ZXN0U3RyaW5nLCBhdHRyU3RyaW5nMik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JfMigpIHsKKyAgICAgICAgU3RyaW5nIHRlc3RTdHJpbmcgPSAiVGVzdCBzdHJpbmciOworICAgICAgICBBdHRyaWJ1dGVkU3RyaW5nIGF0dHJTdHJpbmcgPSBuZXcgQXR0cmlidXRlZFN0cmluZyh0ZXN0U3RyaW5nKTsKKyAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGl0ZXIgPSBhdHRyU3RyaW5nLmdldEl0ZXJhdG9yKCk7CisgICAgICAgIEF0dHJpYnV0ZWRTdHJpbmcgYXR0clN0cmluZzIgPSBuZXcgQXR0cmlidXRlZFN0cmluZyhpdGVyLCAyLCA3KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxTdHJpbmcoIlN0cmluZyBtdXN0IG1hdGNoISIsICJzdCBzdCIsIGF0dHJTdHJpbmcyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnRleHQuQXR0cmlidXRlZFN0cmluZyNBdHRyaWJ1dGVkU3RyaW5nKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciwKKyAgICAgKiAgICAgICAgaW50LCBpbnQpIFRlc3Qgb2YgbWV0aG9kCisgICAgICogICAgICAgIGphdmEudGV4dC5BdHRyaWJ1dGVkU3RyaW5nI0F0dHJpYnV0ZWRTdHJpbmcoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLAorICAgICAqICAgICAgICBpbnQsIGludCkuIENhc2UgMTogVHJ5IHRvIGNvbnNydWN0IEF0dHJpYnV0ZWRTdHJpbmcuIENhc2UgMjogVHJ5CisgICAgICogICAgICAgIHRvIGNvbnNydWN0IEF0dHJpYnV0ZWRTdHJpbmcgdXNpbmcgaW5jb3JyZWN0IGJlZ2luSW5kZXguIENhc2UgMzoKKyAgICAgKiAgICAgICAgVHJ5IHRvIGNvbnNydWN0IEF0dHJpYnV0ZWRTdHJpbmcgdXNpbmcgaW5jb3JyZWN0IGVuZEluZGV4LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9ySUkoKSB7CisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMTM1NQorCisgICAgICAgIC8vIGNhc2UgMTogVHJ5IHRvIGNvbnNydWN0IEF0dHJpYnV0ZWRTdHJpbmcuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgQXR0cmlidXRlZFN0cmluZyhuZXcgdGVzdEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcigpLCAwLCAwKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gY2FzZSAyOiBUcnkgdG8gY29uc3J1Y3QgQXR0cmlidXRlZFN0cmluZyB1c2luZyBpbmNvcnJlY3QgYmVnaW5JbmRleC4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGVkU3RyaW5nKG5ldyB0ZXN0QXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yKCksIC0xLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNhc2UgMzogVHJ5IHRvIGNvbnNydWN0IEF0dHJpYnV0ZWRTdHJpbmcgdXNpbmcgaW5jb3JyZWN0IGVuZEluZGV4LgorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEF0dHJpYnV0ZWRTdHJpbmcobmV3IHRlc3RBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IoKSwgMCwgLTEpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JfMygpIHsKKyAgICAgICAgU3RyaW5nIHRlc3RTdHJpbmcgPSAiVGVzdCBzdHJpbmciOworICAgICAgICBBdHRyaWJ1dGVkU3RyaW5nIGF0dHJTdHJpbmcgPSBuZXcgQXR0cmlidXRlZFN0cmluZyh0ZXN0U3RyaW5nKTsKKyAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGl0ZXIgPSBhdHRyU3RyaW5nLmdldEl0ZXJhdG9yKCk7CisgICAgICAgIEF0dHJpYnV0ZWRTdHJpbmcgYXR0clN0cmluZzI7CisKKyAgICAgICAgYXR0clN0cmluZzIgPSBuZXcgQXR0cmlidXRlZFN0cmluZyhpdGVyLCAyLCA3LCBuZXcgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZVtdIHt9KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxTdHJpbmcoIlN0cmluZyBtdXN0IG1hdGNoISIsICJzdCBzdCIsIGF0dHJTdHJpbmcyKTsKKworICAgICAgICBhdHRyU3RyaW5nMiA9IG5ldyBBdHRyaWJ1dGVkU3RyaW5nKGl0ZXIsIDIsIDcsIG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbFN0cmluZygiU3RyaW5nIG11c3QgbWF0Y2ghIiwgInN0IHN0IiwgYXR0clN0cmluZzIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudGV4dC5BdHRyaWJ1dGVkU3RyaW5nI0F0dHJpYnV0ZWRTdHJpbmcoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLAorICAgICAqICAgICAgICBpbnQsIGludCwgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZVtdKSBUZXN0IG9mIG1ldGhvZAorICAgICAqICAgICAgICBqYXZhLnRleHQuQXR0cmlidXRlZFN0cmluZyNBdHRyaWJ1dGVkU3RyaW5nKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciwKKyAgICAgKiAgICAgICAgaW50LCBpbnQsIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGVbXSkuIENhc2UgMTogVHJ5IHRvCisgICAgICogICAgICAgIGNvbnNydWN0IEF0dHJpYnV0ZWRTdHJpbmcuIENhc2UgMjogVHJ5IHRvIGNvbnNydWN0CisgICAgICogICAgICAgIEF0dHJpYnV0ZWRTdHJpbmcgdXNpbmcgaW5jb3JyZWN0IGJlZ2luSW5kZXguIENhc2UgMzogVHJ5IHRvCisgICAgICogICAgICAgIGNvbnNydWN0IEF0dHJpYnV0ZWRTdHJpbmcgdXNpbmcgaW5jb3JyZWN0IGVuZEluZGV4LiBDYXNlIDQ6IFRyeSB0bworICAgICAqICAgICAgICBjb25zcnVjdCBBdHRyaWJ1dGVkU3RyaW5nIHVzaW5nIHNwZWNpZmllZCBhdHRyaWJ1dGVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9ySUkkTGphdmFfdGV4dF9BdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IkQXR0cmlidXRlKCkgeworICAgICAgICAvLyBjYXNlIDE6IFRyeSB0byBjb25zcnVjdCBBdHRyaWJ1dGVkU3RyaW5nLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEF0dHJpYnV0ZWRTdHJpbmcobmV3IHRlc3RBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IoKSwgMCwgMCwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNhc2UgMjogVHJ5IHRvIGNvbnNydWN0IEF0dHJpYnV0ZWRTdHJpbmcgdXNpbmcgaW5jb3JyZWN0IGJlZ2luSW5kZXguCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgQXR0cmlidXRlZFN0cmluZyhuZXcgdGVzdEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcigpLCAtMSwgMCwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBjYXNlIDM6IFRyeSB0byBjb25zcnVjdCBBdHRyaWJ1dGVkU3RyaW5nIHVzaW5nIGluY29ycmVjdCBlbmRJbmRleC4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGVkU3RyaW5nKG5ldyB0ZXN0QXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yKCksIDAsIC0xLAorICAgICAgICAgICAgICAgICAgICBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNhc2UgNDogVHJ5IHRvIGNvbnNydWN0IEF0dHJpYnV0ZWRTdHJpbmcgdXNpbmcgc3BlY2lmaWVkIGF0dHJpYnV0ZXMuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlW10gYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlWzFdOworICAgICAgICAgICAgYXR0cmlidXRlc1swXSA9IG5ldyBUZXN0QXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlKCJ0ZXN0Iik7CisgICAgICAgICAgICBuZXcgQXR0cmlidXRlZFN0cmluZyhuZXcgdGVzdEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvcigpLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhwZWN0ZWQgIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnRleHQuQXR0cmlidXRlZFN0cmluZyNBdHRyaWJ1dGVkU3RyaW5nKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciwKKyAgICAgKiAgICAgICAgaW50LCBpbnQsIE1hcDw/IGV4dGVuZHMgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSw/PikKKyAgICAgKiAgICAgICAgVGVzdCBvZiBtZXRob2QKKyAgICAgKiAgICAgICAgamF2YS50ZXh0LkF0dHJpYnV0ZWRTdHJpbmcjQXR0cmlidXRlZFN0cmluZyhBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IsCisgICAgICogICAgICAgIGludCwgaW50LCBNYXA8PyBleHRlbmRzCisgICAgICogICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUsPz4pLiBDYXNlIDE6IFRyeSB0bworICAgICAqICAgICAgICBjb25zdHJ1Y3QgQXR0cmlidXRlZFN0cmluZy4gQ2FzZSAyOiBUcnkgdG8gY29uc3RydWN0CisgICAgICogICAgICAgIEF0dHJpYnV0ZWRTdHJpbmcgdXNpbmcgMC1sZW5ndGggdGV4dCBhbmQgbm90IGFuIGVtcHR5IE1hcAorICAgICAqICAgICAgICBhdHRyaWJ1dGVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZ0xqYXZhX3V0aWxfTWFwKCkgeworICAgICAgICBTdHJpbmcgdGVzdCA9ICJUZXN0IHN0cmluZyI7CisKKyAgICAgICAgLy8gY2FzZSAxOiBUcnkgdG8gY29uc3RydWN0IEF0dHJpYnV0ZWRTdHJpbmcKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEF0dHJpYnV0ZWRTdHJpbmcgYXR0clN0cmluZyA9IG5ldyBBdHRyaWJ1dGVkU3RyaW5nKAorICAgICAgICAgICAgICAgICAgICB0ZXN0LAorICAgICAgICAgICAgICAgICAgICBuZXcgV2Vha0hhc2hNYXA8QXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSwgU3RyaW5nPigpKTsKKyAgICAgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBpdCA9IGF0dHJTdHJpbmcuZ2V0SXRlcmF0b3IoKTsKKyAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgICAgICBidWYuYXBwZW5kKGl0LmZpcnN0KCkpOworICAgICAgICAgICAgY2hhciBjaDsKKyAgICAgICAgICAgIHdoaWxlICgoY2ggPSBpdC5uZXh0KCkpICE9IENoYXJhY3Rlckl0ZXJhdG9yLkRPTkUpCisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChjaCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBzdHJpbmc6ICIgKyBidWYsIGJ1Zi50b1N0cmluZygpLmVxdWFscyh0ZXN0KSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNhc2UgMjogVHJ5IHRvIGNvbnN0cnVjdCBBdHRyaWJ1dGVkU3RyaW5nIHVzaW5nIDAtbGVuZ3RoIHRleHQgYW5kCisgICAgICAgIC8vIG5vdCBhbiBlbXB0eSBNYXAgYXR0cmlidXRlcy4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE1hcDxBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlLCBTdHJpbmc+IHdobSA9IG5ldyBXZWFrSGFzaE1hcDxBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlLCBTdHJpbmc+KCk7CisgICAgICAgICAgICB3aG0ucHV0KG5ldyBUZXN0QXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlKCJ0ZXN0IiksCisgICAgICAgICAgICAgICAgICAgICJ2YWx1ZSIpOworICAgICAgICAgICAgbmV3IEF0dHJpYnV0ZWRTdHJpbmcoIiIsIHdobSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIFRlc3RBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JBdHRyaWJ1dGUgZXh0ZW5kcworICAgICAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yOTE3NjEzMzczOTM1Nzg1MTc5TDsKKworICAgICAgICBwdWJsaWMgVGVzdEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZShTdHJpbmcgbmFtZSkgeworICAgICAgICAgICAgc3VwZXIobmFtZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIHRlc3RBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgaW1wbGVtZW50cworICAgICAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIHsKKyAgICAgICAgcHVibGljIFNldCBnZXRBbGxBdHRyaWJ1dGVLZXlzKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IGdldEF0dHJpYnV0ZShBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlIHApIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE1hcCBnZXRBdHRyaWJ1dGVzKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldFJ1bkxpbWl0KFNldCBwKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0UnVuTGltaXQoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSBwKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0UnVuTGltaXQoKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0UnVuU3RhcnQoU2V0IHApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXRSdW5TdGFydChBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlIHApIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXRSdW5TdGFydCgpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXRJbmRleCgpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXRFbmRJbmRleCgpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXRCZWdpbkluZGV4KCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgY2hhciBzZXRJbmRleChpbnQgcCkgeworICAgICAgICAgICAgcmV0dXJuICdhJzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBjaGFyIHByZXZpb3VzKCkgeworICAgICAgICAgICAgcmV0dXJuICdhJzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBjaGFyIG5leHQoKSB7CisgICAgICAgICAgICByZXR1cm4gJ2EnOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGNoYXIgY3VycmVudCgpIHsKKyAgICAgICAgICAgIHJldHVybiAnYSc7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgY2hhciBsYXN0KCkgeworICAgICAgICAgICAgcmV0dXJuICdhJzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBjaGFyIGZpcnN0KCkgeworICAgICAgICAgICAgcmV0dXJuICdhJzsKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZEF0dHJpYnV0ZUxqYXZhX3RleHRfQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yJEF0dHJpYnV0ZUxqYXZhX2xhbmdfT2JqZWN0SUkoKSB7CisgICAgICAgIEF0dHJpYnV0ZWRTdHJpbmcgYXMgPSBuZXcgQXR0cmlidXRlZFN0cmluZygidGVzdCIpOworICAgICAgICBhcy5hZGRBdHRyaWJ1dGUoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5MQU5HVUFHRSwgImEiLCAyLAorICAgICAgICAgICAgICAgIDMpOworICAgICAgICBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgaXQgPSBhcy5nZXRJdGVyYXRvcigpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5vbi1udWxsIHZhbHVlIGxpbWl0IiwgMiwgaXQKKyAgICAgICAgICAgICAgICAuZ2V0UnVuTGltaXQoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5MQU5HVUFHRSkpOworCisgICAgICAgIGFzID0gbmV3IEF0dHJpYnV0ZWRTdHJpbmcoInRlc3QiKTsKKyAgICAgICAgYXMuYWRkQXR0cmlidXRlKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUuTEFOR1VBR0UsIG51bGwsCisgICAgICAgICAgICAgICAgMiwgMyk7CisgICAgICAgIGl0ID0gYXMuZ2V0SXRlcmF0b3IoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJudWxsIHZhbHVlIGxpbWl0IiwgNCwgaXQKKyAgICAgICAgICAgICAgICAuZ2V0UnVuTGltaXQoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5MQU5HVUFHRSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcyA9IG5ldyBBdHRyaWJ1dGVkU3RyaW5nKCJ0ZXN0Iik7CisgICAgICAgICAgICBhcy5hZGRBdHRyaWJ1dGUoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZS5MQU5HVUFHRSwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCwgLTEsIDMpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gcmVncmVzc2lvbiBmb3IgSGFybW9ueS0xMjQ0CisgICAgICAgIGFzID0gbmV3IEF0dHJpYnV0ZWRTdHJpbmcoIjEyMyIsIG5ldyBXZWFrSGFzaE1hcCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzLmFkZEF0dHJpYnV0ZShudWxsLCBuZXcgVHJlZVNldCgpLCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzLmFkZEF0dHJpYnV0ZShudWxsLCBuZXcgVHJlZVNldCgpLCAtMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudGV4dC5BdHRyaWJ1dGVkU3RyaW5nLmFkZEF0dHJpYnV0ZShBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IsCisgICAgICogICAgICAgIE9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZEF0dHJpYnV0ZUxqYXZhX3RleHRfQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yJEF0dHJpYnV0ZUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyByZWdyZXNzaW9uIGZvciBIYXJtb255LTEyNDQKKyAgICAgICAgQXR0cmlidXRlZFN0cmluZyBhcyA9IG5ldyBBdHRyaWJ1dGVkU3RyaW5nKCIxMjMiLCBuZXcgV2Vha0hhc2hNYXAoKSk7CisKKyAgICAgICAgYXMuYWRkQXR0cmlidXRlKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUuTEFOR1VBR0UsICJlbmdsaXNoIik7CisgICAgICAgIGFzLmFkZEF0dHJpYnV0ZShBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlLklOUFVUX01FVEhPRF9TRUdNRU5ULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpbnB1dCBtZXRob2QiKTsKKyAgICAgICAgYXMuYWRkQXR0cmlidXRlKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUuUkVBRElORywgInJlYWRpbmciKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXMuYWRkQXR0cmlidXRlKG51bGwsIG5ldyBUcmVlU2V0KCkpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzLmFkZEF0dHJpYnV0ZShudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS50ZXh0LkF0dHJpYnV0ZWRTdHJpbmcjYWRkQXR0cmlidXRlcyhNYXA8PyBleHRlbmRzCisgICAgICogICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUsPz4sIGludCwgaW50KSBUZXN0cyBvZgorICAgICAqICAgICAgICBtZXRob2QgamF2YS50ZXh0LkF0dHJpYnV0ZWRTdHJpbmcjYWRkQXR0cmlidXRlcyhNYXA8PyBleHRlbmRzCisgICAgICogICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUsPz4sIGludCwgaW50KS4gQ2FzZSAxOiBUcnkKKyAgICAgKiAgICAgICAgdG8gYWRkIGF0dHJpYnV0ZXMgdG8gQXR0cmlidXRlc1N0cmluZy4gQ2FzZSAyOiBUcnkgdG8gYWRkCisgICAgICogICAgICAgIG51bGwtYXR0cmlidXRlcyB0byBBdHRyaWJ1dGVzU3RyaW5nLiBDYXNlIDM6IFRyeSB0byBhZGQgYXR0cmlidXRlcworICAgICAqICAgICAgICB0byBBdHRyaWJ1dGVzU3RyaW5nIHVzaW5nIGluY29ycmVjdCBpbmRleC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZEF0dHJpYnV0ZXNMamF2YV91dGlsX01hcElJKCkgeworICAgICAgICBBdHRyaWJ1dGVkU3RyaW5nIGFzID0gbmV3IEF0dHJpYnV0ZWRTdHJpbmcoInRlc3QiKTsKKyAgICAgICAgTWFwPEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUsIFN0cmluZz4gd2htID0gbmV3IFdlYWtIYXNoTWFwPEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUsIFN0cmluZz4oKTsKKworICAgICAgICAvLyBjYXNlIDE6IFRyeSB0byBhZGQgYXR0cmlidXRlcyB0byBBdHRyaWJ1dGVzU3RyaW5nLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgd2htLnB1dChuZXcgVGVzdEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSgidGVzdDEiKSwKKyAgICAgICAgICAgICAgICAgICAgInZhbHVlMSIpOworICAgICAgICAgICAgd2htLnB1dChuZXcgVGVzdEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSgidGVzdDIiKSwKKyAgICAgICAgICAgICAgICAgICAgInZhbHVlMiIpOworICAgICAgICAgICAgd2htLnB1dChuZXcgVGVzdEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSgidGVzdDMiKSwKKyAgICAgICAgICAgICAgICAgICAgInZhbHVlMyIpOworICAgICAgICAgICAgYXMuYWRkQXR0cmlidXRlcyh3aG0sIDAsIDMpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBjYXNlIDI6IFRyeSB0byBhZGQgbnVsbC1hdHRyaWJ1dGVzIHRvIEF0dHJpYnV0ZXNTdHJpbmcuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcy5hZGRBdHRyaWJ1dGVzKG51bGwsIDAsIDMpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNhc2UgMzogVHJ5IHRvIGFkZCBhdHRyaWJ1dGVzIHRvIEF0dHJpYnV0ZXNTdHJpbmcgdXNpbmcgaW5jb3JyZWN0CisgICAgICAgIC8vIGluZGV4LgorICAgICAgICB0cnkgeworICAgICAgICAgICAgYXMuYWRkQXR0cmlidXRlcyh3aG0sIDAsIDApOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS50ZXh0LkF0dHJpYnV0ZWRTdHJpbmcjZ2V0SXRlcmF0b3IoKSBUZXN0IG9mIG1ldGhvZAorICAgICAqICAgICAgICBqYXZhLnRleHQuQXR0cmlidXRlZFN0cmluZyNnZXRJdGVyYXRvcigpLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SXRlcmF0b3IoKSB7CisgICAgICAgIFN0cmluZyB0ZXN0ID0gIlRlc3Qgc3RyaW5nIjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEF0dHJpYnV0ZWRTdHJpbmcgYXR0clN0cmluZyA9IG5ldyBBdHRyaWJ1dGVkU3RyaW5nKHRlc3QpOworICAgICAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGl0ID0gYXR0clN0cmluZy5nZXRJdGVyYXRvcigpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgaXRlcmF0aW9uIG9uIEF0dHJpYnV0ZWRTdHJpbmciLCBpdC5maXJzdCgpLAorICAgICAgICAgICAgICAgICAgICB0ZXN0LmNoYXJBdCgwKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudGV4dC5BdHRyaWJ1dGVkU3RyaW5nI2dldEl0ZXJhdG9yKEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGVbXSkKKyAgICAgKiAgICAgICAgVGVzdCBvZiBtZXRob2QKKyAgICAgKiAgICAgICAgamF2YS50ZXh0LkF0dHJpYnV0ZWRTdHJpbmcjZ2V0SXRlcmF0b3IoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZVtdKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEl0ZXJhdG9yJExqYXZhX3RleHRfQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yJEF0dHJpYnV0ZSgpIHsKKyAgICAgICAgU3RyaW5nIHRlc3QgPSAiVGVzdCBzdHJpbmciOworICAgICAgICB0cnkgeworICAgICAgICAgICAgTWFwPEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUsIFN0cmluZz4gaG0gPSBuZXcgSGFzaE1hcDxBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlLCBTdHJpbmc+KCk7CisgICAgICAgICAgICBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlW10gYWNpID0gbmV3IEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGVbM107CisgICAgICAgICAgICBhY2lbMF0gPSBuZXcgVGVzdEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSgiYXR0MSIpOworICAgICAgICAgICAgYWNpWzFdID0gbmV3IFRlc3RBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JBdHRyaWJ1dGUoImF0dDIiKTsKKyAgICAgICAgICAgIGFjaVsyXSA9IG5ldyBUZXN0QXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlKCJhdHQzIik7CisgICAgICAgICAgICBobS5wdXQoYWNpWzBdLCAidmFsdWUxIik7CisgICAgICAgICAgICBobS5wdXQoYWNpWzFdLCAidmFsdWUyIik7CisKKyAgICAgICAgICAgIEF0dHJpYnV0ZWRTdHJpbmcgYXR0clN0cmluZyA9IG5ldyBBdHRyaWJ1dGVkU3RyaW5nKHRlc3QsIGhtKTsKKyAgICAgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciBpdCA9IGF0dHJTdHJpbmcuZ2V0SXRlcmF0b3IoYWNpKTsKKworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGl0ZXJhdGlvbiBvbiBBdHRyaWJ1dGVkU3RyaW5nIiwgaXQKKyAgICAgICAgICAgICAgICAgICAgLmdldEF0dHJpYnV0ZShhY2lbMF0pLmVxdWFscygidmFsdWUxIikpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGl0ZXJhdGlvbiBvbiBBdHRyaWJ1dGVkU3RyaW5nIiwgaXQKKyAgICAgICAgICAgICAgICAgICAgLmdldEF0dHJpYnV0ZShhY2lbMV0pLmVxdWFscygidmFsdWUyIikpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGl0ZXJhdGlvbiBvbiBBdHRyaWJ1dGVkU3RyaW5nIiwgaXQKKyAgICAgICAgICAgICAgICAgICAgLmdldEF0dHJpYnV0ZShhY2lbMl0pID09IG51bGwpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnRleHQuQXR0cmlidXRlZFN0cmluZyNnZXRJdGVyYXRvcihBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlW10sCisgICAgICogICAgICAgIGludCwgaW50KSBUZXN0IG9mIG1ldGhvZAorICAgICAqICAgICAgICBqYXZhLnRleHQuQXR0cmlidXRlZFN0cmluZyNnZXRJdGVyYXRvcihBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IuQXR0cmlidXRlW10sCisgICAgICogICAgICAgIGludCwgaW50KS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEl0ZXJhdG9yJExqYXZhX3RleHRfQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yJEF0dHJpYnV0ZUlJKCkgeworICAgICAgICBTdHJpbmcgdGVzdCA9ICJUZXN0IHN0cmluZyI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNYXA8QXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSwgU3RyaW5nPiBobSA9IG5ldyBIYXNoTWFwPEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGUsIFN0cmluZz4oKTsKKyAgICAgICAgICAgIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvci5BdHRyaWJ1dGVbXSBhY2kgPSBuZXcgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZVszXTsKKyAgICAgICAgICAgIGFjaVswXSA9IG5ldyBUZXN0QXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yQXR0cmlidXRlKCJhdHQxIik7CisgICAgICAgICAgICBhY2lbMV0gPSBuZXcgVGVzdEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvckF0dHJpYnV0ZSgiYXR0MiIpOworICAgICAgICAgICAgYWNpWzJdID0gbmV3IFRlc3RBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3JBdHRyaWJ1dGUoImF0dDMiKTsKKyAgICAgICAgICAgIGhtLnB1dChhY2lbMF0sICJ2YWx1ZTEiKTsKKyAgICAgICAgICAgIGhtLnB1dChhY2lbMV0sICJ2YWx1ZTIiKTsKKworICAgICAgICAgICAgQXR0cmlidXRlZFN0cmluZyBhdHRyU3RyaW5nID0gbmV3IEF0dHJpYnV0ZWRTdHJpbmcodGVzdCk7CisgICAgICAgICAgICBhdHRyU3RyaW5nLmFkZEF0dHJpYnV0ZXMoaG0sIDIsIDQpOworICAgICAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGl0ID0gYXR0clN0cmluZy5nZXRJdGVyYXRvcihhY2ksIDEsIDUpOworCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgaXRlcmF0aW9uIG9uIEF0dHJpYnV0ZWRTdHJpbmciLCBpdAorICAgICAgICAgICAgICAgICAgICAuZ2V0QXR0cmlidXRlKGFjaVswXSkgPT0gbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgaXRlcmF0aW9uIG9uIEF0dHJpYnV0ZWRTdHJpbmciLCBpdAorICAgICAgICAgICAgICAgICAgICAuZ2V0QXR0cmlidXRlKGFjaVsxXSkgPT0gbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgaXRlcmF0aW9uIG9uIEF0dHJpYnV0ZWRTdHJpbmciLCBpdAorICAgICAgICAgICAgICAgICAgICAuZ2V0QXR0cmlidXRlKGFjaVsyXSkgPT0gbnVsbCk7CisKKyAgICAgICAgICAgIGl0Lm5leHQoKTsKKworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGl0ZXJhdGlvbiBvbiBBdHRyaWJ1dGVkU3RyaW5nIiwgaXQKKyAgICAgICAgICAgICAgICAgICAgLmdldEF0dHJpYnV0ZShhY2lbMF0pLmVxdWFscygidmFsdWUxIikpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGl0ZXJhdGlvbiBvbiBBdHRyaWJ1dGVkU3RyaW5nIiwgaXQKKyAgICAgICAgICAgICAgICAgICAgLmdldEF0dHJpYnV0ZShhY2lbMV0pLmVxdWFscygidmFsdWUyIikpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGl0ZXJhdGlvbiBvbiBBdHRyaWJ1dGVkU3RyaW5nIiwgaXQKKyAgICAgICAgICAgICAgICAgICAgLmdldEF0dHJpYnV0ZShhY2lbMl0pID09IG51bGwpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGF0dHJTdHJpbmcuZ2V0SXRlcmF0b3IoYWNpLCAtMSwgNSk7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXR0clN0cmluZy5nZXRJdGVyYXRvcihhY2ksIDYsIDUpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGF0dHJTdHJpbmcuZ2V0SXRlcmF0b3IoYWNpLCAzLCAyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkQmlkaVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGRCaWRpVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlNWZkMjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkQmlkaVRlc3QuamF2YQpAQCAtMCwwICsxLDg5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudGV4dDsKKworaW1wb3J0IGphdmEudGV4dC5CaWRpOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZEJpZGlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgQmlkaSBiZDsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RUb1N0cmluZygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJkID0gbmV3IEJpZGkoImJpZGkiLCAxNzMpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQmlkaSByZXByZXNlbnRhdGlvbiBpcyBudWxsIiwgYmQudG9TdHJpbmcoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVMaW5lQmlkaV9BbmRyb2lkRmFpbHVyZSgpIHsKKyAgICAgICAgLy8gVGhpcyBpcyBhIGRpZmZlcmVuY2UgYmV0d2VlbiBJQ1U0QyBhbmQgdGhlIFJJLiBJQ1U0QyBpbnNpc3RzIHRoYXQgJ2xpbWl0JyBpcyBzdHJpY3RseQorICAgICAgICAvLyBncmVhdGVyIHRoYW4gJ3N0YXJ0Jy4gV2UgaGF2ZSB0byBwYXBlciBvdmVyIHRoaXMgaW4gb3VyIEphdmEgY29kZS4KKyAgICAgICAgQmlkaSBiaWRpID0gbmV3IEJpZGkoInN0ciIsIEJpZGkuRElSRUNUSU9OX1JJR0hUX1RPX0xFRlQpOworICAgICAgICBiaWRpLmNyZWF0ZUxpbmVCaWRpKDIsIDIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRSdW5MZXZlbExJbnQoKSB7CisgICAgICAgIGJkID0gbmV3IEJpZGkoInRleHQiLCBCaWRpLkRJUkVDVElPTl9MRUZUX1RPX1JJR0hUKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBiZC5nZXRSdW5MZXZlbCgwKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYmQuZ2V0UnVuTGV2ZWwoYmQuZ2V0UnVuQ291bnQoKSkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGJkID0gbmV3IEJpZGkoInRleHQiLCBCaWRpLkRJUkVDVElPTl9SSUdIVF9UT19MRUZUKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygyLCBiZC5nZXRSdW5MZXZlbCgwKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgYmQgPSBuZXcgQmlkaSgidGV4dCIsIEJpZGkuRElSRUNUSU9OX0RFRkFVTFRfUklHSFRfVE9fTEVGVCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYmQuZ2V0UnVuTGV2ZWwoMCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRSdW5TdGFydCgpIHsKKyAgICAgICAgYmQgPSBuZXcgQmlkaShuZXcgY2hhcltdIHsgJ3MnLCAncycsICdzJyB9LCAwLCBuZXcgYnl0ZVtdIHsgKGJ5dGUpIC03LAorICAgICAgICAgICAgICAgIChieXRlKSAtMiwgKGJ5dGUpIDMgfSwgMCwgMywKKyAgICAgICAgICAgICAgICBCaWRpLkRJUkVDVElPTl9ERUZBVUxUX0xFRlRfVE9fUklHSFQpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYmQuZ2V0UnVuU3RhcnQoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgYmQuZ2V0UnVuU3RhcnQoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgYmQuZ2V0UnVuU3RhcnQoMikpOworCisgICAgICAgIFN0cmluZyBMVFIgPSAiXHUwMDYxXHUwMDYyIjsKKyAgICAgICAgU3RyaW5nIFJUTCA9ICJcdTA1RENcdTA1REQiOworICAgICAgICBTdHJpbmcgbmV3TGluZSA9ICJcbiI7CisgICAgICAgIFN0cmluZyBkZWZUZXh0ID0gTFRSICsgbmV3TGluZSArIFJUTCArIExUUiArIFJUTDsKKworICAgICAgICBpbnRbXVtdIGV4cGVjdGVkUnVucyA9IHsgeyAwLCAzIH0sIHsgMywgNSB9LCB7IDUsIDcgfSwgeyA3LCA5IH0sIH07CisKKyAgICAgICAgQmlkaSBiaSA9IG5ldyBCaWRpKGRlZlRleHQsIDApOworCisgICAgICAgIGZpbmFsIGludCBjb3VudCA9IGJpLmdldFJ1bkNvdW50KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkUnVuc1tpXVswXSwgYmkuZ2V0UnVuU3RhcnQoaSkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWU5OGE1NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3JUZXN0LmphdmEKQEAgLTAsMCArMSw1MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLnRleHQuQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOworaW1wb3J0IGphdmEudGV4dC5Db2xsYXRvcjsKK2ltcG9ydCBqYXZhLnRleHQuUnVsZUJhc2VkQ29sbGF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3JUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdFByZXZpb3VzKCkgeworICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciBjb2xsID0gKFJ1bGVCYXNlZENvbGxhdG9yKSBDb2xsYXRvci5nZXRJbnN0YW5jZShMb2NhbGUuVVMpOworICAgICAgICBTdHJpbmcgdGV4dCA9ICJhYmMiOworICAgICAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgaXRlcmF0b3IgPSBjb2xsCisgICAgICAgICAgICAgICAgLmdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcih0ZXh0KTsKKyAgICAgICAgaW50W10gb3JkZXJzID0gbmV3IGludFt0ZXh0Lmxlbmd0aCgpXTsKKyAgICAgICAgaW50IG9yZGVyID0gaXRlcmF0b3IubmV4dCgpOworICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgIHdoaWxlIChvcmRlciAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CisgICAgICAgICAgICBvcmRlcnNbaSsrXSA9IG9yZGVyOworICAgICAgICAgICAgb3JkZXIgPSBpdGVyYXRvci5uZXh0KCk7CisgICAgICAgIH0KKworICAgICAgICBpbnQgb2Zmc2V0ID0gaXRlcmF0b3IuZ2V0T2Zmc2V0KCk7CisgICAgICAgIGFzc2VydEVxdWFscyh0ZXh0Lmxlbmd0aCgpLCBvZmZzZXQpOworICAgICAgICBvcmRlciA9IGl0ZXJhdG9yLnByZXZpb3VzKCk7CisKKyAgICAgICAgd2hpbGUgKG9yZGVyICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhvcmRlcnNbLS1pXSwgb3JkZXIpOworICAgICAgICAgICAgb3JkZXIgPSBpdGVyYXRvci5wcmV2aW91cygpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGl0ZXJhdG9yLmdldE9mZnNldCgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkQ29sbGF0aW9uS2V5VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZENvbGxhdGlvbktleVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZmM4MjY0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZENvbGxhdGlvbktleVRlc3QuamF2YQpAQCAtMCwwICsxLDk3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLnRleHQuQ29sbGF0aW9uS2V5OworaW1wb3J0IGphdmEudGV4dC5Db2xsYXRvcjsKK2ltcG9ydCBqYXZhLnRleHQuUGFyc2VFeGNlcHRpb247CitpbXBvcnQgamF2YS50ZXh0LlJ1bGVCYXNlZENvbGxhdG9yOworCisKK3B1YmxpYyBjbGFzcyBPbGRDb2xsYXRpb25LZXlUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9CeXRlQXJyYXkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBieXRlIFtdIGphdmEudGV4dC5Db2xsYXRpb25LZXkudG9CeXRlQXJyYXkoKQorICAgICAgICBDb2xsYXRvciBjb2xsYXRvciA9IENvbGxhdG9yLmdldEluc3RhbmNlKCk7CisgICAgICAgIGNvbGxhdG9yLnNldFN0cmVuZ3RoKENvbGxhdG9yLlBSSU1BUlkpOworICAgICAgICBDb2xsYXRpb25LZXkga2V5MSA9IGNvbGxhdG9yLmdldENvbGxhdGlvbktleSgiYWJjIik7CisgICAgICAgIGJ5dGVbXSBieXRlcyA9IGtleTEudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTm90IGVub3VnaCBieXRlcyIsIGJ5dGVzLmxlbmd0aCA+PSAzKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29sbGF0b3IgPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoIj0gMSAsIDIgOyAzICwgNCA8IDUgOyA2ICwgNyIpOworICAgICAgICB9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJQYXJzZUV4Y2VwdGlvbiIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIC8qCisgICAgICAgICAqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBpdCA9CisgICAgICAgICAqICgoUnVsZUJhc2VkQ29sbGF0b3IpY29sbGF0b3IpLmdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcigiMTIzNDU2NyIpOworICAgICAgICAgKiBpbnQgb3JkZXI7IHdoaWxlICgob3JkZXIgPSBpdC5uZXh0KCkpICE9CisgICAgICAgICAqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKKyAgICAgICAgICogU3lzdGVtLm91dC5wcmludGxuKEludGVnZXIudG9IZXhTdHJpbmcob3JkZXIpKTsgfSBmb3IgKGludCBpPTA7IGk8Ynl0ZXMubGVuZ3RoOworICAgICAgICAgKiBpKz0yKSB7IFN5c3RlbS5vdXQucHJpbnQoSW50ZWdlci50b0hleFN0cmluZyhieXRlc1tpXSkgKworICAgICAgICAgKiBJbnRlZ2VyLnRvSGV4U3RyaW5nKGJ5dGVzW2krMV0pICsgIiAiKTsgfSBTeXN0ZW0ub3V0LnByaW50bG4oKTsKKyAgICAgICAgICovCisKKyAgICAgICAgLy8gVGhlIFJJIGhhcyBhIGRpZmZlcmVudCBhbGdvcml0aG0gdG8gZ2VuZXJhdGUgdGhlIGNvbGxhdGlvbiBrZXlzLgorICAgICAgICAvLyBieXRlcyA9IGNvbGxhdG9yLmdldENvbGxhdGlvbktleSgiMTIzNDU2NyIpLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIC8vIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtdIHsgMCwgMiwgMCwgMiwgMCwgMiwgMCwgMCwgMCwgMywgMCwgMywgMCwgMSwKKyAgICAgICAgLy8gICAgICAgICAwLCAyLCAwLCAyLCAwLCAwLCAwLCA0LCAwLCA0LCAwLCAxLCAwLCAxLCAwLCAyIH07CisgICAgICAgIGJ5dGVbXSBieXRlczEgPSBjb2xsYXRvci5nZXRDb2xsYXRpb25LZXkoIjEyIikudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgYnl0ZVtdIGJ5dGVzMiA9IGNvbGxhdG9yLmdldENvbGxhdGlvbktleSgiMTIzIikudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgYnl0ZVtdIGJ5dGVzMyA9IGNvbGxhdG9yLmdldENvbGxhdGlvbktleSgiMTI0IikudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgYnl0ZVtdIGJ5dGVzNCA9IGNvbGxhdG9yLmdldENvbGxhdGlvbktleSgiMTI0NSIpLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIGJ5dGVbXSBieXRlczUgPSBjb2xsYXRvci5nZXRDb2xsYXRpb25LZXkoIjEyNDUiKS50b0J5dGVBcnJheSgpOworCisgICAgICAgIGFzc2VydFRydWUoInJldHVybmVkIGNvbGxhdGlvbiBrZXkgZG9lcyBub3Qgc29ydCBjb3JyZWN0bHkiLAorICAgICAgICAgICAgICAgIGNvbXBhcmVVbnNpZ25lZEJ5dGVBcnJheXMoYnl0ZXMxLCBieXRlczIpIDwgMCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgicmV0dXJuZWQgY29sbGF0aW9uIGtleSBkb2VzIG5vdCBzb3J0IGNvcnJlY3RseSIsCisgICAgICAgICAgICAgICAgY29tcGFyZVVuc2lnbmVkQnl0ZUFycmF5cyhieXRlczIsIGJ5dGVzMykgPCAwKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJyZXR1cm5lZCBjb2xsYXRpb24ga2V5IGRvZXMgbm90IHNvcnQgY29ycmVjdGx5IiwKKyAgICAgICAgICAgICAgICBjb21wYXJlVW5zaWduZWRCeXRlQXJyYXlzKGJ5dGVzMywgYnl0ZXM0KSA8IDApOworCisgICAgICAgIGFzc2VydFRydWUoInJldHVybmVkIGNvbGxhdGlvbiBrZXkgZG9lcyBub3Qgc29ydCBjb3JyZWN0bHkiLAorICAgICAgICAgICAgICAgIGNvbXBhcmVVbnNpZ25lZEJ5dGVBcnJheXMoYnl0ZXM0LCBieXRlczUpID09IDApOworCisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgY29tcGFyZVVuc2lnbmVkQnl0ZUFycmF5cyhieXRlW10gYnl0ZXMxLCBieXRlW10gYnl0ZXMyKSB7CisgICAgICAgIGludCBjb21tb25MZW5ndGggPSBNYXRoLm1pbihieXRlczEubGVuZ3RoLCBieXRlczIubGVuZ3RoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbW1vbkxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpbnQga2V5QSA9IGJ5dGVzMVtpXSAmIDB4RkY7CisgICAgICAgICAgICBpbnQga2V5QiA9IGJ5dGVzMltpXSAmIDB4RkY7CisgICAgICAgICAgICBpZiAoa2V5QSA8IGtleUIpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoa2V5QSA+IGtleUIpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChieXRlczEubGVuZ3RoIDwgYnl0ZXMyLmxlbmd0aCkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzMS5sZW5ndGggPiBieXRlczIubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZERhdGVGb3JtYXRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkRGF0ZUZvcm1hdFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNjE0ZDZmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZERhdGVGb3JtYXRUZXN0LmphdmEKQEAgLTAsMCArMSw0ODYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEudGV4dDsKKworaW1wb3J0IGphdmEudGV4dC5EYXRlRm9ybWF0OworaW1wb3J0IGphdmEudGV4dC5GaWVsZFBvc2l0aW9uOworaW1wb3J0IGphdmEudGV4dC5QYXJzZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnRleHQuUGFyc2VQb3NpdGlvbjsKK2ltcG9ydCBqYXZhLnRleHQuU2ltcGxlRGF0ZUZvcm1hdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CisKK3B1YmxpYyBjbGFzcyBPbGREYXRlRm9ybWF0VGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIGNsYXNzIE1vY2tEYXRlRm9ybWF0IGV4dGVuZHMgRGF0ZUZvcm1hdCB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAgICAgcHVibGljIE1vY2tEYXRlRm9ybWF0KCkgeworICAgICAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgRGF0ZSBwYXJzZShTdHJpbmcgc291cmNlLCBQYXJzZVBvc2l0aW9uIHBvcykgeworICAgICAgICAgICAgLy8gaXQgaXMgYSBmYWtlCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGZvcm1hdChEYXRlIGRhdGUsIFN0cmluZ0J1ZmZlciB0b0FwcGVuZFRvLAorICAgICAgICAgICAgICAgIEZpZWxkUG9zaXRpb24gZmllbGRQb3NpdGlvbikgeworICAgICAgICAgICAgLy8gaXQgaXMgYSBmYWtlCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudGV4dC5EYXRlRm9ybWF0I0RhdGVGb3JtYXQoKSBUZXN0IG9mIG1ldGhvZAorICAgICAqICAgICAgICBqYXZhLnRleHQuRGF0ZUZvcm1hdCNEYXRlRm9ybWF0KCkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBNb2NrRGF0ZUZvcm1hdCgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnRleHQuRGF0ZUZvcm1hdCNlcXVhbHMoamF2YS5sYW5nLk9iamVjdCBvYmopIFRlc3Qgb2YKKyAgICAgKiAgICAgICAgamF2YS50ZXh0LkRhdGVGb3JtYXQjZXF1YWxzKGphdmEubGFuZy5PYmplY3Qgb2JqKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VxdWFsc0xqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgRGF0ZUZvcm1hdCBmb3JtYXQgPSBEYXRlRm9ybWF0LmdldEluc3RhbmNlKCk7CisgICAgICAgICAgICBEYXRlRm9ybWF0IGNsb25lID0gKERhdGVGb3JtYXQpIGZvcm1hdC5jbG9uZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2xvbmUgYW5kIHBhcmVudCBhcmUgbm90IGVxdWFsZWQiLCBmb3JtYXQuZXF1YWxzKGNsb25lKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJDbG9uZSBpcyBlcXVhbCB0byBvdGhlciBvYmplY3QiLCAhY2xvbmUKKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhEYXRlRm9ybWF0LmdldFRpbWVJbnN0YW5jZSgpKSk7CisgICAgICAgICAgICBmb3JtYXQuc2V0Q2FsZW5kYXIoQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJDbG9uZSBhbmQgcGFyZW50IGFyZSBub3QgZXF1YWxlZCIsIGZvcm1hdC5lcXVhbHMoY2xvbmUpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS50ZXh0LkRhdGVGb3JtYXQjZm9ybWF0KGphdmEudXRpbC5EYXRlKSBUZXN0IG9mIG1ldGhvZAorICAgICAqICAgICAgICBqYXZhLnRleHQuRGF0ZUZvcm1hdCNmb3JtYXQoamF2YS51dGlsLkRhdGUpLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZm9ybWF0TGphdmFfdXRpbF9EYXRlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgRGF0ZUZvcm1hdCBmb3JtYXQgPSBEYXRlRm9ybWF0LmdldERhdGVUaW1lSW5zdGFuY2UoCisgICAgICAgICAgICAgICAgICAgIERhdGVGb3JtYXQuU0hPUlQsIERhdGVGb3JtYXQuU0hPUlQsIExvY2FsZS5VUyk7CisgICAgICAgICAgICBEYXRlIGN1cnJlbnQgPSBuZXcgRGF0ZSgpOworICAgICAgICAgICAgU3RyaW5nIGR0ZiA9IGZvcm1hdC5mb3JtYXQoY3VycmVudCk7CisgICAgICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IHNkZiA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCJNL2QveXkgaDptbSBhIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZGF0ZSBmb3JtYXQiLCBzZGYuZm9ybWF0KGN1cnJlbnQpLmVxdWFscyhkdGYpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS50ZXh0LkRhdGVGb3JtYXQjZm9ybWF0KE9iamVjdCwgU3RyaW5nQnVmZmVyLCBGaWVsZFBvc2l0aW9uKQorICAgICAqICAgICAgICBUZXN0IG9mIG1ldGhvZCBqYXZhLnRleHQuRGF0ZUZvcm1hdCNmb3JtYXQoT2JqZWN0LCBTdHJpbmdCdWZmZXIsCisgICAgICogICAgICAgIEZpZWxkUG9zaXRpb24pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9mb3JtYXRMamF2YV9sYW5nX09iamVjdExqYXZhX2xhbmdfU3RyaW5nQnVmZmVyTGphdmFfdGV4dF9GaWVsZFBvc2l0aW9uKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgRGF0ZUZvcm1hdCBmb3JtYXQgPSBEYXRlRm9ybWF0LmdldERhdGVUaW1lSW5zdGFuY2UoCisgICAgICAgICAgICAgICAgICAgIERhdGVGb3JtYXQuU0hPUlQsIERhdGVGb3JtYXQuU0hPUlQsIExvY2FsZS5VUyk7CisgICAgICAgICAgICBEYXRlIGN1cnJlbnQgPSBuZXcgRGF0ZSgpOworICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHRvQXBwZW5kID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICAgICAgRmllbGRQb3NpdGlvbiBmcCA9IG5ldyBGaWVsZFBvc2l0aW9uKERhdGVGb3JtYXQuWUVBUl9GSUVMRCk7CisgICAgICAgICAgICBTdHJpbmdCdWZmZXIgc2IgPSBmb3JtYXQuZm9ybWF0KGN1cnJlbnQsIHRvQXBwZW5kLCBmcCk7CisgICAgICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IHNkZiA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCJNL2QveXkgaDptbSBhIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZGF0ZSBmb3JtYXQiLCBzZGYuZm9ybWF0KGN1cnJlbnQpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgc2IudG9TdHJpbmcoKSkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGJlZ2luSW5kZXggb2YgZmlsZWQgcG9zaXRpb24iLCBmcAorICAgICAgICAgICAgICAgICAgICAuZ2V0QmVnaW5JbmRleCgpID09IHNiLmxhc3RJbmRleE9mKCIvIikgKyAxKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBlbmRJbmRleCBvZiBmaWxlZCBwb3NpdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIGZwLmdldEVuZEluZGV4KCkgPT0gc2IubGFzdEluZGV4T2YoIi8iKSArIDMpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFRpbWVab25lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgRGF0ZUZvcm1hdCBmb3JtYXQgPSBEYXRlRm9ybWF0LmdldEluc3RhbmNlKCk7CisgICAgICAgICAgICBUaW1lWm9uZSAgIHR6ICAgICA9IGZvcm1hdC5nZXRUaW1lWm9uZSgpOworICAgICAgICAgICAgLy9pZigxID09IDEpCisgICAgICAgICAgICAvLyAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKHR6LmdldENsYXNzKCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIC8vIFdlIGtub3cgd2UgYXJlIG5vdCBzdW4udXRpbCBzbzoKKyAgICAgICAgICAgIC8vIFJlZHVuZGFudCBjaGVja2luZworICAgICAgICAgICAgLy9hc3NlcnRGYWxzZSgiSW5jb3JyZWN0IHpvbmUgaW5mbyIsIHR6LmdldENsYXNzKCkuZ2V0TmFtZSgpLmVxdWFscygKKyAgICAgICAgICAgIC8vICAgICAgICAic3VuLnV0aWwuY2FsZW5kYXIuWm9uZUluZm8iKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgdGltZSB6b25lIiwgdHouZXF1YWxzKGZvcm1hdC5nZXRDYWxlbmRhcigpCisgICAgICAgICAgICAgICAgICAgIC5nZXRUaW1lWm9uZSgpKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudGV4dC5EYXRlRm9ybWF0I2hhc2hDb2RlKCkgVGVzdCBvZiBtZXRob2QKKyAgICAgKiAgICAgICAgamF2YS50ZXh0LkRhdGVGb3JtYXQjaGFzaENvZGUoKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc2hDb2RlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgRGF0ZUZvcm1hdCBkZjEgPSBEYXRlRm9ybWF0LmdldEluc3RhbmNlKCk7CisgICAgICAgICAgICBEYXRlRm9ybWF0IGRmMiA9IChEYXRlRm9ybWF0KSBkZjEuY2xvbmUoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkhhc2ggY29kZXMgb2YgY2xvbmVzIGFyZSBub3QgZXF1YWwiLAorICAgICAgICAgICAgICAgICAgICBkZjEuaGFzaENvZGUoKSA9PSBkZjIuaGFzaENvZGUoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJIYXNoIGNvZGVzIG9mIGRpZmZlcmVudCBvYmplY3RzIGFyZSB0aGUgc2FtZSIsIGRmMQorICAgICAgICAgICAgICAgICAgICAuaGFzaENvZGUoKSAhPSBEYXRlRm9ybWF0LmdldERhdGVJbnN0YW5jZSgpLmhhc2hDb2RlKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnRleHQuRGF0ZUZvcm1hdCNpc0xlbmllbnQoKSBUZXN0IG9mIG1ldGhvZAorICAgICAqICAgICAgICBqYXZhLnRleHQuRGF0ZUZvcm1hdCNpc0xlbmllbnQoKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzTGVuaWVudCgpIHsKKyAgICAgICAgRGF0ZUZvcm1hdCBkZiA9IERhdGVGb3JtYXQuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgQ2FsZW5kYXIgYyA9IGRmLmdldENhbGVuZGFyKCk7CisgICAgICAgIGlmIChkZi5pc0xlbmllbnQoKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjLnNldChDYWxlbmRhci5EQVlfT0ZfTU9OVEgsIDMyKTsKKyAgICAgICAgICAgICAgICBjLmdldChDYWxlbmRhci5EQVlfT0ZfTU9OVEgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGMuc2V0TGVuaWVudChmYWxzZSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGMuc2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCwgMzIpOworICAgICAgICAgICAgICAgIGMuZ2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCk7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjLnNldChDYWxlbmRhci5EQVlfT0ZfTU9OVEgsIDMyKTsKKyAgICAgICAgICAgICAgICBjLmdldChDYWxlbmRhci5EQVlfT0ZfTU9OVEgpOworICAgICAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGMuc2V0TGVuaWVudCh0cnVlKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYy5zZXQoQ2FsZW5kYXIuREFZX09GX01PTlRILCAzMik7CisgICAgICAgICAgICAgICAgYy5nZXQoQ2FsZW5kYXIuREFZX09GX01PTlRIKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnRleHQuRGF0ZUZvcm1hdCNwYXJzZShTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wYXJzZUxTdHJpbmcoKSB7CisgICAgICAgIERhdGVGb3JtYXQgZm9ybWF0ID0gRGF0ZUZvcm1hdC5nZXREYXRlVGltZUluc3RhbmNlKERhdGVGb3JtYXQuU0hPUlQsIERhdGVGb3JtYXQuU0hPUlQsIExvY2FsZS5VUyk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvcm1hdC5wYXJzZSgibm90IGEgRGF0ZSIpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IFBhcnNlRXhjZXB0aW9uIGZpcnN0Iik7CisgICAgICAgIH0gY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIHBlKSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBEYXRlIGN1cnJlbnQgPSBuZXcgRGF0ZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEYXRlIGRhdGUgPSBmb3JtYXQucGFyc2UoZm9ybWF0LmZvcm1hdChjdXJyZW50KS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjdXJyZW50LmdldERhdGUoKSwgZGF0ZS5nZXREYXRlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnQuZ2V0RGF5KCksIGRhdGUuZ2V0RGF5KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnQuZ2V0TW9udGgoKSwgZGF0ZS5nZXRNb250aCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjdXJyZW50LmdldFllYXIoKSwgZGF0ZS5nZXRZZWFyKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnQuZ2V0SG91cnMoKSwgZGF0ZS5nZXRIb3VycygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjdXJyZW50LmdldE1pbnV0ZXMoKSwgZGF0ZS5nZXRNaW51dGVzKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGRhdGUuZ2V0U2Vjb25kcygpKTsKKyAgICAgICAgfSBjYXRjaChQYXJzZUV4Y2VwdGlvbiBwZSkgeworICAgICAgICAgICAgZmFpbCgiUGFyc2VFeGNlcHRpb24gd2FzIHRocm93biBmb3IgY3VycmVudCBEYXRlLiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvcm1hdC5wYXJzZSgiMjcvMDgvMTk5OCIpOworICAgICAgICAgICAgZmFpbCgiUGFyc2VFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goUGFyc2VFeGNlcHRpb24gcGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9ybWF0LnBhcnNlKCIzMC8zMC85MDggNDo1MCwgUERUIik7CisgICAgICAgICAgICBmYWlsKCJQYXJzZUV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChQYXJzZUV4Y2VwdGlvbiBwZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3JtYXQucGFyc2UoIjgzNzAzOTkyODA0NiIpOworICAgICAgICAgICAgZmFpbCgiUGFyc2VFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goUGFyc2VFeGNlcHRpb24gcGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGZvcm1hdCA9IERhdGVGb3JtYXQuZ2V0RGF0ZUluc3RhbmNlKERhdGVGb3JtYXQuREVGQVVMVCwgTG9jYWxlLlVTKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIERhdGUgZGF0ZSA9IGZvcm1hdC5wYXJzZShmb3JtYXQuZm9ybWF0KGN1cnJlbnQpLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnQuZ2V0RGF0ZSgpLCBkYXRlLmdldERhdGUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoY3VycmVudC5nZXREYXkoKSwgZGF0ZS5nZXREYXkoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoY3VycmVudC5nZXRNb250aCgpLCBkYXRlLmdldE1vbnRoKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnQuZ2V0WWVhcigpLCBkYXRlLmdldFllYXIoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZGF0ZS5nZXRIb3VycygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBkYXRlLmdldE1pbnV0ZXMoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZGF0ZS5nZXRTZWNvbmRzKCkpOworICAgICAgICB9IGNhdGNoKFBhcnNlRXhjZXB0aW9uIHBlKSB7CisgICAgICAgICAgICBmYWlsKCJQYXJzZUV4Y2VwdGlvbiB3YXMgdGhyb3duIGZvciBjdXJyZW50IERhdGUuIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9ybWF0LnBhcnNlKCJKYW4gMTYgMTk3MCIpOworICAgICAgICAgICAgZmFpbCgiUGFyc2VFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goUGFyc2VFeGNlcHRpb24gcGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3JtYXQucGFyc2UoIjI3LzA4LzE5OTgiKTsKKyAgICAgICAgICAgIGZhaWwoIlBhcnNlRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFBhcnNlRXhjZXB0aW9uIHBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBmb3JtYXQgPSBEYXRlRm9ybWF0LmdldERhdGVJbnN0YW5jZShEYXRlRm9ybWF0LkxPTkcsIExvY2FsZS5VUyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEYXRlIGRhdGUgPSBmb3JtYXQucGFyc2UoZm9ybWF0LmZvcm1hdChjdXJyZW50KS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjdXJyZW50LmdldERhdGUoKSwgZGF0ZS5nZXREYXRlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnQuZ2V0RGF5KCksIGRhdGUuZ2V0RGF5KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnQuZ2V0TW9udGgoKSwgZGF0ZS5nZXRNb250aCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjdXJyZW50LmdldFllYXIoKSwgZGF0ZS5nZXRZZWFyKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGRhdGUuZ2V0SG91cnMoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZGF0ZS5nZXRNaW51dGVzKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGRhdGUuZ2V0U2Vjb25kcygpKTsKKyAgICAgICAgfSBjYXRjaChQYXJzZUV4Y2VwdGlvbiBwZSkgeworICAgICAgICAgICAgZmFpbCgiUGFyc2VFeGNlcHRpb24gd2FzIHRocm93biBmb3IgY3VycmVudCBEYXRlLiIpOworICAgICAgICB9CisKKyAgICAgICAgZm9ybWF0ID0gRGF0ZUZvcm1hdC5nZXREYXRlSW5zdGFuY2UoRGF0ZUZvcm1hdC5NRURJVU0sIExvY2FsZS5VUyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEYXRlIGRhdGUgPSBmb3JtYXQucGFyc2UoZm9ybWF0LmZvcm1hdChjdXJyZW50KS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjdXJyZW50LmdldERhdGUoKSwgZGF0ZS5nZXREYXRlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnQuZ2V0RGF5KCksIGRhdGUuZ2V0RGF5KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnQuZ2V0TW9udGgoKSwgZGF0ZS5nZXRNb250aCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjdXJyZW50LmdldFllYXIoKSwgZGF0ZS5nZXRZZWFyKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGRhdGUuZ2V0SG91cnMoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZGF0ZS5nZXRNaW51dGVzKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGRhdGUuZ2V0U2Vjb25kcygpKTsKKyAgICAgICAgfSBjYXRjaChQYXJzZUV4Y2VwdGlvbiBwZSkgeworICAgICAgICAgICAgZmFpbCgiUGFyc2VFeGNlcHRpb24gd2FzIHRocm93biBmb3IgY3VycmVudCBEYXRlLiIpOworICAgICAgICB9CisKKyAgICAgICAgZm9ybWF0ID0gRGF0ZUZvcm1hdC5nZXRUaW1lSW5zdGFuY2UoRGF0ZUZvcm1hdC5ERUZBVUxULCBMb2NhbGUuVVMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgRGF0ZSBkYXRlID0gZm9ybWF0LnBhcnNlKGZvcm1hdC5mb3JtYXQoY3VycmVudCkudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZGF0ZS5nZXREYXRlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGRhdGUuZ2V0TW9udGgoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNzAsIGRhdGUuZ2V0WWVhcigpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjdXJyZW50LmdldEhvdXJzKCksIGRhdGUuZ2V0SG91cnMoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoY3VycmVudC5nZXRNaW51dGVzKCksIGRhdGUuZ2V0TWludXRlcygpKTsKKyAgICAgICAgfSBjYXRjaChQYXJzZUV4Y2VwdGlvbiBwZSkgeworICAgICAgICAgICAgZmFpbCgiUGFyc2VFeGNlcHRpb24gd2FzIHRocm93biBmb3IgY3VycmVudCBEYXRlLiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvcm1hdC5wYXJzZSgiODo1ODo0NCIpOworICAgICAgICAgICAgZmFpbCgiUGFyc2VFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goUGFyc2VFeGNlcHRpb24gcGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGZvcm1hdCA9IERhdGVGb3JtYXQuZ2V0RGF0ZVRpbWVJbnN0YW5jZShEYXRlRm9ybWF0LkRFRkFVTFQsIERhdGVGb3JtYXQuU0hPUlQsIExvY2FsZS5VUyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEYXRlIGRhdGUgPSBmb3JtYXQucGFyc2UoZm9ybWF0LmZvcm1hdChjdXJyZW50KS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjdXJyZW50LmdldERhdGUoKSwgZGF0ZS5nZXREYXRlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnQuZ2V0RGF5KCksIGRhdGUuZ2V0RGF5KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnQuZ2V0TW9udGgoKSwgZGF0ZS5nZXRNb250aCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjdXJyZW50LmdldFllYXIoKSwgZGF0ZS5nZXRZZWFyKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnQuZ2V0SG91cnMoKSwgZGF0ZS5nZXRIb3VycygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjdXJyZW50LmdldE1pbnV0ZXMoKSwgZGF0ZS5nZXRNaW51dGVzKCkpOworICAgICAgICB9IGNhdGNoKFBhcnNlRXhjZXB0aW9uIHBlKSB7CisgICAgICAgICAgICBmYWlsKCJQYXJzZUV4Y2VwdGlvbiB3YXMgdGhyb3duIGZvciBjdXJyZW50IERhdGUuIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9ybWF0LnBhcnNlKCJKYW51YXJ5IDMxIDE5NzAgNzo1MjozNCBBTSBQU1QiKTsKKyAgICAgICAgICAgIGZhaWwoIlBhcnNlRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFBhcnNlRXhjZXB0aW9uIHBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9ybWF0LnBhcnNlKCJKYW51YXJ5IDMxIDE5NzAiKTsKKyAgICAgICAgICAgIGZhaWwoIlBhcnNlRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKFBhcnNlRXhjZXB0aW9uIHBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBmb3JtYXQgPSBEYXRlRm9ybWF0LmdldERhdGVUaW1lSW5zdGFuY2UoRGF0ZUZvcm1hdC5GVUxMLCBEYXRlRm9ybWF0LkZVTEwsIExvY2FsZS5VUyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEYXRlIGRhdGUgPSBmb3JtYXQucGFyc2UoZm9ybWF0LmZvcm1hdChjdXJyZW50KS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjdXJyZW50LmdldERhdGUoKSwgZGF0ZS5nZXREYXRlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnQuZ2V0RGF5KCksIGRhdGUuZ2V0RGF5KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnQuZ2V0TW9udGgoKSwgZGF0ZS5nZXRNb250aCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjdXJyZW50LmdldFllYXIoKSwgZGF0ZS5nZXRZZWFyKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnQuZ2V0SG91cnMoKSwgZGF0ZS5nZXRIb3VycygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjdXJyZW50LmdldE1pbnV0ZXMoKSwgZGF0ZS5nZXRNaW51dGVzKCkpOworICAgICAgICB9IGNhdGNoKFBhcnNlRXhjZXB0aW9uIHBlKSB7CisgICAgICAgICAgICBmYWlsKCJQYXJzZUV4Y2VwdGlvbiB3YXMgdGhyb3duIGZvciBjdXJyZW50IERhdGUuIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9ybWF0LnBhcnNlKCJKYW51YXJ5IDE2LCAxOTcwIDg6MDM6NTIgUE0gQ0VUIik7CisgICAgICAgICAgICBmYWlsKCJQYXJzZUV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChQYXJzZUV4Y2VwdGlvbiBwZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS50ZXh0LkRhdGVGb3JtYXQjcGFyc2VPYmplY3QoU3RyaW5nLCBQYXJzZVBvc2l0aW9uKSBUZXN0IG9mCisgICAgICogICAgICAgIG1ldGhvZCBqYXZhLnRleHQuRGF0ZUZvcm1hdCNwYXJzZU9iamVjdChTdHJpbmcsIFBhcnNlUG9zaXRpb24pLgorICAgICAqICAgICAgICBDYXNlIDE6IFRyeSB0byBwYXJzZSBjb3JyZWN0IGRhdGEgc3RyaW5nLiBDYXNlIDI6IFRyeSB0byBwYXJzZQorICAgICAqICAgICAgICBwYXJ0aWFseSBjb3JyZWN0IGRhdGEgc3RyaW5nLiBDYXNlIDM6IFRyeSB0byB1c2UgYXJndW1lbnQKKyAgICAgKiAgICAgICAgUGFyc2VQb3NpdGlvbiBhcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcGFyc2VPYmplY3RMamF2YV9sYW5nX1N0cmluZ0xqYXZhX3RleHRfUGFyc2VQb3NpdGlvbigpIHsKKyAgICAgICAgRGF0ZUZvcm1hdCBkZiA9IERhdGVGb3JtYXQuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGNhc2UgMTogVHJ5IHRvIHBhcnNlIGNvcnJlY3QgZGF0YSBzdHJpbmcuCisgICAgICAgICAgICBEYXRlIGN1cnJlbnQgPSBuZXcgRGF0ZSgpOworICAgICAgICAgICAgUGFyc2VQb3NpdGlvbiBwcCA9IG5ldyBQYXJzZVBvc2l0aW9uKDApOworICAgICAgICAgICAgaW50IHBhcnNlSW5kZXggPSBwcC5nZXRJbmRleCgpOworICAgICAgICAgICAgRGF0ZSByZXN1bHQgPSAoRGF0ZSkgZGYucGFyc2VPYmplY3QoZGYuZm9ybWF0KGN1cnJlbnQpLCBwcCk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiRGF0ZXMgYXJlIGRpZmZlcmVudC4iLCBjdXJyZW50LmdldERhdGUoKSwgcmVzdWx0LmdldERhdGUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkRheXMgYXJlIGRpZmZlcmVudC4iLCBjdXJyZW50LmdldERheSgpLCByZXN1bHQuZ2V0RGF5KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJNb250aHMgYXJlIGRpZmZlcmVudC4iLCBjdXJyZW50LmdldE1vbnRoKCksIHJlc3VsdC5nZXRNb250aCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiWWVhcnMgYXJlIGRpZmZlcmVudC4iLCBjdXJyZW50LmdldFllYXIoKSwgcmVzdWx0LmdldFllYXIoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkhvdXJzIGFyZSBkaWZmZXJlbnQiLCBjdXJyZW50LmdldEhvdXJzKCksIHJlc3VsdC5nZXRIb3VycygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiTWludXRlcyBhcmUgZGlmZmV0cmVudCwiLCBjdXJyZW50LmdldE1pbnV0ZXMoKSwgcmVzdWx0LmdldE1pbnV0ZXMoKSk7CisKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlBhcnNlIG9wZXJhdGlvbiByZXR1cm4gbnVsbCIsIHJlc3VsdCAhPSBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlBhcnNlSW5kZXggaXMgaW5jb3JyZWN0IiwgcHAuZ2V0SW5kZXgoKSAhPSBwYXJzZUluZGV4KTsKKworICAgICAgICAgICAgLy8gY2FzZSAyOiBUcnkgdG8gcGFyc2UgcGFydGlhbGx5IGNvcnJlY3QgZGF0YSBzdHJpbmcuCisgICAgICAgICAgICBwcC5zZXRJbmRleCgwKTsKKyAgICAgICAgICAgIGNoYXJbXSBjdXIgPSBkZi5mb3JtYXQoY3VycmVudCkudG9DaGFyQXJyYXkoKTsKKyAgICAgICAgICAgIGN1cltjdXIubGVuZ3RoIC8gMl0gPSAnWic7CisgICAgICAgICAgICBTdHJpbmcgcGFydGlhbENvcnJlY3QgPSBuZXcgU3RyaW5nKGN1cik7CisgICAgICAgICAgICByZXN1bHQgPSAoRGF0ZSkgZGYucGFyc2VPYmplY3QocGFydGlhbENvcnJlY3QsIHBwKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlBhcnNlIG9wZXJhdGlvbiByZXR1cm4gbm90LW51bGwiLCByZXN1bHQgPT0gbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJQYXJzZUluZGV4IGlzIGluY29ycmVjdCIsIHBwLmdldEluZGV4KCkgPT0gMCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJQYXJzZUVycm9ySW5kZXggaXMgaW5jb3JyZWN0IiwKKyAgICAgICAgICAgICAgICAgICAgcHAuZ2V0RXJyb3JJbmRleCgpID09IGN1ci5sZW5ndGggLyAyKTsKKworICAgICAgICAgICAgcHAuc2V0SW5kZXgoMik7CisgICAgICAgICAgICBjaGFyW10gY3VyRGF0ZSA9IGRmLmZvcm1hdChjdXJyZW50KS50b0NoYXJBcnJheSgpOworICAgICAgICAgICAgY2hhciBbXSBuZXdBcnJheSA9IG5ldyBjaGFyW2N1ckRhdGUubGVuZ3RoICsgcHAuZ2V0SW5kZXgoKV07CisgICAgICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgY3VyRGF0ZS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIG5ld0FycmF5W2kgKyBwcC5nZXRJbmRleCgpXSA9IGN1ckRhdGVbaV07CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHQgPSAoRGF0ZSkgZGYucGFyc2VPYmplY3QobmV3IFN0cmluZyhuZXdBcnJheSksIHBwKTsKKyAgICAgICAgICAgIC8vYXNzZXJ0RXF1YWxzKGN1cnJlbnQsIHJlc3VsdCk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiRGF0ZXMgYXJlIGRpZmZlcmVudC4iLCBjdXJyZW50LmdldERhdGUoKSwgcmVzdWx0LmdldERhdGUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkRheXMgYXJlIGRpZmZlcmVudC4iLCBjdXJyZW50LmdldERheSgpLCByZXN1bHQuZ2V0RGF5KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJNb250aHMgYXJlIGRpZmZlcmVudC4iLCBjdXJyZW50LmdldE1vbnRoKCksIHJlc3VsdC5nZXRNb250aCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiWWVhcnMgYXJlIGRpZmZlcmVudC4iLCBjdXJyZW50LmdldFllYXIoKSwgcmVzdWx0LmdldFllYXIoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkhvdXJzIGFyZSBkaWZmZXJlbnQiLCBjdXJyZW50LmdldEhvdXJzKCksIHJlc3VsdC5nZXRIb3VycygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiTWludXRlcyBhcmUgZGlmZmV0cmVudCwiLCBjdXJyZW50LmdldE1pbnV0ZXMoKSwgcmVzdWx0LmdldE1pbnV0ZXMoKSk7CisKKyAgICAgICAgICAgIC8vIGNhc2UgMzogVHJ5IHRvIHVzZSBhcmd1bWVudCBQYXJzZVBvc2l0aW9uIGFzIG51bGwuCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGRmLnBhcnNlT2JqZWN0KGRmLmZvcm1hdChjdXJyZW50KSwgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBhc3NlcnROdWxsKGRmLnBhcnNlT2JqZWN0KCJ0ZXN0IiwgcHApKTsKKworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnRleHQuRGF0ZUZvcm1hdCNzZXRMZW5pZW50KGJvb2xlYW4pIFRlc3Qgb2YgbWV0aG9kCisgICAgICogICAgICAgIGphdmEudGV4dC5EYXRlRm9ybWF0I3NldExlbmllbnQoYm9vbGVhbikuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRMZW5pZW50WigpIHsKKyAgICAgICAgRGF0ZUZvcm1hdCBkZiA9IERhdGVGb3JtYXQuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgQ2FsZW5kYXIgYyA9IGRmLmdldENhbGVuZGFyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLnNldExlbmllbnQodHJ1ZSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGMuc2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCwgMzIpOworICAgICAgICAgICAgICAgIGMuZ2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYy5zZXRMZW5pZW50KGZhbHNlKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYy5zZXQoQ2FsZW5kYXIuREFZX09GX01PTlRILCAzMik7CisgICAgICAgICAgICAgICAgYy5nZXQoQ2FsZW5kYXIuREFZX09GX01PTlRIKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS50ZXh0LkRhdGVGb3JtYXQjc2V0VGltZVpvbmUoVGltZVpvbmUpIFRlc3Qgb2YgbWV0aG9kCisgICAgICogICAgICAgIGphdmEudGV4dC5EYXRlRm9ybWF0I3NldFRpbWVab25lKFRpbWVab25lKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFRpbWVab25lTGphdmFfdXRpbF9UaW1lWm9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIERhdGVGb3JtYXQgZm9ybWF0ID0gRGF0ZUZvcm1hdC5nZXRJbnN0YW5jZSgpOworICAgICAgICAgICAgVGltZVpvbmUgdHogPSBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiQW1lcmljYS9Mb3NfQW5nZWxlcyIpOworICAgICAgICAgICAgZm9ybWF0LnNldFRpbWVab25lKHR6KTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlRpbWVab25lIGlzIHNldCBpbmNvcnJlY3RseSIsIHR6LmVxdWFscyhmb3JtYXQKKyAgICAgICAgICAgICAgICAgICAgLmdldFRpbWVab25lKCkpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZERlY2ltYWxGb3JtYXRTeW1ib2xzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZERlY2ltYWxGb3JtYXRTeW1ib2xzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJmMWEzY2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkRGVjaW1hbEZvcm1hdFN5bWJvbHNUZXN0LmphdmEKQEAgLTAsMCArMSwxNjAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS50ZXh0OworCitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdFN5bWJvbHM7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGREZWNpbWFsRm9ybWF0U3ltYm9sc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBEZWNpbWFsRm9ybWF0U3ltYm9scyBkZnM7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgZGZzID0gbmV3IERlY2ltYWxGb3JtYXRTeW1ib2xzKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9SSUhhcm1vbnlfY29tcGF0aWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBPYmplY3RJbnB1dFN0cmVhbSBpID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIERlY2ltYWxGb3JtYXRTeW1ib2xzIHN5bWJvbHMgPSBuZXcgRGVjaW1hbEZvcm1hdFN5bWJvbHMoCisgICAgICAgICAgICAgICAgICAgIExvY2FsZS5GUkFOQ0UpOworICAgICAgICAgICAgaSA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICAgICAgZ2V0Q2xhc3MoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRDbGFzc0xvYWRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldFJlc291cmNlQXNTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgICJzZXJpYWxpemF0aW9uL2phdmEvdGV4dC9EZWNpbWFsRm9ybWF0U3ltYm9scy5zZXIiKSk7CisgICAgICAgICAgICBEZWNpbWFsRm9ybWF0U3ltYm9scyBzeW1ib2xzRCA9IChEZWNpbWFsRm9ybWF0U3ltYm9scykgaQorICAgICAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHN5bWJvbHMsIHN5bWJvbHNEKTsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJGYWlsZWQgdG8gbG9hZCAvc2VyaWFsaXphdGlvbi9qYXZhL3RleHQvIiArCisgICAgICAgICAgICAgICAgICAgICJEZWNpbWFsRm9ybWF0U3ltYm9scy5zZXIiLCBpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKGkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnREZWNpbWFsRm9ybWF0U3ltYm9sc1JJRnJhbmNlKGRmcyk7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICBuZXcgRGVjaW1hbEZvcm1hdFN5bWJvbHMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdFN5bWJvbHMjRGVjaW1hbEZvcm1hdFN5bWJvbHMoamF2YS51dGlsLkxvY2FsZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfdXRpbF9Mb2NhbGUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRGVjaW1hbEZvcm1hdFN5bWJvbHMobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TW9uZXRhcnlEZWNpbWFsU2VwYXJhdG9yKCkgeworICAgICAgICBkZnMuc2V0TW9uZXRhcnlEZWNpbWFsU2VwYXJhdG9yKCcsJyk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IE1vbmV0YXJ5RGVjaW1hbFNlcGFyYXRvciBzeW1ib2wiLAorICAgICAgICAgICAgICAgICcsJywgZGZzLmdldE1vbmV0YXJ5RGVjaW1hbFNlcGFyYXRvcigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc2hDb2RlKCkgeworICAgICAgICBEZWNpbWFsRm9ybWF0U3ltYm9scyBkZnMxID0gbmV3IERlY2ltYWxGb3JtYXRTeW1ib2xzKCk7CisgICAgICAgIERlY2ltYWxGb3JtYXRTeW1ib2xzIGRmczIgPSAoRGVjaW1hbEZvcm1hdFN5bWJvbHMpIGRmczEuY2xvbmUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSGFzaCBjb2RlcyBvZiBlcXVhbCBvYmplY3QgYXJlIGVxdWFsIiwgZGZzMgorICAgICAgICAgICAgICAgIC5oYXNoQ29kZSgpID09IGRmczEuaGFzaENvZGUoKSk7CisgICAgICAgIGRmczEuc2V0SW5maW5pdHkoImluZmluaXR5X2luZmluaXR5Iik7CisgICAgICAgIGFzc2VydFRydWUoIkhhc2ggY29kZXMgb2Ygbm9uLWVxdWFsIG9iamVjdHMgYXJlIGVxdWFsIiwgZGZzMgorICAgICAgICAgICAgICAgIC5oYXNoQ29kZSgpICE9IGRmczEuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jbG9uZSgpIHsKKyAgICAgICAgLy8gY2FzZSAxOiBDb21wYXJlIG9mIGludGVybmFsIHZhcmlhYmxlcyBvZiBjbG9uZWQgb2JqZWN0cworICAgICAgICBEZWNpbWFsRm9ybWF0U3ltYm9scyBmcyA9IG5ldyBEZWNpbWFsRm9ybWF0U3ltYm9scyhMb2NhbGUuVVMpOworICAgICAgICBEZWNpbWFsRm9ybWF0U3ltYm9scyBmc2MgPSAoRGVjaW1hbEZvcm1hdFN5bWJvbHMpIGZzLmNsb25lKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhmcy5nZXRDdXJyZW5jeSgpLCBmc2MuZ2V0Q3VycmVuY3koKSk7CisKKyAgICAgICAgLy8gY2FzZSAyOiBDb21wYXJlIG9mIGNsb25lcworICAgICAgICBmcyA9IG5ldyBEZWNpbWFsRm9ybWF0U3ltYm9scygpOworICAgICAgICBEZWNpbWFsRm9ybWF0U3ltYm9scyBmc2MyID0gKERlY2ltYWxGb3JtYXRTeW1ib2xzKSAoZnMuY2xvbmUoKSk7CisgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgb2JqZWN0cyBhcmUgZXF1YWwKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiT2JqZWN0J3MgY2xvbmUgaXNuJ3QgZXF1YWwhIiwgZnMuZXF1YWxzKGZzYzIpKTsKKworICAgICAgICAvLyBjYXNlIDM6CisgICAgICAgIC8vIGNoYW5nZSB0aGUgY29udGVudCBvZiB0aGUgY2xvbmUgYW5kIG1ha2Ugc3VyZSBpdCdzIG5vdCBlcXVhbAorICAgICAgICAvLyBhbnltb3JlCisgICAgICAgIC8vIHZlcmlmaWVzIHRoYXQgaXQncyBkYXRhIGlzIG5vdyBkaXN0aW5jdCBmcm9tIHRoZSBvcmlnaW5hbAorICAgICAgICBmcy5zZXROYU4oIm5vdC1hLW51bWJlciIpOworICAgICAgICBhc3NlcnRUcnVlKCJPYmplY3QncyBjaGFuZ2VkIGNsb25lIHNob3VsZCBub3QgYmUgZXF1YWwhIiwgIWZzLmVxdWFscyhmc2MyKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRDdXJyZW5jeVN5bWJvbExqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICBkZnMuc2V0Q3VycmVuY3lTeW1ib2woIiQiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgQ3VycmVuY3lTeW1ib2wgc3ltYm9sIiwgIiQiLCBkZnMuZ2V0Q3VycmVuY3lTeW1ib2woKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRNb25ldGFyeURlY2ltYWxTZXBhcmF0b3JDKCkgeworICAgICAgICBkZnMuc2V0TW9uZXRhcnlEZWNpbWFsU2VwYXJhdG9yKCcjJyk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IE1vbmV0YXJ5RGVjaW1hbFNlcGFyYXRvciBzeW1ib2wiLAorICAgICAgICAgICAgICAgICcjJywgZGZzLmdldE1vbmV0YXJ5RGVjaW1hbFNlcGFyYXRvcigpKTsKKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBhc3NlcnREZWNpbWFsRm9ybWF0U3ltYm9sc1JJRnJhbmNlKERlY2ltYWxGb3JtYXRTeW1ib2xzIGRmcykgeworICAgICAgICAvLyBWYWx1ZXMgYmFzZWQgb24gSmF2YSAxLjUgUkkgRGVjaW1hbEZvcm1hdFN5bWJvbHMgZm9yIExvY2FsZS5GUkFOQ0UKKyAgICAgICAgLyoKKyAgICAgICAgICogY3VycmVuY3kgPSBbRVVSXQorICAgICAgICAgKiBjdXJyZW5jeVN5bWJvbCA9IFtVKzIwYWNdIC8vIEVVUk8gU0lHTgorICAgICAgICAgKiBkZWNpbWFsU2VwYXJhdG9yID0gWyxdW1UrMDAyY10KKyAgICAgICAgICogZGlnaXQgPSBbI11bVSswMDIzXQorICAgICAgICAgKiBncm91cGluZ1NlcGFyYXRvciA9IFtVKzAwYTBdIC8vIE5PTi1CUkVBS0lORyBTUEFDRQorICAgICAgICAgKiBpbmZpbml0eSA9IFtVKzIyMWVdIC8vIElORklOSVRZCisgICAgICAgICAqIGludGVybmF0aW9uYWxDdXJyZW5jeVN5bWJvbCA9IFtFVVJdCisgICAgICAgICAqIG1pbnVzU2lnbiA9IFstXVtVKzAwMmRdCisgICAgICAgICAqIG1vbmV0YXJ5RGVjaW1hbFNlcGFyYXRvciA9IFssXVtVKzAwMmNdCisgICAgICAgICAqIG5hTiA9IFtVK2ZmZmRdIC8vIFJFUExBQ0VNRU5UIENIQVJBQ1RFUgorICAgICAgICAgKiBwYXR0ZXJuU2VwYXJhdG9yID0gWztdW1UrMDAzYl0KKyAgICAgICAgICogcGVyTWlsbCA9IFtVKzIwMzBdIC8vIFBFUiBNSUxMRQorICAgICAgICAgKiBwZXJjZW50ID0gWyVdW1UrMDAyNV0KKyAgICAgICAgICogemVyb0RpZ2l0ID0gWzBdW1UrMDAzMF0KKyAgICAgICAgICovCisgICAgICAgIGFzc2VydEVxdWFscygiRVVSIiwgZGZzLmdldEN1cnJlbmN5KCkuZ2V0Q3VycmVuY3lDb2RlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlx1MjBBQyIsIGRmcy5nZXRDdXJyZW5jeVN5bWJvbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCcsJywgZGZzLmdldERlY2ltYWxTZXBhcmF0b3IoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygnIycsIGRmcy5nZXREaWdpdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdcdTAwYTAnLCBkZnMuZ2V0R3JvdXBpbmdTZXBhcmF0b3IoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiXHUyMjFlIiwgZGZzLmdldEluZmluaXR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkVVUiIsIGRmcy5nZXRJbnRlcm5hdGlvbmFsQ3VycmVuY3lTeW1ib2woKSk7CisgICAgICAgIGFzc2VydEVxdWFscygnLScsIGRmcy5nZXRNaW51c1NpZ24oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygnLCcsIGRmcy5nZXRNb25ldGFyeURlY2ltYWxTZXBhcmF0b3IoKSk7CisgICAgICAgIC8vIFJJJ3MgZGVmYXVsdCBOYU4gaXMgVStGRkZELCBIYXJtb255J3MgaXMgYmFzZWQgb24gSUNVCisgICAgICAgIC8vIFRoaXMgc3VnZ2VzdHMgYW4gUkkgYnVnLCBhc3N1bWluZyB0aGF0IG5vbi1VVEY4IGJ5dGVzIGFyZSBVVEY4IGFuZAorICAgICAgICAvLyBnZXR0aW5nIGEgY29udmVyc2lvbiBmYWlsdXJlLgorICAgICAgICBhc3NlcnRFcXVhbHMoIlx1RkZGRCIsIGRmcy5nZXROYU4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygnXHUwMDNiJywgZGZzLmdldFBhdHRlcm5TZXBhcmF0b3IoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygnXHUyMDMwJywgZGZzLmdldFBlck1pbGwoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygnJScsIGRmcy5nZXRQZXJjZW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoJzAnLCBkZnMuZ2V0WmVyb0RpZ2l0KCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGREZWNpbWFsRm9ybWF0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZERlY2ltYWxGb3JtYXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjNlMDE2ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGREZWNpbWFsRm9ybWF0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTAwNyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnRGVjaW1hbDsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yOworaW1wb3J0IGphdmEudGV4dC5EZWNpbWFsRm9ybWF0OworaW1wb3J0IGphdmEudGV4dC5EZWNpbWFsRm9ybWF0U3ltYm9sczsKK2ltcG9ydCBqYXZhLnRleHQuRmllbGRQb3NpdGlvbjsKK2ltcG9ydCBqYXZhLnRleHQuTnVtYmVyRm9ybWF0OworaW1wb3J0IGphdmEudGV4dC5QYXJzZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnRleHQuUGFyc2VQb3NpdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQml0U2V0OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9EZWNpbWFsRm9ybWF0OworCitwdWJsaWMgY2xhc3MgT2xkRGVjaW1hbEZvcm1hdFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Zvcm1hdFRvQ2hhcmFjdGVySXRlcmF0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGl0ZXJhdG9yOworICAgICAgICBpbnRbXSBydW5TdGFydHM7CisgICAgICAgIGludFtdIHJ1bkxpbWl0czsKKyAgICAgICAgU3RyaW5nIHJlc3VsdDsKKyAgICAgICAgY2hhciBjdXJyZW50OworCisgICAgICAgIC8vIEZvciBCaWdEZWNpbWFsIHdpdGggbXVsdGlwbGllciB0ZXN0LgorICAgICAgICBEZWNpbWFsRm9ybWF0IGRmID0gbmV3IERlY2ltYWxGb3JtYXQoKTsKKyAgICAgICAgZGYuc2V0TXVsdGlwbGllcigxMCk7CisgICAgICAgIGl0ZXJhdG9yID0gZGYuZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcihuZXcgQmlnRGVjaW1hbCgiMTIzNDU2Nzg5MDEyMzQ1Njc4OTAiKSk7CisgICAgICAgIHJlc3VsdCA9ICIxMjMsNDU2LDc4OSwwMTIsMzQ1LDY3OCw5MDAiOworICAgICAgICBjdXJyZW50ID0gaXRlcmF0b3IuY3VycmVudCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlc3VsdC5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIGNoYXIgQCIgKyBpLCByZXN1bHQuY2hhckF0KGkpLCBjdXJyZW50KTsKKyAgICAgICAgICAgIGN1cnJlbnQgPSBpdGVyYXRvci5uZXh0KCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBGb3IgQmlnRGVjaW1hbCB3aXRoIG11bHRpcGxpZXIgdGVzdC4KKyAgICAgICAgZGYgPSBuZXcgRGVjaW1hbEZvcm1hdCgpOworICAgICAgICBkZi5zZXRNdWx0aXBsaWVyKC0xKTsKKyAgICAgICAgZGYuc2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKDIwKTsKKyAgICAgICAgaXRlcmF0b3IgPSBkZi5mb3JtYXRUb0NoYXJhY3Rlckl0ZXJhdG9yKG5ldyBCaWdEZWNpbWFsKCIxLjIzNDU2Nzg5MDEyMzQ1Njc4OTAxIikpOworICAgICAgICByZXN1bHQgPSAiLTEuMjM0NTY3ODkwMTIzNDU2Nzg5MDEiOworICAgICAgICBjdXJyZW50ID0gaXRlcmF0b3IuY3VycmVudCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlc3VsdC5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIGNoYXIgQCIgKyBpLCByZXN1bHQuY2hhckF0KGkpLCBjdXJyZW50KTsKKyAgICAgICAgICAgIGN1cnJlbnQgPSBpdGVyYXRvci5uZXh0KCk7CisgICAgICAgIH0KKworICAgICAgICBpdGVyYXRvciA9IG5ldyBEZWNpbWFsRm9ybWF0KCkKKyAgICAgICAgICAgICAgICAuZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcihuZXcgQmlnRGVjaW1hbCgiMS4yMzQ1Njc4OUUxMjM0IikpOworICAgICAgICBydW5TdGFydHMgPSBuZXcgaW50W10gezAsIDAsIDIsIDMsIDMsIDMsIDYsIDcsIDcsIDcsIDEwLCAxMSwgMTEsIDExLCAxNH07CisgICAgICAgIHJ1bkxpbWl0cyA9IG5ldyBpbnRbXSB7MiwgMiwgMywgNiwgNiwgNiwgNywgMTAsIDEwLCAxMCwgMTEsIDE0LCAxNCwgMTQsIDE1fTsKKyAgICAgICAgcmVzdWx0ID0gIjEyLDM0NSw2NzgsOTAwLCI7IC8vIDAwMCwwMDAsMDAwLDAwMC4uLi4KKyAgICAgICAgY3VycmVudCA9IGl0ZXJhdG9yLmN1cnJlbnQoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBydW5TdGFydHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygid3Jvbmcgc3RhcnQgQCIgKyBpLCBydW5TdGFydHNbaV0sIGl0ZXJhdG9yLmdldFJ1blN0YXJ0KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ3cm9uZyBsaW1pdCBAIiArIGksIHJ1bkxpbWl0c1tpXSwgaXRlcmF0b3IuZ2V0UnVuTGltaXQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIGNoYXIgQCIgKyBpLCByZXN1bHQuY2hhckF0KGkpLCBjdXJyZW50KTsKKyAgICAgICAgICAgIGN1cnJlbnQgPSBpdGVyYXRvci5uZXh0KCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGl0ZXJhdG9yLmdldEJlZ2luSW5kZXgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxNjQ2LCBpdGVyYXRvci5nZXRFbmRJbmRleCgpKTsKKworICAgICAgICBpdGVyYXRvciA9IG5ldyBEZWNpbWFsRm9ybWF0KCkKKyAgICAgICAgICAgICAgICAuZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcihuZXcgQmlnRGVjaW1hbCgiMS4yMzQ1Njc4OUUzMDEiKSk7CisgICAgICAgIHJ1blN0YXJ0cyA9IG5ldyBpbnRbXSB7MCwgMCwgMiwgMywgMywgMywgNiwgNywgNywgNywgMTAsIDExLCAxMSwgMTEsIDE0fTsKKyAgICAgICAgcnVuTGltaXRzID0gbmV3IGludFtdIHsyLCAyLCAzLCA2LCA2LCA2LCA3LCAxMCwgMTAsIDEwLCAxMSwgMTQsIDE0LCAxNCwgMTV9OworICAgICAgICByZXN1bHQgPSAiMTIsMzQ1LDY3OCw5MDAsIjsgLy8gMDAwLDAwMCwwMDAsMDAwLi4uLgorICAgICAgICBjdXJyZW50ID0gaXRlcmF0b3IuY3VycmVudCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJ1blN0YXJ0cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ3cm9uZyBzdGFydCBAIiArIGksIHJ1blN0YXJ0c1tpXSwgaXRlcmF0b3IuZ2V0UnVuU3RhcnQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIGxpbWl0IEAiICsgaSwgcnVuTGltaXRzW2ldLCBpdGVyYXRvci5nZXRSdW5MaW1pdCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygid3JvbmcgY2hhciBAIiArIGksIHJlc3VsdC5jaGFyQXQoaSksIGN1cnJlbnQpOworICAgICAgICAgICAgY3VycmVudCA9IGl0ZXJhdG9yLm5leHQoKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaXRlcmF0b3IuZ2V0QmVnaW5JbmRleCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQwMiwgaXRlcmF0b3IuZ2V0RW5kSW5kZXgoKSk7CisKKyAgICAgICAgaXRlcmF0b3IgPSBuZXcgRGVjaW1hbEZvcm1hdCgpCisgICAgICAgICAgICAgICAgLmZvcm1hdFRvQ2hhcmFjdGVySXRlcmF0b3IobmV3IEJpZ0RlY2ltYWwoIjEuMjM0NTY3OEU0IikpOworICAgICAgICBydW5TdGFydHMgPSBuZXcgaW50W10gezAsIDAsIDIsIDMsIDMsIDMsIDYsIDcsIDcsIDd9OworICAgICAgICBydW5MaW1pdHMgPSBuZXcgaW50W10gezIsIDIsIDMsIDYsIDYsIDYsIDcsIDEwLCAxMCwgMTB9OworICAgICAgICByZXN1bHQgPSAiMTIsMzQ1LjY3OCI7CisgICAgICAgIGN1cnJlbnQgPSBpdGVyYXRvci5jdXJyZW50KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcnVuU3RhcnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIHN0YXJ0IEAiICsgaSwgcnVuU3RhcnRzW2ldLCBpdGVyYXRvci5nZXRSdW5TdGFydCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygid3JvbmcgbGltaXQgQCIgKyBpLCBydW5MaW1pdHNbaV0sIGl0ZXJhdG9yLmdldFJ1bkxpbWl0KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ3cm9uZyBjaGFyIEAiICsgaSwgcmVzdWx0LmNoYXJBdChpKSwgY3VycmVudCk7CisgICAgICAgICAgICBjdXJyZW50ID0gaXRlcmF0b3IubmV4dCgpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygwLCBpdGVyYXRvci5nZXRCZWdpbkluZGV4KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTAsIGl0ZXJhdG9yLmdldEVuZEluZGV4KCkpOworCisgICAgICAgIGl0ZXJhdG9yID0gbmV3IERlY2ltYWxGb3JtYXQoKQorICAgICAgICAgICAgICAgIC5mb3JtYXRUb0NoYXJhY3Rlckl0ZXJhdG9yKG5ldyBCaWdJbnRlZ2VyKCIxMjM0NTY3ODkiKSk7CisgICAgICAgIHJ1blN0YXJ0cyA9IG5ldyBpbnRbXSB7MCwgMCwgMCwgMywgNCwgNCwgNCwgNywgOCwgOCwgOH07CisgICAgICAgIHJ1bkxpbWl0cyA9IG5ldyBpbnRbXSB7MywgMywgMywgNCwgNywgNywgNywgOCwgMTEsIDExLCAxMX07CisgICAgICAgIHJlc3VsdCA9ICIxMjMsNDU2LDc4OSI7CisgICAgICAgIGN1cnJlbnQgPSBpdGVyYXRvci5jdXJyZW50KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcnVuU3RhcnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIHN0YXJ0IEAiICsgaSwgcnVuU3RhcnRzW2ldLCBpdGVyYXRvci5nZXRSdW5TdGFydCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygid3JvbmcgbGltaXQgQCIgKyBpLCBydW5MaW1pdHNbaV0sIGl0ZXJhdG9yLmdldFJ1bkxpbWl0KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ3cm9uZyBjaGFyIEAiICsgaSwgcmVzdWx0LmNoYXJBdChpKSwgY3VycmVudCk7CisgICAgICAgICAgICBjdXJyZW50ID0gaXRlcmF0b3IubmV4dCgpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygwLCBpdGVyYXRvci5nZXRCZWdpbkluZGV4KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTEsIGl0ZXJhdG9yLmdldEVuZEluZGV4KCkpOworICAgIH0KKworICAgIC8qCisgICAgICogVGVzdCB0aGUgZ2V0dGVyIGFuZCBzZXR0ZXIgb2YgcGFyc2VCaWdEZWNpbWFsIGFuZCBwYXJzZUludGVnZXJPbmx5IGFuZAorICAgICAqIHRlc3QgdGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzUGFyc2VCaWdEZWNpbWFsTGphdmFfbGFuZ19Cb29sZWFuX2lzUGFyc2VJbnRlZ2VyT25seUxqYXZhX2xhbmdfQm9vbGVhbigpIHsKKworICAgICAgICAvLyBwYXJzZUJpZ0RlY2ltYWwgZGVmYXVsdCB0byBmYWxzZQorICAgICAgICBEZWNpbWFsRm9ybWF0IGZvcm0gPSAoRGVjaW1hbEZvcm1hdCkgRGVjaW1hbEZvcm1hdAorICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZShMb2NhbGUuVVMpOworICAgICAgICBhc3NlcnRGYWxzZShmb3JtLmlzUGFyc2VCaWdEZWNpbWFsKCkpOworICAgICAgICBmb3JtLnNldFBhcnNlQmlnRGVjaW1hbCh0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShmb3JtLmlzUGFyc2VCaWdEZWNpbWFsKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOdW1iZXIgcmVzdWx0ID0gZm9ybS5wYXJzZSgiMTIzLjEyMyIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBCaWdEZWNpbWFsKCIxMjMuMTIzIiksIHJlc3VsdCk7CisgICAgICAgIH0gY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlBhcnNlRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKworICAgICAgICBmb3JtLnNldFBhcnNlQmlnRGVjaW1hbChmYWxzZSk7CisgICAgICAgIGFzc2VydEZhbHNlKGZvcm0uaXNQYXJzZUJpZ0RlY2ltYWwoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE51bWJlciByZXN1bHQgPSBmb3JtLnBhcnNlKCIxMjMuMTIzIik7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShyZXN1bHQgaW5zdGFuY2VvZiBCaWdEZWNpbWFsKTsKKyAgICAgICAgfSBjYXRjaCAoUGFyc2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiUGFyc2VFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHBhcnNlSW50ZWdlck9ubHkgZGVmYXVsdCB0byBmYWxzZQorICAgICAgICBhc3NlcnRGYWxzZShmb3JtLmlzUGFyc2VJbnRlZ2VyT25seSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzUGFyc2VJbnRlZ2VyT25seSgpIHsKKworICAgICAgICAgICAgRGVjaW1hbEZvcm1hdCBmb3JtYXQgPSBuZXcgRGVjaW1hbEZvcm1hdCgpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIkRlZmF1bHQgdmFsdWUgb2YgaXNQYXJzZUludGVnZXJPbmx5IGlzIHRydWUiLAorICAgICAgICAgICAgICAgICAgICBmb3JtYXQuaXNQYXJzZUludGVnZXJPbmx5KCkpOworCisgICAgICAgICAgICBmb3JtYXQuc2V0UGFyc2VJbnRlZ2VyT25seSh0cnVlKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZm9ybWF0LmlzUGFyc2VJbnRlZ2VyT25seSgpKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTnVtYmVyIHJlc3VsdCA9IGZvcm1hdC5wYXJzZSgiMTIzLjEyMyIpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhuZXcgTG9uZygiMTIzIiksIHJlc3VsdCk7CisgICAgICAgICAgICB9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiUGFyc2VFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZm9ybWF0LnNldFBhcnNlSW50ZWdlck9ubHkoZmFsc2UpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZm9ybWF0LmlzUGFyc2VJbnRlZ2VyT25seSgpKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTnVtYmVyIHJlc3VsdCA9IGZvcm1hdC5wYXJzZSgiMTIzLjEyMyIpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhuZXcgRG91YmxlKCIxMjMuMTIzIiksIHJlc3VsdCk7CisgICAgICAgICAgICB9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiUGFyc2VFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzR3JvdXBpbmdVc2VkKCkgeworICAgICAgICBTdHJpbmcgW10gcGF0dGVybnMgPSB7IiMjIyMuIyMiLCAiIyMjIyMjLiMjIyMjIyIsICIwMDAwMDAuMDAwMDAwIiwKKyAgICAgICAgICAgICAgICAiIyMjIyMjLjAwMDAwMCIsICIwMDAwMDAuIyMjIyMjIiwgIiAjIyMuIyMjIiwgIiQjIyMjIy4jIyMjIyMiLAorICAgICAgICAgICAgICAgICIkJCMjIyMuIyMjIyMjIn07CisKKyAgICAgICAgZm9yKFN0cmluZyBwYXR0ZXJuOnBhdHRlcm5zKSB7CisgICAgICAgICAgICBEZWNpbWFsRm9ybWF0IGZvcm1hdCA9IG5ldyBEZWNpbWFsRm9ybWF0KHBhdHRlcm4pOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZm9ybWF0LmlzR3JvdXBpbmdVc2VkKCkpOworICAgICAgICB9CisKKyAgICAgICAgRGVjaW1hbEZvcm1hdCBmb3JtYXQgPSBuZXcgRGVjaW1hbEZvcm1hdCgiIyMjLCMjIyMiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShmb3JtYXQuaXNHcm91cGluZ1VzZWQoKSk7CisgICAgfQorCisgICAgLy8gVGVzdCB0aGUgdHlwZSBvZiB0aGUgcmV0dXJuZWQgb2JqZWN0CisgICAgcHVibGljIHZvaWQgdGVzdF9wYXJzZUxqYXZhX2xhbmdfU3RyaW5nX0xqYXZhX3RleHRfUGFyc2VQb3NpdGlvbigpIHsKKyAgICAgICAgRGVjaW1hbEZvcm1hdCBmb3JtID0gKERlY2ltYWxGb3JtYXQpIERlY2ltYWxGb3JtYXQuZ2V0SW5zdGFuY2UoTG9jYWxlLlVTKTsKKyAgICAgICAgZm9ybS5zZXRQYXJzZUludGVnZXJPbmx5KHRydWUpOworICAgICAgICBmb3JtLnNldFBhcnNlQmlnRGVjaW1hbCh0cnVlKTsKKworICAgICAgICBmaW5hbCBTdHJpbmcgZG91YmxlTWF4MiA9ICIzNTksNTM4LDYyNiw5NzIsNDYzLDE0MSw2MjksMDU0LDg0Nyw0NjMsNDA4LCIKKyAgICAgICAgICAgICsgIjcxMyw1OTYsMTQxLDEzNSwwNTEsNjg5LDk5MywxOTcsODM0LDk1Myw2MDYsMzE0LDUyMSw1NjAsMDU3LDA3NywiCisgICAgICAgICAgICArICI1MjEsMTc5LDExNywyNjUsNTMzLDc1NiwzNDMsMDgwLDkxNyw5MDcsMDI4LDc2NCw5MjgsNDY4LDY0Miw2NTMsIgorICAgICAgICAgICAgKyAiNzc4LDkyOCwzNjUsNTM2LDkzNSwwOTMsNDA3LDA3NSwwMzMsOTcyLDA5OSw4MjEsMTUzLDEwMiw1NjQsMTUyLCIKKyAgICAgICAgICAgICsgIjQ5MCw5ODAsMTgwLDc3OCw2NTcsODg4LDE1MSw3MzcsMDE2LDkxMCwyNjcsODg0LDYwOSwxNjYsNDczLDgwNiwiCisgICAgICAgICAgICArICI0NDUsODk2LDMzMSw2MTcsMTE4LDY2NCwyNDYsNjk2LDU0OSw1OTUsNjUyLDQwOCwyODksNDQ2LDMzNyw0NzYsIgorICAgICAgICAgICAgKyAiMzU0LDM2MSw4MzgsNTk5LDc2Miw1MDAsODA4LDA1MiwzNjgsMjQ5LDcxNiw3MzYiOworICAgICAgICBOdW1iZXIgbnVtYmVyID0gZm9ybS5wYXJzZShkb3VibGVNYXgyLCBuZXcgUGFyc2VQb3NpdGlvbigwKSk7CisgICAgICAgIGFzc2VydFRydWUobnVtYmVyIGluc3RhbmNlb2YgQmlnRGVjaW1hbCk7CisgICAgICAgIEJpZ0RlY2ltYWwgcmVzdWx0ID0gKEJpZ0RlY2ltYWwpbnVtYmVyOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IEJpZ0RlY2ltYWwoRG91YmxlLk1BWF9WQUxVRSkuYWRkKG5ldyBCaWdEZWNpbWFsKAorICAgICAgICAgICAgICAgIERvdWJsZS5NQVhfVkFMVUUpKSwgcmVzdWx0KTsKKyAgICB9CisKKyAgICAvLyBBbmRyb2lkT25seTogRGlmZmVyZW5jZSB0byBSSQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TWF4aW11bUludGVnZXJEaWdpdHNfQW5kcm9pZE9ubHkoKSB7CisgICAgICAgIGZpbmFsIGludCBtYXhJbnREaWdpdCA9IDMwOTsKKworICAgICAgICAvLyBXaGVuIHVzZSBkZWZhdWx0IGxvY2FsZSwgaW4gdGhpcyBjYXNlIHpoX0NOCisgICAgICAgIC8vIHRoZSByZXR1cm5lZCBpbnN0YW5jZSBvZiBOdW1iZXJGb3JtYXQgaXMgYSBEZWNpbWFsRm9ybWF0CisgICAgICAgIERlY2ltYWxGb3JtYXQgZm9ybSA9IG5ldyBEZWNpbWFsRm9ybWF0KCIwMC4jIyNFMCIpOworICAgICAgICBOdW1iZXJGb3JtYXQgbmZvcm0gPSBEZWNpbWFsRm9ybWF0LmdldEluc3RhbmNlKExvY2FsZS5VUyk7CisgICAgICAgIG5mb3JtID0gRGVjaW1hbEZvcm1hdC5nZXRJbnN0YW5jZShMb2NhbGUuVVMpOworICAgICAgICBmb3JtID0gbnVsbDsKKyAgICAgICAgaWYgKG5mb3JtIGluc3RhbmNlb2YgRGVjaW1hbEZvcm1hdCkgeworICAgICAgICAgICAgZm9ybSA9IChEZWNpbWFsRm9ybWF0KSBuZm9ybTsKKyAgICAgICAgfQorICAgICAgICAvLyBnZXRNYXhpbXVtSW50ZWdlckRpZ2l0cyBmcm9tIE51bWJlckZvcm1hdCBkZWZhdWx0IHRvIDMwOQorICAgICAgICAvLyBnZXRNYXhpbXVtSW50ZWdlckRpZ2l0cyBmcm9tIERlY2ltYWxGb3JtYXQgZGVmYXVsdCB0byAzMDkKKyAgICAgICAgLy8gdGhlIGZvbGxvd2luZyAyIGFzc2VydGlvbnMgd2lsbCBmYWlsIG9uIFJJIGltcGxlbWVudGF0aW9uLCBzaW5jZSB0aGUKKyAgICAgICAgLy8gaW1wbGVtZW50YXRpb24gb2YgSUNVIGFuZCBSSSBhcmUgbm90IGlkZW50aWNhbC4gUkkgZG9lcyBub3QgZ2l2ZQorICAgICAgICAvLyBEZWNpbWFsRm9ybWF0IGFuIGluaXRpYWwgYm91bmQgYWJvdXQgaXRzIG1heGltdW1JbnRlZ2VyRGlnaXRzCisgICAgICAgIC8vIChkZWZhdWx0IHRvIEludGVnZXIuTUFYX1ZBTFVFOiAyMTQ3NDgzNjQ3ICkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1heEludERpZ2l0LCBuZm9ybS5nZXRNYXhpbXVtSW50ZWdlckRpZ2l0cygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1heEludERpZ2l0LCBmb3JtLmdldE1heGltdW1JbnRlZ2VyRGlnaXRzKCkpOworICAgIH0KKworICAgIC8vIEFuZHJvaWRPbmx5OiBzZWNvbmQgMCBuZWVkcyB0byBiZSBxdW90ZWQgaW4gaWN1LgorICAgIC8vIChxdW90aW5nIHNwZWNpYWwgY2hhcmFjdGVycyBpbiBwcmVmaXggYW5kIHN1ZmZpeCBuZWNlc3NhcnkpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRNYXhpbXVtSW50ZWdlckRpZ2l0czIoKSB7CisgICAgICAgIC8vIHJlZ3Jlc3Npb24gdGVzdCBmb3IgSEFSTU9OWS04NzgKKyAgICAgICAgYXNzZXJ0VHJ1ZShuZXcgRGVjaW1hbEZvcm1hdCgiMFx0JzAnIikuZ2V0TWF4aW11bUludGVnZXJEaWdpdHMoKSA+IDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0UG9zaXRpdmVQcmVmaXhMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgRGVjaW1hbEZvcm1hdCBmb3JtYXQgPSBuZXcgRGVjaW1hbEZvcm1hdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGZvcm1hdC5nZXRQb3NpdGl2ZVByZWZpeCgpKTsKKworICAgICAgICBmb3JtYXQuc2V0UG9zaXRpdmVQcmVmaXgoIlBvc1ByZiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlBvc1ByZiIsIGZvcm1hdC5nZXRQb3NpdGl2ZVByZWZpeCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZm9ybWF0LnBhcnNlKCJQb3NQcmYxMjMuNDUiKS5kb3VibGVWYWx1ZSgpID09IDEyMy40NSk7CisgICAgICAgIH0gY2F0Y2goamF2YS50ZXh0LlBhcnNlRXhjZXB0aW9uIHBlKSB7CisgICAgICAgICAgICBmYWlsKCJQYXJzZUV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisKKyAgICAgICAgZm9ybWF0LnNldFBvc2l0aXZlUHJlZml4KCIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBmb3JtYXQuZ2V0UG9zaXRpdmVQcmVmaXgoKSk7CisKKyAgICAgICAgZm9ybWF0LnNldFBvc2l0aXZlUHJlZml4KG51bGwpOworICAgICAgICBhc3NlcnROdWxsKGZvcm1hdC5nZXRQb3NpdGl2ZVByZWZpeCgpKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRQb3NpdGl2ZVN1ZmZpeExqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICBEZWNpbWFsRm9ybWF0IGZvcm1hdCA9IG5ldyBEZWNpbWFsRm9ybWF0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgZm9ybWF0LmdldFBvc2l0aXZlU3VmZml4KCkpOworCisgICAgICAgIGZvcm1hdC5zZXRQb3NpdGl2ZVN1ZmZpeCgiUG9zU2Z4Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiUG9zU2Z4IiwgZm9ybWF0LmdldFBvc2l0aXZlU3VmZml4KCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShmb3JtYXQucGFyc2UoIjEyMy40NVBvc1NmeCIpLmRvdWJsZVZhbHVlKCkgPT0gMTIzLjQ1KTsKKyAgICAgICAgfSBjYXRjaChqYXZhLnRleHQuUGFyc2VFeGNlcHRpb24gcGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlBhcnNlRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKworICAgICAgICBmb3JtYXQuc2V0UG9zaXRpdmVTdWZmaXgoIiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGZvcm1hdC5nZXRQb3NpdGl2ZVN1ZmZpeCgpKTsKKworICAgICAgICBmb3JtYXQuc2V0UG9zaXRpdmVTdWZmaXgobnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoZm9ybWF0LmdldFBvc2l0aXZlU3VmZml4KCkpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldE5lZ2F0aXZlUHJlZml4TGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIERlY2ltYWxGb3JtYXQgZm9ybWF0ID0gbmV3IERlY2ltYWxGb3JtYXQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCItIiwgZm9ybWF0LmdldE5lZ2F0aXZlUHJlZml4KCkpOworCisgICAgICAgIGZvcm1hdC5zZXROZWdhdGl2ZVByZWZpeCgiTmVnUHJmIik7CisgICAgICAgIGFzc2VydEVxdWFscygiTmVnUHJmIiwgZm9ybWF0LmdldE5lZ2F0aXZlUHJlZml4KCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShmb3JtYXQucGFyc2UoIk5lZ1ByZjEyMy40NSIpLmRvdWJsZVZhbHVlKCkgPT0gLTEyMy40NSk7CisgICAgICAgIH0gY2F0Y2goamF2YS50ZXh0LlBhcnNlRXhjZXB0aW9uIHBlKSB7CisgICAgICAgICAgICBmYWlsKCJQYXJzZUV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgICAgIGZvcm1hdC5zZXROZWdhdGl2ZVByZWZpeCgiIik7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgZm9ybWF0LmdldE5lZ2F0aXZlUHJlZml4KCkpOworCisgICAgICAgIGZvcm1hdC5zZXROZWdhdGl2ZVByZWZpeChudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChmb3JtYXQuZ2V0TmVnYXRpdmVQcmVmaXgoKSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0TmVnYXRpdmVTdWZmaXhMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgRGVjaW1hbEZvcm1hdCBmb3JtYXQgPSBuZXcgRGVjaW1hbEZvcm1hdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGZvcm1hdC5nZXROZWdhdGl2ZVN1ZmZpeCgpKTsKKworICAgICAgICBmb3JtYXQuc2V0TmVnYXRpdmVTdWZmaXgoIk5lZ1NmeCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIk5lZ1NmeCIsIGZvcm1hdC5nZXROZWdhdGl2ZVN1ZmZpeCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZm9ybWF0LnBhcnNlKCIxMjMuNDVOZWdQZngiKS5kb3VibGVWYWx1ZSgpID09IDEyMy40NSk7CisgICAgICAgIH0gY2F0Y2goamF2YS50ZXh0LlBhcnNlRXhjZXB0aW9uIHBlKSB7CisgICAgICAgICAgICBmYWlsKCJQYXJzZUV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisKKyAgICAgICAgZm9ybWF0LnNldE5lZ2F0aXZlU3VmZml4KCIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBmb3JtYXQuZ2V0TmVnYXRpdmVTdWZmaXgoKSk7CisKKyAgICAgICAgZm9ybWF0LnNldE5lZ2F0aXZlU3VmZml4KG51bGwpOworICAgICAgICBhc3NlcnROdWxsKGZvcm1hdC5nZXROZWdhdGl2ZVN1ZmZpeCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvTG9jYWxpemVkUGF0dGVybigpIHsKKyAgICAgICAgRGVjaW1hbEZvcm1hdCBmb3JtYXQgPSBuZXcgRGVjaW1hbEZvcm1hdCgpOworICAgICAgICBmb3JtYXQuc2V0RGVjaW1hbEZvcm1hdFN5bWJvbHMobmV3IERlY2ltYWxGb3JtYXRTeW1ib2xzKExvY2FsZS5VUykpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9ybWF0LmFwcGx5TG9jYWxpemVkUGF0dGVybigiIy4jIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHBhdHRlcm4gMSIsICIjMC4jIiwgZm9ybWF0LnRvTG9jYWxpemVkUGF0dGVybigpKTsKKyAgICAgICAgICAgIGZvcm1hdC5hcHBseUxvY2FsaXplZFBhdHRlcm4oIiMuIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHBhdHRlcm4gMiIsICIjMC4iLCBmb3JtYXQudG9Mb2NhbGl6ZWRQYXR0ZXJuKCkpOworICAgICAgICAgICAgZm9ybWF0LmFwcGx5TG9jYWxpemVkUGF0dGVybigiIyIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYXR0ZXJuIDMiLCAiIyIsIGZvcm1hdC50b0xvY2FsaXplZFBhdHRlcm4oKSk7CisgICAgICAgICAgICBmb3JtYXQuYXBwbHlMb2NhbGl6ZWRQYXR0ZXJuKCIuIyIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYXR0ZXJuIDQiLCAiIy4wIiwgZm9ybWF0LnRvTG9jYWxpemVkUGF0dGVybigpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90b1BhdHRlcm4oKSB7CisgICAgICAgIERlY2ltYWxGb3JtYXQgZm9ybWF0ID0gbmV3IERlY2ltYWxGb3JtYXQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIiMuIyIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYXR0ZXJuIDEiLCAiIzAuIyIsIGZvcm1hdC50b1BhdHRlcm4oKSk7CisgICAgICAgICAgICBmb3JtYXQuYXBwbHlQYXR0ZXJuKCIjLiIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYXR0ZXJuIDIiLCAiIzAuIiwgZm9ybWF0LnRvUGF0dGVybigpKTsKKyAgICAgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIiMiKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcGF0dGVybiAzIiwgIiMiLCBmb3JtYXQudG9QYXR0ZXJuKCkpOworICAgICAgICAgICAgZm9ybWF0LmFwcGx5UGF0dGVybigiLiMiKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcGF0dGVybiA0IiwgIiMuMCIsIGZvcm1hdC50b1BhdHRlcm4oKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEdyb3VwaW5nVXNlKCkgeworICAgICAgICBEZWNpbWFsRm9ybWF0IGZvcm1hdCA9IG5ldyBEZWNpbWFsRm9ybWF0KCk7CisKKyAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgZm9ybWF0LnNldEdyb3VwaW5nVXNlZChmYWxzZSk7CisgICAgICAgIGZvcm1hdC5mb3JtYXQobmV3IExvbmcoMTk3MCksIGJ1ZiwgbmV3IEZpZWxkUG9zaXRpb24oMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjE5NzAiLCBidWYudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGZvcm1hdC5pc0dyb3VwaW5nVXNlZCgpKTsKKyAgICAgICAgZm9ybWF0LmZvcm1hdChuZXcgTG9uZygxOTcwKSwgYnVmLCBuZXcgRmllbGRQb3NpdGlvbigwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTk3MDE5NzAiLCBidWYudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGZvcm1hdC5pc0dyb3VwaW5nVXNlZCgpKTsKKworICAgICAgICBmb3JtYXQuc2V0R3JvdXBpbmdVc2VkKHRydWUpOworICAgICAgICBmb3JtYXQuZm9ybWF0KG5ldyBMb25nKDE5NzApLCBidWYsIG5ldyBGaWVsZFBvc2l0aW9uKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxOTcwMTk3MDEsOTcwIiwgYnVmLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRUcnVlKGZvcm1hdC5pc0dyb3VwaW5nVXNlZCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXQoKQorICAgICAgICAvLyB0aGUgY29uc3RydWN0b3IgZm9ybSB0aGF0IHNwZWNpZmllcyBhIHBhdHRlcm4gaXMgZXF1YWwgdG8gdGhlIGZvcm0KKyAgICAgICAgLy8gY29uc3RydWN0ZWQgd2l0aCBubyBwYXR0ZXJuIGFuZCBhcHBseWluZyB0aGF0IHBhdHRlcm4gdXNpbmcgdGhlCisgICAgICAgIC8vIGFwcGx5UGF0dGVybiBjYWxsCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEZWNpbWFsRm9ybWF0IGZvcm1hdDEgPSBuZXcgRGVjaW1hbEZvcm1hdCgpOworICAgICAgICAgICAgZm9ybWF0MS5hcHBseVBhdHRlcm4oIickJzEwMDAuMDAwMCIpOworICAgICAgICAgICAgRGVjaW1hbEZvcm1hdCBmb3JtYXQyID0gbmV3IERlY2ltYWxGb3JtYXQoKTsKKyAgICAgICAgICAgIGZvcm1hdDIuYXBwbHlQYXR0ZXJuKCInJCcxMDAwLjAwMDAiKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJDb25zdHJ1Y3RlZCBmb3JtYXQgZGlkIG5vdCBtYXRjaCBhcHBsaWVkIGZvcm1hdCBvYmplY3QiLAorICAgICAgICAgICAgICAgICAgICBmb3JtYXQyLmVxdWFscyhmb3JtYXQxKSk7CisgICAgICAgICAgICBEZWNpbWFsRm9ybWF0IGZvcm1hdDMgPSBuZXcgRGVjaW1hbEZvcm1hdCgiJyQnMTAwMC4wMDAwIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiQ29uc3RydWN0ZWQgZm9ybWF0IGRpZCBub3QgbWF0Y2ggYXBwbGllZCBmb3JtYXQgb2JqZWN0IiwKKyAgICAgICAgICAgICAgICAgICAgZm9ybWF0My5lcXVhbHMoZm9ybWF0MSkpOworICAgICAgICAgICAgRGVjaW1hbEZvcm1hdCBmb3JtYXQ0ID0gbmV3IERlY2ltYWxGb3JtYXQoIickJzgwMDAuMDAwMCIpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIkNvbnN0cnVjdGVkIGZvcm1hdCBkaWQgbm90IG1hdGNoIGFwcGxpZWQgZm9ybWF0IG9iamVjdCIsCisgICAgICAgICAgICAgICAgICAgICFmb3JtYXQ0LmVxdWFscyhmb3JtYXQxKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudGV4dC5EZWNpbWFsRm9ybWF0KGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIC8vIHRoZSBjb25zdHJ1Y3RvciBmb3JtIHRoYXQgc3BlY2lmaWVzIGEgcGF0dGVybiBpcyBlcXVhbCB0byB0aGUgZm9ybQorICAgICAgICAvLyBjb25zdHJ1Y3RlZCB3aXRoIG5vIHBhdHRlcm4gYW5kIGFwcGx5aW5nIHRoYXQgcGF0dGVybiB1c2luZyB0aGUKKyAgICAgICAgLy8gYXBwbHlQYXR0ZXJuIGNhbGwKKyAgICAgICAgRGVjaW1hbEZvcm1hdCBmb3JtYXQgPSBuZXcgRGVjaW1hbEZvcm1hdCgiJyQnMDAwMC4wMDAwIik7CisgICAgICAgIERlY2ltYWxGb3JtYXQgZm9ybWF0MSA9IG5ldyBEZWNpbWFsRm9ybWF0KCk7CisgICAgICAgIGZvcm1hdDEuYXBwbHlQYXR0ZXJuKCInJCcwMDAwLjAwMDAiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29uc3RydWN0ZWQgZm9ybWF0IGRpZCBub3QgbWF0Y2ggYXBwbGllZCBmb3JtYXQgb2JqZWN0IiwKKyAgICAgICAgICAgICAgICBmb3JtYXQuZXF1YWxzKGZvcm1hdDEpKTsKKworICAgICAgICBTdHJpbmcgW10gcGF0dGVybnMgPSB7IiMjIyMuIyMiLCAiIyMjIyMjLiMjIyMjIyIsICIwMDAwMDAuMDAwMDAwIiwKKyAgICAgICAgICAgICAgICAiIyMjIyMjLjAwMDAwMCIsICIwMDAwMDAuIyMjIyMjIiwgIiAjIyMuIyMjIiwgIiQjIyMjIy4jIyMjIyMiLAorICAgICAgICAgICAgICAgICIkJCMjIyMuIyMjIyMjIiwgIiUjLCMjLCMjIywjIyMjIiwgIiMsIyMwLjAwOygjLCMjMC4wMCkifTsKKworICAgICAgICBmb3IoU3RyaW5nIHN0cjpwYXR0ZXJucykgeworICAgICAgICAgICAgbmV3IERlY2ltYWxGb3JtYXQoc3RyKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRGVjaW1hbEZvcm1hdChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHdhc24ndCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKXsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBbXSBpbmNQYXR0ZXJucyA9IHsiJSMsIyMsIyMjLCMjIyMnIiwgIiMuIyMwLjAwIn07CisgICAgICAgIGZvcihTdHJpbmcgc3RyOmluY1BhdHRlcm5zKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG5ldyBEZWNpbWFsRm9ybWF0KHN0cik7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24gZm9yIHBhdHRlcm46ICIgKyBzdHIpOworICAgICAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKXsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYXNlIDE6IFRyeSB0byBjb25zdHJ1Y3Qgb2JqZWN0IHVzaW5nIGNvcnJlY3QgcGF0dGVybiBhbmQgZnJvbWF0IHN5bWJvbHMuCisgICAgICogQ2FzZSAyOiBUcnkgdG8gY29uc3RydWN0IG9iamVjdCB1c2luZyBudWxsIGFyZ3VtZW50cy4KKyAgICAgKiBDYXNlIDM6IFRyeSB0byBjb25zdHJ1Y3Qgb2JqZWN0IHVzaW5nIGluY29ycmVjdCBwYXR0ZXJuLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZ0xqYXZhX3RleHRfRGVjaW1hbEZvcm1hdFN5bWJvbHMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBjYXNlIDE6IFRyeSB0byBjb25zdHJ1Y3Qgb2JqZWN0IHVzaW5nIGNvcnJlY3QgcGF0dGVybiBhbmQgZnJvbWF0CisgICAgICAgICAgICAvLyBzeW1ib2xzLgorICAgICAgICAgICAgRGVjaW1hbEZvcm1hdFN5bWJvbHMgZGZzID0gbmV3IERlY2ltYWxGb3JtYXRTeW1ib2xzKExvY2FsZS5DQU5BREEpOworICAgICAgICAgICAgRGVjaW1hbEZvcm1hdCBmb3JtYXQxID0gbmV3IERlY2ltYWxGb3JtYXQoIickJzEwMDAuMDAwMCIsIGRmcyk7CisgICAgICAgICAgICBEZWNpbWFsRm9ybWF0IGZvcm1hdDIgPSBuZXcgRGVjaW1hbEZvcm1hdCgpOworICAgICAgICAgICAgZm9ybWF0Mi5hcHBseVBhdHRlcm4oIickJzEwMDAuMDAwMCIpOworICAgICAgICAgICAgZm9ybWF0Mi5zZXREZWNpbWFsRm9ybWF0U3ltYm9scyhkZnMpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIkNvbnN0cnVjdGVkIGZvcm1hdCBkaWQgbm90IG1hdGNoIGFwcGxpZWQgZm9ybWF0IG9iamVjdCIsCisgICAgICAgICAgICAgICAgICAgIGZvcm1hdDIuZXF1YWxzKGZvcm1hdDEpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJDb25zdHJ1Y3RlZCBmb3JtYXQgZGlkIG5vdCBtYXRjaCBhcHBsaWVkIGZvcm1hdCBvYmplY3QiLAorICAgICAgICAgICAgICAgICAgICAhZm9ybWF0MS5lcXVhbHMobmV3IERlY2ltYWxGb3JtYXQoIickJzEwMDAuMDAwMCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IERlY2ltYWxGb3JtYXRTeW1ib2xzKExvY2FsZS5DSElOQSkpKSk7CisKKyAgICAgICAgICAgIC8vIGNhc2UgMjogVHJ5IHRvIGNvbnN0cnVjdCBvYmplY3QgdXNpbmcgbnVsbCBhcmd1bWVudHMuCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG5ldyBEZWNpbWFsRm9ybWF0KCInJCcxMDAwLjAwMDAiLCAoRGVjaW1hbEZvcm1hdFN5bWJvbHMpIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbmV3IERlY2ltYWxGb3JtYXQobnVsbCwgbmV3IERlY2ltYWxGb3JtYXRTeW1ib2xzKCkpOworICAgICAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbmV3IERlY2ltYWxGb3JtYXQobnVsbCwgKERlY2ltYWxGb3JtYXRTeW1ib2xzKSBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGNhc2UgMzogVHJ5IHRvIGNvbnN0cnVjdCBvYmplY3QgdXNpbmcgaW5jb3JyZWN0IHBhdHRlcm4uCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG5ldyBEZWNpbWFsRm9ybWF0KCIkJyIsIG5ldyBEZWNpbWFsRm9ybWF0U3ltYm9scygpKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FzZSAxOiBUcnkgdG8gYXBwbHkgY29ycmVjdCB2YXJpYW50cyBvZiBwYXR0ZXJuLgorICAgICAqIENhc2UgMjogVHJ5IHRvIGFwcGx5IG1hbGZvcm1lZCBwYXR0ZW4uIENhc2UgMzogVHJ5IHRvIGFwcGx5IG51bGwgcGF0dGVybi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FwcGx5TG9jYWxpemVkUGF0dGVybkxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICBEZWNpbWFsRm9ybWF0IGZvcm1hdCA9IG5ldyBEZWNpbWFsRm9ybWF0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBjYXNlIDE6IFRyeSB0byBhcHBseSBjb3JyZWN0IHZhcmlhbnRzIG9mIHBhdHRlcm4uCisgICAgICAgICAgICBmb3JtYXQuYXBwbHlMb2NhbGl6ZWRQYXR0ZXJuKCIjLiMiKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcGF0dGVybiAxIiwgIiMwLiMiLCBmb3JtYXQudG9Mb2NhbGl6ZWRQYXR0ZXJuKCkpOworICAgICAgICAgICAgZm9ybWF0LmFwcGx5TG9jYWxpemVkUGF0dGVybigiIy4iKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcGF0dGVybiAyIiwgIiMwLiIsIGZvcm1hdC50b0xvY2FsaXplZFBhdHRlcm4oKSk7CisgICAgICAgICAgICBmb3JtYXQuYXBwbHlMb2NhbGl6ZWRQYXR0ZXJuKCIjIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHBhdHRlcm4gMyIsICIjIiwgZm9ybWF0LnRvTG9jYWxpemVkUGF0dGVybigpKTsKKyAgICAgICAgICAgIGZvcm1hdC5hcHBseUxvY2FsaXplZFBhdHRlcm4oIi4jIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHBhdHRlcm4gNCIsICIjLjAiLCBmb3JtYXQudG9Mb2NhbGl6ZWRQYXR0ZXJuKCkpOworCisgICAgICAgICAgICAvLyBjYXNlIDI6IFRyeSB0byBhcHBseSBtYWxmb3JtZWQgcGF0dGVuLgorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmb3JtYXQuYXBwbHlMb2NhbGl6ZWRQYXR0ZXJuKCInIywjOiMwLjAjOygjKSIpOworICAgICAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBjYXNlIDM6IFRyeSB0byBhcHBseSBudWxsIHBhdGVybi4KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZm9ybWF0LmFwcGx5TG9jYWxpemVkUGF0dGVybigoU3RyaW5nKSBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYXBwbHlQYXR0ZXJuTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIERlY2ltYWxGb3JtYXQgZm9ybWF0ID0gbmV3IERlY2ltYWxGb3JtYXQoIiMuIyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHBhdHRlcm4gMSIsICIjMC4jIiwgZm9ybWF0LnRvUGF0dGVybigpKTsKKyAgICAgICAgZm9ybWF0ID0gbmV3IERlY2ltYWxGb3JtYXQoIiMuIik7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcGF0dGVybiAyIiwgIiMwLiIsIGZvcm1hdC50b1BhdHRlcm4oKSk7CisgICAgICAgIGZvcm1hdCA9IG5ldyBEZWNpbWFsRm9ybWF0KCIjIik7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcGF0dGVybiAzIiwgIiMiLCBmb3JtYXQudG9QYXR0ZXJuKCkpOworICAgICAgICBmb3JtYXQgPSBuZXcgRGVjaW1hbEZvcm1hdCgiLiMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYXR0ZXJuIDQiLCAiIy4wIiwgZm9ybWF0LnRvUGF0dGVybigpKTsKKworICAgICAgICBEZWNpbWFsRm9ybWF0IGRlY0Zvcm1hdCA9IG5ldyBEZWNpbWFsRm9ybWF0KCIjLiMiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGVjRm9ybWF0LmFwcGx5UGF0dGVybihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIFtdIGluY1BhdHRlcm5zID0geyIlIywjIywjIyMsIyMjIyciLCAiIy4jIzAuMDAifTsKKyAgICAgICAgZm9yKFN0cmluZyBzdHI6aW5jUGF0dGVybnMpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZGVjRm9ybWF0LmFwcGx5UGF0dGVybihzdHIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biBmb3IgcGF0dGVybjogIiArCisgICAgICAgICAgICAgICAgICAgICAgICBzdHIpOworICAgICAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gIGlhZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIEFuZHJvaWRPbmx5OiBpY3Ugc3VwcG9ydHMgMiBncm91cGluZyBzaXplcworICAgIHB1YmxpYyB2b2lkIHRlc3RfYXBwbHlQYXR0ZXJuTGphdmFfbGFuZ19TdHJpbmcyKCkgeworICAgICAgICBEZWNpbWFsRm9ybWF0IGRlY0Zvcm1hdCA9IG5ldyBEZWNpbWFsRm9ybWF0KCIjLiMiKTsKKyAgICAgICAgU3RyaW5nIFtdIHBhdHRlcm5zID0geyIjIyMjLiMjIiwgIiMjIyMjIy4jIyMjIyMiLCAiMDAwMDAwLjAwMDAwMCIsCisgICAgICAgICAgICAgICAgIiMjIyMjIy4wMDAwMDAiLCAiMDAwMDAwLiMjIyMjIyIsICIgIyMjLiMjIyIsICIkIyMjIyMuIyMjIyMjIiwKKyAgICAgICAgICAgICAgICAiJCQjIyMjLiMjIyMjIyIsICIlIywjIywjIyMsIyMjIyIsICIjLCMjMC4wMDsoIywjIzAuMDApIiwKKyAgICAgICAgICAgICAgICAgIiMjLiMjLUUifTsKKworICAgICAgICBTdHJpbmcgW10gZXhwUmVzdWx0ID0geyIjMC4jIyIsICIjMC4jIyMjIyMiLCAiIzAwMDAwMC4wMDAwMDAiLAorICAgICAgICAgICAgICAgICIjLjAwMDAwMCIsICIjMDAwMDAwLiMjIyMjIyIsICIgIzAuIyMjIiwgIiQjMC4jIyMjIyMiLAorICAgICAgICAgICAgICAgICIkJCMwLiMjIyMjIyIsCisgICAgICAgICAgICAgICAgIiUjLCMjIywjIyMjIiwgLy8gaWN1IG9ubHkuIGljdSBzdXBwb3J0cyB0d28gZ3JvdXBpbmcgc2l6ZXMKKyAgICAgICAgICAgICAgICAiIywjIzAuMDA7KCMsIyMwLjAwKSIsCisgICAgICAgICAgICAgICAgIiMwLiMjLSdFJyJ9OyAvLyBpY3Ugb25seS4gRSBpbiB0aGUgc3VmZml4IGRvZXMgbm90IG5lZWQgdG8gYmUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHF1b3RlZC4gVGhpcyBpcyBkb25lIGF1dG9tYXRpY2FsbHkuCisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXR0ZXJucy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZGVjRm9ybWF0LmFwcGx5UGF0dGVybihwYXR0ZXJuc1tpXSk7CisgICAgICAgICAgICBTdHJpbmcgcmVzdWx0ID0gZGVjRm9ybWF0LnRvUGF0dGVybigpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gYXBwbHkgZm9sbG93aW5nIHBhdHRlcm46ICIgKyBwYXR0ZXJuc1tpXSArCisgICAgICAgICAgICAgICAgICAgICIgZXhwZWN0ZWQ6ICIgKyBleHBSZXN1bHRbaV0gKyAiIHJldHVybmVkOiAiICsgcmVzdWx0LAorICAgICAgICAgICAgICAgICAgICBleHBSZXN1bHRbaV0sIHJlc3VsdCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb25lKCkgeworICAgICAgICBEZWNpbWFsRm9ybWF0IGZvcm1hdCA9IChEZWNpbWFsRm9ybWF0KSBEZWNpbWFsRm9ybWF0CisgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKExvY2FsZS5VUyk7CisgICAgICAgIERlY2ltYWxGb3JtYXQgY2xvbmVkID0gKERlY2ltYWxGb3JtYXQpIGZvcm1hdC5jbG9uZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoY2xvbmVkLmdldERlY2ltYWxGb3JtYXRTeW1ib2xzKCksIGZvcm1hdAorICAgICAgICAgICAgICAgIC5nZXREZWNpbWFsRm9ybWF0U3ltYm9scygpKTsKKworICAgICAgICBmb3JtYXQgPSBuZXcgRGVjaW1hbEZvcm1hdCgiJyQnMDAwMC4wMDAwIik7CisgICAgICAgIERlY2ltYWxGb3JtYXQgZm9ybWF0MSA9IChEZWNpbWFsRm9ybWF0KSAoZm9ybWF0LmNsb25lKCkpOworICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIG9iamVjdHMgYXJlIGVxdWFsCisgICAgICAgIGFzc2VydFRydWUoIk9iamVjdCdzIGNsb25lIGlzbid0IGVxdWFsISIsIGZvcm1hdC5lcXVhbHMoZm9ybWF0MSkpOworICAgICAgICAvLyBjaGFuZ2UgdGhlIGNvbnRlbnQgb2YgdGhlIGNsb25lIGFuZCBtYWtlIHN1cmUgaXQncyBub3QgZXF1YWwgYW55bW9yZQorICAgICAgICAvLyB2ZXJpZmllcyB0aGF0IGl0J3MgZGF0YSBpcyBub3cgZGlzdGluY3QgZnJvbSB0aGUgb3JpZ2luYWwKKyAgICAgICAgZm9ybWF0MS5hcHBseVBhdHRlcm4oIickJzAwMDAuIyMjIyIpOworICAgICAgICBhc3NlcnRUcnVlKCJPYmplY3QncyBjaGFuZ2VkIGNsb25lIHNob3VsZCBub3QgYmUgZXF1YWwhIiwgIWZvcm1hdAorICAgICAgICAgICAgICAgIC5lcXVhbHMoZm9ybWF0MSkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjb21wYXJlKFN0cmluZyB0ZXN0TmFtZSwgU3RyaW5nIGZvcm1hdCwgU3RyaW5nIGV4cGVjdGVkKSB7CisgICAgICAgIGFzc2VydFRydWUodGVzdE5hbWUgKyAiIGdvdDogIiArIGZvcm1hdCArICIgZXhwZWN0ZWQ6ICIgKyBleHBlY3RlZCwKKyAgICAgICAgICAgICAgICBmb3JtYXQuZXF1YWxzKGV4cGVjdGVkKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGNvbXBhcmUoaW50IGNvdW50LCBTdHJpbmcgZm9ybWF0LCBTdHJpbmcgZXhwZWN0ZWQpIHsKKyAgICAgICAgYm9vbGVhbiByZXN1bHQgPSBmb3JtYXQuZXF1YWxzKGV4cGVjdGVkKTsKKyAgICAgICAgaWYgKCFyZXN1bHQpCisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZhaWx1cmUgdGVzdDogIiArIGNvdW50ICsgIiBnb3Q6ICIgKyBmb3JtYXQKKyAgICAgICAgICAgICAgICAgICAgKyAiIGV4cGVjdGVkOiAiICsgZXhwZWN0ZWQpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZm9ybWF0RExqYXZhX2xhbmdfU3RyaW5nQnVmZmVyTGphdmFfdGV4dF9GaWVsZFBvc2l0aW9uKCkgeworICAgICAgICBuZXcgU3VwcG9ydF9EZWNpbWFsRm9ybWF0KAorICAgICAgICAgICAgICAgICJ0ZXN0X2Zvcm1hdERMamF2YV9sYW5nX1N0cmluZ0J1ZmZlckxqYXZhX3RleHRfRmllbGRQb3NpdGlvbiIpCisgICAgICAgICAgICAgICAgLnRfZm9ybWF0X3dpdGhfRmllbGRQb3NpdGlvbigpOworCisgICAgICAgIGludCBmYWlsQ291bnQgPSAwOworICAgICAgICBCaXRTZXQgZmFpbHVyZXMgPSBuZXcgQml0U2V0KCk7CisKKyAgICAgICAgZmluYWwgRGVjaW1hbEZvcm1hdFN5bWJvbHMgZGZzID0gbmV3IERlY2ltYWxGb3JtYXRTeW1ib2xzKExvY2FsZS5VUyk7CisKKyAgICAgICAgRGVjaW1hbEZvcm1hdCBkZiA9IG5ldyBEZWNpbWFsRm9ybWF0KCIwMC4wI0UwIiwgZGZzKTsKKyAgICAgICAgY29tcGFyZSgiMDAuMCNFMDogMC4wIiwgZGYuZm9ybWF0KDAuMCksICIwMC4wRTAiKTsKKyAgICAgICAgY29tcGFyZSgiMDAuMCNFMDogMS4wIiwgZGYuZm9ybWF0KDEuMCksICIxMC4wRS0xIik7CisgICAgICAgIGNvbXBhcmUoIjAwLjAjRTA6IDEyLjAiLCBkZi5mb3JtYXQoMTIuMCksICIxMi4wRTAiKTsKKyAgICAgICAgY29tcGFyZSgiMDAuMCNFMDogMTIzLjAiLCBkZi5mb3JtYXQoMTIzLjApLCAiMTIuM0UxIik7CisgICAgICAgIGNvbXBhcmUoIjAwLjAjRTA6IDEyMzQuMCIsIGRmLmZvcm1hdCgxMjM0LjApLCAiMTIuMzRFMiIpOworICAgICAgICBjb21wYXJlKCIwMC4wI0UwOiAxMjM0Ni4wIiwgZGYuZm9ybWF0KDEyMzQ2LjApLCAiMTIuMzVFMyIpOworICAgICAgICBjb21wYXJlKCIwMC4wI0UwOiA5OTk5OS4wIiwgZGYuZm9ybWF0KDk5OTk5LjApLCAiMTAuMEU0Iik7CisgICAgICAgIGNvbXBhcmUoIjAwLjAjRTA6IDEuMiIsIGRmLmZvcm1hdCgxLjIpLCAiMTIuMEUtMSIpOworICAgICAgICBjb21wYXJlKCIwMC4wI0UwOiAxMi4zIiwgZGYuZm9ybWF0KDEyLjMpLCAiMTIuM0UwIik7CisgICAgICAgIGNvbXBhcmUoIjAwLjAjRTA6IDEyMy40IiwgZGYuZm9ybWF0KDEyMy40KSwgIjEyLjM0RTEiKTsKKyAgICAgICAgY29tcGFyZSgiMDAuMCNFMDogMTIzNC42IiwgZGYuZm9ybWF0KDEyMzQuNiksICIxMi4zNUUyIik7CisgICAgICAgIGNvbXBhcmUoIjAwLjAjRTA6IDk5OTkuOSIsIGRmLmZvcm1hdCg5OTk5LjkpLCAiMTAuMEUzIik7CisgICAgICAgIGNvbXBhcmUoIjAwLjAjRTA6IDAuMSIsIGRmLmZvcm1hdCgwLjEpLCAiMTAuMEUtMiIpOworICAgICAgICBjb21wYXJlKCIwMC4wI0UwOiAwLjEyIiwgZGYuZm9ybWF0KDAuMTIpLCAiMTIuMEUtMiIpOworICAgICAgICBjb21wYXJlKCIwMC4wI0UwOiAwLjEyMyIsIGRmLmZvcm1hdCgwLjEyMyksICIxMi4zRS0yIik7CisgICAgICAgIGNvbXBhcmUoIjAwLjAjRTA6IDAuMTIzNCIsIGRmLmZvcm1hdCgwLjEyMzQpLCAiMTIuMzRFLTIiKTsKKyAgICAgICAgY29tcGFyZSgiMDAuMCNFMDogMC4xMjM0NiIsIGRmLmZvcm1hdCgwLjEyMzQ2KSwgIjEyLjM1RS0yIik7CisgICAgICAgIGNvbXBhcmUoIjAwLjAjRTA6IDAuOTk5OTkiLCBkZi5mb3JtYXQoMC45OTk5OSksICIxMC4wRS0xIik7CisgICAgICAgIGNvbXBhcmUoIjAwLjAjRTA6IC0wLjAiLCBkZi5mb3JtYXQoLTAuMCksICItMDAuMEUwIik7CisgICAgICAgIGNvbXBhcmUoIjAwLjAjRTA6IC0xLjAiLCBkZi5mb3JtYXQoLTEuMCksICItMTAuMEUtMSIpOworICAgICAgICBjb21wYXJlKCIwMC4wI0UwOiAtMTIuMCIsIGRmLmZvcm1hdCgtMTIuMCksICItMTIuMEUwIik7CisgICAgICAgIGNvbXBhcmUoIjAwLjAjRTA6IC0xMjMuMCIsIGRmLmZvcm1hdCgtMTIzLjApLCAiLTEyLjNFMSIpOworICAgICAgICBjb21wYXJlKCIwMC4wI0UwOiAtMTIzNC4wIiwgZGYuZm9ybWF0KC0xMjM0LjApLCAiLTEyLjM0RTIiKTsKKyAgICAgICAgY29tcGFyZSgiMDAuMCNFMDogLTEyMzQ2LjAiLCBkZi5mb3JtYXQoLTEyMzQ2LjApLCAiLTEyLjM1RTMiKTsKKyAgICAgICAgY29tcGFyZSgiMDAuMCNFMDogLTk5OTk5LjAiLCBkZi5mb3JtYXQoLTk5OTk5LjApLCAiLTEwLjBFNCIpOworCisgICAgICAgIGRmID0gbmV3IERlY2ltYWxGb3JtYXQoIiMjMC4wRTAiLCBkZnMpOworICAgICAgICBjb21wYXJlKCIjIzAuMEUwOiAtMC4wIiwgZGYuZm9ybWF0KC0wLjApLCAiLTAuMEUwIik7CisgICAgICAgIGNvbXBhcmUoIiMjMC4wRTA6IDAuMCIsIGRmLmZvcm1hdCgwLjApLCAiMC4wRTAiKTsKKyAgICAgICAgY29tcGFyZSgiIyMwLjBFMDogMS4wIiwgZGYuZm9ybWF0KDEuMCksICIxLjBFMCIpOworICAgICAgICBjb21wYXJlKCIjIzAuMEUwOiAxMi4wIiwgZGYuZm9ybWF0KDEyLjApLCAiMTJFMCIpOworICAgICAgICBjb21wYXJlKCIjIzAuMEUwOiAxMjMuMCIsIGRmLmZvcm1hdCgxMjMuMCksICIxMjNFMCIpOyAgLy8gQW5kcm9pZCBmYWlscywgaGVyZSEKKyAgICAgICAgY29tcGFyZSgiIyMwLjBFMDogMTIzNC4wIiwgZGYuZm9ybWF0KDEyMzQuMCksICIxLjIzNEUzIik7CisgICAgICAgIGNvbXBhcmUoIiMjMC4wRTA6IDEyMzQ2LjAiLCBkZi5mb3JtYXQoMTIzNDYuMCksICIxMi4zNUUzIik7CisgICAgICAgIC8vIEZhaWxzIGluIEpESyAxLjIuMgorICAgICAgICBpZiAoIWNvbXBhcmUoZmFpbENvdW50LCBkZi5mb3JtYXQoOTk5OTkuMCksICIxMDBFMyIpKQorICAgICAgICAgICAgZmFpbHVyZXMuc2V0KGZhaWxDb3VudCk7CisgICAgICAgIGZhaWxDb3VudCsrOworICAgICAgICBjb21wYXJlKCIjIzAuMEUwOiA5OTk5OTkuMCIsIGRmLmZvcm1hdCg5OTk5OTkuMCksICIxLjBFNiIpOworCisgICAgICAgIGRmID0gbmV3IERlY2ltYWxGb3JtYXQoIiMwMC4wIyNFMCIsIGRmcyk7CisgICAgICAgIGNvbXBhcmUoIiMwMC4wIyNFMDogMC4xIiwgZGYuZm9ybWF0KDAuMSksICIxMDBFLTMiKTsKKyAgICAgICAgY29tcGFyZSgiIzAwLjAjI0UwOiAwLjEyIiwgZGYuZm9ybWF0KDAuMTIpLCAiMTIwRS0zIik7CisgICAgICAgIGNvbXBhcmUoIiMwMC4wIyNFMDogMC4xMjMiLCBkZi5mb3JtYXQoMC4xMjMpLCAiMTIzRS0zIik7CisgICAgICAgIGNvbXBhcmUoIiMwMC4wIyNFMDogMC4xMjM0IiwgZGYuZm9ybWF0KDAuMTIzNCksICIxMjMuNEUtMyIpOworICAgICAgICBjb21wYXJlKCIjMDAuMCMjRTA6IDAuMTIzNDU2NyIsIGRmLmZvcm1hdCgwLjEyMzQ1NjcpLCAiMTIzLjQ1N0UtMyIpOworICAgICAgICBjb21wYXJlKCIjMDAuMCMjRTA6IDAuMDEiLCBkZi5mb3JtYXQoMC4wMSksICIxMC4wRS0zIik7CisgICAgICAgIGNvbXBhcmUoIiMwMC4wIyNFMDogMC4wMTIiLCBkZi5mb3JtYXQoMC4wMTIpLCAiMTIuMEUtMyIpOworICAgICAgICBjb21wYXJlKCIjMDAuMCMjRTA6IDAuMDEyMyIsIGRmLmZvcm1hdCgwLjAxMjMpLCAiMTIuM0UtMyIpOworICAgICAgICBjb21wYXJlKCIjMDAuMCMjRTA6IDAuMDEyMzQiLCBkZi5mb3JtYXQoMC4wMTIzNCksICIxMi4zNEUtMyIpOworICAgICAgICBjb21wYXJlKCIjMDAuMCMjRTA6IDAuMDEyMzQ1NjciLCBkZi5mb3JtYXQoMC4wMTIzNDU2NyksICIxMi4zNDU3RS0zIik7CisgICAgICAgIGNvbXBhcmUoIiMwMC4wIyNFMDogMC4wMDEiLCBkZi5mb3JtYXQoMC4wMDEpLCAiMS4wMEUtMyIpOworICAgICAgICBjb21wYXJlKCIjMDAuMCMjRTA6IDAuMDAxMiIsIGRmLmZvcm1hdCgwLjAwMTIpLCAiMS4yMEUtMyIpOworICAgICAgICBjb21wYXJlKCIjMDAuMCMjRTA6IDAuMDAxMjMiLCBkZi5mb3JtYXQoMC4wMDEyMyksICIxLjIzRS0zIik7CisgICAgICAgIGNvbXBhcmUoIiMwMC4wIyNFMDogMC4wMDEyMzQiLCBkZi5mb3JtYXQoMC4wMDEyMzQpLCAiMS4yMzRFLTMiKTsKKyAgICAgICAgY29tcGFyZSgiIzAwLjAjI0UwOiAwLjAwMTIzNDU2NyIsIGRmLmZvcm1hdCgwLjAwMTIzNDU2NyksICIxLjIzNDU3RS0zIik7CisgICAgICAgIGNvbXBhcmUoIiMwMC4wIyNFMDogMC4wMDAxIiwgZGYuZm9ybWF0KDAuMDAwMSksICIxMDBFLTYiKTsKKyAgICAgICAgY29tcGFyZSgiIzAwLjAjI0UwOiAwLjAwMDEyIiwgZGYuZm9ybWF0KDAuMDAwMTIpLCAiMTIwRS02Iik7CisgICAgICAgIGNvbXBhcmUoIiMwMC4wIyNFMDogMC4wMDAxMjMiLCBkZi5mb3JtYXQoMC4wMDAxMjMpLCAiMTIzRS02Iik7CisgICAgICAgIGNvbXBhcmUoIiMwMC4wIyNFMDogMC4wMDAxMjM0IiwgZGYuZm9ybWF0KDAuMDAwMTIzNCksICIxMjMuNEUtNiIpOworICAgICAgICBjb21wYXJlKCIjMDAuMCMjRTA6IDAuMDAwMTIzNDU2NyIsIGRmLmZvcm1hdCgwLjAwMDEyMzQ1NjcpLAorICAgICAgICAgICAgICAgICIxMjMuNDU3RS02Iik7CisKKyAgICAgICAgLy8gRmFpbHMgaW4gSkRLIDEuMi4yCisgICAgICAgIGlmICghY29tcGFyZShmYWlsQ291bnQsIGRmLmZvcm1hdCgwLjApLCAiMC4wMEUwIikpCisgICAgICAgICAgICBmYWlsdXJlcy5zZXQoZmFpbENvdW50KTsKKyAgICAgICAgZmFpbENvdW50Kys7CisgICAgICAgIGNvbXBhcmUoIiMwMC4wIyNFMDogMS4wIiwgZGYuZm9ybWF0KDEuMCksICIxLjAwRTAiKTsKKyAgICAgICAgY29tcGFyZSgiIzAwLjAjI0UwOiAxMi4wIiwgZGYuZm9ybWF0KDEyLjApLCAiMTIuMEUwIik7CisgICAgICAgIGNvbXBhcmUoIiMwMC4wIyNFMDogMTIzLjAiLCBkZi5mb3JtYXQoMTIzLjApLCAiMTIzRTAiKTsKKyAgICAgICAgY29tcGFyZSgiIzAwLjAjI0UwOiAxMjM0LjAiLCBkZi5mb3JtYXQoMTIzNC4wKSwgIjEuMjM0RTMiKTsKKyAgICAgICAgY29tcGFyZSgiIzAwLjAjI0UwOiAxMjM0NS4wIiwgZGYuZm9ybWF0KDEyMzQ1LjApLCAiMTIuMzQ1RTMiKTsKKyAgICAgICAgY29tcGFyZSgiIzAwLjAjI0UwOiAxMjM0NTYuMCIsIGRmLmZvcm1hdCgxMjM0NTYuMCksICIxMjMuNDU2RTMiKTsKKyAgICAgICAgY29tcGFyZSgiIzAwLjAjI0UwOiAxMjM0NTY3LjAiLCBkZi5mb3JtYXQoMTIzNDU2Ny4wKSwgIjEuMjM0NTdFNiIpOworICAgICAgICBjb21wYXJlKCIjMDAuMCMjRTA6IDEyMzQ1Njc4LjAiLCBkZi5mb3JtYXQoMTIzNDU2NzguMCksICIxMi4zNDU3RTYiKTsKKyAgICAgICAgY29tcGFyZSgiIzAwLjAjI0UwOiA5OTk5OTk5OS4wIiwgZGYuZm9ybWF0KDk5OTk5OTk5LjApLCAiMTAwRTYiKTsKKworICAgICAgICBkZiA9IG5ldyBEZWNpbWFsRm9ybWF0KCIjLjBFMCIsIGRmcyk7CisgICAgICAgIGNvbXBhcmUoIiMuMEUwOiAtMC4wIiwgZGYuZm9ybWF0KC0wLjApLCAiLS4wRTAiKTsKKyAgICAgICAgY29tcGFyZSgiIy4wRTA6IDAuMCIsIGRmLmZvcm1hdCgwLjApLCAiLjBFMCIpOworICAgICAgICBjb21wYXJlKCIjLjBFMDogMS4wIiwgZGYuZm9ybWF0KDEuMCksICIuMUUxIik7CisgICAgICAgIGNvbXBhcmUoIiMuMEUwOiAxMi4wIiwgZGYuZm9ybWF0KDEyLjApLCAiLjEyRTIiKTsKKyAgICAgICAgY29tcGFyZSgiIy4wRTA6IDEyMy4wIiwgZGYuZm9ybWF0KDEyMy4wKSwgIi4xMkUzIik7CisgICAgICAgIGNvbXBhcmUoIiMuMEUwOiAxMjM0LjAiLCBkZi5mb3JtYXQoMTIzNC4wKSwgIi4xMkU0Iik7CisgICAgICAgIGNvbXBhcmUoIiMuMEUwOiA5OTk5LjAiLCBkZi5mb3JtYXQoOTk5OS4wKSwgIi4xRTUiKTsKKworICAgICAgICBkZiA9IG5ldyBEZWNpbWFsRm9ybWF0KCIwLiNFMCIsIGRmcyk7CisgICAgICAgIGNvbXBhcmUoIjAuI0UwOiAtMC4wIiwgZGYuZm9ybWF0KC0wLjApLCAiLTBFMCIpOworICAgICAgICBjb21wYXJlKCIwLiNFMDogMC4wIiwgZGYuZm9ybWF0KDAuMCksICIwRTAiKTsKKyAgICAgICAgY29tcGFyZSgiMC4jRTA6IDEuMCIsIGRmLmZvcm1hdCgxLjApLCAiMUUwIik7CisgICAgICAgIGNvbXBhcmUoIjAuI0UwOiAxMi4wIiwgZGYuZm9ybWF0KDEyLjApLCAiMS4yRTEiKTsKKyAgICAgICAgY29tcGFyZSgiMC4jRTA6IDEyMy4wIiwgZGYuZm9ybWF0KDEyMy4wKSwgIjEuMkUyIik7CisgICAgICAgIGNvbXBhcmUoIjAuI0UwOiAxMjM0LjAiLCBkZi5mb3JtYXQoMTIzNC4wKSwgIjEuMkUzIik7CisgICAgICAgIGNvbXBhcmUoIjAuI0UwOiA5OTk5LjAiLCBkZi5mb3JtYXQoOTk5OS4wKSwgIjFFNCIpOworCisgICAgICAgIGRmID0gbmV3IERlY2ltYWxGb3JtYXQoIi4wRTAiLCBkZnMpOworICAgICAgICBjb21wYXJlKCIuMEUwOiAtMC4wIiwgZGYuZm9ybWF0KC0wLjApLCAiLS4wRTAiKTsKKyAgICAgICAgY29tcGFyZSgiLjBFMDogMC4wIiwgZGYuZm9ybWF0KDAuMCksICIuMEUwIik7CisgICAgICAgIGNvbXBhcmUoIi4wRTA6IDEuMCIsIGRmLmZvcm1hdCgxLjApLCAiLjFFMSIpOworICAgICAgICBjb21wYXJlKCIuMEUwOiAxMi4wIiwgZGYuZm9ybWF0KDEyLjApLCAiLjFFMiIpOworICAgICAgICBjb21wYXJlKCIuMEUwOiAxMjMuMCIsIGRmLmZvcm1hdCgxMjMuMCksICIuMUUzIik7CisgICAgICAgIGNvbXBhcmUoIi4wRTA6IDEyMzQuMCIsIGRmLmZvcm1hdCgxMjM0LjApLCAiLjFFNCIpOworICAgICAgICBjb21wYXJlKCIuMEUwOiA5OTk5LjAiLCBkZi5mb3JtYXQoOTk5OS4wKSwgIi4xRTUiKTsKKworICAgICAgICBkZiA9IG5ldyBEZWNpbWFsRm9ybWF0KCIwLkUwIiwgZGZzKTsKKyAgICAgICAgLy8gRmFpbHMgaW4gSkRLIDEuMi4yCisgICAgICAgIGlmICghY29tcGFyZShmYWlsQ291bnQsIGRmLmZvcm1hdCgwLjApLCAiMC5FMCIpKQorICAgICAgICAgICAgZmFpbHVyZXMuc2V0KGZhaWxDb3VudCk7CisgICAgICAgIGZhaWxDb3VudCsrOworICAgICAgICBpZiAoIWNvbXBhcmUoZmFpbENvdW50LCBkZi5mb3JtYXQoMS4wKSwgIjEuRTAiKSkKKyAgICAgICAgICAgIGZhaWx1cmVzLnNldChmYWlsQ291bnQpOworICAgICAgICBmYWlsQ291bnQrKzsKKyAgICAgICAgaWYgKCFjb21wYXJlKGZhaWxDb3VudCwgZGYuZm9ybWF0KDEyLjApLCAiMS5FMSIpKQorICAgICAgICAgICAgZmFpbHVyZXMuc2V0KGZhaWxDb3VudCk7CisgICAgICAgIGZhaWxDb3VudCsrOworICAgICAgICBpZiAoIWNvbXBhcmUoZmFpbENvdW50LCBkZi5mb3JtYXQoMTIzLjApLCAiMS5FMiIpKQorICAgICAgICAgICAgZmFpbHVyZXMuc2V0KGZhaWxDb3VudCk7CisgICAgICAgIGZhaWxDb3VudCsrOworICAgICAgICBpZiAoIWNvbXBhcmUoZmFpbENvdW50LCBkZi5mb3JtYXQoMTIzNC4wKSwgIjEuRTMiKSkKKyAgICAgICAgICAgIGZhaWx1cmVzLnNldChmYWlsQ291bnQpOworICAgICAgICBmYWlsQ291bnQrKzsKKyAgICAgICAgaWYgKCFjb21wYXJlKGZhaWxDb3VudCwgZGYuZm9ybWF0KDk5OTkuMCksICIxLkU0IikpCisgICAgICAgICAgICBmYWlsdXJlcy5zZXQoZmFpbENvdW50KTsKKyAgICAgICAgZmFpbENvdW50Kys7CisKKyAgICAgICAgZGYgPSBuZXcgRGVjaW1hbEZvcm1hdCgiIyMwLjAwI0UwIiwgZGZzKTsKKyAgICAgICAgY29tcGFyZSgiIyMwLjAwI0UwOiAwLjEiLCBkZi5mb3JtYXQoMC4xKSwgIjEwMEUtMyIpOworICAgICAgICBjb21wYXJlKCIjIzAuMDAjRTA6IDAuMTIzNDU2NyIsIGRmLmZvcm1hdCgwLjEyMzQ1NjcpLCAiMTIzLjQ1N0UtMyIpOworICAgICAgICBjb21wYXJlKCIjIzAuMDAjRTA6IDAuOTk5OTk5OSIsIGRmLmZvcm1hdCgwLjk5OTk5OTkpLCAiMS4wMEUwIik7CisgICAgICAgIGNvbXBhcmUoIiMjMC4wMCNFMDogMC4wMSIsIGRmLmZvcm1hdCgwLjAxKSwgIjEwLjBFLTMiKTsKKyAgICAgICAgY29tcGFyZSgiIyMwLjAwI0UwOiAwLjAxMjM0NTY3IiwgZGYuZm9ybWF0KDAuMDEyMzQ1NjcpLCAiMTIuMzQ1N0UtMyIpOworICAgICAgICBjb21wYXJlKCIjIzAuMDAjRTA6IDAuMDk5OTk5OTkiLCBkZi5mb3JtYXQoMC4wOTk5OTk5OSksICIxMDBFLTMiKTsKKyAgICAgICAgY29tcGFyZSgiIyMwLjAwI0UwOiAwLjAwMSIsIGRmLmZvcm1hdCgwLjAwMSksICIxLjAwRS0zIik7CisgICAgICAgIGNvbXBhcmUoIiMjMC4wMCNFMDogMC4wMDEyMzQ1NjciLCBkZi5mb3JtYXQoMC4wMDEyMzQ1NjcpLCAiMS4yMzQ1N0UtMyIpOworICAgICAgICBjb21wYXJlKCIjIzAuMDAjRTA6IDAuMDA5OTk5OTk5IiwgZGYuZm9ybWF0KDAuMDA5OTk5OTk5KSwgIjEwLjBFLTMiKTsKKyAgICAgICAgY29tcGFyZSgiIyMwLjAwI0UwOiAwLjAwMDEiLCBkZi5mb3JtYXQoMC4wMDAxKSwgIjEwMEUtNiIpOworICAgICAgICBjb21wYXJlKCIjIzAuMDAjRTA6IDAuMDAwMTIzNDU2NyIsIGRmLmZvcm1hdCgwLjAwMDEyMzQ1NjcpLAorICAgICAgICAgICAgICAgICIxMjMuNDU3RS02Iik7CisgICAgICAgIGNvbXBhcmUoIiMjMC4wMCNFMDogMC4wMDA5OTk5OTk5IiwgZGYuZm9ybWF0KDAuMDAwOTk5OTk5OSksICIxLjAwRS0zIik7CisKKyAgICAgICAgZGYgPSBuZXcgRGVjaW1hbEZvcm1hdCgiIyMjMC4wMCNFMCIsIGRmcyk7CisgICAgICAgIGNvbXBhcmUoIiMjIzAuMDAjRTA6IDAuMSIsIGRmLmZvcm1hdCgwLjEpLCAiMTAwMEUtNCIpOworICAgICAgICBjb21wYXJlKCIjIyMwLjAwI0UwOiAwLjEyMzQ1Njc4IiwgZGYuZm9ybWF0KDAuMTIzNDU2NzgpLCAiMTIzNC41NjhFLTQiKTsKKyAgICAgICAgY29tcGFyZSgiIyMjMC4wMCNFMDogMC45OTk5OTk5OSIsIGRmLmZvcm1hdCgwLjk5OTk5OTk5KSwgIjEuMDBFMCIpOworICAgICAgICBjb21wYXJlKCIjIyMwLjAwI0UwOiAwLjAxIiwgZGYuZm9ybWF0KDAuMDEpLCAiMTAwRS00Iik7CisgICAgICAgIGNvbXBhcmUoIiMjIzAuMDAjRTA6IDAuMDEyMzQ1Njc4IiwgZGYuZm9ybWF0KDAuMDEyMzQ1Njc4KSwKKyAgICAgICAgICAgICAgICAiMTIzLjQ1NjhFLTQiKTsKKyAgICAgICAgY29tcGFyZSgiIyMjMC4wMCNFMDogMC4wOTk5OTk5OTkiLCBkZi5mb3JtYXQoMC4wOTk5OTk5OTkpLCAiMTAwMEUtNCIpOworICAgICAgICBjb21wYXJlKCIjIyMwLjAwI0UwOiAwLjAwMSIsIGRmLmZvcm1hdCgwLjAwMSksICIxMC4wRS00Iik7CisgICAgICAgIGNvbXBhcmUoIiMjIzAuMDAjRTA6IDAuMDAxMjM0NTY3OCIsIGRmLmZvcm1hdCgwLjAwMTIzNDU2NzgpLAorICAgICAgICAgICAgICAgICIxMi4zNDU2OEUtNCIpOworICAgICAgICBjb21wYXJlKCIjIyMwLjAwI0UwOiAwLjAwOTk5OTk5OTkiLCBkZi5mb3JtYXQoMC4wMDk5OTk5OTk5KSwgIjEwMEUtNCIpOworICAgICAgICBjb21wYXJlKCIjIyMwLjAwI0UwOiAwLjAwMDEiLCBkZi5mb3JtYXQoMC4wMDAxKSwgIjEuMDBFLTQiKTsKKyAgICAgICAgY29tcGFyZSgiIyMjMC4wMCNFMDogMC4wMDAxMjM0NTY3OCIsIGRmLmZvcm1hdCgwLjAwMDEyMzQ1Njc4KSwKKyAgICAgICAgICAgICAgICAiMS4yMzQ1NjhFLTQiKTsKKyAgICAgICAgY29tcGFyZSgiIyMjMC4wMCNFMDogMC4wMDA5OTk5OTk5OSIsIGRmLmZvcm1hdCgwLjAwMDk5OTk5OTk5KSwKKyAgICAgICAgICAgICAgICAiMTAuMEUtNCIpOworICAgICAgICAvLyBGYWlscyBpbiBKREsgMS4yLjIKKyAgICAgICAgaWYgKCFjb21wYXJlKGZhaWxDb3VudCwgZGYuZm9ybWF0KDAuMDAwMDEpLCAiMTAwMEUtOCIpKQorICAgICAgICAgICAgZmFpbHVyZXMuc2V0KGZhaWxDb3VudCk7CisgICAgICAgIGZhaWxDb3VudCsrOworICAgICAgICBjb21wYXJlKCIjIyMwLjAwI0UwOiAwLjAwMDAxMjM0NTY3OCIsIGRmLmZvcm1hdCgwLjAwMDAxMjM0NTY3OCksCisgICAgICAgICAgICAgICAgIjEyMzQuNTY4RS04Iik7CisgICAgICAgIGNvbXBhcmUoIiMjIzAuMDAjRTA6IDAuMDAwMDk5OTk5OTk5IiwgZGYuZm9ybWF0KDAuMDAwMDk5OTk5OTk5KSwKKyAgICAgICAgICAgICAgICAiMS4wMEUtNCIpOworCisgICAgICAgIGRmID0gbmV3IERlY2ltYWxGb3JtYXQoIiMjIzAuMCNFMCIsIGRmcyk7CisgICAgICAgIGNvbXBhcmUoIiMjIzAuMCNFMDogMC4xIiwgZGYuZm9ybWF0KDAuMSksICIxMDAwRS00Iik7CisgICAgICAgIGNvbXBhcmUoIiMjIzAuMCNFMDogMC4xMjM0NTY3IiwgZGYuZm9ybWF0KDAuMTIzNDU2NyksICIxMjM0LjU3RS00Iik7CisgICAgICAgIGNvbXBhcmUoIiMjIzAuMCNFMDogMC45OTk5OTk5IiwgZGYuZm9ybWF0KDAuOTk5OTk5OSksICIxLjBFMCIpOworICAgICAgICAvLyBGYWlscyBpbiBKREsgMS4yLjIKKyAgICAgICAgaWYgKCFjb21wYXJlKGZhaWxDb3VudCwgZGYuZm9ybWF0KDAuMDEpLCAiMTAwRS00IikpCisgICAgICAgICAgICBmYWlsdXJlcy5zZXQoZmFpbENvdW50KTsKKyAgICAgICAgZmFpbENvdW50Kys7CisgICAgICAgIGNvbXBhcmUoIiMjIzAuMCNFMDogMC4wMTIzNDU2NyIsIGRmLmZvcm1hdCgwLjAxMjM0NTY3KSwgIjEyMy40NTdFLTQiKTsKKyAgICAgICAgY29tcGFyZSgiIyMjMC4wI0UwOiAwLjA5OTk5OTk5IiwgZGYuZm9ybWF0KDAuMDk5OTk5OTkpLCAiMTAwMEUtNCIpOworICAgICAgICBjb21wYXJlKCIjIyMwLjAjRTA6IDAuMDAxIiwgZGYuZm9ybWF0KDAuMDAxKSwgIjEwRS00Iik7CisgICAgICAgIGNvbXBhcmUoIiMjIzAuMCNFMDogMC4wMDEyMzQ1NjciLCBkZi5mb3JtYXQoMC4wMDEyMzQ1NjcpLCAiMTIuMzQ1N0UtNCIpOworICAgICAgICAvLyBGYWlscyBpbiBKREsgMS4yLjIKKyAgICAgICAgaWYgKCFjb21wYXJlKGZhaWxDb3VudCwgZGYuZm9ybWF0KDAuMDA5OTk5OTk5KSwgIjEwMEUtNCIpKQorICAgICAgICAgICAgZmFpbHVyZXMuc2V0KGZhaWxDb3VudCk7CisgICAgICAgIGZhaWxDb3VudCsrOworICAgICAgICBjb21wYXJlKCIjIyMwLjAjRTA6IDAuMDAwMSIsIGRmLmZvcm1hdCgwLjAwMDEpLCAiMS4wRS00Iik7CisgICAgICAgIGNvbXBhcmUoIiMjIzAuMCNFMDogMC4wMDAxMjM0NTY3IiwgZGYuZm9ybWF0KDAuMDAwMTIzNDU2NyksCisgICAgICAgICAgICAgICAgIjEuMjM0NTdFLTQiKTsKKyAgICAgICAgY29tcGFyZSgiIyMjMC4wI0UwOiAwLjAwMDk5OTk5OTkiLCBkZi5mb3JtYXQoMC4wMDA5OTk5OTk5KSwgIjEwRS00Iik7CisgICAgICAgIC8vIEZhaWxzIGluIEpESyAxLjIuMgorICAgICAgICBpZiAoIWNvbXBhcmUoZmFpbENvdW50LCBkZi5mb3JtYXQoMC4wMDAwMSksICIxMDAwRS04IikpCisgICAgICAgICAgICBmYWlsdXJlcy5zZXQoZmFpbENvdW50KTsKKyAgICAgICAgZmFpbENvdW50Kys7CisgICAgICAgIGNvbXBhcmUoIiMjIzAuMCNFMDogMC4wMDAwMTIzNDU2NyIsIGRmLmZvcm1hdCgwLjAwMDAxMjM0NTY3KSwKKyAgICAgICAgICAgICAgICAiMTIzNC41N0UtOCIpOworICAgICAgICBjb21wYXJlKCIjIyMwLjAjRTA6IDAuMDAwMDk5OTk5OTkiLCBkZi5mb3JtYXQoMC4wMDAwOTk5OTk5OSksICIxLjBFLTQiKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgIiArIGZhaWx1cmVzICsgIiBvZiAiICsgZmFpbENvdW50LAorICAgICAgICAgICAgICAgIGZhaWx1cmVzLmxlbmd0aCgpID09IDApOworCisgICAgICAgIFN0cmluZyBmb3JtYXRTdHJpbmcgPSAiIyMwLiMiOworICAgICAgICBkZiA9IG5ldyBEZWNpbWFsRm9ybWF0KGZvcm1hdFN0cmluZywgZGZzKTsKKyAgICAgICAgZGYuc2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKDMwKTsKKyAgICAgICAgY29tcGFyZShmb3JtYXRTdHJpbmcgKyAiOiAwLjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCIsIGRmCisgICAgICAgICAgICAgICAgLmZvcm1hdCgwLjApLCAiMC4wMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiKTsKKyAgICAgICAgY29tcGFyZShmb3JtYXRTdHJpbmcgKyAiOiAtMC4wMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiLCBkZgorICAgICAgICAgICAgICAgIC5mb3JtYXQoLTAuMCksICItMC4wMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiKTsKKyAgICAgICAgY29tcGFyZShmb3JtYXRTdHJpbmcgKyAiOiAxLjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCIsIGRmCisgICAgICAgICAgICAgICAgLmZvcm1hdCgxLjApLCAiMS4wMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiKTsKKyAgICAgICAgY29tcGFyZShmb3JtYXRTdHJpbmcgKyAiOiAtMS4wMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiLCBkZgorICAgICAgICAgICAgICAgIC5mb3JtYXQoLTEuMCksICItMS4wMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiKTsKKworICAgICAgICBkZiA9IG5ldyBEZWNpbWFsRm9ybWF0KGZvcm1hdFN0cmluZyk7CisgICAgICAgIGRmLnNldE1heGltdW1GcmFjdGlvbkRpZ2l0cygzMCk7CisgICAgICAgIGNvbXBhcmUoZm9ybWF0U3RyaW5nICsgIjogMCIsIGRmLmZvcm1hdCgwLjApLCAiMCIpOworICAgICAgICBjb21wYXJlKGZvcm1hdFN0cmluZyArICI6IC0wIiwgZGYuZm9ybWF0KC0wLjApLCAiLTAiKTsKKyAgICAgICAgY29tcGFyZShmb3JtYXRTdHJpbmcgKyAiOiAxIiwgZGYuZm9ybWF0KDEuMCksICIxIik7CisgICAgICAgIGNvbXBhcmUoZm9ybWF0U3RyaW5nICsgIjogLTEiLCBkZi5mb3JtYXQoLTEuMCksICItMSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZm9ybWF0RCgpIHsKKyAgICAgICAgRGVjaW1hbEZvcm1hdCBmb3JtYXQgPSAoRGVjaW1hbEZvcm1hdCkgTnVtYmVyRm9ybWF0CisgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKExvY2FsZS5FTkdMSVNIKTsKKyAgICAgICAgZm9ybWF0LnNldEdyb3VwaW5nVXNlZChmYWxzZSk7CisgICAgICAgIGZvcm1hdC5zZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoNDAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMjM0NTY3ODkwMTIzNDUiLCBmb3JtYXQuZm9ybWF0KDEyMzQ1Njc4OTAxMjM0NS4pKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxIiwgIjEyMzQ1Njc4OTAxMjM0LjUiLCBmb3JtYXQuZm9ybWF0KDEyMzQ1Njc4OTAxMjM0LjUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIyIiwgIjEyMzQ1Njc4OTAxMjMuMjUiLCBmb3JtYXQuZm9ybWF0KDEyMzQ1Njc4OTAxMjMuMjUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIzIiwgIjk5OTk5OTk5OTk5OS4zNzUiLCBmb3JtYXQuZm9ybWF0KDk5OTk5OTk5OTk5OS4zNzUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI0IiwgIjk5OTk5OTk5OTk5LjA2MjUiLCBmb3JtYXQuZm9ybWF0KDk5OTk5OTk5OTk5LjA2MjUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI1IiwgIjk5OTk5OTk5OTkuMDMxMjUiLCBmb3JtYXQuZm9ybWF0KDk5OTk5OTk5OTkuMDMxMjUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI2IiwgIjk5OTk5OTk5OS4wMTU2MjUiLCBmb3JtYXQuZm9ybWF0KDk5OTk5OTk5OS4wMTU2MjUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI3IiwgIjk5OTk5OTk5LjAwNzgxMjUiLCBmb3JtYXQuZm9ybWF0KDk5OTk5OTk5LjAwNzgxMjUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI4IiwgIjk5OTk5OTkuMDAzOTA2MjUiLCBmb3JtYXQuZm9ybWF0KDk5OTk5OTkuMDAzOTA2MjUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI5IiwgIjk5OTk5OS4wMDE5NTMxMjUiLCBmb3JtYXQuZm9ybWF0KDk5OTk5OS4wMDE5NTMxMjUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMCIsICI5OTk5LjAwMDQ4ODI4MTI1IiwgZm9ybWF0LmZvcm1hdCg5OTk5LjAwMDQ4ODI4MTI1KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTEiLCAiOTk5LjAwMDI0NDE0MDYyNSIsIGZvcm1hdC5mb3JtYXQoOTk5LjAwMDI0NDE0MDYyNSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEyIiwgIjk5LjAwMDEyMjA3MDMxMjUiLCBmb3JtYXQuZm9ybWF0KDk5LjAwMDEyMjA3MDMxMjUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMyIsICI5LjAwMDA2MTAzNTE1NjI1IiwgZm9ybWF0LmZvcm1hdCg5LjAwMDA2MTAzNTE1NjI1KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTQiLCAiMC4wMDAwMzA1MTc1NzgxMjUiLCBmb3JtYXQuZm9ybWF0KDAuMDAwMDMwNTE3NTc4MTI1KSk7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE5lZ2F0aXZlUHJlZml4KCkgeworICAgICAgICBEZWNpbWFsRm9ybWF0IGRmID0gbmV3IERlY2ltYWxGb3JtYXQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRmLnNldE5lZ2F0aXZlUHJlZml4KCItLSIpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG5lZ2F0aXZlIHByZWZpeCIsIGRmLmdldE5lZ2F0aXZlUHJlZml4KCkKKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscygiLS0iKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TmVnYXRpdmVTdWZmaXgoKSB7CisgICAgICAgIERlY2ltYWxGb3JtYXQgZGYgPSBuZXcgRGVjaW1hbEZvcm1hdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGYuc2V0TmVnYXRpdmVTdWZmaXgoIiYiKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBuZWdhdGl2ZSBzdWZmaXgiLCBkZi5nZXROZWdhdGl2ZVN1ZmZpeCgpCisgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoIiYiKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UG9zaXRpdmVQcmVmaXgoKSB7CisgICAgICAgIERlY2ltYWxGb3JtYXQgZGYgPSBuZXcgRGVjaW1hbEZvcm1hdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGYuc2V0UG9zaXRpdmVQcmVmaXgoIisrIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcG9zaXRpdmUgcHJlZml4IiwgZGYuZ2V0UG9zaXRpdmVQcmVmaXgoKQorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKCIrKyIpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQb3NpdGl2ZVN1ZmZpeCgpIHsKKyAgICAgICAgRGVjaW1hbEZvcm1hdCBkZiA9IG5ldyBEZWNpbWFsRm9ybWF0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkZi5zZXRQb3NpdGl2ZVN1ZmZpeCgiJSIpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHBvc2l0aXZlIHByZWZpeCIsIGRmLmdldFBvc2l0aXZlU3VmZml4KCkKKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscygiJSIpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIERlY2ltYWxGb3JtYXQgZGYxID0gbmV3IERlY2ltYWxGb3JtYXQoKTsKKyAgICAgICAgICAgIERlY2ltYWxGb3JtYXQgZGYyID0gKERlY2ltYWxGb3JtYXQpIGRmMS5jbG9uZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSGFzaCBjb2RlcyBvZiBlcXVhbHMgb2JqZWN0IGFyZSBub3QgZXF1YWwiLCBkZjIKKyAgICAgICAgICAgICAgICAgICAgLmhhc2hDb2RlKCkgPT0gZGYxLmhhc2hDb2RlKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BhcnNlTGphdmFfbGFuZ19TdHJpbmdMamF2YV90ZXh0X1BhcnNlUG9zaXRpb24oKSB7CisgICAgICAgIERlY2ltYWxGb3JtYXQgZm9ybWF0ID0gKERlY2ltYWxGb3JtYXQpIE51bWJlckZvcm1hdAorICAgICAgICAgICAgICAgIC5nZXROdW1iZXJJbnN0YW5jZShMb2NhbGUuRU5HTElTSCk7CisgICAgICAgIFBhcnNlUG9zaXRpb24gcG9zID0gbmV3IFBhcnNlUG9zaXRpb24oMCk7CisgICAgICAgIE51bWJlciByZXN1bHQgPSBmb3JtYXQucGFyc2UoIjkyMjMzNzIwMzY4NTQ3NzU4MDciLCBwb3MpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyByZXN1bHQgdHlwZSBmb3IgTG9uZy5NQVhfVkFMVUUiLAorICAgICAgICAgICAgICAgIHJlc3VsdC5nZXRDbGFzcygpID09IExvbmcuY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHJlc3VsdCBMb25nLk1BWF9WQUxVRSIsCisgICAgICAgICAgICAgICAgTG9uZy5NQVhfVkFMVUUsIHJlc3VsdC5sb25nVmFsdWUoKSk7CisgICAgICAgIHBvcyA9IG5ldyBQYXJzZVBvc2l0aW9uKDApOworICAgICAgICByZXN1bHQgPSBmb3JtYXQucGFyc2UoIi05MjIzMzcyMDM2ODU0Nzc1ODA4IiwgcG9zKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcmVzdWx0IHR5cGUgZm9yIExvbmcuTUlOX1ZBTFVFIiwKKyAgICAgICAgICAgICAgICByZXN1bHQuZ2V0Q2xhc3MoKSA9PSBMb25nLmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcmVzdWx0IExvbmcuTUlOX1ZBTFVFOiAiICsgcmVzdWx0LmxvbmdWYWx1ZSgpLCByZXN1bHQKKyAgICAgICAgICAgICAgICAubG9uZ1ZhbHVlKCkgPT0gTG9uZy5NSU5fVkFMVUUpOworICAgICAgICBwb3MgPSBuZXcgUGFyc2VQb3NpdGlvbigwKTsKKyAgICAgICAgcmVzdWx0ID0gZm9ybWF0LnBhcnNlKCI5MjIzMzcyMDM2ODU0Nzc1ODA4IiwgcG9zKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcmVzdWx0IHR5cGUgZm9yIExvbmcuTUFYX1ZBTFVFKzEiLAorICAgICAgICAgICAgICAgIHJlc3VsdC5nZXRDbGFzcygpID09IERvdWJsZS5jbGFzcyk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcmVzdWx0IExvbmcuTUFYX1ZBTFVFICsgMSIsCisgICAgICAgICAgICAgICAgKGRvdWJsZSkgTG9uZy5NQVhfVkFMVUUgKyAxLCByZXN1bHQuZG91YmxlVmFsdWUoKSk7CisgICAgICAgIHBvcyA9IG5ldyBQYXJzZVBvc2l0aW9uKDApOworICAgICAgICByZXN1bHQgPSBmb3JtYXQucGFyc2UoIi05MjIzMzcyMDM2ODU0Nzc1ODA5IiwgcG9zKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcmVzdWx0IHR5cGUgZm9yIExvbmcuTUlOX1ZBTFVFIC0gMSIsCisgICAgICAgICAgICAgICAgcmVzdWx0LmdldENsYXNzKCkgPT0gRG91YmxlLmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXN1bHQgTG9uZy5NSU5fVkFMVUUgLSAxIiwKKyAgICAgICAgICAgICAgICAoZG91YmxlKSBMb25nLk1JTl9WQUxVRSAtIDEsIHJlc3VsdC5kb3VibGVWYWx1ZSgpKTsKKworICAgICAgICBwb3MgPSBuZXcgUGFyc2VQb3NpdGlvbigwKTsKKyAgICAgICAgcmVzdWx0ID0gZm9ybWF0LnBhcnNlKCIxODQ0Njc0NDA3MzcwOTU1MTYyOSIsIHBvcyk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHJlc3VsdCB0eXBlIGZvciBvdmVyZmxvdyIsCisgICAgICAgICAgICAgICAgcmVzdWx0LmdldENsYXNzKCkgPT0gRG91YmxlLmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXN1bHQgZm9yIG92ZXJmbG93IiwKKyAgICAgICAgICAgICAgICAxODQ0Njc0NDA3MzcwOTU1MTYyOWQsIHJlc3VsdC5kb3VibGVWYWx1ZSgpKTsKKworICAgICAgICBwb3MgPSBuZXcgUGFyc2VQb3NpdGlvbigwKTsKKyAgICAgICAgcmVzdWx0ID0gZm9ybWF0LnBhcnNlKCI0MjMyNTkxNzMxNzA2NzU3MTE5OSIsIHBvcyk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHJlc3VsdCB0eXBlIGZvciBvdmVyZmxvdyBhOiAiICsgcmVzdWx0LCByZXN1bHQKKyAgICAgICAgICAgICAgICAuZ2V0Q2xhc3MoKSA9PSBEb3VibGUuY2xhc3MpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyByZXN1bHQgZm9yIG92ZXJmbG93IGE6ICIgKyByZXN1bHQsIHJlc3VsdAorICAgICAgICAgICAgICAgIC5kb3VibGVWYWx1ZSgpID09IDQyMzI1OTE3MzE3MDY3NTcxMTk5ZCk7CisgICAgICAgIHBvcyA9IG5ldyBQYXJzZVBvc2l0aW9uKDApOworICAgICAgICByZXN1bHQgPSBmb3JtYXQucGFyc2UoIjQyMzI1OTE3MzE3MDY3NTcxMTlFMSIsIHBvcyk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHJlc3VsdCB0eXBlIGZvciBvdmVyZmxvdyBiOiAiICsgcmVzdWx0LCByZXN1bHQKKyAgICAgICAgICAgICAgICAuZ2V0Q2xhc3MoKSA9PSBEb3VibGUuY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHJlc3VsdCBmb3Igb3ZlcmZsb3cgYjogIiArIHJlc3VsdCwKKyAgICAgICAgICAgICAgICA0MjMyNTkxNzMxNzA2NzU3MTE5MGQsIHJlc3VsdC5kb3VibGVWYWx1ZSgpKTsKKyAgICAgICAgcG9zID0gbmV3IFBhcnNlUG9zaXRpb24oMCk7CisgICAgICAgIHJlc3VsdCA9IGZvcm1hdC5wYXJzZSgiLjQyMzI1OTE3MzE3MDY3NTcxMTk5RTIwIiwgcG9zKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcmVzdWx0IHR5cGUgZm9yIG92ZXJmbG93IGM6ICIgKyByZXN1bHQsIHJlc3VsdAorICAgICAgICAgICAgICAgIC5nZXRDbGFzcygpID09IERvdWJsZS5jbGFzcyk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHJlc3VsdCBmb3Igb3ZlcmZsb3cgYzogIiArIHJlc3VsdCwgcmVzdWx0CisgICAgICAgICAgICAgICAgLmRvdWJsZVZhbHVlKCkgPT0gNDIzMjU5MTczMTcwNjc1NzExOTlkKTsKKyAgICAgICAgcG9zID0gbmV3IFBhcnNlUG9zaXRpb24oMCk7CisgICAgICAgIHJlc3VsdCA9IGZvcm1hdC5wYXJzZSgiOTIyMzM3MjAzNjg1NDc3NTgwLjlFMSIsIHBvcyk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHJlc3VsdCB0eXBlIGZvciBvdmVyZmxvdyBkOiAiICsgcmVzdWx0LCByZXN1bHQKKyAgICAgICAgICAgICAgICAuZ2V0Q2xhc3MoKSA9PSBEb3VibGUuY2xhc3MpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyByZXN1bHQgZm9yIG92ZXJmbG93IGQ6ICIgKyByZXN1bHQsIHJlc3VsdAorICAgICAgICAgICAgICAgIC5kb3VibGVWYWx1ZSgpID09IDkyMjMzNzIwMzY4NTQ3NzU4MDlkKTsKKyAgICAgICAgcG9zID0gbmV3IFBhcnNlUG9zaXRpb24oMCk7CisgICAgICAgIHJlc3VsdCA9IGZvcm1hdC5wYXJzZSgiOS4yMjMzNzIwMzY4NTQ3NzU4MDlFMTgiLCBwb3MpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyByZXN1bHQgdHlwZSBmb3Igb3ZlcmZsb3cgZTogIiArIHJlc3VsdCwgcmVzdWx0CisgICAgICAgICAgICAgICAgLmdldENsYXNzKCkgPT0gRG91YmxlLmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcmVzdWx0IGZvciBvdmVyZmxvdyBlOiAiICsgcmVzdWx0LCByZXN1bHQKKyAgICAgICAgICAgICAgICAuZG91YmxlVmFsdWUoKSA9PSA5MjIzMzcyMDM2ODU0Nzc1ODA5ZCk7CisKKyAgICAgICAgLy8gdGVzdCBwYXJzZSB3aXRoIG11bHRpcGxpZXJzCisgICAgICAgIGZvcm1hdC5zZXRNdWx0aXBsaWVyKDEwMCk7CisgICAgICAgIHJlc3VsdCA9IGZvcm1hdC5wYXJzZSgiOTIyMzM3MjAzNjg1NDc3NTgwNyIsIG5ldyBQYXJzZVBvc2l0aW9uKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXN1bHQgdHlwZSBtdWx0aXBsaWVyIDEwMDogIiArIHJlc3VsdCwgTG9uZy5jbGFzcywgcmVzdWx0LmdldENsYXNzKCkpOworICAgICAgICAvLyBSSSBvbiB3aW5kb3dzIGFuZCBsaW51eCBib3RoIGFuc3dlciB3aXRoIGEgc2xpZ2h0bHkgcm91bmRlZCByZXN1bHQKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcmVzdWx0IGZvciBtdWx0aXBsaWVyIDEwMDogIiArIHJlc3VsdCwgcmVzdWx0CisgICAgICAgICAgICAgICAgLmxvbmdWYWx1ZSgpID09IDkyMjMzNzIwMzY4NTQ3NzYwTCk7CisgICAgICAgIGZvcm1hdC5zZXRNdWx0aXBsaWVyKDEwMDApOworICAgICAgICByZXN1bHQgPSBmb3JtYXQucGFyc2UoIjkyMjMzNzIwMzY4NTQ3NzU4MDciLCBuZXcgUGFyc2VQb3NpdGlvbigwKSk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHJlc3VsdCB0eXBlIG11bHRpcGxpZXIgMTAwMDogIiArIHJlc3VsdCwgcmVzdWx0CisgICAgICAgICAgICAgICAgLmdldENsYXNzKCkgPT0gTG9uZy5jbGFzcyk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHJlc3VsdCBmb3IgbXVsdGlwbGllciAxMDAwOiAiICsgcmVzdWx0LCByZXN1bHQKKyAgICAgICAgICAgICAgICAubG9uZ1ZhbHVlKCkgPT0gOTIyMzM3MjAzNjg1NDc3NkwpOworCisgICAgICAgIGZvcm1hdC5zZXRNdWx0aXBsaWVyKDEwMDAwKTsKKyAgICAgICAgcmVzdWx0ID0gZm9ybWF0LnBhcnNlKCI5MjIzMzcyMDM2ODU0Nzc1ODA3IiwgbmV3IFBhcnNlUG9zaXRpb24oMCkpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyByZXN1bHQgdHlwZSBtdWx0aXBsaWVyIDEwMDAwOiAiICsgcmVzdWx0LCByZXN1bHQKKyAgICAgICAgICAgICAgICAuZ2V0Q2xhc3MoKSA9PSBEb3VibGUuY2xhc3MpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyByZXN1bHQgZm9yIG11bHRpcGxpZXIgMTAwMDA6ICIgKyByZXN1bHQsIHJlc3VsdAorICAgICAgICAgICAgICAgIC5kb3VibGVWYWx1ZSgpID09IDkyMjMzNzIwMzY4NTQ3Ny41ODA3ZCk7CisKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkRGVjaW1hbEZvcm1hdFRlc3RJQ1UuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGREZWNpbWFsRm9ybWF0VGVzdElDVS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIwNWZhYWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkRGVjaW1hbEZvcm1hdFRlc3RJQ1UuamF2YQpAQCAtMCwwICsxLDE1NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuTnVtYmVyRm9ybWF0OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3QgZm9yIGFkZGl0aW9uYWwgZmVhdHVyZXMgaW50cm9kdWNlZCBieSBpY3UuIFRoZXNlIHRlc3RzIGZhaWwgb24gdGhlIFJJCisgKiBidXQgc3VjY2VlZCBvbiBBbmRyb2lkIDEuMC4gVGhlIGZlYXR1cmVzIGFyZSBvbmx5IGFjY2Vzc2libGUgdGhyb3VnaCB0aGUKKyAqIHBhdHRlcm4uIEFwaSBtZXRob2RzIHdoZXJlIG5vdCBpbnRyb2R1Y2VkIHRvIGFsbG93IGRpcmVjdCBhY2Nlc3Mgb2YgdGhlc2UKKyAqIGZlYXR1cmVzLiBUaGlzIHdvdWxkIGhhdmUgY2hhbmdlZCB0aGUgYXBpIHRvbyBtdWNoLgorICovCitwdWJsaWMgY2xhc3MgT2xkRGVjaW1hbEZvcm1hdFRlc3RJQ1UgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBEZWNpbWFsRm9ybWF0IGZvcm1hdDsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICBmb3JtYXQgPSAoRGVjaW1hbEZvcm1hdCkgTnVtYmVyRm9ybWF0LmdldE51bWJlckluc3RhbmNlKCk7CisgICAgfQorCisgICAgLy8gQW5kcm9pZE9ubHk6IHNwZWNpYWwgZmVhdHVyZSBvZiBpY3U0YworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2lnRGlnaXRQYXR0ZXJucygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEZWNpbWFsRm9ybWF0IGZvcm1hdCA9IChEZWNpbWFsRm9ybWF0KSBOdW1iZXJGb3JtYXQKKyAgICAgICAgLmdldEluc3RhbmNlKExvY2FsZS5VUyk7CisKKyAgICAgICAgZm9ybWF0LmFwcGx5UGF0dGVybigiQEBAIik7CisgICAgICAgIGFzc2VydEVxdWFscygic2lnRGlnaXQgZG9lc24ndCB3b3JrIiwgIjEyMzAwIiwgZm9ybWF0LmZvcm1hdCgxMjM0NSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInNpZ0RpZ2l0IGRvZXNuJ3Qgd29yayIsICIwLjEyMyIsIGZvcm1hdC5mb3JtYXQoMC4xMjM0NSkpOworCisgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIkBAIyMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzaWdEaWdpdCBkb2Vzbid0IHdvcmsiLCAiMy4xNDIiLCBmb3JtYXQuZm9ybWF0KDMuMTQxNTkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzaWdEaWdpdCBkb2Vzbid0IHdvcmsiLCAiMS4yMyIsIGZvcm1hdC5mb3JtYXQoMS4yMzAwNCkpOworCisgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIkBAIyMjRTAiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxLjIzRTEiLCBmb3JtYXQuZm9ybWF0KDEyLjMpKTsKKyAgICAgICAgZm9ybWF0LmFwcGx5UGF0dGVybigiMC4wIyMjRTAiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxLjIzRTEiLCBmb3JtYXQuZm9ybWF0KDEyLjMpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9ybWF0LmFwcGx5UGF0dGVybigiQDAwIik7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24gZm9yICIKKyAgICAgICAgICAgICAgICAgICAgKyAicGF0dGVybiBcIkAwMFwiLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3JtYXQuYXBwbHlQYXR0ZXJuKCJALiMjIyIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIGZvciAiCisgICAgICAgICAgICAgICAgICAgICsgInBhdHRlcm4gXCJALiMjI1wiLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIEFuZHJvaWRPbmx5OiBzcGVjaWFsIGZlYXR1cmUgb2YgaWN1NGMKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BhZGRpbmdQYXR0ZXJuKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIip4IyMsIyMsIywjIzAuMCMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4eHh4eHh4eHgxMjMuMCIsIGZvcm1hdC5mb3JtYXQoMTIzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMjMsIGZvcm1hdC5wYXJzZSgieHh4eHh4eHh4MTIzLjAiKS5pbnRWYWx1ZSgpKTsKKworICAgICAgICBmb3JtYXQuYXBwbHlQYXR0ZXJuKCIkKngjLCMjMC4wMCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiR4eDEyMy4wMCIsIGZvcm1hdC5mb3JtYXQoMTIzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiJDEsMjM0LjAwIiwgZm9ybWF0LmZvcm1hdCgxMjM0KSk7CisKKyAgICAgICAgZm9ybWF0LmFwcGx5UGF0dGVybigiKlx1MDBlNyMwIG8nJ2Nsb2NrIik7CisgICAgICAgIGFzc2VydEVxdWFscygiXHUwMGU3MiBvJ2Nsb2NrIiwgZm9ybWF0LmZvcm1hdCgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTIgbydjbG9jayIsIGZvcm1hdC5mb3JtYXQoMTIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGZvcm1hdC5wYXJzZSgiXHUwMGU3MiBvJ2Nsb2NrIikuaW50VmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMiwgZm9ybWF0LnBhcnNlKCIxMiBvJ2Nsb2NrIikuaW50VmFsdWUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIiMwLiMjKnhFMCIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIGZvciIKKyAgICAgICAgICAgICAgICAgICAgKyAicGF0dGVybiBcIiMwLiMjKnhFMFwiLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3JtYXQuYXBwbHlQYXR0ZXJuKCIjIzAuIyMgKiIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIGZvciAiCisgICAgICAgICAgICAgICAgICAgICsgInBhdHRlcm4gXCIjIzAuIyMgKlwiLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIEFuZHJvaWRPbmx5OiBzcGVjaWFsIGZlYXR1cmUgb2YgaWN1NGMKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Bvc2l0aXZlRXhwb25lbnRTaWduKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIjAuIyMjRSswIik7CisgICAgICAgIGFzc2VydEVxdWFscygiMUUrMiIsIGZvcm1hdC5mb3JtYXQoMTAwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMUUtMiIsIGZvcm1hdC5mb3JtYXQoMC4wMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTAwLCBmb3JtYXQucGFyc2UoIjFFKzIiKS5pbnRWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAuMDFmLCBmb3JtYXQucGFyc2UoIjFFLTIiKS5mbG9hdFZhbHVlKCkpOworCisgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIjAuIyMjRTAgbS9zIik7CisgICAgICAgIGFzc2VydEVxdWFscygiMUUyIG0vcyIsIGZvcm1hdC5mb3JtYXQoMTAwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMDAsIGZvcm1hdC5wYXJzZSgiMUUyIG0vcyIpLmludFZhbHVlKCkpOworCisgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIjAwLiMjI0UwIik7CisgICAgICAgIGFzc2VydEVxdWFscygiMTIuM0UtNCIsIGZvcm1hdC5mb3JtYXQoMC4wMDEyMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoMC4wMDEyM2YsIGZvcm1hdC5wYXJzZSgiMTIuM0UtNCIpLmZsb2F0VmFsdWUoKSk7CisKKyAgICAgICAgZm9ybWF0LmFwcGx5UGF0dGVybigiIyMwLiMjIyNFMCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEyLjM0NUUzIiwgZm9ybWF0LmZvcm1hdCgxMjM0NSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTIzNDUsIGZvcm1hdC5wYXJzZSgiMTIuMzQ1RTMiKS5pbnRWYWx1ZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9ybWF0LmFwcGx5UGF0dGVybigiIywjIzAuIyNFMCIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIGZvciAiCisgICAgICAgICAgICAgICAgICAgICsgInBhdHRlcm4gXCIjLCMjMC4jI0UwXCIuIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLy8gQW5kcm9pZE9ubHk6IHNwZWNpYWwgZmVhdHVyZSBvZiBpY3U0YworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2Vjb25kYXJ5R3JvdXBpbmdTaXplKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIiMsIyMsIyMjLCMjIyMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMjMsNDU2LDc4OTAiLCBmb3JtYXQuZm9ybWF0KDEyMzQ1Njc4OTApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEyMzQ1Njc4OTAsIGZvcm1hdC5wYXJzZSgiMTIzLDQ1Niw3ODkwIikuaW50VmFsdWUoKSk7CisgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIiMjLCMsIyMjLCMjIyMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMjMsNDU2LDc4OTAiLCBmb3JtYXQuZm9ybWF0KDEyMzQ1Njc4OTApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEyMzQ1Njc4OTAsIGZvcm1hdC5wYXJzZSgiMTIzLDQ1Niw3ODkwIikuaW50VmFsdWUoKSk7CisgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIiMjIywjIyMsIyMjIyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEyMyw0NTYsNzg5MCIsIGZvcm1hdC5mb3JtYXQoMTIzNDU2Nzg5MCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTIzNDU2Nzg5MCwgZm9ybWF0LnBhcnNlKCIxMjMsNDU2LDc4OTAiKS5pbnRWYWx1ZSgpKTsKKworICAgICAgICBmb3JtYXQuYXBwbHlQYXR0ZXJuKCIjIyMsIyMsIyMjLiMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMiwzNCw1NjcuOCIsIGZvcm1hdC5mb3JtYXQoMTIzNDU2Ny44KSk7CisgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIiMjLCMsIyMsIyMjLiMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMiwzNCw1NjcuOCIsIGZvcm1hdC5mb3JtYXQoMTIzNDU2Ny44KSk7CisgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIiMsIyMsIyMsIyMjLiMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMiwzNCw1NjcuOCIsIGZvcm1hdC5mb3JtYXQoMTIzNDU2Ny44KSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZEZpZWxkUG9zaXRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkRmllbGRQb3NpdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNmZiZDk4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZEZpZWxkUG9zaXRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw3OSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS50ZXh0OworCitpbXBvcnQgamF2YS50ZXh0LkRhdGVGb3JtYXQ7CitpbXBvcnQgamF2YS50ZXh0LkZpZWxkUG9zaXRpb247CisKK3B1YmxpYyBjbGFzcyBPbGRGaWVsZFBvc2l0aW9uVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc2hDb2RlKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudGV4dC5GaWVsZFBvc2l0aW9uLmhhc2hDb2RlKCkKKyAgICAgICAgRmllbGRQb3NpdGlvbiBmcG9zMSA9IG5ldyBGaWVsZFBvc2l0aW9uKDEpOworICAgICAgICBGaWVsZFBvc2l0aW9uIGZwb3MyID0gbmV3IEZpZWxkUG9zaXRpb24oMSk7CisgICAgICAgIGFzc2VydFRydWUoInRlc3QgMTogaGFzaCBjb2RlcyBhcmUgbm90IGVxdWFsIGZvciBlcXVhbCBvYmplY3RzLiIsCisgICAgICAgICAgICAgICAgZnBvczEuaGFzaENvZGUoKSA9PSBmcG9zMi5oYXNoQ29kZSgpKTsKKyAgICAgICAgZnBvczEuc2V0QmVnaW5JbmRleCg1KTsKKyAgICAgICAgZnBvczEuc2V0RW5kSW5kZXgoMTEwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGVzdCAyOiBoYXNoIGNvZGVzIGFyZSBlcXVhbCBmb3Igbm9uIGVxdWFsIG9iamVjdHMuIiwKKyAgICAgICAgICAgICAgICBmcG9zMS5oYXNoQ29kZSgpICE9IGZwb3MyLmhhc2hDb2RlKCkpOworICAgICAgICBmcG9zMi5zZXRCZWdpbkluZGV4KDUpOworICAgICAgICBmcG9zMi5zZXRFbmRJbmRleCgxMTApOworICAgICAgICBhc3NlcnRUcnVlKCJ0ZXN0IDM6IGhhc2ggY29kZXMgYXJlIG5vdCBlcXVhbCBmb3IgZXF1YWwgb2JqZWN0cy4iLAorICAgICAgICAgICAgICAgIGZwb3MxLmhhc2hDb2RlKCkgPT0gZnBvczIuaGFzaENvZGUoKSk7CisKKyAgICAgICAgRmllbGRQb3NpdGlvbiBmcG9zMyA9IG5ldyBGaWVsZFBvc2l0aW9uKAorICAgICAgICAgICAgICAgIERhdGVGb3JtYXQuRmllbGQuREFZX09GX1dFRUtfSU5fTU9OVEgpOworCisgICAgICAgIGFzc2VydFRydWUoInRlc3QgNDogaGFzaCBjb2RlcyBhcmUgZXF1YWwgZm9yIG5vbiBlcXVhbCBvYmplY3RzLiIsCisgICAgICAgICAgICAgICAgZnBvczIuaGFzaENvZGUoKSAhPSBmcG9zMy5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEJlZ2luSW5kZXhJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnRleHQuRmllbGRQb3NpdGlvbi5zZXRCZWdpbkluZGV4KGludCkKKyAgICAgICAgRmllbGRQb3NpdGlvbiBmcG9zID0gbmV3IEZpZWxkUG9zaXRpb24oMSk7CisgICAgICAgIGZwb3Muc2V0QmVnaW5JbmRleCgyKTsKKyAgICAgICAgZnBvcy5zZXRFbmRJbmRleCgzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiZWdpbkluZGV4IHNob3VsZCBoYXZlIGJlZW4gc2V0IHRvIDIiLCAyLCBmcG9zCisgICAgICAgICAgICAgICAgLmdldEJlZ2luSW5kZXgoKSk7CisKKyAgICAgICAgZnBvcy5zZXRCZWdpbkluZGV4KEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiZWdpbkluZGV4IHNob3VsZCBoYXZlIGJlZW4gc2V0IHRvIEludGVnZXIuTUFYX1ZBTFVFIiwKKyAgICAgICAgICAgICAgICBJbnRlZ2VyLk1BWF9WQUxVRSwgZnBvcy5nZXRCZWdpbkluZGV4KCkpOworCisgICAgICAgIGZwb3Muc2V0QmVnaW5JbmRleCgtMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYmVnaW5JbmRleCBzaG91bGQgaGF2ZSBiZWVuIHNldCB0byAtMSIsCisgICAgICAgICAgICAgICAgLTEsIGZwb3MuZ2V0QmVnaW5JbmRleCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEVuZEluZGV4SSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS50ZXh0LkZpZWxkUG9zaXRpb24uc2V0RW5kSW5kZXgoaW50KQorICAgICAgICBGaWVsZFBvc2l0aW9uIGZwb3MgPSBuZXcgRmllbGRQb3NpdGlvbigxKTsKKyAgICAgICAgZnBvcy5zZXRFbmRJbmRleCgzKTsKKyAgICAgICAgZnBvcy5zZXRCZWdpbkluZGV4KDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkVuZEluZGV4IHNob3VsZCBoYXZlIGJlZW4gc2V0IHRvIDMiLCAzLCBmcG9zCisgICAgICAgICAgICAgICAgLmdldEVuZEluZGV4KCkpOworCisgICAgICAgIGZwb3Muc2V0RW5kSW5kZXgoSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVuZEluZGV4IHNob3VsZCBoYXZlIGJlZW4gc2V0IHRvIEludGVnZXIuTUFYX1ZBTFVFIiwKKyAgICAgICAgICAgICAgICBJbnRlZ2VyLk1BWF9WQUxVRSwgZnBvcy5nZXRFbmRJbmRleCgpKTsKKworICAgICAgICBmcG9zLnNldEVuZEluZGV4KC0xKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbmRJbmRleCBzaG91bGQgaGF2ZSBiZWVuIHNldCB0byAtMSIsCisgICAgICAgICAgICAgICAgLTEsIGZwb3MuZ2V0RW5kSW5kZXgoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZEZvcm1hdEZpZWxkVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZEZvcm1hdEZpZWxkVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU1ZDhlMzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkRm9ybWF0RmllbGRUZXN0LmphdmEKQEAgLTAsMCArMSwzNiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLnRleHQuRm9ybWF0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZEZvcm1hdEZpZWxkVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwcml2YXRlIGNsYXNzIE1vY2tGb3JtYXRGaWVsZCBleHRlbmRzIEZvcm1hdC5GaWVsZCB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAgICAgcHVibGljIE1vY2tGb3JtYXRGaWVsZChTdHJpbmcgbmFtZSkgeworICAgICAgICAgICAgc3VwZXIobmFtZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICBuZXcgTW9ja0Zvcm1hdEZpZWxkKCJ0ZXN0Iik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZEZvcm1hdFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGRGb3JtYXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2M2YzUyOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGRGb3JtYXRUZXN0LmphdmEKQEAgLTAsMCArMSw5NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yOworaW1wb3J0IGphdmEudGV4dC5GaWVsZFBvc2l0aW9uOworaW1wb3J0IGphdmEudGV4dC5Gb3JtYXQ7CitpbXBvcnQgamF2YS50ZXh0LlBhcnNlRXhjZXB0aW9uOworaW1wb3J0IGphdmEudGV4dC5QYXJzZVBvc2l0aW9uOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworCitwdWJsaWMgY2xhc3MgT2xkRm9ybWF0VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwcml2YXRlIGNsYXNzIE1vY2tGb3JtYXQgZXh0ZW5kcyBGb3JtYXQgeworCisgICAgICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgZm9ybWF0KE9iamVjdCBvYmosIFN0cmluZ0J1ZmZlciB0b0FwcGVuZFRvLAorICAgICAgICAgICAgICAgIEZpZWxkUG9zaXRpb24gcG9zKSB7CisgICAgICAgICAgICAvLyBpdCBpcyBhIGZha2UKKyAgICAgICAgICAgIGlmIChvYmogPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm9iaiBpcyBudWxsIik7CisgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZ0J1ZmZlcigiIik7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IHBhcnNlT2JqZWN0KFN0cmluZyBzb3VyY2UsIFBhcnNlUG9zaXRpb24gcG9zKSB7CisgICAgICAgICAgICAvLyBpdCBpcyBhIGZha2UKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgbmV3IE1vY2tGb3JtYXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnRleHQuRm9ybWF0I2Nsb25lKCkgVGVzdCBvZiBtZXRob2QgamF2YS50ZXh0LkZvcm1hdCNjbG9uZSgpLgorICAgICAqICAgICAgICBDb21wYXJlIG9mIGludGVybmFsIHZhcmlhYmxlcyBvZiBjbG9uZWQgb2JqZWN0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb25lKCkgeworICAgICAgICAvLyBDb21wYXJlIG9mIGludGVybmFsIHZhcmlhYmxlcyBvZiBjbG9uZWQgb2JqZWN0cworICAgICAgICBGb3JtYXQgZm0gPSBuZXcgTW9ja0Zvcm1hdCgpOworICAgICAgICBGb3JtYXQgZm1jID0gKEZvcm1hdCkgZm0uY2xvbmUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZtLmdldENsYXNzKCksIGZtYy5nZXRDbGFzcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Zvcm1hdExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICBNb2NrRm9ybWF0IG1mID0gbmV3IE1vY2tGb3JtYXQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBtZi5mb3JtYXQoIiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSXQgY2FsbHMgYW4gYWJzdHJhY3QgbWV0b2QgZm9ybWF0IiwgdHJ1ZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9mb3JtYXRUb0NoYXJhY3Rlckl0ZXJhdG9yTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIE1vY2tGb3JtYXQgbWYgPSBuZXcgTW9ja0Zvcm1hdCgpOworICAgICAgICBBdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3IgYWNpID0gbWYuZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcigiVGVzdCAxMjMgVGVzdCIpOworCisgICAgICAgIGFzc2VydEVxdWFscygwLCBhY2kuZ2V0QmVnaW5JbmRleCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWYuZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1mLmZvcm1hdFRvQ2hhcmFjdGVySXRlcmF0b3IoIiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAgaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BhcnNlT2JqZWN0TGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIE1vY2tGb3JtYXQgbWYgPSBuZXcgTW9ja0Zvcm1hdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbChtZi5wYXJzZU9iamVjdCgiIikpOworICAgICAgICAgICAgZmFpbCgiUGFyc2VFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGRNZXNzYWdlRm9ybWF0RmllbGRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkTWVzc2FnZUZvcm1hdEZpZWxkVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlNjBlZjgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkTWVzc2FnZUZvcm1hdEZpZWxkVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnZhbGlkT2JqZWN0RXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQ7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkTWVzc2FnZUZvcm1hdEZpZWxkVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgLy8gcHJvdGVjdGVkIGNvbnN0cnVjdG9yCisgICAgICAgIFN0cmluZyBuYW1lID0gIm5ldyBNZXNzYWdlIGZvcm1hdCI7CisgICAgICAgIE15TWVzc2FnZUZvcm1hdCBmaWVsZCA9IG5ldyBNeU1lc3NhZ2VGb3JtYXQobmFtZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZmllbGQgaGFzIHdyb25nIG5hbWUiLCBuYW1lLCBmaWVsZC5nZXROYW1lKCkpOworCisgICAgICAgIGZpZWxkID0gbmV3IE15TWVzc2FnZUZvcm1hdChudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmaWVsZCBoYXMgd3JvbmcgbmFtZSIsIG51bGwsIGZpZWxkLmdldE5hbWUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkUmVzb2x2ZSgpIHsKKyAgICAgICAgLy8gdGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QgcmVhZFJlc29sdmUoKQorCisgICAgICAgIC8vIHNlZSBzZXJpYWxpemF0aW9uIHN0cmVzcyB0ZXN0czoKKyAgICAgICAgLy8gaW1wbGVtZW50ZWQgaW4KKyAgICAgICAgLy8gU2VyaWFsaXphdGlvblN0cmVzc1Rlc3Q0LnRlc3Rfd3JpdGVPYmplY3RfTWVzc2FnZUZvcm1hdF9GaWVsZCgpCisgICAgICAgIE9iamVjdE91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICBPYmplY3RJbnB1dFN0cmVhbSBpbiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZXMgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICBvdXQgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKGJ5dGVzKTsKKworICAgICAgICAgICAgTWVzc2FnZUZvcm1hdC5GaWVsZCBtZmllbGQsIG1maWVsZDI7CisgICAgICAgICAgICBNeU1lc3NhZ2VGb3JtYXQgZmllbGQ7CisKKyAgICAgICAgICAgIG1maWVsZCA9IE1lc3NhZ2VGb3JtYXQuRmllbGQuQVJHVU1FTlQ7CisKKyAgICAgICAgICAgIGZpZWxkID0gbmV3IE15TWVzc2FnZUZvcm1hdChudWxsKTsKKworICAgICAgICAgICAgb3V0LndyaXRlT2JqZWN0KG1maWVsZCk7CisgICAgICAgICAgICBvdXQud3JpdGVPYmplY3QoZmllbGQpOworCisgICAgICAgICAgICBpbiA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZXMKKyAgICAgICAgICAgICAgICAgICAgLnRvQnl0ZUFycmF5KCkpKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBtZmllbGQyID0gKE1lc3NhZ2VGb3JtYXQuRmllbGQpIGluLnJlYWRPYmplY3QoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRTYW1lKCJyZXNvbHZlZCBpbmNvcnJlY3RseSIsIG1maWVsZCwgbWZpZWxkMik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaW4ucmVhZE9iamVjdCgpOworICAgICAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIEludmFsaWRPYmplY3RFeGNlcHRpb24gZm9yIHN1YmNsYXNzIGluc3RhbmNlIHdpdGggbnVsbCBuYW1lIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkT2JqZWN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIElPRXhjZXB0aW9uIiArIGUpOworICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiIgKyBlKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKG91dCAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBpZiAoaW4gIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBNeU1lc3NhZ2VGb3JtYXQgZXh0ZW5kcyBNZXNzYWdlRm9ybWF0LkZpZWxkIHsKKyAgICAgICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgICAgIHByb3RlY3RlZCBNeU1lc3NhZ2VGb3JtYXQoU3RyaW5nIGF0dHIpIHsKKyAgICAgICAgICAgIHN1cGVyKGF0dHIpOworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldE5hbWUoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGRNZXNzYWdlRm9ybWF0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZE1lc3NhZ2VGb3JtYXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjcwMWQwZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGRNZXNzYWdlRm9ybWF0VGVzdC5qYXZhCkBAIC0wLDAgKzEsNDYzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudGV4dDsKKworaW1wb3J0IGphdmEudGV4dC5DaG9pY2VGb3JtYXQ7CitpbXBvcnQgamF2YS50ZXh0LkRhdGVGb3JtYXQ7CitpbXBvcnQgamF2YS50ZXh0LkZpZWxkUG9zaXRpb247CitpbXBvcnQgamF2YS50ZXh0LkZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuTnVtYmVyRm9ybWF0OworaW1wb3J0IGphdmEudGV4dC5QYXJzZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnRleHQuUGFyc2VQb3NpdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9NZXNzYWdlRm9ybWF0OworCitwdWJsaWMgY2xhc3MgT2xkTWVzc2FnZUZvcm1hdFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIE1lc3NhZ2VGb3JtYXQgZm9ybWF0MTsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChMb2NhbGUuVVMpOworCisgICAgICAgIC8vIHRlc3Qgd2l0aCByZXBlYXRpbmcgZm9ybWF0cyBhbmQgbWF4IGFyZ3VtZW50IGluZGV4IDwgbWF4IG9mZnNldAorICAgICAgICBTdHJpbmcgcGF0dGVybiA9ICJBIHszLCBudW1iZXIsIGN1cnJlbmN5fSBCIHsyLCB0aW1lfSBDIHswLCBudW1iZXIsIHBlcmNlbnR9IEQgezR9ICBFIHsxLGNob2ljZSwwI29mZnwxI29ufSBGIHswLCBkYXRlfSI7CisgICAgICAgIGZvcm1hdDEgPSBuZXcgTWVzc2FnZUZvcm1hdChwYXR0ZXJuKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FwcGx5UGF0dGVybkxqYXZhX2xhbmdfU3RyaW5nX0FuZHJvaWRGYWlsdXJlKCkgeworICAgICAgICBNZXNzYWdlRm9ybWF0IGZvcm1hdCA9IG5ldyBNZXNzYWdlRm9ybWF0KCJ0ZXN0Iik7CisgICAgICAgIGZvcm1hdC5zZXRMb2NhbGUoTG9jYWxlLkZSRU5DSCk7IC8vIHVzZSBGcmVuY2ggc2luY2UgRW5nbGlzaCBoYXMgdGhlCisgICAgICAgIC8vIHNhbWUgTE9ORyBhbmQgRlVMTCB0aW1lIHBhdHRlcm5zCisgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oInswLHRpbWUsIEZ1bGx9Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgZnVsbCB0aW1lIHBhdHRlcm4iLCAiezAsdGltZSxmdWxsfSIsIGZvcm1hdAorICAgICAgICAgICAgICAgIC50b1BhdHRlcm4oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9mb3JtYXRUb0NoYXJhY3Rlckl0ZXJhdG9yTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBmb3JtYXRUb0NoYXJhY3Rlckl0ZXJhdG9yKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIG5ldyBTdXBwb3J0X01lc3NhZ2VGb3JtYXQoCisgICAgICAgICAgICAgICAgInRlc3RfZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvckxqYXZhX2xhbmdfT2JqZWN0IikKKyAgICAgICAgICAgICAgICAudF9mb3JtYXRUb0NoYXJhY3Rlckl0ZXJhdG9yKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBNZXNzYWdlRm9ybWF0KCJ7MSwgbnVtYmVyfSIpLmZvcm1hdFRvQ2hhcmFjdGVySXRlcmF0b3IobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgTWVzc2FnZUZvcm1hdCgiezAsIHRpbWV9IikuZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcihuZXcgT2JqZWN0W117IiJ9KTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldExvY2FsZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIExvY2FsZVtdIGwgPSB7CisgICAgICAgICAgICAgICAgICAgIExvY2FsZS5GUkFOQ0UsCisgICAgICAgICAgICAgICAgICAgIExvY2FsZS5LT1JFQSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvY2FsZShMb2NhbGUuRlJBTkNFLmdldENvdW50cnkoKSwgTG9jYWxlLkZSQU5DRQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRMYW5ndWFnZSgpKSwgbmV3IExvY2FsZSgibWsiKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvY2FsZSgibWsiLCAiTUsiKSwgTG9jYWxlLlVTLAorICAgICAgICAgICAgICAgICAgICBuZXcgTG9jYWxlKCIjcnUiLCAiQDMxMjMwIikgfTsKKworICAgICAgICAgICAgU3RyaW5nIHBhdHRlcm4gPSAiZ2V0TG9jYWxlIHRlc3QgezAsbnVtYmVyLCMsIyMjI30iOworICAgICAgICAgICAgTWVzc2FnZUZvcm1hdCBtZjsKKworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAwOyBpKyspIHsKKyAgICAgICAgICAgICAgICBtZiA9IG5ldyBNZXNzYWdlRm9ybWF0KHBhdHRlcm4sIGxbaV0pOworICAgICAgICAgICAgICAgIExvY2FsZSByZXN1bHQgPSBtZi5nZXRMb2NhbGUoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGxvY2FsOiAiICsgcmVzdWx0ICsgIiBpbnN0ZWFkIG9mICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgbFtpXSwgbFtpXSwgcmVzdWx0KTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGxhbmd1YWdlOiAiICsgcmVzdWx0LmdldExhbmd1YWdlKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiBpbnN0ZWFkIG9mICIgKyBsW2ldLmdldExhbmd1YWdlKCksIGxbaV0KKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRMYW5ndWFnZSgpLCByZXN1bHQuZ2V0TGFuZ3VhZ2UoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBjb3VudHJ5OiAiICsgcmVzdWx0LmdldENvdW50cnkoKQorICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGluc3RlYWQgb2YgIiArIGxbaV0uZ2V0Q291bnRyeSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgbFtpXS5nZXRDb3VudHJ5KCksIHJlc3VsdC5nZXRDb3VudHJ5KCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBtZiA9IG5ldyBNZXNzYWdlRm9ybWF0KHBhdHRlcm4pOworICAgICAgICAgICAgbWYuc2V0TG9jYWxlKG51bGwpOworICAgICAgICAgICAgTG9jYWxlIHJlc3VsdCA9IG1mLmdldExvY2FsZSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBsb2NhbDogIiArIHJlc3VsdCArICIgaW5zdGVhZCBvZiBudWxsIiwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCwgcmVzdWx0KTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQjc2V0Rm9ybWF0KGludCwgRm9ybWF0KSBUZXN0IG9mIG1ldGhvZAorICAgICAqICAgICAgICBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdCNzZXRGb3JtYXQoaW50LCBGb3JtYXQpLiBDYXNlIDE6IENvbXBhcmUKKyAgICAgKiAgICAgICAgZ2V0Rm9ybWF0cygpIHJlc3VsdHMgYWZ0ZXIgY2FsbHMgdG8gc2V0Rm9ybWF0KCkuIENhc2UgMjogVHJ5IHRvCisgICAgICogICAgICAgIGNhbGwgc2V0Rm9ybWF0KCkgdXNpbmcgaW5jb3JyZWN0IGluZGV4LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0Rm9ybWF0SUxqYXZhX3RleHRfRm9ybWF0KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gY2FzZSAxOiBDb21wYXJlIGdldEZvcm1hdHMoKSByZXN1bHRzIGFmdGVyIGNhbGxzIHRvIHNldEZvcm1hdCgpCisgICAgICAgICAgICBNZXNzYWdlRm9ybWF0IGYxID0gKE1lc3NhZ2VGb3JtYXQpIGZvcm1hdDEuY2xvbmUoKTsKKyAgICAgICAgICAgIGYxLnNldEZvcm1hdCgwLCBEYXRlRm9ybWF0LmdldFRpbWVJbnN0YW5jZSgpKTsKKyAgICAgICAgICAgIGYxLnNldEZvcm1hdCgxLCBEYXRlRm9ybWF0LmdldFRpbWVJbnN0YW5jZSgpKTsKKyAgICAgICAgICAgIGYxLnNldEZvcm1hdCgyLCBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKSk7CisgICAgICAgICAgICBmMS5zZXRGb3JtYXQoMywgbmV3IENob2ljZUZvcm1hdCgiMCNvZmZ8MSNvbiIpKTsKKyAgICAgICAgICAgIGYxLnNldEZvcm1hdCg0LCBuZXcgQ2hvaWNlRm9ybWF0KCIxI2Zld3wyI29rfDMjYSBsb3QiKSk7CisgICAgICAgICAgICBmMS5zZXRGb3JtYXQoNSwgRGF0ZUZvcm1hdC5nZXRUaW1lSW5zdGFuY2UoKSk7CisKKyAgICAgICAgICAgIEZvcm1hdFtdIGZvcm1hdHMgPSBmMS5nZXRGb3JtYXRzKCk7CisgICAgICAgICAgICBmb3JtYXRzID0gZjEuZ2V0Rm9ybWF0cygpOworCisgICAgICAgICAgICBGb3JtYXRbXSBjb3JyZWN0Rm9ybWF0cyA9IG5ldyBGb3JtYXRbXSB7CisgICAgICAgICAgICAgICAgICAgIERhdGVGb3JtYXQuZ2V0VGltZUluc3RhbmNlKCksIERhdGVGb3JtYXQuZ2V0VGltZUluc3RhbmNlKCksCisgICAgICAgICAgICAgICAgICAgIE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpLCBuZXcgQ2hvaWNlRm9ybWF0KCIwI29mZnwxI29uIiksCisgICAgICAgICAgICAgICAgICAgIG5ldyBDaG9pY2VGb3JtYXQoIjEjZmV3fDIjb2t8MyNhIGxvdCIpLAorICAgICAgICAgICAgICAgICAgICBEYXRlRm9ybWF0LmdldFRpbWVJbnN0YW5jZSgpIH07CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDFBOlJldHVybmVkIHdyb25nIG51bWJlciBvZiBmb3JtYXRzOiIsCisgICAgICAgICAgICAgICAgICAgIGNvcnJlY3RGb3JtYXRzLmxlbmd0aCwgZm9ybWF0cy5sZW5ndGgpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3JyZWN0Rm9ybWF0cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgICJUZXN0MUI6d3JvbmcgZm9ybWF0IGZvciBwYXR0ZXJuIGluZGV4ICIgKyBpICsgIjoiLAorICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVjdEZvcm1hdHNbaV0sIGZvcm1hdHNbaV0pOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBjYXNlIDI6IFRyeSB0byBzZXRGb3JtYXQgdXNpbmcgaW5jb3JyZWN0IGluZGV4CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGYxLnNldEZvcm1hdCgtMSwgRGF0ZUZvcm1hdC5nZXREYXRlSW5zdGFuY2UoKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICAgICAgZjEuc2V0Rm9ybWF0KGYxLmdldEZvcm1hdHMoKS5sZW5ndGgsIERhdGVGb3JtYXQKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXREYXRlSW5zdGFuY2UoKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZm9ybWF0JExqYXZhX2xhbmdfT2JqZWN0TGphdmFfbGFuZ19TdHJpbmdCdWZmZXJMamF2YV90ZXh0X0ZpZWxkUG9zaXRpb24oKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuU3RyaW5nQnVmZmVyCisgICAgICAgIC8vIGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChqYXZhLmxhbmcuT2JqZWN0IFtdLAorICAgICAgICAvLyBqYXZhLmxhbmcuU3RyaW5nQnVmZmVyLCBqYXZhLnRleHQuRmllbGRQb3NpdGlvbikKKyAgICAgICAgTWVzc2FnZUZvcm1hdCBmb3JtYXQgPSBuZXcgTWVzc2FnZUZvcm1hdCgiezEsbnVtYmVyLGludGVnZXJ9Iik7CisgICAgICAgIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIGZvcm1hdC5mb3JtYXQobmV3IE9iamVjdFtdIHsgIjAiLCBuZXcgRG91YmxlKDUzLjg2MykgfSwgYnVmZmVyLAorICAgICAgICAgICAgICAgIG5ldyBGaWVsZFBvc2l0aW9uKE1lc3NhZ2VGb3JtYXQuRmllbGQuQVJHVU1FTlQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXN1bHQiLCAiNTQiLCBidWZmZXIudG9TdHJpbmcoKSk7CisKKyAgICAgICAgZm9ybWF0LmZvcm1hdChuZXcgT2JqZWN0W10geyAiMCIsIG5ldyBEb3VibGUoNTMuODYzKSB9LCBidWZmZXIsCisgICAgICAgICAgICAgICAgbmV3IEZpZWxkUG9zaXRpb24oTWVzc2FnZUZvcm1hdC5GaWVsZC5BUkdVTUVOVCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcmVzdWx0IiwgIjU0NTQiLCBidWZmZXIudG9TdHJpbmcoKSk7CisKKyAgICAgICAgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBmb3JtYXQKKyAgICAgICAgICAgICAgICAuYXBwbHlQYXR0ZXJuKCJ7MCxjaG9pY2UsMCN6ZXJvfDEjb25lICd7MSxjaG9pY2UsMiN0d28gezIsdGltZX19J30iKTsKKyAgICAgICAgRGF0ZSBkYXRlID0gbmV3IERhdGUoKTsKKyAgICAgICAgU3RyaW5nIGV4cGVjdGVkID0gIm9uZSB0d28gIgorICAgICAgICAgICAgICAgICsgRGF0ZUZvcm1hdC5nZXRUaW1lSW5zdGFuY2UoKS5mb3JtYXQoZGF0ZSk7CisgICAgICAgIGZvcm1hdC5mb3JtYXQobmV3IE9iamVjdFtdIHsgbmV3IERvdWJsZSgxLjYpLAorICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKDMpLCBkYXRlIH0sIGJ1ZmZlciwgbmV3IEZpZWxkUG9zaXRpb24oTWVzc2FnZUZvcm1hdAorICAgICAgICAgICAgICAgICAgICAgICAgLkZpZWxkLkFSR1VNRU5UKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQ2hvaWNlIG5vdCByZWN1cnNpdmU6XG4iICsgZXhwZWN0ZWQgKyAiXG4iICsgYnVmZmVyLAorICAgICAgICAgICAgICAgIGV4cGVjdGVkLCBidWZmZXIudG9TdHJpbmcoKSk7CisKKyAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IGZvcm1hdC5mb3JtYXQobmV3IE9iamVjdFtdIHsgbmV3IERvdWJsZSgwLjYpLAorICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKDMpfSwgYnVmZmVyLCBudWxsKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQgKyAiemVybyIsIHN0ci50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkICsgInplcm8iLCBidWZmZXIudG9TdHJpbmcoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvcm1hdC5mb3JtYXQobmV3IE9iamVjdFtdIHsgIjAiLCBuZXcgRG91YmxlKDEpLCAiIiB9LCBidWZmZXIsCisgICAgICAgICAgICAgICAgICAgIG5ldyBGaWVsZFBvc2l0aW9uKE1lc3NhZ2VGb3JtYXQuRmllbGQuQVJHVU1FTlQpKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9ybWF0LmZvcm1hdChuZXcgT2JqZWN0W10geyAiIiwgIG5ldyBJbnRlZ2VyKDMpfSwgYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICBuZXcgRmllbGRQb3NpdGlvbihNZXNzYWdlRm9ybWF0LkZpZWxkLkFSR1VNRU5UKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9mb3JtYXRMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICBUaW1lWm9uZS5zZXREZWZhdWx0KFRpbWVab25lLmdldFRpbWVab25lKCJVVEMiKSk7CisgICAgICAgIGludCBpQ3VycmVuY3kgPSAxMjM7CisgICAgICAgIGludCBpSW50ZWdlciAgPSBJbnRlZ2VyLk1JTl9WQUxVRTsKKworICAgICAgICBEYXRlICAgICBkYXRlICAgICA9IG5ldyBEYXRlKDEyMzQ1Njc4KTsKKyAgICAgICAgT2JqZWN0W10gYXJncyAgICAgPSB7IGRhdGUsIGlDdXJyZW5jeSwgaUludGVnZXIgfTsKKyAgICAgICAgU3RyaW5nICAgcmVzU3RyICAgPSAiRGF0ZTogSmFuIDEsIDE5NzAgQ3VycmVuY3k6ICQiICsgaUN1cnJlbmN5CisgICAgICAgICAgICAgICAgICAgICsgIi4wMCBJbnRlZ2VyOiAtMiwxNDcsNDgzLDY0OCI7CisgICAgICAgIFN0cmluZyAgIHBhdHRlcm4gID0gIkRhdGU6IHswLGRhdGV9IEN1cnJlbmN5OiB7MSwgbnVtYmVyLCBjdXJyZW5jeX0gSW50ZWdlcjogezIsIG51bWJlciwgaW50ZWdlcn0iOworICAgICAgICBTdHJpbmcgICBzRm9ybWF0ICA9IE1lc3NhZ2VGb3JtYXQuZm9ybWF0KHBhdHRlcm4sIChPYmplY3RbXSkgYXJncyk7CisgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAiZm9ybWF0KFN0cmluZywgT2JqZWN0W10pIHdpdGggdmFsaWQgcGFyYW1ldGVycyByZXR1cm5zIGluY29ycmVjdCBzdHJpbmc6IGNhc2UgMSIsCisgICAgICAgICAgICAgICAgc0Zvcm1hdCwgcmVzU3RyKTsKKworICAgICAgICBwYXR0ZXJuID0gImFiYyB7NCwgbnVtYmVyLCBpbnRlZ2VyfSBkZWYgezMsZGF0ZX0gZ2hpIHsyLG51bWJlcn0gamtsIHsxLGNob2ljZSwwI2xvd3wxI2hpZ2h9IG1ub3AgezB9IjsKKyAgICAgICAgcmVzU3RyICA9ICJhYmMgLTIsMTQ3LDQ4Myw2NDggZGVmIEphbiAxLCAxOTcwIGdoaSAtMiwxNDcsNDgzLDY0OCBqa2wgaGlnaCBtbm9wIC0yLDE0Nyw0ODMsNjQ4IjsKKyAgICAgICAgT2JqZWN0W10gYXJnc18gPSB7IGlJbnRlZ2VyLCAxLCBpSW50ZWdlciwgZGF0ZSwgaUludGVnZXIgfTsKKyAgICAgICAgc0Zvcm1hdCA9IE1lc3NhZ2VGb3JtYXQuZm9ybWF0KHBhdHRlcm4sIGFyZ3NfKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICJmb3JtYXQoU3RyaW5nLCBPYmplY3RbXSkgd2l0aCB2YWxpZCBwYXJhbWV0ZXJzIHJldHVybnMgaW5jb3JyZWN0IHN0cmluZzogY2FzZSAxIiwKKyAgICAgICAgICAgICAgICBzRm9ybWF0LCByZXNTdHIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcmdzID0gbnVsbDsKKyAgICAgICAgICAgIE1lc3NhZ2VGb3JtYXQuZm9ybWF0KG51bGwsIGFyZ3MpOworICAgICAgICAgICAgZmFpbCgiRG9lc24ndCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb246IG51bGwsIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTWVzc2FnZUZvcm1hdC5mb3JtYXQoIkludmFsaWQgezEsZm9vYmFyfSBmb3JtYXQgZGVzY3JpcHRvciEiLAorICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10ge2lJbnRlZ2VyfSApOworICAgICAgICAgICAgZmFpbCgiRG9lc24ndCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2l0aCBpbnZhbGlkIHBhdHRlcm4gYXMgYSBwYXJhbWV0ZXI6IGNhc2UgMSIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTWVzc2FnZUZvcm1hdC5mb3JtYXQoCisgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIHsxLGRhdGUsaW52YWxpZC1zcGVjfSBmb3JtYXQgZGVzY3JpcHRvciEiLCBuZXcgT2JqZWN0W117IiJ9KTsKKyAgICAgICAgICAgIGZhaWwoIkRvZXNuJ3QgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdpdGggaW52YWxpZCBwYXR0ZXJuIGFzIGEgcGFyYW1ldGVyOiBjYXNlIDIiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE1lc3NhZ2VGb3JtYXQuZm9ybWF0KCJ7MCxudW1iZXIsaW50ZWdlciIsIG5ldyBPYmplY3RbXSB7aUludGVnZXJ9KTsKKyAgICAgICAgICAgIGZhaWwoIkRvZXNuJ3QgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBkb2Vzbid0IGRldGVjdCB1bm1hdGNoZWQgYnJhY2tldHMiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE1lc3NhZ2VGb3JtYXQuZm9ybWF0KAorICAgICAgICAgICAgICAgICAgICAiVmFsaWQgezEsIGRhdGV9IGZvcm1hdCB7MCwgbnVtYmVyfSBkZXNjcmlwdG9yISIsIG5ldyBPYmplY3RbXXsgIiIgfSApOworICAgICAgICAgICAgZmFpbCgiRG9lc24ndCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2l0aCBpbnZhbGlkIE9iamVjdCBhcnJheSIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Zvcm1hdExqYXZhX2xhbmdfT2JqZWN0TGphdmFfbGFuZ19TdHJpbmdCdWZmZXJMamF2YV90ZXh0X0ZpZWxkUG9zaXRpb24oKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuU3RyaW5nQnVmZmVyCisgICAgICAgIC8vIGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChqYXZhLmxhbmcuT2JqZWN0LAorICAgICAgICAvLyBqYXZhLmxhbmcuU3RyaW5nQnVmZmVyLCBqYXZhLnRleHQuRmllbGRQb3NpdGlvbikKKyAgICAgICAgbmV3IFN1cHBvcnRfTWVzc2FnZUZvcm1hdCgKKyAgICAgICAgICAgICAgICAidGVzdF9mb3JtYXRMamF2YV9sYW5nX09iamVjdExqYXZhX2xhbmdfU3RyaW5nQnVmZmVyTGphdmFfdGV4dF9GaWVsZFBvc2l0aW9uIikKKyAgICAgICAgICAgICAgICAudF9mb3JtYXRfd2l0aF9GaWVsZFBvc2l0aW9uKCk7CisKKyAgICAgICAgU3RyaW5nIHBhdHRlcm4gPSAiT24gezQsZGF0ZX0gYXQgezMsdGltZX0sIGhlIGF0ZSB7MixudW1iZXIsIGludGVnZXJ9ICIgKworICAgICAgICAgICAgICAgICJoYW1idXJnZXJ7MixjaG9pY2UsMSN8MTxzfS4iOworICAgICAgICBNZXNzYWdlRm9ybWF0IGZvcm1hdCA9IG5ldyBNZXNzYWdlRm9ybWF0KHBhdHRlcm4sIExvY2FsZS5VUyk7CisKKyAgICAgICAgT2JqZWN0W10gb2JqZWN0cyA9IG5ldyBPYmplY3RbXSB7ICIiLCBuZXcgSW50ZWdlcigzKSwgOCwgIiJ9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3JtYXQuZm9ybWF0KG9iamVjdHMsIG5ldyBTdHJpbmdCdWZmZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEZpZWxkUG9zaXRpb24oRGF0ZUZvcm1hdC5GaWVsZC5BTV9QTSkpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0Rm9ybWF0cyRMamF2YV90ZXh0X0Zvcm1hdCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE1lc3NhZ2VGb3JtYXQgZjEgPSAoTWVzc2FnZUZvcm1hdCkgZm9ybWF0MS5jbG9uZSgpOworCisgICAgICAgICAgICAvLyBjYXNlIDE6IFRlc3Qgd2l0aCByZXBlYXRpbmcgZm9ybWF0cyBhbmQgbWF4IGFyZ3VtZW50IGluZGV4IDwgbWF4CisgICAgICAgICAgICAvLyBvZmZzZXQKKyAgICAgICAgICAgIC8vIGNvbXBhcmUgZ2V0Rm9ybWF0cygpIHJlc3VsdHMgYWZ0ZXIgY2FsbHMgdG8gc2V0Rm9ybWF0cyhGb3JtYXRbXSkKKyAgICAgICAgICAgIEZvcm1hdFtdIGNvcnJlY3RGb3JtYXRzID0gbmV3IEZvcm1hdFtdIHsKKyAgICAgICAgICAgICAgICAgICAgRGF0ZUZvcm1hdC5nZXRUaW1lSW5zdGFuY2UoKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IENob2ljZUZvcm1hdCgiMCNvZmZ8MSNvbiIpLAorICAgICAgICAgICAgICAgICAgICBEYXRlRm9ybWF0LmdldFRpbWVJbnN0YW5jZSgpLAorICAgICAgICAgICAgICAgICAgICBOdW1iZXJGb3JtYXQuZ2V0Q3VycmVuY3lJbnN0YW5jZSgpLAorICAgICAgICAgICAgICAgICAgICBuZXcgQ2hvaWNlRm9ybWF0KCIxI2Zld3wyI29rfDMjYSBsb3QiKSB9OworCisgICAgICAgICAgICBmMS5zZXRGb3JtYXRzKGNvcnJlY3RGb3JtYXRzKTsKKyAgICAgICAgICAgIEZvcm1hdFtdIGZvcm1hdHMgPSBmMS5nZXRGb3JtYXRzKCk7CisKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlRlc3QxQTpSZXR1cm5lZCB3cm9uZyBudW1iZXIgb2YgZm9ybWF0czoiLAorICAgICAgICAgICAgICAgICAgICBjb3JyZWN0Rm9ybWF0cy5sZW5ndGggPD0gZm9ybWF0cy5sZW5ndGgpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3JyZWN0Rm9ybWF0cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDFCOndyb25nIGZvcm1hdCBmb3IgYXJndW1lbnQgaW5kZXggIiArIGkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIjoiLCBjb3JyZWN0Rm9ybWF0c1tpXSwgZm9ybWF0c1tpXSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGNhc2UgMjogVHJ5IHRvIHBhc3MgbnVsbCBhcmd1bWVudCB0byBzZXRGb3JtYXRzKCkuCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGYxLnNldEZvcm1hdHMobnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgZXhjZXB0aW9uIE51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9wYXJzZUxqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHBhdHRlcm4gPSAiQSB7MywgbnVtYmVyLCBjdXJyZW5jeX0gQiB7MiwgdGltZX0gQyB7MCwgbnVtYmVyLCBwZXJjZW50fSBEIHs0fSAgRSB7MSxjaG9pY2UsMCNvZmZ8MSNvbn0gRiB7MCwgZGF0ZX0iOworICAgICAgICBNZXNzYWdlRm9ybWF0IG1mID0gbmV3IE1lc3NhZ2VGb3JtYXQocGF0dGVybik7CisgICAgICAgIFN0cmluZyBzVG9QYXJzZSA9ICJBICQxMiwzNDUuMDAgQiA5OjU2OjA3IEFNIEMgMywyMDAlIEQgMS8xNS83MCA5OjU2IEFNICBFIG9uIEYgSmFuIDEsIDE5NzAiOworICAgICAgICBPYmplY3RbXSByZXN1bHQ7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXN1bHQgPSBtZi5wYXJzZShzVG9QYXJzZSk7CisKKyAgICAgICAgICAgIGFzc2VydFRydWUoIk5vIHJlc3VsdDogIiArIHJlc3VsdC5sZW5ndGgsIHJlc3VsdC5sZW5ndGggPT0gNSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJPYmplY3QgMCBpcyBub3QgZGF0ZSIsIHJlc3VsdFswXSBpbnN0YW5jZW9mIERhdGUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJPYmplY3QgMSBpcyBub3Qgc3RyaW5nciIsIHJlc3VsdFsxXS50b1N0cmluZygpLCAiMS4wIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJPYmplY3QgMiBpcyBub3QgZGF0ZSIsIHJlc3VsdFsyXSBpbnN0YW5jZW9mIERhdGUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJPYmplY3QgMyBpcyBub3QgbnVtYmVyIiwgcmVzdWx0WzNdLnRvU3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgICIxMjM0NSIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJPYmplY3QgNCBpcyBub3Qgc3RyaW5nIiwgcmVzdWx0WzRdLnRvU3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgICIxLzE1LzcwIDk6NTYgQU0iKTsKKworICAgICAgICB9IGNhdGNoIChqYXZhLnRleHQuUGFyc2VFeGNlcHRpb24gcGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlBhcnNlRXhjZXB0aW9uIGlzIHRocm93biBmb3IgaW5jb3JyZWN0IHN0cmluZyAiICsgc1RvUGFyc2UpOworICAgICAgICB9CisKKyAgICAgICAgc1RvUGFyc2UgPSAieHhkYXRlIGlzIEZlYiAyOCwgMTk5OSI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXN1bHQgPSBmb3JtYXQxLnBhcnNlKHNUb1BhcnNlKTsKKyAgICAgICAgICAgIGZhaWwoIlBhcnNlRXhjZXB0aW9uIGlzIHRocm93biBmb3IgaW5jb3JyZWN0IHN0cmluZyAiICsgc1RvUGFyc2UpOworICAgICAgICB9IGNhdGNoIChqYXZhLnRleHQuUGFyc2VFeGNlcHRpb24gcGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBzVG9QYXJzZSA9ICJ2bT1UZXN0LCBAMyA0IDYsIDMgICAiOworICAgICAgICBtZiA9IG5ldyBNZXNzYWdlRm9ybWF0KCJ2bT17MH0sezF9LHsyfSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzdWx0ID0gbWYucGFyc2Uoc1RvUGFyc2UpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTm8gcmVzdWx0OiAiICsgcmVzdWx0Lmxlbmd0aCwgcmVzdWx0Lmxlbmd0aCA9PSAzKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiT2JqZWN0IDAgaXMgbm90IHN0cmluZyIsIHJlc3VsdFswXS50b1N0cmluZygpLCAiVGVzdCIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJPYmplY3QgMSBpcyBub3Qgc3RyaW5nIiwgcmVzdWx0WzFdLnRvU3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgICIgQDMgNCA2Iik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIk9iamVjdCAyIGlzIG5vdCBzdHJpbmciLCByZXN1bHRbMl0udG9TdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgIiAzICAgIik7CisgICAgICAgIH0gY2F0Y2ggKGphdmEudGV4dC5QYXJzZUV4Y2VwdGlvbiBwZSkgeworICAgICAgICAgICAgZmFpbCgiUGFyc2VFeGNlcHRpb24gaXMgdGhyb3duIGZvciBjb3JyZWN0IHN0cmluZyAiICsgc1RvUGFyc2UpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlc3VsdCA9IG1mLnBhcnNlKG51bGwpOworICAgICAgICAgICAgZmFpbCgiUGFyc2VFeGNlcHRpb24gaXMgbm90IHRocm93biBmb3IgbnVsbCAiICsgc1RvUGFyc2UpOworICAgICAgICB9IGNhdGNoIChqYXZhLnRleHQuUGFyc2VFeGNlcHRpb24gcGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdCNwYXJzZU9iamVjdChqYXZhLmxhbmcuU3RyaW5nLAorICAgICAqICAgICAgICBqYXZhLnRleHQuUGFyc2VQb3NpdGlvbikgVGVzdCBvZiBtZXRob2QKKyAgICAgKiAgICAgICAgamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQjcGFyc2VPYmplY3QoamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS50ZXh0LlBhcnNlUG9zaXRpb24pLiBDYXNlIDE6IFBhcnNpbmcgb2YgY29ycmVjdCBkYXRhIHN0cmluZy4KKyAgICAgKiAgICAgICAgQ2FzZSAyOiBQYXJzaW5nIG9mIHBhcnRpYWwgY29ycmVjdCBkYXRhIHN0cmluZy4gQ2FzZSAzOiBUcnkgdG8gdXNlCisgICAgICogICAgICAgIGFyZ3VtZW50IFBhcnNlUG9zaXRpb24gYXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BhcnNlT2JqZWN0TGphdmFfbGFuZ19TdHJpbmdMamF2YWphdmFfdGV4dF9QYXJzZVBvc2l0aW9uKCkgeworICAgICAgICBNZXNzYWdlRm9ybWF0IG1mID0gbmV3IE1lc3NhZ2VGb3JtYXQoInswLG51bWJlciwjLiMjfSwgezAsbnVtYmVyLCMuI30iKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGNhc2UgMTogVHJ5IHRvIHBhcnNlIGNvcnJlY3QgZGF0YSBzdHJpbmcuCisgICAgICAgICAgICBPYmplY3RbXSBvYmpzID0geyBuZXcgRG91YmxlKDMuMTQxNSkgfTsKKyAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSBtZi5mb3JtYXQob2Jqcyk7CisgICAgICAgICAgICAvLyByZXN1bHQgbm93IGVxdWFscyAiMy4xNCwgMy4xIgorICAgICAgICAgICAgT2JqZWN0W10gcmVzID0gbnVsbDsKKyAgICAgICAgICAgIFBhcnNlUG9zaXRpb24gcHAgPSBuZXcgUGFyc2VQb3NpdGlvbigwKTsKKyAgICAgICAgICAgIGludCBwYXJzZUluZGV4ID0gcHAuZ2V0SW5kZXgoKTsKKyAgICAgICAgICAgIHJlcyA9IChPYmplY3RbXSkgbWYucGFyc2VPYmplY3QocmVzdWx0LCBwcCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJQYXJzZSBvcGVyYXRpb24gcmV0dXJuIG51bGwiLCByZXMgIT0gbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJwYXJzZSBvcGVyYXRpb24gcmV0dXJuIGFycmF5IHdpdGggaW5jb3JyZWN0IGxlbmd0aCIsCisgICAgICAgICAgICAgICAgICAgIDEgPT0gcmVzLmxlbmd0aCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJQYXJzZUluZGV4IGlzIGluY29ycmVjdCIsIHBwLmdldEluZGV4KCkgIT0gcGFyc2VJbmRleCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXN1bHQgb2JqZWN0IGlzIGluY29ycmVjdCIsIG5ldyBEb3VibGUoMy4xKQorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKHJlc1swXSkpOworCisgICAgICAgICAgICAvLyBjYXNlIDI6IFRyeSB0byBwYXJzZSBwYXJ0aWFsbHkgY29ycmVjdCBkYXRhIHN0cmluZy4KKyAgICAgICAgICAgIHBwLnNldEluZGV4KDApOworICAgICAgICAgICAgY2hhcltdIGN1ciA9IHJlc3VsdC50b0NoYXJBcnJheSgpOworICAgICAgICAgICAgY3VyW2N1ci5sZW5ndGggLyAyXSA9ICdaJzsKKyAgICAgICAgICAgIFN0cmluZyBwYXJ0aWFsQ29ycmVjdCA9IG5ldyBTdHJpbmcoY3VyKTsKKyAgICAgICAgICAgIHJlcyA9IChPYmplY3RbXSkgbWYucGFyc2VPYmplY3QocGFydGlhbENvcnJlY3QsIHBwKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlBhcnNlIG9wZXJhdGlvbiByZXR1cm4gbnVsbCIsIHJlcyA9PSBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlBhcnNlSW5kZXggaXMgaW5jb3JyZWN0IiwgcHAuZ2V0SW5kZXgoKSA9PSAwKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlBhcnNlRXJyb3JJbmRleCBpcyBpbmNvcnJlY3QiLAorICAgICAgICAgICAgICAgICAgICBwcC5nZXRFcnJvckluZGV4KCkgPT0gY3VyLmxlbmd0aCAvIDIpOworCisgICAgICAgICAgICAvLyBjYXNlIDM6IFRyeSB0byB1c2UgYXJndW1lbnQgUGFyc2VQb3NpdGlvbiBhcyBudWxsLgorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBtZi5wYXJzZU9iamVjdChyZXN1bHQsIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9mb3JtYXRfT2JqZWN0KCkgeworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTE4NzUKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQoTG9jYWxlLkNBTkFEQSk7CisgICAgICAgIFRpbWVab25lLnNldERlZmF1bHQoVGltZVpvbmUuZ2V0VGltZVpvbmUoIlVUQyIpKTsKKyAgICAgICAgU3RyaW5nIHBhdCA9ICJ0ZXh0IGhlcmUgezAsZGF0ZSx5eXl5eXl5eXl9IGFuZCBoZXJlIjsKKyAgICAgICAgQ2FsZW5kYXIgYyA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7CisgICAgICAgIFN0cmluZyBldGFsb24gPSAidGV4dCBoZXJlIDAwMDAwIiArIGMuZ2V0KENhbGVuZGFyLllFQVIpICsgIiBhbmQgaGVyZSI7CisgICAgICAgIE1lc3NhZ2VGb3JtYXQgb2JqID0gbmV3IE1lc3NhZ2VGb3JtYXQocGF0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV0YWxvbiwgb2JqLmZvcm1hdChuZXcgT2JqZWN0W10geyBuZXcgRGF0ZSgpIH0pKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BhcnNlTGphdmFfbGFuZ19TdHJpbmdMamF2YV90ZXh0X1BhcnNlUG9zaXRpb24oKSB7CisgICAgICAgIFBhcnNlUG9zaXRpb24gcG9zID0gbmV3IFBhcnNlUG9zaXRpb24oMik7CisKKyAgICAgICAgTWVzc2FnZUZvcm1hdCBtZiA9IG5ldyBNZXNzYWdlRm9ybWF0KCJ7MH07IHswfTsgezB9Iik7CisgICAgICAgIFN0cmluZyBwYXJzZSA9ICJhOyBiOyBjIjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1mLnBhcnNlKHBhcnNlLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1mLnBhcnNlKG51bGwsIHBvcyk7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZE51bWJlckZvcm1hdEZpZWxkVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZE51bWJlckZvcm1hdEZpZWxkVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZjYTAyNzYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkTnVtYmVyRm9ybWF0RmllbGRUZXN0LmphdmEKQEAgLTAsMCArMSw4NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS50ZXh0OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW52YWxpZE9iamVjdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudGV4dC5OdW1iZXJGb3JtYXQ7CisKK3B1YmxpYyBjbGFzcyBPbGROdW1iZXJGb3JtYXRGaWVsZFRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICAvLyBwcm90ZWN0ZWQgY29uc3RydWN0b3IKKyAgICAgICAgU3RyaW5nIG5hbWUgPSAibmV3IG51bWJlciBmb3JtYXQiOworICAgICAgICBNeU51bWJlckZvcm1hdCBmaWVsZCA9IG5ldyBNeU51bWJlckZvcm1hdChuYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmaWVsZCBoYXMgd3JvbmcgbmFtZSIsIG5hbWUsIGZpZWxkLmdldE5hbWUoKSk7CisKKyAgICAgICAgZmllbGQgPSBuZXcgTXlOdW1iZXJGb3JtYXQobnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZmllbGQgaGFzIHdyb25nIG5hbWUiLCBudWxsLCBmaWVsZC5nZXROYW1lKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZFJlc29sdmUoKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICAvLyB0ZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdCByZWFkUmVzb2x2ZSgpCisKKyAgICAgICAgLy8gc2VlIHNlcmlhbGl6YXRpb24gc3RyZXNzIHRlc3RzOgorICAgICAgICAvLyBpbXBsZW1lbnRlZCBpbgorICAgICAgICAvLyBTZXJpYWxpemF0aW9uU3RyZXNzVGVzdDQudGVzdF93cml0ZU9iamVjdF9OdW1iZXJGb3JtYXRfRmllbGQoKQorICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZXMgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIE9iamVjdE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKGJ5dGVzKTsKKworICAgICAgICBNeU51bWJlckZvcm1hdCBmaWVsZDsKKworICAgICAgICBOdW1iZXJGb3JtYXQuRmllbGQgbmZpZWxkID0gTnVtYmVyRm9ybWF0LkZpZWxkLkNVUlJFTkNZOworCisgICAgICAgIGZpZWxkID0gbmV3IE15TnVtYmVyRm9ybWF0KG51bGwpOworCisgICAgICAgIG91dC53cml0ZU9iamVjdChuZmllbGQpOworICAgICAgICBvdXQud3JpdGVPYmplY3QoZmllbGQpOworCisgICAgICAgIE9iamVjdElucHV0U3RyZWFtIGluID0gbmV3IE9iamVjdElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcy50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIE51bWJlckZvcm1hdC5GaWVsZCBuZmllbGQyID0gKE51bWJlckZvcm1hdC5GaWVsZCkgaW4ucmVhZE9iamVjdCgpOworICAgICAgICBhc3NlcnRTYW1lKCJyZXNvbHZlZCBpbmNvcnJlY3RseSIsIG5maWVsZCwgbmZpZWxkMik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluLnJlYWRPYmplY3QoKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIEludmFsaWRPYmplY3RFeGNlcHRpb24gZm9yIHN1YmNsYXNzIGluc3RhbmNlIHdpdGggbnVsbCBuYW1lIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRPYmplY3RFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIE15TnVtYmVyRm9ybWF0IGV4dGVuZHMgTnVtYmVyRm9ybWF0LkZpZWxkIHsKKyAgICAgICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgICAgIHN0YXRpYyBib29sZWFuIGZsYWcgPSBmYWxzZTsKKworICAgICAgICBwcm90ZWN0ZWQgTXlOdW1iZXJGb3JtYXQoU3RyaW5nIGF0dHIpIHsKKyAgICAgICAgICAgIHN1cGVyKGF0dHIpOworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldE5hbWUoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGROdW1iZXJGb3JtYXRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkTnVtYmVyRm9ybWF0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY0ZmQ3Y2EKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkTnVtYmVyRm9ybWF0VGVzdC5qYXZhCkBAIC0wLDAgKzEsODQ1IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLnRleHQ7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5Ccm9rZW5UZXN0OworaW1wb3J0IGphdmEudGV4dC5DaG9pY2VGb3JtYXQ7CitpbXBvcnQgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXQ7CitpbXBvcnQgamF2YS50ZXh0LkZpZWxkUG9zaXRpb247CitpbXBvcnQgamF2YS50ZXh0Lk51bWJlckZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuUGFyc2VFeGNlcHRpb247CitpbXBvcnQgamF2YS50ZXh0LlBhcnNlUG9zaXRpb247CitpbXBvcnQgamF2YS51dGlsLkN1cnJlbmN5OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Mb2NhbGU7CisKK3B1YmxpYyBjbGFzcyBPbGROdW1iZXJGb3JtYXRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnRlZ2VySW5zdGFuY2VMamF2YV91dGlsX0xvY2FsZSgpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgIERlY2ltYWxGb3JtYXQgZm9ybWF0ID0gKERlY2ltYWxGb3JtYXQpIE51bWJlckZvcm1hdC5nZXRJbnRlZ2VySW5zdGFuY2UoTG9jYWxlLlVTKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIjLCMjMCIsIGZvcm1hdC50b1BhdHRlcm4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLTM2IiwgZm9ybWF0LmZvcm1hdCgtMzUuNzYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBMb25nKC0zNiksIGZvcm1hdC5wYXJzZSgiLTM2IikpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IExvbmcoLTM2KSwgZm9ybWF0LnBhcnNlT2JqZWN0KCItMzYiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBmb3JtYXQuZ2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKCkpOworICAgICAgICBhc3NlcnRUcnVlKGZvcm1hdC5pc1BhcnNlSW50ZWdlck9ubHkoKSk7CisKKyAgICAgICAgLy8gdHJ5IHdpdGggYSBsb2NhbGUgdGhhdCBoYXMgYSBkaWZmZXJlbnQgaW50ZWdlciBwYXR0ZXJuCisgICAgICAgIExvY2FsZSBjaExvY2FsZSA9IG5ldyBMb2NhbGUoImRlIiwgIkNIIik7CisgICAgICAgIGlmIChTdXBwb3J0X0xvY2FsZS5pc0xvY2FsZUF2YWlsYWJsZShjaExvY2FsZSkpIHsKKyAgICAgICAgICAgIGZvcm1hdCA9IChEZWNpbWFsRm9ybWF0KSBOdW1iZXJGb3JtYXQuZ2V0SW50ZWdlckluc3RhbmNlKGNoTG9jYWxlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiIywjIzAiLCBmb3JtYXQudG9QYXR0ZXJuKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCItMzYiLCBmb3JtYXQuZm9ybWF0KC0zNS43NikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBMb25nKC0zNiksIGZvcm1hdC5wYXJzZSgiLTM2IikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBMb25nKC0zNiksIGZvcm1hdC5wYXJzZU9iamVjdCgiLTM2IikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGZvcm1hdC5nZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGZvcm1hdC5pc1BhcnNlSW50ZWdlck9ubHkoKSk7CisgICAgICAgIH0KKyAgICAgICAgTG9jYWxlIGFyTG9jYWxlID0gbmV3IExvY2FsZSgiYXIiLCAiQUUiKTsKKyAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKGFyTG9jYWxlKSkgeworICAgICAgICAgICAgZm9ybWF0ID0gKERlY2ltYWxGb3JtYXQpIE51bWJlckZvcm1hdC5nZXRJbnRlZ2VySW5zdGFuY2UoYXJMb2NhbGUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCIjLCMjMDsjLCMjMC0iLCBmb3JtYXQudG9QYXR0ZXJuKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJcdTA2NjYtIiwgZm9ybWF0LmZvcm1hdCgtNikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBMb25nKC0zNiksIGZvcm1hdC5wYXJzZSgiMzYtIikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBMb25nKC0zNiksIGZvcm1hdC5wYXJzZU9iamVjdCgiMzYtIikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGZvcm1hdC5nZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGZvcm1hdC5pc1BhcnNlSW50ZWdlck9ubHkoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldE1heGltdW1JbnRlZ2VyRGlnaXRzKCkgeworICAgICAgICBOdW1iZXJGb3JtYXQgZm9ybWF0ID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCk7CisgICAgICAgIGZvcm1hdC5zZXRNYXhpbXVtSW50ZWdlckRpZ2l0cygyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXN1bHQ6IGNhc2UgMSIsICIyMyIsIGZvcm1hdC5mb3JtYXQoMTIzKSk7CisKKyAgICAgICAgZm9ybWF0LnNldE1heGltdW1JbnRlZ2VyRGlnaXRzKEludGVnZXIuTUlOX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXN1bHQ6IGNhc2UgMiIsICIwIiwgZm9ybWF0LmZvcm1hdCgxMjMpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEN1cnJlbmN5TGphdmFfdXRpbF9DdXJyZW5jeSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgc2V0Q3VycmVuY3koamF2YS51dGlsLkN1cnJlbmN5KQorICAgICAgICAvLyBhIHN1YmNsYXNzIHRoYXQgc3VwcG9ydHMgY3VycmVuY3kgZm9ybWF0dGluZworICAgICAgICBDdXJyZW5jeSBjdXJyQSA9IEN1cnJlbmN5LmdldEluc3RhbmNlKCJBUlMiKTsKKyAgICAgICAgTnVtYmVyRm9ybWF0IGZvcm1hdCA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZShuZXcgTG9jYWxlKCJodSIsICJIVSIpKTsKKyAgICAgICAgZm9ybWF0LnNldEN1cnJlbmN5KGN1cnJBKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGN1cnJlbmN5IiwgY3VyckEsIGZvcm1hdC5nZXRDdXJyZW5jeSgpKTsKKworICAgICAgICAvLyBhIHN1YmNsYXNzIHRoYXQgZG9lc24ndCBzdXBwb3J0IGN1cnJlbmN5IGZvcm1hdHRpbmcKKyAgICAgICAgQ2hvaWNlRm9ybWF0IGNmb3JtYXQgPSBuZXcgQ2hvaWNlRm9ybWF0KAorICAgICAgICAgICAgICAgICIwI0xlc3MgdGhhbiBvbmV8MSNvbmV8MTxCZXR3ZWVuIG9uZSBhbmQgdHdvfDI8R3JlYXRlciB0aGFuIHR3byIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgKChOdW1iZXJGb3JtYXQpIGNmb3JtYXQpLnNldEN1cnJlbmN5KGN1cnJBKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKS5zZXRDdXJyZW5jeShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTnVtYmVyRm9ybWF0LmdldEludGVnZXJJbnN0YW5jZSgpLnNldEN1cnJlbmN5KG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcGFyc2VPYmplY3RMamF2YV9sYW5nX1N0cmluZ0xqYXZhX3RleHRfUGFyc2VQb3NpdGlvbigpIHsKKyAgICAgICAgLy8gcmVncmVzc2lvbiB0ZXN0IGZvciBIQVJNT05ZLTEwMDMKKyAgICAgICAgYXNzZXJ0TnVsbChOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKS5wYXJzZU9iamVjdCgiMCIsCisgICAgICAgICAgICAgICAgbmV3IFBhcnNlUG9zaXRpb24oLTEpKSk7CisKKyAgICAgICAgcGFyc2VPYmplY3RUZXN0KE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpLCAiMTIzLjEyMyIsCisgICAgICAgICAgICAgICAgbmV3IFBhcnNlUG9zaXRpb24oMSksIG5ldyBEb3VibGUoMjMuMTIzKSwgNywgdHJ1ZSk7CisKKyAgICAgICAgcGFyc2VPYmplY3RUZXN0KE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpLCAiMTIzLjEyM2FiYzEyMyIsCisgICAgICAgICAgICAgICAgbmV3IFBhcnNlUG9zaXRpb24oMyksIG5ldyBEb3VibGUoMC4xMjMpLCA3LCB0cnVlKTsKKworICAgICAgICBpZiAoU3VwcG9ydF9Mb2NhbGUuaXNMb2NhbGVBdmFpbGFibGUoTG9jYWxlLkZSQU5DRSkpIHsKKyAgICAgICAgICAgIHBhcnNlT2JqZWN0VGVzdChOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoTG9jYWxlLkZSQU5DRSksCisgICAgICAgICAgICAgICAgImFzZDEyMywxMjNhYmMxMjMiLAorICAgICAgICAgICAgICAgIG5ldyBQYXJzZVBvc2l0aW9uKDMpLCBuZXcgRG91YmxlKDEyMy4xMjMpLCAxMCwgdHJ1ZSk7CisKKyAgICAgICAgICAgIHBhcnNlT2JqZWN0VGVzdChOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoTG9jYWxlLkZSQU5DRSksCisgICAgICAgICAgICAgICAgInRlc3QgdGVzdCIsCisgICAgICAgICAgICAgICAgbmV3IFBhcnNlUG9zaXRpb24oMCksIG51bGwsIDAsIGZhbHNlKTsKKyAgICAgICAgfQorCisgICAgICAgIHBhcnNlT2JqZWN0VGVzdChOdW1iZXJGb3JtYXQuZ2V0SW50ZWdlckluc3RhbmNlKCksCisgICAgICAgICAgICAgICAgImFzZDEyMy4xMjNhYmMxMjMiLAorICAgICAgICAgICAgICAgIG5ldyBQYXJzZVBvc2l0aW9uKDMpLCBuZXcgTG9uZygxMjMpLCA2LCB0cnVlKTsKKworICAgICAgICBwYXJzZU9iamVjdFRlc3QoTnVtYmVyRm9ybWF0LmdldE51bWJlckluc3RhbmNlKCksCisgICAgICAgICAgICAgICAgIiQtMTIzLDEyMy4xMjMjIiwKKyAgICAgICAgICAgICAgICBuZXcgUGFyc2VQb3NpdGlvbigxKSwgbmV3IERvdWJsZSgtMTIzMTIzLjEyMyksIDEzLCB0cnVlKTsKKyAgICAgICAgcGFyc2VPYmplY3RUZXN0KE51bWJlckZvcm1hdC5nZXROdW1iZXJJbnN0YW5jZSgpLAorICAgICAgICAgICAgICAgICIkLTEyMywxMjMuMTIzIyIsCisgICAgICAgICAgICAgICAgbmV3IFBhcnNlUG9zaXRpb24oMCksIG51bGwsIDAsIGZhbHNlKTsKKyAgICAgICAgcGFyc2VPYmplY3RUZXN0KE51bWJlckZvcm1hdC5nZXROdW1iZXJJbnN0YW5jZSgpLAorICAgICAgICAgICAgICAgICIkLTEyMywxMjMuMTIzIyIsCisgICAgICAgICAgICAgICAgbmV3IFBhcnNlUG9zaXRpb24oMTMpLCBudWxsLCAxMywgZmFsc2UpOworICAgICAgICBwYXJzZU9iamVjdFRlc3QoTnVtYmVyRm9ybWF0LmdldFBlcmNlbnRJbnN0YW5jZSgpLAorICAgICAgICAgICAgICAgICIlMjAuMTIzIyIsCisgICAgICAgICAgICAgICAgbmV3IFBhcnNlUG9zaXRpb24oMCksIG5ldyBEb3VibGUoMjAuMTIzKSwgMCwgZmFsc2UpOworICAgICAgICBwYXJzZU9iamVjdFRlc3QoTnVtYmVyRm9ybWF0LmdldFBlcmNlbnRJbnN0YW5jZSgpLAorICAgICAgICAgICAgICAgICIlLTIwMCwxMjMuMTIzIyIsCisgICAgICAgICAgICAgICAgbmV3IFBhcnNlUG9zaXRpb24oMCksIG51bGwsIDAsIGZhbHNlKTsKKworCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMTY4NQorICAgICAgICB0cnkgeworICAgICAgICAgICAgTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCkucGFyc2VPYmplY3QoInRlc3QiLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICB2b2lkIHBhcnNlT2JqZWN0VGVzdChOdW1iZXJGb3JtYXQgbmYsIFN0cmluZyBzb3Vyc2VTdHIsIFBhcnNlUG9zaXRpb24gcG9zaXRpb24sCisgICAgICAgICAgICBPYmplY3QgcmVzdWx0T2JqLCBpbnQgb3V0SW5kZXgsIGJvb2xlYW4gaXNTdWNjZXNzKSB7CisgICAgICAgIGludCBpbmRleEJlZm9yZSA9IHBvc2l0aW9uLmdldEluZGV4KCk7CisgICAgICAgIE9iamVjdCByZXN1bHQgPSBuZi5wYXJzZU9iamVjdChzb3Vyc2VTdHIsIHBvc2l0aW9uKTsKKyAgICAgICAgaWYoaXNTdWNjZXNzKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMocmVzdWx0T2JqLCByZXN1bHQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG91dEluZGV4LCBwb3NpdGlvbi5nZXRJbmRleCgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFzc2VydE51bGwocmVzdWx0KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpbmRleEJlZm9yZSwgcG9zaXRpb24uZ2V0SW5kZXgoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMob3V0SW5kZXgsIHBvc2l0aW9uLmdldEVycm9ySW5kZXgoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb25lKCkgeworCisgICAgICAgIGludCBtYXhfZGlnaXRzID0gMTAwOworICAgICAgICBOdW1iZXJGb3JtYXQgbmYxID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCk7CisgICAgICAgIG5mMS5zZXRNYXhpbXVtSW50ZWdlckRpZ2l0cyhtYXhfZGlnaXRzKTsKKworICAgICAgICBOdW1iZXJGb3JtYXQgbmYyID0gKE51bWJlckZvcm1hdCkgbmYxLmNsb25lKCk7CisgICAgICAgIE51bWJlckZvcm1hdCBuZjMgPSAoTnVtYmVyRm9ybWF0KSBuZjEuY2xvbmUoKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJDbG9ubmVkIG9iamVjdCBpcyBub3QgZXF1YWwgdG8gb2JqZWN0IiwgbmYyLmVxdWFscyhuZjEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVHdvIGNsb25uZWQgb2JqZWN0cyBhcmUgbm90IGVxdWFsIiwgbmYyLmVxdWFscyhuZjMpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJNYXggZGlnaXRzIHZhbHVlIGlzIGluY29ycmVjdCBmb3IgY2xvbm5lZCBvYmplY3QiLCBuZjIKKyAgICAgICAgICAgICAgICAuZ2V0TWF4aW11bUludGVnZXJEaWdpdHMoKSA9PSBtYXhfZGlnaXRzKTsKKworICAgICAgICBuZjEuc2V0TWF4aW11bUludGVnZXJEaWdpdHMoMTApOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJNYXggZGlnaXRzIHZhbHVlIGlzIGluY29ycmVjdCBmb3IgY2xvbm5lZCBvYmplY3QgYWZ0ZXIgY2hhbmdpbmcgdGhpcyB2YWx1ZSBmb3Igb2JqZWN0IiwKKyAgICAgICAgICAgICAgICBuZjIuZ2V0TWF4aW11bUludGVnZXJEaWdpdHMoKSA9PSBtYXhfZGlnaXRzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VxdWFscygpIHsKKworICAgICAgICBOdW1iZXJGb3JtYXQgbmYxID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCk7CisgICAgICAgIE51bWJlckZvcm1hdCBuZjIgPSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJPYmplY3RzIGFyZSBub3QgZXF1YWwiLCBuZjEuZXF1YWxzKG5mMikpOworICAgICAgICBhc3NlcnRUcnVlKCJUSGUgc2FtZSBPYmplY3RzIGFyZSBub3QgZXF1YWwiLCBuZjEuZXF1YWxzKG5mMSkpOworCisgICAgICAgIG5mMi5zZXRNYXhpbXVtSW50ZWdlckRpZ2l0cygxMDApOworICAgICAgICBhc3NlcnRGYWxzZSgiRGlmZmVyZW50IE51bWJlckZvcm1hdCBhcmUgZXF1YWwiLCBuZjEuZXF1YWxzKG5mMikpOworCisgICAgICAgIG5mMi5zZXRNYXhpbXVtSW50ZWdlckRpZ2l0cyhuZjEuZ2V0TWF4aW11bUludGVnZXJEaWdpdHMoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRIZSBzYW1lIE9iamVjdHMgYXJlIG5vdCBlcXVhbCIsIG5mMS5lcXVhbHMobmYyKSk7CisKKyAgICAgICAgbmYxID0gTnVtYmVyRm9ybWF0LmdldEludGVnZXJJbnN0YW5jZSgpOworICAgICAgICBuZjIgPSBOdW1iZXJGb3JtYXQuZ2V0SW50ZWdlckluc3RhbmNlKExvY2FsZS5DSElOQSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJEaWZmZXJlbnQgTnVtYmVyRm9ybWF0IGFyZSBlcXVhbCIsIG5mMS5lcXVhbHMobmYyKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoIk9iamVjdCBpcyBlcXVhbCBudWxsIiwgbmYxLmVxdWFscyhudWxsKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9mb3JtYXRMZG91YmxlKCkgeworICAgICAgICBOdW1iZXJGb3JtYXQgbmYxID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKExvY2FsZS5VUyk7CisKKyAgICAgICAgU3RyaW5nIG91dCA9IG5mMS5mb3JtYXQoMTIzNDU2Nzg5MC4wMTIzNDU2Nzg5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXN1bHQgZm9yIGRvdWJsZSA6ICIgKyBvdXQsICIxLDIzNCw1NjcsODkwLjAxMiIsCisgICAgICAgICAgICAgICAgb3V0LnRvU3RyaW5nKCkpOworCisgICAgICAgIG91dCA9IG5mMS5mb3JtYXQoLTEyMzQ1Njc4OTAuMDEyMzQ1Njc4OSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcmVzdWx0IGZvciBkb3VibGUgOiAiICsgb3V0LCAiLTEsMjM0LDU2Nyw4OTAuMDEyIiwKKyAgICAgICAgICAgICAgICBvdXQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgTG9jYWxlIGRlTG9jYWxlID0gbmV3IExvY2FsZSgiZGUiLCAiQ0giKTsKKyAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKGRlTG9jYWxlKSkgeworICAgICAgICAgICAgTnVtYmVyRm9ybWF0IG5mMiA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZShkZUxvY2FsZSk7CisgICAgICAgICAgICBvdXQgPSBuZjIuZm9ybWF0KC0xMjM0NTY3ODkwLjAxMjM0NTY3ODkpOworICAgICAgICAgICAgLy8gdXNlIGRlX0NIIGluc3RlYWQKKyAgICAgICAgICAgIC8vIGFzc2VydEVxdWFscygiV3JvbmcgcmVzdWx0IGZvciBkb3VibGUgOiAiICsgb3V0LCAiMSwyMzQsNTY3LDg5MC4wMTItIiwKKyAgICAgICAgICAgIC8vICAgICAgICAgb3V0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXN1bHQgZm9yIGRvdWJsZSA6ICIgKyBvdXQsICItMScyMzQnNTY3Jzg5MC4wMTIiLCBvdXQudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICBvdXQgPSBuZjEuZm9ybWF0KDEuMDAwMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcmVzdWx0IGZvciBmb3IgZG91YmxlOiAiICsgb3V0LCAiMSIsIG91dC50b1N0cmluZygpKTsKKworICAgICAgICBvdXQgPSBuZjEuZm9ybWF0KDUuMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcmVzdWx0IGZvciBmb3IgZG91YmxlOiAiICsgb3V0LCAiNSIsIG91dC50b1N0cmluZygpKTsKKyAgICAgICAgLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZm9ybWF0TGxvbmcoKSB7CisgICAgICAgIE51bWJlckZvcm1hdCBuZjEgPSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoTG9jYWxlLlVTKTsKKworICAgICAgICBTdHJpbmcgb3V0ID0gbmYxLmZvcm1hdChMb25nLk1BWF9WQUxVRSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcmVzdWx0IGZvciBkb3VibGUgOiAiICsgb3V0LAorICAgICAgICAgICAgICAgICI5LDIyMywzNzIsMDM2LDg1NCw3NzUsODA3Iiwgb3V0LnRvU3RyaW5nKCkpOworCisgICAgICAgIG91dCA9IG5mMS5mb3JtYXQoTG9uZy5NSU5fVkFMVUUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHJlc3VsdCBmb3IgZG91YmxlIDogIiArIG91dCwKKyAgICAgICAgICAgICAgICAiLTksMjIzLDM3MiwwMzYsODU0LDc3NSw4MDgiLCBvdXQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgTG9jYWxlIGRlTG9jYWxlID0gbmV3IExvY2FsZSgiZGUiLCAiQ0giKTsKKyAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKGRlTG9jYWxlKSkgeworICAgICAgICAgICAgTnVtYmVyRm9ybWF0IG5mMiA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZShkZUxvY2FsZSk7CisgICAgICAgICAgICBvdXQgPSBuZjIuZm9ybWF0KC0xMjM0NTY3ODkwKTsKKyAgICAgICAgICAgIC8vIHVzZSBkZV9DSCBpbnN0ZWFkCisgICAgICAgICAgICAvLyBhc3NlcnRFcXVhbHMoIldyb25nIHJlc3VsdCBmb3IgZG91YmxlIDogIiArIG91dCwgIi0xIDIzNCA1NjcgODkwIiwgb3V0CisgICAgICAgICAgICAvLyAgICAgICAgIC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcmVzdWx0IGZvciBkb3VibGUgOiAiICsgb3V0LCAiLTEnMjM0JzU2Nyc4OTAiLCBvdXQudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyB0aGUgTG9jYWxlIGRhdGEgb2YgaWN1IHVzZXMgXHVjMmEwCisgICAgICAgIG91dCA9IG5mMS5mb3JtYXQoMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcmVzdWx0IGZvciBmb3IgZG91YmxlOiAiICsgb3V0LCAiMSIsIG91dC50b1N0cmluZygpKTsKKworICAgICAgICBvdXQgPSBuZjEuZm9ybWF0KDApOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHJlc3VsdCBmb3IgZm9yIGRvdWJsZTogIiArIG91dCwgIjAiLCBvdXQudG9TdHJpbmcoKSk7CisgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEF2YWlsYWJsZUxvY2FsZXMoKSB7CisKKyAgICAgICAgTG9jYWxlW10gbCA9IE51bWJlckZvcm1hdC5nZXRBdmFpbGFibGVMb2NhbGVzKCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJyZXR1cm5lZCBMb2NhbGUgYXJyYXkgaXMgbnVsbCIsIGwgPT0gbnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoInJldHVybmVkIExvY2FsZSBsZW5ndGggPD0gMCIsIGwubGVuZ3RoID4gMCk7CisgICAgICAgIExvY2FsZVtdIHJlc2wgPSBMb2NhbGUuZ2V0QXZhaWxhYmxlTG9jYWxlcygpOworICAgICAgICBhc3NlcnRUcnVlKCJyZXR1cm5lZCBMb2NhbGUgYXJyYXlzIGFyZSBkaWZmZXJlbnQiLAorICAgICAgICAgICAgICAgIGwubGVuZ3RoID09IHJlc2wubGVuZ3RoKTsKKyAgICAgICAgYm9vbGVhbiBpc1VTID0gZmFsc2U7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVzbC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50cyAiICsgaSArICIgYXJlIG5vdCBlcXVhbDogIiwgcmVzbFtpXSwgbFtpXSk7CisgICAgICAgICAgICBpZiAobFtpXS5lcXVhbHMoTG9jYWxlLlVTKSkKKyAgICAgICAgICAgICAgICBpc1VTID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJ0aGVyZSBpcyBubyBMb2NhbGUuVVMiLCBpc1VTKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEN1cnJlbmN5SW5zdGFuY2UoKSB7CisKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQoTG9jYWxlLlVTKTsKKyAgICAgICAgTnVtYmVyRm9ybWF0IGZvcm1hdCA9IE51bWJlckZvcm1hdC5nZXRDdXJyZW5jeUluc3RhbmNlKCk7CisKKyAgICAgICAgYXNzZXJ0Tm90U2FtZSgiSW5zdGFuY2UgaXMgbnVsbCIsIG51bGwsIGZvcm1hdCk7CisgICAgICAgIGFzc2VydFRydWUoIk9iamVjdCBpcyBub3QgaW5zdGFuY2Ugb2YgTnVtYmVyRm9ybWF0IiwKKyAgICAgICAgICAgICAgICBmb3JtYXQgaW5zdGFuY2VvZiBOdW1iZXJGb3JtYXQpOworCisgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAiVGVzdDE6IE51bWJlckZvcm1hdC5nZXRDdXJyZW5jeUluc3RhbmNlKCkuZm9ybWF0KDM1Ljc2KSByZXR1cm5lZCB3cm9uZyB2YWx1ZSIsCisgICAgICAgICAgICAgICAgIiQzNS43NiIsIGZvcm1hdC5mb3JtYXQoMzUuNzYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICJUZXN0MjogTnVtYmVyRm9ybWF0LmdldEN1cnJlbmN5SW5zdGFuY2UoKS5mb3JtYXQoMTIzNDU2Ljc4OSkgcmV0dXJuZWQgd3JvbmcgdmFsdWUiLAorICAgICAgICAgICAgICAgICIkMTIzLDQ1Ni43OSIsIGZvcm1hdC5mb3JtYXQoMTIzNDU2Ljc4OSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgIlRlc3QzOiBOdW1iZXJGb3JtYXQuZ2V0Q3VycmVuY3lJbnN0YW5jZSgpLmZvcm1hdCgwLjEpIHJldHVybmVkIHdyb25nIHZhbHVlIiwKKyAgICAgICAgICAgICAgICAiJDAuMTAiLCBmb3JtYXQuZm9ybWF0KDAuMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgIlRlc3Q0OiBOdW1iZXJGb3JtYXQuZ2V0Q3VycmVuY3lJbnN0YW5jZSgpLmZvcm1hdCgwLjk5OSkgcmV0dXJuZWQgd3JvbmcgdmFsdWUiLAorICAgICAgICAgICAgICAgICIkMS4wMCIsIGZvcm1hdC5mb3JtYXQoMC45OTkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEN1cnJlbmN5SW5zdGFuY2VMamF2YV91dGlsX0xvY2FsZSgpIHsKKyAgICAgICAgTG9jYWxlIHVzTG9jYWxlID0gTG9jYWxlLlVTOworICAgICAgICBOdW1iZXJGb3JtYXQgZm9ybWF0ID0gTnVtYmVyRm9ybWF0LmdldEN1cnJlbmN5SW5zdGFuY2UodXNMb2NhbGUpOworCisgICAgICAgIGFzc2VydE5vdFNhbWUoIkluc3RhbmNlIGlzIG51bGwiLCBudWxsLCBmb3JtYXQpOworICAgICAgICBhc3NlcnRUcnVlKGZvcm1hdCBpbnN0YW5jZW9mIE51bWJlckZvcm1hdCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIkMzUuNzYiLCBmb3JtYXQuZm9ybWF0KDM1Ljc2KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiJDEyMyw0NTYuNzkiLCBmb3JtYXQuZm9ybWF0KDEyMzQ1Ni43ODkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIkMC4xMCIsIGZvcm1hdC5mb3JtYXQoMC4xKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiJDEuMDAiLCBmb3JtYXQuZm9ybWF0KDAuOTk5KSk7CisKKyAgICAgICAgTG9jYWxlIGF0TG9jYWxlID0gbmV3IExvY2FsZSgiZGUiLCAiQVQiKTsKKyAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKGF0TG9jYWxlKSkgeworICAgICAgICAgICAgZm9ybWF0ID0gTnVtYmVyRm9ybWF0LmdldEN1cnJlbmN5SW5zdGFuY2UoYXRMb2NhbGUpOworICAgICAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkOiBJQ1UgdXNlcyBub24tYnJlYWtpbmcgc3BhY2UgYWZ0ZXIgdGhlIGV1cm8gc2lnbjsgdGhlIFJJIHVzZXMgJyAnLgorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJcdTIwYWNcdTAwYTAzNSw3NiIsIGZvcm1hdC5mb3JtYXQoMzUuNzYpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiXHUyMGFjXHUwMGEwMTIzLjQ1Niw3OSIsIGZvcm1hdC5mb3JtYXQoMTIzNDU2Ljc4OSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJcdTIwYWNcdTAwYTAwLDEwIiwgZm9ybWF0LmZvcm1hdCgwLjEpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiXHUyMGFjXHUwMGEwMSwwMCIsIGZvcm1hdC5mb3JtYXQoMC45OTkpKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTnVtYmVyRm9ybWF0LmdldEN1cnJlbmN5SW5zdGFuY2UobnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZSgpIHsKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQoTG9jYWxlLlVTKTsKKyAgICAgICAgTnVtYmVyRm9ybWF0IGZvcm1hdCA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpOworCisgICAgICAgIGFzc2VydE5vdFNhbWUoIkluc3RhbmNlIGlzIG51bGwiLCBudWxsLCBmb3JtYXQpOworICAgICAgICBhc3NlcnRUcnVlKCJPYmplY3QgaXMgbm90IGluc3RhbmNlIG9mIE51bWJlckZvcm1hdCIsCisgICAgICAgICAgICAgICAgZm9ybWF0IGluc3RhbmNlb2YgTnVtYmVyRm9ybWF0KTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgIlRlc3QxOiBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKS5mb3JtYXQoMTIzNDU2Nzg5MC4wOTg3NjU0MzIxKSByZXR1cm5lZCB3cm9uZyB2YWx1ZSIsCisgICAgICAgICAgICAgICAgIjEsMjM0LDU2Nyw4OTAuMDk5IiwgZm9ybWF0LmZvcm1hdCgxMjM0NTY3ODkwLjA5ODc2NTQzMjEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICJUZXN0MjogKChEZWNpbWFsRm9ybWF0KSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKSkudG9QYXR0ZXJuIHJldHVybmVkIHdyb25nIHZhbHVlIiwKKyAgICAgICAgICAgICAgICAiIywjIzAuIyMjIiwgKChEZWNpbWFsRm9ybWF0KSBmb3JtYXQpLnRvUGF0dGVybigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICJUZXN0MzogTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCkuZm9ybWF0KDEyMzQ1Njc4OSkgcmV0dXJuZWQgd3JvbmcgdmFsdWUiLAorICAgICAgICAgICAgICAgICIxMjMsNDU2LDc4OSIsIGZvcm1hdC5mb3JtYXQoMTIzNDU2Nzg5KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX3V0aWxfTG9jYWxlKCkgeworICAgICAgICBMb2NhbGUgdGVzdExvY2FsZSA9IG5ldyBMb2NhbGUoImRlIiwgIkNIIik7CisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KExvY2FsZS5VUyk7CisgICAgICAgIGlmIChTdXBwb3J0X0xvY2FsZS5pc0xvY2FsZUF2YWlsYWJsZSh0ZXN0TG9jYWxlKSkgeworICAgICAgICAgICAgTnVtYmVyRm9ybWF0IGZvcm1hdCA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSh0ZXN0TG9jYWxlKTsKKworICAgICAgICAgICAgYXNzZXJ0Tm90U2FtZShudWxsLCBmb3JtYXQpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShmb3JtYXQgaW5zdGFuY2VvZiBOdW1iZXJGb3JtYXQpOworCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIjEnMjM0JzU2Nyc4OTAuMDk5IiwgZm9ybWF0LmZvcm1hdCgxMjM0NTY3ODkwLjA5ODc2NTQzMjEpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiIywjIzAuIyMjIiwgKChEZWNpbWFsRm9ybWF0KSBmb3JtYXQpLnRvUGF0dGVybigpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiMTIzJzQ1Nic3ODkiLCBmb3JtYXQuZm9ybWF0KDEyMzQ1Njc4OSkpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TnVtYmVySW5zdGFuY2UoKSB7CisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KExvY2FsZS5VUyk7CisgICAgICAgIE51bWJlckZvcm1hdCBmb3JtYXQgPSBOdW1iZXJGb3JtYXQuZ2V0TnVtYmVySW5zdGFuY2UoKTsKKworICAgICAgICBhc3NlcnROb3RTYW1lKCJJbnN0YW5jZSBpcyBudWxsIiwgbnVsbCwgZm9ybWF0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiT2JqZWN0IGlzIG5vdCBpbnN0YW5jZSBvZiBOdW1iZXJGb3JtYXQiLAorICAgICAgICAgICAgICAgIGZvcm1hdCBpbnN0YW5jZW9mIE51bWJlckZvcm1hdCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICJUZXN0MTogTnVtYmVyRm9ybWF0LmdldE51bWJlckluc3RhbmNlKCkuZm9ybWF0KDEyMzQ1Njc4OTAuMDk4NzY1NDMyMSkgcmV0dXJuZWQgd3JvbmcgdmFsdWUiLAorICAgICAgICAgICAgICAgICIxLDIzNCw1NjcsODkwLjA5OSIsIGZvcm1hdC5mb3JtYXQoMTIzNDU2Nzg5MC4wOTg3NjU0MzIxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAiVGVzdDI6ICgoRGVjaW1hbEZvcm1hdCkgTnVtYmVyRm9ybWF0LmdldE51bWJlckluc3RhbmNlKCkpLnRvUGF0dGVybiByZXR1cm5lZCB3cm9uZyB2YWx1ZSIsCisgICAgICAgICAgICAgICAgIiMsIyMwLiMjIyIsICgoRGVjaW1hbEZvcm1hdCkgZm9ybWF0KS50b1BhdHRlcm4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAiVGVzdDM6IE51bWJlckZvcm1hdC5nZXROdW1iZXJJbnN0YW5jZSgpLmZvcm1hdCgxMjM0NTY3ODkpIHJldHVybmVkIHdyb25nIHZhbHVlIiwKKyAgICAgICAgICAgICAgICAiMTIzLDQ1Niw3ODkiLCBmb3JtYXQuZm9ybWF0KDEyMzQ1Njc4OSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TnVtYmVySW5zdGFuY2VMamF2YV91dGlsX0xvY2FsZSgpIHsKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQoTG9jYWxlLlVTKTsKKyAgICAgICAgTG9jYWxlIGRlTG9jYWxlID0gbmV3IExvY2FsZSgiZGUiLCAiQ0giKTsKKyAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKGRlTG9jYWxlKSkgeworICAgICAgICAgICAgTnVtYmVyRm9ybWF0IGZvcm1hdCA9IE51bWJlckZvcm1hdC5nZXROdW1iZXJJbnN0YW5jZShkZUxvY2FsZSk7CisgICAgICAgICAgICBhc3NlcnROb3RTYW1lKCJJbnN0YW5jZSBpcyBudWxsIiwgbnVsbCwgZm9ybWF0KTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIk9iamVjdCBpcyBub3QgaW5zdGFuY2Ugb2YgTnVtYmVyRm9ybWF0IiwgZm9ybWF0IGluc3RhbmNlb2YgTnVtYmVyRm9ybWF0KTsKKworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCItMScyMzQnNTY3Jzg5MC4wOTkiLCBmb3JtYXQuZm9ybWF0KC0xMjM0NTY3ODkwLjA5ODc2NTQzMjEpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiIywjIzAuIyMjIiwgKChEZWNpbWFsRm9ybWF0KSBmb3JtYXQpLnRvUGF0dGVybigpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiMTIzJzQ1Nic3ODkiLCBmb3JtYXQuZm9ybWF0KDEyMzQ1Njc4OSkpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UGVyY2VudEluc3RhbmNlKCkgeworICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChMb2NhbGUuVVMpOworICAgICAgICBOdW1iZXJGb3JtYXQgZm9ybWF0ID0gTnVtYmVyRm9ybWF0LmdldFBlcmNlbnRJbnN0YW5jZSgpOworCisgICAgICAgIGFzc2VydE5vdFNhbWUoIkluc3RhbmNlIGlzIG51bGwiLCBudWxsLCBmb3JtYXQpOworICAgICAgICBhc3NlcnRUcnVlKCJPYmplY3QgaXMgbm90IGluc3RhbmNlIG9mIE51bWJlckZvcm1hdCIsCisgICAgICAgICAgICAgICAgZm9ybWF0IGluc3RhbmNlb2YgTnVtYmVyRm9ybWF0KTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgIlRlc3QxOiBOdW1iZXJGb3JtYXQuZ2V0UGVyY2VudEluc3RhbmNlKCkuZm9ybWF0KDEyMzQ1Njc4OTAuMDk4NzY1NDMyMSkgcmV0dXJuZWQgd3JvbmcgdmFsdWUiLAorICAgICAgICAgICAgICAgICIxMjMsNDU2LDc4OSwwMTAlIiwgZm9ybWF0LmZvcm1hdCgxMjM0NTY3ODkwLjA5ODc2NTQzMjEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICJUZXN0MjogKChEZWNpbWFsRm9ybWF0KSBOdW1iZXJGb3JtYXQuZ2V0UGVyY2VudEluc3RhbmNlKCkpLnRvUGF0dGVybiByZXR1cm5lZCB3cm9uZyB2YWx1ZSIsCisgICAgICAgICAgICAgICAgIiMsIyMwJSIsICgoRGVjaW1hbEZvcm1hdCkgZm9ybWF0KS50b1BhdHRlcm4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAiVGVzdDM6IE51bWJlckZvcm1hdC5nZXRQZXJjZW50SW5zdGFuY2UoKS5mb3JtYXQoMTIzNDU2Nzg5KSByZXR1cm5lZCB3cm9uZyB2YWx1ZSIsCisgICAgICAgICAgICAgICAgIjEyLDM0NSw2NzgsOTAwJSIsIGZvcm1hdC5mb3JtYXQoMTIzNDU2Nzg5KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQZXJjZW50SW5zdGFuY2VMamF2YV91dGlsX0xvY2FsZSgpIHsKKyAgICAgICAgTG9jYWxlIGNzTG9jYWxlID0gbmV3IExvY2FsZSgiY3MiLCAiQ1oiKTsKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQoTG9jYWxlLlVTKTsKKyAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKGNzTG9jYWxlKSkgeworICAgICAgICAgICAgTnVtYmVyRm9ybWF0IGZvcm1hdCA9IE51bWJlckZvcm1hdC5nZXRQZXJjZW50SW5zdGFuY2UoY3NMb2NhbGUpOworCisgICAgICAgICAgICBhc3NlcnROb3RTYW1lKCJJbnN0YW5jZSBpcyBudWxsIiwgbnVsbCwgZm9ybWF0KTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIk9iamVjdCBpcyBub3QgaW5zdGFuY2Ugb2YgTnVtYmVyRm9ybWF0IiwgZm9ybWF0IGluc3RhbmNlb2YgTnVtYmVyRm9ybWF0KTsKKworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMjNcdTAwYTA0NTZcdTAwYTA3ODlcdTAwYTAwMTBcdTAwYTAlIiwgZm9ybWF0LmZvcm1hdCgxMjM0NTY3ODkwLjA5ODc2NTQzMjEpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiIywjIzBcdTAwYTAlIiwgKChEZWNpbWFsRm9ybWF0KSBmb3JtYXQpLnRvUGF0dGVybigpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiMTJcdTAwYTAzNDVcdTAwYTA2NzhcdTAwYTA5MDBcdTAwYTAlIiwgZm9ybWF0LmZvcm1hdCgxMjM0NTY3ODkpKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKG51bGwpOworICAgICAgICAgICAgZmFpbCgiamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1heGltdW1GcmFjdGlvbkRpZ2l0cygpIHsKKyAgICAgICAgTnVtYmVyRm9ybWF0IG5mMSA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpOworCisgICAgICAgIG5mMS5zZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICBpbnQgcmVzdWx0ID0gbmYxLmdldE1heGltdW1GcmFjdGlvbkRpZ2l0cygpOworICAgICAgICBhc3NlcnRUcnVlKCJnZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMgcmV0dXJucyAiICsgcmVzdWx0CisgICAgICAgICAgICAgICAgKyAiIGluc3RlYWQgb2Y6ICIgKyBJbnRlZ2VyLk1BWF9WQUxVRSwKKyAgICAgICAgICAgICAgICByZXN1bHQgPT0gSW50ZWdlci5NQVhfVkFMVUUpOworCisgICAgICAgIG5mMS5zZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoMCk7CisgICAgICAgIHJlc3VsdCA9IG5mMS5nZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzIHJldHVybnMgIiArIHJlc3VsdAorICAgICAgICAgICAgICAgICsgIiBpbnN0ZWFkIG9mIDAiLCByZXN1bHQgPT0gMCk7CisKKyAgICAgICAgbmYxLnNldE1pbmltdW1GcmFjdGlvbkRpZ2l0cyhJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIHJlc3VsdCA9IG5mMS5nZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzIHJldHVybnMgIiArIHJlc3VsdAorICAgICAgICAgICAgICAgICsgIiBpbnN0ZWFkIG9mIEludGVnZXIuTUFYX1ZBTFVFIiwgcmVzdWx0ID09IEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1pbmltdW1GcmFjdGlvbkRpZ2l0cygpIHsKKyAgICAgICAgTnVtYmVyRm9ybWF0IG5mMSA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpOworICAgICAgICBuZjEuc2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgaW50IHJlc3VsdCA9IG5mMS5nZXRNaW5pbXVtRnJhY3Rpb25EaWdpdHMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWluaW11bUZyYWN0aW9uRGlnaXRzIHJldHVybnMgIiArIHJlc3VsdAorICAgICAgICAgICAgICAgICsgIiBpbnN0ZWFkIG9mOiAiICsgSW50ZWdlci5NQVhfVkFMVUUsCisgICAgICAgICAgICAgICAgcmVzdWx0ID09IEludGVnZXIuTUFYX1ZBTFVFKTsKKworICAgICAgICBuZjEuc2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKDApOworICAgICAgICByZXN1bHQgPSBuZjEuZ2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKCk7CisgICAgICAgIGFzc2VydFRydWUoImdldE1pbmltdW1GcmFjdGlvbkRpZ2l0cyByZXR1cm5zICIgKyByZXN1bHQKKyAgICAgICAgICAgICAgICArICIgaW5zdGVhZCBvZiAwIiwgcmVzdWx0ID09IDApOworCisgICAgICAgIG5mMS5zZXRNaW5pbXVtRnJhY3Rpb25EaWdpdHMoNTIpOworICAgICAgICByZXN1bHQgPSBuZjEuZ2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKCk7CisgICAgICAgIGFzc2VydFRydWUoImdldE1pbmltdW1GcmFjdGlvbkRpZ2l0cyByZXR1cm5zICIgKyByZXN1bHQKKyAgICAgICAgICAgICAgICArICIgaW5zdGVhZCBvZiA1MiIsIHJlc3VsdCA9PSA1Mik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRNYXhpbXVtSW50ZWdlckRpZ2l0cygpIHsKKyAgICAgICAgTnVtYmVyRm9ybWF0IG5mMSA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpOworICAgICAgICBuZjEuc2V0TWF4aW11bUludGVnZXJEaWdpdHMoSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICBpbnQgcmVzdWx0ID0gbmYxLmdldE1heGltdW1JbnRlZ2VyRGlnaXRzKCk7CisgICAgICAgIGFzc2VydFRydWUoImdldE1heGltdW1JbnRlZ2VyRGlnaXRzIHJldHVybnMgIiArIHJlc3VsdAorICAgICAgICAgICAgICAgICsgIiBpbnN0ZWFkIG9mOiAiICsgSW50ZWdlci5NQVhfVkFMVUUsCisgICAgICAgICAgICAgICAgcmVzdWx0ID09IEludGVnZXIuTUFYX1ZBTFVFKTsKKworICAgICAgICBuZjEuc2V0TWF4aW11bUludGVnZXJEaWdpdHMoMCk7CisgICAgICAgIHJlc3VsdCA9IG5mMS5nZXRNYXhpbXVtSW50ZWdlckRpZ2l0cygpOworICAgICAgICBhc3NlcnRUcnVlKCJnZXRNYXhpbXVtSW50ZWdlckRpZ2l0cyByZXR1cm5zICIgKyByZXN1bHQKKyAgICAgICAgICAgICAgICArICIgaW5zdGVhZCBvZiAwIiwgcmVzdWx0ID09IDApOworCisgICAgICAgIG5mMS5zZXRNaW5pbXVtSW50ZWdlckRpZ2l0cyhJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIHJlc3VsdCA9IG5mMS5nZXRNYXhpbXVtSW50ZWdlckRpZ2l0cygpOworICAgICAgICBhc3NlcnRUcnVlKCJnZXRNYXhpbXVtSW50ZWdlcmlnaXRzIHJldHVybnMgIiArIHJlc3VsdAorICAgICAgICAgICAgICAgICsgIiBpbnN0ZWFkIG9mIEludGVnZXIuTUFYX1ZBTFVFIiwgcmVzdWx0ID09IEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1pbmltdW1JbnRlZ2VybkRpZ2l0cygpIHsKKyAgICAgICAgTnVtYmVyRm9ybWF0IG5mMSA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpOworICAgICAgICBuZjEuc2V0TWluaW11bUludGVnZXJEaWdpdHMoSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICBpbnQgcmVzdWx0ID0gbmYxLmdldE1pbmltdW1JbnRlZ2VyRGlnaXRzKCk7CisgICAgICAgIGFzc2VydFRydWUoImdldE1pbmltdW1JbnRlZ2VyRGlnaXRzIHJldHVybnMgIiArIHJlc3VsdAorICAgICAgICAgICAgICAgICsgIiBpbnN0ZWFkIG9mOiAiICsgSW50ZWdlci5NQVhfVkFMVUUsCisgICAgICAgICAgICAgICAgcmVzdWx0ID09IEludGVnZXIuTUFYX1ZBTFVFKTsKKworICAgICAgICBuZjEuc2V0TWF4aW11bUludGVnZXJEaWdpdHMoMCk7CisgICAgICAgIHJlc3VsdCA9IG5mMS5nZXRNaW5pbXVtSW50ZWdlckRpZ2l0cygpOworICAgICAgICBhc3NlcnRUcnVlKCJnZXRNaW5pbXVtSW50ZWdlckRpZ2l0cyByZXR1cm5zICIgKyByZXN1bHQKKyAgICAgICAgICAgICAgICArICIgaW5zdGVhZCBvZiAwIiwgcmVzdWx0ID09IDApOworCisgICAgICAgIG5mMS5zZXRNaW5pbXVtSW50ZWdlckRpZ2l0cygweDEyMDM0KTsKKyAgICAgICAgcmVzdWx0ID0gbmYxLmdldE1pbmltdW1JbnRlZ2VyRGlnaXRzKCk7CisgICAgICAgIGFzc2VydFRydWUoImdldE1pbmltdW1JbnRlZ2VyRGlnaXRzIHJldHVybnMgIiArIHJlc3VsdAorICAgICAgICAgICAgICAgICsgIiBpbnN0ZWFkIG9mIDUxNDgiLCByZXN1bHQgPT0gNzM3ODApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGFzaENvZGUoKSB7CisKKyAgICAgICAgTnVtYmVyRm9ybWF0IG5mMSA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpOworICAgICAgICBOdW1iZXJGb3JtYXQgbmYxMSA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpOworICAgICAgICBOdW1iZXJGb3JtYXQgbmYyID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKExvY2FsZS5VUyk7CisgICAgICAgIE51bWJlckZvcm1hdCBuZjMgPSBOdW1iZXJGb3JtYXQuZ2V0UGVyY2VudEluc3RhbmNlKCk7CisgICAgICAgIE51bWJlckZvcm1hdCBuZjQgPSBOdW1iZXJGb3JtYXQuZ2V0Q3VycmVuY3lJbnN0YW5jZSgpOworICAgICAgICBOdW1iZXJGb3JtYXQgbmY1ID0gTnVtYmVyRm9ybWF0CisgICAgICAgICAgICAgICAgLmdldE51bWJlckluc3RhbmNlKG5ldyBMb2NhbGUoIm1rIiwgIk1LIikpOworICAgICAgICBOdW1iZXJGb3JtYXQgbmY2ID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKExvY2FsZS5VUyk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSGFzaCBjb2RlcyBhcmUgbm90IGVxdWFsOiBjYXNlIDEiLCBuZjEuaGFzaENvZGUoKSA9PSBuZjIKKyAgICAgICAgICAgICAgICAuaGFzaENvZGUoKSk7CisgICAgICAgIGFzc2VydFRydWUoIkhhc2ggY29kZXMgYXJlIG5vdCBlcXVhbDogY2FzZSAyIiwgbmYxLmhhc2hDb2RlKCkgPT0gbmYxMQorICAgICAgICAgICAgICAgIC5oYXNoQ29kZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSGFzaCBjb2RlcyBhcmUgbm90IGVxdWFsOiBjYXNlIDMiLCBuZjEuaGFzaENvZGUoKSA9PSBuZjMKKyAgICAgICAgICAgICAgICAuaGFzaENvZGUoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJIYXNoIGNvZGVzIGFyZSBlcXVhbDogY2FzZSA0IiwgbmYzLmhhc2hDb2RlKCkgPT0gbmY0CisgICAgICAgICAgICAgICAgLmhhc2hDb2RlKCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiSGFzaCBjb2RlcyBhcmUgZXF1YWw6IGNhc2UgNSIsIG5mNC5oYXNoQ29kZSgpID09IG5mNQorICAgICAgICAgICAgICAgIC5oYXNoQ29kZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSGFzaCBjb2RlcyBhcmUgbm90IGVxdWFsOiBjYXNlIDYiLCBuZjUuaGFzaENvZGUoKSA9PSBuZjYKKyAgICAgICAgICAgICAgICAuaGFzaENvZGUoKSk7CisKKyAgICAgICAgbmYxLnNldE1heGltdW1GcmFjdGlvbkRpZ2l0cygwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSGFzaCBjb2RlcyBhcmUgbm90IGVxdWFsOiBjYXNlIDciLCBuZjEuaGFzaENvZGUoKSA9PSBuZjExCisgICAgICAgICAgICAgICAgLmhhc2hDb2RlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNHcm91cGluZ1VzZWQoKSB7CisgICAgICAgIE51bWJlckZvcm1hdCBuZjEgPSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZ3JvdXBpbmcgaXMgbm90IHVzZWQgZm9yIE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSIsIG5mMQorICAgICAgICAgICAgICAgIC5pc0dyb3VwaW5nVXNlZCgpKTsKKworICAgICAgICBuZjEuc2V0R3JvdXBpbmdVc2VkKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgICAgICAgImdyb3VwaW5nIGlzIHVzZWQgZm9yIE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSBhZnRlciBzZXR0aW5nIGZhbHNlIiwKKyAgICAgICAgICAgICAgICBuZjEuaXNHcm91cGluZ1VzZWQoKSk7CisKKyAgICAgICAgbmYxLnNldEdyb3VwaW5nVXNlZCh0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiZ3JvdXBpbmcgaXMgbm90IHVzZWQgZm9yIE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSBhZnRlciBzZXR0aW5nIHRydWUiLAorICAgICAgICAgICAgICAgIG5mMS5pc0dyb3VwaW5nVXNlZCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEdyb3VwaW5nVXNlZCgpIHsKKyAgICAgICAgTnVtYmVyRm9ybWF0IG5mMSA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZShMb2NhbGUuVVMpOworICAgICAgICBuZjEuc2V0R3JvdXBpbmdVc2VkKGZhbHNlKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoImdyb3VwaW5nIGlzIHVzZWQgZm9yIDEyMzQ1Njc4OTAuMSIsICIxMjM0NTY3ODkwLjEiLAorICAgICAgICAgICAgICAgIG5mMS5mb3JtYXQoMTIzNDU2Nzg5MC4xKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJncm91cGluZyBpcyB1c2VkIGZvciAtMTIzNDU2Nzg5MC4xIiwgIi0xMjM0NTY3ODkwLjEiLAorICAgICAgICAgICAgICAgIG5mMS5mb3JtYXQoLTEyMzQ1Njc4OTAuMSkpOworCisgICAgICAgIG5mMS5zZXRHcm91cGluZ1VzZWQoZmFsc2UpOworCisgICAgICAgIGFzc2VydEVxdWFscygiZ3JvdXBpbmcgaXMgdXNlZCBmb3IgMTIzNDU2Nzg5MC4xIiwgIjEyMzQ1Njc4OTAuMSIsCisgICAgICAgICAgICAgICAgbmYxLmZvcm1hdCgxMjM0NTY3ODkwLjEpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoImdyb3VwaW5nIGlzIHVzZWQgZm9yIC0xMjM0NTY3ODkwLjEiLCAiLTEyMzQ1Njc4OTAuMSIsCisgICAgICAgICAgICAgICAgbmYxLmZvcm1hdCgtMTIzNDU2Nzg5MC4xKSk7CisKKyAgICAgICAgbmYxLnNldEdyb3VwaW5nVXNlZCh0cnVlKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoImdyb3VwaW5nIGlzIG5vdCB1c2VkIGZvciAxMjM0NTY3ODkwLjEiLAorICAgICAgICAgICAgICAgICIxLDIzNCw1NjcsODkwLjEiLCBuZjEuZm9ybWF0KDEyMzQ1Njc4OTAuMSkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiZ3JvdXBpbmcgaXMgbm90IHVzZWQgZm9yIC0xMjM0NTY3ODkwLjEiLAorICAgICAgICAgICAgICAgICItMSwyMzQsNTY3LDg5MC4xIiwgbmYxLmZvcm1hdCgtMTIzNDU2Nzg5MC4xKSk7CisKKyAgICAgICAgTG9jYWxlIGNzTG9jYWxlID0gbmV3IExvY2FsZSgiY3MiLCAiQ1oiKTsKKyAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKGNzTG9jYWxlKSkgeworICAgICAgICAgICAgTnVtYmVyRm9ybWF0IG5mMiA9IE51bWJlckZvcm1hdC5nZXRQZXJjZW50SW5zdGFuY2UoY3NMb2NhbGUpOworICAgICAgICAgICAgbmYyLnNldEdyb3VwaW5nVXNlZChmYWxzZSk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiMTIzNDU2Nzg5MDEwXHUwMGEwJSIsIG5mMi5mb3JtYXQoMTIzNDU2Nzg5MC4xKSk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiLTEyMzQ1Njc4OTAxMFx1MDBhMCUiLCBuZjIuZm9ybWF0KC0xMjM0NTY3ODkwLjEpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiMSwyMzQsNTY3LDg5MC4xIiwgbmYxLmZvcm1hdCgxMjM0NTY3ODkwLjEpKTsKKworICAgICAgICAgICAgbmYyLnNldEdyb3VwaW5nVXNlZCh0cnVlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiMTIzXHUwMGEwNDU2XHUwMGEwNzg5XHUwMGEwMDEwXHUwMGEwJSIsIG5mMi5mb3JtYXQoMTIzNDU2Nzg5MC4xKSk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiLTEyM1x1MDBhMDQ1Nlx1MDBhMDc4OVx1MDBhMDAxMFx1MDBhMCUiLCBuZjIuZm9ybWF0KC0xMjM0NTY3ODkwLjEpKTsKKworICAgICAgICAgICAgbmYyLnNldEdyb3VwaW5nVXNlZCh0cnVlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiMTIzXHUwMGEwNDU2XHUwMGEwNzg5XHUwMGEwMDEwXHUwMGEwJSIsIG5mMi5mb3JtYXQoMTIzNDU2Nzg5MC4xKSk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiLTEyM1x1MDBhMDQ1Nlx1MDBhMDc4OVx1MDBhMDAxMFx1MDBhMCUiLCBuZjIuZm9ybWF0KC0xMjM0NTY3ODkwLjEpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNQYXJzZUludGVnZXJPbmx5KCkgeworICAgICAgICBOdW1iZXJGb3JtYXQgbmYxID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCk7CisgICAgICAgIGFzc2VydFRydWUoIlBhcnNlSW50ZWdlck9ubHkgaXMgbm90IHVzZWQgZm9yIE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSIsCisgICAgICAgICAgICAgICAgbmYxLmlzR3JvdXBpbmdVc2VkKCkpOworCisgICAgICAgIG5mMS5zZXRQYXJzZUludGVnZXJPbmx5KGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgICAgICAgIlBhcnNlSW50ZWdlck9ubHkgaXMgdXNlZCBmb3IgTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlIGFmdGVyIHNldHRpbmcgZmFsc2UiLAorICAgICAgICAgICAgICAgIG5mMS5pc1BhcnNlSW50ZWdlck9ubHkoKSk7CisKKyAgICAgICAgbmYxLnNldFBhcnNlSW50ZWdlck9ubHkodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIlBhcnNlSW50ZWdlck9ubHkgaXMgbm90IHVzZWQgZm9yIE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSBhZnRlciBzZXR0aW5nIHRydWUiLAorICAgICAgICAgICAgICAgIG5mMS5pc1BhcnNlSW50ZWdlck9ubHkoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRQYXJzZUludGVnZXJPbmx5KCkgeworICAgICAgICBOdW1iZXJGb3JtYXQgbmYxID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKExvY2FsZS5VUyk7CisgICAgICAgIG5mMS5zZXRQYXJzZUludGVnZXJPbmx5KHRydWUpOworCisgICAgICAgIGFzc2VydEVxdWFscygiUGFyc2VJbnRlZ2VyT25seSBpcyBub3QgdXNlZCBmb3IgMTIzNDU2Nzg5MC4xIiwKKyAgICAgICAgICAgICAgICAiMSwyMzQsNTY3LDg5MC4xIiwgbmYxLmZvcm1hdCgxMjM0NTY3ODkwLjEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJQYXJzZUludGVnZXJPbmx5IGlzIG5vdCB1c2VkIGZvciAtMTIzNDU2Nzg5MC4xIiwKKyAgICAgICAgICAgICAgICAiLTEsMjM0LDU2Nyw4OTAuMSIsIG5mMS5mb3JtYXQoLTEyMzQ1Njc4OTAuMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlBhcnNlSW50ZWdlck9ubHkgaXMgbm90IHVzZWQgZm9yIC0xMjM0NTY3ODkwLiIsCisgICAgICAgICAgICAgICAgIi0xLDIzNCw1NjcsODkwIiwgbmYxLmZvcm1hdCgtMTIzNDU2Nzg5MC4pKTsKKworICAgICAgICBuZjEuc2V0UGFyc2VJbnRlZ2VyT25seShmYWxzZSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJQYXJzZUludGVnZXJPbmx5IGlzIG5vdCB1c2VkIGZvciAxMjM0NTY3ODkwLjEiLAorICAgICAgICAgICAgICAgICIxLDIzNCw1NjcsODkwLjEiLCBuZjEuZm9ybWF0KDEyMzQ1Njc4OTAuMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlBhcnNlSW50ZWdlck9ubHkgaXMgbm90IHVzZWQgZm9yIC0xMjM0NTY3ODkwLjEiLAorICAgICAgICAgICAgICAgICItMSwyMzQsNTY3LDg5MC4xIiwgbmYxLmZvcm1hdCgtMTIzNDU2Nzg5MC4xKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUGFyc2VJbnRlZ2VyT25seSBpcyBub3QgdXNlZCBmb3IgLTEyMzQ1Njc4OTAuIiwKKyAgICAgICAgICAgICAgICAiLTEsMjM0LDU2Nyw4OTAiLCBuZjEuZm9ybWF0KC0xMjM0NTY3ODkwLikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKCkgeworICAgICAgICBOdW1iZXJGb3JtYXQgbmYxID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKExvY2FsZS5VUyk7CisgICAgICAgIG5mMS5zZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICBpbnQgcmVzdWx0ID0gbmYxLmdldE1heGltdW1GcmFjdGlvbkRpZ2l0cygpOworICAgICAgICBhc3NlcnRUcnVlKCJzZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMgc2V0ICIgKyByZXN1bHQKKyAgICAgICAgICAgICAgICArICIgaW5zdGVhZCBvZiBJbnRlZ2VyLk1BWF9WQUxVRSIsIHJlc3VsdCA9PSBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIG5mMS5zZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoMCk7CisgICAgICAgIHJlc3VsdCA9IG5mMS5nZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgic2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzIHNldCAiICsgcmVzdWx0ICsgIiBpbnN0ZWFkIG9mIDAiLAorICAgICAgICAgICAgICAgIHJlc3VsdCA9PSAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb3JtYXQgb2YgMTIzNDU2Nzg5MC4wOTg3NjU0MzIxIHJldHVybnMgaW5jb3JyZWN0IHZhbHVlIiwKKyAgICAgICAgICAgICAgICAiMSwyMzQsNTY3LDg5MCIsIG5mMS5mb3JtYXQoMTIzNDU2Nzg5MC4wOTg3NjU0MzIxKSk7CisgICAgICAgIG5mMS5zZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoNSk7CisgICAgICAgIHJlc3VsdCA9IG5mMS5nZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgic2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzIHNldCAiICsgcmVzdWx0ICsgIiBpbnN0ZWFkIG9mIDUiLAorICAgICAgICAgICAgICAgIHJlc3VsdCA9PSA1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICJmb3JtYXQgb2YgMTIzNDU2Nzg5MC4wOTg3NjU0MzIxIHJldHVybnMgaW5jb3JyZWN0IHZhbHVlIHdpdGggTWF4aW11bUZyYWN0aW9uRGlnaXRzID0gNSIsCisgICAgICAgICAgICAgICAgIjEsMjM0LDU2Nyw4OTAuMDk4NzciLCBuZjEuZm9ybWF0KDEyMzQ1Njc4OTAuMDk4NzY1NDMyMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgImZvcm1hdCBvZiAtMTIzNDU2Nzg5MCByZXR1cm5zIGluY29ycmVjdCB2YWx1ZSB3aXRoIE1heGltdW1GcmFjdGlvbkRpZ2l0cyA9IDUiLAorICAgICAgICAgICAgICAgICItMSwyMzQsNTY3LDg5MCIsIG5mMS5mb3JtYXQoLTEyMzQ1Njc4OTApKTsKKyAgICAgICAgbmYxLnNldE1heGltdW1GcmFjdGlvbkRpZ2l0cyhJbnRlZ2VyLk1JTl9WQUxVRSk7CisgICAgICAgIHJlc3VsdCA9IG5mMS5nZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgic2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzIHNldCAiICsgcmVzdWx0CisgICAgICAgICAgICAgICAgKyAiIGluc3RlYWQgb2YgSW50ZWdlci5NSU5fVkFMVUUiLCByZXN1bHQgPT0gMCk7CisgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAiZm9ybWF0IG9mIDEyMzQ1Njc4OTAuMDk4NzY1NDMyMSByZXR1cm5zIGluY29ycmVjdCB2YWx1ZSB3aXRoIE1heGltdW1GcmFjdGlvbkRpZ2l0cyA9IDUiLAorICAgICAgICAgICAgICAgICIxLDIzNCw1NjcsODkwIiwgbmYxLmZvcm1hdCgxMjM0NTY3ODkwLjA5ODc2NTQzMjEpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldE1pbmltdW1GcmFjdGlvbkRpZ2l0cygpIHsKKworICAgICAgICBOdW1iZXJGb3JtYXQgbmYxID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKExvY2FsZS5VUyk7CisgICAgICAgIG5mMS5zZXRNaW5pbXVtRnJhY3Rpb25EaWdpdHMoSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICBpbnQgcmVzdWx0ID0gbmYxLmdldE1pbmltdW1GcmFjdGlvbkRpZ2l0cygpOworICAgICAgICBhc3NlcnRUcnVlKCJzZXRNaW5pbXVtRnJhY3Rpb25EaWdpdHMgc2V0ICIgKyByZXN1bHQKKyAgICAgICAgICAgICAgICArICIgaW5zdGVhZCBvZiBJbnRlZ2VyLk1BWF9WQUxVRSIsIHJlc3VsdCA9PSBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIG5mMS5zZXRNaW5pbXVtRnJhY3Rpb25EaWdpdHMoMCk7CisgICAgICAgIHJlc3VsdCA9IG5mMS5nZXRNaW5pbXVtRnJhY3Rpb25EaWdpdHMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgic2V0TWluaW11bUZyYWN0aW9uRGlnaXRzIHNldCAiICsgcmVzdWx0ICsgIiBpbnN0ZWFkIG9mIDAiLAorICAgICAgICAgICAgICAgIHJlc3VsdCA9PSAwKTsKKyAgICAgICAgbmYxLnNldE1pbmltdW1GcmFjdGlvbkRpZ2l0cyg1KTsKKyAgICAgICAgcmVzdWx0ID0gbmYxLmdldE1pbmltdW1GcmFjdGlvbkRpZ2l0cygpOworICAgICAgICBhc3NlcnRUcnVlKCJzZXRNaW5pbXVtRnJhY3Rpb25EaWdpdHMgc2V0ICIgKyByZXN1bHQgKyAiIGluc3RlYWQgb2YgNSIsCisgICAgICAgICAgICAgICAgcmVzdWx0ID09IDUpOworICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgImZvcm1hdCBvZiAxMjM0NTY3ODkwLjA5ODc2NTQzMjEgcmV0dXJucyBpbmNvcnJlY3QgdmFsdWUgd2l0aCBNaW5pbXVtRnJhY3Rpb25EaWdpdHMgPSA1IiwKKyAgICAgICAgICAgICAgICAiMSwyMzQsNTY3LDg5MC4wOTAwMCIsIG5mMS5mb3JtYXQoMTIzNDU2Nzg5MC4wOSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgImZvcm1hdCBvZiAtMTIzNDU2Nzg5MCByZXR1cm5zIGluY29ycmVjdCB2YWx1ZSB3aXRoIE1pbmltdW1GcmFjdGlvbkRpZ2l0cyA9IDUiLAorICAgICAgICAgICAgICAgICItMSwyMzQsNTY3LDg5MC4wMDAwMCIsIG5mMS5mb3JtYXQoLTEyMzQ1Njc4OTApKTsKKyAgICAgICAgbmYxLnNldE1pbmltdW1GcmFjdGlvbkRpZ2l0cyhJbnRlZ2VyLk1JTl9WQUxVRSk7CisgICAgICAgIHJlc3VsdCA9IG5mMS5nZXRNaW5pbXVtRnJhY3Rpb25EaWdpdHMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgic2V0TWluaW11bUZyYWN0aW9uRGlnaXRzIHNldCAiICsgcmVzdWx0CisgICAgICAgICAgICAgICAgKyAiIGluc3RlYWQgb2YgSW50ZWdlci5NSU5fVkFMVUUiLCByZXN1bHQgPT0gMCk7CisgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAiZm9ybWF0IG9mIDEyMzQ1Njc4OTAuMDk4IHJldHVybnMgaW5jb3JyZWN0IHZhbHVlIHdpdGggTWluaW11bUZyYWN0aW9uRGlnaXRzID0gNSIsCisgICAgICAgICAgICAgICAgIjEsMjM0LDU2Nyw4OTAuMDk4IiwgbmYxLmZvcm1hdCgxMjM0NTY3ODkwLjA5OCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0TWluaW11bUludGVnZXJEaWdpdHMoKSB7CisKKyAgICAgICAgTnVtYmVyRm9ybWF0IG5mMSA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZShMb2NhbGUuVVMpOworICAgICAgICBuZjEuc2V0TWluaW11bUludGVnZXJEaWdpdHMoSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICBpbnQgcmVzdWx0ID0gbmYxLmdldE1pbmltdW1JbnRlZ2VyRGlnaXRzKCk7CisgICAgICAgIGFzc2VydFRydWUoInNldE1pbmltdW1JbnRlZ2VyRGlnaXRzIHNldCAiICsgcmVzdWx0CisgICAgICAgICAgICAgICAgKyAiIGluc3RlYWQgb2YgSW50ZWdlci5NQVhfVkFMVUUiLCByZXN1bHQgPT0gSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICBuZjEuc2V0TWluaW11bUludGVnZXJEaWdpdHMoMCk7CisgICAgICAgIHJlc3VsdCA9IG5mMS5nZXRNaW5pbXVtSW50ZWdlckRpZ2l0cygpOworICAgICAgICBhc3NlcnRUcnVlKCJzZXRNaW5pbXVtSW50ZWdlckRpZ2l0cyBzZXQgIiArIHJlc3VsdCArICIgaW5zdGVhZCBvZiAwIiwKKyAgICAgICAgICAgICAgICByZXN1bHQgPT0gMCk7CisgICAgICAgIG5mMS5zZXRNaW5pbXVtSW50ZWdlckRpZ2l0cyg1KTsKKyAgICAgICAgcmVzdWx0ID0gbmYxLmdldE1pbmltdW1JbnRlZ2VyRGlnaXRzKCk7CisgICAgICAgIGFzc2VydFRydWUoInNldE1pbmltdW1JbnRlZ2VyRGlnaXRzIHNldCAiICsgcmVzdWx0ICsgIiBpbnN0ZWFkIG9mIDUiLAorICAgICAgICAgICAgICAgIHJlc3VsdCA9PSA1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICJmb3JtYXQgb2YgMTIzLjA5IHJldHVybnMgaW5jb3JyZWN0IHZhbHVlIHdpdGggTWluaW11bUludGVnZXJEaWdpdHMgPSA1IiwKKyAgICAgICAgICAgICAgICAiMDAsMTIzLjA5IiwgbmYxLmZvcm1hdCgxMjMuMDkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICJmb3JtYXQgb2YgLTEyMyByZXR1cm5zIGluY29ycmVjdCB2YWx1ZSB3aXRoIE1pbmltdW1JbnRlZ2VyRGlnaXRzID0gNSIsCisgICAgICAgICAgICAgICAgIi0wMCwxMjMiLCBuZjEuZm9ybWF0KC0xMjMpKTsKKyAgICAgICAgbmYxLnNldE1pbmltdW1JbnRlZ2VyRGlnaXRzKEludGVnZXIuTUlOX1ZBTFVFKTsKKyAgICAgICAgcmVzdWx0ID0gbmYxLmdldE1pbmltdW1JbnRlZ2VyRGlnaXRzKCk7CisgICAgICAgIGFzc2VydFRydWUoInNldE1pbmltdW1JbnRlZ2VyRGlnaXRzIHNldCAiICsgcmVzdWx0CisgICAgICAgICAgICAgICAgKyAiIGluc3RlYWQgb2YgSW50ZWdlci5NSU5fVkFMVUUiLCByZXN1bHQgPT0gMCk7CisgICAgfQorCisgICAgQEJyb2tlblRlc3QoIkZhaWxzIGluIENUUywgcGFzc2VzIGluIENvcmVUZXN0UnVubmVyIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BhcnNlTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIE51bWJlckZvcm1hdCBuZjEgPSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgIlRlc3QxOiBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKS5wYXJzZShcIjEyMzQ1Njc4OTAuMVwiKSByZXR1cm5lZCB3cm9uZyBudW1iZXIiLAorICAgICAgICAgICAgICAgICAgICBuZXcgRG91YmxlKDEyMzQ1Njc4OTAuMSksIG5mMS5wYXJzZSgiMTIzNDU2Nzg5MC4xIikpOworICAgICAgICB9IGNhdGNoIChqYXZhLnRleHQuUGFyc2VFeGNlcHRpb24gcGUpIHsKKyAgICAgICAgICAgIGZhaWwoImphdmEudGV4dC5QYXJzZUV4Y2VwdGlvbiBpcyB0aHJvd24gZm9yIDEyMzQ1Njc4OTAuMSIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgIlRlc3QyOiBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKS5wYXJzZShcIi0xMjM0NTY3ODkwLjFcIikgcmV0dXJuZWQgd3JvbmcgbnVtYmVyIiwKKyAgICAgICAgICAgICAgICAgICAgbmV3IERvdWJsZSgtMTIzNDU2Nzg5MC4xKSwgbmYxLnBhcnNlKCItMSwyMzQsNTY3LDg5MC4xIikpOworICAgICAgICB9IGNhdGNoIChqYXZhLnRleHQuUGFyc2VFeGNlcHRpb24gcGUpIHsKKyAgICAgICAgICAgIGZhaWwoImphdmEudGV4dC5QYXJzZUV4Y2VwdGlvbiBpcyB0aHJvd24gZm9yIC0xLDIzNCw1NjcsODkwLjEiKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZjEucGFyc2UoIkAxLDIzNCw1NjcsODkwMSIpOworICAgICAgICAgICAgZmFpbCgiamF2YS50ZXh0LlBhcnNlRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24gZm9yIDEsMjM0LDU2Nyw4OTB6MSIpOworICAgICAgICB9IGNhdGNoIChqYXZhLnRleHQuUGFyc2VFeGNlcHRpb24gcGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBuZjEgPSBOdW1iZXJGb3JtYXQuZ2V0UGVyY2VudEluc3RhbmNlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICJUZXN0MzogTnVtYmVyRm9ybWF0LmdldFBlcmNlbnRJbnN0YW5jZSgpLnBhcnNlKFwiLTEyMyVcIikgcmV0dXJuZWQgd3JvbmcgbnVtYmVyIiwKKyAgICAgICAgICAgICAgICAgICAgbmV3IERvdWJsZSgtMS4yMyksIG5mMS5wYXJzZSgiLTEyMyUiKSk7CisgICAgICAgIH0gY2F0Y2ggKGphdmEudGV4dC5QYXJzZUV4Y2VwdGlvbiBwZSkgeworICAgICAgICAgICAgZmFpbCgiamF2YS50ZXh0LlBhcnNlRXhjZXB0aW9uIGlzIHRocm93biBmb3IgLTEyMyUiKTsKKyAgICAgICAgfQorCisgICAgICAgIG5mMSA9IE51bWJlckZvcm1hdC5nZXRDdXJyZW5jeUluc3RhbmNlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICJUZXN0NDogTnVtYmVyRm9ybWF0LmdldEN1cnJlbmN5SW5zdGFuY2UoKS5wYXJzZShcIiQxMjNcIikgcmV0dXJuZWQgd3JvbmcgbnVtYmVyIiwKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvbmcoMTIzKSwgbmYxLnBhcnNlKCIkMTIzIikpOworICAgICAgICB9IGNhdGNoIChqYXZhLnRleHQuUGFyc2VFeGNlcHRpb24gcGUpIHsKKyAgICAgICAgICAgIGZhaWwoImphdmEudGV4dC5QYXJzZUV4Y2VwdGlvbiBpcyB0aHJvd24gZm9yICQxMjMiKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICJUZXN0NDogTnVtYmVyRm9ybWF0LmdldEN1cnJlbmN5SW5zdGFuY2UoKS5wYXJzZShcIiQxMjNhYmNcIikgcmV0dXJuZWQgd3JvbmcgbnVtYmVyIiwKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvbmcoMTIzKSwgbmYxLnBhcnNlKCIkMTIzYWJjIikpOworICAgICAgICB9IGNhdGNoIChqYXZhLnRleHQuUGFyc2VFeGNlcHRpb24gcGUpIHsKKyAgICAgICAgICAgIGZhaWwoImphdmEudGV4dC5QYXJzZUV4Y2VwdGlvbiBpcyB0aHJvd24gZm9yICQxMjMiKTsKKyAgICAgICAgfQorCisgICAgICAgIG5mMSA9IE51bWJlckZvcm1hdC5nZXRJbnRlZ2VySW5zdGFuY2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgIlRlc3Q1OiBOdW1iZXJGb3JtYXQuZ2V0SW50ZWdlckluc3RhbmNlKCkucGFyc2UoXCItMTIzLjEyM1wiKSByZXR1cm5lZCB3cm9uZyBudW1iZXIiLAorICAgICAgICAgICAgICAgICAgICBuZjEucGFyc2VPYmplY3QoIi0xMjMuMTIzIiksIG5mMS5wYXJzZSgiLTEyMy4xMjMiKSk7CisgICAgICAgIH0gY2F0Y2ggKGphdmEudGV4dC5QYXJzZUV4Y2VwdGlvbiBwZSkgeworICAgICAgICAgICAgZmFpbCgiamF2YS50ZXh0LlBhcnNlRXhjZXB0aW9uIGlzIHRocm93biBmb3IgJDEyMyIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25zdHJ1Y3RvcigpIHsKKyAgICAgICAgTXlOdW1iZXJGb3JtYXQgbWYgPSBuZXcgTXlOdW1iZXJGb3JtYXQoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkdyZWF0ZWQgTnVtYmVyRm9ybWF0IG9iamVjdCBpcyBudWxsIiwgbWYgPT0gbnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIkdyZWF0ZWQgTnVtYmVyRm9ybWF0IG9iamVjdCBpcyBub3QgaW5zdGFuY2Ugb2YgTnVtYmVyRm9ybWF0IiwKKyAgICAgICAgICAgICAgICBtZiBpbnN0YW5jZW9mIE51bWJlckZvcm1hdCk7CisgICAgfQorCisgICAgY2xhc3MgTXlOdW1iZXJGb3JtYXQgZXh0ZW5kcyBOdW1iZXJGb3JtYXQgeworICAgICAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAgICAgcHVibGljIE15TnVtYmVyRm9ybWF0KCkgeworICAgICAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgZm9ybWF0KGRvdWJsZSBudW1iZXIsIFN0cmluZ0J1ZmZlciB0b0FwcGVuZFRvLAorICAgICAgICAgICAgICAgIEZpZWxkUG9zaXRpb24gcG9zKSB7CisKKyAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTnVtYmVyIHBhcnNlKFN0cmluZyBzb3VyY2UsIFBhcnNlUG9zaXRpb24gcGFyc2VQb3NpdGlvbikgeworCisgICAgICAgICAgICByZXR1cm4gbmV3IERvdWJsZSgwKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgZm9ybWF0KGxvbmcgbnVtYmVyLCBTdHJpbmdCdWZmZXIgdG9BcHBlbmRUbywKKyAgICAgICAgICAgICAgICBGaWVsZFBvc2l0aW9uIHBvcykgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgfQorCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZFBhcnNlUG9zaXRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3RleHQvT2xkUGFyc2VQb3NpdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZDY3NzExCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZFBhcnNlUG9zaXRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw0NiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS50ZXh0OworCitpbXBvcnQgamF2YS50ZXh0LlBhcnNlUG9zaXRpb247CisKK3B1YmxpYyBjbGFzcyBPbGRQYXJzZVBvc2l0aW9uVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBQYXJzZVBvc2l0aW9uIHBwID0gbmV3IFBhcnNlUG9zaXRpb24oSW50ZWdlci5NQVhfVkFMVUUpOworCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnRleHQuUGFyc2VQb3NpdGlvbi5oYXNoQ29kZSgpCisgICAgICAgIFBhcnNlUG9zaXRpb24gcHAxID0gbmV3IFBhcnNlUG9zaXRpb24oMCk7CisgICAgICAgIFBhcnNlUG9zaXRpb24gcHAyID0gbmV3IFBhcnNlUG9zaXRpb24oMCk7CisgICAgICAgIGFzc2VydFRydWUoImhhc2hDb2RlIHJldHVybnMgbm9uIGVxdWFsIGhhc2ggY29kZXMgZm9yIGVxdWFsIG9iamVjdHMuIiwKKyAgICAgICAgICAgICAgICBwcDEuaGFzaENvZGUoKSA9PSBwcDIuaGFzaENvZGUoKSk7CisgICAgICAgIHBwMS5zZXRJbmRleChJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIGFzc2VydFRydWUoImhhc2hDb2RlIHJldHVybnMgZXF1YWwgaGFzaCBjb2RlcyBmb3Igbm9uIGVxdWFsIG9iamVjdHMuIiwKKyAgICAgICAgICAgICAgICBwcDEuaGFzaENvZGUoKSAhPSBwcDIuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRFcnJvckluZGV4KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudGV4dC5QYXJzZVBvc2l0aW9uLmdldEVycm9ySW5kZXgoKQorICAgICAgICBwcC5zZXRFcnJvckluZGV4KDU2KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRFcnJvckluZGV4IGZhaWxlZC4iLCA1NiwgcHAuZ2V0RXJyb3JJbmRleCgpKTsKKyAgICAgICAgcHAuc2V0RXJyb3JJbmRleChJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ2V0RXJyb3JJbmRleCBmYWlsZWQuIiwgSW50ZWdlci5NQVhfVkFMVUUsCisgICAgICAgICAgICAgICAgcHAuZ2V0RXJyb3JJbmRleCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRFcnJvckluZGV4IGZhaWxlZC4iLCBJbnRlZ2VyLk1BWF9WQUxVRSwKKyAgICAgICAgICAgICAgICBwcC5nZXRFcnJvckluZGV4KCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGRTaW1wbGVEYXRlRm9ybWF0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L09sZFNpbXBsZURhdGVGb3JtYXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDE1MDZkZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9PbGRTaW1wbGVEYXRlRm9ybWF0VGVzdC5qYXZhCkBAIC0wLDAgKzEsNTMwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLnRleHQ7CisKK2ltcG9ydCBqYXZhLnRleHQuRGF0ZUZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuRGF0ZUZvcm1hdFN5bWJvbHM7CitpbXBvcnQgamF2YS50ZXh0LkZpZWxkUG9zaXRpb247CitpbXBvcnQgamF2YS50ZXh0LlBhcnNlUG9zaXRpb247CitpbXBvcnQgamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQ7CitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZTsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CisKK3B1YmxpYyBjbGFzcyBPbGRTaW1wbGVEYXRlRm9ybWF0VGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBTaW1wbGVEYXRlRm9ybWF0IGZvcm1hdCA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCIiLCBMb2NhbGUuRU5HTElTSCk7CisKKyAgICBTaW1wbGVEYXRlRm9ybWF0IHBGb3JtYXQgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgiIiwgTG9jYWxlLkVOR0xJU0gpOworCisgICAgY2xhc3MgRm9ybWF0VGVzdGVyIHsKKyAgICAgICAgYm9vbGVhbiB0ZXN0c0ZhaWxlZCA9IGZhbHNlOworCisgICAgICAgIHB1YmxpYyB2b2lkIHRlc3QoU3RyaW5nIHBhdHRlcm4sIENhbGVuZGFyIGNhbCwgU3RyaW5nIGV4cGVjdGVkLCBpbnQgZmllbGQpIHsKKyAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgICAgICBGaWVsZFBvc2l0aW9uIHBvc2l0aW9uID0gbmV3IEZpZWxkUG9zaXRpb24oZmllbGQpOworICAgICAgICAgICAgZm9ybWF0LmFwcGx5UGF0dGVybihwYXR0ZXJuKTsKKyAgICAgICAgICAgIGZvcm1hdC5mb3JtYXQoY2FsLmdldFRpbWUoKSwgYnVmZmVyLCBwb3NpdGlvbik7CisgICAgICAgICAgICBTdHJpbmcgcmVzdWx0ID0gYnVmZmVyLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBpZiAoIXJlc3VsdC5lcXVhbHMoZXhwZWN0ZWQpKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJXcm9uZyBmb3JtYXQ6IFwiIiArIHBhdHRlcm4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiXCIgZXhwZWN0ZWQ6ICIgKyBleHBlY3RlZCArICIgcmVzdWx0OiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgcmVzdWx0KTsKKyAgICAgICAgICAgICAgICB0ZXN0c0ZhaWxlZCA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBwYXJzZShTdHJpbmcgcGF0dGVybiwgU3RyaW5nIGlucHV0LCBEYXRlIGV4cGVjdGVkLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKyAgICAgICAgICAgIHBGb3JtYXQuYXBwbHlQYXR0ZXJuKHBhdHRlcm4pOworICAgICAgICAgICAgUGFyc2VQb3NpdGlvbiBwb3NpdGlvbiA9IG5ldyBQYXJzZVBvc2l0aW9uKHN0YXJ0KTsKKyAgICAgICAgICAgIERhdGUgcmVzdWx0ID0gcEZvcm1hdC5wYXJzZShpbnB1dCwgcG9zaXRpb24pOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcmVzdWx0OiAiICsgcGF0dGVybiArICIgaW5wdXQ6ICIgKyBpbnB1dAorICAgICAgICAgICAgICAgICAgICArICIgZXhwZWN0ZWQ6ICIgKyBleHBlY3RlZCArICIgcmVzdWx0OiAiICsgcmVzdWx0LCBleHBlY3RlZAorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKHJlc3VsdCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgZW5kIHBvc2l0aW9uOiAiICsgcGF0dGVybiArICIgaW5wdXQ6ICIgKyBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24uZ2V0SW5kZXgoKSA9PSBlbmQpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgdmVyaWZ5Rm9ybWF0VGltZXpvbmUoU3RyaW5nIHRpbWVab25lSWQsIFN0cmluZyBleHBlY3RlZDEsCisgICAgICAgICAgICAgICAgU3RyaW5nIGV4cGVjdGVkMiwgRGF0ZSBkYXRlKSB7CisgICAgICAgICAgICBmb3JtYXQuc2V0VGltZVpvbmUoU2ltcGxlVGltZVpvbmUuZ2V0VGltZVpvbmUodGltZVpvbmVJZCkpOworICAgICAgICAgICAgZm9ybWF0LmFwcGx5UGF0dGVybigieiwgenp6eiIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IHogZm9yIFRpbWVab25lIDogIiArIHRpbWVab25lSWQsIGV4cGVjdGVkMSwKKyAgICAgICAgICAgICAgICAgICAgZm9ybWF0LmZvcm1hdChkYXRlKSk7CisKKyAgICAgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIlosIFpaWloiKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCBaIGZvciBUaW1lWm9uZSA6ICIgKyB0aW1lWm9uZUlkLCBleHBlY3RlZDIsCisgICAgICAgICAgICAgICAgICAgIGZvcm1hdC5mb3JtYXQoZGF0ZSkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQjU2ltcGxlRGF0ZUZvcm1hdChqYXZhLmxhbmcuU3RyaW5nLAorICAgICAqICAgICAgICBqYXZhLnRleHQuRGF0ZUZvcm1hdFN5bWJvbHMpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfU3RyaW5nTGphdmFfdGV4dF9EYXRlRm9ybWF0U3ltYm9scygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0KGphdmEubGFuZy5TdHJpbmcsCisgICAgICAgIC8vIGphdmEudGV4dC5EYXRlRm9ybWF0U3ltYm9scykKKyAgICAgICAgRGF0ZUZvcm1hdFN5bWJvbHMgc3ltYm9scyA9IG5ldyBEYXRlRm9ybWF0U3ltYm9scyhMb2NhbGUuRU5HTElTSCk7CisgICAgICAgIHN5bWJvbHMuc2V0RXJhcyhuZXcgU3RyaW5nW10geyAiQmVmb3JlIiwgIkFmdGVyIiB9KTsKKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBmMiA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCJ5J3kneXkiLCBzeW1ib2xzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgY2xhc3MiLCBmMi5nZXRDbGFzcygpID09IFNpbXBsZURhdGVGb3JtYXQuY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHBhdHRlcm4iLCAieSd5J3l5IiwgZjIudG9QYXR0ZXJuKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBzeW1ib2xzIiwgZjIuZ2V0RGF0ZUZvcm1hdFN5bWJvbHMoKS5lcXVhbHMoc3ltYm9scykpOworICAgICAgICBhc3NlcnRUcnVlKCJEb2Vzbid0IHdvcmsiLAorICAgICAgICAgICAgICAgIGYyLmZvcm1hdChuZXcgRGF0ZSgpKS5nZXRDbGFzcygpID09IFN0cmluZy5jbGFzcyk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTaW1wbGVEYXRlRm9ybWF0KG51bGwsIHN5bWJvbHMpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFNpbXBsZURhdGVGb3JtYXQoImVlZSIsIHN5bWJvbHMpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZ0xqYXZhX3V0aWxfTG9jYWxlKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQoamF2YS5sYW5nLlN0cmluZywKKyAgICAgICAgLy8gamF2YS51dGlsLkxvY2FsZSkKKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBmMiA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCIneXl5eScgTU0geXkiLAorICAgICAgICAgICAgICAgIExvY2FsZS5HRVJNQU4pOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBjbGFzcyIsIGYyLmdldENsYXNzKCkgPT0gU2ltcGxlRGF0ZUZvcm1hdC5jbGFzcyk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcGF0dGVybiIsICIneXl5eScgTU0geXkiLCBmMi50b1BhdHRlcm4oKSk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHN5bWJvbHMiLCBmMi5nZXREYXRlRm9ybWF0U3ltYm9scygpLmVxdWFscygKKyAgICAgICAgICAgICAgICBuZXcgRGF0ZUZvcm1hdFN5bWJvbHMoTG9jYWxlLkdFUk1BTikpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRG9lc24ndCB3b3JrIiwKKyAgICAgICAgICAgICAgICBmMi5mb3JtYXQobmV3IERhdGUoKSkuZ2V0Q2xhc3MoKSA9PSBTdHJpbmcuY2xhc3MpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2ltcGxlRGF0ZUZvcm1hdChudWxsLCBMb2NhbGUuR0VSTUFOKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgiZWVlIiwgTG9jYWxlLkdFUk1BTik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9hcHBseUxvY2FsaXplZFBhdHRlcm5MamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQKKyAgICAgICAgLy8gamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQuYXBwbHlMb2NhbGl6ZWRQYXR0ZXJuKGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgZjIgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgieSIsIG5ldyBMb2NhbGUoImRlIiwgIkNIIikpOworICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLXJlbW92ZWQKKyAgICAgICAgLy8gVGhpcyB0ZXN0IGRvZXNuJ3Qgd29yayBsaWtlIHRoaXMuIFRoZSBjYXVzZSBsaWVzIGluc2lkZSBvZiBpY3UKKyAgICAgICAgLy8gdGhhdCBkb2Vzbid0IHN1cHBvcnQgbG9jYWxpemVkIHBhdHRlcm4gY2hhcmFjdGVycyBhbnltb3JlLiBTbyB0aGlzCisgICAgICAgIC8vIHRlc3QgZmFpbHMgYmVjYXVzZSB0aGUgcGF0dGVybiB0ZW1wbGF0ZSBjb250YWlucyBjaGFyYWN0ZXJzIHRoYXQgYXJlCisgICAgICAgIC8vIG5vdCBwYXJ0IG9mIHRoZSBzdGFuZGFyZCBwYXR0ZXJuIHJldHVybmVkIGZvciBldmVyeSBsb2NhbGUuCisgICAgICAgIC8vIFRoZSBkZWZhdWx0IHBhdHRlcm4gY2hhcmFjdGVycyBhcmU6IEd5TWRrSG1zU0VERndXYWhLeloKKyAgICAgICAgLy8KKyAgICAgICAgLy8gZjIuYXBwbHlMb2NhbGl6ZWRQYXR0ZXJuKCJHdU10a0htc1NFREZ3V2FoS3oiKTsKKyAgICAgICAgLy8gU3RyaW5nIHBhdHRlcm4gPSBmMi50b1BhdHRlcm4oKTsKKyAgICAgICAgLy8gYXNzZXJ0VHJ1ZSgiV3JvbmcgcGF0dGVybjogIiArIHBhdHRlcm4sIHBhdHRlcm4KKyAgICAgICAgLy8gICAgICAgICAuZXF1YWxzKCJHeU1ka0htc1NFREZ3V2FoS3oiKSk7CisgICAgICAgIC8vCisgICAgICAgIC8vIHRlc3QgdGhlIG5ldyAiWiIgcGF0dGVybiBjaGFyCisgICAgICAgIC8vIGYyID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoInkiLCBuZXcgTG9jYWxlKCJkZSIsICJDSCIpKTsKKyAgICAgICAgLy8gZjIuYXBwbHlMb2NhbGl6ZWRQYXR0ZXJuKCJHIHUgTSB0IFoiKTsKKyAgICAgICAgLy8gcGF0dGVybiA9IGYyLnRvUGF0dGVybigpOworICAgICAgICAvLyBhc3NlcnRUcnVlKCJXcm9uZyBwYXR0ZXJuOiAiICsgcGF0dGVybiwgcGF0dGVybi5lcXVhbHMoIkcgeSBNIGQgWiIpKTsKKyAgICAgICAgLy8gRU5EIGFuZHJvaWQtcmVtb3ZlZAorCisgICAgICAgIC8vIHRlc3QgaW52YWxpZCBwYXR0ZXJucworICAgICAgICB0cnkgeworICAgICAgICAgICAgZjIuYXBwbHlMb2NhbGl6ZWRQYXR0ZXJuKCJiIik7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZm9yIHBhdHRlcm4gd2l0aCBpbnZhbGlkIHBhdHRlcm4gbGV0dGVyOiBiIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gSUNVIG9ubHkhIHRoaXMgZmFpbHMgb24gdGhlIFJJCisgICAgICAgICAgICBmMi5hcHBseUxvY2FsaXplZFBhdHRlcm4oInUiKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBmb3IgcGF0dGVybiB3aXRoIGludmFsaWQgcGF0dGVybiBsZXR0ZXI6IHUiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmMi5hcHBseUxvY2FsaXplZFBhdHRlcm4oImEgJyIpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGZvciBwYXR0ZXJuIHdpdGggdW50ZXJtaW5hdGVkIHF1b3RlOiBhICciKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmMi5hcHBseUxvY2FsaXplZFBhdHRlcm4obnVsbCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiBmb3IgbnVsbCBwYXR0ZXJuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0I2FwcGx5UGF0dGVybihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYXBwbHlQYXR0ZXJuTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkCisgICAgICAgIC8vIGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0LmFwcGx5UGF0dGVybihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IGYyID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoInkiLCBuZXcgTG9jYWxlKCJkZSIsICJDSCIpKTsKKyAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIGYyLmFwcGx5UGF0dGVybigiR3lNZGtIbXNTRURGd1dhaEt6WiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHBhdHRlcm4iLCAiR3lNZGtIbXNTRURGd1dhaEt6WiIsIGYyLnRvUGF0dGVybigpKTsKKyAgICAgICAgLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorCisgICAgICAgIC8vIHRlc3QgaW52YWxpZCBwYXR0ZXJucworICAgICAgICB0cnkgeworICAgICAgICAgICAgZjIuYXBwbHlQYXR0ZXJuKCJ1Iik7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZm9yIHBhdHRlcm4gd2l0aCBpbnZhbGlkIHBhdHRlciBsZXR0ZXI6IHUiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGFzaENvZGUoKSB7CisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgZm9ybWF0ID0gKFNpbXBsZURhdGVGb3JtYXQpIERhdGVGb3JtYXQuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBjbG9uZSA9IChTaW1wbGVEYXRlRm9ybWF0KSBmb3JtYXQuY2xvbmUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiY2xvbmUgaGFzIG5vdCBlcXVhbCBoYXNoIGNvZGUiLCBjbG9uZS5oYXNoQ29kZSgpID09IGZvcm1hdAorICAgICAgICAgICAgICAgIC5oYXNoQ29kZSgpKTsKKyAgICAgICAgZm9ybWF0LmZvcm1hdChuZXcgRGF0ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiY2xvbmUgaGFzIG5vdCBlcXVhbCBoYXNoIGNvZGUgYWZ0ZXIgZm9ybWF0IiwgY2xvbmUKKyAgICAgICAgICAgICAgICAuaGFzaENvZGUoKSA9PSBmb3JtYXQuaGFzaENvZGUoKSk7CisgICAgICAgIERhdGVGb3JtYXRTeW1ib2xzIHN5bWJvbHMgPSBuZXcgRGF0ZUZvcm1hdFN5bWJvbHMoTG9jYWxlLkVOR0xJU0gpOworICAgICAgICBzeW1ib2xzLnNldEVyYXMobmV3IFN0cmluZ1tdIHsgIkJlZm9yZSIsICJBZnRlciIgfSk7CisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgZm9ybWF0MiA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCJ5J3kneXkiLCBzeW1ib2xzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIm9iamVjdHMgaGFzIGVxdWFsIGhhc2ggY29kZSIsIGZvcm1hdDIuaGFzaENvZGUoKSA9PSBmb3JtYXQKKyAgICAgICAgICAgICAgICAuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9mb3JtYXRMamF2YV91dGlsX0RhdGVMamF2YV9sYW5nX1N0cmluZ0J1ZmZlckxqYXZhX3RleHRfRmllbGRQb3NpdGlvbigpIHsKKyAgICAgICAgRm9ybWF0VGVzdGVyIHRlc3QgPSBuZXcgRm9ybWF0VGVzdGVyKCk7CisKKyAgICAgICAgQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLkpVTkUsIDIsIDE1LCAzLCA2KTsKKyAgICAgICAgdGVzdC50ZXN0KCIgRyIsIGNhbCwgIiBBRCIsIERhdGVGb3JtYXQuRVJBX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgR0ciLCBjYWwsICIgQUQiLCBEYXRlRm9ybWF0LkVSQV9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIEdHRyIsIGNhbCwgIiBBRCIsIERhdGVGb3JtYXQuRVJBX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgRyIsIG5ldyBHcmVnb3JpYW5DYWxlbmRhcigtMTk5OSwgQ2FsZW5kYXIuSlVORSwgMiksICIgQkMiLAorICAgICAgICAgICAgICAgIERhdGVGb3JtYXQuRVJBX0ZJRUxEKTsKKworICAgICAgICB0ZXN0LnRlc3QoIiBNIiwgY2FsLCAiIDYiLCBEYXRlRm9ybWF0Lk1PTlRIX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgTSIsIG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk5LCBDYWxlbmRhci5OT1ZFTUJFUiwgMiksCisgICAgICAgICAgICAgICAgIiAxMSIsIERhdGVGb3JtYXQuTU9OVEhfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiBNTSIsIGNhbCwgIiAwNiIsIERhdGVGb3JtYXQuTU9OVEhfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiBNTU0iLCBjYWwsICIgSnVuIiwgRGF0ZUZvcm1hdC5NT05USF9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIE1NTU0iLCBjYWwsICIgSnVuZSIsIERhdGVGb3JtYXQuTU9OVEhfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiBNTU1NTSIsIGNhbCwgIiBKdW5lIiwgRGF0ZUZvcm1hdC5NT05USF9GSUVMRCk7CisKKyAgICAgICAgdGVzdC50ZXN0KCIgZCIsIGNhbCwgIiAyIiwgRGF0ZUZvcm1hdC5EQVRFX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgZCIsIG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk5LCBDYWxlbmRhci5OT1ZFTUJFUiwgMTIpLAorICAgICAgICAgICAgICAgICIgMTIiLCBEYXRlRm9ybWF0LkRBVEVfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiBkZCIsIGNhbCwgIiAwMiIsIERhdGVGb3JtYXQuREFURV9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIGRkZGQiLCBjYWwsICIgMDAwMiIsIERhdGVGb3JtYXQuREFURV9GSUVMRCk7CisKKyAgICAgICAgdGVzdC50ZXN0KCIgaCIsIGNhbCwgIiAzIiwgRGF0ZUZvcm1hdC5IT1VSMV9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIGgiLCBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OSwgQ2FsZW5kYXIuTk9WRU1CRVIsIDEyKSwKKyAgICAgICAgICAgICAgICAiIDEyIiwgRGF0ZUZvcm1hdC5IT1VSMV9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIGhoIiwgY2FsLCAiIDAzIiwgRGF0ZUZvcm1hdC5IT1VSMV9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIGhoaGgiLCBjYWwsICIgMDAwMyIsIERhdGVGb3JtYXQuSE9VUjFfRklFTEQpOworCisgICAgICAgIHRlc3QudGVzdCgiIEgiLCBjYWwsICIgMTUiLCBEYXRlRm9ybWF0LkhPVVJfT0ZfREFZMF9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIEgiLAorICAgICAgICAgICAgICAgIG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk5LCBDYWxlbmRhci5OT1ZFTUJFUiwgMTIsIDQsIDApLCAiIDQiLAorICAgICAgICAgICAgICAgIERhdGVGb3JtYXQuSE9VUl9PRl9EQVkwX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgSCIsIG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk5LCBDYWxlbmRhci5OT1ZFTUJFUiwgMTIsIDEyLAorICAgICAgICAgICAgICAgIDApLCAiIDEyIiwgRGF0ZUZvcm1hdC5IT1VSX09GX0RBWTBfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiBIIiwgbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLk5PVkVNQkVSLCAxMiksCisgICAgICAgICAgICAgICAgIiAwIiwgRGF0ZUZvcm1hdC5IT1VSX09GX0RBWTBfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiBISCIsIGNhbCwgIiAxNSIsIERhdGVGb3JtYXQuSE9VUl9PRl9EQVkwX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgSEhISCIsIGNhbCwgIiAwMDE1IiwgRGF0ZUZvcm1hdC5IT1VSX09GX0RBWTBfRklFTEQpOworCisgICAgICAgIHRlc3QudGVzdCgiIG0iLCBjYWwsICIgMyIsIERhdGVGb3JtYXQuTUlOVVRFX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgbSIsIG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk5LCBDYWxlbmRhci5OT1ZFTUJFUiwgMTIsIDQsCisgICAgICAgICAgICAgICAgNDcpLCAiIDQ3IiwgRGF0ZUZvcm1hdC5NSU5VVEVfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiBtbSIsIGNhbCwgIiAwMyIsIERhdGVGb3JtYXQuTUlOVVRFX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgbW1tbSIsIGNhbCwgIiAwMDAzIiwgRGF0ZUZvcm1hdC5NSU5VVEVfRklFTEQpOworCisgICAgICAgIHRlc3QudGVzdCgiIHMiLCBjYWwsICIgNiIsIERhdGVGb3JtYXQuU0VDT05EX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgcyIsIG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk5LCBDYWxlbmRhci5OT1ZFTUJFUiwgMTIsIDQsCisgICAgICAgICAgICAgICAgNDcsIDEzKSwgIiAxMyIsIERhdGVGb3JtYXQuU0VDT05EX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgc3MiLCBjYWwsICIgMDYiLCBEYXRlRm9ybWF0LlNFQ09ORF9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIHNzc3MiLCBjYWwsICIgMDAwNiIsIERhdGVGb3JtYXQuU0VDT05EX0ZJRUxEKTsKKworICAgICAgICB0ZXN0LnRlc3QoIiBTIiwgY2FsLCAiIDAiLCBEYXRlRm9ybWF0Lk1JTExJU0VDT05EX0ZJRUxEKTsKKyAgICAgICAgQ2FsZW5kYXIgdGVtcCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigpOworICAgICAgICB0ZW1wLnNldChDYWxlbmRhci5NSUxMSVNFQ09ORCwgOTYxKTsKKworICAgICAgICB0ZXN0LnRlc3QoIiBTUyIsIHRlbXAsICIgOTYxIiwgRGF0ZUZvcm1hdC5NSUxMSVNFQ09ORF9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIFNTU1MiLCBjYWwsICIgMDAwMCIsIERhdGVGb3JtYXQuTUlMTElTRUNPTkRfRklFTEQpOworCisgICAgICAgIHRlc3QudGVzdCgiIFNTIiwgY2FsLCAiIDAwIiwgRGF0ZUZvcm1hdC5NSUxMSVNFQ09ORF9GSUVMRCk7CisKKyAgICAgICAgdGVzdC50ZXN0KCIgRSIsIGNhbCwgIiBXZWQiLCBEYXRlRm9ybWF0LkRBWV9PRl9XRUVLX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgRUUiLCBjYWwsICIgV2VkIiwgRGF0ZUZvcm1hdC5EQVlfT0ZfV0VFS19GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIEVFRSIsIGNhbCwgIiBXZWQiLCBEYXRlRm9ybWF0LkRBWV9PRl9XRUVLX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgRUVFRSIsIGNhbCwgIiBXZWRuZXNkYXkiLCBEYXRlRm9ybWF0LkRBWV9PRl9XRUVLX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgRUVFRUUiLCBjYWwsICIgV2VkbmVzZGF5IiwgRGF0ZUZvcm1hdC5EQVlfT0ZfV0VFS19GSUVMRCk7CisKKyAgICAgICAgdGVzdC50ZXN0KCIgRCIsIGNhbCwgIiAxNTMiLCBEYXRlRm9ybWF0LkRBWV9PRl9ZRUFSX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgREQiLCBjYWwsICIgMTUzIiwgRGF0ZUZvcm1hdC5EQVlfT0ZfWUVBUl9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIEREREQiLCBjYWwsICIgMDE1MyIsIERhdGVGb3JtYXQuREFZX09GX1lFQVJfRklFTEQpOworCisgICAgICAgIHRlc3QudGVzdCgiIEYiLCBjYWwsICIgMSIsIERhdGVGb3JtYXQuREFZX09GX1dFRUtfSU5fTU9OVEhfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiBGIiwgbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLk5PVkVNQkVSLCAxNCksCisgICAgICAgICAgICAgICAgIiAyIiwgRGF0ZUZvcm1hdC5EQVlfT0ZfV0VFS19JTl9NT05USF9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIEZGIiwgY2FsLCAiIDAxIiwgRGF0ZUZvcm1hdC5EQVlfT0ZfV0VFS19JTl9NT05USF9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIEZGRkYiLCBjYWwsICIgMDAwMSIsIERhdGVGb3JtYXQuREFZX09GX1dFRUtfSU5fTU9OVEhfRklFTEQpOworCisgICAgICAgIHRlc3QudGVzdCgiIGEiLCBjYWwsICIgUE0iLCBEYXRlRm9ybWF0LkFNX1BNX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgYSIsIG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk5LCBDYWxlbmRhci5OT1ZFTUJFUiwgMTQpLAorICAgICAgICAgICAgICAgICIgQU0iLCBEYXRlRm9ybWF0LkFNX1BNX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgYSIsIG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk5LCBDYWxlbmRhci5OT1ZFTUJFUiwgMTQsIDEyLAorICAgICAgICAgICAgICAgIDApLCAiIFBNIiwgRGF0ZUZvcm1hdC5BTV9QTV9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIGFhIiwgY2FsLCAiIFBNIiwgRGF0ZUZvcm1hdC5BTV9QTV9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIGFhYSIsIGNhbCwgIiBQTSIsIERhdGVGb3JtYXQuQU1fUE1fRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiBhYWFhIiwgY2FsLCAiIFBNIiwgRGF0ZUZvcm1hdC5BTV9QTV9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIGFhYWFhIiwgY2FsLCAiIFBNIiwgRGF0ZUZvcm1hdC5BTV9QTV9GSUVMRCk7CisKKyAgICAgICAgdGVzdC50ZXN0KCIgayIsIGNhbCwgIiAxNSIsIERhdGVGb3JtYXQuSE9VUl9PRl9EQVkxX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgayIsCisgICAgICAgICAgICAgICAgbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLk5PVkVNQkVSLCAxMiwgNCwgMCksICIgNCIsCisgICAgICAgICAgICAgICAgRGF0ZUZvcm1hdC5IT1VSX09GX0RBWTFfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiBrIiwgbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLk5PVkVNQkVSLCAxMiwgMTIsCisgICAgICAgICAgICAgICAgMCksICIgMTIiLCBEYXRlRm9ybWF0LkhPVVJfT0ZfREFZMV9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIGsiLCBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OSwgQ2FsZW5kYXIuTk9WRU1CRVIsIDEyKSwKKyAgICAgICAgICAgICAgICAiIDI0IiwgRGF0ZUZvcm1hdC5IT1VSX09GX0RBWTFfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiBrayIsIGNhbCwgIiAxNSIsIERhdGVGb3JtYXQuSE9VUl9PRl9EQVkxX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIga2trayIsIGNhbCwgIiAwMDE1IiwgRGF0ZUZvcm1hdC5IT1VSX09GX0RBWTFfRklFTEQpOworCisgICAgICAgIHRlc3QudGVzdCgiIEsiLCBjYWwsICIgMyIsIERhdGVGb3JtYXQuSE9VUjBfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiBLIiwgbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLk5PVkVNQkVSLCAxMiksCisgICAgICAgICAgICAgICAgIiAwIiwgRGF0ZUZvcm1hdC5IT1VSMF9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIEtLIiwgY2FsLCAiIDAzIiwgRGF0ZUZvcm1hdC5IT1VSMF9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIEtLS0siLCBjYWwsICIgMDAwMyIsIERhdGVGb3JtYXQuSE9VUjBfRklFTEQpOworCisgICAgICAgIGZvcm1hdC5hcHBseVBhdHRlcm4oIidNa3onJyc6LkA1Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgb3V0cHV0IiwgIk1reic6LkA1IiwgZm9ybWF0LmZvcm1hdChuZXcgRGF0ZSgpKSk7CisKKyAgICAgICAgLy9hc3NlcnRUcnVlKCJUZXN0cyBmYWlsZWQiLCAhdGVzdC50ZXN0c0ZhaWxlZCgpKTsKKworICAgICAgICAvLyBUZXN0IGludmFsaWQgYXJncyB0byBmb3JtYXQuCisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgZGF0ZUZvcm1hdCA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkYXRlRm9ybWF0LmZvcm1hdChudWxsLCBuZXcgU3RyaW5nQnVmZmVyKCksIG5ldyBGaWVsZFBvc2l0aW9uKDEpKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIHRlc3QgdG8gdGhyb3cgTlBFLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCB0ZXN0IHRvIHRocm93IE5QRSwgbm90ICIgKyBleC5nZXRDbGFzcygpLmdldE5hbWUoKSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRGYWxzZSh0ZXN0LnRlc3RzRmFpbGVkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIHRlc3QgYXNzdW1lcyBVbmljb2RlIGJlaGF2aW9yIHdoZXJlICd5JyBhbmQgJ3l5eScgZG9uJ3QgdHJ1bmNhdGUsCisgICAgICogd2hpY2ggbWVhbnMgdGhhdCBpdCB3aWxsIGZhaWwgb24gdGhlIFJJLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXR0aW5nWWVhcigpIHsKKyAgICAgICAgRm9ybWF0VGVzdGVyIHRlc3QgPSBuZXcgRm9ybWF0VGVzdGVyKCk7CisKKyAgICAgICAgQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLkpVTkUsIDIsIDE1LCAzLCA2KTsKKyAgICAgICAgdGVzdC50ZXN0KCIgeSIsIGNhbCwgIiAxOTk5IiwgRGF0ZUZvcm1hdC5ZRUFSX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgeXkiLCBjYWwsICIgOTkiLCBEYXRlRm9ybWF0LllFQVJfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiB5eSIsIG5ldyBHcmVnb3JpYW5DYWxlbmRhcigyMDAxLCBDYWxlbmRhci5KVU5FLCAyKSwgIiAwMSIsCisgICAgICAgICAgICAgICAgRGF0ZUZvcm1hdC5ZRUFSX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgeXkiLCBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMjAwMCwgQ2FsZW5kYXIuSlVORSwgMiksICIgMDAiLAorICAgICAgICAgICAgICAgIERhdGVGb3JtYXQuWUVBUl9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIHl5eSIsIG5ldyBHcmVnb3JpYW5DYWxlbmRhcigyMDAwLCBDYWxlbmRhci5KVU5FLCAyKSwgIiAyMDAwIiwKKyAgICAgICAgICAgICAgICBEYXRlRm9ybWF0LllFQVJfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiB5eXkiLCBjYWwsICIgMTk5OSIsIERhdGVGb3JtYXQuWUVBUl9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIHl5eXkiLCBjYWwsICIgMTk5OSIsIERhdGVGb3JtYXQuWUVBUl9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIHl5eXl5IiwgY2FsLCAiIDAxOTk5IiwgRGF0ZUZvcm1hdC5ZRUFSX0ZJRUxEKTsKKworICAgICAgICBhc3NlcnRGYWxzZSh0ZXN0LnRlc3RzRmFpbGVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0dGluZ1dlZWtPZlllYXIoKSB7CisgICAgICAgIEZvcm1hdFRlc3RlciB0ZXN0ID0gbmV3IEZvcm1hdFRlc3RlcigpOworICAgICAgICBDYWxlbmRhciBjYWwgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OSwgQ2FsZW5kYXIuSlVORSwgMiwgMTUsIDMsIDYpOworICAgICAgICBjYWwuc2V0TWluaW1hbERheXNJbkZpcnN0V2VlaygxKTsKKyAgICAgICAgY2FsLnNldEZpcnN0RGF5T2ZXZWVrKDEpOworCisgICAgICAgIHRlc3QudGVzdCgiIHciLCBjYWwsICIgMjMiLCBEYXRlRm9ybWF0LldFRUtfT0ZfWUVBUl9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIHd3IiwgY2FsLCAiIDIzIiwgRGF0ZUZvcm1hdC5XRUVLX09GX1lFQVJfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiB3d3d3IiwgY2FsLCAiIDAwMjMiLCBEYXRlRm9ybWF0LldFRUtfT0ZfWUVBUl9GSUVMRCk7CisKKyAgICAgICAgdGVzdC50ZXN0KCIgVyIsIGNhbCwgIiAxIiwgRGF0ZUZvcm1hdC5XRUVLX09GX01PTlRIX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgVyIsIG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk5LCBDYWxlbmRhci5OT1ZFTUJFUiwgMTQpLAorICAgICAgICAgICAgICAgICIgMyIsIERhdGVGb3JtYXQuV0VFS19PRl9NT05USF9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIFdXIiwgY2FsLCAiIDAxIiwgRGF0ZUZvcm1hdC5XRUVLX09GX01PTlRIX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgV1dXVyIsIGNhbCwgIiAwMDAxIiwgRGF0ZUZvcm1hdC5XRUVLX09GX01PTlRIX0ZJRUxEKTsKKworICAgICAgICBhc3NlcnRGYWxzZSh0ZXN0LnRlc3RzRmFpbGVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0dGluZ1RpbWV6b25lcygpIHsKKyAgICAgICAgRm9ybWF0VGVzdGVyIHRlc3QgPSBuZXcgRm9ybWF0VGVzdGVyKCk7CisgICAgICAgIENhbGVuZGFyIGNhbCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk5LCBDYWxlbmRhci5KVU5FLCAyLCAxNSwgMywgNik7CisKKyAgICAgICAgVGltZVpvbmUgdHowMDAxID0gbmV3IFNpbXBsZVRpbWVab25lKDYwMDAwLCAiT05FIE1JTlVURSIpOworICAgICAgICBUaW1lWm9uZSB0ejAxMzAgPSBuZXcgU2ltcGxlVGltZVpvbmUoNTQwMDAwMCwgIk9ORSBIT1VSLCBUSElSVFkiKTsKKyAgICAgICAgVGltZVpvbmUgdHpNaW51czAxMzAgPSBuZXcgU2ltcGxlVGltZVpvbmUoLTU0MDAwMDAsICJORUcgT05FIEhPVVIsIFRISVJUWSIpOworCisgICAgICAgIGZvcm1hdC5zZXRUaW1lWm9uZSh0ejAwMDEpOworICAgICAgICB0ZXN0LnRlc3QoIiBaIiwgY2FsLCAiICswMDAxIiwgRGF0ZUZvcm1hdC5USU1FWk9ORV9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIFpaWloiLCBjYWwsICIgKzAwMDEiLCBEYXRlRm9ybWF0LlRJTUVaT05FX0ZJRUxEKTsKKyAgICAgICAgZm9ybWF0LnNldFRpbWVab25lKHR6MDEzMCk7CisgICAgICAgIHRlc3QudGVzdCgiIFoiLCBjYWwsICIgKzAxMzAiLCBEYXRlRm9ybWF0LlRJTUVaT05FX0ZJRUxEKTsKKyAgICAgICAgZm9ybWF0LnNldFRpbWVab25lKHR6TWludXMwMTMwKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgWiIsIGNhbCwgIiAtMDEzMCIsIERhdGVGb3JtYXQuVElNRVpPTkVfRklFTEQpOworCisgICAgICAgIGZvcm1hdC5zZXRUaW1lWm9uZSh0ejAwMDEpOworICAgICAgICB0ZXN0LnRlc3QoIiB6IiwgY2FsLCAiIEdNVCswMDowMSIsIERhdGVGb3JtYXQuVElNRVpPTkVfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiB6enp6IiwgY2FsLCAiIEdNVCswMDowMSIsIERhdGVGb3JtYXQuVElNRVpPTkVfRklFTEQpOworICAgICAgICBmb3JtYXQuc2V0VGltZVpvbmUodHowMTMwKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgeiIsIGNhbCwgIiBHTVQrMDE6MzAiLCBEYXRlRm9ybWF0LlRJTUVaT05FX0ZJRUxEKTsKKyAgICAgICAgZm9ybWF0LnNldFRpbWVab25lKHR6TWludXMwMTMwKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgeiIsIGNhbCwgIiBHTVQtMDE6MzAiLCBEYXRlRm9ybWF0LlRJTUVaT05FX0ZJRUxEKTsKKworICAgICAgICBmb3JtYXQuc2V0VGltZVpvbmUoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkFtZXJpY2EvTmV3X1lvcmsiKSk7CisgICAgICAgIHRlc3QudGVzdCgiIHoiLCBjYWwsICIgRURUIiwgRGF0ZUZvcm1hdC5USU1FWk9ORV9GSUVMRCk7CisgICAgICAgIENhbGVuZGFyIHRlbXAyID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLkpBTlVBUlksIDEyKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgeiIsIHRlbXAyLCAiIEVTVCIsIERhdGVGb3JtYXQuVElNRVpPTkVfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiB6eiIsIGNhbCwgIiBFRFQiLCBEYXRlRm9ybWF0LlRJTUVaT05FX0ZJRUxEKTsKKyAgICAgICAgdGVzdC50ZXN0KCIgenp6IiwgY2FsLCAiIEVEVCIsIERhdGVGb3JtYXQuVElNRVpPTkVfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiB6enp6IiwgY2FsLCAiIEVhc3Rlcm4gRGF5bGlnaHQgVGltZSIsIERhdGVGb3JtYXQuVElNRVpPTkVfRklFTEQpOworICAgICAgICB0ZXN0LnRlc3QoIiB6enp6IiwgdGVtcDIsICIgRWFzdGVybiBTdGFuZGFyZCBUaW1lIiwgRGF0ZUZvcm1hdC5USU1FWk9ORV9GSUVMRCk7CisgICAgICAgIHRlc3QudGVzdCgiIHp6enp6IiwgY2FsLCAiIEVhc3Rlcm4gRGF5bGlnaHQgVGltZSIsIERhdGVGb3JtYXQuVElNRVpPTkVfRklFTEQpOworCisgICAgICAgIGFzc2VydEZhbHNlKHRlc3QudGVzdHNGYWlsZWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0I2Zvcm1hdChqYXZhLnV0aWwuRGF0ZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RpbWVab25lRm9ybWF0dGluZygpIHsKKyAgICAgICAgLy8gdGVzdHMgc3BlY2lmaWMgdG8gZm9ybWF0dGluZyBvZiB0aW1lem9uZXMKKyAgICAgICAgRGF0ZSBzdW1tZXJEYXRlID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLkpVTkUsIDIsIDE1LCAzLCA2KS5nZXRUaW1lKCk7CisgICAgICAgIERhdGUgd2ludGVyRGF0ZSA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk5LCBDYWxlbmRhci5KQU5VQVJZLCAxMikuZ2V0VGltZSgpOworCisgICAgICAgIEZvcm1hdFRlc3RlciB0ZXN0ID0gbmV3IEZvcm1hdFRlc3RlcigpOworICAgICAgICB0ZXN0LnZlcmlmeUZvcm1hdFRpbWV6b25lKCJHTVQtNyIsICJHTVQtMDc6MDAsIEdNVC0wNzowMCIsICItMDcwMCwgLTA3MDAiLCBzdW1tZXJEYXRlKTsKKyAgICAgICAgdGVzdC52ZXJpZnlGb3JtYXRUaW1lem9uZSgiR01ULTciLCAiR01ULTA3OjAwLCBHTVQtMDc6MDAiLCAiLTA3MDAsIC0wNzAwIiwgd2ludGVyRGF0ZSk7CisKKyAgICAgICAgdGVzdC52ZXJpZnlGb3JtYXRUaW1lem9uZSgiR01UKzE0IiwgIkdNVCsxNDowMCwgR01UKzE0OjAwIiwgIisxNDAwLCArMTQwMCIsIHN1bW1lckRhdGUpOworICAgICAgICB0ZXN0LnZlcmlmeUZvcm1hdFRpbWV6b25lKCJHTVQrMTQiLCAiR01UKzE0OjAwLCBHTVQrMTQ6MDAiLCAiKzE0MDAsICsxNDAwIiwgd2ludGVyRGF0ZSk7CisKKyAgICAgICAgdGVzdC52ZXJpZnlGb3JtYXRUaW1lem9uZSgiQW1lcmljYS9Mb3NfQW5nZWxlcyIsICJQRFQsIFBhY2lmaWMgRGF5bGlnaHQgVGltZSIsCisgICAgICAgICAgICAgICAgIi0wNzAwLCAtMDcwMCIsIHN1bW1lckRhdGUpOworICAgICAgICB0ZXN0LnZlcmlmeUZvcm1hdFRpbWV6b25lKCJBbWVyaWNhL0xvc19BbmdlbGVzIiwgIlBTVCwgUGFjaWZpYyBTdGFuZGFyZCBUaW1lIiwKKyAgICAgICAgICAgICAgICAiLTA4MDAsIC0wODAwIiwgd2ludGVyRGF0ZSk7CisKKyAgICAgICAgLy8gdGhpcyBmYWlscyBvbiB0aGUgUkkhCisgICAgICAgIHRlc3QudmVyaWZ5Rm9ybWF0VGltZXpvbmUoIkFtZXJpY2EvRGV0cm9pdCIsICJFRFQsIEVhc3Rlcm4gRGF5bGlnaHQgVGltZSIsCisgICAgICAgICAgICAgICAgIi0wNDAwLCAtMDQwMCIsIHN1bW1lckRhdGUpOworICAgICAgICB0ZXN0LnZlcmlmeUZvcm1hdFRpbWV6b25lKCJBbWVyaWNhL0RldHJvaXQiLCAiRVNULCBFYXN0ZXJuIFN0YW5kYXJkIFRpbWUiLAorICAgICAgICAgICAgICAgICItMDUwMCwgLTA1MDAiLCB3aW50ZXJEYXRlKTsKKworICAgICAgICBhc3NlcnRGYWxzZSh0ZXN0LnRlc3RzRmFpbGVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BhcnNlTGphdmFfbGFuZ19TdHJpbmdMamF2YV90ZXh0X1BhcnNlUG9zaXRpb25fMigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvcm1hdC5wYXJzZSgiMjQwIDExIDIwMDIgTWFyY2giLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlBhcnNlUG9zaXRpb24gaXMgbnVsbDogTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gcGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3JtYXQucGFyc2UobnVsbCwgbmV3IFBhcnNlUG9zaXRpb24oMCkpOworICAgICAgICAgICAgZmFpbCgiU3RyaW5nIGlzIG51bGw6IE51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIHBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldERhdGVGb3JtYXRTeW1ib2xzTGphdmFfdGV4dF9EYXRlRm9ybWF0U3ltYm9scygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQKKyAgICAgICAgLy8gamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQuc2V0RGF0ZUZvcm1hdFN5bWJvbHMoamF2YS50ZXh0LkRhdGVGb3JtYXRTeW1ib2xzKQorICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IGYxID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoImEiKTsKKyAgICAgICAgRGF0ZUZvcm1hdFN5bWJvbHMgc3ltYm9scyA9IG5ldyBEYXRlRm9ybWF0U3ltYm9scygpOworICAgICAgICBzeW1ib2xzLnNldEFtUG1TdHJpbmdzKG5ldyBTdHJpbmdbXSB7ICJtb3JuaW5nIiwgIm5pZ2h0IiB9KTsKKyAgICAgICAgZjEuc2V0RGF0ZUZvcm1hdFN5bWJvbHMoc3ltYm9scyk7CisgICAgICAgIERhdGVGb3JtYXRTeW1ib2xzIG5ld1N5bSA9IGYxLmdldERhdGVGb3JtYXRTeW1ib2xzKCk7CisgICAgICAgIGFzc2VydFRydWUoIlNldCBpbmNvcnJlY3RseSIsIG5ld1N5bS5lcXVhbHMoc3ltYm9scykpOworICAgICAgICBhc3NlcnRUcnVlKCJOb3QgYSBjbG9uZSIsIGYxLmdldERhdGVGb3JtYXRTeW1ib2xzKCkgIT0gc3ltYm9scyk7CisgICAgICAgIFN0cmluZyByZXN1bHQgPSBmMS5mb3JtYXQobmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLkpVTkUsCisgICAgICAgICAgICAgICAgMTIsIDMsIDApLmdldFRpbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHN5bWJvbHMgdXNlZCIsICJtb3JuaW5nIiwgcmVzdWx0KTsKKyAgICAgICAgc3ltYm9scy5zZXRFcmFzKG5ldyBTdHJpbmdbXSB7ICJiZWZvcmUiLCAiYWZ0ZXIiIH0pOworICAgICAgICBhc3NlcnRUcnVlKCJJZGVudGljYWwgc3ltYm9scyIsICFmMS5nZXREYXRlRm9ybWF0U3ltYm9scygpLmVxdWFscygKKyAgICAgICAgICAgICAgICBzeW1ib2xzKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYxLnNldERhdGVGb3JtYXRTeW1ib2xzKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvTG9jYWxpemVkUGF0dGVybigpIHsKKyAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuU3RyaW5nCisgICAgICAgIC8vIGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0LnRvTG9jYWxpemVkUGF0dGVybigpCisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgZjIgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgiR3lNZGtIbXNTRURGd1dhaEt6WiIsCisgICAgICAgICAgICAgICAgbmV3IExvY2FsZSgiZGUiLCAiQ0giKSk7CisgICAgICAgIFN0cmluZyBwYXR0ZXJuID0gZjIudG9Mb2NhbGl6ZWRQYXR0ZXJuKCk7CisgICAgICAgIC8vIHRoZSBkZWZhdWx0IGxvY2FsaXplZCBwYXR0ZXJuIGNoYXJhY3RlcnMgYXJlIHRoZSBzYW1lIGZvciBhbGwgbG9jYWxlcworICAgICAgICAvLyBzaW5jZSBpY3UgaGFzIGRyb3BwZWQgc3VwcG9ydCBmb3IgdGhpcy4gdGhlIGRlZmF1bHQgcGF0dGVybiBjaGFyYWN0ZXJzCisgICAgICAgIC8vIGFyZSB0aGVzZTogR3lNZGtIbXNTRURGd1dhaEt6CisgICAgICAgIC8vIElDVSBvbmx5ISB0aGlzIGZhaWxzIG9uIHRoZSBSSQorICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBwYXR0ZXJuOiAiICsgcGF0dGVybiwgcGF0dGVybgorICAgICAgICAgICAgICAgIC5lcXVhbHMoIkd5TWRrSG1zU0VERndXYWhLeloiKSk7CisKKworICAgICAgICAvLyB0ZXN0IHRoZSBuZXcgIloiIHBhdHRlcm4gY2hhcgorICAgICAgICBmMiA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCJHIHkgTSBkIFoiLCBuZXcgTG9jYWxlKCJkZSIsICJDSCIpKTsKKyAgICAgICAgcGF0dGVybiA9IGYyLnRvTG9jYWxpemVkUGF0dGVybigpOworICAgICAgICAvLyBhc3NlcnRUcnVlKCJXcm9uZyBwYXR0ZXJuOiAiICsgcGF0dGVybiwgcGF0dGVybi5lcXVhbHMoIkcgdSBNIHQgWiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcGF0dGVybjogIiArIHBhdHRlcm4sIHBhdHRlcm4uZXF1YWxzKCJHIHkgTSBkIFoiKSk7CisgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvUGF0dGVybigpIHsKKyAgICAgICAgU3RyaW5nIHBhdHRlcm4gPSAieXl5eSBtbSBkZCI7CisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgZiA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KHBhdHRlcm4pOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHBhdHRlcm46ICIgKyBwYXR0ZXJuLCBwYXR0ZXJuLCBmLnRvUGF0dGVybigpKTsKKworICAgICAgICBwYXR0ZXJuID0gIkd5TWRrSG1zU0VERndXYWhLeiI7CisgICAgICAgIGYgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgiR3lNZGtIbXNTRURGd1dhaEt6IiwgbmV3IExvY2FsZSgiZGUiLCAiQ0giKSk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHBhdHRlcm46ICIgKyBwYXR0ZXJuLCBmLnRvUGF0dGVybigpLmVxdWFscyhwYXR0ZXJuKSk7CisKKyAgICAgICAgcGF0dGVybiA9ICJHIHkgTSBkIFoiOworICAgICAgICBmID0gbmV3IFNpbXBsZURhdGVGb3JtYXQocGF0dGVybiwgbmV3IExvY2FsZSgiZGUiLCAiQ0giKSk7CisgICAgICAgIHBhdHRlcm4gPSBmLnRvUGF0dGVybigpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBwYXR0ZXJuOiAiICsgcGF0dGVybiwgZi50b1BhdHRlcm4oKS5lcXVhbHMocGF0dGVybikpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9TaW1wbGVEYXRlRm9ybWF0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS90ZXh0L1NpbXBsZURhdGVGb3JtYXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzYyOTZmZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdGV4dC9TaW1wbGVEYXRlRm9ybWF0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjMwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudGV4dDsKKworaW1wb3J0IGphdmEudGV4dC5EYXRlRm9ybWF0OworaW1wb3J0IGphdmEudGV4dC5QYXJzZVBvc2l0aW9uOworaW1wb3J0IGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0OworaW1wb3J0IGphdmEudXRpbC5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CisKK3B1YmxpYyBjbGFzcyBTaW1wbGVEYXRlRm9ybWF0VGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUaW1lWm9uZSBBTUVSSUNBX0xPU19BTkdFTEVTID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkFtZXJpY2EvTG9zX0FuZ2VsZXMiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUaW1lWm9uZSBBVVNUUkFMSUFfTE9SRF9IT1dFID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkF1c3RyYWxpYS9Mb3JkX0hvd2UiKTsKKworICAgIC8vIFRoZSBSSSBmYWlscyB0aGlzIHRlc3QuCisgICAgcHVibGljIHZvaWQgdGVzdDJEaWdpdFllYXJTdGFydElzQ2xvbmVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgdGhhdCBnZXQyRGlnaXRZZWFyU3RhcnQgcmV0dXJucyBhIGNsb25lLgorICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IHNkZiA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCk7CisgICAgICAgIERhdGUgb3JpZ2luYWxEYXRlID0gc2RmLmdldDJEaWdpdFllYXJTdGFydCgpOworICAgICAgICBhc3NlcnROb3RTYW1lKHNkZi5nZXQyRGlnaXRZZWFyU3RhcnQoKSwgb3JpZ2luYWxEYXRlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNkZi5nZXQyRGlnaXRZZWFyU3RhcnQoKSwgb3JpZ2luYWxEYXRlKTsKKyAgICAgICAgb3JpZ2luYWxEYXRlLnNldFRpbWUoMCk7CisgICAgICAgIGFzc2VydEZhbHNlKHNkZi5nZXQyRGlnaXRZZWFyU3RhcnQoKS5lcXVhbHMob3JpZ2luYWxEYXRlKSk7CisgICAgICAgIC8vIFRlc3QgdGhhdCBzZXQyRGlnaXRZZWFyU3RhcnQgdGFrZXMgYSBjbG9uZS4KKyAgICAgICAgRGF0ZSBuZXdEYXRlID0gbmV3IERhdGUoKTsKKyAgICAgICAgc2RmLnNldDJEaWdpdFllYXJTdGFydChuZXdEYXRlKTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShzZGYuZ2V0MkRpZ2l0WWVhclN0YXJ0KCksIG5ld0RhdGUpOworICAgICAgICBhc3NlcnRFcXVhbHMoc2RmLmdldDJEaWdpdFllYXJTdGFydCgpLCBuZXdEYXRlKTsKKyAgICAgICAgbmV3RGF0ZS5zZXRUaW1lKDApOworICAgICAgICBhc3NlcnRGYWxzZShzZGYuZ2V0MkRpZ2l0WWVhclN0YXJ0KCkuZXF1YWxzKG5ld0RhdGUpKTsKKyAgICB9CisKKyAgICAvLyBUaGUgUkkgZmFpbHMgdGhpcyB0ZXN0IGJlY2F1c2UgdGhpcyBpcyBhbiBJQ1UtY29tcGF0aWJsZSBBbmRyb2lkIGV4dGVuc2lvbi4KKyAgICAvLyBOZWNlc3NhcnkgZm9yIGNvcnJlY3QgbG9jYWxpemF0aW9uIGluIHZhcmlvdXMgbGFuZ3VhZ2VzIChodHRwOi8vYi8yNjMzNDE0KS4KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RhbmRBbG9uZU5hbWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIExvY2FsZSBlbiA9IExvY2FsZS5FTkdMSVNIOworICAgICAgICBMb2NhbGUgcGwgPSBuZXcgTG9jYWxlKCJwbCIpOworICAgICAgICBMb2NhbGUgcnUgPSBuZXcgTG9jYWxlKCJydSIpOworCisgICAgICAgIGFzc2VydEVxdWFscygiSmFudWFyeSIsIGZvcm1hdERhdGUoZW4sICJNTU1NIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkphbnVhcnkiLCBmb3JtYXREYXRlKGVuLCAiTExMTCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdHljem5pYSIsIGZvcm1hdERhdGUocGwsICJNTU1NIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoInN0eWN6ZVx1MDE0NCIsIGZvcm1hdERhdGUocGwsICJMTExMIikpOworCisgICAgICAgIGFzc2VydEVxdWFscygiVGh1cnNkYXkiLCBmb3JtYXREYXRlKGVuLCAiRUVFRSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaHVyc2RheSIsIGZvcm1hdERhdGUoZW4sICJjY2NjIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlx1MDQ0N1x1MDQzNVx1MDQ0Mlx1MDQzMlx1MDQzNVx1MDQ0MFx1MDQzMyIsIGZvcm1hdERhdGUocnUsICJFRUVFIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlx1MDQyN1x1MDQzNVx1MDQ0Mlx1MDQzMlx1MDQzNVx1MDQ0MFx1MDQzMyIsIGZvcm1hdERhdGUocnUsICJjY2NjIikpOworCisgICAgICAgIGFzc2VydEVxdWFscyhDYWxlbmRhci5KVU5FLCBwYXJzZURhdGUoZW4sICJ5eXl5LU1NTU0tZGQiLCAiMTk4MC1KdW5lLTEyIikuZ2V0KENhbGVuZGFyLk1PTlRIKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDYWxlbmRhci5KVU5FLCBwYXJzZURhdGUoZW4sICJ5eXl5LUxMTEwtZGQiLCAiMTk4MC1KdW5lLTEyIikuZ2V0KENhbGVuZGFyLk1PTlRIKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDYWxlbmRhci5KVU5FLCBwYXJzZURhdGUocGwsICJ5eXl5LU1NTU0tZGQiLCAiMTk4MC1jemVyd2NhLTEyIikuZ2V0KENhbGVuZGFyLk1PTlRIKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDYWxlbmRhci5KVU5FLCBwYXJzZURhdGUocGwsICJ5eXl5LUxMTEwtZGQiLCAiMTk4MC1jemVyd2llYy0xMiIpLmdldChDYWxlbmRhci5NT05USCkpOworCisgICAgICAgIGFzc2VydEVxdWFscyhDYWxlbmRhci5UVUVTREFZLCBwYXJzZURhdGUoZW4sICJFRUVFIiwgIlR1ZXNkYXkiKS5nZXQoQ2FsZW5kYXIuREFZX09GX1dFRUspKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENhbGVuZGFyLlRVRVNEQVksIHBhcnNlRGF0ZShlbiwgImNjY2MiLCAiVHVlc2RheSIpLmdldChDYWxlbmRhci5EQVlfT0ZfV0VFSykpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ2FsZW5kYXIuVFVFU0RBWSwgcGFyc2VEYXRlKHJ1LCAiRUVFRSIsICJcdTA0MzJcdTA0NDJcdTA0M2VcdTA0NDBcdTA0M2RcdTA0MzhcdTA0M2EiKS5nZXQoQ2FsZW5kYXIuREFZX09GX1dFRUspKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENhbGVuZGFyLlRVRVNEQVksIHBhcnNlRGF0ZShydSwgImNjY2MiLCAiXHUwNDEyXHUwNDQyXHUwNDNlXHUwNDQwXHUwNDNkXHUwNDM4XHUwNDNhIikuZ2V0KENhbGVuZGFyLkRBWV9PRl9XRUVLKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdDIwMzgoKSB7CisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgZm9ybWF0ID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoIkVFRSBNTU0gZGQgSEg6bW06c3MgeXl5eSIpOworICAgICAgICBmb3JtYXQuc2V0VGltZVpvbmUoVGltZVpvbmUuZ2V0VGltZVpvbmUoIlVUQyIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlN1biBOb3YgMjQgMTc6MzE6NDQgMTgzMyIsCisgICAgICAgICAgICAgICAgZm9ybWF0LmZvcm1hdChuZXcgRGF0ZSgoKGxvbmcpIEludGVnZXIuTUlOX1ZBTFVFICsgSW50ZWdlci5NSU5fVkFMVUUpICogMTAwMEwpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRnJpIERlYyAxMyAyMDo0NTo1MiAxOTAxIiwKKyAgICAgICAgICAgICAgICBmb3JtYXQuZm9ybWF0KG5ldyBEYXRlKEludGVnZXIuTUlOX1ZBTFVFICogMTAwMEwpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGh1IEphbiAwMSAwMDowMDowMCAxOTcwIiwKKyAgICAgICAgICAgICAgICBmb3JtYXQuZm9ybWF0KG5ldyBEYXRlKDBMKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlR1ZSBKYW4gMTkgMDM6MTQ6MDcgMjAzOCIsCisgICAgICAgICAgICAgICAgZm9ybWF0LmZvcm1hdChuZXcgRGF0ZShJbnRlZ2VyLk1BWF9WQUxVRSAqIDEwMDBMKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlN1biBGZWIgMDcgMDY6Mjg6MTYgMjEwNiIsCisgICAgICAgICAgICAgICAgZm9ybWF0LmZvcm1hdChuZXcgRGF0ZSgoMkwgKyBJbnRlZ2VyLk1BWF9WQUxVRSArIEludGVnZXIuTUFYX1ZBTFVFKSAqIDEwMDBMKSkpOworICAgIH0KKyAgICBwcml2YXRlIFN0cmluZyBmb3JtYXREYXRlKExvY2FsZSBsLCBTdHJpbmcgZm10KSB7CisgICAgICAgIERhdGVGb3JtYXQgZGF0ZUZvcm1hdCA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KGZtdCwgbCk7CisgICAgICAgIGRhdGVGb3JtYXQuc2V0VGltZVpvbmUoVGltZVpvbmUuZ2V0VGltZVpvbmUoIlVUQyIpKTsKKyAgICAgICAgcmV0dXJuIGRhdGVGb3JtYXQuZm9ybWF0KG5ldyBEYXRlKDApKTsKKyAgICB9CisKKyAgICBwcml2YXRlIENhbGVuZGFyIHBhcnNlRGF0ZShMb2NhbGUgbCwgU3RyaW5nIGZtdCwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgc2RmID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoZm10LCBsKTsKKyAgICAgICAgUGFyc2VQb3NpdGlvbiBwcCA9IG5ldyBQYXJzZVBvc2l0aW9uKDApOworICAgICAgICBEYXRlIGQgPSBzZGYucGFyc2UodmFsdWUsIHBwKTsKKyAgICAgICAgaWYgKGQgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbChwcC50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICBDYWxlbmRhciBjID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoVGltZVpvbmUuZ2V0VGltZVpvbmUoIlVUQyIpKTsKKyAgICAgICAgYy5zZXRUaW1lKGQpOworICAgICAgICByZXR1cm4gYzsKKyAgICB9CisKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTEzNDIwCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNpbmdVbmNvbW1vblRpbWVab25lQWJicmV2aWF0aW9ucygpIHsKKyAgICAgICAgU3RyaW5nIGZtdCA9ICJ5eXl5LU1NLWRkIEhIOm1tOnNzLlNTUyB6IjsKKyAgICAgICAgU3RyaW5nIGRhdGUgPSAiMjAxMC0xMi0yMyAxMjo0NDo1Ny4wIENFVCI7CisgICAgICAgIC8vIElDVSBjb25zaWRlcnMgIkNFVCIgKENlbnRyYWwgRXVyb3BlYW4gVGltZSkgdG8gYmUgY29tbW9uIGluIEJyaXRhaW4uLi4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEyOTMxMDQ2OTcwMDBMLCBwYXJzZURhdGUoTG9jYWxlLlVLLCBmbXQsIGRhdGUpLmdldFRpbWVJbk1pbGxpcygpKTsKKyAgICAgICAgLy8gLi4uYnV0IG5vdCBpbiB0aGUgVVMuIENoZWNrIHdlIGNhbiBwYXJzZSBzdWNoIGEgZGF0ZSBhbnl3YXkuCisgICAgICAgIGFzc2VydEVxdWFscygxMjkzMTA0Njk3MDAwTCwgcGFyc2VEYXRlKExvY2FsZS5VUywgZm10LCBkYXRlKS5nZXRUaW1lSW5NaWxsaXMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdHRpbmdVbmNvbW1vblRpbWVab25lQWJicmV2aWF0aW9ucygpIHsKKyAgICAgICAgLy8gSW4gSG9uZXljb21iLCBvbmx5IG9uZSBPbHNvbiBpZCB3YXMgYXNzb2NpYXRlZCB3aXRoIENFVCAob3IgYW55CisgICAgICAgIC8vIG90aGVyICJ1bmNvbW1vbiIgYWJicmV2aWF0aW9uKS4KKyAgICAgICAgU3RyaW5nIGZtdCA9ICJ5eXl5LU1NLWRkIEhIOm1tOnNzLlNTUyB6IjsKKyAgICAgICAgU3RyaW5nIGRhdGUgPSAiMTk3MC0wMS0wMSAwMTowMDowMC4wMDAgQ0VUIjsKKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBzZGYgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdChmbXQsIExvY2FsZS5VUyk7CisgICAgICAgIHNkZi5zZXRUaW1lWm9uZShUaW1lWm9uZS5nZXRUaW1lWm9uZSgiRXVyb3BlL0JlcmxpbiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGRhdGUsIHNkZi5mb3JtYXQobmV3IERhdGUoMCkpKTsKKyAgICAgICAgc2RmID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoZm10LCBMb2NhbGUuVVMpOworICAgICAgICBzZGYuc2V0VGltZVpvbmUoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkV1cm9wZS9adXJpY2giKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhkYXRlLCBzZGYuZm9ybWF0KG5ldyBEYXRlKDApKSk7CisgICAgfQorCisgICAgLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD04MjU4CisgICAgcHVibGljIHZvaWQgdGVzdFRpbWVab25lRm9ybWF0dGluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEYXRlIGVwb2NoID0gbmV3IERhdGUoMCk7CisKKyAgICAgICAgLy8gQ3JlYXRlIGEgU2ltcGxlRGF0ZUZvcm1hdCB0aGF0IGRlZmF1bHRzIHRvIEFtZXJpY2EvQ2hpY2Fnby4uLgorICAgICAgICBUaW1lWm9uZS5zZXREZWZhdWx0KFRpbWVab25lLmdldFRpbWVab25lKCJBbWVyaWNhL0NoaWNhZ28iKSk7CisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgc2RmID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoInl5eXktTU0tZGQgSEg6bW06c3MgWiIpOworICAgICAgICAvLyBXZSBzaG91bGQgc2VlIHNvbWV0aGluZyBhcHByb3ByaWF0ZSB0byBBbWVyaWNhL0NoaWNhZ28uLi4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxOTY5LTEyLTMxIDE4OjAwOjAwIC0wNjAwIiwgc2RmLmZvcm1hdChlcG9jaCkpOworICAgICAgICAvLyBXZSBjYW4gc2V0IGFueSBUaW1lWm9uZSB3ZSB3YW50OgorICAgICAgICBzZGYuc2V0VGltZVpvbmUoQU1FUklDQV9MT1NfQU5HRUxFUyk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTk2OS0xMi0zMSAxNjowMDowMCAtMDgwMCIsIHNkZi5mb3JtYXQoZXBvY2gpKTsKKyAgICAgICAgc2RmLnNldFRpbWVab25lKFRpbWVab25lLmdldFRpbWVab25lKCJVVEMiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTk3MC0wMS0wMSAwMDowMDowMCArMDAwMCIsIHNkZi5mb3JtYXQoZXBvY2gpKTsKKworICAgICAgICAvLyBBIG5ldyBTaW1wbGVEYXRlRm9ybWF0IHdpbGwgZGVmYXVsdCB0byBBbWVyaWNhL0NoaWNhZ28uLi4KKyAgICAgICAgc2RmID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoInl5eXktTU0tZGQgSEg6bW06c3MgWiIpOworICAgICAgICAvLyAuLi5hbmQgcGFyc2luZyBhbiBBbWVyaWNhL0xvc19BbmdlbGVzIHRpbWUgd2lsbCAqbm90KiBjaGFuZ2UgdGhhdC4uLgorICAgICAgICBzZGYucGFyc2UoIjIwMTAtMTItMDMgMDA6MDA6MDAgLTA4MDAiKTsKKyAgICAgICAgLy8gLi4uc28gb3VyIHRpbWUgem9uZSBoZXJlIGlzICJBbWVyaWNhL0NoaWNhZ28iOgorICAgICAgICBhc3NlcnRFcXVhbHMoIjE5NjktMTItMzEgMTg6MDA6MDAgLTA2MDAiLCBzZGYuZm9ybWF0KGVwb2NoKSk7CisgICAgICAgIC8vIFdlIGNhbiBzZXQgYW55IFRpbWVab25lIHdlIHdhbnQ6CisgICAgICAgIHNkZi5zZXRUaW1lWm9uZShBTUVSSUNBX0xPU19BTkdFTEVTKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxOTY5LTEyLTMxIDE2OjAwOjAwIC0wODAwIiwgc2RmLmZvcm1hdChlcG9jaCkpOworICAgICAgICBzZGYuc2V0VGltZVpvbmUoVGltZVpvbmUuZ2V0VGltZVpvbmUoIlVUQyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxOTcwLTAxLTAxIDAwOjAwOjAwICswMDAwIiwgc2RmLmZvcm1hdChlcG9jaCkpOworCisgICAgICAgIHNkZiA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCJ5eXl5LU1NLWRkIEhIOm1tOnNzIik7CisgICAgICAgIHNkZi5zZXRUaW1lWm9uZShUaW1lWm9uZS5nZXRUaW1lWm9uZSgiVVRDIikpOworICAgICAgICBEYXRlIGRhdGUgPSBzZGYucGFyc2UoIjIwMTAtMDctMDggMDI6NDQ6NDgiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEyNzg1NTcwODgwMDBMLCBkYXRlLmdldFRpbWUoKSk7CisgICAgICAgIHNkZiA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCJ5eXl5LU1NLWRkJ1QnSEg6bW06c3NaIik7CisgICAgICAgIHNkZi5zZXRUaW1lWm9uZShBTUVSSUNBX0xPU19BTkdFTEVTKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIyMDEwLTA3LTA3VDE5OjQ0OjQ4LTA3MDAiLCBzZGYuZm9ybWF0KGRhdGUpKTsKKyAgICAgICAgc2RmLnNldFRpbWVab25lKFRpbWVab25lLmdldFRpbWVab25lKCJVVEMiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMjAxMC0wNy0wOFQwMjo0NDo0OCswMDAwIiwgc2RmLmZvcm1hdChkYXRlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWZyaWNhL0NhaXJvIHN0YW5kYXJkIHRpbWUgaXMgRUVUIGFuZCBkYXlsaWdodCB0aW1lIGlzIEVFU1QuIFRoZXkgbm8KKyAgICAgKiBsb25nZXIgdXNlIHRoZWlyIERTVCB6b25lIGJ1dCB3ZSBzaG91bGQgY29udGludWUgdG8gcGFyc2UgaXQgcHJvcGVybHkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE9ic29sZXRlRHN0Wm9uZU5hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBmb3JtYXQgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgieXl5eS1NTS1kZCdUJ0hIOm1tIHp6enoiKTsKKyAgICAgICAgRGF0ZSBub3JtYWwgPSBmb3JtYXQucGFyc2UoIjE5NzAtMDEtMDFUMDA6MDAgRUVUIik7CisgICAgICAgIERhdGUgZHN0ID0gZm9ybWF0LnBhcnNlKCIxOTcwLTAxLTAxVDAwOjAwIEVFU1QiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDYwICogNjAgKiAxMDAwLCBub3JtYWwuZ2V0VGltZSgpIC0gZHN0LmdldFRpbWUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERzdFpvbmVOYW1lV2l0aE5vbkRzdFRpbWVzdGFtcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IGZvcm1hdCA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCJ5eXl5LU1NLWRkJ1QnSEg6bW0genp6eiIpOworICAgICAgICBDYWxlbmRhciBjYWxlbmRhciA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcihBTUVSSUNBX0xPU19BTkdFTEVTKTsKKyAgICAgICAgY2FsZW5kYXIuc2V0VGltZShmb3JtYXQucGFyc2UoIjIwMTEtMDYtMjFUMTA6MDAgUGFjaWZpYyBTdGFuZGFyZCBUaW1lIikpOyAvLyAxODowMCBHTVQtOAorICAgICAgICBhc3NlcnRFcXVhbHMoMTEsIGNhbGVuZGFyLmdldChDYWxlbmRhci5IT1VSX09GX0RBWSkpOyAvLyAxODowMCBHTVQtNworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLk1JTlVURSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROb25Ec3Rab25lTmFtZVdpdGhEc3RUaW1lc3RhbXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBmb3JtYXQgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgieXl5eS1NTS1kZCdUJ0hIOm1tIHp6enoiKTsKKyAgICAgICAgQ2FsZW5kYXIgY2FsZW5kYXIgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoQU1FUklDQV9MT1NfQU5HRUxFUyk7CisgICAgICAgIGNhbGVuZGFyLnNldFRpbWUoZm9ybWF0LnBhcnNlKCIyMDEwLTEyLTIxVDEwOjAwIFBhY2lmaWMgRGF5bGlnaHQgVGltZSIpKTsgLy8gMTc6MDAgR01ULTcKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDksIGNhbGVuZGFyLmdldChDYWxlbmRhci5IT1VSX09GX0RBWSkpOyAvLyAxNzowMCBHTVQtOAorICAgICAgICBhc3NlcnRFcXVhbHMoMCwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLk1JTlVURSkpOworICAgIH0KKworICAgIC8vIGh0dHA6Ly9iLzQ3MjM0MTIKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RHN0Wm9uZVdpdGhOb25Ec3RUaW1lc3RhbXBGb3JOb25Ib3VyRHN0Wm9uZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IGZvcm1hdCA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCJ5eXl5LU1NLWRkJ1QnSEg6bW0genp6eiIpOworICAgICAgICBDYWxlbmRhciBjYWxlbmRhciA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcihBVVNUUkFMSUFfTE9SRF9IT1dFKTsKKyAgICAgICAgY2FsZW5kYXIuc2V0VGltZShmb3JtYXQucGFyc2UoIjIwMTEtMDYtMjFUMjA6MDAgTG9yZCBIb3dlIERheWxpZ2h0IFRpbWUiKSk7IC8vIDk6MDAgR01UKzExCisgICAgICAgIGFzc2VydEVxdWFscygxOSwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkhPVVJfT0ZfREFZKSk7IC8vIDk6MDAgR01UKzEwOjMwCisgICAgICAgIGFzc2VydEVxdWFscygzMCwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLk1JTlVURSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROb25Ec3Rab25lV2l0aERzdFRpbWVzdGFtcEZvck5vbkhvdXJEc3Rab25lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgZm9ybWF0ID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoInl5eXktTU0tZGQnVCdISDptbSB6enp6Iik7CisgICAgICAgIENhbGVuZGFyIGNhbGVuZGFyID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKEFVU1RSQUxJQV9MT1JEX0hPV0UpOworICAgICAgICBjYWxlbmRhci5zZXRUaW1lKGZvcm1hdC5wYXJzZSgiMjAxMC0xMi0yMVQxOTozMCBMb3JkIEhvd2UgU3RhbmRhcmQgVGltZSIpKTsgLy85OjAwIEdNVCsxMDozMAorICAgICAgICBhc3NlcnRFcXVhbHMoMjAsIGNhbGVuZGFyLmdldChDYWxlbmRhci5IT1VSX09GX0RBWSkpOyAvLyA5OjAwIEdNVCsxMTowMAorICAgICAgICBhc3NlcnRFcXVhbHMoMCwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLk1JTlVURSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RMb2NhbGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIEp1c3QgcnVuIHRocm91Z2ggdGhlbSBhbGwuIEhhbmR5IGFzIGEgcG9vciBtYW4ncyBiZW5jaG1hcmssIGFuZCBhIHNhbml0eSBjaGVjay4KKyAgICAgICAgZm9yIChMb2NhbGUgbCA6IExvY2FsZS5nZXRBdmFpbGFibGVMb2NhbGVzKCkpIHsKKyAgICAgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgc2RmID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoInl5eXktTU0tZGQgSEg6bW06c3Mgenp6eiIsIGwpOworICAgICAgICAgICAgc2RmLmZvcm1hdChuZXcgRGF0ZSgwKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTE0OTYzCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlVGltZXpvbmVPbmx5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG5ldyBTaW1wbGVEYXRlRm9ybWF0KCJ6IiwgTG9jYWxlLkZSQU5DRSkucGFyc2UoIlVUQyIpOworICAgICAgICBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgieiIsIExvY2FsZS5VUykucGFyc2UoIlVUQyIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9CaXRTZXRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvQml0U2V0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ5OThhMDcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvQml0U2V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjM0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uTG9uZ0J1ZmZlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5CaXRTZXQ7CisKK3B1YmxpYyBjbGFzcyBCaXRTZXRUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIEZyb20gdGhlIFJJIGphdmFkb2MuCisgICAgICAgIEJpdFNldCBicyA9IG5ldyBCaXRTZXQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ7fSIsIGJzLnRvU3RyaW5nKCkpOworICAgICAgICBicy5zZXQoMik7CisgICAgICAgIGFzc2VydEVxdWFscygiezJ9IiwgYnMudG9TdHJpbmcoKSk7CisgICAgICAgIGJzLnNldCg0KTsKKyAgICAgICAgYnMuc2V0KDEwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ7MiwgNCwgMTB9IiwgYnMudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhc3NlcnRCaXRTZXQoQml0U2V0IGJzLCBsb25nW10gbG9uZ3MsIFN0cmluZyBzKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNjQgKiBsb25ncy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGJzLnRvU3RyaW5nKCksICgobG9uZ3NbaSAvIDY0XSAmICgxTCA8PCAoaSAlIDY0KSkpICE9IDApLCBicy5nZXQoaSkpOworICAgICAgICB9CisgICAgICAgIGludCBjYXJkaW5hbGl0eSA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbG9uZ3MubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIGNhcmRpbmFsaXR5ICs9IExvbmcuYml0Q291bnQobG9uZ3NbaV0pOworICAgICAgICB9CisgICAgICAgIGlmIChjYXJkaW5hbGl0eSAhPSAwKSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShicy5pc0VtcHR5KCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShicy5pc0VtcHR5KCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyhjYXJkaW5hbGl0eSwgYnMuY2FyZGluYWxpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg2NCAqIGxvbmdzLmxlbmd0aCwgYnMuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMsIGJzLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYXNzZXJ0Qml0U2V0KGxvbmdbXSBsb25ncywgU3RyaW5nIHMpIHsKKyAgICAgICAgLy8gVGVzdCBCaXRTZXQudmFsdWVPZihsb25nW10pLgorICAgICAgICBhc3NlcnRCaXRTZXQoQml0U2V0LnZhbHVlT2YobG9uZ3MpLCBsb25ncywgcyk7CisgICAgICAgIC8vIFRlc3QgQml0U2V0LnZhbHVlT2YoTG9uZ0J1ZmZlcikuCisgICAgICAgIGFzc2VydEJpdFNldChCaXRTZXQudmFsdWVPZihMb25nQnVmZmVyLndyYXAobG9uZ3MpKSwgbG9uZ3MsIHMpOworICAgICAgICAvLyBTdXJyb3VuZCAnbG9uZ3MnIHdpdGgganVuayBzZXQgYml0cyBidXQgZXhjbHVkZSB0aGVtIGZyb20gdGhlIExvbmdCdWZmZXIuCisgICAgICAgIGxvbmdbXSBwYWRkZWRMb25ncyA9IG5ldyBsb25nWzEgKyBsb25ncy5sZW5ndGggKyAxXTsKKyAgICAgICAgcGFkZGVkTG9uZ3NbMF0gPSBwYWRkZWRMb25nc1twYWRkZWRMb25ncy5sZW5ndGggLSAxXSA9IC0xTDsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShsb25ncywgMCwgcGFkZGVkTG9uZ3MsIDEsIGxvbmdzLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEJpdFNldChCaXRTZXQudmFsdWVPZihMb25nQnVmZmVyLndyYXAocGFkZGVkTG9uZ3MsIDEsIGxvbmdzLmxlbmd0aCkpLCBsb25ncywgcyk7CisKKyAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGUgbG9uZ1tdIGlzIGNvcGllZC4KKyAgICAgICAgaWYgKGxvbmdzLmxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgIEJpdFNldCBvcmlnaW5hbCA9IEJpdFNldC52YWx1ZU9mKGxvbmdzKTsKKyAgICAgICAgICAgIGxvbmdzWzBdID0gfmxvbmdzWzBdOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoQml0U2V0LnZhbHVlT2YobG9uZ3MpLmVxdWFscyhvcmlnaW5hbCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF92YWx1ZU9mX2xvbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0Qml0U2V0KG5ldyBsb25nWzBdLCAie30iKTsKKyAgICAgICAgYXNzZXJ0Qml0U2V0KG5ldyBsb25nW10geyAxTCB9LCAiezB9Iik7CisgICAgICAgIGFzc2VydEJpdFNldChuZXcgbG9uZ1tdIHsgMHgxMTFMIH0sICJ7MCwgNCwgOH0iKTsKKyAgICAgICAgYXNzZXJ0Qml0U2V0KG5ldyBsb25nW10geyAweDEwMUwsIDB4NDAwMDAwMDAwMDAwMDAwMEwgfSwgInswLCA4LCAxMjZ9Iik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhc3NlcnRCaXRTZXQoQml0U2V0IGJzLCBieXRlW10gYnl0ZXMsIFN0cmluZyBzKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgOCAqIGJ5dGVzLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYnMudG9TdHJpbmcoKSwgKChieXRlc1tpIC8gOF0gJiAoMUwgPDwgKGkgJSA4KSkpICE9IDApLCBicy5nZXQoaSkpOworICAgICAgICB9CisgICAgICAgIGludCBjYXJkaW5hbGl0eSA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIGNhcmRpbmFsaXR5ICs9IEludGVnZXIuYml0Q291bnQoKChpbnQpIGJ5dGVzW2ldKSAmIDB4ZmYpOworICAgICAgICB9CisgICAgICAgIGlmIChjYXJkaW5hbGl0eSAhPSAwKSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShicy5pc0VtcHR5KCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShicy5pc0VtcHR5KCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyhjYXJkaW5hbGl0eSwgYnMuY2FyZGluYWxpdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhyb3VuZFVwKDggKiBieXRlcy5sZW5ndGgsIDY0KSwgYnMuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMsIGJzLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGludCByb3VuZFVwKGludCBuLCBpbnQgbXVsdGlwbGUpIHsKKyAgICAgICAgcmV0dXJuIChuID09IDApID8gMCA6ICgobiArIG11bHRpcGxlIC0gMSkgLyBtdWx0aXBsZSkgKiBtdWx0aXBsZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGFzc2VydEJpdFNldChieXRlW10gYnl0ZXMsIFN0cmluZyBzKSB7CisgICAgICAgIC8vIFRlc3QgQml0U2V0LnZhbHVlT2YoYnl0ZVtdKS4KKyAgICAgICAgYXNzZXJ0Qml0U2V0KEJpdFNldC52YWx1ZU9mKGJ5dGVzKSwgYnl0ZXMsIHMpOworICAgICAgICAvLyBUZXN0IEJpdFNldC52YWx1ZU9mKEJ5dGVCdWZmZXIpLgorICAgICAgICBhc3NlcnRCaXRTZXQoQml0U2V0LnZhbHVlT2YoQnl0ZUJ1ZmZlci53cmFwKGJ5dGVzKSksIGJ5dGVzLCBzKTsKKyAgICAgICAgLy8gU3Vycm91bmQgJ2J5dGVzJyB3aXRoIGp1bmsgc2V0IGJpdHMgYnV0IGV4Y2x1ZGUgdGhlbSBmcm9tIHRoZSBCeXRlQnVmZmVyLgorICAgICAgICBieXRlW10gcGFkZGVkQnl0ZXMgPSBuZXcgYnl0ZVsxICsgYnl0ZXMubGVuZ3RoICsgMV07CisgICAgICAgIHBhZGRlZEJ5dGVzWzBdID0gcGFkZGVkQnl0ZXNbcGFkZGVkQnl0ZXMubGVuZ3RoIC0gMV0gPSAoYnl0ZSkgLTE7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnl0ZXMsIDAsIHBhZGRlZEJ5dGVzLCAxLCBieXRlcy5sZW5ndGgpOworICAgICAgICBhc3NlcnRCaXRTZXQoQml0U2V0LnZhbHVlT2YoQnl0ZUJ1ZmZlci53cmFwKHBhZGRlZEJ5dGVzLCAxLCBieXRlcy5sZW5ndGgpKSwgYnl0ZXMsIHMpOworCisgICAgICAgIC8vIENoZWNrIHRoYXQgdGhlIGJ5dGVbXSBpcyBjb3BpZWQuCisgICAgICAgIGlmIChieXRlcy5sZW5ndGggPiAwKSB7CisgICAgICAgICAgICBCaXRTZXQgb3JpZ2luYWwgPSBCaXRTZXQudmFsdWVPZihieXRlcyk7CisgICAgICAgICAgICBieXRlc1swXSA9IChieXRlKSB+Ynl0ZXNbMF07CisgICAgICAgICAgICBhc3NlcnRGYWxzZShCaXRTZXQudmFsdWVPZihieXRlcykuZXF1YWxzKG9yaWdpbmFsKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3ZhbHVlT2ZfYnl0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBOb3RoaW5nLi4uCisgICAgICAgIGFzc2VydEJpdFNldChuZXcgYnl0ZVswXSwgInt9Iik7CisgICAgICAgIC8vIExlc3MgdGhhbiBhIGxvbmcuLi4KKyAgICAgICAgYXNzZXJ0Qml0U2V0KG5ldyBieXRlW10geyAweDAxIH0sICJ7MH0iKTsKKyAgICAgICAgYXNzZXJ0Qml0U2V0KG5ldyBieXRlW10geyAweDAxLCAweDExIH0sICJ7MCwgOCwgMTJ9Iik7CisgICAgICAgIGFzc2VydEJpdFNldChuZXcgYnl0ZVtdIHsgMHgwMSwgMHgwMSwgMHgwMCwgMHgwMCwgMHgwMSB9LCAiezAsIDgsIDMyfSIpOworICAgICAgICAvLyBFeGFjdGx5IG9uZSBsb25nLi4uLgorICAgICAgICBhc3NlcnRCaXRTZXQobmV3IGJ5dGVbXSB7IDB4MDEsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIChieXRlKSAweDgwIH0sICJ7MCwgNjN9Iik7CisgICAgICAgIC8vIE9uZSBsb25nIGFuZCBhIGJ5dGUgbGVmdCBvdmVyLi4uCisgICAgICAgIGFzc2VydEJpdFNldChuZXcgYnl0ZVtdIHsgMHgwMSwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMSB9LCAiezAsIDY0fSIpOworICAgICAgICAvLyBUd28gbG9uZ3MuLi4KKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbXSB7IDB4MDEsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIChieXRlKSAweDgwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMSwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgKGJ5dGUpIDB4ODAgfTsKKyAgICAgICAgYXNzZXJ0Qml0U2V0KGJ5dGVzLCAiezAsIDYzLCA2NCwgMTI3fSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9Mb25nQXJyYXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbXSIsIEFycmF5cy50b1N0cmluZyhCaXRTZXQudmFsdWVPZihuZXcgbG9uZ1swXSkudG9Mb25nQXJyYXkoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlsxXSIsIEFycmF5cy50b1N0cmluZyhCaXRTZXQudmFsdWVPZihuZXcgbG9uZ1tdIHsgMSB9KS50b0xvbmdBcnJheSgpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWzEsIDJdIiwgQXJyYXlzLnRvU3RyaW5nKEJpdFNldC52YWx1ZU9mKG5ldyBsb25nW10geyAxLCAyIH0pLnRvTG9uZ0FycmF5KCkpKTsKKworICAgICAgICAvLyBDaGVjayB0aGF0IHdlJ3JlIG5vdCByZXR1cm5pbmcgdHJhaWxpbmcgZW1wdHkgc3BhY2UuCisgICAgICAgIGFzc2VydEVxdWFscygiW10iLCBBcnJheXMudG9TdHJpbmcobmV3IEJpdFNldCgxMjgpLnRvTG9uZ0FycmF5KCkpKTsKKyAgICAgICAgQml0U2V0IGJzID0gbmV3IEJpdFNldCgpOworICAgICAgICBicy5zZXQoMCk7CisgICAgICAgIGJzLnNldCg2NCwgNjYpOworICAgICAgICBicy5jbGVhcig2NCwgNjYpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlsxXSIsIEFycmF5cy50b1N0cmluZyhicy50b0xvbmdBcnJheSgpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90b0J5dGVBcnJheSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoIltdIiwgQXJyYXlzLnRvU3RyaW5nKEJpdFNldC52YWx1ZU9mKG5ldyBsb25nWzBdKS50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWzFdIiwgQXJyYXlzLnRvU3RyaW5nKEJpdFNldC52YWx1ZU9mKG5ldyBsb25nW10geyAxIH0pLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbLTE3LCAtNTEsIC04NSwgLTExMiwgMTIwLCA4NiwgNTIsIDE4XSIsCisgICAgICAgICAgICAgICAgQXJyYXlzLnRvU3RyaW5nKEJpdFNldC52YWx1ZU9mKG5ldyBsb25nW10geyAweDEyMzQ1Njc4OTBhYmNkZWZMIH0pLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMl0iLAorICAgICAgICAgICAgICAgIEFycmF5cy50b1N0cmluZyhCaXRTZXQudmFsdWVPZihuZXcgbG9uZ1tdIHsgMSwgMiB9KS50b0J5dGVBcnJheSgpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9wcmV2aW91c1NldEJpdCgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBuZXcgQml0U2V0KCkucHJldmlvdXNTZXRCaXQoNjY2KSk7CisKKyAgICAgICAgQml0U2V0IGJzOworCisgICAgICAgIGJzID0gbmV3IEJpdFNldCgpOworICAgICAgICBicy5zZXQoMzIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMzIsIGJzLnByZXZpb3VzU2V0Qml0KDk5OSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMzIsIGJzLnByZXZpb3VzU2V0Qml0KDMzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzMiwgYnMucHJldmlvdXNTZXRCaXQoMzIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBicy5wcmV2aW91c1NldEJpdCgzMSkpOworCisgICAgICAgIGJzID0gbmV3IEJpdFNldCgpOworICAgICAgICBicy5zZXQoMCk7CisgICAgICAgIGJzLnNldCgxKTsKKyAgICAgICAgYnMuc2V0KDMyKTsKKyAgICAgICAgYnMuc2V0KDE5Mik7CisgICAgICAgIGJzLnNldCg2NjYpOworCisgICAgICAgIGFzc2VydEVxdWFscyg2NjYsIGJzLnByZXZpb3VzU2V0Qml0KDk5OSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNjY2LCBicy5wcmV2aW91c1NldEJpdCg2NjcpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDY2NiwgYnMucHJldmlvdXNTZXRCaXQoNjY2KSk7CisgICAgICAgIGFzc2VydEVxdWFscygxOTIsIGJzLnByZXZpb3VzU2V0Qml0KDY2NSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMzIsIGJzLnByZXZpb3VzU2V0Qml0KDE5MSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgYnMucHJldmlvdXNTZXRCaXQoMzEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGJzLnByZXZpb3VzU2V0Qml0KDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBicy5wcmV2aW91c1NldEJpdCgtMSkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIEJpdFNldCBiaWcoKSB7CisgICAgICAgIEJpdFNldCByZXN1bHQgPSBuZXcgQml0U2V0KCk7CisgICAgICAgIHJlc3VsdC5zZXQoMTAwMCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgQml0U2V0IHNtYWxsKCkgeworICAgICAgICBCaXRTZXQgcmVzdWx0ID0gbmV3IEJpdFNldCgpOworICAgICAgICByZXN1bHQuc2V0KDEwKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RpZmZlcmVudFNpemVzKCkgeworICAgICAgICBCaXRTZXQgcmVzdWx0ID0gYmlnKCk7CisgICAgICAgIHJlc3VsdC5hbmQoc21hbGwoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygie30iLCByZXN1bHQudG9TdHJpbmcoKSk7CisgICAgICAgIHJlc3VsdCA9IHNtYWxsKCk7CisgICAgICAgIHJlc3VsdC5hbmQoYmlnKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInt9IiwgcmVzdWx0LnRvU3RyaW5nKCkpOworCisgICAgICAgIHJlc3VsdCA9IGJpZygpOworICAgICAgICByZXN1bHQuYW5kTm90KHNtYWxsKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInsxMDAwfSIsIHJlc3VsdC50b1N0cmluZygpKTsKKyAgICAgICAgcmVzdWx0ID0gc21hbGwoKTsKKyAgICAgICAgcmVzdWx0LmFuZE5vdChiaWcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiezEwfSIsIHJlc3VsdC50b1N0cmluZygpKTsKKworICAgICAgICBhc3NlcnRGYWxzZShiaWcoKS5pbnRlcnNlY3RzKHNtYWxsKCkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc21hbGwoKS5pbnRlcnNlY3RzKGJpZygpKSk7CisKKyAgICAgICAgcmVzdWx0ID0gYmlnKCk7CisgICAgICAgIHJlc3VsdC5vcihzbWFsbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ7MTAsIDEwMDB9IiwgcmVzdWx0LnRvU3RyaW5nKCkpOworICAgICAgICByZXN1bHQgPSBzbWFsbCgpOworICAgICAgICByZXN1bHQub3IoYmlnKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInsxMCwgMTAwMH0iLCByZXN1bHQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgcmVzdWx0ID0gYmlnKCk7CisgICAgICAgIHJlc3VsdC54b3Ioc21hbGwoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiezEwLCAxMDAwfSIsIHJlc3VsdC50b1N0cmluZygpKTsKKyAgICAgICAgcmVzdWx0ID0gc21hbGwoKTsKKyAgICAgICAgcmVzdWx0LnhvcihiaWcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiezEwLCAxMDAwfSIsIHJlc3VsdC50b1N0cmluZygpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvQ2FsZW5kYXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvQ2FsZW5kYXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTZjOWFlZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9DYWxlbmRhclRlc3QuamF2YQpAQCAtMCwwICsxLDIwNyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLlRpbWVab25lOworCitwdWJsaWMgY2xhc3MgQ2FsZW5kYXJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRpbWVab25lIEFNRVJJQ0FfU0FPX1BBVUxPID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkFtZXJpY2EvU2FvX1BhdWxvIik7CisKKyAgICAvKiogVGhpcyB6b25lJ3MgRFNUIG9mZnNldCBpcyBvbmx5IDMwIG1pbnV0ZXMuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVGltZVpvbmUgQVVTVFJBTElBX0xPUkRfSE9XRSA9IFRpbWVab25lLmdldFRpbWVab25lKCJBdXN0cmFsaWEvTG9yZF9Ib3dlIik7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIHpvbmUgaGFkIG9uY2UgdXNlZCBEU1QgYnV0IGRvZXNuJ3QgY3VycmVudGx5LiBBbnkgY29kZSB0aGF0IHVzZXMKKyAgICAgKiBUaW1lWm9uZS51c2VEYXlsaWdodFRpbWUoKSBhcyBhbiBvcHRpbWl6YXRpb24gd2lsbCBwcm9iYWJseSBiZSBicm9rZW4KKyAgICAgKiBmb3IgdGhpcyB6b25lLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRpbWVab25lIEFTSUFfS1VBTEFfTFVNUFVSID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkFzaWEvS3VhbGFfTHVtcHVyIik7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUaW1lWm9uZSBBU0lBX1NFT1VMID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkFzaWEvU2VvdWwiKTsKKworICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9NjE4NAorICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0VGltZVpvbmUoKSB7CisgICAgICAgIC8vIFRoZSBzcGVjaWZpYyB0aW1lIHpvbmVzIGRvbid0IG1hdHRlcjsgdGhleSBqdXN0IGhhdmUgdG8gYmUgZGlmZmVyZW50IHNvIHdlIGNhbiBzZWUgdGhhdAorICAgICAgICAvLyBnZXQoQ2FsZW5kYXIuWk9ORV9PRkZTRVQpIHJldHVybnMgdGhlIHpvbmUgb2Zmc2V0IG9mIHRoZSB0aW1lIHpvbmUgcGFzc2VkIHRvIHNldFRpbWVab25lLgorICAgICAgICBDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZShUaW1lWm9uZS5nZXRUaW1lWm9uZSgiVVRDIiksIExvY2FsZS5VUyk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBjYWwuZ2V0KENhbGVuZGFyLlpPTkVfT0ZGU0VUKSk7CisgICAgICAgIFRpbWVab25lIHR6ID0gamF2YS51dGlsLlRpbWVab25lLmdldFRpbWVab25lKCJHTVQrNyIpOworICAgICAgICBjYWwuc2V0VGltZVpvbmUodHopOworICAgICAgICBhc3NlcnRFcXVhbHMoMjUyMDAwMDAsIGNhbC5nZXQoQ2FsZW5kYXIuWk9ORV9PRkZTRVQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWRkT25lRGF5T3ZlckRzdEZvcndhcmRBZGRzMjNIb3Vyc0F0MDEwMCgpIHsKKyAgICAgICAgQ2FsZW5kYXIgY2FsZW5kYXIgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoQU1FUklDQV9TQU9fUEFVTE8pOworICAgICAgICBjYWxlbmRhci5zZXQoMjAxMSwgOSwgMTUsIDEsIDApOyAvLyAwMTowMCBHTVQtMworICAgICAgICBkb3VibGUgaG91cnNTaW5jZUVwb2NoID0gaG91cnNTaW5jZUVwb2NoKGNhbGVuZGFyKTsKKyAgICAgICAgY2FsZW5kYXIuYWRkKENhbGVuZGFyLkRBVEUsIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoMjMuMCwgaG91cnNTaW5jZUVwb2NoKGNhbGVuZGFyKSAtIGhvdXJzU2luY2VFcG9jaCk7CisgICAgICAgIGFzc2VydENhbGVuZGFyRXF1YWxzKGNhbGVuZGFyLCAyMDExLCA5LCAxNiwgMSwgMCk7IC8vIDAxOjAwIEdNVC0yOyArMjMgaG91cnMKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdCB0aGVpciBkYXlsaWdodCBzYXZpbmdzIHRpbWUgc3dpdGNoLCBTYW8gUGF1bG8gY2hhbmdlcyBmcm9tCisgICAgICogIjAwOjAwIEdNVC0zIiB0byAiMDE6MDAgR01ULTIiLiBXaGVuIGFkZGluZyB0aW1lIGFjcm9zcyB0aGlzIGJvdW5kYXJ5LAorICAgICAqIGRyb3AgYW4gaG91ciB0byBrZWVwIHRoZSBob3VyK21pbnV0ZSBjb25zdGFudCB1bmxlc3MgdGhhdCBwcmV2ZW50cyB0aGUKKyAgICAgKiBkYXRlIGZpZWxkIGZyb20gYmVpbmcgaW5jcmVtZW50ZWQuCisgICAgICogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD0xNzUwMgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRPbmVEYXlPdmVyRHN0Rm9yd2FyZEFkZHMyNEhvdXJzQXQwMDAwKCkgeworICAgICAgICBDYWxlbmRhciBjYWxlbmRhciA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcihBTUVSSUNBX1NBT19QQVVMTyk7CisgICAgICAgIGNhbGVuZGFyLnNldCgyMDExLCA5LCAxNSwgMCwgMCk7IC8vIDAwOjAwIEdNVC0zCisgICAgICAgIGRvdWJsZSBob3Vyc1NpbmNlRXBvY2ggPSBob3Vyc1NpbmNlRXBvY2goY2FsZW5kYXIpOworICAgICAgICBjYWxlbmRhci5hZGQoQ2FsZW5kYXIuREFURSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygyNC4wLCBob3Vyc1NpbmNlRXBvY2goY2FsZW5kYXIpIC0gaG91cnNTaW5jZUVwb2NoKTsKKyAgICAgICAgYXNzZXJ0Q2FsZW5kYXJFcXVhbHMoY2FsZW5kYXIsIDIwMTEsIDksIDE2LCAxLCAwKTsgLy8gMDE6MDAgR01ULTI7ICsyNCBob3VycworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRPbmVEYXlPdmVyRHN0QmFja0FkZHMyNUhvdXJzQXQwMDAwKCkgeworICAgICAgICBDYWxlbmRhciBjYWxlbmRhciA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcihBTUVSSUNBX1NBT19QQVVMTyk7CisgICAgICAgIGNhbGVuZGFyLnNldCgyMDExLCAxLCAxOSwgMCwgMCk7IC8vIDAwOjAwIEdNVC0yCisgICAgICAgIGRvdWJsZSBob3Vyc1NpbmNlRXBvY2ggPSBob3Vyc1NpbmNlRXBvY2goY2FsZW5kYXIpOworICAgICAgICBjYWxlbmRhci5hZGQoQ2FsZW5kYXIuREFURSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygyNS4wLCBob3Vyc1NpbmNlRXBvY2goY2FsZW5kYXIpIC0gaG91cnNTaW5jZUVwb2NoKTsKKyAgICAgICAgYXNzZXJ0Q2FsZW5kYXJFcXVhbHMoY2FsZW5kYXIsIDIwMTEsIDEsIDIwLCAwLCAwKTsgLy8gMDA6MDAgR01ULTM7ICsyNSBob3VycworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRPbmVEYXlPdmVyRHN0QmFja0FkZHMyNUhvdXJzQXQwMTAwKCkgeworICAgICAgICBDYWxlbmRhciBjYWxlbmRhciA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcihBTUVSSUNBX1NBT19QQVVMTyk7CisgICAgICAgIGNhbGVuZGFyLnNldCgyMDExLCAxLCAxOSwgMSwgMCk7IC8vIDAwOjAwIEdNVC0yCisgICAgICAgIGRvdWJsZSBob3Vyc1NpbmNlRXBvY2ggPSBob3Vyc1NpbmNlRXBvY2goY2FsZW5kYXIpOworICAgICAgICBjYWxlbmRhci5hZGQoQ2FsZW5kYXIuREFURSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygyNS4wLCBob3Vyc1NpbmNlRXBvY2goY2FsZW5kYXIpIC0gaG91cnNTaW5jZUVwb2NoKTsKKyAgICAgICAgYXNzZXJ0Q2FsZW5kYXJFcXVhbHMoY2FsZW5kYXIsIDIwMTEsIDEsIDIwLCAxLCAwKTsgLy8gMDA6MDAgR01ULTM7ICsyNSBob3VycworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRUd29IYWxmRGF5c092ZXJEc3RGb3J3YXJkQWRkczIzSG91cnNBdDAxMDAoKSB7CisgICAgICAgIENhbGVuZGFyIGNhbGVuZGFyID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKEFNRVJJQ0FfU0FPX1BBVUxPKTsKKyAgICAgICAgY2FsZW5kYXIuc2V0KDIwMTEsIDksIDE1LCAxLCAwKTsgLy8gMDE6MDAgR01ULTMKKyAgICAgICAgZG91YmxlIGhvdXJzU2luY2VFcG9jaCA9IGhvdXJzU2luY2VFcG9jaChjYWxlbmRhcik7CisgICAgICAgIGNhbGVuZGFyLmFkZChDYWxlbmRhci5BTV9QTSwgMik7CisgICAgICAgIGFzc2VydEVxdWFscygyMy4wLCBob3Vyc1NpbmNlRXBvY2goY2FsZW5kYXIpIC0gaG91cnNTaW5jZUVwb2NoKTsKKyAgICAgICAgYXNzZXJ0Q2FsZW5kYXJFcXVhbHMoY2FsZW5kYXIsIDIwMTEsIDksIDE2LCAxLCAwKTsgLy8gMDE6MDAgR01ULTI7ICsyMyBob3VycworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGQyNEhvdXJzT3ZlckRzdEZvcndhcmRBZGRzMjRIb3VycygpIHsKKyAgICAgICAgQ2FsZW5kYXIgY2FsZW5kYXIgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoQU1FUklDQV9TQU9fUEFVTE8pOworICAgICAgICBjYWxlbmRhci5zZXQoMjAxMSwgOSwgMTUsIDEsIDApOyAvLyAwMTowMCBHTVQtMworICAgICAgICBkb3VibGUgaG91cnNTaW5jZUVwb2NoID0gaG91cnNTaW5jZUVwb2NoKGNhbGVuZGFyKTsKKyAgICAgICAgY2FsZW5kYXIuYWRkKENhbGVuZGFyLkhPVVIsIDI0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDI0LjAsIGhvdXJzU2luY2VFcG9jaChjYWxlbmRhcikgLSBob3Vyc1NpbmNlRXBvY2gpOworICAgICAgICBhc3NlcnRDYWxlbmRhckVxdWFscyhjYWxlbmRhciwgMjAxMSwgOSwgMTYsIDIsIDApOyAvLyAwMjowMCBHTVQtMjsgKzI0IGhvdXJzCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFkZE9uZURheUFuZE9uZURheU92ZXIzME1pbnV0ZURzdEZvcndhcmRBZGRzNDhIb3VycygpIHsKKyAgICAgICAgQ2FsZW5kYXIgY2FsZW5kYXIgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoQVVTVFJBTElBX0xPUkRfSE9XRSk7CisgICAgICAgIGNhbGVuZGFyLnNldCgyMDExLCA5LCAxLCAyLCAxMCk7IC8vIDAyOjEwIEdNVCsxMDozMAorICAgICAgICBkb3VibGUgaG91cnNTaW5jZUVwb2NoID0gaG91cnNTaW5jZUVwb2NoKGNhbGVuZGFyKTsKKyAgICAgICAgY2FsZW5kYXIuYWRkKENhbGVuZGFyLkRBVEUsIDEpOworICAgICAgICBjYWxlbmRhci5hZGQoQ2FsZW5kYXIuREFURSwgMSk7CisgICAgICAgIC8vIFRoZSBSSSBmYWlscyB0aGlzIHRlc3QgYnkgcmV0dXJuaW5nIDQ3LjAuIEl0IGFkanVzdHMgZm9yIERTVCBvbiBib3RoIG9mIHRoZSBhZGQoKSBjYWxscyEKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQ4LjAsIGhvdXJzU2luY2VFcG9jaChjYWxlbmRhcikgLSBob3Vyc1NpbmNlRXBvY2gpOworICAgICAgICBhc3NlcnRDYWxlbmRhckVxdWFscyhjYWxlbmRhciwgMjAxMSwgOSwgMywgMiwgNDApOyAvLyAwMjo0MCBHTVQrMTE6MDA7ICs0OC4wIGhvdXJzCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFkZFR3b0RheXNPdmVyMzBNaW51dGVEc3RGb3J3YXJkQWRkczQ3QW5kQUhhbGZIb3VycygpIHsKKyAgICAgICAgQ2FsZW5kYXIgY2FsZW5kYXIgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoQVVTVFJBTElBX0xPUkRfSE9XRSk7CisgICAgICAgIGNhbGVuZGFyLnNldCgyMDExLCA5LCAxLCAyLCAxMCk7IC8vIDAyOjEwIEdNVCsxMDozMAorICAgICAgICBkb3VibGUgaG91cnNTaW5jZUVwb2NoID0gaG91cnNTaW5jZUVwb2NoKGNhbGVuZGFyKTsKKyAgICAgICAgY2FsZW5kYXIuYWRkKENhbGVuZGFyLkRBVEUsIDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoNDcuNSwgaG91cnNTaW5jZUVwb2NoKGNhbGVuZGFyKSAtIGhvdXJzU2luY2VFcG9jaCk7CisgICAgICAgIGFzc2VydENhbGVuZGFyRXF1YWxzKGNhbGVuZGFyLCAyMDExLCA5LCAzLCAyLCAxMCk7IC8vIDAyOjEwIEdNVCsxMTowMDsgKzQ3LjUgaG91cnMKKyAgICB9CisKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTE3NzQxCisgICAgcHVibGljIHZvaWQgdGVzdE5ld0NhbGVuZGFyS29yZWFJc1NlbGZDb25zaXN0ZW50KCkgeworICAgICAgICB0ZXN0U2V0U2VsZkNvbnNpc3RlbnQoQVNJQV9TRU9VTCwgMTkyMSwgMCwgMSk7CisgICAgICAgIHRlc3RTZXRTZWxmQ29uc2lzdGVudChBU0lBX1NFT1VMLCAxOTU1LCAwLCAxKTsKKyAgICAgICAgdGVzdFNldFNlbGZDb25zaXN0ZW50KEFTSUFfU0VPVUwsIDE5NjIsIDAsIDEpOworICAgICAgICB0ZXN0U2V0U2VsZkNvbnNpc3RlbnQoQVNJQV9TRU9VTCwgMjA2NSwgMCwgMSk7CisgICAgfQorCisgICAgLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD0xNTYyOQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRUaW1lSW5ab25lV2hlcmVEc3RJc05vTG9uZ2VyVXNlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0U2V0U2VsZkNvbnNpc3RlbnQoQVNJQV9LVUFMQV9MVU1QVVIsIDE5NzAsIDAsIDEpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0U2V0U2VsZkNvbnNpc3RlbnQoVGltZVpvbmUgdGltZVpvbmUsIGludCB5ZWFyLCBpbnQgbW9udGgsIGludCBkYXkpIHsKKyAgICAgICAgaW50IGhvdXIgPSAwOworICAgICAgICBpbnQgbWludXRlID0gMDsKKyAgICAgICAgQ2FsZW5kYXIgY2FsZW5kYXIgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIodGltZVpvbmUpOworICAgICAgICBjYWxlbmRhci5jbGVhcigpOworICAgICAgICBjYWxlbmRhci5zZXQoeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHllYXIsIGNhbGVuZGFyLmdldChDYWxlbmRhci5ZRUFSKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtb250aCwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLk1PTlRIKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhkYXksIGNhbGVuZGFyLmdldChDYWxlbmRhci5EQVlfT0ZfTU9OVEgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGhvdXIsIGNhbGVuZGFyLmdldChDYWxlbmRhci5IT1VSX09GX0RBWSkpOworICAgICAgICBhc3NlcnRFcXVhbHMobWludXRlLCBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuTUlOVVRFKSk7CisgICAgfQorCisgICAgLy8gaHR0cDovL2IvNTE3OTc3NQorICAgIHB1YmxpYyB2b2lkIHRlc3RDYWxlbmRhclNlcmlhbGl6YXRpb24oKSB7CisgICAgICAgIFN0cmluZyBzID0gImFjZWQwMDA1NzM3MjAwMWI2YTYxNzY2MTJlNzU3NDY5NmMyZTQ3NzI2NTY3NmY3MjY5NjE2ZTQzNjE2YzY1NmU2NDYxNzI4ZjNkZDdkNmUiCisgICAgICAgICAgICAgICAgKyAiNWIwZDBjMTAzMDAwNzQ5MDAwZjYzNzU3MjcyNjU2ZTc0NTk2NTYxNzI1MzZiNjU3NzRhMDAxMDY3NzI2NTY3NmY3MjY5NjE2ZTQzNzU3NDYiCisgICAgICAgICAgICAgICAgKyAiZjc2NjU3MjVhMDAwODY5NzM0MzYxNjM2ODY1NjQ0YTAwMTI2YzYxNzM3NDRkNjk2NDZlNjk2NzY4NzQ0ZDY5NmM2YzY5NzM0OTAwMGM2YzYiCisgICAgICAgICAgICAgICAgKyAiMTczNzQ1OTY1NjE3MjUzNmI2NTc3NGEwMDEyNmU2NTc4NzQ0ZDY5NjQ2ZTY5Njc2ODc0NGQ2OTZjNmM2OTczNWIwMDBjNjM2MTYzNjg2NTYiCisgICAgICAgICAgICAgICAgKyAiNDQ2Njk2NTZjNjQ3Mzc0MDAwMjViNDk3ODcyMDAxMjZhNjE3NjYxMmU3NTc0Njk2YzJlNDM2MTZjNjU2ZTY0NjE3MmU2ZWE0ZDFlYzhkYzUiCisgICAgICAgICAgICAgICAgKyAiYjhlMDMwMDBiNWEwMDBjNjE3MjY1NDY2OTY1NmM2NDczNTM2NTc0NDkwMDBlNjY2OTcyNzM3NDQ0NjE3OTRmNjY1NzY1NjU2YjVhMDAwOTYiCisgICAgICAgICAgICAgICAgKyAiOTczNTQ2OTZkNjU1MzY1NzQ1YTAwMDc2YzY1NmU2OTY1NmU3NDQ5MDAxNjZkNjk2ZTY5NmQ2MTZjNDQ2MTc5NzM0OTZlNDY2OTcyNzM3NDUiCisgICAgICAgICAgICAgICAgKyAiNzY1NjU2YjQ5MDAwOTZlNjU3ODc0NTM3NDYxNmQ3MDQ5MDAxNTczNjU3MjY5NjE2YzU2NjU3MjczNjk2ZjZlNGY2ZTUzNzQ3MjY1NjE2ZDQiCisgICAgICAgICAgICAgICAgKyAiYTAwMDQ3NDY5NmQ2NTViMDAwNjY2Njk2NTZjNjQ3MzcxMDA3ZTAwMDE1YjAwMDU2OTczNTM2NTc0NzQwMDAyNWI1YTRjMDAwNDdhNmY2ZTYiCisgICAgICAgICAgICAgICAgKyAiNTc0MDAxNDRjNmE2MTc2NjEyZjc1NzQ2OTZjMmY1NDY5NmQ2NTVhNmY2ZTY1M2I3ODcwMDEwMDAwMDAwMTAxMDEwMDAwMDAwNDAwMDAwMDAiCisgICAgICAgICAgICAgICAgKyAiMjAwMDAwMDAxMDAwMDAwMDBhMTVjOTgwMDc1NzIwMDAyNWI0OTRkYmE2MDI2NzZlYWIyYTUwMjAwMDA3ODcwMDAwMDAwMTEwMDAwMDAwMTAiCisgICAgICAgICAgICAgICAgKyAiMDAwMDdiMjAwMDAwMDAxMDAwMDAwMDUwMDAwMDAwMTAwMDAwMDAxMDAwMDAwMjAwMDAwMDAwMTAwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAiCisgICAgICAgICAgICAgICAgKyAiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMGZlNDg4YzAwMDAwMDAwMDA3NTcyMDAwMjViNWE1NzhmMjAzOTE0Yjg1ZGUyMDIwMDAiCisgICAgICAgICAgICAgICAgKyAiMDc4NzAwMDAwMDAxMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDE3MzcyMDAxODZhNjE3NjYxMmU3NTc0Njk2YzJlNTM2OTYiCisgICAgICAgICAgICAgICAgKyAiZDcwNmM2NTU0Njk2ZDY1NWE2ZjZlNjVmYTY3NWQ2MGQxNWVmNWE2MDMwMDEwNDkwMDBhNjQ3Mzc0NTM2MTc2Njk2ZTY3NzM0OTAwMDY2NTYiCisgICAgICAgICAgICAgICAgKyAiZTY0NDQ2MTc5NDkwMDBjNjU2ZTY0NDQ2MTc5NGY2NjU3NjU2NTZiNDkwMDA3NjU2ZTY0NGQ2ZjY0NjU0OTAwMDg2NTZlNjQ0ZDZmNmU3NDYiCisgICAgICAgICAgICAgICAgKyAiODQ5MDAwNzY1NmU2NDU0Njk2ZDY1NDkwMDA5NzI2MTc3NGY2NjY2NzM2NTc0NDkwMDE1NzM2NTcyNjk2MTZjNTY2NTcyNzM2OTZmNmU0ZjYiCisgICAgICAgICAgICAgICAgKyAiZTUzNzQ3MjY1NjE2ZDQ5MDAwODczNzQ2MTcyNzQ0NDYxNzk0OTAwMGU3Mzc0NjE3Mjc0NDQ2MTc5NGY2NjU3NjU2NTZiNDkwMDA5NzM3NDYiCisgICAgICAgICAgICAgICAgKyAiMTcyNzQ0ZDZmNjQ2NTQ5MDAwYTczNzQ2MTcyNzQ0ZDZmNmU3NDY4NDkwMDA5NzM3NDYxNzI3NDU0Njk2ZDY1NDkwMDA5NzM3NDYxNzI3NDUiCisgICAgICAgICAgICAgICAgKyAiOTY1NjE3MjVhMDAwYjc1NzM2NTQ0NjE3OTZjNjk2NzY4NzQ1YjAwMGI2ZDZmNmU3NDY4NGM2NTZlNjc3NDY4NzQwMDAyNWI0Mjc4NzIwMDEiCisgICAgICAgICAgICAgICAgKyAiMjZhNjE3NjYxMmU3NTc0Njk2YzJlNTQ2OTZkNjU1YTZmNmU2NTMxYjNlOWY1Nzc0NGFjYTEwMjAwMDE0YzAwMDI0OTQ0NzQwMDEyNGM2YTYiCisgICAgICAgICAgICAgICAgKyAiMTc2NjEyZjZjNjE2ZTY3MmY1Mzc0NzI2OTZlNjczYjc4NzA3NDAwMDk0NzRkNTQyZDMwMzgzYTMwMzAwMDM2ZWU4MDAwMDAwMDAwMDAwMDAiCisgICAgICAgICAgICAgICAgKyAiMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwZmU0ODhjMDAwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAiCisgICAgICAgICAgICAgICAgKyAiMDAwMDAwMDAwMDAwMDc1NzIwMDAyNWI0MmFjZjMxN2Y4MDYwODU0ZTAwMjAwMDA3ODcwMDAwMDAwMGMxZjFjMWYxZTFmMWUxZjFmMWUxZjEiCisgICAgICAgICAgICAgICAgKyAiZTFmNzcwODAwMDAwMDA0MDAwMTAwMDE3ODc4MDAwMDAwMGFmZmZmZjRlMmY5NjRhYzAwMDEwMDAwMDAwMDlmYTUyNDAwMDAwMDAwMDAwMDAiCisgICAgICAgICAgICAgICAgKyAiMDAwMDBhNGNiN2MxODc1NzEwMDdlMDAwNjAwMDAwMDBhMDAwMDA3YjIwMDAwMDAwMTAwMDAwMDAxMDAwMDAwMDFmZTQ4OGMwMDAwMDAwMDAiCisgICAgICAgICAgICAgICAgKyAiMTAwMDAwMDA1MDAwMDAwMDEwMDAwMDAyMDAwMDAwMDAxNzgiOworICAgICAgICBDYWxlbmRhciBjYWxlbmRhciA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTcwLCAxLCAxLCAwLCAwLCAwKTsKKyAgICAgICAgY2FsZW5kYXIuc2V0VGltZVpvbmUoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkdNVC0wODowMCIpKTsKKyAgICAgICAgY2FsZW5kYXIuc2V0Rmlyc3REYXlPZldlZWsoMSk7CisgICAgICAgIGNhbGVuZGFyLnNldE1pbmltYWxEYXlzSW5GaXJzdFdlZWsoNCk7CisgICAgICAgIG5ldyBTZXJpYWxpemFibGVUZXN0ZXI8Q2FsZW5kYXI+KGNhbGVuZGFyLCBzKS50ZXN0KCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydENhbGVuZGFyRXF1YWxzKENhbGVuZGFyIGNhbGVuZGFyLAorICAgICAgICAgICAgaW50IHllYXIsIGludCBtb250aCwgaW50IGRheSwgaW50IGhvdXIsIGludCBtaW51dGUpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHllYXIsIGNhbGVuZGFyLmdldChDYWxlbmRhci5ZRUFSKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtb250aCwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLk1PTlRIKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhkYXksIGNhbGVuZGFyLmdldChDYWxlbmRhci5EQVRFKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhob3VyLCBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1pbnV0ZSwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLk1JTlVURSkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGRvdWJsZSBob3Vyc1NpbmNlRXBvY2goQ2FsZW5kYXIgYykgeworICAgICAgICBkb3VibGUgT05FX0hPVVIgPSAzNjAwZCAqIDEwMDBkOworICAgICAgICByZXR1cm4gYy5nZXRUaW1lSW5NaWxsaXMoKSAvIE9ORV9IT1VSOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9Db2xsZWN0aW9uc1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9Db2xsZWN0aW9uc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MGM3NjllCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL0NvbGxlY3Rpb25zVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgR29vZ2xlIEluYy4KKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdEl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIENvbGxlY3Rpb25zVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eUVudW1lcmF0aW9uKCkgeworICAgICAgICBFbnVtZXJhdGlvbjxPYmplY3Q+IGUgPSBDb2xsZWN0aW9ucy5lbXB0eUVudW1lcmF0aW9uKCk7CisgICAgICAgIGFzc2VydEZhbHNlKGUgaW5zdGFuY2VvZiBTZXJpYWxpemFibGUpOworICAgICAgICBhc3NlcnRGYWxzZShlLmhhc01vcmVFbGVtZW50cygpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGUubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVtcHR5SXRlcmF0b3IoKSB7CisgICAgICAgIHRlc3RFbXB0eUl0ZXJhdG9yKENvbGxlY3Rpb25zLmVtcHR5SXRlcmF0b3IoKSk7CisgICAgICAgIHRlc3RFbXB0eUl0ZXJhdG9yKENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpLml0ZXJhdG9yKCkpOworICAgICAgICB0ZXN0RW1wdHlJdGVyYXRvcihDb2xsZWN0aW9ucy5lbXB0eVNldCgpLml0ZXJhdG9yKCkpOworICAgICAgICB0ZXN0RW1wdHlJdGVyYXRvcihDb2xsZWN0aW9ucy5lbXB0eU1hcCgpLmtleVNldCgpLml0ZXJhdG9yKCkpOworICAgICAgICB0ZXN0RW1wdHlJdGVyYXRvcihDb2xsZWN0aW9ucy5lbXB0eU1hcCgpLmVudHJ5U2V0KCkuaXRlcmF0b3IoKSk7CisgICAgICAgIHRlc3RFbXB0eUl0ZXJhdG9yKENvbGxlY3Rpb25zLmVtcHR5TWFwKCkudmFsdWVzKCkuaXRlcmF0b3IoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RFbXB0eUl0ZXJhdG9yKEl0ZXJhdG9yPD8+IGkpIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoaSBpbnN0YW5jZW9mIFNlcmlhbGl6YWJsZSk7CisgICAgICAgIGFzc2VydEZhbHNlKGkuaGFzTmV4dCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGkubmV4dCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGkucmVtb3ZlKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVtcHR5TGlzdEl0ZXJhdG9yKCkgeworICAgICAgICB0ZXN0RW1wdHlMaXN0SXRlcmF0b3IoQ29sbGVjdGlvbnMuZW1wdHlMaXN0SXRlcmF0b3IoKSk7CisgICAgICAgIHRlc3RFbXB0eUxpc3RJdGVyYXRvcihDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKS5saXN0SXRlcmF0b3IoKSk7CisgICAgICAgIHRlc3RFbXB0eUxpc3RJdGVyYXRvcihDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKS5saXN0SXRlcmF0b3IoMCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0RW1wdHlMaXN0SXRlcmF0b3IoTGlzdEl0ZXJhdG9yPD8+IGkpIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoaSBpbnN0YW5jZW9mIFNlcmlhbGl6YWJsZSk7CisgICAgICAgIGFzc2VydEZhbHNlKGkuaGFzTmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoaS5oYXNQcmV2aW91cygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGkubmV4dEluZGV4KCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaS5uZXh0KCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGkucHJldmlvdXNJbmRleCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGkucHJldmlvdXMoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpLmFkZChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaS5yZW1vdmUoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvQ3VycmVuY3lUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvQ3VycmVuY3lUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTNlMjI0MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9DdXJyZW5jeVRlc3QuamF2YQpAQCAtMCwwICsxLDcxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5DdXJyZW5jeTsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK3B1YmxpYyBjbGFzcyBDdXJyZW5jeVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCB0byBlbnN1cmUgdGhhdCBDdXJyZW5jeS5nZXRTeW1ib2woTG9jYWxlKSByZXR1cm5zIHRoZQorICAgIC8vIGN1cnJlbmN5IGNvZGUgaWYgSUNVIGRvZXNuJ3QgaGF2ZSBhIGxvY2FsaXphdGlvbiBvZiB0aGUgc3ltYm9sLiBUaGUKKyAgICAvLyBoYXJtb255IEN1cnJlbmN5IHRlc3RzIGRvbid0IHRlc3QgdGhpcywgYW5kIHRoZWlyIERlY2ltYWxGb3JtYXQgdGVzdHMKKyAgICAvLyBvbmx5IHRlc3QgaXQgYXMgYSBzaWRlLWVmZmVjdCwgYW5kIGluIGEgd2F5IHRoYXQgb25seSBkZXRlY3RlZCBteQorICAgIC8vIHNwZWNpZmljIG1pc3Rha2Ugb2YgcmV0dXJuaW5nIG51bGwgKHJldHVybmluZyAic3Rpbmt5IiB3b3VsZCBoYXZlCisgICAgLy8gcGFzc2VkKS4KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFN5bWJvbF9mYWxsYmFjaygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUaGlzIGFzc3VtZXMgdGhhdCBBRUQgbmV2ZXIgYmVjb21lcyBhIGN1cnJlbmN5IGltcG9ydGFudCBlbm91Z2ggdG8KKyAgICAgICAgLy8gQ2FuYWRhIHRoYXQgQ2FuYWRpYW5zIGdpdmUgaXQgYSBsb2NhbGl6ZWQgKHRvIENhbmFkYSkgc3ltYm9sLgorICAgICAgICBhc3NlcnRFcXVhbHMoIkFFRCIsIEN1cnJlbmN5LmdldEluc3RhbmNlKCJBRUQiKS5nZXRTeW1ib2woTG9jYWxlLkNBTkFEQSkpOworICAgIH0KKworICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCB0byBlbnN1cmUgdGhhdCBDdXJyZW5jeS5nZXRJbnN0YW5jZShTdHJpbmcpIHRocm93cyBpZgorICAgIC8vIGdpdmVuIGFuIGludmFsaWQgSVNPIGN1cnJlbmN5IGNvZGUuCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZV9pbGxlZ2FsX2N1cnJlbmN5X2NvZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ3VycmVuY3kuZ2V0SW5zdGFuY2UoIlVTRCIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ3VycmVuY3kuZ2V0SW5zdGFuY2UoIkJPR08tRE9MTEFSUyIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGZvciBpbnZhbGlkIElTTyBjdXJyZW5jeSBjb2RlIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEF2YWlsYWJsZUN1cnJlbmNpZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2V0PEN1cnJlbmN5PiBhbGwgPSBDdXJyZW5jeS5nZXRBdmFpbGFibGVDdXJyZW5jaWVzKCk7CisgICAgICAgIC8vIENvbmZpcm0gdGhhdCBhIGZldyB3ZWxsLWtub3duIHN0YWJsZSBjdXJyZW5jaWVzIGFyZSBwcmVzZW50LgorICAgICAgICBhc3NlcnRUcnVlKGFsbC50b1N0cmluZygpLCBhbGwuY29udGFpbnMoQ3VycmVuY3kuZ2V0SW5zdGFuY2UoIkNIRiIpKSk7CisgICAgICAgIGFzc2VydFRydWUoYWxsLnRvU3RyaW5nKCksIGFsbC5jb250YWlucyhDdXJyZW5jeS5nZXRJbnN0YW5jZSgiRVVSIikpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhbGwudG9TdHJpbmcoKSwgYWxsLmNvbnRhaW5zKEN1cnJlbmN5LmdldEluc3RhbmNlKCJHQlAiKSkpOworICAgICAgICBhc3NlcnRUcnVlKGFsbC50b1N0cmluZygpLCBhbGwuY29udGFpbnMoQ3VycmVuY3kuZ2V0SW5zdGFuY2UoIkpQWSIpKSk7CisgICAgICAgIGFzc2VydFRydWUoYWxsLnRvU3RyaW5nKCksIGFsbC5jb250YWlucyhDdXJyZW5jeS5nZXRJbnN0YW5jZSgiVVNEIikpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERpc3BsYXlOYW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiU3dpc3MgRnJhbmMiLCBDdXJyZW5jeS5nZXRJbnN0YW5jZSgiQ0hGIikuZ2V0RGlzcGxheU5hbWUoTG9jYWxlLlVTKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2Nod2VpemVyIEZyYW5rZW4iLCBDdXJyZW5jeS5nZXRJbnN0YW5jZSgiQ0hGIikuZ2V0RGlzcGxheU5hbWUobmV3IExvY2FsZSgiZGUiLCAiQ0giKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZyYW5jIHN1aXNzZSIsIEN1cnJlbmN5LmdldEluc3RhbmNlKCJDSEYiKS5nZXREaXNwbGF5TmFtZShuZXcgTG9jYWxlKCJmciIsICJDSCIpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRnJhbmNvIFN2aXp6ZXJvIiwgQ3VycmVuY3kuZ2V0SW5zdGFuY2UoIkNIRiIpLmdldERpc3BsYXlOYW1lKG5ldyBMb2NhbGUoIml0IiwgIkNIIikpKTsKKyAgICAgICAgLy8gVGVzdCBiZWhhdmlvciB3aXRoIHVua25vd24gbG9jYWxlczsgc2hvdWxkIHJldHVybiB0aGUgY3VycmVuY3kgY29kZS4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDSEYiLCBDdXJyZW5jeS5nZXRJbnN0YW5jZSgiQ0hGIikuZ2V0RGlzcGxheU5hbWUobmV3IExvY2FsZSgieHgiLCAiWVkiKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGVmYXVsdEZyYWN0aW9uRGlnaXRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBDdXJyZW5jeS5nZXRJbnN0YW5jZSgiVVNEIikuZ2V0RGVmYXVsdEZyYWN0aW9uRGlnaXRzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgQ3VycmVuY3kuZ2V0SW5zdGFuY2UoIkpQWSIpLmdldERlZmF1bHRGcmFjdGlvbkRpZ2l0cygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBDdXJyZW5jeS5nZXRJbnN0YW5jZSgiWFhYIikuZ2V0RGVmYXVsdEZyYWN0aW9uRGlnaXRzKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9EYXRlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL0RhdGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGRjYzNlNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9EYXRlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLlRpbWVab25lOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIERhdGVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9NjAxMworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gRW5zdXJlIHRoYXQgbm8gbWF0dGVyIHdoZXJlIHRoaXMgaXMgcnVuLCB3ZSBrbm93IHdoYXQgdGltZSB6b25lCisgICAgICAgIC8vIHRvIGV4cGVjdC4gKFRob3VnaCB3ZSBzdGlsbCBhc3N1bWUgYW4gImVuIiBsb2NhbGUuKQorICAgICAgICBUaW1lWm9uZS5zZXREZWZhdWx0KFRpbWVab25lLmdldFRpbWVab25lKCJBbWVyaWNhL0NoaWNhZ28iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV2VkIERlYyAzMSAxODowMDowMCBDU1QgMTk2OSIsIG5ldyBEYXRlKDApLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9HTVRTdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQmFzZWQgb24gaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9IQVJNT05ZLTUwMQorICAgICAgICBUaW1lWm9uZS5zZXREZWZhdWx0KFRpbWVab25lLmdldFRpbWVab25lKCJBbWVyaWNhL0xvc19BbmdlbGVzIikpOworICAgICAgICBDYWxlbmRhciBjID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgYy5jbGVhcigpOworICAgICAgICBjLnNldChDYWxlbmRhci5ZRUFSLCAyMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV2VkIEphbiAwMSAwMDowMDowMCBQU1QgMjEiLCBjLmdldFRpbWUoKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxIEphbiAyMSAwODowMDowMCBHTVQiLCBjLmdldFRpbWUoKS50b0dNVFN0cmluZygpKTsKKyAgICAgICAgYy5zZXQoQ2FsZW5kYXIuWUVBUiwgMzIxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTdW4gSmFuIDAxIDAwOjAwOjAwIFBTVCAzMjEiLCBjLmdldFRpbWUoKS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxIEphbiAzMjEgMDg6MDA6MDAgR01UIiwgYy5nZXRUaW1lKCkudG9HTVRTdHJpbmcoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL0V2ZW50T2JqZWN0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL0V2ZW50T2JqZWN0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE4MGU4YzcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvRXZlbnRPYmplY3RUZXN0LmphdmEKQEAgLTAsMCArMSw1NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5FdmVudE9iamVjdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBFdmVudE9iamVjdFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RydWN0b3IoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRXZlbnRPYmplY3QobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFNvdXJjZSgpIHsKKyAgICAgICAgT2JqZWN0IHNvdXJjZSA9IG5ldyBPYmplY3QoKTsKKyAgICAgICAgYXNzZXJ0U2FtZShzb3VyY2UsIG5ldyBFdmVudE9iamVjdChzb3VyY2UpLmdldFNvdXJjZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9TdHJpbmcoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiamF2YS51dGlsLkV2ZW50T2JqZWN0W3NvdXJjZT14XSIsIG5ldyBFdmVudE9iamVjdCgieCIpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemF0aW9uTnVsbHNPdXRTb3VyY2UoKSB7CisgICAgICAgIFN0cmluZyBzID0gImFjZWQwMDA1NzM3MjAwMTU2YTYxNzY2MTJlNzU3NDY5NmMyZTQ1NzY2NTZlNzQ0ZjYyNmE2NTYzNzQ0IgorICAgICAgICAgICAgICAgICsgImM4ZDA5NGUxODZkN2RhODAyMDAwMDc4NzAiOworICAgICAgICBPYmplY3Qgc291cmNlID0gbmV3IE9iamVjdCgpOworICAgICAgICBFdmVudE9iamVjdCBldmVudE9iamVjdCA9IG5ldyBFdmVudE9iamVjdChzb3VyY2UpOworICAgICAgICBuZXcgU2VyaWFsaXphYmxlVGVzdGVyPEV2ZW50T2JqZWN0PihldmVudE9iamVjdCwgcykgeworICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBib29sZWFuIGVxdWFscyhFdmVudE9iamVjdCBhLCBFdmVudE9iamVjdCBiKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGEuZ2V0U291cmNlKCkgPT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgfHwgYi5nZXRTb3VyY2UoKSA9PSBudWxsCisgICAgICAgICAgICAgICAgICAgICAgICB8fCBhLmdldFNvdXJjZSgpID09IGIuZ2V0U291cmNlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0udGVzdCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9Gb3JtYXR0ZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvRm9ybWF0dGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVjNTk4MDcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvRm9ybWF0dGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTMzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOworaW1wb3J0IGphdmEudXRpbC5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5UaW1lWm9uZTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfTG9jYWxlOworCitwdWJsaWMgY2xhc3MgRm9ybWF0dGVyVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdF9udW1iZXJMb2NhbGl6YXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTG9jYWxlIGFyYWJpYyA9IG5ldyBMb2NhbGUoImFyIik7CisgICAgICAgIGlmICghU3VwcG9ydF9Mb2NhbGUuaXNMb2NhbGVBdmFpbGFibGUoYXJhYmljKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIC8vIENoZWNrIHRoZSBmYXN0IHBhdGggZm9yICVkOgorICAgICAgICBhc3NlcnRFcXVhbHMoIjEyIFx1MDY2MVx1MDY2Mlx1MDY2M1x1MDY2NFx1MDY2NVx1MDY2Nlx1MDY2N1x1MDY2OFx1MDY2OVx1MDY2MCAzNCIsCisgICAgICAgICAgICAgICAgU3RyaW5nLmZvcm1hdChhcmFiaWMsICIxMiAlZCAzNCIsIDEyMzQ1Njc4OTApKTsKKyAgICAgICAgLy8gQW5kIHRoZSBzbG93IHBhdGggdG9vOgorICAgICAgICBhc3NlcnRFcXVhbHMoIjEyIFx1MDY2MVx1MDY2Y1x1MDY2Mlx1MDY2M1x1MDY2NFx1MDY2Y1x1MDY2NVx1MDY2Nlx1MDY2N1x1MDY2Y1x1MDY2OFx1MDY2OVx1MDY2MCAzNCIsCisgICAgICAgICAgICAgICAgU3RyaW5nLmZvcm1hdChhcmFiaWMsICIxMiAlLGQgMzQiLCAxMjM0NTY3ODkwKSk7CisgICAgICAgIC8vIEFuZCB0aHJlZSBsb2NhbGl6ZWQgZmxvYXRpbmcgcG9pbnQgZm9ybWF0czoKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMiBcdTA2NjFcdTA2NmJcdTA2NjJcdTA2NjNcdTA2NjBcdTA2MjdcdTA2MzMrXHUwNjYwXHUwNjYwIDM0IiwKKyAgICAgICAgICAgICAgICBTdHJpbmcuZm9ybWF0KGFyYWJpYywgIjEyICUuM2UgMzQiLCAxLjIzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTIgXHUwNjYxXHUwNjZiXHUwNjYyXHUwNjYzXHUwNjYwIDM0IiwKKyAgICAgICAgICAgICAgICBTdHJpbmcuZm9ybWF0KGFyYWJpYywgIjEyICUuM2YgMzQiLCAxLjIzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTIgXHUwNjYxXHUwNjZiXHUwNjYyXHUwNjYzIDM0IiwKKyAgICAgICAgICAgICAgICBTdHJpbmcuZm9ybWF0KGFyYWJpYywgIjEyICUuM2cgMzQiLCAxLjIzKSk7CisgICAgICAgIC8vIEFuZCBkYXRlL3RpbWUgZm9ybWF0dGluZyAod2UgYXNzdW1lIHRoYXQgYWxsIHRpbWUvZGF0ZSBudW1iZXIgZm9ybWF0dGluZyBpcyBkb25lIGJ5IHRoZQorICAgICAgICAvLyBzYW1lIGNvZGUsIHNvIHRoaXMgaXMgcmVwcmVzZW50YXRpdmUpOgorICAgICAgICBDYWxlbmRhciBjID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkdNVC0wODowMCIpKTsKKyAgICAgICAgYy5zZXRUaW1lSW5NaWxsaXMoMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTIgXHUwNjYxXHUwNjY2Olx1MDY2MFx1MDY2MDpcdTA2NjBcdTA2NjAgMzQiLAorICAgICAgICAgICAgICAgIFN0cmluZy5mb3JtYXQoYXJhYmljLCAiMTIgJXRUIDM0IiwgYykpOworICAgICAgICAvLyBUaGVzZSBzaG91bGRuJ3QgZ2V0IGxvY2FsaXplZDoKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMjM0IiwgU3RyaW5nLmZvcm1hdChhcmFiaWMsICIxMjM0IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEyMzQiLCBTdHJpbmcuZm9ybWF0KGFyYWJpYywgIiVzIiwgIjEyMzQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTIzNCIsIFN0cmluZy5mb3JtYXQoYXJhYmljLCAiJXMiLCAxMjM0KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMjMyMiIsIFN0cmluZy5mb3JtYXQoYXJhYmljLCAiJW8iLCAxMjM0KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiNGQyIiwgU3RyaW5nLmZvcm1hdChhcmFiaWMsICIleCIsIDEyMzQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIweDEuMHAwIiwgU3RyaW5nLmZvcm1hdChhcmFiaWMsICIlYSIsIDEuMCkpOworICAgIH0KKworICAgIC8vIGh0dHA6Ly9iLzIzMDE5MzgKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VwcGVyY2FzZUNvbnZlcnNpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIEluIG1vc3QgbG9jYWxlcywgdGhlIHVwcGVyLWNhc2UgZXF1aXZhbGVudCBvZiAiaSIgaXMgIkkiLgorICAgICAgICBhc3NlcnRFcXVhbHMoIkpBS09CIEFSSk9VTkkiLCBTdHJpbmcuZm9ybWF0KExvY2FsZS5VUywgIiVTIiwgImpha29iIGFyam91bmkiKSk7CisgICAgICAgIC8vIEluIFR1cmtpc2gtbGFuZ3VhZ2UgbG9jYWxlcywgdGhlcmUncyBhIGRvdHRlZCBjYXBpdGFsICJpIi4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJKQUtPQiBBUkpPVU5cdTAxMzAiLCBTdHJpbmcuZm9ybWF0KG5ldyBMb2NhbGUoInRyIiwgIlRSIiksICIlUyIsICJqYWtvYiBhcmpvdW5pIikpOworICAgIH0KKworICAgIC8vIENyZWF0aW5nIGEgTnVtYmVyRm9ybWF0IGlzIGV4cGVuc2l2ZSwgc28gd2UgbGlrZSB0byByZXVzZSB0aGVtLCBidXQgd2UgbmVlZCB0byBiZSBjYXJlZnVsCisgICAgLy8gYmVjYXVzZSB0aGV5J3JlIG11dGFibGUuCisgICAgcHVibGljIHZvaWQgdGVzdF9OdW1iZXJGb3JtYXRfcmV1c2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI3LjAwMDAwMCA3IiwgU3RyaW5nLmZvcm1hdCgiJS42ZiAlZCIsIDcuMCwgNykpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ3JvdXBpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGhlIGludGVyZXN0aW5nIGNhc2UgaXMgLTEyMywgd2hlcmUgeW91IG1pZ2h0IG5haXZlbHkgb3V0cHV0ICItLDEyMyIgaWYgeW91J3JlIGp1c3QKKyAgICAgICAgLy8gaW5zZXJ0aW5nIGEgc2VwYXJhdG9yIGV2ZXJ5IHRocmVlIGNoYXJhY3RlcnMuIFRoZSBjYXNlcyB3aGVyZSB0aGVyZSBhcmUgdGhyZWUgZGlnaXRzCisgICAgICAgIC8vIGJlZm9yZSB0aGUgZmlyc3Qgc2VwYXJhdG9yIG1heSBhbHNvIGJlIGludGVyZXN0aW5nLgorICAgICAgICBhc3NlcnRFcXVhbHMoIi0xIiwgU3RyaW5nLmZvcm1hdCgiJSxkIiwgLTEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCItMTIiLCBTdHJpbmcuZm9ybWF0KCIlLGQiLCAtMTIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCItMTIzIiwgU3RyaW5nLmZvcm1hdCgiJSxkIiwgLTEyMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi0xLDIzNCIsIFN0cmluZy5mb3JtYXQoIiUsZCIsIC0xMjM0KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLTEyLDM0NSIsIFN0cmluZy5mb3JtYXQoIiUsZCIsIC0xMjM0NSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi0xMjMsNDU2IiwgU3RyaW5nLmZvcm1hdCgiJSxkIiwgLTEyMzQ1NikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi0xLDIzNCw1NjciLCBTdHJpbmcuZm9ybWF0KCIlLGQiLCAtMTIzNDU2NykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi0xMiwzNDUsNjc4IiwgU3RyaW5nLmZvcm1hdCgiJSxkIiwgLTEyMzQ1Njc4KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLTEyMyw0NTYsNzg5IiwgU3RyaW5nLmZvcm1hdCgiJSxkIiwgLTEyMzQ1Njc4OSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEiLCBTdHJpbmcuZm9ybWF0KCIlLGQiLCAxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTIiLCBTdHJpbmcuZm9ybWF0KCIlLGQiLCAxMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEyMyIsIFN0cmluZy5mb3JtYXQoIiUsZCIsIDEyMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEsMjM0IiwgU3RyaW5nLmZvcm1hdCgiJSxkIiwgMTIzNCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEyLDM0NSIsIFN0cmluZy5mb3JtYXQoIiUsZCIsIDEyMzQ1KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTIzLDQ1NiIsIFN0cmluZy5mb3JtYXQoIiUsZCIsIDEyMzQ1NikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEsMjM0LDU2NyIsIFN0cmluZy5mb3JtYXQoIiUsZCIsIDEyMzQ1NjcpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMiwzNDUsNjc4IiwgU3RyaW5nLmZvcm1hdCgiJSxkIiwgMTIzNDU2NzgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMjMsNDU2LDc4OSIsIFN0cmluZy5mb3JtYXQoIiUsZCIsIDEyMzQ1Njc4OSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZm9ybWF0TnVsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBXZSBmYXN0LXBhdGggJXMgYW5kICVkICh3aXRoIG5vIGNvbmZpZ3VyYXRpb24pIGJ1dCBuZWVkIHRvIG1ha2Ugc3VyZSB3ZSBoYW5kbGUgdGhlCisgICAgICAgIC8vIHNwZWNpYWwgY2FzZSBvZiB0aGUgbnVsbCBhcmd1bWVudC4uLgorICAgICAgICBhc3NlcnRFcXVhbHMoIm51bGwiLCBTdHJpbmcuZm9ybWF0KExvY2FsZS5VUywgIiVzIiwgKFN0cmluZykgbnVsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm51bGwiLCBTdHJpbmcuZm9ybWF0KExvY2FsZS5VUywgIiVkIiwgKEludGVnZXIpIG51bGwpKTsKKyAgICAgICAgLy8gLi4ud2l0aG91dCBzY3Jld2luZyB1cCBjb252ZXJzaW9ucyB0aGF0IGRvbid0IHRha2UgYW4gYXJndW1lbnQuCisgICAgICAgIGFzc2VydEVxdWFscygiJSIsIFN0cmluZy5mb3JtYXQoTG9jYWxlLlVTLCAiJSUiKSk7CisgICAgfQorCisgICAgLy8gQWxsZWdlZCByZWdyZXNzaW9uIHRlc3RzIGZvciBoaXN0b3JpY2FsIGJ1Z3MuIChJdCdzIHVuY2xlYXIgd2hldGhlciB0aGUgYnVncyB3ZXJlIGluCisgICAgLy8gQmlnRGVjaW1hbCBvciBGb3JtYXR0ZXIuKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfQmlnRGVjaW1hbEZvcm1hdHRpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQmlnRGVjaW1hbFtdIGlucHV0ID0gbmV3IEJpZ0RlY2ltYWxbXSB7CisgICAgICAgICAgICBuZXcgQmlnRGVjaW1hbCgiMjAuMDAwMDAiKSwKKyAgICAgICAgICAgIG5ldyBCaWdEZWNpbWFsKCIyMC4wMDAwMDAiKSwKKyAgICAgICAgICAgIG5ldyBCaWdEZWNpbWFsKCIuMiIpLAorICAgICAgICAgICAgbmV3IEJpZ0RlY2ltYWwoIjIiKSwKKyAgICAgICAgICAgIG5ldyBCaWdEZWNpbWFsKCItMiIpLAorICAgICAgICAgICAgbmV3IEJpZ0RlY2ltYWwoIjIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCIpLAorICAgICAgICAgICAgbmV3IEJpZ0RlY2ltYWwoIjIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIikKKyAgICAgICAgfTsKKyAgICAgICAgU3RyaW5nW10gb3V0cHV0ID0gbmV3IFN0cmluZ1tdIHsKKyAgICAgICAgICAgICIyMC4wMCIsCisgICAgICAgICAgICAiMjAuMDAiLAorICAgICAgICAgICAgIjAuMjAiLAorICAgICAgICAgICAgIjIuMDAiLAorICAgICAgICAgICAgIi0yLjAwIiwKKyAgICAgICAgICAgICIyMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAuMDAiLAorICAgICAgICAgICAgIjIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwLjAwIgorICAgICAgICB9OworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGlucHV0Lmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICBTdHJpbmcgcmVzdWx0ID0gU3RyaW5nLmZvcm1hdCgiJS4yZiIsIGlucHV0W2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiaW5wdXQ9XCIiICsgaW5wdXRbaV0gKyAiXCIsICIgKyAiLGV4cGVjdGVkPSIgKyBvdXRwdXRbaV0gKyAiLGFjdHVhbD0iICsgcmVzdWx0LAorICAgICAgICAgICAgICAgICAgICBvdXRwdXRbaV0sIHJlc3VsdCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvTG9jYWxlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL0xvY2FsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NDFkZDY2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL0xvY2FsZVRlc3QuamF2YQpAQCAtMCwwICsxLDkzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudGV4dC5CcmVha0l0ZXJhdG9yOworaW1wb3J0IGphdmEudGV4dC5Db2xsYXRvcjsKK2ltcG9ydCBqYXZhLnRleHQuRGF0ZUZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuRGF0ZUZvcm1hdFN5bWJvbHM7CitpbXBvcnQgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXRTeW1ib2xzOworaW1wb3J0IGphdmEudGV4dC5OdW1iZXJGb3JtYXQ7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworcHVibGljIGNsYXNzIExvY2FsZVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIC8vIGh0dHA6Ly9iLzI2MTEzMTE7IGlmIHRoZXJlJ3Mgbm8gZGlzcGxheSBsYW5ndWFnZS9jb3VudHJ5L3ZhcmlhbnQsIHVzZSB0aGUgcmF3IGNvZGVzLgorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGlzcGxheU5hbWVfcmF3KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIExvY2FsZSB3ZWlyZCA9IG5ldyBMb2NhbGUoIkFhQmJDYyIsICJEZEVlRmYiLCAiR2dIaElpIik7CisgICAgICAgIGFzc2VydEVxdWFscygiYWFiYmNjIiwgd2VpcmQuZ2V0TGFuZ3VhZ2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgd2VpcmQuZ2V0RGlzcGxheUxhbmd1YWdlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkRERUVGRiIsIHdlaXJkLmdldENvdW50cnkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgd2VpcmQuZ2V0RGlzcGxheUNvdW50cnkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiR2dIaElpIiwgd2VpcmQuZ2V0VmFyaWFudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCB3ZWlyZC5nZXREaXNwbGF5VmFyaWFudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhYWJiY2MgKERERUVGRixHZ0hoSWkpIiwgd2VpcmQuZ2V0RGlzcGxheU5hbWUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREaXNwbGF5TmFtZV9lYXN5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiRW5nbGlzaCIsIExvY2FsZS5FTkdMSVNILmdldERpc3BsYXlMYW5ndWFnZShMb2NhbGUuRU5HTElTSCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkdlcm1hbiIsIExvY2FsZS5HRVJNQU4uZ2V0RGlzcGxheUxhbmd1YWdlKExvY2FsZS5FTkdMSVNIKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRW5nbGlzY2giLCBMb2NhbGUuRU5HTElTSC5nZXREaXNwbGF5TGFuZ3VhZ2UoTG9jYWxlLkdFUk1BTikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkRldXRzY2giLCBMb2NhbGUuR0VSTUFOLmdldERpc3BsYXlMYW5ndWFnZShMb2NhbGUuR0VSTUFOKSk7CisgICAgfQorCisgICAgLy8gaHR0cDovL2IvMzQ1MjYxMTsgTG9jYWxlLmdldERpc3BsYXlMYW5ndWFnZSBmYWlscyBmb3IgdGhlIG9ic29sZXRlIGxhbmd1YWdlIGNvZGVzLgorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGlzcGxheU5hbWVfb2Jzb2xldGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gaGUgKG5ldykgLT4gaXcgKG9ic29sZXRlKQorICAgICAgICBhc3NlcnRPYnNvbGV0ZSgiaGUiLCAiaXciLCAi16LXkdeo15nXqiIpOworICAgICAgICAvLyBpZCAobmV3KSAtPiBpbiAob2Jzb2xldGUpCisgICAgICAgIGFzc2VydE9ic29sZXRlKCJpZCIsICJpbiIsICJCYWhhc2EgSW5kb25lc2lhIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhc3NlcnRPYnNvbGV0ZShTdHJpbmcgbmV3Q29kZSwgU3RyaW5nIG9sZENvZGUsIFN0cmluZyBkaXNwbGF5TmFtZSkgeworICAgICAgICAvLyBFaXRoZXIgY29kZSBzaG91bGQgZ2V0IHlvdSB0aGUgc2FtZSBsb2NhbGUuCisgICAgICAgIExvY2FsZSBuZXdMb2NhbGUgPSBuZXcgTG9jYWxlKG5ld0NvZGUpOworICAgICAgICBMb2NhbGUgb2xkTG9jYWxlID0gbmV3IExvY2FsZShvbGRDb2RlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ld0xvY2FsZSwgb2xkTG9jYWxlKTsKKworICAgICAgICAvLyBObyBtYXR0ZXIgd2hhdCBjb2RlIHlvdSB1c2VkIHRvIGNyZWF0ZSB0aGUgbG9jYWxlLCB5b3Ugc2hvdWxkIGdldCB0aGUgb2xkIGNvZGUgYmFjay4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKG9sZENvZGUsIG5ld0xvY2FsZS5nZXRMYW5ndWFnZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG9sZENvZGUsIG9sZExvY2FsZS5nZXRMYW5ndWFnZSgpKTsKKworICAgICAgICAvLyBDaGVjayB3ZSBnZXQgdGhlIHJpZ2h0IGRpc3BsYXkgbmFtZS4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGRpc3BsYXlOYW1lLCBuZXdMb2NhbGUuZ2V0RGlzcGxheUxhbmd1YWdlKG5ld0xvY2FsZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZGlzcGxheU5hbWUsIG9sZExvY2FsZS5nZXREaXNwbGF5TGFuZ3VhZ2UobmV3TG9jYWxlKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhkaXNwbGF5TmFtZSwgbmV3TG9jYWxlLmdldERpc3BsYXlMYW5ndWFnZShvbGRMb2NhbGUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGRpc3BsYXlOYW1lLCBvbGRMb2NhbGUuZ2V0RGlzcGxheUxhbmd1YWdlKG9sZExvY2FsZSkpOworCisgICAgICAgIC8vIENoZWNrIHRoYXQgbm9uZSBvZiB0aGUgJ2dldEF2YWlsYWJsZUxvY2FsZXMnIG1ldGhvZHMgYXJlIGFjY2lkZW50YWxseSByZXR1cm5pbmcgdHdvCisgICAgICAgIC8vIGVxdWFsIGxvY2FsZXMgKGJlY2F1c2UgdG8gSUNVIHRoZXkncmUgZGlmZmVyZW50LCBidXQgd2UgbWFuZ2xlIG9uZSBpbnRvIHRoZSBvdGhlcikuCisgICAgICAgIGFzc2VydE9uY2UobmV3TG9jYWxlLCBCcmVha0l0ZXJhdG9yLmdldEF2YWlsYWJsZUxvY2FsZXMoKSk7CisgICAgICAgIGFzc2VydE9uY2UobmV3TG9jYWxlLCBDYWxlbmRhci5nZXRBdmFpbGFibGVMb2NhbGVzKCkpOworICAgICAgICBhc3NlcnRPbmNlKG5ld0xvY2FsZSwgQ29sbGF0b3IuZ2V0QXZhaWxhYmxlTG9jYWxlcygpKTsKKyAgICAgICAgYXNzZXJ0T25jZShuZXdMb2NhbGUsIERhdGVGb3JtYXQuZ2V0QXZhaWxhYmxlTG9jYWxlcygpKTsKKyAgICAgICAgYXNzZXJ0T25jZShuZXdMb2NhbGUsIERhdGVGb3JtYXRTeW1ib2xzLmdldEF2YWlsYWJsZUxvY2FsZXMoKSk7CisgICAgICAgIGFzc2VydE9uY2UobmV3TG9jYWxlLCBOdW1iZXJGb3JtYXQuZ2V0QXZhaWxhYmxlTG9jYWxlcygpKTsKKyAgICAgICAgYXNzZXJ0T25jZShuZXdMb2NhbGUsIExvY2FsZS5nZXRBdmFpbGFibGVMb2NhbGVzKCkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYXNzZXJ0T25jZShMb2NhbGUgZWxlbWVudCwgTG9jYWxlW10gYXJyYXkpIHsKKyAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgZm9yIChMb2NhbGUgbCA6IGFycmF5KSB7CisgICAgICAgICAgICBpZiAobC5lcXVhbHMoZWxlbWVudCkpIHsKKyAgICAgICAgICAgICAgICArK2NvdW50OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygxLCBjb3VudCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZEFic3RyYWN0TWFwVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZEFic3RyYWN0TWFwVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE0YzRkZDAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkQWJzdHJhY3RNYXBUZXN0LmphdmEKQEAgLTAsMCArMSwxMjEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuQWJzdHJhY3RNYXA7CitpbXBvcnQgamF2YS51dGlsLkFic3RyYWN0U2V0OworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkQWJzdHJhY3RNYXBUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgQU1UIGFtdCA9IG5ldyBBTVQoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChhbXQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIEFic3RyYWN0TWFwPFN0cmluZywgU3RyaW5nPiBhbXQxID0gbmV3IEFNVCgpOworICAgICAgICBBYnN0cmFjdE1hcDxTdHJpbmcsIFN0cmluZz4gYW10MiA9IG5ldyBBTVQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiYXNzZXJ0IDAiLCBhbXQxLmVxdWFscyhhbXQyKSk7CisgICAgICAgIGFzc2VydFRydWUoImFzc2VydCAxIiwgYW10MS5lcXVhbHMoYW10MSkpOworICAgICAgICBhc3NlcnRUcnVlKCJhc3NlcnQgMiIsIGFtdDIuZXF1YWxzKGFtdDEpKTsKKyAgICAgICAgYW10MS5wdXQoIjEiLCAib25lIik7CisgICAgICAgIGFzc2VydEZhbHNlKCJhc3NlcnQgMyIsIGFtdDEuZXF1YWxzKGFtdDIpKTsKKyAgICAgICAgYW10MS5wdXQoIjIiLCAidHdvIik7CisgICAgICAgIGFtdDEucHV0KCIzIiwgInRocmVlIik7CisKKyAgICAgICAgYW10Mi5wdXQoIjEiLCAib25lIik7CisgICAgICAgIGFtdDIucHV0KCIyIiwgInR3byIpOworICAgICAgICBhbXQyLnB1dCgiMyIsICJ0aHJlZSIpOworICAgICAgICBhc3NlcnRUcnVlKCJhc3NlcnQgNCIsIGFtdDEuZXF1YWxzKGFtdDIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoImFzc2VydCA1IiwgYW10MS5lcXVhbHModGhpcykpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGFzaENvZGUoKSB7CisgICAgICAgIEFNVCBhbXQxID0gbmV3IEFNVCgpOworICAgICAgICBBTVQgYW10MiA9IG5ldyBBTVQoKTsKKyAgICAgICAgYW10MS5wdXQoIjEiLCAib25lIik7CisKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShhbXQxLmhhc2hDb2RlKCksIGFtdDIuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0VtcHR5KCkgeworICAgICAgICBBTVQgYW10ID0gbmV3IEFNVCgpOworICAgICAgICBhc3NlcnRUcnVlKGFtdC5pc0VtcHR5KCkpOworICAgICAgICBhbXQucHV0KCIxIiwgIm9uZSIpOworICAgICAgICBhc3NlcnRGYWxzZShhbXQuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3B1dCgpIHsKKyAgICAgICAgQU1UIGFtdCA9IG5ldyBBTVQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGFtdC5zaXplKCkpOworICAgICAgICBhbXQucHV0KCIxIiwgIm9uZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgYW10LnNpemUoKSk7CisgICAgICAgIGFtdC5wdXQoIjIiLCAidHdvIik7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBhbXQuc2l6ZSgpKTsKKyAgICAgICAgYW10LnB1dCgiMyIsICJ0aHJlZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgYW10LnNpemUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zaXplKCkgeworICAgICAgICBBTVQgYW10ID0gbmV3IEFNVCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYW10LnNpemUoKSk7CisgICAgICAgIGFtdC5wdXQoIjEiLCAib25lIik7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBhbXQuc2l6ZSgpKTsKKyAgICAgICAgYW10LnB1dCgiMiIsICJ0d28iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGFtdC5zaXplKCkpOworICAgICAgICBhbXQucHV0KCIzIiwgInRocmVlIik7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBhbXQuc2l6ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nKCkgeworICAgICAgICBBTVQgYW10ID0gbmV3IEFNVCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoInt9IiwgYW10LnRvU3RyaW5nKCkpOworICAgICAgICBhbXQucHV0KCIxIiwgIm9uZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInsxPW9uZX0iLCBhbXQudG9TdHJpbmcoKSk7CisgICAgICAgIGFtdC5wdXQoIjIiLCAidHdvIik7CisgICAgICAgIGFzc2VydEVxdWFscygiezE9b25lLCAyPXR3b30iLCBhbXQudG9TdHJpbmcoKSk7CisgICAgICAgIGFtdC5wdXQoIjMiLCAidGhyZWUiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ7MT1vbmUsIDI9dHdvLCAzPXRocmVlfSIsIGFtdC50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgQU1UIGV4dGVuZHMgQWJzdHJhY3RNYXA8U3RyaW5nLCBTdHJpbmc+IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PEVudHJ5PFN0cmluZywgU3RyaW5nPj4gZW50cmllcyA9IG5ldyBBcnJheUxpc3Q8RW50cnk8U3RyaW5nLCBTdHJpbmc+PigpOworCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHB1dChTdHJpbmcga2V5LCBTdHJpbmcgdmFsdWUpIHsKKyAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSByZW1vdmUoa2V5KTsKKyAgICAgICAgICAgIGVudHJpZXMuYWRkKG5ldyBBYnN0cmFjdE1hcC5TaW1wbGVFbnRyeTxTdHJpbmcsIFN0cmluZz4oa2V5LCB2YWx1ZSkpOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU2V0PEVudHJ5PFN0cmluZywgU3RyaW5nPj4gZW50cnlTZXQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEFic3RyYWN0U2V0PEVudHJ5PFN0cmluZywgU3RyaW5nPj4oKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBJdGVyYXRvcjxFbnRyeTxTdHJpbmcsIFN0cmluZz4+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW50cmllcy5pdGVyYXRvcigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW50cmllcy5zaXplKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRBYnN0cmFjdFNldFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRBYnN0cmFjdFNldFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNmUwNTE5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZEFic3RyYWN0U2V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTEwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdFNlcXVlbnRpYWxMaXN0OworaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKKworcHVibGljIGNsYXNzIE9sZEFic3RyYWN0U2V0VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIGNsYXNzIE1vY2tfQWJzdHJhY3RTZXQgZXh0ZW5kcyBBYnN0cmFjdFNldHsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIEl0ZXJhdG9yIGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcigpIHsKKyAgICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBuZXh0KCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RIYXNoQ29kZSgpIHsKKyAgICAgICAgQWJzdHJhY3RTZXQgYXMgPSBuZXcgTW9ja19BYnN0cmFjdFNldCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKGFzLmhhc2hDb2RlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHMoKSB7CisgICAgICAgIEFic3RyYWN0U2V0IGFzMSA9IG5ldyBNb2NrX0Fic3RyYWN0U2V0KCk7CisgICAgICAgIEFic3RyYWN0U2V0IGFzMiA9IG5ldyBNb2NrX0Fic3RyYWN0U2V0KCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShhczEuZXF1YWxzKGFzMikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVBbGwoKSB7CisgICAgICAgIEFic3RyYWN0U2V0IGFzID0gbmV3IEFic3RyYWN0U2V0KCl7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBJdGVyYXRvciBpdGVyYXRvcigpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKCkgeworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IG5leHQoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB9OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMTA7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzLnJlbW92ZUFsbChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBDb2xsZWN0aW9uIGMgPSBuZXcgVmVjdG9yKCk7CisgICAgICAgIGMuYWRkKG51bGwpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXMucmVtb3ZlQWxsKGMpOworICAgICAgICAgICAgZmFpbCgiVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYXMgPSBuZXcgTW9ja19BYnN0cmFjdFNldCgpOworCisgICAgICAgIGFzLnJlbW92ZUFsbChjKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkQW5kcm9pZEFycmF5TGlzdFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRBbmRyb2lkQXJyYXlMaXN0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVlYWEzYjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkQW5kcm9pZEFycmF5TGlzdFRlc3QuamF2YQpAQCAtMCwwICsxLDkxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CisKKy8qKgorICogVGhpcyB0ZXN0IGNhc2UgdGVzdHMgc2V2ZXJhbCBvZnRlbiB1c2VkIGZ1bmN0aW9uYWxpdHkgb2YgQXJyYXlMaXN0cy4KKyAqLworcHVibGljIGNsYXNzIE9sZEFuZHJvaWRBcnJheUxpc3RUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdEFycmF5TGlzdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBBcnJheUxpc3QgYXJyYXkgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBhcnJheS5zaXplKCkpOworICAgICAgICBhc3NlcnRUcnVlKGFycmF5LmlzRW1wdHkoKSk7CisKKyAgICAgICAgYXJyYXkuYWRkKG5ldyBJbnRlZ2VyKDApKTsKKyAgICAgICAgYXJyYXkuYWRkKDAsIG5ldyBJbnRlZ2VyKDEpKTsKKyAgICAgICAgYXJyYXkuYWRkKDEsIG5ldyBJbnRlZ2VyKDIpKTsKKyAgICAgICAgYXJyYXkuYWRkKG5ldyBJbnRlZ2VyKDMpKTsKKyAgICAgICAgYXJyYXkuYWRkKG5ldyBJbnRlZ2VyKDEpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgYXJyYXkuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoYXJyYXkuaXNFbXB0eSgpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgKChJbnRlZ2VyKSBhcnJheS5nZXQoMCkpLmludFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgKChJbnRlZ2VyKSBhcnJheS5nZXQoMSkpLmludFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgKChJbnRlZ2VyKSBhcnJheS5nZXQoMikpLmludFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgKChJbnRlZ2VyKSBhcnJheS5nZXQoMykpLmludFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgKChJbnRlZ2VyKSBhcnJheS5nZXQoNCkpLmludFZhbHVlKCkpOworCisgICAgICAgIGFzc2VydEZhbHNlKGFycmF5LmNvbnRhaW5zKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhcnJheS5jb250YWlucyhuZXcgSW50ZWdlcigyKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYXJyYXkuaW5kZXhPZihuZXcgSW50ZWdlcigxKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgYXJyYXkubGFzdEluZGV4T2YobmV3IEludGVnZXIoMSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhcnJheS5pbmRleE9mKG5ldyBJbnRlZ2VyKDUpKSA8IDApOworICAgICAgICBhc3NlcnRUcnVlKGFycmF5Lmxhc3RJbmRleE9mKG5ldyBJbnRlZ2VyKDUpKSA8IDApOworCisgICAgICAgIGFycmF5LnJlbW92ZSgxKTsKKyAgICAgICAgYXJyYXkucmVtb3ZlKDEpOworCisgICAgICAgIGFzc2VydEVxdWFscygzLCBhcnJheS5zaXplKCkpOworICAgICAgICBhc3NlcnRGYWxzZShhcnJheS5pc0VtcHR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgKChJbnRlZ2VyKSBhcnJheS5nZXQoMCkpLmludFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgKChJbnRlZ2VyKSBhcnJheS5nZXQoMSkpLmludFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgKChJbnRlZ2VyKSBhcnJheS5nZXQoMikpLmludFZhbHVlKCkpOworCisgICAgICAgIGFzc2VydEZhbHNlKGFycmF5LmNvbnRhaW5zKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoYXJyYXkuY29udGFpbnMobmV3IEludGVnZXIoMikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGFycmF5LmluZGV4T2YobmV3IEludGVnZXIoMSkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGFycmF5Lmxhc3RJbmRleE9mKG5ldyBJbnRlZ2VyKDEpKSk7CisgICAgICAgIGFzc2VydFRydWUoYXJyYXkuaW5kZXhPZihuZXcgSW50ZWdlcig1KSkgPCAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhcnJheS5sYXN0SW5kZXhPZihuZXcgSW50ZWdlcig1KSkgPCAwKTsKKworICAgICAgICBhcnJheS5jbGVhcigpOworCisgICAgICAgIGFzc2VydEVxdWFscygwLCBhcnJheS5zaXplKCkpOworICAgICAgICBhc3NlcnRUcnVlKGFycmF5LmlzRW1wdHkoKSk7CisgICAgICAgIGFzc2VydFRydWUoYXJyYXkuaW5kZXhPZihuZXcgSW50ZWdlcig1KSkgPCAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhcnJheS5sYXN0SW5kZXhPZihuZXcgSW50ZWdlcig1KSkgPCAwKTsKKworICAgICAgICBBcnJheUxpc3QgYWwgPSBuZXcgQXJyYXlMaXN0KCk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoYWwucmVtb3ZlKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoYWwucmVtb3ZlKCJzdHJpbmciKSk7CisKKyAgICAgICAgYWwuYWRkKCJzdHJpbmciKTsKKyAgICAgICAgYWwuYWRkKG51bGwpOworCisgICAgICAgIGFzc2VydFRydWUoYWwucmVtb3ZlKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhbC5yZW1vdmUoInN0cmluZyIpKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRBbmRyb2lkSGFzaE1hcFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRBbmRyb2lkSGFzaE1hcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYmU0MTlhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZEFuZHJvaWRIYXNoTWFwVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjM5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIEdvb2dsZSBJbmMuCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgT2xkQW5kcm9pZEhhc2hNYXBUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSW50ZWdlciBPTkUgPSAxOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEludGVnZXIgVFdPID0gMjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBJbnRlZ2VyIFRIUkVFID0gMzsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBJbnRlZ2VyIEZPVVIgPSA0OworCisgICAgcHJpdmF0ZSB2b2lkIGFkZEl0ZW1zKEhhc2hNYXA8U3RyaW5nLCBJbnRlZ2VyPiBtYXApIHsKKyAgICAgICAgbWFwLnB1dCgib25lIiwgT05FKTsKKyAgICAgICAgbWFwLnB1dCgidHdvIiwgVFdPKTsKKyAgICAgICAgbWFwLnB1dCgidGhyZWUiLCBUSFJFRSk7CisgICAgICAgIG1hcC5wdXQoImZvdXIiLCBGT1VSKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgbWFwLnNpemUoKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE9ORSwgbWFwLmdldCgib25lIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoVFdPLCBtYXAuZ2V0KCJ0d28iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhUSFJFRSwgbWFwLmdldCgidGhyZWUiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhGT1VSLCBtYXAuZ2V0KCJmb3VyIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSGFzaE1hcDxTdHJpbmcsIEludGVnZXI+IG1hcCA9IG5ldyBIYXNoTWFwPFN0cmluZywgSW50ZWdlcj4oKTsKKyAgICAgICAgYWRkSXRlbXMobWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xlYXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSGFzaE1hcDxTdHJpbmcsIEludGVnZXI+IG1hcCA9IG5ldyBIYXNoTWFwPFN0cmluZywgSW50ZWdlcj4oKTsKKworICAgICAgICBhZGRJdGVtcyhtYXApOworICAgICAgICBtYXAuY2xlYXIoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG1hcC5zaXplKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSGFzaE1hcDxTdHJpbmcsIEludGVnZXI+IG1hcCA9IG5ldyBIYXNoTWFwPFN0cmluZywgSW50ZWdlcj4oKTsKKworICAgICAgICBhZGRJdGVtcyhtYXApOworICAgICAgICBtYXAucmVtb3ZlKCJ0aHJlZSIpOworICAgICAgICBhc3NlcnROdWxsKG1hcC5nZXQoInRocmVlIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYW5pcHVsYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEhhc2hNYXA8U3RyaW5nLCBJbnRlZ2VyPiBtYXAgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIEludGVnZXI+KCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXAuaXNFbXB0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG1hcC5zaXplKCkpOworICAgICAgICBhc3NlcnROdWxsKG1hcC5nZXQobnVsbCkpOworICAgICAgICBhc3NlcnROdWxsKG1hcC5nZXQoIm9uZSIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWFwLmNvbnRhaW5zS2V5KCJvbmUiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG1hcC5jb250YWluc1ZhbHVlKG5ldyBJbnRlZ2VyKDEpKSk7CisgICAgICAgIGFzc2VydE51bGwobWFwLnJlbW92ZShudWxsKSk7CisgICAgICAgIGFzc2VydE51bGwobWFwLnJlbW92ZSgib25lIikpOworCisgICAgICAgIGFzc2VydE51bGwobWFwLnB1dChudWxsLCAtMSkpOworICAgICAgICBhc3NlcnROdWxsKG1hcC5wdXQoIm9uZSIsIDEpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChtYXAucHV0KCJ0d28iLCAyKSk7CisgICAgICAgIGFzc2VydE51bGwobWFwLnB1dCgidGhyZWUiLCAzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgbWFwLnB1dChudWxsLCAwKS5pbnRWYWx1ZSgpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbWFwLmdldChudWxsKS5pbnRWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG1hcC5nZXQoIm9uZSIpLmludFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgbWFwLmdldCgidHdvIikuaW50VmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBtYXAuZ2V0KCJ0aHJlZSIpLmludFZhbHVlKCkpOworCisgICAgICAgIGFzc2VydFRydWUobWFwLmNvbnRhaW5zS2V5KG51bGwpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXAuY29udGFpbnNLZXkoIm9uZSIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXAuY29udGFpbnNLZXkoInR3byIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXAuY29udGFpbnNLZXkoInRocmVlIikpOworCisgICAgICAgIGFzc2VydFRydWUobWFwLmNvbnRhaW5zVmFsdWUobmV3IEludGVnZXIoMCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXAuY29udGFpbnNWYWx1ZShuZXcgSW50ZWdlcigxKSkpOworICAgICAgICBhc3NlcnRUcnVlKG1hcC5jb250YWluc1ZhbHVlKG5ldyBJbnRlZ2VyKDIpKSk7CisgICAgICAgIGFzc2VydFRydWUobWFwLmNvbnRhaW5zVmFsdWUobmV3IEludGVnZXIoMykpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbWFwLnJlbW92ZShudWxsKS5pbnRWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG1hcC5yZW1vdmUoIm9uZSIpLmludFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgbWFwLnJlbW92ZSgidHdvIikuaW50VmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBtYXAucmVtb3ZlKCJ0aHJlZSIpLmludFZhbHVlKCkpOworCisgICAgICAgIGFzc2VydFRydWUobWFwLmlzRW1wdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBtYXAuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChtYXAuZ2V0KG51bGwpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChtYXAuZ2V0KCJvbmUiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG1hcC5jb250YWluc0tleSgib25lIikpOworICAgICAgICBhc3NlcnRGYWxzZShtYXAuY29udGFpbnNWYWx1ZShuZXcgSW50ZWdlcigxKSkpOworICAgICAgICBhc3NlcnROdWxsKG1hcC5yZW1vdmUobnVsbCkpOworICAgICAgICBhc3NlcnROdWxsKG1hcC5yZW1vdmUoIm9uZSIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5SXRlcmF0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSGFzaE1hcDxTdHJpbmcsIEludGVnZXI+IG1hcCA9IG5ldyBIYXNoTWFwPFN0cmluZywgSW50ZWdlcj4oKTsKKworICAgICAgICBib29sZWFuW10gc2xvdHMgPSBuZXcgYm9vbGVhbls0XTsKKworICAgICAgICBhZGRJdGVtcyhtYXApOworCisgICAgICAgIGZvciAoU3RyaW5nIHMgOiBtYXAua2V5U2V0KCkpIHsKKyAgICAgICAgICAgIGludCBzbG90ID0gMDsKKworICAgICAgICAgICAgaWYgKHMuZXF1YWxzKCJvbmUiKSkgeworICAgICAgICAgICAgICAgIHNsb3QgPSAwOworICAgICAgICAgICAgfSBlbHNlIGlmIChzLmVxdWFscygidHdvIikpIHsKKyAgICAgICAgICAgICAgICBzbG90ID0gMTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAocy5lcXVhbHMoInRocmVlIikpIHsKKyAgICAgICAgICAgICAgICBzbG90ID0gMjsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAocy5lcXVhbHMoImZvdXIiKSkgeworICAgICAgICAgICAgICAgIHNsb3QgPSAzOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmtub3duIGtleSBpbiBIYXNoTWFwIik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChzbG90c1tzbG90XSkgeworICAgICAgICAgICAgICAgIGZhaWwoImtleSByZXR1cm5lZCBtb3JlIHRoYW4gb25jZSIpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzbG90c1tzbG90XSA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRUcnVlKHNsb3RzWzBdKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzbG90c1sxXSk7CisgICAgICAgIGFzc2VydFRydWUoc2xvdHNbMl0pOworICAgICAgICBhc3NlcnRUcnVlKHNsb3RzWzNdKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmFsdWVJdGVyYXRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBIYXNoTWFwPFN0cmluZywgSW50ZWdlcj4gbWFwID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBJbnRlZ2VyPigpOworCisgICAgICAgIGJvb2xlYW5bXSBzbG90cyA9IG5ldyBib29sZWFuWzRdOworCisgICAgICAgIGFkZEl0ZW1zKG1hcCk7CisKKyAgICAgICAgZm9yIChPYmplY3QgbyA6IG1hcC52YWx1ZXMoKSkgeworICAgICAgICAgICAgaW50IHNsb3QgPSAwOworCisgICAgICAgICAgICBpZiAoby5lcXVhbHMoT05FKSkgeworICAgICAgICAgICAgICAgIHNsb3QgPSAwOworICAgICAgICAgICAgfSBlbHNlIGlmIChvLmVxdWFscyhUV08pKSB7CisgICAgICAgICAgICAgICAgc2xvdCA9IDE7CisgICAgICAgICAgICB9IGVsc2UgaWYgKG8uZXF1YWxzKFRIUkVFKSkgeworICAgICAgICAgICAgICAgIHNsb3QgPSAyOworICAgICAgICAgICAgfSBlbHNlIGlmIChvLmVxdWFscyhGT1VSKSkgeworICAgICAgICAgICAgICAgIHNsb3QgPSAzOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmtub3duIHZhbHVlIGluIEhhc2hNYXAiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHNsb3RzW3Nsb3RdKSB7CisgICAgICAgICAgICAgICAgZmFpbCgidmFsdWUgcmV0dXJuZWQgbW9yZSB0aGFuIG9uY2UiKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc2xvdHNbc2xvdF0gPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShzbG90c1swXSk7CisgICAgICAgIGFzc2VydFRydWUoc2xvdHNbMV0pOworICAgICAgICBhc3NlcnRUcnVlKHNsb3RzWzJdKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzbG90c1szXSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVudHJ5SXRlcmF0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSGFzaE1hcDxTdHJpbmcsIEludGVnZXI+IG1hcCA9IG5ldyBIYXNoTWFwPFN0cmluZywgSW50ZWdlcj4oKTsKKworICAgICAgICBib29sZWFuW10gc2xvdHMgPSBuZXcgYm9vbGVhbls0XTsKKworICAgICAgICBhZGRJdGVtcyhtYXApOworCisgICAgICAgIGZvciAoT2JqZWN0IG8gOiBtYXAuZW50cnlTZXQoKSkgeworICAgICAgICAgICAgaW50IHNsb3QgPSAwOworCisgICAgICAgICAgICBpZiAoby50b1N0cmluZygpLmVxdWFscygib25lPTEiKSkgeworICAgICAgICAgICAgICAgIHNsb3QgPSAwOworICAgICAgICAgICAgfSBlbHNlIGlmIChvLnRvU3RyaW5nKCkuZXF1YWxzKCJ0d289MiIpKSB7CisgICAgICAgICAgICAgICAgc2xvdCA9IDE7CisgICAgICAgICAgICB9IGVsc2UgaWYgKG8udG9TdHJpbmcoKS5lcXVhbHMoInRocmVlPTMiKSkgeworICAgICAgICAgICAgICAgIHNsb3QgPSAyOworICAgICAgICAgICAgfSBlbHNlIGlmIChvLnRvU3RyaW5nKCkuZXF1YWxzKCJmb3VyPTQiKSkgeworICAgICAgICAgICAgICAgIHNsb3QgPSAzOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmtub3duIGVudHJ5IGluIEhhc2hNYXAiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHNsb3RzW3Nsb3RdKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiZW50cnkgcmV0dXJuZWQgbW9yZSB0aGFuIG9uY2UiKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc2xvdHNbc2xvdF0gPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShzbG90c1swXSk7CisgICAgICAgIGFzc2VydFRydWUoc2xvdHNbMV0pOworICAgICAgICBhc3NlcnRUcnVlKHNsb3RzWzJdKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzbG90c1szXSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVxdWFscygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBIYXNoTWFwPFN0cmluZywgU3RyaW5nPiBtYXAxID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgICAgIEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IG1hcDIgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4gbWFwMyA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOworCisgICAgICAgIG1hcDEucHV0KCJvbmUiLCAiMSIpOworICAgICAgICBtYXAxLnB1dCgidHdvIiwgIjIiKTsKKyAgICAgICAgbWFwMS5wdXQoInRocmVlIiwgIjMiKTsKKworICAgICAgICBtYXAyLnB1dCgib25lIiwgIjEiKTsKKyAgICAgICAgbWFwMi5wdXQoInR3byIsICIyIik7CisgICAgICAgIG1hcDIucHV0KCJ0aHJlZSIsICIzIik7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXAxLmVxdWFscyhtYXAyKSk7CisKKyAgICAgICAgbWFwMy5wdXQoIm9uZSIsICIxIik7CisgICAgICAgIG1hcDMucHV0KCJ0d28iLCAiMSIpOworICAgICAgICBtYXAzLnB1dCgidGhyZWUiLCAiMSIpOworCisgICAgICAgIGFzc2VydEZhbHNlKG1hcDEuZXF1YWxzKG1hcDMpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWFwMi5lcXVhbHMobWFwMykpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRBbmRyb2lkTG9jYWxlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZEFuZHJvaWRMb2NhbGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTQ3YjcwYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRBbmRyb2lkTG9jYWxlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjMxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBqYXZhLnRleHQuRGF0ZUZvcm1hdFN5bWJvbHM7CitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5DdXJyZW5jeTsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlRpbWVab25lOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0IHNvbWUgbG9jYWxlLWRlcGVuZGVudCBzdHVmZiBmb3IgQW5kcm9pZC4gVGhpcyB0ZXN0IG1haW5seSBlbnN1cmVzIHRoYXQKKyAqIG91ciBJQ1UgY29uZmlndXJhdGlvbiBpcyBjb3JyZWN0IGFuZCBjb250YWlucyBhbGwgdGhlIG5lZWRlZCBsb2NhbGVzIGFuZAorICogcmVzb3VyY2UgYnVuZGxlcy4KKyAqLworcHVibGljIGNsYXNzIE9sZEFuZHJvaWRMb2NhbGVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLy8gVGVzdCBiYXNpYyBMb2NhbGUgaW5mcmFzdHJ1Y3R1cmUuCisgICAgcHVibGljIHZvaWQgdGVzdExvY2FsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBMb2NhbGUgbG9jYWxlID0gbmV3IExvY2FsZSgiZW4iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbiIsIGxvY2FsZS50b1N0cmluZygpKTsKKworICAgICAgICBsb2NhbGUgPSBuZXcgTG9jYWxlKCJlbiIsICJVUyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVuX1VTIiwgbG9jYWxlLnRvU3RyaW5nKCkpOworCisgICAgICAgIGxvY2FsZSA9IG5ldyBMb2NhbGUoImVuIiwgIiIsICJQT1NJWCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVuX19QT1NJWCIsIGxvY2FsZS50b1N0cmluZygpKTsKKworICAgICAgICBsb2NhbGUgPSBuZXcgTG9jYWxlKCJlbiIsICJVUyIsICJQT1NJWCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVuX1VTX1BPU0lYIiwgbG9jYWxlLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qCisgICAgICogVGVzdHMgc29tZSBtdXN0LWhhdmUgbG9jYWxlcy4gVE9ETzogQWRkIGJhY2sgImRlIi4gU2VlIGRpc2N1c3Npb24KKyAgICAgKiBpbW1lZGlhdGVseSBiZWxvdyB0aGlzIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVzb3VyY2VCdW5kbGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIExvY2FsZSBlbmcgPSBuZXcgTG9jYWxlKCJlbiIsICJVUyIpOworICAgICAgICBEYXRlRm9ybWF0U3ltYm9scyBlbmdTeW1ib2xzID0gbmV3IERhdGVGb3JtYXRTeW1ib2xzKGVuZyk7CisKKyAgICAgICAgLy9Mb2NhbGUgZGV1ID0gbmV3IExvY2FsZSgiZGUiLCAiREUiKTsKKyAgICAgICAgLy9EYXRlRm9ybWF0U3ltYm9scyBkZXVTeW1ib2xzID0gbmV3IERhdGVGb3JtYXRTeW1ib2xzKGRldSk7CisKKyAgICAgICAgVGltZVpvbmUgYmVybGluID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkV1cm9wZS9CZXJsaW4iKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkphbnVhcnkiLCBlbmdTeW1ib2xzLmdldE1vbnRocygpWzBdKTsKKyAgICAgICAgLy9hc3NlcnRFcXVhbHMoIkphbnVhciIsIGRldVN5bWJvbHMuZ2V0TW9udGhzKClbMF0pOworCisgICAgICAgIGFzc2VydEVxdWFscygiU3VuZGF5IiwgZW5nU3ltYm9scy5nZXRXZWVrZGF5cygpW0NhbGVuZGFyLlNVTkRBWV0pOworICAgICAgICAvL2Fzc2VydEVxdWFscygiU29ubnRhZyIsIGRldVN5bWJvbHMuZ2V0V2Vla2RheXMoKVtDYWxlbmRhci5TVU5EQVldKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkNlbnRyYWwgRXVyb3BlYW4gVGltZSIsCisgICAgICAgICAgICAgICAgYmVybGluLmdldERpc3BsYXlOYW1lKGZhbHNlLCBUaW1lWm9uZS5MT05HLCBlbmcpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDZW50cmFsIEV1cm9wZWFuIFN1bW1lciBUaW1lIiwKKyAgICAgICAgICAgICAgICBiZXJsaW4uZ2V0RGlzcGxheU5hbWUodHJ1ZSwgVGltZVpvbmUuTE9ORywgZW5nKSk7CisKKyAgICAgICAgLy9hc3NlcnRFcXVhbHMoIk1pdHRlbGV1cm9wXHUwMEU0aXNjaGUgWmVpdCIsCisgICAgICAgIC8vICAgICAgICBiZXJsaW4uZ2V0RGlzcGxheU5hbWUoZmFsc2UsIFRpbWVab25lLkxPTkcsIGRldSkpOworICAgICAgICAvL2Fzc2VydEVxdWFscygiTWl0dGVsZXVyb3BcdTAwRTRpc2NoZSBTb21tZXJ6ZWl0IiwKKyAgICAgICAgLy8gICAgICAgIGJlcmxpbi5nZXREaXNwbGF5TmFtZSh0cnVlLCBUaW1lWm9uZS5MT05HLCBkZXUpKTsKKworICAgICAgICBhc3NlcnRUcnVlKGVuZ1N5bWJvbHMuZ2V0Wm9uZVN0cmluZ3MoKS5sZW5ndGggPiAxMDApOworICAgIH0KKworICAgIC8qCisgICAgICogRGlzYWJsZWQgdmVyc2lvbiBvZiB0aGUgYWJvdmUgdGVzdC4gVGhlIHZlcnNpb24gYWJvdmUgb21pdHMKKyAgICAgKiBjaGVja3MgZm9yIHN0dWZmIGluIHRoZSAiZGUiIGxvY2FsZSwgYmVjYXVzZSB3ZSBzdHJpcHBlZCB0aGF0CisgICAgICogb3V0IGFzIHBhcnQgb2YgdGhlIGZsYXNoIHJlZHVjdGlvbiBlZmZvcnQgKHNvIHRoYXQgd2UgY291bGQKKyAgICAgKiBzdGlsbCBzaGlwIG9uIERyZWFtKS4gV2UgZXhwZWN0IHRvIGhhdmUgYSBiYXNlbGluZSB0YXJnZXQgdGhhdAorICAgICAqIGluY2x1ZGVzIGEgbGFyZ2UgZW5vdWdoIHN5c3RlbSBwYXJ0aXRpb24gdG8gaW5jbHVkZSAiZGUiCisgICAgICogaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIGxhc3Qgb2ZmaWNpYWwgcmVsZWFzZSBmb3IgRHJlYW0gKHdoZW5ldmVyCisgICAgICogdGhhdCBtYXkgYmUpLgorICAgICAqCisgICAgLy8gVGVzdCBzb21lIG11c3QtaGF2ZSBsb2NhbGVzLgorICAgIEBMYXJnZVRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVzb3VyY2VCdW5kbGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIExvY2FsZSBlbmcgPSBuZXcgTG9jYWxlKCJlbiIsICJVUyIpOworICAgICAgICBEYXRlRm9ybWF0U3ltYm9scyBlbmdTeW1ib2xzID0gbmV3IERhdGVGb3JtYXRTeW1ib2xzKGVuZyk7CisKKyAgICAgICAgTG9jYWxlIGRldSA9IG5ldyBMb2NhbGUoImRlIiwgIkRFIik7CisgICAgICAgIERhdGVGb3JtYXRTeW1ib2xzIGRldVN5bWJvbHMgPSBuZXcgRGF0ZUZvcm1hdFN5bWJvbHMoZGV1KTsKKworICAgICAgICBUaW1lWm9uZSBiZXJsaW4gPSBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiRXVyb3BlL0JlcmxpbiIpOworCisgICAgICAgIGFzc2VydEVxdWFscygiSmFudWFyeSIsIGVuZ1N5bWJvbHMuZ2V0TW9udGhzKClbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoIkphbnVhciIsIGRldVN5bWJvbHMuZ2V0TW9udGhzKClbMF0pOworCisgICAgICAgIGFzc2VydEVxdWFscygiU3VuZGF5IiwgZW5nU3ltYm9scy5nZXRXZWVrZGF5cygpW0NhbGVuZGFyLlNVTkRBWV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNvbm50YWciLCBkZXVTeW1ib2xzLmdldFdlZWtkYXlzKClbQ2FsZW5kYXIuU1VOREFZXSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDZW50cmFsIEV1cm9wZWFuIFRpbWUiLAorICAgICAgICAgICAgICAgIGJlcmxpbi5nZXREaXNwbGF5TmFtZShmYWxzZSwgVGltZVpvbmUuTE9ORywgZW5nKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQ2VudHJhbCBFdXJvcGVhbiBTdW1tZXIgVGltZSIsCisgICAgICAgICAgICAgICAgYmVybGluLmdldERpc3BsYXlOYW1lKHRydWUsIFRpbWVab25lLkxPTkcsIGVuZykpOworCisgICAgICAgIGFzc2VydEVxdWFscygiTWl0dGVsZXVyb3BcdTAwRTRpc2NoZSBaZWl0IiwKKyAgICAgICAgICAgICAgICBiZXJsaW4uZ2V0RGlzcGxheU5hbWUoZmFsc2UsIFRpbWVab25lLkxPTkcsIGRldSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIk1pdHRlbGV1cm9wXHUwMEU0aXNjaGUgU29tbWVyemVpdCIsCisgICAgICAgICAgICAgICAgYmVybGluLmdldERpc3BsYXlOYW1lKHRydWUsIFRpbWVab25lLkxPTkcsIGRldSkpOworCisgICAgICAgIGFzc2VydFRydWUoZW5nU3ltYm9scy5nZXRab25lU3RyaW5ncygpLmxlbmd0aCA+IDEwMCk7CisgICAgfQorICAgICovCisKKyAgICAvLyBUaGlzIG9uZSBtYWtlcyBzdXJlIHdlIGhhdmUgYWxsIG5lY2Vzc2FyeSBsb2NhbGVzIGluc3RhbGxlZC4KKyAgICAvLyBTdXBwcmVzcyB0aGlzIGZsYWt5IHRlc3QgZm9yIG5vdy4KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SUNVTG9jYWxlcygpIHsKKyAgICAgICAgU3RyaW5nW10gbG9jYWxlcyA9IG5ldyBTdHJpbmdbXSB7CisgICAgICAgICAgICAgICAgLy8gTGlzdCBvZiBsb2NhbGVzIGN1cnJlbnRseSByZXF1aXJlZCBmb3IgQW5kcm9pZC4KKyAgICAgICAgICAgICAgICAiZW5fVVMiLCAiZXNfVVMiLCAiZW5fR0IiLCAiZnJfRlIiLCAiZGVfREUiLCAiZGVfQVQiLCAiY3NfQ1oiLCAibmxfTkwiIH07CisKKyAgICAgICAgU3RyaW5nW10gbW9uZGF5cyA9IG5ldyBTdHJpbmdbXSB7CisgICAgICAgICAgICAgICAgIk1vbmRheSIsICJsdW5lcyIsICJNb25kYXkiLCAibHVuZGkiLCAiTW9udGFnIiwgIk1vbnRhZyIsICJwb25kXHUwMTFibFx1MDBlZCIsICJtYWFuZGFnIiB9OworCisgICAgICAgIFN0cmluZ1tdIGN1cnJlbmNpZXMgPSBuZXcgU3RyaW5nW10geworICAgICAgICAgICAgICAgICJVU0QiLCAiVVNEIiwgIkdCUCIsICJFVVIiLCAiRVVSIiwgIkVVUiIsICJDWksiLCAiRVVSIn07CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsb2NhbGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBMb2NhbGUgbCA9IG5ldyBMb2NhbGUobG9jYWxlc1tpXS5zdWJzdHJpbmcoMCwgMiksIGxvY2FsZXNbaV0uc3Vic3RyaW5nKDMpKTsKKworICAgICAgICAgICAgLy8gQ2hlY2sgbGFuZ3VhZ2UgcGFydCBvZiBsb2NhbGUuCisgICAgICAgICAgICBEYXRlRm9ybWF0U3ltYm9scyBkID0gbmV3IERhdGVGb3JtYXRTeW1ib2xzKGwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJNb25kYXkgbmFtZSBmb3IgIiArIGxvY2FsZXNbaV0gKyAiIG11c3QgbWF0Y2giLAorICAgICAgICAgICAgICAgICAgICBtb25kYXlzW2ldLCBkLmdldFdlZWtkYXlzKClbMl0pOworCisgICAgICAgICAgICAvLyBDaGVjayBjb3VudHJ5IHBhcnQgb2YgbG9jYWxlLgorICAgICAgICAgICAgQ3VycmVuY3kgYyA9IEN1cnJlbmN5LmdldEluc3RhbmNlKGwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJDdXJyZW5jeSBjb2RlIGZvciAiICsgbG9jYWxlc1tpXSArICIgbXVzdCBtYXRjaCIsCisgICAgICAgICAgICAgICAgICAgIGN1cnJlbmNpZXNbaV0sIGMuZ2V0Q3VycmVuY3lDb2RlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gUmVncmVzc2lvbiB0ZXN0IGZvciAxMTE4NTcwOiBDcmVhdGUgdGVzdCBjYXNlcyBmb3IgdHJhY2tpbmcgSUNVIGNvbmZpZworICAgIC8vIGNoYW5nZXMuIFRoaXMgb25lIG1ha2VzIHN1cmUgd2UgaGF2ZSB0aGUgbmVjZXNzYXJ5IGNvbnZlcnRlcnMgaW5zdGFsbGVkCisgICAgLy8gYW5kIGRvbid0IGxvc2UgdGhlIGNoYW5nZXMgdG8gdGhlIGNvbnZlcnRlciBhbGlhcyB0YWJsZS4KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SUNVQ29udmVydGVycygpIHsKKyAgICAgICAgLy8gTGlzdCBvZiBlbmNvZGluZ3MgY3VycmVudGx5IHJlcXVpcmVkIGZvciBBbmRyb2lkLgorICAgICAgICBTdHJpbmdbXSBlbmNvZGluZ3MgPSBuZXcgU3RyaW5nW10geworICAgICAgICAgICAgICAgIC8vIEVuY29kaW5nIHJlcXVpcmVkIGJ5IHRoZSBsYW5ndWFnZSBzcGVjaWZpY2F0aW9uLgorICAgICAgICAgICAgICAgICJVUy1BU0NJSSIsCisgICAgICAgICAgICAgICAgIlVURi04IiwKKyAgICAgICAgICAgICAgICAiVVRGLTE2IiwKKyAgICAgICAgICAgICAgICAiVVRGLTE2QkUiLAorICAgICAgICAgICAgICAgICJVVEYtMTZMRSIsCisgICAgICAgICAgICAgICAgIklTTy04ODU5LTEiLAorCisgICAgICAgICAgICAgICAgLy8gQWRkaXRpb25hbCBlbmNvZGluZ3MgaW5jbHVkZWQgaW4gc3RhbmRhcmQgSUNVCisgICAgICAgICAgICAgICAgIklTTy04ODU5LTIiLAorICAgICAgICAgICAgICAgICJJU08tODg1OS0zIiwKKyAgICAgICAgICAgICAgICAiSVNPLTg4NTktNCIsCisgICAgICAgICAgICAgICAgIklTTy04ODU5LTUiLAorICAgICAgICAgICAgICAgICJJU08tODg1OS02IiwKKyAgICAgICAgICAgICAgICAiSVNPLTg4NTktNyIsCisgICAgICAgICAgICAgICAgIklTTy04ODU5LTgiLAorICAgICAgICAgICAgICAgICJJU08tODg1OS04LUkiLAorICAgICAgICAgICAgICAgICJJU08tODg1OS05IiwKKyAgICAgICAgICAgICAgICAiSVNPLTg4NTktMTAiLAorICAgICAgICAgICAgICAgICJJU08tODg1OS0xMSIsCisgICAgICAgICAgICAgICAgIklTTy04ODU5LTEzIiwKKyAgICAgICAgICAgICAgICAiSVNPLTg4NTktMTQiLAorICAgICAgICAgICAgICAgICJJU08tODg1OS0xNSIsCisgICAgICAgICAgICAgICAgIklTTy04ODU5LTE2IiwKKyAgICAgICAgICAgICAgICAiSVNPLTIwMjItSlAiLAorICAgICAgICAgICAgICAgICJXaW5kb3dzLTk1MCIsCisgICAgICAgICAgICAgICAgIldpbmRvd3MtMTI1MCIsCisgICAgICAgICAgICAgICAgIldpbmRvd3MtMTI1MSIsCisgICAgICAgICAgICAgICAgIldpbmRvd3MtMTI1MiIsCisgICAgICAgICAgICAgICAgIldpbmRvd3MtMTI1MyIsCisgICAgICAgICAgICAgICAgIldpbmRvd3MtMTI1NCIsCisgICAgICAgICAgICAgICAgIldpbmRvd3MtMTI1NSIsCisgICAgICAgICAgICAgICAgIldpbmRvd3MtMTI1NiIsCisgICAgICAgICAgICAgICAgIldpbmRvd3MtMTI1NyIsCisgICAgICAgICAgICAgICAgIldpbmRvd3MtMTI1OCIsCisgICAgICAgICAgICAgICAgIkJpZzUiLAorICAgICAgICAgICAgICAgICJDUDg2NCIsCisgICAgICAgICAgICAgICAgIkNQODc0IiwKKyAgICAgICAgICAgICAgICAiRVVDLUNOIiwKKyAgICAgICAgICAgICAgICAiRVVDLUpQIiwKKyAgICAgICAgICAgICAgICAiS09JOC1SIiwKKyAgICAgICAgICAgICAgICAiTWFjaW50b3NoIiwKKyAgICAgICAgICAgICAgICAiR0JLIiwKKyAgICAgICAgICAgICAgICAiR0IyMzEyIiwKKyAgICAgICAgICAgICAgICAiRVVDLUtSIiwKKworICAgICAgICAgICAgICAgIC8vIEFkZGl0aW9uYWwgZW5jb2Rpbmcgbm90IGluY2x1ZGVkIGluIHN0YW5kYXJkIElDVS4KKyAgICAgICAgICAgICAgICAiR1NNMDMzOCIgfTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVuY29kaW5ncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2hhcnNldCAiICsgZW5jb2RpbmdzW2ldICsgIiBtdXN0IGJlIHN1cHBvcnRlZCIsCisgICAgICAgICAgICAgICAgICAgIENoYXJzZXQuaXNTdXBwb3J0ZWQoZW5jb2RpbmdzW2ldKSk7CisKKyAgICAgICAgICAgIENoYXJzZXQgY3MgPSBDaGFyc2V0LmZvck5hbWUoZW5jb2RpbmdzW2ldKTsKKworICAgICAgICAgICAgU2V0PFN0cmluZz4gYWxpYXNlcyA9IGNzLmFsaWFzZXMoKTsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihhbGlhc2VzKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3QgZm9yIHZhbGlkIGVuY29kaW5nIHRoYXQgaXMgbm90IGluY2x1ZGVkIGluIEFuZHJvaWQuIElCTS0zNyBpcworICAgICAgICAvLyBhIHBlcmZlY3QgY2FuZGlkYXRlIGZvciB0aGlzLCBhcyBpdCBpcyBiZWluZyB1c2VkIGZvciBtYWluZnJhbWVzIGFuZAorICAgICAgICAvLyB0aHVzIHNvbWV3aGF0IG91dCBvZiB0aGUgc2NvcGUgb2YgQW5kcm9pZC4KKyAgICAgICAgYXNzZXJ0RmFsc2UoIkNoYXJzZXQgSUJNLTM3IG11c3Qgbm90IGJlIHN1cHBvcnRlZCIsCisgICAgICAgICAgICAgICAgQ2hhcnNldC5pc1N1cHBvcnRlZCgiSUJNLTM3IikpOworCisgICAgICAgIC8vIFRlc3QgZm9yIGEgYm9ndXMgZW5jb2RpbmcuCisgICAgICAgIGFzc2VydEZhbHNlKCJDaGFyc2V0IEtMSU5HT04gbXVzdCBub3QgYmUgc3VwcG9ydGVkIiwKKyAgICAgICAgICAgICAgICBDaGFyc2V0LmlzU3VwcG9ydGVkKCJLTElOR09OIikpOworCisgICAgICAgIC8vIE1ha2Ugc3VyZSBvdXIgbG9jYWwgY2hhbmdlIHRvIHRoZSByZWFsIHRyYW5zbGF0aW9uIHRhYmxlIHVzZWQgZm9yCisgICAgICAgIC8vIEVVQy1KUCBkb2Vzbid0IGdldCBsb3N0LgorICAgICAgICBDaGFyc2V0IGNzID0gQ2hhcnNldC5mb3JOYW1lKCJFVUMtSlAiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRVVDLUpQIG11c3QgdXNlICdpYm0tOTU0X1AxMDEtMjAwNyciLCBjcy5hbGlhc2VzKCkuY29udGFpbnMoImlibS05NTRfUDEwMS0yMDA3IikpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZEFuZHJvaWRUcmVlTWFwVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZEFuZHJvaWRUcmVlTWFwVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUyNzk5MTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkQW5kcm9pZFRyZWVNYXBUZXN0LmphdmEKQEAgLTAsMCArMSwxMDMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKKworLyoqCisgKiBUZXN0cyBmb3IgYmFzaWMgZnVuY3RpbmFsaXR5IG9mIFRyZWVNYXBzCisgKi8KK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkVHJlZU1hcFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIFJhbmRvbSBtUmFuZG9tID0gbmV3IFJhbmRvbSgxKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gU1BFVyA9IGZhbHNlOworCisgICAgcHVibGljIHZvaWQgdGVzdFRyZWVNYXAoKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgICAgICAgICAgaWYgKFNQRVcpIFN5c3RlbS5vdXQucHJpbnRsbigiUnVubmluZyBkb1Rlc3QgY3ljbGUgIyIgKyAoaSArIDEpKTsKKyAgICAgICAgICAgIGRvVGVzdCgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGRvVGVzdCgpIHsKKyAgICAgICAgVHJlZU1hcDxJbnRlZ2VyLCBTdHJpbmc+IHRtID0gbmV3IFRyZWVNYXA8SW50ZWdlciwgU3RyaW5nPigpOworICAgICAgICBIYXNoTWFwPEludGVnZXIsIFN0cmluZz4gaG0gPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBTdHJpbmc+KCk7CisKKyAgICAgICAgaW50IG1pblZhbCA9IEludGVnZXIuTUFYX1ZBTFVFOworICAgICAgICBpbnQgbWF4VmFsID0gSW50ZWdlci5NSU5fVkFMVUU7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykgeworICAgICAgICAgICAgaW50IHZhbCA9IG1SYW5kb20ubmV4dEludCgxMDAwKTsKKyAgICAgICAgICAgIGlmIChTUEVXKSBTeXN0ZW0ub3V0LnByaW50bG4oIkFkZGluZyB2YWwgPSAiICsgdmFsKTsKKyAgICAgICAgICAgIGlmICh2YWwgPCBtaW5WYWwpIHsKKyAgICAgICAgICAgICAgICBtaW5WYWwgPSB2YWw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodmFsID4gbWF4VmFsKSB7CisgICAgICAgICAgICAgICAgbWF4VmFsID0gdmFsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdG0ucHV0KG5ldyBJbnRlZ2VyKHZhbCksICJWOiIgKyB2YWwpOworICAgICAgICAgICAgaG0ucHV0KG5ldyBJbnRlZ2VyKHZhbCksICJWOiIgKyB2YWwpOworCisgICAgICAgICAgICBpZiAoU1BFVykgU3lzdGVtLm91dC5wcmludGxuKCJ0bSA9ICIgKyB0bSk7CisKKyAgICAgICAgICAgIGlmIChTUEVXKSBTeXN0ZW0ub3V0LnByaW50bG4oInRtLnNpemUoKSA9ICIgKyB0bS5zaXplKCkpOworICAgICAgICAgICAgaWYgKFNQRVcpIFN5c3RlbS5vdXQucHJpbnRsbigiaG0uc2l6ZSgpID0gIiArIGhtLnNpemUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModG0uc2l6ZSgpLCBobS5zaXplKCkpOworCisgICAgICAgICAgICBpZiAoU1BFVykgU3lzdGVtLm91dC5wcmludGxuKCJ0bS5maXJzdEtleSgpID0gIiArIHRtLmZpcnN0S2V5KCkpOworICAgICAgICAgICAgaWYgKFNQRVcpIFN5c3RlbS5vdXQucHJpbnRsbigibWluVmFsID0gIiArIG1pblZhbCk7CisgICAgICAgICAgICBpZiAoU1BFVykgU3lzdGVtLm91dC5wcmludGxuKCJ0bS5sYXN0S2V5KCkgPSAiICsgdG0ubGFzdEtleSgpKTsKKyAgICAgICAgICAgIGlmIChTUEVXKSBTeXN0ZW0ub3V0LnByaW50bG4oIm1heFZhbCA9ICIgKyBtYXhWYWwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG1pblZhbCwgdG0uZmlyc3RLZXkoKS5pbnRWYWx1ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhtYXhWYWwsIHRtLmxhc3RLZXkoKS5pbnRWYWx1ZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIENoZWNrIGZvciBlcXVhbGl0eQorICAgICAgICBmb3IgKGludCB2YWwgPSAwOyB2YWwgPCAxMDAwOyB2YWwrKykgeworICAgICAgICAgICAgSW50ZWdlciB2diA9IG5ldyBJbnRlZ2VyKHZhbCk7CisgICAgICAgICAgICBTdHJpbmcgdG1zID0gdG0uZ2V0KHZ2KTsKKyAgICAgICAgICAgIFN0cmluZyBobXMgPSBobS5nZXQodnYpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHRtcywgaG1zKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwMDsgaSsrKSB7CisgICAgICAgICAgICBpbnQgdmFsID0gbVJhbmRvbS5uZXh0SW50KDEwMDApOworICAgICAgICAgICAgaWYgKFNQRVcpIFN5c3RlbS5vdXQucHJpbnRsbigiUmVtb3ZpbmcgdmFsID0gIiArIHZhbCk7CisKKyAgICAgICAgICAgIFN0cmluZyB0bXMgPSB0bS5yZW1vdmUobmV3IEludGVnZXIodmFsKSk7CisgICAgICAgICAgICBTdHJpbmcgaG1zID0gaG0ucmVtb3ZlKG5ldyBJbnRlZ2VyKHZhbCkpOworCisgICAgICAgICAgICBpZiAoU1BFVykgU3lzdGVtLm91dC5wcmludGxuKCJ0bSA9ICIgKyB0bSk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0bS5zaXplKCksIGhtLnNpemUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModG1zLCBobXMpOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ2hlY2sgZm9yIGVxdWFsaXR5CisgICAgICAgIGZvciAoaW50IHZhbCA9IDA7IHZhbCA8IDEwMDA7IHZhbCsrKSB7CisgICAgICAgICAgICBJbnRlZ2VyIHZ2ID0gbmV3IEludGVnZXIodmFsKTsKKyAgICAgICAgICAgIFN0cmluZyB0bXMgPSB0bS5nZXQodnYpOworICAgICAgICAgICAgU3RyaW5nIGhtcyA9IGhtLmdldCh2dik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModG1zLCBobXMpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZENvbGxlY3Rpb25zVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZENvbGxlY3Rpb25zVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1NGZjNTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkQ29sbGVjdGlvbnNUZXN0LmphdmEKQEAgLTAsMCArMSw3NzUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQKKyAqIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZQorICogTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKKyAqIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5Db21wYXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5SYW5kb21BY2Nlc3M7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkTWFwOworaW1wb3J0IGphdmEudXRpbC5Tb3J0ZWRTZXQ7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS50ZXN0ZnJhbWV3b3JrLnNlcmlhbGl6YXRpb24uU2VyaWFsaXphdGlvblRlc3Q7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnRlc3RmcmFtZXdvcmsuc2VyaWFsaXphdGlvbi5TZXJpYWxpemF0aW9uVGVzdC5TZXJpYWxpemFibGVBc3NlcnQ7CisKK2ltcG9ydCB0ZXN0cy51dGlsLlNlcmlhbGl6YXRpb25UZXN0ZXI7CisKK3B1YmxpYyBjbGFzcyBPbGRDb2xsZWN0aW9uc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTZXJpYWxpemFibGVBc3NlcnQgY29tcGFyYXRvciA9IG5ldyBTZXJpYWxpemFibGVBc3NlcnQoKSB7CisgICAgICAgIHB1YmxpYyB2b2lkIGFzc2VydERlc2VyaWFsaXplZChTZXJpYWxpemFibGUgcmVmZXJlbmNlLCBTZXJpYWxpemFibGUgdGVzdCkgeworICAgICAgICAgICAgYXNzZXJ0U2FtZShyZWZlcmVuY2UsIHRlc3QpOworICAgICAgICB9CisgICAgfTsKKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Db2xsZWN0aW9ucyNiaW5hcnlTZWFyY2goamF2YS51dGlsLkxpc3QsCisgICAgICogICAgICAgIGphdmEubGFuZy5PYmplY3QsIGphdmEudXRpbC5Db21wYXJhdG9yKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYmluYXJ5U2VhcmNoTGphdmFfdXRpbF9MaXN0TGphdmFfbGFuZ19PYmplY3RMamF2YV91dGlsX0NvbXBhcmF0b3IoKSB7CisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktOTQKKyAgICAgICAgTGlua2VkTGlzdDxJbnRlZ2VyPiBsc3QgPSBuZXcgTGlua2VkTGlzdDxJbnRlZ2VyPigpOworICAgICAgICBsc3QuYWRkKG5ldyBJbnRlZ2VyKDMwKSk7CisgICAgICAgIENvbGxlY3Rpb25zLnNvcnQobHN0LCBudWxsKTsKKyAgICAgICAgaW50IGluZGV4ID0gQ29sbGVjdGlvbnMuYmluYXJ5U2VhcmNoKGxzdCwgbmV3IEludGVnZXIoMiksIG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluZGV4KTsKKworICAgICAgICBMaW5rZWRMaXN0PFN0cmluZz4gbGxzID0gbmV3IExpbmtlZExpc3Q8U3RyaW5nPigpOworICAgICAgICBsbHMuYWRkKCIxIik7CisgICAgICAgIGxscy5hZGQoIjIiKTsKKyAgICAgICAgbGxzLmFkZCgiMyIpOworICAgICAgICBsbHMuYWRkKCI0Iik7CisgICAgICAgIGxscy5hZGQoIiIpOworICAgICAgICBMaW5rZWRMaXN0PFN0cmluZz4gbGwgPSBsbHM7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLmJpbmFyeVNlYXJjaChsbCwgbmV3IEludGVnZXIoMTApLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkNsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI2JpbmFyeVNlYXJjaChqYXZhLnV0aWwuTGlzdCwKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2JpbmFyeVNlYXJjaExqYXZhX3V0aWxfTGlzdExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyByZWdyZXNzaW9uIGZvciBIYXJtb255LTEzNjcKKyAgICAgICAgTGlzdCBsb2NhbExpc3QgPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIENvbGxlY3Rpb25zLmJpbmFyeVNlYXJjaChsb2NhbExpc3QsIG5ldyBPYmplY3QoKSkpOworICAgICAgICBsb2NhbExpc3QuYWRkKG5ldyBPYmplY3QoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5iaW5hcnlTZWFyY2gobG9jYWxMaXN0LCBuZXcgSW50ZWdlcigxKSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgQ2xhc3NDYXN0RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgTGlua2VkTGlzdDxTdHJpbmc+IGxscyA9IG5ldyBMaW5rZWRMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgbGxzLmFkZCgiMSIpOworICAgICAgICBsbHMuYWRkKCIyIik7CisgICAgICAgIGxscy5hZGQoIjMiKTsKKyAgICAgICAgbGxzLmFkZCgiNCIpOworICAgICAgICBsbHMuYWRkKCIiKTsKKyAgICAgICAgTGlua2VkTGlzdCBsbCA9IGxsczsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMuYmluYXJ5U2VhcmNoKGxsLCBuZXcgSW50ZWdlcigxMCkpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjcm90YXRlKGphdmEudXRpbC5MaXN0LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yb3RhdGVMamF2YV91dGlsX0xpc3RJKCkgeworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTE5IFJvdGF0ZSBhbiAqZW1wdHkqIGxpc3QKKyAgICAgICAgQ29sbGVjdGlvbnMucm90YXRlKG5ldyBBcnJheUxpc3Q8T2JqZWN0PigpLCAyNSk7CisKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS0yMAorICAgICAgICBMaXN0PFN0cmluZz4gbGlzdCA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBsaXN0LmFkZCgwLCAiemVybyIpOworICAgICAgICBsaXN0LmFkZCgxLCAib25lIik7CisgICAgICAgIGxpc3QuYWRkKDIsICJ0d28iKTsKKyAgICAgICAgbGlzdC5hZGQoMywgInRocmVlIik7CisgICAgICAgIGxpc3QuYWRkKDQsICJmb3VyIik7CisKKyAgICAgICAgQ29sbGVjdGlvbnMucm90YXRlKGxpc3QsIEludGVnZXIuTUlOX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSb3RhdGVkIGluY29ycmVjdGx5IGF0IHBvc2l0aW9uIDAsICIsICJ0aHJlZSIsCisgICAgICAgICAgICAgICAgbGlzdC5nZXQoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJvdGF0ZWQgaW5jb3JyZWN0bHkgYXQgcG9zaXRpb24gMSwgIiwgImZvdXIiLAorICAgICAgICAgICAgICAgIGxpc3QuZ2V0KDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSb3RhdGVkIGluY29ycmVjdGx5IGF0IHBvc2l0aW9uIDIsICIsICJ6ZXJvIiwKKyAgICAgICAgICAgICAgICBsaXN0LmdldCgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUm90YXRlZCBpbmNvcnJlY3RseSBhdCBwb3NpdGlvbiAzLCAiLCAib25lIiwKKyAgICAgICAgICAgICAgICBsaXN0LmdldCgzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUm90YXRlZCBpbmNvcnJlY3RseSBhdCBwb3NpdGlvbiA0LCAiLCAidHdvIiwKKyAgICAgICAgICAgICAgICBsaXN0LmdldCg0KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI3N5bmNocm9uaXplZENvbGxlY3Rpb24oamF2YS51dGlsLkNvbGxlY3Rpb24pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zeW5jaHJvbml6ZWRDb2xsZWN0aW9uTGphdmFfdXRpbF9Db2xsZWN0aW9uKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS05MworICAgICAgICAgICAgQ29sbGVjdGlvbnMuc3luY2hyb25pemVkQ29sbGVjdGlvbihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkFzc2VydCAwOiBzeW5jaHJvbml6ZWRDb2xsZWN0aW9uKG51bGwpIG11c3QgdGhyb3cgTlBFIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjc3luY2hyb25pemVkU29ydGVkTWFwKGphdmEudXRpbC5Tb3J0ZWRNYXApCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zeW5jaHJvbml6ZWRTb3J0ZWRNYXBMamF2YV91dGlsX1NvcnRlZE1hcCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktOTMKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLnN5bmNocm9uaXplZFNvcnRlZE1hcChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkFzc2VydCAwOiBzeW5jaHJvbml6ZWRTb3J0ZWRNYXAobnVsbCkgbXVzdCB0aHJvdyBOUEUiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Db2xsZWN0aW9ucyNzeW5jaHJvbml6ZWRNYXAoamF2YS51dGlsLk1hcCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N5bmNocm9uaXplZE1hcExqYXZhX3V0aWxfTWFwKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS05MworICAgICAgICAgICAgQ29sbGVjdGlvbnMuc3luY2hyb25pemVkTWFwKG51bGwpOworICAgICAgICAgICAgZmFpbCgiQXNzZXJ0IDA6IHN5bmNocm9uaXplZE1hcChtYXApIG11c3QgdGhyb3cgTlBFIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjc3luY2hyb25pemVkU2V0KGphdmEudXRpbC5TZXQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zeW5jaHJvbml6ZWRTZXRMamF2YV91dGlsX1NldCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktOTMKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLnN5bmNocm9uaXplZFNldChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkFzc2VydCAwOiBzeW5jaHJvbml6ZWRTZXQoc2V0KSBtdXN0IHRocm93IE5QRSIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI3N5bmNocm9uaXplZFNvcnRlZFNldChqYXZhLnV0aWwuU29ydGVkU2V0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3luY2hyb25pemVkU29ydGVkU2V0TGphdmFfdXRpbF9Tb3J0ZWRTZXQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTkzCisgICAgICAgICAgICBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRTb3J0ZWRTZXQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJBc3NlcnQgMDogc3luY2hyb25pemVkU29ydGVkU2V0KG51bGwpIG11c3QgdGhyb3cgTlBFIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjdW5tb2RpZmlhYmxlQ29sbGVjdGlvbihqYXZhLnV0aWwuQ29sbGVjdGlvbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VubW9kaWZpYWJsZUNvbGxlY3Rpb25MamF2YV91dGlsX0NvbGxlY3Rpb24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTkzCisgICAgICAgICAgICBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVDb2xsZWN0aW9uKG51bGwpOworICAgICAgICAgICAgZmFpbCgiQXNzZXJ0IDA6IHVubW9kaWZpYWJsZUNvbGxlY3Rpb24obnVsbCkgbXVzdCB0aHJvdyBOUEUiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Db2xsZWN0aW9ucyN1bm1vZGlmaWFibGVNYXAoamF2YS51dGlsLk1hcCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VubW9kaWZpYWJsZU1hcExqYXZhX3V0aWxfTWFwKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS05MworICAgICAgICAgICAgQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG51bGwpOworICAgICAgICAgICAgZmFpbCgiQXNzZXJ0IDA6IHVubW9kaWZpYWJsZU1hcChudWxsKSBtdXN0IHRocm93IE5QRSIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI3VubW9kaWZpYWJsZVNldChqYXZhLnV0aWwuU2V0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdW5tb2RpZmlhYmxlU2V0TGphdmFfdXRpbF9TZXQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTkzCisgICAgICAgICAgICBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVTZXQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJBc3NlcnQgMDogdW5tb2RpZmlhYmxlU2V0KG51bGwpIG11c3QgdGhyb3cgTlBFIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjdW5tb2RpZmlhYmxlU29ydGVkTWFwKGphdmEudXRpbC5Tb3J0ZWRNYXApCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF91bm1vZGlmaWFibGVTb3J0ZWRNYXBMamF2YV91dGlsX1NvcnRlZE1hcCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktOTMKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNvcnRlZE1hcChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkFzc2VydCAwOiB1bm1vZGlmaWFibGVTb3J0ZWRNYXAobnVsbCkgbXVzdCB0aHJvdyBOUEUiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Db2xsZWN0aW9ucyN1bm1vZGlmaWFibGVTb3J0ZWRTZXQoamF2YS51dGlsLlNvcnRlZFNldCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VubW9kaWZpYWJsZVNvcnRlZFNldExqYXZhX3V0aWxfU29ydGVkU2V0KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS05MworICAgICAgICAgICAgQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU29ydGVkU2V0KG51bGwpOworICAgICAgICAgICAgZmFpbCgiQXNzZXJ0IDA6IHVubW9kaWZpYWJsZVNvcnRlZFNldChudWxsKSBtdXN0IHRocm93IE5QRSIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI2ZyZXF1ZW5jeShqYXZhLnV0aWwuQ29sbGVjdGlvbixPYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9mcmVxdWVuY3lMamF2YV91dGlsX0NvbGxlY3Rpb25MaW50KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMuZnJlcXVlbmN5KG51bGwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiQXNzZXJ0IDA6IGZyZXF1ZW5jeShudWxsLDxhbnk+KSBtdXN0IHRocm93IE5QRSIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7fQorCisgICAgICAgIExpc3Q8U3RyaW5nPiBzdHJpbmdzID0gQXJyYXlzLmFzTGlzdChuZXcgU3RyaW5nW10geyAiMSIsICIyIiwgIjMiLCAiMSIsICIxIiB9KTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkFzc2VydCAxOiBkaWQgbm90IGZpbmQgdGhyZWUgXCIxXCIgc3RyaW5ncyIsIDMsCisgICAgICAgICAgICAgICAgQ29sbGVjdGlvbnMuZnJlcXVlbmN5KHN0cmluZ3MsICIxIikpOworCisgICAgICAgIGFzc2VydEVxdWFscygiQXNzZXJ0IDI6IGRpZCBub3QgZmluZCBvbmUgXCIyXCIgc3RyaW5ncyIsIDEsIENvbGxlY3Rpb25zCisgICAgICAgICAgICAgICAgLmZyZXF1ZW5jeShzdHJpbmdzLCAiMiIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkFzc2VydCAzOiBkaWQgbm90IGZpbmQgdGhyZWUgXCIzXCIgc3RyaW5ncyIsIDEsCisgICAgICAgICAgICAgICAgQ29sbGVjdGlvbnMuZnJlcXVlbmN5KHN0cmluZ3MsICIzIikpOworCisgICAgICAgIGFzc2VydEVxdWFscygiQXNzZXJ0IDQ6IG1hdGNoZWQgb24gbnVsbCB3aGVuIHRoZXJlIGFyZSBub25lIiwgMCwKKyAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy5mcmVxdWVuY3koc3RyaW5ncywgbnVsbCkpOworCisgICAgICAgIExpc3Q8T2JqZWN0PiBvYmplY3RzID0gQXJyYXlzLmFzTGlzdChuZXcgT2JqZWN0W10geyBuZXcgSW50ZWdlcigxKSwgbnVsbCwgbnVsbCwKKyAgICAgICAgICAgICAgICBuZXcgTG9uZygxKSB9KTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkFzc2VydCA1OiBkaWQgbm90IGZpbmQgb25lIEludGVnZXIoMSkiLCAxLCBDb2xsZWN0aW9ucworICAgICAgICAgICAgICAgIC5mcmVxdWVuY3kob2JqZWN0cywgbmV3IEludGVnZXIoMSkpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkFzc2VydCA2OiBkaWQgbm90IGZpbmQgb25lIExvbmcoMSkiLCAxLCBDb2xsZWN0aW9ucworICAgICAgICAgICAgICAgIC5mcmVxdWVuY3kob2JqZWN0cywgbmV3IExvbmcoMSkpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkFzc2VydCA3OiBkaWQgbm90IGZpbmQgdHdvIG51bGwgcmVmZXJlbmNlcyIsIDIsCisgICAgICAgICAgICAgICAgQ29sbGVjdGlvbnMuZnJlcXVlbmN5KG9iamVjdHMsIG51bGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjcmV2ZXJzZU9yZGVyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JldmVyc2VPcmRlcigpIHsKKyAgICAgICAgQ29tcGFyYXRvcjxTdHJpbmc+IHJvYyA9IENvbGxlY3Rpb25zLnJldmVyc2VPcmRlcigpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJBc3NlcnQgMDogY29tcGFyYXRvciBtdXN0IG5vdCBiZSBudWxsIiwgcm9jKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJBc3NlcnQgMTogY29tcGFyYXRvciBtdXN0IGltcGxlbWVudCBTZXJpYWxpemFibGUiLAorICAgICAgICAgICAgICAgIHJvYyBpbnN0YW5jZW9mIFNlcmlhbGl6YWJsZSk7CisKKyAgICAgICAgU3RyaW5nW10gZml4dHVyZURlc2MgPSBuZXcgU3RyaW5nW10geyAiMiIsICIxIiwgIjAiIH07CisgICAgICAgIFN0cmluZ1tdIG51bWJlcnMgPSBuZXcgU3RyaW5nW10geyAiMCIsICIxIiwgIjIiIH07CisgICAgICAgIEFycmF5cy5zb3J0KG51bWJlcnMsIHJvYyk7CisgICAgICAgIGFzc2VydFRydWUoIkFzc2VydCAyOiB0aGUgYXJyYXlzIGFyZSBub3QgZXF1YWwsIHRoZSBzb3J0IGZhaWxlZCIsCisgICAgICAgICAgICAgICAgQXJyYXlzLmVxdWFscyhmaXh0dXJlRGVzYywgbnVtYmVycykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Db2xsZWN0aW9ucyNyZXZlcnNlT3JkZXIoamF2YS51dGlsLkNvbXBhcmF0b3IpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZXZlcnNlT3JkZXJMamF2YV91dGlsX0NvbXBhcmF0b3IoKSB7CisgICAgICAgIENvbXBhcmF0b3I8U3RyaW5nPiByb2MgPSBDb2xsZWN0aW9ucworICAgICAgICAgICAgICAgIC5yZXZlcnNlT3JkZXIoU3RyaW5nLkNBU0VfSU5TRU5TSVRJVkVfT1JERVIpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJBc3NlcnQgMDogY29tcGFyYXRvciBtdXN0IG5vdCBiZSBudWxsIiwgcm9jKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJBc3NlcnQgMTogY29tcGFyYXRvciBtdXN0IGltcGxlbWVudCBTZXJpYWxpemFibGUiLAorICAgICAgICAgICAgICAgIHJvYyBpbnN0YW5jZW9mIFNlcmlhbGl6YWJsZSk7CisKKyAgICAgICAgU3RyaW5nW10gZml4dHVyZURlc2MgPSBuZXcgU3RyaW5nW10geyAiMiIsICIxIiwgIjAiIH07CisgICAgICAgIFN0cmluZ1tdIG51bWJlcnMgPSBuZXcgU3RyaW5nW10geyAiMCIsICIxIiwgIjIiIH07CisgICAgICAgIEFycmF5cy5zb3J0KG51bWJlcnMsIHJvYyk7CisgICAgICAgIGFzc2VydFRydWUoIkFzc2VydCAyOiB0aGUgYXJyYXlzIGFyZSBub3QgZXF1YWwsIHRoZSBzb3J0IGZhaWxlZCIsCisgICAgICAgICAgICAgICAgQXJyYXlzLmVxdWFscyhmaXh0dXJlRGVzYywgbnVtYmVycykpOworCisgICAgICAgIHJvYyA9IENvbGxlY3Rpb25zLnJldmVyc2VPcmRlcihudWxsKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQXNzZXJ0IDM6IGNvbXBhcmF0b3IgbXVzdCBub3QgYmUgbnVsbCIsIHJvYyk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQXNzZXJ0IDQ6IGNvbXBhcmF0b3IgbXVzdCBpbXBsZW1lbnQgU2VyaWFsaXphYmxlIiwKKyAgICAgICAgICAgICAgICByb2MgaW5zdGFuY2VvZiBTZXJpYWxpemFibGUpOworCisgICAgICAgIG51bWJlcnMgPSBuZXcgU3RyaW5nW10geyAiMCIsICIxIiwgIjIiIH07CisgICAgICAgIEFycmF5cy5zb3J0KG51bWJlcnMsIHJvYyk7CisgICAgICAgIGFzc2VydFRydWUoIkFzc2VydCA1OiB0aGUgYXJyYXlzIGFyZSBub3QgZXF1YWwsIHRoZSBzb3J0IGZhaWxlZCIsCisgICAgICAgICAgICAgICAgQXJyYXlzLmVxdWFscyhmaXh0dXJlRGVzYywgbnVtYmVycykpOworICAgIH0KKworICAgIGNsYXNzIE1vY2tfQ29sbGVjdGlvbiBpbXBsZW1lbnRzIENvbGxlY3Rpb24geworICAgICAgICBwdWJsaWMgYm9vbGVhbiBhZGQoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gYWRkQWxsKENvbGxlY3Rpb24gYykgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3QgbykgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNBbGwoQ29sbGVjdGlvbiBjKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEl0ZXJhdG9yIGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZUFsbChDb2xsZWN0aW9uIGMpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIHJldGFpbkFsbChDb2xsZWN0aW9uIGMpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBPYmplY3RbXSB0b0FycmF5KE9iamVjdFtdIGEpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgTW9ja19Xcm9uZ0NvbGxlY3Rpb24gaW1wbGVtZW50cyBDb2xsZWN0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIHdyb25nRWxlbWVudCA9ICJXcm9uZyBlbGVtZW50IjsKKyAgICAgICAgcHVibGljIGJvb2xlYW4gYWRkKE9iamVjdCBvKSB7CisgICAgICAgICAgICBpZiAoby5lcXVhbHMod3JvbmdFbGVtZW50KSkgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgaWYgKG8gPT0gbnVsbCkgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBhZGRBbGwoQ29sbGVjdGlvbiBjKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBvKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0FsbChDb2xsZWN0aW9uIGMpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSXRlcmF0b3IgaXRlcmF0b3IoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIHJlbW92ZShPYmplY3QgbykgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlQWxsKENvbGxlY3Rpb24gYykgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gcmV0YWluQWxsKENvbGxlY3Rpb24gYykgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoT2JqZWN0W10gYSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0FkZEFsbCgpIHsKKyAgICAgICAgTGlzdDxPYmplY3Q+IGwgPSBuZXcgQXJyYXlMaXN0PE9iamVjdD4oKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoQ29sbGVjdGlvbnMuYWRkQWxsKGwsIG5ldyBPYmplY3RbXSB7fSkpOworICAgICAgICBhc3NlcnRUcnVlKGwuaXNFbXB0eSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShDb2xsZWN0aW9ucy5hZGRBbGwobCwgbmV3IE9iamVjdFtdIHsgbmV3IEludGVnZXIoMSksCisgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoMiksIG5ldyBJbnRlZ2VyKDMpIH0pKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobC5pc0VtcHR5KCkpOworICAgICAgICBhc3NlcnRUcnVlKGwuZXF1YWxzKEFycmF5cy5hc0xpc3QobmV3IE9iamVjdFtdIHsgbmV3IEludGVnZXIoMSksCisgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoMiksIG5ldyBJbnRlZ2VyKDMpIH0pKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLmFkZEFsbChudWxsLG5ldyBPYmplY3RbXSB7IG5ldyBJbnRlZ2VyKDEpLAorICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcigyKSwgbmV3IEludGVnZXIoMykgfSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2ZhaWwKKyAgICAgICAgfQorCisgICAgICAgIENvbGxlY3Rpb24gYyA9IG5ldyBNb2NrX0NvbGxlY3Rpb24oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLmFkZEFsbChjLCBuZXcgT2JqZWN0W10geyBuZXcgSW50ZWdlcigxKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoMiksIG5ldyBJbnRlZ2VyKDMpIH0pOworICAgICAgICAgICAgZmFpbCgiVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYyA9IG5ldyBNb2NrX1dyb25nQ29sbGVjdGlvbiAoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMuYWRkQWxsKGMsIG5ldyBTdHJpbmdbXSB7ICJTdHJpbmciLAorICAgICAgICAgICAgICAgICAgICAiQ29ycmVjdCBlbGVtZW50IiwgbnVsbCB9KTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZmFpbAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLmFkZEFsbChjLCBuZXcgU3RyaW5nW10geyAiU3RyaW5nIiwKKyAgICAgICAgICAgICAgICAgICAgIldyb25nIGVsZW1lbnQiLCAiQ29ycmVjdCBlbGVtZW50IiB9KTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9mYWlsCisgICAgICAgIH0KKworICAgICAgICBDb2xsZWN0aW9ucy5hZGRBbGwoYywgbmV3IFN0cmluZ1tdIHsgIlN0cmluZyIsCisgICAgICAgICAgICAgICAgIiIsICJDb3JyZWN0IGVsZW1lbnQiIH0pOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0Rpc2pvaW50KCkgeworICAgICAgICBPYmplY3RbXSBhcnIxID0gbmV3IE9iamVjdFsxMF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyMS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXJyMVtpXSA9IG5ldyBJbnRlZ2VyKGkpOworICAgICAgICB9CisgICAgICAgIE9iamVjdFtdIGFycjIgPSBuZXcgT2JqZWN0WzIwXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnIyLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhcnIyW2ldID0gbmV3IEludGVnZXIoMTAwICsgaSk7CisgICAgICAgIH0KKyAgICAgICAgQ29sbGVjdGlvbjxPYmplY3Q+IGMxID0gbmV3IEFycmF5TGlzdDxPYmplY3Q+KCk7CisgICAgICAgIENvbGxlY3Rpb248T2JqZWN0PiBjMiA9IG5ldyBBcnJheUxpc3Q8T2JqZWN0PigpOworICAgICAgICBDb2xsZWN0aW9ucy5hZGRBbGwoYzEsIGFycjEpOworICAgICAgICBDb2xsZWN0aW9ucy5hZGRBbGwoYzIsIGFycjIpOworICAgICAgICBhc3NlcnRUcnVlKENvbGxlY3Rpb25zLmRpc2pvaW50KGMxLCBjMikpOworICAgICAgICBjMS5hZGQoYXJyMlsxMF0pOworICAgICAgICBhc3NlcnRGYWxzZShDb2xsZWN0aW9ucy5kaXNqb2ludChjMSwgYzIpKTsKKworICAgICAgICBjMSA9IG5ldyBMaW5rZWRMaXN0PE9iamVjdD4oKTsKKyAgICAgICAgYzIgPSBuZXcgTGlua2VkTGlzdDxPYmplY3Q+KCk7CisgICAgICAgIENvbGxlY3Rpb25zLmFkZEFsbChjMSwgYXJyMSk7CisgICAgICAgIENvbGxlY3Rpb25zLmFkZEFsbChjMiwgYXJyMik7CisgICAgICAgIGFzc2VydFRydWUoQ29sbGVjdGlvbnMuZGlzam9pbnQoYzEsIGMyKSk7CisgICAgICAgIGMxLmFkZChhcnIyWzEwXSk7CisgICAgICAgIGFzc2VydEZhbHNlKENvbGxlY3Rpb25zLmRpc2pvaW50KGMxLCBjMikpOworCisgICAgICAgIGMxID0gbmV3IFRyZWVTZXQ8T2JqZWN0PigpOworICAgICAgICBjMiA9IG5ldyBUcmVlU2V0PE9iamVjdD4oKTsKKyAgICAgICAgQ29sbGVjdGlvbnMuYWRkQWxsKGMxLCBhcnIxKTsKKyAgICAgICAgQ29sbGVjdGlvbnMuYWRkQWxsKGMyLCBhcnIyKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShDb2xsZWN0aW9ucy5kaXNqb2ludChjMSwgYzIpKTsKKyAgICAgICAgYzEuYWRkKGFycjJbMTBdKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoQ29sbGVjdGlvbnMuZGlzam9pbnQoYzEsIGMyKSk7CisKKyAgICAgICAgYzEgPSBuZXcgSGFzaFNldDxPYmplY3Q+KCk7CisgICAgICAgIGMyID0gbmV3IEhhc2hTZXQ8T2JqZWN0PigpOworICAgICAgICBDb2xsZWN0aW9ucy5hZGRBbGwoYzEsIGFycjEpOworICAgICAgICBDb2xsZWN0aW9ucy5hZGRBbGwoYzIsIGFycjIpOworICAgICAgICBhc3NlcnRUcnVlKENvbGxlY3Rpb25zLmRpc2pvaW50KGMxLCBjMikpOworICAgICAgICBjMS5hZGQoYXJyMlsxMF0pOworICAgICAgICBhc3NlcnRGYWxzZShDb2xsZWN0aW9ucy5kaXNqb2ludChjMSwgYzIpKTsKKworICAgICAgICBjMSA9IG5ldyBMaW5rZWRMaXN0PE9iamVjdD4oKTsKKyAgICAgICAgYzIgPSBuZXcgVHJlZVNldDxPYmplY3Q+KCk7CisgICAgICAgIENvbGxlY3Rpb25zLmFkZEFsbChjMSwgYXJyMSk7CisgICAgICAgIENvbGxlY3Rpb25zLmFkZEFsbChjMiwgYXJyMik7CisgICAgICAgIGFzc2VydFRydWUoQ29sbGVjdGlvbnMuZGlzam9pbnQoYzEsIGMyKSk7CisgICAgICAgIGMxLmFkZChhcnIyWzEwXSk7CisgICAgICAgIGFzc2VydEZhbHNlKENvbGxlY3Rpb25zLmRpc2pvaW50KGMxLCBjMikpOworCisgICAgICAgIGMxID0gbmV3IFZlY3RvcjxPYmplY3Q+KCk7CisgICAgICAgIGMyID0gbmV3IEhhc2hTZXQ8T2JqZWN0PigpOworICAgICAgICBDb2xsZWN0aW9ucy5hZGRBbGwoYzEsIGFycjEpOworICAgICAgICBDb2xsZWN0aW9ucy5hZGRBbGwoYzIsIGFycjIpOworICAgICAgICBhc3NlcnRUcnVlKENvbGxlY3Rpb25zLmRpc2pvaW50KGMxLCBjMikpOworICAgICAgICBjMS5hZGQoYXJyMlsxMF0pOworICAgICAgICBhc3NlcnRGYWxzZShDb2xsZWN0aW9ucy5kaXNqb2ludChjMSwgYzIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMuZGlzam9pbnQoYzEsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLmRpc2pvaW50KG51bGwsIGMyKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Db2xsZWN0aW9ucy5FbXB0eUxpc3QjcmVhZFJlc29sdmUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfRW1wdHlMaXN0X3JlYWRSZXNvbHZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0LnZlcmlmeVNlbGYoQ29sbGVjdGlvbnMuRU1QVFlfTElTVCwgY29tcGFyYXRvcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zLkVtcHR5TWFwI3JlYWRSZXNvbHZlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0VtcHR5TWFwX3JlYWRSZXNvbHZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0LnZlcmlmeVNlbGYoQ29sbGVjdGlvbnMuRU1QVFlfTUFQLCBjb21wYXJhdG9yKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuRW1wdHlTZXQjcmVhZFJlc29sdmUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfRW1wdHlTZXRfcmVhZFJlc29sdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3QudmVyaWZ5U2VsZihDb2xsZWN0aW9ucy5FTVBUWV9TRVQsIGNvbXBhcmF0b3IpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2hlY2tlZENvbGxlY3Rpb25TZXJpYWxpemF0aW9uQ29tcGF0YWJpbGl0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDb2xsZWN0aW9uPFN0cmluZz4gYyA9IENvbGxlY3Rpb25zLmVtcHR5U2V0KCk7CisgICAgICAgIGMgPSBDb2xsZWN0aW9ucy5jaGVja2VkQ29sbGVjdGlvbihjLCBTdHJpbmcuY2xhc3MpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdGVyLmFzc2VydENvbXBhdGliaWxpdHlFcXVhbHMoYywgIi9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Db2xsZWN0aW9uc19DaGVja2VkQ29sbGVjdGlvbi5nb2xkZW4uc2VyIik7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RfY2hlY2tlZExpc3RSYW5kb21BY2Nlc3NTZXJpYWxpemF0aW9uQ29tcGF0YWJpbGl0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBMaXN0PFN0cmluZz4gYyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBhc3NlcnRUcnVlKGMgaW5zdGFuY2VvZiBSYW5kb21BY2Nlc3MpOworICAgICAgICBjID0gQ29sbGVjdGlvbnMuY2hlY2tlZExpc3QoYywgU3RyaW5nLmNsYXNzKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3Rlci5hc3NlcnRDb21wYXRpYmlsaXR5RXF1YWxzKGMsICIvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvQ29sbGVjdGlvbnNfQ2hlY2tlZExpc3RSYW5kb21BY2Nlc3MuZ29sZGVuLnNlciIpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NoZWNrZWRMaXN0U2VyaWFsaXphdGlvbkNvbXBhdGFiaWxpdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGMgPSBuZXcgTGlua2VkTGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGFzc2VydEZhbHNlKGMgaW5zdGFuY2VvZiBSYW5kb21BY2Nlc3MpOworICAgICAgICBjID0gQ29sbGVjdGlvbnMuY2hlY2tlZExpc3QoYywgU3RyaW5nLmNsYXNzKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3Rlci5hc3NlcnRDb21wYXRpYmlsaXR5RXF1YWxzKGMsICIvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvQ29sbGVjdGlvbnNfQ2hlY2tlZExpc3QuZ29sZGVuLnNlciIpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NoZWNrZWRTZXRTZXJpYWxpemF0aW9uQ29tcGF0YWJpbGl0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTZXQ8U3RyaW5nPiBjID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgICBhc3NlcnRGYWxzZShjIGluc3RhbmNlb2YgU29ydGVkU2V0KTsKKyAgICAgICAgYyA9IENvbGxlY3Rpb25zLmNoZWNrZWRTZXQoYywgU3RyaW5nLmNsYXNzKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3Rlci5hc3NlcnRDb21wYXRpYmlsaXR5RXF1YWxzKGMsICIvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvQ29sbGVjdGlvbnNfQ2hlY2tlZFNldC5nb2xkZW4uc2VyIik7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RfY2hlY2tlZE1hcFNlcmlhbGl6YXRpb25Db21wYXRhYmlsaXR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gYyA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOworICAgICAgICBhc3NlcnRGYWxzZShjIGluc3RhbmNlb2YgU29ydGVkTWFwKTsKKyAgICAgICAgYyA9IENvbGxlY3Rpb25zLmNoZWNrZWRNYXAoYywgU3RyaW5nLmNsYXNzLCBTdHJpbmcuY2xhc3MpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdGVyLmFzc2VydENvbXBhdGliaWxpdHlFcXVhbHMoYywgIi9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Db2xsZWN0aW9uc19DaGVja2VkTWFwLmdvbGRlbi5zZXIiKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdF9jaGVja2VkU29ydGVkU2V0U2VyaWFsaXphdGlvbkNvbXBhdGFiaWxpdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU29ydGVkU2V0PFN0cmluZz4gYyA9IG5ldyBUcmVlU2V0PFN0cmluZz4oKTsKKyAgICAgICAgYyA9IENvbGxlY3Rpb25zLmNoZWNrZWRTb3J0ZWRTZXQoYywgU3RyaW5nLmNsYXNzKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3Rlci5hc3NlcnRDb21wYXRpYmlsaXR5RXF1YWxzKGMsICIvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvQ29sbGVjdGlvbnNfQ2hlY2tlZFNvcnRlZFNldC5nb2xkZW4uc2VyIik7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RfY2hlY2tlZFNvcnRlZE1hcFNlcmlhbGl6YXRpb25Db21wYXRhYmlsaXR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNvcnRlZE1hcDxTdHJpbmcsIFN0cmluZz4gYyA9IG5ldyBUcmVlTWFwPFN0cmluZywgU3RyaW5nPigpOworICAgICAgICBjID0gQ29sbGVjdGlvbnMuY2hlY2tlZFNvcnRlZE1hcChjLCBTdHJpbmcuY2xhc3MsIFN0cmluZy5jbGFzcyk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0ZXIuYXNzZXJ0Q29tcGF0aWJpbGl0eUVxdWFscyhjLCAiL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL0NvbGxlY3Rpb25zX0NoZWNrZWRTb3J0ZWRNYXAuZ29sZGVuLnNlciIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2hlY2tlZENvbGxlY3Rpb25MamF2YV91dGlsX0NvbGxlY3Rpb25MamF2YV9sYW5nX0NsYXNzKCkgeworICAgICAgICBBcnJheUxpc3QgYWwgPSBuZXcgQXJyYXlMaXN0PEludGVnZXI+KCk7CisKKyAgICAgICAgQ29sbGVjdGlvbiBjID0gQ29sbGVjdGlvbnMuY2hlY2tlZENvbGxlY3Rpb24oYWwsIEludGVnZXIuY2xhc3MpOworCisgICAgICAgIGMuYWRkKG5ldyBJbnRlZ2VyKDEpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5hZGQobmV3IERvdWJsZSgzLjE0KSk7CisgICAgICAgICAgICBmYWlsKCJDbGFzc0Nhc3RFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2hlY2tlZExpc3RMamF2YV91dGlsX0xpc3RMamF2YV9sYW5nX0NsYXNzKCkgeworICAgICAgICBBcnJheUxpc3QgYWwgPSBuZXcgQXJyYXlMaXN0PEludGVnZXI+KCk7CisKKyAgICAgICAgTGlzdCBsID0gQ29sbGVjdGlvbnMuY2hlY2tlZExpc3QoYWwsIEludGVnZXIuY2xhc3MpOworCisgICAgICAgIGwuYWRkKG5ldyBJbnRlZ2VyKDEpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbC5hZGQobmV3IERvdWJsZSgzLjE0KSk7CisgICAgICAgICAgICBmYWlsKCJDbGFzc0Nhc3RFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2hlY2tlZE1hcExqYXZhX3V0aWxfTWFwTGphdmFfbGFuZ19DbGFzc0xqYXZhX2xhbmdfQ2xhc3MoKSB7CisgICAgICAgIEhhc2hNYXAgaG0gPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBTdHJpbmc+KCk7CisKKyAgICAgICAgTWFwIG0gPSBDb2xsZWN0aW9ucy5jaGVja2VkTWFwKGhtLCBJbnRlZ2VyLmNsYXNzLCBTdHJpbmcuY2xhc3MpOworCisgICAgICAgIG0ucHV0KDEsICJvbmUiKTsKKyAgICAgICAgbS5wdXQoMiwgInR3byIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLnB1dCgid3JvbiBrZXkiLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkNsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG0ucHV0KDMsIG5ldyBEb3VibGUoMy4xNCkpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NoZWNrZWRTZXRMamF2YV91dGlsX1NldExqYXZhX2xhbmdfQ2xhc3MoKSB7CisgICAgICAgIEhhc2hTZXQgaHMgPSBuZXcgSGFzaFNldDxJbnRlZ2VyPigpOworCisgICAgICAgIFNldCBzID0gQ29sbGVjdGlvbnMuY2hlY2tlZFNldChocywgSW50ZWdlci5jbGFzcyk7CisKKyAgICAgICAgcy5hZGQobmV3IEludGVnZXIoMSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmFkZChuZXcgRG91YmxlKDMuMTQpKTsKKyAgICAgICAgICAgIGZhaWwoIkNsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jaGVja2VkU29ydGVkTWFwTGphdmFfdXRpbF9Tb3J0ZWRNYXBMamF2YV9sYW5nX0NsYXNzTGphdmFfbGFuZ19DbGFzcygpIHsKKyAgICAgICAgVHJlZU1hcCB0bSA9IG5ldyBUcmVlTWFwPEludGVnZXIsIFN0cmluZz4oKTsKKworICAgICAgICBTb3J0ZWRNYXAgc20gPSBDb2xsZWN0aW9ucy5jaGVja2VkU29ydGVkTWFwKHRtLCBJbnRlZ2VyLmNsYXNzLCBTdHJpbmcuY2xhc3MpOworCisgICAgICAgIHNtLnB1dCgxLCAib25lIik7CisgICAgICAgIHNtLnB1dCgyLCAidHdvIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNtLnB1dCgid3JvbiBrZXkiLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkNsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNtLnB1dCgzLCBuZXcgRG91YmxlKDMuMTQpKTsKKyAgICAgICAgICAgIGZhaWwoIkNsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jaGVja2VkU29ydGVkU2V0TGphdmFfdXRpbF9Tb3J0ZWRTZXRMamF2YV9sYW5nX0NsYXNzKCkgeworICAgICAgICBUcmVlU2V0IHRzID0gbmV3IFRyZWVTZXQ8SW50ZWdlcj4oKTsKKworICAgICAgICBTb3J0ZWRTZXQgc3MgPSBDb2xsZWN0aW9ucy5jaGVja2VkU29ydGVkU2V0KHRzLCBJbnRlZ2VyLmNsYXNzKTsKKworICAgICAgICBzcy5hZGQobmV3IEludGVnZXIoMSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzcy5hZGQobmV3IERvdWJsZSgzLjE0KSk7CisgICAgICAgICAgICBmYWlsKCJDbGFzc0Nhc3RFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZW1wdHlMaXN0KCkgeworICAgICAgICBMaXN0PFN0cmluZz4gbHMgPSBDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKKyAgICAgICAgTGlzdDxJbnRlZ2VyPiBsaSA9IENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOworCisgICAgICAgIGFzc2VydFRydWUobHMuZXF1YWxzKGxpKSk7CisgICAgICAgIGFzc2VydFRydWUobGkuZXF1YWxzKENvbGxlY3Rpb25zLkVNUFRZX0xJU1QpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VtcHR5TWFwKCkgeworICAgICAgICBNYXA8SW50ZWdlciwgU3RyaW5nPiBtaXMgPSBDb2xsZWN0aW9ucy5lbXB0eU1hcCgpOworICAgICAgICBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBtc2kgPSBDb2xsZWN0aW9ucy5lbXB0eU1hcCgpOworCisgICAgICAgIGFzc2VydFRydWUobWlzLmVxdWFscyhtc2kpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtc2kuZXF1YWxzKENvbGxlY3Rpb25zLkVNUFRZX01BUCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZW1wdHlTZXQoKSB7CisgICAgICAgIFNldDxTdHJpbmc+IHNzID0gQ29sbGVjdGlvbnMuZW1wdHlTZXQoKTsKKyAgICAgICAgU2V0PEludGVnZXI+IHNpID0gQ29sbGVjdGlvbnMuZW1wdHlTZXQoKTsKKworICAgICAgICBhc3NlcnRUcnVlKHNzLmVxdWFscyhzaSkpOworICAgICAgICBhc3NlcnRUcnVlKHNpLmVxdWFscyhDb2xsZWN0aW9ucy5FTVBUWV9TRVQpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkRXZlbnRMaXN0ZW5lclByb3h5VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZEV2ZW50TGlzdGVuZXJQcm94eVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MDA3YmE2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZEV2ZW50TGlzdGVuZXJQcm94eVRlc3QuamF2YQpAQCAtMCwwICsxLDQ2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyOworaW1wb3J0IGphdmEudXRpbC5FdmVudExpc3RlbmVyUHJveHk7CisKK3B1YmxpYyBjbGFzcyBPbGRFdmVudExpc3RlbmVyUHJveHlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgY2xhc3MgTW9ja19FdmVudExpc3RlbmVyIGltcGxlbWVudHMgRXZlbnRMaXN0ZW5lciB7CisgICAgfQorCisgICAgY2xhc3MgTW9ja19FdmVudExpc3RlbmVyUHJveHkgZXh0ZW5kcyBFdmVudExpc3RlbmVyUHJveHkgeworICAgICAgICBwdWJsaWMgTW9ja19FdmVudExpc3RlbmVyUHJveHkoRXZlbnRMaXN0ZW5lciBsaXN0ZW5lcikgeworICAgICAgICAgICAgc3VwZXIobGlzdGVuZXIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEV2ZW50TGlzdGVuZXJQcm94eSgpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXcgTW9ja19FdmVudExpc3RlbmVyUHJveHkobnVsbCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKG5ldyBNb2NrX0V2ZW50TGlzdGVuZXJQcm94eShuZXcgTW9ja19FdmVudExpc3RlbmVyKCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TGlzdGVuZXIoKSB7CisgICAgICAgIEV2ZW50TGlzdGVuZXIgZWwgPSBuZXcgTW9ja19FdmVudExpc3RlbmVyKCk7CisgICAgICAgIEV2ZW50TGlzdGVuZXJQcm94eSBlbHAgPSBuZXcgTW9ja19FdmVudExpc3RlbmVyUHJveHkoZWwpOworCisgICAgICAgIGFzc2VydFNhbWUoZWwsIGVscC5nZXRMaXN0ZW5lcigpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkRm9ybWF0dGFibGVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkRm9ybWF0dGFibGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzI3MmY4ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRGb3JtYXR0YWJsZVRlc3QuamF2YQpAQCAtMCwwICsxLDU4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEudXRpbC5Gb3JtYXR0YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuRm9ybWF0dGVyOworCitwdWJsaWMgY2xhc3MgT2xkRm9ybWF0dGFibGVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgY2xhc3MgTW9ja19Gb3JtYXR0YWJsZSBpbXBsZW1lbnRzIEZvcm1hdHRhYmxlIHsKKyAgICAgICAgYm9vbGVhbiBmbGFnID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIHZvaWQgZm9ybWF0VG8oRm9ybWF0dGVyIGFyZzAsIGludCBhcmcxLCBpbnQgYXJnMiwgaW50IGFyZzMpIHsKKyAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCisgICAgICAgICAgICBpZiAoYXJnMyA9PSAxKSB7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCJzaW5nbGUgcHJlY2lzaW9uICIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGFyZzMgPT0gMikgeworICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgiZG91YmxlIHByZWNpc2lvbiAiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYXJnMC5mb3JtYXQoc2IudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBmbGFnID0gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRm9ybWF0VG9DYWxsZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gZmxhZzsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRUbygpIHsKKyAgICAgICAgRm9ybWF0dGVyIGZtdCA9IG5ldyBGb3JtYXR0ZXIoKTsKKyAgICAgICAgTW9ja19Gb3JtYXR0YWJsZSBtZiA9IG5ldyBNb2NrX0Zvcm1hdHRhYmxlKCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShmbXQuZm9ybWF0KCIlMS4xcyIsIG1mKS50b1N0cmluZygpLmVxdWFscygic2luZ2xlIHByZWNpc2lvbiAiKSk7CisgICAgICAgIGFzc2VydFRydWUoZm10LmZvcm1hdCgiJTIuMXMiLCBtZikudG9TdHJpbmcoKS5lcXVhbHMoInNpbmdsZSBwcmVjaXNpb24gc2luZ2xlIHByZWNpc2lvbiAiKSk7CisgICAgICAgIGFzc2VydFRydWUoZm10LmZvcm1hdCgiJTIuMnMiLCBtZikudG9TdHJpbmcoKS5lcXVhbHMoInNpbmdsZSBwcmVjaXNpb24gc2luZ2xlIHByZWNpc2lvbiBkb3VibGUgcHJlY2lzaW9uICIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtZi5pc0Zvcm1hdFRvQ2FsbGVkKCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZEZvcm1hdHRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRGb3JtYXR0ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTNkOGViMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRGb3JtYXR0ZXJUZXN0LmphdmEKQEAgLTAsMCArMSwxMzcgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkZvcm1hdHRhYmxlOworaW1wb3J0IGphdmEudXRpbC5Gb3JtYXR0ZXI7CitpbXBvcnQgamF2YS51dGlsLkZvcm1hdHRlckNsb3NlZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSWxsZWdhbEZvcm1hdEZsYWdzRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Mb2NhbGU7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBPbGRGb3JtYXR0ZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF9Gb3JtYXR0YWJsZSgpIHsKKyAgICAgICAgRm9ybWF0dGFibGUgb25lcyA9IG5ldyBGb3JtYXR0YWJsZSgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGZvcm1hdFRvKEZvcm1hdHRlciBmb3JtYXR0ZXIsIGludCBmbGFncywgaW50IHdpZHRoLCBpbnQgcHJlY2lzaW9uKSB0aHJvd3MgSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZm9ybWF0dGVyLm91dCgpLmFwcGVuZCgiMTExIik7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIEZvcm1hdHRhYmxlIHR3b3MgPSBuZXcgRm9ybWF0dGFibGUoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBmb3JtYXRUbyhGb3JtYXR0ZXIgZm9ybWF0dGVyLCBpbnQgZmxhZ3MsIGludCB3aWR0aCwgaW50IHByZWNpc2lvbikgdGhyb3dzIElsbGVnYWxGb3JtYXRFeGNlcHRpb24geworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGZvcm1hdHRlci5vdXQoKS5hcHBlbmQoIjIyMiIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIGFzc2VydEVxdWFscygiYWFhIDExMT8iLCBuZXcgRm9ybWF0dGVyKCkuZm9ybWF0KCJhYWEgJXM/Iiwgb25lcykudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYWFhIDExMSBiYmIgMjIyPyIsIG5ldyBGb3JtYXR0ZXIoKS5mb3JtYXQoImFhYSAlcyBiYmIgJXM/Iiwgb25lcywgdHdvcykudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9mb3JtYXRMamF2YV91dGlsX0xvY2FsZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIERvdWJsZSB2YWwgPSBuZXcgRG91YmxlKDMuMTQpOworICAgICAgICBDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOworICAgICAgICBGb3JtYXR0ZXIgZkxvYyA9IG51bGw7CisgICAgICAgIEZvcm1hdHRlciBmTm9MID0gbnVsbDsKKyAgICAgICAgY2FsLnNldCgyMDA4LCBDYWxlbmRhci5TRVBURU1CRVIsIDIzLCAxOCwgMzApOworCisgICAgICAgIGlmIChTdXBwb3J0X0xvY2FsZS5pc0xvY2FsZUF2YWlsYWJsZShMb2NhbGUuR0VSTUFOKSkgeworICAgICAgICAgICAgZkxvYyA9IG5ldyBGb3JtYXR0ZXIoTG9jYWxlLkdFUk1BTik7CisgICAgICAgICAgICBmTm9MID0gbmV3IEZvcm1hdHRlcihMb2NhbGUuR0VSTUFOKTsKKyAgICAgICAgICAgIGZMb2MuZm9ybWF0KExvY2FsZS5VUywgIiVmIiwgdmFsKTsKKyAgICAgICAgICAgIGZOb0wuZm9ybWF0KCIlZiIsIHZhbCk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShmTG9jLnRvU3RyaW5nKCkuZXF1YWxzKGZOb0wudG9TdHJpbmcoKSkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKExvY2FsZS5GUkFOQ0UpKSB7CisgICAgICAgICAgICBmTG9jID0gbmV3IEZvcm1hdHRlcihMb2NhbGUuRlJBTkNFKTsKKyAgICAgICAgICAgIGZOb0wgPSBuZXcgRm9ybWF0dGVyKExvY2FsZS5GUkFOQ0UpOworICAgICAgICAgICAgZkxvYy5mb3JtYXQoTG9jYWxlLlVTLCAiJWYiLCB2YWwpOworICAgICAgICAgICAgZk5vTC5mb3JtYXQoIiVmIiwgdmFsKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGZMb2MudG9TdHJpbmcoKS5lcXVhbHMoZk5vTC50b1N0cmluZygpKSk7CisgICAgICAgIH0KKworICAgICAgICBmTG9jID0gbmV3IEZvcm1hdHRlcihMb2NhbGUuVVMpOworICAgICAgICBmTm9MID0gbmV3IEZvcm1hdHRlcihMb2NhbGUuVVMpOworICAgICAgICBmTG9jLmZvcm1hdChMb2NhbGUuVVMsICIlZiIsIHZhbCk7CisgICAgICAgIGZOb0wuZm9ybWF0KCIlZiIsIHZhbCk7CisgICAgICAgIGFzc2VydFRydWUoZkxvYy50b1N0cmluZygpLmVxdWFscyhmTm9MLnRvU3RyaW5nKCkpKTsKKworICAgICAgICBpZiAoU3VwcG9ydF9Mb2NhbGUuaXNMb2NhbGVBdmFpbGFibGUoTG9jYWxlLkdFUk1BTikpIHsKKyAgICAgICAgICAgIGZMb2MgPSBuZXcgRm9ybWF0dGVyKExvY2FsZS5HRVJNQU4pOworICAgICAgICAgICAgZk5vTCA9IG5ldyBGb3JtYXR0ZXIoTG9jYWxlLkdFUk1BTik7CisgICAgICAgICAgICBmTG9jLmZvcm1hdChMb2NhbGUuVVMsICIldEEgJXRCICV0ZCAldFQiLCBjYWwsIGNhbCwgIGNhbCwgY2FsKTsKKyAgICAgICAgICAgIGZOb0wuZm9ybWF0KCIldEEgJXRCICV0ZCAldFQiLCBjYWwsIGNhbCwgIGNhbCwgY2FsKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGZMb2MudG9TdHJpbmcoKS5lcXVhbHMoZk5vTC50b1N0cmluZygpKSk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoU3VwcG9ydF9Mb2NhbGUuaXNMb2NhbGVBdmFpbGFibGUoTG9jYWxlLkZSQU5DRSkpIHsKKyAgICAgICAgICAgIGZMb2MgPSBuZXcgRm9ybWF0dGVyKExvY2FsZS5GUkFOQ0UpOworICAgICAgICAgICAgZk5vTCA9IG5ldyBGb3JtYXR0ZXIoTG9jYWxlLkZSQU5DRSk7CisgICAgICAgICAgICBmTG9jLmZvcm1hdChMb2NhbGUuVVMsICIldEEgJXRCICV0ZCAldFQiLCBjYWwsIGNhbCwgIGNhbCwgY2FsKTsKKyAgICAgICAgICAgIGZOb0wuZm9ybWF0KCIldEEgJXRCICV0ZCAldFQiLCBjYWwsIGNhbCwgIGNhbCwgY2FsKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGZMb2MudG9TdHJpbmcoKS5lcXVhbHMoZk5vTC50b1N0cmluZygpKSk7CisgICAgICAgIH0KKworICAgICAgICBmTG9jID0gbmV3IEZvcm1hdHRlcihMb2NhbGUuVVMpOworICAgICAgICBmTm9MID0gbmV3IEZvcm1hdHRlcihMb2NhbGUuVVMpOworICAgICAgICBmTG9jLmZvcm1hdChMb2NhbGUuVVMsICIldEEgJXRCICV0ZCAldFQiLCBjYWwsIGNhbCwgIGNhbCwgY2FsKTsKKyAgICAgICAgZk5vTC5mb3JtYXQoIiV0QSAldEIgJXRkICV0VCIsIGNhbCwgY2FsLCAgY2FsLCBjYWwpOworICAgICAgICBhc3NlcnRUcnVlKGZMb2MudG9TdHJpbmcoKS5lcXVhbHMoZk5vTC50b1N0cmluZygpKSk7CisKKyAgICAgICAgZmluYWwgU3RyaW5nW10gaWxsRmxhZ3MgPSB7ICIlKyBlIiwgIiUrIEUiLCAiJSsgZyIsICIlKyBHIiwgIiUrIGYiLAorICAgICAgICAgICAgICAgICIlKyBhIiwgIiUrIEEiLCAiJS0wM2UiLCAiJS0wM0UiLCAiJS0wM2ciLCAiJS0wM0ciLCAiJS0wM2YiLAorICAgICAgICAgICAgICAgICIlLTAzYSIsICIlLTAzQSIgfTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbGxGbGFncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKExvY2FsZS5GUkFOQ0UpKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZkxvYyA9IG5ldyBGb3JtYXR0ZXIoTG9jYWxlLlVTKTsKKyAgICAgICAgICAgICAgICAgICAgZkxvYy5mb3JtYXQoTG9jYWxlLkZSQU5DRSwgaWxsRmxhZ3NbaV0sIDEuMjNkKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElsbGVnYWxGb3JtYXRGbGFnc0V4Y2VwdGlvbiIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxGb3JtYXRGbGFnc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKExvY2FsZS5DQU5BREEpKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZkxvYyA9IG5ldyBGb3JtYXR0ZXIoTG9jYWxlLkNBTkFEQSk7CisgICAgICAgICAgICAgICAgICAgIGZMb2MuZm9ybWF0KExvY2FsZS5HRVJNQU4sIGlsbEZsYWdzW2ldLCAoRG91YmxlKSBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElsbGVnYWxGb3JtYXRGbGFnc0V4Y2VwdGlvbiIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxGb3JtYXRGbGFnc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmTG9jLmNsb3NlKCk7CisKKyAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKExvY2FsZS5HRVJNQU4pKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZMb2MuZm9ybWF0KExvY2FsZS5HRVJNQU4sICIlZiIsIHZhbCk7CisgICAgICAgICAgICB9IGNhdGNoIChGb3JtYXR0ZXJDbG9zZWRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRHcmVnb3JpYW5DYWxlbmRhclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRHcmVnb3JpYW5DYWxlbmRhclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NjY1ZWYzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZEdyZWdvcmlhbkNhbGVuZGFyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5UaW1lWm9uZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBPbGRHcmVnb3JpYW5DYWxlbmRhclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SG91cigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcihqYXZhLnV0aWwuVGltZVpvbmUsIGphdmEudXRpbC5Mb2NhbGUpCisgICAgICAgIERhdGUgbm93ID0gbmV3IERhdGUoKTsKKworICAgICAgICBHcmVnb3JpYW5DYWxlbmRhciBnYzEgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkdNVCsxIiksIExvY2FsZS5GUkFOQ0UpOworICAgICAgICBnYzEuc2V0VGltZShub3cpOworICAgICAgICBHcmVnb3JpYW5DYWxlbmRhciBnYzIgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkdNVCsyIiksIExvY2FsZS5VUyk7CisgICAgICAgIGdjMi5zZXRUaW1lKG5vdyk7CisgICAgICAgIC8vIENTVCBpcyAxIGhvdXIgYmVmb3JlIEVTVCwgYWRkIDEgdG8gdGhlIENTVCB0aW1lIGFuZCBjb252ZXJ0IHRvIDAtMTIgdmFsdWUKKyAgICAgICAgYXNzZXJ0VHJ1ZShnYzIuZ2V0KENhbGVuZGFyLkhPVVIpID09ICgoZ2MxLmdldChDYWxlbmRhci5IT1VSKSArIDEpICUgMTIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbXB1dGVUaW1lKCkgeworICAgICAgICBHcmVnb3JpYW5DYWxlbmRhciBnMSA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcihUaW1lWm9uZS5nZXRUaW1lWm9uZSgiRXVyb3BlL01vc2NvdyIpKTsKKyAgICAgICAgZzEuY2xlYXIoKTsKKyAgICAgICAgZzEuc2V0KDIwMDYsIC05LCAyOSwgMDIsIDUwLCAwMCk7IC8vIHRyYW5zaXRpb24gZnJvbSBEU1QKKyAgICAgICAgZzEuc2V0TGVuaWVudChmYWxzZSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGcxLmdldFRpbWVJbk1pbGxpcygpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY29tcHV0ZUZpZWxkcygpIHsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgZyA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigKKyAgICAgICAgICAgIFRpbWVab25lLmdldFRpbWVab25lKCJFdXJvcGUvTG9uZG9uIiksCisgICAgICAgICAgICBuZXcgTG9jYWxlKCJlbiIsICJHQiIpKTsKKyAgICAgICAgZy5jbGVhcigpOworICAgICAgICBnLnNldFRpbWVJbk1pbGxpcygxMjIyMTg1NjAwMjI1TCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCAgICAgICAgICAgICAgICAgIGcuZ2V0KENhbGVuZGFyLkVSQSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMjAwOCwgZy5nZXQoQ2FsZW5kYXIuWUVBUikpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ2FsZW5kYXIuU0VQVEVNQkVSLCBnLmdldChDYWxlbmRhci5NT05USCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMjMsICAgICAgICAgICAgICAgICBnLmdldChDYWxlbmRhci5EQVlfT0ZfTU9OVEgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDE3LCAgICAgICAgICAgICAgICAgZy5nZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGcuZ2V0KENhbGVuZGFyLk1JTlVURSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGFzaENvZGUoKSB7CisgICAgICAgIEdyZWdvcmlhbkNhbGVuZGFyIGcgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoCisgICAgICAgICAgICAgICAgVGltZVpvbmUuZ2V0VGltZVpvbmUoIkV1cm9wZS9Mb25kb24iKSwKKyAgICAgICAgICAgICAgICBuZXcgTG9jYWxlKCJlbiIsICJHQiIpKTsKKyAgICAgICAgZy5jbGVhcigpOworICAgICAgICBnLnNldFRpbWVJbk1pbGxpcygxMjIyMTg1NjAwMjI1TCk7CisKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgZzEgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoCisgICAgICAgICAgICAgICAgVGltZVpvbmUuZ2V0VGltZVpvbmUoIkV1cm9wZS9Nb3Njb3ciKSk7CisgICAgICAgIGcxLmNsZWFyKCk7CisgICAgICAgIGcxLnNldCgyMDA4LCBDYWxlbmRhci5TRVBURU1CRVIsIDIzLCAxOCwgMCwgMCk7CisgICAgICAgIGFzc2VydE5vdFNhbWUoZy5oYXNoQ29kZSgpLCBnMS5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEZpcnN0RGF5T2ZXZWVrSSgpIHsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgZyA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigKKyAgICAgICAgICAgICAgICBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiRXVyb3BlL0xvbmRvbiIpLAorICAgICAgICAgICAgICAgIG5ldyBMb2NhbGUoImVuIiwgIkdCIikpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgICAgICAgICAgZy5zZXRGaXJzdERheU9mV2VlayhpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpLCBnLmdldEZpcnN0RGF5T2ZXZWVrKCkpOworICAgICAgICB9CisgICAgICAgIGcuc2V0TGVuaWVudChmYWxzZSk7CisgICAgICAgIGcuc2V0Rmlyc3REYXlPZldlZWsoMTApOworICAgICAgICBnLnNldEZpcnN0RGF5T2ZXZWVrKC0xMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRNaW5pbWFsRGF5c0luRmlyc3RXZWVrSSgpIHsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgZyA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigKKyAgICAgICAgICAgICAgICBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiRXVyb3BlL0xvbmRvbiIpLAorICAgICAgICAgICAgICAgIG5ldyBMb2NhbGUoImVuIiwgIkdCIikpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgICAgICAgICAgZy5zZXRNaW5pbWFsRGF5c0luRmlyc3RXZWVrKGkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGksIGcuZ2V0TWluaW1hbERheXNJbkZpcnN0V2VlaygpKTsKKyAgICAgICAgfQorICAgICAgICBnLnNldExlbmllbnQoZmFsc2UpOworICAgICAgICBnLnNldE1pbmltYWxEYXlzSW5GaXJzdFdlZWsoMTApOworICAgICAgICBnLnNldE1pbmltYWxEYXlzSW5GaXJzdFdlZWsoLTEwKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkTGlua2VkSGFzaE1hcFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRMaW5rZWRIYXNoTWFwVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjYmQ5NWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkTGlua2VkSGFzaE1hcFRlc3QuamF2YQpAQCAtMCwwICsxLDY4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkNvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoTWFwOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZExpbmtlZEhhc2hNYXBUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdExpbmtlZEhhc2hNYXAoKSB7CisgICAgICAgIC8vIHdlIHdhbnQgdG8gdGVzdCB0aGUgTGlua2VkSGFzaE1hcCBpbiBhY2Nlc3Mgb3JkZXJpbmcgbW9kZS4KKyAgICAgICAgTGlua2VkSGFzaE1hcCBtYXAgPSBuZXcgTGlua2VkSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oMTAsIDAuNzVmLCB0cnVlKTsKKworICAgICAgICBtYXAucHV0KCJrZXkxIiwgInZhbHVlMSIpOworICAgICAgICBtYXAucHV0KCJrZXkyIiwgInZhbHVlMiIpOworICAgICAgICBtYXAucHV0KCJrZXkzIiwgInZhbHVlMyIpOworCisgICAgICAgIEl0ZXJhdG9yIGl0ZXJhdG9yID0gbWFwLmtleVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgIFN0cmluZyBpZCA9IChTdHJpbmcpIGl0ZXJhdG9yLm5leHQoKTsKKyAgICAgICAgbWFwLmdldChpZCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpdGVyYXRvci5uZXh0KCk7CisgICAgICAgICAgICAvLyBBIExpbmtlZEhhc2hNYXAgaXMgc3VwcG9zZWQgdG8gdGhyb3cgdGhpcyBFeGNlcHRpb24gd2hlbiBhCisgICAgICAgICAgICAvLyBpdGVyYXRvci5uZXh0KCkgT3BlcmF0aW9uIHRha2VzIHBsYWNlIGFmdGVyIGEgZ2V0CisgICAgICAgICAgICAvLyBPcGVyYXRpb24uIFRoaXMgaXMgYmVjYXVzZSB0aGUgZ2V0IE9wZXJhdGlvbiBpcyBjb25zaWRlcmVkCisgICAgICAgICAgICAvLyBhIHN0cnVjdHVyYWwgbW9kaWZpY2F0aW9uIGlmIHRoZSBMaW5rZWRIYXNoTWFwIGlzIGluCisgICAgICAgICAgICAvLyBhY2Nlc3Mgb3JkZXIgbW9kZS4KKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgTGlua2VkSGFzaE1hcCBtYXBDbG9uZSA9IChMaW5rZWRIYXNoTWFwKSBtYXAuY2xvbmUoKTsKKworICAgICAgICBpdGVyYXRvciA9IG1hcC5rZXlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICBpZCA9IChTdHJpbmcpIGl0ZXJhdG9yLm5leHQoKTsKKyAgICAgICAgbWFwQ2xvbmUuZ2V0KGlkKTsKKyAgICAgICAgaXRlcmF0b3IubmV4dCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgTGlua2VkSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oLTEwLCAwLjc1ZiwgdHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IExpbmtlZEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KDEwLCAtMC43NWYsIHRydWUpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZExpc3RJdGVyYXRvclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRMaXN0SXRlcmF0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGIzODEyZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRMaXN0SXRlcmF0b3JUZXN0LmphdmEKQEAgLTAsMCArMSwyNTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS51dGlsLkxpbmtlZExpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3RJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKKworcHVibGljIGNsYXNzIE9sZExpc3RJdGVyYXRvclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBMaXN0SXRlcmF0b3I8SW50ZWdlcj4gbCA9IG51bGw7CisKKyAgICBzdGF0aWMgT2JqZWN0W10gb2JqQXJyYXk7CisgICAgeworICAgICAgICBvYmpBcnJheSA9IG5ldyBPYmplY3RbMTAwXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvYmpBcnJheS5sZW5ndGg7IGkrKykKKyAgICAgICAgICAgIG9iakFycmF5W2ldID0gbmV3IEludGVnZXIoaSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEhhc05leHQoKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2JqQXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUobC5oYXNOZXh0KCkpOworICAgICAgICAgICAgbC5uZXh0KCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UobC5oYXNOZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROZXh0KCkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iakFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKG9iakFycmF5W2ldLmVxdWFscyhsLm5leHQoKSkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGwubmV4dCgpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIE1vY2tfTGlzdEl0ZXJhdG9yIGltcGxlbWVudHMgTGlzdEl0ZXJhdG9yIHsKKyAgICAgICAgcHVibGljIHZvaWQgYWRkKE9iamVjdCBvKSB7CisgICAgICAgICAgICBpZigoKFN0cmluZykgbykuZXF1YWxzKCJXcm9uZyBlbGVtZW50IikpIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGlmKG8uZ2V0Q2xhc3MoKSA9PSBEb3VibGUuY2xhc3MpIHRocm93IG5ldyBDbGFzc0Nhc3RFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc1ByZXZpb3VzKCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBuZXh0KCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IG5leHRJbmRleCgpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBwcmV2aW91cygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBwcmV2aW91c0luZGV4KCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldChPYmplY3QgbykgeworICAgICAgICAgICAgaWYoKChTdHJpbmcpIG8pLmVxdWFscygiV3JvbmcgZWxlbWVudCIpKSB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICBpZihvLmdldENsYXNzKCkgPT0gRG91YmxlLmNsYXNzKSB0aHJvdyBuZXcgQ2xhc3NDYXN0RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsLnJlbW92ZSgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvYmpBcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbC5uZXh0KCk7CisgICAgICAgICAgICBsLnJlbW92ZSgpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UobC5oYXNQcmV2aW91cygpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsLnJlbW92ZSgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBNb2NrX0xpc3RJdGVyYXRvciBtbCA9IG5ldyBNb2NrX0xpc3RJdGVyYXRvcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWwucmVtb3ZlKCk7CisgICAgICAgICAgICBmYWlsKCJVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzUHJldmlvdXMoKSB7CisgICAgICAgIGFzc2VydEZhbHNlKGwuaGFzUHJldmlvdXMoKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2JqQXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGwubmV4dCgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShsLmhhc1ByZXZpb3VzKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFByZXZpb3VzKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbC5wcmV2aW91cygpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB3aGlsZShsLmhhc05leHQoKSkgeworICAgICAgICAgICAgbC5uZXh0KCk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gb2JqQXJyYXkubGVuZ3RoIC0gMTsgaSA+IC0xIDsgaS0tKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKG9iakFycmF5W2ldLmVxdWFscyhsLnByZXZpb3VzKCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsLnByZXZpb3VzKCk7CisgICAgICAgICAgICBmYWlsKCJOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5leHRJbmRleCgpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvYmpBcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShvYmpBcnJheVtpXS5lcXVhbHMobC5uZXh0SW5kZXgoKSkpOworICAgICAgICAgICAgbC5uZXh0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJldmlvdXNJbmRleCgpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvYmpBcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShvYmpBcnJheVtpXS5lcXVhbHMobC5wcmV2aW91c0luZGV4KCkgKyAxKSk7CisgICAgICAgICAgICBsLm5leHQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsLnNldChuZXcgSW50ZWdlcigxKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2JqQXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGwubmV4dCgpOworICAgICAgICAgICAgbC5zZXQoKEludGVnZXIpb2JqQXJyYXlbb2JqQXJyYXkubGVuZ3RoIC0gaSAtIDFdKTsKKyAgICAgICAgfQorCisgICAgICAgIGwucmVtb3ZlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsLnNldChuZXcgSW50ZWdlcigxKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIE1vY2tfTGlzdEl0ZXJhdG9yIG1sID0gbmV3IE1vY2tfTGlzdEl0ZXJhdG9yKCk7CisgICAgICAgIG1sLm5leHQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1sLnNldCgiV3JvbmcgZWxlbWVudCIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWwuc2V0KG5ldyBEb3VibGUoIjMuMTQiKSk7CisgICAgICAgICAgICBmYWlsKCJDbGFzc0Nhc3RFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtbC5zZXQoIiIpOworICAgICAgICAgICAgZmFpbCgiVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFkZCgpIHsKKyAgICAgICAgbC5hZGQobmV3IEludGVnZXIoMzMpKTsKKworICAgICAgICBNb2NrX0xpc3RJdGVyYXRvciBtbCA9IG5ldyBNb2NrX0xpc3RJdGVyYXRvcigpOworICAgICAgICBtbC5uZXh0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtbC5hZGQoIldyb25nIGVsZW1lbnQiKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1sLmFkZChuZXcgRG91YmxlKCIzLjE0IikpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWwuYWRkKCIiKTsKKyAgICAgICAgICAgIGZhaWwoIlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIExpbmtlZExpc3QgbGwgPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iakFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBsbC5hZGQob2JqQXJyYXlbaV0pOworICAgICAgICB9CisgICAgICAgIGwgPSBsbC5saXN0SXRlcmF0b3IoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkTWFwRW50cnlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkTWFwRW50cnlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWY4YWRkNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRNYXBFbnRyeVRlc3QuamF2YQpAQCAtMCwwICsxLDExMiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCitwdWJsaWMgY2xhc3MgT2xkTWFwRW50cnlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIE1hcC5FbnRyeSBtZSA9IG51bGw7CisgICAgSGFzaE1hcCAgIGhtID0gbnVsbDsKKyAgICBJdGVyYXRvciAgaSAgPSBudWxsOworCisgICAgcHVibGljIHZvaWQgdGVzdEdldEtleSgpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShobS5jb250YWluc0tleShtZS5nZXRLZXkoKSkpOworICAgICAgICBobS5jbGVhcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWUuZ2V0S2V5KCk7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VmFsdWUoKSB7CisgICAgICAgIGFzc2VydFRydWUoaG0uY29udGFpbnNWYWx1ZShtZS5nZXRWYWx1ZSgpKSk7CisgICAgICAgIGhtLmNsZWFyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtZS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgTW9ja19IYXNoTWFwIGV4dGVuZHMgSGFzaE1hcCB7CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgT2JqZWN0IHB1dChPYmplY3Qga2V5LCBPYmplY3QgdmFsKSB7CisgICAgICAgICAgICBpZiAodmFsID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgaWYgKHZhbC5nZXRDbGFzcygpID09IERvdWJsZS5jbGFzcykgdGhyb3cgbmV3IENsYXNzQ2FzdEV4Y2VwdGlvbigpOworICAgICAgICAgICAgaWYgKCgoU3RyaW5nKXZhbCkuZXF1YWxzKCJXcm9uZyBlbGVtZW50IikpIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBmYWtlUHV0KE9iamVjdCBrZXksIE9iamVjdCB2YWwpIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5wdXQoa2V5LCB2YWwpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldFZhbHVlKCkgeworICAgICAgICBNb2NrX0hhc2hNYXAgbWhtID0gbmV3IE1vY2tfSGFzaE1hcCgpOworCisgICAgICAgIG1obS5mYWtlUHV0KG5ldyBJbnRlZ2VyKDEpLCAiT25lIik7CisgICAgICAgIG1obS5mYWtlUHV0KG5ldyBJbnRlZ2VyKDIpLCAiVHdvIik7CisKKyAgICAgICAgaSA9IG1obS5lbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgIG1lID0gKE1hcC5FbnRyeSlpLm5leHQoKTsKKworICAgICAgICBtZS5zZXRWYWx1ZSgiV3JvbmcgZWxlbWVudCIpOworCisgICAgICAgIGhtLmNsZWFyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtZS5zZXRWYWx1ZSgiIik7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXF1YWxzKCkgeworICAgICAgICBNYXAuRW50cnkgbWUxID0gKE1hcC5FbnRyeSlpLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWUuZXF1YWxzKG1lMSkpOworICAgICAgICBhc3NlcnRGYWxzZShtZS5lcXVhbHModGhpcykpOworICAgICAgICBtZTEgPSBtZTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtZS5lcXVhbHMobWUxKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEhhc2hDb2RlKCkgeworICAgICAgICBNYXAuRW50cnkgbWUxID0gKE1hcC5FbnRyeSlpLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtZS5oYXNoQ29kZSgpICE9IG1lMS5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBobSA9IG5ldyBIYXNoTWFwKCk7CisKKyAgICAgICAgaG0ucHV0KG5ldyBJbnRlZ2VyKDEpLCAib25lIik7CisgICAgICAgIGhtLnB1dChuZXcgSW50ZWdlcigyKSwgInR3byIpOworCisgICAgICAgIGkgPSBobS5lbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgIG1lID0gKE1hcC5FbnRyeSlpLm5leHQoKTsKKworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRPYnNlcnZlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRPYnNlcnZlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MmI5MTYxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZE9ic2VydmVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLk9ic2VydmFibGU7CitpbXBvcnQgamF2YS51dGlsLk9ic2VydmVyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZE9ic2VydmVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIGNsYXNzIE1vY2tfT2JzZXJ2ZXIgaW1wbGVtZW50cyBPYnNlcnZlciB7CisgICAgICAgIGludCB1cGRhdGVDb3VudCA9IDA7CisKKyAgICAgICAgcHVibGljIHZvaWQgdXBkYXRlKE9ic2VydmFibGUgb2JzZXJ2ZWQsIE9iamVjdCBhcmcpIHsKKyAgICAgICAgICAgICsrdXBkYXRlQ291bnQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldFVwZGF0ZUNvdW50KCkgeworICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZUNvdW50OworICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgVGVzdE9ic2VydmFibGUgZXh0ZW5kcyBPYnNlcnZhYmxlIHsKKyAgICAgICAgcHVibGljIHZvaWQgZG9DaGFuZ2UoKSB7CisgICAgICAgICAgICBzZXRDaGFuZ2VkKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXBkYXRlKCkgeworICAgICAgICBUZXN0T2JzZXJ2YWJsZSBvYnNlcnZhYmxlID0gbmV3IFRlc3RPYnNlcnZhYmxlKCk7CisgICAgICAgIE1vY2tfT2JzZXJ2ZXIgb2JzZXJ2ZXIgPSBudWxsOworICAgICAgICBvYnNlcnZhYmxlLmFkZE9ic2VydmVyKG9ic2VydmVyID0gbmV3IE1vY2tfT2JzZXJ2ZXIoKSk7CisgICAgICAgIG9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBvYnNlcnZlci5nZXRVcGRhdGVDb3VudCgpKTsKKyAgICAgICAgb2JzZXJ2YWJsZS5kb0NoYW5nZSgpOworICAgICAgICBvYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgb2JzZXJ2ZXIuZ2V0VXBkYXRlQ291bnQoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZFByaW9yaXR5UXVldWVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkUHJpb3JpdHlRdWV1ZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMmUyYTAzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZFByaW9yaXR5UXVldWVUZXN0LmphdmEKQEAgLTAsMCArMSwxMzEgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db21wYXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Qcmlvcml0eVF1ZXVlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCB0ZXN0cy51dGlsLlNlcmlhbGl6YXRpb25UZXN0ZXI7CisKK3B1YmxpYyBjbGFzcyBPbGRQcmlvcml0eVF1ZXVlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRVJJQUxJWkFUSU9OX0ZJTEVfTkFNRSA9ICIvc2VyaWFsaXphdGlvbi90ZXN0cy9hcGkvamF2YS91dGlsL1ByaW9yaXR5UXVldWUuZ29sZGVuLnNlciI7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySSgpIHsKKyAgICAgICAgUHJpb3JpdHlRdWV1ZTxPYmplY3Q+IHF1ZXVlID0gbmV3IFByaW9yaXR5UXVldWU8T2JqZWN0PigxMDApOworICAgICAgICBhc3NlcnROb3ROdWxsKHF1ZXVlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHF1ZXVlLnNpemUoKSk7CisgICAgICAgIGFzc2VydE51bGwocXVldWUuY29tcGFyYXRvcigpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFByaW9yaXR5UXVldWUoMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlX0xqYXZhX2xhbmdfT2JqZWN0X3VzaW5nX2NvbXBhcmF0b3IoKSB7CisgICAgICAgIFByaW9yaXR5UXVldWU8U3RyaW5nPiBxdWV1ZSA9IG5ldyBQcmlvcml0eVF1ZXVlPFN0cmluZz4oMTAsCisgICAgICAgICAgICAgICAgbmV3IE1vY2tDb21wYXJhdG9yU3RyaW5nQnlMZW5ndGgoKSk7CisgICAgICAgIFN0cmluZ1tdIGFycmF5ID0geyAiQUFBQUEiLCAiQUEiLCAiQUFBQSIsICJBQUFBQUFBQSIgfTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgcXVldWUub2ZmZXIoYXJyYXlbaV0pOworICAgICAgICB9CisgICAgICAgIGFzc2VydEZhbHNlKHF1ZXVlLmNvbnRhaW5zKCJCQiIpKTsKKyAgICAgICAgLy8gRXZlbiB0aG91Z2ggIkJCIiBpcyBlcXVpdmFsZW50IHRvICJBQSIgdXNpbmcgdGhlIHN0cmluZyBsZW5ndGggY29tcGFyYXRvciwgcmVtb3ZlKCkKKyAgICAgICAgLy8gdXNlcyBlcXVhbHMoKSwgc28gb25seSAiQUEiIHN1Y2NlZWRzIGluIHJlbW92aW5nIGVsZW1lbnQgIkFBIi4KKyAgICAgICAgYXNzZXJ0RmFsc2UocXVldWUucmVtb3ZlKCJCQiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShxdWV1ZS5yZW1vdmUoIkFBIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlX0xqYXZhX2xhbmdfT2JqZWN0X25vdF9leGlzdHMoKSB7CisgICAgICAgIEludGVnZXJbXSBhcnJheSA9IHsgMiwgNDUsIDcsIC0xMiwgOSwgMjMsIDE3LCAxMTE4LCAxMCwgMTYsIDM5IH07CisgICAgICAgIExpc3Q8SW50ZWdlcj4gbGlzdCA9IEFycmF5cy5hc0xpc3QoYXJyYXkpOworICAgICAgICBQcmlvcml0eVF1ZXVlPEludGVnZXI+IGludGVnZXJRdWV1ZSA9IG5ldyBQcmlvcml0eVF1ZXVlPEludGVnZXI+KGxpc3QpOworICAgICAgICBhc3NlcnRGYWxzZShpbnRlZ2VyUXVldWUucmVtb3ZlKDExMSkpOworICAgICAgICBhc3NlcnRGYWxzZShpbnRlZ2VyUXVldWUucmVtb3ZlKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoaW50ZWdlclF1ZXVlLnJlbW92ZSgiIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU2VyaWFsaXphdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBJbnRlZ2VyW10gYXJyYXkgPSB7IDIsIDQ1LCA3LCAtMTIsIDksIDIzLCAxNywgMTExOCwgMTAsIDE2LCAzOSB9OworICAgICAgICBMaXN0PEludGVnZXI+IGxpc3QgPSBBcnJheXMuYXNMaXN0KGFycmF5KTsKKyAgICAgICAgUHJpb3JpdHlRdWV1ZTxJbnRlZ2VyPiBzcmNJbnRlZ2VyUXVldWUgPSBuZXcgUHJpb3JpdHlRdWV1ZTxJbnRlZ2VyPihsaXN0KTsKKyAgICAgICAgUHJpb3JpdHlRdWV1ZTxJbnRlZ2VyPiBkZXN0SW50ZWdlclF1ZXVlID0gU2VyaWFsaXphdGlvblRlc3Rlci5nZXREZXNlcmlhbGl6ZWRPYmplY3Qoc3JjSW50ZWdlclF1ZXVlKTsKKyAgICAgICAgQXJyYXlzLnNvcnQoYXJyYXkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYXJyYXlbaV0sIGRlc3RJbnRlZ2VyUXVldWUucG9sbCgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZGVzdEludGVnZXJRdWV1ZS5zaXplKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU2VyaWFsaXphdGlvbl9jYXN0aW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEludGVnZXJbXSBhcnJheSA9IHsgMiwgNDUsIDcsIC0xMiwgOSwgMjMsIDE3LCAxMTE4LCAxMCwgMTYsIDM5IH07CisgICAgICAgIExpc3Q8SW50ZWdlcj4gbGlzdCA9IEFycmF5cy5hc0xpc3QoYXJyYXkpOworICAgICAgICBQcmlvcml0eVF1ZXVlPEludGVnZXI+IHNyY0ludGVnZXJRdWV1ZSA9IG5ldyBQcmlvcml0eVF1ZXVlPEludGVnZXI+KGxpc3QpOworICAgICAgICBPYmplY3QgZG9kZ3kgPSBTZXJpYWxpemF0aW9uVGVzdGVyLmdldERlc2VyaWFsaXplZE9iamVjdCgoT2JqZWN0KSBzcmNJbnRlZ2VyUXVldWUpOworICAgICAgICBQcmlvcml0eVF1ZXVlPFN0cmluZz4gZGVzdFN0cmluZ1F1ZXVlID0gKFByaW9yaXR5UXVldWU8U3RyaW5nPikgZG9kZ3k7CisgICAgICAgIC8vIHdpbGwgbm90IGluY3VyIGNsYXNzIGNhc3QgZXhjZXB0aW9uLgorICAgICAgICBPYmplY3QgbyA9IGRlc3RTdHJpbmdRdWV1ZS5wZWVrKCk7CisgICAgICAgIEFycmF5cy5zb3J0KGFycmF5KTsKKyAgICAgICAgSW50ZWdlciBJID0gKEludGVnZXIpIG87CisgICAgICAgIGFzc2VydEVxdWFscyhhcnJheVswXSwgSSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TZXJpYWxpemF0aW9uQ29tcGF0aWJpbGl0eV9jYXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEludGVnZXJbXSBhcnJheSA9IHsgMiwgNDUsIDcsIC0xMiwgOSwgMjMsIDE3LCAxMTE4LCAxMCwgMTYsIDM5IH07CisgICAgICAgIExpc3Q8SW50ZWdlcj4gbGlzdCA9IEFycmF5cy5hc0xpc3QoYXJyYXkpOworICAgICAgICBQcmlvcml0eVF1ZXVlPEludGVnZXI+IHNyY0ludGVnZXJRdWV1ZSA9IG5ldyBQcmlvcml0eVF1ZXVlPEludGVnZXI+KAorICAgICAgICAgICAgICAgIGxpc3QpOworICAgICAgICBQcmlvcml0eVF1ZXVlPFN0cmluZz4gZGVzdFN0cmluZ1F1ZXVlID0gKFByaW9yaXR5UXVldWU8U3RyaW5nPikgU2VyaWFsaXphdGlvblRlc3RlcgorICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KHNyY0ludGVnZXJRdWV1ZSwgU0VSSUFMSVpBVElPTl9GSUxFX05BTUUpOworCisgICAgICAgIC8vIHdpbGwgbm90IGluY3VyIGNsYXNzIGNhc3QgZXhjZXB0aW9uLgorICAgICAgICBPYmplY3QgbyA9IGRlc3RTdHJpbmdRdWV1ZS5wZWVrKCk7CisgICAgICAgIEFycmF5cy5zb3J0KGFycmF5KTsKKyAgICAgICAgSW50ZWdlciBJID0gKEludGVnZXIpIG87CisgICAgICAgIGFzc2VydEVxdWFscyhhcnJheVswXSwgSSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTW9ja0NvbXBhcmF0b3JTdHJpbmdCeUxlbmd0aCBpbXBsZW1lbnRzCisgICAgICAgICAgICBDb21wYXJhdG9yPFN0cmluZz4geworCisgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShTdHJpbmcgb2JqZWN0MSwgU3RyaW5nIG9iamVjdDIpIHsKKyAgICAgICAgICAgIGludCBsZW5ndGgxID0gb2JqZWN0MS5sZW5ndGgoKTsKKyAgICAgICAgICAgIGludCBsZW5ndGgyID0gb2JqZWN0Mi5sZW5ndGgoKTsKKyAgICAgICAgICAgIGlmIChsZW5ndGgxID4gbGVuZ3RoMikgeworICAgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgICAgfSBlbHNlIGlmIChsZW5ndGgxID09IGxlbmd0aDIpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBNb2NrQ29tcGFyYXRvckNhc3Q8RT4gaW1wbGVtZW50cyBDb21wYXJhdG9yPEU+IHsKKworICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoRSBvYmplY3QxLCBFIG9iamVjdDIpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkU2Nhbm5lclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRTY2FubmVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI1MWNmYmMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkU2Nhbm5lclRlc3QuamF2YQpAQCAtMCwwICsxLDU1OSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOworaW1wb3J0IGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmlvLkNoYXJCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5TZXJ2ZXJTb2NrZXRDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNvY2tldENoYW5uZWw7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuU2Nhbm5lcjsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguTWF0Y2hSZXN1bHQ7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm47CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Qb3J0TWFuYWdlcjsKKworcHVibGljIGZpbmFsIGNsYXNzIE9sZFNjYW5uZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBTY2FubmVyIHM7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ZpbmRXaXRoaW5Ib3Jpem9uX0xqYXZhX2xhbmdfU3RyaW5nSSgpIHsKKyAgICAgICAgLy8gVGhpcyBtZXRob2Qgc2VhcmNoZXMgdGhyb3VnaCB0aGUgaW5wdXQgdXAgdG8gdGhlIHNwZWNpZmllZCBzZWFyY2gKKyAgICAgICAgLy8gaG9yaXpvbihleGNsdXNpdmUpLgorICAgICAgICBzID0gbmV3IFNjYW5uZXIoIjEyM3Rlc3QiKTsKKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IHMuZmluZFdpdGhpbkhvcml6b24oIlxccHtMb3dlcn0iLCA1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0IiwgcmVzdWx0KTsKKyAgICAgICAgTWF0Y2hSZXN1bHQgbXJlc3VsdCA9IHMubWF0Y2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIG1yZXN1bHQuc3RhcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg0LCBtcmVzdWx0LmVuZCgpKTsKKworICAgICAgICBzID0gbmV3IFNjYW5uZXIoIjEyMzQ1dGVzdDEyMzR0ZXN0IG5leHQiKTsKKyAgICAgICAgLyoKKyAgICAgICAgICogSWYgdGhlIHBhdHRlcm4gaXMgZm91bmQgdGhlIHNjYW5uZXIgYWR2YW5jZXMgcGFzdCB0aGUgaW5wdXQgdGhhdAorICAgICAgICAgKiBtYXRjaGVkIGFuZCByZXR1cm5zIHRoZSBzdHJpbmcgdGhhdCBtYXRjaGVkIHRoZSBwYXR0ZXJuLgorICAgICAgICAgKi8KKyAgICAgICAgcmVzdWx0ID0gcy5maW5kV2l0aGluSG9yaXpvbigiXFxwe0RpZ2l0fSsiLCAyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMiIsIHJlc3VsdCk7CisgICAgICAgIG1yZXN1bHQgPSBzLm1hdGNoKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBtcmVzdWx0LnN0YXJ0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgbXJlc3VsdC5lbmQoKSk7CisgICAgICAgIC8vIFBvc2l0aW9uIGlzIG5vdyBwb2ludGluZyBhdCB0aGUgYmFyLiAiMTJ8MzQ1dGVzdDEyMzR0ZXN0IG5leHQiCisKKyAgICAgICAgcmVzdWx0ID0gcy5maW5kV2l0aGluSG9yaXpvbigiXFxwe0RpZ2l0fSsiLCA2KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIzNDUiLCByZXN1bHQpOworCisgICAgICAgIG1yZXN1bHQgPSBzLm1hdGNoKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBtcmVzdWx0LnN0YXJ0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgbXJlc3VsdC5lbmQoKSk7CisgICAgICAgIC8vIFBvc2l0aW9uIGlzIG5vdyBwb2ludGluZyBhdCB0aGUgYmFyLiAiMTIzNDV8dGVzdDEyMzR0ZXN0IG5leHQiCisKKyAgICAgICAgLy8gSWYgbm8gc3VjaCBwYXR0ZXJuIGlzIGRldGVjdGVkIHRoZW4gdGhlIG51bGwgaXMgcmV0dXJuZWQgYW5kIHRoZQorICAgICAgICAvLyBzY2FubmVyJ3MgcG9zaXRpb24gcmVtYWlucyB1bmNoYW5nZWQuCisgICAgICAgIHJlc3VsdCA9IHMuZmluZFdpdGhpbkhvcml6b24oIlxccHtEaWdpdH0rIiwgMyk7CisgICAgICAgIGFzc2VydE51bGwocmVzdWx0KTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5tYXRjaCgpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIjM0NSIsIG1yZXN1bHQuZ3JvdXAoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBtcmVzdWx0LnN0YXJ0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgbXJlc3VsdC5lbmQoKSk7CisgICAgICAgIC8vIFBvc2l0aW9uIGlzIG5vdyBzdGlsbCBwb2ludGluZyBhdCB0aGUgYmFyLiAiMTIzNDV8dGVzdDEyMzR0ZXN0IG5leHQiCisKKyAgICAgICAgLy8gSWYgaG9yaXpvbiBpcyAwLCB0aGVuIHRoZSBob3Jpem9uIGlzIGlnbm9yZWQgYW5kIHRoaXMgbWV0aG9kCisgICAgICAgIC8vIGNvbnRpbnVlcyB0byBzZWFyY2ggdGhyb3VnaCB0aGUgaW5wdXQgbG9va2luZyBmb3IgdGhlIHNwZWNpZmllZAorICAgICAgICAvLyBwYXR0ZXJuIHdpdGhvdXQgYm91bmQuCisgICAgICAgIHJlc3VsdCA9IHMuZmluZFdpdGhpbkhvcml6b24oIlxccHtEaWdpdH0rIiwgMCk7CisgICAgICAgIG1yZXN1bHQgPSBzLm1hdGNoKCk7CisgICAgICAgIGFzc2VydEVxdWFscyg5LCBtcmVzdWx0LnN0YXJ0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTMsIG1yZXN1bHQuZW5kKCkpOworICAgICAgICAvLyBQb3NpdGlvbiBpcyBub3cgcG9pbnRpbmcgYXQgdGhlIGJhci4gIjEyMzQ1dGVzdDEyMzR8dGVzdCBuZXh0IgorCisgICAgICAgIGFzc2VydEVxdWFscygidGVzdCIsIHMubmV4dCgpKTsKKyAgICAgICAgbXJlc3VsdCA9IHMubWF0Y2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEzLCBtcmVzdWx0LnN0YXJ0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTcsIG1yZXN1bHQuZW5kKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygibmV4dCIsIHMubmV4dCgpKTsKKyAgICAgICAgbXJlc3VsdCA9IHMubWF0Y2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDE4LCBtcmVzdWx0LnN0YXJ0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMjIsIG1yZXN1bHQuZW5kKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmZpbmRXaXRoaW5Ib3Jpem9uKChTdHJpbmcpbnVsbCwgMSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmZpbmRXaXRoaW5Ib3Jpem9uKCJcXHB7RGlnaXR9KyIsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgIC8vIG9uIFJJIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAgICAvKgorICAgICAgICAgKiB0cnkgeyBTeXN0ZW0ub3V0LnByaW50bG4oImZzZGZzIik7IHMuZmluZFdpdGhpbkhvcml6b24oKFN0cmluZykgbnVsbCwKKyAgICAgICAgICogLTEpOyBTeXN0ZW0ub3V0LnByaW50bG4oImZzZGZzIik7IGZhaWwoIlNob3VsZCB0aHJvdworICAgICAgICAgKiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsgLy8KKyAgICAgICAgICogZXhwZWN0ZWQgfQorICAgICAgICAgKi8KKyAgICAgICAgcyA9IG5ldyBTY2FubmVyKCJ0ZXN0Iik7CisgICAgICAgIHJlc3VsdCA9IHMuZmluZFdpdGhpbkhvcml6b24oIlxcdysiLCAxMCk7CisgICAgICAgIGFzc2VydEVxdWFscygidGVzdCIsIHJlc3VsdCk7CisKKyAgICAgICAgcyA9IG5ldyBTY2FubmVyKCJhYVxuXHJiIik7CisgICAgICAgIFN0cmluZyBwYXR0ZXJuU3RyID0gIl4oYSkkIjsKKyAgICAgICAgcmVzdWx0ID0gcy5maW5kV2l0aGluSG9yaXpvbigiYSIsIDUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCByZXN1bHQpOworICAgICAgICBtcmVzdWx0ID0gcy5tYXRjaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbXJlc3VsdC5zdGFydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG1yZXN1bHQuZW5kKCkpOworCisgICAgICAgIHJlc3VsdCA9IHMuZmluZFdpdGhpbkhvcml6b24ocGF0dGVyblN0ciwgNSk7CisgICAgICAgIGFzc2VydE51bGwocmVzdWx0KTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXJlc3VsdCA9IHMubWF0Y2goKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBzID0gbmV3IFNjYW5uZXIoIiIpOworICAgICAgICByZXN1bHQgPSBzLmZpbmRXaXRoaW5Ib3Jpem9uKCJeIiwgMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgcmVzdWx0KTsKKyAgICAgICAgTWF0Y2hSZXN1bHQgbWF0Y2hSZXN1bHQgPSBzLm1hdGNoKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBtYXRjaFJlc3VsdC5zdGFydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG1hdGNoUmVzdWx0LmVuZCgpKTsKKworICAgICAgICByZXN1bHQgPSBzLmZpbmRXaXRoaW5Ib3Jpem9uKCIkIiwgMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgcmVzdWx0KTsKKyAgICAgICAgbWF0Y2hSZXN1bHQgPSBzLm1hdGNoKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBtYXRjaFJlc3VsdC5zdGFydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG1hdGNoUmVzdWx0LmVuZCgpKTsKKworICAgICAgICBzID0gbmV3IFNjYW5uZXIoIjEgZmlzaCAyIGZpc2ggcmVkIGZpc2ggYmx1ZSBmaXNoIik7CisgICAgICAgIHJlc3VsdCA9IHMuZmluZFdpdGhpbkhvcml6b24oIihcXGQrKSBmaXNoIChcXGQrKSBmaXNoIChcXHcrKSBmaXNoIChcXHcrKSIsIDEwKTsKKyAgICAgICAgYXNzZXJ0TnVsbChyZXN1bHQpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtcmVzdWx0ID0gcy5tYXRjaCgpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbXJlc3VsdC5ncm91cENvdW50KCkpOworCisgICAgICAgIHJlc3VsdCA9IHMuZmluZFdpdGhpbkhvcml6b24oIihcXGQrKSBmaXNoIChcXGQrKSBmaXNoIChcXHcrKSBmaXNoIChcXHcrKSIsIDEwMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiMSBmaXNoIDIgZmlzaCByZWQgZmlzaCBibHVlIiwgcmVzdWx0KTsKKyAgICAgICAgbXJlc3VsdCA9IHMubWF0Y2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIG1yZXN1bHQuZ3JvdXBDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxIiwgbXJlc3VsdC5ncm91cCgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMiIsIG1yZXN1bHQuZ3JvdXAoMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoInJlZCIsIG1yZXN1bHQuZ3JvdXAoMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJsdWUiLCBtcmVzdWx0Lmdyb3VwKDQpKTsKKworICAgICAgICBzID0gbmV3IFNjYW5uZXIoInRlc3QiKTsKKyAgICAgICAgcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5maW5kV2l0aGluSG9yaXpvbigidGVzdCIsIDEpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHMgPSBuZXcgU2Nhbm5lcigid29yZDEgV29yRDIgICIpOworICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmZpbmRXaXRoaW5Ib3Jpem9uKCJcXGQrIiwgMTApOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHMgPSBuZXcgU2Nhbm5lcigid29yZDEgV29yRDIgd09yZDMgIik7CisgICAgICAgIHBhdHRlcm5TdHIgPSAiXFxkKyI7CisgICAgICAgIGFzc2VydEVxdWFscygiMSIsIHMuZmluZFdpdGhpbkhvcml6b24ocGF0dGVyblN0ciwgMTApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXb3JEMiIsIHMubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIzIiwgcy5maW5kV2l0aGluSG9yaXpvbihwYXR0ZXJuU3RyLCAxNSkpOworCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gdGVzdAorICAgICAgICBzID0gbmV3IFNjYW5uZXIobmV3IE1vY2tTdHJpbmdSZWFkZXIoIk1vY2tTdHJpbmdSZWFkZXIiKSk7CisgICAgICAgIHBhdHRlcm5TdHIgPSAidGVzdCI7CisgICAgICAgIHJlc3VsdCA9IHMuZmluZFdpdGhpbkhvcml6b24ocGF0dGVyblN0ciwgMTApOworICAgICAgICBhc3NlcnRFcXVhbHMoInRlc3QiLCByZXN1bHQpOworCisgICAgICAgIC8vIFRlc3QgdGhlIHNpdHVhdGlvbiB3aGVuIGlucHV0IGxlbmd0aCBpcyBsb25nZXIgdGhhbiBidWZmZXIgc2l6ZS4KKyAgICAgICAgU3RyaW5nQnVpbGRlciBzdHJpbmdCdWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDI2OyBpKyspIHsKKyAgICAgICAgICAgIHN0cmluZ0J1aWxkZXIuYXBwZW5kKCdhJyk7CisgICAgICAgIH0KKyAgICAgICAgcyA9IG5ldyBTY2FubmVyKHN0cmluZ0J1aWxkZXIudG9TdHJpbmcoKSk7CisgICAgICAgIHBhdHRlcm5TdHIgPSAiXFxwe0xvd2VyfSsiOworICAgICAgICByZXN1bHQgPSBzLmZpbmRXaXRoaW5Ib3Jpem9uKHBhdHRlcm5TdHIsIDEwMjYpOworICAgICAgICBhc3NlcnRFcXVhbHMoc3RyaW5nQnVpbGRlci50b1N0cmluZygpLCByZXN1bHQpOworCisgICAgICAgIC8vIFRlc3QgdGhlIHNpdHVhdGlvbiB3aGVuIGlucHV0IGxlbmd0aCBpcyBsb25nZXIgdGhhbiBidWZmZXIgc2l6ZSBhbmQKKyAgICAgICAgLy8gc2V0IGhvcml6b24gdG8gYnVmZmVyIHNpemUuCisgICAgICAgIHN0cmluZ0J1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMjY7IGkrKykgeworICAgICAgICAgICAgc3RyaW5nQnVpbGRlci5hcHBlbmQoJ2EnKTsKKyAgICAgICAgfQorICAgICAgICBzID0gbmV3IFNjYW5uZXIoc3RyaW5nQnVpbGRlci50b1N0cmluZygpKTsKKyAgICAgICAgcGF0dGVyblN0ciA9ICJcXHB7TG93ZXJ9KyI7CisgICAgICAgIHJlc3VsdCA9IHMuZmluZFdpdGhpbkhvcml6b24ocGF0dGVyblN0ciwgMTAyMik7CisgICAgICAgIGFzc2VydEVxdWFscygxMDIyLCByZXN1bHQubGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoc3RyaW5nQnVpbGRlci5zdWJTZXF1ZW5jZSgwLCAxMDIyKSwgcmVzdWx0KTsKKworICAgICAgICAvLyBUZXN0IHRoZSBzaXR1YXRpb24sIHVuZGVyIHdoaWNoIHBhdHRlcm4gaXMgY2xpcHBlZCBieSBidWZmZXIuCisgICAgICAgIHN0cmluZ0J1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMjI7IGkrKykgeworICAgICAgICAgICAgc3RyaW5nQnVpbGRlci5hcHBlbmQoJyAnKTsKKyAgICAgICAgfQorICAgICAgICBzdHJpbmdCdWlsZGVyLmFwcGVuZCgiYmJjIik7CisgICAgICAgIGFzc2VydEVxdWFscygxMDI1LCBzdHJpbmdCdWlsZGVyLmxlbmd0aCgpKTsKKyAgICAgICAgcyA9IG5ldyBTY2FubmVyKHN0cmluZ0J1aWxkZXIudG9TdHJpbmcoKSk7CisgICAgICAgIHBhdHRlcm5TdHIgPSAiYmJjIjsKKyAgICAgICAgcmVzdWx0ID0gcy5maW5kV2l0aGluSG9yaXpvbihwYXR0ZXJuU3RyLCAxMDI1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHJlc3VsdC5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzdHJpbmdCdWlsZGVyLnN1YlNlcXVlbmNlKDEwMjIsIDEwMjUpLCByZXN1bHQpOworCisgICAgICAgIHN0cmluZ0J1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMjY7IGkrKykgeworICAgICAgICAgICAgc3RyaW5nQnVpbGRlci5hcHBlbmQoJ2EnKTsKKyAgICAgICAgfQorICAgICAgICBzID0gbmV3IFNjYW5uZXIoc3RyaW5nQnVpbGRlci50b1N0cmluZygpKTsKKyAgICAgICAgcGF0dGVyblN0ciA9ICJcXHB7TG93ZXJ9KyI7CisgICAgICAgIHJlc3VsdCA9IHMuZmluZFdpdGhpbkhvcml6b24ocGF0dGVyblN0ciwgMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhzdHJpbmdCdWlsZGVyLnRvU3RyaW5nKCksIHJlc3VsdCk7CisKKyAgICAgICAgc3RyaW5nQnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAyNDA7IGkrKykgeworICAgICAgICAgICAgc3RyaW5nQnVpbGRlci5hcHBlbmQoJy0nKTsKKyAgICAgICAgfQorICAgICAgICBzdHJpbmdCdWlsZGVyLnJlcGxhY2UoMCwgMiwgImFhIik7CisgICAgICAgIHMgPSBuZXcgU2Nhbm5lcihzdHJpbmdCdWlsZGVyLnRvU3RyaW5nKCkpOworICAgICAgICByZXN1bHQgPSBzLmZpbmRXaXRoaW5Ib3Jpem9uKCJhYSIsIDApOworICAgICAgICBhc3NlcnRFcXVhbHMoImFhIiwgcmVzdWx0KTsKKworICAgICAgICBzID0gbmV3IFNjYW5uZXIoImFhYWEiKTsKKyAgICAgICAgcmVzdWx0ID0gcy5maW5kV2l0aGluSG9yaXpvbigiYSoiLCAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhYWFhIiwgcmVzdWx0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ZpbmRJbkxpbmVfTFN0cmluZygpIHsKKyAgICAgICAgcyA9IG5ldyBTY2FubmVyKCJ0ZXN0Iik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmZpbmRJbkxpbmUoKFN0cmluZykgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHMuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMuZmluZEluTGluZSgoU3RyaW5nKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmZpbmRJbkxpbmUoInRlc3QiKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cHRlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcyA9IG5ldyBTY2FubmVyKCIiKTsKKworICAgICAgICBTdHJpbmcgcmVzdWx0ID0gcy5maW5kSW5MaW5lKCJeIik7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgcmVzdWx0KTsKKyAgICAgICAgTWF0Y2hSZXN1bHQgbWF0Y2hSZXN1bHQgPSBzLm1hdGNoKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBtYXRjaFJlc3VsdC5zdGFydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG1hdGNoUmVzdWx0LmVuZCgpKTsKKworICAgICAgICByZXN1bHQgPSBzLmZpbmRJbkxpbmUoIiQiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCByZXN1bHQpOworICAgICAgICBtYXRjaFJlc3VsdCA9IHMubWF0Y2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG1hdGNoUmVzdWx0LnN0YXJ0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbWF0Y2hSZXN1bHQuZW5kKCkpOworCisgICAgICAgIC8qCisgICAgICAgICAqIFdoZW4gd2UgdXNlIHRoZSBvcGVyYXRpb24gb2YgZmluZEluTGluZShQYXR0ZXJuKSwgdGhlIG1hdGNoIHJlZ2lvbgorICAgICAgICAgKiBzaG91bGQgbm90IHNwYW4gdGhlIGxpbmUgc2VwYXJhdG9yLgorICAgICAgICAgKi8KKyAgICAgICAgcyA9IG5ldyBTY2FubmVyKCJhYVxuYi5iIik7CisgICAgICAgIHJlc3VsdCA9IHMuZmluZEluTGluZSgiYVxuYioiKTsKKyAgICAgICAgYXNzZXJ0TnVsbChyZXN1bHQpOworCisgICAgICAgIHMgPSBuZXcgU2Nhbm5lcigiYWFcbmJiLmIiKTsKKyAgICAgICAgcmVzdWx0ID0gcy5maW5kSW5MaW5lKCJcXC4iKTsKKyAgICAgICAgYXNzZXJ0TnVsbChyZXN1bHQpOworCisgICAgICAgIHMgPSBuZXcgU2Nhbm5lcigiYWJjZDEyMzR0ZXN0XG4iKTsKKyAgICAgICAgcmVzdWx0ID0gcy5maW5kSW5MaW5lKCJcXHB7TG93ZXJ9KyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFiY2QiLCByZXN1bHQpOworICAgICAgICBtYXRjaFJlc3VsdCA9IHMubWF0Y2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG1hdGNoUmVzdWx0LnN0YXJ0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgbWF0Y2hSZXN1bHQuZW5kKCkpOworCisgICAgICAgIHJlc3VsdCA9IHMuZmluZEluTGluZSgiXFxwe0RpZ2l0fXs1fSIpOworICAgICAgICBhc3NlcnROdWxsKHJlc3VsdCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtYXRjaFJlc3VsdCA9IHMubWF0Y2goKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG1hdGNoUmVzdWx0LnN0YXJ0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgbWF0Y2hSZXN1bHQuZW5kKCkpOworCisgICAgICAgIHJlc3VsdCA9IHMuZmluZEluTGluZSgiXFxwe0xvd2VyfSsiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXN0IiwgcmVzdWx0KTsKKyAgICAgICAgbWF0Y2hSZXN1bHQgPSBzLm1hdGNoKCk7CisgICAgICAgIGFzc2VydEVxdWFscyg4LCBtYXRjaFJlc3VsdC5zdGFydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEyLCBtYXRjaFJlc3VsdC5lbmQoKSk7CisKKyAgICAgICAgY2hhcltdIGNoYXJzID0gbmV3IGNoYXJbMjA0OF07CisgICAgICAgIEFycmF5cy5maWxsKGNoYXJzLCAnYScpOworICAgICAgICBTdHJpbmdCdWlsZGVyIHN0cmluZ0J1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBzdHJpbmdCdWlsZGVyLmFwcGVuZChjaGFycyk7CisgICAgICAgIHN0cmluZ0J1aWxkZXIuYXBwZW5kKCIxMjM0Iik7CisgICAgICAgIHMgPSBuZXcgU2Nhbm5lcihzdHJpbmdCdWlsZGVyLnRvU3RyaW5nKCkpOworICAgICAgICByZXN1bHQgPSBzLmZpbmRJbkxpbmUoIlxccHtEaWdpdH0rIik7CisgICAgICAgIGFzc2VydEVxdWFscygiMTIzNCIsIHJlc3VsdCk7CisgICAgICAgIG1hdGNoUmVzdWx0ID0gcy5tYXRjaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMjA0OCwgbWF0Y2hSZXN1bHQuc3RhcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyMDUyLCBtYXRjaFJlc3VsdC5lbmQoKSk7CisKKyAgICAgICAgcyA9IG5ldyBTY2FubmVyKCJ0ZXN0MTIzNFxuMTIzNCB0ZXN0Iik7CisgICAgICAgIHJlc3VsdCA9IHMuZmluZEluTGluZSgidGVzdCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRlc3QiLCByZXN1bHQpOworICAgICAgICBtYXRjaFJlc3VsdCA9IHMubWF0Y2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG1hdGNoUmVzdWx0LnN0YXJ0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgbWF0Y2hSZXN1bHQuZW5kKCkpOworCisgICAgICAgIGludCBudW1iZXIgPSBzLm5leHRJbnQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEyMzQsIG51bWJlcik7CisgICAgICAgIG1hdGNoUmVzdWx0ID0gcy5tYXRjaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgbWF0Y2hSZXN1bHQuc3RhcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg4LCBtYXRjaFJlc3VsdC5lbmQoKSk7CisKKyAgICAgICAgcmVzdWx0ID0gcy5uZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTIzNCIsIHJlc3VsdCk7CisgICAgICAgIG1hdGNoUmVzdWx0ID0gcy5tYXRjaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoOSwgbWF0Y2hSZXN1bHQuc3RhcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMywgbWF0Y2hSZXN1bHQuZW5kKCkpOworCisgICAgICAgIHJlc3VsdCA9IHMuZmluZEluTGluZSgidGVzdCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRlc3QiLCByZXN1bHQpOworICAgICAgICBtYXRjaFJlc3VsdCA9IHMubWF0Y2goKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDE0LCBtYXRjaFJlc3VsdC5zdGFydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDE4LCBtYXRjaFJlc3VsdC5lbmQoKSk7CisKKyAgICAgICAgcyA9IG5ldyBTY2FubmVyKCJ0ZXN0XHUwMDg1XG50ZXN0Iik7CisgICAgICAgIHJlc3VsdCA9IHMuZmluZEluTGluZSgiZXN0Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiZXN0IiwgcmVzdWx0KTsKKyAgICAgICAgcmVzdWx0ID0gcy5maW5kSW5MaW5lKCJlc3QiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlc3QiLCByZXN1bHQpOworCisgICAgICAgIHMgPSBuZXcgU2Nhbm5lcigidGVzdFxudGVzdCIpOworICAgICAgICByZXN1bHQgPSBzLmZpbmRJbkxpbmUoImVzdCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVzdCIsIHJlc3VsdCk7CisgICAgICAgIHJlc3VsdCA9IHMuZmluZEluTGluZSgiZXN0Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiZXN0IiwgcmVzdWx0KTsKKworICAgICAgICBzID0gbmV3IFNjYW5uZXIoInRlc3RcbjEyM1xudGVzdCIpOworICAgICAgICByZXN1bHQgPSBzLmZpbmRJbkxpbmUoImVzdCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVzdCIsIHJlc3VsdCk7CisgICAgICAgIHJlc3VsdCA9IHMuZmluZEluTGluZSgiZXN0Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9za2lwX0xQYXR0ZXJuKCkgeworICAgICAgICBzID0gbmV3IFNjYW5uZXIoInRlc3QiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMuc2tpcCgoU3RyaW5nKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gSWYgcGF0dGVybiBkb2VzIG5vdCBtYXRjaCwgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiB3aWxsIGJlIHRocm93biBvdXQuCisgICAgICAgIHMgPSBuZXcgU2Nhbm5lcigiMTIzNCIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5za2lwKFBhdHRlcm4uY29tcGlsZSgiXFxwe0xvd2VyfSIpKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICAvLyBUaGVuLCBubyBtYXRjaFJlc3VsdCB3aWxsIGJlIHRocm93biBvdXQuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLm1hdGNoKCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcy5za2lwKFBhdHRlcm4uY29tcGlsZSgiXFxwe0RpZ2l0fSIpKTsKKyAgICAgICAgTWF0Y2hSZXN1bHQgbWF0Y2hSZXN1bHQgPSBzLm1hdGNoKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBtYXRjaFJlc3VsdC5zdGFydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG1hdGNoUmVzdWx0LmVuZCgpKTsKKworICAgICAgICBzLnNraXAoUGF0dGVybi5jb21waWxlKCJcXHB7RGlnaXR9KyIpKTsKKyAgICAgICAgbWF0Y2hSZXN1bHQgPSBzLm1hdGNoKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBtYXRjaFJlc3VsdC5zdGFydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIG1hdGNoUmVzdWx0LmVuZCgpKTsKKworICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLnNraXAoUGF0dGVybi5jb21waWxlKCJ0ZXN0IikpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIE1vY2tTdHJpbmdSZWFkZXIyUmVhZCByZWFkZXIgPSBuZXcgTW9ja1N0cmluZ1JlYWRlcjJSZWFkKCJ0ZXN0Iik7CisgICAgICAgIHMgPSBuZXcgU2Nhbm5lcihyZWFkZXIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5za2lwKFBhdHRlcm4uY29tcGlsZSgiXFxwe0RpZ2l0fXs0fSIpKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5tYXRjaCgpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBzLnNraXAoUGF0dGVybi5jb21waWxlKCJcXHB7RGlnaXR9ezN9XFxwe0xvd2VyfSIpKTsKKyAgICAgICAgbWF0Y2hSZXN1bHQgPSBzLm1hdGNoKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBtYXRjaFJlc3VsdC5zdGFydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIG1hdGNoUmVzdWx0LmVuZCgpKTsKKworICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLnNraXAoKFBhdHRlcm4pIG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ0J1aWxkZXIgc3RyaW5nQnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGNoYXIgW10gY2hhcnMgPSBuZXcgY2hhclsxMDI0XTsKKyAgICAgICAgQXJyYXlzLmZpbGwoY2hhcnMsICdhJyk7CisgICAgICAgIHN0cmluZ0J1aWxkZXIuYXBwZW5kKGNoYXJzKTsKKyAgICAgICAgc3RyaW5nQnVpbGRlci5hcHBlbmQoJzMnKTsKKyAgICAgICAgcyA9IG5ldyBTY2FubmVyKHN0cmluZ0J1aWxkZXIudG9TdHJpbmcoKSk7CisgICAgICAgIHMuc2tpcChQYXR0ZXJuLmNvbXBpbGUoIlxccHtMb3dlcn0rXFxwe0RpZ2l0fSIpKTsKKyAgICAgICAgbWF0Y2hSZXN1bHQgPSBzLm1hdGNoKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBtYXRjaFJlc3VsdC5zdGFydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEwMjUsIG1hdGNoUmVzdWx0LmVuZCgpKTsKKworICAgICAgICAvLyBMYXJnZSBhbW91bnQgb2YgaW5wdXQgbWF5IGJlIGNhY2hlZAorICAgICAgICBjaGFycyA9IG5ldyBjaGFyWzEwMjQwMF07CisgICAgICAgIEFycmF5cy5maWxsKGNoYXJzLCAnYScpOworICAgICAgICBzdHJpbmdCdWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgc3RyaW5nQnVpbGRlci5hcHBlbmQoY2hhcnMpOworICAgICAgICBzID0gbmV3IFNjYW5uZXIoc3RyaW5nQnVpbGRlci50b1N0cmluZygpKTsKKyAgICAgICAgcy5za2lwKFBhdHRlcm4uY29tcGlsZSgiLioiKSk7CisgICAgICAgIG1hdGNoUmVzdWx0ID0gcy5tYXRjaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbWF0Y2hSZXN1bHQuc3RhcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMDI0MDAsIG1hdGNoUmVzdWx0LmVuZCgpKTsKKworICAgICAgICAvLyBza2lwIHNvbWV0aGluZyB3aXRob3V0IHJpc2tpbmcgYSBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uCisgICAgICAgIHMuc2tpcChQYXR0ZXJuLmNvbXBpbGUoIlsgXHRdKiIpKTsKKyAgICAgICAgbWF0Y2hSZXN1bHQgPSBzLm1hdGNoKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxMDI0MDAsIG1hdGNoUmVzdWx0LnN0YXJ0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTAyNDAwLCBtYXRjaFJlc3VsdC5lbmQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3Rvcl9MUmVhZGFibGVCeXRlQ2hhbm5lbCgpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBJbmV0U29ja2V0QWRkcmVzcyBsb2NhbEFkZHIgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoIjEyNy4wLjAuMSIsCisgICAgICAgICAgICAgICAgU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpKTsKKyAgICAgICAgU2VydmVyU29ja2V0Q2hhbm5lbCBzc2MgPSBTZXJ2ZXJTb2NrZXRDaGFubmVsLm9wZW4oKTsKKyAgICAgICAgc3NjLnNvY2tldCgpLmJpbmQobG9jYWxBZGRyKTsKKworICAgICAgICBTb2NrZXRDaGFubmVsIHNjID0gU29ja2V0Q2hhbm5lbC5vcGVuKCk7CisgICAgICAgIHNjLmNvbm5lY3QobG9jYWxBZGRyKTsKKyAgICAgICAgc2MuY29uZmlndXJlQmxvY2tpbmcoZmFsc2UpOworICAgICAgICBhc3NlcnRGYWxzZShzYy5pc0Jsb2NraW5nKCkpOworCisgICAgICAgIHNzYy5hY2NlcHQoKS5jbG9zZSgpOworICAgICAgICBzc2MuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2MuaXNCbG9ja2luZygpKTsKKworICAgICAgICBTY2FubmVyIHMgPSBuZXcgU2Nhbm5lcihzYyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmhhc05leHRJbnQoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgc2MuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBNb2NrU3RyaW5nUmVhZGVyIGV4dGVuZHMgU3RyaW5nUmVhZGVyIHsKKworICAgICAgICBwdWJsaWMgTW9ja1N0cmluZ1JlYWRlcihTdHJpbmcgcGFyYW0pIHsKKyAgICAgICAgICAgIHN1cGVyKHBhcmFtKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgcmVhZChDaGFyQnVmZmVyIHRhcmdldCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRhcmdldC5hcHBlbmQoJ3QnKTsKKyAgICAgICAgICAgIHRhcmdldC5hcHBlbmQoJ2UnKTsKKyAgICAgICAgICAgIHRhcmdldC5hcHBlbmQoJ3MnKTsKKyAgICAgICAgICAgIHRhcmdldC5hcHBlbmQoJ3QnKTsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTW9ja1N0cmluZ1JlYWRlcjJSZWFkIGV4dGVuZHMgU3RyaW5nUmVhZGVyIHsKKyAgICAgICAgcHJpdmF0ZSBpbnQgdGltZXNSZWFkID0gMTsKKworICAgICAgICBwdWJsaWMgTW9ja1N0cmluZ1JlYWRlcjJSZWFkKFN0cmluZyBwYXJhbSkgeworICAgICAgICAgICAgc3VwZXIocGFyYW0pOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCByZWFkKENoYXJCdWZmZXIgdGFyZ2V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaWYgKHRpbWVzUmVhZCA9PSAxKSB7CisgICAgICAgICAgICAgICAgdGFyZ2V0LmFwcGVuZCgnMScpOworICAgICAgICAgICAgICAgIHRhcmdldC5hcHBlbmQoJzInKTsKKyAgICAgICAgICAgICAgICB0YXJnZXQuYXBwZW5kKCczJyk7CisgICAgICAgICAgICAgICAgdGltZXNSZWFkKys7CisgICAgICAgICAgICAgICAgcmV0dXJuIDM7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHRpbWVzUmVhZCA9PSAyKSB7CisgICAgICAgICAgICAgICAgdGFyZ2V0LmFwcGVuZCgndCcpOworICAgICAgICAgICAgICAgIHRpbWVzUmVhZCsrOworICAgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRUaW1lWm9uZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRUaW1lWm9uZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNDA0MDNlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL09sZFRpbWVab25lVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTY0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsOworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uQW5kcm9pZE9ubHk7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Mb2NhbGU7CisKK3B1YmxpYyBjbGFzcyBPbGRUaW1lWm9uZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBjbGFzcyBNb2NrX1RpbWVab25lIGV4dGVuZHMgVGltZVpvbmUgeworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBnZXRPZmZzZXQoaW50IGVyYSwgaW50IHllYXIsIGludCBtb250aCwgaW50IGRheSwgaW50IGRheU9mV2VlaywgaW50IG1pbGxpc2Vjb25kcykgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBnZXRSYXdPZmZzZXQoKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpbkRheWxpZ2h0VGltZShEYXRlIGRhdGUpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRSYXdPZmZzZXQoaW50IG9mZnNldE1pbGxpcykgeworCisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gdXNlRGF5bGlnaHRUaW1lKCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25zdHJ1Y3RvcigpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXcgTW9ja19UaW1lWm9uZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb25lKCkgeworICAgICAgICBUaW1lWm9uZSB0ejEgPSBUaW1lWm9uZS5nZXREZWZhdWx0KCk7CisgICAgICAgIFRpbWVab25lIHR6MiA9IChUaW1lWm9uZSl0ejEuY2xvbmUoKTsKKworICAgICAgICBhc3NlcnRUcnVlKHR6MS5lcXVhbHModHoyKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBdmFpbGFibGVJRHMoKSB7CisgICAgICAgIFN0cmluZ1tdIHN0ciA9IFRpbWVab25lLmdldEF2YWlsYWJsZUlEcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKHN0cik7CisgICAgICAgIGFzc2VydFRydWUoc3RyLmxlbmd0aCAhPSAwKTsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChUaW1lWm9uZS5nZXRUaW1lWm9uZShzdHJbaV0pKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0QXZhaWxhYmxlSURzSSgpIHsKKyAgICAgICAgU3RyaW5nW10gc3RyID0gVGltZVpvbmUuZ2V0QXZhaWxhYmxlSURzKDApOworICAgICAgICBhc3NlcnROb3ROdWxsKHN0cik7CisgICAgICAgIGFzc2VydFRydWUoc3RyLmxlbmd0aCAhPSAwKTsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChUaW1lWm9uZS5nZXRUaW1lWm9uZShzdHJbaV0pKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGlzcGxheU5hbWUoKSB7CisgICAgICAgIFRpbWVab25lIHR6ID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkdNVC02Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiR01ULTA2OjAwIiwgdHouZ2V0RGlzcGxheU5hbWUoKSk7CisgICAgICAgIHR6ID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkFtZXJpY2EvTG9zX0FuZ2VsZXMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJQYWNpZmljIFN0YW5kYXJkIFRpbWUiLCB0ei5nZXREaXNwbGF5TmFtZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERpc3BsYXlOYW1lTGphdmFfdXRpbF9Mb2NhbGUoKSB7CisgICAgICAgIFRpbWVab25lIHR6ID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkFtZXJpY2EvTG9zX0FuZ2VsZXMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJQYWNpZmljIFN0YW5kYXJkIFRpbWUiLCB0ei5nZXREaXNwbGF5TmFtZShuZXcgTG9jYWxlKCJVUyIpKSk7CisgICAgICAgIGlmIChTdXBwb3J0X0xvY2FsZS5pc0xvY2FsZUF2YWlsYWJsZShMb2NhbGUuRlJBTkNFKSkgeworICAgICAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1ub3RlOiBSSSBoYXMgIkhldXJlIiwgQ0xEUi9JQ1UgaGFzICJoZXVyZSIuCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImhldXJlIG5vcm1hbGUgZHUgUGFjaWZpcXVlIiwgdHouZ2V0RGlzcGxheU5hbWUoTG9jYWxlLkZSQU5DRSkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREaXNwbGF5TmFtZVpJKCkgeworICAgICAgICBUaW1lWm9uZSB0eiA9IFRpbWVab25lLmdldFRpbWVab25lKCJBbWVyaWNhL0xvc19BbmdlbGVzIik7CisgICAgICAgIGFzc2VydEVxdWFscygiUFNUIiwgICAgICAgICAgICAgICAgICAgdHouZ2V0RGlzcGxheU5hbWUoZmFsc2UsIDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJQYWNpZmljIERheWxpZ2h0IFRpbWUiLCB0ei5nZXREaXNwbGF5TmFtZSh0cnVlLCAxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUGFjaWZpYyBTdGFuZGFyZCBUaW1lIiwgdHouZ2V0RGlzcGxheU5hbWUoZmFsc2UsIDEpKTsKKyAgICB9CisKKyAgICBAQW5kcm9pZE9ubHkoImZhaWwgb24gUkkuIFNlZSBjb21tZW50IGJlbG93IikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERpc3BsYXlOYW1lWklMamF2YV91dGlsX0xvY2FsZSgpIHsKKyAgICAgICAgVGltZVpvbmUgdHogPSBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiQW1lcmljYS9Mb3NfQW5nZWxlcyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlBTVCIsICAgICAgICAgICAgICAgICAgIHR6LmdldERpc3BsYXlOYW1lKGZhbHNlLCAwLCBMb2NhbGUuVVMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJQYWNpZmljIERheWxpZ2h0IFRpbWUiLCB0ei5nZXREaXNwbGF5TmFtZSh0cnVlLCAgMSwgTG9jYWxlLlVTKSk7CisgICAgICAgIGlmIChTdXBwb3J0X0xvY2FsZS5pc0xvY2FsZUF2YWlsYWJsZShMb2NhbGUuVUspKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlBhY2lmaWMgU3RhbmRhcmQgVGltZSIsIHR6LmdldERpc3BsYXlOYW1lKGZhbHNlLCAxLCBMb2NhbGUuVUspKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoU3VwcG9ydF9Mb2NhbGUuaXNMb2NhbGVBdmFpbGFibGUoTG9jYWxlLkZSQU5DRSkpIHsKKyAgICAgICAgICAgIC8vUkkgZmFpbHMgb24gZm9sbG93aW5nIGxpbmUuIFJJIGFsd2F5cyByZXR1cm5zIHNob3J0IHRpbWUgem9uZSBuYW1lIGFzICJQU1QiCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlVUQy0wODowMCIsICAgICAgICAgICAgIHR6LmdldERpc3BsYXlOYW1lKGZhbHNlLCAwLCBMb2NhbGUuRlJBTkNFKSk7CisgICAgICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLW5vdGU6IFJJIGhhcyAiSGV1cmUiLCBDTERSL0lDVSBoYXMgImhldXJlIi4KKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiaGV1cmUgYXZhbmNcdTAwZTllIGR1IFBhY2lmaXF1ZSIsIHR6LmdldERpc3BsYXlOYW1lKHRydWUsICAxLCBMb2NhbGUuRlJBTkNFKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImhldXJlIG5vcm1hbGUgZHUgUGFjaWZpcXVlIiwgdHouZ2V0RGlzcGxheU5hbWUoZmFsc2UsIDEsIExvY2FsZS5GUkFOQ0UpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SUQoKSB7CisgICAgICAgIFRpbWVab25lIHR6ID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkdNVC02Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiR01ULTA2OjAwIiwgdHouZ2V0SUQoKSk7CisgICAgICAgIHR6ID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkFtZXJpY2EvRGVudmVyIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQW1lcmljYS9EZW52ZXIiLCB0ei5nZXRJRCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc1NhbWVSdWxlc0xqYXZhX3V0aWxfVGltZVpvbmUoKSB7CisgICAgICAgIFRpbWVab25lIHR6MSA9IFRpbWVab25lLmdldFRpbWVab25lKCJBbWVyaWNhL0RlbnZlciIpOworICAgICAgICBUaW1lWm9uZSB0ejIgPSBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiQW1lcmljYS9QaG9lbml4Iik7CisgICAgICAgIGFzc2VydEVxdWFscyh0ejEuZ2V0RGlzcGxheU5hbWUoZmFsc2UsIDApLCB0ejIuZ2V0RGlzcGxheU5hbWUoZmFsc2UsIDApKTsKKyAgICAgICAgLy8gQXJpem9uYSBkb2Vzbid0IG9ic2VydmUgRFNULiBTZWUgaHR0cDovL3Bob2VuaXguYWJvdXQuY29tL2NzL3dlYXRoZXIvcXQvdGltZXpvbmUuaHRtCisgICAgICAgIGFzc2VydEZhbHNlKHR6MS5oYXNTYW1lUnVsZXModHoyKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHR6MS5oYXNTYW1lUnVsZXMobnVsbCkpOworICAgICAgICB0ejEgPSBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiQW1lcmljYS9OZXdfWW9yayIpOworICAgICAgICB0ejIgPSBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiVVMvRWFzdGVybiIpOworICAgICAgICBhc3NlcnRFcXVhbHModHoxLmdldERpc3BsYXlOYW1lKCksIHR6Mi5nZXREaXNwbGF5TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UodHoxLmdldElEKCkuZXF1YWxzKHR6Mi5nZXRJRCgpKSk7CisgICAgICAgIGFzc2VydFRydWUodHoyLmhhc1NhbWVSdWxlcyh0ejEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0ejEuaGFzU2FtZVJ1bGVzKHR6MSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0SURMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgVGltZVpvbmUgdHogPSBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiR01ULTYiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHTVQtMDY6MDAiLCB0ei5nZXRJRCgpKTsKKyAgICAgICAgdHouc2V0SUQoIk5ldyBJRCBmb3IgR01ULTYiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJOZXcgSUQgZm9yIEdNVC02IiwgdHouZ2V0SUQoKSk7CisgICAgfQorCisgICAgTG9jYWxlIGxvYyA9IG51bGw7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgbG9jID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQoTG9jYWxlLlVTKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobG9jKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkVHJlZU1hcFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRUcmVlTWFwVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlZjVlNjgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkVHJlZU1hcFRlc3QuamF2YQpAQCAtMCwwICsxLDUwMSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEudGV4dC5Db2xsYXRpb25LZXk7CitpbXBvcnQgamF2YS50ZXh0LkNvbGxhdG9yOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db21wYXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9NYXBUZXN0MjsKKworcHVibGljIGNsYXNzIE9sZFRyZWVNYXBUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgUmV2ZXJzZWRDb21wYXJhdG9yIGltcGxlbWVudHMgQ29tcGFyYXRvciB7CisgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShPYmplY3QgbzEsIE9iamVjdCBvMikgeworICAgICAgICAgICAgcmV0dXJuIC0oKChDb21wYXJhYmxlKSBvMSkuY29tcGFyZVRvKG8yKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8xLCBPYmplY3QgbzIpIHsKKyAgICAgICAgICAgIHJldHVybiAoKChDb21wYXJhYmxlKSBvMSkuY29tcGFyZVRvKG8yKSkgPT0gMDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhhcm1vbnktMTAyNgorICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTW9ja0NvbXBhcmF0b3I8VCBleHRlbmRzIENvbXBhcmFibGU8VD4+IGltcGxlbWVudHMKKyAgICAgICAgICAgIENvbXBhcmF0b3I8VD4sIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgcHVibGljIGludCBjb21wYXJlKFQgbzEsIFQgbzIpIHsKKyAgICAgICAgICAgIGlmIChvMSA9PSBvMikgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG51bGwgPT0gbzEgfHwgbnVsbCA9PSBvMikgeworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFQgYzEgPSBvMTsKKyAgICAgICAgICAgIFQgYzIgPSBvMjsKKyAgICAgICAgICAgIHJldHVybiBjMS5jb21wYXJlVG8oYzIpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gUmVncmVzc2lvbiBmb3IgSGFybW9ueS0xMTYxCisgICAgY2xhc3MgTW9ja0NvbXBhcmF0b3JOdWxsVG9sZXJhYmxlIGltcGxlbWVudHMgQ29tcGFyYXRvcjxTdHJpbmc+IHsKKworICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoU3RyaW5nIG8xLCBTdHJpbmcgbzIpIHsKKyAgICAgICAgICAgIGlmIChvMSA9PSBvMikgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG51bGwgPT0gbzEpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobnVsbCA9PSBvMikgeworICAgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG8xLmNvbXBhcmVUbyhvMik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBUcmVlTWFwIHRtOworCisgICAgT2JqZWN0IG9iakFycmF5W10gPSBuZXcgT2JqZWN0WzEwMDBdOworCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5UcmVlTWFwKCkKKyAgICAgICAgbmV3IFN1cHBvcnRfTWFwVGVzdDIobmV3IFRyZWVNYXAoKSkucnVuVGVzdCgpOworCisgICAgICAgIGFzc2VydFRydWUoIk5ldyB0cmVlTWFwIG5vbi1lbXB0eSIsIG5ldyBUcmVlTWFwKCkuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfdXRpbF9Db21wYXJhdG9yKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlRyZWVNYXAoamF2YS51dGlsLkNvbXBhcmF0b3IpCisgICAgICAgIENvbXBhcmF0b3IgY29tcCA9IG5ldyBSZXZlcnNlZENvbXBhcmF0b3IoKTsKKyAgICAgICAgVHJlZU1hcCByZXZlcnNlZFRyZWVNYXAgPSBuZXcgVHJlZU1hcChjb21wKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVHJlZU1hcCBhbnN3ZXJlZCBpbmNvcnJlY3QgY29tcGFyYXRvciIsIHJldmVyc2VkVHJlZU1hcAorICAgICAgICAgICAgICAgIC5jb21wYXJhdG9yKCkgPT0gY29tcCk7CisgICAgICAgIHJldmVyc2VkVHJlZU1hcC5wdXQobmV3IEludGVnZXIoMSkudG9TdHJpbmcoKSwgbmV3IEludGVnZXIoMSkpOworICAgICAgICByZXZlcnNlZFRyZWVNYXAucHV0KG5ldyBJbnRlZ2VyKDIpLnRvU3RyaW5nKCksIG5ldyBJbnRlZ2VyKDIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVHJlZU1hcCBkb2VzIG5vdCB1c2UgY29tcGFyYXRvciAoZmlyc3RLZXkgd2FzIGluY29ycmVjdCkiLAorICAgICAgICAgICAgICAgIHJldmVyc2VkVHJlZU1hcC5maXJzdEtleSgpLmVxdWFscyhuZXcgSW50ZWdlcigyKS50b1N0cmluZygpKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRyZWVNYXAgZG9lcyBub3QgdXNlIGNvbXBhcmF0b3IgKGxhc3RLZXkgd2FzIGluY29ycmVjdCkiLAorICAgICAgICAgICAgICAgIHJldmVyc2VkVHJlZU1hcC5sYXN0S2V5KCkuZXF1YWxzKG5ldyBJbnRlZ2VyKDEpLnRvU3RyaW5nKCkpKTsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV91dGlsX01hcCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5UcmVlTWFwKGphdmEudXRpbC5NYXApCisgICAgICAgIFRyZWVNYXAgbXlUcmVlTWFwID0gbmV3IFRyZWVNYXAobmV3IEhhc2hNYXAodG0pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTWFwIGlzIGluY29ycmVjdCBzaXplIiwgbXlUcmVlTWFwLnNpemUoKSA9PSBvYmpBcnJheS5sZW5ndGgpOworICAgICAgICBmb3IgKE9iamVjdCBlbGVtZW50IDogb2JqQXJyYXkpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIk1hcCBoYXMgaW5jb3JyZWN0IG1hcHBpbmdzIiwgbXlUcmVlTWFwLmdldCgKKyAgICAgICAgICAgICAgICAgICAgZWxlbWVudC50b1N0cmluZygpKS5lcXVhbHMoZWxlbWVudCkpOworICAgICAgICB9CisKKyAgICAgICAgSGFzaE1hcCBobSA9IG5ldyBIYXNoTWFwKCk7CisgICAgICAgIGhtLnB1dChuZXcgSW50ZWdlcigxKSwgIm9uZSIpOworICAgICAgICBobS5wdXQoIm9uZSIsIG5ldyBJbnRlZ2VyKDEpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFRyZWVNYXAoaG0pOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFRyZWVNYXAoKE1hcCludWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV91dGlsX1NvcnRlZE1hcCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5UcmVlTWFwKGphdmEudXRpbC5Tb3J0ZWRNYXApCisgICAgICAgIENvbXBhcmF0b3IgY29tcCA9IG5ldyBSZXZlcnNlZENvbXBhcmF0b3IoKTsKKyAgICAgICAgVHJlZU1hcCByZXZlcnNlZFRyZWVNYXAgPSBuZXcgVHJlZU1hcChjb21wKTsKKyAgICAgICAgcmV2ZXJzZWRUcmVlTWFwLnB1dChuZXcgSW50ZWdlcigxKS50b1N0cmluZygpLCBuZXcgSW50ZWdlcigxKSk7CisgICAgICAgIHJldmVyc2VkVHJlZU1hcC5wdXQobmV3IEludGVnZXIoMikudG9TdHJpbmcoKSwgbmV3IEludGVnZXIoMikpOworICAgICAgICBUcmVlTWFwIGFub3RoZXJUcmVlTWFwID0gbmV3IFRyZWVNYXAocmV2ZXJzZWRUcmVlTWFwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTmV3IHRyZWUgbWFwIGRvZXMgbm90IGFuc3dlciBjb3JyZWN0IGNvbXBhcmF0b3IiLAorICAgICAgICAgICAgICAgIGFub3RoZXJUcmVlTWFwLmNvbXBhcmF0b3IoKSA9PSBjb21wKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVHJlZU1hcCBkb2VzIG5vdCB1c2UgY29tcGFyYXRvciAoZmlyc3RLZXkgd2FzIGluY29ycmVjdCkiLAorICAgICAgICAgICAgICAgIGFub3RoZXJUcmVlTWFwLmZpcnN0S2V5KCkuZXF1YWxzKG5ldyBJbnRlZ2VyKDIpLnRvU3RyaW5nKCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVHJlZU1hcCBkb2VzIG5vdCB1c2UgY29tcGFyYXRvciAobGFzdEtleSB3YXMgaW5jb3JyZWN0KSIsCisgICAgICAgICAgICAgICAgYW5vdGhlclRyZWVNYXAubGFzdEtleSgpLmVxdWFscyhuZXcgSW50ZWdlcigxKS50b1N0cmluZygpKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBUcmVlTWFwKChTb3J0ZWRNYXApbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbnRhaW5zS2V5TGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuCisgICAgICAgIC8vIGphdmEudXRpbC5UcmVlTWFwLmNvbnRhaW5zS2V5KGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciB2YWxpZCBrZXkiLCB0bS5jb250YWluc0tleSgiOTUiKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHRydWUgZm9yIGludmFsaWQga2V5IiwgIXRtLmNvbnRhaW5zS2V5KCJYWFhYWCIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG0uY29udGFpbnNLZXkobmV3IERvdWJsZSgzLjE0KSk7CisgICAgICAgICAgICBmYWlsKCJDbGFzc0Nhc3RFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0bS5jb250YWluc0tleShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmlyc3RLZXkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IGphdmEudXRpbC5UcmVlTWFwLmZpcnN0S2V5KCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgZmlyc3Qga2V5IiwgIjAiLCB0bS5maXJzdEtleSgpKTsKKyAgICAgICAgdG0gPSBuZXcgVHJlZU1hcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG0uZmlyc3RLZXkoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdAorICAgICAgICAvLyBqYXZhLnV0aWwuVHJlZU1hcC5nZXQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgT2JqZWN0IG8gPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIHRtLnB1dCgiSGVsbG8iLCBvKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGdldCBtYXBwaW5nIiwgdG0uZ2V0KCJIZWxsbyIpID09IG8pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0bS5nZXQobmV3IERvdWJsZSgzLjE0KSk7CisgICAgICAgICAgICBmYWlsKCJDbGFzc0Nhc3RFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0bS5nZXQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hlYWRNYXBMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5Tb3J0ZWRNYXAKKyAgICAgICAgLy8gamF2YS51dGlsLlRyZWVNYXAuaGVhZE1hcChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBNYXAgaGVhZCA9IHRtLmhlYWRNYXAoIjEwMCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIG1hcCBvZiBpbmNvcnJlY3Qgc2l6ZSIsIDMsIGhlYWQuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGVsZW1lbnRzIiwgaGVhZC5jb250YWluc0tleSgiMCIpCisgICAgICAgICAgICAgICAgJiYgaGVhZC5jb250YWluc1ZhbHVlKG5ldyBJbnRlZ2VyKCIxIikpCisgICAgICAgICAgICAgICAgJiYgaGVhZC5jb250YWluc0tleSgiMTAiKSk7CisgICAgICAgIFNvcnRlZE1hcCBzb3J0ID0gdG0uaGVhZE1hcCgiMTAwIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzb3J0LmhlYWRNYXAoIjUwIik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0bS5oZWFkTWFwKHRoaXMpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG0uaGVhZE1hcChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhhcm1vbnktMTAyNgorICAgICAgICBUcmVlTWFwPEludGVnZXIsIERvdWJsZT4gbWFwID0gbmV3IFRyZWVNYXA8SW50ZWdlciwgRG91YmxlPigKKyAgICAgICAgICAgICAgICBuZXcgTW9ja0NvbXBhcmF0b3IoKSk7CisgICAgICAgIG1hcC5wdXQoMSwgMi4xKTsKKyAgICAgICAgbWFwLnB1dCgyLCAzLjEpOworICAgICAgICBtYXAucHV0KDMsIDQuNSk7CisgICAgICAgIG1hcC5wdXQoNywgMjEuMyk7CisgICAgICAgIG1hcC5wdXQobnVsbCwgbnVsbCk7CisKKyAgICAgICAgU29ydGVkTWFwPEludGVnZXIsIERvdWJsZT4gc21hcCA9IG1hcC5oZWFkTWFwKG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgc21hcC5zaXplKCkpOworCisgICAgICAgIFNldDxJbnRlZ2VyPiBrZXlTZXQgPSBzbWFwLmtleVNldCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwga2V5U2V0LnNpemUoKSk7CisKKyAgICAgICAgU2V0PE1hcC5FbnRyeTxJbnRlZ2VyLCBEb3VibGU+PiBlbnRyeVNldCA9IHNtYXAuZW50cnlTZXQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGVudHJ5U2V0LnNpemUoKSk7CisKKyAgICAgICAgQ29sbGVjdGlvbjxEb3VibGU+IHZhbHVlQ29sbGVjdGlvbiA9IHNtYXAudmFsdWVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCB2YWx1ZUNvbGxlY3Rpb24uc2l6ZSgpKTsKKworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIYXJtb255LTEwNjYKKyAgICAgICAgYXNzZXJ0VHJ1ZShoZWFkIGluc3RhbmNlb2YgU2VyaWFsaXphYmxlKTsKKworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBpbGwtYmVoYXZlZCBjb2xsYXRvcgorICAgICAgICBDb2xsYXRvciBjID0gbmV3IENvbGxhdG9yKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoU3RyaW5nIG8xLCBTdHJpbmcgbzIpIHsKKyAgICAgICAgICAgICAgICBpZiAobzEgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG8xLmNvbXBhcmVUbyhvMik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIENvbGxhdGlvbktleSBnZXRDb2xsYXRpb25LZXkoU3RyaW5nIHN0cmluZykgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4gdHJlZW1hcCA9IG5ldyBUcmVlTWFwPFN0cmluZywgU3RyaW5nPihjKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHRyZWVtYXAuaGVhZE1hcChudWxsKS5zaXplKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGFzdEtleSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QgamF2YS51dGlsLlRyZWVNYXAubGFzdEtleSgpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBsYXN0IGtleSIsIHRtLmxhc3RLZXkoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgb2JqQXJyYXlbb2JqQXJyYXkubGVuZ3RoIC0gMV0udG9TdHJpbmcoKSkpOworICAgICAgICB0bSA9IG5ldyBUcmVlTWFwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0bS5sYXN0S2V5KCk7CisgICAgICAgICAgICBmYWlsKCJOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9wdXRMamF2YV9sYW5nX09iamVjdExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdAorICAgICAgICAvLyBqYXZhLnV0aWwuVHJlZU1hcC5wdXQoamF2YS5sYW5nLk9iamVjdCwgamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgT2JqZWN0IG8gPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIHRtLnB1dCgiSGVsbG8iLCBvKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIHB1dCBtYXBwaW5nIiwgdG0uZ2V0KCJIZWxsbyIpID09IG8pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0bS5wdXQobnVsbCwgIm51bGwiKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIHJlZ3Jlc3Npb24gZm9yIEhhcm1vbnktNzgwCisgICAgICAgIHRtID0gbmV3IFRyZWVNYXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydE51bGwodG0ucHV0KG5ldyBPYmplY3QoKSwgbmV3IE9iamVjdCgpKSk7CisgICAgICAgICAgICB0bS5wdXQobmV3IEludGVnZXIoMSksIG5ldyBPYmplY3QoKSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgQ2xhc3NDYXN0RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdG0gPSBuZXcgVHJlZU1hcCgpOworICAgICAgICBhc3NlcnROdWxsKHRtLnB1dChuZXcgSW50ZWdlcigxKSwgbmV3IE9iamVjdCgpKSk7CisgICAgfQorCisgICAgIC8qKgorICAgICAgKiBBbmRyb2lkJ3MgVHJlZU1hcCByZXF1aXJlcyBldmVyeSBlbGVtZW50IHRvIGJlIGNvbXBhcmFibGUsIGV2ZW4gaWYKKyAgICAgICogdGhlcmUncyBubyBvdGhlciBlbGVtZW50IHRvIGNvbXBhcmUgaXQgdG8uIFRoaXMgaXMgbW9yZSBzdHJpY3QgdGhhbiB0aGUKKyAgICAgICogUkkuIFNlZSBIYXJtb255LTI0NzQuCisgICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVOb25Db21wYXJhYmxlRnJvbUVtcHR5TWFwKCkgeworICAgICAgICB0bSA9IG5ldyBUcmVlTWFwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0bS5yZW1vdmUobmV3IE9iamVjdCgpKTsgLy8gc3VjY2VlZHMgb24gUkkKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZCBvbiBsaWJjb3JlIG9ubHkKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcHV0QWxsTGphdmFfdXRpbF9NYXAoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5UcmVlTWFwLnB1dEFsbChqYXZhLnV0aWwuTWFwKQorICAgICAgICBUcmVlTWFwIHggPSBuZXcgVHJlZU1hcCgpOworICAgICAgICB4LnB1dEFsbCh0bSk7CisgICAgICAgIGFzc2VydFRydWUoIk1hcCBpbmNvcnJlY3Qgc2l6ZSBhZnRlciBwdXQiLCB4LnNpemUoKSA9PSB0bS5zaXplKCkpOworICAgICAgICBmb3IgKE9iamVjdCBlbGVtZW50IDogb2JqQXJyYXkpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBwdXQgYWxsIGVsZW1lbnRzIiwgeC5nZXQoZWxlbWVudC50b1N0cmluZygpKQorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKGVsZW1lbnQpKTsKKyAgICAgICAgfQorICAgICAgICB4ID0gbmV3IFRyZWVNYXAoKTsKKyAgICAgICAgeC5wdXQobmV3IEludGVnZXIoMSksICJvbmUiKTsKKyAgICAgICAgeC5wdXQobmV3IEludGVnZXIoMiksICJ0d28iKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG0ucHV0QWxsKHgpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG0ucHV0QWxsKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZW1vdmVMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QKKyAgICAgICAgLy8gamF2YS51dGlsLlRyZWVNYXAucmVtb3ZlKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIHRtLnJlbW92ZSgiOTkwIik7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byByZW1vdmUgbWFwcGluZyIsICF0bS5jb250YWluc0tleSgiOTkwIikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0bS5yZW1vdmUobmV3IERvdWJsZSgzLjE0KSk7CisgICAgICAgICAgICBmYWlsKCJDbGFzc0Nhc3RFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0bS5yZW1vdmUobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1Yk1hcExqYXZhX2xhbmdfT2JqZWN0TGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuU29ydGVkTWFwCisgICAgICAgIC8vIGphdmEudXRpbC5UcmVlTWFwLnN1Yk1hcChqYXZhLmxhbmcuT2JqZWN0LCBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBTb3J0ZWRNYXAgc3ViTWFwID0gdG0uc3ViTWFwKG9iakFycmF5WzEwMF0udG9TdHJpbmcoKSwgb2JqQXJyYXlbMTA5XQorICAgICAgICAgICAgICAgIC50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdWJNYXAgaXMgb2YgaW5jb3JyZWN0IHNpemUiLCA5LCBzdWJNYXAuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDEwMDsgY291bnRlciA8IDEwOTsgY291bnRlcisrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTdWJNYXAgY29udGFpbnMgaW5jb3JyZWN0IGVsZW1lbnRzIiwgc3ViTWFwLmdldCgKKyAgICAgICAgICAgICAgICAgICAgb2JqQXJyYXlbY291bnRlcl0udG9TdHJpbmcoKSkuZXF1YWxzKG9iakFycmF5W2NvdW50ZXJdKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG0uc3ViTWFwKG9iakFycmF5WzldLnRvU3RyaW5nKCksIG9iakFycmF5WzFdLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgZmFpbCgiZW5kIGtleSBsZXNzIHRoYW4gc3RhcnQga2V5IHNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIYXJtb255LTExNjEKKyAgICAgICAgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4gdHJlZU1hcFdpdGhOdWxsID0gbmV3IFRyZWVNYXA8U3RyaW5nLCBTdHJpbmc+KAorICAgICAgICAgICAgICAgIG5ldyBNb2NrQ29tcGFyYXRvck51bGxUb2xlcmFibGUoKSk7CisgICAgICAgIHRyZWVNYXBXaXRoTnVsbC5wdXQoImtleTEiLCAidmFsdWUxIik7CisgICAgICAgIHRyZWVNYXBXaXRoTnVsbC5wdXQobnVsbCwgInZhbHVlMiIpOworICAgICAgICBTb3J0ZWRNYXA8U3RyaW5nLCBTdHJpbmc+IHN1Yk1hcFdpdGhOdWxsID0gdHJlZU1hcFdpdGhOdWxsLnN1Yk1hcChudWxsLAorICAgICAgICAgICAgICAgICJrZXkxIik7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBvZiBzdWJNYXAgc2hvdWxkIGJlIDE6IiwgMSwgc3ViTWFwV2l0aE51bGwuc2l6ZSgpKTsKKworICAgICAgICAvLyBSZWdyZXNzaW9uIHRlc3QgZm9yIHR5cG8gaW4gbGFzdEtleSBtZXRob2QKKyAgICAgICAgU29ydGVkTWFwPFN0cmluZywgU3RyaW5nPiBtYXAgPSBuZXcgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgbWFwLnB1dCgiMSIsICJvbmUiKTsKKyAgICAgICAgbWFwLnB1dCgiMiIsICJ0d28iKTsKKyAgICAgICAgbWFwLnB1dCgiMyIsICJ0aHJlZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjMiLCBtYXAubGFzdEtleSgpKTsKKyAgICAgICAgU29ydGVkTWFwPFN0cmluZywgU3RyaW5nPiBzdWIgPSBtYXAuc3ViTWFwKCIxIiwgIjMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIyIiwgc3ViLmxhc3RLZXkoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRtLnN1Yk1hcCh0aGlzLCB0aGlzKTsKKyAgICAgICAgICAgIGZhaWwoIkNsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRtLnN1Yk1hcChvYmpBcnJheVs5XS50b1N0cmluZygpLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0bS5zdWJNYXAobnVsbCwgb2JqQXJyYXlbOV0udG9TdHJpbmcoKSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RhaWxNYXBMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5Tb3J0ZWRNYXAKKyAgICAgICAgLy8gamF2YS51dGlsLlRyZWVNYXAudGFpbE1hcChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBNYXAgdGFpbCA9IHRtLnRhaWxNYXAob2JqQXJyYXlbOTAwXS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgbWFwIG9mIGluY29ycmVjdCBzaXplIDogIiArIHRhaWwuc2l6ZSgpLCB0YWlsCisgICAgICAgICAgICAgICAgLnNpemUoKSA9PSAob2JqQXJyYXkubGVuZ3RoIC0gOTAwKSArIDkpOworICAgICAgICBmb3IgKGludCBpID0gOTAwOyBpIDwgb2JqQXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIk1hcCBjb250YWlucyBpbmNvcnJlY3QgZW50cmllcyIsIHRhaWwKKyAgICAgICAgICAgICAgICAgICAgLmNvbnRhaW5zVmFsdWUob2JqQXJyYXlbaV0pKTsKKyAgICAgICAgfQorCisgICAgICAgIFNvcnRlZE1hcCBzb3J0ID0gdG0udGFpbE1hcCgiOTkiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc29ydC50YWlsTWFwKCIxMDEiKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRtLnRhaWxNYXAodGhpcyk7CisgICAgICAgICAgICBmYWlsKCJDbGFzc0Nhc3RFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0bS50YWlsTWFwKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSGFybW9ueS0xMDY2CisgICAgICAgIGFzc2VydFRydWUodGFpbCBpbnN0YW5jZW9mIFNlcmlhbGl6YWJsZSk7CisgICAgfQorICAgIC8qKgorICAgICAqIFNldHMgdXAgdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBvcGVuIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzIG1ldGhvZAorICAgICAqIGlzIGNhbGxlZCBiZWZvcmUgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICB0bSA9IG5ldyBUcmVlTWFwKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2JqQXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIE9iamVjdCB4ID0gb2JqQXJyYXlbaV0gPSBuZXcgSW50ZWdlcihpKTsKKyAgICAgICAgICAgIHRtLnB1dCh4LnRvU3RyaW5nKCksIHgpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkVHJlZVNldFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9PbGRUcmVlU2V0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg2ZWQ5ZjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvT2xkVHJlZVNldFRlc3QuamF2YQpAQCAtMCwwICsxLDI3MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlNvcnRlZFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZVNldDsKKworcHVibGljIGNsYXNzIE9sZFRyZWVTZXRUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIFRyZWVTZXQgdHM7CisKKyAgICBPYmplY3Qgb2JqQXJyYXlbXSA9IG5ldyBPYmplY3RbMTAwMF07CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfdXRpbF9Db2xsZWN0aW9uKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlRyZWVTZXQoamF2YS51dGlsLkNvbGxlY3Rpb24pCisgICAgICAgIFRyZWVTZXQgbXlUcmVlU2V0ID0gbmV3IFRyZWVTZXQoQXJyYXlzLmFzTGlzdChvYmpBcnJheSkpOworICAgICAgICBhc3NlcnRUcnVlKCJUcmVlU2V0IGluY29ycmVjdCBzaXplIiwKKyAgICAgICAgICAgICAgICBteVRyZWVTZXQuc2l6ZSgpID09IG9iakFycmF5Lmxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgb2JqQXJyYXkubGVuZ3RoOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJUcmVlU2V0IGRvZXMgbm90IGNvbnRhaW4gY29ycmVjdCBlbGVtZW50cyIsIG15VHJlZVNldAorICAgICAgICAgICAgICAgICAgICAuY29udGFpbnMob2JqQXJyYXlbY291bnRlcl0pKTsKKworICAgICAgICBIYXNoTWFwIGhtID0gbmV3IEhhc2hNYXAoKTsKKyAgICAgICAgaG0ucHV0KCJGaXJzdCIsIG5ldyBJbnRlZ2VyKDEpKTsKKyAgICAgICAgaG0ucHV0KG5ldyBJbnRlZ2VyKDIpLCAidHdvIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBUcmVlU2V0KGhtLnZhbHVlcygpKTsKKyAgICAgICAgICAgIGZhaWwoIkNsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBUcmVlU2V0KChDb2xsZWN0aW9uKW51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX3V0aWxfU29ydGVkU2V0KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFRyZWVTZXQoKFNvcnRlZFNldCludWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEudXRpbC5UcmVlU2V0LmFkZChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICB0cy5hZGQobmV3IEludGVnZXIoLTgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGFkZCBPYmplY3QiLCB0cy5jb250YWlucyhuZXcgSW50ZWdlcigtOCkpKTsKKyAgICAgICAgdHMuYWRkKG9iakFycmF5WzBdKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQWRkZWQgZXhpc3RpbmcgZWxlbWVudCIsIHRzLnNpemUoKSA9PSBvYmpBcnJheS5sZW5ndGggKyAxKTsKKworICAgICAgICBIYXNoTWFwIGhtID0gbmV3IEhhc2hNYXAoKTsKKyAgICAgICAgaG0ucHV0KCJGaXJzdCIsIG5ldyBJbnRlZ2VyKDEpKTsKKyAgICAgICAgaG0ucHV0KG5ldyBJbnRlZ2VyKDIpLCAidHdvIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRzLmFkZCgiV3JvbmcgZWxlbWVudCIpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZEFsbExqYXZhX3V0aWxfQ29sbGVjdGlvbigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4KKyAgICAgICAgLy8gamF2YS51dGlsLlRyZWVTZXQuYWRkQWxsKGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAgICBUcmVlU2V0IHMgPSBuZXcgVHJlZVNldCgpOworICAgICAgICBzLmFkZEFsbCh0cyk7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBzaXplIGFmdGVyIGFkZCIsIHMuc2l6ZSgpID09IHRzLnNpemUoKSk7CisgICAgICAgIEl0ZXJhdG9yIGkgPSB0cy5pdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoaS5oYXNOZXh0KCkpCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3Qgc2V0Iiwgcy5jb250YWlucyhpLm5leHQoKSkpOworCisgICAgICAgIEhhc2hNYXAgaG0gPSBuZXcgSGFzaE1hcCgpOworICAgICAgICBobS5wdXQoIkZpcnN0IiwgbmV3IEludGVnZXIoMSkpOworICAgICAgICBobS5wdXQobmV3IEludGVnZXIoMiksICJ0d28iKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5hZGRBbGwoaG0udmFsdWVzKCkpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5hZGRBbGwobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ZpcnN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdCBqYXZhLnV0aWwuVHJlZVNldC5maXJzdCgpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBmaXJzdCBlbGVtZW50IiwKKyAgICAgICAgICAgICAgICB0cy5maXJzdCgpID09IG9iakFycmF5WzBdKTsKKworICAgICAgICB0cyA9IG5ldyBUcmVlU2V0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0cy5maXJzdCgpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGVhZFNldExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlNvcnRlZFNldAorICAgICAgICAvLyBqYXZhLnV0aWwuVHJlZVNldC5oZWFkU2V0KGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIFNldCBzID0gdHMuaGVhZFNldChuZXcgSW50ZWdlcigxMDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBzZXQgb2YgaW5jb3JyZWN0IHNpemUiLCAxMDAsIHMuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBzZXQiLCBzLmNvbnRhaW5zKG9iakFycmF5W2ldKSk7CisKKyAgICAgICAgU29ydGVkU2V0IHNvcnQgPSB0cy5oZWFkU2V0KG5ldyBJbnRlZ2VyKDEwMCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc29ydC5oZWFkU2V0KG5ldyBJbnRlZ2VyKDEwMSkpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdHMuaGVhZFNldCh0aGlzKTsKKyAgICAgICAgICAgIGZhaWwoIkNsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRzLmhlYWRTZXQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xhc3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IGphdmEudXRpbC5UcmVlU2V0Lmxhc3QoKQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgbGFzdCBlbGVtZW50IiwKKyAgICAgICAgICAgICAgICB0cy5sYXN0KCkgPT0gb2JqQXJyYXlbb2JqQXJyYXkubGVuZ3RoIC0gMV0pOworCisgICAgICAgIHRzID0gbmV3IFRyZWVTZXQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRzLmxhc3QoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1YlNldExqYXZhX2xhbmdfT2JqZWN0TGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuU29ydGVkU2V0CisgICAgICAgIC8vIGphdmEudXRpbC5UcmVlU2V0LnN1YlNldChqYXZhLmxhbmcuT2JqZWN0LCBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBmaW5hbCBpbnQgc3RhcnRQb3MgPSBvYmpBcnJheS5sZW5ndGggLyA0OworICAgICAgICBmaW5hbCBpbnQgZW5kUG9zID0gMyAqIG9iakFycmF5Lmxlbmd0aCAvIDQ7CisgICAgICAgIFNvcnRlZFNldCBhU3ViU2V0ID0gdHMuc3ViU2V0KG9iakFycmF5W3N0YXJ0UG9zXSwgb2JqQXJyYXlbZW5kUG9zXSk7CisgICAgICAgIGFzc2VydFRydWUoIlN1YnNldCBoYXMgd3JvbmcgbnVtYmVyIG9mIGVsZW1lbnRzIiwKKyAgICAgICAgICAgICAgICBhU3ViU2V0LnNpemUoKSA9PSAoZW5kUG9zIC0gc3RhcnRQb3MpKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IHN0YXJ0UG9zOyBjb3VudGVyIDwgZW5kUG9zOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTdWJzZXQgZG9lcyBub3QgY29udGFpbiBhbGwgdGhlIGVsZW1lbnRzIGl0IHNob3VsZCIsCisgICAgICAgICAgICAgICAgICAgIGFTdWJTZXQuY29udGFpbnMob2JqQXJyYXlbY291bnRlcl0pKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdHMuc3ViU2V0KG9iakFycmF5WzNdLCBvYmpBcnJheVswXSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0cy5zdWJTZXQobnVsbCwgb2JqQXJyYXlbM10pOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRzLnN1YlNldChvYmpBcnJheVszXSwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdHMuc3ViU2V0KG9iakFycmF5WzNdLCB0aGlzKTsKKyAgICAgICAgICAgIGZhaWwoIkNsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90YWlsU2V0TGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuU29ydGVkU2V0CisgICAgICAgIC8vIGphdmEudXRpbC5UcmVlU2V0LnRhaWxTZXQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgU2V0IHMgPSB0cy50YWlsU2V0KG5ldyBJbnRlZ2VyKDkwMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIHNldCBvZiBpbmNvcnJlY3Qgc2l6ZSIsIDEwMCwgcy5zaXplKCkpOworICAgICAgICBmb3IgKGludCBpID0gOTAwOyBpIDwgb2JqQXJyYXkubGVuZ3RoOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3Qgc2V0Iiwgcy5jb250YWlucyhvYmpBcnJheVtpXSkpOworCisgICAgICAgIFNvcnRlZFNldCBzb3J0ID0gdHMudGFpbFNldChuZXcgSW50ZWdlcigxMDEpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc29ydC50YWlsU2V0KG5ldyBJbnRlZ2VyKDEwMCkpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdHMudGFpbFNldCh0aGlzKTsKKyAgICAgICAgICAgIGZhaWwoIkNsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRzLnRhaWxTZXQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgdHMgPSBuZXcgVHJlZVNldCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iakFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBPYmplY3QgeCA9IG9iakFycmF5W2ldID0gbmV3IEludGVnZXIoaSk7CisgICAgICAgICAgICB0cy5hZGQoeCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWFycyBkb3duIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgY2xvc2UgYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMKKyAgICAgKiBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvUmFuZG9tVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL1JhbmRvbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMWJkYzYzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL1JhbmRvbVRlc3QuamF2YQpAQCAtMCwwICsxLDQzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CisKK3B1YmxpYyBjbGFzcyBSYW5kb21UZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1YmNsYXNzaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIGh0dHA6Ly9iLzI1MDIyMzEKKyAgICAgICAgLy8gRW5zdXJlIHRoYXQgUmFuZG9tJ3MgY29uc3RydWN0b3JzIGNhbGwgc2V0U2VlZCBieSBlbXVsYXRpbmcgdGhlIGFjdGl2ZSBpbmdyZWRpZW50CisgICAgICAgIC8vIGZyb20gdGhlIGJ1ZzogdGhlIHN1YmNsYXNzJyBzZXRTZWVkIGhhZCBhIHNpZGUtZWZmZWN0IG5lY2Vzc2FyeSBmb3IgdGhlIGNvcnJlY3QKKyAgICAgICAgLy8gZnVuY3Rpb25pbmcgb2YgbmV4dC4KKyAgICAgICAgY2xhc3MgTXlSYW5kb20gZXh0ZW5kcyBSYW5kb20geworICAgICAgICAgICAgcHVibGljIFN0cmluZyBzdGF0ZTsKKyAgICAgICAgICAgIHB1YmxpYyBNeVJhbmRvbSgpIHsgc3VwZXIoKTsgfQorICAgICAgICAgICAgcHVibGljIE15UmFuZG9tKGxvbmcgbCkgeyBzdXBlcihsKTsgfQorICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBzeW5jaHJvbml6ZWQgaW50IG5leHQoaW50IGJpdHMpIHsgcmV0dXJuIHN0YXRlLmxlbmd0aCgpOyB9CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFNlZWQobG9uZyBzZWVkKSB7IHN0YXRlID0gTG9uZy50b1N0cmluZyhzZWVkKTsgfQorICAgICAgICB9CisgICAgICAgIC8vIFRlc3QgdGhlIDAtYXJndW1lbnQgY29uc3RydWN0b3IuLi4KKyAgICAgICAgTXlSYW5kb20gcjEgPSBuZXcgTXlSYW5kb20oKTsKKyAgICAgICAgcjEubmV4dEludCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKHIxLnN0YXRlKTsKKyAgICAgICAgLy8gVGVzdCB0aGUgMS1hcmd1bWVudCBjb25zdHJ1Y3Rvci4uLgorICAgICAgICBNeVJhbmRvbSByMiA9IG5ldyBNeVJhbmRvbSgxMjNMKTsKKyAgICAgICAgcjIubmV4dEludCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKHIyLnN0YXRlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvU2VyaWFsaXphYmxlVGVzdGVyLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvU2VyaWFsaXphYmxlVGVzdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTBiNjQzNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9TZXJpYWxpemFibGVUZXN0ZXIuamF2YQpAQCAtMCwwICsxLDExNyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBHb29nbGUgSW5jLgorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IHN0YXRpYyBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0Lio7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydGlvbkZhaWxlZEVycm9yOworCitwdWJsaWMgY2xhc3MgU2VyaWFsaXphYmxlVGVzdGVyPFQ+IHsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGdvbGRlbjsKKyAgICBwcml2YXRlIGZpbmFsIFQgdmFsdWU7CisKKyAgICBwdWJsaWMgU2VyaWFsaXphYmxlVGVzdGVyKFQgdmFsdWUsIFN0cmluZyBnb2xkZW4pIHsKKyAgICAgICAgdGhpcy5nb2xkZW4gPSBnb2xkZW47CisgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYge0Bjb2RlIGF9IGFuZCB7QGNvZGUgYn0gYXJlIGVxdWFsLiBPdmVycmlkZSB0aGlzIGlmCisgICAgICoge0BsaW5rIE9iamVjdCNlcXVhbHN9IGlzbid0IGFwcHJvcHJpYXRlIG9yIHN1ZmZpY2llbnQgZm9yIHRoaXMgdGVzdGVyJ3MKKyAgICAgKiB2YWx1ZSB0eXBlLgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGVxdWFscyhUIGEsIFQgYikgeworICAgICAgICByZXR1cm4gYS5lcXVhbHMoYik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVmVyaWZpZXMgdGhhdCB7QGNvZGUgZGVzZXJpYWxpemVkfSBpcyB2YWxpZC4gSW1wbGVtZW50YXRpb25zIG9mIHRoaXMKKyAgICAgKiBtZXRob2QgbWF5IG11dGF0ZSB7QGNvZGUgZGVzZXJpYWxpemVkfS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB2ZXJpZnkoVCBkZXNlcmlhbGl6ZWQpIHt9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGdvbGRlbiA9PSBudWxsIHx8IGdvbGRlbi5sZW5ndGgoKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiTm8gZ29sZGVuIHZhbHVlIHN1cHBsaWVkISBDb25zaWRlciB1c2luZyB0aGlzOiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIGhleEVuY29kZShzZXJpYWxpemUodmFsdWUpKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSAvLyBkZXNlcmlhbGl6ZSBzaG91bGQgcmV0dXJuIHRoZSBwcm9wZXIgdHlwZQorICAgICAgICAgICAgVCBkZXNlcmlhbGl6ZWQgPSAoVCkgZGVzZXJpYWxpemUoaGV4RGVjb2RlKGdvbGRlbikpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVXNlci1jb25zdHJ1Y3RlZCB2YWx1ZSBkb2Vzbid0IGVxdWFsIGRlc2VyaWFsaXplZCBnb2xkZW4gdmFsdWUiLAorICAgICAgICAgICAgICAgICAgICBlcXVhbHModmFsdWUsIGRlc2VyaWFsaXplZCkpOworCisgICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikgLy8gZGVzZXJpYWxpemUgc2hvdWxkIHJldHVybiB0aGUgcHJvcGVyIHR5cGUKKyAgICAgICAgICAgIFQgcmVzZXJpYWxpemVkID0gKFQpIGRlc2VyaWFsaXplKHNlcmlhbGl6ZSh2YWx1ZSkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVXNlci1jb25zdHJ1Y3RlZCB2YWx1ZSBkb2Vzbid0IGVxdWFsIGl0c2VsZiwgcmVzZXJpYWxpemVkIiwKKyAgICAgICAgICAgICAgICAgICAgZXF1YWxzKHZhbHVlLCByZXNlcmlhbGl6ZWQpKTsKKworICAgICAgICAgICAgLy8ganVzdCBhIHNhbml0eSBjaGVjayEgaWYgdGhpcyBmYWlscywgdmVyaWZ5KCkgaXMgcHJvYmFibHkgYnJva2VuCisgICAgICAgICAgICB2ZXJpZnkodmFsdWUpOworICAgICAgICAgICAgdmVyaWZ5KGRlc2VyaWFsaXplZCk7CisgICAgICAgICAgICB2ZXJpZnkocmVzZXJpYWxpemVkKTsKKworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgRXJyb3IgZmFpbHVyZSA9IG5ldyBBc3NlcnRpb25GYWlsZWRFcnJvcigpOworICAgICAgICAgICAgZmFpbHVyZS5pbml0Q2F1c2UoZSk7CisgICAgICAgICAgICB0aHJvdyBmYWlsdXJlOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdIHNlcmlhbGl6ZShPYmplY3Qgb2JqZWN0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKG91dCkud3JpdGVPYmplY3Qob2JqZWN0KTsKKyAgICAgICAgcmV0dXJuIG91dC50b0J5dGVBcnJheSgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIE9iamVjdCBkZXNlcmlhbGl6ZShieXRlW10gYnl0ZXMpIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdElucHV0U3RyZWFtIGluID0gbmV3IE9iamVjdElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcykpOworICAgICAgICBPYmplY3QgcmVzdWx0ID0gaW4ucmVhZE9iamVjdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGhleEVuY29kZShieXRlW10gYnl0ZXMpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcihieXRlcy5sZW5ndGggKiAyKTsKKyAgICAgICAgZm9yIChieXRlIGIgOiBieXRlcykgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChTdHJpbmcuZm9ybWF0KCIlMDJ4IiwgYikpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlW10gaGV4RGVjb2RlKFN0cmluZyBzKSB7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtzLmxlbmd0aCgpIC8gMl07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVzdWx0Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICByZXN1bHRbaV0gPSAoYnl0ZSkgSW50ZWdlci5wYXJzZUludChzLnN1YnN0cmluZyhpKjIsIGkqMiArIDIpLCAxNik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBzZXJpYWxpemVIZXgoT2JqZWN0IG9iamVjdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGhleEVuY29kZShzZXJpYWxpemUob2JqZWN0KSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBPYmplY3QgZGVzZXJpYWxpemVIZXgoU3RyaW5nIGhleCkgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGRlc2VyaWFsaXplKGhleERlY29kZShoZXgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvU2VydmljZUxvYWRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9TZXJ2aWNlTG9hZGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2YmI2NTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvU2VydmljZUxvYWRlclRlc3QuamF2YQpAQCAtMCwwICsxLDM5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuU2VydmljZUxvYWRlcjsKKworcHVibGljIGNsYXNzIFNlcnZpY2VMb2FkZXJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICBwdWJsaWMgc3RhdGljIGludGVyZmFjZSBVbmltcGxlbWVudGVkSW50ZXJmYWNlIHsgfQorICAgIHB1YmxpYyB2b2lkIHRlc3Rfbm9JbXBsZW1lbnRhdGlvbnMoKSB7CisgICAgICAgIGFzc2VydEZhbHNlKFNlcnZpY2VMb2FkZXIubG9hZChVbmltcGxlbWVudGVkSW50ZXJmYWNlLmNsYXNzKS5pdGVyYXRvcigpLmhhc05leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBJbXBsMSBpbXBsZW1lbnRzIFNlcnZpY2VMb2FkZXJUZXN0SW50ZXJmYWNlIHsgfQorICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSW1wbDIgaW1wbGVtZW50cyBTZXJ2aWNlTG9hZGVyVGVzdEludGVyZmFjZSB7IH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ltcGxlbWVudGF0aW9ucygpIHsKKyAgICAgICAgU2VydmljZUxvYWRlcjxTZXJ2aWNlTG9hZGVyVGVzdEludGVyZmFjZT4gbG9hZGVyID0gU2VydmljZUxvYWRlci5sb2FkKFNlcnZpY2VMb2FkZXJUZXN0SW50ZXJmYWNlLmNsYXNzKTsKKyAgICAgICAgSXRlcmF0b3I8U2VydmljZUxvYWRlclRlc3RJbnRlcmZhY2U+IGl0ID0gbG9hZGVyLml0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydFRydWUoaXQuaGFzTmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShpdC5uZXh0KCkgaW5zdGFuY2VvZiBJbXBsMSk7CisgICAgICAgIGFzc2VydFRydWUoaXQuaGFzTmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShpdC5uZXh0KCkgaW5zdGFuY2VvZiBJbXBsMik7CisgICAgICAgIGFzc2VydEZhbHNlKGl0Lmhhc05leHQoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL1NlcnZpY2VMb2FkZXJUZXN0SW50ZXJmYWNlLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvU2VydmljZUxvYWRlclRlc3RJbnRlcmZhY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NzUxYjQzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL1NlcnZpY2VMb2FkZXJUZXN0SW50ZXJmYWNlLmphdmEKQEAgLTAsMCArMSwyNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWw7CisKKy8qKgorICogSWRlYWxseSwgdGhpcyB3b3VsZCBoYXZlIGJlZW4gYW4gaW5uZXIgY2xhc3MgaW4gU2VydmljZUxvYWRlclRlc3QsIGJ1dCB3ZSBuZWVkIGEgY29ycmVzcG9uZGluZworICogcmVzb3VyY2UgZmlsZSwgYW5kIG91ciBidWlsZCBzeXN0ZW0gY2FuJ3QgY29wZSB3aXRoICQgaW4gZmlsZW5hbWVzLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFNlcnZpY2VMb2FkZXJUZXN0SW50ZXJmYWNlIHsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9UaW1lWm9uZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9UaW1lWm9uZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOWFjMTlkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL1RpbWVab25lVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTUxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0OworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLlRpbWVab25lOworaW1wb3J0IGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZTsKKworcHVibGljIGNsYXNzIFRpbWVab25lVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD04NzcKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VzZURheWxpZ2h0VGltZV9UYWl3YW4oKSB7CisgICAgICAgIFRpbWVab25lIGFzaWFUYWlwZWkgPSBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiQXNpYS9UYWlwZWkiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRhaXdhbiBkb2Vzbid0IHVzZSBEU1QiLCBhc2lhVGFpcGVpLnVzZURheWxpZ2h0VGltZSgpKTsKKyAgICB9CisKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTgwMTYKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VzZURheWxpZ2h0VGltZV9JY2VsYW5kKCkgeworICAgICAgICBUaW1lWm9uZSBhdGxhbnRpY1JleWtqYXZpayA9IFRpbWVab25lLmdldFRpbWVab25lKCJBdGxhbnRpYy9SZXlramF2aWsiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJleWtqYXZpayBkb2Vzbid0IHVzZSBEU1QiLCBhdGxhbnRpY1JleWtqYXZpay51c2VEYXlsaWdodFRpbWUoKSk7CisgICAgfQorCisgICAgLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD0xMTU0MgorICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvbmVfU2ltcGxlVGltZVpvbmUoKSB7CisgICAgICAgIFNpbXBsZVRpbWVab25lIHN0eiA9IG5ldyBTaW1wbGVUaW1lWm9uZSgyMTYwMDAwMCwgIkNlbnRyYWwgU3RhbmRhcmQgVGltZSIpOworICAgICAgICBzdHouc2V0U3RhcnRZZWFyKDEwMDApOworICAgICAgICBzdHouaW5EYXlsaWdodFRpbWUobmV3IERhdGUoKSk7CisgICAgICAgIHN0ei5jbG9uZSgpOworICAgIH0KKworICAgIC8vIGh0dHA6Ly9iLzMwNDkwMTQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q3VzdG9tVGltZVpvbmVEaXNwbGF5TmFtZXMoKSB7CisgICAgICAgIFRpbWVab25lIHR6MDAwMSA9IG5ldyBTaW1wbGVUaW1lWm9uZSg2MDAwMCwgIk9ORSBNSU5VVEUiKTsKKyAgICAgICAgVGltZVpvbmUgdHowMTMwID0gbmV3IFNpbXBsZVRpbWVab25lKDU0MDAwMDAsICJPTkUgSE9VUiwgVEhJUlRZIik7CisgICAgICAgIFRpbWVab25lIHR6TWludXMwMTMwID0gbmV3IFNpbXBsZVRpbWVab25lKC01NDAwMDAwLCAiTkVHIE9ORSBIT1VSLCBUSElSVFkiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHTVQrMDA6MDEiLCB0ejAwMDEuZ2V0RGlzcGxheU5hbWUoZmFsc2UsIFRpbWVab25lLlNIT1JULCBMb2NhbGUuVVMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHTVQrMDE6MzAiLCB0ejAxMzAuZ2V0RGlzcGxheU5hbWUoZmFsc2UsIFRpbWVab25lLlNIT1JULCBMb2NhbGUuVVMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHTVQtMDE6MzAiLCB0ek1pbnVzMDEzMC5nZXREaXNwbGF5TmFtZShmYWxzZSwgVGltZVpvbmUuU0hPUlQsIExvY2FsZS5VUykpOworICAgIH0KKworICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9MTQzOTUKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJlSGlzdG9yaWNJbkRheWxpZ2h0VGltZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUaW1lWm9uZSB0eiA9IFRpbWVab25lLmdldFRpbWVab25lKCJBbWVyaWNhL0xvc19BbmdlbGVzIik7CisgICAgICAgIFRpbWVab25lLnNldERlZmF1bHQodHopOworICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IHNkZiA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KCJ5eXl5LU1NLWRkJ1QnSEg6bW06c3MuU1NTWiIpOworICAgICAgICBEYXRlIGRhdGUgPSBzZGYucGFyc2UoIjE5MDItMTEtMDFUMDA6MDA6MDAuMDAwKzA4MDAiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0yMTE5NjgwMDAwMDAwTCwgZGF0ZS5nZXRUaW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTI4ODAwMDAwLCB0ei5nZXRPZmZzZXQoZGF0ZS5nZXRUaW1lKCkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UodHouaW5EYXlsaWdodFRpbWUoZGF0ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZyaSBPY3QgMzEgMDg6MDA6MDAgUFNUIDE5MDIiLCBkYXRlLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjMxIE9jdCAxOTAyIDE2OjAwOjAwIEdNVCIsIGRhdGUudG9HTVRTdHJpbmcoKSk7CisgICAgICAgIC8vIEFueSB0aW1lIGJlZm9yZSB3ZSBoYXZlIHRyYW5zaXRpb24gZGF0YSBpcyBjb25zaWRlcmVkIG5vbi1kYXlsaWdodCwgZXZlbiBpbiBzdW1tZXIuCisgICAgICAgIGRhdGUgPSBzZGYucGFyc2UoIjE5MDItMDYtMDFUMDA6MDA6MDAuMDAwKzA4MDAiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0yODgwMDAwMCwgdHouZ2V0T2Zmc2V0KGRhdGUuZ2V0VGltZSgpKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHR6LmluRGF5bGlnaHRUaW1lKGRhdGUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJlSGlzdG9yaWNPZmZzZXRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRoZSAiQXNpYS9TYWlnb24iIHRpbWUgem9uZSBoYXMganVzdCBhIGZldyB0cmFuc2l0aW9ucywgYW5kIGhhc24ndCBjaGFuZ2VkIGluIGEKKyAgICAgICAgLy8gbG9uZyB0aW1lLCB3aGljaCBpcyBjb252ZW5pZW50IGZvciB0ZXN0aW5nOgorICAgICAgICAvLworICAgICAgICAvLyBsaWJjb3JlLnV0aWwuWm9uZUluZm9bQXNpYS9TYWlnb24sbVJhd09mZnNldD0yNTIwMDAwMCxtVXNlRHN0PWZhbHNlXQorICAgICAgICAvLyAwIDogdGltZT0tMjAwNTk3NDQwMCBGcmkgSnVuIDA4IDE2OjUzOjIwIDE5MDYgR01UKzAwOjAwID0gRnJpIEp1biAwOCAyMzo1OTo0MCAxOTA2IElDVCBpc0RzdD0wIG9mZnNldD0gIDM4MCBnbXRPZmZzZXQ9MjU1ODAKKyAgICAgICAgLy8gMSA6IHRpbWU9LTE4NTU5ODM5MjAgRnJpIE1hciAxMCAxNjo1NDo0MCAxOTExIEdNVCswMDowMCA9IEZyaSBNYXIgMTAgMjM6NTQ6NDAgMTkxMSBJQ1QgaXNEc3Q9MCBvZmZzZXQ9ICAgIDAgZ210T2Zmc2V0PTI1MjAwCisgICAgICAgIC8vIDIgOiB0aW1lPS0xODE5OTU0ODAwIFR1ZSBBcHIgMzAgMTc6MDA6MDAgMTkxMiBHTVQrMDA6MDAgPSBXZWQgTWF5IDAxIDAxOjAwOjAwIDE5MTIgSUNUIGlzRHN0PTAgb2Zmc2V0PSAzNjAwIGdtdE9mZnNldD0yODgwMAorICAgICAgICAvLyAzIDogdGltZT0tMTIyMDQyODgwMCBUaHUgQXByIDMwIDE2OjAwOjAwIDE5MzEgR01UKzAwOjAwID0gVGh1IEFwciAzMCAyMzowMDowMCAxOTMxIElDVCBpc0RzdD0wIG9mZnNldD0gICAgMCBnbXRPZmZzZXQ9MjUyMDAKKyAgICAgICAgVGltZVpvbmUgdHogPSBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiQXNpYS9TYWlnb24iKTsKKworICAgICAgICAvLyBUaW1lcyBiZWZvcmUgb3VyIGZpcnN0IHRyYW5zaXRpb24gc2hvdWxkIGFzc3VtZSB3ZSdyZSBzdGlsbCBmb2xsb3dpbmcgdGhhdCB0cmFuc2l0aW9uLgorICAgICAgICAvLyBOb3RlOiB0aGUgUkkgcmVwb3J0cyAyNTYwMCBoZXJlIGJlY2F1c2UgaXQgaGFzIG1vcmUgdHJhbnNpdGlvbnMgdGhhbiB3ZSBkby4KKyAgICAgICAgYXNzZXJ0Tm9uRGF5bGlnaHRPZmZzZXQoMjU1ODAsIC0yMDA1OTc1MDAwTCwgdHopOworCisgICAgICAgIGFzc2VydE5vbkRheWxpZ2h0T2Zmc2V0KDI1NTgwLCAtMjAwNTk3NDQwMEwsIHR6KTsgLy8gMAorICAgICAgICBhc3NlcnROb25EYXlsaWdodE9mZnNldCgyNTU4MCwgLTIwMDU5NzQwMDBMLCB0eik7CisKKyAgICAgICAgYXNzZXJ0Tm9uRGF5bGlnaHRPZmZzZXQoMjUyMDAsIC0xODU1OTgzOTIwTCwgdHopOyAvLyAxCisgICAgICAgIGFzc2VydE5vbkRheWxpZ2h0T2Zmc2V0KDI1MjAwLCAtMTg1NTk4MzkwMEwsIHR6KTsKKworICAgICAgICBhc3NlcnROb25EYXlsaWdodE9mZnNldCgyODgwMCwgLTE4MTk5NTQ4MDBMLCB0eik7IC8vIDIKKyAgICAgICAgYXNzZXJ0Tm9uRGF5bGlnaHRPZmZzZXQoMjg4MDAsIC0xODE5OTU0MDAwTCwgdHopOworCisgICAgICAgIGFzc2VydE5vbkRheWxpZ2h0T2Zmc2V0KDI1MjAwLCAtMTIyMDQyODgwMEwsIHR6KTsgLy8gMworCisgICAgICAgIC8vIFRpbWVzIGFmdGVyIG91dCBsYXN0IHRyYW5zaXRpb24gc2hvdWxkIGFzc3VtZSB3ZSdyZSBzdGlsbCBmb2xsb3dpbmcgdGhhdCB0cmFuc2l0aW9uLgorICAgICAgICBhc3NlcnROb25EYXlsaWdodE9mZnNldCgyNTIwMCwgLTEyMjA0MjgwMDBMLCB0eik7CisKKyAgICAgICAgLy8gVGhlcmUgYXJlIHBsZW50eSBtb3JlIGV4YW1wbGVzLiAiQWZyaWNhL0Jpc3NhdSIgaXMgb25lOgorICAgICAgICAvLworICAgICAgICAvLyBsaWJjb3JlLnV0aWwuWm9uZUluZm9bQWZyaWNhL0Jpc3NhdSxtUmF3T2Zmc2V0PTAsbVVzZURzdD1mYWxzZV0KKyAgICAgICAgLy8gMCA6IHRpbWU9LTE4NDkzODgyNjAgRnJpIE1heSAyNiAwMTowMjoyMCAxOTExIEdNVCswMDowMCA9IEZyaSBNYXkgMjYgMDA6MDI6MjAgMTkxMSBHTVQgaXNEc3Q9MCBvZmZzZXQ9LTM2MDAgZ210T2Zmc2V0PS0zNjAwCisgICAgICAgIC8vIDEgOiB0aW1lPSAgMTU3NzcwMDAwIFdlZCBKYW4gMDEgMDE6MDA6MDAgMTk3NSBHTVQrMDA6MDAgPSBXZWQgSmFuIDAxIDAxOjAwOjAwIDE5NzUgR01UIGlzRHN0PTAgb2Zmc2V0PSAgICAwIGdtdE9mZnNldD0wCisgICAgICAgIHR6ID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkFmcmljYS9CaXNzYXUiKTsKKyAgICAgICAgYXNzZXJ0Tm9uRGF5bGlnaHRPZmZzZXQoLTM2MDAsIC0xODQ5Mzg4MzAwTCwgdHopOworICAgICAgICBhc3NlcnROb25EYXlsaWdodE9mZnNldCgtMzYwMCwgLTE4NDkzODgyNjBMLCB0eik7IC8vIDAKKyAgICAgICAgYXNzZXJ0Tm9uRGF5bGlnaHRPZmZzZXQoLTM2MDAsIC0xODQ5Mzg4MjAwTCwgdHopOworICAgICAgICBhc3NlcnROb25EYXlsaWdodE9mZnNldCgwLCAxNTc3NzAwMDBMLCB0eik7IC8vIDEKKyAgICAgICAgYXNzZXJ0Tm9uRGF5bGlnaHRPZmZzZXQoMCwgMTU3NzgwMDAwTCwgdHopOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYXNzZXJ0Tm9uRGF5bGlnaHRPZmZzZXQoaW50IGV4cGVjdGVkT2Zmc2V0U2Vjb25kcywgbG9uZyBlcG9jaFNlY29uZHMsIFRpbWVab25lIHR6KSB7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZE9mZnNldFNlY29uZHMgKiAxMDAwLCB0ei5nZXRPZmZzZXQoZXBvY2hTZWNvbmRzICogMTAwMCkpOworICAgICAgICBhc3NlcnRGYWxzZSh0ei5pbkRheWxpZ2h0VGltZShuZXcgRGF0ZShlcG9jaFNlY29uZHMgKiAxMDAwKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RaZXJvVHJhbnNpdGlvblpvbmVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFpvbmVzIHdpdGggbm8gdHJhbnNpdGlvbnMgaGlzdG9yaWNhbCBvciBmdXR1cmUgc2VlbSBpZGVhbCBmb3IgdGVzdGluZy4KKyAgICAgICAgU3RyaW5nW10gaWRzID0gbmV3IFN0cmluZ1tdIHsgIkFmcmljYS9CdWp1bWJ1cmEiLCAiSW5kaWFuL0NvY29zIiwgIlBhY2lmaWMvV2FrZSIsICJVVEMiIH07CisgICAgICAgIGZvciAoU3RyaW5nIGlkIDogaWRzKSB7CisgICAgICAgICAgICBUaW1lWm9uZSB0eiA9IFRpbWVab25lLmdldFRpbWVab25lKGlkKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHR6LnVzZURheWxpZ2h0VGltZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHR6LmluRGF5bGlnaHRUaW1lKG5ldyBEYXRlKEludGVnZXIuTUlOX1ZBTFVFKSkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UodHouaW5EYXlsaWdodFRpbWUobmV3IERhdGUoMCkpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHR6LmluRGF5bGlnaHRUaW1lKG5ldyBEYXRlKEludGVnZXIuTUFYX1ZBTFVFKSkpOworICAgICAgICAgICAgaW50IGN1cnJlbnRPZmZzZXQgPSB0ei5nZXRPZmZzZXQobmV3IERhdGUoMCkuZ2V0VGltZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjdXJyZW50T2Zmc2V0LCB0ei5nZXRPZmZzZXQobmV3IERhdGUoSW50ZWdlci5NSU5fVkFMVUUpLmdldFRpbWUoKSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGN1cnJlbnRPZmZzZXQsIHR6LmdldE9mZnNldChuZXcgRGF0ZShJbnRlZ2VyLk1BWF9WQUxVRSkuZ2V0VGltZSgpKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTE2NjA4CisgICAgcHVibGljIHZvaWQgdGVzdEhlbHNpbmtpT3ZlcmZsb3coKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbG9uZyB0aW1lID0gMjE0NzQ4MzY0ODAwMEw7Ly8gVHVlLCAxOSBKYW4gMjAzOCAwMzoxNDowOCBHTVQKKyAgICAgICAgVGltZVpvbmUgdGltZVpvbmUgPSBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiRXVyb3BlL0hlbHNpbmtpIik7CisgICAgICAgIGxvbmcgb2Zmc2V0ID0gdGltZVpvbmUuZ2V0T2Zmc2V0KHRpbWUpOworICAgICAgICAvLyBUaGlzIG1pZ2h0IGNhdXNlIHVzIHRyb3VibGUgaWYgRXVyb3BlL0hlbHNpbmtpIGNoYW5nZXMgaXRzIHJ1bGVzLiBTZWUgdGhlIGJ1ZyBmb3IKKyAgICAgICAgLy8gZGV0YWlscyBvZiB0aGUgaW50ZW50IG9mIHRoaXMgdGVzdC4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDcyMDAwMDAsIG9mZnNldCk7CisgICAgfQorCisgICAgLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD0xMTkxOAorICAgIHB1YmxpYyB2b2lkIHRlc3RIYXNTYW1lUnVsZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGltZVpvbmUgZGVudmVyID0gVGltZVpvbmUuZ2V0VGltZVpvbmUgKCJBbWVyaWNhL0RlbnZlciIpIDsKKyAgICAgICAgVGltZVpvbmUgcGhvZW5peCA9IFRpbWVab25lLmdldFRpbWVab25lICgiQW1lcmljYS9QaG9lbml4IikgOworICAgICAgICBhc3NlcnRGYWxzZShkZW52ZXIuaGFzU2FtZVJ1bGVzKHBob2VuaXgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvVHJlZU1hcFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9UcmVlTWFwVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRhMDQ4ZjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvVHJlZU1hcFRlc3QuamF2YQpAQCAtMCwwICsxLDQzMyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBHb29nbGUgSW5jLgorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdE1hcC5TaW1wbGVFbnRyeTsKK2ltcG9ydCBqYXZhLnV0aWwuQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwLkVudHJ5OworaW1wb3J0IGphdmEudXRpbC5OYXZpZ2FibGVNYXA7CitpbXBvcnQgamF2YS51dGlsLlNvcnRlZE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBUcmVlTWFwVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCB0aGUgZW50cnlTZXQoKSBtZXRob2QgcHJvZHVjZXMgY29ycmVjdGx5IG11dGFibGUgRW50cnlzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFbnRyeVNldFNldFZhbHVlKCkgeworICAgICAgICBUcmVlTWFwPFN0cmluZywgU3RyaW5nPiBtYXAgPSBuZXcgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgbWFwLnB1dCgiQSIsICJhIik7CisgICAgICAgIG1hcC5wdXQoIkIiLCAiYiIpOworICAgICAgICBtYXAucHV0KCJDIiwgImMiKTsKKworICAgICAgICBJdGVyYXRvcjxFbnRyeTxTdHJpbmcsU3RyaW5nPj4gaXRlcmF0b3IgPSBtYXAuZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICBFbnRyeTxTdHJpbmcsIFN0cmluZz4gZW50cnlBID0gaXRlcmF0b3IubmV4dCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBlbnRyeUEuc2V0VmFsdWUoIngiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieCIsIGVudHJ5QS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4IiwgbWFwLmdldCgiQSIpKTsKKyAgICAgICAgRW50cnk8U3RyaW5nLCBTdHJpbmc+IGVudHJ5QiA9IGl0ZXJhdG9yLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiIiwgZW50cnlCLnNldFZhbHVlKCJ5IikpOworICAgICAgICBFbnRyeTxTdHJpbmcsIFN0cmluZz4gZW50cnlDID0gaXRlcmF0b3IubmV4dCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImMiLCBlbnRyeUMuc2V0VmFsdWUoInoiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieSIsIGVudHJ5Qi5nZXRWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ5IiwgbWFwLmdldCgiQiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ6IiwgZW50cnlDLmdldFZhbHVlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInoiLCBtYXAuZ2V0KCJDIikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCB0aGUgZW50cnlTZXQoKSBtZXRob2Qgb2YgYSBzdWJtYXAgcHJvZHVjZXMgY29ycmVjdGx5IG11dGFibGUgRW50cnlzIHRoYXQKKyAgICAgKiBwcm9wYWdhdGUgY2hhbmdlcyB0byB0aGUgb3JpZ2luYWwgbWFwLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTdWJNYXBFbnRyeVNldFNldFZhbHVlKCkgeworICAgICAgICBUcmVlTWFwPFN0cmluZywgU3RyaW5nPiBtYXAgPSBuZXcgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgbWFwLnB1dCgiQSIsICJhIik7CisgICAgICAgIG1hcC5wdXQoIkIiLCAiYiIpOworICAgICAgICBtYXAucHV0KCJDIiwgImMiKTsKKyAgICAgICAgbWFwLnB1dCgiRCIsICJkIik7CisgICAgICAgIE5hdmlnYWJsZU1hcDxTdHJpbmcsIFN0cmluZz4gc3ViTWFwID0gbWFwLnN1Yk1hcCgiQSIsIHRydWUsICJDIiwgdHJ1ZSk7CisKKyAgICAgICAgSXRlcmF0b3I8RW50cnk8U3RyaW5nLFN0cmluZz4+IGl0ZXJhdG9yID0gc3ViTWFwLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgICAgRW50cnk8U3RyaW5nLCBTdHJpbmc+IGVudHJ5QSA9IGl0ZXJhdG9yLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgZW50cnlBLnNldFZhbHVlKCJ4IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIngiLCBlbnRyeUEuZ2V0VmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieCIsIHN1Yk1hcC5nZXQoIkEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieCIsIG1hcC5nZXQoIkEiKSk7CisgICAgICAgIEVudHJ5PFN0cmluZywgU3RyaW5nPiBlbnRyeUIgPSBpdGVyYXRvci5uZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiYiIsIGVudHJ5Qi5zZXRWYWx1ZSgieSIpKTsKKyAgICAgICAgRW50cnk8U3RyaW5nLCBTdHJpbmc+IGVudHJ5QyA9IGl0ZXJhdG9yLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjIiwgZW50cnlDLnNldFZhbHVlKCJ6IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoInkiLCBlbnRyeUIuZ2V0VmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieSIsIHN1Yk1hcC5nZXQoIkIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieSIsIG1hcC5nZXQoIkIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieiIsIGVudHJ5Qy5nZXRWYWx1ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ6Iiwgc3ViTWFwLmdldCgiQyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ6IiwgbWFwLmdldCgiQyIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgYW4gRW50cnkgZ2l2ZW4gYnkgYW55IG1ldGhvZCBleGNlcHQgZW50cnlTZXQoKSBpcyBpbW11dGFibGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEV4Y2VwdGlvbnNPblNldFZhbHVlKCkgeworICAgICAgICBUcmVlTWFwPFN0cmluZywgU3RyaW5nPiBtYXAgPSBuZXcgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgbWFwLnB1dCgiQSIsICJhIik7CisgICAgICAgIG1hcC5wdXQoIkIiLCAiYiIpOworICAgICAgICBtYXAucHV0KCJDIiwgImMiKTsKKworICAgICAgICBhc3NlcnRBbGxFbnRyeU1ldGhvZHNSZXR1cm5JbW11dGFibGVFbnRyaWVzKG1hcCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IGFuIEVudHJ5IGdpdmVuIGJ5IGFueSBtZXRob2QgZXhjZXB0IGVudHJ5U2V0KCkgb2YgYSBzdWJtYXAgaXMgaW1tdXRhYmxlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFeGNlcHRpb25zT25TdWJNYXBTZXRWYWx1ZSgpIHsKKyAgICAgICAgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4gbWFwID0gbmV3IFRyZWVNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgICAgIG1hcC5wdXQoIkEiLCAiYSIpOworICAgICAgICBtYXAucHV0KCJCIiwgImIiKTsKKyAgICAgICAgbWFwLnB1dCgiQyIsICJjIik7CisgICAgICAgIG1hcC5wdXQoIkQiLCAiZCIpOworCisgICAgICAgIGFzc2VydEFsbEVudHJ5TWV0aG9kc1JldHVybkltbXV0YWJsZUVudHJpZXMobWFwLnN1Yk1hcCgiQSIsIHRydWUsICJDIiwgdHJ1ZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFzc2VydHMgdGhhdCBlYWNoIE5hdmlnYWJsZU1hcCBtZXRob2QgdGhhdCByZXR1cm5zIGFuIEVudHJ5IChleGNlcHQgZW50cnlTZXQoKSkgcmV0dXJucyBhbgorICAgICAqIGltbXV0YWJsZSBvbmUuIEFzc3VtZXMgdGhhdCB0aGUgbWFwIGNvbnRhaW5zIGF0IGxlYXN0IGVudHJpZXMgd2l0aCBrZXlzICJBIiwgIkIiIGFuZCAiQyIuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydEFsbEVudHJ5TWV0aG9kc1JldHVybkltbXV0YWJsZUVudHJpZXMoTmF2aWdhYmxlTWFwPFN0cmluZywgU3RyaW5nPiBtYXApIHsKKyAgICAgICAgYXNzZXJ0SW1tdXRhYmxlKG1hcC5jZWlsaW5nRW50cnkoIkIiKSk7CisgICAgICAgIGFzc2VydEltbXV0YWJsZShtYXAuZmlyc3RFbnRyeSgpKTsKKyAgICAgICAgYXNzZXJ0SW1tdXRhYmxlKG1hcC5mbG9vckVudHJ5KCJEIikpOworICAgICAgICBhc3NlcnRJbW11dGFibGUobWFwLmhpZ2hlckVudHJ5KCJBIikpOworICAgICAgICBhc3NlcnRJbW11dGFibGUobWFwLmxhc3RFbnRyeSgpKTsKKyAgICAgICAgYXNzZXJ0SW1tdXRhYmxlKG1hcC5sb3dlckVudHJ5KCJDIikpOworICAgICAgICBhc3NlcnRJbW11dGFibGUobWFwLnBvbGxGaXJzdEVudHJ5KCkpOworICAgICAgICBhc3NlcnRJbW11dGFibGUobWFwLnBvbGxMYXN0RW50cnkoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydEltbXV0YWJsZShFbnRyeTxTdHJpbmcsIFN0cmluZz4gZW50cnkpIHsKKyAgICAgICAgU3RyaW5nIGluaXRpYWxWYWx1ZSA9IGVudHJ5LmdldFZhbHVlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbnRyeS5zZXRWYWx1ZSgieCIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGluaXRpYWxWYWx1ZSwgZW50cnkuZ2V0VmFsdWUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbmN1cnJlbnRNb2RpZmljYXRpb25EZXRlY3Rpb24oKSB7CisgICAgICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gbWFwID0gbmV3IFRyZWVNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgICAgIG1hcC5wdXQoIkEiLCAiYSIpOworICAgICAgICBtYXAucHV0KCJCIiwgImIiKTsKKyAgICAgICAgbWFwLnB1dCgiQyIsICJjIik7CisgICAgICAgIEl0ZXJhdG9yPEVudHJ5PFN0cmluZyxTdHJpbmc+PiBpdGVyYXRvciA9IG1hcC5lbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgIGl0ZXJhdG9yLm5leHQoKTsKKyAgICAgICAgaXRlcmF0b3IubmV4dCgpOworICAgICAgICBpdGVyYXRvci5yZW1vdmUoKTsKKyAgICAgICAgbWFwLnB1dCgiRCIsICJkIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpdGVyYXRvci5uZXh0KCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEl0ZXJhdG9yUmVtb3ZlcygpIHsKKyAgICAgICAgTWFwPFN0cmluZywgU3RyaW5nPiBtYXAgPSBuZXcgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgbWFwLnB1dCgiQSIsICJhIik7CisgICAgICAgIG1hcC5wdXQoIkIiLCAiYiIpOworICAgICAgICBtYXAucHV0KCJDIiwgImMiKTsKKyAgICAgICAgSXRlcmF0b3I8RW50cnk8U3RyaW5nLFN0cmluZz4+IGl0ZXJhdG9yID0gbWFwLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgaXRlcmF0b3IubmV4dCgpLmdldEtleSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCIiwgaXRlcmF0b3IubmV4dCgpLmdldEtleSgpKTsKKyAgICAgICAgaXRlcmF0b3IucmVtb3ZlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQyIsIGl0ZXJhdG9yLm5leHQoKS5nZXRLZXkoKSk7CisgICAgICAgIGl0ZXJhdG9yLnJlbW92ZSgpOworICAgICAgICBhc3NlcnRGYWxzZShpdGVyYXRvci5oYXNOZXh0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBlbnRyeSBzZXQgY29udGFpbnMgYW5kIHJlbW92YWwgdXNlIHRoZSBjb21wYXJhdG9yIHJhdGhlciB0aGFuIGVxdWFscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW50cnlTZXRVc2VzQ29tcGFyYXRvck9ubHkoKSB7CisgICAgICAgIE1hcDxTdHJpbmcsU3RyaW5nPiBtYXAgPSBuZXcgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4oU3RyaW5nLkNBU0VfSU5TRU5TSVRJVkVfT1JERVIpOworICAgICAgICBtYXAucHV0KCJBQkMiLCAiYSIpOworICAgICAgICBhc3NlcnRUcnVlKG1hcC5lbnRyeVNldCgpLmNvbnRhaW5zKG5ldyBTaW1wbGVFbnRyeTxTdHJpbmcsIFN0cmluZz4oImFiYyIsICJhIikpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXAuZW50cnlTZXQoKS5yZW1vdmUobmV3IFNpbXBsZUVudHJ5PFN0cmluZywgU3RyaW5nPigiYWJjIiwgImEiKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbWFwLnNpemUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1hcENvbnN0cnVjdG9yUGFzc2luZ1NvcnRlZE1hcCgpIHsKKyAgICAgICAgTWFwPFN0cmluZyxTdHJpbmc+IHNvdXJjZSA9IG5ldyBUcmVlTWFwPFN0cmluZywgU3RyaW5nPihTdHJpbmcuQ0FTRV9JTlNFTlNJVElWRV9PUkRFUik7CisgICAgICAgIE5hdmlnYWJsZU1hcDxTdHJpbmcsU3RyaW5nPiBjb3B5ID0gbmV3IFRyZWVNYXA8U3RyaW5nLCBTdHJpbmc+KHNvdXJjZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBjb3B5LmNvbXBhcmF0b3IoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE51bGxzV2l0aE5hdHVyYWxPcmRlcigpIHsKKyAgICAgICAgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4gY29weUZyb20gPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgY29weUZyb20ucHV0KG51bGwsICJiIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4oY29weUZyb20pOworICAgICAgICAgICAgZmFpbCgpOyAvLyB0aGUgUkkgZG9lc24ndCB0aHJvdyBpZiBudWxsIGlzIHRoZSBvbmx5IGtleQorICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgVHJlZU1hcDxTdHJpbmcsU3RyaW5nPiBtYXAgPSBuZXcgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1hcC5wdXQobnVsbCwgImIiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1hcC5kZXNjZW5kaW5nTWFwKCkucHV0KG51bGwsICJiIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtYXAuc3ViTWFwKCJhIiwgInoiKS5wdXQobnVsbCwgImIiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENsYXNzQ2FzdEV4Y2VwdGlvbnMoKSB7CisgICAgICAgIE1hcDxPYmplY3QsIE9iamVjdD4gbWFwID0gbmV3IFRyZWVNYXA8T2JqZWN0LCBPYmplY3Q+KCk7CisgICAgICAgIG1hcC5wdXQoIkEiLCAiYSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWFwLmdldCg1KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbWFwLmNvbnRhaW5zS2V5KDUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtYXAucmVtb3ZlKDUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENsYXNzQ2FzdEV4Y2VwdGlvbnNPbkJvdW5kcygpIHsKKyAgICAgICAgTWFwPE9iamVjdCwgT2JqZWN0PiBtYXAgPSBuZXcgVHJlZU1hcDxPYmplY3QsIE9iamVjdD4oKS5zdWJNYXAoImEiLCAieiIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWFwLmdldCg1KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbWFwLmNvbnRhaW5zS2V5KDUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtYXAucmVtb3ZlKDUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENsb25lKCkgeworICAgICAgICBUcmVlTWFwPFN0cmluZywgU3RyaW5nPiBtYXAgPSBuZXcgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4oKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gIng6IiArIHN1cGVyLnRvU3RyaW5nKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgbWFwLnB1dCgiQSIsICJhIik7CisgICAgICAgIG1hcC5wdXQoIkIiLCAiYiIpOworCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICBUcmVlTWFwPFN0cmluZywgU3RyaW5nPiBjbG9uZSA9IChUcmVlTWFwPFN0cmluZywgU3RyaW5nPikgbWFwLmNsb25lKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhtYXAuZ2V0Q2xhc3MoKSwgY2xvbmUuZ2V0Q2xhc3MoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieDp7QT1hLCBCPWJ9IiwgbWFwLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eU1hcFNlcmlhbGl6YXRpb24oKSB7CisgICAgICAgIFN0cmluZyBzID0gImFjZWQwMDA1NzM3MjAwMTE2YTYxNzY2MTJlNzU3NDY5NmMyZTU0NzI2NTY1NGQ2MTcwMGNjMWY2M2UyZDI1NmEiCisgICAgICAgICAgICAgICAgKyAiZTYwMzAwMDE0YzAwMGE2MzZmNmQ3MDYxNzI2MTc0NmY3Mjc0MDAxNjRjNmE2MTc2NjEyZjc1NzQ2OTZjMmY0MzYiCisgICAgICAgICAgICAgICAgKyAiZjZkNzA2MTcyNjE3NDZmNzIzYjc4NzA3MDc3MDQwMDAwMDAwMDc4IjsKKyAgICAgICAgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4gbWFwID0gbmV3IFRyZWVNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgICAgIG5ldyBTZXJpYWxpemFibGVUZXN0ZXI8VHJlZU1hcDxTdHJpbmcsIFN0cmluZz4+KG1hcCwgcykudGVzdCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemF0aW9uV2l0aENvbXBhcmF0b3IoKSB7CisgICAgICAgIFN0cmluZyBzID0gImFjZWQwMDA1NzM3MjAwMTE2YTYxNzY2MTJlNzU3NDY5NmMyZTU0NzI2NTY1NGQ2MTcwMGNjMWY2M2UyZDI1NmEiCisgICAgICAgICAgICAgICAgKyAiZTYwMzAwMDE0YzAwMGE2MzZmNmQ3MDYxNzI2MTc0NmY3Mjc0MDAxNjRjNmE2MTc2NjEyZjc1NzQ2OTZjMmY0MzYiCisgICAgICAgICAgICAgICAgKyAiZjZkNzA2MTcyNjE3NDZmNzIzYjc4NzA3MzcyMDAyYTZhNjE3NjYxMmU2YzYxNmU2NzJlNTM3NDcyNjk2ZTY3MjQiCisgICAgICAgICAgICAgICAgKyAiNDM2MTczNjU0OTZlNzM2NTZlNzM2OTc0Njk3NjY1NDM2ZjZkNzA2MTcyNjE3NDZmNzI3NzAzNWM3ZDVjNTBlNWMiCisgICAgICAgICAgICAgICAgKyAiZTAyMDAwMDc4NzA3NzA0MDAwMDAwMDI3NDAwMDE2MTcxMDA3ZTAwMDU3NDAwMDE2MjcxMDA3ZTAwMDY3OCI7CisgICAgICAgIFRyZWVNYXA8U3RyaW5nLFN0cmluZz4gbWFwID0gbmV3IFRyZWVNYXA8U3RyaW5nLCBTdHJpbmc+KAorICAgICAgICAgICAgICAgIFN0cmluZy5DQVNFX0lOU0VOU0lUSVZFX09SREVSKTsKKyAgICAgICAgbWFwLnB1dCgiYSIsICJhIik7CisgICAgICAgIG1hcC5wdXQoImIiLCAiYiIpOworICAgICAgICBuZXcgU2VyaWFsaXphYmxlVGVzdGVyPE5hdmlnYWJsZU1hcDxTdHJpbmcsIFN0cmluZz4+KG1hcCwgcykgeworICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIHZlcmlmeShOYXZpZ2FibGVNYXA8U3RyaW5nLCBTdHJpbmc+IGRlc2VyaWFsaXplZCkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBkZXNlcmlhbGl6ZWQuY29tcGFyYXRvcigpLmNvbXBhcmUoIlgiLCAieCIpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfS50ZXN0KCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN1Ym1hcFNlcmlhbGl6YXRpb24oKSB7CisgICAgICAgIFN0cmluZyBzID0gImFjZWQwMDA1NzM3MjAwMjE2YTYxNzY2MTJlNzU3NDY5NmMyZTU0NzI2NTY1NGQ2MTcwMjQ0MTczNjM2NTZlNjQ2IgorICAgICAgICAgICAgICAgICsgIjk2ZTY3NTM3NTYyNGQ2MTcwMGNhYjk0NmQxZjBmYWIxYzAyMDAwMDc4NzIwMDIxNmE2MTc2NjEyZTc1NzQ2OTZjMiIKKyAgICAgICAgICAgICAgICArICJlNTQ3MjY1NjU0ZDYxNzAyNDRlNjE3NjY5Njc2MTYyNmM2NTUzNzU2MjRkNjE3MGUyZDBhNzBlNjQyMTBlMDgwMjAiCisgICAgICAgICAgICAgICAgKyAiMDA3NWEwMDA5NjY3MjZmNmQ1Mzc0NjE3Mjc0NWEwMDBiNjg2OTQ5NmU2MzZjNzU3MzY5NzY2NTVhMDAwYjZjNmY0IgorICAgICAgICAgICAgICAgICsgIjk2ZTYzNmM3NTczNjk3NjY1NWEwMDA1NzQ2ZjQ1NmU2NDRjMDAwMjY4Njk3NDAwMTI0YzZhNjE3NjYxMmY2YzYxNiIKKyAgICAgICAgICAgICAgICArICJlNjcyZjRmNjI2YTY1NjM3NDNiNGMwMDAyNmM2ZjcxMDA3ZTAwMDI0YzAwMDE2ZDc0MDAxMzRjNmE2MTc2NjEyZjciCisgICAgICAgICAgICAgICAgKyAiNTc0Njk2YzJmNTQ3MjY1NjU0ZDYxNzAzYjc4NzAwMDAwMDEwMDc0MDAwMTYzNzQwMDAxNjE3MzcyMDAxMTZhNjE3IgorICAgICAgICAgICAgICAgICsgIjY2MTJlNzU3NDY5NmMyZTU0NzI2NTY1NGQ2MTcwMGNjMWY2M2UyZDI1NmFlNjAzMDAwMTRjMDAwYTYzNmY2ZDcwNiIKKyAgICAgICAgICAgICAgICArICIxNzI2MTc0NmY3Mjc0MDAxNjRjNmE2MTc2NjEyZjc1NzQ2OTZjMmY0MzZmNmQ3MDYxNzI2MTc0NmY3MjNiNzg3MDciCisgICAgICAgICAgICAgICAgKyAiMzcyMDAyYTZhNjE3NjYxMmU2YzYxNmU2NzJlNTM3NDcyNjk2ZTY3MjQ0MzYxNzM2NTQ5NmU3MzY1NmU3MzY5NzQ2IgorICAgICAgICAgICAgICAgICsgIjk3NjY1NDM2ZjZkNzA2MTcyNjE3NDZmNzI3NzAzNWM3ZDVjNTBlNWNlMDIwMDAwNzg3MDc3MDQwMDAwMDAwNDcxMCIKKyAgICAgICAgICAgICAgICArICIwN2UwMDA2NzEwMDdlMDAwNjc0MDAwMTYyNzEwMDdlMDAwYzcxMDA3ZTAwMDU3MTAwN2UwMDA1NzQwMDAxNjQ3MTAiCisgICAgICAgICAgICAgICAgKyAiMDdlMDAwZDc4IjsKKyAgICAgICAgVHJlZU1hcDxTdHJpbmcsU3RyaW5nPiBtYXAgPSBuZXcgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4oCisgICAgICAgICAgICAgICAgU3RyaW5nLkNBU0VfSU5TRU5TSVRJVkVfT1JERVIpOworICAgICAgICBtYXAucHV0KCJhIiwgImEiKTsKKyAgICAgICAgbWFwLnB1dCgiYiIsICJiIik7CisgICAgICAgIG1hcC5wdXQoImMiLCAiYyIpOworICAgICAgICBtYXAucHV0KCJkIiwgImQiKTsKKyAgICAgICAgU29ydGVkTWFwPFN0cmluZywgU3RyaW5nPiBzdWJtYXAgPSBtYXAuc3ViTWFwKCJhIiwgImMiKTsKKyAgICAgICAgbmV3IFNlcmlhbGl6YWJsZVRlc3RlcjxTb3J0ZWRNYXA8U3RyaW5nLCBTdHJpbmc+PihzdWJtYXAsIHMpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCB2ZXJpZnkoU29ydGVkTWFwPFN0cmluZywgU3RyaW5nPiBkZXNlcmlhbGl6ZWQpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBkZXNlcmlhbGl6ZWQucHV0KCJlIiwgImUiKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9LnRlc3QoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmF2aWdhYmxlU3VibWFwU2VyaWFsaXphdGlvbigpIHsKKyAgICAgICAgU3RyaW5nIHMgPSAiYWNlZDAwMDU3MzcyMDAyMTZhNjE3NjYxMmU3NTc0Njk2YzJlNTQ3MjY1NjU0ZDYxNzAyNDQxNzM2MzY1NmU2NDYiCisgICAgICAgICAgICAgICAgKyAiOTZlNjc1Mzc1NjI0ZDYxNzAwY2FiOTQ2ZDFmMGZhYjFjMDIwMDAwNzg3MjAwMjE2YTYxNzY2MTJlNzU3NDY5NmMyIgorICAgICAgICAgICAgICAgICsgImU1NDcyNjU2NTRkNjE3MDI0NGU2MTc2Njk2NzYxNjI2YzY1NTM3NTYyNGQ2MTcwZTJkMGE3MGU2NDIxMGUwODAyMCIKKyAgICAgICAgICAgICAgICArICIwMDc1YTAwMDk2NjcyNmY2ZDUzNzQ2MTcyNzQ1YTAwMGI2ODY5NDk2ZTYzNmM3NTczNjk3NjY1NWEwMDBiNmM2ZjQiCisgICAgICAgICAgICAgICAgKyAiOTZlNjM2Yzc1NzM2OTc2NjU1YTAwMDU3NDZmNDU2ZTY0NGMwMDAyNjg2OTc0MDAxMjRjNmE2MTc2NjEyZjZjNjE2IgorICAgICAgICAgICAgICAgICsgImU2NzJmNGY2MjZhNjU2Mzc0M2I0YzAwMDI2YzZmNzEwMDdlMDAwMjRjMDAwMTZkNzQwMDEzNGM2YTYxNzY2MTJmNyIKKyAgICAgICAgICAgICAgICArICI1NzQ2OTZjMmY1NDcyNjU2NTRkNjE3MDNiNzg3MDAwMDEwMDAwNzQwMDAxNjM3NDAwMDE2MTczNzIwMDExNmE2MTciCisgICAgICAgICAgICAgICAgKyAiNjYxMmU3NTc0Njk2YzJlNTQ3MjY1NjU0ZDYxNzAwY2MxZjYzZTJkMjU2YWU2MDMwMDAxNGMwMDBhNjM2ZjZkNzA2IgorICAgICAgICAgICAgICAgICsgIjE3MjYxNzQ2ZjcyNzQwMDE2NGM2YTYxNzY2MTJmNzU3NDY5NmMyZjQzNmY2ZDcwNjE3MjYxNzQ2ZjcyM2I3ODcwNyIKKyAgICAgICAgICAgICAgICArICIzNzIwMDJhNmE2MTc2NjEyZTZjNjE2ZTY3MmU1Mzc0NzI2OTZlNjcyNDQzNjE3MzY1NDk2ZTczNjU2ZTczNjk3NDYiCisgICAgICAgICAgICAgICAgKyAiOTc2NjU0MzZmNmQ3MDYxNzI2MTc0NmY3Mjc3MDM1YzdkNWM1MGU1Y2UwMjAwMDA3ODcwNzcwNDAwMDAwMDA0NzEwIgorICAgICAgICAgICAgICAgICsgIjA3ZTAwMDY3MTAwN2UwMDA2NzQwMDAxNjI3MTAwN2UwMDBjNzEwMDdlMDAwNTcxMDA3ZTAwMDU3NDAwMDE2NDcxMCIKKyAgICAgICAgICAgICAgICArICIwN2UwMDBkNzgiOworICAgICAgICBUcmVlTWFwPFN0cmluZyxTdHJpbmc+IG1hcCA9IG5ldyBUcmVlTWFwPFN0cmluZywgU3RyaW5nPigKKyAgICAgICAgICAgICAgICBTdHJpbmcuQ0FTRV9JTlNFTlNJVElWRV9PUkRFUik7CisgICAgICAgIG1hcC5wdXQoImEiLCAiYSIpOworICAgICAgICBtYXAucHV0KCJiIiwgImIiKTsKKyAgICAgICAgbWFwLnB1dCgiYyIsICJjIik7CisgICAgICAgIG1hcC5wdXQoImQiLCAiZCIpOworICAgICAgICBTb3J0ZWRNYXA8U3RyaW5nLCBTdHJpbmc+IHN1Ym1hcCA9IG1hcC5zdWJNYXAoImEiLCBmYWxzZSwgImMiLCB0cnVlKTsKKyAgICAgICAgbmV3IFNlcmlhbGl6YWJsZVRlc3RlcjxTb3J0ZWRNYXA8U3RyaW5nLCBTdHJpbmc+PihzdWJtYXAsIHMpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCB2ZXJpZnkoU29ydGVkTWFwPFN0cmluZywgU3RyaW5nPiBkZXNlcmlhbGl6ZWQpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBkZXNlcmlhbGl6ZWQucHV0KCJlIiwgImUiKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9LnRlc3QoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVzY2VuZGluZ01hcFNlcmlhbGl6YXRpb24oKSB7CisgICAgICAgIFN0cmluZyBzID0gImFjZWQwMDA1NzM3MjAwMjI2YTYxNzY2MTJlNzU3NDY5NmMyZTU0NzI2NTY1NGQ2MTcwMjQ0NDY1NzM2MzY1NmU2IgorICAgICAgICAgICAgICAgICsgIjQ2OTZlNjc1Mzc1NjI0ZDYxNzAwY2FiOTQ2ZDFmMGY5ZDBjMDIwMDAxNGMwMDExNzI2NTc2NjU3MjczNjU0MzZmNiIKKyAgICAgICAgICAgICAgICArICJkNzA2MTcyNjE3NDZmNzI3NDAwMTY0YzZhNjE3NjYxMmY3NTc0Njk2YzJmNDM2ZjZkNzA2MTcyNjE3NDZmNzIzYjciCisgICAgICAgICAgICAgICAgKyAiODcyMDAyMTZhNjE3NjYxMmU3NTc0Njk2YzJlNTQ3MjY1NjU0ZDYxNzAyNDRlNjE3NjY5Njc2MTYyNmM2NTUzNzU2IgorICAgICAgICAgICAgICAgICsgIjI0ZDYxNzBlMmQwYTcwZTY0MjEwZTA4MDIwMDA3NWEwMDA5NjY3MjZmNmQ1Mzc0NjE3Mjc0NWEwMDBiNjg2OTQ5NiIKKyAgICAgICAgICAgICAgICArICJlNjM2Yzc1NzM2OTc2NjU1YTAwMGI2YzZmNDk2ZTYzNmM3NTczNjk3NjY1NWEwMDA1NzQ2ZjQ1NmU2NDRjMDAwMjYiCisgICAgICAgICAgICAgICAgKyAiODY5NzQwMDEyNGM2YTYxNzY2MTJmNmM2MTZlNjcyZjRmNjI2YTY1NjM3NDNiNGMwMDAyNmM2ZjcxMDA3ZTAwMDM0IgorICAgICAgICAgICAgICAgICsgImMwMDAxNmQ3NDAwMTM0YzZhNjE3NjYxMmY3NTc0Njk2YzJmNTQ3MjY1NjU0ZDYxNzAzYjc4NzAwMTAxMDEwMTcwNyIKKyAgICAgICAgICAgICAgICArICIwNzM3MjAwMTE2YTYxNzY2MTJlNzU3NDY5NmMyZTU0NzI2NTY1NGQ2MTcwMGNjMWY2M2UyZDI1NmFlNjAzMDAwMTQiCisgICAgICAgICAgICAgICAgKyAiYzAwMGE2MzZmNmQ3MDYxNzI2MTc0NmY3MjcxMDA3ZTAwMDE3ODcwNzM3MjAwMmE2YTYxNzY2MTJlNmM2MTZlNjcyIgorICAgICAgICAgICAgICAgICsgImU1Mzc0NzI2OTZlNjcyNDQzNjE3MzY1NDk2ZTczNjU2ZTczNjk3NDY5NzY2NTQzNmY2ZDcwNjE3MjYxNzQ2ZjcyNyIKKyAgICAgICAgICAgICAgICArICI3MDM1YzdkNWM1MGU1Y2UwMjAwMDA3ODcwNzcwNDAwMDAwMDAyNzQwMDAxNjE3MTAwN2UwMDBhNzQwMDAxNjI3MTAiCisgICAgICAgICAgICAgICAgKyAiMDdlMDAwYjc4NzM3MjAwMjg2YTYxNzY2MTJlNzU3NDY5NmMyZTQzNmY2YzZjNjU2Mzc0Njk2ZjZlNzMyNDUyNjU3IgorICAgICAgICAgICAgICAgICsgIjY2NTcyNzM2NTQzNmY2ZDcwNjE3MjYxNzQ2ZjcyMzIwMDAwMDNmYTZjMzU0ZDUxMDIwMDAxNGMwMDAzNjM2ZDcwNyIKKyAgICAgICAgICAgICAgICArICIxMDA3ZTAwMDE3ODcwNzEwMDdlMDAwOSI7CisgICAgICAgIFRyZWVNYXA8U3RyaW5nLFN0cmluZz4gbWFwID0gbmV3IFRyZWVNYXA8U3RyaW5nLCBTdHJpbmc+KAorICAgICAgICAgICAgICAgIFN0cmluZy5DQVNFX0lOU0VOU0lUSVZFX09SREVSKTsKKyAgICAgICAgbWFwLnB1dCgiYSIsICJhIik7CisgICAgICAgIG1hcC5wdXQoImIiLCAiYiIpOworICAgICAgICBOYXZpZ2FibGVNYXA8U3RyaW5nLCBTdHJpbmc+IGRlc2NlbmRpbmdNYXAgPSBtYXAuZGVzY2VuZGluZ01hcCgpOworICAgICAgICBuZXcgU2VyaWFsaXphYmxlVGVzdGVyPE5hdmlnYWJsZU1hcDxTdHJpbmcsIFN0cmluZz4+KGRlc2NlbmRpbmdNYXAsIHMpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCB2ZXJpZnkoTmF2aWdhYmxlTWFwPFN0cmluZywgU3RyaW5nPiBkZXNlcmlhbGl6ZWQpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImIiLCBkZXNlcmlhbGl6ZWQubmF2aWdhYmxlS2V5U2V0KCkuZmlyc3QoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0udGVzdCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RKYXZhNVNlcmlhbGl6YXRpb25XaXRoQ29tcGFyYXRvcigpIHsKKyAgICAgICAgU3RyaW5nIHMgPSAiYWNlZDAwMDU3MzcyMDAxMTZhNjE3NjYxMmU3NTc0Njk2YzJlNTQ3MjY1NjU0ZDYxNzAwY2MxZjYzZTJkMjU2YSIKKyAgICAgICAgICAgICAgICArICJlNjAzMDAwMTRjMDAwYTYzNmY2ZDcwNjE3MjYxNzQ2ZjcyNzQwMDE2NGM2YTYxNzY2MTJmNzU3NDY5NmMyZjQzNiIKKyAgICAgICAgICAgICAgICArICJmNmQ3MDYxNzI2MTc0NmY3MjNiNzg3MDczNzIwMDJhNmE2MTc2NjEyZTZjNjE2ZTY3MmU1Mzc0NzI2OTZlNjcyNCIKKyAgICAgICAgICAgICAgICArICI0MzYxNzM2NTQ5NmU3MzY1NmU3MzY5NzQ2OTc2NjU0MzZmNmQ3MDYxNzI2MTc0NmY3Mjc3MDM1YzdkNWM1MGU1YyIKKyAgICAgICAgICAgICAgICArICJlMDIwMDAwNzg3MDc3MDQwMDAwMDAwMjc0MDAwMTYxNzEwMDdlMDAwNTc0MDAwMTYyNzEwMDdlMDAwNjc4IjsKKyAgICAgICAgVHJlZU1hcDxTdHJpbmcsU3RyaW5nPiBtYXAgPSBuZXcgVHJlZU1hcDxTdHJpbmcsIFN0cmluZz4oCisgICAgICAgICAgICAgICAgU3RyaW5nLkNBU0VfSU5TRU5TSVRJVkVfT1JERVIpOworICAgICAgICBtYXAucHV0KCJhIiwgImEiKTsKKyAgICAgICAgbWFwLnB1dCgiYiIsICJiIik7CisgICAgICAgIG5ldyBTZXJpYWxpemFibGVUZXN0ZXI8VHJlZU1hcDxTdHJpbmcsIFN0cmluZz4+KG1hcCwgcykgeworICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIHZlcmlmeShUcmVlTWFwPFN0cmluZywgU3RyaW5nPiBkZXNlcmlhbGl6ZWQpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZGVzZXJpYWxpemVkLmNvbXBhcmF0b3IoKS5jb21wYXJlKCJYIiwgIngiKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0udGVzdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE9uIEpESzUsIHRoaXMgZmFpbHMgd2l0aCBhIE51bGxQb2ludGVyRXhjZXB0aW9uIGFmdGVyIGRlc2VyaWFsaXphdGlvbiEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SmF2YTVTdWJtYXBTZXJpYWxpemF0aW9uKCkgeworICAgICAgICBTdHJpbmcgcyA9ICJhY2VkMDAwNTczNzIwMDE4NmE2MTc2NjEyZTc1NzQ2OTZjMmU1NDcyNjU2NTRkNjE3MDI0NTM3NTYyNGQ2MTcwIgorICAgICAgICAgICAgICAgICsgImE1ODE4MzQzYTIxM2MyN2YwMjAwMDU1YTAwMDk2NjcyNmY2ZDUzNzQ2MTcyNzQ1YTAwMDU3NDZmNDU2ZTY0NGMwIgorICAgICAgICAgICAgICAgICsgIjAwNzY2NzI2ZjZkNGI2NTc5NzQwMDEyNGM2YTYxNzY2MTJmNmM2MTZlNjcyZjRmNjI2YTY1NjM3NDNiNGMwMDA2IgorICAgICAgICAgICAgICAgICsgIjc0Njg2OTczMjQzMDc0MDAxMzRjNmE2MTc2NjEyZjc1NzQ2OTZjMmY1NDcyNjU2NTRkNjE3MDNiNGMwMDA1NzQ2IgorICAgICAgICAgICAgICAgICsgImY0YjY1Nzk3MTAwN2UwMDAxNzg3MDAwMDA3NDAwMDE2MTczNzIwMDExNmE2MTc2NjEyZTc1NzQ2OTZjMmU1NDcyIgorICAgICAgICAgICAgICAgICsgIjY1NjU0ZDYxNzAwY2MxZjYzZTJkMjU2YWU2MDMwMDAxNGMwMDBhNjM2ZjZkNzA2MTcyNjE3NDZmNzI3NDAwMTY0IgorICAgICAgICAgICAgICAgICsgImM2YTYxNzY2MTJmNzU3NDY5NmMyZjQzNmY2ZDcwNjE3MjYxNzQ2ZjcyM2I3ODcwNzM3MjAwMmE2YTYxNzY2MTJlIgorICAgICAgICAgICAgICAgICsgIjZjNjE2ZTY3MmU1Mzc0NzI2OTZlNjcyNDQzNjE3MzY1NDk2ZTczNjU2ZTczNjk3NDY5NzY2NTQzNmY2ZDcwNjE3IgorICAgICAgICAgICAgICAgICsgIjI2MTc0NmY3Mjc3MDM1YzdkNWM1MGU1Y2UwMjAwMDA3ODcwNzcwNDAwMDAwMDA0NzEwMDdlMDAwNDcxMDA3ZTAwIgorICAgICAgICAgICAgICAgICsgIjA0NzQwMDAxNjI3MTAwN2UwMDBhNzQwMDAxNjM3MTAwN2UwMDBiNzQwMDAxNjQ3MTAwN2UwMDBjNzg3MTAwN2UwIgorICAgICAgICAgICAgICAgICsgIjAwYiI7CisgICAgICAgIFRyZWVNYXA8U3RyaW5nLFN0cmluZz4gbWFwID0gbmV3IFRyZWVNYXA8U3RyaW5nLCBTdHJpbmc+KFN0cmluZy5DQVNFX0lOU0VOU0lUSVZFX09SREVSKTsKKyAgICAgICAgbWFwLnB1dCgiYSIsICJhIik7CisgICAgICAgIG1hcC5wdXQoImIiLCAiYiIpOworICAgICAgICBtYXAucHV0KCJjIiwgImMiKTsKKyAgICAgICAgbWFwLnB1dCgiZCIsICJkIik7CisgICAgICAgIFNvcnRlZE1hcDxTdHJpbmcsIFN0cmluZz4gc3VibWFwID0gbWFwLnN1Yk1hcCgiYSIsICJjIik7CisgICAgICAgIG5ldyBTZXJpYWxpemFibGVUZXN0ZXI8U29ydGVkTWFwPFN0cmluZywgU3RyaW5nPj4oc3VibWFwLCBzKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgdmVyaWZ5KFNvcnRlZE1hcDxTdHJpbmcsIFN0cmluZz4gZGVzZXJpYWxpemVkKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZGVzZXJpYWxpemVkLnB1dCgiZSIsICJlIik7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfS50ZXN0KCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2JlYW5zL1Byb3BlcnR5Q2hhbmdlU3VwcG9ydFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9iZWFucy9Qcm9wZXJ0eUNoYW5nZVN1cHBvcnRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGM5ZDg4ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9iZWFucy9Qcm9wZXJ0eUNoYW5nZVN1cHBvcnRUZXN0LmphdmEKQEAgLTAsMCArMSwyODYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgR29vZ2xlIEluYy4KKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWwuYmVhbnM7CisKK2ltcG9ydCBqYXZhLmJlYW5zLlByb3BlcnR5Q2hhbmdlRXZlbnQ7CitpbXBvcnQgamF2YS5iZWFucy5Qcm9wZXJ0eUNoYW5nZUxpc3RlbmVyOworaW1wb3J0IGphdmEuYmVhbnMuUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5OworaW1wb3J0IGphdmEuYmVhbnMuUHJvcGVydHlDaGFuZ2VTdXBwb3J0OworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGxpYmNvcmUuamF2YS51dGlsLlNlcmlhbGl6YWJsZVRlc3RlcjsKKworcHVibGljIGZpbmFsIGNsYXNzIFByb3BlcnR5Q2hhbmdlU3VwcG9ydFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T2xkQW5kTmV3QXJlQm90aE51bGwoKSB7CisgICAgICAgIE9iamVjdCBiZWFuID0gbmV3IE9iamVjdCgpOworICAgICAgICBQcm9wZXJ0eUNoYW5nZVN1cHBvcnQgc3VwcG9ydCA9IG5ldyBQcm9wZXJ0eUNoYW5nZVN1cHBvcnQoYmVhbik7CisgICAgICAgIEV2ZW50TG9nIGxpc3RlbmVyID0gbmV3IEV2ZW50TG9nKCk7CisgICAgICAgIHN1cHBvcnQuYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihsaXN0ZW5lcik7CisKKyAgICAgICAgUHJvcGVydHlDaGFuZ2VFdmVudCBudWxsVG9OdWxsID0gbmV3IFByb3BlcnR5Q2hhbmdlRXZlbnQoYmVhbiwgImEiLCBudWxsLCBudWxsKTsKKyAgICAgICAgc3VwcG9ydC5maXJlUHJvcGVydHlDaGFuZ2UobnVsbFRvTnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuPFByb3BlcnR5Q2hhbmdlRXZlbnQ+YXNMaXN0KG51bGxUb051bGwpLCBsaXN0ZW5lci5sb2cpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RPbGRBbmROZXdBcmVUaGVTYW1lKCkgeworICAgICAgICBPYmplY3QgYmVhbiA9IG5ldyBPYmplY3QoKTsKKyAgICAgICAgUHJvcGVydHlDaGFuZ2VTdXBwb3J0IHN1cHBvcnQgPSBuZXcgUHJvcGVydHlDaGFuZ2VTdXBwb3J0KGJlYW4pOworICAgICAgICBFdmVudExvZyBsaXN0ZW5lciA9IG5ldyBFdmVudExvZygpOworICAgICAgICBzdXBwb3J0LmFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIobGlzdGVuZXIpOworCisgICAgICAgIFByb3BlcnR5Q2hhbmdlRXZlbnQgeFRvWCA9IG5ldyBQcm9wZXJ0eUNoYW5nZUV2ZW50KGJlYW4sICJhIiwgIngiLCBuZXcgU3RyaW5nKCJ4IikpOworICAgICAgICBzdXBwb3J0LmZpcmVQcm9wZXJ0eUNoYW5nZSh4VG9YKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy48UHJvcGVydHlDaGFuZ2VFdmVudD5hc0xpc3QoKSwgbGlzdGVuZXIubG9nKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXZlbnRzRmlsdGVyZWRCeVByb3hpZXMoKSB7CisgICAgICAgIE9iamVjdCBiZWFuID0gbmV3IE9iamVjdCgpOworICAgICAgICBQcm9wZXJ0eUNoYW5nZUV2ZW50IGV2ZW50QSA9IG5ldyBQcm9wZXJ0eUNoYW5nZUV2ZW50KGJlYW4sICJhIiwgZmFsc2UsIHRydWUpOworICAgICAgICBQcm9wZXJ0eUNoYW5nZUV2ZW50IGV2ZW50QiA9IG5ldyBQcm9wZXJ0eUNoYW5nZUV2ZW50KGJlYW4sICJiIiwgZmFsc2UsIHRydWUpOworICAgICAgICBQcm9wZXJ0eUNoYW5nZUV2ZW50IGV2ZW50QyA9IG5ldyBQcm9wZXJ0eUNoYW5nZUV2ZW50KGJlYW4sICJjIiwgZmFsc2UsIHRydWUpOworCisgICAgICAgIFByb3BlcnR5Q2hhbmdlU3VwcG9ydCBzdXBwb3J0ID0gbmV3IFByb3BlcnR5Q2hhbmdlU3VwcG9ydChiZWFuKTsKKworICAgICAgICBFdmVudExvZyBhbGwgPSBuZXcgRXZlbnRMb2coKTsKKyAgICAgICAgc3VwcG9ydC5hZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKGFsbCk7CisKKyAgICAgICAgRXZlbnRMb2cgcHJveGllZEEgPSBuZXcgRXZlbnRMb2coKTsKKyAgICAgICAgc3VwcG9ydC5hZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKG5ldyBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkoImEiLCBwcm94aWVkQSkpOworCisgICAgICAgIEV2ZW50TG9nIGFkZEEgPSBuZXcgRXZlbnRMb2coKTsKKyAgICAgICAgc3VwcG9ydC5hZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKCJhIiwgYWRkQSk7CisKKyAgICAgICAgRXZlbnRMb2cgYWRkQVByb3hpZWRCID0gbmV3IEV2ZW50TG9nKCk7CisgICAgICAgIHN1cHBvcnQuYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcigiYSIsIG5ldyBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkoImIiLCBhZGRBUHJveGllZEIpKTsKKworICAgICAgICBFdmVudExvZyBwcm94aWVkQUIgPSBuZXcgRXZlbnRMb2coKTsKKyAgICAgICAgc3VwcG9ydC5hZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKG5ldyBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkoCisgICAgICAgICAgICAgICAgImEiLCBuZXcgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5KCJiIiwgcHJveGllZEFCKSkpOworCisgICAgICAgIEV2ZW50TG9nIHByb3hpZWRBQSA9IG5ldyBFdmVudExvZygpOworICAgICAgICBzdXBwb3J0LmFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIobmV3IFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSgiYSIsCisgICAgICAgICAgICAgICAgbmV3IFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSgiYSIsIHByb3hpZWRBQSkpKTsKKworICAgICAgICBFdmVudExvZyBwcm94aWVkQUFDID0gbmV3IEV2ZW50TG9nKCk7CisgICAgICAgIHN1cHBvcnQuYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihuZXcgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5KCJhIiwKKyAgICAgICAgICAgICAgICBuZXcgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5KCJhIiwKKyAgICAgICAgICAgICAgICBuZXcgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5KCJjIiwgcHJveGllZEFBQykpKSk7CisKKyAgICAgICAgc3VwcG9ydC5maXJlUHJvcGVydHlDaGFuZ2UoZXZlbnRBKTsKKyAgICAgICAgc3VwcG9ydC5maXJlUHJvcGVydHlDaGFuZ2UoZXZlbnRCKTsKKyAgICAgICAgc3VwcG9ydC5maXJlUHJvcGVydHlDaGFuZ2UoZXZlbnRDKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChldmVudEEsIGV2ZW50QiwgZXZlbnRDKSwgYWxsLmxvZyk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KGV2ZW50QSksIHByb3hpZWRBLmxvZyk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KGV2ZW50QSksIGFkZEEubG9nKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy48UHJvcGVydHlDaGFuZ2VFdmVudD5hc0xpc3QoKSwgYWRkQVByb3hpZWRCLmxvZyk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuPFByb3BlcnR5Q2hhbmdlRXZlbnQ+YXNMaXN0KCksIHByb3hpZWRBQi5sb2cpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLjxQcm9wZXJ0eUNoYW5nZUV2ZW50PmFzTGlzdChldmVudEEpLCBwcm94aWVkQUEubG9nKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy48UHJvcGVydHlDaGFuZ2VFdmVudD5hc0xpc3QoKSwgcHJveGllZEFBQy5sb2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCB3ZSBuZWVkIHRvIGRvIG91ciBvd24gZXF1YWxzKCkgd29yayB0byBtYW51YWxseSB1bndyYXAgYW4KKyAgICAgKiBhcmJpdHJhcnkgbnVtYmVyIG9mIHByb3hpZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZVdpdGhQcm94aWVzKCkgeworICAgICAgICBPYmplY3QgYmVhbiA9IG5ldyBPYmplY3QoKTsKKyAgICAgICAgUHJvcGVydHlDaGFuZ2VTdXBwb3J0IHN1cHBvcnQgPSBuZXcgUHJvcGVydHlDaGFuZ2VTdXBwb3J0KGJlYW4pOworCisgICAgICAgIEV2ZW50TG9nIGFsbCA9IG5ldyBFdmVudExvZygpOworICAgICAgICBzdXBwb3J0LmFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoYWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHN1cHBvcnQuZ2V0UHJvcGVydHlDaGFuZ2VMaXN0ZW5lcnMoKS5sZW5ndGgpOworCisgICAgICAgIEV2ZW50TG9nIHByb3hpZWRBID0gbmV3IEV2ZW50TG9nKCk7CisgICAgICAgIHN1cHBvcnQuYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihuZXcgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5KCJhIiwgcHJveGllZEEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHN1cHBvcnQuZ2V0UHJvcGVydHlDaGFuZ2VMaXN0ZW5lcnMoKS5sZW5ndGgpOworCisgICAgICAgIEV2ZW50TG9nIGFkZEEgPSBuZXcgRXZlbnRMb2coKTsKKyAgICAgICAgc3VwcG9ydC5hZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKCJhIiwgYWRkQSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBzdXBwb3J0LmdldFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJzKCkubGVuZ3RoKTsKKworICAgICAgICBFdmVudExvZyBhZGRBUHJveGllZEIgPSBuZXcgRXZlbnRMb2coKTsKKyAgICAgICAgc3VwcG9ydC5hZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKCJhIiwgbmV3IFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSgiYiIsIGFkZEFQcm94aWVkQikpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgc3VwcG9ydC5nZXRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVycygpLmxlbmd0aCk7CisKKyAgICAgICAgRXZlbnRMb2cgcHJveGllZEFCID0gbmV3IEV2ZW50TG9nKCk7CisgICAgICAgIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSBwcm94eUFCID0gbmV3IFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSgKKyAgICAgICAgICAgICAgICAiYSIsIG5ldyBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkoImIiLCBwcm94aWVkQUIpKTsKKyAgICAgICAgc3VwcG9ydC5hZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKHByb3h5QUIpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgc3VwcG9ydC5nZXRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVycygpLmxlbmd0aCk7CisKKyAgICAgICAgRXZlbnRMb2cgcHJveGllZEFBQyA9IG5ldyBFdmVudExvZygpOworICAgICAgICBzdXBwb3J0LmFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIobmV3IFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSgiYSIsCisgICAgICAgICAgICAgICAgbmV3IFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSgiYSIsCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5KCJjIiwgcHJveGllZEFBQykpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg2LCBzdXBwb3J0LmdldFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJzKCkubGVuZ3RoKTsKKworICAgICAgICBzdXBwb3J0LnJlbW92ZVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoYWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIHN1cHBvcnQuZ2V0UHJvcGVydHlDaGFuZ2VMaXN0ZW5lcnMoKS5sZW5ndGgpOworICAgICAgICBzdXBwb3J0LnJlbW92ZVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoImEiLCBwcm94aWVkQSk7CisgICAgICAgIGFzc2VydEVxdWFscyg0LCBzdXBwb3J0LmdldFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJzKCkubGVuZ3RoKTsKKyAgICAgICAgc3VwcG9ydC5yZW1vdmVQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKG5ldyBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkoImEiLCBhZGRBKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBzdXBwb3J0LmdldFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJzKCkubGVuZ3RoKTsKKyAgICAgICAgc3VwcG9ydC5yZW1vdmVQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKAorICAgICAgICAgICAgICAgICJhIiwgbmV3IFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSgiYiIsIGFkZEFQcm94aWVkQikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgc3VwcG9ydC5nZXRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVycygpLmxlbmd0aCk7CisgICAgICAgIHN1cHBvcnQucmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihwcm94eUFCKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHN1cHBvcnQuZ2V0UHJvcGVydHlDaGFuZ2VMaXN0ZW5lcnMoKS5sZW5ndGgpOworCisgICAgICAgIHN1cHBvcnQucmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihwcm94aWVkQUFDKTsKKyAgICAgICAgc3VwcG9ydC5yZW1vdmVQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKG5ldyBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkoImEiLCBwcm94aWVkQUFDKSk7CisgICAgICAgIHN1cHBvcnQucmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcigiYSIsIG5ldyBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkoImMiLCBwcm94aWVkQUFDKSk7CisgICAgICAgIHN1cHBvcnQucmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcigiYSIsIG5ldyBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkoImMiLAorICAgICAgICAgICAgICAgIG5ldyBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkoImEiLCBwcm94aWVkQUFDKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgc3VwcG9ydC5nZXRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVycygpLmxlbmd0aCk7CisKKyAgICAgICAgc3VwcG9ydC5yZW1vdmVQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKCJhIiwgbmV3IFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSgiYSIsCisgICAgICAgICAgICAgICAgbmV3IFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSgiYyIsIHByb3hpZWRBQUMpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBzdXBwb3J0LmdldFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJzKCkubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWRkaW5nT25lTGlzdGVuZXJUd2ljZSgpIHsKKyAgICAgICAgT2JqZWN0IGJlYW4gPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIFByb3BlcnR5Q2hhbmdlU3VwcG9ydCBzdXBwb3J0ID0gbmV3IFByb3BlcnR5Q2hhbmdlU3VwcG9ydChiZWFuKTsKKyAgICAgICAgRXZlbnRMb2cgbG9nID0gbmV3IEV2ZW50TG9nKCk7CisgICAgICAgIHN1cHBvcnQuYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcigiYSIsIGxvZyk7CisgICAgICAgIHN1cHBvcnQuYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihsb2cpOworICAgICAgICBzdXBwb3J0LmFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIobG9nKTsKKyAgICAgICAgc3VwcG9ydC5hZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKCJhIiwgbG9nKTsKKworICAgICAgICBQcm9wZXJ0eUNoYW5nZUV2ZW50IGV2ZW50QSA9IG5ldyBQcm9wZXJ0eUNoYW5nZUV2ZW50KGJlYW4sICJhIiwgZmFsc2UsIHRydWUpOworICAgICAgICBQcm9wZXJ0eUNoYW5nZUV2ZW50IGV2ZW50QiA9IG5ldyBQcm9wZXJ0eUNoYW5nZUV2ZW50KGJlYW4sICJiIiwgZmFsc2UsIHRydWUpOworCisgICAgICAgIHN1cHBvcnQuZmlyZVByb3BlcnR5Q2hhbmdlKGV2ZW50QSk7CisgICAgICAgIHN1cHBvcnQuZmlyZVByb3BlcnR5Q2hhbmdlKGV2ZW50Qik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoZXZlbnRBLCBldmVudEEsIGV2ZW50QSwgZXZlbnRBLCBldmVudEIsIGV2ZW50QiksIGxvZy5sb2cpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRpbmdBTGlzdGVuZXJBY3R1YWxseUFkZHNBUHJveHkoKSB7CisgICAgICAgIE9iamVjdCBiZWFuID0gbmV3IE9iamVjdCgpOworICAgICAgICBQcm9wZXJ0eUNoYW5nZVN1cHBvcnQgc3VwcG9ydCA9IG5ldyBQcm9wZXJ0eUNoYW5nZVN1cHBvcnQoYmVhbik7CisgICAgICAgIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIgPSBuZXcgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHByb3BlcnR5Q2hhbmdlKFByb3BlcnR5Q2hhbmdlRXZlbnQgZXZlbnQpIHt9CisgICAgICAgIH07CisgICAgICAgIHN1cHBvcnQuYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcigiYSIsIGxpc3RlbmVyKTsKKworICAgICAgICBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkgcDEKKyAgICAgICAgICAgICAgICA9IChQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkpIHN1cHBvcnQuZ2V0UHJvcGVydHlDaGFuZ2VMaXN0ZW5lcnMoKVswXTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eS5jbGFzcywgcDEuZ2V0Q2xhc3MoKSk7CisgICAgICAgIGFzc2VydFRydWUocDEgIT0gbGlzdGVuZXIpOyAvLyB3ZWlyZCBidXQgY29uc2lzdGVudCB3aXRoIHRoZSBSSQorICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBwMS5nZXRQcm9wZXJ0eU5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhsaXN0ZW5lciwgcDEuZ2V0TGlzdGVuZXIoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFkZGluZ0FQcm94eSgpIHsKKyAgICAgICAgT2JqZWN0IGJlYW4gPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIFByb3BlcnR5Q2hhbmdlU3VwcG9ydCBzdXBwb3J0ID0gbmV3IFByb3BlcnR5Q2hhbmdlU3VwcG9ydChiZWFuKTsKKyAgICAgICAgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lciA9IG5ldyBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcHJvcGVydHlDaGFuZ2UoUHJvcGVydHlDaGFuZ2VFdmVudCBldmVudCkge30KKyAgICAgICAgfTsKKyAgICAgICAgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5IHByb3h5ID0gbmV3IFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSgiYSIsIGxpc3RlbmVyKTsKKyAgICAgICAgc3VwcG9ydC5hZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKCJiIiwgcHJveHkpOworCisgICAgICAgIC8vIHRoaXMgcHJveHkgc2V0cyB1cyB1cCB0byByZWNlaXZlICdiJyBldmVudHMKKyAgICAgICAgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5IHAxCisgICAgICAgICAgICAgICAgPSAoUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5KSBzdXBwb3J0LmdldFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJzKClbMF07CisgICAgICAgIGFzc2VydEVxdWFscyhQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkuY2xhc3MsIHAxLmdldENsYXNzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImIiLCBwMS5nZXRQcm9wZXJ0eU5hbWUoKSk7CisKKyAgICAgICAgLy8gdGhpcyBwcm94eSBzZXRzIHVzIHVwIHRvIHJlY2VpdmUgJ2EnIGV2ZW50cworICAgICAgICBQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUHJveHkgcDIgPSAoUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5KSBwMS5nZXRMaXN0ZW5lcigpOworICAgICAgICBhc3NlcnRFcXVhbHMoUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5LmNsYXNzLCBwMi5nZXRDbGFzcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgcDIuZ2V0UHJvcGVydHlOYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobGlzdGVuZXIsIHAyLmdldExpc3RlbmVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemUoKSB7CisgICAgICAgIFN0cmluZyBzID0gImFjZWQwMDA1NzM3MjAwMjA2YTYxNzY2MTJlNjI2NTYxNmU3MzJlNTA3MjZmNzA2NTcyNzQ3OTQzNjg2MTZlNjciCisgICAgICAgICAgICAgICAgKyAiNjU1Mzc1NzA3MDZmNzI3NDU4ZDVkMjY0NTc0ODYwYmIwMzAwMDM0OTAwMmE3MDcyNmY3MDY1NzI3NDc5NDM2ODYiCisgICAgICAgICAgICAgICAgKyAiMTZlNjc2NTUzNzU3MDcwNmY3Mjc0NTM2NTcyNjk2MTZjNjk3YTY1NjQ0NDYxNzQ2MTU2NjU3MjczNjk2ZjZlNGMiCisgICAgICAgICAgICAgICAgKyAiMDAwODYzNjg2OTZjNjQ3MjY1NmU3NDAwMTU0YzZhNjE3NjYxMmY3NTc0Njk2YzJmNDg2MTczNjg3NDYxNjI2YzYiCisgICAgICAgICAgICAgICAgKyAiNTNiNGMwMDA2NzM2Zjc1NzI2MzY1NzQwMDEyNGM2YTYxNzY2MTJmNmM2MTZlNjcyZjRmNjI2YTY1NjM3NDNiNzgiCisgICAgICAgICAgICAgICAgKyAiNzAwMDAwMDAwMjczNzIwMDEzNmE2MTc2NjEyZTc1NzQ2OTZjMmU0ODYxNzM2ODc0NjE2MjZjNjUxM2JiMGYyNTIiCisgICAgICAgICAgICAgICAgKyAiMTRhZTRiODAzMDAwMjQ2MDAwYTZjNmY2MTY0NDY2MTYzNzQ2ZjcyNDkwMDA5NzQ2ODcyNjU3MzY4NmY2YzY0NzgiCisgICAgICAgICAgICAgICAgKyAiNzAzZjQwMDAwMDAwMDAwMDA4NzcwODAwMDAwMDBiMDAwMDAwMDE3NDAwMDE2MTczNzEwMDdlMDAwMDAwMDAwMDAiCisgICAgICAgICAgICAgICAgKyAiMjcwNzQwMDA0NjI2NTYxNmU3MzcyMDAzYTZjNjk2MjYzNmY3MjY1MmU2YTYxNzY2MTJlNzU3NDY5NmMyZTYyNjUiCisgICAgICAgICAgICAgICAgKyAiNjE2ZTczMmU1MDcyNmY3MDY1NzI3NDc5NDM2ODYxNmU2NzY1NTM3NTcwNzA2ZjcyNzQ1NDY1NzM3NDI0NDU3NjYiCisgICAgICAgICAgICAgICAgKyAiNTZlNzQ0YzZmNjdiOTI2Njc2MzdkMGI2ZjQ1MDIwMDAyNGMwMDAzNmM2ZjY3NzQwMDEwNGM2YTYxNzY2MTJmNzUiCisgICAgICAgICAgICAgICAgKyAiNzQ2OTZjMmY0YzY5NzM3NDNiNGMwMDA0NmU2MTZkNjU3NDAwMTI0YzZhNjE3NjYxMmY2YzYxNmU2NzJmNTM3NDciCisgICAgICAgICAgICAgICAgKyAiMjY5NmU2NzNiNzg3MDczNzIwMDEzNmE2MTc2NjEyZTc1NzQ2OTZjMmU0MTcyNzI2MTc5NGM2OTczNzQ3ODgxZDIiCisgICAgICAgICAgICAgICAgKyAiMWQ5OWM3NjE5ZDAzMDAwMTQ5MDAwNDczNjk3YTY1Nzg3MDAwMDAwMDAwNzcwNDAwMDAwMDBhNzg3NDAwMGI2YzYiCisgICAgICAgICAgICAgICAgKyAiOTczNzQ2NTZlNjU3MjU0NmY0MTcxMDA3ZTAwMGM3MDc4Nzg3MTAwN2UwMDA4NzM3MTAwN2UwMDA5NzM3MTAwN2UiCisgICAgICAgICAgICAgICAgKyAiMDAwZDAwMDAwMDAwNzcwNDAwMDAwMDBhNzg3NDAwMGQ2YzY5NzM3NDY1NmU2NTcyNTQ2ZjQxNmM2YzcwNzgiOworCisgICAgICAgIE9iamVjdCBiZWFuID0gImJlYW4iOworICAgICAgICBQcm9wZXJ0eUNoYW5nZVN1cHBvcnQgc3VwcG9ydCA9IG5ldyBQcm9wZXJ0eUNoYW5nZVN1cHBvcnQoYmVhbik7CisgICAgICAgIEV2ZW50TG9nIGxpc3RlbmVyVG9BbGwgPSBuZXcgRXZlbnRMb2coKTsKKyAgICAgICAgbGlzdGVuZXJUb0FsbC5uYW1lID0gImxpc3RlbmVyVG9BbGwiOworICAgICAgICBFdmVudExvZyBsaXN0ZW5lclRvQSA9IG5ldyBFdmVudExvZygpOworICAgICAgICBsaXN0ZW5lclRvQS5uYW1lID0gImxpc3RlbmVyVG9BIjsKKyAgICAgICAgc3VwcG9ydC5hZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKGxpc3RlbmVyVG9BbGwpOworICAgICAgICBzdXBwb3J0LmFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoImEiLCBsaXN0ZW5lclRvQSk7CisgICAgICAgIHN1cHBvcnQuYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcigiYSIsIGxpc3RlbmVyVG9BKTsKKworICAgICAgICBuZXcgU2VyaWFsaXphYmxlVGVzdGVyPFByb3BlcnR5Q2hhbmdlU3VwcG9ydD4oc3VwcG9ydCwgcykgeworICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBib29sZWFuIGVxdWFscyhQcm9wZXJ0eUNoYW5nZVN1cHBvcnQgYSwgUHJvcGVydHlDaGFuZ2VTdXBwb3J0IGIpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZGVzY3JpYmUoYS5nZXRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVycygpKQorICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhkZXNjcmliZShiLmdldFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJzKCkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCB2ZXJpZnkoUHJvcGVydHlDaGFuZ2VTdXBwb3J0IGRlc2VyaWFsaXplZCkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiW2EgdG8gbGlzdGVuZXJUb0EsIGEgdG8gbGlzdGVuZXJUb0EsIGxpc3RlbmVyVG9BbGxdIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaWJlKGRlc2VyaWFsaXplZC5nZXRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVycygpKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0udGVzdCgpOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGRlc2NyaWJlKFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJbXSBsaXN0ZW5lcnMpIHsKKyAgICAgICAgTGlzdDxTdHJpbmc+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBmb3IgKFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIgOiBsaXN0ZW5lcnMpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hZGQoZGVzY3JpYmUobGlzdGVuZXIpKTsKKyAgICAgICAgfQorICAgICAgICBDb2xsZWN0aW9ucy5zb3J0KHJlc3VsdCk7CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyBkZXNjcmliZShFdmVudExpc3RlbmVyIGxpc3RlbmVyKSB7CisgICAgICAgIGlmIChsaXN0ZW5lciBpbnN0YW5jZW9mIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSkgeworICAgICAgICAgICAgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lclByb3h5IHByb3h5ID0gKFByb3BlcnR5Q2hhbmdlTGlzdGVuZXJQcm94eSkgbGlzdGVuZXI7CisgICAgICAgICAgICByZXR1cm4gcHJveHkuZ2V0UHJvcGVydHlOYW1lKCkgKyAiIHRvICIgKyBkZXNjcmliZShwcm94eS5nZXRMaXN0ZW5lcigpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBsaXN0ZW5lci50b1N0cmluZygpOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIEV2ZW50TG9nIGltcGxlbWVudHMgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciwgU2VyaWFsaXphYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSAiRXZlbnRMb2ciOworICAgICAgICBMaXN0PFByb3BlcnR5Q2hhbmdlRXZlbnQ+IGxvZyA9IG5ldyBBcnJheUxpc3Q8UHJvcGVydHlDaGFuZ2VFdmVudD4oKTsKKyAgICAgICAgcHVibGljIHZvaWQgcHJvcGVydHlDaGFuZ2UoUHJvcGVydHlDaGFuZ2VFdmVudCBldmVudCkgeworICAgICAgICAgICAgbG9nLmFkZChldmVudCk7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICByZXR1cm4gbmFtZTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9jb25jdXJyZW50L0NvcHlPbldyaXRlQXJyYXlMaXN0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2NvbmN1cnJlbnQvQ29weU9uV3JpdGVBcnJheUxpc3RUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjEwYmUzMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9jb25jdXJyZW50L0NvcHlPbldyaXRlQXJyYXlMaXN0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjgyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC5jb25jdXJyZW50OworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3RJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db3B5T25Xcml0ZUFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db3VudERvd25MYXRjaDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvclNlcnZpY2U7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkZ1dHVyZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgbGliY29yZS5qYXZhLnV0aWwuU2VyaWFsaXphYmxlVGVzdGVyOworCitwdWJsaWMgZmluYWwgY2xhc3MgQ29weU9uV3JpdGVBcnJheUxpc3RUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdEl0ZXJhdG9yQW5kTm9uU3RydWN0dXJhbENoYW5nZXMoKSB7CisgICAgICAgIENvcHlPbldyaXRlQXJyYXlMaXN0PFN0cmluZz4gbGlzdCA9IG5ldyBDb3B5T25Xcml0ZUFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGxpc3QuYWRkQWxsKEFycmF5cy5hc0xpc3QoImEiLCAiYiIsICJjIiwgImQiLCAiZSIpKTsKKyAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBhYmNkZSA9IGxpc3QuaXRlcmF0b3IoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgYWJjZGUubmV4dCgpKTsKKyAgICAgICAgbGlzdC5zZXQoMSwgIkIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiIiwgYWJjZGUubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjIiwgYWJjZGUubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkIiwgYWJjZGUubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlIiwgYWJjZGUubmV4dCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3ViIGxpc3QgdGhyb3dzIG9uIG5vbi1zdHJ1Y3R1cmFsIGNoYW5nZXMsIGV2ZW4gdGhvdWdoIHRoYXQgZGlzYWdyZWVzCisgICAgICogd2l0aCB0aGUgc3ViTGlzdCgpIGRvY3VtZW50YXRpb24gd2hpY2ggc3VnZ2VzdHMgdGhhdCBvbmx5IHNpemUtY2hhbmdpbmcKKyAgICAgKiBvcGVyYXRpb25zIHdpbGwgdHJpZ2dlciBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTdWJMaXN0QW5kTm9uU3RydWN0dXJhbENoYW5nZXMoKSB7CisgICAgICAgIENvcHlPbldyaXRlQXJyYXlMaXN0PFN0cmluZz4gbGlzdCA9IG5ldyBDb3B5T25Xcml0ZUFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGxpc3QuYWRkQWxsKEFycmF5cy5hc0xpc3QoImEiLCAiYiIsICJjIiwgImQiLCAiZSIpKTsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGJjZCA9IGxpc3Quc3ViTGlzdCgxLCA0KTsKKyAgICAgICAgbGlzdC5zZXQoMiwgIkMiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJjZC5nZXQoMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdWJMaXN0QW5kU3RydWN0dXJhbENoYW5nZXMoKSB7CisgICAgICAgIENvcHlPbldyaXRlQXJyYXlMaXN0PFN0cmluZz4gbGlzdCA9IG5ldyBDb3B5T25Xcml0ZUFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGxpc3QuYWRkQWxsKEFycmF5cy5hc0xpc3QoImEiLCAiYiIsICJjIiwgImQiLCAiZSIpKTsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGJjZCA9IGxpc3Quc3ViTGlzdCgxLCA0KTsKKyAgICAgICAgbGlzdC5jbGVhcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmNkLmdldCgxKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN1Ykxpc3RBbmRTaXplUHJlc2VydmluZ1N0cnVjdHVyYWxDaGFuZ2VzKCkgeworICAgICAgICBDb3B5T25Xcml0ZUFycmF5TGlzdDxTdHJpbmc+IGxpc3QgPSBuZXcgQ29weU9uV3JpdGVBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBsaXN0LmFkZEFsbChBcnJheXMuYXNMaXN0KCJhIiwgImIiLCAiYyIsICJkIiwgImUiKSk7CisgICAgICAgIExpc3Q8U3RyaW5nPiBiY2QgPSBsaXN0LnN1Ykxpc3QoMSwgNCk7CisgICAgICAgIGxpc3QuY2xlYXIoKTsKKyAgICAgICAgbGlzdC5hZGRBbGwoQXJyYXlzLmFzTGlzdCgiQSIsICJCIiwgIkMiLCAiRCIsICJFIikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmNkLmdldCgxKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZUFsbCgpIHsKKyAgICAgICAgQ29weU9uV3JpdGVBcnJheUxpc3Q8U3RyaW5nPiBsaXN0ID0gbmV3IENvcHlPbldyaXRlQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgbGlzdC5hZGRBbGwoQXJyYXlzLmFzTGlzdCgiYSIsICJiIiwgImMiLCAiZCIsICJlIikpOworCisgICAgICAgIGxpc3QucmVtb3ZlQWxsKEFycmF5cy5hc0xpc3QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KCJhIiwgImIiLCAiYyIsICJkIiwgImUiKSwgbGlzdCk7CisKKyAgICAgICAgbGlzdC5yZW1vdmVBbGwoQXJyYXlzLmFzTGlzdCgiZSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoImEiLCAiYiIsICJjIiwgImQiKSwgbGlzdCk7CisKKyAgICAgICAgbGlzdC5yZW1vdmVBbGwoQXJyYXlzLmFzTGlzdCgiYiIsICJjIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdCgiYSIsICJkIiksIGxpc3QpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdWJMaXN0Q2xlYXIoKSB7CisgICAgICAgIENvcHlPbldyaXRlQXJyYXlMaXN0PFN0cmluZz4gbGlzdCA9IG5ldyBDb3B5T25Xcml0ZUFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGxpc3QuYWRkQWxsKEFycmF5cy5hc0xpc3QoImEiLCAiYiIsICJjIiwgImQiLCAiZSIpKTsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGJjZCA9IGxpc3Quc3ViTGlzdCgxLCA0KTsKKyAgICAgICAgYmNkLmNsZWFyKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KCJhIiwgImUiKSwgbGlzdCk7CisgICAgICAgIGJjZC5hZGRBbGwoQXJyYXlzLmFzTGlzdCgiQiIsICJDIiwgIkQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KCJhIiwgIkIiLCAiQyIsICJEIiwgImUiKSwgbGlzdCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN1Ykxpc3RDbGVhcldoZW5FbXB0eSgpIHsKKyAgICAgICAgbmV3IENvcHlPbldyaXRlQXJyYXlMaXN0PFN0cmluZz4oKS5zdWJMaXN0KDAsIDApLmNsZWFyKCk7IC8vIHRoZSBSSSBmYWlscyBoZXJlCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN1Ykxpc3RJdGVyYXRvckdldHNTbmFwc2hvdCgpIHsKKyAgICAgICAgQ29weU9uV3JpdGVBcnJheUxpc3Q8U3RyaW5nPiBsaXN0ID0gbmV3IENvcHlPbldyaXRlQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgbGlzdC5hZGRBbGwoQXJyYXlzLmFzTGlzdCgiYSIsICJiIiwgImMiLCAiZCIsICJlIikpOworICAgICAgICBJdGVyYXRvcjxTdHJpbmc+IGJjZCA9IGxpc3Quc3ViTGlzdCgxLCA0KS5pdGVyYXRvcigpOworICAgICAgICBsaXN0LmNsZWFyKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiYiIsIGJjZC5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImMiLCBiY2QubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkIiwgYmNkLm5leHQoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGJjZC5oYXNOZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdWJMaXN0UmVtb3ZlQnlWYWx1ZSgpIHsKKyAgICAgICAgQ29weU9uV3JpdGVBcnJheUxpc3Q8U3RyaW5nPiBsaXN0ID0gbmV3IENvcHlPbldyaXRlQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgbGlzdC5hZGRBbGwoQXJyYXlzLmFzTGlzdCgiYSIsICJiIiwgImMiLCAiZCIsICJlIikpOworICAgICAgICBMaXN0PFN0cmluZz4gYmNkID0gbGlzdC5zdWJMaXN0KDEsIDQpOworICAgICAgICBiY2QucmVtb3ZlKCJjIik7IC8vIHRoZSBSSSBmYWlscyBoZXJlCisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KCJiIiwgImQiKSwgYmNkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoImEiLCAiYiIsICJkIiwgImUiKSwgbGlzdCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN1Ykxpc3RSZW1vdmVCeUluZGV4KCkgeworICAgICAgICBDb3B5T25Xcml0ZUFycmF5TGlzdDxTdHJpbmc+IGxpc3QgPSBuZXcgQ29weU9uV3JpdGVBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBsaXN0LmFkZEFsbChBcnJheXMuYXNMaXN0KCJhIiwgImIiLCAiYyIsICJkIiwgImUiKSk7CisgICAgICAgIExpc3Q8U3RyaW5nPiBiY2QgPSBsaXN0LnN1Ykxpc3QoMSwgNCk7CisgICAgICAgIGJjZC5yZW1vdmUoMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KCJiIiwgImQiKSwgYmNkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoImEiLCAiYiIsICJkIiwgImUiKSwgbGlzdCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN1Ykxpc3RSZXRhaW5BbGwoKSB7CisgICAgICAgIENvcHlPbldyaXRlQXJyYXlMaXN0PFN0cmluZz4gbGlzdCA9IG5ldyBDb3B5T25Xcml0ZUFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGxpc3QuYWRkQWxsKEFycmF5cy5hc0xpc3QoImEiLCAiYiIsICJjIiwgImQiLCAiZSIsICJmIiwgImciLCAiaCIsICJpIikpOworICAgICAgICBMaXN0PFN0cmluZz4gZGVmID0gbGlzdC5zdWJMaXN0KDMsIDYpOworICAgICAgICBkZWYucmV0YWluQWxsKEFycmF5cy5hc0xpc3QoImMiLCAiZSIsICJoIikpOyAvLyB0aGUgUkkgZmFpbHMgaGVyZQorICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdCgiYSIsICJiIiwgImMiLCAiZSIsICJnIiwgImgiLCAiaSIpLCBsaXN0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoImUiKSwgZGVmKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3ViTGlzdFJlbW92ZUFsbCgpIHsKKyAgICAgICAgQ29weU9uV3JpdGVBcnJheUxpc3Q8U3RyaW5nPiBsaXN0ID0gbmV3IENvcHlPbldyaXRlQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgbGlzdC5hZGRBbGwoQXJyYXlzLmFzTGlzdCgiYSIsICJiIiwgImMiLCAiZCIsICJlIiwgImYiLCAiZyIsICJoIiwgImkiKSk7CisgICAgICAgIExpc3Q8U3RyaW5nPiBkZWYgPSBsaXN0LnN1Ykxpc3QoMywgNik7CisgICAgICAgIGRlZi5yZW1vdmVBbGwoQXJyYXlzLmFzTGlzdCgiYyIsICJlIiwgImgiKSk7ICAvLyB0aGUgUkkgZmFpbHMgaGVyZQorICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdCgiYSIsICJiIiwgImMiLCAiZCIsICJmIiwgImciLCAiaCIsICJpIiksIGxpc3QpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdCgiZCIsICJmIiksIGRlZik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEF0b21pY0FkZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdEFkZEFsbElzQXRvbWljKG5ldyBDb3B5T25Xcml0ZUFycmF5TGlzdDxPYmplY3Q+KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdWJMaXN0QXRvbWljQWRkcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0QWRkQWxsSXNBdG9taWMobmV3IENvcHlPbldyaXRlQXJyYXlMaXN0PE9iamVjdD4oKS5zdWJMaXN0KDAsIDApKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBdHRlbXB0cyB0byBvYnNlcnZlIHtAY29kZSBsaXN0fSBpbiB0aGUgbWlkZGxlIG9mIGFuIGFkZC4gVGhlIFJJJ3MKKyAgICAgKiBDb3B5T25Xcml0ZUFycmF5TGlzdCBwYXNzZXMgdGhpcyB0ZXN0LCBidXQgaXRzIHN1YiBsaXN0IGRvZXNuJ3QuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RBZGRBbGxJc0F0b21pYyhmaW5hbCBMaXN0PE9iamVjdD4gbGlzdCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIENvdW50RG93bkxhdGNoIGRvbmUgPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisKKyAgICAgICAgRXhlY3V0b3JTZXJ2aWNlIGV4ZWN1dG9yID0gRXhlY3V0b3JzLm5ld1NpbmdsZVRocmVhZEV4ZWN1dG9yKCk7CisgICAgICAgIEZ1dHVyZTw/PiBmdXR1cmUgPSBleGVjdXRvci5zdWJtaXQobmV3IFJ1bm5hYmxlKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB3aGlsZSAoZG9uZS5nZXRDb3VudCgpID4gMCkgeworICAgICAgICAgICAgICAgICAgICBpbnQgbGlzdFNpemUgPSBsaXN0LnNpemUoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJhZGRBbGwoKSBub3QgYXRvbWljOyBzaXplPSIgKyBsaXN0U2l6ZSwgMCwgbGlzdFNpemUgJSAxMDAwKTsKKyAgICAgICAgICAgICAgICAgICAgVGhyZWFkLnlpZWxkKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAgICAgZXhlY3V0b3Iuc2h1dGRvd24oKTsKKworICAgICAgICBMaXN0PE9iamVjdD4gdG9BZGQgPSBBcnJheXMuYXNMaXN0KG5ldyBPYmplY3RbMTAwMF0pOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKSB7CisgICAgICAgICAgICBsaXN0LmFkZEFsbCh0b0FkZCk7CisgICAgICAgICAgICBsaXN0LmNsZWFyKCk7CisgICAgICAgICAgICBUaHJlYWQueWllbGQoKTsKKyAgICAgICAgfQorCisgICAgICAgIGRvbmUuY291bnREb3duKCk7CisgICAgICAgIGZ1dHVyZS5nZXQoKTsgLy8gdGhpcyB3aWxsIHRocm93IHRoZSBhYm92ZSBleGNlcHRpb24KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3ViTGlzdEFkZElzQXRFbmQoKSB7CisgICAgICAgIENvcHlPbldyaXRlQXJyYXlMaXN0PFN0cmluZz4gbGlzdCA9IG5ldyBDb3B5T25Xcml0ZUFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGxpc3QuYWRkQWxsKEFycmF5cy5hc0xpc3QoImEiLCAiYiIsICJjIiwgImQiLCAiZSIpKTsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGJjZCA9IGxpc3Quc3ViTGlzdCgxLCA0KTsKKyAgICAgICAgYmNkLmFkZCgiZiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdCgiYSIsICJiIiwgImMiLCAiZCIsICJmIiwgImUiKSwgbGlzdCk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KCJiIiwgImMiLCAiZCIsICJmIiksIGJjZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN1Ykxpc3RBZGRBbGwoKSB7CisgICAgICAgIENvcHlPbldyaXRlQXJyYXlMaXN0PFN0cmluZz4gbGlzdCA9IG5ldyBDb3B5T25Xcml0ZUFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGxpc3QuYWRkQWxsKEFycmF5cy5hc0xpc3QoImEiLCAiYiIsICJjIiwgImQiLCAiZSIpKTsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGJjZCA9IGxpc3Quc3ViTGlzdCgxLCA0KTsKKyAgICAgICAgYmNkLmFkZEFsbCgxLCBBcnJheXMuYXNMaXN0KCJmIiwgImciLCAiaCIsICJpIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdCgiYSIsICJiIiwgImYiLCAiZyIsICJoIiwgImkiLCAiYyIsICJkIiwgImUiKSwgbGlzdCk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KCJiIiwgImYiLCAiZyIsICJoIiwgImkiLCAiYyIsICJkIiksIGJjZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdExpc3RJdGVyYXRvcigpIHsKKyAgICAgICAgQ29weU9uV3JpdGVBcnJheUxpc3Q8U3RyaW5nPiBsaXN0ID0gbmV3IENvcHlPbldyaXRlQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgbGlzdC5hZGRBbGwoQXJyYXlzLmFzTGlzdCgiYSIsICJiIiwgImMiLCAiZCIsICJlIikpOworICAgICAgICBMaXN0SXRlcmF0b3I8U3RyaW5nPiBpID0gbGlzdC5saXN0SXRlcmF0b3IoNSk7CisgICAgICAgIGxpc3QuY2xlYXIoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgaS5uZXh0SW5kZXgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg0LCBpLnByZXZpb3VzSW5kZXgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZSIsIGkucHJldmlvdXMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg0LCBpLm5leHRJbmRleCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGkucHJldmlvdXNJbmRleCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShpLmhhc05leHQoKSk7CisgICAgICAgIGFzc2VydFRydWUoaS5oYXNQcmV2aW91cygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkIiwgaS5wcmV2aW91cygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGkubmV4dEluZGV4KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgaS5wcmV2aW91c0luZGV4KCkpOworICAgICAgICBhc3NlcnRUcnVlKGkuaGFzTmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShpLmhhc1ByZXZpb3VzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImMiLCBpLnByZXZpb3VzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgaS5uZXh0SW5kZXgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBpLnByZXZpb3VzSW5kZXgoKSk7CisgICAgICAgIGFzc2VydFRydWUoaS5oYXNOZXh0KCkpOworICAgICAgICBhc3NlcnRUcnVlKGkuaGFzUHJldmlvdXMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYiIsIGkucHJldmlvdXMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBpLm5leHRJbmRleCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGkucHJldmlvdXNJbmRleCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShpLmhhc05leHQoKSk7CisgICAgICAgIGFzc2VydFRydWUoaS5oYXNQcmV2aW91cygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgaS5wcmV2aW91cygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGkubmV4dEluZGV4KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGkucHJldmlvdXNJbmRleCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShpLmhhc05leHQoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGkuaGFzUHJldmlvdXMoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpLnByZXZpb3VzKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemUoKSB7CisgICAgICAgIFN0cmluZyBzID0gImFjZWQwMDA1NzM3MjAwMjk2YTYxNzY2MTJlNzU3NDY5NmMyZTYzNmY2ZTYzNzU3MjcyNjU2ZTc0MmU0MzZmNzAiCisgICAgICAgICAgICAgICAgKyAiNzk0ZjZlNTc3MjY5NzQ2NTQxNzI3MjYxNzk0YzY5NzM3NDc4NWQ5ZmQ1NDZhYjkwYzMwMzAwMDA3ODcwNzcwNDAiCisgICAgICAgICAgICAgICAgKyAiMDAwMDAwNTc0MDAwMTYxNzQwMDAxNjI3NDAwMDE2MzcwNzQwMDAxNjU3OCI7CisKKyAgICAgICAgTGlzdDxTdHJpbmc+IGNvbnRlbnRzID0gQXJyYXlzLmFzTGlzdCgiYSIsICJiIiwgImMiLCBudWxsLCAiZSIpOworICAgICAgICBDb3B5T25Xcml0ZUFycmF5TGlzdDxTdHJpbmc+IGxpc3QgPSBuZXcgQ29weU9uV3JpdGVBcnJheUxpc3Q8U3RyaW5nPihjb250ZW50cyk7CisKKyAgICAgICAgbmV3IFNlcmlhbGl6YWJsZVRlc3RlcjxDb3B5T25Xcml0ZUFycmF5TGlzdDxTdHJpbmc+PihsaXN0LCBzKS50ZXN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHdlIGRvbid0IHJldGFpbiB0aGUgYXJyYXkgcmV0dXJuZWQgYnkgdG9BcnJheSgpIG9uIHRoZSBjb3B5CisgICAgICogY29uc3RydWN0b3IuIFRoYXQgYXJyYXkgbWF5IG5vdCBiZSBvZiB0aGUgcmVxdWlyZWQgdHlwZSEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RG9lc05vdFJldGFpblRvQXJyYXkoKSB7CisgICAgICAgIFN0cmluZ1tdIHN0cmluZ3MgPSB7ICJhIiwgImIiLCAiYyIgfTsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGFzTGlzdCA9IEFycmF5cy5hc0xpc3Qoc3RyaW5ncyk7CisgICAgICAgIGFzc2VydEVxdWFscyhTdHJpbmdbXS5jbGFzcywgYXNMaXN0LnRvQXJyYXkoKS5nZXRDbGFzcygpKTsKKyAgICAgICAgQ29weU9uV3JpdGVBcnJheUxpc3Q8T2JqZWN0PiBvYmplY3RzID0gbmV3IENvcHlPbldyaXRlQXJyYXlMaXN0PE9iamVjdD4oYXNMaXN0KTsKKyAgICAgICAgb2JqZWN0cy5hZGQoQm9vbGVhbi5UUlVFKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvamFyL0RhbHZpa0V4ZWNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvamFyL0RhbHZpa0V4ZWNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDIxY2QzZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9qYXIvRGFsdmlrRXhlY1Rlc3QuamF2YQpAQCAtMCwwICsxLDI1OCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWwuamFyOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLmphci5BdHRyaWJ1dGVzOworaW1wb3J0IGphdmEudXRpbC5qYXIuSmFyRW50cnk7CitpbXBvcnQgamF2YS51dGlsLmphci5KYXJGaWxlOworaW1wb3J0IGphdmEudXRpbC5qYXIuSmFyT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5qYXIuTWFuaWZlc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGxpYmNvcmUuaW8uU3RyZWFtczsKK2ltcG9ydCBzdGF0aWMgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0V4ZWMuZXhlY0FuZEdldE91dHB1dDsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LnJlc291cmNlLlN1cHBvcnRfUmVzb3VyY2VzOworCisKK3B1YmxpYyBjbGFzcyBEYWx2aWtFeGVjVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIFN0cmluZyBleGVjRGFsdmlrMShTdHJpbmcgY2xhc3NwYXRoLCBTdHJpbmcgbWFpbkNsYXNzLCBTdHJpbmcgYXJnMSkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBQcm9jZXNzQnVpbGRlciBidWlsZGVyID0gbmV3IFByb2Nlc3NCdWlsZGVyKCk7CisKKyAgICAgICAgRmlsZSBkYWx2aWt2bSA9IG5ldyBGaWxlKCIvc3lzdGVtL2Jpbi9kYWx2aWt2bSIpOworICAgICAgICBpZiAoZGFsdmlrdm0uZXhpc3RzKCkpIHsKKyAgICAgICAgICAgIGJ1aWxkZXIuY29tbWFuZCgpLmFkZChkYWx2aWt2bS5nZXRQYXRoKCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYnVpbGRlci5jb21tYW5kKCkuYWRkKCJkYWx2aWt2bSIpOyAvLyBmb3IgaG9zdCBtb2RlLCBhc3N1bWUgZGFsdmlrdm0gaXMgb24gdGhlIHBhdGgKKyAgICAgICAgfQorCisgICAgICAgIGJ1aWxkZXIuY29tbWFuZCgpLmFkZCgiLUR1c2VyLmxhbmd1YWdlPWVuIik7CisgICAgICAgIGJ1aWxkZXIuY29tbWFuZCgpLmFkZCgiLUR1c2VyLnJlZ2lvbj1VUyIpOworICAgICAgICBidWlsZGVyLmNvbW1hbmQoKS5hZGQoIi1YYm9vdGNsYXNzcGF0aDoiICsgU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmJvb3QuY2xhc3MucGF0aCIpKTsKKyAgICAgICAgYnVpbGRlci5jb21tYW5kKCkuYWRkKCItY2xhc3NwYXRoIik7CisgICAgICAgIGJ1aWxkZXIuY29tbWFuZCgpLmFkZChjbGFzc3BhdGgpOworICAgICAgICBidWlsZGVyLmNvbW1hbmQoKS5hZGQobWFpbkNsYXNzKTsKKworICAgICAgICBpZiAoYXJnMSAhPSBudWxsKSB7CisgICAgICAgICAgICBidWlsZGVyLmNvbW1hbmQoKS5hZGQoYXJnMSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBDcmVhdGUgYSB3cml0YWJsZSBkYWx2aWstY2FjaGUgdW5kZXIgQU5EUk9JRF9EQVRBLgorICAgICAgICAvLyBUaGUgZGVmYXVsdCBkYWx2aWstY2FjaGUgaXMgb25seSB3cml0YWJsZSBieSB0aGUgc3lzdGVtIHVzZXIgKGFuZCByb290KS4KKyAgICAgICAgU3RyaW5nIHRtcCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKTsKKyAgICAgICAgYnVpbGRlci5lbnZpcm9ubWVudCgpLnB1dCgiQU5EUk9JRF9EQVRBIiwgdG1wKTsKKyAgICAgICAgbmV3IEZpbGUodG1wLCAiZGFsdmlrLWNhY2hlIikubWtkaXIoKTsKKworICAgICAgICByZXR1cm4gZXhlY0FuZEdldE91dHB1dChidWlsZGVyKTsKKyAgICB9CisKKyAgICBTdHJpbmcgZXhlY0RhbHZpayAoU3RyaW5nIGNsYXNzcGF0aCwgU3RyaW5nIG1haW5DbGFzcykKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZXhlY0RhbHZpazEoY2xhc3NwYXRoLCBtYWluQ2xhc3MsIG51bGwpOworICAgIH0KKworICAgIC8vIEV4ZWN1dGUgYW4gZXhpc3RpbmcgSkFSIG9uIGRhbHZpa3ZtIHVzaW5nIC1jbGFzc3BhdGggb3B0aW9uLiIsCisgICAgcHVibGljIHZvaWQgdGVzdF9leGVjRXhpc3RpbmdKYXIgKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyByZXM7CisgICAgICAgIEZpbGUgamFyRmlsZTsKKyAgICAgICAgaWYgKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS52ZW5kb3IiKS5jb250YWlucygiQW5kcm9pZCIpKSB7CisgICAgICAgICAgICAvLworICAgICAgICAgICAgLy8gVGVzdCBhZ2FpbnN0IEFuZHJvaWQ6CisgICAgICAgICAgICAvLworICAgICAgICAgICAgRmlsZSB0ZW1wRGlyID0gU3VwcG9ydF9SZXNvdXJjZXMuY3JlYXRlVGVtcEZvbGRlcigpOworICAgICAgICAgICAgamFyRmlsZSA9IFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKAorICAgICAgICAgICAgICAgICAgICB0ZW1wRGlyLCBudWxsLCAiY3RzX2RhbHZpa0V4ZWNUZXN0LmphciIgKTsKKyAgICAgICAgICAgIHJlcyA9IGV4ZWNEYWx2aWsoamFyRmlsZS5nZXRBYnNvbHV0ZVBhdGgoKSwgImRhbHZpa0V4ZWNUZXN0LkhlbGxvV29ybGQiKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSGVsbG8gQW5kcm9pZCBXb3JsZCEiLCAiSGVsbG8gQW5kcm9pZCBXb3JsZCFcbiIsIHJlcyk7CisKKyAgICAgICAgICAgIHJlcyA9IGV4ZWNEYWx2aWsoamFyRmlsZS5nZXRBYnNvbHV0ZVBhdGgoKSwgImRhbHZpa0V4ZWNUZXN0LlJlc291cmNlRHVtcGVyIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJBbmRyb2lkIFJlc291cmNlIER1bXBlciBzdGFydGVkIiwKKyAgICAgICAgICAgICAgICAgICAgcmVzLmNvbnRhaW5zKCJBbmRyb2lkIFJlc291cmNlIER1bXBlciBzdGFydGVkIikpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhpcyBSZXNvdXJjZSBjb250YWlucyBzb21lIHRleHQuIiwKKyAgICAgICAgICAgICAgICAgICAgcmVzLmNvbnRhaW5zKCJUaGlzIFJlc291cmNlIGNvbnRhaW5zIHNvbWUgdGV4dC4iKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLworICAgICAgICAgICAgLy8gVGVzdCBhZ2FpbnN0IFJJOgorICAgICAgICAgICAgLy8KKyAgICAgICAgICAgIC8vIERvIG5vdGhpbmchCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBDcmVhdGUgYSB0ZW1wIGZpbGUsIGZpbGwgaXQgd2l0aCBjb250ZW50cyBhY2NvcmRpbmcgdG8gRGFsdmlrIEpBUiBmb3JtYXQsIGFuZCBleGVjdXRlIGl0IG9uIGRhbHZpa3ZtIHVzaW5nIC1jbGFzc3BhdGggb3B0aW9uLiIsCisgICAgcHVibGljIHZvaWQgdGVzdF9leGVjQ3JlYXRlZEphciAoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZSBqYXJGaWxlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiY3RzX2RhbHZpa0V4ZWNUZXN0XyIsICIuamFyIik7CisgICAgICAgIGphckZpbGUuZGVsZXRlT25FeGl0KCk7CisKKyAgICAgICAgLy8gQ3JlYXRlIGEgSkFSIG91dHB1dCBzdHJlYW0gb24gdGhlIHRlbXAgZmlsZToKKyAgICAgICAgSmFyT3V0cHV0U3RyZWFtIGphck91dCA9IG5ldyBKYXJPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oamFyRmlsZSkpOworCisgICAgICAgIC8vIERlZmluZSB0aGUgZW50cnkgZm9yIHRoZSBjbGFzc2VzLmRleDoKKyAgICAgICAgamFyT3V0LnB1dE5leHRFbnRyeShuZXcgSmFyRW50cnkoImNsYXNzZXMuZGV4IikpOworCisgICAgICAgIC8vIEZpbGwgaW4gdGhlIGNsYXNzZXMuZGV4IGNvbnRlbnRzLCBpLmUuIHRoZSBEYWx2aWsgZXhlY3V0YWJsZSBjb2RlOgorICAgICAgICAvLyAoU2VlIGJlbG93IGZvciB0aGUgZGV0YWlsZWQgc291cmNlIGNvZGUgY29udGVudHMuKQorICAgICAgICBTdHJlYW1zLmNvcHkoU3VwcG9ydF9SZXNvdXJjZXMuZ2V0UmVzb3VyY2VTdHJlYW0oImN0c19kYWx2aWtFeGVjVGVzdF9jbGFzc2VzLmRleCIpLCBqYXJPdXQpOworCisgICAgICAgIC8vIE5vdyBhZGQgYSByZXNvdXJjZSBmaWxlOgorICAgICAgICAvLworICAgICAgICBqYXJPdXQucHV0TmV4dEVudHJ5KG5ldyBKYXJFbnRyeSgiZGFsdmlrRXhlY1Rlc3QvbXlSZXNvdXJjZSIpKTsKKyAgICAgICAgamFyT3V0LndyaXRlKCJUaGlzIFJlc291cmNlIGNvbnRhaW5zIHNvbWUgdGV4dC4iLmdldEJ5dGVzKCkpOworCisgICAgICAgIC8vIENsb3NlIHRoZSBzdHJlYW0gdG8gdGhlIGNvbXBsZXRlZCBKQVIgZmlsZS4KKyAgICAgICAgamFyT3V0LmNsb3NlKCk7CisKKyAgICAgICAgLy8gVGhlIHJlc3VsdGluZyBKQVIgZmlsZSBjb250YWlucyB0aGUgY2xhc3NlcyBsaXN0ZWQgYXQgdGhlIGVuZCBvZiB0aGlzIHRleHQsCisgICAgICAgIC8vIGxpa2UgdGhlICdjdHNfZGFsdmlrRXhlY1Rlc3QuamFyJyBhcyBwYXJ0IG9mIHRoZSByZXNvdXJjZXMsIHRvby4KKworICAgICAgICBTdHJpbmcgcmVzOworCisgICAgICAgIHJlcyA9IGV4ZWNEYWx2aWsoamFyRmlsZS5nZXRBYnNvbHV0ZVBhdGgoKSwgImRhbHZpa0V4ZWNUZXN0LkhlbGxvV29ybGQiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJIZWxsbyBBbmRyb2lkIFdvcmxkISIsICJIZWxsbyBBbmRyb2lkIFdvcmxkIVxuIiwgcmVzKTsKKworICAgICAgICByZXMgPSBleGVjRGFsdmlrKGphckZpbGUuZ2V0QWJzb2x1dGVQYXRoKCksICJkYWx2aWtFeGVjVGVzdC5SZXNvdXJjZUR1bXBlciIpOworICAgICAgICBhc3NlcnRUcnVlKCJBbmRyb2lkIFJlc291cmNlIER1bXBlciBzdGFydGVkIiwKKyAgICAgICAgICAgICAgICByZXMuY29udGFpbnMoIkFuZHJvaWQgUmVzb3VyY2UgRHVtcGVyIHN0YXJ0ZWQiKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoaXMgUmVzb3VyY2UgY29udGFpbnMgc29tZSB0ZXh0LiIsCisgICAgICAgICAgICAgICAgcmVzLmNvbnRhaW5zKCJUaGlzIFJlc291cmNlIGNvbnRhaW5zIHNvbWUgdGV4dC4iKSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBUaGlzIHRlc3QgZG9lcyBxdWl0ZSB0aGUgc2FtZSBhcyB0ZXN0X2V4ZWNDcmVhdGVkSmFyLCBidXQgaW5jbHVkZXMgYSBtYW5pZmVzdC4KKyAgICAgKiBOb3RlIGhvd2V2ZXIgdGhhdCB0aGUgRGFsdmlrIEpBUiBmb3JtYXQgZG9lcyBub3QgcmVxdWlyZSB0aGlzIG1hbmlmZXN0LgorICAgICAqIFdlIGp1c3QgdGVzdCB3aGV0aGVyIHRoZSBtYW5pZmVzdCBpcyBwbGFjZWQgY29ycmVjdGx5IHdpdGhpbiB0aGUgSkFSIGJ5CisgICAgICogZHVtcGluZyBpdHMgY29udGVudHMgcmVhZCBhcyBhIHNpbXBsZSB0ZXh0IHJlc291cmNlLgorICAgICAqIE5vISBXZSBjYW4ndCBkbyB0aGF0IHNvIGVhc2lseSBlaXRoZXIsIGFzIHRoZXJlIGFyZSBvdGhlciAocGFyZW50KSBKQVJzCisgICAgICogd2l0aCBhIG1hbmlmZXN0IGluc2lkZSwgdGFrZW4gd2l0aCBwcmVjZWRlbmNlLgorICAgICAqIFNvIHdlIHdpbGwgcmVvcGVuIHRoZSBKQVIgYXMgYSBKYXJGaWxlIGFuZCBjaGVjayB0aGUgbWFuaWZlc3QKKyAgICAgKiAgd2l0aCBhIHRvcCBsZXZlbCBlbmQtdG8tZW5kIGFwcHJvYWNoLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXhlY0NyZWF0ZWRKYXJXaXRoTWFuaWZlc3QgKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgamFyRmlsZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoImN0c19kYWx2aWtFeGVjVGVzdF8iLCAiLmphciIpOworICAgICAgICBqYXJGaWxlLmRlbGV0ZU9uRXhpdCgpOworCisgICAgICAgIC8vIENyZWF0ZSB0aGUgbWFuaWZlc3Q6CisgICAgICAgIE1hbmlmZXN0IG1hbmlmZXN0ID0gbmV3IE1hbmlmZXN0KCk7CisgICAgICAgIEF0dHJpYnV0ZXMgYXR0cnMgPSBtYW5pZmVzdC5nZXRNYWluQXR0cmlidXRlcygpOworICAgICAgICBhdHRycy5wdXQoQXR0cmlidXRlcy5OYW1lLk1BTklGRVNUX1ZFUlNJT04sICIzLjE0MTU5NjIiKTsKKyAgICAgICAgYXR0cnMucHV0KEF0dHJpYnV0ZXMuTmFtZS5NQUlOX0NMQVNTLCAiZGFsdmlrRXhlY1Rlc3QuSGVsbG9Xb3JsZCIpOworICAgICAgICBhdHRycy5wdXQoQXR0cmlidXRlcy5OYW1lLkNMQVNTX1BBVEgsIGphckZpbGUuZ2V0TmFtZSgpKTsKKworICAgICAgICAvLyBDcmVhdGUgYSBKQVIgb3V0cHV0IHN0cmVhbSBvbiB0aGUgdGVtcCBmaWxlIHVzaW5nIHRoZSBtYW5pZmVzdDoKKyAgICAgICAgSmFyT3V0cHV0U3RyZWFtIGphck91dCA9IG5ldyBKYXJPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oamFyRmlsZSksIG1hbmlmZXN0KTsKKworICAgICAgICAvLyBEZWZpbmUgdGhlIGVudHJ5IGZvciB0aGUgY2xhc3Nlcy5kZXg6CisgICAgICAgIGphck91dC5wdXROZXh0RW50cnkobmV3IEphckVudHJ5KCJjbGFzc2VzLmRleCIpKTsKKworICAgICAgICAvLyBGaWxsIGluIHRoZSBjbGFzc2VzLmRleCBjb250ZW50cywgaS5lLiB0aGUgRGFsdmlrIGV4ZWN1dGFibGUgY29kZToKKyAgICAgICAgLy8gKFNlZSBiZWxvdyBmb3IgdGhlIGRldGFpbGVkIHNvdXJjZSBjb2RlIGNvbnRlbnRzLikKKyAgICAgICAgU3RyZWFtcy5jb3B5KFN1cHBvcnRfUmVzb3VyY2VzLmdldFJlc291cmNlU3RyZWFtKCJjdHNfZGFsdmlrRXhlY1Rlc3RfY2xhc3Nlcy5kZXgiKSwgamFyT3V0KTsKKworICAgICAgICAvLyBOb3cgYWRkIGEgcmVzb3VyY2UgZmlsZToKKyAgICAgICAgLy8KKyAgICAgICAgamFyT3V0LnB1dE5leHRFbnRyeShuZXcgSmFyRW50cnkoImRhbHZpa0V4ZWNUZXN0L215UmVzb3VyY2UiKSk7CisgICAgICAgIGphck91dC53cml0ZSgiVGhpcyBSZXNvdXJjZSBjb250YWlucyBzb21lIHRleHQuIi5nZXRCeXRlcygpKTsKKworICAgICAgICAvLyBDbG9zZSB0aGUgc3RyZWFtIHRvIHRoZSBjb21wbGV0ZWQgSkFSIGZpbGUuCisgICAgICAgIGphck91dC5jbG9zZSgpOworCisgICAgICAgIC8vIFRoZSByZXN1bHRpbmcgSkFSIGZpbGUgY29udGFpbnMgdGhlIGNsYXNzZXMgbGlzdGVkIGF0IHRoZSBlbmQgb2YgdGhpcyB0ZXh0LAorICAgICAgICAvLyBsaWtlIHRoZSAnY3RzX2RhbHZpa0V4ZWNUZXN0LmphcicgYXMgcGFydCBvZiB0aGUgcmVzb3VyY2VzLCB0b28uCisKKyAgICAgICAgU3RyaW5nIHJlczsKKworICAgICAgICByZXMgPSBleGVjRGFsdmlrKGphckZpbGUuZ2V0QWJzb2x1dGVQYXRoKCksICJkYWx2aWtFeGVjVGVzdC5IZWxsb1dvcmxkIik7CisgICAgICAgIGFzc2VydEVxdWFscygiSGVsbG8gQW5kcm9pZCBXb3JsZCEiLCAiSGVsbG8gQW5kcm9pZCBXb3JsZCFcbiIsIHJlcyk7CisKKyAgICAgICAgcmVzID0gZXhlY0RhbHZpayhqYXJGaWxlLmdldEFic29sdXRlUGF0aCgpLCAiZGFsdmlrRXhlY1Rlc3QuUmVzb3VyY2VEdW1wZXIiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQW5kcm9pZCBSZXNvdXJjZSBEdW1wZXIgc3RhcnRlZCIsCisgICAgICAgICAgICAgICAgcmVzLmNvbnRhaW5zKCJBbmRyb2lkIFJlc291cmNlIER1bXBlciBzdGFydGVkIikpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGlzIFJlc291cmNlIGNvbnRhaW5zIHNvbWUgdGV4dC4iLAorICAgICAgICAgICAgICAgIHJlcy5jb250YWlucygiVGhpcyBSZXNvdXJjZSBjb250YWlucyBzb21lIHRleHQuIikpOworCisgICAgICAgIC8vIEFuZCBub3cgcmVyZWFkIHRoZSBtYW5pZmVzdDoKKyAgICAgICAgLy8KKyAgICAgICAgSmFyRmlsZSBqYXJJbiA9IG5ldyBKYXJGaWxlKGphckZpbGUpOworICAgICAgICBtYW5pZmVzdCA9IGphckluLmdldE1hbmlmZXN0KCk7CisgICAgICAgIGF0dHJzID0gbWFuaWZlc3QuZ2V0TWFpbkF0dHJpYnV0ZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJNQU5JRkVTVF9WRVJTSU9OIG11c3QgbWF0Y2ghIiwgIjMuMTQxNTk2MiIsCisgICAgICAgICAgICAgICAgYXR0cnMuZ2V0KEF0dHJpYnV0ZXMuTmFtZS5NQU5JRkVTVF9WRVJTSU9OKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiTUFJTl9DTEFTUyBtdXN0IG1hdGNoISIsICJkYWx2aWtFeGVjVGVzdC5IZWxsb1dvcmxkIiwKKyAgICAgICAgICAgICAgICBhdHRycy5nZXQoQXR0cmlidXRlcy5OYW1lLk1BSU5fQ0xBU1MpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDTEFTU19QQVRIIG11c3QgbWF0Y2ghIiwgamFyRmlsZS5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgYXR0cnMuZ2V0KEF0dHJpYnV0ZXMuTmFtZS5DTEFTU19QQVRIKSk7CisgICAgfQorCisKKyAgICAvKgorICAgICAqIFRoZSBmb2xsb3dpbmcgdHdvIGNsYXNzZXMgYXJlIGFkZGVkLCBoZXJlLCBvbmx5IGZvciBjb21wbGV0ZW5lc3MuCisgICAgICogVGhleSBmb3JtIHRoZSBjb250ZW50cyBvZiB0aGUgZGFsdmlrRXhlY1Rlc3QgcGFja2FnZSBjb250YWluZWQKKyAgICAgKiBpbiB0aGUgJ2N0c19kYWx2aWtFeGVjVGVzdF9jbGFzc2VzLmRleCcgcmVzb3VyY2UgZmlsZS4KKyAgICAgKi8KKyAgICAvKioKKyAgICAgKiBAaGlkZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSGVsbG9Xb3JsZCB7CisKKyAgICAgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJIZWxsbyBBbmRyb2lkIFdvcmxkISIpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFJlc291cmNlRHVtcGVyIHsKKworICAgICAgICBzdGF0aWMgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dHB1dEZyb20gKElucHV0U3RyZWFtIGlucHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVs1MTJdOworICAgICAgICAgICAgaW50IHRvdGFsID0gMDsKKyAgICAgICAgICAgIGludCBjb3VudDsKKyAgICAgICAgICAgIGNvdW50ID0gaW5wdXQucmVhZChidWZmZXIpOworICAgICAgICAgICAgd2hpbGUgKGNvdW50ICE9IC0xKSB7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZmZlciwgMCwgY291bnQpOworICAgICAgICAgICAgICAgIHRvdGFsID0gdG90YWwgKyBjb3VudDsKKyAgICAgICAgICAgICAgICBjb3VudCA9IGlucHV0LnJlYWQoYnVmZmVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBvdXQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiQW5kcm9pZCBSZXNvdXJjZSBEdW1wZXIgc3RhcnRlZCAiKTsKKyAgICAgICAgICAgIFN0cmluZyBmaWxlTmFtZTsKKyAgICAgICAgICAgIGlmIChhcmdzLmxlbmd0aCA+PSAxKSB7CisgICAgICAgICAgICAgICAgZmlsZU5hbWUgPSBhcmdzWzBdOworICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQuZm9ybWF0KCJmb3IgYXJndW1lbnQgJyVzJy5cbiIsIGZpbGVOYW1lKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgic3RhbmRhcmQgIik7CisgICAgICAgICAgICAgICAgZmlsZU5hbWUgPSAibXlSZXNvdXJjZSI7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJmb3Igc3RhbmRhcmQgJ215UmVzb3VyY2UnLiIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBSZXNvdXJjZUR1bXBlci5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKGZpbGVOYW1lKTsKKyAgICAgICAgICAgIGlmIChpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJSZXNvdXJjZSBvYnRhaW5lZCBhbmQgYmVpbmcgZHVtcGVkOiIpOworICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihvdXRwdXRGcm9tKGlzKS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvamFyL09sZEF0dHJpYnV0ZXNOYW1lVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2phci9PbGRBdHRyaWJ1dGVzTmFtZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNDk5NDE0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2phci9PbGRBdHRyaWJ1dGVzTmFtZVRlc3QuamF2YQpAQCAtMCwwICsxLDYzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC5qYXI7CisKK2ltcG9ydCBqYXZhLnV0aWwuamFyLkF0dHJpYnV0ZXM7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkQXR0cmlidXRlc05hbWVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLmphci5BdHRyaWJ1dGVzLk5hbWUjTmFtZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQXR0cmlidXRlc05hbWVfQ29uc3RydWN0b3IoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgQXR0cmlidXRlcy5OYW1lKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VxdWFsc0xqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICBBdHRyaWJ1dGVzLk5hbWUgYXR0cjEgPSBuZXcgQXR0cmlidXRlcy5OYW1lKCJBdHRyIik7CisgICAgICAgIEF0dHJpYnV0ZXMuTmFtZSBhdHRyMiA9IG5ldyBBdHRyaWJ1dGVzLk5hbWUoIkF0dHIiKTsKKworICAgICAgICBhc3NlcnRUcnVlKGF0dHIxLmVxdWFscyhhdHRyMikpOworICAgICAgICBhdHRyMiA9IG5ldyBBdHRyaWJ1dGVzLk5hbWUoIkF0dHIxIik7CisgICAgICAgIGFzc2VydEZhbHNlKGF0dHIxLmVxdWFscyhhdHRyMikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGFzaENvZGUoKSB7CisgICAgICAgIEF0dHJpYnV0ZXMuTmFtZSBhdHRyMSA9IG5ldyBBdHRyaWJ1dGVzLk5hbWUoIkF0dHIxIik7CisgICAgICAgIEF0dHJpYnV0ZXMuTmFtZSBhdHRyMiA9IG5ldyBBdHRyaWJ1dGVzLk5hbWUoIkF0dHIyIik7CisKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShhdHRyMS5oYXNoQ29kZSgpLCBhdHRyMi5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nKCkgeworICAgICAgICBTdHJpbmcgc3RyMSA9ICJBdHRyMSI7CisgICAgICAgIFN0cmluZyBzdHIyID0gIkF0dHIyIjsKKyAgICAgICAgQXR0cmlidXRlcy5OYW1lIGF0dHIxID0gbmV3IEF0dHJpYnV0ZXMuTmFtZShzdHIxKTsKKyAgICAgICAgQXR0cmlidXRlcy5OYW1lIGF0dHIyID0gbmV3IEF0dHJpYnV0ZXMuTmFtZSgiQXR0cjIiKTsKKworICAgICAgICBhc3NlcnRUcnVlKGF0dHIxLnRvU3RyaW5nKCkuZXF1YWxzKHN0cjEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhdHRyMi50b1N0cmluZygpLmVxdWFscyhzdHIyKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGF0dHIyLnRvU3RyaW5nKCkuZXF1YWxzKHN0cjEpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvamFyL09sZEF0dHJpYnV0ZXNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvamFyL09sZEF0dHJpYnV0ZXNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTk0NWUzMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9qYXIvT2xkQXR0cmlidXRlc1Rlc3QuamF2YQpAQCAtMCwwICsxLDEwNCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWwuamFyOworCitpbXBvcnQgamF2YS51dGlsLmphci5BdHRyaWJ1dGVzOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZEF0dHJpYnV0ZXNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHByaXZhdGUgQXR0cmlidXRlcyBhOworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIGEgPSBuZXcgQXR0cmlidXRlcygpOworICAgICAgICBhLnB1dFZhbHVlKCIxIiwgIm9uZSIpOworICAgICAgICBhLnB1dFZhbHVlKCIyIiwgInR3byIpOworICAgICAgICBhLnB1dFZhbHVlKCIzIiwgInRocmVlIik7CisgICAgICAgIGEucHV0VmFsdWUoIjQiLCAiZm91ciIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TGphdmFfbGFuZ19PYmplY3QoKSB7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGEuZ2V0VmFsdWUoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICBBdHRyaWJ1dGVzIGF0dHIgPSBuZXcgQXR0cmlidXRlcygpOworICAgICAgICBhc3NlcnRUcnVlKGF0dHIuc2l6ZSgpID49IDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JJKCkgeworICAgICAgICBBdHRyaWJ1dGVzIGF0dHIgPSBuZXcgQXR0cmlidXRlcygxMCk7CisgICAgICAgIGFzc2VydFRydWUoYXR0ci5zaXplKCkgPj0gMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRMamF2YV9sYW5nX09iamVjdF90cnVlKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoImEpIEluY29ycmVjdCB2YWx1ZSByZXR1cm5lZCIsICJvbmUiLCBhCisgICAgICAgICAgICAgICAgLmdldChuZXcgQXR0cmlidXRlcy5OYW1lKCIxIikpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiYikgSW5jb3JyZWN0IHZhbHVlIHJldHVybmVkIiwgYS5nZXQoIjAiKSk7CisgICAgICAgIGFzc2VydE51bGwoImIpIEluY29ycmVjdCB2YWx1ZSByZXR1cm5lZCIsIGEuZ2V0KCIxIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0VmFsdWVMamF2YV91dGlsX2phcl9BdHRyaWJ1dGVzX05hbWUoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiYSkgSW5jb3JyZWN0IHZhbHVlIHJldHVybmVkIiwgIm9uZSIsIGEKKyAgICAgICAgICAgICAgICAuZ2V0VmFsdWUobmV3IEF0dHJpYnV0ZXMuTmFtZSgiMSIpKSk7CisgICAgICAgIGFzc2VydE51bGwoImIpIEluY29ycmVjdCB2YWx1ZSByZXR1cm5lZCIsIGEKKyAgICAgICAgICAgICAgICAuZ2V0VmFsdWUobmV3IEF0dHJpYnV0ZXMuTmFtZSgiMCIpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSgpIHsKKyAgICAgICAgQXR0cmlidXRlcyBiID0gKEF0dHJpYnV0ZXMpIGEuY2xvbmUoKTsKKyAgICAgICAgYi5wdXRWYWx1ZSgiMzMiLCAiVGhpcnR5IHRocmVlIik7CisgICAgICAgIGFzc2VydE5vdFNhbWUoYS5oYXNoQ29kZSgpLCBiLmhhc2hDb2RlKCkpOworICAgICAgICBiID0gKEF0dHJpYnV0ZXMpIGEuY2xvbmUoKTsKKyAgICAgICAgYi5jbGVhcigpOworICAgICAgICBhc3NlcnROb3RTYW1lKGEuaGFzaENvZGUoKSwgYi5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3B1dFZhbHVlTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgQXR0cmlidXRlcyBiID0gbmV3IEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgYi5wdXQobmV3IEF0dHJpYnV0ZXMuTmFtZSgiMSIpLCAib25lIik7CisgICAgICAgIGIucHV0VmFsdWUoIjIiLCAidHdvIik7CisgICAgICAgIGIucHV0KG5ldyBBdHRyaWJ1dGVzLk5hbWUoIjMiKSwgInRocmVlIik7CisgICAgICAgIGIucHV0VmFsdWUoIjQiLCAiZm91ciIpOworCisgICAgICAgIGFzc2VydFRydWUoYS5lcXVhbHMoYikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiLnB1dFZhbHVlKG51bGwsICJudWxsIik7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAweDEwMDAwOyBpKyspIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgnMycpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiLnB1dFZhbHVlKG5ldyBTdHJpbmcoc2IpLCAid3JvbmcgbmFtZSIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9qYXIvT2xkSmFyRW50cnlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvamFyL09sZEphckVudHJ5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIxNDQ0YTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvamFyL09sZEphckVudHJ5VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTM4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC5qYXI7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuamFyLkphckVudHJ5OworaW1wb3J0IGphdmEudXRpbC5qYXIuSmFyRmlsZTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEVudHJ5OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LnJlc291cmNlLlN1cHBvcnRfUmVzb3VyY2VzOworCisKK3B1YmxpYyBjbGFzcyBPbGRKYXJFbnRyeVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHJpdmF0ZSBaaXBFbnRyeSB6aXBFbnRyeTsKKyAgICBwcml2YXRlIEphckVudHJ5IGphckVudHJ5OworICAgIHByaXZhdGUgSmFyRmlsZSBqYXJGaWxlOworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGphck5hbWUgPSAiaHl0c19wYXRjaC5qYXIiOworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGVudHJ5TmFtZSA9ICJmb28vYmFyL0EuY2xhc3MiOworICAgIHByaXZhdGUgRmlsZSByZXNvdXJjZXM7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICByZXNvdXJjZXMgPSBTdXBwb3J0X1Jlc291cmNlcy5jcmVhdGVUZW1wRm9sZGVyKCk7CisgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgamFyTmFtZSk7CisgICAgICAgIGphckZpbGUgPSBuZXcgSmFyRmlsZShuZXcgRmlsZShyZXNvdXJjZXMsIGphck5hbWUpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpZiAoamFyRmlsZSAhPSBudWxsKSB7CisgICAgICAgICAgICBqYXJGaWxlLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogamF2YS51dGlsLmphci5KYXJFbnRyeSNKYXJFbnRyeShqYXZhLnV0aWwuamFyLkphckVudHJ5KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV91dGlsX2phcl9KYXJFbnRyeV9vbl9udWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSmFyRW50cnkgbmV3SmFyRW50cnkgPSBuZXcgSmFyRW50cnkoamFyRmlsZS5nZXRKYXJFbnRyeShlbnRyeU5hbWUpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXdKYXJFbnRyeSk7CisKKyAgICAgICAgamFyRW50cnkgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3SmFyRW50cnkgPSBuZXcgSmFyRW50cnkoamFyRW50cnkpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuamFyLkphckVudHJ5I0phckVudHJ5KGphdmEudXRpbC56aXAuWmlwRW50cnkpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX3V0aWxfemlwX1ppcEVudHJ5KCkgeworICAgICAgICBhc3NlcnROb3ROdWxsKCJKYXIgZmlsZSBpcyBudWxsIiwgamFyRmlsZSk7CisgICAgICAgIHppcEVudHJ5ID0gamFyRmlsZS5nZXRFbnRyeShlbnRyeU5hbWUpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJaaXAgZW50cnkgaXMgbnVsbCIsIHppcEVudHJ5KTsKKyAgICAgICAgamFyRW50cnkgPSBuZXcgSmFyRW50cnkoemlwRW50cnkpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJKYXIgZW50cnkgaXMgbnVsbCIsIGphckVudHJ5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBlbnRyeSBjb25zdHJ1Y3RlZC0td3JvbmcgbmFtZSIsIGVudHJ5TmFtZSwgamFyRW50cnkKKyAgICAgICAgICAgICAgICAuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBlbnRyeSBjb25zdHJ1Y3RlZC0td3Jvbmcgc2l6ZSIsIDMxMSwgamFyRW50cnkKKyAgICAgICAgICAgICAgICAuZ2V0U2l6ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuamFyLkphckVudHJ5I2dldEF0dHJpYnV0ZXMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0QXR0cmlidXRlcygpIHsKKyAgICAgICAgSmFyRmlsZSBhdHRySmFyID0gbnVsbDsKKyAgICAgICAgRmlsZSBmaWxlID0gbnVsbDsKKworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsICJCcm9rZW5fbWFuaWZlc3QuamFyIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhdHRySmFyID0gbmV3IEphckZpbGUobmV3IEZpbGUocmVzb3VyY2VzLCAiQnJva2VuX21hbmlmZXN0LmphciIpKTsKKyAgICAgICAgICAgIGphckVudHJ5ID0gYXR0ckphci5nZXRKYXJFbnRyeSgiTUVUQS1JTkYvIik7CisgICAgICAgICAgICBqYXJFbnRyeS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiSmFyIGZpbGUgaXMgbnVsbCIsIGphckZpbGUpOworICAgICAgICB6aXBFbnRyeSA9IGphckZpbGUuZ2V0RW50cnkoZW50cnlOYW1lKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiWmlwIGVudHJ5IGlzIG51bGwiLCB6aXBFbnRyeSk7CisgICAgICAgIGphckVudHJ5ID0gbmV3IEphckVudHJ5KGVudHJ5TmFtZSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkphciBlbnRyeSBpcyBudWxsIiwgamFyRW50cnkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGVudHJ5IGNvbnN0cnVjdGVkLS13cm9uZyBuYW1lIiwgZW50cnlOYW1lLCBqYXJFbnRyeQorICAgICAgICAgICAgICAgIC5nZXROYW1lKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgamFyRW50cnkgPSBuZXcgSmFyRW50cnkoKFN0cmluZykgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMHgxMDAwMDsgaSsrKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoJzMnKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgamFyRW50cnkgPSBuZXcgSmFyRW50cnkobmV3IFN0cmluZyhzYikpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV91dGlsX2phcl9KYXJFbnRyeSgpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiSmFyIGZpbGUgaXMgbnVsbCIsIGphckZpbGUpOworICAgICAgICBKYXJFbnRyeSBqZSA9IGphckZpbGUuZ2V0SmFyRW50cnkoZW50cnlOYW1lKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiSmFyIGVudHJ5IGlzIG51bGwiLCBqZSk7CisgICAgICAgIGphckVudHJ5ID0gbmV3IEphckVudHJ5KGplKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiSmFyIGVudHJ5IGlzIG51bGwiLCBqYXJFbnRyeSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgZW50cnkgY29uc3RydWN0ZWQtLXdyb25nIG5hbWUiLCBlbnRyeU5hbWUsIGphckVudHJ5CisgICAgICAgICAgICAgICAgLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgZW50cnkgY29uc3RydWN0ZWQtLXdyb25nIHNpemUiLCAzMTEsIGphckVudHJ5CisgICAgICAgICAgICAgICAgLmdldFNpemUoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2phci9PbGRKYXJFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvamFyL09sZEphckV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOWQ2YzVkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2phci9PbGRKYXJFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWwuamFyOworCitpbXBvcnQgamF2YS51dGlsLmphci5KYXJFeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkSmFyRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuamFyLkphckV4Y2VwdGlvbiNKYXJFeGNlcHRpb24oamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEphckV4Y2VwdGlvbiBleCA9IG5ldyBKYXJFeGNlcHRpb24oKTsKKyAgICAgICAgSmFyRXhjZXB0aW9uIGV4MSA9IG5ldyBKYXJFeGNlcHRpb24oIlRlc3Qgc3RyaW5nIik7CisgICAgICAgIEphckV4Y2VwdGlvbiBleDIgPSBuZXcgSmFyRXhjZXB0aW9uKG51bGwpOworICAgICAgICBhc3NlcnROb3RTYW1lKGV4LCBleDEpOworICAgICAgICBhc3NlcnROb3RTYW1lKGV4LmdldE1lc3NhZ2UoKSwgZXgxLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE5vdFNhbWUoZXgsIGV4Mik7CisgICAgICAgIGFzc2VydFNhbWUoZXguZ2V0TWVzc2FnZSgpLCBleDIuZ2V0TWVzc2FnZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSmFyRXhjZXB0aW9uIGV4MSA9IG5ldyBKYXJFeGNlcHRpb24oIlRlc3Qgc3RyaW5nIik7CisgICAgICAgIEphckV4Y2VwdGlvbiBleDIgPSBuZXcgSmFyRXhjZXB0aW9uKG51bGwpOworICAgICAgICBhc3NlcnROb3RTYW1lKGV4MSwgZXgyKTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShleDEuZ2V0TWVzc2FnZSgpLCBleDIuZ2V0TWVzc2FnZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvamFyL09sZEphckZpbGVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvamFyL09sZEphckZpbGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWJmMjVlNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9qYXIvT2xkSmFyRmlsZVRlc3QuamF2YQpAQCAtMCwwICsxLDE2MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLmphcjsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLmphci5KYXJFbnRyeTsKK2ltcG9ydCBqYXZhLnV0aWwuamFyLkphckZpbGU7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBGaWxlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LnJlc291cmNlLlN1cHBvcnRfUmVzb3VyY2VzOworCitwdWJsaWMgY2xhc3MgT2xkSmFyRmlsZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBqYXJOYW1lID0gImh5dHNfcGF0Y2guamFyIjsgLy8gYSAnbm9ybWFsJyBqYXIgZmlsZQorICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGVudHJ5TmFtZSA9ICJmb28vYmFyL0EuY2xhc3MiOworICAgIHByaXZhdGUgRmlsZSByZXNvdXJjZXMgPSBTdXBwb3J0X1Jlc291cmNlcy5jcmVhdGVUZW1wRm9sZGVyKCk7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fRmlsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSmFyRmlsZShuZXcgRmlsZSgiV3JvbmcuZmlsZSIpKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJT0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBqYXJOYW1lKTsKKyAgICAgICAgbmV3IEphckZpbGUobmV3IEZpbGUocmVzb3VyY2VzLCBqYXJOYW1lKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKYXJGaWxlKCJXcm9uZy5maWxlIik7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgamFyTmFtZSk7CisgICAgICAgIFN0cmluZyBmaWxlTmFtZSA9IChuZXcgRmlsZShyZXNvdXJjZXMsIGphck5hbWUpKS5nZXRDYW5vbmljYWxQYXRoKCk7CisgICAgICAgIG5ldyBKYXJGaWxlKGZpbGVOYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmdaKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKYXJGaWxlKCJXcm9uZy5maWxlIiwgZmFsc2UpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IElPRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsIGphck5hbWUpOworICAgICAgICBTdHJpbmcgZmlsZU5hbWUgPSAobmV3IEZpbGUocmVzb3VyY2VzLCBqYXJOYW1lKSkuZ2V0Q2Fub25pY2FsUGF0aCgpOworICAgICAgICBuZXcgSmFyRmlsZShmaWxlTmFtZSwgdHJ1ZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX0ZpbGVaKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBKYXJGaWxlKG5ldyBGaWxlKCJXcm9uZy5maWxlIiksIHRydWUpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IElPRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsIGphck5hbWUpOworICAgICAgICBuZXcgSmFyRmlsZShuZXcgRmlsZShyZXNvdXJjZXMsIGphck5hbWUpLCBmYWxzZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX0ZpbGVaSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSmFyRmlsZShuZXcgRmlsZSgiV3JvbmcuZmlsZSIpLCB0cnVlLAorICAgICAgICAgICAgICAgICAgICBaaXBGaWxlLk9QRU5fUkVBRCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgamFyTmFtZSk7CisgICAgICAgIG5ldyBKYXJGaWxlKG5ldyBGaWxlKHJlc291cmNlcywgamFyTmFtZSksIGZhbHNlLAorICAgICAgICAgICAgICAgIFppcEZpbGUuT1BFTl9SRUFEKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBqYXJOYW1lKTsKKyAgICAgICAgICAgIG5ldyBKYXJGaWxlKG5ldyBGaWxlKHJlc291cmNlcywgamFyTmFtZSksIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICBaaXBGaWxlLk9QRU5fUkVBRCB8IFppcEZpbGUuT1BFTl9ERUxFVEUgKyAzMyk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBtb2RpZmllZEphck5hbWUgPSAiTW9kaWZpZWRfU0ZfRW50cnlBdHRyaWJ1dGVzLmphciI7CisgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgbW9kaWZpZWRKYXJOYW1lKTsKKyAgICAgICAgSmFyRmlsZSBqYXJGaWxlID0gbmV3IEphckZpbGUobmV3IEZpbGUocmVzb3VyY2VzLCBtb2RpZmllZEphck5hbWUpLCB0cnVlKTsKKyAgICAgICAgamFyRmlsZS5lbnRyaWVzKCk7CisKKyAgICAgICAgamFyRmlsZS5jbG9zZSgpOworICAgICAgICBqYXJGaWxlLmNsb3NlKCk7CisKKyAgICAgICAgLy8gQ2FuIG5vdCBjaGVjayBJT0V4Y2VwdGlvbgorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5wdXRTdHJlYW1MamF2YV91dGlsX2phcl9KYXJFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgamFyTmFtZSk7CisgICAgICAgIEZpbGUgbG9jYWxGaWxlID0gbmV3IEZpbGUocmVzb3VyY2VzLCBqYXJOYW1lKTsKKworICAgICAgICBieXRlW10gYiA9IG5ldyBieXRlWzEwMjRdOworICAgICAgICBKYXJGaWxlIGpmID0gbmV3IEphckZpbGUobG9jYWxGaWxlKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBqZi5nZXRJbnB1dFN0cmVhbShqZi5nZXRFbnRyeShlbnRyeU5hbWUpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW52YWxpZCBzdHJlYW0iLCBpcy5hdmFpbGFibGUoKSA+IDApOworICAgICAgICBpbnQgciA9IGlzLnJlYWQoYiwgMCwgMTAyNCk7CisgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgc3RyaW5nQnVmZmVyID0gbmV3IFN0cmluZ0J1aWxkZXIocik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcjsgaSsrKSB7CisgICAgICAgICAgICBzdHJpbmdCdWZmZXIuYXBwZW5kKChjaGFyKSAoYltpXSAmIDB4ZmYpKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgY29udGVudHMgPSBzdHJpbmdCdWZmZXIudG9TdHJpbmcoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHN0cmVhbSByZWFkIiwgY29udGVudHMuaW5kZXhPZigiYmFyIikgPiAwKTsKKyAgICAgICAgamYuY2xvc2UoKTsKKworICAgICAgICBqZiA9IG5ldyBKYXJGaWxlKGxvY2FsRmlsZSk7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gamYuZ2V0SW5wdXRTdHJlYW0obmV3IEphckVudHJ5KCJpbnZhbGlkIikpOworICAgICAgICBhc3NlcnROdWxsKCJHb3Qgc3RyZWFtIGZvciBub24tZXhpc3RlbnQgZW50cnkiLCBpbik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgamFyTmFtZSk7CisgICAgICAgICAgICBGaWxlIHNpZ25lZEZpbGUgPSBuZXcgRmlsZShyZXNvdXJjZXMsIGphck5hbWUpOworICAgICAgICAgICAgamYgPSBuZXcgSmFyRmlsZShzaWduZWRGaWxlKTsKKyAgICAgICAgICAgIEphckVudHJ5IGpyZSA9IG5ldyBKYXJFbnRyeSgiZm9vL2Jhci9BLmNsYXNzIik7CisgICAgICAgICAgICBqZi5nZXRJbnB1dFN0cmVhbShqcmUpOworICAgICAgICAgICAgLy8gSW5wdXRTdHJlYW0gcmV0dXJuZWQgaW4gYW55IHdheSwgZXhjZXB0aW9uIGNhbiBiZSB0aHJvd24gaW4gY2FzZQorICAgICAgICAgICAgLy8gb2YgcmVhZGluZyBmcm9tIHRoaXMgc3RyZWFtIG9ubHkuCisgICAgICAgICAgICAvLyBmYWlsKCJTaG91bGQgdGhyb3cgWmlwRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFppcEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgamFyTmFtZSk7CisgICAgICAgICAgICBGaWxlIHNpZ25lZEZpbGUgPSBuZXcgRmlsZShyZXNvdXJjZXMsIGphck5hbWUpOworICAgICAgICAgICAgamYgPSBuZXcgSmFyRmlsZShzaWduZWRGaWxlKTsKKyAgICAgICAgICAgIEphckVudHJ5IGpyZSA9IG5ldyBKYXJFbnRyeSgiZm9vL2Jhci9BLmNsYXNzIik7CisgICAgICAgICAgICBqZi5jbG9zZSgpOworICAgICAgICAgICAgamYuZ2V0SW5wdXRTdHJlYW0oanJlKTsKKyAgICAgICAgICAgIC8vIElucHV0U3RyZWFtIHJldHVybmVkIGluIGFueSB3YXksIGV4Y2VwdGlvbiBjYW4gYmUgdGhyb3duIGluIGNhc2UKKyAgICAgICAgICAgIC8vIG9mIHJlYWRpbmcgZnJvbSB0aGlzIHN0cmVhbSBvbmx5LgorICAgICAgICAgICAgLy8gVGhlIHNhbWUgZm9yIElPRXhjZXB0aW9uCisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2phci9PbGRKYXJJbnB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9qYXIvT2xkSmFySW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzdiYjNiYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9qYXIvT2xkSmFySW5wdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSw5MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWwuamFyOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuamFyLkphcklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRW50cnk7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFeGNlcHRpb247CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5yZXNvdXJjZS5TdXBwb3J0X1Jlc291cmNlczsKKworcHVibGljIGNsYXNzIE9sZEphcklucHV0U3RyZWFtVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fSW5wdXRTdHJlYW1aKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gd2UgbmVlZCBhIGJ1ZmZlcmVkIHN0cmVhbSBiZWNhdXNlIEJ5dGVBcnJheUlucHV0U3RyZWFtLmNsb3NlKCkgaXMgYSBuby1vcAorICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbMF0pKTsKKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgICAgICBuZXcgSmFySW5wdXRTdHJlYW0oaXMsIGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisKKyAgICBjbGFzcyBNb2NrX0phcklucHV0U3RyZWFtIGV4dGVuZHMgSmFySW5wdXRTdHJlYW0geworCisgICAgICAgIHB1YmxpYyBNb2NrX0phcklucHV0U3RyZWFtKElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIoaW4pOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFppcEVudHJ5IGNyZWF0ZVppcEVudHJ5KFN0cmluZyBzdHIpIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jcmVhdGVaaXBFbnRyeShzdHIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jcmVhdGVaaXBFbnRyeUxqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgcmVzb3VyY2VzID0gU3VwcG9ydF9SZXNvdXJjZXMuY3JlYXRlVGVtcEZvbGRlcigpOworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsICJCcm9rZW5fZW50cnkuamFyIik7CisgICAgICAgIElucHV0U3RyZWFtIGlzID0gU3VwcG9ydF9SZXNvdXJjZXMuZ2V0U3RyZWFtKCJCcm9rZW5fZW50cnkuamFyIik7CisgICAgICAgIE1vY2tfSmFySW5wdXRTdHJlYW0gbWppcyA9IG5ldyBNb2NrX0phcklucHV0U3RyZWFtKGlzKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChtamlzLmNyZWF0ZVppcEVudHJ5KCJOZXcgZW50cnkiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkJFpJSSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGaWxlIHJlc291cmNlcyA9IFN1cHBvcnRfUmVzb3VyY2VzLmNyZWF0ZVRlbXBGb2xkZXIoKTsKKyAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCAiQnJva2VuX2VudHJ5X2RhdGEuamFyIik7CisgICAgICAgIElucHV0U3RyZWFtIGlzID0gU3VwcG9ydF9SZXNvdXJjZXMuZ2V0U3RyZWFtKCJCcm9rZW5fZW50cnlfZGF0YS5qYXIiKTsKKyAgICAgICAgSmFySW5wdXRTdHJlYW0gamlzID0gbmV3IEphcklucHV0U3RyZWFtKGlzLCB0cnVlKTsKKyAgICAgICAgYnl0ZSBiW10gPSBuZXcgYnl0ZVsxMDBdOworCisgICAgICAgIGppcy5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgamlzLnJlYWQoYiwgMCwgMTAwKTsKKyAgICAgICAgamlzLmdldE5leHRFbnRyeSgpOworICAgICAgICBqaXMuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgIGppcy5nZXROZXh0RW50cnkoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgamlzLnJlYWQoYiwgMCwgMTAwKTsKKyAgICAgICAgICAgIGZhaWwoIlppcEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChaaXBFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgamlzLmNsb3NlKCk7ICAvLyBBbmRyb2lkIHRocm93cyBleGNlcHRpb24gaGVyZSwgYWxyZWFkeSEKKyAgICAgICAgICAgIGppcy5yZWFkKGIsIDAsIDEwMCk7ICAvLyBCdXQgUkkgaGVyZSwgb25seSEKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2phci9PbGRKYXJPdXRwdXRTdHJlYW1UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvamFyL09sZEphck91dHB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNWUyZjMyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2phci9PbGRKYXJPdXRwdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWwuamFyOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5qYXIuSmFyRW50cnk7CitpbXBvcnQgamF2YS51dGlsLmphci5KYXJPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLmphci5NYW5pZmVzdDsKKworcHVibGljIGNsYXNzIE9sZEphck91dHB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF9wdXROZXh0RW50cnlMamF2YV91dGlsX3ppcF9aaXBFbnRyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgZW50cnlOYW1lID0gImZvby9iYXIvZXhlY2phcnRlc3QvTWFpbkNsYXNzLmNsYXNzIjsKKyAgICAgICAgTWFuaWZlc3QgbmV3bWFuID0gbmV3IE1hbmlmZXN0KCk7CisgICAgICAgIEZpbGUgb3V0cHV0SmFyID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiaHl0c18iLCAiLmphciIpOworICAgICAgICBPdXRwdXRTdHJlYW0gb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRwdXRKYXIpOworICAgICAgICBKYXJPdXRwdXRTdHJlYW0gam91dCA9IG5ldyBKYXJPdXRwdXRTdHJlYW0ob3MsIG5ld21hbik7CisgICAgICAgIG9zLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBqb3V0LnB1dE5leHRFbnRyeShuZXcgSmFyRW50cnkoZW50cnlOYW1lKSk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2phci9PbGRNYW5pZmVzdFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9qYXIvT2xkTWFuaWZlc3RUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTU1MmFlZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9qYXIvT2xkTWFuaWZlc3RUZXN0LmphdmEKQEAgLTAsMCArMSwxNDQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC5qYXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEudXRpbC5qYXIuQXR0cmlidXRlczsKK2ltcG9ydCBqYXZhLnV0aWwuamFyLk1hbmlmZXN0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LnJlc291cmNlLlN1cHBvcnRfUmVzb3VyY2VzOworCitwdWJsaWMgY2xhc3MgT2xkTWFuaWZlc3RUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX3V0aWxfamFyX01hbmlmZXN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLmphci5NYW5pZmVzdCgpCisgICAgICAgIE1hbmlmZXN0IGVtcHR5TWFuaWZlc3QgPSBuZXcgTWFuaWZlc3QoKTsKKyAgICAgICAgTWFuaWZlc3QgZW1wdHlDbG9uZSA9IG5ldyBNYW5pZmVzdChlbXB0eU1hbmlmZXN0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGhhdmUgbm8gZW50cmllcyIsIGVtcHR5Q2xvbmUuZ2V0RW50cmllcygpLmlzRW1wdHkoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBoYXZlIG5vIG1haW4gYXR0cmlidXRlcyIsIGVtcHR5Q2xvbmUKKyAgICAgICAgICAgICAgICAuZ2V0TWFpbkF0dHJpYnV0ZXMoKS5pc0VtcHR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZW1wdHlDbG9uZSwgZW1wdHlNYW5pZmVzdCk7CisgICAgICAgIGFzc2VydEVxdWFscyhlbXB0eUNsb25lLCBlbXB0eU1hbmlmZXN0LmNsb25lKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRBdHRyaWJ1dGUoQXR0cmlidXRlcyBhdHRyLCBTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0ICIgKyBuYW1lLCB2YWx1ZSwgYXR0ci5nZXRWYWx1ZShuYW1lKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrTWFuaWZlc3QoTWFuaWZlc3QgbWFuaWZlc3QpIHsKKyAgICAgICAgQXR0cmlidXRlcyBtYWluID0gbWFuaWZlc3QuZ2V0TWFpbkF0dHJpYnV0ZXMoKTsKKyAgICAgICAgYXNzZXJ0QXR0cmlidXRlKG1haW4sICJCdW5kbGUtTmFtZSIsICJDbGllbnRTdXBwb3J0Iik7CisgICAgICAgIGFzc2VydEF0dHJpYnV0ZShtYWluLCAiQnVuZGxlLURlc2NyaXB0aW9uIiwKKyAgICAgICAgICAgICAgICAiUHJvdmlkZXMgU2Vzc2lvblNlcnZpY2UsIEF1dGhlbnRpY2F0aW9uU2VydmljZS4gRXh0ZW5kcyBSZWdpc3RyeVNlcnZpY2UuIik7CisgICAgICAgIGFzc2VydEF0dHJpYnV0ZShtYWluLCAiQnVuZGxlLUFjdGl2YXRvciIsCisgICAgICAgICAgICAgICAgImNvbS5pYm0uaXZlLmVjY29tbS5jbGllbnQuc3VwcG9ydC5DbGllbnRTdXBwb3J0QWN0aXZhdG9yIik7CisgICAgICAgIGFzc2VydEF0dHJpYnV0ZSgKKyAgICAgICAgICAgICAgICBtYWluLAorICAgICAgICAgICAgICAgICJJbXBvcnQtUGFja2FnZSIsCisgICAgICAgICAgICAgICAgImNvbS5pYm0uaXZlLmVjY29tbS5jbGllbnQuc2VydmljZXMubG9nLGNvbS5pYm0uaXZlLmVjY29tbS5jbGllbnQuc2VydmljZXMucmVnaXN0cnksY29tLmlibS5pdmUuZWNjb21tLnNlcnZpY2UucmVnaXN0cnk7IHNwZWNpZmljYXRpb24tdmVyc2lvbj0xLjAuMCxjb20uaWJtLml2ZS5lY2NvbW0uc2VydmljZS5zZXNzaW9uOyBzcGVjaWZpY2F0aW9uLXZlcnNpb249MS4wLjAsY29tLmlibS5pdmUuZWNjb21tLnNlcnZpY2UuZnJhbWV3b3JrOyBzcGVjaWZpY2F0aW9uLXZlcnNpb249MS4yLjAsb3JnLm9zZ2kuZnJhbWV3b3JrOyBzcGVjaWZpY2F0aW9uLXZlcnNpb249MS4wLjAsb3JnLm9zZ2kuc2VydmljZS5sb2c7IHNwZWNpZmljYXRpb24tdmVyc2lvbj0xLjAuMCxjb20uaWJtLml2ZS5lY2NvbW0uZmxhc2g7IHNwZWNpZmljYXRpb24tdmVyc2lvbj0xLjIuMCxjb20uaWJtLml2ZS5lY2NvbW0uY2xpZW50LnhtbCxjb20uaWJtLml2ZS5lY2NvbW0uY2xpZW50Lmh0dHAuY29tbW9uLGNvbS5pYm0uaXZlLmVjY29tbS5jbGllbnQuaHR0cC5jbGllbnQiKTsKKyAgICAgICAgYXNzZXJ0QXR0cmlidXRlKAorICAgICAgICAgICAgICAgIG1haW4sCisgICAgICAgICAgICAgICAgIkltcG9ydC1TZXJ2aWNlIiwKKyAgICAgICAgICAgICAgICAib3JnLm9zZ2kuc2VydmljZS5sb2cuTG9nUmVhZGVyU2VydmljZW9yZy5vc2dpLnNlcnZpY2UubG9nLkxvZ1NlcnZpY2UsY29tLmlibS5pdmUuZWNjb21tLnNlcnZpY2UucmVnaXN0cnkuUmVnaXN0cnlTZXJ2aWNlIik7CisgICAgICAgIGFzc2VydEF0dHJpYnV0ZSgKKyAgICAgICAgICAgICAgICBtYWluLAorICAgICAgICAgICAgICAgICJFeHBvcnQtUGFja2FnZSIsCisgICAgICAgICAgICAgICAgImNvbS5pYm0uaXZlLmVjY29tbS5jbGllbnQuc2VydmljZXMuYXV0aGVudGljYXRpb247IHNwZWNpZmljYXRpb24tdmVyc2lvbj0xLjAuMCxjb20uaWJtLml2ZS5lY2NvbW0uc2VydmljZS5hdXRoZW50aWNhdGlvbjsgc3BlY2lmaWNhdGlvbi12ZXJzaW9uPTEuMC4wLGNvbS5pYm0uaXZlLmVjY29tbS5jb21tb247IHNwZWNpZmljYXRpb24tdmVyc2lvbj0xLjAuMCxjb20uaWJtLml2ZS5lY2NvbW0uY2xpZW50LnNlcnZpY2VzLnJlZ2lzdHJ5LnN0b3JlOyBzcGVjaWZpY2F0aW9uLXZlcnNpb249MS4wLjAiKTsKKyAgICAgICAgYXNzZXJ0QXR0cmlidXRlKAorICAgICAgICAgICAgICAgIG1haW4sCisgICAgICAgICAgICAgICAgIkV4cG9ydC1TZXJ2aWNlIiwKKyAgICAgICAgICAgICAgICAiY29tLmlibS5pdmUuZWNjb21tLnNlcnZpY2UuYXV0aGVudGljYXRpb24uQXV0aGVudGljYXRpb25TZXJ2aWNlLGNvbS5pYm0uaXZlLmVjY29tbS5zZXJ2aWNlLnNlc3Npb24uU2Vzc2lvblNlcnZpY2UiKTsKKyAgICAgICAgYXNzZXJ0QXR0cmlidXRlKG1haW4sICJCdW5kbGUtVmVuZG9yIiwgIklCTSIpOworICAgICAgICBhc3NlcnRBdHRyaWJ1dGUobWFpbiwgIkJ1bmRsZS1WZXJzaW9uIiwgIjEuMi4wIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jbG9uZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIE1hbmlmZXN0IGVtcHR5TWFuaWZlc3QgPSBuZXcgTWFuaWZlc3QoKTsKKyAgICAgICAgTWFuaWZlc3QgZW1wdHlDbG9uZSA9IChNYW5pZmVzdCkgZW1wdHlNYW5pZmVzdC5jbG9uZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgaGF2ZSBubyBlbnRyaWVzIiwgZW1wdHlDbG9uZS5nZXRFbnRyaWVzKCkuaXNFbXB0eSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGhhdmUgbm8gbWFpbiBhdHRyaWJ1dGVzIiwgZW1wdHlDbG9uZQorICAgICAgICAgICAgICAgIC5nZXRNYWluQXR0cmlidXRlcygpLmlzRW1wdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhlbXB0eUNsb25lLCBlbXB0eU1hbmlmZXN0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGVtcHR5TWFuaWZlc3QuY2xvbmUoKS5nZXRDbGFzcygpLmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAiamF2YS51dGlsLmphci5NYW5pZmVzdCIpOworCisgICAgICAgIE1hbmlmZXN0IG1hbmlmZXN0ID0gbmV3IE1hbmlmZXN0KG5ldyBVUkwoU3VwcG9ydF9SZXNvdXJjZXMKKyAgICAgICAgICAgICAgICAuZ2V0VVJMKCJtYW5pZmVzdC9oeXRzX01BTklGRVNULk1GIikpLm9wZW5TdHJlYW0oKSk7CisgICAgICAgIE1hbmlmZXN0IG1hbmlmZXN0Q2xvbmUgPSAoTWFuaWZlc3QpIG1hbmlmZXN0LmNsb25lKCk7CisgICAgICAgIG1hbmlmZXN0Q2xvbmUuZ2V0TWFpbkF0dHJpYnV0ZXMoKTsKKyAgICAgICAgY2hlY2tNYW5pZmVzdChtYW5pZmVzdENsb25lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VxdWFscygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIE1hbmlmZXN0IG1hbmlmZXN0MSA9IG5ldyBNYW5pZmVzdChuZXcgVVJMKFN1cHBvcnRfUmVzb3VyY2VzLmdldFVSTCgKKyAgICAgICAgICAgICAgICAibWFuaWZlc3QvaHl0c19NQU5JRkVTVC5NRiIpKS5vcGVuU3RyZWFtKCkpOworICAgICAgICBNYW5pZmVzdCBtYW5pZmVzdDIgPSBuZXcgTWFuaWZlc3QobmV3IFVSTChTdXBwb3J0X1Jlc291cmNlcy5nZXRVUkwoCisgICAgICAgICAgICAgICAgIm1hbmlmZXN0L2h5dHNfTUFOSUZFU1QuTUYiKSkub3BlblN0cmVhbSgpKTsKKyAgICAgICAgTWFuaWZlc3QgbWFuaWZlc3QzID0gbmV3IE1hbmlmZXN0KCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYW5pZmVzdDEuZXF1YWxzKG1hbmlmZXN0MSkpOworICAgICAgICBhc3NlcnRUcnVlKG1hbmlmZXN0MS5lcXVhbHMobWFuaWZlc3QyKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG1hbmlmZXN0MS5lcXVhbHMobWFuaWZlc3QzKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG1hbmlmZXN0MS5lcXVhbHModGhpcykpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGVMamF2YV9pb19PdXRwdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlIGJbXTsKKyAgICAgICAgTWFuaWZlc3QgbWFuaWZlc3QxID0gbnVsbDsKKyAgICAgICAgTWFuaWZlc3QgbWFuaWZlc3QyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1hbmlmZXN0MSA9IG5ldyBNYW5pZmVzdChuZXcgVVJMKFN1cHBvcnRfUmVzb3VyY2VzCisgICAgICAgICAgICAgICAgICAgIC5nZXRVUkwoIm1hbmlmZXN0L2h5dHNfTUFOSUZFU1QuTUYiKSkub3BlblN0cmVhbSgpKTsKKyAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIk1hbGZvcm1lZCBVUkwiKTsKKyAgICAgICAgfQorCisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCisgICAgICAgIG1hbmlmZXN0MS53cml0ZShiYW9zKTsKKworICAgICAgICBiID0gYmFvcy50b0J5dGVBcnJheSgpOworCisgICAgICAgIEZpbGUgZiA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoIjExMSIsICIxMTEiKTsKKyAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBmb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShmKTsKKyAgICAgICAgZm9zLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtYW5pZmVzdDEud3JpdGUoZm9zKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgZi5kZWxldGUoKTsKKworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiYWlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtYW5pZmVzdDIgPSBuZXcgTWFuaWZlc3QoYmFpcyk7CisgICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJNYWxmb3JtZWQgVVJMIik7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRUcnVlKG1hbmlmZXN0MS5lcXVhbHMobWFuaWZlc3QyKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvbG9nZ2luZy9PbGRFcnJvck1hbmFnZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvbG9nZ2luZy9PbGRFcnJvck1hbmFnZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDllZTFlNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9sb2dnaW5nL09sZEVycm9yTWFuYWdlclRlc3QuamF2YQpAQCAtMCwwICsxLDY2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC5sb2dnaW5nOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QcmludFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5FcnJvck1hbmFnZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkRXJyb3JNYW5hZ2VyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgZmluYWwgUHJpbnRTdHJlYW0gZXJyID0gU3lzdGVtLmVycjsKKyAgICBwcml2YXRlIGZpbmFsIFByaW50U3RyZWFtIG91dCA9IFN5c3RlbS5vdXQ7CisKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIFN5c3RlbS5zZXRFcnIoZXJyKTsKKyAgICAgICAgU3lzdGVtLnNldE91dChvdXQpOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXJyb3JDaGVjaygpIHsKKyAgICAgICAgRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEVycm9yTWFuYWdlcigpOworICAgICAgICBNb2NrU3RyZWFtIGFvcyA9IG5ldyBNb2NrU3RyZWFtKCk7CisgICAgICAgIFByaW50U3RyZWFtIHN0ID0gbmV3IFByaW50U3RyZWFtKGFvcyk7CisgICAgICAgIFN5c3RlbS5zZXRFcnIoc3QpOworICAgICAgICBTeXN0ZW0uc2V0T3V0KHN0KTsKKyAgICAgICAgZW0uZXJyb3IoInN1cGVydGVzdCIsIG51bGwsIEVycm9yTWFuYWdlci5HRU5FUklDX0ZBSUxVUkUpOworICAgICAgICBzdC5mbHVzaCgpOworICAgICAgICBhc3NlcnRUcnVlKCJtZXNzYWdlIGFwcGVhcnMgKHN1cGVydGVzdCkiLCBhb3MuZ2V0V3JpdHRlbkRhdGEoKS5pbmRleE9mKCJzdXBlcnRlc3QiKSAhPSAtMSk7CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIE1vY2tTdHJlYW0gZXh0ZW5kcyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0geworCisgICAgICAgIHByaXZhdGUgU3RyaW5nQnVmZmVyIGxpbmVzV3JpdHRlbiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKworICAgICAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHt9CisgICAgICAgIHB1YmxpYyAgdm9pZCBjbG9zZSgpIHt9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBidWZmZXIpIHsKKyAgICAgICAgICAgIGxpbmVzV3JpdHRlbi5hcHBlbmQobmV3IFN0cmluZyhidWZmZXIpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgd3JpdGUoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbikgeworICAgICAgICAgICAgbGluZXNXcml0dGVuLmFwcGVuZChuZXcgU3RyaW5nKGJ1ZmZlciwgb2Zmc2V0LCBsZW4pKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0V3JpdHRlbkRhdGEoKSB7cmV0dXJuIGxpbmVzV3JpdHRlbi50b1N0cmluZygpO30KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvbG9nZ2luZy9PbGRGaWxlSGFuZGxlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9sb2dnaW5nL09sZEZpbGVIYW5kbGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc4NWIyNjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvbG9nZ2luZy9PbGRGaWxlSGFuZGxlclRlc3QuamF2YQpAQCAtMCwwICsxLDQ5NiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWwubG9nZ2luZzsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlUmVhZGVyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlJlYWRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5GaWxlSGFuZGxlcjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5GaWx0ZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuRm9ybWF0dGVyOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkhhbmRsZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nTWFuYWdlcjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5Mb2dSZWNvcmQ7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkRmlsZUhhbmRsZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgc3RhdGljIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgIGZpbmFsIHN0YXRpYyBQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICBmaW5hbCBzdGF0aWMgU3RyaW5nIGNsYXNzTmFtZSA9IE9sZEZpbGVIYW5kbGVyVGVzdC5jbGFzcy5nZXROYW1lKCk7CisgICAgZmluYWwgc3RhdGljIFN0cmluZyBTRVAgPSBGaWxlLnNlcGFyYXRvcjsKKyAgICBTdHJpbmcgSE9NRVBBVEg7CisgICAgU3RyaW5nIFRFTVBQQVRIOworICAgIEZpbGVIYW5kbGVyIGhhbmRsZXI7CisgICAgTG9nUmVjb3JkIHI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisKKyAgICAgICAgLy9pbml0UHJvcAorICAgICAgICBwcm9wcy5jbGVhcigpOworICAgICAgICBwcm9wcy5wdXQoImphdmEudXRpbC5sb2dnaW5nLkZpbGVIYW5kbGVyLmxldmVsIiwgIkZJTkUiKTsKKyAgICAgICAgcHJvcHMucHV0KCJqYXZhLnV0aWwubG9nZ2luZy5GaWxlSGFuZGxlci5maWx0ZXIiLCBjbGFzc05hbWUKKyAgICAgICAgICAgICAgICArICIkTW9ja0ZpbHRlciIpOworICAgICAgICBwcm9wcy5wdXQoImphdmEudXRpbC5sb2dnaW5nLkZpbGVIYW5kbGVyLmZvcm1hdHRlciIsIGNsYXNzTmFtZQorICAgICAgICAgICAgICAgICsgIiRNb2NrRm9ybWF0dGVyIik7CisgICAgICAgIHByb3BzLnB1dCgiamF2YS51dGlsLmxvZ2dpbmcuRmlsZUhhbmRsZXIuZW5jb2RpbmciLCAiaXNvLTg4NTktMSIpOworICAgICAgICAvLyBsaW1pdCB0byBvbmx5IHR3byBtZXNzYWdlCisgICAgICAgIHByb3BzLnB1dCgiamF2YS51dGlsLmxvZ2dpbmcuRmlsZUhhbmRsZXIubGltaXQiLCAiMTAwMCIpOworICAgICAgICAvLyByb3RhdGlvbiBjb3VudCBpcyAyCisgICAgICAgIHByb3BzLnB1dCgiamF2YS51dGlsLmxvZ2dpbmcuRmlsZUhhbmRsZXIuY291bnQiLCAiMiIpOworICAgICAgICAvLyB1c2luZyBhcHBlbmQgbW9kZQorICAgICAgICBwcm9wcy5wdXQoImphdmEudXRpbC5sb2dnaW5nLkZpbGVIYW5kbGVyLmFwcGVuZCIsICJ0cnVlIik7CisgICAgICAgIHByb3BzLnB1dCgiamF2YS51dGlsLmxvZ2dpbmcuRmlsZUhhbmRsZXIucGF0dGVybiIsCisgICAgICAgICAgICAgICAgICAgICAgICAiJXQvbG9nL2phdmEldS50ZXN0Iik7CisKKyAgICAgICAgSE9NRVBBVEggPSBTeXN0ZW0uZ2V0UHJvcGVydHkoInVzZXIuaG9tZSIpOworICAgICAgICBURU1QUEFUSCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKTsKKworICAgICAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShURU1QUEFUSCArIFNFUCArICJsb2ciKTsKKyAgICAgICAgZmlsZS5ta2RpcigpOworICAgICAgICBtYW5hZ2VyLnJlYWRDb25maWd1cmF0aW9uKHByb3BlcnRpZXNUb0lucHV0U3RyZWFtKHByb3BzKSk7CisgICAgICAgIGhhbmRsZXIgPSBuZXcgRmlsZUhhbmRsZXIoKTsKKyAgICAgICAgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuQ09ORklHLCAibXNnIik7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG51bGwgIT0gaGFuZGxlcikgeworICAgICAgICAgICAgaGFuZGxlci5jbG9zZSgpOworICAgICAgICB9CisgICAgICAgIHJlc2V0KFRFTVBQQVRIICsgU0VQICsgImxvZyIsICIiKTsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIElucHV0U3RyZWFtIHByb3BlcnRpZXNUb0lucHV0U3RyZWFtKFByb3BlcnRpZXMgcCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgcC5zdG9yZShib3MsICIiKTsKKyAgICAgICAgcmV0dXJuIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShib3MudG9CeXRlQXJyYXkoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZpbGVIYW5kbGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiY2hhcmFjdGVyIGVuY29kaW5nIGlzIG5vbiBlcXVhbCB0byBhY3R1YWwgdmFsdWUiLAorICAgICAgICAgICAgICAgICJpc28tODg1OS0xIiwgaGFuZGxlci5nZXRFbmNvZGluZygpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiRmlsdGVyIGlzIG51bGwiLCBoYW5kbGVyLmdldEZpbHRlcigpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiRm9ybWF0dGVyIGlzIG51bGwiLCBoYW5kbGVyLmdldEZvcm1hdHRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpcyBub24gZXF1YWwgdG8gYWN0dWFsIHZhbHVlIiwgTGV2ZWwuRklORSwgaGFuZGxlcgorICAgICAgICAgICAgICAgIC5nZXRMZXZlbCgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiRXJyb3JNYW5hZ2VyIGlzIG51bGwiLCBoYW5kbGVyLmdldEVycm9yTWFuYWdlcigpKTsKKyAgICAgICAgaGFuZGxlci5wdWJsaXNoKHIpOworICAgICAgICBoYW5kbGVyLmNsb3NlKCk7CisgICAgICAgIC8vIG91dHB1dCAzIHRpbWVzLCBhbmQgYWxsIHJlY29yZHMgbGVmdAorICAgICAgICAvLyBhcHBlbmQgbW9kZSBpcyB0cnVlCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgaSsrKSB7CisgICAgICAgICAgICBoYW5kbGVyID0gbmV3IEZpbGVIYW5kbGVyKCk7CisgICAgICAgICAgICBoYW5kbGVyLnB1Ymxpc2gocik7CisgICAgICAgICAgICBoYW5kbGVyLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmlsZUNvbnRlbnQoVEVNUFBBVEggKyBTRVAgKyAibG9nIiwgImphdmEwLnRlc3QuMCIsCisgICAgICAgICAgICAgICAgbmV3IExvZ1JlY29yZFtdIHsgciwgbnVsbCwgciwgbnVsbCwgciwgbnVsbCwgciB9LAorICAgICAgICAgICAgICAgIG5ldyBNb2NrRm9ybWF0dGVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGaWxlSGFuZGxlcl8xcGFyYW1zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgaGFuZGxlciA9IG5ldyBGaWxlSGFuZGxlcigiJXQvbG9nL3N0cmluZyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlciBlbmNvZGluZyBpcyBub24gZXF1YWwgdG8gYWN0dWFsIHZhbHVlIiwKKyAgICAgICAgICAgICAgICAiaXNvLTg4NTktMSIsIGhhbmRsZXIuZ2V0RW5jb2RpbmcoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkZpbHRlciBpcyBudWxsIiwgaGFuZGxlci5nZXRGaWx0ZXIoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkZvcm1hdHRlciBpcyBudWxsIiwgaGFuZGxlci5nZXRGb3JtYXR0ZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaXMgbm9uIGVxdWFsIHRvIGFjdHVhbCB2YWx1ZSIsIExldmVsLkZJTkUsIGhhbmRsZXIKKyAgICAgICAgICAgICAgICAuZ2V0TGV2ZWwoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkVycm9yTWFuYWdlciBpcyBudWxsIiwgaGFuZGxlci5nZXRFcnJvck1hbmFnZXIoKSk7CisgICAgICAgIGhhbmRsZXIucHVibGlzaChyKTsKKyAgICAgICAgaGFuZGxlci5jbG9zZSgpOworCisgICAgICAgIC8vIG91dHB1dCAzIHRpbWVzLCBhbmQgYWxsIHJlY29yZHMgbGVmdAorICAgICAgICAvLyBhcHBlbmQgbW9kZSBpcyB0cnVlCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgaSsrKSB7CisgICAgICAgICAgICBoYW5kbGVyID0gbmV3IEZpbGVIYW5kbGVyKCIldC9sb2cvc3RyaW5nIik7CisgICAgICAgICAgICBoYW5kbGVyLnB1Ymxpc2gocik7CisgICAgICAgICAgICBoYW5kbGVyLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmlsZUNvbnRlbnQoVEVNUFBBVEggKyBTRVAgKyAibG9nIiwgIi9zdHJpbmciLCBuZXcgTG9nUmVjb3JkW10geworICAgICAgICAgICAgICAgIHIsIG51bGwsIHIsIG51bGwsIHIsIG51bGwsIHIgfSwgbmV3IE1vY2tGb3JtYXR0ZXIoKSk7CisKKyAgICAgICAgLy8gdGVzdCBpZiB1bmlxdWUgaWRzIG5vdCBzcGVjaWZpZWQsIGl0IHdpbGwgYXBwZW5kIGF0IHRoZSBlbmQKKyAgICAgICAgLy8gbm8gZ2VuZXJhdGlvbiBudW1iZXIgaXMgdXNlZAorICAgICAgICBGaWxlSGFuZGxlciBoID0gbmV3IEZpbGVIYW5kbGVyKCIldC9sb2cvc3RyaW5nIik7CisgICAgICAgIEZpbGVIYW5kbGVyIGgyID0gbmV3IEZpbGVIYW5kbGVyKCIldC9sb2cvc3RyaW5nIik7CisgICAgICAgIEZpbGVIYW5kbGVyIGgzID0gbmV3IEZpbGVIYW5kbGVyKCIldC9sb2cvc3RyaW5nIik7CisgICAgICAgIEZpbGVIYW5kbGVyIGg0ID0gbmV3IEZpbGVIYW5kbGVyKCIldC9sb2cvc3RyaW5nIik7CisgICAgICAgIGgucHVibGlzaChyKTsKKyAgICAgICAgaDIucHVibGlzaChyKTsKKyAgICAgICAgaDMucHVibGlzaChyKTsKKyAgICAgICAgaDQucHVibGlzaChyKTsKKyAgICAgICAgaC5jbG9zZSgpOworICAgICAgICBoMi5jbG9zZSgpOworICAgICAgICBoMy5jbG9zZSgpOworICAgICAgICBoNC5jbG9zZSgpOworICAgICAgICBhc3NlcnRGaWxlQ29udGVudChURU1QUEFUSCArIFNFUCArICJsb2ciLCAic3RyaW5nIiwgaC5nZXRGb3JtYXR0ZXIoKSk7CisgICAgICAgIGFzc2VydEZpbGVDb250ZW50KFRFTVBQQVRIICsgU0VQICsgImxvZyIsICJzdHJpbmcuMSIsIGguZ2V0Rm9ybWF0dGVyKCkpOworICAgICAgICBhc3NlcnRGaWxlQ29udGVudChURU1QUEFUSCArIFNFUCArICJsb2ciLCAic3RyaW5nLjIiLCBoLmdldEZvcm1hdHRlcigpKTsKKyAgICAgICAgYXNzZXJ0RmlsZUNvbnRlbnQoVEVNUFBBVEggKyBTRVAgKyAibG9nIiwgInN0cmluZy4zIiwgaC5nZXRGb3JtYXR0ZXIoKSk7CisKKyAgICAgICAgLy8gZGVmYXVsdCBpcyBhcHBlbmQgbW9kZQorICAgICAgICBGaWxlSGFuZGxlciBoNiA9IG5ldyBGaWxlSGFuZGxlcigiJXQvbG9nL3N0cmluZyV1LmxvZyIpOworICAgICAgICBoNi5wdWJsaXNoKHIpOworICAgICAgICBoNi5jbG9zZSgpOworICAgICAgICBGaWxlSGFuZGxlciBoNyA9IG5ldyBGaWxlSGFuZGxlcigiJXQvbG9nL3N0cmluZyV1LmxvZyIpOworICAgICAgICBoNy5wdWJsaXNoKHIpOworICAgICAgICBoNy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RmlsZUNvbnRlbnQoVEVNUFBBVEggKyBTRVAgKyAibG9nIiwgInN0cmluZzAubG9nIiwgaAorICAgICAgICAgICAgICAgICAgICAuZ2V0Rm9ybWF0dGVyKCkpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIGFzc2VydGlvbiBmYWlsZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoRXJyb3IgZSkgeworICAgICAgICB9CisgICAgICAgIEZpbGUgZmlsZSA9IG5ldyBGaWxlKFRFTVBQQVRIICsgU0VQICsgImxvZyIpOworICAgICAgICBhc3NlcnRUcnVlKCJsZW5ndGggbGlzdCBvZiBmaWxlIGlzIGluY29ycmVjdCIsIGZpbGUubGlzdCgpLmxlbmd0aCA8PSAyKTsKKworICAgICAgICAvLyB0ZXN0IHVuaXF1ZSBpZHMKKyAgICAgICAgRmlsZUhhbmRsZXIgaDggPSBuZXcgRmlsZUhhbmRsZXIoIiV0L2xvZy8ldXN0cmluZyV1LmxvZyIpOworICAgICAgICBoOC5wdWJsaXNoKHIpOworICAgICAgICBGaWxlSGFuZGxlciBoOSA9IG5ldyBGaWxlSGFuZGxlcigiJXQvbG9nLyV1c3RyaW5nJXUubG9nIik7CisgICAgICAgIGg5LnB1Ymxpc2gocik7CisgICAgICAgIGg5LmNsb3NlKCk7CisgICAgICAgIGg4LmNsb3NlKCk7CisgICAgICAgIGFzc2VydEZpbGVDb250ZW50KFRFTVBQQVRIICsgU0VQICsgImxvZyIsICIwc3RyaW5nMC5sb2ciLCBoCisgICAgICAgICAgICAgICAgLmdldEZvcm1hdHRlcigpKTsKKyAgICAgICAgYXNzZXJ0RmlsZUNvbnRlbnQoVEVNUFBBVEggKyBTRVAgKyAibG9nIiwgIjFzdHJpbmcxLmxvZyIsIGgKKyAgICAgICAgICAgICAgICAuZ2V0Rm9ybWF0dGVyKCkpOworICAgICAgICBmaWxlID0gbmV3IEZpbGUoVEVNUFBBVEggKyBTRVAgKyAibG9nIik7CisgICAgICAgIGFzc2VydFRydWUoImxlbmd0aCBsaXN0IG9mIGZpbGUgaXMgaW5jb3JyZWN0IiwgZmlsZS5saXN0KCkubGVuZ3RoIDw9IDIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRmlsZUhhbmRsZXIoIiIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmlsZUhhbmRsZXJfMnBhcmFtcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBib29sZWFuIGFwcGVuZCA9IGZhbHNlOworICAgICAgICBkbyB7CisgICAgICAgICAgICBhcHBlbmQgPSAhYXBwZW5kOworICAgICAgICAgICAgaGFuZGxlciA9IG5ldyBGaWxlSGFuZGxlcigiJXQvbG9nL3N0cmluZyIsIGFwcGVuZCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImNoYXJhY3RlciBlbmNvZGluZyBpcyBub24gZXF1YWwgdG8gYWN0dWFsIHZhbHVlIiwKKyAgICAgICAgICAgICAgICAgICAgImlzby04ODU5LTEiLCBoYW5kbGVyLmdldEVuY29kaW5nKCkpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiRmlsdGVyIGlzIG51bGwiLCBoYW5kbGVyLmdldEZpbHRlcigpKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIkZvcm1hdHRlciBpcyBudWxsIiwgaGFuZGxlci5nZXRGb3JtYXR0ZXIoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImlzIG5vbiBlcXVhbCB0byBhY3R1YWwgdmFsdWUiLCBMZXZlbC5GSU5FLCBoYW5kbGVyCisgICAgICAgICAgICAgICAgICAgIC5nZXRMZXZlbCgpKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIkVycm9yTWFuYWdlciBpcyBudWxsIiwgaGFuZGxlci5nZXRFcnJvck1hbmFnZXIoKSk7CisgICAgICAgICAgICBoYW5kbGVyLnB1Ymxpc2gocik7CisgICAgICAgICAgICBoYW5kbGVyLmNsb3NlKCk7CisgICAgICAgICAgICAvLyBvdXRwdXQgMyB0aW1lcywgYW5kIGFsbCByZWNvcmRzIGxlZnQKKyAgICAgICAgICAgIC8vIGFwcGVuZCBtb2RlIGlzIHRydWUKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgaSsrKSB7CisgICAgICAgICAgICAgICAgaGFuZGxlciA9IG5ldyBGaWxlSGFuZGxlcigiJXQvbG9nL3N0cmluZyIsIGFwcGVuZCk7CisgICAgICAgICAgICAgICAgaGFuZGxlci5wdWJsaXNoKHIpOworICAgICAgICAgICAgICAgIGhhbmRsZXIuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhcHBlbmQpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRGaWxlQ29udGVudChURU1QUEFUSCArIFNFUCArICJsb2ciLCAiL3N0cmluZyIsCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTG9nUmVjb3JkW10geyByLCBudWxsLCByLCBudWxsLCByLCBudWxsLCByIH0sCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTW9ja0Zvcm1hdHRlcigpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmlsZUNvbnRlbnQoVEVNUFBBVEggKyBTRVAgKyAibG9nIiwgIi9zdHJpbmciLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IExvZ1JlY29yZFtdIHsgciB9LCBuZXcgTW9ja0Zvcm1hdHRlcigpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSB3aGlsZSAoYXBwZW5kKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEZpbGVIYW5kbGVyKCIiLCB0cnVlKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZpbGVIYW5kbGVyXzNwYXJhbXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGxpbWl0ID0gMTIwOworICAgICAgICBpbnQgY291bnQgPSAxOworICAgICAgICBoYW5kbGVyID0gbmV3IEZpbGVIYW5kbGVyKCIldC9sb2cvc3RyaW5nIiwgbGltaXQsIGNvdW50KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyYWN0ZXIgZW5jb2RpbmcgaXMgbm9uIGVxdWFsIHRvIGFjdHVhbCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgImlzby04ODU5LTEiLCBoYW5kbGVyLmdldEVuY29kaW5nKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJGaWx0ZXIgaXMgbnVsbCIsIGhhbmRsZXIuZ2V0RmlsdGVyKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJGb3JtYXR0ZXIgaXMgbnVsbCIsIGhhbmRsZXIuZ2V0Rm9ybWF0dGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImlzIG5vbiBlcXVhbCB0byBhY3R1YWwgdmFsdWUiLCBMZXZlbC5GSU5FLCBoYW5kbGVyCisgICAgICAgICAgICAgICAgLmdldExldmVsKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJFcnJvck1hbmFnZXIgaXMgbnVsbCIsIGhhbmRsZXIuZ2V0RXJyb3JNYW5hZ2VyKCkpOworICAgICAgICBoYW5kbGVyLnB1Ymxpc2gocik7CisgICAgICAgIGhhbmRsZXIuY2xvc2UoKTsKKyAgICAgICAgLy8gb3V0cHV0IDMgdGltZXMsIGFuZCBhbGwgcmVjb3JkcyBsZWZ0CisgICAgICAgIC8vIGFwcGVuZCBtb2RlIGlzIHRydWUKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAzOyBpKyspIHsKKyAgICAgICAgICAgIGhhbmRsZXIgPSBuZXcgRmlsZUhhbmRsZXIoIiV0L2xvZy9zdHJpbmciLCBsaW1pdCwgY291bnQpOworICAgICAgICAgICAgaGFuZGxlci5wdWJsaXNoKHIpOworICAgICAgICAgICAgaGFuZGxlci5jbG9zZSgpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEZpbGVDb250ZW50KFRFTVBQQVRIICsgU0VQICsgImxvZyIsICIvc3RyaW5nIiwgbmV3IExvZ1JlY29yZFtdIHsKKyAgICAgICAgICAgICAgICByLCBudWxsLCByLCBudWxsLCByLCBudWxsLCByIH0sIG5ldyBNb2NrRm9ybWF0dGVyKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRmlsZUhhbmRsZXIoIiIsIGxpbWl0LCBjb3VudCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRmlsZUhhbmRsZXIoIiV0L2xvZy9zdHJpbmciLCAtMSwgY291bnQpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEZpbGVIYW5kbGVyKCIldC9sb2cvc3RyaW5nIiwgbGltaXQsIDApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmlsZUhhbmRsZXJfNHBhcmFtcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbnQgbGltaXQgPSAxMjA7CisgICAgICAgIGludCBjb3VudCA9IDE7CisgICAgICAgIGJvb2xlYW4gYXBwZW5kID0gZmFsc2U7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGFwcGVuZCA9ICFhcHBlbmQ7CisgICAgICAgICAgICBoYW5kbGVyID0gbmV3IEZpbGVIYW5kbGVyKCIldC9sb2cvc3RyaW5nIiwgbGltaXQsIGNvdW50LCBhcHBlbmQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyYWN0ZXIgZW5jb2RpbmcgaXMgbm9uIGVxdWFsIHRvIGFjdHVhbCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgICAgICJpc28tODg1OS0xIiwgaGFuZGxlci5nZXRFbmNvZGluZygpKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIkZpbHRlciBpcyBudWxsIiwgaGFuZGxlci5nZXRGaWx0ZXIoKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJGb3JtYXR0ZXIgaXMgbnVsbCIsIGhhbmRsZXIuZ2V0Rm9ybWF0dGVyKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJpcyBub24gZXF1YWwgdG8gYWN0dWFsIHZhbHVlIiwgTGV2ZWwuRklORSwgaGFuZGxlcgorICAgICAgICAgICAgICAgICAgICAuZ2V0TGV2ZWwoKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJFcnJvck1hbmFnZXIgaXMgbnVsbCIsIGhhbmRsZXIuZ2V0RXJyb3JNYW5hZ2VyKCkpOworICAgICAgICAgICAgaGFuZGxlci5wdWJsaXNoKHIpOworICAgICAgICAgICAgaGFuZGxlci5jbG9zZSgpOworICAgICAgICAgICAgLy8gb3V0cHV0IDMgdGltZXMsIGFuZCBhbGwgcmVjb3JkcyBsZWZ0CisgICAgICAgICAgICAvLyBhcHBlbmQgbW9kZSBpcyB0cnVlCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykgeworICAgICAgICAgICAgICAgIGhhbmRsZXIgPSBuZXcgRmlsZUhhbmRsZXIoIiV0L2xvZy9zdHJpbmciLCBsaW1pdCwgY291bnQsIGFwcGVuZCk7CisgICAgICAgICAgICAgICAgaGFuZGxlci5wdWJsaXNoKHIpOworICAgICAgICAgICAgICAgIGhhbmRsZXIuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChhcHBlbmQpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRGaWxlQ29udGVudChURU1QUEFUSCArIFNFUCArICJsb2ciLCAiL3N0cmluZyIsCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTG9nUmVjb3JkW10geyByLCBudWxsLCByLCBudWxsLCByLCBudWxsLCByIH0sCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTW9ja0Zvcm1hdHRlcigpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmlsZUNvbnRlbnQoVEVNUFBBVEggKyBTRVAgKyAibG9nIiwgIi9zdHJpbmciLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IExvZ1JlY29yZFtdIHsgciB9LCBuZXcgTW9ja0Zvcm1hdHRlcigpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSB3aGlsZSAoYXBwZW5kKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEZpbGVIYW5kbGVyKCIiLCBsaW1pdCwgY291bnQsIHRydWUpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEZpbGVIYW5kbGVyKCIldC9sb2cvc3RyaW5nIiwgLTEsIGNvdW50LCBmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRmlsZUhhbmRsZXIoIiV0L2xvZy9zdHJpbmciLCBsaW1pdCwgMCwgdHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRGaWxlQ29udGVudChTdHJpbmcgaG9tZXBhdGgsIFN0cmluZyBmaWxlbmFtZSwKKyAgICAgICAgICAgIEZvcm1hdHRlciBmb3JtYXR0ZXIpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGaWxlQ29udGVudChob21lcGF0aCwgZmlsZW5hbWUsIG5ldyBMb2dSZWNvcmRbXSB7IHIgfSwgZm9ybWF0dGVyKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0RmlsZUNvbnRlbnQoU3RyaW5nIGhvbWVwYXRoLCBTdHJpbmcgZmlsZW5hbWUsCisgICAgICAgICAgICBMb2dSZWNvcmRbXSBsciwgRm9ybWF0dGVyIGZvcm1hdHRlcikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGhhbmRsZXIuY2xvc2UoKTsKKyAgICAgICAgU3RyaW5nIG1zZyA9ICIiOworICAgICAgICAvLyBpZiBmb3JtYXR0ZXIgaXMgbnVsbCwgdGhlIGZpbGUgY29udGVudCBzaG91bGQgYmUgZW1wdHkKKyAgICAgICAgLy8gZWxzZSB0aGUgbWVzc2FnZSBzaG91bGQgYmUgZm9ybWF0dGVkIGdpdmVuIHJlY29yZHMKKyAgICAgICAgaWYgKG51bGwgIT0gZm9ybWF0dGVyKSB7CisgICAgICAgICAgICBTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgICAgICBzYi5hcHBlbmQoZm9ybWF0dGVyLmdldEhlYWQoaGFuZGxlcikpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChudWxsID09IGxyW2ldICYmIGkgPCBsci5sZW5ndGggLSAxKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGlmIG9uZSByZWNvcmQgaXMgbnVsbCBhbmQgaXMgbm90IHRoZSBsYXN0IHJlY29yZCwgbWVhbnMKKyAgICAgICAgICAgICAgICAgICAgLy8gaGVyZSBpcworICAgICAgICAgICAgICAgICAgICAvLyBvdXRwdXQgY29tcGxldGlvbiBwb2ludCwgc2hvdWxkIG91dHB1dCB0YWlsLCB0aGVuIG91dHB1dAorICAgICAgICAgICAgICAgICAgICAvLyBoZWFkCisgICAgICAgICAgICAgICAgICAgIC8vIChyZWFkeSBmb3IgbmV4dCBvdXRwdXQpCisgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZChmb3JtYXR0ZXIuZ2V0VGFpbChoYW5kbGVyKSk7CisgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZChmb3JtYXR0ZXIuZ2V0SGVhZChoYW5kbGVyKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKGZvcm1hdHRlci5mb3JtYXQobHJbaV0pKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzYi5hcHBlbmQoZm9ybWF0dGVyLmdldFRhaWwoaGFuZGxlcikpOworICAgICAgICAgICAgbXNnID0gc2IudG9TdHJpbmcoKTsKKyAgICAgICAgfQorICAgICAgICBjaGFyW10gY2hhcnMgPSBuZXcgY2hhclttc2cubGVuZ3RoKCldOworICAgICAgICBSZWFkZXIgcmVhZGVyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRlciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgRmlsZVJlYWRlcihob21lcGF0aCArIFNFUAorICAgICAgICAgICAgICAgICAgICArIGZpbGVuYW1lKSk7CisgICAgICAgICAgICByZWFkZXIucmVhZChjaGFycyk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobXNnLCBuZXcgU3RyaW5nKGNoYXJzKSk7CisgICAgICAgICAgICAvLyBhc3NlcnQgaGFzIHJlYWNoZWQgdGhlIGVuZCBvZiB0aGUgZmlsZQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCByZWFkZXIucmVhZCgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKHJlYWRlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJlYWRlci5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gZG9uJ3QgY2FyZQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzZXQoaG9tZXBhdGgsIGZpbGVuYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIERvZXMgYSBjbGVhbnVwIG9mIGdpdmVuIGZpbGUKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVzZXQoU3RyaW5nIGhvbWVwYXRoLCBTdHJpbmcgZmlsZW5hbWUpIHsKKyAgICAgICAgRmlsZSBmaWxlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmlsZSA9IG5ldyBGaWxlKGhvbWVwYXRoICsgU0VQICsgZmlsZW5hbWUpOworICAgICAgICAgICAgaWYgKGZpbGUuaXNGaWxlKCkpIHsKKyAgICAgICAgICAgICAgICBmaWxlLmRlbGV0ZSgpOworICAgICAgICAgICAgfSBlbHNlIGlmIChmaWxlLmlzRGlyZWN0b3J5KCkpIHsKKyAgICAgICAgICAgICAgICBGaWxlW10gZmlsZXMgPSBmaWxlLmxpc3RGaWxlcygpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZmlsZXNbaV0uZGVsZXRlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZpbGUuZGVsZXRlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaWxlID0gbmV3IEZpbGUoaG9tZXBhdGggKyBTRVAgKyBmaWxlbmFtZSArICIubGNrIik7CisgICAgICAgICAgICBmaWxlLmRlbGV0ZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRoaXMgdGVzdCBmYWlscyBvbiBSSS4gRG9lc24ndCBwYXJzZSBzcGVjaWFsIHBhdHRlcm4gXCIldC8laC4iCisgICAgcHVibGljIHZvaWQgdGVzdEludmFsaWRQYXJhbXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIC8vICV0IGFuZCAlcCBwYXJzaW5nIGNhbiBhZGQgZmlsZSBzZXBhcmF0b3IgYXV0b21hdGljYWxseQorCisgICAgICAgIC8vIGJhZCBkaXJlY3RvcnksIElPRXhjZXB0aW9uLCBhcHBlbmQKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBGaWxlSGFuZGxlcigiJXQvYmFkZGlyL211bHRpJWciLCB0cnVlKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJTyBleGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIEZpbGUgZmlsZSA9IG5ldyBGaWxlKFRFTVBQQVRIICsgU0VQICsgImJhZGRpciIgKyBTRVAgKyAibXVsdGkwIik7CisgICAgICAgIGFzc2VydEZhbHNlKGZpbGUuZXhpc3RzKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEZpbGVIYW5kbGVyKCIldC9iYWRkaXIvbXVsdGklZyIsIGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJTyBleGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZpbGUgPSBuZXcgRmlsZShURU1QUEFUSCArIFNFUCArICJiYWRkaXIiICsgU0VQICsgIm11bHRpMCIpOworICAgICAgICBhc3NlcnRGYWxzZShmaWxlLmV4aXN0cygpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEZpbGVIYW5kbGVyKCIldC9iYWRkaXIvbXVsdGklZyIsIDEyLCA0KTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJTyBleGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZpbGUgPSBuZXcgRmlsZShURU1QUEFUSCArIFNFUCArICJiYWRkaXIiICsgU0VQICsgIm11bHRpMCIpOworICAgICAgICBhc3NlcnRGYWxzZShmaWxlLmV4aXN0cygpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEZpbGVIYW5kbGVyKCIldC9qYXZhJXUiLCAtMSwgLTEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1Ymxpc2goKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTG9nUmVjb3JkW10gciA9IG5ldyBMb2dSZWNvcmRbXSB7IG5ldyBMb2dSZWNvcmQoTGV2ZWwuQ09ORklHLCAibXNnX18iKSwKKyAgICAgICAgICAgICAgICBuZXcgTG9nUmVjb3JkKExldmVsLldBUk5JTkcsICJtZXNzYWdlIiksCisgICAgICAgICAgICAgICAgbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCAibWVzc2FnZSBmb3IiKSwKKyAgICAgICAgICAgICAgICBuZXcgTG9nUmVjb3JkKExldmVsLkZJTkUsICJtZXNzYWdlIGZvciB0ZXN0IikgfTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBoYW5kbGVyID0gbmV3IEZpbGVIYW5kbGVyKCIldC9sb2cvc3RyaW5nUHVibGlzaCIpOworICAgICAgICAgICAgaGFuZGxlci5wdWJsaXNoKHJbaV0pOworICAgICAgICAgICAgaGFuZGxlci5jbG9zZSgpOworICAgICAgICAgICAgYXNzZXJ0RmlsZUNvbnRlbnQoVEVNUFBBVEggKyBTRVAgKyAibG9nIiwgInN0cmluZ1B1Ymxpc2giLAorICAgICAgICAgICAgICAgICAgICBuZXcgTG9nUmVjb3JkW10geyByW2ldIH0sIGhhbmRsZXIuZ2V0Rm9ybWF0dGVyKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENsb3NlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGVIYW5kbGVyIGggPSBuZXcgRmlsZUhhbmRsZXIoIiV0L2xvZy9zdHJpbmdQdWJsaXNoIik7CisgICAgICAgIGgucHVibGlzaChyKTsKKyAgICAgICAgaC5jbG9zZSgpOworICAgICAgICBhc3NlcnRGaWxlQ29udGVudChURU1QUEFUSCArIFNFUCArICJsb2ciLCAic3RyaW5nUHVibGlzaCIsIGgKKyAgICAgICAgICAgICAgICAuZ2V0Rm9ybWF0dGVyKCkpOworICAgIH0KKworICAgIC8qCisgICAgICogbW9jayBjbGFzc2VzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBNb2NrRmlsdGVyIGltcGxlbWVudHMgRmlsdGVyIHsKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNMb2dnYWJsZShMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgICAgICByZXR1cm4gIXJlY29yZC5nZXRNZXNzYWdlKCkuZXF1YWxzKCJmYWxzZSIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBNb2NrRm9ybWF0dGVyIGV4dGVuZHMgRm9ybWF0dGVyIHsKKyAgICAgICAgcHVibGljIFN0cmluZyBmb3JtYXQoTG9nUmVjb3JkIHIpIHsKKyAgICAgICAgICAgIGlmIChudWxsID09IHIpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gIiI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gci5nZXRNZXNzYWdlKCkgKyAiIGJ5IE1vY2tGb3JtYXR0ZXJcbiI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRhaWwoSGFuZGxlciBoKSB7CisgICAgICAgICAgICByZXR1cm4gInRhaWxcbiI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEhlYWQoSGFuZGxlciBoKSB7CisgICAgICAgICAgICByZXR1cm4gImhlYWRcbiI7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvbG9nZ2luZy9PbGRGb3JtYXR0ZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvbG9nZ2luZy9PbGRGb3JtYXR0ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2JjMWVkZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9sb2dnaW5nL09sZEZvcm1hdHRlclRlc3QuamF2YQpAQCAtMCwwICsxLDc0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC5sb2dnaW5nOworCitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuRm9ybWF0dGVyOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkhhbmRsZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLlN0cmVhbUhhbmRsZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkRm9ybWF0dGVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBzdGF0aWMgU3RyaW5nIE1TRyA9ICJtc2csIHBscy4gaWdub3JlIGl0IjsKKworICAgIEZvcm1hdHRlciBmID0gbmV3IE1vY2tGb3JtYXR0ZXIoKTsKKyAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuRklORSwgTVNHKTsKKyAgICBIYW5kbGVyIGg7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgaCA9IG5ldyBTdHJlYW1IYW5kbGVyKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdHRlcigpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJoZWFkIHN0cmluZyBpcyBub3QgZW1wdHkiLCAiIiwgZi5nZXRIZWFkKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0YWlsIHN0cmluZyBpcyBub3QgZW1wdHkiLCAiIiwgZi5nZXRUYWlsKG51bGwpKTsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRIZWFkKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoImhlYWQgc3RyaW5nIGlzIG5vdCBlbXB0eSIsICIiLCBmLmdldEhlYWQobnVsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImhlYWQgc3RyaW5nIGlzIG5vdCBlbXB0eSIsICIiLCBmLmdldEhlYWQoaCkpOworICAgICAgICBoLnB1Ymxpc2gocik7CisgICAgICAgIGFzc2VydEVxdWFscygiaGVhZCBzdHJpbmcgaXMgbm90IGVtcHR5IiwgIiIsIGYuZ2V0SGVhZChoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFRhaWwoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygidGFpbCBzdHJpbmcgaXMgbm90IGVtcHR5IiwgIiIsIGYuZ2V0VGFpbChudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidGFpbCBzdHJpbmcgaXMgbm90IGVtcHR5IiwgIiIsIGYuZ2V0VGFpbChoKSk7CisgICAgICAgIGgucHVibGlzaChyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0YWlsIHN0cmluZyBpcyBub3QgZW1wdHkiLCAiIiwgZi5nZXRUYWlsKGgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0TWVzc2FnZSgpIHsKKyAgICAgICAgLy8gVGhlIFJJIGZhaWxzIGluIHRoaXMgdGVzdCBiZWNhdXNlIGl0IHVzZXMgYSBNZXNzYWdlRm9ybWF0IHRvIGZvcm1hdAorICAgICAgICAvLyB0aGUgbWVzc2FnZSBldmVuIHRob3VnaCBpdCBkb2Vzbid0IGNvbnRhaW4gInswIi4gVGhlIHNwZWMgc2F5cyB0aGF0CisgICAgICAgIC8vIHRoaXMgd291bGQgaW5kaWNhdGUgdGhhdCBhIE1lc3NhZ2VGb3JtYXQgc2hvdWxkIGJlIHVzZWQgYW5kIGVsc2Ugbm8KKyAgICAgICAgLy8gZm9ybWF0dGluZyBzaG91bGQgYmUgZG9uZS4KKyAgICAgICAgU3RyaW5nIHBhdHRlcm4gPSAicGF0dGVybiB3aXRob3V0IDAgezEsIG51bWJlcn0iOworICAgICAgICByLnNldE1lc3NhZ2UocGF0dGVybik7CisgICAgICAgIGFzc2VydEVxdWFscyhwYXR0ZXJuLCBmLmZvcm1hdE1lc3NhZ2UocikpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTW9ja0Zvcm1hdHRlciBleHRlbmRzIEZvcm1hdHRlciB7CisgICAgICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0KExvZ1JlY29yZCBhcmcwKSB7CisgICAgICAgICAgICByZXR1cm4gImZvcm1hdCI7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvbG9nZ2luZy9PbGRMZXZlbFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9sb2dnaW5nL09sZExldmVsVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNkMGIzMWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvbG9nZ2luZy9PbGRMZXZlbFRlc3QuamF2YQpAQCAtMCwwICsxLDYwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC5sb2dnaW5nOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgT2xkTGV2ZWxUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRSZXNvdXJjZUJ1bmRsZU5hbWUoKSB7CisgICAgICAgIFN0cmluZyBidW5kbGVOYW1lID0gImJ1bmRsZXMvamF2YS91dGlsL2xvZ2dpbmcvcmVzIjsKKyAgICAgICAgTGV2ZWwgbCA9IG5ldyBNb2NrTGV2ZWwoImxldmVsMSIsIDEyMCk7CisgICAgICAgIGFzc2VydE51bGwoImxldmVsJ3MgbG9jYWxpemF0aW9uIHJlc291cmNlIGJ1bmRsZSBuYW1lIGlzIG5vdCBudWxsIiwgbAorICAgICAgICAgICAgICAgIC5nZXRSZXNvdXJjZUJ1bmRsZU5hbWUoKSk7CisgICAgICAgIGwgPSBuZXcgTW9ja0xldmVsKCJsZXZlbDEiLCAxMjAsIGJ1bmRsZU5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJ1bmRsZU5hbWUgaXMgbm9uIGVxdWFsIHRvIGFjdHVhbCB2YWx1ZSIsIGJ1bmRsZU5hbWUsIGwKKyAgICAgICAgICAgICAgICAuZ2V0UmVzb3VyY2VCdW5kbGVOYW1lKCkpOworICAgICAgICBsID0gbmV3IE1vY2tMZXZlbCgibGV2ZWwxIiwgMTIwLCBidW5kbGVOYW1lICsgIithYmNkZWYiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJidW5kbGVOYW1lIGlzIG5vbiBlcXVhbCB0byBhY3R1YWwgdmFsdWUiLCBidW5kbGVOYW1lCisgICAgICAgICAgICAgICAgKyAiK2FiY2RlZiIsIGwuZ2V0UmVzb3VyY2VCdW5kbGVOYW1lKCkpOworICAgIH0KKworICAgICAvKgorICAgICAqIHRlc3QgZm9yIG1ldGhvZCBwdWJsaWMgZmluYWwgaW50IGludFZhbHVlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW50VmFsdWUoKSB7CisgICAgICAgIGludCB2YWx1ZTEgPSAxMjA7CisgICAgICAgIExldmVsIGwgPSBuZXcgTW9ja0xldmVsKCJsZXZlbDEiLCB2YWx1ZTEpOworICAgICAgICBhc3NlcnRFcXVhbHMoImludGVnZXIgdmFsdWUgZm9yIHRoaXMgbGV2ZWwgaXMgbm9uIGVxdWFsIHRvIGFjdHVhbCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgdmFsdWUxLCBsLmludFZhbHVlKCkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTW9ja0xldmVsIGV4dGVuZHMgTGV2ZWwgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKworICAgICAgICBwdWJsaWMgTW9ja0xldmVsKFN0cmluZyBuYW1lLCBpbnQgdmFsdWUpIHsKKyAgICAgICAgICAgIHN1cGVyKG5hbWUsIHZhbHVlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBNb2NrTGV2ZWwoU3RyaW5nIG5hbWUsIGludCB2YWx1ZSwgU3RyaW5nIHJlc291cmNlQnVuZGxlTmFtZSkgeworICAgICAgICAgICAgc3VwZXIobmFtZSwgdmFsdWUsIHJlc291cmNlQnVuZGxlTmFtZSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvbG9nZ2luZy9PbGRMb2dNYW5hZ2VyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2xvZ2dpbmcvT2xkTG9nTWFuYWdlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNzZjMTc4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2xvZ2dpbmcvT2xkTG9nTWFuYWdlclRlc3QuamF2YQpAQCAtMCwwICsxLDI1NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWwubG9nZ2luZzsKKworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5IYW5kbGVyOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ01hbmFnZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ2dlcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRMb2dNYW5hZ2VyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGT08gPSAiTG9nTWFuYWdlclRlc3RGb28iOworCisgICAgTG9nTWFuYWdlciBtb2NrTWFuYWdlcjsKKworICAgIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworCisgICAgUHJvcGVydGllcyBwcm9wczsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBjbGFzc05hbWUgPSBPbGRMb2dNYW5hZ2VyVGVzdC5jbGFzcy5nZXROYW1lKCk7CisKKyAgICBzdGF0aWMgSGFuZGxlciBoYW5kbGVyID0gbnVsbDsKKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBtb2NrTWFuYWdlciA9IG5ldyBNb2NrTG9nTWFuYWdlcigpOworICAgICAgICBoYW5kbGVyID0gbmV3IE1vY2tIYW5kbGVyKCk7CisgICAgICAgIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgcHJvcHMucHV0KCJoYW5kbGVycyIsIGNsYXNzTmFtZSArICIkTW9ja0hhbmRsZXIgIiArIGNsYXNzTmFtZSArICIkTW9ja0hhbmRsZXIiKTsKKyAgICAgICAgcHJvcHMucHV0KCJqYXZhLnV0aWwubG9nZ2luZy5GaWxlSGFuZGxlci5wYXR0ZXJuIiwgIiVoL2phdmEldS5sb2ciKTsKKyAgICAgICAgcHJvcHMucHV0KCJqYXZhLnV0aWwubG9nZ2luZy5GaWxlSGFuZGxlci5saW1pdCIsICI1MDAwMCIpOworICAgICAgICBwcm9wcy5wdXQoImphdmEudXRpbC5sb2dnaW5nLkZpbGVIYW5kbGVyLmNvdW50IiwgIjUiKTsKKyAgICAgICAgcHJvcHMucHV0KCJqYXZhLnV0aWwubG9nZ2luZy5GaWxlSGFuZGxlci5mb3JtYXR0ZXIiLCAiamF2YS51dGlsLmxvZ2dpbmcuWE1MRm9ybWF0dGVyIik7CisgICAgICAgIHByb3BzLnB1dCgiLmxldmVsIiwgIkZJTkUiKTsKKyAgICAgICAgcHJvcHMucHV0KCJqYXZhLnV0aWwubG9nZ2luZy5Db25zb2xlSGFuZGxlci5sZXZlbCIsICJPRkYiKTsKKyAgICAgICAgcHJvcHMucHV0KCJqYXZhLnV0aWwubG9nZ2luZy5Db25zb2xlSGFuZGxlci5mb3JtYXR0ZXIiLCJqYXZhLnV0aWwubG9nZ2luZy5TaW1wbGVGb3JtYXR0ZXIiKTsKKyAgICAgICAgcHJvcHMucHV0KCJMb2dNYW5hZ2VyVGVzdEZvby5oYW5kbGVycyIsICJqYXZhLnV0aWwubG9nZ2luZy5Db25zb2xlSGFuZGxlciIpOworICAgICAgICBwcm9wcy5wdXQoIkxvZ01hbmFnZXJUZXN0Rm9vLmxldmVsIiwgIldBUk5JTkciKTsKKyAgICB9CisKKworCisgICAgLyoKKyAgICAgKiBAc2VlIFRlc3RDYXNlI3RlYXJEb3duKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgICAgICBoYW5kbGVyID0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9nTWFuYWdlcigpIHsKKyAgICAgICBjbGFzcyBUZXN0TG9nTWFuYWdlciBleHRlbmRzIExvZ01hbmFnZXIgeworICAgICAgICAgICBwdWJsaWMgVGVzdExvZ01hbmFnZXIoKSB7CisgICAgICAgICAgICAgICBzdXBlcigpOworICAgICAgICAgICB9CisgICAgICAgfQorICAgICAgIFRlc3RMb2dNYW5hZ2VyIHRsbSA9IG5ldyBUZXN0TG9nTWFuYWdlcigpOworICAgICAgIGFzc2VydE5vdE51bGwodGxtLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qCisgICAgICogdGVzdCBmb3IgbWV0aG9kIHB1YmxpYyBMb2dnZXIgZ2V0TG9nZ2VyKFN0cmluZyBuYW1lKQorICAgICAqIHRlc3QgY292ZXJzIGZvbGxvd2luZyB1c2UgY2FzZXM6CisgICAgICogY2FzZSAxOiB0ZXN0IGRlZmF1bHQgYW5kIHZhbGlkIHZhbHVlCisgICAgICogY2FzZSAyOiB0ZXN0IHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogY2FzZSAzOiB0ZXN0IGJhZCBuYW1lCisgICAgICogY2FzZSA0OiBjaGVjayBjb3JyZWN0IHRlc3RlZCB2YWx1ZQorICAgICAqLworCisgICAgcHVibGljIHZvaWQgdGVzdEdldExvZ2dlcigpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIC8vIGNhc2UgMTogdGVzdCBkZWZhdWx0IGFuZCB2YWxpZCB2YWx1ZQorICAgICAgICBMb2dnZXIgbG9nID0gbmV3IE1vY2tMb2dnZXIoRk9PLCBudWxsKTsKKyAgICAgICAgTG9nZ2VyIGZvbyA9IG1vY2tNYW5hZ2VyLmdldExvZ2dlcihGT08pOworICAgICAgICBhc3NlcnROdWxsKCJMb2dnZXIgc2hvdWxkIGJlIG51bGwiLCBmb28pOworICAgICAgICBhc3NlcnRUcnVlKCJsb2dnZXIgd2Fzbid0IHJlZ2lzdGVyZWQgc3VjY2Vzc2Z1bGx5IiwgbW9ja01hbmFnZXIuYWRkTG9nZ2VyKGxvZykpOworICAgICAgICBmb28gPSBtb2NrTWFuYWdlci5nZXRMb2dnZXIoRk9PKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgidHdvIGxvZ2dlcnMgbm90IHJlZmVyIHRvIHRoZSBzYW1lIG9iamVjdCIsIGZvbywgbG9nKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgibG9nZ2VyIGZvbyBzaG91bGQgbm90IGhhdmVuIHBhcmVudCIsIGZvby5nZXRQYXJlbnQoKSk7CisKKyAgICAgICAgLy8gY2FzZSAyOiB0ZXN0IHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtb2NrTWFuYWdlci5nZXRMb2dnZXIobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJnZXQgbnVsbCBzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gY2FzZSAzOiB0ZXN0IGJhZCBuYW1lCisgICAgICAgIGFzc2VydE51bGwoIkxvZ01hbmFnZXIgc2hvdWxkIG5vdCBoYXZlIGxvZ2dlciB3aXRoIHVuZm9yZXNlZW4gbmFtZSIsIG1vY2tNYW5hZ2VyCisgICAgICAgICAgICAgICAgLmdldExvZ2dlcigiYmFkIG5hbWUiKSk7CisKKyAgICAgICAgLy8gY2FzZSA0OiBjaGVjayBjb3JyZWN0IHRlc3RlZCB2YWx1ZQorICAgICAgICBFbnVtZXJhdGlvbjxTdHJpbmc+IGVudW1hciA9IG1vY2tNYW5hZ2VyLmdldExvZ2dlck5hbWVzKCk7CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgd2hpbGUgKGVudW1hci5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBlbnVtYXIubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygibmFtZSBsb2dnZXIgc2hvdWxkIGJlIGVxdWFsIHRvIGZvcmVzZWVuIG5hbWUiLCBGT08sIG5hbWUpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiTG9nTWFuYWdlciBzaG91bGQgY29udGFpbiBvbmUgZWxlbWVudCIsIDEsIGkpOworICAgIH0KKworICAgIC8qCisgICAgICogdGVzdCBmb3IgbWV0aG9kIHB1YmxpYyBMb2dnZXIgZ2V0TG9nZ2VyKFN0cmluZyBuYW1lKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRMb2dnZXJfZHVwbGljYXRlTmFtZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyB0ZXN0IGR1cGxpY2F0ZSBuYW1lCisgICAgICAgIC8vIGFkZCBsb2dnZXIgd2l0aCBkdXBsaWNhdGUgbmFtZSBoYXMgbm8gZWZmZWN0CisgICAgICAgIG1vY2tNYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgIExvZ2dlciBmb28yID0gbmV3IE1vY2tMb2dnZXIoRk9PLCBudWxsKTsKKyAgICAgICAgTG9nZ2VyIGZvbzMgPSBuZXcgTW9ja0xvZ2dlcihGT08sIG51bGwpOworICAgICAgICBtb2NrTWFuYWdlci5hZGRMb2dnZXIoZm9vMik7CisgICAgICAgIGFzc2VydFNhbWUoZm9vMiwgbW9ja01hbmFnZXIuZ2V0TG9nZ2VyKEZPTykpOworICAgICAgICBtb2NrTWFuYWdlci5hZGRMb2dnZXIoZm9vMyk7CisgICAgICAgIGFzc2VydFNhbWUoZm9vMiwgbW9ja01hbmFnZXIuZ2V0TG9nZ2VyKEZPTykpOworCisgICAgICAgIEVudW1lcmF0aW9uPFN0cmluZz4gZW51bWFyMiA9IG1vY2tNYW5hZ2VyLmdldExvZ2dlck5hbWVzKCk7CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgd2hpbGUgKGVudW1hcjIuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIGVudW1hcjIubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGkrKzsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiB0ZXN0IGZvciBtZXRob2QgcHVibGljIExvZ2dlciBnZXRMb2dnZXIoU3RyaW5nIG5hbWUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldExvZ2dlcl9oaWVyYXJjaHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gdGVzdCBoaWVyYXJjaHkKKyAgICAgICAgTG9nZ2VyIGZvbyA9IG5ldyBNb2NrTG9nZ2VyKCJ0ZXN0R2V0TG9nZ2VyX2hpZXJhY2h5LmZvbyIsIG51bGwpOworICAgICAgICAvLyBidXQgZm9yIG5vbi1tb2NrIExvZ01hbmFnZXIsIGZvbydzIHBhcmVudCBzaG91bGQgYmUgcm9vdAorICAgICAgICBhc3NlcnRUcnVlKG1hbmFnZXIuYWRkTG9nZ2VyKGZvbykpOworICAgICAgICBhc3NlcnRTYW1lKG1hbmFnZXIuZ2V0TG9nZ2VyKCIiKSwgbWFuYWdlci5nZXRMb2dnZXIoInRlc3RHZXRMb2dnZXJfaGllcmFjaHkuZm9vIikKKyAgICAgICAgICAgICAgICAuZ2V0UGFyZW50KCkpOworICAgIH0KKworICAgIC8qCisgICAgICogdGVzdCBmb3IgbWV0aG9kIHB1YmxpYyBMb2dnZXIgZ2V0TG9nZ2VyKFN0cmluZyBuYW1lKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRMb2dnZXJfbmFtZVNwYWNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIHRlc3QgbmFtZSB3aXRoIHNwYWNlCisgICAgICAgIExvZ2dlciBmb28gPSBuZXcgTW9ja0xvZ2dlcihGT08sIG51bGwpOworICAgICAgICBMb2dnZXIgZm9vQmVmb3JlU3BhY2UgPSBuZXcgTW9ja0xvZ2dlcihGT08gKyAiICIsIG51bGwpOworICAgICAgICBMb2dnZXIgZm9vQWZ0ZXJTcGFjZSA9IG5ldyBNb2NrTG9nZ2VyKCIgIiArIEZPTywgbnVsbCk7CisgICAgICAgIExvZ2dlciBmb29XaXRoQm90aFNwYWNlID0gbmV3IE1vY2tMb2dnZXIoIiAiICsgRk9PICsgIiAiLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtb2NrTWFuYWdlci5hZGRMb2dnZXIoZm9vKSk7CisgICAgICAgIGFzc2VydFRydWUobW9ja01hbmFnZXIuYWRkTG9nZ2VyKGZvb0JlZm9yZVNwYWNlKSk7CisgICAgICAgIGFzc2VydFRydWUobW9ja01hbmFnZXIuYWRkTG9nZ2VyKGZvb0FmdGVyU3BhY2UpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtb2NrTWFuYWdlci5hZGRMb2dnZXIoZm9vV2l0aEJvdGhTcGFjZSkpOworCisgICAgICAgIGFzc2VydFNhbWUoZm9vLCBtb2NrTWFuYWdlci5nZXRMb2dnZXIoRk9PKSk7CisgICAgICAgIGFzc2VydFNhbWUoZm9vQmVmb3JlU3BhY2UsIG1vY2tNYW5hZ2VyLmdldExvZ2dlcihGT08gKyAiICIpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShmb29BZnRlclNwYWNlLCBtb2NrTWFuYWdlci5nZXRMb2dnZXIoIiAiICsgRk9PKSk7CisgICAgICAgIGFzc2VydFNhbWUoZm9vV2l0aEJvdGhTcGFjZSwgbW9ja01hbmFnZXIuZ2V0TG9nZ2VyKCIgIiArIEZPTyArICIgIikpOworICAgIH0KKworICAgIC8qCisgICAgICogdGVzdCBmb3IgbWV0aG9kIHB1YmxpYyB2b2lkIGNoZWNrQWNjZXNzKCkgdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENoZWNrQWNjZXNzKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWFuYWdlci5jaGVja0FjY2VzcygpOworICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJzZWN1cml0eUV4Y2VwdGlvbiBzaG91bGQgbm90IGJlIHRocm93biIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRDb25maWd1cmF0aW9uKCkgdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uLAorICAgICAgICAgICAgSU9FeGNlcHRpb24geworCisgICAgICAgIE1vY2tDb25maWdMb2dNYW5hZ2VyIGxtID0gbmV3IE1vY2tDb25maWdMb2dNYW5hZ2VyKCk7CisgICAgICAgIGFzc2VydEZhbHNlKGxtLmlzQ2FsbGVkKTsKKworICAgICAgICBsbS5yZWFkQ29uZmlndXJhdGlvbigpOworICAgICAgICBhc3NlcnRUcnVlKGxtLmlzQ2FsbGVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZENvbmZpZ3VyYXRpb25JbnB1dFN0cmVhbV9JT0V4Y2VwdGlvbl8xcGFybSgpIHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtb2NrTWFuYWdlci5yZWFkQ29uZmlndXJhdGlvbihuZXcgTW9ja0lucHV0U3RyZWFtKCkpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElPRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE1vY2tJbnB1dFN0cmVhbSBleHRlbmRzIElucHV0U3RyZWFtIHsKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTW9ja0xvZ2dlciBleHRlbmRzIExvZ2dlciB7CisgICAgICAgIHB1YmxpYyBNb2NrTG9nZ2VyKFN0cmluZyBuYW1lLCBTdHJpbmcgcmJOYW1lKSB7CisgICAgICAgICAgICBzdXBlcihuYW1lLCByYk5hbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBNb2NrTG9nTWFuYWdlciBleHRlbmRzIExvZ01hbmFnZXIge30KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTW9ja0NvbmZpZ0xvZ01hbmFnZXIgZXh0ZW5kcyBMb2dNYW5hZ2VyIHsKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNDYWxsZWQgPSBmYWxzZTsKKworICAgICAgICBwdWJsaWMgdm9pZCByZWFkQ29uZmlndXJhdGlvbihJbnB1dFN0cmVhbSBpbnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpc0NhbGxlZCA9IHRydWU7CisgICAgICAgICAgICBzdXBlci5yZWFkQ29uZmlndXJhdGlvbihpbnMpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBNb2NrSGFuZGxlciBleHRlbmRzIEhhbmRsZXIgeworICAgICAgICBzdGF0aWMgaW50IG51bWJlciA9IDA7CisKKyAgICAgICAgcHVibGljIE1vY2tIYW5kbGVyKCkgeworICAgICAgICAgICAgYWRkTnVtYmVyKCk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIGFkZE51bWJlcigpIHsKKyAgICAgICAgICAgIG51bWJlcisrOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgICAgICBtaW51c051bWJlcigpOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCBtaW51c051bWJlcigpIHsKKyAgICAgICAgICAgIG51bWJlci0tOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgZmx1c2goKSB7fQorCisgICAgICAgIHB1YmxpYyB2b2lkIHB1Ymxpc2goTG9nUmVjb3JkIHJlY29yZCkge30KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvbG9nZ2luZy9PbGRMb2dSZWNvcmRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvbG9nZ2luZy9PbGRMb2dSZWNvcmRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjdmNGJjOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9sb2dnaW5nL09sZExvZ1JlY29yZFRlc3QuamF2YQpAQCAtMCwwICsxLDg2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC5sb2dnaW5nOworCitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZExvZ1JlY29yZFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIE1TRyA9ICJ0ZXN0IG1zZywgcGxzLiBpZ25vcmUgaXRiIjsKKworICAgIHByaXZhdGUgTG9nUmVjb3JkIGxyID0gbmV3IExvZ1JlY29yZChMZXZlbC5DT05GSUcsIE1TRyk7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2V0VGltZUNoZWNrKCkgeworICAgICAgICBsb25nIGJlZm9yZSA9IGxyLmdldE1pbGxpcygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDIpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisgICAgICAgIExvZ1JlY29yZCBscjIgPSBuZXcgTG9nUmVjb3JkKExldmVsLkNPTkZJRywgIk1TRzIiKTsKKyAgICAgICAgbG9uZyBhZnRlciA9IGxyMi5nZXRNaWxsaXMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhZnRlci1iZWZvcmU+MCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFNldExldmVsTm9ybWFsKCkgeworICAgICAgICBhc3NlcnRTYW1lKGxyLmdldExldmVsKCksIExldmVsLkNPTkZJRyk7CisgICAgICAgIGxyLnNldExldmVsKExldmVsLkFMTCk7CisgICAgICAgIGFzc2VydFNhbWUobHIuZ2V0TGV2ZWwoKSwgTGV2ZWwuQUxMKTsKKyAgICAgICAgbHIuc2V0TGV2ZWwoTGV2ZWwuRklORVNUKTsKKyAgICAgICAgYXNzZXJ0U2FtZShsci5nZXRMZXZlbCgpLCBMZXZlbC5GSU5FU1QpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRTZXRUaHJlYWRJRF9EaWZmZXJlbnRUaHJlYWQoKSB7CisgICAgICAgIGxyLmdldFRocmVhZElEKCk7CisgICAgICAgIC8vIENyZWF0ZSBhbmQgc3RhcnQgdGhlIHRocmVhZAorICAgICAgICBNb2NrVGhyZWFkIHRocmVhZCA9IG5ldyBNb2NrVGhyZWFkKCk7CisgICAgICAgIHRocmVhZC5zdGFydCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhyZWFkLmpvaW4oKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgICAgICAvLyBDcmVhdGUgYW5kIHN0YXJ0IHRoZSB0aHJlYWQyCisgICAgICAgIE1vY2tUaHJlYWQgdGhyZWFkMiA9IG5ldyBNb2NrVGhyZWFkKCk7CisgICAgICAgIHRocmVhZDIuc3RhcnQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRocmVhZDIuam9pbigpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisKKyAgICAgICAgLy9BbGwgdGhyZWFkSUQgbXVzdCBiZSBkaWZmZXJlbnQsIGJhc2VkIG9uIHRoZSBUaHJlYWRMb2NhbC5qYXZhIElECisgICAgICAgIGFzc2VydFRydWUobHIuZ2V0VGhyZWFkSUQoKSAhPSB0aHJlYWQubHIuZ2V0VGhyZWFkSUQoKSk7CisgICAgICAgIGFzc2VydFRydWUobHIuZ2V0VGhyZWFkSUQoKSAhPSB0aHJlYWQyLmxyLmdldFRocmVhZElEKCkpOworICAgICAgICBhc3NlcnRUcnVlKHRocmVhZC5sci5nZXRUaHJlYWRJRCgpICE9IHRocmVhZDIubHIuZ2V0VGhyZWFkSUQoKSk7CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIE1vY2tUaHJlYWQgZXh0ZW5kcyBUaHJlYWQgeworICAgICAgICBwdWJsaWMgTG9nUmVjb3JkIGxyID0gbnVsbDsgLy93aWxsIGJlIHVwZGF0ZSBieSB0aGUgdGhyZWFkCisKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgdXBkYXRlKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgdXBkYXRlKCl7CisgICAgICAgICAgICBsciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuQ09ORklHLCAibXNnIHRocmVhZCIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2xvZ2dpbmcvT2xkTG9nZ2VyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2xvZ2dpbmcvT2xkTG9nZ2VyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFkOGVkMjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvbG9nZ2luZy9PbGRMb2dnZXJUZXN0LmphdmEKQEAgLTAsMCArMSwyMzAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLmxvZ2dpbmc7CisKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkZpbHRlcjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5IYW5kbGVyOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxldmVsOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ01hbmFnZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ2dlcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBPbGRMb2dnZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBWQUxJRF9SRVNPVVJDRV9CVU5ETEUgPSAiYnVuZGxlcy9qYXZhL3V0aWwvbG9nZ2luZy9yZXMiOworICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBJTlZBTElEX1JFU09VUkNFX0JVTkRMRSA9ICJpbXBvc3NpYmxlX25vdF9leGlzdGluZyI7CisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFZBTElEX0tFWSA9ICJMT0dHRVJURVNUIjsKKyAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgVkFMSURfVkFMVUUgPSAiVGVzdF9aSF9DTiI7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCkucmVzZXQoKTsKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobmV3IExvY2FsZSgiemgiLCAiQ04iKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpLnJlc2V0KCk7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldExvZ2dlcldpdGhSZXNfSW52YWxpZFJlc291cmNlQnVuZGxlKCkgeworICAgICAgICBhc3NlcnROdWxsKExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpLmdldExvZ2dlcigKKyAgICAgICAgICAgICAgICAidGVzdE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiIpKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpLmdldExvZ2dlcigiIikpOworICAgICAgICAvLyBUaGUgcm9vdCBsb2dnZXIgYWx3YXlzIGV4aXN0cyBUT0RPCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMb2dnZXIuZ2V0TG9nZ2VyKCIiLCBJTlZBTElEX1JFU09VUkNFX0JVTkRMRSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdsb2JhbExvZ2dlcigpIHsKKyAgICAgICAgYXNzZXJ0TnVsbChMb2dnZXIuZ2xvYmFsLmdldEZpbHRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIExvZ2dlci5nbG9iYWwuZ2V0SGFuZGxlcnMoKS5sZW5ndGgpOworICAgICAgICBhc3NlcnROdWxsKExvZ2dlci5nbG9iYWwuZ2V0TGV2ZWwoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ2xvYmFsIiwgTG9nZ2VyLmdsb2JhbC5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnROdWxsKExvZ2dlci5nbG9iYWwuZ2V0UGFyZW50KCkuZ2V0UGFyZW50KCkpOworICAgICAgICBhc3NlcnROdWxsKExvZ2dlci5nbG9iYWwuZ2V0UmVzb3VyY2VCdW5kbGUoKSk7CisgICAgICAgIGFzc2VydE51bGwoTG9nZ2VyLmdsb2JhbC5nZXRSZXNvdXJjZUJ1bmRsZU5hbWUoKSk7CisgICAgICAgIGFzc2VydFRydWUoTG9nZ2VyLmdsb2JhbC5nZXRVc2VQYXJlbnRIYW5kbGVycygpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShMb2dnZXIuZ2xvYmFsLCBMb2dnZXIuZ2V0TG9nZ2VyKCJnbG9iYWwiKSk7CisgICAgICAgIGFzc2VydFNhbWUoTG9nZ2VyLmdsb2JhbCwgTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCkuZ2V0TG9nZ2VyKCJnbG9iYWwiKSk7CisgICAgICAgIGFzc2VydFNhbWUoTG9nZ2VyLmdsb2JhbCwgTG9nZ2VyLmdldEdsb2JhbCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RydWN0b3JfTm9ybWFsKCkgeworICAgICAgICBNb2NrTG9nZ2VyIG1sb2cgPSBuZXcgTW9ja0xvZ2dlcigibXluYW1lIiwgVkFMSURfUkVTT1VSQ0VfQlVORExFKTsKKyAgICAgICAgYXNzZXJ0TnVsbChtbG9nLmdldEZpbHRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG1sb2cuZ2V0SGFuZGxlcnMoKS5sZW5ndGgpOworICAgICAgICBhc3NlcnROdWxsKG1sb2cuZ2V0TGV2ZWwoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibXluYW1lIiwgbWxvZy5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnROdWxsKG1sb2cuZ2V0UGFyZW50KCkpOworICAgICAgICBSZXNvdXJjZUJ1bmRsZSByYiA9IG1sb2cuZ2V0UmVzb3VyY2VCdW5kbGUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFZBTElEX1ZBTFVFLCByYi5nZXRTdHJpbmcoVkFMSURfS0VZKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtbG9nLmdldFJlc291cmNlQnVuZGxlTmFtZSgpLCBWQUxJRF9SRVNPVVJDRV9CVU5ETEUpOworICAgICAgICBhc3NlcnRUcnVlKG1sb2cuZ2V0VXNlUGFyZW50SGFuZGxlcnMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdG9yX051bGwoKSB7CisgICAgICAgIE1vY2tMb2dnZXIgbWxvZyA9IG5ldyBNb2NrTG9nZ2VyKG51bGwsIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKG1sb2cuZ2V0RmlsdGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbWxvZy5nZXRIYW5kbGVycygpLmxlbmd0aCk7CisgICAgICAgIGFzc2VydE51bGwobWxvZy5nZXRMZXZlbCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChtbG9nLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydE51bGwobWxvZy5nZXRQYXJlbnQoKSk7CisgICAgICAgIGFzc2VydE51bGwobWxvZy5nZXRSZXNvdXJjZUJ1bmRsZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChtbG9nLmdldFJlc291cmNlQnVuZGxlTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtbG9nLmdldFVzZVBhcmVudEhhbmRsZXJzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25zdHJ1Y3Rvcl9JbnZhbGlkTmFtZSgpIHsKKyAgICAgICAgTW9ja0xvZ2dlciBtbG9nID0gbmV3IE1vY2tMb2dnZXIoIi4uLiMkJSVeJiYoKS1fKz0hQH4uLyxbXXt9OzonXFxcIj98IiwKKyAgICAgICAgICAgICAgICBudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIuLi4jJCUlXiYmKCktXys9IUB+Li8sW117fTs6J1xcXCI/fCIsIG1sb2cuZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFRlc3QgY29uc3RydWN0b3Igd2l0aCBlbXB0eSBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25zdHJ1Y3Rvcl9FbXB0eU5hbWUoKSB7CisgICAgICAgIE1vY2tMb2dnZXIgbWxvZyA9IG5ldyBNb2NrTG9nZ2VyKCIiLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBtbG9nLmdldE5hbWUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdG9yX0ludmFsaWRSZXNvdXJjZUJ1bmRsZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBNb2NrTG9nZ2VyKCJ0ZXN0Q29uc3RydWN0b3JfSW52YWxpZFJlc291cmNlQnVuZGxlIiwKKyAgICAgICAgICAgICAgICAgICAgSU5WQUxJRF9SRVNPVVJDRV9CVU5ETEUpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiEiKTsKKyAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TG9nZ2VyX051bGwoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMb2dnZXIuZ2V0TG9nZ2VyKG51bGwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uISIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldExvZ2dlcl9XaXRoUGFyZW50KCkgeworICAgICAgICBhc3NlcnROdWxsKExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpLmdldExvZ2dlcigKKyAgICAgICAgICAgICAgICAidGVzdEdldExvZ2dlcl9XaXRoUGFyZW50X1BhcmVudExvZ2dlciIpKTsKKworICAgICAgICAvLyBnZXQgcm9vdCBvZiBoaWVyYXJjaHkKKyAgICAgICAgTG9nZ2VyIHJvb3QgPSBMb2dnZXIuZ2V0TG9nZ2VyKCIiKTsKKyAgICAgICAgLy8gY3JlYXRlIHRoZSBwYXJlbnQgbG9nZ2VyCisgICAgICAgIExvZ2dlciBwTG9nID0gTG9nZ2VyLmdldExvZ2dlcigidGVzdEdldExvZ2dlcl9XaXRoUGFyZW50X1BhcmVudExvZ2dlciIsCisgICAgICAgICAgICAgICAgVkFMSURfUkVTT1VSQ0VfQlVORExFKTsKKyAgICAgICAgcExvZy5zZXRMZXZlbChMZXZlbC5DT05GSUcpOworICAgICAgICBwTG9nLmFkZEhhbmRsZXIobmV3IE1vY2tIYW5kbGVyKCkpOworICAgICAgICBwTG9nLnNldEZpbHRlcihuZXcgTW9ja0ZpbHRlcigpKTsKKyAgICAgICAgcExvZy5zZXRVc2VQYXJlbnRIYW5kbGVycyhmYWxzZSk7CisgICAgICAgIC8vIGNoZWNrIHJvb3QgcGFyZW50CisgICAgICAgIGFzc2VydEVxdWFscygidGVzdEdldExvZ2dlcl9XaXRoUGFyZW50X1BhcmVudExvZ2dlciIsIHBMb2cuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShwTG9nLmdldFBhcmVudCgpLCByb290KTsKKworICAgICAgICAvLyBjaGlsZCBwYXJ0CisgICAgICAgIGFzc2VydE51bGwoTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCkuZ2V0TG9nZ2VyKAorICAgICAgICAgICAgICAgICJ0ZXN0R2V0TG9nZ2VyX1dpdGhQYXJlbnRfUGFyZW50TG9nZ2VyLmNoaWxkIikpOworICAgICAgICAvLyBjcmVhdGUgdGhlIGNoaWxkIGxvZ2dlcgorICAgICAgICBMb2dnZXIgY2hpbGQgPSBMb2dnZXIKKyAgICAgICAgICAgICAgICAuZ2V0TG9nZ2VyKCJ0ZXN0R2V0TG9nZ2VyX1dpdGhQYXJlbnRfUGFyZW50TG9nZ2VyLmNoaWxkIik7CisgICAgICAgIGFzc2VydE51bGwoY2hpbGQuZ2V0RmlsdGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgY2hpbGQuZ2V0SGFuZGxlcnMoKS5sZW5ndGgpOworICAgICAgICBhc3NlcnROdWxsKGNoaWxkLmdldExldmVsKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRlc3RHZXRMb2dnZXJfV2l0aFBhcmVudF9QYXJlbnRMb2dnZXIuY2hpbGQiLCBjaGlsZAorICAgICAgICAgICAgICAgIC5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRTYW1lKGNoaWxkLmdldFBhcmVudCgpLCBwTG9nKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjaGlsZC5nZXRSZXNvdXJjZUJ1bmRsZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjaGlsZC5nZXRSZXNvdXJjZUJ1bmRsZU5hbWUoKSk7CisgICAgICAgIGFzc2VydFRydWUoY2hpbGQuZ2V0VXNlUGFyZW50SGFuZGxlcnMoKSk7CisKKyAgICAgICAgLy8gY3JlYXRlIG5vdCB2YWxpZCBjaGlsZAorICAgICAgICBMb2dnZXIgbm90Q2hpbGQgPSBMb2dnZXIKKyAgICAgICAgICAgICAgICAuZ2V0TG9nZ2VyKCJ0ZXN0R2V0TG9nZ2VyX1dpdGhQYXJlbnRfUGFyZW50TG9nZ2VyMS5jaGlsZCIpOworICAgICAgICBhc3NlcnROdWxsKG5vdENoaWxkLmdldEZpbHRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG5vdENoaWxkLmdldEhhbmRsZXJzKCkubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChub3RDaGlsZC5nZXRMZXZlbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXN0R2V0TG9nZ2VyX1dpdGhQYXJlbnRfUGFyZW50TG9nZ2VyMS5jaGlsZCIsIG5vdENoaWxkCisgICAgICAgICAgICAgICAgLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydE5vdFNhbWUobm90Q2hpbGQuZ2V0UGFyZW50KCksIHBMb2cpOworICAgICAgICBhc3NlcnROdWxsKG5vdENoaWxkLmdldFJlc291cmNlQnVuZGxlKCkpOworICAgICAgICBhc3NlcnROdWxsKG5vdENoaWxkLmdldFJlc291cmNlQnVuZGxlTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShub3RDaGlsZC5nZXRVc2VQYXJlbnRIYW5kbGVycygpKTsKKyAgICAgICAgLy8gdmVyaWZ5IHR3byBsZXZlbCByb290LnBhcmVudAorICAgICAgICBhc3NlcnRFcXVhbHMoInRlc3RHZXRMb2dnZXJfV2l0aFBhcmVudF9QYXJlbnRMb2dnZXIuY2hpbGQiLCBjaGlsZAorICAgICAgICAgICAgICAgIC5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRTYW1lKGNoaWxkLmdldFBhcmVudCgpLmdldFBhcmVudCgpLCByb290KTsKKworCisgICAgICAgIC8vIGNyZWF0ZSB0aHJlZSBsZXZlbCBjaGlsZAorICAgICAgICBMb2dnZXIgY2hpbGRPZkNoaWxkID0gTG9nZ2VyCisgICAgICAgICAgICAgICAgLmdldExvZ2dlcigidGVzdEdldExvZ2dlcl9XaXRoUGFyZW50X1BhcmVudExvZ2dlci5jaGlsZC5jaGlsZCIpOworICAgICAgICBhc3NlcnROdWxsKGNoaWxkT2ZDaGlsZC5nZXRGaWx0ZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBjaGlsZE9mQ2hpbGQuZ2V0SGFuZGxlcnMoKS5sZW5ndGgpOworICAgICAgICBhc3NlcnRTYW1lKGNoaWxkLmdldFBhcmVudCgpLmdldFBhcmVudCgpLCByb290KTsKKyAgICAgICAgYXNzZXJ0TnVsbChjaGlsZE9mQ2hpbGQuZ2V0TGV2ZWwoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidGVzdEdldExvZ2dlcl9XaXRoUGFyZW50X1BhcmVudExvZ2dlci5jaGlsZC5jaGlsZCIsCisgICAgICAgICAgICAgICAgY2hpbGRPZkNoaWxkLmdldE5hbWUoKSk7CisKKyAgICAgICAgYXNzZXJ0U2FtZShjaGlsZE9mQ2hpbGQuZ2V0UGFyZW50KCksIGNoaWxkKTsKKyAgICAgICAgYXNzZXJ0U2FtZShjaGlsZE9mQ2hpbGQuZ2V0UGFyZW50KCkuZ2V0UGFyZW50KCksIHBMb2cpOworICAgICAgICBhc3NlcnRTYW1lKGNoaWxkT2ZDaGlsZC5nZXRQYXJlbnQoKS5nZXRQYXJlbnQoKS5nZXRQYXJlbnQoKSwgcm9vdCk7CisgICAgICAgIGFzc2VydE51bGwoY2hpbGRPZkNoaWxkLmdldFJlc291cmNlQnVuZGxlKCkpOworICAgICAgICBhc3NlcnROdWxsKGNoaWxkT2ZDaGlsZC5nZXRSZXNvdXJjZUJ1bmRsZU5hbWUoKSk7CisgICAgICAgIGFzc2VydFRydWUoY2hpbGRPZkNoaWxkLmdldFVzZVBhcmVudEhhbmRsZXJzKCkpOworCisgICAgICAgIC8vIGFibm9ybWFsIGNhc2UgOiBsb29rdXAgdG8gcm9vdCBwYXJlbnQgaW4gYSBoaWVyYXJjaHkgd2l0aG91dCBhIGxvZ2dlcgorICAgICAgICAvLyBwYXJlbnQgY3JlYXRlZCBiZXR3ZWVuCisgICAgICAgIGFzc2VydEVxdWFscygidGVzdEdldExvZ2dlcl9XaXRoUGFyZW50X1BhcmVudExvZ2dlcjEuY2hpbGQiLCBub3RDaGlsZAorICAgICAgICAgICAgICAgIC5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRTYW1lKGNoaWxkLmdldFBhcmVudCgpLmdldFBhcmVudCgpLCByb290KTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShjaGlsZC5nZXRQYXJlbnQoKSwgcm9vdCk7CisKKyAgICAgICAgLy8gYWJub3JtYWwgY2FzZXMKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShyb290LmdldFBhcmVudCgpLCByb290KTsKKyAgICAgICAgTG9nZ2VyIHR3b0RvdCA9IExvZ2dlci5nZXRMb2dnZXIoIi4uIik7CisgICAgICAgIGFzc2VydFNhbWUodHdvRG90LmdldFBhcmVudCgpLCByb290KTsKKworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTW9ja0xvZ2dlciBleHRlbmRzIExvZ2dlciB7CisgICAgICAgIHB1YmxpYyBNb2NrTG9nZ2VyKFN0cmluZyBuYW1lLCBTdHJpbmcgcmVzb3VyY2VCdW5kbGVOYW1lKSB7CisgICAgICAgICAgICBzdXBlcihuYW1lLCByZXNvdXJjZUJ1bmRsZU5hbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBNb2NrSGFuZGxlciBleHRlbmRzIEhhbmRsZXIgeworICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHt9CisgICAgICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkge30KKyAgICAgICAgcHVibGljIHZvaWQgcHVibGlzaChMb2dSZWNvcmQgcmVjb3JkKSB7fQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTW9ja0ZpbHRlciBpbXBsZW1lbnRzIEZpbHRlciB7CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzTG9nZ2FibGUoTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2xvZ2dpbmcvT2xkTWVtb3J5SGFuZGxlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9sb2dnaW5nL09sZE1lbW9yeUhhbmRsZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzI3NzBjNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9sb2dnaW5nL09sZE1lbW9yeUhhbmRsZXJUZXN0LmphdmEKQEAgLTAsMCArMSw5NSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWwubG9nZ2luZzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkZpbHRlcjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5IYW5kbGVyOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxldmVsOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ01hbmFnZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLk1lbW9yeUhhbmRsZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkTWVtb3J5SGFuZGxlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBmaW5hbCBzdGF0aWMgTG9nTWFuYWdlciBtYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7CisgICAgZmluYWwgc3RhdGljIFByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworICAgIGZpbmFsIHN0YXRpYyBTdHJpbmcgYmFzZUNsYXNzTmFtZSA9IE9sZE1lbW9yeUhhbmRsZXJUZXN0LmNsYXNzLmdldE5hbWUoKTsKKyAgICBNZW1vcnlIYW5kbGVyIGhhbmRsZXI7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgbWFuYWdlci5yZXNldCgpOworICAgICAgICBpbml0UHJvcHMoKTsKKyAgICAgICAgbWFuYWdlci5yZWFkQ29uZmlndXJhdGlvbihwcm9wZXJ0aWVzVG9JbnB1dFN0cmVhbShwcm9wcykpOworICAgICAgICBoYW5kbGVyID0gbmV3IE1lbW9yeUhhbmRsZXIoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICAgICAgbWFuYWdlci5yZWFkQ29uZmlndXJhdGlvbigpOworICAgICAgICBwcm9wcy5jbGVhcigpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgSW5wdXRTdHJlYW0gcHJvcGVydGllc1RvSW5wdXRTdHJlYW0oUHJvcGVydGllcyBwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBwLnN0b3JlKGJvcywgIiIpOworICAgICAgICByZXR1cm4gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJvcy50b0J5dGVBcnJheSgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgaW5pdFByb3BzKCkgeworICAgICAgICBwcm9wcy5wdXQoImphdmEudXRpbC5sb2dnaW5nLk1lbW9yeUhhbmRsZXIubGV2ZWwiLCAiRklORSIpOworICAgICAgICBwcm9wcy5wdXQoImphdmEudXRpbC5sb2dnaW5nLk1lbW9yeUhhbmRsZXIuZmlsdGVyIiwgYmFzZUNsYXNzTmFtZSArICIkTW9ja0ZpbHRlciIpOworICAgICAgICBwcm9wcy5wdXQoImphdmEudXRpbC5sb2dnaW5nLk1lbW9yeUhhbmRsZXIuc2l6ZSIsICIyIik7CisgICAgICAgIHByb3BzLnB1dCgiamF2YS51dGlsLmxvZ2dpbmcuTWVtb3J5SGFuZGxlci5wdXNoIiwgIldBUk5JTkciKTsKKyAgICAgICAgcHJvcHMucHV0KCJqYXZhLnV0aWwubG9nZ2luZy5NZW1vcnlIYW5kbGVyLnRhcmdldCIsIGJhc2VDbGFzc05hbWUgKyAiJE1vY2tIYW5kbGVyIik7CisgICAgICAgIHByb3BzLnB1dCgiamF2YS51dGlsLmxvZ2dpbmcuTWVtb3J5SGFuZGxlci5mb3JtYXR0ZXIiLCBiYXNlQ2xhc3NOYW1lICsgIiRNb2NrRm9ybWF0dGVyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdElzTG9nZ2FibGUoKSB7CisgICAgICAgIGFzc2VydFRydWUoaGFuZGxlci5pc0xvZ2dhYmxlKG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgIjEiKSkpOworICAgICAgICBhc3NlcnRUcnVlKGhhbmRsZXIuaXNMb2dnYWJsZShuZXcgTG9nUmVjb3JkKExldmVsLldBUk5JTkcsICIyIikpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShoYW5kbGVyLmlzTG9nZ2FibGUobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIzIikpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWVtb3J5SGFuZGxlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkZpbHRlciBzaG91bGQgbm90IGJlIG51bGwiLCBoYW5kbGVyLmdldEZpbHRlcigpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiRm9ybWF0dGVyIHNob3VsZCBub3QgYmUgbnVsbCIsIGhhbmRsZXIuZ2V0Rm9ybWF0dGVyKCkpOworICAgICAgICBhc3NlcnROdWxsKCJjaGFyYWN0ZXIgZW5jb2Rpbmcgc2hvdWxkIGJlIG51bGwiLCBoYW5kbGVyLmdldEVuY29kaW5nKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJFcnJvck1hbmFnZXIgc2hvdWxkIG5vdCBiZSBudWxsIiwgaGFuZGxlci5nZXRFcnJvck1hbmFnZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiTGV2ZWwgc2hvdWxkIGJlIEZJTkUiLCBMZXZlbC5GSU5FLCBoYW5kbGVyLmdldExldmVsKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkxldmVsIHNob3VsZCBiZSBXQVJOSU5HIiwgTGV2ZWwuV0FSTklORywgaGFuZGxlci5nZXRQdXNoTGV2ZWwoKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBNb2NrRmlsdGVyIGltcGxlbWVudHMgRmlsdGVyIHsKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNMb2dnYWJsZShMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgICAgICByZXR1cm4gIXJlY29yZC5nZXRNZXNzYWdlKCkuZXF1YWxzKCJmYWxzZSIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBNb2NrSGFuZGxlciBleHRlbmRzIEhhbmRsZXIgeworICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHt9CisgICAgICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkge30KKyAgICAgICAgcHVibGljIHZvaWQgcHVibGlzaChMb2dSZWNvcmQgcmVjb3JkKSB7fQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9sb2dnaW5nL09sZFNpbXBsZUZvcm1hdHRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9sb2dnaW5nL09sZFNpbXBsZUZvcm1hdHRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NGJlMDEwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL2xvZ2dpbmcvT2xkU2ltcGxlRm9ybWF0dGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLmxvZ2dpbmc7CisKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5TaW1wbGVGb3JtYXR0ZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkU2ltcGxlRm9ybWF0dGVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIFNpbXBsZUZvcm1hdHRlciBzZiA9IG5ldyBTaW1wbGVGb3JtYXR0ZXIoKTsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RTaW1wbGVGb3JtYXR0ZXIoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiSGVhZCBmb3IgdGhpcyBTaW1wbGVGb3JtYXR0ZXIgc2hvdWxkIGJlIGVtcHR5IiwgIiIsIHNmLmdldEhlYWQobnVsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRhaWwgZm9yIHRoaXMgU2ltcGxlRm9ybWF0dGVyIHNob3VsZCBiZSBlbXB0eSIsICIiLCBzZi5nZXRUYWlsKG51bGwpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvbG9nZ2luZy9PbGRYTUxGb3JtYXR0ZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvbG9nZ2luZy9PbGRYTUxGb3JtYXR0ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTg5N2ZhMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9sb2dnaW5nL09sZFhNTEZvcm1hdHRlclRlc3QuamF2YQpAQCAtMCwwICsxLDc0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC5sb2dnaW5nOworCitpbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkhhbmRsZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLlhNTEZvcm1hdHRlcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBPbGRYTUxGb3JtYXR0ZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgWE1MRm9ybWF0dGVyIGZvcm1hdHRlciA9IG51bGw7CisgICAgTW9ja0hhbmRsZXIgaGFuZGxlciA9IG51bGw7CisgICAgTG9nUmVjb3JkIGxyID0gbnVsbDsKKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBmb3JtYXR0ZXIgPSBuZXcgWE1MRm9ybWF0dGVyKCk7CisgICAgICAgIGhhbmRsZXIgPSBuZXcgTW9ja0hhbmRsZXIoKTsKKyAgICAgICAgbHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgInBhdHRlcm4iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0WE1MRm9ybWF0dGVyKCkgdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uLCBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgaGFuZGxlci5zZXRFbmNvZGluZygiVVRGLTgiKTsKKworICAgICAgICBTdHJpbmcgcmVzdWx0ID0gZm9ybWF0dGVyLmdldEhlYWQoaGFuZGxlcik7CisgICAgICAgIGludCBoZWFkUG9zID0gcmVzdWx0CisgICAgICAgICAgICAgICAgLmluZGV4T2YoIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi04XCIgc3RhbmRhbG9uZT1cIm5vXCI/PiIpOworICAgICAgICBpbnQgZHRkUG9zID0gcmVzdWx0LmluZGV4T2YoIjwhRE9DVFlQRSBsb2cgU1lTVEVNIFwibG9nZ2VyLmR0ZFwiPiIpOworICAgICAgICBpbnQgcm9vdFBvcyA9IHJlc3VsdC5pbmRleE9mKCI8bG9nPiIpOworICAgICAgICBhc3NlcnRUcnVlKCJoZWFkIHN0cmluZyBwb3NpdGlvbiBzaG91bGQgYmUgbW9yZSBvciBlcXVhbCB6ZXJvIiwKKyAgICAgICAgICAgICAgICBoZWFkUG9zID49IDApOworICAgICAgICBhc3NlcnRUcnVlKCJkdGQgc3RyaW5nIHBvc2l0aW9uIHNob3VsZCBiZSBtb3JlIGhlYWQgc3RyaW5nIHBvc2l0aW9uIiwKKyAgICAgICAgICAgICAgICBkdGRQb3MgPiBoZWFkUG9zKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgicm9vdCBzdHJpbmcgcG9zaXRpb24gc2hvdWxkIGJlIG1vcmUgZHRkIHN0cmluZyBwb3NpdGlvbiIsCisgICAgICAgICAgICAgICAgcm9vdFBvcyA+IGR0ZFBvcyk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGFpbCBzdHJpbmcgcG9zaXRpb24gc2hvdWxkIGJlIG1vcmUgemVybyIsIGZvcm1hdHRlcgorICAgICAgICAgICAgICAgIC5nZXRUYWlsKGhhbmRsZXIpLmluZGV4T2YoIi9sb2c+IikgPiAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VGFpbCgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUYWlsIHN0cmluZyB3aXRoIG51bGwgaGFuZGxlciBzaG91bGQgYmUgZXF1YWwgZXhwZWN0ZWQgdmFsdWUiLAorICAgICAgICAgICAgICAgICI8L2xvZz4iLCBmb3JtYXR0ZXIuZ2V0VGFpbChudWxsKS50cmltKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRhaWwgc3RyaW5nIHNob3VsZCBiZSBlcXVhbCBleHBlY3RlZCB2YWx1ZSIsICI8L2xvZz4iLAorICAgICAgICAgICAgICAgIGZvcm1hdHRlci5nZXRUYWlsKGhhbmRsZXIpLnRyaW0oKSk7CisgICAgICAgIGhhbmRsZXIucHVibGlzaChscik7CisgICAgICAgIGFzc2VydEVxdWFscygiVGFpbCBzdHJpbmcgYWZ0ZXIgcHVibGlzaCgpIHNob3VsZCBiZSBlcXVhbCBleHBlY3RlZCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgIjwvbG9nPiIsIGZvcm1hdHRlci5nZXRUYWlsKGhhbmRsZXIpLnRyaW0oKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBNb2NrSGFuZGxlciBleHRlbmRzIEhhbmRsZXIgeworICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHt9CisgICAgICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkge30KKyAgICAgICAgcHVibGljIHZvaWQgcHVibGlzaChMb2dSZWNvcmQgcmVjb3JkKSB7fQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9wcmVmcy9PbGRBYnN0cmFjdFByZWZlcmVuY2VzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ByZWZzL09sZEFic3RyYWN0UHJlZmVyZW5jZXNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjlkM2YxZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9wcmVmcy9PbGRBYnN0cmFjdFByZWZlcmVuY2VzVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTEzNiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWwucHJlZnM7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLnByZWZzLkFic3RyYWN0UHJlZmVyZW5jZXM7CitpbXBvcnQgamF2YS51dGlsLnByZWZzLkJhY2tpbmdTdG9yZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwucHJlZnMuSW52YWxpZFByZWZlcmVuY2VzRm9ybWF0RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5wcmVmcy5Ob2RlQ2hhbmdlRXZlbnQ7CitpbXBvcnQgamF2YS51dGlsLnByZWZzLk5vZGVDaGFuZ2VMaXN0ZW5lcjsKK2ltcG9ydCBqYXZhLnV0aWwucHJlZnMuUHJlZmVyZW5jZUNoYW5nZUV2ZW50OworaW1wb3J0IGphdmEudXRpbC5wcmVmcy5QcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXI7CitpbXBvcnQgamF2YS51dGlsLnByZWZzLlByZWZlcmVuY2VzOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIE9sZEFic3RyYWN0UHJlZmVyZW5jZXNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBub2RlTmFtZSA9ICJtb2NrIjsKKworICAgIEFic3RyYWN0UHJlZmVyZW5jZXMgcHJlZjsKKyAgICBBYnN0cmFjdFByZWZlcmVuY2VzIHJvb3Q7CisgICAgQWJzdHJhY3RQcmVmZXJlbmNlcyBwYXJlbnQgPSBudWxsOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKworICAgICAgICByb290ID0gKEFic3RyYWN0UHJlZmVyZW5jZXMpIFByZWZlcmVuY2VzLnVzZXJSb290KCk7CisgICAgICAgIGZvciAoU3RyaW5nIGNoaWxkIDogcm9vdC5jaGlsZHJlbk5hbWVzKCkpIHsKKyAgICAgICAgICAgIHJvb3Qubm9kZShjaGlsZCkucmVtb3ZlTm9kZSgpOworICAgICAgICB9CisgICAgICAgIHJvb3QuY2xlYXIoKTsKKworICAgICAgICBwYXJlbnQgPSAoQWJzdHJhY3RQcmVmZXJlbmNlcykgUHJlZmVyZW5jZXMudXNlck5vZGVGb3JQYWNrYWdlKGdldENsYXNzKCkpOworICAgICAgICBwcmVmID0gKEFic3RyYWN0UHJlZmVyZW5jZXMpIHBhcmVudC5ub2RlKG5vZGVOYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9TdHJpbmcoKSB7CisgICAgICAgIGFzc2VydFRydWUocHJlZi50b1N0cmluZygpLmNvbnRhaW5zKG5vZGVOYW1lKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1dCgpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBwcmVmLnB1dCgiVmFsdWUiLCAiU3RyaW5nIik7CisgICAgICAgIHByZWYuZmx1c2goKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlN0cmluZyIsIHByZWYuZ2V0KCJWYWx1ZSIsICI6IikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnB1dChudWxsLCAiRXhjZXB0aW9uIik7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBpbnQgaTsKKyAgICAgICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOworCisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBQcmVmZXJlbmNlcy5NQVhfS0VZX0xFTkdUSCArIDE7IGkrKykgeworICAgICAgICAgICAgc2IuYXBwZW5kKCdjJyk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXQobmV3IFN0cmluZyhzYiksICJFeGNlcHRpb24iKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IFByZWZlcmVuY2VzLk1BWF9WQUxVRV9MRU5HVEggKyAxOyBpKyspIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgnYycpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0KCJEb3VibGVWYWx1ZSIsIG5ldyBTdHJpbmcoc2IpKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0KCJEb3VibGVWYWx1ZSIsICJFeGNlcHRpb24iKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldCgpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBwcmVmLnB1dCgiVmFsdWUiLCAiU3RyaW5nIik7CisgICAgICAgIHByZWYucHV0RG91YmxlKCJEb3VibGVWYWx1ZSIsIG5ldyBEb3VibGUoOS4xMDkzODE4OGUtMzEpKTsKKyAgICAgICAgcHJlZi5wdXRCb29sZWFuKCJCb29sVmFsdWUiLCB0cnVlKTsKKyAgICAgICAgcHJlZi5mbHVzaCgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiU3RyaW5nIiwgcHJlZi5nZXQoIlZhbHVlIiwgIjoiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidHJ1ZSIsIHByZWYuZ2V0KCJCb29sVmFsdWUiLCAiOiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI5LjEwOTM4MTg4RS0zMSIsIHByZWYuZ2V0KCJEb3VibGVWYWx1ZSIsIG51bGwpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5nZXQobnVsbCwgIkV4Y2VwdGlvbiIpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYuZ2V0KCJEb3VibGVWYWx1ZSIsICJFeGNlcHRpb24iKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZSgpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBTdHJpbmdbXSBrZXlBcnJheSA9IG5ldyBTdHJpbmdbXXsiVmFsdWUiLCAiRG91YmxlVmFsdWUiLCAiTG9uZ1ZhbHVlIiwgIkludFZhbHVlIn07CisgICAgICAgIHByZWYucHV0KGtleUFycmF5WzBdLCAiU3RyaW5nIik7CisgICAgICAgIHByZWYucHV0RG91YmxlKGtleUFycmF5WzFdLCBuZXcgRG91YmxlKDkuMTA5MzgxODhlLTMxKSk7CisgICAgICAgIHByZWYucHV0TG9uZyhrZXlBcnJheVsyXSwgbmV3IExvbmcoTG9uZy5NSU5fVkFMVUUpKTsKKyAgICAgICAgcHJlZi5wdXRJbnQoa2V5QXJyYXlbM10sIDI5OTc5MjQ1OCk7CisgICAgICAgIHByZWYubm9kZSgiTmV3IG5vZGUiKTsKKyAgICAgICAgcHJlZi5mbHVzaCgpOworCisgICAgICAgIFN0cmluZ1tdIHN0ciA9IHByZWYua2V5cygpOworICAgICAgICBhc3NlcnRFcXVhbHMoa2V5QXJyYXkubGVuZ3RoLCBzdHIubGVuZ3RoKTsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGtleUFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBwcmVmLnJlbW92ZShrZXlBcnJheVtpXSk7CisgICAgICAgICAgICBzdHIgPSBwcmVmLmtleXMoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhrZXlBcnJheS5sZW5ndGggLSBpIC0gMSwgc3RyLmxlbmd0aCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHByZWYuY2hpbGRyZW5OYW1lcygpLmxlbmd0aCk7CisgICAgICAgIHByZWYucmVtb3ZlKCJOZXcgbm9kZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgcHJlZi5jaGlsZHJlbk5hbWVzKCkubGVuZ3RoKTsKKworICAgICAgICBwcmVmLnJlbW92ZU5vZGUoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5yZW1vdmUoIk5ldyBub2RlIik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDbGVhcigpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBBYnN0cmFjdFByZWZlcmVuY2VzIGFwID0gKEFic3RyYWN0UHJlZmVyZW5jZXMpIHByZWYubm9kZSgiTmV3IG5vZGUiKTsKKyAgICAgICAgcHJlZi5wdXRJbnQoIkludFZhbHVlIiwgMzMpOworICAgICAgICBwcmVmLnB1dEJvb2xlYW4oIkJvb2xWYWx1ZSIsIHRydWUpOworICAgICAgICBwcmVmLmZsdXNoKCk7CisgICAgICAgIGFzc2VydFRydWUocHJlZi5nZXRCb29sZWFuKCJCb29sVmFsdWUiLCBmYWxzZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMzMsIHByZWYuZ2V0SW50KCJJbnRWYWx1ZSIsIDIyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBwcmVmLmNoaWxkcmVuTmFtZXMoKS5sZW5ndGgpOworICAgICAgICBwcmVmLmNsZWFyKCk7CisgICAgICAgIGFzc2VydEZhbHNlKHByZWYuZ2V0Qm9vbGVhbigiQm9vbFZhbHVlIiwgZmFsc2UpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIyLCBwcmVmLmdldEludCgiSW50VmFsdWUiLCAyMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgcHJlZi5jaGlsZHJlbk5hbWVzKCkubGVuZ3RoKTsKKworICAgICAgICBwcmVmLnJlbW92ZU5vZGUoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5jbGVhcigpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXAuY2xlYXIoKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1dEludCgpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBwcmVmLnB1dEludCgiSW50VmFsdWUiLCAyOTk3OTI0NTgpOworICAgICAgICBwcmVmLmZsdXNoKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDI5OTc5MjQ1OCwgcHJlZi5nZXRJbnQoIkludFZhbHVlIiwgbmV3IEludGVnZXIoMSkpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXRJbnQobnVsbCwgbmV3IEludGVnZXIoMSkpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgaW50IGk7CisgICAgICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgUHJlZmVyZW5jZXMuTUFYX0tFWV9MRU5HVEggKyAxOyBpKyspIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgnYycpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0SW50KG5ldyBTdHJpbmcoc2IpLCBuZXcgSW50ZWdlcigxKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHByZWYucmVtb3ZlTm9kZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnB1dEludCgiSW50VmFsdWUiLCBuZXcgSW50ZWdlcigxKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnQoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgcHJlZi5wdXQoIlZhbHVlIiwgIlN0cmluZyIpOworICAgICAgICBwcmVmLnB1dERvdWJsZSgiRG91YmxlVmFsdWUiLCBuZXcgRG91YmxlKDkuMTA5MzgxODhlLTMxKSk7CisgICAgICAgIHByZWYucHV0TG9uZygiTG9uZ1ZhbHVlIiwgbmV3IExvbmcoTG9uZy5NSU5fVkFMVUUpKTsKKyAgICAgICAgcHJlZi5wdXRJbnQoIkludFZhbHVlIiwgMjk5NzkyNDU4KTsKKyAgICAgICAgcHJlZi5mbHVzaCgpOworCisgICAgICAgIGFzc2VydEVxdWFscygxLCBwcmVmLmdldEludCgiVmFsdWUiLCBuZXcgSW50ZWdlcigxKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgcHJlZi5nZXRJbnQoIkxvbmdWYWx1ZSIsIG5ldyBJbnRlZ2VyKDEpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBwcmVmLmdldEludCgiRG91YmxlVmFsdWUiLCBuZXcgSW50ZWdlcigxKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMjk5NzkyNDU4LCBwcmVmLmdldEludCgiSW50VmFsdWUiLCBuZXcgSW50ZWdlcigxKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLmdldEludChudWxsLCBuZXcgSW50ZWdlcigxKSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBwcmVmLnJlbW92ZU5vZGUoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5nZXRJbnQoIkludFZhbHVlIiwgbmV3IEludGVnZXIoMSkpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHV0TG9uZygpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBwcmVmLnB1dExvbmcoIkxvbmdWYWx1ZSIsIG5ldyBMb25nKDI5OTc5MjQ1OCkpOworICAgICAgICBwcmVmLmZsdXNoKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDI5OTc5MjQ1OEwsIHByZWYuZ2V0TG9uZygiTG9uZ1ZhbHVlIiwgbmV3IExvbmcoMSkpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXRMb25nKG51bGwsIG5ldyBMb25nKDEpKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGludCBpOworICAgICAgICBTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IFByZWZlcmVuY2VzLk1BWF9LRVlfTEVOR1RIICsgMTsgaSsrKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoJ2MnKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnB1dExvbmcobmV3IFN0cmluZyhzYiksIG5ldyBMb25nKDEpKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0TG9uZygiTG9uZ1ZhbHVlIiwgbmV3IExvbmcoMSkpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TG9uZygpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBwcmVmLnB1dCgiVmFsdWUiLCAiU3RyaW5nIik7CisgICAgICAgIHByZWYucHV0RG91YmxlKCJEb3VibGVWYWx1ZSIsIG5ldyBEb3VibGUoOS4xMDkzODE4OGUtMzEpKTsKKyAgICAgICAgcHJlZi5wdXRMb25nKCJMb25nVmFsdWUiLCBuZXcgTG9uZyhMb25nLk1JTl9WQUxVRSkpOworICAgICAgICBwcmVmLnB1dEludCgiSW50VmFsdWUiLCAyOTk3OTI0NTgpOworICAgICAgICBwcmVmLmZsdXNoKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDFMLCBwcmVmLmdldExvbmcoIlZhbHVlIiwgbmV3IExvbmcoMSkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExvbmcuTUlOX1ZBTFVFLCBwcmVmLmdldExvbmcoIkxvbmdWYWx1ZSIsIG5ldyBMb25nKDEpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxTCwgcHJlZi5nZXRMb25nKCJEb3VibGVWYWx1ZSIsIG5ldyBMb25nKDEpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyOTk3OTI0NThMLCBwcmVmLmdldExvbmcoIkludFZhbHVlIiwgbmV3IExvbmcoMSkpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5nZXRMb25nKG51bGwsIG5ldyBMb25nKDEpKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHByZWYucmVtb3ZlTm9kZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLmdldExvbmcoIkxvbmdWYWx1ZSIsIG5ldyBMb25nKDEpKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1dEJvb2xlYW4oKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgcHJlZi5wdXRCb29sZWFuKCJCb29sVmFsdWUiLCB0cnVlKTsKKyAgICAgICAgcHJlZi5mbHVzaCgpOworCisgICAgICAgIGFzc2VydFRydWUocHJlZi5nZXRCb29sZWFuKCJCb29sVmFsdWUiLCBmYWxzZSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnB1dEJvb2xlYW4obnVsbCwgdHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBpbnQgaTsKKyAgICAgICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOworCisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBQcmVmZXJlbmNlcy5NQVhfS0VZX0xFTkdUSCArIDE7IGkrKykgeworICAgICAgICAgICAgc2IuYXBwZW5kKCdjJyk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXRCb29sZWFuKG5ldyBTdHJpbmcoc2IpLCB0cnVlKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0Qm9vbGVhbigiRG91YmxlVmFsdWUiLCB0cnVlKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEJvb2xlYW4oKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgcHJlZi5wdXQoIlZhbHVlIiwgIlN0cmluZyIpOworICAgICAgICBwcmVmLnB1dERvdWJsZSgiRG91YmxlVmFsdWUiLCBuZXcgRG91YmxlKDkuMTA5MzgxODhlLTMxKSk7CisgICAgICAgIHByZWYucHV0Qm9vbGVhbigiQm9vbFZhbHVlIiwgdHJ1ZSk7CisgICAgICAgIHByZWYuZmx1c2goKTsKKworICAgICAgICBhc3NlcnRGYWxzZShwcmVmLmdldEJvb2xlYW4oIlZhbHVlIiwgZmFsc2UpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwcmVmLmdldEJvb2xlYW4oIkJvb2xWYWx1ZSIsIGZhbHNlKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHByZWYuZ2V0Qm9vbGVhbigiRG91YmxlVmFsdWUiLCBmYWxzZSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLmdldEJvb2xlYW4obnVsbCwgdHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBwcmVmLnJlbW92ZU5vZGUoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5nZXRCb29sZWFuKCJEb3VibGVWYWx1ZSIsIHRydWUpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHV0RmxvYXQoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgcHJlZi5wdXRGbG9hdCgiRmxvYXRWYWx1ZSIsIG5ldyBGbG9hdCgxLjYwMmUtMTkpKTsKKyAgICAgICAgcHJlZi5mbHVzaCgpOworCisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgRmxvYXQoMS42MDJlLTE5KSwgcHJlZi5nZXRGbG9hdCgiRmxvYXRWYWx1ZSIsIG5ldyBGbG9hdCgwLjIpKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0RmxvYXQobnVsbCwgbmV3IEZsb2F0KDAuMSkpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgaW50IGk7CisgICAgICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgUHJlZmVyZW5jZXMuTUFYX0tFWV9MRU5HVEggKyAxOyBpKyspIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgnYycpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0RmxvYXQobmV3IFN0cmluZyhzYiksIG5ldyBGbG9hdCgwLjEpKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0RmxvYXQoIkZsb2F0VmFsdWUiLCBuZXcgRmxvYXQoMC4xKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRGbG9hdCgpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBwcmVmLnB1dCgiVmFsdWUiLCAiU3RyaW5nIik7CisgICAgICAgIHByZWYucHV0RG91YmxlKCJEb3VibGVWYWx1ZSIsIG5ldyBEb3VibGUoOS4xMDkzODE4OGUtMzEpKTsKKyAgICAgICAgcHJlZi5wdXRGbG9hdCgiRmxvYXRWYWx1ZSIsIG5ldyBGbG9hdCgtMC4xMjMpKTsKKyAgICAgICAgcHJlZi5wdXRJbnQoIkludFZhbHVlIiwgMjk5NzkyNDU4KTsKKyAgICAgICAgcHJlZi5mbHVzaCgpOworCisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgRmxvYXQoMC4xKSwgcHJlZi5nZXRGbG9hdCgiVmFsdWUiLCBuZXcgRmxvYXQoMC4xKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IEZsb2F0KC0wLjEyMyksIHByZWYuZ2V0RmxvYXQoIkZsb2F0VmFsdWUiLCBuZXcgRmxvYXQoMC4yKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IEZsb2F0KDkuMTA5MzgyZS0zMSksIHByZWYuZ2V0RmxvYXQoIkRvdWJsZVZhbHVlIiwgbmV3IEZsb2F0KDIuMTQpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgRmxvYXQoMi45OTc5MjQ0OGU4KSwgcHJlZi5nZXRGbG9hdCgiSW50VmFsdWUiLCBuZXcgRmxvYXQoNSkpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5nZXRGbG9hdChudWxsLCBuZXcgRmxvYXQoMC4xKSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBwcmVmLnJlbW92ZU5vZGUoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5nZXRGbG9hdCgiRmxvYXRWYWx1ZSIsIG5ldyBGbG9hdCgwLjEpKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1dERvdWJsZSgpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBwcmVmLnB1dERvdWJsZSgiRG91YmxlVmFsdWUiLCBuZXcgRG91YmxlKDkuMTA5MzgxODhlLTMxKSk7CisgICAgICAgIHByZWYuZmx1c2goKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IERvdWJsZSg5LjEwOTM4MTg4ZS0zMSksIHByZWYuZ2V0RG91YmxlKCJEb3VibGVWYWx1ZSIsIG5ldyBEb3VibGUoMi4xNCkpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXREb3VibGUobnVsbCwgbmV3IERvdWJsZSgwLjEpKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGludCBpOworICAgICAgICBTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IFByZWZlcmVuY2VzLk1BWF9LRVlfTEVOR1RIICsgMTsgaSsrKSB7CisgICAgICAgICAgICBzYi5hcHBlbmQoJ2MnKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnB1dERvdWJsZShuZXcgU3RyaW5nKHNiKSwgbmV3IERvdWJsZSgwLjEpKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0RG91YmxlKCJEb3VibGVWYWx1ZSIsIG5ldyBEb3VibGUoMC4xKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXREb3VibGUoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgcHJlZi5wdXQoIlZhbHVlIiwgIlN0cmluZyIpOworICAgICAgICBwcmVmLnB1dERvdWJsZSgiRG91YmxlVmFsdWUiLCBuZXcgRG91YmxlKDkuMTA5MzgxODhlLTMxKSk7CisgICAgICAgIHByZWYucHV0Qm9vbGVhbigiQm9vbFZhbHVlIiwgdHJ1ZSk7CisgICAgICAgIHByZWYucHV0SW50KCJJbnRWYWx1ZSIsIDI5OTc5MjQ1OCk7CisgICAgICAgIHByZWYuZmx1c2goKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IERvdWJsZSgwLjEpLCBwcmVmLmdldERvdWJsZSgiVmFsdWUiLCBuZXcgRG91YmxlKDAuMSkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBEb3VibGUoMC4yKSwgcHJlZi5nZXREb3VibGUoIkJvb2xWYWx1ZSIsIG5ldyBEb3VibGUoMC4yKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IERvdWJsZSg5LjEwOTM4MTg4ZS0zMSksIHByZWYuZ2V0RG91YmxlKCJEb3VibGVWYWx1ZSIsIG5ldyBEb3VibGUoMi4xNCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBEb3VibGUoMi45OTc5MjQ1OGU4KSwgcHJlZi5nZXREb3VibGUoIkludFZhbHVlIiwgbmV3IERvdWJsZSg1KSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLmdldERvdWJsZShudWxsLCBuZXcgRG91YmxlKDAuMSkpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYuZ2V0RG91YmxlKCJEb3VibGVWYWx1ZSIsIG5ldyBEb3VibGUoMC4xKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQdXRCeXRlQXJyYXkoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJBcnJheSA9IG5ldyBieXRlW117MSwgMiwgMywgNCwgNX07CisgICAgICAgIGJ5dGVbXSBhcnJheSAgPSBudWxsOworICAgICAgICBpbnQgaTsKKyAgICAgICAgcHJlZi5wdXRCeXRlQXJyYXkoIkFycmF5IiwgYkFycmF5KTsKKyAgICAgICAgcHJlZi5mbHVzaCgpOworCisgICAgICAgIGFycmF5ID0gcHJlZi5nZXRCeXRlQXJyYXkoIkFycmF5IiwgbnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhiQXJyYXkubGVuZ3RoLCBhcnJheS5sZW5ndGgpOworICAgICAgICBmb3IoaSA9IDA7IGkgPCBiQXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhiQXJyYXlbaV0sIGFycmF5W2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnB1dEJ5dGVBcnJheShudWxsLCBiQXJyYXkpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOworCisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBQcmVmZXJlbmNlcy5NQVhfS0VZX0xFTkdUSCArIDE7IGkrKykgeworICAgICAgICAgICAgc2IuYXBwZW5kKCdjJyk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXRCeXRlQXJyYXkobmV3IFN0cmluZyhzYiksIGJBcnJheSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGJBcnJheSA9IG5ldyBieXRlW1ByZWZlcmVuY2VzLk1BWF9WQUxVRV9MRU5HVEggKiAzIC8gNCArIDFdOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnB1dEJ5dGVBcnJheSgiQmlnIGFycmF5IiwgYkFycmF5KTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0Qnl0ZUFycmF5KCJBcnJheSIsIG5ldyBieXRlWzEwXSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRCeXRlQXJyYXkoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJBcnJheSA9IG5ldyBieXRlW117MSwgMiwgMywgNCwgNX07CisgICAgICAgIGJ5dGVbXSB0bXAgICAgPSBuZXcgYnl0ZVtdezV9OworICAgICAgICBieXRlW10gYXJyYXkgID0gbnVsbDsKKyAgICAgICAgaW50IGk7CisgICAgICAgIHByZWYucHV0KCJWYWx1ZSIsICJTdHJpbmciKTsKKyAgICAgICAgcHJlZi5wdXREb3VibGUoIkRvdWJsZVZhbHVlIiwgbmV3IERvdWJsZSg5LjEwOTM4MTg4ZS0zMSkpOworICAgICAgICBwcmVmLnB1dEJ5dGVBcnJheSgiQXJyYXkiLCBiQXJyYXkpOworICAgICAgICBwcmVmLmZsdXNoKCk7CisKKyAgICAgICAgYXJyYXkgPSBwcmVmLmdldEJ5dGVBcnJheSgiVmFsdWUiLCB0bXApOworICAgICAgICBhc3NlcnRFcXVhbHModG1wLmxlbmd0aCwgYXJyYXkubGVuZ3RoKTsKKyAgICAgICAgZm9yKGkgPSAwOyBpIDwgdG1wLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModG1wW2ldLCBhcnJheVtpXSk7CisgICAgICAgIH0KKworICAgICAgICBhcnJheSA9IHByZWYuZ2V0Qnl0ZUFycmF5KCJEb3VibGVWYWx1ZSIsIHRtcCk7CisgICAgICAgIGFzc2VydEVxdWFscyh0bXAubGVuZ3RoLCBhcnJheS5sZW5ndGgpOworICAgICAgICBmb3IoaSA9IDA7IGkgPCB0bXAubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0bXBbaV0sIGFycmF5W2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIGFycmF5ID0gcHJlZi5nZXRCeXRlQXJyYXkoIkFycmF5IiwgdG1wKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJBcnJheS5sZW5ndGgsIGFycmF5Lmxlbmd0aCk7CisgICAgICAgIGZvcihpID0gMDsgaSA8IGJBcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGJBcnJheVtpXSwgYXJyYXlbaV0pOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYuZ2V0Qnl0ZUFycmF5KG51bGwsIHRtcCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBwcmVmLnJlbW92ZU5vZGUoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5nZXRCeXRlQXJyYXkoIkFycmF5IiwgdG1wKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEtleXMoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nW10ga2V5QXJyYXkgPSBuZXcgU3RyaW5nW117IlZhbHVlIiwgIkRvdWJsZVZhbHVlIiwgIkJvb2xWYWx1ZSIsICJJbnRWYWx1ZSJ9OworICAgICAgICBTdHJpbmcgbm9kZVN0ciA9ICJOZXcgbm9kZSI7CisgICAgICAgIHByZWYubm9kZShub2RlU3RyKTsKKyAgICAgICAgcHJlZi5wdXQoa2V5QXJyYXlbMF0sICJTdHJpbmciKTsKKyAgICAgICAgcHJlZi5wdXREb3VibGUoa2V5QXJyYXlbMV0sIG5ldyBEb3VibGUoOS4xMDkzODE4OGUtMzEpKTsKKyAgICAgICAgcHJlZi5wdXRCb29sZWFuKGtleUFycmF5WzJdLCB0cnVlKTsKKyAgICAgICAgcHJlZi5wdXRJbnQoa2V5QXJyYXlbM10sIDI5OTc5MjQ1OCk7CisgICAgICAgIHByZWYuZmx1c2goKTsKKworICAgICAgICBTdHJpbmdbXSBzdHIgPSBwcmVmLmtleXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGtleUFycmF5Lmxlbmd0aCwgc3RyLmxlbmd0aCk7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGJvb2xlYW4gZmxhZyA9IGZhbHNlOworICAgICAgICAgICAgZm9yKGludCBqID0gMDsgaiA8IGtleUFycmF5Lmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgaWYgKHN0cltpXS5jb21wYXJlVG8oa2V5QXJyYXlbal0pID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgZmxhZyA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoc3RyW2ldLmNvbXBhcmVUbyhub2RlU3RyKSAhPSAwKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZmxhZyk7CisgICAgICAgIH0KKworICAgICAgICBwcmVmLnJlbW92ZU5vZGUoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5rZXlzKCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENoaWxkcmVuTmFtZXMoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgQWJzdHJhY3RQcmVmZXJlbmNlcyBmaXJzdCA9IChBYnN0cmFjdFByZWZlcmVuY2VzKSBwcmVmLm5vZGUoIkZpcnN0IG5vZGUiKTsKKyAgICAgICAgQWJzdHJhY3RQcmVmZXJlbmNlcyBzZWNvbmQgPSAoQWJzdHJhY3RQcmVmZXJlbmNlcykgcHJlZi5ub2RlKCJTZWNvbmQgbm9kZSIpOworCisgICAgICAgIGFzc2VydEVxdWFscygyLCBwcmVmLmNoaWxkcmVuTmFtZXMoKS5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZmlyc3QuY2hpbGRyZW5OYW1lcygpLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBzZWNvbmQuY2hpbGRyZW5OYW1lcygpLmxlbmd0aCk7CisKKyAgICAgICAgc2Vjb25kLnJlbW92ZU5vZGUoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2Vjb25kLmNoaWxkcmVuTmFtZXMoKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpcnN0LmNoaWxkcmVuTmFtZXMoKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9ub2RlRXhpc3RzKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIEFic3RyYWN0UHJlZmVyZW5jZXMgdGVzdCA9IChBYnN0cmFjdFByZWZlcmVuY2VzKSBQcmVmZXJlbmNlcy51c2VyUm9vdCgpCisgICAgICAgICAgICAgICAgLm5vZGUoInRlc3QiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRlc3Qubm9kZUV4aXN0cyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdGVzdC5yZW1vdmVOb2RlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0Lm5vZGVFeGlzdHMobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJlbnQoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgQWJzdHJhY3RQcmVmZXJlbmNlcyBub2RlID0gKEFic3RyYWN0UHJlZmVyZW5jZXMpIHByZWYubm9kZSgiRmlyc3Qgbm9kZS9zdWIgbm9kZSIpOworCisgICAgICAgIGFzc2VydFRydWUobm9kZS5wYXJlbnQoKS5uYW1lKCkuY29tcGFyZVRvKCJGaXJzdCBub2RlIikgPT0gMCk7CisKKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5vZGUucGFyZW50KCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROb2RlKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIEFic3RyYWN0UHJlZmVyZW5jZXMgZmlyc3QgPSAoQWJzdHJhY3RQcmVmZXJlbmNlcykgcHJlZi5ub2RlKCJGaXJzdCBub2RlIik7CisgICAgICAgIEFic3RyYWN0UHJlZmVyZW5jZXMgc2Vjb25kID0gKEFic3RyYWN0UHJlZmVyZW5jZXMpIHByZWYubm9kZSgiU2Vjb25kIG5vZGUiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmlyc3Qubm9kZSgiYmxhYmxhLyIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmlyc3Qubm9kZSgiLy8vaW52YWxpZCIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBQcmVmZXJlbmNlcy5NQVhfTkFNRV9MRU5HVEg7IGkrKykgeworICAgICAgICAgICAgc2IuYXBwZW5kKCdjJyk7CisgICAgICAgIH0KKyAgICAgICAgZmlyc3Qubm9kZShuZXcgU3RyaW5nKHNiKSk7CisgICAgICAgIHNiLmFwcGVuZCgnYycpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaXJzdC5ub2RlKG5ldyBTdHJpbmcoc2IpKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgc2Vjb25kLnJlbW92ZU5vZGUoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2Vjb25kLm5vZGUoIiIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaXJzdC5ub2RlKCIiKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vZGVFeGlzdHMoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgQWJzdHJhY3RQcmVmZXJlbmNlcyBhcDEgPSAoQWJzdHJhY3RQcmVmZXJlbmNlcykgcHJlZi5ub2RlKCJGaXJzdCBub2RlIik7CisgICAgICAgIEFic3RyYWN0UHJlZmVyZW5jZXMgYXAyID0gKEFic3RyYWN0UHJlZmVyZW5jZXMpIHByZWYubm9kZSgiU2Vjb25kIG5vZGUiKTsKKyAgICAgICAgcHJlZi5wdXRJbnQoIkludGVnZXJWYWx1ZSIsIDMzKTsKKyAgICAgICAgcHJlZi5wdXRCb29sZWFuKCJCb29sVmFsdWUiLCB0cnVlKTsKKyAgICAgICAgcHJlZi5mbHVzaCgpOworCisgICAgICAgIGFzc2VydFRydWUocHJlZi5ub2RlRXhpc3RzKCJGaXJzdCBub2RlIikpOworICAgICAgICBhc3NlcnRUcnVlKHByZWYubm9kZUV4aXN0cygiU2Vjb25kIG5vZGUiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHByZWYubm9kZUV4aXN0cygiSW50ZWdlclZhbHVlIikpOworICAgICAgICBhc3NlcnRGYWxzZShwcmVmLm5vZGVFeGlzdHMoIkJvb2xWYWx1ZSIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocHJlZi5ub2RlRXhpc3RzKCJWYWx1ZSIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocHJlZi5ub2RlRXhpc3RzKG5vZGVOYW1lKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYubm9kZUV4aXN0cygiLy8vaW52YWxpZCIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBwcmVmLnJlbW92ZU5vZGUoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5ub2RlRXhpc3RzKCJFeGNlcHRpb24iKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZU5vZGUoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nW10gbm9kZUFycmF5ID0gbmV3IFN0cmluZ1tdeyJGaXJzdCBub2RlIiwgIlNlY29uZCBub2RlIiwgIkxhc3Qgbm9kZSJ9OworICAgICAgICBpbnQgaTsKKyAgICAgICAgcHJlZi5wdXQoIktleSIsICJTdHJpbmciKTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IG5vZGVBcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgcHJlZi5ub2RlKG5vZGVBcnJheVtpXSk7CisgICAgICAgIH0KKyAgICAgICAgcHJlZi5mbHVzaCgpOworCisgICAgICAgIFN0cmluZ1tdIHN0ciA9IHByZWYuY2hpbGRyZW5OYW1lcygpOworICAgICAgICBhc3NlcnRFcXVhbHMobm9kZUFycmF5Lmxlbmd0aCwgc3RyLmxlbmd0aCk7CisgICAgICAgIGZvcihpID0gMDsgaSA8IG5vZGVBcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgcHJlZi5ub2RlKG5vZGVBcnJheVtpXSkucmVtb3ZlTm9kZSgpOworICAgICAgICAgICAgc3RyID0gcHJlZi5jaGlsZHJlbk5hbWVzKCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobm9kZUFycmF5Lmxlbmd0aCAtIGkgLSAxLCBzdHIubGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoMSwgcHJlZi5rZXlzKCkubGVuZ3RoKTsKKyAgICAgICAgcHJlZi5ub2RlKCJLZXkiKS5yZW1vdmVOb2RlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBwcmVmLmtleXMoKS5sZW5ndGgpOworCisgICAgICAgIHByZWYucmVtb3ZlTm9kZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnJlbW92ZU5vZGUoKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJvb3QucmVtb3ZlTm9kZSgpOworICAgICAgICAgICAgZmFpbCgiVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5hbWUoKSB7CisgICAgICAgIEFic3RyYWN0UHJlZmVyZW5jZXMgZmlyc3QgPSAoQWJzdHJhY3RQcmVmZXJlbmNlcykgcHJlZi5ub2RlKCJGaXJzdCBub2RlIik7CisgICAgICAgIEFic3RyYWN0UHJlZmVyZW5jZXMgc2Vjb25kID0gKEFic3RyYWN0UHJlZmVyZW5jZXMpIHByZWYubm9kZSgiU2Vjb25kIG5vZGUvc3ViIG5vZGUiKTsKKworICAgICAgICBhc3NlcnRUcnVlKGZpcnN0Lm5hbWUoKS5jb21wYXJlVG8oIkZpcnN0IG5vZGUiKSA9PSAwKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZmlyc3QubmFtZSgpLmNvbXBhcmVUbygiU2Vjb25kIG5vZGUiKSA9PSAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzZWNvbmQubmFtZSgpLmNvbXBhcmVUbygic3ViIG5vZGUiKSA9PSAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWJzb2x1dGVQYXRoKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMocGFyZW50LmFic29sdXRlUGF0aCgpICsgIi8iICsgbm9kZU5hbWUsIHByZWYuYWJzb2x1dGVQYXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMocGFyZW50LmFic29sdXRlUGF0aCgpICsgIi8iICsgIm5ldyBub2RlIiwgcGFyZW50Lm5vZGUoIm5ldyBub2RlIikuYWJzb2x1dGVQYXRoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJc1VzZXJOb2RlKCkgeworICAgICAgICBhc3NlcnRUcnVlKHBhcmVudC5pc1VzZXJOb2RlKCkpOworICAgICAgICBhc3NlcnRGYWxzZShQcmVmZXJlbmNlcy5zeXN0ZW1Sb290KCkuaXNVc2VyTm9kZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3luYygpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBwcmVmLm5vZGUoIm5ldyBub2RlL3N1YiBub2RlIik7CisgICAgICAgIHByZWYuc3luYygpOworCisgICAgICAgIHByZWYucmVtb3ZlTm9kZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnN5bmMoKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgTW9ja1ByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lciBpbXBsZW1lbnRzIFByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lciB7CisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBmbGFnQ2hhbmdlID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHByZWZlcmVuY2VDaGFuZ2UoUHJlZmVyZW5jZUNoYW5nZUV2ZW50IGFyZzApIHsKKyAgICAgICAgICAgIGZsYWdDaGFuZ2UgPSB0cnVlOworICAgICAgICAgICAgbm90aWZ5QWxsKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYXNzZXJ0Q2hhbmdlZChib29sZWFuIGV4cGVjdGVkKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICAgICAgd2FpdCgxMDApOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBmbGFnQ2hhbmdlKTsKKyAgICAgICAgICAgIGZsYWdDaGFuZ2UgPSBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja1ByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lciBtcGNsID0gbmV3IE1vY2tQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIoKTsKKyAgICAgICAgcGFyZW50LmFkZFByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcihtcGNsKTsKKyAgICAgICAgbXBjbC5hc3NlcnRDaGFuZ2VkKGZhbHNlKTsKKyAgICAgICAgcHJlZi5ub2RlKCJuZXcgbm9kZSIpOworICAgICAgICBtcGNsLmFzc2VydENoYW5nZWQoZmFsc2UpOworICAgICAgICBwYXJlbnQubm9kZSgibmV3IG5vZGUiKTsKKyAgICAgICAgbXBjbC5hc3NlcnRDaGFuZ2VkKGZhbHNlKTsKKyAgICAgICAgcGFyZW50LnB1dEludCgiSW50VmFsdWUiLCAzMyk7CisgICAgICAgIG1wY2wuYXNzZXJ0Q2hhbmdlZCh0cnVlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMzLCBwYXJlbnQuZ2V0SW50KCJJbnRWYWx1ZSIsIDIyKSk7CisgICAgICAgIG1wY2wuYXNzZXJ0Q2hhbmdlZChmYWxzZSk7CisgICAgICAgIGFzc2VydEVxdWFscygyMiwgcGFyZW50LmdldEludCgiTWlzc2VkIFZhbHVlIiwgMjIpKTsKKyAgICAgICAgbXBjbC5hc3NlcnRDaGFuZ2VkKGZhbHNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1vY2tQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIgbXBjbCA9IG5ldyBNb2NrUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyKCk7CisgICAgICAgIHBhcmVudC5hZGRQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIobXBjbCk7CisgICAgICAgIG1wY2wuYXNzZXJ0Q2hhbmdlZChmYWxzZSk7CisgICAgICAgIHBhcmVudC5wdXRJbnQoIkludFZhbHVlIiwgMzMpOworICAgICAgICBtcGNsLmFzc2VydENoYW5nZWQodHJ1ZSk7CisgICAgICAgIHBhcmVudC5yZW1vdmVQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIobXBjbCk7CisgICAgICAgIHBhcmVudC5wdXRJbnQoIkludFZhbHVlIiwgMzMpOworICAgICAgICBtcGNsLmFzc2VydENoYW5nZWQoZmFsc2UpOworICAgIH0KKworICAgIGNsYXNzIE1vY2tOb2RlQ2hhbmdlTGlzdGVuZXIgaW1wbGVtZW50cyBOb2RlQ2hhbmdlTGlzdGVuZXIgeworICAgICAgICBwcml2YXRlIGJvb2xlYW4gZmxhZ0FkZGVkID0gZmFsc2U7CisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBmbGFnUmVtb3ZlZCA9IGZhbHNlOworCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjaGlsZEFkZGVkKE5vZGVDaGFuZ2VFdmVudCBhcmcwKSB7CisgICAgICAgICAgICBmbGFnQWRkZWQgPSB0cnVlOworICAgICAgICAgICAgbm90aWZ5QWxsKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2hpbGRSZW1vdmVkKE5vZGVDaGFuZ2VFdmVudCBhcmcwKSB7CisgICAgICAgICAgICBmbGFnUmVtb3ZlZCA9IHRydWU7CisgICAgICAgICAgICBub3RpZnlBbGwoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhc3NlcnRBZGRlZChib29sZWFuIGV4cGVjdGVkKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICAgICAgd2FpdCgxMDApOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBmbGFnQWRkZWQpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFzc2VydFJlbW92ZWQoYm9vbGVhbiBleHBlY3RlZCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHdhaXQoMTAwKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwgZmxhZ1JlbW92ZWQpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFkZE5vZGVDaGFuZ2VMaXN0ZW5lcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNb2NrTm9kZUNoYW5nZUxpc3RlbmVyIG1uY2wgPSBuZXcgTW9ja05vZGVDaGFuZ2VMaXN0ZW5lcigpOworICAgICAgICBwYXJlbnQuYWRkTm9kZUNoYW5nZUxpc3RlbmVyKG1uY2wpOworICAgICAgICBwcmVmLm5vZGUoInRlc3QiKTsKKyAgICAgICAgbW5jbC5hc3NlcnRBZGRlZChmYWxzZSk7CisgICAgICAgIG1uY2wuYXNzZXJ0UmVtb3ZlZChmYWxzZSk7CisgICAgICAgIHByZWYucmVtb3ZlTm9kZSgpOworICAgICAgICBtbmNsLmFzc2VydEFkZGVkKGZhbHNlKTsKKyAgICAgICAgbW5jbC5hc3NlcnRSZW1vdmVkKHRydWUpOworICAgICAgICBwYXJlbnQubm9kZSgibmV3IG5vZGUiKTsKKyAgICAgICAgbW5jbC5hc3NlcnRBZGRlZCh0cnVlKTsKKyAgICAgICAgbW5jbC5hc3NlcnRSZW1vdmVkKHRydWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVOb2RlQ2hhbmdlTGlzdGVuZXIoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIE1vY2tOb2RlQ2hhbmdlTGlzdGVuZXIgbW5jbCA9IG5ldyBNb2NrTm9kZUNoYW5nZUxpc3RlbmVyKCk7CisgICAgICAgIHBhcmVudC5hZGROb2RlQ2hhbmdlTGlzdGVuZXIobW5jbCk7CisgICAgICAgIHByZWYubm9kZSgidGVzdCIpOworICAgICAgICBtbmNsLmFzc2VydEFkZGVkKGZhbHNlKTsKKyAgICAgICAgbW5jbC5hc3NlcnRSZW1vdmVkKGZhbHNlKTsKKyAgICAgICAgcGFyZW50LnJlbW92ZU5vZGVDaGFuZ2VMaXN0ZW5lcihtbmNsKTsKKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlKCk7CisgICAgICAgIG1uY2wuYXNzZXJ0QWRkZWQoZmFsc2UpOworICAgICAgICBtbmNsLmFzc2VydFJlbW92ZWQoZmFsc2UpOworICAgICAgICBwYXJlbnQubm9kZSgibmV3IG5vZGUiKTsKKyAgICAgICAgbW5jbC5hc3NlcnRBZGRlZChmYWxzZSk7CisgICAgICAgIG1uY2wuYXNzZXJ0UmVtb3ZlZChmYWxzZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEV4cG9ydE5vZGUoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgSW52YWxpZFByZWZlcmVuY2VzRm9ybWF0RXhjZXB0aW9uIHsKKyAgICAgICAgQWJzdHJhY3RQcmVmZXJlbmNlcyBhcCA9IChBYnN0cmFjdFByZWZlcmVuY2VzKSBwcmVmLm5vZGUoIk5ldyBub2RlIik7CisgICAgICAgIHByZWYucHV0SW50KCJJbnRWYWx1ZSIsIDMzKTsKKyAgICAgICAgcHJlZi5wdXRCb29sZWFuKCJCb29sVmFsdWUiLCB0cnVlKTsKKyAgICAgICAgcHJlZi5mbHVzaCgpOworCisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCisgICAgICAgIHByZWYuZXhwb3J0Tm9kZShiYW9zKTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYW9zLnRvQnl0ZUFycmF5KCkpOworCisgICAgICAgIGFzc2VydFRydWUocHJlZi5nZXRCb29sZWFuKCJCb29sVmFsdWUiLCBmYWxzZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMzMsIHByZWYuZ2V0SW50KCJJbnRWYWx1ZSIsIDIyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBwcmVmLmNoaWxkcmVuTmFtZXMoKS5sZW5ndGgpOworCisgICAgICAgIFN0cmluZyB4bWxEYXRhID0gbmV3IFN0cmluZyhiYW9zLnRvQnl0ZUFycmF5KCkpOworCisgICAgICAgIGFzc2VydFRydWUoeG1sRGF0YS5jb250YWlucygiSW50VmFsdWUiKSk7CisgICAgICAgIGFzc2VydFRydWUoeG1sRGF0YS5jb250YWlucygiQm9vbFZhbHVlIikpOworICAgICAgICBhc3NlcnRUcnVlKHhtbERhdGEuY29udGFpbnMoIjMzIikpOworICAgICAgICBhc3NlcnRUcnVlKHhtbERhdGEuY29udGFpbnMoInRydWUiKSk7CisKKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYuZXhwb3J0Tm9kZShuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCkpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5nZXRCb29sZWFuKCJCb29sVmFsdWUiLCBmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBwcmVmID0gKEFic3RyYWN0UHJlZmVyZW5jZXMpIHBhcmVudC5ub2RlKG5vZGVOYW1lKTsKKworICAgICAgICBwcmVmLmltcG9ydFByZWZlcmVuY2VzKGJhaXMpOworCisgICAgICAgIGFzc2VydFRydWUocHJlZi5nZXRCb29sZWFuKCJCb29sVmFsdWUiLCBmYWxzZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMzMsIHByZWYuZ2V0SW50KCJJbnRWYWx1ZSIsIDIyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBwcmVmLmNoaWxkcmVuTmFtZXMoKS5sZW5ndGgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFeHBvcnRTdWJ0cmVlKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIEludmFsaWRQcmVmZXJlbmNlc0Zvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIEFic3RyYWN0UHJlZmVyZW5jZXMgYXAxID0gKEFic3RyYWN0UHJlZmVyZW5jZXMpIHByZWYubm9kZSgiRmlyc3Qgbm9kZSIpOworICAgICAgICBBYnN0cmFjdFByZWZlcmVuY2VzIGFwMiA9IChBYnN0cmFjdFByZWZlcmVuY2VzKSBwcmVmLm5vZGUoIlNlY29uZCBub2RlIik7CisgICAgICAgIHByZWYucHV0SW50KCJJbnRlZ2VyVmFsdWUiLCAzMyk7CisgICAgICAgIHByZWYucHV0Qm9vbGVhbigiQm9vbFZhbHVlIiwgdHJ1ZSk7CisgICAgICAgIHByZWYuZmx1c2goKTsKKworICAgICAgICBhcDEucHV0SW50KCJGaXJzdEludFZhbHVlIiwgMTEpOworICAgICAgICBhcDIucHV0RG91YmxlKCJEb3VibGVWYWx1ZSIsIG5ldyBEb3VibGUoNi42MjZlLTM0KSk7CisKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisKKyAgICAgICAgcHJlZi5leHBvcnRTdWJ0cmVlKGJhb3MpOworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiYWlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhb3MudG9CeXRlQXJyYXkoKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShwcmVmLmdldEJvb2xlYW4oIkJvb2xWYWx1ZSIsIGZhbHNlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzMywgcHJlZi5nZXRJbnQoIkludGVnZXJWYWx1ZSIsIDIyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBwcmVmLmNoaWxkcmVuTmFtZXMoKS5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTEsIGFwMS5nZXRJbnQoIkZpcnN0SW50VmFsdWUiLCAyMikpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IERvdWJsZSg2LjYyNmUtMzQpLCBhcDIuZ2V0RG91YmxlKCJEb3VibGVWYWx1ZSIsIG5ldyBEb3VibGUgKDMuMTQpKSk7CisKKyAgICAgICAgU3RyaW5nIHhtbERhdGEgPSBuZXcgU3RyaW5nKGJhb3MudG9CeXRlQXJyYXkoKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSh4bWxEYXRhLmNvbnRhaW5zKCJJbnRlZ2VyVmFsdWUiKSk7CisgICAgICAgIGFzc2VydFRydWUoeG1sRGF0YS5jb250YWlucygiQm9vbFZhbHVlIikpOworICAgICAgICBhc3NlcnRUcnVlKHhtbERhdGEuY29udGFpbnMoIkZpcnN0SW50VmFsdWUiKSk7CisgICAgICAgIGFzc2VydFRydWUoeG1sRGF0YS5jb250YWlucygiRG91YmxlVmFsdWUiKSk7CisgICAgICAgIGFzc2VydFRydWUoeG1sRGF0YS5jb250YWlucygiMzMiKSk7CisgICAgICAgIGFzc2VydFRydWUoeG1sRGF0YS5jb250YWlucygidHJ1ZSIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh4bWxEYXRhLmNvbnRhaW5zKCIxMSIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh4bWxEYXRhLmNvbnRhaW5zKCI2LjYyNkUtMzQiKSk7CisKKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYuZXhwb3J0U3VidHJlZShuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCkpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5nZXRCb29sZWFuKCJCb29sVmFsdWUiLCBmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBwcmVmID0gKEFic3RyYWN0UHJlZmVyZW5jZXMpIHBhcmVudC5ub2RlKG5vZGVOYW1lKTsKKyAgICAgICAgcHJlZi5pbXBvcnRQcmVmZXJlbmNlcyhiYWlzKTsKKworICAgICAgICBhcDEgPSAoQWJzdHJhY3RQcmVmZXJlbmNlcykgcHJlZi5ub2RlKCJGaXJzdCBub2RlIik7CisgICAgICAgIGFwMiA9IChBYnN0cmFjdFByZWZlcmVuY2VzKSBwcmVmLm5vZGUoIlNlY29uZCBub2RlIik7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShwcmVmLmdldEJvb2xlYW4oIkJvb2xWYWx1ZSIsIGZhbHNlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzMywgcHJlZi5nZXRJbnQoIkludGVnZXJWYWx1ZSIsIDIyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBwcmVmLmNoaWxkcmVuTmFtZXMoKS5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTEsIGFwMS5nZXRJbnQoIkZpcnN0SW50VmFsdWUiLCAyMikpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IERvdWJsZSg2LjYyNmUtMzQpLCBhcDIuZ2V0RG91YmxlKCJEb3VibGVWYWx1ZSIsIG5ldyBEb3VibGUgKDMuMTQpKSk7CisgICAgfQorCisgICAgY2xhc3MgTW9ja0Fic3RyYWN0UHJlZmVyZW5jZXMgZXh0ZW5kcyBBYnN0cmFjdFByZWZlcmVuY2VzIHsKKyAgICAgICAgcHJvdGVjdGVkIE1vY2tBYnN0cmFjdFByZWZlcmVuY2VzKEFic3RyYWN0UHJlZmVyZW5jZXMgcGFyZW50LCBTdHJpbmcgbmFtZSkgeworICAgICAgICAgICAgc3VwZXIocGFyZW50LCBuYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgQWJzdHJhY3RQcmVmZXJlbmNlcyBjaGlsZFNwaShTdHJpbmcgbmFtZSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIFN0cmluZ1tdIGNoaWxkcmVuTmFtZXNTcGkoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGZsdXNoU3BpKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIFN0cmluZyBnZXRTcGkoU3RyaW5nIGtleSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIFN0cmluZ1tdIGtleXNTcGkoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIHB1dFNwaShTdHJpbmcga2V5LCBTdHJpbmcgdmFsdWUpIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZW1vdmVOb2RlU3BpKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgcmVtb3ZlU3BpKFN0cmluZyBrZXkpIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBzeW5jU3BpKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWJzdHJhY3RQcmVmZXJlbmNlcygpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXcgTW9ja0Fic3RyYWN0UHJlZmVyZW5jZXMocHJlZiwgIm5vZGUgbmFtZSIpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBNb2NrQWJzdHJhY3RQcmVmZXJlbmNlcyhwcmVmLCAibm9kZS9uYW1lIik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgTW9ja0Fic3RyYWN0UHJlZmVyZW5jZXMobnVsbCwgIm5vZGUiKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENhY2hlZENoaWxkcmVuKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIHByZWYubm9kZSgiRmlyc3Qgbm9kZSIpOworICAgICAgICBwcmVmLm5vZGUoIlNlY29uZCBub2RlIik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHByZWYuY2hpbGRyZW5OYW1lcygpLmxlbmd0aCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ByZWZzL09sZEZpbGVQcmVmZXJlbmNlc0ltcGxUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvcHJlZnMvT2xkRmlsZVByZWZlcmVuY2VzSW1wbFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45M2JhNDg1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ByZWZzL09sZEZpbGVQcmVmZXJlbmNlc0ltcGxUZXN0LmphdmEKQEAgLTAsMCArMSw3MyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC5wcmVmczsKKworaW1wb3J0IGphdmEudXRpbC5wcmVmcy5QcmVmZXJlbmNlczsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBPbGRGaWxlUHJlZmVyZW5jZXNJbXBsVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8vIEFuZHJvaWRPbmx5OiB0aGUgUkkgY2FuJ3QgcmVtb3ZlIG5vZGVzIGNyZWF0ZWQgaW4gdGhlIHN5c3RlbSByb290LgorICAgIHB1YmxpYyB2b2lkIHRlc3RTeXN0ZW1DaGlsZE5vZGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFByZWZlcmVuY2VzIHNyb290ID0gUHJlZmVyZW5jZXMuc3lzdGVtUm9vdCgpLm5vZGUoInRlc3QiKTsKKworICAgICAgICBQcmVmZXJlbmNlcyBjaGlsZDEgPSBzcm9vdC5ub2RlKCJjaGlsZDEiKTsKKyAgICAgICAgUHJlZmVyZW5jZXMgY2hpbGQyID0gc3Jvb3Qubm9kZSgiY2hpbGQyIik7CisgICAgICAgIFByZWZlcmVuY2VzIGdyYW5kY2hpbGQgPSBjaGlsZDEubm9kZSgiZ3JhbmQiKTsKKworICAgICAgICBTdHJpbmdbXSBjaGlsZE5hbWVzID0gc3Jvb3QuY2hpbGRyZW5OYW1lcygpOworICAgICAgICBhc3NlcnRDb250YWlucyhjaGlsZE5hbWVzLCAiY2hpbGQxIik7CisgICAgICAgIGFzc2VydENvbnRhaW5zKGNoaWxkTmFtZXMsICJjaGlsZDIiKTsKKyAgICAgICAgYXNzZXJ0Tm90Q29udGFpbnMoY2hpbGROYW1lcywgImdyYW5kIik7CisKKyAgICAgICAgY2hpbGROYW1lcyA9IGNoaWxkMS5jaGlsZHJlbk5hbWVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBjaGlsZE5hbWVzLmxlbmd0aCk7CisKKyAgICAgICAgY2hpbGROYW1lcyA9IGNoaWxkMi5jaGlsZHJlbk5hbWVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBjaGlsZE5hbWVzLmxlbmd0aCk7CisKKyAgICAgICAgY2hpbGQxLnJlbW92ZU5vZGUoKTsKKyAgICAgICAgY2hpbGROYW1lcyA9IHNyb290LmNoaWxkcmVuTmFtZXMoKTsKKyAgICAgICAgYXNzZXJ0Tm90Q29udGFpbnMoY2hpbGROYW1lcywgImNoaWxkMSIpOworICAgICAgICBhc3NlcnRDb250YWlucyhjaGlsZE5hbWVzLCAiY2hpbGQyIik7CisgICAgICAgIGFzc2VydE5vdENvbnRhaW5zKGNoaWxkTmFtZXMsICJncmFuZCIpOworCisgICAgICAgIGNoaWxkMi5yZW1vdmVOb2RlKCk7CisgICAgICAgIGNoaWxkTmFtZXMgPSBzcm9vdC5jaGlsZHJlbk5hbWVzKCk7CisgICAgICAgIGFzc2VydE5vdENvbnRhaW5zKGNoaWxkTmFtZXMsICJjaGlsZDEiKTsKKyAgICAgICAgYXNzZXJ0Tm90Q29udGFpbnMoY2hpbGROYW1lcywgImNoaWxkMiIpOworICAgICAgICBhc3NlcnROb3RDb250YWlucyhjaGlsZE5hbWVzLCAiZ3JhbmQiKTsKKyAgICAgICAgc3Jvb3QucmVtb3ZlTm9kZSgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRDb250YWlucyhTdHJpbmdbXSBjaGlsZE5hbWVzLCBTdHJpbmcgbmFtZSkgeworICAgICAgICBmb3IgKFN0cmluZyBjaGlsZE5hbWUgOiBjaGlsZE5hbWVzKSB7CisgICAgICAgICAgICBpZiAoY2hpbGROYW1lID09IG5hbWUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZmFpbCgiTm8gY2hpbGQgd2l0aCBuYW1lICIgKyBuYW1lICsgIiB3YXMgZm91bmQuIEl0IHdhcyBleHBlY3RlZCB0byBleGlzdC4iKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0Tm90Q29udGFpbnMoU3RyaW5nW10gY2hpbGROYW1lcywgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgZm9yIChTdHJpbmcgY2hpbGROYW1lIDogY2hpbGROYW1lcykgeworICAgICAgICAgICAgaWYgKGNoaWxkTmFtZSA9PSBuYW1lKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiQ2hpbGQgd2l0aCBuYW1lICIgKyBuYW1lICsgIiB3YXMgZm91bmQuIFRoaXMgd2FzIHVuZXhwZWN0ZWQuIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvcHJlZnMvT2xkTm9kZUNoYW5nZUV2ZW50VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ByZWZzL09sZE5vZGVDaGFuZ2VFdmVudFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMmQ0ODNlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ByZWZzL09sZE5vZGVDaGFuZ2VFdmVudFRlc3QuamF2YQpAQCAtMCwwICsxLDE2OCBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC5wcmVmczsKKworaW1wb3J0IGphdmEudXRpbC5wcmVmcy5BYnN0cmFjdFByZWZlcmVuY2VzOworaW1wb3J0IGphdmEudXRpbC5wcmVmcy5CYWNraW5nU3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLnByZWZzLk5vZGVDaGFuZ2VFdmVudDsKK2ltcG9ydCBqYXZhLnV0aWwucHJlZnMuTm9kZUNoYW5nZUxpc3RlbmVyOworaW1wb3J0IGphdmEudXRpbC5wcmVmcy5QcmVmZXJlbmNlczsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBPbGROb2RlQ2hhbmdlRXZlbnRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdEdldENoaWxkKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIEFic3RyYWN0UHJlZmVyZW5jZXMgcGFyZW50ID0gKEFic3RyYWN0UHJlZmVyZW5jZXMpIFByZWZlcmVuY2VzCisgICAgICAgICAgICAgICAgLnVzZXJOb2RlRm9yUGFja2FnZShQcmVmZXJlbmNlcy5jbGFzcyk7CisKKyAgICAgICAgQWJzdHJhY3RQcmVmZXJlbmNlcyBwcmVmID0gKEFic3RyYWN0UHJlZmVyZW5jZXMpIHBhcmVudC5ub2RlKCJtb2NrIik7CisKKyAgICAgICAgTW9ja05vZGVDaGFuZ2VMaXN0ZW5lciBubCA9IG5ldyBNb2NrTm9kZUNoYW5nZUxpc3RlbmVyKCkgeworICAgICAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNoaWxkQWRkZWQoTm9kZUNoYW5nZUV2ZW50IGUpIHsKKyAgICAgICAgICAgICAgICBQcmVmZXJlbmNlcyBjaGlsZCA9IGUuZ2V0Q2hpbGQoKTsKKyAgICAgICAgICAgICAgICBpZiAoY2hpbGQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBhZGRSZXN1bHQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQubmFtZSgpID09ICJtb2NrMSIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFkZFJlc3VsdCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc3VwZXIuY2hpbGRBZGRlZChlKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNoaWxkUmVtb3ZlZChOb2RlQ2hhbmdlRXZlbnQgZSkgeworICAgICAgICAgICAgICAgIFByZWZlcmVuY2VzIGNoaWxkID0gZS5nZXRDaGlsZCgpOworICAgICAgICAgICAgICAgIGlmIChjaGlsZCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJlbW92ZVJlc3VsdCA9IGZhbHNlOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZC5uYW1lKCkgPT0gIm1vY2sxIikgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlUmVzdWx0ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzdXBlci5jaGlsZFJlbW92ZWQoZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLmFkZE5vZGVDaGFuZ2VMaXN0ZW5lcihubCk7CisgICAgICAgICAgICBQcmVmZXJlbmNlcyBjaGlsZDEgPSBwcmVmLm5vZGUoIm1vY2sxIik7CisgICAgICAgICAgICBubC53YWl0Rm9yRXZlbnQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBubC5nZXRBZGRlZCgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUobmwuZ2V0QWRkUmVzdWx0KCkpOworICAgICAgICAgICAgbmwucmVzZXQoKTsKKyAgICAgICAgICAgIGNoaWxkMS5yZW1vdmVOb2RlKCk7CisgICAgICAgICAgICBubC53YWl0Rm9yRXZlbnQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBubC5nZXRSZW1vdmVkKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShubC5nZXRSZW1vdmVSZXN1bHQoKSk7CisgICAgICAgICAgICBubC5yZXNldCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgcHJlZi5yZW1vdmVOb2RlQ2hhbmdlTGlzdGVuZXIobmwpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFBhcmVudCgpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBBYnN0cmFjdFByZWZlcmVuY2VzIHBhcmVudCA9IChBYnN0cmFjdFByZWZlcmVuY2VzKSBQcmVmZXJlbmNlcworICAgICAgICAgICAgICAgIC51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworCisgICAgICAgIEFic3RyYWN0UHJlZmVyZW5jZXMgcHJlZiA9IChBYnN0cmFjdFByZWZlcmVuY2VzKSBwYXJlbnQubm9kZSgibW9jayIpOworCisgICAgICAgIE1vY2tOb2RlQ2hhbmdlTGlzdGVuZXIgbmwgPSBuZXcgTW9ja05vZGVDaGFuZ2VMaXN0ZW5lcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjaGlsZEFkZGVkKE5vZGVDaGFuZ2VFdmVudCBlKSB7CisgICAgICAgICAgICAgICAgUHJlZmVyZW5jZXMgcGFyZW50ID0gZS5nZXRQYXJlbnQoKTsKKyAgICAgICAgICAgICAgICBpZiAocGFyZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYWRkUmVzdWx0ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudC5uYW1lKCkgPT0gIm1vY2siKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhZGRSZXN1bHQgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHN1cGVyLmNoaWxkQWRkZWQoZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjaGlsZFJlbW92ZWQoTm9kZUNoYW5nZUV2ZW50IGUpIHsKKyAgICAgICAgICAgICAgICBQcmVmZXJlbmNlcyBwYXJlbnQgPSBlLmdldFBhcmVudCgpOworICAgICAgICAgICAgICAgIGlmIChwYXJlbnQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZW1vdmVSZXN1bHQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50Lm5hbWUoKSA9PSAibW9jayIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZVJlc3VsdCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc3VwZXIuY2hpbGRSZW1vdmVkKGUpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5hZGROb2RlQ2hhbmdlTGlzdGVuZXIobmwpOworICAgICAgICAgICAgUHJlZmVyZW5jZXMgY2hpbGQxID0gcHJlZi5ub2RlKCJtb2NrMSIpOworICAgICAgICAgICAgbmwud2FpdEZvckV2ZW50KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgbmwuZ2V0QWRkZWQoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKG5sLmdldEFkZFJlc3VsdCgpKTsKKyAgICAgICAgICAgIG5sLnJlc2V0KCk7CisgICAgICAgICAgICBjaGlsZDEucmVtb3ZlTm9kZSgpOworICAgICAgICAgICAgbmwud2FpdEZvckV2ZW50KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgbmwuZ2V0UmVtb3ZlZCgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUobmwuZ2V0UmVtb3ZlUmVzdWx0KCkpOworICAgICAgICAgICAgbmwucmVzZXQoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHByZWYucmVtb3ZlTm9kZUNoYW5nZUxpc3RlbmVyKG5sKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIE1vY2tOb2RlQ2hhbmdlTGlzdGVuZXIgaW1wbGVtZW50cyBOb2RlQ2hhbmdlTGlzdGVuZXIgeworICAgICAgICBwcml2YXRlIGludCBhZGRlZCA9IDA7CisgICAgICAgIHByaXZhdGUgaW50IHJlbW92ZWQgPSAwOworICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBhZGRSZXN1bHQgPSBmYWxzZTsKKyAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gcmVtb3ZlUmVzdWx0ID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHdhaXRGb3JFdmVudCgpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgd2FpdCg1MDApOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjaGlsZEFkZGVkKE5vZGVDaGFuZ2VFdmVudCBlKSB7CisgICAgICAgICAgICArK2FkZGVkOworICAgICAgICAgICAgbm90aWZ5QWxsKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2hpbGRSZW1vdmVkKE5vZGVDaGFuZ2VFdmVudCBlKSB7CisgICAgICAgICAgICByZW1vdmVkKys7CisgICAgICAgICAgICBub3RpZnlBbGwoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBnZXRBZGRSZXN1bHQoKSB7CisgICAgICAgICAgICByZXR1cm4gYWRkUmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGdldFJlbW92ZVJlc3VsdCgpIHsKKyAgICAgICAgICAgIHJldHVybiByZW1vdmVSZXN1bHQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkICBpbnQgZ2V0QWRkZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gYWRkZWQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRSZW1vdmVkKCkgeworICAgICAgICAgICAgcmV0dXJuIHJlbW92ZWQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKKyAgICAgICAgICAgIGFkZGVkID0gMDsKKyAgICAgICAgICAgIHJlbW92ZWQgPSAwOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ByZWZzL09sZFByZWZlcmVuY2VDaGFuZ2VFdmVudFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9wcmVmcy9PbGRQcmVmZXJlbmNlQ2hhbmdlRXZlbnRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWNkYmQ2OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9wcmVmcy9PbGRQcmVmZXJlbmNlQ2hhbmdlRXZlbnRUZXN0LmphdmEKQEAgLTAsMCArMSwxNTYgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWwucHJlZnM7CisKK2ltcG9ydCBqYXZhLnV0aWwucHJlZnMuQWJzdHJhY3RQcmVmZXJlbmNlczsKK2ltcG9ydCBqYXZhLnV0aWwucHJlZnMuUHJlZmVyZW5jZUNoYW5nZUV2ZW50OworaW1wb3J0IGphdmEudXRpbC5wcmVmcy5QcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXI7CitpbXBvcnQgamF2YS51dGlsLnByZWZzLlByZWZlcmVuY2VzOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIE9sZFByZWZlcmVuY2VDaGFuZ2VFdmVudFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0S2V5KCkgeworICAgICAgICBBYnN0cmFjdFByZWZlcmVuY2VzIHBhcmVudCA9IChBYnN0cmFjdFByZWZlcmVuY2VzKSBQcmVmZXJlbmNlcworICAgICAgICAgICAgICAgIC51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworCisgICAgICAgIEFic3RyYWN0UHJlZmVyZW5jZXMgcHJlZiA9IChBYnN0cmFjdFByZWZlcmVuY2VzKSBwYXJlbnQubm9kZSgibW9jayIpOworCisgICAgICAgIE1vY2tQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIgcGwgPSBuZXcgTW9ja1ByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHByZWZlcmVuY2VDaGFuZ2UoUHJlZmVyZW5jZUNoYW5nZUV2ZW50IHBjZSkgeworICAgICAgICAgICAgICAgIGlmIChwY2UgIT0gbnVsbCAmJiBwY2UuZ2V0S2V5KCkuZXF1YWxzKCJrZXlfaW50IikpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc3VwZXIucHJlZmVyZW5jZUNoYW5nZShwY2UpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBwcmVmLmFkZFByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcihwbCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnB1dEludCgia2V5X2ludCIsIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBwbC5nZXRDaGFuZ2VkKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShwbC5nZXRSZXN1bHQoKSk7CisgICAgICAgICAgICBwbC5yZXNldCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgcHJlZi5yZW1vdmVQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIocGwpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldE5ld1ZhbHVlKCkgeworICAgICAgICBBYnN0cmFjdFByZWZlcmVuY2VzIHBhcmVudCA9IChBYnN0cmFjdFByZWZlcmVuY2VzKSBQcmVmZXJlbmNlcworICAgICAgICAgICAgICAgIC51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworCisgICAgICAgIEFic3RyYWN0UHJlZmVyZW5jZXMgcHJlZiA9IChBYnN0cmFjdFByZWZlcmVuY2VzKSBwYXJlbnQubm9kZSgibW9jayIpOworCisgICAgICAgIE1vY2tQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIgcGwgPSBuZXcgTW9ja1ByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHByZWZlcmVuY2VDaGFuZ2UoUHJlZmVyZW5jZUNoYW5nZUV2ZW50IHBjZSkgeworICAgICAgICAgICAgICAgIGlmIChwY2UgIT0gbnVsbCAmJiBwY2UuZ2V0TmV3VmFsdWUoKS5lcXVhbHMoSW50ZWdlci50b1N0cmluZyhJbnRlZ2VyLk1BWF9WQUxVRSkpKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHN1cGVyLnByZWZlcmVuY2VDaGFuZ2UocGNlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgcHJlZi5hZGRQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIocGwpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXRJbnQoImtleV9pbnQiLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgcGwuZ2V0Q2hhbmdlZCgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUocGwuZ2V0UmVzdWx0KCkpOworICAgICAgICAgICAgcGwucmVzZXQoKTsKKworICAgICAgICAgICAgcHJlZi5wdXRJbnQoImtleV9pbnQiLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgcGwuZ2V0Q2hhbmdlZCgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUocGwuZ2V0UmVzdWx0KCkpOworICAgICAgICAgICAgcGwucmVzZXQoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHByZWYucmVtb3ZlUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyKHBsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXROb2RlKCkgeworICAgICAgICBBYnN0cmFjdFByZWZlcmVuY2VzIHBhcmVudCA9IChBYnN0cmFjdFByZWZlcmVuY2VzKSBQcmVmZXJlbmNlcworICAgICAgICAgICAgICAgIC51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworCisgICAgICAgIEFic3RyYWN0UHJlZmVyZW5jZXMgcHJlZiA9IChBYnN0cmFjdFByZWZlcmVuY2VzKSBwYXJlbnQubm9kZSgibW9jayIpOworCisgICAgICAgIE1vY2tQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIgcGwgPSBuZXcgTW9ja1ByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHByZWZlcmVuY2VDaGFuZ2UoUHJlZmVyZW5jZUNoYW5nZUV2ZW50IHBjZSkgeworICAgICAgICAgICAgICAgIGlmIChwY2UgIT0gbnVsbCAmJiAibW9jayIuZXF1YWxzKHBjZS5nZXROb2RlKCkubmFtZSgpKSkgeworICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzdXBlci5wcmVmZXJlbmNlQ2hhbmdlKHBjZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIHByZWYuYWRkUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyKHBsKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0SW50KCJrZXlfaW50IiwgSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHBsLmdldENoYW5nZWQoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHBsLmdldFJlc3VsdCgpKTsKKyAgICAgICAgICAgIHBsLnJlc2V0KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBwcmVmLnJlbW92ZVByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcihwbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBNb2NrUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyIGltcGxlbWVudHMgUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyIHsKKyAgICAgICAgcHJpdmF0ZSBpbnQgY2hhbmdlZCA9IDA7CisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBhZGREaXNwYXRjaGVkID0gZmFsc2U7CisgICAgICAgIHByb3RlY3RlZCBib29sZWFuIHJlc3VsdCA9IGZhbHNlOworCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCB3YWl0Rm9yRXZlbnQoKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHdhaXQoNTAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcHJlZmVyZW5jZUNoYW5nZShQcmVmZXJlbmNlQ2hhbmdlRXZlbnQgcGNlKSB7CisgICAgICAgICAgICBjaGFuZ2VkKys7CisgICAgICAgICAgICBhZGREaXNwYXRjaGVkID0gdHJ1ZTsKKyAgICAgICAgICAgIG5vdGlmeUFsbCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGdldFJlc3VsdCgpIHsKKyAgICAgICAgICAgIGlmICghYWRkRGlzcGF0Y2hlZCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IGRvbid0IGtub3cgd2h5IG11c3QgYWRkIGxpbWl0YXRpb24KKyAgICAgICAgICAgICAgICAgICAgdGhpcy53YWl0KDEwMCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFkZERpc3BhdGNoZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRDaGFuZ2VkKCkgeworICAgICAgICAgICAgaWYgKCFhZGREaXNwYXRjaGVkKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogZG9uJ3Qga25vdyB3aHkgbXVzdCBhZGQgbGltaXRhdGlvbgorICAgICAgICAgICAgICAgICAgICB0aGlzLndhaXQoMTAwMCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFkZERpc3BhdGNoZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIHJldHVybiBjaGFuZ2VkOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcmVzZXQoKSB7CisgICAgICAgICAgICBjaGFuZ2VkID0gMDsKKyAgICAgICAgICAgIHJlc3VsdCA9IGZhbHNlOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ByZWZzL09sZFByZWZlcmVuY2VzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ByZWZzL09sZFByZWZlcmVuY2VzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFhNWYwODgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvcHJlZnMvT2xkUHJlZmVyZW5jZXNUZXN0LmphdmEKQEAgLTAsMCArMSwxMTA0IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLnByZWZzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5wcmVmcy5CYWNraW5nU3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLnByZWZzLk5vZGVDaGFuZ2VFdmVudDsKK2ltcG9ydCBqYXZhLnV0aWwucHJlZnMuTm9kZUNoYW5nZUxpc3RlbmVyOworaW1wb3J0IGphdmEudXRpbC5wcmVmcy5QcmVmZXJlbmNlQ2hhbmdlRXZlbnQ7CitpbXBvcnQgamF2YS51dGlsLnByZWZzLlByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcjsKK2ltcG9ydCBqYXZhLnV0aWwucHJlZnMuUHJlZmVyZW5jZXM7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgT2xkUHJlZmVyZW5jZXNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgZmluYWwgc3RhdGljIFN0cmluZyBsb25nS2V5OworICAgIGZpbmFsIHN0YXRpYyBTdHJpbmcgbG9uZ1ZhbHVlOworCisgICAgc3RhdGljIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBrZXkgPSBuZXcgU3RyaW5nQnVpbGRlcihQcmVmZXJlbmNlcy5NQVhfS0VZX0xFTkdUSCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUHJlZmVyZW5jZXMuTUFYX0tFWV9MRU5HVEg7IGkrKykgeworICAgICAgICAgICAga2V5LmFwcGVuZCgnYScpOworICAgICAgICB9CisgICAgICAgIGxvbmdLZXkgPSBrZXkudG9TdHJpbmcoKTsKKworICAgICAgICBTdHJpbmdCdWlsZGVyIHZhbHVlID0gbmV3IFN0cmluZ0J1aWxkZXIoUHJlZmVyZW5jZXMuTUFYX1ZBTFVFX0xFTkdUSCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUHJlZmVyZW5jZXMuTUFYX1ZBTFVFX0xFTkdUSDsgaSsrKSB7CisgICAgICAgICAgICB2YWx1ZS5hcHBlbmQoJ2EnKTsKKyAgICAgICAgfQorICAgICAgICBsb25nVmFsdWUgPSB2YWx1ZS50b1N0cmluZygpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworCisgICAgICAgIFByZWZlcmVuY2VzIHByZWYgPSBQcmVmZXJlbmNlcy51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworICAgICAgICBmb3IgKFN0cmluZyBjaGlsZCA6IHByZWYuY2hpbGRyZW5OYW1lcygpKSB7CisgICAgICAgICAgICBwcmVmLm5vZGUoY2hpbGQpLnJlbW92ZU5vZGUoKTsKKyAgICAgICAgfQorICAgICAgICBwcmVmLmNsZWFyKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFic3RyYWN0TWV0aG9kcygpIHRocm93cyBJT0V4Y2VwdGlvbiwgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgUHJlZmVyZW5jZXMgcCA9IG5ldyBNb2NrUHJlZmVyZW5jZXMoKTsKKyAgICAgICAgcC5hYnNvbHV0ZVBhdGgoKTsKKyAgICAgICAgcC5jaGlsZHJlbk5hbWVzKCk7CisgICAgICAgIHAuY2xlYXIoKTsKKyAgICAgICAgcC5leHBvcnROb2RlKG51bGwpOworICAgICAgICBwLmV4cG9ydFN1YnRyZWUobnVsbCk7CisgICAgICAgIHAuZmx1c2goKTsKKyAgICAgICAgcC5nZXQobnVsbCwgbnVsbCk7CisgICAgICAgIHAuZ2V0Qm9vbGVhbihudWxsLCBmYWxzZSk7CisgICAgICAgIHAuZ2V0Qnl0ZUFycmF5KG51bGwsIG51bGwpOworICAgICAgICBwLmdldEZsb2F0KG51bGwsIDAuMWYpOworICAgICAgICBwLmdldERvdWJsZShudWxsLCAwLjEpOworICAgICAgICBwLmdldEludChudWxsLCAxKTsKKyAgICAgICAgcC5nZXRMb25nKG51bGwsIDFsKTsKKyAgICAgICAgcC5pc1VzZXJOb2RlKCk7CisgICAgICAgIHAua2V5cygpOworICAgICAgICBwLm5hbWUoKTsKKyAgICAgICAgcC5ub2RlKG51bGwpOworICAgICAgICBwLm5vZGVFeGlzdHMobnVsbCk7CisgICAgICAgIHAucGFyZW50KCk7CisgICAgICAgIHAucHV0KG51bGwsIG51bGwpOworICAgICAgICBwLnB1dEJvb2xlYW4obnVsbCwgZmFsc2UpOworICAgICAgICBwLnB1dEJ5dGVBcnJheShudWxsLCBudWxsKTsKKyAgICAgICAgcC5wdXREb3VibGUobnVsbCwgMSk7CisgICAgICAgIHAucHV0RmxvYXQobnVsbCwgMWYpOworICAgICAgICBwLnB1dEludChudWxsLCAxKTsKKyAgICAgICAgcC5wdXRMb25nKG51bGwsIDFsKTsKKyAgICAgICAgcC5yZW1vdmUobnVsbCk7CisgICAgICAgIHAucmVtb3ZlTm9kZSgpOworICAgICAgICBwLmFkZE5vZGVDaGFuZ2VMaXN0ZW5lcihudWxsKTsKKyAgICAgICAgcC5hZGRQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIobnVsbCk7CisgICAgICAgIHAucmVtb3ZlTm9kZUNoYW5nZUxpc3RlbmVyKG51bGwpOworICAgICAgICBwLnJlbW92ZVByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcihudWxsKTsKKyAgICAgICAgcC5zeW5jKCk7CisgICAgICAgIHAudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RydWN0b3IoKSB7CisgICAgICAgIE1vY2tQcmVmZXJlbmNlcyBtcCA9IG5ldyBNb2NrUHJlZmVyZW5jZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1wLmdldENsYXNzKCksIE1vY2tQcmVmZXJlbmNlcy5jbGFzcyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRvU3RyaW5nKCkgeworICAgICAgICBQcmVmZXJlbmNlcyBwMSA9IFByZWZlcmVuY2VzLnVzZXJOb2RlRm9yUGFja2FnZShQcmVmZXJlbmNlcy5jbGFzcyk7CisgICAgICAgIGFzc2VydE5vdE51bGwocDEudG9TdHJpbmcoKSk7CisKKyAgICAgICAgUHJlZmVyZW5jZXMgcDIgPSBQcmVmZXJlbmNlcy5zeXN0ZW1Sb290KCk7CisgICAgICAgIGFzc2VydE5vdE51bGwocDIudG9TdHJpbmcoKSk7CisKKyAgICAgICAgUHJlZmVyZW5jZXMgcDMgPSBQcmVmZXJlbmNlcy51c2VyUm9vdCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKHAzLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBYnNvbHV0ZVBhdGgoKSB7CisgICAgICAgIFByZWZlcmVuY2VzIHAgPSBQcmVmZXJlbmNlcy51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi9qYXZhL3V0aWwvcHJlZnMiLCBwLmFic29sdXRlUGF0aCgpKTsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDaGlsZHJlbk5hbWVzKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIFByZWZlcmVuY2VzIHByZWYgPSBQcmVmZXJlbmNlcy51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworCisgICAgICAgIFByZWZlcmVuY2VzIGNoaWxkMSA9IHByZWYubm9kZSgiY2hpbGQxIik7CisKKyAgICAgICAgcHJlZi5ub2RlKCJjaGlsZDIiKTsKKyAgICAgICAgcHJlZi5ub2RlKCJjaGlsZDMiKTsKKyAgICAgICAgY2hpbGQxLm5vZGUoInN1YmNoaWxkMSIpOworCisgICAgICAgIGFzc2VydFNhbWUocHJlZiwgY2hpbGQxLnBhcmVudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHByZWYuY2hpbGRyZW5OYW1lcygpLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygiY2hpbGQxIiwgcHJlZi5jaGlsZHJlbk5hbWVzKClbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY2hpbGQxLmNoaWxkcmVuTmFtZXMoKS5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoInN1YmNoaWxkMSIsIGNoaWxkMS5jaGlsZHJlbk5hbWVzKClbMF0pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDbGVhcigpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBQcmVmZXJlbmNlcyBwcmVmID0gUHJlZmVyZW5jZXMudXNlck5vZGVGb3JQYWNrYWdlKFByZWZlcmVuY2VzLmNsYXNzKTsKKyAgICAgICAgcHJlZi5wdXQoInRlc3RDbGVhcktleSIsICJ0ZXN0Q2xlYXJWYWx1ZSIpOworICAgICAgICBwcmVmLnB1dCgidGVzdENsZWFyS2V5MSIsICJ0ZXN0Q2xlYXJWYWx1ZTEiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXN0Q2xlYXJWYWx1ZSIsIHByZWYuZ2V0KCJ0ZXN0Q2xlYXJLZXkiLCBudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidGVzdENsZWFyVmFsdWUxIiwgcHJlZi5nZXQoInRlc3RDbGVhcktleTEiLCBudWxsKSk7CisgICAgICAgIHByZWYuY2xlYXIoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChwcmVmLmdldCgidGVzdENsZWFyS2V5IiwgbnVsbCkpOworICAgICAgICBhc3NlcnROdWxsKHByZWYuZ2V0KCJ0ZXN0Q2xlYXJLZXkxIiwgbnVsbCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXQoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgUHJlZmVyZW5jZXMgcm9vdCA9IFByZWZlcmVuY2VzLnVzZXJOb2RlRm9yUGFja2FnZShQcmVmZXJlbmNlcy5jbGFzcyk7CisgICAgICAgIFByZWZlcmVuY2VzIHByZWYgPSByb290Lm5vZGUoIm1vY2siKTsKKyAgICAgICAgYXNzZXJ0TnVsbChwcmVmLmdldCgiIiwgbnVsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRlZmF1bHQiLCBwcmVmLmdldCgia2V5IiwgImRlZmF1bHQiKSk7CisgICAgICAgIGFzc2VydE51bGwocHJlZi5nZXQoImtleSIsIG51bGwpKTsKKyAgICAgICAgcHJlZi5wdXQoInRlc3RHZXRrZXkiLCAidmFsdWUiKTsKKyAgICAgICAgYXNzZXJ0TnVsbChwcmVmLmdldCgidGVzdEdldEtleSIsIG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZSIsIHByZWYuZ2V0KCJ0ZXN0R2V0a2V5IiwgbnVsbCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLmdldChudWxsLCAiYWJjIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgcHJlZi5nZXQoIiIsICJhYmMiKTsKKyAgICAgICAgcHJlZi5nZXQoImtleSIsIG51bGwpOworICAgICAgICBwcmVmLmdldCgia2V5IiwgIiIpOworICAgICAgICBwcmVmLnB1dEZsb2F0KCJmbG9hdEtleSIsIDEuMGYpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEuMCIsIHByZWYuZ2V0KCJmbG9hdEtleSIsIG51bGwpKTsKKworICAgICAgICBwcmVmLnJlbW92ZU5vZGUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYuZ2V0KCJrZXkiLCAiYWJjIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLmdldChudWxsLCAiYWJjIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Qm9vbGVhbigpIHsKKyAgICAgICAgUHJlZmVyZW5jZXMgcHJlZiA9IFByZWZlcmVuY2VzLnVzZXJOb2RlRm9yUGFja2FnZShQcmVmZXJlbmNlcy5jbGFzcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLmdldEJvb2xlYW4obnVsbCwgZmFsc2UpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgcHJlZi5wdXQoInRlc3RHZXRCb29sZWFuS2V5IiwgImZhbHNlIik7CisgICAgICAgIHByZWYucHV0KCJ0ZXN0R2V0Qm9vbGVhbktleTIiLCAidmFsdWUiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocHJlZi5nZXRCb29sZWFuKCJ0ZXN0R2V0Qm9vbGVhbktleSIsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwcmVmLmdldEJvb2xlYW4oInRlc3RHZXRCb29sZWFuS2V5MiIsIHRydWUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Qnl0ZUFycmF5KCkgeworICAgICAgICBQcmVmZXJlbmNlcyBwcmVmID0gUHJlZmVyZW5jZXMudXNlck5vZGVGb3JQYWNrYWdlKFByZWZlcmVuY2VzLmNsYXNzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYuZ2V0Qnl0ZUFycmF5KG51bGwsIG5ldyBieXRlWzBdKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gYjY0QXJyYXkgPSBuZXcgYnl0ZVtdIHsgMHg1OSwgMHg1NywgMHg0YSwgMHg2YSB9Oy8vIEJBU0U2NAorCisgICAgICAgIHByZWYucHV0KCJ0ZXN0R2V0Qnl0ZUFycmF5S2V5IiwgImFiYz0iKTsKKyAgICAgICAgcHJlZi5wdXQoInRlc3RHZXRCeXRlQXJyYXlLZXkyIiwgbmV3IFN0cmluZyhiNjRBcnJheSkpOworICAgICAgICBwcmVmLnB1dCgiaW52YWxpZEtleSIsICI8Pj8iKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKG5ldyBieXRlW10geyAxMDUsIC03MyB9LCBwcmVmLmdldEJ5dGVBcnJheSgKKyAgICAgICAgICAgICAgICAidGVzdEdldEJ5dGVBcnJheUtleSIsIG5ldyBieXRlWzBdKSkpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMobmV3IGJ5dGVbXSB7ICdhJywgJ2InLCAnYycgfSwgcHJlZgorICAgICAgICAgICAgICAgIC5nZXRCeXRlQXJyYXkoInRlc3RHZXRCeXRlQXJyYXlLZXkyIiwgbmV3IGJ5dGVbMF0pKSk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhuZXcgYnl0ZVswXSwgcHJlZi5nZXRCeXRlQXJyYXkoImludmFsaWRLZXkiLAorICAgICAgICAgICAgICAgIG5ldyBieXRlWzBdKSkpOworCisgICAgICAgIHByZWYucHV0Qnl0ZUFycmF5KCJ0ZXN0R2V0Qnl0ZUFycmF5S2V5MyIsIGI2NEFycmF5KTsKKyAgICAgICAgcHJlZi5wdXRCeXRlQXJyYXkoInRlc3RHZXRCeXRlQXJyYXlLZXk0IiwgImFiYyIuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhiNjRBcnJheSwgcHJlZi5nZXRCeXRlQXJyYXkoCisgICAgICAgICAgICAgICAgInRlc3RHZXRCeXRlQXJyYXlLZXkzIiwgbmV3IGJ5dGVbMF0pKSk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscygiYWJjIi5nZXRCeXRlcygpLCBwcmVmLmdldEJ5dGVBcnJheSgKKyAgICAgICAgICAgICAgICAidGVzdEdldEJ5dGVBcnJheUtleTQiLCBuZXcgYnl0ZVswXSkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RG91YmxlKCkgeworICAgICAgICBQcmVmZXJlbmNlcyBwcmVmID0gUHJlZmVyZW5jZXMudXNlck5vZGVGb3JQYWNrYWdlKFByZWZlcmVuY2VzLmNsYXNzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYuZ2V0RG91YmxlKG51bGwsIDApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgcHJlZi5wdXQoInRlc3RHZXREb3VibGVLZXkiLCAiMSIpOworICAgICAgICBwcmVmLnB1dCgidGVzdEdldERvdWJsZUtleTIiLCAidmFsdWUiKTsKKyAgICAgICAgcHJlZi5wdXREb3VibGUoInRlc3RHZXREb3VibGVLZXkzIiwgMSk7CisgICAgICAgIHByZWYucHV0SW50KCJ0ZXN0R2V0RG91YmxlS2V5NCIsIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoMS4wLCBwcmVmLmdldERvdWJsZSgidGVzdEdldERvdWJsZUtleSIsIDAuMCksIDApOworICAgICAgICBhc3NlcnRFcXVhbHMoMC4wLCBwcmVmLmdldERvdWJsZSgidGVzdEdldERvdWJsZUtleTIiLCAwLjApLCAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMCwgcHJlZi5nZXREb3VibGUoInRlc3RHZXREb3VibGVLZXkzIiwgMC4wKSwgMCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLjAsIHByZWYuZ2V0RG91YmxlKCJ0ZXN0R2V0RG91YmxlS2V5NCIsIDAuMCksIDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRGbG9hdCgpIHsKKyAgICAgICAgUHJlZmVyZW5jZXMgcHJlZiA9IFByZWZlcmVuY2VzLnVzZXJOb2RlRm9yUGFja2FnZShQcmVmZXJlbmNlcy5jbGFzcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLmdldEZsb2F0KG51bGwsIDBmKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBwcmVmLnB1dCgidGVzdEdldEZsb2F0S2V5IiwgIjEiKTsKKyAgICAgICAgcHJlZi5wdXQoInRlc3RHZXRGbG9hdEtleTIiLCAidmFsdWUiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDFmLCBwcmVmLmdldEZsb2F0KCJ0ZXN0R2V0RmxvYXRLZXkiLCAwZiksIDApOworICAgICAgICBhc3NlcnRFcXVhbHMoMGYsIHByZWYuZ2V0RmxvYXQoInRlc3RHZXRGbG9hdEtleTIiLCAwZiksIDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnQoKSB7CisgICAgICAgIFByZWZlcmVuY2VzIHByZWYgPSBQcmVmZXJlbmNlcy51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5nZXRJbnQobnVsbCwgMCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBwcmVmLnB1dCgidGVzdEdldEludEtleSIsICIxIik7CisgICAgICAgIHByZWYucHV0KCJ0ZXN0R2V0SW50S2V5MiIsICJ2YWx1ZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgcHJlZi5nZXRJbnQoInRlc3RHZXRJbnRLZXkiLCAwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBwcmVmLmdldEludCgidGVzdEdldEludEtleTIiLCAwKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldExvbmcoKSB7CisgICAgICAgIFByZWZlcmVuY2VzIHByZWYgPSBQcmVmZXJlbmNlcy51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5nZXRMb25nKG51bGwsIDApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgcHJlZi5wdXQoInRlc3RHZXRMb25nS2V5IiwgIjEiKTsKKyAgICAgICAgcHJlZi5wdXQoInRlc3RHZXRMb25nS2V5MiIsICJ2YWx1ZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgcHJlZi5nZXRJbnQoInRlc3RHZXRMb25nS2V5IiwgMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgcHJlZi5nZXRJbnQoInRlc3RHZXRMb25nS2V5MiIsIDApKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNVc2VyTm9kZSgpIHsKKyAgICAgICAgUHJlZmVyZW5jZXMgcHJlZjEgPSBQcmVmZXJlbmNlcy51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworICAgICAgICBhc3NlcnRUcnVlKHByZWYxLmlzVXNlck5vZGUoKSk7CisKKyAgICAgICAgUHJlZmVyZW5jZXMgcHJlZjIgPSBQcmVmZXJlbmNlcy5zeXN0ZW1Ob2RlRm9yUGFja2FnZShQcmVmZXJlbmNlcy5jbGFzcyk7CisgICAgICAgIGFzc2VydEZhbHNlKHByZWYyLmlzVXNlck5vZGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEtleXMoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgUHJlZmVyZW5jZXMgcHJlZiA9IFByZWZlcmVuY2VzLnVzZXJOb2RlRm9yUGFja2FnZShQcmVmZXJlbmNlcy5jbGFzcyk7CisgICAgICAgIHByZWYuY2xlYXIoKTsKKworICAgICAgICBwcmVmLnB1dCgia2V5MCIsICJ2YWx1ZSIpOworICAgICAgICBwcmVmLnB1dCgia2V5MSIsICJ2YWx1ZTEiKTsKKyAgICAgICAgcHJlZi5wdXQoImtleTIiLCAidmFsdWUyIik7CisgICAgICAgIHByZWYucHV0KCJrZXkzIiwgInZhbHVlMyIpOworCisgICAgICAgIFN0cmluZ1tdIGtleXMgPSBwcmVmLmtleXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIGtleXMubGVuZ3RoKTsKKyAgICAgICAgZm9yIChTdHJpbmcga2V5IDoga2V5cykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGtleS5pbmRleE9mKCJrZXkiKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNCwga2V5Lmxlbmd0aCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROYW1lKCkgeworICAgICAgICBQcmVmZXJlbmNlcyBwcmVmID0gUHJlZmVyZW5jZXMudXNlck5vZGVGb3JQYWNrYWdlKFByZWZlcmVuY2VzLmNsYXNzKTsKKyAgICAgICAgUHJlZmVyZW5jZXMgY2hpbGQgPSBwcmVmLm5vZGUoIm1vY2siKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJtb2NrIiwgY2hpbGQubmFtZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9kZSgpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBTdHJpbmdCdWlsZGVyIG5hbWUgPSBuZXcgU3RyaW5nQnVpbGRlcihQcmVmZXJlbmNlcy5NQVhfTkFNRV9MRU5HVEgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IFByZWZlcmVuY2VzLk1BWF9OQU1FX0xFTkdUSDsgaSsrKSB7CisgICAgICAgICAgICBuYW1lLmFwcGVuZCgnYScpOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBsb25nTmFtZSA9IG5hbWUudG9TdHJpbmcoKTsKKworICAgICAgICBQcmVmZXJlbmNlcyByb290ID0gUHJlZmVyZW5jZXMudXNlclJvb3QoKTsKKyAgICAgICAgUHJlZmVyZW5jZXMgcGFyZW50ID0gUHJlZmVyZW5jZXMKKyAgICAgICAgICAgICAgICAudXNlck5vZGVGb3JQYWNrYWdlKFByZWZlcmVuY2VzLmNsYXNzKTsKKyAgICAgICAgUHJlZmVyZW5jZXMgcHJlZiA9IHBhcmVudC5ub2RlKCJtb2NrIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYubm9kZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5ub2RlKCIvamF2YS91dGlsL3ByZWZzLyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5ub2RlKCIvamF2YS8vdXRpbC9wcmVmcyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5ub2RlKGxvbmdOYW1lICsgImEiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbChwcmVmLm5vZGUobG9uZ05hbWUpKTsKKworICAgICAgICBhc3NlcnRTYW1lKHJvb3QsIHByZWYubm9kZSgiLyIpKTsKKworICAgICAgICBQcmVmZXJlbmNlcyBwcmVmcyA9IHByZWYubm9kZSgiL2phdmEvdXRpbC9wcmVmcyIpOworICAgICAgICBhc3NlcnRTYW1lKHByZWZzLCBwYXJlbnQpOworCisgICAgICAgIGFzc2VydFNhbWUocHJlZiwgcHJlZi5ub2RlKCIiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vZGVFeGlzdHMoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKworICAgICAgICBQcmVmZXJlbmNlcyBwYXJlbnQgPSBQcmVmZXJlbmNlcworICAgICAgICAgICAgICAgIC51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworICAgICAgICBQcmVmZXJlbmNlcyBwcmVmID0gcGFyZW50Lm5vZGUoIm1vY2siKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5ub2RlRXhpc3RzKG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLm5vZGVFeGlzdHMoIi9qYXZhL3V0aWwvcHJlZnMvIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLm5vZGVFeGlzdHMoIi9qYXZhLy91dGlsL3ByZWZzIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShwcmVmLm5vZGVFeGlzdHMoIi8iKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShwcmVmLm5vZGVFeGlzdHMoIi9qYXZhL3V0aWwvcHJlZnMiKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShwcmVmLm5vZGVFeGlzdHMoIiIpKTsKKworICAgICAgICBhc3NlcnRGYWxzZShwcmVmLm5vZGVFeGlzdHMoImNoaWxkIikpOworICAgICAgICBQcmVmZXJlbmNlcyBncmFuZGNoaWxkID0gcHJlZi5ub2RlKCJjaGlsZC9ncmFuZGNoaWxkIik7CisgICAgICAgIGFzc2VydFRydWUocHJlZi5ub2RlRXhpc3RzKCJjaGlsZCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwcmVmLm5vZGVFeGlzdHMoImNoaWxkL2dyYW5kY2hpbGQiKSk7CisgICAgICAgIGdyYW5kY2hpbGQucmVtb3ZlTm9kZSgpOworICAgICAgICBhc3NlcnRUcnVlKHByZWYubm9kZUV4aXN0cygiY2hpbGQiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHByZWYubm9kZUV4aXN0cygiY2hpbGQvZ3JhbmRjaGlsZCIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZ3JhbmRjaGlsZC5ub2RlRXhpc3RzKCIiKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UocHJlZi5ub2RlRXhpc3RzKCJjaGlsZDIvZ3JhbmRjaGlsZCIpKTsKKyAgICAgICAgcHJlZi5ub2RlKCJjaGlsZDIvZ3JhbmRjaGlsZCIpOworICAgICAgICBhc3NlcnRUcnVlKHByZWYubm9kZUV4aXN0cygiY2hpbGQyL2dyYW5kY2hpbGQiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcmVudCgpIHsKKyAgICAgICAgUHJlZmVyZW5jZXMgcGFyZW50ID0gUHJlZmVyZW5jZXMKKyAgICAgICAgICAgICAgICAudXNlck5vZGVGb3JQYWNrYWdlKFByZWZlcmVuY2VzLmNsYXNzKTsKKyAgICAgICAgUHJlZmVyZW5jZXMgcHJlZiA9IHBhcmVudC5ub2RlKCJtb2NrIik7CisKKyAgICAgICAgYXNzZXJ0U2FtZShwYXJlbnQsIHByZWYucGFyZW50KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQdXQoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgUHJlZmVyZW5jZXMgcHJlZiA9IFByZWZlcmVuY2VzCisgICAgICAgIC51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworICAgICAgICBwcmVmLnB1dCgiIiwgImVtcHR5dmFsdWUiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbXB0eXZhbHVlIiwgcHJlZi5nZXQoIiIsIG51bGwpKTsKKyAgICAgICAgcHJlZi5wdXQoInRlc3RQdXRrZXkiLCAidmFsdWUxIik7CisgICAgICAgIGFzc2VydEVxdWFscygidmFsdWUxIiwgcHJlZi5nZXQoInRlc3RQdXRrZXkiLCBudWxsKSk7CisgICAgICAgIHByZWYucHV0KCJ0ZXN0UHV0a2V5IiwgInZhbHVlMiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlMiIsIHByZWYuZ2V0KCJ0ZXN0UHV0a2V5IiwgbnVsbCkpOworCisgICAgICAgIHByZWYucHV0KCIiLCAiZW1wdHl2YWx1ZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVtcHR5dmFsdWUiLCBwcmVmLmdldCgiIiwgbnVsbCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnB1dChudWxsLCAidmFsdWUiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXQoImtleSIsIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHByZWYucHV0KGxvbmdLZXksIGxvbmdWYWx1ZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnB1dChsb25nS2V5ICsgMSwgbG9uZ1ZhbHVlKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0KGxvbmdLZXksIGxvbmdWYWx1ZSArIDEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHByZWYucmVtb3ZlTm9kZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXQobG9uZ0tleSwgbG9uZ1ZhbHVlICsgMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0KGxvbmdLZXksIGxvbmdWYWx1ZSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1dEJvb2xlYW4oKSB7CisgICAgICAgIFByZWZlcmVuY2VzIHByZWYgPSBQcmVmZXJlbmNlcy51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXRCb29sZWFuKG51bGwsIGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBwcmVmLnB1dEJvb2xlYW4obG9uZ0tleSwgZmFsc2UpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXRCb29sZWFuKGxvbmdLZXkgKyAiYSIsIGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgcHJlZi5wdXRCb29sZWFuKCJ0ZXN0UHV0Qm9vbGVhbktleSIsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmYWxzZSIsIHByZWYuZ2V0KCJ0ZXN0UHV0Qm9vbGVhbktleSIsIG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocHJlZi5nZXRCb29sZWFuKCJ0ZXN0UHV0Qm9vbGVhbktleSIsIHRydWUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHV0RG91YmxlKCkgeworICAgICAgICBQcmVmZXJlbmNlcyBwcmVmID0gUHJlZmVyZW5jZXMKKyAgICAgICAgLnVzZXJOb2RlRm9yUGFja2FnZShQcmVmZXJlbmNlcy5jbGFzcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnB1dERvdWJsZShudWxsLCAzKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBwcmVmLnB1dERvdWJsZShsb25nS2V5LCAzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0RG91YmxlKGxvbmdLZXkgKyAiYSIsIDMpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBwcmVmLnB1dERvdWJsZSgidGVzdFB1dERvdWJsZUtleSIsIDMpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjMuMCIsIHByZWYuZ2V0KCJ0ZXN0UHV0RG91YmxlS2V5IiwgbnVsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgcHJlZi5nZXREb3VibGUoInRlc3RQdXREb3VibGVLZXkiLCAwKSwgMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1dEZsb2F0KCkgeworICAgICAgICBQcmVmZXJlbmNlcyBwcmVmID0gUHJlZmVyZW5jZXMudXNlck5vZGVGb3JQYWNrYWdlKFByZWZlcmVuY2VzLmNsYXNzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0RmxvYXQobnVsbCwgM2YpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHByZWYucHV0RmxvYXQobG9uZ0tleSwgM2YpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXRGbG9hdChsb25nS2V5ICsgImEiLCAzZik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHByZWYucHV0RmxvYXQoInRlc3RQdXRGbG9hdEtleSIsIDNmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIzLjAiLCBwcmVmLmdldCgidGVzdFB1dEZsb2F0S2V5IiwgbnVsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoM2YsIHByZWYuZ2V0RmxvYXQoInRlc3RQdXRGbG9hdEtleSIsIDApLCAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHV0SW50KCkgeworICAgICAgICBQcmVmZXJlbmNlcyBwcmVmID0gUHJlZmVyZW5jZXMudXNlck5vZGVGb3JQYWNrYWdlKFByZWZlcmVuY2VzLmNsYXNzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0SW50KG51bGwsIDMpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHByZWYucHV0SW50KGxvbmdLZXksIDMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXRJbnQobG9uZ0tleSArICJhIiwgMyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHByZWYucHV0SW50KCJ0ZXN0UHV0SW50S2V5IiwgMyk7CisgICAgICAgIGFzc2VydEVxdWFscygiMyIsIHByZWYuZ2V0KCJ0ZXN0UHV0SW50S2V5IiwgbnVsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgcHJlZi5nZXRJbnQoInRlc3RQdXRJbnRLZXkiLCAwKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1dExvbmcoKSB7CisgICAgICAgIFByZWZlcmVuY2VzIHByZWYgPSBQcmVmZXJlbmNlcy51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXRMb25nKG51bGwsIDNMKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBwcmVmLnB1dExvbmcobG9uZ0tleSwgM0wpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXRMb25nKGxvbmdLZXkgKyAiYSIsIDNMKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgcHJlZi5wdXRMb25nKCJ0ZXN0UHV0TG9uZ0tleSIsIDNMKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIzIiwgcHJlZi5nZXQoInRlc3RQdXRMb25nS2V5IiwgbnVsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoM0wsIHByZWYuZ2V0TG9uZygidGVzdFB1dExvbmdLZXkiLCAwKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1dEJ5dGVBcnJheSgpIHsKKyAgICAgICAgUHJlZmVyZW5jZXMgcHJlZiA9IFByZWZlcmVuY2VzLnVzZXJOb2RlRm9yUGFja2FnZShQcmVmZXJlbmNlcy5jbGFzcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnB1dEJ5dGVBcnJheShudWxsLCBuZXcgYnl0ZVswXSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0Qnl0ZUFycmF5KCJ0ZXN0UHV0Qnl0ZUFycmF5S2V5NCIsIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgcHJlZi5wdXRCeXRlQXJyYXkobG9uZ0tleSwgbmV3IGJ5dGVbMF0pOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5wdXRCeXRlQXJyYXkobG9uZ0tleSArICJhIiwgbmV3IGJ5dGVbMF0pOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gbG9uZ0FycmF5ID0gbmV3IGJ5dGVbKGludCkgKFByZWZlcmVuY2VzLk1BWF9WQUxVRV9MRU5HVEggKiAwLjc0KV07CisgICAgICAgIGJ5dGVbXSBsb25nZXJBcnJheSA9IG5ldyBieXRlWyhpbnQpIChQcmVmZXJlbmNlcy5NQVhfVkFMVUVfTEVOR1RIICogMC43NSkgKyAxXTsKKyAgICAgICAgcHJlZi5wdXRCeXRlQXJyYXkobG9uZ0tleSwgbG9uZ0FycmF5KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucHV0Qnl0ZUFycmF5KGxvbmdLZXksIGxvbmdlckFycmF5KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBwcmVmLnB1dEJ5dGVBcnJheSgidGVzdFB1dEJ5dGVBcnJheUtleSIsIG5ldyBieXRlWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBwcmVmLmdldCgidGVzdFB1dEJ5dGVBcnJheUtleSIsIG51bGwpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKG5ldyBieXRlWzBdLCBwcmVmLmdldEJ5dGVBcnJheSgKKyAgICAgICAgICAgICAgICAidGVzdFB1dEJ5dGVBcnJheUtleSIsIG51bGwpKSk7CisKKyAgICAgICAgcHJlZi5wdXRCeXRlQXJyYXkoInRlc3RQdXRCeXRlQXJyYXlLZXkzIiwgbmV3IGJ5dGVbXSB7ICdhJywgJ2InLCAnYycgfSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWVdKaiIsIHByZWYuZ2V0KCJ0ZXN0UHV0Qnl0ZUFycmF5S2V5MyIsIG51bGwpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKG5ldyBieXRlW10geyAnYScsICdiJywgJ2MnIH0sIHByZWYKKyAgICAgICAgICAgICAgICAuZ2V0Qnl0ZUFycmF5KCJ0ZXN0UHV0Qnl0ZUFycmF5S2V5MyIsIG51bGwpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZSgpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICBQcmVmZXJlbmNlcyBwcmVmID0gUHJlZmVyZW5jZXMKKyAgICAgICAgLnVzZXJOb2RlRm9yUGFja2FnZShQcmVmZXJlbmNlcy5jbGFzcyk7CisgICAgICAgIHByZWYucmVtb3ZlKCJrZXkiKTsKKworICAgICAgICBwcmVmLnB1dCgia2V5IiwgInZhbHVlIik7CisgICAgICAgIGFzc2VydEVxdWFscygidmFsdWUiLCBwcmVmLmdldCgia2V5IiwgbnVsbCkpOworICAgICAgICBwcmVmLnJlbW92ZSgia2V5Iik7CisgICAgICAgIGFzc2VydE51bGwocHJlZi5nZXQoImtleSIsIG51bGwpKTsKKworICAgICAgICBwcmVmLnJlbW92ZSgia2V5Iik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucmVtb3ZlKG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnJlbW92ZSgia2V5Iik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZU5vZGUoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgUHJlZmVyZW5jZXMgcHJlZiA9IFByZWZlcmVuY2VzCisgICAgICAgIC51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworICAgICAgICBQcmVmZXJlbmNlcyBjaGlsZCA9IHByZWYubm9kZSgiY2hpbGQiKTsKKyAgICAgICAgUHJlZmVyZW5jZXMgY2hpbGQxID0gcHJlZi5ub2RlKCJjaGlsZDEiKTsKKyAgICAgICAgUHJlZmVyZW5jZXMgZ3JhbmRjaGlsZCA9IGNoaWxkLm5vZGUoImdyYW5kY2hpbGQiKTsKKworICAgICAgICBwcmVmLnJlbW92ZU5vZGUoKTsKKworICAgICAgICBhc3NlcnRGYWxzZShjaGlsZC5ub2RlRXhpc3RzKCIiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGNoaWxkMS5ub2RlRXhpc3RzKCIiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGdyYW5kY2hpbGQubm9kZUV4aXN0cygiIikpOworICAgICAgICBhc3NlcnRGYWxzZShwcmVmLm5vZGVFeGlzdHMoIiIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWRkTm9kZUNoYW5nZUxpc3RlbmVyKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIFByZWZlcmVuY2VzIHByZWYgPSBQcmVmZXJlbmNlcy51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5hZGROb2RlQ2hhbmdlTGlzdGVuZXIobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBQcmVmZXJlbmNlcyBjaGlsZDEgPSBudWxsOworCisgICAgICAgIE1vY2tOb2RlQ2hhbmdlTGlzdGVuZXIgbmwgPSBudWxsOworICAgICAgICAvLyBUbyBnZXQgZXhpc3RlZCBub2RlIGRvZXNuJ3QgY3JlYXRlIHRoZSBjaGFuZ2UgZXZlbnQKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5sID0gbmV3IE1vY2tOb2RlQ2hhbmdlTGlzdGVuZXIoKTsKKyAgICAgICAgICAgIHByZWYuYWRkTm9kZUNoYW5nZUxpc3RlbmVyKG5sKTsKKyAgICAgICAgICAgIGNoaWxkMSA9IHByZWYubm9kZSgibW9jazEiKTsKKyAgICAgICAgICAgIG5sLndhaXRGb3JFdmVudCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG5sLmdldEFkZGVkKCkpOworICAgICAgICAgICAgbmwucmVzZXQoKTsKKyAgICAgICAgICAgIHByZWYubm9kZSgibW9jazEiKTsKKyAgICAgICAgICAgIG5sLndhaXRGb3JFdmVudCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG5sLmdldEFkZGVkKCkpOworICAgICAgICAgICAgbmwucmVzZXQoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHByZWYucmVtb3ZlTm9kZUNoYW5nZUxpc3RlbmVyKG5sKTsKKyAgICAgICAgICAgIGNoaWxkMS5yZW1vdmVOb2RlKCk7CisgICAgICAgIH0KKyAgICAgICAgLy8gc2FtZSBsaXN0ZW5lciBjYW4gYmUgYWRkZWQgdHdpY2UsIGFuZCBtdXN0IGJlIHJlbW92ZWQgdHdpY2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5sID0gbmV3IE1vY2tOb2RlQ2hhbmdlTGlzdGVuZXIoKTsKKyAgICAgICAgICAgIHByZWYuYWRkTm9kZUNoYW5nZUxpc3RlbmVyKG5sKTsKKyAgICAgICAgICAgIHByZWYuYWRkTm9kZUNoYW5nZUxpc3RlbmVyKG5sKTsKKyAgICAgICAgICAgIGNoaWxkMSA9IHByZWYubm9kZSgibW9jazIiKTsKKyAgICAgICAgICAgIG5sLndhaXRGb3JFdmVudCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIG5sLmdldEFkZGVkKCkpOworICAgICAgICAgICAgbmwucmVzZXQoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHByZWYucmVtb3ZlTm9kZUNoYW5nZUxpc3RlbmVyKG5sKTsKKyAgICAgICAgICAgIHByZWYucmVtb3ZlTm9kZUNoYW5nZUxpc3RlbmVyKG5sKTsKKyAgICAgICAgICAgIGNoaWxkMS5yZW1vdmVOb2RlKCk7CisgICAgICAgIH0KKyAgICAgICAgLy8gdGVzdCByZW1vdmUgZXZlbnQKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5sID0gbmV3IE1vY2tOb2RlQ2hhbmdlTGlzdGVuZXIoKTsKKyAgICAgICAgICAgIHByZWYuYWRkTm9kZUNoYW5nZUxpc3RlbmVyKG5sKTsKKyAgICAgICAgICAgIGNoaWxkMSA9IHByZWYubm9kZSgibW9jazMiKTsKKyAgICAgICAgICAgIGNoaWxkMS5yZW1vdmVOb2RlKCk7CisgICAgICAgICAgICBubC53YWl0Rm9yRXZlbnQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBubC5nZXRSZW1vdmVkKCkpOworICAgICAgICAgICAgbmwucmVzZXQoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHByZWYucmVtb3ZlTm9kZUNoYW5nZUxpc3RlbmVyKG5sKTsKKyAgICAgICAgfQorICAgICAgICAvLyB0ZXN0IHJlbW92ZSBldmVudCB3aXRoIHR3byBsaXN0ZW5lcnMKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5sID0gbmV3IE1vY2tOb2RlQ2hhbmdlTGlzdGVuZXIoKTsKKyAgICAgICAgICAgIHByZWYuYWRkTm9kZUNoYW5nZUxpc3RlbmVyKG5sKTsKKyAgICAgICAgICAgIHByZWYuYWRkTm9kZUNoYW5nZUxpc3RlbmVyKG5sKTsKKyAgICAgICAgICAgIGNoaWxkMSA9IHByZWYubm9kZSgibW9jazYiKTsKKyAgICAgICAgICAgIGNoaWxkMS5yZW1vdmVOb2RlKCk7CisgICAgICAgICAgICBubC53YWl0Rm9yRXZlbnQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygyLCBubC5nZXRSZW1vdmVkKCkpOworICAgICAgICAgICAgbmwucmVzZXQoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHByZWYucmVtb3ZlTm9kZUNoYW5nZUxpc3RlbmVyKG5sKTsKKyAgICAgICAgICAgIHByZWYucmVtb3ZlTm9kZUNoYW5nZUxpc3RlbmVyKG5sKTsKKyAgICAgICAgfQorICAgICAgICAvLyB0ZXN0IGFkZC9yZW1vdmUgaW5kaXJlY3QgY2hpbGRyZW4sIG9yIHJlbW92ZSBzZXZlcmFsIGNoaWxkcmVuIGF0IHRoZQorICAgICAgICAvLyBzYW1lIHRpbWUKKyAgICAgICAgUHJlZmVyZW5jZXMgY2hpbGQzOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmwgPSBuZXcgTW9ja05vZGVDaGFuZ2VMaXN0ZW5lcigpOworICAgICAgICAgICAgY2hpbGQxID0gcHJlZi5ub2RlKCJtb2NrNCIpOworICAgICAgICAgICAgY2hpbGQxLmFkZE5vZGVDaGFuZ2VMaXN0ZW5lcihubCk7CisgICAgICAgICAgICBwcmVmLm5vZGUoIm1vY2s0L21vY2s1Iik7CisgICAgICAgICAgICBubC53YWl0Rm9yRXZlbnQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBubC5nZXRBZGRlZCgpKTsKKyAgICAgICAgICAgIG5sLnJlc2V0KCk7CisgICAgICAgICAgICBjaGlsZDMgPSBwcmVmLm5vZGUoIm1vY2s0L21vY2s1L21vY2s2Iik7CisgICAgICAgICAgICBubC53YWl0Rm9yRXZlbnQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBubC5nZXRBZGRlZCgpKTsKKyAgICAgICAgICAgIG5sLnJlc2V0KCk7CisKKyAgICAgICAgICAgIGNoaWxkMy5yZW1vdmVOb2RlKCk7CisgICAgICAgICAgICBubC53YWl0Rm9yRXZlbnQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBubC5nZXRSZW1vdmVkKCkpOworICAgICAgICAgICAgbmwucmVzZXQoKTsKKworICAgICAgICAgICAgcHJlZi5ub2RlKCJtb2NrNC9tb2NrNyIpOworICAgICAgICAgICAgbmwud2FpdEZvckV2ZW50KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgbmwuZ2V0QWRkZWQoKSk7CisgICAgICAgICAgICBubC5yZXNldCgpOworCisgICAgICAgICAgICBjaGlsZDEucmVtb3ZlTm9kZSgpOworICAgICAgICAgICAgbmwud2FpdEZvckV2ZW50KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMiwgbmwuZ2V0UmVtb3ZlZCgpKTsgLy8gZmFpbCAxCisgICAgICAgICAgICBubC5yZXNldCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjaGlsZDEucmVtb3ZlTm9kZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJlZmVyZW5jZXMgcHJlZiA9IFByZWZlcmVuY2VzLnVzZXJOb2RlRm9yUGFja2FnZShQcmVmZXJlbmNlcy5jbGFzcyk7CisgICAgICAgIE1vY2tQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIgcGwgPSBudWxsOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLmFkZFByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRvIGdldCBleGlzdGVkIG5vZGUgZG9lc24ndCBjcmVhdGUgdGhlIGNoYW5nZSBldmVudAorICAgICAgICB0cnkgeworICAgICAgICAgICAgcGwgPSBuZXcgTW9ja1ByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcigpOworICAgICAgICAgICAgcHJlZi5hZGRQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIocGwpOworICAgICAgICAgICAgcHJlZi5wdXRJbnQoIm1vY2sxIiwgMTIzKTsKKyAgICAgICAgICAgIHBsLndhaXRGb3JFdmVudCgxKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBwbC5nZXRDaGFuZ2VkKCkpOworICAgICAgICAgICAgcHJlZi5wdXRMb25nKCJsb25nX2tleSIsIExvbmcuTUFYX1ZBTFVFKTsKKyAgICAgICAgICAgIHBsLndhaXRGb3JFdmVudCgyKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygyLCBwbC5nZXRDaGFuZ2VkKCkpOworICAgICAgICAgICAgcGwucmVzZXQoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHJlZi5jbGVhcigpOworICAgICAgICAgICAgICAgIHBsLndhaXRGb3JFdmVudCgyKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMiwgcGwuZ2V0Q2hhbmdlZCgpKTsgLy8gZmFpbCAxCisgICAgICAgICAgICB9IGNhdGNoKEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiBic2UpIHsKKyAgICAgICAgICAgICAgICBwbC5yZXNldCgpOworICAgICAgICAgICAgICAgIGZhaWwoIkJhY2tpbmdTdG9yZUV4Y2VwdGlvbiBpcyB0aHJvd24iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBsLnJlc2V0KCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBwcmVmLnJlbW92ZVByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcihwbCk7CisgICAgICAgICAgICAvL2NoaWxkMS5yZW1vdmVOb2RlKCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBzYW1lIGxpc3RlbmVyIGNhbiBiZSBhZGRlZCB0d2ljZSwgYW5kIG11c3QgYmUgcmVtb3ZlZCB0d2ljZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcGwgPSBuZXcgTW9ja1ByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcigpOworICAgICAgICAgICAgcHJlZi5hZGRQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIocGwpOworICAgICAgICAgICAgcHJlZi5hZGRQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIocGwpOworICAgICAgICAgICAgcHJlZi5wdXRGbG9hdCgiZmxvYXRfa2V5IiwgRmxvYXQuTUlOX1ZBTFVFKTsKKyAgICAgICAgICAgIHBsLndhaXRGb3JFdmVudCgyKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygyLCBwbC5nZXRDaGFuZ2VkKCkpOworICAgICAgICAgICAgcGwucmVzZXQoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHByZWYucmVtb3ZlUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyKHBsKTsKKyAgICAgICAgICAgIHByZWYucmVtb3ZlUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyKHBsKTsKKworICAgICAgICB9CisgICAgICAgIC8vIHRlc3QgcmVtb3ZlIGV2ZW50CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwbCA9IG5ldyBNb2NrUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyKCk7CisgICAgICAgICAgICBwcmVmLmFkZFByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcihwbCk7CisgICAgICAgICAgICBwcmVmLnB1dERvdWJsZSgiZG91YmxlX2tleSIsIERvdWJsZS5NQVhfVkFMVUUpOworICAgICAgICAgICAgcGwud2FpdEZvckV2ZW50KDEpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHBsLmdldENoYW5nZWQoKSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHByZWYuY2xlYXIoKTsKKyAgICAgICAgICAgICAgICBwbC53YWl0Rm9yRXZlbnQoMyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHBsLmdldENoYW5nZWQoKSk7IC8vIGZhaWxzCisgICAgICAgICAgICB9IGNhdGNoKEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiBic2UpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJCYWNraW5nU3RvcmVFeGNlcHRpb24gaXMgdGhyb3duIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwbC5yZXNldCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgcHJlZi5yZW1vdmVQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIocGwpOworICAgICAgICB9CisgICAgICAgIC8vIHRlc3QgcmVtb3ZlIGV2ZW50IHdpdGggdHdvIGxpc3RlbmVycworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGwgPSBuZXcgTW9ja1ByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcigpOworICAgICAgICAgICAgcHJlZi5hZGRQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIocGwpOworICAgICAgICAgICAgcHJlZi5hZGRQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIocGwpOworICAgICAgICAgICAgcHJlZi5wdXRCeXRlQXJyYXkoImJ5dGVfYXJyYXlfa2V5IiwgbmV3IGJ5dGUgW10gezEgLDIgLCAzfSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHByZWYuY2xlYXIoKTsKKyAgICAgICAgICAgICAgICBwbC53YWl0Rm9yRXZlbnQoNCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIHBsLmdldENoYW5nZWQoKSk7CisgICAgICAgICAgICB9IGNhdGNoKEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiBic2UpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJCYWNraW5nU3RvcmVFeGNlcHRpb24gaXMgdGhyb3duIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwbC5yZXNldCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgcHJlZi5yZW1vdmVQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIocGwpOworICAgICAgICAgICAgcHJlZi5yZW1vdmVQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIocGwpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlTm9kZUNoYW5nZUxpc3RlbmVyKCkgeworICAgICAgICBQcmVmZXJlbmNlcyBwcmVmID0gUHJlZmVyZW5jZXMudXNlck5vZGVGb3JQYWNrYWdlKFByZWZlcmVuY2VzLmNsYXNzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByZWYucmVtb3ZlTm9kZUNoYW5nZUxpc3RlbmVyKG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBNb2NrTm9kZUNoYW5nZUxpc3RlbmVyIGwxID0gbmV3IE1vY2tOb2RlQ2hhbmdlTGlzdGVuZXIoKTsKKyAgICAgICAgTW9ja05vZGVDaGFuZ2VMaXN0ZW5lciBsMiA9IG5ldyBNb2NrTm9kZUNoYW5nZUxpc3RlbmVyKCk7CisgICAgICAgIHByZWYuYWRkTm9kZUNoYW5nZUxpc3RlbmVyKGwxKTsKKyAgICAgICAgcHJlZi5hZGROb2RlQ2hhbmdlTGlzdGVuZXIobDEpOworCisgICAgICAgIHByZWYucmVtb3ZlTm9kZUNoYW5nZUxpc3RlbmVyKGwxKTsKKyAgICAgICAgcHJlZi5yZW1vdmVOb2RlQ2hhbmdlTGlzdGVuZXIobDEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5yZW1vdmVOb2RlQ2hhbmdlTGlzdGVuZXIobDEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5yZW1vdmVOb2RlQ2hhbmdlTGlzdGVuZXIobDIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIoKSB7CisgICAgICAgIFByZWZlcmVuY2VzIHByZWYgPSBQcmVmZXJlbmNlcy51c2VyTm9kZUZvclBhY2thZ2UoUHJlZmVyZW5jZXMuY2xhc3MpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5yZW1vdmVQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIE1vY2tQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIgbDEgPSBuZXcgTW9ja1ByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcigpOworICAgICAgICBNb2NrUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyIGwyID0gbmV3IE1vY2tQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIoKTsKKyAgICAgICAgcHJlZi5hZGRQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIobDEpOworICAgICAgICBwcmVmLmFkZFByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcihsMSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmVmLnJlbW92ZVByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcihsMik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHByZWYucmVtb3ZlUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyKGwxKTsKKyAgICAgICAgcHJlZi5yZW1vdmVQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIobDEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJlZi5yZW1vdmVQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIobDEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIE1vY2tOb2RlQ2hhbmdlTGlzdGVuZXIgaW1wbGVtZW50cyBOb2RlQ2hhbmdlTGlzdGVuZXIgeworICAgICAgICBwcml2YXRlIGludCBhZGRlZCA9IDA7CisgICAgICAgIHByaXZhdGUgaW50IHJlbW92ZWQgPSAwOworCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCB3YWl0Rm9yRXZlbnQoKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHdhaXQoNTAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjaGlsZEFkZGVkKE5vZGVDaGFuZ2VFdmVudCBlKSB7CisgICAgICAgICAgICArK2FkZGVkOworICAgICAgICAgICAgbm90aWZ5QWxsKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2hpbGRSZW1vdmVkKE5vZGVDaGFuZ2VFdmVudCBlKSB7CisgICAgICAgICAgICByZW1vdmVkKys7CisgICAgICAgICAgICBub3RpZnlBbGwoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgIGludCBnZXRBZGRlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBhZGRlZDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldFJlbW92ZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gcmVtb3ZlZDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgICAgICAgICAgYWRkZWQgPSAwOworICAgICAgICAgICAgcmVtb3ZlZCA9IDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBNb2NrUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyIGltcGxlbWVudHMgUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyIHsKKyAgICAgICAgcHJpdmF0ZSBpbnQgY2hhbmdlZCA9IDA7CisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBhZGREaXNwYXRjaGVkID0gZmFsc2U7CisgICAgICAgIHByaXZhdGUgYm9vbGVhbiByZXN1bHQgPSBmYWxzZTsKKworICAgICAgICBwdWJsaWMgdm9pZCB3YWl0Rm9yRXZlbnQoaW50IGNvdW50KSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHdhaXQoNTAwKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcHJlZmVyZW5jZUNoYW5nZShQcmVmZXJlbmNlQ2hhbmdlRXZlbnQgcGNlKSB7CisgICAgICAgICAgICBjaGFuZ2VkKys7CisgICAgICAgICAgICBhZGREaXNwYXRjaGVkID0gdHJ1ZTsKKyAgICAgICAgICAgIG5vdGlmeUFsbCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZ2V0UmVzdWx0KCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmICghYWRkRGlzcGF0Y2hlZCkgeworICAgICAgICAgICAgICAgIC8vIFRPRE86IGRvbid0IGtub3cgd2h5IG11c3QgYWRkIGxpbWl0YXRpb24KKyAgICAgICAgICAgICAgICB3YWl0KDEwMCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhZGREaXNwYXRjaGVkID0gZmFsc2U7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0Q2hhbmdlZCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoIWFkZERpc3BhdGNoZWQpIHsKKyAgICAgICAgICAgICAgICAvLyBUT0RPOiBkb24ndCBrbm93IHdoeSBtdXN0IGFkZCBsaW1pdGF0aW9uCisgICAgICAgICAgICAgICAgd2FpdCgxMDAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFkZERpc3BhdGNoZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIHJldHVybiBjaGFuZ2VkOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcmVzZXQoKSB7CisgICAgICAgICAgICBjaGFuZ2VkID0gMDsKKyAgICAgICAgICAgIHJlc3VsdCA9IGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgICAgc3RhdGljIGNsYXNzIE1vY2tQcmVmZXJlbmNlcyBleHRlbmRzIFByZWZlcmVuY2VzIHsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBhYnNvbHV0ZVBhdGgoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nW10gY2hpbGRyZW5OYW1lcygpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBleHBvcnROb2RlKE91dHB1dFN0cmVhbSBvc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24sIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgZXhwb3J0U3VidHJlZShPdXRwdXRTdHJlYW0gb3N0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uLCBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXQoU3RyaW5nIGtleSwgU3RyaW5nIGRlZmx0KSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBnZXRCb29sZWFuKFN0cmluZyBrZXksIGJvb2xlYW4gZGVmbHQpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEJ5dGVBcnJheShTdHJpbmcga2V5LCBieXRlW10gZGVmbHQpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RG91YmxlKFN0cmluZyBrZXksIGRvdWJsZSBkZWZsdCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGZsb2F0IGdldEZsb2F0KFN0cmluZyBrZXksIGZsb2F0IGRlZmx0KSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IGdldEludChTdHJpbmcga2V5LCBpbnQgZGVmbHQpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBsb25nIGdldExvbmcoU3RyaW5nIGtleSwgbG9uZyBkZWZsdCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNVc2VyTm9kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nW10ga2V5cygpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBuYW1lKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFByZWZlcmVuY2VzIG5vZGUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIG5vZGVFeGlzdHMoU3RyaW5nIG5hbWUpIHRocm93cyBCYWNraW5nU3RvcmVFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBQcmVmZXJlbmNlcyBwYXJlbnQoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBwdXQoU3RyaW5nIGtleSwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcHV0Qm9vbGVhbihTdHJpbmcga2V5LCBib29sZWFuIHZhbHVlKSB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcHV0Qnl0ZUFycmF5KFN0cmluZyBrZXksIGJ5dGVbXSB2YWx1ZSkgeworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHB1dERvdWJsZShTdHJpbmcga2V5LCBkb3VibGUgdmFsdWUpIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBwdXRGbG9hdChTdHJpbmcga2V5LCBmbG9hdCB2YWx1ZSkgeworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHB1dEludChTdHJpbmcga2V5LCBpbnQgdmFsdWUpIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBwdXRMb25nKFN0cmluZyBrZXksIGxvbmcgdmFsdWUpIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoU3RyaW5nIGtleSkgeworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZU5vZGUoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBhZGROb2RlQ2hhbmdlTGlzdGVuZXIoTm9kZUNoYW5nZUxpc3RlbmVyIG5jbCkgeworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGFkZFByZWZlcmVuY2VDaGFuZ2VMaXN0ZW5lcihQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIgcGNsKSB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlTm9kZUNoYW5nZUxpc3RlbmVyKE5vZGVDaGFuZ2VMaXN0ZW5lciBuY2wpIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmVQcmVmZXJlbmNlQ2hhbmdlTGlzdGVuZXIoUHJlZmVyZW5jZUNoYW5nZUxpc3RlbmVyIHBjbCkgeworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHN5bmMoKSB0aHJvd3MgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvcHJlZnMvUHJlZmVyZW5jZXNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvcHJlZnMvUHJlZmVyZW5jZXNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTU2MGZiZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9wcmVmcy9QcmVmZXJlbmNlc1Rlc3QuamF2YQpAQCAtMCwwICsxLDYwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC5wcmVmczsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVXcml0ZXI7CitpbXBvcnQgamF2YS51dGlsLnByZWZzLlByZWZlcmVuY2VzOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIFByZWZlcmVuY2VzVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBwcmVmZXJlbmNlcyBBUEkgaXMgZGVzaWduZWQgdG8gYmUgaG9zdGlsZSB0b3dhcmRzIGZpbGVzIHRoYXQgZXhpc3QKKyAgICAgKiB3aGVyZSBpdCB3YW50cyB0byBzdG9yZSBpdHMgWE1MIGRhdGEuIGh0dHA6Ly9iLzM0MzEyMzMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJlZmVyZW5jZXNDbG9iYmVyc0V4aXN0aW5nRmlsZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZSB1c2VyUHJlZnMgPSBuZXcgRmlsZShTeXN0ZW0uZ2V0UHJvcGVydHkoInVzZXIuaG9tZSIpICsgIi8uamF2YS8udXNlclByZWZzL3ByZWZzLnhtbCIpOworICAgICAgICBGaWxlV3JpdGVyIHdyaXRlciA9IG5ldyBGaWxlV3JpdGVyKHVzZXJQcmVmcyk7CisgICAgICAgIHdyaXRlci53cml0ZSgibGFtYiIpOworICAgICAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICAgICAgdXNlclByZWZzLnNldFJlYWRhYmxlKGZhbHNlKTsKKyAgICAgICAgdXNlclByZWZzLnNldFdyaXRhYmxlKGZhbHNlKTsKKyAgICAgICAgbG9uZyBvbGRMZW5ndGggPSB1c2VyUHJlZnMubGVuZ3RoKCk7CisKKyAgICAgICAgUHJlZmVyZW5jZXMgdXNlclByZWZlcmVuY2VzID0gUHJlZmVyZW5jZXMudXNlclJvb3QoKTsKKyAgICAgICAgdXNlclByZWZlcmVuY2VzLnN5bmMoKTsKKyAgICAgICAgdXNlclByZWZlcmVuY2VzLnB1dCgiYSIsICJsaW9uIik7CisgICAgICAgIHVzZXJQcmVmZXJlbmNlcy5mbHVzaCgpOworICAgICAgICBhc3NlcnRUcnVlKCJFeHBlY3RlZCB0byBleGlzdCAiICsgdXNlclByZWZzLCB1c2VyUHJlZnMuZXhpc3RzKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJFeHBlY3RlZCBmaWxlIHRvIGJlIGNsb2JiZXJlZCIsIG9sZExlbmd0aCAhPSB1c2VyUHJlZnMubGVuZ3RoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RIdG1sRW5jb2RpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJlZmVyZW5jZXMgcGFyZW50ID0gUHJlZmVyZW5jZXMudXNlck5vZGVGb3JQYWNrYWdlKHRoaXMuZ2V0Q2xhc3MoKSk7CisgICAgICAgIFByZWZlcmVuY2VzIHAgPSBwYXJlbnQubm9kZSgidGVzdEh0bWxFbmNvZGluZyIpOworICAgICAgICBwLnB1dCgia2V5IiwgImE8PiYnXCJcXGIiKTsKKyAgICAgICAgcC5mbHVzaCgpOworCisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBwLmV4cG9ydE5vZGUoYmFvcyk7CisKKyAgICAgICAgU3RyaW5nIHMgPSBuZXcgU3RyaW5nKGJhb3MudG9CeXRlQXJyYXkoKSwgIlVURi04Iik7CisgICAgICAgIGFzc2VydFRydWUocywgcy5jb250YWlucygidmFsdWU9XCJhJmx0OyZndDsmYW1wOycmcXVvdDtcXGJcIiIpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvcmVnZXgvT2xkTWF0Y2hlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC9yZWdleC9PbGRNYXRjaGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ1MGI4ZDkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvcmVnZXgvT2xkTWF0Y2hlclRlc3QuamF2YQpAQCAtMCwwICsxLDU4MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC5yZWdleDsKKworaW1wb3J0IGphdmEudXRpbC5yZWdleC5NYXRjaGVyOworaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE9sZE1hdGNoZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIFN0cmluZ1tdIGdyb3VwUGF0dGVybnMgPSB7ICIoYXxiKSphYWJiIiwgIigoYSl8YikqYWFiYiIsICIoKGF8YikqKWEoYWJiKSIsCisgICAgICAgICAgICAiKCgoYSl8KGIpKSopYWFiYiIsICIoKChhKXwoYikpKilhYShiKWIiLCAiKCgoYSl8KGIpKSopYShhKGIpYikiIH07CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXBwZW5kUmVwbGFjZW1lbnQoKSB7CisgICAgICAgIFBhdHRlcm4gcGF0ID0gUGF0dGVybi5jb21waWxlKCJYWCIpOworICAgICAgICBNYXRjaGVyIG0gPSBwYXQubWF0Y2hlcigiVG9kYXkgaXMgWFgtWFgtWFggLi4uIik7CisgICAgICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgbS5maW5kKCk7IGkrKykgeworICAgICAgICAgICAgbS5hcHBlbmRSZXBsYWNlbWVudChzYiwgbmV3IEludGVnZXIoaSAqIDEwICsgaSkudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgICAgbS5hcHBlbmRUYWlsKHNiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUb2RheSBpcyAwLTExLTIyIC4uLiIsIHNiLnRvU3RyaW5nKCkpOworCisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiY2F0Iik7CisgICAgICAgIG0gPSBwYXQubWF0Y2hlcigib25lLWNhdC10d28tY2F0cy1pbi10aGUteWFyZCIpOworICAgICAgICBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgVGhyb3dhYmxlIHQgPSBudWxsOworICAgICAgICBtLmZpbmQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG0uYXBwZW5kUmVwbGFjZW1lbnQobnVsbCwgImRvZyIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0ID0gZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROb3ROdWxsKHQpOworICAgICAgICB0ID0gbnVsbDsKKyAgICAgICAgbS5maW5kKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLmFwcGVuZFJlcGxhY2VtZW50KHNiLCBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdCA9IGU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Jlc2V0TGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZyB0ZXN0UGF0dGVybiA9ICIoYWJiKSI7CisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nMSA9ICJiYWJiYWJiY2NjYWJiYWJiYWJiYWJiYWJiIjsKKyAgICAgICAgU3RyaW5nIHRlc3RTdHJpbmcyID0gImNkZGNkZGNkZGNkZGNkZGJiYmIiOworICAgICAgICBQYXR0ZXJuIHBhdCA9IFBhdHRlcm4uY29tcGlsZSh0ZXN0UGF0dGVybik7CisgICAgICAgIE1hdGNoZXIgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZzEpOworCisgICAgICAgIHdoaWxlIChtYXQuZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXNldCBzaG91bGQgcmV0dXJuIGl0c2VsZiAxIiwgbWF0LCBtYXQucmVzZXQodGVzdFN0cmluZzIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkFmdGVyIHJlc2V0IG1hdGNoZXIgc2hvdWxkIG5vdCBmaW5kIHBhdHRlcm4gaW4gZ2l2ZW4gaW5wdXQiLCBtYXQuZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXNldCBzaG91bGQgcmV0dXJuIGl0c2VsZiAyIiwgbWF0LCBtYXQucmVzZXQodGVzdFN0cmluZzEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQWZ0ZXIgcmVzZXQgbWF0Y2hlciBzaG91bGQgZmluZCBwYXR0ZXJuIGluIGdpdmVuIGlucHV0IiwgbWF0LmZpbmQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFwcGVuZFRhaWwoKSB7CisgICAgICAgIFBhdHRlcm4gcCA9IFBhdHRlcm4uY29tcGlsZSgiY2F0Iik7CisgICAgICAgIE1hdGNoZXIgbSA9IHAubWF0Y2hlcigib25lLWNhdC10d28tY2F0cy1pbi10aGUteWFyZCIpOworICAgICAgICBTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIHdoaWxlIChtLmZpbmQoKSkgeworICAgICAgICAgICAgbS5hcHBlbmRSZXBsYWNlbWVudChzYiwgImRvZyIpOworICAgICAgICB9CisgICAgICAgIG0uYXBwZW5kVGFpbChzYik7CisgICAgICAgIGFzc2VydEVxdWFscygib25lLWRvZy10d28tZG9ncy1pbi10aGUteWFyZCIsIHNiLnRvU3RyaW5nKCkpOworCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoImNhdHx5YXJkIik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIm9uZS1jYXQtdHdvLWNhdHMtaW4tdGhlLXlhcmQiKTsKKyAgICAgICAgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIHdoaWxlIChtLmZpbmQoKSkgeworICAgICAgICAgICAgbS5hcHBlbmRSZXBsYWNlbWVudChzYiwgImRvZyIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygib25lLWRvZy10d28tZG9ncy1pbi10aGUtZG9nIiwgc2IudG9TdHJpbmcoKSk7CisgICAgICAgIG0uYXBwZW5kVGFpbChzYik7CisgICAgICAgIGFzc2VydEVxdWFscygib25lLWRvZy10d28tZG9ncy1pbi10aGUtZG9nIiwgc2IudG9TdHJpbmcoKSk7CisKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiY2F0Iik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIm9uZS1jYXQtdHdvLWNhdHMtaW4tdGhlLXlhcmQiKTsKKyAgICAgICAgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIHdoaWxlIChtLmZpbmQoKSkgeworICAgICAgICAgICAgbS5hcHBlbmRSZXBsYWNlbWVudChzYiwgImRvZyIpOworICAgICAgICB9CisgICAgICAgIFRocm93YWJsZSB0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG0uYXBwZW5kVGFpbChudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdCA9IGU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Jlc2V0KCkgeworICAgICAgICBTdHJpbmcgdGVzdFBhdHRlcm4gPSAiKGFiYikiOworICAgICAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJiYWJiYWJiY2NjYWJiYWJiYWJiYWJiYWJiIjsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUodGVzdFBhdHRlcm4pOworICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworCisgICAgICAgIHdoaWxlIChtYXQuZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXNldCBzaG91bGQgcmV0dXJuIGl0c2VsZiIsIG1hdCwgbWF0LnJlc2V0KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJBZnRlciByZXNldCBtYXRjaGVyIHNob3VsZCBmaW5kIHBhdHRlcm4gaW4gZ2l2ZW4gaW5wdXQiLCBtYXQuZmluZCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc0FuY2hvcmluZ0JvdW5kcygpIHsKKyAgICAgICAgU3RyaW5nIHRlc3RQYXR0ZXJuID0gImFiYiI7CisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gImFiYiI7CisgICAgICAgIFBhdHRlcm4gcGF0ID0gUGF0dGVybi5jb21waWxlKHRlc3RQYXR0ZXJuKTsKKyAgICAgICAgTWF0Y2hlciBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJNYXRjaGVyIHVzZXMgYW5jaG9yaW5nIGJvdW5kIGJ5IGRlZmF1bHQiLAorICAgICAgICAgICAgICAgIG1hdC5oYXNBbmNob3JpbmdCb3VuZHMoKSk7CisKKyAgICAgICAgTWF0Y2hlciBtdSA9IG1hdC51c2VBbmNob3JpbmdCb3VuZHModHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCB2YWx1ZSBvZiBhbmNob3JpbmcgYm91bmRzIiwKKyAgICAgICAgICAgICAgICBtdS5oYXNBbmNob3JpbmdCb3VuZHMoKSk7CisKKyAgICAgICAgbXUgPSBtYXQudXNlQW5jaG9yaW5nQm91bmRzKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkluY29ycmVjdCB2YWx1ZSBvZiBhbmNob3JpbmcgYm91bmRzIiwKKyAgICAgICAgICAgICAgICBtdS5oYXNBbmNob3JpbmdCb3VuZHMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNUcmFuc3BhcmVudEJvdW5kcygpIHsKKyAgICAgICAgU3RyaW5nIHRlc3RQYXR0ZXJuID0gImFiYiI7CisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gImFiXG5iIjsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUodGVzdFBhdHRlcm4pOworICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworCisgICAgICAgIGFzc2VydEZhbHNlKCJNYXRjaGVyIHVzZXMgb3BhcXVlIGJvdW5kcyBieSBkZWZhdWx0IiwKKyAgICAgICAgICAgICAgICBtYXQuaGFzVHJhbnNwYXJlbnRCb3VuZHMoKSk7CisKKyAgICAgICAgTWF0Y2hlciBtdSA9IG1hdC51c2VUcmFuc3BhcmVudEJvdW5kcyh0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHZhbHVlIG9mIGFuY2hvcmluZyBib3VuZHMiLAorICAgICAgICAgICAgICAgIG11Lmhhc1RyYW5zcGFyZW50Qm91bmRzKCkpOworCisgICAgICAgIG11ID0gbWF0LnVzZVRyYW5zcGFyZW50Qm91bmRzKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkluY29ycmVjdCB2YWx1ZSBvZiBhbmNob3JpbmcgYm91bmRzIiwKKyAgICAgICAgICAgICAgICBtdS5oYXNUcmFuc3BhcmVudEJvdW5kcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N0YXJ0SSgpIHsKKyAgICAgICAgU3RyaW5nIHRlc3RQYXR0ZXJuID0gIigoKGFiYilhKShiYikpIjsKKyAgICAgICAgU3RyaW5nIHRlc3RTdHJpbmcgPSAiY2NjYWJiYWJiYWJiYWJiYWJiIjsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUodGVzdFBhdHRlcm4pOworICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBpbnQgc3RhcnQgPSAzOworICAgICAgICBpbnQgZW5kID0gNjsKKyAgICAgICAgaW50IGksIGo7CisKKyAgICAgICAgZm9yIChqID0gMDsgaiA8IDM7IGorKykgeworICAgICAgICAgICAgd2hpbGUgKG1hdC5maW5kKHN0YXJ0ICsgaiAtIDIpKSB7CisgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlN0YXJ0IGlzIHdyb25nIGZvciBncm91cCAiICsgaSArICIgOiIgKyBtYXQuZ3JvdXAoaSksIHN0YXJ0LCBtYXQuc3RhcnQoaSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlN0YXJ0IGlzIHdyb25nIGZvciBncm91cCAiICsgaSArICIgOiIgKyBtYXQuZ3JvdXAoaSksIHN0YXJ0ICsgNCwgbWF0LnN0YXJ0KGkpKTsKKworICAgICAgICAgICAgICAgIHN0YXJ0ID0gZW5kOworICAgICAgICAgICAgICAgIGVuZCArPSAzOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9lbmRJKCkgeworICAgICAgICBTdHJpbmcgdGVzdFBhdHRlcm4gPSAiKCgoYWJiKWEpKGJiKSkiOworICAgICAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJjY2NhYmJhYmJhYmJhYmJhYmIiOworICAgICAgICBQYXR0ZXJuIHBhdCA9IFBhdHRlcm4uY29tcGlsZSh0ZXN0UGF0dGVybik7CisgICAgICAgIE1hdGNoZXIgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGludCBzdGFydCA9IDM7CisgICAgICAgIGludCBlbmQgPSA2OworICAgICAgICBpbnQgaSwgajsKKworICAgICAgICBmb3IgKGogPSAwOyBqIDwgMzsgaisrKSB7CisgICAgICAgICAgICB3aGlsZSAobWF0LmZpbmQoc3RhcnQgKyBqIC0gMikpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiRW5kIGlzIHdyb25nIGZvciBncm91cCAiICsgaSArICIgOiIgKyBtYXQuZ3JvdXAoaSksIHN0YXJ0ICsgbWF0Lmdyb3VwKGkpLmxlbmd0aCgpLCBtYXQuZW5kKGkpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJFbmQgaXMgd3JvbmcgZm9yIGdyb3VwICIgKyBpICsgIiA6IiArIG1hdC5ncm91cChpKSwgc3RhcnQgKyA0ICsgbWF0Lmdyb3VwKGkpLmxlbmd0aCgpLCBtYXQuZW5kKGkpKTsKKworICAgICAgICAgICAgICAgIHN0YXJ0ID0gZW5kOworICAgICAgICAgICAgICAgIGVuZCArPSAzOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xvb2tpbmdBdCgpIHsKKyAgICAgICAgU3RyaW5nIHRlc3RQYXR0ZXJuID0gIigoKGFiYilhKShiYikpIjsKKyAgICAgICAgU3RyaW5nIHRlc3RTdHJpbmcxID0gImJhYmJhYmJjY2NhYmJhYmJhYmJhYmJhYmIiOworICAgICAgICBTdHJpbmcgdGVzdFN0cmluZzIgPSAiYWJiYWJiIjsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUodGVzdFBhdHRlcm4pOworICAgICAgICBNYXRjaGVyIG1hdDEgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nMSk7CisgICAgICAgIE1hdGNoZXIgbWF0MiA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcyKTsKKworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIG5vdCBmaW5kIGdpdmVuIHBhdHRlcm4gaW4gMSBzdHJpbmciLCBtYXQxLmxvb2tpbmdBdCgpKTsKKyAgICAgICAgbWF0MS5yZWdpb24oMSwgMTApOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgZmluZCBnaXZlbiBwYXR0ZXJuIGluIHJlZ2lvbiBvZiBzdHJpbmciLCBtYXQxLmxvb2tpbmdBdCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGZpbmQgZ2l2ZW4gcGF0dGVybiBpbiAyIHN0cmluZyIsIG1hdDIubG9va2luZ0F0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmluZEkoKSB7CisgICAgICAgIFN0cmluZyB0ZXN0UGF0dGVybiA9ICIoYWJiKSI7CisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gImNjY2FiYmFiYmFiYmFiYmFiYiI7CisgICAgICAgIFBhdHRlcm4gcGF0ID0gUGF0dGVybi5jb21waWxlKHRlc3RQYXR0ZXJuKTsKKyAgICAgICAgTWF0Y2hlciBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgaW50IHN0YXJ0ID0gMzsKKyAgICAgICAgaW50IGVuZCA9IDY7CisgICAgICAgIGludCBqOworCisgICAgICAgIGZvciAoaiA9IDA7IGogPCAzOyBqKyspIHsKKyAgICAgICAgICAgIHdoaWxlIChtYXQuZmluZChzdGFydCArIGogLSAyKSkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhzdGFydCwgbWF0LnN0YXJ0KDEpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZW5kLCBtYXQuZW5kKDEpKTsKKworICAgICAgICAgICAgICAgIHN0YXJ0ID0gZW5kOworICAgICAgICAgICAgICAgIGVuZCArPSAzOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3RhcnQgPSA2OworICAgICAgICAgICAgZW5kID0gOTsKKyAgICAgICAgfQorCisgICAgICAgIHRlc3RQYXR0ZXJuID0gIihcXGR7MSwzfSkiOworICAgICAgICB0ZXN0U3RyaW5nID0gImFhYWExMjM0NTY3ODkwNDUiOworCisgICAgICAgIFBhdHRlcm4gcGF0MiA9IFBhdHRlcm4uY29tcGlsZSh0ZXN0UGF0dGVybik7CisgICAgICAgIE1hdGNoZXIgbWF0MiA9IHBhdDIubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgc3RhcnQgPSA0OworICAgICAgICBpbnQgbGVuZ3RoID0gMzsKKyAgICAgICAgZm9yIChqID0gMDsgaiA8IGxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gNCArIGo7IGkgPCB0ZXN0U3RyaW5nLmxlbmd0aCgpIC0gbGVuZ3RoOyBpICs9IGxlbmd0aCkgeworICAgICAgICAgICAgICAgIG1hdDIuZmluZChpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHModGVzdFN0cmluZy5zdWJzdHJpbmcoaSwgaSArIGxlbmd0aCksIG1hdDIuZ3JvdXAoMSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gU3RhcnRpbmcgaW5kZXggb3V0IG9mIHJlZ2lvbgorICAgICAgICBQYXR0ZXJuIHBhdDMgPSBQYXR0ZXJuLmNvbXBpbGUoIm5ldyIpOworICAgICAgICBNYXRjaGVyIG1hdDMgPSBwYXQzLm1hdGNoZXIoIkJyYXZlIG5ldyB3b3JsZCIpOworCisgICAgICAgIGFzc2VydFRydWUobWF0My5maW5kKC0xKSk7CisgICAgICAgIGFzc2VydFRydWUobWF0My5maW5kKDYpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWF0My5maW5kKDcpKTsKKworICAgICAgICBtYXQzLnJlZ2lvbig3LCAxMCk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UobWF0My5maW5kKDMpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWF0My5maW5kKDYpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWF0My5maW5kKDcpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U0VPTHN5bWJvbHMoKSB7CisgICAgICAgIFBhdHRlcm4gcGF0ID0gUGF0dGVybi5jb21waWxlKCJeYVxcKGJiXFxbJCIpOworICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKCJhKGJiWyIpOworCisgICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdGFydCgpIHsKKyAgICAgICAgU3RyaW5nIHRlc3RQYXR0ZXJuID0gIihhYmIpIjsKKyAgICAgICAgU3RyaW5nIHRlc3RTdHJpbmcgPSAiY2NjYWJiYWJiYWJiYWJiYWJiIjsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUodGVzdFBhdHRlcm4pOworICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBpbnQgc3RhcnQgPSAzOworICAgICAgICBpbnQgZW5kID0gNjsKKyAgICAgICAgaW50IGo7CisKKyAgICAgICAgZm9yIChqID0gMDsgaiA8IDM7IGorKykgeworICAgICAgICAgICAgd2hpbGUgKG1hdC5maW5kKCkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlN0YXJ0IGlzIHdyb25nIiwgc3RhcnQsIG1hdC5zdGFydCgpKTsKKworICAgICAgICAgICAgICAgIHN0YXJ0ID0gZW5kOworICAgICAgICAgICAgICAgIGVuZCArPSAzOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9lbmQoKSB7CisgICAgICAgIFN0cmluZyB0ZXN0UGF0dGVybiA9ICIoYWJiKSI7CisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gImNjY2FiYmFiYmFiYmFiYmFiYiI7CisgICAgICAgIFBhdHRlcm4gcGF0ID0gUGF0dGVybi5jb21waWxlKHRlc3RQYXR0ZXJuKTsKKyAgICAgICAgTWF0Y2hlciBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgaW50IHN0YXJ0ID0gMzsKKyAgICAgICAgaW50IGVuZCA9IDY7CisgICAgICAgIGludCBqOworCisgICAgICAgIGZvciAoaiA9IDA7IGogPCAzOyBqKyspIHsKKyAgICAgICAgICAgIHdoaWxlIChtYXQuZmluZCgpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJTdGFydCBpcyB3cm9uZyIsIGVuZCwgbWF0LmVuZCgpKTsKKworICAgICAgICAgICAgICAgIHN0YXJ0ID0gZW5kOworICAgICAgICAgICAgICAgIGVuZCArPSAzOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdyb3VwQ291bnQoKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ3JvdXBQYXR0ZXJucy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgUGF0dGVybiB0ZXN0ID0gUGF0dGVybi5jb21waWxlKGdyb3VwUGF0dGVybnNbaV0pOworICAgICAgICAgICAgTWF0Y2hlciBtYXQgPSB0ZXN0Lm1hdGNoZXIoImFiYWJhYmFiYmFhYWJiIik7CisgICAgICAgICAgICBtYXQubWF0Y2hlcygpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGkgKyAxLCBtYXQuZ3JvdXBDb3VudCgpKTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgcHVibGljIHZvaWQgdGVzdFJlZ2lvbigpIHsKKyAgICAgICAgUGF0dGVybiBwID0gUGF0dGVybi5jb21waWxlKCJhYmJhIik7CisgICAgICAgIE1hdGNoZXIgbSA9IHAubWF0Y2hlcigiR2FiYmEgZ2FiYmEgaGV5Iik7CisKKyAgICAgICAgbS5yZWdpb24oMCwgMTUpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKworICAgICAgICBtLnJlZ2lvbig1LCAxNSk7CisgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICBhc3NlcnRGYWxzZShtLmZpbmQoKSk7CisKKyAgICAgICAgbS5yZWdpb24oMTAsIDE1KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5maW5kKCkpOworCisgICAgICAgIFRocm93YWJsZSB0ID0gbnVsbDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbS5yZWdpb24oLTEsIDE1KTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0ID0gZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROb3ROdWxsKHQpOworCisgICAgICAgIHQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbS5yZWdpb24oMCwgMTYpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHQgPSBlOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwodCk7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF0Y2hlc1VSSSgpIHsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLgorICAgICAgICAgICAgICAgIGNvbXBpbGUoIl4oLy8oW14vPyNdKikpPyhbXj8jXSopKFxcPyhbXiNdKikpPygjKC4qKSk/Iik7CisgICAgICAgIE1hdGNoZXIgbWF0ID0gcGF0CisgICAgICAgICAgICAgICAgLm1hdGNoZXIoImZpbGU6L2M6L3dvcmtzcGFjZS9hcGkvYnVpbGQud2luMzIvY2xhc3Nlcy9NRVRBLUlORi8iCisgICAgICAgICAgICAgICAgICAgICAgICArICJzZXJ2aWNlcy9qYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5Iik7CisgICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UXVvdGVSZXBsYWNlbWVudCgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJcXCRkb2xsYXIgYW5kIHNsYXNoXFxcXCIsIE1hdGNoZXIucXVvdGVSZXBsYWNlbWVudCgiJGRvbGxhciBhbmQgc2xhc2hcXCIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VW5pY29kZSgpIHsKKworICAgICAgICBhc3NlcnRUcnVlKFBhdHRlcm4uY29tcGlsZSgiXFx4NjFhIikubWF0Y2hlcigiYWEiKS5tYXRjaGVzKCkpOworLy8gICAgICAgIGFzc2VydFRydWUoUGF0dGVybi5tYXRjaGVzKCJcXHUwMDYxYSIsICJhYSIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShQYXR0ZXJuLmNvbXBpbGUoIlxcMDE0MWEiKS5tYXRjaGVyKCJhYSIpLm1hdGNoZXMoKSk7CisgICAgICAgIGFzc2VydFRydWUoUGF0dGVybi5jb21waWxlKCJcXDA3NzciKS5tYXRjaGVyKCI/NyIpLm1hdGNoZXMoKSk7CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VW5pY29kZUNhdGVnb3J5KCkgeworICAgICAgICBhc3NlcnRUcnVlKFBhdHRlcm4uY29tcGlsZSgiXFxwe0xsfSIpLm1hdGNoZXIoImsiKS5tYXRjaGVzKCkpOyAvLyBVbmljb2RlIGxvd2VyIGNhc2UKKyAgICAgICAgYXNzZXJ0VHJ1ZShQYXR0ZXJuLmNvbXBpbGUoIlxcUHtMbH0iKS5tYXRjaGVyKCJLIikubWF0Y2hlcygpKTsgLy8gVW5pY29kZSBub24tbG93ZXIKKyAgICAgICAgLy8gY2FzZQorICAgICAgICBhc3NlcnRUcnVlKFBhdHRlcm4uY29tcGlsZSgiXFxwe0x1fSIpLm1hdGNoZXIoIksiKS5tYXRjaGVzKCkpOyAvLyBVbmljb2RlIHVwcGVyIGNhc2UKKyAgICAgICAgYXNzZXJ0VHJ1ZShQYXR0ZXJuLmNvbXBpbGUoIlxcUHtMdX0iKS5tYXRjaGVyKCJrIikubWF0Y2hlcygpKTsgLy8gVW5pY29kZSBub24tdXBwZXIKKyAgICAgICAgLy8gY2FzZQorICAgICAgICAvLyBjb21iaW5hdGlvbnMKKyAgICAgICAgYXNzZXJ0VHJ1ZShQYXR0ZXJuLmNvbXBpbGUoIltcXHB7TH0mJlteXFxwe0x1fV1dIikubWF0Y2hlcigiayIpLm1hdGNoZXMoKSk7CisgICAgICAgIGFzc2VydFRydWUoUGF0dGVybi5jb21waWxlKCJbXFxwe0x9JiZbXlxccHtMbH1dXSIpLm1hdGNoZXIoIksiKS5tYXRjaGVzKCkpOworICAgICAgICBhc3NlcnRGYWxzZShQYXR0ZXJuLmNvbXBpbGUoIltcXHB7TH0mJlteXFxwe0x1fV1dIikubWF0Y2hlcigiSyIpLm1hdGNoZXMoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKFBhdHRlcm4uY29tcGlsZSgiW1xccHtMfSYmW15cXHB7TGx9XV0iKS5tYXRjaGVyKCJrIikubWF0Y2hlcygpKTsKKworICAgICAgICAvLyBjYXRlZ29yeS9jaGFyYWN0ZXIgY29tYmluYXRpb25zCisgICAgICAgIGFzc2VydEZhbHNlKFBhdHRlcm4uY29tcGlsZSgiW1xccHtMfSYmW15hLXpdXSIpLm1hdGNoZXIoImsiKS5tYXRjaGVzKCkpOworICAgICAgICBhc3NlcnRUcnVlKFBhdHRlcm4uY29tcGlsZSgiW1xccHtMfSYmW15hLXpdXSIpLm1hdGNoZXIoIksiKS5tYXRjaGVzKCkpOworCisgICAgICAgIGFzc2VydFRydWUoUGF0dGVybi5jb21waWxlKCJbXFxwe0x1fWEtel0iKS5tYXRjaGVyKCJrIikubWF0Y2hlcygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShQYXR0ZXJuLmNvbXBpbGUoIlthLXpcXHB7THV9XSIpLm1hdGNoZXIoImsiKS5tYXRjaGVzKCkpOworCisgICAgICAgIGFzc2VydEZhbHNlKFBhdHRlcm4uY29tcGlsZSgiW1xccHtMdX1hLWRdIikubWF0Y2hlcigiayIpLm1hdGNoZXMoKSk7CisgICAgICAgIGFzc2VydFRydWUoUGF0dGVybi5jb21waWxlKCJbYS1kXFxwe0x1fV0iKS5tYXRjaGVyKCJLIikubWF0Y2hlcygpKTsKKworICAgICAgICAvLyAgICAgICAgYXNzZXJ0VHJ1ZShQYXR0ZXJuLm1hdGNoZXMoIltcXHB7TH0mJlteXFxwe0x1fSYmW15LXV1dIiwgIksiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKFBhdHRlcm4uY29tcGlsZSgiW1xccHtMfSYmW15cXHB7THV9JiZbXkddXV0iKS5tYXRjaGVyKCJLIikubWF0Y2hlcygpKTsKKworICAgIH0KKworICAgIC8vIEJFR0lOIGFuZHJvaWQtbm90ZQorICAgIC8vIFRlc3QgdG9vayBhZ2VzLCBub3cgZ29pbmcgaW4gc3RlcHMgb2YgMTYgY29kZSBwb2ludHMgdG8gc3BlZWQgdGhpbmdzIHVwLgorICAgIC8vIEVORCBhbmRyb2lkLW5vdGUKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWxsQ29kZVBvaW50cygpIHsKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS0zMTQ1CisgICAgICAgIGludFtdIGNvZGVQb2ludCA9IG5ldyBpbnRbMV07CisgICAgICAgIFBhdHRlcm4gcCA9IFBhdHRlcm4uY29tcGlsZSgiKFxccHthbGx9KSsiKTsKKyAgICAgICAgYm9vbGVhbiByZXMgPSB0cnVlOworICAgICAgICBpbnQgY250ID0gMDsKKyAgICAgICAgU3RyaW5nIHM7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMHgxMTAwMDA7IGkgPSBpICsgMHgxMCkgeworICAgICAgICAgICAgY29kZVBvaW50WzBdID0gaTsKKyAgICAgICAgICAgIHMgPSBuZXcgU3RyaW5nKGNvZGVQb2ludCwgMCwgMSk7CisgICAgICAgICAgICBpZiAoIXMubWF0Y2hlcyhwLnRvU3RyaW5nKCkpKSB7CisgICAgICAgICAgICAgICAgY250Kys7CisgICAgICAgICAgICAgICAgcmVzID0gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgY250KTsKKworICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCIoXFxQe2FsbH0pKyIpOworICAgICAgICByZXMgPSB0cnVlOworICAgICAgICBjbnQgPSAwOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMHgxMTAwMDA7IGkgPSBpICsgMHgxMCkgeworICAgICAgICAgICAgY29kZVBvaW50WzBdID0gaTsKKyAgICAgICAgICAgIHMgPSBuZXcgU3RyaW5nKGNvZGVQb2ludCwgMCwgMSk7CisgICAgICAgICAgICBpZiAoIXMubWF0Y2hlcyhwLnRvU3RyaW5nKCkpKSB7CisgICAgICAgICAgICAgICAgY250Kys7CisgICAgICAgICAgICAgICAgcmVzID0gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRGYWxzZShyZXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoMHgxMTAwMDAgLyAweDEwLCBjbnQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVnaW9uU3RhcnQoKSB7CisgICAgICAgIFN0cmluZyB0ZXN0UGF0dGVybiA9ICIoYWJiKSI7CisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gImNjY2FiYmFiYmFiYmFiYmFiYiI7CisgICAgICAgIFBhdHRlcm4gcGF0ID0gUGF0dGVybi5jb21waWxlKHRlc3RQYXR0ZXJuKTsKKyAgICAgICAgTWF0Y2hlciBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlJlZ2lvbiBzb3VsZCBzdGFydCBmcm9tIDAgcG9zaXRpb24iLCAwLCBtYXQucmVnaW9uU3RhcnQoKSk7CisgICAgICAgIG1hdC5yZWdpb24oMSwgMTApOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJlZ2lvbiBzb3VsZCBzdGFydCBmcm9tIDEgcG9zaXRpb24gYWZ0ZXIgc2V0dGluZyBuZXcgcmVnaW9uIiwgMSwgbWF0LnJlZ2lvblN0YXJ0KCkpOworICAgICAgICBtYXQucmVzZXQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZWdpb24gc291bGQgc3RhcnQgZnJvbSAwIHBvc2l0aW9uIGFmdGVyIHJlc2V0IiwgMCwgbWF0LnJlZ2lvblN0YXJ0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVnaW9uRW5kKCkgeworICAgICAgICBTdHJpbmcgdGVzdFBhdHRlcm4gPSAiKGFiYikiOworICAgICAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJjY2NhYmJhYmJhYmJhYmJhYmIiOworICAgICAgICBQYXR0ZXJuIHBhdCA9IFBhdHRlcm4uY29tcGlsZSh0ZXN0UGF0dGVybik7CisgICAgICAgIE1hdGNoZXIgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZWdpb24gZW5kIHZhbHVlIHNob3VsZCBiZSBlcXVhbCB0byBzdHJpbmcgbGVuZ3RoIiwgdGVzdFN0cmluZy5sZW5ndGgoKSwgbWF0LnJlZ2lvbkVuZCgpKTsKKyAgICAgICAgbWF0LnJlZ2lvbigxLCAxMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmVnaW9uIGVuZCB2YWx1ZSBzaG91bGQgYmUgZXF1YWwgdG8gMTAgYWZ0ZXIgc2V0dGluZyBuZXcgcmVnaW9uIiwgMTAsIG1hdC5yZWdpb25FbmQoKSk7CisgICAgICAgIG1hdC5yZXNldCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJlZ2lvbiBlbmQgdmFsdWUgc2hvdWxkIGJlIGVxdWFsIHRvIHN0cmluZyBsZW5ndGggYWZ0ZXIgcmVzZXQiLCB0ZXN0U3RyaW5nLmxlbmd0aCgpLCBtYXQucmVnaW9uRW5kKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9NYXRjaFJlc3VsdCgpIHsKKyAgICAgICAgU3RyaW5nIHRlc3RQYXR0ZXJuID0gIigoKGFiYilhKShiYikpIjsKKyAgICAgICAgU3RyaW5nIHRlc3RTdHJpbmcgPSAiYmFiYmFiYmNjY2FiYmFiYmFiYmFiYmFiYiI7CisgICAgICAgIFBhdHRlcm4gcGF0ID0gUGF0dGVybi5jb21waWxlKHRlc3RQYXR0ZXJuKTsKKyAgICAgICAgTWF0Y2hlciBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKworICAgICAgICBtYXQucmVnaW9uKDEsIDcpOworICAgICAgICBhc3NlcnRUcnVlKCJtYXRjaGVyIHNob3VsZCBmaW5kIHBhdHRlcm4gaW4gZ2l2ZW4gcmVnaW9uIiwgbWF0Lm1hdGNoZXMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibWF0Y2hlZCBzZWN0aW9uIHNob3VsZCBzdGFydCBmcm9tIDEgcG9zaXRpb24iLCAxLCBtYXQudG9NYXRjaFJlc3VsdCgpLnN0YXJ0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm1hdGNoZWQgc2VjdGlvbiBmb3IgMiBncm91cCBzaG91bGQgc3RhcnQgZnJvbSAxIHBvc2l0aW9uIiwgMSwgbWF0LnRvTWF0Y2hSZXN1bHQoKS5zdGFydCgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibWF0Y2hlZCBzZWN0aW9uIGZvciB3aG9sZSBwYXR0ZXJuIHNob3VsZCBlbmQgb24gNyBwb3NpdGlvbiIsIDcsIG1hdC50b01hdGNoUmVzdWx0KCkuZW5kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm1hdGNoZWQgc2VjdGlvbiBmb3IgMyBncm91cCBzaG91bGQgZW5kIGF0IDQgcG9zaXRpb24iLCA0LCBtYXQudG9NYXRjaFJlc3VsdCgpLmVuZCgzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ3JvdXAgbm90IG1hdGNoZWQiLCAiYWJiYWJiIiwgbWF0LnRvTWF0Y2hSZXN1bHQoKS5ncm91cCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIzIGdyb3VwIG5vdCBtYXRjaGVkIiwgImFiYiIsIG1hdC50b01hdGNoUmVzdWx0KCkuZ3JvdXAoMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRvdGFsIG51bWJlciBvZiBncm91cHMgZG9lcyBub3QgbWF0Y2hlZCB3aXRoIGdpdmVuIHBhdHRlcm4iLCA0LCBtYXQudG9NYXRjaFJlc3VsdCgpLmdyb3VwQ291bnQoKSk7CisgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VzZVBhdHRlcm5MamF2YV91dGlsX3JlZ2V4X1BhdHRlcm4oKSB7CisgICAgICAgIFN0cmluZyB0ZXN0UGF0dGVybjEgPSAiKCgoYWJiKWEpKGJiKSkiOworICAgICAgICBTdHJpbmcgdGVzdFBhdHRlcm4yID0gIihhYmJhYmIpIjsKKyAgICAgICAgU3RyaW5nIHRlc3RQYXR0ZXJuMyA9ICIoYmFiYikiOworICAgICAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJiYWJiYWJiY2NjYWJiYWJiYWJiYWJiYWJiIjsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUodGVzdFBhdHRlcm4xKTsKKyAgICAgICAgTWF0Y2hlciBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKworICAgICAgICBtYXQucmVnaW9uKDEsIDcpOworICAgICAgICBhc3NlcnRUcnVlKCJtYXRjaGVyIHNob3VsZCBmaW5kIHBhdHRlcm4gaW4gZ2l2ZW4gcmVnaW9uIGluIGNhc2Ugb2YgZ3JvdXBlIGluIHBhdHRlcm4iLCBtYXQubWF0Y2hlcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBtYXQsIG1hdC51c2VQYXR0ZXJuKFBhdHRlcm4uY29tcGlsZSh0ZXN0UGF0dGVybjIpKSk7CisgICAgICAgIGFzc2VydFRydWUoIm1hdGNoZXIgc2hvdWxkIGZpbmQgcGF0dGVybiBpbiBnaXZlbiByZWdpb24iLCBtYXQubWF0Y2hlcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBtYXQsIG1hdC51c2VQYXR0ZXJuKFBhdHRlcm4uY29tcGlsZSh0ZXN0UGF0dGVybjMpKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJtYXRjaGVyIHNob3VsZCBub3QgZmluZCBwYXR0ZXJuIGluIGdpdmVuIHJlZ2lvbiIsIG1hdC5tYXRjaGVzKCkpOworICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9hbmNob3JpbmdCb3VuZHMoKSB7CisgICAgICAgIFN0cmluZyB0ZXN0UGF0dGVybiA9ICJecm8kIjsKKyAgICAgICAgU3RyaW5nIHRlc3RTdHJpbmcgPSAiYW5kcm9pZCI7CisgICAgICAgIFBhdHRlcm4gcGF0ID0gUGF0dGVybi5jb21waWxlKHRlc3RQYXR0ZXJuKTsKKyAgICAgICAgTWF0Y2hlciBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKworICAgICAgICBtYXQucmVnaW9uKDIsIDUpOworICAgICAgICBtYXQudXNlQW5jaG9yaW5nQm91bmRzKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZG4ndCBmaW5kIHBhdHRlcm4gd2l0aCBub24tYW5jaG9yaW5nIGJvdW5kcyIsIG1hdC5maW5kKDApKTsKKworICAgICAgICBtYXQucmVnaW9uKDIsIDUpOworICAgICAgICBtYXQudXNlQW5jaG9yaW5nQm91bmRzKHRydWUpOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIGZpbmQgcGF0dGVybiB3aXRoIGFuY2hvcmluZyBib3VuZHMiLCBtYXQuZmluZCgwKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90cmFuc3BhcmVudEJvdW5kcygpIHsKKyAgICAgICAgU3RyaW5nIHRlc3RQYXR0ZXJuID0gImFuZCg/PXJvaWQpIjsKKyAgICAgICAgU3RyaW5nIHRlc3RTdHJpbmcgPSAiYW5kcm9pZCI7CisgICAgICAgIFBhdHRlcm4gcGF0ID0gUGF0dGVybi5jb21waWxlKHRlc3RQYXR0ZXJuKTsKKyAgICAgICAgTWF0Y2hlciBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKworICAgICAgICBtYXQucmVnaW9uKDAsIDMpOworICAgICAgICBtYXQudXNlVHJhbnNwYXJlbnRCb3VuZHMoZmFsc2UpOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkbid0IGZpbmQgcGF0dGVybiB3aXRoIG9wYXF1ZSBib3VuZHMiLCBtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBtYXQudXNlVHJhbnNwYXJlbnRCb3VuZHModHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBmaW5kIHBhdHRlcm4gdHJhbnNwYXJlbnQgYm91bmRzIiwgbWF0Lm1hdGNoZXMoKSk7IC8vICoqKgorCisgICAgICAgIHRlc3RQYXR0ZXJuID0gImFuZCg/IXJvaWQpIjsKKyAgICAgICAgdGVzdFN0cmluZyA9ICJhbmRyb2lkIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKHRlc3RQYXR0ZXJuKTsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisKKyAgICAgICAgbWF0LnJlZ2lvbigwLCAzKTsKKyAgICAgICAgbWF0LnVzZVRyYW5zcGFyZW50Qm91bmRzKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGZpbmQgcGF0dGVybiB3aXRoIG9wYXF1ZSBib3VuZHMiLCBtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBtYXQudXNlVHJhbnNwYXJlbnRCb3VuZHModHJ1ZSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGRuJ3QgZmluZCBwYXR0ZXJuIHRyYW5zcGFyZW50IGJvdW5kcyIsIG1hdC5tYXRjaGVzKCkpOyAvLyAqKioKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hpdEVuZCgpIHsKKyAgICAgICAgU3RyaW5nIHRlc3RQYXR0ZXJuID0gImFiYiI7CisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gImJhYmJhYmJjY2NhYmJhYmJhYmJhYmJhYmIiOworICAgICAgICBQYXR0ZXJuIHBhdCA9IFBhdHRlcm4uY29tcGlsZSh0ZXN0UGF0dGVybik7CisgICAgICAgIE1hdGNoZXIgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisKKyAgICAgICAgd2hpbGUgKG1hdC5maW5kKCkpIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJoaXRFbmQgc2hvdWxkIHJldHVybiBmYWxzZSBkdXJpbmcgcGFyc2luZyBpbnB1dCIsIG1hdC5oaXRFbmQoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaGl0RW5kIHNob3VsZCByZXR1cm4gdHJ1ZSBhZnRlciBmaW5kaW5nIGxhc3QgbWF0Y2giLCBtYXQuaGl0RW5kKCkpOyAvLyAqKioKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlcXVpcmVFbmQoKSB7CisgICAgICAgIFN0cmluZyB0ZXN0UGF0dGVybiA9ICJiYmEiOworICAgICAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJhYmJiYmJhIjsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUodGVzdFBhdHRlcm4pOworICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworCisgICAgICAgIGFzc2VydFRydWUobWF0LmZpbmQoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG1hdC5yZXF1aXJlRW5kKCkpOworCisgICAgICAgIHRlc3RQYXR0ZXJuID0gImJiYSQiOworICAgICAgICB0ZXN0U3RyaW5nID0gImFiYmJiYmEiOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUodGVzdFBhdHRlcm4pOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKworICAgICAgICBhc3NlcnRUcnVlKG1hdC5maW5kKCkpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5yZXF1aXJlRW5kKCkpOworICAgIH0KKworICAgIC8qCisgICAgICogUmVncmVzc2lvbiB0ZXN0IGZvciBIQVJNT05ZLTY3NAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXR0ZXJuTWF0Y2hlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQYXR0ZXJuIHBhdHRlcm4gPSBQYXR0ZXJuLmNvbXBpbGUoIig/OlxcZCspKD86cHQpIik7CisgICAgICAgIGFzc2VydFRydWUocGF0dGVybi5tYXRjaGVyKCIxNHB0IikubWF0Y2hlcygpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvRGVmbGF0ZXJJbnB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvRGVmbGF0ZXJJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MzhiMTZlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ppcC9EZWZsYXRlcklucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTEyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC56aXA7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC56aXAuRGVmbGF0ZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkluZmxhdGVySW5wdXRTdHJlYW07CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgRGVmbGF0ZXJJbnB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZEJ5dGVCeUJ5dGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IHsgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAgfTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBuZXcgRGVmbGF0ZXJJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSkpOworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCisgICAgICAgIGFzc2VydEVxdWFscygxLCBpbi5hdmFpbGFibGUoKSk7CisgICAgICAgIGludCBiOworICAgICAgICB3aGlsZSAoKGIgPSBpbi5yZWFkKCkpICE9IC0xKSB7CisgICAgICAgICAgICBvdXQud3JpdGUoYik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGluLmF2YWlsYWJsZSgpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLnRvU3RyaW5nKGRhdGEpLCBBcnJheXMudG9TdHJpbmcoaW5mbGF0ZShvdXQudG9CeXRlQXJyYXkoKSkpKTsKKworICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4uYXZhaWxhYmxlKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGluZmxhdGUoYnl0ZVtdIGJ5dGVzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGluID0gbmV3IEluZmxhdGVySW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzKSk7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVsxMDI0XTsKKyAgICAgICAgaW50IGNvdW50OworICAgICAgICB3aGlsZSAoKGNvdW50ID0gaW4ucmVhZChidWZmZXIpKSAhPSAtMSkgeworICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZmZlciwgMCwgY291bnQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBvdXQudG9CeXRlQXJyYXkoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZFdpdGhCdWZmZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IHsgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAgfTsKKyAgICAgICAgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlWzhdOworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG5ldyBEZWZsYXRlcklucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShkYXRhKSk7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBpbi5hdmFpbGFibGUoKSk7CisgICAgICAgIGludCBjb3VudDsKKyAgICAgICAgd2hpbGUgKChjb3VudCA9IGluLnJlYWQoYnVmZmVyLCAwLCA1KSkgIT0gLTEpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoY291bnQgPD0gNSk7CisgICAgICAgICAgICBvdXQud3JpdGUoYnVmZmVyLCAwLCBjb3VudCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGluLmF2YWlsYWJsZSgpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLnRvU3RyaW5nKGRhdGEpLCBBcnJheXMudG9TdHJpbmcoaW5mbGF0ZShvdXQudG9CeXRlQXJyYXkoKSkpKTsKKworICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4uYXZhaWxhYmxlKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZEV4Y2VwdGlvbnMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IHsgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAgfTsKKyAgICAgICAgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlWzhdOworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG5ldyBEZWZsYXRlcklucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShkYXRhKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbi5yZWFkKGJ1ZmZlciwgMCwgMTApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluLnJlYWQobnVsbCwgMCwgNSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluLnJlYWQoYnVmZmVyLCAtMSwgNSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4ucmVhZChidWZmZXIsIDAsIDUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ppcC9EZWZsYXRlck91dHB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvRGVmbGF0ZXJPdXRwdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzdkMTI0OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvRGVmbGF0ZXJPdXRwdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSwxNTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLnppcDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5FT0ZFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlBpcGVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QaXBlZE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNhbGxhYmxlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcnM7CitpbXBvcnQgamF2YS51dGlsLnppcC5EZWZsYXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkRlZmxhdGVyT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC56aXAuSW5mbGF0ZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBEZWZsYXRlck91dHB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3luY0ZsdXNoRW5hYmxlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBJbmZsYXRlcklucHV0U3RyZWFtIGluID0gY3JlYXRlSW5mbGF0ZXJTdHJlYW0odHJ1ZSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBpbi5yZWFkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgaW4ucmVhZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGluLnJlYWQoKSk7CisgICAgICAgIGluLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN5bmNGbHVzaERpc2FibGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEluZmxhdGVySW5wdXRTdHJlYW0gaW4gPSBjcmVhdGVJbmZsYXRlclN0cmVhbShmYWxzZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbi5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgaW4uY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIG9wdGlvbmFsbHktZmx1c2hpbmcgZGVmbGF0ZXIgc3RyZWFtLCB3cml0ZXMgc29tZSBieXRlcyB0byBpdCwKKyAgICAgKiBhbmQgZmx1c2hlcyBpdC4gUmV0dXJucyBhbiBpbmZsYXRlciBzdHJlYW0gdGhhdCByZWFkcyB0aGlzIGRlZmxhdGVyJ3MKKyAgICAgKiBvdXRwdXQuCisgICAgICoKKyAgICAgKiA8cD5UaGVzZSBieXRlcyBhcmUgd3JpdHRlbiBvbiBhIHNlcGFyYXRlIHRocmVhZCBzbyB0aGF0IHdoZW4gdGhlIGluZmxhdGVyCisgICAgICogc3RyZWFtIGlzIHJlYWQsIHRoYXQgcmVhZCB3aWxsIGZhaWwgd2hlbiBubyBieXRlcyBhcmUgYXZhaWxhYmxlLiBGYWlsaW5nCisgICAgICogdGFrZXMgMyBzZWNvbmRzLCBjby1vcmRpbmF0ZWQgYnkgUGlwZWRJbnB1dFN0cmVhbSdzICdicm9rZW4gcGlwZScKKyAgICAgKiB0aW1lb3V0LiBUaGUgMyBzZWNvbmQgZGVsYXkgaXMgdW5mb3J0dW5hdGUgYnV0IHNlZW1zIHRvIGJlIHRoZSBlYXNpZXN0CisgICAgICogd2F5IGRlbW9uc3RyYXRlIHRoYXQgZGF0YSBpcyB1bmF2YWlsYWJsZS4gSWUuIG90aGVyIHRlY2huaXF1ZXMgd2lsbCBjYXVzZQorICAgICAqIHRoZSBkcnkgcmVhZCB0byBibG9jayBpbmRlZmluaXRlbHkuCisgICAgICovCisgICAgcHJpdmF0ZSBJbmZsYXRlcklucHV0U3RyZWFtIGNyZWF0ZUluZmxhdGVyU3RyZWFtKGZpbmFsIGJvb2xlYW4gZmx1c2hpbmcpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBFeGVjdXRvclNlcnZpY2UgZXhlY3V0b3IgPSBFeGVjdXRvcnMubmV3U2luZ2xlVGhyZWFkRXhlY3V0b3IoKTsKKyAgICAgICAgZmluYWwgUGlwZWRPdXRwdXRTdHJlYW0gcG91dCA9IG5ldyBQaXBlZE91dHB1dFN0cmVhbSgpOworICAgICAgICBQaXBlZElucHV0U3RyZWFtIHBpbiA9IG5ldyBQaXBlZElucHV0U3RyZWFtKHBvdXQpOworCisgICAgICAgIGV4ZWN1dG9yLnN1Ym1pdChuZXcgQ2FsbGFibGU8Vm9pZD4oKSB7CisgICAgICAgICAgICBwdWJsaWMgVm9pZCBjYWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBEZWZsYXRlck91dHB1dFN0cmVhbShwb3V0LCBmbHVzaGluZyk7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlKDEpOworICAgICAgICAgICAgICAgIG91dC53cml0ZSgyKTsKKyAgICAgICAgICAgICAgICBvdXQud3JpdGUoMyk7CisgICAgICAgICAgICAgICAgb3V0LmZsdXNoKCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0pLmdldCgpOworICAgICAgICBleGVjdXRvci5zaHV0ZG93bigpOworCisgICAgICAgIHJldHVybiBuZXcgSW5mbGF0ZXJJbnB1dFN0cmVhbShwaW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbmZpcm0gdGhhdCBhIERlZmxhdGVyT3V0cHV0U3RyZWFtIGNvbnN0cnVjdGVkIHdpdGggRGVmbGF0ZXIKKyAgICAgKiB3aXRoIGZsdXNoUGFybSA9PSBTWU5DX0ZMVVNIIGRvZXMgbm90IG5lZWQgdG8gdG8gYmUgZmx1c2hlZC4KKyAgICAgKgorICAgICAqIGh0dHA6Ly9iLzQwMDUwOTEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3luY0ZsdXNoRGVmbGF0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRGVmbGF0ZXIgZGVmID0gbmV3IERlZmxhdGVyKCk7CisgICAgICAgIEZpZWxkIGYgPSBkZWYuZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJmbHVzaFBhcm0iKTsKKyAgICAgICAgZi5zZXRBY2Nlc3NpYmxlKHRydWUpOworICAgICAgICBmLnNldEludChkZWYsIERlZmxhdGVyLlNZTkNfRkxVU0gpOworCisgICAgICAgIGZpbmFsIGludCBkZWZsYXRlckJ1ZmZlclNpemUgPSA1MTI7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBEZWZsYXRlck91dHB1dFN0cmVhbSBkb3MgPSBuZXcgRGVmbGF0ZXJPdXRwdXRTdHJlYW0oYmFvcywgZGVmLCBkZWZsYXRlckJ1ZmZlclNpemUpOworCisgICAgICAgIC8vIG1ha2Ugb3V0cHV0IGJ1ZmZlciBsYXJnZSBlbm91Z2ggdGhhdCBldmVuIGlmIGNvbXByZXNzZWQgaXQKKyAgICAgICAgLy8gd29uJ3QgYWxsIGZpdCB3aXRoaW4gdGhlIGRlZmxhdGVyQnVmZmVyU2l6ZS4KKyAgICAgICAgZmluYWwgaW50IG91dHB1dEJ1ZmZlclNpemUgPSAxMjggKiBkZWZsYXRlckJ1ZmZlclNpemU7CisgICAgICAgIGJ5dGVbXSBvdXRwdXQgPSBuZXcgYnl0ZVtvdXRwdXRCdWZmZXJTaXplXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvdXRwdXQubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG91dHB1dFtpXSA9IChieXRlKSBpOworICAgICAgICB9CisgICAgICAgIGRvcy53cml0ZShvdXRwdXQpOworICAgICAgICBieXRlW10gY29tcHJlc3NlZCA9IGJhb3MudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgLy8gdGhpcyBtYWluIHJlYXNvbiBmb3IgdGhpcyBhc3NlcnQgaXMgdG8gbWFrZSBzdXJlIHRoYXQgdGhlCisgICAgICAgIC8vIGNvbXByZXNzZWQgYnl0ZSBjb3VudCBpcyBsYXJnZXIgdGhhbiB0aGUKKyAgICAgICAgLy8gZGVmbGF0ZXJCdWZmZXJTaXplLiBIb3dldmVyLCB3aGVuIHRoZSBvcmlnaW5hbCBidWcgZXhpc3RzLAorICAgICAgICAvLyBpdCB3aWxsIGFsc28gZmFpbCBiZWNhdXNlIHRoZSBjb21wcmVzc2VkIGxlbmd0aCB3aWxsIGJlCisgICAgICAgIC8vIGV4YWN0bHkgdGhlIGxlbmd0aCBvZiB0aGUgZGVmbGF0ZXJCdWZmZXJTaXplLgorICAgICAgICBhc3NlcnRUcnVlKCJjb21wcmVzc2VkPSIgKyBjb21wcmVzc2VkLmxlbmd0aAorICAgICAgICAgICAgICAgICAgICsgIiBidXQgZGVmbGF0ZXJCdWZmZXJTaXplPSIgKyBkZWZsYXRlckJ1ZmZlclNpemUsCisgICAgICAgICAgICAgICAgICAgY29tcHJlc3NlZC5sZW5ndGggPiBkZWZsYXRlckJ1ZmZlclNpemUpOworCisgICAgICAgIC8vIGFzc2VydCB0aGF0IHdlIHJldHVybmVkIGRhdGEgbWF0Y2hlcyB0aGUgaW5wdXQgZXhhY3RseS4KKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShjb21wcmVzc2VkKTsKKyAgICAgICAgSW5mbGF0ZXJJbnB1dFN0cmVhbSBpaXMgPSBuZXcgSW5mbGF0ZXJJbnB1dFN0cmVhbShiYWlzKTsKKyAgICAgICAgYnl0ZVtdIGlucHV0ID0gbmV3IGJ5dGVbb3V0cHV0Lmxlbmd0aF07CisgICAgICAgIGludCB0b3RhbCA9IDA7CisgICAgICAgIHdoaWxlICh0cnVlKSAgeworICAgICAgICAgICAgaW50IG4gPSBpaXMucmVhZChpbnB1dCwgdG90YWwsIGlucHV0Lmxlbmd0aCAtIHRvdGFsKTsKKyAgICAgICAgICAgIGlmIChuID09IC0xKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0b3RhbCArPSBuOworICAgICAgICAgICAgaWYgKHRvdGFsID09IGlucHV0Lmxlbmd0aCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGlpcy5yZWFkKCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyhvdXRwdXQubGVuZ3RoLCB0b3RhbCk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhpbnB1dCwgb3V0cHV0KSk7CisKKyAgICAgICAgLy8gZW5zdXJlIERlZmxhdGVyLmZpbmlzaCBoYXMgbm90IGJlZW4gY2FsbGVkIGF0IGFueSBwb2ludAorICAgICAgICAvLyBkdXJpbmcgdGhlIHRlc3QsIHNpbmNlIHRoYXQgd291bGQgbGVhZCB0byB0aGUgcmVzdWx0cyBiZWluZworICAgICAgICAvLyBmbHVzaGVkIGV2ZW4gd2l0aG91dCBTWU5DX0ZMVVNIIGJlaW5nIHVzZWQKKyAgICAgICAgYXNzZXJ0RmFsc2UoZGVmLmZpbmlzaGVkKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvRGVmbGF0ZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvemlwL0RlZmxhdGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMwYWE3ZjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvemlwL0RlZmxhdGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsODUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLnppcDsKKworaW1wb3J0IGphdmEudXRpbC56aXAuRGF0YUZvcm1hdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkRlZmxhdGVyOworaW1wb3J0IGphdmEudXRpbC56aXAuSW5mbGF0ZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgRGVmbGF0ZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBieXRlW10gY29tcHJlc3NlZCA9IG5ldyBieXRlWzMyXTsKKyAgICBwcml2YXRlIGJ5dGVbXSBkZWNvbXByZXNzZWQgPSBuZXcgYnl0ZVsyMF07CisgICAgcHJpdmF0ZSBEZWZsYXRlciBkZWZsYXRlciA9IG5ldyBEZWZsYXRlcigpOworICAgIHByaXZhdGUgSW5mbGF0ZXIgaW5mbGF0ZXIgPSBuZXcgSW5mbGF0ZXIoKTsKKyAgICBwcml2YXRlIGludCB0b3RhbERlZmxhdGVkID0gMDsKKyAgICBwcml2YXRlIGludCB0b3RhbEluZmxhdGVkID0gMDsKKworICAgIHB1YmxpYyB2b2lkIHRlc3REZWZsYXRlKCkgdGhyb3dzIERhdGFGb3JtYXRFeGNlcHRpb24geworICAgICAgICBkZWZsYXRlci5zZXRJbnB1dChuZXcgYnl0ZVtdIHsgMSwgMiwgMyB9KTsKKyAgICAgICAgZGVmbGF0ZUluZmxhdGUoRGVmbGF0ZXIuTk9fRkxVU0gpOworICAgICAgICBhc3NlcnRUcnVlKHRvdGFsSW5mbGF0ZWQgPCAzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGRlY29tcHJlc3NlZFsyXSk7IC8vIHRoZSAzcmQgYnl0ZSBzaG91bGRuJ3QgaGF2ZSBiZWVuIGZsdXNoZWQgeWV0CisKKyAgICAgICAgZGVmbGF0ZXIuc2V0SW5wdXQobmV3IGJ5dGVbXSB7IDQsIDUsIDYgfSk7CisgICAgICAgIGRlZmxhdGVJbmZsYXRlKERlZmxhdGVyLlNZTkNfRkxVU0gpOworICAgICAgICBhc3NlcnRFcXVhbHMoNiwgdG90YWxJbmZsYXRlZCk7CisgICAgICAgIGFzc2VydERlY29tcHJlc3NlZCgxLCAyLCAzLCA0LCA1LCA2KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGluZmxhdGVyLmluZmxhdGUoZGVjb21wcmVzc2VkKSk7CisKKyAgICAgICAgZGVmbGF0ZXIuc2V0SW5wdXQobmV3IGJ5dGVbXSB7IDcsIDgsIDkgfSk7CisgICAgICAgIGRlZmxhdGVJbmZsYXRlKERlZmxhdGVyLkZVTExfRkxVU0gpOworICAgICAgICBhc3NlcnRFcXVhbHMoOSwgdG90YWxJbmZsYXRlZCk7CisgICAgICAgIGFzc2VydERlY29tcHJlc3NlZCgxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGluZmxhdGVyLmluZmxhdGUoZGVjb21wcmVzc2VkKSk7CisgICAgICAgIGluZmxhdGVyID0gbmV3IEluZmxhdGVyKHRydWUpOyAvLyBzYWZlIGJlY2F1c2Ugd2UgZGlkIGEgRlVMTF9GTFVTSAorCisgICAgICAgIGRlZmxhdGVyLnNldElucHV0KG5ldyBieXRlW10geyAxMCwgMTEsIDEyIH0pOworICAgICAgICBkZWZsYXRlSW5mbGF0ZShEZWZsYXRlci5TWU5DX0ZMVVNIKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEyLCB0b3RhbEluZmxhdGVkKTsKKyAgICAgICAgYXNzZXJ0RGVjb21wcmVzc2VkKDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaW5mbGF0ZXIuaW5mbGF0ZShkZWNvbXByZXNzZWQpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZGVmbGF0ZUluZmxhdGUoaW50IGZsdXNoKSB0aHJvd3MgRGF0YUZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBsYXN0RGVmbGF0ZWQgPSBkZWZsYXRlci5kZWZsYXRlKGNvbXByZXNzZWQsIHRvdGFsRGVmbGF0ZWQsCisgICAgICAgICAgICAgICAgY29tcHJlc3NlZC5sZW5ndGggLSB0b3RhbERlZmxhdGVkLCBmbHVzaCk7CisgICAgICAgIGFzc2VydFRydWUoaW5mbGF0ZXIubmVlZHNJbnB1dCgpKTsKKyAgICAgICAgaW5mbGF0ZXIuc2V0SW5wdXQoY29tcHJlc3NlZCwgdG90YWxEZWZsYXRlZCwgbGFzdERlZmxhdGVkKTsKKyAgICAgICAgdG90YWxEZWZsYXRlZCArPSBsYXN0RGVmbGF0ZWQ7CisgICAgICAgIHRvdGFsSW5mbGF0ZWQgKz0gaW5mbGF0ZXIuaW5mbGF0ZShkZWNvbXByZXNzZWQsIHRvdGFsSW5mbGF0ZWQsCisgICAgICAgICAgICAgICAgZGVjb21wcmVzc2VkLmxlbmd0aCAtIHRvdGFsSW5mbGF0ZWQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnREZWNvbXByZXNzZWQoaW50Li4uIGV4cGVjdGVkKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVjb21wcmVzc2VkLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpbnQgZXhwZWN0ZWRWYWx1ZSA9IGkgPCBleHBlY3RlZC5sZW5ndGggPyBleHBlY3RlZFtpXSA6IDA7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRWYWx1ZSwgZGVjb21wcmVzc2VkW2ldKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIERlZmxhdGluZyB3aXRob3V0IGNhbGxpbmcgc2V0SW5wdXQoKSBpcyB0aGUgc2FtZSBhcyBkZWZsYXRpbmcgYW4gZW1wdHkKKyAgICAgKiBieXRlIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REZWZsYXRlV2l0aG91dFNldHRpbmdJbnB1dCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkZWZsYXRlSW5mbGF0ZShEZWZsYXRlci5GVUxMX0ZMVVNIKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0b3RhbERlZmxhdGVkID4gMCk7IC8vIHRoZSBkZWZsYXRlZCBmb3JtIHNob3VsZCBiZSBub24tZW1wdHkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHRvdGFsSW5mbGF0ZWQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvR1pJUElucHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ppcC9HWklQSW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTI4ZmFlNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvR1pJUElucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLnppcDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkdaSVBJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkdaSVBPdXRwdXRTdHJlYW07CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgR1pJUElucHV0U3RyZWFtVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2hvcnRNZXNzYWdlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgIDMxLCAtMTE3LCA4LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAtMTMsIDcyLCAtNTEsIC01NSwgLTU1LCA4NywgOCwgLTQ5LAorICAgICAgICAgICAgNDcsIC01NCwgNzMsIDEsIDAsIDg2LCAtNzksIDIzLCA3NCwgMTEsIDAsIDAsIDAKKyAgICAgICAgfTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJIZWxsbyBXb3JsZCIsIG5ldyBTdHJpbmcoZ3VuemlwKGRhdGEpLCAiVVRGLTgiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdExvbmdNZXNzYWdlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVsxMDI0ICogMTAyNF07CisgICAgICAgIG5ldyBSYW5kb20oKS5uZXh0Qnl0ZXMoZGF0YSk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhkYXRhLCBndW56aXAoR1pJUE91dHB1dFN0cmVhbVRlc3QuZ3ppcChkYXRhKSkpKTsKKyAgICB9CisKKyAgICAvKiogaHR0cDovL2IvMzA0MjU3NCBHemlwSW5wdXRTdHJlYW0uc2tpcCgpIGNhdXNpbmcgQ1JDIGZhaWx1cmVzICovCisgICAgcHVibGljIHZvaWQgdGVzdFNraXAoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlWzEwMjQgKiAxMDI0XTsKKyAgICAgICAgYnl0ZVtdIGd6aXBwZWQgPSBHWklQT3V0cHV0U3RyZWFtVGVzdC5nemlwKGRhdGEpOworICAgICAgICBHWklQSW5wdXRTdHJlYW0gaW4gPSBuZXcgR1pJUElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShnemlwcGVkKSk7CisgICAgICAgIGxvbmcgdG90YWxTa2lwcGVkID0gMDsKKworICAgICAgICBsb25nIGNvdW50OworICAgICAgICBkbyB7CisgICAgICAgICAgICBjb3VudCA9IGluLnNraXAoTG9uZy5NQVhfVkFMVUUpOworICAgICAgICAgICAgdG90YWxTa2lwcGVkICs9IGNvdW50OworICAgICAgICB9IHdoaWxlIChjb3VudCA+IDApOworCisgICAgICAgIGFzc2VydEVxdWFscyhkYXRhLmxlbmd0aCwgdG90YWxTa2lwcGVkKTsKKyAgICAgICAgaW4uY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBndW56aXAoYnl0ZVtdIGJ5dGVzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG5ldyBHWklQSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzKSk7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVsxMDI0XTsKKyAgICAgICAgaW50IGNvdW50OworICAgICAgICB3aGlsZSAoKGNvdW50ID0gaW4ucmVhZChidWZmZXIpKSAhPSAtMSkgeworICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZmZlciwgMCwgY291bnQpOworICAgICAgICB9CisgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIHJldHVybiBvdXQudG9CeXRlQXJyYXkoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvemlwL0daSVBPdXRwdXRTdHJlYW1UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvemlwL0daSVBPdXRwdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTYxODgwZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvR1pJUE91dHB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDUwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC56aXA7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CitpbXBvcnQgamF2YS51dGlsLnppcC5HWklQSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLnppcC5HWklQT3V0cHV0U3RyZWFtOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIEdaSVBPdXRwdXRTdHJlYW1UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RTaG9ydE1lc3NhZ2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IGd6aXAoKCJIZWxsbyBXb3JsZCIpLmdldEJ5dGVzKCJVVEYtOCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbMzEsIC0xMTcsIDgsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIC0xMywgNzIsIC01MSwgLTU1LCAtNTUsIDg3LCA4LCAtNDksICIgKworICAgICAgICAgICAgICAgICI0NywgLTU0LCA3MywgMSwgMCwgODYsIC03OSwgMjMsIDc0LCAxMSwgMCwgMCwgMF0iLCBBcnJheXMudG9TdHJpbmcoZGF0YSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RMb25nTWVzc2FnZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbMTAyNCAqIDEwMjRdOworICAgICAgICBuZXcgUmFuZG9tKCkubmV4dEJ5dGVzKGRhdGEpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoZGF0YSwgR1pJUElucHV0U3RyZWFtVGVzdC5ndW56aXAoZ3ppcChkYXRhKSkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBnemlwKGJ5dGVbXSBieXRlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVzT3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBPdXRwdXRTdHJlYW0gZ3ppcHBlZE91dCA9IG5ldyBHWklQT3V0cHV0U3RyZWFtKGJ5dGVzT3V0KTsKKyAgICAgICAgZ3ppcHBlZE91dC53cml0ZShieXRlcyk7CisgICAgICAgIGd6aXBwZWRPdXQuY2xvc2UoKTsKKyAgICAgICAgcmV0dXJuIGJ5dGVzT3V0LnRvQnl0ZUFycmF5KCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ppcC9JbmZsYXRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvSW5mbGF0ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTU4YjNlOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvSW5mbGF0ZXJUZXN0LmphdmEKQEAgLTAsMCArMSwxMjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLnppcDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC56aXAuQWRsZXIzMjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkRlZmxhdGVyOworaW1wb3J0IGphdmEudXRpbC56aXAuSW5mbGF0ZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgSW5mbGF0ZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3REZWZhdWx0RGljdGlvbmFyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRSb3VuZFRyaXAobnVsbCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFByZXNldEN1c3RvbURpY3Rpb25hcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0Um91bmRUcmlwKCJkaWN0aW9uYXJ5Ii5nZXRCeXRlcygiVVRGLTgiKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhc3NlcnRSb3VuZFRyaXAoYnl0ZVtdIGRpY3Rpb25hcnkpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBDb25zdHJ1Y3QgYSBuaWNlIGxvbmcgaW5wdXQgYnl0ZSBzZXF1ZW5jZS4KKyAgICAgICAgU3RyaW5nIGV4cGVjdGVkID0gbWFrZVN0cmluZygpOworICAgICAgICBieXRlW10gZXhwZWN0ZWRCeXRlcyA9IGV4cGVjdGVkLmdldEJ5dGVzKCJVVEYtOCIpOworCisgICAgICAgIC8vIENvbXByZXNzIHRoZSBieXRlcywgdXNpbmcgdGhlIHBhc3NlZC1pbiBkaWN0aW9uYXJ5IChvciBubyBkaWN0aW9uYXJ5KS4KKyAgICAgICAgYnl0ZVtdIGRlZmxhdGVkQnl0ZXMgPSBkZWZsYXRlKGV4cGVjdGVkQnl0ZXMsIGRpY3Rpb25hcnkpOworCisgICAgICAgIC8vIEdldCByZWFkeSB0byBkZWNvbXByZXNzIGRlZmxhdGVkQnl0ZXMgYmFjayB0byB0aGUgb3JpZ2luYWwgYnl0ZXMgLi4uCisgICAgICAgIEluZmxhdGVyIGluZmxhdGVyID0gbmV3IEluZmxhdGVyKCk7CisgICAgICAgIC8vIFdlJ2xsIG9ubHkgc3VwcGx5IHRoZSBpbnB1dCBhIGxpdHRsZSBiaXQgYXQgYSB0aW1lLCBzbyB0aGF0IHpsaWIgaGFzIHRvIGFzayBmb3IgbW9yZS4KKyAgICAgICAgZmluYWwgaW50IENIVU5LX1NJWkUgPSAxNjsKKyAgICAgICAgaW50IG9mZnNldCA9IDA7CisgICAgICAgIGluZmxhdGVyLnNldElucHV0KGRlZmxhdGVkQnl0ZXMsIG9mZnNldCwgQ0hVTktfU0laRSk7CisgICAgICAgIG9mZnNldCArPSBDSFVOS19TSVpFOworICAgICAgICAvLyBJZiB3ZSB1c2VkIGEgZGljdGlvbmFyeSB0byBjb21wcmVzcywgY2hlY2sgdGhhdCB3ZSdyZSBhc2tlZCBmb3IgdGhhdCBzYW1lIGRpY3Rpb25hcnkuCisgICAgICAgIGlmIChkaWN0aW9uYXJ5ICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vIDEuIHRoZXJlJ3Mgbm8gZGF0YSBhdmFpbGFibGUgaW1tZWRpYXRlbHkuLi4KKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBpbmZsYXRlci5pbmZsYXRlKG5ldyBieXRlWzhdKSk7CisgICAgICAgICAgICAvLyAyLiAuLi5iZWNhdXNlIHlvdSBuZWVkIGEgZGljdGlvbmFyeS4KKyAgICAgICAgICAgIGFzc2VydFRydWUoaW5mbGF0ZXIubmVlZHNEaWN0aW9uYXJ5KCkpOworICAgICAgICAgICAgLy8gMy4gLi4uYW5kIHRoYXQgZGljdGlvbmFyeSBoYXMgdGhlIHNhbWUgQWRsZXIzMiBhcyB0aGUgZGljdGlvbmFyeSB3ZSB1c2VkLgorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFkbGVyMzIoZGljdGlvbmFyeSksIGluZmxhdGVyLmdldEFkbGVyKCkpOworICAgICAgICAgICAgaW5mbGF0ZXIuc2V0RGljdGlvbmFyeShkaWN0aW9uYXJ5KTsKKyAgICAgICAgfQorICAgICAgICAvLyBEbyB0aGUgYWN0dWFsIGRlY29tcHJlc3Npb24sIG5vdyB0aGUgZGljdGlvbmFyeSdzIHNldCB1cCBhcHByb3ByaWF0ZWx5Li4uCisgICAgICAgIC8vIFdlIHVzZSBhIHRpbnkgb3V0cHV0IGJ1ZmZlciB0byBlbnN1cmUgdGhhdCB3ZSBjYWxsIGluZmxhdGUgbXVsdGlwbGUgdGltZXMsIGFuZAorICAgICAgICAvLyBhIHRpbnkgaW5wdXQgYnVmZmVyIHRvIGVuc3VyZSB0aGF0IHpsaWIgaGFzIHRvIGFzayBmb3IgbW9yZSBpbnB1dC4KKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGluZmxhdGVkQnl0ZXMgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVs4XTsKKyAgICAgICAgd2hpbGUgKGluZmxhdGVkQnl0ZXMuc2l6ZSgpICE9IGV4cGVjdGVkQnl0ZXMubGVuZ3RoKSB7CisgICAgICAgICAgICBpZiAoaW5mbGF0ZXIubmVlZHNJbnB1dCgpKSB7CisgICAgICAgICAgICAgICAgaW50IG5leHRDaHVua0J5dGVDb3VudCA9IE1hdGgubWluKENIVU5LX1NJWkUsIGRlZmxhdGVkQnl0ZXMubGVuZ3RoIC0gb2Zmc2V0KTsKKyAgICAgICAgICAgICAgICBpbmZsYXRlci5zZXRJbnB1dChkZWZsYXRlZEJ5dGVzLCBvZmZzZXQsIG5leHRDaHVua0J5dGVDb3VudCk7CisgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IG5leHRDaHVua0J5dGVDb3VudDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaW50IGluZmxhdGVkQnl0ZUNvdW50ID0gaW5mbGF0ZXIuaW5mbGF0ZShidWYpOworICAgICAgICAgICAgICAgIGlmIChpbmZsYXRlZEJ5dGVDb3VudCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgaW5mbGF0ZWRCeXRlcy53cml0ZShidWYsIDAsIGluZmxhdGVkQnl0ZUNvdW50KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaW5mbGF0ZXIuZW5kKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBuZXcgU3RyaW5nKGluZmxhdGVkQnl0ZXMudG9CeXRlQXJyYXkoKSwgIlVURi04IikpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBtYWtlU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDI0OyArK2kpIHsKKyAgICAgICAgICAgIC8vIFRoaXMgaXMgYXJiaXRyYXJ5IGJ1dCBjb252ZW5pZW50IGluIHRoYXQgaXQgZ2l2ZXMgb3VyIHN0cmluZworICAgICAgICAgICAgLy8gYW4gZWFzaWx5LXJlY29nbml6YWJsZSBiZWdpbm5pbmcgYW5kIGVuZC4KKyAgICAgICAgICAgIHNiLmFwcGVuZChpICsgMTAyNCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD0xMTc1NQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eUZpbGVBbmRFbXB0eUJ1ZmZlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gZW1wdHlJbnB1dCA9IGRlZmxhdGUobmV3IGJ5dGVbMF0sIG51bGwpOworICAgICAgICBJbmZsYXRlciBpbmZsYXRlciA9IG5ldyBJbmZsYXRlcigpOworICAgICAgICBpbmZsYXRlci5zZXRJbnB1dChlbXB0eUlucHV0KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoaW5mbGF0ZXIuZmluaXNoZWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBpbmZsYXRlci5pbmZsYXRlKG5ldyBieXRlWzBdLCAwLCAwKSk7CisgICAgICAgIGFzc2VydFRydWUoaW5mbGF0ZXIuZmluaXNoZWQoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdIGRlZmxhdGUoYnl0ZVtdIGlucHV0LCBieXRlW10gZGljdGlvbmFyeSkgeworICAgICAgICBEZWZsYXRlciBkZWZsYXRlciA9IG5ldyBEZWZsYXRlcigpOworICAgICAgICBpZiAoZGljdGlvbmFyeSAhPSBudWxsKSB7CisgICAgICAgICAgICBkZWZsYXRlci5zZXREaWN0aW9uYXJ5KGRpY3Rpb25hcnkpOworICAgICAgICB9CisgICAgICAgIGRlZmxhdGVyLnNldElucHV0KGlucHV0KTsKKyAgICAgICAgZGVmbGF0ZXIuZmluaXNoKCk7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBkZWZsYXRlZEJ5dGVzID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbOF07CisgICAgICAgIHdoaWxlICghZGVmbGF0ZXIuZmluaXNoZWQoKSkgeworICAgICAgICAgICAgaW50IGJ5dGVDb3VudCA9IGRlZmxhdGVyLmRlZmxhdGUoYnVmKTsKKyAgICAgICAgICAgIGRlZmxhdGVkQnl0ZXMud3JpdGUoYnVmLCAwLCBieXRlQ291bnQpOworICAgICAgICB9CisgICAgICAgIGRlZmxhdGVyLmVuZCgpOworICAgICAgICByZXR1cm4gZGVmbGF0ZWRCeXRlcy50b0J5dGVBcnJheSgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGludCBhZGxlcjMyKGJ5dGVbXSBieXRlcykgeworICAgICAgICBBZGxlcjMyIGFkbGVyMzIgPSBuZXcgQWRsZXIzMigpOworICAgICAgICBhZGxlcjMyLnVwZGF0ZShieXRlcyk7CisgICAgICAgIHJldHVybiAoaW50KSBhZGxlcjMyLmdldFZhbHVlKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ppcC9PbGRBbmRyb2lkQ2hlY2tzdW1UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvemlwL09sZEFuZHJvaWRDaGVja3N1bVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZDI0MDZkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ppcC9PbGRBbmRyb2lkQ2hlY2tzdW1UZXN0LmphdmEKQEAgLTAsMCArMSw5NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWwuemlwOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS51dGlsLnppcC5BZGxlcjMyOworaW1wb3J0IGphdmEudXRpbC56aXAuQ1JDMzI7CisKKy8qKgorICogdGVzdHMgZm9yIENSQzMyIGFuZCBBZGxlcjMyIGNoZWNrc3VtIGFsZ29yaXRobXMuCisgKi8KK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkQ2hlY2tzdW1UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdENoZWNrc3VtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8qCisgICAgICAgICAqIFZhbHVlcyBjb21wdXRlZCBleHBlcmltZW50YWxseSwgdXNpbmcgQyBpbnRlcmZhY2VzLgorICAgICAgICAgKi8KKyAgICAgICAgYWRsZXIzMlRlc3QobVRlc3RTdHJpbmcsIDB4OWRlMjEwZGJMKTsKKyAgICAgICAgY1JDMzJUZXN0KG1UZXN0U3RyaW5nLCAweDkzOWYwNGFmTCk7CisKKyAgICAgICAgLy8gVGVzdCBmb3IgaXNzdWUgMTAxNjAzNworICAgICAgICB3cm9uZ0NoZWNrc3VtV2l0aEFkbGVyMzJUZXN0KCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFkbGVyMzJUZXN0KGJ5dGVbXSB2YWx1ZXMsIGxvbmcgZXhwZWN0ZWQpIHsKKyAgICAgICAgQWRsZXIzMiBhZGxlciA9IG5ldyBBZGxlcjMyKCk7CisKKyAgICAgICAgLy8gdHJ5IGl0IGFsbCBhdCBvbmNlCisgICAgICAgIGFkbGVyLnVwZGF0ZSh2YWx1ZXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoYWRsZXIuZ2V0VmFsdWUoKSwgZXhwZWN0ZWQpOworCisgICAgICAgIC8vIHRyeSByZXNldHRpbmcgYW5kIGNvbXB1dGluZyBvbmUgYnl0ZSBhdCBhIHRpbWUKKyAgICAgICAgYWRsZXIucmVzZXQoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFkbGVyLnVwZGF0ZSh2YWx1ZXNbaV0pOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyhhZGxlci5nZXRWYWx1ZSgpLCBleHBlY3RlZCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNSQzMyVGVzdChieXRlW10gdmFsdWVzLCBsb25nIGV4cGVjdGVkKSB7CisgICAgICAgIENSQzMyIGNyYyA9IG5ldyBDUkMzMigpOworCisgICAgICAgIC8vIHRyeSBpdCBhbGwgYXQgb25jZQorICAgICAgICBjcmMudXBkYXRlKHZhbHVlcyk7CisgICAgICAgIGFzc2VydEVxdWFscyhjcmMuZ2V0VmFsdWUoKSwgZXhwZWN0ZWQpOworCisgICAgICAgIC8vIHRyeSByZXNldHRpbmcgYW5kIGNvbXB1dGluZyBvbmUgYnl0ZSBhdCBhIHRpbWUKKyAgICAgICAgY3JjLnJlc2V0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjcmMudXBkYXRlKHZhbHVlc1tpXSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNyYy5nZXRWYWx1ZSgpLCBleHBlY3RlZCk7CisgICAgfQorCisgICAgLy8gIlRoZSBxdWljayBicm93biBmb3gganVtcGVkIG92ZXIgdGhlIGxhenkgZG9nc1xuIgorICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBtVGVzdFN0cmluZyA9IHsKKyAgICAgICAgICAgIDB4NTQsIDB4NjgsIDB4NjUsIDB4MjAsIDB4NzEsIDB4NzUsIDB4NjksIDB4NjMsCisgICAgICAgICAgICAweDZiLCAweDIwLCAweDYyLCAweDcyLCAweDZmLCAweDc3LCAweDZlLCAweDIwLAorICAgICAgICAgICAgMHg2NiwgMHg2ZiwgMHg3OCwgMHgyMCwgMHg2YSwgMHg3NSwgMHg2ZCwgMHg3MCwKKyAgICAgICAgICAgIDB4NjUsIDB4NjQsIDB4MjAsIDB4NmYsIDB4NzYsIDB4NjUsIDB4NzIsIDB4MjAsCisgICAgICAgICAgICAweDc0LCAweDY4LCAweDY1LCAweDIwLCAweDZjLCAweDYxLCAweDdhLCAweDc5LAorICAgICAgICAgICAgMHgyMCwgMHg2NCwgMHg2ZiwgMHg2NywgMHg3MywgMHgyZSwgMHgwYQorICAgIH07CisKKworICAgIC8vIFRlc3QgZm9yIGlzc3VlIDEwMTYwMzcKKyAgICBwcml2YXRlIHZvaWQgd3JvbmdDaGVja3N1bVdpdGhBZGxlcjMyVGVzdCgpIHsKKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0gezEsIDAsIDUsIDAsIDE1LCAwLCAxLCAxMSwgMCwgMX07CisgICAgICAgIEFkbGVyMzIgYWRsZXIgPSBuZXcgQWRsZXIzMigpOworICAgICAgICBhZGxlci51cGRhdGUoYnl0ZXMpOworICAgICAgICBsb25nIGFycmF5Q2hlY2tzdW0gPSBhZGxlci5nZXRWYWx1ZSgpOworICAgICAgICBhZGxlci5yZXNldCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhZGxlci51cGRhdGUoYnl0ZXNbaV0pOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiQ2hlY2tzdW1zIG5vdCBlcXVhbDogZXhwZWN0ZWQ6ICIgKyBhcnJheUNoZWNrc3VtICsKKyAgICAgICAgICAgICAgICAiIGFjdHVhbDogIiArIGFkbGVyLmdldFZhbHVlKCksIGFycmF5Q2hlY2tzdW0sIGFkbGVyLmdldFZhbHVlKCkpOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ppcC9PbGRBbmRyb2lkRGVmbGF0ZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvT2xkQW5kcm9pZERlZmxhdGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjRkMDVlZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvT2xkQW5kcm9pZERlZmxhdGVUZXN0LmphdmEKQEAgLTAsMCArMSwxOTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLnppcDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkRhdGFGb3JtYXRFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLnppcC5EZWZsYXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkluZmxhdGVyOworCitwdWJsaWMgY2xhc3MgT2xkQW5kcm9pZERlZmxhdGVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdERlZmxhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2ltcGxlVGVzdCgpOworCisgICAgICAgIGJpZ1Rlc3QoMCwgMTczODE0OTYxOCk7CisgICAgICAgIGJpZ1Rlc3QoMSwgOTM0MzUwNTE4KTsKKyAgICAgICAgYmlnVGVzdCgyLCAtNTMyODY5MzkwKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFNpbXBsZSBpbmZsYXRlL2RlZmxhdGUgdGVzdCwgdGFrZW4gZnJvbSB0aGUgcmVmZXJlbmNlIGRvY3MgZm9yIHRoZQorICAgICAqIEluZmxhdGVyL0RlZmxhdGVyIGNsYXNzZXMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNpbXBsZVRlc3QoKQorICAgICAgICAgICAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24sIERhdGFGb3JtYXRFeGNlcHRpb24geworICAgICAgICAvLyBFbmNvZGUgYSBTdHJpbmcgaW50byBieXRlcworICAgICAgICBTdHJpbmcgaW5wdXRTdHJpbmcgPSAiYmxhaGJsYWhibGFoPz8iOworICAgICAgICBieXRlW10gaW5wdXQgPSBpbnB1dFN0cmluZy5nZXRCeXRlcygiVVRGLTgiKTsKKworICAgICAgICAvLyBDb21wcmVzcyB0aGUgYnl0ZXMKKyAgICAgICAgYnl0ZVtdIG91dHB1dCA9IG5ldyBieXRlWzEwMF07CisgICAgICAgIERlZmxhdGVyIGNvbXByZXNzZXIgPSBuZXcgRGVmbGF0ZXIoKTsKKyAgICAgICAgY29tcHJlc3Nlci5zZXRJbnB1dChpbnB1dCk7CisgICAgICAgIGNvbXByZXNzZXIuZmluaXNoKCk7CisgICAgICAgIGludCBjb21wcmVzc2VkRGF0YUxlbmd0aCA9IGNvbXByZXNzZXIuZGVmbGF0ZShvdXRwdXQpOworCisgICAgICAgIC8vIERlY29tcHJlc3MgdGhlIGJ5dGVzCisgICAgICAgIEluZmxhdGVyIGRlY29tcHJlc3NlciA9IG5ldyBJbmZsYXRlcigpOworICAgICAgICBkZWNvbXByZXNzZXIuc2V0SW5wdXQob3V0cHV0LCAwLCBjb21wcmVzc2VkRGF0YUxlbmd0aCk7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVsxMDBdOworICAgICAgICBpbnQgcmVzdWx0TGVuZ3RoID0gZGVjb21wcmVzc2VyLmluZmxhdGUocmVzdWx0KTsKKworICAgICAgICAvLyBEZWNvZGUgdGhlIGJ5dGVzIGludG8gYSBTdHJpbmcKKyAgICAgICAgU3RyaW5nIG91dHB1dFN0cmluZyA9IG5ldyBTdHJpbmcocmVzdWx0LCAwLCByZXN1bHRMZW5ndGgsICJVVEYtOCIpOworCisgICAgICAgIGFzc2VydEVxdWFscyhpbnB1dFN0cmluZywgb3V0cHV0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNvbXByZXNzZXIuZ2V0QWRsZXIoKSwgZGVjb21wcmVzc2VyLmdldEFkbGVyKCkpOworCisgICAgICAgIGRlY29tcHJlc3Nlci5lbmQoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqICJzdGVwIiBkZXRlcm1pbmVzIGhvdyBjb21wcmVzc2libGUgdGhlIGRhdGEgaXMuCisgICAgICoKKyAgICAgKiBOb3RlIHdlIG11c3Qgc2V0ICJub3dyYXAiIHRvIGZhbHNlLCBvciB0aGUgQWRsZXItMzIgZG9lc24ndCBnZXQKKyAgICAgKiBjb21wdXRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYmlnVGVzdChpbnQgc3RlcCwgaW50IGV4cGVjdGVkQWRsZXIpCisgICAgICAgICAgICB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgRGF0YUZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBpbnB1dCA9IG5ldyBieXRlWzEyOCAqIDEwMjRdOworICAgICAgICBieXRlW10gY29tcCA9IG5ldyBieXRlWzEyOCAqIDEwMjQgKyA1MTJdOworICAgICAgICBieXRlW10gb3V0cHV0ID0gbmV3IGJ5dGVbMTI4ICogMTAyNCArIDUxMl07CisgICAgICAgIEluZmxhdGVyIGluZmxhdGVyID0gbmV3IEluZmxhdGVyKGZhbHNlKTsKKyAgICAgICAgRGVmbGF0ZXIgZGVmbGF0ZXIgPSBuZXcgRGVmbGF0ZXIoRGVmbGF0ZXIuQkVTVF9DT01QUkVTU0lPTiwgZmFsc2UpOworCisgICAgICAgIGNyZWF0ZVNhbXBsZShpbnB1dCwgc3RlcCk7CisKKyAgICAgICAgY29tcHJlc3MoZGVmbGF0ZXIsIGlucHV0LCBjb21wKTsKKyAgICAgICAgZXhwYW5kKGluZmxhdGVyLCBjb21wLCAoaW50KSBkZWZsYXRlci5nZXRCeXRlc1dyaXR0ZW4oKSwgb3V0cHV0KTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoaW5mbGF0ZXIuZ2V0Qnl0ZXNXcml0dGVuKCksIGlucHV0Lmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscyhkZWZsYXRlci5nZXRBZGxlcigpLCBpbmZsYXRlci5nZXRBZGxlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGRlZmxhdGVyLmdldEFkbGVyKCksIGV4cGVjdGVkQWRsZXIpOworICAgIH0KKworICAgIC8qCisgICAgICogQ3JlYXRlIGEgbGFyZ2UgZGF0YSBzYW1wbGUuCisgICAgICogc3RlcFN0ZXAgPSAwIC0tPiA+OTklIGNvbXByZXNzaW9uCisgICAgICogc3RlcFN0ZXAgPSAxIC0tPiB+MzAlIGNvbXByZXNzaW9uCisgICAgICogc3RlcFN0ZXAgPSAyIC0tPiBubyBjb21wcmVzc2lvbgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjcmVhdGVTYW1wbGUoYnl0ZVtdIHNhbXBsZSwgaW50IHN0ZXBTdGVwKSB7CisgICAgICAgIGJ5dGUgdmFsLCBzdGVwOworICAgICAgICBpbnQgaSwgaiwgb2Zmc2V0OworCisgICAgICAgIGFzc2VydFRydWUoc2FtcGxlLmxlbmd0aCA+PSAxMjggKiAxMDI0KTsKKworICAgICAgICB2YWwgPSAwOworICAgICAgICBzdGVwID0gMTsKKyAgICAgICAgb2Zmc2V0ID0gMDsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8ICgxMjggKiAxMDI0KSAvIDI1NjsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgMjU2OyBqKyspIHsKKyAgICAgICAgICAgICAgICBzYW1wbGVbb2Zmc2V0KytdID0gdmFsOworICAgICAgICAgICAgICAgIHZhbCArPSBzdGVwOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzdGVwICs9IHN0ZXBTdGVwOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExPQ0FMX0JVRl9TSVpFID0gMjU2OworCisgICAgLyoKKyAgICAgKiBDb21wcmVzcyBhbGwgZGF0YSBpbiAiaW4iIHRvICJvdXQiLiAgV2UgdXNlIGEgc21hbGwgd2luZG93IG9uIGlucHV0CisgICAgICogYW5kIG91dHB1dCB0byBleGVyY2lzZSB0aGF0IHBhcnQgb2YgdGhlIGNvZGUuCisgICAgICoKKyAgICAgKiBJdCdzIHRoZSBjYWxsZXIncyByZXNwb25zaWJpbGl0eSB0byBlbnN1cmUgdGhhdCAib3V0IiBoYXMgZW5vdWdoCisgICAgICogc3BhY2UuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNvbXByZXNzKERlZmxhdGVyIGRlZmxhdGVyLCBieXRlW10gaW5CdWYsIGJ5dGVbXSBvdXRCdWYpIHsKKyAgICAgICAgaW50IGluQ291bnQgPSBpbkJ1Zi5sZW5ndGg7ICAgICAgICAvLyB1c2UgYWxsCisgICAgICAgIGludCBpblBvc247CisgICAgICAgIGludCBvdXRQb3NuOworCisgICAgICAgIGluUG9zbiA9IG91dFBvc24gPSAwOworCisgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCIjIyMgc3RhcnRpbmcgY29tcHJlc3MiKTsKKworICAgICAgICB3aGlsZSAoIWRlZmxhdGVyLmZpbmlzaGVkKCkpIHsKKyAgICAgICAgICAgIGludCB3YW50ID0gLTEsIGdvdDsKKworICAgICAgICAgICAgLy8gb25seSByZWFkIGlmIHRoZSBpbnB1dCBidWZmZXIgaXMgZW1wdHkKKyAgICAgICAgICAgIGlmIChkZWZsYXRlci5uZWVkc0lucHV0KCkgJiYgaW5Db3VudCAhPSAwKSB7CisgICAgICAgICAgICAgICAgd2FudCA9IChpbkNvdW50IDwgTE9DQUxfQlVGX1NJWkUpID8gaW5Db3VudCA6IExPQ0FMX0JVRl9TSVpFOworCisgICAgICAgICAgICAgICAgZGVmbGF0ZXIuc2V0SW5wdXQoaW5CdWYsIGluUG9zbiwgd2FudCk7CisKKyAgICAgICAgICAgICAgICBpbkNvdW50IC09IHdhbnQ7CisgICAgICAgICAgICAgICAgaW5Qb3NuICs9IHdhbnQ7CisgICAgICAgICAgICAgICAgaWYgKGluQ291bnQgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICBkZWZsYXRlci5maW5pc2goKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGRlZmxhdGUgdG8gY3VycmVudCBwb3NpdGlvbiBpbiBvdXRwdXQgYnVmZmVyCisgICAgICAgICAgICBpbnQgY29tcENvdW50OworCisgICAgICAgICAgICBjb21wQ291bnQgPSBkZWZsYXRlci5kZWZsYXRlKG91dEJ1Ziwgb3V0UG9zbiwgTE9DQUxfQlVGX1NJWkUpOworICAgICAgICAgICAgb3V0UG9zbiArPSBjb21wQ291bnQ7CisKKyAgICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJDb21wcmVzc2VkICIgKyB3YW50ICsgIiwgb3V0cHV0ICIgKyBjb21wQ291bnQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBFeHBhbmQgZGF0YSBmcm9tICJpbkJ1ZiIgdG8gIm91dEJ1ZiIuICBVc2VzIGEgc21hbGwgd2luZG93IHRvIGJldHRlcgorICAgICAqIGV4ZXJjaXNlIHRoZSBjb2RlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBleHBhbmQoSW5mbGF0ZXIgaW5mbGF0ZXIsIGJ5dGVbXSBpbkJ1ZiwgaW50IGluQ291bnQsCisgICAgICAgICAgICBieXRlW10gb3V0QnVmKSB0aHJvd3MgRGF0YUZvcm1hdEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBpblBvc247CisgICAgICAgIGludCBvdXRQb3NuOworCisgICAgICAgIGluUG9zbiA9IG91dFBvc24gPSAwOworCisgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCIjIyMgc3RhcnRpbmcgZXhwYW5kLCBpbkNvdW50IGlzICIgKyBpbkNvdW50KTsKKworICAgICAgICB3aGlsZSAoIWluZmxhdGVyLmZpbmlzaGVkKCkpIHsKKyAgICAgICAgICAgIGludCB3YW50ID0gLTEsIGdvdDsKKworICAgICAgICAgICAgLy8gb25seSByZWFkIGlmIHRoZSBpbnB1dCBidWZmZXIgaXMgZW1wdHkKKyAgICAgICAgICAgIGlmIChpbmZsYXRlci5uZWVkc0lucHV0KCkgJiYgaW5Db3VudCAhPSAwKSB7CisgICAgICAgICAgICAgICAgd2FudCA9IChpbkNvdW50IDwgTE9DQUxfQlVGX1NJWkUpID8gaW5Db3VudCA6IExPQ0FMX0JVRl9TSVpFOworCisgICAgICAgICAgICAgICAgaW5mbGF0ZXIuc2V0SW5wdXQoaW5CdWYsIGluUG9zbiwgd2FudCk7CisKKyAgICAgICAgICAgICAgICBpbkNvdW50IC09IHdhbnQ7CisgICAgICAgICAgICAgICAgaW5Qb3NuICs9IHdhbnQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGluZmxhdGUgdG8gY3VycmVudCBwb3NpdGlvbiBpbiBvdXRwdXQgYnVmZmVyCisgICAgICAgICAgICBpbnQgY29tcENvdW50OworCisgICAgICAgICAgICBjb21wQ291bnQgPSBpbmZsYXRlci5pbmZsYXRlKG91dEJ1Ziwgb3V0UG9zbiwgTE9DQUxfQlVGX1NJWkUpOworICAgICAgICAgICAgb3V0UG9zbiArPSBjb21wQ291bnQ7CisKKyAgICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJFeHBhbmRlZCAiICsgd2FudCArICIsIG91dHB1dCAiICsgY29tcENvdW50KTsKKyAgICAgICAgfQorICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ppcC9PbGRBbmRyb2lkR1pJUFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvT2xkQW5kcm9pZEdaSVBTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTVjNDBjZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvT2xkQW5kcm9pZEdaSVBTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSwxMTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLnppcDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkdaSVBJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkdaSVBPdXRwdXRTdHJlYW07CisKKy8qKgorICogRGVmbGF0ZXMgYW5kIGluZmxhdGVzIHNvbWUgdGVzdCBkYXRhIHdpdGggR1ppcFN0cmVhbXMKKyAqLworcHVibGljIGNsYXNzIE9sZEFuZHJvaWRHWklQU3RyZWFtVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RHWklQU3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBieXRlc091dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgY3JlYXRlR1pJUChieXRlc091dCk7CisKKyAgICAgICAgYnl0ZVtdIHppcERhdGE7CisgICAgICAgIHppcERhdGEgPSBieXRlc091dC50b0J5dGVBcnJheSgpOworCisgICAgICAgIC8qCisgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gb3V0RmlsZSA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKCIvdG1wL2Zvby5neiIpOworICAgICAgICBvdXRGaWxlLndyaXRlKHppcERhdGEsIDAsIHppcERhdGEubGVuZ3RoKTsKKyAgICAgICAgb3V0RmlsZS5jbG9zZSgpOworICAgICAgICAqLworCisgICAgICAgIC8qCisgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBpbkZpbGUgPSBuZXcgRmlsZUlucHV0U3RyZWFtKCIvdG1wL2Zvby5neiIpOworICAgICAgICBpbnQgaW5wdXRMZW5ndGggPSBpbkZpbGUuYXZhaWxhYmxlKCk7CisgICAgICAgIHppcERhdGEgPSBuZXcgYnl0ZVtpbnB1dExlbmd0aF07CisgICAgICAgIGlmIChpbkZpbGUucmVhZCh6aXBEYXRhKSAhPSBpbnB1dExlbmd0aCkKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCk7CisgICAgICAgIGluRmlsZS5jbG9zZSgpOworICAgICAgICAqLworCisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJ5dGVzSW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oemlwRGF0YSk7CisgICAgICAgIHNjYW5HWklQKGJ5dGVzSW4pOworICAgIH0KKworICAgIC8qCisgICAgICogc3RlcFN0ZXAgPT0gMCAtLT4gPjk5JSBjb21wcmVzc2lvbgorICAgICAqIHN0ZXBTdGVwID09IDEgLS0+IH4zMCUgY29tcHJlc3Npb24KKyAgICAgKiBzdGVwU3RlcCA9PSAyIC0tPiBubyBjb21wcmVzc2lvbgorICAgICAqLworICAgIHN0YXRpYyBieXRlW10gbWFrZVNhbXBsZUZpbGUoaW50IHN0ZXBTdGVwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gc2FtcGxlID0gbmV3IGJ5dGVbMTI4ICogMTAyNF07CisgICAgICAgIGJ5dGUgdmFsLCBzdGVwOworICAgICAgICBpbnQgaSwgaiwgb2Zmc2V0OworCisgICAgICAgIHZhbCA9IDA7CisgICAgICAgIHN0ZXAgPSAxOworICAgICAgICBvZmZzZXQgPSAwOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgKDEyOCAqIDEwMjQpIC8gMjU2OyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCAyNTY7IGorKykgeworICAgICAgICAgICAgICAgIHNhbXBsZVtvZmZzZXQrK10gPSB2YWw7CisgICAgICAgICAgICAgICAgdmFsICs9IHN0ZXA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHN0ZXAgKz0gc3RlcFN0ZXA7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gc2FtcGxlOworICAgIH0KKworICAgIHN0YXRpYyB2b2lkIGNyZWF0ZUdaSVAoQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVzT3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBHWklQT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBHWklQT3V0cHV0U3RyZWFtKGJ5dGVzT3V0KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ5dGVbXSBpbnB1dCA9IG1ha2VTYW1wbGVGaWxlKDEpOworICAgICAgICAgICAgb3V0LndyaXRlKGlucHV0LCAwLCBpbnB1dC5sZW5ndGgpOworICAgICAgICAgICAgLy9vdXQuZmluaXNoKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyB2b2lkIHNjYW5HWklQKEJ5dGVBcnJheUlucHV0U3RyZWFtIGJ5dGVzSW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEdaSVBJbnB1dFN0cmVhbSBpbiA9IG5ldyBHWklQSW5wdXRTdHJlYW0oYnl0ZXNJbik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gY29udGVudHMgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbNDA5Nl07CisgICAgICAgICAgICBpbnQgbGVuLCB0b3RhbExlbiA9IDA7CisKKyAgICAgICAgICAgIHdoaWxlICgobGVuID0gaW4ucmVhZChidWYpKSA+IDApIHsKKyAgICAgICAgICAgICAgICBjb250ZW50cy53cml0ZShidWYsIDAsIGxlbik7CisgICAgICAgICAgICAgICAgdG90YWxMZW4gKz0gbGVuOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBhc3NlcnRFcXVhbHModG90YWxMZW4sIDEyOCAqIDEwMjQpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ppcC9PbGRBbmRyb2lkWmlwRmlsZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvT2xkQW5kcm9pZFppcEZpbGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTdjMGY2MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvT2xkQW5kcm9pZFppcEZpbGVUZXN0LmphdmEKQEAgLTAsMCArMSwxOTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLnppcDsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEVudHJ5OworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRmlsZTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKworLyoqCisgKiBCYXNpYyB0ZXN0cyBmb3IgWmlwRmlsZS4KKyAqLworcHVibGljIGNsYXNzIE9sZEFuZHJvaWRaaXBGaWxlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0FNUExFX1NJWkUgPSAxMjggKiAxMDI0OworCisgICAgcHVibGljIHZvaWQgdGVzdFppcEZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBGaWxlIGZpbGUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJaaXBGaWxlVGVzdCIsICIuemlwIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBjcmVhdGUgYSB0ZXN0IGZpbGU7IGFzc3VtZSBpdCdzIG5vdCBnb2luZyB0byBjb2xsaWRlIHcvYW55dGhpbmcKKyAgICAgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gb3V0U3RyZWFtID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZSk7CisgICAgICAgICAgICBjcmVhdGVDb21wcmVzc2VkWmlwKG91dFN0cmVhbSk7CisKKyAgICAgICAgICAgIHNjYW5aaXAoZmlsZS5nZXRQYXRoKCkpOworICAgICAgICAgICAgcmVhZDIoZmlsZS5nZXRQYXRoKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZmlsZS5kZWxldGUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogc3RlcFN0ZXAgPT0gMCAtLT4gPjk5JSBjb21wcmVzc2lvbgorICAgICAqIHN0ZXBTdGVwID09IDEgLS0+IH4zMCUgY29tcHJlc3Npb24KKyAgICAgKiBzdGVwU3RlcCA9PSAyIC0tPiBubyBjb21wcmVzc2lvbgorICAgICAqLworICAgIHN0YXRpYyBieXRlW10gbWFrZVNhbXBsZUZpbGUoaW50IHN0ZXBTdGVwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gc2FtcGxlID0gbmV3IGJ5dGVbU0FNUExFX1NJWkVdOworICAgICAgICBieXRlIHZhbCwgc3RlcDsKKyAgICAgICAgaW50IGksIGosIG9mZnNldDsKKworICAgICAgICB2YWwgPSAwOworICAgICAgICBzdGVwID0gMTsKKyAgICAgICAgb2Zmc2V0ID0gMDsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IFNBTVBMRV9TSVpFIC8gMjU2OyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCAyNTY7IGorKykgeworICAgICAgICAgICAgICAgIHNhbXBsZVtvZmZzZXQrK10gPSB2YWw7CisgICAgICAgICAgICAgICAgdmFsICs9IHN0ZXA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHN0ZXAgKz0gc3RlcFN0ZXA7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gc2FtcGxlOworICAgIH0KKworICAgIHN0YXRpYyB2b2lkIGNyZWF0ZUNvbXByZXNzZWRaaXAoT3V0cHV0U3RyZWFtIGJ5dGVzT3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBaaXBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IFppcE91dHB1dFN0cmVhbShieXRlc091dCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgaTsKKworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IDM7IGkrKykgeworICAgICAgICAgICAgICAgIGJ5dGVbXSBpbnB1dCA9IG1ha2VTYW1wbGVGaWxlKGkpOworICAgICAgICAgICAgICAgIFppcEVudHJ5IG5ld0VudHJ5ID0gbmV3IFppcEVudHJ5KCJmaWxlLSIgKyBpKTsKKworICAgICAgICAgICAgICAgIGlmIChpICE9IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgbmV3RW50cnkuc2V0Q29tbWVudCgidGhpcyBpcyBmaWxlICIgKyBpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgb3V0LnB1dE5leHRFbnRyeShuZXdFbnRyeSk7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlKGlucHV0LCAwLCBpbnB1dC5sZW5ndGgpOworICAgICAgICAgICAgICAgIG91dC5jbG9zZUVudHJ5KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIG91dC5zZXRDb21tZW50KCJUaGlzIGlzIGEgbG92ZWx5IGNvbXByZXNzZWQgYXJjaGl2ZSEiKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIHZvaWQgc2NhblppcChTdHJpbmcgZmlsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFppcEZpbGUgemlwRmlsZSA9IG5ldyBaaXBGaWxlKGZpbGVOYW1lKTsKKyAgICAgICAgRW51bWVyYXRpb24gZmlsZUxpc3Q7CisgICAgICAgIGludCBpZHggPSAwOworCisvLyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJDb250ZW50cyBvZiAiICsgemlwRmlsZSArICI6Iik7CisgICAgICAgIGZvciAoZmlsZUxpc3QgPSB6aXBGaWxlLmVudHJpZXMoKTsgZmlsZUxpc3QuaGFzTW9yZUVsZW1lbnRzKCk7KSB7CisgICAgICAgICAgICBaaXBFbnRyeSBlbnRyeSA9IChaaXBFbnRyeSkgZmlsZUxpc3QubmV4dEVsZW1lbnQoKTsKKy8vICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgICIgKyBlbnRyeS5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGVudHJ5LmdldE5hbWUoKSwgImZpbGUtIiArIGlkeCk7CisgICAgICAgICAgICBpZHgrKzsKKyAgICAgICAgfQorCisgICAgICAgIHppcEZpbGUuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFJlYWQgY29tcHJlc3NlZCBkYXRhIGZyb20gdHdvIGRpZmZlcmVudCBlbnRyaWVzIGF0IHRoZSBzYW1lIHRpbWUsCisgICAgICogdG8gdmVyaWZ5IHRoYXQgdGhlIHN0cmVhbXMgYXJlbid0IGdldHRpbmcgY29uZnVzZWQuICBJZiB3ZSBkbworICAgICAqIHNvbWV0aGluZyB3cm9uZywgdGhlIGluZmxhdGVyIHdpbGwgY2hva2UgYW5kIHRocm93IGEgWmlwRXhjZXB0aW9uLgorICAgICAqCisgICAgICogVGhpcyBkb2Vzbid0IHRlc3Qgc3luY2hyb25pemF0aW9uIGluIG11bHRpLXRocmVhZGVkIHVzZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgdm9pZCByZWFkMihTdHJpbmcgZmlsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFppcEZpbGUgemlwRmlsZTsKKyAgICAgICAgWmlwRW50cnkgZW50cnkxLCBlbnRyeTI7CisgICAgICAgIGJ5dGUgYnVmW10gPSBuZXcgYnl0ZVsxNjM4NF07CisgICAgICAgIElucHV0U3RyZWFtIHN0cmVhbTEsIHN0cmVhbTI7CisgICAgICAgIGludCBsZW4sIHRvdGFsTGVuMSwgdG90YWxMZW4yOworCisgICAgICAgIC8qIHVzZSBmaWxlLTEgYW5kIGZpbGUtMiBiZWNhdXNlIHRoZSBjb21wcmVzc2VkIGRhdGEgaXMgbGFyZ2UgKi8KKyAgICAgICAgemlwRmlsZSA9IG5ldyBaaXBGaWxlKGZpbGVOYW1lKTsKKyAgICAgICAgZW50cnkxID0gemlwRmlsZS5nZXRFbnRyeSgiZmlsZS0xIik7CisgICAgICAgIGVudHJ5MiA9IHppcEZpbGUuZ2V0RW50cnkoImZpbGUtMiIpOworCisgICAgICAgIC8qIG1ha2Ugc3VyZSB3ZSBnb3QgdGhlIHJpZ2h0IHRoaW5nICovCisgICAgICAgIGFzc2VydEVxdWFscygiZmlsZS0xIiwgZW50cnkxLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZmlsZS0yIiwgZW50cnkyLmdldE5hbWUoKSk7CisKKyAgICAgICAgLyogY3JlYXRlIHN0cmVhbXMgKi8KKyAgICAgICAgc3RyZWFtMSA9IHppcEZpbGUuZ2V0SW5wdXRTdHJlYW0oZW50cnkxKTsKKyAgICAgICAgc3RyZWFtMiA9IHppcEZpbGUuZ2V0SW5wdXRTdHJlYW0oZW50cnkyKTsKKworICAgICAgICAvKgorICAgICAgICAgKiBSZWFkIGEgcGllY2Ugb2YgZmlsZSAjMS4KKyAgICAgICAgICovCisgICAgICAgIHRvdGFsTGVuMSA9IHN0cmVhbTEucmVhZChidWYpOworICAgICAgICBhc3NlcnRUcnVlKCJpbml0aWFsIHJlYWQgZmFpbGVkIG9uICMxIiwgdG90YWxMZW4xID49IDApOworCisgICAgICAgIC8qCisgICAgICAgICAqIFJlYWQgYSBwaWVjZSBvZiBmaWxlICMyLgorICAgICAgICAgKi8KKyAgICAgICAgdG90YWxMZW4yID0gc3RyZWFtMi5yZWFkKGJ1Zik7CisgICAgICAgIGFzc2VydFRydWUoImluaXRpYWwgcmVhZCBmYWlsZWQgb24gIzIiLCB0b3RhbExlbjIgPj0gMCk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogUmVhZCB0aGUgcmVzdCBvZiBmaWxlICMxLCBhbmQgY2xvc2UgdGhlIHN0cmVhbS4KKyAgICAgICAgICoKKyAgICAgICAgICogSWYgb3VyIHN0cmVhbXMgYXJlIGNyb3NzZWQgdXAsIHdlJ2xsIGZhaWwgaGVyZS4KKyAgICAgICAgICovCisgICAgICAgIHdoaWxlICgobGVuID0gc3RyZWFtMS5yZWFkKGJ1ZikpID4gMCkgeworICAgICAgICAgICAgdG90YWxMZW4xICs9IGxlbjsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoU0FNUExFX1NJWkUsIHRvdGFsTGVuMSk7CisgICAgICAgIHN0cmVhbTEuY2xvc2UoKTsKKworICAgICAgICAvKgorICAgICAgICAgKiBSZWFkIHRoZSByZXN0IG9mIGZpbGUgIzIsIGFuZCBjbG9zZSB0aGUgc3RyZWFtLgorICAgICAgICAgKi8KKyAgICAgICAgd2hpbGUgKChsZW4gPSBzdHJlYW0yLnJlYWQoYnVmKSkgPiAwKSB7CisgICAgICAgICAgICB0b3RhbExlbjIgKz0gbGVuOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyhTQU1QTEVfU0laRSwgdG90YWxMZW4yKTsKKyAgICAgICAgc3RyZWFtMi5jbG9zZSgpOworCisgICAgICAgIC8qCisgICAgICAgICAqIE9wZW4gYSBuZXcgb25lLgorICAgICAgICAgKi8KKyAgICAgICAgc3RyZWFtMSA9IHppcEZpbGUuZ2V0SW5wdXRTdHJlYW0oemlwRmlsZS5nZXRFbnRyeSgiZmlsZS0wIikpOworCisgICAgICAgIC8qCisgICAgICAgICAqIENsb3NlIHRoZSBaaXBGaWxlLiBBY2NvcmRpbmcgdG8gdGhlIFJJLCBub25lIGlmIGl0cyBJbnB1dFN0cmVhbXMgY2FuCisgICAgICAgICAqIGJlIHJlYWQgYWZ0ZXIgdGhpcyBwb2ludC4KKyAgICAgICAgICovCisgICAgICAgIHppcEZpbGUuY2xvc2UoKTsKKworICAgICAgICBFeGNlcHRpb24gZXJyb3IgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RyZWFtMS5yZWFkKGJ1Zik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZXJyb3IgPSBleDsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydE5vdE51bGwoIlppcEZpbGUgc2hvdWxkbid0IGFsbG93IHJlYWRpbmcgb2YgY2xvc2VkIGZpbGVzLiIsIGVycm9yKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvT2xkQW5kcm9pZFppcFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvT2xkQW5kcm9pZFppcFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOGI2YzVhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ppcC9PbGRBbmRyb2lkWmlwU3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTY4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC56aXA7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFbnRyeTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcElucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwT3V0cHV0U3RyZWFtOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBCYXNpYyB0ZXN0cyBmb3IgWmlwU3RyZWFtCisgKi8KK3B1YmxpYyBjbGFzcyBPbGRBbmRyb2lkWmlwU3RyZWFtVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RaaXBTdHJlYW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVzT3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBjcmVhdGVDb21wcmVzc2VkWmlwKGJ5dGVzT3V0KTsKKworICAgICAgICBieXRlW10gemlwRGF0YSA9IGJ5dGVzT3V0LnRvQnl0ZUFycmF5KCk7CisKKyAgICAgICAgLyoKKyAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBvdXRGaWxlID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oIi90bXAvZm9vLnppcCIpOworICAgICAgICBvdXRGaWxlLndyaXRlKHppcERhdGEsIDAsIHppcERhdGEubGVuZ3RoKTsKKyAgICAgICAgb3V0RmlsZS5jbG9zZSgpOworICAgICAgICAqLworCisgICAgICAgIC8qCisgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBpbkZpbGUgPSBuZXcgRmlsZUlucHV0U3RyZWFtKCIvdG1wL2Zvby56aXAiKTsKKyAgICAgICAgaW50IGlucHV0TGVuZ3RoID0gaW5GaWxlLmF2YWlsYWJsZSgpOworICAgICAgICB6aXBEYXRhID0gbmV3IGJ5dGVbaW5wdXRMZW5ndGhdOworICAgICAgICBpZiAoaW5GaWxlLnJlYWQoemlwRGF0YSkgIT0gaW5wdXRMZW5ndGgpCisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigpOworICAgICAgICBpbkZpbGUuY2xvc2UoKTsKKyAgICAgICAgKi8KKworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBieXRlc0luID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHppcERhdGEpOworICAgICAgICBzY2FuWmlwKGJ5dGVzSW4pOworCisgICAgICAgIGJ5dGVzT3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBjcmVhdGVVbmNvbXByZXNzZWRaaXAoYnl0ZXNPdXQpOworCisgICAgICAgIHppcERhdGEgPSBieXRlc091dC50b0J5dGVBcnJheSgpOworCisgICAgICAgIGJ5dGVzSW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oemlwRGF0YSk7CisgICAgICAgIHNjYW5aaXAoYnl0ZXNJbik7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBzdGVwU3RlcCA9PSAwIC0tPiA+OTklIGNvbXByZXNzaW9uCisgICAgICogc3RlcFN0ZXAgPT0gMSAtLT4gfjMwJSBjb21wcmVzc2lvbgorICAgICAqIHN0ZXBTdGVwID09IDIgLS0+IG5vIGNvbXByZXNzaW9uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdIG1ha2VTYW1wbGVGaWxlKGludCBzdGVwU3RlcCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIHNhbXBsZSA9IG5ldyBieXRlWzEyOCAqIDEwMjRdOworICAgICAgICBieXRlIHZhbCwgc3RlcDsKKyAgICAgICAgaW50IGksIGosIG9mZnNldDsKKworICAgICAgICB2YWwgPSAwOworICAgICAgICBzdGVwID0gMTsKKyAgICAgICAgb2Zmc2V0ID0gMDsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8ICgxMjggKiAxMDI0KSAvIDI1NjsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgMjU2OyBqKyspIHsKKyAgICAgICAgICAgICAgICBzYW1wbGVbb2Zmc2V0KytdID0gdmFsOworICAgICAgICAgICAgICAgIHZhbCArPSBzdGVwOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzdGVwICs9IHN0ZXBTdGVwOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHNhbXBsZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNyZWF0ZUNvbXByZXNzZWRaaXAoQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVzT3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBaaXBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IFppcE91dHB1dFN0cmVhbShieXRlc091dCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgaTsKKworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IDM7IGkrKykgeworICAgICAgICAgICAgICAgIGJ5dGVbXSBpbnB1dCA9IG1ha2VTYW1wbGVGaWxlKGkpOworICAgICAgICAgICAgICAgIFppcEVudHJ5IG5ld0VudHJ5ID0gbmV3IFppcEVudHJ5KCJmaWxlLSIgKyBpKTsKKworICAgICAgICAgICAgICAgIGlmIChpICE9IDEpCisgICAgICAgICAgICAgICAgICAgIG5ld0VudHJ5LnNldENvbW1lbnQoInRoaXMgaXMgZmlsZSAiICsgaSk7CisgICAgICAgICAgICAgICAgb3V0LnB1dE5leHRFbnRyeShuZXdFbnRyeSk7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlKGlucHV0LCAwLCBpbnB1dC5sZW5ndGgpOworICAgICAgICAgICAgICAgIG91dC5jbG9zZUVudHJ5KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIG91dC5zZXRDb21tZW50KCJUaGlzIGlzIGEgbG92ZWx5IGNvbXByZXNzZWQgYXJjaGl2ZSEiKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjcmVhdGVVbmNvbXByZXNzZWRaaXAoQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVzT3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBaaXBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IFppcE91dHB1dFN0cmVhbShieXRlc091dCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsb25nW10gY3JjcyA9IHsweDIwNWZiZmYzLCAweDkwNmZhZTU3TCwgMHgyYzIzNTEzMX07CisgICAgICAgICAgICBpbnQgaTsKKworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IDM7IGkrKykgeworICAgICAgICAgICAgICAgIGJ5dGVbXSBpbnB1dCA9IG1ha2VTYW1wbGVGaWxlKGkpOworICAgICAgICAgICAgICAgIFppcEVudHJ5IG5ld0VudHJ5ID0gbmV3IFppcEVudHJ5KCJmaWxlLSIgKyBpKTsKKworICAgICAgICAgICAgICAgIGlmIChpICE9IDEpCisgICAgICAgICAgICAgICAgICAgIG5ld0VudHJ5LnNldENvbW1lbnQoInRoaXMgaXMgZmlsZSAiICsgaSk7CisgICAgICAgICAgICAgICAgbmV3RW50cnkuc2V0TWV0aG9kKFppcEVudHJ5LlNUT1JFRCk7CisgICAgICAgICAgICAgICAgbmV3RW50cnkuc2V0U2l6ZSgxMjggKiAxMDI0KTsKKyAgICAgICAgICAgICAgICBuZXdFbnRyeS5zZXRDcmMoY3Jjc1tpXSk7CisgICAgICAgICAgICAgICAgb3V0LnB1dE5leHRFbnRyeShuZXdFbnRyeSk7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlKGlucHV0LCAwLCBpbnB1dC5sZW5ndGgpOworICAgICAgICAgICAgICAgIG91dC5jbG9zZUVudHJ5KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIG91dC5zZXRDb21tZW50KCJUaGlzIGlzIGEgbG92ZWx5LCBidXQgdW5jb21wcmVzc2VkLCBhcmNoaXZlISIpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHNjYW5aaXAoQnl0ZUFycmF5SW5wdXRTdHJlYW0gYnl0ZXNJbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgWmlwSW5wdXRTdHJlYW0gaW4gPSBuZXcgWmlwSW5wdXRTdHJlYW0oYnl0ZXNJbik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgaTsKKworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IDM7IGkrKykgeworICAgICAgICAgICAgICAgIFppcEVudHJ5IGVudHJ5ID0gaW4uZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgICAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGNvbnRlbnRzID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVs0MDk2XTsKKyAgICAgICAgICAgICAgICBpbnQgbGVuLCB0b3RhbExlbiA9IDA7CisKKyAgICAgICAgICAgICAgICB3aGlsZSAoKGxlbiA9IGluLnJlYWQoYnVmKSkgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRzLndyaXRlKGJ1ZiwgMCwgbGVuKTsKKyAgICAgICAgICAgICAgICAgICAgdG90YWxMZW4gKz0gbGVuOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxMjggKiAxMDI0LCB0b3RhbExlbik7CisKKy8vICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiT2xkQW5kcm9pZFppcFN0cmVhbVRlc3Q6IG5hbWU9JyIgKyBlbnRyeS5nZXROYW1lKCkKKy8vICAgICAgICAgICAgICAgICAgICAgICAgKyAiJywgemVybz0iICsgY29udGVudHMudG9CeXRlQXJyYXkoKVswXQorLy8gICAgICAgICAgICAgICAgICAgICAgICArICIsIHRmcz0iICsgY29udGVudHMudG9CeXRlQXJyYXkoKVsyNTddCisvLyAgICAgICAgICAgICAgICAgICAgICAgICsgIiwgY3JjPSIgKyBMb25nLnRvSGV4U3RyaW5nKGVudHJ5LmdldENyYygpKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGFzc2VydE51bGwoInNob3VsZCBvbmx5IGJlIHRocmVlIGVudHJpZXMiLCBpbi5nZXROZXh0RW50cnkoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvemlwL09sZERhdGFGb3JtYXRFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvemlwL09sZERhdGFGb3JtYXRFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzQzOWNkOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvT2xkRGF0YUZvcm1hdEV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDM1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEudXRpbC56aXA7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkRhdGFGb3JtYXRFeGNlcHRpb247CisKK3B1YmxpYyBjbGFzcyBPbGREYXRhRm9ybWF0RXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3REYXRhRm9ybWF0RXhjZXB0aW9uKCkgeworICAgICAgICBEYXRhRm9ybWF0RXhjZXB0aW9uIGRmZSA9IG5ldyBEYXRhRm9ybWF0RXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhkZmUuZ2V0TWVzc2FnZSgpLCBudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGF0YUZvcm1hdEV4Y2VwdGlvblN0cmluZygpIHsKKyAgICAgICAgRGF0YUZvcm1hdEV4Y2VwdGlvbiBkZmUgPSBuZXcgRGF0YUZvcm1hdEV4Y2VwdGlvbigiVGVzdCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoZGZlLmdldE1lc3NhZ2UoKSwgIlRlc3QiKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvT2xkWmlwRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ppcC9PbGRaaXBFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjQ0ZmJmNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvT2xkWmlwRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLnppcDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgT2xkWmlwRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RaaXBFeGNlcHRpb24oKSB7CisgICAgICAgIFppcEV4Y2VwdGlvbiB6eiA9IG5ldyBaaXBFeGNlcHRpb24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHp6LmdldE1lc3NhZ2UoKSwgbnVsbCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFppcEV4Y2VwdGlvbkxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICBaaXBFeGNlcHRpb24genogPSBuZXcgWmlwRXhjZXB0aW9uKCJUZXN0Iik7CisgICAgICAgIGFzc2VydEVxdWFscyh6ei5nZXRNZXNzYWdlKCksICJUZXN0Iik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvemlwL09sZFppcEZpbGVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvemlwL09sZFppcEZpbGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWYyODY0YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvT2xkWmlwRmlsZVRlc3QuamF2YQpAQCAtMCwwICsxLDE5NiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWwuemlwOworCitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1BsYXRmb3JtRmlsZTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LnJlc291cmNlLlN1cHBvcnRfUmVzb3VyY2VzOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVQZXJtaXNzaW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRW50cnk7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBGaWxlOworCitwdWJsaWMgY2xhc3MgT2xkWmlwRmlsZVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgcHVibGljIGJ5dGVbXSBnZXRBbGxCeXRlc0Zyb21TdHJlYW0oSW5wdXRTdHJlYW0gaXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBicyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzUxMl07CisgICAgICAgIGludCBpUmVhZDsKKyAgICAgICAgd2hpbGUgKChpUmVhZCA9IGlzLnJlYWQoYnVmLCAwLCBidWYubGVuZ3RoKSkgIT0gLTEpIHsKKyAgICAgICAgICAgIGJzLndyaXRlKGJ1ZiwgMCwgaVJlYWQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBicy50b0J5dGVBcnJheSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2l6ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHpmaWxlLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB6ZmlsZS5zaXplKCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEVudHJ5TGphdmFfbGFuZ19TdHJpbmdfQW5kcm9pZE9ubHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBqYXZhLnV0aWwuemlwLlppcEVudHJ5IHplbnRyeSA9IHpmaWxlLmdldEVudHJ5KCJGaWxlMS50eHQiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ291bGQgbm90IG9idGFpbiBaaXBFbnRyeSIsIHplbnRyeSk7CisgICAgICAgIGludCByOworICAgICAgICBJbnB1dFN0cmVhbSBpbjsKKworICAgICAgICB6ZW50cnkgPSB6ZmlsZS5nZXRFbnRyeSgidGVzdGRpcjEiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTXVzdCBiZSBhYmxlIHRvIG9idGFpbiBaaXBFbnRyeTogdGVzdGRpcjEiLCB6ZW50cnkpOworICAgICAgICBpbiA9IHpmaWxlLmdldElucHV0U3RyZWFtKHplbnRyeSk7CisgICAgICAgIC8qCisgICAgICAgICAqIEFuZHJvaWQgZGVsaXZlcnMgZW1wdHkgSW5wdXRTdHJlYW0sIFJJIG5vIElucHV0U3RyZWFtIGF0IGFsbC4gVGhlCisgICAgICAgICAqIHNwZWMgZG9lc24ndCBjbGFyaWZ5IHRoaXMsIHNvIHdlIG5lZWQgdG8gZGVhbCB3aXRoIGJvdGggc2l0dWF0aW9ucy4KKyAgICAgICAgICovCisgICAgICAgIGludCBkYXRhID0gLTE7CisgICAgICAgIGlmIChpbiAhPSBudWxsKSB7CisgICAgICAgICAgICBkYXRhID0gaW4ucmVhZCgpOworICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIk11c3Qgbm90IGJlIGFibGUgdG8gcmVhZCBkaXJlY3RvcnkgZGF0YSIsIC0xLCBkYXRhKTsKKyAgICB9CisKKyAgICAvLyB0aGUgZmlsZSBoeXRzX3ppcEZpbGUuemlwIGluIHNldHVwIG11c3QgYmUgaW5jbHVkZWQgYXMgYSByZXNvdXJjZQorICAgIHByaXZhdGUgU3RyaW5nIHRlbXBGaWxlTmFtZTsKKworICAgIHByaXZhdGUgWmlwRmlsZSB6ZmlsZTsKKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBqYXZhLnV0aWwuemlwLlppcEZpbGUjY2xvc2UoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuemlwLlppcEZpbGUuY2xvc2UoKQorICAgICAgICBGaWxlIGZsID0gbmV3IEZpbGUodGVtcEZpbGVOYW1lKTsKKyAgICAgICAgWmlwRmlsZSB6ZiA9IG5ldyBaaXBGaWxlKGZsKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMxID0gemYuZ2V0SW5wdXRTdHJlYW0oemYuZ2V0RW50cnkoIkZpbGUxLnR4dCIpKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMyID0gemYuZ2V0SW5wdXRTdHJlYW0oemYuZ2V0RW50cnkoIkZpbGUyLnR4dCIpKTsKKworICAgICAgICBpczEucmVhZCgpOworICAgICAgICBpczIucmVhZCgpOworCisgICAgICAgIHpmLmNsb3NlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzMS5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpczIucmVhZCgpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEVudHJ5TGphdmFfbGFuZ19TdHJpbmdfRXgoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBqYXZhLnV0aWwuemlwLlppcEVudHJ5IHplbnRyeSA9IHpmaWxlLmdldEVudHJ5KCJGaWxlMS50eHQiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ291bGQgbm90IG9idGFpbiBaaXBFbnRyeSIsIHplbnRyeSk7CisKKyAgICAgICAgemZpbGUuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHpmaWxlLmdldEVudHJ5KCJGaWxlMi50eHQiKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBqYXZhLnV0aWwuemlwLlppcEZpbGUjZ2V0SW5wdXRTdHJlYW0oamF2YS51dGlsLnppcC5aaXBFbnRyeSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldElucHV0U3RyZWFtTGphdmFfdXRpbF96aXBfWmlwRW50cnkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5pby5JbnB1dFN0cmVhbQorICAgICAgICAvLyBqYXZhLnV0aWwuemlwLlppcEZpbGUuZ2V0SW5wdXRTdHJlYW0oamF2YS51dGlsLnppcC5aaXBFbnRyeSkKKyAgICAgICAgWmlwRW50cnkgemVudHJ5ID0gbnVsbDsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBudWxsOworCisgICAgICAgIHplbnRyeSA9IHpmaWxlLmdldEVudHJ5KCJGaWxlMi50eHQiKTsKKyAgICAgICAgemZpbGUuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzID0gemZpbGUuZ2V0SW5wdXRTdHJlYW0oemVudHJ5KTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIENyZWF0ZSBhIGxvY2FsIGNvcHkgb2YgdGhlIGZpbGUgc2luY2Ugc29tZSB0ZXN0cyB3YW50IHRvIGFsdGVyIGluZm9ybWF0aW9uLgorICAgICAgICB0ZW1wRmlsZU5hbWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaW8udG1wZGlyIik7CisgICAgICAgIFN0cmluZyBzZXBhcmF0b3IgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImZpbGUuc2VwYXJhdG9yIik7CisgICAgICAgIGlmICh0ZW1wRmlsZU5hbWUuY2hhckF0KHRlbXBGaWxlTmFtZS5sZW5ndGgoKSAtIDEpID09IHNlcGFyYXRvci5jaGFyQXQoMCkpIHsKKyAgICAgICAgICAgIHRlbXBGaWxlTmFtZSA9IFN1cHBvcnRfUGxhdGZvcm1GaWxlLmdldE5ld1BsYXRmb3JtRmlsZSh0ZW1wRmlsZU5hbWUsICJnYWJiYS56aXAiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRlbXBGaWxlTmFtZSA9IFN1cHBvcnRfUGxhdGZvcm1GaWxlLmdldE5ld1BsYXRmb3JtRmlsZSgKKyAgICAgICAgICAgICAgICAgICAgdGVtcEZpbGVOYW1lICsgc2VwYXJhdG9yLCAiZ2FiYmEuemlwIik7CisgICAgICAgIH0KKworICAgICAgICBGaWxlIGYgPSBuZXcgRmlsZSh0ZW1wRmlsZU5hbWUpOworICAgICAgICBmLmRlbGV0ZSgpOworICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IFN1cHBvcnRfUmVzb3VyY2VzLmdldFN0cmVhbSgiaHl0c19aaXBGaWxlLnppcCIpOworICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIGZvcyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGYpOworICAgICAgICBieXRlW10gcmJ1ZiA9IGdldEFsbEJ5dGVzRnJvbVN0cmVhbShpcyk7CisgICAgICAgIGZvcy53cml0ZShyYnVmLCAwLCByYnVmLmxlbmd0aCk7CisgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIGZvcy5jbG9zZSgpOworICAgICAgICB6ZmlsZSA9IG5ldyBaaXBGaWxlKGYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gTm90ZSB6ZmlsZSBpcyBhIHVzZXItZGVmaW5lZCB6aXAgZmlsZSB1c2VkIGJ5IG90aGVyIHRlc3RzIGFuZAorICAgICAgICAvLyBzaG91bGQgbm90IGJlIGRlbGV0ZWQKKyAgICAgICAgemZpbGUuY2xvc2UoKTsKKyAgICAgICAgdGVtcEZpbGVOYW1lID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmlvLnRtcGRpciIpOworICAgICAgICBTdHJpbmcgc2VwYXJhdG9yID0gU3lzdGVtLmdldFByb3BlcnR5KCJmaWxlLnNlcGFyYXRvciIpOworICAgICAgICBpZiAodGVtcEZpbGVOYW1lLmNoYXJBdCh0ZW1wRmlsZU5hbWUubGVuZ3RoKCkgLSAxKSA9PSBzZXBhcmF0b3IKKyAgICAgICAgICAgICAgICAuY2hhckF0KDApKSB7CisgICAgICAgICAgICB0ZW1wRmlsZU5hbWUgPSBTdXBwb3J0X1BsYXRmb3JtRmlsZS5nZXROZXdQbGF0Zm9ybUZpbGUoCisgICAgICAgICAgICAgICAgICAgIHRlbXBGaWxlTmFtZSwgImdhYmJhLnppcCIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGVtcEZpbGVOYW1lID0gU3VwcG9ydF9QbGF0Zm9ybUZpbGUuZ2V0TmV3UGxhdGZvcm1GaWxlKAorICAgICAgICAgICAgICAgICAgICB0ZW1wRmlsZU5hbWUgKyBzZXBhcmF0b3IsICJnYWJiYS56aXAiKTsKKyAgICAgICAgfQorCisgICAgICAgIEZpbGUgZiA9IG5ldyBGaWxlKHRlbXBGaWxlTmFtZSk7CisgICAgICAgIGYuZGVsZXRlKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ppcC9PbGRaaXBJbnB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvT2xkWmlwSW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjI4ODE3YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvT2xkWmlwSW5wdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSwxNzYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLnppcDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFbnRyeTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcElucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwT3V0cHV0U3RyZWFtOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LnJlc291cmNlLlN1cHBvcnRfUmVzb3VyY2VzOworCitwdWJsaWMgY2xhc3MgT2xkWmlwSW5wdXRTdHJlYW1UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHByaXZhdGUgWmlwSW5wdXRTdHJlYW0gemlzOworICAgIHByaXZhdGUgYnl0ZVtdIGRhdGFCeXRlcyA9ICJTb21lIGRhdGEgaW4gbXkgZmlsZSIuZ2V0Qnl0ZXMoKTsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBTdXBwb3J0X1Jlc291cmNlcy5nZXRTdHJlYW0oImh5dHNfWmlwRmlsZS56aXAiKTsKKyAgICAgICAgaWYgKGlzID09IG51bGwpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZmlsZSBoeXRzX1ppcEZpbGUuemlwIGNhbiBub3QgYmUgZm91bmQiKTsKKyAgICAgICAgfQorICAgICAgICB6aXMgPSBuZXcgWmlwSW5wdXRTdHJlYW0oaXMpOworCisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIFppcE91dHB1dFN0cmVhbSB6b3MgPSBuZXcgWmlwT3V0cHV0U3RyZWFtKGJvcyk7CisgICAgICAgIFppcEVudHJ5IGVudHJ5ID0gbmV3IFppcEVudHJ5KCJteUZpbGUiKTsKKyAgICAgICAgem9zLnB1dE5leHRFbnRyeShlbnRyeSk7CisgICAgICAgIHpvcy53cml0ZShkYXRhQnl0ZXMpOworICAgICAgICB6b3MuY2xvc2VFbnRyeSgpOworICAgICAgICB6b3MuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh6aXMgIT0gbnVsbCkgeworICAgICAgICAgICAgemlzLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NraXBKKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgcmVzb3VyY2VzID0gU3VwcG9ydF9SZXNvdXJjZXMuY3JlYXRlVGVtcEZvbGRlcigpOworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsICJCcm9rZW5fbWFuaWZlc3QuamFyIik7CisgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBmaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKG5ldyBGaWxlKHJlc291cmNlcywKKyAgICAgICAgICAgICAgICAiQnJva2VuX21hbmlmZXN0LmphciIpKTsKKworICAgICAgICBaaXBJbnB1dFN0cmVhbSB6aXMxID0gbmV3IFppcElucHV0U3RyZWFtKGZpcyk7CisKKyAgICAgICAgemlzMS5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgemlzMS5nZXROZXh0RW50cnkoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgemlzMS5za2lwKDEwKTsKKyAgICAgICAgICAgIGZhaWwoIlppcEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChaaXBFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgemlzMS5jbG9zZSgpOyAgLy8gQW5kcm9pZCB0aHJvd3MgZXhjZXB0aW9uIGhlcmUsIGFscmVhZHkhCisgICAgICAgICAgICB6aXMxLnNraXAoMTApOyAgLy8gQnV0IFJJIGhlcmUsIG9ubHkhCisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCRCSUkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIHJidWY7CisKKyAgICAgICAgRmlsZSByZXNvdXJjZXMgPSBTdXBwb3J0X1Jlc291cmNlcy5jcmVhdGVUZW1wRm9sZGVyKCk7CisgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgIkJyb2tlbl9tYW5pZmVzdC5qYXIiKTsKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0obmV3IEZpbGUocmVzb3VyY2VzLAorICAgICAgICAgICAgICAgICJCcm9rZW5fbWFuaWZlc3QuamFyIikpOworCisgICAgICAgIFppcElucHV0U3RyZWFtIHppczEgPSBuZXcgWmlwSW5wdXRTdHJlYW0oZmlzKTsKKworICAgICAgICB6aXMxLmdldE5leHRFbnRyeSgpOworICAgICAgICB6aXMxLmdldE5leHRFbnRyeSgpOworCisgICAgICAgIHJidWYgPSBuZXcgYnl0ZVsxMDBdOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB6aXMxLnJlYWQocmJ1ZiwgMTAsIDkwKTsKKyAgICAgICAgICAgIGZhaWwoIlppcEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChaaXBFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgemlzMS5jbG9zZSgpOyAgLy8gQW5kcm9pZCB0aHJvd3MgZXhjZXB0aW9uIGhlcmUsIGFscmVhZHkhCisgICAgICAgICAgICB6aXMxLnJlYWQocmJ1ZiwgMTAsIDkwKTsgIC8vIEJ1dCBSSSBoZXJlLCBvbmx5IQorICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb3NlRW50cnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgemlzLmdldE5leHRFbnRyeSgpOworICAgICAgICB6aXMuY2xvc2VFbnRyeSgpOworICAgICAgICB6aXMuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgIHppcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgemlzLmNsb3NlRW50cnkoKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIEZpbGUgcmVzb3VyY2VzID0gU3VwcG9ydF9SZXNvdXJjZXMuY3JlYXRlVGVtcEZvbGRlcigpOworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsICJCcm9rZW5fbWFuaWZlc3QuamFyIik7CisgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBmaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKG5ldyBGaWxlKHJlc291cmNlcywKKyAgICAgICAgICAgICAgICAiQnJva2VuX21hbmlmZXN0LmphciIpKTsKKworICAgICAgICBaaXBJbnB1dFN0cmVhbSB6aXMxID0gbmV3IFppcElucHV0U3RyZWFtKGZpcyk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNjsgaSsrKSB7CisgICAgICAgICAgICAgICAgemlzMS5nZXROZXh0RW50cnkoKTsKKyAgICAgICAgICAgICAgICB6aXMxLmNsb3NlRW50cnkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZhaWwoIlppcEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChaaXBFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBNb2NrX1ppcElucHV0U3RyZWFtIGV4dGVuZHMgWmlwSW5wdXRTdHJlYW0geworICAgICAgICBib29sZWFuIGNyZWF0ZUZsYWcgPSBmYWxzZTsKKworICAgICAgICBwdWJsaWMgTW9ja19aaXBJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBhcmcwKSB7CisgICAgICAgICAgICBzdXBlcihhcmcwKTsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gZ2V0Q3JlYXRlRmxhZygpIHsKKyAgICAgICAgICAgIHJldHVybiBjcmVhdGVGbGFnOworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIFppcEVudHJ5IGNyZWF0ZVppcEVudHJ5KFN0cmluZyBuYW1lKSB7CisgICAgICAgICAgICBjcmVhdGVGbGFnID0gdHJ1ZTsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jcmVhdGVaaXBFbnRyeShuYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY3JlYXRlWmlwRW50cnlMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIEZpbGUgcmVzb3VyY2VzID0gU3VwcG9ydF9SZXNvdXJjZXMuY3JlYXRlVGVtcEZvbGRlcigpOworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsICJCcm9rZW5fbWFuaWZlc3QuamFyIik7CisgICAgICAgIEZpbGUgZmwgPSBuZXcgRmlsZShyZXNvdXJjZXMsICJCcm9rZW5fbWFuaWZlc3QuamFyIik7CisgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBmaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZsKTsKKworICAgICAgICBNb2NrX1ppcElucHV0U3RyZWFtIHppczEgPSBuZXcgTW9ja19aaXBJbnB1dFN0cmVhbShmaXMpOworICAgICAgICBhc3NlcnRGYWxzZSh6aXMxLmdldENyZWF0ZUZsYWcoKSk7CisgICAgICAgIHppczEuZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgIGFzc2VydFRydWUoemlzMS5nZXRDcmVhdGVGbGFnKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvWmlwRW50cnlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvemlwL1ppcEVudHJ5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxOGViYjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3V0aWwvemlwL1ppcEVudHJ5VGVzdC5qYXZhCkBAIC0wLDAgKzEsNzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLnppcDsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuamFyLkphckVudHJ5OworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRW50cnk7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBGaWxlOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBPdXRwdXRTdHJlYW07CisKK3B1YmxpYyBjbGFzcyBaaXBFbnRyeVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD00NjkwCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF91dGY4RmlsZU5hbWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIENyZWF0ZSBhIHppcCBmaWxlIGNvbnRhaW5pbmcgbm9uLUFTQ0lJIGZpbGVuYW1lcy4KKyAgICAgICAgRmlsZSBmID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgieW91ciIsICJtdW0iKTsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGZpbGVuYW1lcyA9IEFycmF5cy5hc0xpc3QoInVzLWFzY2lpIiwKKyAgICAgICAgICAgICAgICAiXHUwNDNjXHUwNDMwXHUwNDQwXHUwNDQyXHUwNDMwIiwgLy8gcnVzc2lhbgorICAgICAgICAgICAgICAgICJcdTFmMDBcdTAzYzBcdTFmNzgiLCAvLyBncmVlaworICAgICAgICAgICAgICAgICJcdTMwYjNcdTMwZjNcdTMwY2JcdTMwYzFcdTMwY2YiKTsgLy8gamFwYW5lc2UKKyAgICAgICAgWmlwT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBaaXBPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oZikpOworICAgICAgICBmb3IgKFN0cmluZyBmaWxlbmFtZSA6IGZpbGVuYW1lcykgeworICAgICAgICAgICAgb3V0LnB1dE5leHRFbnRyeShuZXcgWmlwRW50cnkoZmlsZW5hbWUpKTsKKyAgICAgICAgICAgIG91dC5jbG9zZUVudHJ5KCk7IC8vIEVtcHR5IGZpbGVzIGFyZSBmaW5lLgorICAgICAgICB9CisgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAvLyBSZWFkIGl0IGJhY2ssIGFuZCBjaGVjayB3ZSBmaW5kIGFsbCB0aG9zZSBuYW1lcy4KKyAgICAgICAgLy8gVGhpcyBmYWlsZWQgd2hlbiB3ZSB3ZXJlIG1hbmdsaW5nIHRoZSBlbmNvZGluZy4KKyAgICAgICAgWmlwRmlsZSB6aXBGaWxlID0gbmV3IFppcEZpbGUoZik7CisgICAgICAgIGZvciAoU3RyaW5nIGZpbGVuYW1lIDogZmlsZW5hbWVzKSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGZpbGVuYW1lLCB6aXBGaWxlLmdldEVudHJ5KGZpbGVuYW1lKSk7CisgICAgICAgIH0KKyAgICAgICAgLy8gQ2hlY2sgdGhhdCBaaXBJbnB1dFN0cmVhbSB3b3JrcyB0b28uCisgICAgICAgIFppcElucHV0U3RyZWFtIGluID0gbmV3IFppcElucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZikpOworICAgICAgICBaaXBFbnRyeSBlbnRyeTsKKyAgICAgICAgaW50IGVudHJ5Q291bnQgPSAwOworICAgICAgICB3aGlsZSAoKGVudHJ5ID0gaW4uZ2V0TmV4dEVudHJ5KCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZW50cnkuZ2V0TmFtZSgpLCBmaWxlbmFtZXMuY29udGFpbnMoZW50cnkuZ2V0TmFtZSgpKSk7CisgICAgICAgICAgICArK2VudHJ5Q291bnQ7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZpbGVuYW1lcy5zaXplKCksIGVudHJ5Q291bnQpOworICAgICAgICBpbi5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGh0dHA6Ly9iLzIwOTk2MTUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvbmUoKSB7CisgICAgICAgIGJ5dGVbXSBleHRyYSA9IHsgNSwgNywgOSB9OworICAgICAgICBKYXJFbnRyeSBqYXJFbnRyeSA9IG5ldyBKYXJFbnRyeSgiZm9vIik7CisgICAgICAgIGphckVudHJ5LnNldEV4dHJhKGV4dHJhKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiRXhwZWN0ZWQgbm8gZGVmZW5zaXZlIGNvcHkgb2YgZXh0cmEiLCBleHRyYSwgamFyRW50cnkuZ2V0RXh0cmEoKSk7CisKKyAgICAgICAgWmlwRW50cnkgY2xvbmUgPSAoWmlwRW50cnkpIGphckVudHJ5LmNsb25lKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhKYXJFbnRyeS5jbGFzcywgY2xvbmUuZ2V0Q2xhc3MoKSk7CisgICAgICAgIGFzc2VydE5vdFNhbWUoZXh0cmEsIGNsb25lLmdldEV4dHJhKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvWmlwRmlsZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvWmlwRmlsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OWI0MzBmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ppcC9aaXBGaWxlVGVzdC5qYXZhCkBAIC0wLDAgKzEsODUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLnppcDsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRW50cnk7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBGaWxlOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBPdXRwdXRTdHJlYW07CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgWmlwRmlsZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBFeGVyY2lzZSBJbmZsYXRlcidzIGFiaWxpdHkgdG8gcmVmaWxsIHRoZSB6bGliJ3MgaW5wdXQgYnVmZmVyLiBBcyBvZiB0aGlzCisgICAgICogd3JpdGluZywgdGhpcyBidWZmZXIncyBtYXggc2l6ZSBpcyA2NEtpQiBjb21wcmVzc2VkIGJ5dGVzLiBXZSdsbCB3cml0ZSBhCisgICAgICogZnVsbCBtZWdhYnl0ZSBvZiB1bmNvbXByZXNzZWQgZGF0YSwgd2hpY2ggc2hvdWxkIGJlIHN1ZmZpY2llbnQgdG8gZXhoYXVzdAorICAgICAqIHRoZSBidWZmZXIuIGh0dHA6Ly9iL2lzc3VlP2lkPTI3MzQ3NTEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5mbGF0aW5nRmlsZXNSZXF1aXJpbmdaaXBSZWZpbGwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgb3JpZ2luYWxTaXplID0gMTAyNCAqIDEwMjQ7CisgICAgICAgIGJ5dGVbXSByZWFkQnVmZmVyID0gbmV3IGJ5dGVbODE5Ml07CisgICAgICAgIFppcEZpbGUgemlwRmlsZSA9IG5ldyBaaXBGaWxlKGNyZWF0ZVppcEZpbGUob3JpZ2luYWxTaXplKSk7CisgICAgICAgIGZvciAoRW51bWVyYXRpb248PyBleHRlbmRzIFppcEVudHJ5PiBlID0gemlwRmlsZS5lbnRyaWVzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7ICkgeworICAgICAgICAgICAgWmlwRW50cnkgemlwRW50cnkgPSBlLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJUaGlzIHRlc3QgbmVlZHMgPjY0IEtpQiBvZiBjb21wcmVzc2VkIGRhdGEgdG8gZXhlcmNpc2UgSW5mbGF0ZXIiLAorICAgICAgICAgICAgICAgICAgICB6aXBFbnRyeS5nZXRDb21wcmVzc2VkU2l6ZSgpID4gKDY0ICogMTAyNCkpOworICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSB6aXBGaWxlLmdldElucHV0U3RyZWFtKHppcEVudHJ5KTsKKyAgICAgICAgICAgIHdoaWxlIChpcy5yZWFkKHJlYWRCdWZmZXIsIDAsIHJlYWRCdWZmZXIubGVuZ3RoKSAhPSAtMSkge30KKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5mbGF0aW5nU3RyZWFtc1JlcXVpcmluZ1ppcFJlZmlsbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBvcmlnaW5hbFNpemUgPSAxMDI0ICogMTAyNDsKKyAgICAgICAgYnl0ZVtdIHJlYWRCdWZmZXIgPSBuZXcgYnl0ZVs4MTkyXTsKKyAgICAgICAgWmlwSW5wdXRTdHJlYW0gaW4gPSBuZXcgWmlwSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShjcmVhdGVaaXBGaWxlKG9yaWdpbmFsU2l6ZSkpKTsKKyAgICAgICAgd2hpbGUgKGluLmdldE5leHRFbnRyeSgpICE9IG51bGwpIHsKKyAgICAgICAgICAgIHdoaWxlIChpbi5yZWFkKHJlYWRCdWZmZXIsIDAsIHJlYWRCdWZmZXIubGVuZ3RoKSAhPSAtMSkge30KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXByZXNzZXMgYSBzaW5nbGUgcmFuZG9tIGZpbGUgaW50byBhIC56aXAgYXJjaGl2ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIEZpbGUgY3JlYXRlWmlwRmlsZShpbnQgdW5jb21wcmVzc2VkU2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZSByZXN1bHQgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJPbGRaaXBGaWxlVGVzdCIsICJ6aXAiKTsKKyAgICAgICAgcmVzdWx0LmRlbGV0ZU9uRXhpdCgpOworCisgICAgICAgIFppcE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgWmlwT3V0cHV0U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKHJlc3VsdCkpOworICAgICAgICBaaXBFbnRyeSBlbnRyeSA9IG5ldyBaaXBFbnRyeSgicmFuZG9tIik7CisgICAgICAgIG91dC5wdXROZXh0RW50cnkoZW50cnkpOworCisgICAgICAgIGJ5dGVbXSB3cml0ZUJ1ZmZlciA9IG5ldyBieXRlWzgxOTJdOworICAgICAgICBSYW5kb20gcmFuZG9tID0gbmV3IFJhbmRvbSgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHVuY29tcHJlc3NlZFNpemU7IGkgKz0gd3JpdGVCdWZmZXIubGVuZ3RoKSB7CisgICAgICAgICAgICByYW5kb20ubmV4dEJ5dGVzKHdyaXRlQnVmZmVyKTsKKyAgICAgICAgICAgIG91dC53cml0ZSh3cml0ZUJ1ZmZlciwgMCwgTWF0aC5taW4od3JpdGVCdWZmZXIubGVuZ3RoLCB1bmNvbXByZXNzZWRTaXplIC0gaSkpOworICAgICAgICB9CisKKyAgICAgICAgb3V0LmNsb3NlRW50cnkoKTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ppcC9aaXBJbnB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvWmlwSW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2I5ODMyMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvWmlwSW5wdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSw2MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZhLnV0aWwuemlwOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRW50cnk7CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBaaXBJbnB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdFNob3J0TWVzc2FnZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0gIkhlbGxvIFdvcmxkIi5nZXRCeXRlcygiVVRGLTgiKTsKKyAgICAgICAgYnl0ZVtdIHppcHBlZCA9IFppcE91dHB1dFN0cmVhbVRlc3QuemlwKCJzaG9ydCIsIGRhdGEpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLnRvU3RyaW5nKGRhdGEpLCBBcnJheXMudG9TdHJpbmcodW56aXAoInNob3J0IiwgemlwcGVkKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RMb25nTWVzc2FnZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbMTAyNCAqIDEwMjRdOworICAgICAgICBuZXcgUmFuZG9tKCkubmV4dEJ5dGVzKGRhdGEpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoZGF0YSwgdW56aXAoInIiLCBaaXBPdXRwdXRTdHJlYW1UZXN0LnppcCgiciIsIGRhdGEpKSkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIHVuemlwKFN0cmluZyBuYW1lLCBieXRlW10gYnl0ZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFppcElucHV0U3RyZWFtIGluID0gbmV3IFppcElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcykpOworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCisgICAgICAgIFppcEVudHJ5IGVudHJ5ID0gaW4uZ2V0TmV4dEVudHJ5KCk7CisgICAgICAgIGFzc2VydEVxdWFscyhuYW1lLCBlbnRyeS5nZXROYW1lKCkpOworCisgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVsxMDI0XTsKKyAgICAgICAgaW50IGNvdW50OworICAgICAgICB3aGlsZSAoKGNvdW50ID0gaW4ucmVhZChidWZmZXIpKSAhPSAtMSkgeworICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZmZlciwgMCwgY291bnQpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0TnVsbChpbi5nZXROZXh0RW50cnkoKSk7IC8vIFRoZXJlJ3Mgb25seSBvbmUgZW50cnkgaW4gdGhlIFppcCBmaWxlcyB3ZSBjcmVhdGUuCisKKyAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgcmV0dXJuIG91dC50b0J5dGVBcnJheSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvWmlwT3V0cHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS91dGlsL3ppcC9aaXBPdXRwdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTdjNTE4ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvdXRpbC96aXAvWmlwT3V0cHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS51dGlsLnppcDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEVudHJ5OworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBPdXRwdXRTdHJlYW07CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgWmlwT3V0cHV0U3RyZWFtVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2hvcnRNZXNzYWdlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGRhdGEgPSAiSGVsbG8gV29ybGQiLmdldEJ5dGVzKCJVVEYtOCIpOworICAgICAgICBieXRlW10gemlwcGVkID0gemlwKCJzaG9ydCIsIGRhdGEpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLnRvU3RyaW5nKGRhdGEpLCBBcnJheXMudG9TdHJpbmcoWmlwSW5wdXRTdHJlYW1UZXN0LnVuemlwKCJzaG9ydCIsIHppcHBlZCkpKTsKKyAgICB9CisKKyAgICAvLyBodHRwOi8vYi8zMTgxNDMwIC0tLSBhIHNpZ24tZXh0ZW5zaW9uIGJ1ZyBvbiBDUkNzIHdpdGggdGhlIHRvcCBiaXQgc2V0LgorICAgIHB1YmxpYyB2b2lkIHRlc3QzMTgxNDMwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVsxXTsgLy8gQ1JDMzIoeyAwIH0pID09IDB4ZDIwMmVmOGQKKyAgICAgICAgYnl0ZVtdIHppcHBlZCA9IHppcCgieiIsIGRhdGEpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLnRvU3RyaW5nKGRhdGEpLCBBcnJheXMudG9TdHJpbmcoWmlwSW5wdXRTdHJlYW1UZXN0LnVuemlwKCJ6IiwgemlwcGVkKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RMb25nTWVzc2FnZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbMTAyNCAqIDEwMjRdOworICAgICAgICBuZXcgUmFuZG9tKCkubmV4dEJ5dGVzKGRhdGEpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoZGF0YSwgWmlwSW5wdXRTdHJlYW1UZXN0LnVuemlwKCJyIiwgemlwKCJyIiwgZGF0YSkpKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gemlwKFN0cmluZyBuYW1lLCBieXRlW10gYnl0ZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBieXRlc091dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgWmlwT3V0cHV0U3RyZWFtIHppcHBlZE91dCA9IG5ldyBaaXBPdXRwdXRTdHJlYW0oYnl0ZXNPdXQpOworCisgICAgICAgIFppcEVudHJ5IGVudHJ5ID0gbmV3IFppcEVudHJ5KG5hbWUpOworICAgICAgICB6aXBwZWRPdXQucHV0TmV4dEVudHJ5KGVudHJ5KTsKKyAgICAgICAgemlwcGVkT3V0LndyaXRlKGJ5dGVzKTsKKyAgICAgICAgemlwcGVkT3V0LmNsb3NlRW50cnkoKTsKKworICAgICAgICB6aXBwZWRPdXQuY2xvc2UoKTsKKyAgICAgICAgcmV0dXJuIGJ5dGVzT3V0LnRvQnl0ZUFycmF5KCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL0NpcGhlcklucHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL0NpcGhlcklucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQwZmQ4ZmQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vQ2lwaGVySW5wdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSw3NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmF4LmNyeXB0bzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YXguY3J5cHRvLkNpcGhlcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uQ2lwaGVySW5wdXRTdHJlYW07CitpbXBvcnQgamF2YXguY3J5cHRvLlNlY3JldEtleTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5TZWNyZXRLZXlTcGVjOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGZpbmFsIGNsYXNzIENpcGhlcklucHV0U3RyZWFtVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGtleUJ5dGVzID0geyAxMjcsIC0yLCAtOTUsIC0zOSwgMzUsIDExOCwgMTIxLCAtOTIgfTsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBwbGFpblRleHQgPSAiYWJjZGUiOworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGNpcGhlclRleHQgPSB7IDEyMSwgLTEyNCwgLTEwNiwgNDMsIC01NSwgLTY3LCAtMTA1LCAtNzUgfTsKKyAgICBwcml2YXRlIFNlY3JldEtleSBrZXk7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAga2V5ID0gbmV3IFNlY3JldEtleVNwZWMoa2V5Qnl0ZXMsICJERVMiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5jcnlwdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaXBoZXIgY2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMiKTsKKyAgICAgICAgY2lwaGVyLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwga2V5KTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBuZXcgQ2lwaGVySW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHBsYWluVGV4dC5nZXRCeXRlcygiVVRGLTgiKSksIGNpcGhlcik7CisgICAgICAgIGJ5dGVbXSBieXRlcyA9IHJlYWRBbGwoaW4pOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLnRvU3RyaW5nKGNpcGhlclRleHQpLCBBcnJheXMudG9TdHJpbmcoYnl0ZXMpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVjcnlwdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaXBoZXIgY2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMiKTsKKyAgICAgICAgY2lwaGVyLmluaXQoQ2lwaGVyLkRFQ1JZUFRfTU9ERSwga2V5KTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBuZXcgQ2lwaGVySW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNpcGhlclRleHQpLCBjaXBoZXIpOworICAgICAgICBieXRlW10gYnl0ZXMgPSByZWFkQWxsKGluKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHBsYWluVGV4dCwgbmV3IFN0cmluZyhieXRlcywgIlVURi04IikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTa2lwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENpcGhlciBjaXBoZXIgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUyIpOworICAgICAgICBjaXBoZXIuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLCBrZXkpOworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG5ldyBDaXBoZXJJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oY2lwaGVyVGV4dCksIGNpcGhlcik7CisgICAgICAgIGFzc2VydFRydWUoaW4uc2tpcCg1KSA+IDApOworICAgIH0KKworICAgIHByaXZhdGUgYnl0ZVtdIHJlYWRBbGwoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGludCBjb3VudDsKKyAgICAgICAgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlWzEwMjRdOworICAgICAgICB3aGlsZSAoKGNvdW50ID0gaW4ucmVhZChidWZmZXIpKSAhPSAtMSkgeworICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZmZlciwgMCwgY291bnQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBvdXQudG9CeXRlQXJyYXkoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vQ2lwaGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL0NpcGhlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OTE5YjM1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL0NpcGhlclRlc3QuamF2YQpAQCAtMCwwICsxLDExMSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmF4LmNyeXB0bzsKKworaW1wb3J0IGNvbS5hbmRyb2lkLm9yZy5ib3VuY3ljYXN0bGUuYXNuMS54NTA5LktleVVzYWdlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YXguY3J5cHRvLkNpcGhlcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgbGliY29yZS5qYXZhLnNlY3VyaXR5LlRlc3RLZXlTdG9yZTsKKworcHVibGljIGZpbmFsIGNsYXNzIENpcGhlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2lwaGVySW5pdFdpdGhDZXJ0aWZpY2F0ZSAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gbm8ga2V5IHVzYWdlIHNwZWNpZmllZCwgZXZlcnl0aGluZyBpcyBmaW5lCisgICAgICAgIGFzc2VydENpcGhlckluaXRXaXRoS2V5VXNhZ2UoMCwgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgIHRydWUsIHRydWUsICB0cnVlKTsKKworICAgICAgICAvLyBjb21tb24gY2FzZSBpcyB0aGF0IGVuY3J5cHQvd3JhcCBpcyBwcm9oaWJpdGVkIHdoZW4gc3BlY2lhbCB1c2FnZSBpcyBzcGVjaWZpZWQKKyAgICAgICAgYXNzZXJ0Q2lwaGVySW5pdFdpdGhLZXlVc2FnZShLZXlVc2FnZS5kaWdpdGFsU2lnbmF0dXJlLCBmYWxzZSwgdHJ1ZSwgZmFsc2UsIHRydWUpOworICAgICAgICBhc3NlcnRDaXBoZXJJbml0V2l0aEtleVVzYWdlKEtleVVzYWdlLm5vblJlcHVkaWF0aW9uLCAgIGZhbHNlLCB0cnVlLCBmYWxzZSwgdHJ1ZSk7CisgICAgICAgIGFzc2VydENpcGhlckluaXRXaXRoS2V5VXNhZ2UoS2V5VXNhZ2Uua2V5QWdyZWVtZW50LCAgICAgZmFsc2UsIHRydWUsIGZhbHNlLCB0cnVlKTsKKyAgICAgICAgYXNzZXJ0Q2lwaGVySW5pdFdpdGhLZXlVc2FnZShLZXlVc2FnZS5rZXlDZXJ0U2lnbiwgICAgICBmYWxzZSwgdHJ1ZSwgZmFsc2UsIHRydWUpOworICAgICAgICBhc3NlcnRDaXBoZXJJbml0V2l0aEtleVVzYWdlKEtleVVzYWdlLmNSTFNpZ24sICAgICAgICAgIGZhbHNlLCB0cnVlLCBmYWxzZSwgdHJ1ZSk7CisKKyAgICAgICAgLy8gTm90ZSB0aGV5IGVuY2lwaGVyT25seS9kZWNpcGhlck9ubHkgZG9uJ3QgaGF2ZSB0byBkbyB3aXRoCisgICAgICAgIC8vIEVOQ1JZUFRfTU9ERSBvciBERUNSWVBUX01PREUsIGJ1dCByZXN0cmljdCB1c2FnZSByZWxhdGl2ZQorICAgICAgICAvLyB0byBrZXlBZ3JlZW1lbnQuIFRoZXJlIGlzIG5vdCBhICpfTU9ERSBvcHRpb24gdGhhdAorICAgICAgICAvLyBjb3JyZXNwb25kcyB0byB0aGlzIGluIENpcGhlciwgdGhlIFJJIGRvZXMgbm90IGVuZm9yY2UKKyAgICAgICAgLy8gYW55dGhpbmcgaW4gQ2lwaGVyLgorICAgICAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTEyOTU1CisgICAgICAgIGFzc2VydENpcGhlckluaXRXaXRoS2V5VXNhZ2UoS2V5VXNhZ2UuZW5jaXBoZXJPbmx5LCAgICAgZmFsc2UsIHRydWUsIGZhbHNlLCB0cnVlKTsKKyAgICAgICAgYXNzZXJ0Q2lwaGVySW5pdFdpdGhLZXlVc2FnZShLZXlVc2FnZS5kZWNpcGhlck9ubHksICAgICBmYWxzZSwgdHJ1ZSwgZmFsc2UsIHRydWUpOworICAgICAgICBhc3NlcnRDaXBoZXJJbml0V2l0aEtleVVzYWdlKEtleVVzYWdlLmtleUFncmVlbWVudCB8IEtleVVzYWdlLmVuY2lwaGVyT25seSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwgdHJ1ZSwgZmFsc2UsIHRydWUpOworICAgICAgICBhc3NlcnRDaXBoZXJJbml0V2l0aEtleVVzYWdlKEtleVVzYWdlLmtleUFncmVlbWVudCB8IEtleVVzYWdlLmRlY2lwaGVyT25seSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwgdHJ1ZSwgZmFsc2UsIHRydWUpOworCisgICAgICAgIC8vIGV4Y2VwdCB3aGVuIHdyYXBwaW5nIGEga2V5IGlzIHNwZWNpZmljYWxseSBhbGxvd2VkIG9yCisgICAgICAgIGFzc2VydENpcGhlckluaXRXaXRoS2V5VXNhZ2UoS2V5VXNhZ2Uua2V5RW5jaXBoZXJtZW50LCAgZmFsc2UsIHRydWUsIHRydWUsICB0cnVlKTsKKyAgICAgICAgLy8gZXhjZXB0IHdoZW4gd3JhcHBpbmcgZGF0YSBlbmNyeXB0aW9uIGlzIHNwZWNpZmljYWxseSBhbGxvd2VkCisgICAgICAgIGFzc2VydENpcGhlckluaXRXaXRoS2V5VXNhZ2UoS2V5VXNhZ2UuZGF0YUVuY2lwaGVybWVudCwgdHJ1ZSwgIHRydWUsIGZhbHNlLCB0cnVlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0Q2lwaGVySW5pdFdpdGhLZXlVc2FnZSAoaW50IGtleVVzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGFsbG93RW5jcnlwdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBhbGxvd0RlY3J5cHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gYWxsb3dXcmFwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGFsbG93VW53cmFwKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2VydGlmaWNhdGUgY2VydGlmaWNhdGUgPSBjZXJ0aWZpY2F0ZVdpdGhLZXlVc2FnZShrZXlVc2FnZSk7CisgICAgICAgIGFzc2VydENpcGhlckluaXRXaXRoS2V5VXNhZ2UoY2VydGlmaWNhdGUsIGFsbG93RW5jcnlwdCwgQ2lwaGVyLkVOQ1JZUFRfTU9ERSk7CisgICAgICAgIGFzc2VydENpcGhlckluaXRXaXRoS2V5VXNhZ2UoY2VydGlmaWNhdGUsIGFsbG93RGVjcnlwdCwgQ2lwaGVyLkRFQ1JZUFRfTU9ERSk7CisgICAgICAgIGFzc2VydENpcGhlckluaXRXaXRoS2V5VXNhZ2UoY2VydGlmaWNhdGUsIGFsbG93V3JhcCwgICAgQ2lwaGVyLldSQVBfTU9ERSk7CisgICAgICAgIGFzc2VydENpcGhlckluaXRXaXRoS2V5VXNhZ2UoY2VydGlmaWNhdGUsIGFsbG93VW53cmFwLCAgQ2lwaGVyLlVOV1JBUF9NT0RFKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0Q2lwaGVySW5pdFdpdGhLZXlVc2FnZShDZXJ0aWZpY2F0ZSBjZXJ0aWZpY2F0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGFsbG93TW9kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbW9kZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENpcGhlciBjaXBoZXIgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIlJTQSIpOworICAgICAgICBpZiAoYWxsb3dNb2RlKSB7CisgICAgICAgICAgICBjaXBoZXIuaW5pdChtb2RlLCBjZXJ0aWZpY2F0ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNpcGhlci5pbml0KG1vZGUsIGNlcnRpZmljYXRlKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcgbW9kZVN0cmluZzsKKyAgICAgICAgICAgICAgICBzd2l0Y2ggKG1vZGUpIHsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBDaXBoZXIuRU5DUllQVF9NT0RFOgorICAgICAgICAgICAgICAgICAgICAgICAgbW9kZVN0cmluZyA9ICJFTkNSWVBUX01PREUiOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgQ2lwaGVyLkRFQ1JZUFRfTU9ERToKKyAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVTdHJpbmcgPSAiREVDUllQVF9NT0RFIjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBjYXNlIENpcGhlci5XUkFQX01PREU6CisgICAgICAgICAgICAgICAgICAgICAgICBtb2RlU3RyaW5nID0gIldSQVBfTU9ERSI7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBDaXBoZXIuVU5XUkFQX01PREU6CisgICAgICAgICAgICAgICAgICAgICAgICBtb2RlU3RyaW5nID0gIlVOV1JBUF9NT0RFIjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJVbmtub3duIENpcGhlci4qX01PREUgIiArIG1vZGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmYWlsKCJTaG91bGQgaGF2ZSBoYWQgSW52YWxpZEtleUV4Y2VwdGlvbiBmb3IgIiArIG1vZGVTdHJpbmcKKyAgICAgICAgICAgICAgICAgICAgICsgIiBmb3IgIiArIGNlcnRpZmljYXRlKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgQ2VydGlmaWNhdGUgY2VydGlmaWNhdGVXaXRoS2V5VXNhZ2UoaW50IGtleVVzYWdlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gbm90ZSB0aGUgcmFyZSB1c2FnZSBvZiBub24temVybyBrZXlVc2FnZQorICAgICAgICByZXR1cm4gbmV3IFRlc3RLZXlTdG9yZS5CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuYWxpYXNQcmVmaXgoInJzYS1kc2EtZWMiKQorICAgICAgICAgICAgICAgIC5rZXlVc2FnZShrZXlVc2FnZSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKQorICAgICAgICAgICAgICAgIC5nZXRQcml2YXRlS2V5KCJSU0EiLCAiUlNBIikuZ2V0Q2VydGlmaWNhdGUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vS2V5R2VuZXJhdG9yVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL0tleUdlbmVyYXRvclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOWVmZDNhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL0tleUdlbmVyYXRvclRlc3QuamF2YQpAQCAtMCwwICsxLDE1NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YXguY3J5cHRvLktleUdlbmVyYXRvcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2VjcmV0S2V5OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIEtleUdlbmVyYXRvclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzVW5zdXBwb3J0ZWQoS2V5R2VuZXJhdG9yIGtnKSB7CisgICAgICAgIC8vIERvbid0IGJvdGhlciB0ZXN0aW5nICJTdW4uLi4iIEtleUdlbmVyYXRvcnMKKyAgICAgICAgcmV0dXJuIChrZy5nZXRBbGdvcml0aG0oKS5zdGFydHNXaXRoKCJTdW4iKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQcm92aWRlcltdIHByb3ZpZGVycyA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygpOworICAgICAgICBmb3IgKFByb3ZpZGVyIHByb3ZpZGVyIDogcHJvdmlkZXJzKSB7CisgICAgICAgICAgICBTZXQ8UHJvdmlkZXIuU2VydmljZT4gc2VydmljZXMgPSBwcm92aWRlci5nZXRTZXJ2aWNlcygpOworICAgICAgICAgICAgZm9yIChQcm92aWRlci5TZXJ2aWNlIHNlcnZpY2UgOiBzZXJ2aWNlcykgeworICAgICAgICAgICAgICAgIFN0cmluZyB0eXBlID0gc2VydmljZS5nZXRUeXBlKCk7CisgICAgICAgICAgICAgICAgaWYgKCF0eXBlLmVxdWFscygiS2V5R2VuZXJhdG9yIikpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIFN0cmluZyBhbGdvcml0aG0gPSBzZXJ2aWNlLmdldEFsZ29yaXRobSgpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIC8vIEtleUdlbmVyYXRvci5nZXRJbnN0YW5jZShTdHJpbmcpCisgICAgICAgICAgICAgICAgICAgIEtleUdlbmVyYXRvciBrZzEgPSBLZXlHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFsZ29yaXRobSwga2cxLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgICAgICAgICAgICAgdGVzdF9LZXlHZW5lcmF0b3Ioa2cxKTsKKworICAgICAgICAgICAgICAgICAgICAvLyBLZXlHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoU3RyaW5nLCBQcm92aWRlcikKKyAgICAgICAgICAgICAgICAgICAgS2V5R2VuZXJhdG9yIGtnMiA9IEtleUdlbmVyYXRvci5nZXRJbnN0YW5jZShhbGdvcml0aG0sIHByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFsZ29yaXRobSwga2cyLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHByb3ZpZGVyLCBrZzIuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgICAgICAgICAgICAgIHRlc3RfS2V5R2VuZXJhdG9yKGtnMik7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKFN0cmluZywgU3RyaW5nKQorICAgICAgICAgICAgICAgICAgICBLZXlHZW5lcmF0b3Iga2czID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKGFsZ29yaXRobSwgcHJvdmlkZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFsZ29yaXRobSwga2czLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHByb3ZpZGVyLCBrZzMuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgICAgICAgICAgICAgIHRlc3RfS2V5R2VuZXJhdG9yKGtnMyk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiUHJvYmxlbSB0ZXN0aW5nIEtleVBhaXJHZW5lcmF0b3IuIiArIGFsZ29yaXRobSwgZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPFN0cmluZywgTGlzdDxJbnRlZ2VyPj4gS0VZX1NJWkVTCisgICAgICAgICAgICA9IG5ldyBIYXNoTWFwPFN0cmluZywgTGlzdDxJbnRlZ2VyPj4oKTsKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHB1dEtleVNpemUoU3RyaW5nIGFsZ29yaXRobSwgaW50IGtleVNpemUpIHsKKyAgICAgICAgYWxnb3JpdGhtID0gYWxnb3JpdGhtLnRvVXBwZXJDYXNlKCk7CisgICAgICAgIExpc3Q8SW50ZWdlcj4ga2V5U2l6ZXMgPSBLRVlfU0laRVMuZ2V0KGFsZ29yaXRobSk7CisgICAgICAgIGlmIChrZXlTaXplcyA9PSBudWxsKSB7CisgICAgICAgICAgICBrZXlTaXplcyA9IG5ldyBBcnJheUxpc3Q8SW50ZWdlcj4oKTsKKyAgICAgICAgICAgIEtFWV9TSVpFUy5wdXQoYWxnb3JpdGhtLCBrZXlTaXplcyk7CisgICAgICAgIH0KKyAgICAgICAga2V5U2l6ZXMuYWRkKGtleVNpemUpOworICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBMaXN0PEludGVnZXI+IGdldEtleVNpemVzKFN0cmluZyBhbGdvcml0aG0pIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhbGdvcml0aG0gPSBhbGdvcml0aG0udG9VcHBlckNhc2UoKTsKKyAgICAgICAgTGlzdDxJbnRlZ2VyPiBrZXlTaXplcyA9IEtFWV9TSVpFUy5nZXQoYWxnb3JpdGhtKTsKKyAgICAgICAgaWYgKGtleVNpemVzID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlVua25vd24ga2V5IHNpemVzIGZvciBLZXlHZW5lcmF0b3IuIiArIGFsZ29yaXRobSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGtleVNpemVzOworICAgIH0KKyAgICBzdGF0aWMgeworICAgICAgICBwdXRLZXlTaXplKCJBRVMiLCAxMjgpOworICAgICAgICBwdXRLZXlTaXplKCJBRVMiLCAxOTIpOworICAgICAgICBwdXRLZXlTaXplKCJBRVMiLCAyNTYpOworICAgICAgICBwdXRLZXlTaXplKCJBUkM0IiwgMTAyNCk7CisgICAgICAgIHB1dEtleVNpemUoIkFSQzQiLCA0MCk7CisgICAgICAgIHB1dEtleVNpemUoIkFSQzQiLCA0MSk7CisgICAgICAgIHB1dEtleVNpemUoIkFSQ0ZPVVIiLCAxMDI0KTsKKyAgICAgICAgcHV0S2V5U2l6ZSgiQVJDRk9VUiIsIDQwKTsKKyAgICAgICAgcHV0S2V5U2l6ZSgiQVJDRk9VUiIsIDQxKTsKKyAgICAgICAgcHV0S2V5U2l6ZSgiQmxvd2Zpc2giLCAzMik7CisgICAgICAgIHB1dEtleVNpemUoIkJsb3dmaXNoIiwgMzIrOCk7CisgICAgICAgIHB1dEtleVNpemUoIkJsb3dmaXNoIiwgNDQ4KTsKKyAgICAgICAgcHV0S2V5U2l6ZSgiREVTIiwgNTYpOworICAgICAgICBwdXRLZXlTaXplKCJERVNlZGUiLCAxMTIpOworICAgICAgICBwdXRLZXlTaXplKCJERVNlZGUiLCAxNjgpOworICAgICAgICBwdXRLZXlTaXplKCJSQzIiLCA0MCk7CisgICAgICAgIHB1dEtleVNpemUoIlJDMiIsIDQxKTsKKyAgICAgICAgcHV0S2V5U2l6ZSgiUkMyIiwgMTAyNCk7CisgICAgICAgIHB1dEtleVNpemUoIlJDNCIsIDQwKTsKKyAgICAgICAgcHV0S2V5U2l6ZSgiUkM0IiwgNDEpOworICAgICAgICBwdXRLZXlTaXplKCJSQzQiLCAxMDI0KTsKKyAgICAgICAgcHV0S2V5U2l6ZSgiSG1hY01ENSIsIDEpOworICAgICAgICBwdXRLZXlTaXplKCJIbWFjTUQ1IiwgMTAyNSk7CisgICAgICAgIHB1dEtleVNpemUoIkhtYWNTSEExIiwgMSk7CisgICAgICAgIHB1dEtleVNpemUoIkhtYWNTSEExIiwgMTAyNSk7CisgICAgICAgIHB1dEtleVNpemUoIkhtYWNTSEEyNTYiLCA0MCk7CisgICAgICAgIHB1dEtleVNpemUoIkhtYWNTSEEyNTYiLCAxMDI1KTsKKyAgICAgICAgcHV0S2V5U2l6ZSgiSG1hY1NIQTM4NCIsIDQwKTsKKyAgICAgICAgcHV0S2V5U2l6ZSgiSG1hY1NIQTM4NCIsIDEwMjUpOworICAgICAgICBwdXRLZXlTaXplKCJIbWFjU0hBNTEyIiwgNDApOworICAgICAgICBwdXRLZXlTaXplKCJIbWFjU0hBNTEyIiwgMTAyNSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RfS2V5R2VuZXJhdG9yKEtleUdlbmVyYXRvciBrZykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpc1Vuc3VwcG9ydGVkKGtnKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAga2cuaW5pdCgoU2VjdXJlUmFuZG9tKSBudWxsKTsKKyAgICAgICAgdGVzdF9TZWNyZXRLZXkoa2csIGtnLmdlbmVyYXRlS2V5KCkpOworCisgICAgICAgIGtnLmluaXQobmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAgdGVzdF9TZWNyZXRLZXkoa2csIGtnLmdlbmVyYXRlS2V5KCkpOworCisgICAgICAgIFN0cmluZyBhbGdvcml0aG0gPSBrZy5nZXRBbGdvcml0aG0oKTsKKyAgICAgICAgTGlzdDxJbnRlZ2VyPiBrZXlTaXplcyA9IGdldEtleVNpemVzKGFsZ29yaXRobSk7CisgICAgICAgIGZvciAoaW50IGtleVNpemUgOiBrZXlTaXplcykgeworICAgICAgICAgICAga2cuaW5pdChrZXlTaXplKTsKKyAgICAgICAgICAgIHRlc3RfU2VjcmV0S2V5KGtnLCBrZy5nZW5lcmF0ZUtleSgpKTsKKworICAgICAgICAgICAga2cuaW5pdChrZXlTaXplLCAoU2VjdXJlUmFuZG9tKSBudWxsKTsKKyAgICAgICAgICAgIHRlc3RfU2VjcmV0S2V5KGtnLCBrZy5nZW5lcmF0ZUtleSgpKTsKKworICAgICAgICAgICAga2cuaW5pdChrZXlTaXplLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAgdGVzdF9TZWNyZXRLZXkoa2csIGtnLmdlbmVyYXRlS2V5KCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RfU2VjcmV0S2V5KEtleUdlbmVyYXRvciBrZywgU2VjcmV0S2V5IHNrKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzayk7CisgICAgICAgIGFzc2VydEVxdWFscyhrZy5nZXRBbGdvcml0aG0oKS50b1VwcGVyQ2FzZSgpLCBzay5nZXRBbGdvcml0aG0oKS50b1VwcGVyQ2FzZSgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzay5nZXRFbmNvZGVkKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHNrLmdldEZvcm1hdCgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vU2VjcmV0S2V5RmFjdG9yeVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L2NyeXB0by9TZWNyZXRLZXlGYWN0b3J5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc1MTlhYWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vU2VjcmV0S2V5RmFjdG9yeVRlc3QuamF2YQpAQCAtMCwwICsxLDE3MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuSW52YWxpZEtleVNwZWNFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLktleVNwZWM7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2VjcmV0S2V5OworaW1wb3J0IGphdmF4LmNyeXB0by5TZWNyZXRLZXlGYWN0b3J5OworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLlBCRUtleVNwZWM7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgU2VjcmV0S2V5RmFjdG9yeVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gUEFTU1dPUkQgPSAiZ29vZ2xlIi50b0NoYXJBcnJheSgpOworICAgIC8qKgorICAgICAqIFNhbHRzIHNob3VsZCBiZSByYW5kb20gdG8gcmVkdWNlIGVmZmVjdGl2ZW5lc3Mgb2YgZGljdGlvbmFyeQorICAgICAqIGF0dGFja3MsIGJ1dCBuZWVkIG5vdCBiZSBrZXB0IHNlY3JldCBmcm9tIGF0dGFja2Vycy4gRm9yIG1vcmUKKyAgICAgKiBpbmZvcm1hdGlvbiwgc2VlIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU2FsdF8oY3J5cHRvZ3JhcGh5KQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBTQUxUID0gezAsIDEsIDIsIDMsIDQsIDUsIDYsIDd9OworICAgIC8qKgorICAgICAqIFRoZSBudW1iZXIgb2YgaXRlcmF0aW9ucyBzaG91bGQgYmUgaGlnaGVyIGZvciBwcm9kdWN0aW9uCisgICAgICogc3RyZW5ndGggcHJvdGVjdGlvbi4gVGhlIHRvbGVyYWJsZSB2YWx1ZSBtYXkgdmFyeSBmcm9tIGRldmljZQorICAgICAqIHRvIGRldmljZSwgYnV0IDgxOTIgc2hvdWxkIGJlIGFjY2VwdGFibGUgZm9yIFBCS0RGMiBvbiBhIE5leHVzIE9uZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSVRFUkFUSU9OUyA9IDEwMjQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEtFWV9MRU5HVEggPSAxMjg7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1BCS0RGMl9yZXF1aXJlZF9wYXJhbWV0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNlY3JldEtleUZhY3RvcnkgZmFjdG9yeSA9IFNlY3JldEtleUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlBCS0RGMldpdGhIbWFjU0hBMSIpOworCisgICAgICAgIC8vIFBCRUtleVNwZWMgdmFsaWRhdGVzIGFyZ3VtZW50cyBtb3N0IHRvIGJlIG5vbi1udWxsLCBub24tZW1wdHksIHBvc3RpdmUsIGV0Yy4KKyAgICAgICAgLy8gRm9jdXMgb24gaW5zdWZmaWNpZW50IFBCRUtleVNwZWNzCisKKyAgICAgICAgLy8gUEJFS2V5U3BlY3MgcGFzc3dvcmQgb25seSBjb25zdHJ1Y3RvcgorICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5U3BlYyBrcyA9IG5ldyBQQkVLZXlTcGVjKG51bGwpOworICAgICAgICAgICAgZmFjdG9yeS5nZW5lcmF0ZVNlY3JldChrcyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVNwZWMga3MgPSBuZXcgUEJFS2V5U3BlYyhuZXcgY2hhclswXSk7CisgICAgICAgICAgICBmYWN0b3J5LmdlbmVyYXRlU2VjcmV0KGtzKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleVNwZWNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5U3BlYyBrcyA9IG5ldyBQQkVLZXlTcGVjKFBBU1NXT1JEKTsKKyAgICAgICAgICAgIGZhY3RvcnkuZ2VuZXJhdGVTZWNyZXQoa3MpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKworICAgICAgICAvLyBQQkVLZXlTcGVjcyBjb25zdHJ1Y3RvciB3aXRob3V0IGtleSBsZW5ndGgKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVNwZWMga3MgPSBuZXcgUEJFS2V5U3BlYyhudWxsLCBTQUxULCBJVEVSQVRJT05TKTsKKyAgICAgICAgICAgIGZhY3RvcnkuZ2VuZXJhdGVTZWNyZXQoa3MpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTcGVjIGtzID0gbmV3IFBCRUtleVNwZWMobmV3IGNoYXJbMF0sIFNBTFQsIElURVJBVElPTlMpOworICAgICAgICAgICAgZmFjdG9yeS5nZW5lcmF0ZVNlY3JldChrcyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVNwZWMga3MgPSBuZXcgUEJFS2V5U3BlYyhQQVNTV09SRCwgU0FMVCwgSVRFUkFUSU9OUyk7CisgICAgICAgICAgICBmYWN0b3J5LmdlbmVyYXRlU2VjcmV0KGtzKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleVNwZWNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTcGVjIGtzID0gbmV3IFBCRUtleVNwZWMobnVsbCwgU0FMVCwgSVRFUkFUSU9OUywgS0VZX0xFTkdUSCk7CisgICAgICAgICAgICBmYWN0b3J5LmdlbmVyYXRlU2VjcmV0KGtzKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5U3BlYyBrcyA9IG5ldyBQQkVLZXlTcGVjKG5ldyBjaGFyWzBdLCBTQUxULCBJVEVSQVRJT05TLCBLRVlfTEVOR1RIKTsKKyAgICAgICAgICAgIGZhY3RvcnkuZ2VuZXJhdGVTZWNyZXQoa3MpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIEtleVNwZWMga3MgPSBuZXcgUEJFS2V5U3BlYyhQQVNTV09SRCwgU0FMVCwgSVRFUkFUSU9OUywgS0VZX0xFTkdUSCk7CisgICAgICAgIGZhY3RvcnkuZ2VuZXJhdGVTZWNyZXQoa3MpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfUEJLREYyX2IzMDU5OTUwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RfUEJLREYyKFBBU1NXT1JELCBTQUxULCBJVEVSQVRJT05TLCBLRVlfTEVOR1RILAorICAgICAgICAgICAgICAgICAgICBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKTB4NzAsIChieXRlKTB4NzQsIChieXRlKTB4ZGIsIChieXRlKTB4NzIsCisgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkweDM1LCAoYnl0ZSkweGQ0LCAoYnl0ZSkweDExLCAoYnl0ZSkweDY4LAorICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpMHg4MywgKGJ5dGUpMHg3YywgKGJ5dGUpMHgxNCwgKGJ5dGUpMHgxZiwKKyAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKTB4ZjYsIChieXRlKTB4NGEsIChieXRlKTB4YjAsIChieXRlKTB4NTQKKyAgICAgICAgICAgICAgICAgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogNjQtYml0IFRlc3QgdmVjdG9yIGZyb20gUkZDIDMyMTEKKyAgICAgKgorICAgICAqIFNlZSBhbHNvIG9yZy5ib3VuY3ljYXN0bGUuY3J5cHRvLnRlc3QuUEtDUzVUZXN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9QQktERjJfcmZjMzIxMV82NCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGFyW10gcGFzc3dvcmQgPSAicGFzc3dvcmQiLnRvQ2hhckFycmF5KCk7CisgICAgICAgIGJ5dGVbXSBzYWx0ID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAoYnl0ZSkweDEyLCAoYnl0ZSkweDM0LCAoYnl0ZSkweDU2LCAoYnl0ZSkweDc4LAorICAgICAgICAgICAgKGJ5dGUpMHg3OCwgKGJ5dGUpMHg1NiwgKGJ5dGUpMHgzNCwgKGJ5dGUpMHgxMgorICAgICAgICB9OworICAgICAgICBpbnQgaXRlcmF0aW9ucyA9IDU7CisgICAgICAgIGludCBrZXlMZW5ndGggPSA2NDsKKyAgICAgICAgYnl0ZVtdIGV4cGVjdGVkID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAoYnl0ZSkweEQxLCAoYnl0ZSkweERBLCAoYnl0ZSkweEE3LCAoYnl0ZSkweDg2LAorICAgICAgICAgICAgKGJ5dGUpMHgxNSwgKGJ5dGUpMHhGMiwgKGJ5dGUpMHg4NywgKGJ5dGUpMHhFNgorICAgICAgICB9OworICAgICAgICB0ZXN0X1BCS0RGMihwYXNzd29yZCwgc2FsdCwgaXRlcmF0aW9ucywga2V5TGVuZ3RoLCBleHBlY3RlZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogMTkyLWJpdCBUZXN0IHZlY3RvciBmcm9tIFJGQyAzMjExCisgICAgICoKKyAgICAgKiBTZWUgYWxzbyBvcmcuYm91bmN5Y2FzdGxlLmNyeXB0by50ZXN0LlBLQ1M1VGVzdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfUEJLREYyX3JmYzMyMTFfMTkyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoYXJbXSBwYXNzd29yZCA9ICgiQWxsIG4tZW50aXRpZXMgbXVzdCBjb21tdW5pY2F0ZSB3aXRoIG90aGVyICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIm4tZW50aXRpZXMgdmlhIG4tMSBlbnRpdGVlaGVlaGVlcyIpLnRvQ2hhckFycmF5KCk7CisgICAgICAgIGJ5dGVbXSBzYWx0ID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAoYnl0ZSkweDEyLCAoYnl0ZSkweDM0LCAoYnl0ZSkweDU2LCAoYnl0ZSkweDc4LAorICAgICAgICAgICAgKGJ5dGUpMHg3OCwgKGJ5dGUpMHg1NiwgKGJ5dGUpMHgzNCwgKGJ5dGUpMHgxMgorICAgICAgICB9OworICAgICAgICBpbnQgaXRlcmF0aW9ucyA9IDUwMDsKKyAgICAgICAgaW50IGtleUxlbmd0aCA9IDE5MjsKKyAgICAgICAgYnl0ZVtdIGV4cGVjdGVkID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAoYnl0ZSkweDZhLCAoYnl0ZSkweDg5LCAoYnl0ZSkweDcwLCAoYnl0ZSkweGJmLCAoYnl0ZSkweDY4LCAoYnl0ZSkweGM5LAorICAgICAgICAgICAgKGJ5dGUpMHgyYywgKGJ5dGUpMHhhZSwgKGJ5dGUpMHhhOCwgKGJ5dGUpMHg0YSwgKGJ5dGUpMHg4ZCwgKGJ5dGUpMHhmMiwKKyAgICAgICAgICAgIChieXRlKTB4ODUsIChieXRlKTB4MTAsIChieXRlKTB4ODUsIChieXRlKTB4ODYsIChieXRlKTB4MDcsIChieXRlKTB4MTIsCisgICAgICAgICAgICAoYnl0ZSkweDYzLCAoYnl0ZSkweDgwLCAoYnl0ZSkweGNjLCAoYnl0ZSkweDQ3LCAoYnl0ZSkweGFiLCAoYnl0ZSkweDJkCisgICAgICAgIH07CisgICAgICAgIHRlc3RfUEJLREYyKHBhc3N3b3JkLCBzYWx0LCBpdGVyYXRpb25zLCBrZXlMZW5ndGgsIGV4cGVjdGVkKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdF9QQktERjIoY2hhcltdIHBhc3N3b3JkLCBieXRlW10gc2FsdCwgaW50IGl0ZXJhdGlvbnMsIGludCBrZXlMZW5ndGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBleHBlY3RlZCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNlY3JldEtleUZhY3RvcnkgZmFjdG9yeSA9IFNlY3JldEtleUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlBCS0RGMldpdGhIbWFjU0hBMSIpOworICAgICAgICBLZXlTcGVjIGtzID0gbmV3IFBCRUtleVNwZWMocGFzc3dvcmQsIHNhbHQsIGl0ZXJhdGlvbnMsIGtleUxlbmd0aCk7CisgICAgICAgIFNlY3JldEtleSBrZXkgPSBmYWN0b3J5LmdlbmVyYXRlU2VjcmV0KGtzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGV4cGVjdGVkLCBrZXkuZ2V0RW5jb2RlZCgpKSk7CisKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JUZXN0REguamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L2NyeXB0by9zcGVjL0FsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclRlc3RESC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU3OGVlNmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JUZXN0REguamF2YQpAQCAtMCwwICsxLDM0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmF4LmNyeXB0by5zcGVjOworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uQnJva2VuVGVzdDsKK2ltcG9ydCB0ZXN0cy5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JUZXN0OworaW1wb3J0IHRlc3RzLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcktleUFncmVlbWVudEhlbHBlcjsKKworcHVibGljIGNsYXNzIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclRlc3RESCBleHRlbmRzCisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclRlc3QgeworCisgICAgcHVibGljIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclRlc3RESCgpIHsKKyAgICAgICAgc3VwZXIoIkRIIiwgbmV3IEFsZ29yaXRobVBhcmFtZXRlcktleUFncmVlbWVudEhlbHBlcigiREgiKSk7CisgICAgfQorCisgICAgQEJyb2tlblRlc3QoIlN1ZmZlcnMgZnJvbSBESCBzbG93bmVzcywgZGlzYWJsaW5nIGZvciBub3ciKQorICAgIHB1YmxpYyB2b2lkIHRlc3RBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IoKSB7CisgICAgICAgIHN1cGVyLnRlc3RBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L2NyeXB0by9zcGVjL0FsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclRlc3REU0EuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L2NyeXB0by9zcGVjL0FsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclRlc3REU0EuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MzRkZTZjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL3NwZWMvQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yVGVzdERTQS5qYXZhCkBAIC0wLDAgKzEsMjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YXguY3J5cHRvLnNwZWM7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRFNBUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCB0ZXN0cy5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JUZXN0OworaW1wb3J0IHRlc3RzLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlclNpZ25hdHVyZUhlbHBlcjsKKworcHVibGljIGNsYXNzIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclRlc3REU0EgZXh0ZW5kcworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JUZXN0IHsKKworICAgIHB1YmxpYyBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JUZXN0RFNBKCkgeworICAgICAgICBzdXBlcigiRFNBIiwgbmV3IEFsZ29yaXRobVBhcmFtZXRlclNpZ25hdHVyZUhlbHBlcjxEU0FQYXJhbWV0ZXJTcGVjPigiRFNBIiwgRFNBUGFyYW1ldGVyU3BlYy5jbGFzcykpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L2NyeXB0by9zcGVjL0FsZ29yaXRobVBhcmFtZXRlcnNUZXN0QUVTLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9BbGdvcml0aG1QYXJhbWV0ZXJzVGVzdEFFUy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1M2I1N2QKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9BbGdvcml0aG1QYXJhbWV0ZXJzVGVzdEFFUy5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YXguY3J5cHRvLnNwZWM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5JdlBhcmFtZXRlclNwZWM7CitpbXBvcnQgdGVzdHMuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyU3ltbWV0cmljSGVscGVyOworaW1wb3J0IHRlc3RzLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnNUZXN0OworCitwdWJsaWMgY2xhc3MgQWxnb3JpdGhtUGFyYW1ldGVyc1Rlc3RBRVMgZXh0ZW5kcyBBbGdvcml0aG1QYXJhbWV0ZXJzVGVzdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gcGFyYW1ldGVyRGF0YSA9IG5ldyBieXRlW10geworICAgICAgICAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MDgsIChieXRlKSAweDY4LCAoYnl0ZSkgMHhDOCwKKyAgICAgICAgKGJ5dGUpIDB4RkYsIChieXRlKSAweDY0LCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4RjUsCisgICAgICAgIChieXRlKSAweDA0LCAoYnl0ZSkgMHgwOCwgKGJ5dGUpIDB4NjgsIChieXRlKSAweEM4LAorICAgICAgICAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4NjQsIChieXRlKSAweDcyLCAoYnl0ZSkgMHhGNSB9OworCisgICAgcHVibGljIEFsZ29yaXRobVBhcmFtZXRlcnNUZXN0QUVTKCkgeworICAgICAgICBzdXBlcigiQUVTIiwgbmV3IEFsZ29yaXRobVBhcmFtZXRlclN5bW1ldHJpY0hlbHBlcigiQUVTIiwgIkNCQy9QS0NTNVBBRERJTkciLCAxMjgpLCBuZXcgSXZQYXJhbWV0ZXJTcGVjKHBhcmFtZXRlckRhdGEpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L2NyeXB0by9zcGVjL0FsZ29yaXRobVBhcmFtZXRlcnNUZXN0REVTLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9BbGdvcml0aG1QYXJhbWV0ZXJzVGVzdERFUy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjNzlkNGMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9BbGdvcml0aG1QYXJhbWV0ZXJzVGVzdERFUy5qYXZhCkBAIC0wLDAgKzEsMzIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YXguY3J5cHRvLnNwZWM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5JdlBhcmFtZXRlclNwZWM7CitpbXBvcnQgdGVzdHMuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyU3ltbWV0cmljSGVscGVyOworaW1wb3J0IHRlc3RzLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnNUZXN0OworCitwdWJsaWMgY2xhc3MgQWxnb3JpdGhtUGFyYW1ldGVyc1Rlc3RERVMgZXh0ZW5kcyBBbGdvcml0aG1QYXJhbWV0ZXJzVGVzdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gcGFyYW1ldGVyRGF0YSA9IG5ldyBieXRlW10geworICAgICAgICAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MDgsIChieXRlKSAweDY4LCAoYnl0ZSkgMHhDOCwKKyAgICAgICAgKGJ5dGUpIDB4RkYsIChieXRlKSAweDY0LCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4RjUgfTsKKworICAgIHB1YmxpYyBBbGdvcml0aG1QYXJhbWV0ZXJzVGVzdERFUygpIHsKKyAgICAgICAgc3VwZXIoIkRFUyIsIG5ldyBBbGdvcml0aG1QYXJhbWV0ZXJTeW1tZXRyaWNIZWxwZXIoIkRFUyIsICJDQkMvUEtDUzVQQURESU5HIiwgNTYpLCBuZXcgSXZQYXJhbWV0ZXJTcGVjKHBhcmFtZXRlckRhdGEpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L2NyeXB0by9zcGVjL0FsZ29yaXRobVBhcmFtZXRlcnNUZXN0REVTZWRlLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9BbGdvcml0aG1QYXJhbWV0ZXJzVGVzdERFU2VkZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI0ZDA0NGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9BbGdvcml0aG1QYXJhbWV0ZXJzVGVzdERFU2VkZS5qYXZhCkBAIC0wLDAgKzEsMzIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YXguY3J5cHRvLnNwZWM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5JdlBhcmFtZXRlclNwZWM7CitpbXBvcnQgdGVzdHMuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyU3ltbWV0cmljSGVscGVyOworaW1wb3J0IHRlc3RzLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnNUZXN0OworCitwdWJsaWMgY2xhc3MgQWxnb3JpdGhtUGFyYW1ldGVyc1Rlc3RERVNlZGUgZXh0ZW5kcyBBbGdvcml0aG1QYXJhbWV0ZXJzVGVzdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gcGFyYW1ldGVyRGF0YSA9IG5ldyBieXRlW10geworICAgICAgICAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MDgsIChieXRlKSAweDY4LCAoYnl0ZSkgMHhDOCwKKyAgICAgICAgKGJ5dGUpIDB4RkYsIChieXRlKSAweDY0LCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4RjUgfTsKKworICAgIHB1YmxpYyBBbGdvcml0aG1QYXJhbWV0ZXJzVGVzdERFU2VkZSgpIHsKKyAgICAgICAgc3VwZXIoIkRFU2VkZSIsIG5ldyBBbGdvcml0aG1QYXJhbWV0ZXJTeW1tZXRyaWNIZWxwZXIoIkRFU2VkZSIsICJDQkMvUEtDUzVQQURESU5HIiwgMTEyKSwgbmV3IEl2UGFyYW1ldGVyU3BlYyhwYXJhbWV0ZXJEYXRhKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9BbGdvcml0aG1QYXJhbWV0ZXJzVGVzdERILmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9BbGdvcml0aG1QYXJhbWV0ZXJzVGVzdERILmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTY1ZGFhMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L2NyeXB0by9zcGVjL0FsZ29yaXRobVBhcmFtZXRlcnNUZXN0REguamF2YQpAQCAtMCwwICsxLDY5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmF4LmNyeXB0by5zcGVjOworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uQnJva2VuVGVzdDsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5ESFBhcmFtZXRlclNwZWM7CitpbXBvcnQgdGVzdHMuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyS2V5QWdyZWVtZW50SGVscGVyOworaW1wb3J0IHRlc3RzLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnNUZXN0OworCitwdWJsaWMgY2xhc3MgQWxnb3JpdGhtUGFyYW1ldGVyc1Rlc3RESCBleHRlbmRzIEFsZ29yaXRobVBhcmFtZXRlcnNUZXN0IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBQID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4QjgsIChieXRlKSAweEE0LCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MTAsCisgICAgICAgICAgICAoYnl0ZSkgMHhBMiwgKGJ5dGUpIDB4OEIsIChieXRlKSAweEQyLCAoYnl0ZSkgMHhDMCwgKGJ5dGUpIDB4QjYsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NywgKGJ5dGUpIDB4RkYsIChieXRlKSAweDE1LCAoYnl0ZSkgMHhCQSwgKGJ5dGUpIDB4MTgsCisgICAgICAgICAgICAoYnl0ZSkgMHhFOSwgKGJ5dGUpIDB4N0QsIChieXRlKSAweDc3LCAoYnl0ZSkgMHg5RiwgKGJ5dGUpIDB4QUYsCisgICAgICAgICAgICAoYnl0ZSkgMHg2RiwgKGJ5dGUpIDB4MEIsIChieXRlKSAweEE0LCAoYnl0ZSkgMHhCNiwgKGJ5dGUpIDB4MkIsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4RTIsIChieXRlKSAweDAxLCAoYnl0ZSkgMHg2NiwgKGJ5dGUpIDB4NDEsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4RTcsIChieXRlKSAweDZBLCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4MTksCisgICAgICAgICAgICAoYnl0ZSkgMHg5NCwgKGJ5dGUpIDB4MTgsIChieXRlKSAweDQ2LCAoYnl0ZSkgMHhCQSwgKGJ5dGUpIDB4NjAsCisgICAgICAgICAgICAoYnl0ZSkgMHgyRSwgKGJ5dGUpIDB4NUEsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg2QywgKGJ5dGUpIDB4NEIsCisgICAgICAgICAgICAoYnl0ZSkgMHhCRiwgKGJ5dGUpIDB4OEMsIChieXRlKSAweEJGLCAoYnl0ZSkgMHhCOSwgKGJ5dGUpIDB4RUUsCisgICAgICAgICAgICAoYnl0ZSkgMHhDQywgKGJ5dGUpIDB4MzUsIChieXRlKSAweDg5LCAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4MDIsCisgICAgICAgICAgICAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4RkUsIChieXRlKSAweEY0LCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4M0IsCisgICAgICAgICAgICAoYnl0ZSkgMHg1RSwgKGJ5dGUpIDB4OEEsIChieXRlKSAweDQyLCAoYnl0ZSkgMHhCMywgKGJ5dGUpIDB4Mzl9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIFEgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgIChieXRlKSAweDAwLCAoYnl0ZSkgMHg4NywgKGJ5dGUpIDB4RTIsIChieXRlKSAweEQxLCAoYnl0ZSkgMHg4QSwKKyAgICAgICAgICAgIChieXRlKSAweDIzLCAoYnl0ZSkgMHg5MCwgKGJ5dGUpIDB4M0EsIChieXRlKSAweDBGLCAoYnl0ZSkgMHhDOCwKKyAgICAgICAgICAgIChieXRlKSAweDM4LCAoYnl0ZSkgMHhBOCwgKGJ5dGUpIDB4NjUsIChieXRlKSAweDM1LCAoYnl0ZSkgMHg4OSwKKyAgICAgICAgICAgIChieXRlKSAweDRGLCAoYnl0ZSkgMHg0QiwgKGJ5dGUpIDB4QjMsIChieXRlKSAweEJGLCAoYnl0ZSkgMHgxOCwKKyAgICAgICAgICAgIChieXRlKSAweDNDLCAoYnl0ZSkgMHgzQiwgKGJ5dGUpIDB4RDgsIChieXRlKSAweDcyLCAoYnl0ZSkgMHhDMywKKyAgICAgICAgICAgIChieXRlKSAweENGLCAoYnl0ZSkgMHhDOSwgKGJ5dGUpIDB4QTcsIChieXRlKSAweDM5LCAoYnl0ZSkgMHg3RSwKKyAgICAgICAgICAgIChieXRlKSAweDlDLCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4REEsIChieXRlKSAweERFLCAoYnl0ZSkgMHg4RSwKKyAgICAgICAgICAgIChieXRlKSAweDk2LCAoYnl0ZSkgMHg5RCwgKGJ5dGUpIDB4NDQsIChieXRlKSAweEMxLCAoYnl0ZSkgMHgxRSwKKyAgICAgICAgICAgIChieXRlKSAweDU4LCAoYnl0ZSkgMHhDNywgKGJ5dGUpIDB4RkMsIChieXRlKSAweDQwLCAoYnl0ZSkgMHgxQiwKKyAgICAgICAgICAgIChieXRlKSAweEU4LCAoYnl0ZSkgMHgyMywgKGJ5dGUpIDB4RjMsIChieXRlKSAweDZCLCAoYnl0ZSkgMHg5NSwKKyAgICAgICAgICAgIChieXRlKSAweDY4LCAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4OTMsIChieXRlKSAweDM1LCAoYnl0ZSkgMHgwNSwKKyAgICAgICAgICAgIChieXRlKSAweEM1LCAoYnl0ZSkgMHhDQiwgKGJ5dGUpIDB4QjgsIChieXRlKSAweDU3LCAoYnl0ZSkgMHg4RiwKKyAgICAgICAgICAgIChieXRlKSAweEI5LCAoYnl0ZSkgMHhDMywgKGJ5dGUpIDB4MzYsIChieXRlKSAweDA5LCAoYnl0ZSkgMHg1MX07CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgbCA9IDUxMTsKKworICAgIHB1YmxpYyBBbGdvcml0aG1QYXJhbWV0ZXJzVGVzdERIKCkgeworICAgICAgICBzdXBlcigiREgiLCBuZXcgQWxnb3JpdGhtUGFyYW1ldGVyS2V5QWdyZWVtZW50SGVscGVyKCJESCIpLAorICAgICAgICAgICAgICAgIG5ldyBESFBhcmFtZXRlclNwZWMobmV3IEJpZ0ludGVnZXIoUCksIG5ldyBCaWdJbnRlZ2VyKFEpLCBsKSk7CisKKyAgICB9CisKKyAgICBAQnJva2VuVGVzdCgiU3VmZmVycyBmcm9tIERIIHNsb3duZXNzLCBkaXNhYmxpbmcgZm9yIG5vdyIpCisgICAgcHVibGljIHZvaWQgdGVzdEFsZ29yaXRobVBhcmFtZXRlcnMoKSB7CisgICAgICAgIHN1cGVyLnRlc3RBbGdvcml0aG1QYXJhbWV0ZXJzKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9BbGdvcml0aG1QYXJhbWV0ZXJzVGVzdERTQS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL3NwZWMvQWxnb3JpdGhtUGFyYW1ldGVyc1Rlc3REU0EuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNDgyMGVkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL3NwZWMvQWxnb3JpdGhtUGFyYW1ldGVyc1Rlc3REU0EuamF2YQpAQCAtMCwwICsxLDY3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmF4LmNyeXB0by5zcGVjOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkRTQVBhcmFtZXRlclNwZWM7CitpbXBvcnQgdGVzdHMuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyU2lnbmF0dXJlSGVscGVyOworaW1wb3J0IHRlc3RzLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnNUZXN0OworCitwdWJsaWMgY2xhc3MgQWxnb3JpdGhtUGFyYW1ldGVyc1Rlc3REU0EgZXh0ZW5kcyBBbGdvcml0aG1QYXJhbWV0ZXJzVGVzdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gUCA9IG5ldyBieXRlW10geworICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweEI5LCAoYnl0ZSkgMHg1MywgKGJ5dGUpIDB4QTQsIChieXRlKSAweEJCLAorICAgICAgICAgICAgKGJ5dGUpIDB4QzgsIChieXRlKSAweEZELCAoYnl0ZSkgMHg5NCwgKGJ5dGUpIDB4NEIsIChieXRlKSAweEMwLAorICAgICAgICAgICAgKGJ5dGUpIDB4RDQsIChieXRlKSAweDZCLCAoYnl0ZSkgMHhBOSwgKGJ5dGUpIDB4QUIsIChieXRlKSAweDVBLAorICAgICAgICAgICAgKGJ5dGUpIDB4MUUsIChieXRlKSAweDg1LCAoYnl0ZSkgMHg3RSwgKGJ5dGUpIDB4ODcsIChieXRlKSAweDM4LAorICAgICAgICAgICAgKGJ5dGUpIDB4NzksIChieXRlKSAweDFDLCAoYnl0ZSkgMHhCRiwgKGJ5dGUpIDB4Q0YsIChieXRlKSAweDMyLAorICAgICAgICAgICAgKGJ5dGUpIDB4NUEsIChieXRlKSAweDQ1LCAoYnl0ZSkgMHhGOCwgKGJ5dGUpIDB4RTQsIChieXRlKSAweDA4LAorICAgICAgICAgICAgKGJ5dGUpIDB4MjgsIChieXRlKSAweEE0LCAoYnl0ZSkgMHgxMiwgKGJ5dGUpIDB4OEEsIChieXRlKSAweDlELAorICAgICAgICAgICAgKGJ5dGUpIDB4MDYsIChieXRlKSAweDUzLCAoYnl0ZSkgMHgxQywgKGJ5dGUpIDB4QUEsIChieXRlKSAweDZBLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjEsIChieXRlKSAweEMxLCAoYnl0ZSkgMHg5NSwgKGJ5dGUpIDB4RjgsIChieXRlKSAweEFBLAorICAgICAgICAgICAgKGJ5dGUpIDB4QjIsIChieXRlKSAweEI4LCAoYnl0ZSkgMHg0MywgKGJ5dGUpIDB4MzgsIChieXRlKSAweDg2LAorICAgICAgICAgICAgKGJ5dGUpIDB4MTUsIChieXRlKSAweDk0LCAoYnl0ZSkgMHhDRiwgKGJ5dGUpIDB4NDAsIChieXRlKSAweEE1LAorICAgICAgICAgICAgKGJ5dGUpIDB4MEQsIChieXRlKSAweEYzLCAoYnl0ZSkgMHg5QSwgKGJ5dGUpIDB4NDksIChieXRlKSAweDEyLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzIsIChieXRlKSAweDY0LCAoYnl0ZSkgMHgxMSwgKGJ5dGUpIDB4REQsIChieXRlKSAweDg1fTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gUSA9IG5ldyBieXRlW10geworICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweEY4LCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4NkEsIChieXRlKSAweDkyLAorICAgICAgICAgICAgKGJ5dGUpIDB4Q0IsIChieXRlKSAweDQ3LCAoYnl0ZSkgMHg5NSwgKGJ5dGUpIDB4MTgsIChieXRlKSAweDFGLAorICAgICAgICAgICAgKGJ5dGUpIDB4N0UsIChieXRlKSAweEQ4LCAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4MDUsIChieXRlKSAweEI2LAorICAgICAgICAgICAgKGJ5dGUpIDB4MjYsIChieXRlKSAweDRELCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4OTQsIChieXRlKSAweEZBLAorICAgICAgICAgICAgKGJ5dGUpIDB4NUR9OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBHID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAoYnl0ZSkgMHgyQiwgKGJ5dGUpIDB4RjUsIChieXRlKSAweDkxLCAoYnl0ZSkgMHg0NywgKGJ5dGUpIDB4QzgsCisgICAgICAgICAgICAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4NzksIChieXRlKSAweDc1LCAoYnl0ZSkgMHgyQSwgKGJ5dGUpIDB4OEUsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4N0UsIChieXRlKSAweEY1LCAoYnl0ZSkgMHhBNSwgKGJ5dGUpIDB4MTQsCisgICAgICAgICAgICAoYnl0ZSkgMHg5OCwgKGJ5dGUpIDB4OTcsIChieXRlKSAweEU4LCAoYnl0ZSkgMHhDNSwgKGJ5dGUpIDB4NUUsCisgICAgICAgICAgICAoYnl0ZSkgMHg3QSwgKGJ5dGUpIDB4MzksIChieXRlKSAweEZFLCAoYnl0ZSkgMHgzQiwgKGJ5dGUpIDB4NjgsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4ODUsIChieXRlKSAweEQ0LCAoYnl0ZSkgMHhEQywgKGJ5dGUpIDB4QTUsCisgICAgICAgICAgICAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4QzEsIChieXRlKSAweDgyLCAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4OTgsCisgICAgICAgICAgICAoYnl0ZSkgMHhEMywgKGJ5dGUpIDB4MDYsIChieXRlKSAweEUyLCAoYnl0ZSkgMHg0QSwgKGJ5dGUpIDB4NDUsCisgICAgICAgICAgICAoYnl0ZSkgMHhENywgKGJ5dGUpIDB4RjUsIChieXRlKSAweDU3LCAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4NTUsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4RDQsIChieXRlKSAweDc0LCAoYnl0ZSkgMHg2QSwgKGJ5dGUpIDB4OUUsCisgICAgICAgICAgICAoYnl0ZSkgMHgyRCwgKGJ5dGUpIDB4NDIsIChieXRlKSAweERGLCAoYnl0ZSkgMHhDMiwgKGJ5dGUpIDB4ODgsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NSwgKGJ5dGUpIDB4OTcsIChieXRlKSAweEE4LCAoYnl0ZSkgMHg3RCwgKGJ5dGUpIDB4MTEsCisgICAgICAgICAgICAoYnl0ZSkgMHg1NSwgKGJ5dGUpIDB4OUMsIChieXRlKSAweDdDLCAoYnl0ZSkgMHg5Rn07CisKKworICAgIHB1YmxpYyBBbGdvcml0aG1QYXJhbWV0ZXJzVGVzdERTQSgpIHsKKyAgICAgICAgc3VwZXIoIkRTQSIsIG5ldyBBbGdvcml0aG1QYXJhbWV0ZXJTaWduYXR1cmVIZWxwZXI8RFNBUGFyYW1ldGVyU3BlYz4oCisgICAgICAgICAgICAgICAgIkRTQSIsIERTQVBhcmFtZXRlclNwZWMuY2xhc3MpLCBuZXcgRFNBUGFyYW1ldGVyU3BlYygKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcihQKSwgbmV3IEJpZ0ludGVnZXIoUSksIG5ldyBCaWdJbnRlZ2VyKEcpKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9BbGdvcml0aG1QYXJhbWV0ZXJzVGVzdE9BRVAuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L2NyeXB0by9zcGVjL0FsZ29yaXRobVBhcmFtZXRlcnNUZXN0T0FFUC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBhNzVkMmMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9BbGdvcml0aG1QYXJhbWV0ZXJzVGVzdE9BRVAuamF2YQpAQCAtMCwwICsxLDMwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmF4LmNyeXB0by5zcGVjOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLk1HRjFQYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLk9BRVBQYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLlBTb3VyY2U7CitpbXBvcnQgdGVzdHMuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyQXN5bW1ldHJpY0hlbHBlcjsKK2ltcG9ydCB0ZXN0cy5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzVGVzdDsKKworcHVibGljIGNsYXNzIEFsZ29yaXRobVBhcmFtZXRlcnNUZXN0T0FFUCBleHRlbmRzIEFsZ29yaXRobVBhcmFtZXRlcnNUZXN0IHsKKworICAgIHB1YmxpYyBBbGdvcml0aG1QYXJhbWV0ZXJzVGVzdE9BRVAoKSB7CisgICAgICAgIHN1cGVyKCJPQUVQIiwgbmV3IEFsZ29yaXRobVBhcmFtZXRlckFzeW1tZXRyaWNIZWxwZXIoIlJTQSIpLCBuZXcgT0FFUFBhcmFtZXRlclNwZWMoIlNIQS0xIiwgIk1HRjEiLCBNR0YxUGFyYW1ldGVyU3BlYy5TSEExLCBQU291cmNlLlBTcGVjaWZpZWQuREVGQVVMVCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL3NwZWMvS2V5RmFjdG9yeVRlc3RESC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL3NwZWMvS2V5RmFjdG9yeVRlc3RESC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY4OWRhOWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9LZXlGYWN0b3J5VGVzdERILmphdmEKQEAgLTAsMCArMSwzMyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5ESFByaXZhdGVLZXlTcGVjOworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLkRIUHVibGljS2V5U3BlYzsKK2ltcG9ydCB0ZXN0cy5zZWN1cml0eS5LZXlBZ3JlZW1lbnRIZWxwZXI7CitpbXBvcnQgdGVzdHMuc2VjdXJpdHkuS2V5RmFjdG9yeVRlc3Q7CisKK3B1YmxpYyBjbGFzcyBLZXlGYWN0b3J5VGVzdERIIGV4dGVuZHMgS2V5RmFjdG9yeVRlc3Q8REhQdWJsaWNLZXlTcGVjLCBESFByaXZhdGVLZXlTcGVjPiB7CisKKyAgICBwdWJsaWMgS2V5RmFjdG9yeVRlc3RESCgpIHsKKyAgICAgICAgc3VwZXIoIkRIIiwgREhQdWJsaWNLZXlTcGVjLmNsYXNzLCBESFByaXZhdGVLZXlTcGVjLmNsYXNzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgY2hlY2soS2V5UGFpciBrZXlQYWlyKSB7CisgICAgICAgIG5ldyBLZXlBZ3JlZW1lbnRIZWxwZXIoIkRIIikudGVzdChrZXlQYWlyKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9LZXlGYWN0b3J5VGVzdERTQS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL3NwZWMvS2V5RmFjdG9yeVRlc3REU0EuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZWU0MzYzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL3NwZWMvS2V5RmFjdG9yeVRlc3REU0EuamF2YQpAQCAtMCwwICsxLDM0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBsaWJjb3JlLmphdmF4LmNyeXB0by5zcGVjOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5EU0FQcml2YXRlS2V5U3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRFNBUHVibGljS2V5U3BlYzsKK2ltcG9ydCB0ZXN0cy5zZWN1cml0eS5LZXlGYWN0b3J5VGVzdDsKK2ltcG9ydCB0ZXN0cy5zZWN1cml0eS5TaWduYXR1cmVIZWxwZXI7CisKK3B1YmxpYyBjbGFzcyBLZXlGYWN0b3J5VGVzdERTQSBleHRlbmRzCisgICAgICAgIEtleUZhY3RvcnlUZXN0PERTQVB1YmxpY0tleVNwZWMsIERTQVByaXZhdGVLZXlTcGVjPiB7CisKKyAgICBwdWJsaWMgS2V5RmFjdG9yeVRlc3REU0EoKSB7CisgICAgICAgIHN1cGVyKCJEU0EiLCBEU0FQdWJsaWNLZXlTcGVjLmNsYXNzLCBEU0FQcml2YXRlS2V5U3BlYy5jbGFzcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGNoZWNrKEtleVBhaXIga2V5UGFpcikgeworICAgICAgICBuZXcgU2lnbmF0dXJlSGVscGVyKCJEU0EiKS50ZXN0KGtleVBhaXIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L2NyeXB0by9zcGVjL0tleUZhY3RvcnlUZXN0UlNBLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9LZXlGYWN0b3J5VGVzdFJTQS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE2NWExOWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9LZXlGYWN0b3J5VGVzdFJTQS5qYXZhCkBAIC0wLDAgKzEsMzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGxpYmNvcmUuamF2YXguY3J5cHRvLnNwZWM7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLlJTQVByaXZhdGVLZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5SU0FQdWJsaWNLZXlTcGVjOworaW1wb3J0IHRlc3RzLnNlY3VyaXR5LkNpcGhlckFzeW1tZXRyaWNDcnlwdEhlbHBlcjsKK2ltcG9ydCB0ZXN0cy5zZWN1cml0eS5LZXlGYWN0b3J5VGVzdDsKKworcHVibGljIGNsYXNzIEtleUZhY3RvcnlUZXN0UlNBIGV4dGVuZHMKKyAgICAgICAgS2V5RmFjdG9yeVRlc3Q8UlNBUHVibGljS2V5U3BlYywgUlNBUHJpdmF0ZUtleVNwZWM+IHsKKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBLZXlGYWN0b3J5VGVzdFJTQSgpIHsKKyAgICAgICAgc3VwZXIoIlJTQSIsIFJTQVB1YmxpY0tleVNwZWMuY2xhc3MsIFJTQVByaXZhdGVLZXlTcGVjLmNsYXNzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgY2hlY2soS2V5UGFpciBrZXlQYWlyKSB7CisgICAgICAgIG5ldyBDaXBoZXJBc3ltbWV0cmljQ3J5cHRIZWxwZXIoIlJTQSIpLnRlc3Qoa2V5UGFpcik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL3NwZWMvS2V5UGFpckdlbmVyYXRvclRlc3RESC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL3NwZWMvS2V5UGFpckdlbmVyYXRvclRlc3RESC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM0MzIyZmYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9jcnlwdG8vc3BlYy9LZXlQYWlyR2VuZXJhdG9yVGVzdERILmphdmEKQEAgLTAsMCArMSwzMyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLkJyb2tlblRlc3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgdGVzdHMuc2VjdXJpdHkuS2V5QWdyZWVtZW50SGVscGVyOworaW1wb3J0IHRlc3RzLnNlY3VyaXR5LktleVBhaXJHZW5lcmF0b3JUZXN0OworCitwdWJsaWMgY2xhc3MgS2V5UGFpckdlbmVyYXRvclRlc3RESCBleHRlbmRzIEtleVBhaXJHZW5lcmF0b3JUZXN0IHsKKworICAgIHB1YmxpYyBLZXlQYWlyR2VuZXJhdG9yVGVzdERIKCkgeworICAgICAgICBzdXBlcigiREgiLCBuZXcgS2V5QWdyZWVtZW50SGVscGVyKCJESCIpKTsKKyAgICB9CisKKyAgICBAQnJva2VuVGVzdCgiVGFrZXMgYWdlcyBkdWUgdG8gREggY29tcHV0YXRpb25zLiBEaXNhYmxpbmcgZm9yIG5vdy4iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlQYWlyR2VuZXJhdG9yKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlc3RLZXlQYWlyR2VuZXJhdG9yKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL3NwZWMvS2V5UGFpckdlbmVyYXRvclRlc3REU0EuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L2NyeXB0by9zcGVjL0tleVBhaXJHZW5lcmF0b3JUZXN0RFNBLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzg3ZWJhZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L2NyeXB0by9zcGVjL0tleVBhaXJHZW5lcmF0b3JUZXN0RFNBLmphdmEKQEAgLTAsMCArMSwyNyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IHRlc3RzLnNlY3VyaXR5LktleVBhaXJHZW5lcmF0b3JUZXN0OworaW1wb3J0IHRlc3RzLnNlY3VyaXR5LlNpZ25hdHVyZUhlbHBlcjsKKworcHVibGljIGNsYXNzIEtleVBhaXJHZW5lcmF0b3JUZXN0RFNBIGV4dGVuZHMgS2V5UGFpckdlbmVyYXRvclRlc3QgeworCisgICAgcHVibGljIEtleVBhaXJHZW5lcmF0b3JUZXN0RFNBKCkgeworICAgICAgICBzdXBlcigiRFNBIiwgbmV3IFNpZ25hdHVyZUhlbHBlcigiRFNBIikpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvY3J5cHRvL3NwZWMvS2V5UGFpckdlbmVyYXRvclRlc3RSU0EuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L2NyeXB0by9zcGVjL0tleVBhaXJHZW5lcmF0b3JUZXN0UlNBLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmU5MjhmZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L2NyeXB0by9zcGVjL0tleVBhaXJHZW5lcmF0b3JUZXN0UlNBLmphdmEKQEAgLTAsMCArMSwyOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgbGliY29yZS5qYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IHRlc3RzLnNlY3VyaXR5LkNpcGhlckFzeW1tZXRyaWNDcnlwdEhlbHBlcjsKK2ltcG9ydCB0ZXN0cy5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yVGVzdDsKKworcHVibGljIGNsYXNzIEtleVBhaXJHZW5lcmF0b3JUZXN0UlNBIGV4dGVuZHMgS2V5UGFpckdlbmVyYXRvclRlc3QgeworCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIEtleVBhaXJHZW5lcmF0b3JUZXN0UlNBKCkgeworICAgICAgICBzdXBlcigiUlNBIiwgbmV3IENpcGhlckFzeW1tZXRyaWNDcnlwdEhlbHBlcigiUlNBIikpOworICAgIH0KKworfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvU2VydmVyU29ja2V0RmFjdG9yeVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9TZXJ2ZXJTb2NrZXRGYWN0b3J5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc3OTk2ZGQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvU2VydmVyU29ja2V0RmFjdG9yeVRlc3QuamF2YQpAQCAtMCwwICsxLDEzMSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZheC5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU2VydmVyU29ja2V0OworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YXgubmV0LlNlcnZlclNvY2tldEZhY3Rvcnk7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgU2VydmVyU29ja2V0RmFjdG9yeVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q3JlYXRlU2VydmVyU29ja2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU2VydmVyU29ja2V0IHNlcnZlclNvY2tldCA9IFNlcnZlclNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpLmNyZWF0ZVNlcnZlclNvY2tldCgpOworICAgICAgICBzZXJ2ZXJTb2NrZXQuYmluZChuZXcgSW5ldFNvY2tldEFkZHJlc3MoMCkpOworICAgICAgICB0ZXN0U29ja2V0KHNlcnZlclNvY2tldCwgNTApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVTZXJ2ZXJTb2NrZXRXaXRoUG9ydCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFNlcnZlclNvY2tldCBzZXJ2ZXJTb2NrZXQgPSBTZXJ2ZXJTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKS5jcmVhdGVTZXJ2ZXJTb2NrZXQoMCk7CisgICAgICAgIHRlc3RTb2NrZXQoc2VydmVyU29ja2V0LCA1MCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZVNlcnZlclNvY2tldFdpdGhQb3J0Tm9CYWNrbG9nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU2VydmVyU29ja2V0IHNlcnZlclNvY2tldCA9IFNlcnZlclNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpLmNyZWF0ZVNlcnZlclNvY2tldCgwLCAxKTsKKyAgICAgICAgdGVzdFNvY2tldChzZXJ2ZXJTb2NrZXQsIDEpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVTZXJ2ZXJTb2NrZXRXaXRoUG9ydFplcm9CYWNrbG9nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU2VydmVyU29ja2V0IHNlcnZlclNvY2tldCA9IFNlcnZlclNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpLmNyZWF0ZVNlcnZlclNvY2tldCgwLCAwKTsKKyAgICAgICAgdGVzdFNvY2tldChzZXJ2ZXJTb2NrZXQsIDUwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q3JlYXRlU2VydmVyU29ja2V0V2l0aFBvcnRBbmRCYWNrbG9nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU2VydmVyU29ja2V0IHNlcnZlclNvY2tldCA9IFNlcnZlclNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpLmNyZWF0ZVNlcnZlclNvY2tldCgwLCA1MCk7CisgICAgICAgIHRlc3RTb2NrZXQoc2VydmVyU29ja2V0LCA1MCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RTb2NrZXQoZmluYWwgU2VydmVyU29ja2V0IHNlcnZlclNvY2tldCwgaW50IHNwZWNpZmllZEJhY2tsb2cpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBieXRlW10gZGF0YSA9ICJhYmMiLmdldEJ5dGVzKCk7CisKKyAgICAgICAgbmV3IFRocmVhZChuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU29ja2V0IHMgPSBzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgICAgICAgICAgICAgIHMuZ2V0T3V0cHV0U3RyZWFtKCkud3JpdGUoZGF0YSk7CisgICAgICAgICAgICAgICAgICAgIHMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9KS5zdGFydCgpOworCisgICAgICAgIFNvY2tldCBzb2NrZXQgPSBuZXcgU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBzZXJ2ZXJTb2NrZXQuZ2V0TG9jYWxQb3J0KCkpOworICAgICAgICBhc3NlcnRCYWNrbG9nKHNwZWNpZmllZEJhY2tsb2csIG5ldyBJbmV0U29ja2V0QWRkcmVzcygKKyAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgc2VydmVyU29ja2V0LmdldExvY2FsUG9ydCgpKSk7CisKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBzb2NrZXQuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgdHJhbnNmZXIoaW4sIG91dCk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMudG9TdHJpbmcoZGF0YSksIEFycmF5cy50b1N0cmluZyhvdXQudG9CeXRlQXJyYXkoKSkpOworICAgICAgICBzb2NrZXQuY2xvc2UoKTsKKworICAgICAgICBzZXJ2ZXJTb2NrZXQuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWYWxpZGF0ZXMgdGhhdCB0aGUgYmFja2xvZyBvZiB0aGUgbGlzdGVuaW5nIGFkZHJlc3MgaXMgYXMgc3BlY2lmaWVkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRCYWNrbG9nKGludCBzcGVjaWZpZWRCYWNrbG9nLCBJbmV0U29ja2V0QWRkcmVzcyBzZXJ2ZXJBZGRyZXNzKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgTGlzdDxTb2NrZXQ+IGJhY2tsb2cgPSBuZXcgQXJyYXlMaXN0PFNvY2tldD4oKTsKKyAgICAgICAgaW50IHBlYWsgPSAwOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IG1heCA9IDEwMDsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWF4OyBpKyspIHsKKyAgICAgICAgICAgICAgICBTb2NrZXQgc29ja2V0ID0gbmV3IFNvY2tldCgpOworICAgICAgICAgICAgICAgIGJhY2tsb2cuYWRkKHNvY2tldCk7CisgICAgICAgICAgICAgICAgc29ja2V0LmNvbm5lY3Qoc2VydmVyQWRkcmVzcywgNTAwKTsKKyAgICAgICAgICAgICAgICBwZWFrKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmYWlsKCJGYWlsZWQgdG8gZXhoYXVzdCBiYWNrbG9nIGFmdGVyICIgKyBtYXggKyAiIGNvbm5lY3Rpb25zISIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJiYWNrbG9nIHBlYWtlZCBhdCAiICsgcGVhayk7CisKKyAgICAgICAgZm9yIChTb2NrZXQgc29ja2V0IDogYmFja2xvZykgeworICAgICAgICAgICAgc29ja2V0LmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBJbiA0LjUgb2YgVU5JWCBOZXR3b3JrIFByb2dyYW1taW5nLCBTdGV2ZW5zIHNheXM6CisgICAgICAgICAqICAgICAiQmVya2VsZXktZGVyaXZlZCBpbXBsZW1lbnRhdGlvbnMgYWRkIGEgZnVkZ2UgZmFjdG9yIHRvIHRoZQorICAgICAgICAgKiAgICAgIGJhY2tsb2c6IGl0IGlzIG11bHRpcGxpZWQgYnkgMS41LiIKKyAgICAgICAgICoKKyAgICAgICAgICogV2UndmUgb2JzZXJ2ZWQgdGhhdCBMaW51eCBhbHdheXMgYWRkcyAzIHRvIHRoZSB1c2VyLXNwZWNpZmllZAorICAgICAgICAgKiBiYWNrbG9nLgorICAgICAgICAgKi8KKyAgICAgICAgYXNzZXJ0VHJ1ZShwZWFrID49IHNwZWNpZmllZEJhY2tsb2cgJiYgcGVhayA8PSAoc3BlY2lmaWVkQmFja2xvZyArIDMpICogMS41KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdHJhbnNmZXIoSW5wdXRTdHJlYW0gaW4sIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVsxMDI0XTsKKyAgICAgICAgaW50IGNvdW50OworICAgICAgICB3aGlsZSAoKGNvdW50ID0gaW4ucmVhZChidWZmZXIpKSAhPSAtMSkgeworICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZmZlciwgMCwgY291bnQpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvbmV0L3NzbC9LZXlNYW5hZ2VyRmFjdG9yeVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvS2V5TWFuYWdlckZhY3RvcnlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjJkMzZjOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvS2V5TWFuYWdlckZhY3RvcnlUZXN0LmphdmEKQEAgLTAsMCArMSwzMDIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlLkJ1aWxkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZS5Qcml2YXRlS2V5RW50cnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlckZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5LZXlTdG9yZUJ1aWxkZXJQYXJhbWV0ZXJzOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuWDUwOUV4dGVuZGVkS2V5TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlg1MDlLZXlNYW5hZ2VyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuU3RhbmRhcmROYW1lczsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuVGVzdEtleVN0b3JlOworCitwdWJsaWMgY2xhc3MgS2V5TWFuYWdlckZhY3RvcnlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgVGVzdEtleVN0b3JlIFRFU1RfS0VZX1NUT1JFOworCisgICAgLy8gbm90ZSB0aGUgcmFyZSB1c2FnZSBvZiBEU0Ega2V5cyBoZXJlIGluIGFkZGl0aW9uIHRvIFJTQQorICAgIHByaXZhdGUgc3RhdGljIFRlc3RLZXlTdG9yZSBnZXRUZXN0S2V5U3RvcmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKFRFU1RfS0VZX1NUT1JFID09IG51bGwpIHsKKyAgICAgICAgICAgIFRFU1RfS0VZX1NUT1JFID0gbmV3IFRlc3RLZXlTdG9yZS5CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLmtleUFsZ29yaXRobXMoIlJTQSIsICJEU0EiLCAiRUMiLCAiRUNfUlNBIikKKyAgICAgICAgICAgICAgICAgICAgLmFsaWFzUHJlZml4KCJyc2EtZHNhLWVjIikKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIFRFU1RfS0VZX1NUT1JFOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfS2V5TWFuYWdlckZhY3RvcnlfZ2V0RGVmYXVsdEFsZ29yaXRobSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgYWxnb3JpdGhtID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0RGVmYXVsdEFsZ29yaXRobSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoU3RhbmRhcmROYW1lcy5LRVlfTUFOQUdFUl9GQUNUT1JZX0RFRkFVTFQsIGFsZ29yaXRobSk7CisgICAgICAgIEtleU1hbmFnZXJGYWN0b3J5IGttZiA9IEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgIHRlc3RfS2V5TWFuYWdlckZhY3Rvcnkoa21mKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBVc2VsZXNzTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzIGltcGxlbWVudHMgTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzIHt9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHN1cHBvcnRzTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzKFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgLy8gT25seSB0aGUgIk5ldyIgb25lIHN1cHBvcnRzIE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycworICAgICAgICByZXR1cm4gYWxnb3JpdGhtLmVxdWFscygiTmV3U3VuWDUwOSIpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIGtleVR5cGVzKFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgLy8gQWx0aG91Z2ggdGhlICJOZXciIG9uZSBzdXBwb3J0cyBNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMsCisgICAgICAgIC8vIGl0IGNhbid0IGhhbmRsZSBudWxscyBpbiB0aGUga2V5IHR5cGVzIGFycmF5LgorICAgICAgICByZXR1cm4gKGFsZ29yaXRobS5lcXVhbHMoIk5ld1N1blg1MDkiKQorICAgICAgICAgICAgICAgID8gS0VZX1RZUEVTX1dJVEhfRU1QVFkKKyAgICAgICAgICAgICAgICA6IEtFWV9UWVBFU19XSVRIX0VNUFRZX0FORF9OVUxMKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdF9LZXlNYW5hZ2VyRmFjdG9yeShLZXlNYW5hZ2VyRmFjdG9yeSBrbWYpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnROb3ROdWxsKGttZik7CisgICAgICAgIGFzc2VydE5vdE51bGwoa21mLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChrbWYuZ2V0UHJvdmlkZXIoKSk7CisKKyAgICAgICAgLy8gYmVmb3JlIGluaXQKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGttZi5nZXRLZXlNYW5hZ2VycygpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGluaXQgd2l0aCBudWxsIE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycworICAgICAgICB0cnkgeworICAgICAgICAgICAga21mLmluaXQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGluaXQgd2l0aCB1c2VsZXNzIE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycworICAgICAgICB0cnkgeworICAgICAgICAgICAga21mLmluaXQobmV3IFVzZWxlc3NNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMoKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGluaXQgd2l0aCBLZXlTdG9yZUJ1aWxkZXJQYXJhbWV0ZXJzIE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycworICAgICAgICBQYXNzd29yZFByb3RlY3Rpb24gcHAgPSBuZXcgUGFzc3dvcmRQcm90ZWN0aW9uKGdldFRlc3RLZXlTdG9yZSgpLnN0b3JlUGFzc3dvcmQpOworICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBCdWlsZGVyLm5ld0luc3RhbmNlKGdldFRlc3RLZXlTdG9yZSgpLmtleVN0b3JlLCBwcCk7CisgICAgICAgIEtleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMga3NicCA9IG5ldyBLZXlTdG9yZUJ1aWxkZXJQYXJhbWV0ZXJzKGJ1aWxkZXIpOworICAgICAgICBpZiAoc3VwcG9ydHNNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMoa21mLmdldEFsZ29yaXRobSgpKSkgeworICAgICAgICAgICAga21mLmluaXQoa3NicCk7CisgICAgICAgICAgICB0ZXN0X0tleU1hbmFnZXJGYWN0b3J5X2dldEtleU1hbmFnZXJzKGttZiwgZmFsc2UpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrbWYuaW5pdChrc2JwKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBpbml0IHdpdGggbnVsbCBmb3IgZGVmYXVsdCBiZWhhdmlvcgorICAgICAgICBrbWYuaW5pdChudWxsLCBudWxsKTsKKyAgICAgICAgdGVzdF9LZXlNYW5hZ2VyRmFjdG9yeV9nZXRLZXlNYW5hZ2VycyhrbWYsIHRydWUpOworCisgICAgICAgIC8vIGluaXQgd2l0aCBzcGVjaWZpYyBrZXkgc3RvcmUgYW5kIHBhc3N3b3JkCisgICAgICAgIGttZi5pbml0KGdldFRlc3RLZXlTdG9yZSgpLmtleVN0b3JlLCBnZXRUZXN0S2V5U3RvcmUoKS5zdG9yZVBhc3N3b3JkKTsKKyAgICAgICAgdGVzdF9LZXlNYW5hZ2VyRmFjdG9yeV9nZXRLZXlNYW5hZ2VycyhrbWYsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdF9LZXlNYW5hZ2VyRmFjdG9yeV9nZXRLZXlNYW5hZ2VycyhLZXlNYW5hZ2VyRmFjdG9yeSBrbWYsIGJvb2xlYW4gZW1wdHkpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5TWFuYWdlcltdIGtleU1hbmFnZXJzID0ga21mLmdldEtleU1hbmFnZXJzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoa2V5TWFuYWdlcnMpOworICAgICAgICBhc3NlcnRUcnVlKGtleU1hbmFnZXJzLmxlbmd0aCA+IDApOworICAgICAgICBmb3IgKEtleU1hbmFnZXIga2V5TWFuYWdlciA6IGtleU1hbmFnZXJzKSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGtleU1hbmFnZXIpOworICAgICAgICAgICAgaWYgKGtleU1hbmFnZXIgaW5zdGFuY2VvZiBYNTA5S2V5TWFuYWdlcikgeworICAgICAgICAgICAgICAgIHRlc3RfWDUwOUtleU1hbmFnZXIoKFg1MDlLZXlNYW5hZ2VyKSBrZXlNYW5hZ2VyLCBlbXB0eSwga21mLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIEtFWV9UWVBFU19PTkxZCisgICAgICAgICAgICA9IFN0YW5kYXJkTmFtZXMuS0VZX1RZUEVTLnRvQXJyYXkobmV3IFN0cmluZ1tTdGFuZGFyZE5hbWVzLktFWV9UWVBFUy5zaXplKCldKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBLRVlfVFlQRVNfV0lUSF9FTVBUWQorICAgICAgICAgICAgPSBuZXcgU3RyaW5nW0tFWV9UWVBFU19PTkxZLmxlbmd0aCArIDFdOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIEtFWV9UWVBFU19XSVRIX0VNUFRZX0FORF9OVUxMCisgICAgICAgICAgICA9IG5ldyBTdHJpbmdbS0VZX1RZUEVTX09OTFkubGVuZ3RoICsgMl07CisgICAgc3RhdGljIHsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShLRVlfVFlQRVNfT05MWSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfVFlQRVNfV0lUSF9FTVBUWSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfVFlQRVNfT05MWS5sZW5ndGgpOworICAgICAgICBLRVlfVFlQRVNfV0lUSF9FTVBUWVtLRVlfVFlQRVNfV0lUSF9FTVBUWS5sZW5ndGgtMV0gPSAiIjsKKworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KEtFWV9UWVBFU19XSVRIX0VNUFRZLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9UWVBFU19XSVRIX0VNUFRZX0FORF9OVUxMLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9UWVBFU19XSVRIX0VNUFRZLmxlbmd0aCk7CisgICAgICAgIC8vIGV4dHJhIG51bGwgYXQgZW5kIHJlcXVpcmVzIG5vIGluaXRpYWxpemF0aW9uCisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RfWDUwOUtleU1hbmFnZXIoWDUwOUtleU1hbmFnZXIga20sIGJvb2xlYW4gZW1wdHksIFN0cmluZyBhbGdvcml0aG0pCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nW10ga2V5VHlwZXMgPSBrZXlUeXBlcyhhbGdvcml0aG0pOworICAgICAgICBmb3IgKFN0cmluZyBrZXlUeXBlIDoga2V5VHlwZXMpIHsKKyAgICAgICAgICAgIFN0cmluZ1tdIGFsaWFzZXMgPSBrbS5nZXRDbGllbnRBbGlhc2VzKGtleVR5cGUsIG51bGwpOworICAgICAgICAgICAgaWYgKGVtcHR5IHx8IGtleVR5cGUgPT0gbnVsbCB8fCBrZXlUeXBlLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoa2V5VHlwZSwgYWxpYXNlcyk7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGtleVR5cGUsIGFsaWFzZXMpOworICAgICAgICAgICAgZm9yIChTdHJpbmcgYWxpYXMgOiBhbGlhc2VzKSB7CisgICAgICAgICAgICAgICAgdGVzdF9YNTA5S2V5TWFuYWdlcl9hbGlhcyhrbSwgYWxpYXMsIGtleVR5cGUsIGZhbHNlLCBlbXB0eSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZm9yIChTdHJpbmcga2V5VHlwZSA6IGtleVR5cGVzKSB7CisgICAgICAgICAgICBTdHJpbmdbXSBhbGlhc2VzID0ga20uZ2V0U2VydmVyQWxpYXNlcyhrZXlUeXBlLCBudWxsKTsKKyAgICAgICAgICAgIGlmIChlbXB0eSB8fCBrZXlUeXBlID09IG51bGwgfHwga2V5VHlwZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGtleVR5cGUsIGFsaWFzZXMpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChrZXlUeXBlLCBhbGlhc2VzKTsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIGFsaWFzIDogYWxpYXNlcykgeworICAgICAgICAgICAgICAgIHRlc3RfWDUwOUtleU1hbmFnZXJfYWxpYXMoa20sIGFsaWFzLCBrZXlUeXBlLCBmYWxzZSwgZW1wdHkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGEgPSBrbS5jaG9vc2VDbGllbnRBbGlhcyhrZXlUeXBlcywgbnVsbCwgbnVsbCk7CisgICAgICAgIHRlc3RfWDUwOUtleU1hbmFnZXJfYWxpYXMoa20sIGEsIG51bGwsIHRydWUsIGVtcHR5KTsKKworICAgICAgICBmb3IgKFN0cmluZyBrZXlUeXBlIDoga2V5VHlwZXMpIHsKKyAgICAgICAgICAgIFN0cmluZ1tdIGFycmF5ID0gbmV3IFN0cmluZ1tdIHsga2V5VHlwZSB9OworICAgICAgICAgICAgU3RyaW5nIGFsaWFzID0ga20uY2hvb3NlQ2xpZW50QWxpYXMoYXJyYXksIG51bGwsIG51bGwpOworICAgICAgICAgICAgdGVzdF9YNTA5S2V5TWFuYWdlcl9hbGlhcyhrbSwgYWxpYXMsIGtleVR5cGUsIGZhbHNlLCBlbXB0eSk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChTdHJpbmcga2V5VHlwZSA6IGtleVR5cGVzKSB7CisgICAgICAgICAgICBTdHJpbmcgYWxpYXMgPSBrbS5jaG9vc2VTZXJ2ZXJBbGlhcyhrZXlUeXBlLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgIHRlc3RfWDUwOUtleU1hbmFnZXJfYWxpYXMoa20sIGFsaWFzLCBrZXlUeXBlLCBmYWxzZSwgZW1wdHkpOworICAgICAgICB9CisgICAgICAgIGlmIChrbSBpbnN0YW5jZW9mIFg1MDlFeHRlbmRlZEtleU1hbmFnZXIpIHsKKyAgICAgICAgICAgIHRlc3RfWDUwOUV4dGVuZGVkS2V5TWFuYWdlcigoWDUwOUV4dGVuZGVkS2V5TWFuYWdlcikga20sIGVtcHR5LCBhbGdvcml0aG0pOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RfWDUwOUV4dGVuZGVkS2V5TWFuYWdlcihYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyIGttLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBlbXB0eSwgU3RyaW5nIGFsZ29yaXRobSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIGtleVR5cGVzID0ga2V5VHlwZXMoYWxnb3JpdGhtKTsKKyAgICAgICAgU3RyaW5nIGEgPSBrbS5jaG9vc2VFbmdpbmVDbGllbnRBbGlhcyhrZXlUeXBlcywgbnVsbCwgbnVsbCk7CisgICAgICAgIHRlc3RfWDUwOUtleU1hbmFnZXJfYWxpYXMoa20sIGEsIG51bGwsIHRydWUsIGVtcHR5KTsKKyAgICAgICAgZm9yIChTdHJpbmcga2V5VHlwZSA6IGtleVR5cGVzKSB7CisgICAgICAgICAgICBTdHJpbmdbXSBhcnJheSA9IG5ldyBTdHJpbmdbXSB7IGtleVR5cGUgfTsKKyAgICAgICAgICAgIFN0cmluZyBhbGlhcyA9IGttLmNob29zZUVuZ2luZUNsaWVudEFsaWFzKGFycmF5LCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgIHRlc3RfWDUwOUtleU1hbmFnZXJfYWxpYXMoa20sIGFsaWFzLCBrZXlUeXBlLCBmYWxzZSwgZW1wdHkpOworICAgICAgICB9CisgICAgICAgIGZvciAoU3RyaW5nIGtleVR5cGUgOiBrZXlUeXBlcykgeworICAgICAgICAgICAgU3RyaW5nIGFsaWFzID0ga20uY2hvb3NlRW5naW5lU2VydmVyQWxpYXMoa2V5VHlwZSwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICB0ZXN0X1g1MDlLZXlNYW5hZ2VyX2FsaWFzKGttLCBhbGlhcywga2V5VHlwZSwgZmFsc2UsIGVtcHR5KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0X1g1MDlLZXlNYW5hZ2VyX2FsaWFzKFg1MDlLZXlNYW5hZ2VyIGttLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhbGlhcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcga2V5VHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIG1hbnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBlbXB0eSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChlbXB0eSB8fCAoIW1hbnkgJiYgKGtleVR5cGUgPT0gbnVsbCB8fCBrZXlUeXBlLmlzRW1wdHkoKSkpKSB7CisgICAgICAgICAgICBhc3NlcnROdWxsKGtleVR5cGUsIGFsaWFzKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoa2V5VHlwZSwga20uZ2V0Q2VydGlmaWNhdGVDaGFpbihhbGlhcykpOworICAgICAgICAgICAgYXNzZXJ0TnVsbChrZXlUeXBlLCBrbS5nZXRQcml2YXRlS2V5KGFsaWFzKSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbChrZXlUeXBlLCBhbGlhcyk7CisKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlW10gY2VydGlmaWNhdGVDaGFpbiA9IGttLmdldENlcnRpZmljYXRlQ2hhaW4oYWxpYXMpOworICAgICAgICBQcml2YXRlS2V5IHByaXZhdGVLZXkgPSBrbS5nZXRQcml2YXRlS2V5KGFsaWFzKTsKKworICAgICAgICBTdHJpbmcga2V5QWxnTmFtZTsKKyAgICAgICAgU3RyaW5nIHNpZ0FsZ05hbWU7CisgICAgICAgIGlmIChrZXlUeXBlID09IG51bGwpIHsKKyAgICAgICAgICAgIGtleUFsZ05hbWUgPSBwcml2YXRlS2V5LmdldEFsZ29yaXRobSgpOworICAgICAgICAgICAgc2lnQWxnTmFtZSA9IGtleUFsZ05hbWU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBwb3RlbnRpYWxseSBoYW5kbGUgRUNfRUMgb3IgRUNfUlNBCisgICAgICAgICAgICBrZXlBbGdOYW1lID0gVGVzdEtleVN0b3JlLmtleUFsZ29yaXRobShrZXlUeXBlKTsKKyAgICAgICAgICAgIHNpZ0FsZ05hbWUgPSBUZXN0S2V5U3RvcmUuc2lnbmF0dXJlQWxnb3JpdGhtKGtleVR5cGUpOworICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlIGNlcnRpZmljYXRlID0gY2VydGlmaWNhdGVDaGFpblswXTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhrZXlUeXBlLCBrZXlBbGdOYW1lLCBjZXJ0aWZpY2F0ZS5nZXRQdWJsaWNLZXkoKS5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoa2V5VHlwZSwga2V5QWxnTmFtZSwgcHJpdmF0ZUtleS5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgICAgICAvLyBza2lwIHRoaXMgZm9yIEVDIHdoaWNoIGNvdWxkIHJldHVybiBFQ19SU0EgY2FzZSBpbnN0ZWFkIG9mIEVDX0VDCisgICAgICAgICAgICBpZiAoIWtleVR5cGUuZXF1YWxzKCJFQyIpKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIGV4cGVjdGVkU2lnQWxnTmFtZSA9IHNpZ0FsZ05hbWUudG9VcHBlckNhc2UoKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcgYWN0dWFsU2lnQWxnTmFtZSA9IGNlcnRpZmljYXRlLmdldFNpZ0FsZ05hbWUoKS50b1VwcGVyQ2FzZSgpOworICAgICAgICAgICAgICAgIFN0cmluZyBleHBlY3RlZCA9IGFjdHVhbFNpZ0FsZ05hbWUgKyAiIGNvbnRhaW5zICIgKyBleHBlY3RlZFNpZ0FsZ05hbWU7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShleHBlY3RlZCwgYWN0dWFsU2lnQWxnTmFtZS5jb250YWlucyhleHBlY3RlZFNpZ0FsZ05hbWUpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFByaXZhdGVLZXlFbnRyeSBwcml2YXRlS2V5RW50cnkgPSBnZXRUZXN0S2V5U3RvcmUoKS5nZXRQcml2YXRlS2V5KGtleUFsZ05hbWUsIHNpZ0FsZ05hbWUpOworICAgICAgICBpZiAoISJFQyIuZXF1YWxzKGtleUFsZ05hbWUpKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoa2V5VHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheXMuPENlcnRpZmljYXRlPmFzTGlzdChwcml2YXRlS2V5RW50cnkuZ2V0Q2VydGlmaWNhdGVDaGFpbigpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheXMuPENlcnRpZmljYXRlPmFzTGlzdChjZXJ0aWZpY2F0ZUNoYWluKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoa2V5VHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlS2V5RW50cnkuZ2V0UHJpdmF0ZUtleSgpLCBwcml2YXRlS2V5KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfS2V5TWFuYWdlckZhY3RvcnlfZ2V0SW5zdGFuY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvdmlkZXJbXSBwcm92aWRlcnMgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoKTsKKyAgICAgICAgZm9yIChQcm92aWRlciBwcm92aWRlciA6IHByb3ZpZGVycykgeworICAgICAgICAgICAgU2V0PFByb3ZpZGVyLlNlcnZpY2U+IHNlcnZpY2VzID0gcHJvdmlkZXIuZ2V0U2VydmljZXMoKTsKKyAgICAgICAgICAgIGZvciAoUHJvdmlkZXIuU2VydmljZSBzZXJ2aWNlIDogc2VydmljZXMpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgdHlwZSA9IHNlcnZpY2UuZ2V0VHlwZSgpOworICAgICAgICAgICAgICAgIGlmICghdHlwZS5lcXVhbHMoIktleU1hbmFnZXJGYWN0b3J5IikpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIFN0cmluZyBhbGdvcml0aG0gPSBzZXJ2aWNlLmdldEFsZ29yaXRobSgpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIEtleU1hbmFnZXJGYWN0b3J5IGttZiA9IEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYWxnb3JpdGhtLCBrbWYuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgdGVzdF9LZXlNYW5hZ2VyRmFjdG9yeShrbWYpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3Rvcnkga21mID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXIpOworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFsZ29yaXRobSwga21mLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhwcm92aWRlciwga21mLmdldFByb3ZpZGVyKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgdGVzdF9LZXlNYW5hZ2VyRmFjdG9yeShrbWYpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3Rvcnkga21mID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhhbGdvcml0aG0sIGttZi5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMocHJvdmlkZXIsIGttZi5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRlc3RfS2V5TWFuYWdlckZhY3Rvcnkoa21mKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlByb2JsZW0gd2l0aCBhbGdvcml0aG0gIiArIGFsZ29yaXRobSwgZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvbmV0L3NzbC9LZXlTdG9yZUJ1aWxkZXJQYXJhbWV0ZXJzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvbmV0L3NzbC9LZXlTdG9yZUJ1aWxkZXJQYXJhbWV0ZXJzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjViOGY2ZTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL0tleVN0b3JlQnVpbGRlclBhcmFtZXRlcnNUZXN0LmphdmEKQEAgLTAsMCArMSw4MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZS5CdWlsZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5U3RvcmVCdWlsZGVyUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuVGVzdEtleVN0b3JlOworCitwdWJsaWMgY2xhc3MgS2V5U3RvcmVCdWlsZGVyUGFyYW1ldGVyc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdF9pbml0X0J1aWxkZXJfbnVsbCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBLZXlTdG9yZUJ1aWxkZXJQYXJhbWV0ZXJzKChCdWlsZGVyKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5pdF9CdWlsZGVyKCkgeworICAgICAgICBUZXN0S2V5U3RvcmUgdGVzdEtleVN0b3JlID0gVGVzdEtleVN0b3JlLmdldENsaWVudCgpOworICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBCdWlsZGVyLm5ld0luc3RhbmNlKHRlc3RLZXlTdG9yZS5rZXlTdG9yZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUGFzc3dvcmRQcm90ZWN0aW9uKHRlc3RLZXlTdG9yZS5zdG9yZVBhc3N3b3JkKSk7CisgICAgICAgIEtleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMga3NicCA9IG5ldyBLZXlTdG9yZUJ1aWxkZXJQYXJhbWV0ZXJzKGJ1aWxkZXIpOworICAgICAgICBhc3NlcnROb3ROdWxsKGtzYnApOworICAgICAgICBhc3NlcnROb3ROdWxsKGtzYnAuZ2V0UGFyYW1ldGVycygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGtzYnAuZ2V0UGFyYW1ldGVycygpLnNpemUoKSk7CisgICAgICAgIGFzc2VydFNhbWUoYnVpbGRlciwga3NicC5nZXRQYXJhbWV0ZXJzKCkuZ2V0KDApKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luaXRfTGlzdF9udWxsKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEtleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMoKExpc3QpIG51bGwpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pbml0X0xpc3QoKSB7CisgICAgICAgIFRlc3RLZXlTdG9yZSB0ZXN0S2V5U3RvcmUxID0gVGVzdEtleVN0b3JlLmdldENsaWVudCgpOworICAgICAgICBUZXN0S2V5U3RvcmUgdGVzdEtleVN0b3JlMiA9IFRlc3RLZXlTdG9yZS5nZXRTZXJ2ZXIoKTsKKyAgICAgICAgQnVpbGRlciBidWlsZGVyMSA9IEJ1aWxkZXIubmV3SW5zdGFuY2UodGVzdEtleVN0b3JlMS5rZXlTdG9yZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFBhc3N3b3JkUHJvdGVjdGlvbih0ZXN0S2V5U3RvcmUxLnN0b3JlUGFzc3dvcmQpKTsKKyAgICAgICAgQnVpbGRlciBidWlsZGVyMiA9IEJ1aWxkZXIubmV3SW5zdGFuY2UodGVzdEtleVN0b3JlMi5rZXlTdG9yZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFBhc3N3b3JkUHJvdGVjdGlvbih0ZXN0S2V5U3RvcmUyLnN0b3JlUGFzc3dvcmQpKTsKKworICAgICAgICBMaXN0IGxpc3QgPSBBcnJheXMuYXNMaXN0KGJ1aWxkZXIxLCBidWlsZGVyMik7CisgICAgICAgIEtleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMga3NicCA9IG5ldyBLZXlTdG9yZUJ1aWxkZXJQYXJhbWV0ZXJzKGxpc3QpOworICAgICAgICBhc3NlcnROb3ROdWxsKGtzYnApOworICAgICAgICBhc3NlcnROb3ROdWxsKGtzYnAuZ2V0UGFyYW1ldGVycygpKTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShsaXN0LCBrc2JwLmdldFBhcmFtZXRlcnMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBrc2JwLmdldFBhcmFtZXRlcnMoKS5zaXplKCkpOworICAgICAgICBhc3NlcnRTYW1lKGJ1aWxkZXIxLCBrc2JwLmdldFBhcmFtZXRlcnMoKS5nZXQoMCkpOworICAgICAgICBhc3NlcnRTYW1lKGJ1aWxkZXIyLCBrc2JwLmdldFBhcmFtZXRlcnMoKS5nZXQoMSkpOworCisgICAgICAgIC8vIGNvbmZpcm0gcmVzdWx0IGlzIG5vdCBtb2RpZmlhYmxlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrc2JwLmdldFBhcmFtZXRlcnMoKS5zZXQoMCwgYnVpbGRlcjIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gY29uZmlybSByZXN1bHQgaXMgYSBjb3B5IG9mIG9yaWdpbmFsCisgICAgICAgIGxpc3Quc2V0KDAsIGJ1aWxkZXIyKTsKKyAgICAgICAgYXNzZXJ0U2FtZShidWlsZGVyMSwga3NicC5nZXRQYXJhbWV0ZXJzKCkuZ2V0KDApKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL1NTTENvbnRleHRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL1NTTENvbnRleHRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTAwZDk1MAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvU1NMQ29udGV4dFRlc3QuamF2YQpAQCAtMCwwICsxLDMxMiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlNYW5hZ2VtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgbGliY29yZS5qYXZhLnNlY3VyaXR5LlN0YW5kYXJkTmFtZXM7CitpbXBvcnQgamF2YXgubmV0LlNlcnZlclNvY2tldEZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LlNvY2tldEZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xDb250ZXh0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldEZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uQ29udGV4dDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3Rvcnk7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgU1NMQ29udGV4dFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTENvbnRleHRfZ2V0RGVmYXVsdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTU0xDb250ZXh0IHNzbENvbnRleHQgPSBTU0xDb250ZXh0LmdldERlZmF1bHQoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzc2xDb250ZXh0KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzbENvbnRleHQuaW5pdChudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xDb250ZXh0X3NldERlZmF1bHQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNTTENvbnRleHQuc2V0RGVmYXVsdChudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIFNTTENvbnRleHQgZGVmYXVsdENvbnRleHQgPSBTU0xDb250ZXh0LmdldERlZmF1bHQoKTsKKyAgICAgICAgZm9yIChTdHJpbmcgcHJvdG9jb2wgOiBTdGFuZGFyZE5hbWVzLlNTTF9DT05URVhUX1BST1RPQ09MUykgeworICAgICAgICAgICAgU1NMQ29udGV4dCBvbGRDb250ZXh0ID0gU1NMQ29udGV4dC5nZXREZWZhdWx0KCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG9sZENvbnRleHQpOworICAgICAgICAgICAgU1NMQ29udGV4dCBuZXdDb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZShwcm90b2NvbCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG5ld0NvbnRleHQpOworICAgICAgICAgICAgYXNzZXJ0Tm90U2FtZShvbGRDb250ZXh0LCBuZXdDb250ZXh0KTsKKyAgICAgICAgICAgIFNTTENvbnRleHQuc2V0RGVmYXVsdChuZXdDb250ZXh0KTsKKyAgICAgICAgICAgIGFzc2VydFNhbWUobmV3Q29udGV4dCwgU1NMQ29udGV4dC5nZXREZWZhdWx0KCkpOworICAgICAgICB9CisgICAgICAgIFNTTENvbnRleHQuc2V0RGVmYXVsdChkZWZhdWx0Q29udGV4dCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xDb250ZXh0X2dldEluc3RhbmNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTU0xDb250ZXh0LmdldEluc3RhbmNlKG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGZvciAoU3RyaW5nIHByb3RvY29sIDogU3RhbmRhcmROYW1lcy5TU0xfQ09OVEVYVF9QUk9UT0NPTFMpIHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoU1NMQ29udGV4dC5nZXRJbnN0YW5jZShwcm90b2NvbCkpOworICAgICAgICAgICAgYXNzZXJ0Tm90U2FtZShTU0xDb250ZXh0LmdldEluc3RhbmNlKHByb3RvY29sKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMQ29udGV4dC5nZXRJbnN0YW5jZShwcm90b2NvbCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNTTENvbnRleHQuZ2V0SW5zdGFuY2UobnVsbCwgKFN0cmluZykgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTU0xDb250ZXh0LmdldEluc3RhbmNlKG51bGwsICIiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChTdHJpbmcgcHJvdG9jb2wgOiBTdGFuZGFyZE5hbWVzLlNTTF9DT05URVhUX1BST1RPQ09MUykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTU0xDb250ZXh0LmdldEluc3RhbmNlKHByb3RvY29sLCAoU3RyaW5nKSBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMQ29udGV4dC5nZXRJbnN0YW5jZShudWxsLCBTdGFuZGFyZE5hbWVzLkpTU0VfUFJPVklERVJfTkFNRSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTENvbnRleHRfZ2V0UHJvdG9jb2woKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChTdHJpbmcgcHJvdG9jb2wgOiBTdGFuZGFyZE5hbWVzLlNTTF9DT05URVhUX1BST1RPQ09MUykgeworICAgICAgICAgICAgU3RyaW5nIHByb3RvY29sTmFtZSA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UocHJvdG9jb2wpLmdldFByb3RvY29sKCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3RvY29sTmFtZSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHByb3RvY29sLnN0YXJ0c1dpdGgocHJvdG9jb2xOYW1lKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTENvbnRleHRfZ2V0UHJvdmlkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIgPSBTU0xDb250ZXh0LmdldERlZmF1bHQoKS5nZXRQcm92aWRlcigpOworICAgICAgICBhc3NlcnROb3ROdWxsKHByb3ZpZGVyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFN0YW5kYXJkTmFtZXMuSlNTRV9QUk9WSURFUl9OQU1FLCBwcm92aWRlci5nZXROYW1lKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMQ29udGV4dF9pbml0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoU3RyaW5nIHByb3RvY29sIDogU3RhbmRhcmROYW1lcy5TU0xfQ09OVEVYVF9QUk9UT0NPTFMpIHsKKyAgICAgICAgICAgIFNTTENvbnRleHQgc3NsQ29udGV4dCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UocHJvdG9jb2wpOworICAgICAgICAgICAgaWYgKHByb3RvY29sLmVxdWFscyhTdGFuZGFyZE5hbWVzLlNTTF9DT05URVhUX1BST1RPQ09MU19ERUZBVUxUKSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHNzbENvbnRleHQuaW5pdChudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzc2xDb250ZXh0LmluaXQobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTENvbnRleHRfZ2V0U29ja2V0RmFjdG9yeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKFN0cmluZyBwcm90b2NvbCA6IFN0YW5kYXJkTmFtZXMuU1NMX0NPTlRFWFRfUFJPVE9DT0xTKSB7CisgICAgICAgICAgICBpZiAocHJvdG9jb2wuZXF1YWxzKFN0YW5kYXJkTmFtZXMuU1NMX0NPTlRFWFRfUFJPVE9DT0xTX0RFRkFVTFQpKSB7CisgICAgICAgICAgICAgICAgU1NMQ29udGV4dC5nZXRJbnN0YW5jZShwcm90b2NvbCkuZ2V0U29ja2V0RmFjdG9yeSgpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBTU0xDb250ZXh0LmdldEluc3RhbmNlKHByb3RvY29sKS5nZXRTb2NrZXRGYWN0b3J5KCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFNTTENvbnRleHQgc3NsQ29udGV4dCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UocHJvdG9jb2wpOworICAgICAgICAgICAgaWYgKCFwcm90b2NvbC5lcXVhbHMoU3RhbmRhcmROYW1lcy5TU0xfQ09OVEVYVF9QUk9UT0NPTFNfREVGQVVMVCkpIHsKKyAgICAgICAgICAgICAgICBzc2xDb250ZXh0LmluaXQobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTb2NrZXRGYWN0b3J5IHNmID0gc3NsQ29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHNmKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoU1NMU29ja2V0RmFjdG9yeS5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKHNmLmdldENsYXNzKCkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMQ29udGV4dF9nZXRTZXJ2ZXJTb2NrZXRGYWN0b3J5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoU3RyaW5nIHByb3RvY29sIDogU3RhbmRhcmROYW1lcy5TU0xfQ09OVEVYVF9QUk9UT0NPTFMpIHsKKyAgICAgICAgICAgIGlmIChwcm90b2NvbC5lcXVhbHMoU3RhbmRhcmROYW1lcy5TU0xfQ09OVEVYVF9QUk9UT0NPTFNfREVGQVVMVCkpIHsKKyAgICAgICAgICAgICAgICBTU0xDb250ZXh0LmdldEluc3RhbmNlKHByb3RvY29sKS5nZXRTZXJ2ZXJTb2NrZXRGYWN0b3J5KCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFNTTENvbnRleHQuZ2V0SW5zdGFuY2UocHJvdG9jb2wpLmdldFNlcnZlclNvY2tldEZhY3RvcnkoKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU1NMQ29udGV4dCBzc2xDb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZShwcm90b2NvbCk7CisgICAgICAgICAgICBpZiAoIXByb3RvY29sLmVxdWFscyhTdGFuZGFyZE5hbWVzLlNTTF9DT05URVhUX1BST1RPQ09MU19ERUZBVUxUKSkgeworICAgICAgICAgICAgICAgIHNzbENvbnRleHQuaW5pdChudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFNlcnZlclNvY2tldEZhY3Rvcnkgc3NmID0gc3NsQ29udGV4dC5nZXRTZXJ2ZXJTb2NrZXRGYWN0b3J5KCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHNzZik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKFNTTFNlcnZlclNvY2tldEZhY3RvcnkuY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShzc2YuZ2V0Q2xhc3MoKSkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xDb250ZXh0X2NyZWF0ZVNTTEVuZ2luZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKFN0cmluZyBwcm90b2NvbCA6IFN0YW5kYXJkTmFtZXMuU1NMX0NPTlRFWFRfUFJPVE9DT0xTKSB7CisKKyAgICAgICAgICAgIGlmIChwcm90b2NvbC5lcXVhbHMoU3RhbmRhcmROYW1lcy5TU0xfQ09OVEVYVF9QUk9UT0NPTFNfREVGQVVMVCkpIHsKKyAgICAgICAgICAgICAgICBTU0xDb250ZXh0LmdldEluc3RhbmNlKHByb3RvY29sKS5jcmVhdGVTU0xFbmdpbmUoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU1NMQ29udGV4dC5nZXRJbnN0YW5jZShwcm90b2NvbCkuY3JlYXRlU1NMRW5naW5lKCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChwcm90b2NvbC5lcXVhbHMoU3RhbmRhcmROYW1lcy5TU0xfQ09OVEVYVF9QUk9UT0NPTFNfREVGQVVMVCkpIHsKKyAgICAgICAgICAgICAgICBTU0xDb250ZXh0LmdldEluc3RhbmNlKHByb3RvY29sKS5jcmVhdGVTU0xFbmdpbmUobnVsbCwgLTEpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBTU0xDb250ZXh0LmdldEluc3RhbmNlKHByb3RvY29sKS5jcmVhdGVTU0xFbmdpbmUobnVsbCwgLTEpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgU1NMQ29udGV4dCBzc2xDb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZShwcm90b2NvbCk7CisgICAgICAgICAgICAgICAgaWYgKCFwcm90b2NvbC5lcXVhbHMoU3RhbmRhcmROYW1lcy5TU0xfQ09OVEVYVF9QUk9UT0NPTFNfREVGQVVMVCkpIHsKKyAgICAgICAgICAgICAgICAgICAgc3NsQ29udGV4dC5pbml0KG51bGwsIG51bGwsIG51bGwpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBTU0xFbmdpbmUgc2UgPSBzc2xDb250ZXh0LmNyZWF0ZVNTTEVuZ2luZSgpOworICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc2UpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgU1NMQ29udGV4dCBzc2xDb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZShwcm90b2NvbCk7CisgICAgICAgICAgICAgICAgaWYgKCFwcm90b2NvbC5lcXVhbHMoU3RhbmRhcmROYW1lcy5TU0xfQ09OVEVYVF9QUk9UT0NPTFNfREVGQVVMVCkpIHsKKyAgICAgICAgICAgICAgICAgICAgc3NsQ29udGV4dC5pbml0KG51bGwsIG51bGwsIG51bGwpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBTU0xFbmdpbmUgc2UgPSBzc2xDb250ZXh0LmNyZWF0ZVNTTEVuZ2luZShudWxsLCAtMSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChzZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTENvbnRleHRfZ2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChTdHJpbmcgcHJvdG9jb2wgOiBTdGFuZGFyZE5hbWVzLlNTTF9DT05URVhUX1BST1RPQ09MUykgeworICAgICAgICAgICAgU1NMQ29udGV4dCBzc2xDb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZShwcm90b2NvbCk7CisgICAgICAgICAgICBTU0xTZXNzaW9uQ29udGV4dCBzZXNzaW9uQ29udGV4dCA9IHNzbENvbnRleHQuZ2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc2Vzc2lvbkNvbnRleHQpOworCisgICAgICAgICAgICBpZiAoIVN0YW5kYXJkTmFtZXMuSVNfUkkgJiYKKyAgICAgICAgICAgICAgICAgICAgcHJvdG9jb2wuZXF1YWxzKFN0YW5kYXJkTmFtZXMuU1NMX0NPTlRFWFRfUFJPVE9DT0xTX0RFRkFVTFQpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0U2FtZShTU0xDb250ZXh0LmdldEluc3RhbmNlKHByb3RvY29sKS5nZXRTZXJ2ZXJTZXNzaW9uQ29udGV4dCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbkNvbnRleHQpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3RTYW1lKFNTTENvbnRleHQuZ2V0SW5zdGFuY2UocHJvdG9jb2wpLmdldFNlcnZlclNlc3Npb25Db250ZXh0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uQ29udGV4dCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTENvbnRleHRfZ2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChTdHJpbmcgcHJvdG9jb2wgOiBTdGFuZGFyZE5hbWVzLlNTTF9DT05URVhUX1BST1RPQ09MUykgeworICAgICAgICAgICAgU1NMQ29udGV4dCBzc2xDb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZShwcm90b2NvbCk7CisgICAgICAgICAgICBTU0xTZXNzaW9uQ29udGV4dCBzZXNzaW9uQ29udGV4dCA9IHNzbENvbnRleHQuZ2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc2Vzc2lvbkNvbnRleHQpOworCisgICAgICAgICAgICBpZiAoIVN0YW5kYXJkTmFtZXMuSVNfUkkgJiYKKyAgICAgICAgICAgICAgICAgICAgcHJvdG9jb2wuZXF1YWxzKFN0YW5kYXJkTmFtZXMuU1NMX0NPTlRFWFRfUFJPVE9DT0xTX0RFRkFVTFQpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0U2FtZShTU0xDb250ZXh0LmdldEluc3RhbmNlKHByb3RvY29sKS5nZXRDbGllbnRTZXNzaW9uQ29udGV4dCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbkNvbnRleHQpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3RTYW1lKFNTTENvbnRleHQuZ2V0SW5zdGFuY2UocHJvdG9jb2wpLmdldENsaWVudFNlc3Npb25Db250ZXh0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uQ29udGV4dCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTENvbnRleHRfZ2V0RGVmYXVsdFNTTFBhcmFtZXRlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChTdHJpbmcgcHJvdG9jb2wgOiBTdGFuZGFyZE5hbWVzLlNTTF9DT05URVhUX1BST1RPQ09MUykgeworICAgICAgICAgICAgU1NMQ29udGV4dCBzc2xDb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZShwcm90b2NvbCk7CisgICAgICAgICAgICBpZiAoIXByb3RvY29sLmVxdWFscyhTdGFuZGFyZE5hbWVzLlNTTF9DT05URVhUX1BST1RPQ09MU19ERUZBVUxUKSkgeworICAgICAgICAgICAgICAgIHNzbENvbnRleHQuaW5pdChudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU1NMUGFyYW1ldGVycyBwID0gc3NsQ29udGV4dC5nZXREZWZhdWx0U1NMUGFyYW1ldGVycygpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwKTsKKworICAgICAgICAgICAgU3RyaW5nW10gY2lwaGVyU3VpdGVzID0gcC5nZXRDaXBoZXJTdWl0ZXMoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoY2lwaGVyU3VpdGVzKTsKKyAgICAgICAgICAgIFN0YW5kYXJkTmFtZXMuYXNzZXJ0VmFsaWRDaXBoZXJTdWl0ZXMoU3RhbmRhcmROYW1lcy5DSVBIRVJfU1VJVEVTLCBjaXBoZXJTdWl0ZXMpOworCisgICAgICAgICAgICBTdHJpbmdbXSBwcm90b2NvbHMgPSBwLmdldFByb3RvY29scygpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwcm90b2NvbHMpOworICAgICAgICAgICAgU3RhbmRhcmROYW1lcy5hc3NlcnRWYWxpZENpcGhlclN1aXRlcyhTdGFuZGFyZE5hbWVzLlNTTF9TT0NLRVRfUFJPVE9DT0xTLCBwcm90b2NvbHMpOworCisgICAgICAgICAgICBhc3NlcnRGYWxzZShwLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UocC5nZXROZWVkQ2xpZW50QXV0aCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMQ29udGV4dF9nZXRTdXBwb3J0ZWRTU0xQYXJhbWV0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoU3RyaW5nIHByb3RvY29sIDogU3RhbmRhcmROYW1lcy5TU0xfQ09OVEVYVF9QUk9UT0NPTFMpIHsKKyAgICAgICAgICAgIFNTTENvbnRleHQgc3NsQ29udGV4dCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UocHJvdG9jb2wpOworICAgICAgICAgICAgaWYgKCFwcm90b2NvbC5lcXVhbHMoU3RhbmRhcmROYW1lcy5TU0xfQ09OVEVYVF9QUk9UT0NPTFNfREVGQVVMVCkpIHsKKyAgICAgICAgICAgICAgICBzc2xDb250ZXh0LmluaXQobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFNTTFBhcmFtZXRlcnMgcCA9IHNzbENvbnRleHQuZ2V0U3VwcG9ydGVkU1NMUGFyYW1ldGVycygpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwKTsKKworICAgICAgICAgICAgU3RyaW5nW10gY2lwaGVyU3VpdGVzID0gcC5nZXRDaXBoZXJTdWl0ZXMoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoY2lwaGVyU3VpdGVzKTsKKyAgICAgICAgICAgIFN0YW5kYXJkTmFtZXMuYXNzZXJ0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKFN0YW5kYXJkTmFtZXMuQ0lQSEVSX1NVSVRFUywgY2lwaGVyU3VpdGVzKTsKKworICAgICAgICAgICAgU3RyaW5nW10gcHJvdG9jb2xzID0gcC5nZXRQcm90b2NvbHMoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHJvdG9jb2xzKTsKKyAgICAgICAgICAgIFN0YW5kYXJkTmFtZXMuYXNzZXJ0U3VwcG9ydGVkUHJvdG9jb2xzKFN0YW5kYXJkTmFtZXMuU1NMX1NPQ0tFVF9QUk9UT0NPTFMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90b2NvbHMpOworCisgICAgICAgICAgICBhc3NlcnRGYWxzZShwLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UocC5nZXROZWVkQ2xpZW50QXV0aCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMQ29udGV4dFRlc3RfVGVzdFNTTENvbnRleHRfY3JlYXRlKCkgeworICAgICAgICBUZXN0U1NMQ29udGV4dCB0ZXN0Q29udGV4dCA9IFRlc3RTU0xDb250ZXh0LmNyZWF0ZSgpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRlc3RDb250ZXh0KTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0ZXN0Q29udGV4dC5jbGllbnRLZXlTdG9yZSk7CisgICAgICAgIGFzc2VydE51bGwodGVzdENvbnRleHQuY2xpZW50U3RvcmVQYXNzd29yZCk7CisgICAgICAgIGFzc2VydE5vdE51bGwodGVzdENvbnRleHQuc2VydmVyS2V5U3RvcmUpOworICAgICAgICBhc3NlcnRFcXVhbHMoU3RhbmRhcmROYW1lcy5JU19SSSwgdGVzdENvbnRleHQuc2VydmVyU3RvcmVQYXNzd29yZCAhPSBudWxsKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0ZXN0Q29udGV4dC5jbGllbnRLZXlNYW5hZ2VyKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0ZXN0Q29udGV4dC5zZXJ2ZXJLZXlNYW5hZ2VyKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0ZXN0Q29udGV4dC5jbGllbnRUcnVzdE1hbmFnZXIpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRlc3RDb250ZXh0LnNlcnZlclRydXN0TWFuYWdlcik7CisgICAgICAgIGFzc2VydE5vdE51bGwodGVzdENvbnRleHQuY2xpZW50Q29udGV4dCk7CisgICAgICAgIGFzc2VydE5vdE51bGwodGVzdENvbnRleHQuc2VydmVyQ29udGV4dCk7CisgICAgICAgIGFzc2VydE5vdE51bGwodGVzdENvbnRleHQuc2VydmVyU29ja2V0KTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0ZXN0Q29udGV4dC5ob3N0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0ZXN0Q29udGV4dC5wb3J0ICE9IDApOworICAgICAgICB0ZXN0Q29udGV4dC5jbG9zZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvU1NMRW5naW5lVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvbmV0L3NzbC9TU0xFbmdpbmVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWU5MWRjMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvU1NMRW5naW5lVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDYyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMQ29udGV4dDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXM7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xIYW5kc2hha2VFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xQYXJhbWV0ZXJzOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgbGliY29yZS5qYXZhLnNlY3VyaXR5LlN0YW5kYXJkTmFtZXM7CitpbXBvcnQgbGliY29yZS5qYXZhLnNlY3VyaXR5LlRlc3RLZXlTdG9yZTsKKworcHVibGljIGNsYXNzIFNTTEVuZ2luZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCBhc3NlcnRDb25uZWN0ZWQoVGVzdFNTTEVuZ2luZVBhaXIgZSkgeworICAgICAgICBhc3NlcnRDb25uZWN0ZWQoZS5jbGllbnQsIGUuc2VydmVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhc3NlcnROb3RDb25uZWN0ZWQoVGVzdFNTTEVuZ2luZVBhaXIgZSkgeworICAgICAgICBhc3NlcnROb3RDb25uZWN0ZWQoZS5jbGllbnQsIGUuc2VydmVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhc3NlcnRDb25uZWN0ZWQoU1NMRW5naW5lIGEsIFNTTEVuZ2luZSBiKSB7CisgICAgICAgIGFzc2VydFRydWUoY29ubmVjdGVkKGEsIGIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhc3NlcnROb3RDb25uZWN0ZWQoU1NMRW5naW5lIGEsIFNTTEVuZ2luZSBiKSB7CisgICAgICAgIGFzc2VydEZhbHNlKGNvbm5lY3RlZChhLCBiKSk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gY29ubmVjdGVkKFNTTEVuZ2luZSBhLCBTU0xFbmdpbmUgYikgeworICAgICAgICByZXR1cm4gKGEuZ2V0SGFuZHNoYWtlU3RhdHVzKCkgPT0gSGFuZHNoYWtlU3RhdHVzLk5PVF9IQU5EU0hBS0lORworICAgICAgICAgICAgICAgICYmIGIuZ2V0SGFuZHNoYWtlU3RhdHVzKCkgPT0gSGFuZHNoYWtlU3RhdHVzLk5PVF9IQU5EU0hBS0lORworICAgICAgICAgICAgICAgICYmIGEuZ2V0U2Vzc2lvbigpICE9IG51bGwKKyAgICAgICAgICAgICAgICAmJiBiLmdldFNlc3Npb24oKSAhPSBudWxsCisgICAgICAgICAgICAgICAgJiYgIWEuaXNJbmJvdW5kRG9uZSgpCisgICAgICAgICAgICAgICAgJiYgIWIuaXNJbmJvdW5kRG9uZSgpCisgICAgICAgICAgICAgICAgJiYgIWEuaXNPdXRib3VuZERvbmUoKQorICAgICAgICAgICAgICAgICYmICFiLmlzT3V0Ym91bmREb25lKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMRW5naW5lX2dldFN1cHBvcnRlZENpcGhlclN1aXRlc19uYW1lcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMQ29udGV4dCBjID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIFNTTEVuZ2luZSBlID0gYy5jbGllbnRDb250ZXh0LmNyZWF0ZVNTTEVuZ2luZSgpOworICAgICAgICBTdHJpbmdbXSBjaXBoZXJTdWl0ZXMgPSBlLmdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpOworICAgICAgICBTdGFuZGFyZE5hbWVzLmFzc2VydFN1cHBvcnRlZENpcGhlclN1aXRlcyhTdGFuZGFyZE5hbWVzLkNJUEhFUl9TVUlURVNfU1NMRU5HSU5FLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaXBoZXJTdWl0ZXMpOworICAgICAgICBhc3NlcnROb3RTYW1lKGNpcGhlclN1aXRlcywgZS5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSk7CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTEVuZ2luZV9nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXNfY29ubmVjdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBub3RlIHRoZSByYXJlIHVzYWdlIG9mIG5vbi1SU0Ega2V5cworICAgICAgICBUZXN0S2V5U3RvcmUgdGVzdEtleVN0b3JlID0gbmV3IFRlc3RLZXlTdG9yZS5CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAua2V5QWxnb3JpdGhtcygiUlNBIiwgIkRTQSIsICJFQyIsICJFQ19SU0EiKQorICAgICAgICAgICAgICAgIC5hbGlhc1ByZWZpeCgicnNhLWRzYS1lYyIpCisgICAgICAgICAgICAgICAgLmNhKHRydWUpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgICAgIHRlc3RfU1NMRW5naW5lX2dldFN1cHBvcnRlZENpcGhlclN1aXRlc19jb25uZWN0KHRlc3RLZXlTdG9yZSwgZmFsc2UpOworICAgICAgICBpZiAoU3RhbmRhcmROYW1lcy5JU19SSSkgeworICAgICAgICAgICAgdGVzdF9TU0xFbmdpbmVfZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzX2Nvbm5lY3QodGVzdEtleVN0b3JlLCB0cnVlKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwcml2YXRlIHZvaWQgdGVzdF9TU0xFbmdpbmVfZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzX2Nvbm5lY3QoVGVzdEtleVN0b3JlIHRlc3RLZXlTdG9yZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBzZWN1cmVSZW5lZ290aWF0aW9uKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUodGVzdEtleVN0b3JlLCB0ZXN0S2V5U3RvcmUpOworICAgICAgICBTdHJpbmdbXSBjaXBoZXJTdWl0ZXMgPSBjLmNsaWVudENvbnRleHQuY3JlYXRlU1NMRW5naW5lKCkuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgICAgIGZvciAoU3RyaW5nIGNpcGhlclN1aXRlIDogY2lwaGVyU3VpdGVzKSB7CisgICAgICAgICAgICBib29sZWFuIGVycm9yRXhwZWN0ZWQgPSBTdGFuZGFyZE5hbWVzLklTX1JJICYmIGNpcGhlclN1aXRlLmVuZHNXaXRoKCJfU0hBMjU2Iik7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogVExTX0VNUFRZX1JFTkVHT1RJQVRJT05fSU5GT19TQ1NWIGNhbm5vdCBiZSB1c2VkIG9uCisgICAgICAgICAgICAgICAgICogaXRzIG93biwgYnV0IGluc3RlYWQgaW4gY29uanVuY3Rpb24gd2l0aCBvdGhlcgorICAgICAgICAgICAgICAgICAqIGNpcGhlciBzdWl0ZXMuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgaWYgKGNpcGhlclN1aXRlLmVxdWFscyhTdGFuZGFyZE5hbWVzLkNJUEhFUl9TVUlURV9TRUNVUkVfUkVORUdPVElBVElPTikpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogS2VyYmVyb3MgY2lwaGVyIHN1aXRlcyByZXF1aXJlIGV4dGVybmFsIHNldHVwLiBTZWUgIktlcmJlcm9zIFJlcXVpcmVtZW50cyIgaW4KKyAgICAgICAgICAgICAgICAgKiBodHRwczovL2phdmEuc3VuLmNvbS9qMnNlLzEuNS4wL2RvY3MvZ3VpZGUvc2VjdXJpdHkvanNzZS9KU1NFUmVmR3VpZGUuaHRtbAorICAgICAgICAgICAgICAgICAqICNLUkJSZXF1aXJlCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgaWYgKGNpcGhlclN1aXRlLnN0YXJ0c1dpdGgoIlRMU19LUkI1XyIpKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZ1tdIGNpcGhlclN1aXRlQXJyYXkKKyAgICAgICAgICAgICAgICAgICAgICAgID0gKHNlY3VyZVJlbmVnb3RpYXRpb24KKyAgICAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3IFN0cmluZ1tdIHsgY2lwaGVyU3VpdGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YW5kYXJkTmFtZXMuQ0lQSEVSX1NVSVRFX1NFQ1VSRV9SRU5FR09USUFUSU9OIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbmV3IFN0cmluZ1tdIHsgY2lwaGVyU3VpdGUgfSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0Q29ubmVjdGVkKFRlc3RTU0xFbmdpbmVQYWlyLmNyZWF0ZShjLCBuZXcgVGVzdFNTTEVuZ2luZVBhaXIuSG9va3MoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCBiZWZvcmVCZWdpbkhhbmRzaGFrZShTU0xFbmdpbmUgY2xpZW50LCBTU0xFbmdpbmUgc2VydmVyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50LnNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoY2lwaGVyU3VpdGVBcnJheSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VydmVyLnNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoY2lwaGVyU3VpdGVBcnJheSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0pKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShlcnJvckV4cGVjdGVkKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBtYXliZUV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgaWYgKCFlcnJvckV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlByb2JsZW0gdHJ5aW5nIHRvIGNvbm5lY3QgY2lwaGVyIHN1aXRlICIgKyBjaXBoZXJTdWl0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXliZUV4cGVjdGVkKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMRW5naW5lX2dldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgYyA9IFRlc3RTU0xDb250ZXh0LmNyZWF0ZSgpOworICAgICAgICBTU0xFbmdpbmUgZSA9IGMuY2xpZW50Q29udGV4dC5jcmVhdGVTU0xFbmdpbmUoKTsKKyAgICAgICAgU3RyaW5nW10gY2lwaGVyU3VpdGVzID0gZS5nZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgICAgIFN0YW5kYXJkTmFtZXMuYXNzZXJ0VmFsaWRDaXBoZXJTdWl0ZXMoU3RhbmRhcmROYW1lcy5DSVBIRVJfU1VJVEVTLCBjaXBoZXJTdWl0ZXMpOworICAgICAgICBhc3NlcnROb3RTYW1lKGNpcGhlclN1aXRlcywgZS5nZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCkpOworICAgICAgICBjLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xFbmdpbmVfc2V0RW5hYmxlZENpcGhlclN1aXRlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMQ29udGV4dCBjID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIFNTTEVuZ2luZSBlID0gYy5jbGllbnRDb250ZXh0LmNyZWF0ZVNTTEVuZ2luZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlLnNldEVuYWJsZWRDaXBoZXJTdWl0ZXMobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlLnNldEVuYWJsZWRDaXBoZXJTdWl0ZXMobmV3IFN0cmluZ1sxXSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlLnNldEVuYWJsZWRDaXBoZXJTdWl0ZXMobmV3IFN0cmluZ1tdIHsgIkJvZ3VzIiB9ICk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgZS5zZXRFbmFibGVkQ2lwaGVyU3VpdGVzKG5ldyBTdHJpbmdbMF0pOworICAgICAgICBlLnNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoZS5nZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCkpOworICAgICAgICBlLnNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoZS5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSk7CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTEVuZ2luZV9nZXRTdXBwb3J0ZWRQcm90b2NvbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgYyA9IFRlc3RTU0xDb250ZXh0LmNyZWF0ZSgpOworICAgICAgICBTU0xFbmdpbmUgZSA9IGMuY2xpZW50Q29udGV4dC5jcmVhdGVTU0xFbmdpbmUoKTsKKyAgICAgICAgU3RyaW5nW10gcHJvdG9jb2xzID0gZS5nZXRTdXBwb3J0ZWRQcm90b2NvbHMoKTsKKyAgICAgICAgU3RhbmRhcmROYW1lcy5hc3NlcnRTdXBwb3J0ZWRQcm90b2NvbHMoU3RhbmRhcmROYW1lcy5TU0xfU09DS0VUX1BST1RPQ09MUywgcHJvdG9jb2xzKTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShwcm90b2NvbHMsIGUuZ2V0U3VwcG9ydGVkUHJvdG9jb2xzKCkpOworICAgICAgICBjLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xFbmdpbmVfZ2V0RW5hYmxlZFByb3RvY29scygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMQ29udGV4dCBjID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIFNTTEVuZ2luZSBlID0gYy5jbGllbnRDb250ZXh0LmNyZWF0ZVNTTEVuZ2luZSgpOworICAgICAgICBTdHJpbmdbXSBwcm90b2NvbHMgPSBlLmdldEVuYWJsZWRQcm90b2NvbHMoKTsKKyAgICAgICAgU3RhbmRhcmROYW1lcy5hc3NlcnRWYWxpZFByb3RvY29scyhTdGFuZGFyZE5hbWVzLlNTTF9TT0NLRVRfUFJPVE9DT0xTLCBwcm90b2NvbHMpOworICAgICAgICBhc3NlcnROb3RTYW1lKHByb3RvY29scywgZS5nZXRFbmFibGVkUHJvdG9jb2xzKCkpOworICAgICAgICBjLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xFbmdpbmVfc2V0RW5hYmxlZFByb3RvY29scygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMQ29udGV4dCBjID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIFNTTEVuZ2luZSBlID0gYy5jbGllbnRDb250ZXh0LmNyZWF0ZVNTTEVuZ2luZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlLnNldEVuYWJsZWRQcm90b2NvbHMobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlLnNldEVuYWJsZWRQcm90b2NvbHMobmV3IFN0cmluZ1sxXSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlLnNldEVuYWJsZWRQcm90b2NvbHMobmV3IFN0cmluZ1tdIHsgIkJvZ3VzIiB9ICk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGUuc2V0RW5hYmxlZFByb3RvY29scyhuZXcgU3RyaW5nWzBdKTsKKyAgICAgICAgZS5zZXRFbmFibGVkUHJvdG9jb2xzKGUuZ2V0RW5hYmxlZFByb3RvY29scygpKTsKKyAgICAgICAgZS5zZXRFbmFibGVkUHJvdG9jb2xzKGUuZ2V0U3VwcG9ydGVkUHJvdG9jb2xzKCkpOworICAgICAgICBjLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xFbmdpbmVfZ2V0U2Vzc2lvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMQ29udGV4dCBjID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIFNTTEVuZ2luZSBlID0gYy5jbGllbnRDb250ZXh0LmNyZWF0ZVNTTEVuZ2luZSgpOworICAgICAgICBTU0xTZXNzaW9uIHNlc3Npb24gPSBlLmdldFNlc3Npb24oKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzZXNzaW9uKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2Vzc2lvbi5pc1ZhbGlkKCkpOworICAgICAgICBjLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xFbmdpbmVfYmVnaW5IYW5kc2hha2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgYyA9IFRlc3RTU0xDb250ZXh0LmNyZWF0ZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLmNsaWVudENvbnRleHQuY3JlYXRlU1NMRW5naW5lKCkuYmVnaW5IYW5kc2hha2UoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRDb25uZWN0ZWQoVGVzdFNTTEVuZ2luZVBhaXIuY3JlYXRlKG51bGwpKTsKKworICAgICAgICBjLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xFbmdpbmVfYmVnaW5IYW5kc2hha2Vfbm9LZXlTdG9yZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMQ29udGV4dCBjID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKG51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMQ29udGV4dC5nZXREZWZhdWx0KCksIFNTTENvbnRleHQuZ2V0RGVmYXVsdCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFRPRE8gRml4IEtub3duRmFpbHVyZSBBbGVydEV4Y2VwdGlvbiAiTk8gU0VSVkVSIENFUlRJRklDQVRFIEZPVU5EIgorICAgICAgICAgICAgLy8gU2VydmVySGFuZHNoYWtlSW1wbC5zZWxlY3RTdWl0ZSBzaG91bGQgbm90IHNlbGVjdCBhIHN1aXRlIHdpdGhvdXQgYSByZXF1aXJlZCBjZXJ0CisgICAgICAgICAgICBUZXN0U1NMRW5naW5lUGFpci5jb25uZWN0KGMsIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTU0xIYW5kc2hha2VFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBjLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xFbmdpbmVfYmVnaW5IYW5kc2hha2Vfbm9DbGllbnRDZXJ0aWZpY2F0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMQ29udGV4dCBjID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIFNTTEVuZ2luZVtdIGVuZ2luZXMgPSBUZXN0U1NMRW5naW5lUGFpci5jb25uZWN0KGMsIG51bGwpOworICAgICAgICBhc3NlcnRDb25uZWN0ZWQoZW5naW5lc1swXSwgZW5naW5lc1sxXSk7CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTEVuZ2luZV9nZXRVc2VDbGllbnRNb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoYy5jbGllbnRDb250ZXh0LmNyZWF0ZVNTTEVuZ2luZSgpLmdldFVzZUNsaWVudE1vZGUoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGMuY2xpZW50Q29udGV4dC5jcmVhdGVTU0xFbmdpbmUobnVsbCwgLTEpLmdldFVzZUNsaWVudE1vZGUoKSk7CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTEVuZ2luZV9zZXRVc2VDbGllbnRNb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIGNsaWVudCBpcyBjbGllbnQsIHNlcnZlciBpcyBzZXJ2ZXIKKyAgICAgICAgYXNzZXJ0Q29ubmVjdGVkKHRlc3RfU1NMRW5naW5lX3NldFVzZUNsaWVudE1vZGUodHJ1ZSwgZmFsc2UpKTsKKworICAgICAgICAvLyBjbGllbnQgaXMgc2VydmVyLCBzZXJ2ZXIgaXMgY2xpZW50CisgICAgICAgIGFzc2VydENvbm5lY3RlZCh0ZXN0X1NTTEVuZ2luZV9zZXRVc2VDbGllbnRNb2RlKGZhbHNlLCB0cnVlKSk7CisKKyAgICAgICAgLy8gYm90aCBhcmUgY2xpZW50CisgICAgICAgIGFzc2VydE5vdENvbm5lY3RlZCh0ZXN0X1NTTEVuZ2luZV9zZXRVc2VDbGllbnRNb2RlKHRydWUsIHRydWUpKTsKKworICAgICAgICAvLyBib3RoIGFyZSBzZXJ2ZXIKKyAgICAgICAgYXNzZXJ0Tm90Q29ubmVjdGVkKHRlc3RfU1NMRW5naW5lX3NldFVzZUNsaWVudE1vZGUoZmFsc2UsIGZhbHNlKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xFbmdpbmVfc2V0VXNlQ2xpZW50TW9kZV9hZnRlckhhbmRzaGFrZSgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIC8vIGNhbid0IHNldCBhZnRlciBoYW5kc2hha2UKKyAgICAgICAgVGVzdFNTTEVuZ2luZVBhaXIgcGFpciA9IFRlc3RTU0xFbmdpbmVQYWlyLmNyZWF0ZShudWxsKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhaXIuc2VydmVyLnNldFVzZUNsaWVudE1vZGUoZmFsc2UpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFpci5jbGllbnQuc2V0VXNlQ2xpZW50TW9kZShmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBUZXN0U1NMRW5naW5lUGFpciB0ZXN0X1NTTEVuZ2luZV9zZXRVc2VDbGllbnRNb2RlKGZpbmFsIGJvb2xlYW4gY2xpZW50Q2xpZW50TW9kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBzZXJ2ZXJDbGllbnRNb2RlKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGM7CisgICAgICAgIGlmICghY2xpZW50Q2xpZW50TW9kZSAmJiBzZXJ2ZXJDbGllbnRNb2RlKSB7CisgICAgICAgICAgICBjID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKFRlc3RLZXlTdG9yZS5nZXRTZXJ2ZXIoKSwgVGVzdEtleVN0b3JlLmdldENsaWVudCgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBUZXN0U1NMRW5naW5lUGFpci5jcmVhdGUoYywgbmV3IFRlc3RTU0xFbmdpbmVQYWlyLkhvb2tzKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICB2b2lkIGJlZm9yZUJlZ2luSGFuZHNoYWtlKFNTTEVuZ2luZSBjbGllbnQsIFNTTEVuZ2luZSBzZXJ2ZXIpIHsKKyAgICAgICAgICAgICAgICBjbGllbnQuc2V0VXNlQ2xpZW50TW9kZShjbGllbnRDbGllbnRNb2RlKTsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIuc2V0VXNlQ2xpZW50TW9kZShzZXJ2ZXJDbGllbnRNb2RlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xFbmdpbmVfY2xpZW50QXV0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMQ29udGV4dCBjID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIFNTTEVuZ2luZSBlID0gYy5jbGllbnRDb250ZXh0LmNyZWF0ZVNTTEVuZ2luZSgpOworCisgICAgICAgIGFzc2VydEZhbHNlKGUuZ2V0V2FudENsaWVudEF1dGgoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGUuZ2V0TmVlZENsaWVudEF1dGgoKSk7CisKKyAgICAgICAgLy8gY29uZmlybSB0dXJuaW5nIG9uZSBvbiBieSBpdHNlbGYKKyAgICAgICAgZS5zZXRXYW50Q2xpZW50QXV0aCh0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShlLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICBhc3NlcnRGYWxzZShlLmdldE5lZWRDbGllbnRBdXRoKCkpOworCisgICAgICAgIC8vIGNvbmZpcm0gdHVybmluZyBzZXR0aW5nIG9uIHRvZ2dsZXMgdGhlIG90aGVyCisgICAgICAgIGUuc2V0TmVlZENsaWVudEF1dGgodHJ1ZSk7CisgICAgICAgIGFzc2VydEZhbHNlKGUuZ2V0V2FudENsaWVudEF1dGgoKSk7CisgICAgICAgIGFzc2VydFRydWUoZS5nZXROZWVkQ2xpZW50QXV0aCgpKTsKKworICAgICAgICAvLyBjb25maXJtIHRvZ2dsaW5nIGJhY2sKKyAgICAgICAgZS5zZXRXYW50Q2xpZW50QXV0aCh0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShlLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICBhc3NlcnRGYWxzZShlLmdldE5lZWRDbGllbnRBdXRoKCkpOworCisgICAgICAgIC8vIFRPRE8gRml4IEtub3duRmFpbHVyZSAiaW5pdCAtIGludmFsaWQgcHJpdmF0ZSBrZXkiCisgICAgICAgIFRlc3RTU0xDb250ZXh0IGNsaWVudEF1dGhDb250ZXh0CisgICAgICAgICAgICAgICAgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoVGVzdEtleVN0b3JlLmdldENsaWVudENlcnRpZmljYXRlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGVzdEtleVN0b3JlLmdldFNlcnZlcigpKTsKKyAgICAgICAgVGVzdFNTTEVuZ2luZVBhaXIgcCA9IFRlc3RTU0xFbmdpbmVQYWlyLmNyZWF0ZShjbGllbnRBdXRoQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVGVzdFNTTEVuZ2luZVBhaXIuSG9va3MoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgdm9pZCBiZWZvcmVCZWdpbkhhbmRzaGFrZShTU0xFbmdpbmUgY2xpZW50LCBTU0xFbmdpbmUgc2VydmVyKSB7CisgICAgICAgICAgICAgICAgc2VydmVyLnNldFdhbnRDbGllbnRBdXRoKHRydWUpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAgICAgYXNzZXJ0Q29ubmVjdGVkKHApOworICAgICAgICBhc3NlcnROb3ROdWxsKHAuY2xpZW50LmdldFNlc3Npb24oKS5nZXRMb2NhbENlcnRpZmljYXRlcygpKTsKKyAgICAgICAgVGVzdEtleVN0b3JlLmFzc2VydENoYWluTGVuZ3RoKHAuY2xpZW50LmdldFNlc3Npb24oKS5nZXRMb2NhbENlcnRpZmljYXRlcygpKTsKKyAgICAgICAgVGVzdFNTTENvbnRleHQuYXNzZXJ0Q2xpZW50Q2VydGlmaWNhdGVDaGFpbihjbGllbnRBdXRoQ29udGV4dC5jbGllbnRUcnVzdE1hbmFnZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcC5jbGllbnQuZ2V0U2Vzc2lvbigpLmdldExvY2FsQ2VydGlmaWNhdGVzKCkpOworICAgICAgICBjbGllbnRBdXRoQ29udGV4dC5jbG9zZSgpOworICAgICAgICBjLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xFbmdpbmVfZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgU1NMRW5naW5lIGUgPSBjLmNsaWVudENvbnRleHQuY3JlYXRlU1NMRW5naW5lKCk7CisgICAgICAgIGFzc2VydFRydWUoZS5nZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oKSk7CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTEVuZ2luZV9zZXRFbmFibGVTZXNzaW9uQ3JlYXRpb25fc2VydmVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xFbmdpbmVQYWlyIHAgPSBUZXN0U1NMRW5naW5lUGFpci5jcmVhdGUobmV3IFRlc3RTU0xFbmdpbmVQYWlyLkhvb2tzKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICB2b2lkIGJlZm9yZUJlZ2luSGFuZHNoYWtlKFNTTEVuZ2luZSBjbGllbnQsIFNTTEVuZ2luZSBzZXJ2ZXIpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIuc2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKGZhbHNlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIGFzc2VydE5vdENvbm5lY3RlZChwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTEVuZ2luZV9zZXRFbmFibGVTZXNzaW9uQ3JlYXRpb25fY2xpZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUZXN0U1NMRW5naW5lUGFpci5jcmVhdGUobmV3IFRlc3RTU0xFbmdpbmVQYWlyLkhvb2tzKCkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHZvaWQgYmVmb3JlQmVnaW5IYW5kc2hha2UoU1NMRW5naW5lIGNsaWVudCwgU1NMRW5naW5lIHNlcnZlcikgeworICAgICAgICAgICAgICAgICAgICBjbGllbnQuc2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKGZhbHNlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU1NMRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTEVuZ2luZV9nZXRTU0xQYXJhbWV0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgU1NMRW5naW5lIGUgPSBjLmNsaWVudENvbnRleHQuY3JlYXRlU1NMRW5naW5lKCk7CisKKyAgICAgICAgU1NMUGFyYW1ldGVycyBwID0gZS5nZXRTU0xQYXJhbWV0ZXJzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwocCk7CisKKyAgICAgICAgU3RyaW5nW10gY2lwaGVyU3VpdGVzID0gcC5nZXRDaXBoZXJTdWl0ZXMoKTsKKyAgICAgICAgU3RhbmRhcmROYW1lcy5hc3NlcnRWYWxpZENpcGhlclN1aXRlcyhTdGFuZGFyZE5hbWVzLkNJUEhFUl9TVUlURVMsIGNpcGhlclN1aXRlcyk7CisgICAgICAgIGFzc2VydE5vdFNhbWUoY2lwaGVyU3VpdGVzLCBlLmdldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KGNpcGhlclN1aXRlcyksIEFycmF5cy5hc0xpc3QoZS5nZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCkpKTsKKworICAgICAgICBTdHJpbmdbXSBwcm90b2NvbHMgPSBwLmdldFByb3RvY29scygpOworICAgICAgICBTdGFuZGFyZE5hbWVzLmFzc2VydFZhbGlkUHJvdG9jb2xzKFN0YW5kYXJkTmFtZXMuU1NMX1NPQ0tFVF9QUk9UT0NPTFMsIHByb3RvY29scyk7CisgICAgICAgIGFzc2VydE5vdFNhbWUocHJvdG9jb2xzLCBlLmdldEVuYWJsZWRQcm90b2NvbHMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KHByb3RvY29scyksIEFycmF5cy5hc0xpc3QoZS5nZXRFbmFibGVkUHJvdG9jb2xzKCkpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMocC5nZXRXYW50Q2xpZW50QXV0aCgpLCBlLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMocC5nZXROZWVkQ2xpZW50QXV0aCgpLCBlLmdldE5lZWRDbGllbnRBdXRoKCkpOworCisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTEVuZ2luZV9zZXRTU0xQYXJhbWV0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgU1NMRW5naW5lIGUgPSBjLmNsaWVudENvbnRleHQuY3JlYXRlU1NMRW5naW5lKCk7CisgICAgICAgIFN0cmluZ1tdIGRlZmF1bHRDaXBoZXJTdWl0ZXMgPSBlLmdldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKTsKKyAgICAgICAgU3RyaW5nW10gZGVmYXVsdFByb3RvY29scyA9IGUuZ2V0RW5hYmxlZFByb3RvY29scygpOworICAgICAgICBTdHJpbmdbXSBzdXBwb3J0ZWRDaXBoZXJTdWl0ZXMgPSBlLmdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpOworICAgICAgICBTdHJpbmdbXSBzdXBwb3J0ZWRQcm90b2NvbHMgPSBlLmdldFN1cHBvcnRlZFByb3RvY29scygpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIFNTTFBhcmFtZXRlcnMgcCA9IG5ldyBTU0xQYXJhbWV0ZXJzKCk7CisgICAgICAgICAgICBlLnNldFNTTFBhcmFtZXRlcnMocCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChkZWZhdWx0Q2lwaGVyU3VpdGVzKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheXMuYXNMaXN0KGUuZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChkZWZhdWx0UHJvdG9jb2xzKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheXMuYXNMaXN0KGUuZ2V0RW5hYmxlZFByb3RvY29scygpKSk7CisgICAgICAgIH0KKworICAgICAgICB7CisgICAgICAgICAgICBTU0xQYXJhbWV0ZXJzIHAgPSBuZXcgU1NMUGFyYW1ldGVycyhzdXBwb3J0ZWRDaXBoZXJTdWl0ZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0ZWRQcm90b2NvbHMpOworICAgICAgICAgICAgZS5zZXRTU0xQYXJhbWV0ZXJzKHApOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3Qoc3VwcG9ydGVkQ2lwaGVyU3VpdGVzKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheXMuYXNMaXN0KGUuZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChzdXBwb3J0ZWRQcm90b2NvbHMpLAorICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5cy5hc0xpc3QoZS5nZXRFbmFibGVkUHJvdG9jb2xzKCkpKTsKKyAgICAgICAgfQorICAgICAgICB7CisgICAgICAgICAgICBTU0xQYXJhbWV0ZXJzIHAgPSBuZXcgU1NMUGFyYW1ldGVycygpOworCisgICAgICAgICAgICBwLnNldE5lZWRDbGllbnRBdXRoKHRydWUpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZS5nZXROZWVkQ2xpZW50QXV0aCgpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGUuZ2V0V2FudENsaWVudEF1dGgoKSk7CisgICAgICAgICAgICBlLnNldFNTTFBhcmFtZXRlcnMocCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGUuZ2V0TmVlZENsaWVudEF1dGgoKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShlLmdldFdhbnRDbGllbnRBdXRoKCkpOworCisgICAgICAgICAgICBwLnNldFdhbnRDbGllbnRBdXRoKHRydWUpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShlLmdldE5lZWRDbGllbnRBdXRoKCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZS5nZXRXYW50Q2xpZW50QXV0aCgpKTsKKyAgICAgICAgICAgIGUuc2V0U1NMUGFyYW1ldGVycyhwKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGUuZ2V0TmVlZENsaWVudEF1dGgoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGUuZ2V0V2FudENsaWVudEF1dGgoKSk7CisKKyAgICAgICAgICAgIHAuc2V0V2FudENsaWVudEF1dGgoZmFsc2UpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZS5nZXROZWVkQ2xpZW50QXV0aCgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZS5nZXRXYW50Q2xpZW50QXV0aCgpKTsKKyAgICAgICAgICAgIGUuc2V0U1NMUGFyYW1ldGVycyhwKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGUuZ2V0TmVlZENsaWVudEF1dGgoKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShlLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICB9CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1Rlc3RTU0xFbmdpbmVQYWlyX2NyZWF0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMRW5naW5lUGFpciB0ZXN0ID0gVGVzdFNTTEVuZ2luZVBhaXIuY3JlYXRlKG51bGwpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRlc3QuYyk7CisgICAgICAgIGFzc2VydE5vdE51bGwodGVzdC5zZXJ2ZXIpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRlc3QuY2xpZW50KTsKKyAgICAgICAgYXNzZXJ0Q29ubmVjdGVkKHRlc3QpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvU1NMUGFyYW1ldGVyc1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvU1NMUGFyYW1ldGVyc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NmQwYjQxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvbmV0L3NzbC9TU0xQYXJhbWV0ZXJzVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMUGFyYW1ldGVyczsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBTU0xQYXJhbWV0ZXJzVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMUGFyYW1ldGVyc19lbXB0eUNvbnN0cnVjdG9yKCkgeworICAgICAgICBTU0xQYXJhbWV0ZXJzIHAgPSBuZXcgU1NMUGFyYW1ldGVycygpOworICAgICAgICBhc3NlcnROdWxsKHAuZ2V0Q2lwaGVyU3VpdGVzKCkpOworICAgICAgICBhc3NlcnROdWxsKHAuZ2V0UHJvdG9jb2xzKCkpOworICAgICAgICBhc3NlcnRGYWxzZShwLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICBhc3NlcnRGYWxzZShwLmdldE5lZWRDbGllbnRBdXRoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMUGFyYW1ldGVyc19jaXBoZXJTdWl0ZXNDb25zdHJ1Y3RvcigpIHsKKyAgICAgICAgU3RyaW5nW10gY2lwaGVyU3VpdGVzID0gbmV3IFN0cmluZ1tdIHsgImZvbyIsIG51bGwsICJiYXIiIH07CisgICAgICAgIFNTTFBhcmFtZXRlcnMgcCA9IG5ldyBTU0xQYXJhbWV0ZXJzKGNpcGhlclN1aXRlcyk7CisgICAgICAgIGFzc2VydE5vdE51bGwocC5nZXRDaXBoZXJTdWl0ZXMoKSk7CisgICAgICAgIGFzc2VydE5vdFNhbWUoY2lwaGVyU3VpdGVzLCBwLmdldENpcGhlclN1aXRlcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoY2lwaGVyU3VpdGVzKSwgQXJyYXlzLmFzTGlzdChwLmdldENpcGhlclN1aXRlcygpKSk7CisgICAgICAgIGFzc2VydE51bGwocC5nZXRQcm90b2NvbHMoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHAuZ2V0V2FudENsaWVudEF1dGgoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHAuZ2V0TmVlZENsaWVudEF1dGgoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xQYXJhbWV0ZXJzX2NwaGVyU3VpdGVzUHJvdG9jb2xzQ29uc3RydWN0b3IoKSB7CisgICAgICAgIFN0cmluZ1tdIGNpcGhlclN1aXRlcyA9IG5ldyBTdHJpbmdbXSB7ICJmb28iLCBudWxsLCAiYmFyIiB9OworICAgICAgICBTdHJpbmdbXSBwcm90b2NvbHMgPSBuZXcgU3RyaW5nW10geyAiYmF6IiwgbnVsbCwgInF1eCIgfTsKKyAgICAgICAgU1NMUGFyYW1ldGVycyBwID0gbmV3IFNTTFBhcmFtZXRlcnMoY2lwaGVyU3VpdGVzLCBwcm90b2NvbHMpOworICAgICAgICBhc3NlcnROb3ROdWxsKHAuZ2V0Q2lwaGVyU3VpdGVzKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHAuZ2V0UHJvdG9jb2xzKCkpOworICAgICAgICBhc3NlcnROb3RTYW1lKGNpcGhlclN1aXRlcywgcC5nZXRDaXBoZXJTdWl0ZXMoKSk7CisgICAgICAgIGFzc2VydE5vdFNhbWUocHJvdG9jb2xzLCBwLmdldFByb3RvY29scygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoY2lwaGVyU3VpdGVzKSwgQXJyYXlzLmFzTGlzdChwLmdldENpcGhlclN1aXRlcygpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KHByb3RvY29scyksIEFycmF5cy5hc0xpc3QocC5nZXRQcm90b2NvbHMoKSkpOworICAgICAgICBhc3NlcnRGYWxzZShwLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICBhc3NlcnRGYWxzZShwLmdldE5lZWRDbGllbnRBdXRoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMUGFyYW1ldGVyc19DaXBoZXJTdWl0ZXMoKSB7CisgICAgICAgIFNTTFBhcmFtZXRlcnMgcCA9IG5ldyBTU0xQYXJhbWV0ZXJzKCk7CisgICAgICAgIGFzc2VydE51bGwocC5nZXRDaXBoZXJTdWl0ZXMoKSk7CisKKyAgICAgICAgLy8gY29uZmlybSBjbG9uZSBvbiBpbnB1dAorICAgICAgICBTdHJpbmdbXSBjaXBoZXJTdWl0ZXMgPSBuZXcgU3RyaW5nW10geyAiZm5vcmQiIH07CisgICAgICAgIFN0cmluZ1tdIGNvcHkgPSBjaXBoZXJTdWl0ZXMuY2xvbmUoKTsKKyAgICAgICAgcC5zZXRDaXBoZXJTdWl0ZXMoY29weSk7CisgICAgICAgIGNvcHlbMF0gPSBudWxsOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChjaXBoZXJTdWl0ZXMpLCBBcnJheXMuYXNMaXN0KHAuZ2V0Q2lwaGVyU3VpdGVzKCkpKTsKKworICAgICAgICAvLyBjb25maXJtIGNsb25lIG9uIG91dHB1dAorICAgICAgICBhc3NlcnROb3RTYW1lKHAuZ2V0Q2lwaGVyU3VpdGVzKCksIHAuZ2V0Q2lwaGVyU3VpdGVzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMUGFyYW1ldGVyc19Qcm90b2NvbHMoKSB7CisgICAgICAgIFNTTFBhcmFtZXRlcnMgcCA9IG5ldyBTU0xQYXJhbWV0ZXJzKCk7CisgICAgICAgIGFzc2VydE51bGwocC5nZXRQcm90b2NvbHMoKSk7CisKKyAgICAgICAgLy8gY29uZmlybSBjbG9uZSBvbiBpbnB1dAorICAgICAgICBTdHJpbmdbXSBwcm90b2NvbHMgPSBuZXcgU3RyaW5nW10geyAiZm5vcmQiIH07CisgICAgICAgIFN0cmluZ1tdIGNvcHkgPSBwcm90b2NvbHMuY2xvbmUoKTsKKyAgICAgICAgcC5zZXRQcm90b2NvbHMoY29weSk7CisgICAgICAgIGNvcHlbMF0gPSBudWxsOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChwcm90b2NvbHMpLCBBcnJheXMuYXNMaXN0KHAuZ2V0UHJvdG9jb2xzKCkpKTsKKworICAgICAgICAvLyBjb25maXJtIGNsb25lIG9uIG91dHB1dAorICAgICAgICBhc3NlcnROb3RTYW1lKHAuZ2V0UHJvdG9jb2xzKCksIHAuZ2V0UHJvdG9jb2xzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMUGFyYW1ldGVyc19DbGllbnRBdXRoKCkgeworICAgICAgICBTU0xQYXJhbWV0ZXJzIHAgPSBuZXcgU1NMUGFyYW1ldGVycygpOworICAgICAgICBhc3NlcnRGYWxzZShwLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICBhc3NlcnRGYWxzZShwLmdldE5lZWRDbGllbnRBdXRoKCkpOworCisgICAgICAgIC8vIGNvbmZpcm0gdHVybmluZyBvbmUgb24gYnkgaXRzZWxmCisgICAgICAgIHAuc2V0V2FudENsaWVudEF1dGgodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUocC5nZXRXYW50Q2xpZW50QXV0aCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocC5nZXROZWVkQ2xpZW50QXV0aCgpKTsKKworICAgICAgICAvLyBjb25maXJtIHR1cm5pbmcgc2V0dGluZyBvbiB0b2dnbGVzIHRoZSBvdGhlcgorICAgICAgICBwLnNldE5lZWRDbGllbnRBdXRoKHRydWUpOworICAgICAgICBhc3NlcnRGYWxzZShwLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICBhc3NlcnRUcnVlKHAuZ2V0TmVlZENsaWVudEF1dGgoKSk7CisKKyAgICAgICAgLy8gY29uZmlybSB0b2dnbGluZyBiYWNrCisgICAgICAgIHAuc2V0V2FudENsaWVudEF1dGgodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUocC5nZXRXYW50Q2xpZW50QXV0aCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocC5nZXROZWVkQ2xpZW50QXV0aCgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL1NTTFNlc3Npb25Db250ZXh0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvbmV0L3NzbC9TU0xTZXNzaW9uQ29udGV4dFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNzVkYzIzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvbmV0L3NzbC9TU0xTZXNzaW9uQ29udGV4dFRlc3QuamF2YQpAQCAtMCwwICsxLDI5MyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbkNvbnRleHQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTb2NrZXQ7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgU1NMU2Vzc2lvbkNvbnRleHRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCB2b2lkIGFzc2VydFNTTFNlc3Npb25Db250ZXh0U2l6ZShpbnQgZXhwZWN0ZWQsIFRlc3RTU0xDb250ZXh0IGMpIHsKKyAgICAgICAgYXNzZXJ0U1NMU2Vzc2lvbkNvbnRleHRTaXplKGV4cGVjdGVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jbGllbnRDb250ZXh0LmdldENsaWVudFNlc3Npb25Db250ZXh0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLnNlcnZlckNvbnRleHQuZ2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKSk7CisgICAgICAgIGFzc2VydFNTTFNlc3Npb25Db250ZXh0U2l6ZSgwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5zZXJ2ZXJDb250ZXh0LmdldENsaWVudFNlc3Npb25Db250ZXh0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLmNsaWVudENvbnRleHQuZ2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCB2b2lkIGFzc2VydFNTTFNlc3Npb25Db250ZXh0U2l6ZShpbnQgZXhwZWN0ZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xTZXNzaW9uQ29udGV4dCBjbGllbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xTZXNzaW9uQ29udGV4dCBzZXJ2ZXIpIHsKKyAgICAgICAgYXNzZXJ0U1NMU2Vzc2lvbkNvbnRleHRTaXplKGV4cGVjdGVkLCBjbGllbnQsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0U1NMU2Vzc2lvbkNvbnRleHRTaXplKGV4cGVjdGVkLCBzZXJ2ZXIsIHRydWUpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgdm9pZCBhc3NlcnRTU0xTZXNzaW9uQ29udGV4dFNpemUoaW50IGV4cGVjdGVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMU2Vzc2lvbkNvbnRleHQgcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gc2VydmVyKSB7CisgICAgICAgIGludCBzaXplID0gQ29sbGVjdGlvbnMubGlzdChzLmdldElkcygpKS5zaXplKCk7CisgICAgICAgIGlmIChzZXJ2ZXIgJiYgVGVzdFNTTENvbnRleHQuc3NsU2VydmVyU29ja2V0U3VwcG9ydHNTZXNzaW9uVGlja2V0cygpKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgc2l6ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIHNpemUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTZXNzaW9uQ29udGV4dF9nZXRJZHMoKSB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgYXNzZXJ0U1NMU2Vzc2lvbkNvbnRleHRTaXplKDAsIGMpOworICAgICAgICBjLmNsb3NlKCk7CisKKyAgICAgICAgVGVzdFNTTFNvY2tldFBhaXIgcyA9IFRlc3RTU0xTb2NrZXRQYWlyLmNyZWF0ZSgpOworICAgICAgICBhc3NlcnRTU0xTZXNzaW9uQ29udGV4dFNpemUoMSwgcy5jKTsKKyAgICAgICAgRW51bWVyYXRpb24gY2xpZW50SWRzID0gcy5jLmNsaWVudENvbnRleHQuZ2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKS5nZXRJZHMoKTsKKyAgICAgICAgRW51bWVyYXRpb24gc2VydmVySWRzID0gcy5jLnNlcnZlckNvbnRleHQuZ2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKS5nZXRJZHMoKTsKKyAgICAgICAgYnl0ZVtdIGNsaWVudElkID0gKGJ5dGVbXSkgY2xpZW50SWRzLm5leHRFbGVtZW50KCk7CisgICAgICAgIGFzc2VydEVxdWFscygzMiwgY2xpZW50SWQubGVuZ3RoKTsKKyAgICAgICAgaWYgKFRlc3RTU0xDb250ZXh0LnNzbFNlcnZlclNvY2tldFN1cHBvcnRzU2Vzc2lvblRpY2tldHMoKSkgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc2VydmVySWRzLmhhc01vcmVFbGVtZW50cygpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJ5dGVbXSBzZXJ2ZXJJZCA9IChieXRlW10pIHNlcnZlcklkcy5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMyLCBzZXJ2ZXJJZC5sZW5ndGgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGNsaWVudElkLCBzZXJ2ZXJJZCkpOworICAgICAgICB9CisgICAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNlc3Npb25Db250ZXh0X2dldFNlc3Npb24oKSB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMuY2xpZW50Q29udGV4dC5nZXRDbGllbnRTZXNzaW9uQ29udGV4dCgpLmdldFNlc3Npb24obnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0TnVsbChjLmNsaWVudENvbnRleHQuZ2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKS5nZXRTZXNzaW9uKG5ldyBieXRlWzBdKSk7CisgICAgICAgIGFzc2VydE51bGwoYy5jbGllbnRDb250ZXh0LmdldENsaWVudFNlc3Npb25Db250ZXh0KCkuZ2V0U2Vzc2lvbihuZXcgYnl0ZVsxXSkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5zZXJ2ZXJDb250ZXh0LmdldFNlcnZlclNlc3Npb25Db250ZXh0KCkuZ2V0U2Vzc2lvbihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROdWxsKGMuc2VydmVyQ29udGV4dC5nZXRTZXJ2ZXJTZXNzaW9uQ29udGV4dCgpLmdldFNlc3Npb24obmV3IGJ5dGVbMF0pKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjLnNlcnZlckNvbnRleHQuZ2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKS5nZXRTZXNzaW9uKG5ldyBieXRlWzFdKSk7CisgICAgICAgIGMuY2xvc2UoKTsKKworICAgICAgICBUZXN0U1NMU29ja2V0UGFpciBzID0gVGVzdFNTTFNvY2tldFBhaXIuY3JlYXRlKCk7CisgICAgICAgIFNTTFNlc3Npb25Db250ZXh0IGNsaWVudCA9IHMuYy5jbGllbnRDb250ZXh0LmdldENsaWVudFNlc3Npb25Db250ZXh0KCk7CisgICAgICAgIFNTTFNlc3Npb25Db250ZXh0IHNlcnZlciA9IHMuYy5zZXJ2ZXJDb250ZXh0LmdldFNlcnZlclNlc3Npb25Db250ZXh0KCk7CisgICAgICAgIGJ5dGVbXSBjbGllbnRJZCA9IChieXRlW10pIGNsaWVudC5nZXRJZHMoKS5uZXh0RWxlbWVudCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKGNsaWVudC5nZXRTZXNzaW9uKGNsaWVudElkKSk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhjbGllbnRJZCwgY2xpZW50LmdldFNlc3Npb24oY2xpZW50SWQpLmdldElkKCkpKTsKKyAgICAgICAgaWYgKFRlc3RTU0xDb250ZXh0LnNzbFNlcnZlclNvY2tldFN1cHBvcnRzU2Vzc2lvblRpY2tldHMoKSkgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc2VydmVyLmdldElkcygpLmhhc01vcmVFbGVtZW50cygpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJ5dGVbXSBzZXJ2ZXJJZCA9IChieXRlW10pIHNlcnZlci5nZXRJZHMoKS5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChzZXJ2ZXIuZ2V0U2Vzc2lvbihzZXJ2ZXJJZCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKHNlcnZlcklkLCBzZXJ2ZXIuZ2V0U2Vzc2lvbihzZXJ2ZXJJZCkuZ2V0SWQoKSkpOworICAgICAgICB9CisgICAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNlc3Npb25Db250ZXh0X2dldFNlc3Npb25DYWNoZVNpemUoKSB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFRlc3RTU0xDb250ZXh0LkVYUEVDVEVEX0RFRkFVTFRfQ0xJRU5UX1NTTF9TRVNTSU9OX0NBQ0hFX1NJWkUsCisgICAgICAgICAgICAgICAgICAgICBjLmNsaWVudENvbnRleHQuZ2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKS5nZXRTZXNzaW9uQ2FjaGVTaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoVGVzdFNTTENvbnRleHQuRVhQRUNURURfREVGQVVMVF9TRVJWRVJfU1NMX1NFU1NJT05fQ0FDSEVfU0laRSwKKyAgICAgICAgICAgICAgICAgICAgIGMuc2VydmVyQ29udGV4dC5nZXRTZXJ2ZXJTZXNzaW9uQ29udGV4dCgpLmdldFNlc3Npb25DYWNoZVNpemUoKSk7CisgICAgICAgIGMuY2xvc2UoKTsKKworICAgICAgICBUZXN0U1NMU29ja2V0UGFpciBzID0gVGVzdFNTTFNvY2tldFBhaXIuY3JlYXRlKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhUZXN0U1NMQ29udGV4dC5FWFBFQ1RFRF9ERUZBVUxUX0NMSUVOVF9TU0xfU0VTU0lPTl9DQUNIRV9TSVpFLAorICAgICAgICAgICAgICAgICAgICAgcy5jLmNsaWVudENvbnRleHQuZ2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKS5nZXRTZXNzaW9uQ2FjaGVTaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoVGVzdFNTTENvbnRleHQuRVhQRUNURURfREVGQVVMVF9TRVJWRVJfU1NMX1NFU1NJT05fQ0FDSEVfU0laRSwKKyAgICAgICAgICAgICAgICAgICAgIHMuYy5zZXJ2ZXJDb250ZXh0LmdldFNlcnZlclNlc3Npb25Db250ZXh0KCkuZ2V0U2Vzc2lvbkNhY2hlU2l6ZSgpKTsKKyAgICAgICAgcy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU2Vzc2lvbkNvbnRleHRfc2V0U2Vzc2lvbkNhY2hlU2l6ZV9ub0Nvbm5lY3QoKSB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgYXNzZXJ0Tm9Db25uZWN0U2V0U2Vzc2lvbkNhY2hlU2l6ZUJlaGF2aW9yKAorICAgICAgICAgICAgICAgIFRlc3RTU0xDb250ZXh0LkVYUEVDVEVEX0RFRkFVTFRfQ0xJRU5UX1NTTF9TRVNTSU9OX0NBQ0hFX1NJWkUsCisgICAgICAgICAgICAgICAgYy5jbGllbnRDb250ZXh0LmdldENsaWVudFNlc3Npb25Db250ZXh0KCkpOworICAgICAgICBhc3NlcnROb0Nvbm5lY3RTZXRTZXNzaW9uQ2FjaGVTaXplQmVoYXZpb3IoCisgICAgICAgICAgICAgICAgVGVzdFNTTENvbnRleHQuRVhQRUNURURfREVGQVVMVF9TRVJWRVJfU1NMX1NFU1NJT05fQ0FDSEVfU0laRSwKKyAgICAgICAgICAgICAgICBjLnNlcnZlckNvbnRleHQuZ2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKSk7CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGFzc2VydE5vQ29ubmVjdFNldFNlc3Npb25DYWNoZVNpemVCZWhhdmlvcihpbnQgZXhwZWN0ZWREZWZhdWx0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTFNlc3Npb25Db250ZXh0IHMpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMuc2V0U2Vzc2lvbkNhY2hlU2l6ZSgtMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZERlZmF1bHQsIHMuZ2V0U2Vzc2lvbkNhY2hlU2l6ZSgpKTsKKyAgICAgICAgcy5zZXRTZXNzaW9uQ2FjaGVTaXplKDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgcy5nZXRTZXNzaW9uQ2FjaGVTaXplKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU2Vzc2lvbkNvbnRleHRfc2V0U2Vzc2lvbkNhY2hlU2l6ZV9vbmVDb25uZWN0KCkgeworICAgICAgICBUZXN0U1NMU29ja2V0UGFpciBzID0gVGVzdFNTTFNvY2tldFBhaXIuY3JlYXRlKCk7CisgICAgICAgIFNTTFNlc3Npb25Db250ZXh0IGNsaWVudCA9IHMuYy5jbGllbnRDb250ZXh0LmdldENsaWVudFNlc3Npb25Db250ZXh0KCk7CisgICAgICAgIFNTTFNlc3Npb25Db250ZXh0IHNlcnZlciA9IHMuYy5zZXJ2ZXJDb250ZXh0LmdldFNlcnZlclNlc3Npb25Db250ZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscyhUZXN0U1NMQ29udGV4dC5FWFBFQ1RFRF9ERUZBVUxUX0NMSUVOVF9TU0xfU0VTU0lPTl9DQUNIRV9TSVpFLAorICAgICAgICAgICAgICAgICAgICAgY2xpZW50LmdldFNlc3Npb25DYWNoZVNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhUZXN0U1NMQ29udGV4dC5FWFBFQ1RFRF9ERUZBVUxUX1NFUlZFUl9TU0xfU0VTU0lPTl9DQUNIRV9TSVpFLAorICAgICAgICAgICAgICAgICAgICAgc2VydmVyLmdldFNlc3Npb25DYWNoZVNpemUoKSk7CisgICAgICAgIGFzc2VydFNTTFNlc3Npb25Db250ZXh0U2l6ZSgxLCBzLmMpOworICAgICAgICBzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTZXNzaW9uQ29udGV4dF9zZXRTZXNzaW9uQ2FjaGVTaXplX2R5bmFtaWMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgYyA9IFRlc3RTU0xDb250ZXh0LmNyZWF0ZSgpOworICAgICAgICBTU0xTZXNzaW9uQ29udGV4dCBjbGllbnQgPSBjLmNsaWVudENvbnRleHQuZ2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKTsKKyAgICAgICAgU1NMU2Vzc2lvbkNvbnRleHQgc2VydmVyID0gYy5zZXJ2ZXJDb250ZXh0LmdldFNlcnZlclNlc3Npb25Db250ZXh0KCk7CisKKyAgICAgICAgU3RyaW5nW10gc3VwcG9ydGVkQ2lwaGVyU3VpdGVzID0gYy5zZXJ2ZXJTb2NrZXQuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgICAgIGMuc2VydmVyU29ja2V0LnNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoc3VwcG9ydGVkQ2lwaGVyU3VpdGVzKTsKKyAgICAgICAgTGlua2VkTGlzdDxTdHJpbmc+IHVuaXF1ZUNpcGhlclN1aXRlcworICAgICAgICAgICAgPSBuZXcgTGlua2VkTGlzdChBcnJheXMuYXNMaXN0KHN1cHBvcnRlZENpcGhlclN1aXRlcykpOworICAgICAgICAvLyBvbmx5IHVzZSBSU0EgY2lwaGVyIHN1aXRlcyB3aGljaCB3aWxsIHdvcmsgd2l0aCBvdXIgVHJ1c3RQcm92aWRlcgorICAgICAgICBJdGVyYXRvcjxTdHJpbmc+IGkgPSB1bmlxdWVDaXBoZXJTdWl0ZXMuaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGkuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBTdHJpbmcgY2lwaGVyU3VpdGUgPSBpLm5leHQoKTsKKworICAgICAgICAgICAgLy8gQ2VydGlmaWNhdGUga2V5IGxlbmd0aCB0b28gbG9uZyBmb3IgZXhwb3J0IGNpcGhlcnMKKyAgICAgICAgICAgIGlmIChjaXBoZXJTdWl0ZS5zdGFydHNXaXRoKCJTU0xfUlNBX0VYUE9SVF8iKSkgeworICAgICAgICAgICAgICAgIGkucmVtb3ZlKCk7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChjaXBoZXJTdWl0ZS5zdGFydHNXaXRoKCJTU0xfUlNBXyIpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY2lwaGVyU3VpdGUuc3RhcnRzV2l0aCgiVExTX1JTQV8iKSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGNpcGhlclN1aXRlLnN0YXJ0c1dpdGgoIlRMU19ESEVfUlNBXyIpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY2lwaGVyU3VpdGUuc3RhcnRzV2l0aCgiU1NMX0RIRV9SU0FfIikpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGkucmVtb3ZlKCk7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBoYXZpbmcgbW9yZSB0aGFuIDMgdW5pcXVlQ2lwaGVyU3VpdGVzIGlzIGEgdGVzdAorICAgICAgICAgKiByZXF1aXJlbWVudCwgbm90IGEgcmVxdWlyZW1lbnQgb2YgdGhlIGludGVyZmFjZSBvcgorICAgICAgICAgKiBpbXBsZW1lbnRhdGlvbi4gSXQgc2ltcGx5IGFsbG93cyB1cyB0byBtYWtlIHN1cmUgdGhhdCB3ZQorICAgICAgICAgKiB3aWxsIG5vdCBnZXQgYSBjYWNoZWQgc2Vzc2lvbiBJRCBzaW5jZSB3ZSdsbCBoYXZlIHRvCisgICAgICAgICAqIHJlbmVnb3RpYXRlIGEgbmV3IHNlc3Npb24gZHVlIHRvIHRoZSBuZXcgY2lwaGVyIHN1aXRlCisgICAgICAgICAqIHJlcXVpcmVtZW50LiBldmVuIHRoaXMgdGVzdCBvbmx5IHJlYWxseSBuZWVkcyB0aHJlZSBpZiBpdAorICAgICAgICAgKiByZXVzZWQgdGhlIHVuaXF1ZSBjaXBoZXIgc3VpdGVzIGV2ZXJ5IHRpbWUgaXQgcmVzZXRzIHRoZQorICAgICAgICAgKiBzZXNzaW9uIGNhY2hlLgorICAgICAgICAgKi8KKyAgICAgICAgYXNzZXJ0VHJ1ZSh1bmlxdWVDaXBoZXJTdWl0ZXMuc2l6ZSgpID49IDMpOworICAgICAgICBTdHJpbmcgY2lwaGVyU3VpdGUxID0gdW5pcXVlQ2lwaGVyU3VpdGVzLmdldCgwKTsKKyAgICAgICAgU3RyaW5nIGNpcGhlclN1aXRlMiA9IHVuaXF1ZUNpcGhlclN1aXRlcy5nZXQoMSk7CisgICAgICAgIFN0cmluZyBjaXBoZXJTdWl0ZTMgPSB1bmlxdWVDaXBoZXJTdWl0ZXMuZ2V0KDIpOworCisgICAgICAgIExpc3Q8U1NMU29ja2V0W10+IHRvQ2xvc2UgPSBuZXcgQXJyYXlMaXN0PFNTTFNvY2tldFtdPigpOworICAgICAgICB0b0Nsb3NlLmFkZChUZXN0U1NMU29ja2V0UGFpci5jb25uZWN0KGMsIG5ldyBTdHJpbmdbXSB7IGNpcGhlclN1aXRlMSB9LCBudWxsKSk7CisgICAgICAgIGFzc2VydFNTTFNlc3Npb25Db250ZXh0U2l6ZSgxLCBjKTsKKyAgICAgICAgdG9DbG9zZS5hZGQoVGVzdFNTTFNvY2tldFBhaXIuY29ubmVjdChjLCBuZXcgU3RyaW5nW10geyBjaXBoZXJTdWl0ZTIgfSwgbnVsbCkpOworICAgICAgICBhc3NlcnRTU0xTZXNzaW9uQ29udGV4dFNpemUoMiwgYyk7CisgICAgICAgIHRvQ2xvc2UuYWRkKFRlc3RTU0xTb2NrZXRQYWlyLmNvbm5lY3QoYywgbmV3IFN0cmluZ1tdIHsgY2lwaGVyU3VpdGUzIH0sIG51bGwpKTsKKyAgICAgICAgYXNzZXJ0U1NMU2Vzc2lvbkNvbnRleHRTaXplKDMsIGMpOworCisgICAgICAgIGNsaWVudC5zZXRTZXNzaW9uQ2FjaGVTaXplKDEpOworICAgICAgICBzZXJ2ZXIuc2V0U2Vzc2lvbkNhY2hlU2l6ZSgxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNsaWVudC5nZXRTZXNzaW9uQ2FjaGVTaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgc2VydmVyLmdldFNlc3Npb25DYWNoZVNpemUoKSk7CisgICAgICAgIGFzc2VydFNTTFNlc3Npb25Db250ZXh0U2l6ZSgxLCBjKTsKKyAgICAgICAgdG9DbG9zZS5hZGQoVGVzdFNTTFNvY2tldFBhaXIuY29ubmVjdChjLCBuZXcgU3RyaW5nW10geyBjaXBoZXJTdWl0ZTEgfSwgbnVsbCkpOworICAgICAgICBhc3NlcnRTU0xTZXNzaW9uQ29udGV4dFNpemUoMSwgYyk7CisKKyAgICAgICAgY2xpZW50LnNldFNlc3Npb25DYWNoZVNpemUoMik7CisgICAgICAgIHNlcnZlci5zZXRTZXNzaW9uQ2FjaGVTaXplKDIpOworICAgICAgICB0b0Nsb3NlLmFkZChUZXN0U1NMU29ja2V0UGFpci5jb25uZWN0KGMsIG5ldyBTdHJpbmdbXSB7IGNpcGhlclN1aXRlMiB9LCBudWxsKSk7CisgICAgICAgIGFzc2VydFNTTFNlc3Npb25Db250ZXh0U2l6ZSgyLCBjKTsKKyAgICAgICAgdG9DbG9zZS5hZGQoVGVzdFNTTFNvY2tldFBhaXIuY29ubmVjdChjLCBuZXcgU3RyaW5nW10geyBjaXBoZXJTdWl0ZTMgfSwgbnVsbCkpOworICAgICAgICBhc3NlcnRTU0xTZXNzaW9uQ29udGV4dFNpemUoMiwgYyk7CisKKyAgICAgICAgZm9yIChTU0xTb2NrZXRbXSBwYWlyIDogdG9DbG9zZSkgeworICAgICAgICAgICAgZm9yIChTU0xTb2NrZXQgcyA6IHBhaXIpIHsKKyAgICAgICAgICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU2Vzc2lvbkNvbnRleHRfZ2V0U2Vzc2lvblRpbWVvdXQoKSB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFRlc3RTU0xDb250ZXh0LkVYUEVDVEVEX0RFRkFVTFRfU1NMX1NFU1NJT05fQ0FDSEVfVElNRU9VVCwKKyAgICAgICAgICAgICAgICAgICAgIGMuY2xpZW50Q29udGV4dC5nZXRDbGllbnRTZXNzaW9uQ29udGV4dCgpLmdldFNlc3Npb25UaW1lb3V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoVGVzdFNTTENvbnRleHQuRVhQRUNURURfREVGQVVMVF9TU0xfU0VTU0lPTl9DQUNIRV9USU1FT1VULAorICAgICAgICAgICAgICAgICAgICAgYy5zZXJ2ZXJDb250ZXh0LmdldFNlcnZlclNlc3Npb25Db250ZXh0KCkuZ2V0U2Vzc2lvblRpbWVvdXQoKSk7CisgICAgICAgIGMuY2xvc2UoKTsKKworICAgICAgICBUZXN0U1NMU29ja2V0UGFpciBzID0gVGVzdFNTTFNvY2tldFBhaXIuY3JlYXRlKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhUZXN0U1NMQ29udGV4dC5FWFBFQ1RFRF9ERUZBVUxUX1NTTF9TRVNTSU9OX0NBQ0hFX1RJTUVPVVQsCisgICAgICAgICAgICAgICAgICAgICBzLmMuY2xpZW50Q29udGV4dC5nZXRDbGllbnRTZXNzaW9uQ29udGV4dCgpLmdldFNlc3Npb25UaW1lb3V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoVGVzdFNTTENvbnRleHQuRVhQRUNURURfREVGQVVMVF9TU0xfU0VTU0lPTl9DQUNIRV9USU1FT1VULAorICAgICAgICAgICAgICAgICAgICAgcy5jLnNlcnZlckNvbnRleHQuZ2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKS5nZXRTZXNzaW9uVGltZW91dCgpKTsKKyAgICAgICAgcy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU2Vzc2lvbkNvbnRleHRfc2V0U2Vzc2lvblRpbWVvdXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgYyA9IFRlc3RTU0xDb250ZXh0LmNyZWF0ZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoVGVzdFNTTENvbnRleHQuRVhQRUNURURfREVGQVVMVF9TU0xfU0VTU0lPTl9DQUNIRV9USU1FT1VULAorICAgICAgICAgICAgICAgICAgICAgYy5jbGllbnRDb250ZXh0LmdldENsaWVudFNlc3Npb25Db250ZXh0KCkuZ2V0U2Vzc2lvblRpbWVvdXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhUZXN0U1NMQ29udGV4dC5FWFBFQ1RFRF9ERUZBVUxUX1NTTF9TRVNTSU9OX0NBQ0hFX1RJTUVPVVQsCisgICAgICAgICAgICAgICAgICAgICBjLnNlcnZlckNvbnRleHQuZ2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKS5nZXRTZXNzaW9uVGltZW91dCgpKTsKKyAgICAgICAgYy5jbGllbnRDb250ZXh0LmdldENsaWVudFNlc3Npb25Db250ZXh0KCkuc2V0U2Vzc2lvblRpbWVvdXQoMCk7CisgICAgICAgIGMuc2VydmVyQ29udGV4dC5nZXRTZXJ2ZXJTZXNzaW9uQ29udGV4dCgpLnNldFNlc3Npb25UaW1lb3V0KDApOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYy5jbGllbnRDb250ZXh0LmdldENsaWVudFNlc3Npb25Db250ZXh0KCkuZ2V0U2Vzc2lvblRpbWVvdXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBjLnNlcnZlckNvbnRleHQuZ2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKS5nZXRTZXNzaW9uVGltZW91dCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5jbGllbnRDb250ZXh0LmdldENsaWVudFNlc3Npb25Db250ZXh0KCkuc2V0U2Vzc2lvblRpbWVvdXQoLTEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5zZXJ2ZXJDb250ZXh0LmdldFNlcnZlclNlc3Npb25Db250ZXh0KCkuc2V0U2Vzc2lvblRpbWVvdXQoLTEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBjLmNsb3NlKCk7CisKKyAgICAgICAgVGVzdFNTTFNvY2tldFBhaXIgcyA9IFRlc3RTU0xTb2NrZXRQYWlyLmNyZWF0ZSgpOworICAgICAgICBhc3NlcnRTU0xTZXNzaW9uQ29udGV4dFNpemUoMSwgcy5jKTsKKyAgICAgICAgVGhyZWFkLnNsZWVwKDEgKiAxMDAwKTsKKyAgICAgICAgcy5jLmNsaWVudENvbnRleHQuZ2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKS5zZXRTZXNzaW9uVGltZW91dCgxKTsKKyAgICAgICAgcy5jLnNlcnZlckNvbnRleHQuZ2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKS5zZXRTZXNzaW9uVGltZW91dCgxKTsKKyAgICAgICAgYXNzZXJ0U1NMU2Vzc2lvbkNvbnRleHRTaXplKDAsIHMuYyk7CisgICAgICAgIHMuY2xvc2UoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL1NTTFNlc3Npb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL1NTTFNlc3Npb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjE3ZGZlOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvU1NMU2Vzc2lvblRlc3QuamF2YQpAQCAtMCwwICsxLDI5NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgbGliY29yZS5qYXZhLnNlY3VyaXR5LlN0YW5kYXJkTmFtZXM7CitpbXBvcnQgbGliY29yZS5qYXZhLnNlY3VyaXR5LlRlc3RLZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgU1NMU2Vzc2lvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF9UZXN0U1NMU2Vzc2lvbnNfY3JlYXRlKCkgeworICAgICAgICBUZXN0U1NMU2Vzc2lvbnMgcyA9IFRlc3RTU0xTZXNzaW9ucy5jcmVhdGUoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzLmludmFsaWQpOworICAgICAgICBhc3NlcnRGYWxzZShzLmludmFsaWQuaXNWYWxpZCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzLnNlcnZlci5pc1ZhbGlkKCkpOworICAgICAgICBhc3NlcnRUcnVlKHMuY2xpZW50LmlzVmFsaWQoKSk7CisgICAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNlc3Npb25fZ2V0QXBwbGljYXRpb25CdWZmZXJTaXplKCkgeworICAgICAgICBUZXN0U1NMU2Vzc2lvbnMgcyA9IFRlc3RTU0xTZXNzaW9ucy5jcmVhdGUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzLmludmFsaWQuZ2V0QXBwbGljYXRpb25CdWZmZXJTaXplKCkgPiAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzLnNlcnZlci5nZXRBcHBsaWNhdGlvbkJ1ZmZlclNpemUoKSA+IDApOworICAgICAgICBhc3NlcnRUcnVlKHMuY2xpZW50LmdldEFwcGxpY2F0aW9uQnVmZmVyU2l6ZSgpID4gMCk7CisgICAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNlc3Npb25fZ2V0Q2lwaGVyU3VpdGUoKSB7CisgICAgICAgIFRlc3RTU0xTZXNzaW9ucyBzID0gVGVzdFNTTFNlc3Npb25zLmNyZWF0ZSgpOworICAgICAgICBhc3NlcnROb3ROdWxsKHMuaW52YWxpZC5nZXRDaXBoZXJTdWl0ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFN0YW5kYXJkTmFtZXMuQ0lQSEVSX1NVSVRFX0lOVkFMSUQsIHMuaW52YWxpZC5nZXRDaXBoZXJTdWl0ZSgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzLnNlcnZlci5nZXRDaXBoZXJTdWl0ZSgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzLmNsaWVudC5nZXRDaXBoZXJTdWl0ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMuc2VydmVyLmdldENpcGhlclN1aXRlKCksCisgICAgICAgICAgICAgICAgICAgICBzLmNsaWVudC5nZXRDaXBoZXJTdWl0ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShTdGFuZGFyZE5hbWVzLkNJUEhFUl9TVUlURVMuY29udGFpbnMocy5zZXJ2ZXIuZ2V0Q2lwaGVyU3VpdGUoKSkpOworICAgICAgICBzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTZXNzaW9uX2dldENyZWF0aW9uVGltZSgpIHsKKyAgICAgICAgVGVzdFNTTFNlc3Npb25zIHMgPSBUZXN0U1NMU2Vzc2lvbnMuY3JlYXRlKCk7CisgICAgICAgIGFzc2VydFRydWUocy5pbnZhbGlkLmdldENyZWF0aW9uVGltZSgpID4gMCk7CisgICAgICAgIGFzc2VydFRydWUocy5zZXJ2ZXIuZ2V0Q3JlYXRpb25UaW1lKCkgPiAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzLmNsaWVudC5nZXRDcmVhdGlvblRpbWUoKSA+IDApOworICAgICAgICBhc3NlcnRUcnVlKE1hdGguYWJzKHMuc2VydmVyLmdldENyZWF0aW9uVGltZSgpIC0gcy5jbGllbnQuZ2V0Q3JlYXRpb25UaW1lKCkpIDwgMSAqIDEwMDApOworICAgICAgICBzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTZXNzaW9uX2dldElkKCkgeworICAgICAgICBUZXN0U1NMU2Vzc2lvbnMgcyA9IFRlc3RTU0xTZXNzaW9ucy5jcmVhdGUoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzLmludmFsaWQuZ2V0SWQoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwocy5zZXJ2ZXIuZ2V0SWQoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwocy5jbGllbnQuZ2V0SWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBzLmludmFsaWQuZ2V0SWQoKS5sZW5ndGgpOworICAgICAgICBpZiAoVGVzdFNTTENvbnRleHQuc3NsU2VydmVyU29ja2V0U3VwcG9ydHNTZXNzaW9uVGlja2V0cygpKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgcy5zZXJ2ZXIuZ2V0SWQoKS5sZW5ndGgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMyLCBzLnNlcnZlci5nZXRJZCgpLmxlbmd0aCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMocy5zZXJ2ZXIuZ2V0SWQoKSwgcy5jbGllbnQuZ2V0SWQoKSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygzMiwgcy5jbGllbnQuZ2V0SWQoKS5sZW5ndGgpOworICAgICAgICBzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTZXNzaW9uX2dldExhc3RBY2Nlc3NlZFRpbWUoKSB7CisgICAgICAgIFRlc3RTU0xTZXNzaW9ucyBzID0gVGVzdFNTTFNlc3Npb25zLmNyZWF0ZSgpOworICAgICAgICBhc3NlcnRUcnVlKHMuaW52YWxpZC5nZXRMYXN0QWNjZXNzZWRUaW1lKCkgPiAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzLnNlcnZlci5nZXRMYXN0QWNjZXNzZWRUaW1lKCkgPiAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzLmNsaWVudC5nZXRMYXN0QWNjZXNzZWRUaW1lKCkgPiAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShNYXRoLmFicyhzLnNlcnZlci5nZXRMYXN0QWNjZXNzZWRUaW1lKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIHMuY2xpZW50LmdldExhc3RBY2Nlc3NlZFRpbWUoKSkgPCAxICogMTAwMCk7CisgICAgICAgIGFzc2VydFRydWUocy5zZXJ2ZXIuZ2V0TGFzdEFjY2Vzc2VkVGltZSgpID49CisgICAgICAgICAgICAgICAgICAgcy5zZXJ2ZXIuZ2V0Q3JlYXRpb25UaW1lKCkpOworICAgICAgICBhc3NlcnRUcnVlKHMuY2xpZW50LmdldExhc3RBY2Nlc3NlZFRpbWUoKSA+PQorICAgICAgICAgICAgICAgICAgIHMuY2xpZW50LmdldENyZWF0aW9uVGltZSgpKTsKKyAgICAgICAgcy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU2Vzc2lvbl9nZXRMb2NhbENlcnRpZmljYXRlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMU2Vzc2lvbnMgcyA9IFRlc3RTU0xTZXNzaW9ucy5jcmVhdGUoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChzLmludmFsaWQuZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgIGFzc2VydE51bGwocy5jbGllbnQuZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwocy5zZXJ2ZXIuZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgIFRlc3RLZXlTdG9yZS5hc3NlcnRDaGFpbkxlbmd0aChzLnNlcnZlci5nZXRMb2NhbENlcnRpZmljYXRlcygpKTsKKyAgICAgICAgVGVzdFNTTENvbnRleHQuYXNzZXJ0U2VydmVyQ2VydGlmaWNhdGVDaGFpbihzLnMuYy5zZXJ2ZXJUcnVzdE1hbmFnZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcy5zZXJ2ZXIuZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgIFRlc3RTU0xDb250ZXh0LmFzc2VydENlcnRpZmljYXRlSW5LZXlTdG9yZShzLnNlcnZlci5nZXRMb2NhbENlcnRpZmljYXRlcygpWzBdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcy5zLmMuc2VydmVyS2V5U3RvcmUpOworICAgICAgICBzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTZXNzaW9uX2dldExvY2FsUHJpbmNpcGFsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xTZXNzaW9ucyBzID0gVGVzdFNTTFNlc3Npb25zLmNyZWF0ZSgpOworICAgICAgICBhc3NlcnROdWxsKHMuaW52YWxpZC5nZXRMb2NhbFByaW5jaXBhbCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChzLmNsaWVudC5nZXRMb2NhbFByaW5jaXBhbCgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzLnNlcnZlci5nZXRMb2NhbFByaW5jaXBhbCgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzLnNlcnZlci5nZXRMb2NhbFByaW5jaXBhbCgpLmdldE5hbWUoKSk7CisgICAgICAgIFRlc3RTU0xDb250ZXh0LmFzc2VydENlcnRpZmljYXRlSW5LZXlTdG9yZShzLnNlcnZlci5nZXRMb2NhbFByaW5jaXBhbCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcy5zLmMuc2VydmVyS2V5U3RvcmUpOworICAgICAgICBzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTZXNzaW9uX2dldFBhY2tldEJ1ZmZlclNpemUoKSB7CisgICAgICAgIFRlc3RTU0xTZXNzaW9ucyBzID0gVGVzdFNTTFNlc3Npb25zLmNyZWF0ZSgpOworICAgICAgICBhc3NlcnRUcnVlKHMuaW52YWxpZC5nZXRQYWNrZXRCdWZmZXJTaXplKCkgPiAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzLnNlcnZlci5nZXRQYWNrZXRCdWZmZXJTaXplKCkgPiAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzLmNsaWVudC5nZXRQYWNrZXRCdWZmZXJTaXplKCkgPiAwKTsKKyAgICAgICAgcy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU2Vzc2lvbl9nZXRQZWVyQ2VydGlmaWNhdGVDaGFpbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMU2Vzc2lvbnMgcyA9IFRlc3RTU0xTZXNzaW9ucy5jcmVhdGUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMuaW52YWxpZC5nZXRQZWVyQ2VydGlmaWNhdGVDaGFpbigpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwocy5jbGllbnQuZ2V0UGVlckNlcnRpZmljYXRlcygpKTsKKyAgICAgICAgVGVzdEtleVN0b3JlLmFzc2VydENoYWluTGVuZ3RoKHMuY2xpZW50LmdldFBlZXJDZXJ0aWZpY2F0ZUNoYWluKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbChzLnNlcnZlci5nZXRQZWVyQ2VydGlmaWNhdGVDaGFpbigpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTZXNzaW9uX2dldFBlZXJDZXJ0aWZpY2F0ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTFNlc3Npb25zIHMgPSBUZXN0U1NMU2Vzc2lvbnMuY3JlYXRlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmludmFsaWQuZ2V0UGVlckNlcnRpZmljYXRlcygpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwocy5jbGllbnQuZ2V0UGVlckNlcnRpZmljYXRlcygpKTsKKyAgICAgICAgVGVzdEtleVN0b3JlLmFzc2VydENoYWluTGVuZ3RoKHMuY2xpZW50LmdldFBlZXJDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgIFRlc3RTU0xDb250ZXh0LmFzc2VydFNlcnZlckNlcnRpZmljYXRlQ2hhaW4ocy5zLmMuc2VydmVyVHJ1c3RNYW5hZ2VyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMuY2xpZW50LmdldFBlZXJDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgIFRlc3RTU0xDb250ZXh0LmFzc2VydENlcnRpZmljYXRlSW5LZXlTdG9yZShzLmNsaWVudC5nZXRQZWVyQ2VydGlmaWNhdGVzKClbMF0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzLnMuYy5zZXJ2ZXJLZXlTdG9yZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLnNlcnZlci5nZXRQZWVyQ2VydGlmaWNhdGVzKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgcy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU2Vzc2lvbl9nZXRQZWVySG9zdCgpIHsKKyAgICAgICAgVGVzdFNTTFNlc3Npb25zIHMgPSBUZXN0U1NMU2Vzc2lvbnMuY3JlYXRlKCk7CisgICAgICAgIGFzc2VydE51bGwocy5pbnZhbGlkLmdldFBlZXJIb3N0KCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHMuc2VydmVyLmdldFBlZXJIb3N0KCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHMuY2xpZW50LmdldFBlZXJIb3N0KCkpOworICAgICAgICBzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTZXNzaW9uX2dldFBlZXJQb3J0KCkgeworICAgICAgICBUZXN0U1NMU2Vzc2lvbnMgcyA9IFRlc3RTU0xTZXNzaW9ucy5jcmVhdGUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBzLmludmFsaWQuZ2V0UGVlclBvcnQoKSk7CisgICAgICAgIGFzc2VydFRydWUocy5zZXJ2ZXIuZ2V0UGVlclBvcnQoKSA+IDApOworICAgICAgICBhc3NlcnRFcXVhbHMocy5zLmMucG9ydCwgcy5jbGllbnQuZ2V0UGVlclBvcnQoKSk7CisgICAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNlc3Npb25fZ2V0UGVlclByaW5jaXBhbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMU2Vzc2lvbnMgcyA9IFRlc3RTU0xTZXNzaW9ucy5jcmVhdGUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMuaW52YWxpZC5nZXRQZWVyUHJpbmNpcGFsKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMuc2VydmVyLmdldFBlZXJQcmluY2lwYWwoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROb3ROdWxsKHMuY2xpZW50LmdldFBlZXJQcmluY2lwYWwoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwocy5jbGllbnQuZ2V0UGVlclByaW5jaXBhbCgpLmdldE5hbWUoKSk7CisgICAgICAgIFRlc3RTU0xDb250ZXh0LmFzc2VydENlcnRpZmljYXRlSW5LZXlTdG9yZShzLmNsaWVudC5nZXRQZWVyUHJpbmNpcGFsKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzLnMuYy5zZXJ2ZXJLZXlTdG9yZSk7CisgICAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNlc3Npb25fZ2V0UHJvdG9jb2woKSB7CisgICAgICAgIFRlc3RTU0xTZXNzaW9ucyBzID0gVGVzdFNTTFNlc3Npb25zLmNyZWF0ZSgpOworICAgICAgICBhc3NlcnROb3ROdWxsKHMuaW52YWxpZC5nZXRQcm90b2NvbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJOT05FIiwgcy5pbnZhbGlkLmdldFByb3RvY29sKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHMuc2VydmVyLmdldFByb3RvY29sKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHMuY2xpZW50LmdldFByb3RvY29sKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMocy5zZXJ2ZXIuZ2V0UHJvdG9jb2woKSwKKyAgICAgICAgICAgICAgICAgICAgIHMuY2xpZW50LmdldFByb3RvY29sKCkpOworICAgICAgICBhc3NlcnRUcnVlKFN0YW5kYXJkTmFtZXMuU1NMX1NPQ0tFVF9QUk9UT0NPTFMuY29udGFpbnMocy5zZXJ2ZXIuZ2V0UHJvdG9jb2woKSkpOworICAgICAgICBzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTZXNzaW9uX2dldFNlc3Npb25Db250ZXh0KCkgeworICAgICAgICBUZXN0U1NMU2Vzc2lvbnMgcyA9IFRlc3RTU0xTZXNzaW9ucy5jcmVhdGUoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChzLmludmFsaWQuZ2V0U2Vzc2lvbkNvbnRleHQoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwocy5zZXJ2ZXIuZ2V0U2Vzc2lvbkNvbnRleHQoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwocy5jbGllbnQuZ2V0U2Vzc2lvbkNvbnRleHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzLnMuYy5zZXJ2ZXJDb250ZXh0LmdldFNlcnZlclNlc3Npb25Db250ZXh0KCksCisgICAgICAgICAgICAgICAgICAgICBzLnNlcnZlci5nZXRTZXNzaW9uQ29udGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMucy5jLmNsaWVudENvbnRleHQuZ2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKSwKKyAgICAgICAgICAgICAgICAgICAgIHMuY2xpZW50LmdldFNlc3Npb25Db250ZXh0KCkpOworICAgICAgICBhc3NlcnROb3RTYW1lKHMuc2VydmVyLmdldFNlc3Npb25Db250ZXh0KCksCisgICAgICAgICAgICAgICAgICAgICAgcy5jbGllbnQuZ2V0U2Vzc2lvbkNvbnRleHQoKSk7CisgICAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNlc3Npb25fZ2V0VmFsdWUoKSB7CisgICAgICAgIFRlc3RTU0xTZXNzaW9ucyBzID0gVGVzdFNTTFNlc3Npb25zLmNyZWF0ZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5pbnZhbGlkLmdldFZhbHVlKG51bGwpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROdWxsKHMuaW52YWxpZC5nZXRWYWx1ZSgiQk9HVVMiKSk7CisgICAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNlc3Npb25fZ2V0VmFsdWVOYW1lcygpIHsKKyAgICAgICAgVGVzdFNTTFNlc3Npb25zIHMgPSBUZXN0U1NMU2Vzc2lvbnMuY3JlYXRlKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwocy5pbnZhbGlkLmdldFZhbHVlTmFtZXMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBzLmludmFsaWQuZ2V0VmFsdWVOYW1lcygpLmxlbmd0aCk7CisgICAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNlc3Npb25faW52YWxpZGF0ZSgpIHsKKyAgICAgICAgVGVzdFNTTFNlc3Npb25zIHMgPSBUZXN0U1NMU2Vzc2lvbnMuY3JlYXRlKCk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2Uocy5pbnZhbGlkLmlzVmFsaWQoKSk7CisgICAgICAgIHMuaW52YWxpZC5pbnZhbGlkYXRlKCk7CisgICAgICAgIGFzc2VydEZhbHNlKHMuaW52YWxpZC5pc1ZhbGlkKCkpOworICAgICAgICBhc3NlcnROdWxsKHMuaW52YWxpZC5nZXRTZXNzaW9uQ29udGV4dCgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKHMuc2VydmVyLmlzVmFsaWQoKSk7CisgICAgICAgIHMuc2VydmVyLmludmFsaWRhdGUoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uocy5zZXJ2ZXIuaXNWYWxpZCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChzLnNlcnZlci5nZXRTZXNzaW9uQ29udGV4dCgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKHMuY2xpZW50LmlzVmFsaWQoKSk7CisgICAgICAgIHMuY2xpZW50LmludmFsaWRhdGUoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uocy5jbGllbnQuaXNWYWxpZCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChzLmNsaWVudC5nZXRTZXNzaW9uQ29udGV4dCgpKTsKKworICAgICAgICBzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTZXNzaW9uX2lzVmFsaWQoKSB7CisgICAgICAgIFRlc3RTU0xTZXNzaW9ucyBzID0gVGVzdFNTTFNlc3Npb25zLmNyZWF0ZSgpOworICAgICAgICBhc3NlcnRGYWxzZShzLmludmFsaWQuaXNWYWxpZCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzLnNlcnZlci5pc1ZhbGlkKCkpOworICAgICAgICBhc3NlcnRUcnVlKHMuY2xpZW50LmlzVmFsaWQoKSk7CisgICAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNlc3Npb25fcHV0VmFsdWUoKSB7CisgICAgICAgIFRlc3RTU0xTZXNzaW9ucyBzID0gVGVzdFNTTFNlc3Npb25zLmNyZWF0ZSgpOworICAgICAgICBTdHJpbmcga2V5ID0gIktFWSI7CisgICAgICAgIFN0cmluZyB2YWx1ZSA9ICJWQUxVRSI7CisgICAgICAgIGFzc2VydE51bGwocy5pbnZhbGlkLmdldFZhbHVlKGtleSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgcy5pbnZhbGlkLmdldFZhbHVlTmFtZXMoKS5sZW5ndGgpOworICAgICAgICBzLmludmFsaWQucHV0VmFsdWUoa2V5LCB2YWx1ZSk7CisgICAgICAgIGFzc2VydFNhbWUodmFsdWUsIHMuaW52YWxpZC5nZXRWYWx1ZShrZXkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHMuaW52YWxpZC5nZXRWYWx1ZU5hbWVzKCkubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGtleSwgcy5pbnZhbGlkLmdldFZhbHVlTmFtZXMoKVswXSk7CisgICAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNlc3Npb25fcmVtb3ZlVmFsdWUoKSB7CisgICAgICAgIFRlc3RTU0xTZXNzaW9ucyBzID0gVGVzdFNTTFNlc3Npb25zLmNyZWF0ZSgpOworICAgICAgICBTdHJpbmcga2V5ID0gIktFWSI7CisgICAgICAgIFN0cmluZyB2YWx1ZSA9ICJWQUxVRSI7CisgICAgICAgIHMuaW52YWxpZC5wdXRWYWx1ZShrZXksIHZhbHVlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHMuaW52YWxpZC5nZXRWYWx1ZU5hbWVzKCkubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGtleSwgcy5pbnZhbGlkLmdldFZhbHVlTmFtZXMoKVswXSk7CisgICAgICAgIHMuaW52YWxpZC5yZW1vdmVWYWx1ZShrZXkpOworICAgICAgICBhc3NlcnROdWxsKHMuaW52YWxpZC5nZXRWYWx1ZShrZXkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHMuaW52YWxpZC5nZXRWYWx1ZU5hbWVzKCkubGVuZ3RoKTsKKyAgICAgICAgcy5jbG9zZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvU1NMU29ja2V0RmFjdG9yeVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvU1NMU29ja2V0RmFjdG9yeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNGE1NGZkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvbmV0L3NzbC9TU0xTb2NrZXRGYWN0b3J5VGVzdC5qYXZhCkBAIC0wLDAgKzEsNzcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0RXhjZXB0aW9uOworaW1wb3J0IGxpYmNvcmUuamF2YS5zZWN1cml0eS5TdGFuZGFyZE5hbWVzOworaW1wb3J0IGphdmF4Lm5ldC5TZXJ2ZXJTb2NrZXRGYWN0b3J5OworaW1wb3J0IGphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0RmFjdG9yeTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBTU0xTb2NrZXRGYWN0b3J5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldEZhY3RvcnlfZ2V0RGVmYXVsdCgpIHsKKyAgICAgICAgU29ja2V0RmFjdG9yeSBzZiA9IFNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKHNmKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShTU0xTb2NrZXRGYWN0b3J5LmNsYXNzLmlzQXNzaWduYWJsZUZyb20oc2YuZ2V0Q2xhc3MoKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU29ja2V0RmFjdG9yeV9nZXREZWZhdWx0Q2lwaGVyU3VpdGVzKCkgeworICAgICAgICBTU0xTb2NrZXRGYWN0b3J5IHNmID0gKFNTTFNvY2tldEZhY3RvcnkpIFNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworICAgICAgICBTdHJpbmdbXSBjaXBoZXJTdWl0ZXMgPSBzZi5nZXREZWZhdWx0Q2lwaGVyU3VpdGVzKCk7CisgICAgICAgIFN0YW5kYXJkTmFtZXMuYXNzZXJ0RGVmYXVsdENpcGhlclN1aXRlcyhjaXBoZXJTdWl0ZXMpOworICAgICAgICBhc3NlcnROb3RTYW1lKGNpcGhlclN1aXRlcywgc2YuZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldEZhY3RvcnlfZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkgeworICAgICAgICBTU0xTb2NrZXRGYWN0b3J5IHNmID0gKFNTTFNvY2tldEZhY3RvcnkpIFNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworICAgICAgICBTdHJpbmdbXSBjaXBoZXJTdWl0ZXMgPSBzZi5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKTsKKyAgICAgICAgU3RhbmRhcmROYW1lcy5hc3NlcnRWYWxpZENpcGhlclN1aXRlcyhTdGFuZGFyZE5hbWVzLkNJUEhFUl9TVUlURVMsIGNpcGhlclN1aXRlcyk7CisgICAgICAgIGFzc2VydE5vdFNhbWUoY2lwaGVyU3VpdGVzLCBzZi5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTb2NrZXRGYWN0b3J5X2NyZWF0ZVNvY2tldCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMU29ja2V0RmFjdG9yeSBzZiA9IChTU0xTb2NrZXRGYWN0b3J5KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKyAgICAgICAgICAgIFNvY2tldCBzID0gc2YuY3JlYXRlU29ja2V0KG51bGwsIG51bGwsIC0xLCBmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMU29ja2V0RmFjdG9yeSBzZiA9IChTU0xTb2NrZXRGYWN0b3J5KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKyAgICAgICAgICAgIFNvY2tldCBzc2wgPSBzZi5jcmVhdGVTb2NrZXQobmV3IFNvY2tldCgpLCBudWxsLCAtMSwgZmFsc2UpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIFNlcnZlclNvY2tldCBzcyA9IFNlcnZlclNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpLmNyZWF0ZVNlcnZlclNvY2tldCgwKTsKKyAgICAgICAgSW5ldFNvY2tldEFkZHJlc3Mgc2EgPSAoSW5ldFNvY2tldEFkZHJlc3MpIHNzLmdldExvY2FsU29ja2V0QWRkcmVzcygpOworICAgICAgICBJbmV0QWRkcmVzcyBob3N0ID0gc2EuZ2V0QWRkcmVzcygpOworICAgICAgICBpbnQgcG9ydCA9IHNhLmdldFBvcnQoKTsKKyAgICAgICAgU29ja2V0IHMgPSBuZXcgU29ja2V0KGhvc3QsIHBvcnQpOworICAgICAgICBTU0xTb2NrZXRGYWN0b3J5IHNmID0gKFNTTFNvY2tldEZhY3RvcnkpIFNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworICAgICAgICBTb2NrZXQgc3NsID0gc2YuY3JlYXRlU29ja2V0KHMsIG51bGwsIC0xLCBmYWxzZSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoc3NsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShTU0xTb2NrZXQuY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShzc2wuZ2V0Q2xhc3MoKSkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvU1NMU29ja2V0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvbmV0L3NzbC9TU0xTb2NrZXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTBjZGViOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvU1NMU29ja2V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTE5NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5TZXJ2ZXJTb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0OworaW1wb3J0IGphdmEubmV0LlNvY2tldEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRUaW1lb3V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5IYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleU1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xDb250ZXh0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMSGFuZHNoYWtlRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMSGFuZHNoYWtlRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMUHJvdG9jb2xFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0RmFjdG9yeTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlg1MDlLZXlNYW5hZ2VyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuU3RhbmRhcmROYW1lczsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuVGVzdEtleVN0b3JlOworCitwdWJsaWMgY2xhc3MgU1NMU29ja2V0VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU29ja2V0X2dldFN1cHBvcnRlZENpcGhlclN1aXRlc19uYW1lcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTU0xTb2NrZXRGYWN0b3J5IHNmID0gKFNTTFNvY2tldEZhY3RvcnkpIFNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworICAgICAgICBTU0xTb2NrZXQgc3NsID0gKFNTTFNvY2tldCkgc2YuY3JlYXRlU29ja2V0KCk7CisgICAgICAgIFN0cmluZ1tdIGNpcGhlclN1aXRlcyA9IHNzbC5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKTsKKyAgICAgICAgU3RhbmRhcmROYW1lcy5hc3NlcnRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoU3RhbmRhcmROYW1lcy5DSVBIRVJfU1VJVEVTLCBjaXBoZXJTdWl0ZXMpOworICAgICAgICBhc3NlcnROb3RTYW1lKGNpcGhlclN1aXRlcywgc3NsLmdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF9nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXNfY29ubmVjdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBub3RlIHRoZSByYXJlIHVzYWdlIG9mIG5vbi1SU0Ega2V5cworICAgICAgICBUZXN0S2V5U3RvcmUgdGVzdEtleVN0b3JlID0gbmV3IFRlc3RLZXlTdG9yZS5CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAua2V5QWxnb3JpdGhtcygiUlNBIiwgIkRTQSIsICJFQyIsICJFQ19SU0EiKQorICAgICAgICAgICAgICAgIC5hbGlhc1ByZWZpeCgicnNhLWRzYS1lYyIpCisgICAgICAgICAgICAgICAgLmNhKHRydWUpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgICAgIGlmIChTdGFuZGFyZE5hbWVzLklTX1JJKSB7CisgICAgICAgICAgICB0ZXN0X1NTTFNvY2tldF9nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXNfY29ubmVjdCh0ZXN0S2V5U3RvcmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFuZGFyZE5hbWVzLkpTU0VfUFJPVklERVJfTkFNRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YW5kYXJkTmFtZXMuSlNTRV9QUk9WSURFUl9OQU1FLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgICAgICB9IGVsc2UgIHsKKyAgICAgICAgICAgIHRlc3RfU1NMU29ja2V0X2dldFN1cHBvcnRlZENpcGhlclN1aXRlc19jb25uZWN0KHRlc3RLZXlTdG9yZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJIYXJtb255SlNTRSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSGFybW9ueUpTU0UiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7CisgICAgICAgICAgICB0ZXN0X1NTTFNvY2tldF9nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXNfY29ubmVjdCh0ZXN0S2V5U3RvcmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQW5kcm9pZE9wZW5TU0wiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFuZHJvaWRPcGVuU1NMIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICAgICAgICAgIHRlc3RfU1NMU29ja2V0X2dldFN1cHBvcnRlZENpcGhlclN1aXRlc19jb25uZWN0KHRlc3RLZXlTdG9yZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJIYXJtb255SlNTRSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQW5kcm9pZE9wZW5TU0wiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICAgICAgICAgIHRlc3RfU1NMU29ja2V0X2dldFN1cHBvcnRlZENpcGhlclN1aXRlc19jb25uZWN0KHRlc3RLZXlTdG9yZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBbmRyb2lkT3BlblNTTCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSGFybW9ueUpTU0UiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKKyAgICAgICAgfQorCisgICAgfQorICAgIHByaXZhdGUgdm9pZCB0ZXN0X1NTTFNvY2tldF9nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXNfY29ubmVjdChUZXN0S2V5U3RvcmUgdGVzdEtleVN0b3JlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2xpZW50UHJvdmlkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzZXJ2ZXJQcm92aWRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjbGllbnRTZWN1cmVSZW5lZ290aWF0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHNlcnZlclNlY3VyZVJlbmVnb3RpYXRpb24pCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBTdHJpbmcgY2xpZW50VG9TZXJ2ZXJTdHJpbmcgPSAidGhpcyBpcyBzZW50IGZyb20gdGhlIGNsaWVudCB0byB0aGUgc2VydmVyLi4uIjsKKyAgICAgICAgU3RyaW5nIHNlcnZlclRvQ2xpZW50U3RyaW5nID0gIi4uLiBhbmQgdGhpcyBmcm9tIHRoZSBzZXJ2ZXIgdG8gdGhlIGNsaWVudCI7CisgICAgICAgIGJ5dGVbXSBjbGllbnRUb1NlcnZlciA9IGNsaWVudFRvU2VydmVyU3RyaW5nLmdldEJ5dGVzKCk7CisgICAgICAgIGJ5dGVbXSBzZXJ2ZXJUb0NsaWVudCA9IHNlcnZlclRvQ2xpZW50U3RyaW5nLmdldEJ5dGVzKCk7CisKKyAgICAgICAgVGVzdFNTTENvbnRleHQgYyA9IFRlc3RTU0xDb250ZXh0LmNyZWF0ZSh0ZXN0S2V5U3RvcmUsIHRlc3RLZXlTdG9yZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRQcm92aWRlciwgc2VydmVyUHJvdmlkZXIpOworICAgICAgICBTdHJpbmdbXSBjaXBoZXJTdWl0ZXM7CisgICAgICAgIGlmIChjbGllbnRQcm92aWRlci5lcXVhbHMoc2VydmVyUHJvdmlkZXIpKSB7CisgICAgICAgICAgICBjaXBoZXJTdWl0ZXMgPSBjLmNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLmdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgU3RyaW5nW10gY2xpZW50U3VpdGVzID0gYy5jbGllbnRDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKS5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKTsKKyAgICAgICAgICAgIFN0cmluZ1tdIHNlcnZlclN1aXRlcyA9IGMuc2VydmVyQ29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgICAgICAgICBTZXQ8U3RyaW5nPiBjY3MgPSBuZXcgSGFzaFNldDxTdHJpbmc+KEFycmF5cy5hc0xpc3QoY2xpZW50U3VpdGVzKSk7CisgICAgICAgICAgICBTZXQ8U3RyaW5nPiBzY3MgPSBuZXcgSGFzaFNldDxTdHJpbmc+KEFycmF5cy5hc0xpc3Qoc2VydmVyU3VpdGVzKSk7CisgICAgICAgICAgICBTZXQ8U3RyaW5nPiBjcyA9IG5ldyBIYXNoU2V0PFN0cmluZz4oY2NzKTsKKyAgICAgICAgICAgIGNzLnJldGFpbkFsbChzY3MpOworICAgICAgICAgICAgY2lwaGVyU3VpdGVzID0gY3MudG9BcnJheShuZXcgU3RyaW5nW2NzLnNpemUoKV0pOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChTdHJpbmcgY2lwaGVyU3VpdGUgOiBjaXBoZXJTdWl0ZXMpIHsKKyAgICAgICAgICAgIGJvb2xlYW4gZXJyb3JFeHBlY3RlZCA9IFN0YW5kYXJkTmFtZXMuSVNfUkkgJiYgY2lwaGVyU3VpdGUuZW5kc1dpdGgoIl9TSEEyNTYiKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgKiBUTFNfRU1QVFlfUkVORUdPVElBVElPTl9JTkZPX1NDU1YgY2Fubm90IGJlIHVzZWQgb24KKyAgICAgICAgICAgICAgICAgKiBpdHMgb3duLCBidXQgaW5zdGVhZCBpbiBjb25qdW5jdGlvbiB3aXRoIG90aGVyCisgICAgICAgICAgICAgICAgICogY2lwaGVyIHN1aXRlcy4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBpZiAoY2lwaGVyU3VpdGUuZXF1YWxzKFN0YW5kYXJkTmFtZXMuQ0lQSEVSX1NVSVRFX1NFQ1VSRV9SRU5FR09USUFUSU9OKSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgKiBLZXJiZXJvcyBjaXBoZXIgc3VpdGVzIHJlcXVpcmUgZXh0ZXJuYWwgc2V0dXAuIFNlZSAiS2VyYmVyb3MgUmVxdWlyZW1lbnRzIiBpbgorICAgICAgICAgICAgICAgICAqIGh0dHBzOi8vamF2YS5zdW4uY29tL2oyc2UvMS41LjAvZG9jcy9ndWlkZS9zZWN1cml0eS9qc3NlL0pTU0VSZWZHdWlkZS5odG1sCisgICAgICAgICAgICAgICAgICogI0tSQlJlcXVpcmUKKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBpZiAoY2lwaGVyU3VpdGUuc3RhcnRzV2l0aCgiVExTX0tSQjVfIikpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgU3RyaW5nW10gY2xpZW50Q2lwaGVyU3VpdGVBcnJheQorICAgICAgICAgICAgICAgICAgICAgICAgPSAoY2xpZW50U2VjdXJlUmVuZWdvdGlhdGlvbgorICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXcgU3RyaW5nW10geyBjaXBoZXJTdWl0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhbmRhcmROYW1lcy5DSVBIRVJfU1VJVEVfU0VDVVJFX1JFTkVHT1RJQVRJT04gfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBuZXcgU3RyaW5nW10geyBjaXBoZXJTdWl0ZSB9KTsKKyAgICAgICAgICAgICAgICBTdHJpbmdbXSBzZXJ2ZXJDaXBoZXJTdWl0ZUFycmF5CisgICAgICAgICAgICAgICAgICAgICAgICA9IChzZXJ2ZXJTZWN1cmVSZW5lZ290aWF0aW9uCisgICAgICAgICAgICAgICAgICAgICAgICAgICA/IG5ldyBTdHJpbmdbXSB7IGNpcGhlclN1aXRlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFuZGFyZE5hbWVzLkNJUEhFUl9TVUlURV9TRUNVUkVfUkVORUdPVElBVElPTiB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG5ldyBTdHJpbmdbXSB7IGNpcGhlclN1aXRlIH0pOworICAgICAgICAgICAgICAgIFNTTFNvY2tldFtdIHBhaXIgPSBUZXN0U1NMU29ja2V0UGFpci5jb25uZWN0KGMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50Q2lwaGVyU3VpdGVBcnJheSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJDaXBoZXJTdWl0ZUFycmF5KTsKKworICAgICAgICAgICAgICAgIFNTTFNvY2tldCBzZXJ2ZXIgPSBwYWlyWzBdOworICAgICAgICAgICAgICAgIFNTTFNvY2tldCBjbGllbnQgPSBwYWlyWzFdOworICAgICAgICAgICAgICAgIHNlcnZlci5nZXRPdXRwdXRTdHJlYW0oKS53cml0ZShzZXJ2ZXJUb0NsaWVudCk7CisgICAgICAgICAgICAgICAgY2xpZW50LmdldE91dHB1dFN0cmVhbSgpLndyaXRlKGNsaWVudFRvU2VydmVyKTsKKyAgICAgICAgICAgICAgICAvLyBhcnJheXMgYXJlIHRvbyBiaWcgdG8gbWFrZSBzdXJlIHdlIGdldCBiYWNrIG9ubHkgd2hhdCB3ZSBleHBlY3QKKyAgICAgICAgICAgICAgICBieXRlW10gY2xpZW50RnJvbVNlcnZlciA9IG5ldyBieXRlW3NlcnZlclRvQ2xpZW50Lmxlbmd0aCsxXTsKKyAgICAgICAgICAgICAgICBieXRlW10gc2VydmVyRnJvbUNsaWVudCA9IG5ldyBieXRlW2NsaWVudFRvU2VydmVyLmxlbmd0aCsxXTsKKyAgICAgICAgICAgICAgICBpbnQgcmVhZEZyb21TZXJ2ZXIgPSBjbGllbnQuZ2V0SW5wdXRTdHJlYW0oKS5yZWFkKGNsaWVudEZyb21TZXJ2ZXIpOworICAgICAgICAgICAgICAgIGludCByZWFkRnJvbUNsaWVudCA9IHNlcnZlci5nZXRJbnB1dFN0cmVhbSgpLnJlYWQoc2VydmVyRnJvbUNsaWVudCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHNlcnZlclRvQ2xpZW50Lmxlbmd0aCwgcmVhZEZyb21TZXJ2ZXIpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhjbGllbnRUb1NlcnZlci5sZW5ndGgsIHJlYWRGcm9tQ2xpZW50KTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoY2xpZW50VG9TZXJ2ZXJTdHJpbmcsIG5ldyBTdHJpbmcoc2VydmVyRnJvbUNsaWVudCwgMCwgcmVhZEZyb21DbGllbnQpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoc2VydmVyVG9DbGllbnRTdHJpbmcsIG5ldyBTdHJpbmcoY2xpZW50RnJvbVNlcnZlciwgMCwgcmVhZEZyb21TZXJ2ZXIpKTsKKyAgICAgICAgICAgICAgICBjbGllbnQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShlcnJvckV4cGVjdGVkKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBtYXliZUV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgaWYgKCFlcnJvckV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlByb2JsZW0gdHJ5aW5nIHRvIGNvbm5lY3QgY2lwaGVyIHN1aXRlICIgKyBjaXBoZXJTdWl0ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBjbGllbnQ9IiArIGNsaWVudFByb3ZpZGVyCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIHNlcnZlcj0iICsgc2VydmVyUHJvdmlkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF5YmVFeHBlY3RlZCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF9nZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNTTFNvY2tldEZhY3Rvcnkgc2YgPSAoU1NMU29ja2V0RmFjdG9yeSkgU1NMU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCk7CisgICAgICAgIFNTTFNvY2tldCBzc2wgPSAoU1NMU29ja2V0KSBzZi5jcmVhdGVTb2NrZXQoKTsKKyAgICAgICAgU3RyaW5nW10gY2lwaGVyU3VpdGVzID0gc3NsLmdldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKTsKKyAgICAgICAgU3RhbmRhcmROYW1lcy5hc3NlcnRWYWxpZENpcGhlclN1aXRlcyhTdGFuZGFyZE5hbWVzLkNJUEhFUl9TVUlURVMsIGNpcGhlclN1aXRlcyk7CisgICAgICAgIGFzc2VydE5vdFNhbWUoY2lwaGVyU3VpdGVzLCBzc2wuZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF9zZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNTTFNvY2tldEZhY3Rvcnkgc2YgPSAoU1NMU29ja2V0RmFjdG9yeSkgU1NMU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCk7CisgICAgICAgIFNTTFNvY2tldCBzc2wgPSAoU1NMU29ja2V0KSBzZi5jcmVhdGVTb2NrZXQoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NsLnNldEVuYWJsZWRDaXBoZXJTdWl0ZXMobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2wuc2V0RW5hYmxlZENpcGhlclN1aXRlcyhuZXcgU3RyaW5nWzFdKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzbC5zZXRFbmFibGVkQ2lwaGVyU3VpdGVzKG5ldyBTdHJpbmdbXSB7ICJCb2d1cyIgfSApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHNzbC5zZXRFbmFibGVkQ2lwaGVyU3VpdGVzKG5ldyBTdHJpbmdbMF0pOworICAgICAgICBzc2wuc2V0RW5hYmxlZENpcGhlclN1aXRlcyhzc2wuZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpKTsKKyAgICAgICAgc3NsLnNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoc3NsLmdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF9nZXRTdXBwb3J0ZWRQcm90b2NvbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMU29ja2V0RmFjdG9yeSBzZiA9IChTU0xTb2NrZXRGYWN0b3J5KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKyAgICAgICAgU1NMU29ja2V0IHNzbCA9IChTU0xTb2NrZXQpIHNmLmNyZWF0ZVNvY2tldCgpOworICAgICAgICBTdHJpbmdbXSBwcm90b2NvbHMgPSBzc2wuZ2V0U3VwcG9ydGVkUHJvdG9jb2xzKCk7CisgICAgICAgIFN0YW5kYXJkTmFtZXMuYXNzZXJ0U3VwcG9ydGVkUHJvdG9jb2xzKFN0YW5kYXJkTmFtZXMuU1NMX1NPQ0tFVF9QUk9UT0NPTFMsIHByb3RvY29scyk7CisgICAgICAgIGFzc2VydE5vdFNhbWUocHJvdG9jb2xzLCBzc2wuZ2V0U3VwcG9ydGVkUHJvdG9jb2xzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU29ja2V0X2dldEVuYWJsZWRQcm90b2NvbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMU29ja2V0RmFjdG9yeSBzZiA9IChTU0xTb2NrZXRGYWN0b3J5KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKyAgICAgICAgU1NMU29ja2V0IHNzbCA9IChTU0xTb2NrZXQpIHNmLmNyZWF0ZVNvY2tldCgpOworICAgICAgICBTdHJpbmdbXSBwcm90b2NvbHMgPSBzc2wuZ2V0RW5hYmxlZFByb3RvY29scygpOworICAgICAgICBTdGFuZGFyZE5hbWVzLmFzc2VydFZhbGlkUHJvdG9jb2xzKFN0YW5kYXJkTmFtZXMuU1NMX1NPQ0tFVF9QUk9UT0NPTFMsIHByb3RvY29scyk7CisgICAgICAgIGFzc2VydE5vdFNhbWUocHJvdG9jb2xzLCBzc2wuZ2V0RW5hYmxlZFByb3RvY29scygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF9zZXRFbmFibGVkUHJvdG9jb2xzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNTTFNvY2tldEZhY3Rvcnkgc2YgPSAoU1NMU29ja2V0RmFjdG9yeSkgU1NMU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCk7CisgICAgICAgIFNTTFNvY2tldCBzc2wgPSAoU1NMU29ja2V0KSBzZi5jcmVhdGVTb2NrZXQoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NsLnNldEVuYWJsZWRQcm90b2NvbHMobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2wuc2V0RW5hYmxlZFByb3RvY29scyhuZXcgU3RyaW5nWzFdKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzbC5zZXRFbmFibGVkUHJvdG9jb2xzKG5ldyBTdHJpbmdbXSB7ICJCb2d1cyIgfSApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBzc2wuc2V0RW5hYmxlZFByb3RvY29scyhuZXcgU3RyaW5nWzBdKTsKKyAgICAgICAgc3NsLnNldEVuYWJsZWRQcm90b2NvbHMoc3NsLmdldEVuYWJsZWRQcm90b2NvbHMoKSk7CisgICAgICAgIHNzbC5zZXRFbmFibGVkUHJvdG9jb2xzKHNzbC5nZXRTdXBwb3J0ZWRQcm90b2NvbHMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTb2NrZXRfZ2V0U2Vzc2lvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTU0xTb2NrZXRGYWN0b3J5IHNmID0gKFNTTFNvY2tldEZhY3RvcnkpIFNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworICAgICAgICBTU0xTb2NrZXQgc3NsID0gKFNTTFNvY2tldCkgc2YuY3JlYXRlU29ja2V0KCk7CisgICAgICAgIFNTTFNlc3Npb24gc2Vzc2lvbiA9IHNzbC5nZXRTZXNzaW9uKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoc2Vzc2lvbik7CisgICAgICAgIGFzc2VydEZhbHNlKHNlc3Npb24uaXNWYWxpZCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF9zdGFydEhhbmRzaGFrZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBUZXN0U1NMQ29udGV4dCBjID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIFNTTFNvY2tldCBjbGllbnQgPSAoU1NMU29ja2V0KSBjLmNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLmNyZWF0ZVNvY2tldChjLmhvc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLnBvcnQpOworICAgICAgICBmaW5hbCBTU0xTb2NrZXQgc2VydmVyID0gKFNTTFNvY2tldCkgYy5zZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgIFRocmVhZCB0aHJlYWQgPSBuZXcgVGhyZWFkKG5ldyBSdW5uYWJsZSAoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc2VydmVyLnN0YXJ0SGFuZHNoYWtlKCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc2VydmVyLmdldFNlc3Npb24oKSk7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXIuZ2V0U2Vzc2lvbigpLmdldFBlZXJDZXJ0aWZpY2F0ZXMoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZVtdIGxvY2FsQ2VydGlmaWNhdGVzID0gc2VydmVyLmdldFNlc3Npb24oKS5nZXRMb2NhbENlcnRpZmljYXRlcygpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGxvY2FsQ2VydGlmaWNhdGVzKTsKKyAgICAgICAgICAgICAgICAgICAgVGVzdEtleVN0b3JlLmFzc2VydENoYWluTGVuZ3RoKGxvY2FsQ2VydGlmaWNhdGVzKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChsb2NhbENlcnRpZmljYXRlc1swXSk7CisgICAgICAgICAgICAgICAgICAgIFRlc3RTU0xDb250ZXh0LmFzc2VydFNlcnZlckNlcnRpZmljYXRlQ2hhaW4oYy5zZXJ2ZXJUcnVzdE1hbmFnZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDZXJ0aWZpY2F0ZXMpOworICAgICAgICAgICAgICAgICAgICBUZXN0U1NMQ29udGV4dC5hc3NlcnRDZXJ0aWZpY2F0ZUluS2V5U3RvcmUobG9jYWxDZXJ0aWZpY2F0ZXNbMF0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLnNlcnZlcktleVN0b3JlKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgICAgICB0aHJlYWQuc3RhcnQoKTsKKyAgICAgICAgY2xpZW50LnN0YXJ0SGFuZHNoYWtlKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoY2xpZW50LmdldFNlc3Npb24oKSk7CisgICAgICAgIGFzc2VydE51bGwoY2xpZW50LmdldFNlc3Npb24oKS5nZXRMb2NhbENlcnRpZmljYXRlcygpKTsKKyAgICAgICAgQ2VydGlmaWNhdGVbXSBwZWVyQ2VydGlmaWNhdGVzID0gY2xpZW50LmdldFNlc3Npb24oKS5nZXRQZWVyQ2VydGlmaWNhdGVzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwocGVlckNlcnRpZmljYXRlcyk7CisgICAgICAgIFRlc3RLZXlTdG9yZS5hc3NlcnRDaGFpbkxlbmd0aChwZWVyQ2VydGlmaWNhdGVzKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChwZWVyQ2VydGlmaWNhdGVzWzBdKTsKKyAgICAgICAgVGVzdFNTTENvbnRleHQuYXNzZXJ0U2VydmVyQ2VydGlmaWNhdGVDaGFpbihjLmNsaWVudFRydXN0TWFuYWdlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZWVyQ2VydGlmaWNhdGVzKTsKKyAgICAgICAgVGVzdFNTTENvbnRleHQuYXNzZXJ0Q2VydGlmaWNhdGVJbktleVN0b3JlKHBlZXJDZXJ0aWZpY2F0ZXNbMF0sIGMuc2VydmVyS2V5U3RvcmUpOworICAgICAgICB0aHJlYWQuam9pbigpOworICAgICAgICBjbGllbnQuY2xvc2UoKTsKKyAgICAgICAgc2VydmVyLmNsb3NlKCk7CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF9zdGFydEhhbmRzaGFrZV9ub0tleVN0b3JlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xDb250ZXh0LmdldERlZmF1bHQoKSwgU1NMQ29udGV4dC5nZXREZWZhdWx0KCkpOworICAgICAgICBTU0xTb2NrZXQgY2xpZW50ID0gKFNTTFNvY2tldCkgYy5jbGllbnRDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKS5jcmVhdGVTb2NrZXQoYy5ob3N0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5wb3J0KTsKKyAgICAgICAgLy8gUkkgdXNlZCB0byB0aHJvdyBTU0xFeGNlcHRpb24gb24gYWNjZXB0LCBub3cgdGhyb3dzIG9uIHN0YXJ0SGFuZHNoYWtlCisgICAgICAgIGlmIChTdGFuZGFyZE5hbWVzLklTX1JJKSB7CisgICAgICAgICAgICBmaW5hbCBTU0xTb2NrZXQgc2VydmVyID0gKFNTTFNvY2tldCkgYy5zZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgICAgICBUaHJlYWQgdGhyZWFkID0gbmV3IFRocmVhZChuZXcgUnVubmFibGUgKCkgeworICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZlci5zdGFydEhhbmRzaGFrZSgpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChTU0xIYW5kc2hha2VFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKyAgICAgICAgICAgIHRocmVhZC5zdGFydCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjbGllbnQuc3RhcnRIYW5kc2hha2UoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTU0xIYW5kc2hha2VFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocmVhZC5qb2luKCk7CisgICAgICAgICAgICBzZXJ2ZXIuY2xvc2UoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYy5zZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1NMRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY2xpZW50LmNsb3NlKCk7CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF9zdGFydEhhbmRzaGFrZV9ub0NsaWVudENlcnRpZmljYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgU1NMQ29udGV4dCBzZXJ2ZXJDb250ZXh0ID0gYy5zZXJ2ZXJDb250ZXh0OworICAgICAgICBTU0xDb250ZXh0IGNsaWVudENvbnRleHQgPSBjLmNsaWVudENvbnRleHQ7CisgICAgICAgIFNTTFNvY2tldCBjbGllbnQgPSAoU1NMU29ja2V0KQorICAgICAgICAgICAgY2xpZW50Q29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkuY3JlYXRlU29ja2V0KGMuaG9zdCwgYy5wb3J0KTsKKyAgICAgICAgZmluYWwgU1NMU29ja2V0IHNlcnZlciA9IChTU0xTb2NrZXQpIGMuc2VydmVyU29ja2V0LmFjY2VwdCgpOworICAgICAgICBUaHJlYWQgdGhyZWFkID0gbmV3IFRocmVhZChuZXcgUnVubmFibGUgKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHNlcnZlci5zdGFydEhhbmRzaGFrZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIHRocmVhZC5zdGFydCgpOworICAgICAgICBjbGllbnQuc3RhcnRIYW5kc2hha2UoKTsKKyAgICAgICAgdGhyZWFkLmpvaW4oKTsKKyAgICAgICAgY2xpZW50LmNsb3NlKCk7CisgICAgICAgIHNlcnZlci5jbG9zZSgpOworICAgICAgICBjLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTb2NrZXRfSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgVGVzdFNTTENvbnRleHQgYyA9IFRlc3RTU0xDb250ZXh0LmNyZWF0ZSgpOworICAgICAgICBmaW5hbCBTU0xTb2NrZXQgY2xpZW50ID0gKFNTTFNvY2tldCkKKyAgICAgICAgICAgICAgICBjLmNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLmNyZWF0ZVNvY2tldChjLmhvc3QsIGMucG9ydCk7CisgICAgICAgIGZpbmFsIFNTTFNvY2tldCBzZXJ2ZXIgPSAoU1NMU29ja2V0KSBjLnNlcnZlclNvY2tldC5hY2NlcHQoKTsKKyAgICAgICAgVGhyZWFkIHRocmVhZCA9IG5ldyBUaHJlYWQobmV3IFJ1bm5hYmxlICgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzZXJ2ZXIuc3RhcnRIYW5kc2hha2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgICAgICB0aHJlYWQuc3RhcnQoKTsKKyAgICAgICAgZmluYWwgYm9vbGVhbltdIGhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyQ2FsbGVkID0gbmV3IGJvb2xlYW5bMV07CisgICAgICAgIGNsaWVudC5hZGRIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lcihuZXcgSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXIoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBoYW5kc2hha2VDb21wbGV0ZWQoSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQgZXZlbnQpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBTU0xTZXNzaW9uIHNlc3Npb24gPSBldmVudC5nZXRTZXNzaW9uKCk7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjaXBoZXJTdWl0ZSA9IGV2ZW50LmdldENpcGhlclN1aXRlKCk7CisgICAgICAgICAgICAgICAgICAgIENlcnRpZmljYXRlW10gbG9jYWxDZXJ0aWZpY2F0ZXMgPSBldmVudC5nZXRMb2NhbENlcnRpZmljYXRlcygpOworICAgICAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZVtdIHBlZXJDZXJ0aWZpY2F0ZXMgPSBldmVudC5nZXRQZWVyQ2VydGlmaWNhdGVzKCk7CisgICAgICAgICAgICAgICAgICAgIGphdmF4LnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlW10gcGVlckNlcnRpZmljYXRlQ2hhaW4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IGV2ZW50LmdldFBlZXJDZXJ0aWZpY2F0ZUNoYWluKCk7CisgICAgICAgICAgICAgICAgICAgIFByaW5jaXBhbCBwZWVyUHJpbmNpcGFsID0gZXZlbnQuZ2V0UGVlclByaW5jaXBhbCgpOworICAgICAgICAgICAgICAgICAgICBQcmluY2lwYWwgbG9jYWxQcmluY2lwYWwgPSBldmVudC5nZXRMb2NhbFByaW5jaXBhbCgpOworICAgICAgICAgICAgICAgICAgICBTb2NrZXQgc29ja2V0ID0gZXZlbnQuZ2V0U29ja2V0KCk7CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZhbHNlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlNlc3Npb249IiArIHNlc3Npb24pOworICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJDaXBoZXJTdWl0ZT0iICsgY2lwaGVyU3VpdGUpOworICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJMb2NhbENlcnRpZmljYXRlcz0iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgQXJyYXlzLnRvU3RyaW5nKGxvY2FsQ2VydGlmaWNhdGVzKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlBlZXJDZXJ0aWZpY2F0ZXM9IgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIEFycmF5cy50b1N0cmluZyhwZWVyQ2VydGlmaWNhdGVzKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlBlZXJDZXJ0aWZpY2F0ZUNoYWluPSIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBBcnJheXMudG9TdHJpbmcocGVlckNlcnRpZmljYXRlQ2hhaW4pKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUGVlclByaW5jaXBhbD0iICsgcGVlclByaW5jaXBhbCk7CisgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkxvY2FsUHJpbmNpcGFsPSIgKyBsb2NhbFByaW5jaXBhbCk7CisgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlNvY2tldD0iICsgc29ja2V0KTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc2Vzc2lvbik7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBpZCA9IHNlc3Npb24uZ2V0SWQoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChpZCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygzMiwgaWQubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChjLmNsaWVudENvbnRleHQuZ2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKS5nZXRTZXNzaW9uKGlkKSk7CisKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChjaXBoZXJTdWl0ZSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmFzTGlzdCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnQuZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpKS5jb250YWlucyhjaXBoZXJTdWl0ZSkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5hc0xpc3QoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5zZXJ2ZXJTb2NrZXQuZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpKS5jb250YWlucyhjaXBoZXJTdWl0ZSkpOworCisgICAgICAgICAgICAgICAgICAgIGFzc2VydE51bGwobG9jYWxDZXJ0aWZpY2F0ZXMpOworCisgICAgICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwocGVlckNlcnRpZmljYXRlcyk7CisgICAgICAgICAgICAgICAgICAgIFRlc3RLZXlTdG9yZS5hc3NlcnRDaGFpbkxlbmd0aChwZWVyQ2VydGlmaWNhdGVzKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwZWVyQ2VydGlmaWNhdGVzWzBdKTsKKyAgICAgICAgICAgICAgICAgICAgVGVzdFNTTENvbnRleHQuYXNzZXJ0U2VydmVyQ2VydGlmaWNhdGVDaGFpbihjLmNsaWVudFRydXN0TWFuYWdlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZWVyQ2VydGlmaWNhdGVzKTsKKyAgICAgICAgICAgICAgICAgICAgVGVzdFNTTENvbnRleHQuYXNzZXJ0Q2VydGlmaWNhdGVJbktleVN0b3JlKHBlZXJDZXJ0aWZpY2F0ZXNbMF0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLnNlcnZlcktleVN0b3JlKTsKKworICAgICAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHBlZXJDZXJ0aWZpY2F0ZUNoYWluKTsKKyAgICAgICAgICAgICAgICAgICAgVGVzdEtleVN0b3JlLmFzc2VydENoYWluTGVuZ3RoKHBlZXJDZXJ0aWZpY2F0ZUNoYWluKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwZWVyQ2VydGlmaWNhdGVDaGFpblswXSk7CisgICAgICAgICAgICAgICAgICAgIFRlc3RTU0xDb250ZXh0LmFzc2VydENlcnRpZmljYXRlSW5LZXlTdG9yZSgKKyAgICAgICAgICAgICAgICAgICAgICAgIHBlZXJDZXJ0aWZpY2F0ZUNoYWluWzBdLmdldFN1YmplY3RETigpLCBjLnNlcnZlcktleVN0b3JlKTsKKworICAgICAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHBlZXJQcmluY2lwYWwpOworICAgICAgICAgICAgICAgICAgICBUZXN0U1NMQ29udGV4dC5hc3NlcnRDZXJ0aWZpY2F0ZUluS2V5U3RvcmUocGVlclByaW5jaXBhbCwgYy5zZXJ2ZXJLZXlTdG9yZSk7CisKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChsb2NhbFByaW5jaXBhbCk7CisKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChzb2NrZXQpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRTYW1lKGNsaWVudCwgc29ja2V0KTsKKworICAgICAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyQ2FsbGVkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBoYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lckNhbGxlZFswXSA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICBoYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lckNhbGxlZC5ub3RpZnkoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBoYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lckNhbGxlZFswXSA9IHRydWU7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAgICAgY2xpZW50LnN0YXJ0SGFuZHNoYWtlKCk7CisgICAgICAgIHRocmVhZC5qb2luKCk7CisgICAgICAgIGlmICghVGVzdFNTTENvbnRleHQuc3NsU2VydmVyU29ja2V0U3VwcG9ydHNTZXNzaW9uVGlja2V0cygpKSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGMuc2VydmVyQ29udGV4dC5nZXRTZXJ2ZXJTZXNzaW9uQ29udGV4dCgpLmdldFNlc3Npb24oCisgICAgICAgICAgICAgICAgICAgIGNsaWVudC5nZXRTZXNzaW9uKCkuZ2V0SWQoKSkpOworICAgICAgICB9CisgICAgICAgIHN5bmNocm9uaXplZCAoaGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXJDYWxsZWQpIHsKKyAgICAgICAgICAgIHdoaWxlICghaGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXJDYWxsZWRbMF0pIHsKKyAgICAgICAgICAgICAgICBoYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lckNhbGxlZC53YWl0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY2xpZW50LmNsb3NlKCk7CisgICAgICAgIHNlcnZlci5jbG9zZSgpOworICAgICAgICBjLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTb2NrZXRfSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXJfUnVudGltZUV4Y2VwdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBUZXN0U1NMQ29udGV4dCBjID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIGZpbmFsIFNTTFNvY2tldCBjbGllbnQgPSAoU1NMU29ja2V0KQorICAgICAgICAgICAgICAgIGMuY2xpZW50Q29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkuY3JlYXRlU29ja2V0KGMuaG9zdCwgYy5wb3J0KTsKKyAgICAgICAgZmluYWwgU1NMU29ja2V0IHNlcnZlciA9IChTU0xTb2NrZXQpIGMuc2VydmVyU29ja2V0LmFjY2VwdCgpOworICAgICAgICBUaHJlYWQgdGhyZWFkID0gbmV3IFRocmVhZChuZXcgUnVubmFibGUgKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHNlcnZlci5zdGFydEhhbmRzaGFrZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIHRocmVhZC5zdGFydCgpOworICAgICAgICBjbGllbnQuYWRkSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXIobmV3IEhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgaGFuZHNoYWtlQ29tcGxldGVkKEhhbmRzaGFrZUNvbXBsZXRlZEV2ZW50IGV2ZW50KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlJ1bnRpbWVFeGNlcHRpb24gZnJvbSBoYW5kc2hha2VDb21wbGV0ZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIGNsaWVudC5zdGFydEhhbmRzaGFrZSgpOworICAgICAgICB0aHJlYWQuam9pbigpOworICAgICAgICBjbGllbnQuY2xvc2UoKTsKKyAgICAgICAgc2VydmVyLmNsb3NlKCk7CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF9nZXRVc2VDbGllbnRNb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgU1NMU29ja2V0IGNsaWVudCA9IChTU0xTb2NrZXQpIGMuY2xpZW50Q29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkuY3JlYXRlU29ja2V0KGMuaG9zdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMucG9ydCk7CisgICAgICAgIFNTTFNvY2tldCBzZXJ2ZXIgPSAoU1NMU29ja2V0KSBjLnNlcnZlclNvY2tldC5hY2NlcHQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjbGllbnQuZ2V0VXNlQ2xpZW50TW9kZSgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2VydmVyLmdldFVzZUNsaWVudE1vZGUoKSk7CisgICAgICAgIGNsaWVudC5jbG9zZSgpOworICAgICAgICBzZXJ2ZXIuY2xvc2UoKTsKKyAgICAgICAgYy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU29ja2V0X3NldFVzZUNsaWVudE1vZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gY2xpZW50IGlzIGNsaWVudCwgc2VydmVyIGlzIHNlcnZlcgorICAgICAgICB0ZXN0X1NTTFNvY2tldF9zZXRVc2VDbGllbnRNb2RlKHRydWUsIGZhbHNlKTsKKyAgICAgICAgLy8gY2xpZW50IGlzIHNlcnZlciwgc2VydmVyIGlzIGNsaWVudAorICAgICAgICB0ZXN0X1NTTFNvY2tldF9zZXRVc2VDbGllbnRNb2RlKHRydWUsIGZhbHNlKTsKKyAgICAgICAgLy8gYm90aCBhcmUgY2xpZW50CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0X1NTTFNvY2tldF9zZXRVc2VDbGllbnRNb2RlKHRydWUsIHRydWUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTU0xQcm90b2NvbEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShTdGFuZGFyZE5hbWVzLklTX1JJKTsKKyAgICAgICAgfSBjYXRjaCAoU1NMSGFuZHNoYWtlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShTdGFuZGFyZE5hbWVzLklTX1JJKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGJvdGggYXJlIHNlcnZlcgorICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdF9TU0xTb2NrZXRfc2V0VXNlQ2xpZW50TW9kZShmYWxzZSwgZmFsc2UpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTb2NrZXRUaW1lb3V0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF9zZXRVc2VDbGllbnRNb2RlX2FmdGVySGFuZHNoYWtlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgLy8gY2FuJ3Qgc2V0IGFmdGVyIGhhbmRzaGFrZQorICAgICAgICBUZXN0U1NMRW5naW5lUGFpciBwYWlyID0gVGVzdFNTTEVuZ2luZVBhaXIuY3JlYXRlKG51bGwpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFpci5zZXJ2ZXIuc2V0VXNlQ2xpZW50TW9kZShmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYWlyLmNsaWVudC5zZXRVc2VDbGllbnRNb2RlKGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdF9TU0xTb2NrZXRfc2V0VXNlQ2xpZW50TW9kZShmaW5hbCBib29sZWFuIGNsaWVudENsaWVudE1vZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBzZXJ2ZXJDbGllbnRNb2RlKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgU1NMU29ja2V0IGNsaWVudCA9IChTU0xTb2NrZXQpIGMuY2xpZW50Q29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkuY3JlYXRlU29ja2V0KGMuaG9zdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMucG9ydCk7CisgICAgICAgIGZpbmFsIFNTTFNvY2tldCBzZXJ2ZXIgPSAoU1NMU29ja2V0KSBjLnNlcnZlclNvY2tldC5hY2NlcHQoKTsKKworICAgICAgICBmaW5hbCBTU0xIYW5kc2hha2VFeGNlcHRpb25bXSBzc2xIYW5kc2hha2VFeGNlcHRpb24gPSBuZXcgU1NMSGFuZHNoYWtlRXhjZXB0aW9uWzFdOworICAgICAgICBmaW5hbCBTb2NrZXRUaW1lb3V0RXhjZXB0aW9uW10gc29ja2V0VGltZW91dEV4Y2VwdGlvbiA9IG5ldyBTb2NrZXRUaW1lb3V0RXhjZXB0aW9uWzFdOworICAgICAgICBUaHJlYWQgdGhyZWFkID0gbmV3IFRocmVhZChuZXcgUnVubmFibGUgKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGlmICghc2VydmVyQ2xpZW50TW9kZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgc2VydmVyLnNldFNvVGltZW91dCgxICogMTAwMCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgc2VydmVyLnNldFVzZUNsaWVudE1vZGUoc2VydmVyQ2xpZW50TW9kZSk7CisgICAgICAgICAgICAgICAgICAgIHNlcnZlci5zdGFydEhhbmRzaGFrZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNTTEhhbmRzaGFrZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHNzbEhhbmRzaGFrZUV4Y2VwdGlvblswXSA9IGU7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU29ja2V0VGltZW91dEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHNvY2tldFRpbWVvdXRFeGNlcHRpb25bMF0gPSBlOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIHRocmVhZC5zdGFydCgpOworICAgICAgICBpZiAoIWNsaWVudENsaWVudE1vZGUpIHsKKyAgICAgICAgICAgIGNsaWVudC5zZXRTb1RpbWVvdXQoMSAqIDEwMDApOworICAgICAgICB9CisgICAgICAgIGNsaWVudC5zZXRVc2VDbGllbnRNb2RlKGNsaWVudENsaWVudE1vZGUpOworICAgICAgICBjbGllbnQuc3RhcnRIYW5kc2hha2UoKTsKKyAgICAgICAgdGhyZWFkLmpvaW4oKTsKKyAgICAgICAgaWYgKHNzbEhhbmRzaGFrZUV4Y2VwdGlvblswXSAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBzc2xIYW5kc2hha2VFeGNlcHRpb25bMF07CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNvY2tldFRpbWVvdXRFeGNlcHRpb25bMF0gIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgc29ja2V0VGltZW91dEV4Y2VwdGlvblswXTsKKyAgICAgICAgfQorICAgICAgICBjbGllbnQuY2xvc2UoKTsKKyAgICAgICAgc2VydmVyLmNsb3NlKCk7CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF91bnRydXN0ZWRTZXJ2ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgYyA9IFRlc3RTU0xDb250ZXh0LmNyZWF0ZShUZXN0S2V5U3RvcmUuZ2V0Q2xpZW50Q0EyKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGVzdEtleVN0b3JlLmdldFNlcnZlcigpKTsKKyAgICAgICAgU1NMU29ja2V0IGNsaWVudCA9IChTU0xTb2NrZXQpIGMuY2xpZW50Q29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkuY3JlYXRlU29ja2V0KGMuaG9zdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMucG9ydCk7CisgICAgICAgIGZpbmFsIFNTTFNvY2tldCBzZXJ2ZXIgPSAoU1NMU29ja2V0KSBjLnNlcnZlclNvY2tldC5hY2NlcHQoKTsKKyAgICAgICAgVGhyZWFkIHRocmVhZCA9IG5ldyBUaHJlYWQobmV3IFJ1bm5hYmxlICgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzZXJ2ZXIuc3RhcnRIYW5kc2hha2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChTU0xIYW5kc2hha2VFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgICAgICB0aHJlYWQuc3RhcnQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNsaWVudC5zdGFydEhhbmRzaGFrZSgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTU0xIYW5kc2hha2VFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZXhwZWN0ZWQuZ2V0Q2F1c2UoKSBpbnN0YW5jZW9mIENlcnRpZmljYXRlRXhjZXB0aW9uKTsKKyAgICAgICAgfQorICAgICAgICBjbGllbnQuY2xvc2UoKTsKKyAgICAgICAgc2VydmVyLmNsb3NlKCk7CisgICAgICAgIHRocmVhZC5qb2luKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTb2NrZXRfY2xpZW50QXV0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMQ29udGV4dCBjID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKFRlc3RLZXlTdG9yZS5nZXRDbGllbnRDZXJ0aWZpY2F0ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRlc3RLZXlTdG9yZS5nZXRTZXJ2ZXIoKSk7CisgICAgICAgIFNTTFNvY2tldCBjbGllbnQgPSAoU1NMU29ja2V0KSBjLmNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLmNyZWF0ZVNvY2tldChjLmhvc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLnBvcnQpOworICAgICAgICBmaW5hbCBTU0xTb2NrZXQgc2VydmVyID0gKFNTTFNvY2tldCkgYy5zZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgIFRocmVhZCB0aHJlYWQgPSBuZXcgVGhyZWFkKG5ldyBSdW5uYWJsZSAoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc2VydmVyLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShzZXJ2ZXIuZ2V0TmVlZENsaWVudEF1dGgoKSk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gY29uZmlybSB0dXJuaW5nIG9uZSBvbiBieSBpdHNlbGYKKyAgICAgICAgICAgICAgICAgICAgc2VydmVyLnNldFdhbnRDbGllbnRBdXRoKHRydWUpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKHNlcnZlci5nZXRXYW50Q2xpZW50QXV0aCgpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc2VydmVyLmdldE5lZWRDbGllbnRBdXRoKCkpOworCisgICAgICAgICAgICAgICAgICAgIC8vIGNvbmZpcm0gdHVybmluZyBzZXR0aW5nIG9uIHRvZ2dsZXMgdGhlIG90aGVyCisgICAgICAgICAgICAgICAgICAgIHNlcnZlci5zZXROZWVkQ2xpZW50QXV0aCh0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc2VydmVyLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKHNlcnZlci5nZXROZWVkQ2xpZW50QXV0aCgpKTsKKworICAgICAgICAgICAgICAgICAgICAvLyBjb25maXJtIHRvZ2dsaW5nIGJhY2sKKyAgICAgICAgICAgICAgICAgICAgc2VydmVyLnNldFdhbnRDbGllbnRBdXRoKHRydWUpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKHNlcnZlci5nZXRXYW50Q2xpZW50QXV0aCgpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc2VydmVyLmdldE5lZWRDbGllbnRBdXRoKCkpOworCisgICAgICAgICAgICAgICAgICAgIHNlcnZlci5zdGFydEhhbmRzaGFrZSgpOworCisgICAgICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAgICAgdGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIGNsaWVudC5zdGFydEhhbmRzaGFrZSgpOworICAgICAgICBhc3NlcnROb3ROdWxsKGNsaWVudC5nZXRTZXNzaW9uKCkuZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgIFRlc3RLZXlTdG9yZS5hc3NlcnRDaGFpbkxlbmd0aChjbGllbnQuZ2V0U2Vzc2lvbigpLmdldExvY2FsQ2VydGlmaWNhdGVzKCkpOworICAgICAgICBUZXN0U1NMQ29udGV4dC5hc3NlcnRDbGllbnRDZXJ0aWZpY2F0ZUNoYWluKGMuY2xpZW50VHJ1c3RNYW5hZ2VyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudC5nZXRTZXNzaW9uKCkuZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgIHRocmVhZC5qb2luKCk7CisgICAgICAgIGNsaWVudC5jbG9zZSgpOworICAgICAgICBzZXJ2ZXIuY2xvc2UoKTsKKyAgICAgICAgYy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU29ja2V0X2NsaWVudEF1dGhfYm9ndXNBbGlhcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMQ29udGV4dCBjID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIFNTTENvbnRleHQgY2xpZW50Q29udGV4dCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UoIlRMUyIpOworICAgICAgICBYNTA5S2V5TWFuYWdlciBrZXlNYW5hZ2VyID0gbmV3IFg1MDlLZXlNYW5hZ2VyKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgY2hvb3NlQ2xpZW50QWxpYXMoU3RyaW5nW10ga2V5VHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByaW5jaXBhbFtdIGlzc3VlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb2NrZXQgc29ja2V0KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuICJib2d1cyI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFN0cmluZyBjaG9vc2VTZXJ2ZXJBbGlhcyhTdHJpbmcga2V5VHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByaW5jaXBhbFtdIGlzc3VlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb2NrZXQgc29ja2V0KSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFg1MDlDZXJ0aWZpY2F0ZVtdIGdldENlcnRpZmljYXRlQ2hhaW4oU3RyaW5nIGFsaWFzKSB7CisgICAgICAgICAgICAgICAgLy8gcmV0dXJuIG51bGwgZm9yICJib2d1cyIgYWxpYXMKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nW10gZ2V0Q2xpZW50QWxpYXNlcyhTdHJpbmcga2V5VHlwZSwgUHJpbmNpcGFsW10gaXNzdWVycykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmdbXSBnZXRTZXJ2ZXJBbGlhc2VzKFN0cmluZyBrZXlUeXBlLCBQcmluY2lwYWxbXSBpc3N1ZXJzKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIFByaXZhdGVLZXkgZ2V0UHJpdmF0ZUtleShTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgICAgICAgICAvLyByZXR1cm4gbnVsbCBmb3IgImJvZ3VzIiBhbGlhcworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBjbGllbnRDb250ZXh0LmluaXQobmV3IEtleU1hbmFnZXJbXSB7IGtleU1hbmFnZXIgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBUcnVzdE1hbmFnZXJbXSB7IGMuY2xpZW50VHJ1c3RNYW5hZ2VyIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKKyAgICAgICAgU1NMU29ja2V0IGNsaWVudCA9IChTU0xTb2NrZXQpIGNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLmNyZWF0ZVNvY2tldChjLmhvc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5wb3J0KTsKKyAgICAgICAgZmluYWwgU1NMU29ja2V0IHNlcnZlciA9IChTU0xTb2NrZXQpIGMuc2VydmVyU29ja2V0LmFjY2VwdCgpOworICAgICAgICBUaHJlYWQgdGhyZWFkID0gbmV3IFRocmVhZChuZXcgUnVubmFibGUgKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHNlcnZlci5zZXROZWVkQ2xpZW50QXV0aCh0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgc2VydmVyLnN0YXJ0SGFuZHNoYWtlKCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChTU0xIYW5kc2hha2VFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworCisgICAgICAgIHRocmVhZC5zdGFydCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2xpZW50LnN0YXJ0SGFuZHNoYWtlKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNTTEhhbmRzaGFrZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgLy8gYmVmb3JlIHdlIHdvdWxkIGdldCBhIE51bGxQb2ludGVyRXhjZXB0aW9uIGZyb20gcGFzc2luZworICAgICAgICAgICAgLy8gZHVlIHRvIHRoZSBudWxsIFByaXZhdGVLZXkgcmV0dXJuIGJ5IHRoZSBYNTA5S2V5TWFuYWdlci4KKyAgICAgICAgfQorICAgICAgICB0aHJlYWQuam9pbigpOworICAgICAgICBjbGllbnQuY2xvc2UoKTsKKyAgICAgICAgc2VydmVyLmNsb3NlKCk7CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF9nZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgYyA9IFRlc3RTU0xDb250ZXh0LmNyZWF0ZSgpOworICAgICAgICBTU0xTb2NrZXQgY2xpZW50ID0gKFNTTFNvY2tldCkgYy5jbGllbnRDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKS5jcmVhdGVTb2NrZXQoYy5ob3N0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5wb3J0KTsKKyAgICAgICAgU1NMU29ja2V0IHNlcnZlciA9IChTU0xTb2NrZXQpIGMuc2VydmVyU29ja2V0LmFjY2VwdCgpOworICAgICAgICBhc3NlcnRUcnVlKGNsaWVudC5nZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oKSk7CisgICAgICAgIGFzc2VydFRydWUoc2VydmVyLmdldEVuYWJsZVNlc3Npb25DcmVhdGlvbigpKTsKKyAgICAgICAgY2xpZW50LmNsb3NlKCk7CisgICAgICAgIHNlcnZlci5jbG9zZSgpOworICAgICAgICBjLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTb2NrZXRfc2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uX3NlcnZlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U1NMQ29udGV4dCBjID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIFNTTFNvY2tldCBjbGllbnQgPSAoU1NMU29ja2V0KSBjLmNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLmNyZWF0ZVNvY2tldChjLmhvc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLnBvcnQpOworICAgICAgICBmaW5hbCBTU0xTb2NrZXQgc2VydmVyID0gKFNTTFNvY2tldCkgYy5zZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgIFRocmVhZCB0aHJlYWQgPSBuZXcgVGhyZWFkKG5ldyBSdW5uYWJsZSAoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc2VydmVyLnNldEVuYWJsZVNlc3Npb25DcmVhdGlvbihmYWxzZSk7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXIuc3RhcnRIYW5kc2hha2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1NMRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgICAgICB0aHJlYWQuc3RhcnQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNsaWVudC5zdGFydEhhbmRzaGFrZSgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTU0xFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0aHJlYWQuam9pbigpOworICAgICAgICBjbGllbnQuY2xvc2UoKTsKKyAgICAgICAgc2VydmVyLmNsb3NlKCk7CisgICAgICAgIGMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF9zZXRFbmFibGVTZXNzaW9uQ3JlYXRpb25fY2xpZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgU1NMU29ja2V0IGNsaWVudCA9IChTU0xTb2NrZXQpIGMuY2xpZW50Q29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkuY3JlYXRlU29ja2V0KGMuaG9zdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMucG9ydCk7CisgICAgICAgIGZpbmFsIFNTTFNvY2tldCBzZXJ2ZXIgPSAoU1NMU29ja2V0KSBjLnNlcnZlclNvY2tldC5hY2NlcHQoKTsKKyAgICAgICAgVGhyZWFkIHRocmVhZCA9IG5ldyBUaHJlYWQobmV3IFJ1bm5hYmxlICgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgc2VydmVyLnN0YXJ0SGFuZHNoYWtlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNTTEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAgICAgdGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIGNsaWVudC5zZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oZmFsc2UpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2xpZW50LnN0YXJ0SGFuZHNoYWtlKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNTTEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRocmVhZC5qb2luKCk7CisgICAgICAgIGNsaWVudC5jbG9zZSgpOworICAgICAgICBzZXJ2ZXIuY2xvc2UoKTsKKyAgICAgICAgYy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU29ja2V0X2dldFNTTFBhcmFtZXRlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMU29ja2V0RmFjdG9yeSBzZiA9IChTU0xTb2NrZXRGYWN0b3J5KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKyAgICAgICAgU1NMU29ja2V0IHNzbCA9IChTU0xTb2NrZXQpIHNmLmNyZWF0ZVNvY2tldCgpOworCisgICAgICAgIFNTTFBhcmFtZXRlcnMgcCA9IHNzbC5nZXRTU0xQYXJhbWV0ZXJzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwocCk7CisKKyAgICAgICAgU3RyaW5nW10gY2lwaGVyU3VpdGVzID0gcC5nZXRDaXBoZXJTdWl0ZXMoKTsKKyAgICAgICAgU3RhbmRhcmROYW1lcy5hc3NlcnRWYWxpZENpcGhlclN1aXRlcyhTdGFuZGFyZE5hbWVzLkNJUEhFUl9TVUlURVMsIGNpcGhlclN1aXRlcyk7CisgICAgICAgIGFzc2VydE5vdFNhbWUoY2lwaGVyU3VpdGVzLCBzc2wuZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoY2lwaGVyU3VpdGVzKSwgQXJyYXlzLmFzTGlzdChzc2wuZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpKSk7CisKKyAgICAgICAgU3RyaW5nW10gcHJvdG9jb2xzID0gcC5nZXRQcm90b2NvbHMoKTsKKyAgICAgICAgU3RhbmRhcmROYW1lcy5hc3NlcnRWYWxpZFByb3RvY29scyhTdGFuZGFyZE5hbWVzLlNTTF9TT0NLRVRfUFJPVE9DT0xTLCBwcm90b2NvbHMpOworICAgICAgICBhc3NlcnROb3RTYW1lKHByb3RvY29scywgc3NsLmdldEVuYWJsZWRQcm90b2NvbHMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KHByb3RvY29scyksIEFycmF5cy5hc0xpc3Qoc3NsLmdldEVuYWJsZWRQcm90b2NvbHMoKSkpOworCisgICAgICAgIGFzc2VydEVxdWFscyhwLmdldFdhbnRDbGllbnRBdXRoKCksIHNzbC5nZXRXYW50Q2xpZW50QXV0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHAuZ2V0TmVlZENsaWVudEF1dGgoKSwgc3NsLmdldE5lZWRDbGllbnRBdXRoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU29ja2V0X3NldFNTTFBhcmFtZXRlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMU29ja2V0RmFjdG9yeSBzZiA9IChTU0xTb2NrZXRGYWN0b3J5KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKyAgICAgICAgU1NMU29ja2V0IHNzbCA9IChTU0xTb2NrZXQpIHNmLmNyZWF0ZVNvY2tldCgpOworICAgICAgICBTdHJpbmdbXSBkZWZhdWx0Q2lwaGVyU3VpdGVzID0gc3NsLmdldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKTsKKyAgICAgICAgU3RyaW5nW10gZGVmYXVsdFByb3RvY29scyA9IHNzbC5nZXRFbmFibGVkUHJvdG9jb2xzKCk7CisgICAgICAgIFN0cmluZ1tdIHN1cHBvcnRlZENpcGhlclN1aXRlcyA9IHNzbC5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKTsKKyAgICAgICAgU3RyaW5nW10gc3VwcG9ydGVkUHJvdG9jb2xzID0gc3NsLmdldFN1cHBvcnRlZFByb3RvY29scygpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIFNTTFBhcmFtZXRlcnMgcCA9IG5ldyBTU0xQYXJhbWV0ZXJzKCk7CisgICAgICAgICAgICBzc2wuc2V0U1NMUGFyYW1ldGVycyhwKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KGRlZmF1bHRDaXBoZXJTdWl0ZXMpLAorICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5cy5hc0xpc3Qoc3NsLmdldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoZGVmYXVsdFByb3RvY29scyksCisgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmFzTGlzdChzc2wuZ2V0RW5hYmxlZFByb3RvY29scygpKSk7CisgICAgICAgIH0KKworICAgICAgICB7CisgICAgICAgICAgICBTU0xQYXJhbWV0ZXJzIHAgPSBuZXcgU1NMUGFyYW1ldGVycyhzdXBwb3J0ZWRDaXBoZXJTdWl0ZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0ZWRQcm90b2NvbHMpOworICAgICAgICAgICAgc3NsLnNldFNTTFBhcmFtZXRlcnMocCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChzdXBwb3J0ZWRDaXBoZXJTdWl0ZXMpLAorICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5cy5hc0xpc3Qoc3NsLmdldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3Qoc3VwcG9ydGVkUHJvdG9jb2xzKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheXMuYXNMaXN0KHNzbC5nZXRFbmFibGVkUHJvdG9jb2xzKCkpKTsKKyAgICAgICAgfQorICAgICAgICB7CisgICAgICAgICAgICBTU0xQYXJhbWV0ZXJzIHAgPSBuZXcgU1NMUGFyYW1ldGVycygpOworCisgICAgICAgICAgICBwLnNldE5lZWRDbGllbnRBdXRoKHRydWUpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc3NsLmdldE5lZWRDbGllbnRBdXRoKCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc3NsLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICAgICAgc3NsLnNldFNTTFBhcmFtZXRlcnMocCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHNzbC5nZXROZWVkQ2xpZW50QXV0aCgpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHNzbC5nZXRXYW50Q2xpZW50QXV0aCgpKTsKKworICAgICAgICAgICAgcC5zZXRXYW50Q2xpZW50QXV0aCh0cnVlKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoc3NsLmdldE5lZWRDbGllbnRBdXRoKCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc3NsLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICAgICAgc3NsLnNldFNTTFBhcmFtZXRlcnMocCk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShzc2wuZ2V0TmVlZENsaWVudEF1dGgoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHNzbC5nZXRXYW50Q2xpZW50QXV0aCgpKTsKKworICAgICAgICAgICAgcC5zZXRXYW50Q2xpZW50QXV0aChmYWxzZSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShzc2wuZ2V0TmVlZENsaWVudEF1dGgoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHNzbC5nZXRXYW50Q2xpZW50QXV0aCgpKTsKKyAgICAgICAgICAgIHNzbC5zZXRTU0xQYXJhbWV0ZXJzKHApOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc3NsLmdldE5lZWRDbGllbnRBdXRoKCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc3NsLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xTb2NrZXRfY2xvc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTFNvY2tldFBhaXIgcGFpciA9IFRlc3RTU0xTb2NrZXRQYWlyLmNyZWF0ZSgpOworICAgICAgICBTU0xTb2NrZXQgc2VydmVyID0gcGFpci5zZXJ2ZXI7CisgICAgICAgIFNTTFNvY2tldCBjbGllbnQgPSBwYWlyLmNsaWVudDsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2VydmVyLmlzQ2xvc2VkKCkpOworICAgICAgICBhc3NlcnRGYWxzZShjbGllbnQuaXNDbG9zZWQoKSk7CisgICAgICAgIElucHV0U3RyZWFtIGlucHV0ID0gY2xpZW50LmdldElucHV0U3RyZWFtKCk7CisgICAgICAgIE91dHB1dFN0cmVhbSBvdXRwdXQgPSBjbGllbnQuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIHNlcnZlci5jbG9zZSgpOworICAgICAgICBjbGllbnQuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzZXJ2ZXIuaXNDbG9zZWQoKSk7CisgICAgICAgIGFzc2VydFRydWUoY2xpZW50LmlzQ2xvc2VkKCkpOworCisgICAgICAgIC8vIGNsb3NlIGFmdGVyIGNsb3NlIGlzIG9rYXkuLi4KKyAgICAgICAgc2VydmVyLmNsb3NlKCk7CisgICAgICAgIGNsaWVudC5jbG9zZSgpOworCisgICAgICAgIC8vIC4uLnNvIGFyZSBhIGxvdCBvZiBvdGhlciBvcGVyYXRpb25zLi4uCisgICAgICAgIEhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyIGwgPSBuZXcgSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXIgKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgaGFuZHNoYWtlQ29tcGxldGVkKEhhbmRzaGFrZUNvbXBsZXRlZEV2ZW50IGUpIHt9CisgICAgICAgIH07CisgICAgICAgIGNsaWVudC5hZGRIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lcihsKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjbGllbnQuZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjbGllbnQuZ2V0RW5hYmxlZFByb3RvY29scygpKTsKKyAgICAgICAgY2xpZW50LmdldEVuYWJsZVNlc3Npb25DcmVhdGlvbigpOworICAgICAgICBjbGllbnQuZ2V0TmVlZENsaWVudEF1dGgoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjbGllbnQuZ2V0U2Vzc2lvbigpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjbGllbnQuZ2V0U1NMUGFyYW1ldGVycygpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjbGllbnQuZ2V0U3VwcG9ydGVkUHJvdG9jb2xzKCkpOworICAgICAgICBjbGllbnQuZ2V0VXNlQ2xpZW50TW9kZSgpOworICAgICAgICBjbGllbnQuZ2V0V2FudENsaWVudEF1dGgoKTsKKyAgICAgICAgY2xpZW50LnJlbW92ZUhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyKGwpOworICAgICAgICBjbGllbnQuc2V0RW5hYmxlZENpcGhlclN1aXRlcyhuZXcgU3RyaW5nWzBdKTsKKyAgICAgICAgY2xpZW50LnNldEVuYWJsZWRQcm90b2NvbHMobmV3IFN0cmluZ1swXSk7CisgICAgICAgIGNsaWVudC5zZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oZmFsc2UpOworICAgICAgICBjbGllbnQuc2V0TmVlZENsaWVudEF1dGgoZmFsc2UpOworICAgICAgICBjbGllbnQuc2V0U1NMUGFyYW1ldGVycyhjbGllbnQuZ2V0U1NMUGFyYW1ldGVycygpKTsKKyAgICAgICAgY2xpZW50LnNldFdhbnRDbGllbnRBdXRoKGZhbHNlKTsKKworICAgICAgICAvLyAuLi5idXQgc29tZSBvcGVyYXRpb25zIGFyZSBleHBlY3RlZCB0byBnaXZlIFNvY2tldEV4Y2VwdGlvbi4uLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgY2xpZW50LnN0YXJ0SGFuZHNoYWtlKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjbGllbnQuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNsaWVudC5nZXRPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlucHV0LnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlucHV0LnJlYWQobnVsbCwgLTEsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoU3RhbmRhcmROYW1lcy5JU19SSSk7CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoU3RhbmRhcmROYW1lcy5JU19SSSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG91dHB1dC53cml0ZSgtMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXRwdXQud3JpdGUobnVsbCwgLTEsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoU3RhbmRhcmROYW1lcy5JU19SSSk7CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoU3RhbmRhcmROYW1lcy5JU19SSSk7CisgICAgICAgIH0KKworICAgICAgICAvLyAuLi4gYW5kIG9uZSBnaXZlcyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNsaWVudC5zZXRVc2VDbGllbnRNb2RlKGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBwYWlyLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogYi8zMzUwNjQ1IFRlc3QgdG8gY29uZmlybSB0aGF0IGFuIFNTTFNvY2tldC5jbG9zZSgpIHBlcmZvcm1pbmcKKyAgICAgKiBhbiBTU0xfc2h1dGRvd24gZG9lcyBub3QgdGhyb3cgYW4gSU9FeGNlcHRpb24gaWYgdGhlIHBlZXIKKyAgICAgKiBzb2NrZXQgaGFzIGJlZW4gY2xvc2VkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU29ja2V0X3NodXRkb3duQ2xvc2VPbkNsb3NlZFBlZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgYyA9IFRlc3RTU0xDb250ZXh0LmNyZWF0ZSgpOworICAgICAgICBmaW5hbCBTb2NrZXQgdW5kZXJseWluZyA9IG5ldyBTb2NrZXQoYy5ob3N0LCBjLnBvcnQpOworICAgICAgICBmaW5hbCBTU0xTb2NrZXQgd3JhcHBpbmcgPSAoU1NMU29ja2V0KQorICAgICAgICAgICAgICAgIGMuY2xpZW50Q29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkuY3JlYXRlU29ja2V0KHVuZGVybHlpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5ob3N0LmdldEhvc3ROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5wb3J0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKKyAgICAgICAgVGhyZWFkIGNsaWVudFRocmVhZCA9IG5ldyBUaHJlYWQobmV3IFJ1bm5hYmxlICgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgd3JhcHBpbmcuc3RhcnRIYW5kc2hha2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHdyYXBwaW5nLmdldE91dHB1dFN0cmVhbSgpLndyaXRlKDQyKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsb3NlIHRoZSB1bmRlcmx5aW5nIHNvY2tldCwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNvIHRoYXQgbm8gU1NMIHNodXRkb3duIGlzIHNlbnQKKyAgICAgICAgICAgICAgICAgICAgICAgIHVuZGVybHlpbmcuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHdyYXBwaW5nLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNTTEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAgICAgY2xpZW50VGhyZWFkLnN0YXJ0KCk7CisKKyAgICAgICAgU1NMU29ja2V0IHNlcnZlciA9IChTU0xTb2NrZXQpIGMuc2VydmVyU29ja2V0LmFjY2VwdCgpOworICAgICAgICBzZXJ2ZXIuc3RhcnRIYW5kc2hha2UoKTsKKyAgICAgICAgc2VydmVyLmdldElucHV0U3RyZWFtKCkucmVhZCgpOworICAgICAgICAvLyB3YWl0IGZvciB0aHJlYWQgdG8gZmluaXNoIHNvIHdlIGtub3cgY2xpZW50IGlzIGNsb3NlZC4KKyAgICAgICAgY2xpZW50VGhyZWFkLmpvaW4oKTsKKyAgICAgICAgLy8gY2xvc2Ugc2hvdWxkIGNhdXNlIGFuIFNTTF9zaHV0ZG93biB3aGljaCB3aWxsIGZhaWwKKyAgICAgICAgLy8gYmVjYXVzZSB0aGUgcGVlciBoYXMgY2xvc2VkLCBidXQgaXQgc2hvdWxkbid0IHRocm93LgorICAgICAgICBzZXJ2ZXIuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF9zZXRTb1RpbWVvdXRfYmFzaWMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2VydmVyU29ja2V0IGxpc3RlbmluZyA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisKKyAgICAgICAgU29ja2V0IHVuZGVybHlpbmcgPSBuZXcgU29ja2V0KGxpc3RlbmluZy5nZXRJbmV0QWRkcmVzcygpLCBsaXN0ZW5pbmcuZ2V0TG9jYWxQb3J0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgdW5kZXJseWluZy5nZXRTb1RpbWVvdXQoKSk7CisKKyAgICAgICAgU1NMU29ja2V0RmFjdG9yeSBzZiA9IChTU0xTb2NrZXRGYWN0b3J5KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKyAgICAgICAgU29ja2V0IHdyYXBwaW5nID0gc2YuY3JlYXRlU29ja2V0KHVuZGVybHlpbmcsIG51bGwsIC0xLCBmYWxzZSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCB3cmFwcGluZy5nZXRTb1RpbWVvdXQoKSk7CisKKyAgICAgICAgLy8gc2V0dGluZyB3cmFwcGVyIHNldHMgdW5kZXJseWluZyBhbmQgLi4uCisgICAgICAgIHdyYXBwaW5nLnNldFNvVGltZW91dCgxMCk7CisgICAgICAgIGFzc2VydEVxdWFscygxMCwgd3JhcHBpbmcuZ2V0U29UaW1lb3V0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTAsIHVuZGVybHlpbmcuZ2V0U29UaW1lb3V0KCkpOworCisgICAgICAgIC8vIC4uLiBnZXR0aW5nIHdyYXBwZXIgaW5zcGVjdHMgdW5kZXJseWluZworICAgICAgICB1bmRlcmx5aW5nLnNldFNvVGltZW91dCgwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHdyYXBwaW5nLmdldFNvVGltZW91dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHVuZGVybHlpbmcuZ2V0U29UaW1lb3V0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMU29ja2V0X3NldFNvVGltZW91dF93cmFwcGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChTdGFuZGFyZE5hbWVzLklTX1JJKSB7CisgICAgICAgICAgICAvLyBSSSBjYW5ub3QgaGFuZGxlIHRoaXMgY2FzZQorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFNlcnZlclNvY2tldCBsaXN0ZW5pbmcgPSBuZXcgU2VydmVyU29ja2V0KDApOworCisgICAgICAgIC8vIHNldFNvVGltZW91dCBhcHBsaWVzIHRvIHJlYWQsIG5vdCBjb25uZWN0LCBzbyBjb25uZWN0IGZpcnN0CisgICAgICAgIFNvY2tldCB1bmRlcmx5aW5nID0gbmV3IFNvY2tldChsaXN0ZW5pbmcuZ2V0SW5ldEFkZHJlc3MoKSwgbGlzdGVuaW5nLmdldExvY2FsUG9ydCgpKTsKKyAgICAgICAgU29ja2V0IHNlcnZlciA9IGxpc3RlbmluZy5hY2NlcHQoKTsKKworICAgICAgICBTU0xTb2NrZXRGYWN0b3J5IHNmID0gKFNTTFNvY2tldEZhY3RvcnkpIFNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworICAgICAgICBTb2NrZXQgY2xpZW50V3JhcHBpbmcgPSBzZi5jcmVhdGVTb2NrZXQodW5kZXJseWluZywgbnVsbCwgLTEsIGZhbHNlKTsKKworICAgICAgICB1bmRlcmx5aW5nLnNldFNvVGltZW91dCgxKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNsaWVudFdyYXBwaW5nLmdldElucHV0U3RyZWFtKCkucmVhZCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTb2NrZXRUaW1lb3V0RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBjbGllbnRXcmFwcGluZy5jbG9zZSgpOworICAgICAgICBzZXJ2ZXIuY2xvc2UoKTsKKyAgICAgICAgdW5kZXJseWluZy5jbG9zZSgpOworICAgICAgICBsaXN0ZW5pbmcuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTFNvY2tldF9pbnRlcnJ1cHQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2VydmVyU29ja2V0IGxpc3RlbmluZyA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAzOyBpKyspIHsKKyAgICAgICAgICAgIFNvY2tldCB1bmRlcmx5aW5nID0gbmV3IFNvY2tldChsaXN0ZW5pbmcuZ2V0SW5ldEFkZHJlc3MoKSwgbGlzdGVuaW5nLmdldExvY2FsUG9ydCgpKTsKKyAgICAgICAgICAgIFNvY2tldCBzZXJ2ZXIgPSBsaXN0ZW5pbmcuYWNjZXB0KCk7CisKKyAgICAgICAgICAgIFNTTFNvY2tldEZhY3Rvcnkgc2YgPSAoU1NMU29ja2V0RmFjdG9yeSkgU1NMU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCk7CisgICAgICAgICAgICBTb2NrZXQgY2xpZW50V3JhcHBpbmcgPSBzZi5jcmVhdGVTb2NrZXQodW5kZXJseWluZywgbnVsbCwgLTEsIHRydWUpOworCisgICAgICAgICAgICBzd2l0Y2ggKGkpIHsKKyAgICAgICAgICAgICAgICBjYXNlIDA6CisgICAgICAgICAgICAgICAgICAgIHRlc3RfU1NMU29ja2V0X2ludGVycnVwdF9jYXNlKHVuZGVybHlpbmcsIHVuZGVybHlpbmcpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIDE6CisgICAgICAgICAgICAgICAgICAgIHRlc3RfU1NMU29ja2V0X2ludGVycnVwdF9jYXNlKHVuZGVybHlpbmcsIGNsaWVudFdyYXBwaW5nKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAyOgorICAgICAgICAgICAgICAgICAgICB0ZXN0X1NTTFNvY2tldF9pbnRlcnJ1cHRfY2FzZShjbGllbnRXcmFwcGluZywgdW5kZXJseWluZyk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgMzoKKyAgICAgICAgICAgICAgICAgICAgdGVzdF9TU0xTb2NrZXRfaW50ZXJydXB0X2Nhc2UoY2xpZW50V3JhcHBpbmcsIGNsaWVudFdyYXBwaW5nKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzZXJ2ZXIuY2xvc2UoKTsKKyAgICAgICAgICAgIHVuZGVybHlpbmcuY2xvc2UoKTsKKyAgICAgICAgfQorICAgICAgICBsaXN0ZW5pbmcuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdF9TU0xTb2NrZXRfaW50ZXJydXB0X2Nhc2UoU29ja2V0IHRvUmVhZCwgZmluYWwgU29ja2V0IHRvQ2xvc2UpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbmV3IFRocmVhZCgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxICogMTAwMCk7CisgICAgICAgICAgICAgICAgICAgIHRvQ2xvc2UuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0uc3RhcnQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRvUmVhZC5zZXRTb1RpbWVvdXQoNSAqIDEwMDApOworICAgICAgICAgICAgdG9SZWFkLmdldElucHV0U3RyZWFtKCkucmVhZCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTb2NrZXRUaW1lb3V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9UZXN0U1NMU29ja2V0UGFpcl9jcmVhdGUoKSB7CisgICAgICAgIFRlc3RTU0xTb2NrZXRQYWlyIHRlc3QgPSBUZXN0U1NMU29ja2V0UGFpci5jcmVhdGUoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0ZXN0LmMpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRlc3Quc2VydmVyKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0ZXN0LmNsaWVudCk7CisgICAgICAgIGFzc2VydFRydWUodGVzdC5zZXJ2ZXIuaXNDb25uZWN0ZWQoKSk7CisgICAgICAgIGFzc2VydFRydWUodGVzdC5jbGllbnQuaXNDb25uZWN0ZWQoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHRlc3Quc2VydmVyLmlzQ2xvc2VkKCkpOworICAgICAgICBhc3NlcnRGYWxzZSh0ZXN0LmNsaWVudC5pc0Nsb3NlZCgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0ZXN0LnNlcnZlci5nZXRTZXNzaW9uKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRlc3QuY2xpZW50LmdldFNlc3Npb24oKSk7CisgICAgICAgIGFzc2VydFRydWUodGVzdC5zZXJ2ZXIuZ2V0U2Vzc2lvbigpLmlzVmFsaWQoKSk7CisgICAgICAgIGFzc2VydFRydWUodGVzdC5jbGllbnQuZ2V0U2Vzc2lvbigpLmlzVmFsaWQoKSk7CisgICAgICAgIHRlc3QuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3QgcnVuIGJ5IGRlZmF1bHQgYnkgSlVuaXQsIGJ1dCBjYW4gYmUgcnVuIGJ5IFZvZ2FyIGJ5CisgICAgICogc3BlY2lmeWluZyBpdCBleHBsaWNpdGx5IChvciB3aXRoIG1haW4gbWV0aG9kIGJlbG93KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHN0cmVzc190ZXN0X1Rlc3RTU0xTb2NrZXRQYWlyX2NyZWF0ZSgpIHsKKyAgICAgICAgZmluYWwgYm9vbGVhbiB2ZXJib3NlID0gdHJ1ZTsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIFRlc3RTU0xTb2NrZXRQYWlyIHRlc3QgPSBUZXN0U1NMU29ja2V0UGFpci5jcmVhdGUoKTsKKyAgICAgICAgICAgIGlmICh2ZXJib3NlKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJjbGllbnQ9IiArIHRlc3QuY2xpZW50LmdldExvY2FsUG9ydCgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBzZXJ2ZXI9IiArIHRlc3Quc2VydmVyLmdldExvY2FsUG9ydCgpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiWCIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICBXZSBkb24ndCBjbG9zZSBvbiBwdXJwb3NlIGluIHRoaXMgc3RyZXNzIHRlc3QgdG8gYWRkCisgICAgICAgICAgICAgIHJhY2VzIGluIGZpbGUgZGVzY3JpcHRvcnMgcmV1c2Ugd2hlbiB0aGUgZ2FyYmFnZQorICAgICAgICAgICAgICBjb2xsZWN0b3IgcnVucyBjb25jdXJyZW50bHkgYW5kIGZpbmFsaXplcyBzb2NrZXRzCisgICAgICAgICAgICAqLworICAgICAgICAgICAgLy8gdGVzdC5jbG9zZSgpOworCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbiAoU3RyaW5nW10gYXJncykgeworICAgICAgICBuZXcgU1NMU29ja2V0VGVzdCgpLnN0cmVzc190ZXN0X1Rlc3RTU0xTb2NrZXRQYWlyX2NyZWF0ZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvVHJ1c3RNYW5hZ2VyRmFjdG9yeVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvVHJ1c3RNYW5hZ2VyRmFjdG9yeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YTNmZTI1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvbmV0L3NzbC9UcnVzdE1hbmFnZXJGYWN0b3J5VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjU4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlLlByaXZhdGVLZXlFbnRyeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5QS0lYQnVpbGRlclBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LlBLSVhQYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLkNlcnRQYXRoVHJ1c3RNYW5hZ2VyUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLk1hbmFnZXJGYWN0b3J5UGFyYW1ldGVyczsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlckZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5YNTA5VHJ1c3RNYW5hZ2VyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuU3RhbmRhcmROYW1lczsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuVGVzdEtleVN0b3JlOworCitwdWJsaWMgY2xhc3MgVHJ1c3RNYW5hZ2VyRmFjdG9yeVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgW10gS0VZX1RZUEVTID0gbmV3IFN0cmluZ1tdIHsgIlJTQSIsICJEU0EiLCAiRUMiLCAiRUNfUlNBIiB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgVGVzdEtleVN0b3JlIFRFU1RfS0VZX1NUT1JFOworCisgICAgLy8gbm90ZSB0aGUgcmFyZSB1c2FnZSBvZiBEU0Ega2V5cyBoZXJlIGluIGFkZGl0aW9uIHRvIFJTQQorICAgIHByaXZhdGUgc3RhdGljIFRlc3RLZXlTdG9yZSBnZXRUZXN0S2V5U3RvcmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKFRFU1RfS0VZX1NUT1JFID09IG51bGwpIHsKKyAgICAgICAgICAgIFRFU1RfS0VZX1NUT1JFID0gbmV3IFRlc3RLZXlTdG9yZS5CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLmtleUFsZ29yaXRobXMoS0VZX1RZUEVTKQorICAgICAgICAgICAgICAgICAgICAuYWxpYXNQcmVmaXgoInJzYS1kc2EtZWMiKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gVEVTVF9LRVlfU1RPUkU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9UcnVzdE1hbmFnZXJGYWN0b3J5X2dldERlZmF1bHRBbGdvcml0aG0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGFsZ29yaXRobSA9IFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0RGVmYXVsdEFsZ29yaXRobSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoU3RhbmRhcmROYW1lcy5UUlVTVF9NQU5BR0VSX0ZBQ1RPUllfREVGQVVMVCwgYWxnb3JpdGhtKTsKKyAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeSB0bWYgPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgIHRlc3RfVHJ1c3RNYW5hZ2VyRmFjdG9yeSh0bWYsIFN0YW5kYXJkTmFtZXMuSVNfUkkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFVzZWxlc3NNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMgaW1wbGVtZW50cyBNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMge30KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0X1RydXN0TWFuYWdlckZhY3RvcnkoVHJ1c3RNYW5hZ2VyRmFjdG9yeSB0bWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHN1cHBvcnRzTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydE5vdE51bGwodG1mKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0bWYuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRtZi5nZXRQcm92aWRlcigpKTsKKworICAgICAgICAvLyBiZWZvcmUgaW5pdAorICAgICAgICB0cnkgeworICAgICAgICAgICAgdG1mLmdldFRydXN0TWFuYWdlcnMoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICAvLyBpbml0IHdpdGggbnVsbCBNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRtZi5pbml0KChNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMpIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICAvLyBpbml0IHdpdGggdXNlbGVzcyBNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRtZi5pbml0KG5ldyBVc2VsZXNzTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzKCkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICAvLyBpbml0IHdpdGggUEtJWFBhcmFtZXRlcnMgTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQS0lYUGFyYW1ldGVycyBwcCA9IG5ldyBQS0lYUGFyYW1ldGVycyhnZXRUZXN0S2V5U3RvcmUoKS5rZXlTdG9yZSk7CisgICAgICAgICAgICBDZXJ0UGF0aFRydXN0TWFuYWdlclBhcmFtZXRlcnMgY3B0bXAgPSBuZXcgQ2VydFBhdGhUcnVzdE1hbmFnZXJQYXJhbWV0ZXJzKHBwKTsKKyAgICAgICAgICAgIHRtZi5pbml0KGNwdG1wKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gaW5pdCB3aXRoIFBLSVhCdWlsZGVyUGFyYW1ldGVycyBNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMKKyAgICAgICAgWDUwOUNlcnRTZWxlY3RvciB4Y3MgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworICAgICAgICBQS0lYQnVpbGRlclBhcmFtZXRlcnMgcGJwID0gbmV3IFBLSVhCdWlsZGVyUGFyYW1ldGVycyhnZXRUZXN0S2V5U3RvcmUoKS5rZXlTdG9yZSwgeGNzKTsKKyAgICAgICAgQ2VydFBhdGhUcnVzdE1hbmFnZXJQYXJhbWV0ZXJzIGNwdG1wID0gbmV3IENlcnRQYXRoVHJ1c3RNYW5hZ2VyUGFyYW1ldGVycyhwYnApOworICAgICAgICBpZiAoc3VwcG9ydHNNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMpIHsKKyAgICAgICAgICAgIHRtZi5pbml0KGNwdG1wKTsKKyAgICAgICAgICAgIHRlc3RfVHJ1c3RNYW5hZ2VyRmFjdG9yeV9nZXRUcnVzdE1hbmFnZXJzKHRtZik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRtZi5pbml0KGNwdG1wKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBpbml0IHdpdGggbnVsbCBmb3IgZGVmYXVsdCBLZXlTdG9yZQorICAgICAgICB0bWYuaW5pdCgoS2V5U3RvcmUpIG51bGwpOworICAgICAgICB0ZXN0X1RydXN0TWFuYWdlckZhY3RvcnlfZ2V0VHJ1c3RNYW5hZ2Vycyh0bWYpOworCisgICAgICAgIC8vIGluaXQgd2l0aCBzcGVjaWZpYyBrZXkgc3RvcmUKKyAgICAgICAgdG1mLmluaXQoZ2V0VGVzdEtleVN0b3JlKCkua2V5U3RvcmUpOworICAgICAgICB0ZXN0X1RydXN0TWFuYWdlckZhY3RvcnlfZ2V0VHJ1c3RNYW5hZ2Vycyh0bWYpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0X1RydXN0TWFuYWdlckZhY3RvcnlfZ2V0VHJ1c3RNYW5hZ2VycyhUcnVzdE1hbmFnZXJGYWN0b3J5IHRtZikKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUcnVzdE1hbmFnZXJbXSB0cnVzdE1hbmFnZXJzID0gdG1mLmdldFRydXN0TWFuYWdlcnMoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0cnVzdE1hbmFnZXJzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0cnVzdE1hbmFnZXJzLmxlbmd0aCA+IDApOworICAgICAgICBmb3IgKFRydXN0TWFuYWdlciB0cnVzdE1hbmFnZXIgOiB0cnVzdE1hbmFnZXJzKSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHRydXN0TWFuYWdlcik7CisgICAgICAgICAgICBpZiAodHJ1c3RNYW5hZ2VyIGluc3RhbmNlb2YgWDUwOVRydXN0TWFuYWdlcikgeworICAgICAgICAgICAgICAgIHRlc3RfWDUwOVRydXN0TWFuYWdlcigoWDUwOVRydXN0TWFuYWdlcikgdHJ1c3RNYW5hZ2VyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0X1g1MDlUcnVzdE1hbmFnZXIoWDUwOVRydXN0TWFuYWdlciB0bSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoU3RyaW5nIGtleVR5cGUgOiBLRVlfVFlQRVMpIHsKKyAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIGlzc3VlcnMgPSB0bS5nZXRBY2NlcHRlZElzc3VlcnMoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoaXNzdWVycyk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGlzc3VlcnMubGVuZ3RoID4gMSk7CisgICAgICAgICAgICBhc3NlcnROb3RTYW1lKGlzc3VlcnMsIHRtLmdldEFjY2VwdGVkSXNzdWVycygpKTsKKyAgICAgICAgICAgIGJvb2xlYW4gZGVmYXVsdFRydXN0TWFuYWdlcgorICAgICAgICAgICAgICAgICAgICAvLyBSSSBkZS1kdXBsaWNhdGVzIGNlcnRzIGZyb20gVHJ1c3RlZENlcnRpZmljYXRlRW50cnkgYW5kIFByaXZhdGVLZXlFbnRyeQorICAgICAgICAgICAgICAgICAgICA9IGlzc3VlcnMubGVuZ3RoID4gKFN0YW5kYXJkTmFtZXMuSVNfUkkgPyAxIDogMikgKiBLRVlfVFlQRVMubGVuZ3RoOworCisgICAgICAgICAgICBTdHJpbmcga2V5QWxnTmFtZSA9IFRlc3RLZXlTdG9yZS5rZXlBbGdvcml0aG0oa2V5VHlwZSk7CisgICAgICAgICAgICBTdHJpbmcgc2lnQWxnTmFtZSA9IFRlc3RLZXlTdG9yZS5zaWduYXR1cmVBbGdvcml0aG0oa2V5VHlwZSk7CisgICAgICAgICAgICBQcml2YXRlS2V5RW50cnkgcGtlID0gZ2V0VGVzdEtleVN0b3JlKCkuZ2V0UHJpdmF0ZUtleShrZXlBbGdOYW1lLCBzaWdBbGdOYW1lKTsKKyAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIGNoYWluID0gKFg1MDlDZXJ0aWZpY2F0ZVtdKSBwa2UuZ2V0Q2VydGlmaWNhdGVDaGFpbigpOworICAgICAgICAgICAgaWYgKGRlZmF1bHRUcnVzdE1hbmFnZXIpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICB0bS5jaGVja0NsaWVudFRydXN0ZWQoY2hhaW4sIGtleVR5cGUpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgdG0uY2hlY2tTZXJ2ZXJUcnVzdGVkKGNoYWluLCBrZXlUeXBlKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0bS5jaGVja0NsaWVudFRydXN0ZWQoY2hhaW4sIGtleVR5cGUpOworICAgICAgICAgICAgICAgIHRtLmNoZWNrU2VydmVyVHJ1c3RlZChjaGFpbiwga2V5VHlwZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfVHJ1c3RNYW5hZ2VyRmFjdG9yeV9nZXRJbnN0YW5jZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQcm92aWRlcltdIHByb3ZpZGVycyA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygpOworICAgICAgICBmb3IgKFByb3ZpZGVyIHByb3ZpZGVyIDogcHJvdmlkZXJzKSB7CisgICAgICAgICAgICBTZXQ8UHJvdmlkZXIuU2VydmljZT4gc2VydmljZXMgPSBwcm92aWRlci5nZXRTZXJ2aWNlcygpOworICAgICAgICAgICAgZm9yIChQcm92aWRlci5TZXJ2aWNlIHNlcnZpY2UgOiBzZXJ2aWNlcykgeworICAgICAgICAgICAgICAgIFN0cmluZyB0eXBlID0gc2VydmljZS5nZXRUeXBlKCk7CisgICAgICAgICAgICAgICAgaWYgKCF0eXBlLmVxdWFscygiVHJ1c3RNYW5hZ2VyRmFjdG9yeSIpKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBTdHJpbmcgYWxnb3JpdGhtID0gc2VydmljZS5nZXRBbGdvcml0aG0oKTsKKyAgICAgICAgICAgICAgICBib29sZWFuIHN1cHBvcnRzTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzID0gYWxnb3JpdGhtLmVxdWFscygiUEtJWCIpOworICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeSB0bWYgPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhhbGdvcml0aG0sIHRtZi5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgICAgICAgICAgICAgIHRlc3RfVHJ1c3RNYW5hZ2VyRmFjdG9yeSh0bWYsIHN1cHBvcnRzTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkgdG1mID0gVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShhbGdvcml0aG0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFsZ29yaXRobSwgdG1mLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHByb3ZpZGVyLCB0bWYuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgICAgICAgICAgICAgIHRlc3RfVHJ1c3RNYW5hZ2VyRmFjdG9yeSh0bWYsIHN1cHBvcnRzTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkgdG1mID0gVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShhbGdvcml0aG0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhhbGdvcml0aG0sIHRtZi5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhwcm92aWRlciwgdG1mLmdldFByb3ZpZGVyKCkpOworICAgICAgICAgICAgICAgICAgICB0ZXN0X1RydXN0TWFuYWdlckZhY3RvcnkodG1mLCBzdXBwb3J0c01hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9UcnVzdE1hbmFnZXJGYWN0b3J5X2ludGVybWVkaWF0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBjaGFpbiBzaG91bGQgYmUgc2VydmVyL2ludGVybWVkaWF0ZS9yb290CisgICAgICAgIFByaXZhdGVLZXlFbnRyeSBwa2UgPSBUZXN0S2V5U3RvcmUuZ2V0U2VydmVyKCkuZ2V0UHJpdmF0ZUtleSgiUlNBIiwgIlJTQSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGVbXSBjaGFpbiA9IChYNTA5Q2VydGlmaWNhdGVbXSlwa2UuZ2V0Q2VydGlmaWNhdGVDaGFpbigpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgY2hhaW4ubGVuZ3RoKTsKKworICAgICAgICAvLyBrZXlTdG9yZSBzaG91bGQgY29udGFpbiBvbmx5IHRoZSBpbnRlcm1lZGlhdGUgQ0Egc28gd2UgY2FuCisgICAgICAgIC8vIHRlc3QgcHJvcGVyIHZhbGlkYXRpb24gZXZlbiBpZiB0aGVyZSBhcmUgZXh0cmEgY2VydHMgYWZ0ZXIKKyAgICAgICAgLy8gdGhlIHRydXN0ZWQgb25lIChpbiB0aGlzIGNhc2UgdGhlIG9yaWdpbmFsIHJvb3QgaXMgImV4dHJhIikKKyAgICAgICAgS2V5U3RvcmUga2V5U3RvcmUgPSBUZXN0S2V5U3RvcmUuY3JlYXRlS2V5U3RvcmUoKTsKKyAgICAgICAga2V5U3RvcmUuc2V0Q2VydGlmaWNhdGVFbnRyeSgiYWxpYXMiLCBjaGFpblsxXSk7CisKKyAgICAgICAgUHJvdmlkZXJbXSBwcm92aWRlcnMgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoKTsKKyAgICAgICAgZm9yIChQcm92aWRlciBwcm92aWRlciA6IHByb3ZpZGVycykgeworICAgICAgICAgICAgU2V0PFByb3ZpZGVyLlNlcnZpY2U+IHNlcnZpY2VzID0gcHJvdmlkZXIuZ2V0U2VydmljZXMoKTsKKyAgICAgICAgICAgIGZvciAoUHJvdmlkZXIuU2VydmljZSBzZXJ2aWNlIDogc2VydmljZXMpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgdHlwZSA9IHNlcnZpY2UuZ2V0VHlwZSgpOworICAgICAgICAgICAgICAgIGlmICghdHlwZS5lcXVhbHMoIlRydXN0TWFuYWdlckZhY3RvcnkiKSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgU3RyaW5nIGFsZ29yaXRobSA9IHNlcnZpY2UuZ2V0QWxnb3JpdGhtKCk7CisgICAgICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeSB0bWYgPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgICAgICAgICAgdG1mLmluaXQoa2V5U3RvcmUpOworICAgICAgICAgICAgICAgIFRydXN0TWFuYWdlcltdIHRydXN0TWFuYWdlcnMgPSB0bWYuZ2V0VHJ1c3RNYW5hZ2VycygpOworICAgICAgICAgICAgICAgIGZvciAoVHJ1c3RNYW5hZ2VyIHRydXN0TWFuYWdlciA6IHRydXN0TWFuYWdlcnMpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCEodHJ1c3RNYW5hZ2VyIGluc3RhbmNlb2YgWDUwOVRydXN0TWFuYWdlcikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIFg1MDlUcnVzdE1hbmFnZXIgdG0gPSAoWDUwOVRydXN0TWFuYWdlcikgdHJ1c3RNYW5hZ2VyOworICAgICAgICAgICAgICAgICAgICB0bS5jaGVja0NsaWVudFRydXN0ZWQoY2hhaW4sICJSU0EiKTsKKyAgICAgICAgICAgICAgICAgICAgdG0uY2hlY2tTZXJ2ZXJUcnVzdGVkKGNoYWluLCAiUlNBIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9UcnVzdE1hbmFnZXJGYWN0b3J5X2tleU9ubHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gY3JlYXRlIGEgS2V5U3RvcmUgY29udGFpbmluZyBvbmx5IGEgcHJpdmF0ZSBrZXkgd2l0aCBjaGFpbi4KKyAgICAgICAgLy8gdW5saWtlIFBLSVhQYXJhbWV0ZXJzKEtleVN0b3JlKSwgdGhlIGNlcnQgY2hhaW4gb2YgdGhlIGtleSBzaG91bGQgYmUgdHJ1c3RlZC4KKyAgICAgICAgS2V5U3RvcmUga3MgPSBUZXN0S2V5U3RvcmUuY3JlYXRlS2V5U3RvcmUoKTsKKyAgICAgICAgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5IHBrZSA9IGdldFRlc3RLZXlTdG9yZSgpLmdldFByaXZhdGVLZXkoIlJTQSIsICJSU0EiKTsKKyAgICAgICAga3Muc2V0S2V5RW50cnkoImtleSIsIHBrZS5nZXRQcml2YXRlS2V5KCksICJwdyIudG9DaGFyQXJyYXkoKSwgcGtlLmdldENlcnRpZmljYXRlQ2hhaW4oKSk7CisKKyAgICAgICAgU3RyaW5nIGFsZ29yaXRobSA9IFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0RGVmYXVsdEFsZ29yaXRobSgpOworICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5IHRtZiA9IFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtKTsKKyAgICAgICAgdG1mLmluaXQoa3MpOworICAgICAgICBYNTA5VHJ1c3RNYW5hZ2VyIHRydXN0TWFuYWdlciA9IChYNTA5VHJ1c3RNYW5hZ2VyKSB0bWYuZ2V0VHJ1c3RNYW5hZ2VycygpWzBdOworICAgICAgICB0cnVzdE1hbmFnZXIuY2hlY2tTZXJ2ZXJUcnVzdGVkKChYNTA5Q2VydGlmaWNhdGVbXSkgcGtlLmdldENlcnRpZmljYXRlQ2hhaW4oKSwgIlJTQSIpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvc2VjdXJpdHkvYXV0aC94NTAwL1g1MDBQcmluY2lwYWxUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9zZWN1cml0eS9hdXRoL3g1MDAvWDUwMFByaW5jaXBhbFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNjg3YTgyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvc2VjdXJpdHkvYXV0aC94NTAwL1g1MDBQcmluY2lwYWxUZXN0LmphdmEKQEAgLTAsMCArMSw5MyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZheC5zZWN1cml0eS5hdXRoLng1MDA7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgbGliY29yZS5qYXZhLnV0aWwuU2VyaWFsaXphYmxlVGVzdGVyOworCitwdWJsaWMgY2xhc3MgWDUwMFByaW5jaXBhbFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXphdGlvbigpIHsKKyAgICAgICAgU3RyaW5nIGV4cGVjdGVkID0gImFjZWQwMDA1NzM3MjAwMjY2YTYxNzY2MTc4MmU3MzY1NjM3NTcyNjk3NDc5MmU2MTc1NzQ2ODJlNyIKKyAgICAgICAgICAgICAgICArICI4MzUzMDMwMmU1ODM1MzAzMDUwNzI2OTZlNjM2OTcwNjE2Y2Y5MGRmZjNjODhiODc3YzcwMzAwMDA3ODcwNzU3MiIKKyAgICAgICAgICAgICAgICArICIwMDAyNWI0MmFjZjMxN2Y4MDYwODU0ZTAwMjAwMDA3ODcwMDAwMDAwNmEzMDY4MzExNzMwMTUwNjAzNTUwNDAzMSIKKyAgICAgICAgICAgICAgICArICIzMGU3Nzc3NzcyZTY3NmY2ZjY3NmM2NTJlNjM2ZjZkMzExMzMwMTEwNjAzNTUwNDBhMTMwYTQ3NmY2ZjY3NmM2NSIKKyAgICAgICAgICAgICAgICArICIyMDQ5NmU2MzMxMTYzMDE0MDYwMzU1MDQwNzEzMGQ0ZDZmNzU2ZTc0NjE2OTZlMjA1NjY5NjU3NzMxMTMzMDExMCIKKyAgICAgICAgICAgICAgICArICI2MDM1NTA0MDgxMzBhNDM2MTZjNjk2NjZmNzI2ZTY5NjEzMTBiMzAwOTA2MDM1NTA0MDYxMzAyNTU1Mzc4IjsKKyAgICAgICAgWDUwMFByaW5jaXBhbCBhY3R1YWwgPSBuZXcgWDUwMFByaW5jaXBhbCgiQz1VUywgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIlNUPUNhbGlmb3JuaWEsICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJMPU1vdW50YWluIFZpZXcsICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJPPUdvb2dsZSBJbmMsICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJDTj13d3cuZ29vZ2xlLmNvbSIpOworICAgICAgICBuZXcgU2VyaWFsaXphYmxlVGVzdGVyPFg1MDBQcmluY2lwYWw+KGFjdHVhbCwgZXhwZWN0ZWQpLnRlc3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBU04xLWVuY29kZWQgdHJ1c3RlZCBjZXJ0aWZpY2F0ZSAjOTQ2MDU5NjIyIGZvcgorICAgICAqIEVudHJ1c3QubmV0LiBUaGlzIGNlcnRpZmljYXRlIHVzZXMgdGhlIFQ2MVN0cmluZyAoYWthCisgICAgICogVGVsZXRleFN0cmluZyBvciBURUxFVEVYU1RSSU5HKSBlbmNvZGluZyBmb3Igb25lCisgICAgICogb3JnYW5pemF0aW9uYWxVbml0TmFtZXM6CisgICAgICoKKyAgICAgKiAid3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKSIKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gVDYxU1RSSU5HX0NFUlQgPSBuZXcgYnl0ZVtdIHsgNDgsIC0xMjYsIDQsIDkyLCA0OCwgLTEyNiwgMywgNjgsIC05NiwgMywgMiwgMSwgMiwgMiwgNCwgNTYsIDk5LCAtNzEsIDEwMiwgNDgsIDEzLCA2LCA5LCA0MiwgLTEyMiwgNzIsIC0xMjIsIC05LCAxMywgMSwgMSwgNSwgNSwgMCwgNDgsIC0xMjcsIC03NiwgNDksIDIwLCA0OCwgMTgsIDYsIDMsIDg1LCA0LCAxMCwgMTksIDExLCA2OSwgMTEwLCAxMTYsIDExNCwgMTE3LCAxMTUsIDExNiwgNDYsIDExMCwgMTAxLCAxMTYsIDQ5LCA2NCwgNDgsIDYyLCA2LCAzLCA4NSwgNCwgMTEsIDIwLCA1NSwgMTE5LCAxMTksIDExOSwgNDYsIDEwMSwgMTEwLCAxMTYsIDExNCwgMTE3LCAxMTUsIDExNiwgNDYsIDExMCwgMTAxLCAxMTYsIDQ3LCA2NywgODAsIDgzLCA5NSwgNTAsIDQ4LCA1MiwgNTYsIDMyLCAxMDUsIDExMCwgOTksIDExMSwgMTE0LCAxMTIsIDQ2LCAzMiwgOTgsIDEyMSwgMzIsIDExNCwgMTAxLCAxMDIsIDQ2LCAzMiwgNDAsIDEwOCwgMTA1LCAxMDksIDEwNSwgMTE2LCAxMTUsIDMyLCAxMDgsIDEwNSwgOTcsIDk4LCA0NiwgNDEsIDQ5LCAzNywgNDgsIDM1LCA2LCAzLCA4NSwgNCwgMTEsIDE5LCAyOCwgNDAsIDk5LCA0MSwgMzIsIDQ5LCA1NywgNTcsIDU3LCAzMiwgNjksIDExMCwgMTE2LCAxMTQsIDExNywgMTE1LCAxMTYsIDQ2LCAxMTAsIDEwMSwgMTE2LCAzMiwgNzYsIDEwNSwgMTA5LCAxMDUsIDExNiwgMTAxLCAxMDAsIDQ5LCA1MSwgNDgsIDQ5LCA2LCAzLCA4NSwgNCwgMywgMTksIDQyLCA2OSwgMTEwLCAxMTYsIDExNCwgMTE3LCAxMTUsIDExNiwgNDYsIDExMCwgMTAxLCAxMTYsIDMyLCA2NywgMTAxLCAxMTQsIDExNiwgMTA1LCAxMDIsIDEwNSwgOTksIDk3LCAxMTYsIDEwNSwgMTExLCAxMTAsIDMyLCA2NSwgMTE3LCAxMTYsIDEwNCwgMTExLCAxMTQsIDEwNSwgMTE2LCAxMjEsIDMyLCA0MCwgNTAsIDQ4LCA1MiwgNTYsIDQxLCA0OCwgMzAsIDIzLCAxMywgNTcsIDU3LCA0OSwgNTAsIDUwLCA1MiwgNDksIDU1LCA1MywgNDgsIDUzLCA0OSwgOTAsIDIzLCAxMywgNDksIDU3LCA0OSwgNTAsIDUwLCA1MiwgNDksIDU2LCA1MCwgNDgsIDUzLCA0OSwgOTAsIDQ4LCAtMTI3LCAtNzYsIDQ5LCAyMCwgNDgsIDE4LCA2LCAzLCA4NSwgNCwgMTAsIDE5LCAxMSwgNjksIDExMCwgMTE2LCAxMTQsIDExNywgMTE1LCAxMTYsIDQ2LCAxMTAsIDEwMSwgMTE2LCA0OSwgNjQsIDQ4LCA2MiwgNiwgMywgODUsIDQsIDExLCAyMCwgNTUsIDExOSwgMTE5LCAxMTksIDQ2LCAxMDEsIDExMCwgMTE2LCAxMTQsIDExNywgMTE1LCAxMTYsIDQ2LCAxMTAsIDEwMSwgMTE2LCA0NywgNjcsIDgwLCA4MywgOTUsIDUwLCA0OCwgNTIsIDU2LCAzMiwgMTA1LCAxMTAsIDk5LCAxMTEsIDExNCwgMTEyLCA0NiwgMzIsIDk4LCAxMjEsIDMyLCAxMTQsIDEwMSwgMTAyLCA0NiwgMzIsIDQwLCAxMDgsIDEwNSwgMTA5LCAxMDUsIDExNiwgMTE1LCAzMiwgMTA4LCAxMDUsIDk3LCA5OCwgNDYsIDQxLCA0OSwgMzcsIDQ4LCAzNSwgNiwgMywgODUsIDQsIDExLCAxOSwgMjgsIDQwLCA5OSwgNDEsIDMyLCA0OSwgNTcsIDU3LCA1NywgMzIsIDY5LCAxMTAsIDExNiwgMTE0LCAxMTcsIDExNSwgMTE2LCA0NiwgMTEwLCAxMDEsIDExNiwgMzIsIDc2LCAxMDUsIDEwOSwgMTA1LCAxMTYsIDEwMSwgMTAwLCA0OSwgNTEsIDQ4LCA0OSwgNiwgMywgODUsIDQsIDMsIDE5LCA0MiwgNjksIDExMCwgMTE2LCAxMTQsIDExNywgMTE1LCAxMTYsIDQ2LCAxMTAsIDEwMSwgMTE2LCAzMiwgNjcsIDEwMSwgMTE0LCAxMTYsIDEwNSwgMTAyLCAxMDUsIDk5LCA5NywgMTE2LCAxMDUsIDExMSwgMTEwLCAzMiwgNjUsIDExNywgMTE2LCAxMDQsIDExMSwgMTE0LCAxMDUsIDExNiwgMTIxLCAzMiwgNDAsIDUwLCA0OCwgNTIsIDU2LCA0MSwgNDgsIC0xMjYsIDEsIDM0LCA0OCwgMTMsIDYsIDksIDQyLCAtMTIyLCA3MiwgLTEyMiwgLTksIDEzLCAxLCAxLCAxLCA1LCAwLCAzLCAtMTI2LCAxLCAxNSwgMCwgNDgsIC0xMjYsIDEsIDEwLCAyLCAtMTI2LCAxLCAxLCAwLCAtODMsIDc3LCA3NSwgLTg3LCAxOCwgLTEyMiwgLTc4LCAtMjIsIC05MywgMzIsIDcsIDIxLCAyMiwgMTAwLCA0MiwgNDMsIDc1LCAtNDcsIC02NSwgMTEsIDc0LCA3NywgLTExNCwgLTE5LCAtMTI4LCAxMTgsIC05MSwgMTAzLCAtNzMsIDEyMCwgNjQsIC02NCwgMTE1LCA2NiwgLTU2LCAxMDQsIC02NCwgLTM3LCA4MywgNDMsIC0zNSwgOTQsIC03MiwgMTE4LCAtMTA0LCA1MywgLTEwOSwgLTExNywgMjYsIC05OSwgMTI0LCAxOSwgNTgsIDE0LCAzMSwgOTEsIC03MywgMzAsIC00OSwgLTI3LCAzNiwgMjAsIDMwLCAtNzksIC0xMjcsIC04NywgLTExNSwgMTI1LCAtNzIsIC01MiwgMTA3LCA3NSwgMywgLTE1LCAyLCAxMiwgLTM2LCAtODUsIC05MSwgNjQsIDM2LCAwLCAxMjcsIDExNiwgLTEwOCwgLTk1LCAtOTksIDgsIDQxLCAtNzcsIC0xMjAsIDExLCAtMTEsIC0xMjEsIDExOSwgLTk5LCA4NSwgLTUxLCAtMjgsIC02MSwgMTI2LCAtNDEsIDEwNiwgMTAwLCAtODUsIC0xMjMsIDIwLCAtMTIyLCAtMTA3LCA5MSwgLTEwNSwgNTAsIDgwLCAxMTEsIDYxLCAtNTYsIC03MCwgMTAyLCAxMiwgLTI5LCAtNCwgLTY3LCAtNzIsIDczLCAtNjMsIDExOCwgLTExOSwgNzMsIDI1LCAtMywgLTY0LCAtODgsIC02NywgLTExOSwgLTkzLCAxMDMsIDQ3LCAtNTgsIC05NywgLTY4LCAxMTMsIDI1LCA5NiwgLTcyLCA0NSwgLTIzLCA0NCwgLTU1LCAtMTEyLCAxMTgsIDEwMiwgMTIzLCAtMTA4LCAtMzAsIC04MSwgMTIwLCAtNDIsIDEwMSwgODMsIDkzLCA2MCwgLTQyLCAtMTAwLCAtNzgsIC00OSwgNDEsIDMsIC03LCA0NywgLTkyLCA4MCwgLTc4LCAtNDQsIDcyLCAtNTAsIDUsIDUwLCA4NSwgLTExOCwgLTMsIC03OCwgMTAwLCA3NiwgMTQsIC0yOCwgLTEwNCwgNywgMTE3LCAtMzcsIDEyNywgLTMzLCAtNzEsIDgsIDg1LCA5NiwgLTEyMywgNDgsIDQxLCAtNywgMTIzLCA3MiwgLTkyLCAxMDUsIC0xMjIsIC0yOSwgNTMsIDYzLCAzMCwgLTEyMiwgOTMsIDEyMiwgMTIyLCAyMSwgLTY3LCAtMTcsIDAsIC0xMTQsIDIxLCAzNCwgODQsIDIzLCAwLCAtMTEyLCAzOCwgLTEwOSwgLTY4LCAxNCwgNzMsIDEwNCwgLTExMSwgLTY1LCAtOCwgNzEsIC00NSwgLTk5LCAtMTA3LCA2NiwgLTYzLCAxNCwgNzcsIC0zMywgMTExLCAzOCwgLTQ5LCAtNjEsIDI0LCAzMywgOTgsIDEwMiwgNjcsIDExMiwgLTQyLCAtNDMsIC02NCwgNywgLTMxLCAyLCAzLCAxLCAwLCAxLCAtOTMsIDExNiwgNDgsIDExNCwgNDgsIDE3LCA2LCA5LCA5NiwgLTEyMiwgNzIsIDEsIC0xMjIsIC04LCA2NiwgMSwgMSwgNCwgNCwgMywgMiwgMCwgNywgNDgsIDMxLCA2LCAzLCA4NSwgMjksIDM1LCA0LCAyNCwgNDgsIDIyLCAtMTI4LCAyMCwgODUsIC0yOCwgLTEyNywgLTQ3LCAxNywgLTEyOCwgLTY2LCAtNDAsIC0xMTksIC03MSwgOCwgLTkzLCA0OSwgLTcsIC05NSwgMzYsIDksIDIyLCAtNzEsIDExMiwgNDgsIDI5LCA2LCAzLCA4NSwgMjksIDE0LCA0LCAyMiwgNCwgMjAsIDg1LCAtMjgsIC0xMjcsIC00NywgMTcsIC0xMjgsIC02NiwgLTQwLCAtMTE5LCAtNzEsIDgsIC05MywgNDksIC03LCAtOTUsIDM2LCA5LCAyMiwgLTcxLCAxMTIsIDQ4LCAyOSwgNiwgOSwgNDIsIC0xMjIsIDcyLCAtMTIyLCAtMTAsIDEyNSwgNywgNjUsIDAsIDQsIDE2LCA0OCwgMTQsIDI3LCA4LCA4NiwgNTMsIDQ2LCA0OCwgNTgsIDUyLCA0NiwgNDgsIDMsIDIsIDQsIC0xMTIsIDQ4LCAxMywgNiwgOSwgNDIsIC0xMjIsIDcyLCAtMTIyLCAtOSwgMTMsIDEsIDEsIDUsIDUsIDAsIDMsIC0xMjYsIDEsIDEsIDAsIDg5LCA3MSwgLTg0LCAzMywgLTEyNCwgLTExOCwgMjMsIC01NSwgLTEwMCwgLTExOSwgODMsIDMwLCAtNzAsIC0xMjgsIC0xMjMsIDI2LCAtNTgsIDYwLCA3OCwgNjIsIC03OSwgLTEwMCwgLTc0LCAxMjQsIC01OCwgLTExMCwgOTMsIDI0LCAxMDAsIDIsIC0yOSwgLTQ1LCA2LCA4LCAxNywgOTcsIDEyNCwgOTksIC0yOSwgNDMsIC05OSwgNDksIDMsIDExMiwgMTE4LCAtNDYsIC05MywgNDAsIC05NiwgLTEyLCAtNjksIC0xMDIsIDk5LCAxMTUsIC0xOSwgMTA5LCAtMjcsIDQyLCAtMzcsIC0xOSwgMjAsIC04NywgNDMsIC01OCwgNTQsIDE3LCAtNDgsIDQzLCAtMjEsIDcsIC0xMTcsIC05MSwgLTM4LCAtOTgsIDkyLCAyNSwgLTk5LCA4NiwgMTgsIC0xMSwgODQsIDQxLCAtNTYsIDUsIC0xOSwgLTc4LCAxOCwgNDIsIC0xMTUsIC0xMiwgMywgMjcsIC0xLCAtMjUsIC0xMTAsIDE2LCAtMTIxLCAtODAsIDU4LCAtNzUsIC02MSwgLTk5LCA1LCA1NSwgMTgsIC05MywgLTU3LCAtMTIsIDIxLCAtNzEsIC00MywgLTkyLCA1NywgMjIsIC0xMDEsIDgzLCA1OCwgMzUsIC0xMTEsIC0xNSwgLTg4LCAtMTI2LCAtOTQsIDEwNiwgLTEyMCwgMTA0LCAtNjMsIDEyMSwgMiwgMzQsIC02OCwgLTg2LCAtOTAsIC00MiwgLTgyLCAtMzMsIC04MCwgMjAsIDk1LCAtNzIsIC0xMjEsIC00OCwgLTM1LCAxMjQsIDEyNywgMTIzLCAtMSwgLTgxLCAyOCwgLTQ5LCAtMjYsIC0zNywgNywgLTgzLCA5NCwgLTM3LCAtMTIzLCAtOTksIC00OCwgNDMsIDEzLCA1MSwgLTM3LCA0LCAtNDcsIC0yNiwgNzMsIDY0LCAxOSwgNDMsIDExOCwgLTUsIDYyLCAtMjMsIC0xMDAsIC0xMTksIDE1LCAyMSwgLTUwLCAyNCwgLTgwLCAtMTIzLCAxMjAsIDMzLCA3OSwgMTA3LCA3OSwgMTQsIC02LCA1NCwgMTAzLCAtNTEsIDcsIC0xNCwgLTEsIDgsIC00OCwgLTMwLCAtMzQsIC0zOSwgLTY1LCA0MiwgLTgxLCAtNzIsIC0xMjEsIC0xMjIsIDMzLCA2MCwgNCwgLTU0LCAtNzMsIC0xMDgsIDEwNCwgMTI3LCAtNDksIDYwLCAtMjMsIC0xMDQsIC00MSwgNTYsIC0xLCAtMjAsIC02NCwgLTM5LCA4MCwgLTE2LCA0NiwgNzUsIDg4LCAtODIsIDcwLCAxMTEsIC00OCwgNDYsIC02MSwgOTYsIC0zOCwgMTE0LCA4NSwgMTE0LCAtNjcsIDc2LCA2OSwgLTk4LCA5NywgLTcwLCAtNjUsIC0xMjQsIC0xMjcsIC0xMTAsIDMsIC00NywgLTQ2LCAxMDUsIDEyNCwgLTU5IH07CisKKyAgICAvKioKKyAgICAgKiBDb25maXJtIERSTENlcnRGYWN0b3J5IHVzZXMgYSBub24taGV4IGZvcm1hdCBmb3IgVDYxU3RyaW5nIGVuY29kaW5nOiBodHRwOi8vYi8yMTAyMTkxCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldE5hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNlcnRGYWN0QkMgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5IiwgIkJDIik7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZXJ0RmFjdERSTCA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiLCAiRFJMQ2VydEZhY3RvcnkiKTsKKworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydEJDID0gKFg1MDlDZXJ0aWZpY2F0ZSkKKyAgICAgICAgICAgICAgICBjZXJ0RmFjdEJDLmdlbmVyYXRlQ2VydGlmaWNhdGUobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKFQ2MVNUUklOR19DRVJUKSk7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0RFJMID0gKFg1MDlDZXJ0aWZpY2F0ZSkKKyAgICAgICAgICAgICAgICBjZXJ0RmFjdERSTC5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShUNjFTVFJJTkdfQ0VSVCkpOworCisgICAgICAgIGFzc2VydEVxdWFscyhjZXJ0QkMsIGNlcnREUkwpOworCisgICAgICAgIGFzc2VydEVxdWFscyhjZXJ0QkMuZ2V0U3ViamVjdFg1MDBQcmluY2lwYWwoKSwgY2VydEJDLmdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoY2VydERSTC5nZXRJc3N1ZXJYNTAwUHJpbmNpcGFsKCksIGNlcnREUkwuZ2V0SXNzdWVyWDUwMFByaW5jaXBhbCgpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoY2VydEJDLmdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCksIGNlcnREUkwuZ2V0U3ViamVjdFg1MDBQcmluY2lwYWwoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjZXJ0QkMuZ2V0SXNzdWVyWDUwMFByaW5jaXBhbCgpLCBjZXJ0RFJMLmdldElzc3Vlclg1MDBQcmluY2lwYWwoKSk7CisKKyAgICAgICAgU3RyaW5nW10gZm9ybWF0cyA9IHsKKyAgICAgICAgICAgIFg1MDBQcmluY2lwYWwuQ0FOT05JQ0FMLAorICAgICAgICAgICAgWDUwMFByaW5jaXBhbC5SRkMxNzc5LAorICAgICAgICAgICAgWDUwMFByaW5jaXBhbC5SRkMyMjUzCisgICAgICAgIH07CisgICAgICAgIGZvciAoU3RyaW5nIGZvcm1hdCA6IGZvcm1hdHMpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjZXJ0QkMuZ2V0U3ViamVjdFg1MDBQcmluY2lwYWwoKS5nZXROYW1lKGZvcm1hdCksCisgICAgICAgICAgICAgICAgICAgICAgICAgY2VydERSTC5nZXRTdWJqZWN0WDUwMFByaW5jaXBhbCgpLmdldE5hbWUoZm9ybWF0KSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoY2VydEJDLmdldElzc3Vlclg1MDBQcmluY2lwYWwoKS5nZXROYW1lKGZvcm1hdCksCisgICAgICAgICAgICAgICAgICAgICAgICAgY2VydERSTC5nZXRJc3N1ZXJYNTAwUHJpbmNpcGFsKCkuZ2V0TmFtZShmb3JtYXQpKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgZXhwZWN0ZWQgPSAiIgorICAgICAgICAgICAgICAgICsgImNuPWVudHJ1c3QubmV0IGNlcnRpZmljYXRpb24gYXV0aG9yaXR5ICgyMDQ4KSwiCisgICAgICAgICAgICAgICAgKyAib3U9KGMpIDE5OTkgZW50cnVzdC5uZXQgbGltaXRlZCwiCisgICAgICAgICAgICAgICAgKyAib3U9d3d3LmVudHJ1c3QubmV0L2Nwc18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKSwiCisgICAgICAgICAgICAgICAgKyAibz1lbnRydXN0Lm5ldCI7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwKKyAgICAgICAgICAgICAgICAgICAgIGNlcnRCQy5nZXRTdWJqZWN0WDUwMFByaW5jaXBhbCgpLmdldE5hbWUoWDUwMFByaW5jaXBhbC5DQU5PTklDQUwpKTsKKworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L3NxbC9PbGRDb25uZWN0aW9uRXZlbnRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9zcWwvT2xkQ29ubmVjdGlvbkV2ZW50VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU1NDA4ZDEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9zcWwvT2xkQ29ubmVjdGlvbkV2ZW50VGVzdC5qYXZhCkBAIC0wLDAgKzEsNjEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YXguc3FsOworCitpbXBvcnQgamF2YS5zcWwuQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247CitpbXBvcnQgamF2YXguc3FsLkNvbm5lY3Rpb25FdmVudDsKK2ltcG9ydCBqYXZheC5zcWwuQ29ubmVjdGlvbkV2ZW50TGlzdGVuZXI7CitpbXBvcnQgamF2YXguc3FsLlBvb2xlZENvbm5lY3Rpb247CitpbXBvcnQgamF2YXguc3FsLlN0YXRlbWVudEV2ZW50TGlzdGVuZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgT2xkQ29ubmVjdGlvbkV2ZW50VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25zdHJ1Y3RvckNvbm5lY3Rpb24oKSB7CisgICAgICAgIEltcGxfUG9vbGVkQ29ubmVjdGlvbiBpcGMgPSBuZXcgSW1wbF9Qb29sZWRDb25uZWN0aW9uKCk7CisgICAgICAgIENvbm5lY3Rpb25FdmVudCBjZSA9IG5ldyBDb25uZWN0aW9uRXZlbnQoaXBjKTsKKyAgICAgICAgQ29ubmVjdGlvbkV2ZW50IGNlMiA9IG5ldyBDb25uZWN0aW9uRXZlbnQoaXBjLG51bGwpOworICAgICAgICBhc3NlcnRTYW1lKGNlMi5nZXRTb3VyY2UoKSxjZS5nZXRTb3VyY2UoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFNRTEV4Y2VwdGlvbigpIHsKKyAgICAgICAgSW1wbF9Qb29sZWRDb25uZWN0aW9uIGlwYyA9IG5ldyBJbXBsX1Bvb2xlZENvbm5lY3Rpb24oKTsKKyAgICAgICAgQ29ubmVjdGlvbkV2ZW50IGNlID0gbmV3IENvbm5lY3Rpb25FdmVudChpcGMpOworCisgICAgICAgIENvbm5lY3Rpb25FdmVudCBjZTIgPSBuZXcgQ29ubmVjdGlvbkV2ZW50KGlwYywgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoY2UuZ2V0U1FMRXhjZXB0aW9uKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoY2UyLmdldFNRTEV4Y2VwdGlvbigpLCBjZS5nZXRTUUxFeGNlcHRpb24oKSk7CisKKyAgICAgICAgU1FMRXhjZXB0aW9uIGUgPSBuZXcgU1FMRXhjZXB0aW9uKCk7CisgICAgICAgIENvbm5lY3Rpb25FdmVudCBjZTMgPSBuZXcgQ29ubmVjdGlvbkV2ZW50KGlwYywgZSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoY2UzLmdldFNRTEV4Y2VwdGlvbigpKTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShjZTMuZ2V0U1FMRXhjZXB0aW9uKCksIGNlMi5nZXRTUUxFeGNlcHRpb24oKSk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIEltcGxfUG9vbGVkQ29ubmVjdGlvbiBpbXBsZW1lbnRzIFBvb2xlZENvbm5lY3Rpb24geworICAgICAgICBwdWJsaWMgdm9pZCBhZGRDb25uZWN0aW9uRXZlbnRMaXN0ZW5lcihDb25uZWN0aW9uRXZlbnRMaXN0ZW5lciB0aGVMaXN0ZW5lcikge30KKyAgICAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHt9CisgICAgICAgIHB1YmxpYyBDb25uZWN0aW9uIGdldENvbm5lY3Rpb24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZUNvbm5lY3Rpb25FdmVudExpc3RlbmVyKENvbm5lY3Rpb25FdmVudExpc3RlbmVyIGxpc3RlbmVyKSB7fQorICAgICAgICBwdWJsaWMgdm9pZCBhZGRTdGF0ZW1lbnRFdmVudExpc3RlbmVyKFN0YXRlbWVudEV2ZW50TGlzdGVuZXIgbGlzdGVuZXIpIHt9CisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZVN0YXRlbWVudEV2ZW50TGlzdGVuZXIoU3RhdGVtZW50RXZlbnRMaXN0ZW5lciBsaXN0ZW5lcikge30KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC94bWwvcGFyc2Vycy9Eb2N1bWVudEJ1aWxkZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC94bWwvcGFyc2Vycy9Eb2N1bWVudEJ1aWxkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjQ2Nzc2YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L3htbC9wYXJzZXJzL0RvY3VtZW50QnVpbGRlclRlc3QuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmF4LnhtbC5wYXJzZXJzOworCitpbXBvcnQgc3RhdGljIHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9YbWwuKjsKKworcHVibGljIGNsYXNzIERvY3VtZW50QnVpbGRlclRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9MjYwNworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2hhcmFjdGVyUmVmZXJlbmNlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoImFBYiIsIGZpcnN0Q2hpbGRUZXh0T2YoZG9tT2YoIjxwPmEmIzY1O2I8L3A+IikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhQWIiLCBmaXJzdENoaWxkVGV4dE9mKGRvbU9mKCI8cD5hJiN4NDE7YjwvcD4iKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFcdTAwZmNiIiwgZmlyc3RDaGlsZFRleHRPZihkb21PZigiPHA+YSYjMjUyO2I8L3A+IikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhXHUwMGZjYiIsIGZpcnN0Q2hpbGRUZXh0T2YoZG9tT2YoIjxwPmEmI3hmYztiPC9wPiIpKSk7CisgICAgfQorCisgICAgLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD0yNjA3CisgICAgcHVibGljIHZvaWQgdGVzdF9wcmVkZWZpbmVkRW50aXRpZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhPGIiLCBmaXJzdENoaWxkVGV4dE9mKGRvbU9mKCI8cD5hJmx0O2I8L3A+IikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhPmIiLCBmaXJzdENoaWxkVGV4dE9mKGRvbU9mKCI8cD5hJmd0O2I8L3A+IikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhJmIiLCBmaXJzdENoaWxkVGV4dE9mKGRvbU9mKCI8cD5hJmFtcDtiPC9wPiIpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSdiIiwgZmlyc3RDaGlsZFRleHRPZihkb21PZigiPHA+YSZhcG9zO2I8L3A+IikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhXCJiIiwgZmlyc3RDaGlsZFRleHRPZihkb21PZigiPHA+YSZxdW90O2I8L3A+IikpKTsKKyAgICB9CisKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTI0ODcKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NkYXRhX2F0dHJpYnV0ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJoZWxsbyAmIHdvcmxkIiwgYXR0ck9mKGZpcnN0RWxlbWVudE9mKGRvbU9mKCI8P3htbCB2ZXJzaW9uPVwiMS4wXCI/Pjxyb290IGF0dHI9XCJoZWxsbyAmYW1wOyB3b3JsZFwiIC8+IikpKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkb21PZigiPD94bWwgdmVyc2lvbj1cIjEuMFwiPz48cm9vdCBhdHRyPVwiaGVsbG8gPCFbQ0RBVEFbIHNvbWUtY2RhdGEgXV0+IHdvcmxkXCIgLz4iKTsKKyAgICAgICAgICAgIGZhaWwoIlNBWFBhcnNlRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAob3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiaGVsbG8gPCFbQ0RBVEFbIHNvbWUtY2RhdGEgXV0+IHdvcmxkIiwgYXR0ck9mKGZpcnN0RWxlbWVudE9mKGRvbU9mKCI8P3htbCB2ZXJzaW9uPVwiMS4wXCI/Pjxyb290IGF0dHI9XCJoZWxsbyAmbHQ7IVtDREFUQVsgc29tZS1jZGF0YSBdXSZndDsgd29ybGRcIiAvPiIpKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImhlbGxvIDwhW0NEQVRBWyBzb21lLWNkYXRhIF1dPiB3b3JsZCIsIGF0dHJPZihmaXJzdEVsZW1lbnRPZihkb21PZigiPD94bWwgdmVyc2lvbj1cIjEuMFwiPz48cm9vdCBhdHRyPVwiaGVsbG8gJmx0OyFbQ0RBVEFbIHNvbWUtY2RhdGEgXV0+IHdvcmxkXCIgLz4iKSkpKTsKKyAgICB9CisKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTI0ODcKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NkYXRhX2JvZHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJoZWxsbyAmIHdvcmxkIiwgZmlyc3RDaGlsZFRleHRPZihkb21PZigiPD94bWwgdmVyc2lvbj1cIjEuMFwiPz48cm9vdD5oZWxsbyAmYW1wOyB3b3JsZDwvcm9vdD4iKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImhlbGxvICBzb21lLWNkYXRhICB3b3JsZCIsIGZpcnN0Q2hpbGRUZXh0T2YoZG9tT2YoIjw/eG1sIHZlcnNpb249XCIxLjBcIj8+PHJvb3Q+aGVsbG8gPCFbQ0RBVEFbIHNvbWUtY2RhdGEgXV0+IHdvcmxkPC9yb290PiIpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaGVsbG8gPCFbQ0RBVEFbIHNvbWUtY2RhdGEgXV0+IHdvcmxkIiwgZmlyc3RDaGlsZFRleHRPZihkb21PZigiPD94bWwgdmVyc2lvbj1cIjEuMFwiPz48cm9vdD5oZWxsbyAmbHQ7IVtDREFUQVsgc29tZS1jZGF0YSBdXSZndDsgd29ybGQ8L3Jvb3Q+IikpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRvbU9mKCI8P3htbCB2ZXJzaW9uPVwiMS4wXCI/Pjxyb290PmhlbGxvICZsdDshW0NEQVRBWyBzb21lLWNkYXRhIF1dPiB3b3JsZDwvcm9vdD4iKTsKKyAgICAgICAgICAgIGZhaWwoIlNBWFBhcnNlRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAob3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvSHR0cFJlc3BvbnNlQ2FjaGVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9uZXQvaHR0cC9IdHRwUmVzcG9uc2VDYWNoZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNjJhMDBlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvSHR0cFJlc3BvbnNlQ2FjaGVUZXN0LmphdmEKQEAgLTAsMCArMSwxODM3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLm5ldC5odHRwOworCitpbXBvcnQgY29tLmdvb2dsZS5tb2Nrd2Vic2VydmVyLk1vY2tSZXNwb25zZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vY2t3ZWJzZXJ2ZXIuTW9ja1dlYlNlcnZlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vY2t3ZWJzZXJ2ZXIuUmVjb3JkZWRSZXF1ZXN0OworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLm1vY2t3ZWJzZXJ2ZXIuU29ja2V0UG9saWN5LkRJU0NPTk5FQ1RfQVRfRU5EOworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25IYW5kbGVyOworaW1wb3J0IGphdmEubmV0LkNhY2hlUmVxdWVzdDsKK2ltcG9ydCBqYXZhLm5ldC5DYWNoZVJlc3BvbnNlOworaW1wb3J0IGphdmEubmV0LkNvb2tpZUhhbmRsZXI7CitpbXBvcnQgamF2YS5uZXQuQ29va2llTWFuYWdlcjsKK2ltcG9ydCBqYXZhLm5ldC5IdHRwQ29va2llOworaW1wb3J0IGphdmEubmV0Lkh0dHBVUkxDb25uZWN0aW9uOworaW1wb3J0IGphdmEubmV0LlJlc3BvbnNlQ2FjaGU7CitpbXBvcnQgamF2YS5uZXQuU2VjdXJlQ2FjaGVSZXNwb25zZTsKK2ltcG9ydCBqYXZhLm5ldC5VUkk7CitpbXBvcnQgamF2YS5uZXQuVVJJU3ludGF4RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnRleHQuRGF0ZUZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuU2ltcGxlRGF0ZUZvcm1hdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5EZXF1ZTsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5UaW1lWm9uZTsKK2ltcG9ydCBqYXZhLnV0aWwuVVVJRDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljUmVmZXJlbmNlOworaW1wb3J0IGphdmEudXRpbC56aXAuR1pJUE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLkh0dHBzVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgbGliY29yZS5qYXZheC5uZXQuc3NsLlRlc3RTU0xDb250ZXh0OworaW1wb3J0IHRlc3RzLmlvLk1vY2tPczsKKworcHVibGljIGZpbmFsIGNsYXNzIEh0dHBSZXNwb25zZUNhY2hlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwcml2YXRlIE1vY2tXZWJTZXJ2ZXIgc2VydmVyID0gbmV3IE1vY2tXZWJTZXJ2ZXIoKTsKKyAgICBwcml2YXRlIEh0dHBSZXNwb25zZUNhY2hlIGNhY2hlOworICAgIHByaXZhdGUgZmluYWwgTW9ja09zIG1vY2tPcyA9IG5ldyBNb2NrT3MoKTsKKyAgICBwcml2YXRlIGZpbmFsIENvb2tpZU1hbmFnZXIgY29va2llTWFuYWdlciA9IG5ldyBDb29raWVNYW5hZ2VyKCk7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKworICAgICAgICBTdHJpbmcgdG1wID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmlvLnRtcGRpciIpOworICAgICAgICBGaWxlIGNhY2hlRGlyID0gbmV3IEZpbGUodG1wLCAiSHR0cENhY2hlLSIgKyBVVUlELnJhbmRvbVVVSUQoKSk7CisgICAgICAgIGNhY2hlID0gbmV3IEh0dHBSZXNwb25zZUNhY2hlKGNhY2hlRGlyLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIFJlc3BvbnNlQ2FjaGUuc2V0RGVmYXVsdChjYWNoZSk7CisgICAgICAgIG1vY2tPcy5pbnN0YWxsKCk7CisgICAgICAgIENvb2tpZUhhbmRsZXIuc2V0RGVmYXVsdChjb29raWVNYW5hZ2VyKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbW9ja09zLnVuaW5zdGFsbCgpOworICAgICAgICBzZXJ2ZXIuc2h1dGRvd24oKTsKKyAgICAgICAgUmVzcG9uc2VDYWNoZS5zZXREZWZhdWx0KG51bGwpOworICAgICAgICBjYWNoZS5nZXRDYWNoZSgpLmRlbGV0ZSgpOworICAgICAgICBDb29raWVIYW5kbGVyLnNldERlZmF1bHQobnVsbCk7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHJlc3BvbnNlIGNhY2hpbmcgaXMgY29uc2lzdGVudCB3aXRoIHRoZSBSSSBhbmQgdGhlIHNwZWMuCisgICAgICogaHR0cDovL3d3dy53My5vcmcvUHJvdG9jb2xzL3JmYzI2MTYvcmZjMjYxNi1zZWMxMy5odG1sI3NlYzEzLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVzcG9uc2VDYWNoaW5nQnlSZXNwb25zZUNvZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBlYWNoIGRvY3VtZW50ZWQgSFRUUC8xLjEgY29kZSwgcGx1cyB0aGUgZmlyc3QgdW51c2VkIHZhbHVlIGluIGVhY2ggcmFuZ2UuCisgICAgICAgIC8vIGh0dHA6Ly93d3cudzMub3JnL1Byb3RvY29scy9yZmMyNjE2L3JmYzI2MTYtc2VjMTAuaHRtbAorCisgICAgICAgIC8vIFdlIGNhbid0IHRlc3QgMTAwIGJlY2F1c2UgaXQncyBub3QgcmVhbGx5IGEgcmVzcG9uc2UuCisgICAgICAgIC8vIGFzc2VydENhY2hlZChmYWxzZSwgMTAwKTsKKyAgICAgICAgYXNzZXJ0Q2FjaGVkKGZhbHNlLCAxMDEpOworICAgICAgICBhc3NlcnRDYWNoZWQoZmFsc2UsIDEwMik7CisgICAgICAgIGFzc2VydENhY2hlZCh0cnVlLCAgMjAwKTsKKyAgICAgICAgYXNzZXJ0Q2FjaGVkKGZhbHNlLCAyMDEpOworICAgICAgICBhc3NlcnRDYWNoZWQoZmFsc2UsIDIwMik7CisgICAgICAgIGFzc2VydENhY2hlZCh0cnVlLCAgMjAzKTsKKyAgICAgICAgYXNzZXJ0Q2FjaGVkKGZhbHNlLCAyMDQpOworICAgICAgICBhc3NlcnRDYWNoZWQoZmFsc2UsIDIwNSk7CisgICAgICAgIGFzc2VydENhY2hlZChmYWxzZSwgMjA2KTsgLy8gd2UgZG9uJ3QgY2FjaGUgcGFydGlhbCByZXNwb25zZXMKKyAgICAgICAgYXNzZXJ0Q2FjaGVkKGZhbHNlLCAyMDcpOworICAgICAgICBhc3NlcnRDYWNoZWQodHJ1ZSwgIDMwMCk7CisgICAgICAgIGFzc2VydENhY2hlZCh0cnVlLCAgMzAxKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDMwMjsgaSA8PSAzMDg7ICsraSkgeworICAgICAgICAgICAgYXNzZXJ0Q2FjaGVkKGZhbHNlLCBpKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gNDAwOyBpIDw9IDQwNjsgKytpKSB7CisgICAgICAgICAgICBhc3NlcnRDYWNoZWQoZmFsc2UsIGkpOworICAgICAgICB9CisgICAgICAgIC8vIChTZWUgdGVzdF9yZXNwb25zZUNhY2hpbmdfNDA3LikKKyAgICAgICAgYXNzZXJ0Q2FjaGVkKGZhbHNlLCA0MDgpOworICAgICAgICBhc3NlcnRDYWNoZWQoZmFsc2UsIDQwOSk7CisgICAgICAgIC8vIChTZWUgdGVzdF9yZXNwb25zZUNhY2hpbmdfNDEwLikKKyAgICAgICAgZm9yIChpbnQgaSA9IDQxMTsgaSA8PSA0MTg7ICsraSkgeworICAgICAgICAgICAgYXNzZXJ0Q2FjaGVkKGZhbHNlLCBpKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gNTAwOyBpIDw9IDUwNjsgKytpKSB7CisgICAgICAgICAgICBhc3NlcnRDYWNoZWQoZmFsc2UsIGkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzcG9uc2UgY29kZSA0MDcgc2hvdWxkIG9ubHkgY29tZSBmcm9tIHByb3h5IHNlcnZlcnMuIEFuZHJvaWQncyBjbGllbnQKKyAgICAgKiB0aHJvd3MgaWYgaXQgaXMgc2VudCBieSBhbiBvcmlnaW4gc2VydmVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RPcmlnaW5TZXJ2ZXJTZW5kczQwNygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0UmVzcG9uc2VDb2RlKDQwNykpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTCB1cmwgPSBzZXJ2ZXIuZ2V0VXJsKCIvIik7CisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm4gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5nZXRSZXNwb25zZUNvZGUoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVzcG9uc2VDYWNoaW5nXzQxMCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyB0aGUgSFRUUCBzcGVjIHBlcm1pdHMgY2FjaGluZyA0MTBzLCBidXQgdGhlIFJJIGRvZXNuJ3QuCisgICAgICAgIGFzc2VydENhY2hlZCh0cnVlLCA0MTApOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRDYWNoZWQoYm9vbGVhbiBzaG91bGRQdXQsIGludCByZXNwb25zZUNvZGUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIgPSBuZXcgTW9ja1dlYlNlcnZlcigpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMYXN0LU1vZGlmaWVkOiAiICsgZm9ybWF0RGF0ZSgtMSwgVGltZVVuaXQuSE9VUlMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkV4cGlyZXM6ICIgKyBmb3JtYXREYXRlKDEsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuc2V0UmVzcG9uc2VDb2RlKHJlc3BvbnNlQ29kZSkKKyAgICAgICAgICAgICAgICAuc2V0Qm9keSgiQUJDREUiKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIldXVy1BdXRoZW50aWNhdGU6IGNoYWxsZW5nZSIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkwgdXJsID0gc2VydmVyLmdldFVybCgiLyIpOworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uID0gKEh0dHBVUkxDb25uZWN0aW9uKSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc3BvbnNlQ29kZSwgY29ubi5nZXRSZXNwb25zZUNvZGUoKSk7CisKKyAgICAgICAgLy8gZXhoYXVzdCB0aGUgY29udGVudCBzdHJlYW0KKyAgICAgICAgcmVhZEFzY2lpKGNvbm4pOworCisgICAgICAgIENhY2hlUmVzcG9uc2UgY2FjaGVkID0gY2FjaGUuZ2V0KHVybC50b1VSSSgpLCAiR0VUIiwKKyAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy48U3RyaW5nLCBMaXN0PFN0cmluZz4+ZW1wdHlNYXAoKSk7CisgICAgICAgIGlmIChzaG91bGRQdXQpIHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoSW50ZWdlci50b1N0cmluZyhyZXNwb25zZUNvZGUpLCBjYWNoZWQpOworICAgICAgICAgICAgY2FjaGVkLmdldEJvZHkoKS5jbG9zZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYXNzZXJ0TnVsbChJbnRlZ2VyLnRvU3RyaW5nKHJlc3BvbnNlQ29kZSksIGNhY2hlZCk7CisgICAgICAgIH0KKyAgICAgICAgc2VydmVyLnNodXRkb3duKCk7IC8vIHRlYXJEb3duKCkgaXNuJ3Qgc3VmZmljaWVudDsgdGhpcyB0ZXN0IHN0YXJ0cyBtdWx0aXBsZSBzZXJ2ZXJzCisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHdlIGNhbiBpbnRlcnJvZ2F0ZSB0aGUgcmVzcG9uc2Ugd2hlbiB0aGUgY2FjaGUgaXMgYmVpbmcKKyAgICAgKiBwb3B1bGF0ZWQuIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9Nzc4NworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXNwb25zZUNhY2hlQ2FsbGJhY2tBcGlzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyBib2R5ID0gIkFCQ0RFIjsKKyAgICAgICAgZmluYWwgQXRvbWljSW50ZWdlciBjYWNoZUNvdW50ID0gbmV3IEF0b21pY0ludGVnZXIoKTsKKworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuc2V0U3RhdHVzKCJIVFRQLzEuMSAyMDAgRmFudGFzdGljIikKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJmZ2g6IGlqayIpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoYm9keSkpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFJlc3BvbnNlQ2FjaGUuc2V0RGVmYXVsdChuZXcgUmVzcG9uc2VDYWNoZSgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgQ2FjaGVSZXNwb25zZSBnZXQoVVJJIHVyaSwgU3RyaW5nIHJlcXVlc3RNZXRob2QsCisgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gcmVxdWVzdEhlYWRlcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIENhY2hlUmVxdWVzdCBwdXQoVVJJIHVyaSwgVVJMQ29ubmVjdGlvbiBjb25uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGh0dHBDb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBjb25uOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGh0dHBDb25uZWN0aW9uLmdldFJlcXVlc3RQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgaHR0cENvbm5lY3Rpb24uYWRkUmVxdWVzdFByb3BlcnR5KCJLIiwgIlYiKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkhUVFAvMS4xIDIwMCBGYW50YXN0aWMiLCBodHRwQ29ubmVjdGlvbi5nZXRIZWFkZXJGaWVsZChudWxsKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoIkhUVFAvMS4xIDIwMCBGYW50YXN0aWMiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGh0dHBDb25uZWN0aW9uLmdldEhlYWRlckZpZWxkcygpLmdldChudWxsKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDIwMCwgaHR0cENvbm5lY3Rpb24uZ2V0UmVzcG9uc2VDb2RlKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiRmFudGFzdGljIiwgaHR0cENvbm5lY3Rpb24uZ2V0UmVzcG9uc2VNZXNzYWdlKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhib2R5Lmxlbmd0aCgpLCBodHRwQ29ubmVjdGlvbi5nZXRDb250ZW50TGVuZ3RoKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiaWprIiwgaHR0cENvbm5lY3Rpb24uZ2V0SGVhZGVyRmllbGQoImZnaCIpKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBodHRwQ29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpOyAvLyB0aGUgUkkgZG9lc24ndCBmb3JiaWQgdGhpcywgYnV0IGl0IHNob3VsZAorICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY2FjaGVDb3VudC5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisKKyAgICAgICAgVVJMIHVybCA9IHNlcnZlci5nZXRVcmwoIi8iKTsKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhib2R5LCByZWFkQXNjaWkoY29ubmVjdGlvbikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY2FjaGVDb3VudC5nZXQoKSk7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVzcG9uc2VDYWNoaW5nQW5kSW5wdXRTdHJlYW1Ta2lwV2l0aEZpeGVkTGVuZ3RoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFJlc3BvbnNlQ2FjaGluZyhUcmFuc2ZlcktpbmQuRklYRURfTEVOR1RIKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVzcG9uc2VDYWNoaW5nQW5kSW5wdXRTdHJlYW1Ta2lwV2l0aENodW5rZWRFbmNvZGluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RSZXNwb25zZUNhY2hpbmcoVHJhbnNmZXJLaW5kLkNIVU5LRUQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXNwb25zZUNhY2hpbmdBbmRJbnB1dFN0cmVhbVNraXBXaXRoTm9MZW5ndGhIZWFkZXJzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFJlc3BvbnNlQ2FjaGluZyhUcmFuc2ZlcktpbmQuRU5EX09GX1NUUkVBTSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSHR0cFVSTENvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKS5za2lwKGxvbmcpIGNhdXNlcyBSZXNwb25zZUNhY2hlIGNvcnJ1cHRpb24KKyAgICAgKiBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTgxNzUKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgdGVzdFJlc3BvbnNlQ2FjaGluZyhUcmFuc2ZlcktpbmQgdHJhbnNmZXJLaW5kKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBNb2NrUmVzcG9uc2UgcmVzcG9uc2UgPSBuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMYXN0LU1vZGlmaWVkOiAiICsgZm9ybWF0RGF0ZSgtMSwgVGltZVVuaXQuSE9VUlMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkV4cGlyZXM6ICIgKyBmb3JtYXREYXRlKDEsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuc2V0U3RhdHVzKCJIVFRQLzEuMSAyMDAgRmFudGFzdGljIik7CisgICAgICAgIHRyYW5zZmVyS2luZC5zZXRCb2R5KHJlc3BvbnNlLCAiSSBsb3ZlIHB1cHBpZXMgYnV0IGhhdGUgc3BpZGVycyIsIDEpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShyZXNwb25zZSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgY2FsbGluZyBza2lwKCkgZG9lc24ndCBvbWl0IGJ5dGVzIGZyb20gdGhlIGNhY2hlLgorICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiB1cmxDb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSB1cmxDb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSSBsb3ZlICIsIHJlYWRBc2NpaSh1cmxDb25uZWN0aW9uLCAiSSBsb3ZlICIubGVuZ3RoKCkpKTsKKyAgICAgICAgcmVsaWFibGVTa2lwKGluLCAicHVwcGllcyBidXQgaGF0ZSAiLmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzcGlkZXJzIiwgcmVhZEFzY2lpKHVybENvbm5lY3Rpb24sICJzcGlkZXJzIi5sZW5ndGgoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBjYWNoZS5nZXRXcml0ZVN1Y2Nlc3NDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGNhY2hlLmdldFdyaXRlQWJvcnRDb3VudCgpKTsKKworICAgICAgICB1cmxDb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsgLy8gY2FjaGVkIQorICAgICAgICBpbiA9IHVybENvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJIGxvdmUgcHVwcGllcyBidXQgaGF0ZSBzcGlkZXJzIiwKKyAgICAgICAgICAgICAgICByZWFkQXNjaWkodXJsQ29ubmVjdGlvbiwgIkkgbG92ZSBwdXBwaWVzIGJ1dCBoYXRlIHNwaWRlcnMiLmxlbmd0aCgpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyMDAsIHVybENvbm5lY3Rpb24uZ2V0UmVzcG9uc2VDb2RlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhbnRhc3RpYyIsIHVybENvbm5lY3Rpb24uZ2V0UmVzcG9uc2VNZXNzYWdlKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygtMSwgaW4ucmVhZCgpKTsKKyAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNhY2hlLmdldFdyaXRlU3VjY2Vzc0NvdW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgY2FjaGUuZ2V0V3JpdGVBYm9ydENvdW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgY2FjaGUuZ2V0UmVxdWVzdENvdW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY2FjaGUuZ2V0SGl0Q291bnQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNlY3VyZVJlc3BvbnNlQ2FjaGluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IHRlc3RTU0xDb250ZXh0ID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIHNlcnZlci51c2VIdHRwcyh0ZXN0U1NMQ29udGV4dC5zZXJ2ZXJDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKSwgZmFsc2UpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMYXN0LU1vZGlmaWVkOiAiICsgZm9ybWF0RGF0ZSgtMSwgVGltZVVuaXQuSE9VUlMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkV4cGlyZXM6ICIgKyBmb3JtYXREYXRlKDEsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuc2V0Qm9keSgiQUJDIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0U1NMU29ja2V0RmFjdG9yeSh0ZXN0U1NMQ29udGV4dC5jbGllbnRDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJDIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24pKTsKKworICAgICAgICAvLyBPcGVuSkRLIDYgZmFpbHMgb24gdGhpcyBsaW5lLCBjb21wbGFpbmluZyB0aGF0IHRoZSBjb25uZWN0aW9uIGlzbid0IG9wZW4geWV0CisgICAgICAgIFN0cmluZyBzdWl0ZSA9IGNvbm5lY3Rpb24uZ2V0Q2lwaGVyU3VpdGUoKTsKKyAgICAgICAgTGlzdDxDZXJ0aWZpY2F0ZT4gbG9jYWxDZXJ0cyA9IHRvTGlzdE9yTnVsbChjb25uZWN0aW9uLmdldExvY2FsQ2VydGlmaWNhdGVzKCkpOworICAgICAgICBMaXN0PENlcnRpZmljYXRlPiBzZXJ2ZXJDZXJ0cyA9IHRvTGlzdE9yTnVsbChjb25uZWN0aW9uLmdldFNlcnZlckNlcnRpZmljYXRlcygpKTsKKyAgICAgICAgUHJpbmNpcGFsIHBlZXJQcmluY2lwYWwgPSBjb25uZWN0aW9uLmdldFBlZXJQcmluY2lwYWwoKTsKKyAgICAgICAgUHJpbmNpcGFsIGxvY2FsUHJpbmNpcGFsID0gY29ubmVjdGlvbi5nZXRMb2NhbFByaW5jaXBhbCgpOworCisgICAgICAgIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsgLy8gY2FjaGVkIQorICAgICAgICBjb25uZWN0aW9uLnNldFNTTFNvY2tldEZhY3RvcnkodGVzdFNTTENvbnRleHQuY2xpZW50Q29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFCQyIsIHJlYWRBc2NpaShjb25uZWN0aW9uKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGNhY2hlLmdldFJlcXVlc3RDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNhY2hlLmdldE5ldHdvcmtDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNhY2hlLmdldEhpdENvdW50KCkpOworCisgICAgICAgIGFzc2VydEVxdWFscyhzdWl0ZSwgY29ubmVjdGlvbi5nZXRDaXBoZXJTdWl0ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxvY2FsQ2VydHMsIHRvTGlzdE9yTnVsbChjb25uZWN0aW9uLmdldExvY2FsQ2VydGlmaWNhdGVzKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNlcnZlckNlcnRzLCB0b0xpc3RPck51bGwoY29ubmVjdGlvbi5nZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMocGVlclByaW5jaXBhbCwgY29ubmVjdGlvbi5nZXRQZWVyUHJpbmNpcGFsKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobG9jYWxQcmluY2lwYWwsIGNvbm5lY3Rpb24uZ2V0TG9jYWxQcmluY2lwYWwoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENhY2hlUmV0dXJuc0luc2VjdXJlUmVzcG9uc2VGb3JTZWN1cmVSZXF1ZXN0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgdGVzdFNTTENvbnRleHQgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgc2VydmVyLnVzZUh0dHBzKHRlc3RTU0xDb250ZXh0LnNlcnZlckNvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLCBmYWxzZSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJBQkMiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJERUYiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgUmVzcG9uc2VDYWNoZS5zZXREZWZhdWx0KG5ldyBJbnNlY3VyZVJlc3BvbnNlQ2FjaGUoKSk7CisKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXRTU0xTb2NrZXRGYWN0b3J5KHRlc3RTU0xDb250ZXh0LmNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkMiLCByZWFkQXNjaWkoY29ubmVjdGlvbikpOworCisgICAgICAgIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsgLy8gbm90IGNhY2hlZCEKKyAgICAgICAgY29ubmVjdGlvbi5zZXRTU0xTb2NrZXRGYWN0b3J5KHRlc3RTU0xDb250ZXh0LmNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJERUYiLCByZWFkQXNjaWkoY29ubmVjdGlvbikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXNwb25zZUNhY2hpbmdBbmRSZWRpcmVjdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTGFzdC1Nb2RpZmllZDogIiArIGZvcm1hdERhdGUoLTEsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJFeHBpcmVzOiAiICsgZm9ybWF0RGF0ZSgxLCBUaW1lVW5pdC5IT1VSUykpCisgICAgICAgICAgICAgICAgLnNldFJlc3BvbnNlQ29kZShIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX01PVkVEX1BFUk0pCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTG9jYXRpb246IC9mb28iKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkxhc3QtTW9kaWZpZWQ6ICIgKyBmb3JtYXREYXRlKC0xLCBUaW1lVW5pdC5IT1VSUykpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiRXhwaXJlczogIiArIGZvcm1hdERhdGUoMSwgVGltZVVuaXQuSE9VUlMpKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBQkMiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJERUYiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJDIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24pKTsKKworICAgICAgICBjb25uZWN0aW9uID0gc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7IC8vIGNhY2hlZCEKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkMiLCByZWFkQXNjaWkoY29ubmVjdGlvbikpOworCisgICAgICAgIGFzc2VydEVxdWFscyg0LCBjYWNoZS5nZXRSZXF1ZXN0Q291bnQoKSk7IC8vIDIgcmVxdWVzdHMgKyAyIHJlZGlyZWN0cworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgY2FjaGUuZ2V0TmV0d29ya0NvdW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgY2FjaGUuZ2V0SGl0Q291bnQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlZGlyZWN0VG9DYWNoZWRSZXN1bHQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT02MCIpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIkFCQyIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLnNldFJlc3BvbnNlQ29kZShIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX01PVkVEX1BFUk0pCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTG9jYXRpb246IC9mb28iKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJERUYiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkMiLCByZWFkQXNjaWkoc2VydmVyLmdldFVybCgiL2ZvbyIpLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IHJlcXVlc3QxID0gc2VydmVyLnRha2VSZXF1ZXN0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiR0VUIC9mb28gSFRUUC8xLjEiLCByZXF1ZXN0MS5nZXRSZXF1ZXN0TGluZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHJlcXVlc3QxLmdldFNlcXVlbmNlTnVtYmVyKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiQUJDIiwgcmVhZEFzY2lpKHNlcnZlci5nZXRVcmwoIi9iYXIiKS5vcGVuQ29ubmVjdGlvbigpKSk7CisgICAgICAgIFJlY29yZGVkUmVxdWVzdCByZXF1ZXN0MiA9IHNlcnZlci50YWtlUmVxdWVzdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkdFVCAvYmFyIEhUVFAvMS4xIiwgcmVxdWVzdDIuZ2V0UmVxdWVzdExpbmUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCByZXF1ZXN0Mi5nZXRTZXF1ZW5jZU51bWJlcigpKTsKKworICAgICAgICAvLyBhbiB1bnJlbGF0ZWQgcmVxdWVzdCBzaG91bGQgcmV1c2UgdGhlIHBvb2xlZCBjb25uZWN0aW9uCisgICAgICAgIGFzc2VydEVxdWFscygiREVGIiwgcmVhZEFzY2lpKHNlcnZlci5nZXRVcmwoIi9iYXoiKS5vcGVuQ29ubmVjdGlvbigpKSk7CisgICAgICAgIFJlY29yZGVkUmVxdWVzdCByZXF1ZXN0MyA9IHNlcnZlci50YWtlUmVxdWVzdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkdFVCAvYmF6IEhUVFAvMS4xIiwgcmVxdWVzdDMuZ2V0UmVxdWVzdExpbmUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCByZXF1ZXN0My5nZXRTZXF1ZW5jZU51bWJlcigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VjdXJlUmVzcG9uc2VDYWNoaW5nQW5kUmVkaXJlY3RzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFNTTENvbnRleHQgdGVzdFNTTENvbnRleHQgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgc2VydmVyLnVzZUh0dHBzKHRlc3RTU0xDb250ZXh0LnNlcnZlckNvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLCBmYWxzZSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkxhc3QtTW9kaWZpZWQ6ICIgKyBmb3JtYXREYXRlKC0xLCBUaW1lVW5pdC5IT1VSUykpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiRXhwaXJlczogIiArIGZvcm1hdERhdGUoMSwgVGltZVVuaXQuSE9VUlMpKQorICAgICAgICAgICAgICAgIC5zZXRSZXNwb25zZUNvZGUoSHR0cFVSTENvbm5lY3Rpb24uSFRUUF9NT1ZFRF9QRVJNKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkxvY2F0aW9uOiAvZm9vIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMYXN0LU1vZGlmaWVkOiAiICsgZm9ybWF0RGF0ZSgtMSwgVGltZVVuaXQuSE9VUlMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkV4cGlyZXM6ICIgKyBmb3JtYXREYXRlKDEsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuc2V0Qm9keSgiQUJDIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiREVGIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0U1NMU29ja2V0RmFjdG9yeSh0ZXN0U1NMQ29udGV4dC5jbGllbnRDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJDIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24pKTsKKworICAgICAgICBjb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7IC8vIGNhY2hlZCEKKyAgICAgICAgY29ubmVjdGlvbi5zZXRTU0xTb2NrZXRGYWN0b3J5KHRlc3RTU0xDb250ZXh0LmNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkMiLCByZWFkQXNjaWkoY29ubmVjdGlvbikpOworCisgICAgICAgIGFzc2VydEVxdWFscyg0LCBjYWNoZS5nZXRSZXF1ZXN0Q291bnQoKSk7IC8vIDIgZGlyZWN0ICsgMiByZWRpcmVjdCA9IDQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGNhY2hlLmdldEhpdENvdW50KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXNwb25zZUNhY2hlUmVxdWVzdEhlYWRlcnMoKSB0aHJvd3MgSU9FeGNlcHRpb24sIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJBQkMiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgZmluYWwgQXRvbWljUmVmZXJlbmNlPE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4+IHJlcXVlc3RIZWFkZXJzUmVmCisgICAgICAgICAgICAgICAgPSBuZXcgQXRvbWljUmVmZXJlbmNlPE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4+KCk7CisgICAgICAgIFJlc3BvbnNlQ2FjaGUuc2V0RGVmYXVsdChuZXcgUmVzcG9uc2VDYWNoZSgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgQ2FjaGVSZXNwb25zZSBnZXQoVVJJIHVyaSwgU3RyaW5nIHJlcXVlc3RNZXRob2QsCisgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gcmVxdWVzdEhlYWRlcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmVxdWVzdEhlYWRlcnNSZWYuc2V0KHJlcXVlc3RIZWFkZXJzKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgQ2FjaGVSZXF1ZXN0IHB1dChVUkkgdXJpLCBVUkxDb25uZWN0aW9uIGNvbm4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworCisgICAgICAgIFVSTCB1cmwgPSBzZXJ2ZXIuZ2V0VXJsKCIvIik7CisgICAgICAgIFVSTENvbm5lY3Rpb24gdXJsQ29ubmVjdGlvbiA9IHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICB1cmxDb25uZWN0aW9uLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQSIsICJhbmRyb2lkIik7CisgICAgICAgIHJlYWRBc2NpaSh1cmxDb25uZWN0aW9uKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoImFuZHJvaWQiKSwgcmVxdWVzdEhlYWRlcnNSZWYuZ2V0KCkuZ2V0KCJBIikpOworICAgIH0KKworCisgICAgcHVibGljIHZvaWQgdGVzdFNlcnZlckRpc2Nvbm5lY3RzUHJlbWF0dXJlbHlXaXRoQ29udGVudExlbmd0aEhlYWRlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RTZXJ2ZXJQcmVtYXR1cmVEaXNjb25uZWN0KFRyYW5zZmVyS2luZC5GSVhFRF9MRU5HVEgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXJ2ZXJEaXNjb25uZWN0c1ByZW1hdHVyZWx5V2l0aENodW5rZWRFbmNvZGluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RTZXJ2ZXJQcmVtYXR1cmVEaXNjb25uZWN0KFRyYW5zZmVyS2luZC5DSFVOS0VEKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VydmVyRGlzY29ubmVjdHNQcmVtYXR1cmVseVdpdGhOb0xlbmd0aEhlYWRlcnMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvKgorICAgICAgICAgKiBJbnRlbnRpb25hbGx5IGVtcHR5LiBUaGlzIGNhc2UgZG9lc24ndCBtYWtlIHNlbnNlIGJlY2F1c2UgdGhlcmUncyBubworICAgICAgICAgKiBzdWNoIHRoaW5nIGFzIGEgcHJlbWF0dXJlIGRpc2Nvbm5lY3Qgd2hlbiB0aGUgZGlzY29ubmVjdCBpdHNlbGYKKyAgICAgICAgICogaW5kaWNhdGVzIHRoZSBlbmQgb2YgdGhlIGRhdGEgc3RyZWFtLgorICAgICAgICAgKi8KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdFNlcnZlclByZW1hdHVyZURpc2Nvbm5lY3QoVHJhbnNmZXJLaW5kIHRyYW5zZmVyS2luZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja1Jlc3BvbnNlIHJlc3BvbnNlID0gbmV3IE1vY2tSZXNwb25zZSgpOworICAgICAgICB0cmFuc2ZlcktpbmQuc2V0Qm9keShyZXNwb25zZSwgIkFCQ0RFXG5GR0hJSktMTU5PUFFSU1RVVldYWVoiLCAxNik7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKHRydW5jYXRlVmlvbGVudGx5KHJlc3BvbnNlLCAxNikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiUmVxdWVzdCAjMiIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBCdWZmZXJlZFJlYWRlciByZWFkZXIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKAorICAgICAgICAgICAgICAgIHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpLmdldElucHV0U3RyZWFtKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkNERSIsIHJlYWRlci5yZWFkTGluZSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRlci5yZWFkTGluZSgpOworICAgICAgICAgICAgZmFpbCgiVGhpcyBpbXBsZW1lbnRhdGlvbiBzaWxlbnRseSBpZ25vcmVkIGEgdHJ1bmNhdGVkIEhUVFAgYm9keS4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHJlYWRlci5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNhY2hlLmdldFdyaXRlQWJvcnRDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGNhY2hlLmdldFdyaXRlU3VjY2Vzc0NvdW50KCkpOworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXF1ZXN0ICMyIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24pKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNhY2hlLmdldFdyaXRlQWJvcnRDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNhY2hlLmdldFdyaXRlU3VjY2Vzc0NvdW50KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDbGllbnRQcmVtYXR1cmVEaXNjb25uZWN0V2l0aENvbnRlbnRMZW5ndGhIZWFkZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0ZXN0Q2xpZW50UHJlbWF0dXJlRGlzY29ubmVjdChUcmFuc2ZlcktpbmQuRklYRURfTEVOR1RIKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xpZW50UHJlbWF0dXJlRGlzY29ubmVjdFdpdGhDaHVua2VkRW5jb2RpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0ZXN0Q2xpZW50UHJlbWF0dXJlRGlzY29ubmVjdChUcmFuc2ZlcktpbmQuQ0hVTktFRCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENsaWVudFByZW1hdHVyZURpc2Nvbm5lY3RXaXRoTm9MZW5ndGhIZWFkZXJzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdENsaWVudFByZW1hdHVyZURpc2Nvbm5lY3QoVHJhbnNmZXJLaW5kLkVORF9PRl9TVFJFQU0pOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0Q2xpZW50UHJlbWF0dXJlRGlzY29ubmVjdChUcmFuc2ZlcktpbmQgdHJhbnNmZXJLaW5kKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBNb2NrUmVzcG9uc2UgcmVzcG9uc2UgPSBuZXcgTW9ja1Jlc3BvbnNlKCk7CisgICAgICAgIHRyYW5zZmVyS2luZC5zZXRCb2R5KHJlc3BvbnNlLCAiQUJDREVcbkZHSElKS0xNTk9QUVJTVFVWV1hZWiIsIDEwMjQpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShyZXNwb25zZSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJSZXF1ZXN0ICMyIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkNERSIsIHJlYWRBc2NpaShjb25uZWN0aW9uLCA1KSk7CisgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbi5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBhbiBJT0V4Y2VwdGlvbiBiZWNhdXNlIHRoZSBzdHJlYW0gaXMgY2xvc2VkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNhY2hlLmdldFdyaXRlQWJvcnRDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGNhY2hlLmdldFdyaXRlU3VjY2Vzc0NvdW50KCkpOworICAgICAgICBjb25uZWN0aW9uID0gc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmVxdWVzdCAjMiIsIHJlYWRBc2NpaShjb25uZWN0aW9uKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBjYWNoZS5nZXRXcml0ZUFib3J0Q291bnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBjYWNoZS5nZXRXcml0ZVN1Y2Nlc3NDb3VudCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVmYXVsdEV4cGlyYXRpb25EYXRlRnVsbHlDYWNoZWRGb3JMZXNzVGhhbjI0SG91cnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gICAgICBsYXN0IG1vZGlmaWVkOiAxMDUgc2Vjb25kcyBhZ28KKyAgICAgICAgLy8gICAgICAgICAgICAgc2VydmVkOiAgIDUgc2Vjb25kcyBhZ28KKyAgICAgICAgLy8gICBkZWZhdWx0IGxpZmV0aW1lOiAoMTA1IC0gNSkgLyAxMCA9IDEwIHNlY29uZHMKKyAgICAgICAgLy8gICAgICAgICAgICBleHBpcmVzOiAgMTAgc2Vjb25kcyBmcm9tIHNlcnZlZCBkYXRlID0gNSBzZWNvbmRzIGZyb20gbm93CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkxhc3QtTW9kaWZpZWQ6ICIgKyBmb3JtYXREYXRlKC0xMDUsIFRpbWVVbml0LlNFQ09ORFMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkRhdGU6ICIgKyBmb3JtYXREYXRlKC01LCBUaW1lVW5pdC5TRUNPTkRTKSkKKyAgICAgICAgICAgICAgICAuc2V0Qm9keSgiQSIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkwgdXJsID0gc2VydmVyLmdldFVybCgiLyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkodXJsLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShjb25uZWN0aW9uKSk7CisgICAgICAgIGFzc2VydE51bGwoY29ubmVjdGlvbi5nZXRIZWFkZXJGaWVsZCgiV2FybmluZyIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVmYXVsdEV4cGlyYXRpb25EYXRlQ29uZGl0aW9uYWxseUNhY2hlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyAgICAgIGxhc3QgbW9kaWZpZWQ6IDExNSBzZWNvbmRzIGFnbworICAgICAgICAvLyAgICAgICAgICAgICBzZXJ2ZWQ6ICAxNSBzZWNvbmRzIGFnbworICAgICAgICAvLyAgIGRlZmF1bHQgbGlmZXRpbWU6ICgxMTUgLSAxNSkgLyAxMCA9IDEwIHNlY29uZHMKKyAgICAgICAgLy8gICAgICAgICAgICBleHBpcmVzOiAgMTAgc2Vjb25kcyBmcm9tIHNlcnZlZCBkYXRlID0gNSBzZWNvbmRzIGFnbworICAgICAgICBTdHJpbmcgbGFzdE1vZGlmaWVkRGF0ZSA9IGZvcm1hdERhdGUoLTExNSwgVGltZVVuaXQuU0VDT05EUyk7CisgICAgICAgIFJlY29yZGVkUmVxdWVzdCBjb25kaXRpb25hbFJlcXVlc3QgPSBhc3NlcnRDb25kaXRpb25hbGx5Q2FjaGVkKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkxhc3QtTW9kaWZpZWQ6ICIgKyBsYXN0TW9kaWZpZWREYXRlKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkRhdGU6ICIgKyBmb3JtYXREYXRlKC0xNSwgVGltZVVuaXQuU0VDT05EUykpKTsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGhlYWRlcnMgPSBjb25kaXRpb25hbFJlcXVlc3QuZ2V0SGVhZGVycygpOworICAgICAgICBhc3NlcnRUcnVlKGhlYWRlcnMuY29udGFpbnMoIklmLU1vZGlmaWVkLVNpbmNlOiAiICsgbGFzdE1vZGlmaWVkRGF0ZSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REZWZhdWx0RXhwaXJhdGlvbkRhdGVGdWxseUNhY2hlZEZvck1vcmVUaGFuMjRIb3VycygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyAgICAgIGxhc3QgbW9kaWZpZWQ6IDEwNSBkYXlzIGFnbworICAgICAgICAvLyAgICAgICAgICAgICBzZXJ2ZWQ6ICAgNSBkYXlzIGFnbworICAgICAgICAvLyAgIGRlZmF1bHQgbGlmZXRpbWU6ICgxMDUgLSA1KSAvIDEwID0gMTAgZGF5cworICAgICAgICAvLyAgICAgICAgICAgIGV4cGlyZXM6ICAxMCBkYXlzIGZyb20gc2VydmVkIGRhdGUgPSA1IGRheXMgZnJvbSBub3cKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTGFzdC1Nb2RpZmllZDogIiArIGZvcm1hdERhdGUoLTEwNSwgVGltZVVuaXQuREFZUykpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiRGF0ZTogIiArIGZvcm1hdERhdGUoLTUsIFRpbWVVbml0LkRBWVMpKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24pKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMTMgSHR0cFVSTENvbm5lY3Rpb24gXCJIZXVyaXN0aWMgZXhwaXJhdGlvblwiIiwKKyAgICAgICAgICAgICAgICBjb25uZWN0aW9uLmdldEhlYWRlckZpZWxkKCJXYXJuaW5nIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROb0RlZmF1bHRFeHBpcmF0aW9uRm9yVXJsc1dpdGhRdWVyeVN0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMYXN0LU1vZGlmaWVkOiAiICsgZm9ybWF0RGF0ZSgtMTA1LCBUaW1lVW5pdC5TRUNPTkRTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJEYXRlOiAiICsgZm9ybWF0RGF0ZSgtNSwgVGltZVVuaXQuU0VDT05EUykpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIkEiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJCIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTCB1cmwgPSBzZXJ2ZXIuZ2V0VXJsKCIvP2Zvbz1iYXIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKHVybC5vcGVuQ29ubmVjdGlvbigpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQiIsIHJlYWRBc2NpaSh1cmwub3BlbkNvbm5lY3Rpb24oKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFeHBpcmF0aW9uRGF0ZUluVGhlUGFzdFdpdGhMYXN0TW9kaWZpZWRIZWFkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGxhc3RNb2RpZmllZERhdGUgPSBmb3JtYXREYXRlKC0yLCBUaW1lVW5pdC5IT1VSUyk7CisgICAgICAgIFJlY29yZGVkUmVxdWVzdCBjb25kaXRpb25hbFJlcXVlc3QgPSBhc3NlcnRDb25kaXRpb25hbGx5Q2FjaGVkKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkxhc3QtTW9kaWZpZWQ6ICIgKyBsYXN0TW9kaWZpZWREYXRlKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkV4cGlyZXM6ICIgKyBmb3JtYXREYXRlKC0xLCBUaW1lVW5pdC5IT1VSUykpKTsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGhlYWRlcnMgPSBjb25kaXRpb25hbFJlcXVlc3QuZ2V0SGVhZGVycygpOworICAgICAgICBhc3NlcnRUcnVlKGhlYWRlcnMuY29udGFpbnMoIklmLU1vZGlmaWVkLVNpbmNlOiAiICsgbGFzdE1vZGlmaWVkRGF0ZSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFeHBpcmF0aW9uRGF0ZUluVGhlUGFzdFdpdGhOb0xhc3RNb2RpZmllZEhlYWRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnROb3RDYWNoZWQobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiRXhwaXJlczogIiArIGZvcm1hdERhdGUoLTEsIFRpbWVVbml0LkhPVVJTKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFeHBpcmF0aW9uRGF0ZUluVGhlRnV0dXJlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZ1bGx5Q2FjaGVkKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkV4cGlyZXM6ICIgKyBmb3JtYXREYXRlKDEsIFRpbWVVbml0LkhPVVJTKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYXhBZ2VQcmVmZXJyZWRXaXRoTWF4QWdlQW5kRXhwaXJlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGdWxseUNhY2hlZChuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJEYXRlOiAiICsgZm9ybWF0RGF0ZSgwLCBUaW1lVW5pdC5IT1VSUykpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiRXhwaXJlczogIiArIGZvcm1hdERhdGUoLTEsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTYwIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYXhBZ2VJblRoZVBhc3RXaXRoRGF0ZUFuZExhc3RNb2RpZmllZEhlYWRlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGxhc3RNb2RpZmllZERhdGUgPSBmb3JtYXREYXRlKC0yLCBUaW1lVW5pdC5IT1VSUyk7CisgICAgICAgIFJlY29yZGVkUmVxdWVzdCBjb25kaXRpb25hbFJlcXVlc3QgPSBhc3NlcnRDb25kaXRpb25hbGx5Q2FjaGVkKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkRhdGU6ICIgKyBmb3JtYXREYXRlKC0xMjAsIFRpbWVVbml0LlNFQ09ORFMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkxhc3QtTW9kaWZpZWQ6ICIgKyBsYXN0TW9kaWZpZWREYXRlKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNhY2hlLUNvbnRyb2w6IG1heC1hZ2U9NjAiKSk7CisgICAgICAgIExpc3Q8U3RyaW5nPiBoZWFkZXJzID0gY29uZGl0aW9uYWxSZXF1ZXN0LmdldEhlYWRlcnMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShoZWFkZXJzLmNvbnRhaW5zKCJJZi1Nb2RpZmllZC1TaW5jZTogIiArIGxhc3RNb2RpZmllZERhdGUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF4QWdlSW5UaGVQYXN0V2l0aERhdGVIZWFkZXJCdXROb0xhc3RNb2RpZmllZEhlYWRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvKgorICAgICAgICAgKiBDaHJvbWUgaW50ZXJwcmV0cyBtYXgtYWdlIHJlbGF0aXZlIHRvIHRoZSBsb2NhbCBjbG9jay4gQm90aCBvdXIgY2FjaGUKKyAgICAgICAgICogYW5kIEZpcmVmb3ggYm90aCB1c2UgdGhlIGVhcmxpZXIgb2YgdGhlIGxvY2FsIGFuZCBzZXJ2ZXIncyBjbG9jay4KKyAgICAgICAgICovCisgICAgICAgIGFzc2VydE5vdENhY2hlZChuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJEYXRlOiAiICsgZm9ybWF0RGF0ZSgtMTIwLCBUaW1lVW5pdC5TRUNPTkRTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTYwIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYXhBZ2VJblRoZUZ1dHVyZVdpdGhEYXRlSGVhZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZ1bGx5Q2FjaGVkKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkRhdGU6ICIgKyBmb3JtYXREYXRlKDAsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTYwIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYXhBZ2VJblRoZUZ1dHVyZVdpdGhOb0RhdGVIZWFkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RnVsbHlDYWNoZWQobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT02MCIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF4QWdlV2l0aExhc3RNb2RpZmllZEJ1dE5vU2VydmVkRGF0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGdWxseUNhY2hlZChuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMYXN0LU1vZGlmaWVkOiAiICsgZm9ybWF0RGF0ZSgtMTIwLCBUaW1lVW5pdC5TRUNPTkRTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTYwIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYXhBZ2VJblRoZUZ1dHVyZVdpdGhEYXRlQW5kTGFzdE1vZGlmaWVkSGVhZGVycygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGdWxseUNhY2hlZChuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMYXN0LU1vZGlmaWVkOiAiICsgZm9ybWF0RGF0ZSgtMTIwLCBUaW1lVW5pdC5TRUNPTkRTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJEYXRlOiAiICsgZm9ybWF0RGF0ZSgwLCBUaW1lVW5pdC5TRUNPTkRTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTYwIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYXhBZ2VQcmVmZXJyZWRPdmVyTG93ZXJTaGFyZWRNYXhBZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RnVsbHlDYWNoZWQobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiRGF0ZTogIiArIGZvcm1hdERhdGUoLTIsIFRpbWVVbml0Lk1JTlVURVMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNhY2hlLUNvbnRyb2w6IHMtbWF4YWdlPTYwIikKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTE4MCIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF4QWdlUHJlZmVycmVkT3ZlckhpZ2hlck1heEFnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnROb3RDYWNoZWQobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiRGF0ZTogIiArIGZvcm1hdERhdGUoLTIsIFRpbWVVbml0Lk1JTlVURVMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNhY2hlLUNvbnRyb2w6IHMtbWF4YWdlPTE4MCIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT02MCIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVxdWVzdE1ldGhvZE9wdGlvbnNJc05vdENhY2hlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0UmVxdWVzdE1ldGhvZCgiT1BUSU9OUyIsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVxdWVzdE1ldGhvZEdldElzQ2FjaGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RSZXF1ZXN0TWV0aG9kKCJHRVQiLCB0cnVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVxdWVzdE1ldGhvZEhlYWRJc05vdENhY2hlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBXZSBjb3VsZCBzdXBwb3J0IHRoaXMgYnV0IGNob29zZSBub3QgdG8gZm9yIGltcGxlbWVudGF0aW9uIHNpbXBsaWNpdHkKKyAgICAgICAgdGVzdFJlcXVlc3RNZXRob2QoIkhFQUQiLCBmYWxzZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlcXVlc3RNZXRob2RQb3N0SXNOb3RDYWNoZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gV2UgY291bGQgc3VwcG9ydCB0aGlzIGJ1dCBjaG9vc2Ugbm90IHRvIGZvciBpbXBsZW1lbnRhdGlvbiBzaW1wbGljaXR5CisgICAgICAgIHRlc3RSZXF1ZXN0TWV0aG9kKCJQT1NUIiwgZmFsc2UpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXF1ZXN0TWV0aG9kUHV0SXNOb3RDYWNoZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFJlcXVlc3RNZXRob2QoIlBVVCIsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVxdWVzdE1ldGhvZERlbGV0ZUlzTm90Q2FjaGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RSZXF1ZXN0TWV0aG9kKCJERUxFVEUiLCBmYWxzZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlcXVlc3RNZXRob2RUcmFjZUlzTm90Q2FjaGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RSZXF1ZXN0TWV0aG9kKCJUUkFDRSIsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdFJlcXVlc3RNZXRob2QoU3RyaW5nIHJlcXVlc3RNZXRob2QsIGJvb2xlYW4gZXhwZWN0Q2FjaGVkKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogMS4gc2VlZCB0aGUgY2FjaGUgKHBvdGVudGlhbGx5KQorICAgICAgICAgKiAyLiBleHBlY3QgYSBjYWNoZSBoaXQgb3IgbWlzcworICAgICAgICAgKi8KKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiRXhwaXJlczogIiArIGZvcm1hdERhdGUoMSwgVGltZVVuaXQuSE9VUlMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIlgtUmVzcG9uc2UtSUQ6IDEiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIlgtUmVzcG9uc2UtSUQ6IDIiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMIHVybCA9IHNlcnZlci5nZXRVcmwoIi8iKTsKKworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiByZXF1ZXN0MSA9IChIdHRwVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIHJlcXVlc3QxLnNldFJlcXVlc3RNZXRob2QocmVxdWVzdE1ldGhvZCk7CisgICAgICAgIGFkZFJlcXVlc3RCb2R5SWZOZWNlc3NhcnkocmVxdWVzdE1ldGhvZCwgcmVxdWVzdDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEiLCByZXF1ZXN0MS5nZXRIZWFkZXJGaWVsZCgiWC1SZXNwb25zZS1JRCIpKTsKKworICAgICAgICBVUkxDb25uZWN0aW9uIHJlcXVlc3QyID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGlmIChleHBlY3RDYWNoZWQpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiMSIsIHJlcXVlc3QxLmdldEhlYWRlckZpZWxkKCJYLVJlc3BvbnNlLUlEIikpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCIyIiwgcmVxdWVzdDIuZ2V0SGVhZGVyRmllbGQoIlgtUmVzcG9uc2UtSUQiKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UG9zdEludmFsaWRhdGVzQ2FjaGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdE1ldGhvZEludmFsaWRhdGVzKCJQT1NUIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1dEludmFsaWRhdGVzQ2FjaGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdE1ldGhvZEludmFsaWRhdGVzKCJQVVQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVsZXRlTWV0aG9kSW52YWxpZGF0ZXNDYWNoZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0TWV0aG9kSW52YWxpZGF0ZXMoIkRFTEVURSIpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0TWV0aG9kSW52YWxpZGF0ZXMoU3RyaW5nIHJlcXVlc3RNZXRob2QpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvKgorICAgICAgICAgKiAxLiBzZWVkIHRoZSBjYWNoZQorICAgICAgICAgKiAyLiBpbnZhbGlkYXRlIGl0CisgICAgICAgICAqIDMuIGV4cGVjdCBhIGNhY2hlIG1pc3MKKyAgICAgICAgICovCisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJBIikKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJFeHBpcmVzOiAiICsgZm9ybWF0RGF0ZSgxLCBUaW1lVW5pdC5IT1VSUykpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkIiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJDIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTCB1cmwgPSBzZXJ2ZXIuZ2V0VXJsKCIvIik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKHVybC5vcGVuQ29ubmVjdGlvbigpKSk7CisKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gaW52YWxpZGF0ZSA9IChIdHRwVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGludmFsaWRhdGUuc2V0UmVxdWVzdE1ldGhvZChyZXF1ZXN0TWV0aG9kKTsKKyAgICAgICAgYWRkUmVxdWVzdEJvZHlJZk5lY2Vzc2FyeShyZXF1ZXN0TWV0aG9kLCBpbnZhbGlkYXRlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCIiwgcmVhZEFzY2lpKGludmFsaWRhdGUpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkMiLCByZWFkQXNjaWkodXJsLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXRhZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBSZWNvcmRlZFJlcXVlc3QgY29uZGl0aW9uYWxSZXF1ZXN0ID0gYXNzZXJ0Q29uZGl0aW9uYWxseUNhY2hlZChuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJFVGFnOiB2MSIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjb25kaXRpb25hbFJlcXVlc3QuZ2V0SGVhZGVycygpLmNvbnRhaW5zKCJJZi1Ob25lLU1hdGNoOiB2MSIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXRhZ0FuZEV4cGlyYXRpb25EYXRlSW5UaGVQYXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBsYXN0TW9kaWZpZWREYXRlID0gZm9ybWF0RGF0ZSgtMiwgVGltZVVuaXQuSE9VUlMpOworICAgICAgICBSZWNvcmRlZFJlcXVlc3QgY29uZGl0aW9uYWxSZXF1ZXN0ID0gYXNzZXJ0Q29uZGl0aW9uYWxseUNhY2hlZChuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJFVGFnOiB2MSIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTGFzdC1Nb2RpZmllZDogIiArIGxhc3RNb2RpZmllZERhdGUpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiRXhwaXJlczogIiArIGZvcm1hdERhdGUoLTEsIFRpbWVVbml0LkhPVVJTKSkpOworICAgICAgICBMaXN0PFN0cmluZz4gaGVhZGVycyA9IGNvbmRpdGlvbmFsUmVxdWVzdC5nZXRIZWFkZXJzKCk7CisgICAgICAgIGFzc2VydFRydWUoaGVhZGVycy5jb250YWlucygiSWYtTm9uZS1NYXRjaDogdjEiKSk7CisgICAgICAgIGFzc2VydFRydWUoaGVhZGVycy5jb250YWlucygiSWYtTW9kaWZpZWQtU2luY2U6ICIgKyBsYXN0TW9kaWZpZWREYXRlKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEV0YWdBbmRFeHBpcmF0aW9uRGF0ZUluVGhlRnV0dXJlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZ1bGx5Q2FjaGVkKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkVUYWc6IHYxIikKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMYXN0LU1vZGlmaWVkOiAiICsgZm9ybWF0RGF0ZSgtMiwgVGltZVVuaXQuSE9VUlMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkV4cGlyZXM6ICIgKyBmb3JtYXREYXRlKDEsIFRpbWVVbml0LkhPVVJTKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDYWNoZUNvbnRyb2xOb0NhY2hlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydE5vdENhY2hlZChuZXcgTW9ja1Jlc3BvbnNlKCkuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBuby1jYWNoZSIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2FjaGVDb250cm9sTm9DYWNoZUFuZEV4cGlyYXRpb25EYXRlSW5UaGVGdXR1cmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGxhc3RNb2RpZmllZERhdGUgPSBmb3JtYXREYXRlKC0yLCBUaW1lVW5pdC5IT1VSUyk7CisgICAgICAgIFJlY29yZGVkUmVxdWVzdCBjb25kaXRpb25hbFJlcXVlc3QgPSBhc3NlcnRDb25kaXRpb25hbGx5Q2FjaGVkKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkxhc3QtTW9kaWZpZWQ6ICIgKyBsYXN0TW9kaWZpZWREYXRlKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkV4cGlyZXM6ICIgKyBmb3JtYXREYXRlKDEsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBuby1jYWNoZSIpKTsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGhlYWRlcnMgPSBjb25kaXRpb25hbFJlcXVlc3QuZ2V0SGVhZGVycygpOworICAgICAgICBhc3NlcnRUcnVlKGhlYWRlcnMuY29udGFpbnMoIklmLU1vZGlmaWVkLVNpbmNlOiAiICsgbGFzdE1vZGlmaWVkRGF0ZSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQcmFnbWFOb0NhY2hlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydE5vdENhY2hlZChuZXcgTW9ja1Jlc3BvbnNlKCkuYWRkSGVhZGVyKCJQcmFnbWE6IG5vLWNhY2hlIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQcmFnbWFOb0NhY2hlQW5kRXhwaXJhdGlvbkRhdGVJblRoZUZ1dHVyZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbGFzdE1vZGlmaWVkRGF0ZSA9IGZvcm1hdERhdGUoLTIsIFRpbWVVbml0LkhPVVJTKTsKKyAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IGNvbmRpdGlvbmFsUmVxdWVzdCA9IGFzc2VydENvbmRpdGlvbmFsbHlDYWNoZWQobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTGFzdC1Nb2RpZmllZDogIiArIGxhc3RNb2RpZmllZERhdGUpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiRXhwaXJlczogIiArIGZvcm1hdERhdGUoMSwgVGltZVVuaXQuSE9VUlMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIlByYWdtYTogbm8tY2FjaGUiKSk7CisgICAgICAgIExpc3Q8U3RyaW5nPiBoZWFkZXJzID0gY29uZGl0aW9uYWxSZXF1ZXN0LmdldEhlYWRlcnMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShoZWFkZXJzLmNvbnRhaW5zKCJJZi1Nb2RpZmllZC1TaW5jZTogIiArIGxhc3RNb2RpZmllZERhdGUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2FjaGVDb250cm9sTm9TdG9yZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnROb3RDYWNoZWQobmV3IE1vY2tSZXNwb25zZSgpLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbm8tc3RvcmUiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENhY2hlQ29udHJvbE5vU3RvcmVBbmRFeHBpcmF0aW9uRGF0ZUluVGhlRnV0dXJlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydE5vdENhY2hlZChuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMYXN0LU1vZGlmaWVkOiAiICsgZm9ybWF0RGF0ZSgtMiwgVGltZVVuaXQuSE9VUlMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkV4cGlyZXM6ICIgKyBmb3JtYXREYXRlKDEsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBuby1zdG9yZSIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFydGlhbFJhbmdlUmVzcG9uc2VzRG9Ob3RDb3JydXB0Q2FjaGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogMS4gcmVxdWVzdCBhIHJhbmdlCisgICAgICAgICAqIDIuIHJlcXVlc3QgYSBmdWxsIGRvY3VtZW50LCBleHBlY3RpbmcgYSBjYWNoZSBtaXNzCisgICAgICAgICAqLworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQUEiKQorICAgICAgICAgICAgICAgIC5zZXRSZXNwb25zZUNvZGUoSHR0cFVSTENvbm5lY3Rpb24uSFRUUF9QQVJUSUFMKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkV4cGlyZXM6ICIgKyBmb3JtYXREYXRlKDEsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDb250ZW50LVJhbmdlOiBieXRlcyAxMDAwLTEwMDEvMjAwMCIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkJCIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTCB1cmwgPSBzZXJ2ZXIuZ2V0VXJsKCIvIik7CisKKyAgICAgICAgVVJMQ29ubmVjdGlvbiByYW5nZSA9IHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICByYW5nZS5hZGRSZXF1ZXN0UHJvcGVydHkoIlJhbmdlIiwgImJ5dGVzPTEwMDAtMTAwMSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFBIiwgcmVhZEFzY2lpKHJhbmdlKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCQiIsIHJlYWRBc2NpaSh1cmwub3BlbkNvbm5lY3Rpb24oKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXJ2ZXJSZXR1cm5zRG9jdW1lbnRPbGRlclRoYW5DYWNoZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQSIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTGFzdC1Nb2RpZmllZDogIiArIGZvcm1hdERhdGUoLTIsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJFeHBpcmVzOiAiICsgZm9ybWF0RGF0ZSgtMSwgVGltZVVuaXQuSE9VUlMpKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJCIikKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMYXN0LU1vZGlmaWVkOiAiICsgZm9ybWF0RGF0ZSgtNCwgVGltZVVuaXQuSE9VUlMpKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMIHVybCA9IHNlcnZlci5nZXRVcmwoIi8iKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkodXJsLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKHVybC5vcGVuQ29ubmVjdGlvbigpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vbklkZW50aXR5RW5jb2RpbmdBbmRDb25kaXRpb25hbENhY2hlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydE5vbklkZW50aXR5RW5jb2RpbmdDYWNoZWQobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTGFzdC1Nb2RpZmllZDogIiArIGZvcm1hdERhdGUoLTIsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJFeHBpcmVzOiAiICsgZm9ybWF0RGF0ZSgtMSwgVGltZVVuaXQuSE9VUlMpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vbklkZW50aXR5RW5jb2RpbmdBbmRGdWxsQ2FjaGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0Tm9uSWRlbnRpdHlFbmNvZGluZ0NhY2hlZChuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMYXN0LU1vZGlmaWVkOiAiICsgZm9ybWF0RGF0ZSgtMiwgVGltZVVuaXQuSE9VUlMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkV4cGlyZXM6ICIgKyBmb3JtYXREYXRlKDEsIFRpbWVVbml0LkhPVVJTKSkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnROb25JZGVudGl0eUVuY29kaW5nQ2FjaGVkKE1vY2tSZXNwb25zZSByZXNwb25zZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKHJlc3BvbnNlCisgICAgICAgICAgICAgICAgLnNldEJvZHkoZ3ppcCgiQUJDQUJDQUJDIi5nZXRCeXRlcygiVVRGLTgiKSkpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ29udGVudC1FbmNvZGluZzogZ3ppcCIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldFJlc3BvbnNlQ29kZShIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX05PVF9NT0RJRklFRCkpOworCisgICAgICAgIHNlcnZlci5wbGF5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJDQUJDQUJDIiwgcmVhZEFzY2lpKHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQUJDQUJDQUJDIiwgcmVhZEFzY2lpKHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEV4cGlyZXNEYXRlQmVmb3JlTW9kaWZpZWREYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydENvbmRpdGlvbmFsbHlDYWNoZWQobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTGFzdC1Nb2RpZmllZDogIiArIGZvcm1hdERhdGUoLTEsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJFeHBpcmVzOiAiICsgZm9ybWF0RGF0ZSgtMiwgVGltZVVuaXQuSE9VUlMpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlcXVlc3RNYXhBZ2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQSIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTGFzdC1Nb2RpZmllZDogIiArIGZvcm1hdERhdGUoLTIsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJEYXRlOiAiICsgZm9ybWF0RGF0ZSgtMSwgVGltZVVuaXQuTUlOVVRFUykpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiRXhwaXJlczogIiArIGZvcm1hdERhdGUoMSwgVGltZVVuaXQuSE9VUlMpKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJCIikpOworCisgICAgICAgIHNlcnZlci5wbGF5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKSkpOworCisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQ2FjaGUtQ29udHJvbCIsICJtYXgtYWdlPTMwIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQiIsIHJlYWRBc2NpaShjb25uZWN0aW9uKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlcXVlc3RNaW5GcmVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJBIikKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTYwIikKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJEYXRlOiAiICsgZm9ybWF0RGF0ZSgwLCBUaW1lVW5pdC5NSU5VVEVTKSkpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQiIpKTsKKworICAgICAgICBzZXJ2ZXIucGxheSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCkpKTsKKworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5hZGRSZXF1ZXN0UHJvcGVydHkoIkNhY2hlLUNvbnRyb2wiLCAibWluLWZyZXNoPTEyMCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkIiLCByZWFkQXNjaWkoY29ubmVjdGlvbikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXF1ZXN0TWF4U3RhbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQSIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT0xMjAiKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkRhdGU6ICIgKyBmb3JtYXREYXRlKC00LCBUaW1lVW5pdC5NSU5VVEVTKSkpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQiIpKTsKKworICAgICAgICBzZXJ2ZXIucGxheSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCkpKTsKKworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5hZGRSZXF1ZXN0UHJvcGVydHkoIkNhY2hlLUNvbnRyb2wiLCAibWF4LXN0YWxlPTE4MCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoY29ubmVjdGlvbikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjExMCBIdHRwVVJMQ29ubmVjdGlvbiBcIlJlc3BvbnNlIGlzIHN0YWxlXCIiLAorICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uZ2V0SGVhZGVyRmllbGQoIldhcm5pbmciKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlcXVlc3RNYXhTdGFsZU5vdEhvbm9yZWRXaXRoTXVzdFJldmFsaWRhdGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQSIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT0xMjAsIG11c3QtcmV2YWxpZGF0ZSIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiRGF0ZTogIiArIGZvcm1hdERhdGUoLTQsIFRpbWVVbml0Lk1JTlVURVMpKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJCIikpOworCisgICAgICAgIHNlcnZlci5wbGF5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKSkpOworCisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQ2FjaGUtQ29udHJvbCIsICJtYXgtc3RhbGU9MTgwIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQiIsIHJlYWRBc2NpaShjb25uZWN0aW9uKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlcXVlc3RPbmx5SWZDYWNoZWRXaXRoTm9SZXNwb25zZUNhY2hlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIChubyByZXNwb25zZXMgZW5xdWV1ZWQpCisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikgc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24uYWRkUmVxdWVzdFByb3BlcnR5KCJDYWNoZS1Db250cm9sIiwgIm9ubHktaWYtY2FjaGVkIik7CisgICAgICAgIGFzc2VydEJhZEdhdGV3YXkoY29ubmVjdGlvbik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlcXVlc3RPbmx5SWZDYWNoZWRXaXRoRnVsbFJlc3BvbnNlQ2FjaGVkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkEiKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNhY2hlLUNvbnRyb2w6IG1heC1hZ2U9MzAiKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkRhdGU6ICIgKyBmb3JtYXREYXRlKDAsIFRpbWVVbml0Lk1JTlVURVMpKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpKSk7CisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQ2FjaGUtQ29udHJvbCIsICJvbmx5LWlmLWNhY2hlZCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVxdWVzdE9ubHlJZkNhY2hlZFdpdGhDb25kaXRpb25hbFJlc3BvbnNlQ2FjaGVkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkEiKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNhY2hlLUNvbnRyb2w6IG1heC1hZ2U9MzAiKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkRhdGU6ICIgKyBmb3JtYXREYXRlKC0xLCBUaW1lVW5pdC5NSU5VVEVTKSkpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5hZGRSZXF1ZXN0UHJvcGVydHkoIkNhY2hlLUNvbnRyb2wiLCAib25seS1pZi1jYWNoZWQiKTsKKyAgICAgICAgYXNzZXJ0QmFkR2F0ZXdheShjb25uZWN0aW9uKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVxdWVzdE9ubHlJZkNhY2hlZFdpdGhVbmhlbHBmdWxSZXNwb25zZUNhY2hlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5hZGRSZXF1ZXN0UHJvcGVydHkoIkNhY2hlLUNvbnRyb2wiLCAib25seS1pZi1jYWNoZWQiKTsKKyAgICAgICAgYXNzZXJ0QmFkR2F0ZXdheShjb25uZWN0aW9uKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVxdWVzdENhY2hlQ29udHJvbE5vQ2FjaGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTGFzdC1Nb2RpZmllZDogIiArIGZvcm1hdERhdGUoLTEyMCwgVGltZVVuaXQuU0VDT05EUykpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiRGF0ZTogIiArIGZvcm1hdERhdGUoMCwgVGltZVVuaXQuU0VDT05EUykpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT02MCIpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIkEiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJCIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTCB1cmwgPSBzZXJ2ZXIuZ2V0VXJsKCIvIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaSh1cmwub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXRSZXF1ZXN0UHJvcGVydHkoIkNhY2hlLUNvbnRyb2wiLCAibm8tY2FjaGUiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24pKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVxdWVzdFByYWdtYU5vQ2FjaGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTGFzdC1Nb2RpZmllZDogIiArIGZvcm1hdERhdGUoLTEyMCwgVGltZVVuaXQuU0VDT05EUykpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiRGF0ZTogIiArIGZvcm1hdERhdGUoMCwgVGltZVVuaXQuU0VDT05EUykpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT02MCIpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIkEiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJCIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTCB1cmwgPSBzZXJ2ZXIuZ2V0VXJsKCIvIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaSh1cmwub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXRSZXF1ZXN0UHJvcGVydHkoIlByYWdtYSIsICJuby1jYWNoZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkIiLCByZWFkQXNjaWkoY29ubmVjdGlvbikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDbGllbnRTdXBwbGllZElmTW9kaWZpZWRTaW5jZVdpdGhDYWNoZWRSZXN1bHQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja1Jlc3BvbnNlIHJlc3BvbnNlID0gbmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiRVRhZzogdjMiKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNhY2hlLUNvbnRyb2w6IG1heC1hZ2U9MCIpOworICAgICAgICBTdHJpbmcgaWZNb2RpZmllZFNpbmNlRGF0ZSA9IGZvcm1hdERhdGUoLTI0LCBUaW1lVW5pdC5IT1VSUyk7CisgICAgICAgIFJlY29yZGVkUmVxdWVzdCByZXF1ZXN0ID0gYXNzZXJ0Q2xpZW50U3VwcGxpZWRDb25kaXRpb24oCisgICAgICAgICAgICAgICAgcmVzcG9uc2UsICJJZi1Nb2RpZmllZC1TaW5jZSIsIGlmTW9kaWZpZWRTaW5jZURhdGUpOworICAgICAgICBMaXN0PFN0cmluZz4gaGVhZGVycyA9IHJlcXVlc3QuZ2V0SGVhZGVycygpOworICAgICAgICBhc3NlcnRUcnVlKGhlYWRlcnMuY29udGFpbnMoIklmLU1vZGlmaWVkLVNpbmNlOiAiICsgaWZNb2RpZmllZFNpbmNlRGF0ZSkpOworICAgICAgICBhc3NlcnRGYWxzZShoZWFkZXJzLmNvbnRhaW5zKCJJZi1Ob25lLU1hdGNoOiB2MyIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xpZW50U3VwcGxpZWRJZk5vbmVNYXRjaFNpbmNlV2l0aENhY2hlZFJlc3VsdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbGFzdE1vZGlmaWVkRGF0ZSA9IGZvcm1hdERhdGUoLTMsIFRpbWVVbml0Lk1JTlVURVMpOworICAgICAgICBNb2NrUmVzcG9uc2UgcmVzcG9uc2UgPSBuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMYXN0LU1vZGlmaWVkOiAiICsgbGFzdE1vZGlmaWVkRGF0ZSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJEYXRlOiAiICsgZm9ybWF0RGF0ZSgtMiwgVGltZVVuaXQuTUlOVVRFUykpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT0wIik7CisgICAgICAgIFJlY29yZGVkUmVxdWVzdCByZXF1ZXN0ID0gYXNzZXJ0Q2xpZW50U3VwcGxpZWRDb25kaXRpb24oCisgICAgICAgICAgICAgICAgcmVzcG9uc2UsICJJZi1Ob25lLU1hdGNoIiwgInYxIik7CisgICAgICAgIExpc3Q8U3RyaW5nPiBoZWFkZXJzID0gcmVxdWVzdC5nZXRIZWFkZXJzKCk7CisgICAgICAgIGFzc2VydFRydWUoaGVhZGVycy5jb250YWlucygiSWYtTm9uZS1NYXRjaDogdjEiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGhlYWRlcnMuY29udGFpbnMoIklmLU1vZGlmaWVkLVNpbmNlOiAiICsgbGFzdE1vZGlmaWVkRGF0ZSkpOworICAgIH0KKworICAgIHByaXZhdGUgUmVjb3JkZWRSZXF1ZXN0IGFzc2VydENsaWVudFN1cHBsaWVkQ29uZGl0aW9uKE1vY2tSZXNwb25zZSBzZWVkLCBTdHJpbmcgY29uZGl0aW9uTmFtZSwKKyAgICAgICAgICAgIFN0cmluZyBjb25kaXRpb25WYWx1ZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKHNlZWQuc2V0Qm9keSgiQSIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldFJlc3BvbnNlQ29kZShIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX05PVF9NT0RJRklFRCkpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTCB1cmwgPSBzZXJ2ZXIuZ2V0VXJsKCIvIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaSh1cmwub3BlbkNvbm5lY3Rpb24oKSkpOworCisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLmFkZFJlcXVlc3RQcm9wZXJ0eShjb25kaXRpb25OYW1lLCBjb25kaXRpb25WYWx1ZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX05PVF9NT0RJRklFRCwgY29ubmVjdGlvbi5nZXRSZXNwb25zZUNvZGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24pKTsKKworICAgICAgICBzZXJ2ZXIudGFrZVJlcXVlc3QoKTsgLy8gc2VlZAorICAgICAgICByZXR1cm4gc2VydmVyLnRha2VSZXF1ZXN0KCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldElmTW9kaWZpZWRTaW5jZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEYXRlIHNpbmNlID0gbmV3IERhdGUoKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkEiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMIHVybCA9IHNlcnZlci5nZXRVcmwoIi8iKTsKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0SWZNb2RpZmllZFNpbmNlKHNpbmNlLmdldFRpbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShjb25uZWN0aW9uKSk7CisgICAgICAgIFJlY29yZGVkUmVxdWVzdCByZXF1ZXN0ID0gc2VydmVyLnRha2VSZXF1ZXN0KCk7CisgICAgICAgIGFzc2VydFRydWUocmVxdWVzdC5nZXRIZWFkZXJzKCkuY29udGFpbnMoIklmLU1vZGlmaWVkLVNpbmNlOiAiICsgZm9ybWF0RGF0ZShzaW5jZSkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xpZW50U3VwcGxpZWRDb25kaXRpb25XaXRob3V0Q2FjaGVkUmVzdWx0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5zZXRSZXNwb25zZUNvZGUoSHR0cFVSTENvbm5lY3Rpb24uSFRUUF9OT1RfTU9ESUZJRUQpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgU3RyaW5nIGNsaWVudElmTW9kaWZpZWRTaW5jZSA9IGZvcm1hdERhdGUoLTI0LCBUaW1lVW5pdC5IT1VSUyk7CisgICAgICAgIGNvbm5lY3Rpb24uYWRkUmVxdWVzdFByb3BlcnR5KCJJZi1Nb2RpZmllZC1TaW5jZSIsIGNsaWVudElmTW9kaWZpZWRTaW5jZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX05PVF9NT0RJRklFRCwgY29ubmVjdGlvbi5nZXRSZXNwb25zZUNvZGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24pKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXV0aG9yaXphdGlvblJlcXVlc3RIZWFkZXJQcmV2ZW50c0NhY2hpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTGFzdC1Nb2RpZmllZDogIiArIGZvcm1hdERhdGUoLTIsIFRpbWVVbml0Lk1JTlVURVMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNhY2hlLUNvbnRyb2w6IG1heC1hZ2U9NjAiKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQiIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkwgdXJsID0gc2VydmVyLmdldFVybCgiLyIpOworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5hZGRSZXF1ZXN0UHJvcGVydHkoIkF1dGhvcml6YXRpb24iLCAicGFzc3dvcmQiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24pKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCIiwgcmVhZEFzY2lpKHVybC5vcGVuQ29ubmVjdGlvbigpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEF1dGhvcml6YXRpb25SZXNwb25zZUNhY2hlZFdpdGhTTWF4QWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEF1dGhvcml6YXRpb25SZXF1ZXN0RnVsbHlDYWNoZWQobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogcy1tYXhhZ2U9NjAiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEF1dGhvcml6YXRpb25SZXNwb25zZUNhY2hlZFdpdGhQdWJsaWMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0QXV0aG9yaXphdGlvblJlcXVlc3RGdWxseUNhY2hlZChuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBwdWJsaWMiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEF1dGhvcml6YXRpb25SZXNwb25zZUNhY2hlZFdpdGhNdXN0UmV2YWxpZGF0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRBdXRob3JpemF0aW9uUmVxdWVzdEZ1bGx5Q2FjaGVkKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNhY2hlLUNvbnRyb2w6IG11c3QtcmV2YWxpZGF0ZSIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhc3NlcnRBdXRob3JpemF0aW9uUmVxdWVzdEZ1bGx5Q2FjaGVkKE1vY2tSZXNwb25zZSByZXNwb25zZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKHJlc3BvbnNlCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT02MCIpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIkEiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJCIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTCB1cmwgPSBzZXJ2ZXIuZ2V0VXJsKCIvIik7CisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQXV0aG9yaXphdGlvbiIsICJwYXNzd29yZCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoY29ubmVjdGlvbikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkodXJsLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29udGVudExvY2F0aW9uRG9lc05vdFBvcHVsYXRlQ2FjaGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT02MCIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ29udGVudC1Mb2NhdGlvbjogL2JhciIpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIkEiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJCIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShzZXJ2ZXIuZ2V0VXJsKCIvZm9vIikub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkIiLCByZWFkQXNjaWkoc2VydmVyLmdldFVybCgiL2JhciIpLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXNlQ2FjaGVzRmFsc2VEb2VzTm90V3JpdGVUb0NhY2hlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNhY2hlLUNvbnRyb2w6IG1heC1hZ2U9NjAiKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBIikuc2V0Qm9keSgiQSIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkIiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0VXNlQ2FjaGVzKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24pKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCIiwgcmVhZEFzY2lpKHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFVzZUNhY2hlc0ZhbHNlRG9lc05vdFJlYWRGcm9tQ2FjaGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT02MCIpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIkEiKS5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQiIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0VXNlQ2FjaGVzKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24pKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVmYXVsdFVzZUNhY2hlc1NldHNJbml0aWFsVmFsdWVPbmx5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vbG9jYWxob3N0LyIpOworICAgICAgICBVUkxDb25uZWN0aW9uIGMxID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIFVSTENvbm5lY3Rpb24gYzIgPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjMS5nZXREZWZhdWx0VXNlQ2FjaGVzKCkpOworICAgICAgICBjMS5zZXREZWZhdWx0VXNlQ2FjaGVzKGZhbHNlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoYzEuZ2V0VXNlQ2FjaGVzKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShjMi5nZXRVc2VDYWNoZXMoKSk7CisgICAgICAgICAgICBVUkxDb25uZWN0aW9uIGMzID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShjMy5nZXRVc2VDYWNoZXMoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBjMS5zZXREZWZhdWx0VXNlQ2FjaGVzKHRydWUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbm5lY3Rpb25Jc1JldHVybmVkVG9Qb29sQWZ0ZXJDb25kaXRpb25hbFN1Y2Nlc3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTGFzdC1Nb2RpZmllZDogIiArIGZvcm1hdERhdGUoLTEsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTAiKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0UmVzcG9uc2VDb2RlKEh0dHBVUkxDb25uZWN0aW9uLkhUVFBfTk9UX01PRElGSUVEKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJCIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShzZXJ2ZXIuZ2V0VXJsKCIvYSIpLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKHNlcnZlci5nZXRVcmwoIi9hIikub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkIiLCByZWFkQXNjaWkoc2VydmVyLmdldFVybCgiL2IiKS5vcGVuQ29ubmVjdGlvbigpKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHNlcnZlci50YWtlUmVxdWVzdCgpLmdldFNlcXVlbmNlTnVtYmVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgc2VydmVyLnRha2VSZXF1ZXN0KCkuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBzZXJ2ZXIudGFrZVJlcXVlc3QoKS5nZXRTZXF1ZW5jZU51bWJlcigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RhdGlzdGljc0NvbmRpdGlvbmFsQ2FjaGVNaXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkxhc3QtTW9kaWZpZWQ6ICIgKyBmb3JtYXREYXRlKC0xLCBUaW1lVW5pdC5IT1VSUykpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT0wIikKKyAgICAgICAgICAgICAgICAuc2V0Qm9keSgiQSIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkIiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJDIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY2FjaGUuZ2V0UmVxdWVzdENvdW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY2FjaGUuZ2V0TmV0d29ya0NvdW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgY2FjaGUuZ2V0SGl0Q291bnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQiIsIHJlYWRBc2NpaShzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkMiLCByZWFkQXNjaWkoc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGNhY2hlLmdldFJlcXVlc3RDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGNhY2hlLmdldE5ldHdvcmtDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGNhY2hlLmdldEhpdENvdW50KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdGF0aXN0aWNzQ29uZGl0aW9uYWxDYWNoZUhpdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMYXN0LU1vZGlmaWVkOiAiICsgZm9ybWF0RGF0ZSgtMSwgVGltZVVuaXQuSE9VUlMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNhY2hlLUNvbnRyb2w6IG1heC1hZ2U9MCIpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIkEiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRSZXNwb25zZUNvZGUoSHR0cFVSTENvbm5lY3Rpb24uSFRUUF9OT1RfTU9ESUZJRUQpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldFJlc3BvbnNlQ29kZShIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX05PVF9NT0RJRklFRCkpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY2FjaGUuZ2V0UmVxdWVzdENvdW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY2FjaGUuZ2V0TmV0d29ya0NvdW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgY2FjaGUuZ2V0SGl0Q291bnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGNhY2hlLmdldFJlcXVlc3RDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGNhY2hlLmdldE5ldHdvcmtDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGNhY2hlLmdldEhpdENvdW50KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdGF0aXN0aWNzRnVsbENhY2hlSGl0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNhY2hlLUNvbnRyb2w6IG1heC1hZ2U9NjAiKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY2FjaGUuZ2V0UmVxdWVzdENvdW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY2FjaGUuZ2V0TmV0d29ya0NvdW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgY2FjaGUuZ2V0SGl0Q291bnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGNhY2hlLmdldFJlcXVlc3RDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNhY2hlLmdldE5ldHdvcmtDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGNhY2hlLmdldEhpdENvdW50KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RWYXJ5TWF0Y2hlc0NoYW5nZWRSZXF1ZXN0SGVhZGVyRmllbGQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT02MCIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiVmFyeTogQWNjZXB0LUxhbmd1YWdlIikKKyAgICAgICAgICAgICAgICAuc2V0Qm9keSgiQSIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkIiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMIHVybCA9IHNlcnZlci5nZXRVcmwoIi8iKTsKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gZnJDb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgZnJDb25uZWN0aW9uLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQWNjZXB0LUxhbmd1YWdlIiwgImZyLUNBIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShmckNvbm5lY3Rpb24pKTsKKworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBlbkNvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBlbkNvbm5lY3Rpb24uYWRkUmVxdWVzdFByb3BlcnR5KCJBY2NlcHQtTGFuZ3VhZ2UiLCAiZW4tVVMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCIiwgcmVhZEFzY2lpKGVuQ29ubmVjdGlvbikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RWYXJ5TWF0Y2hlc1VuY2hhbmdlZFJlcXVlc3RIZWFkZXJGaWVsZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTYwIikKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJWYXJ5OiBBY2NlcHQtTGFuZ3VhZ2UiKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQiIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkwgdXJsID0gc2VydmVyLmdldFVybCgiLyIpOworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24xID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24xLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQWNjZXB0LUxhbmd1YWdlIiwgImZyLUNBIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShjb25uZWN0aW9uMSkpOworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24yID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24yLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQWNjZXB0LUxhbmd1YWdlIiwgImZyLUNBIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShjb25uZWN0aW9uMikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RWYXJ5TWF0Y2hlc0Fic2VudFJlcXVlc3RIZWFkZXJGaWVsZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTYwIikKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJWYXJ5OiBGb28iKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQiIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFZhcnlNYXRjaGVzQWRkZWRSZXF1ZXN0SGVhZGVyRmllbGQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT02MCIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiVmFyeTogRm9vIikKKyAgICAgICAgICAgICAgICAuc2V0Qm9keSgiQSIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkIiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpKSk7CisgICAgICAgIFVSTENvbm5lY3Rpb24gZm9vQ29ubmVjdGlvbiA9IHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBmb29Db25uZWN0aW9uLmFkZFJlcXVlc3RQcm9wZXJ0eSgiRm9vIiwgImJhciIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkIiLCByZWFkQXNjaWkoZm9vQ29ubmVjdGlvbikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RWYXJ5TWF0Y2hlc1JlbW92ZWRSZXF1ZXN0SGVhZGVyRmllbGQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT02MCIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiVmFyeTogRm9vIikKKyAgICAgICAgICAgICAgICAuc2V0Qm9keSgiQSIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkIiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBmb29Db25uZWN0aW9uID0gc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGZvb0Nvbm5lY3Rpb24uYWRkUmVxdWVzdFByb3BlcnR5KCJGb28iLCAiYmFyIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShmb29Db25uZWN0aW9uKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQiIsIHJlYWRBc2NpaShzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RWYXJ5RmllbGRzQXJlQ2FzZUluc2Vuc2l0aXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNhY2hlLUNvbnRyb2w6IG1heC1hZ2U9NjAiKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIlZhcnk6IEFDQ0VQVC1MQU5HVUFHRSIpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIkEiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJCIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTCB1cmwgPSBzZXJ2ZXIuZ2V0VXJsKCIvIik7CisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbjEgPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbjEuYWRkUmVxdWVzdFByb3BlcnR5KCJBY2NlcHQtTGFuZ3VhZ2UiLCAiZnItQ0EiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24xKSk7CisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbjIgPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbjIuYWRkUmVxdWVzdFByb3BlcnR5KCJhY2NlcHQtbGFuZ3VhZ2UiLCAiZnItQ0EiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24yKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFZhcnlNdWx0aXBsZUZpZWxkc1dpdGhNYXRjaCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTYwIikKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJWYXJ5OiBBY2NlcHQtTGFuZ3VhZ2UsIEFjY2VwdC1DaGFyc2V0IikKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJWYXJ5OiBBY2NlcHQtRW5jb2RpbmciKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQiIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkwgdXJsID0gc2VydmVyLmdldFVybCgiLyIpOworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24xID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24xLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQWNjZXB0LUxhbmd1YWdlIiwgImZyLUNBIik7CisgICAgICAgIGNvbm5lY3Rpb24xLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQWNjZXB0LUNoYXJzZXQiLCAiVVRGLTgiKTsKKyAgICAgICAgY29ubmVjdGlvbjEuYWRkUmVxdWVzdFByb3BlcnR5KCJBY2NlcHQtRW5jb2RpbmciLCAiaWRlbnRpdHkiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24xKSk7CisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbjIgPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbjIuYWRkUmVxdWVzdFByb3BlcnR5KCJBY2NlcHQtTGFuZ3VhZ2UiLCAiZnItQ0EiKTsKKyAgICAgICAgY29ubmVjdGlvbjIuYWRkUmVxdWVzdFByb3BlcnR5KCJBY2NlcHQtQ2hhcnNldCIsICJVVEYtOCIpOworICAgICAgICBjb25uZWN0aW9uMi5hZGRSZXF1ZXN0UHJvcGVydHkoIkFjY2VwdC1FbmNvZGluZyIsICJpZGVudGl0eSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoY29ubmVjdGlvbjIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmFyeU11bHRpcGxlRmllbGRzV2l0aE5vTWF0Y2goKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT02MCIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiVmFyeTogQWNjZXB0LUxhbmd1YWdlLCBBY2NlcHQtQ2hhcnNldCIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiVmFyeTogQWNjZXB0LUVuY29kaW5nIikKKyAgICAgICAgICAgICAgICAuc2V0Qm9keSgiQSIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkIiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMIHVybCA9IHNlcnZlci5nZXRVcmwoIi8iKTsKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBmckNvbm5lY3Rpb24gPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgZnJDb25uZWN0aW9uLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQWNjZXB0LUxhbmd1YWdlIiwgImZyLUNBIik7CisgICAgICAgIGZyQ29ubmVjdGlvbi5hZGRSZXF1ZXN0UHJvcGVydHkoIkFjY2VwdC1DaGFyc2V0IiwgIlVURi04Iik7CisgICAgICAgIGZyQ29ubmVjdGlvbi5hZGRSZXF1ZXN0UHJvcGVydHkoIkFjY2VwdC1FbmNvZGluZyIsICJpZGVudGl0eSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoZnJDb25uZWN0aW9uKSk7CisgICAgICAgIFVSTENvbm5lY3Rpb24gZW5Db25uZWN0aW9uID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGVuQ29ubmVjdGlvbi5hZGRSZXF1ZXN0UHJvcGVydHkoIkFjY2VwdC1MYW5ndWFnZSIsICJlbi1DQSIpOworICAgICAgICBlbkNvbm5lY3Rpb24uYWRkUmVxdWVzdFByb3BlcnR5KCJBY2NlcHQtQ2hhcnNldCIsICJVVEYtOCIpOworICAgICAgICBlbkNvbm5lY3Rpb24uYWRkUmVxdWVzdFByb3BlcnR5KCJBY2NlcHQtRW5jb2RpbmciLCAiaWRlbnRpdHkiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCIiwgcmVhZEFzY2lpKGVuQ29ubmVjdGlvbikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RWYXJ5TXVsdGlwbGVGaWVsZFZhbHVlc1dpdGhNYXRjaCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTYwIikKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJWYXJ5OiBBY2NlcHQtTGFuZ3VhZ2UiKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQiIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkwgdXJsID0gc2VydmVyLmdldFVybCgiLyIpOworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24xID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24xLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQWNjZXB0LUxhbmd1YWdlIiwgImZyLUNBLCBmci1GUiIpOworICAgICAgICBjb25uZWN0aW9uMS5hZGRSZXF1ZXN0UHJvcGVydHkoIkFjY2VwdC1MYW5ndWFnZSIsICJlbi1VUyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoY29ubmVjdGlvbjEpKTsKKworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24yID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24yLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQWNjZXB0LUxhbmd1YWdlIiwgImZyLUNBLCBmci1GUiIpOworICAgICAgICBjb25uZWN0aW9uMi5hZGRSZXF1ZXN0UHJvcGVydHkoIkFjY2VwdC1MYW5ndWFnZSIsICJlbi1VUyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoY29ubmVjdGlvbjIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmFyeU11bHRpcGxlRmllbGRWYWx1ZXNXaXRoTm9NYXRjaCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTYwIikKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJWYXJ5OiBBY2NlcHQtTGFuZ3VhZ2UiKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQiIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkwgdXJsID0gc2VydmVyLmdldFVybCgiLyIpOworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24xID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24xLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQWNjZXB0LUxhbmd1YWdlIiwgImZyLUNBLCBmci1GUiIpOworICAgICAgICBjb25uZWN0aW9uMS5hZGRSZXF1ZXN0UHJvcGVydHkoIkFjY2VwdC1MYW5ndWFnZSIsICJlbi1VUyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoY29ubmVjdGlvbjEpKTsKKworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24yID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24yLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQWNjZXB0LUxhbmd1YWdlIiwgImZyLUNBIik7CisgICAgICAgIGNvbm5lY3Rpb24yLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQWNjZXB0LUxhbmd1YWdlIiwgImVuLVVTIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQiIsIHJlYWRBc2NpaShjb25uZWN0aW9uMikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RWYXJ5QXN0ZXJpc2soKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT02MCIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiVmFyeTogKiIpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIkEiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRCb2R5KCJCIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkIiLCByZWFkQXNjaWkoc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmFyeUFuZEh0dHBzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IHRlc3RTU0xDb250ZXh0ID0gVGVzdFNTTENvbnRleHQuY3JlYXRlKCk7CisgICAgICAgIHNlcnZlci51c2VIdHRwcyh0ZXN0U1NMQ29udGV4dC5zZXJ2ZXJDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKSwgZmFsc2UpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTYwIikKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJWYXJ5OiBBY2NlcHQtTGFuZ3VhZ2UiKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQiIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkwgdXJsID0gc2VydmVyLmdldFVybCgiLyIpOworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24gY29ubmVjdGlvbjEgPSAoSHR0cHNVUkxDb25uZWN0aW9uKSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbjEuc2V0U1NMU29ja2V0RmFjdG9yeSh0ZXN0U1NMQ29udGV4dC5jbGllbnRDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKSk7CisgICAgICAgIGNvbm5lY3Rpb24xLmFkZFJlcXVlc3RQcm9wZXJ0eSgiQWNjZXB0LUxhbmd1YWdlIiwgImVuLVVTIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShjb25uZWN0aW9uMSkpOworCisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uMiA9IChIdHRwc1VSTENvbm5lY3Rpb24pIHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uMi5zZXRTU0xTb2NrZXRGYWN0b3J5KHRlc3RTU0xDb250ZXh0LmNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpKTsKKyAgICAgICAgY29ubmVjdGlvbjIuYWRkUmVxdWVzdFByb3BlcnR5KCJBY2NlcHQtTGFuZ3VhZ2UiLCAiZW4tVVMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24yKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERpc2tXcml0ZUZhaWx1cmVDYWNoZURlZ3JhZGF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIERlcXVlPEludm9jYXRpb25IYW5kbGVyPiB3cml0ZUhhbmRsZXJzID0gbW9ja09zLmdldEhhbmRsZXJzKCJ3cml0ZSIpOworICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgIGJvb2xlYW4gaGFzTW9yZVNjZW5hcmlvcyA9IHRydWU7CisgICAgICAgIHdoaWxlIChoYXNNb3JlU2NlbmFyaW9zKSB7CisgICAgICAgICAgICBtb2NrT3MuZW5xdWV1ZU5vcm1hbCgid3JpdGUiLCBpKyspOworICAgICAgICAgICAgbW9ja09zLmVucXVldWVGYXVsdCgid3JpdGUiKTsKKyAgICAgICAgICAgIGV4ZXJjaXNlUG9zc2libHlGYXVsdHlDYWNoZShmYWxzZSk7CisgICAgICAgICAgICBoYXNNb3JlU2NlbmFyaW9zID0gd3JpdGVIYW5kbGVycy5pc0VtcHR5KCk7CisgICAgICAgICAgICB3cml0ZUhhbmRsZXJzLmNsZWFyKCk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFeGVyY2lzaW5nIHRoZSBjYWNoZSBwZXJmb3JtcyAiICsgKGkgLSAxKSArICIgd3JpdGVzLiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REaXNrUmVhZEZhaWx1cmVDYWNoZURlZ3JhZGF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIERlcXVlPEludm9jYXRpb25IYW5kbGVyPiByZWFkSGFuZGxlcnMgPSBtb2NrT3MuZ2V0SGFuZGxlcnMoInJlYWQiKTsKKyAgICAgICAgaW50IGkgPSAwOworICAgICAgICBib29sZWFuIGhhc01vcmVTY2VuYXJpb3MgPSB0cnVlOworICAgICAgICB3aGlsZSAoaGFzTW9yZVNjZW5hcmlvcykgeworICAgICAgICAgICAgbW9ja09zLmVucXVldWVOb3JtYWwoInJlYWQiLCBpKyspOworICAgICAgICAgICAgbW9ja09zLmVucXVldWVGYXVsdCgicmVhZCIpOworICAgICAgICAgICAgZXhlcmNpc2VQb3NzaWJseUZhdWx0eUNhY2hlKHRydWUpOworICAgICAgICAgICAgaGFzTW9yZVNjZW5hcmlvcyA9IHJlYWRIYW5kbGVycy5pc0VtcHR5KCk7CisgICAgICAgICAgICByZWFkSGFuZGxlcnMuY2xlYXIoKTsKKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkV4ZXJjaXNpbmcgdGhlIGNhY2hlIHBlcmZvcm1zICIgKyAoaSAtIDEpICsgIiByZWFkcy4iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2FjaGVQbHVzQ29va2llcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJTZXQtQ29va2llOiBhPUZJUlNUOyBkb21haW49LmxvY2FsOyIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTGFzdC1Nb2RpZmllZDogIiArIGZvcm1hdERhdGUoLTEsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTAiKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJTZXQtQ29va2llOiBhPVNFQ09ORDsgZG9tYWluPS5sb2NhbDsiKQorICAgICAgICAgICAgICAgIC5zZXRSZXNwb25zZUNvZGUoSHR0cFVSTENvbm5lY3Rpb24uSFRUUF9OT1RfTU9ESUZJRUQpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkwgdXJsID0gc2VydmVyLmdldFVybCgiLyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkodXJsLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICAgICAgYXNzZXJ0Q29va2llcyh1cmwsICJhPUZJUlNUIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaSh1cmwub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBhc3NlcnRDb29raWVzKHVybCwgImE9U0VDT05EIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEhlYWRlcnNSZXR1cm5zTmV0d29ya0VuZFRvRW5kSGVhZGVycygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJBbGxvdzogR0VULCBIRUFEIikKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJMYXN0LU1vZGlmaWVkOiAiICsgZm9ybWF0RGF0ZSgtMSwgVGltZVVuaXQuSE9VUlMpKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNhY2hlLUNvbnRyb2w6IG1heC1hZ2U9MCIpCisgICAgICAgICAgICAgICAgLnNldEJvZHkoIkEiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkFsbG93OiBHRVQsIEhFQUQsIFBVVCIpCisgICAgICAgICAgICAgICAgLnNldFJlc3BvbnNlQ29kZShIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX05PVF9NT0RJRklFRCkpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbjEgPSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24xKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiR0VULCBIRUFEIiwgY29ubmVjdGlvbjEuZ2V0SGVhZGVyRmllbGQoIkFsbG93IikpOworCisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbjIgPSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24yKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiR0VULCBIRUFELCBQVVQiLCBjb25uZWN0aW9uMi5nZXRIZWFkZXJGaWVsZCgiQWxsb3ciKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEhlYWRlcnNSZXR1cm5zQ2FjaGVkSG9wQnlIb3BIZWFkZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIlRyYW5zZmVyLUVuY29kaW5nOiBpZGVudGl0eSIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTGFzdC1Nb2RpZmllZDogIiArIGZvcm1hdERhdGUoLTEsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTAiKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJUcmFuc2Zlci1FbmNvZGluZzogbm9uZSIpCisgICAgICAgICAgICAgICAgLnNldFJlc3BvbnNlQ29kZShIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX05PVF9NT0RJRklFRCkpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbjEgPSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24xKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaWRlbnRpdHkiLCBjb25uZWN0aW9uMS5nZXRIZWFkZXJGaWVsZCgiVHJhbnNmZXItRW5jb2RpbmciKSk7CisKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uMiA9IHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoY29ubmVjdGlvbjIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpZGVudGl0eSIsIGNvbm5lY3Rpb24yLmdldEhlYWRlckZpZWxkKCJUcmFuc2Zlci1FbmNvZGluZyIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SGVhZGVyc0RlbGV0ZXNDYWNoZWQxMDBMZXZlbFdhcm5pbmdzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIldhcm5pbmc6IDE5OSB0ZXN0IGRhbmdlciIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiTGFzdC1Nb2RpZmllZDogIiArIGZvcm1hdERhdGUoLTEsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDYWNoZS1Db250cm9sOiBtYXgtYWdlPTAiKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuc2V0UmVzcG9uc2VDb2RlKEh0dHBVUkxDb25uZWN0aW9uLkhUVFBfTk9UX01PRElGSUVEKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uMSA9IHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoY29ubmVjdGlvbjEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxOTkgdGVzdCBkYW5nZXIiLCBjb25uZWN0aW9uMS5nZXRIZWFkZXJGaWVsZCgiV2FybmluZyIpKTsKKworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24yID0gc2VydmVyLmdldFVybCgiLyIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaShjb25uZWN0aW9uMikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgY29ubmVjdGlvbjIuZ2V0SGVhZGVyRmllbGQoIldhcm5pbmciKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEhlYWRlcnNSZXRhaW5zQ2FjaGVkMjAwTGV2ZWxXYXJuaW5ncygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJXYXJuaW5nOiAyOTkgdGVzdCBkYW5nZXIiKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkxhc3QtTW9kaWZpZWQ6ICIgKyBmb3JtYXREYXRlKC0xLCBUaW1lVW5pdC5IT1VSUykpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT0wIikKKyAgICAgICAgICAgICAgICAuc2V0Qm9keSgiQSIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpCisgICAgICAgICAgICAgICAgLnNldFJlc3BvbnNlQ29kZShIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX05PVF9NT0RJRklFRCkpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbjEgPSBzZXJ2ZXIuZ2V0VXJsKCIvIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKGNvbm5lY3Rpb24xKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMjk5IHRlc3QgZGFuZ2VyIiwgY29ubmVjdGlvbjEuZ2V0SGVhZGVyRmllbGQoIldhcm5pbmciKSk7CisKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uMiA9IHNlcnZlci5nZXRVcmwoIi8iKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkoY29ubmVjdGlvbjIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIyOTkgdGVzdCBkYW5nZXIiLCBjb25uZWN0aW9uMi5nZXRIZWFkZXJGaWVsZCgiV2FybmluZyIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhc3NlcnRDb29raWVzKFVSTCB1cmwsIFN0cmluZy4uLiBleHBlY3RlZENvb2tpZXMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBMaXN0PFN0cmluZz4gYWN0dWFsQ29va2llcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBmb3IgKEh0dHBDb29raWUgY29va2llIDogY29va2llTWFuYWdlci5nZXRDb29raWVTdG9yZSgpLmdldCh1cmwudG9VUkkoKSkpIHsKKyAgICAgICAgICAgIGFjdHVhbENvb2tpZXMuYWRkKGNvb2tpZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdChleHBlY3RlZENvb2tpZXMpLCBhY3R1YWxDb29raWVzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2FjaGVQbHVzUmFuZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0Tm90Q2FjaGVkKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5zZXRSZXNwb25zZUNvZGUoSHR0cFVSTENvbm5lY3Rpb24uSFRUUF9QQVJUSUFMKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkRhdGU6ICIgKyBmb3JtYXREYXRlKDAsIFRpbWVVbml0LkhPVVJTKSkKKyAgICAgICAgICAgICAgICAuYWRkSGVhZGVyKCJDb250ZW50LVJhbmdlOiBieXRlcyAxMDAtMTAwLzIwMCIpCisgICAgICAgICAgICAgICAgLmFkZEhlYWRlcigiQ2FjaGUtQ29udHJvbDogbWF4LWFnZT02MCIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gZGVsdGEgdGhlIG9mZnNldCBmcm9tIHRoZSBjdXJyZW50IGRhdGUgdG8gdXNlLiBOZWdhdGl2ZQorICAgICAqICAgICB2YWx1ZXMgeWllbGQgZGF0ZXMgaW4gdGhlIHBhc3Q7IHBvc2l0aXZlIHZhbHVlcyB5aWVsZCBkYXRlcyBpbiB0aGUKKyAgICAgKiAgICAgZnV0dXJlLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGZvcm1hdERhdGUobG9uZyBkZWx0YSwgVGltZVVuaXQgdGltZVVuaXQpIHsKKyAgICAgICAgcmV0dXJuIGZvcm1hdERhdGUobmV3IERhdGUoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgKyB0aW1lVW5pdC50b01pbGxpcyhkZWx0YSkpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyBmb3JtYXREYXRlKERhdGUgZGF0ZSkgeworICAgICAgICBEYXRlRm9ybWF0IHJmYzExMjMgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgiRUVFLCBkZCBNTU0geXl5eSBISDptbTpzcyB6enoiLCBMb2NhbGUuVVMpOworICAgICAgICByZmMxMTIzLnNldFRpbWVab25lKFRpbWVab25lLmdldFRpbWVab25lKCJVVEMiKSk7CisgICAgICAgIHJldHVybiByZmMxMTIzLmZvcm1hdChkYXRlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYWRkUmVxdWVzdEJvZHlJZk5lY2Vzc2FyeShTdHJpbmcgcmVxdWVzdE1ldGhvZCwgSHR0cFVSTENvbm5lY3Rpb24gaW52YWxpZGF0ZSkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChyZXF1ZXN0TWV0aG9kLmVxdWFscygiUE9TVCIpIHx8IHJlcXVlc3RNZXRob2QuZXF1YWxzKCJQVVQiKSkgeworICAgICAgICAgICAgaW52YWxpZGF0ZS5zZXREb091dHB1dCh0cnVlKTsKKyAgICAgICAgICAgIE91dHB1dFN0cmVhbSByZXF1ZXN0Qm9keSA9IGludmFsaWRhdGUuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICByZXF1ZXN0Qm9keS53cml0ZSgneCcpOworICAgICAgICAgICAgcmVxdWVzdEJvZHkuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnROb3RDYWNoZWQoTW9ja1Jlc3BvbnNlIHJlc3BvbnNlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLmVucXVldWUocmVzcG9uc2Uuc2V0Qm9keSgiQSIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkIiKSk7CisgICAgICAgIHNlcnZlci5wbGF5KCk7CisKKyAgICAgICAgVVJMIHVybCA9IHNlcnZlci5nZXRVcmwoIi8iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKHVybC5vcGVuQ29ubmVjdGlvbigpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQiIsIHJlYWRBc2NpaSh1cmwub3BlbkNvbm5lY3Rpb24oKSkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBleGVyY2lzZVBvc3NpYmx5RmF1bHR5Q2FjaGUoYm9vbGVhbiBwZXJtaXRSZWFkQm9keUZhaWx1cmVzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2VydmVyLnNodXRkb3duKCk7CisgICAgICAgIHNlcnZlciA9IG5ldyBNb2NrV2ViU2VydmVyKCk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKQorICAgICAgICAgICAgICAgIC5hZGRIZWFkZXIoIkNhY2hlLUNvbnRyb2w6IG1heC1hZ2U9NjAiKQorICAgICAgICAgICAgICAgIC5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShuZXcgTW9ja1Jlc3BvbnNlKCkuc2V0Qm9keSgiQiIpKTsKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkwgdXJsID0gc2VydmVyLmdldFVybCgiLyIgKyBVVUlELnJhbmRvbVVVSUQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaSh1cmwub3BlbkNvbm5lY3Rpb24oKSkpOworCisgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IGNvbm5lY3Rpb24uZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBib2R5Q2hhciA9IGluLnJlYWQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoYm9keUNoYXIgPT0gJ0EnIHx8IGJvZHlDaGFyID09ICdCJyk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGluLnJlYWQoKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGlmICghcGVybWl0UmVhZEJvZHlGYWlsdXJlcykgeworICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0IHdpdGggdGhlIGNvbmRpdGlvbmFsIGdldCBoZWFkZXJzLgorICAgICAqLworICAgIHByaXZhdGUgUmVjb3JkZWRSZXF1ZXN0IGFzc2VydENvbmRpdGlvbmFsbHlDYWNoZWQoTW9ja1Jlc3BvbnNlIHJlc3BvbnNlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gc2NlbmFyaW8gMTogY29uZGl0aW9uIHN1Y2NlZWRzCisgICAgICAgIHNlcnZlci5lbnF1ZXVlKHJlc3BvbnNlLnNldEJvZHkoIkEiKSk7CisgICAgICAgIHNlcnZlci5lbnF1ZXVlKG5ldyBNb2NrUmVzcG9uc2UoKS5zZXRSZXNwb25zZUNvZGUoSHR0cFVSTENvbm5lY3Rpb24uSFRUUF9OT1RfTU9ESUZJRUQpKTsKKworICAgICAgICAvLyBzY2VuYXJpbyAyOiBjb25kaXRpb24gZmFpbHMKKyAgICAgICAgc2VydmVyLmVucXVldWUocmVzcG9uc2Uuc2V0Qm9keSgiQiIpKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIkMiKSk7CisKKyAgICAgICAgc2VydmVyLnBsYXkoKTsKKworICAgICAgICBVUkwgdmFsaWQgPSBzZXJ2ZXIuZ2V0VXJsKCIvdmFsaWQiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKHZhbGlkLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBIiwgcmVhZEFzY2lpKHZhbGlkLm9wZW5Db25uZWN0aW9uKCkpKTsKKworICAgICAgICBVUkwgaW52YWxpZCA9IHNlcnZlci5nZXRVcmwoIi9pbnZhbGlkIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQiIsIHJlYWRBc2NpaShpbnZhbGlkLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDIiwgcmVhZEFzY2lpKGludmFsaWQub3BlbkNvbm5lY3Rpb24oKSkpOworCisgICAgICAgIHNlcnZlci50YWtlUmVxdWVzdCgpOyAvLyByZWd1bGFyIGdldAorICAgICAgICByZXR1cm4gc2VydmVyLnRha2VSZXF1ZXN0KCk7IC8vIGNvbmRpdGlvbmFsIGdldAorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRGdWxseUNhY2hlZChNb2NrUmVzcG9uc2UgcmVzcG9uc2UpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShyZXNwb25zZS5zZXRCb2R5KCJBIikpOworICAgICAgICBzZXJ2ZXIuZW5xdWV1ZShyZXNwb25zZS5zZXRCb2R5KCJCIikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIFVSTCB1cmwgPSBzZXJ2ZXIuZ2V0VXJsKCIvIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHJlYWRBc2NpaSh1cmwub3BlbkNvbm5lY3Rpb24oKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEiLCByZWFkQXNjaWkodXJsLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTaG9ydGVucyB0aGUgYm9keSBvZiB7QGNvZGUgcmVzcG9uc2V9IGJ1dCBub3QgdGhlIGNvcnJlc3BvbmRpbmcgaGVhZGVycy4KKyAgICAgKiBPbmx5IHVzZWZ1bCB0byB0ZXN0IGhvdyBjbGllbnRzIHJlc3BvbmQgdG8gdGhlIHByZW1hdHVyZSBjb25jbHVzaW9uIG9mCisgICAgICogdGhlIEhUVFAgYm9keS4KKyAgICAgKi8KKyAgICBwcml2YXRlIE1vY2tSZXNwb25zZSB0cnVuY2F0ZVZpb2xlbnRseShNb2NrUmVzcG9uc2UgcmVzcG9uc2UsIGludCBudW1CeXRlc1RvS2VlcCkgeworICAgICAgICByZXNwb25zZS5zZXRTb2NrZXRQb2xpY3koRElTQ09OTkVDVF9BVF9FTkQpOworICAgICAgICBMaXN0PFN0cmluZz4gaGVhZGVycyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPihyZXNwb25zZS5nZXRIZWFkZXJzKCkpOworICAgICAgICByZXNwb25zZS5zZXRCb2R5KEFycmF5cy5jb3B5T2ZSYW5nZShyZXNwb25zZS5nZXRCb2R5KCksIDAsIG51bUJ5dGVzVG9LZWVwKSk7CisgICAgICAgIHJlc3BvbnNlLmdldEhlYWRlcnMoKS5jbGVhcigpOworICAgICAgICByZXNwb25zZS5nZXRIZWFkZXJzKCkuYWRkQWxsKGhlYWRlcnMpOworICAgICAgICByZXR1cm4gcmVzcG9uc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMge0Bjb2RlIGNvdW50fSBjaGFyYWN0ZXJzIGZyb20gdGhlIHN0cmVhbS4gSWYgdGhlIHN0cmVhbSBpcworICAgICAqIGV4aGF1c3RlZCBiZWZvcmUge0Bjb2RlIGNvdW50fSBjaGFyYWN0ZXJzIGNhbiBiZSByZWFkLCB0aGUgcmVtYWluaW5nCisgICAgICogY2hhcmFjdGVycyBhcmUgcmV0dXJuZWQgYW5kIHRoZSBzdHJlYW0gaXMgY2xvc2VkLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHJlYWRBc2NpaShVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24sIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gaHR0cENvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIGNvbm5lY3Rpb247CisgICAgICAgIElucHV0U3RyZWFtIGluID0gaHR0cENvbm5lY3Rpb24uZ2V0UmVzcG9uc2VDb2RlKCkgPCBIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX0JBRF9SRVFVRVNUCisgICAgICAgICAgICAgICAgPyBjb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCkKKyAgICAgICAgICAgICAgICA6IGh0dHBDb25uZWN0aW9uLmdldEVycm9yU3RyZWFtKCk7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CisgICAgICAgICAgICBpbnQgdmFsdWUgPSBpbi5yZWFkKCk7CisgICAgICAgICAgICBpZiAodmFsdWUgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgoY2hhcikgdmFsdWUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyByZWFkQXNjaWkoVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gcmVhZEFzY2lpKGNvbm5lY3Rpb24sIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVsaWFibGVTa2lwKElucHV0U3RyZWFtIGluLCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3aGlsZSAobGVuZ3RoID4gMCkgeworICAgICAgICAgICAgbGVuZ3RoIC09IGluLnNraXAobGVuZ3RoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRCYWRHYXRld2F5KEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyhIdHRwVVJMQ29ubmVjdGlvbi5IVFRQX0JBRF9HQVRFV0FZLCBjb25uZWN0aW9uLmdldFJlc3BvbnNlQ29kZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBjb25uZWN0aW9uLmdldEVycm9yU3RyZWFtKCkucmVhZCgpKTsKKyAgICB9CisKKyAgICBlbnVtIFRyYW5zZmVyS2luZCB7CisgICAgICAgIENIVU5LRUQoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgdm9pZCBzZXRCb2R5KE1vY2tSZXNwb25zZSByZXNwb25zZSwgYnl0ZVtdIGNvbnRlbnQsIGludCBjaHVua1NpemUpCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmVzcG9uc2Uuc2V0Q2h1bmtlZEJvZHkoY29udGVudCwgY2h1bmtTaXplKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSwKKyAgICAgICAgRklYRURfTEVOR1RIKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHZvaWQgc2V0Qm9keShNb2NrUmVzcG9uc2UgcmVzcG9uc2UsIGJ5dGVbXSBjb250ZW50LCBpbnQgY2h1bmtTaXplKSB7CisgICAgICAgICAgICAgICAgcmVzcG9uc2Uuc2V0Qm9keShjb250ZW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSwKKyAgICAgICAgRU5EX09GX1NUUkVBTSgpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSB2b2lkIHNldEJvZHkoTW9ja1Jlc3BvbnNlIHJlc3BvbnNlLCBieXRlW10gY29udGVudCwgaW50IGNodW5rU2l6ZSkgeworICAgICAgICAgICAgICAgIHJlc3BvbnNlLnNldEJvZHkoY29udGVudCk7CisgICAgICAgICAgICAgICAgcmVzcG9uc2Uuc2V0U29ja2V0UG9saWN5KERJU0NPTk5FQ1RfQVRfRU5EKTsKKyAgICAgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yPFN0cmluZz4gaCA9IHJlc3BvbnNlLmdldEhlYWRlcnMoKS5pdGVyYXRvcigpOyBoLmhhc05leHQoKTsgKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChoLm5leHQoKS5zdGFydHNXaXRoKCJDb250ZW50LUxlbmd0aDoiKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaC5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIGFic3RyYWN0IHZvaWQgc2V0Qm9keShNb2NrUmVzcG9uc2UgcmVzcG9uc2UsIGJ5dGVbXSBjb250ZW50LCBpbnQgY2h1bmtTaXplKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgICAgICB2b2lkIHNldEJvZHkoTW9ja1Jlc3BvbnNlIHJlc3BvbnNlLCBTdHJpbmcgY29udGVudCwgaW50IGNodW5rU2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHNldEJvZHkocmVzcG9uc2UsIGNvbnRlbnQuZ2V0Qnl0ZXMoIlVURi04IiksIGNodW5rU2l6ZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIDxUPiBMaXN0PFQ+IHRvTGlzdE9yTnVsbChUW10gYXJyYXlPck51bGwpIHsKKyAgICAgICAgcmV0dXJuIGFycmF5T3JOdWxsICE9IG51bGwgPyBBcnJheXMuYXNMaXN0KGFycmF5T3JOdWxsKSA6IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGd6aXBwZWQgY29weSBvZiB7QGNvZGUgYnl0ZXN9LgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ3ppcChieXRlW10gYnl0ZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBieXRlc091dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgT3V0cHV0U3RyZWFtIGd6aXBwZWRPdXQgPSBuZXcgR1pJUE91dHB1dFN0cmVhbShieXRlc091dCk7CisgICAgICAgIGd6aXBwZWRPdXQud3JpdGUoYnl0ZXMpOworICAgICAgICBnemlwcGVkT3V0LmNsb3NlKCk7CisgICAgICAgIHJldHVybiBieXRlc091dC50b0J5dGVBcnJheSgpOworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgSW5zZWN1cmVSZXNwb25zZUNhY2hlIGV4dGVuZHMgUmVzcG9uc2VDYWNoZSB7CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgQ2FjaGVSZXF1ZXN0IHB1dChVUkkgdXJpLCBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gY2FjaGUucHV0KHVyaSwgY29ubmVjdGlvbik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIENhY2hlUmVzcG9uc2UgZ2V0KFVSSSB1cmksIFN0cmluZyByZXF1ZXN0TWV0aG9kLAorICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsIExpc3Q8U3RyaW5nPj4gcmVxdWVzdEhlYWRlcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBmaW5hbCBDYWNoZVJlc3BvbnNlIHJlc3BvbnNlID0gY2FjaGUuZ2V0KHVyaSwgcmVxdWVzdE1ldGhvZCwgcmVxdWVzdEhlYWRlcnMpOworICAgICAgICAgICAgaWYgKHJlc3BvbnNlIGluc3RhbmNlb2YgU2VjdXJlQ2FjaGVSZXNwb25zZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ2FjaGVSZXNwb25zZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRCb2R5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZS5nZXRCb2R5KCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IGdldEhlYWRlcnMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLmdldEhlYWRlcnMoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9uZXQvaHR0cC9QYXJzZWRIZWFkZXJzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvUGFyc2VkSGVhZGVyc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZGIyZDRkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvUGFyc2VkSGVhZGVyc1Rlc3QuamF2YQpAQCAtMCwwICsxLDE4NyBAQAorLyoKKyogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyoKKyogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisqCisqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisqCisqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCitwYWNrYWdlIGxpYmNvcmUubmV0Lmh0dHA7CisKK2ltcG9ydCBqYXZhLm5ldC5VUkk7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgUGFyc2VkSGVhZGVyc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIFVSSSB1cmk7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdXJpID0gbmV3IFVSSSgiaHR0cCIsICJsb2NhbGhvc3QiLCAiLyIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVcHBlckNhc2VIdHRwSGVhZGVycygpIHsKKyAgICAgICAgUmF3SGVhZGVycyBoZWFkZXJzID0gbmV3IFJhd0hlYWRlcnMoKTsKKyAgICAgICAgaGVhZGVycy5hZGQoIkNBQ0hFLUNPTlRST0wiLCAibm8tc3RvcmUiKTsKKyAgICAgICAgaGVhZGVycy5hZGQoIkRBVEUiLCAiVGh1LCAwMSBKYW4gMTk3MCAwMDowMDowMSBVVEMiKTsKKyAgICAgICAgaGVhZGVycy5hZGQoIkVYUElSRVMiLCAiVGh1LCAwMSBKYW4gMTk3MCAwMDowMDowMiBVVEMiKTsKKyAgICAgICAgaGVhZGVycy5hZGQoIkxBU1QtTU9ESUZJRUQiLCAiVGh1LCAwMSBKYW4gMTk3MCAwMDowMDowMyBVVEMiKTsKKyAgICAgICAgaGVhZGVycy5hZGQoIkVUQUciLCAidjEiKTsKKyAgICAgICAgaGVhZGVycy5hZGQoIlBSQUdNQSIsICJuby1jYWNoZSIpOworICAgICAgICBSZXNwb25zZUhlYWRlcnMgcGFyc2VkSGVhZGVycyA9IG5ldyBSZXNwb25zZUhlYWRlcnModXJpLCBoZWFkZXJzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwYXJzZWRIZWFkZXJzLmlzTm9TdG9yZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBEYXRlKDEwMDApLCBwYXJzZWRIZWFkZXJzLmdldFNlcnZlZERhdGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgRGF0ZSgyMDAwKSwgcGFyc2VkSGVhZGVycy5nZXRFeHBpcmVzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IERhdGUoMzAwMCksIHBhcnNlZEhlYWRlcnMuZ2V0TGFzdE1vZGlmaWVkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInYxIiwgcGFyc2VkSGVhZGVycy5nZXRFdGFnKCkpOworICAgICAgICBhc3NlcnRUcnVlKHBhcnNlZEhlYWRlcnMuaXNOb0NhY2hlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb21tYVNlcGFyYXRlZENhY2hlQ29udHJvbEhlYWRlcnMoKSB7CisgICAgICAgIFJhd0hlYWRlcnMgaGVhZGVycyA9IG5ldyBSYXdIZWFkZXJzKCk7CisgICAgICAgIGhlYWRlcnMuYWRkKCJDYWNoZS1Db250cm9sIiwgIm5vLXN0b3JlLCBtYXgtYWdlPTYwLCBwdWJsaWMiKTsKKyAgICAgICAgUmVzcG9uc2VIZWFkZXJzIHBhcnNlZEhlYWRlcnMgPSBuZXcgUmVzcG9uc2VIZWFkZXJzKHVyaSwgaGVhZGVycyk7CisgICAgICAgIGFzc2VydFRydWUocGFyc2VkSGVhZGVycy5pc05vU3RvcmUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg2MCwgcGFyc2VkSGVhZGVycy5nZXRNYXhBZ2VTZWNvbmRzKCkpOworICAgICAgICBhc3NlcnRUcnVlKHBhcnNlZEhlYWRlcnMuaXNQdWJsaWMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFF1b3RlZEZpZWxkTmFtZSgpIHsKKyAgICAgICAgUmF3SGVhZGVycyBoZWFkZXJzID0gbmV3IFJhd0hlYWRlcnMoKTsKKyAgICAgICAgaGVhZGVycy5hZGQoIkNhY2hlLUNvbnRyb2wiLCAicHJpdmF0ZT1cIlNldC1Db29raWVcIiwgbm8tc3RvcmUiKTsKKyAgICAgICAgUmVzcG9uc2VIZWFkZXJzIHBhcnNlZEhlYWRlcnMgPSBuZXcgUmVzcG9uc2VIZWFkZXJzKHVyaSwgaGVhZGVycyk7CisgICAgICAgIGFzc2VydFRydWUocGFyc2VkSGVhZGVycy5pc05vU3RvcmUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFVucXVvdGVkVmFsdWUoKSB7CisgICAgICAgIFJhd0hlYWRlcnMgaGVhZGVycyA9IG5ldyBSYXdIZWFkZXJzKCk7CisgICAgICAgIGhlYWRlcnMuYWRkKCJDYWNoZS1Db250cm9sIiwgInByaXZhdGU9U2V0LUNvb2tpZSwgbm8tc3RvcmUiKTsKKyAgICAgICAgUmVzcG9uc2VIZWFkZXJzIHBhcnNlZEhlYWRlcnMgPSBuZXcgUmVzcG9uc2VIZWFkZXJzKHVyaSwgaGVhZGVycyk7CisgICAgICAgIGFzc2VydFRydWUocGFyc2VkSGVhZGVycy5pc05vU3RvcmUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFF1b3RlZFZhbHVlKCkgeworICAgICAgICBSYXdIZWFkZXJzIGhlYWRlcnMgPSBuZXcgUmF3SGVhZGVycygpOworICAgICAgICBoZWFkZXJzLmFkZCgiQ2FjaGUtQ29udHJvbCIsICJwcml2YXRlPVwiIGEsIG5vLWNhY2hlLCBjIFwiLCBuby1zdG9yZSIpOworICAgICAgICBSZXNwb25zZUhlYWRlcnMgcGFyc2VkSGVhZGVycyA9IG5ldyBSZXNwb25zZUhlYWRlcnModXJpLCBoZWFkZXJzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwYXJzZWRIZWFkZXJzLmlzTm9TdG9yZSgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocGFyc2VkSGVhZGVycy5pc05vQ2FjaGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERhbmdsaW5nUXVvdGUoKSB7CisgICAgICAgIFJhd0hlYWRlcnMgaGVhZGVycyA9IG5ldyBSYXdIZWFkZXJzKCk7CisgICAgICAgIGhlYWRlcnMuYWRkKCJDYWNoZS1Db250cm9sIiwgInByaXZhdGU9XCJhLCBuby1jYWNoZSwgYyIpOworICAgICAgICBSZXNwb25zZUhlYWRlcnMgcGFyc2VkSGVhZGVycyA9IG5ldyBSZXNwb25zZUhlYWRlcnModXJpLCBoZWFkZXJzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocGFyc2VkSGVhZGVycy5pc05vQ2FjaGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRyYWlsaW5nQ29tbWEoKSB7CisgICAgICAgIFJhd0hlYWRlcnMgaGVhZGVycyA9IG5ldyBSYXdIZWFkZXJzKCk7CisgICAgICAgIGhlYWRlcnMuYWRkKCJDYWNoZS1Db250cm9sIiwgInB1YmxpYywiKTsKKyAgICAgICAgUmVzcG9uc2VIZWFkZXJzIHBhcnNlZEhlYWRlcnMgPSBuZXcgUmVzcG9uc2VIZWFkZXJzKHVyaSwgaGVhZGVycyk7CisgICAgICAgIGFzc2VydFRydWUocGFyc2VkSGVhZGVycy5pc1B1YmxpYygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VHJhaWxpbmdFcXVhbHMoKSB7CisgICAgICAgIFJhd0hlYWRlcnMgaGVhZGVycyA9IG5ldyBSYXdIZWFkZXJzKCk7CisgICAgICAgIGhlYWRlcnMuYWRkKCJDYWNoZS1Db250cm9sIiwgInByaXZhdGU9Iik7CisgICAgICAgIG5ldyBSZXNwb25zZUhlYWRlcnModXJpLCBoZWFkZXJzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3BhY2VCZWZvcmVFcXVhbHMoKSB7CisgICAgICAgIFJhd0hlYWRlcnMgaGVhZGVycyA9IG5ldyBSYXdIZWFkZXJzKCk7CisgICAgICAgIGhlYWRlcnMuYWRkKCJDYWNoZS1Db250cm9sIiwgIm1heC1hZ2UgPTYwIik7CisgICAgICAgIFJlcXVlc3RIZWFkZXJzIHBhcnNlZEhlYWRlcnMgPSBuZXcgUmVxdWVzdEhlYWRlcnModXJpLCBoZWFkZXJzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDYwLCBwYXJzZWRIZWFkZXJzLmdldE1heEFnZVNlY29uZHMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNwYWNlQWZ0ZXJFcXVhbHNXaXRoUXVvdGVzKCkgeworICAgICAgICBSYXdIZWFkZXJzIGhlYWRlcnMgPSBuZXcgUmF3SGVhZGVycygpOworICAgICAgICBoZWFkZXJzLmFkZCgiQ2FjaGUtQ29udHJvbCIsICJtYXgtYWdlPSBcIjYwXCIiKTsKKyAgICAgICAgUmVxdWVzdEhlYWRlcnMgcGFyc2VkSGVhZGVycyA9IG5ldyBSZXF1ZXN0SGVhZGVycyh1cmksIGhlYWRlcnMpOworICAgICAgICBhc3NlcnRFcXVhbHMoNjAsIHBhcnNlZEhlYWRlcnMuZ2V0TWF4QWdlU2Vjb25kcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3BhY2VBZnRlckVxdWFsc1dpdGhvdXRRdW90ZXMoKSB7CisgICAgICAgIFJhd0hlYWRlcnMgaGVhZGVycyA9IG5ldyBSYXdIZWFkZXJzKCk7CisgICAgICAgIGhlYWRlcnMuYWRkKCJDYWNoZS1Db250cm9sIiwgIm1heC1hZ2U9IDYwIik7CisgICAgICAgIFJlcXVlc3RIZWFkZXJzIHBhcnNlZEhlYWRlcnMgPSBuZXcgUmVxdWVzdEhlYWRlcnModXJpLCBoZWFkZXJzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDYwLCBwYXJzZWRIZWFkZXJzLmdldE1heEFnZVNlY29uZHMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENhY2hlQ29udHJvbFJlcXVlc3REaXJlY3RpdmVzQXJlQ2FzZUluc2Vuc2l0aXZlKCkgeworICAgICAgICBSYXdIZWFkZXJzIGhlYWRlcnMgPSBuZXcgUmF3SGVhZGVycygpOworICAgICAgICBoZWFkZXJzLmFkZCgiQ2FjaGUtQ29udHJvbCIsICJOTy1DQUNIRSIpOworICAgICAgICBoZWFkZXJzLmFkZCgiQ2FjaGUtQ29udHJvbCIsICJNQVgtQUdFPTYwIik7CisgICAgICAgIGhlYWRlcnMuYWRkKCJDYWNoZS1Db250cm9sIiwgIk1BWC1TVEFMRT03MCIpOworICAgICAgICBoZWFkZXJzLmFkZCgiQ2FjaGUtQ29udHJvbCIsICJNSU4tRlJFU0g9ODAiKTsKKyAgICAgICAgaGVhZGVycy5hZGQoIkNhY2hlLUNvbnRyb2wiLCAiT05MWS1JRi1DQUNIRUQiKTsKKyAgICAgICAgUmVxdWVzdEhlYWRlcnMgcGFyc2VkSGVhZGVycyA9IG5ldyBSZXF1ZXN0SGVhZGVycyh1cmksIGhlYWRlcnMpOworICAgICAgICBhc3NlcnRUcnVlKHBhcnNlZEhlYWRlcnMuaXNOb0NhY2hlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNjAsIHBhcnNlZEhlYWRlcnMuZ2V0TWF4QWdlU2Vjb25kcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDcwLCBwYXJzZWRIZWFkZXJzLmdldE1heFN0YWxlU2Vjb25kcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDgwLCBwYXJzZWRIZWFkZXJzLmdldE1pbkZyZXNoU2Vjb25kcygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwYXJzZWRIZWFkZXJzLmlzT25seUlmQ2FjaGVkKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDYWNoZUNvbnRyb2xSZXNwb25zZURpcmVjdGl2ZXNBcmVDYXNlSW5zZW5zaXRpdmUoKSB7CisgICAgICAgIFJhd0hlYWRlcnMgaGVhZGVycyA9IG5ldyBSYXdIZWFkZXJzKCk7CisgICAgICAgIGhlYWRlcnMuYWRkKCJDYWNoZS1Db250cm9sIiwgIk5PLUNBQ0hFIik7CisgICAgICAgIGhlYWRlcnMuYWRkKCJDYWNoZS1Db250cm9sIiwgIk5PLVNUT1JFIik7CisgICAgICAgIGhlYWRlcnMuYWRkKCJDYWNoZS1Db250cm9sIiwgIk1BWC1BR0U9NjAiKTsKKyAgICAgICAgaGVhZGVycy5hZGQoIkNhY2hlLUNvbnRyb2wiLCAiUy1NQVhBR0U9NzAiKTsKKyAgICAgICAgaGVhZGVycy5hZGQoIkNhY2hlLUNvbnRyb2wiLCAiUFVCTElDIik7CisgICAgICAgIGhlYWRlcnMuYWRkKCJDYWNoZS1Db250cm9sIiwgIk1VU1QtUkVWQUxJREFURSIpOworICAgICAgICBSZXNwb25zZUhlYWRlcnMgcGFyc2VkSGVhZGVycyA9IG5ldyBSZXNwb25zZUhlYWRlcnModXJpLCBoZWFkZXJzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwYXJzZWRIZWFkZXJzLmlzTm9DYWNoZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwYXJzZWRIZWFkZXJzLmlzTm9TdG9yZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDYwLCBwYXJzZWRIZWFkZXJzLmdldE1heEFnZVNlY29uZHMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg3MCwgcGFyc2VkSGVhZGVycy5nZXRTTWF4QWdlU2Vjb25kcygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwYXJzZWRIZWFkZXJzLmlzUHVibGljKCkpOworICAgICAgICBhc3NlcnRUcnVlKHBhcnNlZEhlYWRlcnMuaXNNdXN0UmV2YWxpZGF0ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJhZ21hRGlyZWN0aXZlc0FyZUNhc2VJbnNlbnNpdGl2ZSgpIHsKKyAgICAgICAgUmF3SGVhZGVycyBoZWFkZXJzID0gbmV3IFJhd0hlYWRlcnMoKTsKKyAgICAgICAgaGVhZGVycy5hZGQoIlByYWdtYSIsICJOTy1DQUNIRSIpOworICAgICAgICBSZXF1ZXN0SGVhZGVycyBwYXJzZWRIZWFkZXJzID0gbmV3IFJlcXVlc3RIZWFkZXJzKHVyaSwgaGVhZGVycyk7CisgICAgICAgIGFzc2VydFRydWUocGFyc2VkSGVhZGVycy5pc05vQ2FjaGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1pc3NpbmdJbnRlZ2VyKCkgeworICAgICAgICBSYXdIZWFkZXJzIGhlYWRlcnMgPSBuZXcgUmF3SGVhZGVycygpOworICAgICAgICBoZWFkZXJzLmFkZCgiQ2FjaGUtQ29udHJvbCIsICJtYXgtYWdlIik7CisgICAgICAgIFJlcXVlc3RIZWFkZXJzIHBhcnNlZEhlYWRlcnMgPSBuZXcgUmVxdWVzdEhlYWRlcnModXJpLCBoZWFkZXJzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBwYXJzZWRIZWFkZXJzLmdldE1heEFnZVNlY29uZHMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEludmFsaWRJbnRlZ2VyKCkgeworICAgICAgICBSYXdIZWFkZXJzIGhlYWRlcnMgPSBuZXcgUmF3SGVhZGVycygpOworICAgICAgICBoZWFkZXJzLmFkZCgiQ2FjaGUtQ29udHJvbCIsICJNQVgtQUdFPXBpIik7CisgICAgICAgIFJlcXVlc3RIZWFkZXJzIHJlcXVlc3RIZWFkZXJzID0gbmV3IFJlcXVlc3RIZWFkZXJzKHVyaSwgaGVhZGVycyk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgcmVxdWVzdEhlYWRlcnMuZ2V0TWF4QWdlU2Vjb25kcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmVyeUxhcmdlSW50ZWdlcigpIHsKKyAgICAgICAgUmF3SGVhZGVycyBoZWFkZXJzID0gbmV3IFJhd0hlYWRlcnMoKTsKKyAgICAgICAgaGVhZGVycy5hZGQoIkNhY2hlLUNvbnRyb2wiLCAiTUFYLUFHRT0iICsgKEludGVnZXIuTUFYX1ZBTFVFICsgMUwpKTsKKyAgICAgICAgUmVxdWVzdEhlYWRlcnMgcGFyc2VkSGVhZGVycyA9IG5ldyBSZXF1ZXN0SGVhZGVycyh1cmksIGhlYWRlcnMpOworICAgICAgICBhc3NlcnRFcXVhbHMoSW50ZWdlci5NQVhfVkFMVUUsIHBhcnNlZEhlYWRlcnMuZ2V0TWF4QWdlU2Vjb25kcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmVnYXRpdmVJbnRlZ2VyKCkgeworICAgICAgICBSYXdIZWFkZXJzIGhlYWRlcnMgPSBuZXcgUmF3SGVhZGVycygpOworICAgICAgICBoZWFkZXJzLmFkZCgiQ2FjaGUtQ29udHJvbCIsICJNQVgtQUdFPS0yIik7CisgICAgICAgIFJlcXVlc3RIZWFkZXJzIHBhcnNlZEhlYWRlcnMgPSBuZXcgUmVxdWVzdEhlYWRlcnModXJpLCBoZWFkZXJzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHBhcnNlZEhlYWRlcnMuZ2V0TWF4QWdlU2Vjb25kcygpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9uZXQvaHR0cC9SYXdIZWFkZXJzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvUmF3SGVhZGVyc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOTllODUxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvbmV0L2h0dHAvUmF3SGVhZGVyc1Rlc3QuamF2YQpAQCAtMCwwICsxLDU0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLm5ldC5odHRwOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBSYXdIZWFkZXJzVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICAvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTY2ODQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nhc2VJbnNlbnNpdGl2ZUJ1dENhc2VQcmVzZXJ2aW5nKCkgeworICAgICAgICBSYXdIZWFkZXJzIGggPSBuZXcgUmF3SGVhZGVycygpOworICAgICAgICBoLmFkZCgiQ29udGVudC1UeXBlIiwgInRleHQvcGxhaW4iKTsKKyAgICAgICAgLy8gQ2FzZS1pbnNlbnNpdGl2ZToKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0L3BsYWluIiwgaC5nZXQoIkNvbnRlbnQtVHlwZSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0L3BsYWluIiwgaC5nZXQoIkNvbnRlbnQtdHlwZSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0L3BsYWluIiwgaC5nZXQoImNvbnRlbnQtdHlwZSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0L3BsYWluIiwgaC5nZXQoIkNPTlRFTlQtVFlQRSIpKTsKKyAgICAgICAgLy8gLi4uYnV0IGNhc2UtcHJlc2VydmluZzoKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDb250ZW50LVR5cGUiLCBoLnRvTXVsdGltYXAoKS5rZXlTZXQoKS50b0FycmF5KClbMF0pOworCisgICAgICAgIC8vIFdlIGRpZmZlciBmcm9tIHRoZSBSSSBpbiB0aGF0IHRoZSBNYXAgd2UgcmV0dXJuIGlzIGFsc28gY2FzZS1pbnNlbnNpdGl2ZS4KKyAgICAgICAgLy8gT3VyIGJlaGF2aW9yIHNlZW1zIG1vcmUgY29uc2lzdGVudC4gKEFuZCBjb2RlIHRoYXQgd29ya3Mgb24gdGhlIFJJIHdpbGwgd29yayBvbiBBbmRyb2lkLikKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoInRleHQvcGxhaW4iKSwgaC50b011bHRpbWFwKCkuZ2V0KCJDb250ZW50LVR5cGUiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KCJ0ZXh0L3BsYWluIiksIGgudG9NdWx0aW1hcCgpLmdldCgiQ29udGVudC10eXBlIikpOyAvLyBSSSBmYWlscyB0aGlzLgorICAgIH0KKworICAgIC8vIFRoZSBjb3B5IGNvbnN0cnVjdG9yIHVzZWQgdG8gYmUgYnJva2VuIGZvciBoZWFkZXJzIHdpdGggbXVsdGlwbGUgdmFsdWVzLgorICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9NjcyMgorICAgIHB1YmxpYyB2b2lkIHRlc3RfY29weUNvbnN0cnVjdG9yKCkgeworICAgICAgICBSYXdIZWFkZXJzIGgxID0gbmV3IFJhd0hlYWRlcnMoKTsKKyAgICAgICAgaDEuYWRkKCJrZXkiLCAidmFsdWUxIik7CisgICAgICAgIGgxLmFkZCgia2V5IiwgInZhbHVlMiIpOworICAgICAgICBSYXdIZWFkZXJzIGgyID0gUmF3SGVhZGVycy5mcm9tTXVsdGltYXAoaDEudG9NdWx0aW1hcCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGgyLmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJrZXkiLCBoMi5nZXRGaWVsZE5hbWUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlMSIsIGgyLmdldFZhbHVlKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJrZXkiLCBoMi5nZXRGaWVsZE5hbWUoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlMiIsIGgyLmdldFZhbHVlKDEpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9uZXQvdXJsL1VybFV0aWxzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvbmV0L3VybC9VcmxVdGlsc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOTg0ZTIyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvbmV0L3VybC9VcmxVdGlsc1Rlc3QuamF2YQpAQCAtMCwwICsxLDg5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLm5ldC51cmw7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBVcmxVdGlsc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdENhbm9uaWNhbGl6ZVBhdGgoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aCgiIiwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIFVybFV0aWxzLmNhbm9uaWNhbGl6ZVBhdGgoIi4iLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aCgiLi4iLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLi4uIiwgVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aCgiLi4uIiwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIFVybFV0aWxzLmNhbm9uaWNhbGl6ZVBhdGgoIi4vIiwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIFVybFV0aWxzLmNhbm9uaWNhbGl6ZVBhdGgoIi4uLyIsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aCgiLi4vYSIsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aCgiYSIsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhLyIsIFVybFV0aWxzLmNhbm9uaWNhbGl6ZVBhdGgoImEvIiwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEvIiwgVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aCgiYS8uIiwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEvYiIsIFVybFV0aWxzLmNhbm9uaWNhbGl6ZVBhdGgoImEvLi9iIiwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIFVybFV0aWxzLmNhbm9uaWNhbGl6ZVBhdGgoImEvLi4iLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYiIsIFVybFV0aWxzLmNhbm9uaWNhbGl6ZVBhdGgoImEvLi4vYiIsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhLy4uLi9iIiwgVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aCgiYS8uLi4vYiIsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhL2IiLCBVcmxVdGlscy5jYW5vbmljYWxpemVQYXRoKCJhL2IiLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYS9iLyIsIFVybFV0aWxzLmNhbm9uaWNhbGl6ZVBhdGgoImEvYi8uIiwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEvYi8iLCBVcmxVdGlscy5jYW5vbmljYWxpemVQYXRoKCJhL2IvLi8iLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYS9iL2MiLCBVcmxVdGlscy5jYW5vbmljYWxpemVQYXRoKCJhL2IvLi9jIiwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEvIiwgVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aCgiYS9iLy4uIiwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEvIiwgVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aCgiYS9iLy4uLyIsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhLy8iLCBVcmxVdGlscy5jYW5vbmljYWxpemVQYXRoKCJhL2IvLi4vLyIsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhL2MiLCBVcmxVdGlscy5jYW5vbmljYWxpemVQYXRoKCJhL2IvLi4vYyIsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhLy9jIiwgVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aCgiYS9iLy4uLy9jIiwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImMiLCBVcmxVdGlscy5jYW5vbmljYWxpemVQYXRoKCJhL2IvLi4vLi4vYyIsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvIiwgVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aCgiLyIsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvLyIsIFVybFV0aWxzLmNhbm9uaWNhbGl6ZVBhdGgoIi8vIiwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIi8iLCBVcmxVdGlscy5jYW5vbmljYWxpemVQYXRoKCIvLiIsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvIiwgVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aCgiLy4vIiwgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIFVybFV0aWxzLmNhbm9uaWNhbGl6ZVBhdGgoIi8uLiIsIHRydWUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjIiwgVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aCgiLy4uL2MiLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiL2EvYi9jIiwgVXJsVXRpbHMuY2Fub25pY2FsaXplUGF0aCgiL2EvYi9jIiwgdHJ1ZSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQcm90b2NvbFByZWZpeCgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwIiwgVXJsVXRpbHMuZ2V0U2NoZW1lUHJlZml4KCJodHRwOiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwIiwgVXJsVXRpbHMuZ2V0U2NoZW1lUHJlZml4KCJIVFRQOiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwIiwgVXJsVXRpbHMuZ2V0U2NoZW1lUHJlZml4KCJodHRwOngiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIFVybFV0aWxzLmdldFNjaGVtZVByZWZpeCgiYToiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieiIsIFVybFV0aWxzLmdldFNjaGVtZVByZWZpeCgiejoiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIFVybFV0aWxzLmdldFNjaGVtZVByZWZpeCgiQToiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieiIsIFVybFV0aWxzLmdldFNjaGVtZVByZWZpeCgiWjoiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaDAiLCBVcmxVdGlscy5nZXRTY2hlbWVQcmVmaXgoImgwOiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJoNSIsIFVybFV0aWxzLmdldFNjaGVtZVByZWZpeCgiaDU6IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImg5IiwgVXJsVXRpbHMuZ2V0U2NoZW1lUHJlZml4KCJoOToiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaCsiLCBVcmxVdGlscy5nZXRTY2hlbWVQcmVmaXgoImgrOiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJoLSIsIFVybFV0aWxzLmdldFNjaGVtZVByZWZpeCgiaC06IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImguIiwgVXJsVXRpbHMuZ2V0U2NoZW1lUHJlZml4KCJoLjoiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFByb3RvY29sUHJlZml4SW52YWxpZFNjaGVtZSgpIHsKKyAgICAgICAgYXNzZXJ0TnVsbChVcmxVdGlscy5nZXRTY2hlbWVQcmVmaXgoIiIpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChVcmxVdGlscy5nZXRTY2hlbWVQcmVmaXgoImh0dHAiKSk7CisgICAgICAgIGFzc2VydE51bGwoVXJsVXRpbHMuZ2V0U2NoZW1lUHJlZml4KCI6IikpOworICAgICAgICBhc3NlcnROdWxsKFVybFV0aWxzLmdldFNjaGVtZVByZWZpeCgiKzoiKSk7CisgICAgICAgIGFzc2VydE51bGwoVXJsVXRpbHMuZ2V0U2NoZW1lUHJlZml4KCItOiIpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChVcmxVdGlscy5nZXRTY2hlbWVQcmVmaXgoIi46IikpOworICAgICAgICBhc3NlcnROdWxsKFVybFV0aWxzLmdldFNjaGVtZVByZWZpeCgiMDoiKSk7CisgICAgICAgIGFzc2VydE51bGwoVXJsVXRpbHMuZ2V0U2NoZW1lUHJlZml4KCI1OiIpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChVcmxVdGlscy5nZXRTY2hlbWVQcmVmaXgoIjk6IikpOworICAgICAgICBhc3NlcnROdWxsKFVybFV0aWxzLmdldFNjaGVtZVByZWZpeCgiaHR0cC8vIikpOworICAgICAgICBhc3NlcnROdWxsKFVybFV0aWxzLmdldFNjaGVtZVByZWZpeCgiaHR0cC86IikpOworICAgICAgICBhc3NlcnROdWxsKFVybFV0aWxzLmdldFNjaGVtZVByZWZpeCgiaHQgdHA6Ly8iKSk7CisgICAgICAgIGFzc2VydE51bGwoVXJsVXRpbHMuZ2V0U2NoZW1lUHJlZml4KCIgaHR0cDovLyIpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChVcmxVdGlscy5nZXRTY2hlbWVQcmVmaXgoImh0dHAgOi8vIikpOworICAgICAgICBhc3NlcnROdWxsKFVybFV0aWxzLmdldFNjaGVtZVByZWZpeCgiOjovLyIpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9zcWxpdGUvQWJzdHJhY3RTcWxUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS9zcWxpdGUvQWJzdHJhY3RTcWxUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDE5NDU0OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9BYnN0cmFjdFNxbFRlc3QuamF2YQpAQCAtMCwwICsxLDIxMyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5zcWxpdGU7CisKK2ltcG9ydCBTUUxpdGUuRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc3FsLkNvbm5lY3Rpb247CitpbXBvcnQgamF2YS5zcWwuRHJpdmVyTWFuYWdlcjsKK2ltcG9ydCBqYXZhLnNxbC5SZXN1bHRTZXQ7CitpbXBvcnQgamF2YS5zcWwuU1FMRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc3FsLlN0YXRlbWVudDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKworLyoqCisgKiBUaGlzIGNsYXNzIHByb3ZpZGVzIFNRTCB1bml0IHRlc3QsIHdoaWNoIGNhbiBiZSB1c2VkIGJ5IHN1YmNsYXNzZXMgZWcuIHRvCisgKiB0ZXN0IEpEQkMgZHJpdmVycy4KKyAqLworYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RTcWxUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogVGhlIGZpcnN0IGNvbm5lY3Rpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBDb25uZWN0aW9uIGZpcnN0Q29ubmVjdGlvbjsKKworICAgIC8qKgorICAgICAqIFRoZSBzZWNvbmQgY29ubmVjdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIENvbm5lY3Rpb24gc2Vjb25kQ29ubmVjdGlvbjsKKworICAgIC8qKgorICAgICAqIFRoZSBzdGF0ZW1lbnQgZnJvbSB0aGUgZmlyc3QgY29ubmVjdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0YXRlbWVudCBmaXJzdFN0bXQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3RhdGVtZW50IGZyb20gdGhlIHNlY29uZCBjb25uZWN0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgU3RhdGVtZW50IHNlY29uZFN0bXQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgdmFsdWVzIG9mIHRoZSBmaXJzdCBjb2x1bW4gIm9uZSIuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmdbXSBvbmVzID0geyJoZWxsbyEiLCAiZ29vZGJ5ZSJ9OworCisgICAgLyoqCisgICAgICogVGhlIHZhbHVlcyBvZiB0aGUgc2Vjb25kIGNvbHVtbiAidHdvIi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIHNob3J0W10gdHdvcyA9IHsxMCwgMjB9OworCisgICAgLyoqCisgICAgICogVGhlIHVwZGF0ZWQgdmFsdWVzIG9mIHRoZSBmaXJzdCBjb2x1bW4gIm9uZSIuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmdbXSBvbmVzX3VwZGF0ZWQ7CisKKyAgICAvKiogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzICovCisgICAgcHVibGljIEFic3RyYWN0U3FsVGVzdCgpIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgb25lc191cGRhdGVkID0gbmV3IFN0cmluZ1tvbmVzLmxlbmd0aF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb25lcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgb25lc191cGRhdGVkW2ldID0gb25lc1tpXSArIHR3b3NbaV07CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIGEgdW5pdCB0ZXN0LCBieSBjcmVhdGluZyB0d28gc3RhdGVtZW50cyBmcm9tIHR3byBjb25uZWN0aW9ucyBhbmQKKyAgICAgKiBjcmVhdGluZyBhIHRlc3QgdGFibGUuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIFNRTEV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZQorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICogQGV4Y2VwdGlvbiBFeGNlcHRpb24gbWF5IGJlIHRocm93biBieSBzdWJjbGFzc2VzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbiB7CisgICAgICAgIENsYXNzLmZvck5hbWUoZ2V0RHJpdmVyQ2xhc3NOYW1lKCkpLm5ld0luc3RhbmNlKCk7CisgICAgICAgIGZpcnN0Q29ubmVjdGlvbiA9IERyaXZlck1hbmFnZXIuZ2V0Q29ubmVjdGlvbihnZXRDb25uZWN0aW9uVVJMKCkpOworICAgICAgICBmaXJzdENvbm5lY3Rpb24uc2V0VHJhbnNhY3Rpb25Jc29sYXRpb24oZ2V0VHJhbnNhY3Rpb25Jc29sYXRpb24oKSk7CisgICAgICAgIHNlY29uZENvbm5lY3Rpb24gPSBEcml2ZXJNYW5hZ2VyLmdldENvbm5lY3Rpb24oZ2V0Q29ubmVjdGlvblVSTCgpKTsKKyAgICAgICAgc2Vjb25kQ29ubmVjdGlvbi5zZXRUcmFuc2FjdGlvbklzb2xhdGlvbihnZXRUcmFuc2FjdGlvbklzb2xhdGlvbigpKTsKKyAgICAgICAgZmlyc3RTdG10ID0gZmlyc3RDb25uZWN0aW9uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICBmaXJzdFN0bXQuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRibDEob25lIHZhcmNoYXIoMTApLCB0d28gc21hbGxpbnQpIik7CisgICAgICAgIHNlY29uZFN0bXQgPSBzZWNvbmRDb25uZWN0aW9uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gYSB1bml0IHRlc3QsIGJ5IHNldHRpbmcgdGhlIGF1dG8gY29tbWl0IHByb3BlcnR5IG9mIHRoZSBmaXJzdAorICAgICAqIGNvbm5lY3Rpb24gYmFjayB0byB0cnVlLCBkcm9wcGluZyB0aGUgdGVzdCB0YWJsZSBhbmQgY2xvc2luZyB0aGUgdHdvCisgICAgICogY29ubmVjdGlvbnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgZmlyc3RTdG10LmNsb3NlKCk7CisgICAgICAgIHNlY29uZFN0bXQuY2xvc2UoKTsKKyAgICAgICAgZmlyc3RDb25uZWN0aW9uLnNldEF1dG9Db21taXQodHJ1ZSk7CisgICAgICAgIGZpcnN0U3RtdCA9IGZpcnN0Q29ubmVjdGlvbi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgZmlyc3RTdG10LmV4ZWN1dGUoImRyb3AgdGFibGUgdGJsMSIpOworICAgICAgICBmaXJzdFN0bXQuY2xvc2UoKTsKKyAgICAgICAgZmlyc3RDb25uZWN0aW9uLmNsb3NlKCk7CisgICAgICAgIHNlY29uZENvbm5lY3Rpb24uY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHNvbWUgcm93cyB0byB0aGUgdGVzdCB0YWJsZSBhbmQgYXNzZXJ0cyB0aGF0IHRoZSByb3dzIGNhbiBiZQorICAgICAqIHJldHJpZXZlZCBhZ2Fpbi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGF1dG9Db21taXRJbnNlcnRTZWxlY3QoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgZmlyc3RTdG10LmdldENvbm5lY3Rpb24oKS5zZXRBdXRvQ29tbWl0KHRydWUpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9uZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGZpcnN0U3RtdC5leGVjdXRlKCJpbnNlcnQgaW50byB0YmwxIHZhbHVlcygnIiArIG9uZXNbaV0gKyAiJywiCisgICAgICAgICAgICAgICAgICAgICsgdHdvc1tpXSArICIpIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0QWxsRnJvbVRibDEoZmlyc3RTdG10LCBvbmVzLCB0d29zKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBc3NlcnRzIHRoYXQgdGhlIGV4cGVjdGVkIHZhbHVlcyBjYW4gYmUgc2VsZWN0ZWQgZnJvbSB0aGUgdGVzdCB0YWJsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdG10IHRoZSBzdGF0ZW1lbnQgdG8gYmUgdXNlZCBmb3IgdGhlIHNlbGVjdGlvbiBvZiB0aGUgZGF0YQorICAgICAqIEBwYXJhbSBvbmVzIHRoZSBleHBlY3RlZCB2YWx1ZXMgb2YgdGhlIGNvbHVtbiAnb25lJworICAgICAqIEBwYXJhbSB0d29zIHRoZSBleHBlY3RlZCB2YWx1ZXMgb2YgdGhlIGNvbHVtbiAndHdvJworICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydEFsbEZyb21UYmwxKFN0YXRlbWVudCBzdG10LCBTdHJpbmdbXSBvbmVzLCBzaG9ydFtdIHR3b3MpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgUmVzdWx0U2V0IHJzID0gc3RtdC5leGVjdXRlUXVlcnkoInNlbGVjdCAqIGZyb20gdGJsMSIpOworICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgIGZvciAoOyBycy5uZXh0KCk7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShpIDwgb25lcy5sZW5ndGgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG9uZXNbaV0sIHJzLmdldFN0cmluZygib25lIikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHR3b3NbaV0sIHJzLmdldFNob3J0KCJ0d28iKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZShpID09IG9uZXMubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXV0b0NvbW1pdEluc2VydFNlbGVjdCgpIHRocm93cyBTUUxFeGNlcHRpb257CisgICAgICAgIGF1dG9Db21taXRJbnNlcnRTZWxlY3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB0aGUgZm9sbG93aW5nIHNlcXVlbmNlIGFmdGVyIHN1Y2Nlc3NmdWwgaW5zZXJ0aW9uIG9mIHNvbWUgdGVzdAorICAgICAqIGRhdGE6CisgICAgICogLSB1cGRhdGUgZGF0YSBmcm9tIGNvbm5lY3Rpb24gb25lCisgICAgICogLSBzZWxlY3QgZGF0YSBmcm9tIGNvbm5lY3Rpb24gdHdvICgtPiBzaG91bGQgaGF2ZSB0aGUgb2xkIHZhbHVlcykKKyAgICAgKiAtIGNvbW1pdCBkYXRhIGZyb20gY29ubmVjdGlvbiBvbmUKKyAgICAgKiAtIHNlbGVjdCBkYXRhIGZyb20gY29ubmVjdGlvbiB0d28gKC0+IHNob3VsZCBoYXZlIHRoZSBuZXcgdmFsdWVzKQorICAgICAqCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBwcm9ibGVtIGFjY2Vzc2luZyB0aGUgZGF0YWJhc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXBkYXRlU2VsZWN0Q29tbWl0U2VsZWN0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGF1dG9Db21taXRJbnNlcnRTZWxlY3QoKTsKKyAgICAgICAgZmlyc3RTdG10LmdldENvbm5lY3Rpb24oKS5zZXRBdXRvQ29tbWl0KGZhbHNlKTsKKyAgICAgICAgdXBkYXRlT25lcyhmaXJzdFN0bXQsIG9uZXNfdXBkYXRlZCwgdHdvcyk7CisgICAgICAgIGFzc2VydEFsbEZyb21UYmwxKHNlY29uZFN0bXQsIG9uZXMsIHR3b3MpOworICAgICAgICBmaXJzdFN0bXQuZ2V0Q29ubmVjdGlvbigpLmNvbW1pdCgpOworICAgICAgICBhc3NlcnRBbGxGcm9tVGJsMShzZWNvbmRTdG10LCBvbmVzX3VwZGF0ZWQsIHR3b3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHRoZSBmb2xsb3dpbmcgc2VxdWVuY2UgYWZ0ZXIgc3VjY2Vzc2Z1bCBpbnNlcnRpb24gb2Ygc29tZSB0ZXN0CisgICAgICogZGF0YToKKyAgICAgKiAtIHVwZGF0ZSBkYXRhIGZyb20gY29ubmVjdGlvbiBvbmUKKyAgICAgKiAtIHNlbGVjdCBkYXRhIGZyb20gY29ubmVjdGlvbiB0d28gKC0+IHNob3VsZCBoYXZlIHRoZSBvbGQgdmFsdWVzKQorICAgICAqIC0gcm9sbGJhY2sgZGF0YSBmcm9tIGNvbm5lY3Rpb24gb25lCisgICAgICogLSBzZWxlY3QgZGF0YSBmcm9tIGNvbm5lY3Rpb24gdHdvICgtPiBzaG91bGQgc3RpbGwgaGF2ZSB0aGUgb2xkIHZhbHVlcykKKyAgICAgKgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBhY2Nlc3NpbmcgdGhlIGRhdGFiYXNlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVwZGF0ZVNlbGVjdFJvbGxiYWNrU2VsZWN0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGF1dG9Db21taXRJbnNlcnRTZWxlY3QoKTsKKyAgICAgICAgZmlyc3RTdG10LmdldENvbm5lY3Rpb24oKS5zZXRBdXRvQ29tbWl0KGZhbHNlKTsKKyAgICAgICAgdXBkYXRlT25lcyhmaXJzdFN0bXQsIG9uZXNfdXBkYXRlZCwgdHdvcyk7CisgICAgICAgIGFzc2VydEFsbEZyb21UYmwxKHNlY29uZFN0bXQsIG9uZXMsIHR3b3MpOworICAgICAgICBmaXJzdFN0bXQuZ2V0Q29ubmVjdGlvbigpLnJvbGxiYWNrKCk7CisgICAgICAgIGFzc2VydEFsbEZyb21UYmwxKHNlY29uZFN0bXQsIG9uZXMsIHR3b3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgdGhlIHZhbHVlcyBpbiBjb2x1bW4gJ29uZScKKyAgICAgKiBAcGFyYW0gc3RtdCB0aGUgc3RhdGVtZW50IHRvIGJlIHVzZWQgdG8gdXBkYXRlIHRoZSBkYXRhCisgICAgICogQHBhcmFtIG9uZXNfdXBkYXRlZCB0aGUgdXBkYXRlZCB2YWx1cyBvZiBjb2x1bW4gJ29uZScKKyAgICAgKiBAcGFyYW0gdHdvcyB0aGUgcmVmZXJlbmNlIHZhbHVlcyBvZiBjb2x1bW4gJ3R3bycKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHByb2JsZW0gYWNjZXNzaW5nIHRoZSBkYXRhYmFzZQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB1cGRhdGVPbmVzKFN0YXRlbWVudCBzdG10LCBTdHJpbmdbXSBvbmVzX3VwZGF0ZWQsIHNob3J0W10gdHdvcykKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9uZXNfdXBkYXRlZC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc3RtdC5leGVjdXRlKCJVUERBVEUgdGJsMSBTRVQgb25lID0gJyIgKyBvbmVzX3VwZGF0ZWRbaV0KKyAgICAgICAgICAgICAgICAgICAgKyAiJyBXSEVSRSB0d28gPSAiICsgdHdvc1tpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgU3RyaW5nIGdldENvbm5lY3Rpb25VUkwoKTsKKworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBTdHJpbmcgZ2V0RHJpdmVyQ2xhc3NOYW1lKCk7CisKKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW50IGdldFRyYW5zYWN0aW9uSXNvbGF0aW9uKCk7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGRCbG9iVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvc3FsaXRlL09sZEJsb2JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzI4OWQzOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGRCbG9iVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTM1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLnNxbGl0ZTsKKworaW1wb3J0IFNRTGl0ZS5CbG9iOworaW1wb3J0IFNRTGl0ZS5EYXRhYmFzZTsKK2ltcG9ydCBTUUxpdGUuRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfU1FMOworCitwdWJsaWMgZmluYWwgY2xhc3MgT2xkQmxvYlRlc3QgZXh0ZW5kcyBPbGRTUUxpdGVUZXN0IHsKKworICAgIHByaXZhdGUgc3RhdGljIEJsb2IgdGVzdEJsb2IgPSBudWxsOworCisgICAgcHJpdmF0ZSBzdGF0aWMgRGF0YWJhc2UgZGIgPSBudWxsOworCisgICAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRlc3RCbG9iID0gbmV3IEJsb2IoKTsKKworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBTdXBwb3J0X1NRTC5sb2FkRHJpdmVyKCk7CisgICAgICAgIGRiID0gbmV3IERhdGFiYXNlKCk7CisgICAgICAgIGRiLm9wZW4oZGJGaWxlLmdldFBhdGgoKSwgMCk7CisKKyAgICAgICAgZGIuZXhlYygiY3JlYXRlIHRhYmxlIEIoaWQgaW50ZWdlciBwcmltYXJ5IGtleSwgdmFsIGJsb2IpIixudWxsKTsKKyAgICAgICAgZGIuZXhlYygiaW5zZXJ0IGludG8gQiB2YWx1ZXMoMSwgemVyb2Jsb2IoMTI4KSkiLCBudWxsKTsKKyAgICAgICAgZGIuZXhlYygiaW5zZXJ0IGludG8gQiB2YWx1ZXMoMiwgemVyb2Jsb2IoMTI4KSkiLCBudWxsKTsKKyAgICAgICAgZGIuZXhlYygiaW5zZXJ0IGludG8gQiB2YWx1ZXMoMywgemVyb2Jsb2IoMTI4KSkiLCBudWxsKTsKKworICAgICAgICAvLyBjYW4gbm90IGZpbGwgQmxvYiB3aXRoIGRhdGEgYXQgdGhpcyBwb2ludC4uLgorICAgICAgICAvKgorICAgICAgICBGaWxlIHJlc291cmNlcyA9IFN1cHBvcnRfUmVzb3VyY2VzLmNyZWF0ZVRlbXBGb2xkZXIoKTsKKyAgICAgICAgQnVmZmVyZWRSZWFkZXIgciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDbGFzcyBjID0gQ2xhc3MuZm9yTmFtZSh0aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoYyk7CisgICAgICAgICAgICBmaWxlID0gQ2xhc3MuZm9yTmFtZSh0aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpKQorICAgICAgICAgICAgICAgICAgICAuZ2V0UmVzb3VyY2VBc1N0cmVhbSgiL2Jsb2IuYyIpOworICAgICAgICAgICAgciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoZmlsZSkpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgbm90IHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIHJlYWRpbmcgZmlsZSIKKyAgICAgICAgICAgICAgICAgICAgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgT3V0cHV0U3RyZWFtIG91dCA9IHRlc3RCbG9iLmdldE91dHB1dFN0cmVhbSgpOworICAgICAgICBTdHJpbmcgcyA9IG51bGw7CisgICAgICAgIHdoaWxlICgocyA9IHIucmVhZExpbmUoKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgb3V0LndyaXRlKHIucmVhZExpbmUoKS5nZXRCeXRlcygpKTsKKyAgICAgICAgfQorICAgICAgICBvdXQuZmx1c2goKTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgIHRlc3RCbG9iLmNsb3NlKCk7CisgICAgICAgICovCisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIGphdmEubGFuZy5FeGNlcHRpb24geworICAgICAgICB0ZXN0QmxvYi5jbG9zZSgpOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGRiLm9wZW5fYmxvYiBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RCbG9iKCkgdGhyb3dzIEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gYiA9IG5ldyBieXRlWzRdOworICAgICAgICBieXRlW10gYjEyOCA9IG5ldyBieXRlWzEyOF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYjEyOC5sZW5ndGg7IGkrKykgeworICAgICAgICBiMTI4W2ldID0gKGJ5dGUpIGk7CisgICAgICAgIH0KKyAgICAgICAgQmxvYiBibG9iID0gZGIub3Blbl9ibG9iKGRiRmlsZS5nZXRQYXRoKCksICJCIiwgInZhbCIsIDEsIHRydWUpOworICAgICAgICB0cnkgeworCisgICAgICAgIE91dHB1dFN0cmVhbSBvcyA9IGJsb2IuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIG9zLndyaXRlKGIxMjgpOworICAgICAgICBvcy5jbG9zZSgpOworCisgICAgICAgIElucHV0U3RyZWFtIGlzID0gYmxvYi5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICBpcy5za2lwKDk2KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsaXMucmVhZChiKSk7CisgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgIGJsb2IuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnB1dFN0cmVhbSgpIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSB0ZXN0QmxvYi5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW4ucmVhZCgpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIG5vdCB0aHJvd24gZm9yIGludmFsaWQgQmxvYi4iKTsKKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRPdXRwdXRTdHJlYW0oKSB7CisgICAgICAgIE91dHB1dFN0cmVhbSBvdXQgPSB0ZXN0QmxvYi5nZXRPdXRwdXRTdHJlYW0oKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICBvdXQud3JpdGUobnVsbCk7CisgICAgICAgICAgIGZhaWwoIldyaXRlIG9wZXJhdGlvbiB1bnN1cHBvcnRlZCIpOworICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcml0ZSBvcGVyYXRpb24gdW5zdXBwb3J0ZWQiLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvc2UoKSB7CisgICAgICAgIGFzc2VydE5vdE51bGwodGVzdEJsb2IpOworCisgICAgICAgIHRlc3RCbG9iLmNsb3NlKCk7CisgICAgICAgIC8vIGlucHV0U3RyZWFtIGVpdGhlciBudWxsIG9yIHNvbWUgZXJyb3Igb2NjdXJzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBUT0RPIFRoaXMgZG9lcyBsb29rIGEgYml0IHdlaXJkLiBSZXZpc2l0IGxhdGVyLgorICAgICAgICAgICAgYXNzZXJ0TnVsbCh0ZXN0QmxvYi5nZXRJbnB1dFN0cmVhbSgpKTsKKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGREYXRhYmFzZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGREYXRhYmFzZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMmNiYzU3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvc3FsaXRlL09sZERhdGFiYXNlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTIyNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5zcWxpdGU7CisKK2ltcG9ydCBTUUxpdGUuQXV0aG9yaXplcjsKK2ltcG9ydCBTUUxpdGUuQmxvYjsKK2ltcG9ydCBTUUxpdGUuQnVzeUhhbmRsZXI7CitpbXBvcnQgU1FMaXRlLkNhbGxiYWNrOworaW1wb3J0IFNRTGl0ZS5Db25zdGFudHM7CitpbXBvcnQgU1FMaXRlLkRhdGFiYXNlOworaW1wb3J0IFNRTGl0ZS5FeGNlcHRpb247CitpbXBvcnQgU1FMaXRlLkZ1bmN0aW9uOworaW1wb3J0IFNRTGl0ZS5GdW5jdGlvbkNvbnRleHQ7CitpbXBvcnQgU1FMaXRlLlByb2dyZXNzSGFuZGxlcjsKK2ltcG9ydCBTUUxpdGUuU3RtdDsKK2ltcG9ydCBTUUxpdGUuVGFibGVSZXN1bHQ7CitpbXBvcnQgU1FMaXRlLlRyYWNlOworaW1wb3J0IFNRTGl0ZS5WbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGE7CitpbXBvcnQgamF2YS5zcWwuUmVzdWx0U2V0OworaW1wb3J0IGphdmEuc3FsLlNRTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5TdGF0ZW1lbnQ7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ2dlcjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LkRhdGFiYXNlQ3JlYXRvcjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0Lk1vY2tGdW5jdGlvbjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlRocmVhZFBvb2w7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBPbGREYXRhYmFzZVRlc3QgZXh0ZW5kcyBPbGRTUUxpdGVUZXN0IHsKKworICAgIHByaXZhdGUgc3RhdGljIEVycm9yVHJhY2tlciB0cmFja2VyID0gbnVsbDsKKworICAgIHByaXZhdGUgU3RhdGVtZW50IHN0YXRlbWVudDsKKworICAgIHByaXZhdGUgRGF0YWJhc2UgZGIgPSBudWxsOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IG51bVRocmVhZHMgPSAxMDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBudW1PZlJlY29yZHMgPSAzMDsKKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ291bGQgbm90IGVzdGFibGlzaCBEQiBjb25uZWN0aW9uIixjb25uKTsKKyAgICAgICAgdHJhY2tlciA9IG5ldyBFcnJvclRyYWNrZXIoKTsKKworICAgICAgICBzdGF0ZW1lbnQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworCisgICAgICAgIC8vIENsZWFudXAgdGFibGVzIGlmIG5lY2Vzc2FyeQorCisgICAgICAgIERhdGFiYXNlTWV0YURhdGEgbWV0YSA9IGNvbm4uZ2V0TWV0YURhdGEoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChtZXRhKTsKKyAgICAgICAgUmVzdWx0U2V0IHVzZXJUYWIgPSBtZXRhLmdldFRhYmxlcyhudWxsLCBudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgd2hpbGUgKHVzZXJUYWIubmV4dCgpKSB7CisgICAgICAgICAgICBTdHJpbmcgdGFibGVOYW1lID0gdXNlclRhYi5nZXRTdHJpbmcoIlRBQkxFX05BTUUiKTsKKyAgICAgICAgICAgIHRoaXMuc3RhdGVtZW50LmV4ZWN1dGUoImRyb3AgdGFibGUgIiArIHRhYmxlTmFtZSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBDcmVhdGUgZGVmYXVsdCB0ZXN0IHRhYmxlCisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEVfU0lNUExFMSk7CisgICAgICAgIHN0YXRlbWVudC5jbG9zZSgpOworCisgICAgICAgIGRiID0gbmV3IERhdGFiYXNlKCk7CisgICAgICAgIGRiLm9wZW4oZGJGaWxlLmdldFBhdGgoKSwgMCk7CisgICAgICAgIGRiLmJ1c3lfaGFuZGxlcihudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRiLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAoIShlLmdldE1lc3NhZ2UoKS5lcXVhbHMoImRhdGFiYXNlIGFscmVhZHkgY2xvc2VkIikpKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJFcnJvciBjbG9zaW5nIERCICIgKyBkYkZpbGUuZ2V0UGF0aCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0cmFja2VyLnJlc2V0KCk7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERhdGFiYXNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIGRiIGNsb3NlZAorICAgICAgICBEYXRhYmFzZSBkYjIgPSBuZXcgRGF0YWJhc2UoKTsKKyAgICAgICAgZGIuY2xvc2UoKTsKKyAgICAgICAgZGIyID0gbmV3IERhdGFiYXNlKCk7CisgICAgICAgIGRiMi5vcGVuKGRiRmlsZS5nZXRQYXRoKCksIDApOworICAgICAgICBkYjIuY2xvc2UoKTsKKyAgICAgICAgZGIub3BlbihkYkZpbGUuZ2V0UGF0aCgpLCAwKTsKKyAgICAgICAgLy9kYiBpcyBvcGVuCisgICAgICAgIGRiMi5vcGVuKGRiRmlsZS5nZXRQYXRoKCksIDApOworICAgICAgICBkYjIuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T3BlbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkYi5jbG9zZSgpOworICAgICAgICBkYi5vcGVuKGRiRmlsZS5nZXRQYXRoKCksIDApOworICAgICAgICAvLyBvcGVuIHNlY29uZCBkYiB3aGlsZSBkYjEgc3RpbGwgb3BlbgorICAgICAgICBEYXRhYmFzZSBkYjIgPSBuZXcgRGF0YWJhc2UoKTsKKyAgICAgICAgZGIyLm9wZW4oZGJGaWxlLmdldFBhdGgoKSwgMCk7CisgICAgICAgIGRiMi5vcGVuKGRiRmlsZS5nZXRQYXRoKCksIDApOworICAgICAgICBkYjIuY2xvc2UoKTsKKyAgICAgICAgLy8gb3BlbiBub24gZGIgZmlsZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgVVJMIGZpbGUgPSBPbGREYXRhYmFzZVRlc3QuY2xhc3MuZ2V0UmVzb3VyY2UoIi9ibG9iLmMiKTsKKyAgICAgICAgICAgIGRiMi5vcGVuKGZpbGUuZ2V0UGF0aCgpLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCBub3QgYmUgYWJsZSB0byBvcGVuIG5vbiBkYiBmaWxlIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTGl0ZS5FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1bmtub3duIGVycm9yIGluIG9wZW4iLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T3Blbl9hdXhfZmlsZSgpIHsKKyAgICAgICAgRmlsZSB0ZW1wID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRiLm9wZW5fYXV4X2ZpbGUoIiIpOworICAgICAgICAgICAgZmFpbCgib3BlbiBzaG91bGQgZmFpbCIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1bnN1cHBvcnRlZCIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgIC8qCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZW1wID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgib3BlbkF1eE1ldGhvZCIsICIuZGIiKTsKKyAgICAgICAgICAgIGRiLm9wZW5fYXV4X2ZpbGUoIiIpOworICAgICAgICAgICAgZGIuZXhlYygiY3JlYXRlIHRhYmxlIEFVWF9UQUJMRSIsIG51bGwpOworICAgICAgICAgICAgZGIuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRlbXAuZGVsZXRlKCk7CisgICAgICAgICAgICBmYWlsKCJFcnJvciBoYW5kbGluZyB0ZW1wb3JhcnkgZmlsZSAiK2UuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRlbXAuZGVsZXRlKCk7CisgICAgICAgICAgICBmYWlsKCJDb3VsZCBub3QgY3JlYXRlIHRlbXBvcmFyeSBGaWxlIik7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkYi5vcGVuKGRiRmlsZS5nZXRQYXRoKCksMCk7CisgICAgICAgICAgICBkYi5leGVjKCJzZWxlY3QgKiBmcm9tIEFVWF9UQUJMRSIsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiU3RhdGVtZW50IHNob3VsZCBmYWlsIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIGNhdGNoIGJsb2NrCisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisKKyAgICAgICAgdGVtcC5kZWxldGUoKTsKKyAgICAgICAgKi8KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRiLmNsb3NlKCk7CisgICAgICAgICAgICBkYi5nZXRfdGFibGUoInRlc3QiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZS5nZXRNZXNzYWdlKCkuZXF1YWxzKCJkYXRhYmFzZSBhbHJlYWR5IGNsb3NlZCIpKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZGIub3BlbihkYkZpbGUuZ2V0UGF0aCgpLCAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlMSkgeworICAgICAgICAgICAgICAgIGZhaWwoIkRhdGFiYXNlIG9iamVjdCBjb3VsZCBub3QgYmUgcmVvcGVuZWQgYWZ0ZXIgJ2Nsb3NlJzogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICAgICAgZTEucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIuY2xvc2UoKTsKKyAgICAgICAgICAgIGRiLmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGUuZ2V0TWVzc2FnZSgpLmVxdWFscygiZGF0YWJhc2UgYWxyZWFkeSBjbG9zZWQiKSk7CisgICAgICAgICAgICBkYi5vcGVuKGRiRmlsZS5nZXRQYXRoKCksIDApOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEV4ZWNTdHJpbmdDYWxsYmFjaygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUYWJsZVJlc3VsdCByZXMgPSBuZXcgVGFibGVSZXN1bHQoKTsKKyAgICAgICAgZGIuZXhlYygiaW5zZXJ0IGludG8gIiArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxCisgICAgICAgICAgICAgICAgKyAiIFZBTFVFUygxLCAxMCwgMjApIiwgbnVsbCk7CisgICAgICAgIGRiLmV4ZWMoInNlbGVjdCAqIGZyb20gIiArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxLCByZXMpOworICAgICAgICBkYi5leGVjKCJkZWxldGUgZnJvbSAiICsgRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTEgKyAiIHdoZXJlIDEiLCBudWxsKTsKKyAgICAgICAgU3RyaW5nIHJvd1tdID0gKFN0cmluZ1tdKSByZXMucm93cy5lbGVtZW50QXQoMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLnBhcnNlSW50KHJvd1swXSksIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoSW50ZWdlci5wYXJzZUludChyb3dbMV0pLCAxMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLnBhcnNlSW50KHJvd1syXSksIDIwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXhlY1N0cmluZ0NhbGxiYWNrU3RyaW5nQXJyYXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGFibGVSZXN1bHQgcmVzID0gbmV3IFRhYmxlUmVzdWx0KCk7CisgICAgICAgIFN0cmluZyBhcmdzW10gPSBuZXcgU3RyaW5nWzFdOworICAgICAgICBhcmdzWzBdID0gInRhYmxlIjsKKyAgICAgICAgZGIuZXhlYygic2VsZWN0IG5hbWUgZnJvbSBzcWxpdGVfbWFzdGVyIHdoZXJlIHR5cGUgPSAnJXEnOyIsIHJlcywgYXJncyk7CisgICAgICAgIFN0cmluZ1tdIHMgPSAoU3RyaW5nW10pIHJlcy5yb3dzLmVsZW1lbnRBdCgwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNbMF0sIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIuZXhlYygic2VsZWN0IG5hbWUgZnJvbSBzcWxpdGVfbWFzdGVyIHdoZXJlIHR5cGUgPSAiLCByZXMsIGFyZ3MpOworICAgICAgICAgICAgZmFpbCgiVGVzdG1ldGhvZCBzaG91bGQgZmFpbCIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gT2sKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RMYXN0X2luc2VydF9yb3dpZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZGIubGFzdF9pbnNlcnRfcm93aWQoKSk7CisgICAgICAgIGRiLmV4ZWMoImNyZWF0ZSB0YWJsZSBURVNUNShpZCBpbnRlZ2VyLCBmaXJzdG5hbWUgdGV4dCwgbGFzdG5hbWUgdGV4dCk7IiwgbnVsbCk7CisgICAgICAgIGRiLmV4ZWMoImluc2VydCBpbnRvIFRFU1Q1IHZhbHVlcyAoMSwnSmFtZXMnLCdCb25kJyk7IiwgbnVsbCk7CisgICAgICAgIGRiLmV4ZWMoImluc2VydCBpbnRvIFRFU1Q1IHZhbHVlcyAoMiwnRmlvbmEnLCdBcHBsZScpOyIsIG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgZGIubGFzdF9pbnNlcnRfcm93aWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhkYi5sYXN0X2luc2VydF9yb3dpZCgpLCBkYi5sYXN0X2luc2VydF9yb3dpZCgpKTsKKworICAgICAgICBkYi5leGVjKCJkcm9wIHRhYmxlIFRFU1Q1OyIsIG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgZGIubGFzdF9pbnNlcnRfcm93aWQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhc29uIGZvciBmYWlsdXJlIHVua25vd246IERhdGFiYXNlIHNob3VsZCBiZSBsb2NrZWQuIFNwZWNpZmljYXRpb24KKyAgICAgKiBvZiBpbnRlcnJ1cHQgaXMgc2NhcmNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnRlcnJ1cHQoKSB0aHJvd3MgRXhjZXB0aW9uLCBTUUxFeGNlcHRpb24geworICAgICAgICBUaHJlYWRQb29sIHRocmVhZFBvb2wgPSBuZXcgVGhyZWFkUG9vbChudW1UaHJlYWRzKTsKKworICAgICAgICAvLyBpbml0aWFsaXphdGlvbgorICAgICAgICBSZXN1bHRTZXQgdXNlclRhYnM7CisgICAgICAgIHVzZXJUYWJzID0gY29ubi5nZXRNZXRhRGF0YSgpLmdldFRhYmxlcyhudWxsLCBudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgd2hpbGUgKHVzZXJUYWJzLm5leHQoKSkgeworICAgICAgICAgICAgU3RyaW5nIHRhYmxlTmFtZSA9IHVzZXJUYWJzLmdldFN0cmluZygiVEFCTEVfTkFNRSIpOworICAgICAgICAgICAgaWYgKHRhYmxlTmFtZS5lcXVhbHMoRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxKSkgeworICAgICAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFMSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZGIuZXhlYyhEYXRhYmFzZUNyZWF0b3IuQ1JFQVRFX1RBQkxFMywgbnVsbCk7CisgICAgICAgIGRiLmV4ZWMoRGF0YWJhc2VDcmVhdG9yLkNSRUFURV9UQUJMRTEsIG51bGwpOworCisgICAgICAgIGludCBpZDEgPSBudW1PZlJlY29yZHMgLSAzOworICAgICAgICB0aHJlYWRQb29sLnJ1blRhc2soY3JlYXRlVGFzazEoaWQxLCBkYkZpbGUuZ2V0UGF0aCgpLCB0cmFja2VyKSk7CisgICAgICAgIC8vIHNob3VsZCBub3QgYmUgYWJsZSB0byBkbyBhbnkgb3RoZXIgaW5zZXJ0aW9ucyBzaW5jZSB0YXNrIDEgaG9sZHMgbG9jaworICAgICAgICBpbnQgaWQyID0gbnVtT2ZSZWNvcmRzICsgMzsKKyAgICAgICAgdGhyZWFkUG9vbAorICAgICAgICAgICAgICAgIC5ydW5UYXNrKGNyZWF0ZVRhc2sySW50ZXJydXB0KGlkMiwgZGJGaWxlLmdldFBhdGgoKSwgdHJhY2tlcikpOworCisgICAgICAgIHRocmVhZFBvb2wuam9pbigpOworCisgICAgICAgIExpc3Q8U3RyaW5nPiBlcnJvcnMgPSB0cmFja2VyLmdldEVycm9ycygpOworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkxhc3QgZXJyb3I6ICIgKyBkYi5lcnJvcl9tZXNzYWdlKCkpOworICAgICAgICBpZiAoZXJyb3JzLnNpemUoKSA+IDApIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhlcnJvcnMuZ2V0KDApLCBkYi5lcnJvcl9zdHJpbmcoQ29uc3RhbnRzLlNRTElURV9MT0NLRUQpKTsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIHMgOiBlcnJvcnMpIHsKKyAgICAgICAgICAgICAgICBMb2dnZXIuZ2xvYmFsLmluZm8oIklOVEVSUlVQVCBFcnJvcjogIiArIHMpOworICAgICAgICAgICAgfQorCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgaGF2ZSBvbmUgZXhjZXB0aW9uOiBkYXRhYmFzZSBzaG91bGQgYmUgbG9ja2VkLiIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gcmVzZXQKKyAgICAgICAgZGIuZXhlYygiZGVsZXRlIGZyb20gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSArICIgd2hlcmUgMSIsIG51bGwpOworICAgICAgICBkYi5leGVjKCJkZWxldGUgZnJvbSAiICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUzICsgIiB3aGVyZSAxIiwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB3cm9uZyBudW1iZXIgZm9yIHVwZGF0ZXM6IHJldHVybnMgdmFsdWUgPiAxIGZvciBzZWxlY3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENoYW5nZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGFibGVSZXN1bHQgcmVzID0gbmV3IFRhYmxlUmVzdWx0KCk7CisgICAgICAgIGFzc2VydFRydWUoZGIuY2hhbmdlcygpID09IDApOworICAgICAgICBkYi5leGVjKCJJTlNFUlQgSU5UTyAiICsgRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgVkFMVUVTKDIsIDUsIDcpOyIsIG51bGwpOworICAgICAgICBpbnQgcm93cyA9IChpbnQpIGRiLmNoYW5nZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsZGIuY2hhbmdlcygpKTsKKyAgICAgICAgZGIuZXhlYygidXBkYXRlICIgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMQorICAgICAgICAgICAgICAgICsgIiBzZXQgc3BlZWQgPSA3LCBzaXplPSA1IHdoZXJlIGlkID0gMjsiLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsZGIuY2hhbmdlcygpKTsKKyAgICAgICAgZGIuZXhlYygic2VsZWN0ICogZnJvbSAiICsgRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTEsIHJlcyk7CisgICAgICAgIGFzc2VydEVxdWFscygwLGRiLmNoYW5nZXMoKSk7CisgICAgICAgIGRiLmV4ZWMoIklOU0VSVCBJTlRPICIgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMQorICAgICAgICAgICAgICAgICsgIiBWQUxVRVMoOCwgNSwgNyk7IiwgbnVsbCk7CisgICAgICAgIGRiLmV4ZWMoIlVwZGF0ZSAiK0RhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxKyIgc2V0IHNwZWVkID0gMTA7IixudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShkYi5jaGFuZ2VzKCkgPiAyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBtZXRob2QgdGVzdCBmYWlscyBvbmNlIGluIGEgd2hpbGUuIENhbm5vdCBiZSBzdXJlIHRoYXQgZXhjZXB0aW9uIGlzCisgICAgICogdGhyb3duIGluIGV2ZXJ5IHRlc3QgZXhlY3V0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RCdXN5X2hhbmRsZXIoKSB0aHJvd3MgU1FMRXhjZXB0aW9uLCBFeGNlcHRpb24geworICAgICAgICBUZXN0QnVzeUhhbmRsZXIgYmggPSBuZXcgVGVzdEJ1c3lIYW5kbGVyKCk7CisgICAgICAgIGRiLmJ1c3lfaGFuZGxlcihiaCk7CisgICAgICAgIGludCBjb3VudGVyID0gMDsKKyAgICAgICAgVGhyZWFkUG9vbCB0aHJlYWRQb29sID0gbmV3IFRocmVhZFBvb2wobnVtVGhyZWFkcyk7CisKKyAgICAgICAgLy8gaW5pdGlhbGl6YXRpb24KKyAgICAgICAgUmVzdWx0U2V0IHVzZXJUYWJzOworICAgICAgICB1c2VyVGFicyA9IGNvbm4uZ2V0TWV0YURhdGEoKS5nZXRUYWJsZXMobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgIHdoaWxlICh1c2VyVGFicy5uZXh0KCkpIHsKKyAgICAgICAgICAgIFN0cmluZyB0YWJsZU5hbWUgPSB1c2VyVGFicy5nZXRTdHJpbmcoIlRBQkxFX05BTUUiKTsKKyAgICAgICAgICAgIGlmICh0YWJsZU5hbWUuZXF1YWxzKERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSkpIHsKKyAgICAgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRTEpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGRiLmV4ZWMoRGF0YWJhc2VDcmVhdG9yLkNSRUFURV9UQUJMRTMsIG51bGwpOworICAgICAgICBkYi5leGVjKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEUxLCBudWxsKTsKKworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uLnNldEF1dG9Db21taXQoZmFsc2UpOworICAgICAgICAgICAgaW50IGlkMSA9IG51bU9mUmVjb3JkcyAtIDM7CisgICAgICAgICAgICB0aHJlYWRQb29sLnJ1blRhc2soY3JlYXRlVGFzazEoaWQxLCBkYkZpbGUuZ2V0UGF0aCgpLCB0cmFja2VyKSk7CisgICAgICAgICAgICBpbnQgaWQyID0gbnVtT2ZSZWNvcmRzICsgMzsKKyAgICAgICAgICAgIHRocmVhZFBvb2wucnVuVGFzayhjcmVhdGVUYXNrMihpZDIsIGRiRmlsZS5nZXRQYXRoKCksIHRyYWNrZXIpKTsKKyAgICAgICAgICAgIGludCBvbGRJRCA9IDU7CisgICAgICAgICAgICBpbnQgbmV3SUQgPSAxMDA7CisgICAgICAgICAgICB0aHJlYWRQb29sLnJ1blRhc2soY3JlYXRlVGFzazMob2xkSUQsIGRiRmlsZS5nZXRQYXRoKCksIG5ld0lELAorICAgICAgICAgICAgICAgICAgICB0cmFja2VyKSk7CisKKyAgICAgICAgICAgIHRocmVhZFBvb2wuam9pbigpOworCisgICAgICAgICAgICBMaXN0PFN0cmluZz4gZXJyb3JzID0gdHJhY2tlci5nZXRFcnJvcnMoKTsKKyAgICAgICAgICAgIGlmIChlcnJvcnMuc2l6ZSgpID4gMCkgeworLy8gICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhlcnJvcnMuZ2V0KDApLAorLy8gICAgICAgICAgICAgICAgIGRiLmVycm9yX3N0cmluZyhDb25zdGFudHMuU1FMSVRFX0xPQ0tFRCkpOworICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIHM6IGVycm9ycykgeworICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJSb3VuZCAyIEVycm9yOiAiK3MpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZhaWwoIk5vIGVycm9yIGhhcHBlbmVkIik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIHJlc2V0CisKKworICAgICAgICAgICAgZGIuZXhlYygiZGVsZXRlIGZyb20gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSArICIgd2hlcmUgMSIsCisgICAgICAgICAgICAgICAgICAgIG51bGwpOworICAgICAgICAgICAgZGIuZXhlYygiZGVsZXRlIGZyb20gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMyArICIgd2hlcmUgMSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7CisvLworLy8gICAgICAgICAgICAvLyBpbmNyZWFzZSB0aW1lb3V0IGZvciByZXRyeQorLy8gICAgICAgICAgICBkYi5idXN5X3RpbWVvdXQoMTAwMCk7CisvLyAgICAgICAgICAgIGRiLmJ1c3lfaGFuZGxlcihiaCk7CisvLyAgICAgICAgICAgIHRyYWNrZXIucmVzZXQoKTsKKworLy8gICAgICAgICAgICB0aHJlYWRQb29sID0gbmV3IFRocmVhZFBvb2wobnVtVGhyZWFkcyk7CisvLworLy8gICAgICAgICAgICB0aHJlYWRQb29sLnJ1blRhc2soY3JlYXRlVGFzazEoaWQxLCBkYkZpbGUuZ2V0UGF0aCgpLCB0cmFja2VyKSk7CisvLyAgICAgICAgICAgIHRocmVhZFBvb2wucnVuVGFzayhjcmVhdGVUYXNrMihpZDIsIGRiRmlsZS5nZXRQYXRoKCksIHRyYWNrZXIpKTsKKy8vCisvLyAgICAgICAgICAgIHRocmVhZFBvb2wuam9pbigpOworLy8KKy8vICAgICAgICAgICAgZXJyb3JzID0gdHJhY2tlci5nZXRFcnJvcnMoKTsKKy8vICAgICAgICAgICAgaWYgKGVycm9ycy5zaXplKCkgPiAwKSB7CisvLyAgICAgICAgICAgICAgICAvLyBhc3NlcnRFcXVhbHMoZXJyb3JzLmdldCgwKSwKKy8vICAgICAgICAgICAgICAgIC8vIGRiLmVycm9yX3N0cmluZyhDb25zdGFudHMuU1FMSVRFX0xPQ0tFRCkpOworLy8gICAgICAgICAgICAgICAgZm9yIChTdHJpbmcgczogZXJyb3JzKSB7CisvLyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJSb3VuZCAyIEVycm9yIitzKTsKKy8vICAgICAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgfSBlbHNlIHsKKy8vICAgICAgICAgICAgICAgIC8vIG9rCisvLyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkJVU1k6IE5vIEVycm9yISIpOworLy8gICAgICAgICAgICB9CisvLworLy8KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGNvbm4uc2V0QXV0b0NvbW1pdCh0cnVlKTsKKyAgICAgICAgICAgIGRiLmV4ZWMoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEUxLCBudWxsKTsKKyAgICAgICAgICAgIGRiLmV4ZWMoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEUzLCBudWxsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHRlc3QgZmFpbHMuIENhbm5vdCBiZSBzdXJlIHRoYXQgZXhjZXB0aW9uIGlzIHRocm93biBldmVyeSB0aW1lLgorICAgICAqIERhdGFiYXNlIGRvZXMgbm90IGxvY2sgdmFsdWVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RCdXN5X3RpbWVvdXQoKSB0aHJvd3MgRXhjZXB0aW9uLCBTUUxFeGNlcHRpb24geworICAgICAgICBpbnQgY291bnRlciA9IDA7CisgICAgICAgIFRocmVhZFBvb2wgdGhyZWFkUG9vbCA9IG5ldyBUaHJlYWRQb29sKG51bVRocmVhZHMpOworCisgICAgICAgIC8vIGluaXRpYWxpemF0aW9uCisgICAgICAgIFJlc3VsdFNldCB1c2VyVGFicyA9IGNvbm4uZ2V0TWV0YURhdGEoKS5nZXRUYWJsZXMobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgIHdoaWxlICh1c2VyVGFicy5uZXh0KCkpIHsKKyAgICAgICAgICAgIFN0cmluZyB0YWJsZU5hbWUgPSB1c2VyVGFicy5nZXRTdHJpbmcoIlRBQkxFX05BTUUiKTsKKyAgICAgICAgICAgIGlmICh0YWJsZU5hbWUuZXF1YWxzKERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSkpIHsKKyAgICAgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRTEpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGRiLmV4ZWMoRGF0YWJhc2VDcmVhdG9yLkNSRUFURV9UQUJMRTMsIG51bGwpOworICAgICAgICBkYi5leGVjKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEUxLCBudWxsKTsKKworICAgICAgICAvLyB0ZXN0IHJ1bgorICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubi5zZXRBdXRvQ29tbWl0KGZhbHNlKTsKKworLy8gICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuZmlsbFRlc3RUYWJsZTEoY29ubiwgbnVtT2ZSZWNvcmRzKTsKKyAgICAgICAgICAgIC8vIHNldCB0byBmYWlsIGltbWVkaWF0ZWx5IGlmIHRhYmxlIGlzIGxvY2tlZC4KKyAgICAgICAgICAgIGRiLmJ1c3lfaGFuZGxlcihudWxsKTsKKyAgICAgICAgICAgIGRiLmJ1c3lfdGltZW91dCgwKTsKKyAgICAgICAgICAgIGludCBpZDEgPSBudW1PZlJlY29yZHMgLSAzOworCisgICAgICAgICAgICB0aHJlYWRQb29sLnJ1blRhc2soY3JlYXRlVGFzazIoaWQxLCBkYkZpbGUuZ2V0UGF0aCgpLCB0cmFja2VyKSk7CisgICAgICAgICAgICBpbnQgaWQyID0gbnVtT2ZSZWNvcmRzICsgMzsKKyAgICAgICAgICAgIHRocmVhZFBvb2wucnVuVGFzayhjcmVhdGVUYXNrMShpZDIsIGRiRmlsZS5nZXRQYXRoKCksIHRyYWNrZXIpKTsKKyAgICAgICAgICAgIGludCBvbGRJRCA9IDU7CisgICAgICAgICAgICBpbnQgbmV3SUQgPSAxMDA7CisgICAgICAgICAgICB0aHJlYWRQb29sLnJ1blRhc2soY3JlYXRlVGFzazMob2xkSUQsIGRiRmlsZS5nZXRQYXRoKCksIG5ld0lELAorICAgICAgICAgICAgICAgICAgICB0cmFja2VyKSk7CisKKyAgICAgICAgICAgIHRocmVhZFBvb2wuam9pbigpOworCisgICAgICAgICAgICBMaXN0PFN0cmluZz4gZXJyb3JzID0gdHJhY2tlci5nZXRFcnJvcnMoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIk5vIGVycm9yIG9jY3VycmVkIG9uIERCIGJ1dCBzaG91bGQgaGF2ZSIsZXJyb3JzLnNpemUoKSA+IDApOworCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXJyb3JzLmdldCgwKSwKKyAgICAgICAgICAgIGRiLmVycm9yX3N0cmluZyhDb25zdGFudHMuU1FMSVRFX0xPQ0tFRCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGVycm9ycy5nZXQoMCksICJkYXRhYmFzZSBpcyBsb2NrZWQiKTsKKworICAgICAgICAgICAgLy8gcmVzZXQKKworICAgICAgICAgICAgZGIuZXhlYygiZGVsZXRlIGZyb20gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSArICIgd2hlcmUgMSIsCisgICAgICAgICAgICAgICAgICAgIG51bGwpOworICAgICAgICAgICAgZGIuZXhlYygiZGVsZXRlIGZyb20gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMyArICIgd2hlcmUgMSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7CisKKyAgICAgICAgICAgIC8vIGluY3JlYXNlIHRpbWVvdXQgZm9yIHJldHJ5CisgICAgICAgICAgICBkYi5idXN5X3RpbWVvdXQoMTAwMDApOworICAgICAgICAgICAgZGIuYnVzeV9oYW5kbGVyKG51bGwpOworICAgICAgICAgICAgdHJhY2tlci5yZXNldCgpOworICAgICAgICAgICAgdGhyZWFkUG9vbCA9IG5ldyBUaHJlYWRQb29sKG51bVRocmVhZHMpOworCisgICAgICAgICAgICB0aHJlYWRQb29sLnJ1blRhc2soY3JlYXRlVGFzazEoaWQxLCBkYkZpbGUuZ2V0UGF0aCgpLCB0cmFja2VyKSk7CisgICAgICAgICAgICB0aHJlYWRQb29sLnJ1blRhc2soY3JlYXRlVGFzazIoaWQyLCBkYkZpbGUuZ2V0UGF0aCgpLCB0cmFja2VyKSk7CisKKyAgICAgICAgICAgIHRocmVhZFBvb2wuam9pbigpOworCisgICAgICAgICAgICBlcnJvcnMgPSB0cmFja2VyLmdldEVycm9ycygpOworICAgICAgICAgICAgaWYgKGVycm9ycy5zaXplKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiYnVzeSB0aW1lb3V0IHNob3VsZCBwcmV2ZW50IGZyb20gbG9jayBleGNlcHRpb24hIik7CisgICAgICAgICAgICAgICAgZm9yIChTdHJpbmcgczogZXJyb3JzKSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUm91bmQgMiBFcnJvciIrcyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBvaworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgY29ubi5zZXRBdXRvQ29tbWl0KHRydWUpOworICAgICAgICAgICAgLy8gY2xlYW51cAorICAgICAgICAgICAgZGIuZXhlYyhEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRTEsIG51bGwpOworICAgICAgICAgICAgZGIuZXhlYyhEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRTMsIG51bGwpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldF90YWJsZVN0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUYWJsZVJlc3VsdCBlbXB0eVRhYmxlID0gbmV3IFRhYmxlUmVzdWx0KCk7CisgICAgICAgIC8vc2VsZWN0IGZyb20gZW1wdHkgdGFibGUKKyAgICAgICAgVGFibGVSZXN1bHQgcmVzID0gZGIuZ2V0X3RhYmxlKCJzZWxlY3QgKiBmcm9tICIgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhyZXMudG9TdHJpbmcoKSwgZW1wdHlUYWJsZS50b1N0cmluZygpKTsKKyAgICAgICAgLy9maWxsIHRhYmxlLT4gdAorLy8gICAgICAgIERhdGFiYXNlQ3JlYXRvci5maWxsU2ltcGxlVGFibGUxKGNvbm4pOworLy8gICAgICAgIHJlcyA9IGRiLmdldF90YWJsZSgic2VsZWN0ICogZnJvbSAiCisvLyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxKTsKKy8vICAgICAgICBhc3NlcnRGYWxzZShlbXB0eVRhYmxlLnRvU3RyaW5nKCkuZXF1YWxzKHJlcy50b1N0cmluZygpKSk7CisKKyAgICAgICAgZGIuZXhlYygiaW5zZXJ0IGludG8gIiArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxICsgIiBWQUxVRVMoMSwgMTAsIDIwKSIsIG51bGwpOworICAgICAgICByZXMgPSBkYi5nZXRfdGFibGUoInNlbGVjdCAqIGZyb20gIiArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxKTsKKyAgICAgICAgZGIuZXhlYygiZGVsZXRlIGZyb20gIiArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxCisgICAgICAgICAgICAgICAgKyAiIHdoZXJlIDEiLCBudWxsKTsKKyAgICAgICAgU3RyaW5nIHJvd1tdID0gKFN0cmluZ1tdKSByZXMucm93cy5lbGVtZW50QXQoMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLnBhcnNlSW50KHJvd1swXSksIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoSW50ZWdlci5wYXJzZUludChyb3dbMV0pLCAxMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLnBhcnNlSW50KHJvd1syXSksIDIwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0X3RhYmxlU3RyaW5nU3RyaW5nQXJyYXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGFyZ3NbXSA9IG5ldyBTdHJpbmdbMV07CisgICAgICAgIGFyZ3NbMF0gPSAidGFibGUiOworICAgICAgICBTdHJpbmcgYXJnc0ZhaWxbXSA9IG5ldyBTdHJpbmdbMV07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkYi5nZXRfdGFibGUoInNlbGVjdCBuYW1lIGZyb20gc3FsaXRlX21hc3RlciB3aGVyZSB0eXBlID0gIiwgYXJnc0ZhaWwpOworICAgICAgICAgICAgZmFpbCgiVGVzdG1ldGhvZCBzaG91bGQgZmFpbCIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgVGFibGVSZXN1bHQgcmVzID0gZGIuZ2V0X3RhYmxlKAorICAgICAgICAgICAgICAgICJzZWxlY3QgbmFtZSBmcm9tIHNxbGl0ZV9tYXN0ZXIgd2hlcmUgdHlwZSA9ICclcSciLAorICAgICAgICAgICAgICAgIGFyZ3MpOworICAgICAgICBTdHJpbmdbXSBzID0gKFN0cmluZ1tdKSByZXMucm93cy5lbGVtZW50QXQoMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhzWzBdLCBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldF90YWJsZVN0cmluZ1N0cmluZ0FycmF5VGFibGVSZXN1bHQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGFyZ3NbXSA9IG5ldyBTdHJpbmdbMV07CisgICAgICAgIFN0cmluZyBhcmdzRmFpbFtdID0gbmV3IFN0cmluZ1sxXTsKKyAgICAgICAgVGFibGVSZXN1bHQgcmVzID0gbmV3IFRhYmxlUmVzdWx0KCk7CisgICAgICAgIFRhYmxlUmVzdWx0IGRlZmF1bHRUYWJsZVJlcyA9IG5ldyBUYWJsZVJlc3VsdCgpOworICAgICAgICBhcmdzWzBdID0gInRhYmxlIjsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIuZ2V0X3RhYmxlKCJzZWxlY3QgbmFtZSBmcm9tIHNxbGl0ZV9tYXN0ZXIgd2hlcmUgdHlwZSA9ICclcSciLCBhcmdzRmFpbCwgcmVzKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhkZWZhdWx0VGFibGVSZXMudG9TdHJpbmcoKSwgcmVzLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZGIuZ2V0X3RhYmxlKCJzZWxlY3QgbmFtZSBmcm9tIHNxbGl0ZV9tYXN0ZXIgd2hlcmUgdHlwZSA9ICclcSciLCBhcmdzLCByZXMpOworICAgICAgICAgICAgU3RyaW5nW10gcyA9IChTdHJpbmdbXSkgcmVzLnJvd3MuZWxlbWVudEF0KDApOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHNbMF0sIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxKTsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRGF0YWJhc2VUZXN0LnRlc3RHZXRfdGFibGVTdHJpbmdTdHJpbmdBcnJheVRhYmxlUmVzdWx0KCkgIgorICAgICAgICAgICAgICAgICAgICArIEFycmF5cy50b1N0cmluZyhyZXMudHlwZXMpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb21wbGV0ZSgpIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZGIuY29tcGxldGUoImNyZWF0ZSIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShkYi5jb21wbGV0ZSgiY3JlYXRlIHRhYmxlIFRFU1QgKHJlcyBkb3VibGUpOyIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmVyc2lvbigpIHsKKyAgICAgICAgU3RyaW5nIHZlcnNpb24gPSBkYi52ZXJzaW9uKCk7CisgICAgICAgIGlmICh2ZXJzaW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoSW50ZWdlci5wYXJzZUludChkYi52ZXJzaW9uKCkuc3Vic3RyaW5nKDAsIDEpKSA+IDApOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGRiLnZlcnNpb24oKSwgZGIudmVyc2lvbigpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZhaWwoIkRCIHZlcnNpb24gaW5mbyBtaXNzaW5nIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGJ2ZXJzaW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB2ZXJObyA9ICIiOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdmVyTm8gPSBkYi5kYnZlcnNpb24oKTsKKyAgICAgICAgICAgIGRiLmNsb3NlKCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZGIuZGJ2ZXJzaW9uKCksInVua25vd24iKTsKKyAgICAgICAgICAgIGRiLm9wZW4oZGJGaWxlLmdldFBhdGgoKSwgMCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModmVyTm8sIGRiLmRidmVyc2lvbigpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGRiLm9wZW4oZGJGaWxlLmdldFBhdGgoKSwgMCk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRUcnVlKEludGVnZXIucGFyc2VJbnQodmVyTm8uc3Vic3RyaW5nKDAsIDEpKT49IDMgKTsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVfZnVuY3Rpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZG91YmxlIGlucHV0ID0gMS4wOworICAgICAgICBkYi5leGVjKCJjcmVhdGUgdGFibGUgVEVTVCAocmVzIGRvdWJsZSkiLCBudWxsKTsKKyAgICAgICAgZGIuZXhlYygiaW5zZXJ0IGludG8gVEVTVCB2YWx1ZXMgKCIgKyBEb3VibGUudG9TdHJpbmcoaW5wdXQpICsgIikiLAorICAgICAgICAgICAgICAgIG51bGwpOworICAgICAgICBUYWJsZVJlc3VsdCByZXMgPSBuZXcgVGFibGVSZXN1bHQoKTsKKyAgICAgICAgRnVuY3Rpb24gc2luRnVuYyA9IChGdW5jdGlvbikgbmV3IFNpbkZ1bmMoKTsKKyAgICAgICAgZGIuY3JlYXRlX2Z1bmN0aW9uKCJzaW4iLCAxLCBzaW5GdW5jKTsKKyAgICAgICAgZGIuZXhlYygic2VsZWN0IHNpbihyZXMpIGZyb20gVEVTVCBXSEVSRSByZXMgPSAiCisgICAgICAgICAgICAgICAgKyBEb3VibGUudG9TdHJpbmcoaW5wdXQpLCByZXMpOworICAgICAgICBTdHJpbmcgcm93W10gPSAoU3RyaW5nW10pIHJlcy5yb3dzLmVsZW1lbnRBdCgwKTsKKyAgICAgICAgU3RyaW5nIHZhbCA9IHJvd1swXTsKKyAgICAgICAgZG91YmxlIHNpbnVzVmFsID0gRG91YmxlLnBhcnNlRG91YmxlKHZhbCk7CisgICAgICAgIGRvdWJsZSBmdW5jVmFsID0gTWF0aC5zaW4oaW5wdXQpOworCisgICAgICAgIGFzc2VydFRydWUoTWF0aC5yb3VuZChmdW5jVmFsKSA9PSBNYXRoLnJvdW5kKHNpbnVzVmFsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWdncmVnYXRpb24gZnVuY3Rpb24gbm90IGNhbGxlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q3JlYXRlX2FnZ3JlZ2F0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0VHJhY2UgdCA9IG5ldyBUZXN0VHJhY2UoKTsKKyAgICAgICAgTW9ja0Z1bmN0aW9uIGFnZ0Z1bmN0aW9uID0gbmV3IE1vY2tGdW5jdGlvbigpOworICAgICAgICBkYi5leGVjKCJjcmVhdGUgdGFibGUgVEVTVChpZCBpbnRlZ2VyLCBmaXJzdG5hbWUgdGV4dCwgbGFzdG5hbWUgdGV4dCkiLCBudWxsKTsKKyAgICAgICAgZGIuZXhlYygiaW5zZXJ0IGludG8gVEVTVCB2YWx1ZXMoMywgJ0phbWVzJywgJ0JvbmQnKTsgIiwgbnVsbCk7CisgICAgICAgIGRiLmV4ZWMoImluc2VydCBpbnRvIFRFU1QgdmFsdWVzKDQsICdGaW9uYScsICdBcHBsZScpOyAiLCBudWxsKTsKKyAgICAgICAgZGIudHJhY2UoKFRyYWNlKSB0KTsKKyAgICAgICAgZGIuY3JlYXRlX2FnZ3JlZ2F0ZSgibXlhZ2dmdW5jIiwgMSwgYWdnRnVuY3Rpb24pOworICAgICAgICBkYi5mdW5jdGlvbl90eXBlKCJteWFnZ2Z1bmMiLCBDb25zdGFudHMuU1FMSVRFM19URVhUKTsKKyAgICAgICAgZGIuZXhlYygiUFJBR01BIHNob3dfZGF0YXR5cGVzID0gb24iLCBudWxsKTsKKworICAgICAgICBhc3NlcnRGYWxzZShhZ2dGdW5jdGlvbi5mdW5jdGlvbkNhbGxlZCk7CisgICAgICAgIGFzc2VydEZhbHNlKGFnZ0Z1bmN0aW9uLnN0ZXBDYWxsZWQpOworICAgICAgICBhc3NlcnRGYWxzZShhZ2dGdW5jdGlvbi5sYXN0U3RlcENhbGxlZCk7CisgICAgICAgIGRiLmV4ZWMoInNlbGVjdCBteWFnZ2Z1bmMoVEVTVC5maXJzdG5hbWUpIGZyb20gVEVTVCIsIHQpOworICAgICAgICBhc3NlcnRUcnVlKGFnZ0Z1bmN0aW9uLnN0ZXBDYWxsZWQpOworICAgICAgICBhc3NlcnRUcnVlKGFnZ0Z1bmN0aW9uLmxhc3RTdGVwQ2FsbGVkKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhZ2dGdW5jdGlvbi5mdW5jdGlvbkNhbGxlZCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJKYW1lcyBGaW9uYSAiLGFnZ0Z1bmN0aW9uLmdldEFnZ1ZhbHVlKCkpOworICAgICAgICBkYi5leGVjKCJkcm9wIHRhYmxlIFRFU1QiLCBudWxsKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIuY3JlYXRlX2FnZ3JlZ2F0ZSgibXlhZ2dmdW5jIiwgMCwgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIm51bGwgU1FMaXRlLkZ1bmN0aW9uIG5vdCBhbGxvd2VkIixlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkYi5jcmVhdGVfYWdncmVnYXRlKCJteWFnZ2Z1bmMiLCAwLCBhZ2dGdW5jdGlvbik7CisgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIG51bWJlciBvZiBhcmd1bWVudHMgdG8gZnVuY3Rpb24gbXlhZ2dmdW5jKCkiLGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGdW5jdGlvbl90eXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRvdWJsZSBpbnB1dCA9IDEuMDsKKyAgICAgICAgVGFibGVSZXN1bHQgcmVzID0gbmV3IFRhYmxlUmVzdWx0KCk7CisgICAgICAgIEZ1bmN0aW9uIHNpbkZ1bmMgPSAoRnVuY3Rpb24pIG5ldyBTaW5GdW5jKCk7CisKKyAgICAgICAgZGIuZXhlYygiUFJBR01BIHNob3dfZGF0YXR5cGVzID0gb24iLCBudWxsKTsKKyAgICAgICAgZGIuZXhlYygiY3JlYXRlIHRhYmxlIFRFU1QgKHJlcyBkb3VibGUpIiwgbnVsbCk7CisgICAgICAgIGRiLmV4ZWMoImluc2VydCBpbnRvIFRFU1QgdmFsdWVzICgiICsgRG91YmxlLnRvU3RyaW5nKGlucHV0KSArICIpIiwKKyAgICAgICAgICAgICAgICBudWxsKTsKKworICAgICAgICBkYi5jcmVhdGVfZnVuY3Rpb24oInNpbiIsIDEsIHNpbkZ1bmMpOworICAgICAgICBkYi5mdW5jdGlvbl90eXBlKCJzaW4iLCBDb25zdGFudHMuU1FMSVRFX0ZMT0FUKTsKKyAgICAgICAgcmVzID0gZGIuZ2V0X3RhYmxlKCJzZWxlY3Qgc2luKHJlcykgZnJvbSBURVNUIFdIRVJFIHJlcyA9ICIKKyAgICAgICAgICAgICAgICArIERvdWJsZS50b1N0cmluZyhpbnB1dCkpOworCisgICAgICAgIFN0cmluZyByb3dbXSA9IChTdHJpbmdbXSkgcmVzLnJvd3MuZWxlbWVudEF0KDApOworICAgICAgICBTdHJpbmcgdmFsID0gcm93WzBdOworICAgICAgICBhc3NlcnRUcnVlKCJkb3VibGUiLmVxdWFsc0lnbm9yZUNhc2UocmVzLnR5cGVzWzBdKSk7CisgICAgICAgIGFzc2VydFNhbWUoTWF0aC5yb3VuZChNYXRoLnNpbihpbnB1dCkpLCBNYXRoLnJvdW5kKERvdWJsZS5wYXJzZURvdWJsZSh2YWwpKSk7CisKKyAgICAgICAgLy8gZnVuY3Rpb24gZGV0ZXJtaW5lcyByZXR1cm4gdHlwZTogdGVzdCB0aGF0IERvdWJsZSB0eXBlIGlzIHJldHVybmVkLgorICAgICAgICBkYi5mdW5jdGlvbl90eXBlKCJzaW4iLCBDb25zdGFudHMuU1FMSVRFX0JMT0IpOworICAgICAgICBTdG10IHMgPSBkYi5wcmVwYXJlKCJzZWxlY3Qgc2luKHJlcykgZnJvbSBURVNUIFdIRVJFIHJlcyA9ID8iKTsKKyAgICAgICAgcy5iaW5kKDEsIGlucHV0KTsKKyAgICAgICAgcy5zdGVwKCk7CisKKyAgICAgICAgcmVzID0gZGIuZ2V0X3RhYmxlKCJzZWxlY3Qgc2luKHJlcykgZnJvbSBURVNUIFdIRVJFIHJlcyA9ICIKKyAgICAgICAgICAgICAgICArIERvdWJsZS50b1N0cmluZyhpbnB1dCkpOworICAgICAgICBhc3NlcnRUcnVlKCJkb3VibGUiLmVxdWFsc0lnbm9yZUNhc2UocmVzLnR5cGVzWzBdKSk7CisgICAgICAgIHJvdyA9IChTdHJpbmdbXSkgcmVzLnJvd3MuZWxlbWVudEF0KDApOworICAgICAgICB2YWwgPSByb3dbMF07CisgICAgICAgIGFzc2VydFNhbWUoTWF0aC5yb3VuZChNYXRoLnNpbihpbnB1dCkpLCBNYXRoLnJvdW5kKERvdWJsZS5wYXJzZURvdWJsZSh2YWwpKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdExhc3RfZXJyb3IoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhkYi5sYXN0X2Vycm9yKCksIENvbnN0YW50cy5TUUxJVEVfT0spOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIuZXhlYygiY3JlYXRlIHRhYmxlIFRFU1QgKHJlcyBkb3VibGUpIixudWxsKTsKKyAgICAgICAgICAgIGRiLmV4ZWMoImNyZWF0ZSB0YWJsZSBURVNUIChyZXMgZG91YmxlKSIsbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJFcnJvciBzaG91bGQgaGF2ZSBoYXBwZW5lZCIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGRiLmxhc3RfZXJyb3IoKSxkYi5sYXN0X2Vycm9yKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGRiLmxhc3RfZXJyb3IoKSxDb25zdGFudHMuU1FMSVRFX0VSUk9SKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRfbGFzdF9lcnJvcigpIHsKKyAgICAgICBhc3NlcnRFcXVhbHMoZGIubGFzdF9lcnJvcigpLCBDb25zdGFudHMuU1FMSVRFX09LKTsKKyAgICAgICB0cnkgeworICAgICAgICAgICBkYi5leGVjKCJzZWwgZnJvbSB0ZXN0OyIsIG51bGwpOworICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgIGFzc2VydEVxdWFscyhDb25zdGFudHMuU1FMSVRFX0VSUk9SLGRiLmxhc3RfZXJyb3IoKSk7CisgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFcnJvcl9tZXNzYWdlKCkgeworICAgICAgICBTdHJpbmcgc3RhdGVtZW50ID0gImNyZWF0ZSB0YWJsZSBURVNUIChyZXMgZG91YmxlKSI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkYi5leGVjKHN0YXRlbWVudCxudWxsKTsKKyAgICAgICAgICAgIGRiLmV4ZWMoc3RhdGVtZW50LG51bGwpOworICAgICAgICAgICAgZmFpbCgiREIgRXJyb3IgZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIFN0cmluZyBkYkVycm9yID0gZGIuZXJyb3JfbWVzc2FnZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShlLmdldE1lc3NhZ2UoKS5lcXVhbHMoZGJFcnJvcikpOworCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXJyb3Jfc3RyaW5nKCkgeworICAgICAgICBUZXN0VHJhY2UgdCA9IG5ldyBUZXN0VHJhY2UoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGRiLmxhc3RfZXJyb3IoKSwgQ29uc3RhbnRzLlNRTElURV9PSyk7CisgICAgICAgIFN0cmluZyBlcnJvclN0cmluZyA9IGRiLmVycm9yX3N0cmluZyhDb25zdGFudHMuU1FMSVRFX0VSUk9SKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRiLnRyYWNlKChUcmFjZSkgdCk7CisgICAgICAgICAgICBkYi5leGVjKCJjcmVhdGUgdGFibGUgVEVTVCAocmVzIGRvdWJsZSkiLCB0KTsKKyAgICAgICAgICAgIGRiLmV4ZWMoImNyZWF0ZSB0YWJsZSBURVNUIChyZXMgZG91YmxlKSIsIHQpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGRiLmxhc3RfZXJyb3IoKSwgQ29uc3RhbnRzLlNRTElURV9FUlJPUik7CisgICAgICAgICAgICBpZiAoZGIuaXMzKCkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlVuc3VwcG9ydGVkIE1ldGhvZCAoc3FsaXRlIDMpOiBlcnJvcl9zdHJpbmciLCBkYgorICAgICAgICAgICAgICAgICAgICAgICAgLmVycm9yX3N0cmluZyhkYi5sYXN0X2Vycm9yKCkpLCBlcnJvclN0cmluZyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBU0NJSSBlbmNvZGluZyBkb2VzIG5vdCB3b3JrOiBhIFVURiBlbmNvZGVkIHZhbCBpcyByZXR1cm5lZC4gU3BlYyBpcyBub3QKKyAgICAgKiBzdWZmaWNpZW50LiBNaWdodCBiZSB0aGF0IHRlc3QgaW1wbCBpcyB3cm9uZyBvciBTdHJpbmcgY29uc3RydWN0b3IgZm9yCisgICAgICogdGhlIEFTQ0lJIGVuY29kaW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRfZW5jb2RpbmcoKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGlucHV0ID0gIlx1MDBiZk1hXHUwMGYxYW5hXHUwMDNmIjsgLy8gP01hbmFuYT8KKyAgICAgICAgVGFibGVSZXN1bHQgcmVzID0gbmV3IFRhYmxlUmVzdWx0KCk7CisgICAgICAgIFN0cmluZyByZWZPdXRwdXQgPSBudWxsOworICAgICAgICBTdG10IHN0YXQgPSBudWxsOworCisgICAgICAgIC8vIERCIHNldHVwCisgICAgICAgIGRiLmV4ZWMoImNyZWF0ZSB0YWJsZSBlbmNvZGluZ1Rlc3QgKGVuY29kZWQgdGV4dCBERUZBVUxUIE5VTEwpOyIsCisgICAgICAgICAgICAgICAgbnVsbCk7CisgICAgICAgIHN0YXQgPSBkYgorICAgICAgICAgICAgICAgIC5wcmVwYXJlKCJpbnNlcnQgaW50byBlbmNvZGluZ1Rlc3QoZW5jb2RlZCkgdmFsdWVzKDpvbmUpOyIpOworICAgICAgICBzdGF0LmJpbmQoMSwgaW5wdXQpOworICAgICAgICBzdGF0LnN0ZXAoKTsKKyAgICAgICAgLy8gc3RhdC5jbG9zZSgpOworICAgICAgICBkYi5leGVjKCJzZWxlY3QgKiBmcm9tIGVuY29kaW5nVGVzdDsiLCByZXMpOworICAgICAgICBTdHJpbmdbXSBlbmNJbnB1dCA9IChTdHJpbmdbXSkgcmVzLnJvd3MuZWxlbWVudEF0KDApOworICAgICAgICBTdHJpbmcgb3V0cHV0ID0gZW5jSW5wdXRbMF07CisgICAgICAgIGFzc2VydEVxdWFscyhpbnB1dCwgb3V0cHV0KTsKKyAgICAgICAgLy8gZGIuZXhlYygiZGVsZXRlIGZyb20gZW5jb2RpbmdUZXN0IHdoZXJlIDEiLCBudWxsKTsKKworICAgICAvLyB0ZXN0cyBmb3IgZGlmZmVyZW50IGVuY29kaW5nIHNjaGVtZXMKKyAgICAgICAgU3RyaW5nW10gY2hhcnNldE5hbWVzID0geyJVVEYtOCIsICJVVEYtMTYiLCAiVVRGLTE2QkUiLCAiVVRGLTE2TEUifTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaGFyc2V0TmFtZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGJ5dGVbXSBlbmNJbnB1dEJ5dGVzID0gaW5wdXQuZ2V0Qnl0ZXMoY2hhcnNldE5hbWVzW2ldKTsKKyAgICAgICAgICAgIGRiLnNldF9lbmNvZGluZyhjaGFyc2V0TmFtZXNbaV0pOworICAgICAgICAgICAgZGIuZXhlYygic2VsZWN0ICogZnJvbSBlbmNvZGluZ1Rlc3Q7IiwgcmVzKTsKKyAgICAgICAgICAgIFN0cmluZ1tdIGVuY091dHB1dCA9IChTdHJpbmdbXSkgcmVzLnJvd3MuZWxlbWVudEF0KDApOworICAgICAgICAgICAgU3RyaW5nIGlucHV0QXNTdHJpbmcgPSBuZXcgU3RyaW5nKGVuY0lucHV0Qnl0ZXMsY2hhcnNldE5hbWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpbnB1dEFzU3RyaW5nLCBlbmNPdXRwdXRbMF0pOworICAgICAgICB9CisKKyAgICAgICAgLy8gRGVmYXVsdCB0ZXN0cworICAgICAgICBkYi5zZXRfZW5jb2RpbmcoIlVURi0xNiIpOworICAgICAgICBkYi5leGVjKCJzZWxlY3QgKiBmcm9tIGVuY29kaW5nVGVzdDsiLCByZXMpOworICAgICAgICBTdHJpbmdbXSBlbmNPdXRwdXQxID0gKFN0cmluZ1tdKSByZXMucm93cy5lbGVtZW50QXQoMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiR290ICIrZW5jT3V0cHV0MVswXSsiIGFzIFVURi0xNiIsaW5wdXQsZW5jT3V0cHV0MVswXSk7CisKKyAgICAgICAgZGIuc2V0X2VuY29kaW5nKCJVUy1BU0NJSSIpOworICAgICAgICBkYi5leGVjKCJzZWxlY3QgKiBmcm9tIGVuY29kaW5nVGVzdDsiLCByZXMpOworICAgICAgICBTdHJpbmdbXSBlbmNPdXRwdXQyID0gKFN0cmluZ1tdKSByZXMucm93cy5lbGVtZW50QXQoMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgU3RyaW5nKGlucHV0LmdldEJ5dGVzKCksIlVTLUFTQ0lJIiksZW5jT3V0cHV0MlswXSk7CisKKyAgICAgICAgLy8gREIgdGVhcmRvd24KKyAgICAgICAgc3RhdC5jbG9zZSgpOworICAgICAgICBkYi5leGVjKCJkZWxldGUgZnJvbSBlbmNvZGluZ1Rlc3QiLCBudWxsKTsKKworICAgICAgICAvLyBEZWZhdWx0IHRlc3RzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkYi5zZXRfZW5jb2RpbmcoIiIpOworICAgICAgICAgICAgZmFpbCgiaW52YWxpZCBpbnB1dCBzaG91bGQgZmFpbCIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbGJhY2sgbmV2ZXIgbWFkZSBmb3IgYXV0aG9yaXphdGlvbi4gUmVzdWx0cyBvZiBwcml2YXRlIHRhYmxlIGFyZQorICAgICAqIHJldHVybmVkIHdpdGhvdXRoIGZ1cmh0ZXIgY2hlY2tzLgorICAgICAqCisgICAgICogVGVzdCBmYWlscyAtPiBpbXBsZW1lbnRlZCBjb3JyZWN0bHk/CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNldF9hdXRob3JpemVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRhYmxlUmVzdWx0IHJlc1ByaXYgPSBudWxsOworICAgICAgICBUYWJsZVJlc3VsdCByZXNQdWIgPSBudWxsOworICAgICAgICBUYWJsZVJlc3VsdCBlbXB0eVRhYmxlID0gbmV3IFRhYmxlUmVzdWx0KCk7CisgICAgICAgIFN0cmluZyBpbnNlcnRQdWJsaWMgPSAiaW5zZXJ0IGludG8gcHVibGljX3RhYmxlIHZhbHVlcygxLDIpIjsKKyAgICAgICAgU3RyaW5nIGluc2VydFByaXZhdGUgPSAiaW5zZXJ0IGludG8gcHJpdmF0ZV90YWJsZSB2YWx1ZXMoMSwyKSI7CisgICAgICAgIC8vIHByZXBhcmUsIGF1dGhvcml6ZXIgaXMgbm90IGFjdGl2YXRlZCB5ZXQKKyAgICAgICAgZGIuZXhlYygiY3JlYXRlIHRhYmxlIHB1YmxpY190YWJsZShjMSBpbnRlZ2VyLCBjMiBpbnRlZ2VyKTsiLCBudWxsKTsKKyAgICAgICAgZGIuZXhlYygiY3JlYXRlIHRhYmxlIHByaXZhdGVfdGFibGUoYzEgaW50ZWdlciwgYzIgaW50ZWdlcik7IiwgbnVsbCk7CisgICAgICAgIC8vIGluc2VydHMKKyAgICAgICAgZGIuZXhlYyhpbnNlcnRQdWJsaWMsIG51bGwpOworICAgICAgICBkYi5leGVjKGluc2VydFByaXZhdGUsIG51bGwpOworICAgICAgICAvLyBzZWxlY3RzCisgICAgICAgIHJlc1ByaXYgPSBkYi5nZXRfdGFibGUoInNlbGVjdCAqIGZyb20gcHJpdmF0ZV90YWJsZSIpOworICAgICAgICByZXNQdWIgPSBkYi5nZXRfdGFibGUoInNlbGVjdCAqIGZyb20gcHVibGljX3RhYmxlIik7CisKKy8vICAgICAgICBkYi5leGVjKCJkZWxldGUgZnJvbSBwdWJsaWNfdGFibGUgd2hlcmUgMSIsIG51bGwpOworLy8gICAgICAgIFRhYmxlUmVzdWx0IGVtcHR5UHViVGFibGUgPSBkYi5leGVjKCJzZWxlY3QgKiBmcm9tIHB1YmxpYyIpOworCisgICAgICAgIC8vIHNldCBBdXRob3JpemVyIChwb3NpdGl2ZSBjYXNlKTogZGVuaWVzIHByaXZhdGUgdGFibGUKKyAgICAgICAgQXV0aG9yaXplckNhbGxiYWNrIGNiID0gbmV3IEF1dGhvcml6ZXJDYWxsYmFjaygpOworICAgICAgICBkYi5zZXRfYXV0aG9yaXplcihjYik7CisgICAgICAgIC8vc2VsZWN0CisKKyAgICAgICAgZGIuZXhlYygic2VsZWN0ICogZnJvbSBwcml2YXRlX3RhYmxlIiwgY2IpOworICAgICAgICBhc3NlcnRUcnVlKGNiLndhc0NhbGxlZCgpKTsKKworICAgICAgIC8qCisgICAgICAgIFRhYmxlUmVzdWx0IHJlcyA9IGRiLmdldF90YWJsZSgic2VsZWN0ICogZnJvbSBwcml2YXRlX3RhYmxlIik7CisgICAgICAgIGFzc2VydEVxdWFscyhlbXB0eVRhYmxlLnRvU3RyaW5nKCkscmVzLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRGYWxzZShlbXB0eVRhYmxlLmVxdWFscyhyZXNQcml2KSk7CisKKyAgICAgICAgcmVzID0gZGIuZ2V0X3RhYmxlKCJzZWxlY3QgKiBmcm9tIHB1YmxpY190YWJsZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMocmVzUHViLHJlcyk7CisgICAgICAgICovCisKKyAgICAgICAgLy8gVHJ5IGluc2VydAorICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIuZXhlYyhpbnNlcnRQdWJsaWMsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiYXV0aG9yaXphdGlvbiBmYWlsZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkYi5leGVjKGluc2VydFByaXZhdGUsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiYXV0aG9yaXphdGlvbiBmYWlsZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUxKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRyYWNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzdG10ID0gImNyZWF0ZSB0YWJsZSBURVNUIChyZXMgZG91YmxlKTsiOworICAgICAgICBUZXN0VHJhY2UgdCA9IG5ldyBUZXN0VHJhY2UoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UodC50cmFjZUNhbGxlZCk7CisgICAgICAgIGFzc2VydEVxdWFscyhkYi5sYXN0X2Vycm9yKCksQ29uc3RhbnRzLlNRTElURV9PSyk7CisgICAgICAgIGRiLnRyYWNlKChUcmFjZSkgdCk7CisgICAgICAgIGRiLmV4ZWMoc3RtdCx0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0LnRyYWNlQ2FsbGVkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHQuZ2V0VHJhY2UoKSxzdG10KTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIuY2xvc2UoKTsKKyAgICAgICAgICAgIGRiLmV4ZWMoc3RtdCx0KTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBFeHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbXBpbGVTdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZGIuY29tcGlsZSgic2VsZWN0IG5hbWUgZnJvbSBzcWxpdGVfbWFzdGVyOyIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIuY29tcGlsZSgidGVzdCIpOworICAgICAgICAgICAgZmFpbCgiQ29tcGlsaW5nIG9mIGluYWNjdXJhdGUgc3RhdGVtZW50IGRvZXMgbm90IGZhaWwuIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29tcGlsZVN0cmluZ1N0cmluZ0FycmF5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBhcmdzW10gPSBuZXcgU3RyaW5nWzFdOworICAgICAgICBhcmdzWzBdID0gInRhYmxlIjsKKyAgICAgICAgZGIuY29tcGlsZSgic2VsZWN0IG5hbWUgZnJvbSBzcWxpdGVfbWFzdGVyIHdoZXJlIHR5cGUgPSAnJXEnOyIsYXJncyk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRiLmNvbXBpbGUoInRlc3QiLG51bGwpOworICAgICAgICAgICAgZmFpbCgiQ29tcGlsaW5nIG9mIGluYWNjdXJhdGUgc3RhdGVtZW50IGRvZXMgbm90IGZhaWwuIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJlcGFyZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdG10IHN0ID0gbnVsbDsKKyAgICAgICAgU3RtdCBzdDIgPSBudWxsOworICAgICAgICAvLyB0ZXN0IGVtcHR5IHN0YXRlbWVudAorICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBkYi5wcmVwYXJlKCIiKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBzdC5iaW5kX3BhcmFtZXRlcl9jb3VudCgpKTsKKyAgICAgICAgICAgIHN0LnN0ZXAoKTsKKyAgICAgICAgICAgIGZhaWwoInN0bXQgc2hvdWxkIG5vdCBiZSBwcmVwYXJlZCIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdG10IGFscmVhZHkgY2xvc2VkIiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gdGVzdCBzdGF0ZW1lbnQgd2l0aCB1bmJvdW5kIGFyZ3VtZW50cworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QyID0gZGIucHJlcGFyZSgiaW5zZXJ0IGludG8gIiArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxCisgICAgICAgICAgICAgICAgICAgICsgIiB2YWx1ZXMgKDpvbmUsOnR3byw6dGhyZWUpIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMywgc3QyLmJpbmRfcGFyYW1ldGVyX2NvdW50KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHN0Mi5iaW5kX3BhcmFtZXRlcl9pbmRleCgiOnRocmVlIikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCI6dHdvIiwgc3QyLmJpbmRfcGFyYW1ldGVyX25hbWUoMikpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc3QyLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIucHJlcGFyZSgiaW5zZXJ0IGludG8gIiArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxCisgICAgICAgICAgICAgICAgICAgICsgIiB2YWx1ZXMoOm9uZSw6dHdvLDp0aHJlZSw6Zm91cik7Iik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInRhYmxlICIgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMQorICAgICAgICAgICAgICAgICAgICArICIgaGFzIDMgY29sdW1ucyBidXQgNCB2YWx1ZXMgd2VyZSBzdXBwbGllZCIsIGUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIucHJlcGFyZSgiaW5zZXJ0IGludG8gIiArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxCisgICAgICAgICAgICAgICAgICAgICsgIiB2YWx1ZXMoNSwgJzEwLCAyMCk7Iik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInVucmVjb2duaXplZCB0b2tlbjogXCInMTAsIDIwKTtcIiIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkYi5wcmVwYXJlKCJpbnNlcnQgaW50byAiICsgRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTEKKyAgICAgICAgICAgICAgICAgICAgKyAiIHZhbHVlcyg1LCAxMCAyMCk7Iik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIm5lYXIgXCIyMFwiOiBzeW50YXggZXJyb3IiLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIE5vdCBzdXBwb3J0ZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE9wZW5fYmxvYigpIHRocm93cyBFeGNlcHRpb24sIGphdmEubGFuZy5FeGNlcHRpb24geworICAgICAgICBTdG10IHN0YXRlbWVudDI7CisgICAgICAgIEJsb2IgYmxvYklucHV0ID0gbmV3IEJsb2IoKTsKKworICAgICAgICAvLyBDcmVhdGUgdGVzdCBpbnB1dCBCbG9iCisgICAgICAgIElucHV0U3RyZWFtIGluU3RyZWFtID0gbnVsbDsKKyAgICAgICAgYnl0ZVtdIGluID0geyhieXRlKSAxLCAoYnl0ZSkgMiwgKGJ5dGUpIDMsIChieXRlKSA0fTsKKworICAgICAgICAvLyBzZXR1cCB0ZXN0IGlucHV0CisgICAgICAgIGRiLmV4ZWMoImNyZWF0ZSB0YWJsZSBURVNUIChyZXMgYmxvYikiLG51bGwpOworICAgICAgICBpblN0cmVhbSA9IENsYXNzLmZvck5hbWUodGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSkuZ2V0UmVzb3VyY2VBc1N0cmVhbSgiL2Jsb2IuYyIpOworICAgICAgICBhc3NlcnROb3ROdWxsKGluU3RyZWFtKTsKKworICAgICAgICAvLyBpbnNlcnQgYnl0ZSBhcnJheSBpbiBkYgorICAgICAgICBzdGF0ZW1lbnQyID0gZGIucHJlcGFyZSgiaW5zZXJ0IGludG8gVEVTVChyZXMpIHZhbHVlcyAoPykiKTsKKyAgICAgICAgc3RhdGVtZW50Mi5iaW5kKDEsIGluKTsKKyAgICAgICAgc3RhdGVtZW50Mi5zdGVwKCk7CisgICAgICAgIHN0YXRlbWVudDIuY2xvc2UoKTsKKworICAgICAgICAvLyByZWFkIGZyb20gZGIKKyAgICAgICAgQmxvYiBibG9iID0gZGIub3Blbl9ibG9iKGRiRmlsZS5nZXRQYXRoKCksICJURVNUIiwgInJlcyIsIDEsIHRydWUpOworICAgICAgICBpZiAoYmxvYiA9PSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKCJCbG9iIGNvdWxkIG5vdCBiZSByZXRyaWV2ZWQiKTsKKyAgICAgICAgfQorICAgICAgICAvL3JlYWQgZnJvbSBibG9iIGFuZCBjb21wYXJlIHZhbHVlcyAocG9zaXRpdmUgY2FzZSkKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBibG9iLmdldElucHV0U3RyZWFtKCk7CisKKyAgICAgICAgaW50IGkgPSAwOworICAgICAgICBpbnQgb3V0Qnl0ZSA9IDA7CisgICAgICAgIGJ5dGVbXSBvdXQgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgd2hpbGUgKChvdXRCeXRlID0gaXMucmVhZCgpKSA+IC0xKSB7CisgICAgICAgICAgICBvdXRbaV0gPSAoYnl0ZSkgb3V0Qnl0ZTsKKyAgICAgICAgICAgIGkrKzsKKyAgICAgICAgfQorICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgIGJsb2IuY2xvc2UoKTsKKworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoaW4sIG91dCkpOworCisgICAgICAgIC8vcmVhZCBmcm9tIGJsb2IgYW5kIGNvbXBhcmUgdmFsdWVzIChkZWZhdWx0IGJsb2IpCisgICAgICAgIGRiLmV4ZWMoImluc2VydCBpbnRvIFRFU1QgdmFsdWVzKHplcm9ibG9iKDEyOCkpIiwgbnVsbCk7CisgICAgICAgIEJsb2IgYmxvYjIgPSBkYi5vcGVuX2Jsb2IoZGJGaWxlLmdldFBhdGgoKSwgIlRFU1QiLCAicmVzIiwgMiwgdHJ1ZSk7CisgICAgICAgIGlzID0gYmxvYjIuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IDEyODsgaSsrKSAgeworICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaXMucmVhZCgpKTsKKyAgICAgICAgfQorICAgICAgICBpcy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJczMoKSB7CisgICAgICAgIGludCB2ZXIgPSBJbnRlZ2VyLnBhcnNlSW50KGRiLnZlcnNpb24oKS5zdWJzdHJpbmcoMCwxKSk7CisgICAgICAgIGlmIChkYi5pczMoKSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSggdmVyID09IDMpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSh2ZXIgIT0gMyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJvZ3Jlc3NfaGFuZGxlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbnQgaW5wdXRWYWwgPSAzOworICAgICAgICBUZXN0UHJvZ3Jlc3NIYW5kbGVyIHByb2cgPSBuZXcgVGVzdFByb2dyZXNzSGFuZGxlcigpOworICAgICAgICBkYi5leGVjKCJjcmVhdGUgdGFibGUgVEVTVDUoaWQgaW50ZWdlciwgZmlyc3RuYW1lIHRleHQsIGxhc3RuYW1lIHRleHQpIixudWxsKTsKKyAgICAgICAgVm0gdm0gPSBkYi5jb21waWxlKCJzZWxlY3QgKiBmcm9tIFRFU1Q1OyAiCisgICAgICAgICAgICAgICAgKyAiaW5zZXJ0IGludG8gVEVTVDUgdmFsdWVzKDMsICdKYW1lcycsICdCb25kJyk7ICIKKyAgICAgICAgICAgICAgICArICJkZWxldGUgZnJvbSBURVNUNSB3aGVyZSBpZCA9IDM7ICIKKyAgICAgICAgICAgICAgICArICJzZWxlY3QgKiBmcm9tIFRFU1Q1Iik7CisgICAgICAgIGludCBzdG10ID0gMDsKKyAgICAgICAgZG8geworICAgICAgICAgICAgKytzdG10OworICAgICAgICAgICAgaWYgKHN0bXQgPiBpbnB1dFZhbCkgeworICAgICAgICAgICAgICAgIGRiLnByb2dyZXNzX2hhbmRsZXIoaW5wdXRWYWwsIHByb2cpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgcHJvZy5nZXRDb3VudHMoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB3aGlsZSAodm0uc3RlcChwcm9nKSkgeworICAgICAgICAgICAgfQorICAgICAgICB9IHdoaWxlICh2bS5jb21waWxlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoaW5wdXRWYWwscHJvZy5nZXRDb3VudHMoKSk7CisKKyAgICAgICAgLy8gQm91bmRhcnkgdmFsdWUgdGVzdAorICAgICAgICBpbnB1dFZhbCA9IDA7CisgICAgICAgIFRlc3RQcm9ncmVzc0hhbmRsZXIgcHJvZ0JvdW5kYXJ5ID0gbmV3IFRlc3RQcm9ncmVzc0hhbmRsZXIoKTsKKyAgICAgICAgZGIucHJvZ3Jlc3NfaGFuZGxlcihpbnB1dFZhbCwgcHJvZ0JvdW5kYXJ5KTsKKyAgICAgICAgVm0gdm0yID0gZGIuY29tcGlsZSgic2VsZWN0ICogZnJvbSBURVNUNTsgIgorICAgICAgICAgICAgICAgICsgImluc2VydCBpbnRvIFRFU1Q1IHZhbHVlcygzLCAnSmFtZXMnLCAnQm9uZCcpOyAiCisgICAgICAgICAgICAgICAgKyAiZGVsZXRlIGZyb20gVEVTVDUgd2hlcmUgaWQgPSAzOyAiCisgICAgICAgICAgICAgICAgKyAic2VsZWN0ICogZnJvbSBURVNUNSIpOworICAgICAgICBkbyB7CisgICAgICAgICAgICB2bTIuc3RlcChwcm9nQm91bmRhcnkpOworICAgICAgICB9IHdoaWxlICh2bTIuY29tcGlsZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGlucHV0VmFsLCBwcm9nQm91bmRhcnkuZ2V0Q291bnRzKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkYi5leGVjKCJkcm9wIHRhYmxlIFRFU1Q1IixudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgU2luRnVuYyBpbXBsZW1lbnRzIEZ1bmN0aW9uIHsKKyAgICAgICAgcHVibGljIHZvaWQgZnVuY3Rpb24oRnVuY3Rpb25Db250ZXh0IGZjLCBTdHJpbmcgYXJnc1tdKSB7CisgICAgICAgICAgICBEb3VibGUgZCA9IG5ldyBEb3VibGUoYXJnc1swXSk7CisgICAgICAgICAgICBmYy5zZXRfcmVzdWx0KE1hdGguc2luKGQuZG91YmxlVmFsdWUoKSkpOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyB2b2lkIGxhc3Rfc3RlcChGdW5jdGlvbkNvbnRleHQgZmMpIHt9CisgICAgICAgIHB1YmxpYyB2b2lkIHN0ZXAoRnVuY3Rpb25Db250ZXh0IGZjLCBTdHJpbmdbXSBhcmdzKSB7fQorICAgIH0KKworICAgIGNsYXNzIFRlc3RUcmFjZSBpbXBsZW1lbnRzIFRyYWNlLENhbGxiYWNrIHsKKworICAgICAgICBwcml2YXRlIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gdHJhY2VDYWxsZWQgPSBmYWxzZTsKKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRyYWNlKCkgeworICAgICAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgdHJhY2UoU3RyaW5nIHN0bXQpIHsKKyAgICAgICAgICAgIHRyYWNlQ2FsbGVkID0gdHJ1ZTsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoc3RtdCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBjb2x1bW5zKFN0cmluZ1tdIGNvbGRhdGEpIHt9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gbmV3cm93KFN0cmluZ1tdIHJvd2RhdGEpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHR5cGVzKFN0cmluZ1tdIHR5cGVzKSB7fQorICAgIH0KKworICAgIGNsYXNzIEF1dGhvcml6ZXJDYWxsYmFjayBpbXBsZW1lbnRzIEF1dGhvcml6ZXIsIENhbGxiYWNrIHsKKworICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNBdXRob3JpemluZyA9IGZhbHNlOworCisgICAgICAgIHB1YmxpYyBib29sZWFuIHdhc0NhbGxlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBpc0F1dGhvcml6aW5nOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBhdXRob3JpemUoaW50IGFjdGlvbiwgU3RyaW5nIGFyZzEsIFN0cmluZyBhcmcyLCBTdHJpbmcgYXJnMywKKyAgICAgICAgICAgICAgICBTdHJpbmcgYXJnNCkgeworICAgICAgICAgICAgTG9nZ2VyLmdsb2JhbC5pbmZvKCJEQiBhdXRob3JpemF0aW9uIGNhbGxiYWNrICIgKyBhY3Rpb24gKyAiICIgKyBhcmcxICsgIiAiICsgYXJnMiArICIgIgorICAgICAgICAgICAgICAgICAgICArIGFyZzMgKyAiICIgKyBhcmc0ICsgIiAiKTsKKyAgICAgICAgICAgIHRoaXMuaXNBdXRob3JpemluZyA9IHRydWU7CisgICAgICAgICAgICBpZiAoYWN0aW9uICE9IENvbnN0YW50cy5TUUxJVEVfU0VMRUNUIHx8IGFyZzEuY29udGFpbnMoInByaXZhdGVfdGFibGUiKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBDb25zdGFudHMuU1FMSVRFX0RFTlk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBDb25zdGFudHMuU1FMSVRFX09LOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgY29sdW1ucyhTdHJpbmdbXSBjb2xkYXRhKSB7fQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIG5ld3JvdyhTdHJpbmdbXSByb3dkYXRhKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCB0eXBlcyhTdHJpbmdbXSB0eXBlcykge30KKworICAgIH0KKworICAgIGNsYXNzIFRlc3RCdXN5SGFuZGxlciBpbXBsZW1lbnRzIEJ1c3lIYW5kbGVyLCBDYWxsYmFjayB7CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gYnVzeShTdHJpbmcgdGFibGUsIGludCBjb3VudCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBjb2x1bW5zKFN0cmluZ1tdIGNvbGRhdGEpIHt9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gbmV3cm93KFN0cmluZ1tdIHJvd2RhdGEpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHR5cGVzKFN0cmluZ1tdIHR5cGVzKSB7fQorICAgIH0KKworICAgIGNsYXNzIFRlc3RQcm9ncmVzc0hhbmRsZXIgaW1wbGVtZW50cyBQcm9ncmVzc0hhbmRsZXIsIENhbGxiYWNrIHsKKworICAgICAgICBwcml2YXRlIGJvb2xlYW4gcHJvZ3Jlc3NlZCA9IGZhbHNlOworCisgICAgICAgIHByaXZhdGUgaW50IGNvdW50ZXIgPSAwOworCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0Q291bnRzKCkgeworICAgICAgICAgICAgcmV0dXJuIGNvdW50ZXI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBwcm9ncmVzcygpIHsKKyAgICAgICAgICAgIHRoaXMucHJvZ3Jlc3NlZCA9IHRydWU7CisgICAgICAgICAgICBjb3VudGVyKys7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGNvbHVtbnMoU3RyaW5nW10gY29sZGF0YSkge30KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBuZXdyb3coU3RyaW5nW10gcm93ZGF0YSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgdHlwZXMoU3RyaW5nW10gdHlwZXMpIHt9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgY3JlYXRlcyBhIFJ1bm5hYmxlIHRoYXQgZXhlY3V0ZXMgaW5zZXJ0IG9wZXJhdGlvbiBmb3IgdGhlIGZpcnN0IHRhYmxlCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgUnVubmFibGUgY3JlYXRlVGFzazJJbnRlcnJ1cHQoZmluYWwgaW50IGlkLAorICAgICAgICAgICAgZmluYWwgU3RyaW5nIGRiTmFtZSwgZmluYWwgRXJyb3JUcmFja2VyIGVycm9yVHJhY2tlcikgeworICAgICAgICByZXR1cm4gbmV3IFJ1bm5hYmxlKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIERhdGFiYXNlIGRiID0gbmV3IERhdGFiYXNlKCk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRTdHJpbmcgKyBpZDsKKworICAgICAgICAgICAgICAgICAgICBkYi5vcGVuKGRiTmFtZSwgMCk7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBpbnNlcnRRdWVyeSA9ICJJTlNFUlQgSU5UTyAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgKGlkLCBmaWVsZDEsIGZpZWxkMiwgZmllbGQzKSBWQUxVRVMoIiArIGlkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiLCAnIiArIHZhbHVlICsgIicsICIgKyBpZCArICIsICIgKyBpZCArICIpIjsKKyAgICAgICAgICAgICAgICAgICAgZGIuZXhlYyhpbnNlcnRRdWVyeSwgbnVsbCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZXJyb3JUcmFja2VyLnJlZ2lzdGVyRXhjZXB0aW9uKHRoaXMsIGUpOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgZGIuaW50ZXJydXB0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICBkYi5leGVjKCJERUxFVEUgRlJPTSAiICsgRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIFdIRVJFIGlkPSIgKyBpZCwgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JUcmFja2VyLnJlZ2lzdGVyRXhjZXB0aW9uKHRoaXMsIGUxKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBjcmVhdGVzIGEgUnVubmFibGUgdGhhdCBleGVjdXRlcyBkZWxldGUgb3BlcmF0aW9uIGZvciB0aGUgZmlyc3QgdGFibGUKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBSdW5uYWJsZSBjcmVhdGVUYXNrMShmaW5hbCBpbnQgaWQsIGZpbmFsIFN0cmluZyBkYk5hbWUsCisgICAgICAgICAgICBmaW5hbCBFcnJvclRyYWNrZXIgZXJyb3JUcmFja2VyKSB7CisgICAgICAgIHJldHVybiBuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgRGF0YWJhc2UgZGIgPSBuZXcgRGF0YWJhc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgZGIub3BlbihkYk5hbWUsIDApOworICAgICAgICAgICAgICAgICAgICBkYi5leGVjKCJERUxFVEUgRlJPTSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMSArICIgV0hFUkUgaWQ9IiArIGlkLCBudWxsKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBlcnJvclRyYWNrZXIucmVnaXN0ZXJFeGNlcHRpb24odGhpcywgZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBSdW5uYWJsZSB0aGF0IGV4ZWN1dGVzIGluc2VydCBvcGVyYXRpb24gZm9yIHRoZSBmaXJzdCB0YWJsZQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFJ1bm5hYmxlIGNyZWF0ZVRhc2syKGZpbmFsIGludCBpZCwgZmluYWwgU3RyaW5nIGRiTmFtZSwKKyAgICAgICAgICAgIGZpbmFsIEVycm9yVHJhY2tlciBlcnJvclRyYWNrZXIpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBEYXRhYmFzZUNyZWF0b3IuZGVmYXVsdFN0cmluZyArIGlkOworICAgICAgICAgICAgICAgICAgICBEYXRhYmFzZSBkYiA9IG5ldyBEYXRhYmFzZSgpOworICAgICAgICAgICAgICAgICAgICBkYi5vcGVuKGRiTmFtZSwgMCk7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBpbnNlcnRRdWVyeSA9ICJJTlNFUlQgSU5UTyAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgKGlkLCBmaWVsZDEsIGZpZWxkMiwgZmllbGQzKSBWQUxVRVMoIiArIGlkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiLCAnIiArIHZhbHVlICsgIicsICIgKyBpZCArICIsICIgKyBpZCArICIpIjsKKyAgICAgICAgICAgICAgICAgICAgZGIuZXhlYyhpbnNlcnRRdWVyeSwgbnVsbCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZXJyb3JUcmFja2VyLnJlZ2lzdGVyRXhjZXB0aW9uKHRoaXMsIGUpOworCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBSdW5uYWJsZSB0aGF0IGV4ZWN1dGVzIHVwZGF0ZSBvcGVyYXRpb24gZm9yIHRoZSBvbmUgcmVjb3JkIG9mIHRoZSBmaXJzdAorICAgICAqIHRhYmxlCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgUnVubmFibGUgY3JlYXRlVGFzazMoZmluYWwgaW50IG9sZElELCBmaW5hbCBTdHJpbmcgZGJOYW1lLAorICAgICAgICAgICAgZmluYWwgaW50IG5ld0lELCBmaW5hbCBFcnJvclRyYWNrZXIgZXJyb3JUcmFja2VyKSB7CisgICAgICAgIHJldHVybiBuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgRGF0YWJhc2UgZGIgPSBuZXcgRGF0YWJhc2UoKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBkYi5vcGVuKGRiTmFtZSwgMCk7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IERhdGFiYXNlQ3JlYXRvci5kZWZhdWx0U3RyaW5nICsgbmV3SUQ7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyB1cGRhdGVRdWVyeSA9ICJVUERBVEUgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxICsgIiBTRVQgaWQ9IiArIG5ld0lECisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiLCBmaWVsZDE9JyIgKyB2YWx1ZSArICInLCBmaWVsZDI9IiArIG5ld0lECisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiLCBmaWVsZDM9IiArIG5ld0lEICsgIiBXSEVSRSBpZD0iICsgb2xkSUQ7CisgICAgICAgICAgICAgICAgICAgIGRiLmV4ZWModXBkYXRlUXVlcnksIG51bGwpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGVycm9yVHJhY2tlci5yZWdpc3RlckV4Y2VwdGlvbih0aGlzLCBlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBFcnJvclRyYWNrZXIgeworCisgICAgICAgIHByaXZhdGUgTGlzdDxTdHJpbmc+IGVycm9ycyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworCisgICAgICAgIHB1YmxpYyB2b2lkIHJlZ2lzdGVyRXhjZXB0aW9uKFJ1bm5hYmxlIHJ1bm5hYmxlLCBFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJSZWdpc3RlcmVkOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgZXJyb3JzLmFkZChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTGlzdDxTdHJpbmc+IGdldEVycm9ycygpIHsKKyAgICAgICAgICAgIHJldHVybiBlcnJvcnM7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKKyAgICAgICAgICAgIGVycm9ycy5jbGVhcigpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvc3FsaXRlL09sZEV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGRFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGRkZmQ2YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGRFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSwzOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5zcWxpdGU7CisKK2ltcG9ydCBTUUxpdGUuRGF0YWJhc2U7CitpbXBvcnQgU1FMaXRlLkV4Y2VwdGlvbjsKKworcHVibGljIGZpbmFsIGNsYXNzIE9sZEV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBPbGRTUUxpdGVUZXN0IHsKKworICAgIHByaXZhdGUgRGF0YWJhc2UgZGIgPSBudWxsOworCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIGphdmEubGFuZy5FeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBkYiA9IG5ldyBEYXRhYmFzZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFeGNlcHRpb24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkYi5vcGVuKGRiRmlsZS5nZXROYW1lKCksIDApOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChlKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvc3FsaXRlL09sZEZ1bmN0aW9uQ29udGV4dFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGRGdW5jdGlvbkNvbnRleHRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDkyNDMxNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGRGdW5jdGlvbkNvbnRleHRUZXN0LmphdmEKQEAgLTAsMCArMSwzMTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuc3FsaXRlOworCitpbXBvcnQgU1FMaXRlLkRhdGFiYXNlOworaW1wb3J0IFNRTGl0ZS5FeGNlcHRpb247CitpbXBvcnQgU1FMaXRlLkZ1bmN0aW9uOworaW1wb3J0IFNRTGl0ZS5GdW5jdGlvbkNvbnRleHQ7CitpbXBvcnQgU1FMaXRlLlN0bXQ7CitpbXBvcnQgU1FMaXRlLlRhYmxlUmVzdWx0OworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247CitpbXBvcnQgamF2YS5zcWwuU3RhdGVtZW50OworaW1wb3J0IHRlc3RzLnN1cHBvcnQuRGF0YWJhc2VDcmVhdG9yOworCitwdWJsaWMgZmluYWwgY2xhc3MgT2xkRnVuY3Rpb25Db250ZXh0VGVzdCBleHRlbmRzIE9sZFNRTGl0ZVRlc3QgeworCisgICAgcHJpdmF0ZSBEYXRhYmFzZSBkYiA9IG51bGw7CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIGRiID0gbmV3IERhdGFiYXNlKCk7CisgICAgICAgIGRiLm9wZW4oZGJGaWxlLmdldFBhdGgoKSwgMCk7CisgICAgICAgIFN0YXRlbWVudCBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgIHN0LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkNSRUFURV9UQUJMRTIpOworICAgICAgICBzdC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEVfU0lNUExFMSk7CisgICAgICAgIHN0LmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldF9yZXN1bHRTdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdEZDU3RyaW5nIHRlc3RTdHJpbmcgPSBuZXcgVGVzdEZDU3RyaW5nKCk7CisgICAgICAgIGRiLmV4ZWMoImluc2VydCBpbnRvICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTIKKyAgICAgICAgICAgICAgICArICIgKGZ0ZXh0KSB2YWx1ZXMgKCdUZXN0SW5wdXQnKSIsIG51bGwpOworICAgICAgICBkYi5jcmVhdGVfZnVuY3Rpb24oInRlc3QiLCAxLCB0ZXN0U3RyaW5nKTsKKyAgICAgICAgVGFibGVSZXN1bHQgcmVzID0gZGIuZ2V0X3RhYmxlKCJzZWxlY3QgdGVzdChmdGV4dCkgZnJvbSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTIpOworICAgICAgICBTdHJpbmcgcm93W10gPSAoU3RyaW5nW10pIHJlcy5yb3dzLmVsZW1lbnRBdCgwKTsKKyAgICAgICAgU3RyaW5nIHZhbCA9IHJvd1swXTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3RJbnB1dCIsIHZhbCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldF9yZXN1bHRJbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdEZDSW50IHRlc3RJbnQgPSBuZXcgVGVzdEZDSW50KCk7CisgICAgICAgIGRiLmV4ZWMoImluc2VydCBpbnRvICIgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMQorICAgICAgICAgICAgICAgICsgIiAgdmFsdWVzICgxLCciICsgdGVzdEludC5pbnRWYWwgKyAiJywzKSIsIG51bGwpOworICAgICAgICBkYi5jcmVhdGVfZnVuY3Rpb24oInRlc3RJbnQiLCAxLCB0ZXN0SW50KTsKKyAgICAgICAgVGFibGVSZXN1bHQgcmVzID0gZGIuZ2V0X3RhYmxlKCJzZWxlY3QgdGVzdEludChzcGVlZCkgZnJvbSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMSk7CisgICAgICAgIFN0cmluZyByb3dbXSA9IChTdHJpbmdbXSkgcmVzLnJvd3MuZWxlbWVudEF0KDApOworICAgICAgICBTdHJpbmcgdmFsID0gcm93WzBdOworCisgICAgICAgIGFzc2VydEVxdWFscyh0ZXN0SW50LmludFZhbCwgSW50ZWdlci5wYXJzZUludCh2YWwpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0X3Jlc3VsdERvdWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTaW5GdW5jIHRlc3REID0gbmV3IFNpbkZ1bmMoKTsKKyAgICAgICAgZGIuZXhlYygiaW5zZXJ0IGludG8gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMgorICAgICAgICAgICAgICAgICsgIiAoZmRvdWJsZSkgIHZhbHVlcyAoIiArIHRlc3RELnRlc3REb3VibGUgKyAiKSIsIG51bGwpOworICAgICAgICBkYi5jcmVhdGVfZnVuY3Rpb24oInRlc3REb3VibGUiLCAxLCB0ZXN0RCk7CisgICAgICAgIFRhYmxlUmVzdWx0IHJlcyA9IGRiLmdldF90YWJsZSgic2VsZWN0IHRlc3REb3VibGUoZmRvdWJsZSkgZnJvbSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTIpOworICAgICAgICBTdHJpbmcgcm93W10gPSAoU3RyaW5nW10pIHJlcy5yb3dzLmVsZW1lbnRBdCgwKTsKKyAgICAgICAgU3RyaW5nIHZhbCA9IHJvd1swXTsKKworICAgICAgICBhc3NlcnRFcXVhbHModGVzdEQudGVzdERvdWJsZSwgRG91YmxlLnBhcnNlRG91YmxlKHZhbCkpOworCisgICAgICAgIGFzc2VydFRydWUodGVzdEQuZnVuY3Rpb25DYWxsZWQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRfZXJyb3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdEZDRXJyb3IgdGVzdEVycm9yID0gbmV3IFRlc3RGQ0Vycm9yKCk7CisgICAgICAgIFNpbkZ1bmMgdGVzdEQgPSBuZXcgU2luRnVuYygpOworICAgICAgICBkYi5leGVjKCJpbnNlcnQgaW50byAiICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUyCisgICAgICAgICAgICAgICAgKyAiIChmZG91YmxlKSAgdmFsdWVzICgiICsgdGVzdEQudGVzdERvdWJsZSArICIpIiwgbnVsbCk7CisgICAgICAgIGRiLmNyZWF0ZV9mdW5jdGlvbigidGVzdEVycm9yIiwgMSwgdGVzdEVycm9yKTsKKworICAgICAgICB0cnkgeworICAgICAgICBUYWJsZVJlc3VsdCByZXMgPSBkYi5nZXRfdGFibGUoInNlbGVjdCB0ZXN0RXJyb3IoZmRvdWJsZSkgZnJvbSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTIpOworICAgICAgICBmYWlsKCJTaG91bGQgZ2V0IEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJlcnJvciBpbiBzdGVwIiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RmFsc2UodGVzdEQuZnVuY3Rpb25DYWxsZWQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRfcmVzdWx0Qnl0ZUFycmF5KCkgdGhyb3dzIEV4Y2VwdGlvbiwgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIFN0bXQgc3QgPSBudWxsOworICAgICAgICBUZXN0RkNCeXRlQXJyYXkgdGVzdEJpbkFycmF5Rm5jID0gbmV3IFRlc3RGQ0J5dGVBcnJheSgpOworICAgICAgICBTdHJpbmcgZXhwZWN0ZWQgPSAiIjsKKyAgICAgICAgZXhwZWN0ZWQgPSAiWCciICsgZ2V0SGV4U3RyaW5nKHRlc3RCaW5BcnJheUZuYy5ieXRlVmFsKSArICInIjsKKworICAgICAgICAvLyBzZXR1cAorICAgICAgICBkYi5leGVjKCJjcmVhdGUgdGFibGUgdGVzdEJpbmFyeURhdGEgKGJpblZhbCBCSU5BUlkpIDsiLCBudWxsKTsKKworICAgICAgICB0cnkgeworICAgICAgICBzdCA9IGRiLnByZXBhcmUoImluc2VydCBpbnRvIHRlc3RCaW5hcnlEYXRhIHZhbHVlcyAoPykiKTsKKyAgICAgICAgc3QuYmluZCgxLCB0ZXN0QmluQXJyYXlGbmMuYnl0ZVZhbCk7CisgICAgICAgIHN0LnN0ZXAoKTsKKworCisgICAgICAgIGRiLmNyZWF0ZV9mdW5jdGlvbigidGVzdEJpbkFycmF5IiwgMSwgdGVzdEJpbkFycmF5Rm5jKTsKKyAgICAgICAgVGFibGVSZXN1bHQgcmVzID0gZGIKKyAgICAgICAgICAgICAgICAuZ2V0X3RhYmxlKCJzZWxlY3QgdGVzdEJpbkFycmF5KGJpblZhbCkgZnJvbSB0ZXN0QmluYXJ5RGF0YSIpOworCisgICAgICAgIFN0cmluZyByb3dbXSA9IChTdHJpbmdbXSkgcmVzLnJvd3MuZWxlbWVudEF0KDApOworICAgICAgICBTdHJpbmcgdmFsID0gcm93WzBdOworCisgICAgICAgIGFzc2VydFRydWUoZXhwZWN0ZWQuZXF1YWxzSWdub3JlQ2FzZSh2YWwpKTsKKworICAgICAgICBhc3NlcnRUcnVlKHRlc3RCaW5BcnJheUZuYy5mdW5jdGlvbkNhbGxlZCk7CisKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIC8vdGVhcmRvd24KKyAgICAgICAgICAgIGRiLmV4ZWMoImRyb3AgdGFibGUgdGVzdEJpbmFyeURhdGE7IiwgbnVsbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBaZXJvQmxvYiBub3Qgc3VwcG9ydGVkCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNldF9yZXN1bHRfemVyb2Jsb2IoKSB0aHJvd3MgRXhjZXB0aW9uLAorICAgICAgICAgICAgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIFN0bXQgc3QgPSBudWxsOworICAgICAgICBUZXN0RkNaZXJvQmxvYiB0ZXN0WmVyb0Jsb2JGbmMgPSBuZXcgVGVzdEZDWmVyb0Jsb2IoKTsKKyAgICAgICAgYnl0ZVtdIGJ5dGVWYWwgPSB7KGJ5dGUpIDEsIChieXRlKSAyLCAoYnl0ZSkgM307CisKKworICAgICAgICAvLyBzZXR1cAorICAgICAgICBkYi5leGVjKCJjcmVhdGUgdGFibGUgdGVzdEJpbmFyeURhdGEgKGJpblZhbCBCSU5BUlkpIDsiLCBudWxsKTsKKworICAgICAgICB0cnkgeworICAgICAgICBzdCA9IGRiLnByZXBhcmUoImluc2VydCBpbnRvIHRlc3RCaW5hcnlEYXRhIHZhbHVlcyAoPykiKTsKKyAgICAgICAgc3QuYmluZCgxLCBieXRlVmFsKTsKKyAgICAgICAgc3Quc3RlcCgpOworCisKKyAgICAgICAgZGIuY3JlYXRlX2Z1bmN0aW9uKCJ0ZXN0WmVyb0Jsb2IiLCAwLCB0ZXN0WmVyb0Jsb2JGbmMpOworICAgICAgICBUYWJsZVJlc3VsdCByZXMgPSBkYgorICAgICAgICAgICAgICAgIC5nZXRfdGFibGUoInNlbGVjdCB0ZXN0WmVyb0Jsb2IoKSBmcm9tIHRlc3RCaW5hcnlEYXRhIik7CisgICAgICAgIFRhYmxlUmVzdWx0IHJlczIgPSBkYi5nZXRfdGFibGUoInNlbGVjdCB6ZXJvYmxvYigiCisgICAgICAgICAgICAgICAgKyB0ZXN0WmVyb0Jsb2JGbmMubnVtQnl0ZXMgKyAiKSBmcm9tIHRlc3RCaW5hcnlEYXRhIik7CisKKyAgICAgICAgU3RyaW5nIHJvd1tdID0gKFN0cmluZ1tdKSByZXMucm93cy5lbGVtZW50QXQoMCk7CisgICAgICAgIFN0cmluZyB2YWwgPSByb3dbMF07CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh2YWwpOworCisgICAgICAgIGFzc2VydEVxdWFscygoKFN0cmluZ1tdKSByZXMyLnJvd3MuZWxlbWVudEF0KDApKVswXSwgdmFsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0ZXN0WmVyb0Jsb2JGbmMuZnVuY3Rpb25DYWxsZWQpOworCisgICAgICAgIH0gZmluYWxseSAgeworICAgICAgICAgLy8gdGVhcmRvd24KKyAgICAgICAgICAgIGRiLmV4ZWMoImRyb3AgdGFibGUgaWYgZXhpc3RzIHRlc3RCaW5hcnlEYXRhOyIsIG51bGwpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBNZXRob2QgcmVzdWx0cyBpbiBhIHNlZ21lbnRhdGlvbiBmYXVsdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDb3VudCgpIHRocm93cyBTUUxFeGNlcHRpb24sIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RGQ0NvdW50IGNvdW50VGVzdCA9IG5ldyBUZXN0RkNDb3VudCgpOworICAgICAgICBpbnQgaW5wdXRDb3VudCA9IDEwOworCisgICAgICAgIGFzc2VydEZhbHNlKGNvdW50VGVzdC5mdW5jdGlvbkNhbGxlZCk7CisKKyAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmZpbGxUZXN0VGFibGUyKGNvbm4sIGlucHV0Q291bnQpOworICAgICAgICBkYi5jcmVhdGVfZnVuY3Rpb24oInRlc3RDb3VudCIsIDAsIGNvdW50VGVzdCk7CisgICAgICAgIC8vIHRoZSBpbnZva2F0aW9uIG9mIHRlc3RDb3VudCBsZWFkcyB0byBhIFNlZ21lbnRhdGlvbiBmYXVsdAorICAgICAgICAvKgorICAgICAgICBUYWJsZVJlc3VsdCByZXMgPSBkYgorICAgICAgICAgICAgICAgIC5nZXRfdGFibGUoInNlbGVjdCB0ZXN0Q291bnQoKSBmcm9tICIrRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUyKTsKKworICAgICAgICBTdHJpbmcgcm93W10gPSAoU3RyaW5nW10pIHJlcy5yb3dzLmVsZW1lbnRBdCgwKTsKKyAgICAgICAgU3RyaW5nIHZhbCA9IHJvd1swXTsKKworICAgICAgICBhc3NlcnRUcnVlKGNvdW50VGVzdC5mdW5jdGlvbkNhbGxlZCk7CisgICAgICAgIGFzc2VydEVxdWFscyhpbnB1dENvdW50LEludGVnZXIucGFyc2VJbnQodmFsKSk7CisgICAgICAgICovCisKKyAgICB9CisKKyAgICBjbGFzcyBUZXN0RkNFcnJvciBpbXBsZW1lbnRzIEZ1bmN0aW9uIHsKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZnVuY3Rpb25DYWxsZWQgPSBmYWxzZTsKKyAgICAgICAgcHVibGljIFN0cmluZyBlcnJvck1zZyA9ICJGdW5jdGlvbkVycm9yIjsKKworICAgICAgICBwdWJsaWMgdm9pZCBmdW5jdGlvbihGdW5jdGlvbkNvbnRleHQgZmMsIFN0cmluZyBhcmdzW10pIHsKKyAgICAgICAgICAgIGZ1bmN0aW9uQ2FsbGVkID0gdHJ1ZTsKKyAgICAgICAgICAgIGZjLnNldF9lcnJvcihlcnJvck1zZyk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBsYXN0X3N0ZXAoRnVuY3Rpb25Db250ZXh0IGZjKSB7fQorICAgICAgICBwdWJsaWMgdm9pZCBzdGVwKEZ1bmN0aW9uQ29udGV4dCBmYywgU3RyaW5nW10gYXJncykge30KKyAgICB9CisKKyAgICBjbGFzcyBUZXN0RkNDb3VudCBpbXBsZW1lbnRzIEZ1bmN0aW9uIHsKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZnVuY3Rpb25DYWxsZWQgPSBmYWxzZTsKKyAgICAgICAgcHVibGljIGludCBub09mUm93cyA9IDA7CisKKyAgICAgICAgcHVibGljIHZvaWQgZnVuY3Rpb24oRnVuY3Rpb25Db250ZXh0IGZjLCBTdHJpbmcgYXJnc1tdKSB7CisgICAgICAgICAgICBmdW5jdGlvbkNhbGxlZCA9IHRydWU7CisgICAgICAgICAgICBub09mUm93cyA9IGZjLmNvdW50KCk7CisgICAgICAgICAgICBmYy5zZXRfcmVzdWx0KG5vT2ZSb3dzKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGxhc3Rfc3RlcChGdW5jdGlvbkNvbnRleHQgZmMpIHt9CisgICAgICAgIHB1YmxpYyB2b2lkIHN0ZXAoRnVuY3Rpb25Db250ZXh0IGZjLCBTdHJpbmdbXSBhcmdzKSB7fQorICAgIH0KKworICAgIGNsYXNzIFRlc3RGQ1plcm9CbG9iIGltcGxlbWVudHMgRnVuY3Rpb24geworICAgICAgICBwdWJsaWMgaW50IG51bUJ5dGVzID0gMTY7CisgICAgICAgIHB1YmxpYyBib29sZWFuIGZ1bmN0aW9uQ2FsbGVkID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIHZvaWQgZnVuY3Rpb24oRnVuY3Rpb25Db250ZXh0IGZjLCBTdHJpbmcgYXJnc1tdKSB7CisgICAgICAgICAgICBmdW5jdGlvbkNhbGxlZCA9IHRydWU7CisgICAgICAgICAgICBmYy5zZXRfcmVzdWx0X3plcm9ibG9iKG51bUJ5dGVzKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGxhc3Rfc3RlcChGdW5jdGlvbkNvbnRleHQgZmMpIHt9CisgICAgICAgIHB1YmxpYyB2b2lkIHN0ZXAoRnVuY3Rpb25Db250ZXh0IGZjLCBTdHJpbmdbXSBhcmdzKSB7fQorICAgIH0KKworICAgIGNsYXNzIFRlc3RGQ1N0cmluZyBpbXBsZW1lbnRzIEZ1bmN0aW9uIHsKKyAgICAgICAgcHVibGljIFN0cmluZyB0ZXN0U3RyaW5nID0gIlRlc3RTdHJpbmciOworICAgICAgICBwdWJsaWMgYm9vbGVhbiBmdW5jdGlvbkNhbGxlZDsKKworICAgICAgICBwdWJsaWMgdm9pZCBmdW5jdGlvbihGdW5jdGlvbkNvbnRleHQgZmMsIFN0cmluZyBhcmdzW10pIHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoYXJncyk7CisgICAgICAgICAgICBmdW5jdGlvbkNhbGxlZCA9IHRydWU7CisgICAgICAgICAgICBmYy5zZXRfcmVzdWx0KGFyZ3NbMF0pOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgbGFzdF9zdGVwKEZ1bmN0aW9uQ29udGV4dCBmYykge30KKyAgICAgICAgcHVibGljIHZvaWQgc3RlcChGdW5jdGlvbkNvbnRleHQgZmMsIFN0cmluZ1tdIGFyZ3MpIHt9CisgICAgfQorCisgICAgY2xhc3MgVGVzdEZDSW50IGltcGxlbWVudHMgRnVuY3Rpb24geworICAgICAgICBwdWJsaWMgaW50IGludFZhbCA9IEludGVnZXIuTUFYX1ZBTFVFOworICAgICAgICBwdWJsaWMgYm9vbGVhbiBmdW5jdGlvbkNhbGxlZDsKKworICAgICAgICBwdWJsaWMgdm9pZCBmdW5jdGlvbihGdW5jdGlvbkNvbnRleHQgZmMsIFN0cmluZyBhcmdzW10pIHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoYXJncyk7CisgICAgICAgICAgICBmdW5jdGlvbkNhbGxlZCA9IHRydWU7CisgICAgICAgICAgICBmYy5zZXRfcmVzdWx0KEludGVnZXIucGFyc2VJbnQoYXJnc1swXSkpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgbGFzdF9zdGVwKEZ1bmN0aW9uQ29udGV4dCBmYykge30KKyAgICAgICAgcHVibGljIHZvaWQgc3RlcChGdW5jdGlvbkNvbnRleHQgZmMsIFN0cmluZ1tdIGFyZ3MpIHt9CisgICAgfQorCisgICAgY2xhc3MgVGVzdEZDQnl0ZUFycmF5IGltcGxlbWVudHMgRnVuY3Rpb24geworICAgICAgICBwdWJsaWMgYnl0ZVtdIGJ5dGVWYWwgPSB7KGJ5dGUpICAxLCAoYnl0ZSkgMiwgKGJ5dGUpIDN9OworICAgICAgICBwdWJsaWMgYm9vbGVhbiBmdW5jdGlvbkNhbGxlZDsKKworICAgICAgICBwdWJsaWMgdm9pZCBmdW5jdGlvbihGdW5jdGlvbkNvbnRleHQgZmMsIFN0cmluZyBhcmdzW10pIHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoYXJncyk7CisgICAgICAgICAgICBmdW5jdGlvbkNhbGxlZCA9IHRydWU7CisgICAgICAgICAgICBmYy5zZXRfcmVzdWx0KGFyZ3NbMF0uZ2V0Qnl0ZXMoKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBsYXN0X3N0ZXAoRnVuY3Rpb25Db250ZXh0IGZjKSB7fQorICAgICAgICBwdWJsaWMgdm9pZCBzdGVwKEZ1bmN0aW9uQ29udGV4dCBmYywgU3RyaW5nW10gYXJncykge30KKyAgICB9CisKKyAgICBjbGFzcyBTaW5GdW5jIGltcGxlbWVudHMgRnVuY3Rpb24geworICAgICAgICBwdWJsaWMgRG91YmxlIHRlc3REb3VibGUgPSAzLjA7CisgICAgICAgIHB1YmxpYyBib29sZWFuIGZ1bmN0aW9uQ2FsbGVkID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIHZvaWQgZnVuY3Rpb24oRnVuY3Rpb25Db250ZXh0IGZjLCBTdHJpbmcgYXJnc1tdKSB7CisgICAgICAgICAgICBEb3VibGUgZCA9IG5ldyBEb3VibGUoYXJnc1swXSk7CisgICAgICAgICAgICBmdW5jdGlvbkNhbGxlZCA9IHRydWU7CisgICAgICAgICAgICBmYy5zZXRfcmVzdWx0KGQuZG91YmxlVmFsdWUoKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBsYXN0X3N0ZXAoRnVuY3Rpb25Db250ZXh0IGZjKSB7fQorICAgICAgICBwdWJsaWMgdm9pZCBzdGVwKEZ1bmN0aW9uQ29udGV4dCBmYywgU3RyaW5nW10gYXJncykge30KKyAgICB9CisKKyAgICBzdGF0aWMgZmluYWwgYnl0ZVtdIEhFWF9DSEFSX1RBQkxFID0geworICAgICAgICAgICAgKGJ5dGUpJzAnLCAoYnl0ZSknMScsIChieXRlKScyJywgKGJ5dGUpJzMnLAorICAgICAgICAgICAgKGJ5dGUpJzQnLCAoYnl0ZSknNScsIChieXRlKSc2JywgKGJ5dGUpJzcnLAorICAgICAgICAgICAgKGJ5dGUpJzgnLCAoYnl0ZSknOScsIChieXRlKSdhJywgKGJ5dGUpJ2InLAorICAgICAgICAgICAgKGJ5dGUpJ2MnLCAoYnl0ZSknZCcsIChieXRlKSdlJywgKGJ5dGUpJ2YnCisgICAgICAgICAgfTsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEhleFN0cmluZyhieXRlW10gcmF3KQorICAgICAgICAgICAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgICAgICBieXRlW10gaGV4ID0gbmV3IGJ5dGVbMiAqIHJhdy5sZW5ndGhdOworICAgICAgICBpbnQgaW5kZXggPSAwOworCisgICAgICAgIGZvciAoYnl0ZSBiIDogcmF3KSB7CisgICAgICAgICAgICBpbnQgdiA9IGIgJiAweEZGOworICAgICAgICAgICAgaGV4W2luZGV4KytdID0gSEVYX0NIQVJfVEFCTEVbdiA+Pj4gNF07CisgICAgICAgICAgICBoZXhbaW5kZXgrK10gPSBIRVhfQ0hBUl9UQUJMRVt2ICYgMHhGXTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhoZXgsICJBU0NJSSIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGRKREJDRHJpdmVyRnVuY3Rpb25hbFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGRKREJDRHJpdmVyRnVuY3Rpb25hbFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40OGVlYWIxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvc3FsaXRlL09sZEpEQkNEcml2ZXJGdW5jdGlvbmFsVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuc3FsaXRlOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zcWwuQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247CisKKy8qKgorICogVGVzdHMgdGhlIFNRTGl0ZS5KREJDRHJpdmVyLgorICovCitwdWJsaWMgY2xhc3MgT2xkSkRCQ0RyaXZlckZ1bmN0aW9uYWxUZXN0IGV4dGVuZHMgQWJzdHJhY3RTcWxUZXN0IHsKKyAgICBwcml2YXRlICBGaWxlIGRiRmlsZSA9IG51bGw7CisgICAgcHJpdmF0ZSBTdHJpbmcgY29ubmVjdGlvblVSTCA9ICJlbXB0eSI7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICAgICAgZGJGaWxlLmRlbGV0ZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgU3RyaW5nIGdldENvbm5lY3Rpb25VUkwoKSB7CisgICAgICAgIGlmIChjb25uZWN0aW9uVVJMLmVxdWFscygiZW1wdHkiKSkgeworICAgICAgICAgICAgU3RyaW5nIHRtcCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKTsKKyAgICAgICAgICAgIEZpbGUgdG1wRGlyID0gbmV3IEZpbGUodG1wKTsKKyAgICAgICAgICAgIGlmICh0bXBEaXIuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGRiRmlsZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoIkpEQkNEcml2ZXJGdW5jdGlvbmFsVGVzdCIsICIuZGIiLCB0bXBEaXIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJlcnJvciBjcmVhdGluZyB0ZW1wb3JhcnkgREIgZmlsZS4iKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZGJGaWxlLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oImphdmEuaW8udG1wZGlyIGRvZXMgbm90IGV4aXN0Iik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNvbm5lY3Rpb25VUkwgPSAiamRiYzpzcWxpdGU6LyIgKyBkYkZpbGUuZ2V0UGF0aCgpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGNvbm5lY3Rpb25VUkw7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBTdHJpbmcgZ2V0RHJpdmVyQ2xhc3NOYW1lKCkgeworICAgICAgICByZXR1cm4gIlNRTGl0ZS5KREJDRHJpdmVyIjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIGludCBnZXRUcmFuc2FjdGlvbklzb2xhdGlvbigpIHsKKyAgICAgICAgcmV0dXJuIENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fU0VSSUFMSVpBQkxFOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGRKREJDRHJpdmVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvc3FsaXRlL09sZEpEQkNEcml2ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWUwNmRjNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGRKREJDRHJpdmVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTEzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLnNxbGl0ZTsKKworaW1wb3J0IFNRTGl0ZS5KREJDRHJpdmVyOworaW1wb3J0IGphdmEuc3FsLkNvbm5lY3Rpb247CitpbXBvcnQgamF2YS5zcWwuRHJpdmVyOworaW1wb3J0IGphdmEuc3FsLkRyaXZlck1hbmFnZXI7CitpbXBvcnQgamF2YS5zcWwuRHJpdmVyUHJvcGVydHlJbmZvOworaW1wb3J0IGphdmEuc3FsLlNRTEV4Y2VwdGlvbjsKKworCitwdWJsaWMgZmluYWwgY2xhc3MgT2xkSkRCQ0RyaXZlclRlc3QgZXh0ZW5kcyBPbGRKREJDRHJpdmVyRnVuY3Rpb25hbFRlc3QgeworCisgICAgLyoqCisgICAgICogVGhlIFNRTGl0ZSBkYiBmaWxlLgorICAgICAqLworICAgIHByaXZhdGUgSkRCQ0RyaXZlciBqRHJpdmVyOworCisgICAgcHJpdmF0ZSBEcml2ZXIgcmV0dXJuZWREcml2ZXI7CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHJldHVybmVkRHJpdmVyID0gRHJpdmVyTWFuYWdlci5nZXREcml2ZXIoZ2V0Q29ubmVjdGlvblVSTCgpKTsKKyAgICAgICAgaWYgKHJldHVybmVkRHJpdmVyIGluc3RhbmNlb2YgSkRCQ0RyaXZlcikgeworICAgICAgICAgICAgdGhpcy5qRHJpdmVyID0gKEpEQkNEcml2ZXIpIHJldHVybmVkRHJpdmVyOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEpEQkNEcml2ZXIoKSB7CisgICAgICAgIGFzc2VydFRydWUocmV0dXJuZWREcml2ZXIgaW5zdGFuY2VvZiBKREJDRHJpdmVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWNjZXB0c1VSTCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICh0aGlzLmpEcml2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoakRyaXZlci5hY2NlcHRzVVJMKGdldENvbm5lY3Rpb25VUkwoKSkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJubyBEcml2ZXIgYXZhaWxhYmxlIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJEcml2ZXIgZG9lcyBub3QgYWNjZXB0IFVSTCIpOworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25uZWN0KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKHRoaXMuakRyaXZlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgQ29ubmVjdGlvbiBjID0gakRyaXZlci5jb25uZWN0KGdldENvbm5lY3Rpb25VUkwoKSwgbnVsbCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoYy5pc0Nsb3NlZCgpKTsKKyAgICAgICAgICAgICAgICBEcml2ZXJNYW5hZ2VyLmdldENvbm5lY3Rpb24oZ2V0Q29ubmVjdGlvblVSTCgpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZmFpbCgibm8gRHJpdmVyIGF2YWlsYWJsZSIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRHJpdmVyIGRvZXMgbm90IGNvbm5lY3QiKTsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TWFqb3JWZXJzaW9uKCkgeworICAgICAgICBpZiAodGhpcy5qRHJpdmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoakRyaXZlci5nZXRNYWpvclZlcnNpb24oKSA+IDApOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmFpbCgibm8gRHJpdmVyIGF2YWlsYWJsZSIpOworICAgICAgICB9CisgICAgfQorCisgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TWlub3JWZXJzaW9uKCkgeworICAgICAgICBpZiAodGhpcy5qRHJpdmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoakRyaXZlci5nZXRNaW5vclZlcnNpb24oKSA+IDApOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmFpbCgibm8gdmVyc2lvbiBpbmZvcm1hdGlvbiBhdmFpbGFibGUiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgcHVibGljIHZvaWQgdGVzdEdldFByb3BlcnR5SW5mbygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBEcml2ZXJQcm9wZXJ0eUluZm9bXSBpbmZvID0gbnVsbDsKKyAgICAgICBpZiAodGhpcy5qRHJpdmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgaW5mbyA9IGpEcml2ZXIuZ2V0UHJvcGVydHlJbmZvKGdldENvbm5lY3Rpb25VUkwoKSwgbnVsbCk7CisgICAgICAgICAgIGFzc2VydE5vdE51bGwoaW5mbyk7CisgICAgICAgICAgIGFzc2VydFRydWUoaW5mby5sZW5ndGggPiAwKTsKKyAgICAgICB9IGVsc2UgeworICAgICAgICAgICBmYWlsKCJubyBEcml2ZXIgYXZhaWxhYmxlIik7CisgICAgICAgfQorCisgICAgICAgIGFzc2VydE5vdE51bGwoaW5mbyk7CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SmRiY0NvbXBsaWFudCgpIHsKKyAgICAgICAgaWYgKHRoaXMuakRyaXZlciAhPSBudWxsKSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShqRHJpdmVyLmpkYmNDb21wbGlhbnQoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmYWlsKCJubyB2ZXJzaW9uIGluZm9ybWF0aW9uIGF2YWlsYWJsZSIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvc3FsaXRlL09sZFNRTGl0ZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGRTUUxpdGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTZiN2YyMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGRTUUxpdGVUZXN0LmphdmEKQEAgLTAsMCArMSw2MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5zcWxpdGU7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5Db25uZWN0aW9uOworaW1wb3J0IGphdmEuc3FsLkRyaXZlck1hbmFnZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nZ2VyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGFic3RyYWN0IGNsYXNzIE9sZFNRTGl0ZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgc3RhdGljIENvbm5lY3Rpb24gY29ubjsKKworICAgIHB1YmxpYyBzdGF0aWMgRmlsZSBkYkZpbGUgPSBudWxsOworCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB0bXAgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaW8udG1wZGlyIik7CisgICAgICAgIEZpbGUgdG1wRGlyID0gbmV3IEZpbGUodG1wKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICh0bXBEaXIuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgICAgICAgIGRiRmlsZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInNxbGl0ZVRlc3QiLCAiLmRiIiwgdG1wRGlyKTsKKyAgICAgICAgICAgICAgICBkYkZpbGUuZGVsZXRlT25FeGl0KCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiY3RzZGlyIGRvZXMgbm90IGV4aXN0Iik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIENsYXNzLmZvck5hbWUoIlNRTGl0ZS5KREJDRHJpdmVyIikubmV3SW5zdGFuY2UoKTsKKworICAgICAgICAgICAgaWYgKCFkYkZpbGUuZXhpc3RzKCkpIHsKKyAgICAgICAgICAgICAgICBMb2dnZXIuZ2xvYmFsLnNldmVyZSgiREIgZmlsZSBjb3VsZCBub3QgYmUgY3JlYXRlZC4gVGVzdHMgY2FuIG5vdCBiZSBleGVjdXRlZC4iKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgY29ubiA9IERyaXZlck1hbmFnZXIuZ2V0Q29ubmVjdGlvbigiamRiYzpzcWxpdGU6LyIgKyBkYkZpbGUuZ2V0UGF0aCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIkVycm9yIGNyZWF0aW5nIGNvbm5lY3Rpb24iLCBjb25uKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJQcm9ibGVtIGNyZWF0aW5nIHRlc3QgZmlsZSBpbiAiICsgdG1wKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFjb25uLmlzQ2xvc2VkKCkpIHsKKyAgICAgICAgICAgIGNvbm4uY2xvc2UoKTsKKyAgICAgICAgfQorICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGRTdG10VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvc3FsaXRlL09sZFN0bXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGQzNzllZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9PbGRTdG10VGVzdC5qYXZhCkBAIC0wLDAgKzEsODIzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLnNxbGl0ZTsKKworaW1wb3J0IFNRTGl0ZS5Db25zdGFudHM7CitpbXBvcnQgU1FMaXRlLkRhdGFiYXNlOworaW1wb3J0IFNRTGl0ZS5TdG10OworaW1wb3J0IFNRTGl0ZS5UYWJsZVJlc3VsdDsKK2ltcG9ydCBqYXZhLnNxbC5Db25uZWN0aW9uOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuRGF0YWJhc2VDcmVhdG9yOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9TUUw7CisKK3B1YmxpYyBjbGFzcyBPbGRTdG10VGVzdCBleHRlbmRzIE9sZFNRTGl0ZVRlc3QgeworCisgICAgcHJpdmF0ZSBEYXRhYmFzZSBkYjsKKyAgICBwcml2YXRlIFN0bXQgc3Q7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ1JFQVRFX0FMTF9UWVBFUyA9ICJjcmVhdGUgdGFibGUgdHlwZSAoIgorICAgICAgICAgICAgKyAiIEJvb2xWYWwgQk9PTEVBTiwiCisgICAgICAgICAgICArICIgSW50VmFsIElOVCwiCisgICAgICAgICAgICArICIgTG9uZ1ZhbCBMT05HLCIKKyAgICAgICAgICAgICsgIiBCaW50IEJJR0lOVCwiCisgICAgICAgICAgICArICIgVGludCBUSU5ZSU5ULCIKKyAgICAgICAgICAgICsgIiBTaW50IFNNQUxMSU5ULCIKKyAgICAgICAgICAgICsgIiBNaW50IE1FRElVTUlOVCwiCisgICAgICAgICAgICArICIgSW50ZWdlclZhbCBJTlRFR0VSLCIKKyAgICAgICAgICAgICsgIiBSZWFsVmFsIFJFQUwsIgorICAgICAgICAgICAgKyAiIERvdWJsZVZhbCBET1VCTEUsIgorICAgICAgICAgICAgKyAiIEZsb2F0VmFsIEZMT0FULCIKKyAgICAgICAgICAgICsgIiBEZWNWYWwgREVDSU1BTCwiCisgICAgICAgICAgICArICIgTnVtVmFsIE5VTUVSSUMsIgorICAgICAgICAgICAgKyAiIGNoYXJTdHIgQ0hBUigyMCksIgorICAgICAgICAgICAgKyAiIGRhdGVWYWwgREFURSwiCisgICAgICAgICAgICArICIgdGltZVZhbCBUSU1FLCIKKyAgICAgICAgICAgICsgIiBUUyBUSU1FU1RBTVAsIgorICAgICAgICAgICAgKyAiIERUIERBVEVUSU1FLCIKKyAgICAgICAgICAgICsgIiBUQmxvYiBUSU5ZQkxPQiwiCisgICAgICAgICAgICArICIgQmxvYlZhbCBCTE9CLCIKKyAgICAgICAgICAgICsgIiBNQmxvYiBNRURJVU1CTE9CLCIKKyAgICAgICAgICAgICsgIiBMQmxvYiBMT05HQkxPQiwiCisgICAgICAgICAgICArICIgVFRleHQgVElOWVRFWFQsIgorICAgICAgICAgICAgKyAiIFRleHRWYWwgVEVYVCwiCisgICAgICAgICAgICArICIgTVRleHQgTUVESVVNVEVYVCwiCisgICAgICAgICAgICArICIgTFRleHQgTE9OR1RFWFQsIgorICAgICAgICAgICAgKyAiIE1heExvbmdWYWwgQklHSU5ULCIKKyAgICAgICAgICAgICsgIiBNaW5Mb25nVmFsIEJJR0lOVCwiCisgICAgICAgICAgICArICIgdmFsaWRVUkwgVVJMLCIKKyAgICAgICAgICAgICsgIiBpbnZhbGlkVVJMIFVSTCk7IjsKKworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5TRVJUX0FMTF9UWVBFUyA9ICJpbnNlcnQgaW50byB0eXBlICgiCisgICAgICAgICAgICArICJCb29sVmFsLCBJbnRWYWwsIExvbmdWYWwsIEJpbnQsIFRpbnQsIFNpbnQsIE1pbnQsSW50ZWdlclZhbCwgUmVhbFZhbCwgRG91YmxlVmFsLCAiCisgICAgICAgICAgICArICJGbG9hdFZhbCwgRGVjVmFsLE51bVZhbCwgY2hhclN0ciwgZGF0ZVZhbCwgdGltZVZhbCwgVFMsRFQsIFRCbG9iLCBCbG9iVmFsLCBNQmxvYiwgIgorICAgICAgICAgICAgKyAiTEJsb2IsVFRleHQsIFRleHRWYWwsIE1UZXh0LCBMVGV4dCwgTWF4TG9uZ1ZhbCwgTWluTG9uZ1ZhbCwgdmFsaWRVUkwsIGludmFsaWRVUkwpICIKKyAgICAgICAgICAgICsgInZhbHVlcyAoMSwgLTEsIDIyLCAyLCAzMywzLCAxLCAyLCAzLjksIDIzLjIsIDMzLjMsIDQ0LDUsICd0ZXN0IHN0cmluZycsICcxNzk5LTA1LTI2JywiCisgICAgICAgICAgICArICInMTI6MzU6NDUnLCAnMjAwNy0xMC0wOSAxNDoyODowMi4wJywnMTIyMS0wOS0yMiAxMDoxMTo1NScsIDEsIDIsIDMsIDQsIgorICAgICAgICAgICAgKyAiJ1Rlc3QgdGV4dCBtZXNzYWdlIHRpbnknLCAnVGVzdCB0ZXh0JywgJ1Rlc3QgdGV4dCBtZXNzYWdlIG1lZGl1bScsIgorICAgICAgICAgICAgKyAiJ1Rlc3QgdGV4dCBtZXNzYWdlIGxvbmcnLCAiICsgTG9uZy5NQVhfVkFMVUUgKyAiLCAiICsgTG9uZy5NSU5fVkFMVUUgKyAiLCIKKyAgICAgICAgICAgICsgIm51bGwsIG51bGwpOyI7CisKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIEFMTF9UWVBFU19UQUJMRSA9ICJ0eXBlIjsKKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBTdXBwb3J0X1NRTC5sb2FkRHJpdmVyKCk7CisgICAgICAgIGRiID0gbmV3IERhdGFiYXNlKCk7CisgICAgICAgIGRiLm9wZW4oZGJGaWxlLmdldFBhdGgoKSwgMCk7CisgICAgICAgIGRiLmV4ZWMoRGF0YWJhc2VDcmVhdG9yLkNSRUFURV9UQUJMRV9TSU1QTEUxLCBudWxsKTsKKyAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmZpbGxTaW1wbGVUYWJsZTEoY29ubik7CisKKyAgICAgICAgc3QgPSBuZXcgU3RtdCgpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpZiAoc3QgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBkYi5jbG9zZSgpOworICAgICAgICBDb25uZWN0aW9uIGNvbiA9IFN1cHBvcnRfU1FMLmdldENvbm5lY3Rpb24oKTsKKyAgICAgICAgY29uLmNsb3NlKCk7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0bXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZGIucHJlcGFyZSgiIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LnN0ZXAoKTsKKyAgICAgICAgICAgIGZhaWwoIkNhbm5vdCBleGVjdXRlIG5vbiBwcmVwYXJlZCBTdG10Iik7CisgICAgICAgIH0gY2F0Y2ggKFNRTGl0ZS5FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQcmVwYXJlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGRiLnByZXBhcmUoIiIpOworICAgICAgICAgICAgc3QucHJlcGFyZSgpOworICAgICAgICAgICAgZmFpbCgic3RhdGVtZW50IGlzIGNsb3NlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxpdGUuRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInN0bXQgYWxyZWFkeSBjbG9zZWQiLCBleHBlY3RlZC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgc3QgPSBuZXcgU3RtdCgpOworICAgICAgICBzdCA9IGRiLnByZXBhcmUoInNlbGVjdCAqIGZyb20gIiArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc3QucHJlcGFyZSgpKTsKKyAgICAgICAgc3QgPSBuZXcgU3RtdCgpOworICAgICAgICBzdCA9IGRiLnByZXBhcmUoImluc2VydCBpbnRvICIgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMQorICAgICAgICAgICAgICAgICsgIiB2YWx1ZXMgKDpvbmUsOnR3byw6dGhyZWUpIik7CisgICAgICAgIGFzc2VydEZhbHNlKHN0LnByZXBhcmUoKSk7CisgICAgICAgIHN0ID0gbmV3IFN0bXQoKTsKKyAgICAgICAgc3QgPSBkYi5wcmVwYXJlKCJpbnNlcnQgaW50byAiICsgRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgdmFsdWVzICg6b25lLDp0d28sOnRocmVlKSIpOworICAgICAgICBzdC5iaW5kKDEsIDEpOworICAgICAgICBzdC5iaW5kKDIsIDEwKTsKKyAgICAgICAgc3QuYmluZCgzLCAzMCk7CisgICAgICAgIGFzc2VydEZhbHNlKHN0LnByZXBhcmUoKSk7CisgICAgICAgIHN0ID0gZGIucHJlcGFyZSgic2VsZWN0ICogZnJvbSAiICsgRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTEKKyAgICAgICAgICAgICAgICArICI7ICIgKyAiZGVsZXRlIGZyb20gIiArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxCisgICAgICAgICAgICAgICAgKyAiIHdoZXJlIGlkID0gNTsgIiArICJpbnNlcnQgaW50byAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMSArICIgdmFsdWVzKDUsIDEwLCAyMCk7ICIKKyAgICAgICAgICAgICAgICArICJzZWxlY3QgKiBmcm9tICIgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMSArICI7Iik7CisgICAgICAgIGFzc2VydFRydWUoc3QucHJlcGFyZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzdC5wcmVwYXJlKCkpOworICAgICAgICBhc3NlcnRUcnVlKHN0LnByZXBhcmUoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHN0LnByZXBhcmUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0ZXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LnN0ZXAoKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxpdGUuRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInN0bXQgYWxyZWFkeSBjbG9zZWQiLCBleHBlY3RlZC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgc3QgPSBuZXcgU3RtdCgpOworICAgICAgICBzdCA9IGRiLnByZXBhcmUoInNlbGVjdCBuYW1lIGZyb20gc3FsaXRlX21hc3RlciB3aGVyZSB0eXBlID0gJ3RhYmxlJyIpOworICAgICAgICBzdC5zdGVwKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENsb3NlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN0ID0gZGIucHJlcGFyZSgiaW5zZXJ0IGludG8gIiArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxCisgICAgICAgICAgICAgICAgKyAiIHZhbHVlcyAoOm9uZSw6dHdvLDp0aHJlZSkiKTsKKyAgICAgICAgc3QuY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3Quc3RlcCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCBmYWlscyIpOworICAgICAgICB9IGNhdGNoIChTUUxpdGUuRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInN0bXQgYWxyZWFkeSBjbG9zZWQiLCBleHBlY3RlZC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlc2V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRiLmV4ZWMoImNyZWF0ZSB0YWJsZSBURVNUIChyZXMgaW50ZWdlciBub3QgbnVsbCkiLCBudWxsKTsKKworICAgICAgICBzdCA9IGRiLnByZXBhcmUoImluc2VydCBpbnRvIFRFU1QgdmFsdWVzICg6b25lKTsiKTsKKyAgICAgICAgc3QuYmluZCgxLCAxKTsKKyAgICAgICAgc3Quc3RlcCgpOworCisgICAgICAgIC8vIHZlcmlmeSB0aGF0IHBhcmFtZXRlciBpcyBzdGlsbCBib3VuZAorICAgICAgICBzdC5yZXNldCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSxzdC5iaW5kX3BhcmFtZXRlcl9jb3VudCgpKTsKKyAgICAgICAgc3Quc3RlcCgpOworCisgICAgICAgIFRhYmxlUmVzdWx0IGNvdW50ID0gZGIuZ2V0X3RhYmxlKCJzZWxlY3QgY291bnQoKikgZnJvbSBURVNUIHdoZXJlIHJlcz0xIiwgbnVsbCk7CisKKyAgICAgICAgU3RyaW5nW10gcm93MCA9IChTdHJpbmdbXSkgY291bnQucm93cy5lbGVtZW50QXQoMCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBJbnRlZ2VyLnBhcnNlSW50KHJvdzBbMF0pKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xlYXJfYmluZGluZ3MoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5jbGVhcl9iaW5kaW5ncygpOworICAgICAgICB9IGNhdGNoIChTUUxpdGUuRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInVuc3VwcG9ydGVkIiwgZXhwZWN0ZWQuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCaW5kSW50SW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBpbnB1dCA9IDA7CisgICAgICAgIGludCBtYXhWYWwgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgICAgICAgaW50IG1pblZhbCA9IEludGVnZXIuTUlOX1ZBTFVFOworCisgICAgICAgIGRiLmV4ZWMoImNyZWF0ZSB0YWJsZSBURVNUIChyZXMgaW50ZWdlcikiLCBudWxsKTsKKyAgICAgICAgc3QgPSBkYi5wcmVwYXJlKCJpbnNlcnQgaW50byBURVNUIHZhbHVlcyAoOm9uZSk7Iik7CisgICAgICAgIHN0LmJpbmQoMSwgaW5wdXQpOworICAgICAgICBzdC5zdGVwKCk7CisKKyAgICAgICAgc3QucmVzZXQoKTsKKyAgICAgICAgc3QuYmluZCgxLG1heFZhbCk7CisgICAgICAgIHN0LnN0ZXAoKTsKKworICAgICAgICBzdC5yZXNldCgpOworICAgICAgICBzdC5iaW5kKDEsbWluVmFsKTsKKyAgICAgICAgc3Quc3RlcCgpOworCisgICAgICAgIFRhYmxlUmVzdWx0IHIgPSBkYi5nZXRfdGFibGUoInNlbGVjdCAqIGZyb20gVEVTVCIpOworCisgICAgICAgIFN0cmluZ1tdIHJvdzAgPSAoU3RyaW5nW10pIHIucm93cy5lbGVtZW50QXQoMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhpbnB1dCxJbnRlZ2VyLnBhcnNlSW50KHJvdzBbMF0pKTsKKworICAgICAgICBTdHJpbmdbXSByb3cxID0gKFN0cmluZ1tdKSByLnJvd3MuZWxlbWVudEF0KDEpOworICAgICAgICBhc3NlcnRFcXVhbHMobWF4VmFsLEludGVnZXIucGFyc2VJbnQocm93MVswXSkpOworCisgICAgICAgIFN0cmluZ1tdIHJvdzIgPSAoU3RyaW5nW10pIHIucm93cy5lbGVtZW50QXQoMik7CisgICAgICAgIGFzc2VydEVxdWFscyhtaW5WYWwsSW50ZWdlci5wYXJzZUludChyb3cyWzBdKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICBzdC5iaW5kKDEsSW50ZWdlci5NSU5fVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTGl0ZS5FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCaW5kSW50TG9uZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBsb25nIGlucHV0ID0gMDsKKyAgICAgICAgbG9uZyBtYXhWYWwgPSBMb25nLk1BWF9WQUxVRTsKKyAgICAgICAgbG9uZyBtaW5WYWwgPSBMb25nLk1JTl9WQUxVRTsKKworICAgICAgICBkYi5leGVjKCJjcmVhdGUgdGFibGUgVEVTVCAocmVzIGxvbmcpIiwgbnVsbCk7CisgICAgICAgIHN0ID0gZGIucHJlcGFyZSgiaW5zZXJ0IGludG8gVEVTVCB2YWx1ZXMgKDpvbmUpOyIpOworICAgICAgICBzdC5iaW5kKDEsIGlucHV0KTsKKyAgICAgICAgc3Quc3RlcCgpOworCisgICAgICAgIHN0LnJlc2V0KCk7CisgICAgICAgIHN0LmJpbmQoMSxtYXhWYWwpOworICAgICAgICBzdC5zdGVwKCk7CisKKyAgICAgICAgc3QucmVzZXQoKTsKKyAgICAgICAgc3QuYmluZCgxLG1pblZhbCk7CisgICAgICAgIHN0LnN0ZXAoKTsKKworICAgICAgICBUYWJsZVJlc3VsdCByID0gZGIuZ2V0X3RhYmxlKCJzZWxlY3QgKiBmcm9tIFRFU1QiKTsKKworICAgICAgICBTdHJpbmdbXSByb3cwID0gKFN0cmluZ1tdKSByLnJvd3MuZWxlbWVudEF0KDApOworICAgICAgICBhc3NlcnRFcXVhbHMoaW5wdXQsTG9uZy5wYXJzZUxvbmcocm93MFswXSkpOworCisgICAgICAgIFN0cmluZ1tdIHJvdzEgPSAoU3RyaW5nW10pIHIucm93cy5lbGVtZW50QXQoMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtYXhWYWwsTG9uZy5wYXJzZUxvbmcocm93MVswXSkpOworCisgICAgICAgIFN0cmluZ1tdIHJvdzIgPSAoU3RyaW5nW10pIHIucm93cy5lbGVtZW50QXQoMik7CisgICAgICAgIGFzc2VydEVxdWFscyhtaW5WYWwsTG9uZy5wYXJzZUxvbmcocm93MlswXSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgc3QuYmluZCgxLExvbmcuTUlOX1ZBTFVFKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxpdGUuRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QmluZEludERvdWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkb3VibGUgaW5wdXQgPSAwLjA7CisgICAgICAgIGRvdWJsZSBtYXhWYWwgPSBEb3VibGUuTUFYX1ZBTFVFOworICAgICAgICBkb3VibGUgbWluVmFsID0gRG91YmxlLk1JTl9WQUxVRTsKKyAgICAgICAgZG91YmxlIG5lZ0luZiA9IERvdWJsZS5ORUdBVElWRV9JTkZJTklUWTsKKyAgICAgICAgZG91YmxlIHBvc0luZiA9IERvdWJsZS5QT1NJVElWRV9JTkZJTklUWTsKKyAgICAgICAgZG91YmxlIG5hbiA9IERvdWJsZS5OYU47CisKKyAgICAgICAgZGIuZXhlYygiY3JlYXRlIHRhYmxlIFRFU1QgKHJlcyBkb3VibGUpIiwgbnVsbCk7CisgICAgICAgIHN0ID0gZGIucHJlcGFyZSgiaW5zZXJ0IGludG8gVEVTVCB2YWx1ZXMgKDpvbmUpOyIpOworICAgICAgICBzdC5iaW5kKDEsIGlucHV0KTsKKyAgICAgICAgc3Quc3RlcCgpOworCisgICAgICAgIHN0LnJlc2V0KCk7CisgICAgICAgIHN0LmJpbmQoMSwgbWF4VmFsKTsKKyAgICAgICAgc3Quc3RlcCgpOworCisgICAgICAgIHN0LnJlc2V0KCk7CisgICAgICAgIHN0LmJpbmQoMSwgbWluVmFsKTsKKyAgICAgICAgc3Quc3RlcCgpOworCisgICAgICAgIHN0LnJlc2V0KCk7CisgICAgICAgIHN0LmJpbmQoMSwgbmVnSW5mKTsKKyAgICAgICAgc3Quc3RlcCgpOworCisgICAgICAgIHN0LnJlc2V0KCk7CisgICAgICAgIHN0LmJpbmQoMSwgcG9zSW5mKTsKKyAgICAgICAgc3Quc3RlcCgpOworCisgICAgICAgIHN0LnJlc2V0KCk7CisgICAgICAgIHN0LmJpbmQoMSwgbmFuKTsKKyAgICAgICAgc3Quc3RlcCgpOworCisKKyAgICAgICAgVGFibGVSZXN1bHQgciA9IGRiLmdldF90YWJsZSgic2VsZWN0ICogZnJvbSBURVNUIik7CisKKyAgICAgICAgU3RyaW5nW10gcm93MCA9IChTdHJpbmdbXSkgci5yb3dzLmVsZW1lbnRBdCgwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShEb3VibGUuY29tcGFyZShpbnB1dCwgRG91YmxlLnBhcnNlRG91YmxlKHJvdzBbMF0pKSA9PSAwKTsKKworICAgICAgICBTdHJpbmdbXSByb3cxID0gKFN0cmluZ1tdKSByLnJvd3MuZWxlbWVudEF0KDEpOworICAgICAgICBhc3NlcnRGYWxzZShEb3VibGUuY29tcGFyZShtYXhWYWwsIERvdWJsZS5wYXJzZURvdWJsZShyb3cxWzBdKSkgPT0gMCk7CisgICAgICAgIGFzc2VydFRydWUoRG91YmxlLmNvbXBhcmUobWF4VmFsLCBEb3VibGUucGFyc2VEb3VibGUocm93MVswXSkpIDwgMCk7CisgICAgICAgIGFzc2VydFRydWUoRG91YmxlLmlzSW5maW5pdGUoRG91YmxlLnBhcnNlRG91YmxlKHJvdzFbMF0pKSk7CisKKyAgICAgICAgU3RyaW5nW10gcm93MiA9IChTdHJpbmdbXSkgci5yb3dzLmVsZW1lbnRBdCgyKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShEb3VibGUuY29tcGFyZShtaW5WYWwsIERvdWJsZS5wYXJzZURvdWJsZShyb3cyWzBdKSkgPT0gMCk7CisKKyAgICAgICAgU3RyaW5nW10gcm93MyA9IChTdHJpbmdbXSkgci5yb3dzLmVsZW1lbnRBdCgzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkgU1FMaXRlIHJlcHJlc2VudGF0aW9uIiwKKyAgICAgICAgICAgICAgICAiLUluZiIsIHJvdzNbMF0pOworCisgICAgICAgIFN0cmluZ1tdIHJvdzQgPSAoU3RyaW5nW10pIHIucm93cy5lbGVtZW50QXQoNCk7CisgICAgICAgIGFzc2VydEVxdWFscygiRG91YmxlLlBPU0lUSVZFX0lORklOSVRZIFNRTGl0ZSByZXByZXNlbnRhdGlvbiIsCisgICAgICAgICAgICAgICAgIkluZiIsIHJvdzRbMF0pOworCisgICAgICAgIFN0cmluZ1tdIHJvdzUgPSAoU3RyaW5nW10pIHIucm93cy5lbGVtZW50QXQoNCk7CisgICAgICAgIGFzc2VydEVxdWFscygiRG91YmxlLk5hbiBTUUxpdGUgcmVwcmVzZW50YXRpb24iLCAiSW5mIiwgcm93NVswXSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LmNsb3NlKCk7CisgICAgICAgICAgICBzdC5iaW5kKDEsMC4wKTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxpdGUuRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QmluZEludEJ5dGVBcnJheSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbmFtZSA9ICJIZWxsbyBXb3JsZCI7CisgICAgICAgIGJ5dGVbXSBiID0gbmFtZS5nZXRCeXRlcygpOworICAgICAgICBTdHJpbmcgc3RyaW5nSW5IZXggPSAiIjsKKworICAgICAgICBkYi5leGVjKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEVfUEFSRU5ULCBudWxsKTsKKyAgICAgICAgc3QgPSBkYi5wcmVwYXJlKCJpbnNlcnQgaW50byAiICsgRGF0YWJhc2VDcmVhdG9yLlBBUkVOVF9UQUJMRQorICAgICAgICAgICAgICAgICsgIiB2YWx1ZXMgKDpvbmUsIDp0d28pOyIpOworICAgICAgICBzdC5iaW5kKDEsIDIpOworICAgICAgICBzdC5iaW5kKDIsIGIpOworICAgICAgICBzdC5zdGVwKCk7CisKKyAgICAgICAgLy9jb21wYXJlIHdoYXQgd2FzIHN0b3JlZCB3aXRoIGlucHV0IGJhc2VkIG9uIEhleCByZXByZXNlbnRhdGlvbgorICAgICAgICAvLyBzaW5jZSB0eXBlIG9mIGNvbHVtbiBpcyBDSEFSCisgICAgICAgIFRhYmxlUmVzdWx0IHIgPSBkYi5nZXRfdGFibGUoInNlbGVjdCAqIGZyb20gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlBBUkVOVF9UQUJMRSk7CisgICAgICAgIFN0cmluZ1tdIHJvdyA9IChTdHJpbmdbXSkgci5yb3dzLmVsZW1lbnRBdCgwKTsKKworICAgICAgICBmb3IgKGJ5dGUgYUJ5dGUgOiBiKSB7CisgICAgICAgICAgICBzdHJpbmdJbkhleCArPSBJbnRlZ2VyLnRvSGV4U3RyaW5nKGFCeXRlKTsKKyAgICAgICAgfQorICAgICAgICBzdHJpbmdJbkhleCA9ICJYJyIgKyBzdHJpbmdJbkhleCArICInIjsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzdHJpbmdJbkhleC5lcXVhbHNJZ25vcmVDYXNlKHJvd1sxXSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgc3QuYmluZCgxLG5hbWUuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMaXRlLkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEJpbmRJbnRTdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSAiSGVsbG8gV29ybGQiOworICAgICAgICBkYi5leGVjKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEVfUEFSRU5ULCBudWxsKTsKKyAgICAgICAgc3QgPSBkYi5wcmVwYXJlKCJpbnNlcnQgaW50byAiICsgRGF0YWJhc2VDcmVhdG9yLlBBUkVOVF9UQUJMRQorICAgICAgICAgICAgICAgICsgIiB2YWx1ZXMgKDpvbmUsIDp0d28pOyIpOworICAgICAgICBzdC5iaW5kKDEsIDIpOworICAgICAgICBzdC5iaW5kKDIsIG5hbWUpOworICAgICAgICBzdC5zdGVwKCk7CisKKyAgICAgICAgVGFibGVSZXN1bHQgciA9IGRiLmdldF90YWJsZSgic2VsZWN0ICogZnJvbSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuUEFSRU5UX1RBQkxFKTsKKyAgICAgICAgU3RyaW5nW10gcm93ID0gKFN0cmluZ1tdKSByLnJvd3MuZWxlbWVudEF0KDApOworICAgICAgICBhc3NlcnRFcXVhbHMobmFtZSxyb3dbMV0pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5jbG9zZSgpOworICAgICAgICAgICAgc3QuYmluZCgxLG5hbWUpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTGl0ZS5FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCaW5kSW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGRiLnByZXBhcmUoImluc2VydCBpbnRvICIgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMQorICAgICAgICAgICAgICAgICAgICArICIgdmFsdWVzICg6b25lLDp0d28sOnRocmVlKSIpOworICAgICAgICAgICAgc3QuYmluZCg0KTsKKyAgICAgICAgICAgIHN0LmJpbmQoMSwgNCk7CisgICAgICAgICAgICBzdC5iaW5kKDIsIDEwKTsKKyAgICAgICAgICAgIHN0LmJpbmQoMywgMzApOworICAgICAgICAgICAgc3Quc3RlcCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTUUxpdGUuRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAvLyBXaGF0IGhhcHBlbnMgaWYgbnVsbCBpcyBib3VuZCB0byBub24gZXhpc3RpbmcgdmFyaWFibGUgcG9zaXRpb24KKyAgICAgICAgICAgIGFzc2VydEVxdWFscygicGFyYW1ldGVyIHBvc2l0aW9uIG91dCBvZiBib3VuZHMiLCBleHBlY3RlZC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gZnVuY3Rpb25hbCB0ZXN0cworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5yZXNldCgpOworICAgICAgICAgICAgc3QuYmluZCgxKTsKKyAgICAgICAgICAgIHN0LmJpbmQoMiwgMTApOworICAgICAgICAgICAgc3QuYmluZCgzLCAzMCk7CisgICAgICAgICAgICBzdC5zdGVwKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNRTGl0ZS5FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIC8vIFdoYXQgaGFwcGVucyBpZiBudWxsIGlzIGJvdW5kIHRvIE5PTiBOVUxMIGZpZWxkCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlNRTCBsb2dpYyBlcnJvciBvciBtaXNzaW5nIGRhdGFiYXNlIiwgZXhwZWN0ZWQuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHN0LnJlc2V0KCk7CisgICAgICAgIHN0LmJpbmQoMSwgMyk7CisgICAgICAgIHN0LmJpbmQoMik7CisgICAgICAgIHN0LmJpbmQoMywgMzApOworICAgICAgICBzdC5zdGVwKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEJpbmRfemVyb2Jsb2IoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5iaW5kX3plcm9ibG9iKDEsIDEyOCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNRTGl0ZS5FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygidW5zdXBwb3J0ZWQiLCBleHBlY3RlZC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEJpbmRfcGFyYW1ldGVyX2NvdW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5iaW5kX3BhcmFtZXRlcl9jb3VudCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTUUxpdGUuRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInN0bXQgYWxyZWFkeSBjbG9zZWQiLCBleHBlY3RlZC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgc3QgPSBkYi5wcmVwYXJlKCJpbnNlcnQgaW50byAiICsgRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgdmFsdWVzICg6b25lLDp0d28sOnRocmVlKSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgc3QuYmluZF9wYXJhbWV0ZXJfY291bnQoKSk7CisKKyAgICAgICAgc3QgPSBkYi5wcmVwYXJlKCJpbnNlcnQgaW50byAiICsgRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgdmFsdWVzICg/LCA/LCA/KSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgc3QuYmluZF9wYXJhbWV0ZXJfY291bnQoKSk7CisKKyAgICAgICAgc3QgPSBkYi5wcmVwYXJlKCJzZWxlY3QgKiBmcm9tICIgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBzdC5iaW5kX3BhcmFtZXRlcl9jb3VudCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgICAgICAgIHN0LmJpbmRfcGFyYW1ldGVyX2NvdW50KCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMaXRlLkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QmluZF9wYXJhbWV0ZXJfbmFtZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LmJpbmRfcGFyYW1ldGVyX25hbWUoMSk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMaXRlLkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdG10IGFscmVhZHkgY2xvc2VkIiwgZXhwZWN0ZWQuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGRiLnByZXBhcmUoImluc2VydCBpbnRvICIgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMQorICAgICAgICAgICAgICAgICAgICArICIgdmFsdWVzICg6b25lLDp0d28sOnRocmVlKSIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCI6b25lIiwgc3QuYmluZF9wYXJhbWV0ZXJfbmFtZSgxKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIjp0d28iLCBzdC5iaW5kX3BhcmFtZXRlcl9uYW1lKDIpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiOnRocmVlIiwgc3QuYmluZF9wYXJhbWV0ZXJfbmFtZSgzKSk7CisgICAgICAgICAgICBzdC5iaW5kX3BhcmFtZXRlcl9uYW1lKDQpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTUUxpdGUuRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInBhcmFtZXRlciBwb3NpdGlvbiBvdXQgb2YgYm91bmRzIiwgZXhwZWN0ZWQuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCaW5kX3BhcmFtZXRlcl9pbmRleCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QuYmluZF9wYXJhbWV0ZXJfaW5kZXgoIiIpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTGl0ZS5FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygic3RtdCBhbHJlYWR5IGNsb3NlZCIsIGV4cGVjdGVkLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBzdCA9IGRiLnByZXBhcmUoImluc2VydCBpbnRvICIgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMQorICAgICAgICAgICAgICAgICsgIiB2YWx1ZXMgKDpvbmUsOnR3byw6dGhyZWUpIik7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBzdC5iaW5kX3BhcmFtZXRlcl9pbmRleCgiOnRocmVlIikpOworCisgICAgICAgIHN0ID0gZGIucHJlcGFyZSgiaW5zZXJ0IGludG8gIiArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxCisgICAgICAgICAgICAgICAgKyAiIHZhbHVlcyAoOm9uZSw6dHdvLDp0aHJlZSkiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHN0LmJpbmRfcGFyYW1ldGVyX2luZGV4KCI6dCIpKTsKKworICAgICAgICBzdCA9IGRiLnByZXBhcmUoImluc2VydCBpbnRvICIgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMQorICAgICAgICAgICAgICAgICsgIiB2YWx1ZXMgKD8sID8sID8pIik7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBzdC5iaW5kX3BhcmFtZXRlcl9pbmRleCgiPyIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29sdW1uX2ludCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkYi5leGVjKENSRUFURV9BTExfVFlQRVMsIG51bGwpOworICAgICAgICBkYi5leGVjKElOU0VSVF9BTExfVFlQRVMsIG51bGwpOworCisgICAgICAgIE9iamVjdCBjb2x1bW5PYmplY3Q7CisgICAgICAgIGludCBpbnRDb2x1bW47CisgICAgICAgIFN0cmluZyBzZWxlY3RTdG10ID0gInNlbGVjdCAqIGZyb20gIitEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMTsKKworICAgICAgICBzdCA9IGRiLnByZXBhcmUoc2VsZWN0U3RtdCk7CisgICAgICAgIHN0LnN0ZXAoKTsKKyAgICAgICAgLy8gc2VsZWN0ICdzcGVlZCcgdmFsdWUKKyAgICAgICAgY29sdW1uT2JqZWN0ID0gc3QuY29sdW1uKDEpOworICAgICAgICBpbnRDb2x1bW4gPSBzdC5jb2x1bW5faW50KDEpOworICAgICAgICBhc3NlcnROb3ROdWxsKGludENvbHVtbik7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW50ZWdlciIuZXF1YWxzSWdub3JlQ2FzZShzdC5jb2x1bW5fZGVjbHR5cGUoMSkpKTsKKyAgICAgICAgaW50IHN0U3BlZWQgPSBJbnRlZ2VyLnBhcnNlSW50KGNvbHVtbk9iamVjdC50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzdFNwZWVkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCBpbnRDb2x1bW4sIHN0U3BlZWQpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTAsc3RTcGVlZCk7CisKKyAgICAgICAgc2VsZWN0U3RtdCA9ICJzZWxlY3QgVGV4dFZhbCBmcm9tICIrIEFMTF9UWVBFU19UQUJMRTsKKworICAgICAgICBzdCA9IGRiLnByZXBhcmUoc2VsZWN0U3RtdCk7CisgICAgICAgIHN0LnN0ZXAoKTsKKyAgICAgICAgc3QuY29sdW1uX2ludCgwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29sdW1uX2xvbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0IGNvbHVtbk9iamVjdDsKKyAgICAgICAgbG9uZyBsb25nQ29sdW1uOworICAgICAgICBTdHJpbmcgc2VsZWN0U3RtdCA9ICJzZWxlY3QgKiBmcm9tICIrRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTE7CisgICAgICAgIHN0ID0gZGIucHJlcGFyZShzZWxlY3RTdG10KTsKKyAgICAgICAgc3Quc3RlcCgpOworICAgICAgICBjb2x1bW5PYmplY3QgPSBzdC5jb2x1bW4oMSk7CisgICAgICAgIGxvbmdDb2x1bW4gPSBzdC5jb2x1bW5fbG9uZygxKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChsb25nQ29sdW1uKTsKKyAgICAgICAgLy8gY29sdW1uIGRlY2xhcmVkIGFzIGludGVnZXIKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW50ZWdlciIuZXF1YWxzSWdub3JlQ2FzZShzdC5jb2x1bW5fZGVjbHR5cGUoMSkpKTsKKyAgICAgICAgaW50IHN0U3BlZWQgPSBJbnRlZ2VyLnBhcnNlSW50KGNvbHVtbk9iamVjdC50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzdFNwZWVkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCBsb25nQ29sdW1uLCBzdFNwZWVkKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QuY29sdW1uX2xvbmcoNCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMaXRlLkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJjb2x1bW4gb3V0IG9mIGJvdW5kcyIsIGV4cGVjdGVkLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QuY29sdW1uX2xvbmcoLTEpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTGl0ZS5FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiY29sdW1uIG91dCBvZiBib3VuZHMiLCBleHBlY3RlZC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbHVtbl9kb3VibGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZGIuZXhlYyhDUkVBVEVfQUxMX1RZUEVTLCBudWxsKTsKKyAgICAgICAgZGIuZXhlYyhJTlNFUlRfQUxMX1RZUEVTLCBudWxsKTsKKworICAgICAgICBkb3VibGUgZG91YmxlQ29sdW1uOworICAgICAgICBkb3VibGUgYWN0dWFsVmFsID0gMjMuMjsKKyAgICAgICAgU3RyaW5nIHNlbGVjdFN0bXQgPSAic2VsZWN0IERvdWJsZVZhbCBmcm9tICIrIEFMTF9UWVBFU19UQUJMRTsKKworICAgICAgICBzdCA9IGRiLnByZXBhcmUoc2VsZWN0U3RtdCk7CisgICAgICAgIHN0LnN0ZXAoKTsKKyAgICAgICAgLy8gc2VsZWN0IGRvdWJsZSB2YWx1ZQorICAgICAgICBkb3VibGVDb2x1bW4gPSBzdC5jb2x1bW5fZG91YmxlKDApOworICAgICAgICBhc3NlcnROb3ROdWxsKGRvdWJsZUNvbHVtbik7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRE9VQkxFIi5lcXVhbHNJZ25vcmVDYXNlKHN0LmNvbHVtbl9kZWNsdHlwZSgwKSkpOworICAgICAgICBhc3NlcnROb3ROdWxsKGRvdWJsZUNvbHVtbik7CisgICAgICAgIGFzc2VydEVxdWFscyggYWN0dWFsVmFsLCBkb3VibGVDb2x1bW4pOworCisgICAgICAgIC8vIEV4Y2VwdGlvbiB0ZXN0CisgICAgICAgIHNlbGVjdFN0bXQgPSAic2VsZWN0IGRhdGVWYWwgZnJvbSAiKyBBTExfVFlQRVNfVEFCTEU7CisKKyAgICAgICAgc3QgPSBkYi5wcmVwYXJlKHNlbGVjdFN0bXQpOworICAgICAgICBzdC5zdGVwKCk7CisgICAgICAgIC8vIHNlbGVjdCBkb3VibGUgdmFsdWUKKyAgICAgICAgc3QuY29sdW1uX2RvdWJsZSgwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29sdW1uX2J5dGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRiLmV4ZWMoImNyZWF0ZSB0YWJsZSBCKGlkIGludGVnZXIgcHJpbWFyeSBrZXksIHZhbCBibG9iKSIsbnVsbCk7CisgICAgICAgIGRiLmV4ZWMoImluc2VydCBpbnRvIEIgdmFsdWVzKDEsIHplcm9ibG9iKDEyOCkpIiwgbnVsbCk7CisgICAgICAgIHN0ID0gZGIucHJlcGFyZSgic2VsZWN0IHZhbCBmcm9tIEIgd2hlcmUgaWQgPSAxIik7CisgICAgICAgIGFzc2VydFRydWUoc3Quc3RlcCgpKTsKKyAgICAgICAgc3QuY29sdW1uX2J5dGVzKDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb2x1bW5fc3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRiLmV4ZWMoQ1JFQVRFX0FMTF9UWVBFUywgbnVsbCk7CisgICAgICAgIGRiLmV4ZWMoSU5TRVJUX0FMTF9UWVBFUywgbnVsbCk7CisKKyAgICAgICAgU3RyaW5nIHN0cmluZ0NvbHVtbjsKKyAgICAgICAgU3RyaW5nIGFjdHVhbFZhbCA9ICJ0ZXN0IHN0cmluZyI7CisgICAgICAgIFN0cmluZyBzZWxlY3RTdG10ID0gInNlbGVjdCBjaGFyU3RyIGZyb20gIisgQUxMX1RZUEVTX1RBQkxFOworCisgICAgICAgIHN0ID0gZGIucHJlcGFyZShzZWxlY3RTdG10KTsKKyAgICAgICAgc3Quc3RlcCgpOworICAgICAgICAvLyBzZWxlY3Qgc3RyaW5nIHZhbHVlCisgICAgICAgIHN0cmluZ0NvbHVtbiA9IHN0LmNvbHVtbl9zdHJpbmcoMCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoc3RyaW5nQ29sdW1uKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJDSEFSKDIwKSIuZXF1YWxzSWdub3JlQ2FzZShzdC5jb2x1bW5fZGVjbHR5cGUoMCkpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzdHJpbmdDb2x1bW4pOworICAgICAgICBhc3NlcnRFcXVhbHMoIGFjdHVhbFZhbCwgc3RyaW5nQ29sdW1uKTsKKworICAgICAgICAvLyBFeGNlcHRpb24gdGVzdAorICAgICAgICBzZWxlY3RTdG10ID0gInNlbGVjdCBEb3VibGVWYWwgZnJvbSAiKyBBTExfVFlQRVNfVEFCTEU7CisKKyAgICAgICAgc3QgPSBkYi5wcmVwYXJlKHNlbGVjdFN0bXQpOworICAgICAgICBzdC5zdGVwKCk7CisgICAgICAgIHN0LmNvbHVtbl9zdHJpbmcoMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbHVtbl90eXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRiLmV4ZWMoQ1JFQVRFX0FMTF9UWVBFUywgbnVsbCk7CisgICAgICAgIGRiLmV4ZWMoSU5TRVJUX0FMTF9UWVBFUywgbnVsbCk7CisgICAgICAgIHN0ID0gZGIucHJlcGFyZSgic2VsZWN0ICogZnJvbSAiICsgQUxMX1RZUEVTX1RBQkxFKTsKKyAgICAgICAgc3Quc3RlcCgpOworCisgICAgICAgIC8vIEV4Y2VwdGlvbiB0ZXN0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5jb2x1bW5fdHlwZSgxMDApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTUUxpdGUuRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICBEaWN0aW9uYXJ5CisKKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1FMSVRFX0lOVEVHRVIgPSAxOworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTUUxJVEVfRkxPQVQgPSAyOworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTUUxJVEVfQkxPQiA9IDQ7CisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNRTElURV9OVUxMID0gNTsKKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1FMSVRFM19URVhUID0gMzsKKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1FMSVRFX05VTUVSSUMgPSAtMTsKKyAgICAgICAgKi8KKworICAgICAgICBhc3NlcnRFcXVhbHMoQ29uc3RhbnRzLlNRTElURTNfVEVYVCwgc3QuY29sdW1uX3R5cGUoMjMpKTsgLy8gb2sgVEVYVAorICAgICAgICBhc3NlcnRFcXVhbHMoQ29uc3RhbnRzLlNRTElURTNfVEVYVCwgc3QuY29sdW1uX3R5cGUoMTMpKTsgLy8gQ0hBUigyMCkKKworICAgICAgICBhc3NlcnRFcXVhbHMoQ29uc3RhbnRzLlNRTElURV9GTE9BVCwgc3QuY29sdW1uX3R5cGUoOCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29uc3RhbnRzLlNRTElURV9GTE9BVCwgc3QuY29sdW1uX3R5cGUoOSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29uc3RhbnRzLlNRTElURV9GTE9BVCwgc3QuY29sdW1uX3R5cGUoMTApKTsgLy8gRkxPQVQKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJFeHBlY3RlZCBJbnRlZ2VyIGF0IHBvc2l0aW9uICIgKyBpLAorICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuU1FMSVRFX0lOVEVHRVIsIHN0LmNvbHVtbl90eXBlKGkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscyhDb25zdGFudHMuU1FMSVRFX05VTEwsIHN0LmNvbHVtbl90eXBlKDI4KSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb25zdGFudHMuU1FMSVRFX05VTEwsIHN0LmNvbHVtbl90eXBlKDI5KSk7CisKKyAgICAgICAgLy8gRmFpbGluZyB0ZXN0cworICAgICAgICBhc3NlcnRUcnVlKCJJTlRFR0VSIi5lcXVhbHNJZ25vcmVDYXNlKHN0LmNvbHVtbl9kZWNsdHlwZSgxMikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENvbnN0YW50cy5TUUxJVEVfSU5URUdFUiwgc3QuY29sdW1uX3R5cGUoMTIpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJGTE9BVCIuZXF1YWxzSWdub3JlQ2FzZShzdC5jb2x1bW5fZGVjbHR5cGUoMTEpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb25zdGFudHMuU1FMSVRFX0ZMT0FULCBzdC5jb2x1bW5fdHlwZSgxMSkpOyAvLyBGTE9BVCAtPgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ290IElOVEVHRVIKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQkxPQiIuZXF1YWxzSWdub3JlQ2FzZShzdC5jb2x1bW5fZGVjbHR5cGUoMTkpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDb25zdGFudHMuU1FMSVRFX0JMT0IsIHN0LmNvbHVtbl90eXBlKDE5KSk7IC8vIEJsb2IgZ290CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElOVEVHRVIKKworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyb25nIHZhbHVlIGlzIHJldHVybmVkIGluIGNhc2Ugb2YgYSBwcmVwYXJlZCBzdGF0ZW1lbnQgdG8gd2hpY2ggYSAnKicgYm91bmQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29sdW1uX2NvdW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzZWxlY3RTdG10ID0gInNlbGVjdCAqIGZyb20gIitEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMTsKKyAgICAgICAgc3QgPSBkYi5wcmVwYXJlKHNlbGVjdFN0bXQpOworCisgICAgICAgIGFzc2VydEVxdWFscygzLCBzdC5jb2x1bW5fY291bnQoKSk7CisKKyAgICAgICAgc3Quc3RlcCgpOworICAgICAgICBpbnQgY29sdW1uQ291bnQgPSBzdC5jb2x1bW5fY291bnQoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjb2x1bW5Db3VudCk7CisgICAgICAgIGFzc2VydEVxdWFscyggMywgY29sdW1uQ291bnQpOworCisgICAgICAgIC8vIGFjdHVhbCBwcmVwYXJlZCBzdGF0ZW1lbnQKKyAgICAgICAgc2VsZWN0U3RtdCA9ICJzZWxlY3QgPyBmcm9tICIrRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTE7CisgICAgICAgIHN0ID0gZGIucHJlcGFyZShzZWxlY3RTdG10KTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMywgc3QuY29sdW1uX2NvdW50KCkpOworCisgICAgICAgIHN0LmJpbmQoMSwgIioiKTsKKyAgICAgICAgc3Quc3RlcCgpOworICAgICAgICBjb2x1bW5Db3VudCA9IHN0LmNvbHVtbl9jb3VudCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKGNvbHVtbkNvdW50KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCAzLCBjb2x1bW5Db3VudCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbHVtbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBPYmplY3QgY29sdW1uT2JqZWN0OworICAgICAgICBpbnQgaW50Q29sdW1uOworICAgICAgICBTdHJpbmcgc2VsZWN0U3RtdCA9ICJzZWxlY3QgKiBmcm9tICIrRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTE7CisgICAgICAgIGRiLmdldF90YWJsZShzZWxlY3RTdG10KTsKKyAgICAgICAgc3QgPSBkYi5wcmVwYXJlKHNlbGVjdFN0bXQpOworICAgICAgICBzdC5zdGVwKCk7CisgICAgICAgIGNvbHVtbk9iamVjdCA9IHN0LmNvbHVtbigxKTsKKyAgICAgICAgaW50Q29sdW1uID0gc3QuY29sdW1uX2ludCgxKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChpbnRDb2x1bW4pOworICAgICAgICBhc3NlcnRUcnVlKCJJbnRlZ2VyIi5lcXVhbHNJZ25vcmVDYXNlKHN0LmNvbHVtbl9kZWNsdHlwZSgxKSkpOworICAgICAgICBpbnQgc3RTcGVlZCA9IEludGVnZXIucGFyc2VJbnQoY29sdW1uT2JqZWN0LnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHN0U3BlZWQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIGludENvbHVtbiwgc3RTcGVlZCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoY29sdW1uT2JqZWN0KTsKKyAgICAgICAgICAgICgoSW50ZWdlcikgY29sdW1uT2JqZWN0KS5pbnRWYWx1ZSgpOworICAgICAgICAgICAgZmFpbCgiQ2FzdCB0byBJbnRlZ2VyIHNob3VsZCBmYWlsIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LmNvbHVtbig0KTsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTUUxpdGUuRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImNvbHVtbiBvdXQgb2YgYm91bmRzIiwgZXhwZWN0ZWQuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5jb2x1bW4oLTEpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTGl0ZS5FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiY29sdW1uIG91dCBvZiBib3VuZHMiLCBleHBlY3RlZC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbHVtbl90YWJsZV9uYW1lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBkYi5wcmVwYXJlKCJzZWxlY3QgKiBmcm9tICIgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMSk7CisgICAgICAgICAgICBzdC5jb2x1bW5fdGFibGVfbmFtZSgxKTsKKyAgICAgICAgICAgIGZhaWwoIkZ1bmN0aW9uIGlzIG5vdyBzdXBwb3J0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTGl0ZS5FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygidW5zdXBwb3J0ZWQiLCBleHBlY3RlZC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbHVtbl9kYXRhYmFzZV9uYW1lKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QgPSBkYi5wcmVwYXJlKCJpbnNlcnQgaW50byAiICsgRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTEKKyAgICAgICAgICAgICAgICAgICAgKyAiIHZhbHVlcyAoOm9uZSw6dHdvLDp0aHJlZSkiKTsKKyAgICAgICAgICAgIHN0LmNvbHVtbl9kYXRhYmFzZV9uYW1lKDEpOworICAgICAgICAgICAgZmFpbCgiRnVuY3Rpb24gaXMgbm93IHN1cHBvcnRlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMaXRlLkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1bnN1cHBvcnRlZCIsIGV4cGVjdGVkLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29sdW1uX2RlY2x0eXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRiLmV4ZWMoQ1JFQVRFX0FMTF9UWVBFUywgbnVsbCk7CisgICAgICAgIGRiLmV4ZWMoSU5TRVJUX0FMTF9UWVBFUywgbnVsbCk7CisgICAgICAgIHN0ID0gZGIucHJlcGFyZSgic2VsZWN0ICogZnJvbSAiICsgQUxMX1RZUEVTX1RBQkxFKTsKKyAgICAgICAgc3Quc3RlcCgpOworCisgICAgICAgIC8vIEV4Y2VwdGlvbiB0ZXN0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5jb2x1bW5fZGVjbHR5cGUoMTAwKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMaXRlLkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShzdC5jb2x1bW5fZGVjbHR5cGUoMCksICJCT09MRUFOIi5lcXVhbHNJZ25vcmVDYXNlKHN0CisgICAgICAgICAgICAgICAgLmNvbHVtbl9kZWNsdHlwZSgwKSkpOworICAgICAgICBhc3NlcnRUcnVlKHN0LmNvbHVtbl9kZWNsdHlwZSgxKSwgIklOVCIuZXF1YWxzSWdub3JlQ2FzZShzdAorICAgICAgICAgICAgICAgIC5jb2x1bW5fZGVjbHR5cGUoMSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzdC5jb2x1bW5fZGVjbHR5cGUoMiksICJMT05HIi5lcXVhbHNJZ25vcmVDYXNlKHN0CisgICAgICAgICAgICAgICAgLmNvbHVtbl9kZWNsdHlwZSgyKSkpOworICAgICAgICBhc3NlcnRUcnVlKHN0LmNvbHVtbl9kZWNsdHlwZSgzKSwgIkJJR0lOVCIuZXF1YWxzSWdub3JlQ2FzZShzdAorICAgICAgICAgICAgICAgIC5jb2x1bW5fZGVjbHR5cGUoMykpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzdC5jb2x1bW5fZGVjbHR5cGUoNCksICJUSU5ZSU5UIi5lcXVhbHNJZ25vcmVDYXNlKHN0CisgICAgICAgICAgICAgICAgLmNvbHVtbl9kZWNsdHlwZSg0KSkpOworICAgICAgICBhc3NlcnRUcnVlKHN0LmNvbHVtbl9kZWNsdHlwZSg1KSwgIlNNQUxMSU5UIi5lcXVhbHNJZ25vcmVDYXNlKHN0CisgICAgICAgICAgICAgICAgLmNvbHVtbl9kZWNsdHlwZSg1KSkpOworICAgICAgICBhc3NlcnRUcnVlKHN0LmNvbHVtbl9kZWNsdHlwZSg2KSwgIk1FRElVTUlOVCIuZXF1YWxzSWdub3JlQ2FzZShzdAorICAgICAgICAgICAgICAgIC5jb2x1bW5fZGVjbHR5cGUoNikpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzdC5jb2x1bW5fZGVjbHR5cGUoNyksICJJTlRFR0VSIi5lcXVhbHNJZ25vcmVDYXNlKHN0CisgICAgICAgICAgICAgICAgLmNvbHVtbl9kZWNsdHlwZSg3KSkpOworICAgICAgICBhc3NlcnRUcnVlKHN0LmNvbHVtbl9kZWNsdHlwZSg4KSwgIlJFQUwiLmVxdWFsc0lnbm9yZUNhc2Uoc3QKKyAgICAgICAgICAgICAgICAuY29sdW1uX2RlY2x0eXBlKDgpKSk7CisgICAgICAgIGFzc2VydFRydWUoc3QuY29sdW1uX2RlY2x0eXBlKDkpLCAiRE9VQkxFIi5lcXVhbHNJZ25vcmVDYXNlKHN0CisgICAgICAgICAgICAgICAgLmNvbHVtbl9kZWNsdHlwZSg5KSkpOworICAgICAgICBhc3NlcnRUcnVlKHN0LmNvbHVtbl9kZWNsdHlwZSgxMCksICJGTE9BVCIuZXF1YWxzSWdub3JlQ2FzZShzdAorICAgICAgICAgICAgICAgIC5jb2x1bW5fZGVjbHR5cGUoMTApKSk7CisgICAgICAgIGFzc2VydFRydWUoc3QuY29sdW1uX2RlY2x0eXBlKDExKSwgIkRFQ0lNQUwiLmVxdWFsc0lnbm9yZUNhc2Uoc3QKKyAgICAgICAgICAgICAgICAuY29sdW1uX2RlY2x0eXBlKDExKSkpOworICAgICAgICBhc3NlcnRUcnVlKHN0LmNvbHVtbl9kZWNsdHlwZSgxMiksICJOVU1FUklDIi5lcXVhbHNJZ25vcmVDYXNlKHN0CisgICAgICAgICAgICAgICAgLmNvbHVtbl9kZWNsdHlwZSgxMikpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzdC5jb2x1bW5fZGVjbHR5cGUoMTMpLCAiQ0hBUigyMCkiLmVxdWFsc0lnbm9yZUNhc2Uoc3QKKyAgICAgICAgICAgICAgICAuY29sdW1uX2RlY2x0eXBlKDEzKSkpOworCisgICAgICAgIGFzc2VydFRydWUoc3QuY29sdW1uX2RlY2x0eXBlKDE5KSwgIkJMT0IiLmVxdWFsc0lnbm9yZUNhc2Uoc3QKKyAgICAgICAgICAgICAgICAuY29sdW1uX2RlY2x0eXBlKDE5KSkpOworCisgICAgICAgIGFzc2VydFRydWUoc3QuY29sdW1uX2RlY2x0eXBlKDIzKSwgIlRFWFQiLmVxdWFsc0lnbm9yZUNhc2Uoc3QKKyAgICAgICAgICAgICAgICAuY29sdW1uX2RlY2x0eXBlKDIzKSkpOworICAgICAgICBhc3NlcnRUcnVlKHN0LmNvbHVtbl9kZWNsdHlwZSgyOCksICJVUkwiLmVxdWFsc0lnbm9yZUNhc2Uoc3QKKyAgICAgICAgICAgICAgICAuY29sdW1uX2RlY2x0eXBlKDI4KSkpOworICAgICAgICBhc3NlcnRUcnVlKHN0LmNvbHVtbl9kZWNsdHlwZSgyOSksICJVUkwiLmVxdWFsc0lnbm9yZUNhc2Uoc3QKKyAgICAgICAgICAgICAgICAuY29sdW1uX2RlY2x0eXBlKDI5KSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb2x1bW5fb3JpZ2luX25hbWUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdCA9IGRiLnByZXBhcmUoInNlbGVjdCAqIGZyb20gIiArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxKTsKKyAgICAgICAgICAgIHN0LmNvbHVtbl9vcmlnaW5fbmFtZSgxKTsKKyAgICAgICAgICAgIGZhaWwoIkZ1bmN0aW9uIGlzIG5vdyBzdXBwb3J0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTGl0ZS5FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygidW5zdXBwb3J0ZWQiLCBleHBlY3RlZC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvc3FsaXRlL1F1ZXJ5VGltZW91dFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9RdWVyeVRpbWVvdXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGZlYmZmZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3NxbGl0ZS9RdWVyeVRpbWVvdXRUZXN0LmphdmEKQEAgLTAsMCArMSwxNjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKworcGFja2FnZSBsaWJjb3JlLnNxbGl0ZTsKKworaW1wb3J0IFNRTGl0ZS5EYXRhYmFzZTsKK2ltcG9ydCBTUUxpdGUuRnVuY3Rpb247CitpbXBvcnQgU1FMaXRlLkZ1bmN0aW9uQ29udGV4dDsKK2ltcG9ydCBTUUxpdGUuSkRCQzJ6LkpEQkNDb25uZWN0aW9uOworaW1wb3J0IGphdmEuc3FsLkNvbm5lY3Rpb247CitpbXBvcnQgamF2YS5zcWwuUHJlcGFyZWRTdGF0ZW1lbnQ7CitpbXBvcnQgamF2YS5zcWwuUmVzdWx0U2V0OworaW1wb3J0IGphdmEuc3FsLlNRTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5TdGF0ZW1lbnQ7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9TUUw7CisKKworLyoqCisgKiBUZXN0IHRoYXQgc3RhdGVtZW50cyBob25vciB0aGVpciB0aW1lb3V0LgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUXVlcnlUaW1lb3V0VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFWEVDX1FVRVJZCisgICAgICAgICAgICA9ICJpbnNlcnQgaW50byB0X2NvcHkgc2VsZWN0IGEgZnJvbSB0X29yaWcgd2hlcmUgREVMQVkoMiwxKT0xIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGRVRDSF9RVUVSWSA9ICJzZWxlY3QgYSBmcm9tIHRfb3JpZyB3aGVyZSBERUxBWSgyLDEpPTEiOworCisgICAgcHJpdmF0ZSBDb25uZWN0aW9uIGNvbm5lY3Rpb247CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3VwcG9ydF9TUUwubG9hZERyaXZlcigpOworICAgICAgICBjb25uZWN0aW9uID0gU3VwcG9ydF9TUUwuZ2V0Q29ubmVjdGlvbigpOworCisgICAgICAgIGV4ZWMoImRyb3AgdGFibGUgaWYgZXhpc3RzIHRfb3JpZzsiKTsKKyAgICAgICAgZXhlYygiZHJvcCB0YWJsZSBpZiBleGlzdHMgdF9jb3B5OyIpOworICAgICAgICBleGVjKCJjcmVhdGUgdGFibGUgdF9vcmlnIChhIGludCkiKTsKKyAgICAgICAgZXhlYygiY3JlYXRlIHRhYmxlIHRfY29weSAoYSBpbnQpIik7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA3OyBpKyspIHsKKyAgICAgICAgICAgIGV4ZWMoImluc2VydCBpbnRvIHRfb3JpZyB2YWx1ZXMgKCIgKyBpICsgIik7Iik7CisgICAgICAgIH0KKworICAgICAgICBEYXRhYmFzZSBkYXRhYmFzZSA9ICgoSkRCQ0Nvbm5lY3Rpb24pIGNvbm5lY3Rpb24pLmdldFNRTGl0ZURhdGFiYXNlKCk7CisgICAgICAgIGRhdGFiYXNlLmNyZWF0ZV9mdW5jdGlvbigiREVMQVkiLCAyLCBuZXcgRnVuY3Rpb24oKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgZnVuY3Rpb24oRnVuY3Rpb25Db250ZXh0IGZ1bmN0aW9uQ29udGV4dCwgU3RyaW5nW10gYXJncykgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGludCBzZWNvbmRzID0gSW50ZWdlci5wYXJzZUludChhcmdzWzBdKTsKKyAgICAgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKHNlY29uZHMgKiAxMDAwKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZ1bmN0aW9uQ29udGV4dC5zZXRfcmVzdWx0KEludGVnZXIucGFyc2VJbnQoYXJnc1sxXSkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGxhc3Rfc3RlcChGdW5jdGlvbkNvbnRleHQgZnVuY3Rpb25Db250ZXh0KSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc3RlcChGdW5jdGlvbkNvbnRleHQgZnVuY3Rpb25Db250ZXh0LCBTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworCisgICAgICAgIGNvbm5lY3Rpb24uc2V0QXV0b0NvbW1pdCh0cnVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY29ubmVjdGlvbi5jbG9zZSgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBleGVjKFN0cmluZyBxdWVyeVN0cmluZykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXhlY3V0aW5nICIgKyBxdWVyeVN0cmluZyk7CisgICAgICAgIFN0YXRlbWVudCBzdGF0ZW1lbnQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RhdGVtZW50ID0gY29ubmVjdGlvbi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKHF1ZXJ5U3RyaW5nKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChzdGF0ZW1lbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHN0YXRlbWVudC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFByZXBhcmVkU3RhdGVtZW50RmV0Y2goKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgc3RhdGVtZW50ID0gY29ubmVjdGlvbi5wcmVwYXJlU3RhdGVtZW50KEZFVENIX1FVRVJZKTsKKyAgICAgICAgc3RhdGVtZW50LnNldFF1ZXJ5VGltZW91dCgxKTsKKyAgICAgICAgUmVzdWx0U2V0IHJlc3VsdFNldCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXN1bHRTZXQgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KCk7CisgICAgICAgICAgICB3aGlsZSAocmVzdWx0U2V0Lm5leHQoKSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHN0YXRlbWVudC5jbG9zZSgpOworICAgICAgICAgICAgaWYgKHJlc3VsdFNldCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0U2V0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJlcGFyZWRTdGF0ZW1lbnRVcGRhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgc3RhdGVtZW50ID0gY29ubmVjdGlvbi5wcmVwYXJlU3RhdGVtZW50KEVYRUNfUVVFUlkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RhdGVtZW50LnNldFF1ZXJ5VGltZW91dCgxKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc3RhdGVtZW50LmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZFRpbWVvdXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY29ubmVjdGlvbi5zZXRBdXRvQ29tbWl0KHRydWUpOworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBzdGF0ZW1lbnQgPSBjb25uZWN0aW9uLnByZXBhcmVTdGF0ZW1lbnQoInNlbGVjdCAnaGVsbG8nIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0YXRlbWVudC5zZXRRdWVyeVRpbWVvdXQoLTEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIFJlc3VsdFNldCByZXN1bHRTZXQgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KCk7CisgICAgICAgIHJlc3VsdFNldC5jbG9zZSgpOworICAgICAgICBzdGF0ZW1lbnQuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXhlY3V0ZVVwZGF0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdGF0ZW1lbnQgc3RhdGVtZW50ID0gY29ubmVjdGlvbi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0YXRlbWVudC5zZXRRdWVyeVRpbWVvdXQoMSk7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZVVwZGF0ZShFWEVDX1FVRVJZKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzdGF0ZW1lbnQuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUaW1lb3V0QW5kU3RhdGVtZW50UmV1c2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0YXRlbWVudCA9IGNvbm5lY3Rpb24uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgIHN0YXRlbWVudC5zZXRRdWVyeVRpbWVvdXQoMSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFJlc3VsdFNldCByZXN1bHRTZXQgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KEZFVENIX1FVRVJZKTsKKyAgICAgICAgICAgICAgICB3aGlsZSAocmVzdWx0U2V0Lm5leHQoKSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzdGF0ZW1lbnQuY2xvc2UoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS91dGlsL0Jhc2ljTHJ1Q2FjaGVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS91dGlsL0Jhc2ljTHJ1Q2FjaGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmNlMDg0NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3V0aWwvQmFzaWNMcnVDYWNoZVRlc3QuamF2YQpAQCAtMCwwICsxLDE0NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgQmFzaWNMcnVDYWNoZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q3JlYXRlT25DYWNoZU1pc3MoKSB7CisgICAgICAgIEJhc2ljTHJ1Q2FjaGU8U3RyaW5nLCBTdHJpbmc+IGNhY2hlID0gbmV3Q3JlYXRpbmdDYWNoZSgpOworICAgICAgICBTdHJpbmcgY3JlYXRlZCA9IGNhY2hlLmdldCgiYWEiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjcmVhdGVkLWFhIiwgY3JlYXRlZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vQ3JlYXRlT25DYWNoZUhpdCgpIHsKKyAgICAgICAgQmFzaWNMcnVDYWNoZTxTdHJpbmcsIFN0cmluZz4gY2FjaGUgPSBuZXdDcmVhdGluZ0NhY2hlKCk7CisgICAgICAgIGNhY2hlLnB1dCgiYWEiLCAicHV0LWFhIik7CisgICAgICAgIGFzc2VydEVxdWFscygicHV0LWFhIiwgY2FjaGUuZ2V0KCJhYSIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RydWN0b3JEb2VzTm90QWxsb3daZXJvQ2FjaGVTaXplKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEJhc2ljTHJ1Q2FjaGU8U3RyaW5nLCBTdHJpbmc+KDApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDYW5ub3RQdXROdWxsS2V5KCkgeworICAgICAgICBCYXNpY0xydUNhY2hlPFN0cmluZywgU3RyaW5nPiBjYWNoZSA9IG5ldyBCYXNpY0xydUNhY2hlPFN0cmluZywgU3RyaW5nPigzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNhY2hlLnB1dChudWxsLCAiQSIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENhbm5vdFB1dE51bGxWYWx1ZSgpIHsKKyAgICAgICAgQmFzaWNMcnVDYWNoZTxTdHJpbmcsIFN0cmluZz4gY2FjaGUgPSBuZXcgQmFzaWNMcnVDYWNoZTxTdHJpbmcsIFN0cmluZz4oMyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjYWNoZS5wdXQoImEiLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFdmljdGlvbldpdGhTaW5nbGV0b25DYWNoZSgpIHsKKyAgICAgICAgQmFzaWNMcnVDYWNoZTxTdHJpbmcsIFN0cmluZz4gY2FjaGUgPSBuZXcgQmFzaWNMcnVDYWNoZTxTdHJpbmcsIFN0cmluZz4oMSk7CisgICAgICAgIGNhY2hlLnB1dCgiYSIsICJBIik7CisgICAgICAgIGNhY2hlLnB1dCgiYiIsICJCIik7CisgICAgICAgIGFzc2VydFNuYXBzaG90KGNhY2hlLCAiYiIsICJCIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVudHJ5RXZpY3RlZFdoZW5GdWxsKCkgeworICAgICAgICBMaXN0PFN0cmluZz4gZXhwZWN0ZWRFdmljdGlvbkxvZyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBmaW5hbCBMaXN0PFN0cmluZz4gZXZpY3Rpb25Mb2cgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgQmFzaWNMcnVDYWNoZTxTdHJpbmcsIFN0cmluZz4gY2FjaGUgPSBuZXcgQmFzaWNMcnVDYWNoZTxTdHJpbmcsIFN0cmluZz4oMykgeworICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIGVudHJ5RXZpY3RlZChTdHJpbmcga2V5LCBTdHJpbmcgdmFsdWUpIHsKKyAgICAgICAgICAgICAgICBldmljdGlvbkxvZy5hZGQoa2V5ICsgIj0iICsgdmFsdWUpOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIGNhY2hlLnB1dCgiYSIsICJBIik7CisgICAgICAgIGNhY2hlLnB1dCgiYiIsICJCIik7CisgICAgICAgIGNhY2hlLnB1dCgiYyIsICJDIik7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZEV2aWN0aW9uTG9nLCBldmljdGlvbkxvZyk7CisKKyAgICAgICAgY2FjaGUucHV0KCJkIiwgIkQiKTsKKyAgICAgICAgZXhwZWN0ZWRFdmljdGlvbkxvZy5hZGQoImE9QSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRFdmljdGlvbkxvZywgZXZpY3Rpb25Mb2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2luZyB0aGUgdmFsdWUgZm9yIGEga2V5IGRvZXNuJ3QgY2F1c2UgYW4gZXZpY3Rpb24gYnV0IGl0IGRvZXMgYnJpbmcKKyAgICAgKiB0aGUgcmVwbGFjZWQgZW50cnkgdG8gdGhlIGZyb250IG9mIHRoZSBxdWV1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHV0RG9lc05vdENhdXNlRXZpY3Rpb24oKSB7CisgICAgICAgIGZpbmFsIExpc3Q8U3RyaW5nPiBldmljdGlvbkxvZyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBMaXN0PFN0cmluZz4gZXhwZWN0ZWRFdmljdGlvbkxvZyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBCYXNpY0xydUNhY2hlPFN0cmluZywgU3RyaW5nPiBjYWNoZSA9IG5ldyBCYXNpY0xydUNhY2hlPFN0cmluZywgU3RyaW5nPigzKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgZW50cnlFdmljdGVkKFN0cmluZyBrZXksIFN0cmluZyB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGV2aWN0aW9uTG9nLmFkZChrZXkgKyAiPSIgKyB2YWx1ZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgY2FjaGUucHV0KCJhIiwgIkEiKTsKKyAgICAgICAgY2FjaGUucHV0KCJiIiwgIkIiKTsKKyAgICAgICAgY2FjaGUucHV0KCJjIiwgIkMiKTsKKyAgICAgICAgY2FjaGUucHV0KCJiIiwgIkIyIik7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZEV2aWN0aW9uTG9nLCBldmljdGlvbkxvZyk7CisgICAgICAgIGFzc2VydFNuYXBzaG90KGNhY2hlLCAiYSIsICJBIiwgImMiLCAiQyIsICJiIiwgIkIyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEV2aWN0QWxsKCkgeworICAgICAgICBmaW5hbCBMaXN0PFN0cmluZz4gZXZpY3Rpb25Mb2cgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgQmFzaWNMcnVDYWNoZTxTdHJpbmcsIFN0cmluZz4gY2FjaGUgPSBuZXcgQmFzaWNMcnVDYWNoZTxTdHJpbmcsIFN0cmluZz4oMTApIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCBlbnRyeUV2aWN0ZWQoU3RyaW5nIGtleSwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgICAgICAgICAgZXZpY3Rpb25Mb2cuYWRkKGtleSArICI9IiArIHZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBjYWNoZS5wdXQoImEiLCAiQSIpOworICAgICAgICBjYWNoZS5wdXQoImIiLCAiQiIpOworICAgICAgICBjYWNoZS5wdXQoImMiLCAiQyIpOworICAgICAgICBjYWNoZS5ldmljdEFsbCgpOworICAgICAgICBhc3NlcnRTbmFwc2hvdChjYWNoZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KCJhPUEiLCAiYj1CIiwgImM9QyIpLCBldmljdGlvbkxvZyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBCYXNpY0xydUNhY2hlPFN0cmluZywgU3RyaW5nPiBuZXdDcmVhdGluZ0NhY2hlKCkgeworICAgICAgICByZXR1cm4gbmV3IEJhc2ljTHJ1Q2FjaGU8U3RyaW5nLCBTdHJpbmc+KDMpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgU3RyaW5nIGNyZWF0ZShTdHJpbmcga2V5KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChrZXkubGVuZ3RoKCkgPiAxKSA/ICgiY3JlYXRlZC0iICsga2V5KSA6IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgfQorCisgICAgcHJpdmF0ZSA8VD4gdm9pZCBhc3NlcnRTbmFwc2hvdChCYXNpY0xydUNhY2hlPFQsIFQ+IGNhY2hlLCBULi4uIGtleXNBbmRWYWx1ZXMpIHsKKyAgICAgICAgTGlzdDxUPiBhY3R1YWxLZXlzQW5kVmFsdWVzID0gbmV3IEFycmF5TGlzdDxUPigpOworICAgICAgICBmb3IgKE1hcC5FbnRyeTxULCBUPiBlbnRyeSA6IGNhY2hlLnNuYXBzaG90KCkuZW50cnlTZXQoKSkgeworICAgICAgICAgICAgYWN0dWFsS2V5c0FuZFZhbHVlcy5hZGQoZW50cnkuZ2V0S2V5KCkpOworICAgICAgICAgICAgYWN0dWFsS2V5c0FuZFZhbHVlcy5hZGQoZW50cnkuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBhc3NlcnQgdXNpbmcgbGlzdHMgYmVjYXVzZSBvcmRlciBpcyBpbXBvcnRhbnQgZm9yIExSVXMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3Qoa2V5c0FuZFZhbHVlcyksIGFjdHVhbEtleXNBbmRWYWx1ZXMpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3V0aWwvQ29sbGVjdGlvblV0aWxzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvdXRpbC9Db2xsZWN0aW9uVXRpbHNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmM3MDkxYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3V0aWwvQ29sbGVjdGlvblV0aWxzVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLnV0aWw7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmLlJlZmVyZW5jZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmLldlYWtSZWZlcmVuY2U7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgZmluYWwgY2xhc3MgQ29sbGVjdGlvblV0aWxzVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3REZXJlZmVyZW5jZUl0ZXJhYmxlKCkgeworICAgICAgICBMaXN0PFJlZmVyZW5jZTxTdHJpbmc+PiByZWZzID0gbmV3IEFycmF5TGlzdDxSZWZlcmVuY2U8U3RyaW5nPj4oKTsKKyAgICAgICAgcmVmcy5hZGQobmV3TGl0ZXJhbFJlZmVyZW5jZSgiYSIpKTsKKyAgICAgICAgcmVmcy5hZGQobmV3TGl0ZXJhbFJlZmVyZW5jZSgiYiIpKTsKKyAgICAgICAgcmVmcy5hZGQobmV3TGl0ZXJhbFJlZmVyZW5jZSgiYyIpKTsKKyAgICAgICAgcmVmcy5hZGQobmV3TGl0ZXJhbFJlZmVyZW5jZSgiZCIpKTsKKyAgICAgICAgcmVmcy5hZGQobmV3TGl0ZXJhbFJlZmVyZW5jZSgiZSIpKTsKKworICAgICAgICBJdGVyYWJsZTxTdHJpbmc+IHN0cmluZ3MgPSBDb2xsZWN0aW9uVXRpbHMuZGVyZWZlcmVuY2VJdGVyYWJsZShyZWZzLCB0cnVlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy48U3RyaW5nPmFzTGlzdCgiYSIsICJiIiwgImMiLCAiZCIsICJlIiksIHRvTGlzdChzdHJpbmdzKSk7CisKKyAgICAgICAgcmVmcy5nZXQoMSkuY2xlYXIoKTsgLy8gYgorICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLjxTdHJpbmc+YXNMaXN0KCJhIiwgImMiLCAiZCIsICJlIiksIHRvTGlzdChzdHJpbmdzKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg0LCByZWZzLnNpemUoKSk7CisKKyAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBpID0gc3RyaW5ncy5pdGVyYXRvcigpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBpLm5leHQoKSk7CisgICAgICAgIGkucmVtb3ZlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCByZWZzLnNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYyIsIGkubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkIiwgaS5uZXh0KCkpOworICAgICAgICBhc3NlcnRUcnVlKGkuaGFzTmV4dCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGkucmVtb3ZlKCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBoYXNOZXh0KCkgdG8gbWFrZSByZW1vdmUoKSBpbXBvc3NpYmxlLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoImUiLCBpLm5leHQoKSk7CisgICAgICAgIGkucmVtb3ZlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCByZWZzLnNpemUoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGkuaGFzTmV4dCgpKTsKKworICAgICAgICByZWZzLmdldCgwKS5jbGVhcigpOyAvLyBjCisgICAgICAgIHJlZnMuZ2V0KDEpLmNsZWFyKCk7IC8vIGQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy48U3RyaW5nPmFzTGlzdCgpLCB0b0xpc3Qoc3RyaW5ncykpOworICAgIH0KKworICAgIHByaXZhdGUgPFQ+IExpc3Q8VD4gdG9MaXN0KEl0ZXJhYmxlPFQ+IGl0ZXJhYmxlKSB7CisgICAgICAgIExpc3Q8VD4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxUPigpOworICAgICAgICBmb3IgKFQgdCA6IGl0ZXJhYmxlKSB7CisgICAgICAgICAgICByZXN1bHQuYWRkKHQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZUR1cGxpY2F0ZXNPbkVtcHR5Q29sbGVjdGlvbigpIHsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGxpc3QgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgQ29sbGVjdGlvblV0aWxzLnJlbW92ZUR1cGxpY2F0ZXMobGlzdCwgU3RyaW5nLkNBU0VfSU5TRU5TSVRJVkVfT1JERVIpOworICAgICAgICBhc3NlcnRUcnVlKGxpc3QuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlRHVwbGljYXRlc09uU2luZ2xldG9uQ29sbGVjdGlvbigpIHsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGxpc3QgPSBBcnJheXMuYXNMaXN0KCJBIik7CisgICAgICAgIENvbGxlY3Rpb25VdGlscy5yZW1vdmVEdXBsaWNhdGVzKGxpc3QsIFN0cmluZy5DQVNFX0lOU0VOU0lUSVZFX09SREVSKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENvbGxlY3Rpb25zLnNpbmdsZXRvbkxpc3QoIkEiKSwgbGlzdCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZUR1cGxpY2F0ZXMoKSB7CisgICAgICAgIExpc3Q8U3RyaW5nPiBsaXN0ID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGxpc3QuYWRkKCJBIik7CisgICAgICAgIGxpc3QuYWRkKCJBIik7CisgICAgICAgIGxpc3QuYWRkKCJBIik7CisgICAgICAgIGxpc3QuYWRkKCJCIik7CisgICAgICAgIGxpc3QuYWRkKCJDIik7CisgICAgICAgIGxpc3QuYWRkKCJDIik7CisgICAgICAgIGxpc3QuYWRkKCJDIik7CisgICAgICAgIENvbGxlY3Rpb25VdGlscy5yZW1vdmVEdXBsaWNhdGVzKGxpc3QsIFN0cmluZy5DQVNFX0lOU0VOU0lUSVZFX09SREVSKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoIkEiLCAiQiIsICJDIiksIGxpc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgcmVmZXJlbmNlIHRoYXQgbXVzdCBiZSBtYW51YWxseSBjbGVhcmVkLgorICAgICAqLworICAgIHB1YmxpYyBSZWZlcmVuY2U8U3RyaW5nPiBuZXdMaXRlcmFsUmVmZXJlbmNlKFN0cmluZyBzKSB7CisgICAgICAgIHJldHVybiBuZXcgV2Vha1JlZmVyZW5jZTxTdHJpbmc+KHMpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3htbC9EZWNsYXJhdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3htbC9EZWNsYXJhdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNGNiMzJjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL0RlY2xhcmF0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLnhtbDsKKworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLktub3duRmFpbHVyZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKKy8qKgorICogVGVzdCB0aGUgcGFyc2luZyBvZiB0aGUgWE1MIGRlY2xhcmF0aW9uLCBwbHVzIHRoZSBhZGRpdGlvbmFsIGRvY3VtZW50IGZpZWxkcworICogY2FwdHVyZWQgZHVyaW5nIHBhcnNpbmcuCisgKi8KK3B1YmxpYyBjbGFzcyBEZWNsYXJhdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIFN0cmluZyBzeXN0ZW1JZEE7CisgICAgcHJpdmF0ZSBEb2N1bWVudCBkb2N1bWVudEE7CisKKyAgICBwcml2YXRlIFN0cmluZyBzeXN0ZW1JZEI7CisgICAgcHJpdmF0ZSBEb2N1bWVudCBkb2N1bWVudEI7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICAgICAgICBmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOworICAgICAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlciA9IGZhY3RvcnkubmV3RG9jdW1lbnRCdWlsZGVyKCk7CisKKyAgICAgICAgc3lzdGVtSWRBID0gc3RyaW5nVG9TeXN0ZW1JZCgKKyAgICAgICAgICAgICAgICAiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiSVNPLTg4NTktMVwiIHN0YW5kYWxvbmU9XCJub1wiID8+PGZvbyAvPiIpOworICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZUEgPSBuZXcgSW5wdXRTb3VyY2Uoc3lzdGVtSWRBKTsKKyAgICAgICAgaW5wdXRTb3VyY2VBLnNldEVuY29kaW5nKCJVUy1BU0NJSSIpOworICAgICAgICBkb2N1bWVudEEgPSBidWlsZGVyLnBhcnNlKGlucHV0U291cmNlQSk7CisKKyAgICAgICAgc3lzdGVtSWRCID0gc3RyaW5nVG9TeXN0ZW1JZCgKKyAgICAgICAgICAgICAgICAiPD94bWwgdmVyc2lvbj1cIjEuMVwiIGVuY29kaW5nPVwiVVMtQVNDSUlcIiBzdGFuZGFsb25lPVwieWVzXCIgPz48Zm9vIC8+Iik7CisgICAgICAgIElucHV0U291cmNlIGlucHV0U291cmNlQiA9IG5ldyBJbnB1dFNvdXJjZShzeXN0ZW1JZEIpOworICAgICAgICBpbnB1dFNvdXJjZUIuc2V0RW5jb2RpbmcoIklTTy04ODU5LTEiKTsKKyAgICAgICAgZG9jdW1lbnRCID0gYnVpbGRlci5wYXJzZShpbnB1dFNvdXJjZUIpOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIHN0cmluZ1RvU3lzdGVtSWQoU3RyaW5nIGNvbnRlbnRzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBGaWxlIGZpbGUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJ0ZW1wIiwgInhtbCIpOworICAgICAgICBmaWxlLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZSk7CisgICAgICAgIG91dC53cml0ZShjb250ZW50cy5nZXRCeXRlcygiVVRGLTgiKSk7CisgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICByZXR1cm4gImZpbGU6IiArIGZpbGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogWE1MIHBhcnNlcnMgYXJlIGFkdmlzZWQgb2YgdGhlIGRvY3VtZW50J3MgY2hhcmFjdGVyIHNldCB2aWEgdHdvIGNoYW5uZWxzOgorICAgICAqIHZpYSB0aGUgZGVjbGFyYXRpb24gYW5kIGFsc28gdGhlIGRvY3VtZW50J3MgaW5wdXQgc291cmNlLiBUbyB0ZXN0IHRoYXQKKyAgICAgKiBlYWNoIG9mIHRoZXNlIHdpbmRzIHVwIGluIHRoZSBjb3JyZWN0IGxvY2F0aW9uIGluIHRoZSBkb2N1bWVudCBtb2RlbCwgd2UKKyAgICAgKiBzdXBwbHkgZGlmZmVyZW50IG5hbWVzIGZvciBlYWNoLiBUaGlzIGlzIG9ubHkgc2FmZSBiZWNhdXNlIGZvciB0aGUgc3Vic2V0CisgICAgICogb2YgY2hhcmFjdGVycyBpbiB0aGUgZG9jdW1lbnQsIHRoZSBjaGFyYWN0ZXIgc2V0cyBhcmUgZXF1aXZhbGVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5wdXRFbmNvZGluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoIlVTLUFTQ0lJIiwgZG9jdW1lbnRBLmdldElucHV0RW5jb2RpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSVNPLTg4NTktMSIsIGRvY3VtZW50Qi5nZXRJbnB1dEVuY29kaW5nKCkpOworICAgIH0KKworICAgIEBLbm93bkZhaWx1cmUoIkRhbHZpayBkb2Vzbid0IHBhcnNlIHRoZSBYTUwgZGVjbGFyYXRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRYbWxFbmNvZGluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbWVzc2FnZSA9ICJUaGlzIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgcGFyc2UgdGhlIGVuY29kaW5nIGZyb20gdGhlIFhNTCBkZWNsYXJhdGlvbiI7CisgICAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLCAiSVNPLTg4NTktMSIsIGRvY3VtZW50QS5nZXRYbWxFbmNvZGluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsICJVUy1BU0NJSSIsIGRvY3VtZW50Qi5nZXRYbWxFbmNvZGluZygpKTsKKyAgICB9CisKKyAgICBAS25vd25GYWlsdXJlKCJEYWx2aWsgZG9lc24ndCBwYXJzZSB0aGUgWE1MIGRlY2xhcmF0aW9uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0WG1sVmVyc2lvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbWVzc2FnZSA9ICJUaGlzIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgcGFyc2UgdGhlIHZlcnNpb24gZnJvbSB0aGUgWE1MIGRlY2xhcmF0aW9uIjsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsICIxLjAiLCBkb2N1bWVudEEuZ2V0WG1sVmVyc2lvbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsICIxLjEiLCBkb2N1bWVudEIuZ2V0WG1sVmVyc2lvbigpKTsKKyAgICB9CisKKyAgICBAS25vd25GYWlsdXJlKCJEYWx2aWsgZG9lc24ndCBwYXJzZSB0aGUgWE1MIGRlY2xhcmF0aW9uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0WG1sU3RhbmRhbG9uZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbWVzc2FnZSA9ICJUaGlzIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgcGFyc2Ugc3RhbmRhbG9uZSBmcm9tIHRoZSBYTUwgZGVjbGFyYXRpb24iOworICAgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgZmFsc2UsIGRvY3VtZW50QS5nZXRYbWxTdGFuZGFsb25lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgdHJ1ZSwgZG9jdW1lbnRCLmdldFhtbFN0YW5kYWxvbmUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldERvY3VtZW50VXJpKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyhzeXN0ZW1JZEEsIGRvY3VtZW50QS5nZXREb2N1bWVudFVSSSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHN5c3RlbUlkQiwgZG9jdW1lbnRCLmdldERvY3VtZW50VVJJKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3htbC9Eb21UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS94bWwvRG9tVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc5NDQwZjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS94bWwvRG9tVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTczNiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS54bWw7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5Lbm93bkZhaWx1cmU7CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlV3JpdGVyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5TdHJpbmdSZWFkZXI7CitpbXBvcnQgamF2YS5pby5TdHJpbmdXcml0ZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4Lk1hdGNoZXI7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm47CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzOworaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01Tb3VyY2U7CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5Bc3NlcnRpb25GYWlsZWRFcnJvcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKK2ltcG9ydCBvcmcudzNjLmRvbS5DREFUQVNlY3Rpb247CitpbXBvcnQgb3JnLnczYy5kb20uQ29tbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRGcmFnbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7CitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbnRpdHk7CitpbXBvcnQgb3JnLnczYy5kb20uRW50aXR5UmVmZXJlbmNlOworaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworaW1wb3J0IG9yZy53M2MuZG9tLk5vdGF0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLlByb2Nlc3NpbmdJbnN0cnVjdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5UZXh0OworaW1wb3J0IG9yZy53M2MuZG9tLlR5cGVJbmZvOworaW1wb3J0IG9yZy53M2MuZG9tLlVzZXJEYXRhSGFuZGxlcjsKK2ltcG9ydCBzdGF0aWMgb3JnLnczYy5kb20uVXNlckRhdGFIYW5kbGVyLk5PREVfQURPUFRFRDsKK2ltcG9ydCBzdGF0aWMgb3JnLnczYy5kb20uVXNlckRhdGFIYW5kbGVyLk5PREVfQ0xPTkVEOworaW1wb3J0IHN0YXRpYyBvcmcudzNjLmRvbS5Vc2VyRGF0YUhhbmRsZXIuTk9ERV9JTVBPUlRFRDsKK2ltcG9ydCBzdGF0aWMgb3JnLnczYy5kb20uVXNlckRhdGFIYW5kbGVyLk5PREVfUkVOQU1FRDsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247CisKKy8qKgorICogQ29uc3RydWN0IGEgRE9NIGFuZCB0aGVuIGludGVycm9nYXRlIGl0LgorICovCitwdWJsaWMgY2xhc3MgRG9tVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXI7CisgICAgcHJpdmF0ZSBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKyAgICBwcml2YXRlIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGxlbWVudGF0aW9uOworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgeG1sCisgICAgICAgICAgICA9ICI8IURPQ1RZUEUgbWVudSBbIgorICAgICAgICAgICAgKyAiICA8IUVOVElUWSBzcCBcIk1hcGxlIFN5cnVwXCI+IgorICAgICAgICAgICAgKyAiICA8IU5PVEFUSU9OIHBuZyBTWVNURU0gXCJpbWFnZS9wbmdcIj4iCisgICAgICAgICAgICArICJdPiIKKyAgICAgICAgICAgICsgIjxtZW51PlxuIgorICAgICAgICAgICAgKyAiICA8aXRlbSB4bWxucz1cImh0dHA6Ly9mb29kXCIgeG1sbnM6YT1cImh0dHA6Ly9hZGRvbnNcIj5cbiIKKyAgICAgICAgICAgICsgIiAgICA8bmFtZSBhOnN0YW5kYXJkPVwic3RyYXdiZXJyeVwiIGRlbHV4ZT1cIiZzcDtcIj5XYWZmbGVzPC9uYW1lPlxuIgorICAgICAgICAgICAgKyAiICAgIDxkZXNjcmlwdGlvbiB4bWxucz1cImh0dHA6Ly9tYXJrZXRpbmdcIj5CZWxnaWFuPCFbQ0RBVEFbIHdhZmZsZXMgJiBzdHJhd2JlcnJpZXMgKDwgNWcgXV0+b2YgZmF0KTwvZGVzY3JpcHRpb24+XG4iCisgICAgICAgICAgICArICIgICAgPGE6b3B0aW9uPldoaXBwZWQgQ3JlYW08L2E6b3B0aW9uPlxuIgorICAgICAgICAgICAgKyAiICAgIDxhOm9wdGlvbj4mc3A7PC9hOm9wdGlvbj5cbiIKKyAgICAgICAgICAgICsgIiAgICA8P3dhZmZsZW1ha2VyIHNxdWFyZSBzaGFwZT8+XG4iCisgICAgICAgICAgICArICIgICAgPG51dHJpdGlvbj5cbiIKKyAgICAgICAgICAgICsgIiAgICAgIDxhOnZpdGFtaW5zIHhtbG5zOmE9XCJodHRwOi8vdXNkYVwiPlxuIgorICAgICAgICAgICAgKyAiICAgICAgICA8IS0tIGFkZCBvdGhlciB2aXRhbWlucz8gLS0+IFxuIgorICAgICAgICAgICAgKyAiICAgICAgICA8YTp2aXRhbWluYz42MCU8L2E6dml0YW1pbmM+XG4iCisgICAgICAgICAgICArICIgICAgICA8L2E6dml0YW1pbnM+XG4iCisgICAgICAgICAgICArICIgICAgPC9udXRyaXRpb24+XG4iCisgICAgICAgICAgICArICIgIDwvaXRlbT5cbiIKKyAgICAgICAgICAgICsgIjwvbWVudT4iOworCisgICAgcHJpdmF0ZSBEb2N1bWVudCBkb2N1bWVudDsKKyAgICBwcml2YXRlIERvY3VtZW50VHlwZSBkb2N0eXBlOworICAgIHByaXZhdGUgRW50aXR5IHNwOworICAgIHByaXZhdGUgTm90YXRpb24gcG5nOworICAgIHByaXZhdGUgRWxlbWVudCBtZW51OworICAgIHByaXZhdGUgRWxlbWVudCBpdGVtOworICAgIHByaXZhdGUgQXR0ciBpdGVtWG1sbnM7CisgICAgcHJpdmF0ZSBBdHRyIGl0ZW1YbWxuc0E7CisgICAgcHJpdmF0ZSBFbGVtZW50IG5hbWU7CisgICAgcHJpdmF0ZSBBdHRyIHN0YW5kYXJkOworICAgIHByaXZhdGUgQXR0ciBkZWx1eGU7CisgICAgcHJpdmF0ZSBUZXh0IHdhZmZsZXM7CisgICAgcHJpdmF0ZSBFbGVtZW50IGRlc2NyaXB0aW9uOworICAgIHByaXZhdGUgVGV4dCBkZXNjcmlwdGlvblRleHQxOworICAgIHByaXZhdGUgQ0RBVEFTZWN0aW9uIGRlc2NyaXB0aW9uVGV4dDI7CisgICAgcHJpdmF0ZSBUZXh0IGRlc2NyaXB0aW9uVGV4dDM7CisgICAgcHJpdmF0ZSBFbGVtZW50IG9wdGlvbjE7CisgICAgcHJpdmF0ZSBFbGVtZW50IG9wdGlvbjI7CisgICAgcHJpdmF0ZSBOb2RlIG9wdGlvbjJSZWZlcmVuY2U7IC8vIHJlc29sdmVkIHRvIFRleHQgb24gUkksIGFuIEVudGl0eVJlZmVyZW5jZSBvbiBEYWx2aWsKKyAgICBwcml2YXRlIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiB3YWZmbGVtYWtlcjsKKyAgICBwcml2YXRlIEVsZW1lbnQgbnV0cml0aW9uOworICAgIHByaXZhdGUgRWxlbWVudCB2aXRhbWluczsKKyAgICBwcml2YXRlIEF0dHIgdml0YW1pbnNYbWxuc0E7CisgICAgcHJpdmF0ZSBDb21tZW50IGNvbW1lbnQ7CisgICAgcHJpdmF0ZSBFbGVtZW50IHZpdGFtaW5jOworICAgIHByaXZhdGUgVGV4dCB2aXRhbWluY1RleHQ7CisgICAgcHJpdmF0ZSBMaXN0PE5vZGU+IGFsbE5vZGVzOworCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyYW5zZm9ybWVyID0gVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCkubmV3VHJhbnNmb3JtZXIoKTsKKyAgICAgICAgdHJhbnNmb3JtZXIuc2V0T3V0cHV0UHJvcGVydHkoT3V0cHV0S2V5cy5PTUlUX1hNTF9ERUNMQVJBVElPTiwgInllcyIpOworICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisgICAgICAgIGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7CisgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5Lm5ld0RvY3VtZW50QnVpbGRlcigpOworICAgICAgICBkb21JbXBsZW1lbnRhdGlvbiA9IGJ1aWxkZXIuZ2V0RE9NSW1wbGVtZW50YXRpb24oKTsKKyAgICAgICAgZG9jdW1lbnQgPSBidWlsZGVyLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShuZXcgU3RyaW5nUmVhZGVyKHhtbCkpKTsKKworICAgICAgICAvLyBkb2N0eXBlIG5vZGVzCisgICAgICAgIGRvY3R5cGUgPSBkb2N1bWVudC5nZXREb2N0eXBlKCk7CisgICAgICAgIGlmIChkb2N0eXBlLmdldEVudGl0aWVzKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgc3AgPSAoRW50aXR5KSBkb2N0eXBlLmdldEVudGl0aWVzKCkuaXRlbSgwKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZG9jdHlwZS5nZXROb3RhdGlvbnMoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBwbmcgPSAoTm90YXRpb24pIGRvY3R5cGUuZ2V0Tm90YXRpb25zKCkuaXRlbSgwKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGRvY3VtZW50IG5vZGVzCisgICAgICAgIG1lbnUgPSBkb2N1bWVudC5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgaXRlbSA9IChFbGVtZW50KSBtZW51LmdldENoaWxkTm9kZXMoKS5pdGVtKDEpOworICAgICAgICBpdGVtWG1sbnMgPSBpdGVtLmdldEF0dHJpYnV0ZU5vZGUoInhtbG5zIik7CisgICAgICAgIGl0ZW1YbWxuc0EgPSBpdGVtLmdldEF0dHJpYnV0ZU5vZGUoInhtbG5zOmEiKTsKKyAgICAgICAgbmFtZSA9IChFbGVtZW50KSBpdGVtLmdldENoaWxkTm9kZXMoKS5pdGVtKDEpOworICAgICAgICBzdGFuZGFyZCA9IG5hbWUuZ2V0QXR0cmlidXRlTm9kZSgiYTpzdGFuZGFyZCIpOworICAgICAgICBkZWx1eGUgPSBuYW1lLmdldEF0dHJpYnV0ZU5vZGUoImRlbHV4ZSIpOworICAgICAgICB3YWZmbGVzID0gKFRleHQpIG5hbWUuZ2V0Q2hpbGROb2RlcygpLml0ZW0oMCk7CisgICAgICAgIGRlc2NyaXB0aW9uID0gKEVsZW1lbnQpIGl0ZW0uZ2V0Q2hpbGROb2RlcygpLml0ZW0oMyk7CisgICAgICAgIGRlc2NyaXB0aW9uVGV4dDEgPSAoVGV4dCkgZGVzY3JpcHRpb24uZ2V0Q2hpbGROb2RlcygpLml0ZW0oMCk7CisgICAgICAgIGRlc2NyaXB0aW9uVGV4dDIgPSAoQ0RBVEFTZWN0aW9uKSBkZXNjcmlwdGlvbi5nZXRDaGlsZE5vZGVzKCkuaXRlbSgxKTsKKyAgICAgICAgZGVzY3JpcHRpb25UZXh0MyA9IChUZXh0KSBkZXNjcmlwdGlvbi5nZXRDaGlsZE5vZGVzKCkuaXRlbSgyKTsKKyAgICAgICAgb3B0aW9uMSA9IChFbGVtZW50KSBpdGVtLmdldENoaWxkTm9kZXMoKS5pdGVtKDUpOworICAgICAgICBvcHRpb24yID0gKEVsZW1lbnQpIGl0ZW0uZ2V0Q2hpbGROb2RlcygpLml0ZW0oNyk7CisgICAgICAgIG9wdGlvbjJSZWZlcmVuY2UgPSBvcHRpb24yLmdldENoaWxkTm9kZXMoKS5pdGVtKDApOworICAgICAgICB3YWZmbGVtYWtlciA9IChQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24pIGl0ZW0uZ2V0Q2hpbGROb2RlcygpLml0ZW0oOSk7CisgICAgICAgIG51dHJpdGlvbiA9IChFbGVtZW50KSBpdGVtLmdldENoaWxkTm9kZXMoKS5pdGVtKDExKTsKKyAgICAgICAgdml0YW1pbnMgPSAoRWxlbWVudCkgbnV0cml0aW9uLmdldENoaWxkTm9kZXMoKS5pdGVtKDEpOworICAgICAgICB2aXRhbWluc1htbG5zQSA9IHZpdGFtaW5zLmdldEF0dHJpYnV0ZU5vZGUoInhtbG5zOmEiKTsKKyAgICAgICAgY29tbWVudCA9IChDb21tZW50KSB2aXRhbWlucy5nZXRDaGlsZE5vZGVzKCkuaXRlbSgxKTsKKyAgICAgICAgdml0YW1pbmMgPSAoRWxlbWVudCkgdml0YW1pbnMuZ2V0Q2hpbGROb2RlcygpLml0ZW0oMyk7CisgICAgICAgIHZpdGFtaW5jVGV4dCA9IChUZXh0KSB2aXRhbWluYy5nZXRDaGlsZE5vZGVzKCkuaXRlbSgwKTsKKworICAgICAgICBhbGxOb2RlcyA9IG5ldyBBcnJheUxpc3Q8Tm9kZT4oKTsKKworICAgICAgICBpZiAoc3AgIT0gbnVsbCkgeworICAgICAgICAgICAgYWxsTm9kZXMuYWRkKHNwKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocG5nICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFsbE5vZGVzLmFkZChwbmcpOworICAgICAgICB9CisKKyAgICAgICAgYWxsTm9kZXMuYWRkQWxsKEFycmF5cy5hc0xpc3QoZG9jdW1lbnQsIGRvY3R5cGUsIG1lbnUsIGl0ZW0sIGl0ZW1YbWxucywKKyAgICAgICAgICAgICAgICBpdGVtWG1sbnNBLCBuYW1lLCBzdGFuZGFyZCwgZGVsdXhlLCB3YWZmbGVzLCBkZXNjcmlwdGlvbiwKKyAgICAgICAgICAgICAgICBkZXNjcmlwdGlvblRleHQxLCBkZXNjcmlwdGlvblRleHQyLCBkZXNjcmlwdGlvblRleHQzLCBvcHRpb24xLAorICAgICAgICAgICAgICAgIG9wdGlvbjIsIG9wdGlvbjJSZWZlcmVuY2UsIHdhZmZsZW1ha2VyLCBudXRyaXRpb24sIHZpdGFtaW5zLAorICAgICAgICAgICAgICAgIHZpdGFtaW5zWG1sbnNBLCBjb21tZW50LCB2aXRhbWluYywgdml0YW1pbmNUZXh0KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQW5kcm9pZCdzIHBhcnNlZCBET00gZG9lc24ndCBpbmNsdWRlIGVudGl0eSBkZWNsYXJhdGlvbnMuIFRoZXNlIG5vZGVzIHdpbGwKKyAgICAgKiBvbmx5IGJlIHRlc3RlZCBmb3IgaW1wbGVtZW50YXRpb25zIHRoYXQgc3VwcG9ydCB0aGVtLgorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIkRhbHZpayBkb2Vzbid0IHBhcnNlIGVudGl0eSBkZWNsYXJhdGlvbnMiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RFbnRpdHlEZWNsYXJhdGlvbnMoKSB7CisgICAgICAgIGFzc2VydE5vdE51bGwoIlRoaXMgaW1wbGVtZW50YXRpb24gZG9lcyBub3QgcGFyc2UgZW50aXR5IGRlY2xhcmF0aW9ucyIsIHNwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbmRyb2lkJ3MgcGFyc2VkIERPTSBkb2Vzbid0IGluY2x1ZGUgbm90YXRpb25zLiBUaGVzZSBub2RlcyB3aWxsIG9ubHkgYmUKKyAgICAgKiB0ZXN0ZWQgZm9yIGltcGxlbWVudGF0aW9ucyB0aGF0IHN1cHBvcnQgdGhlbS4KKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJEYWx2aWsgZG9lc24ndCBwYXJzZSBub3RhdGlvbnMiKQorICAgIHB1YmxpYyB2b2lkIHRlc3ROb3RhdGlvbnMoKSB7CisgICAgICAgIGFzc2VydE5vdE51bGwoIlRoaXMgaW1wbGVtZW50YXRpb24gZG9lcyBub3QgcGFyc2Ugbm90YXRpb25zIiwgcG5nKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9va3VwTmFtZXNwYWNlVVJJQnlQcmVmaXgoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBkb2N0eXBlLmxvb2t1cE5hbWVzcGFjZVVSSSgiYSIpKTsKKyAgICAgICAgaWYgKHNwICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBzcC5sb29rdXBOYW1lc3BhY2VVUkkoImEiKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBuZyAhPSBudWxsKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgcG5nLmxvb2t1cE5hbWVzcGFjZVVSSSgiYSIpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZG9jdW1lbnQubG9va3VwTmFtZXNwYWNlVVJJKCJhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbWVudS5sb29rdXBOYW1lc3BhY2VVUkkoImEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2FkZG9ucyIsIGl0ZW0ubG9va3VwTmFtZXNwYWNlVVJJKCJhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hZGRvbnMiLCBpdGVtWG1sbnMubG9va3VwTmFtZXNwYWNlVVJJKCJhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hZGRvbnMiLCBpdGVtWG1sbnNBLmxvb2t1cE5hbWVzcGFjZVVSSSgiYSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYWRkb25zIiwgbmFtZS5sb29rdXBOYW1lc3BhY2VVUkkoImEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2FkZG9ucyIsIHN0YW5kYXJkLmxvb2t1cE5hbWVzcGFjZVVSSSgiYSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYWRkb25zIiwgZGVsdXhlLmxvb2t1cE5hbWVzcGFjZVVSSSgiYSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYWRkb25zIiwgZGVzY3JpcHRpb24ubG9va3VwTmFtZXNwYWNlVVJJKCJhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hZGRvbnMiLCBkZXNjcmlwdGlvblRleHQxLmxvb2t1cE5hbWVzcGFjZVVSSSgiYSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYWRkb25zIiwgZGVzY3JpcHRpb25UZXh0Mi5sb29rdXBOYW1lc3BhY2VVUkkoImEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2FkZG9ucyIsIGRlc2NyaXB0aW9uVGV4dDMubG9va3VwTmFtZXNwYWNlVVJJKCJhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hZGRvbnMiLCBvcHRpb24xLmxvb2t1cE5hbWVzcGFjZVVSSSgiYSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYWRkb25zIiwgb3B0aW9uMi5sb29rdXBOYW1lc3BhY2VVUkkoImEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2FkZG9ucyIsIG9wdGlvbjJSZWZlcmVuY2UubG9va3VwTmFtZXNwYWNlVVJJKCJhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9hZGRvbnMiLCB3YWZmbGVtYWtlci5sb29rdXBOYW1lc3BhY2VVUkkoImEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2FkZG9ucyIsIG51dHJpdGlvbi5sb29rdXBOYW1lc3BhY2VVUkkoImEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL3VzZGEiLCB2aXRhbWlucy5sb29rdXBOYW1lc3BhY2VVUkkoImEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL3VzZGEiLCB2aXRhbWluc1htbG5zQS5sb29rdXBOYW1lc3BhY2VVUkkoImEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL3VzZGEiLCBjb21tZW50Lmxvb2t1cE5hbWVzcGFjZVVSSSgiYSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vdXNkYSIsIHZpdGFtaW5jLmxvb2t1cE5hbWVzcGFjZVVSSSgiYSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vdXNkYSIsIHZpdGFtaW5jVGV4dC5sb29rdXBOYW1lc3BhY2VVUkkoImEiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdExvb2t1cE5hbWVzcGFjZVVSSVdpdGhOdWxsUHJlZml4KCkgeworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZG9jdW1lbnQubG9va3VwTmFtZXNwYWNlVVJJKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGRvY3R5cGUubG9va3VwTmFtZXNwYWNlVVJJKG51bGwpKTsKKyAgICAgICAgaWYgKHNwICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBzcC5sb29rdXBOYW1lc3BhY2VVUkkobnVsbCkpOworICAgICAgICB9CisgICAgICAgIGlmIChwbmcgIT0gbnVsbCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHBuZy5sb29rdXBOYW1lc3BhY2VVUkkobnVsbCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtZW51Lmxvb2t1cE5hbWVzcGFjZVVSSShudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2Zvb2QiLCBpdGVtLmxvb2t1cE5hbWVzcGFjZVVSSShudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2Zvb2QiLCBpdGVtWG1sbnMubG9va3VwTmFtZXNwYWNlVVJJKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vZm9vZCIsIGl0ZW1YbWxuc0EubG9va3VwTmFtZXNwYWNlVVJJKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vZm9vZCIsIG5hbWUubG9va3VwTmFtZXNwYWNlVVJJKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vZm9vZCIsIHN0YW5kYXJkLmxvb2t1cE5hbWVzcGFjZVVSSShudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2Zvb2QiLCBkZWx1eGUubG9va3VwTmFtZXNwYWNlVVJJKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vbWFya2V0aW5nIiwgZGVzY3JpcHRpb24ubG9va3VwTmFtZXNwYWNlVVJJKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vbWFya2V0aW5nIiwgZGVzY3JpcHRpb25UZXh0MS5sb29rdXBOYW1lc3BhY2VVUkkobnVsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9tYXJrZXRpbmciLCBkZXNjcmlwdGlvblRleHQyLmxvb2t1cE5hbWVzcGFjZVVSSShudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL21hcmtldGluZyIsIGRlc2NyaXB0aW9uVGV4dDMubG9va3VwTmFtZXNwYWNlVVJJKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vZm9vZCIsIG9wdGlvbjEubG9va3VwTmFtZXNwYWNlVVJJKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vZm9vZCIsIG9wdGlvbjIubG9va3VwTmFtZXNwYWNlVVJJKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vZm9vZCIsIG9wdGlvbjJSZWZlcmVuY2UubG9va3VwTmFtZXNwYWNlVVJJKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vZm9vZCIsIHdhZmZsZW1ha2VyLmxvb2t1cE5hbWVzcGFjZVVSSShudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2Zvb2QiLCBudXRyaXRpb24ubG9va3VwTmFtZXNwYWNlVVJJKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vZm9vZCIsIHZpdGFtaW5zLmxvb2t1cE5hbWVzcGFjZVVSSShudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2Zvb2QiLCB2aXRhbWluc1htbG5zQS5sb29rdXBOYW1lc3BhY2VVUkkobnVsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9mb29kIiwgY29tbWVudC5sb29rdXBOYW1lc3BhY2VVUkkobnVsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9mb29kIiwgdml0YW1pbmMubG9va3VwTmFtZXNwYWNlVVJJKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vZm9vZCIsIHZpdGFtaW5jVGV4dC5sb29rdXBOYW1lc3BhY2VVUkkobnVsbCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RMb29rdXBOYW1lc3BhY2VVUklXaXRoWG1sbnNQcmVmaXgoKSB7CisgICAgICAgIGZvciAoTm9kZSBub2RlIDogYWxsTm9kZXMpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBub2RlLmxvb2t1cE5hbWVzcGFjZVVSSSgieG1sbnMiKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9va3VwUHJlZml4V2l0aFNoYWRvd2VkVXJpKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZG9jdW1lbnQubG9va3VwUHJlZml4KCJodHRwOi8vYWRkb25zIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZG9jdHlwZS5sb29rdXBQcmVmaXgoImh0dHA6Ly9hZGRvbnMiKSk7CisgICAgICAgIGlmIChzcCAhPSBudWxsKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgc3AubG9va3VwUHJlZml4KCJodHRwOi8vYWRkb25zIikpOworICAgICAgICB9CisgICAgICAgIGlmIChwbmcgIT0gbnVsbCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHBuZy5sb29rdXBQcmVmaXgoImh0dHA6Ly9hZGRvbnMiKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG1lbnUubG9va3VwUHJlZml4KCJodHRwOi8vYWRkb25zIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBpdGVtLmxvb2t1cFByZWZpeCgiaHR0cDovL2FkZG9ucyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgaXRlbVhtbG5zLmxvb2t1cFByZWZpeCgiaHR0cDovL2FkZG9ucyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgaXRlbVhtbG5zQS5sb29rdXBQcmVmaXgoImh0dHA6Ly9hZGRvbnMiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIG5hbWUubG9va3VwUHJlZml4KCJodHRwOi8vYWRkb25zIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBzdGFuZGFyZC5sb29rdXBQcmVmaXgoImh0dHA6Ly9hZGRvbnMiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIGRlbHV4ZS5sb29rdXBQcmVmaXgoImh0dHA6Ly9hZGRvbnMiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIGRlc2NyaXB0aW9uLmxvb2t1cFByZWZpeCgiaHR0cDovL2FkZG9ucyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgZGVzY3JpcHRpb25UZXh0MS5sb29rdXBQcmVmaXgoImh0dHA6Ly9hZGRvbnMiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIGRlc2NyaXB0aW9uVGV4dDIubG9va3VwUHJlZml4KCJodHRwOi8vYWRkb25zIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBkZXNjcmlwdGlvblRleHQzLmxvb2t1cFByZWZpeCgiaHR0cDovL2FkZG9ucyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgb3B0aW9uMS5sb29rdXBQcmVmaXgoImh0dHA6Ly9hZGRvbnMiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIG9wdGlvbjIubG9va3VwUHJlZml4KCJodHRwOi8vYWRkb25zIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBvcHRpb24yUmVmZXJlbmNlLmxvb2t1cFByZWZpeCgiaHR0cDovL2FkZG9ucyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgd2FmZmxlbWFrZXIubG9va3VwUHJlZml4KCJodHRwOi8vYWRkb25zIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBudXRyaXRpb24ubG9va3VwUHJlZml4KCJodHRwOi8vYWRkb25zIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgdml0YW1pbnMubG9va3VwUHJlZml4KCJodHRwOi8vYWRkb25zIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgdml0YW1pbnNYbWxuc0EubG9va3VwUHJlZml4KCJodHRwOi8vYWRkb25zIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgY29tbWVudC5sb29rdXBQcmVmaXgoImh0dHA6Ly9hZGRvbnMiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCB2aXRhbWluYy5sb29rdXBQcmVmaXgoImh0dHA6Ly9hZGRvbnMiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCB2aXRhbWluY1RleHQubG9va3VwUHJlZml4KCJodHRwOi8vYWRkb25zIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RMb29rdXBQcmVmaXhXaXRoVW51c2VkVXJpKCkgeworICAgICAgICBmb3IgKE5vZGUgbm9kZSA6IGFsbE5vZGVzKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbm9kZS5sb29rdXBQcmVmaXgoImh0dHA6Ly91bnVzZWQiKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9va3VwUHJlZml4V2l0aE51bGxVcmkoKSB7CisgICAgICAgIGZvciAoTm9kZSBub2RlIDogYWxsTm9kZXMpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBub2RlLmxvb2t1cFByZWZpeChudWxsKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9va3VwUHJlZml4V2l0aFNoYWRvd2luZ1VyaSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGRvY3VtZW50Lmxvb2t1cFByZWZpeCgiaHR0cDovL3VzZGEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBkb2N0eXBlLmxvb2t1cFByZWZpeCgiaHR0cDovL3VzZGEiKSk7CisgICAgICAgIGlmIChzcCAhPSBudWxsKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgc3AubG9va3VwUHJlZml4KCJodHRwOi8vdXNkYSIpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocG5nICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBwbmcubG9va3VwUHJlZml4KCJodHRwOi8vdXNkYSIpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbWVudS5sb29rdXBQcmVmaXgoImh0dHA6Ly91c2RhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgaXRlbS5sb29rdXBQcmVmaXgoImh0dHA6Ly91c2RhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgaXRlbVhtbG5zLmxvb2t1cFByZWZpeCgiaHR0cDovL3VzZGEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBpdGVtWG1sbnNBLmxvb2t1cFByZWZpeCgiaHR0cDovL3VzZGEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBuYW1lLmxvb2t1cFByZWZpeCgiaHR0cDovL3VzZGEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBzdGFuZGFyZC5sb29rdXBQcmVmaXgoImh0dHA6Ly91c2RhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZGVsdXhlLmxvb2t1cFByZWZpeCgiaHR0cDovL3VzZGEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBkZXNjcmlwdGlvbi5sb29rdXBQcmVmaXgoImh0dHA6Ly91c2RhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZGVzY3JpcHRpb25UZXh0MS5sb29rdXBQcmVmaXgoImh0dHA6Ly91c2RhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZGVzY3JpcHRpb25UZXh0Mi5sb29rdXBQcmVmaXgoImh0dHA6Ly91c2RhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZGVzY3JpcHRpb25UZXh0My5sb29rdXBQcmVmaXgoImh0dHA6Ly91c2RhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgb3B0aW9uMS5sb29rdXBQcmVmaXgoImh0dHA6Ly91c2RhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgb3B0aW9uMi5sb29rdXBQcmVmaXgoImh0dHA6Ly91c2RhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgb3B0aW9uMlJlZmVyZW5jZS5sb29rdXBQcmVmaXgoImh0dHA6Ly91c2RhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgd2FmZmxlbWFrZXIubG9va3VwUHJlZml4KCJodHRwOi8vdXNkYSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG51dHJpdGlvbi5sb29rdXBQcmVmaXgoImh0dHA6Ly91c2RhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCB2aXRhbWlucy5sb29rdXBQcmVmaXgoImh0dHA6Ly91c2RhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCB2aXRhbWluc1htbG5zQS5sb29rdXBQcmVmaXgoImh0dHA6Ly91c2RhIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBjb21tZW50Lmxvb2t1cFByZWZpeCgiaHR0cDovL3VzZGEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIHZpdGFtaW5jLmxvb2t1cFByZWZpeCgiaHR0cDovL3VzZGEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIHZpdGFtaW5jVGV4dC5sb29rdXBQcmVmaXgoImh0dHA6Ly91c2RhIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJc0RlZmF1bHROYW1lc3BhY2UoKSB7CisgICAgICAgIGFzc2VydEZhbHNlKGRvY3VtZW50LmlzRGVmYXVsdE5hbWVzcGFjZSgiaHR0cDovL2Zvb2QiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGRvY3R5cGUuaXNEZWZhdWx0TmFtZXNwYWNlKCJodHRwOi8vZm9vZCIpKTsKKyAgICAgICAgaWYgKHNwICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHNwLmlzRGVmYXVsdE5hbWVzcGFjZSgiaHR0cDovL2Zvb2QiKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBuZyAhPSBudWxsKSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShwbmcuaXNEZWZhdWx0TmFtZXNwYWNlKCJodHRwOi8vZm9vZCIpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZShtZW51LmlzRGVmYXVsdE5hbWVzcGFjZSgiaHR0cDovL2Zvb2QiKSk7CisgICAgICAgIGFzc2VydFRydWUoaXRlbS5pc0RlZmF1bHROYW1lc3BhY2UoImh0dHA6Ly9mb29kIikpOworICAgICAgICBhc3NlcnRUcnVlKGl0ZW1YbWxucy5pc0RlZmF1bHROYW1lc3BhY2UoImh0dHA6Ly9mb29kIikpOworICAgICAgICBhc3NlcnRUcnVlKGl0ZW1YbWxuc0EuaXNEZWZhdWx0TmFtZXNwYWNlKCJodHRwOi8vZm9vZCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuYW1lLmlzRGVmYXVsdE5hbWVzcGFjZSgiaHR0cDovL2Zvb2QiKSk7CisgICAgICAgIGFzc2VydFRydWUoc3RhbmRhcmQuaXNEZWZhdWx0TmFtZXNwYWNlKCJodHRwOi8vZm9vZCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShkZWx1eGUuaXNEZWZhdWx0TmFtZXNwYWNlKCJodHRwOi8vZm9vZCIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZGVzY3JpcHRpb24uaXNEZWZhdWx0TmFtZXNwYWNlKCJodHRwOi8vZm9vZCIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZGVzY3JpcHRpb25UZXh0MS5pc0RlZmF1bHROYW1lc3BhY2UoImh0dHA6Ly9mb29kIikpOworICAgICAgICBhc3NlcnRGYWxzZShkZXNjcmlwdGlvblRleHQyLmlzRGVmYXVsdE5hbWVzcGFjZSgiaHR0cDovL2Zvb2QiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGRlc2NyaXB0aW9uVGV4dDMuaXNEZWZhdWx0TmFtZXNwYWNlKCJodHRwOi8vZm9vZCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShvcHRpb24xLmlzRGVmYXVsdE5hbWVzcGFjZSgiaHR0cDovL2Zvb2QiKSk7CisgICAgICAgIGFzc2VydFRydWUob3B0aW9uMi5pc0RlZmF1bHROYW1lc3BhY2UoImh0dHA6Ly9mb29kIikpOworICAgICAgICBhc3NlcnRUcnVlKG9wdGlvbjJSZWZlcmVuY2UuaXNEZWZhdWx0TmFtZXNwYWNlKCJodHRwOi8vZm9vZCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh3YWZmbGVtYWtlci5pc0RlZmF1bHROYW1lc3BhY2UoImh0dHA6Ly9mb29kIikpOworICAgICAgICBhc3NlcnRUcnVlKG51dHJpdGlvbi5pc0RlZmF1bHROYW1lc3BhY2UoImh0dHA6Ly9mb29kIikpOworICAgICAgICBhc3NlcnRUcnVlKHZpdGFtaW5zLmlzRGVmYXVsdE5hbWVzcGFjZSgiaHR0cDovL2Zvb2QiKSk7CisgICAgICAgIGFzc2VydFRydWUodml0YW1pbnNYbWxuc0EuaXNEZWZhdWx0TmFtZXNwYWNlKCJodHRwOi8vZm9vZCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjb21tZW50LmlzRGVmYXVsdE5hbWVzcGFjZSgiaHR0cDovL2Zvb2QiKSk7CisgICAgICAgIGFzc2VydFRydWUodml0YW1pbmMuaXNEZWZhdWx0TmFtZXNwYWNlKCJodHRwOi8vZm9vZCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh2aXRhbWluY1RleHQuaXNEZWZhdWx0TmFtZXNwYWNlKCJodHRwOi8vZm9vZCIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBYZXJjZXMgZmFpbHMgdGhpcyB0ZXN0LiBJdCByZXR1cm5zIGZhbHNlIGFsd2F5cyBmb3IgZW50aXR5LCBub3RhdGlvbiwKKyAgICAgKiBkb2N1bWVudCBmcmFnbWVudCBhbmQgZG9jdW1lbnQgdHlwZSBub2Rlcy4gVGhpcyBjb250cmFkaWN0cyBpdHMgb3duCisgICAgICogYmVoYXZpb3VyIG9uIGxvb2t1cE5hbWVzcGFjZVVSSShudWxsKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNEZWZhdWx0TmFtZXNwYWNlTnVsbF9YZXJjZXNCdWdzKCkgeworICAgICAgICBTdHJpbmcgbWVzc2FnZSA9ICJpc0RlZmF1bHROYW1lc3BhY2UoKSBzaG91bGQgYmUgY29uc2lzdGVudCB3aXRoIGxvb2t1cE5hbWVzcGFjZVVSSShudWxsKSI7CisgICAgICAgIGFzc2VydFRydWUobWVzc2FnZSwgZG9jdHlwZS5pc0RlZmF1bHROYW1lc3BhY2UobnVsbCkpOworICAgICAgICBpZiAoc3AgIT0gbnVsbCkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLCBzcC5pc0RlZmF1bHROYW1lc3BhY2UobnVsbCkpOworICAgICAgICB9CisgICAgICAgIGlmIChwbmcgIT0gbnVsbCkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLCBwbmcuaXNEZWZhdWx0TmFtZXNwYWNlKG51bGwpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJc0RlZmF1bHROYW1lc3BhY2VOdWxsKCkgeworICAgICAgICBhc3NlcnRUcnVlKGRvY3VtZW50LmlzRGVmYXVsdE5hbWVzcGFjZShudWxsKSk7CisgICAgICAgIGFzc2VydFRydWUobWVudS5pc0RlZmF1bHROYW1lc3BhY2UobnVsbCkpOworICAgICAgICBhc3NlcnRGYWxzZShpdGVtLmlzRGVmYXVsdE5hbWVzcGFjZShudWxsKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGl0ZW1YbWxucy5pc0RlZmF1bHROYW1lc3BhY2UobnVsbCkpOworICAgICAgICBhc3NlcnRGYWxzZShpdGVtWG1sbnNBLmlzRGVmYXVsdE5hbWVzcGFjZShudWxsKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG5hbWUuaXNEZWZhdWx0TmFtZXNwYWNlKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc3RhbmRhcmQuaXNEZWZhdWx0TmFtZXNwYWNlKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZGVsdXhlLmlzRGVmYXVsdE5hbWVzcGFjZShudWxsKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGRlc2NyaXB0aW9uLmlzRGVmYXVsdE5hbWVzcGFjZShudWxsKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGRlc2NyaXB0aW9uVGV4dDEuaXNEZWZhdWx0TmFtZXNwYWNlKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZGVzY3JpcHRpb25UZXh0Mi5pc0RlZmF1bHROYW1lc3BhY2UobnVsbCkpOworICAgICAgICBhc3NlcnRGYWxzZShkZXNjcmlwdGlvblRleHQzLmlzRGVmYXVsdE5hbWVzcGFjZShudWxsKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG9wdGlvbjEuaXNEZWZhdWx0TmFtZXNwYWNlKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uob3B0aW9uMi5pc0RlZmF1bHROYW1lc3BhY2UobnVsbCkpOworICAgICAgICBhc3NlcnRGYWxzZShvcHRpb24yUmVmZXJlbmNlLmlzRGVmYXVsdE5hbWVzcGFjZShudWxsKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHdhZmZsZW1ha2VyLmlzRGVmYXVsdE5hbWVzcGFjZShudWxsKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG51dHJpdGlvbi5pc0RlZmF1bHROYW1lc3BhY2UobnVsbCkpOworICAgICAgICBhc3NlcnRGYWxzZSh2aXRhbWlucy5pc0RlZmF1bHROYW1lc3BhY2UobnVsbCkpOworICAgICAgICBhc3NlcnRGYWxzZSh2aXRhbWluc1htbG5zQS5pc0RlZmF1bHROYW1lc3BhY2UobnVsbCkpOworICAgICAgICBhc3NlcnRGYWxzZShjb21tZW50LmlzRGVmYXVsdE5hbWVzcGFjZShudWxsKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHZpdGFtaW5jLmlzRGVmYXVsdE5hbWVzcGFjZShudWxsKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHZpdGFtaW5jVGV4dC5pc0RlZmF1bHROYW1lc3BhY2UobnVsbCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REb2N0eXBlU2V0VGV4dENvbnRlbnQoKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgb3JpZ2luYWwgPSBkb21Ub1N0cmluZyhkb2N1bWVudCk7CisgICAgICAgIGRvY3R5cGUuc2V0VGV4dENvbnRlbnQoImZvb2JhciIpOyAvLyBzdHJhbmdlbHksIHRoaXMgaXMgc3BlY2lmaWVkIHRvIG5vLW9wCisgICAgICAgIGFzc2VydEVxdWFscyhvcmlnaW5hbCwgZG9tVG9TdHJpbmcoZG9jdW1lbnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RG9jdW1lbnRTZXRUZXh0Q29udGVudCgpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBvcmlnaW5hbCA9IGRvbVRvU3RyaW5nKGRvY3VtZW50KTsKKyAgICAgICAgZG9jdW1lbnQuc2V0VGV4dENvbnRlbnQoImZvb2JhciIpOyAvLyBzdHJhbmdlbHksIHRoaXMgaXMgc3BlY2lmaWVkIHRvIG5vLW9wCisgICAgICAgIGFzc2VydEVxdWFscyhvcmlnaW5hbCwgZG9tVG9TdHJpbmcoZG9jdW1lbnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RWxlbWVudFNldFRleHRDb250ZW50KCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIG9yaWdpbmFsID0gZG9tVG9TdHJpbmcoZG9jdW1lbnQpOworICAgICAgICBudXRyaXRpb24uc2V0VGV4dENvbnRlbnQoImZvb2JhciIpOworICAgICAgICBTdHJpbmcgZXhwZWN0ZWQgPSBvcmlnaW5hbC5yZXBsYWNlRmlyc3QoCisgICAgICAgICAgICAgICAgIig/cyk8bnV0cml0aW9uPi4qPC9udXRyaXRpb24+IiwgIjxudXRyaXRpb24+Zm9vYmFyPC9udXRyaXRpb24+Iik7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwgZG9tVG9TdHJpbmcoZG9jdW1lbnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW50aXR5U2V0VGV4dENvbnRlbnQoKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24geworICAgICAgICBpZiAoc3AgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzcC5zZXRUZXh0Q29udGVudCgiZm9vYmFyIik7CisgICAgICAgICAgICBmYWlsKCk7IC8vIGlzIHRoaXMgaW1wbGVtZW50YXRpb24tc3BlY2lmaWMgYmVoYXZpb3VyPworICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vdGF0aW9uU2V0VGV4dENvbnRlbnQoKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24geworICAgICAgICBpZiAocG5nID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgb3JpZ2luYWwgPSBkb21Ub1N0cmluZyhkb2N1bWVudCk7CisgICAgICAgIHBuZy5zZXRUZXh0Q29udGVudCgiZm9vYmFyIik7CisgICAgICAgIFN0cmluZyBleHBlY3RlZCA9IG9yaWdpbmFsLnJlcGxhY2UoImltYWdlL3BuZyIsICJmb29iYXIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBkb21Ub1N0cmluZyhkb2N1bWVudCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHNldFRleHRDb250ZW50IG9uIGVudGl0eSByZWZlcmVuY2VzLiBBbHRob3VnaCB0aGUgb3RoZXIgdGVzdHMgY2FuCisgICAgICogYWN0IG9uIGEgcGFyc2VkIERPTSwgdGhpcyBuZWVkcyB0byB1c2UgYSBwcm9ncmFtbWF0aWNhbGx5IGNvbnN0cnVjdGVkIERPTQorICAgICAqIGJlY2F1c2UgdGhlIHBhcnNlciBtYXkgaGF2ZSByZXBsYWNlZCB0aGUgZW50aXR5IHJlZmVyZW5jZSB3aXRoIHRoZQorICAgICAqIGNvcnJlc3BvbmRpbmcgdGV4dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW50aXR5UmVmZXJlbmNlU2V0VGV4dENvbnRlbnQoKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24geworICAgICAgICBkb2N1bWVudCA9IGJ1aWxkZXIubmV3RG9jdW1lbnQoKTsKKyAgICAgICAgRWxlbWVudCByb290ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgibWVudSIpOworICAgICAgICBkb2N1bWVudC5hcHBlbmRDaGlsZChyb290KTsKKworICAgICAgICBFbnRpdHlSZWZlcmVuY2UgZW50aXR5UmVmZXJlbmNlID0gZG9jdW1lbnQuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJzcCIpOworICAgICAgICByb290LmFwcGVuZENoaWxkKGVudGl0eVJlZmVyZW5jZSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVudGl0eVJlZmVyZW5jZS5zZXRUZXh0Q29udGVudCgiTGl0ZSBTeXJ1cCIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEF0dHJpYnV0ZVNldFRleHRDb250ZW50KCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIG9yaWdpbmFsID0gZG9tVG9TdHJpbmcoZG9jdW1lbnQpOworICAgICAgICBzdGFuZGFyZC5zZXRUZXh0Q29udGVudCgiZm9vYmFyIik7CisgICAgICAgIFN0cmluZyBleHBlY3RlZCA9IG9yaWdpbmFsLnJlcGxhY2UoInN0YW5kYXJkPVwic3RyYXdiZXJyeVwiIiwgInN0YW5kYXJkPVwiZm9vYmFyXCIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBkb21Ub1N0cmluZyhkb2N1bWVudCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUZXh0U2V0VGV4dENvbnRlbnQoKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgb3JpZ2luYWwgPSBkb21Ub1N0cmluZyhkb2N1bWVudCk7CisgICAgICAgIGRlc2NyaXB0aW9uVGV4dDEuc2V0VGV4dENvbnRlbnQoImZvb2JhciIpOworICAgICAgICBTdHJpbmcgZXhwZWN0ZWQgPSBvcmlnaW5hbC5yZXBsYWNlKCI+QmVsZ2lhbjwhIiwgIj5mb29iYXI8ISIpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIGRvbVRvU3RyaW5nKGRvY3VtZW50KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENkYXRhU2V0VGV4dENvbnRlbnQoKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgb3JpZ2luYWwgPSBkb21Ub1N0cmluZyhkb2N1bWVudCk7CisgICAgICAgIGRlc2NyaXB0aW9uVGV4dDIuc2V0VGV4dENvbnRlbnQoImZvb2JhciIpOworICAgICAgICBTdHJpbmcgZXhwZWN0ZWQgPSBvcmlnaW5hbC5yZXBsYWNlKAorICAgICAgICAgICAgICAgICIgd2FmZmxlcyAmIHN0cmF3YmVycmllcyAoPCA1ZyAiLCAiZm9vYmFyIik7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwgZG9tVG9TdHJpbmcoZG9jdW1lbnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJvY2Vzc2luZ0luc3RydWN0aW9uU2V0VGV4dENvbnRlbnQoKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgb3JpZ2luYWwgPSBkb21Ub1N0cmluZyhkb2N1bWVudCk7CisgICAgICAgIHdhZmZsZW1ha2VyLnNldFRleHRDb250ZW50KCJmb29iYXIiKTsKKyAgICAgICAgU3RyaW5nIGV4cGVjdGVkID0gb3JpZ2luYWwucmVwbGFjZSgiIHNxdWFyZSBzaGFwZT8+IiwgIiBmb29iYXI/PiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIGRvbVRvU3RyaW5nKGRvY3VtZW50KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbW1lbnRTZXRUZXh0Q29udGVudCgpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBvcmlnaW5hbCA9IGRvbVRvU3RyaW5nKGRvY3VtZW50KTsKKyAgICAgICAgY29tbWVudC5zZXRUZXh0Q29udGVudCgiZm9vYmFyIik7CisgICAgICAgIFN0cmluZyBleHBlY3RlZCA9IG9yaWdpbmFsLnJlcGxhY2UoIi0tIGFkZCBvdGhlciB2aXRhbWlucz8gLS0iLCAiLS1mb29iYXItLSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIGRvbVRvU3RyaW5nKGRvY3VtZW50KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvcmVGZWF0dXJlKCkgeworICAgICAgICBhc3NlcnRGZWF0dXJlKCJDb3JlIiwgbnVsbCk7CisgICAgICAgIGFzc2VydEZlYXR1cmUoIkNvcmUiLCAiIik7CisgICAgICAgIGFzc2VydEZlYXR1cmUoIkNvcmUiLCAiMS4wIik7CisgICAgICAgIGFzc2VydEZlYXR1cmUoIkNvcmUiLCAiMi4wIik7CisgICAgICAgIGFzc2VydEZlYXR1cmUoIkNvcmUiLCAiMy4wIik7CisgICAgICAgIGFzc2VydEZlYXR1cmUoIkNPUkUiLCAiMy4wIik7CisgICAgICAgIGFzc2VydEZlYXR1cmUoIitDb3JlIiwgIjMuMCIpOworICAgICAgICBhc3NlcnROb0ZlYXR1cmUoIkNvcmUiLCAiNC4wIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFhtbEZlYXR1cmUoKSB7CisgICAgICAgIGFzc2VydEZlYXR1cmUoIlhNTCIsIG51bGwpOworICAgICAgICBhc3NlcnRGZWF0dXJlKCJYTUwiLCAiIik7CisgICAgICAgIGFzc2VydEZlYXR1cmUoIlhNTCIsICIxLjAiKTsKKyAgICAgICAgYXNzZXJ0RmVhdHVyZSgiWE1MIiwgIjIuMCIpOworICAgICAgICBhc3NlcnRGZWF0dXJlKCJYTUwiLCAiMy4wIik7CisgICAgICAgIGFzc2VydEZlYXR1cmUoIlhtbCIsICIzLjAiKTsKKyAgICAgICAgYXNzZXJ0RmVhdHVyZSgiK1hNTCIsICIzLjAiKTsKKyAgICAgICAgYXNzZXJ0Tm9GZWF0dXJlKCJYTUwiLCAiNC4wIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIFJJIGZhaWxzIHRoaXMgdGVzdC4KKyAgICAgKiBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3L2NvcmUuaHRtbCNEb2N1bWVudDMtdmVyc2lvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RYbWxWZXJzaW9uRmVhdHVyZSgpIHsKKyAgICAgICAgYXNzZXJ0RmVhdHVyZSgiWE1MVmVyc2lvbiIsIG51bGwpOworICAgICAgICBhc3NlcnRGZWF0dXJlKCJYTUxWZXJzaW9uIiwgIiIpOworICAgICAgICBhc3NlcnRGZWF0dXJlKCJYTUxWZXJzaW9uIiwgIjEuMCIpOworICAgICAgICBhc3NlcnRGZWF0dXJlKCJYTUxWZXJzaW9uIiwgIjEuMSIpOworICAgICAgICBhc3NlcnRGZWF0dXJlKCJYTUxWRVJTSU9OIiwgIjEuMSIpOworICAgICAgICBhc3NlcnRGZWF0dXJlKCIrWE1MVmVyc2lvbiIsICIxLjEiKTsKKyAgICAgICAgYXNzZXJ0Tm9GZWF0dXJlKCJYTUxWZXJzaW9uIiwgIjEuMiIpOworICAgICAgICBhc3NlcnROb0ZlYXR1cmUoIlhNTFZlcnNpb24iLCAiMi4wIik7CisgICAgICAgIGFzc2VydE5vRmVhdHVyZSgiWE1MVmVyc2lvbiIsICIyLjAiKTsKKyAgICB9CisKKyAgICBAS25vd25GYWlsdXJlKCJEYWx2aWsgZG9lc24ndCBzdXBwb3J0IGxvYWQvc2F2ZSIpCisgICAgcHVibGljIHZvaWQgdGVzdExvYWRTYXZlRmVhdHVyZSgpIHsKKyAgICAgICAgYXNzZXJ0RmVhdHVyZSgiTFMiLCAiMy4wIik7CisgICAgfQorCisgICAgQEtub3duRmFpbHVyZSgiRGFsdmlrIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgZWxlbWVudCB0cmF2ZXJzYWwgZmVhdHVyZSIpCisgICAgcHVibGljIHZvaWQgdGVzdEVsZW1lbnRUcmF2ZXJzYWxGZWF0dXJlKCkgeworICAgICAgICBhc3NlcnRGZWF0dXJlKCJFbGVtZW50VHJhdmVyc2FsIiwgIjEuMCIpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRGZWF0dXJlKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikgeworICAgICAgICBTdHJpbmcgbWVzc2FnZSA9ICJUaGlzIGltcGxlbWVudGF0aW9uIGlzIGV4cGVjdGVkIHRvIHN1cHBvcnQgIgorICAgICAgICAgICAgICAgICsgZmVhdHVyZSArICIgdi4gIiArIHZlcnNpb24gKyAiIGJ1dCBkb2VzIG5vdC4iOworICAgICAgICBhc3NlcnRUcnVlKG1lc3NhZ2UsIGRvbUltcGxlbWVudGF0aW9uLmhhc0ZlYXR1cmUoZmVhdHVyZSwgdmVyc2lvbikpOworICAgICAgICBhc3NlcnROb3ROdWxsKG1lc3NhZ2UsIGRvbUltcGxlbWVudGF0aW9uLmdldEZlYXR1cmUoZmVhdHVyZSwgdmVyc2lvbikpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnROb0ZlYXR1cmUoU3RyaW5nIGZlYXR1cmUsIFN0cmluZyB2ZXJzaW9uKSB7CisgICAgICAgIGFzc2VydEZhbHNlKGRvbUltcGxlbWVudGF0aW9uLmhhc0ZlYXR1cmUoZmVhdHVyZSwgdmVyc2lvbikpOworICAgICAgICBhc3NlcnROdWxsKGRvbUltcGxlbWVudGF0aW9uLmdldEZlYXR1cmUoZmVhdHVyZSwgdmVyc2lvbikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJc1N1cHBvcnRlZCgpIHsKKyAgICAgICAgLy8gd2UgZG9uJ3QgaW5kZXBlbmRlbnRseSB0ZXN0IHRoZSBmZWF0dXJlczsgaW5zdGVhZCBqdXN0IGFzc3VtZSB0aGUKKyAgICAgICAgLy8gaW1wbGVtZW50YXRpb24gY2FsbHMgdGhyb3VnaCB0byBoYXNGZWF0dXJlIChhcyB0ZXN0ZWQgYWJvdmUpCisgICAgICAgIGZvciAoTm9kZSBub2RlIDogYWxsTm9kZXMpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUobm9kZS5pc1N1cHBvcnRlZCgiWE1MIiwgbnVsbCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShub2RlLmlzU3VwcG9ydGVkKCJYTUwiLCAiMy4wIikpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uobm9kZS5pc1N1cHBvcnRlZCgiZm9vIiwgbnVsbCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uobm9kZS5pc1N1cHBvcnRlZCgiZm9vIiwgImJhciIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRGZWF0dXJlKCkgeworICAgICAgICAvLyB3ZSBkb24ndCBpbmRlcGVuZGVudGx5IHRlc3QgdGhlIGZlYXR1cmVzOyBpbnN0ZWFkIGp1c3QgYXNzdW1lIHRoZQorICAgICAgICAvLyBpbXBsZW1lbnRhdGlvbiBjYWxscyB0aHJvdWdoIHRvIGhhc0ZlYXR1cmUgKGFzIHRlc3RlZCBhYm92ZSkKKyAgICAgICAgZm9yIChOb2RlIG5vZGUgOiBhbGxOb2RlcykgeworICAgICAgICAgICAgYXNzZXJ0U2FtZShub2RlLCBub2RlLmdldEZlYXR1cmUoIlhNTCIsIG51bGwpKTsKKyAgICAgICAgICAgIGFzc2VydFNhbWUobm9kZSwgbm9kZS5nZXRGZWF0dXJlKCJYTUwiLCAiMy4wIikpOworICAgICAgICAgICAgYXNzZXJ0TnVsbChub2RlLmdldEZlYXR1cmUoImZvbyIsIG51bGwpKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwobm9kZS5nZXRGZWF0dXJlKCJmb28iLCAiYmFyIikpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vZGVFcXVhbHNQb3NpdGl2ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEb21UZXN0IGNvcHkgPSBuZXcgRG9tVGVzdCgpOworICAgICAgICBjb3B5LnNldFVwKCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGxOb2Rlcy5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgTm9kZSBhID0gYWxsTm9kZXMuZ2V0KGkpOworICAgICAgICAgICAgTm9kZSBiID0gY29weS5hbGxOb2Rlcy5nZXQoaSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGEuaXNFcXVhbE5vZGUoYikpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vZGVFcXVhbHNOZWdhdGl2ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKE5vZGUgYSA6IGFsbE5vZGVzKSB7CisgICAgICAgICAgICBmb3IgKE5vZGUgYiA6IGFsbE5vZGVzKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGEgPT0gYiwgYS5pc0VxdWFsTm9kZShiKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9kZUVxdWFsc05lZ2F0aXZlUmVjdXJzaXZlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIERvbVRlc3QgY29weSA9IG5ldyBEb21UZXN0KCk7CisgICAgICAgIGNvcHkuc2V0VXAoKTsKKyAgICAgICAgY29weS52aXRhbWluYy5zZXRUZXh0Q29udGVudCgiNTUlIik7CisKKyAgICAgICAgLy8gY2hhbmdpbmcgYW55dGhpbmcgYWJvdXQgYSBub2RlIHNob3VsZCBicmVhayBlcXVhbGl0eSBmb3IgYWxsIHBhcmVudHMKKyAgICAgICAgYXNzZXJ0RmFsc2UoZG9jdW1lbnQuaXNFcXVhbE5vZGUoY29weS5kb2N1bWVudCkpOworICAgICAgICBhc3NlcnRGYWxzZShtZW51LmlzRXF1YWxOb2RlKGNvcHkubWVudSkpOworICAgICAgICBhc3NlcnRGYWxzZShpdGVtLmlzRXF1YWxOb2RlKGNvcHkuaXRlbSkpOworICAgICAgICBhc3NlcnRGYWxzZShudXRyaXRpb24uaXNFcXVhbE5vZGUoY29weS5udXRyaXRpb24pKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uodml0YW1pbnMuaXNFcXVhbE5vZGUoY29weS52aXRhbWlucykpOworICAgICAgICBhc3NlcnRGYWxzZSh2aXRhbWluYy5pc0VxdWFsTm9kZShjb3B5LnZpdGFtaW5jKSk7CisKKyAgICAgICAgLy8gYnV0IG5vdCBzaWJsaW5ncworICAgICAgICBhc3NlcnRUcnVlKGRvY3R5cGUuaXNFcXVhbE5vZGUoY29weS5kb2N0eXBlKSk7CisgICAgICAgIGFzc2VydFRydWUoZGVzY3JpcHRpb24uaXNFcXVhbE5vZGUoY29weS5kZXNjcmlwdGlvbikpOworICAgICAgICBhc3NlcnRUcnVlKG9wdGlvbjEuaXNFcXVhbE5vZGUoY29weS5vcHRpb24xKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vZGVFcXVhbHNOdWxsKCkgeworICAgICAgICBmb3IgKE5vZGUgbm9kZSA6IGFsbE5vZGVzKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG5vZGUuaXNFcXVhbE5vZGUobnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdElzRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlV2l0aG91dERlY2xhcmF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB4bWwgPSAiPG1lbnU+ICAgIDxpdGVtLz4gICA8L21lbnU+IjsKKworICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisgICAgICAgIFRleHQgdGV4dCA9IChUZXh0KSBmYWN0b3J5Lm5ld0RvY3VtZW50QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShuZXcgU3RyaW5nUmVhZGVyKHhtbCkpKQorICAgICAgICAgICAgICAgIC5nZXREb2N1bWVudEVsZW1lbnQoKS5nZXRDaGlsZE5vZGVzKCkuaXRlbSgwKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UodGV4dC5pc0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSgpKTsKKyAgICB9CisKKyAgICBAS25vd25GYWlsdXJlKCJEYWx2aWsgZG9lc24ndCByZWNvZ25pemUgZWxlbWVudCBjb250ZW50IHdoaXRlc3BhY2UiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RJc0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZVdpdGhEZWNsYXJhdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgeG1sID0gIjwhRE9DVFlQRSBtZW51IFtcbiIKKyAgICAgICAgICAgICAgICArICIgIDwhRUxFTUVOVCBtZW51IChpdGVtKSo+XG4iCisgICAgICAgICAgICAgICAgKyAiICA8IUVMRU1FTlQgaXRlbSAoI1BDREFUQSk+XG4iCisgICAgICAgICAgICAgICAgKyAiXT48bWVudT4gICAgPGl0ZW0vPiAgIDwvbWVudT4iOworCisgICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9IERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgVGV4dCB0ZXh0ID0gKFRleHQpIGZhY3RvcnkubmV3RG9jdW1lbnRCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAucGFyc2UobmV3IElucHV0U291cmNlKG5ldyBTdHJpbmdSZWFkZXIoeG1sKSkpCisgICAgICAgICAgICAgICAgLmdldERvY3VtZW50RWxlbWVudCgpLmdldENoaWxkTm9kZXMoKS5pdGVtKDApOworICAgICAgICBhc3NlcnRUcnVlKCJUaGlzIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHJlY29nbml6ZSBlbGVtZW50IGNvbnRlbnQgd2hpdGVzcGFjZSIsCisgICAgICAgICAgICAgICAgdGV4dC5pc0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0V2hvbGVUZXh0Rmlyc3QoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiQmVsZ2lhbiB3YWZmbGVzICYgc3RyYXdiZXJyaWVzICg8IDVnIG9mIGZhdCkiLAorICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uVGV4dDEuZ2V0V2hvbGVUZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRXaG9sZVRleHRNaWRkbGUoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhpcyBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IGluY2x1ZGUgcHJlY2VkaW5nIG5vZGVzIGluIGdldFdob2xlVGV4dCgpIiwKKyAgICAgICAgICAgICAgICAiQmVsZ2lhbiB3YWZmbGVzICYgc3RyYXdiZXJyaWVzICg8IDVnIG9mIGZhdCkiLCBkZXNjcmlwdGlvblRleHQyLmdldFdob2xlVGV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0V2hvbGVUZXh0TGFzdCgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGlzIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgaW5jbHVkZSBwcmVjZWRpbmcgbm9kZXMgaW4gZ2V0V2hvbGVUZXh0KCkiLAorICAgICAgICAgICAgICAgICJCZWxnaWFuIHdhZmZsZXMgJiBzdHJhd2JlcnJpZXMgKDwgNWcgb2YgZmF0KSIsIGRlc2NyaXB0aW9uVGV4dDMuZ2V0V2hvbGVUZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRXaG9sZVRleHRPbmx5KCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIjYwJSIsIHZpdGFtaW5jVGV4dC5nZXRXaG9sZVRleHQoKSk7CisgICAgfQorCisgICAgQEtub3duRmFpbHVyZSgiRGFsdmlrIGRvZXNuJ3QgcmVzb2x2ZSBlbnRpdHkgcmVmZXJlbmNlcyIpCisgICAgcHVibGljIHZvaWQgdGVzdEdldFdob2xlVGV4dFdpdGhFbnRpdHlSZWZlcmVuY2UoKSB7CisgICAgICAgIEVudGl0eVJlZmVyZW5jZSBzcFJlZmVyZW5jZSA9IGRvY3VtZW50LmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgic3AiKTsKKyAgICAgICAgZGVzY3JpcHRpb24uaW5zZXJ0QmVmb3JlKHNwUmVmZXJlbmNlLCBkZXNjcmlwdGlvblRleHQyKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlRoaXMgaW1wbGVtZW50YXRpb24gZG9lc24ndCByZXNvbHZlIGVudGl0eSByZWZlcmVuY2VzIGluIGdldFdob2xlVGV4dCgpIiwKKyAgICAgICAgICAgICAgICAiQmVsZ2lhbk1hcGxlIFN5cnVwIHdhZmZsZXMgJiBzdHJhd2JlcnJpZXMgKDwgNWcgb2YgZmF0KSIsCisgICAgICAgICAgICAgICAgZGVzY3JpcHRpb25UZXh0MS5nZXRXaG9sZVRleHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlcGxhY2VXaG9sZVRleHRGaXJzdCgpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBvcmlnaW5hbCA9IGRvbVRvU3RyaW5nKGRvY3VtZW50KTsKKyAgICAgICAgVGV4dCByZXBsYWNlbWVudCA9IGRlc2NyaXB0aW9uVGV4dDEucmVwbGFjZVdob2xlVGV4dCgiRWdnb3MiKTsKKyAgICAgICAgYXNzZXJ0U2FtZShkZXNjcmlwdGlvblRleHQxLCByZXBsYWNlbWVudCk7CisgICAgICAgIFN0cmluZyBleHBlY3RlZCA9IG9yaWdpbmFsLnJlcGxhY2UoCisgICAgICAgICAgICAgICAgIkJlbGdpYW48IVtDREFUQVsgd2FmZmxlcyAmIHN0cmF3YmVycmllcyAoPCA1ZyBdXT5vZiBmYXQpIiwgIkVnZ29zIik7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwgZG9tVG9TdHJpbmcoZG9jdW1lbnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVwbGFjZVdob2xlVGV4dE1pZGRsZSgpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBvcmlnaW5hbCA9IGRvbVRvU3RyaW5nKGRvY3VtZW50KTsKKyAgICAgICAgVGV4dCByZXBsYWNlbWVudCA9IGRlc2NyaXB0aW9uVGV4dDIucmVwbGFjZVdob2xlVGV4dCgiRWdnb3MiKTsKKyAgICAgICAgYXNzZXJ0U2FtZShkZXNjcmlwdGlvblRleHQyLCByZXBsYWNlbWVudCk7CisgICAgICAgIFN0cmluZyBleHBlY3RlZCA9IG9yaWdpbmFsLnJlcGxhY2UoCisgICAgICAgICAgICAgICAgIkJlbGdpYW48IVtDREFUQVsgd2FmZmxlcyAmIHN0cmF3YmVycmllcyAoPCA1ZyBdXT5vZiBmYXQpIiwgIjwhW0NEQVRBW0VnZ29zXV0+Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhpcyBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHJlbW92ZSBwcmVjZWRpbmcgbm9kZXMgaW4gcmVwbGFjZVdob2xlVGV4dCgpIiwKKyAgICAgICAgICAgICAgICBleHBlY3RlZCwgZG9tVG9TdHJpbmcoZG9jdW1lbnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVwbGFjZVdob2xlVGV4dExhc3QoKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgb3JpZ2luYWwgPSBkb21Ub1N0cmluZyhkb2N1bWVudCk7CisgICAgICAgIFRleHQgcmVwbGFjZW1lbnQgPSBkZXNjcmlwdGlvblRleHQzLnJlcGxhY2VXaG9sZVRleHQoIkVnZ29zIik7CisgICAgICAgIGFzc2VydFNhbWUoZGVzY3JpcHRpb25UZXh0MywgcmVwbGFjZW1lbnQpOworICAgICAgICBTdHJpbmcgZXhwZWN0ZWQgPSBvcmlnaW5hbC5yZXBsYWNlKAorICAgICAgICAgICAgICAgICJCZWxnaWFuPCFbQ0RBVEFbIHdhZmZsZXMgJiBzdHJhd2JlcnJpZXMgKDwgNWcgXV0+b2YgZmF0KSIsICJFZ2dvcyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRoaXMgaW1wbGVtZW50YXRpb24gZG9lc24ndCByZW1vdmUgcHJlY2VkaW5nIG5vZGVzIGluIHJlcGxhY2VXaG9sZVRleHQoKSIsCisgICAgICAgICAgICAgICAgZXhwZWN0ZWQsIGRvbVRvU3RyaW5nKGRvY3VtZW50KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlcGxhY2VXaG9sZVRleHRPbmx5KCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIG9yaWdpbmFsID0gZG9tVG9TdHJpbmcoZG9jdW1lbnQpOworICAgICAgICBUZXh0IHJlcGxhY2VtZW50ID0gdml0YW1pbmNUZXh0LnJlcGxhY2VXaG9sZVRleHQoIjcwJSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoTm9kZS5URVhUX05PREUsIHJlcGxhY2VtZW50LmdldE5vZGVUeXBlKCkpOworICAgICAgICBhc3NlcnRTYW1lKHZpdGFtaW5jVGV4dCwgcmVwbGFjZW1lbnQpOworICAgICAgICBTdHJpbmcgZXhwZWN0ZWQgPSBvcmlnaW5hbC5yZXBsYWNlKCI2MCUiLCAiNzAlIik7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwgZG9tVG9TdHJpbmcoZG9jdW1lbnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVwbGFjZVdob2xlVGV4dEZpcnN0V2l0aE51bGwoKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgb3JpZ2luYWwgPSBkb21Ub1N0cmluZyhkb2N1bWVudCk7CisgICAgICAgIGFzc2VydE51bGwoZGVzY3JpcHRpb25UZXh0MS5yZXBsYWNlV2hvbGVUZXh0KG51bGwpKTsKKyAgICAgICAgU3RyaW5nIGV4cGVjdGVkID0gb3JpZ2luYWwucmVwbGFjZUZpcnN0KCI+Lio8L2Rlc2NyaXB0aW9uPiIsICIvPiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRoaXMgaW1wbGVtZW50YXRpb24gZG9lc24ndCByZW1vdmUgYWRqYWNlbnQgbm9kZXMgaW4gcmVwbGFjZVdob2xlVGV4dChudWxsKSIsCisgICAgICAgICAgICAgICAgZXhwZWN0ZWQsIGRvbVRvU3RyaW5nKGRvY3VtZW50KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlcGxhY2VXaG9sZVRleHRNaWRkbGVXaXRoTnVsbCgpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBvcmlnaW5hbCA9IGRvbVRvU3RyaW5nKGRvY3VtZW50KTsKKyAgICAgICAgYXNzZXJ0TnVsbChkZXNjcmlwdGlvblRleHQyLnJlcGxhY2VXaG9sZVRleHQobnVsbCkpOworICAgICAgICBTdHJpbmcgZXhwZWN0ZWQgPSBvcmlnaW5hbC5yZXBsYWNlRmlyc3QoIj4uKjwvZGVzY3JpcHRpb24+IiwgIi8+Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhpcyBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHJlbW92ZSBhZGphY2VudCBub2RlcyBpbiByZXBsYWNlV2hvbGVUZXh0KG51bGwpIiwKKyAgICAgICAgICAgICAgICBleHBlY3RlZCwgZG9tVG9TdHJpbmcoZG9jdW1lbnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVwbGFjZVdob2xlVGV4dExhc3RXaXRoTnVsbCgpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBvcmlnaW5hbCA9IGRvbVRvU3RyaW5nKGRvY3VtZW50KTsKKyAgICAgICAgYXNzZXJ0TnVsbChkZXNjcmlwdGlvblRleHQzLnJlcGxhY2VXaG9sZVRleHQobnVsbCkpOworICAgICAgICBTdHJpbmcgZXhwZWN0ZWQgPSBvcmlnaW5hbC5yZXBsYWNlRmlyc3QoIj4uKjwvZGVzY3JpcHRpb24+IiwgIi8+Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhpcyBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHJlbW92ZSBhZGphY2VudCBub2RlcyBpbiByZXBsYWNlV2hvbGVUZXh0KG51bGwpIiwKKyAgICAgICAgICAgICAgICBleHBlY3RlZCwgZG9tVG9TdHJpbmcoZG9jdW1lbnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVwbGFjZVdob2xlVGV4dEZpcnN0V2l0aEVtcHR5U3RyaW5nKCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIG9yaWdpbmFsID0gZG9tVG9TdHJpbmcoZG9jdW1lbnQpOworICAgICAgICBhc3NlcnROdWxsKGRlc2NyaXB0aW9uVGV4dDEucmVwbGFjZVdob2xlVGV4dCgiIikpOworICAgICAgICBTdHJpbmcgZXhwZWN0ZWQgPSBvcmlnaW5hbC5yZXBsYWNlRmlyc3QoIj4uKjwvZGVzY3JpcHRpb24+IiwgIi8+Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhpcyBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHJlbW92ZSBhZGphY2VudCBub2RlcyBpbiByZXBsYWNlV2hvbGVUZXh0KG51bGwpIiwKKyAgICAgICAgICAgICAgICBleHBlY3RlZCwgZG9tVG9TdHJpbmcoZG9jdW1lbnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVwbGFjZVdob2xlVGV4dE9ubHlXaXRoRW1wdHlTdHJpbmcoKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgb3JpZ2luYWwgPSBkb21Ub1N0cmluZyhkb2N1bWVudCk7CisgICAgICAgIGFzc2VydE51bGwodml0YW1pbmNUZXh0LnJlcGxhY2VXaG9sZVRleHQoIiIpKTsKKyAgICAgICAgU3RyaW5nIGV4cGVjdGVkID0gb3JpZ2luYWwucmVwbGFjZUZpcnN0KCI+Lio8L2E6dml0YW1pbmM+IiwgIi8+Iik7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwgZG9tVG9TdHJpbmcoZG9jdW1lbnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXNlckRhdGFBdHRhY2htZW50cygpIHsKKyAgICAgICAgT2JqZWN0IGEgPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIE9iamVjdCBiID0gbmV3IE9iamVjdCgpOworICAgICAgICBmb3IgKE5vZGUgbm9kZSA6IGFsbE5vZGVzKSB7CisgICAgICAgICAgICBub2RlLnNldFVzZXJEYXRhKCJhIiwgYSwgbnVsbCk7CisgICAgICAgICAgICBub2RlLnNldFVzZXJEYXRhKCJiIiwgYiwgbnVsbCk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChOb2RlIG5vZGUgOiBhbGxOb2RlcykgeworICAgICAgICAgICAgYXNzZXJ0U2FtZShhLCBub2RlLmdldFVzZXJEYXRhKCJhIikpOworICAgICAgICAgICAgYXNzZXJ0U2FtZShiLCBub2RlLmdldFVzZXJEYXRhKCJiIikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG5vZGUuZ2V0VXNlckRhdGEoImMiKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbm9kZS5nZXRVc2VyRGF0YSgiQSIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVc2VyRGF0YVJlamVjdHNOdWxsS2V5KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWVudS5zZXRVc2VyRGF0YShudWxsLCAiYXBwbGUiLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtZW51LmdldFVzZXJEYXRhKG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmFsdWVPZk5ld0F0dHJpYnV0ZXNJc0VtcHR5U3RyaW5nKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGRvY3VtZW50LmNyZWF0ZUF0dHJpYnV0ZSgiYmFyIikuZ2V0VmFsdWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgZG9jdW1lbnQuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly9mb28iLCAiYmFyIikuZ2V0VmFsdWUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENsb25lTm9kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkb2N1bWVudCA9IGJ1aWxkZXIucGFyc2UobmV3IElucHV0U291cmNlKG5ldyBTdHJpbmdSZWFkZXIoIjxtZW51ICIKKyAgICAgICAgICAgICAgICArICJ4bWxuczpmPVwiaHR0cDovL2Zvb2RcIiB4bWxuczphPVwiaHR0cDovL2FkZG9uc1wiPiIKKyAgICAgICAgICAgICAgICArICI8ZjppdGVtIGE6c3RhbmRhcmQ9XCJzdHJhd2JlcnJ5XCIgZGVsdXhlPVwieWVzXCI+V2FmZmxlczwvZjppdGVtPjwvbWVudT4iKSkpOworICAgICAgICBuYW1lID0gKEVsZW1lbnQpIGRvY3VtZW50LmdldEZpcnN0Q2hpbGQoKS5nZXRGaXJzdENoaWxkKCk7CisKKyAgICAgICAgRWxlbWVudCBjbG9uZWROYW1lID0gKEVsZW1lbnQpIG5hbWUuY2xvbmVOb2RlKHRydWUpOworICAgICAgICBhc3NlcnROdWxsKGNsb25lZE5hbWUuZ2V0UGFyZW50Tm9kZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjbG9uZWROYW1lLmdldE5leHRTaWJsaW5nKCkpOworICAgICAgICBhc3NlcnROdWxsKGNsb25lZE5hbWUuZ2V0UHJldmlvdXNTaWJsaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9mb29kIiwgY2xvbmVkTmFtZS5nZXROYW1lc3BhY2VVUkkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZjppdGVtIiwgY2xvbmVkTmFtZS5nZXROb2RlTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpdGVtIiwgY2xvbmVkTmFtZS5nZXRMb2NhbE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2Zvb2QiLCBjbG9uZWROYW1lLmdldE5hbWVzcGFjZVVSSSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ5ZXMiLCBjbG9uZWROYW1lLmdldEF0dHJpYnV0ZSgiZGVsdXhlIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoInN0cmF3YmVycnkiLCBjbG9uZWROYW1lLmdldEF0dHJpYnV0ZSgiYTpzdGFuZGFyZCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdHJhd2JlcnJ5IiwgY2xvbmVkTmFtZS5nZXRBdHRyaWJ1dGVOUygiaHR0cDovL2FkZG9ucyIsICJzdGFuZGFyZCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG5hbWUuZ2V0Q2hpbGROb2RlcygpLmdldExlbmd0aCgpKTsKKworICAgICAgICBUZXh0IGNsb25lZENoaWxkID0gKFRleHQpIGNsb25lZE5hbWUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgICBhc3NlcnRTYW1lKGNsb25lZE5hbWUsIGNsb25lZENoaWxkLmdldFBhcmVudE5vZGUoKSk7CisgICAgICAgIGFzc2VydE51bGwoY2xvbmVkQ2hpbGQuZ2V0TmV4dFNpYmxpbmcoKSk7CisgICAgICAgIGFzc2VydE51bGwoY2xvbmVkQ2hpbGQuZ2V0UHJldmlvdXNTaWJsaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldhZmZsZXMiLCBjbG9uZWRDaGlsZC5nZXRUZXh0Q29udGVudCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXZSBjYW4ndCB1c2UgdGhlIG5hbWVzcGFjZS1hd2FyZSBmYWN0b3J5IG1ldGhvZCBmb3Igbm9uLW5hbWVzcGFjZS1hd2FyZQorICAgICAqIG5vZGVzLiBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTI3MzUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvbmVOb2RlTm90TmFtZXNwYWNlQXdhcmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICAgICAgICBmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKGZhbHNlKTsKKyAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkubmV3RG9jdW1lbnRCdWlsZGVyKCk7CisgICAgICAgIGRvY3VtZW50ID0gYnVpbGRlci5wYXJzZShuZXcgSW5wdXRTb3VyY2UobmV3IFN0cmluZ1JlYWRlcigiPG1lbnUgIgorICAgICAgICAgICAgICAgICsgInhtbG5zOmY9XCJodHRwOi8vZm9vZFwiIHhtbG5zOmE9XCJodHRwOi8vYWRkb25zXCI+IgorICAgICAgICAgICAgICAgICsgIjxmOml0ZW0gYTpzdGFuZGFyZD1cInN0cmF3YmVycnlcIiBkZWx1eGU9XCJ5ZXNcIj5XYWZmbGVzPC9mOml0ZW0+PC9tZW51PiIpKSk7CisgICAgICAgIG5hbWUgPSAoRWxlbWVudCkgZG9jdW1lbnQuZ2V0Rmlyc3RDaGlsZCgpLmdldEZpcnN0Q2hpbGQoKTsKKworICAgICAgICBFbGVtZW50IGNsb25lZE5hbWUgPSAoRWxlbWVudCkgbmFtZS5jbG9uZU5vZGUodHJ1ZSk7CisgICAgICAgIGFzc2VydE51bGwoY2xvbmVkTmFtZS5nZXROYW1lc3BhY2VVUkkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZjppdGVtIiwgY2xvbmVkTmFtZS5nZXROb2RlTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjbG9uZWROYW1lLmdldExvY2FsTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjbG9uZWROYW1lLmdldE5hbWVzcGFjZVVSSSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ5ZXMiLCBjbG9uZWROYW1lLmdldEF0dHJpYnV0ZSgiZGVsdXhlIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoInN0cmF3YmVycnkiLCBjbG9uZWROYW1lLmdldEF0dHJpYnV0ZSgiYTpzdGFuZGFyZCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBjbG9uZWROYW1lLmdldEF0dHJpYnV0ZU5TKCJodHRwOi8vYWRkb25zIiwgInN0YW5kYXJkIikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgc2hhbGxvdyBjbG9uZSByZXF1aXJlcyBjbG9uaW5nIHRoZSBhdHRyaWJ1dGVzIGJ1dCBub3QgdGhlIGNoaWxkIG5vZGVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVc2VyRGF0YUhhbmRsZXJOb3RpZmllZE9mU2hhbGxvd0Nsb25lcygpIHsKKyAgICAgICAgUmVjb3JkaW5nSGFuZGxlciBoYW5kbGVyID0gbmV3IFJlY29yZGluZ0hhbmRsZXIoKTsKKyAgICAgICAgbmFtZS5zZXRVc2VyRGF0YSgiYSIsICJhcHBsZSIsIGhhbmRsZXIpOworICAgICAgICBuYW1lLnNldFVzZXJEYXRhKCJiIiwgImJhbmFuYSIsIGhhbmRsZXIpOworICAgICAgICBzdGFuZGFyZC5zZXRVc2VyRGF0YSgiYyIsICJjYXQiLCBoYW5kbGVyKTsKKyAgICAgICAgd2FmZmxlcy5zZXRVc2VyRGF0YSgiZCIsICJkb2ciLCBoYW5kbGVyKTsKKworICAgICAgICBFbGVtZW50IGNsb25lZE5hbWUgPSAoRWxlbWVudCkgbmFtZS5jbG9uZU5vZGUoZmFsc2UpOworICAgICAgICBBdHRyIGNsb25lZFN0YW5kYXJkID0gY2xvbmVkTmFtZS5nZXRBdHRyaWJ1dGVOb2RlKCJhOnN0YW5kYXJkIik7CisKKyAgICAgICAgU2V0PFN0cmluZz4gZXhwZWN0ZWQgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7CisgICAgICAgIGV4cGVjdGVkLmFkZChub3RpZmljYXRpb24oTk9ERV9DTE9ORUQsICJhIiwgImFwcGxlIiwgbmFtZSwgY2xvbmVkTmFtZSkpOworICAgICAgICBleHBlY3RlZC5hZGQobm90aWZpY2F0aW9uKE5PREVfQ0xPTkVELCAiYiIsICJiYW5hbmEiLCBuYW1lLCBjbG9uZWROYW1lKSk7CisgICAgICAgIGV4cGVjdGVkLmFkZChub3RpZmljYXRpb24oTk9ERV9DTE9ORUQsICJjIiwgImNhdCIsIHN0YW5kYXJkLCBjbG9uZWRTdGFuZGFyZCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIGhhbmRsZXIuY2FsbHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgZGVlcCBjbG9uZSByZXF1aXJlcyBjbG9uaW5nIGJvdGggdGhlIGF0dHJpYnV0ZXMgYW5kIHRoZSBjaGlsZCBub2Rlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXNlckRhdGFIYW5kbGVyTm90aWZpZWRPZkRlZXBDbG9uZXMoKSB7CisgICAgICAgIFJlY29yZGluZ0hhbmRsZXIgaGFuZGxlciA9IG5ldyBSZWNvcmRpbmdIYW5kbGVyKCk7CisgICAgICAgIG5hbWUuc2V0VXNlckRhdGEoImEiLCAiYXBwbGUiLCBoYW5kbGVyKTsKKyAgICAgICAgbmFtZS5zZXRVc2VyRGF0YSgiYiIsICJiYW5hbmEiLCBoYW5kbGVyKTsKKyAgICAgICAgc3RhbmRhcmQuc2V0VXNlckRhdGEoImMiLCAiY2F0IiwgaGFuZGxlcik7CisgICAgICAgIHdhZmZsZXMuc2V0VXNlckRhdGEoImQiLCAiZG9nIiwgaGFuZGxlcik7CisKKyAgICAgICAgRWxlbWVudCBjbG9uZWROYW1lID0gKEVsZW1lbnQpIG5hbWUuY2xvbmVOb2RlKHRydWUpOworICAgICAgICBBdHRyIGNsb25lZFN0YW5kYXJkID0gY2xvbmVkTmFtZS5nZXRBdHRyaWJ1dGVOb2RlKCJhOnN0YW5kYXJkIik7CisgICAgICAgIFRleHQgY2xvbmVkV2FmZmxlcyA9IChUZXh0KSBjbG9uZWROYW1lLmdldENoaWxkTm9kZXMoKS5pdGVtKDApOworCisgICAgICAgIFNldDxTdHJpbmc+IGV4cGVjdGVkID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgICBleHBlY3RlZC5hZGQobm90aWZpY2F0aW9uKE5PREVfQ0xPTkVELCAiYSIsICJhcHBsZSIsIG5hbWUsIGNsb25lZE5hbWUpKTsKKyAgICAgICAgZXhwZWN0ZWQuYWRkKG5vdGlmaWNhdGlvbihOT0RFX0NMT05FRCwgImIiLCAiYmFuYW5hIiwgbmFtZSwgY2xvbmVkTmFtZSkpOworICAgICAgICBleHBlY3RlZC5hZGQobm90aWZpY2F0aW9uKE5PREVfQ0xPTkVELCAiYyIsICJjYXQiLCBzdGFuZGFyZCwgY2xvbmVkU3RhbmRhcmQpKTsKKyAgICAgICAgZXhwZWN0ZWQuYWRkKG5vdGlmaWNhdGlvbihOT0RFX0NMT05FRCwgImQiLCAiZG9nIiwgd2FmZmxlcywgY2xvbmVkV2FmZmxlcykpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIGhhbmRsZXIuY2FsbHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgc2hhbGxvdyBpbXBvcnQgcmVxdWlyZXMgaW1wb3J0aW5nIHRoZSBhdHRyaWJ1dGVzIGJ1dCBub3QgdGhlIGNoaWxkCisgICAgICogbm9kZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVzZXJEYXRhSGFuZGxlck5vdGlmaWVkT2ZTaGFsbG93SW1wb3J0cygpIHsKKyAgICAgICAgUmVjb3JkaW5nSGFuZGxlciBoYW5kbGVyID0gbmV3IFJlY29yZGluZ0hhbmRsZXIoKTsKKyAgICAgICAgbmFtZS5zZXRVc2VyRGF0YSgiYSIsICJhcHBsZSIsIGhhbmRsZXIpOworICAgICAgICBuYW1lLnNldFVzZXJEYXRhKCJiIiwgImJhbmFuYSIsIGhhbmRsZXIpOworICAgICAgICBzdGFuZGFyZC5zZXRVc2VyRGF0YSgiYyIsICJjYXQiLCBoYW5kbGVyKTsKKyAgICAgICAgd2FmZmxlcy5zZXRVc2VyRGF0YSgiZCIsICJkb2ciLCBoYW5kbGVyKTsKKworICAgICAgICBEb2N1bWVudCBuZXdEb2N1bWVudCA9IGJ1aWxkZXIubmV3RG9jdW1lbnQoKTsKKyAgICAgICAgRWxlbWVudCBpbXBvcnRlZE5hbWUgPSAoRWxlbWVudCkgbmV3RG9jdW1lbnQuaW1wb3J0Tm9kZShuYW1lLCBmYWxzZSk7CisgICAgICAgIEF0dHIgaW1wb3J0ZWRTdGFuZGFyZCA9IGltcG9ydGVkTmFtZS5nZXRBdHRyaWJ1dGVOb2RlKCJhOnN0YW5kYXJkIik7CisKKyAgICAgICAgU2V0PFN0cmluZz4gZXhwZWN0ZWQgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7CisgICAgICAgIGV4cGVjdGVkLmFkZChub3RpZmljYXRpb24oTk9ERV9JTVBPUlRFRCwgImEiLCAiYXBwbGUiLCBuYW1lLCBpbXBvcnRlZE5hbWUpKTsKKyAgICAgICAgZXhwZWN0ZWQuYWRkKG5vdGlmaWNhdGlvbihOT0RFX0lNUE9SVEVELCAiYiIsICJiYW5hbmEiLCBuYW1lLCBpbXBvcnRlZE5hbWUpKTsKKyAgICAgICAgZXhwZWN0ZWQuYWRkKG5vdGlmaWNhdGlvbihOT0RFX0lNUE9SVEVELCAiYyIsICJjYXQiLCBzdGFuZGFyZCwgaW1wb3J0ZWRTdGFuZGFyZCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIGhhbmRsZXIuY2FsbHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgZGVlcCBpbXBvcnQgcmVxdWlyZXMgY2xvbmluZyBib3RoIHRoZSBhdHRyaWJ1dGVzIGFuZCB0aGUgY2hpbGQgbm9kZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVzZXJEYXRhSGFuZGxlck5vdGlmaWVkT2ZEZWVwSW1wb3J0cygpIHsKKyAgICAgICAgUmVjb3JkaW5nSGFuZGxlciBoYW5kbGVyID0gbmV3IFJlY29yZGluZ0hhbmRsZXIoKTsKKyAgICAgICAgbmFtZS5zZXRVc2VyRGF0YSgiYSIsICJhcHBsZSIsIGhhbmRsZXIpOworICAgICAgICBuYW1lLnNldFVzZXJEYXRhKCJiIiwgImJhbmFuYSIsIGhhbmRsZXIpOworICAgICAgICBzdGFuZGFyZC5zZXRVc2VyRGF0YSgiYyIsICJjYXQiLCBoYW5kbGVyKTsKKyAgICAgICAgd2FmZmxlcy5zZXRVc2VyRGF0YSgiZCIsICJkb2ciLCBoYW5kbGVyKTsKKworICAgICAgICBEb2N1bWVudCBuZXdEb2N1bWVudCA9IGJ1aWxkZXIubmV3RG9jdW1lbnQoKTsKKyAgICAgICAgRWxlbWVudCBpbXBvcnRlZE5hbWUgPSAoRWxlbWVudCkgbmV3RG9jdW1lbnQuaW1wb3J0Tm9kZShuYW1lLCB0cnVlKTsKKyAgICAgICAgQXR0ciBpbXBvcnRlZFN0YW5kYXJkID0gaW1wb3J0ZWROYW1lLmdldEF0dHJpYnV0ZU5vZGUoImE6c3RhbmRhcmQiKTsKKyAgICAgICAgVGV4dCBpbXBvcnRlZFdhZmZsZXMgPSAoVGV4dCkgaW1wb3J0ZWROYW1lLmdldENoaWxkTm9kZXMoKS5pdGVtKDApOworCisgICAgICAgIFNldDxTdHJpbmc+IGV4cGVjdGVkID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgICBleHBlY3RlZC5hZGQobm90aWZpY2F0aW9uKE5PREVfSU1QT1JURUQsICJhIiwgImFwcGxlIiwgbmFtZSwgaW1wb3J0ZWROYW1lKSk7CisgICAgICAgIGV4cGVjdGVkLmFkZChub3RpZmljYXRpb24oTk9ERV9JTVBPUlRFRCwgImIiLCAiYmFuYW5hIiwgbmFtZSwgaW1wb3J0ZWROYW1lKSk7CisgICAgICAgIGV4cGVjdGVkLmFkZChub3RpZmljYXRpb24oTk9ERV9JTVBPUlRFRCwgImMiLCAiY2F0Iiwgc3RhbmRhcmQsIGltcG9ydGVkU3RhbmRhcmQpKTsKKyAgICAgICAgZXhwZWN0ZWQuYWRkKG5vdGlmaWNhdGlvbihOT0RFX0lNUE9SVEVELCAiZCIsICJkb2ciLCB3YWZmbGVzLCBpbXBvcnRlZFdhZmZsZXMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBoYW5kbGVyLmNhbGxzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0Tm9kZURlZXAoKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgb3JpZ2luYWwgPSBkb21Ub1N0cmluZ1N0cmlwRWxlbWVudFdoaXRlc3BhY2UoZG9jdW1lbnQpOworCisgICAgICAgIERvY3VtZW50IG5ld0RvY3VtZW50ID0gYnVpbGRlci5uZXdEb2N1bWVudCgpOworICAgICAgICBFbGVtZW50IGltcG9ydGVkSXRlbSA9IChFbGVtZW50KSBuZXdEb2N1bWVudC5pbXBvcnROb2RlKGl0ZW0sIHRydWUpOworICAgICAgICBhc3NlcnREZXRhY2hlZChpdGVtLmdldFBhcmVudE5vZGUoKSwgaW1wb3J0ZWRJdGVtKTsKKworICAgICAgICBuZXdEb2N1bWVudC5hcHBlbmRDaGlsZChpbXBvcnRlZEl0ZW0pOworICAgICAgICBTdHJpbmcgZXhwZWN0ZWQgPSBvcmlnaW5hbC5yZXBsYWNlQWxsKCI8Lz9tZW51PiIsICIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBkb21Ub1N0cmluZ1N0cmlwRWxlbWVudFdoaXRlc3BhY2UobmV3RG9jdW1lbnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0Tm9kZVNoYWxsb3coKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24geworICAgICAgICBEb2N1bWVudCBuZXdEb2N1bWVudCA9IGJ1aWxkZXIubmV3RG9jdW1lbnQoKTsKKyAgICAgICAgRWxlbWVudCBpbXBvcnRlZEl0ZW0gPSAoRWxlbWVudCkgbmV3RG9jdW1lbnQuaW1wb3J0Tm9kZShpdGVtLCBmYWxzZSk7CisgICAgICAgIGFzc2VydERldGFjaGVkKGl0ZW0uZ2V0UGFyZW50Tm9kZSgpLCBpbXBvcnRlZEl0ZW0pOworCisgICAgICAgIG5ld0RvY3VtZW50LmFwcGVuZENoaWxkKGltcG9ydGVkSXRlbSk7CisgICAgICAgIGFzc2VydEVxdWFscygiPGl0ZW0geG1sbnM9XCJodHRwOi8vZm9vZFwiIHhtbG5zOmE9XCJodHRwOi8vYWRkb25zXCIvPiIsCisgICAgICAgICAgICAgICAgZG9tVG9TdHJpbmcobmV3RG9jdW1lbnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9kZUFkb3B0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoTm9kZSBub2RlIDogYWxsTm9kZXMpIHsKKyAgICAgICAgICAgIGlmIChub2RlID09IGRvY3VtZW50IHx8IG5vZGUgPT0gZG9jdHlwZSB8fCBub2RlID09IHNwIHx8IG5vZGUgPT0gcG5nKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90QWRvcHRhYmxlKG5vZGUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhZG9wdEFuZENoZWNrKG5vZGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydE5vdEFkb3B0YWJsZShOb2RlIG5vZGUpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ1aWxkZXIubmV3RG9jdW1lbnQoKS5hZG9wdE5vZGUobm9kZSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZG9wdHMgdGhlIG5vZGUgaW50byBhbm90aGVyIGRvY3VtZW50LCB0aGVuIGFkb3B0cyB0aGUgcm9vdCBlbGVtZW50LCBhbmQKKyAgICAgKiB0aGVuIGF0dGFjaGVzIHRoZSBhZG9wdGVkIG5vZGUgaW4gdGhlIHByb3BlciBwbGFjZS4gVGhlIG5ldCByZXN1bHQgc2hvdWxkCisgICAgICogYmUgdGhhdCB0aGUgZG9jdW1lbnQncyBlbnRpcmUgY29udGVudHMgaGF2ZSBtb3ZlZCB0byBhbm90aGVyIGRvY3VtZW50LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhZG9wdEFuZENoZWNrKE5vZGUgbm9kZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBvcmlnaW5hbCA9IGRvbVRvU3RyaW5nKGRvY3VtZW50KTsKKyAgICAgICAgRG9jdW1lbnQgbmV3RG9jdW1lbnQgPSBidWlsZGVyLm5ld0RvY3VtZW50KCk7CisKKyAgICAgICAgLy8gcmVtZW1iZXIgd2hlcmUgdG8gaW5zZXJ0IHRoZSBub2RlIGluIHRoZSBuZXcgZG9jdW1lbnQKKyAgICAgICAgYm9vbGVhbiBpc0F0dHJpYnV0ZSA9IG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkFUVFJJQlVURV9OT0RFOworICAgICAgICBOb2RlIHBhcmVudCA9IGlzQXR0cmlidXRlCisgICAgICAgICAgICAgICAgPyAoKEF0dHIpIG5vZGUpLmdldE93bmVyRWxlbWVudCgpIDogbm9kZS5nZXRQYXJlbnROb2RlKCk7CisgICAgICAgIE5vZGUgbmV4dFNpYmxpbmcgPSBub2RlLmdldE5leHRTaWJsaW5nKCk7CisKKyAgICAgICAgLy8gbW92ZSB0aGUgbm9kZSBhbmQgbWFrZSBzdXJlIGl0IHdhcyBkZXRhY2hlZAorICAgICAgICBhc3NlcnRTYW1lKG5vZGUsIG5ld0RvY3VtZW50LmFkb3B0Tm9kZShub2RlKSk7CisgICAgICAgIGFzc2VydERldGFjaGVkKHBhcmVudCwgbm9kZSk7CisKKyAgICAgICAgLy8gbW92ZSB0aGUgcmVzdCBvZiB0aGUgZG9jdW1lbnQgYW5kIHdpcmUgdGhlIGFkb3B0ZWQgYmFjayBpbnRvIHBsYWNlCisgICAgICAgIGFzc2VydFNhbWUobWVudSwgbmV3RG9jdW1lbnQuYWRvcHROb2RlKG1lbnUpKTsKKyAgICAgICAgbmV3RG9jdW1lbnQuYXBwZW5kQ2hpbGQobWVudSk7CisgICAgICAgIGlmIChpc0F0dHJpYnV0ZSkgeworICAgICAgICAgICAgKChFbGVtZW50KSBwYXJlbnQpLnNldEF0dHJpYnV0ZU5vZGVOUygoQXR0cikgbm9kZSk7CisgICAgICAgIH0gZWxzZSBpZiAobmV4dFNpYmxpbmcgIT0gbnVsbCkgeworICAgICAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShub2RlLCBuZXh0U2libGluZyk7CisgICAgICAgIH0gZWxzZSBpZiAocGFyZW50ICE9IGRvY3VtZW50KSB7CisgICAgICAgICAgICBwYXJlbnQuYXBwZW5kQ2hpbGQobm9kZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMob3JpZ2luYWwsIGRvbVRvU3RyaW5nKG5ld0RvY3VtZW50KSk7CisgICAgICAgIGRvY3VtZW50ID0gbmV3RG9jdW1lbnQ7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydERldGFjaGVkKE5vZGUgZm9ybWVyUGFyZW50LCBOb2RlIG5vZGUpIHsKKyAgICAgICAgYXNzZXJ0TnVsbChub2RlLmdldFBhcmVudE5vZGUoKSk7CisgICAgICAgIE5vZGVMaXN0IGNoaWxkcmVuID0gZm9ybWVyUGFyZW50LmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaGlsZHJlbi5nZXRMZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGNoaWxkcmVuLml0ZW0oaSkgIT0gbm9kZSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkFUVFJJQlVURV9OT0RFKSB7CisgICAgICAgICAgICBhc3NlcnROdWxsKCgoQXR0cikgbm9kZSkuZ2V0T3duZXJFbGVtZW50KCkpOworICAgICAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXMgPSBmb3JtZXJQYXJlbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGF0dHJpYnV0ZXMuaXRlbShpKSAhPSBub2RlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZG9wdGlvbkltbWVkaWF0ZWx5QWZ0ZXJQYXJzaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIERvY3VtZW50IG5ld0RvY3VtZW50ID0gYnVpbGRlci5uZXdEb2N1bWVudCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0U2FtZShuYW1lLCBuZXdEb2N1bWVudC5hZG9wdE5vZGUobmFtZSkpOworICAgICAgICAgICAgYXNzZXJ0U2FtZShuZXdEb2N1bWVudCwgbmFtZS5nZXRPd25lckRvY3VtZW50KCkpOworICAgICAgICAgICAgYXNzZXJ0U2FtZShuZXdEb2N1bWVudCwgc3RhbmRhcmQuZ2V0T3duZXJEb2N1bWVudCgpKTsKKyAgICAgICAgICAgIGFzc2VydFNhbWUobmV3RG9jdW1lbnQsIHdhZmZsZXMuZ2V0T3duZXJEb2N1bWVudCgpKTsKKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgICAgIEFzc2VydGlvbkZhaWxlZEVycm9yIGZhaWx1cmUgPSBuZXcgQXNzZXJ0aW9uRmFpbGVkRXJyb3IoCisgICAgICAgICAgICAgICAgICAgICJUaGlzIGltcGxlbWVudGF0aW9uIGZhaWxzIHRvIGFkb3B0IG5vZGVzIGJlZm9yZSB0aGUgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgImRvY3VtZW50IGhhcyBiZWVuIHRyYXZlcnNlZCIpOworICAgICAgICAgICAgZmFpbHVyZS5pbml0Q2F1c2UoZSk7CisgICAgICAgICAgICB0aHJvdyBmYWlsdXJlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlcmUgc2hvdWxkIGJlIG5vdGlmaWNhdGlvbnMgZm9yIGFkb3B0ZWQgbm9kZSBpdHNlbGYgYnV0IG5vbmUgb2YgaXRzCisgICAgICogY2hpbGRyZW4uIFRoZSBET00gc3BlYyBpcyB2YWd1ZSBvbiB0aGlzLCBzbyB3ZSdyZSBjb25zaXN0ZW50IHdpdGggdGhlIFJJLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVc2VyRGF0YUhhbmRsZXJOb3RpZmllZE9mT25seVNoYWxsb3dBZG9wdGlvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogRm9yY2UgYSB0cmF2ZXJzYWwgb2YgdGhlIGRvY3VtZW50LCBvdGhlcndpc2UgdGhpcyB0ZXN0IG1heSBmYWlsIGZvcgorICAgICAgICAgKiBhbiB1bnJlbGF0ZWQgcmVhc29uIG9uIHZlcnNpb24gNSBvZiB0aGUgUkkuIFRoYXQgYmVoYXZpb3IgaXMKKyAgICAgICAgICogZXhlcmNpc2VkIGJ5IHRlc3RBZG9wdGlvbkltbWVkaWF0ZWx5QWZ0ZXJQYXJzaW5nKCkuCisgICAgICAgICAqLworICAgICAgICBkb21Ub1N0cmluZyhkb2N1bWVudCk7CisKKyAgICAgICAgUmVjb3JkaW5nSGFuZGxlciBoYW5kbGVyID0gbmV3IFJlY29yZGluZ0hhbmRsZXIoKTsKKyAgICAgICAgbmFtZS5zZXRVc2VyRGF0YSgiYSIsICJhcHBsZSIsIGhhbmRsZXIpOworICAgICAgICBuYW1lLnNldFVzZXJEYXRhKCJiIiwgImJhbmFuYSIsIGhhbmRsZXIpOworICAgICAgICBzdGFuZGFyZC5zZXRVc2VyRGF0YSgiYyIsICJjYXQiLCBoYW5kbGVyKTsKKyAgICAgICAgd2FmZmxlcy5zZXRVc2VyRGF0YSgiZCIsICJkb2ciLCBoYW5kbGVyKTsKKworICAgICAgICBEb2N1bWVudCBuZXdEb2N1bWVudCA9IGJ1aWxkZXIubmV3RG9jdW1lbnQoKTsKKyAgICAgICAgYXNzZXJ0U2FtZShuYW1lLCBuZXdEb2N1bWVudC5hZG9wdE5vZGUobmFtZSkpOworICAgICAgICBhc3NlcnRTYW1lKG5ld0RvY3VtZW50LCBuYW1lLmdldE93bmVyRG9jdW1lbnQoKSk7CisgICAgICAgIGFzc2VydFNhbWUobmV3RG9jdW1lbnQsIHN0YW5kYXJkLmdldE93bmVyRG9jdW1lbnQoKSk7CisgICAgICAgIGFzc2VydFNhbWUobmV3RG9jdW1lbnQsIHdhZmZsZXMuZ2V0T3duZXJEb2N1bWVudCgpKTsKKworICAgICAgICBTZXQ8U3RyaW5nPiBleHBlY3RlZCA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKyAgICAgICAgZXhwZWN0ZWQuYWRkKG5vdGlmaWNhdGlvbihOT0RFX0FET1BURUQsICJhIiwgImFwcGxlIiwgbmFtZSwgbnVsbCkpOworICAgICAgICBleHBlY3RlZC5hZGQobm90aWZpY2F0aW9uKE5PREVfQURPUFRFRCwgImIiLCAiYmFuYW5hIiwgbmFtZSwgbnVsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIGhhbmRsZXIuY2FsbHMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCYXNlVXJpUmVsYXRpdmVVcmlSZXNvbHV0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgZmlsZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoIkRvbVRlc3QuamF2YSIsICJ4bWwiKTsKKyAgICAgICAgRmlsZSBwYXJlbnRGaWxlID0gZmlsZS5nZXRQYXJlbnRGaWxlKCk7CisgICAgICAgIEZpbGVXcml0ZXIgd3JpdGVyID0gbmV3IEZpbGVXcml0ZXIoZmlsZSk7CisgICAgICAgIHdyaXRlci53cml0ZSgiPGE+IgorICAgICAgICAgICAgICAgICsgIiAgPGIgeG1sOmJhc2U9XCJiMS9iMlwiPiIKKyAgICAgICAgICAgICAgICArICIgICAgPGM+IgorICAgICAgICAgICAgICAgICsgIiAgICAgIDxkIHhtbDpiYXNlPVwiLi4vZDEvZDJcIj48ZS8+PC9kPiIKKyAgICAgICAgICAgICAgICArICIgICAgPC9jPiIKKyAgICAgICAgICAgICAgICArICIgIDwvYj4iCisgICAgICAgICAgICAgICAgKyAiICA8aCB4bWw6YmFzZT1cImgxL2gyL1wiPiIKKyAgICAgICAgICAgICAgICArICIgICAgPGkgeG1sOmJhc2U9XCIuLi9pMS9pMlwiLz4iCisgICAgICAgICAgICAgICAgKyAiICA8L2g+IgorICAgICAgICAgICAgICAgICsgIjwvYT4iKTsKKyAgICAgICAgd3JpdGVyLmNsb3NlKCk7CisgICAgICAgIGRvY3VtZW50ID0gYnVpbGRlci5wYXJzZShmaWxlKTsKKworICAgICAgICBhc3NlcnRGaWxlVXJpRXF1YWxzKCIiLCBmaWxlLmdldFBhdGgoKSwgZG9jdW1lbnQuZ2V0QmFzZVVSSSgpKTsKKyAgICAgICAgYXNzZXJ0RmlsZVVyaUVxdWFscygiIiwgZmlsZS5nZXRQYXRoKCksIGRvY3VtZW50LmdldERvY3VtZW50VVJJKCkpOworICAgICAgICBFbGVtZW50IGEgPSBkb2N1bWVudC5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgYXNzZXJ0RmlsZVVyaUVxdWFscygiIiwgZmlsZS5nZXRQYXRoKCksIGEuZ2V0QmFzZVVSSSgpKTsKKworICAgICAgICBTdHJpbmcgbWVzc2FnZSA9ICJUaGlzIGltcGxlbWVudGF0aW9uJ3MgZ2V0QmFzZVVSSSgpIGRvZXNuJ3QgaGFuZGxlIHJlbGF0aXZlIFVSSXMiOworICAgICAgICBFbGVtZW50IGIgPSAoRWxlbWVudCkgYS5nZXRDaGlsZE5vZGVzKCkuaXRlbSgxKTsKKyAgICAgICAgRWxlbWVudCBjID0gKEVsZW1lbnQpIGIuZ2V0Q2hpbGROb2RlcygpLml0ZW0oMSk7CisgICAgICAgIEVsZW1lbnQgZCA9IChFbGVtZW50KSBjLmdldENoaWxkTm9kZXMoKS5pdGVtKDEpOworICAgICAgICBFbGVtZW50IGUgPSAoRWxlbWVudCkgZC5nZXRDaGlsZE5vZGVzKCkuaXRlbSgwKTsKKyAgICAgICAgRWxlbWVudCBoID0gKEVsZW1lbnQpIGEuZ2V0Q2hpbGROb2RlcygpLml0ZW0oMyk7CisgICAgICAgIEVsZW1lbnQgaSA9IChFbGVtZW50KSBoLmdldENoaWxkTm9kZXMoKS5pdGVtKDEpOworICAgICAgICBhc3NlcnRGaWxlVXJpRXF1YWxzKG1lc3NhZ2UsIHBhcmVudEZpbGUgKyAiL2IxL2IyIiwgYi5nZXRCYXNlVVJJKCkpOworICAgICAgICBhc3NlcnRGaWxlVXJpRXF1YWxzKG1lc3NhZ2UsIHBhcmVudEZpbGUgKyAiL2IxL2IyIiwgYy5nZXRCYXNlVVJJKCkpOworICAgICAgICBhc3NlcnRGaWxlVXJpRXF1YWxzKG1lc3NhZ2UsIHBhcmVudEZpbGUgKyAiL2QxL2QyIiwgZC5nZXRCYXNlVVJJKCkpOworICAgICAgICBhc3NlcnRGaWxlVXJpRXF1YWxzKG1lc3NhZ2UsIHBhcmVudEZpbGUgKyAiL2QxL2QyIiwgZS5nZXRCYXNlVVJJKCkpOworICAgICAgICBhc3NlcnRGaWxlVXJpRXF1YWxzKG1lc3NhZ2UsIHBhcmVudEZpbGUgKyAiL2gxL2gyLyIsIGguZ2V0QmFzZVVSSSgpKTsKKyAgICAgICAgYXNzZXJ0RmlsZVVyaUVxdWFscyhtZXNzYWdlLCBwYXJlbnRGaWxlICsgIi9oMS9pMS9pMiIsIGkuZ2V0QmFzZVVSSSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWdyZXR0YWJseSBib3RoICJmaWxlOi90bXAvZm9vLnR4dCIgYW5kICJmaWxlOi8vL3RtcC9mb28udHh0IiBhcmUKKyAgICAgKiBsZWdhbCBVUklzLCBhbmQgZGlmZmVyZW50IGltcGxlbWVudGF0aW9ucyBlbWl0IGRpZmZlcmVudCBmb3Jtcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0RmlsZVVyaUVxdWFscygKKyAgICAgICAgICAgIFN0cmluZyBtZXNzYWdlLCBTdHJpbmcgZXhwZWN0ZWRGaWxlLCBTdHJpbmcgYWN0dWFsKSB7CisgICAgICAgIGlmICghKCJmaWxlOiIgKyBleHBlY3RlZEZpbGUpLmVxdWFscyhhY3R1YWwpCisgICAgICAgICAgICAgICAgJiYgISgiZmlsZTovLyIgKyBleHBlY3RlZEZpbGUpLmVxdWFscyhhY3R1YWwpKSB7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBVUkkgZm9yOiAiICsgZXhwZWN0ZWRGaWxlCisgICAgICAgICAgICAgICAgICAgICsgIiBidXQgd2FzICIgKyBhY3R1YWwgKyAiLiAiICsgbWVzc2FnZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBY2NvcmRpbmcgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbGJhc2UvIj5YTUwgQmFzZTwvYT4KKyAgICAgKiBzcGVjLCBmcmFnbWVudHMgKGxpa2UgIiNmcmFnIiBvciAiIikgc2hvdWxkIG5vdCBiZSBkZXJlZmVyZW5jZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEJhc2VVcmlSZXNvbHV0aW9uV2l0aEhhc2hlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkb2N1bWVudCA9IGJ1aWxkZXIucGFyc2UobmV3IElucHV0U291cmNlKG5ldyBTdHJpbmdSZWFkZXIoCisgICAgICAgICAgICAgICAgIjxhIHhtbDpiYXNlPVwiaHR0cDovL2ExL2EyXCI+IgorICAgICAgICAgICAgICAgICAgICAgICAgKyAiICA8YiB4bWw6YmFzZT1cImIxI2IyXCIvPiIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgPGMgeG1sOmJhc2U9XCIjYzFcIj4iCisgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgPGQgeG1sOmJhc2U9XCJcIi8+IgorICAgICAgICAgICAgICAgICAgICAgICAgKyAiICA8L2M+IgorICAgICAgICAgICAgICAgICAgICAgICAgKyAiICA8ZSB4bWw6YmFzZT1cIlwiLz4iCisgICAgICAgICAgICAgICAgICAgICAgICArICI8L2E+IikpKTsKKyAgICAgICAgRWxlbWVudCBhID0gZG9jdW1lbnQuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2ExL2EyIiwgYS5nZXRCYXNlVVJJKCkpOworCisgICAgICAgIFN0cmluZyBtZXNzYWdlID0gIlRoaXMgaW1wbGVtZW50YXRpb24ncyBnZXRCYXNlVVJJKCkgZG9lc24ndCBoYW5kbGUgIgorICAgICAgICAgICAgICAgICsgInJlbGF0aXZlIFVSSXMgd2l0aCBoYXNoZXMiOworICAgICAgICBFbGVtZW50IGIgPSAoRWxlbWVudCkgYS5nZXRDaGlsZE5vZGVzKCkuaXRlbSgxKTsKKyAgICAgICAgRWxlbWVudCBjID0gKEVsZW1lbnQpIGEuZ2V0Q2hpbGROb2RlcygpLml0ZW0oMyk7CisgICAgICAgIEVsZW1lbnQgZCA9IChFbGVtZW50KSBjLmdldENoaWxkTm9kZXMoKS5pdGVtKDEpOworICAgICAgICBFbGVtZW50IGUgPSAoRWxlbWVudCkgYS5nZXRDaGlsZE5vZGVzKCkuaXRlbSg1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsICJodHRwOi8vYTEvYjEjYjIiLCBiLmdldEJhc2VVUkkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLCAiaHR0cDovL2ExL2EyI2MxIiwgYy5nZXRCYXNlVVJJKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobWVzc2FnZSwgImh0dHA6Ly9hMS9hMiNjMSIsIGQuZ2V0QmFzZVVSSSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsICJodHRwOi8vYTEvYTIiLCBlLmdldEJhc2VVUkkoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEJhc2VVcmlJbmhlcml0ZWRGb3JQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25zKCkgeworICAgICAgICBkb2N1bWVudC5zZXREb2N1bWVudFVSSSgiaHR0cDovL2QxL2QyIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2QxL2QyIiwgd2FmZmxlbWFrZXIuZ2V0QmFzZVVSSSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QmFzZVVyaUluaGVyaXRlZEZvckVudGl0aWVzKCkgeworICAgICAgICBpZiAoc3AgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGRvY3VtZW50LnNldERvY3VtZW50VVJJKCJodHRwOi8vZDEvZDIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vZDEvZDIiLCBzcC5nZXRCYXNlVVJJKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCYXNlVXJpTm90SW5oZXJpdGVkRm9yTm90YXRpb25zKCkgeworICAgICAgICBpZiAocG5nID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBkb2N1bWVudC5zZXREb2N1bWVudFVSSSgiaHR0cDovL2QxL2QyIik7CisgICAgICAgIGFzc2VydE51bGwocG5nLmdldEJhc2VVUkkoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEJhc2VVcmlOb3RJbmhlcml0ZWRGb3JEb2N0eXBlcygpIHsKKyAgICAgICAgZG9jdW1lbnQuc2V0RG9jdW1lbnRVUkkoImh0dHA6Ly9kMS9kMiIpOworICAgICAgICBhc3NlcnROdWxsKGRvY3R5cGUuZ2V0QmFzZVVSSSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QmFzZVVyaU5vdEluaGVyaXRlZEZvckF0dHJpYnV0ZXMoKSB7CisgICAgICAgIGRvY3VtZW50LnNldERvY3VtZW50VVJJKCJodHRwOi8vZDEvZDIiKTsKKyAgICAgICAgYXNzZXJ0TnVsbChpdGVtWG1sbnMuZ2V0QmFzZVVSSSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChpdGVtWG1sbnNBLmdldEJhc2VVUkkoKSk7CisgICAgICAgIGFzc2VydE51bGwoc3RhbmRhcmQuZ2V0QmFzZVVSSSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh2aXRhbWluc1htbG5zQS5nZXRCYXNlVVJJKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCYXNlVXJpTm90SW5oZXJpdGVkRm9yVGV4dHNPckNkYXRhcygpIHsKKyAgICAgICAgZG9jdW1lbnQuc2V0RG9jdW1lbnRVUkkoImh0dHA6Ly9kMS9kMiIpOworICAgICAgICBhc3NlcnROdWxsKGRlc2NyaXB0aW9uVGV4dDEuZ2V0QmFzZVVSSSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChkZXNjcmlwdGlvblRleHQyLmdldEJhc2VVUkkoKSk7CisgICAgICAgIGFzc2VydE51bGwob3B0aW9uMlJlZmVyZW5jZS5nZXRCYXNlVVJJKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCYXNlVXJpTm90SW5oZXJpdGVkRm9yQ29tbWVudHMoKSB7CisgICAgICAgIGRvY3VtZW50LnNldERvY3VtZW50VVJJKCJodHRwOi8vZDEvZDIiKTsKKyAgICAgICAgYXNzZXJ0TnVsbChkZXNjcmlwdGlvblRleHQxLmdldEJhc2VVUkkoKSk7CisgICAgICAgIGFzc2VydE51bGwoZGVzY3JpcHRpb25UZXh0Mi5nZXRCYXNlVVJJKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCYXNlVXJpTm90SW5oZXJpdGVkRm9yRW50aXR5UmVmZXJlbmNlcygpIHsKKyAgICAgICAgZG9jdW1lbnQuc2V0RG9jdW1lbnRVUkkoImh0dHA6Ly9kMS9kMiIpOworICAgICAgICBhc3NlcnROdWxsKG9wdGlvbjJSZWZlcmVuY2UuZ2V0QmFzZVVSSSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJvZ3JhbW1hdGljRWxlbWVudElkcygpIHsKKyAgICAgICAgdml0YW1pbmMuc2V0QXR0cmlidXRlKCJuYW1lIiwgImMiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uodml0YW1pbmMuZ2V0QXR0cmlidXRlTm9kZSgibmFtZSIpLmlzSWQoKSk7CisgICAgICAgIGFzc2VydE51bGwoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImMiKSk7CisKKyAgICAgICAgLy8gc2V0IHRoZSBJRCBhdHRyaWJ1dGUuLi4KKyAgICAgICAgdml0YW1pbmMuc2V0SWRBdHRyaWJ1dGUoIm5hbWUiLCB0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh2aXRhbWluYy5nZXRBdHRyaWJ1dGVOb2RlKCJuYW1lIikuaXNJZCgpKTsKKyAgICAgICAgYXNzZXJ0U2FtZSh2aXRhbWluYywgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImMiKSk7CisKKyAgICAgICAgLy8gLi4uIGFuZCB0aGVuIHRha2UgaXQgYXdheQorICAgICAgICB2aXRhbWluYy5zZXRJZEF0dHJpYnV0ZSgibmFtZSIsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uodml0YW1pbmMuZ2V0QXR0cmlidXRlTm9kZSgibmFtZSIpLmlzSWQoKSk7CisgICAgICAgIGFzc2VydE51bGwoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImMiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE11bHRpcGxlSWRzT25PbmVFbGVtZW50KCkgeworICAgICAgICB2aXRhbWluYy5zZXRBdHRyaWJ1dGUoIm5hbWUiLCAiYyIpOworICAgICAgICB2aXRhbWluYy5zZXRJZEF0dHJpYnV0ZSgibmFtZSIsIHRydWUpOworICAgICAgICB2aXRhbWluYy5zZXRBdHRyaWJ1dGUoImF0YyIsICJhMTFnIik7CisgICAgICAgIHZpdGFtaW5jLnNldElkQXR0cmlidXRlKCJhdGMiLCB0cnVlKTsKKworICAgICAgICBhc3NlcnRUcnVlKHZpdGFtaW5jLmdldEF0dHJpYnV0ZU5vZGUoIm5hbWUiKS5pc0lkKCkpOworICAgICAgICBhc3NlcnRUcnVlKHZpdGFtaW5jLmdldEF0dHJpYnV0ZU5vZGUoImF0YyIpLmlzSWQoKSk7CisgICAgICAgIGFzc2VydFNhbWUodml0YW1pbmMsIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjIikpOworICAgICAgICBhc3NlcnRTYW1lKHZpdGFtaW5jLCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYTExZyIpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZyIpKTsKKyAgICB9CisKKyAgICBAS25vd25GYWlsdXJlKCJEYWx2aWsgdHJlYXRzIGlkIGF0dHJpYnV0ZXMgYXMgaWRlbnRpZmllcnMiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RBdHRyaWJ1dGVOYW1lZElkSXNOb3RBbklkQnlEZWZhdWx0KCkgeworICAgICAgICBTdHJpbmcgbWVzc2FnZSA9ICJUaGlzIGltcGxlbWVudGF0aW9uIGluY29ycmVjdGx5IGludGVycHJldHMgdGhlICIKKyAgICAgICAgICAgICAgICArICJcImlkXCIgYXR0cmlidXRlIGFzIGFuIGlkZW50aWZpZXIgYnkgZGVmYXVsdC4iOworICAgICAgICB2aXRhbWluYy5zZXRBdHRyaWJ1dGUoImlkIiwgImMiKTsKKyAgICAgICAgYXNzZXJ0TnVsbChtZXNzYWdlLCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYyIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RWxlbWVudFR5cGVJbmZvKCkgeworICAgICAgICBUeXBlSW5mbyB0eXBlSW5mbyA9IGRlc2NyaXB0aW9uLmdldFNjaGVtYVR5cGVJbmZvKCk7CisgICAgICAgIGFzc2VydE51bGwodHlwZUluZm8uZ2V0VHlwZU5hbWUoKSk7CisgICAgICAgIGFzc2VydE51bGwodHlwZUluZm8uZ2V0VHlwZU5hbWVzcGFjZSgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UodHlwZUluZm8uaXNEZXJpdmVkRnJvbSgieCIsICJ5IiwgVHlwZUluZm8uREVSSVZBVElPTl9VTklPTikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdHRyaWJ1dGVUeXBlSW5mbygpIHsKKyAgICAgICAgVHlwZUluZm8gdHlwZUluZm8gPSBzdGFuZGFyZC5nZXRTY2hlbWFUeXBlSW5mbygpOworICAgICAgICBhc3NlcnROdWxsKHR5cGVJbmZvLmdldFR5cGVOYW1lKCkpOworICAgICAgICBhc3NlcnROdWxsKHR5cGVJbmZvLmdldFR5cGVOYW1lc3BhY2UoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHR5cGVJbmZvLmlzRGVyaXZlZEZyb20oIngiLCAieSIsIFR5cGVJbmZvLkRFUklWQVRJT05fVU5JT04pKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVuYW1lRWxlbWVudCgpIHsKKyAgICAgICAgZG9jdW1lbnQucmVuYW1lTm9kZShkZXNjcmlwdGlvbiwgbnVsbCwgImRlc2MiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkZXNjIiwgZGVzY3JpcHRpb24uZ2V0VGFnTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkZXNjIiwgZGVzY3JpcHRpb24uZ2V0TG9jYWxOYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZGVzY3JpcHRpb24uZ2V0UHJlZml4KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZGVzY3JpcHRpb24uZ2V0TmFtZXNwYWNlVVJJKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZW5hbWVFbGVtZW50V2l0aFByZWZpeCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRvY3VtZW50LnJlbmFtZU5vZGUoZGVzY3JpcHRpb24sIG51bGwsICJhOmRlc2MiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZW5hbWVFbGVtZW50V2l0aE5hbWVzcGFjZSgpIHsKKyAgICAgICAgZG9jdW1lbnQucmVuYW1lTm9kZShkZXNjcmlwdGlvbiwgImh0dHA6Ly9zYWxlcyIsICJkZXNjIik7CisgICAgICAgIGFzc2VydEVxdWFscygiZGVzYyIsIGRlc2NyaXB0aW9uLmdldFRhZ05hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZGVzYyIsIGRlc2NyaXB0aW9uLmdldExvY2FsTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGRlc2NyaXB0aW9uLmdldFByZWZpeCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vc2FsZXMiLCBkZXNjcmlwdGlvbi5nZXROYW1lc3BhY2VVUkkoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlbmFtZUVsZW1lbnRXaXRoUHJlZml4QW5kTmFtZXNwYWNlKCkgeworICAgICAgICBkb2N1bWVudC5yZW5hbWVOb2RlKGRlc2NyaXB0aW9uLCAiaHR0cDovL3NhbGVzIiwgImE6ZGVzYyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImE6ZGVzYyIsIGRlc2NyaXB0aW9uLmdldFRhZ05hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZGVzYyIsIGRlc2NyaXB0aW9uLmdldExvY2FsTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgZGVzY3JpcHRpb24uZ2V0UHJlZml4KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9zYWxlcyIsIGRlc2NyaXB0aW9uLmdldE5hbWVzcGFjZVVSSSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVuYW1lQXR0cmlidXRlKCkgeworICAgICAgICBkb2N1bWVudC5yZW5hbWVOb2RlKGRlbHV4ZSwgbnVsbCwgInNwZWNpYWwiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzcGVjaWFsIiwgZGVsdXhlLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygic3BlY2lhbCIsIGRlbHV4ZS5nZXRMb2NhbE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBkZWx1eGUuZ2V0UHJlZml4KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZGVsdXhlLmdldE5hbWVzcGFjZVVSSSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVuYW1lQXR0cmlidXRlV2l0aFByZWZpeCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRvY3VtZW50LnJlbmFtZU5vZGUoZGVsdXhlLCBudWxsLCAiYTpzcGVjaWFsIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVuYW1lQXR0cmlidXRlV2l0aE5hbWVzcGFjZSgpIHsKKyAgICAgICAgZG9jdW1lbnQucmVuYW1lTm9kZShkZWx1eGUsICJodHRwOi8vc2FsZXMiLCAic3BlY2lhbCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInNwZWNpYWwiLCBkZWx1eGUuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzcGVjaWFsIiwgZGVsdXhlLmdldExvY2FsTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGRlbHV4ZS5nZXRQcmVmaXgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL3NhbGVzIiwgZGVsdXhlLmdldE5hbWVzcGFjZVVSSSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVuYW1lQXR0cmlidXRlV2l0aFByZWZpeEFuZE5hbWVzcGFjZSgpIHsKKyAgICAgICAgZG9jdW1lbnQucmVuYW1lTm9kZShkZWx1eGUsICJodHRwOi8vc2FsZXMiLCAiYTpzcGVjaWFsIik7CisgICAgICAgIGFzc2VydEVxdWFscygiYTpzcGVjaWFsIiwgZGVsdXhlLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygic3BlY2lhbCIsIGRlbHV4ZS5nZXRMb2NhbE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIGRlbHV4ZS5nZXRQcmVmaXgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL3NhbGVzIiwgZGVsdXhlLmdldE5hbWVzcGFjZVVSSSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXNlckRhdGFIYW5kbGVyTm90aWZpZWRPZlJlbmFtZXMoKSB7CisgICAgICAgIFJlY29yZGluZ0hhbmRsZXIgaGFuZGxlciA9IG5ldyBSZWNvcmRpbmdIYW5kbGVyKCk7CisgICAgICAgIGRlc2NyaXB0aW9uLnNldFVzZXJEYXRhKCJhIiwgImFwcGxlIiwgaGFuZGxlcik7CisgICAgICAgIGRlbHV4ZS5zZXRVc2VyRGF0YSgiYiIsICJiYW5hbmEiLCBoYW5kbGVyKTsKKyAgICAgICAgc3RhbmRhcmQuc2V0VXNlckRhdGEoImMiLCAiY2F0IiwgaGFuZGxlcik7CisKKyAgICAgICAgZG9jdW1lbnQucmVuYW1lTm9kZShkZWx1eGUsIG51bGwsICJzcGVjaWFsIik7CisgICAgICAgIGRvY3VtZW50LnJlbmFtZU5vZGUoZGVzY3JpcHRpb24sIG51bGwsICJkZXNjIik7CisKKyAgICAgICAgU2V0PFN0cmluZz4gZXhwZWN0ZWQgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7CisgICAgICAgIGV4cGVjdGVkLmFkZChub3RpZmljYXRpb24oTk9ERV9SRU5BTUVELCAiYSIsICJhcHBsZSIsIGRlc2NyaXB0aW9uLCBudWxsKSk7CisgICAgICAgIGV4cGVjdGVkLmFkZChub3RpZmljYXRpb24oTk9ERV9SRU5BTUVELCAiYiIsICJiYW5hbmEiLCBkZWx1eGUsIG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBoYW5kbGVyLmNhbGxzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVuYW1lVG9JbnZhbGlkKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgZG9jdW1lbnQucmVuYW1lTm9kZShkZXNjcmlwdGlvbiwgbnVsbCwgInhtbG5zOmZvbyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkb2N1bWVudC5yZW5hbWVOb2RlKGRlc2NyaXB0aW9uLCBudWxsLCAieG1sOmZvbyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkb2N1bWVudC5yZW5hbWVOb2RlKGRlbHV4ZSwgbnVsbCwgInhtbG5zIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVuYW1lTm9kZU90aGVyVGhhbkVsZW1lbnRPckF0dHJpYnV0ZSgpIHsKKyAgICAgICAgZm9yIChOb2RlIG5vZGUgOiBhbGxOb2RlcykgeworICAgICAgICAgICAgaWYgKG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkFUVFJJQlVURV9OT0RFCisgICAgICAgICAgICAgICAgICAgIHx8IG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGRvY3VtZW50LnJlbmFtZU5vZGUobm9kZSwgbnVsbCwgImZvbyIpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RG9jdW1lbnREb2VzTm90SGF2ZVdoaXRlc3BhY2VDaGlsZHJlbigpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB4bWwgPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIj8+ICBcbiIKKyAgICAgICAgICAgICAgICArICIgICA8Zm9vLz5cbiIKKyAgICAgICAgICAgICAgICArICIgIFxuIjsKKyAgICAgICAgZG9jdW1lbnQgPSBidWlsZGVyLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShuZXcgU3RyaW5nUmVhZGVyKHhtbCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJEb2N1bWVudCBub2RlcyBzaG91bGRuJ3QgaGF2ZSB0ZXh0IGNoaWxkcmVuIiwKKyAgICAgICAgICAgICAgICAxLCBkb2N1bWVudC5nZXRDaGlsZE5vZGVzKCkuZ2V0TGVuZ3RoKCkpOworICAgIH0KKworICAgIEBLbm93bkZhaWx1cmUoIkRhbHZpayBkb2N1bWVudCBub2RlcyBhY2NlcHQgYXJiaXRyYXJ5IGNoaWxkIG5vZGVzIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RG9jdW1lbnRBZGRDaGlsZCgpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkb2N1bWVudC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgiICAgIikpOworICAgICAgICAgICAgZmFpbCgiRG9jdW1lbnQgbm9kZXMgc2hvdWxkbid0IGFjY2VwdCBjaGlsZCBub2RlcyIpOworICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEl0ZXJhdGVGb3J3YXJkc1Rocm91Z2hJbm5lck5vZGVTaWJsaW5ncygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkb2N1bWVudCA9IGJ1aWxkZXIucGFyc2UobmV3IElucHV0U291cmNlKG5ldyBTdHJpbmdSZWFkZXIoCisgICAgICAgICAgICAgICAgIjxyb290PjxjaGlsZC8+PGNoaWxkLz48L3Jvb3Q+IikpKTsKKyAgICAgICAgTm9kZSByb290ID0gZG9jdW1lbnQuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIE5vZGUgY3VycmVudCA9IHJvb3QuZ2V0Q2hpbGROb2RlcygpLml0ZW0oMCk7CisgICAgICAgIHdoaWxlIChjdXJyZW50LmdldE5leHRTaWJsaW5nKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgY3VycmVudCA9IGN1cnJlbnQuZ2V0TmV4dFNpYmxpbmcoKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMocm9vdC5nZXRDaGlsZE5vZGVzKCkuaXRlbShyb290LmdldENoaWxkTm9kZXMoKS5nZXRMZW5ndGgoKSAtIDEpLCBjdXJyZW50KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXRlcmF0ZUJhY2t3YXJkc1Rocm91Z2hJbm5lck5vZGVTaWJsaW5ncygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkb2N1bWVudCA9IGJ1aWxkZXIucGFyc2UobmV3IElucHV0U291cmNlKG5ldyBTdHJpbmdSZWFkZXIoCisgICAgICAgICAgICAgICAgIjxyb290PjxjaGlsZC8+PGNoaWxkLz48L3Jvb3Q+IikpKTsKKyAgICAgICAgTm9kZSByb290ID0gZG9jdW1lbnQuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIE5vZGUgY3VycmVudCA9IHJvb3QuZ2V0Q2hpbGROb2RlcygpLml0ZW0ocm9vdC5nZXRDaGlsZE5vZGVzKCkuZ2V0TGVuZ3RoKCkgLSAxKTsKKyAgICAgICAgd2hpbGUgKGN1cnJlbnQuZ2V0UHJldmlvdXNTaWJsaW5nKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgY3VycmVudCA9IGN1cnJlbnQuZ2V0UHJldmlvdXNTaWJsaW5nKCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJvb3QuZ2V0Q2hpbGROb2RlcygpLml0ZW0oMCksIGN1cnJlbnQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJdGVyYXRlRm9yd2FyZHNUaHJvdWdoTGVhZk5vZGVTaWJsaW5ncygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkb2N1bWVudCA9IGJ1aWxkZXIucGFyc2UobmV3IElucHV0U291cmNlKG5ldyBTdHJpbmdSZWFkZXIoCisgICAgICAgICAgICAgICAgIjxyb290PiA8IS0tIC0tPiA8L3Jvb3Q+IikpKTsKKyAgICAgICAgTm9kZSByb290ID0gZG9jdW1lbnQuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIE5vZGUgY3VycmVudCA9IHJvb3QuZ2V0Q2hpbGROb2RlcygpLml0ZW0oMCk7CisgICAgICAgIHdoaWxlIChjdXJyZW50LmdldE5leHRTaWJsaW5nKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgY3VycmVudCA9IGN1cnJlbnQuZ2V0TmV4dFNpYmxpbmcoKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMocm9vdC5nZXRDaGlsZE5vZGVzKCkuaXRlbShyb290LmdldENoaWxkTm9kZXMoKS5nZXRMZW5ndGgoKSAtIDEpLCBjdXJyZW50KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXRlcmF0ZUJhY2t3YXJkc1Rocm91Z2hMZWFmTm9kZVNpYmxpbmdzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRvY3VtZW50ID0gYnVpbGRlci5wYXJzZShuZXcgSW5wdXRTb3VyY2UobmV3IFN0cmluZ1JlYWRlcigKKyAgICAgICAgICAgICAgICAiPHJvb3Q+IDwhLS0gLS0+IDwvcm9vdD4iKSkpOworICAgICAgICBOb2RlIHJvb3QgPSBkb2N1bWVudC5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgTm9kZSBjdXJyZW50ID0gcm9vdC5nZXRDaGlsZE5vZGVzKCkuaXRlbShyb290LmdldENoaWxkTm9kZXMoKS5nZXRMZW5ndGgoKSAtIDEpOworICAgICAgICB3aGlsZSAoY3VycmVudC5nZXRQcmV2aW91c1NpYmxpbmcoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBjdXJyZW50ID0gY3VycmVudC5nZXRQcmV2aW91c1NpYmxpbmcoKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMocm9vdC5nZXRDaGlsZE5vZGVzKCkuaXRlbSgwKSwgY3VycmVudCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB1YmxpY0lkQW5kU3lzdGVtSWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZG9jdW1lbnQgPSBidWlsZGVyLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShuZXcgU3RyaW5nUmVhZGVyKAorICAgICAgICAgICAgICAgICIgPCFET0NUWVBFIGh0bWwgUFVCTElDIFwiLS8vVzNDLy9EVEQgSFRNTCA0LjAxLy9FTlwiIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAiIFwiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQvc3RyaWN0LmR0ZFwiPiIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIjxodG1sPjwvaHRtbD4iKSkpOworICAgICAgICBkb2N0eXBlID0gZG9jdW1lbnQuZ2V0RG9jdHlwZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0bWwiLCBkb2N0eXBlLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLS8vVzNDLy9EVEQgSFRNTCA0LjAxLy9FTiIsIGRvY3R5cGUuZ2V0UHVibGljSWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQvc3RyaWN0LmR0ZCIsIGRvY3R5cGUuZ2V0U3lzdGVtSWQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN5c3RlbUlkT25seSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkb2N1bWVudCA9IGJ1aWxkZXIucGFyc2UobmV3IElucHV0U291cmNlKG5ldyBTdHJpbmdSZWFkZXIoCisgICAgICAgICAgICAgICAgIiA8IURPQ1RZUEUgaHRtbCBTWVNURU0gXCJodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sNC9zdHJpY3QuZHRkXCI+IgorICAgICAgICAgICAgICAgICAgICAgICAgKyAiPGh0bWw+PC9odG1sPiIpKSk7CisgICAgICAgIGRvY3R5cGUgPSBkb2N1bWVudC5nZXREb2N0eXBlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHRtbCIsIGRvY3R5cGUuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChkb2N0eXBlLmdldFB1YmxpY0lkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw0L3N0cmljdC5kdGQiLCBkb2N0eXBlLmdldFN5c3RlbUlkKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTaW5nbGVRdW90ZWRQdWJsaWNJZEFuZFN5c3RlbUlkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRvY3VtZW50ID0gYnVpbGRlci5wYXJzZShuZXcgSW5wdXRTb3VyY2UobmV3IFN0cmluZ1JlYWRlcigKKyAgICAgICAgICAgICAgICAiIDwhRE9DVFlQRSBodG1sIFBVQkxJQyAnLS8vVzNDLy9EVEQgSFRNTCA0LjAxLy9FTiciCisgICAgICAgICAgICAgICAgICAgICAgICArICIgJ2h0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw0L3N0cmljdC5kdGQnPiIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIjxodG1sPjwvaHRtbD4iKSkpOworICAgICAgICBkb2N0eXBlID0gZG9jdW1lbnQuZ2V0RG9jdHlwZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0bWwiLCBkb2N0eXBlLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLS8vVzNDLy9EVEQgSFRNTCA0LjAxLy9FTiIsIGRvY3R5cGUuZ2V0UHVibGljSWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQvc3RyaWN0LmR0ZCIsIGRvY3R5cGUuZ2V0U3lzdGVtSWQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEVsZW1lbnRzQnlUYWdOYW1lTnMoKSB7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRzID0gaXRlbS5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vYWRkb25zIiwgIm9wdGlvbiIpOworICAgICAgICBhc3NlcnRFcXVhbHMob3B0aW9uMSwgZWxlbWVudHMuaXRlbSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhvcHRpb24yLCBlbGVtZW50cy5pdGVtKDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGVsZW1lbnRzLmdldExlbmd0aCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RWxlbWVudHNCeVRhZ05hbWVXaXRoTmFtZXNwYWNlUHJlZml4KCkgeworICAgICAgICBOb2RlTGlzdCBlbGVtZW50cyA9IGl0ZW0uZ2V0RWxlbWVudHNCeVRhZ05hbWUoImE6b3B0aW9uIik7CisgICAgICAgIGFzc2VydEVxdWFscyhvcHRpb24xLCBlbGVtZW50cy5pdGVtKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG9wdGlvbjIsIGVsZW1lbnRzLml0ZW0oMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgZWxlbWVudHMuZ2V0TGVuZ3RoKCkpOworICAgIH0KKworICAgIC8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9MTc5MDcKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RWxlbWVudHNCeVRhZ05hbWVXaXRob3V0TmFtZXNwYWNlUHJlZml4KCkgeworICAgICAgICBOb2RlTGlzdCBlbGVtZW50cyA9IGl0ZW0uZ2V0RWxlbWVudHNCeVRhZ05hbWUoIm51dHJpdGlvbiIpOworICAgICAgICBhc3NlcnRFcXVhbHMobnV0cml0aW9uLCBlbGVtZW50cy5pdGVtKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGVsZW1lbnRzLmdldExlbmd0aCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RWxlbWVudHNCeVRhZ05hbWVXaXRoV2lsZGNhcmQoKSB7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRzID0gaXRlbS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpOworICAgICAgICBhc3NlcnRFcXVhbHMobmFtZSwgZWxlbWVudHMuaXRlbSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhkZXNjcmlwdGlvbiwgZWxlbWVudHMuaXRlbSgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhvcHRpb24xLCBlbGVtZW50cy5pdGVtKDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG9wdGlvbjIsIGVsZW1lbnRzLml0ZW0oMykpOworICAgICAgICBhc3NlcnRFcXVhbHMobnV0cml0aW9uLCBlbGVtZW50cy5pdGVtKDQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHZpdGFtaW5zLCBlbGVtZW50cy5pdGVtKDUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHZpdGFtaW5jLCBlbGVtZW50cy5pdGVtKDYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDcsIGVsZW1lbnRzLmdldExlbmd0aCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RWxlbWVudHNCeVRhZ05hbWVOc1dpdGhXaWxkY2FyZCgpIHsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudHMgPSBpdGVtLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiKiIpOworICAgICAgICBhc3NlcnRFcXVhbHMobmFtZSwgZWxlbWVudHMuaXRlbSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhkZXNjcmlwdGlvbiwgZWxlbWVudHMuaXRlbSgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhvcHRpb24xLCBlbGVtZW50cy5pdGVtKDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG9wdGlvbjIsIGVsZW1lbnRzLml0ZW0oMykpOworICAgICAgICBhc3NlcnRFcXVhbHMobnV0cml0aW9uLCBlbGVtZW50cy5pdGVtKDQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHZpdGFtaW5zLCBlbGVtZW50cy5pdGVtKDUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHZpdGFtaW5jLCBlbGVtZW50cy5pdGVtKDYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDcsIGVsZW1lbnRzLmdldExlbmd0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb2N1bWVudHMgc2hvdWxkbid0IGNvbnRhaW4gZG9jdW1lbnQgZnJhZ21lbnRzLgorICAgICAqIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9MjczNQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRpbmdBRG9jdW1lbnRGcmFnbWVudEFkZHNJdHNDaGlsZHJlbigpIHsKKyAgICAgICAgRWxlbWVudCBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOworICAgICAgICBFbGVtZW50IGIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJiIik7CisgICAgICAgIEVsZW1lbnQgYyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImMiKTsKKyAgICAgICAgRG9jdW1lbnRGcmFnbWVudCBmcmFnbWVudCA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKKyAgICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQoYSk7CisgICAgICAgIGZyYWdtZW50LmFwcGVuZENoaWxkKGIpOworICAgICAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChjKTsKKworICAgICAgICBOb2RlIHJldHVybmVkID0gbWVudS5hcHBlbmRDaGlsZChmcmFnbWVudCk7CisgICAgICAgIGFzc2VydFNhbWUoZnJhZ21lbnQsIHJldHVybmVkKTsKKyAgICAgICAgTm9kZUxpc3QgY2hpbGRyZW4gPSBtZW51LmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDYsIGNoaWxkcmVuLmdldExlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjaGlsZHJlbi5pdGVtKDApIGluc3RhbmNlb2YgVGV4dCk7IC8vIHdoaXRlc3BhY2UKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGl0ZW0sIGNoaWxkcmVuLml0ZW0oMSkpOworICAgICAgICBhc3NlcnRUcnVlKGNoaWxkcmVuLml0ZW0oMikgaW5zdGFuY2VvZiBUZXh0KTsgLy8gd2hpdGVzcGFjZQorICAgICAgICBhc3NlcnRFcXVhbHMoYSwgY2hpbGRyZW4uaXRlbSgzKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhiLCBjaGlsZHJlbi5pdGVtKDQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGMsIGNoaWxkcmVuLml0ZW0oNSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXBsYWNpbmdXaXRoQURvY3VtZW50RnJhZ21lbnRJbnNlcnRzSXRzQ2hpbGRyZW4oKSB7CisgICAgICAgIEVsZW1lbnQgYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKTsKKyAgICAgICAgRWxlbWVudCBiID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYiIpOworICAgICAgICBFbGVtZW50IGMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJjIik7CisgICAgICAgIERvY3VtZW50RnJhZ21lbnQgZnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CisgICAgICAgIGZyYWdtZW50LmFwcGVuZENoaWxkKGEpOworICAgICAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChiKTsKKyAgICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQoYyk7CisKKyAgICAgICAgTm9kZSByZXR1cm5lZCA9IG1lbnUucmVwbGFjZUNoaWxkKGZyYWdtZW50LCBpdGVtKTsKKyAgICAgICAgYXNzZXJ0U2FtZShpdGVtLCByZXR1cm5lZCk7CisgICAgICAgIE5vZGVMaXN0IGNoaWxkcmVuID0gbWVudS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBjaGlsZHJlbi5nZXRMZW5ndGgoKSk7CisgICAgICAgIGFzc2VydFRydWUoY2hpbGRyZW4uaXRlbSgwKSBpbnN0YW5jZW9mIFRleHQpOyAvLyB3aGl0ZXNwYWNlCisgICAgICAgIGFzc2VydEVxdWFscyhhLCBjaGlsZHJlbi5pdGVtKDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGIsIGNoaWxkcmVuLml0ZW0oMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoYywgY2hpbGRyZW4uaXRlbSgzKSk7CisgICAgICAgIGFzc2VydFRydWUoY2hpbGRyZW4uaXRlbSg0KSBpbnN0YW5jZW9mIFRleHQpOyAvLyB3aGl0ZXNwYWNlCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvYWxlc2NpbmdPZmZCeURlZmF1bHQoKSB7CisgICAgICAgIGFzc2VydEZhbHNlKERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKS5pc0NvYWxlc2NpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvYWxlc2NpbmdPbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgeG1sID0gIjxmb28+YWJjPCFbQ0RBVEFbZGVmXV0+Z2hpPC9mb28+IjsKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICAgICAgICBmYWN0b3J5LnNldENvYWxlc2NpbmcodHJ1ZSk7CisgICAgICAgIGRvY3VtZW50ID0gZmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKS5wYXJzZShuZXcgSW5wdXRTb3VyY2UobmV3IFN0cmluZ1JlYWRlcih4bWwpKSk7CisgICAgICAgIEVsZW1lbnQgZG9jdW1lbnRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIFRleHQgdGV4dCA9IChUZXh0KSBkb2N1bWVudEVsZW1lbnQuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFiY2RlZmdoaSIsIHRleHQuZ2V0VGV4dENvbnRlbnQoKSk7CisgICAgICAgIGFzc2VydE51bGwodGV4dC5nZXROZXh0U2libGluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29hbGVzY2luZ09mZigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgeG1sID0gIjxmb28+YWJjPCFbQ0RBVEFbZGVmXV0+Z2hpPC9mb28+IjsKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICAgICAgICBmYWN0b3J5LnNldENvYWxlc2NpbmcoZmFsc2UpOworICAgICAgICBkb2N1bWVudCA9IGZhY3RvcnkubmV3RG9jdW1lbnRCdWlsZGVyKCkucGFyc2UobmV3IElucHV0U291cmNlKG5ldyBTdHJpbmdSZWFkZXIoeG1sKSkpOworICAgICAgICBFbGVtZW50IGRvY3VtZW50RWxlbWVudCA9IGRvY3VtZW50LmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgICBUZXh0IGFiYyA9IChUZXh0KSBkb2N1bWVudEVsZW1lbnQuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFiYyIsIGFiYy5nZXRUZXh0Q29udGVudCgpKTsKKyAgICAgICAgQ0RBVEFTZWN0aW9uIGRlZiA9IChDREFUQVNlY3Rpb24pIGFiYy5nZXROZXh0U2libGluZygpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRlZiIsIGRlZi5nZXRUZXh0Q29udGVudCgpKTsKKyAgICAgICAgVGV4dCBnaGkgPSAoVGV4dCkgZGVmLmdldE5leHRTaWJsaW5nKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ2hpIiwgZ2hpLmdldFRleHRDb250ZW50KCkpOworICAgICAgICBhc3NlcnROdWxsKGdoaS5nZXROZXh0U2libGluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXhwYW5kaW5nRW50aXR5UmVmZXJlbmNlc09uQnlEZWZhdWx0KCkgeworICAgICAgICBhc3NlcnRUcnVlKERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKS5pc0V4cGFuZEVudGl0eVJlZmVyZW5jZXMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEV4cGFuZGluZ0VudGl0eVJlZmVyZW5jZXNPbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgeG1sID0gIjwhRE9DVFlQRSBmb28gWyA8IUVOVElUWSBkZWYgXCJERUZcIj4gXT4iCisgICAgICAgICAgICAgICAgKyAiPGZvbz5hYmMmZGVmO2doaTwvZm9vPiI7CisgICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9IERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgZmFjdG9yeS5zZXRFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKHRydWUpOworICAgICAgICBkb2N1bWVudCA9IGZhY3RvcnkubmV3RG9jdW1lbnRCdWlsZGVyKCkucGFyc2UobmV3IElucHV0U291cmNlKG5ldyBTdHJpbmdSZWFkZXIoeG1sKSkpOworICAgICAgICBFbGVtZW50IGRvY3VtZW50RWxlbWVudCA9IGRvY3VtZW50LmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgICBUZXh0IHRleHQgPSAoVGV4dCkgZG9jdW1lbnRFbGVtZW50LmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGlzIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgZXhwYW5kIGVudGl0eSByZWZlcmVuY2VzIiwKKyAgICAgICAgICAgICAgICAiYWJjREVGZ2hpIiwgdGV4dC5nZXRUZXh0Q29udGVudCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh0ZXh0LmdldE5leHRTaWJsaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFeHBhbmRpbmdFbnRpdHlSZWZlcmVuY2VzT2ZmKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB4bWwgPSAiPCFET0NUWVBFIGZvbyBbIDwhRU5USVRZIGRlZiBcIkRFRlwiPiBdPiIKKyAgICAgICAgICAgICAgICArICI8Zm9vPmFiYyZkZWY7Z2hpPC9mb28+IjsKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICAgICAgICBmYWN0b3J5LnNldEV4cGFuZEVudGl0eVJlZmVyZW5jZXMoZmFsc2UpOworCisgICAgICAgIGRvY3VtZW50ID0gZmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKS5wYXJzZShuZXcgSW5wdXRTb3VyY2UobmV3IFN0cmluZ1JlYWRlcih4bWwpKSk7CisgICAgICAgIEVsZW1lbnQgZG9jdW1lbnRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIFRleHQgYWJjID0gKFRleHQpIGRvY3VtZW50RWxlbWVudC5nZXRGaXJzdENoaWxkKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiYWJjIiwgYWJjLmdldFRleHRDb250ZW50KCkpOworCisgICAgICAgIEVudGl0eVJlZmVyZW5jZSBkZWYgPSAoRW50aXR5UmVmZXJlbmNlKSBhYmMuZ2V0TmV4dFNpYmxpbmcoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkZWYiLCBkZWYuZ2V0Tm9kZU5hbWUoKSk7CisKKyAgICAgICAgVGV4dCBnaGkgPSAoVGV4dCkgZGVmLmdldE5leHRTaWJsaW5nKCk7CisgICAgICAgIGFzc2VydE51bGwoZ2hpLmdldE5leHRTaWJsaW5nKCkpOworCisgICAgICAgIC8qCisgICAgICAgICAqIFdlIGV4cGVjdCB0aGUgZW50aXR5IHJlZmVyZW5jZSB0byBjb250YWluIG9uZSBjaGlsZCBUZXh0IG5vZGUgIkRFRiIuCisgICAgICAgICAqIFRoZSBSSSdzIGVudGl0eSByZWZlcmVuY2UgY29udGFpbnMgbm8gY2hpbGRyZW4uIEluc3RlYWQgaXQgc3Rhc2hlcworICAgICAgICAgKiAiREVGIiBpbiB0aGUgbmV4dCBzaWJsaW5nIG5vZGUuCisgICAgICAgICAqLworICAgICAgICBhc3NlcnRFcXVhbHMoIkV4cGVjdGVkIHRleHQgdmFsdWUgb25seSBhbmQgbm8gZXhwYW5kZWQgZW50aXR5IGRhdGEiLAorICAgICAgICAgICAgICAgICJnaGkiLCBnaGkuZ2V0VGV4dENvbnRlbnQoKSk7CisgICAgICAgIE5vZGVMaXN0IGRlZkNoaWxkcmVuID0gZGVmLmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGlzIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgaW5jbHVkZSBjaGlsZHJlbiBpbiBlbnRpdHkgcmVmZXJlbmNlcyIsCisgICAgICAgICAgICAgICAgMSwgZGVmQ2hpbGRyZW4uZ2V0TGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkRFRiIsIGRlZkNoaWxkcmVuLml0ZW0oMCkuZ2V0VGV4dENvbnRlbnQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJlZGVmaW5lZCBlbnRpdGllcyBzaG91bGQgYWx3YXlzIGJlIGV4cGFuZGVkLgorICAgICAqIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTIyNQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFeHBhbmRpbmdFbnRpdHlSZWZlcmVuY2VzT2ZmRG9lc05vdEltcGFjdFByZWRlZmluZWRFbnRpdGllcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgeG1sID0gIjxmb28+YWJjJmFtcDtkZWY8L2Zvbz4iOworICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisgICAgICAgIGZhY3Rvcnkuc2V0RXhwYW5kRW50aXR5UmVmZXJlbmNlcyhmYWxzZSk7CisgICAgICAgIGRvY3VtZW50ID0gZmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKS5wYXJzZShuZXcgSW5wdXRTb3VyY2UobmV3IFN0cmluZ1JlYWRlcih4bWwpKSk7CisgICAgICAgIEVsZW1lbnQgZG9jdW1lbnRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIFRleHQgdGV4dCA9IChUZXh0KSBkb2N1bWVudEVsZW1lbnQuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFiYyZkZWYiLCB0ZXh0LmdldFRleHRDb250ZW50KCkpOworICAgICAgICBhc3NlcnROdWxsKHRleHQuZ2V0TmV4dFNpYmxpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEV4cGFuZGluZ0VudGl0eVJlZmVyZW5jZXNPZmZEb2VzTm90SW1wYWN0Q2hhcmFjdGVyRW50aXRpZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8Zm9vPmFiYyYjMzg7ZGVmJiN4MjY7Z2hpPC9mb28+IjsKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICAgICAgICBmYWN0b3J5LnNldEV4cGFuZEVudGl0eVJlZmVyZW5jZXMoZmFsc2UpOworICAgICAgICBkb2N1bWVudCA9IGZhY3RvcnkubmV3RG9jdW1lbnRCdWlsZGVyKCkucGFyc2UobmV3IElucHV0U291cmNlKG5ldyBTdHJpbmdSZWFkZXIoeG1sKSkpOworICAgICAgICBFbGVtZW50IGRvY3VtZW50RWxlbWVudCA9IGRvY3VtZW50LmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgICBUZXh0IHRleHQgPSAoVGV4dCkgZG9jdW1lbnRFbGVtZW50LmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhYmMmZGVmJmdoaSIsIHRleHQuZ2V0VGV4dENvbnRlbnQoKSk7CisgICAgICAgIGFzc2VydE51bGwodGV4dC5nZXROZXh0U2libGluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qm9tQW5kQnl0ZUlucHV0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSB4bWwgPSB7CisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZWYsIChieXRlKSAweGJiLCAoYnl0ZSkgMHhiZiwKKyAgICAgICAgICAgICAgICAnPCcsICdpJywgJ24nLCAncCcsICd1JywgJ3QnLCAnLycsICc+JworICAgICAgICB9OworICAgICAgICBkb2N1bWVudCA9IGJ1aWxkZXIucGFyc2UobmV3IElucHV0U291cmNlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSh4bWwpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5wdXQiLCBkb2N1bWVudC5nZXREb2N1bWVudEVsZW1lbnQoKS5nZXROb2RlTmFtZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qm9tQW5kQnl0ZUlucHV0V2l0aEV4cGxpY2l0Q2hhcnNldCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10geG1sID0geworICAgICAgICAgICAgICAgIChieXRlKSAweGVmLCAoYnl0ZSkgMHhiYiwgKGJ5dGUpIDB4YmYsCisgICAgICAgICAgICAgICAgJzwnLCAnaScsICduJywgJ3AnLCAndScsICd0JywgJy8nLCAnPicKKyAgICAgICAgfTsKKyAgICAgICAgSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UgPSBuZXcgSW5wdXRTb3VyY2UobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHhtbCkpOworICAgICAgICBpbnB1dFNvdXJjZS5zZXRFbmNvZGluZygiVVRGLTgiKTsKKyAgICAgICAgZG9jdW1lbnQgPSBidWlsZGVyLnBhcnNlKGlucHV0U291cmNlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbnB1dCIsIGRvY3VtZW50LmdldERvY3VtZW50RWxlbWVudCgpLmdldE5vZGVOYW1lKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCb21BbmRDaGFyYWN0ZXJJbnB1dCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZShuZXcgU3RyaW5nUmVhZGVyKCJcdWZlZmY8aW5wdXQvPiIpKTsKKyAgICAgICAgaW5wdXRTb3VyY2Uuc2V0RW5jb2RpbmcoIlVURi04Iik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidWlsZGVyLnBhcnNlKGlucHV0U291cmNlKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIFJlY29yZGluZ0hhbmRsZXIgaW1wbGVtZW50cyBVc2VyRGF0YUhhbmRsZXIgeworICAgICAgICBmaW5hbCBTZXQ8U3RyaW5nPiBjYWxscyA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKyAgICAgICAgcHVibGljIHZvaWQgaGFuZGxlKHNob3J0IG9wZXJhdGlvbiwgU3RyaW5nIGtleSwgT2JqZWN0IGRhdGEsIE5vZGUgc3JjLCBOb2RlIGRzdCkgeworICAgICAgICAgICAgY2FsbHMuYWRkKG5vdGlmaWNhdGlvbihvcGVyYXRpb24sIGtleSwgZGF0YSwgc3JjLCBkc3QpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIG5vdGlmaWNhdGlvbihzaG9ydCBvcGVyYXRpb24sIFN0cmluZyBrZXksIE9iamVjdCBkYXRhLCBOb2RlIHNyYywgTm9kZSBkc3QpIHsKKyAgICAgICAgcmV0dXJuICJvcDoiICsgb3BlcmF0aW9uICsgIiBrZXk6IiArIGtleSArICIgZGF0YToiICsgZGF0YSArICIgc3JjOiIgKyBzcmMgKyAiIGRzdDoiICsgZHN0OworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGRvbVRvU3RyaW5nKERvY3VtZW50IGRvY3VtZW50KSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24geworICAgICAgICBTdHJpbmdXcml0ZXIgd3JpdGVyID0gbmV3IFN0cmluZ1dyaXRlcigpOworICAgICAgICB0cmFuc2Zvcm1lci50cmFuc2Zvcm0obmV3IERPTVNvdXJjZShkb2N1bWVudCksIG5ldyBTdHJlYW1SZXN1bHQod3JpdGVyKSk7CisgICAgICAgIFN0cmluZyByZXN1bHQgPSB3cml0ZXIudG9TdHJpbmcoKTsKKworICAgICAgICAvKgorICAgICAgICAgKiBIYWNrOiBzd2FwIDxuYW1lPidzIGE6c3RhbmRhcmQgYXR0cmlidXRlIGFuZCBkZWx1eGUgYXR0cmlidXRlIGlmCisgICAgICAgICAqIHRoZXkncmUgb3V0IG9mIG9yZGVyLiBTb21lIGRvY3VtZW50IHRyYW5zZm9ybWF0aW9ucyByZW9yZGVyIHRoZQorICAgICAgICAgKiBhdHRyaWJ1dGVzLCB3aGljaCBjYXVzZXMgcGFpbiB3aGVuIHdlIHRyeSB0byB1c2UgU3RyaW5nIGNvbXBhcmlzb24gb24KKyAgICAgICAgICogdGhlbS4KKyAgICAgICAgICovCisgICAgICAgIE1hdGNoZXIgYXR0cmlidXRlTWF0Y2hlciA9IFBhdHRlcm4uY29tcGlsZSgiIGE6c3RhbmRhcmQ9XCJbXlwiXStcIiIpLm1hdGNoZXIocmVzdWx0KTsKKyAgICAgICAgaWYgKGF0dHJpYnV0ZU1hdGNoZXIuZmluZCgpKSB7CisgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQuc3Vic3RyaW5nKDAsIGF0dHJpYnV0ZU1hdGNoZXIuc3RhcnQoKSkKKyAgICAgICAgICAgICAgICAgICAgKyByZXN1bHQuc3Vic3RyaW5nKGF0dHJpYnV0ZU1hdGNoZXIuZW5kKCkpOworICAgICAgICAgICAgaW50IGluc2VydGlvblBvaW50ID0gcmVzdWx0LmluZGV4T2YoIiBkZWx1eGU9XCIiKTsKKyAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zdWJzdHJpbmcoMCwgaW5zZXJ0aW9uUG9pbnQpCisgICAgICAgICAgICAgICAgICAgICsgYXR0cmlidXRlTWF0Y2hlci5ncm91cCgpCisgICAgICAgICAgICAgICAgICAgICsgcmVzdWx0LnN1YnN0cmluZyhpbnNlcnRpb25Qb2ludCk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGRvbVRvU3RyaW5nU3RyaXBFbGVtZW50V2hpdGVzcGFjZShEb2N1bWVudCBkb2N1bWVudCkKKyAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBkb21Ub1N0cmluZyhkb2N1bWVudCkucmVwbGFjZUFsbCgiKD9tKT5cXHMrPCIsICI+PCIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3htbC9FeHBhdFNheFBhcnNlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3htbC9FeHBhdFNheFBhcnNlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MWNhNWJmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL0V4cGF0U2F4UGFyc2VyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjg1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLnhtbDsKKworaW1wb3J0IGNvbS5nb29nbGUubW9ja3dlYnNlcnZlci5Nb2NrUmVzcG9uc2U7CitpbXBvcnQgY29tLmdvb2dsZS5tb2Nrd2Vic2VydmVyLk1vY2tXZWJTZXJ2ZXI7CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CitpbXBvcnQgamF2YS5pby5TdHJpbmdSZWFkZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnhtbC5FeHBhdFJlYWRlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOworaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOworaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5leHQuRGVmYXVsdEhhbmRsZXIyOworaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuRGVmYXVsdEhhbmRsZXI7CisKK3B1YmxpYyBjbGFzcyBFeHBhdFNheFBhcnNlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU05JUFBFVCA9ICI8ZGFnbnkgZGFkPVwiYm9iXCI+aGVsbG88L2RhZ255PiI7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2xvYmFsUmVmZXJlbmNlVGFibGVPdmVyZmxvdygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBXZSB1c2VkIHRvIHVzZSBhIEpOSSBnbG9iYWwgcmVmZXJlbmNlIHBlciBpbnRlcm5lZCBzdHJpbmcuCisgICAgICAgIC8vIEZyYW1ld29yayBhcHBzIGhhdmUgYSBsaW1pdCBvZiAyMDAwIEpOSSBnbG9iYWwgcmVmZXJlbmNlcyBwZXIgVk0uCisgICAgICAgIFN0cmluZ0J1aWxkZXIgeG1sID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgeG1sLmFwcGVuZCgiPHJvb3Q+Iik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNDAwMDsgKytpKSB7CisgICAgICAgICAgICB4bWwuYXBwZW5kKCI8dGFnIiArIGkgKyAiPiIpOworICAgICAgICAgICAgeG1sLmFwcGVuZCgiPC90YWciICsgaSArICI+Iik7CisgICAgICAgIH0KKyAgICAgICAgeG1sLmFwcGVuZCgiPC9yb290PiIpOworICAgICAgICBwYXJzZSh4bWwudG9TdHJpbmcoKSwgbmV3IERlZmF1bHRIYW5kbGVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFeGNlcHRpb25zKCkgeworICAgICAgICAvLyBGcm9tIHN0YXJ0RWxlbWVudCgpLgorICAgICAgICBDb250ZW50SGFuZGxlciBjb250ZW50SGFuZGxlciA9IG5ldyBEZWZhdWx0SGFuZGxlcigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsCisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxTmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJzZShTTklQUEVULCBjb250ZW50SGFuZGxlcik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBjaGVja2VkKSB7IC8qIGV4cGVjdGVkICovIH0KKworICAgICAgICAvLyBGcm9tIGVuZEVsZW1lbnQoKS4KKyAgICAgICAgY29udGVudEhhbmRsZXIgPSBuZXcgRGVmYXVsdEhhbmRsZXIoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHFOYW1lKQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJzZShTTklQUEVULCBjb250ZW50SGFuZGxlcik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBjaGVja2VkKSB7IC8qIGV4cGVjdGVkICovIH0KKworICAgICAgICAvLyBGcm9tIGNoYXJhY3RlcnMoKS4KKyAgICAgICAgY29udGVudEhhbmRsZXIgPSBuZXcgRGVmYXVsdEhhbmRsZXIoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcnNlKFNOSVBQRVQsIGNvbnRlbnRIYW5kbGVyKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGNoZWNrZWQpIHsgLyogZXhwZWN0ZWQgKi8gfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTYXgoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBQYXJzZSBTdHJpbmcuCisgICAgICAgICAgICBUZXN0SGFuZGxlciBoYW5kbGVyID0gbmV3IFRlc3RIYW5kbGVyKCk7CisgICAgICAgICAgICBwYXJzZShTTklQUEVULCBoYW5kbGVyKTsKKyAgICAgICAgICAgIHZhbGlkYXRlKGhhbmRsZXIpOworCisgICAgICAgICAgICAvLyBQYXJzZSBSZWFkZXIuCisgICAgICAgICAgICBoYW5kbGVyID0gbmV3IFRlc3RIYW5kbGVyKCk7CisgICAgICAgICAgICBwYXJzZShuZXcgU3RyaW5nUmVhZGVyKFNOSVBQRVQpLCBoYW5kbGVyKTsKKyAgICAgICAgICAgIHZhbGlkYXRlKGhhbmRsZXIpOworCisgICAgICAgICAgICAvLyBQYXJzZSBJbnB1dFN0cmVhbS4KKyAgICAgICAgICAgIGhhbmRsZXIgPSBuZXcgVGVzdEhhbmRsZXIoKTsKKyAgICAgICAgICAgIHBhcnNlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShTTklQUEVULmdldEJ5dGVzKCkpLAorICAgICAgICAgICAgICAgICAgICBFbmNvZGluZy5VVEZfOCwgaGFuZGxlcik7CisgICAgICAgICAgICB2YWxpZGF0ZShoYW5kbGVyKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyB2b2lkIHZhbGlkYXRlKFRlc3RIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkYWdueSIsIGhhbmRsZXIuc3RhcnRFbGVtZW50TmFtZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZGFnbnkiLCBoYW5kbGVyLmVuZEVsZW1lbnROYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJoZWxsbyIsIGhhbmRsZXIudGV4dC50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgVGVzdEhhbmRsZXIgZXh0ZW5kcyBEZWZhdWx0SGFuZGxlciB7CisKKyAgICAgICAgU3RyaW5nIHN0YXJ0RWxlbWVudE5hbWU7CisgICAgICAgIFN0cmluZyBlbmRFbGVtZW50TmFtZTsKKyAgICAgICAgU3RyaW5nQnVpbGRlciB0ZXh0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSwKKyAgICAgICAgICAgICAgICBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHRocm93cyBTQVhFeGNlcHRpb24geworCisgICAgICAgICAgICBhc3NlcnROdWxsKHRoaXMuc3RhcnRFbGVtZW50TmFtZSk7CisgICAgICAgICAgICB0aGlzLnN0YXJ0RWxlbWVudE5hbWUgPSBsb2NhbE5hbWU7CisKKyAgICAgICAgICAgIC8vIFZhbGlkYXRlIGF0dHJpYnV0ZXMuCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgYXR0cmlidXRlcy5nZXRMZW5ndGgoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGF0dHJpYnV0ZXMuZ2V0VVJJKDApKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZGFkIiwgYXR0cmlidXRlcy5nZXRMb2NhbE5hbWUoMCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJib2IiLCBhdHRyaWJ1dGVzLmdldFZhbHVlKDApKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBhdHRyaWJ1dGVzLmdldEluZGV4KCIiLCAiZGFkIikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJib2IiLCBhdHRyaWJ1dGVzLmdldFZhbHVlKCIiLCAiZGFkIikpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lKQorICAgICAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICAgICAgYXNzZXJ0TnVsbCh0aGlzLmVuZEVsZW1lbnROYW1lKTsKKyAgICAgICAgICAgIHRoaXMuZW5kRWxlbWVudE5hbWUgPSBsb2NhbE5hbWU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRoaXMudGV4dC5hcHBlbmQoY2gsIHN0YXJ0LCBsZW5ndGgpOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBYTUwgPQorICAgICAgICAiPG9uZSB4bWxucz0nbnM6ZGVmYXVsdCcgeG1sbnM6bjE9J25zOjEnIGE9J2InPlxuIgorICAgICAgICAgICAgICArICIgIDxuMTp0d28gYz0nZCcgbjE6ZT0nZicgeG1sbnM6bjI9J25zOjInPnRleHQ8L24xOnR3bz5cbiIKKyAgICAgICAgICAgICAgKyAiPC9vbmU+IjsKKworICAgIHB1YmxpYyB2b2lkIHRlc3ROYW1lc3BhY2VzKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmFtZXNwYWNlSGFuZGxlciBoYW5kbGVyID0gbmV3IE5hbWVzcGFjZUhhbmRsZXIoKTsKKyAgICAgICAgICAgIHBhcnNlKFhNTCwgaGFuZGxlcik7CisgICAgICAgICAgICBoYW5kbGVyLnZhbGlkYXRlKCk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBOYW1lc3BhY2VIYW5kbGVyIGltcGxlbWVudHMgQ29udGVudEhhbmRsZXIgeworCisgICAgICAgIExvY2F0b3IgbG9jYXRvcjsKKyAgICAgICAgYm9vbGVhbiBkb2N1bWVudFN0YXJ0ZWQ7CisgICAgICAgIGJvb2xlYW4gZG9jdW1lbnRFbmRlZDsKKyAgICAgICAgTWFwPFN0cmluZywgU3RyaW5nPiBwcmVmaXhNYXBwaW5ncyA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOworCisgICAgICAgIGJvb2xlYW4gb25lU3RhcnRlZDsKKyAgICAgICAgYm9vbGVhbiB0d29TdGFydGVkOworICAgICAgICBib29sZWFuIG9uZUVuZGVkOworICAgICAgICBib29sZWFuIHR3b0VuZGVkOworCisgICAgICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShkb2N1bWVudEVuZGVkKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvcihMb2NhdG9yIGxvY2F0b3IpIHsKKyAgICAgICAgICAgIHRoaXMubG9jYXRvciA9IGxvY2F0b3I7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBkb2N1bWVudFN0YXJ0ZWQgPSB0cnVlOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChsb2NhdG9yKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBwcmVmaXhNYXBwaW5ncy5zaXplKCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZG9jdW1lbnRFbmRlZCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShkb2N1bWVudFN0YXJ0ZWQpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShvbmVFbmRlZCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHR3b0VuZGVkKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBwcmVmaXhNYXBwaW5ncy5zaXplKCkpOworICAgICAgICAgICAgZG9jdW1lbnRFbmRlZCA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHByZWZpeE1hcHBpbmdzLnB1dChwcmVmaXgsIHVyaSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwcmVmaXhNYXBwaW5ncy5yZW1vdmUocHJlZml4KSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lLAorICAgICAgICAgICAgICAgIEF0dHJpYnV0ZXMgYXR0cykgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisKKyAgICAgICAgICAgIGlmIChsb2NhbE5hbWUgPT0gIm9uZSIpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMiwgcHJlZml4TWFwcGluZ3Muc2l6ZSgpKTsKKworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBsb2NhdG9yLmdldExpbmVOdW1iZXIoKSk7CisKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShvbmVTdGFydGVkKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZSh0d29TdGFydGVkKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShvbmVFbmRlZCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UodHdvRW5kZWQpOworCisgICAgICAgICAgICAgICAgb25lU3RhcnRlZCA9IHRydWU7CisKKyAgICAgICAgICAgICAgICBhc3NlcnRTYW1lKCJuczpkZWZhdWx0IiwgdXJpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIm9uZSIsIHFOYW1lKTsKKworICAgICAgICAgICAgICAgIC8vIENoZWNrIGF0dHMuCisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGF0dHMuZ2V0TGVuZ3RoKCkpOworCisgICAgICAgICAgICAgICAgYXNzZXJ0U2FtZSgiIiwgYXR0cy5nZXRVUkkoMCkpOworICAgICAgICAgICAgICAgIGFzc2VydFNhbWUoImEiLCBhdHRzLmdldExvY2FsTmFtZSgwKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJiIiwgYXR0cy5nZXRWYWx1ZSgwKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGF0dHMuZ2V0SW5kZXgoIiIsICJhIikpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiYiIsIGF0dHMuZ2V0VmFsdWUoIiIsICJhIikpOworCisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAobG9jYWxOYW1lID09ICJ0d28iKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHByZWZpeE1hcHBpbmdzLnNpemUoKSk7CisKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKG9uZVN0YXJ0ZWQpOworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKHR3b1N0YXJ0ZWQpOworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKG9uZUVuZGVkKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZSh0d29FbmRlZCk7CisKKyAgICAgICAgICAgICAgICB0d29TdGFydGVkID0gdHJ1ZTsKKworICAgICAgICAgICAgICAgIGFzc2VydFNhbWUoIm5zOjEiLCB1cmkpOworICAgICAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIm4xOnR3byIsIHFOYW1lKTsKKworICAgICAgICAgICAgICAgIC8vIENoZWNrIGF0dHMuCisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGF0dHMuZ2V0TGVuZ3RoKCkpOworCisgICAgICAgICAgICAgICAgYXNzZXJ0U2FtZSgiIiwgYXR0cy5nZXRVUkkoMCkpOworICAgICAgICAgICAgICAgIGFzc2VydFNhbWUoImMiLCBhdHRzLmdldExvY2FsTmFtZSgwKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJkIiwgYXR0cy5nZXRWYWx1ZSgwKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGF0dHMuZ2V0SW5kZXgoIiIsICJjIikpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiZCIsIGF0dHMuZ2V0VmFsdWUoIiIsICJjIikpOworCisgICAgICAgICAgICAgICAgYXNzZXJ0U2FtZSgibnM6MSIsIGF0dHMuZ2V0VVJJKDEpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRTYW1lKCJlIiwgYXR0cy5nZXRMb2NhbE5hbWUoMSkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiZiIsIGF0dHMuZ2V0VmFsdWUoMSkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBhdHRzLmdldEluZGV4KCJuczoxIiwgImUiKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmIiwgYXR0cy5nZXRWYWx1ZSgibnM6MSIsICJlIikpOworCisgICAgICAgICAgICAgICAgLy8gV2Ugc2hvdWxkbid0IGZpbmQgdGhlc2UuCisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBhdHRzLmdldEluZGV4KCJuczpkZWZhdWx0IiwgImUiKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGF0dHMuZ2V0VmFsdWUoIm5zOmRlZmF1bHQiLCAiZSIpKTsKKworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lKQorICAgICAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKGxvY2FsTmFtZSA9PSAib25lIikgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygzLCBsb2NhdG9yLmdldExpbmVOdW1iZXIoKSk7CisKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKG9uZVN0YXJ0ZWQpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUodHdvU3RhcnRlZCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSh0d29FbmRlZCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2Uob25lRW5kZWQpOworCisgICAgICAgICAgICAgICAgb25lRW5kZWQgPSB0cnVlOworCisgICAgICAgICAgICAgICAgYXNzZXJ0U2FtZSgibnM6ZGVmYXVsdCIsIHVyaSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJvbmUiLCBxTmFtZSk7CisKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChsb2NhbE5hbWUgPT0gInR3byIpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKG9uZVN0YXJ0ZWQpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUodHdvU3RhcnRlZCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UodHdvRW5kZWQpOworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKG9uZUVuZGVkKTsKKworICAgICAgICAgICAgICAgIHR3b0VuZGVkID0gdHJ1ZTsKKworICAgICAgICAgICAgICAgIGFzc2VydFNhbWUoIm5zOjEiLCB1cmkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygibjE6dHdvIiwgcU5hbWUpOworCisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICAgICAgU3RyaW5nIHMgPSBuZXcgU3RyaW5nKGNoLCBzdGFydCwgbGVuZ3RoKS50cmltKCk7CisKKyAgICAgICAgICAgIGlmICghcy5lcXVhbHMoIiIpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShvbmVTdGFydGVkKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKHR3b1N0YXJ0ZWQpOworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKG9uZUVuZGVkKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZSh0d29FbmRlZCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0Iiwgcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQorICAgICAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQorICAgICAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIFRlc3REdGRIYW5kbGVyIHJ1bkR0ZFRlc3QoU3RyaW5nIHMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBSZWFkZXIgaW4gPSBuZXcgU3RyaW5nUmVhZGVyKHMpOworICAgICAgICBFeHBhdFJlYWRlciByZWFkZXIgPSBuZXcgRXhwYXRSZWFkZXIoKTsKKyAgICAgICAgVGVzdER0ZEhhbmRsZXIgaGFuZGxlciA9IG5ldyBUZXN0RHRkSGFuZGxlcigpOworICAgICAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIoaGFuZGxlcik7CisgICAgICAgIHJlYWRlci5zZXREVERIYW5kbGVyKGhhbmRsZXIpOworICAgICAgICByZWFkZXIuc2V0TGV4aWNhbEhhbmRsZXIoaGFuZGxlcik7CisgICAgICAgIHJlYWRlci5wYXJzZShuZXcgSW5wdXRTb3VyY2UoaW4pKTsKKyAgICAgICAgcmV0dXJuIGhhbmRsZXI7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdER0ZERvY3R5cGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdER0ZEhhbmRsZXIgaGFuZGxlciA9IHJ1bkR0ZFRlc3QoIjw/eG1sIHZlcnNpb249XCIxLjBcIj8+PCFET0NUWVBFIGZvbyBQVUJMSUMgJ2JhcicgJ3RlZSc+PGE+PC9hPiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZvbyIsIGhhbmRsZXIubmFtZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYmFyIiwgaGFuZGxlci5wdWJsaWNJZCk7CisgICAgICAgIGFzc2VydEVxdWFscygidGVlIiwgaGFuZGxlci5zeXN0ZW1JZCk7CisgICAgICAgIGFzc2VydFRydWUoaGFuZGxlci5lbmRlZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdER0ZFVucGFyc2VkRW50aXR5X3N5c3RlbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0RHRkSGFuZGxlciBoYW5kbGVyID0gcnVuRHRkVGVzdCgiPD94bWwgdmVyc2lvbj1cIjEuMFwiPz48IURPQ1RZUEUgZm9vIFBVQkxJQyAnYmFyJyAndGVlJyBbIDwhRU5USVRZIGVudCBTWVNURU0gJ2JsYWgnIE5EQVRBIHBvb3A+IF0+PGE+PC9hPiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVudCIsIGhhbmRsZXIudWVOYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGhhbmRsZXIudWVQdWJsaWNJZCk7CisgICAgICAgIGFzc2VydEVxdWFscygiYmxhaCIsIGhhbmRsZXIudWVTeXN0ZW1JZCk7CisgICAgICAgIGFzc2VydEVxdWFscygicG9vcCIsIGhhbmRsZXIudWVOb3RhdGlvbk5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REdGRVbnBhcnNlZEVudGl0eV9wdWJsaWMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdER0ZEhhbmRsZXIgaGFuZGxlciA9IHJ1bkR0ZFRlc3QoIjw/eG1sIHZlcnNpb249XCIxLjBcIj8+PCFET0NUWVBFIGZvbyBQVUJMSUMgJ2JhcicgJ3RlZScgWyA8IUVOVElUWSBlbnQgUFVCTElDICdhJyAnYicgTkRBVEEgcG9vcD4gXT48YT48L2E+Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiZW50IiwgaGFuZGxlci51ZU5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBoYW5kbGVyLnVlUHVibGljSWQpOworICAgICAgICBhc3NlcnRFcXVhbHMoImIiLCBoYW5kbGVyLnVlU3lzdGVtSWQpOworICAgICAgICBhc3NlcnRFcXVhbHMoInBvb3AiLCBoYW5kbGVyLnVlTm90YXRpb25OYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RHRkTm90YXRpb25fc3lzdGVtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3REdGRIYW5kbGVyIGhhbmRsZXIgPSBydW5EdGRUZXN0KCI8P3htbCB2ZXJzaW9uPVwiMS4wXCI/PjwhRE9DVFlQRSBmb28gUFVCTElDICdiYXInICd0ZWUnIFsgPCFOT1RBVElPTiBzbiBTWVNURU0gJ25mMic+IF0+PGE+PC9hPiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInNuIiwgaGFuZGxlci5uZE5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgaGFuZGxlci5uZFB1YmxpY0lkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuZjIiLCBoYW5kbGVyLm5kU3lzdGVtSWQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REdGROb3RhdGlvbl9wdWJsaWMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdER0ZEhhbmRsZXIgaGFuZGxlciA9IHJ1bkR0ZFRlc3QoIjw/eG1sIHZlcnNpb249XCIxLjBcIj8+PCFET0NUWVBFIGZvbyBQVUJMSUMgJ2JhcicgJ3RlZScgWyA8IU5PVEFUSU9OIHBuIFBVQkxJQyAnbmYxJz4gXT48YT48L2E+Iik7CisgICAgICAgIGFzc2VydEVxdWFscygicG4iLCBoYW5kbGVyLm5kTmFtZSk7CisgICAgICAgIGFzc2VydEVxdWFscygibmYxIiwgaGFuZGxlci5uZFB1YmxpY0lkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGhhbmRsZXIubmRTeXN0ZW1JZCk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFRlc3REdGRIYW5kbGVyIGV4dGVuZHMgRGVmYXVsdEhhbmRsZXIyIHsKKworICAgICAgICBTdHJpbmcgbmFtZTsKKyAgICAgICAgU3RyaW5nIHB1YmxpY0lkOworICAgICAgICBTdHJpbmcgc3lzdGVtSWQ7CisgICAgICAgIFN0cmluZyBuZE5hbWU7CisgICAgICAgIFN0cmluZyBuZFB1YmxpY0lkOworICAgICAgICBTdHJpbmcgbmRTeXN0ZW1JZDsKKyAgICAgICAgU3RyaW5nIHVlTmFtZTsKKyAgICAgICAgU3RyaW5nIHVlUHVibGljSWQ7CisgICAgICAgIFN0cmluZyB1ZVN5c3RlbUlkOworICAgICAgICBTdHJpbmcgdWVOb3RhdGlvbk5hbWU7CisKKyAgICAgICAgYm9vbGVhbiBlbmRlZDsKKworICAgICAgICBMb2NhdG9yIGxvY2F0b3I7CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHN0YXJ0RFREKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkgeworICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgICAgICAgIHRoaXMucHVibGljSWQgPSBwdWJsaWNJZDsKKyAgICAgICAgICAgIHRoaXMuc3lzdGVtSWQgPSBzeXN0ZW1JZDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBlbmREVEQoKSB7CisgICAgICAgICAgICBlbmRlZCA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikgeworICAgICAgICAgICAgdGhpcy5sb2NhdG9yID0gbG9jYXRvcjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBub3RhdGlvbkRlY2woU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKSB7CisgICAgICAgICAgICB0aGlzLm5kTmFtZSA9IG5hbWU7CisgICAgICAgICAgICB0aGlzLm5kUHVibGljSWQgPSBwdWJsaWNJZDsKKyAgICAgICAgICAgIHRoaXMubmRTeXN0ZW1JZCA9IHN5c3RlbUlkOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbChTdHJpbmcgZW50aXR5TmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQsIFN0cmluZyBub3RhdGlvbk5hbWUpIHsKKyAgICAgICAgICAgIHRoaXMudWVOYW1lID0gZW50aXR5TmFtZTsKKyAgICAgICAgICAgIHRoaXMudWVQdWJsaWNJZCA9IHB1YmxpY0lkOworICAgICAgICAgICAgdGhpcy51ZVN5c3RlbUlkID0gc3lzdGVtSWQ7CisgICAgICAgICAgICB0aGlzLnVlTm90YXRpb25OYW1lID0gbm90YXRpb25OYW1lOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENkYXRhKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFJlYWRlciBpbiA9IG5ldyBTdHJpbmdSZWFkZXIoCisgICAgICAgICAgICAiPGE+PCFbQ0RBVEFbPGI+PC9iPl1dPiA8IVtDREFUQVs8Yz48L2M+XV0+PC9hPiIpOworCisgICAgICAgIEV4cGF0UmVhZGVyIHJlYWRlciA9IG5ldyBFeHBhdFJlYWRlcigpOworICAgICAgICBUZXN0Q2RhdGFIYW5kbGVyIGhhbmRsZXIgPSBuZXcgVGVzdENkYXRhSGFuZGxlcigpOworICAgICAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIoaGFuZGxlcik7CisgICAgICAgIHJlYWRlci5zZXRMZXhpY2FsSGFuZGxlcihoYW5kbGVyKTsKKworICAgICAgICByZWFkZXIucGFyc2UobmV3IElucHV0U291cmNlKGluKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGhhbmRsZXIuc3RhcnRDZGF0YSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBoYW5kbGVyLmVuZENkYXRhKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI8Yj48L2I+IDxjPjwvYz4iLCBoYW5kbGVyLmJ1ZmZlci50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgVGVzdENkYXRhSGFuZGxlciBleHRlbmRzIERlZmF1bHRIYW5kbGVyMiB7CisKKyAgICAgICAgaW50IHN0YXJ0Q2RhdGEsIGVuZENkYXRhOworICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOworCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGNoLCBzdGFydCwgbGVuZ3RoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdGFydENkYXRhKys7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgZW5kQ0RBVEEoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGVuZENkYXRhKys7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJvY2Vzc2luZ0luc3RydWN0aW9ucygpIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgUmVhZGVyIGluID0gbmV3IFN0cmluZ1JlYWRlcigKKyAgICAgICAgICAgICI8P2JvYiBsZWU/PjxhPjwvYT4iKTsKKworICAgICAgICBFeHBhdFJlYWRlciByZWFkZXIgPSBuZXcgRXhwYXRSZWFkZXIoKTsKKyAgICAgICAgVGVzdFByb2Nlc3NpbmdJbnN0cnV0aW9uSGFuZGxlciBoYW5kbGVyCisgICAgICAgICAgICAgICAgPSBuZXcgVGVzdFByb2Nlc3NpbmdJbnN0cnV0aW9uSGFuZGxlcigpOworICAgICAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIoaGFuZGxlcik7CisKKyAgICAgICAgcmVhZGVyLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShpbikpOworCisgICAgICAgIGFzc2VydEVxdWFscygiYm9iIiwgaGFuZGxlci50YXJnZXQpOworICAgICAgICBhc3NlcnRFcXVhbHMoImxlZSIsIGhhbmRsZXIuZGF0YSk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFRlc3RQcm9jZXNzaW5nSW5zdHJ1dGlvbkhhbmRsZXIgZXh0ZW5kcyBEZWZhdWx0SGFuZGxlcjIgeworCisgICAgICAgIFN0cmluZyB0YXJnZXQ7CisgICAgICAgIFN0cmluZyBkYXRhOworCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpIHsKKyAgICAgICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0OworICAgICAgICAgICAgdGhpcy5kYXRhID0gZGF0YTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFeHRlcm5hbEVudGl0eSgpIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgY2xhc3MgSGFuZGxlciBleHRlbmRzIERlZmF1bHRIYW5kbGVyIHsKKworICAgICAgICAgICAgTGlzdDxTdHJpbmc+IGVsZW1lbnROYW1lcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICAgICAgU3RyaW5nQnVpbGRlciB0ZXh0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKworICAgICAgICAgICAgcHVibGljIElucHV0U291cmNlIHJlc29sdmVFbnRpdHkoU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBpZiAocHVibGljSWQuZXF1YWxzKCJwdWJsaWNBIikgJiYgc3lzdGVtSWQuZXF1YWxzKCJzeXN0ZW1BIikpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBJbnB1dFNvdXJjZShuZXcgU3RyaW5nUmVhZGVyKCI8YS8+IikpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocHVibGljSWQuZXF1YWxzKCJwdWJsaWNCIikKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIHN5c3RlbUlkLmVxdWFscygic3lzdGVtQiIpKSB7CisgICAgICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICAgICAqIEV4cGxpY2l0bHkgc2V0IHRoZSBlbmNvZGluZyBoZXJlIG9yIGVsc2UgdGhlIHBhcnNlciB3aWxsCisgICAgICAgICAgICAgICAgICAgICAqIHRyeSB0byB1c2UgdGhlIHBhcmVudCBwYXJzZXIncyBlbmNvZGluZyB3aGljaCBpcyB1dGYtMTYuCisgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oImJvYiIuZ2V0Qnl0ZXMoInV0Zi04IikpKTsKKyAgICAgICAgICAgICAgICAgICAgaW5wdXRTb3VyY2Uuc2V0RW5jb2RpbmcoInV0Zi04Iik7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dFNvdXJjZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lLAorICAgICAgICAgICAgICAgICAgICBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICAgICAgICAgIGVsZW1lbnROYW1lcy5hZGQobG9jYWxOYW1lKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgZWxlbWVudE5hbWVzLmFkZCgiLyIgKyBsb2NhbE5hbWUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICAgICAgICAgIHRleHQuYXBwZW5kKGNoLCBzdGFydCwgbGVuZ3RoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFJlYWRlciBpbiA9IG5ldyBTdHJpbmdSZWFkZXIoIjw/eG1sIHZlcnNpb249XCIxLjBcIj8+XG4iCisgICAgICAgICAgICArICI8IURPQ1RZUEUgZm9vIFtcbiIKKyAgICAgICAgICAgICsgIiAgPCFFTlRJVFkgYSBQVUJMSUMgJ3B1YmxpY0EnICdzeXN0ZW1BJz5cbiIKKyAgICAgICAgICAgICsgIiAgPCFFTlRJVFkgYiBQVUJMSUMgJ3B1YmxpY0InICdzeXN0ZW1CJz5cbiIKKyAgICAgICAgICAgICsgIl0+XG4iCisgICAgICAgICAgICArICI8Zm9vPlxuIgorICAgICAgICAgICAgKyAiICAmYTs8Yj4mYjs8L2I+PC9mb28+Iik7CisKKyAgICAgICAgRXhwYXRSZWFkZXIgcmVhZGVyID0gbmV3IEV4cGF0UmVhZGVyKCk7CisgICAgICAgIEhhbmRsZXIgaGFuZGxlciA9IG5ldyBIYW5kbGVyKCk7CisgICAgICAgIHJlYWRlci5zZXRDb250ZW50SGFuZGxlcihoYW5kbGVyKTsKKyAgICAgICAgcmVhZGVyLnNldEVudGl0eVJlc29sdmVyKGhhbmRsZXIpOworCisgICAgICAgIHJlYWRlci5wYXJzZShuZXcgSW5wdXRTb3VyY2UoaW4pKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdCgiZm9vIiwgImEiLCAiL2EiLCAiYiIsICIvYiIsICIvZm9vIiksCisgICAgICAgICAgICAgICAgaGFuZGxlci5lbGVtZW50TmFtZXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJvYiIsIGhhbmRsZXIudGV4dC50b1N0cmluZygpLnRyaW0oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEV4dGVybmFsRW50aXR5RG93bmxvYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIE1vY2tXZWJTZXJ2ZXIgc2VydmVyID0gbmV3IE1vY2tXZWJTZXJ2ZXIoKTsKKyAgICAgICAgc2VydmVyLmVucXVldWUobmV3IE1vY2tSZXNwb25zZSgpLnNldEJvZHkoIjxiYXI+PC9iYXI+IikpOworICAgICAgICBzZXJ2ZXIucGxheSgpOworCisgICAgICAgIGNsYXNzIEhhbmRsZXIgZXh0ZW5kcyBEZWZhdWx0SGFuZGxlciB7CisgICAgICAgICAgICBmaW5hbCBMaXN0PFN0cmluZz4gZWxlbWVudE5hbWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eShTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAvLyBUaGUgcGFyc2VyIHNob3VsZCBoYXZlIHJlc29sdmVkIHRoZSBzeXN0ZW1JZC4KKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoc2VydmVyLmdldFVybCgiL3N5c3RlbUJhciIpLnRvU3RyaW5nKCksIHN5c3RlbUlkKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IElucHV0U291cmNlKHN5c3RlbUlkKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUsCisgICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZXMgYXR0cmlidXRlcykgeworICAgICAgICAgICAgICAgIGVsZW1lbnROYW1lcy5hZGQobG9jYWxOYW1lKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lKSB7CisgICAgICAgICAgICAgICAgZWxlbWVudE5hbWVzLmFkZCgiLyIgKyBsb2NhbE5hbWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gJ3N5c3RlbUJhcicsIHRoZSBleHRlcm5hbCBlbnRpdHksIGlzIHJlbGF0aXZlIHRvICdzeXN0ZW1Gb28nOgorICAgICAgICBSZWFkZXIgaW4gPSBuZXcgU3RyaW5nUmVhZGVyKCI8P3htbCB2ZXJzaW9uPVwiMS4wXCI/PlxuIgorICAgICAgICAgICAgKyAiPCFET0NUWVBFIGZvbyBbXG4iCisgICAgICAgICAgICArICIgIDwhRU5USVRZIGJhciBTWVNURU0gJ3N5c3RlbUJhcic+XG4iCisgICAgICAgICAgICArICJdPlxuIgorICAgICAgICAgICAgKyAiPGZvbz4mYmFyOzwvZm9vPiIpOworICAgICAgICBFeHBhdFJlYWRlciByZWFkZXIgPSBuZXcgRXhwYXRSZWFkZXIoKTsKKyAgICAgICAgSGFuZGxlciBoYW5kbGVyID0gbmV3IEhhbmRsZXIoKTsKKyAgICAgICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKGhhbmRsZXIpOworICAgICAgICByZWFkZXIuc2V0RW50aXR5UmVzb2x2ZXIoaGFuZGxlcik7CisgICAgICAgIElucHV0U291cmNlIHNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZShpbik7CisgICAgICAgIHNvdXJjZS5zZXRTeXN0ZW1JZChzZXJ2ZXIuZ2V0VXJsKCIvc3lzdGVtRm9vIikudG9TdHJpbmcoKSk7CisgICAgICAgIHJlYWRlci5wYXJzZShzb3VyY2UpOworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmFzTGlzdCgiZm9vIiwgImJhciIsICIvYmFyIiwgIi9mb28iKSwgaGFuZGxlci5lbGVtZW50TmFtZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgZ2l2ZW4geG1sIHN0cmluZyBhbmQgZmlyZXMgZXZlbnRzIG9uIHRoZSBnaXZlbiBTQVggaGFuZGxlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHBhcnNlKFN0cmluZyB4bWwsIENvbnRlbnRIYW5kbGVyIGNvbnRlbnRIYW5kbGVyKQorICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBYTUxSZWFkZXIgcmVhZGVyID0gbmV3IEV4cGF0UmVhZGVyKCk7CisgICAgICAgICAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIoY29udGVudEhhbmRsZXIpOworICAgICAgICAgICAgcmVhZGVyLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShuZXcgU3RyaW5nUmVhZGVyKHhtbCkpKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHhtbCBmcm9tIHRoZSBnaXZlbiByZWFkZXIgYW5kIGZpcmVzIGV2ZW50cyBvbiB0aGUgZ2l2ZW4gU0FYCisgICAgICogaGFuZGxlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHBhcnNlKFJlYWRlciBpbiwgQ29udGVudEhhbmRsZXIgY29udGVudEhhbmRsZXIpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIFhNTFJlYWRlciByZWFkZXIgPSBuZXcgRXhwYXRSZWFkZXIoKTsKKyAgICAgICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKGNvbnRlbnRIYW5kbGVyKTsKKyAgICAgICAgcmVhZGVyLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShpbikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB4bWwgZnJvbSB0aGUgZ2l2ZW4gaW5wdXQgc3RyZWFtIGFuZCBmaXJlcyBldmVudHMgb24gdGhlIGdpdmVuIFNBWAorICAgICAqIGhhbmRsZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwYXJzZShJbnB1dFN0cmVhbSBpbiwgRW5jb2RpbmcgZW5jb2RpbmcsCisgICAgICAgICAgICBDb250ZW50SGFuZGxlciBjb250ZW50SGFuZGxlcikgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgWE1MUmVhZGVyIHJlYWRlciA9IG5ldyBFeHBhdFJlYWRlcigpOworICAgICAgICAgICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKGNvbnRlbnRIYW5kbGVyKTsKKyAgICAgICAgICAgIElucHV0U291cmNlIHNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZShpbik7CisgICAgICAgICAgICBzb3VyY2Uuc2V0RW5jb2RpbmcoZW5jb2RpbmcuZXhwYXROYW1lKTsKKyAgICAgICAgICAgIHJlYWRlci5wYXJzZShzb3VyY2UpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdXBwb3J0ZWQgY2hhcmFjdGVyIGVuY29kaW5ncy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGVudW0gRW5jb2RpbmcgeworCisgICAgICAgIFVTX0FTQ0lJKCJVUy1BU0NJSSIpLAorICAgICAgICBVVEZfOCgiVVRGLTgiKSwKKyAgICAgICAgVVRGXzE2KCJVVEYtMTYiKSwKKyAgICAgICAgSVNPXzg4NTlfMSgiSVNPLTg4NTktMSIpOworCisgICAgICAgIGZpbmFsIFN0cmluZyBleHBhdE5hbWU7CisKKyAgICAgICAgRW5jb2RpbmcoU3RyaW5nIGV4cGF0TmFtZSkgeworICAgICAgICAgICAgdGhpcy5leHBhdE5hbWUgPSBleHBhdE5hbWU7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS94bWwvSmF4ZW5YUGF0aFRlc3RTdWl0ZS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL0pheGVuWFBhdGhUZXN0U3VpdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYjc5MGFhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL0pheGVuWFBhdGhUZXN0U3VpdGUuamF2YQpAQCAtMCwwICsxLDMwNiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS54bWw7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0aW9uRmFpbGVkRXJyb3I7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKKworaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWU7CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LnhtbC54cGF0aC5YUGF0aDsKK2ltcG9ydCBqYXZheC54bWwueHBhdGguWFBhdGhDb25zdGFudHM7CitpbXBvcnQgamF2YXgueG1sLnhwYXRoLlhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC54bWwueHBhdGguWFBhdGhGYWN0b3J5OworaW1wb3J0IGphdmF4LnhtbC54cGF0aC5YUGF0aFZhcmlhYmxlUmVzb2x2ZXI7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBUaGUgaW1wbGVtZW50YXRpb24taW5kZXBlbmRlbnQgcGFydCBvZiB0aGUgPGEKKyAqIGhyZWY9Imh0dHA6Ly9qYXhlbi5jb2RlaGF1cy5vcmcvIj5KYXhlbjwvYT4gWFBhdGggdGVzdCBzdWl0ZSwgYWRhcHRlZCBmb3IgdXNlCisgKiBieSBKVW5pdC4gVG8gcnVuIHRoZXNlIHRlc3RzIG9uIGEgZGV2aWNlOgorICogPHVsPgorICogICA8bGk+T2J0YWluIHRoZSBKYXhlbiBzb3VyY2UgZnJvbSB0aGUgcHJvamVjdCdzIHdlYnNpdGUuCisgKiAgIDxsaT5Db3B5IHRoZSBmaWxlcyB0byBhIGRldmljZTogPGNvZGU+YWRiIHNoZWxsIG1rZGlyIC9kYXRhL2pheGVuIDsKKyAqICAgICAgIGFkYiBwdXNoIC9ob21lL2RhbHZpay1wcmVidWlsZC9qYXhlbiAvZGF0YS9qYXhlbjwvY29kZT4KKyAqICAgPGxpPkludm9rZSB0aGlzIGNsYXNzJyBtYWluIG1ldGhvZCwgcGFzc2luZyB0aGUgb24tZGV2aWNlIHBhdGggdG8gdGhlIHRlc3QKKyAqICAgICAgIHN1aXRlJ3Mgcm9vdCBkaXJlY3RvcnkgYXMgYW4gYXJndW1lbnQuCisgKiA8L3VsPgorICovCitwdWJsaWMgY2xhc3MgSmF4ZW5YUGF0aFRlc3RTdWl0ZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9KQVhFTl9IT01FID0gIi9ob21lL2RhbHZpay1wcmVidWlsZC9qYXhlbiI7CisKKyAgICBwdWJsaWMgc3RhdGljIFRlc3Qgc3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGpheGVuSG9tZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF4ZW4uaG9tZSIsIERFRkFVTFRfSkFYRU5fSE9NRSk7CisgICAgICAgIHJldHVybiBzdWl0ZShuZXcgRmlsZShqYXhlbkhvbWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgdGVzdCBzdWl0ZSBmcm9tIHRoZSBKYXhlbiB0ZXN0cy54bWwgY2F0YWxvZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFRlc3Qgc3VpdGUoRmlsZSBqYXhlbkhvbWUpCisgICAgICAgICAgICB0aHJvd3MgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiB7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVGhlIHRlc3RzLnhtbCBkb2N1bWVudCBoYXMgdGhpcyBzdHJ1Y3R1cmU6CisgICAgICAgICAqCisgICAgICAgICAqIDx0ZXN0cz4KKyAgICAgICAgICogICA8ZG9jdW1lbnQgdXJsPSIuLi4iPgorICAgICAgICAgKiAgICAgPGNvbnRleHQgLi4uLz4KKyAgICAgICAgICogICAgIDxjb250ZXh0IC4uLi8+CisgICAgICAgICAqICAgICA8Y29udGV4dCAuLi4vPgorICAgICAgICAgKiAgIDwvZG9jdW1lbnQ+CisgICAgICAgICAqICAgPGRvY3VtZW50IHVybD0iLi4uIj4KKyAgICAgICAgICogICAgIDxjb250ZXh0IC4uLi8+CisgICAgICAgICAqICAgPC9kb2N1bWVudD4KKyAgICAgICAgICogPC90ZXN0cz4KKyAgICAgICAgICovCisKKyAgICAgICAgRmlsZSB0ZXN0c1htbCA9IG5ldyBGaWxlKGpheGVuSG9tZSArICIveG1sL3Rlc3QvdGVzdHMueG1sIik7CisgICAgICAgIEVsZW1lbnQgdGVzdHMgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCkKKyAgICAgICAgICAgICAgICAubmV3RG9jdW1lbnRCdWlsZGVyKCkucGFyc2UodGVzdHNYbWwpLmdldERvY3VtZW50RWxlbWVudCgpOworCisgICAgICAgIFRlc3RTdWl0ZSByZXN1bHQgPSBuZXcgVGVzdFN1aXRlKCk7CisgICAgICAgIGZvciAoRWxlbWVudCBkb2N1bWVudCA6IGVsZW1lbnRzT2YodGVzdHMuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImRvY3VtZW50IikpKSB7CisgICAgICAgICAgICBTdHJpbmcgdXJsID0gZG9jdW1lbnQuZ2V0QXR0cmlidXRlKCJ1cmwiKTsKKyAgICAgICAgICAgIElucHV0U291cmNlIGlucHV0U291cmNlID0gbmV3IElucHV0U291cmNlKCJmaWxlOiIgKyBqYXhlbkhvbWUgKyAiLyIgKyB1cmwpOworICAgICAgICAgICAgZm9yIChmaW5hbCBFbGVtZW50IGNvbnRleHQgOiBlbGVtZW50c09mKGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJjb250ZXh0IikpKSB7CisgICAgICAgICAgICAgICAgY29udGV4dFRvVGVzdFN1aXRlKHJlc3VsdCwgdXJsLCBpbnB1dFNvdXJjZSwgY29udGV4dCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFBvcHVsYXRlcyB0aGUgdGVzdCBzdWl0ZSB3aXRoIHRlc3RzIGZyb20gdGhlIGdpdmVuIFhNTCBjb250ZXh0IGVsZW1lbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjb250ZXh0VG9UZXN0U3VpdGUoVGVzdFN1aXRlIHN1aXRlLCBTdHJpbmcgdXJsLAorICAgICAgICAgICAgSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UsIEVsZW1lbnQgZWxlbWVudCkgeworCisgICAgICAgIC8qCisgICAgICAgICAqIEVhY2ggY29udGV4dCBlbGVtZW50IGhhcyB0aGlzIHN0cnVjdHVyZToKKyAgICAgICAgICoKKyAgICAgICAgICogPGNvbnRleHQgc2VsZWN0PSIuLi4iPgorICAgICAgICAgKiAgIDx0ZXN0IC4uLi8+CisgICAgICAgICAqICAgPHRlc3QgLi4uLz4KKyAgICAgICAgICogICA8dGVzdCAuLi4vPgorICAgICAgICAgKiAgIDx2YWx1ZU9mIC4uLi8+CisgICAgICAgICAqICAgPHZhbHVlT2YgLi4uLz4KKyAgICAgICAgICogICA8dmFsdWVPZiAuLi4vPgorICAgICAgICAgKiA8L2NvbnRleHQ+CisgICAgICAgICAqLworCisgICAgICAgIFN0cmluZyBzZWxlY3QgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgic2VsZWN0Iik7CisgICAgICAgIENvbnRleHQgY29udGV4dCA9IG5ldyBDb250ZXh0KGlucHV0U291cmNlLCB1cmwsIHNlbGVjdCk7CisKKyAgICAgICAgWFBhdGggeHBhdGggPSBYUGF0aEZhY3RvcnkubmV3SW5zdGFuY2UoKS5uZXdYUGF0aCgpOworICAgICAgICB4cGF0aC5zZXRYUGF0aFZhcmlhYmxlUmVzb2x2ZXIobmV3IEVsZW1lbnRWYXJpYWJsZVJlc29sdmVyKGVsZW1lbnQpKTsKKworICAgICAgICBmb3IgKEVsZW1lbnQgdGVzdCA6IGVsZW1lbnRzT2YoZWxlbWVudC5nZXRDaGlsZE5vZGVzKCkpKSB7CisgICAgICAgICAgICBpZiAodGVzdC5nZXRUYWdOYW1lKCkuZXF1YWxzKCJ0ZXN0IikpIHsKKyAgICAgICAgICAgICAgICBzdWl0ZS5hZGRUZXN0KGNyZWF0ZUZyb21UZXN0KHhwYXRoLCBjb250ZXh0LCB0ZXN0KSk7CisKKyAgICAgICAgICAgIH0gZWxzZSBpZiAodGVzdC5nZXRUYWdOYW1lKCkuZXF1YWxzKCJ2YWx1ZU9mIikpIHsKKyAgICAgICAgICAgICAgICBzdWl0ZS5hZGRUZXN0KGNyZWF0ZUZyb21WYWx1ZU9mKHhwYXRoLCBjb250ZXh0LCB0ZXN0KSk7CisKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJVbnN1cHBvcnRlZCB0ZXN0OiAiICsgY29udGV4dCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0ZXN0IGRlc2NyaWJlZCBieSB0aGUgZ2l2ZW4ge0Bjb2RlIDx0ZXN0Pn0gZWxlbWVudC4gU3VjaAorICAgICAqIHRlc3RzIGNvbWUgaW4gb25lIG9mIHRocmVlIHZhcmlldGllczoKKyAgICAgKgorICAgICAqIDx1bD4KKyAgICAgKiAgIDxsaT5FeHBlY3RlZCBmYWlsdXJlcy4KKyAgICAgKiAgIDxsaT5TdHJpbmcgbWF0Y2hlcy4gVGhlc2UgdGVzdHMgaGF2ZSBhIG5lc3RlZCB7QGNvZGUgPHZhbHVlT2Y+fSBlbGVtZW50CisgICAgICogICAgICAgdGhhdCBzdWItc2VsZWN0cyBhbiBleHBlY3RlZCB0ZXh0LgorICAgICAqICAgPGxpPkNvdW50IG1hdGNoZXMuIFRoZXNlIHRlc3RzIHNwZWNpZnkgaG93IG1hbnkgbm9kZXMgYXJlIGV4cGVjdGVkIHRvCisgICAgICogICAgICAgbWF0Y2guCisgICAgICogPC91bD4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBUZXN0Q2FzZSBjcmVhdGVGcm9tVGVzdCgKKyAgICAgICAgICAgIGZpbmFsIFhQYXRoIHhwYXRoLCBmaW5hbCBDb250ZXh0IGNvbnRleHQsIGZpbmFsIEVsZW1lbnQgZWxlbWVudCkgeworICAgICAgICBmaW5hbCBTdHJpbmcgc2VsZWN0ID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoInNlbGVjdCIpOworCisgICAgICAgIC8qIFN1Y2ggYXMgPHRlc3QgZXhjZXB0aW9uPSJ0cnVlIiBzZWxlY3Q9Ii4uLiIgY291bnQ9IjAiLz4gKi8KKyAgICAgICAgaWYgKGVsZW1lbnQuZ2V0QXR0cmlidXRlKCJleGNlcHRpb24iKS5lcXVhbHMoInRydWUiKSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBYUGF0aFRlc3QoY29udGV4dCwgc2VsZWN0KSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlIHZvaWQgdGVzdChOb2RlIGNvbnRleHROb2RlKSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICB4cGF0aC5ldmFsdWF0ZShzZWxlY3QsIGNvbnRleHROb2RlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIGV4Y2VwdGlvbiEiKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9OworICAgICAgICB9CisKKyAgICAgICAgLyogYSA8dGVzdD4gd2l0aCBhIG5lc3RlZCA8dmFsdWVPZj4sIGJvdGggb2Ygd2hpY2ggaGF2ZSBzZWxlY3QgYXR0cmlidXRlcyAqLworICAgICAgICBOb2RlTGlzdCB2YWx1ZU9mRWxlbWVudHMgPSBlbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJ2YWx1ZU9mIik7CisgICAgICAgIGlmICh2YWx1ZU9mRWxlbWVudHMuZ2V0TGVuZ3RoKCkgPT0gMSkgeworICAgICAgICAgICAgZmluYWwgRWxlbWVudCB2YWx1ZU9mID0gKEVsZW1lbnQpIHZhbHVlT2ZFbGVtZW50cy5pdGVtKDApOworICAgICAgICAgICAgZmluYWwgU3RyaW5nIHZhbHVlT2ZTZWxlY3QgPSB2YWx1ZU9mLmdldEF0dHJpYnV0ZSgic2VsZWN0Iik7CisKKyAgICAgICAgICAgIHJldHVybiBuZXcgWFBhdGhUZXN0KGNvbnRleHQsIHNlbGVjdCkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZSB2b2lkIHRlc3QoTm9kZSBjb250ZXh0Tm9kZSkgdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgICAgIE5vZGUgbmV3Q29udGV4dCA9IChOb2RlKSB4cGF0aC5ldmFsdWF0ZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QsIGNvbnRleHROb2RlLCBYUGF0aENvbnN0YW50cy5OT0RFKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHZhbHVlT2YuZ2V0VGV4dENvbnRlbnQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB4cGF0aC5ldmFsdWF0ZSh2YWx1ZU9mU2VsZWN0LCBuZXdDb250ZXh0LCBYUGF0aENvbnN0YW50cy5TVFJJTkcpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9OworICAgICAgICB9CisKKyAgICAgICAgLyogU3VjaCBhcyA8dGVzdCBzZWxlY3Q9Ii4uLiIgY291bnQ9IjUiLz4gKi8KKyAgICAgICAgZmluYWwgU3RyaW5nIGNvdW50ID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoImNvdW50Iik7CisgICAgICAgIGlmIChjb3VudC5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgWFBhdGhUZXN0KGNvbnRleHQsIHNlbGVjdCkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZSB2b2lkIHRlc3QoTm9kZSBjb250ZXh0Tm9kZSkgdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgICAgIE5vZGVMaXN0IHJlc3VsdCA9IChOb2RlTGlzdCkgeHBhdGguZXZhbHVhdGUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0LCBjb250ZXh0Tm9kZSwgWFBhdGhDb25zdGFudHMuTk9ERVNFVCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLnBhcnNlSW50KGNvdW50KSwgcmVzdWx0LmdldExlbmd0aCgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9OworICAgICAgICB9CisKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJVbnN1cHBvcnRlZCB0ZXN0OiAiICsgY29udGV4dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGVzdCBkZXNjcmliZWQgYnkgdGhlIGdpdmVuIHtAY29kZSA8dmFsdWVPZj59IGVsZW1lbnQuIFRoZXNlCisgICAgICogdGVzdHMgc2VsZWN0IGFuIGV4cGVjdGVkIHRleHQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgVGVzdENhc2UgY3JlYXRlRnJvbVZhbHVlT2YoCisgICAgICAgICAgICBmaW5hbCBYUGF0aCB4cGF0aCwgZmluYWwgQ29udGV4dCBjb250ZXh0LCBmaW5hbCBFbGVtZW50IGVsZW1lbnQpIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIHNlbGVjdCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCJzZWxlY3QiKTsKKyAgICAgICAgcmV0dXJuIG5ldyBYUGF0aFRlc3QoY29udGV4dCwgc2VsZWN0KSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgdm9pZCB0ZXN0KE5vZGUgY29udGV4dE5vZGUpIHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24geworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhlbGVtZW50LmdldFRleHRDb250ZW50KCksCisgICAgICAgICAgICAgICAgICAgICAgICB4cGF0aC5ldmFsdWF0ZShzZWxlY3QsIGNvbnRleHROb2RlLCBYUGF0aENvbnN0YW50cy5TVFJJTkcpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3ViamVjdCBvZiBhbiBYUGF0aCBxdWVyeS4gVGhpcyBpcyBpdHNlbGYgZGVmaW5lZCBieSBhbiBYUGF0aCBxdWVyeSwKKyAgICAgKiBzbyBlYWNoIHRlc3QgcmVxdWlyZXMgYXQgbGVhc3QgWFBhdGggZXhwcmVzc2lvbnMgdG8gYmUgZXZhbHVhdGVkLgorICAgICAqLworICAgIHN0YXRpYyBjbGFzcyBDb250ZXh0IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZTsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgdXJsOworICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBzZWxlY3Q7CisKKyAgICAgICAgQ29udGV4dChJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSwgU3RyaW5nIHVybCwgU3RyaW5nIHNlbGVjdCkgeworICAgICAgICAgICAgdGhpcy5pbnB1dFNvdXJjZSA9IGlucHV0U291cmNlOworICAgICAgICAgICAgdGhpcy51cmwgPSB1cmw7CisgICAgICAgICAgICB0aGlzLnNlbGVjdCA9IHNlbGVjdDsKKyAgICAgICAgfQorCisgICAgICAgIE5vZGUgZ2V0Tm9kZSgpIHsKKyAgICAgICAgICAgIFhQYXRoIHhwYXRoID0gWFBhdGhGYWN0b3J5Lm5ld0luc3RhbmNlKCkubmV3WFBhdGgoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChOb2RlKSB4cGF0aC5ldmFsdWF0ZShzZWxlY3QsIGlucHV0U291cmNlLCBYUGF0aENvbnN0YW50cy5OT0RFKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgRXJyb3IgZXJyb3IgPSBuZXcgQXNzZXJ0aW9uRmFpbGVkRXJyb3IoIkZhaWxlZCB0byBnZXQgY29udGV4dCIpOworICAgICAgICAgICAgICAgIGVycm9yLmluaXRDYXVzZShlKTsKKyAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuIHVybCArICIgIiArIHNlbGVjdDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgdGVzdCBldmFsdWF0ZXMgYW4gWFBhdGggZXhwcmVzc2lvbiBhZ2FpbnN0IGEgY29udGV4dCBub2RlIGFuZAorICAgICAqIGNvbXBhcmVzIHRoZSByZXN1bHQgdG8gYSBrbm93biBleHBlY3RhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIFhQYXRoVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBDb250ZXh0IGNvbnRleHQ7CisgICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHNlbGVjdDsKKworICAgICAgICBwdWJsaWMgWFBhdGhUZXN0KENvbnRleHQgY29udGV4dCwgU3RyaW5nIHNlbGVjdCkgeworICAgICAgICAgICAgc3VwZXIoInRlc3QiKTsKKyAgICAgICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CisgICAgICAgICAgICB0aGlzLnNlbGVjdCA9IHNlbGVjdDsKKyAgICAgICAgfQorCisgICAgICAgIGFic3RyYWN0IHZvaWQgdGVzdChOb2RlIGNvbnRleHROb2RlKSB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uOworCisgICAgICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3QoKSB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdGVzdChjb250ZXh0LmdldE5vZGUoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGlmIChpc01pc3NpbmdGdW5jdGlvbihlKSkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKGUuZ2V0Q2F1c2UoKS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzTWlzc2luZ0Z1bmN0aW9uKFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gZS5nZXRDYXVzZSgpICE9IG51bGwKKyAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRDYXVzZSgpLmdldE1lc3NhZ2UoKS5zdGFydHNXaXRoKCJDb3VsZCBub3QgZmluZCBmdW5jdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBjb250ZXh0ICsgIiAiICsgc2VsZWN0OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgWFBhdGggdmFyaWFibGUgcmVzb2x1dGlvbiBieSB1c2luZyB7QGNvZGUgdmFyOm5hbWU9InZhbHVlIn0KKyAgICAgKiBhdHRyaWJ1dGVzIGZyb20gdGhlIGdpdmVuIGVsZW1lbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgRWxlbWVudFZhcmlhYmxlUmVzb2x2ZXIgaW1wbGVtZW50cyBYUGF0aFZhcmlhYmxlUmVzb2x2ZXIgeworICAgICAgICBwcml2YXRlIGZpbmFsIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgcHVibGljIEVsZW1lbnRWYXJpYWJsZVJlc29sdmVyKEVsZW1lbnQgZWxlbWVudCkgeworICAgICAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgT2JqZWN0IHJlc29sdmVWYXJpYWJsZShRTmFtZSB2YXJpYWJsZU5hbWUpIHsKKyAgICAgICAgICAgIHJldHVybiBlbGVtZW50LmdldEF0dHJpYnV0ZSgidmFyOiIgKyB2YXJpYWJsZU5hbWUuZ2V0TG9jYWxQYXJ0KCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgTGlzdDxFbGVtZW50PiBlbGVtZW50c09mKE5vZGVMaXN0IG5vZGVMaXN0KSB7CisgICAgICAgIExpc3Q8RWxlbWVudD4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxFbGVtZW50PigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5vZGVMaXN0LmdldExlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgICAgIE5vZGUgbm9kZSA9IG5vZGVMaXN0Lml0ZW0oaSk7CisgICAgICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIEVsZW1lbnQpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYWRkKChFbGVtZW50KSBub2RlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3htbC9LeG1sUHVsbFBhcnNlckR0ZFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3htbC9LeG1sUHVsbFBhcnNlckR0ZFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMTc1YjM3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL0t4bWxQdWxsUGFyc2VyRHRkVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUueG1sOworCitpbXBvcnQgb3JnLmt4bWwyLmlvLktYbWxQYXJzZXI7CitpbXBvcnQgb3JnLnhtbHB1bGwudjEuWG1sUHVsbFBhcnNlcjsKK2ltcG9ydCBvcmcueG1scHVsbC52MS5YbWxQdWxsUGFyc2VyRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgS3htbFB1bGxQYXJzZXJEdGRUZXN0IGV4dGVuZHMgUHVsbFBhcnNlckR0ZFRlc3QgeworICAgIEBPdmVycmlkZSBYbWxQdWxsUGFyc2VyIG5ld1B1bGxQYXJzZXIoKSB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiB7CisgICAgICAgIEtYbWxQYXJzZXIgcmVzdWx0ID0gbmV3IEtYbWxQYXJzZXIoKTsKKyAgICAgICAgcmVzdWx0LnNldEZlYXR1cmUoWG1sUHVsbFBhcnNlci5GRUFUVVJFX1BST0NFU1NfRE9DREVDTCwgdHJ1ZSk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL0t4bWxQdWxsUGFyc2VyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL0t4bWxQdWxsUGFyc2VyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcxZjI1ZTkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS94bWwvS3htbFB1bGxQYXJzZXJUZXN0LmphdmEKQEAgLTAsMCArMSwyNyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS54bWw7CisKK2ltcG9ydCBvcmcua3htbDIuaW8uS1htbFBhcnNlcjsKK2ltcG9ydCBvcmcueG1scHVsbC52MS5YbWxQdWxsUGFyc2VyOworCitwdWJsaWMgY2xhc3MgS3htbFB1bGxQYXJzZXJUZXN0IGV4dGVuZHMgUHVsbFBhcnNlclRlc3QgeworCisgICAgQE92ZXJyaWRlIFhtbFB1bGxQYXJzZXIgbmV3UHVsbFBhcnNlcigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBLWG1sUGFyc2VyKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL05hbWVzcGFjZWRBdHRyaWJ1dGVzTG9va3VwVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL05hbWVzcGFjZWRBdHRyaWJ1dGVzTG9va3VwVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNmMTIwMDAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS94bWwvTmFtZXNwYWNlZEF0dHJpYnV0ZXNMb29rdXBUZXN0LmphdmEKQEAgLTAsMCArMSwxMzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUueG1sOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7CitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CitpbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOworaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuRGVmYXVsdEhhbmRsZXI7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5OworaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBUZXN0cyB0aGF0IHdlIGJvdGggcmVwb3J0IGFuZCByZXRyaWV2ZSBhdHRyaWJ1dGVzIHVzaW5nIHRoZSBhcHByb3ByaWF0ZQorICogbmFtZXMgZm9yIGRpZmZlcmVudCBjb21iaW5hdGlvbnMgb2YgbmFtZXNwYWNlcyBhbmQgbmFtZXNwYWNlIHByZWZpeGVzLgorICovCitwdWJsaWMgY2xhc3MgTmFtZXNwYWNlZEF0dHJpYnV0ZXNMb29rdXBUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNBWF9QUk9QRVJUWV9OUyA9CisgICAgICAgICAgICAiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXMiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTQVhfUFJPUEVSVFlfTlNfUFJFRklYRVMgPQorICAgICAgICAgICAgImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2UtcHJlZml4ZXMiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHhtbCA9ICI8P3htbCB2ZXJzaW9uPScxLjAnIGVuY29kaW5nPSdVVEYtOCc/PiIgKworICAgICAgICAgICAgIjx0ZXN0IHhtbG5zPSdodHRwOi8vZm9vJyB4bWxuczpiYXI9J2h0dHA6Ly9iYXInIHhtbG5zOmJhej0naHR0cDovL2JheicgYmF6OmM9J2EnPiIgKworICAgICAgICAgICAgIjxiIGM9J3cnIGJhcjpjPSd4Jy8+IiArCisgICAgICAgICAgICAiPGJhcjplIGJhejpjPSd5JyBiYXI6Yz0neicvPiIgKworICAgICAgICAgICAgIjwvdGVzdD4iOworCisgICAgcHVibGljIHZvaWQgdGVzdE5hbWVzcGFjZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBMaXN0PFN0cmluZz4gZXhwZWN0ZWQgPSBBcnJheXMuYXNMaXN0KAorICAgICAgICAgICAgICAgICJodHRwOi8vZm9vLHRlc3RcbiIgKworICAgICAgICAgICAgICAgICIgIGh0dHA6Ly9iYXosY1xuIiArCisgICAgICAgICAgICAgICAgIiAgaHR0cDovL2JhcitjPW51bGwsXG4iICsKKyAgICAgICAgICAgICAgICAiICBiYXI6Yz1udWxsXG4iLAorCisgICAgICAgICAgICAgICAgImh0dHA6Ly9mb28sYlxuIiArCisgICAgICAgICAgICAgICAgIiAgLGNcbiIgKworICAgICAgICAgICAgICAgICIgIGh0dHA6Ly9iYXIsY1xuIiArCisgICAgICAgICAgICAgICAgIiAgaHR0cDovL2JhcitjPXgsXG4iICsKKyAgICAgICAgICAgICAgICAiICBiYXI6Yz14XG4iLAorCisgICAgICAgICAgICAgICAgImh0dHA6Ly9iYXIsZVxuIiArCisgICAgICAgICAgICAgICAgIiAgaHR0cDovL2JheixjXG4iICsKKyAgICAgICAgICAgICAgICAiICBodHRwOi8vYmFyLGNcbiIgKworICAgICAgICAgICAgICAgICIgIGh0dHA6Ly9iYXIrYz16LFxuIiArCisgICAgICAgICAgICAgICAgIiAgYmFyOmM9elxuIik7CisKKyAgICAgICAgYm9vbGVhbiBuYW1lc3BhY2UgPSB0cnVlOworICAgICAgICBib29sZWFuIG5hbWVzcGFjZVByZWZpeGVzID0gZmFsc2U7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwgZ2V0U3RhcnRFbGVtZW50cyh4bWwsIG5hbWVzcGFjZSwgbmFtZXNwYWNlUHJlZml4ZXMpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmFtZXNwYWNlUHJlZml4ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGV4cGVjdGVkID0gQXJyYXlzLmFzTGlzdCgKKyAgICAgICAgICAgICAgICAidGVzdFxuIiArCisgICAgICAgICAgICAgICAgIiAgeG1sbnNcbiIgKworICAgICAgICAgICAgICAgICIgIHhtbG5zOmJhclxuIiArCisgICAgICAgICAgICAgICAgIiAgeG1sbnM6YmF6XG4iICsKKyAgICAgICAgICAgICAgICAiICBiYXo6Y1xuIiArCisgICAgICAgICAgICAgICAgIiAgaHR0cDovL2JhcitjPW51bGwsXG4iICsKKyAgICAgICAgICAgICAgICAiICBiYXI6Yz1udWxsXG4iLAorCisgICAgICAgICAgICAgICAgImJcbiIgKworICAgICAgICAgICAgICAgICIgIGNcbiIgKworICAgICAgICAgICAgICAgICIgIGJhcjpjXG4iICsKKyAgICAgICAgICAgICAgICAiICBodHRwOi8vYmFyK2M9bnVsbCxcbiIgKworICAgICAgICAgICAgICAgICIgIGJhcjpjPXhcbiIsCisKKyAgICAgICAgICAgICAgICAiYmFyOmVcbiIgKworICAgICAgICAgICAgICAgICIgIGJhejpjXG4iICsKKyAgICAgICAgICAgICAgICAiICBiYXI6Y1xuIiArCisgICAgICAgICAgICAgICAgIiAgaHR0cDovL2JhcitjPW51bGwsXG4iICsKKyAgICAgICAgICAgICAgICAiICBiYXI6Yz16XG4iKTsKKworICAgICAgICBib29sZWFuIG5hbWVzcGFjZSA9IGZhbHNlOworICAgICAgICBib29sZWFuIG5hbWVzcGFjZVByZWZpeGVzID0gdHJ1ZTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBnZXRTdGFydEVsZW1lbnRzKHhtbCwgbmFtZXNwYWNlLCBuYW1lc3BhY2VQcmVmaXhlcykpOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PFN0cmluZz4gZ2V0U3RhcnRFbGVtZW50cyhTdHJpbmcgeG1sLCBmaW5hbCBib29sZWFuIG5hbWVzcGFjZSwgYm9vbGVhbiBuYW1lc3BhY2VQcmVmaXhlcykKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBMaXN0PFN0cmluZz4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIFhNTFJlYWRlciByZWFkZXIgPSBTQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCkubmV3U0FYUGFyc2VyKCkuZ2V0WE1MUmVhZGVyKCk7CisgICAgICAgIHJlYWRlci5zZXRGZWF0dXJlKFNBWF9QUk9QRVJUWV9OUywgbmFtZXNwYWNlKTsKKyAgICAgICAgcmVhZGVyLnNldEZlYXR1cmUoU0FYX1BST1BFUlRZX05TX1BSRUZJWEVTLCBuYW1lc3BhY2VQcmVmaXhlcyk7CisgICAgICAgIHJlYWRlci5zZXRDb250ZW50SGFuZGxlcihuZXcgRGVmYXVsdEhhbmRsZXIoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGZpbmFsIHZvaWQgc3RhcnRFbGVtZW50KAorICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cmlidXRlcykgeworICAgICAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgc2VyaWFsaXplZCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgKiBPbmx5IHN1cHBseSB0aGUgdXJpK2xvY2FsTmFtZSBvciBxbmFtZSBkZXBlbmRpbmcgb24gd2hldGhlciBuYW1lc3BhY2VzIGFyZQorICAgICAgICAgICAgICAgICAqIGVuYWJsZWQuIEl0J3MgYW4gb3B0aW9uYWwgcGFyYW1ldGVyIGFuZCB0aGUgUkkgb25seSBzdXBwbGllcyBvbmUgb3IgdGhlIG90aGVyLgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIGlmIChuYW1lc3BhY2UpIHsKKyAgICAgICAgICAgICAgICAgICAgc2VyaWFsaXplZC5hcHBlbmQodXJpKS5hcHBlbmQoIiwiKTsKKyAgICAgICAgICAgICAgICAgICAgc2VyaWFsaXplZC5hcHBlbmQobG9jYWxOYW1lKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBzZXJpYWxpemVkLmFwcGVuZChxTmFtZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWQuYXBwZW5kKCJcbiAgIik7CisgICAgICAgICAgICAgICAgICAgIGlmIChuYW1lc3BhY2UpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWQuYXBwZW5kKGF0dHJpYnV0ZXMuZ2V0VVJJKGkpKS5hcHBlbmQoIiwiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWQuYXBwZW5kKGF0dHJpYnV0ZXMuZ2V0TG9jYWxOYW1lKGkpKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWQuYXBwZW5kKGF0dHJpYnV0ZXMuZ2V0UU5hbWUoaSkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWQuYXBwZW5kKCJcbiAgaHR0cDovL2JhcitjPSIpCisgICAgICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKGF0dHJpYnV0ZXMuZ2V0VmFsdWUoImh0dHA6Ly9iYXIiLCAiYyIpKS5hcHBlbmQoIiwiKQorICAgICAgICAgICAgICAgICAgICAgICAgLmFwcGVuZCgiXG4gIGJhcjpjPSIpCisgICAgICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKGF0dHJpYnV0ZXMuZ2V0VmFsdWUoImJhcjpjIikpCisgICAgICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKCJcbiIpOworICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQoc2VyaWFsaXplZC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIHJlYWRlci5wYXJzZShuZXcgSW5wdXRTb3VyY2UobmV3IFN0cmluZ1JlYWRlcih4bWwpKSk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL05vZGVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS94bWwvTm9kZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZTM4NjczCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL05vZGVUZXN0LmphdmEKQEAgLTAsMCArMSw4OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS54bWw7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworaW1wb3J0IHRlc3RzLnN1cHBvcnQucmVzb3VyY2UuU3VwcG9ydF9SZXNvdXJjZXM7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCitwdWJsaWMgY2xhc3MgTm9kZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBGb3IgYnVnIDc3OTogTm9kZSNnZXROZXh0U2libGluZyB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE5leHRTaWJsaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIENhbGxpbmcgZ2V0TmV4dFNpYmxpbmcgd2hlbiB0aGVyZSBpcyBubyBuZXh0IHNpYmxpbmcgc2hvdWxkIHJldHVybiBudWxsLgorICAgICAgICAvLyBGcm9tIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9Nzc5LgorICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oIjxyb290Lz4iLmdldEJ5dGVzKCkpOworICAgICAgICBEb2N1bWVudCBkb2N1bWVudCA9IERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKS5uZXdEb2N1bWVudEJ1aWxkZXIoKS5wYXJzZShiaXMpOworICAgICAgICBOb2RlIHJvb3QgPSBkb2N1bWVudC5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChyb290LmdldE5leHRTaWJsaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRCYXNlVXJpKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpLm5ld0RvY3VtZW50QnVpbGRlcigpOworICAgICAgICBGaWxlIGZpbGUgPSBTdXBwb3J0X1Jlc291cmNlcy5yZXNvdXJjZVRvVGVtcEZpbGUoIi9zaW1wbGUueG1sIik7CisgICAgICAgIERvY3VtZW50IGRvY3VtZW50ID0gYnVpbGRlci5wYXJzZShmaWxlKTsKKworICAgICAgICBhc3NlcnRGaWxlVXJpRXF1YWxzKGZpbGUsIGRvY3VtZW50LmdldEJhc2VVUkkoKSk7CisKKyAgICAgICAgRWxlbWVudCBkb2N1bWVudEVsZW1lbnQgPSBkb2N1bWVudC5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgZm9yIChOb2RlIG5vZGUgOiBmbGF0dGVuU3VidHJlZShkb2N1bWVudEVsZW1lbnQpKSB7CisgICAgICAgICAgICBpZiAobm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFCisgICAgICAgICAgICAgICAgICAgIHx8IG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRGaWxlVXJpRXF1YWxzKGZpbGUsIG5vZGUuZ2V0QmFzZVVSSSgpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbCgiVW5leHBlY3RlZCBiYXNlIFVSSSBmb3IgIiArIG5vZGUsIG5vZGUuZ2V0QmFzZVVSSSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIFRPRE86IHRlc3Qgb3RoZXIgbm9kZSB0eXBlcworICAgICAgICAvLyBUT0RPOiB0ZXN0IHJlc29sdXRpb24gb2YgcmVsYXRpdmUgcGF0aHMKKyAgICAgICAgLy8gVE9ETzogdGVzdCBVUkkgc2FuaXRpemF0aW9uCisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydEZpbGVVcmlFcXVhbHMoRmlsZSBleHBlY3RlZEZpbGUsIFN0cmluZyBhY3R1YWwpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRXhwZWN0ZWQgVVJJIGZvcjogIiArIGV4cGVjdGVkRmlsZSArICIgYnV0IHdhcyAiICsgYWN0dWFsICsgIi4gIiwKKyAgICAgICAgICAgICAgICBhY3R1YWwuZXF1YWxzKCJmaWxlOiIgKyBleHBlY3RlZEZpbGUpCisgICAgICAgICAgICAgICAgICAgICAgICB8fCBhY3R1YWwuZXF1YWxzKCJmaWxlOi8vIiArIGV4cGVjdGVkRmlsZSkpOworICAgIH0KKworICAgIHByaXZhdGUgTGlzdDxOb2RlPiBmbGF0dGVuU3VidHJlZShOb2RlIHN1YnRyZWUpIHsKKyAgICAgICAgTGlzdDxOb2RlPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PE5vZGU+KCk7CisgICAgICAgIHRyYXZlcnNlKHN1YnRyZWUsIHJlc3VsdCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRyYXZlcnNlKE5vZGUgbm9kZSwgTGlzdDxOb2RlPiBzaW5rKSB7CisgICAgICAgIHNpbmsuYWRkKG5vZGUpOworCisgICAgICAgIE5vZGVMaXN0IGNoaWxkcmVuID0gbm9kZS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2hpbGRyZW4uZ2V0TGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgdHJhdmVyc2UoY2hpbGRyZW4uaXRlbShpKSwgc2luayk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS94bWwvTm9ybWFsaXplVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL05vcm1hbGl6ZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZTUzOWY3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL05vcm1hbGl6ZVRlc3QuamF2YQpAQCAtMCwwICsxLDYyMiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS54bWw7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5Lbm93bkZhaWx1cmU7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tLkNEQVRBU2VjdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Db21tZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXJyb3I7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXJyb3JIYW5kbGVyOworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CitpbXBvcnQgb3JnLnczYy5kb20uUHJvY2Vzc2luZ0luc3RydWN0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLlRleHQ7CitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5czsKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyOworaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnk7CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NU291cmNlOworaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVJlc3VsdDsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1JlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIFRlc3RzIHRoZSBhY2NlcHRhbmNlIG9mIHZhcmlvdXMgcGFyYW1ldGVycyBvbiB0aGUgRE9NIGNvbmZpZ3VyYXRpb24uIFRoaXMKKyAqIHRlc3QgYXNzdW1lcyB0aGUgc2FtZSBzZXQgb2YgcGFyYW1ldGVycyBhcyB0aGUgUkkgdmVyc2lvbiAxLjUuIFBlcmZlY3RseQorICogY29ycmVjdCBET00gaW1wbGVtZW50YXRpb25zIG1heSBmYWlsIHRoaXMgdGVzdCBiZWNhdXNlIGl0IGFzc3VtZXMgY2VydGFpbgorICogcGFyYW1ldGVycyB3aWxsIGJlIHVuc3VwcG9ydGVkLgorICovCitwdWJsaWMgY2xhc3MgTm9ybWFsaXplVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgRG9jdW1lbnQgZG9jdW1lbnQ7CisgICAgcHJpdmF0ZSBET01Db25maWd1cmF0aW9uIGRvbUNvbmZpZ3VyYXRpb247CisKKyAgICBTdHJpbmdbXSBpbmZvc2V0SW1wbGllc0ZhbHNlID0geworICAgICAgICAgICAgInZhbGlkYXRlLWlmLXNjaGVtYSIsICJlbnRpdGllcyIsICJkYXRhdHlwZS1ub3JtYWxpemF0aW9uIiwgImNkYXRhLXNlY3Rpb25zIiB9OworICAgIFN0cmluZ1tdIGluZm9zZXRJbXBsaWVzVHJ1ZSA9IHsgIm5hbWVzcGFjZS1kZWNsYXJhdGlvbnMiLCAid2VsbC1mb3JtZWQiLAorICAgICAgICAgICAgImVsZW1lbnQtY29udGVudC13aGl0ZXNwYWNlIiwgImNvbW1lbnRzIiwgIm5hbWVzcGFjZXMiIH07CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZG9jdW1lbnQgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCkubmV3RG9jdW1lbnRCdWlsZGVyKCkubmV3RG9jdW1lbnQoKTsKKyAgICAgICAgZG9tQ29uZmlndXJhdGlvbiA9IGRvY3VtZW50LmdldERvbUNvbmZpZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDYW5vbmljYWxGb3JtKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIGRvbUNvbmZpZ3VyYXRpb24uZ2V0UGFyYW1ldGVyKCJjYW5vbmljYWwtZm9ybSIpKTsKKyAgICAgICAgYXNzZXJ0U3VwcG9ydGVkKCJjYW5vbmljYWwtZm9ybSIsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0VW5zdXBwb3J0ZWQoImNhbm9uaWNhbC1mb3JtIiwgdHJ1ZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENkYXRhU2VjdGlvbnMoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBkb21Db25maWd1cmF0aW9uLmdldFBhcmFtZXRlcigiY2RhdGEtc2VjdGlvbnMiKSk7CisgICAgICAgIGFzc2VydFN1cHBvcnRlZCgiY2RhdGEtc2VjdGlvbnMiLCBmYWxzZSk7CisgICAgICAgIGFzc2VydFN1cHBvcnRlZCgiY2RhdGEtc2VjdGlvbnMiLCB0cnVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2hlY2tDaGFyYWN0ZXJOb3JtYWxpemF0aW9uKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIGRvbUNvbmZpZ3VyYXRpb24uZ2V0UGFyYW1ldGVyKCJjaGVjay1jaGFyYWN0ZXItbm9ybWFsaXphdGlvbiIpKTsKKyAgICAgICAgYXNzZXJ0U3VwcG9ydGVkKCJjaGVjay1jaGFyYWN0ZXItbm9ybWFsaXphdGlvbiIsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0VW5zdXBwb3J0ZWQoImNoZWNrLWNoYXJhY3Rlci1ub3JtYWxpemF0aW9uIiwgdHJ1ZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbW1lbnRzKCkgeworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgZG9tQ29uZmlndXJhdGlvbi5nZXRQYXJhbWV0ZXIoImNvbW1lbnRzIikpOworICAgICAgICBhc3NlcnRTdXBwb3J0ZWQoImNvbW1lbnRzIiwgZmFsc2UpOworICAgICAgICBhc3NlcnRTdXBwb3J0ZWQoImNvbW1lbnRzIiwgdHJ1ZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERhdGF0eXBlTm9ybWFsaXphdGlvbigpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBkb21Db25maWd1cmF0aW9uLmdldFBhcmFtZXRlcigiZGF0YXR5cGUtbm9ybWFsaXphdGlvbiIpKTsKKyAgICAgICAgYXNzZXJ0U3VwcG9ydGVkKCJkYXRhdHlwZS1ub3JtYWxpemF0aW9uIiwgZmFsc2UpOworICAgICAgICBhc3NlcnRTdXBwb3J0ZWQoImRhdGF0eXBlLW5vcm1hbGl6YXRpb24iLCB0cnVlKTsKKworICAgICAgICAvLyBzZXR0aW5nIHRoaXMgcGFyYW1ldGVyIHRvIHRydWUgc2hvdWxkIHNldCB2YWxpZGF0ZSB0byB0cnVlLi4uCisgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKCJ2YWxpZGF0ZSIsIGZhbHNlKTsKKyAgICAgICAgZG9tQ29uZmlndXJhdGlvbi5zZXRQYXJhbWV0ZXIoImRhdGF0eXBlLW5vcm1hbGl6YXRpb24iLCB0cnVlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGRvbUNvbmZpZ3VyYXRpb24uZ2V0UGFyYW1ldGVyKCJ2YWxpZGF0ZSIpKTsKKworICAgICAgICAvLyAuLi5idXQgdGhlIG5lZ2F0aXZlIGNhc2UgaXNuJ3Qgc28KKyAgICAgICAgZG9tQ29uZmlndXJhdGlvbi5zZXRQYXJhbWV0ZXIoImRhdGF0eXBlLW5vcm1hbGl6YXRpb24iLCBmYWxzZSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBkb21Db25maWd1cmF0aW9uLmdldFBhcmFtZXRlcigidmFsaWRhdGUiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVsZW1lbnRDb250ZW50V2hpdGVzcGFjZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGRvbUNvbmZpZ3VyYXRpb24uZ2V0UGFyYW1ldGVyKCJlbGVtZW50LWNvbnRlbnQtd2hpdGVzcGFjZSIpKTsKKyAgICAgICAgYXNzZXJ0VW5zdXBwb3J0ZWQoImVsZW1lbnQtY29udGVudC13aGl0ZXNwYWNlIiwgZmFsc2UpOworICAgICAgICBhc3NlcnRTdXBwb3J0ZWQoImVsZW1lbnQtY29udGVudC13aGl0ZXNwYWNlIiwgdHJ1ZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVudGl0aWVzKCkgeworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgZG9tQ29uZmlndXJhdGlvbi5nZXRQYXJhbWV0ZXIoImVudGl0aWVzIikpOworICAgICAgICBhc3NlcnRTdXBwb3J0ZWQoImVudGl0aWVzIiwgZmFsc2UpOworICAgICAgICBhc3NlcnRTdXBwb3J0ZWQoImVudGl0aWVzIiwgdHJ1ZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVycm9ySGFuZGxlcigpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGRvbUNvbmZpZ3VyYXRpb24uZ2V0UGFyYW1ldGVyKCJlcnJvci1oYW5kbGVyIikpOworICAgICAgICBhc3NlcnRTdXBwb3J0ZWQoImVycm9yLWhhbmRsZXIiLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0U3VwcG9ydGVkKCJlcnJvci1oYW5kbGVyIiwgbmV3IERPTUVycm9ySGFuZGxlcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhbmRsZUVycm9yKERPTUVycm9yIGVycm9yKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJbmZvc2V0KCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIGRvbUNvbmZpZ3VyYXRpb24uZ2V0UGFyYW1ldGVyKCJpbmZvc2V0IikpOworICAgICAgICBhc3NlcnRTdXBwb3J0ZWQoImluZm9zZXQiLCBmYWxzZSk7CisgICAgICAgIGFzc2VydFN1cHBvcnRlZCgiaW5mb3NldCIsIHRydWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXR0aW5nSW5mb3NldFVwZGF0ZXNJbXBsaWVkKCkgeworICAgICAgICAvLyBmaXJzdCBjbGVhciB0aG9zZSBvdGhlciBwYXJhbWV0ZXJzCisgICAgICAgIGZvciAoU3RyaW5nIG5hbWUgOiBpbmZvc2V0SW1wbGllc0ZhbHNlKSB7CisgICAgICAgICAgICBpZiAoZG9tQ29uZmlndXJhdGlvbi5jYW5TZXRQYXJhbWV0ZXIobmFtZSwgdHJ1ZSkpIHsKKyAgICAgICAgICAgICAgICBkb21Db25maWd1cmF0aW9uLnNldFBhcmFtZXRlcihuYW1lLCB0cnVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmb3IgKFN0cmluZyBuYW1lIDogaW5mb3NldEltcGxpZXNUcnVlKSB7CisgICAgICAgICAgICBpZiAoZG9tQ29uZmlndXJhdGlvbi5jYW5TZXRQYXJhbWV0ZXIobmFtZSwgZmFsc2UpKSB7CisgICAgICAgICAgICAgICAgZG9tQ29uZmlndXJhdGlvbi5zZXRQYXJhbWV0ZXIobmFtZSwgZmFsc2UpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gc2V0IGluZm9zZXQKKyAgICAgICAgZG9tQ29uZmlndXJhdGlvbi5zZXRQYXJhbWV0ZXIoImluZm9zZXQiLCB0cnVlKTsKKworICAgICAgICAvLyBub3cgdGhlIHBhcmFtZXRlcnMgc2hvdWxkIGFsbCBtYXRjaCB3aGF0IGluZm9zZXQgaW1wbGllcworICAgICAgICBmb3IgKFN0cmluZyBuYW1lIDogaW5mb3NldEltcGxpZXNGYWxzZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBkb21Db25maWd1cmF0aW9uLmdldFBhcmFtZXRlcihuYW1lKSk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChTdHJpbmcgbmFtZSA6IGluZm9zZXRJbXBsaWVzVHJ1ZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGRvbUNvbmZpZ3VyYXRpb24uZ2V0UGFyYW1ldGVyKG5hbWUpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXR0aW5nSW1wbGllZFVwZGF0ZXNJbmZvc2V0KCkgeworICAgICAgICBmb3IgKFN0cmluZyBuYW1lIDogaW5mb3NldEltcGxpZXNGYWxzZSkgeworICAgICAgICAgICAgZG9tQ29uZmlndXJhdGlvbi5zZXRQYXJhbWV0ZXIoImluZm9zZXQiLCB0cnVlKTsKKyAgICAgICAgICAgIGlmIChkb21Db25maWd1cmF0aW9uLmNhblNldFBhcmFtZXRlcihuYW1lLCB0cnVlKSkgeworICAgICAgICAgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKG5hbWUsIHRydWUpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgZG9tQ29uZmlndXJhdGlvbi5nZXRQYXJhbWV0ZXIoImluZm9zZXQiKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmb3IgKFN0cmluZyBuYW1lIDogaW5mb3NldEltcGxpZXNUcnVlKSB7CisgICAgICAgICAgICBkb21Db25maWd1cmF0aW9uLnNldFBhcmFtZXRlcigiaW5mb3NldCIsIHRydWUpOworICAgICAgICAgICAgaWYgKGRvbUNvbmZpZ3VyYXRpb24uY2FuU2V0UGFyYW1ldGVyKG5hbWUsIGZhbHNlKSkgeworICAgICAgICAgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKG5hbWUsIGZhbHNlKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIGRvbUNvbmZpZ3VyYXRpb24uZ2V0UGFyYW1ldGVyKCJpbmZvc2V0IikpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5hbWVzcGFjZXMoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBkb21Db25maWd1cmF0aW9uLmdldFBhcmFtZXRlcigibmFtZXNwYWNlcyIpKTsKKyAgICAgICAgYXNzZXJ0U3VwcG9ydGVkKCJuYW1lc3BhY2VzIiwgZmFsc2UpOworICAgICAgICBhc3NlcnRTdXBwb3J0ZWQoIm5hbWVzcGFjZXMiLCB0cnVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmFtZXNwYWNlRGVjbGFyYXRpb25zKCkgeworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgZG9tQ29uZmlndXJhdGlvbi5nZXRQYXJhbWV0ZXIoIm5hbWVzcGFjZS1kZWNsYXJhdGlvbnMiKSk7CisgICAgICAgIGFzc2VydFVuc3VwcG9ydGVkKCJuYW1lc3BhY2UtZGVjbGFyYXRpb25zIiwgZmFsc2UpOyAvLyBzdXBwb3J0ZWQgaW4gUkkgNgorICAgICAgICBhc3NlcnRTdXBwb3J0ZWQoIm5hbWVzcGFjZS1kZWNsYXJhdGlvbnMiLCB0cnVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9ybWFsaXplQ2hhcmFjdGVycygpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBkb21Db25maWd1cmF0aW9uLmdldFBhcmFtZXRlcigibm9ybWFsaXplLWNoYXJhY3RlcnMiKSk7CisgICAgICAgIGFzc2VydFN1cHBvcnRlZCgibm9ybWFsaXplLWNoYXJhY3RlcnMiLCBmYWxzZSk7CisgICAgICAgIGFzc2VydFVuc3VwcG9ydGVkKCJub3JtYWxpemUtY2hhcmFjdGVycyIsIHRydWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTY2hlbWFMb2NhdGlvbigpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGRvbUNvbmZpZ3VyYXRpb24uZ2V0UGFyYW1ldGVyKCJzY2hlbWEtbG9jYXRpb24iKSk7CisgICAgICAgIGFzc2VydFN1cHBvcnRlZCgic2NoZW1hLWxvY2F0aW9uIiwgImh0dHA6Ly9mb28iKTsKKyAgICAgICAgYXNzZXJ0U3VwcG9ydGVkKCJzY2hlbWEtbG9jYXRpb24iLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGZhaWxzIHVuZGVyIHRoZSBSSSBiZWNhdXNlIHNldFBhcmFtZXRlcigpIHN1Y2NlZWRzIGV2ZW4gdGhvdWdoCisgICAgICogY2FuU2V0UGFyYW1ldGVyKCkgcmV0dXJucyBmYWxzZS4KKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJEYWx2aWsgZG9lc24ndCBob25vciB0aGUgc2NoZW1hLXR5cGUgcGFyYW1ldGVyIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2NoZW1hVHlwZUR0ZCgpIHsKKyAgICAgICAgYXNzZXJ0VW5zdXBwb3J0ZWQoInNjaGVtYS10eXBlIiwgImh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwiKTsgLy8gc3VwcG9ydGVkIGluIFJJIHY2CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNjaGVtYVR5cGVYbWxTY2hlbWEoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBkb21Db25maWd1cmF0aW9uLmdldFBhcmFtZXRlcigic2NoZW1hLXR5cGUiKSk7CisgICAgICAgIGFzc2VydFN1cHBvcnRlZCgic2NoZW1hLXR5cGUiLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0U3VwcG9ydGVkKCJzY2hlbWEtdHlwZSIsICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTcGxpdENkYXRhU2VjdGlvbnMoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBkb21Db25maWd1cmF0aW9uLmdldFBhcmFtZXRlcigic3BsaXQtY2RhdGEtc2VjdGlvbnMiKSk7CisgICAgICAgIGFzc2VydFN1cHBvcnRlZCgic3BsaXQtY2RhdGEtc2VjdGlvbnMiLCBmYWxzZSk7CisgICAgICAgIGFzc2VydFN1cHBvcnRlZCgic3BsaXQtY2RhdGEtc2VjdGlvbnMiLCB0cnVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmFsaWRhdGUoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgZG9tQ29uZmlndXJhdGlvbi5nZXRQYXJhbWV0ZXIoInZhbGlkYXRlIikpOworICAgICAgICBhc3NlcnRTdXBwb3J0ZWQoInZhbGlkYXRlIiwgZmFsc2UpOworICAgICAgICBhc3NlcnRTdXBwb3J0ZWQoInZhbGlkYXRlIiwgdHJ1ZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFZhbGlkYXRlSWZTY2hlbWEoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgZG9tQ29uZmlndXJhdGlvbi5nZXRQYXJhbWV0ZXIoInZhbGlkYXRlLWlmLXNjaGVtYSIpKTsKKyAgICAgICAgYXNzZXJ0U3VwcG9ydGVkKCJ2YWxpZGF0ZS1pZi1zY2hlbWEiLCBmYWxzZSk7CisgICAgICAgIGFzc2VydFVuc3VwcG9ydGVkKCJ2YWxpZGF0ZS1pZi1zY2hlbWEiLCB0cnVlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V2VsbEZvcm1lZCgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGRvbUNvbmZpZ3VyYXRpb24uZ2V0UGFyYW1ldGVyKCJ3ZWxsLWZvcm1lZCIpKTsKKyAgICAgICAgYXNzZXJ0U3VwcG9ydGVkKCJ3ZWxsLWZvcm1lZCIsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0U3VwcG9ydGVkKCJ3ZWxsLWZvcm1lZCIsIHRydWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNaXNzaW5nUGFyYW1ldGVyKCkgeworICAgICAgICBhc3NlcnRGYWxzZShkb21Db25maWd1cmF0aW9uLmNhblNldFBhcmFtZXRlcigiZm9vIiwgdHJ1ZSkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZG9tQ29uZmlndXJhdGlvbi5nZXRQYXJhbWV0ZXIoImZvbyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkb21Db25maWd1cmF0aW9uLnNldFBhcmFtZXRlcigiZm9vIiwgdHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TnVsbEtleSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uY2FuU2V0UGFyYW1ldGVyKG51bGwsIHRydWUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uZ2V0UGFyYW1ldGVyKG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKG51bGwsIHRydWUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TnVsbFZhbHVlKCkgeworICAgICAgICBTdHJpbmcgbWVzc2FnZSA9ICJUaGlzIGltcGxlbWVudGF0aW9uJ3MgY2FuU2V0UGFyYW1ldGVyKCkgZGlzYWdyZWVzIgorICAgICAgICAgICAgICAgICsgIiB3aXRoIGl0cyBzZXRQYXJhbWV0ZXIoKSI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkb21Db25maWd1cmF0aW9uLnNldFBhcmFtZXRlcigid2VsbC1mb3JtZWQiLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwobWVzc2FnZSk7CisgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsIGZhbHNlLCBkb21Db25maWd1cmF0aW9uLmNhblNldFBhcmFtZXRlcigid2VsbC1mb3JtZWQiLCBudWxsKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFR5cGVNaXNtYXRjaCgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBkb21Db25maWd1cmF0aW9uLmNhblNldFBhcmFtZXRlcigid2VsbC1mb3JtZWQiLCAidHJ1ZSIpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKCJ3ZWxsLWZvcm1lZCIsICJ0cnVlIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIGRvbUNvbmZpZ3VyYXRpb24uY2FuU2V0UGFyYW1ldGVyKCJ3ZWxsLWZvcm1lZCIsIG5ldyBPYmplY3QoKSkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZG9tQ29uZmlndXJhdGlvbi5zZXRQYXJhbWV0ZXIoIndlbGwtZm9ybWVkIiwgbmV3IE9iamVjdCgpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRVbnN1cHBvcnRlZChTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIFN0cmluZyBtZXNzYWdlID0gIlRoaXMgaW1wbGVtZW50YXRpb24ncyBzZXRQYXJhbWV0ZXIoKSBzdXBwb3J0cyBhbiB1bmV4cGVjdGVkIHZhbHVlOiAiCisgICAgICAgICAgICAgICAgKyBuYW1lICsgIj0iICsgdmFsdWU7CisgICAgICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UsIGRvbUNvbmZpZ3VyYXRpb24uY2FuU2V0UGFyYW1ldGVyKG5hbWUsIHZhbHVlKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkb21Db25maWd1cmF0aW9uLnNldFBhcmFtZXRlcihuYW1lLCB2YWx1ZSk7CisgICAgICAgICAgICBmYWlsKG1lc3NhZ2UpOworICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgZS5jb2RlKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZG9tQ29uZmlndXJhdGlvbi5zZXRQYXJhbWV0ZXIobmFtZS50b1VwcGVyQ2FzZSgpLCB2YWx1ZSk7CisgICAgICAgICAgICBmYWlsKG1lc3NhZ2UpOworICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgZS5jb2RlKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZSh2YWx1ZS5lcXVhbHMoZG9tQ29uZmlndXJhdGlvbi5nZXRQYXJhbWV0ZXIobmFtZSkpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0U3VwcG9ydGVkKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgU3RyaW5nIG1lc3NhZ2UgPSAiVGhpcyBpbXBsZW1lbnRhdGlvbidzIGNhblNldFBhcmFtZXRlcigpIGRpc2FncmVlcyIKKyAgICAgICAgICAgICAgICArICIgd2l0aCBpdHMgc2V0UGFyYW1ldGVyKCkgZm9yICIgKyBuYW1lICsgIj0iICsgdmFsdWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkb21Db25maWd1cmF0aW9uLnNldFBhcmFtZXRlcihuYW1lLCB2YWx1ZSk7CisgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAoZG9tQ29uZmlndXJhdGlvbi5jYW5TZXRQYXJhbWV0ZXIobmFtZSwgdmFsdWUpKSB7CisgICAgICAgICAgICAgICAgZmFpbChtZXNzYWdlKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVGhpcyBpbXBsZW1lbnRhdGlvbidzIHNldFBhcmFtZXRlcigpIGRvZXNuJ3Qgc3VwcG9ydDogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBuYW1lICsgIj0iICsgdmFsdWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUobWVzc2FnZSwgZG9tQ29uZmlndXJhdGlvbi5jYW5TZXRQYXJhbWV0ZXIobmFtZS50b1VwcGVyQ2FzZSgpLCB2YWx1ZSkpOworICAgICAgICBhc3NlcnRUcnVlKG1lc3NhZ2UsIGRvbUNvbmZpZ3VyYXRpb24uY2FuU2V0UGFyYW1ldGVyKG5hbWUsIHZhbHVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh2YWx1ZSwgZG9tQ29uZmlndXJhdGlvbi5nZXRQYXJhbWV0ZXIobmFtZSkpOworICAgICAgICBkb21Db25maWd1cmF0aW9uLnNldFBhcmFtZXRlcihuYW1lLnRvVXBwZXJDYXNlKCksIHZhbHVlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHZhbHVlLCBkb21Db25maWd1cmF0aW9uLmdldFBhcmFtZXRlcihuYW1lLnRvVXBwZXJDYXNlKCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2RhdGFTZWN0aW9uc05vdEhvbm9yZWRCeU5vZGVOb3JtYWxpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8Zm9vPkFCQzwhW0NEQVRBW0RFRl1dPkdISTwvZm9vPiI7CisgICAgICAgIHBhcnNlKHhtbCk7CisgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKCJjZGF0YS1zZWN0aW9ucyIsIHRydWUpOworICAgICAgICBkb2N1bWVudC5nZXREb2N1bWVudEVsZW1lbnQoKS5ub3JtYWxpemUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHhtbCwgZG9tVG9TdHJpbmcoZG9jdW1lbnQpKTsKKworICAgICAgICBwYXJzZSh4bWwpOworICAgICAgICBkb21Db25maWd1cmF0aW9uLnNldFBhcmFtZXRlcigiY2RhdGEtc2VjdGlvbnMiLCBmYWxzZSk7CisgICAgICAgIGRvY3VtZW50LmdldERvY3VtZW50RWxlbWVudCgpLm5vcm1hbGl6ZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoeG1sLCBkb21Ub1N0cmluZyhkb2N1bWVudCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDZGF0YVNlY3Rpb25zSG9ub3JlZEJ5RG9jdW1lbnROb3JtYWxpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8Zm9vPkFCQzwhW0NEQVRBW0RFRl1dPkdISTwvZm9vPiI7CisgICAgICAgIHBhcnNlKHhtbCk7CisgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKCJjZGF0YS1zZWN0aW9ucyIsIHRydWUpOworICAgICAgICBkb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoeG1sLCBkb21Ub1N0cmluZyhkb2N1bWVudCkpOworCisgICAgICAgIHBhcnNlKHhtbCk7CisgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKCJjZGF0YS1zZWN0aW9ucyIsIGZhbHNlKTsKKyAgICAgICAgZG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTsKKyAgICAgICAgU3RyaW5nIGV4cGVjdGVkID0geG1sLnJlcGxhY2UoIjwhW0NEQVRBW0RFRl1dPiIsICJERUYiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBkb21Ub1N0cmluZyhkb2N1bWVudCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNZXJnZUFkamFjZW50VGV4dE5vZGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRvY3VtZW50ID0gY3JlYXRlRG9jdW1lbnRXaXRoQWRqYWNlbnRUZXh0cygiYWJjIiwgImRlZiIpOworICAgICAgICBkb2N1bWVudC5nZXREb2N1bWVudEVsZW1lbnQoKS5ub3JtYWxpemUoKTsKKyAgICAgICAgYXNzZXJ0Q2hpbGRyZW4oZG9jdW1lbnQuZ2V0RG9jdW1lbnRFbGVtZW50KCksICJhYmNkZWYiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VBZGphY2VudEVtcHR5VGV4dE5vZGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRvY3VtZW50ID0gY3JlYXRlRG9jdW1lbnRXaXRoQWRqYWNlbnRUZXh0cygiIiwgIiIsICIiKTsKKyAgICAgICAgZG9jdW1lbnQuZ2V0RG9jdW1lbnRFbGVtZW50KCkubm9ybWFsaXplKCk7CisgICAgICAgIGFzc2VydENoaWxkcmVuKGRvY3VtZW50LmdldERvY3VtZW50RWxlbWVudCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VBZGphY2VudE5vZGVzV2l0aE5vblRleHRTaWJsaW5ncygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkb2N1bWVudCA9IGNyZWF0ZURvY3VtZW50V2l0aEFkamFjZW50VGV4dHMoImFiYyIsICJkZWYiLCAiPGJyPiIsICJnaGkiLCAiamtsIik7CisgICAgICAgIGRvY3VtZW50LmdldERvY3VtZW50RWxlbWVudCgpLm5vcm1hbGl6ZSgpOworICAgICAgICBhc3NlcnRDaGlsZHJlbihkb2N1bWVudC5nZXREb2N1bWVudEVsZW1lbnQoKSwgImFiY2RlZiIsICI8YnI+IiwgImdoaWprbCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNZXJnZUFkamFjZW50Tm9kZXNFbGltaW5hdGVzRW1wdHlUZXh0cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkb2N1bWVudCA9IGNyZWF0ZURvY3VtZW50V2l0aEFkamFjZW50VGV4dHMoIiIsICIiLCAiPGJyPiIsICIiLCAiIiwgIjxicj4iLCAiIiwgIjxicj4iLCAiIik7CisgICAgICAgIGRvY3VtZW50LmdldERvY3VtZW50RWxlbWVudCgpLm5vcm1hbGl6ZSgpOworICAgICAgICBhc3NlcnRDaGlsZHJlbihkb2N1bWVudC5nZXREb2N1bWVudEVsZW1lbnQoKSwgIjxicj4iLCAiPGJyPiIsICI8YnI+Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJldGFpbmluZ0NvbW1lbnRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB4bWwgPSAiPGZvbz5BQkM8IS0tIGJhciAtLT5ERUY8IS0tIGJheiAtLT5HSEk8L2Zvbz4iOworICAgICAgICBwYXJzZSh4bWwpOworICAgICAgICBkb21Db25maWd1cmF0aW9uLnNldFBhcmFtZXRlcigiY29tbWVudHMiLCB0cnVlKTsKKyAgICAgICAgZG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHhtbCwgZG9tVG9TdHJpbmcoZG9jdW1lbnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29tbWVudENvbnRhaW5pbmdEb3VibGVEYXNoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEVycm9yUmVjb3JkZXIgZXJyb3JSZWNvcmRlciA9IG5ldyBFcnJvclJlY29yZGVyKCk7CisgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKCJlcnJvci1oYW5kbGVyIiwgZXJyb3JSZWNvcmRlcik7CisgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKCJuYW1lc3BhY2VzIiwgZmFsc2UpOworICAgICAgICBFbGVtZW50IHJvb3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJmb28iKTsKKyAgICAgICAgZG9jdW1lbnQuYXBwZW5kQ2hpbGQocm9vdCk7CisgICAgICAgIHJvb3QuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlQ29tbWVudCgiQUJDIC0tIERFRiIpKTsKKyAgICAgICAgZG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTsKKyAgICAgICAgZXJyb3JSZWNvcmRlci5hc3NlcnRBbGxFcnJvcnMoRE9NRXJyb3IuU0VWRVJJVFlfRVJST1IsICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdHJpcHBpbmdDb21tZW50cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgeG1sID0gIjxmb28+QUJDPCEtLSBiYXIgLS0+REVGPCEtLSBiYXogLS0+R0hJPC9mb28+IjsKKyAgICAgICAgcGFyc2UoeG1sKTsKKyAgICAgICAgZG9tQ29uZmlndXJhdGlvbi5zZXRQYXJhbWV0ZXIoImNvbW1lbnRzIiwgZmFsc2UpOworICAgICAgICBkb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpOworICAgICAgICBhc3NlcnRDaGlsZHJlbihkb2N1bWVudC5nZXREb2N1bWVudEVsZW1lbnQoKSwgIkFCQ0RFRkdISSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTcGxpdHRpbmdDZGF0YVNlY3Rpb25zU3BsaXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRXJyb3JSZWNvcmRlciBlcnJvclJlY29yZGVyID0gbmV3IEVycm9yUmVjb3JkZXIoKTsKKyAgICAgICAgZG9tQ29uZmlndXJhdGlvbi5zZXRQYXJhbWV0ZXIoInNwbGl0LWNkYXRhLXNlY3Rpb25zIiwgdHJ1ZSk7CisgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKCJlcnJvci1oYW5kbGVyIiwgZXJyb3JSZWNvcmRlcik7CisgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKCJuYW1lc3BhY2VzIiwgZmFsc2UpOworICAgICAgICBFbGVtZW50IHJvb3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJmb28iKTsKKyAgICAgICAgZG9jdW1lbnQuYXBwZW5kQ2hpbGQocm9vdCk7CisgICAgICAgIHJvb3QuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlQ0RBVEFTZWN0aW9uKCJBQkNdXT5ERUZdXT5HSEkiKSk7CisgICAgICAgIGRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk7CisgICAgICAgIGVycm9yUmVjb3JkZXIuYXNzZXJ0QWxsRXJyb3JzKERPTUVycm9yLlNFVkVSSVRZX1dBUk5JTkcsICJjZGF0YS1zZWN0aW9ucy1zcGxpdHRlZCIpOworICAgICAgICBhc3NlcnRDaGlsZHJlbihyb290LCAiPCFbQ0RBVEFbQUJDXV1dXT4iLCAiPCFbQ0RBVEFbPkRFRl1dXV0+IiwgIjwhW0NEQVRBWz5HSEldXT4iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3BsaXR0aW5nQ2RhdGFTZWN0aW9uc1JlcG9ydEVycm9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEVycm9yUmVjb3JkZXIgZXJyb3JSZWNvcmRlciA9IG5ldyBFcnJvclJlY29yZGVyKCk7CisgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKCJzcGxpdC1jZGF0YS1zZWN0aW9ucyIsIGZhbHNlKTsKKyAgICAgICAgZG9tQ29uZmlndXJhdGlvbi5zZXRQYXJhbWV0ZXIoImVycm9yLWhhbmRsZXIiLCBlcnJvclJlY29yZGVyKTsKKyAgICAgICAgZG9tQ29uZmlndXJhdGlvbi5zZXRQYXJhbWV0ZXIoIm5hbWVzcGFjZXMiLCBmYWxzZSk7CisgICAgICAgIEVsZW1lbnQgcm9vdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImZvbyIpOworICAgICAgICBkb2N1bWVudC5hcHBlbmRDaGlsZChyb290KTsKKyAgICAgICAgcm9vdC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVDREFUQVNlY3Rpb24oIkFCQ11dPkRFRiIpKTsKKyAgICAgICAgZG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTsKKyAgICAgICAgZXJyb3JSZWNvcmRlci5hc3NlcnRBbGxFcnJvcnMoRE9NRXJyb3IuU0VWRVJJVFlfRVJST1IsICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkQ2hhcmFjdGVyc0NkYXRhKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEVycm9yUmVjb3JkZXIgZXJyb3JSZWNvcmRlciA9IG5ldyBFcnJvclJlY29yZGVyKCk7CisgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKCJjZGF0YS1zZWN0aW9ucyIsIHRydWUpOworICAgICAgICBkb21Db25maWd1cmF0aW9uLnNldFBhcmFtZXRlcigiZXJyb3ItaGFuZGxlciIsIGVycm9yUmVjb3JkZXIpOworICAgICAgICBkb21Db25maWd1cmF0aW9uLnNldFBhcmFtZXRlcigibmFtZXNwYWNlcyIsIGZhbHNlKTsKKyAgICAgICAgRWxlbWVudCByb290ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZm9vIik7CisgICAgICAgIGRvY3VtZW50LmFwcGVuZENoaWxkKHJvb3QpOworICAgICAgICBDREFUQVNlY3Rpb24gY2RhdGEgPSBkb2N1bWVudC5jcmVhdGVDREFUQVNlY3Rpb24oIiIpOworICAgICAgICByb290LmFwcGVuZENoaWxkKGNkYXRhKTsKKworICAgICAgICBmb3IgKGludCBjID0gMDsgYyA8PSBDaGFyYWN0ZXIuTUFYX1ZBTFVFOyBjKyspIHsKKyAgICAgICAgICAgIGNkYXRhLnNldERhdGEobmV3IFN0cmluZyhuZXcgY2hhcltdeyAnQScsICdCJywgKGNoYXIpIGMgfSkpOworICAgICAgICAgICAgZG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTsKKyAgICAgICAgICAgIGlmIChpc1ZhbGlkKChjaGFyKSBjKSkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhDb2xsZWN0aW9ucy48RE9NRXJyb3I+ZW1wdHlMaXN0KCksIGVycm9yUmVjb3JkZXIuZXJyb3JzKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZXJyb3JSZWNvcmRlci5hc3NlcnRBbGxFcnJvcnMoIkZvciBjaGFyYWN0ZXIgIiArIGMsCisgICAgICAgICAgICAgICAgICAgICAgICBET01FcnJvci5TRVZFUklUWV9FUlJPUiwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZENoYXJhY3RlcnNUZXh0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEVycm9yUmVjb3JkZXIgZXJyb3JSZWNvcmRlciA9IG5ldyBFcnJvclJlY29yZGVyKCk7CisgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKCJlcnJvci1oYW5kbGVyIiwgZXJyb3JSZWNvcmRlcik7CisgICAgICAgIGRvbUNvbmZpZ3VyYXRpb24uc2V0UGFyYW1ldGVyKCJuYW1lc3BhY2VzIiwgZmFsc2UpOworICAgICAgICBFbGVtZW50IHJvb3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJmb28iKTsKKyAgICAgICAgZG9jdW1lbnQuYXBwZW5kQ2hpbGQocm9vdCk7CisgICAgICAgIFRleHQgdGV4dCA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCIiKTsKKyAgICAgICAgcm9vdC5hcHBlbmRDaGlsZCh0ZXh0KTsKKworICAgICAgICBmb3IgKGludCBjID0gMDsgYyA8PSBDaGFyYWN0ZXIuTUFYX1ZBTFVFOyBjKyspIHsKKyAgICAgICAgICAgIHRleHQuc2V0RGF0YShuZXcgU3RyaW5nKG5ldyBjaGFyW117ICdBJywgJ0InLCAoY2hhcikgYyB9KSk7CisgICAgICAgICAgICBkb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpOworICAgICAgICAgICAgaWYgKGlzVmFsaWQoKGNoYXIpIGMpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKENvbGxlY3Rpb25zLjxET01FcnJvcj5lbXB0eUxpc3QoKSwgZXJyb3JSZWNvcmRlci5lcnJvcnMpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBlcnJvclJlY29yZGVyLmFzc2VydEFsbEVycm9ycygiRm9yIGNoYXJhY3RlciAiICsgYywKKyAgICAgICAgICAgICAgICAgICAgICAgIERPTUVycm9yLlNFVkVSSVRZX0VSUk9SLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkQ2hhcmFjdGVyc0F0dHJpYnV0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBFcnJvclJlY29yZGVyIGVycm9yUmVjb3JkZXIgPSBuZXcgRXJyb3JSZWNvcmRlcigpOworICAgICAgICBkb21Db25maWd1cmF0aW9uLnNldFBhcmFtZXRlcigiZXJyb3ItaGFuZGxlciIsIGVycm9yUmVjb3JkZXIpOworICAgICAgICBkb21Db25maWd1cmF0aW9uLnNldFBhcmFtZXRlcigibmFtZXNwYWNlcyIsIGZhbHNlKTsKKyAgICAgICAgRWxlbWVudCByb290ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZm9vIik7CisgICAgICAgIGRvY3VtZW50LmFwcGVuZENoaWxkKHJvb3QpOworCisgICAgICAgIGZvciAoaW50IGMgPSAwOyBjIDw9IENoYXJhY3Rlci5NQVhfVkFMVUU7IGMrKykgeworICAgICAgICAgICAgcm9vdC5zZXRBdHRyaWJ1dGUoImJhciIsIG5ldyBTdHJpbmcobmV3IGNoYXJbXSB7ICdBJywgJ0InLCAoY2hhcikgY30pKTsKKyAgICAgICAgICAgIGRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk7CisgICAgICAgICAgICBpZiAoaXNWYWxpZCgoY2hhcikgYykpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoQ29sbGVjdGlvbnMuPERPTUVycm9yPmVtcHR5TGlzdCgpLCBlcnJvclJlY29yZGVyLmVycm9ycyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGVycm9yUmVjb3JkZXIuYXNzZXJ0QWxsRXJyb3JzKCJGb3IgY2hhcmFjdGVyICIgKyBjLAorICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXJyb3IuU0VWRVJJVFlfRVJST1IsICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEludmFsaWRDaGFyYWN0ZXJzQ29tbWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBFcnJvclJlY29yZGVyIGVycm9yUmVjb3JkZXIgPSBuZXcgRXJyb3JSZWNvcmRlcigpOworICAgICAgICBkb21Db25maWd1cmF0aW9uLnNldFBhcmFtZXRlcigiZXJyb3ItaGFuZGxlciIsIGVycm9yUmVjb3JkZXIpOworICAgICAgICBkb21Db25maWd1cmF0aW9uLnNldFBhcmFtZXRlcigibmFtZXNwYWNlcyIsIGZhbHNlKTsKKyAgICAgICAgRWxlbWVudCByb290ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZm9vIik7CisgICAgICAgIGRvY3VtZW50LmFwcGVuZENoaWxkKHJvb3QpOworICAgICAgICBDb21tZW50IGNvbW1lbnQgPSBkb2N1bWVudC5jcmVhdGVDb21tZW50KCIiKTsKKyAgICAgICAgcm9vdC5hcHBlbmRDaGlsZChjb21tZW50KTsKKworICAgICAgICBmb3IgKGludCBjID0gMDsgYyA8PSBDaGFyYWN0ZXIuTUFYX1ZBTFVFOyBjKyspIHsKKyAgICAgICAgICAgIGNvbW1lbnQuc2V0RGF0YShuZXcgU3RyaW5nKG5ldyBjaGFyW10geyAnQScsICdCJywgKGNoYXIpIGN9KSk7CisgICAgICAgICAgICBkb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpOworICAgICAgICAgICAgaWYgKGlzVmFsaWQoKGNoYXIpIGMpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKENvbGxlY3Rpb25zLjxET01FcnJvcj5lbXB0eUxpc3QoKSwgZXJyb3JSZWNvcmRlci5lcnJvcnMpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBlcnJvclJlY29yZGVyLmFzc2VydEFsbEVycm9ycygiRm9yIGNoYXJhY3RlciAiICsgYywKKyAgICAgICAgICAgICAgICAgICAgICAgIERPTUVycm9yLlNFVkVSSVRZX0VSUk9SLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkQ2hhcmFjdGVyc1Byb2Nlc3NpbmdJbnN0cnVjdGlvbkRhdGEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRXJyb3JSZWNvcmRlciBlcnJvclJlY29yZGVyID0gbmV3IEVycm9yUmVjb3JkZXIoKTsKKyAgICAgICAgZG9tQ29uZmlndXJhdGlvbi5zZXRQYXJhbWV0ZXIoImVycm9yLWhhbmRsZXIiLCBlcnJvclJlY29yZGVyKTsKKyAgICAgICAgZG9tQ29uZmlndXJhdGlvbi5zZXRQYXJhbWV0ZXIoIm5hbWVzcGFjZXMiLCBmYWxzZSk7CisgICAgICAgIEVsZW1lbnQgcm9vdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImZvbyIpOworICAgICAgICBkb2N1bWVudC5hcHBlbmRDaGlsZChyb290KTsKKyAgICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uIHBpID0gZG9jdW1lbnQuY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKCJmb28iLCAiIik7CisgICAgICAgIHJvb3QuYXBwZW5kQ2hpbGQocGkpOworCisgICAgICAgIGZvciAoaW50IGMgPSAwOyBjIDw9IENoYXJhY3Rlci5NQVhfVkFMVUU7IGMrKykgeworICAgICAgICAgICAgcGkuc2V0RGF0YShuZXcgU3RyaW5nKG5ldyBjaGFyW10geyAnQScsICdCJywgKGNoYXIpIGN9KSk7CisgICAgICAgICAgICBkb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpOworICAgICAgICAgICAgaWYgKGlzVmFsaWQoKGNoYXIpIGMpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKENvbGxlY3Rpb25zLjxET01FcnJvcj5lbXB0eUxpc3QoKSwgZXJyb3JSZWNvcmRlci5lcnJvcnMpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBlcnJvclJlY29yZGVyLmFzc2VydEFsbEVycm9ycygiRm9yIGNoYXJhY3RlciAiICsgYywKKyAgICAgICAgICAgICAgICAgICAgICAgIERPTUVycm9yLlNFVkVSSVRZX0VSUk9SLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRPRE86IHRlc3QgZm9yIHN1cnJvZ2F0ZXMKKworICAgIHByaXZhdGUgYm9vbGVhbiBpc1ZhbGlkKGNoYXIgYykgeworICAgICAgICAvLyBhcyBkZWZpbmVkIGJ5IGh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwvI2NoYXJzZXRzLgorICAgICAgICByZXR1cm4gYyA9PSAweDkgfHwgYyA9PSAweEEgfHwgYyA9PSAweEQgfHwgKGMgPj0gMHgyMCAmJiBjIDw9IDB4ZDdmZikKKyAgICAgICAgICAgICAgICB8fCAoYyA+PSAweGUwMDAgJiYgYyA8PSAweGZmZmQpOworICAgIH0KKworICAgIHByaXZhdGUgRG9jdW1lbnQgY3JlYXRlRG9jdW1lbnRXaXRoQWRqYWNlbnRUZXh0cyhTdHJpbmcuLi4gdGV4dHMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEb2N1bWVudCByZXN1bHQgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCkKKyAgICAgICAgICAgICAgICAubmV3RG9jdW1lbnRCdWlsZGVyKCkubmV3RG9jdW1lbnQoKTsKKyAgICAgICAgRWxlbWVudCByb290ID0gcmVzdWx0LmNyZWF0ZUVsZW1lbnQoImZvbyIpOworICAgICAgICByZXN1bHQuYXBwZW5kQ2hpbGQocm9vdCk7CisgICAgICAgIGZvciAoU3RyaW5nIHRleHQgOiB0ZXh0cykgeworICAgICAgICAgICAgaWYgKHRleHQuZXF1YWxzKCI8YnI+IikpIHsKKyAgICAgICAgICAgICAgICByb290LmFwcGVuZENoaWxkKHJlc3VsdC5jcmVhdGVFbGVtZW50KCJiciIpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcm9vdC5hcHBlbmRDaGlsZChyZXN1bHQuY3JlYXRlVGV4dE5vZGUodGV4dCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydENoaWxkcmVuKEVsZW1lbnQgZWxlbWVudCwgU3RyaW5nLi4uIHRleHRzKSB7CisgICAgICAgIExpc3Q8U3RyaW5nPiBhY3R1YWwgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgTm9kZUxpc3Qgbm9kZXMgPSBlbGVtZW50LmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBub2Rlcy5nZXRMZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBOb2RlIG5vZGUgPSBub2Rlcy5pdGVtKGkpOworICAgICAgICAgICAgaWYgKG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSkgeworICAgICAgICAgICAgICAgIGFjdHVhbC5hZGQoKChUZXh0KSBub2RlKS5nZXREYXRhKCkpOworICAgICAgICAgICAgfSBlbHNlIGlmIChub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5DREFUQV9TRUNUSU9OX05PREUpIHsKKyAgICAgICAgICAgICAgICBhY3R1YWwuYWRkKCI8IVtDREFUQVsiICsgKChDREFUQVNlY3Rpb24pIG5vZGUpLmdldERhdGEoKSArICJdXT4iKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYWN0dWFsLmFkZCgiPCIgKyBub2RlLmdldE5vZGVOYW1lKCkgKyAiPiIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KHRleHRzKSwgYWN0dWFsKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcGFyc2UoU3RyaW5nIHhtbCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRvY3VtZW50ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpLm5ld0RvY3VtZW50QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShuZXcgU3RyaW5nUmVhZGVyKHhtbCkpKTsKKyAgICAgICAgZG9tQ29uZmlndXJhdGlvbiA9IGRvY3VtZW50LmdldERvbUNvbmZpZygpOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGRvbVRvU3RyaW5nKERvY3VtZW50IGRvY3VtZW50KSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24geworICAgICAgICBTdHJpbmdXcml0ZXIgd3JpdGVyID0gbmV3IFN0cmluZ1dyaXRlcigpOworICAgICAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IFRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpIC5uZXdUcmFuc2Zvcm1lcigpOworICAgICAgICB0cmFuc2Zvcm1lci5zZXRPdXRwdXRQcm9wZXJ0eShPdXRwdXRLZXlzLk9NSVRfWE1MX0RFQ0xBUkFUSU9OLCAieWVzIik7CisgICAgICAgIHRyYW5zZm9ybWVyLnRyYW5zZm9ybShuZXcgRE9NU291cmNlKGRvY3VtZW50KSwgbmV3IFN0cmVhbVJlc3VsdCh3cml0ZXIpKTsKKyAgICAgICAgcmV0dXJuIHdyaXRlci50b1N0cmluZygpOworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgRXJyb3JSZWNvcmRlciBpbXBsZW1lbnRzIERPTUVycm9ySGFuZGxlciB7CisgICAgICAgIHByaXZhdGUgZmluYWwgTGlzdDxET01FcnJvcj4gZXJyb3JzID0gbmV3IEFycmF5TGlzdDxET01FcnJvcj4oKTsKKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYW5kbGVFcnJvcihET01FcnJvciBlcnJvcikgeworICAgICAgICAgICAgZXJyb3JzLmFkZChlcnJvcik7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGFzc2VydEFsbEVycm9ycyhpbnQgc2V2ZXJpdHksIFN0cmluZyB0eXBlKSB7CisgICAgICAgICAgICBhc3NlcnRBbGxFcnJvcnMoIkV4cGVjdGVkIG9uZSBvciBtb3JlICIgKyB0eXBlICsgIiBlcnJvcnMiLCBzZXZlcml0eSwgdHlwZSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBhc3NlcnRBbGxFcnJvcnMoU3RyaW5nIG1lc3NhZ2UsIGludCBzZXZlcml0eSwgU3RyaW5nIHR5cGUpIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKG1lc3NhZ2UsIGVycm9ycy5pc0VtcHR5KCkpOworICAgICAgICAgICAgZm9yIChET01FcnJvciBlcnJvciA6IGVycm9ycykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLCBzZXZlcml0eSwgZXJyb3IuZ2V0U2V2ZXJpdHkoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsIHR5cGUsIGVycm9yLmdldFR5cGUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlcnJvcnMuY2xlYXIoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3htbC9QdWxsUGFyc2VyRHRkVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL1B1bGxQYXJzZXJEdGRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGU0ZWFjMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3htbC9QdWxsUGFyc2VyRHRkVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTQyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLnhtbDsKKworaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IG9yZy54bWxwdWxsLnYxLlhtbFB1bGxQYXJzZXI7CitpbXBvcnQgb3JnLnhtbHB1bGwudjEuWG1sUHVsbFBhcnNlckV4Y2VwdGlvbjsKKworLyoqCisgKiBUZXN0IGRvY3R5cGUgaGFuZGxpbmcgaW4gcHVsbCBwYXJzZXJzLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgUHVsbFBhcnNlckR0ZFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUkVBRF9CVUZGRVJfU0laRSA9IDgxOTI7CisKKyAgICAvKioKKyAgICAgKiBBbmRyb2lkJ3MgRXhwYXQgcHVsbCBwYXJzZXIgcGVybWl0cyBwYXJhbWV0ZXIgZW50aXRpZXMgdG8gYmUgZGVjbGFyZWQsCisgICAgICogYnV0IGl0IGRvZXNuJ3QgcGVybWl0IHN1Y2ggZW50aXRpZXMgdG8gYmUgdXNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVjbGFyaW5nUGFyYW1ldGVyRW50aXRpZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8IURPQ1RZUEUgZm9vIFsiCisgICAgICAgICAgICArICIgIDwhRU5USVRZICUgYSBcImFuZHJvaWRcIj4iCisgICAgICAgICAgICArICJdPjxmb28+PC9mb28+IjsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKHhtbCk7CisgICAgICAgIHdoaWxlIChwYXJzZXIubmV4dCgpICE9IFhtbFB1bGxQYXJzZXIuRU5EX0RPQ1VNRU5UKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXNpbmdQYXJhbWV0ZXJFbnRpdGllc0luRHRkcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRQYXJzZUZhaWx1cmUoIjwhRE9DVFlQRSBmb28gWyIKKyAgICAgICAgICAgICsgIiAgPCFFTlRJVFkgJSBhIFwiYW5kcm9pZFwiPiIKKyAgICAgICAgICAgICsgIiAgPCFFTlRJVFkgYiBcIiVhO1wiPiIKKyAgICAgICAgICAgICsgIl0+PGZvbz48L2Zvbz4iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXNpbmdQYXJhbWV0ZXJJbkRvY3VtZW50cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRQYXJzZUZhaWx1cmUoIjwhRE9DVFlQRSBmb28gWyIKKyAgICAgICAgICAgICsgIiAgPCFFTlRJVFkgJSBhIFwiYW5kcm9pZFwiPiIKKyAgICAgICAgICAgICsgIl0+PGZvbz4mYTs8L2Zvbz4iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2VuZXJhbEFuZFBhcmFtZXRlckVudGl0eVdpdGhUaGVTYW1lTmFtZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgeG1sID0gIjwhRE9DVFlQRSBmb28gWyIKKyAgICAgICAgICAgICAgICArICIgIDwhRU5USVRZIGEgXCJhYWFcIj4iCisgICAgICAgICAgICAgICAgKyAiICA8IUVOVElUWSAlIGEgXCJiYmJcIj4iCisgICAgICAgICAgICAgICAgKyAiXT48Zm9vPiZhOzwvZm9vPiI7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcih4bWwpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5URVhULCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhYWEiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgcGFyc2VyLm5leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEludGVybmFsRW50aXRpZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8IURPQ1RZUEUgZm9vIFsiCisgICAgICAgICAgICAgICAgKyAiICA8IUVOVElUWSBhIFwiYW5kcm9pZFwiPiIKKyAgICAgICAgICAgICAgICArICJdPjxmb28+JmE7PC9mb28+IjsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKHhtbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFuZHJvaWQiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgcGFyc2VyLm5leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEV4dGVybmFsRHRkSXNTaWxlbnRseUlnbm9yZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8IURPQ1RZUEUgZm9vIFNZU1RFTSBcImh0dHA6Ly8xMjcuMC4wLjE6MS9uby1zdWNoLWZpbGUuZHRkXCI+PGZvbz48L2Zvbz4iOworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoeG1sKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgcGFyc2VyLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgcGFyc2VyLm5leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEV4dGVybmFsQW5kSW50ZXJuYWxEdGQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8IURPQ1RZUEUgZm9vIFNZU1RFTSBcImh0dHA6Ly8xMjcuMC4wLjE6MS9uby1zdWNoLWZpbGUuZHRkXCIgWyIKKyAgICAgICAgICAgICAgICArICIgIDwhRU5USVRZIGEgXCJhbmRyb2lkXCI+IgorICAgICAgICAgICAgICAgICsgIl0+PGZvbz4mYTs8L2Zvbz4iOworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoeG1sKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuVEVYVCwgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYW5kcm9pZCIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX0RPQ1VNRU5ULCBwYXJzZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW50ZXJuYWxFbnRpdGllc0FyZVBhcnNlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgeG1sID0gIjwhRE9DVFlQRSBmb28gWyIKKyAgICAgICAgICAgICAgICArICIgIDwhRU5USVRZIGEgXCImIzM4OyM2NTtcIj4iIC8vICYjMzg7IGV4cGFuZHMgdG8gJyYnLCAmIzY1OyBleHBhbmRzIHRvICdBJworICAgICAgICAgICAgICAgICsgIl0+PGZvbz4mYTs8L2Zvbz4iOworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoeG1sKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuVEVYVCwgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX0RPQ1VNRU5ULCBwYXJzZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9vbGlzaGx5UmVjdXJzaXZlSW50ZXJuYWxFbnRpdGllcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgeG1sID0gIjwhRE9DVFlQRSBmb28gWyIKKyAgICAgICAgICAgICAgICArICIgIDwhRU5USVRZIGEgXCImIzM4OyMzODsjMzg7IzM4O1wiPiIgLy8gZXhwYW5kICYjMzg7IHRvICcmJyBvbmx5IHR3aWNlCisgICAgICAgICAgICAgICAgKyAiXT48Zm9vPiZhOzwvZm9vPiI7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcih4bWwpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5URVhULCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCImIzM4OyMzODsiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgcGFyc2VyLm5leHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHRoZSBvdXRwdXQgb2Yge0Bjb2RlICYjMzg7fSBpcyBwYXJzZWQsIGJ1dCB7QGNvZGUgJmFtcDt9IGlzbid0LgorICAgICAqIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDgvUkVDLXhtbC0yMDA4MTEyNi8jc2VjLWVudGV4cGFuZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFeHBhbnNpb25PZkVudGl0eUFuZENoYXJhY3RlclJlZmVyZW5jZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8IURPQ1RZUEUgZm9vIFsiCisgICAgICAgICAgICAgICAgKyAiPCFFTlRJVFkgZXhhbXBsZSBcIjxwPkFuIGFtcGVyc2FuZCAoJiMzODsjMzg7KSBtYXkgYmUgZXNjYXBlZFxuIgorICAgICAgICAgICAgICAgICsgIm51bWVyaWNhbGx5ICgmIzM4OyMzODsjMzg7KSBvciB3aXRoIGEgZ2VuZXJhbCBlbnRpdHlcbiIKKyAgICAgICAgICAgICAgICArICIoJmFtcDthbXA7KS48L3A+XCIgPiIKKyAgICAgICAgICAgICAgICArICJdPjxmb28+JmV4YW1wbGU7PC9mb28+IjsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKHhtbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygicCIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5URVhULCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBbiBhbXBlcnNhbmQgKCYpIG1heSBiZSBlc2NhcGVkXG4iCisgICAgICAgICAgICAgICAgKyAibnVtZXJpY2FsbHkgKCYjMzg7KSBvciB3aXRoIGEgZ2VuZXJhbCBlbnRpdHlcbiIKKyAgICAgICAgICAgICAgICArICIoJmFtcDspLiIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwIiwgcGFyc2VyLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQsIHBhcnNlci5uZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmFsRW50aXRpZXNBcmVTdG9yZWRVbnJlc29sdmVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB4bWwgPSAiPCFET0NUWVBFIGZvbyBbIgorICAgICAgICAgICAgICAgICsgIjwhRU5USVRZIGIgXCImYTtcIiA+IgorICAgICAgICAgICAgICAgICsgIjwhRU5USVRZIGEgXCJhbmRyb2lkXCIgPiIKKyAgICAgICAgICAgICAgICArICJdPjxmb28+JmE7PC9mb28+IjsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKHhtbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFuZHJvaWQiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgcGFyc2VyLm5leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0cnVjdHVyZWRFbnRpdHlBbmROZXh0VG9rZW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8IURPQ1RZUEUgZm9vIFs8IUVOVElUWSBiYiBcIjxiYXI+YmF6PCEtLXF1dXgtLT48L2Jhcj5cIj5dPjxmb28+YSZiYjtjPC9mb28+IjsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKHhtbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkRPQ0RFQ0wsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuVEVYVCwgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgcGFyc2VyLmdldFRleHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVOVElUWV9SRUYsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYmIiLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJhciIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5URVhULCBwYXJzZXIubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJheiIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5DT01NRU5ULCBwYXJzZXIubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInF1dXgiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiYXIiLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuVEVYVCwgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjIiwgcGFyc2VyLmdldFRleHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQsIHBhcnNlci5uZXh0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFuZHJvaWQncyBFeHBhdCByZXBsYWNlcyBleHRlcm5hbCBlbnRpdGllcyB3aXRoIHRoZSBlbXB0eSBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVzaW5nRXh0ZXJuYWxFbnRpdGllcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgeG1sID0gIjwhRE9DVFlQRSBmb28gWyIKKyAgICAgICAgICAgICAgICArICIgIDwhRU5USVRZIGEgU1lTVEVNIFwiaHR0cDovL2xvY2FsaG9zdDoxL25vLXN1Y2gtZmlsZS54bWxcIj4iCisgICAgICAgICAgICAgICAgKyAiXT48Zm9vPiZhOzwvZm9vPiI7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcih4bWwpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICAvLyAmYTsgaXMgZHJvcHBlZCEKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgcGFyc2VyLm5leHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQW5kcm9pZCdzIEV4cGF0UHVsbFBhcnNlciByZXBsYWNlcyBtaXNzaW5nIGVudGl0aWVzIHdpdGggdGhlIGVtcHR5IHN0cmluZworICAgICAqIHdoZW4gYW4gZXh0ZXJuYWwgRFREIGlzIGRlY2xhcmVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFeHRlcm5hbER0ZEFuZE1pc3NpbmdFbnRpdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8IURPQ1RZUEUgZm9vIFNZU1RFTSBcImh0dHA6Ly8xMjcuMC4wLjE6MS9uby1zdWNoLWZpbGUuZHRkXCI+IgorICAgICAgICAgICAgICAgICsgIjxmb28+JmE7PC9mb28+IjsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKHhtbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQsIHBhcnNlci5uZXh0KCkpOworICAgIH0KKworCisgICAgcHVibGljIHZvaWQgdGVzdEV4dGVybmFsSWRJc0Nhc2VTZW5zaXRpdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGhlIHNwZWMgcmVxdWlyZXMgJ1NZU1RFTScgaW4gdXBwZXIgY2FzZQorICAgICAgICBhc3NlcnRQYXJzZUZhaWx1cmUoIjwhRE9DVFlQRSBmb28gWyIKKyAgICAgICAgICAgICAgICArICIgIDwhRU5USVRZIGEgc3lzdGVtIFwiaHR0cDovL2xvY2FsaG9zdDoxL25vLXN1Y2gtZmlsZS54bWxcIj4iCisgICAgICAgICAgICAgICAgKyAiXT48Zm9vLz4iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2UgYSBEVEQgdG8gc3BlY2lmeSB0aGF0IHtAY29kZSA8Zm9vPn0gb25seSBjb250YWlucyB7QGNvZGUgPGJhcj59IHRhZ3MuCisgICAgICogVmFsaWRhdGluZyBwYXJzZXJzIHJlYWN0IHRvIHRoaXMgYnkgZHJvcHBpbmcgd2hpdGVzcGFjZSBiZXR3ZWVuIHRoZSB0d28KKyAgICAgKiB0YWdzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REdGREb2VzTm90SW5mb3JtSWdub3JhYmxlV2hpdGVzcGFjZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgeG1sID0gIjwhRE9DVFlQRSBmb28gW1xuIgorICAgICAgICAgICAgICAgICsgIiAgPCFFTEVNRU5UIGZvbyAoYmFyKSo+XG4iCisgICAgICAgICAgICAgICAgKyAiICA8IUVMRU1FTlQgYmFyIEFOWT5cbiIKKyAgICAgICAgICAgICAgICArICJdPiIKKyAgICAgICAgICAgICAgICArICI8Zm9vPiAgXG4gIDxiYXI+PC9iYXI+ICBcdCAgPC9mb28+IjsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKHhtbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgcGFyc2VyLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiAgXG4gICIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJhciIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiYXIiLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuVEVYVCwgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiICBcdCAgIiwgcGFyc2VyLmdldFRleHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQsIHBhcnNlci5uZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eURvZXNOb3RJbmZvcm1JZ25vcmFibGVXaGl0ZXNwYWNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB4bWwgPSAiPCFET0NUWVBFIGZvbyBbXG4iCisgICAgICAgICAgICAgICAgKyAiICA8IUVMRU1FTlQgZm9vIEVNUFRZPlxuIgorICAgICAgICAgICAgICAgICsgIl0+IgorICAgICAgICAgICAgICAgICsgIjxmb28+ICBcbiAgPC9mb28+IjsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKHhtbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgcGFyc2VyLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiAgXG4gICIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX0RPQ1VNRU5ULCBwYXJzZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgdGhlIHBhcnNlciBkb2Vzbid0IGV4cGFuZCB0aGUgZW50aXR5IGF0dHJpYnV0ZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEF0dHJpYnV0ZU9mVHlwZUVudGl0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgeG1sID0gIjwhRE9DVFlQRSBmb28gW1xuIgorICAgICAgICAgICAgICAgICsgIiAgPCFFTlRJVFkgYSBcImFuZHJvaWRcIj4iCisgICAgICAgICAgICAgICAgKyAiICA8IUVMRU1FTlQgZm9vIEFOWT5cbiIKKyAgICAgICAgICAgICAgICArICIgIDwhQVRUTElTVCBmb29cbiIKKyAgICAgICAgICAgICAgICArICIgICAgYmFyIEVOVElUWSAjSU1QTElFRD4iCisgICAgICAgICAgICAgICAgKyAiXT4iCisgICAgICAgICAgICAgICAgKyAiPGZvbyBiYXI9XCJhXCI+PC9mb28+IjsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKHhtbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgcGFyc2VyLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIHBhcnNlci5nZXRBdHRyaWJ1dGVWYWx1ZShudWxsLCAiYmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX0RPQ1VNRU5ULCBwYXJzZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VGFnU3RydWN0dXJlTm90VmFsaWRhdGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB4bWwgPSAiPCFET0NUWVBFIGZvbyBbXG4iCisgICAgICAgICAgICAgICAgKyAiICA8IUVMRU1FTlQgZm9vIChiYXIpKj5cbiIKKyAgICAgICAgICAgICAgICArICIgIDwhRUxFTUVOVCBiYXIgQU5ZPlxuIgorICAgICAgICAgICAgICAgICsgIiAgPCFFTEVNRU5UIGJheiBBTlk+XG4iCisgICAgICAgICAgICAgICAgKyAiXT4iCisgICAgICAgICAgICAgICAgKyAiPGZvbz48YmFyLz48YmFyLz48YmF6Lz48L2Zvbz4iOworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoeG1sKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiYXIiLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYmFyIiwgcGFyc2VyLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJheiIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgcGFyc2VyLm5leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEF0dHJpYnV0ZURlZmF1bHRWYWx1ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8IURPQ1RZUEUgZm9vIFtcbiIKKyAgICAgICAgICAgICAgICArICIgIDwhQVRUTElTVCBiYXJcbiIKKyAgICAgICAgICAgICAgICArICIgICAgYmF6IChhfGJ8YykgIFwiY1wiPiIKKyAgICAgICAgICAgICAgICArICJdPiIKKyAgICAgICAgICAgICAgICArICI8Zm9vPiIKKyAgICAgICAgICAgICAgICArICI8YmFyLz4iCisgICAgICAgICAgICAgICAgKyAiPGJhciBiYXo9XCJhXCIvPiIKKyAgICAgICAgICAgICAgICArICI8L2Zvbz4iOworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoeG1sKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiYXIiLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjIiwgcGFyc2VyLmdldEF0dHJpYnV0ZVZhbHVlKG51bGwsICJiYXoiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJhciIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBwYXJzZXIuZ2V0QXR0cmlidXRlVmFsdWUobnVsbCwgImJheiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQsIHBhcnNlci5uZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdHRyaWJ1dGVEZWZhdWx0VmFsdWVFbnRpdGllc0V4cGFuZGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB4bWwgPSAiPCFET0NUWVBFIGZvbyBbXG4iCisgICAgICAgICAgICAgICAgKyAiICA8IUVOVElUWSBnIFwiZ2hpXCI+IgorICAgICAgICAgICAgICAgICsgIiAgPCFFTEVNRU5UIGZvbyBBTlk+XG4iCisgICAgICAgICAgICAgICAgKyAiICA8IUFUVExJU1QgZm9vXG4iCisgICAgICAgICAgICAgICAgKyAiICAgIGJhciBDREFUQSBcImFiYyAmYW1wOyBkZWYgJmc7IGprXCI+IgorICAgICAgICAgICAgICAgICsgIl0+IgorICAgICAgICAgICAgICAgICsgIjxmb28+PC9mb28+IjsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKHhtbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgcGFyc2VyLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYWJjICYgZGVmIGdoaSBqayIsIHBhcnNlci5nZXRBdHRyaWJ1dGVWYWx1ZShudWxsLCAiYmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX0RPQ1VNRU5ULCBwYXJzZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXR0cmlidXRlRGVmYXVsdFZhbHVlc0FuZE5hbWVzcGFjZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8IURPQ1RZUEUgZm9vIFtcbiIKKyAgICAgICAgICAgICAgICArICIgIDwhQVRUTElTVCBmb29cbiIKKyAgICAgICAgICAgICAgICArICIgICAgYmFyOmEgQ0RBVEEgXCJhbmRyb2lkXCI+IgorICAgICAgICAgICAgICAgICsgIl0+IgorICAgICAgICAgICAgICAgICsgIjxmb28geG1sbnM6YmFyPSdodHRwOi8vYmFyJz48L2Zvbz4iOworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoeG1sKTsKKyAgICAgICAgcGFyc2VyLnNldEZlYXR1cmUoWG1sUHVsbFBhcnNlci5GRUFUVVJFX1BST0NFU1NfTkFNRVNQQUNFUywgdHJ1ZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgcGFyc2VyLmdldE5hbWUoKSk7CisgICAgICAgIC8vIEluIEV4cGF0LCBuYW1lc3BhY2VzIGRvbid0IGFwcGx5IHRvIGRlZmF1bHQgYXR0cmlidXRlcworICAgICAgICBpbnQgaW5kZXggPSBpbmRleE9mQXR0cmlidXRlV2l0aE5hbWUocGFyc2VyLCAiYmFyOmEiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBwYXJzZXIuZ2V0QXR0cmlidXRlTmFtZXNwYWNlKGluZGV4KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYmFyOmEiLCBwYXJzZXIuZ2V0QXR0cmlidXRlTmFtZShpbmRleCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFuZHJvaWQiLCBwYXJzZXIuZ2V0QXR0cmlidXRlVmFsdWUoaW5kZXgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDREFUQSIsIHBhcnNlci5nZXRBdHRyaWJ1dGVUeXBlKGluZGV4KSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQsIHBhcnNlci5uZXh0KCkpOworICAgIH0KKworICAgIHByaXZhdGUgaW50IGluZGV4T2ZBdHRyaWJ1dGVXaXRoTmFtZShYbWxQdWxsUGFyc2VyIHBhcnNlciwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJzZXIuZ2V0QXR0cmlidXRlQ291bnQoKTsgaSsrKSB7CisgICAgICAgICAgICBpZiAocGFyc2VyLmdldEF0dHJpYnV0ZU5hbWUoaSkuZXF1YWxzKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdHRyaWJ1dGVFbnRpdGllc0V4cGFuZGVkRWFnZXJseSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRQYXJzZUZhaWx1cmUoIjwhRE9DVFlQRSBmb28gW1xuIgorICAgICAgICAgICAgICAgICsgIiAgPCFFTEVNRU5UIGZvbyBBTlk+XG4iCisgICAgICAgICAgICAgICAgKyAiICA8IUFUVExJU1QgZm9vXG4iCisgICAgICAgICAgICAgICAgKyAiICAgIGJhciBDREFUQSBcImFiYyAmYW1wOyBkZWYgJmc7IGprXCI+IgorICAgICAgICAgICAgICAgICsgIiAgPCFFTlRJVFkgZyBcImdoaVwiPiIKKyAgICAgICAgICAgICAgICArICJdPiIKKyAgICAgICAgICAgICAgICArICI8Zm9vPjwvZm9vPiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXF1aXJlZEF0dHJpYnV0ZXNPbWl0dGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB4bWwgPSAiPCFET0NUWVBFIGZvbyBbXG4iCisgICAgICAgICAgICAgICAgKyAiICA8IUVMRU1FTlQgZm9vIEFOWT5cbiIKKyAgICAgICAgICAgICAgICArICIgIDwhQVRUTElTVCBmb29cbiIKKyAgICAgICAgICAgICAgICArICIgICAgYmFyIChhfGJ8YykgI1JFUVVJUkVEPiIKKyAgICAgICAgICAgICAgICArICJdPiIKKyAgICAgICAgICAgICAgICArICI8Zm9vPjwvZm9vPiI7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcih4bWwpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZvbyIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgcGFyc2VyLmdldEF0dHJpYnV0ZVZhbHVlKG51bGwsICJiYXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGaXhlZEF0dHJpYnV0ZXNXaXRoQ29uZmxpY3RpbmdWYWx1ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8IURPQ1RZUEUgZm9vIFtcbiIKKyAgICAgICAgICAgICAgICArICIgIDwhRUxFTUVOVCBmb28gQU5ZPlxuIgorICAgICAgICAgICAgICAgICsgIiAgPCFBVFRMSVNUIGZvb1xuIgorICAgICAgICAgICAgICAgICsgIiAgICBiYXIgKGF8YnxjKSAjRklYRUQgXCJjXCI+IgorICAgICAgICAgICAgICAgICsgIl0+IgorICAgICAgICAgICAgICAgICsgIjxmb28gYmFyPVwiYVwiPjwvZm9vPiI7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcih4bWwpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZvbyIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBwYXJzZXIuZ2V0QXR0cmlidXRlVmFsdWUobnVsbCwgImJhciIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNpbmdOb3RhdGlvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8IURPQ1RZUEUgZm9vIFtcbiIKKyAgICAgICAgICAgICAgICArICIgIDwhTk9UQVRJT04gdHlwZS1hIFBVQkxJQyBcImFwcGxpY2F0aW9uL2FcIj4gXG4iCisgICAgICAgICAgICAgICAgKyAiICA8IU5PVEFUSU9OIHR5cGUtYiBQVUJMSUMgXCJpbWFnZS9iXCI+XG4iCisgICAgICAgICAgICAgICAgKyAiICA8IU5PVEFUSU9OIHR5cGUtYyBQVUJMSUMgXCItLy9XM0MvL0RURCBTVkcgMS4xLy9FTlwiXG4iCisgICAgICAgICAgICAgICAgKyAiICAgICBcImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZFwiPiBcbiIKKyAgICAgICAgICAgICAgICArICIgIDwhRU5USVRZIGZpbGUgICAgICAgICAgU1lTVEVNIFwiZC54bWxcIj5cbiIKKyAgICAgICAgICAgICAgICArICIgIDwhRU5USVRZIGZpbGVXaXRoTmRhdGEgU1lTVEVNIFwiZS5iaW5cIiBOREFUQSB0eXBlLWI+XG4iCisgICAgICAgICAgICAgICAgKyAiXT4iCisgICAgICAgICAgICAgICAgKyAiPGZvbyB0eXBlPVwidHlwZS1hXCIvPiI7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcih4bWwpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZvbyIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29tbWVudHNJbkRvY3R5cGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8IURPQ1RZUEUgZm9vIFsiCisgICAgICAgICAgICAgICAgKyAiICA8IS0tICcgLS0+IgorICAgICAgICAgICAgICAgICsgIl0+PGZvbz5hbmRyb2lkPC9mb28+IjsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKHhtbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFuZHJvaWQiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgcGFyc2VyLm5leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERvY3R5cGVOYW1lT25seSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgeG1sID0gIjwhRE9DVFlQRSBmb28+PGZvbz48L2Zvbz4iOworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoeG1sKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgcGFyc2VyLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgcGFyc2VyLm5leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFZlcnlMb25nRW50aXRpZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGEgPSByZXBlYXQoJ2EnLCBSRUFEX0JVRkZFUl9TSVpFICsgMSk7CisgICAgICAgIFN0cmluZyBiID0gcmVwZWF0KCdiJywgUkVBRF9CVUZGRVJfU0laRSArIDEpOworICAgICAgICBTdHJpbmcgYyA9IHJlcGVhdCgnYycsIFJFQURfQlVGRkVSX1NJWkUgKyAxKTsKKworICAgICAgICBTdHJpbmcgeG1sID0gIjwhRE9DVFlQRSBmb28gW1xuIgorICAgICAgICAgICAgICAgICsgIiAgPCFFTlRJVFkgIiArIGEgKyAiICBcImQgJiIgKyBiICsgIjsgZVwiPiIKKyAgICAgICAgICAgICAgICArICIgIDwhRU5USVRZICIgKyBiICsgIiAgXCJmICIgKyBjICsgIiBnXCI+IgorICAgICAgICAgICAgICAgICsgIl0+IgorICAgICAgICAgICAgICAgICsgIjxmb28+aCAmIiArIGEgKyAiOyBpPC9mb28+IjsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKHhtbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImggZCBmICIgKyBjICsgIiBnIGUgaSIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX0RPQ1VNRU5ULCBwYXJzZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFudWFsbHlSZWdpc3RlcmVkRW50aXRpZXNXaXRoRG9jdHlwZVBhcnNpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8Zm9vPiZhOzwvZm9vPiI7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcih4bWwpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFyc2VyLmRlZmluZUVudGl0eVJlcGxhY2VtZW50VGV4dCgiYSIsICJhbmRyb2lkIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERvY3R5cGVXaXRoTmV4dFRva2VuKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB4bWwgPSAiPCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgYmIgXCJiYXIgYmF6XCI+XT48Zm9vPmEmYmI7YzwvZm9vPiI7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcih4bWwpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5ET0NERUNMLCBwYXJzZXIubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiBmb28gWzwhRU5USVRZIGJiIFwiYmFyIGJhelwiPl0iLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5URVhULCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhYmFyIGJhemMiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgcGFyc2VyLm5leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERvY3R5cGVTcGFuc0J1ZmZlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhcltdIGRvY3R5cGVDaGFycyA9IG5ldyBjaGFyW1JFQURfQlVGRkVSX1NJWkUgKyAxXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZG9jdHlwZUNoYXJzLCAneCcpOworICAgICAgICBTdHJpbmcgZG9jdHlwZUJvZHkgPSAiIGZvbyBbPCEtLSIgKyBuZXcgU3RyaW5nKGRvY3R5cGVDaGFycykgKyAiLS0+XSI7CisgICAgICAgIFN0cmluZyB4bWwgPSAiPCFET0NUWVBFIiArIGRvY3R5cGVCb2R5ICsgIj48Zm9vLz4iOworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoeG1sKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRE9DREVDTCwgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGRvY3R5cGVCb2R5LCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgcGFyc2VyLm5leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERvY3R5cGVJbkRvY3VtZW50RWxlbWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRQYXJzZUZhaWx1cmUoIjxmb28+PCFET0NUWVBFIGZvbz48L2Zvbz4iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RG9jdHlwZUFmdGVyRG9jdW1lbnRFbGVtZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFBhcnNlRmFpbHVyZSgiPGZvby8+PCFET0NUWVBFIGZvbz4iKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0UGFyc2VGYWlsdXJlKFN0cmluZyB4bWwpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBTdHJpbmdSZWFkZXIoeG1sKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3aGlsZSAocGFyc2VyLm5leHQoKSAhPSBYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyByZXBlYXQoY2hhciBjLCBpbnQgbGVuZ3RoKSB7CisgICAgICAgIGNoYXJbXSBjaGFycyA9IG5ldyBjaGFyW2xlbmd0aF07CisgICAgICAgIEFycmF5cy5maWxsKGNoYXJzLCBjKTsKKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoY2hhcnMpOworICAgIH0KKworICAgIHByaXZhdGUgWG1sUHVsbFBhcnNlciBuZXdQdWxsUGFyc2VyKFN0cmluZyB4bWwpIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciByZXN1bHQgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHJlc3VsdC5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKHhtbCkpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgcHVsbCBwYXJzZXIuCisgICAgICovCisgICAgYWJzdHJhY3QgWG1sUHVsbFBhcnNlciBuZXdQdWxsUGFyc2VyKCkgdGhyb3dzIFhtbFB1bGxQYXJzZXJFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS94bWwvUHVsbFBhcnNlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3htbC9QdWxsUGFyc2VyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhMDBmZTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS94bWwvUHVsbFBhcnNlclRlc3QuamF2YQpAQCAtMCwwICsxLDczOCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS54bWw7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBvcmcueG1scHVsbC52MS5YbWxQdWxsUGFyc2VyOworaW1wb3J0IG9yZy54bWxwdWxsLnYxLlhtbFB1bGxQYXJzZXJFeGNlcHRpb247CisKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBQdWxsUGFyc2VyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdHRyaWJ1dGVOb1ZhbHVlV2l0aFJlbGF4ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRGZWF0dXJlKCJodHRwOi8veG1scHVsbC5vcmcvdjEvZG9jL2ZlYXR1cmVzLmh0bWwjcmVsYXhlZCIsIHRydWUpOworICAgICAgICBwYXJzZXIuc2V0SW5wdXQobmV3IFN0cmluZ1JlYWRlcigiPGlucHV0IGNoZWNrZWQ+PC9pbnB1dD4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5wdXQiLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjaGVja2VkIiwgcGFyc2VyLmdldEF0dHJpYnV0ZU5hbWUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImNoZWNrZWQiLCBwYXJzZXIuZ2V0QXR0cmlidXRlVmFsdWUoMCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdHRyaWJ1dGVVbnF1b3RlZFZhbHVlV2l0aFJlbGF4ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRGZWF0dXJlKCJodHRwOi8veG1scHVsbC5vcmcvdjEvZG9jL2ZlYXR1cmVzLmh0bWwjcmVsYXhlZCIsIHRydWUpOworICAgICAgICBwYXJzZXIuc2V0SW5wdXQobmV3IFN0cmluZ1JlYWRlcigiPGlucHV0IGNoZWNrZWQ9dHJ1ZT48L2lucHV0PiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbnB1dCIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImNoZWNrZWQiLCBwYXJzZXIuZ2V0QXR0cmlidXRlTmFtZSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidHJ1ZSIsIHBhcnNlci5nZXRBdHRyaWJ1dGVWYWx1ZSgwKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFVudGVybWluYXRlZEVudGl0eVdpdGhSZWxheGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcigpOworICAgICAgICBwYXJzZXIuc2V0RmVhdHVyZSgiaHR0cDovL3htbHB1bGwub3JnL3YxL2RvYy9mZWF0dXJlcy5odG1sI3JlbGF4ZWQiLCB0cnVlKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBTdHJpbmdSZWFkZXIoIjxmb28gYmFyPSdBJlcnPm1hYyZjaGVlc2U8L2Zvbz4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgcGFyc2VyLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYmFyIiwgcGFyc2VyLmdldEF0dHJpYnV0ZU5hbWUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkEmVyIsIHBhcnNlci5nZXRBdHRyaWJ1dGVWYWx1ZSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm1hYyZjaGVlc2UiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW50aXRpZXNBbmROYW1lc3BhY2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcigpOworICAgICAgICBwYXJzZXIuc2V0RmVhdHVyZSgiaHR0cDovL3htbHB1bGwub3JnL3YxL2RvYy9mZWF0dXJlcy5odG1sI3Byb2Nlc3MtbmFtZXNwYWNlcyIsIHRydWUpOworICAgICAgICBwYXJzZXIuc2V0SW5wdXQobmV3IFN0cmluZ1JlYWRlcigKKyAgICAgICAgICAgICAgICAiPGZvbzphIHhtbG5zOmZvbz0naHR0cDovL2ZvbycgeG1sbnM6YmFyPSdodHRwOi8vYmFyJz48YmFyOmIvPjwvZm9vOmE+IikpOworICAgICAgICB0ZXN0TmFtZXNwYWNlKHBhcnNlcik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVudGl0aWVzQW5kTmFtZXNwYWNlc1dpdGhSZWxheGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcigpOworICAgICAgICBwYXJzZXIuc2V0RmVhdHVyZSgiaHR0cDovL3htbHB1bGwub3JnL3YxL2RvYy9mZWF0dXJlcy5odG1sI3Byb2Nlc3MtbmFtZXNwYWNlcyIsIHRydWUpOworICAgICAgICBwYXJzZXIuc2V0RmVhdHVyZSgiaHR0cDovL3htbHB1bGwub3JnL3YxL2RvYy9mZWF0dXJlcy5odG1sI3JlbGF4ZWQiLCB0cnVlKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBTdHJpbmdSZWFkZXIoCisgICAgICAgICAgICAgICAgIjxmb286YSB4bWxuczpmb289J2h0dHA6Ly9mb28nIHhtbG5zOmJhcj0naHR0cDovL2Jhcic+PGJhcjpiLz48L2ZvbzphPiIpKTsKKyAgICAgICAgdGVzdE5hbWVzcGFjZShwYXJzZXIpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0TmFtZXNwYWNlKFhtbFB1bGxQYXJzZXIgcGFyc2VyKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vZm9vIiwgcGFyc2VyLmdldE5hbWVzcGFjZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgcGFyc2VyLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL2JhciIsIHBhcnNlci5nZXROYW1lc3BhY2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYiIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vYmFyIiwgcGFyc2VyLmdldE5hbWVzcGFjZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiIiwgcGFyc2VyLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9mb28iLCBwYXJzZXIuZ2V0TmFtZXNwYWNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVndWxhck51bWVyaWNFbnRpdGllcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBTdHJpbmdSZWFkZXIoIjxmb28+JiM2NTs8L2Zvbz4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVOVElUWV9SRUYsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIzY1IiwgcGFyc2VyLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROdW1lcmljRW50aXRpZXNMYXJnZXJUaGFuQ2hhcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRQYXJzZUZhaWx1cmUoIjxmb28+JiMyMTQ3NDgzNjQ3OyAmIy0yMTQ3NDgzNjQ4OzwvZm9vPiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROdW1lcmljRW50aXRpZXNMYXJnZXJUaGFuSW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFBhcnNlRmFpbHVyZSgiPGZvbz4mIzIxNDc0ODM2NDg7PC9mb28+Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENoYXJhY3RlclJlZmVyZW5jZU9mSGV4VXRmMTZTdXJyb2dhdGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RDaGFyYWN0ZXJSZWZlcmVuY2VPZlV0ZjE2U3Vycm9nYXRlcygiPGZvbz4mI3gxMDAwMDsgJiN4MTAzODE7ICYjeDEwRkZGMDs8L2Zvbz4iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2hhcmFjdGVyUmVmZXJlbmNlT2ZEZWNpbWFsVXRmMTZTdXJyb2dhdGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RDaGFyYWN0ZXJSZWZlcmVuY2VPZlV0ZjE2U3Vycm9nYXRlcygiPGZvbz4mIzY1NTM2OyAmIzY2NDMzOyAmIzExMTQwOTY7PC9mb28+Iik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RDaGFyYWN0ZXJSZWZlcmVuY2VPZlV0ZjE2U3Vycm9nYXRlcyhTdHJpbmcgeG1sKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKHhtbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5URVhULCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBTdHJpbmcobmV3IGludFtdezY1NTM2LCAnICcsIDY2NDMzLCAnICcsIDExMTQwOTZ9LCAwLCA1KSwKKyAgICAgICAgICAgICAgICBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENoYXJhY3RlclJlZmVyZW5jZU9mTGFzdFV0ZjE2U3Vycm9nYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcigpOworICAgICAgICBwYXJzZXIuc2V0SW5wdXQobmV3IFN0cmluZ1JlYWRlcigiPGZvbz4mI3gxMEZGRkY7PC9mb28+IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5URVhULCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBTdHJpbmcobmV3IGludFtdezB4MTBGRkZGfSwgMCwgMSksIHBhcnNlci5nZXRUZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0T21pdHRlZE51bWVyaWNFbnRpdGllcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRQYXJzZUZhaWx1cmUoIjxmb28+JiM7PC9mb28+Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FycmlhZ2UgcmV0dXJucyBmb2xsb3dlZCBieSBsaW5lIGZlZWRzIGFyZSBzaWxlbnRseSBkaXNjYXJkZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENhcnJpYWdlUmV0dXJuTGluZUZlZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdExpbmVFbmRpbmdzKCJcclxuPGZvb1xyXG5hPSdiXHJcbmMnXHJcbj5kXHJcbmU8L2Zvb1xyXG4+XHJcbiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvbmUgY2FycmlhZ2UgcmV0dXJucyBhcmUgdHJlYXRlZCBsaWtlIG5ld2xpbmVzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RMb25lQ2FycmlhZ2VSZXR1cm4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdExpbmVFbmRpbmdzKCJccjxmb29ccmE9J2JccmMnXHI+ZFxyZTwvZm9vXHI+XHIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9uZU5ld0xpbmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdExpbmVFbmRpbmdzKCJcbjxmb29cbmE9J2JcbmMnXG4+ZFxuZTwvZm9vXG4+XG4iKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdExpbmVFbmRpbmdzKFN0cmluZyB4bWwpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBTdHJpbmdSZWFkZXIoeG1sKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgcGFyc2VyLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYiBjIiwgcGFyc2VyLmdldEF0dHJpYnV0ZVZhbHVlKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuVEVYVCwgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZFxuZSIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX0RPQ1VNRU5ULCBwYXJzZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0WG1sRGVjbGFyYXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKAorICAgICAgICAgICAgICAgICI8P3htbCB2ZXJzaW9uPScxLjAnIGVuY29kaW5nPSdVVEYtOCcgc3RhbmRhbG9uZT0nbm8nPz48Zm9vLz4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxLjAiLCBwYXJzZXIuZ2V0UHJvcGVydHkoCisgICAgICAgICAgICAgICAgImh0dHA6Ly94bWxwdWxsLm9yZy92MS9kb2MvcHJvcGVydGllcy5odG1sI3htbGRlY2wtdmVyc2lvbiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJvb2xlYW4uRkFMU0UsIHBhcnNlci5nZXRQcm9wZXJ0eSgKKyAgICAgICAgICAgICAgICAiaHR0cDovL3htbHB1bGwub3JnL3YxL2RvYy9wcm9wZXJ0aWVzLmh0bWwjeG1sZGVjbC1zdGFuZGFsb25lIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlVURi04IiwgcGFyc2VyLmdldElucHV0RW5jb2RpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFhtbERlY2xhcmF0aW9uRXh0cmFBdHRyaWJ1dGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFBhcnNlRmFpbHVyZSgiPD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnIHN0YW5kYWxvbmU9J25vJyBhPSdiJz8+PGZvby8+Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEN1c3RvbUVudGl0aWVzVXNpbmdOZXh0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcigpOworICAgICAgICBwYXJzZXIuc2V0SW5wdXQobmV3IFN0cmluZ1JlYWRlcigKKyAgICAgICAgICAgICAgICAiPGZvbyBhPSdjZCZhYWFhYWFhYWFhO2VmJz53eCZhYWFhYWFhYWFhO3l6PC9mb28+IikpOworICAgICAgICBwYXJzZXIuZGVmaW5lRW50aXR5UmVwbGFjZW1lbnRUZXh0KCJhYWFhYWFhYWFhIiwgImIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjZGJlZiIsIHBhcnNlci5nZXRBdHRyaWJ1dGVWYWx1ZSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInd4Ynl6IiwgcGFyc2VyLmdldFRleHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEN1c3RvbUVudGl0aWVzVXNpbmdOZXh0VG9rZW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKAorICAgICAgICAgICAgICAgICI8Zm9vIGE9J2NkJmFhYWFhYWFhYWE7ZWYnPnd4JmFhYWFhYWFhYWE7eXo8L2Zvbz4iKSk7CisgICAgICAgIHBhcnNlci5kZWZpbmVFbnRpdHlSZXBsYWNlbWVudFRleHQoImFhYWFhYWFhYWEiLCAiYiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiY2RiZWYiLCBwYXJzZXIuZ2V0QXR0cmlidXRlVmFsdWUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5URVhULCBwYXJzZXIubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInd4IiwgcGFyc2VyLmdldFRleHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVOVElUWV9SRUYsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYWFhYWFhYWFhYSIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImIiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuVEVYVCwgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ5eiIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDdXN0b21FbnRpdGllc0FyZU5vdEV2YWx1YXRlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBTdHJpbmdSZWFkZXIoCisgICAgICAgICAgICAgICAgIjxmb28gYT0nJmE7Jz4mYTs8L2Zvbz4iKSk7CisgICAgICAgIHBhcnNlci5kZWZpbmVFbnRpdHlSZXBsYWNlbWVudFRleHQoImEiLCAiJmFtcDsgJmE7Iik7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiJmFtcDsgJmE7IiwgcGFyc2VyLmdldEF0dHJpYnV0ZVZhbHVlKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuVEVYVCwgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiJmFtcDsgJmE7IiwgcGFyc2VyLmdldFRleHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1pc3NpbmdFbnRpdGllcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRQYXJzZUZhaWx1cmUoIjxmb28+JmFhYTs8L2Zvbz4iKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWlzc2luZ0VudGl0aWVzV2l0aFJlbGF4ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRGZWF0dXJlKCJodHRwOi8veG1scHVsbC5vcmcvdjEvZG9jL2ZlYXR1cmVzLmh0bWwjcmVsYXhlZCIsIHRydWUpOworICAgICAgICBwYXJzZXIuc2V0SW5wdXQobmV3IFN0cmluZ1JlYWRlcigiPGZvbz4mYWFhOzwvZm9vPiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuVEVYVCwgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJFeHBlY3RlZCB1bnJlc29sdmVkIGVudGl0aWVzIHRvIGJlIGxlZnQgaW4tcGxhY2UuIFRoZSBvbGQgcGFyc2VyICIKKyAgICAgICAgICAgICAgICArICJ3b3VsZCByZXNvbHZlIHRoZXNlIHRvIHRoZSBlbXB0eSBzdHJpbmcuIiwgIiZhYWE7IiwgcGFyc2VyLmdldFRleHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNaXNzaW5nRW50aXRpZXNVc2luZ05leHRUb2tlbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgdGVzdE1pc3NpbmdFbnRpdGllc1VzaW5nTmV4dFRva2VuKHBhcnNlcik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1pc3NpbmdFbnRpdGllc1VzaW5nTmV4dFRva2VuV2l0aFJlbGF4ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRGZWF0dXJlKCJodHRwOi8veG1scHVsbC5vcmcvdjEvZG9jL2ZlYXR1cmVzLmh0bWwjcmVsYXhlZCIsIHRydWUpOworICAgICAgICB0ZXN0TWlzc2luZ0VudGl0aWVzVXNpbmdOZXh0VG9rZW4ocGFyc2VyKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdE1pc3NpbmdFbnRpdGllc1VzaW5nTmV4dFRva2VuKFhtbFB1bGxQYXJzZXIgcGFyc2VyKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBTdHJpbmdSZWFkZXIoIjxmb28+JmFhYTs8L2Zvbz4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5USVRZX1JFRiwgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhYWEiLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHBhcnNlci5nZXRUZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW50aXR5SW5BdHRyaWJ1dGVVc2luZ05leHRUb2tlbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBTdHJpbmdSZWFkZXIoIjxmb28gYmFyPVwiJmFtcDtcIj48L2Zvbz4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCImIiwgcGFyc2VyLmdldEF0dHJpYnV0ZVZhbHVlKG51bGwsICJiYXIiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1pc3NpbmdFbnRpdGllc0luQXR0cmlidXRlc1VzaW5nTmV4dCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRQYXJzZUZhaWx1cmUoIjxmb28gYj0nJmFhYTsnPjwvZm9vPiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNaXNzaW5nRW50aXRpZXNJbkF0dHJpYnV0ZXNVc2luZ05leHRXaXRoUmVsYXhlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBTdHJpbmdSZWFkZXIoIjxmb28gYj0nJmFhYTsnPjwvZm9vPiIpKTsKKyAgICAgICAgcGFyc2VyLnNldEZlYXR1cmUoImh0dHA6Ly94bWxwdWxsLm9yZy92MS9kb2MvZmVhdHVyZXMuaHRtbCNyZWxheGVkIiwgdHJ1ZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHBhcnNlci5nZXRBdHRyaWJ1dGVDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiIiwgcGFyc2VyLmdldEF0dHJpYnV0ZU5hbWUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkV4cGVjdGVkIHVucmVzb2x2ZWQgZW50aXRpZXMgdG8gYmUgbGVmdCBpbi1wbGFjZS4gVGhlIG9sZCBwYXJzZXIgIgorICAgICAgICAgICAgICAgICsgIndvdWxkIHJlc29sdmUgdGhlc2UgdG8gdGhlIGVtcHR5IHN0cmluZy4iLCAiJmFhYTsiLCBwYXJzZXIuZ2V0QXR0cmlidXRlVmFsdWUoMCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNaXNzaW5nRW50aXRpZXNJbkF0dHJpYnV0ZXNVc2luZ05leHRUb2tlbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBTdHJpbmdSZWFkZXIoIjxmb28gYj0nJmFhYTsnPjwvZm9vPiIpKTsKKyAgICAgICAgdGVzdE1pc3NpbmdFbnRpdGllc0luQXR0cmlidXRlc1VzaW5nTmV4dFRva2VuKHBhcnNlcik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1pc3NpbmdFbnRpdGllc0luQXR0cmlidXRlc1VzaW5nTmV4dFRva2VuV2l0aFJlbGF4ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKCI8Zm9vIGI9JyZhYWE7Jz48L2Zvbz4iKSk7CisgICAgICAgIHBhcnNlci5zZXRGZWF0dXJlKCJodHRwOi8veG1scHVsbC5vcmcvdjEvZG9jL2ZlYXR1cmVzLmh0bWwjcmVsYXhlZCIsIHRydWUpOworICAgICAgICB0ZXN0TWlzc2luZ0VudGl0aWVzSW5BdHRyaWJ1dGVzVXNpbmdOZXh0VG9rZW4ocGFyc2VyKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdE1pc3NpbmdFbnRpdGllc0luQXR0cmlidXRlc1VzaW5nTmV4dFRva2VuKFhtbFB1bGxQYXJzZXIgcGFyc2VyKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHBhcnNlci5nZXRBdHRyaWJ1dGVDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiIiwgcGFyc2VyLmdldEF0dHJpYnV0ZU5hbWUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkV4cGVjdGVkIHVucmVzb2x2ZWQgZW50aXRpZXMgdG8gYmUgbGVmdCBpbi1wbGFjZS4gVGhlIG9sZCBwYXJzZXIgIgorICAgICAgICAgICAgICAgICsgIndvdWxkIHJlc29sdmUgdGhlc2UgdG8gdGhlIGVtcHR5IHN0cmluZy4iLCAiJmFhYTsiLCBwYXJzZXIuZ2V0QXR0cmlidXRlVmFsdWUoMCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHcmVhdGVyVGhhbkluVGV4dCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBTdHJpbmdSZWFkZXIoIjxmb28+PjwvZm9vPiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuVEVYVCwgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiPiIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHcmVhdGVyVGhhbkluQXR0cmlidXRlKCkgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKCI8Zm9vIGE9Jz4nPjwvZm9vPiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI+IiwgcGFyc2VyLmdldEF0dHJpYnV0ZVZhbHVlKDApKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TGVzc1RoYW5JblRleHQoKSB0aHJvd3MgRXhjZXB0aW9ueworICAgICAgICBhc3NlcnRQYXJzZUZhaWx1cmUoIjxmb28+PDwvZm9vPiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RMZXNzVGhhbkluQXR0cmlidXRlKCkgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICAgICAgYXNzZXJ0UGFyc2VGYWlsdXJlKCI8Zm9vIGE9JzwnPjwvZm9vPiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RRdW90ZXNJbkF0dHJpYnV0ZSgpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcigpOworICAgICAgICBwYXJzZXIuc2V0SW5wdXQobmV3IFN0cmluZ1JlYWRlcigiPGZvbyBhPSdcIicgYj1cIidcIj48L2Zvbz4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiXCIiLCBwYXJzZXIuZ2V0QXR0cmlidXRlVmFsdWUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiciLCBwYXJzZXIuZ2V0QXR0cmlidXRlVmFsdWUoMSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RRdW90ZXNJblRleHQoKSB0aHJvd3MgRXhjZXB0aW9ueworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBTdHJpbmdSZWFkZXIoIjxmb28+XCIgJzwvZm9vPiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuVEVYVCwgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiXCIgJyIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDZGF0YURlbGltaXRlckluQXR0cmlidXRlKCkgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKCI8Zm9vIGE9J11dPic+PC9mb28+IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIl1dPiIsIHBhcnNlci5nZXRBdHRyaWJ1dGVWYWx1ZSgwKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENkYXRhRGVsaW1pdGVySW5UZXh0KCkgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICAgICAgYXNzZXJ0UGFyc2VGYWlsdXJlKCI8Zm9vPl1dPjwvZm9vPiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVbmV4cGVjdGVkRW9mKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFBhcnNlRmFpbHVyZSgiPGZvbz48IVtDIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFVuZXhwZWN0ZWRTZXF1ZW5jZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRQYXJzZUZhaWx1cmUoIjxmb28+PCFbQ2RhdGFbYmFyXV0+PC9mb28+Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRocmVlRGFzaENvbW1lbnREZWxpbWl0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UGFyc2VGYWlsdXJlKCI8Zm9vPjwhLS1hLS0tPjwvZm9vPiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUd29EYXNoZXNJbkNvbW1lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UGFyc2VGYWlsdXJlKCI8Zm9vPjwhLS0gLS0gLS0+PC9mb28+Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVtcHR5Q29tbWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBTdHJpbmdSZWFkZXIoIjxmb28+PCEtLS0tPjwvZm9vPiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuQ09NTUVOVCwgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZSBicmFjZXMgcmVxdWlyZSBsb29rYWhlYWRzIGJlY2F1c2Ugd2UgbmVlZCB0byBkZWZlbmQgYWdhaW5zdCAiXV0+Ii4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFueUNsb3NlQnJhY2VzKCkgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKCI8Zm9vPl1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dPC9mb28+IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5URVhULCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJdXV1dXV1dXV1dXV1dXV1dXV1dXV1dXSIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb21tZW50VXNpbmdOZXh0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcigpOworICAgICAgICBwYXJzZXIuc2V0SW5wdXQobmV3IFN0cmluZ1JlYWRlcigiPGZvbz5hYjwhLS0gY29tbWVudCEgLS0+Y2Q8L2Zvbz4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFiY2QiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29tbWVudFVzaW5nTmV4dFRva2VuKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcigpOworICAgICAgICBwYXJzZXIuc2V0SW5wdXQobmV3IFN0cmluZ1JlYWRlcigiPGZvbz5hYjwhLS0gY29tbWVudCEgLS0+Y2Q8L2Zvbz4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYWIiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuQ09NTUVOVCwgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIgY29tbWVudCEgIiwgcGFyc2VyLmdldFRleHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiY2QiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2RhdGFVc2luZ05leHQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKCI8Zm9vPmFiPCFbQ0RBVEFbY2RlZl1dZ2gmYW1wO2ldXT5qazwvZm9vPiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuVEVYVCwgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYWJjZGVmXV1naCZhbXA7aWprIiwgcGFyc2VyLmdldFRleHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDZGF0YVVzaW5nTmV4dFRva2VuKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcigpOworICAgICAgICBwYXJzZXIuc2V0SW5wdXQobmV3IFN0cmluZ1JlYWRlcigiPGZvbz5hYjwhW0NEQVRBW2NkZWZdXWdoJmFtcDtpXV0+ams8L2Zvbz4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYWIiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuQ0RTRUNULCBwYXJzZXIubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImNkZWZdXWdoJmFtcDtpIiwgcGFyc2VyLmdldFRleHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiamsiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW50aXR5TG9va3NMaWtlQ2RhdGFDbG9zZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBTdHJpbmdSZWFkZXIoIjxmb28+JiM5MzsmIzkzOz48L2Zvbz4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIl1dPiIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25Vc2luZ05leHQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKCI8Zm9vPmFiPD9jZCBlZmcgaGlqPz5rbDwvZm9vPiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuVEVYVCwgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYWJrbCIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJvY2Vzc2luZ0luc3RydWN0aW9uVXNpbmdOZXh0VG9rZW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKCI8Zm9vPmFiPD9jZCBlZmcgaGlqPz5rbDwvZm9vPiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5URVhULCBwYXJzZXIubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFiIiwgcGFyc2VyLmdldFRleHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlBST0NFU1NJTkdfSU5TVFJVQ1RJT04sIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiY2QgZWZnIGhpaiIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5URVhULCBwYXJzZXIubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImtsIiwgcGFyc2VyLmdldFRleHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RXaGl0ZXNwYWNlVXNpbmdOZXh0VG9rZW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKCIgIFxuICA8Zm9vPiBcbiA8L2Zvbz4gICBcbiAgICIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuSUdOT1JBQkxFX1dISVRFU1BBQ0UsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBwYXJzZXIuaXNXaGl0ZXNwYWNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiAgXG4gICIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBwYXJzZXIuaXNXaGl0ZXNwYWNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiBcbiAiLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuSUdOT1JBQkxFX1dISVRFU1BBQ0UsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBwYXJzZXIuaXNXaGl0ZXNwYWNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiAgIFxuICAgIiwgcGFyc2VyLmdldFRleHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TGluZXNBbmRDb2x1bW5zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcigpOworICAgICAgICBwYXJzZXIuc2V0SW5wdXQobmV3IFN0cmluZ1JlYWRlcigiXG4iCisgICAgICAgICAgICAgICAgKyAiICA8Zm9vPjxiYXIgYT0nXG4iCisgICAgICAgICAgICAgICAgKyAiJyBiPSdjZGUnPjwvYmFyXG4iCisgICAgICAgICAgICAgICAgKyAiPjwhLS1cbiIKKyAgICAgICAgICAgICAgICArICJcbiIKKyAgICAgICAgICAgICAgICArICItLT48YmF6Lz5mZ1xuIgorICAgICAgICAgICAgICAgICsgIjwvZm9vPiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxLDEiLCBwYXJzZXIuZ2V0TGluZU51bWJlcigpICsgIiwiICsgcGFyc2VyLmdldENvbHVtbk51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuSUdOT1JBQkxFX1dISVRFU1BBQ0UsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMiwzIiwgcGFyc2VyLmdldExpbmVOdW1iZXIoKSArICIsIiArIHBhcnNlci5nZXRDb2x1bW5OdW1iZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIyLDgiLCBwYXJzZXIuZ2V0TGluZU51bWJlcigpICsgIiwiICsgcGFyc2VyLmdldENvbHVtbk51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjMsMTEiLCBwYXJzZXIuZ2V0TGluZU51bWJlcigpICsgIiwiICsgcGFyc2VyLmdldENvbHVtbk51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI0LDIiLCBwYXJzZXIuZ2V0TGluZU51bWJlcigpICsgIiwiICsgcGFyc2VyLmdldENvbHVtbk51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuQ09NTUVOVCwgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI2LDQiLCBwYXJzZXIuZ2V0TGluZU51bWJlcigpICsgIiwiICsgcGFyc2VyLmdldENvbHVtbk51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjYsMTAiLCBwYXJzZXIuZ2V0TGluZU51bWJlcigpICsgIiwiICsgcGFyc2VyLmdldENvbHVtbk51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI2LDEwIiwgcGFyc2VyLmdldExpbmVOdW1iZXIoKSArICIsIiArIHBhcnNlci5nZXRDb2x1bW5OdW1iZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlRFWFQsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiNywxIiwgcGFyc2VyLmdldExpbmVOdW1iZXIoKSArICIsIiArIHBhcnNlci5nZXRDb2x1bW5OdW1iZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9UQUcsIHBhcnNlci5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiNyw3IiwgcGFyc2VyLmdldExpbmVOdW1iZXIoKSArICIsIiArIHBhcnNlci5nZXRDb2x1bW5OdW1iZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI3LDciLCBwYXJzZXIuZ2V0TGluZU51bWJlcigpICsgIiwiICsgcGFyc2VyLmdldENvbHVtbk51bWJlcigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW1wdHlFbnRpdHlSZWZlcmVuY2VVc2luZ05leHQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKCI8Zm9vPiZlbXB0eTs8L2Zvbz4iKSk7CisgICAgICAgIHBhcnNlci5kZWZpbmVFbnRpdHlSZXBsYWNlbWVudFRleHQoImVtcHR5IiwgIiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW1wdHlFbnRpdHlSZWZlcmVuY2VVc2luZ05leHRUb2tlbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBTdHJpbmdSZWFkZXIoIjxmb28+JmVtcHR5OzwvZm9vPiIpKTsKKyAgICAgICAgcGFyc2VyLmRlZmluZUVudGl0eVJlcGxhY2VtZW50VGV4dCgiZW1wdHkiLCAiIik7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5USVRZX1JFRiwgcGFyc2VyLm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbXB0eSIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dFRva2VuKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eUNkYXRhVXNpbmdOZXh0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFhtbFB1bGxQYXJzZXIgcGFyc2VyID0gbmV3UHVsbFBhcnNlcigpOworICAgICAgICBwYXJzZXIuc2V0SW5wdXQobmV3IFN0cmluZ1JlYWRlcigiPGZvbz48IVtDREFUQVtdXT48L2Zvbz4iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9UQUcsIHBhcnNlci5uZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eUNkYXRhVXNpbmdOZXh0VG9rZW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKCI8Zm9vPjwhW0NEQVRBW11dPjwvZm9vPiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuQ0RTRUNULCBwYXJzZXIubmV4dFRva2VuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHBhcnNlci5nZXRUZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VSZWFkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHNuaXBwZXQgPSAiPGRhZ255IGRhZD1cImJvYlwiPmhlbGxvPC9kYWdueT4iOworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldEZlYXR1cmUoWG1sUHVsbFBhcnNlci5GRUFUVVJFX1BST0NFU1NfTkFNRVNQQUNFUywgZmFsc2UpOworICAgICAgICBwYXJzZXIuc2V0SW5wdXQobmV3IFN0cmluZ1JlYWRlcihzbmlwcGV0KSk7CisgICAgICAgIHZhbGlkYXRlKHBhcnNlcik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlSW5wdXRTdHJlYW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHNuaXBwZXQgPSAiPGRhZ255IGRhZD1cImJvYlwiPmhlbGxvPC9kYWdueT4iOworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldEZlYXR1cmUoWG1sUHVsbFBhcnNlci5GRUFUVVJFX1BST0NFU1NfTkFNRVNQQUNFUywgZmFsc2UpOworICAgICAgICBwYXJzZXIuc2V0SW5wdXQobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHNuaXBwZXQuZ2V0Qnl0ZXMoKSksICJVVEYtOCIpOworICAgICAgICB2YWxpZGF0ZShwYXJzZXIpOworICAgIH0KKworICAgIHN0YXRpYyB2b2lkIHZhbGlkYXRlKFhtbFB1bGxQYXJzZXIgcGFyc2VyKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfRE9DVU1FTlQsIHBhcnNlci5nZXRFdmVudFR5cGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBwYXJzZXIuZ2V0RGVwdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBwYXJzZXIuZ2V0RGVwdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZGFnbnkiLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHBhcnNlci5nZXRBdHRyaWJ1dGVDb3VudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkYWQiLCBwYXJzZXIuZ2V0QXR0cmlidXRlTmFtZSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYm9iIiwgcGFyc2VyLmdldEF0dHJpYnV0ZVZhbHVlKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJib2IiLCBwYXJzZXIuZ2V0QXR0cmlidXRlVmFsdWUobnVsbCwgImRhZCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuVEVYVCwgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBwYXJzZXIuZ2V0RGVwdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaGVsbG8iLCBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBwYXJzZXIuZ2V0RGVwdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZGFnbnkiLCBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX0RPQ1VNRU5ULCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHBhcnNlci5nZXREZXB0aCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV4dEFmdGVyRW5kRG9jdW1lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKCI8Zm9vPjwvZm9vPiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLkVORF9ET0NVTUVOVCwgcGFyc2VyLm5leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5hbWVzcGFjZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHhtbCA9ICI8b25lIHhtbG5zPSduczpkZWZhdWx0JyB4bWxuczpuMT0nbnM6MScgYT0nYic+XG4iCisgICAgICAgICAgICAgICAgKyAiICA8bjE6dHdvIGM9J2QnIG4xOmU9J2YnIHhtbG5zOm4yPSduczoyJz50ZXh0PC9uMTp0d28+XG4iCisgICAgICAgICAgICAgICAgKyAiPC9vbmU+IjsKKworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldEZlYXR1cmUoWG1sUHVsbFBhcnNlci5GRUFUVVJFX1BST0NFU1NfTkFNRVNQQUNFUywgdHJ1ZSk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKHhtbCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygwLCBwYXJzZXIuZ2V0RGVwdGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBwYXJzZXIuZ2V0TmFtZXNwYWNlQ291bnQoMCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJzZXIuZ2V0TmFtZXNwYWNlQ291bnQoMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeyAvKiBleHBlY3RlZCAqLyB9CisKKyAgICAgICAgLy8gb25lCisgICAgICAgIGFzc2VydEVxdWFscyhYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRywgcGFyc2VyLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBwYXJzZXIuZ2V0RGVwdGgoKSk7CisKKyAgICAgICAgY2hlY2tOYW1lc3BhY2VzSW5PbmUocGFyc2VyKTsKKworICAgICAgICAvLyBuMTp0d28KKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dFRhZygpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgcGFyc2VyLmdldERlcHRoKCkpOworICAgICAgICBjaGVja05hbWVzcGFjZXNJblR3byhwYXJzZXIpOworCisgICAgICAgIC8vIEJvZHkgb2YgdHdvLgorICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5URVhULCBwYXJzZXIubmV4dCgpKTsKKworICAgICAgICAvLyBFbmQgb2YgdHdvLgorICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dFRhZygpKTsKKworICAgICAgICAvLyBEZXB0aCBzaG91bGQgc3RpbGwgYmUgMi4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHBhcnNlci5nZXREZXB0aCgpKTsKKworICAgICAgICAvLyBXZSBzaG91bGQgc3RpbGwgYmUgYWJsZSB0byBzZWUgdGhlIG5hbWVzcGFjZXMgZnJvbSB0d28uCisgICAgICAgIGNoZWNrTmFtZXNwYWNlc0luVHdvKHBhcnNlcik7CisKKyAgICAgICAgLy8gRW5kIG9mIG9uZS4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX1RBRywgcGFyc2VyLm5leHRUYWcoKSk7CisKKyAgICAgICAgLy8gRGVwdGggc2hvdWxkIGJlIGJhY2sgdG8gMS4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHBhcnNlci5nZXREZXB0aCgpKTsKKworICAgICAgICAvLyBXZSBjYW4gc3RpbGwgc2VlIHRoZSBuYW1lc3BhY2VzIGluIG9uZS4KKyAgICAgICAgY2hlY2tOYW1lc3BhY2VzSW5PbmUocGFyc2VyKTsKKworICAgICAgICAvLyBXZSBzaG91bGRuJ3QgYmUgYWJsZSB0byBzZWUgdGhlIG5hbWVzcGFjZXMgaW4gdHdvIGFueW1vcmUuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJzZXIuZ2V0TmFtZXNwYWNlQ291bnQoMik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeyAvKiBleHBlY3RlZCAqLyB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuRU5EX0RPQ1VNRU5ULCBwYXJzZXIubmV4dCgpKTsKKworICAgICAgICAvLyBXZSBzaG91bGRuJ3QgYmUgYWJsZSB0byBzZWUgdGhlIG5hbWVzcGFjZXMgaW4gb25lIGFueW1vcmUuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJzZXIuZ2V0TmFtZXNwYWNlQ291bnQoMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeyAvKiBleHBlY3RlZCAqLyB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHBhcnNlci5nZXROYW1lc3BhY2VDb3VudCgwKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrTmFtZXNwYWNlc0luT25lKFhtbFB1bGxQYXJzZXIgcGFyc2VyKSB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBwYXJzZXIuZ2V0TmFtZXNwYWNlQ291bnQoMSkpOworCisgICAgICAgIC8vIFByZWZpeCBmb3IgZGVmYXVsdCBuYW1lc3BhY2UgaXMgbnVsbC4KKyAgICAgICAgYXNzZXJ0TnVsbChwYXJzZXIuZ2V0TmFtZXNwYWNlUHJlZml4KDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuczpkZWZhdWx0IiwgcGFyc2VyLmdldE5hbWVzcGFjZVVyaSgwKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuMSIsIHBhcnNlci5nZXROYW1lc3BhY2VQcmVmaXgoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5zOjEiLCBwYXJzZXIuZ2V0TmFtZXNwYWNlVXJpKDEpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIm5zOmRlZmF1bHQiLCBwYXJzZXIuZ2V0TmFtZXNwYWNlKG51bGwpKTsKKworICAgICAgICAvLyBLWE1MIHJldHVybnMgbnVsbC4KKyAgICAgICAgLy8gYXNzZXJ0RXF1YWxzKCJuczpkZWZhdWx0IiwgcGFyc2VyLmdldE5hbWVzcGFjZSgiIikpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja05hbWVzcGFjZXNJblR3byhYbWxQdWxsUGFyc2VyIHBhcnNlcikgdGhyb3dzIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworICAgICAgICAvLyBUaGVzZSBzaG91bGQgc3RpbGwgYmUgdmFsaWQuCisgICAgICAgIGNoZWNrTmFtZXNwYWNlc0luT25lKHBhcnNlcik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHBhcnNlci5nZXROYW1lc3BhY2VDb3VudCgyKSk7CisKKyAgICAgICAgLy8gRGVmYXVsdCBucyBzaG91bGQgc3RpbGwgYmUgaW4gdGhlIHN0YWNrCisgICAgICAgIGFzc2VydE51bGwocGFyc2VyLmdldE5hbWVzcGFjZVByZWZpeCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibnM6ZGVmYXVsdCIsIHBhcnNlci5nZXROYW1lc3BhY2VVcmkoMCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUZXh0QmVmb3JlRG9jdW1lbnRFbGVtZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFBhcnNlRmFpbHVyZSgibm90IHhtbDxmb28vPiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUZXh0QWZ0ZXJEb2N1bWVudEVsZW1lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0UGFyc2VGYWlsdXJlKCI8Zm9vLz5ub3QgeG1sIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFRleHROb0RvY3VtZW50RWxlbWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRQYXJzZUZhaWx1cmUoIm5vdCB4bWwiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qm9tQW5kQnl0ZUlucHV0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSB4bWwgPSAiXHVmZWZmPD94bWwgdmVyc2lvbj0nMS4wJz8+PGlucHV0Lz4iLmdldEJ5dGVzKCJVVEYtOCIpOworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSh4bWwpLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbnB1dCIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbnB1dCIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQsIHBhcnNlci5uZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCb21BbmRCeXRlSW5wdXRXaXRoRXhwbGljaXRDaGFyc2V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSB4bWwgPSAiXHVmZWZmPD94bWwgdmVyc2lvbj0nMS4wJz8+PGlucHV0Lz4iLmdldEJ5dGVzKCJVVEYtOCIpOworICAgICAgICBYbWxQdWxsUGFyc2VyIHBhcnNlciA9IG5ld1B1bGxQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnNldElucHV0KG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSh4bWwpLCAiVVRGLTgiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbnB1dCIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfVEFHLCBwYXJzZXIubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbnB1dCIsIHBhcnNlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQsIHBhcnNlci5uZXh0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCb21BbmRDaGFyYWN0ZXJJbnB1dCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRQYXJzZUZhaWx1cmUoIlx1ZmVmZjw/eG1sIHZlcnNpb249JzEuMCc/PjxpbnB1dC8+Iik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydFBhcnNlRmFpbHVyZShTdHJpbmcgeG1sKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgWG1sUHVsbFBhcnNlciBwYXJzZXIgPSBuZXdQdWxsUGFyc2VyKCk7CisgICAgICAgIHBhcnNlci5zZXRJbnB1dChuZXcgU3RyaW5nUmVhZGVyKHhtbCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgd2hpbGUgKHBhcnNlci5uZXh0KCkgIT0gWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBwdWxsIHBhcnNlci4KKyAgICAgKi8KKyAgICBhYnN0cmFjdCBYbWxQdWxsUGFyc2VyIG5ld1B1bGxQYXJzZXIoKTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3htbC9TYXhUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS94bWwvU2F4VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEwODEwNGQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS94bWwvU2F4VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjc2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLnhtbDsKKworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLktub3duRmFpbHVyZTsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1JlYWRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlcjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5Bc3NlcnRpb25GYWlsZWRFcnJvcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKK2ltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcjsKKworLyoqCisgKiBJbml0aWF0ZSBhbmQgb2JzZXJ2ZSBhIFNBWCBwYXJzZSBzZXNzaW9uLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU2F4VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3ROb1ByZWZpeGVzTm9OYW1lc3BhY2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHBhcnNlKGZhbHNlLCBmYWxzZSwgIjxmb28gYmFyPVwiYmF6XCIvPiIsIG5ldyBEZWZhdWx0SGFuZGxlcigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHFOYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHVyaSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBsb2NhbE5hbWUpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgcU5hbWUpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBhdHRyaWJ1dGVzLmdldExlbmd0aCgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGF0dHJpYnV0ZXMuZ2V0VVJJKDApKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRPbmVPZigiYmFyIiwgIiIsIGF0dHJpYnV0ZXMuZ2V0TG9jYWxOYW1lKDApKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImJhciIsIGF0dHJpYnV0ZXMuZ2V0UU5hbWUoMCkpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKworICAgICAgICBwYXJzZShmYWxzZSwgZmFsc2UsICI8YTpmb28gYTpiYXI9XCJiYXpcIi8+IiwgbmV3IERlZmF1bHRIYW5kbGVyKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLAorICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cmlidXRlcykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiIiwgdXJpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGxvY2FsTmFtZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJhOmZvbyIsIHFOYW1lKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgYXR0cmlidXRlcy5nZXRMZW5ndGgoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBhdHRyaWJ1dGVzLmdldFVSSSgwKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0T25lT2YoImE6YmFyIiwgIiIsIGF0dHJpYnV0ZXMuZ2V0TG9jYWxOYW1lKDApKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImE6YmFyIiwgYXR0cmlidXRlcy5nZXRRTmFtZSgwKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROb1ByZWZpeGVzWWVzTmFtZXNwYWNlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBwYXJzZShmYWxzZSwgdHJ1ZSwgIjxmb28gYmFyPVwiYmF6XCIvPiIsIG5ldyBEZWZhdWx0SGFuZGxlcigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHFOYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHVyaSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBsb2NhbE5hbWUpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgcU5hbWUpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBhdHRyaWJ1dGVzLmdldExlbmd0aCgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGF0dHJpYnV0ZXMuZ2V0VVJJKDApKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImJhciIsIGF0dHJpYnV0ZXMuZ2V0TG9jYWxOYW1lKDApKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImJhciIsIGF0dHJpYnV0ZXMuZ2V0UU5hbWUoMCkpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKworICAgICAgICBwYXJzZShmYWxzZSwgdHJ1ZSwgIjxhOmZvbyBhOmJhcj1cImJhelwiIHhtbG5zOmE9XCJodHRwOi8vcXV1eFwiLz4iLCBuZXcgRGVmYXVsdEhhbmRsZXIoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsCisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxTmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vcXV1eCIsIHVyaSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBsb2NhbE5hbWUpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiYTpmb28iLCBxTmFtZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL3F1dXgiLCBhdHRyaWJ1dGVzLmdldFVSSSgwKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJiYXIiLCBhdHRyaWJ1dGVzLmdldExvY2FsTmFtZSgwKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJhOmJhciIsIGF0dHJpYnV0ZXMuZ2V0UU5hbWUoMCkpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbmRyb2lkJ3MgRXhwYXQtYmFzZWQgU0FYIHBhcnNlciBmYWlscyB0aGlzIHRlc3QgYmVjYXVzZSBFeHBhdCBkb2Vzbid0CisgICAgICogc3VwcGx5IHVzIHdpdGggb3VyIG11Y2ggZGVzaXJlZCB7QGNvZGUgeG1sbnM9Imh0dHA6Ly8uLi4ifSBhdHRyaWJ1dGVzLgorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIk5vIHhtbG5zIGF0dHJpYnV0ZXMgZnJvbSBFeHBhdCIpCisgICAgcHVibGljIHZvaWQgdGVzdFllc1ByZWZpeGVzWWVzTmFtZXNwYWNlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBwYXJzZSh0cnVlLCB0cnVlLCAiPGZvbyBiYXI9XCJiYXpcIi8+IiwgbmV3IERlZmF1bHRIYW5kbGVyKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLAorICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cmlidXRlcykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiIiwgdXJpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImZvbyIsIGxvY2FsTmFtZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBxTmFtZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiIiwgYXR0cmlidXRlcy5nZXRVUkkoMCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiYmFyIiwgYXR0cmlidXRlcy5nZXRMb2NhbE5hbWUoMCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiYmFyIiwgYXR0cmlidXRlcy5nZXRRTmFtZSgwKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworCisgICAgICAgIHBhcnNlKHRydWUsIHRydWUsICI8YTpmb28gYTpiYXI9XCJiYXpcIiB4bWxuczphPVwiaHR0cDovL3F1dXhcIi8+IiwgbmV3IERlZmF1bHRIYW5kbGVyKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLAorICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cmlidXRlcykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL3F1dXgiLCB1cmkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgbG9jYWxOYW1lKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImE6Zm9vIiwgcU5hbWUpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygyLCBhdHRyaWJ1dGVzLmdldExlbmd0aCgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9xdXV4IiwgYXR0cmlidXRlcy5nZXRVUkkoMCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiYmFyIiwgYXR0cmlidXRlcy5nZXRMb2NhbE5hbWUoMCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiYTpiYXIiLCBhdHRyaWJ1dGVzLmdldFFOYW1lKDApKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGF0dHJpYnV0ZXMuZ2V0VVJJKDEpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGF0dHJpYnV0ZXMuZ2V0TG9jYWxOYW1lKDEpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInhtbG5zOmEiLCBhdHRyaWJ1dGVzLmdldFFOYW1lKDEpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFllc1ByZWZpeGVzTm9OYW1lc3BhY2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHBhcnNlKHRydWUsIGZhbHNlLCAiPGZvbyBiYXI9XCJiYXpcIi8+IiwgbmV3IERlZmF1bHRIYW5kbGVyKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLAorICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cmlidXRlcykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiIiwgdXJpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGxvY2FsTmFtZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBxTmFtZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiIiwgYXR0cmlidXRlcy5nZXRVUkkoMCkpOworICAgICAgICAgICAgICAgIGFzc2VydE9uZU9mKCJiYXIiLCAiIiwgYXR0cmlidXRlcy5nZXRMb2NhbE5hbWUoMCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiYmFyIiwgYXR0cmlidXRlcy5nZXRRTmFtZSgwKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworCisgICAgICAgIHBhcnNlKHRydWUsIGZhbHNlLCAiPGE6Zm9vIGE6YmFyPVwiYmF6XCIvPiIsIG5ldyBEZWZhdWx0SGFuZGxlcigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHFOYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHVyaSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBsb2NhbE5hbWUpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiYTpmb28iLCBxTmFtZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiIiwgYXR0cmlidXRlcy5nZXRVUkkoMCkpOworICAgICAgICAgICAgICAgIGFzc2VydE9uZU9mKCJhOmJhciIsICIiLCBhdHRyaWJ1dGVzLmdldExvY2FsTmFtZSgwKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJhOmJhciIsIGF0dHJpYnV0ZXMuZ2V0UU5hbWUoMCkpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgdGhlIGV4dGVybmFsLWdlbmVyYWwtZW50aXRpZXMgZmVhdHVyZSBjYW4gYmUgZGlzYWJsZWQuCisgICAgICogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD05NDkzCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdERpc2FibGVFeHRlcm5hbEdlbmVyYWxFbnRpdGllcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgeG1sID0gIjwhRE9DVFlQRSBmb28gWyIKKyAgICAgICAgICAgICAgICArICIgIDwhRU5USVRZIGJhciBTWVNURU0gXCIvbm8tc3VjaC1kb2N1bWVudC54bWxcIj4iCisgICAgICAgICAgICAgICAgKyAiXT4iCisgICAgICAgICAgICAgICAgKyAiPGZvbz4mYmFyOzwvZm9vPiI7CisgICAgICAgIHRlc3REaXNhYmxlRXh0ZXJuYWxFbnRpdGllcygiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL2V4dGVybmFsLWdlbmVyYWwtZW50aXRpZXMiLCB4bWwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCB0aGUgZXh0ZXJuYWwtcGFyYW1ldGVyLWVudGl0aWVzIGZlYXR1cmUgY2FuIGJlIGRpc2FibGVkLgorICAgICAqIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9OTQ5MworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REaXNhYmxlRXh0ZXJuYWxQYXJhbWV0ZXJFbnRpdGllcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgeG1sID0gIjwhRE9DVFlQRSBmb28gWyIKKyAgICAgICAgICAgICAgICArICIgIDwhRU5USVRZICUgYmFyIFNZU1RFTSBcIi9uby1zdWNoLWRvY3VtZW50LnhtbFwiPiIKKyAgICAgICAgICAgICAgICArICIgICViYXI7IgorICAgICAgICAgICAgICAgICsgIl0+IgorICAgICAgICAgICAgICAgICsgIjxmb28vPiI7CisgICAgICAgIHRlc3REaXNhYmxlRXh0ZXJuYWxFbnRpdGllcygiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL2V4dGVybmFsLXBhcmFtZXRlci1lbnRpdGllcyIsIHhtbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGlzYWJsZXMgdGhlIG5hbWVkIGZlYXR1cmUgYW5kIHRoZW4gcGFyc2VzIHRoZSBzdXBwbGllZCBYTUwuIFRoZSBjb250ZW50CisgICAgICogaXMgZXhwZWN0ZWQgdG8gYmUgZXF1aXZhbGVudCB0byAiPGZvby8+Ii4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgdGVzdERpc2FibGVFeHRlcm5hbEVudGl0aWVzKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgeG1sKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU0FYUGFyc2VyIHBhcnNlciA9IFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKS5uZXdTQVhQYXJzZXIoKTsKKyAgICAgICAgWE1MUmVhZGVyIHJlYWRlciA9IHBhcnNlci5nZXRYTUxSZWFkZXIoKTsKKyAgICAgICAgcmVhZGVyLnNldEZlYXR1cmUoZmVhdHVyZSwgZmFsc2UpOworICAgICAgICBhc3NlcnRGYWxzZShyZWFkZXIuZ2V0RmVhdHVyZShmZWF0dXJlKSk7CisgICAgICAgIHJlYWRlci5zZXRDb250ZW50SGFuZGxlcihuZXcgVGhyb3dpbmdIYW5kbGVyKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImZvbyIsIHFOYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgcU5hbWUpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAgICAgcmVhZGVyLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShuZXcgU3RyaW5nUmVhZGVyKHhtbCkpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcGFyc2UoYm9vbGVhbiBwcmVmaXhlcywgYm9vbGVhbiBuYW1lc3BhY2VzLCBTdHJpbmcgeG1sLAorICAgICAgICAgICAgQ29udGVudEhhbmRsZXIgaGFuZGxlcikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNBWFBhcnNlciBwYXJzZXIgPSBTQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCkubmV3U0FYUGFyc2VyKCk7CisgICAgICAgIFhNTFJlYWRlciByZWFkZXIgPSBwYXJzZXIuZ2V0WE1MUmVhZGVyKCk7CisgICAgICAgIHJlYWRlci5zZXRGZWF0dXJlKCJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzIiwgcHJlZml4ZXMpOworICAgICAgICByZWFkZXIuc2V0RmVhdHVyZSgiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXMiLCBuYW1lc3BhY2VzKTsKKyAgICAgICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKGhhbmRsZXIpOworICAgICAgICByZWFkZXIucGFyc2UobmV3IElucHV0U291cmNlKG5ldyBTdHJpbmdSZWFkZXIoeG1sKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBleHBlY3RlZCBhbiBvcHRpb25hbCB2YWx1ZSB0aGF0IG1heSBvciBtYXkgaGF2ZSBub3QgYmVlbiBzdXBwbGllZAorICAgICAqIEBwYXJhbSBzZW50aW5lbCBhIG1hcmtlciB2YWx1ZSB0aGF0IG1lYW5zIHRoZSBleHBlY3RlZCB2YWx1ZSB3YXMgb21pdHRlZAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRPbmVPZihTdHJpbmcgZXhwZWN0ZWQsIFN0cmluZyBzZW50aW5lbCwgU3RyaW5nIGFjdHVhbCkgeworICAgICAgICBMaXN0PFN0cmluZz4gb3B0aW9uc0xpc3QgPSBBcnJheXMuYXNMaXN0KHNlbnRpbmVsLCBleHBlY3RlZCk7CisgICAgICAgIGFzc2VydFRydWUoIkV4cGVjdGVkIG9uZSBvZiAiICsgb3B0aW9uc0xpc3QgKyAiIGJ1dCB3YXMgIiArIGFjdHVhbCwKKyAgICAgICAgICAgICAgICBvcHRpb25zTGlzdC5jb250YWlucyhhY3R1YWwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIFNBWCBoYW5kbGVyIHRocm93cyBvbiBldmVyeXRoaW5nIGJ1dCBzdGFydERvY3VtZW50LCBlbmREb2N1bWVudCwKKyAgICAgKiBhbmQgc2V0RG9jdW1lbnRMb2NhdG9yKCkuIE92ZXJyaWRlIHRoZSBtZXRob2RzIHRoYXQgYXJlIGV4cGVjdGVkIHRvIGJlCisgICAgICogY2FsbGVkLgorICAgICAqLworICAgIHN0YXRpYyBjbGFzcyBUaHJvd2luZ0hhbmRsZXIgZXh0ZW5kcyBEZWZhdWx0SGFuZGxlciB7CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eShTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkZhaWxlZEVycm9yKCk7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25GYWlsZWRFcnJvcigpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCB1bnBhcnNlZEVudGl0eURlY2woCisgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgbm90YXRpb25OYW1lKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRmFpbGVkRXJyb3IoKTsKKyAgICAgICAgfQorICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25GYWlsZWRFcnJvcigpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25GYWlsZWRFcnJvcigpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCisgICAgICAgICAgICAgICAgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25GYWlsZWRFcnJvcigpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkZhaWxlZEVycm9yKCk7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25GYWlsZWRFcnJvcigpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRmFpbGVkRXJyb3IoKTsKKyAgICAgICAgfQorICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRmFpbGVkRXJyb3IoKTsKKyAgICAgICAgfQorICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eShTdHJpbmcgbmFtZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkZhaWxlZEVycm9yKCk7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHdhcm5pbmcoU0FYUGFyc2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkZhaWxlZEVycm9yKCk7CisgICAgICAgIH0KKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25GYWlsZWRFcnJvcigpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCBmYXRhbEVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25GYWlsZWRFcnJvcigpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL1NpbXBsZUJ1aWxkZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS94bWwvU2ltcGxlQnVpbGRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYjRkMWFmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL1NpbXBsZUJ1aWxkZXJUZXN0LmphdmEKQEAgLTAsMCArMSwxMTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUueG1sOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IG9yZy53M2MuZG9tLkNvbW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworaW1wb3J0IG9yZy53M2MuZG9tLlByb2Nlc3NpbmdJbnN0cnVjdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5UZXh0OworCitwdWJsaWMgY2xhc3MgU2ltcGxlQnVpbGRlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICAgICAgICBmYWN0b3J5LnNldFZhbGlkYXRpbmcoZmFsc2UpOworICAgICAgICBmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOworCisgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5Lm5ld0RvY3VtZW50QnVpbGRlcigpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGdldFRleHRDb250ZW50KE5vZGUgbm9kZSkgeworICAgICAgICBTdHJpbmcgcmVzdWx0ID0gKG5vZGUgaW5zdGFuY2VvZiBUZXh0ID8gKChUZXh0KSBub2RlKS5nZXREYXRhKCkgOiAiIik7CisKKyAgICAgICAgTm9kZSBjaGlsZCA9IG5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworICAgICAgICB3aGlsZSAoY2hpbGQgIT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgZ2V0VGV4dENvbnRlbnQoY2hpbGQpOworICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5nZXROZXh0U2libGluZygpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdvb2RGaWxlMSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEb2N1bWVudCBkb2N1bWVudCA9IGJ1aWxkZXIucGFyc2UoZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKAorICAgICAgICAgICAgICAgICIvU2ltcGxlQnVpbGRlclRlc3QueG1sIikpOworCisgICAgICAgIEVsZW1lbnQgcm9vdCA9IGRvY3VtZW50LmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKHJvb3QpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly93d3cuZm9vLmJhciIsIHJvb3QuZ2V0TmFtZXNwYWNlVVJJKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInQiLCByb290LmdldFByZWZpeCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdHVmZiIsIHJvb3QuZ2V0TG9jYWxOYW1lKCkpOworCisgICAgICAgIE5vZGVMaXN0IGxpc3QgPSByb290LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJuZXN0ZWRTdHVmZiIpOworICAgICAgICBhc3NlcnROb3ROdWxsKGxpc3QpOworICAgICAgICBhc3NlcnRFcXVhbHMobGlzdC5nZXRMZW5ndGgoKSwgNCk7CisKKyAgICAgICAgRWxlbWVudCBvbmUgPSAoRWxlbWVudCkgbGlzdC5pdGVtKDApOworICAgICAgICBFbGVtZW50IHR3byA9IChFbGVtZW50KSBsaXN0Lml0ZW0oMSk7CisgICAgICAgIEVsZW1lbnQgdGhyZWUgPSAoRWxlbWVudCkgbGlzdC5pdGVtKDIpOworICAgICAgICBFbGVtZW50IGZvdXIgPSAoRWxlbWVudCkgbGlzdC5pdGVtKDMpOworCisgICAgICAgIGFzc2VydEVxdWFscygiVGhpcyBzcGFjZSBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsuIiwKKyAgICAgICAgICAgICAgICBnZXRUZXh0Q29udGVudChvbmUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJOb3RoaW5nIHRvIHNlZSBoZXJlIC0gcGxlYXNlIGdldCBhbG9uZyEiLAorICAgICAgICAgICAgICAgIGdldFRleHRDb250ZW50KHR3bykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJlbnQgdGhpcyBzcGFjZSEiLCBnZXRUZXh0Q29udGVudCh0aHJlZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGdldFRleHRDb250ZW50KGZvdXIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoImVpbnMiLCBvbmUuZ2V0QXR0cmlidXRlKCJvbmUiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiendlaSIsIHR3by5nZXRBdHRyaWJ1dGUoInR3byIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkcmVpIiwgdGhyZWUuZ2V0QXR0cmlidXRlKCJ0aHJlZSIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoInZpZXIiLCBmb3VyLmdldEF0dHJpYnV0ZSgidDpmb3VyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoInZpZXIiLCBmb3VyLmdldEF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LmZvby5iYXIiLCAiZm91ciIpKTsKKworICAgICAgICBsaXN0ID0gZG9jdW1lbnQuZ2V0Q2hpbGROb2RlcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKGxpc3QpOworCisgICAgICAgIFN0cmluZyBwcm9pbnN0ID0gIiI7CisgICAgICAgIFN0cmluZyBjb21tZW50ID0gIiI7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsaXN0LmdldExlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgICAgIE5vZGUgbm9kZSA9IGxpc3QuaXRlbShpKTsKKworICAgICAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24pIHsKKyAgICAgICAgICAgICAgICBwcm9pbnN0ID0gcHJvaW5zdCArIG5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKG5vZGUgaW5zdGFuY2VvZiBDb21tZW50KSB7CisgICAgICAgICAgICAgICAgY29tbWVudCA9IGNvbW1lbnQgKyBub2RlLmdldE5vZGVWYWx1ZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgcXVpY2sgYnJvd24gZm94IGp1bXBzIG92ZXIgdGhlIGxhenkgZG9nLiIsIHByb2luc3QpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiBGcmFnaWxlISAgSGFuZGxlIG1lIHdpdGggY2FyZSEgIiwgY29tbWVudCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdvb2RGaWxlMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBEb2N1bWVudCBkb2N1bWVudCA9IGJ1aWxkZXIucGFyc2UoZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKAorICAgICAgICAgICAgICAgICIvc3RhZmZOUy54bWwiKSk7CisKKyAgICAgICAgRWxlbWVudCByb290ID0gZG9jdW1lbnQuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIGFzc2VydE5vdE51bGwocm9vdCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL2xpYmNvcmUveG1sL1NpbXBsZVBhcnNlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3htbC9TaW1wbGVQYXJzZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmE0OTY0MAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3htbC9TaW1wbGVQYXJzZXJUZXN0LmphdmEKQEAgLTAsMCArMSwyNDMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUueG1sOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKK2ltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKK2ltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlcjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5OworCitwdWJsaWMgY2xhc3MgU2ltcGxlUGFyc2VyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgU0FYUGFyc2VyIHBhcnNlcjsKKworICAgIHByaXZhdGUgU3RyaW5nQnVmZmVyIGluc3RydWN0aW9uczsKKworICAgIHByaXZhdGUgTWFwPFN0cmluZywgU3RyaW5nPiBuYW1lc3BhY2VzMTsKKyAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFN0cmluZz4gbmFtZXNwYWNlczI7CisKKyAgICBwcml2YXRlIFN0cmluZ0J1ZmZlciBlbGVtZW50czE7CisgICAgcHJpdmF0ZSBTdHJpbmdCdWZmZXIgZWxlbWVudHMyOworCisgICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBTdHJpbmc+IGF0dHJpYnV0ZXMxOworICAgIHByaXZhdGUgTWFwPFN0cmluZywgU3RyaW5nPiBhdHRyaWJ1dGVzMjsKKworICAgIHByaXZhdGUgU3RyaW5nQnVmZmVyIHRleHQ7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTQVhQYXJzZXJGYWN0b3J5IGZhY3RvcnkgPSBTQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisgICAgICAgIGZhY3Rvcnkuc2V0VmFsaWRhdGluZyhmYWxzZSk7CisgICAgICAgIGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7CisKKyAgICAgICAgcGFyc2VyID0gZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLmdldFhNTFJlYWRlcigpLnNldENvbnRlbnRIYW5kbGVyKGNvbnRlbnRIYW5kbGVyKTsKKworICAgICAgICBpbnN0cnVjdGlvbnMgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIG5hbWVzcGFjZXMxID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgICAgIG5hbWVzcGFjZXMyID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgICAgIGVsZW1lbnRzMSA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgZWxlbWVudHMyID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBhdHRyaWJ1dGVzMSA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOworICAgICAgICBhdHRyaWJ1dGVzMiA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOworICAgICAgICB0ZXh0ID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGluc3RydWN0aW9ucyA9IG51bGw7CisgICAgICAgIHBhcnNlciA9IG51bGw7CisgICAgICAgIG5hbWVzcGFjZXMxID0gbnVsbDsKKyAgICAgICAgbmFtZXNwYWNlczIgPSBudWxsOworICAgICAgICBhdHRyaWJ1dGVzMSA9IG51bGw7CisgICAgICAgIGF0dHJpYnV0ZXMyID0gbnVsbDsKKyAgICAgICAgZWxlbWVudHMxID0gbnVsbDsKKyAgICAgICAgZWxlbWVudHMyID0gbnVsbDsKKyAgICAgICAgdGV4dCA9IG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBDb250ZW50SGFuZGxlciBjb250ZW50SGFuZGxlciA9IG5ldyBDb250ZW50SGFuZGxlcigpIHsKKyAgICAgICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkgeworICAgICAgICAgICAgU3RyaW5nIHMgPSBuZXcgU3RyaW5nKGNoLCBzdGFydCwgbGVuZ3RoKS50cmltKCk7CisgICAgICAgICAgICBpZiAoIXMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgaWYgKHRleHQubGVuZ3RoKCkgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICB0ZXh0LmFwcGVuZCgiLCIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0ZXh0LmFwcGVuZChzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkgeworICAgICAgICAgICAgU3RyaW5nIHMgPSB0YXJnZXQgKyAiOiIgKyBkYXRhOworICAgICAgICAgICAgaWYgKGluc3RydWN0aW9ucy5sZW5ndGgoKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgaW5zdHJ1Y3Rpb25zLmFwcGVuZCgiLCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW5zdHJ1Y3Rpb25zLmFwcGVuZChzKTsKKyAgICAgICAgfQorCisKKyAgICAgICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSwgQXR0cmlidXRlcyBhdHRzKSB7CisKKyAgICAgICAgICAgIGlmIChlbGVtZW50czEubGVuZ3RoKCkgIT0gMCkgeworICAgICAgICAgICAgICAgIGVsZW1lbnRzMS5hcHBlbmQoIiwiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZWxlbWVudHMxLmFwcGVuZChsb2NhbE5hbWUpOworCisgICAgICAgICAgICBpZiAoISIiLmVxdWFscyh1cmkpKSB7CisgICAgICAgICAgICAgICAgbmFtZXNwYWNlczEucHV0KGxvY2FsTmFtZSwgdXJpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRzLmdldExlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzMS5wdXQoYXR0cy5nZXRMb2NhbE5hbWUoaSksIGF0dHMuZ2V0VmFsdWUoaSkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZWxlbWVudHMyLmxlbmd0aCgpICE9IDApIHsKKyAgICAgICAgICAgICAgICBlbGVtZW50czIuYXBwZW5kKCIsIik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGVsZW1lbnRzMi5hcHBlbmQocU5hbWUpOworCisgICAgICAgICAgICBpZiAoISIiLmVxdWFscyh1cmkpKSB7CisgICAgICAgICAgICAgICAgbmFtZXNwYWNlczIucHV0KHFOYW1lLCB1cmkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGF0dHMuZ2V0TGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMyLnB1dChhdHRzLmdldFFOYW1lKGkpLCBhdHRzLmdldFZhbHVlKGkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkge30KKyAgICAgICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUpIHt9CisgICAgICAgIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCkge30KKyAgICAgICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkge30KKyAgICAgICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikge30KKyAgICAgICAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eShTdHJpbmcgbmFtZSkge30KKyAgICAgICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHt9CisgICAgICAgIHB1YmxpYyB2b2lkIHN0YXJ0UHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKSB7fQorICAgIH07CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V29ya2luZ0ZpbGUxKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNBWFBhcnNlckZhY3RvcnkgZmFjdG9yeSA9IFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgZmFjdG9yeS5zZXRWYWxpZGF0aW5nKGZhbHNlKTsKKyAgICAgICAgZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKKworICAgICAgICBTQVhQYXJzZXIgcGFyc2VyID0gZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLmdldFhNTFJlYWRlcigpLnNldENvbnRlbnRIYW5kbGVyKGNvbnRlbnRIYW5kbGVyKTsKKworICAgICAgICBwYXJzZXIucGFyc2UoZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvU2ltcGxlUGFyc2VyVGVzdC54bWwiKSwKKyAgICAgICAgICAgICAgICAoRGVmYXVsdEhhbmRsZXIpIG51bGwpOworCisgICAgICAgIGFzc2VydEVxdWFscygiVGhlOnF1aWNrLGJyb3duOmZveCIsIGluc3RydWN0aW9ucy50b1N0cmluZygpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoInN0dWZmLG5lc3RlZFN0dWZmLG5lc3RlZFN0dWZmLG5lc3RlZFN0dWZmIiwgZWxlbWVudHMxCisgICAgICAgICAgICAgICAgLnRvU3RyaW5nKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiU29tZSB0ZXh0IGhlcmUsc29tZSBtb3JlIGhlcmUuLi4iLCB0ZXh0LnRvU3RyaW5nKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiZWlucyIsIGF0dHJpYnV0ZXMxLmdldCgib25lIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoInp3ZWkiLCBhdHRyaWJ1dGVzMS5nZXQoInR3byIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkcmVpIiwgYXR0cmlidXRlczEuZ2V0KCJ0aHJlZSIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly93d3cuZm9vYmFyLm9yZyIsIG5hbWVzcGFjZXMxLmdldCgic3R1ZmYiKSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RXb3JraW5nRmlsZTIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU0FYUGFyc2VyRmFjdG9yeSBmYWN0b3J5ID0gU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworCisgICAgICAgIGZhY3Rvcnkuc2V0VmFsaWRhdGluZyhmYWxzZSk7CisgICAgICAgIGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUoZmFsc2UpOworICAgICAgICBmYWN0b3J5LnNldEZlYXR1cmUoImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2UtcHJlZml4ZXMiLAorICAgICAgICAgICAgICAgIHRydWUpOworCisgICAgICAgIFNBWFBhcnNlciBwYXJzZXIgPSBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOworICAgICAgICBwYXJzZXIuZ2V0WE1MUmVhZGVyKCkuc2V0Q29udGVudEhhbmRsZXIoY29udGVudEhhbmRsZXIpOworICAgICAgICBwYXJzZXIucGFyc2UoZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvU2ltcGxlUGFyc2VyVGVzdC54bWwiKSwKKyAgICAgICAgICAgICAgICAoRGVmYXVsdEhhbmRsZXIpIG51bGwpOworCisgICAgICAgIGFzc2VydEZhbHNlKHBhcnNlci5pc05hbWVzcGFjZUF3YXJlKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiVGhlOnF1aWNrLGJyb3duOmZveCIsIGluc3RydWN0aW9ucy50b1N0cmluZygpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoInQ6c3R1ZmYsbmVzdGVkU3R1ZmYsbmVzdGVkU3R1ZmYsbmVzdGVkU3R1ZmYiLCBlbGVtZW50czIKKyAgICAgICAgICAgICAgICAudG9TdHJpbmcoKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTb21lIHRleHQgaGVyZSxzb21lIG1vcmUgaGVyZS4uLiIsIHRleHQudG9TdHJpbmcoKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlaW5zIiwgYXR0cmlidXRlczIuZ2V0KCJvbmUiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiendlaSIsIGF0dHJpYnV0ZXMyLmdldCgidHdvIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRyZWkiLCBhdHRyaWJ1dGVzMi5nZXQoInRocmVlIikpOworCisgICAgICAgIGFzc2VydEVxdWFscygwLCBuYW1lc3BhY2VzMi5zaXplKCkpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW50aXR5UmVzb2x2ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciB0ZXh0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgRGVmYXVsdEhhbmRsZXIgaGFuZGxlciA9IG5ldyBEZWZhdWx0SGFuZGxlcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgcyA9IG5ldyBTdHJpbmcoY2gsIHN0YXJ0LCBsZW5ndGgpLnRyaW0oKTsKKyAgICAgICAgICAgICAgICBpZiAocy5sZW5ndGgoKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0Lmxlbmd0aCgpICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRleHQuYXBwZW5kKCIsIik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgdGV4dC5hcHBlbmQocyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eShTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSW5wdXRTb3VyY2UobmV3IElucHV0U3RyZWFtUmVhZGVyKAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKCJ0ZXN0Ii5nZXRCeXRlcygpKSkpOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIFNBWFBhcnNlckZhY3Rvcnkgc3BmID0gU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICAgICAgICBzcGYuc2V0VmFsaWRhdGluZyhmYWxzZSk7CisgICAgICAgIHBhcnNlciA9IHNwZi5uZXdTQVhQYXJzZXIoKTsKKyAgICAgICAgcGFyc2VyLnBhcnNlKHRoaXMuZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvc3RhZmZFbnRSZXMueG1sIiksCisgICAgICAgICAgICAgICAgaGFuZGxlcik7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgInJlc29sdmVkIGV4dGVybmFsIGVudGl0eSBtdXN0IGJlIGluIHBhcnNlciBjaGFyYWN0ZXIgc3RyZWFtIiwKKyAgICAgICAgICAgICAgICB0ZXh0LnRvU3RyaW5nKCkuY29udGFpbnMoInRlc3QiKSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRWYWx1ZSgpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIHBhcnNlci5wYXJzZShnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oIi9zdGFmZk5TLnhtbCIpLAorICAgICAgICAgICAgICAgIG5ldyBEZWZhdWx0SGFuZGxlcigpIHsKKyAgICAgICAgICAgIGJvb2xlYW4gZmlyc3RBZGRyZXNzRWxlbSA9IHRydWU7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHFOYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHsKKyAgICAgICAgICAgICAgICBpZihmaXJzdEFkZHJlc3NFbGVtICYmIGxvY2FsTmFtZS5lcXVhbHMoImFkZHJlc3MiKSkgeworICAgICAgICAgICAgICAgICAgICBmaXJzdEFkZHJlc3NFbGVtID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoYXR0cmlidXRlcy5nZXRWYWx1ZSgiaHR0cDovL3d3dy51c2EuY29tIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZG9tZXN0aWMiKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS94bWwvWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9saWJjb3JlL3htbC9Yc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1OWY0NTcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvbGliY29yZS94bWwvWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUuamF2YQpAQCAtMCwwICsxLDYzNSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS54bWw7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEuaW8uUmVhZGVyOworaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOworaW1wb3J0IGphdmEuaW8uU3RyaW5nV3JpdGVyOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5Db21wYXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyOworaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OworaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOworaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01SZXN1bHQ7CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0OworaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5Bc3NlcnRpb25GYWlsZWRFcnJvcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5BdHRyOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRW50aXR5UmVmZXJlbmNlOworaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworaW1wb3J0IG9yZy53M2MuZG9tLlByb2Nlc3NpbmdJbnN0cnVjdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbHB1bGwudjEuWG1sUHVsbFBhcnNlckV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1scHVsbC52MS5YbWxQdWxsUGFyc2VyRmFjdG9yeTsKK2ltcG9ydCBvcmcueG1scHVsbC52MS5YbWxTZXJpYWxpemVyOworCisvKioKKyAqIFRoZSA8YSBocmVmPSJodHRwOi8vd3d3Lm9hc2lzLW9wZW4ub3JnL2NvbW1pdHRlZXMvdGNfaG9tZS5waHA/d2dfYWJicmV2PXhzbHQiPk9BU0lTCisgKiBYU0xUIGNvbmZvcm1hbmNlIHRlc3Qgc3VpdGU8L2E+LCBhZGFwdGVkIGZvciB1c2UgYnkgSlVuaXQuIFRvIHJ1biB0aGVzZSB0ZXN0cworICogb24gYSBkZXZpY2U6CisgKiA8dWw+CisgKiAgICAgPGxpPk9idGFpbiB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy5vYXNpcy1vcGVuLm9yZy9jb21taXR0ZWVzL2Rvd25sb2FkLnBocC8xMjE3MS9YU0xULXRlc3RzdWl0ZS0wNC5aSVAiPnRlc3QKKyAqICAgICAgICAgc3VpdGUgemlwIGZpbGUgZnJvbSB0aGUgT0FTSVMgcHJvamVjdCBzaXRlLjwvbGk+CisgKiAgICAgPGxpPlVuemlwLgorICogICAgIDxsaT5Db3B5IHRoZSBmaWxlcyB0byBhIGRldmljZTogPGNvZGU+YWRiIHNoZWxsIG1rZGlyIC9kYXRhL29hc2lzIDsKKyAqICAgICAgICAgYWRiIHB1c2ggLi9YU0xULUNvbmZvcm1hbmNlLVRDIC9kYXRhL29hc2lzPC9jb2RlPi4KKyAqICAgICA8bGk+SW52b2tlIHRoaXMgY2xhc3MnIG1haW4gbWV0aG9kLCBwYXNzaW5nIHRoZSBvbi1kZXZpY2UgcGF0aCB0byB0aGUgdGVzdAorICogICAgICAgICBzdWl0ZSdzIDxjb2RlPmNhdGFsb2cueG1sPC9jb2RlPiBmaWxlIGFzIGFuIGFyZ3VtZW50LgorICogPC91bD4KKyAqCisgKiA8cD5VbmZvcnR1bmF0ZWx5LCBzb21lIG9mIHRoZSB0ZXN0cyBpbiB0aGUgT0FTSVMgc3VpdGUgd2lsbCBmYWlsIHdoZW4KKyAqIGV4ZWN1dGVkIG91dHNpZGUgb2YgdGhlaXIgb3JpZ2luYWwgZGV2ZWxvcG1lbnQgZW52aXJvbm1lbnQ6CisgKiA8dWw+CisgKiAgICAgPGxpPlRoZSB0ZXN0cyBhc3N1bWUgY2FzZSBpbnNlbnNpdGl2ZSBmaWxlc3lzdGVtcy4gU29tZSB3aWxsIGZhaWwgd2l0aAorICogICAgICAgICJDb3VsZG4ndCBvcGVuIGZpbGUiIGVycm9ycyBkdWUgdG8gYSBtaXNtYXRjaCBpbiBmaWxlIG5hbWUgY2FzaW5nLgorICogICAgIDxsaT5UaGUgdGVzdHMgYXNzdW1lIGNlcnRhaW4gbmV0d29yayBob3N0cyB3aWxsIGV4aXN0IGFuZCBzZXJ2ZQorICogICAgICAgICBzdHlsZXNoZWV0IGZpbGVzLiBJbiBwYXJ0aWN1bGFyLCAiaHR0cDovL3dlYnh0ZXN0LyIgaXNuJ3QgZ2VuZXJhbGx5CisgKiAgICAgICAgIGF2YWlsYWJsZS4KKyAqIDwvdWw+CisgKi8KK3B1YmxpYyBjbGFzcyBYc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZGVmYXVsdENhdGFsb2dGaWxlCisgICAgICAgICAgICA9ICIvaG9tZS9kYWx2aWstcHJlYnVpbGQvT0FTSVMvWFNMVC1Db25mb3JtYW5jZS1UQy9URVNUUy9jYXRhbG9nLnhtbCI7CisKKyAgICAvKiogT3JkZXJzIGVsZW1lbnQgYXR0cmlidXRlcyBieSBvcHRpb25hbCBVUkkgYW5kIG5hbWUuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29tcGFyYXRvcjxBdHRyPiBvcmRlckJ5TmFtZSA9IG5ldyBDb21wYXJhdG9yPEF0dHI+KCkgeworICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoQXR0ciBhLCBBdHRyIGIpIHsKKyAgICAgICAgICAgIGludCByZXN1bHQgPSBjb21wYXJlTnVsbHNGaXJzdChhLmdldE5hbWVzcGFjZVVSSSgpLCBiLmdldE5hbWVzcGFjZVVSSSgpKTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gMCA/IHJlc3VsdAorICAgICAgICAgICAgICAgICAgICA6IGNvbXBhcmVOdWxsc0ZpcnN0KGEuZ2V0TmFtZSgpLCBiLmdldE5hbWUoKSk7CisgICAgICAgIH0KKworICAgICAgICA8VCBleHRlbmRzIENvbXBhcmFibGU8VD4+IGludCBjb21wYXJlTnVsbHNGaXJzdChUIGEsIFQgYikgeworICAgICAgICAgICAgcmV0dXJuIChhID09IGIpID8gMAorICAgICAgICAgICAgICAgICAgICA6IChhID09IG51bGwpID8gLTEKKyAgICAgICAgICAgICAgICAgICAgOiAoYiA9PSBudWxsKSA/IDEKKyAgICAgICAgICAgICAgICAgICAgOiBhLmNvbXBhcmVUbyhiKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBwcml2YXRlIGZpbmFsIERvY3VtZW50QnVpbGRlciBkb2N1bWVudEJ1aWxkZXI7CisgICAgcHJpdmF0ZSBmaW5hbCBUcmFuc2Zvcm1lckZhY3RvcnkgdHJhbnNmb3JtZXJGYWN0b3J5OworICAgIHByaXZhdGUgZmluYWwgWG1sUHVsbFBhcnNlckZhY3RvcnkgeG1sUHVsbFBhcnNlckZhY3Rvcnk7CisKKyAgICBwdWJsaWMgWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUoKQorICAgICAgICAgICAgdGhyb3dzIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24sIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisgICAgICAgIGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7CisgICAgICAgIGZhY3Rvcnkuc2V0Q29hbGVzY2luZyh0cnVlKTsKKyAgICAgICAgZG9jdW1lbnRCdWlsZGVyID0gZmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKKworICAgICAgICB0cmFuc2Zvcm1lckZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgeG1sUHVsbFBhcnNlckZhY3RvcnkgPSBYbWxQdWxsUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpZiAoYXJncy5sZW5ndGggIT0gMSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJVc2FnZTogWHNsdFhQYXRoQ29uZm9ybWFuY2VUZXN0U3VpdGUgPGNhdGFsb2cteG1sPiIpOworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiAgY2F0YWxvZy14bWw6IGFuIFhNTCBmaWxlIGRlc2NyaWJpbmcgYW4gT0FTSVMgdGVzdCBzdWl0ZSIpOworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgICAgICAgICAgICAgICBzdWNoIGFzOiAiICsgZGVmYXVsdENhdGFsb2dGaWxlKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIEZpbGUgY2F0YWxvZ1htbCA9IG5ldyBGaWxlKGFyZ3NbMF0pOworICAgICAgICAvLyBUZXN0UnVubmVyLnJ1bihzdWl0ZShjYXRhbG9nWG1sKSk7IGFuZHJvaWQtY2hhbmdlZAorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgVGVzdCBzdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc3VpdGUobmV3IEZpbGUoZGVmYXVsdENhdGFsb2dGaWxlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIEpVbml0IHRlc3Qgc3VpdGUgZm9yIHRoZSB0ZXN0cyBkZXNjcmliZWQgYnkgdGhlIGdpdmVuIGRvY3VtZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVGVzdCBzdWl0ZShGaWxlIGNhdGFsb2dYbWwpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBYc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSBzdWl0ZSA9IG5ldyBYc2x0WFBhdGhDb25mb3JtYW5jZVRlc3RTdWl0ZSgpOworCisgICAgICAgIC8qCisgICAgICAgICAqIEV4dHJhY3QgdGhlIHRlc3RzIGZyb20gYW4gWE1MIGRvY3VtZW50IHdpdGggdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6CisgICAgICAgICAqCisgICAgICAgICAqICA8dGVzdC1zdWl0ZT4KKyAgICAgICAgICogICAgPHRlc3QtY2F0YWxvZyBzdWJtaXR0ZXI9IkxvdHVzIj4KKyAgICAgICAgICogICAgICA8Y3JlYXRvcj5Mb3R1cy9JQk08L2NyZWF0b3I+CisgICAgICAgICAqICAgICAgPG1ham9yLXBhdGg+WGFsYW5fQ29uZm9ybWFuY2VfVGVzdHM8L21ham9yLXBhdGg+CisgICAgICAgICAqICAgICAgPGRhdGU+MjAwMS0xMS0xNjwvZGF0ZT4KKyAgICAgICAgICogICAgICA8dGVzdC1jYXNlIC4uLj4gLi4uIDwvdGVzdC1jYXNlPgorICAgICAgICAgKiAgICAgIDx0ZXN0LWNhc2UgLi4uPiAuLi4gPC90ZXN0LWNhc2U+CisgICAgICAgICAqICAgICAgPHRlc3QtY2FzZSAuLi4+IC4uLiA8L3Rlc3QtY2FzZT4KKyAgICAgICAgICogICAgPC90ZXN0LWNhdGFsb2c+CisgICAgICAgICAqICA8L3Rlc3Qtc3VpdGU+CisgICAgICAgICAqLworCisgICAgICAgIERvY3VtZW50IGRvY3VtZW50ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpCisgICAgICAgICAgICAgICAgLm5ld0RvY3VtZW50QnVpbGRlcigpLnBhcnNlKGNhdGFsb2dYbWwpOworICAgICAgICBFbGVtZW50IHRlc3RTdWl0ZUVsZW1lbnQgPSBkb2N1bWVudC5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgVGVzdFN1aXRlIHJlc3VsdCA9IG5ldyBUZXN0U3VpdGUoKTsKKyAgICAgICAgZm9yIChFbGVtZW50IHRlc3RDYXRhbG9nIDogZWxlbWVudHNPZih0ZXN0U3VpdGVFbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJ0ZXN0LWNhdGFsb2ciKSkpIHsKKyAgICAgICAgICAgIEVsZW1lbnQgbWFqb3JQYXRoRWxlbWVudCA9IChFbGVtZW50KSB0ZXN0Q2F0YWxvZy5nZXRFbGVtZW50c0J5VGFnTmFtZSgibWFqb3ItcGF0aCIpLml0ZW0oMCk7CisgICAgICAgICAgICBTdHJpbmcgbWFqb3JQYXRoID0gbWFqb3JQYXRoRWxlbWVudC5nZXRUZXh0Q29udGVudCgpOworICAgICAgICAgICAgRmlsZSBiYXNlID0gbmV3IEZpbGUoY2F0YWxvZ1htbC5nZXRQYXJlbnRGaWxlKCksIG1ham9yUGF0aCk7CisKKyAgICAgICAgICAgIGZvciAoRWxlbWVudCB0ZXN0Q2FzZUVsZW1lbnQgOiBlbGVtZW50c09mKHRlc3RDYXRhbG9nLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJ0ZXN0LWNhc2UiKSkpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYWRkVGVzdChzdWl0ZS5jcmVhdGUoYmFzZSwgdGVzdENhc2VFbGVtZW50KSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBKVW5pdCB0ZXN0IGZvciB0aGUgdGVzdCBkZXNjcmliZWQgYnkgdGhlIGdpdmVuIGVsZW1lbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBUZXN0Q2FzZSBjcmVhdGUoRmlsZSBiYXNlLCBFbGVtZW50IHRlc3RDYXNlRWxlbWVudCkgeworCisgICAgICAgIC8qCisgICAgICAgICAqIEV4dHJhY3QgdGhlIFhTTFQgdGVzdCBmcm9tIGEgRE9NIGVudGl0eSB3aXRoIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlOgorICAgICAgICAgKgorICAgICAgICAgKiAgIDx0ZXN0LWNhc2UgY2F0ZWdvcnk9IlhTTFQtUmVzdWx0LVRyZWUiIGlkPSJhdHRyaWJzZXRfYXR0cmlic2V0MDEiPgorICAgICAgICAgKiAgICAgICA8ZmlsZS1wYXRoPmF0dHJpYnNldDwvZmlsZS1wYXRoPgorICAgICAgICAgKiAgICAgICA8Y3JlYXRvcj5QYXVsIERpY2s8L2NyZWF0b3I+CisgICAgICAgICAqICAgICAgIDxkYXRlPjIwMDEtMTEtMDg8L2RhdGU+CisgICAgICAgICAqICAgICAgIDxwdXJwb3NlPlNldCBhdHRyaWJ1dGUgb2YgYSBMUkUgZnJvbSBzaW5nbGUgYXR0cmlidXRlIHNldC48L3B1cnBvc2U+CisgICAgICAgICAqICAgICAgIDxzcGVjLWNpdGF0aW9uIHBsYWNlPSI3LjEuNCIgdHlwZT0ic2VjdGlvbiIgdmVyc2lvbj0iMS4wIiBzcGVjPSJ4c2x0Ii8+CisgICAgICAgICAqICAgICAgICA8c2NlbmFyaW8gb3BlcmF0aW9uPSJzdGFuZGFyZCI+CisgICAgICAgICAqICAgICAgICAgICA8aW5wdXQtZmlsZSByb2xlPSJwcmluY2lwYWwtZGF0YSI+YXR0cmlic2V0MDEueG1sPC9pbnB1dC1maWxlPgorICAgICAgICAgKiAgICAgICAgICAgPGlucHV0LWZpbGUgcm9sZT0icHJpbmNpcGFsLXN0eWxlc2hlZXQiPmF0dHJpYnNldDAxLnhzbDwvaW5wdXQtZmlsZT4KKyAgICAgICAgICogICAgICAgICAgIDxvdXRwdXQtZmlsZSByb2xlPSJwcmluY2lwYWwiIGNvbXBhcmU9IlhNTCI+YXR0cmlic2V0MDEub3V0PC9vdXRwdXQtZmlsZT4KKyAgICAgICAgICogICAgICAgPC9zY2VuYXJpbz4KKyAgICAgICAgICogICA8L3Rlc3QtY2FzZT4KKyAgICAgICAgICovCisKKyAgICAgICAgRWxlbWVudCBmaWxlUGF0aEVsZW1lbnQgPSAoRWxlbWVudCkgdGVzdENhc2VFbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJmaWxlLXBhdGgiKS5pdGVtKDApOworICAgICAgICBFbGVtZW50IHB1cnBvc2VFbGVtZW50ID0gKEVsZW1lbnQpIHRlc3RDYXNlRWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgicHVycG9zZSIpLml0ZW0oMCk7CisgICAgICAgIEVsZW1lbnQgc3BlY0NpdGF0aW9uRWxlbWVudCA9IChFbGVtZW50KSB0ZXN0Q2FzZUVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInNwZWMtY2l0YXRpb24iKS5pdGVtKDApOworICAgICAgICBFbGVtZW50IHNjZW5hcmlvRWxlbWVudCA9IChFbGVtZW50KSB0ZXN0Q2FzZUVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInNjZW5hcmlvIikuaXRlbSgwKTsKKworICAgICAgICBTdHJpbmcgY2F0ZWdvcnkgPSB0ZXN0Q2FzZUVsZW1lbnQuZ2V0QXR0cmlidXRlKCJjYXRlZ29yeSIpOworICAgICAgICBTdHJpbmcgaWQgPSB0ZXN0Q2FzZUVsZW1lbnQuZ2V0QXR0cmlidXRlKCJpZCIpOworICAgICAgICBTdHJpbmcgbmFtZSA9IGNhdGVnb3J5ICsgIi4iICsgaWQ7CisgICAgICAgIFN0cmluZyBwdXJwb3NlID0gcHVycG9zZUVsZW1lbnQgIT0gbnVsbCA/IHB1cnBvc2VFbGVtZW50LmdldFRleHRDb250ZW50KCkgOiAiIjsKKyAgICAgICAgU3RyaW5nIHNwZWMgPSAicGxhY2U9IiArIHNwZWNDaXRhdGlvbkVsZW1lbnQuZ2V0QXR0cmlidXRlKCJwbGFjZSIpCisgICAgICAgICAgICAgICAgKyAiIHR5cGUiICsgc3BlY0NpdGF0aW9uRWxlbWVudC5nZXRBdHRyaWJ1dGUoInR5cGUiKQorICAgICAgICAgICAgICAgICsgIiB2ZXJzaW9uPSIgKyBzcGVjQ2l0YXRpb25FbGVtZW50LmdldEF0dHJpYnV0ZSgidmVyc2lvbiIpCisgICAgICAgICAgICAgICAgKyAiIHNwZWM9IiArIHNwZWNDaXRhdGlvbkVsZW1lbnQuZ2V0QXR0cmlidXRlKCJzcGVjIik7CisgICAgICAgIFN0cmluZyBvcGVyYXRpb24gPSBzY2VuYXJpb0VsZW1lbnQuZ2V0QXR0cmlidXRlKCJvcGVyYXRpb24iKTsKKworICAgICAgICBFbGVtZW50IHByaW5jaXBhbERhdGFFbGVtZW50ID0gbnVsbDsKKyAgICAgICAgRWxlbWVudCBwcmluY2lwYWxTdHlsZXNoZWV0RWxlbWVudCA9IG51bGw7CisgICAgICAgIEVsZW1lbnQgcHJpbmNpcGFsRWxlbWVudCA9IG51bGw7CisKKyAgICAgICAgZm9yIChFbGVtZW50IGVsZW1lbnQgOiBlbGVtZW50c09mKHNjZW5hcmlvRWxlbWVudC5nZXRDaGlsZE5vZGVzKCkpKSB7CisgICAgICAgICAgICBTdHJpbmcgcm9sZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCJyb2xlIik7CisgICAgICAgICAgICBpZiAocm9sZS5lcXVhbHMoInByaW5jaXBhbC1kYXRhIikpIHsKKyAgICAgICAgICAgICAgICBwcmluY2lwYWxEYXRhRWxlbWVudCA9IGVsZW1lbnQ7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHJvbGUuZXF1YWxzKCJwcmluY2lwYWwtc3R5bGVzaGVldCIpKSB7CisgICAgICAgICAgICAgICAgcHJpbmNpcGFsU3R5bGVzaGVldEVsZW1lbnQgPSBlbGVtZW50OworICAgICAgICAgICAgfSBlbHNlIGlmIChyb2xlLmVxdWFscygicHJpbmNpcGFsIikpIHsKKyAgICAgICAgICAgICAgICBwcmluY2lwYWxFbGVtZW50ID0gZWxlbWVudDsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIXJvbGUuZXF1YWxzKCJzdXBwbGVtZW50YWwtc3R5bGVzaGVldCIpCisgICAgICAgICAgICAgICAgICAgICYmICFyb2xlLmVxdWFscygic3VwcGxlbWVudGFsLWRhdGEiKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWlzc3BlY2lmaWVkVGVzdCgiVW5leHBlY3RlZCBlbGVtZW50IGF0ICIgKyBuYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyB0ZXN0RGlyZWN0b3J5ID0gZmlsZVBhdGhFbGVtZW50LmdldFRleHRDb250ZW50KCk7CisgICAgICAgIEZpbGUgaW5CYXNlID0gbmV3IEZpbGUoYmFzZSwgdGVzdERpcmVjdG9yeSk7CisgICAgICAgIEZpbGUgb3V0QmFzZSA9IG5ldyBGaWxlKG5ldyBGaWxlKGJhc2UsICJSRUZfT1VUIiksIHRlc3REaXJlY3RvcnkpOworCisgICAgICAgIGlmIChwcmluY2lwYWxEYXRhRWxlbWVudCA9PSBudWxsIHx8IHByaW5jaXBhbFN0eWxlc2hlZXRFbGVtZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgTWlzc3BlY2lmaWVkVGVzdCgiRXhwZWN0ZWQgPHNjZW5hcmlvPiB0byBoYXZlICIKKyAgICAgICAgICAgICAgICAgICAgKyAicHJpbmNpcGFsPWRhdGEgYW5kIHByaW5jaXBhbC1zdHlsZXNoZWV0IGVsZW1lbnRzIGF0ICIgKyBuYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBGaWxlIHByaW5jaXBhbERhdGEgPSBmaW5kRmlsZShpbkJhc2UsIHByaW5jaXBhbERhdGFFbGVtZW50LmdldFRleHRDb250ZW50KCkpOworICAgICAgICAgICAgRmlsZSBwcmluY2lwYWxTdHlsZXNoZWV0ID0gZmluZEZpbGUoaW5CYXNlLCBwcmluY2lwYWxTdHlsZXNoZWV0RWxlbWVudC5nZXRUZXh0Q29udGVudCgpKTsKKworICAgICAgICAgICAgZmluYWwgRmlsZSBwcmluY2lwYWw7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgY29tcGFyZUFzOworICAgICAgICAgICAgaWYgKCFvcGVyYXRpb24uZXF1YWxzKCJleGVjdXRpb24tZXJyb3IiKSkgeworICAgICAgICAgICAgICAgIGlmIChwcmluY2lwYWxFbGVtZW50ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNaXNzcGVjaWZpZWRUZXN0KCJFeHBlY3RlZCA8c2NlbmFyaW8+IHRvIGhhdmUgcHJpbmNpcGFsIGVsZW1lbnQgYXQgIiArIG5hbWUpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHByaW5jaXBhbCA9IGZpbmRGaWxlKG91dEJhc2UsIHByaW5jaXBhbEVsZW1lbnQuZ2V0VGV4dENvbnRlbnQoKSk7CisgICAgICAgICAgICAgICAgY29tcGFyZUFzID0gcHJpbmNpcGFsRWxlbWVudC5nZXRBdHRyaWJ1dGUoImNvbXBhcmUiKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcHJpbmNpcGFsID0gbnVsbDsKKyAgICAgICAgICAgICAgICBjb21wYXJlQXMgPSBudWxsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gbmV3IFhzbHRUZXN0KGNhdGVnb3J5LCBpZCwgcHVycG9zZSwgc3BlYywgcHJpbmNpcGFsRGF0YSwKKyAgICAgICAgICAgICAgICAgICAgcHJpbmNpcGFsU3R5bGVzaGVldCwgcHJpbmNpcGFsLCBvcGVyYXRpb24sIGNvbXBhcmVBcyk7CisgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IE1pc3NwZWNpZmllZFRlc3QoZS5nZXRNZXNzYWdlKCkgKyAiIGF0ICIgKyBuYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmRzIHRoZSBuYW1lZCBmaWxlIGluIHRoZSBuYW1lZCBkaXJlY3RvcnkuIFRoaXMgdHJpZXMgZXh0cmEgaGFyZCB0bworICAgICAqIGF2b2lkIGNhc2UtaW5zZW5zaXRpdmUtbmFtaW5nIHByb2JsZW1zLCB3aGVyZSB0aGUgcmVxdWVzdGVkIGZpbGUgaXMKKyAgICAgKiBhdmFpbGFibGUgaW4gYSBkaWZmZXJlbnQgY2FzaW5nLgorICAgICAqLworICAgIHByaXZhdGUgRmlsZSBmaW5kRmlsZShGaWxlIGRpcmVjdG9yeSwgU3RyaW5nIG5hbWUpIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShkaXJlY3RvcnksIG5hbWUpOworICAgICAgICBpZiAoZmlsZS5leGlzdHMoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZpbGU7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKFN0cmluZyBjaGlsZCA6IGRpcmVjdG9yeS5saXN0KCkpIHsKKyAgICAgICAgICAgIGlmIChjaGlsZC5lcXVhbHNJZ25vcmVDYXNlKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWxlKGRpcmVjdG9yeSwgY2hpbGQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdGhyb3cgbmV3IEZpbGVOb3RGb3VuZEV4Y2VwdGlvbigiTWlzc2luZyBmaWxlOiAiICsgZmlsZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGxhY2Vob2xkZXIgZm9yIGEgdGVzdCB0aGF0IGNvdWxkbid0IGJlIGNvbmZpZ3VyZWQgdG8gcnVuIHByb3Blcmx5LgorICAgICAqLworICAgIHB1YmxpYyBjbGFzcyBNaXNzcGVjaWZpZWRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBtZXNzYWdlOworCisgICAgICAgIE1pc3NwZWNpZmllZFRlc3QoU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICAgICAgICAgIHN1cGVyKCJ0ZXN0Iik7CisgICAgICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgdGVzdCgpIHsKKyAgICAgICAgICAgIGZhaWwobWVzc2FnZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzZXMgYW4gaW5wdXQgWE1MIGZpbGUgd2l0aCBhbiBpbnB1dCBYU0xUIHN0eWxlc2hlZXQgYW5kIGNvbXBhcmVzCisgICAgICogdGhlIHJlc3VsdCB0byBhbiBleHBlY3RlZCBvdXRwdXQgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgY2xhc3MgWHNsdFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGNhdGVnb3J5OworICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBpZDsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcHVycG9zZTsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgc3BlYzsKKworICAgICAgICBwcml2YXRlIGZpbmFsIEZpbGUgcHJpbmNpcGFsRGF0YTsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBGaWxlIHByaW5jaXBhbFN0eWxlc2hlZXQ7CisgICAgICAgIHByaXZhdGUgZmluYWwgRmlsZSBwcmluY2lwYWw7CisKKyAgICAgICAgLyoqIGVpdGhlciAic3RhbmRhcmQiIG9yICJleGVjdXRpb24tZXJyb3IiICovCisgICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG9wZXJhdGlvbjsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHN5bnRheCB0byBjb21wYXJlIHRoZSBvdXRwdXQgZmlsZSB1c2luZywgc3VjaCBhcyAiWE1MIiwgIkhUTUwiLAorICAgICAgICAgKiAibWFudWFsIiwgb3IgbnVsbCBmb3IgZXhwZWN0ZWQgZXhlY3V0aW9uIGVycm9ycy4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGNvbXBhcmVBczsKKworICAgICAgICBYc2x0VGVzdChTdHJpbmcgY2F0ZWdvcnksIFN0cmluZyBpZCwgU3RyaW5nIHB1cnBvc2UsIFN0cmluZyBzcGVjLAorICAgICAgICAgICAgICAgIEZpbGUgcHJpbmNpcGFsRGF0YSwgRmlsZSBwcmluY2lwYWxTdHlsZXNoZWV0LCBGaWxlIHByaW5jaXBhbCwKKyAgICAgICAgICAgICAgICBTdHJpbmcgb3BlcmF0aW9uLCBTdHJpbmcgY29tcGFyZUFzKSB7CisgICAgICAgICAgICBzdXBlcigidGVzdCIpOworICAgICAgICAgICAgdGhpcy5jYXRlZ29yeSA9IGNhdGVnb3J5OworICAgICAgICAgICAgdGhpcy5pZCA9IGlkOworICAgICAgICAgICAgdGhpcy5wdXJwb3NlID0gcHVycG9zZTsKKyAgICAgICAgICAgIHRoaXMuc3BlYyA9IHNwZWM7CisgICAgICAgICAgICB0aGlzLnByaW5jaXBhbERhdGEgPSBwcmluY2lwYWxEYXRhOworICAgICAgICAgICAgdGhpcy5wcmluY2lwYWxTdHlsZXNoZWV0ID0gcHJpbmNpcGFsU3R5bGVzaGVldDsKKyAgICAgICAgICAgIHRoaXMucHJpbmNpcGFsID0gcHJpbmNpcGFsOworICAgICAgICAgICAgdGhpcy5vcGVyYXRpb24gPSBvcGVyYXRpb247CisgICAgICAgICAgICB0aGlzLmNvbXBhcmVBcyA9IGNvbXBhcmVBczsKKyAgICAgICAgfQorCisgICAgICAgIFhzbHRUZXN0KEZpbGUgcHJpbmNpcGFsRGF0YSwgRmlsZSBwcmluY2lwYWxTdHlsZXNoZWV0LCBGaWxlIHByaW5jaXBhbCkgeworICAgICAgICAgICAgdGhpcygic3RhbmRhbG9uZSIsICJ0ZXN0IiwgIiIsICIiLAorICAgICAgICAgICAgICAgICAgICBwcmluY2lwYWxEYXRhLCBwcmluY2lwYWxTdHlsZXNoZWV0LCBwcmluY2lwYWwsICJzdGFuZGFyZCIsICJYTUwiKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHRlc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChwdXJwb3NlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlB1cnBvc2U6ICIgKyBwdXJwb3NlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzcGVjICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlNwZWM6ICIgKyBzcGVjKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgUmVzdWx0IHJlc3VsdDsKKyAgICAgICAgICAgIGlmICgiWE1MIi5lcXVhbHMoY29tcGFyZUFzKSkgeworICAgICAgICAgICAgICAgIERPTVJlc3VsdCBkb21SZXN1bHQgPSBuZXcgRE9NUmVzdWx0KCk7CisgICAgICAgICAgICAgICAgZG9tUmVzdWx0LnNldE5vZGUoZG9jdW1lbnRCdWlsZGVyLm5ld0RvY3VtZW50KCkuY3JlYXRlRWxlbWVudE5TKCIiLCAicmVzdWx0IikpOworICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRvbVJlc3VsdDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IFN0cmVhbVJlc3VsdChuZXcgU3RyaW5nV3JpdGVyKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBFcnJvclJlY29yZGVyIGVycm9yUmVjb3JkZXIgPSBuZXcgRXJyb3JSZWNvcmRlcigpOworICAgICAgICAgICAgdHJhbnNmb3JtZXJGYWN0b3J5LnNldEVycm9yTGlzdGVuZXIoZXJyb3JSZWNvcmRlcik7CisKKyAgICAgICAgICAgIFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTb3VyY2UgeHNsdCA9IG5ldyBTdHJlYW1Tb3VyY2UocHJpbmNpcGFsU3R5bGVzaGVldCk7CisgICAgICAgICAgICAgICAgdHJhbnNmb3JtZXIgPSB0cmFuc2Zvcm1lckZhY3RvcnkubmV3VHJhbnNmb3JtZXIoeHNsdCk7CisgICAgICAgICAgICAgICAgaWYgKGVycm9yUmVjb3JkZXIuZXJyb3IgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lci5zZXRFcnJvckxpc3RlbmVyKGVycm9yUmVjb3JkZXIpOworICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lci50cmFuc2Zvcm0obmV3IFN0cmVhbVNvdXJjZShwcmluY2lwYWxEYXRhKSwgcmVzdWx0KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGVycm9yUmVjb3JkZXIuZmF0YWxFcnJvcihlKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKG9wZXJhdGlvbi5lcXVhbHMoInN0YW5kYXJkIikpIHsKKyAgICAgICAgICAgICAgICBpZiAoZXJyb3JSZWNvcmRlci5lcnJvciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IGVycm9yUmVjb3JkZXIuZXJyb3I7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmIChvcGVyYXRpb24uZXF1YWxzKCJleGVjdXRpb24tZXJyb3IiKSkgeworICAgICAgICAgICAgICAgIGlmIChlcnJvclJlY29yZGVyLmVycm9yICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCAiICsgb3BlcmF0aW9uICsgIiwgYnV0IHRyYW5zZm9ybSBjb21wbGV0ZWQgbm9ybWFsbHkuIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAiIChXYXJuaW5nPSIgKyBlcnJvclJlY29yZGVyLndhcm5pbmcgKyAiKSIpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlVuZXhwZWN0ZWQgb3BlcmF0aW9uOiAiICsgb3BlcmF0aW9uKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKCJYTUwiLmVxdWFscyhjb21wYXJlQXMpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm9kZXNBcmVFcXVpdmFsZW50KHByaW5jaXBhbCwgKChET01SZXN1bHQpIHJlc3VsdCkuZ2V0Tm9kZSgpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gVE9ETzogaW1wbGVtZW50IHN1cHBvcnQgZm9yIGNvbXBhcmluZyBIVE1MIGV0Yy4KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIkNhbm5vdCBjb21wYXJlIGFzICIgKyBjb21wYXJlQXMpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBjYXRlZ29yeSArICIuIiArIGlkOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5zdXJlcyBib3RoIFhNTCBkb2N1bWVudHMgcmVwcmVzZW50IHRoZSBzYW1lIHNlbWFudGljIGRhdGEuIE5vbi1zZW1hbnRpYworICAgICAqIGRhdGEgc3VjaCBhcyBuYW1lc3BhY2UgcHJlZml4ZXMsIGNvbW1lbnRzLCBhbmQgd2hpdGVzcGFjZSBpcyBpZ25vcmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGFjdHVhbCBhbiBYTUwgZG9jdW1lbnQgd2hvc2Ugcm9vdCBpcyBhIHtAY29kZSA8cmVzdWx0Pn0gZWxlbWVudC4KKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWQgYSBmaWxlIGNvbnRhaW5pbmcgYW4gWE1MIGRvY3VtZW50IGZyYWdtZW50LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhc3NlcnROb2Rlc0FyZUVxdWl2YWxlbnQoRmlsZSBleHBlY3RlZCwgTm9kZSBhY3R1YWwpCisgICAgICAgICAgICB0aHJvd3MgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiwKKyAgICAgICAgICAgIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworCisgICAgICAgIE5vZGUgZXhwZWN0ZWROb2RlID0gZmlsZVRvUmVzdWx0Tm9kZShleHBlY3RlZCk7CisgICAgICAgIFN0cmluZyBleHBlY3RlZFN0cmluZyA9IG5vZGVUb05vcm1hbGl6ZWRTdHJpbmcoZXhwZWN0ZWROb2RlKTsKKyAgICAgICAgU3RyaW5nIGFjdHVhbFN0cmluZyA9IG5vZGVUb05vcm1hbGl6ZWRTdHJpbmcoYWN0dWFsKTsKKworICAgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCJFeHBlY3RlZCBYTUwgdG8gbWF0Y2ggZmlsZSAiICsgZXhwZWN0ZWQsCisgICAgICAgICAgICAgICAgZXhwZWN0ZWRTdHJpbmcsIGFjdHVhbFN0cmluZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZ2l2ZW4gZmlsZSdzIFhNTCBmcmFnbWVudCBhcyBhIHNpbmdsZSBub2RlLCB3cmFwcGVkIGluCisgICAgICoge0Bjb2RlIDxyZXN1bHQ+fSB0YWdzLiBUaGlzIHRha2VzIGNhcmUgb2Ygbm9ybWFsaXppbmcgdGhlIGZvbGxvd2luZworICAgICAqIGNvbmRpdGlvbnM6CisgICAgICoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPkZpbGVzIGNvbnRhaW5pbmcgWE1MIGRvY3VtZW50IGZyYWdtZW50cyB3aXRoIG11bHRpcGxlIGVsZW1lbnRzOgorICAgICAqIHtAY29kZSA8U1BBTiBzdHlsZT0iY29sb3I9Ymx1ZSI+U211cmZzITwvU1BBTj48YnIgLz59CisgICAgICoKKyAgICAgKiA8bGk+RmlsZXMgY29udGFpbmluZyBYTUwgZG9jdW1lbnQgZnJhZ21lbnRzIHdpdGggbm8gZWxlbWVudHM6CisgICAgICoge0Bjb2RlIFNtdXJmcyF9CisgICAgICoKKyAgICAgKiA8bGk+RmlsZXMgY29udGFpbmluZyBwcm9wZXIgWE1MIGRvY3VtZW50cyB3aXRoIGEgc2luZ2xlIGVsZW1lbnQgYW5kIGFuCisgICAgICogWE1MIGRlY2xhcmF0aW9uOgorICAgICAqIHtAY29kZSA8P3htbCB2ZXJzaW9uPSIxLjAiPz48ZG9jIC8+fQorICAgICAqCisgICAgICogPGxpPkZpbGVzIHByZWZpeGVkIHdpdGggYSBieXRlIG9yZGVyIG1hcmsgaGVhZGVyLCBzdWNoIGFzIDB4RUZCQkJGLgorICAgICAqIDwvdWw+CisgICAgICovCisgICAgcHJpdmF0ZSBOb2RlIGZpbGVUb1Jlc3VsdE5vZGUoRmlsZSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyByYXdDb250ZW50cyA9IGZpbGVUb1N0cmluZyhmaWxlKTsKKyAgICAgICAgU3RyaW5nIGZyYWdtZW50ID0gcmF3Q29udGVudHM7CisKKyAgICAgICAgLy8gSWYgdGhlIGZpbGUgaGFkIGFuIFhNTCBkZWNsYXJhdGlvbiwgc3RyaXAgdGhhdC4gT3RoZXJ3aXNlIHdyYXBwaW5nCisgICAgICAgIC8vIGl0IGluIDxyZXN1bHQ+IHRhZ3Mgd291bGQgcmVzdWx0IGluIGEgbWFsZm9ybWVkIFhNTCBkb2N1bWVudC4KKyAgICAgICAgaWYgKGZyYWdtZW50LnN0YXJ0c1dpdGgoIjw/eG1sIikpIHsKKyAgICAgICAgICAgIGludCBkZWNsYXJhdGlvbkVuZCA9IGZyYWdtZW50LmluZGV4T2YoIj8+Iik7CisgICAgICAgICAgICBmcmFnbWVudCA9IGZyYWdtZW50LnN1YnN0cmluZyhkZWNsYXJhdGlvbkVuZCArIDIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gUGFyc2UgaXQgYXMgZG9jdW1lbnQgZnJhZ21lbnQgd3JhcHBlZCBpbiA8cmVzdWx0PiB0YWdzLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgZnJhZ21lbnQgPSAiPHJlc3VsdD4iICsgZnJhZ21lbnQgKyAiPC9yZXN1bHQ+IjsKKyAgICAgICAgICAgIHJldHVybiBkb2N1bWVudEJ1aWxkZXIucGFyc2UobmV3IElucHV0U291cmNlKG5ldyBTdHJpbmdSZWFkZXIoZnJhZ21lbnQpKSkKKyAgICAgICAgICAgICAgICAgICAgLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgICB9IGNhdGNoIChTQVhQYXJzZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBFcnJvciBlcnJvciA9IG5ldyBBc3NlcnRpb25GYWlsZWRFcnJvcigKKyAgICAgICAgICAgICAgICAgICAgIkZhaWxlZCB0byBwYXJzZSBYTUw6ICIgKyBmaWxlICsgIlxuIiArIHJhd0NvbnRlbnRzKTsKKyAgICAgICAgICAgIGVycm9yLmluaXRDYXVzZShlKTsKKyAgICAgICAgICAgIHRocm93IGVycm9yOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgbm9kZVRvTm9ybWFsaXplZFN0cmluZyhOb2RlIG5vZGUpCisgICAgICAgICAgICB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmdXcml0ZXIgd3JpdGVyID0gbmV3IFN0cmluZ1dyaXRlcigpOworICAgICAgICBYbWxTZXJpYWxpemVyIHhtbFNlcmlhbGl6ZXIgPSB4bWxQdWxsUGFyc2VyRmFjdG9yeS5uZXdTZXJpYWxpemVyKCk7CisgICAgICAgIHhtbFNlcmlhbGl6ZXIuc2V0RmVhdHVyZSgiaHR0cDovL3htbHB1bGwub3JnL3YxL2RvYy9mZWF0dXJlcy5odG1sI2luZGVudC1vdXRwdXQiLCB0cnVlKTsKKyAgICAgICAgeG1sU2VyaWFsaXplci5zZXRPdXRwdXQod3JpdGVyKTsKKyAgICAgICAgZW1pdE5vZGUoeG1sU2VyaWFsaXplciwgbm9kZSk7CisgICAgICAgIHhtbFNlcmlhbGl6ZXIuZmx1c2goKTsKKyAgICAgICAgcmV0dXJuIHdyaXRlci50b1N0cmluZygpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBlbWl0Tm9kZShYbWxTZXJpYWxpemVyIHNlcmlhbGl6ZXIsIE5vZGUgbm9kZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJDYW5ub3QgZW1pdCBudWxsIG5vZGVzIik7CisKKyAgICAgICAgfSBlbHNlIGlmIChub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKKyAgICAgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IChFbGVtZW50KSBub2RlOworICAgICAgICAgICAgc2VyaWFsaXplci5zdGFydFRhZyhlbGVtZW50LmdldE5hbWVzcGFjZVVSSSgpLCBlbGVtZW50LmdldExvY2FsTmFtZSgpKTsKKyAgICAgICAgICAgIGVtaXRBdHRyaWJ1dGVzKHNlcmlhbGl6ZXIsIGVsZW1lbnQpOworICAgICAgICAgICAgZW1pdENoaWxkcmVuKHNlcmlhbGl6ZXIsIGVsZW1lbnQpOworICAgICAgICAgICAgc2VyaWFsaXplci5lbmRUYWcoZWxlbWVudC5nZXROYW1lc3BhY2VVUkkoKSwgZWxlbWVudC5nZXRMb2NhbE5hbWUoKSk7CisKKyAgICAgICAgfSBlbHNlIGlmIChub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUKKyAgICAgICAgICAgICAgICB8fCBub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5DREFUQV9TRUNUSU9OX05PREUpIHsKKyAgICAgICAgICAgIC8vIFRPRE86IGlzIGl0IG9rYXkgdG8gdHJpbSB3aGl0ZXNwYWNlIGluIGdlbmVyYWw/IFRoaXMgbWF5IGNhdXNlCisgICAgICAgICAgICAvLyAgICAgZmFsc2UgcG9zaXRpdmVzIGZvciBlbGVtZW50cyBsaWtlIEhUTUwncyA8cHJlPiB0YWcKKyAgICAgICAgICAgIFN0cmluZyB0cmltbWVkID0gbm9kZS5nZXRUZXh0Q29udGVudCgpLnRyaW0oKTsKKyAgICAgICAgICAgIGlmICh0cmltbWVkLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgICAgIHNlcmlhbGl6ZXIudGV4dCh0cmltbWVkKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9IGVsc2UgaWYgKG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpIHsKKyAgICAgICAgICAgIERvY3VtZW50IGRvY3VtZW50ID0gKERvY3VtZW50KSBub2RlOworICAgICAgICAgICAgc2VyaWFsaXplci5zdGFydERvY3VtZW50KCJVVEYtOCIsIHRydWUpOworICAgICAgICAgICAgZW1pdE5vZGUoc2VyaWFsaXplciwgZG9jdW1lbnQuZ2V0RG9jdW1lbnRFbGVtZW50KCkpOworICAgICAgICAgICAgc2VyaWFsaXplci5lbmREb2N1bWVudCgpOworCisgICAgICAgIH0gZWxzZSBpZiAobm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFKSB7CisgICAgICAgICAgICBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gcHJvY2Vzc2luZ0luc3RydWN0aW9uID0gKFByb2Nlc3NpbmdJbnN0cnVjdGlvbikgbm9kZTsKKyAgICAgICAgICAgIFN0cmluZyBkYXRhID0gcHJvY2Vzc2luZ0luc3RydWN0aW9uLmdldERhdGEoKTsKKyAgICAgICAgICAgIFN0cmluZyB0YXJnZXQgPSBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24uZ2V0VGFyZ2V0KCk7CisgICAgICAgICAgICBzZXJpYWxpemVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQgKyAiICIgKyBkYXRhKTsKKworICAgICAgICB9IGVsc2UgaWYgKG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkNPTU1FTlRfTk9ERSkgeworICAgICAgICAgICAgLy8gaWdub3JlIQorCisgICAgICAgIH0gZWxzZSBpZiAobm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFKSB7CisgICAgICAgICAgICBFbnRpdHlSZWZlcmVuY2UgZW50aXR5UmVmZXJlbmNlID0gKEVudGl0eVJlZmVyZW5jZSkgbm9kZTsKKyAgICAgICAgICAgIHNlcmlhbGl6ZXIuZW50aXR5UmVmKGVudGl0eVJlZmVyZW5jZS5nZXROb2RlTmFtZSgpKTsKKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IGVtaXQgIiArIG5vZGUgKyAiIG9mIHR5cGUgIiArIG5vZGUuZ2V0Tm9kZVR5cGUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZW1pdEF0dHJpYnV0ZXMoWG1sU2VyaWFsaXplciBzZXJpYWxpemVyLCBOb2RlIG5vZGUpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBOYW1lZE5vZGVNYXAgbWFwID0gbm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAgIGlmIChtYXAgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgTGlzdDxBdHRyPiBhdHRyaWJ1dGVzID0gbmV3IEFycmF5TGlzdDxBdHRyPigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1hcC5nZXRMZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBhdHRyaWJ1dGVzLmFkZCgoQXR0cikgbWFwLml0ZW0oaSkpOworICAgICAgICB9CisgICAgICAgIENvbGxlY3Rpb25zLnNvcnQoYXR0cmlidXRlcywgb3JkZXJCeU5hbWUpOworCisgICAgICAgIGZvciAoQXR0ciBhdHRyIDogYXR0cmlidXRlcykgeworICAgICAgICAgICAgaWYgKCJ4bWxucyIuZXF1YWxzKGF0dHIuZ2V0UHJlZml4KCkpIHx8ICJ4bWxucyIuZXF1YWxzKGF0dHIuZ2V0TG9jYWxOYW1lKCkpKSB7CisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgKiBPbWl0IG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgYmVjYXVzZSB0aGV5IGFyZW4ndCBjb25zaWRlcmVkCisgICAgICAgICAgICAgICAgICogZGF0YS4gSWUuIDxmb286YSB4bWxuczpiYXI9Imh0dHA6Ly9nb29nbGUuY29tIj4gaXMgc2VtYW50aWNhbGx5CisgICAgICAgICAgICAgICAgICogZXF1YWwgdG8gPGJhcjphIHhtbG5zOmJhcj0iaHR0cDovL2dvb2dsZS5jb20iPiBzaW5jZSB0aGUKKyAgICAgICAgICAgICAgICAgKiBwcmVmaXggZG9lc24ndCBtYXR0ZXIsIG9ubHkgdGhlIFVSSSBpdCBwb2ludHMgdG8uCisgICAgICAgICAgICAgICAgICoKKyAgICAgICAgICAgICAgICAgKiBXaGVuIHdlIG9taXQgdGhlIHByZWZpeCwgb3VyIFhNTCBzZXJpYWxpemVyIHdpbGwgc3RpbGwKKyAgICAgICAgICAgICAgICAgKiBnZW5lcmF0ZSBvbmUgZm9yIHVzLCB1c2luZyBhIHByZWRpY3RhYmxlIHBhdHRlcm4uCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHNlcmlhbGl6ZXIuYXR0cmlidXRlKGF0dHIuZ2V0TmFtZXNwYWNlVVJJKCksIGF0dHIuZ2V0TG9jYWxOYW1lKCksIGF0dHIuZ2V0VmFsdWUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZW1pdENoaWxkcmVuKFhtbFNlcmlhbGl6ZXIgc2VyaWFsaXplciwgTm9kZSBub2RlKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgTm9kZUxpc3QgY2hpbGROb2RlcyA9IG5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoaWxkTm9kZXMuZ2V0TGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgZW1pdE5vZGUoc2VyaWFsaXplciwgY2hpbGROb2Rlcy5pdGVtKGkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIExpc3Q8RWxlbWVudD4gZWxlbWVudHNPZihOb2RlTGlzdCBub2RlTGlzdCkgeworICAgICAgICBMaXN0PEVsZW1lbnQ+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8RWxlbWVudD4oKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBub2RlTGlzdC5nZXRMZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBOb2RlIG5vZGUgPSBub2RlTGlzdC5pdGVtKGkpOworICAgICAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBFbGVtZW50KSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFkZCgoRWxlbWVudCkgbm9kZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB0aGUgZ2l2ZW4gZmlsZSBpbnRvIGEgc3RyaW5nLiBJZiB0aGUgZmlsZSBjb250YWlucyBhIGJ5dGUgb3JkZXIKKyAgICAgKiBtYXJrLCB0aGUgY29ycmVzcG9uZGluZyBjaGFyYWN0ZXIgc2V0IHdpbGwgYmUgdXNlZC4gT3RoZXJ3aXNlIHRoZSBzeXN0ZW0KKyAgICAgKiBkZWZhdWx0IGNoYXJzZXQgd2lsbCBiZSB1c2VkLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGZpbGVUb1N0cmluZyhGaWxlIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKSwgMTAyNCk7CisKKyAgICAgICAgLy8gUmVhZCB0aGUgYnl0ZSBvcmRlciBtYXJrIHRvIGRldGVybWluZSB0aGUgY2hhcnNldC4KKyAgICAgICAgLy8gVE9ETzogdXNlIGEgYnVpbHQtaW4gQVBJIGZvciB0aGlzLi4uCisgICAgICAgIFJlYWRlciByZWFkZXI7CisgICAgICAgIGluLm1hcmsoMyk7CisgICAgICAgIGludCBieXRlMSA9IGluLnJlYWQoKTsKKyAgICAgICAgaW50IGJ5dGUyID0gaW4ucmVhZCgpOworICAgICAgICBpZiAoYnl0ZTEgPT0gMHhGRiAmJiBieXRlMiA9PSAweEZFKSB7CisgICAgICAgICAgICByZWFkZXIgPSBuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaW4sICJVVEYtMTZMRSIpOworICAgICAgICB9IGVsc2UgaWYgKGJ5dGUxID09IDB4RkYgJiYgYnl0ZTIgPT0gMHhGRikgeworICAgICAgICAgICAgcmVhZGVyID0gbmV3IElucHV0U3RyZWFtUmVhZGVyKGluLCAiVVRGLTE2QkUiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGludCBieXRlMyA9IGluLnJlYWQoKTsKKyAgICAgICAgICAgIGlmIChieXRlMSA9PSAweEVGICYmIGJ5dGUyID09IDB4QkIgJiYgYnl0ZTMgPT0gMHhCRikgeworICAgICAgICAgICAgICAgIHJlYWRlciA9IG5ldyBJbnB1dFN0cmVhbVJlYWRlcihpbiwgIlVURi04Iik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGluLnJlc2V0KCk7CisgICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3IElucHV0U3RyZWFtUmVhZGVyKGluKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ1dyaXRlciBvdXQgPSBuZXcgU3RyaW5nV3JpdGVyKCk7CisgICAgICAgIGNoYXJbXSBidWZmZXIgPSBuZXcgY2hhclsxMDI0XTsKKyAgICAgICAgaW50IGNvdW50OworICAgICAgICB3aGlsZSAoKGNvdW50ID0gcmVhZGVyLnJlYWQoYnVmZmVyKSkgIT0gLTEpIHsKKyAgICAgICAgICAgIG91dC53cml0ZShidWZmZXIsIDAsIGNvdW50KTsKKyAgICAgICAgfQorICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICByZXR1cm4gb3V0LnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIEVycm9yUmVjb3JkZXIgaW1wbGVtZW50cyBFcnJvckxpc3RlbmVyIHsKKyAgICAgICAgRXhjZXB0aW9uIHdhcm5pbmc7CisgICAgICAgIEV4Y2VwdGlvbiBlcnJvcjsKKworICAgICAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGV4Y2VwdGlvbikgeworICAgICAgICAgICAgaWYgKHRoaXMud2FybmluZyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhpcy53YXJuaW5nID0gZXhjZXB0aW9uOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgZXJyb3IoVHJhbnNmb3JtZXJFeGNlcHRpb24gZXhjZXB0aW9uKSB7CisgICAgICAgICAgICBpZiAodGhpcy5lcnJvciA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoVHJhbnNmb3JtZXJFeGNlcHRpb24gZXhjZXB0aW9uKSB7CisgICAgICAgICAgICBpZiAodGhpcy5lcnJvciA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvYW5ub3RhdGlvbi90ZXN0cy9qYXZhL2xhbmcvYW5ub3RhdGlvbi9Bbm5vdGF0aW9uRm9ybWF0RXJyb3JUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2Fubm90YXRpb24vdGVzdHMvamF2YS9sYW5nL2Fubm90YXRpb24vQW5ub3RhdGlvbkZvcm1hdEVycm9yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMzMDkzN2YKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2Fubm90YXRpb24vdGVzdHMvamF2YS9sYW5nL2Fubm90YXRpb24vQW5ub3RhdGlvbkZvcm1hdEVycm9yVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmFubm90YXRpb24udGVzdHMuamF2YS5sYW5nLmFubm90YXRpb247CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5Bbm5vdGF0aW9uRm9ybWF0RXJyb3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBBbm5vdGF0aW9uRm9ybWF0RXJyb3JUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RfY29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgQW5ub3RhdGlvbkZvcm1hdEVycm9yIGUgPSBuZXcgQW5ub3RhdGlvbkZvcm1hdEVycm9yKCJzb21lIG1lc3NhZ2UiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzb21lIG1lc3NhZ2UiLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25zdHJ1Y3RvckxqYXZhX2xhbmdfVGhyb3dhYmxlKCkgeworICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlID0gbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICBBbm5vdGF0aW9uRm9ybWF0RXJyb3IgZSA9IG5ldyBBbm5vdGF0aW9uRm9ybWF0RXJyb3IoaWFlKTsKKyAgICAgICAgYXNzZXJ0U2FtZShpYWUsIGUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25zdHJ1Y3RvckxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19UaHJvd2FibGUoKSB7CisgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUgPSBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIEFubm90YXRpb25Gb3JtYXRFcnJvciBlID0gbmV3IEFubm90YXRpb25Gb3JtYXRFcnJvcigic29tZSBtZXNzYWdlIiwgaWFlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzb21lIG1lc3NhZ2UiLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydFNhbWUoaWFlLCBlLmdldENhdXNlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvYW5ub3RhdGlvbi90ZXN0cy9qYXZhL2xhbmcvYW5ub3RhdGlvbi9Bbm5vdGF0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9hbm5vdGF0aW9uL3Rlc3RzL2phdmEvbGFuZy9hbm5vdGF0aW9uL0Fubm90YXRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzNjZThmYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvYW5ub3RhdGlvbi90ZXN0cy9qYXZhL2xhbmcvYW5ub3RhdGlvbi9Bbm5vdGF0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDMxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hbm5vdGF0aW9uLnRlc3RzLmphdmEubGFuZy5hbm5vdGF0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogVGVzdCBjYXNlIG9mIGphdmEubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb24KKyAqLworcHVibGljIGNsYXNzIEFubm90YXRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF9hbm5vdGF0aW9uVHlwZSgpIHsKKyAgICAgICAgQW5ub3RhdGlvbiBbXSBhbm5vdGF0aW9ucyA9IEFubm90YXRlZENsYXNzLmNsYXNzLmdldERlY2xhcmVkQW5ub3RhdGlvbnMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGFubm90YXRpb25zLmxlbmd0aCk7CisgICAgICAgIEFubm90YXRpb24gYW5ubyA9IGFubm90YXRpb25zWzBdOworICAgICAgICBhc3NlcnRFcXVhbHMoVGVzdEFubm90YXRpb24xLmNsYXNzLCBhbm5vLmFubm90YXRpb25UeXBlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIHRlc3QgdHlwZQorICAgICAgICBNZXRob2QgbTEgPSBBbm5vdGF0ZWRDbGFzczIuY2xhc3MKKyAgICAgICAgICAgICAgICAuZ2V0RGVjbGFyZWRNZXRob2QoImEiLCBuZXcgQ2xhc3NbXSB7fSk7CisgICAgICAgIE1ldGhvZCBtMiA9IEFubm90YXRlZENsYXNzMi5jbGFzcworICAgICAgICAgICAgICAgIC5nZXREZWNsYXJlZE1ldGhvZCgiYiIsIG5ldyBDbGFzc1tdIHt9KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIm90aGVyIGFubm90YXRpb24gY2xhc3MgdHlwZSIsCisgICAgICAgICAgICAgICAgbTEuZ2V0RGVjbGFyZWRBbm5vdGF0aW9ucygpWzBdLmVxdWFscyhtMgorICAgICAgICAgICAgICAgICAgICAgICAgLmdldERlY2xhcmVkQW5ub3RhdGlvbnMoKVswXSkpOworCisgICAgICAgIC8vIHRlc3QgZXF1YWxpdHkgLyBub24gZXF1YWxpdHkgZm9yIGJhc2UgdHlwZXMgYW5kIGNvbXBvdW5kIHR5cGVzCisgICAgICAgIExpc3Q8TWV0aG9kPiBtZXRob2RzID0gQXJyYXlzLmFzTGlzdChBbm5vdGF0ZWRDbGFzcy5jbGFzcy5nZXREZWNsYXJlZE1ldGhvZHMoKSk7CisgICAgICAgIE1hcDxTdHJpbmcsIExpc3Q8TWV0aG9kPj4gZXFzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBMaXN0PE1ldGhvZD4+KCk7CisgICAgICAgIE1hcDxTdHJpbmcsIExpc3Q8TWV0aG9kPj4gbmVxcyA9IG5ldyBIYXNoTWFwPFN0cmluZywgTGlzdDxNZXRob2Q+PigpOworICAgICAgICBmb3IgKE1ldGhvZCBtIDogbWV0aG9kcykgeworICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBtLmdldE5hbWUoKTsKKyAgICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJuYW1lICIrbmFtZSk7CisgICAgICAgICAgICBNYXA8U3RyaW5nLCBMaXN0PE1ldGhvZD4+IGN1clQgPSBuYW1lLmNoYXJBdCgwKSA9PSAnZSc/IGVxcyA6IG5lcXM7CisgICAgICAgICAgICBTdHJpbmcgdGVzdE51bSA9IG5hbWUuc3Vic3RyaW5nKDEsMyk7IC8vIDAxCisgICAgICAgICAgICBMaXN0PE1ldGhvZD4gbWxpc3QgPSBjdXJULmdldCh0ZXN0TnVtKTsKKyAgICAgICAgICAgIGlmIChtbGlzdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgbWxpc3QgPSBuZXcgQXJyYXlMaXN0PE1ldGhvZD4oKTsKKyAgICAgICAgICAgICAgICBjdXJULnB1dCh0ZXN0TnVtLCBtbGlzdCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtbGlzdC5hZGQoQW5ub3RhdGVkQ2xhc3MuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QobmFtZSwgbmV3IENsYXNzW10ge30pKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoTGlzdDxNZXRob2Q+IGVxTGlzdCA6IGVxcy52YWx1ZXMoKSkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlcUxpc3Quc2l6ZSgpIC0xOyBpKyspIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gaSsxOyBqIDwgZXFMaXN0LnNpemUoKTsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgIE1ldGhvZCBtZTEgPSBlcUxpc3QuZ2V0KGkpOworICAgICAgICAgICAgICAgICAgICBNZXRob2QgbWUyID0gZXFMaXN0LmdldChqKTsKKyAgICAgICAgICAgICAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oImVxIHRlc3QgZm9yICIrbWUxLmdldE5hbWUoKSsiLCAiK21lMi5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgICAgICBBbm5vdGF0aW9uIGExID0gbWUxLmdldERlY2xhcmVkQW5ub3RhdGlvbnMoKVswXTsKKyAgICAgICAgICAgICAgICAgICAgQW5ub3RhdGlvbiBhMiA9IG1lMi5nZXREZWNsYXJlZEFubm90YXRpb25zKClbMF07CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygibXVzdCBiZSBlcXVhbCA6IG1ldGhvZDE6IittZTEuZ2V0TmFtZSgpKyIsIG1ldGhvZDI6ICIrbWUyLmdldE5hbWUoKSwgYTEsIGEyKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJzYW1lIGhhc2hjb2RlIiwgYTEuaGFzaENvZGUoKSwgYTIuaGFzaENvZGUoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChMaXN0PE1ldGhvZD4gZXFMaXN0IDogbmVxcy52YWx1ZXMoKSkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlcUxpc3Quc2l6ZSgpIC0xOyBpKyspIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gaSsxOyBqIDwgZXFMaXN0LnNpemUoKTsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgIE1ldGhvZCBtZTEgPSBlcUxpc3QuZ2V0KGkpOworICAgICAgICAgICAgICAgICAgICBNZXRob2QgbWUyID0gZXFMaXN0LmdldChqKTsKKyAgICAgICAgICAgICAgICAgICAgQW5ub3RhdGlvbiBhMSA9IG1lMS5nZXREZWNsYXJlZEFubm90YXRpb25zKClbMF07CisgICAgICAgICAgICAgICAgICAgIEFubm90YXRpb24gYTIgPSBtZTIuZ2V0RGVjbGFyZWRBbm5vdGF0aW9ucygpWzBdOworICAgICAgICAgICAgICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigibmUgdGVzdCBmb3IgIittZTEuZ2V0TmFtZSgpKyIsICIrbWUyLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKCJtdXN0IG5vdCBiZSBlcXVhbCA6IG1ldGhvZDE6IittZTEuZ2V0TmFtZSgpKyIsIG1ldGhvZDI6ICIrbWUyLmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhMS5lcXVhbHMoYTIpKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGExLmhhc2hDb2RlKCkgIT0gYTIuaGFzaENvZGUoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIm5vdCBzYW1lIGhhc2hjb2RlIC0+IG5vdCBlcXVhbHMiLCBhMS5lcXVhbHMoYTIpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSgpIHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiwgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIHsKKyAgICAgICAgQW5ub3RhdGlvbiBhMSA9IEFubm90YXRlZENsYXNzLmNsYXNzLmdldERlY2xhcmVkQW5ub3RhdGlvbnMoKVswXTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGExLmhhc2hDb2RlKCksICgxMjcgKiAidmFsdWUiLmhhc2hDb2RlKCkgXiAiZm9vYmFyIi5oYXNoQ29kZSgpKSk7CisgICAgICAgIC8vIGkrPSAxMjcgKihrZXkuaGFzaENvZGUoKSBeIG1lbWJlclZhbEhhc2hDb2RlKHZhbHVlKTsKKworICAgICAgICBNZXRob2QgbTEgPSBBbm5vdGF0ZWRDbGFzcy5jbGFzcy5nZXREZWNsYXJlZE1ldGhvZCgiZTM0YyIsIG5ldyBDbGFzc1tdIHt9KTsKKyAgICAgICAgaW50IGFyckhjID0gQXJyYXlzLmhhc2hDb2RlKG5ldyBPYmplY3RbXXt9KTsKKyAgICAgICAgLyoKKyAgICAgICAgVGVzdEFubm90YXRpb24zW10gYXJyQW5ubygpIGRlZmF1bHQge307CisgICAgICAgIFN0cmluZ1tdIGFyclN0cmluZygpIGRlZmF1bHQge307CisgICAgICAgIENsYXNzW10gYXJyQ2xhc3MoKSBkZWZhdWx0IHt9OworICAgICAgICBUZXN0RW51bTFbXSBhcnJFbnVtKCkgZGVmYXVsdCB7fTsKKyAgICAgICAgICovCisgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAoMTI3ICogImFyckFubm8iLmhhc2hDb2RlKCkgXiBhcnJIYykgKworICAgICAgICAgICAgICAgICgxMjcgKiAiYXJyU3RyaW5nIi5oYXNoQ29kZSgpIF4gYXJySGMpKworICAgICAgICAgICAgICAgICgxMjcgKiAiYXJyQ2xhc3MiLmhhc2hDb2RlKCkgXiBhcnJIYykgKworICAgICAgICAgICAgICAgICgxMjcgKiAiYXJyRW51bSIuaGFzaENvZGUoKSBeIGFyckhjKQorICAgICAgICAgICAgICAgICwKKyAgICAgICAgICAgICAgICBtMS5nZXREZWNsYXJlZEFubm90YXRpb25zKClbMF0uaGFzaENvZGUoKSk7CisKKyAgICAgICAgTWV0aG9kIG0yID0gQW5ub3RhdGVkQ2xhc3MzLmNsYXNzLmdldERlY2xhcmVkTWV0aG9kKCJhIiwgbmV3IENsYXNzW10ge30pOworICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgKDEyNyAqICJpIi5oYXNoQ29kZSgpIF4gMTIzNDUpLAorICAgICAgICAgICAgICAgIG0yLmdldERlY2xhcmVkQW5ub3RhdGlvbnMoKVswXS5oYXNoQ29kZSgpKTsKKworICAgIH0KK30KKworY2xhc3MgQW5ub3RhdGVkQ2xhc3MyIHsKKyAgICBAVGVzdEFubm90YXRpb24zKCkKKyAgICB2b2lkIGEoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjNiKCkKKyAgICB2b2lkIGIoKSB7fQorfQorCitjbGFzcyBBbm5vdGF0ZWRDbGFzczMgeworICAgIEBUZXN0QW5ub3RhdGlvbjQoaSA9IDEyMzQ1KQorICAgIHZvaWQgYSgpIHt9Cit9CisKK0BUZXN0QW5ub3RhdGlvbjEoImZvb2JhciIpCitjbGFzcyBBbm5vdGF0ZWRDbGFzcyB7CisKKyAgICAvLyAtLS0tLSBib29sZWFuIC0tLS0tCisgICAgQFRlc3RBbm5vdGF0aW9uMyh6ID0gZmFsc2UpCisgICAgdm9pZCBlMDFhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24zKHogPSBmYWxzZSkKKyAgICB2b2lkIGUwMWIoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjMoKQorICAgIHZvaWQgZTAxYygpIHt9CisKKyAgICBAVGVzdEFubm90YXRpb24zKHogPSB0cnVlKQorICAgIHZvaWQgZTAyYSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyh6ID0gdHJ1ZSkKKyAgICB2b2lkIGUwMmIoKSB7fQorCisgICAgQFRlc3RBbm5vdGF0aW9uMyh6ID0gZmFsc2UpCisgICAgdm9pZCBuMDNhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24zKHogPSB0cnVlKQorICAgIHZvaWQgbjAzYigpIHt9CisKKworICAgIC8vIC0tLS0tIGJ5dGUgLS0tLS0KKyAgICBAVGVzdEFubm90YXRpb24zKGIgPSAwKQorICAgIHZvaWQgZTA0YSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyhiID0gMCkKKyAgICB2b2lkIGUwNGIoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjMoKQorICAgIHZvaWQgZTA0YygpIHt9CisKKyAgICBAVGVzdEFubm90YXRpb24zKGI9IDEyNykKKyAgICB2b2lkIGUwNWEoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjMoYiA9IDEyNykKKyAgICB2b2lkIGUwNWIoKSB7fQorCisgICAgQFRlc3RBbm5vdGF0aW9uMyhiID0gLTEyOCkKKyAgICB2b2lkIG4wNmEoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjMoYiA9IDEyNykKKyAgICB2b2lkIG4wNmIoKSB7fQorCisKKyAgICAvLyAtLS0tLSBzaG9ydCAtLS0tLQorICAgIEBUZXN0QW5ub3RhdGlvbjMocyA9IDApCisgICAgdm9pZCBlMDdhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24zKHMgPSAwKQorICAgIHZvaWQgZTA3YigpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMygpCisgICAgdm9pZCBlMDdjKCkge30KKworICAgIEBUZXN0QW5ub3RhdGlvbjMocz0gMzI3NjcpCisgICAgdm9pZCBlMDhhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24zKHMgPSAzMjc2NykKKyAgICB2b2lkIGUwOGIoKSB7fQorCisgICAgQFRlc3RBbm5vdGF0aW9uMyhzID0gLTMyNzY4KQorICAgIHZvaWQgbjA5YSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyhzID0gMzI3NjcpCisgICAgdm9pZCBuMDliKCkge30KKworCisgICAgLy8gLS0tLS0gaW50IC0tLS0tCisgICAgQFRlc3RBbm5vdGF0aW9uMyhpID0gMTAwKQorICAgIHZvaWQgZTEwYSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyhpID0gMTAwKQorICAgIHZvaWQgZTEwYigpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMygpCisgICAgdm9pZCBlMTBjKCkge30KKworICAgIEBUZXN0QW5ub3RhdGlvbjMoaSA9IEludGVnZXIuTUFYX1ZBTFVFKQorICAgIHZvaWQgZTExYSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyhpID0gSW50ZWdlci5NQVhfVkFMVUUpCisgICAgdm9pZCBlMTFiKCkge30KKworICAgIEBUZXN0QW5ub3RhdGlvbjMoaSA9IEludGVnZXIuTUFYX1ZBTFVFKQorICAgIHZvaWQgbjEyYSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyhpID0gSW50ZWdlci5NSU5fVkFMVUUpCisgICAgdm9pZCBuMTJiKCkge30KKworCisgICAgLy8gLS0tLS0gbG9uZyAtLS0tLQorICAgIEBUZXN0QW5ub3RhdGlvbjMoaiA9IDApCisgICAgdm9pZCBlMTNhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24zKGogPSAwKQorICAgIHZvaWQgZTEzYigpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMygpCisgICAgdm9pZCBlMTNjKCkge30KKworICAgIEBUZXN0QW5ub3RhdGlvbjMoaiA9IExvbmcuTUFYX1ZBTFVFKQorICAgIHZvaWQgZTE0YSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyhqID0gTG9uZy5NQVhfVkFMVUUpCisgICAgdm9pZCBlMTRiKCkge30KKworICAgIEBUZXN0QW5ub3RhdGlvbjMoaiA9IExvbmcuTUFYX1ZBTFVFKQorICAgIHZvaWQgbjE1YSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyhqID0gTG9uZy5NSU5fVkFMVUUpCisgICAgdm9pZCBuMTViKCkge30KKworCisgICAgLy8gLS0tLS0gZmxvYXQgLS0tLS0KKyAgICBAVGVzdEFubm90YXRpb24zKGYgPSAwLjBmKQorICAgIHZvaWQgZTE2YSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyhmID0gMC4wZikKKyAgICB2b2lkIGUxNmIoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjMoKQorICAgIHZvaWQgZTE2YygpIHt9CisKKyAgICBAVGVzdEFubm90YXRpb24zKGYgPSBGbG9hdC5NQVhfVkFMVUUpCisgICAgdm9pZCBlMTdhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24zKGYgPSBGbG9hdC5NQVhfVkFMVUUpCisgICAgdm9pZCBlMTdiKCkge30KKworICAgIEBUZXN0QW5ub3RhdGlvbjMoZiA9IEZsb2F0Lk5hTikKKyAgICB2b2lkIGUxOGEoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjMoZiA9IEZsb2F0Lk5hTikKKyAgICB2b2lkIGUxOGIoKSB7fQorCisgICAgQFRlc3RBbm5vdGF0aW9uMyhmID0gTG9uZy5NQVhfVkFMVUUpCisgICAgdm9pZCBuMTlhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24zKGYgPSBMb25nLk1JTl9WQUxVRSkKKyAgICB2b2lkIG4xOWIoKSB7fQorCisgICAgQFRlc3RBbm5vdGF0aW9uMyhmID0gMC4wZikKKyAgICB2b2lkIG4yMGEoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjMoZiA9IC0wLjBmKQorICAgIHZvaWQgbjIwYigpIHt9CisKKworICAgIC8vIC0tLS0tIGRvdWJsZSAtLS0tLQorICAgIEBUZXN0QW5ub3RhdGlvbjMoZCA9IDAuMGQpCisgICAgdm9pZCBlMjFhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24zKGQgPSAwLjBkKQorICAgIHZvaWQgZTIxYigpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMygpCisgICAgdm9pZCBlMjFjKCkge30KKworICAgIEBUZXN0QW5ub3RhdGlvbjMoZCA9IERvdWJsZS5NQVhfVkFMVUUpCisgICAgdm9pZCBlMjJhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24zKGQgPSBEb3VibGUuTUFYX1ZBTFVFKQorICAgIHZvaWQgZTIyYigpIHt9CisKKyAgICBAVGVzdEFubm90YXRpb24zKGQgPSBEb3VibGUuTmFOKQorICAgIHZvaWQgZTIzYSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyhkID0gRG91YmxlLk5hTikKKyAgICB2b2lkIGUyM2IoKSB7fQorCisKKyAgICBAVGVzdEFubm90YXRpb24zKGQgPSBEb3VibGUuTUFYX1ZBTFVFKQorICAgIHZvaWQgbjI0YSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyhkID0gRG91YmxlLk1JTl9WQUxVRSkKKyAgICB2b2lkIG4yNGIoKSB7fQorCisgICAgQFRlc3RBbm5vdGF0aW9uMyhkID0gMC4wZCkKKyAgICB2b2lkIG4yNWEoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjMoZCA9IC0wLjBkKQorICAgIHZvaWQgbjI1YigpIHt9CisKKworIC8vIC0tLS0tIFN0cmluZyAtLS0tLQorICAgIEBUZXN0QW5ub3RhdGlvbjMoYVN0cmluZyA9ICIiKQorICAgIHZvaWQgZTI2YSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyhhU3RyaW5nID0gIiIpCisgICAgdm9pZCBlMjZiKCkge30KKyAgICBAVGVzdEFubm90YXRpb24zKCkKKyAgICB2b2lkIGUyNmMoKSB7fQorCisgICAgQFRlc3RBbm5vdGF0aW9uMyhhU3RyaW5nID0gImFzamRmayBqa2xzIGRmamtsc2QgZmtsc2QgamtsZHMga2ZsZHMgamZrbGRzZmpkIisiZCIpCisgICAgdm9pZCBlMjdhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24zKGFTdHJpbmcgPSAiYXNqZGZrIGprbHMgZGZqa2xzZCBma2xzZCBqa2xkcyBrZmxkcyBqZmtsZHNmaiIrImRkIikKKyAgICB2b2lkIGUyN2IoKSB7fQorCisgICAgQFRlc3RBbm5vdGF0aW9uMyhhU3RyaW5nID0gImEiKQorICAgIHZvaWQgbjI4YSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyhhU3RyaW5nID0gImIiKQorICAgIHZvaWQgbjI4YigpIHt9CisKKworICAgIC8vIC0tLS0tIENsYXNzLS0tLS0KKyAgICBAVGVzdEFubm90YXRpb24zKGFDbGF6eiA9IFZvaWQuY2xhc3MpCisgICAgdm9pZCBlMjlhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24zKGFDbGF6eiA9IFZvaWQuY2xhc3MpCisgICAgdm9pZCBlMjliKCkge30KKyAgICBAVGVzdEFubm90YXRpb24zKCkKKyAgICB2b2lkIGUyOWMoKSB7fQorCisgICAgQFRlc3RBbm5vdGF0aW9uMyhhQ2xhenogPSBJbnRlZ2VyLmNsYXNzKQorICAgIHZvaWQgbjMwYSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyhhQ2xhenogPSBpbnQuY2xhc3MpCisgICAgdm9pZCBuMzBiKCkge30KKworCisgICAgLy8gLS0tLS0gRW51bS0tLS0tCisgICAgQFRlc3RBbm5vdGF0aW9uMyhhRW51bSA9IFRlc3RFbnVtMS5GKQorICAgIHZvaWQgZTMxYSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyhhRW51bSA9IFRlc3RFbnVtMS5GKQorICAgIHZvaWQgZTMxYigpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMygpCisgICAgdm9pZCBlMzFjKCkge30KKworICAgIEBUZXN0QW5ub3RhdGlvbjMoYUVudW0gPSBUZXN0RW51bTEuRikKKyAgICB2b2lkIG4zMmEoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjMoYUVudW0gPSBUZXN0RW51bTEuQSkKKyAgICB2b2lkIG4zMmIoKSB7fQorCisgICAgQFRlc3RBbm5vdGF0aW9uMyhhRW51bSA9IFRlc3RFbnVtMS5GKQorICAgIHZvaWQgbjMzYSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMyhhRW51bSA9IFRlc3RFbnVtMS5MKQorICAgIHZvaWQgbjMzYigpIHt9CisKKworICAgIC8vIC0tLS0tIFN0cmluZyBhcnItLS0tLQorICAgIEBUZXN0QW5ub3RhdGlvbjIoYXJyU3RyaW5nID0ge30pCisgICAgdm9pZCBlMzRhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24yKGFyclN0cmluZyA9IHt9KQorICAgIHZvaWQgZTM0YigpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMihhcnJTdHJpbmcgPSB7fSkKKyAgICB2b2lkIGUzNGMoKSB7fQorCisgICAgQFRlc3RBbm5vdGF0aW9uMihhcnJTdHJpbmcgPSB7ICJhIiwgImIifSkKKyAgICB2b2lkIGUzNWEoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjIoYXJyU3RyaW5nID0geyAiYSIsICJiIiB9KQorICAgIHZvaWQgZTM1YigpIHt9CisKKyAgICBAVGVzdEFubm90YXRpb24yKGFyclN0cmluZyA9IHsgImEiLCAiYiJ9KQorICAgIHZvaWQgbjM2YSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMihhcnJTdHJpbmcgPSB7ICJhIiwgImMiIH0pCisgICAgdm9pZCBuMzZiKCkge30KKworCisgICAgLy8gLS0tLS0gQ2xhc3MgYXJyLS0tLS0KKyAgICBAVGVzdEFubm90YXRpb24yKGFyckNsYXNzPSB7fSkKKyAgICB2b2lkIGUzN2EoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjIoYXJyQ2xhc3MgPSB7fSkKKyAgICB2b2lkIGUzN2IoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjIoYXJyQ2xhc3MgPSB7fSkKKyAgICB2b2lkIGUzN2MoKSB7fQorCisgICAgQFRlc3RBbm5vdGF0aW9uMihhcnJDbGFzcyA9IHsgVm9pZC5jbGFzcywgSW50ZWdlci5jbGFzc30pCisgICAgdm9pZCBlMzhhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24yKGFyckNsYXNzID0geyBWb2lkLmNsYXNzLCBJbnRlZ2VyLmNsYXNzfSkKKyAgICB2b2lkIGUzOGIoKSB7fQorCisgICAgQFRlc3RBbm5vdGF0aW9uMihhcnJDbGFzcyA9IHsgVm9pZC5jbGFzcywgSW50ZWdlci5jbGFzc30pCisgICAgdm9pZCBuMzlhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24yKGFyckNsYXNzID0geyBWb2lkLmNsYXNzLCBpbnQuY2xhc3N9KQorICAgIHZvaWQgbjM5YigpIHt9CisKKyAgICAvLyAtLS0tLSBFbnVtIGFyci0tLS0tCisgICAgQFRlc3RBbm5vdGF0aW9uMihhcnJFbnVtPSB7fSkKKyAgICB2b2lkIGU0MGEoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjIoYXJyRW51bSA9IHt9KQorICAgIHZvaWQgZTQwYigpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMihhcnJFbnVtID0ge30pCisgICAgdm9pZCBlNDBjKCkge30KKworICAgIEBUZXN0QW5ub3RhdGlvbjIoYXJyRW51bSA9IHsgVGVzdEVudW0xLkEsIFRlc3RFbnVtMS5GIH0pCisgICAgdm9pZCBlNDFhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24yKGFyckVudW0gPSB7IFRlc3RFbnVtMS5BLCBUZXN0RW51bTEuRiB9KQorICAgIHZvaWQgZTQxYigpIHt9CisKKyAgICBAVGVzdEFubm90YXRpb24yKGFyckVudW0gPSB7IFRlc3RFbnVtMS5BLCBUZXN0RW51bTEuRiB9KQorICAgIHZvaWQgbjQyYSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMihhcnJFbnVtID0geyBUZXN0RW51bTEuQSwgVGVzdEVudW0xLkwgfSkKKyAgICB2b2lkIG40MmIoKSB7fQorCisKKyAgICAvLyAtLS0tLSBBbm5vdGF0aW9uIGFyci0tLS0tCisgICAgQFRlc3RBbm5vdGF0aW9uMihhcnJBbm5vPSB7fSkKKyAgICB2b2lkIGU0M2EoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjIoYXJyQW5ubyA9IHt9KQorICAgIHZvaWQgZTQzYigpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMigpCisgICAgdm9pZCBlNDNjKCkge30KKworICAgIEBUZXN0QW5ub3RhdGlvbjIoYXJyQW5ubyA9IHsgQFRlc3RBbm5vdGF0aW9uMyhpID0gMjApLCBAVGVzdEFubm90YXRpb24zKGogPSAxMjMpfSkKKyAgICB2b2lkIGU0NGEoKSB7fQorICAgIEBUZXN0QW5ub3RhdGlvbjIoYXJyQW5ubyA9IHsgQFRlc3RBbm5vdGF0aW9uMyhpID0gMjApLCBAVGVzdEFubm90YXRpb24zKGogPSAxMjMpfSkKKyAgICB2b2lkIGU0NGIoKSB7fQorCisgICAgQFRlc3RBbm5vdGF0aW9uMihhcnJBbm5vID0geyBAVGVzdEFubm90YXRpb24zKGkgPSAyMCksIEBUZXN0QW5ub3RhdGlvbjMoaiA9IDEyMyl9KQorICAgIHZvaWQgbjQ1YSgpIHt9CisgICAgQFRlc3RBbm5vdGF0aW9uMihhcnJBbm5vID0geyBAVGVzdEFubm90YXRpb24zKGkgPSAyMCksIEBUZXN0QW5ub3RhdGlvbjMoaiA9IDEyNCl9KQorICAgIHZvaWQgbjQ1YigpIHt9CisKKyAgICBAVGVzdEFubm90YXRpb24yKGFyckFubm8gPSB7IEBUZXN0QW5ub3RhdGlvbjMoaSA9IDIwKSwgQFRlc3RBbm5vdGF0aW9uMyhqID0gMTIzKX0pCisgICAgdm9pZCBuNDZhKCkge30KKyAgICBAVGVzdEFubm90YXRpb24yKGFyckFubm8gPSB7IEBUZXN0QW5ub3RhdGlvbjMoaSA9IC0yMCksIEBUZXN0QW5ub3RhdGlvbjMoaiA9IDEyMyl9KQorICAgIHZvaWQgbjQ2YigpIHt9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvYW5ub3RhdGlvbi90ZXN0cy9qYXZhL2xhbmcvYW5ub3RhdGlvbi9FbGVtZW50VHlwZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvYW5ub3RhdGlvbi90ZXN0cy9qYXZhL2xhbmcvYW5ub3RhdGlvbi9FbGVtZW50VHlwZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42Yzk5Zjc0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9hbm5vdGF0aW9uL3Rlc3RzL2phdmEvbGFuZy9hbm5vdGF0aW9uL0VsZW1lbnRUeXBlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmFubm90YXRpb24udGVzdHMuamF2YS5sYW5nLmFubm90YXRpb247CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgRWxlbWVudFR5cGVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF92YWx1ZU9mTGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0U2FtZShFbGVtZW50VHlwZS5BTk5PVEFUSU9OX1RZUEUsIEVsZW1lbnRUeXBlLnZhbHVlT2YoIkFOTk9UQVRJT05fVFlQRSIpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShFbGVtZW50VHlwZS5DT05TVFJVQ1RPUiwgRWxlbWVudFR5cGUudmFsdWVPZigiQ09OU1RSVUNUT1IiKSk7CisgICAgICAgIGFzc2VydFNhbWUoRWxlbWVudFR5cGUuRklFTEQsIEVsZW1lbnRUeXBlLnZhbHVlT2YoIkZJRUxEIikpOworICAgICAgICBhc3NlcnRTYW1lKEVsZW1lbnRUeXBlLkxPQ0FMX1ZBUklBQkxFLCBFbGVtZW50VHlwZS52YWx1ZU9mKCJMT0NBTF9WQVJJQUJMRSIpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShFbGVtZW50VHlwZS5NRVRIT0QsIEVsZW1lbnRUeXBlLnZhbHVlT2YoIk1FVEhPRCIpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShFbGVtZW50VHlwZS5QQUNLQUdFLCBFbGVtZW50VHlwZS52YWx1ZU9mKCJQQUNLQUdFIikpOworICAgICAgICBhc3NlcnRTYW1lKEVsZW1lbnRUeXBlLlBBUkFNRVRFUiwgRWxlbWVudFR5cGUudmFsdWVPZigiUEFSQU1FVEVSIikpOworICAgICAgICBhc3NlcnRTYW1lKEVsZW1lbnRUeXBlLlRZUEUsIEVsZW1lbnRUeXBlLnZhbHVlT2YoIlRZUEUiKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbGVtZW50VHlwZS52YWx1ZU9mKCJPVEhFUiIpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdmFsdWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEVsZW1lbnRUeXBlW10gdmFsdWVzID0gRWxlbWVudFR5cGUudmFsdWVzKCk7CisgICAgICAgIGFzc2VydFRydWUodmFsdWVzLmxlbmd0aCA+IDEpOworICAgICAgICBBcnJheXMuc29ydCh2YWx1ZXMpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5iaW5hcnlTZWFyY2godmFsdWVzLCBFbGVtZW50VHlwZS5NRVRIT0QpID49IDApOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvYW5ub3RhdGlvbi90ZXN0cy9qYXZhL2xhbmcvYW5ub3RhdGlvbi9JbmNvbXBsZXRlQW5ub3RhdGlvbkV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvYW5ub3RhdGlvbi90ZXN0cy9qYXZhL2xhbmcvYW5ub3RhdGlvbi9JbmNvbXBsZXRlQW5ub3RhdGlvbkV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZTFjYTgwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9hbm5vdGF0aW9uL3Rlc3RzL2phdmEvbGFuZy9hbm5vdGF0aW9uL0luY29tcGxldGVBbm5vdGF0aW9uRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmFubm90YXRpb24udGVzdHMuamF2YS5sYW5nLmFubm90YXRpb247CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5JbmNvbXBsZXRlQW5ub3RhdGlvbkV4Y2VwdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIEluY29tcGxldGVBbm5vdGF0aW9uRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICAvKgorICAgICAqIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMjQ3NworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3ROdWxsVHlwZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBJbmNvbXBsZXRlQW5ub3RhdGlvbkV4Y2VwdGlvbihudWxsLCAic3RyIik7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25zdHJ1Y3RvckxqYXZhX2xhbmdfQ2xhc3NfTGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2xhc3MgY2xhenogPSBTdHJpbmcuY2xhc3M7CisgICAgICAgIFN0cmluZyBlbGVtZW50TmFtZSA9ICJzb21lIGVsZW1lbnQiOworICAgICAgICBJbmNvbXBsZXRlQW5ub3RhdGlvbkV4Y2VwdGlvbiBlID0gbmV3IEluY29tcGxldGVBbm5vdGF0aW9uRXhjZXB0aW9uKGNsYXp6LCBlbGVtZW50TmFtZSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoImNhbiBub3QgaW5zdGFudGlhdGUgSW5jb21wbGV0ZUFubm90YXRpb25FeGNlcHRpb24iLCBlKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgid3JvbmcgYW5ub3RhdGlvbiB0eXBlIiwgY2xhenosIGUuYW5ub3RhdGlvblR5cGUoKSk7CisgICAgICAgIGFzc2VydFNhbWUoIndyb25nIGVsZW1lbnQgbmFtZSIsIGVsZW1lbnROYW1lLCBlLmVsZW1lbnROYW1lKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvYW5ub3RhdGlvbi90ZXN0cy9qYXZhL2xhbmcvYW5ub3RhdGlvbi9SZXRlbnRpb25Qb2xpY3lUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2Fubm90YXRpb24vdGVzdHMvamF2YS9sYW5nL2Fubm90YXRpb24vUmV0ZW50aW9uUG9saWN5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxYzI1NjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2Fubm90YXRpb24vdGVzdHMvamF2YS9sYW5nL2Fubm90YXRpb24vUmV0ZW50aW9uUG9saWN5VGVzdC5qYXZhCkBAIC0wLDAgKzEsNDQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmFubm90YXRpb24udGVzdHMuamF2YS5sYW5nLmFubm90YXRpb247CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3k7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIFJldGVudGlvblBvbGljeVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdF92YWx1ZU9mTGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0U2FtZShSZXRlbnRpb25Qb2xpY3kuQ0xBU1MsIFJldGVudGlvblBvbGljeS52YWx1ZU9mKCJDTEFTUyIpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSwgUmV0ZW50aW9uUG9saWN5LnZhbHVlT2YoIlJVTlRJTUUiKSk7CisgICAgICAgIGFzc2VydFNhbWUoUmV0ZW50aW9uUG9saWN5LlNPVVJDRSwgUmV0ZW50aW9uUG9saWN5LnZhbHVlT2YoIlNPVVJDRSIpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJldGVudGlvblBvbGljeS52YWx1ZU9mKCJPVEhFUiIpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdmFsdWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFJldGVudGlvblBvbGljeVtdIHZhbHVlcyA9IFJldGVudGlvblBvbGljeS52YWx1ZXMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh2YWx1ZXMubGVuZ3RoID4gMSk7CisgICAgICAgIEFycmF5cy5zb3J0KHZhbHVlcyk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmJpbmFyeVNlYXJjaCh2YWx1ZXMsIFJldGVudGlvblBvbGljeS5SVU5USU1FKSA+PSAwKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2Fubm90YXRpb24vdGVzdHMvamF2YS9sYW5nL2Fubm90YXRpb24vVGVzdEFubm90YXRpb24xLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2Fubm90YXRpb24vdGVzdHMvamF2YS9sYW5nL2Fubm90YXRpb24vVGVzdEFubm90YXRpb24xLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjQzOTNlZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvYW5ub3RhdGlvbi90ZXN0cy9qYXZhL2xhbmcvYW5ub3RhdGlvbi9UZXN0QW5ub3RhdGlvbjEuamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYW5ub3RhdGlvbi50ZXN0cy5qYXZhLmxhbmcuYW5ub3RhdGlvbjsKKworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3k7CisKK0BSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCitwdWJsaWMgQGludGVyZmFjZSBUZXN0QW5ub3RhdGlvbjEgeworICAgIFN0cmluZyB2YWx1ZSgpOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9hbm5vdGF0aW9uL3Rlc3RzL2phdmEvbGFuZy9hbm5vdGF0aW9uL1Rlc3RBbm5vdGF0aW9uMi5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9hbm5vdGF0aW9uL3Rlc3RzL2phdmEvbGFuZy9hbm5vdGF0aW9uL1Rlc3RBbm5vdGF0aW9uMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQzYzdkNDIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2Fubm90YXRpb24vdGVzdHMvamF2YS9sYW5nL2Fubm90YXRpb24vVGVzdEFubm90YXRpb24yLmphdmEKQEAgLTAsMCArMSwxNSBAQAorcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYW5ub3RhdGlvbi50ZXN0cy5qYXZhLmxhbmcuYW5ub3RhdGlvbjsKKworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3k7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OworCitAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorQFRhcmdldCgge0VsZW1lbnRUeXBlLk1FVEhPRH0pCitwdWJsaWMgQGludGVyZmFjZSBUZXN0QW5ub3RhdGlvbjIgeworICAgIFRlc3RBbm5vdGF0aW9uM1tdIGFyckFubm8oKSBkZWZhdWx0IHt9OworICAgIFN0cmluZ1tdIGFyclN0cmluZygpIGRlZmF1bHQge307CisgICAgQ2xhc3NbXSBhcnJDbGFzcygpIGRlZmF1bHQge307CisgICAgVGVzdEVudW0xW10gYXJyRW51bSgpIGRlZmF1bHQge307Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2Fubm90YXRpb24vdGVzdHMvamF2YS9sYW5nL2Fubm90YXRpb24vVGVzdEFubm90YXRpb24zLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2Fubm90YXRpb24vdGVzdHMvamF2YS9sYW5nL2Fubm90YXRpb24vVGVzdEFubm90YXRpb24zLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjAyNzkyNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvYW5ub3RhdGlvbi90ZXN0cy9qYXZhL2xhbmcvYW5ub3RhdGlvbi9UZXN0QW5ub3RhdGlvbjMuamF2YQpAQCAtMCwwICsxLDI4IEBACitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hbm5vdGF0aW9uLnRlc3RzLmphdmEubGFuZy5hbm5vdGF0aW9uOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CisKK0BSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCitAVGFyZ2V0KCB7RWxlbWVudFR5cGUuTUVUSE9EfSkKK3B1YmxpYyBAaW50ZXJmYWNlIFRlc3RBbm5vdGF0aW9uMyB7CisgICAgLyoKKyAgICAgKiBvbmx5IHByaW1pdGl2ZSB0eXBlLCBTdHJpbmcsIENsYXNzLCBhbm5vdGF0aW9uLAorICAgICAqIGVudW1lcmF0aW9uIGFyZSBwZXJtaXR0ZWQKKyAgICAgKiBvciAxLWRpbWVuc2lvbmFsIGFycmF5cyB0aGVyZW9mCisgICAgICovCisgICAgYm9vbGVhbiB6KCkgZGVmYXVsdCBmYWxzZTsKKyAgICBieXRlIGIoKSBkZWZhdWx0IDA7CisgICAgc2hvcnQgcygpIGRlZmF1bHQgMDsKKyAgICBpbnQgaSgpIGRlZmF1bHQgMTAwOworICAgIGxvbmcgaigpIGRlZmF1bHQgMDsKKworICAgIGZsb2F0IGYoKSBkZWZhdWx0IDAuMGY7CisgICAgZG91YmxlIGQoKSBkZWZhdWx0IDAuMGQ7CisKKyAgICBTdHJpbmcgYVN0cmluZygpIGRlZmF1bHQgIiI7CisgICAgQ2xhc3MgYUNsYXp6KCkgZGVmYXVsdCBWb2lkLmNsYXNzOworICAgIFRlc3RFbnVtMSBhRW51bSgpIGRlZmF1bHQgVGVzdEVudW0xLkY7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2Fubm90YXRpb24vdGVzdHMvamF2YS9sYW5nL2Fubm90YXRpb24vVGVzdEFubm90YXRpb24zYi5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9hbm5vdGF0aW9uL3Rlc3RzL2phdmEvbGFuZy9hbm5vdGF0aW9uL1Rlc3RBbm5vdGF0aW9uM2IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMDAwZDJhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9hbm5vdGF0aW9uL3Rlc3RzL2phdmEvbGFuZy9hbm5vdGF0aW9uL1Rlc3RBbm5vdGF0aW9uM2IuamF2YQpAQCAtMCwwICsxLDI4IEBACitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hbm5vdGF0aW9uLnRlc3RzLmphdmEubGFuZy5hbm5vdGF0aW9uOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CisKK0BSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCitAVGFyZ2V0KCB7RWxlbWVudFR5cGUuTUVUSE9EfSkKK3B1YmxpYyBAaW50ZXJmYWNlIFRlc3RBbm5vdGF0aW9uM2IgeworICAgIC8qCisgICAgICogb25seSBwcmltaXRpdmUgdHlwZSwgU3RyaW5nLCBDbGFzcywgYW5ub3RhdGlvbiwKKyAgICAgKiBlbnVtZXJhdGlvbiBhcmUgcGVybWl0dGVkCisgICAgICogb3IgMS1kaW1lbnNpb25hbCBhcnJheXMgdGhlcmVvZgorICAgICAqLworICAgIGJvb2xlYW4geigpIGRlZmF1bHQgZmFsc2U7CisgICAgYnl0ZSBiKCkgZGVmYXVsdCAwOworICAgIHNob3J0IHMoKSBkZWZhdWx0IDA7CisgICAgaW50IGkoKSBkZWZhdWx0IDEwMDsKKyAgICBsb25nIGwoKSBkZWZhdWx0IDA7CisKKyAgICBmbG9hdCBmKCkgZGVmYXVsdCAwLjBmOworICAgIGRvdWJsZSBkKCkgZGVmYXVsdCAwLjBkOworCisgICAgU3RyaW5nIGFTdHJpbmcoKSBkZWZhdWx0ICIiOworICAgIENsYXNzIGFDbGF6eigpIGRlZmF1bHQgVm9pZC5jbGFzczsKKyAgICBUZXN0RW51bTEgYUVudW0oKSBkZWZhdWx0IFRlc3RFbnVtMS5GOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9hbm5vdGF0aW9uL3Rlc3RzL2phdmEvbGFuZy9hbm5vdGF0aW9uL1Rlc3RBbm5vdGF0aW9uNC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9hbm5vdGF0aW9uL3Rlc3RzL2phdmEvbGFuZy9hbm5vdGF0aW9uL1Rlc3RBbm5vdGF0aW9uNC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIyNjc1MzYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2Fubm90YXRpb24vdGVzdHMvamF2YS9sYW5nL2Fubm90YXRpb24vVGVzdEFubm90YXRpb240LmphdmEKQEAgLTAsMCArMSwxMiBAQAorcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYW5ub3RhdGlvbi50ZXN0cy5qYXZhLmxhbmcuYW5ub3RhdGlvbjsKKworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3k7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OworCitAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorQFRhcmdldCgge0VsZW1lbnRUeXBlLk1FVEhPRH0pCitwdWJsaWMgQGludGVyZmFjZSBUZXN0QW5ub3RhdGlvbjQgeworICAgIGludCBpKCkgZGVmYXVsdCAwOworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9hbm5vdGF0aW9uL3Rlc3RzL2phdmEvbGFuZy9hbm5vdGF0aW9uL1Rlc3RFbnVtMS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9hbm5vdGF0aW9uL3Rlc3RzL2phdmEvbGFuZy9hbm5vdGF0aW9uL1Rlc3RFbnVtMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4ZWQ3M2QKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2Fubm90YXRpb24vdGVzdHMvamF2YS9sYW5nL2Fubm90YXRpb24vVGVzdEVudW0xLmphdmEKQEAgLTAsMCArMSw1IEBACitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5hbm5vdGF0aW9uLnRlc3RzLmphdmEubGFuZy5hbm5vdGF0aW9uOworCitwdWJsaWMgZW51bSBUZXN0RW51bTEgeworICAgIFosIEYsIEwsIEEsIEIKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvYW5ub3RhdGlvbi90ZXN0cy9qYXZhL2xhbmcvYW5ub3RhdGlvbi9UZXN0RW51bTFiLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2Fubm90YXRpb24vdGVzdHMvamF2YS9sYW5nL2Fubm90YXRpb24vVGVzdEVudW0xYi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg3NGQ4OTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2Fubm90YXRpb24vdGVzdHMvamF2YS9sYW5nL2Fubm90YXRpb24vVGVzdEVudW0xYi5qYXZhCkBAIC0wLDAgKzEsNSBAQAorcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYW5ub3RhdGlvbi50ZXN0cy5qYXZhLmxhbmcuYW5ub3RhdGlvbjsKKworcHVibGljIGVudW0gVGVzdEVudW0xYiB7CisgICAgWiwgRiwgTCwgQSwgQgorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9hcmNoaXZlL3Rlc3RzL2phdmEvdXRpbC9qYXIvSmFyRmlsZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvYXJjaGl2ZS90ZXN0cy9qYXZhL3V0aWwvamFyL0phckZpbGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjI2ZWE2NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvYXJjaGl2ZS90ZXN0cy9qYXZhL3V0aWwvamFyL0phckZpbGVUZXN0LmphdmEKQEAgLTAsMCArMSw4ODQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuYXJjaGl2ZS50ZXN0cy5qYXZhLnV0aWwuamFyOworCisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfUGxhdGZvcm1GaWxlOworaW1wb3J0IHRlc3RzLnN1cHBvcnQucmVzb3VyY2UuU3VwcG9ydF9SZXNvdXJjZXM7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKK2ltcG9ydCBqYXZhLnV0aWwuamFyLkF0dHJpYnV0ZXM7CitpbXBvcnQgamF2YS51dGlsLmphci5KYXJFbnRyeTsKK2ltcG9ydCBqYXZhLnV0aWwuamFyLkphckZpbGU7CitpbXBvcnQgamF2YS51dGlsLmphci5KYXJPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLmphci5NYW5pZmVzdDsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEVudHJ5OworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRmlsZTsKKworCitwdWJsaWMgY2xhc3MgSmFyRmlsZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvLyBCRUdJTiBhbmRyb2lkLWFkZGVkCisgICAgcHVibGljIGJ5dGVbXSBnZXRBbGxCeXRlc0Zyb21TdHJlYW0oSW5wdXRTdHJlYW0gaXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBicyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzY2Nl07CisgICAgICAgIGludCBpUmVhZDsKKyAgICAgICAgaW50IG9mZjsKKyAgICAgICAgd2hpbGUgKGlzLmF2YWlsYWJsZSgpID4gMCkgeworICAgICAgICAgICAgaVJlYWQgPSBpcy5yZWFkKGJ1ZiwgMCwgYnVmLmxlbmd0aCk7CisgICAgICAgICAgICBpZiAoaVJlYWQgPiAwKSBicy53cml0ZShidWYsIDAsIGlSZWFkKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnMudG9CeXRlQXJyYXkoKTsKKyAgICB9CisKKyAgICAvLyBFTkQgYW5kcm9pZC1hZGRlZAorCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgamFyTmFtZSA9ICJoeXRzX3BhdGNoLmphciI7IC8vIGEgJ25vcm1hbCcgamFyIGZpbGUKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGphck5hbWUyID0gImh5dHNfcGF0Y2gyLmphciI7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBqYXJOYW1lMyA9ICJoeXRzX21hbmlmZXN0MS5qYXIiOworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgamFyTmFtZTQgPSAiaHl0c19zaWduZWQuamFyIjsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGphck5hbWU1ID0gImh5dHNfc2lnbmVkX2luYy5qYXIiOworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZW50cnlOYW1lID0gImZvby9iYXIvQS5jbGFzcyI7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBlbnRyeU5hbWUzID0gImNvdWNvdS9GaWxlQWNjZXNzLmNsYXNzIjsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGludGVncmF0ZUphciA9ICJJbnRlZ3JhdGUuamFyIjsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGludGVncmF0ZUphckVudHJ5ID0gIlRlc3QuY2xhc3MiOworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZW1wdHlFbnRyeUphciA9ICJFbXB0eUVudHJpZXNfc2lnbmVkLmphciI7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBlbXB0eUVudHJ5MSA9ICJzdWJmb2xkZXIvaW50ZXJuYWxTdWJzZXQwMS5qcyI7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBlbXB0eUVudHJ5MiA9ICJzdmd0ZXN0LmpzIjsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGVtcHR5RW50cnkzID0gInN2Z3VuaXQuanMiOworCisgICAgcHJpdmF0ZSBGaWxlIHJlc291cmNlczsKKworICAgIC8vIGN1c3RvbSBzZWN1cml0eSBtYW5hZ2VyCisgICAgU2VjdXJpdHlNYW5hZ2VyIHNtID0gbmV3IFNlY3VyaXR5TWFuYWdlcigpIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGZvcmJpZGVuUGVybWlzc2lvbk5hbWUgPSAidXNlci5kaXIiOworCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihQZXJtaXNzaW9uIHBlcm0pIHsKKyAgICAgICAgICAgIGlmIChwZXJtLmdldE5hbWUoKS5lcXVhbHMoZm9yYmlkZW5QZXJtaXNzaW9uTmFtZSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH07CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgcmVzb3VyY2VzID0gU3VwcG9ydF9SZXNvdXJjZXMuY3JlYXRlVGVtcEZvbGRlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5qYXIuSmFyRmlsZSNKYXJGaWxlKGphdmEuaW8uRmlsZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fRmlsZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKG5ldyBGaWxlKCJXcm9uZy5maWxlIikpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IElPRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBqYXJOYW1lKTsKKyAgICAgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKG5ldyBGaWxlKHJlc291cmNlcywgamFyTmFtZSkpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgbm90IHRocm93IElPRXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuamFyLkphckZpbGUjSmFyRmlsZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKCJXcm9uZy5maWxlIik7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsIGphck5hbWUpOworICAgICAgICAgICAgU3RyaW5nIGZpbGVOYW1lID0gKG5ldyBGaWxlKHJlc291cmNlcywgamFyTmFtZSkpLmdldENhbm9uaWNhbFBhdGgoKTsKKyAgICAgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKGZpbGVOYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIG5vdCB0aHJvdyBJT0V4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLmphci5KYXJGaWxlI0phckZpbGUoamF2YS5sYW5nLlN0cmluZywgYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmdaKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgSmFyRmlsZSBqYXJGaWxlID0gbmV3IEphckZpbGUoIldyb25nLmZpbGUiLCBmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsIGphck5hbWUpOworICAgICAgICAgICAgU3RyaW5nIGZpbGVOYW1lID0gKG5ldyBGaWxlKHJlc291cmNlcywgamFyTmFtZSkpLmdldENhbm9uaWNhbFBhdGgoKTsKKyAgICAgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKGZpbGVOYW1lLCB0cnVlKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIG5vdCB0aHJvdyBJT0V4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLmphci5KYXJGaWxlI0phckZpbGUoamF2YS5pby5GaWxlLCBib29sZWFuKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9pb19GaWxlWigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKG5ldyBGaWxlKCJXcm9uZy5maWxlIiksIHRydWUpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IElPRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBqYXJOYW1lKTsKKyAgICAgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKG5ldyBGaWxlKHJlc291cmNlcywgamFyTmFtZSksIGZhbHNlKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIG5vdCB0aHJvdyBJT0V4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLmphci5KYXJGaWxlI0phckZpbGUoamF2YS5pby5GaWxlLCBib29sZWFuLCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX0ZpbGVaSSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKG5ldyBGaWxlKCJXcm9uZy5maWxlIiksIHRydWUsCisgICAgICAgICAgICAgICAgICAgIFppcEZpbGUuT1BFTl9SRUFEKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJT0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgamFyTmFtZSk7CisgICAgICAgICAgICBKYXJGaWxlIGphckZpbGUgPSBuZXcgSmFyRmlsZShuZXcgRmlsZShyZXNvdXJjZXMsIGphck5hbWUpLCBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgWmlwRmlsZS5PUEVOX1JFQUQpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgbm90IHRocm93IElPRXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBqYXJOYW1lKTsKKyAgICAgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKG5ldyBGaWxlKHJlc291cmNlcywgamFyTmFtZSksIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICBaaXBGaWxlLk9QRU5fUkVBRCB8IFppcEZpbGUuT1BFTl9ERUxFVEUgKyAzMyk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCBub3QgdGhyb3cgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIEphckZpbGUgb2JqZWN0LgorICAgICAqCisgICAgICogamF2YS51dGlsLmphci5KYXJGaWxlI0phckZpbGUoamF2YS5pby5GaWxlKQorICAgICAqIGphdmEudXRpbC5qYXIuSmFyRmlsZSNKYXJGaWxlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdG9yX2ZpbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBGaWxlIGYgPSBuZXcgRmlsZShyZXNvdXJjZXMsIGphck5hbWUpOworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsIGphck5hbWUpOworICAgICAgICBhc3NlcnRUcnVlKG5ldyBKYXJGaWxlKGYpLmdldEVudHJ5KGVudHJ5TmFtZSkuZ2V0TmFtZSgpLmVxdWFscygKKyAgICAgICAgICAgICAgICBlbnRyeU5hbWUpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuZXcgSmFyRmlsZShmLmdldFBhdGgoKSkuZ2V0RW50cnkoZW50cnlOYW1lKS5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICAuZXF1YWxzKGVudHJ5TmFtZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5qYXIuSmFyRmlsZSNlbnRyaWVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VudHJpZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogTm90ZSBvbmx5IChhbmQgYWxsIG9mKSB0aGUgZm9sbG93aW5nIHNob3VsZCBiZSBjb250YWluZWQgaW4gdGhlIGZpbGUKKyAgICAgICAgICogTUVUQS1JTkYvIE1FVEEtSU5GL01BTklGRVNULk1GIGZvby8gZm9vL2Jhci8gZm9vL2Jhci9BLmNsYXNzIEJsYWgudHh0CisgICAgICAgICAqLworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsIGphck5hbWUpOworICAgICAgICBKYXJGaWxlIGphckZpbGUgPSBuZXcgSmFyRmlsZShuZXcgRmlsZShyZXNvdXJjZXMsIGphck5hbWUpKTsKKyAgICAgICAgRW51bWVyYXRpb248SmFyRW50cnk+IGUgPSBqYXJGaWxlLmVudHJpZXMoKTsKKyAgICAgICAgaW50IGk7CisgICAgICAgIGZvciAoaSA9IDA7IGUuaGFzTW9yZUVsZW1lbnRzKCk7IGkrKykgeworICAgICAgICAgICAgZS5uZXh0RWxlbWVudCgpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyhqYXJGaWxlLnNpemUoKSwgaSk7CisgICAgICAgIGphckZpbGUuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDYsIGkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZW50cmllczIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBqYXJOYW1lKTsKKyAgICAgICAgSmFyRmlsZSBqYXJGaWxlID0gbmV3IEphckZpbGUobmV3IEZpbGUocmVzb3VyY2VzLCBqYXJOYW1lKSk7CisgICAgICAgIEVudW1lcmF0aW9uPEphckVudHJ5PiBlbnVtZXJhdGlvbiA9IGphckZpbGUuZW50cmllcygpOworICAgICAgICBqYXJGaWxlLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbnVtZXJhdGlvbi5oYXNNb3JlRWxlbWVudHMoKTsKKyAgICAgICAgICAgIGZhaWwoImhhc01vcmVFbGVtZW50cygpIGRpZCBub3QgZGV0ZWN0IGEgY2xvc2VkIGphciBmaWxlIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBqYXJOYW1lKTsKKyAgICAgICAgamFyRmlsZSA9IG5ldyBKYXJGaWxlKG5ldyBGaWxlKHJlc291cmNlcywgamFyTmFtZSkpOworICAgICAgICBlbnVtZXJhdGlvbiA9IGphckZpbGUuZW50cmllcygpOworICAgICAgICBqYXJGaWxlLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbnVtZXJhdGlvbi5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgZmFpbCgibmV4dEVsZW1lbnQoKSBkaWQgbm90IGRldGVjdCBjbG9zZWQgamFyIGZpbGUiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBqYXZhLnV0aWwuamFyLkphckZpbGUjZ2V0SmFyRW50cnkoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEVudHJ5TGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBqYXJOYW1lKTsKKyAgICAgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKG5ldyBGaWxlKHJlc291cmNlcywgamFyTmFtZSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJFcnJvciBpbiByZXR1cm5lZCBlbnRyeSIsIDMxMSwgamFyRmlsZS5nZXRFbnRyeSgKKyAgICAgICAgICAgICAgICAgICAgZW50cnlOYW1lKS5nZXRTaXplKCkpOworICAgICAgICAgICAgamFyRmlsZS5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyB0ZXN0OiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgamFyTmFtZSk7CisgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKG5ldyBGaWxlKHJlc291cmNlcywgamFyTmFtZSkpOworICAgICAgICBFbnVtZXJhdGlvbjxKYXJFbnRyeT4gZW51bWVyYXRpb24gPSBqYXJGaWxlLmVudHJpZXMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShlbnVtZXJhdGlvbi5oYXNNb3JlRWxlbWVudHMoKSk7CisgICAgICAgIHdoaWxlIChlbnVtZXJhdGlvbi5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgSmFyRW50cnkgamUgPSBlbnVtZXJhdGlvbi5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgamFyRmlsZS5nZXRFbnRyeShqZS5nZXROYW1lKCkpOworICAgICAgICB9CisKKyAgICAgICAgZW51bWVyYXRpb24gPSBqYXJGaWxlLmVudHJpZXMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShlbnVtZXJhdGlvbi5oYXNNb3JlRWxlbWVudHMoKSk7CisgICAgICAgIEphckVudHJ5IGplID0gZW51bWVyYXRpb24ubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGphckZpbGUuY2xvc2UoKTsKKyAgICAgICAgICAgIGphckZpbGUuZ2V0RW50cnkoamUuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIC8vIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGVlKSB7IC8vIFBlciBkb2N1bWVudGF0aW9uIGV4Y2VwdGlvbgorICAgICAgICAgICAgLy8gbWF5IGJlIHRocm93bi4KKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogamF2YS51dGlsLmphci5KYXJGaWxlI2dldEphckVudHJ5KGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRKYXJFbnRyeUxqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgamFyTmFtZSk7CisgICAgICAgICAgICBKYXJGaWxlIGphckZpbGUgPSBuZXcgSmFyRmlsZShuZXcgRmlsZShyZXNvdXJjZXMsIGphck5hbWUpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiRXJyb3IgaW4gcmV0dXJuZWQgZW50cnkiLCAzMTEsIGphckZpbGUuZ2V0SmFyRW50cnkoCisgICAgICAgICAgICAgICAgICAgIGVudHJ5TmFtZSkuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICAgIGphckZpbGUuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgdGVzdDogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsIGphck5hbWUpOworICAgICAgICBKYXJGaWxlIGphckZpbGUgPSBuZXcgSmFyRmlsZShuZXcgRmlsZShyZXNvdXJjZXMsIGphck5hbWUpKTsKKyAgICAgICAgRW51bWVyYXRpb248SmFyRW50cnk+IGVudW1lcmF0aW9uID0gamFyRmlsZS5lbnRyaWVzKCk7CisgICAgICAgIGFzc2VydFRydWUoZW51bWVyYXRpb24uaGFzTW9yZUVsZW1lbnRzKCkpOworICAgICAgICB3aGlsZSAoZW51bWVyYXRpb24uaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIEphckVudHJ5IGplID0gZW51bWVyYXRpb24ubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGphckZpbGUuZ2V0SmFyRW50cnkoamUuZ2V0TmFtZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGVudW1lcmF0aW9uID0gamFyRmlsZS5lbnRyaWVzKCk7CisgICAgICAgIGFzc2VydFRydWUoZW51bWVyYXRpb24uaGFzTW9yZUVsZW1lbnRzKCkpOworICAgICAgICBKYXJFbnRyeSBqZSA9IGVudW1lcmF0aW9uLm5leHRFbGVtZW50KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBqYXJGaWxlLmNsb3NlKCk7CisgICAgICAgICAgICBqYXJGaWxlLmdldEphckVudHJ5KGplLmdldE5hbWUoKSk7CisgICAgICAgICAgICAvLyBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlZSkgeyAvLyBQZXIgZG9jdW1lbnRhdGlvbiBleGNlcHRpb24KKyAgICAgICAgICAgIC8vIG1heSBiZSB0aHJvd24uCisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuamFyLkphckZpbGUjZ2V0SmFyRW50cnkoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SmFyRW50cnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBqYXJOYW1lKTsKKyAgICAgICAgSmFyRmlsZSBqYXJGaWxlID0gbmV3IEphckZpbGUobmV3IEZpbGUocmVzb3VyY2VzLCBqYXJOYW1lKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRXJyb3IgaW4gcmV0dXJuZWQgZW50cnkiLCAzMTEsIGphckZpbGUuZ2V0RW50cnkoCisgICAgICAgICAgICAgICAgZW50cnlOYW1lKS5nZXRTaXplKCkpOworICAgICAgICBqYXJGaWxlLmNsb3NlKCk7CisKKyAgICAgICAgLy8gdGVzdHMgZm9yIHNpZ25lZCBqYXJzCisgICAgICAgIC8vIHRlc3QgYWxsIHNpZ25lZCBqYXJzIGluIHRoZSAvVGVzdHJlcy9JbnRlcm5hbC9TaWduZWRKYXJzIGRpcmVjdG9yeQorICAgICAgICBTdHJpbmcgamFyRGlyVXJsID0gU3VwcG9ydF9SZXNvdXJjZXMKKyAgICAgICAgICAgICAgICAuZ2V0UmVzb3VyY2VVUkwoIi8uLi9pbnRlcm5hbHJlcy9zaWduZWRqYXJzIik7CisgICAgICAgIFZlY3RvcjxTdHJpbmc+IHNpZ25lZEphcnMgPSBuZXcgVmVjdG9yPFN0cmluZz4oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gbmV3IFVSTChqYXJEaXJVcmwgKyAiL2phcmxpc3QudHh0Iikub3BlblN0cmVhbSgpOworICAgICAgICAgICAgd2hpbGUgKGlzLmF2YWlsYWJsZSgpID4gMCkgeworICAgICAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgbGluZWJ1ZmYgPSBuZXcgU3RyaW5nQnVpbGRlcig4MCk7IC8vIFR5cGljYWwgbGluZQorICAgICAgICAgICAgICAgIC8vIGxlbmd0aAorICAgICAgICAgICAgICAgIGRvbmU6IHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgICAgIGludCBuZXh0Qnl0ZSA9IGlzLnJlYWQoKTsKKyAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChuZXh0Qnl0ZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMToKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBkb25lOworICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAoYnl0ZSkgJ1xyJzoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGluZWJ1ZmYubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgZG9uZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgKGJ5dGUpICdcbic6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmVidWZmLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIGRvbmU7CisgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVidWZmLmFwcGVuZCgoY2hhcikgbmV4dEJ5dGUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChsaW5lYnVmZi5sZW5ndGgoKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBTdHJpbmcgbGluZSA9IGxpbmVidWZmLnRvU3RyaW5nKCk7CisgICAgICAgICAgICAgICAgc2lnbmVkSmFycy5hZGQobGluZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBubyBsaXN0IG9mIGphcnMgZm91bmQKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2lnbmVkSmFycy5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIGphck5hbWUgPSBzaWduZWRKYXJzLmdldChpKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgRmlsZSBmaWxlID0gU3VwcG9ydF9SZXNvdXJjZXMuZ2V0RXh0ZXJuYWxMb2NhbEZpbGUoamFyRGlyVXJsCisgICAgICAgICAgICAgICAgICAgICAgICArICIvIiArIGphck5hbWUpOworICAgICAgICAgICAgICAgIGphckZpbGUgPSBuZXcgSmFyRmlsZShmaWxlLCB0cnVlKTsKKyAgICAgICAgICAgICAgICBib29sZWFuIGZvdW5kQ2VydHMgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBFbnVtZXJhdGlvbjxKYXJFbnRyeT4gZSA9IGphckZpbGUuZW50cmllcygpOworICAgICAgICAgICAgICAgIHdoaWxlIChlLmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICAgICAgICAgIEphckVudHJ5IGVudHJ5ID0gZS5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IGphckZpbGUuZ2V0SW5wdXRTdHJlYW0oZW50cnkpOworICAgICAgICAgICAgICAgICAgICBpcy5za2lwKDEwMDAwMCk7CisgICAgICAgICAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIENlcnRpZmljYXRlW10gY2VydHMgPSBlbnRyeS5nZXRDZXJ0aWZpY2F0ZXMoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNlcnRzICE9IG51bGwgJiYgY2VydHMubGVuZ3RoID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRDZXJ0cyA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAgICAgIk5vIGNlcnRpZmljYXRlcyBmb3VuZCBkdXJpbmcgc2lnbmVkIGphciB0ZXN0IGZvciBqYXIgXCIiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgamFyTmFtZSArICJcIiIsIGZvdW5kQ2VydHMpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgc2lnbmVkIGphciB0ZXN0IGZvciBqYXIgXCIiICsgamFyTmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgKyAiXCI6ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLmphci5KYXJGaWxlI2dldE1hbmlmZXN0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1hbmlmZXN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLmphci5NYW5pZmVzdAorICAgICAgICAvLyBqYXZhLnV0aWwuamFyLkphckZpbGUuZ2V0TWFuaWZlc3QoKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBqYXJOYW1lKTsKKyAgICAgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKG5ldyBGaWxlKHJlc291cmNlcywgamFyTmFtZSkpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiRXJyb3ItLU1hbmlmZXN0IG5vdCByZXR1cm5lZCIsIGphckZpbGUuZ2V0TWFuaWZlc3QoKSk7CisgICAgICAgICAgICBqYXJGaWxlLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIDFzdCB0ZXN0OiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBqYXJOYW1lMik7CisgICAgICAgICAgICBKYXJGaWxlIGphckZpbGUgPSBuZXcgSmFyRmlsZShuZXcgRmlsZShyZXNvdXJjZXMsIGphck5hbWUyKSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJFcnJvci0tc2hvdWxkIGhhdmUgcmV0dXJuZWQgbnVsbCIsIGphckZpbGUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1hbmlmZXN0KCkpOworICAgICAgICAgICAgamFyRmlsZS5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyAybmQgdGVzdDogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gamFyTmFtZTMgd2FzIGNyZWF0ZWQgdXNpbmcgdGhlIGZvbGxvd2luZyB0ZXN0CisgICAgICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsIGphck5hbWUzKTsKKyAgICAgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKG5ldyBGaWxlKHJlc291cmNlcywgamFyTmFtZTMpKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIlNob3VsZCBmaW5kIG1hbmlmZXN0IHdpdGhvdXQgdmVyaWZ5aW5nIiwgamFyRmlsZQorICAgICAgICAgICAgICAgICAgICAuZ2V0TWFuaWZlc3QoKSk7CisgICAgICAgICAgICBqYXJGaWxlLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIDNyZCB0ZXN0OiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyB0aGlzIGlzIHVzZWQgdG8gY3JlYXRlIGphck5hbWUzIHVzZWQgaW4gdGhlIHByZXZpb3VzIHRlc3QKKyAgICAgICAgICAgIE1hbmlmZXN0IG1hbmlmZXN0ID0gbmV3IE1hbmlmZXN0KCk7CisgICAgICAgICAgICBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMgPSBtYW5pZmVzdC5nZXRNYWluQXR0cmlidXRlcygpOworICAgICAgICAgICAgYXR0cmlidXRlcy5wdXQobmV3IEF0dHJpYnV0ZXMuTmFtZSgiTWFuaWZlc3QtVmVyc2lvbiIpLCAiMS4wIik7CisgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gbWFuT3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgbWFuaWZlc3Qud3JpdGUobWFuT3V0KTsKKyAgICAgICAgICAgIGJ5dGVbXSBtYW5CeXRlcyA9IG1hbk91dC50b0J5dGVBcnJheSgpOworICAgICAgICAgICAgRmlsZSBmaWxlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgKKyAgICAgICAgICAgICAgICAgICAgU3VwcG9ydF9QbGF0Zm9ybUZpbGUuZ2V0TmV3UGxhdGZvcm1GaWxlKCJoeXRzX21hbmlmZXN0MSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiIpLCAiLmphciIpOworICAgICAgICAgICAgSmFyT3V0cHV0U3RyZWFtIGphck91dCA9IG5ldyBKYXJPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgIGZpbGUuZ2V0QWJzb2x1dGVQYXRoKCkpKTsKKyAgICAgICAgICAgIFppcEVudHJ5IGVudHJ5ID0gbmV3IFppcEVudHJ5KCJNRVRBLUlORi8iKTsKKyAgICAgICAgICAgIGVudHJ5LnNldFNpemUoMCk7CisgICAgICAgICAgICBqYXJPdXQucHV0TmV4dEVudHJ5KGVudHJ5KTsKKyAgICAgICAgICAgIGVudHJ5ID0gbmV3IFppcEVudHJ5KEphckZpbGUuTUFOSUZFU1RfTkFNRSk7CisgICAgICAgICAgICBlbnRyeS5zZXRTaXplKG1hbkJ5dGVzLmxlbmd0aCk7CisgICAgICAgICAgICBqYXJPdXQucHV0TmV4dEVudHJ5KGVudHJ5KTsKKyAgICAgICAgICAgIGphck91dC53cml0ZShtYW5CeXRlcyk7CisgICAgICAgICAgICBlbnRyeSA9IG5ldyBaaXBFbnRyeSgibXlmaWxlIik7CisgICAgICAgICAgICBlbnRyeS5zZXRTaXplKDEpOworICAgICAgICAgICAgamFyT3V0LnB1dE5leHRFbnRyeShlbnRyeSk7CisgICAgICAgICAgICBqYXJPdXQud3JpdGUoNjUpOworICAgICAgICAgICAgamFyT3V0LmNsb3NlKCk7CisgICAgICAgICAgICBKYXJGaWxlIGphciA9IG5ldyBKYXJGaWxlKGZpbGUuZ2V0QWJzb2x1dGVQYXRoKCksIGZhbHNlKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIlNob3VsZCBmaW5kIG1hbmlmZXN0IHdpdGhvdXQgdmVyaWZ5aW5nIiwgamFyCisgICAgICAgICAgICAgICAgICAgIC5nZXRNYW5pZmVzdCgpKTsKKyAgICAgICAgICAgIGphci5jbG9zZSgpOworICAgICAgICAgICAgZmlsZS5kZWxldGUoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gMyIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsIGphck5hbWUyKTsKKyAgICAgICAgICAgIEphckZpbGUgakYgPSBuZXcgSmFyRmlsZShuZXcgRmlsZShyZXNvdXJjZXMsIGphck5hbWUyKSk7CisgICAgICAgICAgICBqRi5jbG9zZSgpOworICAgICAgICAgICAgakYuZ2V0TWFuaWZlc3QoKTsKKyAgICAgICAgICAgIGZhaWwoIkZBSUxFRDogZXhwZWN0ZWQgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpc2UpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyA0dGggdGVzdDogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsICJCcm9rZW5fbWFuaWZlc3QuamFyIik7CisgICAgICAgIEphckZpbGUgamY7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBqZiA9IG5ldyBKYXJGaWxlKG5ldyBGaWxlKHJlc291cmNlcywgIkJyb2tlbl9tYW5pZmVzdC5qYXIiKSk7CisgICAgICAgICAgICBqZi5nZXRNYW5pZmVzdCgpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLmphci5KYXJGaWxlI2dldElucHV0U3RyZWFtKGphdmEudXRpbC56aXAuWmlwRW50cnkpCisgICAgICovCisgICAgLy8gVGhpcyB0ZXN0IGRvZXNuJ3QgcGFzcyBvbiBSSS4gSWYgZW50cnkgc2l6ZSBpcyBzZXQgdXAgaW5jb3JyZWN0bHksCisgICAgLy8gU2VjdXJpdHlFeGNlcHRpb24gaXMgdGhyb3duLiBCdXQgU2VjdXJpdHlFeGNlcHRpb24gaXMgdGhyb3duIG9uIFJJIG9ubHkKKyAgICAvLyBpZiBqYXIgZmlsZSBpcyBzaWduZWQgaW5jb3JyZWN0bHkuCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnB1dFN0cmVhbUxqYXZhX3V0aWxfamFyX0phckVudHJ5X3N1YnRlc3QwKCkgeworICAgICAgICBGaWxlIHNpZ25lZEZpbGUgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBqYXJOYW1lNCk7CisgICAgICAgICAgICBzaWduZWRGaWxlID0gbmV3IEZpbGUocmVzb3VyY2VzLCBqYXJOYW1lNCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJGYWlsZWQgdG8gY3JlYXRlIGxvY2FsIGZpbGUgMjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEphckZpbGUgamFyID0gbmV3IEphckZpbGUoc2lnbmVkRmlsZSk7CisgICAgICAgICAgICBKYXJFbnRyeSBlbnRyeSA9IG5ldyBKYXJFbnRyeShlbnRyeU5hbWUzKTsKKyAgICAgICAgICAgIElucHV0U3RyZWFtIGluID0gamFyLmdldElucHV0U3RyZWFtKGVudHJ5KTsKKyAgICAgICAgICAgIGluLnJlYWQoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgdGVzdCAzOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgSmFyRmlsZSBqYXIgPSBuZXcgSmFyRmlsZShzaWduZWRGaWxlKTsKKyAgICAgICAgICAgIEphckVudHJ5IGVudHJ5ID0gbmV3IEphckVudHJ5KGVudHJ5TmFtZTMpOworICAgICAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBqYXIuZ2V0SW5wdXRTdHJlYW0oZW50cnkpOworICAgICAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1hZGRlZAorICAgICAgICAgICAgYnl0ZVtdIGR1bW15ID0gZ2V0QWxsQnl0ZXNGcm9tU3RyZWFtKGluKTsKKyAgICAgICAgICAgIC8vIEVORCBhbmRyb2lkLWFkZGVkCisgICAgICAgICAgICBhc3NlcnROdWxsKCJmb3VuZCBjZXJ0aWZpY2F0ZXMiLCBlbnRyeS5nZXRDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHRlc3QgNDogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEphckZpbGUgamFyID0gbmV3IEphckZpbGUoc2lnbmVkRmlsZSk7CisgICAgICAgICAgICBKYXJFbnRyeSBlbnRyeSA9IG5ldyBKYXJFbnRyeShlbnRyeU5hbWUzKTsKKyAgICAgICAgICAgIGVudHJ5LnNldFNpemUoMTA3Nik7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IGphci5nZXRJbnB1dFN0cmVhbShlbnRyeSk7CisgICAgICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLWFkZGVkCisgICAgICAgICAgICBieXRlW10gZHVtbXkgPSBnZXRBbGxCeXRlc0Zyb21TdHJlYW0oaW4pOworICAgICAgICAgICAgLy8gRU5EIGFuZHJvaWQtYWRkZWQKKyAgICAgICAgICAgIGZhaWwoIlNlY3VyaXR5RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHRlc3QgNTogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgamFyTmFtZTUpOworICAgICAgICAgICAgc2lnbmVkRmlsZSA9IG5ldyBGaWxlKHJlc291cmNlcywgamFyTmFtZTUpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRmFpbGVkIHRvIGNyZWF0ZSBsb2NhbCBmaWxlIDU6ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBKYXJGaWxlIGphciA9IG5ldyBKYXJGaWxlKHNpZ25lZEZpbGUpOworICAgICAgICAgICAgSmFyRW50cnkgZW50cnkgPSBuZXcgSmFyRW50cnkoZW50cnlOYW1lMyk7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IGphci5nZXRJbnB1dFN0cmVhbShlbnRyeSk7CisgICAgICAgICAgICBmYWlsKCJTZWN1cml0eUV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyB0ZXN0IDU6ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogVGhlIGphciBjcmVhdGVkIGJ5IDEuNCB3aGljaCBkb2VzIG5vdCBwcm92aWRlIGEKKyAgICAgKiBhbGdvcml0aG0tRGlnZXN0LU1hbmlmZXN0LU1haW4tQXR0cmlidXRlcyBlbnRyeSBpbiAuU0YgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0phcl9jcmVhdGVkX2JlZm9yZV9qYXZhXzUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbW9kaWZpZWRKYXJOYW1lID0gIkNyZWF0ZWRfYnlfMV80LmphciI7CisgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgbW9kaWZpZWRKYXJOYW1lKTsKKyAgICAgICAgSmFyRmlsZSBqYXJGaWxlID0gbmV3IEphckZpbGUobmV3IEZpbGUocmVzb3VyY2VzLCBtb2RpZmllZEphck5hbWUpLAorICAgICAgICAgICAgICAgIHRydWUpOworICAgICAgICBFbnVtZXJhdGlvbjxKYXJFbnRyeT4gZW50cmllcyA9IGphckZpbGUuZW50cmllcygpOworICAgICAgICB3aGlsZSAoZW50cmllcy5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgWmlwRW50cnkgemlwRW50cnkgPSBlbnRyaWVzLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICBqYXJGaWxlLmdldElucHV0U3RyZWFtKHppcEVudHJ5KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIFRoZSBqYXIgaXMgaW50YWN0LCB0aGVuIGV2ZXJ5dGhpbmcgaXMgYWxsIHJpZ2h0LiAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfSmFyRmlsZV9JbnRlZ3JhdGVfSmFyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIG1vZGlmaWVkSmFyTmFtZSA9ICJJbnRlZ3JhdGUuamFyIjsKKyAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBtb2RpZmllZEphck5hbWUpOworICAgICAgICBKYXJGaWxlIGphckZpbGUgPSBuZXcgSmFyRmlsZShuZXcgRmlsZShyZXNvdXJjZXMsIG1vZGlmaWVkSmFyTmFtZSksCisgICAgICAgICAgICAgICAgdHJ1ZSk7CisgICAgICAgIEVudW1lcmF0aW9uPEphckVudHJ5PiBlbnRyaWVzID0gamFyRmlsZS5lbnRyaWVzKCk7CisgICAgICAgIHdoaWxlIChlbnRyaWVzLmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICBaaXBFbnRyeSB6aXBFbnRyeSA9IGVudHJpZXMubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGphckZpbGUuZ2V0SW5wdXRTdHJlYW0oemlwRW50cnkpLnNraXAoTG9uZy5NQVhfVkFMVUUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGphciBpcyBpbnRhY3QsIGJ1dCB0aGUgZW50cnkgb2JqZWN0IGlzIG1vZGlmaWVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RKYXJWZXJpZmljYXRpb25Nb2RpZmllZEVudHJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBpbnRlZ3JhdGVKYXIpOworICAgICAgICBGaWxlIGYgPSBuZXcgRmlsZShyZXNvdXJjZXMsIGludGVncmF0ZUphcik7CisKKyAgICAgICAgSmFyRmlsZSBqYXJGaWxlID0gbmV3IEphckZpbGUoZik7CisgICAgICAgIFppcEVudHJ5IHppcEVudHJ5ID0gamFyRmlsZS5nZXRKYXJFbnRyeShpbnRlZ3JhdGVKYXJFbnRyeSk7CisgICAgICAgIHppcEVudHJ5LnNldFNpemUoemlwRW50cnkuZ2V0U2l6ZSgpICsgMSk7CisgICAgICAgIGphckZpbGUuZ2V0SW5wdXRTdHJlYW0oemlwRW50cnkpLnNraXAoTG9uZy5NQVhfVkFMVUUpOworCisgICAgICAgIGphckZpbGUgPSBuZXcgSmFyRmlsZShmKTsKKyAgICAgICAgemlwRW50cnkgPSBqYXJGaWxlLmdldEphckVudHJ5KGludGVncmF0ZUphckVudHJ5KTsKKyAgICAgICAgemlwRW50cnkuc2V0U2l6ZSh6aXBFbnRyeS5nZXRTaXplKCkgLSAxKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vamFyRmlsZS5nZXRJbnB1dFN0cmVhbSh6aXBFbnRyeSkuc2tpcChMb25nLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBqYXJGaWxlLmdldElucHV0U3RyZWFtKHppcEVudHJ5KS5yZWFkKG5ldyBieXRlWzUwMDBdLCAwLCA1MDAwKTsKKyAgICAgICAgICAgIGZhaWwoIlNlY3VyaXR5RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGRlc2lyZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogSWYgYW5vdGhlciBlbnRyeSBpcyBpbnNlcnRlZCBpbnRvIE1hbmlmZXN0LCBubyBzZWN1cml0eSBleGNlcHRpb24gd2lsbCBiZQorICAgICAqIHRocm93biBvdXQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9KYXJGaWxlX0luc2VydEVudHJ5X2luX01hbmlmZXN0X0phcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBtb2RpZmllZEphck5hbWUgPSAiSW5zZXJ0ZWRfRW50cnlfTWFuaWZlc3QuamFyIjsKKyAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBtb2RpZmllZEphck5hbWUpOworICAgICAgICBKYXJGaWxlIGphckZpbGUgPSBuZXcgSmFyRmlsZShuZXcgRmlsZShyZXNvdXJjZXMsIG1vZGlmaWVkSmFyTmFtZSksCisgICAgICAgICAgICAgICAgdHJ1ZSk7CisgICAgICAgIEVudW1lcmF0aW9uPEphckVudHJ5PiBlbnRyaWVzID0gamFyRmlsZS5lbnRyaWVzKCk7CisgICAgICAgIGludCBjb3VudCA9IDA7CisgICAgICAgIHdoaWxlIChlbnRyaWVzLmhhc01vcmVFbGVtZW50cygpKSB7CisKKyAgICAgICAgICAgIFppcEVudHJ5IHppcEVudHJ5ID0gZW50cmllcy5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgamFyRmlsZS5nZXRJbnB1dFN0cmVhbSh6aXBFbnRyeSk7CisgICAgICAgICAgICBjb3VudCsrOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBjb3VudCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBJZiBhbm90aGVyIGVudHJ5IGlzIGluc2VydGVkIGludG8gTWFuaWZlc3QsIG5vIHNlY3VyaXR5IGV4Y2VwdGlvbiB3aWxsIGJlCisgICAgICogdGhyb3duIG91dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0luc2VydGVkX0VudHJ5X01hbmlmZXN0X3dpdGhfRGlnZXN0Q29kZSgpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbW9kaWZpZWRKYXJOYW1lID0gIkluc2VydGVkX0VudHJ5X01hbmlmZXN0X3dpdGhfRGlnZXN0Q29kZS5qYXIiOworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsIG1vZGlmaWVkSmFyTmFtZSk7CisgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKG5ldyBGaWxlKHJlc291cmNlcywgbW9kaWZpZWRKYXJOYW1lKSwKKyAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICAgICAgRW51bWVyYXRpb248SmFyRW50cnk+IGVudHJpZXMgPSBqYXJGaWxlLmVudHJpZXMoKTsKKyAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgd2hpbGUgKGVudHJpZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIFppcEVudHJ5IHppcEVudHJ5ID0gZW50cmllcy5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgamFyRmlsZS5nZXRJbnB1dFN0cmVhbSh6aXBFbnRyeSk7CisgICAgICAgICAgICBjb3VudCsrOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBjb3VudCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUaGUgY29udGVudCBvZiBUZXN0LmNsYXNzIGlzIG1vZGlmaWVkLCBqYXJGaWxlLmdldElucHV0U3RyZWFtIHdpbGwgbm90CisgICAgICogdGhyb3cgc2VjdXJpdHkgRXhjZXB0aW9uLCBidXQgaXQgd2lsbCBhbnl0aW1lIGJlZm9yZSB0aGUgaW5wdXRTdHJlYW0gZ290CisgICAgICogZnJvbSBnZXRJbnB1dFN0cmVhbSBtZXRob2QgaGFzIGJlZW4gcmVhZCB0byBlbmQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9KYXJGaWxlX01vZGlmaWVkX0NsYXNzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIG1vZGlmaWVkSmFyTmFtZSA9ICJNb2RpZmllZF9DbGFzcy5qYXIiOworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsIG1vZGlmaWVkSmFyTmFtZSk7CisgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKG5ldyBGaWxlKHJlc291cmNlcywgbW9kaWZpZWRKYXJOYW1lKSwKKyAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICAgICAgRW51bWVyYXRpb248SmFyRW50cnk+IGVudHJpZXMgPSBqYXJGaWxlLmVudHJpZXMoKTsKKyAgICAgICAgd2hpbGUgKGVudHJpZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIFppcEVudHJ5IHppcEVudHJ5ID0gZW50cmllcy5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgamFyRmlsZS5nZXRJbnB1dFN0cmVhbSh6aXBFbnRyeSk7CisgICAgICAgIH0KKyAgICAgICAgLyogVGhlIGNvbnRlbnQgb2YgVGVzdC5jbGFzcyBoYXMgYmVlbiB0YW1wZXJlZC4gKi8KKyAgICAgICAgWmlwRW50cnkgemlwRW50cnkgPSBqYXJGaWxlLmdldEVudHJ5KCJUZXN0LmNsYXNzIik7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gamFyRmlsZS5nZXRJbnB1dFN0cmVhbSh6aXBFbnRyeSk7CisgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVsxMDI0XTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdoaWxlIChpbi5hdmFpbGFibGUoKSA+IDApIHsKKyAgICAgICAgICAgICAgICBpbi5yZWFkKGJ1ZmZlcik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmYWlsKCJTZWN1cml0eUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBkZXNpcmVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIEluIHRoZSBNb2RpZmllZC5qYXIsIHRoZSBtYWluIGF0dHJpYnV0ZXMgb2YgTUVUQS1JTkYvTUFOSUZFU1QuTUYgaXMKKyAgICAgKiB0YW1wZXJlZCBtYW51YWxseS4gSGVuY2UgdGhlIFJJIDUuMCBKYXJGaWxlLmdldElucHV0U3RyZWFtIG9mIGFueQorICAgICAqIEphckVudHJ5IHdpbGwgdGhyb3cgc2VjdXJpdHkgZXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfSmFyRmlsZV9Nb2RpZmllZF9NYW5pZmVzdF9NYWluQXR0cmlidXRlcygpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbW9kaWZpZWRKYXJOYW1lID0gIk1vZGlmaWVkX01hbmlmZXN0X01haW5BdHRyaWJ1dGVzLmphciI7CisgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgbW9kaWZpZWRKYXJOYW1lKTsKKyAgICAgICAgSmFyRmlsZSBqYXJGaWxlID0gbmV3IEphckZpbGUobmV3IEZpbGUocmVzb3VyY2VzLCBtb2RpZmllZEphck5hbWUpLAorICAgICAgICAgICAgICAgIHRydWUpOworICAgICAgICBFbnVtZXJhdGlvbjxKYXJFbnRyeT4gZW50cmllcyA9IGphckZpbGUuZW50cmllcygpOworICAgICAgICB3aGlsZSAoZW50cmllcy5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgWmlwRW50cnkgemlwRW50cnkgPSBlbnRyaWVzLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGphckZpbGUuZ2V0SW5wdXRTdHJlYW0oemlwRW50cnkpOworICAgICAgICAgICAgICAgIGZhaWwoIlNlY3VyaXR5RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gZGVzaXJlZAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBJdCBpcyBhbGwgcmlnaHQgaW4gb3VyIG9yaWdpbmFsIEphckZpbGUuIElmIHRoZSBFbnRyeSBBdHRyaWJ1dGVzLCBmb3IKKyAgICAgKiBleGFtcGxlIFRlc3QuY2xhc3MgaW4gb3VyIGphciwgdGhlIGphckZpbGUuZ2V0SW5wdXRTdHJlYW0gd2lsbCB0aHJvdworICAgICAqIFNlY3VyaXR5IEV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0phckZpbGVfTW9kaWZpZWRfTWFuaWZlc3RfRW50cnlBdHRyaWJ1dGVzKCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBtb2RpZmllZEphck5hbWUgPSAiTW9kaWZpZWRfTWFuaWZlc3RfRW50cnlBdHRyaWJ1dGVzLmphciI7CisgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgbW9kaWZpZWRKYXJOYW1lKTsKKyAgICAgICAgSmFyRmlsZSBqYXJGaWxlID0gbmV3IEphckZpbGUobmV3IEZpbGUocmVzb3VyY2VzLCBtb2RpZmllZEphck5hbWUpLAorICAgICAgICAgICAgICAgIHRydWUpOworICAgICAgICBFbnVtZXJhdGlvbjxKYXJFbnRyeT4gZW50cmllcyA9IGphckZpbGUuZW50cmllcygpOworICAgICAgICB3aGlsZSAoZW50cmllcy5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgWmlwRW50cnkgemlwRW50cnkgPSBlbnRyaWVzLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGphckZpbGUuZ2V0SW5wdXRTdHJlYW0oemlwRW50cnkpOworICAgICAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBTZWN1cml0eSBFeGNlcHRpb24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBkZXNpcmVkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIElmIHRoZSBjb250ZW50IG9mIHRoZSAuU0EgZmlsZSBpcyBtb2RpZmllZCwgbm8gbWF0dGVyIHdoYXQgaXQgcmVzaWRlcywKKyAgICAgKiBKYXJGaWxlLmdldElucHV0U3RyZWFtIG9mIGFueSBKYXJFbnRyeSB3aWxsIHRocm93IFNlY3VyaXR5IEV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0phckZpbGVfTW9kaWZpZWRfU0ZfRW50cnlBdHRyaWJ1dGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIG1vZGlmaWVkSmFyTmFtZSA9ICJNb2RpZmllZF9TRl9FbnRyeUF0dHJpYnV0ZXMuamFyIjsKKyAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCBtb2RpZmllZEphck5hbWUpOworICAgICAgICBKYXJGaWxlIGphckZpbGUgPSBuZXcgSmFyRmlsZShuZXcgRmlsZShyZXNvdXJjZXMsIG1vZGlmaWVkSmFyTmFtZSksCisgICAgICAgICAgICAgICAgdHJ1ZSk7CisgICAgICAgIEVudW1lcmF0aW9uPEphckVudHJ5PiBlbnRyaWVzID0gamFyRmlsZS5lbnRyaWVzKCk7CisgICAgICAgIHdoaWxlIChlbnRyaWVzLmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICBaaXBFbnRyeSB6aXBFbnRyeSA9IGVudHJpZXMubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgamFyRmlsZS5nZXRJbnB1dFN0cmVhbSh6aXBFbnRyeSk7CisgICAgICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IFNlY3VyaXR5IEV4Y2VwdGlvbiIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGRlc2lyZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbW9kaWZpZWRKYXJOYW1lID0gIk1vZGlmaWVkX1NGX0VudHJ5QXR0cmlidXRlcy5qYXIiOworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsIG1vZGlmaWVkSmFyTmFtZSk7CisgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKG5ldyBGaWxlKHJlc291cmNlcywgbW9kaWZpZWRKYXJOYW1lKSwKKyAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICAgICAgRW51bWVyYXRpb248SmFyRW50cnk+IGVudHJpZXMgPSBqYXJGaWxlLmVudHJpZXMoKTsKKworICAgICAgICBqYXJGaWxlLmNsb3NlKCk7CisgICAgICAgIGphckZpbGUuY2xvc2UoKTsKKworICAgICAgICAvLyBDYW4gbm90IGNoZWNrIElPRXhjZXB0aW9uCisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIGphdmEudXRpbC5qYXIuSmFyRmlsZSNnZXRJbnB1dFN0cmVhbShqYXZhLnV0aWwuemlwLlppcEVudHJ5KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5wdXRTdHJlYW1MamF2YV91dGlsX2phcl9KYXJFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgbG9jYWxGaWxlID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgamFyTmFtZSk7CisgICAgICAgICAgICBsb2NhbEZpbGUgPSBuZXcgRmlsZShyZXNvdXJjZXMsIGphck5hbWUpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRmFpbGVkIHRvIGNyZWF0ZSBsb2NhbCBmaWxlOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICBieXRlW10gYiA9IG5ldyBieXRlWzEwMjRdOworICAgICAgICB0cnkgeworICAgICAgICAgICAgSmFyRmlsZSBqZiA9IG5ldyBKYXJGaWxlKGxvY2FsRmlsZSk7CisgICAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlzID0gamYuZ2V0SW5wdXRTdHJlYW0oamYuZ2V0RW50cnkoZW50cnlOYW1lKSk7CisgICAgICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLXJlbW92ZWQKKyAgICAgICAgICAgIC8vIGpmLmNsb3NlKCk7CisgICAgICAgICAgICAvLyBFTkQgYW5kcm9pZC1yZW1vdmVkCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbnZhbGlkIHN0cmVhbSIsIGlzLmF2YWlsYWJsZSgpID4gMCk7CisgICAgICAgICAgICBpbnQgciA9IGlzLnJlYWQoYiwgMCwgMTAyNCk7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcihyKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcjsgaSsrKSB7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKChjaGFyKSAoYltpXSAmIDB4ZmYpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFN0cmluZyBjb250ZW50cyA9IHNiLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3Qgc3RyZWFtIHJlYWQiLCBjb250ZW50cy5pbmRleE9mKCJiYXIiKSA+IDApOworICAgICAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1hZGRlZAorICAgICAgICAgICAgamYuY2xvc2UoKTsKKyAgICAgICAgICAgIC8vIEVORCBhbmRyb2lkLWFkZGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHRlc3Q6ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEphckZpbGUgamYgPSBuZXcgSmFyRmlsZShsb2NhbEZpbGUpOworICAgICAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBqZi5nZXRJbnB1dFN0cmVhbShuZXcgSmFyRW50cnkoImludmFsaWQiKSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJHb3Qgc3RyZWFtIGZvciBub24tZXhpc3RlbnQgZW50cnkiLCBpbik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHRlc3QgMjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgamFyTmFtZSk7CisgICAgICAgICAgICBGaWxlIHNpZ25lZEZpbGUgPSBuZXcgRmlsZShyZXNvdXJjZXMsIGphck5hbWUpOworICAgICAgICAgICAgSmFyRmlsZSBqZiA9IG5ldyBKYXJGaWxlKHNpZ25lZEZpbGUpOworICAgICAgICAgICAgSmFyRW50cnkganJlID0gbmV3IEphckVudHJ5KCJmb28vYmFyL0EuY2xhc3MiKTsKKyAgICAgICAgICAgIGpmLmdldElucHV0U3RyZWFtKGpyZSk7CisgICAgICAgICAgICAvLyBJbnB1dFN0cmVhbSByZXR1cm5lZCBpbiBhbnkgd2F5LCBleGNlcHRpb24gY2FuIGJlIHRocm93biBpbiBjYXNlCisgICAgICAgICAgICAvLyBvZiByZWFkaW5nIGZyb20gdGhpcyBzdHJlYW0gb25seS4KKyAgICAgICAgICAgIC8vIGZhaWwoIlNob3VsZCB0aHJvdyBaaXBFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoWmlwRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHJlc291cmNlcywgbnVsbCwgamFyTmFtZSk7CisgICAgICAgICAgICBGaWxlIHNpZ25lZEZpbGUgPSBuZXcgRmlsZShyZXNvdXJjZXMsIGphck5hbWUpOworICAgICAgICAgICAgSmFyRmlsZSBqZiA9IG5ldyBKYXJGaWxlKHNpZ25lZEZpbGUpOworICAgICAgICAgICAgSmFyRW50cnkganJlID0gbmV3IEphckVudHJ5KCJmb28vYmFyL0EuY2xhc3MiKTsKKyAgICAgICAgICAgIGpmLmNsb3NlKCk7CisgICAgICAgICAgICBqZi5nZXRJbnB1dFN0cmVhbShqcmUpOworICAgICAgICAgICAgLy8gSW5wdXRTdHJlYW0gcmV0dXJuZWQgaW4gYW55IHdheSwgZXhjZXB0aW9uIGNhbiBiZSB0aHJvd24gaW4gY2FzZQorICAgICAgICAgICAgLy8gb2YgcmVhZGluZyBmcm9tIHRoaXMgc3RyZWFtIG9ubHkuCisgICAgICAgICAgICAvLyBUaGUgc2FtZSBmb3IgSU9FeGNlcHRpb24KKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGphciBpcyBpbnRhY3QsIGJ1dCB0aGUgZW50cnkgb2JqZWN0IGlzIG1vZGlmaWVkLgorICAgICAqLworICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgaXNzdWUgaW50cm9kdWNlZCBieSBIQVJNT05ZLTQ1Njk6IHNpZ25lZCBhcmNoaXZlcyBjb250YWluaW5nIGZpbGVzIHdpdGggc2l6ZSAwIGNvdWxkIG5vdCBnZXQgdmVyaWZpZWQuCisgICAgcHVibGljIHZvaWQgdGVzdEphclZlcmlmaWNhdGlvbkVtcHR5RW50cnkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsIGVtcHR5RW50cnlKYXIpOworICAgICAgICBGaWxlIGYgPSBuZXcgRmlsZShyZXNvdXJjZXMsIGVtcHR5RW50cnlKYXIpOworCisgICAgICAgIEphckZpbGUgamFyRmlsZSA9IG5ldyBKYXJGaWxlKGYpOworCisgICAgICAgIFppcEVudHJ5IHppcEVudHJ5ID0gamFyRmlsZS5nZXRKYXJFbnRyeShlbXB0eUVudHJ5MSk7CisgICAgICAgIGludCByZXMgPSBqYXJGaWxlLmdldElucHV0U3RyZWFtKHppcEVudHJ5KS5yZWFkKG5ldyBieXRlWzEwMF0sIDAsIDEwMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgbGVuZ3RoIG9mIGVtcHR5IGphciBlbnRyeSIsIC0xLCByZXMpOworCisgICAgICAgIHppcEVudHJ5ID0gamFyRmlsZS5nZXRKYXJFbnRyeShlbXB0eUVudHJ5Mik7CisgICAgICAgIHJlcyA9IGphckZpbGUuZ2V0SW5wdXRTdHJlYW0oemlwRW50cnkpLnJlYWQobmV3IGJ5dGVbMTAwXSwgMCwgMTAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBsZW5ndGggb2YgZW1wdHkgamFyIGVudHJ5IiwgLTEsIHJlcyk7CisKKyAgICAgICAgemlwRW50cnkgPSBqYXJGaWxlLmdldEphckVudHJ5KGVtcHR5RW50cnkzKTsKKyAgICAgICAgcmVzID0gamFyRmlsZS5nZXRJbnB1dFN0cmVhbSh6aXBFbnRyeSkucmVhZCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGxlbmd0aCBvZiBlbXB0eSBqYXIgZW50cnkiLCAtMSwgcmVzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2FyY2hpdmUvdGVzdHMvamF2YS91dGlsL3ppcC9aaXBGaWxlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9hcmNoaXZlL3Rlc3RzL2phdmEvdXRpbC96aXAvWmlwRmlsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xN2QyNTFiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9hcmNoaXZlL3Rlc3RzL2phdmEvdXRpbC96aXAvWmlwRmlsZVRlc3QuamF2YQpAQCAtMCwwICsxLDUwNyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmFyY2hpdmUudGVzdHMuamF2YS51dGlsLnppcDsKKworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9QbGF0Zm9ybUZpbGU7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5yZXNvdXJjZS5TdXBwb3J0X1Jlc291cmNlczsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEVudHJ5OworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRmlsZTsKKworcHVibGljIGNsYXNzIFppcEZpbGVUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHB1YmxpYyBieXRlW10gZ2V0QWxsQnl0ZXNGcm9tU3RyZWFtKElucHV0U3RyZWFtIGlzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnMgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVs1MTJdOworICAgICAgICBpbnQgaVJlYWQ7CisgICAgICAgIGludCBvZmY7CisgICAgICAgIHdoaWxlIChpcy5hdmFpbGFibGUoKSA+IDApIHsKKyAgICAgICAgICAgIGlSZWFkID0gaXMucmVhZChidWYsIDAsIGJ1Zi5sZW5ndGgpOworICAgICAgICAgICAgaWYgKGlSZWFkID4gMCkgYnMud3JpdGUoYnVmLCAwLCBpUmVhZCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGJzLnRvQnl0ZUFycmF5KCk7CisgICAgfQorCisgICAgLy8gdGhlIGZpbGUgaHl0c196aXBGaWxlLnppcCBpbiBzZXR1cCBtdXN0IGJlIGluY2x1ZGVkIGFzIGEgcmVzb3VyY2UKKyAgICBwcml2YXRlIFN0cmluZyB0ZW1wRmlsZU5hbWU7CisKKyAgICBwcml2YXRlIFppcEZpbGUgemZpbGU7CisKKyAgICAvLyBjdXN0b20gc2VjdXJpdHkgbWFuYWdlcgorICAgIFNlY3VyaXR5TWFuYWdlciBzbSA9IG5ldyBTZWN1cml0eU1hbmFnZXIoKSB7CisgICAgICAgIGZpbmFsIFN0cmluZyBmb3JiaWRlblBlcm1pc3Npb25BY3Rpb24gPSAicmVhZCI7CisKKworCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihQZXJtaXNzaW9uIHBlcm0pIHsKKyAgICAgICAgICAgIC8vIG9ubHkgY2hlY2sgaWYgaXQncyBhIEZpbGVQZXJtaXNzaW9uIGJlY2F1c2UgTG9jYWxlIGNoZWNrcworICAgICAgICAgICAgLy8gZm9yIGEgUHJvcGVydHlQZXJtaXNzaW9uIHdpdGggYWN0aW9uInJlYWQiIHRvIGdldCBzeXN0ZW0gcHJvcHMuCisgICAgICAgICAgICBpZiAocGVybSBpbnN0YW5jZW9mIEZpbGVQZXJtaXNzaW9uCisgICAgICAgICAgICAgICAgICAgICYmIHBlcm0uZ2V0QWN0aW9ucygpLmVxdWFscyhmb3JiaWRlblBlcm1pc3Npb25BY3Rpb24pKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9OworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLnppcC5aaXBGaWxlI1ppcEZpbGUoamF2YS5pby5GaWxlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9pb19GaWxlKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLnppcC5aaXBGaWxlKGphdmEuaW8uRmlsZSkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVXNlZCB0byB0ZXN0IiwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLnppcC5aaXBGaWxlI1ppcEZpbGUoamF2YS5pby5GaWxlLCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX0ZpbGVJKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgemZpbGUuY2xvc2UoKTsgLy8gYWJvdXQgdG8gcmVvcGVuIHRoZSBzYW1lIHRlbXAgZmlsZQorICAgICAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZSh0ZW1wRmlsZU5hbWUpOworICAgICAgICBaaXBGaWxlIHppcCA9IG5ldyBaaXBGaWxlKGZpbGUsIFppcEZpbGUuT1BFTl9ERUxFVEUgfCBaaXBGaWxlLk9QRU5fUkVBRCk7CisgICAgICAgIHppcC5jbG9zZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJaaXAgc2hvdWxkIG5vdCBleGlzdCIsICFmaWxlLmV4aXN0cygpKTsKKyAgICAgICAgZmlsZSA9IG5ldyBGaWxlKHRlbXBGaWxlTmFtZSk7CisgICAgICAgIGZpbGUuZGVsZXRlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB6aXAgPSBuZXcgWmlwRmlsZShmaWxlLCBaaXBGaWxlLk9QRU5fUkVBRCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBmaWxlID0gbmV3IEZpbGUodGVtcEZpbGVOYW1lKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHppcCA9IG5ldyBaaXBGaWxlKGZpbGUsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogamF2YS51dGlsLnppcC5aaXBGaWxlI1ppcEZpbGUoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoInVzZXIuZGlyIiwgU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmlvLnRtcGRpciIpKTsKKworICAgICAgICB6ZmlsZS5jbG9zZSgpOyAvLyBhYm91dCB0byByZW9wZW4gdGhlIHNhbWUgdGVtcCBmaWxlCisgICAgICAgIFppcEZpbGUgemlwID0gbmV3IFppcEZpbGUodGVtcEZpbGVOYW1lKTsKKyAgICAgICAgemlwLmNsb3NlKCk7CisgICAgICAgIEZpbGUgZmlsZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoInppcCIsICJ0bXAiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHppcCA9IG5ldyBaaXBGaWxlKGZpbGUuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGZhaWwoIlppcEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChaaXBFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgZmlsZS5kZWxldGUoKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgWmlwRW50cnkgdGVzdF9maW5hbGl6ZTEoWmlwRmlsZSB6aXApIHsKKyAgICAgICAgcmV0dXJuIHppcC5nZXRFbnRyeSgiRmlsZTEudHh0Iik7CisgICAgfQorCisgICAgcHJvdGVjdGVkIFppcEZpbGUgdGVzdF9maW5hbGl6ZTIoRmlsZSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3IFppcEZpbGUoZmlsZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLnppcC5aaXBGaWxlI2ZpbmFsaXplKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ZpbmFsaXplKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBTdXBwb3J0X1Jlc291cmNlcy5nZXRTdHJlYW0oImh5dHNfWmlwRmlsZS56aXAiKTsKKyAgICAgICAgRmlsZSBmaWxlID0gU3VwcG9ydF9SZXNvdXJjZXMuY3JlYXRlVGVtcEZpbGUoIi5qYXIiKTsKKyAgICAgICAgT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZpbGUpOworICAgICAgICBpbnQgcmVzdWx0OworICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbNDA5Nl07CisgICAgICAgIHdoaWxlICgocmVzdWx0ID0gaW4ucmVhZChidWYpKSAhPSAtMSkgeworICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZiwgMCwgcmVzdWx0KTsKKyAgICAgICAgfQorICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgLyoKKyAgICAgICAgICogWmlwRmlsZSB6aXAgPSBuZXcgWmlwRmlsZShmaWxlKTsgWmlwRW50cnkgZW50cnkxID0KKyAgICAgICAgICogemlwLmdldEVudHJ5KCJGaWxlMS50eHQiKTsgYXNzZXJ0Tm90TnVsbCgiRGlkIG5vdCBmaW5kIGVudHJ5IiwKKyAgICAgICAgICogZW50cnkxKTsgZW50cnkxID0gbnVsbDsgemlwID0gbnVsbDsKKyAgICAgICAgICovCisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiRGlkIG5vdCBmaW5kIGVudHJ5IiwKKyAgICAgICAgICAgICAgICB0ZXN0X2ZpbmFsaXplMSh0ZXN0X2ZpbmFsaXplMihmaWxlKSkpOworICAgICAgICBTeXN0ZW0uZ2MoKTsKKyAgICAgICAgU3lzdGVtLmdjKCk7CisgICAgICAgIFN5c3RlbS5ydW5GaW5hbGl6YXRpb24oKTsKKyAgICAgICAgZmlsZS5kZWxldGUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiWmlwIHNob3VsZCBub3QgZXhpc3QiLCAhZmlsZS5leGlzdHMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIGphdmEudXRpbC56aXAuWmlwRmlsZSNjbG9zZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC56aXAuWmlwRmlsZS5jbG9zZSgpCisgICAgICAgIEZpbGUgZmwgPSBuZXcgRmlsZSh0ZW1wRmlsZU5hbWUpOworICAgICAgICBaaXBGaWxlIHpmID0gbmV3IFppcEZpbGUoZmwpOworICAgICAgICBJbnB1dFN0cmVhbSBpczEgPSB6Zi5nZXRJbnB1dFN0cmVhbSh6Zi5nZXRFbnRyeSgiRmlsZTEudHh0IikpOworICAgICAgICBJbnB1dFN0cmVhbSBpczIgPSB6Zi5nZXRJbnB1dFN0cmVhbSh6Zi5nZXRFbnRyeSgiRmlsZTIudHh0IikpOworCisgICAgICAgIGlzMS5yZWFkKCk7CisgICAgICAgIGlzMi5yZWFkKCk7CisKKyAgICAgICAgemYuY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMxLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzMi5yZWFkKCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC56aXAuWmlwRmlsZSNlbnRyaWVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VudHJpZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5FbnVtZXJhdGlvbiBqYXZhLnV0aWwuemlwLlppcEZpbGUuZW50cmllcygpCisgICAgICAgIEVudW1lcmF0aW9uPD8gZXh0ZW5kcyBaaXBFbnRyeT4gZW51bWVyID0gemZpbGUuZW50cmllcygpOworICAgICAgICBpbnQgYyA9IDA7CisgICAgICAgIHdoaWxlIChlbnVtZXIuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgICsrYzsKKyAgICAgICAgICAgIGVudW1lci5uZXh0RWxlbWVudCgpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBudW1iZXIgb2YgZW50cmllcyByZXR1cm5lZDogIiArIGMsIGMgPT0gNik7CisKKyAgICAgICAgRW51bWVyYXRpb248PyBleHRlbmRzIFppcEVudHJ5PiBlbnVtZXJhdGlvbiA9IHpmaWxlLmVudHJpZXMoKTsKKyAgICAgICAgemZpbGUuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVudW1lcmF0aW9uLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICBmYWlsKCJkaWQgbm90IGRldGVjdCBjbG9zZWQgZmlsZSIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbnVtZXJhdGlvbi5oYXNNb3JlRWxlbWVudHMoKTsKKyAgICAgICAgICAgIGZhaWwoImRpZCBub3QgZGV0ZWN0IGNsb3NlZCBmaWxlIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHpmaWxlLmVudHJpZXMoKTsKKyAgICAgICAgICAgIGZhaWwoImRpZCBub3QgZGV0ZWN0IGNsb3NlZCBmaWxlIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLnppcC5aaXBGaWxlI2dldEVudHJ5KGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRFbnRyeUxqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC56aXAuWmlwRW50cnkKKyAgICAgICAgLy8gamF2YS51dGlsLnppcC5aaXBGaWxlLmdldEVudHJ5KGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIGphdmEudXRpbC56aXAuWmlwRW50cnkgemVudHJ5ID0gemZpbGUuZ2V0RW50cnkoIkZpbGUxLnR4dCIpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJDb3VsZCBub3Qgb2J0YWluIFppcEVudHJ5IiwgemVudHJ5KTsKKyAgICAgICAgaW50IHI7CisgICAgICAgIElucHV0U3RyZWFtIGluOworCisgICAgICAgIHplbnRyeSA9IHpmaWxlLmdldEVudHJ5KCJ0ZXN0ZGlyMS9GaWxlMS50eHQiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ291bGQgbm90IG9idGFpbiBaaXBFbnRyeTogdGVzdGRpcjEvRmlsZTEudHh0IiwgemVudHJ5KTsKKyAgICAgICAgemVudHJ5ID0gemZpbGUuZ2V0RW50cnkoInRlc3RkaXIxLyIpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJDb3VsZCBub3Qgb2J0YWluIFppcEVudHJ5OiB0ZXN0ZGlyMS8iLCB6ZW50cnkpOworICAgICAgICBpbiA9IHpmaWxlLmdldElucHV0U3RyZWFtKHplbnRyeSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoInRlc3RkaXIxLyBzaG91bGQgbm90IGhhdmUgbnVsbCBpbnB1dCBzdHJlYW0iLCBpbik7CisgICAgICAgIHIgPSBpbi5yZWFkKCk7CisgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygidGVzdGRpcjEvIHNob3VsZCBub3QgY29udGFpbiBkYXRhIiwgLTEsIHIpOworCisgICAgICAgIHplbnRyeSA9IHpmaWxlLmdldEVudHJ5KCJ0ZXN0ZGlyMS90ZXN0ZGlyMSIpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJDb3VsZCBub3Qgb2J0YWluIFppcEVudHJ5OiB0ZXN0ZGlyMS90ZXN0ZGlyMSIsIHplbnRyeSk7CisgICAgICAgIGluID0gemZpbGUuZ2V0SW5wdXRTdHJlYW0oemVudHJ5KTsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzI1Nl07CisgICAgICAgIHIgPSBpbi5yZWFkKGJ1Zik7CisgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IGNvbnRlbnRzIiwgIlRoaXMgaXMgYWxzbyB0ZXh0IiwgbmV3IFN0cmluZyhidWYsCisgICAgICAgICAgICAgICAgMCwgcikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RW50cnlMamF2YV9sYW5nX1N0cmluZ19BbmRyb2lkT25seSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGphdmEudXRpbC56aXAuWmlwRW50cnkgemVudHJ5ID0gemZpbGUuZ2V0RW50cnkoIkZpbGUxLnR4dCIpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJDb3VsZCBub3Qgb2J0YWluIFppcEVudHJ5IiwgemVudHJ5KTsKKyAgICAgICAgaW50IHI7CisgICAgICAgIElucHV0U3RyZWFtIGluOworCisgICAgICAgIHplbnRyeSA9IHpmaWxlLmdldEVudHJ5KCJ0ZXN0ZGlyMSIpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJNdXN0IGJlIGFibGUgdG8gb2J0YWluIFppcEVudHJ5OiB0ZXN0ZGlyMSIsIHplbnRyeSk7CisgICAgICAgIGluID0gemZpbGUuZ2V0SW5wdXRTdHJlYW0oemVudHJ5KTsKKyAgICAgICAgLyoKKyAgICAgICAgICogQW5kcm9pZCBkZWxpdmVycyBlbXB0eSBJbnB1dFN0cmVhbSwgUkkgbm8gSW5wdXRTdHJlYW0gYXQgYWxsLiBUaGUKKyAgICAgICAgICogc3BlYyBkb2Vzbid0IGNsYXJpZnkgdGhpcywgc28gd2UgbmVlZCB0byBkZWFsIHdpdGggYm90aCBzaXR1YXRpb25zLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IGRhdGEgPSAtMTsKKyAgICAgICAgaWYgKGluICE9IG51bGwpIHsKKyAgICAgICAgICAgIGRhdGEgPSBpbi5yZWFkKCk7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiTXVzdCBub3QgYmUgYWJsZSB0byByZWFkIGRpcmVjdG9yeSBkYXRhIiwgLTEsIGRhdGEpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RW50cnlMamF2YV9sYW5nX1N0cmluZ19FeCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGphdmEudXRpbC56aXAuWmlwRW50cnkgemVudHJ5ID0gemZpbGUuZ2V0RW50cnkoIkZpbGUxLnR4dCIpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJDb3VsZCBub3Qgb2J0YWluIFppcEVudHJ5IiwgemVudHJ5KTsKKworICAgICAgICB6ZmlsZS5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgemZpbGUuZ2V0RW50cnkoIkZpbGUyLnR4dCIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIGphdmEudXRpbC56aXAuWmlwRmlsZSNnZXRJbnB1dFN0cmVhbShqYXZhLnV0aWwuemlwLlppcEVudHJ5KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5wdXRTdHJlYW1MamF2YV91dGlsX3ppcF9aaXBFbnRyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmlvLklucHV0U3RyZWFtCisgICAgICAgIC8vIGphdmEudXRpbC56aXAuWmlwRmlsZS5nZXRJbnB1dFN0cmVhbShqYXZhLnV0aWwuemlwLlppcEVudHJ5KQorICAgICAgICBaaXBFbnRyeSB6ZW50cnkgPSBudWxsOworICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB6ZW50cnkgPSB6ZmlsZS5nZXRFbnRyeSgiRmlsZTEudHh0Iik7CisgICAgICAgICAgICBpcyA9IHpmaWxlLmdldElucHV0U3RyZWFtKHplbnRyeSk7CisgICAgICAgICAgICBieXRlW10gcmJ1ZiA9IG5ldyBieXRlWzEwMDBdOworICAgICAgICAgICAgaW50IHI7CisgICAgICAgICAgICBpcy5yZWFkKHJidWYsIDAsIHIgPSAoaW50KSB6ZW50cnkuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0SW5wdXRTdHJlYW0gcmVhZCBpbmNvcnJlY3QgZGF0YSIsICJUaGlzIGlzIHRleHQiLAorICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKHJidWYsIDAsIHIpKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBkdXJpbmcgZ2V0SW5wdXRTdHJlYW0iKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIkZhaWxlZCB0byBjbG9zZSBpbnB1dCBzdHJlYW0iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHplbnRyeSA9IHpmaWxlLmdldEVudHJ5KCJGaWxlMi50eHQiKTsKKyAgICAgICAgemZpbGUuY2xvc2UoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzID0gemZpbGUuZ2V0SW5wdXRTdHJlYW0oemVudHJ5KTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBaaXBFeGNlcHRpb24gY2FuIG5vdCBiZSBjaGVja2VkLiBTdHJlYW0gb2JqZWN0IHJldHVybmVkIG9yIG51bGwuCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLnppcC5aaXBGaWxlI2dldE5hbWUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TmFtZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcgamF2YS51dGlsLnppcC5aaXBGaWxlLmdldE5hbWUoKQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgbmFtZTogIiArIHpmaWxlLmdldE5hbWUoKSwgemZpbGUKKyAgICAgICAgICAgICAgICAuZ2V0TmFtZSgpLmVxdWFscyh0ZW1wRmlsZU5hbWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogamF2YS51dGlsLnppcC5aaXBGaWxlI3NpemUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2l6ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyg2LCB6ZmlsZS5zaXplKCkpOworICAgICAgICB6ZmlsZS5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgemZpbGUuc2l6ZSgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5JbnB1dFN0cmVhbSNyZXNldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZXNldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIHJlYWQgYW4gdW5jb21wcmVzc2VkIGVudHJ5CisgICAgICAgIFppcEVudHJ5IHplbnRyeSA9IHpmaWxlLmdldEVudHJ5KCJGaWxlMS50eHQiKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSB6ZmlsZS5nZXRJbnB1dFN0cmVhbSh6ZW50cnkpOworICAgICAgICBieXRlW10gcmJ1ZjEgPSBuZXcgYnl0ZVs2XTsKKyAgICAgICAgYnl0ZVtdIHJidWYyID0gbmV3IGJ5dGVbNl07CisgICAgICAgIGludCByMSwgcjI7CisgICAgICAgIHIxID0gaXMucmVhZChyYnVmMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhyYnVmMS5sZW5ndGgsIHIxKTsKKyAgICAgICAgcjIgPSBpcy5yZWFkKHJidWYyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJidWYyLmxlbmd0aCwgcjIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZXNldCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGlzLmNsb3NlKCk7CisKKyAgICAgICAgLy8gcmVhZCBhIGNvbXByZXNzZWQgZW50cnkKKyAgICAgICAgYnl0ZVtdIHJidWYzID0gbmV3IGJ5dGVbNDE4NV07CisgICAgICAgIFppcEVudHJ5IHplbnRyeTIgPSB6ZmlsZS5nZXRFbnRyeSgiRmlsZTMudHh0Iik7CisgICAgICAgIGlzID0gemZpbGUuZ2V0SW5wdXRTdHJlYW0oemVudHJ5Mik7CisgICAgICAgIHIxID0gaXMucmVhZChyYnVmMyk7CisgICAgICAgIGFzc2VydEVxdWFscyg0MTgzLCByMSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZXNldCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGlzLmNsb3NlKCk7CisKKyAgICAgICAgaXMgPSB6ZmlsZS5nZXRJbnB1dFN0cmVhbSh6ZW50cnkyKTsKKyAgICAgICAgcjEgPSBpcy5yZWFkKHJidWYzLCAwLCAzMDAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMwMDAsIHIxKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlc2V0KCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLklucHV0U3RyZWFtI3Jlc2V0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Jlc2V0X3N1YnRlc3QwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gcmVhZCBhbiB1bmNvbXByZXNzZWQgZW50cnkKKyAgICAgICAgWmlwRW50cnkgemVudHJ5ID0gemZpbGUuZ2V0RW50cnkoIkZpbGUxLnR4dCIpOworICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IHpmaWxlLmdldElucHV0U3RyZWFtKHplbnRyeSk7CisgICAgICAgIGJ5dGVbXSByYnVmMSA9IG5ldyBieXRlWzEyXTsKKyAgICAgICAgYnl0ZVtdIHJidWYyID0gbmV3IGJ5dGVbMTJdOworICAgICAgICBpbnQgciA9IGlzLnJlYWQocmJ1ZjEsIDAsIDQpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgcik7CisgICAgICAgIGlzLm1hcmsoMCk7CisgICAgICAgIHIgPSBpcy5yZWFkKHJidWYxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDgsIHIpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGlzLnJlYWQoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlc2V0KCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgIC8vIHJlYWQgYSBjb21wcmVzc2VkIGVudHJ5CisgICAgICAgIGJ5dGVbXSByYnVmMyA9IG5ldyBieXRlWzQxODVdOworICAgICAgICBaaXBFbnRyeSB6ZW50cnkyID0gemZpbGUuZ2V0RW50cnkoIkZpbGUzLnR4dCIpOworICAgICAgICBpcyA9IHpmaWxlLmdldElucHV0U3RyZWFtKHplbnRyeTIpOworICAgICAgICByID0gaXMucmVhZChyYnVmMywgMCwgMzAwMCk7CisgICAgICAgIGFzc2VydEVxdWFscygzMDAwLCByKTsKKyAgICAgICAgaXMubWFyaygwKTsKKyAgICAgICAgciA9IGlzLnJlYWQocmJ1ZjMpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTE4Mywgcik7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgaXMucmVhZCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVzZXQoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGlzLmNsb3NlKCk7CisgICAgfQorCisJLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBDcmVhdGUgYSBsb2NhbCBjb3B5IG9mIHRoZSBmaWxlIHNpbmNlIHNvbWUgdGVzdHMgd2FudCB0byBhbHRlcgorICAgICAgICAgICAgLy8gaW5mb3JtYXRpb24uCisgICAgICAgICAgICB0ZW1wRmlsZU5hbWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaW8udG1wZGlyIik7CisgICAgICAgICAgICBTdHJpbmcgc2VwYXJhdG9yID0gU3lzdGVtLmdldFByb3BlcnR5KCJmaWxlLnNlcGFyYXRvciIpOworICAgICAgICAgICAgaWYgKHRlbXBGaWxlTmFtZS5jaGFyQXQodGVtcEZpbGVOYW1lLmxlbmd0aCgpIC0gMSkgPT0gc2VwYXJhdG9yCisgICAgICAgICAgICAgICAgICAgIC5jaGFyQXQoMCkpIHsKKyAgICAgICAgICAgICAgICB0ZW1wRmlsZU5hbWUgPSBTdXBwb3J0X1BsYXRmb3JtRmlsZS5nZXROZXdQbGF0Zm9ybUZpbGUoCisgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wRmlsZU5hbWUsICJnYWJiYS56aXAiKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGVtcEZpbGVOYW1lID0gU3VwcG9ydF9QbGF0Zm9ybUZpbGUuZ2V0TmV3UGxhdGZvcm1GaWxlKAorICAgICAgICAgICAgICAgICAgICAgICAgdGVtcEZpbGVOYW1lICsgc2VwYXJhdG9yLCAiZ2FiYmEuemlwIik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEZpbGUgZiA9IG5ldyBGaWxlKHRlbXBGaWxlTmFtZSk7CisgICAgICAgICAgICBmLmRlbGV0ZSgpOworICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBTdXBwb3J0X1Jlc291cmNlcy5nZXRTdHJlYW0oImh5dHNfWmlwRmlsZS56aXAiKTsKKyAgICAgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gZm9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZik7CisgICAgICAgICAgICBieXRlW10gcmJ1ZiA9IGdldEFsbEJ5dGVzRnJvbVN0cmVhbShpcyk7CisgICAgICAgICAgICBmb3Mud3JpdGUocmJ1ZiwgMCwgcmJ1Zi5sZW5ndGgpOworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIGZvcy5jbG9zZSgpOworICAgICAgICAgICAgemZpbGUgPSBuZXcgWmlwRmlsZShmKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXhjZXB0aW9uIGR1cmluZyBaaXBGaWxlIHNldHVwOiIpOworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKHpmaWxlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAvLyBOb3RlIHpmaWxlIGlzIGEgdXNlci1kZWZpbmVkIHppcCBmaWxlIHVzZWQgYnkgb3RoZXIgdGVzdHMgYW5kCisgICAgICAgICAgICAgICAgLy8gc2hvdWxkIG5vdCBiZSBkZWxldGVkCisgICAgICAgICAgICAgICAgemZpbGUuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB0ZW1wRmlsZU5hbWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaW8udG1wZGlyIik7CisgICAgICAgICAgICAgICAgU3RyaW5nIHNlcGFyYXRvciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiZmlsZS5zZXBhcmF0b3IiKTsKKyAgICAgICAgICAgICAgICBpZiAodGVtcEZpbGVOYW1lLmNoYXJBdCh0ZW1wRmlsZU5hbWUubGVuZ3RoKCkgLSAxKSA9PSBzZXBhcmF0b3IKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jaGFyQXQoMCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGVtcEZpbGVOYW1lID0gU3VwcG9ydF9QbGF0Zm9ybUZpbGUuZ2V0TmV3UGxhdGZvcm1GaWxlKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBGaWxlTmFtZSwgImdhYmJhLnppcCIpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRlbXBGaWxlTmFtZSA9IFN1cHBvcnRfUGxhdGZvcm1GaWxlLmdldE5ld1BsYXRmb3JtRmlsZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wRmlsZU5hbWUgKyBzZXBhcmF0b3IsICJnYWJiYS56aXAiKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBGaWxlIGYgPSBuZXcgRmlsZSh0ZW1wRmlsZU5hbWUpOworICAgICAgICAgICAgICAgIGYuZGVsZXRlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9CYWRQYWRkaW5nRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0JhZFBhZGRpbmdFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWFhNDU2MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9CYWRQYWRkaW5nRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0bzsKKworaW1wb3J0IGphdmF4LmNyeXB0by5CYWRQYWRkaW5nRXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkJhZFBhZGRpbmdFeGNlcHRpb248L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBCYWRQYWRkaW5nRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisgICAgc3RhdGljIFRocm93YWJsZSB0Q2F1c2UgPSBuZXcgVGhyb3dhYmxlKCJUaHJvd2FibGUgZm9yIGV4Y2VwdGlvbiIpOworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+QmFkUGFkZGluZ0V4Y2VwdGlvbigpPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246CisgICAgICogY29uc3RydWN0cyBCYWRQYWRkaW5nRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QmFkUGFkZGluZ0V4Y2VwdGlvbjAxKCkgeworICAgICAgICBCYWRQYWRkaW5nRXhjZXB0aW9uIHRFID0gbmV3IEJhZFBhZGRpbmdFeGNlcHRpb24oKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+QmFkUGFkZGluZ0V4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBCYWRQYWRkaW5nRXhjZXB0aW9uIHdpdGggZGV0YWlsIG1lc3NhZ2UgbXNnLgorICAgICAqIFBhcmFtZXRlciA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RCYWRQYWRkaW5nRXhjZXB0aW9uMDIoKSB7CisgICAgICAgIEJhZFBhZGRpbmdFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgQmFkUGFkZGluZ0V4Y2VwdGlvbihtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkJhZFBhZGRpbmdFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgQmFkUGFkZGluZ0V4Y2VwdGlvbiB3aGVuIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RCYWRQYWRkaW5nRXhjZXB0aW9uMDMoKSB7CisgICAgICAgIFN0cmluZyBtc2cgPSBudWxsOworICAgICAgICBCYWRQYWRkaW5nRXhjZXB0aW9uIHRFID0gbmV3IEJhZFBhZGRpbmdFeGNlcHRpb24obXNnKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0NpcGhlcklucHV0U3RyZWFtMVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9DaXBoZXJJbnB1dFN0cmVhbTFUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGZjOWIzZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9DaXBoZXJJbnB1dFN0cmVhbTFUZXN0LmphdmEKQEAgLTAsMCArMSwyNjggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0bzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworCitpbXBvcnQgamF2YXguY3J5cHRvLkNpcGhlcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uS2V5R2VuZXJhdG9yOworaW1wb3J0IGphdmF4LmNyeXB0by5Ob1N1Y2hQYWRkaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmNyeXB0by5OdWxsQ2lwaGVyOworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXJJbnB1dFN0cmVhbTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKi8KK3B1YmxpYyBjbGFzcyBDaXBoZXJJbnB1dFN0cmVhbTFUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgVGVzdElucHV0U3RyZWFtIGV4dGVuZHMgQnl0ZUFycmF5SW5wdXRTdHJlYW0geworICAgICAgICBwcml2YXRlIGJvb2xlYW4gY2xvc2VkID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIFRlc3RJbnB1dFN0cmVhbShieXRlW10gZGF0YSkgeworICAgICAgICAgICAgc3VwZXIoZGF0YSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICAgICAgICAgIGNsb3NlZCA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiB3YXNDbG9zZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gY2xvc2VkOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2lwaGVySW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaXMpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGF0CisgICAgICogQ2lwaGVySW5wdXRTdHJlYW0gdXNlcyBOdWxsQ2lwaGVyIGlmIENpcGhlciBpcyBub3Qgc3BlY2lmaWVkCisgICAgICogaW4gdGhlIGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDaXBoZXJJbnB1dFN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlW10geyAtMTI3LCAtMTAwLCAtNTAsIC0xMCwgLTEsIDAsIDEsIDEwLCA1MCwgMTI3IH07CisgICAgICAgIFRlc3RJbnB1dFN0cmVhbSB0aXMgPSBuZXcgVGVzdElucHV0U3RyZWFtKGRhdGEpOworICAgICAgICBDaXBoZXJJbnB1dFN0cmVhbSBjaXMgPSBuZXcgQ2lwaGVySW5wdXRTdHJlYW0odGlzKXt9OworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKChieXRlKSBjaXMucmVhZCgpICE9IGRhdGFbaV0pIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJOdWxsQ2lwaGVyIHNob3VsZCBiZSB1c2VkICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgImlmIENpcGhlciBpcyBub3Qgc3BlY2lmaWVkLiIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChjaXMucmVhZCgpICE9IC0xKSB7CisgICAgICAgICAgICBmYWlsKCJOdWxsQ2lwaGVyIHNob3VsZCBiZSB1c2VkIGlmIENpcGhlciBpcyBub3Qgc3BlY2lmaWVkLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogcmVhZCgpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGF0IG1ldGhvZCByZXR1cm5zIHRoZSBjb3JyZWN0IHZhbHVlCisgICAgICogKHJlbGF0ZWQgdG8gdGhlIElucHV0U3RyZWFtKSBhbmQgdGhhdCBpdCByZXR1cm5zIC0xIGF0IHRoZSBlbmQgb2Ygc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkMSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlW10geyAtMTI3LCAtMTAwLCAtNTAsIC0xMCwgLTEsIDAsIDEsIDEwLCA1MCwgMTI3IH07CisgICAgICAgIFRlc3RJbnB1dFN0cmVhbSB0aXMgPSBuZXcgVGVzdElucHV0U3RyZWFtKGRhdGEpOworICAgICAgICBDaXBoZXJJbnB1dFN0cmVhbSBjaXMgPSBuZXcgQ2lwaGVySW5wdXRTdHJlYW0odGlzLCBuZXcgTnVsbENpcGhlcigpKTsKKyAgICAgICAgYnl0ZSByZXM7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKChyZXMgPSAoYnl0ZSkgY2lzLnJlYWQoKSkgIT0gZGF0YVtpXSkgeworICAgICAgICAgICAgICAgIGZhaWwoInJlYWQoKSByZXR1cm5lZCB0aGUgaW5jb3JyZWN0IHZhbHVlLiAiICsgIkV4cGVjdGVkOiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIGRhdGFbaV0gKyAiLCBHb3Q6ICIgKyByZXMgKyAiLiIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChjaXMucmVhZCgpICE9IC0xKSB7CisgICAgICAgICAgICBmYWlsKCJyZWFkKCkgc2hvdWxkIHJldHVybiAtMSBhdCB0aGUgZW5kIG9mIHRoZSBzdHJlYW0uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiByZWFkKGJ5dGVbXSBiKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhhdCBtZXRob2QgcmV0dXJucyB0aGUgY29ycmVjdAorICAgICAqIHZhbHVlIChyZWxhdGVkIHRvIHRoZSBJbnB1dFN0cmVhbSkgYW5kIHRoYXQgaXQgcmV0dXJucyAtMSBhdCB0aGUgZW5kIG9mCisgICAgICogc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlW10geyAtMTI3LCAtMTAwLCAtNTAsIC0xMCwgLTEsIDAsIDEsIDEwLCA1MCwgMTI3IH07CisgICAgICAgIFRlc3RJbnB1dFN0cmVhbSB0aXMgPSBuZXcgVGVzdElucHV0U3RyZWFtKGRhdGEpOworICAgICAgICBDaXBoZXJJbnB1dFN0cmVhbSBjaXMgPSBuZXcgQ2lwaGVySW5wdXRTdHJlYW0odGlzLCBuZXcgTnVsbENpcGhlcigpKTsKKworICAgICAgICBpbnQgZXhwZWN0ZWQgPSBkYXRhLmxlbmd0aDsKKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW2V4cGVjdGVkXTsKKworICAgICAgICBpbnQgaW5kID0gMDsgLy8gaW5kZXggaW50byB0aGUgZGF0YSBhcnJheSAodG8gY2hlY2sgdGhlIGdvdCBkYXRhKQorICAgICAgICBpbnQgZ290ID0gY2lzLnJlYWQocmVzdWx0KTsgLy8gdGhlIG51bWJlciBvZiBnb3QgYnl0ZXMKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgZ290IC0gaW5kOyBqKyspIHsKKyAgICAgICAgICAgICAgICBpZiAocmVzdWx0W2pdICE9IGRhdGFbaW5kICsgal0pIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgicmVhZChieXRlW10gYikgcmV0dXJuZWQgaW5jb3JyZWN0IGRhdGEuIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGdvdCA9PSBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfSBlbHNlIGlmIChnb3QgPiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgIGZhaWwoIlRoZSBkYXRhIHJldHVybmVkIGJ5IHJlYWQoYnl0ZVtdIGIpICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgImlzIGxhcmdlciB0aGFuIGV4cGVjdGVkLiIpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpbmQgPSBnb3Q7CisgICAgICAgICAgICAgICAgZ290ICs9IGNpcy5yZWFkKHJlc3VsdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNpcy5yZWFkKHJlc3VsdCkgIT0gLTEpIHsKKyAgICAgICAgICAgIGZhaWwoInJlYWQoYnl0ZVtdIGIpIHNob3VsZCByZXR1cm4gLTEgIgorICAgICAgICAgICAgICAgICAgICArICJhdCB0aGUgZW5kIG9mIHRoZSBzdHJlYW0uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiByZWFkKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhhdCBtZXRob2QKKyAgICAgKiByZXR1cm5zIHRoZSBjb3JyZWN0IHZhbHVlIChyZWxhdGVkIHRvIHRoZSBJbnB1dFN0cmVhbSksIHRoYXQgaXQgZGlzY2FyZHMKKyAgICAgKiBieXRlcyBpbiB0aGUgY2FzZSBvZiBudWxsIGJ1ZmZlciwgYW5kIHRoYXQgaXQgcmV0dXJucyAtMSBhdCB0aGUgZW5kIG9mCisgICAgICogc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkMygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlW10geyAtMTI3LCAtMTAwLCAtNTAsIC0xMCwgLTEsIDAsIDEsIDEwLCA1MCwgMTI3IH07CisgICAgICAgIFRlc3RJbnB1dFN0cmVhbSB0aXMgPSBuZXcgVGVzdElucHV0U3RyZWFtKGRhdGEpOworICAgICAgICBDaXBoZXJJbnB1dFN0cmVhbSBjaXMgPSBuZXcgQ2lwaGVySW5wdXRTdHJlYW0odGlzLCBuZXcgTnVsbENpcGhlcigpKTsKKworICAgICAgICBpbnQgZXhwZWN0ZWQgPSBkYXRhLmxlbmd0aDsKKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW2V4cGVjdGVkXTsKKworICAgICAgICBpbnQgc2tpcCA9IDI7CisgICAgICAgIGludCBpbmQgPSBza2lwOyAvLyBpbmRleCBpbnRvIHRoZSBkYXRhIGFycmF5ICh0byBjaGVjayB0aGUgZ290IGRhdGEpCisgICAgICAgIC8vIHNob3VsZCByZWFkIGFuZCBkaXNjYXJkIGJ5dGVzOworICAgICAgICBjaXMucmVhZChudWxsLCAwLCBza2lwKTsKKyAgICAgICAgaW50IGdvdCA9IHNraXAgKyBjaXMucmVhZChyZXN1bHQsIDAsIDEpOyAvLyB0aGUgbnVtYmVyIG9mIGdvdCBieXRlcworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBnb3QgLSBpbmQ7IGorKykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygicmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAicmV0dXJuZWQgaW5jb3JyZWN0IGRhdGEuIiwgcmVzdWx0W2pdLCBkYXRhW2luZCArIGpdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChnb3QgPT0gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZ290ID4gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJUaGUgZGF0YSByZXR1cm5lZCBieSAiCisgICAgICAgICAgICAgICAgICAgICAgICArICJyZWFkKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSAiCisgICAgICAgICAgICAgICAgICAgICAgICArICJpcyBsYXJnZXIgdGhhbiBleHBlY3RlZC4iKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaW5kID0gZ290OworICAgICAgICAgICAgICAgIGdvdCArPSBjaXMucmVhZChyZXN1bHQsIDAsIDMpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChjaXMucmVhZChyZXN1bHQsIDAsIDEpICE9IC0xKSB7CisgICAgICAgICAgICBmYWlsKCJyZWFkKCkgc2hvdWxkIHJldHVybiAtMSBhdCB0aGUgZW5kIG9mIHRoZSBzdHJlYW0uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBza2lwKGxvbmcgbikgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIHRoYXQgdGhlIG1ldGhvZCBjb3JyZWN0bHkgc2tpcHMgdGhlCisgICAgICogYnl0ZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNraXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVtdIHsgLTEyNywgLTEwMCwgLTUwLCAtMTAsIC0xLCAwLCAxLCAxMCwgNTAsIDEyNyB9OworICAgICAgICBUZXN0SW5wdXRTdHJlYW0gdGlzID0gbmV3IFRlc3RJbnB1dFN0cmVhbShkYXRhKTsKKyAgICAgICAgQ2lwaGVySW5wdXRTdHJlYW0gY2lzID0gbmV3IENpcGhlcklucHV0U3RyZWFtKHRpcywgbmV3IE51bGxDaXBoZXIoKSk7CisgICAgICAgIGludCBleHBlY3RlZCA9IGRhdGEubGVuZ3RoOworICAgICAgICBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbZXhwZWN0ZWRdOworCisgICAgICAgIGludCBza2lwcGVkID0gKGludCkgY2lzLnNraXAoMik7CisgICAgICAgIGludCBpbmQgPSBza2lwcGVkOworICAgICAgICBpbnQgZ290ID0gc2tpcHBlZCArIGNpcy5yZWFkKHJlc3VsdCwgMCwgMSk7IC8vIHRoZSBudW1iZXIgb2YgZ290IGJ5dGVzCisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGdvdCAtIGluZDsgaisrKSB7CisgICAgICAgICAgICAgICAgaWYgKHJlc3VsdFtqXSAhPSBkYXRhW2luZCArIGpdKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoInJlYWQoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJyZXR1cm5lZCBpbmNvcnJlY3QgZGF0YTogRXhwZWN0ZWQgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZGF0YVtpbmQgKyBqXSArICIsIGdvdDogIiArIHJlc3VsdFtqXSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGdvdCA9PSBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfSBlbHNlIGlmIChnb3QgPiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgIGZhaWwoIlRoZSBkYXRhIHJldHVybmVkIGJ5ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgInJlYWQoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgImlzIGxhcmdlciB0aGFuIGV4cGVjdGVkLiIpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpbmQgPSBnb3Q7CisgICAgICAgICAgICAgICAgZ290ICs9IGNpcy5yZWFkKHJlc3VsdCwgMCwgMSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKChnb3QgPSBjaXMucmVhZChyZXN1bHQsIDAsIDEpKSAhPSAtMSkgeworICAgICAgICAgICAgZmFpbCgicmVhZCgpIHNob3VsZCByZXR1cm4gLTEgYXQgdGhlIGVuZCBvZiB0aGUgc3RyZWFtLiAiCisgICAgICAgICAgICAgICAgICAgICsgIk91dHB1dCBpczogIiArIGdvdCArICIuIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBhdmFpbGFibGUoKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhhdCB0aGUgbWV0aG9kIGFsd2F5cyByZXR1cm4gMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXZhaWxhYmxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbXSB7IC0xMjcsIC0xMDAsIC01MCwgLTEwLCAtMSwgMCwgMSwgMTAsIDUwLCAxMjcgfTsKKyAgICAgICAgVGVzdElucHV0U3RyZWFtIHRpcyA9IG5ldyBUZXN0SW5wdXRTdHJlYW0oZGF0YSk7CisgICAgICAgIENpcGhlcklucHV0U3RyZWFtIGNpcyA9IG5ldyBDaXBoZXJJbnB1dFN0cmVhbSh0aXMsIG5ldyBOdWxsQ2lwaGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSByZXR1cm5lZCBieSBhdmFpbGFibGUoKSBtZXRob2QgdmFsdWUgIgorICAgICAgICAgICAgICAgICsgInNob3VsZCBiZSAwLiIsIGNpcy5hdmFpbGFibGUoKSwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogY2xvc2UoKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhhdCB0aGUgbWV0aG9kIGNhbGxzIHRoZSBjbG9zZSgpCisgICAgICogbWV0aG9kIG9mIHRoZSB1bmRlcmx5aW5nIGlucHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVtdIHsgLTEyNywgLTEwMCwgLTUwLCAtMTAsIC0xLCAwLCAxLCAxMCwgNTAsIDEyNyB9OworICAgICAgICBUZXN0SW5wdXRTdHJlYW0gdGlzID0gbmV3IFRlc3RJbnB1dFN0cmVhbShkYXRhKTsKKyAgICAgICAgQ2lwaGVySW5wdXRTdHJlYW0gY2lzID0gbmV3IENpcGhlcklucHV0U3RyZWFtKHRpcywgbmV3IE51bGxDaXBoZXIoKSk7CisgICAgICAgIGNpcy5jbG9zZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgY2xvc2UoKSBtZXRob2Qgc2hvdWxkIGNhbGwgdGhlIGNsb3NlKCkgbWV0aG9kICIKKyAgICAgICAgICAgICAgICArICJvZiBpdHMgdW5kZXJseWluZyBpbnB1dCBzdHJlYW0uIiwgdGlzLndhc0Nsb3NlZCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBtYXJrU3VwcG9ydGVkKCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIHRoYXQgbWFyayBpcyBub3Qgc3VwcG9ydGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RNYXJrU3VwcG9ydGVkKCkgeworICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlW10gey0xMjcsIC0xMDAsIC01MCwgLTEwLCAtMSwgMCwgMSwgMTAsIDUwLCAxMjd9OworICAgICAgICBUZXN0SW5wdXRTdHJlYW0gdGlzID0gbmV3IFRlc3RJbnB1dFN0cmVhbShkYXRhKTsKKyAgICAgICAgQ2lwaGVySW5wdXRTdHJlYW0gY2lzID0gbmV3IENpcGhlcklucHV0U3RyZWFtKHRpcywgbmV3IE51bGxDaXBoZXIoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgcmV0dXJuZWQgYnkgbWFya1N1cHBvcnRlZCgpIG1ldGhvZCB2YWx1ZSAiCisgICAgICAgICAgICAgICAgKyAic2hvdWxkIGJlIGZhbHNlLiIsIGNpcy5tYXJrU3VwcG9ydGVkKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9pb19JbnB1dFN0cmVhbUxqYXZheF9jcnlwdG9fQ2lwaGVyICgpIHRocm93cworICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbiwgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJhaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbMTAwXSk7CisKKyAgICAgICAgS2V5R2VuZXJhdG9yIGtnID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKCJERVMiKTsKKyAgICAgICAga2cuaW5pdCg1NiwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAgS2V5IGtleSA9IGtnLmdlbmVyYXRlS2V5KCk7CisKKyAgICAgICAgQ2lwaGVyIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvTm9QYWRkaW5nIik7CisgICAgICAgIGMuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBrZXkpOworCisgICAgICAgIENpcGhlcklucHV0U3RyZWFtIGNpcyA9IG5ldyBDaXBoZXJJbnB1dFN0cmVhbShiYWlzLCBjKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKGNpcyk7CisgICAgfQorCit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9DaXBoZXJJbnB1dFN0cmVhbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9DaXBoZXJJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNDBjZWFjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0NpcGhlcklucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YXguY3J5cHRvLkNpcGhlcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uQ2lwaGVySW5wdXRTdHJlYW07CitpbXBvcnQgamF2YXguY3J5cHRvLk51bGxDaXBoZXI7CisKK3B1YmxpYyBjbGFzcyBDaXBoZXJJbnB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5jcnlwdG8uQ2lwaGVySW5wdXRTdHJlYW0jcmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZEJJSSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTEwODAKKyAgICAgICAgQ2lwaGVySW5wdXRTdHJlYW0gc3RyZWFtID0gbmV3IENpcGhlcklucHV0U3RyZWFtKG51bGwsIG5ldyBOdWxsQ2lwaGVyKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RyZWFtLnJlYWQobmV3IGJ5dGVbMV0sIDEsIDApOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LmNyeXB0by5DaXBoZXJJbnB1dFN0cmVhbSNjbG9zZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENsb3NlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMTA4NworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IENpcGhlcklucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVtdIHsgMSB9KSwKKyAgICAgICAgICAgICAgICAgICAgQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL1BLQ1M1UGFkZGluZyIpKS5jbG9zZSgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkISIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IENpcGhlcklucHV0U3RyZWFtKG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKChJbnB1dFN0cmVhbSkgbnVsbCksCisgICAgICAgICAgICAgICAgICAgIENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9QS0NTNVBhZGRpbmciKSkuY2xvc2UoKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCEiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9DaXBoZXJPdXRwdXRTdHJlYW0xVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0NpcGhlck91dHB1dFN0cmVhbTFUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzU5YWM2NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9DaXBoZXJPdXRwdXRTdHJlYW0xVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjA5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uS2V5R2VuZXJhdG9yOworaW1wb3J0IGphdmF4LmNyeXB0by5Ob1N1Y2hQYWRkaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmNyeXB0by5OdWxsQ2lwaGVyOworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXJPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YXguY3J5cHRvLkNpcGhlcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKi8KK3B1YmxpYyBjbGFzcyBDaXBoZXJPdXRwdXRTdHJlYW0xVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFRlc3RPdXRwdXRTdHJlYW0gZXh0ZW5kcyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0geworICAgICAgICBwcml2YXRlIGJvb2xlYW4gY2xvc2VkID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgICAgICBjbG9zZWQgPSB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gd2FzQ2xvc2VkKCkgeworICAgICAgICAgICAgcmV0dXJuIGNsb3NlZDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENpcGhlck91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3MpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGF0CisgICAgICogQ2lwaGVyT3V0cHV0U3RyZWFtIHVzZXMgTnVsbENpcGhlciBpZiBDaXBoZXIgaXMgbm90IHNwZWNpZmllZAorICAgICAqIGluIHRoZSBjb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2lwaGVyT3V0cHV0U3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbXSB7IC0xMjcsIC0xMDAsIC01MCwgLTEwLCAtMSwgMCwgMSwgMTAsIDUwLCAxMjcgfTsKKyAgICAgICAgVGVzdE91dHB1dFN0cmVhbSB0b3MgPSBuZXcgVGVzdE91dHB1dFN0cmVhbSgpOworICAgICAgICBDaXBoZXJPdXRwdXRTdHJlYW0gY29zID0gbmV3IENpcGhlck91dHB1dFN0cmVhbSh0b3Mpe307CisgICAgICAgIGNvcy53cml0ZShkYXRhKTsKKyAgICAgICAgY29zLmZsdXNoKCk7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSB0b3MudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgaWYgKCFBcnJheXMuZXF1YWxzKHJlc3VsdCwgZGF0YSkpIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGxDaXBoZXIgc2hvdWxkIGJlIHVzZWQgIiArICJpZiBDaXBoZXIgaXMgbm90IHNwZWNpZmllZC4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHdyaXRlKGludCBiKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhhdCBtZXRob2Qgd3JpdGVzIGNvcnJlY3QgdmFsdWVzIHRvCisgICAgICogdGhlIHVuZGVybHlpbmcgb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGUxKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbXSB7IC0xMjcsIC0xMDAsIC01MCwgLTEwLCAtMSwgMCwgMSwgMTAsIDUwLCAxMjcgfTsKKyAgICAgICAgVGVzdE91dHB1dFN0cmVhbSB0b3MgPSBuZXcgVGVzdE91dHB1dFN0cmVhbSgpOworICAgICAgICBDaXBoZXJPdXRwdXRTdHJlYW0gY29zID0gbmV3IENpcGhlck91dHB1dFN0cmVhbSh0b3MsIG5ldyBOdWxsQ2lwaGVyKCkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNvcy53cml0ZShkYXRhW2ldKTsKKyAgICAgICAgfQorICAgICAgICBjb3MuZmx1c2goKTsKKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IHRvcy50b0J5dGVBcnJheSgpOworICAgICAgICBpZiAoIUFycmF5cy5lcXVhbHMocmVzdWx0LCBkYXRhKSkgeworICAgICAgICAgICAgZmFpbCgiQ2lwaGVyT3V0cHV0U3RyZWFtIHdyb3RlIGluY29ycmVjdCBkYXRhLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogd3JpdGUoYnl0ZVtdIGIpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGF0IG1ldGhvZCB3cml0ZXMgY29ycmVjdCB2YWx1ZXMKKyAgICAgKiB0byB0aGUgdW5kZXJseWluZyBvdXRwdXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZTIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVtdIHsgLTEyNywgLTEwMCwgLTUwLCAtMTAsIC0xLCAwLCAxLCAxMCwgNTAsIDEyNyB9OworICAgICAgICBUZXN0T3V0cHV0U3RyZWFtIHRvcyA9IG5ldyBUZXN0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIENpcGhlck91dHB1dFN0cmVhbSBjb3MgPSBuZXcgQ2lwaGVyT3V0cHV0U3RyZWFtKHRvcywgbmV3IE51bGxDaXBoZXIoKSk7CisgICAgICAgIGNvcy53cml0ZShkYXRhKTsKKyAgICAgICAgY29zLmZsdXNoKCk7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSB0b3MudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgaWYgKCFBcnJheXMuZXF1YWxzKHJlc3VsdCwgZGF0YSkpIHsKKyAgICAgICAgICAgIGZhaWwoIkNpcGhlck91dHB1dFN0cmVhbSB3cm90ZSBpbmNvcnJlY3QgZGF0YS4iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb3Mud3JpdGUobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB3cml0ZShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgbWV0aG9kIHRlc3RpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFdyaXRlMygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlW10geyAtMTI3LCAtMTAwLCAtNTAsIC0xMCwgLTEsIDAsIDEsIDEwLCA1MCwgMTI3IH07CisgICAgICAgIFRlc3RPdXRwdXRTdHJlYW0gdG9zID0gbmV3IFRlc3RPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgQ2lwaGVyT3V0cHV0U3RyZWFtIGNvcyA9IG5ldyBDaXBoZXJPdXRwdXRTdHJlYW0odG9zLCBuZXcgTnVsbENpcGhlcigpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjb3Mud3JpdGUoZGF0YSwgaSwgMSk7CisgICAgICAgIH0KKyAgICAgICAgY29zLmZsdXNoKCk7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSB0b3MudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgaWYgKCFBcnJheXMuZXF1YWxzKHJlc3VsdCwgZGF0YSkpIHsKKyAgICAgICAgICAgIGZhaWwoIkNpcGhlck91dHB1dFN0cmVhbSB3cm90ZSBpbmNvcnJlY3QgZGF0YS4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHdyaXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZTQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy9SZWdyZXNzaW9uIGZvciBIQVJNT05ZLTc1OAorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IENpcGhlck91dHB1dFN0cmVhbShuZXcgQnVmZmVyZWRPdXRwdXRTdHJlYW0oKE91dHB1dFN0cmVhbSkgbnVsbCksIG5ldyBOdWxsQ2lwaGVyKCkpLndyaXRlKG5ldyBieXRlW10gezB9LCAxLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB3cml0ZShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0V3JpdGU1KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vUmVncmVzc2lvbiBmb3IgSEFSTU9OWS03NTgKKyAgICAgICAgQ2lwaGVyIGNmID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL1BLQ1M1UGFkZGluZyIpOworICAgICAgICBOdWxsQ2lwaGVyIG5jID0gbmV3IE51bGxDaXBoZXIoKTsKKyAgICAgICAgQ2lwaGVyT3V0cHV0U3RyZWFtIHN0cmVhbTEgPSBuZXcgQ2lwaGVyT3V0cHV0U3RyZWFtKG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbSgoT3V0cHV0U3RyZWFtKSBudWxsKSwgbmMpOworICAgICAgICBDaXBoZXJPdXRwdXRTdHJlYW0gc3RyZWFtMiA9IG5ldyBDaXBoZXJPdXRwdXRTdHJlYW0oc3RyZWFtMSwgY2YpOworICAgICAgICBDaXBoZXJPdXRwdXRTdHJlYW0gc3RyZWFtMyA9IG5ldyBDaXBoZXJPdXRwdXRTdHJlYW0oc3RyZWFtMiwgbmMpOworICAgICAgICBzdHJlYW0zLndyaXRlKG5ldyBieXRlW10gezB9LCAwLCAwKTsKKyAgICAgICAgICAgLy9ubyBleGNlcHRpb24gZXhwZWN0ZWQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBmbHVzaCgpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGF0IG1ldGhvZCBmbHVzaGVzIHRoZSBkYXRhIHRvIHRoZQorICAgICAqIHVuZGVybHlpbmcgb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rmx1c2goKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVtdIHsgLTEyNywgLTEwMCwgLTUwLCAtMTAsIC0xLCAwLCAxLCAxMCwgNTAsIDEyNyB9OworICAgICAgICBUZXN0T3V0cHV0U3RyZWFtIHRvcyA9IG5ldyBUZXN0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIENpcGhlck91dHB1dFN0cmVhbSBjb3MgPSBuZXcgQ2lwaGVyT3V0cHV0U3RyZWFtKHRvcyl7fTsKKyAgICAgICAgY29zLndyaXRlKGRhdGEpOworICAgICAgICBjb3MuZmx1c2goKTsKKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IHRvcy50b0J5dGVBcnJheSgpOworICAgICAgICBpZiAoIUFycmF5cy5lcXVhbHMocmVzdWx0LCBkYXRhKSkgeworICAgICAgICAgICAgZmFpbCgiQ2lwaGVyT3V0cHV0U3RyZWFtIGRpZCBub3QgZmx1c2ggdGhlIGRhdGEuIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBjbG9zZSgpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGF0IHRoZSBtZXRob2QgY2FsbHMgdGhlIGNsb3NlKCkgbWV0aG9kIG9mCisgICAgICogdGhlIHVuZGVybHlpbmcgaW5wdXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDbG9zZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlW10geyAtMTI3LCAtMTAwLCAtNTAsIC0xMCwgLTEsIDAsIDEsIDEwLCA1MCwgMTI3IH07CisgICAgICAgIFRlc3RPdXRwdXRTdHJlYW0gdG9zID0gbmV3IFRlc3RPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgQ2lwaGVyT3V0cHV0U3RyZWFtIGNvcyA9IG5ldyBDaXBoZXJPdXRwdXRTdHJlYW0odG9zKXt9OworICAgICAgICBjb3Mud3JpdGUoZGF0YSk7CisgICAgICAgIGNvcy5jbG9zZSgpOworICAgICAgICBieXRlW10gcmVzdWx0ID0gdG9zLnRvQnl0ZUFycmF5KCk7CisgICAgICAgIGlmICghQXJyYXlzLmVxdWFscyhyZXN1bHQsIGRhdGEpKSB7CisgICAgICAgICAgICBmYWlsKCJDaXBoZXJPdXRwdXRTdHJlYW0gZGlkIG5vdCBmbHVzaCB0aGUgZGF0YS4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgY2xvc2UoKSBtZXRob2Qgc2hvdWxkIGNhbGwgdGhlIGNsb3NlKCkgbWV0aG9kICIKKyAgICAgICAgICAgICAgICArICJvZiBpdHMgdW5kZXJseWluZyBvdXRwdXQgc3RyZWFtLiIsIHRvcy53YXNDbG9zZWQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX091dHB1dFN0cmVhbUxqYXZheF9jcnlwdG9fQ2lwaGVyKCkgdGhyb3dzCisgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQYWRkaW5nRXhjZXB0aW9uLCBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisKKyAgICAgICAgS2V5R2VuZXJhdG9yIGtnID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKCJERVMiKTsKKyAgICAgICAga2cuaW5pdCg1NiwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAgS2V5IGtleSA9IGtnLmdlbmVyYXRlS2V5KCk7CisKKyAgICAgICAgQ2lwaGVyIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvTm9QYWRkaW5nIik7CisgICAgICAgIGMuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBrZXkpOworCisgICAgICAgIENpcGhlck91dHB1dFN0cmVhbSBjb3MgPSBuZXcgQ2lwaGVyT3V0cHV0U3RyZWFtKGJhb3MsIGMpOworCisgICAgICAgIGFzc2VydE5vdE51bGwoY29zKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9DaXBoZXJPdXRwdXRTdHJlYW1UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vQ2lwaGVyT3V0cHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyOWZjMWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vQ2lwaGVyT3V0cHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uQ2lwaGVyOworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXJPdXRwdXRTdHJlYW07CisKK3B1YmxpYyBjbGFzcyBDaXBoZXJPdXRwdXRTdHJlYW1UZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmF4LmNyeXB0by5DaXBoZXJPdXRwdXRTdHJlYW0jY2xvc2UoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gcmVncmVzc2lvbiB0ZXN0IGZvciBIQVJNT05ZLTExMzkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBDaXBoZXJPdXRwdXRTdHJlYW0oKE91dHB1dFN0cmVhbSkgbnVsbCwgQ2lwaGVyCisgICAgICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZSgiREVTL0NCQy9QS0NTNVBhZGRpbmciKSkuY2xvc2UoKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIENpcGhlck91dHB1dFN0cmVhbSBjaCA9IG5ldyBDaXBoZXJPdXRwdXRTdHJlYW0oKE91dHB1dFN0cmVhbSkgbnVsbCkge307CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgQ2lwaGVyT3V0cHV0U3RyZWFtKGNoLCBDaXBoZXIKKyAgICAgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKCJERVMvQ0JDL1BLQ1M1UGFkZGluZyIpKS5jbG9zZSgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0NpcGhlclNwaVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9DaXBoZXJTcGlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTI0MGY2ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9DaXBoZXJTcGlUZXN0LmphdmEKQEAgLTAsMCArMSw0MTQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0bzsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzOworaW1wb3J0IGphdmF4LmNyeXB0by5CYWRQYWRkaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmNyeXB0by5JbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmNyeXB0by5Ob1N1Y2hQYWRkaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmNyeXB0by5TaG9ydEJ1ZmZlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uQ2lwaGVyU3BpOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+Q2lwaGVyU3BpPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgQ2lwaGVyU3BpVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBjbGFzcyBNb2NrX0NpcGhlclNwaSBleHRlbmRzIG15Q2lwaGVyU3BpIHsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVEb0ZpbmFsKGJ5dGVbXSBpbnB1dCwgaW50IGlucHV0T2Zmc2V0LCBpbnQgaW5wdXRMZW4pCisgICAgICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24sIEJhZFBhZGRpbmdFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVuZ2luZURvRmluYWwoaW5wdXQsIGlucHV0T2Zmc2V0LCBpbnB1dExlbik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGludCBlbmdpbmVEb0ZpbmFsKGJ5dGVbXSBpbnB1dCwgaW50IGlucHV0T2Zmc2V0LCBpbnQgaW5wdXRMZW4sIGJ5dGVbXSBvdXRwdXQsCisgICAgICAgICAgICAgICAgaW50IG91dHB1dE9mZnNldCkgdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uLCBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIEJhZFBhZGRpbmdFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVuZ2luZURvRmluYWwoaW5wdXQsIGlucHV0T2Zmc2V0LCBpbnB1dExlbiwgb3V0cHV0LCBvdXRwdXRPZmZzZXQpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBpbnQgZW5naW5lR2V0QmxvY2tTaXplKCkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVuZ2luZUdldEJsb2NrU2l6ZSgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBieXRlW10gZW5naW5lR2V0SVYoKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZW5naW5lR2V0SVYoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgaW50IGVuZ2luZUdldE91dHB1dFNpemUoaW50IGlucHV0TGVuKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZW5naW5lR2V0T3V0cHV0U2l6ZShpbnB1dExlbik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIEFsZ29yaXRobVBhcmFtZXRlcnMgZW5naW5lR2V0UGFyYW1ldGVycygpIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5lbmdpbmVHZXRQYXJhbWV0ZXJzKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChpbnQgb3Btb2RlLCBLZXkga2V5LCBTZWN1cmVSYW5kb20gcmFuZG9tKQorICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyLmVuZ2luZUluaXQob3Btb2RlLCBrZXksIHJhbmRvbSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChpbnQgb3Btb2RlLCBLZXkga2V5LCBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtcywKKyAgICAgICAgICAgICAgICBTZWN1cmVSYW5kb20gcmFuZG9tKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlci5lbmdpbmVJbml0KG9wbW9kZSwga2V5LCBwYXJhbXMsIHJhbmRvbSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChpbnQgb3Btb2RlLCBLZXkga2V5LCBBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtcywKKyAgICAgICAgICAgICAgICBTZWN1cmVSYW5kb20gcmFuZG9tKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlci5lbmdpbmVJbml0KG9wbW9kZSwga2V5LCBwYXJhbXMsIHJhbmRvbSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lU2V0TW9kZShTdHJpbmcgbW9kZSkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlci5lbmdpbmVTZXRNb2RlKG1vZGUpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVNldFBhZGRpbmcoU3RyaW5nIHBhZGRpbmcpIHRocm93cyBOb1N1Y2hQYWRkaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyLmVuZ2luZVNldFBhZGRpbmcocGFkZGluZyk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVVcGRhdGUoYnl0ZVtdIGlucHV0LCBpbnQgaW5wdXRPZmZzZXQsIGludCBpbnB1dExlbikgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVuZ2luZVVwZGF0ZShpbnB1dCwgaW5wdXRPZmZzZXQsIGlucHV0TGVuKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgaW50IGVuZ2luZVVwZGF0ZShieXRlW10gaW5wdXQsIGludCBpbnB1dE9mZnNldCwgaW50IGlucHV0TGVuLCBieXRlW10gb3V0cHV0LAorICAgICAgICAgICAgICAgIGludCBvdXRwdXRPZmZzZXQpIHRocm93cyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZW5naW5lVXBkYXRlKGlucHV0LCBpbnB1dE9mZnNldCwgaW5wdXRMZW4sIG91dHB1dCwgb3V0cHV0T2Zmc2V0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgaW50IGVuZ2luZUdldEtleVNpemUoS2V5IGtleSkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVuZ2luZUdldEtleVNpemUoa2V5KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuZ2luZVdyYXAoS2V5IGtleSkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24sIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVuZ2luZVdyYXAoa2V5KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgS2V5IGVuZ2luZVVud3JhcChieXRlW10gd3JhcHBlZEtleSwgU3RyaW5nIHdyYXBwZWRLZXlBbGdvcml0aG0sIGludCB3cmFwcGVkS2V5VHlwZSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5lbmdpbmVVbndyYXAod3JhcHBlZEtleSwgd3JhcHBlZEtleUFsZ29yaXRobSwgd3JhcHBlZEtleVR5cGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2lwaGVyU3BpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDaXBoZXJTcGkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2lwaGVyU3BpVGVzdHMwMSgpIHRocm93cyBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uLAorICAgICAgICAgICAgQmFkUGFkZGluZ0V4Y2VwdGlvbiwgU2hvcnRCdWZmZXJFeGNlcHRpb24geworCisgICAgICAgIE1vY2tfQ2lwaGVyU3BpIGNTcGkgPSBuZXcgTW9ja19DaXBoZXJTcGkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCbG9ja1NpemUgaXMgbm90IDAiLCBjU3BpLmVuZ2luZUdldEJsb2NrU2l6ZSgpLCAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJPdXRwdXRTaXplIGlzIG5vdCAwIiwgY1NwaS5lbmdpbmVHZXRPdXRwdXRTaXplKDEpLCAwKTsKKyAgICAgICAgYnl0ZVtdIGJiID0gY1NwaS5lbmdpbmVHZXRJVigpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkxlbmd0aCBvZiByZXN1bHQgYnl0ZSBhcnJheSBpcyBub3QgMCIsIGJiLmxlbmd0aCwgMCk7CisgICAgICAgIGFzc2VydE51bGwoIk5vdCBudWxsIHJlc3VsdCIsIGNTcGkuZW5naW5lR2V0UGFyYW1ldGVycygpKTsKKyAgICAgICAgYnl0ZVtdIGJiMSA9IG5ldyBieXRlWzEwXTsKKyAgICAgICAgYnl0ZVtdIGJiMiA9IG5ldyBieXRlWzEwXTsKKyAgICAgICAgYmIgPSBjU3BpLmVuZ2luZVVwZGF0ZShiYjEsIDEsIDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCByZXN1bHQgb2YgZW5naW5lVXBkYXRlKGJ5dGUsIGludCwgaW50KSIsCisgICAgICAgICAgICAgICAgYmIubGVuZ3RoLCAyKTsKKyAgICAgICAgYmIgPSBjU3BpLmVuZ2luZURvRmluYWwoYmIxLCAxLCAyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcmVzdWx0IG9mIGVuZ2luZURvRmluYWwoYnl0ZSwgaW50LCBpbnQpIiwgMiwKKyAgICAgICAgICAgICAgICBiYi5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgIkluY29ycmVjdCByZXN1bHQgb2YgZW5naW5lVXBkYXRlKGJ5dGUsIGludCwgaW50LCBieXRlLCBpbnQpIiwKKyAgICAgICAgICAgICAgICBjU3BpLmVuZ2luZVVwZGF0ZShiYjEsIDEsIDIsIGJiMiwgNyksIDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgIkluY29ycmVjdCByZXN1bHQgb2YgZW5naW5lRG9GaW5hbChieXRlLCBpbnQsIGludCwgYnl0ZSwgaW50KSIsCisgICAgICAgICAgICAgICAgMiwgY1NwaS5lbmdpbmVEb0ZpbmFsKGJiMSwgMSwgMiwgYmIyLCAwKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+ZW5naW5lR2V0S2V5U2l6ZShLZXkpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IEl0IHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiBpdCBpcyBub3Qgb3ZlcnJpZGRlbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDaXBoZXJTcGkwMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNb2NrX0NpcGhlclNwaSBjU3BpID0gbmV3IE1vY2tfQ2lwaGVyU3BpKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjU3BpLmVuZ2luZUdldEtleVNpemUobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5lbmdpbmVXcmFwKEtleSk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogSXQgdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIGl0IGlzIG5vdCBvdmVycmlkZGVuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENpcGhlclNwaTAzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1vY2tfQ2lwaGVyU3BpIGNTcGkgPSBuZXcgTW9ja19DaXBoZXJTcGkoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNTcGkuZW5naW5lV3JhcChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmVuZ2luZVVud3JhcChieXRlW10sIFN0cmluZywgaW50KTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiBJdCB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgaXQgaXMgbm90IG92ZXJyaWRkZW4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2lwaGVyU3BpMDQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja19DaXBoZXJTcGkgY1NwaSA9IG5ldyBNb2NrX0NpcGhlclNwaSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY1NwaS5lbmdpbmVVbndyYXAobmV3IGJ5dGVbMF0sICIiLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmVuZ2luZVVwZGF0ZShCeXRlQnVmZmVyLCBCeXRlQnVmZmVyKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uczoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgb25lIG9mIHRoZXNlIGJ1ZmZlcnMgaXMgbnVsbDsKKyAgICAgKiB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24gaXMgdGhlcmUgaXMgbm8gc3BhY2UgaW4gb3V0cHV0IHRvIGhvbGQgcmVzdWx0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENpcGhlclNwaTA1KCkgdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja19DaXBoZXJTcGkgY1NwaSA9IG5ldyBNb2NrX0NpcGhlclNwaSgpOworICAgICAgICBieXRlW10gYmIgPSB7IChieXRlKSAwLCAoYnl0ZSkgMSwgKGJ5dGUpIDIsIChieXRlKSAzLCAoYnl0ZSkgNCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgNSwgKGJ5dGUpIDYsIChieXRlKSA3LCAoYnl0ZSkgOCwgKGJ5dGUpIDksIChieXRlKSAxMCB9OworICAgICAgICBpbnQgcG9zID0gNTsKKyAgICAgICAgaW50IGxlbiA9IGJiLmxlbmd0aDsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYk51bGwgPSBudWxsOworICAgICAgICBCeXRlQnVmZmVyIGJiMSA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUobGVuKTsKKyAgICAgICAgYmIxLnB1dChiYik7CisgICAgICAgIGJiMS5wb3NpdGlvbigwKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNTcGkuZW5naW5lVXBkYXRlKGJiTnVsbCwgYmIxKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY1NwaS5lbmdpbmVVcGRhdGUoYmIxLCBiYk51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIEJ5dGVCdWZmZXIgYmIyID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShiYi5sZW5ndGgpOworICAgICAgICBiYjEucG9zaXRpb24obGVuKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbnVtYmVyIG9mIHN0b3JlZCBieXRlcyIsIDAsIGNTcGkuZW5naW5lVXBkYXRlKAorICAgICAgICAgICAgICAgIGJiMSwgYmIyKSk7CisKKyAgICAgICAgYmIxLnBvc2l0aW9uKDApOworICAgICAgICBiYjIucG9zaXRpb24obGVuIC0gMik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjU3BpLmVuZ2luZVVwZGF0ZShiYjEsIGJiMik7CisgICAgICAgICAgICBmYWlsKCJTaG9ydEJ1ZmZlckV4Y2VwdGlvbiBidXN0IGJlIHRocm93bi4gT3V0cHV0IGJ1ZmZlciByZW1haW5pbmc6ICIKKyAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChJbnRlZ2VyLnRvU3RyaW5nKGJiMi5yZW1haW5pbmcoKSkpKTsKKyAgICAgICAgfSBjYXRjaCAoU2hvcnRCdWZmZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGJiMS5wb3NpdGlvbigxMCk7CisgICAgICAgIGJiMi5wb3NpdGlvbigwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG51bWJlciBvZiBzdG9yZWQgYnl0ZXMiLCBjU3BpLmVuZ2luZVVwZGF0ZShiYjEsCisgICAgICAgICAgICAgICAgYmIyKSA+IDApOworICAgICAgICBiYjEucG9zaXRpb24oYmIubGVuZ3RoKTsKKyAgICAgICAgY1NwaS5lbmdpbmVVcGRhdGUoYmIxLCBiYjIpOworCisgICAgICAgIGJiMS5wb3NpdGlvbihwb3MpOworICAgICAgICBiYjIucG9zaXRpb24oMCk7CisgICAgICAgIGludCByZXMgPSBjU3BpLmVuZ2luZVVwZGF0ZShiYjEsIGJiMik7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCByZXN1bHQiLCByZXMgPiAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5lbmdpbmVEb0ZpbmFsKEJ5dGVCdWZmZXIsIEJ5dGVCdWZmZXIpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb25zOgorICAgICAqIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBvbmUgb2YgdGhlc2UgYnVmZmVycyBpcyBudWxsOworICAgICAqIHRocm93cyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbiBpcyB0aGVyZSBpcyBubyBzcGFjZSBpbiBvdXRwdXQgdG8gaG9sZCByZXN1bHQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2lwaGVyU3BpMDYoKSB0aHJvd3MgQmFkUGFkZGluZ0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIFNob3J0QnVmZmVyRXhjZXB0aW9uLCBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja19DaXBoZXJTcGkgY1NwaSA9IG5ldyBNb2NrX0NpcGhlclNwaSgpOworICAgICAgICBpbnQgbGVuID0gMTA7CisgICAgICAgIGJ5dGVbXSBiYnVmID0gbmV3IGJ5dGVbbGVuXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBiYnVmLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBiYnVmW2ldID0gKGJ5dGUpIGk7CisgICAgICAgIH0KKyAgICAgICAgQnl0ZUJ1ZmZlciBiYjEgPSBCeXRlQnVmZmVyLndyYXAoYmJ1Zik7CisgICAgICAgIEJ5dGVCdWZmZXIgYmJOdWxsID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNTcGkuZW5naW5lRG9GaW5hbChiYk51bGwsIGJiMSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNTcGkuZW5naW5lRG9GaW5hbChiYjEsIGJiTnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgQnl0ZUJ1ZmZlciBiYjIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKGxlbik7CisgICAgICAgIGJiMS5wb3NpdGlvbihiYjEubGltaXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHJlc3VsdCIsIDAsIGNTcGkuZW5naW5lRG9GaW5hbChiYjEsIGJiMikpOworCisgICAgICAgIGJiMS5wb3NpdGlvbigwKTsKKyAgICAgICAgYmIyLnBvc2l0aW9uKGxlbiAtIDIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY1NwaS5lbmdpbmVEb0ZpbmFsKGJiMSwgYmIyKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3J0QnVmZmVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duLiBPdXRwdXQgYnVmZmVyIHJlbWFpbmluZzogIgorICAgICAgICAgICAgICAgICAgICAuY29uY2F0KEludGVnZXIudG9TdHJpbmcoYmIyLnJlbWFpbmluZygpKSkpOworICAgICAgICB9IGNhdGNoIChTaG9ydEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgaW50IHBvcyA9IDU7CisgICAgICAgIGJiMS5wb3NpdGlvbihwb3MpOworICAgICAgICBiYjIucG9zaXRpb24oMCk7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCByZXN1bHQiLCBjU3BpLmVuZ2luZURvRmluYWwoYmIxLCBiYjIpID4gMCk7CisgICAgfQorfQorLyoqCisgKgorICogQWRkaXRpb25hbCBjbGFzcyBmb3IgQ2lwaGVyR2VuZXJhdG9yU3BpIGNvbnN0cnVjdG9yIHZlcmlmaWNhdGlvbgorICovCisKK2NsYXNzIG15Q2lwaGVyU3BpIGV4dGVuZHMgQ2lwaGVyU3BpIHsKKyAgICBwcml2YXRlIGJ5dGVbXSBpbml0VjsKKworICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSByZXNWID0geyAoYnl0ZSkgNywgKGJ5dGUpIDYsIChieXRlKSA1LCAoYnl0ZSkgNCwKKyAgICAgICAgICAgIChieXRlKSAzLCAoYnl0ZSkgMiwgKGJ5dGUpIDEsIChieXRlKSAwIH07CisKKyAgICBwdWJsaWMgbXlDaXBoZXJTcGkoKSB7CisgICAgICAgIHRoaXMuaW5pdFYgPSBuZXcgYnl0ZVswXTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVTZXRNb2RlKFN0cmluZyBtb2RlKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVTZXRQYWRkaW5nKFN0cmluZyBwYWRkaW5nKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaFBhZGRpbmdFeGNlcHRpb24geworICAgIH0KKworICAgIHByb3RlY3RlZCBpbnQgZW5naW5lR2V0QmxvY2tTaXplKCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgaW50IGVuZ2luZUdldE91dHB1dFNpemUoaW50IGlucHV0TGVuKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHByb3RlY3RlZCBieXRlW10gZW5naW5lR2V0SVYoKSB7CisgICAgICAgIHJldHVybiBuZXcgYnl0ZVswXTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgQWxnb3JpdGhtUGFyYW1ldGVycyBlbmdpbmVHZXRQYXJhbWV0ZXJzKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0KGludCBvcG1vZGUsIEtleSBrZXksIFNlY3VyZVJhbmRvbSByYW5kb20pCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChpbnQgb3Btb2RlLCBLZXkga2V5LAorICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMsIFNlY3VyZVJhbmRvbSByYW5kb20pCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChpbnQgb3Btb2RlLCBLZXkga2V5LCBBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtcywKKyAgICAgICAgICAgIFNlY3VyZVJhbmRvbSByYW5kb20pIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVVcGRhdGUoYnl0ZVtdIGlucHV0LCBpbnQgaW5wdXRPZmZzZXQsIGludCBpbnB1dExlbikgeworICAgICAgICBpZiAoaW5pdFYubGVuZ3RoIDwgaW5wdXRMZW4pIHsKKyAgICAgICAgICAgIGluaXRWID0gbmV3IGJ5dGVbaW5wdXRMZW5dOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5wdXRMZW47IGkrKykgeworICAgICAgICAgICAgaW5pdFZbaV0gPSBpbnB1dFtpbnB1dE9mZnNldCArIGldOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpbml0VjsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgaW50IGVuZ2luZVVwZGF0ZShieXRlW10gaW5wdXQsIGludCBpbnB1dE9mZnNldCwgaW50IGlucHV0TGVuLAorICAgICAgICAgICAgYnl0ZVtdIG91dHB1dCwgaW50IG91dHB1dE9mZnNldCkgdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZSBbXXJlcyA9IGVuZ2luZVVwZGF0ZShpbnB1dCwgaW5wdXRPZmZzZXQsIGlucHV0TGVuKTsKKyAgICAgICAgaW50IHQgPSByZXMubGVuZ3RoOworICAgICAgICBpZiAoKG91dHB1dC5sZW5ndGggLSBvdXRwdXRPZmZzZXQpIDwgdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNob3J0QnVmZmVyRXhjZXB0aW9uKCJVcGRhdGUiKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHQ7IGkrKykgeworICAgICAgICAgICAgb3V0cHV0W2kgKyBvdXRwdXRPZmZzZXRdID0gaW5pdFZbaV07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHQ7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVEb0ZpbmFsKGJ5dGVbXSBpbnB1dCwgaW50IGlucHV0T2Zmc2V0LCBpbnQgaW5wdXRMZW4pCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiwgQmFkUGFkZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChyZXNWLmxlbmd0aCA+IGlucHV0TGVuKSB7CisgICAgICAgICAgICBieXRlW10gYmIgPSBuZXcgYnl0ZVtpbnB1dExlbl07CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGlucHV0TGVuOyBpKyspIHsKKyAgICAgICAgICAgICAgICBiYltpXSA9IHJlc1ZbaV07CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gYmI7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc1Y7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGludCBlbmdpbmVEb0ZpbmFsKGJ5dGVbXSBpbnB1dCwgaW50IGlucHV0T2Zmc2V0LCBpbnQgaW5wdXRMZW4sCisgICAgICAgICAgICBieXRlW10gb3V0cHV0LCBpbnQgb3V0cHV0T2Zmc2V0KSB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uLCBCYWRQYWRkaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIHJlcyA9IGVuZ2luZURvRmluYWwoaW5wdXQsIGlucHV0T2Zmc2V0LCBpbnB1dExlbik7CisKKyAgICAgICAgaW50IHQgPSByZXMubGVuZ3RoOworICAgICAgICBpZiAoKG91dHB1dC5sZW5ndGggLSBvdXRwdXRPZmZzZXQpIDwgdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNob3J0QnVmZmVyRXhjZXB0aW9uKCJEb0ZpbmFsIik7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0OyBpKyspIHsKKyAgICAgICAgICAgIG91dHB1dFtpICsgb3V0cHV0T2Zmc2V0XSA9IHJlc1tpXTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdDsKKyAgICB9CisKKworICAgIHByb3RlY3RlZCBpbnQgZW5naW5lVXBkYXRlKEJ5dGVCdWZmZXIgaW5wdXQsIEJ5dGVCdWZmZXIgb3V0cHV0KQorICAgIHRocm93cyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzdXBlci5lbmdpbmVVcGRhdGUoaW5wdXQsIG91dHB1dCk7CisgICAgfQorICAgIHByb3RlY3RlZCBpbnQgZW5naW5lRG9GaW5hbChCeXRlQnVmZmVyIGlucHV0LCBCeXRlQnVmZmVyIG91dHB1dCkKKyAgICB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24sIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24sCisgICAgQmFkUGFkZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzdXBlci5lbmdpbmVEb0ZpbmFsKGlucHV0LCBvdXRwdXQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9DaXBoZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vQ2lwaGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA1MDcxNDcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vQ2lwaGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTIxMyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5SZWFkT25seUJ1ZmZlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLlJTQUtleUdlblBhcmFtZXRlclNwZWM7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZheC5jcnlwdG8uQmFkUGFkZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uQ2lwaGVyOworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXJTcGk7CitpbXBvcnQgamF2YXguY3J5cHRvLklsbGVnYWxCbG9ja1NpemVFeGNlcHRpb247CitpbXBvcnQgamF2YXguY3J5cHRvLktleUdlbmVyYXRvcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2VjcmV0S2V5RmFjdG9yeTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2hvcnRCdWZmZXJFeGNlcHRpb247CitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuREVTZWRlS2V5U3BlYzsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5JdlBhcmFtZXRlclNwZWM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5zdXBwb3J0Lk15Q2lwaGVyOworaW1wb3J0IHRlc3RzLnN1cHBvcnQucmVzb3VyY2UuU3VwcG9ydF9SZXNvdXJjZXM7CisKK3B1YmxpYyBjbGFzcyBDaXBoZXJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBLZXkgY2lwaGVyS2V5OworICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgYWxnb3JpdGhtID0gIkRFU2VkZSI7CisgICAgc3RhdGljIGZpbmFsIGludCBrZXlMZW4gPSAxNjg7CisKKyAgICBzdGF0aWMgS2V5IGNpcGhlcktleURFUzsKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIGFsZ29yaXRobURFUyA9ICJERVMiOworICAgIHN0YXRpYyBmaW5hbCBpbnQga2V5TGVuREVTID0gNTY7CisKKyAgICBzdGF0aWMgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5R2VuZXJhdG9yIGtnID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgICAgICBrZy5pbml0KGtleUxlbiwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAgICAgIGNpcGhlcktleSA9IGtnLmdlbmVyYXRlS2V5KCk7CisKKyAgICAgICAgICAgIGtnID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKGFsZ29yaXRobURFUyk7CisgICAgICAgICAgICBrZy5pbml0KGtleUxlbkRFUywgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAgICAgIGNpcGhlcktleURFUyA9IGtnLmdlbmVyYXRlS2V5KCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJObyBrZXkgIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXguY3J5cHRvLkNpcGhlciNnZXRJbnN0YW5jZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaXBoZXIgY2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVNlZGUvQ0JDL1BLQ1M1UGFkZGluZyIpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJSZWNlaXZlZCBhIG51bGwgQ2lwaGVyIGluc3RhbmNlIiwgY2lwaGVyKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2lwaGVyLmdldEluc3RhbmNlKCJXcm9uZ0FsZ29yaXRobU5hbWUiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5jcnlwdG8uQ2lwaGVyI2dldEluc3RhbmNlKGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgICAgIGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcoKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgUHJvdmlkZXJbXSBwcm92aWRlcnMgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoIkNpcGhlci5ERVMiKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKCJObyBpbnN0YWxsZWQgcHJvdmlkZXJzIHN1cHBvcnQgQ2lwaGVyLkRFUyIsIHByb3ZpZGVycyk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcm92aWRlcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIENpcGhlciBjaXBoZXIgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUyIsIHByb3ZpZGVyc1tpXS5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ2lwaGVyLmdldEluc3RhbmNlKCkgcmV0dXJuZWQgYSBudWxsIHZhbHVlIiwgY2lwaGVyKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjaXBoZXIgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRvQmVEb0JlRG8iLCBwcm92aWRlcnNbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENpcGhlci5nZXRJbnN0YW5jZSgiREVTIiwgKFN0cmluZykgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENpcGhlci5nZXRJbnN0YW5jZSgiREVTIiwgIklIYXZlTm90QmVlbkNvbmZpZ3VyZWQiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LmNyeXB0by5DaXBoZXIjZ2V0SW5zdGFuY2UoamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS5zZWN1cml0eS5Qcm92aWRlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmdMamF2YV9zZWN1cml0eV9Qcm92aWRlcigpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIFByb3ZpZGVyW10gcHJvdmlkZXJzID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKCJDaXBoZXIuREVTIik7CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTm8gaW5zdGFsbGVkIHByb3ZpZGVycyBzdXBwb3J0IENpcGhlci5ERVMiLCBwcm92aWRlcnMpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdmlkZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBDaXBoZXIgY2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMiLCBwcm92aWRlcnNbaV0pOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ2lwaGVyLmdldEluc3RhbmNlKCkgcmV0dXJuZWQgYSBudWxsIHZhbHVlIiwgY2lwaGVyKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUyIsIChQcm92aWRlcikgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENpcGhlci5nZXRJbnN0YW5jZSgiV3JvbmdBbGciLCBwcm92aWRlcnNbMF0pOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LmNyeXB0by5DaXBoZXIjZ2V0UHJvdmlkZXIoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UHJvdmlkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBQcm92aWRlcltdIHByb3ZpZGVycyA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygiQ2lwaGVyLkFFUyIpOworCisgICAgICAgIGFzc2VydE5vdE51bGwoIk5vIHByb3ZpZGVycyBzdXBwb3J0IENpcGhlci5BRVMiLCBwcm92aWRlcnMpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdmlkZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBQcm92aWRlciBwcm92aWRlciA9IHByb3ZpZGVyc1tpXTsKKyAgICAgICAgICAgIENpcGhlciBjaXBoZXIgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkFFUyIsIHByb3ZpZGVyLmdldE5hbWUoKSk7CisgICAgICAgICAgICBQcm92aWRlciBjaXBoZXJQcm92aWRlciA9IGNpcGhlci5nZXRQcm92aWRlcigpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2lwaGVyIHByb3ZpZGVyIGlzIG5vdCB0aGUgc2FtZSBhcyB0aGF0ICIKKyAgICAgICAgICAgICAgICAgICAgKyAicHJvdmlkZWQgYXMgcGFyYW1ldGVyIHRvIGdldEluc3RhbmNlKCkiLCBjaXBoZXJQcm92aWRlcgorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKHByb3ZpZGVyKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5jcnlwdG8uQ2lwaGVyI2dldEFsZ29yaXRobSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBbGdvcml0aG0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGFsZ29yaXRobSA9ICJERVNlZGUvQ0JDL1BLQ1M1UGFkZGluZyI7CisKKyAgICAgICAgQ2lwaGVyIGNpcGhlciA9IENpcGhlci5nZXRJbnN0YW5jZShhbGdvcml0aG0pOworICAgICAgICBhc3NlcnRUcnVlKCJDaXBoZXIgYWxnb3JpdGhtIGRvZXMgbm90IG1hdGNoIiwgY2lwaGVyLmdldEFsZ29yaXRobSgpCisgICAgICAgICAgICAgICAgLmVxdWFscyhhbGdvcml0aG0pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5jcnlwdG8uQ2lwaGVyI2dldEJsb2NrU2l6ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRCbG9ja1NpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGFsZ29yaXRobSA9ICJERVNlZGUvQ0JDL1BLQ1M1UGFkZGluZyI7CisKKyAgICAgICAgQ2lwaGVyIGNpcGhlciA9IENpcGhlci5nZXRJbnN0YW5jZShhbGdvcml0aG0pOworICAgICAgICBhc3NlcnRFcXVhbHMoIkJsb2NrIHNpemUgZG9lcyBub3QgbWF0Y2giLCA4LCBjaXBoZXIuZ2V0QmxvY2tTaXplKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LmNyeXB0by5DaXBoZXIjZ2V0T3V0cHV0U2l6ZShpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRPdXRwdXRTaXplSSgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIFNlY3VyZVJhbmRvbSBzciA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgQ2lwaGVyIGNpcGhlciA9IENpcGhlci5nZXRJbnN0YW5jZShhbGdvcml0aG0gKyAiL0VDQi9QS0NTNVBhZGRpbmciKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2lwaGVyLmdldE91dHB1dFNpemUoMjUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGNpcGhlci5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNpcGhlcktleSwgc3IpOworCisgICAgICAgIC8vIEEgMjUtYnl0ZSBpbnB1dCBjb3VsZCByZXN1bHQgaW4gYXQgbGVhc3QgNCA4LWJ5dGUgYmxvY2tzCisgICAgICAgIGludCByZXN1bHQgPSBjaXBoZXIuZ2V0T3V0cHV0U2l6ZSgyNSk7CisgICAgICAgIGFzc2VydFRydWUoIk91dHB1dCBzaXplIHRvbyBzbWFsbCIsIHJlc3VsdCA+IDMxKTsKKworICAgICAgICAvLyBBIDgtYnl0ZSBpbnB1dCBzaG91bGQgcmVzdWx0IGluIDIgOC1ieXRlIGJsb2NrcworICAgICAgICByZXN1bHQgPSBjaXBoZXIuZ2V0T3V0cHV0U2l6ZSg4KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiT3V0cHV0IHNpemUgdG9vIHNtYWxsIiwgcmVzdWx0ID4gMTUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LmNyeXB0by5DaXBoZXIjaW5pdChpbnQsIGphdmEuc2VjdXJpdHkuS2V5KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5pdFdpdGhLZXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2lwaGVyIGNpcGhlciA9IENpcGhlci5nZXRJbnN0YW5jZShhbGdvcml0aG0gKyAiL0VDQi9QS0NTNVBhZGRpbmciKTsKKyAgICAgICAgY2lwaGVyLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2lwaGVyS2V5KTsKKworCisgICAgICAgIGNpcGhlciA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9Ob1BhZGRpbmciKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNpcGhlci5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNpcGhlcktleSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LmNyeXB0by5DaXBoZXIjaW5pdChpbnQsIGphdmEuc2VjdXJpdHkuS2V5LAorICAgICAqICAgICAgICBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luaXRXaXRoU2VjdXJlUmFuZG9tKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNlY3VyZVJhbmRvbSBzciA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgQ2lwaGVyIGNpcGhlciA9IENpcGhlci5nZXRJbnN0YW5jZShhbGdvcml0aG0gKyAiL0VDQi9QS0NTNVBhZGRpbmciKTsKKyAgICAgICAgY2lwaGVyLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2lwaGVyS2V5LCBzcik7CisKKyAgICAgICAgY2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL05vUGFkZGluZyIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2lwaGVyLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2lwaGVyS2V5LCBzcik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LmNyeXB0by5DaXBoZXIjaW5pdChpbnQsIGphdmEuc2VjdXJpdHkuS2V5LAorICAgICAqICAgICAgICBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luaXRXaXRoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTZWN1cmVSYW5kb20gc3IgPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIENpcGhlciBjaXBoZXIgPSBudWxsOworCisgICAgICAgIGJ5dGVbXSBpdiA9IG51bGw7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgYXAgPSBudWxsOworCisgICAgICAgIGl2ID0gbmV3IGJ5dGVbOF07CisgICAgICAgIHNyLm5leHRCeXRlcyhpdik7CisgICAgICAgIGFwID0gbmV3IEl2UGFyYW1ldGVyU3BlYyhpdik7CisKKyAgICAgICAgY2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKGFsZ29yaXRobSArICIvQ0JDL1BLQ1M1UGFkZGluZyIpOworCisgICAgICAgIGNpcGhlci5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNpcGhlcktleSwgYXApOworCisgICAgICAgIGJ5dGVbXSBjaXBoZXJJViA9IGNpcGhlci5nZXRJVigpOworCisgICAgICAgIGFzc2VydFRydWUoIklWcyBkaWZmZXIiLCBBcnJheXMuZXF1YWxzKGNpcGhlcklWLCBpdikpOworCisgICAgICAgIGNpcGhlciA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9Ob1BhZGRpbmciKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNpcGhlci5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNpcGhlcktleSwgYXApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBjaXBoZXIgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvTm9QYWRkaW5nIik7CisgICAgICAgIGFwID0gbmV3IFJTQUtleUdlblBhcmFtZXRlclNwZWMoMTAsIG5ldyBCaWdJbnRlZ2VyKCIxMCIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2lwaGVyLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2lwaGVyS2V5REVTLCBhcCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LmNyeXB0by5DaXBoZXIjaW5pdChpbnQsIGphdmEuc2VjdXJpdHkuS2V5LAorICAgICAqICAgICAgICBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYywKKyAgICAgKiAgICAgICAgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb20pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pbml0V2l0aEtleUFsZ29yaXRobVBhcmFtZXRlclNwZWNTZWN1cmVSYW5kb20oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2VjdXJlUmFuZG9tIHNyID0gbmV3IFNlY3VyZVJhbmRvbSgpOworICAgICAgICBDaXBoZXIgY2lwaGVyID0gbnVsbDsKKworICAgICAgICBieXRlW10gaXYgPSBudWxsOworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIGFwID0gbnVsbDsKKworICAgICAgICBpdiA9IG5ldyBieXRlWzhdOworICAgICAgICBzci5uZXh0Qnl0ZXMoaXYpOworICAgICAgICBhcCA9IG5ldyBJdlBhcmFtZXRlclNwZWMoaXYpOworCisgICAgICAgIGNpcGhlciA9IENpcGhlci5nZXRJbnN0YW5jZShhbGdvcml0aG0gKyAiL0NCQy9QS0NTNVBhZGRpbmciKTsKKworICAgICAgICBjaXBoZXIuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBjaXBoZXJLZXksIGFwLCBzcik7CisKKyAgICAgICAgYnl0ZVtdIGNpcGhlcklWID0gY2lwaGVyLmdldElWKCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSVZzIGRpZmZlciIsIEFycmF5cy5lcXVhbHMoY2lwaGVySVYsIGl2KSk7CisgICAgICAgIGNpcGhlciA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9Ob1BhZGRpbmciKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNpcGhlci5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNpcGhlcktleSwgYXAsIHNyKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgY2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL05vUGFkZGluZyIpOworICAgICAgICBhcCA9IG5ldyBSU0FLZXlHZW5QYXJhbWV0ZXJTcGVjKDEwLCBuZXcgQmlnSW50ZWdlcigiMTAiKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNpcGhlci5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNpcGhlcktleURFUywgYXAsIHNyKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXguY3J5cHRvLkNpcGhlciN1cGRhdGUoYnl0ZVtdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VwZGF0ZSRCSUkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChpbnQgaW5kZXggPSAxOyBpbmRleCA8IDQ7IGluZGV4KyspIHsKKyAgICAgICAgICAgIENpcGhlciBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVNFREUvQ0JDL1BLQ1M1UGFkZGluZyIpOworCisgICAgICAgICAgICBieXRlW10ga2V5TWF0ZXJpYWwgPSBsb2FkQnl0ZXMoImh5dHNfIiArICJkZXMtZWRlMy1jYmMudGVzdCIKKyAgICAgICAgICAgICAgICAgICAgKyBpbmRleCArICIua2V5Iik7CisgICAgICAgICAgICBERVNlZGVLZXlTcGVjIGtleVNwZWMgPSBuZXcgREVTZWRlS2V5U3BlYyhrZXlNYXRlcmlhbCk7CisgICAgICAgICAgICBTZWNyZXRLZXlGYWN0b3J5IHNrZiA9IFNlY3JldEtleUZhY3RvcnkuZ2V0SW5zdGFuY2UoIkRFU0VERSIpOworICAgICAgICAgICAgS2V5IGsgPSBza2YuZ2VuZXJhdGVTZWNyZXQoa2V5U3BlYyk7CisKKyAgICAgICAgICAgIGJ5dGVbXSBpdk1hdGVyaWFsID0gbG9hZEJ5dGVzKCJoeXRzXyIgKyAiZGVzLWVkZTMtY2JjLnRlc3QiICsgaW5kZXgKKyAgICAgICAgICAgICAgICAgICAgKyAiLml2Iik7CisgICAgICAgICAgICBJdlBhcmFtZXRlclNwZWMgaXYgPSBuZXcgSXZQYXJhbWV0ZXJTcGVjKGl2TWF0ZXJpYWwpOworCisgICAgICAgICAgICBjLmluaXQoQ2lwaGVyLkRFQ1JZUFRfTU9ERSwgaywgaXYpOworCisgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIGJ5dGVbXSBpbnB1dCA9IG5ldyBieXRlWzI1Nl07CisgICAgICAgICAgICBTdHJpbmcgcmVzUGF0aCA9ICJoeXRzXyIgKyAiZGVzLWVkZTMtY2JjLnRlc3QiICsgaW5kZXgKKyAgICAgICAgICAgICAgICAgICAgKyAiLmNpcGhlcnRleHQiOworICAgICAgICAgICAgRmlsZSByZXNvdXJjZXMgPSBTdXBwb3J0X1Jlc291cmNlcy5jcmVhdGVUZW1wRm9sZGVyKCk7CisgICAgICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsIHJlc1BhdGgpOworICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBTdXBwb3J0X1Jlc291cmNlcy5nZXRTdHJlYW0ocmVzUGF0aCk7CisKKyAgICAgICAgICAgIGludCBieXRlc1JlYWQgPSBpcy5yZWFkKGlucHV0LCAwLCAyNTYpOworICAgICAgICAgICAgd2hpbGUgKGJ5dGVzUmVhZCA+IDApIHsKKyAgICAgICAgICAgICAgICBieXRlW10gb3V0cHV0ID0gYy51cGRhdGUoaW5wdXQsIDAsIGJ5dGVzUmVhZCk7CisgICAgICAgICAgICAgICAgaWYgKG91dHB1dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGJhb3Mud3JpdGUob3V0cHV0KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnl0ZXNSZWFkID0gaXMucmVhZChpbnB1dCwgMCwgMjU2KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYnl0ZVtdIG91dHB1dCA9IGMuZG9GaW5hbCgpOworICAgICAgICAgICAgaWYgKG91dHB1dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgYmFvcy53cml0ZShvdXRwdXQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBieXRlW10gZGVjaXBoZXJlZENpcGhlclRleHQgPSBiYW9zLnRvQnl0ZUFycmF5KCk7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgICAgICBieXRlW10gcGxhaW50ZXh0Qnl0ZXMgPSBsb2FkQnl0ZXMoImh5dHNfIiArICJkZXMtZWRlMy1jYmMudGVzdCIKKyAgICAgICAgICAgICAgICAgICAgKyBpbmRleCArICIucGxhaW50ZXh0Iik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJPcGVyYXRpb24gcHJvZHVjZWQgaW5jb3JyZWN0IHJlc3VsdHMiLCBBcnJheXMuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICBwbGFpbnRleHRCeXRlcywgZGVjaXBoZXJlZENpcGhlclRleHQpKTsKKyAgICAgICAgfQorCisgICAgICAgIENpcGhlciBjaXBoZXIgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFU0VERS9DQkMvUEtDUzVQYWRkaW5nIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaXBoZXIudXBkYXRlKG5ldyBieXRlWzY0XSwgMCwgMzIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LmNyeXB0by5DaXBoZXIjZG9GaW5hbCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9kb0ZpbmFsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoaW50IGluZGV4ID0gMTsgaW5kZXggPCA0OyBpbmRleCsrKSB7CisgICAgICAgICAgICBDaXBoZXIgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTRURFL0NCQy9QS0NTNVBhZGRpbmciKTsKKworICAgICAgICAgICAgYnl0ZVtdIGtleU1hdGVyaWFsID0gbG9hZEJ5dGVzKCJoeXRzXyIgKyAiZGVzLWVkZTMtY2JjLnRlc3QiCisgICAgICAgICAgICAgICAgICAgICsgaW5kZXggKyAiLmtleSIpOworICAgICAgICAgICAgREVTZWRlS2V5U3BlYyBrZXlTcGVjID0gbmV3IERFU2VkZUtleVNwZWMoa2V5TWF0ZXJpYWwpOworICAgICAgICAgICAgU2VjcmV0S2V5RmFjdG9yeSBza2YgPSBTZWNyZXRLZXlGYWN0b3J5LmdldEluc3RhbmNlKCJERVNFREUiKTsKKyAgICAgICAgICAgIEtleSBrID0gc2tmLmdlbmVyYXRlU2VjcmV0KGtleVNwZWMpOworCisgICAgICAgICAgICBieXRlW10gaXZNYXRlcmlhbCA9IGxvYWRCeXRlcygiaHl0c18iICsgImRlcy1lZGUzLWNiYy50ZXN0IiArIGluZGV4CisgICAgICAgICAgICAgICAgICAgICsgIi5pdiIpOworICAgICAgICAgICAgSXZQYXJhbWV0ZXJTcGVjIGl2ID0gbmV3IEl2UGFyYW1ldGVyU3BlYyhpdk1hdGVyaWFsKTsKKworICAgICAgICAgICAgYy5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGssIGl2KTsKKworICAgICAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICBieXRlW10gaW5wdXQgPSBuZXcgYnl0ZVsyNTZdOworICAgICAgICAgICAgU3RyaW5nIHJlc1BhdGggPSAiaHl0c18iICsgImRlcy1lZGUzLWNiYy50ZXN0IiArIGluZGV4CisgICAgICAgICAgICAgICAgICAgICsgIi5wbGFpbnRleHQiOworICAgICAgICAgICAgRmlsZSByZXNvdXJjZXMgPSBTdXBwb3J0X1Jlc291cmNlcy5jcmVhdGVUZW1wRm9sZGVyKCk7CisgICAgICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZShyZXNvdXJjZXMsIG51bGwsIHJlc1BhdGgpOworICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBTdXBwb3J0X1Jlc291cmNlcy5nZXRTdHJlYW0ocmVzUGF0aCk7CisKKyAgICAgICAgICAgIGludCBieXRlc1JlYWQgPSBpcy5yZWFkKGlucHV0LCAwLCAyNTYpOworICAgICAgICAgICAgd2hpbGUgKGJ5dGVzUmVhZCA+IDApIHsKKyAgICAgICAgICAgICAgICBieXRlW10gb3V0cHV0ID0gYy51cGRhdGUoaW5wdXQsIDAsIGJ5dGVzUmVhZCk7CisgICAgICAgICAgICAgICAgaWYgKG91dHB1dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGJhb3Mud3JpdGUob3V0cHV0KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnl0ZXNSZWFkID0gaXMucmVhZChpbnB1dCwgMCwgMjU2KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ5dGVbXSBvdXRwdXQgPSBjLmRvRmluYWwoKTsKKyAgICAgICAgICAgIGlmIChvdXRwdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGJhb3Mud3JpdGUob3V0cHV0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ5dGVbXSBlbmNyeXB0ZWRQbGFpbnRleHQgPSBiYW9zLnRvQnl0ZUFycmF5KCk7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgICAgICBieXRlW10gY2lwaGVyVGV4dCA9IGxvYWRCeXRlcygiaHl0c18iICsgImRlcy1lZGUzLWNiYy50ZXN0IiArIGluZGV4CisgICAgICAgICAgICAgICAgICAgICsgIi5jaXBoZXJ0ZXh0Iik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJPcGVyYXRpb24gcHJvZHVjZWQgaW5jb3JyZWN0IHJlc3VsdHMiLCBBcnJheXMuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQbGFpbnRleHQsIGNpcGhlclRleHQpKTsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGVbXSBiID0gezEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwfTsKKyAgICAgICAgYnl0ZVtdIGIxID0gbmV3IGJ5dGVbMzBdOworCisgICAgICAgIENpcGhlciBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL05vUGFkZGluZyIpOworICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2lwaGVyS2V5REVTKTsKKyAgICAgICAgYy51cGRhdGUoYiwgMCwgMTAsIGIxLCA1KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMuZG9GaW5hbCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL05vUGFkZGluZyIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5kb0ZpbmFsKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9Ob1BhZGRpbmciKTsKKyAgICAgICAgYy5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNpcGhlcktleURFUyk7CisgICAgICAgIGMuZG9GaW5hbChiLCAwLCAxNiwgYjEsIDApOworCisgICAgICAgIFNlY3VyZVJhbmRvbSBzciA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgYnl0ZVtdIGl2ID0gbmV3IGJ5dGVbOF07CisgICAgICAgIHNyLm5leHRCeXRlcyhpdik7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgYXAgPSBuZXcgSXZQYXJhbWV0ZXJTcGVjKGl2KTsKKworICAgICAgICBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL1BLQ1M1UGFkZGluZyIpOworICAgICAgICBjLmluaXQoQ2lwaGVyLkRFQ1JZUFRfTU9ERSwgY2lwaGVyS2V5REVTLCBhcCk7CisKKyAgICAgICAgYy51cGRhdGUoYjEsIDAsIDI0LCBiLCAwKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMuZG9GaW5hbCgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChCYWRQYWRkaW5nRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGJ5dGVbXSBsb2FkQnl0ZXMoU3RyaW5nIHJlc1BhdGgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGaWxlIHJlc291cmNlcyA9IFN1cHBvcnRfUmVzb3VyY2VzLmNyZWF0ZVRlbXBGb2xkZXIoKTsKKyAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUocmVzb3VyY2VzLCBudWxsLCByZXNQYXRoKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBTdXBwb3J0X1Jlc291cmNlcy5nZXRTdHJlYW0ocmVzUGF0aCk7CisKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgYnl0ZVtdIGJ1ZmYgPSBuZXcgYnl0ZVsxMDI0XTsKKyAgICAgICAgaW50IHJlYWRsZW47CisgICAgICAgIHdoaWxlICgocmVhZGxlbiA9IGlzLnJlYWQoYnVmZikpID4gMCkgeworICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZmYsIDAsIHJlYWRsZW4pOworICAgICAgICB9CisgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIHJldHVybiBvdXQudG9CeXRlQXJyYXkoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UGFyYW1ldGVycygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaXBoZXIgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTIik7CisgICAgICAgIGFzc2VydE51bGwoYy5nZXRQYXJhbWV0ZXJzKCkpOworICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3IgaW50IHVwZGF0ZShieXRlW10sIGludCwgaW50LCBieXRlW10sIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXBkYXRlYnl0ZUFycmF5aW50aW50Ynl0ZUFycmF5aW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBiID0gezEsMiwzLDQsNSw2LDcsOCw5LDEwfTsKKyAgICAgICAgYnl0ZVtdIGIxID0gbmV3IGJ5dGVbNl07CisgICAgICAgIENpcGhlciBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVNlZGUiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy51cGRhdGUoYiwgMCwgMTAsIGIxLCA1KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2lwaGVyS2V5KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMudXBkYXRlKGIsIDAsIDEwLCBiMSwgNSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNob3J0QnVmZmVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBiMSA9IG5ldyBieXRlWzMwXTsKKyAgICAgICAgYy51cGRhdGUoYiwgMCwgMTAsIGIxLCA1KTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIGludCBkb0ZpbmFsKGJ5dGVbXSwgaW50LCBpbnQsIGJ5dGVbXSwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REb0ZpbmFsYnl0ZUFycmF5aW50aW50Ynl0ZUFycmF5aW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBiID0gezEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwfTsKKyAgICAgICAgYnl0ZVtdIGIxID0gbmV3IGJ5dGVbMzBdOworCisgICAgICAgIENpcGhlciBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL05vUGFkZGluZyIpOworICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2lwaGVyS2V5REVTKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMuZG9GaW5hbChiLCAwLCAxMCwgYjEsIDUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL05vUGFkZGluZyIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5kb0ZpbmFsKGIsIDAsIDEwLCBiMSwgNSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9Ob1BhZGRpbmciKTsKKyAgICAgICAgYy5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNpcGhlcktleURFUyk7CisgICAgICAgIGMuZG9GaW5hbChiLCAwLCAxNiwgYjEsIDApOworCisgICAgICAgIFNlY3VyZVJhbmRvbSBzciA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgYnl0ZVtdIGl2ID0gbmV3IGJ5dGVbOF07CisgICAgICAgIHNyLm5leHRCeXRlcyhpdik7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgYXAgPSBuZXcgSXZQYXJhbWV0ZXJTcGVjKGl2KTsKKworICAgICAgICBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL1BLQ1M1UGFkZGluZyIpOworICAgICAgICBjLmluaXQoQ2lwaGVyLkRFQ1JZUFRfTU9ERSwgY2lwaGVyS2V5REVTLCBhcCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMuZG9GaW5hbChiMSwgMCwgMjQsIG5ldyBieXRlWzQyXSwgMCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEJhZFBhZGRpbmdFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGIxID0gbmV3IGJ5dGVbNl07CisgICAgICAgIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFU2VkZSIpOworICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2lwaGVyS2V5KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMuZG9GaW5hbChiLCAzLCA2LCBiMSwgNSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNob3J0QnVmZmVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TWF4QWxsb3dlZEtleUxlbmd0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2lwaGVyLmdldE1heEFsbG93ZWRLZXlMZW5ndGgobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENpcGhlci5nZXRNYXhBbGxvd2VkS2V5TGVuZ3RoKCIiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENpcGhlci5nZXRNYXhBbGxvd2VkS2V5TGVuZ3RoKCIvL0NCQy9QS0NTNVBhZGRpbiIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2lwaGVyLmdldE1heEFsbG93ZWRLZXlMZW5ndGgoIi9ERVMvQ0JDL1BLQ1M1UGFkZGluLzEiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZShDaXBoZXIuZ2V0TWF4QWxsb3dlZEtleUxlbmd0aCgiL0RFUy9DQkMvUEtDUzVQYWRkaW4iKSA+IDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRNYXhBbGxvd2VkUGFyYW1ldGVyU3BlYygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2lwaGVyLmdldE1heEFsbG93ZWRQYXJhbWV0ZXJTcGVjKG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDaXBoZXIuZ2V0TWF4QWxsb3dlZFBhcmFtZXRlclNwZWMoIi9ERVMvL1BLQ1M1UGFkZGluIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDaXBoZXIuZ2V0TWF4QWxsb3dlZFBhcmFtZXRlclNwZWMoIi9ERVMvQ0JDLyAvMSIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBDaXBoZXIuZ2V0TWF4QWxsb3dlZFBhcmFtZXRlclNwZWMoIkRFUy9DQkMvUEtDUzVQYWRkaW4iKTsKKyAgICAgICAgQ2lwaGVyLmdldE1heEFsbG93ZWRQYXJhbWV0ZXJTcGVjKCJSU0EiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5jcnlwdG8uQ2lwaGVyI0NpcGhlcihDaXBoZXJTcGkgY2lwaGVyU3BpLCBQcm92aWRlciBwcm92aWRlciwKKyAgICAgKiAgICAgICAgU3RyaW5nIHRyYW5zZm9ybWF0aW9uKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ3RvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIYXJtb255LTExODQKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyB0ZXN0Q2lwaGVyKG51bGwsIG51bGwsICJzIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IHRlc3RDaXBoZXIobmV3IE15Q2lwaGVyKCksIG51bGwsICJzIik7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCBmb3IgJ251bGwnIHByb3ZpZGVyIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IHRlc3RDaXBoZXIobnVsbCwgbmV3IFByb3ZpZGVyKCJxd2VydHkiLCAxLjAsICJxd2VydHkiKSB7fSwgInMiKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGZvciAnbnVsbCcgY2lwaGVyU3BpIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RvRmluYWxMamF2YV9uaW9fQnl0ZUJ1ZmZlckxqYXZhX25pb19CeXRlQnVmZmVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBiID0gezEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwfTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiSW5wdXQgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDY0KTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiT3V0cHV0ID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSg2NCk7CisKKyAgICAgICAgQ2lwaGVyIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvTm9QYWRkaW5nIik7CisgICAgICAgIGMuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBjaXBoZXJLZXlERVMpOworICAgICAgICBiSW5wdXQucHV0KGIsIDAsIDEwKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMuZG9GaW5hbChiSW5wdXQsIGJPdXRwdXQpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL05vUGFkZGluZyIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5kb0ZpbmFsKGJJbnB1dCwgYk91dHB1dCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9Ob1BhZGRpbmciKTsKKyAgICAgICAgYy5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNpcGhlcktleURFUyk7CisgICAgICAgIGJJbnB1dCA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTYpOworICAgICAgICBiSW5wdXQucHV0KGIsIDAsIDE2KTsKKyAgICAgICAgYy5kb0ZpbmFsKGJJbnB1dCwgYk91dHB1dCk7CisKKyAgICAgICAgU2VjdXJlUmFuZG9tIHNyID0gbmV3IFNlY3VyZVJhbmRvbSgpOworICAgICAgICBieXRlW10gaXYgPSBuZXcgYnl0ZVs4XTsKKyAgICAgICAgc3IubmV4dEJ5dGVzKGl2KTsKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBhcCA9IG5ldyBJdlBhcmFtZXRlclNwZWMoaXYpOworCisgICAgICAgIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvUEtDUzVQYWRkaW5nIik7CisgICAgICAgIGMuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLCBjaXBoZXJLZXlERVMsIGFwKTsKKyAgICAgICAgYklucHV0ID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSg2NCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMuZG9GaW5hbChiT3V0cHV0LCBiSW5wdXQpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChCYWRQYWRkaW5nRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL05vUGFkZGluZyIpOworICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2lwaGVyS2V5REVTKTsKKyAgICAgICAgYklucHV0LnB1dChiLCAwLCAxNik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLmRvRmluYWwoYklucHV0LCBiSW5wdXQpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvTm9QYWRkaW5nIik7CisgICAgICAgIGMuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBjaXBoZXJLZXlERVMpOworICAgICAgICBiSW5wdXQucHV0KGIsIDAsIDE2KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMuZG9GaW5hbChiSW5wdXQsIGJPdXRwdXQuYXNSZWFkT25seUJ1ZmZlcigpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGJJbnB1dC5yZXdpbmQoKTsKKyAgICAgICAgYklucHV0LnB1dChiLCAwLCAxNik7CisgICAgICAgIGJPdXRwdXQgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDgpOworICAgICAgICBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVNlZGUiKTsKKyAgICAgICAgYy5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNpcGhlcktleSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLmRvRmluYWwoYklucHV0LCBiT3V0cHV0KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU2hvcnRCdWZmZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5pdFdpdGhLZXlBbGdvcml0aG1QYXJhbWV0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNlY3VyZVJhbmRvbSBzciA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgYnl0ZVtdIGl2ID0gbmV3IGJ5dGVbOF07CisgICAgICAgIHNyLm5leHRCeXRlcyhpdik7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgYXAgPSBuZXcgSXZQYXJhbWV0ZXJTcGVjKGl2KTsKKworICAgICAgICBDaXBoZXIgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9QS0NTNVBhZGRpbmciKTsKKyAgICAgICAgYy5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGNpcGhlcktleURFUywgYXApOworICAgICAgICBhc3NlcnROb3ROdWxsKGMuZ2V0UGFyYW1ldGVycygpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGNpcGhlcktleSwgYXApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGNpcGhlcktleURFUywgKEFsZ29yaXRobVBhcmFtZXRlcnMpbnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5pdFdpdGhLZXlBbGdvcml0aG1QYXJhbWV0ZXJzU2VjdXJlUmFuZG9tKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNlY3VyZVJhbmRvbSBzciA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgYnl0ZVtdIGl2ID0gbmV3IGJ5dGVbOF07CisgICAgICAgIHNyLm5leHRCeXRlcyhpdik7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgYXAgPSBuZXcgSXZQYXJhbWV0ZXJTcGVjKGl2KTsKKworICAgICAgICBDaXBoZXIgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9QS0NTNVBhZGRpbmciKTsKKyAgICAgICAgYy5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGNpcGhlcktleURFUywgYXAsIHNyKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjLmdldFBhcmFtZXRlcnMoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLCBjaXBoZXJLZXksIGFwLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGNpcGhlcktleURFUywgKEFsZ29yaXRobVBhcmFtZXRlcnMpbnVsbCwgc3IpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBjLmluaXQoQ2lwaGVyLkRFQ1JZUFRfTU9ERSwgY2lwaGVyS2V5REVTLCBhcCwgKFNlY3VyZVJhbmRvbSludWxsKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjLmdldFBhcmFtZXRlcnMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pbml0V2l0aENlcnRpZmljYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAvKiBDZXJ0aWZpY2F0ZSBjcmVhdGlvbiBub3RlczogY2VydGlmaWNhdGUgc2hvdWxkIGJlIHZhbGlkIDM3MjczIHN0YXJ0aW5nCisgICAgICogZnJvbSAxMyBOb3YgMjAwOAorICAgICAqIElmIGl0IGJyY29tZXMgaW52YWxpZGF0ZWQgcmVnZW5lcmF0ZSBpdCB1c2luZyBmb2xsb3dpbmcgY29tbWFuZHM6CisgICAgICogMS4gb3BlbnNzbCBnZW5yc2EgLWRlczMgLW91dCB0ZXN0LmtleSAxMDI0CisgICAgICogMi4gb3BlbnNzbCByZXEgLW5ldyAta2V5IHRlc3Qua2V5IC1vdXQgdGVzdC5jc3IKKyAgICAgKiAzLiBjcCB0ZXN0LmtleSB0ZXN0LmtleS5vcmcKKyAgICAgKiA0LiBvcGVuc3NsIHJzYSAtaW4gdGVzdC5rZXkub3JnIC1vdXQgdGVzdC5rZXkKKyAgICAgKiA1LiBvcGVuc3NsIHg1MDkgLXJlcSAtZGF5cyAzNzI3MyAtaW4gdGVzdC5jc3IgLXNpZ25rZXkgdGVzdC5rZXkgLW91dCB0ZXN0LmNlcnQKKyAgICAgKiAqLworCisgICAgICAgIFN0cmluZyBjZXJ0TmFtZSA9IFN1cHBvcnRfUmVzb3VyY2VzLmdldFVSTCgidGVzdC5jZXJ0Iik7CisgICAgICAgIElucHV0U3RyZWFtIGlzID0gbmV3IFVSTChjZXJ0TmFtZSkub3BlbkNvbm5lY3Rpb24oKS5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisKKyAgICAgICAgQ2VydGlmaWNhdGUgY2VydCA9IGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoaXMpOworICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgIENpcGhlciBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJSU0EiKTsKKworICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2VydCk7CisgICAgICAgIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvUEtDUzVQYWRkaW5nIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2VydCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5pdFdpdGhDZXJ0aWZpY2F0ZVNlY3VyZVJhbmRvbSgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgLyogQ2VydGlmaWNhdGUgY3JlYXRpb24gbm90ZXM6IGNlcnRpZmljYXRlIHNob3VsZCBiZSB2YWxpZCAzNzI3MyBzdGFydGluZworICAgICAqIGZyb20gMTMgTm92IDIwMDgKKyAgICAgKiBJZiBpdCBicmNvbWVzIGludmFsaWRhdGVkIHJlZ2VuZXJhdGUgaXQgdXNpbmcgZm9sbG93aW5nIGNvbW1hbmRzOgorICAgICAqIDEuIG9wZW5zc2wgZ2VucnNhIC1kZXMzIC1vdXQgdGVzdC5rZXkgMTAyNAorICAgICAqIDIuIG9wZW5zc2wgcmVxIC1uZXcgLWtleSB0ZXN0LmtleSAtb3V0IHRlc3QuY3NyCisgICAgICogMy4gY3AgdGVzdC5rZXkgdGVzdC5rZXkub3JnCisgICAgICogNC4gb3BlbnNzbCByc2EgLWluIHRlc3Qua2V5Lm9yZyAtb3V0IHRlc3Qua2V5CisgICAgICogNS4gb3BlbnNzbCB4NTA5IC1yZXEgLWRheXMgMzcyNzMgLWluIHRlc3QuY3NyIC1zaWdua2V5IHRlc3Qua2V5IC1vdXQgdGVzdC5jZXJ0CisgICAgICogKi8KKworICAgICAgICBTdHJpbmcgY2VydE5hbWUgPSBTdXBwb3J0X1Jlc291cmNlcy5nZXRVUkwoInRlc3QuY2VydCIpOworICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBVUkwoY2VydE5hbWUpLm9wZW5Db25uZWN0aW9uKCkuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworCisgICAgICAgIENlcnRpZmljYXRlIGNlcnQgPSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKGlzKTsKKyAgICAgICAgaXMuY2xvc2UoKTsKKworICAgICAgICBDaXBoZXIgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiUlNBIik7CisKKyAgICAgICAgYy5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNlcnQsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvUEtDUzVQYWRkaW5nIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2VydCwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF91bndyYXAkQkxqYXZhX2xhbmdfU3RyaW5nSSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTZWN1cmVSYW5kb20gc3IgPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIGJ5dGVbXSBpdiA9IG5ldyBieXRlWzhdOworICAgICAgICBzci5uZXh0Qnl0ZXMoaXYpOworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIGFwID0gbmV3IEl2UGFyYW1ldGVyU3BlYyhpdik7CisKKyAgICAgICAgQ2lwaGVyIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvUEtDUzVQYWRkaW5nIik7CisKKyAgICAgICAgYy5pbml0KENpcGhlci5XUkFQX01PREUsIGNpcGhlcktleURFUywgYXAsIHNyKTsKKyAgICAgICAgYnl0ZVtdIGFyREVTID0gYy53cmFwKGNpcGhlcktleURFUyk7CisgICAgICAgIGJ5dGVbXSBhciAgICA9IGMud3JhcChjaXBoZXJLZXkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLnVud3JhcChhckRFUywgIkRFUyIsIENpcGhlci5TRUNSRVRfS0VZKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBjLmluaXQoQ2lwaGVyLlVOV1JBUF9NT0RFLCBjaXBoZXJLZXlERVMsIGFwLCBzcik7CisgICAgICAgIGFzc2VydFRydWUoY2lwaGVyS2V5REVTLmVxdWFscyhjLnVud3JhcChhckRFUywgIkRFUyIsIENpcGhlci5TRUNSRVRfS0VZKSkpOworICAgICAgICBhc3NlcnRGYWxzZShjaXBoZXJLZXlERVMuZXF1YWxzKGMudW53cmFwKGFyLCAiREVTIiwgQ2lwaGVyLlNFQ1JFVF9LRVkpKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMudW53cmFwKGFyREVTLCAiUlNBMzgiLCBDaXBoZXIuUFVCTElDX0tFWSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTZWRlL0NCQy9QS0NTNVBhZGRpbmciKTsKKyAgICAgICAgYy5pbml0KENpcGhlci5VTldSQVBfTU9ERSwgY2lwaGVyS2V5LCBhcCwgc3IpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy51bndyYXAoYXJERVMsICJERVNlZGUiLCBDaXBoZXIuU0VDUkVUX0tFWSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdXBkYXRlTGphdmFfbmlvX0J5dGVCdWZmZXJMamF2YV9uaW9fQnl0ZUJ1ZmZlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gYiA9IHsxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwxOSwyMH07CisgICAgICAgIEJ5dGVCdWZmZXIgYklucHV0ID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgyNTYpOworICAgICAgICBCeXRlQnVmZmVyIGJPdXRwdXQgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDI1Nik7CisKKyAgICAgICAgQ2lwaGVyIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvTm9QYWRkaW5nIik7CisgICAgICAgIGMuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBjaXBoZXJLZXlERVMpOworICAgICAgICBiSW5wdXQucHV0KGIsIDAsIDEwKTsKKyAgICAgICAgYklucHV0LnJld2luZCgpOworICAgICAgICBiT3V0cHV0LnJld2luZCgpOworICAgICAgICBjLnVwZGF0ZShiSW5wdXQsIGJPdXRwdXQpOworCisgICAgICAgIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvTm9QYWRkaW5nIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLnVwZGF0ZShiSW5wdXQsIGJPdXRwdXQpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvTm9QYWRkaW5nIik7CisgICAgICAgIGMuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBjaXBoZXJLZXlERVMpOworICAgICAgICBiSW5wdXQgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDE2KTsKKyAgICAgICAgYklucHV0LnB1dChiLCAwLCAxNik7CisgICAgICAgIGJJbnB1dC5yZXdpbmQoKTsKKyAgICAgICAgYk91dHB1dC5yZXdpbmQoKTsKKyAgICAgICAgYy51cGRhdGUoYklucHV0LCBiT3V0cHV0KTsKKworICAgICAgICBTZWN1cmVSYW5kb20gc3IgPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIGJ5dGVbXSBpdiA9IG5ldyBieXRlWzhdOworICAgICAgICBzci5uZXh0Qnl0ZXMoaXYpOworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIGFwID0gbmV3IEl2UGFyYW1ldGVyU3BlYyhpdik7CisKKyAgICAgICAgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9QS0NTNVBhZGRpbmciKTsKKyAgICAgICAgYy5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGNpcGhlcktleURFUywgYXApOworICAgICAgICBiSW5wdXQgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDY0KTsKKworICAgICAgICBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL05vUGFkZGluZyIpOworICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2lwaGVyS2V5REVTKTsKKyAgICAgICAgYklucHV0LnB1dChiLCAwLCAxNik7CisgICAgICAgIGJJbnB1dC5yZXdpbmQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMudXBkYXRlKGJJbnB1dCwgYklucHV0KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL05vUGFkZGluZyIpOworICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2lwaGVyS2V5REVTKTsKKyAgICAgICAgYklucHV0LnB1dChiLCAwLCAxNik7CisgICAgICAgIGJJbnB1dC5yZXdpbmQoKTsKKyAgICAgICAgYk91dHB1dC5yZXdpbmQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMudXBkYXRlKGJJbnB1dCwgYk91dHB1dC5hc1JlYWRPbmx5QnVmZmVyKCkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYklucHV0LnJld2luZCgpOworICAgICAgICBiSW5wdXQucHV0KGIsIDAsIDE2KTsKKyAgICAgICAgYklucHV0LnJld2luZCgpOworICAgICAgICBiT3V0cHV0ID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSg4KTsKKyAgICAgICAgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTZWRlIik7CisgICAgICAgIGMuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBjaXBoZXJLZXkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy51cGRhdGUoYklucHV0LCBiT3V0cHV0KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU2hvcnRCdWZmZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIE1vY2tfS2V5IGltcGxlbWVudHMgS2V5IHsKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRGb3JtYXQoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cmFwX2phdmFfc2VjdXJpdHlfS2V5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNlY3VyZVJhbmRvbSBzciA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgYnl0ZVtdIGl2ID0gbmV3IGJ5dGVbOF07CisgICAgICAgIHNyLm5leHRCeXRlcyhpdik7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgYXAgPSBuZXcgSXZQYXJhbWV0ZXJTcGVjKGl2KTsKKworICAgICAgICBDaXBoZXIgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9QS0NTNVBhZGRpbmciKTsKKworICAgICAgICBjLmluaXQoQ2lwaGVyLldSQVBfTU9ERSwgY2lwaGVyS2V5REVTLCBhcCwgc3IpOworICAgICAgICBhc3NlcnROb3ROdWxsKGMud3JhcChjaXBoZXJLZXlERVMpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjLndyYXAoY2lwaGVyS2V5KSk7CisgICAgICAgIFN0cmluZyBjZXJ0TmFtZSA9IFN1cHBvcnRfUmVzb3VyY2VzLmdldFVSTCgidGVzdC5jZXJ0Iik7CisgICAgICAgIElucHV0U3RyZWFtIGlzID0gbmV3IFVSTChjZXJ0TmFtZSkub3BlbkNvbm5lY3Rpb24oKS5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisKKyAgICAgICAgQ2VydGlmaWNhdGUgY2VydCA9IGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoaXMpOworICAgICAgICBhc3NlcnROb3ROdWxsKGMud3JhcChjZXJ0LmdldFB1YmxpY0tleSgpKSk7CisKKyAgICAgICAgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9Ob1BhZGRpbmciKTsKKyAgICAgICAgYy5pbml0KENpcGhlci5XUkFQX01PREUsIGNpcGhlcktleURFUywgYXAsIHNyKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoYy53cmFwKGNlcnQuZ2V0UHVibGljS2V5KCkpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYy5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGNpcGhlcktleURFUywgYXAsIHNyKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy53cmFwKGNpcGhlcktleURFUyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYy5pbml0KENpcGhlci5XUkFQX01PREUsIGNpcGhlcktleURFUywgYXAsIHNyKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMud3JhcChuZXcgTW9ja19LZXkoKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZG9GaW5hbCRCSSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gYiA9IHsxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwxOSwyMH07CisgICAgICAgIGJ5dGVbXSBiMSA9IG5ldyBieXRlWzMwXTsKKworICAgICAgICBDaXBoZXIgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9Ob1BhZGRpbmciKTsKKyAgICAgICAgYy5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNpcGhlcktleURFUyk7CisgICAgICAgIGMudXBkYXRlKGIsIDAsIDEwKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMuZG9GaW5hbChiMSwgNSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvTm9QYWRkaW5nIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLmRvRmluYWwoYjEsIDUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvTm9QYWRkaW5nIik7CisgICAgICAgIGMuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBjaXBoZXJLZXlERVMpOworICAgICAgICBjLnVwZGF0ZShiLCAzLCA4KTsKKyAgICAgICAgYy5kb0ZpbmFsKGIxLCAwKTsKKworICAgICAgICBTZWN1cmVSYW5kb20gc3IgPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIGJ5dGVbXSBpdiA9IG5ldyBieXRlWzhdOworICAgICAgICBzci5uZXh0Qnl0ZXMoaXYpOworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIGFwID0gbmV3IEl2UGFyYW1ldGVyU3BlYyhpdik7CisKKyAgICAgICAgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9QS0NTNVBhZGRpbmciKTsKKyAgICAgICAgYy5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGNpcGhlcktleURFUywgYXApOworCisgICAgICAgIGMudXBkYXRlKGIxLCAwLCAyNCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLmRvRmluYWwoYiwgMCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEJhZFBhZGRpbmdFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGIxID0gbmV3IGJ5dGVbNl07CisgICAgICAgIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFU2VkZSIpOworICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2lwaGVyS2V5KTsKKyAgICAgICAgYy51cGRhdGUoYiwgMywgNik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLmRvRmluYWwoYjEsIDUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTaG9ydEJ1ZmZlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9kb0ZpbmFsJEIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGIxID0gbmV3IGJ5dGVbMzJdOworICAgICAgICBieXRlW10gYkkxID0gezEsMiwzLDQsNSw2LDcsOCw5LDEwfTsKKyAgICAgICAgYnl0ZVtdIGJJMiA9IHsxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNn07CisgICAgICAgIGJ5dGVbXSBiSTMgPSB7MSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTIsMTMsMTQsMTUsMTYsMTcsMTgsMTksMjB9OworICAgICAgICBieXRlW10gYkk0ID0gezEsMiwzfTsKKworICAgICAgICBDaXBoZXIgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9Ob1BhZGRpbmciKTsKKyAgICAgICAgYy5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNpcGhlcktleURFUyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLmRvRmluYWwoYkkxKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9Ob1BhZGRpbmciKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMuZG9GaW5hbChiSTEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvTm9QYWRkaW5nIik7CisgICAgICAgIGMuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBjaXBoZXJLZXlERVMpOworICAgICAgICBjLmRvRmluYWwoYkkyKTsKKyAgICAgICAgYy5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNpcGhlcktleURFUyk7CisgICAgICAgIGMuZG9GaW5hbChiSTMsIDAsIDE2LCBiMSwgMCk7CisKKyAgICAgICAgU2VjdXJlUmFuZG9tIHNyID0gbmV3IFNlY3VyZVJhbmRvbSgpOworICAgICAgICBieXRlW10gaXYgPSBuZXcgYnl0ZVs4XTsKKyAgICAgICAgc3IubmV4dEJ5dGVzKGl2KTsKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBhcCA9IG5ldyBJdlBhcmFtZXRlclNwZWMoaXYpOworCisgICAgICAgIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvUEtDUzVQYWRkaW5nIik7CisgICAgICAgIGMuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLCBjaXBoZXJLZXlERVMsIGFwKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5kb0ZpbmFsKGIxKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQmFkUGFkZGluZ0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9kb0ZpbmFsJEJJSSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gYiA9IHsxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwxOSwyMH07CisgICAgICAgIGJ5dGVbXSBiMSA9IG5ldyBieXRlWzMwXTsKKworICAgICAgICBDaXBoZXIgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9Ob1BhZGRpbmciKTsKKyAgICAgICAgYy5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNpcGhlcktleURFUyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLmRvRmluYWwoYiwgMCwgMTApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL05vUGFkZGluZyIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5kb0ZpbmFsKGIsIDAsIDEwKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL05vUGFkZGluZyIpOworICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2lwaGVyS2V5REVTKTsKKyAgICAgICAgYy5kb0ZpbmFsKGIsIDAsIDE2KTsKKyAgICAgICAgYy5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGNpcGhlcktleURFUyk7CisgICAgICAgIGMuZG9GaW5hbChiLCAwLCAxNiwgYjEsIDApOworCisgICAgICAgIFNlY3VyZVJhbmRvbSBzciA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgYnl0ZVtdIGl2ID0gbmV3IGJ5dGVbOF07CisgICAgICAgIHNyLm5leHRCeXRlcyhpdik7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgYXAgPSBuZXcgSXZQYXJhbWV0ZXJTcGVjKGl2KTsKKworICAgICAgICBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL1BLQ1M1UGFkZGluZyIpOworICAgICAgICBjLmluaXQoQ2lwaGVyLkRFQ1JZUFRfTU9ERSwgY2lwaGVyS2V5REVTLCBhcCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMuZG9GaW5hbChiMSwgMCwgMjQpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChCYWRQYWRkaW5nRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RvRmluYWwkQklJJEIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGIgPSB7MSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTIsMTMsMTQsMTUsMTYsMTcsMTgsMTksMjB9OworICAgICAgICBieXRlW10gYjEgPSBuZXcgYnl0ZVszMF07CisKKyAgICAgICAgQ2lwaGVyIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvTm9QYWRkaW5nIik7CisgICAgICAgIGMuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBjaXBoZXJLZXlERVMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5kb0ZpbmFsKGIsIDAsIDEwLCBiMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvTm9QYWRkaW5nIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLmRvRmluYWwoYiwgMCwgMTAsIGIxKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL05vUGFkZGluZyIpOworICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2lwaGVyS2V5REVTKTsKKyAgICAgICAgYy5kb0ZpbmFsKGIsIDAsIDE2LCBiMSk7CisKKyAgICAgICAgU2VjdXJlUmFuZG9tIHNyID0gbmV3IFNlY3VyZVJhbmRvbSgpOworICAgICAgICBieXRlW10gaXYgPSBuZXcgYnl0ZVs4XTsKKyAgICAgICAgc3IubmV4dEJ5dGVzKGl2KTsKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBhcCA9IG5ldyBJdlBhcmFtZXRlclNwZWMoaXYpOworCisgICAgICAgIGMgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvUEtDUzVQYWRkaW5nIik7CisgICAgICAgIGMuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLCBjaXBoZXJLZXlERVMsIGFwKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5kb0ZpbmFsKGIxLCAwLCAyNCwgbmV3IGJ5dGVbNDJdKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQmFkUGFkZGluZ0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYjEgPSBuZXcgYnl0ZVs2XTsKKyAgICAgICAgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTZWRlIik7CisgICAgICAgIGMuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBjaXBoZXJLZXkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5kb0ZpbmFsKGIsIDMsIDYsIGIxKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU2hvcnRCdWZmZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdXBkYXRlJEIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2lwaGVyIGNpcGhlciA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTRURFL0NCQy9QS0NTNVBhZGRpbmciKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNpcGhlci51cGRhdGUobmV3IGJ5dGVbNjRdKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0XygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gYiA9IHsxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwxOSwyMH07CisgICAgICAgIGJ5dGVbXSBiMSA9IG5ldyBieXRlWzMwXTsKKworICAgICAgICBDaXBoZXIgYyA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9Ob1BhZGRpbmciKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy51cGRhdGUoYiwgMCwgMTAsIGIxKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBjID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL05vUGFkZGluZyIpOworICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgY2lwaGVyS2V5REVTKTsKKyAgICAgICAgYy51cGRhdGUoYiwgMCwgMTYsIGIxKTsKKworICAgICAgICBiMSA9IG5ldyBieXRlWzNdOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLnVwZGF0ZShiLCAzLCAxNSwgYjEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTaG9ydEJ1ZmZlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgdGVzdENpcGhlciBleHRlbmRzIENpcGhlciB7CisgICAgICAgIHRlc3RDaXBoZXIoQ2lwaGVyU3BpIGMsIFByb3ZpZGVyIHAsIFN0cmluZyBzKSB7CisgICAgICAgICAgICBzdXBlcihjLCBwLCBzKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9FbmNyeXB0ZWRQcml2YXRlS2V5SW5mb1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9FbmNyeXB0ZWRQcml2YXRlS2V5SW5mb1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42M2U1NjAwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0VuY3J5cHRlZFByaXZhdGVLZXlJbmZvVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTk5OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0bzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyc1NwaTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXJHZW5lcmF0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkludmFsaWRLZXlTcGVjRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5JbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuUEtDUzhFbmNvZGVkS2V5U3BlYzsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQgamF2YXguY3J5cHRvLkJhZFBhZGRpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXguY3J5cHRvLkNpcGhlcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uRW5jcnlwdGVkUHJpdmF0ZUtleUluZm87CitpbXBvcnQgamF2YXguY3J5cHRvLklsbGVnYWxCbG9ja1NpemVFeGNlcHRpb247CitpbXBvcnQgamF2YXguY3J5cHRvLktleUdlbmVyYXRvcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2VjcmV0S2V5RmFjdG9yeTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5QQkVLZXlTcGVjOworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLlBCRVBhcmFtZXRlclNwZWM7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLnN1cHBvcnQuRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3QgZm9yIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIGNsYXNzLgorICoKKyAqIEFsbCBiaW5hcnkgZGF0YSBmb3IgdGhpcyB0ZXN0IHdlcmUgZ2VuZXJhdGVkIHVzaW5nIEJFQSBKUm9ja2l0IGoyc2RrMS40LjJfMDQKKyAqIChodHRwOi8vd3d3LmJlYS5jb20pIHdpdGggc2VjdXJpdHkgcHJvdmlkZXJzIGxpc3QgZXh0ZW5kZWQgYnkgQm91bmN5IENhc3RsZSdzCisgKiBvbmUgKGh0dHA6Ly93d3cuYm91bmN5Y2FzdGxlLm9yZykKKyAqLworcHVibGljIGNsYXNzIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFByb3ZpZGVyW10gcHJvdmlkZXIgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoKTsKKworICAgIC8qKgorICAgICAqIEFsZ29yaXRobSBuYW1lcy90cmFuc2Zvcm1hdGlvbnMgdXNlZCBpbiByb3VuZHRyaXAgdGVzdHMgb2YKKyAgICAgKiBnZXRLZXlTcGVjKC4uLikgbWV0aG9kcworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdW10gYWxnTmFtZSA9IHsKKyAgICAvLyBBRVMKKyAgICAgICAgICAgIHsgIkFFUyIsIG51bGx9LAorICAgICAgICAgICAgLy8gICAgICAgICAgICB7IkFFUyIsICJBRVMvRUNCL1BLQ1M1UGFkZGluZyJ9LAorICAgICAgICAgICAgLy8gICAgICAgICAgICB7IkFFUyIsICJBRVMvQ0JDL1BLQ1M1UGFkZGluZyJ9LAorICAgICAgICAgICAgLy8gICAgICAgICAgICB7IkFFUyIsICJBRVMvT0ZCL1BLQ1M1UGFkZGluZyJ9LAorICAgICAgICAgICAgLy8gICAgICAgICAgICB7IkFFUyIsICJBRVMvQ0ZCL1BLQ1M1UGFkZGluZyJ9LAorICAgICAgICAgICAgLy8gICAgICAgICAgICB7IjIuMTYuODQwLjEuMTAxLjMuNC4xLjEiLCBudWxsfSwKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgeyIyLjE2Ljg0MC4xLjEwMS4zLjQuMS4yIiwgbnVsbH0sCisgICAgICAgICAgICAvLyAgICAgICAgICAgIHsiMi4xNi44NDAuMS4xMDEuMy40LjEuMyIsIG51bGx9LAorICAgICAgICAgICAgLy8gICAgICAgICAgICB7IjIuMTYuODQwLjEuMTAxLjMuNC4xLjQiLCBudWxsfSwKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgeyIyLjE2Ljg0MC4xLjEwMS4zLjQuMS41IiwgbnVsbH0sCisgICAgICAgICAgICAvLyAgICAgICAgICAgIHsiMi4xNi44NDAuMS4xMDEuMy40LjEuMjEiLCBudWxsfSwKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgeyIyLjE2Ljg0MC4xLjEwMS4zLjQuMS4yMiIsIG51bGx9LAorICAgICAgICAgICAgLy8gICAgICAgICAgICB7IjIuMTYuODQwLjEuMTAxLjMuNC4xLjIzIiwgbnVsbH0sCisgICAgICAgICAgICAvLyAgICAgICAgICAgIHsiMi4xNi44NDAuMS4xMDEuMy40LjEuMjQiLCBudWxsfSwKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgeyIyLjE2Ljg0MC4xLjEwMS4zLjQuMS4yNSIsIG51bGx9LAorICAgICAgICAgICAgLy8gICAgICAgICAgICB7IjIuMTYuODQwLjEuMTAxLjMuNC4xLjQxIiwgbnVsbH0sCisgICAgICAgICAgICAvLyAgICAgICAgICAgIHsiMi4xNi44NDAuMS4xMDEuMy40LjEuNDIiLCBudWxsfSwKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgeyIyLjE2Ljg0MC4xLjEwMS4zLjQuMS40MyIsIG51bGx9LAorICAgICAgICAgICAgLy8gICAgICAgICAgICB7IjIuMTYuODQwLjEuMTAxLjMuNC4xLjQ0IiwgbnVsbH0sCisgICAgICAgICAgICAvLyAgICAgICAgICAgIHsiMi4xNi44NDAuMS4xMDEuMy40LjEuNDUiLCBudWxsfSwKKworICAgICAgICAgICAgLy8gQmxvd2Zpc2gKKyAgICAgICAgICAgIC8vIE5PIE9JRHMgZm9yIEJsb3dmaXNoIGRlZmluZWQgKD8pCisgICAgICAgICAgICB7ICJCbG93ZmlzaCIsIG51bGwgfSwKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgeyJCbG93ZmlzaCIsIkJsb3dmaXNoL0NCQy9QS0NTNVBhZGRpbmcifSwKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgeyJCbG93ZmlzaCIsIkJsb3dmaXNoL0NGQi9QS0NTNVBhZGRpbmcifSwKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgeyJCbG93ZmlzaCIsIkJsb3dmaXNoL09GQi9QS0NTNVBhZGRpbmcifSwKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgeyJCbG93ZmlzaCIsIkJsb3dmaXNoL1BDQkMvUEtDUzVQYWRkaW5nIn0sCisKKyAgICAgICAgICAgIC8vIERFUzogT0lXIE9JRHMgb25seQorICAgICAgICAgICAgLy8ge2lzbygxKSBpZGVudGlmaWVkLW9yZ2FuaXphdGlvbigzKSBvaXcoMTQpIHNlY3NpZygzKQorICAgICAgICAgICAgLy8gYWxnb3JpdGhtcygyKSBkZXNFQ0IoNil9CisgICAgICAgICAgICAvLyAxLjMuMTQuMy4yLjYKKyAgICAgICAgICAgIC8vIDEuMy4xNC4zLjIuNworICAgICAgICAgICAgLy8gMS4zLjE0LjMuMi44CisgICAgICAgICAgICAvLyAxLjMuMTQuMy4yLjkKKyAgICAgICAgICAgIHsgIkRFUyIsIG51bGwgfSwKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgeyJERVMiLCAiREVTL0NCQy9QS0NTNVBhZGRpbmcifSwKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgeyJERVMiLCJERVMvQ0ZCL1BLQ1M1UGFkZGluZyJ9LAorICAgICAgICAgICAgLy8gICAgICAgICAgICB7IkRFUyIsIkRFUy9PRkIvUEtDUzVQYWRkaW5nIn0sCisgICAgICAgICAgICAvLyAgICAgICAgICAgIHsiREVTIiwiREVTL1BDQkMvUEtDUzVQYWRkaW5nIn0sCisKKyAgICAgICAgICAgIC8vIERFU2VkZSAoPVRyaXBsZURlcykKKyAgICAgICAgICAgIC8ve2lzbygxKSBpZGVudGlmaWVkLW9yZ2FuaXphdGlvbigzKSBvaXcoMTQpIHNlY3NpZygzKQorICAgICAgICAgICAgLy8gYWxnb3JpdGhtcygyKSBkZXNFREUoMTcpfQorICAgICAgICAgICAgLy8gMS4zLjE0LjMuMi4xNworICAgICAgICAgICAgLy8gICAgICAgICAgICB7IkRFU2VkZSIsbnVsbH0sCisgICAgICAgICAgICAvLyAgICAgICAgICAgIHsiREVTZWRlIiwiREVTZWRlL0NCQy9QS0NTNVBhZGRpbmcifSwKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgeyJERVNlZGUiLCJERVNlZGUvQ0ZCL1BLQ1M1UGFkZGluZyJ9LAorICAgICAgICAgICAgLy8gICAgICAgICAgICB7IkRFU2VkZSIsIkRFU2VkZS9PRkIvUEtDUzVQYWRkaW5nIn0sCisgICAgICAgICAgICAvLyAgICAgICAgICAgIHsiREVTZWRlIiwiREVTZWRlL1BDQkMvUEtDUzVQYWRkaW5nIn0sCisgICAgICAgICAgICB7ICJUcmlwbGVERVMiLCBudWxsIH0sCisgICAgICAgICAgICAvLyAgICAgICAgICAgIHsiVHJpcGxlREVTIiwiVHJpcGxlREVTL0NCQy9QS0NTNVBhZGRpbmcifSwKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgeyJUcmlwbGVERVMiLCJUcmlwbGVERVMvQ0ZCL1BLQ1M1UGFkZGluZyJ9LAorICAgICAgICAgICAgLy8gICAgICAgICAgICB7IlRyaXBsZURFUyIsIlRyaXBsZURFUy9PRkIvUEtDUzVQYWRkaW5nIn0sCisgICAgICAgICAgICAvLyAgICAgICAgICAgIHsiVHJpcGxlREVTIiwiVHJpcGxlREVTL1BDQkMvUEtDUzVQYWRkaW5nIn0sCisKKyAgICAgICAgICAgIC8vIFBCRVdpdGg8ZGlnZXN0PkFuZDxlbmNyeXB0aW9uPgorICAgICAgICAgICAgeyAiUEJFV2l0aE1ENUFuZFRyaXBsZURFUyIsIG51bGwgfSwKKyAgICAgICAgICAgIC8vIHtpc28oMSkgbWVtYmVyLWJvZHkoMikgdXMoODQwKSByc2Fkc2koMTEzNTQ5KSBwa2NzKDEpIHBrY3MtNSg1KQorICAgICAgICAgICAgLy8gcGJlV2l0aE1ENUFuZERFUy1DQkMoMyl9CisgICAgICAgICAgICB7ICJQQkVXaXRoTUQ1QW5kREVTIiwgIlBCRVdpdGhNRDVBbmRERVMvQ0JDL1BLQ1M1UGFkZGluZyIsICJQQkVXaXRoTUQ1QW5kREVTIn0sCisgICAgICAgICAgICB7ICJQQkVXaXRoTUQ1QW5kREVTIiwgbnVsbCwgIlBCRVdpdGhNRDVBbmRERVMifSwgeyAiUEJFV2l0aEhtYWNTSEExQW5kREVTZWRlIiwgbnVsbCB9LAorICAgICAgICAgICAgLy8gbW9yZSBvaWRzOgorICAgICAgICAgICAgLy8ge2lzbygxKSBtZW1iZXItYm9keSgyKSB1cyg4NDApIG5vcnRlbG5ldHdvcmtzKDExMzUzMykgZW50cnVzdCg3KQorICAgICAgICAgICAgLy8gYWxnb3JpdGhtcyg2NikgcGJlV2l0aE1ENUFuZENBU1Q1LUNCQygxMil9CisgICAgICAgICAgICAvLworICAgICAgICAgICAgLy8gYWxzbyBuYW1lZCBwYmVXaXRoU0hBQW5kMTI4Qml0UkM0LCBwYmVXaXRoU0hBMUFuZDEyOEJpdFJDNDoKKyAgICAgICAgICAgIC8vIHtpc28oMSkgbWVtYmVyLWJvZHkoMikgdXMoODQwKSByc2Fkc2koMTEzNTQ5KSBwa2NzKDEpIHBrY3MtMTIoMTIpCisgICAgICAgICAgICAvLyBwa2NzLTEyLVBiZUlkcygxKSBwa2NzLTEyLU9mZmxpbmVUcmFuc3BvcnRNb2RlKDEpfQorICAgICAgICAgICAgLy8KKyAgICAgICAgICAgIC8vIHtpc28oMSkgbWVtYmVyLWJvZHkoMikgdXMoODQwKSByc2Fkc2koMTEzNTQ5KSBwa2NzKDEpIHBrY3MtMTIoMTIpCisgICAgICAgICAgICAvLyBwa2NzLTEyLVBiZUlkcygxKX0gKworICAgICAgICAgICAgLy8gcGJlV2l0aFNIQUFuZDQwQml0UkM0KDIpIHBiZVdpdGhTSEFBbmQzLUtleVRyaXBsZURFUy1DQkMoMykKKyAgICAgICAgICAgIC8vIHBiZVdpdGhTSEFBbmQyLUtleVRyaXBsZURFUy1DQkMoNCkgcGJlV2l0aFNIQUFuZDEyOEJpdFJDMi1DQkMoNSkKKyAgICAgICAgICAgIC8vIHBiZVdpdGhTSEFBbmQ0MEJpdFJDMi1DQkMoNikKKworICAgICAgICAgICAgLy8gRGlmZmllSGVsbG1hbgorICAgICAgICAgICAgeyAiRGlmZmllSGVsbG1hbiIsIG51bGwgfSwgLy8gMS4yLjg0MC4xMDA0Ni4yLjEKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgeyJESCIsbnVsbH0sIC8vIDEuMi44NDAuMTAwNDYuMi4xCisgICAgICAgICAgICAvLyAgICAgICAgICAgIHsiMS4yLjg0MC4xMTM1NDkuMS4zLjEiLCBudWxsfSwKKworICAgICAgICAgICAgeyAiRFNBIiwgbnVsbCB9LCAvLyAxLjIuODQwLjEwMDQwLjQuMQorCisgICAgICAgICAgICB7ICJSQzIiLCBudWxsIH0sCisKKyAgICAgICAgICAgIHsgIlJDNCIsIG51bGwgfSwKKworICAgICAgICAgICAgeyAiUkM1IiwgbnVsbCB9LAorCisgICAgICAgICAgICAvLyAgICAgICAgICAgIHsiMS4yLjg0MC4xMTM1NDkuMS4xMi4xLjEiLG51bGx9LAorICAgICAgICAgICAgLy8gICAgICAgICAgICB7IjEuMi44NDAuMTEzNTQ5LjEuMTIuMS4yIixudWxsfSwKKyAgICAgICAgICAgIC8veyAiMS4yLjg0MC4xMTM1NDkuMS4xMi4xLjMiLCBudWxsLCAiUEJFV2l0aFNIQTFBbmRERVNlZGUifSwKKyAgICAgICAgICAgIC8veyAiUEJFV2l0aFNIQTFBbmRERVNlZGUiLCBudWxsLCAiUEJFV2l0aFNIQTFBbmRERVNlZGUifSwKKyAgICAvLyAgICAgICAgICAgIHsiMS4yLjg0MC4xMTM1NDkuMS4xMi4xLjQiLG51bGx9LAorICAgIC8vICAgICAgICAgICAgeyIxLjIuODQwLjExMzU0OS4xLjEyLjEuNSIsbnVsbH0sCisgICAgLy8gICAgICAgICAgICB7IjEuMi44NDAuMTEzNTQ5LjEuMTIuMS42IixudWxsfSwKKyAgICAvLyAgICAgICAgICAgIHsiRUxHQU1BTC9QS0NTMSIsICJFTEdBTUFML0VDQi9QS0NTMVBBRERJTkcifSwKKyAgICAvLyAgICAgICAgICAgIHsiRUxHQU1BTC9QS0NTMSIsIkVMR0FNQUwvTk9ORS9QS0NTMVBBRERJTkcifSwKKyAgICAvLyAgICAgICAgICAgIHsiUEJFV0lUSFNIQUFORDMtS0VZVFJJUExFREVTLUNCQyIsIG51bGx9LAorICAgIC8vICAgICAgICAgICAgeyJQQkVXSVRIU0hBMUFORERFU0VERSIsIG51bGx9LAorICAgIC8vICAgICAgICAgICAgeyJQQkVXaXRoU0hBQW5kM0tleVRyaXBsZURFUyIsbnVsbH0sCisgICAgLy8gICAgICAgICAgICB7IlBCRVdJVEhTSEFBTkQzLUtFWVRSSVBMRURFUy1DQkMiLG51bGx9LAorICAgIC8vCisgICAgLy8gICAgICAgICAgICB7IlJDNS0zMiIsbnVsbH0sCisgICAgLy8KKyAgICAvLyAgICAgICAgICAgIHsiUlNBLzEiLCAiUlNBLzEvUEtDUzFQQURESU5HIn0sCisgICAgLy8gICAgICAgICAgICB7IlJTQS8yIiwgIlJTQS8yL1BLQ1MxUEFERElORyJ9LAorICAgIC8vICAgICAgICAgICAgeyJSU0EvSVNPOTc5Ni0xIiwgIlJTQS9FQ0IvSVNPOTc5Ni0xUEFERElORyJ9LAorICAgIC8vICAgICAgICAgICAgeyJSU0EiLCAiUlNBL0VDQi9OT1BBRERJTkcifSwKKyAgICAvLyAgICAgICAgICAgIHsiUlNBL09BRVAiLCAiUlNBL0VDQi9PQUVQUEFERElORyJ9LAorICAgIC8vICAgICAgICAgICAgeyJSU0EvUEtDUzEiLCAiUlNBL0VDQi9QS0NTMVBBRERJTkcifSwKKyAgICAvLyAgICAgICAgICAgIHsiUlNBL0lTTzk3OTYtMSIsICJSU0EvTk9ORS9JU085Nzk2LTFQQURESU5HIn0sCisgICAgLy8gICAgICAgICAgICB7IlJTQSIsICJSU0EvTk9ORS9OT1BBRERJTkcifSwKKyAgICAvLyAgICAgICAgICAgIHsiUlNBL09BRVAiLCAiUlNBL05PTkUvT0FFUFBBRERJTkcifSwKKyAgICAvLyAgICAgICAgICAgIHsiUlNBL1BLQ1MxIiwgIlJTQS9OT05FL1BLQ1MxUEFERElORyJ9LAorICAgIC8vICAgICAgICAgICAgeyJSU0EiLG51bGx9LCAvLyAxLjIuODQwLjExMzU0OS4xLjEuMQorICAgIC8vICAgICAgICAgICAgeyIxLjIuODQwLjExMzU0OS4xLjEuMSIsIG51bGx9LAorICAgIH07CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEFsZ05hbWUgKCkgeworICAgICAgICBib29sZWFuIHBlcmZvcm1lZCA9IGZhbHNlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsZ05hbWUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgLy8gZ2VuZXJhdGUgdGVzdCBkYXRhCisgICAgICAgICAgICAgICAgVGVzdERhdGFHZW5lcmF0b3IgZyA9IG5ldyBUZXN0RGF0YUdlbmVyYXRvcihhbGdOYW1lW2ldWzBdLAorICAgICAgICAgICAgICAgICAgICAgICAgYWxnTmFtZVtpXVsxXSwgcHJpdmF0ZUtleUluZm9EYW1hZ2VkLCBudWxsKTsKKworICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSB0ZXN0IG9iamVjdAorICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIGVwa2k7CisgICAgICAgICAgICAgICAgaWYgKGcuYXAoKSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGVwa2kgPSBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oYWxnTmFtZVtpXVswXSwgZy5jdCgpKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBlcGtpID0gbmV3IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKGcuYXAoKSwgZy5jdCgpKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBjYWxsIG1ldGhvZHMgdW5kZXIgdGVzdAorICAgICAgICAgICAgICAgIGlmIChhbGdOYW1lW2ldLmxlbmd0aCA9PSAzKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhhbGdOYW1lW2ldWzJdLCBlcGtpLmdldEFsZ05hbWUoKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcGVyZm9ybWVkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFRlc3REYXRhR2VuZXJhdG9yLkFsbG93ZWRGYWlsdXJlIGFsbG93ZWRGYWlsdXJlKSB7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IG5vdCBwZXJmb3JtZWQiLCBwZXJmb3JtZWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPkVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKGJ5dGVbXSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogPGJyPgorICAgICAqIEFzc2VydGlvbjogY3JlYXRlcyA8Y29kZT5FbmNyeXB0ZWRQcml2YXRlS2V5SW5mbzwvY29kZT4gaW5zdGFuY2UgPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogdmFsaWQgcGFyYW1ldGVycyBwYXNzZWQgPGJyPgorICAgICAqIEV4cGVjdGVkOiBtdXN0IHBhc3Mgd2l0aG91dCBhbnkgZXhjZXB0aW9ucworICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvYnl0ZUFycmF5MSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhCisgICAgICAgICAgICAgICAgLmdldFZhbGlkRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9FbmNvZGluZygiREgiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+RW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oYnl0ZVtdKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiA8YnI+CisgICAgICogQXNzZXJ0aW9uOiA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaWYgZW5jb2RpbmcgaXMKKyAgICAgKiA8Y29kZT5udWxsPC9jb2RlPjxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IDxjb2RlPm51bGw8L2NvZGU+IHBhc3NlZCBhcyBhIHBhcmFtZXRlciA8YnI+CisgICAgICogRXhwZWN0ZWQ6IDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb2J5dGVBcnJheTIoKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogTnVsbFBvaW50ZXJFeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBvaykgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMyBmb3IgPGNvZGU+RW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oYnl0ZVtdKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiA8YnI+CisgICAgICogQXNzZXJ0aW9uOiA8Y29kZT5JT0V4Y2VwdGlvbjwvY29kZT4gaWYgZW5jb2RpbmcgaXMgd3JvbmcgPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogd3JvbmcgZW5jb2RpbmcgcGFzc2VkIGFzIGEgcGFyYW1ldGVyIDxicj4KKyAgICAgKiBFeHBlY3RlZDogPGNvZGU+SU9FeGNlcHRpb248L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvYnl0ZUFycmF5MygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhuZXcgYnl0ZVswXSk7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IElPRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gb2spIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzQgZm9yIDxjb2RlPkVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKGJ5dGVbXSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogPGJyPgorICAgICAqIEFzc2VydGlvbjogPGNvZGU+SU9FeGNlcHRpb248L2NvZGU+IGlmIGVuY29kaW5nIGlzIHdyb25nIDxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHdyb25nIGVuY29kaW5nIHBhc3NlZCBhcyBhIHBhcmFtZXRlciA8YnI+CisgICAgICogRXhwZWN0ZWQ6IDxjb2RlPklPRXhjZXB0aW9uPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb2J5dGVBcnJheTQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8obmV3IGJ5dGVbXSB7IDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksCisgICAgICAgICAgICAgICAgICAgIDEwIH0pOworICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiOiBJT0V4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIG9rKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM1IGZvciA8Y29kZT5FbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhieXRlW10pPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIDxicj4KKyAgICAgKiBBc3NlcnRpb246IDxjb2RlPklPRXhjZXB0aW9uPC9jb2RlPiBpZiBlbmNvZGluZyBpcyB3cm9uZyA8YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiB3cm9uZyBlbmNvZGluZyBwYXNzZWQgYXMgYSBwYXJhbWV0ZXIgPGJyPgorICAgICAqIEV4cGVjdGVkOiA8Y29kZT5JT0V4Y2VwdGlvbjwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RW5jcnlwdGVkUHJpdmF0ZUtleUluZm9ieXRlQXJyYXk1KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBlbmMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gMTogZ2V0IHZhbGlkIGVuY29kaW5nCisgICAgICAgICAgICBlbmMgPSBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEKKyAgICAgICAgICAgICAgICAgICAgLmdldFZhbGlkRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9FbmNvZGluZygiRFNBIik7CisKKyAgICAgICAgICAgIC8vIC4uLiBhbmQgY29ycnVwdCBpdCAoc2V0IHdyb25nIGFsZyBPSUQgbGVuZ3RoKQorICAgICAgICAgICAgZW5jWzldID0gKGJ5dGUpIDY7CisKKyAgICAgICAgICAgIG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhlbmMpOworICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiKDEpOiBJT0V4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIG9rKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gMjogZ2V0IHZhbGlkIGVuY29kaW5nCisgICAgICAgICAgICBlbmMgPSBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEKKyAgICAgICAgICAgICAgICAgICAgLmdldFZhbGlkRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9FbmNvZGluZygiRFNBIik7CisgICAgICAgICAgICAvLyAuLi4gYW5kIGNvcnJ1cHQgaXQgKHNldCB3cm9uZyBlbmNyeXB0ZWQgZGF0YSB0YWcpCisgICAgICAgICAgICBlbmNbMzA3XSA9IChieXRlKSA2OworICAgICAgICAgICAgbmV3IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKGVuYyk7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICIoMik6IElPRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gb2spIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyAzOiBnZXQgdmFsaWQgZW5jb2RpbmcKKyAgICAgICAgICAgIGVuYyA9IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YQorICAgICAgICAgICAgICAgICAgICAuZ2V0VmFsaWRFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0VuY29kaW5nKCJEU0EiKTsKKyAgICAgICAgICAgIC8vIC4uLiBhbmQgY29ycnVwdCBpdCAoc2V0IHdyb25nIGVuY3J5cHRlZCBkYXRhIGxlbmd0aCkKKyAgICAgICAgICAgIGVuY1szMTBdID0gKGJ5dGUpIDE7CisgICAgICAgICAgICBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oZW5jKTsKKyAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIigzKTogSU9FeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBvaykgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIDQ6IGdldCB2YWxpZCBlbmNvZGluZworICAgICAgICAgICAgZW5jID0gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhCisgICAgICAgICAgICAgICAgICAgIC5nZXRWYWxpZEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRW5jb2RpbmcoIkRTQSIpOworICAgICAgICAgICAgLy8gLi4uIGFuZCBjb3JydXB0IGl0IChzZXQgd3JvbmcgdGFnIGZvciBhbGcgcGFyYW1zIHNlcXVlbmNlKQorICAgICAgICAgICAgZW5jWzE3XSA9IChieXRlKSAweDI5OworICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gZXBraSA9IG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhlbmMpOworCisgICAgICAgICAgICBpZiAoZXBraS5nZXRBbGdQYXJhbWV0ZXJzKCkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIFRoaXMga2luZCBvZiBlbmNvZGluZyBjb3JydXB0aW9uIGNhbgorICAgICAgICAgICAgICAgIC8vIGJlIG9ubHkgZGV0ZXJtaW5lZCB3aGlsZSBBbGdvcml0aG1QYXJhbWV0ZXJzCisgICAgICAgICAgICAgICAgLy8gaW5pdGlhbGl6YXRpb24gQlVUIE5vIEFsZ29yaXRobVBhcmFtZXRlcnMgaW5zdGFuY2UKKyAgICAgICAgICAgICAgICAvLyBhdmFpbGFibGUgZm9yIGFsZ05hbWUwW2ldWzBdLgorICAgICAgICAgICAgICAgIC8vIFNvIGp1c3Qgc2tpcCB0aGlzIHN1YiB0ZXN0CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIig0KTogSU9FeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICAgICAgfQorCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIG9rKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gNTogZ2V0IHZhbGlkIGVuY29kaW5nCisgICAgICAgICAgICBlbmMgPSBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEKKyAgICAgICAgICAgICAgICAgICAgLmdldFZhbGlkRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9FbmNvZGluZygiRFNBIik7CisgICAgICAgICAgICAvLyAuLi4gYW5kIGNvcnJ1cHQgaXQgKHNldCB3cm9uZyBsZW5ndGggZm9yIGFsZyBwYXJhbXMgc2VxdWVuY2UpCisgICAgICAgICAgICBlbmNbMjBdID0gKGJ5dGUpIDB4MWQ7CisgICAgICAgICAgICBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oZW5jKTsKKyAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIig1KTogSU9FeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBvaykgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIDY6IGdldCB2YWxpZCBlbmNvZGluZworICAgICAgICAgICAgZW5jID0gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhCisgICAgICAgICAgICAgICAgICAgIC5nZXRWYWxpZEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRW5jb2RpbmcoIkRTQSIpOworICAgICAgICAgICAgLy8gLi4uIGFuZCBjb3JydXB0IGl0IChzZXQgd3JvbmcgbGVuZ3RoIGZvciBhbGcgcGFyYW1zIHNlcXVlbmNlKQorICAgICAgICAgICAgZW5jWzIwXSA9IChieXRlKSAweDFmOworICAgICAgICAgICAgbmV3IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKGVuYyk7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICIoNik6IElPRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gb2spIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzYgZm9yIDxjb2RlPkVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKGJ5dGVbXSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogPGJyPgorICAgICAqIEFzc2VydGlvbjogYnl0ZSBhcnJheSBpcyBjb3BpZWQgdG8gcHJldmVudCBzdWJzZXF1ZW50IG1vZGlmaWNhdGlvbiA8YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiB2YWxpZCBhcnJheSBwYXNzZWQgdGhlbiBtb2RpZmllZCA8YnI+CisgICAgICogRXhwZWN0ZWQ6IGdldEVuY29kZWQoKSwgaW52b2tlZCBhZnRlciBhYm92ZSBtb2RpZmljYXRpb24sIG11c3QgcmV0dXJuCisgICAgICogYXJyYXkgYXMgaXQgd2FzIGJlZm9yZSB0aGUgbW9kaWZpY2F0aW9uCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvYnl0ZUFycmF5NigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gZW5jb2RlZCA9IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YQorICAgICAgICAgICAgICAgIC5nZXRWYWxpZEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRW5jb2RpbmcoIkRTQSIpOworICAgICAgICBieXRlW10gZW5jb2RlZENvcHkgPSBlbmNvZGVkLmNsb25lKCk7CisgICAgICAgIC8vIHBhc3MgdmFsaWQgYXJyYXkKKyAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gZXBraSA9IG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhlbmNvZGVkQ29weSk7CisgICAgICAgIC8vIG1vZGlmeSBhcnJheSBwYXNzZWQKKyAgICAgICAgZW5jb2RlZENvcHlbOV0gPSAoYnl0ZSkgNjsKKyAgICAgICAgLy8gY2hlY2sgdGhhdCBpbnRlcm5hbCBzdGF0ZSBoYXMgbm90IGJlZW4gYWZmZWN0ZWQKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGVuY29kZWQsIGVwa2kuZ2V0RW5jb2RlZCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+RW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oU3RyaW5nLCBieXRlW10pPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIDxicj4KKyAgICAgKiBBc3NlcnRpb246IGNyZWF0ZXMgPGNvZGU+RW5jcnlwdGVkUHJpdmF0ZUtleUluZm88L2NvZGU+IGluc3RhbmNlIDxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHZhbGlkIHBhcmFtZXRlcnMgcGFzc2VkIDxicj4KKyAgICAgKiBFeHBlY3RlZDogbXVzdCBwYXNzIHdpdGhvdXQgYW55IGV4Y2VwdGlvbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RW5jcnlwdGVkUHJpdmF0ZUtleUluZm9TdHJpbmdieXRlQXJyYXkxKCkgeworICAgICAgICBib29sZWFuIHBlcmZvcm1lZCA9IGZhbHNlOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmFsZ05hbWUwLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbygKKyAgICAgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5hbGdOYW1lMFtpXVswXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5lbmNyeXB0ZWREYXRhKTsKKyAgICAgICAgICAgICAgICBwZXJmb3JtZWQgPSB0cnVlOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGFsbG93ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydFRydWUoIlRlc3Qgbm90IHBlcmZvcm1lZCIsIHBlcmZvcm1lZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+RW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oU3RyaW5nLCBieXRlW10pPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIDxicj4KKyAgICAgKiBBc3NlcnRpb246IDxjb2RlPk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjwvY29kZT4tIGlmIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBhbGdvcml0aG0gaXMgbm90IHN1cHBvcnRlZCA8YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiBwYXNzIG5vbmV4aXN0ZW50IGFsZ29yaXRobSBuYW1lIDxicj4KKyAgICAgKiBFeHBlY3RlZDogPGNvZGU+Tm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb1N0cmluZ2J5dGVBcnJheTIoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oImJsYS1ibGEiLAorICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuZW5jcnlwdGVkRGF0YSk7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBvaykgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbygiIiwKKyAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmVuY3J5cHRlZERhdGEpOworICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiOiBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gb2spIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzMgZm9yIDxjb2RlPkVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKFN0cmluZywgYnl0ZVtdKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciA8YnI+CisgICAgICogQXNzZXJ0aW9uOiA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4tIGlmIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBhbGdvcml0aG0gb3IgZW5jcnlwdGVkIGRhdGEgaXMgPGNvZGU+bnVsbDwvY29kZT48YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiBwYXNzIDxjb2RlPm51bGw8L2NvZGU+IGFzIGFsZ29yaXRobSBuYW1lIHRoZW4gYXMKKyAgICAgKiBlbmNyeXB0ZWQgZGF0YSA8YnI+CisgICAgICogRXhwZWN0ZWQ6IDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpbiBib3RoIGNhc2VzCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb1N0cmluZ2J5dGVBcnJheTMoKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIC8vIHBhc3MgbnVsbCBhcyBuYW1lCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oKFN0cmluZykgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmVuY3J5cHRlZERhdGEpOworICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG9rKSB7CisgICAgICAgIH0KKworICAgICAgICAvLyBwYXNzIG51bGwgYXMgZW5jcnlwdGVkIGRhdGEKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbygiRFNBIiwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IE51bGxQb2ludGVyRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gb2spIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzQgZm9yIDxjb2RlPkVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKFN0cmluZywgYnl0ZVtdKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciA8YnI+CisgICAgICogQXNzZXJ0aW9uOiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+LSBpZiBlbmNyeXB0ZWQgZGF0YSBpcworICAgICAqIGVtcHR5LCBpLmUuIDAtbGVuZ3RoIDxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHBhc3MgZW1wdHkgZW5jcnlwdGVkIGRhdGEgPGJyPgorICAgICAqIEV4cGVjdGVkOiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvU3RyaW5nYnl0ZUFycmF5NCgpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbygiRFNBIiwgbmV3IGJ5dGVbXSB7fSk7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBvaykgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjNSBmb3IgPGNvZGU+RW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oU3RyaW5nLCBieXRlW10pPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIDxicj4KKyAgICAgKiBBc3NlcnRpb246IGJ5dGUgYXJyYXkgaXMgY29waWVkIHRvIHByZXZlbnQgc3Vic2VxdWVudCBtb2RpZmljYXRpb24gPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogdmFsaWQgYXJyYXkgcGFzc2VkIHRoZW4gbW9kaWZpZWQgPGJyPgorICAgICAqIEV4cGVjdGVkOiBnZXRFbmNyeXB0ZWREYXRhKCksIGludm9rZWQgYWZ0ZXIgYWJvdmUgbW9kaWZpY2F0aW9uLCBtdXN0CisgICAgICogcmV0dXJuIGFycmF5IGFzIGl0IHdhcyBiZWZvcmUgdGhlIG1vZGlmaWNhdGlvbgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb1N0cmluZ2J5dGVBcnJheTUoKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBlbmNyeXB0ZWREYXRhQ29weSA9IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5lbmNyeXB0ZWREYXRhCisgICAgICAgICAgICAgICAgLmNsb25lKCk7CisgICAgICAgIC8vIHBhc3MgdmFsaWQgYXJyYXkKKyAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gZXBraSA9IG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbygiRFNBIiwKKyAgICAgICAgICAgICAgICBlbmNyeXB0ZWREYXRhQ29weSk7CisgICAgICAgIC8vIG1vZGlmeSBhcnJheSBwYXNzZWQKKyAgICAgICAgZW5jcnlwdGVkRGF0YUNvcHlbMF0gPSAoYnl0ZSkgNjsKKyAgICAgICAgLy8gY2hlY2sgdGhhdCBpbnRlcm5hbCBzdGF0ZSBoYXMgbm90IGJlZW4gYWZmZWN0ZWQKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5lbmNyeXB0ZWREYXRhLAorICAgICAgICAgICAgICAgIGVwa2kuZ2V0RW5jcnlwdGVkRGF0YSgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgvY3J5cHRvL0VuY3J5cHRlZFByaXZhdGVLZXlJbmZvKFN0cmluZywgYnl0ZVtdKQorICAgICAqIENoZWNrcyBleGNlcHRpb24gb3JkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RW5jcnlwdGVkUHJpdmF0ZUtleUluZm9TdHJpbmdieXRlQXJyYXk2KCkgeworICAgICAgICAvL1JlZ3Jlc3Npb24gZm9yIEhBUk1PTlktNzY4CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oIjAiLCBuZXcgYnl0ZVtdIHt9KTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgTW9ja19BbGdvcml0aG1QYXJhbWV0ZXJzIGV4dGVuZHMgQWxnb3JpdGhtUGFyYW1ldGVycyB7CisgICAgICAgIHByb3RlY3RlZCBNb2NrX0FsZ29yaXRobVBhcmFtZXRlcnMoQWxnb3JpdGhtUGFyYW1ldGVyc1NwaSBwYXJhbVNwaSwgUHJvdmlkZXIgcHJvdmlkZXIsIFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgICAgIHN1cGVyKHBhcmFtU3BpLCBwcm92aWRlciwgYWxnb3JpdGhtKTsKKyAgICAgICAgfQorICAgIH0KKworLyoqCisgICAgICogVGVzdCAjMSBmb3IKKyAgICAgKiA8Y29kZT5FbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnMsIGJ5dGVbXSkKKyAgICAgKiA8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgPGJyPgorICAgICAqIEFzc2VydGlvbjogY3JlYXRlcyA8Y29kZT5FbmNyeXB0ZWRQcml2YXRlS2V5SW5mbzwvY29kZT4gaW5zdGFuY2UgPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogdmFsaWQgcGFyYW1ldGVycyBwYXNzZWQgPGJyPgorICAgICAqIEV4cGVjdGVkOiBtdXN0IHBhc3Mgd2l0aG91dCBhbnkgZXhjZXB0aW9ucworICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvQWxnb3JpdGhtUGFyYW1ldGVyc2J5dGVBcnJheTEoKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIGFwID0gbnVsbDsKKworICAgICAgICBib29sZWFuIHBlcmZvcm1lZCA9IGZhbHNlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5hbGdOYW1lMC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhcCA9IEFsZ29yaXRobVBhcmFtZXRlcnMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZShFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTBbaV1bMF0pOworICAgICAgICAgICAgICAgIC8vIHVzZSBwcmVnZW5lcmF0ZWQgQWxnb3JpdGhtUGFyYW1ldGVycyBlbmNvZGluZ3MKKyAgICAgICAgICAgICAgICBhcC5pbml0KEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5nZXRQYXJhbWV0ZXJzRW5jb2RpbmcoCisgICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTBbaV1bMF0pKTsKKworICAgICAgICAgICAgICAgIG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhhcCwKKyAgICAgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5lbmNyeXB0ZWREYXRhKTsKKworICAgICAgICAgICAgICAgIHBlcmZvcm1lZCA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IG5vdCBwZXJmb3JtZWQiLCBwZXJmb3JtZWQpOworCisgICAgICAgIGFwID0gbmV3IE1vY2tfQWxnb3JpdGhtUGFyYW1ldGVycyhudWxsLCBudWxsLCAiV3JvbmcgYWxnIG5hbWUiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKGFwLAorICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5lbmNyeXB0ZWREYXRhKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IKKyAgICAgKiA8Y29kZT5FbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnMsIGJ5dGVbXSkKKyAgICAgKiA8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgPGJyPgorICAgICAqIEFzc2VydGlvbjogPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+LSBpZiB0aGUgc3BlY2lmaWVkCisgICAgICogYWxnb3JpdGhtIHBhcmFtZXRlcnMgb3IgZW5jcnlwdGVkIGRhdGEgaXMgPGNvZGU+bnVsbDwvY29kZT48YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiBwYXNzIDxjb2RlPm51bGw8L2NvZGU+IGFzIGFsZ29yaXRobSBwYXJhbWV0ZXJzIHRoZW4KKyAgICAgKiBhcyBlbmNyeXB0ZWQgZGF0YSA8YnI+CisgICAgICogRXhwZWN0ZWQ6IDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpbiBib3RoIGNhc2VzCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RW5jcnlwdGVkUHJpdmF0ZUtleUluZm9BbGdvcml0aG1QYXJhbWV0ZXJzYnl0ZUFycmF5MigpCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIDE6IHBhc3MgbnVsbCBhcyBBbGdvcml0aG1QYXJhbWV0ZXJzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oKEFsZ29yaXRobVBhcmFtZXRlcnMpIG51bGwsCisgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5lbmNyeXB0ZWREYXRhKTsKKyAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogTnVsbFBvaW50ZXJFeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBvaykgeworICAgICAgICB9CisKKyAgICAgICAgLy8gMjogcGFzcyBudWxsIGFzIGVuY3J5cHRlZCBkYXRhCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIGFwID0gQWxnb3JpdGhtUGFyYW1ldGVycy5nZXRJbnN0YW5jZSgiRFNBIik7CisgICAgICAgICAgICAvLyB1c2UgcHJlZ2VuZXJhdGVkIEFsZ29yaXRobVBhcmFtZXRlcnMgZW5jb2RpbmdzCisgICAgICAgICAgICBhcC5pbml0KEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5nZXRQYXJhbWV0ZXJzRW5jb2RpbmcoIkRTQSIpKTsKKyAgICAgICAgICAgIG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhhcCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IE51bGxQb2ludGVyRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gb2spIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzMgZm9yCisgICAgICogPGNvZGU+RW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzLCBieXRlW10pCisgICAgICogPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIDxicj4KKyAgICAgKiBBc3NlcnRpb246IDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4tIGlmIGVuY3J5cHRlZCBkYXRhIGlzCisgICAgICogZW1wdHksIGkuZS4gMC1sZW5ndGggPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogcGFzcyBlbXB0eSBlbmNyeXB0ZWQgZGF0YSA8YnI+CisgICAgICogRXhwZWN0ZWQ6IDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0FsZ29yaXRobVBhcmFtZXRlcnNieXRlQXJyYXkzKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVycyBhcCA9IEFsZ29yaXRobVBhcmFtZXRlcnMuZ2V0SW5zdGFuY2UoIkRTQSIpOworICAgICAgICAgICAgLy8gdXNlIHByZWdlbmVyYXRlZCBBbGdvcml0aG1QYXJhbWV0ZXJzIGVuY29kaW5ncworICAgICAgICAgICAgYXAuaW5pdChFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuZ2V0UGFyYW1ldGVyc0VuY29kaW5nKCJEU0EiKSk7CisKKyAgICAgICAgICAgIG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhhcCwgbmV3IGJ5dGVbXSB7fSk7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG9rKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM0IGZvcgorICAgICAqIDxjb2RlPkVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKGphdmEuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVycywgYnl0ZVtdKQorICAgICAqIDwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciA8YnI+CisgICAgICogQXNzZXJ0aW9uOiBieXRlIGFycmF5IGlzIGNvcGllZCB0byBwcmV2ZW50IHN1YnNlcXVlbnQgbW9kaWZpY2F0aW9uIDxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHZhbGlkIGFycmF5IHBhc3NlZCB0aGVuIG1vZGlmaWVkIDxicj4KKyAgICAgKiBFeHBlY3RlZDogZ2V0RW5jcnlwdGVkRGF0YSgpLCBpbnZva2VkIGFmdGVyIGFib3ZlIG1vZGlmaWNhdGlvbiwgbXVzdAorICAgICAqIHJldHVybiBhcnJheSBhcyBpdCB3YXMgYmVmb3JlIHRoZSBtb2RpZmljYXRpb24KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RW5jcnlwdGVkUHJpdmF0ZUtleUluZm9BbGdvcml0aG1QYXJhbWV0ZXJzYnl0ZUFycmF5NCgpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVycyBhcCA9IEFsZ29yaXRobVBhcmFtZXRlcnMuZ2V0SW5zdGFuY2UoIkRTQSIpOworICAgICAgICAvLyB1c2UgcHJlZ2VuZXJhdGVkIEFsZ29yaXRobVBhcmFtZXRlcnMgZW5jb2RpbmdzCisgICAgICAgIGFwLmluaXQoRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmdldFBhcmFtZXRlcnNFbmNvZGluZygiRFNBIikpOworCisgICAgICAgIGJ5dGVbXSBlbmNyeXB0ZWREYXRhQ29weSA9IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5lbmNyeXB0ZWREYXRhLmNsb25lKCk7CisgICAgICAgIC8vIHBhc3MgdmFsaWQgYXJyYXkKKyAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gZXBraSA9IG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhhcCwKKyAgICAgICAgICAgICAgICBlbmNyeXB0ZWREYXRhQ29weSk7CisKKyAgICAgICAgLy8gbW9kaWZ5IGFycmF5IHBhc3NlZAorICAgICAgICBlbmNyeXB0ZWREYXRhQ29weVswXSA9IChieXRlKSA2OworCisgICAgICAgIC8vIGNoZWNrIHRoYXQgaW50ZXJuYWwgc3RhdGUgaGFzIG5vdCBiZWVuIGFmZmVjdGVkCisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuZW5jcnlwdGVkRGF0YSwKKyAgICAgICAgICAgICAgICBlcGtpLmdldEVuY3J5cHRlZERhdGEoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPmdldEFsZ1BhcmFtZXRlcnMoKTwvY29kZT4gbWV0aG9kIDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgdGhlIGFsZ29yaXRobSBwYXJhbWV0ZXJzIDxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHRlc3Qgb2JqZWN0IGNyZWF0ZWQgdXNpbmcgY3RvciB3aGljaCB0YWtlcyBlbmNvZGVkCisgICAgICogZm9ybSBhcyB0aGUgb25seSBwYXJhbWV0ZXI7IGVuY29kZWQgZm9ybSBwYXNzZWQgY29udGFpbnMgYWxnb3JpdGhtCisgICAgICogcGFyYW1ldGVycyBlbmNvZGluZyA8YnI+CisgICAgICogRXhwZWN0ZWQ6IGNvcnJlc3BvbmRpbmcgYWxnb3JpdGhtIHBhcmFtZXRlcnMgbXVzdCBiZSByZXR1cm5lZAorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRBbGdQYXJhbWV0ZXJzMDEoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBib29sZWFuIHBlcmZvcm1lZCA9IGZhbHNlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5hbGdOYW1lMC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyBlcGtpID0gbmV3IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKAorICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRWYWxpZEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRW5jb2RpbmcoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmFsZ05hbWUwW2ldWzBdKSk7CisKKyAgICAgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIGFwYXIgPSBlcGtpLmdldEFsZ1BhcmFtZXRlcnMoKTsKKyAgICAgICAgICAgICAgICBpZiAoYXBhciA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgbWV0aG9kIHVuZGVyIHRlc3QgcmV0dXJucworICAgICAgICAgICAgICAgIC8vIHBhcmFtZXRlcnMgd2l0aCB0aGUgc2FtZSBlbmNvZGVkIGZvcm0KKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKEFycmF5cworICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldFBhcmFtZXRlcnNFbmNvZGluZyhFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTBbaV1bMF0pLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcGFyLmdldEVuY29kZWQoKSkpOworICAgICAgICAgICAgICAgIHBlcmZvcm1lZCA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IG5vdCBwZXJmb3JtZWQiLCBwZXJmb3JtZWQpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRBbGdQYXJhbWV0ZXJzMDFfMDEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIHZhbGlkRW5jb2RpbmdXaXRoVW5rbm93bkFsZ09JRCA9IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YQorICAgICAgICAgICAgICAgIC5nZXRWYWxpZEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRW5jb2RpbmcoIkRIIik7CisgICAgICAgIC8vIGNvcnJlY3Qgb2lkIHZhbHVlCisgICAgICAgIHZhbGlkRW5jb2RpbmdXaXRoVW5rbm93bkFsZ09JRFsxOF0gPSAwOworICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyBlcGtpID0gbmV3IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKAorICAgICAgICAgICAgICAgIHZhbGlkRW5jb2RpbmdXaXRoVW5rbm93bkFsZ09JRCk7CisKKyAgICAgICAgYXNzZXJ0TnVsbChlcGtpLmdldEFsZ1BhcmFtZXRlcnMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+Z2V0QWxnUGFyYW1ldGVycygpPC9jb2RlPiBtZXRob2QgPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyB0aGUgYWxnb3JpdGhtIHBhcmFtZXRlcnMgPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogdGVzdCBvYmplY3QgY3JlYXRlZCB1c2luZyBjdG9yIHdoaWNoIHRha2VzIGVuY29kZWQKKyAgICAgKiBmb3JtIGFzIHRoZSBvbmx5IHBhcmFtZXRlcjsgZW5jb2RlZCBmb3JtIHBhc3NlZCBkb2VzIG5vdCBjb250YWluCisgICAgICogYWxnb3JpdGhtIHBhcmFtZXRlcnMgZW5jb2RpbmcgPGJyPgorICAgICAqIEV4cGVjdGVkOiA8Y29kZT5udWxsPC9jb2RlPiBtdXN0IGJlIHJldHVybmVkCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEFsZ1BhcmFtZXRlcnMwMigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gcGVyZm9ybWVkID0gZmFsc2U7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmFsZ05hbWUwLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIGVwa2kgPSBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oCisgICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldFZhbGlkRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9FbmNvZGluZygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTBbaV1bMF0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpKTsKKworICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgbWV0aG9kIHVuZGVyIHRlc3QgcmV0dXJucyBudWxsCisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChlcGtpLmdldEFsZ1BhcmFtZXRlcnMoKSk7CisKKyAgICAgICAgICAgICAgICBwZXJmb3JtZWQgPSB0cnVlOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGFsbG93ZWRGYWlsdXJlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCBub3QgcGVyZm9ybWVkIiwgcGVyZm9ybWVkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMzIGZvciA8Y29kZT5nZXRBbGdQYXJhbWV0ZXJzKCk8L2NvZGU+IG1ldGhvZCA8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHRoZSBhbGdvcml0aG0gcGFyYW1ldGVycyA8YnI+CisgICAgICogVGVzdCAjNiBmb3IgPGNvZGU+RW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oU3RyaW5nLCBieXRlW10pPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIDxicj4KKyAgICAgKiBBc3NlcnRpb246IC4uLlRoaXMgY29uc3RydWN0b3Igd2lsbCB1c2UgbnVsbCBhcyB0aGUgdmFsdWUgb2YgdGhlCisgICAgICogYWxnb3JpdGhtIHBhcmFtZXRlcnMuIDxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHRlc3Qgb2JqZWN0IGNyZWF0ZWQgdXNpbmcgY3RvciB3aGljaCB0YWtlcyBhbGdvcml0aG0KKyAgICAgKiBuYW1lIGFuZCBlbmNyeXB0ZWQgZGF0YSBhcyBhIHBhcmFtZXRlcnMgPGJyPgorICAgICAqIEV4cGVjdGVkOiA8Y29kZT5udWxsPC9jb2RlPiBtdXN0IGJlIHJldHVybmVkCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEFsZ1BhcmFtZXRlcnMwMygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gcGVyZm9ybWVkID0gZmFsc2U7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmFsZ05hbWUwLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIGVwa2kgPSBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oCisgICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTBbaV1bMF0sCisgICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuZW5jcnlwdGVkRGF0YSk7CisKKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IG1ldGhvZCB1bmRlciB0ZXN0IHJldHVybnMgbnVsbAorICAgICAgICAgICAgICAgIC8vIGZvciBvYmplY3QgY29uc3RydWN0ZWQgaW4gc3VjaCBhIHdheQorICAgICAgICAgICAgICAgIGFzc2VydE51bGwoZXBraS5nZXRBbGdQYXJhbWV0ZXJzKCkpOworCisgICAgICAgICAgICAgICAgcGVyZm9ybWVkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBhbGxvd2VkRmFpbHVyZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlRlc3Qgbm90IHBlcmZvcm1lZCIsIHBlcmZvcm1lZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjNCBmb3IgPGNvZGU+Z2V0QWxnUGFyYW1ldGVycygpPC9jb2RlPiBtZXRob2QgPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyB0aGUgYWxnb3JpdGhtIHBhcmFtZXRlcnMgPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogdGVzdCBvYmplY3QgY3JlYXRlZCB1c2luZyBjdG9yIHdoaWNoIHRha2VzCisgICAgICogQWxnb3JpdGhtUGFyYW1ldGVycyBhbmQgZW5jcnlwdGVkIGRhdGEgYXMgYSBwYXJhbWV0ZXJzOyA8YnI+CisgICAgICogRXhwZWN0ZWQ6IHRoZSBzYW1lIGFsZ29yaXRobSBwYXJhbWV0ZXJzIGFzIG9uZXMgcGFzc2VkIHRvIHRoZSBjdG9yIG11c3QgYmUKKyAgICAgKiByZXR1cm5lZAorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRBbGdQYXJhbWV0ZXJzMDQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBib29sZWFuIHBlcmZvcm1lZCA9IGZhbHNlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5hbGdOYW1lMC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIGFwID0gQWxnb3JpdGhtUGFyYW1ldGVycworICAgICAgICAgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5hbGdOYW1lMFtpXVswXSk7CisgICAgICAgICAgICAgICAgLy8gdXNlIHByZWdlbmVyYXRlZCBBbGdvcml0aG1QYXJhbWV0ZXJzIGVuY29kaW5ncworICAgICAgICAgICAgICAgIGFwCisgICAgICAgICAgICAgICAgICAgICAgICAuaW5pdChFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldFBhcmFtZXRlcnNFbmNvZGluZygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTBbaV1bMF0pKTsKKworICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIGVwa2kgPSBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oYXAsCisgICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuZW5jcnlwdGVkRGF0YSk7CisKKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IG1ldGhvZCB1bmRlciB0ZXN0IHJldHVybnMKKyAgICAgICAgICAgICAgICAvLyB0aGUgc2FtZSBwYXJhbWV0ZXJzIGluc3RhbmNlCisgICAgICAgICAgICAgICAgYXNzZXJ0U2FtZShhcCwgZXBraS5nZXRBbGdQYXJhbWV0ZXJzKCkpOworCisgICAgICAgICAgICAgICAgcGVyZm9ybWVkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBhbGxvd2VkRmFpbHVyZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlRlc3Qgbm90IHBlcmZvcm1lZCIsIHBlcmZvcm1lZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+Z2V0RW5jcnlwdGVkRGF0YSgpPC9jb2RlPiBtZXRob2QgPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyB0aGUgZW5jcnlwdGVkIGRhdGEgPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogdGVzdCBvYmplY3QgY3JlYXRlZCB1c2luZyBjdG9yIHdoaWNoIHRha2VzIGVuY29kZWQKKyAgICAgKiBmb3JtIGFzIHRoZSBvbmx5IHBhcmFtZXRlcjsgZW5jb2RlZCBmb3JtIHBhc3NlZCBjb250YWlucyBlbmNyeXB0ZWQgZGF0YQorICAgICAqIDxicj4KKyAgICAgKiBFeHBlY3RlZDogdGhlIGVxdWl2YWxlbnQgZW5jcnlwdGVkIGRhdGEgbXVzdCBiZSByZXR1cm5lZAorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRFbmNyeXB0ZWREYXRhMDEoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBib29sZWFuIHBlcmZvcm1lZCA9IGZhbHNlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5hbGdOYW1lMC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyBlcGtpID0gbmV3IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKAorICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRWYWxpZEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRW5jb2RpbmcoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmFsZ05hbWUwW2ldWzBdKSk7CisKKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IG1ldGhvZCB1bmRlciB0ZXN0IHJldHVybnMKKyAgICAgICAgICAgICAgICAvLyB2YWxpZCBlbmNyeXB0ZWQgZGF0YQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5lbmNyeXB0ZWREYXRhLCBlcGtpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRFbmNyeXB0ZWREYXRhKCkpKTsKKworICAgICAgICAgICAgICAgIHBlcmZvcm1lZCA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IG5vdCBwZXJmb3JtZWQiLCBwZXJmb3JtZWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPmdldEVuY3J5cHRlZERhdGEoKTwvY29kZT4gbWV0aG9kIDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgdGhlIGVuY3J5cHRlZCBkYXRhIDxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHRlc3Qgb2JqZWN0IGNyZWF0ZWQgdXNpbmcgY3RvciB3aGljaCB0YWtlcyBhbGdvcml0aG0KKyAgICAgKiBuYW1lIGFuZCBlbmNyeXB0ZWQgZGF0YSBhcyBhIHBhcmFtZXRlcnMgPGJyPgorICAgICAqIEV4cGVjdGVkOiB0aGUgZXF1aXZhbGVudCBlbmNyeXB0ZWQgZGF0YSBtdXN0IGJlIHJldHVybmVkCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEVuY3J5cHRlZERhdGEwMigpIHsKKyAgICAgICAgYm9vbGVhbiBwZXJmb3JtZWQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTAubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gZXBraSA9IG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbygKKyAgICAgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5hbGdOYW1lMFtpXVswXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5lbmNyeXB0ZWREYXRhKTsKKworICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgbWV0aG9kIHVuZGVyIHRlc3QgcmV0dXJucworICAgICAgICAgICAgICAgIC8vIHZhbGlkIGVuY3J5cHRlZCBkYXRhCisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmVuY3J5cHRlZERhdGEsIGVwa2kKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEVuY3J5cHRlZERhdGEoKSkpOworCisgICAgICAgICAgICAgICAgcGVyZm9ybWVkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBhbGxvd2VkRmFpbHVyZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlRlc3Qgbm90IHBlcmZvcm1lZCIsIHBlcmZvcm1lZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMyBmb3IgPGNvZGU+Z2V0RW5jcnlwdGVkRGF0YSgpPC9jb2RlPiBtZXRob2QgPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyB0aGUgZW5jcnlwdGVkIGRhdGEgPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogdGVzdCBvYmplY3QgY3JlYXRlZCB1c2luZyBjdG9yIHdoaWNoIHRha2VzIGFsZ29yaXRobQorICAgICAqIHBhcmFtZXRlcnMgYW5kIGVuY3J5cHRlZCBkYXRhIGFzIGEgcGFyYW1ldGVycyA8YnI+CisgICAgICogRXhwZWN0ZWQ6IHRoZSBlcXVpdmFsZW50IGVuY3J5cHRlZCBkYXRhIG11c3QgYmUgcmV0dXJuZWQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0RW5jcnlwdGVkRGF0YTAzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYm9vbGVhbiBwZXJmb3JtZWQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTAubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVycyBhcCA9IEFsZ29yaXRobVBhcmFtZXRlcnMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZShFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTBbaV1bMF0pOworICAgICAgICAgICAgICAgIC8vIHVzZSBwcmVnZW5lcmF0ZWQgQWxnb3JpdGhtUGFyYW1ldGVycyBlbmNvZGluZ3MKKyAgICAgICAgICAgICAgICBhcC5pbml0KEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5nZXRQYXJhbWV0ZXJzRW5jb2RpbmcoCisgICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTBbaV1bMF0pKTsKKworICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIGVwa2kgPSBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oYXAsCisgICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuZW5jcnlwdGVkRGF0YSk7CisKKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IG1ldGhvZCB1bmRlciB0ZXN0IHJldHVybnMKKyAgICAgICAgICAgICAgICAvLyB2YWxpZCBlbmNyeXB0ZWQgZGF0YQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5lbmNyeXB0ZWREYXRhLCBlcGtpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRFbmNyeXB0ZWREYXRhKCkpKTsKKworICAgICAgICAgICAgICAgIHBlcmZvcm1lZCA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IG5vdCBwZXJmb3JtZWQiLCBwZXJmb3JtZWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzQgZm9yIDxjb2RlPmdldEVuY3J5cHRlZERhdGEoKTwvY29kZT4gbWV0aG9kIDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgYSBuZXcgYXJyYXkgZWFjaCB0aW1lIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCA8YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiB0ZXN0IG9iamVjdCBjcmVhdGVkIHVzaW5nIGN0b3Igd2hpY2ggdGFrZXMgYWxnb3JpdGhtCisgICAgICogbmFtZSBhbmQgZW5jcnlwdGVkIGRhdGEgYXMgYSBwYXJhbWV0ZXJzIDxicj4KKyAgICAgKiBFeHBlY3RlZDogcmVmcyB0byBlbmNyeXB0ZWQgZGF0YSBieXRlIGFycmF5IHBhc3NlZCB0byB0aGUgY3RvciBhbmQKKyAgICAgKiByZXR1cm5lZCBieSB0aGUgbWV0aG9kIHVuZGVyIHRlc3QgbXVzdCBiZSBkaWZmZXJlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0RW5jcnlwdGVkRGF0YTA0KCkgeworICAgICAgICBib29sZWFuIHBlcmZvcm1lZCA9IGZhbHNlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5hbGdOYW1lMC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyBlcGtpID0gbmV3IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKAorICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmFsZ05hbWUwW2ldWzBdLAorICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmVuY3J5cHRlZERhdGEpOworCisgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCBtZXRob2QgdW5kZXIgdGVzdCByZXR1cm5zCisgICAgICAgICAgICAgICAgLy8gbmV3IGFycmF5IGVhY2ggdGltZQorICAgICAgICAgICAgICAgIGJ5dGVbXSBlY2QxID0gZXBraS5nZXRFbmNyeXB0ZWREYXRhKCk7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGVjZDIgPSBlcGtpLmdldEVuY3J5cHRlZERhdGEoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3RTYW1lKEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5lbmNyeXB0ZWREYXRhLCBlY2QxKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3RTYW1lKEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5lbmNyeXB0ZWREYXRhLCBlY2QyKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3RTYW1lKGVjZDEsIGVjZDIpOworCisgICAgICAgICAgICAgICAgcGVyZm9ybWVkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBhbGxvd2VkRmFpbHVyZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlRlc3Qgbm90IHBlcmZvcm1lZCIsIHBlcmZvcm1lZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+Z2V0RW5jb2RlZCgpPC9jb2RlPiBtZXRob2QgPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyB0aGUgQVNOLjEgZW5jb2Rpbmcgb2YgdGhpcyBvYmplY3QgPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogdGVzdCBvYmplY3QgY3JlYXRlZCB1c2luZyBjdG9yIHdoaWNoIHRha2VzIGVuY29kZWQKKyAgICAgKiBmb3JtIGFzIHRoZSBvbmx5IHBhcmFtZXRlciA8YnI+CisgICAgICogRXhwZWN0ZWQ6IGVxdWl2YWxlbnQgZW5jb2RlZCBmb3JtIG11c3QgYmUgcmV0dXJuZWQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0RW5jb2RlZDAxKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYm9vbGVhbiBwZXJmb3JtZWQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTAubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGVuYyA9IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YQorICAgICAgICAgICAgICAgICAgICAgICAgLmdldFZhbGlkRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9FbmNvZGluZygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmFsZ05hbWUwW2ldWzBdKTsKKyAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyBlcGtpID0gbmV3IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKGVuYyk7CisKKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IG1ldGhvZCB1bmRlciB0ZXN0IHJldHVybnMKKyAgICAgICAgICAgICAgICAvLyB2YWxpZCBlbmNvZGVkIGZvcm0KKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoZW5jLCBlcGtpLmdldEVuY29kZWQoKSkpOworCisgICAgICAgICAgICAgICAgcGVyZm9ybWVkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBhbGxvd2VkRmFpbHVyZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlRlc3Qgbm90IHBlcmZvcm1lZCIsIHBlcmZvcm1lZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+Z2V0RW5jb2RlZCgpPC9jb2RlPiBtZXRob2QgPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyB0aGUgQVNOLjEgZW5jb2Rpbmcgb2YgdGhpcyBvYmplY3QgPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogdGVzdCBvYmplY3QgY3JlYXRlZCB1c2luZyBjdG9yIHdoaWNoIHRha2VzIGFsZ29yaXRobQorICAgICAqIG5hbWUgYW5kIGVuY3J5cHRlZCBkYXRhIGFzIGEgcGFyYW1ldGVycyA8YnI+CisgICAgICogRXhwZWN0ZWQ6IGVxdWl2YWxlbnQgZW5jb2RlZCBmb3JtICh3aXRob3V0IGFsZyBwYXJhbXMpIG11c3QgYmUgcmV0dXJuZWQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0RW5jb2RlZDAyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYm9vbGVhbiBwZXJmb3JtZWQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTAubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gZXBraSA9IG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbygKKyAgICAgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5hbGdOYW1lMFtpXVswXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5lbmNyeXB0ZWREYXRhKTsKKworICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgbWV0aG9kIHVuZGVyIHRlc3QgcmV0dXJucworICAgICAgICAgICAgICAgIC8vIHZhbGlkIGVuY29kZWQgZm9ybQorICAgICAgICAgICAgICAgIGJ5dGVbXSByZWZFbmMgPSBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRWYWxpZEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRW5jb2RpbmcoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5hbGdOYW1lMFtpXVswXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOworICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihBcnJheS50b1N0cmluZyhyZWZFbmMsICIgIikpOworICAgICAgICAgICAgICAgIGJ5dGVbXSBhY3RFbmMgPSBlcGtpLmdldEVuY29kZWQoKTsKKyAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oQXJyYXkudG9TdHJpbmcoYWN0RW5jLCAiICIpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMocmVmRW5jLCBhY3RFbmMpKTsKKworICAgICAgICAgICAgICAgIHBlcmZvcm1lZCA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IG5vdCBwZXJmb3JtZWQiLCBwZXJmb3JtZWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzMgZm9yIDxjb2RlPmdldEVuY29kZWQoKTwvY29kZT4gbWV0aG9kIDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgdGhlIEFTTi4xIGVuY29kaW5nIG9mIHRoaXMgb2JqZWN0IDxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHRlc3Qgb2JqZWN0IGNyZWF0ZWQgdXNpbmcgY3RvciB3aGljaCB0YWtlcyBhbGdvcml0aG0KKyAgICAgKiBuYW1lIGFuZCBlbmNyeXB0ZWQgZGF0YSBhcyBhIHBhcmFtZXRlcnMgPGJyPgorICAgICAqIEV4cGVjdGVkOiBlcXVpdmFsZW50IGVuY29kZWQgZm9ybSAod2l0aG91dCBhbGcgcGFyYW1zKSBtdXN0IGJlIHJldHVybmVkCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEVuY29kZWQwMygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gcGVyZm9ybWVkID0gZmFsc2U7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmFsZ05hbWUwLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlcnMgYXAgPSBBbGdvcml0aG1QYXJhbWV0ZXJzCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2UoRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmFsZ05hbWUwW2ldWzBdKTsKKyAgICAgICAgICAgICAgICAvLyB1c2UgcHJlZ2VuZXJhdGVkIEFsZ29yaXRobVBhcmFtZXRlcnMgZW5jb2RpbmdzCisgICAgICAgICAgICAgICAgYXAuaW5pdChFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuZ2V0UGFyYW1ldGVyc0VuY29kaW5nKAorICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmFsZ05hbWUwW2ldWzBdKSk7CisKKyAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyBlcGtpID0gbmV3IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKGFwLAorICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmVuY3J5cHRlZERhdGEpOworCisgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCBtZXRob2QgdW5kZXIgdGVzdCByZXR1cm5zCisgICAgICAgICAgICAgICAgLy8gdmFsaWQgZW5jb2RlZCBmb3JtCisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldFZhbGlkRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9FbmNvZGluZygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmFsZ05hbWUwW2ldWzBdKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXBraS5nZXRFbmNvZGVkKCkpKTsKKworICAgICAgICAgICAgICAgIHBlcmZvcm1lZCA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IG5vdCBwZXJmb3JtZWQiLCBwZXJmb3JtZWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzQgZm9yIDxjb2RlPmdldEVuY29kZWQoKTwvY29kZT4gbWV0aG9kIDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgYSBuZXcgYXJyYXkgZWFjaCB0aW1lIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCA8YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiB0ZXN0IG9iamVjdCBjcmVhdGVkIHVzaW5nIGN0b3Igd2hpY2ggdGFrZXMgYWxnb3JpdGhtCisgICAgICogbmFtZSBhbmQgZW5jcnlwdGVkIGRhdGEgYXMgYSBwYXJhbWV0ZXJzIDxicj4KKyAgICAgKiBFeHBlY3RlZDogc2V2ZXJhbCByZWZzIHRvIGJ5dGUgYXJyYXkgcmV0dXJuZWQgYnkgdGhlIG1ldGhvZCB1bmRlciB0ZXN0CisgICAgICogbXVzdCBiZSBkaWZmZXJlbnQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0RW5jb2RlZDA0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYm9vbGVhbiBwZXJmb3JtZWQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTAubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gZXBraSA9IG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbygKKyAgICAgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5hbGdOYW1lMFtpXVswXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5lbmNyeXB0ZWREYXRhKTsKKworICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgbWV0aG9kIHVuZGVyIHRlc3QgcmV0dXJucworICAgICAgICAgICAgICAgIC8vIG5ldyBhcnJheSBlYWNoIHRpbWUKKyAgICAgICAgICAgICAgICBieXRlW10gZWMxID0gZXBraS5nZXRFbmNvZGVkKCk7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGVjMiA9IGVwa2kuZ2V0RW5jb2RlZCgpOworICAgICAgICAgICAgICAgIGJ5dGVbXSBlYzMgPSBlcGtpLmdldEVuY29kZWQoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3RTYW1lKGVjMSwgZWMyKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3RTYW1lKGVjMiwgZWMzKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3RTYW1lKGVjMSwgZWMzKTsKKworICAgICAgICAgICAgICAgIHBlcmZvcm1lZCA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IG5vdCBwZXJmb3JtZWQiLCBwZXJmb3JtZWQpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRLZXlTcGVjQ2lwaGVyMDEoKSB7CisgICAgICAgIGJvb2xlYW4gcGVyZm9ybWVkID0gZmFsc2U7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmFsZ05hbWUwLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIGVwa2kgPSBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oCisgICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTBbaV1bMF0sCisgICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuZW5jcnlwdGVkRGF0YSk7CisKKyAgICAgICAgICAgICAgICB0cnkgeworCisgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgbWV0aG9kIHVuZGVyIHRlc3QgdGhyb3dzIE5QRQorICAgICAgICAgICAgICAgICAgICBlcGtpLmdldEtleVNwZWMoKENpcGhlcikgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIk51bGxQb2ludGVyRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG9rKSB7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleVNwZWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHBlcmZvcm1lZCA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IG5vdCBwZXJmb3JtZWQiLCBwZXJmb3JtZWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuY3J5cHRlZCBkYXRhIGNvbnRhaW5zIHZhbGlkIFBLQ1M4IGtleSBpbmZvIGVuY29kaW5nCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF9ST1VORFRSSVBfR2V0S2V5U3BlY0NpcGhlcjAxKCkgeworICAgICAgICBib29sZWFuIHBlcmZvcm1lZCA9IGZhbHNlOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxnTmFtZS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAvLyBnZW5lcmF0ZSB0ZXN0IGRhdGEKKyAgICAgICAgICAgICAgICBUZXN0RGF0YUdlbmVyYXRvciBnID0gbmV3IFRlc3REYXRhR2VuZXJhdG9yKGFsZ05hbWVbaV1bMF0sCisgICAgICAgICAgICAgICAgICAgICAgICBhbGdOYW1lW2ldWzFdLCBwcml2YXRlS2V5SW5mbywgbnVsbCk7CisKKyAgICAgICAgICAgICAgICAvLyBjcmVhdGUgdGVzdCBvYmplY3QKKyAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyBlcGtpOworICAgICAgICAgICAgICAgIGlmIChnLmFwKCkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBlcGtpID0gbmV3IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKGFsZ05hbWVbaV1bMF0sIGcuY3QoKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZXBraSA9IG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhnLmFwKCksIGcuY3QoKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gY2FsbCBtZXRob2RzIHVuZGVyIHRlc3QKKyAgICAgICAgICAgICAgICB0cnkgeworCisgICAgICAgICAgICAgICAgICAgIFBLQ1M4RW5jb2RlZEtleVNwZWMgZWtzID0gZXBraS5nZXRLZXlTcGVjKGcuYygpKTsKKworICAgICAgICAgICAgICAgICAgICBpZiAoIUFycmF5cy5lcXVhbHMocHJpdmF0ZUtleUluZm8sIGVrcy5nZXRFbmNvZGVkKCkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKGFsZ05hbWVbaV1bMF0gKyAiICE9ICIgKyBhbGdOYW1lW2ldWzFdKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbChhbGdOYW1lW2ldWzBdICsgIiwgIiArIGFsZ05hbWVbaV1bMV0gKyBlICsgIlxuIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHBlcmZvcm1lZCA9IHRydWU7CisKKyAgICAgICAgICAgIH0gY2F0Y2ggKFRlc3REYXRhR2VuZXJhdG9yLkFsbG93ZWRGYWlsdXJlIGFsbG93ZWRGYWlsdXJlKSB7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYWxsb3dlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlRlc3Qgbm90IHBlcmZvcm1lZCIsIHBlcmZvcm1lZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jcnlwdGVkIGRhdGEgY29udGFpbnMgaW52YWxpZCBQS0NTOCBrZXkgaW5mbyBlbmNvZGluZworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfUk9VTkRUUklQX0dldEtleVNwZWNDaXBoZXIwMigpIHsKKyAgICAgICAgYm9vbGVhbiBwZXJmb3JtZWQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGdOYW1lLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIGdlbmVyYXRlIHRlc3QgZGF0YQorICAgICAgICAgICAgICAgIFRlc3REYXRhR2VuZXJhdG9yIGcgPSBuZXcgVGVzdERhdGFHZW5lcmF0b3IoYWxnTmFtZVtpXVswXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGFsZ05hbWVbaV1bMV0sIHByaXZhdGVLZXlJbmZvRGFtYWdlZCwgbnVsbCk7CisKKyAgICAgICAgICAgICAgICAvLyBjcmVhdGUgdGVzdCBvYmplY3QKKyAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyBlcGtpOworICAgICAgICAgICAgICAgIGlmIChnLmFwKCkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBlcGtpID0gbmV3IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKGFsZ05hbWVbaV1bMF0sIGcuY3QoKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZXBraSA9IG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhnLmFwKCksIGcuY3QoKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gY2FsbCBtZXRob2RzIHVuZGVyIHRlc3QKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBlcGtpLmdldEtleVNwZWMoZy5jKCkpOworCisgICAgICAgICAgICAgICAgICAgIC8vIG11c3Qgbm90IGdldCBoZXJlIGJlY2F1c2UgZGVjcnlwdGVkIGRhdGEgZG9lcworICAgICAgICAgICAgICAgICAgICAvLyBub3QgcmVwcmVzZW50IHZhbGlkIFBLQ1M4IGVuY29kaW5nCisgICAgICAgICAgICAgICAgICAgIGZhaWwoYWxnTmFtZVtpXVswXSArICIsICIgKyBhbGdOYW1lW2ldWzFdKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiBvaykgeworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHBlcmZvcm1lZCA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChUZXN0RGF0YUdlbmVyYXRvci5BbGxvd2VkRmFpbHVyZSBhbGxvd2VkRmFpbHVyZSkgeworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGFsbG93ZWRGYWlsdXJlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCBub3QgcGVyZm9ybWVkIiwgcGVyZm9ybWVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0S2V5U3BlY0tleTAxKCkgeworICAgICAgICBib29sZWFuIHBlcmZvcm1lZCA9IGZhbHNlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5hbGdOYW1lMC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyBlcGtpID0gbmV3IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKAorICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmFsZ05hbWUwW2ldWzBdLAorICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmVuY3J5cHRlZERhdGEpOworCisgICAgICAgICAgICAgICAgdHJ5IHsKKworICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IG1ldGhvZCB1bmRlciB0ZXN0IHRocm93cyBOUEUKKyAgICAgICAgICAgICAgICAgICAgZXBraS5nZXRLZXlTcGVjKChLZXkpIG51bGwpOworICAgICAgICAgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICJOdWxsUG9pbnRlckV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBvaykgeworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHBlcmZvcm1lZCA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IG5vdCBwZXJmb3JtZWQiLCBwZXJmb3JtZWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuY3J5cHRlZCBkYXRhIGNvbnRhaW5zIHZhbGlkIFBLQ1M4IGtleSBpbmZvIGVuY29kaW5nCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF9ST1VORFRSSVBfR2V0S2V5U3BlY0tleTAxKCkgeworICAgICAgICBib29sZWFuIHBlcmZvcm1lZCA9IGZhbHNlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsZ05hbWUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgLy8gZ2VuZXJhdGUgdGVzdCBkYXRhCisgICAgICAgICAgICAgICAgVGVzdERhdGFHZW5lcmF0b3IgZyA9IG5ldyBUZXN0RGF0YUdlbmVyYXRvcihhbGdOYW1lW2ldWzBdLAorICAgICAgICAgICAgICAgICAgICAgICAgYWxnTmFtZVtpXVsxXSwgcHJpdmF0ZUtleUluZm8sIG51bGwpOworCisgICAgICAgICAgICAgICAgLy8gY3JlYXRlIHRlc3Qgb2JqZWN0CisgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gZXBraTsKKyAgICAgICAgICAgICAgICBpZiAoZy5hcCgpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgZXBraSA9IG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhhbGdOYW1lW2ldWzBdLCBnLmN0KCkpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGVwa2kgPSBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oZy5hcCgpLCBnLmN0KCkpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFBLQ1M4RW5jb2RlZEtleVNwZWMgZWtzID0gZXBraQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRLZXlTcGVjKGcucHViSygpID09IG51bGwgPyBnLmsoKSA6IGcucHViSygpKTsKKworICAgICAgICAgICAgICAgICAgICBpZiAoIUFycmF5cy5lcXVhbHMocHJpdmF0ZUtleUluZm8sIGVrcy5nZXRFbmNvZGVkKCkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKGFsZ05hbWVbaV1bMF0gKyAiICE9ICIgKyBhbGdOYW1lW2ldWzFdKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKGFsZ05hbWVbaV1bMF0gKyAiLCAiICsgYWxnTmFtZVtpXVsxXSArICI6ICIgKyBlKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBwZXJmb3JtZWQgPSB0cnVlOworICAgICAgICAgICAgfSBjYXRjaCAoVGVzdERhdGFHZW5lcmF0b3IuQWxsb3dlZEZhaWx1cmUgYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBhbGxvd2VkRmFpbHVyZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlRlc3Qgbm90IHBlcmZvcm1lZCIsIHBlcmZvcm1lZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jcnlwdGVkIGRhdGEgY29udGFpbnMgaW52YWxpZCBQS0NTOCBrZXkgaW5mbyBlbmNvZGluZworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfUk9VTkRUUklQX0dldEtleVNwZWNLZXkwMigpIHsKKyAgICAgICAgYm9vbGVhbiBwZXJmb3JtZWQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGdOYW1lLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIGdlbmVyYXRlIHRlc3QgZGF0YQorICAgICAgICAgICAgICAgIFRlc3REYXRhR2VuZXJhdG9yIGcgPSBuZXcgVGVzdERhdGFHZW5lcmF0b3IoYWxnTmFtZVtpXVswXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGFsZ05hbWVbaV1bMV0sIHByaXZhdGVLZXlJbmZvRGFtYWdlZCwgbnVsbCk7CisKKyAgICAgICAgICAgICAgICAvLyBjcmVhdGUgdGVzdCBvYmplY3QKKyAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyBlcGtpOworICAgICAgICAgICAgICAgIGlmIChnLmFwKCkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBlcGtpID0gbmV3IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKGFsZ05hbWVbaV1bMF0sIGcuY3QoKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZXBraSA9IG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhnLmFwKCksIGcuY3QoKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZXBraS5nZXRLZXlTcGVjKGcucHViSygpID09IG51bGwgPyBnLmsoKSA6IGcucHViSygpKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbChhbGdOYW1lW2ldWzBdICsgIiwgIiArIGFsZ05hbWVbaV1bMV0pOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHBlcmZvcm1lZCA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChUZXN0RGF0YUdlbmVyYXRvci5BbGxvd2VkRmFpbHVyZSBhbGxvd2VkRmFpbHVyZSkgeworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGFsbG93ZWRGYWlsdXJlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCBub3QgcGVyZm9ybWVkIiwgcGVyZm9ybWVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0S2V5U3BlY0tleVN0cmluZzAxKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gcGVyZm9ybWVkID0gZmFsc2U7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmFsZ05hbWUwLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIGVwa2kgPSBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oCisgICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTBbaV1bMF0sCisgICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuZW5jcnlwdGVkRGF0YSk7CisKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IG1ldGhvZCB1bmRlciB0ZXN0IHRocm93cyBOUEUKKyAgICAgICAgICAgICAgICAgICAgZXBraS5nZXRLZXlTcGVjKChLZXkpIG51bGwsICJTb21lUHJvdmlkZXJOYW1lIik7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIk51bGxQb2ludGVyRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG9rKSB7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZXBraS5nZXRLZXlTcGVjKG5ldyBLZXkoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gImFsZyI7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiZm10IjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVtdIHt9OworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9LCAiU3RyYW5nZVByb3ZpZGVyTmFtZSIpOworICAgICAgICAgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICJOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gb2spIHsKKyAgICAgICAgICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCBtZXRob2QgdW5kZXIgdGVzdCB0aHJvd3MgTlBFCisgICAgICAgICAgICAgICAgICAgIGVwa2kuZ2V0S2V5U3BlYyhuZXcgS2V5KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJhbGciOworICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gImZtdCI7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7fTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSwgKFN0cmluZykgbnVsbCk7CisKKyAgICAgICAgICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiTnVsbFBvaW50ZXJFeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworCisgICAgICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gb2spIHsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBwZXJmb3JtZWQgPSB0cnVlOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGFsbG93ZWRGYWlsdXJlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCBub3QgcGVyZm9ybWVkIiwgcGVyZm9ybWVkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmNyeXB0ZWQgZGF0YSBjb250YWlucyB2YWxpZCBQS0NTOCBrZXkgaW5mbyBlbmNvZGluZworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfUk9VTkRUUklQX0dldEtleVNwZWNLZXlTdHJpbmcwMSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBib29sZWFuIHBlcmZvcm1lZCA9IGZhbHNlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsZ05hbWUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGwgPSAwOyBsIDwgcHJvdmlkZXIubGVuZ3RoOyBsKyspIHsKKyAgICAgICAgICAgICAgICBpZiAocHJvdmlkZXJbbF0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgVGVzdERhdGFHZW5lcmF0b3IgZzsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAvLyBnZW5lcmF0ZSB0ZXN0IGRhdGEKKyAgICAgICAgICAgICAgICAgICAgZyA9IG5ldyBUZXN0RGF0YUdlbmVyYXRvcihhbGdOYW1lW2ldWzBdLCBhbGdOYW1lW2ldWzFdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaXZhdGVLZXlJbmZvLCBwcm92aWRlcltsXSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVGVzdERhdGFHZW5lcmF0b3IuQWxsb3dlZEZhaWx1cmUgYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgLy8gY3JlYXRlIHRlc3Qgb2JqZWN0CisgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIGVwa2k7CisgICAgICAgICAgICAgICAgICAgIGlmIChnLmFwKCkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZXBraSA9IG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhhbGdOYW1lW2ldWzBdLCBnCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jdCgpKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGVwa2kgPSBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oZy5hcCgpLCBnLmN0KCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIFBLQ1M4RW5jb2RlZEtleVNwZWMgZWtzID0gZXBraS5nZXRLZXlTcGVjKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnLnB1YksoKSA9PSBudWxsID8gZy5rKCkgOiBnLnB1YksoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXJbbF0uZ2V0TmFtZSgpKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFBcnJheXMuZXF1YWxzKHByaXZhdGVLZXlJbmZvLCBla3MuZ2V0RW5jb2RlZCgpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoYWxnTmFtZVtpXVswXSArICIgIT0gIiArIGFsZ05hbWVbaV1bMV0pOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoYWxnTmFtZVtpXVswXSArICIsICIgKyBhbGdOYW1lW2ldWzFdICsgIjogIiArIGUpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgcGVyZm9ybWVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCBub3QgcGVyZm9ybWVkIiwgcGVyZm9ybWVkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmNyeXB0ZWQgZGF0YSBjb250YWlucyBpbnZhbGlkIFBLQ1M4IGtleSBpbmZvIGVuY29kaW5nCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF9ST1VORFRSSVBfR2V0S2V5U3BlY0tleVN0cmluZzAyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gcGVyZm9ybWVkID0gZmFsc2U7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxnTmFtZS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgbCA9IDA7IGwgPCBwcm92aWRlci5sZW5ndGg7IGwrKykgeworICAgICAgICAgICAgICAgIGlmIChwcm92aWRlcltsXSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBUZXN0RGF0YUdlbmVyYXRvciBnOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGdlbmVyYXRlIHRlc3QgZGF0YQorICAgICAgICAgICAgICAgICAgICBnID0gbmV3IFRlc3REYXRhR2VuZXJhdG9yKGFsZ05hbWVbaV1bMF0sIGFsZ05hbWVbaV1bMV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpdmF0ZUtleUluZm9EYW1hZ2VkLCBwcm92aWRlcltsXSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVGVzdERhdGFHZW5lcmF0b3IuQWxsb3dlZEZhaWx1cmUgYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgLy8gY3JlYXRlIHRlc3Qgb2JqZWN0CisgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIGVwa2k7CisgICAgICAgICAgICAgICAgICAgIGlmIChnLmFwKCkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZXBraSA9IG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhhbGdOYW1lW2ldWzBdLCBnCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jdCgpKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGVwa2kgPSBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oZy5hcCgpLCBnLmN0KCkpOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKworICAgICAgICAgICAgICAgICAgICAgICAgZXBraS5nZXRLZXlTcGVjKGcucHViSygpID09IG51bGwgPyBnLmsoKSA6IGcucHViSygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm92aWRlcltsXS5nZXROYW1lKCkpOworCisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKGFsZ05hbWVbaV1bMF0gKyAiLCAiICsgYWxnTmFtZVtpXVsxXSk7CisKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBwZXJmb3JtZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBhbGxvd2VkRmFpbHVyZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IG5vdCBwZXJmb3JtZWQiLCBwZXJmb3JtZWQpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRLZXlTcGVjS2V5UHJvdmlkZXIwMSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBib29sZWFuIHBlcmZvcm1lZCA9IGZhbHNlOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmFsZ05hbWUwLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIGVwa2kgPSBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oCisgICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuYWxnTmFtZTBbaV1bMF0sCisgICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEuZW5jcnlwdGVkRGF0YSk7CisKKyAgICAgICAgICAgICAgICB0cnkgeworCisgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgbWV0aG9kIHVuZGVyIHRlc3QgdGhyb3dzIE5QRQorICAgICAgICAgICAgICAgICAgICBlcGtpLmdldEtleVNwZWMoKEtleSkgbnVsbCwgKFByb3ZpZGVyKSBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiTnVsbFBvaW50ZXJFeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG9rKSB7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKworICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IG1ldGhvZCB1bmRlciB0ZXN0IHRocm93cyBOUEUKKyAgICAgICAgICAgICAgICAgICAgZXBraS5nZXRLZXlTcGVjKG5ldyBLZXkoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gImFsZyI7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiZm10IjsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVtdIHt9OworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9LCAoUHJvdmlkZXIpIG51bGwpOworCisgICAgICAgICAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIk51bGxQb2ludGVyRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBvaykgeworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHBlcmZvcm1lZCA9IHRydWU7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IG5vdCBwZXJmb3JtZWQiLCBwZXJmb3JtZWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuY3J5cHRlZCBkYXRhIGNvbnRhaW5zIHZhbGlkIFBLQ1M4IGtleSBpbmZvIGVuY29kaW5nCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF9ST1VORFRSSVBfR2V0S2V5U3BlY0tleVByb3ZpZGVyMDEoKSB7CisgICAgICAgIGJvb2xlYW4gcGVyZm9ybWVkID0gZmFsc2U7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGdOYW1lLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGludCBsID0gMDsgbCA8IHByb3ZpZGVyLmxlbmd0aDsgbCsrKSB7CisgICAgICAgICAgICAgICAgaWYgKHByb3ZpZGVyW2xdID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIFRlc3REYXRhR2VuZXJhdG9yIGc7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgLy8gZ2VuZXJhdGUgdGVzdCBkYXRhCisgICAgICAgICAgICAgICAgICAgIGcgPSBuZXcgVGVzdERhdGFHZW5lcmF0b3IoYWxnTmFtZVtpXVswXSwgYWxnTmFtZVtpXVsxXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlS2V5SW5mbywgcHJvdmlkZXJbbF0pOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFRlc3REYXRhR2VuZXJhdG9yLkFsbG93ZWRGYWlsdXJlIGFsbG93ZWRGYWlsdXJlKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAvLyBjcmVhdGUgdGVzdCBvYmplY3QKKyAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gZXBraTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGcuYXAoKSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBlcGtpID0gbmV3IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKGFsZ05hbWVbaV1bMF0sIGcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmN0KCkpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgZXBraSA9IG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhnLmFwKCksIGcuY3QoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKworICAgICAgICAgICAgICAgICAgICAgICAgUEtDUzhFbmNvZGVkS2V5U3BlYyBla3MgPSBlcGtpLmdldEtleVNwZWMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGcucHViSygpID09IG51bGwgPyBnLmsoKSA6IGcucHViSygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm92aWRlcltsXSk7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICghQXJyYXlzLmVxdWFscyhwcml2YXRlS2V5SW5mbywgZWtzLmdldEVuY29kZWQoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKGFsZ05hbWVbaV1bMF0gKyAiICE9ICIgKyBhbGdOYW1lW2ldWzFdKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKGFsZ05hbWVbaV1bMF0gKyAiLCAiICsgYWxnTmFtZVtpXVsxXSArICI6ICIgKyBlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBwZXJmb3JtZWQgPSB0cnVlOworCisgICAgICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGFsbG93ZWRGYWlsdXJlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlRlc3Qgbm90IHBlcmZvcm1lZCIsIHBlcmZvcm1lZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jcnlwdGVkIGRhdGEgY29udGFpbnMgaW52YWxpZCBQS0NTOCBrZXkgaW5mbyBlbmNvZGluZworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfUk9VTkRUUklQX0dldEtleVNwZWNLZXlQcm92aWRlcjAyKCkgeworICAgICAgICBib29sZWFuIHBlcmZvcm1lZCA9IGZhbHNlOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxnTmFtZS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgbCA9IDA7IGwgPCBwcm92aWRlci5sZW5ndGg7IGwrKykgeworICAgICAgICAgICAgICAgIGlmIChwcm92aWRlcltsXSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBUZXN0RGF0YUdlbmVyYXRvciBnOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGdlbmVyYXRlIHRlc3QgZGF0YQorICAgICAgICAgICAgICAgICAgICBnID0gbmV3IFRlc3REYXRhR2VuZXJhdG9yKGFsZ05hbWVbaV1bMF0sIGFsZ05hbWVbaV1bMV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpdmF0ZUtleUluZm9EYW1hZ2VkLCBwcm92aWRlcltsXSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVGVzdERhdGFHZW5lcmF0b3IuQWxsb3dlZEZhaWx1cmUgYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgLy8gY3JlYXRlIHRlc3Qgb2JqZWN0CisgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIGVwa2k7CisgICAgICAgICAgICAgICAgICAgIGlmIChnLmFwKCkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZXBraSA9IG5ldyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyhhbGdOYW1lW2ldWzBdLCBnCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jdCgpKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGVwa2kgPSBuZXcgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8oZy5hcCgpLCBnLmN0KCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIGVwa2kuZ2V0S2V5U3BlYyhnLnB1YksoKSA9PSBudWxsID8gZy5rKCkgOiBnLnB1YksoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXJbbF0pOworCisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKGFsZ05hbWVbaV1bMF0gKyAiLCAiICsgYWxnTmFtZVtpXVsxXSk7CisKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcGVyZm9ybWVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gYWxsb3dlZEZhaWx1cmUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCBub3QgcGVyZm9ybWVkIiwgcGVyZm9ybWVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFRlc3REYXRhR2VuZXJhdG9yIHsKKworICAgICAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEFsbG93ZWRGYWlsdXJlIGV4dGVuZHMgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIEFsbG93ZWRGYWlsdXJlKFN0cmluZyBtc2cpIHsKKyAgICAgICAgICAgICAgICBzdXBlcihtc2cpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBDaXBoZXIgYyA9IG51bGw7CisKKyAgICAgICAgcHJpdmF0ZSBLZXkgayA9IG51bGwsIHB1YksgPSBudWxsOworCisgICAgICAgIHByaXZhdGUgQWxnb3JpdGhtUGFyYW1ldGVycyBhcCA9IG51bGw7CisKKyAgICAgICAgYnl0ZVtdIGN0OworCisgICAgICAgIHB1YmxpYyBUZXN0RGF0YUdlbmVyYXRvcihTdHJpbmcgYWxnTmFtZSwgU3RyaW5nIHRyYW5zZm9ybWF0aW9uLAorICAgICAgICAgICAgICAgIGJ5dGVbXSBwcml2YXRlS2V5SW5mbywgUHJvdmlkZXIgcHJvdmlkZXIpIHRocm93cyBBbGxvd2VkRmFpbHVyZSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGMgPSAocHJvdmlkZXIgPT0gbnVsbCkgPyBDaXBoZXIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZSh0cmFuc2Zvcm1hdGlvbiAhPSBudWxsID8gdHJhbnNmb3JtYXRpb24KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBhbGdOYW1lKSA6IENpcGhlci5nZXRJbnN0YW5jZSgKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWF0aW9uICE9IG51bGwgPyB0cmFuc2Zvcm1hdGlvbiA6IGFsZ05hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICBwcm92aWRlcik7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBbGxvd2VkRmFpbHVyZShlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hQYWRkaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWxsb3dlZEZhaWx1cmUoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEtleUdlbmVyYXRvciBrZyA9IChwcm92aWRlciA9PSBudWxsKSA/IEtleUdlbmVyYXRvcgorICAgICAgICAgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKGFsZ05hbWUpIDogS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKAorICAgICAgICAgICAgICAgICAgICAgICAgYWxnTmFtZSwgcHJvdmlkZXIpOworICAgICAgICAgICAgICAgIGsgPSBrZy5nZW5lcmF0ZUtleSgpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGsgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIEtleVBhaXJHZW5lcmF0b3Iga3BnID0gKHByb3ZpZGVyID09IG51bGwpID8gS2V5UGFpckdlbmVyYXRvcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZShhbGdOYW1lKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZShhbGdOYW1lLCBwcm92aWRlcik7CisgICAgICAgICAgICAgICAgICAgIEtleVBhaXIga3AgPSBrcGcuZ2VuS2V5UGFpcigpOworICAgICAgICAgICAgICAgICAgICBrID0ga3AuZ2V0UHJpdmF0ZSgpOworICAgICAgICAgICAgICAgICAgICBwdWJLID0ga3AuZ2V0UHVibGljKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFBCRVBhcmFtZXRlclNwZWMgcGJlUGFyYW1TcGVjID0gbnVsbDsKKyAgICAgICAgICAgIGlmIChrID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBwYmVQYXJhbVNwZWMgPSBuZXcgUEJFUGFyYW1ldGVyU3BlYyhuZXcgYnl0ZVtdIHsgMSwgMiwgMywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA0LCA1LCA2LCA3LCA4IH0sIDEwKTsKKyAgICAgICAgICAgICAgICAgICAgU2VjcmV0S2V5RmFjdG9yeSBza2YgPSAocHJvdmlkZXIgPT0gbnVsbCkgPyBTZWNyZXRLZXlGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKGFsZ05hbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBTZWNyZXRLZXlGYWN0b3J5LmdldEluc3RhbmNlKGFsZ05hbWUsIHByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICAgICAgUEJFS2V5U3BlYyBrcyA9IG5ldyBQQkVLZXlTcGVjKCIxMjM0NTY3OCIudG9DaGFyQXJyYXkoKSk7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBrID0gc2tmLmdlbmVyYXRlU2VjcmV0KGtzKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleVNwZWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFsbG93ZWRGYWlsdXJlKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFsbG93ZWRGYWlsdXJlKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKHBiZVBhcmFtU3BlYyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGMuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBrKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgaywgcGJlUGFyYW1TcGVjKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWxsb3dlZEZhaWx1cmUoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBbGxvd2VkRmFpbHVyZShlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWxsb3dlZEZhaWx1cmUoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBhcCA9IGMuZ2V0UGFyYW1ldGVycygpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGN0ID0gYy5kb0ZpbmFsKHByaXZhdGVLZXlJbmZvKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFsbG93ZWRGYWlsdXJlKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBBbGxvd2VkRmFpbHVyZShlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChCYWRQYWRkaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWxsb3dlZEZhaWx1cmUoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFsbG93ZWRGYWlsdXJlKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAvLyB0cnkgdG8gY29udmVydCBwYmVQYXJhbVNwZWMtPmFwCisgICAgICAgICAgICAgICAgaWYgKHBiZVBhcmFtU3BlYyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhcCA9IChwcm92aWRlciA9PSBudWxsKSA/IEFsZ29yaXRobVBhcmFtZXRlcnMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKGFsZ05hbWUpIDogQWxnb3JpdGhtUGFyYW1ldGVycworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2UoYWxnTmFtZSwgcHJvdmlkZXIpOworICAgICAgICAgICAgICAgICAgICAgICAgYXAuaW5pdChwYmVQYXJhbVNwZWMpOworICAgICAgICAgICAgICAgICAgICAgICAgcGJlUGFyYW1TcGVjID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvdWxkbid0IGNvbnZlcnQKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBbGxvd2VkRmFpbHVyZShlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvdWxkbid0IGNvbnZlcnQKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBbGxvd2VkRmFpbHVyZShlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoYXAgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBjLmluaXQoQ2lwaGVyLkRFQ1JZUFRfTU9ERSwgcHViSyA9PSBudWxsID8gayA6IHB1YkspOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGMuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLCBwdWJLID09IG51bGwgPyBrIDogcHViSywgYXApOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFsbG93ZWRGYWlsdXJlKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWxsb3dlZEZhaWx1cmUoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFsbG93ZWRGYWlsdXJlKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBLZXkgaygpIHsKKyAgICAgICAgICAgIHJldHVybiBrOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEtleSBwdWJLKCkgeworICAgICAgICAgICAgcmV0dXJuIHB1Yks7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgQ2lwaGVyIGMoKSB7CisgICAgICAgICAgICByZXR1cm4gYzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gY3QoKSB7CisgICAgICAgICAgICByZXR1cm4gY3Q7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgQWxnb3JpdGhtUGFyYW1ldGVycyBhcCgpIHsKKyAgICAgICAgICAgIHJldHVybiBhcDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIHZhbGlkIFByaXZhdGVLZXlJbmZvIGVuY29kaW5nCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIHByaXZhdGVLZXlJbmZvID0geyAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4ODIsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4NzcsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDAsCisgICAgICAgICAgICAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4MGQsIChieXRlKSAweDA2LCAoYnl0ZSkgMHgwOSwgKGJ5dGUpIDB4MmEsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4NDgsIChieXRlKSAweDg2LCAoYnl0ZSkgMHhmNywgKGJ5dGUpIDB4MGQsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4MDAsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDAyLCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4MzAsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDVkLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDEsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4MDAsCisgICAgICAgICAgICAoYnl0ZSkgMHhiMiwgKGJ5dGUpIDB4NGEsIChieXRlKSAweDliLCAoYnl0ZSkgMHg1YiwgKGJ5dGUpIDB4YmEsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4YzAsIChieXRlKSAweGNkLCAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4MDksCisgICAgICAgICAgICAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4NzAsIChieXRlKSAweDBiLCAoYnl0ZSkgMHg1YSwgKGJ5dGUpIDB4MWIsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4MDgsIChieXRlKSAweGY4LCAoYnl0ZSkgMHg1NSwgKGJ5dGUpIDB4NWUsCisgICAgICAgICAgICAoYnl0ZSkgMHg3YywgKGJ5dGUpIDB4MWIsIChieXRlKSAweDUwLCAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4ZWMsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4NGMsIChieXRlKSAweDU4LCAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4MmIsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4MDksIChieXRlKSAweDU5LCAoYnl0ZSkgMHhmMiwgKGJ5dGUpIDB4ZTEsCisgICAgICAgICAgICAoYnl0ZSkgMHg1ZCwgKGJ5dGUpIDB4NDMsIChieXRlKSAweDcxLCAoYnl0ZSkgMHg0ZCwgKGJ5dGUpIDB4OTIsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MWQsIChieXRlKSAweGI2LCAoYnl0ZSkgMHg2YywgKGJ5dGUpIDB4N2YsCisgICAgICAgICAgICAoYnl0ZSkgMHg1ZCwgKGJ5dGUpIDB4NDgsIChieXRlKSAweGNkLCAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4ZWMsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNywgKGJ5dGUpIDB4NGMsIChieXRlKSAweDM5LCAoYnl0ZSkgMHhiMSwgKGJ5dGUpIDB4N2IsCisgICAgICAgICAgICAoYnl0ZSkgMHhlMiwgKGJ5dGUpIDB4YmYsIChieXRlKSAweDk2LCAoYnl0ZSkgMHg3NywgKGJ5dGUpIDB4YmUsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMCwgKGJ5dGUpIDB4YTAsIChieXRlKSAweGYwLCAoYnl0ZSkgMHgyZCwgKGJ5dGUpIDB4NmIsCisgICAgICAgICAgICAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4YWEsIChieXRlKSAweDE0LCAoYnl0ZSkgMHhiYSwgKGJ5dGUpIDB4ODIsCisgICAgICAgICAgICAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4MTAsIChieXRlKSAweDliLCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4NjgsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NywgKGJ5dGUpIDB4ODEsIChieXRlKSAweDU0LCAoYnl0ZSkgMHhhMiwgKGJ5dGUpIDB4ZmEsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MSwgKGJ5dGUpIDB4OWUsIChieXRlKSAweDBhLCAoYnl0ZSkgMHgyYSwgKGJ5dGUpIDB4NTMsCisgICAgICAgICAgICAoYnl0ZSkgMHhhNiwgKGJ5dGUpIDB4ZTcsIChieXRlKSAweDllLCAoYnl0ZSkgMHg3ZCwgKGJ5dGUpIDB4MjksCisgICAgICAgICAgICAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4ZDgsIChieXRlKSAweDA1LCAoYnl0ZSkgMHhmYywgKGJ5dGUpIDB4MDIsCisgICAgICAgICAgICAoYnl0ZSkgMHgzZiwgKGJ5dGUpIDB4YmQsIChieXRlKSAweGM3LCAoYnl0ZSkgMHg2ZSwgKGJ5dGUpIDB4ZWQsCisgICAgICAgICAgICAoYnl0ZSkgMHhhYSwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDZjLCAoYnl0ZSkgMHg1ZiwgKGJ5dGUpIDB4NTIsCisgICAgICAgICAgICAoYnl0ZSkgMHhlZCwgKGJ5dGUpIDB4MzUsIChieXRlKSAweDY1LCAoYnl0ZSkgMHg0YiwgKGJ5dGUpIDB4MGUsCisgICAgICAgICAgICAoYnl0ZSkgMHhjOCwgKGJ5dGUpIDB4YTcsIChieXRlKSAweDEyLCAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4NTYsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNywgKGJ5dGUpIDB4YWYsIChieXRlKSAweDExLCAoYnl0ZSkgMHhmYSwgKGJ5dGUpIDB4MjEsCisgICAgICAgICAgICAoYnl0ZSkgMHgwZSwgKGJ5dGUpIDB4OTksIChieXRlKSAweGZmLCAoYnl0ZSkgMHhmYSwgKGJ5dGUpIDB4OGMsCisgICAgICAgICAgICAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4OGUsIChieXRlKSAweDZkLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDMsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4ODEsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4NzgsIChieXRlKSAweDQxLCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4NDAsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MCwgKGJ5dGUpIDB4NTksIChieXRlKSAweDk2LCAoYnl0ZSkgMHg1ZCwgKGJ5dGUpIDB4ZjMsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NCwgKGJ5dGUpIDB4M2QsIChieXRlKSAweDk5LCAoYnl0ZSkgMHhkOSwgKGJ5dGUpIDB4NGUsCisgICAgICAgICAgICAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4YzIsIChieXRlKSAweDUyLCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4OGQsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMiwgKGJ5dGUpIDB4NDksIChieXRlKSAweDBiLCAoYnl0ZSkgMHg3MywgKGJ5dGUpIDB4MWUsCisgICAgICAgICAgICAoYnl0ZSkgMHg2ZiwgKGJ5dGUpIDB4YjIsIChieXRlKSAweDMxLCAoYnl0ZSkgMHg3YywgKGJ5dGUpIDB4NjYsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4MWUsIChieXRlKSAweDdjLCAoYnl0ZSkgMHhkYywgKGJ5dGUpIDB4M2EsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMiwgKGJ5dGUpIDB4NWYsIChieXRlKSAweDUxLCAoYnl0ZSkgMHg5YSwgKGJ5dGUpIDB4MWUsCisgICAgICAgICAgICAoYnl0ZSkgMHhhNCwgKGJ5dGUpIDB4MTksIChieXRlKSAweDhkLCAoYnl0ZSkgMHhmNCwgKGJ5dGUpIDB4ZjksCisgICAgICAgICAgICAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4N2UsIChieXRlKSAweGJlLCAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4ZjcsCisgICAgICAgICAgICAoYnl0ZSkgMHhjNywgKGJ5dGUpIDB4M2MsIChieXRlKSAweDAwLCAoYnl0ZSkgMHhhMSwgKGJ5dGUpIDB4ZjksCisgICAgICAgICAgICAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDM0LCAoYnl0ZSkgMHg4ZiwgKGJ5dGUpIDB4OWMsCisgICAgICAgICAgICAoYnl0ZSkgMHhmZCwgKGJ5dGUpIDB4MGIsIChieXRlKSAweDYzLCAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4MWIsCisgICAgICAgICAgICAoYnl0ZSkgMHg3ZiwgKGJ5dGUpIDB4NDUsIChieXRlKSAweGYxLCAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4YzMsCisgICAgICAgICAgICAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4NDcsIChieXRlKSAweDVjLCAoYnl0ZSkgMHhjMSwgKGJ5dGUpIDB4YjIsCisgICAgICAgICAgICAoYnl0ZSkgMHg1ZiwgKGJ5dGUpIDB4NTcsIChieXRlKSAweGVlLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4OWYsCisgICAgICAgICAgICAoYnl0ZSkgMHg1ZSwgKGJ5dGUpIDB4MDgsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHhiYSwgKGJ5dGUpIDB4NzQsCisgICAgICAgICAgICAoYnl0ZSkgMHhiYSwgKGJ5dGUpIDB4ODEsIChieXRlKSAweGI3LCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4YWMsCisgICAgICAgICAgICAoYnl0ZSkgMHg0YywgKGJ5dGUpIDB4MDEsIChieXRlKSAweDM1LCAoYnl0ZSkgMHhjZSwgKGJ5dGUpIDB4NDYsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NywgKGJ5dGUpIDB4OGMsIChieXRlKSAweGU0LCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4MzYsCisgICAgICAgICAgICAoYnl0ZSkgMHgxYSwgKGJ5dGUpIDB4NjUsIChieXRlKSAweDBlLCAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4NTYsCisgICAgICAgICAgICAoYnl0ZSkgMHhmOSwgKGJ5dGUpIDB4YjcsIChieXRlKSAweGEwLCAoYnl0ZSkgMHhjNCwgKGJ5dGUpIDB4YjYsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDdkLCAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4NTUsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMCwgKGJ5dGUpIDB4NTIsIChieXRlKSAweDVlLCAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4NTQsCisgICAgICAgICAgICAoYnl0ZSkgMHhiZCwgKGJ5dGUpIDB4OTcsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4YmYsCisgICAgICAgICAgICAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4ZGMsIChieXRlKSAweDFiLCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4MDIsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweGU3LCAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4MDMsCisgICAgICAgICAgICAoYnl0ZSkgMHgzZSwgKGJ5dGUpIDB4MjEsIChieXRlKSAweDY0LCAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4MjQsCisgICAgICAgICAgICAoYnl0ZSkgMHg3YiwgKGJ5dGUpIDB4ZDAsIChieXRlKSAweDMxLCAoYnl0ZSkgMHhhMCwgKGJ5dGUpIDB4YTIsCisgICAgICAgICAgICAoYnl0ZSkgMHhkOSwgKGJ5dGUpIDB4ODcsIChieXRlKSAweDZkLCAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4ODEsCisgICAgICAgICAgICAoYnl0ZSkgMHg4ZiwgKGJ5dGUpIDB4OGYsIChieXRlKSAweDJkLCAoYnl0ZSkgMHg3YSwgKGJ5dGUpIDB4OTUsCisgICAgICAgICAgICAoYnl0ZSkgMHgyZSwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDlmLCAoYnl0ZSkgMHhkNywgKGJ5dGUpIDB4ODYsCisgICAgICAgICAgICAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4OTMsIChieXRlKSAweGJkLCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4N2UsCisgICAgICAgICAgICAoYnl0ZSkgMHg0ZiwgKGJ5dGUpIDB4ZGIsIChieXRlKSAweDU2LCAoYnl0ZSkgMHhmMSwgKGJ5dGUpIDB4NzUsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMCwgKGJ5dGUpIDB4NGIsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgzYSwgKGJ5dGUpIDB4ZTAsCisgICAgICAgICAgICAoYnl0ZSkgMHgyNiwgKGJ5dGUpIDB4ZjYsIChieXRlKSAweGFiLCAoYnl0ZSkgMHg5ZSwgKGJ5dGUpIDB4MGIsCisgICAgICAgICAgICAoYnl0ZSkgMHgyYSwgKGJ5dGUpIDB4ZjQsIChieXRlKSAweGE4LCAoYnl0ZSkgMHhkNywgKGJ5dGUpIDB4ZmYsCisgICAgICAgICAgICAoYnl0ZSkgMHhiZSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweGViLCAoYnl0ZSkgMHg5YiwgKGJ5dGUpIDB4ODEsCisgICAgICAgICAgICAoYnl0ZSkgMHhjNywgKGJ5dGUpIDB4NWYsIChieXRlKSAweDAyLCAoYnl0ZSkgMHg3MywgKGJ5dGUpIDB4ZTEsCisgICAgICAgICAgICAoYnl0ZSkgMHgyYiwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDQxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4YzUsCisgICAgICAgICAgICAoYnl0ZSkgMHgzZCwgKGJ5dGUpIDB4NzgsIChieXRlKSAweGFiLCAoYnl0ZSkgMHhlNiwgKGJ5dGUpIDB4YWIsCisgICAgICAgICAgICAoYnl0ZSkgMHgzZSwgKGJ5dGUpIDB4MjksIChieXRlKSAweGZkLCAoYnl0ZSkgMHg5OCwgKGJ5dGUpIDB4ZDAsCisgICAgICAgICAgICAoYnl0ZSkgMHhhNCwgKGJ5dGUpIDB4M2UsIChieXRlKSAweDU4LCAoYnl0ZSkgMHhlZSwgKGJ5dGUpIDB4NDgsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4YTMsIChieXRlKSAweDY2LCAoYnl0ZSkgMHhhYywgKGJ5dGUpIDB4ZTksCisgICAgICAgICAgICAoYnl0ZSkgMHg0ZCwgKGJ5dGUpIDB4YmQsIChieXRlKSAweDYwLCAoYnl0ZSkgMHhlYSwgKGJ5dGUpIDB4MjQsCisgICAgICAgICAgICAoYnl0ZSkgMHhmZiwgKGJ5dGUpIDB4ZWQsIChieXRlKSAweDBjLCAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4YzUsCisgICAgICAgICAgICAoYnl0ZSkgMHhmZCwgKGJ5dGUpIDB4MzYsIChieXRlKSAweDI4LCAoYnl0ZSkgMHhlYSwgKGJ5dGUpIDB4NzQsCisgICAgICAgICAgICAoYnl0ZSkgMHg4OCwgKGJ5dGUpIDB4ZDEsIChieXRlKSAweGQxLCAoYnl0ZSkgMHhhZCwgKGJ5dGUpIDB4NTgsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNywgKGJ5dGUpIDB4ZjAsIChieXRlKSAweDY3LCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4YzEsCisgICAgICAgICAgICAoYnl0ZSkgMHhlMywgKGJ5dGUpIDB4YjMsIChieXRlKSAweGRiLCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4YWQsCisgICAgICAgICAgICAoYnl0ZSkgMHhmMywgKGJ5dGUpIDB4YzQsIChieXRlKSAweDIxLCAoYnl0ZSkgMHhkOCwgKGJ5dGUpIDB4OGMsCisgICAgICAgICAgICAoYnl0ZSkgMHg0YywgKGJ5dGUpIDB4NDEsIChieXRlKSAweDI3LCAoYnl0ZSkgMHhkYiwgKGJ5dGUpIDB4ZDAsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4OTIsIChieXRlKSAweGM3LCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4NDEsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4ZTAsIChieXRlKSAweDk5LCAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4YjQsCisgICAgICAgICAgICAoYnl0ZSkgMHg3NiwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDk3LCAoYnl0ZSkgMHg1NSwgKGJ5dGUpIDB4ZjksCisgICAgICAgICAgICAoYnl0ZSkgMHhkYSwgKGJ5dGUpIDB4M2IsIChieXRlKSAweGEwLCAoYnl0ZSkgMHhkNywgKGJ5dGUpIDB4MGUsCisgICAgICAgICAgICAoYnl0ZSkgMHhkYywgKGJ5dGUpIDB4ZjQsIChieXRlKSAweDMzLCAoYnl0ZSkgMHg3ZiwgKGJ5dGUpIDB4YmQsCisgICAgICAgICAgICAoYnl0ZSkgMHhjZiwgKGJ5dGUpIDB4ZDAsIChieXRlKSAweGViLCAoYnl0ZSkgMHg2ZSwgKGJ5dGUpIDB4ODksCisgICAgICAgICAgICAoYnl0ZSkgMHhmNywgKGJ5dGUpIDB4NGYsIChieXRlKSAweDVhLCAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4N2MsCisgICAgICAgICAgICAoYnl0ZSkgMHhhOSwgKGJ5dGUpIDB4NDksIChieXRlKSAweDQ3LCAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4MzUsCisgICAgICAgICAgICAoYnl0ZSkgMHhhOCwgKGJ5dGUpIDB4MDUsIChieXRlKSAweDNkLCAoYnl0ZSkgMHhmZCwgKGJ5dGUpIDB4MDQsCisgICAgICAgICAgICAoYnl0ZSkgMHg3YiwgKGJ5dGUpIDB4MTcsIChieXRlKSAweDMxLCAoYnl0ZSkgMHgwZCwgKGJ5dGUpIDB4YzgsCisgICAgICAgICAgICAoYnl0ZSkgMHhhMywgKGJ5dGUpIDB4OTgsIChieXRlKSAweDM0LCAoYnl0ZSkgMHhhMCwgKGJ5dGUpIDB4NTAsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweGYxLCAoYnl0ZSkgMHgwYywgKGJ5dGUpIDB4ZTYsCisgICAgICAgICAgICAoYnl0ZSkgMHhlNSwgKGJ5dGUpIDB4YzQsIChieXRlKSAweDQxLCAoYnl0ZSkgMHgzZCwgKGJ5dGUpIDB4ZjgsCisgICAgICAgICAgICAoYnl0ZSkgMHgzZCwgKGJ5dGUpIDB4NGUsIChieXRlKSAweDBiLCAoYnl0ZSkgMHgxYywgKGJ5dGUpIDB4ZGIsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4NDEsIChieXRlKSAweDAwLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4OWIsCisgICAgICAgICAgICAoYnl0ZSkgMHg4YSwgKGJ5dGUpIDB4ZmQsIChieXRlKSAweGExLCAoYnl0ZSkgMHg5OCwgKGJ5dGUpIDB4NDEsCisgICAgICAgICAgICAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4YzIsIChieXRlKSAweGQxLCAoYnl0ZSkgMHhkZiwgKGJ5dGUpIDB4NGUsCisgICAgICAgICAgICAoYnl0ZSkgMHhmMywgKGJ5dGUpIDB4MmUsIChieXRlKSAweDI2LCAoYnl0ZSkgMHg1MywgKGJ5dGUpIDB4NWIsCisgICAgICAgICAgICAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4YjEsIChieXRlKSAweDdhLCAoYnl0ZSkgMHhjYywgKGJ5dGUpIDB4NWUsCisgICAgICAgICAgICAoYnl0ZSkgMHhiYiwgKGJ5dGUpIDB4MDksIChieXRlKSAweGEyLCAoYnl0ZSkgMHhlMiwgKGJ5dGUpIDB4NmYsCisgICAgICAgICAgICAoYnl0ZSkgMHg0YSwgKGJ5dGUpIDB4MDQsIChieXRlKSAweDBkLCAoYnl0ZSkgMHhlZiwgKGJ5dGUpIDB4OTAsCisgICAgICAgICAgICAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4YmUsIChieXRlKSAweDEwLCAoYnl0ZSkgMHg0YSwgKGJ5dGUpIDB4YWMsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4ZWIsIChieXRlKSAweGRhLCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4ZGIsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MywgKGJ5dGUpIDB4MDgsIChieXRlKSAweGI3LCAoYnl0ZSkgMHgyYiwgKGJ5dGUpIDB4NGMsCisgICAgICAgICAgICAoYnl0ZSkgMHhlMSwgKGJ5dGUpIDB4YmIsIChieXRlKSAweDU4LCAoYnl0ZSkgMHhjYiwgKGJ5dGUpIDB4NzEsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4YWQsIChieXRlKSAweGJjLCAoYnl0ZSkgMHhkYywgKGJ5dGUpIDB4NjIsCisgICAgICAgICAgICAoYnl0ZSkgMHg1ZSwgKGJ5dGUpIDB4M2UsIChieXRlKSAweGNiLCAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4ZGEsCisgICAgICAgICAgICAoYnl0ZSkgMHhmNiwgKGJ5dGUpIDB4ZGYsIChieXRlKSAweDAyLCAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NGQsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4OTAsIChieXRlKSAweGM1LCAoYnl0ZSkgMHg3NywgKGJ5dGUpIDB4MzAsCisgICAgICAgICAgICAoYnl0ZSkgMHhiNywgKGJ5dGUpIDB4MjksIChieXRlKSAweDAwLCAoYnl0ZSkgMHhhOCwgKGJ5dGUpIDB4ZjEsCisgICAgICAgICAgICAoYnl0ZSkgMHhiNCwgKGJ5dGUpIDB4YWUsIChieXRlKSAweDUyLCAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4MDAsCisgICAgICAgICAgICAoYnl0ZSkgMHhiMiwgKGJ5dGUpIDB4MmQsIChieXRlKSAweDNlLCAoYnl0ZSkgMHg3ZCwgKGJ5dGUpIDB4ZDYsCisgICAgICAgICAgICAoYnl0ZSkgMHg0ZCwgKGJ5dGUpIDB4ZjksIChieXRlKSAweDhhLCAoYnl0ZSkgMHhjMSwgKGJ5dGUpIDB4YjEsCisgICAgICAgICAgICAoYnl0ZSkgMHg5OCwgKGJ5dGUpIDB4ODksIChieXRlKSAweDUyLCAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4MTQsCisgICAgICAgICAgICAoYnl0ZSkgMHgxYiwgKGJ5dGUpIDB4MGUsIChieXRlKSAweDYxLCAoYnl0ZSkgMHg4ZiwgKGJ5dGUpIDB4ZjQsCisgICAgICAgICAgICAoYnl0ZSkgMHhiZSwgKGJ5dGUpIDB4NTksIChieXRlKSAweDc5LCAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4OTUsCisgICAgICAgICAgICAoYnl0ZSkgMHgxOSwgKGJ5dGUpIDB4NWMsIChieXRlKSAweDUxLCAoYnl0ZSkgMHgwOCwgKGJ5dGUpIDB4NjYsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMSwgKGJ5dGUpIDB4NDIsIChieXRlKSAweDMwLCAoYnl0ZSkgMHhiMywgKGJ5dGUpIDB4N2EsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4OWYsIChieXRlKSAweDNlLCAoYnl0ZSkgMHhmNSwgKGJ5dGUpIDB4MTksCisgICAgICAgICAgICAoYnl0ZSkgMHhhMywgKGJ5dGUpIDB4YWUsIChieXRlKSAweDY0LCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4MTQsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4NTAsIChieXRlKSAweDk3LCB9OworCisgICAgLy8gdmFsaWQgUHJpdmF0ZUtleUluZm8gZW5jb2RpbmcgKERhbWFnZWQpCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIHByaXZhdGVLZXlJbmZvRGFtYWdlZCA9IHsgKGJ5dGUpIDB4MzAsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDc3LCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDEsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDBkLCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MDksCisgICAgICAgICAgICAoYnl0ZSkgMHgyYSwgKGJ5dGUpIDB4ODYsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4ZjcsCisgICAgICAgICAgICAoYnl0ZSkgMHgwZCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDUsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDQsIC8vIHByaXZhdGUga2V5IG9jdGV0IHN0cgorICAgICAgICAgICAgKGJ5dGUpIDB4ODIsIChieXRlKSAweDAyLCAoYnl0ZSkgMHg2MiwgLy8gRGFtYWdlOiBsPTQ2MC0+NDYxCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAoMHg2MS0+MHg2MikKKyAgICAgICAgICAgIChieXRlKSAweDMwLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDVkLCAoYnl0ZSkgMHgwMiwKKyAgICAgICAgICAgIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4MSwKKyAgICAgICAgICAgIChieXRlKSAweDAwLCAoYnl0ZSkgMHhiMiwgKGJ5dGUpIDB4NGEsIChieXRlKSAweDliLCAoYnl0ZSkgMHg1YiwKKyAgICAgICAgICAgIChieXRlKSAweGJhLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4YzAsIChieXRlKSAweGNkLCAoYnl0ZSkgMHg2NSwKKyAgICAgICAgICAgIChieXRlKSAweDA5LCAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4NzAsIChieXRlKSAweDBiLCAoYnl0ZSkgMHg1YSwKKyAgICAgICAgICAgIChieXRlKSAweDFiLCAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4MDgsIChieXRlKSAweGY4LCAoYnl0ZSkgMHg1NSwKKyAgICAgICAgICAgIChieXRlKSAweDVlLCAoYnl0ZSkgMHg3YywgKGJ5dGUpIDB4MWIsIChieXRlKSAweDUwLCAoYnl0ZSkgMHgxNywKKyAgICAgICAgICAgIChieXRlKSAweGVjLCAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4NGMsIChieXRlKSAweDU4LCAoYnl0ZSkgMHg0MiwKKyAgICAgICAgICAgIChieXRlKSAweDJiLCAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4MDksIChieXRlKSAweDU5LCAoYnl0ZSkgMHhmMiwKKyAgICAgICAgICAgIChieXRlKSAweGUxLCAoYnl0ZSkgMHg1ZCwgKGJ5dGUpIDB4NDMsIChieXRlKSAweDcxLCAoYnl0ZSkgMHg0ZCwKKyAgICAgICAgICAgIChieXRlKSAweDkyLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MWQsIChieXRlKSAweGI2LCAoYnl0ZSkgMHg2YywKKyAgICAgICAgICAgIChieXRlKSAweDdmLCAoYnl0ZSkgMHg1ZCwgKGJ5dGUpIDB4NDgsIChieXRlKSAweGNkLCAoYnl0ZSkgMHgxNywKKyAgICAgICAgICAgIChieXRlKSAweGVjLCAoYnl0ZSkgMHhkNywgKGJ5dGUpIDB4NGMsIChieXRlKSAweDM5LCAoYnl0ZSkgMHhiMSwKKyAgICAgICAgICAgIChieXRlKSAweDdiLCAoYnl0ZSkgMHhlMiwgKGJ5dGUpIDB4YmYsIChieXRlKSAweDk2LCAoYnl0ZSkgMHg3NywKKyAgICAgICAgICAgIChieXRlKSAweGJlLCAoYnl0ZSkgMHhkMCwgKGJ5dGUpIDB4YTAsIChieXRlKSAweGYwLCAoYnl0ZSkgMHgyZCwKKyAgICAgICAgICAgIChieXRlKSAweDZiLCAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4YWEsIChieXRlKSAweDE0LCAoYnl0ZSkgMHhiYSwKKyAgICAgICAgICAgIChieXRlKSAweDgyLCAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4MTAsIChieXRlKSAweDliLCAoYnl0ZSkgMHgxNiwKKyAgICAgICAgICAgIChieXRlKSAweDY4LCAoYnl0ZSkgMHg0NywgKGJ5dGUpIDB4ODEsIChieXRlKSAweDU0LCAoYnl0ZSkgMHhhMiwKKyAgICAgICAgICAgIChieXRlKSAweGZhLCAoYnl0ZSkgMHg5MSwgKGJ5dGUpIDB4OWUsIChieXRlKSAweDBhLCAoYnl0ZSkgMHgyYSwKKyAgICAgICAgICAgIChieXRlKSAweDUzLCAoYnl0ZSkgMHhhNiwgKGJ5dGUpIDB4ZTcsIChieXRlKSAweDllLCAoYnl0ZSkgMHg3ZCwKKyAgICAgICAgICAgIChieXRlKSAweDI5LCAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4ZDgsIChieXRlKSAweDA1LCAoYnl0ZSkgMHhmYywKKyAgICAgICAgICAgIChieXRlKSAweDAyLCAoYnl0ZSkgMHgzZiwgKGJ5dGUpIDB4YmQsIChieXRlKSAweGM3LCAoYnl0ZSkgMHg2ZSwKKyAgICAgICAgICAgIChieXRlKSAweGVkLCAoYnl0ZSkgMHhhYSwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDZjLCAoYnl0ZSkgMHg1ZiwKKyAgICAgICAgICAgIChieXRlKSAweDUyLCAoYnl0ZSkgMHhlZCwgKGJ5dGUpIDB4MzUsIChieXRlKSAweDY1LCAoYnl0ZSkgMHg0YiwKKyAgICAgICAgICAgIChieXRlKSAweDBlLCAoYnl0ZSkgMHhjOCwgKGJ5dGUpIDB4YTcsIChieXRlKSAweDEyLCAoYnl0ZSkgMHgxMCwKKyAgICAgICAgICAgIChieXRlKSAweDU2LCAoYnl0ZSkgMHgzNywgKGJ5dGUpIDB4YWYsIChieXRlKSAweDExLCAoYnl0ZSkgMHhmYSwKKyAgICAgICAgICAgIChieXRlKSAweDIxLCAoYnl0ZSkgMHgwZSwgKGJ5dGUpIDB4OTksIChieXRlKSAweGZmLCAoYnl0ZSkgMHhmYSwKKyAgICAgICAgICAgIChieXRlKSAweDhjLCAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4OGUsIChieXRlKSAweDZkLCAoYnl0ZSkgMHgwMiwKKyAgICAgICAgICAgIChieXRlKSAweDAzLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMiwKKyAgICAgICAgICAgIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4NzgsIChieXRlKSAweDQxLCAoYnl0ZSkgMHg3MiwKKyAgICAgICAgICAgIChieXRlKSAweDQwLCAoYnl0ZSkgMHg5MCwgKGJ5dGUpIDB4NTksIChieXRlKSAweDk2LCAoYnl0ZSkgMHg1ZCwKKyAgICAgICAgICAgIChieXRlKSAweGYzLCAoYnl0ZSkgMHg4NCwgKGJ5dGUpIDB4M2QsIChieXRlKSAweDk5LCAoYnl0ZSkgMHhkOSwKKyAgICAgICAgICAgIChieXRlKSAweDRlLCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4YzIsIChieXRlKSAweDUyLCAoYnl0ZSkgMHg2MiwKKyAgICAgICAgICAgIChieXRlKSAweDhkLCAoYnl0ZSkgMHhkMiwgKGJ5dGUpIDB4NDksIChieXRlKSAweDBiLCAoYnl0ZSkgMHg3MywKKyAgICAgICAgICAgIChieXRlKSAweDFlLCAoYnl0ZSkgMHg2ZiwgKGJ5dGUpIDB4YjIsIChieXRlKSAweDMxLCAoYnl0ZSkgMHg3YywKKyAgICAgICAgICAgIChieXRlKSAweDY2LCAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4MWUsIChieXRlKSAweDdjLCAoYnl0ZSkgMHhkYywKKyAgICAgICAgICAgIChieXRlKSAweDNhLCAoYnl0ZSkgMHhjMiwgKGJ5dGUpIDB4NWYsIChieXRlKSAweDUxLCAoYnl0ZSkgMHg5YSwKKyAgICAgICAgICAgIChieXRlKSAweDFlLCAoYnl0ZSkgMHhhNCwgKGJ5dGUpIDB4MTksIChieXRlKSAweDhkLCAoYnl0ZSkgMHhmNCwKKyAgICAgICAgICAgIChieXRlKSAweGY5LCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4N2UsIChieXRlKSAweGJlLCAoYnl0ZSkgMHgxNywKKyAgICAgICAgICAgIChieXRlKSAweGY3LCAoYnl0ZSkgMHhjNywgKGJ5dGUpIDB4M2MsIChieXRlKSAweDAwLCAoYnl0ZSkgMHhhMSwKKyAgICAgICAgICAgIChieXRlKSAweGY5LCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDM0LCAoYnl0ZSkgMHg4ZiwKKyAgICAgICAgICAgIChieXRlKSAweDljLCAoYnl0ZSkgMHhmZCwgKGJ5dGUpIDB4MGIsIChieXRlKSAweDYzLCAoYnl0ZSkgMHg0MiwKKyAgICAgICAgICAgIChieXRlKSAweDFiLCAoYnl0ZSkgMHg3ZiwgKGJ5dGUpIDB4NDUsIChieXRlKSAweGYxLCAoYnl0ZSkgMHgzMSwKKyAgICAgICAgICAgIChieXRlKSAweGMzLCAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4NDcsIChieXRlKSAweDVjLCAoYnl0ZSkgMHhjMSwKKyAgICAgICAgICAgIChieXRlKSAweGIyLCAoYnl0ZSkgMHg1ZiwgKGJ5dGUpIDB4NTcsIChieXRlKSAweGVlLCAoYnl0ZSkgMHgwMiwKKyAgICAgICAgICAgIChieXRlKSAweDlmLCAoYnl0ZSkgMHg1ZSwgKGJ5dGUpIDB4MDgsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHhiYSwKKyAgICAgICAgICAgIChieXRlKSAweDc0LCAoYnl0ZSkgMHhiYSwgKGJ5dGUpIDB4ODEsIChieXRlKSAweGI3LCAoYnl0ZSkgMHgzMCwKKyAgICAgICAgICAgIChieXRlKSAweGFjLCAoYnl0ZSkgMHg0YywgKGJ5dGUpIDB4MDEsIChieXRlKSAweDM1LCAoYnl0ZSkgMHhjZSwKKyAgICAgICAgICAgIChieXRlKSAweDQ2LCAoYnl0ZSkgMHg0NywgKGJ5dGUpIDB4OGMsIChieXRlKSAweGU0LCAoYnl0ZSkgMHg2MiwKKyAgICAgICAgICAgIChieXRlKSAweDM2LCAoYnl0ZSkgMHgxYSwgKGJ5dGUpIDB4NjUsIChieXRlKSAweDBlLCAoYnl0ZSkgMHgzMywKKyAgICAgICAgICAgIChieXRlKSAweDU2LCAoYnl0ZSkgMHhmOSwgKGJ5dGUpIDB4YjcsIChieXRlKSAweGEwLCAoYnl0ZSkgMHhjNCwKKyAgICAgICAgICAgIChieXRlKSAweGI2LCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDdkLCAoYnl0ZSkgMHgzNiwKKyAgICAgICAgICAgIChieXRlKSAweDU1LCAoYnl0ZSkgMHhjMCwgKGJ5dGUpIDB4NTIsIChieXRlKSAweDVlLCAoYnl0ZSkgMHgzNSwKKyAgICAgICAgICAgIChieXRlKSAweDU0LCAoYnl0ZSkgMHhiZCwgKGJ5dGUpIDB4OTcsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMCwKKyAgICAgICAgICAgIChieXRlKSAweGJmLCAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4ZGMsIChieXRlKSAweDFiLCAoYnl0ZSkgMHg1MSwKKyAgICAgICAgICAgIChieXRlKSAweDAyLCAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweGU3LCAoYnl0ZSkgMHg2OCwKKyAgICAgICAgICAgIChieXRlKSAweDAzLCAoYnl0ZSkgMHgzZSwgKGJ5dGUpIDB4MjEsIChieXRlKSAweDY0LCAoYnl0ZSkgMHg2OCwKKyAgICAgICAgICAgIChieXRlKSAweDI0LCAoYnl0ZSkgMHg3YiwgKGJ5dGUpIDB4ZDAsIChieXRlKSAweDMxLCAoYnl0ZSkgMHhhMCwKKyAgICAgICAgICAgIChieXRlKSAweGEyLCAoYnl0ZSkgMHhkOSwgKGJ5dGUpIDB4ODcsIChieXRlKSAweDZkLCAoYnl0ZSkgMHg3OSwKKyAgICAgICAgICAgIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4ZiwgKGJ5dGUpIDB4OGYsIChieXRlKSAweDJkLCAoYnl0ZSkgMHg3YSwKKyAgICAgICAgICAgIChieXRlKSAweDk1LCAoYnl0ZSkgMHgyZSwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDlmLCAoYnl0ZSkgMHhkNywKKyAgICAgICAgICAgIChieXRlKSAweDg2LCAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4OTMsIChieXRlKSAweGJkLCAoYnl0ZSkgMHgwNCwKKyAgICAgICAgICAgIChieXRlKSAweDdlLCAoYnl0ZSkgMHg0ZiwgKGJ5dGUpIDB4ZGIsIChieXRlKSAweDU2LCAoYnl0ZSkgMHhmMSwKKyAgICAgICAgICAgIChieXRlKSAweDc1LCAoYnl0ZSkgMHhkMCwgKGJ5dGUpIDB4NGIsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgzYSwKKyAgICAgICAgICAgIChieXRlKSAweGUwLCAoYnl0ZSkgMHgyNiwgKGJ5dGUpIDB4ZjYsIChieXRlKSAweGFiLCAoYnl0ZSkgMHg5ZSwKKyAgICAgICAgICAgIChieXRlKSAweDBiLCAoYnl0ZSkgMHgyYSwgKGJ5dGUpIDB4ZjQsIChieXRlKSAweGE4LCAoYnl0ZSkgMHhkNywKKyAgICAgICAgICAgIChieXRlKSAweGZmLCAoYnl0ZSkgMHhiZSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweGViLCAoYnl0ZSkgMHg5YiwKKyAgICAgICAgICAgIChieXRlKSAweDgxLCAoYnl0ZSkgMHhjNywgKGJ5dGUpIDB4NWYsIChieXRlKSAweDAyLCAoYnl0ZSkgMHg3MywKKyAgICAgICAgICAgIChieXRlKSAweGUxLCAoYnl0ZSkgMHgyYiwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDQxLCAoYnl0ZSkgMHgwMCwKKyAgICAgICAgICAgIChieXRlKSAweGM1LCAoYnl0ZSkgMHgzZCwgKGJ5dGUpIDB4NzgsIChieXRlKSAweGFiLCAoYnl0ZSkgMHhlNiwKKyAgICAgICAgICAgIChieXRlKSAweGFiLCAoYnl0ZSkgMHgzZSwgKGJ5dGUpIDB4MjksIChieXRlKSAweGZkLCAvLyA4OAorICAgICAgICAgICAgKGJ5dGUpIDB4OTgsIChieXRlKSAweGQwLCAoYnl0ZSkgMHhhNCwgKGJ5dGUpIDB4M2UsIChieXRlKSAweDU4LAorICAgICAgICAgICAgKGJ5dGUpIDB4ZWUsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4YTMsIChieXRlKSAweDY2LAorICAgICAgICAgICAgKGJ5dGUpIDB4YWMsIChieXRlKSAweGU5LCAoYnl0ZSkgMHg0ZCwgKGJ5dGUpIDB4YmQsIChieXRlKSAweDYwLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZWEsIChieXRlKSAweDI0LCAoYnl0ZSkgMHhmZiwgKGJ5dGUpIDB4ZWQsIChieXRlKSAweDBjLAorICAgICAgICAgICAgKGJ5dGUpIDB4NjcsIChieXRlKSAweGM1LCAoYnl0ZSkgMHhmZCwgKGJ5dGUpIDB4MzYsIChieXRlKSAweDI4LAorICAgICAgICAgICAgKGJ5dGUpIDB4ZWEsIChieXRlKSAweDc0LCAoYnl0ZSkgMHg4OCwgKGJ5dGUpIDB4ZDEsIChieXRlKSAweGQxLAorICAgICAgICAgICAgKGJ5dGUpIDB4YWQsIChieXRlKSAweDU4LCAoYnl0ZSkgMHhkNywgKGJ5dGUpIDB4ZjAsIChieXRlKSAweDY3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MjAsIChieXRlKSAweGMxLCAoYnl0ZSkgMHhlMywgKGJ5dGUpIDB4YjMsIChieXRlKSAweGRiLAorICAgICAgICAgICAgKGJ5dGUpIDB4NTIsIChieXRlKSAweGFkLCAoYnl0ZSkgMHhmMywgKGJ5dGUpIDB4YzQsIChieXRlKSAweDIxLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZDgsIChieXRlKSAweDhjLCAoYnl0ZSkgMHg0YywgKGJ5dGUpIDB4NDEsIChieXRlKSAweDI3LAorICAgICAgICAgICAgKGJ5dGUpIDB4ZGIsIChieXRlKSAweGQwLCAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4OTIsIChieXRlKSAweGM3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDIsIChieXRlKSAweDQxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4ZTAsIChieXRlKSAweDk5LAorICAgICAgICAgICAgKGJ5dGUpIDB4NDIsIChieXRlKSAweGI0LCAoYnl0ZSkgMHg3NiwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDk3LAorICAgICAgICAgICAgKGJ5dGUpIDB4NTUsIChieXRlKSAweGY5LCAoYnl0ZSkgMHhkYSwgKGJ5dGUpIDB4M2IsIChieXRlKSAweGEwLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZDcsIChieXRlKSAweDBlLCAoYnl0ZSkgMHhkYywgKGJ5dGUpIDB4ZjQsIChieXRlKSAweDMzLAorICAgICAgICAgICAgKGJ5dGUpIDB4N2YsIChieXRlKSAweGJkLCAoYnl0ZSkgMHhjZiwgKGJ5dGUpIDB4ZDAsIChieXRlKSAweGViLAorICAgICAgICAgICAgKGJ5dGUpIDB4NmUsIChieXRlKSAweDg5LCAoYnl0ZSkgMHhmNywgKGJ5dGUpIDB4NGYsIChieXRlKSAweDVhLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDcsIChieXRlKSAweDdjLCAoYnl0ZSkgMHhhOSwgKGJ5dGUpIDB4NDksIChieXRlKSAweDQ3LAorICAgICAgICAgICAgKGJ5dGUpIDB4NjgsIChieXRlKSAweDM1LCAoYnl0ZSkgMHhhOCwgKGJ5dGUpIDB4MDUsIChieXRlKSAweDNkLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZmQsIChieXRlKSAweDA0LCAoYnl0ZSkgMHg3YiwgKGJ5dGUpIDB4MTcsIChieXRlKSAweDMxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MGQsIChieXRlKSAweGM4LCAoYnl0ZSkgMHhhMywgKGJ5dGUpIDB4OTgsIChieXRlKSAweDM0LAorICAgICAgICAgICAgKGJ5dGUpIDB4YTAsIChieXRlKSAweDUwLCAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweGYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MGMsIChieXRlKSAweGU2LCAoYnl0ZSkgMHhlNSwgKGJ5dGUpIDB4YzQsIChieXRlKSAweDQxLAorICAgICAgICAgICAgKGJ5dGUpIDB4M2QsIChieXRlKSAweGY4LCAoYnl0ZSkgMHgzZCwgKGJ5dGUpIDB4NGUsIChieXRlKSAweDBiLCAvLyAxMTgKKyAgICAgICAgICAgIChieXRlKSAweDFjLCAoYnl0ZSkgMHhkYiwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDQxLCAoYnl0ZSkgMHgwMCwKKyAgICAgICAgICAgIChieXRlKSAweDgyLCAoYnl0ZSkgMHg5YiwgKGJ5dGUpIDB4OGEsIChieXRlKSAweGZkLCAoYnl0ZSkgMHhhMSwKKyAgICAgICAgICAgIChieXRlKSAweDk4LCAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4NjgsIChieXRlKSAweGMyLCAoYnl0ZSkgMHhkMSwKKyAgICAgICAgICAgIChieXRlKSAweGRmLCAoYnl0ZSkgMHg0ZSwgKGJ5dGUpIDB4ZjMsIChieXRlKSAweDJlLCAoYnl0ZSkgMHgyNiwKKyAgICAgICAgICAgIChieXRlKSAweDUzLCAoYnl0ZSkgMHg1YiwgKGJ5dGUpIDB4MzEsIChieXRlKSAweGIxLCAoYnl0ZSkgMHg3YSwKKyAgICAgICAgICAgIChieXRlKSAweGNjLCAoYnl0ZSkgMHg1ZSwgKGJ5dGUpIDB4YmIsIChieXRlKSAweDA5LCAoYnl0ZSkgMHhhMiwKKyAgICAgICAgICAgIChieXRlKSAweGUyLCAoYnl0ZSkgMHg2ZiwgKGJ5dGUpIDB4NGEsIChieXRlKSAweDA0LCAoYnl0ZSkgMHgwZCwKKyAgICAgICAgICAgIChieXRlKSAweGVmLCAoYnl0ZSkgMHg5MCwgKGJ5dGUpIDB4MTUsIChieXRlKSAweGJlLCAoYnl0ZSkgMHgxMCwKKyAgICAgICAgICAgIChieXRlKSAweDRhLCAoYnl0ZSkgMHhhYywgKGJ5dGUpIDB4OTIsIChieXRlKSAweGViLCAoYnl0ZSkgMHhkYSwKKyAgICAgICAgICAgIChieXRlKSAweDcyLCAoYnl0ZSkgMHhkYiwgKGJ5dGUpIDB4NDMsIChieXRlKSAweDA4LCAoYnl0ZSkgMHhiNywKKyAgICAgICAgICAgIChieXRlKSAweDJiLCAoYnl0ZSkgMHg0YywgKGJ5dGUpIDB4ZTEsIChieXRlKSAweGJiLCAoYnl0ZSkgMHg1OCwKKyAgICAgICAgICAgIChieXRlKSAweGNiLCAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4ODAsIChieXRlKSAweGFkLCAoYnl0ZSkgMHhiYywKKyAgICAgICAgICAgIChieXRlKSAweGRjLCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4NWUsIChieXRlKSAweDNlLCAoYnl0ZSkgMHhjYiwKKyAgICAgICAgICAgIChieXRlKSAweDkyLCAoYnl0ZSkgMHhkYSwgKGJ5dGUpIDB4ZjYsIChieXRlKSAweGRmLCAoYnl0ZSkgMHgwMiwKKyAgICAgICAgICAgIChieXRlKSAweDQwLCAoYnl0ZSkgMHg0ZCwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDkwLCAoYnl0ZSkgMHhjNSwKKyAgICAgICAgICAgIChieXRlKSAweDc3LCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4YjcsIChieXRlKSAweDI5LCAoYnl0ZSkgMHgwMCwKKyAgICAgICAgICAgIChieXRlKSAweGE4LCAoYnl0ZSkgMHhmMSwgKGJ5dGUpIDB4YjQsIChieXRlKSAweGFlLCAoYnl0ZSkgMHg1MiwKKyAgICAgICAgICAgIChieXRlKSAweDYzLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4YjIsIC8vIDE0MAorICAgICAgICAgICAgKGJ5dGUpIDB4MmQsIChieXRlKSAweDNlLCAoYnl0ZSkgMHg3ZCwgKGJ5dGUpIDB4ZDYsIChieXRlKSAweDRkLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZjksIChieXRlKSAweDhhLCAoYnl0ZSkgMHhjMSwgKGJ5dGUpIDB4YjEsIChieXRlKSAweDk4LAorICAgICAgICAgICAgKGJ5dGUpIDB4ODksIChieXRlKSAweDUyLCAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4MTQsIChieXRlKSAweDFiLAorICAgICAgICAgICAgKGJ5dGUpIDB4MGUsIChieXRlKSAweDYxLCAoYnl0ZSkgMHg4ZiwgKGJ5dGUpIDB4ZjQsIChieXRlKSAweGJlLAorICAgICAgICAgICAgKGJ5dGUpIDB4NTksIChieXRlKSAweDc5LCAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4OTUsIChieXRlKSAweDE5LAorICAgICAgICAgICAgKGJ5dGUpIDB4NWMsIChieXRlKSAweDUxLCAoYnl0ZSkgMHgwOCwgKGJ5dGUpIDB4NjYsIChieXRlKSAweGMxLAorICAgICAgICAgICAgKGJ5dGUpIDB4NDIsIChieXRlKSAweDMwLCAoYnl0ZSkgMHhiMywgKGJ5dGUpIDB4N2EsIChieXRlKSAweDg2LAorICAgICAgICAgICAgKGJ5dGUpIDB4OWYsIChieXRlKSAweDNlLCAoYnl0ZSkgMHhmNSwgKGJ5dGUpIDB4MTksIChieXRlKSAweGEzLCAvLyAxNTAKKyAgICAgICAgICAgIChieXRlKSAweGFlLCAoYnl0ZSkgMHg2NCwgKGJ5dGUpIDB4NjksIChieXRlKSAweDE0LCAoYnl0ZSkgMHgwNywKKyAgICAgICAgICAgIChieXRlKSAweDUwLCAoYnl0ZSkgMHg5NywgfTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9FeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg2NmFjOTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5FeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb248L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQKKyAqIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisgICAgc3RhdGljIFRocm93YWJsZSB0Q2F1c2UgPSBuZXcgVGhyb3dhYmxlKCJUaHJvd2FibGUgZm9yIGV4Y2VwdGlvbiIpOworCisgICAgc3RhdGljIFN0cmluZyBjcmVhdGVFcnIoRXhjZXB0aW9uIHRFLCBFeGNlcHRpb24gZUUpIHsKKyAgICAgICAgcmV0dXJuICJFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb246ICIuY29uY2F0KHRFLnRvU3RyaW5nKCkpLmNvbmNhdCgKKyAgICAgICAgICAgICAgICAiIGlzIG5vdCBlcXVhbCB0byBjYXVnaHQgZXhjZXB0aW9uOiAiKS5jb25jYXQoZUUudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+RXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uKCk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbjAxKCkgeworICAgICAgICBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24gdEUgPSBuZXcgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhyb3cgdEU7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGNyZWF0ZUVycih0RSwgZSksIHRFLmVxdWFscyhlKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5FeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIHdpdGggZGV0YWlsIG1lc3NhZ2UKKyAgICAgKiBtc2cuIFBhcmFtZXRlciA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24wMigpIHsKKyAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbihtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdGhyb3cgdEU7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoY3JlYXRlRXJyKHRFLCBlKSwgdEUuZXF1YWxzKGUpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24gd2hlbiA8Y29kZT5tc2c8L2NvZGU+CisgICAgICogaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24wMygpIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9IG51bGw7CisgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiB0RSA9IG5ldyBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24obXNnKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aHJvdyB0RTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoY3JlYXRlRXJyKHRFLCBlKSwgdEUuZXF1YWxzKGUpKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0V4ZW1wdGlvbk1lY2hhbmlzbVNwaVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9FeGVtcHRpb25NZWNoYW5pc21TcGlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjM2M2U5MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9FeGVtcHRpb25NZWNoYW5pc21TcGlUZXN0LmphdmEKQEAgLTAsMCArMSwxMzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0bzsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5SU0FLZXlHZW5QYXJhbWV0ZXJTcGVjOworCitpbXBvcnQgamF2YXguY3J5cHRvLkV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2hvcnRCdWZmZXJFeGNlcHRpb247CitpbXBvcnQgamF2YXguY3J5cHRvLkV4ZW1wdGlvbk1lY2hhbmlzbVNwaTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLnN1cHBvcnQuTXlFeGVtcHRpb25NZWNoYW5pc21TcGk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+RXhlbXB0aW9uTWVjaGFuaXNtU3BpPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kCisgKiBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIEV4ZW1wdGlvbk1lY2hhbmlzbVNwaVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CitjbGFzcyBNb2NrX0V4ZW1wdGlvbk1lY2hhbmlzbVNwaSBleHRlbmRzIE15RXhlbXB0aW9uTWVjaGFuaXNtU3BpeworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVHZW5FeGVtcHRpb25CbG9iKCkgdGhyb3dzIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzdXBlci5lbmdpbmVHZW5FeGVtcHRpb25CbG9iKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBlbmdpbmVHZW5FeGVtcHRpb25CbG9iKGJ5dGVbXSBvdXRwdXQsIGludCBvdXRwdXRPZmZzZXQpIHRocm93cyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbiwgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmVuZ2luZUdlbkV4ZW1wdGlvbkJsb2Iob3V0cHV0LCBvdXRwdXRPZmZzZXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgZW5naW5lR2V0T3V0cHV0U2l6ZShpbnQgaW5wdXRMZW4pIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmVuZ2luZUdldE91dHB1dFNpemUoaW5wdXRMZW4pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXQoS2V5IGtleSkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24sIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLmVuZ2luZUluaXQoa2V5KTsKKworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXQoS2V5IGtleSwgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLCBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uLCBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24geworICAgICAgICBzdXBlci5lbmdpbmVJbml0KGtleSwgcGFyYW1zKTsKKworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXQoS2V5IGtleSwgQWxnb3JpdGhtUGFyYW1ldGVycyBwYXJhbXMpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLCBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uLCBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24geworICAgICAgICBzdXBlci5lbmdpbmVJbml0KGtleSwgcGFyYW1zKTsKKworICAgIH0KKworfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+RXhlbXB0aW9uTWVjaGFuaXNtU3BpPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246CisgICAgICogY29uc3RydWN0cyBFeGVtcHRpb25NZWNoYW5pc21TcGkKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFeGVtcHRpb25NZWNoYW5pc21TcGkwMSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNb2NrX0V4ZW1wdGlvbk1lY2hhbmlzbVNwaSBlbVNwaSA9IG5ldyBNb2NrX0V4ZW1wdGlvbk1lY2hhbmlzbVNwaSgpe307CisgICAgICAgIGludCBsZW4gPSBNeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaS5nZXRMZW5ndGgoKTsKKyAgICAgICAgYnl0ZSBbXSBiYlJlcyA9IGVtU3BpLmVuZ2luZUdlbkV4ZW1wdGlvbkJsb2IoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbGVuZ3RoIiwgYmJSZXMubGVuZ3RoLCBsZW4pOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCByZXN1bHQiLAorICAgICAgICAgICAgICAgIGVtU3BpLmVuZ2luZUdlbkV4ZW1wdGlvbkJsb2IobmV3IGJ5dGVbMV0sIGxlbiksIGxlbik7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IG91dHB1dCBzaXplIiwgMTAsIGVtU3BpLmVuZ2luZUdldE91dHB1dFNpemUoMTAwKSk7CisgICAgICAgIEtleSBrZXkgPSBudWxsOworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtcyA9IG51bGw7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyU3BlYyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbVNwaS5lbmdpbmVJbml0KGtleSk7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkS2V5RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbVNwaS5lbmdpbmVJbml0KGtleSwgcGFyYW1zKTsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWRLZXlFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVtU3BpLmVuZ2luZUluaXQoa2V5LCBwYXJTcGVjKTsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWRLZXlFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAga2V5ID0gKChNeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaSllbVNwaSkubmV3IHRtcDFLZXkoIlByb2JhIiwgbmV3IGJ5dGVbMF0pOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW1TcGkuZW5naW5lSW5pdChrZXkpOworICAgICAgICAgICAgZmFpbCgiRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVtU3BpLmVuZ2luZUluaXQoa2V5LCBwYXJhbXMpOworICAgICAgICAgICAgZmFpbCgiRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVtU3BpLmVuZ2luZUluaXQoa2V5LCBwYXJTcGVjKTsKKyAgICAgICAgICAgIGZhaWwoIkV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGtleSA9ICgoTXlFeGVtcHRpb25NZWNoYW5pc21TcGkpZW1TcGkpLm5ldyB0bXBLZXkoIlByb2JhIiwgbmV3IGJ5dGVbMF0pOworICAgICAgICBlbVNwaS5lbmdpbmVJbml0KGtleSk7CisgICAgICAgIGVtU3BpLmVuZ2luZUluaXQoa2V5LCBBbGdvcml0aG1QYXJhbWV0ZXJzLmdldEluc3RhbmNlKCJESCIpKTsKKyAgICAgICAgZW1TcGkuZW5naW5lSW5pdChrZXksIG5ldyBSU0FLZXlHZW5QYXJhbWV0ZXJTcGVjKDEwLCBuZXcgQmlnSW50ZWdlciAoIjEwIikpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCByZXN1bHQiLCAxMCwgZW1TcGkuZW5naW5lR2V0T3V0cHV0U2l6ZSgxMDApKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vRXhlbXB0aW9uTWVjaGFuaXNtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0V4ZW1wdGlvbk1lY2hhbmlzbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNjE3YWRiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0V4ZW1wdGlvbk1lY2hhbmlzbVRlc3QuamF2YQpAQCAtMCwwICsxLDU4MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0bzsKKworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLlNpZGVFZmZlY3Q7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLlJTQUtleUdlblBhcmFtZXRlclNwZWM7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKKworaW1wb3J0IGphdmF4LmNyeXB0by5FeGVtcHRpb25NZWNoYW5pc207CitpbXBvcnQgamF2YXguY3J5cHRvLkV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uRXhlbXB0aW9uTWVjaGFuaXNtU3BpOworaW1wb3J0IGphdmF4LmNyeXB0by5LZXlHZW5lcmF0b3I7CitpbXBvcnQgamF2YXguY3J5cHRvLlNob3J0QnVmZmVyRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5zdXBwb3J0Lk15RXhlbXB0aW9uTWVjaGFuaXNtU3BpOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuc3VwcG9ydC5NeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaS50bXBLZXk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuU3BpRW5nVXRpbHM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkV4ZW1wdGlvbk1lY2hhbmlzbTwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzCisgKgorICovCitwdWJsaWMgY2xhc3MgRXhlbXB0aW9uTWVjaGFuaXNtVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBzcnZFeGVtcHRpb25NZWNoYW5pc20gPSAiRXhlbXB0aW9uTWVjaGFuaXNtIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBkZWZhdWx0QWxnID0gIkVNZWNoIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFeGVtcHRpb25NZWNoYW5pc21Qcm92aWRlckNsYXNzID0gIm9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuc3VwcG9ydC5NeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaSI7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5FeGVtcHRpb25NZWNoYW5pc208L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjcmVhdGVzIG5ldyBvYmplY3QgdXNpbmcgcHJvdmlkZXIgYW5kIG1lY2hhbmlzbSBuYW1lCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEV4ZW1wdGlvbk1lY2hhbmlzbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQcm92aWRlciBtUHJvdiA9IChuZXcgU3BpRW5nVXRpbHMoKSkubmV3IE15UHJvdmlkZXIoIk15RXhNZWNoUHJvdmlkZXIiLAorICAgICAgICAgICAgICAgICJQcm92aWRlciBmb3IgRXhlbXB0aW9uTWVjaGFuaXNtIHRlc3RpbmciLAorICAgICAgICAgICAgICAgIHNydkV4ZW1wdGlvbk1lY2hhbmlzbS5jb25jYXQoIi4iKS5jb25jYXQoZGVmYXVsdEFsZyksCisgICAgICAgICAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtUHJvdmlkZXJDbGFzcyk7CisKKyAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtU3BpIHNwaSA9IG5ldyBNeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaSgpOworCisgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbSBlbSA9IG5ldyBFeGVtcHRpb25NZWNoYW5pc20oc3BpLCBtUHJvdiwgZGVmYXVsdEFsZykge307CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwgZW0uZ2V0UHJvdmlkZXIoKSwgbVByb3YpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBlbS5nZXROYW1lKCksIGRlZmF1bHRBbGcpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW0uaW5pdChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWRLZXlFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7fQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbS5nZXRPdXRwdXRTaXplKDEwMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHt9CisKKworICAgICAgICBlbSA9IG5ldyBFeGVtcHRpb25NZWNoYW5pc20obnVsbCwgbnVsbCwgbnVsbCkge307CisgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCBtZWNoYW5pc20iLCBlbS5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnROdWxsKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBlbS5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVtLmluaXQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7fQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZW0uZ2V0T3V0cHV0U2l6ZSgxMDApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7fQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4L2NyeXB0by9FeGVtcHRpb25NZWNoYW5pc20jZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKQorICAgICAqIENoZWNrcyBleGNlcHRpb24gb3JkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy9SZWdyZXNzaW9uIGZvciBIQVJNT05ZLTc2MgorICAgICAgICB0cnkgeworICAgICAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtLmdldEluc3RhbmNlKChTdHJpbmcpIG51bGwsICJhYWEiKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbS5nZXRJbnN0YW5jZSgiQWxnTmFtZSIsIChTdHJpbmcpbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmlzQ3J5cHRvQWxsb3dlZChLZXkga2V5KTwvY29kZT4gbWV0aG9kCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdElzQ3J5cHRvQWxsb3dlZCgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIC8vUmVncmVzc2lvbiBmb3IgSEFSTU9OWS0xMDI5CisgICAgICAgIFByb3ZpZGVyIG1Qcm92ID0gKG5ldyBTcGlFbmdVdGlscygpKS5uZXcgTXlQcm92aWRlcigiTXlFeE1lY2hQcm92aWRlciIsCisgICAgICAgICAgICAgICAgIlByb3ZpZGVyIGZvciBFeGVtcHRpb25NZWNoYW5pc20gdGVzdGluZyIsCisgICAgICAgICAgICAgICAgc3J2RXhlbXB0aW9uTWVjaGFuaXNtLmNvbmNhdCgiLiIpLmNvbmNhdChkZWZhdWx0QWxnKSwKKyAgICAgICAgICAgICAgICBFeGVtcHRpb25NZWNoYW5pc21Qcm92aWRlckNsYXNzKTsKKworICAgICAgICBFeGVtcHRpb25NZWNoYW5pc20gZW0gPSBuZXcgRXhlbXB0aW9uTWVjaGFuaXNtKAorICAgICAgICAgICAgICAgIG5ldyBNeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaSgpLCBtUHJvdiwgZGVmYXVsdEFsZykgeworICAgICAgICB9OworCisgICAgICAgIEtleSBrZXkgPSBuZXcgTXlFeGVtcHRpb25NZWNoYW5pc21TcGkoKS5uZXcgdG1wS2V5KCJQcm9iYSIsIG5ldyBieXRlWzBdKTsKKworICAgICAgICBhc3NlcnRGYWxzZShlbS5pc0NyeXB0b0FsbG93ZWQoa2V5KSk7CisKKyAgICAgICAgZW0uaW5pdChrZXkpOworICAgICAgICBhc3NlcnRGYWxzZShlbS5pc0NyeXB0b0FsbG93ZWQoa2V5KSk7CisKKyAgICAgICAgZW0uZ2VuRXhlbXB0aW9uQmxvYigpOworICAgICAgICBhc3NlcnRUcnVlKGVtLmlzQ3J5cHRvQWxsb3dlZChrZXkpKTsKKworICAgICAgICBLZXkga2V5MSA9IG5ldyBNeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaSgpLm5ldyB0bXBLZXkoIlByb2JhIiwKKyAgICAgICAgICAgICAgICBuZXcgYnl0ZVtdIHsgMSB9KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZW0uaXNDcnlwdG9BbGxvd2VkKGtleTEpKTsKKworICAgICAgICBlbS5pbml0KGtleTEpOworICAgICAgICBhc3NlcnRGYWxzZShlbS5pc0NyeXB0b0FsbG93ZWQoa2V5KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2VuRXhlbXB0aW9uQmxvYigoYnl0ZVtdIG91dHB1dCwgaW50IG91dHB1dE9mZnNldCk8L2NvZGU+IG1ldGhvZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5FeGVtcHRpb25CbG9iKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vUmVncmVzc2lvbiBmb3IgSEFSTU9OWS0xMDI5CisgICAgICAgIFByb3ZpZGVyIG1Qcm92ID0gKG5ldyBTcGlFbmdVdGlscygpKS5uZXcgTXlQcm92aWRlcigiTXlFeE1lY2hQcm92aWRlciIsCisgICAgICAgICAgICAgICAgIlByb3ZpZGVyIGZvciBFeGVtcHRpb25NZWNoYW5pc20gdGVzdGluZyIsCisgICAgICAgICAgICAgICAgc3J2RXhlbXB0aW9uTWVjaGFuaXNtLmNvbmNhdCgiLiIpLmNvbmNhdChkZWZhdWx0QWxnKSwKKyAgICAgICAgICAgICAgICBFeGVtcHRpb25NZWNoYW5pc21Qcm92aWRlckNsYXNzKTsKKworICAgICAgICBFeGVtcHRpb25NZWNoYW5pc20gZW0gPSBuZXcgRXhlbXB0aW9uTWVjaGFuaXNtKAorICAgICAgICAgICAgICAgIG5ldyBNeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaSgpLCBtUHJvdiwgZGVmYXVsdEFsZykgeworICAgICAgICB9OworCisgICAgICAgIEtleSBrZXkgPSBuZXcgTXlFeGVtcHRpb25NZWNoYW5pc21TcGkoKS5uZXcgdG1wS2V5KCJQcm9iYSIsIG5ldyBieXRlWzBdKTsKKworICAgICAgICBlbS5pbml0KGtleSk7CisgICAgICAgIC8vIEV4ZW1wdGlvbk1lY2hhbmlzbSBkb2Vzbid0IGNoZWNrIHBhcmFtZXRlcnMKKyAgICAgICAgLy8gaXQgaXMgYSByZXNwb25zaWJpbGl0eSBvZiBFeGVtcHRpb25NZWNoYW5pc21TcGkKKyAgICAgICAgZW0uZ2VuRXhlbXB0aW9uQmxvYihudWxsLCAwKTsKKyAgICAgICAgZW0uZ2VuRXhlbXB0aW9uQmxvYihuZXcgYnl0ZVswXSwgMCk7CisgICAgICAgIGVtLmdlbkV4ZW1wdGlvbkJsb2IobmV3IGJ5dGVbMTBdLCAtNSk7CisgICAgfQorCisgICAgc3RhdGljIGJvb2xlYW4gZmxhZyA9IGZhbHNlOworCisgICAgY2xhc3MgTW9ja19FeGVtcHRpb25NZWNoYW5pc20gZXh0ZW5kcyAgRXhlbXB0aW9uTWVjaGFuaXNtICB7CisgICAgICAgIHByb3RlY3RlZCBNb2NrX0V4ZW1wdGlvbk1lY2hhbmlzbShFeGVtcHRpb25NZWNoYW5pc21TcGkgZXhtZWNoU3BpLCBQcm92aWRlciBwcm92aWRlciwgU3RyaW5nIG1lY2hhbmlzbSkgeworICAgICAgICAgICAgc3VwZXIoZXhtZWNoU3BpLCBwcm92aWRlciwgbWVjaGFuaXNtKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHsKKyAgICAgICAgICAgIGZsYWcgPSB0cnVlOworICAgICAgICAgICAgc3VwZXIuZmluYWxpemUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBTaWRlRWZmZWN0KCJDYXVzZXMgT3V0T2ZNZW1vcnlFcnJvciB0byB0ZXN0IGZpbmFsaXphdGlvbiIpCisgICAgcHVibGljIHZvaWQgdGVzdF9maW5hbGl6ZSAoKSB7CisgICAgICAgIE1vY2tfRXhlbXB0aW9uTWVjaGFuaXNtIG1lbSA9IG5ldyBNb2NrX0V4ZW1wdGlvbk1lY2hhbmlzbShudWxsLCBudWxsLCAiTmFtZSIpOworICAgICAgICBhc3NlcnROb3ROdWxsKG1lbSk7CisgICAgICAgIG1lbSA9IG51bGw7CisgICAgICAgIGFzc2VydEZhbHNlKGZsYWcpOworICAgICAgICBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoKTsKKyAgICAgICAgaW50IGNhcGFjaXR5OworICAgICAgICB0cnkgeworICAgICAgICAgICAgd2hpbGUodHJ1ZSkgeworICAgICAgICAgICAgICAgIHYuYWRkKHRoaXMpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChPdXRPZk1lbW9yeUVycm9yIGUpIHsKKyAgICAgICAgICAgIGNhcGFjaXR5ID0gdi5zaXplKCk7CisgICAgICAgICAgICB2ID0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHYgPSBuZXcgVmVjdG9yKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2FwYWNpdHkvMjsgaSsrKSB7CisgICAgICAgICAgICB2LmFkZCh0aGlzKTsKKyAgICAgICAgfQorICAgICAgICB2ID0gbnVsbDsKKyAgICAgICAgYXNzZXJ0VHJ1ZShmbGFnKTsKKyAgICB9CisKKyAgICBjbGFzcyBNb2NrX0V4ZW1wdGlvbk1lY2hhbmlzbVNwaSBleHRlbmRzIE15RXhlbXB0aW9uTWVjaGFuaXNtU3BpIHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBieXRlW10gZW5naW5lR2VuRXhlbXB0aW9uQmxvYigpCisgICAgICAgIHRocm93cyBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24geworICAgICAgICAgICAgdGhyb3cgbmV3IEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBpbnQgZW5naW5lR2VuRXhlbXB0aW9uQmxvYihieXRlW10gb3V0cHV0LCBpbnQgb3V0cHV0T2Zmc2V0KQorICAgICAgICB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24sIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAob3V0cHV0Lmxlbmd0aCAtIG91dHB1dE9mZnNldCA8CisgICAgICAgICAgICAgICAgICAgIHN1cGVyLmVuZ2luZUdlbkV4ZW1wdGlvbkJsb2Iob3V0cHV0LCBvdXRwdXRPZmZzZXQpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNob3J0QnVmZmVyRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAob3V0cHV0W291dHB1dE9mZnNldCArIDNdID09IDMzKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVuZ2luZUdlbkV4ZW1wdGlvbkJsb2Iob3V0cHV0LCBvdXRwdXRPZmZzZXQpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZW5FeGVtcHRpb25CbG9iKCkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24sCisgICAgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvdmlkZXIgbVByb3YgPSAobmV3IFNwaUVuZ1V0aWxzKCkpLm5ldyBNeVByb3ZpZGVyKCJNeUV4TWVjaFByb3ZpZGVyIiwKKyAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yIEV4ZW1wdGlvbk1lY2hhbmlzbSB0ZXN0aW5nIiwKKyAgICAgICAgICAgICAgICBzcnZFeGVtcHRpb25NZWNoYW5pc20uY29uY2F0KCIuIikuY29uY2F0KGRlZmF1bHRBbGcpLAorICAgICAgICAgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbVByb3ZpZGVyQ2xhc3MpOworCisgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbSBlbSA9IG5ldyBFeGVtcHRpb25NZWNoYW5pc20oCisgICAgICAgICAgICAgICAgbmV3IE15RXhlbXB0aW9uTWVjaGFuaXNtU3BpKCksIG1Qcm92LCBkZWZhdWx0QWxnKSB7CisgICAgICAgIH07CisKKyAgICAgICAgS2V5IGtleSA9IG5ldyBNeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaSgpLm5ldyB0bXBLZXkoIlByb2JhIiwgbmV3IGJ5dGVbMF0pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbS5nZW5FeGVtcHRpb25CbG9iKCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZmFpbGVkCisgICAgICAgIH0KKworICAgICAgICBlbS5pbml0KGtleSk7CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChlbS5nZW5FeGVtcHRpb25CbG9iKCkpOworCisgICAgICAgIGVtID0gbmV3IEV4ZW1wdGlvbk1lY2hhbmlzbSgKKyAgICAgICAgICAgICAgICBuZXcgTW9ja19FeGVtcHRpb25NZWNoYW5pc21TcGkoKSwgbVByb3YsIGRlZmF1bHRBbGcpIHsKKyAgICAgICAgfTsKKyAgICAgICAga2V5ID0gbmV3IE1vY2tfRXhlbXB0aW9uTWVjaGFuaXNtU3BpKCkubmV3IHRtcEtleSgiUHJvYmEiLCBuZXcgYnl0ZVswXSk7CisgICAgICAgIGVtLmluaXQoa2V5KTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW0uZ2VuRXhlbXB0aW9uQmxvYigpOworICAgICAgICAgICAgZmFpbCgiRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2ZhaWxlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZW5FeGVtcHRpb25CbG9iJEIoKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24sIFNob3J0QnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvdmlkZXIgbVByb3YgPSAobmV3IFNwaUVuZ1V0aWxzKCkpLm5ldyBNeVByb3ZpZGVyKCJNeUV4TWVjaFByb3ZpZGVyIiwKKyAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yIEV4ZW1wdGlvbk1lY2hhbmlzbSB0ZXN0aW5nIiwKKyAgICAgICAgICAgICAgICBzcnZFeGVtcHRpb25NZWNoYW5pc20uY29uY2F0KCIuIikuY29uY2F0KGRlZmF1bHRBbGcpLAorICAgICAgICAgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbVByb3ZpZGVyQ2xhc3MpOworCisgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbSBlbSA9IG5ldyBFeGVtcHRpb25NZWNoYW5pc20oCisgICAgICAgICAgICAgICAgbmV3IE1vY2tfRXhlbXB0aW9uTWVjaGFuaXNtU3BpKCksIG1Qcm92LCBkZWZhdWx0QWxnKSB7CisgICAgICAgIH07CisKKyAgICAgICAgS2V5IGtleSA9IG5ldyBNb2NrX0V4ZW1wdGlvbk1lY2hhbmlzbVNwaSgpLm5ldyB0bXBLZXkoIlByb2JhIiwgbmV3IGJ5dGVbMF0pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbS5nZW5FeGVtcHRpb25CbG9iKG5ldyBieXRlWzEwXSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZmFpbGVkCisgICAgICAgIH0KKworICAgICAgICBlbS5pbml0KGtleSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIChlbS5nZW5FeGVtcHRpb25CbG9iKG5ldyBieXRlWzEwXSkpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW0uZ2VuRXhlbXB0aW9uQmxvYihuZXcgYnl0ZVsyXSk7CisgICAgICAgICAgICBmYWlsKCJTaG9ydEJ1ZmZlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTaG9ydEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2ZhaWxlZAorICAgICAgICB9CisgICAgICAgIGJ5dGVbXSBiID0gbmV3IGJ5dGVbXSB7MCwwLDAsMzMsMH07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVtLmdlbkV4ZW1wdGlvbkJsb2IoYik7CisgICAgICAgICAgICBmYWlsKCJFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZmFpbGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dlbkV4ZW1wdGlvbkJsb2IkQkkoKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24sIFNob3J0QnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvdmlkZXIgbVByb3YgPSAobmV3IFNwaUVuZ1V0aWxzKCkpLm5ldyBNeVByb3ZpZGVyKCJNeUV4TWVjaFByb3ZpZGVyIiwKKyAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yIEV4ZW1wdGlvbk1lY2hhbmlzbSB0ZXN0aW5nIiwKKyAgICAgICAgICAgICAgICBzcnZFeGVtcHRpb25NZWNoYW5pc20uY29uY2F0KCIuIikuY29uY2F0KGRlZmF1bHRBbGcpLAorICAgICAgICAgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbVByb3ZpZGVyQ2xhc3MpOworCisgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbSBlbSA9IG5ldyBFeGVtcHRpb25NZWNoYW5pc20oCisgICAgICAgICAgICAgICAgbmV3IE1vY2tfRXhlbXB0aW9uTWVjaGFuaXNtU3BpKCksIG1Qcm92LCBkZWZhdWx0QWxnKSB7CisgICAgICAgIH07CisKKyAgICAgICAgS2V5IGtleSA9IG5ldyBNb2NrX0V4ZW1wdGlvbk1lY2hhbmlzbVNwaSgpLm5ldyB0bXBLZXkoIlByb2JhIiwgbmV3IGJ5dGVbMF0pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbS5nZW5FeGVtcHRpb25CbG9iKG5ldyBieXRlWzEwXSwgMik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZmFpbGVkCisgICAgICAgIH0KKworICAgICAgICBlbS5pbml0KGtleSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIChlbS5nZW5FeGVtcHRpb25CbG9iKG5ldyBieXRlWzEwXSwgNSkpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW0uZ2VuRXhlbXB0aW9uQmxvYihuZXcgYnl0ZVs3XSwgMyk7CisgICAgICAgICAgICBmYWlsKCJTaG9ydEJ1ZmZlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTaG9ydEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2ZhaWxlZAorICAgICAgICB9CisgICAgICAgIGJ5dGVbXSBiID0gbmV3IGJ5dGVbXSB7MCwgMCwgMCwgMSwgMiwgMywgMzMsIDB9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbS5nZW5FeGVtcHRpb25CbG9iKGIsIDMpOworICAgICAgICAgICAgZmFpbCgiRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2ZhaWxlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFeGVtcHRpb25NZWNoYW5pc20uZ2V0SW5zdGFuY2UoKFN0cmluZykgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBQcm92aWRlciBtUHJvdiA9IChuZXcgU3BpRW5nVXRpbHMoKSkubmV3IE15UHJvdmlkZXIoIk15RXhNZWNoUHJvdmlkZXIiLAorICAgICAgICAgICAgICAgICJQcm92aWRlciBmb3IgRXhlbXB0aW9uTWVjaGFuaXNtIHRlc3RpbmciLAorICAgICAgICAgICAgICAgIHNydkV4ZW1wdGlvbk1lY2hhbmlzbS5jb25jYXQoIi4iKS5jb25jYXQoZGVmYXVsdEFsZyksCisgICAgICAgICAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtUHJvdmlkZXJDbGFzcyk7CisKKyAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtIGVtID0gbmV3IEV4ZW1wdGlvbk1lY2hhbmlzbSgKKyAgICAgICAgICAgICAgICBuZXcgTW9ja19FeGVtcHRpb25NZWNoYW5pc21TcGkoKSwgbVByb3YsIGRlZmF1bHRBbGcpIHsKKyAgICAgICAgfTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW0uZ2V0SW5zdGFuY2UoIldyb25nQWxnTmFtZSIpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmdMamF2YV9zZWN1cml0eV9Qcm92aWRlcigpCisgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFByb3ZpZGVyIG1Qcm92ID0gKG5ldyBTcGlFbmdVdGlscygpKS5uZXcgTXlQcm92aWRlcigiTXlFeE1lY2hQcm92aWRlciIsCisgICAgICAgICAgICAgICAgIlByb3ZpZGVyIGZvciBFeGVtcHRpb25NZWNoYW5pc20gdGVzdGluZyIsCisgICAgICAgICAgICAgICAgc3J2RXhlbXB0aW9uTWVjaGFuaXNtLmNvbmNhdCgiLiIpLmNvbmNhdChkZWZhdWx0QWxnKSwKKyAgICAgICAgICAgICAgICBFeGVtcHRpb25NZWNoYW5pc21Qcm92aWRlckNsYXNzKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtLmdldEluc3RhbmNlKChTdHJpbmcpIG51bGwsIG1Qcm92KTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbSBlbSA9IG5ldyBFeGVtcHRpb25NZWNoYW5pc20oCisgICAgICAgICAgICAgICAgbmV3IE1vY2tfRXhlbXB0aW9uTWVjaGFuaXNtU3BpKCksIG1Qcm92LCBkZWZhdWx0QWxnKSB7CisgICAgICAgIH07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVtLmdldEluc3RhbmNlKCJXcm9uZ0FsZ05hbWUiLCBtUHJvdik7CisgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbS5nZXRJbnN0YW5jZSgiV3JvbmdBbGdOYW1lIiwgKFByb3ZpZGVyKW51bGwpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE5hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvdmlkZXIgbVByb3YgPSAobmV3IFNwaUVuZ1V0aWxzKCkpLm5ldyBNeVByb3ZpZGVyKCJNeUV4TWVjaFByb3ZpZGVyIiwKKyAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yIEV4ZW1wdGlvbk1lY2hhbmlzbSB0ZXN0aW5nIiwKKyAgICAgICAgICAgICAgICBzcnZFeGVtcHRpb25NZWNoYW5pc20uY29uY2F0KCIuIikuY29uY2F0KGRlZmF1bHRBbGcpLAorICAgICAgICAgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbVByb3ZpZGVyQ2xhc3MpOworCisgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbSBlbSA9IG5ldyBFeGVtcHRpb25NZWNoYW5pc20oCisgICAgICAgICAgICAgICAgbmV3IE15RXhlbXB0aW9uTWVjaGFuaXNtU3BpKCksIG1Qcm92LCBkZWZhdWx0QWxnKSB7CisgICAgICAgIH07CisKKyAgICAgICAgS2V5IGtleSA9IG5ldyBNeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaSgpLm5ldyB0bXBLZXkoIlByb2JhIiwgbmV3IGJ5dGVbMF0pOworCisgICAgICAgIGFzc2VydEVxdWFscyhkZWZhdWx0QWxnLCBlbS5nZXROYW1lKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0T3V0cHV0U2l6ZUkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvdmlkZXIgbVByb3YgPSAobmV3IFNwaUVuZ1V0aWxzKCkpLm5ldyBNeVByb3ZpZGVyKCJNeUV4TWVjaFByb3ZpZGVyIiwKKyAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yIEV4ZW1wdGlvbk1lY2hhbmlzbSB0ZXN0aW5nIiwKKyAgICAgICAgICAgICAgICBzcnZFeGVtcHRpb25NZWNoYW5pc20uY29uY2F0KCIuIikuY29uY2F0KGRlZmF1bHRBbGcpLAorICAgICAgICAgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbVByb3ZpZGVyQ2xhc3MpOworCisgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbSBlbSA9IG5ldyBFeGVtcHRpb25NZWNoYW5pc20oCisgICAgICAgICAgICAgICAgbmV3IE15RXhlbXB0aW9uTWVjaGFuaXNtU3BpKCksIG1Qcm92LCBkZWZhdWx0QWxnKSB7CisgICAgICAgIH07CisKKyAgICAgICAgS2V5IGtleSA9IG5ldyBNeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaSgpLm5ldyB0bXBLZXkoIlByb2JhIiwgbmV3IGJ5dGVbMF0pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbS5nZXRPdXRwdXRTaXplKDEwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9mYWlsZWQKKyAgICAgICAgfQorCisgICAgICAgIGVtLmluaXQoa2V5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEwLCBlbS5nZXRPdXRwdXRTaXplKDEwKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQcm92aWRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQcm92aWRlciBtUHJvdiA9IChuZXcgU3BpRW5nVXRpbHMoKSkubmV3IE15UHJvdmlkZXIoIk15RXhNZWNoUHJvdmlkZXIiLAorICAgICAgICAgICAgICAgICJQcm92aWRlciBmb3IgRXhlbXB0aW9uTWVjaGFuaXNtIHRlc3RpbmciLAorICAgICAgICAgICAgICAgIHNydkV4ZW1wdGlvbk1lY2hhbmlzbS5jb25jYXQoIi4iKS5jb25jYXQoZGVmYXVsdEFsZyksCisgICAgICAgICAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtUHJvdmlkZXJDbGFzcyk7CisKKyAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtIGVtID0gbmV3IEV4ZW1wdGlvbk1lY2hhbmlzbSgKKyAgICAgICAgICAgICAgICBuZXcgTXlFeGVtcHRpb25NZWNoYW5pc21TcGkoKSwgbVByb3YsIGRlZmF1bHRBbGcpIHsKKyAgICAgICAgfTsKKworICAgICAgICBLZXkga2V5ID0gbmV3IE15RXhlbXB0aW9uTWVjaGFuaXNtU3BpKCkubmV3IHRtcEtleSgiUHJvYmEiLCBuZXcgYnl0ZVswXSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1Qcm92LCBlbS5nZXRQcm92aWRlcigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luaXRMamF2YV9zZWN1cml0eV9LZXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvdmlkZXIgbVByb3YgPSAobmV3IFNwaUVuZ1V0aWxzKCkpLm5ldyBNeVByb3ZpZGVyKCJNeUV4TWVjaFByb3ZpZGVyIiwKKyAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yIEV4ZW1wdGlvbk1lY2hhbmlzbSB0ZXN0aW5nIiwKKyAgICAgICAgICAgICAgICBzcnZFeGVtcHRpb25NZWNoYW5pc20uY29uY2F0KCIuIikuY29uY2F0KGRlZmF1bHRBbGcpLAorICAgICAgICAgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbVByb3ZpZGVyQ2xhc3MpOworCisgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbSBlbSA9IG5ldyBFeGVtcHRpb25NZWNoYW5pc20oCisgICAgICAgICAgICAgICAgbmV3IE15RXhlbXB0aW9uTWVjaGFuaXNtU3BpKCksIG1Qcm92LCBkZWZhdWx0QWxnKSB7CisgICAgICAgIH07CisKKyAgICAgICAgS2V5IGtleSA9IG5ldyBNeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaSgpLm5ldyB0bXBLZXkoIlByb2JhIiwgbmV3IGJ5dGVbMF0pOworCisgICAgICAgIGVtLmluaXQoa2V5KTsKKworICAgICAgICBLZXlHZW5lcmF0b3Iga2cgPSBLZXlHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRFUyIpOworICAgICAgICBrZy5pbml0KDU2LCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICBrZXkgPSBrZy5nZW5lcmF0ZUtleSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbS5pbml0KG51bGwpOworICAgICAgICAgICAgZmFpbCgiSW52YWxpZEtleUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbS5pbml0KGtleSk7CisgICAgICAgICAgICBmYWlsKCJFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5pdExqYXZhX3NlY3VyaXR5X0tleUxqYXZhX3NlY3VyaXR5X0FsZ29yaXRobVBhcmFtZXRlcnMoKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFByb3ZpZGVyIG1Qcm92ID0gKG5ldyBTcGlFbmdVdGlscygpKS5uZXcgTXlQcm92aWRlcigiTXlFeE1lY2hQcm92aWRlciIsCisgICAgICAgICAgICAgICAgIlByb3ZpZGVyIGZvciBFeGVtcHRpb25NZWNoYW5pc20gdGVzdGluZyIsCisgICAgICAgICAgICAgICAgc3J2RXhlbXB0aW9uTWVjaGFuaXNtLmNvbmNhdCgiLiIpLmNvbmNhdChkZWZhdWx0QWxnKSwKKyAgICAgICAgICAgICAgICBFeGVtcHRpb25NZWNoYW5pc21Qcm92aWRlckNsYXNzKTsKKworICAgICAgICBFeGVtcHRpb25NZWNoYW5pc20gZW0gPSBuZXcgRXhlbXB0aW9uTWVjaGFuaXNtKAorICAgICAgICAgICAgICAgIG5ldyBNeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaSgpLCBtUHJvdiwgZGVmYXVsdEFsZykgeworICAgICAgICB9OworCisgICAgICAgIEtleSBrZXkgPSBuZXcgTXlFeGVtcHRpb25NZWNoYW5pc21TcGkoKS5uZXcgdG1wS2V5KCJQcm9iYSIsIG5ldyBieXRlWzBdKTsKKworICAgICAgICBlbS5pbml0KGtleSwgQWxnb3JpdGhtUGFyYW1ldGVycy5nZXRJbnN0YW5jZSgiREVTIikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbS5pbml0KGtleSwgKEFsZ29yaXRobVBhcmFtZXRlcnMpbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgS2V5R2VuZXJhdG9yIGtnID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKCJERVMiKTsKKyAgICAgICAga2cuaW5pdCg1NiwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAga2V5ID0ga2cuZ2VuZXJhdGVLZXkoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW0uaW5pdChudWxsLCBBbGdvcml0aG1QYXJhbWV0ZXJzLmdldEluc3RhbmNlKCJERVMiKSk7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkS2V5RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVtLmluaXQoa2V5LCBBbGdvcml0aG1QYXJhbWV0ZXJzLmdldEluc3RhbmNlKCJERVMiKSk7CisgICAgICAgICAgICBmYWlsKCJFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5pdExqYXZhX3NlY3VyaXR5X0tleUxqYXZhX3NlY3VyaXR5X3NwZWNfQWxnb3JpdGhtUGFyYW1ldGVyU3BlYygpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9ueworICAgICAgICBQcm92aWRlciBtUHJvdiA9IChuZXcgU3BpRW5nVXRpbHMoKSkubmV3IE15UHJvdmlkZXIoIk15RXhNZWNoUHJvdmlkZXIiLAorICAgICAgICAgICAgICAgICJQcm92aWRlciBmb3IgRXhlbXB0aW9uTWVjaGFuaXNtIHRlc3RpbmciLAorICAgICAgICAgICAgICAgIHNydkV4ZW1wdGlvbk1lY2hhbmlzbS5jb25jYXQoIi4iKS5jb25jYXQoZGVmYXVsdEFsZyksCisgICAgICAgICAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtUHJvdmlkZXJDbGFzcyk7CisKKyAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtIGVtID0gbmV3IEV4ZW1wdGlvbk1lY2hhbmlzbSgKKyAgICAgICAgICAgICAgICBuZXcgTXlFeGVtcHRpb25NZWNoYW5pc21TcGkoKSwgbVByb3YsIGRlZmF1bHRBbGcpIHsKKyAgICAgICAgfTsKKworICAgICAgICBLZXkga2V5ID0gbmV3IE15RXhlbXB0aW9uTWVjaGFuaXNtU3BpKCkubmV3IHRtcEtleSgiUHJvYmEiLCBuZXcgYnl0ZVswXSk7CisKKyAgICAgICAgZW0uaW5pdChrZXksIG5ldyBSU0FLZXlHZW5QYXJhbWV0ZXJTcGVjKDEwLCBuZXcgQmlnSW50ZWdlcigiMTAiKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbS5pbml0KGtleSwgKEFsZ29yaXRobVBhcmFtZXRlclNwZWMpbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgS2V5R2VuZXJhdG9yIGtnID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKCJERVMiKTsKKyAgICAgICAga2cuaW5pdCg1NiwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAga2V5ID0ga2cuZ2VuZXJhdGVLZXkoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW0uaW5pdChudWxsLCBuZXcgUlNBS2V5R2VuUGFyYW1ldGVyU3BlYygxMCwgbmV3IEJpZ0ludGVnZXIoIjEwIikpKTsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWRLZXlFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW0uaW5pdChrZXksIG5ldyBSU0FLZXlHZW5QYXJhbWV0ZXJTcGVjKDEwLCBuZXcgQmlnSW50ZWdlcigiMTAiKSkpOworICAgICAgICAgICAgZmFpbCgiRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9Cit9CisKKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0lsbGVnYWxCbG9ja1NpemVFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YjRhZTEyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0lsbGVnYWxCbG9ja1NpemVFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw4MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvOworCitpbXBvcnQgamF2YXguY3J5cHRvLklsbGVnYWxCbG9ja1NpemVFeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+SWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZAorICogbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisgICAgc3RhdGljIFRocm93YWJsZSB0Q2F1c2UgPSBuZXcgVGhyb3dhYmxlKCJUaHJvd2FibGUgZm9yIGV4Y2VwdGlvbiIpOworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+SWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbigpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbjAxKCkgeworICAgICAgICBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uIHRFID0gbmV3IElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24oKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+SWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uIHdpdGggZGV0YWlsIG1lc3NhZ2UgbXNnLgorICAgICAqIFBhcmFtZXRlciA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uMDIoKSB7CisgICAgICAgIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbihtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPklsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiB3aGVuIDxjb2RlPm1zZzwvY29kZT4KKyAgICAgKiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24wMygpIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9IG51bGw7CisgICAgICAgIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24gdEUgPSBuZXcgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbihtc2cpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vS2V5QWdyZWVtZW50U3BpVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0tleUFncmVlbWVudFNwaVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44M2Q2ZWQ3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0tleUFncmVlbWVudFNwaVRlc3QuamF2YQpAQCAtMCwwICsxLDEyMCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKKworaW1wb3J0IGphdmF4LmNyeXB0by5LZXlBZ3JlZW1lbnRTcGk7CitpbXBvcnQgamF2YXguY3J5cHRvLlNlY3JldEtleTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2hvcnRCdWZmZXJFeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLnN1cHBvcnQuTXlLZXlBZ3JlZW1lbnRTcGk7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPktleUFncmVlbWVudFNwaTwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIEtleUFncmVlbWVudFNwaVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgY2xhc3MgTW9ja19LZXlBZ3JlZW1lbnRTcGkgZXh0ZW5kcyBNeUtleUFncmVlbWVudFNwaSB7CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBLZXkgZW5naW5lRG9QaGFzZShLZXkga2V5LCBib29sZWFuIGxhc3RQaGFzZSkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5lbmdpbmVEb1BoYXNlKGtleSwgbGFzdFBoYXNlKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuZ2luZUdlbmVyYXRlU2VjcmV0KCkgdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZW5naW5lR2VuZXJhdGVTZWNyZXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgU2VjcmV0S2V5IGVuZ2luZUdlbmVyYXRlU2VjcmV0KFN0cmluZyBhbGdvcml0aG0pIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5lbmdpbmVHZW5lcmF0ZVNlY3JldChhbGdvcml0aG0pOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBpbnQgZW5naW5lR2VuZXJhdGVTZWNyZXQoYnl0ZVtdIHNoYXJlZFNlY3JldCwgaW50IG9mZnNldCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uLCBTaG9ydEJ1ZmZlckV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZW5naW5lR2VuZXJhdGVTZWNyZXQoc2hhcmVkU2VjcmV0LCBvZmZzZXQpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXQoS2V5IGtleSwgU2VjdXJlUmFuZG9tIHJhbmRvbSkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIuZW5naW5lSW5pdChrZXksIHJhbmRvbSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChLZXkga2V5LCBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtcywgU2VjdXJlUmFuZG9tIHJhbmRvbSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlci5lbmdpbmVJbml0KGtleSwgcGFyYW1zLCByYW5kb20pOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5LZXlBZ3JlZW1lbnRTcGk8L2NvZGU+IGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cworICAgICAqIEtleUFncmVlbWVudFNwaQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlBZ3JlZW1lbnRTcGkwMSgpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgU2hvcnRCdWZmZXJFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBNb2NrX0tleUFncmVlbWVudFNwaSBrYVNwaSA9IG5ldyBNb2NrX0tleUFncmVlbWVudFNwaSgpOworCisgICAgICAgIGFzc2VydE51bGwoIk5vdCBudWxsIHJlc3VsdCIsIGthU3BpLmVuZ2luZURvUGhhc2UobnVsbCwgdHJ1ZSkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAga2FTcGkuZW5naW5lRG9QaGFzZShudWxsLCBmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gYmIgPSBrYVNwaS5lbmdpbmVHZW5lcmF0ZVNlY3JldCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkxlbmd0aCBpcyBub3QgMCIsIGJiLmxlbmd0aCwgMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW50ZWdlciBpcyBub3QgMCIsIGthU3BpLmVuZ2luZUdlbmVyYXRlU2VjcmV0KG5ldyBieXRlWzFdLCAxMCksIC0xKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiTm90IG51bGwgcmVzdWx0Iiwga2FTcGkuZW5naW5lR2VuZXJhdGVTZWNyZXQoImFhYSIpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGthU3BpLmVuZ2luZUdlbmVyYXRlU2VjcmV0KCIiKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIEtleSBrZXkgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAga2FTcGkuZW5naW5lSW5pdChrZXksIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrYVNwaS5lbmdpbmVJbml0KGtleSwgcGFyYW1zLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vS2V5QWdyZWVtZW50VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0tleUFncmVlbWVudFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45OWQxMjdhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0tleUFncmVlbWVudFRlc3QuamF2YQpAQCAtMCwwICsxLDY3OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5EU0FQYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5SU0FLZXlHZW5QYXJhbWV0ZXJTcGVjOworCitpbXBvcnQgamF2YXguY3J5cHRvLktleUFncmVlbWVudDsKK2ltcG9ydCBqYXZheC5jcnlwdG8uS2V5QWdyZWVtZW50U3BpOworaW1wb3J0IGphdmF4LmNyeXB0by5TaG9ydEJ1ZmZlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uaW50ZXJmYWNlcy5ESFByaXZhdGVLZXk7CitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuREhQYXJhbWV0ZXJTcGVjOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5zdXBwb3J0Lk15S2V5QWdyZWVtZW50U3BpOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlNwaUVuZ1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlRlc3RLZXlQYWlyOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisKKy8qKgorICogVGVzdHMgZm9yIEtleUFncmVlbWVudCBjb25zdHJ1Y3RvciBhbmQgbWV0aG9kcworICoKKyAqLworcHVibGljIGNsYXNzIEtleUFncmVlbWVudFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBzcnZLZXlBZ3JlZW1lbnQgPSAiS2V5QWdyZWVtZW50IjsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZWZhdWx0QWxnb3JpdGhtID0gIkRIIjsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZWZhdWx0UHJvdmlkZXJOYW1lID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIFByb3ZpZGVyIGRlZmF1bHRQcm92aWRlciA9IG51bGw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIERFRlN1cHBvcnRlZCA9IGZhbHNlOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5vdFN1cHBvcnRNc2cgPSAiVGhlcmUgaXMgbm8gc3VpdGFibGUgcHJvdmlkZXIgZm9yIEtleUFncmVlbWVudCI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBpbnZhbGlkVmFsdWVzID0gU3BpRW5nVXRpbHMuaW52YWxpZFZhbHVlczsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIHZhbGlkVmFsdWVzID0geyAiREgiLCAiZEgiLAorICAgICAgICAgICAgIkRoIiwgImRoIiB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgUHJpdmF0ZUtleSBwcml2S2V5ID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIFB1YmxpY0tleSBwdWJsS2V5ID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaW5pdEtleXMgPSBmYWxzZTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIGRlZmF1bHRQcm92aWRlciA9IFNwaUVuZ1V0aWxzLmlzU3VwcG9ydChkZWZhdWx0QWxnb3JpdGhtLAorICAgICAgICAgICAgICAgIHNydktleUFncmVlbWVudCk7CisgICAgICAgIERFRlN1cHBvcnRlZCA9IChkZWZhdWx0UHJvdmlkZXIgIT0gbnVsbCk7CisgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUgPSAoREVGU3VwcG9ydGVkID8gZGVmYXVsdFByb3ZpZGVyLmdldE5hbWUoKSA6IG51bGwpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjcmVhdGVLZXlzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaW5pdEtleXMpIHsKKyAgICAgICAgICAgIFRlc3RLZXlQYWlyIHRrcCA9IG5ldyBUZXN0S2V5UGFpcihkZWZhdWx0QWxnb3JpdGhtKTsKKyAgICAgICAgICAgIHByaXZLZXkgPSB0a3AuZ2V0UHJpdmF0ZSgpOworICAgICAgICAgICAgcHVibEtleSA9IHRrcC5nZXRQdWJsaWMoKTsKKyAgICAgICAgICAgIGluaXRLZXlzID0gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgcHJpdmF0ZSBLZXlBZ3JlZW1lbnRbXSBjcmVhdGVLQXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgIH0KKworICAgICAgICBLZXlBZ3JlZW1lbnRbXSBrYSA9IG5ldyBLZXlBZ3JlZW1lbnRbM107CisgICAgICAgIGthWzBdID0gS2V5QWdyZWVtZW50LmdldEluc3RhbmNlKGRlZmF1bHRBbGdvcml0aG0pOworICAgICAgICBrYVsxXSA9IEtleUFncmVlbWVudC5nZXRJbnN0YW5jZShkZWZhdWx0QWxnb3JpdGhtLCBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICBrYVsyXSA9IEtleUFncmVlbWVudC5nZXRJbnN0YW5jZShkZWZhdWx0QWxnb3JpdGhtLAorICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICByZXR1cm4ga2E7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0RGVmQWxnKCkgeworICAgICAgICByZXR1cm4gZGVmYXVsdEFsZ29yaXRobTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT4gZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSkgPC9jb2RlPiBtZXRob2QgQXNzZXJ0aW9uczoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbnVsbCB0aHJvd3MKKyAgICAgKiBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXNub3QgYXZhaWxhYmxlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlU3RyaW5nMDEoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleUFncmVlbWVudC5nZXRJbnN0YW5jZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIGlmIGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5QWdyZWVtZW50LmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPiBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKSA8L2NvZGU+IG1ldGhvZCBBc3NlcnRpb25zOgorICAgICAqIHJldHVybnMgS2V5QWdyZWVtZW50IG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZVN0cmluZzAyKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIEtleUFncmVlbWVudCBrZXlBOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBrZXlBID0gS2V5QWdyZWVtZW50LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGtleUEuZ2V0QWxnb3JpdGhtKCksCisgICAgICAgICAgICAgICAgICAgIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPiBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZCBBc3NlcnRpb25zOiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbnVsbAorICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZVN0cmluZ1N0cmluZzAxKCkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleUFncmVlbWVudC5nZXRJbnN0YW5jZShudWxsLCBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIGlmIGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5QWdyZWVtZW50LmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0sIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPiBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZCBBc3NlcnRpb25zOiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbAorICAgICAqIG9yIGVtcHR5IHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB3aGVuIHByb3ZpZGVyIGhhcyBub3QgYmUKKyAgICAgKiBjb25maWd1cmVkCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlU3RyaW5nU3RyaW5nMDIoKQorICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcHJvdmlkZXIgPSBudWxsOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEtleUFncmVlbWVudC5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgcHJvdmlkZXIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHByb3ZpZGVyIGlzIG51bGwiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEtleUFncmVlbWVudC5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgIiIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHByb3ZpZGVyIGlzIGVtcHR5Iik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChpbnQgaiA9IDE7IGogPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgS2V5QWdyZWVtZW50LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBpbnZhbGlkVmFsdWVzW2pdKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gKGFsZ29yaXRobTogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQodmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiIHByb3ZpZGVyOiAiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tqXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT4gZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QgQXNzZXJ0aW9uczogcmV0dXJucyBLZXlBZ3JlZW1lbnQgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlU3RyaW5nU3RyaW5nMDMoKQorICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBLZXlBZ3JlZW1lbnQga2V5QTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAga2V5QSA9IEtleUFncmVlbWVudAorICAgICAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwga2V5QS5nZXRBbGdvcml0aG0oKSwKKyAgICAgICAgICAgICAgICAgICAgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBrZXlBLmdldFByb3ZpZGVyKCkuZ2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPiBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBQcm92aWRlciBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kIEFzc2VydGlvbnM6IHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBudWxsCisgICAgICogdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpc25vdCBhdmFpbGFibGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2VTdHJpbmdQcm92aWRlcjAxKCkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlBZ3JlZW1lbnQuZ2V0SW5zdGFuY2UobnVsbCwgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIGlmIGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5QWdyZWVtZW50LmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0sIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+IGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QgQXNzZXJ0aW9uczogdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aGVuIHByb3ZpZGVyIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2VTdHJpbmdQcm92aWRlcjAyKCkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyID0gbnVsbDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEtleUFncmVlbWVudC5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldLCBwcm92aWRlcik7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+IGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QgQXNzZXJ0aW9uczogcmV0dXJucyBLZXlBZ3JlZW1lbnQgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlU3RyaW5nUHJvdmlkZXIwMygpCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBLZXlBZ3JlZW1lbnQga2V5QTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAga2V5QSA9IEtleUFncmVlbWVudC5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGtleUEuZ2V0QWxnb3JpdGhtKCksCisgICAgICAgICAgICAgICAgICAgIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwga2V5QS5nZXRQcm92aWRlcigpLAorICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgdGhlIG1ldGhvZHM6IDxjb2RlPmluaXQoS2V5IGtleSk8L2NvZGU+CisgICAgICogPGNvZGU+Z2VuZXJhdGVTZWNyZXQoKTwvY29kZT4KKyAgICAgKiA8Y29kZT5nZW5lcmF0ZVNlY3JldChieXRlW10gc2hhcmVkc2VjcmV0LCBpbnQgb2Zmc2V0KTwvY29kZT4KKyAgICAgKiA8Y29kZT5nZW5lcmF0ZVNlY3JldChTdHJpbmcgYWxnb3JpdGhtKTwvY29kZT4KKyAgICAgKiBBc3NlcnRpb25zOiBpbml0aWFsaXplcyBLZXlBZ3JlZW1lbnQ7IHJldHVybnMgc2hhcmVkU2VjcmV0OyBwdXRzCisgICAgICogc2hhcmVkc2VjcmV0IGluIGJ1ZmZlciBhbmQgcmV0dXJuIG51bWJlcnMgb2YgYnl0ZXM7IHJldHVybnMgU2VjcmV0S2V5CisgICAgICogb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdlbmVyYXRlU2VjcmV0MDMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgY3JlYXRlS2V5cygpOworICAgICAgICBLZXlBZ3JlZW1lbnRbXSBrQWdzID0gY3JlYXRlS0FzKCk7CisKKyAgICAgICAgYnl0ZVtdIGJiOworICAgICAgICBieXRlW10gYmIxID0gbmV3IGJ5dGVbMTBdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGtBZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGtBZ3NbaV0uaW5pdChwcml2S2V5KTsKKyAgICAgICAgICAgIGtBZ3NbaV0uZG9QaGFzZShwdWJsS2V5LCB0cnVlKTsKKyAgICAgICAgICAgIGJiID0ga0Fnc1tpXS5nZW5lcmF0ZVNlY3JldCgpOworICAgICAgICAgICAga0Fnc1tpXS5pbml0KHByaXZLZXkpOworICAgICAgICAgICAga0Fnc1tpXS5kb1BoYXNlKHB1YmxLZXksIHRydWUpOworICAgICAgICAgICAgYmIxID0gbmV3IGJ5dGVbYmIubGVuZ3RoICsgMTBdOworICAgICAgICAgICAga0Fnc1tpXS5nZW5lcmF0ZVNlY3JldChiYjEsIDkpOworICAgICAgICAgICAga0Fnc1tpXS5pbml0KHByaXZLZXkpOworICAgICAgICAgICAga0Fnc1tpXS5kb1BoYXNlKHB1YmxLZXksIHRydWUpOworICAgICAgICAgICAga0Fnc1tpXS5nZW5lcmF0ZVNlY3JldCgiREVTIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5kb1BoYXNlKEtleSBrZXksIGJvb2xlYW4gbGFzdFBoYXNlKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiBpZiBrZXkgaXMgbm90IGFwcHJvcHJpYXRlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdERvUGhhc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgY3JlYXRlS2V5cygpOworICAgICAgICBLZXlBZ3JlZW1lbnRbXSBrQWdzID0gY3JlYXRlS0FzKCk7CisgICAgICAgIERIUGFyYW1ldGVyU3BlYyBkaFBzID0gKChESFByaXZhdGVLZXkpIHByaXZLZXkpLmdldFBhcmFtcygpOworICAgICAgICBTZWN1cmVSYW5kb20gcmFuZG9tTnVsbCA9IG51bGw7CisgICAgICAgIFNlY3VyZVJhbmRvbSByYW5kb20gPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrQWdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtBZ3NbaV0uZG9QaGFzZShwdWJsS2V5LCB0cnVlKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBrQWdzW2ldLmluaXQocHJpdktleSk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga0Fnc1tpXS5kb1BoYXNlKHByaXZLZXksIGZhbHNlKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbnZhbGlkS2V5RXhjZXB0aW9uIG11c3QgYmUgdGhyb3ciKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtBZ3NbaV0uZG9QaGFzZShwcml2S2V5LCB0cnVlKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbnZhbGlkS2V5RXhjZXB0aW9uIG11c3QgYmUgdGhyb3ciKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBrQWdzW2ldLmluaXQocHJpdktleSwgZGhQcyk7CisgICAgICAgICAgICBrQWdzW2ldLmRvUGhhc2UocHVibEtleSwgdHJ1ZSk7CisgICAgICAgICAgICBrQWdzW2ldLmluaXQocHJpdktleSwgZGhQcywgcmFuZG9tKTsKKyAgICAgICAgICAgIGtBZ3NbaV0uZG9QaGFzZShwdWJsS2V5LCB0cnVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIHRoZSBtZXRob2RzIDxjb2RlPmluaXQoS2V5IGtleSk8L2NvZGU+CisgICAgICogPGNvZGU+aW5pdChLZXkga2V5LCBTZWN1cmVSYW5kb20gcmFuZG9tKTwvY29kZT4KKyAgICAgKiA8Y29kZT5pbml0KEtleSBrZXksIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1zKTwvY29kZT4KKyAgICAgKiA8Y29kZT5pbml0KEtleSBrZXksIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1zLCBTZWN1cmVSYW5kb20gcmFuZG9tKTwvY29kZT4KKyAgICAgKiBBc3NlcnRpb246IHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHdoZW4ga2V5IGlzIGluYXBwcm9wcmlhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5pdDAxKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGNyZWF0ZUtleXMoKTsKKyAgICAgICAgS2V5QWdyZWVtZW50W10ga0FncyA9IGNyZWF0ZUtBcygpOworCisgICAgICAgIFNlY3VyZVJhbmRvbSByYW5kb20gPSBudWxsOworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIGFwcyA9IG51bGw7CisgICAgICAgIERIUGFyYW1ldGVyU3BlYyBkaFBzID0gbmV3IERIUGFyYW1ldGVyU3BlYyhuZXcgQmlnSW50ZWdlcigiNTYiKSwKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiNTYiKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga0Fncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrQWdzW2ldLmluaXQocHVibEtleSk7CisgICAgICAgICAgICAgICAgZmFpbCgiSW52YWxpZEtleUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93Iik7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga0Fnc1tpXS5pbml0KHB1YmxLZXksIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiSW52YWxpZEtleUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93Iik7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga0Fnc1tpXS5pbml0KHB1YmxLZXksIHJhbmRvbSk7CisgICAgICAgICAgICAgICAgZmFpbCgiSW52YWxpZEtleUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93Iik7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga0Fnc1tpXS5pbml0KHB1YmxLZXksIGRoUHMpOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRLZXlFeGNlcHRpb24gbXVzdCBiZSB0aHJvdyIpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtBZ3NbaV0uaW5pdChwdWJsS2V5LCBhcHMpOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRLZXlFeGNlcHRpb24gbXVzdCBiZSB0aHJvdyIpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtBZ3NbaV0uaW5pdChwdWJsS2V5LCBkaFBzLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRLZXlFeGNlcHRpb24gbXVzdCBiZSB0aHJvdyIpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciB0aGUgbWV0aG9kcworICAgICAqIDxjb2RlPmluaXQoS2V5IGtleSwgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMpPC9jb2RlPgorICAgICAqIDxjb2RlPmluaXQoS2V5IGtleSwgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMsIFNlY3VyZVJhbmRvbSByYW5kb20pPC9jb2RlPgorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB3aGVuIHBhcmFtcyBhcmUKKyAgICAgKiBpbmFwcHJvcHJpYXRlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEluaXQwMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBjcmVhdGVLZXlzKCk7CisgICAgICAgIEtleUFncmVlbWVudFtdIGtBZ3MgPSBjcmVhdGVLQXMoKTsKKworICAgICAgICBTZWN1cmVSYW5kb20gcmFuZG9tID0gbnVsbDsKKyAgICAgICAgRFNBUGFyYW1ldGVyU3BlYyBkc2EgPSBuZXcgRFNBUGFyYW1ldGVyU3BlYyhuZXcgQmlnSW50ZWdlcigiNTYiKSwKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiNTYiKSwgbmV3IEJpZ0ludGVnZXIoIjU2IikpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGtBZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga0Fnc1tpXS5pbml0KHByaXZLZXksIGRzYSk7CisgICAgICAgICAgICAgICAgZmFpbCgiSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBvciBJbnZhbGlkS2V5RXhjZXB0aW9uIG11c3QgYmUgdGhyb3ciKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtBZ3NbaV0uaW5pdChwcml2S2V5LCBkc2EsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBvciBJbnZhbGlkS2V5RXhjZXB0aW9uIG11c3QgYmUgdGhyb3ciKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtBZ3NbaV0uaW5pdChwcml2S2V5LCBkc2EsIHJhbmRvbSk7CisgICAgICAgICAgICAgICAgZmFpbCgiSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBvciBJbnZhbGlkS2V5RXhjZXB0aW9uIG11c3QgYmUgdGhyb3ciKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciB0aGUgbWV0aG9kczogPGNvZGU+aW5pdChLZXkga2V5KTwvY29kZT4KKyAgICAgKiA8Y29kZT5pbml0KEtleSBrZXksIFNlY3VyZVJhbmRvbSByYW5kb20pPC9jb2RlPgorICAgICAqIDxjb2RlPmdlbmVyYXRlU2VjcmV0KCk8L2NvZGU+CisgICAgICogQXNzZXJ0aW9uczogaW5pdGlhbGl6ZXMgS2V5QWdyZWVtZW50IGFuZCByZXR1cm5zIGJ5dGUgYXJyYXkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5pdDAzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGNyZWF0ZUtleXMoKTsKKyAgICAgICAgS2V5QWdyZWVtZW50W10ga0FncyA9IGNyZWF0ZUtBcygpOworCisgICAgICAgIGJ5dGVbXSBiYlJlczE7CisgICAgICAgIGJ5dGVbXSBiYlJlczI7CisgICAgICAgIGJ5dGVbXSBiYlJlczM7CisgICAgICAgIFNlY3VyZVJhbmRvbSByYW5kb21OdWxsID0gbnVsbDsKKyAgICAgICAgU2VjdXJlUmFuZG9tIHJhbmRvbSA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrQWdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBrQWdzW2ldLmluaXQocHJpdktleSk7CisgICAgICAgICAgICBrQWdzW2ldLmRvUGhhc2UocHVibEtleSwgdHJ1ZSk7CisgICAgICAgICAgICBiYlJlczEgPSBrQWdzW2ldLmdlbmVyYXRlU2VjcmV0KCk7CisgICAgICAgICAgICBrQWdzW2ldLmluaXQocHJpdktleSwgcmFuZG9tKTsKKyAgICAgICAgICAgIGtBZ3NbaV0uZG9QaGFzZShwdWJsS2V5LCB0cnVlKTsKKyAgICAgICAgICAgIGJiUmVzMiA9IGtBZ3NbaV0uZ2VuZXJhdGVTZWNyZXQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGJ5dGUgYXJyYXkgbGVuZ3RoIiwgYmJSZXMxLmxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgYmJSZXMyLmxlbmd0aCk7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGJiUmVzMS5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGJ5dGUgKGluZGV4OiAiLmNvbmNhdCgKKyAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIudG9TdHJpbmcoaSkpLmNvbmNhdCgiKSIpLCBiYlJlczFbal0sIGJiUmVzMltqXSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBrQWdzW2ldLmluaXQocHJpdktleSwgcmFuZG9tTnVsbCk7CisgICAgICAgICAgICBrQWdzW2ldLmRvUGhhc2UocHVibEtleSwgdHJ1ZSk7CisgICAgICAgICAgICBiYlJlczMgPSBrQWdzW2ldLmdlbmVyYXRlU2VjcmV0KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBieXRlIGFycmF5IGxlbmd0aCIsIGJiUmVzMS5sZW5ndGgsCisgICAgICAgICAgICAgICAgICAgIGJiUmVzMy5sZW5ndGgpOworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBiYlJlczEubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBieXRlIChpbmRleDogIi5jb25jYXQoCisgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLnRvU3RyaW5nKGkpKS5jb25jYXQoIikiKSwgYmJSZXMxW2pdLCBiYlJlczNbal0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgdGhlIG1ldGhvZHM6CisgICAgICogPGNvZGU+aW5pdChLZXkga2V5LCBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtcyk8L2NvZGU+CisgICAgICogPGNvZGU+aW5pdChLZXkga2V5LCBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtcywgU2VjdXJlUmFuZG9tIHJhbmRvbSk8L2NvZGU+CisgICAgICogPGNvZGU+Z2VuZXJhdGVTZWNyZXQoKTwvY29kZT4KKyAgICAgKiBBc3NlcnRpb25zOiBpbml0aWFsaXplcyBLZXlBZ3JlZW1lbnQgYW5kIHJldHVybnMgYnl0ZSBhcnJheQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbml0MDQoKSB0aHJvd3MgRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGNyZWF0ZUtleXMoKTsKKyAgICAgICAgS2V5QWdyZWVtZW50W10ga0FncyA9IGNyZWF0ZUtBcygpOworCisgICAgICAgIERIUGFyYW1ldGVyU3BlYyBkaFBzID0gKChESFByaXZhdGVLZXkpIHByaXZLZXkpLmdldFBhcmFtcygpOworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIGFwcyA9IG5ldyBSU0FLZXlHZW5QYXJhbWV0ZXJTcGVjKDEwLCBuZXcgQmlnSW50ZWdlcigiMTAiKSk7CisKKyAgICAgICAgYnl0ZVtdIGJiUmVzMTsKKyAgICAgICAgYnl0ZVtdIGJiUmVzMjsKKyAgICAgICAgYnl0ZVtdIGJiUmVzMzsKKyAgICAgICAgU2VjdXJlUmFuZG9tIHJhbmRvbU51bGwgPSBudWxsOworICAgICAgICBTZWN1cmVSYW5kb20gcmFuZG9tID0gbmV3IFNlY3VyZVJhbmRvbSgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGtBZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGtBZ3NbaV0uaW5pdChwcml2S2V5LCBkaFBzKTsKKyAgICAgICAgICAgIGtBZ3NbaV0uZG9QaGFzZShwdWJsS2V5LCB0cnVlKTsKKyAgICAgICAgICAgIGJiUmVzMSA9IGtBZ3NbaV0uZ2VuZXJhdGVTZWNyZXQoKTsKKyAgICAgICAgICAgIGtBZ3NbaV0uaW5pdChwcml2S2V5LCBkaFBzLCByYW5kb20pOworICAgICAgICAgICAga0Fnc1tpXS5kb1BoYXNlKHB1YmxLZXksIHRydWUpOworICAgICAgICAgICAgYmJSZXMyID0ga0Fnc1tpXS5nZW5lcmF0ZVNlY3JldCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYnl0ZSBhcnJheSBsZW5ndGgiLCBiYlJlczEubGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICBiYlJlczIubGVuZ3RoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgYmJSZXMxLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYnl0ZSAoaW5kZXg6ICIuY29uY2F0KAorICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhpKSkuY29uY2F0KCIpIiksIGJiUmVzMVtqXSwgYmJSZXMyW2pdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGtBZ3NbaV0uaW5pdChwcml2S2V5LCBkaFBzLCByYW5kb21OdWxsKTsKKyAgICAgICAgICAgIGtBZ3NbaV0uZG9QaGFzZShwdWJsS2V5LCB0cnVlKTsKKyAgICAgICAgICAgIGJiUmVzMyA9IGtBZ3NbaV0uZ2VuZXJhdGVTZWNyZXQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGJ5dGUgYXJyYXkgbGVuZ3RoIiwgYmJSZXMxLmxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgYmJSZXMzLmxlbmd0aCk7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGJiUmVzMS5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGJ5dGUgKGluZGV4OiAiLmNvbmNhdCgKKyAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIudG9TdHJpbmcoaSkpLmNvbmNhdCgiKSIpLCBiYlJlczFbal0sIGJiUmVzM1tqXSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga0Fnc1tpXS5pbml0KHB1YmxLZXksIGRoUHMsIHJhbmRvbSk7CisgICAgICAgICAgICAgICAgZmFpbCgiSW52YWxpZEtleUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrQWdzW2ldLmluaXQocHJpdktleSwgYXBzLCByYW5kb20pOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIE1vY2tfS2V5QWdyZWVtZW50IGV4dGVuZHMgS2V5QWdyZWVtZW50IHsKKyAgICAgICAgcHJvdGVjdGVkIE1vY2tfS2V5QWdyZWVtZW50KEtleUFncmVlbWVudFNwaSBhcmcwLCBQcm92aWRlciBhcmcxLCBTdHJpbmcgYXJnMikgeworICAgICAgICAgICAgc3VwZXIoYXJnMCwgYXJnMSwgYXJnMik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbnN0cnVjdG9yKCkgeworICAgICAgICBhc3NlcnROb3ROdWxsKG5ldyBNb2NrX0tleUFncmVlbWVudChudWxsLCBudWxsLCBudWxsKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBbGdvcml0aG0oKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja19LZXlBZ3JlZW1lbnQgbWthID0gbmV3IE1vY2tfS2V5QWdyZWVtZW50KG51bGwsIG51bGwsIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKG1rYS5nZXRBbGdvcml0aG0oKSk7CisKKyAgICAgICAgS2V5QWdyZWVtZW50IGtleUE7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGtleUEgPSBLZXlBZ3JlZW1lbnQuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwga2V5QS5nZXRBbGdvcml0aG0oKSwKKyAgICAgICAgICAgICAgICAgICAgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQcm92aWRlcigpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBLZXlBZ3JlZW1lbnQga2V5QTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAga2V5QSA9IEtleUFncmVlbWVudC5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGtleUEuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dlbmVyYXRlU2VjcmV0JEJJKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGNyZWF0ZUtleXMoKTsKKyAgICAgICAgS2V5QWdyZWVtZW50W10ga0FncyA9IGNyZWF0ZUtBcygpOworICAgICAgICBLZXlBZ3JlZW1lbnQga2EgPSBLZXlBZ3JlZW1lbnQuZ2V0SW5zdGFuY2UoIkRIIik7CisKKyAgICAgICAgYnl0ZVtdIGJiMSA9IG5ldyBieXRlWzFdOworICAgICAgICB0cnkgeworICAgICAgICAgICAga2EuZ2VuZXJhdGVTZWNyZXQoYmIxLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgICAgIGthLmluaXQocHJpdktleSk7CisgICAgICAgIGthLmRvUGhhc2UocHVibEtleSwgdHJ1ZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrYS5nZW5lcmF0ZVNlY3JldChiYjEsIDApOworICAgICAgICAgICAgZmFpbCgiU2hvcnRCdWZmZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU2hvcnRCdWZmZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZW5lcmF0ZVNlY3JldExqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGNyZWF0ZUtleXMoKTsKKyAgICAgICAgS2V5QWdyZWVtZW50W10ga0FncyA9IGNyZWF0ZUtBcygpOworICAgICAgICBLZXlBZ3JlZW1lbnQga2EgPSBLZXlBZ3JlZW1lbnQuZ2V0SW5zdGFuY2UoIkRIIik7CisKKyAgICAgICAgYnl0ZVtdIGJiMSA9IG5ldyBieXRlWzFdOworICAgICAgICB0cnkgeworICAgICAgICAgICAga2EuZ2VuZXJhdGVTZWNyZXQoImRoIik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBrYS5pbml0KHByaXZLZXkpOworICAgICAgICBrYS5kb1BoYXNlKHB1YmxLZXksIHRydWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAga2EuZ2VuZXJhdGVTZWNyZXQoIldyb25nIGFsZyBuYW1lIik7CisgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5pdExqYXZhX3NlY3VyaXR5X0tleUxqYXZhX3NlY3VyaXR5X1NlY3VyZVJhbmRvbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBjcmVhdGVLZXlzKCk7CisgICAgICAgIEtleUFncmVlbWVudFtdIGtBZ3MgPSBjcmVhdGVLQXMoKTsKKyAgICAgICAgS2V5QWdyZWVtZW50IGthID0gS2V5QWdyZWVtZW50LmdldEluc3RhbmNlKCJESCIpOworCisgICAgICAgIGthLmluaXQocHJpdktleSwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGthLmluaXQocHVibEtleSwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWRLZXlFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vS2V5R2VuZXJhdG9yU3BpVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0tleUdlbmVyYXRvclNwaVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YWRkOTllCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL0tleUdlbmVyYXRvclNwaVRlc3QuamF2YQpAQCAtMCwwICsxLDk2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CitpbXBvcnQgamF2YXguY3J5cHRvLktleUdlbmVyYXRvclNwaTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2VjcmV0S2V5OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5zdXBwb3J0Lk15S2V5R2VuZXJhdG9yU3BpOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5LZXlHZW5lcmF0b3JTcGk8L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBLZXlHZW5lcmF0b3JTcGlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIGNsYXNzIE1vY2tfS2V5R2VuZXJhdG9yU3BpIGV4dGVuZHMgTXlLZXlHZW5lcmF0b3JTcGkgeworCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgU2VjcmV0S2V5IGVuZ2luZUdlbmVyYXRlS2V5KCkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVuZ2luZUdlbmVyYXRlS2V5KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChTZWN1cmVSYW5kb20gcmFuZG9tKSB7CisgICAgICAgICAgICBzdXBlci5lbmdpbmVJbml0KHJhbmRvbSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtcywgU2VjdXJlUmFuZG9tIHJhbmRvbSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlci5lbmdpbmVJbml0KHBhcmFtcywgcmFuZG9tKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0KGludCBrZXlzaXplLCBTZWN1cmVSYW5kb20gcmFuZG9tKSB7CisgICAgICAgICAgICBzdXBlci5lbmdpbmVJbml0KGtleXNpemUsIHJhbmRvbSk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPktleUdlbmVyYXRvclNwaTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzCisgICAgICogS2V5R2VuZXJhdG9yU3BpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEtleUdlbmVyYXRvclNwaTAxKCkgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBNb2NrX0tleUdlbmVyYXRvclNwaSBrZ1NwaSA9IG5ldyBNb2NrX0tleUdlbmVyYXRvclNwaSgpOworICAgICAgICBhc3NlcnROdWxsKCJOb3QgbnVsbCByZXN1bHQiLCBrZ1NwaS5lbmdpbmVHZW5lcmF0ZUtleSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtnU3BpLmVuZ2luZUluaXQoNzcsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAga2dTcGkuZW5naW5lSW5pdChuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBhcHMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAga2dTcGkuZW5naW5lSW5pdChhcHMsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gcGFyYW1ldGVyIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgYXBzID0gbmV3IEFQU3BlY1NwaSgpOworICAgICAgICBrZ1NwaS5lbmdpbmVJbml0KGFwcywgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICB9CisKK30KKworY2xhc3MgQVBTcGVjU3BpIGltcGxlbWVudHMgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyB7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9LZXlHZW5lcmF0b3JUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vS2V5R2VuZXJhdG9yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2YjUwZTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vS2V5R2VuZXJhdG9yVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTMzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRFNBUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuUlNBS2V5R2VuUGFyYW1ldGVyU3BlYzsKKworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXI7CitpbXBvcnQgamF2YXguY3J5cHRvLktleUdlbmVyYXRvcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uS2V5R2VuZXJhdG9yU3BpOworaW1wb3J0IGphdmF4LmNyeXB0by5TZWNyZXRLZXk7CitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuSXZQYXJhbWV0ZXJTcGVjOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5zdXBwb3J0Lk15S2V5R2VuZXJhdG9yU3BpOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlNwaUVuZ1V0aWxzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisKKy8qKgorICogVGVzdHMgZm9yIEtleUdlbmVyYXRvciBjb25zdHJ1Y3RvciBhbmQgbWV0aG9kcworICoKKyAqLworcHVibGljIGNsYXNzIEtleUdlbmVyYXRvclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBzcnZLZXlHZW5lcmF0b3IgPSAiS2V5R2VuZXJhdG9yIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIHZhbGlkQWxnb3JpdGhtc0tleUdlbmVyYXRvciBbXSA9CisgICAgICAgIHsiREVTZWRlIiwgIkRFUyIsICJBRVMiLCAiSG1hY01ENSJ9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFtdIHZhbGlkS2V5U2l6ZXMgPSB7IDE2OCwgNTYsIDI1NiwgNTZ9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGRlZmF1bHRLZXlTaXplID0gLTE7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZGVmYXVsdEFsZ29yaXRobSA9IG51bGw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZGVmYXVsdFByb3ZpZGVyTmFtZSA9IG51bGw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBQcm92aWRlciBkZWZhdWx0UHJvdmlkZXIgPSBudWxsOworCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBERUZTdXBwb3J0ZWQgPSBmYWxzZTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOb3RTdXBwb3J0TXNnID0gIlRoZXJlIGlzIG5vIHN1aXRhYmxlIHByb3ZpZGVyIGZvciBLZXlHZW5lcmF0b3IiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gaW52YWxpZFZhbHVlcyA9IFNwaUVuZ1V0aWxzLmludmFsaWRWYWx1ZXM7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSB2YWxpZFZhbHVlcyA9IG5ldyBTdHJpbmdbM107CisKKyAgICBzdGF0aWMgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkQWxnb3JpdGhtc0tleUdlbmVyYXRvci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyID0gU3BpRW5nVXRpbHMuaXNTdXBwb3J0KHZhbGlkQWxnb3JpdGhtc0tleUdlbmVyYXRvcltpXSwKKyAgICAgICAgICAgICAgICBzcnZLZXlHZW5lcmF0b3IpOworICAgICAgICAgICAgREVGU3VwcG9ydGVkID0gKGRlZmF1bHRQcm92aWRlciAhPSBudWxsKTsKKyAgICAgICAgICAgIGlmIChERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgICAgICBkZWZhdWx0QWxnb3JpdGhtID0gdmFsaWRBbGdvcml0aG1zS2V5R2VuZXJhdG9yW2ldOworICAgICAgICAgICAgICAgIGRlZmF1bHRLZXlTaXplID0gdmFsaWRLZXlTaXplc1tpXTsKKyAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lID0gZGVmYXVsdFByb3ZpZGVyLmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1swXSA9IGRlZmF1bHRBbGdvcml0aG07CisgICAgICAgICAgICAgICAgdmFsaWRWYWx1ZXNbMV0gPSBkZWZhdWx0QWxnb3JpdGhtLnRvVXBwZXJDYXNlKCk7CisgICAgICAgICAgICAgICAgdmFsaWRWYWx1ZXNbMl0gPSBkZWZhdWx0QWxnb3JpdGhtLnRvTG93ZXJDYXNlKCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIEtleUdlbmVyYXRvcltdIGNyZWF0ZUtHcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgfQorCisgICAgICAgIEtleUdlbmVyYXRvciBbXSBrZyA9IG5ldyBLZXlHZW5lcmF0b3JbM107CisgICAgICAgIGtnWzBdID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKGRlZmF1bHRBbGdvcml0aG0pOworICAgICAgICBrZ1sxXSA9IEtleUdlbmVyYXRvci5nZXRJbnN0YW5jZShkZWZhdWx0QWxnb3JpdGhtLCBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICBrZ1syXSA9IEtleUdlbmVyYXRvci5nZXRJbnN0YW5jZShkZWZhdWx0QWxnb3JpdGhtLCBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgcmV0dXJuIGtnOworICAgIH0KKworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+S2V5R2VuZXJhdG9yPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IHJldHVybnMKKyAgICAgKiBLZXlHZW5lcmF0b3Igb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEtleUdlbmVyYXRvcigpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgS2V5R2VuZXJhdG9yU3BpIHNwaSA9IG5ldyBNeUtleUdlbmVyYXRvclNwaSgpOworICAgICAgICBLZXlHZW5lcmF0b3Iga2V5RyA9IG5ldyBteUtleUdlbmVyYXRvcihzcGksIGRlZmF1bHRQcm92aWRlciwKKyAgICAgICAgICAgICAgICBkZWZhdWx0QWxnb3JpdGhtKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwga2V5Ry5nZXRBbGdvcml0aG0oKSwKKyAgICAgICAgICAgICAgICBkZWZhdWx0QWxnb3JpdGhtKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBrZXlHLmdldFByb3ZpZGVyKCksIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1zID0gbnVsbDsKKyAgICAgICAgaW50IGtleXNpemUgPSAwOworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5Ry5pbml0KHBhcmFtcywgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlHLmluaXQoa2V5c2l6ZSwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBrZXlHID0gbmV3IG15S2V5R2VuZXJhdG9yKG51bGwsIG51bGwsIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJBbGdvcml0aG0gbXVzdCBiZSBudWxsIiwga2V5Ry5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgIGFzc2VydE51bGwoIlByb3ZpZGVyIG11c3QgYmUgbnVsbCIsIGtleUcuZ2V0UHJvdmlkZXIoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleUcuaW5pdChwYXJhbXMsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlHLmluaXQoa2V5c2l6ZSwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBvciBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPiBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKSA8L2NvZGU+IG1ldGhvZCBBc3NlcnRpb25zOgorICAgICAqIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBudWxsIHRocm93cworICAgICAqIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpc25vdCBhdmFpbGFibGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2VTdHJpbmcwMSgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gaWYgYWxnb3JpdGhtIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBLZXlHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPiBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKSA8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbnM6IHJldHVybnMgS2V5R2VuZXJhdG9yIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZVN0cmluZzAyKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIEtleUdlbmVyYXRvciBrZXlHOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBrZXlHID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGtleUcuZ2V0QWxnb3JpdGhtKCksIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogVGVzdCBmb3IgPGNvZGU+IGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcik8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbnM6CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzbm90IGF2YWlsYWJsZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZVN0cmluZ1N0cmluZzAxKCkgdGhyb3dzCisgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleUdlbmVyYXRvci5nZXRJbnN0YW5jZShudWxsLCBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIGlmIGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0sIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogVGVzdCBmb3IgPGNvZGU+IGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcik8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbnM6CisgICAgICogdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aGVuIHByb3ZpZGVyIGlzIG51bGwgb3IgZW1wdHkKKyAgICAgKiB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gd2hlbiBwcm92aWRlciBoYXMgbm90IGJlIGNvbmZpZ3VyZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2VTdHJpbmdTdHJpbmcwMigpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHByb3ZpZGVyID0gbnVsbDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBLZXlHZW5lcmF0b3IuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIHByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBudWxsIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBLZXlHZW5lcmF0b3IuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sICIiKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBlbXB0eSIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZvciAoaW50IGogPSAxOyBqIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIEtleUdlbmVyYXRvci5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgaW52YWxpZFZhbHVlc1tqXSk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIChhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KHZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIiBwcm92aWRlcjogIikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbal0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUZXN0IGZvciA8Y29kZT4gZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uczogcmV0dXJucyBLZXlHZW5lcmF0b3Igb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlU3RyaW5nU3RyaW5nMDMoKSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIEtleUdlbmVyYXRvciBrZXlHOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBrZXlHID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGtleUcuZ2V0QWxnb3JpdGhtKCksIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwga2V5Ry5nZXRQcm92aWRlcigpLmdldE5hbWUoKSwgZGVmYXVsdFByb3ZpZGVyTmFtZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPiBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBQcm92aWRlciBwcm92aWRlcik8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbnM6CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzbm90IGF2YWlsYWJsZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZVN0cmluZ1Byb3ZpZGVyMDEoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleUdlbmVyYXRvci5nZXRJbnN0YW5jZShudWxsLCBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gaWYgYWxnb3JpdGhtIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBLZXlHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgLyoKKyAgICAgKiBUZXN0IGZvciA8Y29kZT4gZ2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgUHJvdmlkZXIgcHJvdmlkZXIpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb25zOgorICAgICAqIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlU3RyaW5nUHJvdmlkZXIwMigpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBwcm92aWRlciA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBLZXlHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwgcHJvdmlkZXIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogVGVzdCBmb3IgPGNvZGU+IGdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uczogcmV0dXJucyBLZXlHZW5lcmF0b3Igb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlU3RyaW5nUHJvdmlkZXIwMygpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBLZXlHZW5lcmF0b3Iga2V5QTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAga2V5QSA9IEtleUdlbmVyYXRvci5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGtleUEuZ2V0QWxnb3JpdGhtKCksIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwga2V5QS5nZXRQcm92aWRlcigpLCBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5pbml0KGludCBrZXlzaXplKTwvY29kZT4gYW5kCisgICAgICogPGNvZGU+aW5pdChpbnQga2V5c2l6ZSwgU2VjdXJlUmFuZG9tIHJhbmRvbSk8L2NvZGU+IG1ldGhvZHMKKyAgICAgKiBBc3NlcnRpb246IHRocm93cyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIGlmIGtleXNpemUgaXMgd3JvbmcKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbml0S2V5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGUgZmxhZyA9IDB4RjsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRlZmF1bHRBbGdvcml0aG0KKyAgICAgICAgICAgICAgICAuZXF1YWxzKHZhbGlkQWxnb3JpdGhtc0tleUdlbmVyYXRvclt2YWxpZEFsZ29yaXRobXNLZXlHZW5lcmF0b3IubGVuZ3RoIC0gMV0pKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaW50W10gc2l6ZSA9IHsgSW50ZWdlci5NSU5fVkFMVUUsIC0xLCAwLCAxMTIsIDE2OCwgSW50ZWdlci5NQVhfVkFMVUUgfTsKKyAgICAgICAgS2V5R2VuZXJhdG9yW10ga2dzID0gY3JlYXRlS0dzKCk7CisgICAgICAgIFNlY3VyZVJhbmRvbSByYW5kb20gPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgc2l6ZS5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtnc1tpXS5pbml0KHNpemVbal0pOworICAgICAgICAgICAgICAgICAgICBmbGFnICY9IDB4RTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICAgICAgICAgICAgICBmbGFnICY9IDB4RDsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBrZ3NbaV0uaW5pdChzaXplW2pdLCByYW5kb20pOworICAgICAgICAgICAgICAgICAgICBmbGFnICY9IDB4QjsKKyAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICAgICAgICAgICBmbGFnICY9IDB4NzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZShmbGFnID09IDApOworICAgIH0KKworICAgIC8qCisgICAgICogVGVzdCBmb3IgPGNvZGU+aW5pdChBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtcyk8L2NvZGU+IGFuZAorICAgICAqIDxjb2RlPmluaXQoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMsIFNlY3VyZVJhbmRvbSByYW5kb20pPC9jb2RlPiBtZXRob2RzCisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB3aGVuIHBhcmFtcyBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEluaXRQYXJhbXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgS2V5R2VuZXJhdG9yIFtdIGtncyA9IGNyZWF0ZUtHcygpOworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIGFwcyA9IG51bGw7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2dzW2ldLmluaXQoYXBzKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2dzW2ldLmluaXQoYXBzLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZW5lcmF0ZUtleSgpPC9jb2RlPiBhbmQKKyAgICAgKiA8Y29kZT5pbml0KFNlY3VyZVJhbmRvbSByYW5kb20pPC9jb2RlPiBtZXRob2RzCisgICAgICogPGNvZGU+aW5pdChpbnQga2V5c2l6ZSwgU2VjdXJlUmFuZG9tIHJhbmRvbSk8L2NvZGU+IG1ldGhvZHMKKyAgICAgKiA8Y29kZT5pbml0KGludCBrZXlzaXplKTwvY29kZT4gbWV0aG9kcworICAgICAqIDxjb2RlPmluaXQoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMsIFNlY3VyZVJhbmRvbSByYW5kb20pPC9jb2RlPiBtZXRob2RzCisgICAgICogPGNvZGU+aW5pdChBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtcyk8L2NvZGU+IG1ldGhvZHMKKyAgICAgKiBBc3NlcnRpb25zOgorICAgICAqIGluaXRpYWxpemVzIEtleUdlbmVyYXRvcjsKKyAgICAgKiByZXR1cm5zIFNlY3JldEtleSBvYmplY3QKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmF0ZUtleSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBTZWNyZXRLZXkgc0tleTsKKyAgICAgICAgU3RyaW5nIGRBbCA9IGRlZmF1bHRBbGdvcml0aG0udG9VcHBlckNhc2UoKTsKKworICAgICAgICBLZXlHZW5lcmF0b3JbXSBrZ3MgPSBjcmVhdGVLR3MoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGtncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc0tleSA9IGtnc1tpXS5nZW5lcmF0ZUtleSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwgc0tleS5nZXRBbGdvcml0aG0oKQorICAgICAgICAgICAgICAgICAgICAudG9VcHBlckNhc2UoKSwgZEFsKTsKKyAgICAgICAgICAgIGtnc1tpXS5pbml0KG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICBzS2V5ID0ga2dzW2ldLmdlbmVyYXRlS2V5KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBzS2V5LmdldEFsZ29yaXRobSgpCisgICAgICAgICAgICAgICAgICAgIC50b1VwcGVyQ2FzZSgpLCBkQWwpOworICAgICAgICAgICAga2dzW2ldLmluaXQoZGVmYXVsdEtleVNpemUpOworICAgICAgICAgICAgc0tleSA9IGtnc1tpXS5nZW5lcmF0ZUtleSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwgc0tleS5nZXRBbGdvcml0aG0oKQorICAgICAgICAgICAgICAgICAgICAudG9VcHBlckNhc2UoKSwgZEFsKTsKKyAgICAgICAgICAgIGtnc1tpXS5pbml0KGRlZmF1bHRLZXlTaXplLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAgc0tleSA9IGtnc1tpXS5nZW5lcmF0ZUtleSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwgc0tleS5nZXRBbGdvcml0aG0oKQorICAgICAgICAgICAgICAgICAgICAudG9VcHBlckNhc2UoKSwgZEFsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0QWxnb3JpdGhtKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIEtleUdlbmVyYXRvciBrZyA9IG51bGw7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZEFsZ29yaXRobXNLZXlHZW5lcmF0b3IubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGtnID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKHZhbGlkQWxnb3JpdGhtc0tleUdlbmVyYXRvcltpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModmFsaWRBbGdvcml0aG1zS2V5R2VuZXJhdG9yW2ldLCBrZy5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgIH0KKworICAgICAgICBrZyA9IG5ldyBteUtleUdlbmVyYXRvcihudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChrZy5nZXRBbGdvcml0aG0oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQcm92aWRlciAoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5R2VuZXJhdG9yIGtnID0gbnVsbDsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkQWxnb3JpdGhtc0tleUdlbmVyYXRvci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAga2cgPSBLZXlHZW5lcmF0b3IuZ2V0SW5zdGFuY2UodmFsaWRBbGdvcml0aG1zS2V5R2VuZXJhdG9yW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoa2cuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgIH0KKworICAgICAgICBrZyA9IG5ldyBteUtleUdlbmVyYXRvcihudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChrZy5nZXRQcm92aWRlcigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luaXRJTGphdmFfc2VjdXJpdHlfU2VjdXJlUmFuZG9tKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIFNlY3VyZVJhbmRvbSByYW5kb20gPSBudWxsOworICAgICAgICBLZXlHZW5lcmF0b3Iga2cgPSBudWxsOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRBbGdvcml0aG1zS2V5R2VuZXJhdG9yLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBrZyA9IEtleUdlbmVyYXRvci5nZXRJbnN0YW5jZSh2YWxpZEFsZ29yaXRobXNLZXlHZW5lcmF0b3JbaV0pOworICAgICAgICAgICAgcmFuZG9tID0gbmV3IFNlY3VyZVJhbmRvbSgpOworICAgICAgICAgICAga2cuaW5pdCh2YWxpZEtleVNpemVzW2ldLCByYW5kb20pOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChrZy5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgfQorCisgICAgICAgIGtnID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKHZhbGlkQWxnb3JpdGhtc0tleUdlbmVyYXRvclswXSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtnLmluaXQoNSwgcmFuZG9tKTsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0xqYXZhX3NlY3VyaXR5X1NlY3VyZVJhbmRvbSgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBTZWN1cmVSYW5kb20gcmFuZG9tID0gbnVsbDsKKyAgICAgICAgS2V5R2VuZXJhdG9yIGtnID0gbnVsbDsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkQWxnb3JpdGhtc0tleUdlbmVyYXRvci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAga2cgPSBLZXlHZW5lcmF0b3IuZ2V0SW5zdGFuY2UodmFsaWRBbGdvcml0aG1zS2V5R2VuZXJhdG9yW2ldKTsKKyAgICAgICAgICAgIHJhbmRvbSA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgICAgIGtnLmluaXQocmFuZG9tKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoa2cuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luaXRMamF2YV9zZWN1cml0eV9zcGVjX0FsZ29yaXRobVBhcmFtZXRlclNwZWMgKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBLZXlHZW5lcmF0b3Iga2cgPSBudWxsOworCisgICAgICAgIEl2UGFyYW1ldGVyU3BlYyBhcHMgPSBudWxsOworICAgICAgICBTZWN1cmVSYW5kb20gc3IgPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisKKyAgICAgICAgYnl0ZVtdIGl2ID0gbnVsbDsKKyAgICAgICAgaXYgPSBuZXcgYnl0ZVs4XTsKKyAgICAgICAgc3IubmV4dEJ5dGVzKGl2KTsKKyAgICAgICAgYXBzID0gbmV3IEl2UGFyYW1ldGVyU3BlYyhpdik7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZEFsZ29yaXRobXNLZXlHZW5lcmF0b3IubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGtnID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKHZhbGlkQWxnb3JpdGhtc0tleUdlbmVyYXRvcltpXSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtnLmluaXQoYXBzKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChrZy5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgfQorICAgIH0KK30KKworLyoqCisgKiBBZGRpdGlvbmFsIGNsYXNzIGZvciBLZXlHZW5lcmF0b3IgY29uc3RydWN0b3IgdmVyaWZpY2F0aW9uCisgKi8KK2NsYXNzIG15S2V5R2VuZXJhdG9yIGV4dGVuZHMgS2V5R2VuZXJhdG9yIHsKKworICAgIHB1YmxpYyBteUtleUdlbmVyYXRvcihLZXlHZW5lcmF0b3JTcGkga2V5QWdyZWVTcGksIFByb3ZpZGVyIHByb3ZpZGVyLAorICAgICAgICAgICAgU3RyaW5nIGFsZ29yaXRobSkgeworICAgICAgICBzdXBlcihrZXlBZ3JlZVNwaSwgcHJvdmlkZXIsIGFsZ29yaXRobSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL01hY1NwaVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9NYWNTcGlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTUwYjI3YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9NYWNTcGlUZXN0LmphdmEKQEAgLTAsMCArMSwyNTQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0bzsKKworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKKworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLlNlY3JldEtleVNwZWM7CitpbXBvcnQgamF2YXguY3J5cHRvLk1hY1NwaTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuc3VwcG9ydC5NeU1hY1NwaTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5NYWNTcGk8L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBNYWNTcGlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworY2xhc3MgTW9ja19NYWNTcGkgZXh0ZW5kcyBNeU1hY1NwaSB7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuZ2luZURvRmluYWwoKSB7CisgICAgICAgIHJldHVybiBzdXBlci5lbmdpbmVEb0ZpbmFsKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBlbmdpbmVHZXRNYWNMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBzdXBlci5lbmdpbmVHZXRNYWNMZW5ndGgoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0KEtleSBrZXksIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1zKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLmVuZ2luZUluaXQoa2V5LCBwYXJhbXMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVJlc2V0KCkgeworICAgICAgICBzdXBlci5lbmdpbmVSZXNldCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShieXRlIGlucHV0KSB7CisgICAgICAgIHN1cGVyLmVuZ2luZVVwZGF0ZShpbnB1dCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGVbXSBpbnB1dCwgaW50IG9mZnNldCwgaW50IGxlbikgeworICAgICAgICBzdXBlci5lbmdpbmVVcGRhdGUoaW5wdXQsIG9mZnNldCwgbGVuKTsKKyAgICB9CisKK30KKworY2xhc3MgTW9ja19NYWNTcGkxIGV4dGVuZHMgTXlNYWNTcGkxIHsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBieXRlW10gZW5naW5lRG9GaW5hbCgpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmVuZ2luZURvRmluYWwoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IGVuZ2luZUdldE1hY0xlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmVuZ2luZUdldE1hY0xlbmd0aCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXQoS2V5IGtleSwgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLCBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuZW5naW5lSW5pdChrZXksIHBhcmFtcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lUmVzZXQoKSB7CisgICAgICAgIHN1cGVyLmVuZ2luZVJlc2V0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGUgaW5wdXQpIHsKKyAgICAgICAgc3VwZXIuZW5naW5lVXBkYXRlKGlucHV0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZVtdIGlucHV0LCBpbnQgb2Zmc2V0LCBpbnQgbGVuKSB7CisgICAgICAgIHN1cGVyLmVuZ2luZVVwZGF0ZShpbnB1dCwgb2Zmc2V0LCBsZW4pOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShCeXRlQnVmZmVyIGlucHV0KSB7CisgICAgICAgIHN1cGVyLmVuZ2luZVVwZGF0ZShpbnB1dCk7CisgICAgfQorCit9CisKKworY2xhc3MgTW9ja19NYWNTcGkyIGV4dGVuZHMgTXlNYWNTcGkyIHsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBieXRlW10gZW5naW5lRG9GaW5hbCgpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmVuZ2luZURvRmluYWwoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IGVuZ2luZUdldE1hY0xlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmVuZ2luZUdldE1hY0xlbmd0aCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXQoS2V5IGtleSwgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLCBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuZW5naW5lSW5pdChrZXksIHBhcmFtcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lUmVzZXQoKSB7CisgICAgICAgIHN1cGVyLmVuZ2luZVJlc2V0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGUgaW5wdXQpIHsKKyAgICAgICAgc3VwZXIuZW5naW5lVXBkYXRlKGlucHV0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZVtdIGlucHV0LCBpbnQgb2Zmc2V0LCBpbnQgbGVuKSB7CisgICAgICAgIHN1cGVyLmVuZ2luZVVwZGF0ZShpbnB1dCwgb2Zmc2V0LCBsZW4pOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShCeXRlQnVmZmVyIGlucHV0KSB7CisgICAgICAgIHN1cGVyLmVuZ2luZVVwZGF0ZShpbnB1dCk7CisgICAgfQorCit9CisKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPk1hY1NwaTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgTWFjU3BpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE1hY1NwaVRlc3RzMDEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTW9ja19NYWNTcGkgbVNwaSA9IG5ldyBNb2NrX01hY1NwaSgpOworCisgICAgICAgIGJ5dGUgW10gYmIxID0geyhieXRlKTEsIChieXRlKTIsIChieXRlKTMsIChieXRlKTQsIChieXRlKTV9OworICAgICAgICBTZWNyZXRLZXlTcGVjIHNrcyA9IG5ldyBTZWNyZXRLZXlTcGVjKGJiMSwgIlNIQTEiKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBNYWNMZW5ndGgiLCBtU3BpLmVuZ2luZUdldE1hY0xlbmd0aCgpLCAwKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbVNwaS5lbmdpbmVJbml0KG51bGwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBtU3BpLmVuZ2luZUluaXQoc2tzLCBudWxsKTsKKworICAgICAgICBieXRlW10gYmIgPSBtU3BpLmVuZ2luZURvRmluYWwoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJiLmxlbmd0aCwgMCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtU3BpLmNsb25lKCk7CisgICAgICAgICAgICBmYWlsKCJDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biBhcyBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBNb2NrX01hY1NwaTEgbVNwaTEgPSBuZXcgTW9ja19NYWNTcGkxKCk7CisgICAgICAgIG1TcGkxLmNsb25lKCk7CisKKyAgICAgICAgYnl0ZSBbXSBiYmIgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYmJiLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBiYmJbaV0gPSAoYnl0ZSlpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtU3BpMS5lbmdpbmVJbml0KG51bGwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgbVNwaTEuZW5naW5lSW5pdChza3MsIG51bGwpOworCisgICAgICAgIEJ5dGVCdWZmZXIgYnl0ZUJ1ZiA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApOworICAgICAgICBieXRlQnVmLnB1dChiYmIpOworICAgICAgICBieXRlQnVmLnBvc2l0aW9uKDUpOworICAgICAgICBpbnQgYmVmb3JlVXAgPSBieXRlQnVmLnJlbWFpbmluZygpOworICAgICAgICBtU3BpMS5lbmdpbmVVcGRhdGUoYnl0ZUJ1Zik7CisgICAgICAgIGJiID0gbVNwaTEuZW5naW5lRG9GaW5hbCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCByZXN1bHQgb2YgZW5naW5lRG9GaW5hbCIsIGJiLmxlbmd0aCwgYmVmb3JlVXApOworCisgICAgICAgIE1vY2tfTWFjU3BpMiBtU3BpMiA9IG5ldyBNb2NrX01hY1NwaTIoKTsKKworICAgICAgICBtU3BpMi5lbmdpbmVJbml0KG51bGwsIG51bGwpOworICAgICAgICBtU3BpMi5lbmdpbmVJbml0KHNrcywgbnVsbCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1TcGkyLmNsb25lKCk7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGUgW10gYmJ1ZiA9IHsoYnl0ZSk1LCAoYnl0ZSk0LCAoYnl0ZSkzLCAoYnl0ZSkyLCAoYnl0ZSkxfTsKKyAgICAgICAgYnl0ZUJ1ZiA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoNSk7CisgICAgICAgIGJ5dGVCdWYucHV0KGJidWYpOworICAgICAgICBieXRlQnVmLnBvc2l0aW9uKDUpOworICAgICAgICBpZiAoIWJ5dGVCdWYuaGFzUmVtYWluaW5nKCkpIHsKKyAgICAgICAgICAgIG1TcGkyLmVuZ2luZVVwZGF0ZShieXRlQnVmKTsKKyAgICAgICAgfQorICAgIH0KK30KKworCitjbGFzcyBNeU1hY1NwaTEgZXh0ZW5kcyBNeU1hY1NwaSB7CisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgTXlNYWNTcGkxKCk7CisgICAgfQorfQorCitjbGFzcyBNeU1hY1NwaTIgZXh0ZW5kcyBNYWNTcGkgeworICAgIHByb3RlY3RlZCBpbnQgZW5naW5lR2V0TWFjTGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0KEtleSBrZXksIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1zKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24sIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShieXRlIGlucHV0KSB7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGVbXSBpbnB1dCwgaW50IG9mZnNldCwgaW50IGxlbikgeworICAgIH0KKworICAgIHByb3RlY3RlZCBieXRlW10gZW5naW5lRG9GaW5hbCgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBieXRlWzBdOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVJlc2V0KCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9NYWNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vTWFjVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU4MDhiYzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vTWFjVGVzdC5qYXZhCkBAIC0wLDAgKzEsODUwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5EU0FQYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5QU1NQYXJhbWV0ZXJTcGVjOworCitpbXBvcnQgamF2YXguY3J5cHRvLk1hYzsKK2ltcG9ydCBqYXZheC5jcnlwdG8uTWFjU3BpOworaW1wb3J0IGphdmF4LmNyeXB0by5TaG9ydEJ1ZmZlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5ESEdlblBhcmFtZXRlclNwZWM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5TZWNyZXRLZXlTcGVjOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5zdXBwb3J0Lk15TWFjU3BpOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlNwaUVuZ1V0aWxzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworLyoqCisgKiBUZXN0cyBmb3IgTWFjIGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcworICoKKyAqLworcHVibGljIGNsYXNzIE1hY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBzcnZNYWMgPSAiTWFjIjsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZWZhdWx0QWxnb3JpdGhtID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZWZhdWx0UHJvdmlkZXJOYW1lID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIFByb3ZpZGVyIGRlZmF1bHRQcm92aWRlciA9IG51bGw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIERFRlN1cHBvcnRlZCA9IGZhbHNlOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5vdFN1cHBvcnRlZE1zZyA9ICJUaGVyZSBpcyBubyBzdWl0YWJsZSBwcm92aWRlciBmb3IgTWFjIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGludmFsaWRWYWx1ZXMgPSBTcGlFbmdVdGlscy5pbnZhbGlkVmFsdWVzOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gdmFsaWRWYWx1ZXMgPSBuZXcgU3RyaW5nWzNdOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgdmFsaWRBbGdvcml0aG1zTWFjIFtdID0KKyAgICAgICAgeyJIbWFjU0hBMSIsICJIbWFjTUQ1IiwgIkhtYWNTSEEyNTYiLCAiSG1hY1NIQTM4NCIsICJIbWFjU0hBNTEyIn07CisKKworICAgIHN0YXRpYyB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRBbGdvcml0aG1zTWFjLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXIgPSBTcGlFbmdVdGlscy5pc1N1cHBvcnQodmFsaWRBbGdvcml0aG1zTWFjW2ldLAorICAgICAgICAgICAgICAgICAgICBzcnZNYWMpOworICAgICAgICAgICAgREVGU3VwcG9ydGVkID0gKGRlZmF1bHRQcm92aWRlciAhPSBudWxsKTsKKyAgICAgICAgICAgIGlmIChERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgICAgICBkZWZhdWx0QWxnb3JpdGhtID0gdmFsaWRBbGdvcml0aG1zTWFjW2ldOworICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUgPSBkZWZhdWx0UHJvdmlkZXIuZ2V0TmFtZSgpOworICAgICAgICAgICAgICAgIHZhbGlkVmFsdWVzWzBdID0gZGVmYXVsdEFsZ29yaXRobTsKKyAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1sxXSA9IGRlZmF1bHRBbGdvcml0aG0udG9VcHBlckNhc2UoKTsKKyAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1syXSA9IGRlZmF1bHRBbGdvcml0aG0udG9Mb3dlckNhc2UoKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgTWFjIFtdIGNyZWF0ZU1hY3MoKSB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgTWFjIG0gW10gPSBuZXcgTWFjWzNdOworICAgICAgICAgICAgbVswXSA9IE1hYy5nZXRJbnN0YW5jZShkZWZhdWx0QWxnb3JpdGhtKTsKKyAgICAgICAgICAgIG1bMV0gPSBNYWMuZ2V0SW5zdGFuY2UoZGVmYXVsdEFsZ29yaXRobSwgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgIG1bMl0gPSBNYWMuZ2V0SW5zdGFuY2UoZGVmYXVsdEFsZ29yaXRobSwgZGVmYXVsdFByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICByZXR1cm4gbTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbnVsbAorICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RNYWMwMSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE1hYy5nZXRJbnN0YW5jZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBNYWMuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGU6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgTWFjIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RNYWMwMigpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0ZWRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIE1hYyBtYWM7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG1hYyA9IE1hYy5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBtYWMuZ2V0QWxnb3JpdGhtKCksIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aGVuIHByb3ZpZGVyIGlzIG51bGwgb3IgZW1wdHkKKyAgICAgKiB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBub3QgYXZhaWxhYmxlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE1hYzAzKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0ZWRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBwcm92aWRlciA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTWFjLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBwcm92aWRlcik7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gcHJvdmlkZXIgaXMgbnVsbCIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTWFjLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCAiIik7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gcHJvdmlkZXIgaXMgZW1wdHkiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKGludCBqID0gMTsgaiA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBNYWMuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIGludmFsaWRWYWx1ZXNbal0pOworICAgICAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdCh2YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIgcHJvdmlkZXI6ICIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChpbnZhbGlkVmFsdWVzW2pdKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcik8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbnVsbAorICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RNYWMwNCgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydGVkTXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgTWFjLmdldEluc3RhbmNlKG51bGwsIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gd2hlbiBhbGdvcml0aG0gaXMgbnVsbCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIE1hYy5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldLCBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbXVzdCBiZSB0aHJvd3Mgd2hlbiBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZTogIgorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChpbnZhbGlkVmFsdWVzW2ldKSk7CisgICAgICAgICAgICB9IGNhdGNoKCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcik8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBNYWMgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE1hYzA1KCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0ZWRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIE1hYyBtYWM7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG1hYyA9IE1hYy5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgZGVmYXVsdFByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBtYWMuZ2V0QWxnb3JpdGhtKCksIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwgbWFjLmdldFByb3ZpZGVyKCkuZ2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RNYWMwNigpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydGVkTXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBwcm92aWRlciA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTWFjLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBwcm92aWRlcik7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gcHJvdmlkZXIgaXMgbnVsbCIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBQcm92aWRlciBwcm92aWRlcik8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbnVsbAorICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbm90IGF2YWlsYWJsZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RNYWMwNygpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydGVkTXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgTWFjLmdldEluc3RhbmNlKG51bGwsIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBvciBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biB3aGVuIGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTWFjLmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0sIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGU6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIE1hYyBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFjMDgoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgTWFjIG1hYzsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbWFjID0gTWFjLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwgbWFjLmdldEFsZ29yaXRobSgpLCB2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsIG1hYy5nZXRQcm92aWRlcigpLCBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICB9CisgICAgfQorICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnVwZGF0ZTwvY29kZT4gYW5kIDxjb2RlPmRvRmluYWw8L2NvZGU+IG1ldGhvZHMKKyAgICAgKiBBc3NlcnRpb246IHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gd2hlbiBNYWMgaXMgbm90IGluaXRpYWxpemVkCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFjMDkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydGVkTXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBNYWMgW10gbWFjcyA9IGNyZWF0ZU1hY3MoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTWFjIG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIG1hY3MpOworICAgICAgICBieXRlIFtdIGJ1ZiA9IG5ldyBieXRlWzEwXTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiQnVmID0gQnl0ZUJ1ZmZlci53cmFwKGJ1ZiwgMCwgMTApOworICAgICAgICBieXRlIFtdIGJiID0geyhieXRlKTEsIChieXRlKTIsIChieXRlKTMsIChieXRlKTQsIChieXRlKTV9OworICAgICAgICBTZWNyZXRLZXlTcGVjIHNrcyA9IG5ldyBTZWNyZXRLZXlTcGVjKGJiLCAiU0hBMSIpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1hY3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbWFjc1tpXS51cGRhdGUoKGJ5dGUpMCk7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBtYWNzW2ldLnVwZGF0ZShidWYpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbWFjc1tpXS51cGRhdGUoYnVmLCAwLCAzKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG1hY3NbaV0udXBkYXRlKGJCdWYpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbWFjc1tpXS5kb0ZpbmFsKCk7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBtYWNzW2ldLmRvRmluYWwobmV3IGJ5dGVbMTBdKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG1hY3NbaV0uZG9GaW5hbChuZXcgYnl0ZVsxMF0sIDApOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgbWFjc1tpXS5pbml0KHNrcyk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG1hY3NbaV0uZG9GaW5hbChuZXcgYnl0ZVsxXSwgMCk7CisgICAgICAgICAgICAgICAgZmFpbCgiU2hvcnRCdWZmZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNob3J0QnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+ZG9GaW5hbChieXRlW10gb3V0cHV0LCBpbnQgb3V0T2Zmc2V0KTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOgorICAgICAqIHRocm93cyBTaG90QnVmZmVyRXhjZXB0aW9uIHdoZW4gb3V0T2Zmc2V0ICBpcyBuZWdhdGl2ZSBvcgorICAgICAqIG91dE9mZnNldCA+PSBvdXRwdXQubGVuZ3RoICBvciB3aGVuIGdpdmVuIGJ1ZmZlciBpcyBzbWFsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RNYWMxMCgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbFN0YXRlRXhjZXB0aW9uLCBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydGVkTXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBNYWNbXSBtYWNzID0gY3JlYXRlTWFjcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJNYWMgb2JqZWN0cyB3ZXJlIG5vdCBjcmVhdGVkIiwgbWFjcyk7CisgICAgICAgIGJ5dGVbXSBiID0geyAoYnl0ZSkgMCwgKGJ5dGUpIDAsIChieXRlKSAwLCAoYnl0ZSkgMCwgKGJ5dGUpIDAgfTsKKyAgICAgICAgYnl0ZVtdIGJ5dGVBID0gbmV3IGJ5dGVbYi5sZW5ndGhdOworICAgICAgICBTZWNyZXRLZXlTcGVjIHNrcyA9IG5ldyBTZWNyZXRLZXlTcGVjKGIsICJTSEExIik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFjcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbWFjc1tpXS5pbml0KHNrcyk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG1hY3NbaV0uZG9GaW5hbChudWxsLCAxMCk7CisgICAgICAgICAgICAgICAgZmFpbCgiU2hvcnRCdWZmZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNob3J0QnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbWFjc1tpXS5kb0ZpbmFsKGJ5dGVBLCAtNCk7CisgICAgICAgICAgICAgICAgZmFpbCgiU2hvcnRCdWZmZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNob3J0QnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbWFjc1tpXS5kb0ZpbmFsKGJ5dGVBLCAxMCk7CisgICAgICAgICAgICAgICAgZmFpbCgiU2hvcnRCdWZmZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNob3J0QnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbWFjc1tpXS5kb0ZpbmFsKG5ldyBieXRlWzFdLCAwKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTaG9ydEJ1ZmZlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2hvcnRCdWZmZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnl0ZVtdIHJlcyA9IG1hY3NbaV0uZG9GaW5hbCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBtYWNzW2ldLmRvRmluYWwobmV3IGJ5dGVbcmVzLmxlbmd0aCAtIDFdLCAwKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTaG9ydEJ1ZmZlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2hvcnRCdWZmZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+ZG9GaW5hbChieXRlW10gb3V0cHV0LCBpbnQgb3V0T2Zmc2V0KTwvY29kZT4gYW5kCisgICAgICogPGNvZGU+ZG9GaW5hbCgpPC9jb2RlPiBtZXRob2RzIEFzc2VydGlvbjogTWFjIHJlc3VsdCBpcyBzdG9yZWQgaW4KKyAgICAgKiBvdXRwdXQgYnVmZmVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE1hYzExKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24sIFNob3J0QnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydGVkTXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBNYWMgW10gbWFjcyA9IGNyZWF0ZU1hY3MoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTWFjIG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIG1hY3MpOworICAgICAgICBieXRlIFtdIGIgPSB7KGJ5dGUpMCwgKGJ5dGUpMCwgKGJ5dGUpMCwgKGJ5dGUpMCwgKGJ5dGUpMH07CisgICAgICAgIFNlY3JldEtleVNwZWMgc2NzID0gbmV3IFNlY3JldEtleVNwZWMoYiwgIlNIQTEiKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYWNzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBtYWNzW2ldLmluaXQoc2NzKTsKKyAgICAgICAgICAgIGJ5dGUgW10gcmVzMSA9IG1hY3NbaV0uZG9GaW5hbCgpOworICAgICAgICAgICAgYnl0ZSBbXSByZXMyID0gbmV3IGJ5dGVbcmVzMS5sZW5ndGggKyAxMF07CisgICAgICAgICAgICBtYWNzW2ldLmRvRmluYWwocmVzMiwgMCk7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHJlczEubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIk5vdCBlcXVhbHMgYnl0ZSBudW1iZXI6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoSW50ZWdlci50b1N0cmluZyhqKSksIHJlczFbal0sIHJlczJbal0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmRvRmluYWwoYnl0ZVtdIGlucHV0KTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiB1cGRhdGUgTWFjIGFuZCByZXR1cm5zIHJlc3VsdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RNYWMxMigpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbGxlZ2FsU3RhdGVFeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkS2V5RXhjZXB0aW9uICB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgTWFjIFtdIG1hY3MgPSBjcmVhdGVNYWNzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIk1hYyBvYmplY3RzIHdlcmUgbm90IGNyZWF0ZWQiLCBtYWNzKTsKKyAgICAgICAgYnl0ZSBbXSBiID0geyhieXRlKTAsIChieXRlKTAsIChieXRlKTAsIChieXRlKTAsIChieXRlKTB9OworICAgICAgICBieXRlIFtdIHVwZCA9IHsoYnl0ZSk1LCAoYnl0ZSk0LCAoYnl0ZSkzLCAoYnl0ZSkyLCAoYnl0ZSkxLCAoYnl0ZSkwfTsKKyAgICAgICAgU2VjcmV0S2V5U3BlYyBzY3MgPSBuZXcgU2VjcmV0S2V5U3BlYyhiLCAiU0hBMSIpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1hY3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG1hY3NbaV0uaW5pdChzY3MpOworICAgICAgICAgICAgYnl0ZSBbXSByZXMxID0gbWFjc1tpXS5kb0ZpbmFsKCk7CisgICAgICAgICAgICBieXRlIFtdIHJlczIgPSBtYWNzW2ldLmRvRmluYWwoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiUmVzdWx0cyBhcmUgbm90IHRoZSBzYW1lIiwgcmVzMS5sZW5ndGgsIHJlczIubGVuZ3RoKTsKKyAgICAgICAgICAgIGZvcihpbnQgdCA9IDA7IHQgPCByZXMxLmxlbmd0aDsgdCsrKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXN1bHRzIGFyZSBub3QgdGhlIHNhbWUiLCByZXMxW3RdLCByZXMyW3RdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlczIgPSBtYWNzW2ldLmRvRmluYWwodXBkKTsKKyAgICAgICAgICAgIG1hY3NbaV0udXBkYXRlKHVwZCk7CisgICAgICAgICAgICByZXMxID0gbWFjc1tpXS5kb0ZpbmFsKCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlJlc3VsdHMgYXJlIG5vdCB0aGUgc2FtZSIsIHJlczEubGVuZ3RoLCByZXMyLmxlbmd0aCk7CisgICAgICAgICAgICBmb3IoaW50IHQgPSAwOyB0IDwgcmVzMS5sZW5ndGg7IHQrKykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiUmVzdWx0cyBhcmUgbm90IHRoZSBzYW1lIiwgcmVzMVt0XSwgcmVzMlt0XSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT51cGRhdGUoYnl0ZVtdIGlucHV0LCBpbnQgb3V0c2V0LCBpbnQgbGVuKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gb2Zmc2V0IG9yIGxlbiBpcyBuZWdhdGl2ZSwKKyAgICAgKiBvZmZzZXQgKyBsZW4gPj0gaW5wdXQubGVuZ3RoCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE1hYzEzKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0ZWRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIE1hYyBbXSBtYWNzID0gY3JlYXRlTWFjcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJNYWMgb2JqZWN0cyB3ZXJlIG5vdCBjcmVhdGVkIiwgbWFjcyk7CisgICAgICAgIGJ5dGUgW10gYiA9IHsoYnl0ZSkwLCAoYnl0ZSkwLCAoYnl0ZSkwLCAoYnl0ZSkwLCAoYnl0ZSkwfTsKKyAgICAgICAgU2VjcmV0S2V5U3BlYyBzY3MgPSBuZXcgU2VjcmV0S2V5U3BlYyhiLCAiU0hBMSIpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1hY3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG1hY3NbaV0uaW5pdChzY3MpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBtYWNzW2ldLnVwZGF0ZShiLCAtMTAsIGIubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG1hY3NbaV0udXBkYXRlKGIsIDAsIC0xMCk7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBtYWNzW2ldLnVwZGF0ZShiLCAwLCBiLmxlbmd0aCArIDEpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbWFjc1tpXS51cGRhdGUoYiwgYi5sZW5ndGggLSAxLCAyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+dXBkYXRlKGJ5dGVbXSBpbnB1dCwgaW50IG91dHNldCwgaW50IGxlbik8L2NvZGU+IGFuZAorICAgICAqIDxjb2RlPnVwZGF0ZShieXRlW10gaW5wdXQ8L2NvZGU+CisgICAgICogbWV0aG9kcworICAgICAqIEFzc2VydGlvbjogdXBkYXRlcyBNYWMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFjMTQoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSWxsZWdhbFN0YXRlRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgTWFjIFtdIG1hY3MgPSBjcmVhdGVNYWNzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIk1hYyBvYmplY3RzIHdlcmUgbm90IGNyZWF0ZWQiLCBtYWNzKTsKKyAgICAgICAgYnl0ZSBbXSBiID0geyhieXRlKTAsIChieXRlKTAsIChieXRlKTAsIChieXRlKTAsIChieXRlKTB9OworICAgICAgICBieXRlIFtdIHVwZDEgPSB7KGJ5dGUpMCwgKGJ5dGUpMSwgKGJ5dGUpNSwgKGJ5dGUpNCwgKGJ5dGUpMywgKGJ5dGUpMn07CisgICAgICAgIGJ5dGUgW10gdXBkMiA9IHsoYnl0ZSk1LCAoYnl0ZSk0LCAoYnl0ZSkzLCAoYnl0ZSkyfTsKKyAgICAgICAgYnl0ZSBbXSByZXMxOworICAgICAgICBieXRlIFtdIHJlczI7CisgICAgICAgIFNlY3JldEtleVNwZWMgc2NzID0gbmV3IFNlY3JldEtleVNwZWMoYiwgIlNIQTEiKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYWNzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBtYWNzW2ldLmluaXQoc2NzKTsKKyAgICAgICAgICAgIG1hY3NbaV0udXBkYXRlKHVwZDEsIDIsIDQpOworICAgICAgICAgICAgcmVzMSA9IG1hY3NbaV0uZG9GaW5hbCgpOworICAgICAgICAgICAgbWFjc1tpXS5pbml0KHNjcyk7CisgICAgICAgICAgICBtYWNzW2ldLnVwZGF0ZSh1cGQyKTsKKyAgICAgICAgICAgIHJlczIgPSBtYWNzW2ldLmRvRmluYWwoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiUmVzdWx0cyBhcmUgbm90IHRoZSBzYW1lIiwgcmVzMS5sZW5ndGgsIHJlczIubGVuZ3RoKTsKKyAgICAgICAgICAgIGZvcihpbnQgdCA9IDA7IHQgPCByZXMxLmxlbmd0aDsgdCsrKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXN1bHRzIGFyZSBub3QgdGhlIHNhbWUiLCByZXMxW3RdLCByZXMyW3RdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG1hY3NbaV0uaW5pdChzY3MpOworICAgICAgICAgICAgbWFjc1tpXS51cGRhdGUoKGJ5dGUpNSk7CisgICAgICAgICAgICByZXMxID0gbWFjc1tpXS5kb0ZpbmFsKCk7CisgICAgICAgICAgICBtYWNzW2ldLmluaXQoc2NzKTsKKyAgICAgICAgICAgIG1hY3NbaV0udXBkYXRlKHVwZDEsMiwxKTsKKyAgICAgICAgICAgIHJlczIgPSBtYWNzW2ldLmRvRmluYWwoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiUmVzdWx0cyBhcmUgbm90IHRoZSBzYW1lIiwgcmVzMS5sZW5ndGgsIHJlczIubGVuZ3RoKTsKKyAgICAgICAgICAgIGZvcihpbnQgdCA9IDA7IHQgPCByZXMxLmxlbmd0aDsgdCsrKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXN1bHRzIGFyZSBub3QgdGhlIHNhbWUiLCByZXMxW3RdLCByZXMyW3RdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5jbG9uZSgpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgTWFjIG9iamVjdCBvciB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFjQ2xvbmUoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgTWFjIFtdIG1hY3MgPSBjcmVhdGVNYWNzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIk1hYyBvYmplY3RzIHdlcmUgbm90IGNyZWF0ZWQiLCBtYWNzKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYWNzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIE1hYyBtYWMxID0gKE1hYykgbWFjc1tpXS5jbG9uZSgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhtYWMxLmdldEFsZ29yaXRobSgpLCBtYWNzW2ldLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMobWFjMS5nZXRQcm92aWRlcigpLCBtYWNzW2ldLmdldFByb3ZpZGVyKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKG1hY3NbaV0uZXF1YWxzKG1hYzEpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBUZXN0IGZvcgorICAgICAqIDxjb2RlPmluaXQoS2V5IGtleSwgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMpPC9jb2RlPgorICAgICAqIDxjb2RlPmluaXQoS2V5IGtleSk8L2NvZGU+CisgICAgICogbWV0aG9kcworICAgICAqIEFzc2VydGlvbjogdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24gYW5kIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiB3aGVuIHBhcmFtZXRlcnMgYXJlIG5vdCBhcHByb3ByaWF0ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbml0KCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0ZWRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIE1hYyBbXSBtYWNzID0gY3JlYXRlTWFjcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJNYWMgb2JqZWN0cyB3ZXJlIG5vdCBjcmVhdGVkIiwgbWFjcyk7CisgICAgICAgIGJ5dGUgW10gYiA9IHsoYnl0ZSkxLCAoYnl0ZSkyLCAoYnl0ZSkzLCAoYnl0ZSk0LCAoYnl0ZSk1fTsKKyAgICAgICAgU2VjcmV0S2V5U3BlYyBza3MgPSBuZXcgU2VjcmV0S2V5U3BlYyhiLCAiU0hBMSIpOworICAgICAgICBESEdlblBhcmFtZXRlclNwZWMgYWxnUFMgPSBuZXcgREhHZW5QYXJhbWV0ZXJTcGVjKDEsIDIpOworICAgICAgICBQU1NQYXJhbWV0ZXJTcGVjIGFsZ1BTUyA9IG5ldyBQU1NQYXJhbWV0ZXJTcGVjKDIwKTsKKyAgICAgICAgU2VjcmV0S2V5U3BlYyBza3MxID0gbmV3IFNlY3JldEtleVNwZWMoYiwgIlJTQSIpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFjcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbWFjc1tpXS5pbml0KHNrcyk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG1hY3NbaV0uaW5pdChza3MxLCBhbGdQU1MpOworICAgICAgICAgICAgICAgIGZhaWwoImluaXQoLi4pIGFjY2VwdHMgaW5jb3JyZWN0IEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1ldGVyIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbWFjc1tpXS5pbml0KHNrcywgYWxnUFMpOworICAgICAgICAgICAgICAgIGZhaWwoImluaXQoLi4pIGFjY2VwdHMgaW5jb3JyZWN0IEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1ldGVyIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBtYWNzW2ldLmluaXQobnVsbCwgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiSW52YWxpZEtleUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbWFjc1tpXS5pbml0KG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRLZXlFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorLy8gICAgICAgICAgICBtYWNzW2ldLmluaXQoc2tzLCBudWxsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnVwZGF0ZShCeXRlQnVmZmVyIGlucHV0KTwvY29kZT4KKyAgICAgKiA8Y29kZT51cGRhdGUoYnl0ZVtdIGlucHV0LCBpbnQgb2Zmc2V0LCBpbnQgbGVuKTwvY29kZT4KKyAgICAgKiBtZXRob2RzCisgICAgICogQXNzZXJ0aW9uOiBwcm9jZXNzZXMgTWFjOyBpZiBpbnB1dCBpcyBudWxsIHRoZW4gZG8gbm90aGluZworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVcGRhdGVCeXRlQnVmZmVyMDEoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSWxsZWdhbFN0YXRlRXhjZXB0aW9uLCBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgTWFjIFtdIG1hY3MgPSBjcmVhdGVNYWNzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIk1hYyBvYmplY3RzIHdlcmUgbm90IGNyZWF0ZWQiLCBtYWNzKTsKKyAgICAgICAgYnl0ZSBbXSBiYiA9IHsoYnl0ZSkxLCAoYnl0ZSkyLCAoYnl0ZSkzLCAoYnl0ZSk0LCAoYnl0ZSk1fTsKKyAgICAgICAgU2VjcmV0S2V5U3BlYyBza3MgPSBuZXcgU2VjcmV0S2V5U3BlYyhiYiwgIlNIQTEiKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBieXRlTnVsbCA9IG51bGw7CisgICAgICAgIEJ5dGVCdWZmZXIgYnl0ZUJ1ZmYgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDApOworICAgICAgICBieXRlIFtdIGJiMTsKKyAgICAgICAgYnl0ZSBbXSBiYjI7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFjcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbWFjc1tpXS5pbml0KHNrcyk7CisgICAgICAgICAgICBiYjEgPSBtYWNzW2ldLmRvRmluYWwoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbWFjc1tpXS51cGRhdGUoYnl0ZU51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biBiZWNhdXNlIGJ1ZmZlciBpcyBudWxsIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgbWFjc1tpXS51cGRhdGUoYnl0ZUJ1ZmYpOworICAgICAgICAgICAgYmIyID0gbWFjc1tpXS5kb0ZpbmFsKCk7CisgICAgICAgICAgICBmb3IgKGludCB0ID0gMDsgdCA8IGJiMS5sZW5ndGg7IHQrKykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRvRmluYWwgcmVzdWx0IiwgYmIxW3RdLCBiYjJbdF0pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbWFjc1tpXS5pbml0KHNrcyk7CisgICAgICAgICAgICBiYjEgPSBtYWNzW2ldLmRvRmluYWwoKTsKKyAgICAgICAgICAgIG1hY3NbaV0udXBkYXRlKG51bGwsIDAsIDApOworICAgICAgICAgICAgYmIyID0gbWFjc1tpXS5kb0ZpbmFsKCk7CisgICAgICAgICAgICBmb3IgKGludCB0ID0gMDsgdCA8IGJiMS5sZW5ndGg7IHQrKykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRvRmluYWwgcmVzdWx0IiwgYmIxW3RdLCBiYjJbdF0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnVwZGF0ZShCeXRlQnVmZmVyIGlucHV0KTwvY29kZT4KKyAgICAgKiA8Y29kZT51cGRhdGUoYnl0ZVtdIGlucHV0LCBpbnQgb2Zmc2V0LCBpbnQgbGVuKTwvY29kZT4KKyAgICAgKiBtZXRob2RzCisgICAgICogQXNzZXJ0aW9uOiBwcm9jZXNzZXMgTWFjCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVwZGF0ZUJ5dGVCdWZmZXIwMigpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbGxlZ2FsU3RhdGVFeGNlcHRpb24sIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydGVkTXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBNYWMgW10gbWFjcyA9IGNyZWF0ZU1hY3MoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTWFjIG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIG1hY3MpOworICAgICAgICBieXRlIFtdIGJiID0geyhieXRlKTEsIChieXRlKTIsIChieXRlKTMsIChieXRlKTQsIChieXRlKTV9OworICAgICAgICBTZWNyZXRLZXlTcGVjIHNrcyA9IG5ldyBTZWNyZXRLZXlTcGVjKGJiLCAiU0hBMSIpOworICAgICAgICBieXRlIFtdIGJidWYgPSB7KGJ5dGUpNSwgKGJ5dGUpNCwgKGJ5dGUpMywgKGJ5dGUpMiwgKGJ5dGUpMX07CisgICAgICAgIEJ5dGVCdWZmZXIgYnl0ZUJ1ZjsKKyAgICAgICAgYnl0ZSBbXSBiYjE7CisgICAgICAgIGJ5dGUgW10gYmIyOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1hY3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGJ5dGVCdWYgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDUpOworICAgICAgICAgICAgYnl0ZUJ1Zi5wdXQoYmJ1Zik7CisgICAgICAgICAgICBieXRlQnVmLnBvc2l0aW9uKDIpOworICAgICAgICAgICAgbWFjc1tpXS5pbml0KHNrcyk7CisgICAgICAgICAgICBtYWNzW2ldLnVwZGF0ZShieXRlQnVmKTsKKyAgICAgICAgICAgIGJiMSA9IG1hY3NbaV0uZG9GaW5hbCgpOworCisgICAgICAgICAgICBtYWNzW2ldLmluaXQoc2tzKTsKKyAgICAgICAgICAgIG1hY3NbaV0udXBkYXRlKGJidWYsIDIsIDMpOworICAgICAgICAgICAgYmIyID0gbWFjc1tpXS5kb0ZpbmFsKCk7CisgICAgICAgICAgICBmb3IgKGludCB0ID0gMDsgdCA8IGJiMS5sZW5ndGg7IHQrKykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRvRmluYWwgcmVzdWx0IiwgYmIxW3RdLCBiYjJbdF0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmNsb25lKCk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogY2xvbmUgaWYgcHJvdmlkZXIgaXMgY2xvCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENsb25lKCkgIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydGVkTXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBNYWMgW10gbWFjcyA9IGNyZWF0ZU1hY3MoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTWFjIG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIG1hY3MpOworICAgICAgICBNYWMgcmVzOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1hY3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmVzID0gKE1hYyltYWNzW2ldLmNsb25lKCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiT2JqZWN0IHNob3VsZCBub3QgYmUgZXF1YWxzIiwgIW1hY3NbaV0uZXF1YWxzKHJlcykpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGNsYXNzIiwgbWFjc1tpXS5nZXRDbGFzcygpLCByZXMuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0TWFjTGVuZ3RoKCk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJuIE1hYyBsZW5ndGgKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TWFjTGVuZ3RoKCkgeworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0ZWRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIE1hYyBbXSBtYWNzID0gY3JlYXRlTWFjcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJNYWMgb2JqZWN0cyB3ZXJlIG5vdCBjcmVhdGVkIiwgbWFjcyk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFjcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTGVuZ3RoIHNob3VsZCBiZSBwb3NpdGl2ZSIsIChtYWNzW2ldLmdldE1hY0xlbmd0aCgpID49IDApKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnJlc2V0KCk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJuIE1hYyBsZW5ndGgKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVzZXQoKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgTWFjIFtdIG1hY3MgPSBjcmVhdGVNYWNzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIk1hYyBvYmplY3RzIHdlcmUgbm90IGNyZWF0ZWQiLCBtYWNzKTsKKyAgICAgICAgYnl0ZSBbXSBiYiA9IHsoYnl0ZSkxLCAoYnl0ZSkyLCAoYnl0ZSkzLCAoYnl0ZSk0LCAoYnl0ZSk1fTsKKyAgICAgICAgU2VjcmV0S2V5U3BlYyBza3MgPSBuZXcgU2VjcmV0S2V5U3BlYyhiYiwgIlNIQTEiKTsKKyAgICAgICAgYnl0ZSBbXSBiYnVmID0geyhieXRlKTUsIChieXRlKTQsIChieXRlKTMsIChieXRlKTIsIChieXRlKTF9OworICAgICAgICBieXRlIFtdIGJiMTsKKyAgICAgICAgYnl0ZSBbXSBiYjI7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFjcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbWFjc1tpXS5pbml0KHNrcyk7CisgICAgICAgICAgICBiYjEgPSBtYWNzW2ldLmRvRmluYWwoKTsKKyAgICAgICAgICAgIG1hY3NbaV0ucmVzZXQoKTsKKyAgICAgICAgICAgIGJiMiA9IG1hY3NbaV0uZG9GaW5hbCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgcmVzdWx0IixiYjEubGVuZ3RoLCBiYjIubGVuZ3RoKTsKKyAgICAgICAgICAgIGZvciAoaW50IHQgPSAwOyB0IDwgYmIxLmxlbmd0aDsgdCsrKSB7CisgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBkb0ZpbmFsIHJlc3VsdCIsIGJiMVt0XSwgYmIyW3RdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG1hY3NbaV0ucmVzZXQoKTsKKyAgICAgICAgICAgIG1hY3NbaV0udXBkYXRlKGJidWYpOworICAgICAgICAgICAgYmIxID0gbWFjc1tpXS5kb0ZpbmFsKCk7CisgICAgICAgICAgICBtYWNzW2ldLnJlc2V0KCk7CisgICAgICAgICAgICBtYWNzW2ldLnVwZGF0ZShiYnVmLCAwLCBiYnVmLmxlbmd0aCk7CisgICAgICAgICAgICBiYjIgPSBtYWNzW2ldLmRvRmluYWwoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IHJlc3VsdCIsYmIxLmxlbmd0aCwgYmIyLmxlbmd0aCk7CisgICAgICAgICAgICBmb3IgKGludCB0ID0gMDsgdCA8IGJiMS5sZW5ndGg7IHQrKykgeworICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgZG9GaW5hbCByZXN1bHQiLCBiYjFbdF0sIGJiMlt0XSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+TWFjPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBNYWMgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE1hY0NvbnN0cnVjdG9yKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24sIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0ZWRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIE1hY1NwaSBzcGkgPSBuZXcgTXlNYWNTcGkoKTsKKyAgICAgICAgTWFjIG1hYyA9IG5ldyBteU1hYyhzcGksIGRlZmF1bHRQcm92aWRlciwgZGVmYXVsdEFsZ29yaXRobSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIG1hYy5nZXRBbGdvcml0aG0oKSwKKyAgICAgICAgICAgICAgICBkZWZhdWx0QWxnb3JpdGhtKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBtYWMuZ2V0UHJvdmlkZXIoKSwgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1hYy5pbml0KG51bGwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gYmVjYXVzZSBpbml0KC4uKSB1c2VzIGluY29ycmVjdCBwYXJhbWV0ZXJzIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbnZhbGlkIG1hYyBsZW5ndGgiLCBtYWMuZ2V0TWFjTGVuZ3RoKCksIDApOworCisgICAgICAgIG1hYyA9IG5ldyBteU1hYyhudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiQWxnb3JpdGhtIG11c3QgYmUgbnVsbCIsIG1hYy5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgIGFzc2VydE51bGwoIlByb3ZpZGVyIG11c3QgYmUgbnVsbCIsIG1hYy5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1hYy5pbml0KG51bGwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gYmVjYXVzZSBpbml0KC4uKSB1c2VzIGluY29ycmVjdCBwYXJhbWV0ZXJzIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1hYy5nZXRNYWNMZW5ndGgoKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0QWxnb3JpdGhtKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIE1hYyBtYWM7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG1hYyA9IE1hYy5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBtYWMuZ2V0QWxnb3JpdGhtKCksIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIG1hYyA9IG5ldyBNb2NrX01hYyhudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChtYWMuZ2V0QWxnb3JpdGhtKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UHJvdmlkZXIoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgTWFjIG1hYzsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbWFjID0gTWFjLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwobWFjLmdldFByb3ZpZGVyKCkpOworICAgICAgICB9CisKKyAgICAgICAgbWFjID0gbmV3IE1vY2tfTWFjKG51bGwsIG51bGwsIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKG1hYy5nZXRQcm92aWRlcigpKTsKKyAgICB9CisKKyAgICBjbGFzcyBNb2NrX01hYyBleHRlbmRzIE1hYyB7CisgICAgICAgIHByb3RlY3RlZCBNb2NrX01hYyhNYWNTcGkgYXJnMCwgUHJvdmlkZXIgYXJnMSwgU3RyaW5nIGFyZzIpIHsKKyAgICAgICAgICAgIHN1cGVyKGFyZzAsIGFyZzEsIGFyZzIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBUZXN0IHN1aXRlKCkgeworICAgICAgICByZXR1cm4gbmV3IFRlc3RTdWl0ZShNYWNUZXN0LmNsYXNzKTsKKyAgICB9Cit9CisvKioKKyAqIEFkZGl0aW9uYWwgY2xhc3MgZm9yIE1hYyBjb25zdHJ1Y3RvciB2ZXJpZmljYXRpb24KKyAqLworY2xhc3MgbXlNYWMgZXh0ZW5kcyBNYWMgeworCisgICAgcHVibGljIG15TWFjKE1hY1NwaSBtYWNTcGksIFByb3ZpZGVyIHByb3ZpZGVyLAorICAgICAgICAgICAgU3RyaW5nIGFsZ29yaXRobSkgeworICAgICAgICBzdXBlcihtYWNTcGksIHByb3ZpZGVyLCBhbGdvcml0aG0pOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9Ob1N1Y2hQYWRkaW5nRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL05vU3VjaFBhZGRpbmdFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTQ4Yjk4NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9Ob1N1Y2hQYWRkaW5nRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsODAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0bzsKKworaW1wb3J0IGphdmF4LmNyeXB0by5Ob1N1Y2hQYWRkaW5nRXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPk5vU3VjaFBhZGRpbmdFeGNlcHRpb248L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQKKyAqIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgTm9TdWNoUGFkZGluZ0V4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBzdGF0aWMgU3RyaW5nW10gbXNncyA9IHsKKyAgICAgICAgICAgICIiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSIgfTsKKworICAgIHN0YXRpYyBUaHJvd2FibGUgdENhdXNlID0gbmV3IFRocm93YWJsZSgiVGhyb3dhYmxlIGZvciBleGNlcHRpb24iKTsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPk5vU3VjaFBhZGRpbmdFeGNlcHRpb24oKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE5vU3VjaFBhZGRpbmdFeGNlcHRpb24wMSgpIHsKKyAgICAgICAgTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbiB0RSA9IG5ldyBOb1N1Y2hQYWRkaW5nRXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPk5vU3VjaFBhZGRpbmdFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4KKyAgICAgKiBQYXJhbWV0ZXIgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9TdWNoUGFkZGluZ0V4Y2VwdGlvbjAyKCkgeworICAgICAgICBOb1N1Y2hQYWRkaW5nRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IE5vU3VjaFBhZGRpbmdFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5Ob1N1Y2hQYWRkaW5nRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIE5vU3VjaFBhZGRpbmdFeGNlcHRpb24gd2hlbiA8Y29kZT5tc2c8L2NvZGU+IGlzCisgICAgICogbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3ROb1N1Y2hQYWRkaW5nRXhjZXB0aW9uMDMoKSB7CisgICAgICAgIFN0cmluZyBtc2cgPSBudWxsOworICAgICAgICBOb1N1Y2hQYWRkaW5nRXhjZXB0aW9uIHRFID0gbmV3IE5vU3VjaFBhZGRpbmdFeGNlcHRpb24obXNnKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL051bGxDaXBoZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vTnVsbENpcGhlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ODNmYTA3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL051bGxDaXBoZXJUZXN0LmphdmEKQEAgLTAsMCArMSwyNjggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEJvcmlzIFYuIEt1em5ldHNvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXI7CitpbXBvcnQgamF2YXguY3J5cHRvLkNpcGhlclNwaTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uTnVsbENpcGhlcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5TZWNyZXRLZXlTcGVjOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqCisgKiBUZXN0cyBmb3IgTnVsbENpcGhlcgorICovCitwdWJsaWMgY2xhc3MgTnVsbENpcGhlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIENpcGhlciBjOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgYyA9IG5ldyBOdWxsQ2lwaGVyKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgYy5nZXRBbGdvcml0aG0oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0QmxvY2tTaXplKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBCbG9ja1NpemUiLCAxLCBjLmdldEJsb2NrU2l6ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0T3V0cHV0U2l6ZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgT3V0cHV0U2l6ZSIsIDExMSwgYy5nZXRPdXRwdXRTaXplKDExMSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJVigpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IElWIiwgQXJyYXlzLmVxdWFscyhjLmdldElWKCksIG5ldyBieXRlWzhdKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFBhcmFtZXRlcnMoKSB7CisgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCBQYXJhbWV0ZXJzIiwgYy5nZXRQYXJhbWV0ZXJzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRFeGVtcHRpb25NZWNoYW5pc20oKSB7CisgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCBFeGVtcHRpb25NZWNoYW5pc20iLCBjLmdldEV4ZW1wdGlvbk1lY2hhbmlzbSgpKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIHZvaWQgaW5pdChpbnQsIEtleSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5pdGludEtleSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwgbmV3IFNlY3JldEtleVNwZWMobmV3IGJ5dGVbMV0sICJhbGdvcml0aG0iKSk7CisKKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIHZvaWQgaW5pdChpbnQsIEtleSwgU2VjdXJlUmFuZG9tKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbml0aW50S2V5U2VjdXJlUmFuZG9tKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGMuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBuZXcgU2VjcmV0S2V5U3BlYyhuZXcgYnl0ZVsxXSwKKyAgICAgICAgICAgICAgICAiYWxnb3JpdGhtIiksIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciB2b2lkIGluaXQoaW50LCBLZXksIEFsZ29yaXRobVBhcmFtZXRlclNwZWMpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEluaXRpbnRLZXlBbGdvcml0aG1QYXJhbWV0ZXJTcGVjKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNsYXNzIG15QWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBpbXBsZW1lbnRzIGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHt9CisgICAgICAgIGMuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBuZXcgU2VjcmV0S2V5U3BlYyhuZXcgYnl0ZVsxXSwKKyAgICAgICAgICAgICAgICAiYWxnb3JpdGhtIiksIG5ldyBteUFsZ29yaXRobVBhcmFtZXRlclNwZWMoKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciBieXRlW10gdXBkYXRlKGJ5dGVbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXBkYXRlYnl0ZUFycmF5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGUgW10gYiA9IHsxLCAyLCAzLCA0LCA1fTsKKyAgICAgICAgYnl0ZSBbXSByID0gYy51cGRhdGUoYik7CisgICAgICAgIGFzc2VydEVxdWFscygiZGlmZmVyZW50IGxlbmd0aCIsIGIubGVuZ3RoLCByLmxlbmd0aCk7CisgICAgICAgIGFzc2VydFRydWUoImRpZmZlcmVudCBjb250ZW50IiwgQXJyYXlzLmVxdWFscyhiLCByKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciBieXRlW10gdXBkYXRlKGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVwZGF0ZWJ5dGVBcnJheWludGludCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlIFtdIGIgPSB7MSwgMiwgMywgNCwgNX07CisgICAgICAgIGJ5dGUgW10gciA9IGMudXBkYXRlKGIsIDAsIDUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRpZmZlcmVudCBsZW5ndGgiLCBiLmxlbmd0aCwgci5sZW5ndGgpOworICAgICAgICBhc3NlcnRUcnVlKCJkaWZmZXJlbnQgY29udGVudCIsIEFycmF5cy5lcXVhbHMoYiwgcikpOworCisgICAgICAgIHIgPSBjLnVwZGF0ZShiLCAxLCAzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkaWZmZXJlbnQgbGVuZ3RoIiwgMywgci5sZW5ndGgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJkaWZmZXJlbnQgY29udGVudCIsIGJbaSArIDFdLCByW2ldKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3IgaW50IHVwZGF0ZShieXRlW10sIGludCwgaW50LCBieXRlW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVwZGF0ZWJ5dGVBcnJheWludGludGJ5dGVBcnJheSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlIFtdIGIgPSB7MSwgMiwgMywgNCwgNX07CisgICAgICAgIGJ5dGUgW10gciA9IG5ldyBieXRlWzVdOworICAgICAgICBjLnVwZGF0ZShiLCAwLCA1LCByKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZGlmZmVyZW50IGNvbnRlbnQiLCBBcnJheXMuZXF1YWxzKGIsIHIpKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIGludCB1cGRhdGUoYnl0ZVtdLCBpbnQsIGludCwgYnl0ZVtdLCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVwZGF0ZWJ5dGVBcnJheWludGludGJ5dGVBcnJheWludCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlIFtdIGIgPSB7MSwgMiwgMywgNCwgNX07CisgICAgICAgIGJ5dGUgW10gciA9IG5ldyBieXRlWzVdOworICAgICAgICBjLnVwZGF0ZShiLCAwLCA1LCByLCAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZGlmZmVyZW50IGNvbnRlbnQiLCBBcnJheXMuZXF1YWxzKGIsIHIpKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIGJ5dGVbXSBkb0ZpbmFsKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RG9GaW5hbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnROdWxsKCJkb0ZpbmFsIGZhaWxlZCIsIGMuZG9GaW5hbCgpKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIGludCBkb0ZpbmFsKGJ5dGVbXSwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REb0ZpbmFsYnl0ZUFycmF5aW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGUgW10gciA9IG5ldyBieXRlWzVdOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvRmluYWwgZmFpbGVkIiwgMCwgYy5kb0ZpbmFsKHIsIDApKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIGJ5dGVbXSBkb0ZpbmFsKGJ5dGVbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RG9GaW5hbGJ5dGVBcnJheSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlIFtdIGIgPSB7MSwgMiwgMywgNCwgNX07CisgICAgICAgIGJ5dGUgW10gciA9IG51bGw7CisgICAgICAgIHIgPSBjLmRvRmluYWwoYik7CisgICAgICAgIGFzc2VydEVxdWFscygiZGlmZmVyZW50IGxlbmd0aCIsIGIubGVuZ3RoLCByLmxlbmd0aCk7CisgICAgICAgIGFzc2VydFRydWUoImRpZmZlcmVudCBjb250ZW50IiwgQXJyYXlzLmVxdWFscyhiLCByKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciBieXRlW10gZG9GaW5hbChieXRlW10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REb0ZpbmFsYnl0ZUFycmF5aW50aW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGUgW10gYiA9IHsxLCAyLCAzLCA0LCA1fTsKKyAgICAgICAgYnl0ZSBbXSByID0gbnVsbDsKKyAgICAgICAgciA9IGMuZG9GaW5hbChiLCAwLCA1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkaWZmZXJlbnQgbGVuZ3RoIiwgYi5sZW5ndGgsIHIubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZGlmZmVyZW50IGNvbnRlbnQiLCBBcnJheXMuZXF1YWxzKGIsIHIpKTsKKworICAgICAgICByID0gYy5kb0ZpbmFsKGIsIDEsIDMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRpZmZlcmVudCBsZW5ndGgiLCAzLCByLmxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImRpZmZlcmVudCBjb250ZW50IiwgYltpICsgMV0sIHJbaV0pOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciBieXRlW10gdXBkYXRlKGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVwZGF0ZWJ5dGVBcnJheWludGludDIoKSB7CisgICAgICAgIC8vUmVncmVzc2lvbiBmb3IgSEFSTU9OWS03NTgKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBOdWxsQ2lwaGVyKCkudXBkYXRlKG5ldyBieXRlWzFdLCAxLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3IgaW50IGRvRmluYWwoYnl0ZVtdLCBpbnQsIGludCwgYnl0ZVtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REb0ZpbmFsYnl0ZUFycmF5aW50aW50Ynl0ZUFycmF5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGUgW10gYiA9IHsxLCAyLCAzLCA0LCA1fTsKKyAgICAgICAgYnl0ZSBbXSByID0gbmV3IGJ5dGVbNV07CisgICAgICAgIGMuZG9GaW5hbChiLCAwLCA1LCByKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZGlmZmVyZW50IGNvbnRlbnQiLCBBcnJheXMuZXF1YWxzKGIsIHIpKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIGludCBkb0ZpbmFsKGJ5dGVbXSwgaW50LCBpbnQsIGJ5dGVbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RG9GaW5hbGJ5dGVBcnJheWludGludGJ5dGVBcnJheTIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy9SZWdyZXNzaW9uIGZvciBIQVJNT05ZLTc1OAorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IE51bGxDaXBoZXIoKS51cGRhdGUobmV3IGJ5dGVbMV0sIDEsIEludGVnZXIuTUFYX1ZBTFVFLAorICAgICAgICAgICAgICAgICAgICBuZXcgYnl0ZVsxXSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3IgaW50IGRvRmluYWwoYnl0ZVtdLCBpbnQsIGludCwgYnl0ZVtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REb0ZpbmFsYnl0ZUFycmF5aW50aW50Ynl0ZUFycmF5MygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvL1JlZ3Jlc3Npb24gZm9yIEhBUk1PTlktNzU4CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgTnVsbENpcGhlcigpLnVwZGF0ZShuZXcgYnl0ZVsxXSwgMCwgMSwgbmV3IGJ5dGVbMF0pOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3IgaW50IGRvRmluYWwoYnl0ZVtdLCBpbnQsIGludCwgYnl0ZVtdLCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdERvRmluYWxieXRlQXJyYXlpbnRpbnRieXRlQXJyYXlpbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZSBbXSBiID0gezEsIDIsIDMsIDQsIDV9OworICAgICAgICBieXRlIFtdIHIgPSBuZXcgYnl0ZVs1XTsKKyAgICAgICAgYy5kb0ZpbmFsKGIsIDAsIDUsIHIsIDApOworICAgICAgICBhc3NlcnRUcnVlKCJkaWZmZXJlbnQgY29udGVudCIsIEFycmF5cy5lcXVhbHMoYiwgcikpOworICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3IgaW50IGRvRmluYWwoYnl0ZVtdLCBpbnQsIGludCwgYnl0ZVtdLCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdERvRmluYWxieXRlQXJyYXlpbnRpbnRieXRlQXJyYXlpbnQyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vUmVncmVzc2lvbiBmb3IgSEFSTU9OWS03NTgKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBOdWxsQ2lwaGVyKCkudXBkYXRlKG5ldyBieXRlWzFdLCAxLCBJbnRlZ2VyLk1BWF9WQUxVRSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IGJ5dGVbMV0sIDApOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIGludCBkb0ZpbmFsKGJ5dGVbXSwgaW50LCBpbnQsIGJ5dGVbXSwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REb0ZpbmFsYnl0ZUFycmF5aW50aW50Ynl0ZUFycmF5aW50MygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvL1JlZ3Jlc3Npb24gZm9yIEhBUk1PTlktNzU4CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgTnVsbENpcGhlcigpLnVwZGF0ZShuZXcgYnl0ZVsxXSwgMCwgMSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IGJ5dGVbMF0sIDApOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9TZWFsZWRPYmplY3RUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vU2VhbGVkT2JqZWN0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIzYjI5MzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vU2VhbGVkT2JqZWN0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjk0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzCisgKiB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiBUaGUgQVNGCisgKiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVAorICogV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlCisgKiBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgorICogdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisgKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXI7CitpbXBvcnQgamF2YXguY3J5cHRvLklsbGVnYWxCbG9ja1NpemVFeGNlcHRpb247CitpbXBvcnQgamF2YXguY3J5cHRvLktleUdlbmVyYXRvcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uTnVsbENpcGhlcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2VhbGVkT2JqZWN0OworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLkl2UGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5TZWNyZXRLZXlTcGVjOworCisvKioKKyAqLworcHVibGljIGNsYXNzIFNlYWxlZE9iamVjdFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgY2xhc3MgTW9ja19TZWFsZWRPYmplY3QgZXh0ZW5kcyBTZWFsZWRPYmplY3QgeworICAgICAgICBwdWJsaWMgTW9ja19TZWFsZWRPYmplY3QoU2VyaWFsaXphYmxlIG9iamVjdCwgQ2lwaGVyIGMpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyKG9iamVjdCwgYyk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldF9lbmNvZGVkUGFyYW1zKCkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVuY29kZWRQYXJhbXM7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gcykgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIGlmIHRoZQorICAgICAqIHNlcmlhbGl6YXRpb24vZGVzZXJpYWxpemF0aW9uIHdvcmtzIGNvcnJlY3RseTogb2JqZWN0IGlzIHNlcmlhbGl6ZWQsCisgICAgICogZGVzZXJpYWxpemVkLCB0aGUgY29udGVudCBvZCBkZXNlcmlhbGl6ZWQgb2JqZWN0IGVxdWFscyB0byB0aGUgY29udGVudCBvZgorICAgICAqIGluaXRpYWwgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RSZWFkT2JqZWN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzZWNyZXQgPSAic2VjcmV0IHN0cmluZyI7CisgICAgICAgIFNlYWxlZE9iamVjdCBzbyA9IG5ldyBTZWFsZWRPYmplY3Qoc2VjcmV0LCBuZXcgTnVsbENpcGhlcigpKTsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtIG9vcyA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0oYm9zKTsKKyAgICAgICAgb29zLndyaXRlT2JqZWN0KHNvKTsKKworICAgICAgICBPYmplY3RJbnB1dFN0cmVhbSBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgIGJvcy50b0J5dGVBcnJheSgpKSk7CisKKyAgICAgICAgU2VhbGVkT2JqZWN0IHNvX2RlcyA9IChTZWFsZWRPYmplY3QpIG9pcy5yZWFkT2JqZWN0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhlIHNlY3JldCBjb250ZW50IG9mIGRlc2VyaWFsaXplZCBvYmplY3QgIgorICAgICAgICAgICAgICAgICsgInNob3VsZCBiZSBlcXVhbCB0byB0aGUgc2VjcmV0IGNvbnRlbnQgb2YgaW5pdGlhbCBvYmplY3QiLAorICAgICAgICAgICAgICAgIHNlY3JldCwgc29fZGVzLmdldE9iamVjdChuZXcgTnVsbENpcGhlcigpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhlIHZhbHVlIHJldHVybmVkIGJ5IGdldEFsZ29yaXRobSgpIG1ldGhvZCBvZiAiCisgICAgICAgICAgICAgICAgKyAiZGVzZXJpYWxpemVkIG9iamVjdCBzaG91bGQgYmUgZXF1YWwgdG8gdGhlIHZhbHVlIHJldHVybmVkICIKKyAgICAgICAgICAgICAgICArICJieSBnZXRBbGdvcml0aG0oKSBtZXRob2Qgb2YgaW5pdGlhbCBvYmplY3QiLCBzbworICAgICAgICAgICAgICAgIC5nZXRBbGdvcml0aG0oKSwgc29fZGVzLmdldEFsZ29yaXRobSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFsZWRPYmplY3QoU2VyaWFsaXphYmxlIG9iamVjdCwgQ2lwaGVyIGMpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyBpZiB0aGUKKyAgICAgKiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcyB0aHJvd24gaW4gdGhlIGNhc2Ugb2YgbnVsbCBjaXBoZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNlYWxlZE9iamVjdDEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHNlY3JldCA9ICJzZWNyZXQgc3RyaW5nIjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTZWFsZWRPYmplY3Qoc2VjcmV0LCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gaW4gdGhlIGNhc2UgIgorICAgICAgICAgICAgICAgICAgICArICJvZiBudWxsIGNpcGhlci4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgS2V5R2VuZXJhdG9yIGtnID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKCJERVMiKTsKKyAgICAgICAgS2V5IGtleSA9IGtnLmdlbmVyYXRlS2V5KCk7CisKKyAgICAgICAgSXZQYXJhbWV0ZXJTcGVjIGlwcyA9IG5ldyBJdlBhcmFtZXRlclNwZWMobmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgMSwgMiwgMywgNCwgNSwgNiwgNywgOH0pOworCisgICAgICAgIENpcGhlciBjaXBoZXIgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvUEtDUzVQYWRkaW5nIik7CisgICAgICAgIGNpcGhlci5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGtleSwgaXBzKTsKKworICAgICAgICBTZWFsZWRPYmplY3Qgc28gPSBuZXcgU2VhbGVkT2JqZWN0KHNlY3JldCwgY2lwaGVyKTsKKworICAgICAgICBjaXBoZXIgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoIkRFUy9DQkMvTm9QYWRkaW5nIik7CisgICAgICAgIGNpcGhlci5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGtleSwgaXBzKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFNlYWxlZE9iamVjdChzZWNyZXQsIGNpcGhlcik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VhbGVkT2JqZWN0KFNlYWxlZE9iamVjdCBzbykgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIGlmIHRoZQorICAgICAqIE51bGxQb2ludGVyRXhjZXB0aW9uIGlzIHRocm93biBpbiB0aGUgY2FzZSBvZiBudWxsIFNlYWxlZE9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VhbGVkT2JqZWN0MigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFNlYWxlZE9iamVjdChudWxsKSB7fTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gaW4gdGhlIGNhc2UgIgorICAgICAgICAgICAgICAgICAgICArICJvZiBudWxsIFNlYWxlZE9iamVjdC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIHNlY3JldCA9ICJzZWNyZXQgc3RyaW5nIjsKKyAgICAgICAgQ2lwaGVyIGNpcGhlciA9IG5ldyBOdWxsQ2lwaGVyKCk7CisgICAgICAgIFNlYWxlZE9iamVjdCBzbzEgPSBuZXcgU2VhbGVkT2JqZWN0KHNlY3JldCwgY2lwaGVyKTsKKyAgICAgICAgU2VhbGVkT2JqZWN0IHNvMiA9IG5ldyBTZWFsZWRPYmplY3Qoc28xKSB7fTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSBzZWNyZXQgY29udGVudCBvZiB0aGUgb2JqZWN0IHNob3VsZCBlcXVhbHMgIgorICAgICAgICAgICAgICAgICsgInRvIHRoZSBzZWNyZXQgY29udGVudCBvZiBpbml0aWFsIG9iamVjdC4iLCBzZWNyZXQsIHNvMgorICAgICAgICAgICAgICAgIC5nZXRPYmplY3QoY2lwaGVyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhlIGFsZ29yaXRobSB3aGljaCB3YXMgdXNlZCB0byBzZWFsIHRoZSBvYmplY3QgIgorICAgICAgICAgICAgICAgICsgInNob3VsZCBiZSB0aGUgc2FtZSBhcyB0aGUgYWxnb3JpdGhtIHVzZWQgdG8gc2VhbCB0aGUgIgorICAgICAgICAgICAgICAgICsgImluaXRpYWwgb2JqZWN0Iiwgc28xLmdldEFsZ29yaXRobSgpLCBzbzIuZ2V0QWxnb3JpdGhtKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGdldEFsZ29yaXRobSgpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyBpZiB0aGUgcmV0dXJuZWQgdmFsdWUgZXF1YWxzIHRvIHRoZQorICAgICAqIGNvcnJlc3BvbmRpbmcgdmFsdWUgb2YgQ2lwaGVyIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0QWxnb3JpdGhtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzZWNyZXQgPSAic2VjcmV0IHN0cmluZyI7CisgICAgICAgIFN0cmluZyBhbGdvcml0aG0gPSAiREVTIjsKKyAgICAgICAgS2V5R2VuZXJhdG9yIGtnID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgIEtleSBrZXkgPSBrZy5nZW5lcmF0ZUtleSgpOworCisgICAgICAgIENpcGhlciBjaXBoZXIgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtKTsKKyAgICAgICAgY2lwaGVyLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwga2V5KTsKKyAgICAgICAgU2VhbGVkT2JqZWN0IHNvID0gbmV3IFNlYWxlZE9iamVjdChzZWNyZXQsIGNpcGhlcik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgYWxnb3JpdGhtIG5hbWUgc2hvdWxkIGJlIHRoZSBzYW1lIGFzIHVzZWQgIgorICAgICAgICAgICAgICAgICsgImluIGNpcGhlci4iLCBhbGdvcml0aG0sIHNvLmdldEFsZ29yaXRobSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRPYmplY3QoS2V5IGtleSkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIGlmIHRoZSBvYmplY3Qgc2VhbGVkIHdpdGgKKyAgICAgKiBlbmNyeXB0aW9uIGFsZ29yaXRobSBhbmQgc3BlY2lmaWVkIHBhcmFtZXRlcnMgY2FuIGJlIHJldHJpZXZlZCBieQorICAgICAqIHNwZWNpZnlpbmcgdGhlIGNyeXB0b2dyYXBoaWMga2V5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRPYmplY3QxKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEtleUdlbmVyYXRvciBrZyA9IEtleUdlbmVyYXRvci5nZXRJbnN0YW5jZSgiREVTIik7CisgICAgICAgIEtleSBrZXkgPSBrZy5nZW5lcmF0ZUtleSgpOworCisgICAgICAgIEl2UGFyYW1ldGVyU3BlYyBpcHMgPSBuZXcgSXZQYXJhbWV0ZXJTcGVjKG5ldyBieXRlW10geworICAgICAgICAgICAgICAgIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDh9KTsKKworICAgICAgICBDaXBoZXIgY2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMvQ0JDL1BLQ1M1UGFkZGluZyIpOworICAgICAgICBjaXBoZXIuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBrZXksIGlwcyk7CisKKyAgICAgICAgU3RyaW5nIHNlY3JldCA9ICJzZWNyZXQgc3RyaW5nIjsKKyAgICAgICAgTW9ja19TZWFsZWRPYmplY3Qgc28gPSBuZXcgTW9ja19TZWFsZWRPYmplY3Qoc2VjcmV0LCBjaXBoZXIpOworCisgICAgICAgIGFzc2VydEVxdWFscygiVGhlIHJldHVybmVkIG9iamVjdCBkb2VzIG5vdCBlcXVhbHMgdG8gdGhlICIKKyAgICAgICAgICAgICAgICArICJvcmlnaW5hbCBvYmplY3QuIiwgc2VjcmV0LCBzby5nZXRPYmplY3Qoa2V5KSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGVuY29kZWRQYXJhbXMgZmllbGQgb2YgU2VhbGVkT2JqZWN0IG9iamVjdCAiCisgICAgICAgICAgICAgICAgKyAic2hvdWxkIGNvbnRhaW4gdGhlIGVuY29kZWQgYWxnb3JpdGhtIHBhcmFtZXRlcnMuIiwgQXJyYXlzCisgICAgICAgICAgICAgICAgLmVxdWFscyhzby5nZXRfZW5jb2RlZFBhcmFtcygpLCBjaXBoZXIuZ2V0UGFyYW1ldGVycygpCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RW5jb2RlZCgpKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzby5nZXRPYmplY3QoKEtleSludWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWRLZXlFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vYWxzbyBvaworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0T2JqZWN0KENpcGhlciBjKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgaWYgdGhlIHByb3BlciBleGNlcHRpb24gaXMKKyAgICAgKiB0aHJvd24gaW4gdGhlIGNhc2Ugb2YgaW5jb3JyZWN0IGlucHV0IHBhcmFtZXRlcnMgYW5kIGlmIHRoZSBvYmplY3Qgc2VhbGVkCisgICAgICogd2l0aCBlbmNyeXB0aW9uIGFsZ29yaXRobSBhbmQgc3BlY2lmaWVkIHBhcmFtZXRlcnMgY2FuIGJlIHJldHJpZXZlZCBieQorICAgICAqIHNwZWNpZnlpbmcgdGhlIGluaXRpYWxpemVkIENpcGhlciBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldE9iamVjdDIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTZWFsZWRPYmplY3QoInNlY3JldCBzdHJpbmciLCBuZXcgTnVsbENpcGhlcigpKQorICAgICAgICAgICAgICAgICAgICAuZ2V0T2JqZWN0KChDaXBoZXIpIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biBpbiB0aGUgY2FzZSBvZiAiCisgICAgICAgICAgICAgICAgICAgICsgIm51bGwgY2lwaGVyLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBLZXlHZW5lcmF0b3Iga2cgPSBLZXlHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRFUyIpOworICAgICAgICBLZXkga2V5ID0ga2cuZ2VuZXJhdGVLZXkoKTsKKworICAgICAgICBJdlBhcmFtZXRlclNwZWMgaXBzID0gbmV3IEl2UGFyYW1ldGVyU3BlYyhuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4fSk7CisKKyAgICAgICAgQ2lwaGVyIGNpcGhlciA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0NCQy9QS0NTNVBhZGRpbmciKTsKKyAgICAgICAgY2lwaGVyLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwga2V5LCBpcHMpOworCisgICAgICAgIFN0cmluZyBzZWNyZXQgPSAic2VjcmV0IHN0cmluZyI7CisgICAgICAgIFNlYWxlZE9iamVjdCBzbyA9IG5ldyBTZWFsZWRPYmplY3Qoc2VjcmV0LCBjaXBoZXIpOworCisgICAgICAgIGNpcGhlci5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGtleSwgaXBzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgcmV0dXJuZWQgb2JqZWN0IGRvZXMgbm90IGVxdWFscyB0byB0aGUgIgorICAgICAgICAgICAgICAgICsgIm9yaWdpbmFsIG9iamVjdC4iLCBzZWNyZXQsIHNvLmdldE9iamVjdChjaXBoZXIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc28uZ2V0T2JqZWN0KChDaXBoZXIpbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRPYmplY3QoS2V5IGtleSwgU3RyaW5nIHByb3ZpZGVyKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgaWYgdGhlIHByb3BlcgorICAgICAqIGV4Y2VwdGlvbiBpcyB0aHJvd24gaW4gdGhlIGNhc2Ugb2YgaW5jb3JyZWN0IGlucHV0IHBhcmFtZXRlcnMgYW5kIGlmIHRoZQorICAgICAqIG9iamVjdCBzZWFsZWQgd2l0aCBlbmNyeXB0aW9uIGFsZ29yaXRobSBjYW4gYmUgcmV0cmlldmVkIGJ5IHNwZWNpZnlpbmcKKyAgICAgKiB0aGUgY3J5cHRvZ3JhcGhpYyBrZXkgYW5kIHByb3ZpZGVyIG5hbWUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldE9iamVjdDMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTZWFsZWRPYmplY3QoInNlY3JldCBzdHJpbmciLCBuZXcgTnVsbENpcGhlcigpKS5nZXRPYmplY3QoCisgICAgICAgICAgICAgICAgICAgIG5ldyBTZWNyZXRLZXlTcGVjKG5ldyBieXRlW10gezAsIDAsIDB9LCAiYWxnb3JpdGhtIiksIG51bGwpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gaW4gdGhlIGNhc2Ugb2YgIgorICAgICAgICAgICAgICAgICAgICArICJudWxsIHByb3ZpZGVyLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTZWFsZWRPYmplY3QoInNlY3JldCBzdHJpbmciLCBuZXcgTnVsbENpcGhlcigpKS5nZXRPYmplY3QoCisgICAgICAgICAgICAgICAgICAgIG5ldyBTZWNyZXRLZXlTcGVjKG5ldyBieXRlW10gezAsIDAsIDB9LCAiYWxnb3JpdGhtIiksICIiKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIGluIHRoZSBjYXNlIG9mICIKKyAgICAgICAgICAgICAgICAgICAgKyAiZW1wdHkgcHJvdmlkZXIuIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBLZXlHZW5lcmF0b3Iga2cgPSBLZXlHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRFUyIpOworICAgICAgICBLZXkga2V5ID0ga2cuZ2VuZXJhdGVLZXkoKTsKKworICAgICAgICBDaXBoZXIgY2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKCJERVMiKTsKKyAgICAgICAgU3RyaW5nIHByb3ZpZGVyID0gY2lwaGVyLmdldFByb3ZpZGVyKCkuZ2V0TmFtZSgpOworICAgICAgICBjaXBoZXIuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBrZXkpOworCisgICAgICAgIFN0cmluZyBzZWNyZXQgPSAic2VjcmV0IHN0cmluZyI7CisgICAgICAgIFNlYWxlZE9iamVjdCBzbyA9IG5ldyBTZWFsZWRPYmplY3Qoc2VjcmV0LCBjaXBoZXIpOworCisgICAgICAgIGNpcGhlci5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGtleSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhlIHJldHVybmVkIG9iamVjdCBkb2VzIG5vdCBlcXVhbHMgdG8gdGhlICIKKyAgICAgICAgICAgICAgICArICJvcmlnaW5hbCBvYmplY3QuIiwgc2VjcmV0LCBzby5nZXRPYmplY3Qoa2V5LCBwcm92aWRlcikpOworCisgICAgICAgIGtnID0gS2V5R2VuZXJhdG9yLmdldEluc3RhbmNlKCJERVNlZGUiKTsKKyAgICAgICAga2V5ID0ga2cuZ2VuZXJhdGVLZXkoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc28uZ2V0T2JqZWN0KGtleSwgcHJvdmlkZXIpOworICAgICAgICAgICAgZmFpbCgiSW52YWxpZEtleUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzby5nZXRPYmplY3Qoa2V5LCAiV3JvbmcgcHJvdmlkZXIgbmFtZSIpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vU2VjcmV0S2V5RmFjdG9yeVNwaVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9TZWNyZXRLZXlGYWN0b3J5U3BpVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlNjhkYzgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vU2VjcmV0S2V5RmFjdG9yeVNwaVRlc3QuamF2YQpAQCAtMCwwICsxLDcyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyAqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG87CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkludmFsaWRLZXlTcGVjRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5LZXlTcGVjOworaW1wb3J0IGphdmF4LmNyeXB0by5TZWNyZXRLZXlGYWN0b3J5U3BpOworaW1wb3J0IGphdmF4LmNyeXB0by5TZWNyZXRLZXk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5zdXBwb3J0Lk15U2VjcmV0S2V5RmFjdG9yeVNwaTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+U2VjcmV0S2V5RmFjdG9yeVNwaTwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICovCitwdWJsaWMgY2xhc3MgU2VjcmV0S2V5RmFjdG9yeVNwaVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgY2xhc3MgTW9ja19TZWNyZXRLZXlGYWN0b3J5U3BpIGV4dGVuZHMgTXlTZWNyZXRLZXlGYWN0b3J5U3BpIHsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIFNlY3JldEtleSBlbmdpbmVHZW5lcmF0ZVNlY3JldChLZXlTcGVjIGtleVNwZWMpIHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZW5naW5lR2VuZXJhdGVTZWNyZXQoa2V5U3BlYyk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIEtleVNwZWMgZW5naW5lR2V0S2V5U3BlYyhTZWNyZXRLZXkga2V5LCBDbGFzcyBrZXlTcGVjKQorICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZW5naW5lR2V0S2V5U3BlYyhrZXksIGtleVNwZWMpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBTZWNyZXRLZXkgZW5naW5lVHJhbnNsYXRlS2V5KFNlY3JldEtleSBrZXkpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5lbmdpbmVUcmFuc2xhdGVLZXkoa2V5KTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+U2VjcmV0S2V5RmFjdG9yeVNwaTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgU2VjcmV0S2V5RmFjdG9yeVNwaQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZWNyZXRLZXlGYWN0b3J5U3BpMDEoKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgSW52YWxpZEtleVNwZWNFeGNlcHRpb24geworICAgICAgICBNb2NrX1NlY3JldEtleUZhY3RvcnlTcGkgc2tmU3BpID0gbmV3IE1vY2tfU2VjcmV0S2V5RmFjdG9yeVNwaSgpOworICAgICAgICBTZWNyZXRLZXkgc2sgPSBudWxsOworICAgICAgICBhc3NlcnROdWxsKCJOb3QgbnVsbCByZXN1bHQiLCBza2ZTcGkuZW5naW5lVHJhbnNsYXRlS2V5KHNrKSk7CisKKyAgICAgICAgS2V5U3BlYyBrc3BlYyA9IG51bGw7CisgICAgICAgIGFzc2VydE51bGwoIk5vdCBudWxsIHJlc3VsdCIsIHNrZlNwaS5lbmdpbmVHZW5lcmF0ZVNlY3JldChrc3BlYykpOworCisgICAgICAgIGFzc2VydE51bGwoIk5vdCBudWxsIHJlc3VsdCIsIHNrZlNwaS5lbmdpbmVHZXRLZXlTcGVjKHNrLCBudWxsKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL1NlY3JldEtleUZhY3RvcnlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vU2VjcmV0S2V5RmFjdG9yeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZDJiY2Y5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL1NlY3JldEtleUZhY3RvcnlUZXN0LmphdmEKQEAgLTAsMCArMSw0ODAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0bzsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkludmFsaWRLZXlTcGVjRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5LZXlTcGVjOworCitpbXBvcnQgamF2YXguY3J5cHRvLktleUdlbmVyYXRvcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2VjcmV0S2V5OworaW1wb3J0IGphdmF4LmNyeXB0by5TZWNyZXRLZXlGYWN0b3J5OworaW1wb3J0IGphdmF4LmNyeXB0by5TZWNyZXRLZXlGYWN0b3J5U3BpOworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLkRFU0tleVNwZWM7CitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuREVTZWRlS2V5U3BlYzsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5TZWNyZXRLZXlTcGVjOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5zdXBwb3J0Lk15U2VjcmV0S2V5RmFjdG9yeVNwaTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5TcGlFbmdVdGlsczsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+U2VjcmV0S2V5RmFjdG9yeTwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIFNlY3JldEtleUZhY3RvcnlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgc3J2U2VjcmV0S2V5RmFjdG9yeSA9ICJTZWNyZXRLZXlGYWN0b3J5IjsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZWZhdWx0QWxnb3JpdGhtMSA9ICJERVNlZGUiOworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZWZhdWx0QWxnb3JpdGhtMiA9ICJERVMiOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZGVmYXVsdEFsZ29yaXRobSA9IG51bGw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZGVmYXVsdFByb3ZpZGVyTmFtZSA9IG51bGw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBQcm92aWRlciBkZWZhdWx0UHJvdmlkZXIgPSBudWxsOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gaW52YWxpZFZhbHVlcyA9IFNwaUVuZ1V0aWxzLmludmFsaWRWYWx1ZXM7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZ1tdIHZhbGlkVmFsdWVzID0gbmV3IFN0cmluZ1syXTsKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIERFRlN1cHBvcnRlZCA9IGZhbHNlOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5vdFN1cHBvcnRNc2cgPSAiRGVmYXVsdCBhbGdvcml0aG0gaXMgbm90IHN1cHBvcnRlZCI7CisKKyAgICBzdGF0aWMgeworICAgICAgICBkZWZhdWx0UHJvdmlkZXIgPSBTcGlFbmdVdGlscy5pc1N1cHBvcnQoZGVmYXVsdEFsZ29yaXRobTEsCisgICAgICAgICAgICAgICAgc3J2U2VjcmV0S2V5RmFjdG9yeSk7CisgICAgICAgIERFRlN1cHBvcnRlZCA9IChkZWZhdWx0UHJvdmlkZXIgIT0gbnVsbCk7CisgICAgICAgIGlmIChERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGRlZmF1bHRBbGdvcml0aG0gPSBkZWZhdWx0QWxnb3JpdGhtMTsKKyAgICAgICAgICAgIHZhbGlkVmFsdWVzWzBdID0gZGVmYXVsdEFsZ29yaXRobS50b1VwcGVyQ2FzZSgpOworICAgICAgICAgICAgdmFsaWRWYWx1ZXNbMV0gPSBkZWZhdWx0QWxnb3JpdGhtLnRvTG93ZXJDYXNlKCk7CisgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lID0gZGVmYXVsdFByb3ZpZGVyLmdldE5hbWUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlciA9IFNwaUVuZ1V0aWxzLmlzU3VwcG9ydChkZWZhdWx0QWxnb3JpdGhtMiwKKyAgICAgICAgICAgICAgICAgICAgc3J2U2VjcmV0S2V5RmFjdG9yeSk7CisgICAgICAgICAgICBERUZTdXBwb3J0ZWQgPSAoZGVmYXVsdFByb3ZpZGVyICE9IG51bGwpOworICAgICAgICAgICAgaWYgKERFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgICAgIGRlZmF1bHRBbGdvcml0aG0gPSBkZWZhdWx0QWxnb3JpdGhtMjsKKyAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1swXSA9IGRlZmF1bHRBbGdvcml0aG0udG9VcHBlckNhc2UoKTsKKyAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1syXSA9IGRlZmF1bHRBbGdvcml0aG0udG9Mb3dlckNhc2UoKTsKKyAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lID0gZGVmYXVsdFByb3ZpZGVyLmdldE5hbWUoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZGVmYXVsdEFsZ29yaXRobSA9IG51bGw7CisgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyTmFtZSA9IG51bGw7CisgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCBTZWNyZXRLZXlGYWN0b3J5W10gY3JlYXRlU0tGYWMoKSB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKGRlZmF1bHRBbGdvcml0aG0gKyAiIGFsZ29yaXRobSBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBTZWNyZXRLZXlGYWN0b3J5W10gc2tGID0gbmV3IFNlY3JldEtleUZhY3RvcnlbM107CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBza0ZbMF0gPSBTZWNyZXRLZXlGYWN0b3J5LmdldEluc3RhbmNlKGRlZmF1bHRBbGdvcml0aG0pOworICAgICAgICAgICAgc2tGWzFdID0gU2VjcmV0S2V5RmFjdG9yeS5nZXRJbnN0YW5jZShkZWZhdWx0QWxnb3JpdGhtLAorICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICAgICAgc2tGWzJdID0gU2VjcmV0S2V5RmFjdG9yeS5nZXRJbnN0YW5jZShkZWZhdWx0QWxnb3JpdGhtLAorICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgIHJldHVybiBza0Y7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5TZWNyZXRLZXlGYWN0b3J5PC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBTZWNyZXRLZXlGYWN0b3J5IG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZWNyZXRLZXlGYWN0b3J5MDEoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEtleVNwZWNFeGNlcHRpb24sIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBTZWNyZXRLZXlGYWN0b3J5U3BpIHNwaSA9IG5ldyBNeVNlY3JldEtleUZhY3RvcnlTcGkoKTsKKyAgICAgICAgU2VjcmV0S2V5RmFjdG9yeSBzZWNLRiA9IG5ldyBteVNlY3JldEtleUZhY3Rvcnkoc3BpLCBkZWZhdWx0UHJvdmlkZXIsCisgICAgICAgICAgICAgICAgZGVmYXVsdEFsZ29yaXRobSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIHNlY0tGLmdldEFsZ29yaXRobSgpLAorICAgICAgICAgICAgICAgIGRlZmF1bHRBbGdvcml0aG0pOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsIHNlY0tGLmdldFByb3ZpZGVyKCksIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCByZXN1bHQiLCBzZWNLRi5nZW5lcmF0ZVNlY3JldChudWxsKSk7CisgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCByZXN1bHQiLCBzZWNLRi5nZXRLZXlTcGVjKG51bGwsIG51bGwpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiSW5jb3JyZWN0IHJlc3VsdCIsIHNlY0tGLnRyYW5zbGF0ZUtleShudWxsKSk7CisgICAgICAgIHNlY0tGID0gbmV3IG15U2VjcmV0S2V5RmFjdG9yeShudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiQWxnb3JpdGhtIG11c3QgYmUgbnVsbCIsIHNlY0tGLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiUHJvdmlkZXIgbXVzdCBiZSBudWxsIiwgc2VjS0YuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZWNLRi50cmFuc2xhdGVLZXkobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uczoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbnVsbDsKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGhhcyBpbnZhbGlkIHZhbHVlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNlY3JldEtleUZhY3RvcnkwMigpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2VjcmV0S2V5RmFjdG9yeS5nZXRJbnN0YW5jZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIGlmIGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgU2VjcmV0S2V5RmFjdG9yeS5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2FzIG5vdCB0aHJvd24gYXMgZXhwZWN0ZWQiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIFNlY3JldEtleU9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZWNyZXRLZXlGYWN0b3J5MDMoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU2VjcmV0S2V5RmFjdG9yeSBzZWNLRiA9IFNlY3JldEtleUZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIHNlY0tGLmdldEFsZ29yaXRobSgpLAorICAgICAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbnVsbDsKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIGludmFsaWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VjcmV0S2V5RmFjdG9yeTA0KCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNlY3JldEtleUZhY3RvcnkuZ2V0SW5zdGFuY2UobnVsbCwgZGVmYXVsdFByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBvciBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biBpZiBhbGdvcml0aG0gaXMgbnVsbCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFNlY3JldEtleUZhY3RvcnkuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3YXMgbm90IHRocm93biBhcyBleHBlY3RlZCAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjoKKyAgICAgKiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbCBvciBlbXB0eTsKKyAgICAgKiB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gd2hlbiBwcm92aWRlciBoYXMgaW52YWxpZCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZWNyZXRLZXlGYWN0b3J5MDUoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcHJvdiA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgU2VjcmV0S2V5RmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgcHJvdik7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIGFzIGV4cGVjdGVkIChhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQodmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiIHByb3ZpZGVyOiBudWxsIikpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgU2VjcmV0S2V5RmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgIiIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biBhcyBleHBlY3RlZCAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KHZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIiBwcm92aWRlcjogZW1wdHkiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChpbnQgaiA9IDE7IGogPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU2VjcmV0S2V5RmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnZhbGlkVmFsdWVzW2pdKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24gYXMgZXhwZWN0ZWQgKGFsZ29yaXRobTogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQodmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiIHByb3ZpZGVyOiAiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tqXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBTZWNyZXRLZXlGYWN0b3J5IG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZWNyZXRLZXlGYWN0b3J5MDYoKSB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBTZWNyZXRLZXlGYWN0b3J5IHNlY0tGID0gU2VjcmV0S2V5RmFjdG9yeS5nZXRJbnN0YW5jZSgKKyAgICAgICAgICAgICAgICAgICAgdmFsaWRWYWx1ZXNbaV0sIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwgc2VjS0YuZ2V0QWxnb3JpdGhtKCksCisgICAgICAgICAgICAgICAgICAgIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwgc2VjS0YuZ2V0UHJvdmlkZXIoKS5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgUHJvdmlkZXIgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG51bGw7CisgICAgICogdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBpbnZhbGlkCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNlY3JldEtleUZhY3RvcnkwNygpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgU2VjcmV0S2V5RmFjdG9yeS5nZXRJbnN0YW5jZShudWxsLCBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gaWYgYWxnb3JpdGhtIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTZWNyZXRLZXlGYWN0b3J5LmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0sIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIGFzIGV4cGVjdGVkIChhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNlY3JldEtleUZhY3RvcnkwOCgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBwcm92ID0gbnVsbDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTZWNyZXRLZXlGYWN0b3J5LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBwcm92KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24gYXMgZXhwZWN0ZWQgKHByb3ZpZGVyIGlzIG51bGwsIGFsZ29yaXRobTogIgorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdCh2YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgU2VjcmV0S2V5RmFjdG9yeSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VjcmV0S2V5RmFjdG9yeTA5KCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFNlY3JldEtleUZhY3Rvcnkgc2VjS0YgPSBTZWNyZXRLZXlGYWN0b3J5LmdldEluc3RhbmNlKAorICAgICAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1tpXSwgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIHNlY0tGLmdldEFsZ29yaXRobSgpLAorICAgICAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsIHNlY0tGLmdldFByb3ZpZGVyKCksCisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZW5lcmF0ZVNlY3JldChLZXlTcGVjIGtleVNwZWMpPC9jb2RlPiBhbmQKKyAgICAgKiA8Y29kZT5nZXRLZXlTcGVjKFNlY3JldEtleSBrZXksIENsYXNzIGtleVNwZWMpCisgICAgICogbWV0aG9kcworICAgICAqIEFzc2VydGlvbjoKKyAgICAgKiB0aHJvdyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiBpZiBwYXJhbWV0ZXIgaXMgaW5hcHByb3ByaWF0ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZWNyZXRLZXlGYWN0b3J5MTAoKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIGJiID0gbmV3IGJ5dGVbMjRdOworICAgICAgICBLZXlTcGVjIGtzID0gKGRlZmF1bHRBbGdvcml0aG0uZXF1YWxzKGRlZmF1bHRBbGdvcml0aG0yKSA/IChLZXlTcGVjKW5ldyBERVNLZXlTcGVjKGJiKSA6CisgICAgICAgICAgICAoS2V5U3BlYyluZXcgREVTZWRlS2V5U3BlYyhiYikpOworICAgICAgICBLZXlTcGVjIHJrcyA9IG51bGw7CisgICAgICAgIFNlY3JldEtleVNwZWMgc2VjS2V5U3BlYyA9IG5ldyBTZWNyZXRLZXlTcGVjKGJiLCBkZWZhdWx0QWxnb3JpdGhtKTsKKyAgICAgICAgU2VjcmV0S2V5IHNlY0tleSA9IG51bGw7CisgICAgICAgIFNlY3JldEtleUZhY3RvcnlbXSBza0YgPSBjcmVhdGVTS0ZhYygpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJTZWNyZXRLZXlGYWN0b3J5IG9iamVjdCB3ZXJlIG5vdCBjcmVhdGVkIiwgc2tGKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBza0YubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2tGW2ldLmdlbmVyYXRlU2VjcmV0KG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoImdlbmVyYXRlU2VjcmV0KG51bGwpOiBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleVNwZWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzZWNLZXkgPSBza0ZbaV0uZ2VuZXJhdGVTZWNyZXQoa3MpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBza0ZbaV0uZ2V0S2V5U3BlYyhudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJnZXRLZXlTcGVjKG51bGwsbnVsbCk6IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHNrRltpXS5nZXRLZXlTcGVjKG51bGwsIGtzLmdldENsYXNzKCkpOworICAgICAgICAgICAgICAgIGZhaWwoImdldEtleVNwZWMobnVsbCwgQ2xhc3MpOiBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleVNwZWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBza0ZbaV0uZ2V0S2V5U3BlYyhzZWNLZXksIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoImdldEtleVNwZWMoc2VjS2V5LCBudWxsKTogTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgSW52YWxpZEtleVNwZWNFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2xhc3MgYzsKKyAgICAgICAgICAgICAgICBpZiAoZGVmYXVsdEFsZ29yaXRobS5lcXVhbHMoZGVmYXVsdEFsZ29yaXRobTIpKSB7CisgICAgICAgICAgICAgICAgICAgIGMgPSBERVNlZGVLZXlTcGVjLmNsYXNzOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGMgPSBERVNLZXlTcGVjLmNsYXNzOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBza0ZbaV0uZ2V0S2V5U3BlYyhzZWNLZXlTcGVjLCBjKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJnZXRLZXlTcGVjKHNlY0tleSwgQ2xhc3MpOiBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleVNwZWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmtzID0gc2tGW2ldLmdldEtleVNwZWMoc2VjS2V5U3BlYywga3MuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICBpZiAoZGVmYXVsdEFsZ29yaXRobS5lcXVhbHMoZGVmYXVsdEFsZ29yaXRobTEpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGdldEtleVNwZWMoKSByZXN1bHQgMSIsCisgICAgICAgICAgICAgICAgICAgICAgICBya3MgaW5zdGFuY2VvZiBERVNlZGVLZXlTcGVjKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGdldEtleVNwZWMoKSByZXN1bHQgMSIsCisgICAgICAgICAgICAgICAgICAgICAgICBya3MgaW5zdGFuY2VvZiBERVNLZXlTcGVjKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmtzID0gc2tGW2ldLmdldEtleVNwZWMoc2VjS2V5LCBrcy5nZXRDbGFzcygpKTsKKyAgICAgICAgICAgIGlmIChkZWZhdWx0QWxnb3JpdGhtLmVxdWFscyhkZWZhdWx0QWxnb3JpdGhtMSkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZ2V0S2V5U3BlYygpIHJlc3VsdCAyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIHJrcyBpbnN0YW5jZW9mIERFU2VkZUtleVNwZWMpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZ2V0S2V5U3BlYygpIHJlc3VsdCAyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIHJrcyBpbnN0YW5jZW9mIERFU0tleVNwZWMpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBbGdvcml0aG0oKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU2VjcmV0S2V5RmFjdG9yeSBzZWNLRiA9IFNlY3JldEtleUZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIHNlY0tGLmdldEFsZ29yaXRobSgpLAorICAgICAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgIH0KKworICAgICAgICBNb2NrX1NlY3JldEtleUZhY3RvcnkgbXNmID0gbmV3IE1vY2tfU2VjcmV0S2V5RmFjdG9yeShudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChtc2YuZ2V0QWxnb3JpdGhtKCkpOworICAgIH0KKworICAgIGNsYXNzIE1vY2tfU2VjcmV0S2V5RmFjdG9yeSBleHRlbmRzIFNlY3JldEtleUZhY3Rvcnl7CisgICAgICAgIHByb3RlY3RlZCBNb2NrX1NlY3JldEtleUZhY3RvcnkoU2VjcmV0S2V5RmFjdG9yeVNwaSBhcmcwLCBQcm92aWRlciBhcmcxLCBTdHJpbmcgYXJnMikgeworICAgICAgICAgICAgc3VwZXIoYXJnMCwgYXJnMSwgYXJnMik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFByb3ZpZGVyKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFNlY3JldEtleUZhY3Rvcnkgc2VjS0YgPSBTZWNyZXRLZXlGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHNlY0tGLmdldFByb3ZpZGVyKCkpOworICAgICAgICB9CisKKyAgICAgICAgTW9ja19TZWNyZXRLZXlGYWN0b3J5IG1zZiA9IG5ldyBNb2NrX1NlY3JldEtleUZhY3RvcnkobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwobXNmLmdldFByb3ZpZGVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdHJhbnNsYXRlS2V5TGphdmF4X2NyeXB0b19TZWNyZXRLZXkoKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIEtleUdlbmVyYXRvciBrZyA9IG51bGw7CisgICAgICAgIEtleSBrZXkgPSBudWxsOworICAgICAgICBTZWNyZXRLZXlGYWN0b3J5IHNlY0tGID0gbnVsbDsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBzZWNLRiA9IFNlY3JldEtleUZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc2VjS0YuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgICAgICBrZyA9IEtleUdlbmVyYXRvci5nZXRJbnN0YW5jZShzZWNLRi5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgICAgICBrZy5pbml0KG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICBrZXkgPSBrZy5nZW5lcmF0ZUtleSgpOworCisgICAgICAgICAgICBzZWNLRi50cmFuc2xhdGVLZXkoKFNlY3JldEtleSkga2V5KTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VjS0YudHJhbnNsYXRlS2V5KG51bGwpOworICAgICAgICAgICAgZmFpbCgiSW52YWxpZEtleUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KK30KKworY2xhc3MgbXlTZWNyZXRLZXlGYWN0b3J5IGV4dGVuZHMgU2VjcmV0S2V5RmFjdG9yeSB7CisgICAgcHVibGljIG15U2VjcmV0S2V5RmFjdG9yeShTZWNyZXRLZXlGYWN0b3J5U3BpIHNwaSwgUHJvdmlkZXIgcHJvdiwgU3RyaW5nIGFsZykgeworICAgICAgICBzdXBlcihzcGksIHByb3YsIGFsZyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL1NlY3JldEtleVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9TZWNyZXRLZXlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTI3MDgzYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9TZWNyZXRLZXlUZXN0LmphdmEKQEAgLTAsMCArMSw2MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvOworCitpbXBvcnQgamF2YXguY3J5cHRvLlNlY3JldEtleTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5TZWNyZXRLZXk8L2NvZGU+IGNsYXNzIGZpZWxkCisgKgorICovCitwdWJsaWMgY2xhc3MgU2VjcmV0S2V5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnNlcmlhbFZlcnNpb25VSUQ8L2NvZGU+IGZpZWxkCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEZpZWxkKCkgeworICAgICAgICBjaGVja1NlY3JldEtleSBzayA9IG5ldyBjaGVja1NlY3JldEtleSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBzZXJpYWxWZXJzaW9uVUlEIiwKKyAgICAgICAgICAgICAgICBzay5nZXRTZXJWZXJVSUQoKSwgLy9TZWNyZXRLZXkuc2VyaWFsVmVyc2lvblVJRAorICAgICAgICAgICAgICAgIC00Nzk1ODc4NzA5NTk1MTQ2OTUyTCk7CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIGNoZWNrU2VjcmV0S2V5IGltcGxlbWVudHMgU2VjcmV0S2V5IHsKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgICAgICByZXR1cm4gIlNlY3JldEtleSI7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRGb3JtYXQoKSB7CisgICAgICAgICAgICByZXR1cm4gIkZvcm1hdCI7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBieXRlWzBdOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBsb25nIGdldFNlclZlclVJRCgpIHsKKyAgICAgICAgICAgIHJldHVybiBzZXJpYWxWZXJzaW9uVUlEOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL1Nob3J0QnVmZmVyRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL1Nob3J0QnVmZmVyRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUyZmE5NjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vU2hvcnRCdWZmZXJFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw3OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvOworCitpbXBvcnQgamF2YXguY3J5cHRvLlNob3J0QnVmZmVyRXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5TaG9ydEJ1ZmZlckV4Y2VwdGlvbjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIFNob3J0QnVmZmVyRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisgICAgc3RhdGljIFRocm93YWJsZSB0Q2F1c2UgPSBuZXcgVGhyb3dhYmxlKCJUaHJvd2FibGUgZm9yIGV4Y2VwdGlvbiIpOworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+U2hvcnRCdWZmZXJFeGNlcHRpb24oKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgU2hvcnRCdWZmZXJFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTaG9ydEJ1ZmZlckV4Y2VwdGlvbjAxKCkgeworICAgICAgICBTaG9ydEJ1ZmZlckV4Y2VwdGlvbiB0RSA9IG5ldyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbigpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5TaG9ydEJ1ZmZlckV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4KKyAgICAgKiBQYXJhbWV0ZXIgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2hvcnRCdWZmZXJFeGNlcHRpb24wMigpIHsKKyAgICAgICAgU2hvcnRCdWZmZXJFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgU2hvcnRCdWZmZXJFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5TaG9ydEJ1ZmZlckV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbiB3aGVuIDxjb2RlPm1zZzwvY29kZT4gaXMKKyAgICAgKiBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNob3J0QnVmZmVyRXhjZXB0aW9uMDMoKSB7CisgICAgICAgIFN0cmluZyBtc2cgPSBudWxsOworICAgICAgICBTaG9ydEJ1ZmZlckV4Y2VwdGlvbiB0RSA9IG5ldyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbihtc2cpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9DaXBoZXJBZXNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9DaXBoZXJBZXNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGI4ZjAxNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL0NpcGhlckFlc1Rlc3QuamF2YQpAQCAtMCwwICsxLDU4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uZnVuYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIENpcGhlckFlc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisvLyAyMTYgY2FzZXMgY2hlY2tlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RfQWVzTm9JU08oKSB7CisgICAgICAgIENpcGhlclN5bW1ldHJpY0tleVRocmVhZCBhZXNOb0lTTyA9IG5ldyBDaXBoZXJTeW1tZXRyaWNLZXlUaHJlYWQoIkFFUyIsCisgICAgICAgICAgICAgICAgbmV3IGludFtdIHsxMjgsIDE5MiwgMjU2fSwgLy8gS2V5c2l6ZSBtdXN0IGJlIDEyOCwgMTkyLCAyNTYuCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICJFQ0IiLCAiQ0JDIiwgIkNGQiIsICJDRkI4IiwgIkNGQjE2IiwgIkNGQjI0IiwgIkNGQjMyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJDRkI0MCIsICJDRkI0OCIsICJDRkI1NiIsICJDRkI2NCIsICJDRkI3MiIsICJDRkI4MCIsCisgICAgICAgICAgICAgICAgICAgICAgICAiQ0ZCODgiLCAiQ0ZCOTYiLCAiQ0ZCMTA0IiwgIkNGQjExMiIsICJDRkIxMjAiLAorICAgICAgICAgICAgICAgICAgICAgICAgIkNGQjEyOCIsICJPRkIiLCAiT0ZCOCIsICJPRkIxNiIsICJPRkIyNCIsICJPRkIzMiIsCisgICAgICAgICAgICAgICAgICAgICAgICAiT0ZCNDAiLCAiT0ZCNDgiLCAiT0ZCNTYiLCAiT0ZCNjQiLCAiT0ZCNzIiLCAiT0ZCODAiLAorICAgICAgICAgICAgICAgICAgICAgICAgIk9GQjg4IiwgIk9GQjk2IiwgIk9GQjEwNCIsICJPRkIxMTIiLCAiT0ZCMTIwIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJPRkIxMjgifSwgbmV3IFN0cmluZ1tdIHsiTm9QYWRkaW5nIiwgIlBLQ1M1UGFkZGluZyJ9KTsKKworICAgICAgICBhZXNOb0lTTy5sYXVuY2hlcigpOworCisgICAgICAgIGFzc2VydEVxdWFscyhhZXNOb0lTTy5nZXRGYWlsdXJlTWVzc2FnZXMoKSwgMCwgYWVzTm9JU08KKyAgICAgICAgICAgICAgICAuZ2V0VG90YWxGYWlsdXJlc051bWJlcigpKTsKKyAgICB9CisKKy8vIDEwOCBjYXNlcyBjaGVja2VkCisgICAgcHVibGljIHZvaWQgdGVzdF9BZXNJU08oKSB7CisgICAgICAgIENpcGhlclN5bW1ldHJpY0tleVRocmVhZCBhZXNJU08gPSBuZXcgQ2lwaGVyU3ltbWV0cmljS2V5VGhyZWFkKCJBRVMiLAorICAgICAgICAgICAgICAgIG5ldyBpbnRbXSB7MTI4LCAxOTIsIDI1Nn0sIC8vIEtleXNpemUgbXVzdCBiZSAxMjgsIDE5MiwgMjU2LgorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAiRUNCIiwgIkNCQyIsICJDRkIiLCAiQ0ZCOCIsICJDRkIxNiIsICJDRkIyNCIsICJDRkIzMiIsCisgICAgICAgICAgICAgICAgICAgICAgICAiQ0ZCNDAiLCAiQ0ZCNDgiLCAiQ0ZCNTYiLCAiQ0ZCNjQiLCAiQ0ZCNzIiLCAiQ0ZCODAiLAorICAgICAgICAgICAgICAgICAgICAgICAgIkNGQjg4IiwgIkNGQjk2IiwgIkNGQjEwNCIsICJDRkIxMTIiLCAiQ0ZCMTIwIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJDRkIxMjgiLCAiT0ZCIiwgIk9GQjgiLCAiT0ZCMTYiLCAiT0ZCMjQiLCAiT0ZCMzIiLAorICAgICAgICAgICAgICAgICAgICAgICAgIk9GQjQwIiwgIk9GQjQ4IiwgIk9GQjU2IiwgIk9GQjY0IiwgIk9GQjcyIiwgIk9GQjgwIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJPRkI4OCIsICJPRkI5NiIsICJPRkIxMDQiLCAiT0ZCMTEyIiwgIk9GQjEyMCIsCisgICAgICAgICAgICAgICAgICAgICAgICAiT0ZCMTI4In0sIG5ldyBTdHJpbmdbXSB7IklTTzEwMTI2UEFERElORyJ9KTsKKworICAgICAgICBhZXNJU08ubGF1bmNoZXIoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoYWVzSVNPLmdldEZhaWx1cmVNZXNzYWdlcygpLCAwLCBhZXNJU08KKyAgICAgICAgICAgICAgICAuZ2V0VG90YWxGYWlsdXJlc051bWJlcigpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9DaXBoZXJBZXNXcmFwVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvQ2lwaGVyQWVzV3JhcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZDg2ZmRkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvQ2lwaGVyQWVzV3JhcFRlc3QuamF2YQpAQCAtMCwwICsxLDM3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uZnVuYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIENpcGhlckFlc1dyYXBUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCisgICAgLy8gMyBjYXNlcyBjaGVja2VkCisgICAgcHVibGljIHZvaWQgdGVzdF9BZXNXcmFwKCkgeworICAgICAgICBDaXBoZXJXcmFwVGhyZWFkIGFlc1dyYXAgPSBuZXcgQ2lwaGVyV3JhcFRocmVhZCgiQUVTV3JhcCIsIG5ldyBpbnRbXSB7CisgICAgICAgICAgICAgICAgMTI4LCAxOTIsIDI1Nn0sIC8vIEtleXNpemUgbXVzdCBiZSAxMjgsIDE5MiwgMjU2LgorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7IkVDQiJ9LCBuZXcgU3RyaW5nW10geyJOb1BhZGRpbmcifSk7CisKKyAgICAgICAgYWVzV3JhcC5sYXVuY2hlcigpOworCisgICAgICAgIGFzc2VydEVxdWFscyhhZXNXcmFwLmdldEZhaWx1cmVNZXNzYWdlcygpLCAwLCBhZXNXcmFwCisgICAgICAgICAgICAgICAgLmdldFRvdGFsRmFpbHVyZXNOdW1iZXIoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvQ2lwaGVyREVTZWRlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvQ2lwaGVyREVTZWRlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ4NTY1ZjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9DaXBoZXJERVNlZGVUZXN0LmphdmEKQEAgLTAsMCArMSw1MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvLmZ1bmM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBDaXBoZXJERVNlZGVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworLy8gODAgY2FzZXMgY2hlY2tlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RfREVTZWRlTm9JU08oKSB7CisgICAgICAgIENpcGhlclN5bW1ldHJpY0tleVRocmVhZCBERVNlZGVOb0lTTyA9IG5ldyBDaXBoZXJTeW1tZXRyaWNLZXlUaHJlYWQoCisgICAgICAgICAgICAgICAgIkRFU2VkZSIsIG5ldyBpbnRbXSB7MTEyLCAxNjh9LC8vIEtleXNpemUgbXVzdCBiZSAxMTIgb3IgMTY4LgorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAiRUNCIiwgIkNCQyIsICJDRkIiLCAiQ0ZCOCIsICJDRkIxNiIsICJDRkIyNCIsICJDRkIzMiIsCisgICAgICAgICAgICAgICAgICAgICAgICAiQ0ZCNDAiLCAiQ0ZCNDgiLCAiQ0ZCNTYiLCAiQ0ZCNjQiLCAiT0ZCIiwgIk9GQjgiLAorICAgICAgICAgICAgICAgICAgICAgICAgIk9GQjE2IiwgIk9GQjI0IiwgIk9GQjMyIiwgIk9GQjQwIiwgIk9GQjQ4IiwgIk9GQjU2IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJPRkI2NCJ9LCBuZXcgU3RyaW5nW10geyJOb1BhZGRpbmciLCAiUEtDUzVQYWRkaW5nIn0pOworCisgICAgICAgIERFU2VkZU5vSVNPLmxhdW5jaGVyKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERFU2VkZU5vSVNPLmdldEZhaWx1cmVNZXNzYWdlcygpLCAwLCBERVNlZGVOb0lTTworICAgICAgICAgICAgICAgIC5nZXRUb3RhbEZhaWx1cmVzTnVtYmVyKCkpOworICAgIH0KKworLy8gNDAgY2FzZXMgY2hlY2tlZAorICAgIHB1YmxpYyB2b2lkIHRlc3RfREVTZWRlSVNPKCkgeworICAgICAgICBDaXBoZXJTeW1tZXRyaWNLZXlUaHJlYWQgREVTZWRlSVNPID0gbmV3IENpcGhlclN5bW1ldHJpY0tleVRocmVhZCgKKyAgICAgICAgICAgICAgICAiREVTZWRlIiwgbmV3IGludFtdIHsxMTIsIDE2OH0sLy8gS2V5c2l6ZSBtdXN0IGJlIDExMiBvciAxNjguCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICJFQ0IiLCAiQ0JDIiwgIkNGQiIsICJDRkI4IiwgIkNGQjE2IiwgIkNGQjI0IiwgIkNGQjMyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJDRkI0MCIsICJDRkI0OCIsICJDRkI1NiIsICJDRkI2NCIsICJPRkIiLCAiT0ZCOCIsCisgICAgICAgICAgICAgICAgICAgICAgICAiT0ZCMTYiLCAiT0ZCMjQiLCAiT0ZCMzIiLCAiT0ZCNDAiLCAiT0ZCNDgiLCAiT0ZCNTYiLAorICAgICAgICAgICAgICAgICAgICAgICAgIk9GQjY0In0sIG5ldyBTdHJpbmdbXSB7IklTTzEwMTI2UEFERElORyJ9KTsKKworICAgICAgICBERVNlZGVJU08ubGF1bmNoZXIoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoREVTZWRlSVNPLmdldEZhaWx1cmVNZXNzYWdlcygpLCAwLCBERVNlZGVJU08KKyAgICAgICAgICAgICAgICAuZ2V0VG90YWxGYWlsdXJlc051bWJlcigpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9DaXBoZXJERVNlZGVXcmFwVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvQ2lwaGVyREVTZWRlV3JhcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wN2FiOTQ1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvQ2lwaGVyREVTZWRlV3JhcFRlc3QuamF2YQpAQCAtMCwwICsxLDMyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uZnVuYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIENpcGhlckRFU2VkZVdyYXBUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworLy8gIDIgY2FzZXMgY2hlY2tlZC4KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0RFU2VkZVdyYXAoKSB7CisgICAgICAgIENpcGhlcldyYXBUaHJlYWQgREVTZWRlV3JhcCA9IG5ldyBDaXBoZXJXcmFwVGhyZWFkKCJERVNlZGVXcmFwIiwKKyAgICAgICAgICAgICAgICBuZXcgaW50W10gezExMiwgMTY4fSwgLy8gS2V5c2l6ZSBtdXN0IGJlIDExMiBvciAxNjguCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHsiQ0JDIn0sIG5ldyBTdHJpbmdbXSB7Ik5vUGFkZGluZyJ9KTsKKworICAgICAgICBERVNlZGVXcmFwLmxhdW5jaGVyKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKERFU2VkZVdyYXAuZ2V0RmFpbHVyZU1lc3NhZ2VzKCksIDAsIERFU2VkZVdyYXAKKyAgICAgICAgICAgICAgICAuZ2V0VG90YWxGYWlsdXJlc051bWJlcigpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9DaXBoZXJEZXNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9DaXBoZXJEZXNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGM0NmFkMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL0NpcGhlckRlc1Rlc3QuamF2YQpAQCAtMCwwICsxLDUyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uZnVuYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIENpcGhlckRlc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisvLyA0MCBjYXNlcyBjaGVja2VkCisgICAgcHVibGljIHZvaWQgdGVzdF9EZXNOb0lTTygpIHsKKyAgICAgICAgQ2lwaGVyU3ltbWV0cmljS2V5VGhyZWFkIGRlc05vSVNPID0gbmV3IENpcGhlclN5bW1ldHJpY0tleVRocmVhZCgiREVTIiwKKyAgICAgICAgICAgICAgICBuZXcgaW50W10gezU2fSwvLyBLZXlzaXplIG11c3QgYmUgNTYuCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICJFQ0IiLCAiQ0JDIiwgIkNGQiIsICJDRkI4IiwgIkNGQjE2IiwgIkNGQjI0IiwgIkNGQjMyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJDRkI0MCIsICJDRkI0OCIsICJDRkI1NiIsICJDRkI2NCIsICJPRkIiLCAiT0ZCOCIsCisgICAgICAgICAgICAgICAgICAgICAgICAiT0ZCMTYiLCAiT0ZCMjQiLCAiT0ZCMzIiLCAiT0ZCNDAiLCAiT0ZCNDgiLCAiT0ZCNTYiLAorICAgICAgICAgICAgICAgICAgICAgICAgIk9GQjY0In0sIG5ldyBTdHJpbmdbXSB7Ik5vUGFkZGluZyIsICJQS0NTNVBhZGRpbmcifSk7CisKKyAgICAgICAgZGVzTm9JU08ubGF1bmNoZXIoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoZGVzTm9JU08uZ2V0RmFpbHVyZU1lc3NhZ2VzKCksIDAsIGRlc05vSVNPCisgICAgICAgICAgICAgICAgLmdldFRvdGFsRmFpbHVyZXNOdW1iZXIoKSk7CisgICAgfQorCisvLyAyMCBjYXNlcyBjaGVja2VkCisgICAgcHVibGljIHZvaWQgdGVzdF9EZXNJU08oKSB7CisgICAgICAgIENpcGhlclN5bW1ldHJpY0tleVRocmVhZCBkZXNJU08gPSBuZXcgQ2lwaGVyU3ltbWV0cmljS2V5VGhyZWFkKCJERVMiLAorICAgICAgICAgICAgICAgIG5ldyBpbnRbXSB7NTZ9LC8vIEtleXNpemUgbXVzdCBiZSA1Ni4KKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geworICAgICAgICAgICAgICAgICAgICAgICAgIkVDQiIsICJDQkMiLCAiQ0ZCIiwgIkNGQjgiLCAiQ0ZCMTYiLCAiQ0ZCMjQiLCAiQ0ZCMzIiLAorICAgICAgICAgICAgICAgICAgICAgICAgIkNGQjQwIiwgIkNGQjQ4IiwgIkNGQjU2IiwgIkNGQjY0IiwgIk9GQiIsICJPRkI4IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJPRkIxNiIsICJPRkIyNCIsICJPRkIzMiIsICJPRkI0MCIsICJPRkI0OCIsICJPRkI1NiIsCisgICAgICAgICAgICAgICAgICAgICAgICAiT0ZCNjQifSwgbmV3IFN0cmluZ1tdIHsiSVNPMTAxMjZQQURESU5HIn0pOworCisgICAgICAgIGRlc0lTTy5sYXVuY2hlcigpOworCisgICAgICAgIGFzc2VydEVxdWFscyhkZXNJU08uZ2V0RmFpbHVyZU1lc3NhZ2VzKCksIDAsIGRlc0lTTworICAgICAgICAgICAgICAgIC5nZXRUb3RhbEZhaWx1cmVzTnVtYmVyKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL0NpcGhlclBCRVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL0NpcGhlclBCRVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMjEzNzRmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvQ2lwaGVyUEJFVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0by5mdW5jOworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uQW5kcm9pZE9ubHk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBDaXBoZXJQQkVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdF9QQkVXaXRoTUQ1QW5kREVTKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENpcGhlclBCRVRocmVhZCBQQkVXaXRoTUQ1QW5kREVTID0gbmV3IENpcGhlclBCRVRocmVhZCgKKyAgICAgICAgICAgICAgICAiUEJFV2l0aE1ENUFuZERFUyIsIG5ldyBpbnRbXSB7NTZ9LCBuZXcgU3RyaW5nW10geyJDQkMifSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geyJQS0NTNVBhZGRpbmcifSk7CisKKyAgICAgICAgUEJFV2l0aE1ENUFuZERFUy5sYXVuY2hlcigpOworCisgICAgICAgIGFzc2VydEVxdWFscyhQQkVXaXRoTUQ1QW5kREVTLmdldEZhaWx1cmVNZXNzYWdlcygpLCAwLCBQQkVXaXRoTUQ1QW5kREVTCisgICAgICAgICAgICAgICAgLmdldFRvdGFsRmFpbHVyZXNOdW1iZXIoKSk7CisgICAgfQorCisgICAgQEFuZHJvaWRPbmx5KCJOb3Qgc3VwcG9ydGVkIGJ5IFJJIChtYXliZSB3aXRoIGEgZGlmZmVyZW50IG5hbWUpIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1BCRVdpdGhTSEFhbmQzS2V5VHJpcGxlREVTKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENpcGhlclBCRVRocmVhZCBQQkVXSVRIU0hBQU5EM0tFWVRSSVBMRURFU0NCQyA9IG5ldyBDaXBoZXJQQkVUaHJlYWQoCisgICAgICAgICAgICAgICAgIlBCRVdJVEhTSEFBTkQzLUtFWVRSSVBMRURFUy1DQkMiLCBuZXcgaW50W10gezExMiwgMTY4fSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geyJDQkMifSwgbmV3IFN0cmluZ1tdIHsiUEtDUzVQYWRkaW5nIn0pOworCisgICAgICAgIFBCRVdJVEhTSEFBTkQzS0VZVFJJUExFREVTQ0JDLmxhdW5jaGVyKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFBCRVdJVEhTSEFBTkQzS0VZVFJJUExFREVTQ0JDLmdldEZhaWx1cmVNZXNzYWdlcygpLCAwLAorICAgICAgICAgICAgICAgIFBCRVdJVEhTSEFBTkQzS0VZVFJJUExFREVTQ0JDLmdldFRvdGFsRmFpbHVyZXNOdW1iZXIoKSk7CisgICAgfQorCisgICAgLy8gU3VwcG9ydGVkLCBidXQgbm90IHBhcnQgb2YgbWFuZGF0b3J5IGNvbXBvbmVudHMgZm9yIEFuZHJvaWQKKyAgICBwdWJsaWMgdm9pZCBkaXNhYmxlZF90ZXN0X1BCRVdpdGhTSEExQW5kNDBCaXRSQzIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2lwaGVyUEJFVGhyZWFkIFBCRVdpdGhTSEExQW5kUkMyXzQwID0gbmV3IENpcGhlclBCRVRocmVhZCgKKyAgICAgICAgICAgICAgICAiUEJFV0lUSFNIQUFORDQwQklUUkMyLUNCQyIsIG5ldyBpbnRbXSB7NDB9LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7IkNCQyJ9LCBuZXcgU3RyaW5nW10geyJQS0NTNVBhZGRpbmcifSk7CisKKyAgICAgICAgUEJFV2l0aFNIQTFBbmRSQzJfNDAubGF1bmNoZXIoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoUEJFV2l0aFNIQTFBbmRSQzJfNDAuZ2V0RmFpbHVyZU1lc3NhZ2VzKCksIDAsCisgICAgICAgICAgICAgICAgUEJFV2l0aFNIQTFBbmRSQzJfNDAuZ2V0VG90YWxGYWlsdXJlc051bWJlcigpKTsKKyAgICB9CisKKworICAgIC8vIE5vdCBzdXBwb3J0ZWQgYnkgQW5kcm9pZAorICAgIHB1YmxpYyB2b2lkIGRpc2FibGVkX3Rlc3RfUEJFV2l0aE1ENUFuZFRyaXBsZURFUygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaXBoZXJQQkVUaHJlYWQgUEJFV2l0aE1ENUFuZFRyaXBsZURFUyA9IG5ldyBDaXBoZXJQQkVUaHJlYWQoCisgICAgICAgICAgICAgICAgIlBCRVdpdGhNRDVBbmRUcmlwbGVERVMiLCBuZXcgaW50W10gezExMiwgMTY4fSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geyJDQkMifSwgbmV3IFN0cmluZ1tdIHsiUEtDUzVQYWRkaW5nIn0pOworCisgICAgICAgIFBCRVdpdGhNRDVBbmRUcmlwbGVERVMubGF1bmNoZXIoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoUEJFV2l0aE1ENUFuZFRyaXBsZURFUy5nZXRGYWlsdXJlTWVzc2FnZXMoKSwgMCwKKyAgICAgICAgICAgICAgICBQQkVXaXRoTUQ1QW5kVHJpcGxlREVTLmdldFRvdGFsRmFpbHVyZXNOdW1iZXIoKSk7CisgICAgfQorCisgICAgLy8gTm90IHN1cHBvcnRlZCBieSBBbmRyb2lkCisgICAgcHVibGljIHZvaWQgZGlzYWJsZWRfdGVzdF9QQkVXaXRoU0hBMUFuZERFU2VkZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaXBoZXJQQkVUaHJlYWQgUEJFV2l0aFNIQTFBbmRERVNlZGUgPSBuZXcgQ2lwaGVyUEJFVGhyZWFkKAorICAgICAgICAgICAgICAgICJQQkVXaXRoU0hBMUFuZERFU2VkZSIsIG5ldyBpbnRbXSB7MTEyLCAxNjh9LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7IkNCQyJ9LCBuZXcgU3RyaW5nW10geyJQS0NTNVBhZGRpbmcifSk7CisKKyAgICAgICAgUEJFV2l0aFNIQTFBbmRERVNlZGUubGF1bmNoZXIoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoUEJFV2l0aFNIQTFBbmRERVNlZGUuZ2V0RmFpbHVyZU1lc3NhZ2VzKCksIDAsCisgICAgICAgICAgICAgICAgUEJFV2l0aFNIQTFBbmRERVNlZGUuZ2V0VG90YWxGYWlsdXJlc051bWJlcigpKTsKKyAgICB9CisKKyAgICAvLyBOb3Qgc3VwcG9ydGVkIGJ5IEFuZHJvaWQKKyAgICBwdWJsaWMgdm9pZCBkaXNhYmxlZF90ZXN0X1BCRVdpdGhTSEExQW5kUkMyXzQwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENpcGhlclBCRVRocmVhZCBQQkVXaXRoU0hBMUFuZFJDMl80MCA9IG5ldyBDaXBoZXJQQkVUaHJlYWQoCisgICAgICAgICAgICAgICAgIlBCRVdpdGhTSEExQW5kUkMyXzQwIiwgbmV3IGludFtdIHs0MH0sIG5ldyBTdHJpbmdbXSB7IkNCQyJ9LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7IlBLQ1M1UGFkZGluZyJ9KTsKKworICAgICAgICBQQkVXaXRoU0hBMUFuZFJDMl80MC5sYXVuY2hlcigpOworCisgICAgICAgIGFzc2VydEVxdWFscyhQQkVXaXRoU0hBMUFuZFJDMl80MC5nZXRGYWlsdXJlTWVzc2FnZXMoKSwgMCwKKyAgICAgICAgICAgICAgICBQQkVXaXRoU0hBMUFuZFJDMl80MC5nZXRUb3RhbEZhaWx1cmVzTnVtYmVyKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL0NpcGhlclBCRVRocmVhZC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvQ2lwaGVyUEJFVGhyZWFkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTgwMTY3MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL0NpcGhlclBCRVRocmVhZC5qYXZhCkBAIC0wLDAgKzEsNjAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0by5mdW5jOworCisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKKworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXI7CitpbXBvcnQgamF2YXguY3J5cHRvLlNlY3JldEtleTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2VjcmV0S2V5RmFjdG9yeTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5QQkVLZXlTcGVjOworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLlBCRVBhcmFtZXRlclNwZWM7CisKK3B1YmxpYyBjbGFzcyBDaXBoZXJQQkVUaHJlYWQgZXh0ZW5kcyBDaXBoZXJUaHJlYWQgeworCisgICAgQ2lwaGVyUEJFVGhyZWFkKFN0cmluZyBuYW1lLCBpbnRbXSBrZXlzLCBTdHJpbmdbXSBtb2RlcywgU3RyaW5nW10gcGFkZGluZ3MpIHsKKyAgICAgICAgc3VwZXIobmFtZSwga2V5cywgbW9kZXMsIHBhZGRpbmdzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjcnlwdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gb3V0cHV0ID0gbmV3IGJ5dGVbMTI4XTsKKyAgICAgICAgYnl0ZVtdIGRlY3J5cHRlZCA9IG5ldyBieXRlWzEyOF07CisgICAgICAgIGJ5dGVbXSBpbnB1dCAgPSAgZ2V0RGF0YSgpLmdldEJ5dGVzKCk7CisgICAgICAgIGJ5dGVbXSBzYWx0ID0gbmV3IGJ5dGVbOF07CisgICAgICAgIFNlY3VyZVJhbmRvbSBzciA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKworICAgICAgICBQQkVLZXlTcGVjIGtleVNwZWMgPSBuZXcgUEJFS2V5U3BlYygidG9wIHNpY3JldCBwYXNzd29yZCIudG9DaGFyQXJyYXkoKSk7CisgICAgICAgIFNlY3JldEtleUZhY3Rvcnkgc2tmID0gU2VjcmV0S2V5RmFjdG9yeS5nZXRJbnN0YW5jZShnZXRBbGdOYW1lKCkpOworICAgICAgICBTZWNyZXRLZXkga2V5ID0gc2tmLmdlbmVyYXRlU2VjcmV0KGtleVNwZWMpOworCisgICAgICAgIENpcGhlciBjaXAgPSBDaXBoZXIuZ2V0SW5zdGFuY2UoZ2V0QWxnTmFtZSgpICsgIi8iICsgZ2V0TW9kZSgpICsgIi8iICsKKyAgICAgICAgICAgICAgICBnZXRQYWRkaW5nKCkpOworCisgICAgICAgIHNyLm5leHRCeXRlcyhzYWx0KTsKKyAgICAgICAgUEJFUGFyYW1ldGVyU3BlYyBwYXJTcGVjID0gbmV3IFBCRVBhcmFtZXRlclNwZWMoc2FsdCwgZ2V0S2V5TGVuZ3RoKCkpOworCisgICAgICAgIGNpcC5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGtleSwgcGFyU3BlYyk7CisgICAgICAgIGNpcC5kb0ZpbmFsKGlucHV0LCAwLCBpbnB1dC5sZW5ndGgsIG91dHB1dCk7CisgICAgICAgIGludCBvdXRwdXRTaXplID0gY2lwLmdldE91dHB1dFNpemUoaW5wdXQubGVuZ3RoKTsKKyAgICAgICAgY2lwLmluaXQoQ2lwaGVyLkRFQ1JZUFRfTU9ERSwga2V5LCBwYXJTcGVjKTsKKyAgICAgICAgY2lwLmRvRmluYWwob3V0cHV0LCAwLCBvdXRwdXRTaXplLCBkZWNyeXB0ZWQpOworCisgICAgICAgIGNoZWNrRW5jb2RlZERhdGEoZ2V0RGF0YSgpLmdldEJ5dGVzKCksIGRlY3J5cHRlZCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvQ2lwaGVyUlNBVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvQ2lwaGVyUlNBVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyNWQ5NTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9DaXBoZXJSU0FUZXN0LmphdmEKQEAgLTAsMCArMSw2NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvLmZ1bmM7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5BbmRyb2lkT25seTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIENpcGhlclJTQVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisvLyAzIGNhc2VzIGNoZWNrZWQKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1JTQVNob3J0S2V5KCkgeworICAgICAgICBDaXBoZXJSU0FUaHJlYWQgcnNhID0gbmV3IENpcGhlclJTQVRocmVhZCgiUlNBIiwgbmV3IGludFtdIHs1MTJ9LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7IkVDQiJ9LCBuZXcgU3RyaW5nW10geworICAgICAgICAgICAgICAgICAgICAgICAgIlBLQ1MxUEFERElORyIsICJPQUVQV0lUSE1ENUFORE1HRjFQQURESU5HIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJPQUVQV0lUSFNIQTFBTkRNR0YxUEFERElORyJ9KTsKKworICAgICAgICByc2EubGF1bmNoZXIoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMocnNhLmdldEZhaWx1cmVNZXNzYWdlcygpLCAwLCByc2EuZ2V0VG90YWxGYWlsdXJlc051bWJlcigpKTsKKyAgICB9CisKKyAgICAvLyBOb3Qgc3VwcG9ydGVkIGJ5IEFuZHJvaWQKKyAgICBwdWJsaWMgdm9pZCBkaXNhYmxlZF90ZXN0X1JTQUxvbmdLZXkoKSB7CisgICAgICAgIENpcGhlclJTQVRocmVhZCByc2EgPSBuZXcgQ2lwaGVyUlNBVGhyZWFkKCJSU0EiLCBuZXcgaW50W10gezEwMjR9LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7IkVDQiJ9LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7Ik9BRVBXSVRIU0hBLTM4NEFORE1HRjFQQURESU5HIiwKKyAgICAgICAgICAgICAgICAiT0FFUFdJVEhTSEEtMjU2QU5ETUdGMVBBRERJTkcifSk7CisKKyAgICAgICAgcnNhLmxhdW5jaGVyKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJzYS5nZXRGYWlsdXJlTWVzc2FnZXMoKSwgMCwgcnNhLmdldFRvdGFsRmFpbHVyZXNOdW1iZXIoKSk7CisgICAgfQorCisgICAgLy8gTm90IHN1cHBvcnRlZCBieSBBbmRyb2lkCisgICAgcHVibGljIHZvaWQgZGlzYWJsZWRfdGVzdF9SU0FYWFhMS2V5KCkgeworICAgICAgICBDaXBoZXJSU0FUaHJlYWQgcnNhID0gbmV3IENpcGhlclJTQVRocmVhZCgiUlNBIiwgbmV3IGludFtdIHsyMDQ4fSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geyJFQ0IifSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geyJPQUVQV0lUSFNIQS01MTJBTkRNR0YxUEFERElORyJ9KTsKKworICAgICAgICByc2EubGF1bmNoZXIoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMocnNhLmdldEZhaWx1cmVNZXNzYWdlcygpLCAwLCByc2EuZ2V0VG90YWxGYWlsdXJlc051bWJlcigpKTsKKyAgICB9CisKKyAgICBAQW5kcm9pZE9ubHkoIkZhaWxzIG9uIFJJIGJ1dCBzdWNjZWVkcyBvbiBBbmRyb2lkLiIpCisgICAgcHVibGljIHZvaWQgdGVzdF9SU0FOb1BhZGRpbmcoKSB7CisgICAgICAgIENpcGhlclJTQVRocmVhZCByc2EgPSBuZXcgQ2lwaGVyUlNBVGhyZWFkKCJSU0EiLCBuZXcgaW50W10gezEwMjR9LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7IkVDQiJ9LCBuZXcgU3RyaW5nW10geyJOT1BBRERJTkcifSk7CisKKyAgICAgICAgcnNhLmxhdW5jaGVyKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJzYS5nZXRGYWlsdXJlTWVzc2FnZXMoKSwgMCwgcnNhLmdldFRvdGFsRmFpbHVyZXNOdW1iZXIoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvQ2lwaGVyUlNBVGhyZWFkLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9DaXBoZXJSU0FUaHJlYWQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNzQ0NWIxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvQ2lwaGVyUlNBVGhyZWFkLmphdmEKQEAgLTAsMCArMSw1MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvLmZ1bmM7CisKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXJHZW5lcmF0b3I7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uQ2lwaGVyOworCitwdWJsaWMgY2xhc3MgQ2lwaGVyUlNBVGhyZWFkIGV4dGVuZHMgQ2lwaGVyVGhyZWFkIHsKKworICAgIENpcGhlclJTQVRocmVhZChTdHJpbmcgbmFtZSwgaW50W10ga2V5cywgU3RyaW5nW10gbW9kZXMsIFN0cmluZ1tdIHBhZGRpbmdzKSB7CisgICAgICAgIHN1cGVyKG5hbWUsIGtleXMsIG1vZGVzLCBwYWRkaW5ncyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY3J5cHQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIG91dHB1dCA9IG5ldyBieXRlWzI1Nl07CisgICAgICAgIGJ5dGVbXSBkZWNyeXB0ZWQgPSBuZXcgYnl0ZVsyNTZdOworICAgICAgICBpbnQgZGF0YUJsb2NrID0gMjA7CisgICAgICAgIGJ5dGVbXSBpbnB1dCAgPSAgZ2V0RGF0YSgpLnN1YnN0cmluZygwLCBkYXRhQmxvY2spLmdldEJ5dGVzKCk7CisgICAgICAgIEtleVBhaXJHZW5lcmF0b3Iga3BnID0gS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZSgiUlNBIik7CisgICAgICAgIGtwZy5pbml0aWFsaXplKGdldEtleUxlbmd0aCgpKTsKKyAgICAgICAgS2V5UGFpciBrcCA9IGtwZy5nZW5lcmF0ZUtleVBhaXIoKTsKKworICAgICAgICBDaXBoZXIgY2lwID0gQ2lwaGVyLmdldEluc3RhbmNlKGdldEFsZ05hbWUoKSArICIvIiArIGdldE1vZGUoKSArICIvIiArCisgICAgICAgICAgICAgICAgZ2V0UGFkZGluZygpKTsKKyAgICAgICAgY2lwLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwga3AuZ2V0UHVibGljKCkpOworICAgICAgICBjaXAuZG9GaW5hbChpbnB1dCwgMCwgaW5wdXQubGVuZ3RoLCBvdXRwdXQpOworICAgICAgICBpbnQgb3V0cHV0U2l6ZSA9IGNpcC5nZXRPdXRwdXRTaXplKGlucHV0Lmxlbmd0aCk7CisgICAgICAgIGNpcC5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGtwLmdldFByaXZhdGUoKSk7CisgICAgICAgIGNpcC5kb0ZpbmFsKG91dHB1dCwgMCwgb3V0cHV0U2l6ZSwgZGVjcnlwdGVkKTsKKworICAgICAgICBjaGVja0VuY29kZWREYXRhKGlucHV0LCBkZWNyeXB0ZWQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL0NpcGhlclN5bW1ldHJpY0tleVRocmVhZC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvQ2lwaGVyU3ltbWV0cmljS2V5VGhyZWFkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjNmYWFkYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL0NpcGhlclN5bW1ldHJpY0tleVRocmVhZC5qYXZhCkBAIC0wLDAgKzEsNzMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0by5mdW5jOworCisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKKworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXI7CitpbXBvcnQgamF2YXguY3J5cHRvLktleUdlbmVyYXRvcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5JdlBhcmFtZXRlclNwZWM7CisKK3B1YmxpYyBjbGFzcyBDaXBoZXJTeW1tZXRyaWNLZXlUaHJlYWQgZXh0ZW5kcyBDaXBoZXJUaHJlYWQgeworICAgIENpcGhlclN5bW1ldHJpY0tleVRocmVhZChTdHJpbmcgbmFtZSwgaW50W10ga2V5cywgU3RyaW5nW10gbW9kZXMsIFN0cmluZ1tdIHBhZGRpbmdzKSB7CisgICAgICAgIHN1cGVyKG5hbWUsIGtleXMsIG1vZGVzLCBwYWRkaW5ncyk7CisgICAgfQorCisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjcnlwdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gb3V0cHV0ID0gbmV3IGJ5dGVbMTI4XTsKKyAgICAgICAgYnl0ZVtdIGRlY3J5cHRlZCA9IG5ldyBieXRlWzEyOF07CisgICAgICAgIGJ5dGVbXSBpbnB1dCAgPSAgZ2V0RGF0YSgpLmdldEJ5dGVzKCk7CisgICAgICAgIFNlY3VyZVJhbmRvbSBzciA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgYnl0ZVtdIGl2ID0gbnVsbDsvL25ldyBieXRlWzE2XTsKKyAgICAgICAgaW50IG91dHB1dFNpemUgPSAwOworCisgICAgICAgIEtleUdlbmVyYXRvciBrZyA9IEtleUdlbmVyYXRvci5nZXRJbnN0YW5jZShnZXRBbGdOYW1lKCkpOworICAgICAgICBrZy5pbml0KGdldEtleUxlbmd0aCgpLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICBLZXkga2V5ID0ga2cuZ2VuZXJhdGVLZXkoKTsKKworICAgICAgICBDaXBoZXIgY2lwID0gQ2lwaGVyLmdldEluc3RhbmNlKGdldEFsZ05hbWUoKSArICIvIiArIGdldE1vZGUoKSArICIvIiArCisgICAgICAgICAgICAgICAgICAgIGdldFBhZGRpbmcoKSk7CisgICAgICAgIGlmIChnZXRBbGdOYW1lKCkgIT0gIkFFUyIpIHsKKyAgICAgICAgICAgIGl2ID0gbmV3IGJ5dGVbOF07CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBpdiA9IG5ldyBieXRlWzE2XTsKKyAgICAgICAgfQorICAgICAgICBzci5uZXh0Qnl0ZXMoaXYpOworICAgICAgICBJdlBhcmFtZXRlclNwZWMgaXZzcGVjID0gbmV3IEl2UGFyYW1ldGVyU3BlYyhpdik7CisgICAgICAgIGlmIChnZXRNb2RlKCkgIT0gIkVDQiIpIHsKKyAgICAgICAgICAgIGNpcC5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGtleSwgaXZzcGVjKTsKKyAgICAgICAgICAgIGNpcC5kb0ZpbmFsKGlucHV0LCAwLCBpbnB1dC5sZW5ndGgsIG91dHB1dCk7CisgICAgICAgICAgICBvdXRwdXRTaXplID0gY2lwLmdldE91dHB1dFNpemUoaW5wdXQubGVuZ3RoKTsKKyAgICAgICAgICAgIGl2ID0gY2lwLmdldElWKCk7CisgICAgICAgICAgICBpdnNwZWMgPSBuZXcgSXZQYXJhbWV0ZXJTcGVjKGl2KTsKKyAgICAgICAgICAgIGNpcC5pbml0KENpcGhlci5ERUNSWVBUX01PREUsIGtleSwgaXZzcGVjKTsKKyAgICAgICAgICAgIGNpcC5kb0ZpbmFsKG91dHB1dCwgMCwgb3V0cHV0U2l6ZSwgZGVjcnlwdGVkKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNpcC5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGtleSk7CisgICAgICAgICAgICBjaXAuZG9GaW5hbChpbnB1dCwgMCwgaW5wdXQubGVuZ3RoLCBvdXRwdXQpOworICAgICAgICAgICAgb3V0cHV0U2l6ZSA9IGNpcC5nZXRPdXRwdXRTaXplKGlucHV0Lmxlbmd0aCk7CisgICAgICAgICAgICBjaXAuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLCBrZXkpOworICAgICAgICAgICAgY2lwLmRvRmluYWwob3V0cHV0LCAwLCBvdXRwdXRTaXplLCBkZWNyeXB0ZWQpOworICAgICAgICB9CisKKyAgICAgICAgY2hlY2tFbmNvZGVkRGF0YShnZXREYXRhKCkuZ2V0Qnl0ZXMoKSwgZGVjcnlwdGVkKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9DaXBoZXJUaHJlYWQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL0NpcGhlclRocmVhZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRkYWMxNzYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9DaXBoZXJUaHJlYWQuamF2YQpAQCAtMCwwICsxLDE3NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvLmZ1bmM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uQ2lwaGVyOworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ2lwaGVyVGhyZWFkIGltcGxlbWVudHMgUnVubmFibGUgeworICAgIHByaXZhdGUgaW50W10ga2V5TGVuZ3RoQXIgPSBudWxsOworICAgIHByaXZhdGUgU3RyaW5nW10gbW9kZUFyID0gbnVsbDsKKyAgICBwcml2YXRlIFN0cmluZ1tdIHBhZGRpbmdNb2RlQXIgPSBudWxsOworICAgIHByaXZhdGUgaW50IGtDb3VudGVyID0gMDsKKyAgICBwcml2YXRlIGludCBtQ291bnRlciA9IDA7CisgICAgcHJpdmF0ZSBpbnQgcENvdW50ZXIgPSAwOworICAgIHByaXZhdGUgU3RyaW5nQnVmZmVyIGVycm9yU0IgPSBudWxsOworCisgICAgcHJpdmF0ZSBib29sZWFuIGZsYWdUZXN0UmVzdWx0ID0gZmFsc2U7CisgICAgcHJpdmF0ZSBTdHJpbmcgZGF0YSA9ICIgICAgQWxiZXJ0IEVpbnN0ZWluIHdhcyBhIEdlcm1hbi1ib3JuICIgKworICAgICAgICAgICAgICAgICJ0aGVvcmV0aWNhbCBwaHlzaWNpc3QuICAgICI7CisgICAgcHJpdmF0ZSBTdHJpbmcgYWxnTmFtZSA9IG51bGw7CisgICAgcHJpdmF0ZSBpbnQga2V5TGVuZ3RoID0gMDsKKyAgICBwcml2YXRlIFN0cmluZyBtb2RlID0gbnVsbDsKKyAgICBwcml2YXRlIFN0cmluZyBwYWRkaW5nTW9kZSA9IG51bGw7CisgICAgcHJpdmF0ZSBpbnQgZmFpbHMgPSAwOworCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgY3J5cHQoKSB0aHJvd3MgRXhjZXB0aW9uOworCisgICAgQ2lwaGVyVGhyZWFkKFN0cmluZyBuYW1lLCBpbnRbXSBrZXlzLCBTdHJpbmdbXSBtb2RlcywgU3RyaW5nW10gcGFkZGluZ3MpIHsKKyAgICAgICAgYWxnTmFtZSAgICAgPSBuYW1lOworICAgICAgICBrZXlMZW5ndGhBciAgID0ga2V5czsKKyAgICAgICAgbW9kZUFyICAgICAgICA9IG1vZGVzOworICAgICAgICBwYWRkaW5nTW9kZUFyID0gcGFkZGluZ3M7CisgICAgICAgIGtDb3VudGVyID0gMDsKKyAgICAgICAgbUNvdW50ZXIgPSAwOworICAgICAgICBwQ291bnRlciA9IDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY2hlY2tFbmNvZGVkRGF0YShieXRlW10gb3JpZ2luYWwsIGJ5dGVbXSBlbmNvZGVkKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBvcmlnaW5hbC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKG9yaWdpbmFsW2ldICE9IGVuY29kZWRbaV0pIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJTb3VyY2UgYW5kIGVuY29kZWQgZGF0YSBub3QgbWF0Y2ggIiArCisgICAgICAgICAgICAgICAgICAgICAgICBnZXRDaXBoZXJQYXJhbWV0ZXJzKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgbGF1bmNoZXIoKSB7CisgICAgICAgIFRocmVhZCB0aHJlYWQgPSBudWxsOworCisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGtleUxlbmd0aCA9IGdldE5leHRLZXkoKTsKKyAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICBtb2RlID0gZ2V0TmV4dE1vZGUoKTsKKyAgICAgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgICAgIHBhZGRpbmdNb2RlID0gZ2V0TmV4dFBhZGRpbmcoKTsKKyAgICAgICAgICAgICAgICAgICAgdGhyZWFkID0gbmV3IFRocmVhZCh0aGlzKTsKKyAgICAgICAgICAgICAgICAgICAgdGhyZWFkLnN0YXJ0KCk7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJlYWQuam9pbigpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSB3aGlsZSAoaGFzTmV4dFBhZGRpbmcoKSk7CisgICAgICAgICAgICB9IHdoaWxlIChoYXNOZXh0TW9kZSgpKTsKKyAgICAgICAgfSB3aGlsZSAoaGFzTmV4dEtleSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjcnlwdCgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaWYoZXJyb3JTQiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgZXJyb3JTQiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVycm9yU0IuYXBwZW5kKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIGVycm9yU0IuYXBwZW5kKCJcbiIpOworICAgICAgICAgICAgZXJyb3JTQi5hcHBlbmQoZ2V0Q2lwaGVyUGFyYW1ldGVycygpKTsKKyAgICAgICAgICAgIGVycm9yU0IuYXBwZW5kKCJcbiIpOworICAgICAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnRbXSBzdCA9IGUuZ2V0U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGVycm9yU0IuYXBwZW5kKHN0W2ldLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIGVycm9yU0IuYXBwZW5kKCJcbiIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmFpbHMrKzsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmbGFnVGVzdFJlc3VsdCA9IHRydWU7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRBbGdOYW1lKCkgeworICAgICAgICByZXR1cm4gYWxnTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldEtleUxlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIGtleUxlbmd0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldERhdGEoKSB7CisgICAgICAgIHJldHVybiBkYXRhOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGFkZGluZygpIHsKKyAgICAgICAgcmV0dXJuIHBhZGRpbmdNb2RlOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TW9kZSgpIHsKKyAgICAgICAgcmV0dXJuIG1vZGU7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRDaXBoZXJQYXJhbWV0ZXJzKCkgeworICAgICAgICByZXR1cm4gIkFsZyBuYW1lOiIgKyBhbGdOYW1lICsgIiBLZXk6IiArIGtleUxlbmd0aCArICIgTW9kZToiICsgbW9kZSArCisgICAgICAgICIgUGFkZGluZzoiICsgcGFkZGluZ01vZGU7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZ2V0VGVzdFN0YXR1cygpIHsKKyAgICAgICAgcmV0dXJuIGZsYWdUZXN0UmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnb3JpdGhtTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIGFsZ05hbWU7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dEtleSgpIHsKKyAgICAgICAgcmV0dXJuIChrQ291bnRlciA8IGtleUxlbmd0aEFyLmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dE1vZGUoKSB7CisgICAgICAgIHJldHVybiAobUNvdW50ZXIgPCBtb2RlQXIubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0UGFkZGluZygpIHsKKyAgICAgICAgcmV0dXJuIChwQ291bnRlciA8IHBhZGRpbmdNb2RlQXIubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldE5leHRLZXkoKSB7CisgICAgICAgIGtDb3VudGVyID0gKGhhc05leHRLZXkoKSkgPyBrQ291bnRlciA6IDA7CisgICAgICAgIHJldHVybiBrZXlMZW5ndGhBcltrQ291bnRlcisrXTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5leHRNb2RlKCkgeworICAgICAgICBtQ291bnRlciA9IChoYXNOZXh0TW9kZSgpKSA/IG1Db3VudGVyIDogMDsKKyAgICAgICAgcmV0dXJuIG1vZGVBclttQ291bnRlcisrXTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5leHRQYWRkaW5nKCkgeworICAgICAgICBwQ291bnRlciA9IChoYXNOZXh0UGFkZGluZygpKSA/IHBDb3VudGVyIDogMDsKKyAgICAgICAgcmV0dXJuIHBhZGRpbmdNb2RlQXJbcENvdW50ZXIrK107CisgICAgfQorCisgICAgcHVibGljIGxvbmcgZ2V0VG90YWxDYXNlc051bWJlcigpIHsKKyAgICAgICAgcmV0dXJuIGtleUxlbmd0aEFyLmxlbmd0aCAqIG1vZGVBci5sZW5ndGggKiBwYWRkaW5nTW9kZUFyLmxlbmd0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBnZXRUb3RhbEZhaWx1cmVzTnVtYmVyKCkgeworICAgICAgICByZXR1cm4gZmFpbHM7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRGYWlsdXJlTWVzc2FnZXMoKSB7CisgICAgICAgIHJldHVybiAoZXJyb3JTQiA9PSBudWxsKSA/ICIiIDogbmV3IFN0cmluZyhlcnJvclNCKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9DaXBoZXJXcmFwVGhyZWFkLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9DaXBoZXJXcmFwVGhyZWFkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjBlYWJlMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL0NpcGhlcldyYXBUaHJlYWQuamF2YQpAQCAtMCwwICsxLDQ3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uZnVuYzsKKworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uQ2lwaGVyOworaW1wb3J0IGphdmF4LmNyeXB0by5LZXlHZW5lcmF0b3I7CisKK3B1YmxpYyBjbGFzcyBDaXBoZXJXcmFwVGhyZWFkIGV4dGVuZHMgQ2lwaGVyVGhyZWFkIHsKKyAgICBDaXBoZXJXcmFwVGhyZWFkKFN0cmluZyBuYW1lLCBpbnRbXSBrZXlzLCBTdHJpbmdbXSBtb2RlcywgU3RyaW5nW10gcGFkZGluZ3MpIHsKKyAgICAgICAgc3VwZXIobmFtZSwga2V5cywgbW9kZXMsIHBhZGRpbmdzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjcnlwdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBLZXlHZW5lcmF0b3Iga2cgPSBLZXlHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoZ2V0QWxnTmFtZSgpLnJlcGxhY2UoIldyYXAiLCAiIikpOworICAgICAgICBrZy5pbml0KGdldEtleUxlbmd0aCgpLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICBLZXkga2V5ID0ga2cuZ2VuZXJhdGVLZXkoKTsKKworICAgICAgICAvLyBpZ25vcmUgbW9kZSBhbmQgcGFkZGluZworICAgICAgICBDaXBoZXIgY2lwID0gQ2lwaGVyLmdldEluc3RhbmNlKGdldEFsZ05hbWUoKSk7CisKKyAgICAgICAgY2lwLmluaXQoQ2lwaGVyLldSQVBfTU9ERSwga2V5KTsKKyAgICAgICAgYnl0ZVtdIG91dHB1dCA9IGNpcC53cmFwKGtleSk7CisgICAgICAgIGNpcC5pbml0KENpcGhlci5VTldSQVBfTU9ERSwga2V5KTsKKyAgICAgICAgS2V5IGRlY3J5cHRlZCA9IGNpcC51bndyYXAob3V0cHV0LCBnZXRBbGdOYW1lKCksIENpcGhlci5TRUNSRVRfS0VZKTsKKworICAgICAgICBjaGVja0VuY29kZWREYXRhKGtleS5nZXRGb3JtYXQoKS5nZXRCeXRlcygpLCBkZWNyeXB0ZWQuZ2V0Rm9ybWF0KCkuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIGNoZWNrRW5jb2RlZERhdGEoa2V5LmdldEVuY29kZWQoKSwgZGVjcnlwdGVkLmdldEVuY29kZWQoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvS2V5QWdyZWVtZW50RnVuY3Rpb25hbFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL0tleUFncmVlbWVudEZ1bmN0aW9uYWxUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWNiMDZhZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL0tleUFncmVlbWVudEZ1bmN0aW9uYWxUZXN0LmphdmEKQEAgLTAsMCArMSwzMiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvLmZ1bmM7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5Ccm9rZW5UZXN0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgS2V5QWdyZWVtZW50RnVuY3Rpb25hbFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgQEJyb2tlblRlc3QoIlRvbyBzbG93IC0gZGlzYWJsaW5nIGZvciBub3ciKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfS2V5QWdyZWVtZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIGFsZ0FycmF5ID0geyJERVMiLCAiREVTZWRlIn07CisKKyAgICAgICAgS2V5QWdyZWVtZW50VGhyZWFkIGthdCA9IG5ldyBLZXlBZ3JlZW1lbnRUaHJlYWQoYWxnQXJyYXkpOworICAgICAgICBrYXQubGF1bmNoZXIoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoa2F0LmdldEZhaWx1cmVNZXNzYWdlcygpLCAwLCBrYXQuZ2V0VG90YWxGYWlsdXJlc051bWJlcigpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9LZXlBZ3JlZW1lbnRUaHJlYWQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL0tleUFncmVlbWVudFRocmVhZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ4MGVhN2YKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9LZXlBZ3JlZW1lbnRUaHJlYWQuamF2YQpAQCAtMCwwICsxLDg3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uZnVuYzsKKworaW1wb3J0IGNvbS5hbmRyb2lkLm9yZy5ib3VuY3ljYXN0bGUudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5RmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuWDUwOUVuY29kZWRLZXlTcGVjOworaW1wb3J0IGphdmF4LmNyeXB0by5LZXlBZ3JlZW1lbnQ7CitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuREhQYXJhbWV0ZXJTcGVjOworCitwdWJsaWMgY2xhc3MgS2V5QWdyZWVtZW50VGhyZWFkIGV4dGVuZHMgVGVzdFRocmVhZCB7CisgICAgY2xhc3MgS2V5QWdyZWVtZW50R2VuIHsKKyAgICAgICAgcHJpdmF0ZSBQcml2YXRlS2V5IHByaXZhdGVLZXkgPSBudWxsOworICAgICAgICBwcml2YXRlIGJ5dGVbXSBwdWJsaWNLZXlCeXRlcyA9IG51bGw7CisKKyAgICAgICAgS2V5QWdyZWVtZW50R2VuKERIUGFyYW1ldGVyU3BlYyBwYXJhbWV0ZXJTcGVjKQorICAgICAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgS2V5UGFpckdlbmVyYXRvciBrZXlHZW4gPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKCJESCIpOworICAgICAgICAgICAga2V5R2VuLmluaXRpYWxpemUocGFyYW1ldGVyU3BlYyk7CisgICAgICAgICAgICBLZXlQYWlyIGtleXBhaXIgPSBrZXlHZW4uZ2VuZXJhdGVLZXlQYWlyKCk7CisKKyAgICAgICAgICAgIHByaXZhdGVLZXkgICAgID0ga2V5cGFpci5nZXRQcml2YXRlKCk7CisgICAgICAgICAgICBwdWJsaWNLZXlCeXRlcyA9IGtleXBhaXIuZ2V0UHVibGljKCkuZ2V0RW5jb2RlZCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRQdWJsaWNLZXlCeXRlcyAoKSB7CisgICAgICAgICAgICByZXR1cm4gcHVibGljS2V5Qnl0ZXM7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldFNlY3JldEtleShTdHJpbmcgYWxnLCBieXRlW10gcHVibGljS2V5KSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIFg1MDlFbmNvZGVkS2V5U3BlYyB4NTA5S2V5U3BlYyA9IG5ldyBYNTA5RW5jb2RlZEtleVNwZWMocHVibGljS2V5KTsKKyAgICAgICAgICAgIEtleUZhY3Rvcnkga2V5RmFjdCA9IEtleUZhY3RvcnkuZ2V0SW5zdGFuY2UoIkRIIik7CisgICAgICAgICAgICBQdWJsaWNLZXkgcHViS2V5ID0ga2V5RmFjdC5nZW5lcmF0ZVB1YmxpYyh4NTA5S2V5U3BlYyk7CisKKyAgICAgICAgICAgIEtleUFncmVlbWVudCBrYSA9IEtleUFncmVlbWVudC5nZXRJbnN0YW5jZSgiREgiKTsKKyAgICAgICAgICAgIGthLmluaXQocHJpdmF0ZUtleSk7CisgICAgICAgICAgICBrYS5kb1BoYXNlKHB1YktleSwgdHJ1ZSk7CisKKyAgICAgICAgICAgIHJldHVybiBrYS5nZW5lcmF0ZVNlY3JldCgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIEtleUFncmVlbWVudFRocmVhZChTdHJpbmdbXSBuYW1lcykgeworICAgICAgICBzdXBlcihuYW1lcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgdGVzdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IgYXBnID0gQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yLmdldEluc3RhbmNlKCJESCIpOworICAgICAgICBhcGcuaW5pdCgxMDI0LCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIGFwID0gYXBnLmdlbmVyYXRlUGFyYW1ldGVycygpOworICAgICAgICBESFBhcmFtZXRlclNwZWMgcHMgPSBhcC5nZXRQYXJhbWV0ZXJTcGVjKERIUGFyYW1ldGVyU3BlYy5jbGFzcyk7CisKKyAgICAgICAgS2V5QWdyZWVtZW50R2VuIGthZzEgPSBuZXcgS2V5QWdyZWVtZW50R2VuKHBzKTsKKyAgICAgICAgS2V5QWdyZWVtZW50R2VuIGthZzIgPSBuZXcgS2V5QWdyZWVtZW50R2VuKHBzKTsKKworICAgICAgICBieXRlW10gYkFycmF5MSA9IGthZzEuZ2V0UHVibGljS2V5Qnl0ZXMoKTsKKyAgICAgICAgYnl0ZVtdIGJBcnJheTIgPSBrYWcyLmdldFB1YmxpY0tleUJ5dGVzKCk7CisKKyAgICAgICAgYnl0ZVtdIHNrMSA9IGthZzEuZ2V0U2VjcmV0S2V5KGFsZ05hbWUsIGJBcnJheTIpOworICAgICAgICBieXRlW10gc2syID0ga2FnMi5nZXRTZWNyZXRLZXkoYWxnTmFtZSwgYkFycmF5MSk7CisKKyAgICAgICAgaWYgKEFycmF5cy5hcmVFcXVhbChzazEsIHNrMikgPT0gZmFsc2UpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24gKCJHZW5lcmF0ZWQga2V5cyBhcmUgbm90IHRoZSBzYW1lIik7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9LZXlHZW5lcmF0b3JGdW5jdGlvbmFsVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvS2V5R2VuZXJhdG9yRnVuY3Rpb25hbFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZTlhMTk4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvS2V5R2VuZXJhdG9yRnVuY3Rpb25hbFRlc3QuamF2YQpAQCAtMCwwICsxLDMyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uZnVuYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIEtleUdlbmVyYXRvckZ1bmN0aW9uYWxUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RfKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIGFsZ0FycmF5ID0geyJBRVMiLCAiREVTIiwgIkRFU0VERSIsICJERVNlZGUiLAorICAgICAgICAgICAgICAgICJITUFDTUQ1IiwgIkhtYWNNRDUiLCAiSE1BQ1NIQTEiLCAiSG1hY1NIQTEiLCAiSE1BQ1NIQTI1NiIsCisgICAgICAgICAgICAgICAgIkhtYWNTSEEyNTYiLCAiSE1BQ1NIQTM4NCIsICJIbWFjU0hBMzg0IiwgIkhNQUNTSEE1MTIiLAorICAgICAgICAgICAgICAgICJIbWFjU0hBNTEyIn07CisKKyAgICAgICAgS2V5R2VuZXJhdG9yVGhyZWFkIGtndCA9IG5ldyBLZXlHZW5lcmF0b3JUaHJlYWQoYWxnQXJyYXkpOworICAgICAgICBrZ3QubGF1bmNoZXIoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoa2d0LmdldEZhaWx1cmVNZXNzYWdlcygpLCAwLCBrZ3QuZ2V0VG90YWxGYWlsdXJlc051bWJlcigpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9LZXlHZW5lcmF0b3JUaHJlYWQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL0tleUdlbmVyYXRvclRocmVhZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI4MDVkNWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vZnVuYy9LZXlHZW5lcmF0b3JUaHJlYWQuamF2YQpAQCAtMCwwICsxLDY4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uZnVuYzsKKworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uS2V5R2VuZXJhdG9yOworCitwdWJsaWMgY2xhc3MgS2V5R2VuZXJhdG9yVGhyZWFkIGV4dGVuZHMgVGVzdFRocmVhZCB7CisgICAgS2V5R2VuZXJhdG9yVGhyZWFkKFN0cmluZ1tdIG5hbWVzKSB7CisgICAgICAgIHN1cGVyKG5hbWVzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEtleUdlbmVyYXRvciBrZyA9IEtleUdlbmVyYXRvci5nZXRJbnN0YW5jZShhbGdOYW1lKTsKKyAgICAgICAgS2V5IGsgPSBrZy5nZW5lcmF0ZUtleSgpOworICAgICAgICBpZihrZy5nZXRBbGdvcml0aG0oKS50b0xvd2VyQ2FzZSgpLmVxdWFscyhrLmdldEFsZ29yaXRobSgpLnRvTG93ZXJDYXNlKCkpICE9IHRydWUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24gKCJBbGdvcml0aG0gbmFtZXMgbm90IG1hdGNoZWQgZm9yIEtleUdlbmVyYXRvciIgKworICAgICAgICAgICAgICAgICAgICAiIGFuZCBmb3IgS2V5IG9iamVjdHMiKTsKKyAgICAgICAgfQorICAgICAgICBpZihrZy5nZXRBbGdvcml0aG0oKS50b0xvd2VyQ2FzZSgpLmVxdWFscyhhbGdOYW1lLnRvTG93ZXJDYXNlKCkpICE9IHRydWUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24gKCJBbGdvcml0aG0gbmFtZXMgbm90IG1hdGNoZWQgZm9yIEtleUdlbmVyYXRvciIgKworICAgICAgICAgICAgIiBhbmQgZm9yIEtleSBvYmplY3RzIik7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIGFycmF5MSA9IGsuZ2V0RW5jb2RlZCgpOworICAgICAgICBrID0ga2cuZ2VuZXJhdGVLZXkoKTsKKyAgICAgICAgYnl0ZVtdIGFycmF5MiA9IGsuZ2V0RW5jb2RlZCgpOworICAgICAgICBpbnQgbWF0Y2hlcyA9IDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkxLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYXJyYXkxW2ldID09IGFycmF5MltpXSkgeworICAgICAgICAgICAgICAgIG1hdGNoZXMrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAobWF0Y2hlcyA+IGFycmF5MS5sZW5ndGggLyAyKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJHZW5lcmF0ZWQga2V5cyBhcmUgc2ltdWxhciIpOworICAgICAgICB9CisgICAgICAgIFNlY3VyZVJhbmRvbSByYW5kb20gPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIGtnLmluaXQocmFuZG9tKTsKKyAgICAgICAgbWF0Y2hlcyA9IDA7CisgICAgICAgIGsgPSBrZy5nZW5lcmF0ZUtleSgpOworICAgICAgICBhcnJheTEgPSBrLmdldEVuY29kZWQoKTsKKyAgICAgICAgcmFuZG9tID0gbmV3IFNlY3VyZVJhbmRvbSgpOworICAgICAgICBrZy5pbml0KHJhbmRvbSk7CisgICAgICAgIGsgPSBrZy5nZW5lcmF0ZUtleSgpOworICAgICAgICBhcnJheTIgPSBrLmdldEVuY29kZWQoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheTEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChhcnJheTFbaV0gPT0gYXJyYXkyW2ldKSB7CisgICAgICAgICAgICAgICAgbWF0Y2hlcysrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvTWFjRnVuY3Rpb25hbFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL01hY0Z1bmN0aW9uYWxUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGMwNTExMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL01hY0Z1bmN0aW9uYWxUZXN0LmphdmEKQEAgLTAsMCArMSwzMCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvLmZ1bmM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBNYWNGdW5jdGlvbmFsVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X01hYygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmdbXSBhbGdBcnJheSA9IHsiSE1BQ1NIQTEiLCAiSE1BQ1NIQTI1NiIsICJITUFDU0hBMzg0IiwKKyAgICAgICAgICAgICAgICAiSE1BQ1NIQTUxMiIsICJITUFDTUQ1In07CisKKyAgICAgICAgTWFjVGhyZWFkIG10ID0gbmV3IE1hY1RocmVhZChhbGdBcnJheSk7CisgICAgICAgIG10LmxhdW5jaGVyKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG10LmdldEZhaWx1cmVNZXNzYWdlcygpLCAwLCBtdC5nZXRUb3RhbEZhaWx1cmVzTnVtYmVyKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL01hY1RocmVhZC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvTWFjVGhyZWFkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2Y4ZWMwOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL01hY1RocmVhZC5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0by5mdW5jOworCitpbXBvcnQgamF2YXguY3J5cHRvLk1hYzsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5TZWNyZXRLZXlTcGVjOworCitwdWJsaWMgY2xhc3MgTWFjVGhyZWFkIGV4dGVuZHMgVGVzdFRocmVhZCB7CisgICAgTWFjVGhyZWFkKFN0cmluZ1tdIG5hbWVzKSB7CisgICAgICAgIHN1cGVyKG5hbWVzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB0ZXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBzaXplID0gMjU2OworICAgICAgICBieXRlW10gc3JjMSA9IG5ldyBieXRlW3NpemVdOworICAgICAgICBieXRlW10gc3JjMiA9IG5ldyBieXRlW3NpemVdOworICAgICAgICBieXRlW10gc3JjMyA9IG5ldyBieXRlW3NpemVdOworICAgICAgICBpbnQgaTsKKworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgICAgICAgICBzcmMxW2ldID0gKGJ5dGUpaTsKKyAgICAgICAgICAgIHNyYzJbaV0gPSAoYnl0ZSlpOworICAgICAgICAgICAgc3JjM1tpXSA9IChieXRlKShzaXplIC0gaSAtIDEpOworICAgICAgICB9CisgICAgICAgIE1hYyBtID0gTWFjLmdldEluc3RhbmNlKGFsZ05hbWUpOworICAgICAgICBieXRlW10gYiA9IHsoYnl0ZSkwLCAoYnl0ZSkwLCAoYnl0ZSkwLCAoYnl0ZSkwLCAoYnl0ZSkwfTsKKyAgICAgICAgU2VjcmV0S2V5U3BlYyBza3MgPSBuZXcgU2VjcmV0S2V5U3BlYyhiLCAiU0hBMSIpOworICAgICAgICBtLmluaXQoc2tzKTsKKworICAgICAgICBieXRlW10gcmVzID0gbS5kb0ZpbmFsKHNyYzEpOworICAgICAgICBTdHJpbmcgc2lnbjEgPSBuZXcgU3RyaW5nKHJlcyk7CisgICAgICAgIG0uaW5pdChza3MpOworICAgICAgICByZXMgPSBtLmRvRmluYWwoc3JjMik7CisgICAgICAgIFN0cmluZyBzaWduMiA9IG5ldyBTdHJpbmcocmVzKTsKKyAgICAgICAgbS5pbml0KHNrcyk7CisgICAgICAgIHJlcyA9IG0uZG9GaW5hbChzcmMzKTsKKyAgICAgICAgU3RyaW5nIHNpZ24zID0gbmV3IFN0cmluZyhyZXMpOworICAgICAgICBpZiAoc2lnbjEuY29tcGFyZVRvKHNpZ24yKSAhPSAwIHx8IHNpZ24xLmNvbXBhcmVUbyhzaWduMykgPT0gMCB8fAorICAgICAgICAgICAgICAgIHNpZ24yLmNvbXBhcmVUbyhzaWduMykgPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbiAoIlNpZ25hdHVyZSBpcyBub3QgY29ycmVjdCBmb3IgYWxnb3JpdGhtICIgKyBhbGdOYW1lKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL1NlY3JldEtleUZhY3RvcnlGdW5jdGlvbmFsVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvU2VjcmV0S2V5RmFjdG9yeUZ1bmN0aW9uYWxUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGMyZTJhZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL1NlY3JldEtleUZhY3RvcnlGdW5jdGlvbmFsVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0by5mdW5jOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgU2VjcmV0S2V5RmFjdG9yeUZ1bmN0aW9uYWxUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RfKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIGFsZ0FycmF5ID0geyJERVMiLCAiREVTZWRlIiwgIlBCRVdJVEhNRDVBTkRERVMifTsKKworICAgICAgICBTZWNyZXRLZXlGYWN0b3J5VGhyZWFkIHNrZnQgPSBuZXcgU2VjcmV0S2V5RmFjdG9yeVRocmVhZChhbGdBcnJheSk7CisgICAgICAgIHNrZnQubGF1bmNoZXIoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoc2tmdC5nZXRGYWlsdXJlTWVzc2FnZXMoKSwgMCwgc2tmdC5nZXRUb3RhbEZhaWx1cmVzTnVtYmVyKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL1NlY3JldEtleUZhY3RvcnlUaHJlYWQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL1NlY3JldEtleUZhY3RvcnlUaHJlYWQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNDI2OTM5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvU2VjcmV0S2V5RmFjdG9yeVRocmVhZC5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0by5mdW5jOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLktleVNwZWM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2VjcmV0S2V5RmFjdG9yeTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5ERVNLZXlTcGVjOworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLkRFU2VkZUtleVNwZWM7CitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuUEJFS2V5U3BlYzsKKworcHVibGljIGNsYXNzIFNlY3JldEtleUZhY3RvcnlUaHJlYWQgZXh0ZW5kcyBUZXN0VGhyZWFkIHsKKyAgICBTZWNyZXRLZXlGYWN0b3J5VGhyZWFkKFN0cmluZ1tdIG5hbWVzKSB7CisgICAgICAgIHN1cGVyKG5hbWVzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB0ZXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNlY3JldEtleUZhY3Rvcnkgc2tmID0gU2VjcmV0S2V5RmFjdG9yeS5nZXRJbnN0YW5jZShhbGdOYW1lKTsKKyAgICAgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVsyNF07CisgICAgICAgIEtleVNwZWMga3MgPSAoS2V5U3BlYykgKChhbGdOYW1lID09ICJERVMiKSA/IG5ldyBERVNLZXlTcGVjKGIpIDoKKyAgICAgICAgICAgIChhbGdOYW1lID09ICJERVNlZGUiKSA/IG5ldyBERVNlZGVLZXlTcGVjKGIpIDoKKyAgICAgICAgICAgIG5ldyBQQkVLZXlTcGVjKCJwYXNzdyIudG9DaGFyQXJyYXkoKSkpOworICAgICAgICBza2YuZ2VuZXJhdGVTZWNyZXQoa3MpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL1Rlc3RUaHJlYWQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9mdW5jL1Rlc3RUaHJlYWQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MjU4NDE1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2Z1bmMvVGVzdFRocmVhZC5qYXZhCkBAIC0wLDAgKzEsOTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0by5mdW5jOworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgVGVzdFRocmVhZCBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKyAgICBwdWJsaWMgU3RyaW5nW10gYWxnTmFtZXNBcnJheSA9IG51bGw7CisgICAgcHVibGljIGludCBhQ291bnRlciA9IDA7CisgICAgcHVibGljIFN0cmluZyBhbGdOYW1lID0gbnVsbDsKKyAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGVycm9yU0IgPSBudWxsOworICAgIHB1YmxpYyBpbnQgZmFpbHMgPSAwOworICAgIHB1YmxpYyBib29sZWFuIGZsYWdUZXN0UmVzdWx0ID0gZmFsc2U7CisKKyAgICBUZXN0VGhyZWFkKFN0cmluZ1tdIG5hbWVzKSB7CisgICAgICAgIGFsZ05hbWVzQXJyYXkgPSBuYW1lczsKKyAgICAgICAgYUNvdW50ZXIgPSAwOworICAgIH0KKworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHRlc3QoKSB0aHJvd3MgRXhjZXB0aW9uOworCisgICAgcHVibGljIHZvaWQgbGF1bmNoZXIoKSB7CisgICAgICAgIFRocmVhZCB0aHJlYWQgPSBudWxsOworCisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGFsZ05hbWUgPSBnZXROZXh0QWxnb3JpdGhtTmFtZSgpOworICAgICAgICAgICAgdGhyZWFkID0gbmV3IFRocmVhZCh0aGlzKTsKKyAgICAgICAgICAgIHRocmVhZC5zdGFydCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0aHJlYWQuam9pbigpOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gd2hpbGUgKGhhc0FsZ29yaXRobU5hbWUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdCgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaWYoZXJyb3JTQiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgZXJyb3JTQiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVycm9yU0IuYXBwZW5kKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIGVycm9yU0IuYXBwZW5kKCJcbiIpOworICAgICAgICAgICAgZXJyb3JTQi5hcHBlbmQoZ2V0QWxnb3JpdGhtTmFtZSgpKTsKKyAgICAgICAgICAgIGVycm9yU0IuYXBwZW5kKCJcbiIpOworICAgICAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnRbXSBzdCA9IGUuZ2V0U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGVycm9yU0IuYXBwZW5kKHN0W2ldLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIGVycm9yU0IuYXBwZW5kKCJcbiIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmFpbHMrKzsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmbGFnVGVzdFJlc3VsdCA9IHRydWU7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG1OYW1lKCkgeworICAgICAgICByZXR1cm4gYWxnTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNBbGdvcml0aG1OYW1lKCkgeworICAgICAgICByZXR1cm4gKGFDb3VudGVyIDwgYWxnTmFtZXNBcnJheS5sZW5ndGgpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmV4dEFsZ29yaXRobU5hbWUoKSB7CisgICAgICAgIGFDb3VudGVyID0gKGhhc0FsZ29yaXRobU5hbWUoKSkgPyBhQ291bnRlciA6IDA7CisgICAgICAgIHJldHVybiBhbGdOYW1lc0FycmF5W2FDb3VudGVyKytdOworICAgIH0KKworICAgIHB1YmxpYyBsb25nIGdldFRvdGFsRmFpbHVyZXNOdW1iZXIoKSB7CisgICAgICAgIHJldHVybiBmYWlsczsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEZhaWx1cmVNZXNzYWdlcygpIHsKKyAgICAgICAgcmV0dXJuIChlcnJvclNCID09IG51bGwpID8gIiIgOiBuZXcgU3RyaW5nKGVycm9yU0IpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9pbnRlcmZhY2VzL0RIUHJpdmF0ZUtleVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9pbnRlcmZhY2VzL0RIUHJpdmF0ZUtleVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZWRiMTRjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2ludGVyZmFjZXMvREhQcml2YXRlS2V5VGVzdC5qYXZhCkBAIC0wLDAgKzEsODUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0by5pbnRlcmZhY2VzOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvcjsKKworaW1wb3J0IGphdmF4LmNyeXB0by5pbnRlcmZhY2VzLkRIS2V5OworaW1wb3J0IGphdmF4LmNyeXB0by5pbnRlcmZhY2VzLkRIUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5ESFBhcmFtZXRlclNwZWM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkRIUHJpdmF0ZUtleTwvY29kZT4gY2xhc3MgZmllbGQKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBESFByaXZhdGVLZXlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+c2VyaWFsVmVyc2lvblVJRDwvY29kZT4gZmllbGQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmllbGQoKSB7CisgICAgICAgIGNoZWNrREhQcml2YXRlS2V5IGtleSA9IG5ldyBjaGVja0RIUHJpdmF0ZUtleSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBzZXJpYWxWZXJzaW9uVUlEIiwKKyAgICAgICAgICAgICAgICBrZXkuZ2V0U2VyVmVyVUlEKCksIC8vREhQcml2YXRlS2V5LnNlcmlhbFZlcnNpb25VSUQKKyAgICAgICAgICAgICAgICAyMjExNzkxMTEzMzgwMzk2NTUzTCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQYXJhbXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvciBrZyA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRIIik7CisgICAgICAgIGtnLmluaXRpYWxpemUoMTkyKTsKKyAgICAgICAgS2V5UGFpciBrcDEgPSBrZy5nZW5LZXlQYWlyKCk7CisgICAgICAgIEtleVBhaXIga3AyID0ga2cuZ2VuS2V5UGFpcigpOworICAgICAgICBESFByaXZhdGVLZXkgcGsxID0gKERIUHJpdmF0ZUtleSkga3AxLmdldFByaXZhdGUoKTsKKyAgICAgICAgREhQcml2YXRlS2V5IHBrMiA9IChESFByaXZhdGVLZXkpIGtwMi5nZXRQcml2YXRlKCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShwazEuZ2V0WCgpLmdldENsYXNzKCkuZ2V0Q2Fub25pY2FsTmFtZSgpLmVxdWFscygiamF2YS5tYXRoLkJpZ0ludGVnZXIiKSk7CisgICAgICAgIGFzc2VydFRydWUocGsxLmdldFBhcmFtcygpLmdldENsYXNzKCkuZ2V0Q2Fub25pY2FsTmFtZSgpLmVxdWFscygiamF2YXguY3J5cHRvLnNwZWMuREhQYXJhbWV0ZXJTcGVjIikpOworICAgICAgICBhc3NlcnRGYWxzZShwazEuZXF1YWxzKHBrMikpOworICAgICAgICBhc3NlcnRUcnVlKHBrMS5nZXRYKCkuZXF1YWxzKHBrMS5nZXRYKCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgY2hlY2tESFByaXZhdGVLZXkgaW1wbGVtZW50cyBESFByaXZhdGVLZXkgeworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgIHJldHVybiAiU2VjcmV0S2V5IjsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgICAgIHJldHVybiAiRm9ybWF0IjsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbMF07CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGxvbmcgZ2V0U2VyVmVyVUlEKCkgeworICAgICAgICAgICAgcmV0dXJuIHNlcmlhbFZlcnNpb25VSUQ7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0WCgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBESFBhcmFtZXRlclNwZWMgZ2V0UGFyYW1zKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vaW50ZXJmYWNlcy9ESFB1YmxpY0tleVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9pbnRlcmZhY2VzL0RIUHVibGljS2V5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ3MWQ2NzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vaW50ZXJmYWNlcy9ESFB1YmxpY0tleVRlc3QuamF2YQpAQCAtMCwwICsxLDg5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uaW50ZXJmYWNlczsKKworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLkJyb2tlblRlc3Q7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yOworCitpbXBvcnQgamF2YXguY3J5cHRvLmludGVyZmFjZXMuREhLZXk7CitpbXBvcnQgamF2YXguY3J5cHRvLmludGVyZmFjZXMuREhQdWJsaWNLZXk7CitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuREhQYXJhbWV0ZXJTcGVjOworCisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkRIUHVibGljS2V5PC9jb2RlPiBjbGFzcyBmaWVsZAorICoKKyAqLworcHVibGljIGNsYXNzIERIUHVibGljS2V5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnNlcmlhbFZlcnNpb25VSUQ8L2NvZGU+IGZpZWxkCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEZpZWxkKCkgeworICAgICAgICBjaGVja0RIUHVibGljS2V5IGtleSA9IG5ldyBjaGVja0RIUHVibGljS2V5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHNlcmlhbFZlcnNpb25VSUQiLAorICAgICAgICAgICAgICAgIGtleS5nZXRTZXJWZXJVSUQoKSwgLy9ESFB1YmxpY0tleS5zZXJpYWxWZXJzaW9uVUlECisgICAgICAgICAgICAgICAgLTY2MjgxMDM1NjMzNTI1MTkxOTNMKTsKKyAgICB9CisKKyAgICBAQnJva2VuVGVzdCgiVG9vIHNsb3cgLSBkaXNhYmxpbmcgZm9yIG5vdyIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQYXJhbXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvciBrZyA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRIIik7CisgICAgICAgIGtnLmluaXRpYWxpemUoMTAyNCk7CisgICAgICAgIEtleVBhaXIga3AxID0ga2cuZ2VuS2V5UGFpcigpOworICAgICAgICBLZXlQYWlyIGtwMiA9IGtnLmdlbktleVBhaXIoKTsKKyAgICAgICAgREhQdWJsaWNLZXkgcGsxID0gKERIUHVibGljS2V5KSBrcDEuZ2V0UHVibGljKCk7CisgICAgICAgIERIUHVibGljS2V5IHBrMiA9IChESFB1YmxpY0tleSkga3AyLmdldFB1YmxpYygpOworCisgICAgICAgIGFzc2VydFRydWUocGsxLmdldFkoKS5nZXRDbGFzcygpLmdldENhbm9uaWNhbE5hbWUoKS5lcXVhbHMoImphdmEubWF0aC5CaWdJbnRlZ2VyIikpOworICAgICAgICBhc3NlcnRUcnVlKHBrMi5nZXRQYXJhbXMoKS5nZXRDbGFzcygpLmdldENhbm9uaWNhbE5hbWUoKS5lcXVhbHMoImphdmF4LmNyeXB0by5zcGVjLkRIUGFyYW1ldGVyU3BlYyIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocGsxLmVxdWFscyhwazIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwazEuZ2V0WSgpLmVxdWFscyhwazEuZ2V0WSgpKSk7CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIGNoZWNrREhQdWJsaWNLZXkgaW1wbGVtZW50cyBESFB1YmxpY0tleSB7CisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICAgICAgcmV0dXJuICJTZWNyZXRLZXkiOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgcmV0dXJuICJGb3JtYXQiOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVswXTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgbG9uZyBnZXRTZXJWZXJVSUQoKSB7CisgICAgICAgICAgICByZXR1cm4gc2VyaWFsVmVyc2lvblVJRDsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRZKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIERIUGFyYW1ldGVyU3BlYyBnZXRQYXJhbXMoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9pbnRlcmZhY2VzL1BCRUtleVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9pbnRlcmZhY2VzL1BCRUtleVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTQxZGM1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL2ludGVyZmFjZXMvUEJFS2V5VGVzdC5qYXZhCkBAIC0wLDAgKzEsOTMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0by5pbnRlcmZhY2VzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uaW50ZXJmYWNlcy5QQkVLZXk7CisKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+UEJFS2V5PC9jb2RlPiBjbGFzcyBmaWVsZAorICoKKyAqLworcHVibGljIGNsYXNzIFBCRUtleVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnNlcmlhbFZlcnNpb25VSUQ8L2NvZGU+IGZpZWxkCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEZpZWxkKCkgeworICAgICAgICBjaGVja1BCRUtleSBrZXkgPSBuZXcgY2hlY2tQQkVLZXkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3Qgc2VyaWFsVmVyc2lvblVJRCIsCisgICAgICAgICAgICAgICAga2V5LmdldFNlclZlclVJRCgpLCAvL1BCRUtleS5zZXJpYWxWZXJzaW9uVUlECisgICAgICAgICAgICAgICAgLTE0MzAwMTU5OTMzMDQzMzM5MjFMKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEl0ZXJhdGlvbkNvdW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrUEJFS2V5IGtleSA9IG5ldyBjaGVja1BCRUtleSgpOworCisgICAgICAgIGtleS5nZXRJdGVyYXRpb25Db3VudCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UGFzc3dvcmQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tQQkVLZXkga2V5ID0gbmV3IGNoZWNrUEJFS2V5KCk7CisKKyAgICAgICAga2V5LmdldFBhc3N3b3JkKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTYWx0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrUEJFS2V5IGtleSA9IG5ldyBjaGVja1BCRUtleSgpOworCisgICAgICAgIGtleS5nZXRTYWx0KCk7CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIGNoZWNrUEJFS2V5IGltcGxlbWVudHMgUEJFS2V5IHsKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgICAgICByZXR1cm4gIlNlY3JldEtleSI7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRGb3JtYXQoKSB7CisgICAgICAgICAgICByZXR1cm4gIkZvcm1hdCI7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBieXRlWzBdOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBsb25nIGdldFNlclZlclVJRCgpIHsKKyAgICAgICAgICAgIHJldHVybiBzZXJpYWxWZXJzaW9uVUlEOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFkoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgaW50IGdldEl0ZXJhdGlvbkNvdW50KCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRTYWx0KCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBieXRlWzBdOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBjaGFyW10gZ2V0UGFzc3dvcmQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IGNoYXJbMF07CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc2VyaWFsaXphdGlvbi9CYWRQYWRkaW5nRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vQmFkUGFkZGluZ0V4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZDI5OTMzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vQmFkUGFkZGluZ0V4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDQ1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uc2VyaWFsaXphdGlvbjsKKworaW1wb3J0IGphdmF4LmNyeXB0by5CYWRQYWRkaW5nRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnRlc3RmcmFtZXdvcmsuc2VyaWFsaXphdGlvbi5TZXJpYWxpemF0aW9uVGVzdDsKKworCisvKioKKyAqIFRlc3QgZm9yIEJhZFBhZGRpbmdFeGNlcHRpb24gc2VyaWFsaXphdGlvbgorICoKKyAqLworCitwdWJsaWMgY2xhc3MgQmFkUGFkZGluZ0V4Y2VwdGlvblRlc3QgZXh0ZW5kcyBTZXJpYWxpemF0aW9uVGVzdCB7CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZ1tdIG1zZ3MgPSB7CisgICAgICAgICAgICAiTmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkxvbmcgbWVzc2FnZSBmb3IgRXhjZXB0aW9uLiBMb25nIG1lc3NhZ2UgZm9yIEV4Y2VwdGlvbi4gTG9uZyBtZXNzYWdlIGZvciBFeGNlcHRpb24uIiB9OworCisgICAgcHJvdGVjdGVkIE9iamVjdFtdIGdldERhdGEoKSB7CisgICAgICAgIHJldHVybiBuZXcgT2JqZWN0W10geyBuZXcgQmFkUGFkZGluZ0V4Y2VwdGlvbigpLAorICAgICAgICAgICAgICAgIG5ldyBCYWRQYWRkaW5nRXhjZXB0aW9uKG51bGwpLCBuZXcgQmFkUGFkZGluZ0V4Y2VwdGlvbihtc2dzWzFdKSB9OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zZXJpYWxpemF0aW9uL0V4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zZXJpYWxpemF0aW9uL0V4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZDA3MTdmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0by5zZXJpYWxpemF0aW9uOworCitpbXBvcnQgamF2YXguY3J5cHRvLkV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS50ZXN0ZnJhbWV3b3JrLnNlcmlhbGl6YXRpb24uU2VyaWFsaXphdGlvblRlc3Q7CisKKworLyoqCisgKiBUZXN0IGZvciBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24gc2VyaWFsaXphdGlvbgorICoKKyAqLworCitwdWJsaWMgY2xhc3MgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uVGVzdCBleHRlbmRzIFNlcmlhbGl6YXRpb25UZXN0IHsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gbXNncyA9IHsKKyAgICAgICAgICAgICJOZXcgbWVzc2FnZSIsCisgICAgICAgICAgICAiTG9uZyBtZXNzYWdlIGZvciBFeGNlcHRpb24uIExvbmcgbWVzc2FnZSBmb3IgRXhjZXB0aW9uLiBMb25nIG1lc3NhZ2UgZm9yIEV4Y2VwdGlvbi4iIH07CisKKyAgICBwcm90ZWN0ZWQgT2JqZWN0W10gZ2V0RGF0YSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXSB7IG5ldyBFeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb24oKSwKKyAgICAgICAgICAgICAgICBuZXcgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uKG51bGwpLCBuZXcgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uKG1zZ3NbMV0pIH07CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zZXJpYWxpemF0aW9uL0lsbGVnYWxCbG9ja1NpemVFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjg2OWQ0MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zZXJpYWxpemF0aW9uL0lsbGVnYWxCbG9ja1NpemVFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvLnNlcmlhbGl6YXRpb247CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS50ZXN0ZnJhbWV3b3JrLnNlcmlhbGl6YXRpb24uU2VyaWFsaXphdGlvblRlc3Q7CisKKworLyoqCisgKiBUZXN0IGZvciBJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uIHNlcmlhbGl6YXRpb24KKyAqCisgKi8KKworcHVibGljIGNsYXNzIElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb25UZXN0IGV4dGVuZHMgU2VyaWFsaXphdGlvblRlc3QgeworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIk5ldyBtZXNzYWdlIiwKKyAgICAgICAgICAgICJMb25nIG1lc3NhZ2UgZm9yIEV4Y2VwdGlvbi4gTG9uZyBtZXNzYWdlIGZvciBFeGNlcHRpb24uIExvbmcgbWVzc2FnZSBmb3IgRXhjZXB0aW9uLiIgfTsKKworICAgIHByb3RlY3RlZCBPYmplY3RbXSBnZXREYXRhKCkgeworICAgICAgICByZXR1cm4gbmV3IE9iamVjdFtdIHsgbmV3IElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24oKSwKKyAgICAgICAgICAgICAgICBuZXcgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbihudWxsKSwgbmV3IElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24obXNnc1sxXSkgfTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc2VyaWFsaXphdGlvbi9Ob1N1Y2hQYWRkaW5nRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vTm9TdWNoUGFkZGluZ0V4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNjk1MzE0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vTm9TdWNoUGFkZGluZ0V4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDQ1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uc2VyaWFsaXphdGlvbjsKKworaW1wb3J0IGphdmF4LmNyeXB0by5Ob1N1Y2hQYWRkaW5nRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnRlc3RmcmFtZXdvcmsuc2VyaWFsaXphdGlvbi5TZXJpYWxpemF0aW9uVGVzdDsKKworCisvKioKKyAqIFRlc3QgZm9yIE51U3VjaFBhZGRpbmdFeGNlcHRpb24gc2VyaWFsaXphdGlvbgorICoKKyAqLworCitwdWJsaWMgY2xhc3MgTm9TdWNoUGFkZGluZ0V4Y2VwdGlvblRlc3QgZXh0ZW5kcyBTZXJpYWxpemF0aW9uVGVzdCB7CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZ1tdIG1zZ3MgPSB7CisgICAgICAgICAgICAiTmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkxvbmcgbWVzc2FnZSBmb3IgRXhjZXB0aW9uLiBMb25nIG1lc3NhZ2UgZm9yIEV4Y2VwdGlvbi4gTG9uZyBtZXNzYWdlIGZvciBFeGNlcHRpb24uIiB9OworCisgICAgcHJvdGVjdGVkIE9iamVjdFtdIGdldERhdGEoKSB7CisgICAgICAgIHJldHVybiBuZXcgT2JqZWN0W10geyBuZXcgTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbigpLAorICAgICAgICAgICAgICAgIG5ldyBOb1N1Y2hQYWRkaW5nRXhjZXB0aW9uKG51bGwpLCBuZXcgTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbihtc2dzWzFdKSB9OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zZXJpYWxpemF0aW9uL1Nob3J0QnVmZmVyRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vU2hvcnRCdWZmZXJFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGZkMWFlYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zZXJpYWxpemF0aW9uL1Nob3J0QnVmZmVyRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0by5zZXJpYWxpemF0aW9uOworCitpbXBvcnQgamF2YXguY3J5cHRvLlNob3J0QnVmZmVyRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnRlc3RmcmFtZXdvcmsuc2VyaWFsaXphdGlvbi5TZXJpYWxpemF0aW9uVGVzdDsKKworCisvKioKKyAqIFRlc3QgZm9yIFNob3J0QnVmZmVyRXhjZXB0aW9uIHNlcmlhbGl6YXRpb24KKyAqCisgKi8KKworcHVibGljIGNsYXNzIFNob3J0QnVmZmVyRXhjZXB0aW9uVGVzdCBleHRlbmRzIFNlcmlhbGl6YXRpb25UZXN0IHsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gbXNncyA9IHsKKyAgICAgICAgICAgICJOZXcgbWVzc2FnZSIsCisgICAgICAgICAgICAiTG9uZyBtZXNzYWdlIGZvciBFeGNlcHRpb24uIExvbmcgbWVzc2FnZSBmb3IgRXhjZXB0aW9uLiBMb25nIG1lc3NhZ2UgZm9yIEV4Y2VwdGlvbi4iIH07CisKKyAgICBwcm90ZWN0ZWQgT2JqZWN0W10gZ2V0RGF0YSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXSB7IG5ldyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbigpLAorICAgICAgICAgICAgICAgIG5ldyBTaG9ydEJ1ZmZlckV4Y2VwdGlvbihudWxsKSwgbmV3IFNob3J0QnVmZmVyRXhjZXB0aW9uKG1zZ3NbMV0pIH07CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NwZWMvREVTS2V5U3BlY1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL0RFU0tleVNwZWNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzhlY2M5ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL0RFU0tleVNwZWNUZXN0LmphdmEKQEAgLTAsMCArMSwyODkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLkRFU0tleVNwZWM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworLyoqCisgKi8KK3B1YmxpYyBjbGFzcyBERVNLZXlTcGVjVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8vIERFUyB3ZWFrIGFuZCBzZW1pLXdlYWsga2V5cworICAgIC8vIEdvdCBmcm9tOgorICAgIC8vIEZJUCBQVUIgNzQKKyAgICAvLyBGRURFUkFMIElORk9STUFUSU9OIFBST0NFU1NJTkcgU1RBTkRBUkRTIFBVQkxJQ0FUSU9OIDE5ODEKKyAgICAvLyBHVUlERUxJTkVTIEZPUiBJTVBMRU1FTlRJTkcgQU5EIFVTSU5HIFRIRSBOQlMgREFUQSBFTkNSWVBUSU9OIFNUQU5EQVJECisgICAgLy8gaHR0cDovL3d3dy5kaWNlLnVjbC5hYy5iZS9jcnlwdG8vc3RhbmRhcmRzL2ZpcHMvZmlwNzQvZmlwNzQtMS5wZGYKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW11bXSBzZW1pd2Vha3MgPSB7CisgICAgICAgICAgICAgICAgeyhieXRlKSAweEUwLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4RTAsIChieXRlKSAweDAxLAorICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweEYxLCAoYnl0ZSkgMHgwMX0sCisKKyAgICAgICAgICAgICAgICB7KGJ5dGUpIDB4MDEsIChieXRlKSAweEUwLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4RTAsCisgICAgICAgICAgICAgICAgIChieXRlKSAweDAxLCAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweEYxfSwKKworICAgICAgICAgICAgICAgIHsoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4MUYsIChieXRlKSAweEZFLCAoYnl0ZSkgMHgxRiwKKyAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4RkUsIChieXRlKSAweDBFLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4MEV9LAorCisgICAgICAgICAgICAgICAgeyhieXRlKSAweDFGLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4MUYsIChieXRlKSAweEZFLAorICAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwRSwgKGJ5dGUpIDB4RkUsIChieXRlKSAweDBFLCAoYnl0ZSkgMHhGRX0sCisKKyAgICAgICAgICAgICAgICB7KGJ5dGUpIDB4RTAsIChieXRlKSAweDFGLCAoYnl0ZSkgMHhFMCwgKGJ5dGUpIDB4MUYsCisgICAgICAgICAgICAgICAgIChieXRlKSAweEYxLCAoYnl0ZSkgMHgwRSwgKGJ5dGUpIDB4RjEsIChieXRlKSAweDBFfSwKKworICAgICAgICAgICAgICAgIHsoYnl0ZSkgMHgxRiwgKGJ5dGUpIDB4RTAsIChieXRlKSAweDFGLCAoYnl0ZSkgMHhFMCwKKyAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MEUsIChieXRlKSAweEYxLCAoYnl0ZSkgMHgwRSwgKGJ5dGUpIDB4RjF9LAorCisgICAgICAgICAgICAgICAgeyhieXRlKSAweDAxLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweEZFLAorICAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4RkUsIChieXRlKSAweDAxLCAoYnl0ZSkgMHhGRX0sCisKKyAgICAgICAgICAgICAgICB7KGJ5dGUpIDB4RkUsIChieXRlKSAweDAxLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4MDEsCisgICAgICAgICAgICAgICAgIChieXRlKSAweEZFLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4RkUsIChieXRlKSAweDAxfSwKKworICAgICAgICAgICAgICAgIHsoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MUYsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgxRiwKKyAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweDBFLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MEV9LAorCisgICAgICAgICAgICAgICAgeyhieXRlKSAweDFGLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MUYsIChieXRlKSAweDAxLAorICAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwRSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDBFLCAoYnl0ZSkgMHgwMX0sCisKKyAgICAgICAgICAgICAgICB7KGJ5dGUpIDB4RTAsIChieXRlKSAweEZFLCAoYnl0ZSkgMHhFMCwgKGJ5dGUpIDB4RkUsCisgICAgICAgICAgICAgICAgIChieXRlKSAweEYxLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4RjEsIChieXRlKSAweEZFfSwKKworICAgICAgICAgICAgICAgIHsoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4RTAsIChieXRlKSAweEZFLCAoYnl0ZSkgMHhFMCwKKyAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4RkUsIChieXRlKSAweEYxLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4RjF9LAorCisgICAgICAgICAgICAgICAgeyhieXRlKSAweDAxLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAxLAorICAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMX0sCisKKyAgICAgICAgICAgICAgICB7KGJ5dGUpIDB4RkUsIChieXRlKSAweEZFLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4RkUsCisgICAgICAgICAgICAgICAgIChieXRlKSAweEZFLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4RkUsIChieXRlKSAweEZFfSwKKworICAgICAgICAgICAgICAgIHsoYnl0ZSkgMHhFMCwgKGJ5dGUpIDB4RTAsIChieXRlKSAweEUwLCAoYnl0ZSkgMHhFMCwKKyAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4RjEsIChieXRlKSAweEYxLCAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4RjF9LAorCisgICAgICAgICAgICAgICAgeyhieXRlKSAweDFGLCAoYnl0ZSkgMHgxRiwgKGJ5dGUpIDB4MUYsIChieXRlKSAweDFGLAorICAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwRSwgKGJ5dGUpIDB4MEUsIChieXRlKSAweDBFLCAoYnl0ZSkgMHgwRX0sCisgICAgICAgICAgICB9OworCisgICAgLyogREVTIG5vdCB3ZWFrIG9yIHNlbWktd2VhayBrZXlzICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdW10gbm90c2VtaXdlYWtzID0geworICAgICAgICAgICAgICAgIHsoYnl0ZSkgMHgxZiwgKGJ5dGUpIDB4MWYsIChieXRlKSAweDFmLCAoYnl0ZSkgMHgxZiwKKyAgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MWYsIChieXRlKSAweDFmLCAoYnl0ZSkgMHgxZiwgKGJ5dGUpIDB4MWZ9LAorCisgICAgICAgICAgICAgICAgeyhieXRlKSAweGUwLCAoYnl0ZSkgMHhlMCwgKGJ5dGUpIDB4ZTAsIChieXRlKSAweGUwLAorICAgICAgICAgICAgICAgICAoYnl0ZSkgMHhlMCwgKGJ5dGUpIDB4ZTAsIChieXRlKSAweGUwLCAoYnl0ZSkgMHhlMH0KKyAgICAgICAgICAgIH07CisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3JzIHRlc3RpbmcuIFRlc3RzIGJlaGF2aW9yIG9mIGVhY2ggb2YgdHdvIGNvbnN0cnVjdG9ycworICAgICAqIGluIHRoZSBjYXNlcyBvZjogbnVsbCBhcnJheSwgc2hvcnQgYXJyYXksIG5vcm1hbCBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0REVTS2V5U3BlYygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBERVNLZXlTcGVjKChieXRlIFtdKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCByYWlzZSBhbiBOdWxsUG9pbnRlckV4Y2VwdGlvbiAiCisgICAgICAgICAgICAgICAgICAgICsgImluIGNhc2Ugb2YgbnVsbCBieXRlIGFycmF5LiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHJhaXNlIGFuIE51bGxQb2ludGVyRXhjZXB0aW9uICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gY2FzZSBvZiBudWxsIGJ5dGUgYXJyYXkuIik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBERVNLZXlTcGVjKG5ldyBieXRlIFtdIHsxLCAyLCAzfSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgcmFpc2UgYW4gSW52YWxpZEtleUV4Y2VwdGlvbiBvbiBhIHNob3J0IGJ5dGUgYXJyYXkuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBERVNLZXlTcGVjKG5ldyBieXRlW10gezEsIDIsIDMsIDQsIDUsIDYsIDcsIDh9KTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSW52YWxpZEtleUV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgREVTS2V5U3BlYygoYnl0ZSBbXSkgbnVsbCwgMSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgcmFpc2UgYW4gTnVsbFBvaW50ZXJFeGNlcHRpb24gIgorICAgICAgICAgICAgICAgICAgICArICJpbiBjYXNlIG9mIG51bGwgYnl0ZSBhcnJheS4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCByYWlzZSBhbiBOdWxsUG9pbnRlckV4Y2VwdGlvbiAiCisgICAgICAgICAgICAgICAgICAgICsgImluIGNhc2Ugb2YgbnVsbCBieXRlIGFycmF5LiIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgREVTS2V5U3BlYyhuZXcgYnl0ZSBbXSAgezEsIDIsIDMsIDQsIDUsIDYsIDcsIDh9LCAxKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCByYWlzZSBhbiBJbnZhbGlkS2V5RXhjZXB0aW9uIG9uIGEgc2hvcnQgYnl0ZSBhcnJheS4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IERFU0tleVNwZWMobmV3IGJ5dGVbXSB7MSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOX0sIDEpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJbnZhbGlkS2V5RXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRLZXkoKSBtZXRob2QgdGVzdGluZy4gQ2hlY2tzIHRoYXQgbW9kaWZpY2F0aW9uIG9mIHJldHVybmVkIGtleQorICAgICAqIGRvZXMgbm90IGFmZmVjdCB0aGUgaW50ZXJuYWwga2V5LiBBbHNvIHRlc3QgY2hlY2sgYW4gZXF1YWxpdHkgb2YKKyAgICAgKiB0aGUga2V5IHdpdGggdGhlIGtleSBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yLiBUaGUgb2JqZWN0IHVuZGVyCisgICAgICogdGhlIHRlc3QgaXMgY3JlYXRlZCBieSBkaWZmZXJlbnQgY29uc3RydWN0b3JzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRLZXkoKSB7CisgICAgICAgIGJ5dGVbXSBrZXkgPSB7MSwgMiwgMywgNCwgNSwgNiwgNywgOH07CisgICAgICAgIERFU0tleVNwZWMga3M7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrcyA9IG5ldyBERVNLZXlTcGVjKGtleSk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSW52YWxpZEtleUV4Y2VwdGlvbiBzaG91bGQgbm90IGJlIHRocm93bi4iKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gcmVzID0ga3MuZ2V0S2V5KCk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSByZXR1cm5lZCBhcnJheSBzaG91bGQgYmUgZXF1YWwgdG8gdGhlIHNwZWNpZmllZCAiCisgICAgICAgICAgICAgICAgICAgICsgImluIGNvbnN0cnVjdG9yLiIsIEFycmF5cy5lcXVhbHMoa2V5LCByZXMpKTsKKyAgICAgICAgcmVzWzBdICs9IDE7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgbW9kaWZpY2F0aW9uIG9mIHJldHVybmVkIGtleSBzaG91bGQgbm90IGFmZmVjdCIKKyAgICAgICAgICAgICAgICAgICAgKyAidGhlIHVuZGVybHlpbmcga2V5LiIsIGtleVswXSA9PSByZXNbMF0pOworCisgICAgICAgIGJ5dGVbXSBrZXkxID0gezEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDB9OworICAgICAgICB0cnkgeworICAgICAgICAgICAga3MgPSBuZXcgREVTS2V5U3BlYyhrZXkxLCAyKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkS2V5RXhjZXB0aW9uIHNob3VsZCBub3QgYmUgdGhyb3duLiIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHJlcyA9IGtzLmdldEtleSgpOworICAgICAgICBhc3NlcnROb3RTYW1lKCJUaGUgcmV0dXJuZWQgYXJyYXkgc2hvdWxkIG5vdCBiZSB0aGUgc2FtZSBvYmplY3QgIgorICAgICAgICAgICAgICAgICAgICArICJhcyBzcGVjaWZpZWQgaW4gYSBjb25zdHJ1Y3Rvci4iLCBrZXkxLCByZXMpOworICAgICAgICBieXRlW10gZXhwID0gbmV3IGJ5dGVbOF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoa2V5MSwgMiwgZXhwLCAwLCA4KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIHJldHVybmVkIGFycmF5IHNob3VsZCBiZSBlcXVhbCB0byB0aGUgc3BlY2lmaWVkICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gY29uc3RydWN0b3IuIiwgQXJyYXlzLmVxdWFscyhleHAsIHJlcykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGlzUGFyaXR5QWRqdXN0ZWQoYnl0ZVtdIGtleSwgb2Zmc2V0KSBtZXRob2QgdGVzdGluZy4gVGVzdHMgaWYgdGhlCisgICAgICogbWV0aG9kIHRocm93cyBhcHByb3ByaWF0ZSBleGNlcHRpb25zIG9uIGluY29ycmVjdCBieXRlIGFycmF5LCBpZgorICAgICAqIGl0IHJldHVybnMgZmFsc2Ugb24gdGhlIGtleSB3aGljaCBpcyBub3QgcGFyaXR5IGFkanVzdGVkLCBhbmQgaWYKKyAgICAgKiBpdCByZXR1cm5zIHRydWUgb24gcGFyaXR5IGFkanVzdGVkIGtleS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNQYXJpdHlBZGp1c3RlZCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIERFU0tleVNwZWMuaXNQYXJpdHlBZGp1c3RlZChudWxsLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCByYWlzZSBhbiBJbnZhbGlkS2V5RXhjZXB0aW9uICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gY2FzZSBvZiBudWxsIGJ5dGUgYXJyYXkuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBieXRlW10ga2V5ID0gezEsIDIsIDMsIDQsIDUsIDYsIDcsIDh9OworICAgICAgICB0cnkgeworICAgICAgICAgICAgREVTS2V5U3BlYy5pc1Bhcml0eUFkanVzdGVkKGtleSwgMSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgcmFpc2UgYW4gSW52YWxpZEtleUV4Y2VwdGlvbiAiCisgICAgICAgICAgICAgICAgICAgICsgImluIGNhc2Ugb2Ygc2hvcnQgYnl0ZSBhcnJheS4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGVbXSBrZXlfbm90X3BhID0gezEsIDIsIDMsIDQsIDUsIDYsIDcsIDh9OworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIk1ldGhvZCByZXR1cm5zIHRydWUgd2hlbiBmYWxzZSBpcyBleHBlY3RlZC4iLAorICAgICAgICAgICAgICAgICAgICAgICAgREVTS2V5U3BlYy5pc1Bhcml0eUFkanVzdGVkKGtleV9ub3RfcGEsIDApKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSW52YWxpZEtleUV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZVtdIGtleV9wYSA9IHsoYnl0ZSkgMTI4LCAoYnl0ZSkgMTMxLCAoYnl0ZSkgMTMzLCAoYnl0ZSkgMTM0LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAxMzcsIChieXRlKSAxMzgsIChieXRlKSAxNDAsIChieXRlKSAxNDN9OworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTWV0aG9kIHJldHVybnMgZmFsc2Ugd2hlbiB0cnVlIGlzIGV4cGVjdGVkLiIsCisgICAgICAgICAgICAgICAgICAgICAgICBERVNLZXlTcGVjLmlzUGFyaXR5QWRqdXN0ZWQoa2V5X3BhLCAwKSk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIEludmFsaWRLZXlFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGlzV2VhayhieXRlW10ga2V5LCBpbnQgb2Zmc2V0KSBtZXRob2QgdGVzdGluZy4gVGVzdHMgaWYgdGhlCisgICAgICogbWV0aG9kIHRocm93cyBhcHByb3ByaWF0ZSBleGNlcHRpb25zIG9uIGluY29ycmVjdCBieXRlIGFycmF5LCBpZgorICAgICAqIGl0IHJldHVybnMgdHJ1ZSBvbiB3ZWFrIG9yIHNlbWktd2VhayBrZXlzLCBhbmQgaWYgaXQgcmV0dXJucworICAgICAqIGZhbHNlIG9uIG90aGVyIGtleXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdElzV2VhaygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIERFU0tleVNwZWMuaXNXZWFrKG51bGwsIDEpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHJhaXNlIGFuIEludmFsaWRLZXlFeGNlcHRpb24gIgorICAgICAgICAgICAgICAgICAgICArICJpbiBjYXNlIG9mIG51bGwgYnl0ZSBhcnJheS4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGVbXSBrZXkgPSB7MSwgMiwgMywgNCwgNSwgNiwgNywgOH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBERVNLZXlTcGVjLmlzV2VhayhrZXksIDEpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHJhaXNlIGFuIEludmFsaWRLZXlFeGNlcHRpb24gIgorICAgICAgICAgICAgICAgICAgICArICJpbiBjYXNlIG9mIHNob3J0IGJ5dGUgYXJyYXkuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpPTA7IGk8c2VtaXdlYWtzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIk1ldGhvZCByZXR1cm5zIGZhbHNlIHdoZW4gdHJ1ZSBpcyBleHBlY3RlZCIsCisgICAgICAgICAgICAgICAgICAgICAgICBERVNLZXlTcGVjLmlzV2VhayhzZW1pd2Vha3NbaV0sIDApKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSW52YWxpZEtleUV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGk9MDsgaTxub3RzZW1pd2Vha3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIk1ldGhvZCByZXR1cm5zIHRydWUgd2hlbiBmYWxzZSBpcyBleHBlY3RlZCIsCisgICAgICAgICAgICAgICAgICAgICAgICBERVNLZXlTcGVjLmlzV2Vhayhub3RzZW1pd2Vha3NbaV0sIDApKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSW52YWxpZEtleUV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBUZXN0IHN1aXRlKCkgeworICAgICAgICByZXR1cm4gbmV3IFRlc3RTdWl0ZShERVNLZXlTcGVjVGVzdC5jbGFzcyk7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc3BlYy9ERVNlZGVLZXlTcGVjVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NwZWMvREVTZWRlS2V5U3BlY1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjZhN2I2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NwZWMvREVTZWRlS2V5U3BlY1Rlc3QuamF2YQpAQCAtMCwwICsxLDE5NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvLnNwZWM7CisKK2ltcG9ydCBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5ERVNlZGVLZXlTcGVjOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKKy8qKgorICovCitwdWJsaWMgY2xhc3MgREVTZWRlS2V5U3BlY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvcnMgdGVzdGluZy4gVGVzdHMgYmVoYXZpb3Igb2YgZWFjaCBvZiB0d28gY29uc3RydWN0b3JzCisgICAgICogaW4gdGhlIGNhc2VzIG9mOiBudWxsIGFycmF5LCBzaG9ydCBhcnJheSwgbm9ybWFsIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RERVNlZGVLZXlTcGVjKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IERFU2VkZUtleVNwZWMoKGJ5dGUgW10pIG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHJhaXNlIGFuIE51bGxQb2ludGVyRXhjZXB0aW9uICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gY2FzZSBvZiBudWxsIGJ5dGUgYXJyYXkuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgcmFpc2UgYW4gTnVsbFBvaW50ZXJFeGNlcHRpb24gIgorICAgICAgICAgICAgICAgICAgICArICJpbiBjYXNlIG9mIG51bGwgYnl0ZSBhcnJheS4iKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IERFU2VkZUtleVNwZWMobmV3IGJ5dGUgW10gezEsIDIsIDN9KTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCByYWlzZSBhbiBJbnZhbGlkS2V5RXhjZXB0aW9uIG9uIGEgc2hvcnQgYnl0ZSBhcnJheS4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IERFU2VkZUtleVNwZWMobmV3IGJ5dGVbXSB7MSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAyLCAzLCA0fSk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIEludmFsaWRLZXlFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IERFU2VkZUtleVNwZWMoKGJ5dGUgW10pIG51bGwsIDEpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHJhaXNlIGFuIE51bGxQb2ludGVyRXhjZXB0aW9uICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gY2FzZSBvZiBudWxsIGJ5dGUgYXJyYXkuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgcmFpc2UgYW4gTnVsbFBvaW50ZXJFeGNlcHRpb24gIgorICAgICAgICAgICAgICAgICAgICArICJpbiBjYXNlIG9mIG51bGwgYnl0ZSBhcnJheS4iKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IERFU2VkZUtleVNwZWMobmV3IGJ5dGUgW10gIHsxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAyLCAzLCA0fSwgMSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgcmFpc2UgYW4gSW52YWxpZEtleUV4Y2VwdGlvbiBvbiBhIHNob3J0IGJ5dGUgYXJyYXkuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBERVNlZGVLZXlTcGVjKG5ldyBieXRlW10gezEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMiwgMywgNCwgNX0sIDEpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJbnZhbGlkS2V5RXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRLZXkoKSBtZXRob2QgdGVzdGluZy4gQ2hlY2tzIHRoYXQgbW9kaWZpY2F0aW9uIG9mIHJldHVybmVkIGtleQorICAgICAqIGRvZXMgbm90IGFmZmVjdCB0aGUgaW50ZXJuYWwga2V5LiBBbHNvIHRlc3QgY2hlY2sgYW4gZXF1YWxpdHkgb2YKKyAgICAgKiB0aGUga2V5IHdpdGggdGhlIGtleSBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yLiBUaGUgb2JqZWN0IHVuZGVyCisgICAgICogdGhlIHRlc3QgaXMgY3JlYXRlZCBieSBkaWZmZXJlbnQgY29uc3RydWN0b3JzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRLZXkoKSB7CisgICAgICAgIGJ5dGVbXSBrZXkgPSB7MSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMCwgMSwgMiwKKyAgICAgICAgICAgICAgICAgICAgICAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAwLCAxLCAyfTsKKyAgICAgICAgREVTZWRlS2V5U3BlYyBrczsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtzID0gbmV3IERFU2VkZUtleVNwZWMoa2V5KTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkS2V5RXhjZXB0aW9uIHNob3VsZCBub3QgYmUgdGhyb3duLiIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSByZXMgPSBrcy5nZXRLZXkoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIHJldHVybmVkIGFycmF5IHNob3VsZCBiZSBlcXVhbCB0byB0aGUgc3BlY2lmaWVkICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gY29uc3RydWN0b3IuIiwgQXJyYXlzLmVxdWFscyhrZXksIHJlcykpOworICAgICAgICByZXNbMF0gKz0gMTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBtb2RpZmljYXRpb24gb2YgcmV0dXJuZWQga2V5IHNob3VsZCBub3QgYWZmZWN0IgorICAgICAgICAgICAgICAgICAgICArICJ0aGUgdW5kZXJseWluZyBrZXkuIiwga2V5WzBdID09IHJlc1swXSk7CisKKyAgICAgICAgYnl0ZVtdIGtleTEgPSB7MSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMCwgMSwgMiwgMywKKyAgICAgICAgICAgICAgICAgICAgICAgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMCwgMSwgMiwgM307CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrcyA9IG5ldyBERVNlZGVLZXlTcGVjKGtleTEsIDIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWRLZXlFeGNlcHRpb24gc2hvdWxkIG5vdCBiZSB0aHJvd24uIik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgcmVzID0ga3MuZ2V0S2V5KCk7CisgICAgICAgIGFzc2VydE5vdFNhbWUoIlRoZSByZXR1cm5lZCBhcnJheSBzaG91bGQgbm90IGJlIHRoZSBzYW1lIG9iamVjdCAiCisgICAgICAgICAgICAgICAgICAgICsgImFzIHNwZWNpZmllZCBpbiBhIGNvbnN0cnVjdG9yLiIsIGtleTEsIHJlcyk7CisgICAgICAgIGJ5dGVbXSBleHAgPSBuZXcgYnl0ZVsyNF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoa2V5MSwgMiwgZXhwLCAwLCAyNCk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSByZXR1cm5lZCBhcnJheSBzaG91bGQgYmUgZXF1YWwgdG8gdGhlIHNwZWNpZmllZCAiCisgICAgICAgICAgICAgICAgICAgICsgImluIGNvbnN0cnVjdG9yLiIsIEFycmF5cy5lcXVhbHMoZXhwLCByZXMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBpc1Bhcml0eUFkanVzdGVkKGJ5dGVbXSBrZXksIG9mZnNldCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIGlmIHRoZQorICAgICAqIG1ldGhvZCB0aHJvd3MgYXBwcm9wcmlhdGUgZXhjZXB0aW9ucyBvbiBpbmNvcnJlY3QgYnl0ZSBhcnJheSwgaWYKKyAgICAgKiBpdCByZXR1cm5zIGZhbHNlIG9uIHRoZSBrZXkgd2hpY2ggaXMgbm90IHBhcml0eSBhZGp1c3RlZCwgYW5kIGlmCisgICAgICogaXQgcmV0dXJucyB0cnVlIG9uIHBhcml0eSBhZGp1c3RlZCBrZXkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdElzUGFyaXR5QWRqdXN0ZWQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBERVNlZGVLZXlTcGVjLmlzUGFyaXR5QWRqdXN0ZWQobnVsbCwgMSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgcmFpc2UgYW4gTnVsbFBvaW50ZXJFeGNlcHRpb24gIgorICAgICAgICAgICAgICAgICAgICArICJpbiBjYXNlIG9mIG51bGwgYnl0ZSBhcnJheS4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCByYWlzZSBhbiBOdWxsUG9pbnRlckV4Y2VwdGlvbiAiCisgICAgICAgICAgICAgICAgICAgICsgImluIGNhc2Ugb2YgbnVsbCBieXRlIGFycmF5LiIpOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZVtdIGtleSA9IHsxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAwLAorICAgICAgICAgICAgICAgICAgICAgIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDB9OworICAgICAgICB0cnkgeworICAgICAgICAgICAgREVTZWRlS2V5U3BlYy5pc1Bhcml0eUFkanVzdGVkKGtleSwgMSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgcmFpc2UgYW4gSW52YWxpZEtleUV4Y2VwdGlvbiAiCisgICAgICAgICAgICAgICAgICAgICsgImluIGNhc2Ugb2Ygc2hvcnQgYnl0ZSBhcnJheS4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGVbXSBrZXlfbm90X3BhID0gezEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDAsIDEsIDIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDAsIDEsIDJ9OworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIk1ldGhvZCByZXR1cm5zIHRydWUgd2hlbiBmYWxzZSBpcyBleHBlY3RlZC4iLAorICAgICAgICAgICAgICAgICAgICAgICAgREVTZWRlS2V5U3BlYy5pc1Bhcml0eUFkanVzdGVkKGtleV9ub3RfcGEsIDApKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSW52YWxpZEtleUV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZVtdIGtleV9wYSA9IHsoYnl0ZSkgMTI4LCAoYnl0ZSkgMTMxLCAoYnl0ZSkgMTMzLCAoYnl0ZSkgMTM0LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAxMzcsIChieXRlKSAxMzgsIChieXRlKSAxNDAsIChieXRlKSAxNDMsCisgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDE0NSwgKGJ5dGUpIDE0NiwgKGJ5dGUpIDE0OCwgKGJ5dGUpIDE1MSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMTUyLCAoYnl0ZSkgMTU1LCAoYnl0ZSkgMTU3LCAoYnl0ZSkgMTU4LAorICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKSAxNjEsIChieXRlKSAxNjIsIChieXRlKSAxNjQsIChieXRlKSAxNjcsCisgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpIDE2OCwgKGJ5dGUpIDE3MSwgKGJ5dGUpIDE3MywgKGJ5dGUpIDE3NH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJNZXRob2QgcmV0dXJucyBmYWxzZSB3aGVuIHRydWUgaXMgZXhwZWN0ZWQuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIERFU2VkZUtleVNwZWMuaXNQYXJpdHlBZGp1c3RlZChrZXlfcGEsIDApKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSW52YWxpZEtleUV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBUZXN0IHN1aXRlKCkgeworICAgICAgICByZXR1cm4gbmV3IFRlc3RTdWl0ZShERVNlZGVLZXlTcGVjVGVzdC5jbGFzcyk7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc3BlYy9ESEdlblBhcmFtZXRlclNwZWNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc3BlYy9ESEdlblBhcmFtZXRlclNwZWNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2MzNzJkYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL0RIR2VuUGFyYW1ldGVyU3BlY1Rlc3QuamF2YQpAQCAtMCwwICsxLDYxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEubGFuZy5JbnRlZ2VyOworCitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuREhHZW5QYXJhbWV0ZXJTcGVjOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKKy8qKgorICovCitwdWJsaWMgY2xhc3MgREhHZW5QYXJhbWV0ZXJTcGVjVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIERIR2VuUGFyYW1ldGVyU3BlYyBjbGFzcyB0ZXN0aW5nLiBUZXN0cyB0aGUgZXF1aXZhbGVuY2Ugb2YKKyAgICAgKiBwYXJhbWV0ZXJzIHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3Igd2l0aCB0aGUgdmFsdWVzIHJldHVybmVkCisgICAgICogYnkgZ2V0dGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0REhHZW5QYXJhbWV0ZXJTcGVjKCkgeworICAgICAgICBpbnRbXSBwcmltZXMgPSB7SW50ZWdlci5NSU5fVkFMVUUsIC0xLCAwLCAxLCBJbnRlZ2VyLk1BWF9WQUxVRX07CisgICAgICAgIGludFtdIGV4cG9uZW50cyA9IHtJbnRlZ2VyLk1JTl9WQUxVRSwgLTEsIDAsIDEsIEludGVnZXIuTUFYX1ZBTFVFfTsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPHByaW1lcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgREhHZW5QYXJhbWV0ZXJTcGVjIHBzID0gbmV3IERIR2VuUGFyYW1ldGVyU3BlYyhwcmltZXNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBvbmVudHNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgdmFsdWUgcmV0dXJuZWQgYnkgZ2V0UHJpbWVTaXplKCkgbXVzdCBiZSAiCisgICAgICAgICAgICAgICAgICAgICAgICArICJlcXVhbCB0byB0aGUgdmFsdWUgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciIsCisgICAgICAgICAgICAgICAgICAgICAgICBwcy5nZXRQcmltZVNpemUoKSwgcHJpbWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGhlIHZhbHVlIHJldHVybmVkIGJ5IGdldEV4cG9uZW50U2l6ZSgpIG11c3QgYmUgIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAiZXF1YWwgdG8gdGhlIHZhbHVlIHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3IiLAorICAgICAgICAgICAgICAgICAgICAgICAgcHMuZ2V0UHJpbWVTaXplKCksIGV4cG9uZW50c1tpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFRlc3Qgc3VpdGUoKSB7CisgICAgICAgIHJldHVybiBuZXcgVGVzdFN1aXRlKERIR2VuUGFyYW1ldGVyU3BlY1Rlc3QuY2xhc3MpOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NwZWMvREhQYXJhbWV0ZXJTcGVjVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NwZWMvREhQYXJhbWV0ZXJTcGVjVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk4ODdmN2QKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc3BlYy9ESFBhcmFtZXRlclNwZWNUZXN0LmphdmEKQEAgLTAsMCArMSw3NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuamF2YXguY3J5cHRvLnNwZWM7CisKK2ltcG9ydCBqYXZhLmxhbmcuSW50ZWdlcjsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKKworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLkRIUGFyYW1ldGVyU3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCisvKioKKyAqLworcHVibGljIGNsYXNzIERIUGFyYW1ldGVyU3BlY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBESFBhcmFtZXRlclNwZWMgY2xhc3MgdGVzdGluZy4gVGVzdHMgdGhlIGVxdWl2YWxlbmNlIG9mIHBhcmFtZXRlcnMKKyAgICAgKiBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yIHdpdGggdGhlIHZhbHVlcyByZXR1cm5lZCBieSBnZXR0ZXJzLgorICAgICAqIFRoZSB0ZXN0ZWQgb2JqZWN0IGlzIGNyZWF0ZWQgYnkgZGlmZmVyZW50IGNvbnN0cnVjdG9ycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0REhQYXJhbWV0ZXJTcGVjKCkgeworICAgICAgICBCaWdJbnRlZ2VyW10gcHMgPSB7bmV3IEJpZ0ludGVnZXIoIi0xMDAwMDAwMDAwMDAwIiksIEJpZ0ludGVnZXIuWkVSTywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwgbmV3IEJpZ0ludGVnZXIoIjEwMDAwMDAwMDAwMDAiKX07CisgICAgICAgIEJpZ0ludGVnZXJbXSBncyA9IHtuZXcgQmlnSW50ZWdlcigiLTEwMDAwMDAwMDAwMDAiKSwgQmlnSW50ZWdlci5aRVJPLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLCBuZXcgQmlnSW50ZWdlcigiMTAwMDAwMDAwMDAwMCIpfTsKKyAgICAgICAgaW50W10gbHMgPSB7SW50ZWdlci5NSU5fVkFMVUUsIDAsIDEsIEludGVnZXIuTUFYX1ZBTFVFfTsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPHBzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBESFBhcmFtZXRlclNwZWMgZGhwcyA9IG5ldyBESFBhcmFtZXRlclNwZWMocHNbaV0sIGdzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGhlIHZhbHVlIHJldHVybmVkIGJ5IGdldFAoKSBtdXN0IGJlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgImVxdWFsIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRocHMuZ2V0UCgpLCBwc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSB2YWx1ZSByZXR1cm5lZCBieSBnZXRHKCkgbXVzdCBiZSAiCisgICAgICAgICAgICAgICAgICAgICAgICArICJlcXVhbCB0byB0aGUgdmFsdWUgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciIsCisgICAgICAgICAgICAgICAgICAgICAgICBkaHBzLmdldEcoKSwgZ3NbaV0pOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGk9MDsgaTxwcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgREhQYXJhbWV0ZXJTcGVjIGRocHMgPSBuZXcgREhQYXJhbWV0ZXJTcGVjKHBzW2ldLCBnc1tpXSwgbHNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgdmFsdWUgcmV0dXJuZWQgYnkgZ2V0UCgpIG11c3QgYmUgIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAiZXF1YWwgdG8gdGhlIHZhbHVlIHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3IiLAorICAgICAgICAgICAgICAgICAgICAgICAgZGhwcy5nZXRQKCksIHBzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGhlIHZhbHVlIHJldHVybmVkIGJ5IGdldEcoKSBtdXN0IGJlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgImVxdWFsIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRocHMuZ2V0RygpLCBnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSB2YWx1ZSByZXR1cm5lZCBieSBnZXRMKCkgbXVzdCBiZSAiCisgICAgICAgICAgICAgICAgICAgICAgICArICJlcXVhbCB0byB0aGUgdmFsdWUgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciIsCisgICAgICAgICAgICAgICAgICAgICAgICBkaHBzLmdldEwoKSwgbHNbaV0pOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBUZXN0IHN1aXRlKCkgeworICAgICAgICByZXR1cm4gbmV3IFRlc3RTdWl0ZShESFBhcmFtZXRlclNwZWNUZXN0LmNsYXNzKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL0RIUHJpdmF0ZUtleVNwZWNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc3BlYy9ESFByaXZhdGVLZXlTcGVjVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4NTczODcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc3BlYy9ESFByaXZhdGVLZXlTcGVjVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0by5zcGVjOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5ESFByaXZhdGVLZXlTcGVjOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKKy8qKgorICovCitwdWJsaWMgY2xhc3MgREhQcml2YXRlS2V5U3BlY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBESFByaXZhdGVLZXlTcGVjIGNsYXNzIHRlc3RpbmcuIFRlc3RzIHRoZSBlcXVpdmFsZW5jZSBvZiBwYXJhbWV0ZXJzCisgICAgICogc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciB3aXRoIHRoZSB2YWx1ZXMgcmV0dXJuZWQgYnkgZ2V0dGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0REhQcml2YXRlS2V5U3BlYygpIHsKKyAgICAgICAgQmlnSW50ZWdlcltdIHhzID0ge25ldyBCaWdJbnRlZ2VyKCItMTAwMDAwMDAwMDAwMCIpLCBCaWdJbnRlZ2VyLlpFUk8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsIG5ldyBCaWdJbnRlZ2VyKCIxMDAwMDAwMDAwMDAwIil9OworICAgICAgICBCaWdJbnRlZ2VyW10gcHMgPSB7bmV3IEJpZ0ludGVnZXIoIi0xMDAwMDAwMDAwMDAwIiksIEJpZ0ludGVnZXIuWkVSTywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwgbmV3IEJpZ0ludGVnZXIoIjEwMDAwMDAwMDAwMDAiKX07CisgICAgICAgIEJpZ0ludGVnZXJbXSBncyA9IHtuZXcgQmlnSW50ZWdlcigiLTEwMDAwMDAwMDAwMDAiKSwgQmlnSW50ZWdlci5aRVJPLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLCBuZXcgQmlnSW50ZWdlcigiMTAwMDAwMDAwMDAwMCIpfTsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPHBzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBESFByaXZhdGVLZXlTcGVjIGRocGtzID0gbmV3IERIUHJpdmF0ZUtleVNwZWMoeHNbaV0sIHBzW2ldLCBnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSB2YWx1ZSByZXR1cm5lZCBieSBnZXRYKCkgbXVzdCBiZSAiCisgICAgICAgICAgICAgICAgICAgICAgICArICJlcXVhbCB0byB0aGUgdmFsdWUgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciIsCisgICAgICAgICAgICAgICAgICAgICAgICBkaHBrcy5nZXRYKCksIHhzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGhlIHZhbHVlIHJldHVybmVkIGJ5IGdldFAoKSBtdXN0IGJlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgImVxdWFsIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRocGtzLmdldFAoKSwgcHNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgdmFsdWUgcmV0dXJuZWQgYnkgZ2V0RygpIG11c3QgYmUgIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAiZXF1YWwgdG8gdGhlIHZhbHVlIHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3IiLAorICAgICAgICAgICAgICAgICAgICAgICAgZGhwa3MuZ2V0RygpLCBnc1tpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFRlc3Qgc3VpdGUoKSB7CisgICAgICAgIHJldHVybiBuZXcgVGVzdFN1aXRlKERIUHJpdmF0ZUtleVNwZWNUZXN0LmNsYXNzKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL0RIUHVibGljS2V5U3BlY1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL0RIUHVibGljS2V5U3BlY1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MzdhZmU1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NwZWMvREhQdWJsaWNLZXlTcGVjVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0by5zcGVjOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5ESFB1YmxpY0tleVNwZWM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworLyoqCisgKi8KK3B1YmxpYyBjbGFzcyBESFB1YmxpY0tleVNwZWNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogREhQdWJsaWNLZXlTcGVjIGNsYXNzIHRlc3RpbmcuIFRlc3RzIHRoZSBlcXVpdmFsZW5jZSBvZiBwYXJhbWV0ZXJzCisgICAgICogc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciB3aXRoIHRoZSB2YWx1ZXMgcmV0dXJuZWQgYnkgZ2V0dGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0REhQcml2YXRlS2V5U3BlYygpIHsKKyAgICAgICAgQmlnSW50ZWdlcltdIHlzID0ge25ldyBCaWdJbnRlZ2VyKCItMTAwMDAwMDAwMDAwMCIpLCBCaWdJbnRlZ2VyLlpFUk8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsIG5ldyBCaWdJbnRlZ2VyKCIxMDAwMDAwMDAwMDAwIil9OworICAgICAgICBCaWdJbnRlZ2VyW10gcHMgPSB7bmV3IEJpZ0ludGVnZXIoIi0xMDAwMDAwMDAwMDAwIiksIEJpZ0ludGVnZXIuWkVSTywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwgbmV3IEJpZ0ludGVnZXIoIjEwMDAwMDAwMDAwMDAiKX07CisgICAgICAgIEJpZ0ludGVnZXJbXSBncyA9IHtuZXcgQmlnSW50ZWdlcigiLTEwMDAwMDAwMDAwMDAiKSwgQmlnSW50ZWdlci5aRVJPLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLCBuZXcgQmlnSW50ZWdlcigiMTAwMDAwMDAwMDAwMCIpfTsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPHBzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBESFB1YmxpY0tleVNwZWMgZGhwa3MgPSBuZXcgREhQdWJsaWNLZXlTcGVjKHlzW2ldLCBwc1tpXSwgZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgdmFsdWUgcmV0dXJuZWQgYnkgZ2V0WSgpIG11c3QgYmUgIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAiZXF1YWwgdG8gdGhlIHZhbHVlIHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3IiLAorICAgICAgICAgICAgICAgICAgICAgICAgZGhwa3MuZ2V0WSgpLCB5c1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSB2YWx1ZSByZXR1cm5lZCBieSBnZXRQKCkgbXVzdCBiZSAiCisgICAgICAgICAgICAgICAgICAgICAgICArICJlcXVhbCB0byB0aGUgdmFsdWUgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciIsCisgICAgICAgICAgICAgICAgICAgICAgICBkaHBrcy5nZXRQKCksIHBzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGhlIHZhbHVlIHJldHVybmVkIGJ5IGdldEcoKSBtdXN0IGJlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgImVxdWFsIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRocGtzLmdldEcoKSwgZ3NbaV0pOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBUZXN0IHN1aXRlKCkgeworICAgICAgICByZXR1cm4gbmV3IFRlc3RTdWl0ZShESFB1YmxpY0tleVNwZWNUZXN0LmNsYXNzKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL0l2UGFyYW1ldGVyU3BlY1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL0l2UGFyYW1ldGVyU3BlY1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYzJlZjY2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NwZWMvSXZQYXJhbWV0ZXJTcGVjVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTM5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb247CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5JdlBhcmFtZXRlclNwZWM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworLyoqCisgKi8KK3B1YmxpYyBjbGFzcyBJdlBhcmFtZXRlclNwZWNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogSXZQYXJhbWV0ZXJTcGVjKGJ5dGVbXSBpdikgY29uc3RydWN0b3IgdGVzdGluZy4gQ2hlY2tzIHRoYXQKKyAgICAgKiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcyB0aHJvd24gaW4gdGhlIGNhc2Ugb2YgbnVsbCBpbnB1dAorICAgICAqIGFycmF5IGFuZCB0aGF0IGlucHV0IGFycmF5IGlzIGNvcGllZCBkdXJpbmcgaW5pdGlhbGl6YXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEl2UGFyYW1ldGVyU3BlYzEoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSXZQYXJhbWV0ZXJTcGVjKG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHJhaXNlIGFuIE51bGxQb2ludGVyRXhjZXB0aW9uICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gdGhlIGNhc2Ugb2YgbnVsbCBieXRlIGFycmF5LiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGVbXSBpdiA9IG5ldyBieXRlW10gezEsIDIsIDMsIDQsIDV9OworICAgICAgICBJdlBhcmFtZXRlclNwZWMgaXZwcyA9IG5ldyBJdlBhcmFtZXRlclNwZWMoaXYpOworICAgICAgICBpdlswXSArKzsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBjaGFuZ2Ugb2YgaW5wdXQgYXJyYXkncyBjb250ZW50IHNob3VsZCBub3QgY2F1c2UgIgorICAgICAgICAgICAgICAgICAgICArICJ0aGUgY2hhbmdlIG9mIGludGVybmFsIGFycmF5IiwgaXZbMF0gPT0gaXZwcy5nZXRJVigpWzBdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJdlBhcmFtZXRlclNwZWMoYnl0ZVtdIGl2KSBjb25zdHJ1Y3RvciB0ZXN0aW5nLiBDaGVja3MgdGhhdAorICAgICAqIE51bGxQb2ludGVyRXhjZXB0aW9uIGlzIHRocm93biBpbiB0aGUgY2FzZSBvZiBudWxsIGlucHV0CisgICAgICogYXJyYXkgYW5kIHRoYXQgaW5wdXQgYXJyYXkgaXMgY29waWVkIGR1cmluZyBpbml0aWFsaXphdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXZQYXJhbWV0ZXJTcGVjMigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBJdlBhcmFtZXRlclNwZWMobnVsbCwgMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgcmFpc2UgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gdGhlIGNhc2Ugb2YgbnVsbCBieXRlIGFycmF5LiIpOworICAgICAgICB9IGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyB0aHJvd24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSXZQYXJhbWV0ZXJTcGVjKG5ldyBieXRlW10gezEsIDIsIDN9LCAyLCAyKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCByYWlzZSBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gIgorICAgICAgICAgICAgICAgICAgICArICJpZiAoaXYubGVuZ3RoIC0gb2Zmc2V0IDwgbGVuKS4iKTsKKyAgICAgICAgfSBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIHRocm93biIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEl2UGFyYW1ldGVyU3BlYyhuZXcgYnl0ZVtdIHsxLCAyLCAzfSwgLTEsIDEpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHJhaXNlIGFuIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiAiCisgICAgICAgICAgICAgICAgICAgICsgImlmIG9mZnNldCBpbmRleCBieXRlcyBvdXRzaWRlIHRoZSBpdi4iKTsKKyAgICAgICAgfSBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKworICAgICAgICAvKiBUT0RPOiBEUkwgZmFpbCB3aXRoIGphdmEubGFuZy5OZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbgorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEl2UGFyYW1ldGVyU3BlYyhuZXcgYnl0ZVtdIHsxLCAyLCAzfSwgMSwgLTIpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHJhaXNlIGFuIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiAiCisgICAgICAgICAgICAgICAgICAgICsgImlmIGxlbiBpbmRleCBieXRlcyBvdXRzaWRlIHRoZSBpdi4iKTsKKyAgICAgICAgfSBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKyAgICAgICAgKi8KKworICAgICAgICBieXRlW10gaXYgPSBuZXcgYnl0ZVtdIHsxLCAyLCAzLCA0LCA1fTsKKyAgICAgICAgSXZQYXJhbWV0ZXJTcGVjIGl2cHMgPSBuZXcgSXZQYXJhbWV0ZXJTcGVjKGl2LCAwLCBpdi5sZW5ndGgpOworICAgICAgICBpdlswXSArKzsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBjaGFuZ2Ugb2YgaW5wdXQgYXJyYXkncyBjb250ZW50IHNob3VsZCBub3QgY2F1c2UgIgorICAgICAgICAgICAgICAgICAgICArICJ0aGUgY2hhbmdlIG9mIGludGVybmFsIGFycmF5IiwgaXZbMF0gPT0gaXZwcy5nZXRJVigpWzBdKTsKKworICAgICAgICAvL1JlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMTA4OQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEl2UGFyYW1ldGVyU3BlYyhuZXcgYnl0ZVsyXSwgMiwgIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldElWKCkgeworICAgICAgICBieXRlW10gaXYgPSBuZXcgYnl0ZVtdIHsxLCAyLCAzLCA0LCA1fTsKKyAgICAgICAgSXZQYXJhbWV0ZXJTcGVjIGl2cHMgPSBuZXcgSXZQYXJhbWV0ZXJTcGVjKGl2KTsKKyAgICAgICAgaXYgPSBpdnBzLmdldElWKCk7CisgICAgICAgIGl2WzBdICsrOworICAgICAgICBhc3NlcnRGYWxzZSgiVGhlIGNoYW5nZSBvZiByZXR1cm5lZCBhcnJheSBzaG91bGQgbm90IGNhdXNlICIKKyAgICAgICAgICAgICAgICAgICAgKyAidGhlIGNoYW5nZSBvZiBpbnRlcm5hbCBhcnJheSIsIGl2WzBdID09IGl2cHMuZ2V0SVYoKVswXSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBUZXN0IHN1aXRlKCkgeworICAgICAgICByZXR1cm4gbmV3IFRlc3RTdWl0ZShJdlBhcmFtZXRlclNwZWNUZXN0LmNsYXNzKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL09BRVBQYXJhbWV0ZXJTcGVjVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NwZWMvT0FFUFBhcmFtZXRlclNwZWNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2UwZWEyZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL09BRVBQYXJhbWV0ZXJTcGVjVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTYxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5NR0YxUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKKworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLk9BRVBQYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLlBTb3VyY2U7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworLyoqCisgKi8KK3B1YmxpYyBjbGFzcyBPQUVQUGFyYW1ldGVyU3BlY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBPQUVQUGFyYW1ldGVyU3BlYyhTdHJpbmcgbWROYW1lLCBTdHJpbmcgbWdmTmFtZSwgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYworICAgICAqIG1nZlNwZWMsIFBTb3VyY2UgcFNyYykgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIHRoYXQgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiBpcyB0aHJvd24gaW4gdGhlIGNhc2Ugb2YgaW5hcHByb3ByaWF0ZSBjb25zdHJ1Y3RvciBwYXJhbWV0ZXJzIGFuZCBjaGVja3MKKyAgICAgKiB0aGUgdmFsdWUgb2YgREVGQVVMVCBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0T0FFUFBhcmFtZXRlclNwZWMoKSB7CisgICAgICAgIC8vIHVzaW5nIGluaXQgdmFsdWVzIGZvciBPQUVQUGFyYW1ldGVyU3BlYy5ERUZBVUxUCisgICAgICAgIFN0cmluZyBtZE5hbWUgPSAiU0hBLTEiOworICAgICAgICBTdHJpbmcgbWdmTmFtZSA9ICJNR0YxIjsKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBtZ2ZTcGVjID0gTUdGMVBhcmFtZXRlclNwZWMuU0hBMTsKKyAgICAgICAgUFNvdXJjZSBwU3JjID0gUFNvdXJjZS5QU3BlY2lmaWVkLkRFRkFVTFQ7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBPQUVQUGFyYW1ldGVyU3BlYyhudWxsLCBtZ2ZOYW1lLCBtZ2ZTcGVjLCBwU3JjKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gaW4gdGhlIGNhc2Ugb2YgIgorICAgICAgICAgICAgICAgICAgICArICJudWxsIG1kTmFtZS4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBPQUVQUGFyYW1ldGVyU3BlYyhtZE5hbWUsIG51bGwsIG1nZlNwZWMsIHBTcmMpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biBpbiB0aGUgY2FzZSBvZiAiCisgICAgICAgICAgICAgICAgICAgICsgIm51bGwgbWdmTmFtZS4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBPQUVQUGFyYW1ldGVyU3BlYyhtZE5hbWUsIG1nZk5hbWUsIG1nZlNwZWMsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biBpbiB0aGUgY2FzZSBvZiAiCisgICAgICAgICAgICAgICAgICAgICsgIm51bGwgcFNyYy4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIG1lc3NhZ2UgZGlnZXN0IGFsZ29yaXRobSBuYW1lIG9mICIKKyAgICAgICAgICAgICAgICArICJPQUVQUGFyYW1ldGVyU3BlYy5ERUZBVUxUIGZpZWxkIHNob3VsZCBiZSAiICsgbWROYW1lLAorICAgICAgICAgICAgICAgIE9BRVBQYXJhbWV0ZXJTcGVjLkRFRkFVTFQuZ2V0RGlnZXN0QWxnb3JpdGhtKCkuZXF1YWxzKG1kTmFtZSkpOworCisgICAgICAgIGFzc2VydFRydWUoIlRoZSBtYXNrIGdlbmVyYXRpb24gZnVuY3Rpb24gYWxnb3JpdGhtIG5hbWUgb2YgIgorICAgICAgICAgICAgICAgICsgIk9BRVBQYXJhbWV0ZXJTcGVjLkRFRkFVTFQgZmllbGQgc2hvdWxkIGJlICIgKyBtZ2ZOYW1lLAorICAgICAgICAgICAgICAgIE9BRVBQYXJhbWV0ZXJTcGVjLkRFRkFVTFQuZ2V0TUdGQWxnb3JpdGhtKCkuZXF1YWxzKG1nZk5hbWUpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgbWFzayBnZW5lcmF0aW9uIGZ1bmN0aW9uIHBhcmFtZXRlcnMgb2YgIgorICAgICAgICAgICAgICAgICsgIk9BRVBQYXJhbWV0ZXJTcGVjLkRFRkFVTFQgZmllbGQgc2hvdWxkIGJlIHRoZSBzYW1lIG9iamVjdCAiCisgICAgICAgICAgICAgICAgKyAiYXMgTUdGMVBhcmFtZXRlclNwZWMuU0hBMSIsCisgICAgICAgICAgICAgICAgT0FFUFBhcmFtZXRlclNwZWMuREVGQVVMVC5nZXRNR0ZQYXJhbWV0ZXJzKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PSBNR0YxUGFyYW1ldGVyU3BlYy5TSEExKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIHNvdXJjZSBvZiB0aGUgZW5jb2RpbmcgaW5wdXQgUCBvZiAiCisgICAgICAgICAgICAgICAgKyAiT0FFUFBhcmFtZXRlclNwZWMuREVGQVVMVCBmaWVsZCBzaG91bGQgYmUgdGhlIHNhbWUgb2JqZWN0ICIKKyAgICAgICAgICAgICAgICArICJQU291cmNlLlBTcGVjaWZpZWQuREVGQVVMVCIsCisgICAgICAgICAgICAgICAgT0FFUFBhcmFtZXRlclNwZWMuREVGQVVMVC5nZXRQU291cmNlKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID09IFBTb3VyY2UuUFNwZWNpZmllZC5ERUZBVUxUKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXREaWdlc3RBbGdvcml0aG0oKSBtZXRob2QgdGVzdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RGlnZXN0QWxnb3JpdGhtKCkgeworICAgICAgICBTdHJpbmcgbWROYW1lID0gIlNIQS0xIjsKKyAgICAgICAgU3RyaW5nIG1nZk5hbWUgPSAiTUdGMSI7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgbWdmU3BlYyA9IE1HRjFQYXJhbWV0ZXJTcGVjLlNIQTE7CisgICAgICAgIFBTb3VyY2UgcFNyYyA9IFBTb3VyY2UuUFNwZWNpZmllZC5ERUZBVUxUOworCisgICAgICAgIE9BRVBQYXJhbWV0ZXJTcGVjIHBzID0gbmV3IE9BRVBQYXJhbWV0ZXJTcGVjKG1kTmFtZSwgbWdmTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZ2ZTcGVjLCBwU3JjKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIHJldHVybmVkIHZhbHVlIGRvZXMgbm90IGVxdWFsIHRvIHRoZSAiCisgICAgICAgICAgICAgICAgKyAidmFsdWUgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3Rvci4iLAorICAgICAgICAgICAgICAgIHBzLmdldERpZ2VzdEFsZ29yaXRobSgpLmVxdWFscyhtZE5hbWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRNR0ZBbGdvcml0aG0oKSBtZXRob2QgdGVzdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TUdGQWxnb3JpdGhtKCkgeworICAgICAgICBTdHJpbmcgbWROYW1lID0gIlNIQS0xIjsKKyAgICAgICAgU3RyaW5nIG1nZk5hbWUgPSAiTUdGMSI7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgbWdmU3BlYyA9IE1HRjFQYXJhbWV0ZXJTcGVjLlNIQTE7CisgICAgICAgIFBTb3VyY2UgcFNyYyA9IFBTb3VyY2UuUFNwZWNpZmllZC5ERUZBVUxUOworCisgICAgICAgIE9BRVBQYXJhbWV0ZXJTcGVjIHBzID0gbmV3IE9BRVBQYXJhbWV0ZXJTcGVjKG1kTmFtZSwgbWdmTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZ2ZTcGVjLCBwU3JjKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIHJldHVybmVkIHZhbHVlIGRvZXMgbm90IGVxdWFsIHRvIHRoZSAiCisgICAgICAgICAgICAgICAgKyAidmFsdWUgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3Rvci4iLAorICAgICAgICAgICAgICAgIHBzLmdldE1HRkFsZ29yaXRobSgpLmVxdWFscyhtZ2ZOYW1lKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0TUdGUGFyYW1ldGVycygpIG1ldGhvZCB0ZXN0aW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRNR0ZQYXJhbWV0ZXJzKCkgeworICAgICAgICBTdHJpbmcgbWROYW1lID0gIlNIQS0xIjsKKyAgICAgICAgU3RyaW5nIG1nZk5hbWUgPSAiTUdGMSI7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgbWdmU3BlYyA9IE1HRjFQYXJhbWV0ZXJTcGVjLlNIQTE7CisgICAgICAgIFBTb3VyY2UgcFNyYyA9IFBTb3VyY2UuUFNwZWNpZmllZC5ERUZBVUxUOworCisgICAgICAgIE9BRVBQYXJhbWV0ZXJTcGVjIHBzID0gbmV3IE9BRVBQYXJhbWV0ZXJTcGVjKG1kTmFtZSwgbWdmTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZ2ZTcGVjLCBwU3JjKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIHJldHVybmVkIHZhbHVlIGRvZXMgbm90IGVxdWFsIHRvIHRoZSAiCisgICAgICAgICAgICAgICAgKyAidmFsdWUgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3Rvci4iLAorICAgICAgICAgICAgICAgIHBzLmdldE1HRlBhcmFtZXRlcnMoKSA9PSBtZ2ZTcGVjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRQU291cmNlKCkgbWV0aG9kIHRlc3RpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldFBTb3VyY2UoKSB7CisgICAgICAgIFN0cmluZyBtZE5hbWUgPSAiU0hBLTEiOworICAgICAgICBTdHJpbmcgbWdmTmFtZSA9ICJNR0YxIjsKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBtZ2ZTcGVjID0gTUdGMVBhcmFtZXRlclNwZWMuU0hBMTsKKyAgICAgICAgUFNvdXJjZSBwU3JjID0gUFNvdXJjZS5QU3BlY2lmaWVkLkRFRkFVTFQ7CisKKyAgICAgICAgT0FFUFBhcmFtZXRlclNwZWMgcHMgPSBuZXcgT0FFUFBhcmFtZXRlclNwZWMobWROYW1lLCBtZ2ZOYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1nZlNwZWMsIHBTcmMpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgcmV0dXJuZWQgdmFsdWUgZG9lcyBub3QgZXF1YWwgdG8gdGhlICIKKyAgICAgICAgICAgICAgICArICJ2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yLiIsCisgICAgICAgICAgICAgICAgcHMuZ2V0UFNvdXJjZSgpID09IHBTcmMpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgVGVzdCBzdWl0ZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBUZXN0U3VpdGUoT0FFUFBhcmFtZXRlclNwZWNUZXN0LmNsYXNzKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL1BCRUtleVNwZWNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc3BlYy9QQkVLZXlTcGVjVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg1ZTQyOWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc3BlYy9QQkVLZXlTcGVjVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzA1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5QQkVLZXlTcGVjOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKKy8qKgorICovCitwdWJsaWMgY2xhc3MgUEJFS2V5U3BlY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBQQkVLZXlTcGVjKGNoYXJbXSBwYXNzd29yZCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIHRoZSBiZWhhdmlvciBvZgorICAgICAqIHRoZSBtZXRob2QgaW4gdGhlIGNhc2Ugb2YgbnVsbCBpbnB1dCBjaGFyIGFycmF5IGFuZCB0ZXN0cyB0aGF0IGlucHV0CisgICAgICogYXJyYXkgaXMgY29waWVkIGR1cmluZyB0aGUgb2JqZWN0IGluaXRpYWxpemF0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RQQkVLZXlTcGVjMSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFBCRUtleVNwZWMgcGJla3MgPSBuZXcgUEJFS2V5U3BlYyhudWxsKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFuIGVtcHR5IGNoYXJbXSBzaG91bGQgYmUgdXNlZCBpbiBjYXNlIG9mIG51bGwgIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAiY2hhciBhcnJheS4iLCBwYmVrcy5nZXRQYXNzd29yZCgpLmxlbmd0aCA9PSAwKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisKKyAgICAgICAgY2hhcltdIHBhc3N3b3JkID0gbmV3IGNoYXJbXSB7JzEnLCAnMicsICczJywgJzQnLCAnNSd9OworICAgICAgICBQQkVLZXlTcGVjIHBiZWtzID0gbmV3IFBCRUtleVNwZWMocGFzc3dvcmQpOworICAgICAgICBwYXNzd29yZFswXSArKzsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBjaGFuZ2Ugb2YgcGFzc3dvcmQgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciAiCisgICAgICAgICAgICAgICAgICAgICsgInNob3VsZCBub3QgY2F1c2UgdGhlIGNoYW5nZSBvZiBpbnRlcm5hbCBhcnJheS4iLAorICAgICAgICAgICAgICAgICAgICBwYXNzd29yZFswXSA9PSBwYmVrcy5nZXRQYXNzd29yZCgpWzBdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQQkVLZXlTcGVjKGNoYXJbXSBwYXNzd29yZCwgYnl0ZVtdIHNhbHQsIGludCBpdGVyYXRpb25Db3VudCwgaW50CisgICAgICoga2V5TGVuZ3RoKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhlIGJlaGF2aW9yIG9mIHRoZSBtZXRob2QgaW4gdGhlIGNhc2UKKyAgICAgKiBvZiBpbmFwcHJvcHJpYXRlIHBhcmFtZXRlcnMgYW5kIGNoZWNrcyB0aGF0IGFycmF5IG9iamVjdHMgc3BlY2lmaWVkIGFzCisgICAgICogYSBwYXJhbWV0ZXJzIGFyZSBjb3BpZWQgZHVyaW5nIHRoZSBvYmplY3QgaW5pdGlhbGl6YXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFBCRUtleVNwZWMyKCkgeworICAgICAgICBjaGFyW10gcGFzc3dvcmQgPSBuZXcgY2hhcltdIHsnMScsICcyJywgJzMnLCAnNCcsICc1J307CisgICAgICAgIGJ5dGVbXSBzYWx0ID0gbmV3IGJ5dGVbXSB7MSwgMiwgMywgNCwgNX07CisgICAgICAgIGludCBpdGVyYXRpb25Db3VudCA9IDEwOworICAgICAgICBpbnQga2V5TGVuZ3RoID0gMTA7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFBCRUtleVNwZWMgcGJla3MgPSBuZXcgUEJFS2V5U3BlYyhudWxsLCBzYWx0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlcmF0aW9uQ291bnQsIGtleUxlbmd0aCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJBbiBlbXB0eSBjaGFyW10gc2hvdWxkIGJlIHVzZWQgaW4gY2FzZSBvZiBudWxsIGlucHV0ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgImNoYXIgYXJyYXkuIiwgcGJla3MuZ2V0UGFzc3dvcmQoKS5sZW5ndGggPT0gMCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFBCRUtleVNwZWMocGFzc3dvcmQsIG51bGwsIGl0ZXJhdGlvbkNvdW50LCBrZXlMZW5ndGgpOworICAgICAgICAgICAgZmFpbCgiQSBOdWxsUG9pbnRlckV4Y2VwdGlvbiBzaG91bGQgYmUgd2FzIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIG51bGwgc2FsdC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUEJFS2V5U3BlYyhwYXNzd29yZCwgbmV3IGJ5dGUgWzBdLCBpdGVyYXRpb25Db3VudCwga2V5TGVuZ3RoKTsKKyAgICAgICAgICAgIGZhaWwoIkFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gdGhlIGNhc2Ugb2YgZW1wdHkgc2FsdC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUEJFS2V5U3BlYyhwYXNzd29yZCwgc2FsdCwgLTEsIGtleUxlbmd0aCk7CisgICAgICAgICAgICBmYWlsKCJBbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIG5lZ2F0aXZlIGl0ZXJhdGlvbkNvdW50LiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBQQkVLZXlTcGVjKHBhc3N3b3JkLCBzYWx0LCBpdGVyYXRpb25Db3VudCwgLTEpOworICAgICAgICAgICAgZmFpbCgiQW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gIgorICAgICAgICAgICAgICAgICAgICArICJpbiB0aGUgY2FzZSBvZiBuZWdhdGl2ZSBrZXlMZW5ndGguIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFBCRUtleVNwZWMocGFzc3dvcmQsIHNhbHQsIDAsIGtleUxlbmd0aCk7CisgICAgICAgICAgICBmYWlsKCJBbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIHplcm8gaXRlcmF0aW9uQ291bnQuIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFBCRUtleVNwZWMocGFzc3dvcmQsIHNhbHQsIGl0ZXJhdGlvbkNvdW50LCAwKTsKKyAgICAgICAgICAgIGZhaWwoIkFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gdGhlIGNhc2Ugb2YgemVybyBrZXlMZW5ndGguIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBQQkVLZXlTcGVjIHBiZWtzID0gbmV3IFBCRUtleVNwZWMocGFzc3dvcmQsIHNhbHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVyYXRpb25Db3VudCwga2V5TGVuZ3RoKTsKKyAgICAgICAgcGFzc3dvcmRbMF0gKys7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2hhbmdlIG9mIHBhc3N3b3JkIHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3IgIgorICAgICAgICAgICAgICAgICAgICArICJzaG91bGQgbm90IGNhdXNlIHRoZSBjaGFuZ2Ugb2YgaW50ZXJuYWwgYXJyYXkuIiwKKyAgICAgICAgICAgICAgICAgICAgcGFzc3dvcmRbMF0gPT0gcGJla3MuZ2V0UGFzc3dvcmQoKVswXSk7CisgICAgICAgIHNhbHRbMF0gKys7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2hhbmdlIG9mIHNhbHQgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciAiCisgICAgICAgICAgICAgICAgICAgICsgIiBzaG91bGQgbm90IGNhdXNlIHRoZSBjaGFuZ2Ugb2YgaW50ZXJuYWwgYXJyYXkuIiwKKyAgICAgICAgICAgICAgICAgICAgc2FsdFswXSA9PSBwYmVrcy5nZXRTYWx0KClbMF0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBCRUtleVNwZWMoY2hhcltdIHBhc3N3b3JkLCBieXRlW10gc2FsdCwgaW50IGl0ZXJhdGlvbkNvdW50KSBtZXRob2QKKyAgICAgKiB0ZXN0aW5nLiBUZXN0cyB0aGUgYmVoYXZpb3Igb2YgdGhlIG1ldGhvZCBpbiB0aGUgY2FzZQorICAgICAqIG9mIGluYXBwcm9wcmlhdGUgcGFyYW1ldGVycyBhbmQgY2hlY2tzIHRoYXQgYXJyYXkgb2JqZWN0cyBzcGVjaWZpZWQgYXMKKyAgICAgKiBhIHBhcmFtZXRlcnMgYXJlIGNvcGllZCBkdXJpbmcgdGhlIG9iamVjdCBpbml0aWFsaXphdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UEJFS2V5U3BlYzMoKSB7CisgICAgICAgIGNoYXJbXSBwYXNzd29yZCA9IG5ldyBjaGFyW10geycxJywgJzInLCAnMycsICc0JywgJzUnfTsKKyAgICAgICAgYnl0ZVtdIHNhbHQgPSBuZXcgYnl0ZVtdIHsxLCAyLCAzLCA0LCA1fTsKKyAgICAgICAgaW50IGl0ZXJhdGlvbkNvdW50ID0gMTA7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFBCRUtleVNwZWMgcGJla3MgPSBuZXcgUEJFS2V5U3BlYyhudWxsLCBzYWx0LCBpdGVyYXRpb25Db3VudCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJBbiBlbXB0eSBjaGFyW10gc2hvdWxkIGJlIHVzZWQgaW4gY2FzZSBvZiBudWxsIGlucHV0ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgImNoYXIgYXJyYXkuIiwgcGJla3MuZ2V0UGFzc3dvcmQoKS5sZW5ndGggPT0gMCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFBCRUtleVNwZWMocGFzc3dvcmQsIG51bGwsIGl0ZXJhdGlvbkNvdW50KTsKKyAgICAgICAgICAgIGZhaWwoIkEgTnVsbFBvaW50ZXJFeGNlcHRpb24gc2hvdWxkIGJlIHdhcyB0aHJvd24gIgorICAgICAgICAgICAgICAgICAgICArICJpbiB0aGUgY2FzZSBvZiBudWxsIHNhbHQuIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFBCRUtleVNwZWMocGFzc3dvcmQsIG5ldyBieXRlIFswXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXJhdGlvbkNvdW50KTsKKyAgICAgICAgICAgIGZhaWwoIkFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gdGhlIGNhc2Ugb2YgZW1wdHkgc2FsdC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUEJFS2V5U3BlYyhwYXNzd29yZCwgc2FsdCwgLTEpOworICAgICAgICAgICAgZmFpbCgiQW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gIgorICAgICAgICAgICAgICAgICAgICArICJpbiB0aGUgY2FzZSBvZiBuZWdhdGl2ZSBpdGVyYXRpb25Db3VudC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUEJFS2V5U3BlYyhwYXNzd29yZCwgc2FsdCwgMCk7CisgICAgICAgICAgICBmYWlsKCJBbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIHplcm8gaXRlcmF0aW9uQ291bnQuIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBQQkVLZXlTcGVjIHBiZWtzID0gbmV3IFBCRUtleVNwZWMocGFzc3dvcmQsIHNhbHQsIGl0ZXJhdGlvbkNvdW50KTsKKyAgICAgICAgcGFzc3dvcmRbMF0gKys7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2hhbmdlIG9mIHBhc3N3b3JkIHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3IgIgorICAgICAgICAgICAgICAgICAgICArICJzaG91bGQgbm90IGNhdXNlIHRoZSBjaGFuZ2Ugb2YgaW50ZXJuYWwgYXJyYXkuIiwKKyAgICAgICAgICAgICAgICAgICAgcGFzc3dvcmRbMF0gPT0gcGJla3MuZ2V0UGFzc3dvcmQoKVswXSk7CisgICAgICAgIHNhbHRbMF0gKys7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2hhbmdlIG9mIHNhbHQgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciAiCisgICAgICAgICAgICAgICAgICAgICsgIiBzaG91bGQgbm90IGNhdXNlIHRoZSBjaGFuZ2Ugb2YgaW50ZXJuYWwgYXJyYXkuIiwKKyAgICAgICAgICAgICAgICAgICAgc2FsdFswXSA9PSBwYmVrcy5nZXRTYWx0KClbMF0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIGNsZWFyUGFzc3dvcmQoKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhhdCBpbnRlcm5hbCBjb3B5IG9mIHBhc3N3b3JkCisgICAgICogaXMgY2xlYXJlZCBhZnRlciB0aGUgbWV0aG9kIGNhbGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENsZWFyUGFzc3dvcmQoKSB7CisgICAgICAgIGNoYXJbXSBwYXNzd29yZCA9IG5ldyBjaGFyW10geycxJywgJzInLCAnMycsICc0JywgJzUnfTsKKyAgICAgICAgUEJFS2V5U3BlYyBwYmVrcyA9IG5ldyBQQkVLZXlTcGVjKHBhc3N3b3JkKTsKKyAgICAgICAgcGJla3MuY2xlYXJQYXNzd29yZCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGJla3MuZ2V0UGFzc3dvcmQoKTsKKyAgICAgICAgICAgIGZhaWwoIkFuIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBzaG91bGQgYmUgd2FzIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImFmdGVyIHRoZSBjbGVhcmluZyB0aGUgcGFzc3dvcmQuIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRQYXNzd29yZCgpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGF0IHJldHVybmVkIHBhc3N3b3JkIGlzIGVxdWFsCisgICAgICogdG8gdGhlIHBhc3N3b3JkIHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3IgYW5kIHRoYXQgdGhlIGNoYW5nZSBvZgorICAgICAqIHJldHVybmVkIGFycmF5IGRvZXMgbm90IGNhdXNlIHRoZSBjaGFuZ2Ugb2YgaW50ZXJuYWwgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldFBhc3N3b3JkKCkgeworICAgICAgICBjaGFyW10gcGFzc3dvcmQgPSBuZXcgY2hhcltdIHsnMScsICcyJywgJzMnLCAnNCcsICc1J307CisgICAgICAgIFBCRUtleVNwZWMgcGJla3MgPSBuZXcgUEJFS2V5U3BlYyhwYXNzd29yZCk7CisgICAgICAgIGNoYXJbXSByZXN1bHQgPSBwYmVrcy5nZXRQYXNzd29yZCgpOworICAgICAgICBpZiAoISBBcnJheXMuZXF1YWxzKHBhc3N3b3JkLCByZXN1bHQpKSB7CisgICAgICAgICAgICBmYWlsKCJUaGUgcmV0dXJuZWQgcGFzc3dvcmQgaXMgbm90IGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQgIgorICAgICAgICAgICAgICAgICAgICArICJpbiB0aGUgY29uc3RydWN0b3IuIik7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0WzBdICsrOworICAgICAgICBhc3NlcnRGYWxzZSgiVGhlIGNoYW5nZSBvZiByZXR1cm5lZCBieSBnZXRQYXNzd29yZCgpIG1ldGhvZCBwYXNzd29yZCAiCisgICAgICAgICAgICAgICAgICAgICsgInNob3VsZCBub3QgY2F1c2UgdGhlIGNoYW5nZSBvZiBpbnRlcm5hbCBhcnJheS4iLAorICAgICAgICAgICAgICAgICAgICByZXN1bHRbMF0gPT0gcGJla3MuZ2V0UGFzc3dvcmQoKVswXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0U2FsdCgpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGF0IHJldHVybmVkIHNhbHQgaXMgZXF1YWwKKyAgICAgKiB0byB0aGUgc2FsdCBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yIGFuZCB0aGF0IHRoZSBjaGFuZ2Ugb2YKKyAgICAgKiByZXR1cm5lZCBhcnJheSBkb2VzIG5vdCBjYXVzZSB0aGUgY2hhbmdlIG9mIGludGVybmFsIGFycmF5LgorICAgICAqIEFsc28gaXQgY2hlY2tzIHRoYXQgdGhlIG1ldGhvZCByZXR1cm5zIG51bGwgaWYgc2FsdCBpcyBub3QKKyAgICAgKiBzcGVjaWZpZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldFNhbHQoKSB7CisgICAgICAgIGNoYXJbXSBwYXNzd29yZCA9IG5ldyBjaGFyW10geycxJywgJzInLCAnMycsICc0JywgJzUnfTsKKyAgICAgICAgYnl0ZVtdIHNhbHQgPSBuZXcgYnl0ZVtdIHsxLCAyLCAzLCA0LCA1fTsKKyAgICAgICAgaW50IGl0ZXJhdGlvbkNvdW50ID0gMTA7CisgICAgICAgIFBCRUtleVNwZWMgcGJla3MgPSBuZXcgUEJFS2V5U3BlYyhwYXNzd29yZCwgc2FsdCwgaXRlcmF0aW9uQ291bnQpOworICAgICAgICBieXRlW10gcmVzdWx0ID0gcGJla3MuZ2V0U2FsdCgpOworICAgICAgICBpZiAoISBBcnJheXMuZXF1YWxzKHNhbHQsIHJlc3VsdCkpIHsKKyAgICAgICAgICAgIGZhaWwoIlRoZSByZXR1cm5lZCBzYWx0IGlzIG5vdCBlcXVhbCB0byB0aGUgc3BlY2lmaWVkICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gdGhlIGNvbnN0cnVjdG9yLiIpOworICAgICAgICB9CisgICAgICAgIHJlc3VsdFswXSArKzsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBjaGFuZ2Ugb2YgcmV0dXJuZWQgYnkgZ2V0U2FsdCgpIG1ldGhvZCBzYWx0IgorICAgICAgICAgICAgICAgICAgICArICJzaG91bGQgbm90IGNhdXNlIHRoZSBjaGFuZ2Ugb2YgaW50ZXJuYWwgYXJyYXkuIiwKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0WzBdID09IHBiZWtzLmdldFNhbHQoKVswXSk7CisgICAgICAgIHBiZWtzID0gbmV3IFBCRUtleVNwZWMocGFzc3dvcmQpOworICAgICAgICBhc3NlcnROdWxsKCJUaGUgZ2V0U2FsdCgpIG1ldGhvZCBzaG91bGQgcmV0dXJuIG51bGwgaWYgdGhlIHNhbHQgIgorICAgICAgICAgICAgICAgICAgICArICJpcyBub3Qgc3BlY2lmaWVkLiIsIHBiZWtzLmdldFNhbHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0SXRlcmF0aW9uQ291bnQoKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhhdCByZXR1cm5lZCB2YWx1ZSBpcyBlcXVhbAorICAgICAqIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yLgorICAgICAqIEFsc28gaXQgY2hlY2tzIHRoYXQgdGhlIG1ldGhvZCByZXR1cm5zIDAgaWYgaXRlcmF0aW9uQ291bnQgaXMgbm90CisgICAgICogc3BlY2lmaWVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJdGVyYXRpb25Db3VudCgpIHsKKyAgICAgICAgY2hhcltdIHBhc3N3b3JkID0gbmV3IGNoYXJbXSB7JzEnLCAnMicsICczJywgJzQnLCAnNSd9OworICAgICAgICBieXRlW10gc2FsdCA9IG5ldyBieXRlW10gezEsIDIsIDMsIDQsIDV9OworICAgICAgICBpbnQgaXRlcmF0aW9uQ291bnQgPSAxMDsKKyAgICAgICAgUEJFS2V5U3BlYyBwYmVrcyA9IG5ldyBQQkVLZXlTcGVjKHBhc3N3b3JkLCBzYWx0LCBpdGVyYXRpb25Db3VudCk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSByZXR1cm5lZCBpdGVyYXRpb25Db3VudCBpcyBub3QgZXF1YWwgdG8gdGhlIHNwZWNpZmllZCAiCisgICAgICAgICAgICAgICAgKyAiaW4gdGhlIGNvbnN0cnVjdG9yLiIsCisgICAgICAgICAgICAgICAgcGJla3MuZ2V0SXRlcmF0aW9uQ291bnQoKSA9PSBpdGVyYXRpb25Db3VudCk7CisgICAgICAgIHBiZWtzID0gbmV3IFBCRUtleVNwZWMocGFzc3dvcmQpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgZ2V0SXRlcmF0aW9uQ291bnQoKSBtZXRob2Qgc2hvdWxkIHJldHVybiAwICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaWYgdGhlIGl0ZXJhdGlvbkNvdW50IGlzIG5vdCBzcGVjaWZpZWQuIiwKKyAgICAgICAgICAgICAgICAgICAgcGJla3MuZ2V0SXRlcmF0aW9uQ291bnQoKSA9PSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRLZXlMZW5ndGgoKSBtZXRob2QgdGVzdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0S2V5TGVuZ3RoKCkgeworICAgICAgICBjaGFyW10gcGFzc3dvcmQgPSBuZXcgY2hhcltdIHsnMScsICcyJywgJzMnLCAnNCcsICc1J307CisgICAgICAgIGJ5dGVbXSBzYWx0ID0gbmV3IGJ5dGVbXSB7MSwgMiwgMywgNCwgNX07CisgICAgICAgIGludCBpdGVyYXRpb25Db3VudCA9IDEwOworICAgICAgICBpbnQga2V5TGVuZ3RoID0gMTA7CisgICAgICAgIFBCRUtleVNwZWMgcGJla3MgPSBuZXcgUEJFS2V5U3BlYyhwYXNzd29yZCwgc2FsdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXJhdGlvbkNvdW50LCBrZXlMZW5ndGgpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgcmV0dXJuZWQga2V5TGVuZ3RoIGlzIG5vdCBlcXVhbCB0byB0aGUgdmFsdWUgc3BlY2lmaWVkICIKKyAgICAgICAgICAgICAgICArICJpbiB0aGUgY29uc3RydWN0b3IuIiwKKyAgICAgICAgICAgICAgICBwYmVrcy5nZXRLZXlMZW5ndGgoKSA9PSBrZXlMZW5ndGgpOworICAgICAgICBwYmVrcyA9IG5ldyBQQkVLZXlTcGVjKHBhc3N3b3JkKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGdldEtleUxlbmd0aCgpIG1ldGhvZCBzaG91bGQgcmV0dXJuIDAgIgorICAgICAgICAgICAgICAgICAgICArICJpZiB0aGUga2V5TGVuZ3RoIGlzIG5vdCBzcGVjaWZpZWQuIiwKKyAgICAgICAgICAgICAgICAgICAgcGJla3MuZ2V0S2V5TGVuZ3RoKCkgPT0gMCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBUZXN0IHN1aXRlKCkgeworICAgICAgICByZXR1cm4gbmV3IFRlc3RTdWl0ZShQQkVLZXlTcGVjVGVzdC5jbGFzcyk7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc3BlYy9QQkVQYXJhbWV0ZXJTcGVjVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NwZWMvUEJFUGFyYW1ldGVyU3BlY1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NjM5MDk5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NwZWMvUEJFUGFyYW1ldGVyU3BlY1Rlc3QuamF2YQpAQCAtMCwwICsxLDk3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5QQkVQYXJhbWV0ZXJTcGVjOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKKy8qKgorICovCitwdWJsaWMgY2xhc3MgUEJFUGFyYW1ldGVyU3BlY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBQQkVQYXJhbWV0ZXJTcGVjKGJ5dGVbXSBzYWx0LCBpbnQgaXRlcmF0aW9uQ291bnQpIG1ldGhvZCB0ZXN0aW5nLgorICAgICAqIFRlc3RzIHRoZSBiZWhhdmlvciBvZiB0aGUgbWV0aG9kIGluIHRoZSBjYXNlIG9mIG51bGwgaW5wdXQgYXJyYXkKKyAgICAgKiBhbmQgdGVzdHMgdGhhdCBpbnB1dCBhcnJheSBpcyBjb3BpZWQgZHVyaW5nIHRoZSBvYmplY3QgaW5pdGlhbGl6YXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFBCRVBhcmFtZXRlclNwZWMoKSB7CisgICAgICAgIGJ5dGVbXSBzYWx0ID0gezEsIDIsIDMsIDQsIDV9OworICAgICAgICBpbnQgaXRlcmF0aW9uQ291bnQgPSAxMDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFBCRVBhcmFtZXRlclNwZWMobnVsbCwgaXRlcmF0aW9uQ291bnQpOworICAgICAgICAgICAgZmFpbCgiQSBOdWxsUG9pbnRlckV4Y2VwdGlvbiBzaG91bGQgYmUgd2FzIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIG51bGwgc2FsdC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgUEJFUGFyYW1ldGVyU3BlYyBwYmVwcyA9IG5ldyBQQkVQYXJhbWV0ZXJTcGVjKHNhbHQsIGl0ZXJhdGlvbkNvdW50KTsKKyAgICAgICAgc2FsdFswXSArKzsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBjaGFuZ2Ugb2Ygc2FsdCBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yICIKKyAgICAgICAgICAgICAgICAgICAgKyAic2hvdWxkIG5vdCBjYXVzZSB0aGUgY2hhbmdlIG9mIGludGVybmFsIGFycmF5LiIsCisgICAgICAgICAgICAgICAgICAgIHNhbHRbMF0gPT0gcGJlcHMuZ2V0U2FsdCgpWzBdKTsKKyAgIH0KKworICAgIC8qKgorICAgICAqIGdldFNhbHQoKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhhdCByZXR1cm5lZCBzYWx0IGlzIGVxdWFsCisgICAgICogdG8gdGhlIHNhbHQgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciBhbmQgdGhhdCB0aGUgY2hhbmdlIG9mCisgICAgICogcmV0dXJuZWQgYXJyYXkgZG9lcyBub3QgY2F1c2UgdGhlIGNoYW5nZSBvZiBpbnRlcm5hbCBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2FsdCgpIHsKKyAgICAgICAgYnl0ZVtdIHNhbHQgPSBuZXcgYnl0ZVtdIHsxLCAyLCAzLCA0LCA1fTsKKyAgICAgICAgaW50IGl0ZXJhdGlvbkNvdW50ID0gMTA7CisgICAgICAgIFBCRVBhcmFtZXRlclNwZWMgcGJlcHMgPSBuZXcgUEJFUGFyYW1ldGVyU3BlYyhzYWx0LCBpdGVyYXRpb25Db3VudCk7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBwYmVwcy5nZXRTYWx0KCk7CisgICAgICAgIGlmICghIEFycmF5cy5lcXVhbHMoc2FsdCwgcmVzdWx0KSkgeworICAgICAgICAgICAgZmFpbCgiVGhlIHJldHVybmVkIHNhbHQgaXMgbm90IGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQgIgorICAgICAgICAgICAgICAgICAgICArICJpbiB0aGUgY29uc3RydWN0b3IuIik7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0WzBdICsrOworICAgICAgICBhc3NlcnRGYWxzZSgiVGhlIGNoYW5nZSBvZiByZXR1cm5lZCBieSBnZXRTYWx0KCkgbWV0aG9kIHNhbHQiCisgICAgICAgICAgICAgICAgICAgICsgInNob3VsZCBub3QgY2F1c2UgdGhlIGNoYW5nZSBvZiBpbnRlcm5hbCBhcnJheS4iLAorICAgICAgICAgICAgICAgICAgICByZXN1bHRbMF0gPT0gcGJlcHMuZ2V0U2FsdCgpWzBdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRJdGVyYXRpb25Db3VudCgpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGF0IHJldHVybmVkIHZhbHVlIGlzIGVxdWFsCisgICAgICogdG8gdGhlIHZhbHVlIHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEl0ZXJhdGlvbkNvdW50KCkgeworICAgICAgICBieXRlW10gc2FsdCA9IG5ldyBieXRlW10gezEsIDIsIDMsIDQsIDV9OworICAgICAgICBpbnQgaXRlcmF0aW9uQ291bnQgPSAxMDsKKyAgICAgICAgUEJFUGFyYW1ldGVyU3BlYyBwYmVwcyA9IG5ldyBQQkVQYXJhbWV0ZXJTcGVjKHNhbHQsIGl0ZXJhdGlvbkNvdW50KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIHJldHVybmVkIGl0ZXJhdGlvbkNvdW50IGlzIG5vdCBlcXVhbCB0byB0aGUgc3BlY2lmaWVkICIKKyAgICAgICAgICAgICAgICArICJpbiB0aGUgY29uc3RydWN0b3IuIiwKKyAgICAgICAgICAgICAgICBwYmVwcy5nZXRJdGVyYXRpb25Db3VudCgpID09IGl0ZXJhdGlvbkNvdW50KTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFRlc3Qgc3VpdGUoKSB7CisgICAgICAgIHJldHVybiBuZXcgVGVzdFN1aXRlKFBCRVBhcmFtZXRlclNwZWNUZXN0LmNsYXNzKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL1BTb3VyY2VUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc3BlYy9QU291cmNlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJlYWQ1OGMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc3BlYy9QU291cmNlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyAqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuUFNvdXJjZTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCisvKioKKyAqLworcHVibGljIGNsYXNzIFBTb3VyY2VUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogUFNwZWNpZmllZChieXRlW10gcCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIHRoYXQgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiBpcyB0aHJvd24gaW4gdGhlIGNhc2Ugb2YgbnVsbCBwIGFycmF5LiBBbHNvIGl0IGNoZWNrcyB0aGUgdmFsdWUgb2YKKyAgICAgKiBERUZBVUxUIGZpZWxkLCBhbmQgdGhhdCBpbnB1dCBwIGFycmF5IGlzIGNvcGllZCB0byBwcm90ZWN0IGFnYWluc3QKKyAgICAgKiBzdWJzZXF1ZW50IG1vZGlmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UFNwZWNpZmllZCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBQU291cmNlLlBTcGVjaWZpZWQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIGluIHRoZSBjYXNlIG9mICIKKyAgICAgICAgICAgICAgICAgICAgKyAibnVsbCBwIGFycmF5LiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSBQU291cmNlLlBTcGVjaWZpZWQgREVGQVVMVCB2YWx1ZSBzaG91bGQgYmUgYnl0ZVswXSIsCisgICAgICAgICAgICAgICAgMCwgUFNvdXJjZS5QU3BlY2lmaWVkLkRFRkFVTFQuZ2V0VmFsdWUoKS5sZW5ndGgpOworCisgICAgICAgIGJ5dGVbXSBwID0gbmV3IGJ5dGVbXSB7MSwgMiwgMywgNCwgNX07CisgICAgICAgIFBTb3VyY2UuUFNwZWNpZmllZCBwcyA9IG5ldyBQU291cmNlLlBTcGVjaWZpZWQocCk7CisgICAgICAgIHBbMF0rKzsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBjaGFuZ2Ugb2YgcCBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yICIKKyAgICAgICAgICAgICAgICArICJzaG91bGQgbm90IGNhdXNlIHRoZSBjaGFuZ2Ugb2YgaW50ZXJuYWwgYXJyYXkuIiwgcFswXSA9PSBwcworICAgICAgICAgICAgICAgIC5nZXRWYWx1ZSgpWzBdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRWYWx1ZSgpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGF0IHJldHVybmVkIGFycmF5IGlzIGVxdWFsIHRvIHRoZQorICAgICAqIGFycmF5IHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3IuIENoZWNrcyB0aGF0IG1vZGlmaWNhdGlvbgorICAgICAqIG9mIHJldHVybmVkIGFycmF5IGRvZXMgbm90IGFmZmVjdCB0aGUgaW50ZXJuYWwgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldFZhbHVlKCkgeworICAgICAgICBieXRlW10gcCA9IG5ldyBieXRlW10gezEsIDIsIDMsIDQsIDV9OworCisgICAgICAgIFBTb3VyY2UuUFNwZWNpZmllZCBwcyA9IG5ldyBQU291cmNlLlBTcGVjaWZpZWQocCk7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBwcy5nZXRWYWx1ZSgpOworICAgICAgICBpZiAoIUFycmF5cy5lcXVhbHMocCwgcmVzdWx0KSkgeworICAgICAgICAgICAgZmFpbCgiVGhlIHJldHVybmVkIGFycmF5IGRvZXMgbm90IGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQgIgorICAgICAgICAgICAgICAgICAgICArICJpbiB0aGUgY29uc3RydWN0b3IuIik7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0WzBdKys7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2hhbmdlIG9mIHJldHVybmVkIGJ5IGdldFZhbHVlKCkgYXJyYXkgIgorICAgICAgICAgICAgICAgICsgInNob3VsZCBub3QgY2F1c2UgdGhlIGNoYW5nZSBvZiBpbnRlcm5hbCBhcnJheS4iLAorICAgICAgICAgICAgICAgIHJlc3VsdFswXSA9PSBwcy5nZXRWYWx1ZSgpWzBdKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFBTb3VyY2UoU3RyaW5nIHBTcmNOYW1lKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhhdCByZXR1cm5lZCB2YWx1ZSBpcworICAgICAqIGVxdWFsIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RQU291cmNlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFBTb3VyY2UobnVsbCkge307CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIGluIHRoZSBjYXNlIG9mICIKKyAgICAgICAgICAgICAgICAgICAgKyAibnVsbCBwU3JjTmFtZS4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0QWxnb3JpdGhtKCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIHRoYXQgcmV0dXJuZWQgdmFsdWUgaXMKKyAgICAgKiBlcXVhbCB0byB0aGUgdmFsdWUgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0QWxnb3JpdGhtKCkgeworICAgICAgICBTdHJpbmcgcFNyY05hbWUgPSAicFNyY05hbWUiOworICAgICAgICBQU291cmNlIHBzID0gbmV3IFBTb3VyY2UocFNyY05hbWUpIHt9OworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgcmV0dXJuZWQgdmFsdWUgaXMgbm90IGVxdWFsIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWQgIgorICAgICAgICAgICAgICAgICsgImluIGNvbnN0cnVjdG9yIiwgcFNyY05hbWUuZXF1YWxzKHBzLmdldEFsZ29yaXRobSgpKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBUZXN0IHN1aXRlKCkgeworICAgICAgICByZXR1cm4gbmV3IFRlc3RTdWl0ZShQU291cmNlVGVzdC5jbGFzcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NwZWMvUkMyUGFyYW1ldGVyU3BlY1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL1JDMlBhcmFtZXRlclNwZWNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjRiMjg5NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL1JDMlBhcmFtZXRlclNwZWNUZXN0LmphdmEKQEAgLTAsMCArMSwyMDkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLmphdmF4LmNyeXB0by5zcGVjOworCitpbXBvcnQgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuUkMyUGFyYW1ldGVyU3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCisvKioKKyAqLworcHVibGljIGNsYXNzIFJDMlBhcmFtZXRlclNwZWNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogUkMyUGFyYW1ldGVyU3BlYyhpbnQgZWZmZWN0aXZlS2V5Qml0cywgYnl0ZVtdIGl2KSBtZXRob2QgdGVzdGluZy4KKyAgICAgKiBUZXN0cyB0aGF0IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyB0aHJvd24gaW4gdGhlIGNhc2Ugb2YKKyAgICAgKiBpbmFwcHJvcHJpYXRlIGNvbnN0cnVjdG9yIHBhcmFtZXRlcnMgYW5kIHRoYXQgaW5wdXQgaXYgYXJyYXkgaXMKKyAgICAgKiBjb3BpZWQgdG8gcHJvdGVjdCBhZ2FpbnN0IHN1YnNlcXVlbnQgbW9kaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RSQzJQYXJhbWV0ZXJTcGVjMSgpIHsKKyAgICAgICAgaW50IGVmZmVjdGl2ZUtleUJpdHMgPSAxMDsKKyAgICAgICAgYnl0ZVtdIGl2ID0gezEsIDIsIDMsIDQsIDUsIDYsIDcsIDh9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUkMyUGFyYW1ldGVyU3BlYyhlZmZlY3RpdmVLZXlCaXRzLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gdGhlIGNhc2Ugb2YgbnVsbCBpdi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUkMyUGFyYW1ldGVyU3BlYyhlZmZlY3RpdmVLZXlCaXRzLCBuZXcgYnl0ZVtdIHsxLCAyLCAzLCA0LCA1fSk7CisgICAgICAgICAgICBmYWlsKCJBbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIHNob3J0IGl2LiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgUkMyUGFyYW1ldGVyU3BlYyBwcyA9IG5ldyBSQzJQYXJhbWV0ZXJTcGVjKGVmZmVjdGl2ZUtleUJpdHMsIGl2KTsKKyAgICAgICAgaXZbMF0gKys7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2hhbmdlIG9mIGl2IHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3IgIgorICAgICAgICAgICAgICAgICAgICArICJzaG91bGQgbm90IGNhdXNlIHRoZSBjaGFuZ2Ugb2YgaW50ZXJuYWwgYXJyYXkuIiwKKyAgICAgICAgICAgICAgICAgICAgaXZbMF0gPT0gcHMuZ2V0SVYoKVswXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUkMyUGFyYW1ldGVyU3BlYyhpbnQgZWZmZWN0aXZlS2V5Qml0cywgYnl0ZVtdIGl2LCBpbnQgb2Zmc2V0KSBtZXRob2QKKyAgICAgKiB0ZXN0aW5nLiBUZXN0cyB0aGF0IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyB0aHJvd24gaW4gdGhlIGNhc2Ugb2YKKyAgICAgKiBpbmFwcHJvcHJpYXRlIGNvbnN0cnVjdG9yIHBhcmFtZXRlcnMgYW5kIHRoYXQgaW5wdXQgaXYgYXJyYXkgaXMKKyAgICAgKiBjb3BpZWQgdG8gcHJvdGVjdCBhZ2FpbnN0IHN1YnNlcXVlbnQgbW9kaWZpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RSQzJQYXJhbWV0ZXJTcGVjMigpIHsKKyAgICAgICAgaW50IGVmZmVjdGl2ZUtleUJpdHMgPSAxMDsKKyAgICAgICAgYnl0ZVtdIGl2ID0gezEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDB9OworICAgICAgICBpbnQgb2Zmc2V0ID0gMjsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFJDMlBhcmFtZXRlclNwZWMoZWZmZWN0aXZlS2V5Qml0cywgbnVsbCwgb2Zmc2V0KTsKKyAgICAgICAgICAgIGZhaWwoIkFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gdGhlIGNhc2Ugb2YgbnVsbCBpdi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUkMyUGFyYW1ldGVyU3BlYyhlZmZlY3RpdmVLZXlCaXRzLCBpdiwgNCk7CisgICAgICAgICAgICBmYWlsKCJBbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIHNob3J0IGl2LiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgUkMyUGFyYW1ldGVyU3BlYyBwcyA9IG5ldyBSQzJQYXJhbWV0ZXJTcGVjKGVmZmVjdGl2ZUtleUJpdHMsIGl2LCBvZmZzZXQpOworICAgICAgICBpdltvZmZzZXRdICsrOworICAgICAgICBhc3NlcnRGYWxzZSgiVGhlIGNoYW5nZSBvZiBpdiBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yICIKKyAgICAgICAgICAgICAgICAgICAgKyAic2hvdWxkIG5vdCBjYXVzZSB0aGUgY2hhbmdlIG9mIGludGVybmFsIGFycmF5LiIsCisgICAgICAgICAgICAgICAgICAgIGl2W29mZnNldF0gPT0gcHMuZ2V0SVYoKVswXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0RWZmZWN0aXZlS2V5Qml0cygpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGF0IHJldHVybmVkIHZhbHVlIGlzCisgICAgICogZXF1YWwgdG8gdGhlIHZhbHVlIHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEVmZmVjdGl2ZUtleUJpdHMoKSB7CisgICAgICAgIGludCBlZmZlY3RpdmVLZXlCaXRzID0gMTA7CisgICAgICAgIGJ5dGVbXSBpdiA9IHsxLCAyLCAzLCA0LCA1LCA2LCA3LCA4fTsKKworICAgICAgICBSQzJQYXJhbWV0ZXJTcGVjIHBzID0gbmV3IFJDMlBhcmFtZXRlclNwZWMoZWZmZWN0aXZlS2V5Qml0cywgaXYpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgcmV0dXJuZWQgZWZmZWN0aXZlS2V5Qml0cyB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gdGhlICIKKyAgICAgICAgICAgICAgICArICJ2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yLiIsCisgICAgICAgICAgICAgICAgZWZmZWN0aXZlS2V5Qml0cyA9PSBwcy5nZXRFZmZlY3RpdmVLZXlCaXRzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGdldElWKCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIHRoYXQgcmV0dXJuZWQgYXJyYXkgaXMgZXF1YWwgdG8gdGhlCisgICAgICogYXJyYXkgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3Rvci4gQ2hlY2tzIHRoYXQgbW9kaWZpY2F0aW9uCisgICAgICogb2YgcmV0dXJuZWQgYXJyYXkgZG9lcyBub3QgYWZmZWN0IHRoZSBpbnRlcm5hbCBhcnJheS4gQWxzbyBpdCBjaGVja3MKKyAgICAgKiB0aGF0IGdldElWKCkgbWV0aG9kIHJldHVybnMgbnVsbCBpZiBpdiBpcyBub3Qgc3BlY2lmaWVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJVigpIHsKKyAgICAgICAgaW50IGVmZmVjdGl2ZUtleUJpdHMgPSAxMDsKKyAgICAgICAgYnl0ZVtdIGl2ID0gbmV3IGJ5dGVbXSB7MSwgMiwgMywgNCwgNSwgNiwgNywgOH07CisKKyAgICAgICAgUkMyUGFyYW1ldGVyU3BlYyBwcyA9IG5ldyBSQzJQYXJhbWV0ZXJTcGVjKGVmZmVjdGl2ZUtleUJpdHMsIGl2KTsKKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IHBzLmdldElWKCk7CisgICAgICAgIGlmICghIEFycmF5cy5lcXVhbHMoaXYsIHJlc3VsdCkpIHsKKyAgICAgICAgICAgIGZhaWwoIlRoZSByZXR1cm5lZCBpdiBpcyBub3QgZXF1YWwgdG8gdGhlIHNwZWNpZmllZCAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjb25zdHJ1Y3Rvci4iKTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHRbMF0gKys7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2hhbmdlIG9mIHJldHVybmVkIGJ5IGdldElWKCkgbWV0aG9kIGl2ICIKKyAgICAgICAgICAgICAgICAgICAgKyAic2hvdWxkIG5vdCBjYXVzZSB0aGUgY2hhbmdlIG9mIGludGVybmFsIGFycmF5LiIsCisgICAgICAgICAgICAgICAgICAgIHJlc3VsdFswXSA9PSBwcy5nZXRJVigpWzBdKTsKKyAgICAgICAgcHMgPSBuZXcgUkMyUGFyYW1ldGVyU3BlYyhlZmZlY3RpdmVLZXlCaXRzKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiVGhlIGdldElWKCkgbWV0aG9kIHNob3VsZCByZXR1cm4gbnVsbCBpZiB0aGUgcGFyYW1ldGVyICIKKyAgICAgICAgICAgICAgICAgICAgKyAic2V0IGRvZXMgbm90IGNvbnRhaW4gaXYuIiwgcHMuZ2V0SVYoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZXF1YWxzKE9iamVjdCBvYmopIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGUgY29ycmVjdG5lc3Mgb2YgZXF1YWwKKyAgICAgKiBvcGVyYXRpb246IGl0IHNob3VsZCBiZSByZWZsZXhpdmUsIHN5bW1ldHJpYywgdHJhbnNpdGl2ZSwgY29uc2lzdGVudAorICAgICAqIGFuZCBzaG91bGQgYmUgZmFsc2Ugb24gbnVsbCBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEVxdWFscygpIHsKKyAgICAgICAgaW50IGVmZmVjdGl2ZUtleUJpdHMgPSAxMDsKKyAgICAgICAgYnl0ZVtdIGl2ID0gbmV3IGJ5dGVbXSB7MSwgMiwgMywgNCwgNSwgNiwgNywgOH07CisKKyAgICAgICAgUkMyUGFyYW1ldGVyU3BlYyBwczEgPSBuZXcgUkMyUGFyYW1ldGVyU3BlYyhlZmZlY3RpdmVLZXlCaXRzLCBpdik7CisgICAgICAgIFJDMlBhcmFtZXRlclNwZWMgcHMyID0gbmV3IFJDMlBhcmFtZXRlclNwZWMoZWZmZWN0aXZlS2V5Qml0cywgaXYpOworICAgICAgICBSQzJQYXJhbWV0ZXJTcGVjIHBzMyA9IG5ldyBSQzJQYXJhbWV0ZXJTcGVjKDEwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IGJ5dGVbXSB7MSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOX0pOworCisgICAgICAgIC8vIGNoZWNraW5nIGZvciByZWZsZXhpdmUgbGF3OgorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgZXF1aXZhbGVuY2UgcmVsYXRpb24gc2hvdWxkIGJlIHJlZmxleGl2ZS4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwczEuZXF1YWxzKHBzMSkpOworCisgICAgICAgIGFzc2VydFRydWUoIk9iamVjdHMgYnVpbHQgb24gdGhlIHNhbWUgcGFyYW1ldGVycyBzaG91bGQgYmUgZXF1YWwuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHMxLmVxdWFscyhwczIpKTsKKyAgICAgICAgLy8gY2hlY2tpbmcgZm9yIHN5bW1ldHJpYyBsYXc6CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBlcXVpdmFsZW5jZSByZWxhdGlvbiBzaG91bGQgYmUgc3ltbWV0cmljLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzMi5lcXVhbHMocHMxKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiT2JqZWN0cyBidWlsdCBvbiB0aGUgZXF1YWwgcGFyYW1ldGVycyBzaG91bGQgYmUgZXF1YWwuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHMyLmVxdWFscyhwczMpKTsKKworICAgICAgICAvLyBjaGVja2luZyBmb3IgdHJhbnNpdGl2ZSBsYXc6CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBlcXVpdmFsZW5jZSByZWxhdGlvbiBzaG91bGQgYmUgdHJhbnNpdGl2ZS4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwczEuZXF1YWxzKHBzMykpOworCisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIG5vdCBiZSBlcXVhbCB0byBudWxsIG9iamVjdC4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwczEuZXF1YWxzKG51bGwpKTsKKworICAgICAgICBwczIgPSBuZXcgUkMyUGFyYW1ldGVyU3BlYygxMSwgaXYpOworICAgICAgICBhc3NlcnRGYWxzZSgiT2JqZWN0cyBzaG91bGQgbm90IGJlIGVxdWFsLiIsIHBzMS5lcXVhbHMocHMyKSk7CisKKyAgICAgICAgcHMyID0gbmV3IFJDMlBhcmFtZXRlclNwZWMoMTEsIG5ldyBieXRlW10gezksIDgsIDcsIDYsIDUsIDQsIDMsIDIsIDF9KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIk9iamVjdHMgc2hvdWxkIG5vdCBiZSBlcXVhbC4iLCBwczEuZXF1YWxzKHBzMikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGhhc2hDb2RlKCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIHRoYXQgZm9yIGVxdWFsIG9iamVjdHMgaGFzaCBjb2RlcworICAgICAqIGFyZSBlcXVhbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzaENvZGUoKSB7CisgICAgICAgIGludCBlZmZlY3RpdmVLZXlCaXRzID0gMDsKKyAgICAgICAgYnl0ZVtdIGl2ID0gbmV3IGJ5dGVbXSB7MSwgMiwgMywgNCwgNSwgNiwgNywgOH07CisKKyAgICAgICAgUkMyUGFyYW1ldGVyU3BlYyBwczEgPSBuZXcgUkMyUGFyYW1ldGVyU3BlYyhlZmZlY3RpdmVLZXlCaXRzLCBpdik7CisgICAgICAgIFJDMlBhcmFtZXRlclNwZWMgcHMyID0gbmV3IFJDMlBhcmFtZXRlclNwZWMoZWZmZWN0aXZlS2V5Qml0cywgaXYpOworCisgICAgICAgIGFzc2VydFRydWUoIkVxdWFsIG9iamVjdHMgc2hvdWxkIGhhdmUgdGhlIHNhbWUgaGFzaCBjb2Rlcy4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwczEuaGFzaENvZGUoKSA9PSBwczIuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25zdHJ1Y3RvckkoKSB7CisgICAgICAgIGludCBlZmZlY3RpdmVLZXlCaXRzID0gMDsKKworICAgICAgICBSQzJQYXJhbWV0ZXJTcGVjIHBzMSA9IG5ldyBSQzJQYXJhbWV0ZXJTcGVjKGVmZmVjdGl2ZUtleUJpdHMpOworICAgICAgICBSQzJQYXJhbWV0ZXJTcGVjIHBzMiA9IG5ldyBSQzJQYXJhbWV0ZXJTcGVjKGVmZmVjdGl2ZUtleUJpdHMpOworCisgICAgICAgIGFzc2VydFRydWUocHMxLmVxdWFscyhwczIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFRlc3Qgc3VpdGUoKSB7CisgICAgICAgIHJldHVybiBuZXcgVGVzdFN1aXRlKFJDMlBhcmFtZXRlclNwZWNUZXN0LmNsYXNzKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL1JDNVBhcmFtZXRlclNwZWNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc3BlYy9SQzVQYXJhbWV0ZXJTcGVjVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjllOTIxNTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc3BlYy9SQzVQYXJhbWV0ZXJTcGVjVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjk0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5SQzVQYXJhbWV0ZXJTcGVjOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKKy8qKgorICovCitwdWJsaWMgY2xhc3MgUkM1UGFyYW1ldGVyU3BlY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBSQzVQYXJhbWV0ZXJTcGVjKGludCB2ZXJzaW9uLCBpbnQgcm91bmRzLCBpbnQgd29yZFNpemUsIGJ5dGVbXSBpdikgbWV0aG9kCisgICAgICogdGVzdGluZy4gVGVzdHMgdGhhdCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duIGluIHRoZSBjYXNlIG9mCisgICAgICogaW5hcHByb3ByaWF0ZSBjb25zdHJ1Y3RvciBwYXJhbWV0ZXJzIGFuZCB0aGF0IGlucHV0IGl2IGFycmF5IGlzCisgICAgICogY29waWVkIHRvIHByb3RlY3QgYWdhaW5zdCBzdWJzZXF1ZW50IG1vZGlmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UkM1UGFyYW1ldGVyU3BlYzEoKSB7CisgICAgICAgIGludCB2ZXJzaW9uID0gMTsKKyAgICAgICAgaW50IHJvdW5kcyA9IDU7CisgICAgICAgIGludCB3b3JkU2l6ZSA9IDE2OworICAgICAgICBieXRlW10gaXYgPSB7MSwgMiwgMywgNH07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBSQzVQYXJhbWV0ZXJTcGVjKHZlcnNpb24sIHJvdW5kcywgd29yZFNpemUsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiQW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gIgorICAgICAgICAgICAgICAgICAgICArICJpbiB0aGUgY2FzZSBvZiBudWxsIGl2LiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBSQzVQYXJhbWV0ZXJTcGVjKHZlcnNpb24sIHJvdW5kcywgd29yZFNpemUrOCwgaXYpOworICAgICAgICAgICAgZmFpbCgiQW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gIgorICAgICAgICAgICAgICAgICAgICArICJpbiB0aGUgY2FzZSBvZiBzaG9ydCBpdi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUkM1UGFyYW1ldGVyU3BlYyh2ZXJzaW9uLCByb3VuZHMsIHdvcmRTaXplLCBuZXcgYnl0ZVtdIHsxLCAyLCAzfSk7CisgICAgICAgICAgICBmYWlsKCJBbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIHNob3J0IGl2LiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgUkM1UGFyYW1ldGVyU3BlYyBwcyA9IG5ldyBSQzVQYXJhbWV0ZXJTcGVjKHZlcnNpb24sIHJvdW5kcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JkU2l6ZSwgaXYpOworICAgICAgICBpdlswXSArKzsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBjaGFuZ2Ugb2YgaXYgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciAiCisgICAgICAgICAgICAgICAgICAgICsgInNob3VsZCBub3QgY2F1c2UgdGhlIGNoYW5nZSBvZiBpbnRlcm5hbCBhcnJheS4iLAorICAgICAgICAgICAgICAgICAgICBpdlswXSA9PSBwcy5nZXRJVigpWzBdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSQzVQYXJhbWV0ZXJTcGVjKGludCB2ZXJzaW9uLCBpbnQgcm91bmRzLCBpbnQgd29yZFNpemUsIGJ5dGVbXSBpdiwgaW50CisgICAgICogb2Zmc2V0KSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhhdCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duIGluCisgICAgICogdGhlIGNhc2Ugb2YgaW5hcHByb3ByaWF0ZSBjb25zdHJ1Y3RvciBwYXJhbWV0ZXJzIGFuZCB0aGF0IGlucHV0IGl2IGFycmF5CisgICAgICogaXMgY29waWVkIHRvIHByb3RlY3QgYWdhaW5zdCBzdWJzZXF1ZW50IG1vZGlmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UkM1UGFyYW1ldGVyU3BlYzIoKSB7CisgICAgICAgIGludCB2ZXJzaW9uID0gMTsKKyAgICAgICAgaW50IHJvdW5kcyA9IDU7CisgICAgICAgIGludCB3b3JkU2l6ZSA9IDE2OworICAgICAgICBieXRlW10gaXYgPSB7MSwgMiwgMywgNCwgNSwgNn07CisgICAgICAgIGludCBvZmZzZXQgPSAyOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUkM1UGFyYW1ldGVyU3BlYyh2ZXJzaW9uLCByb3VuZHMsIHdvcmRTaXplLCBudWxsLCBvZmZzZXQpOworICAgICAgICAgICAgZmFpbCgiQW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gIgorICAgICAgICAgICAgICAgICAgICArICJpbiB0aGUgY2FzZSBvZiBudWxsIGl2LiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBSQzVQYXJhbWV0ZXJTcGVjKHZlcnNpb24sIHJvdW5kcywgd29yZFNpemUrOCwgaXYsIG9mZnNldCk7CisgICAgICAgICAgICBmYWlsKCJBbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIHNob3J0IGl2LiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBSQzVQYXJhbWV0ZXJTcGVjKHZlcnNpb24sIHJvdW5kcywgd29yZFNpemUsIGl2LCBvZmZzZXQrMSk7CisgICAgICAgICAgICBmYWlsKCJBbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIHNob3J0IGl2LiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBSQzVQYXJhbWV0ZXJTcGVjKHZlcnNpb24sIHJvdW5kcywgd29yZFNpemUsIG5ldyBieXRlW10geyAxLCAyLAorICAgICAgICAgICAgICAgICAgICAzLCA0IH0sIG9mZnNldCk7CisgICAgICAgICAgICBmYWlsKCJBbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIHNob3J0IGl2LiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgUkM1UGFyYW1ldGVyU3BlYyBwcyA9IG5ldyBSQzVQYXJhbWV0ZXJTcGVjKHZlcnNpb24sIHJvdW5kcywgd29yZFNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl2LCBvZmZzZXQpOworICAgICAgICBpdltvZmZzZXRdICsrOworICAgICAgICBhc3NlcnRGYWxzZSgiVGhlIGNoYW5nZSBvZiBpdiBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yICIKKyAgICAgICAgICAgICAgICAgICAgKyAic2hvdWxkIG5vdCBjYXVzZSB0aGUgY2hhbmdlIG9mIGludGVybmFsIGFycmF5LiIsCisgICAgICAgICAgICAgICAgICAgIGl2W29mZnNldF0gPT0gcHMuZ2V0SVYoKVswXSk7CisKKyAgICAgICAgLy8gUmVncmVzc2lvbiB0ZXN0IGZvciBIQVJNT05ZLTEwNzcKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBSQzVQYXJhbWV0ZXJTcGVjKDAsIDksIDc3LCBuZXcgYnl0ZVtdIHsgMiB9LCAtMTAwKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGdldFZlcnNpb24oKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhhdCByZXR1cm5lZCB2YWx1ZSBpcworICAgICAqIGVxdWFsIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRWZXJzaW9uKCkgeworICAgICAgICBpbnQgdmVyc2lvbiA9IDE7CisgICAgICAgIGludCByb3VuZHMgPSA1OworICAgICAgICBpbnQgd29yZFNpemUgPSAxNjsKKworICAgICAgICBSQzVQYXJhbWV0ZXJTcGVjIHBzID0gbmV3IFJDNVBhcmFtZXRlclNwZWModmVyc2lvbiwgcm91bmRzLCB3b3JkU2l6ZSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSByZXR1cm5lZCB2ZXJzaW9uIHZhbHVlIHNob3VsZCBiZSBlcXVhbCB0byB0aGUgIgorICAgICAgICAgICAgICAgICsgInZhbHVlIHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3IuIiwKKyAgICAgICAgICAgICAgICBwcy5nZXRWZXJzaW9uKCkgPT0gdmVyc2lvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0Um91bmRzKCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIHRoYXQgcmV0dXJuZWQgdmFsdWUgaXMKKyAgICAgKiBlcXVhbCB0byB0aGUgdmFsdWUgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Um91bmRzKCkgeworICAgICAgICBpbnQgdmVyc2lvbiA9IDE7CisgICAgICAgIGludCByb3VuZHMgPSA1OworICAgICAgICBpbnQgd29yZFNpemUgPSAxNjsKKworICAgICAgICBSQzVQYXJhbWV0ZXJTcGVjIHBzID0gbmV3IFJDNVBhcmFtZXRlclNwZWModmVyc2lvbiwgcm91bmRzLCB3b3JkU2l6ZSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSByZXR1cm5lZCByb3VuZHMgdmFsdWUgc2hvdWxkIGJlIGVxdWFsIHRvIHRoZSAiCisgICAgICAgICAgICAgICAgKyAidmFsdWUgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3Rvci4iLAorICAgICAgICAgICAgICAgIHBzLmdldFJvdW5kcygpID09IHJvdW5kcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0V29yZFNpemUoKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhhdCByZXR1cm5lZCB2YWx1ZSBpcworICAgICAqIGVxdWFsIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRXb3JkU2l6ZSgpIHsKKyAgICAgICAgaW50IHZlcnNpb24gPSAxOworICAgICAgICBpbnQgcm91bmRzID0gNTsKKyAgICAgICAgaW50IHdvcmRTaXplID0gMTY7CisKKyAgICAgICAgUkM1UGFyYW1ldGVyU3BlYyBwcyA9IG5ldyBSQzVQYXJhbWV0ZXJTcGVjKHZlcnNpb24sIHJvdW5kcywgd29yZFNpemUpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgcmV0dXJuZWQgd29yZFNpemUgdmFsdWUgc2hvdWxkIGJlIGVxdWFsIHRvIHRoZSAiCisgICAgICAgICAgICAgICAgKyAidmFsdWUgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3Rvci4iLAorICAgICAgICAgICAgICAgIHBzLmdldFdvcmRTaXplKCkgPT0gd29yZFNpemUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGdldElWKCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIHRoYXQgcmV0dXJuZWQgYXJyYXkgaXMgZXF1YWwgdG8gdGhlCisgICAgICogYXJyYXkgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3Rvci4gQ2hlY2tzIHRoYXQgbW9kaWZpY2F0aW9uCisgICAgICogb2YgcmV0dXJuZWQgYXJyYXkgZG9lcyBub3QgYWZmZWN0IHRoZSBpbnRlcm5hbCBhcnJheS4gQWxzbyBpdCBjaGVja3MKKyAgICAgKiB0aGF0IGdldElWKCkgbWV0aG9kIHJldHVybnMgbnVsbCBpZiBpdiBpcyBub3Qgc3BlY2lmaWVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJVigpIHsKKyAgICAgICAgaW50IHZlcnNpb24gPSAxOworICAgICAgICBpbnQgcm91bmRzID0gNTsKKyAgICAgICAgaW50IHdvcmRTaXplID0gMTY7CisgICAgICAgIGJ5dGVbXSBpdiA9IHsxLCAyLCAzLCA0fTsKKworICAgICAgICBSQzVQYXJhbWV0ZXJTcGVjIHBzID0gbmV3IFJDNVBhcmFtZXRlclNwZWModmVyc2lvbiwgcm91bmRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd29yZFNpemUsIGl2KTsKKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IHBzLmdldElWKCk7CisgICAgICAgIGlmICghIEFycmF5cy5lcXVhbHMoaXYsIHJlc3VsdCkpIHsKKyAgICAgICAgICAgIGZhaWwoIlRoZSByZXR1cm5lZCBpdiBpcyBub3QgZXF1YWwgdG8gdGhlIHNwZWNpZmllZCAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjb25zdHJ1Y3Rvci4iKTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHRbMF0gKys7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2hhbmdlIG9mIHJldHVybmVkIGJ5IGdldElWKCkgbWV0aG9kIGl2ICIKKyAgICAgICAgICAgICAgICAgICAgKyAic2hvdWxkIG5vdCBjYXVzZSB0aGUgY2hhbmdlIG9mIGludGVybmFsIGFycmF5LiIsCisgICAgICAgICAgICAgICAgICAgIHJlc3VsdFswXSA9PSBwcy5nZXRJVigpWzBdKTsKKyAgICAgICAgcHMgPSBuZXcgUkM1UGFyYW1ldGVyU3BlYyh2ZXJzaW9uLCByb3VuZHMsIHdvcmRTaXplKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiVGhlIGdldElWKCkgbWV0aG9kIHNob3VsZCByZXR1cm4gbnVsbCBpZiB0aGUgcGFyYW1ldGVyICIKKyAgICAgICAgICAgICAgICAgICAgKyAic2V0IGRvZXMgbm90IGNvbnRhaW4gSVYuIiwgcHMuZ2V0SVYoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZXF1YWxzKE9iamVjdCBvYmopIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGUgY29ycmVjdG5lc3Mgb2YgZXF1YWwKKyAgICAgKiBvcGVyYXRpb246IGl0IHNob3VsZCBiZSByZWZsZXhpdmUsIHN5bW1ldHJpYywgdHJhbnNpdGl2ZSwgY29uc2lzdGVudAorICAgICAqIGFuZCBzaG91bGQgYmUgZmFsc2Ugb24gbnVsbCBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEVxdWFscygpIHsKKyAgICAgICAgaW50IHZlcnNpb24gPSAxOworICAgICAgICBpbnQgcm91bmRzID0gNTsKKyAgICAgICAgaW50IHdvcmRTaXplID0gMTY7CisgICAgICAgIGJ5dGVbXSBpdiA9IHsxLCAyLCAzLCA0LCA1LCA2fTsKKworICAgICAgICBSQzVQYXJhbWV0ZXJTcGVjIHBzMSA9IG5ldyBSQzVQYXJhbWV0ZXJTcGVjKHZlcnNpb24sIHJvdW5kcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JkU2l6ZSwgaXYpOworICAgICAgICBSQzVQYXJhbWV0ZXJTcGVjIHBzMiA9IG5ldyBSQzVQYXJhbWV0ZXJTcGVjKHZlcnNpb24sIHJvdW5kcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JkU2l6ZSwgaXYpOworICAgICAgICBSQzVQYXJhbWV0ZXJTcGVjIHBzMyA9IG5ldyBSQzVQYXJhbWV0ZXJTcGVjKHZlcnNpb24sIHJvdW5kcywgd29yZFNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IGJ5dGVbXSB7MSwgMiwgMywgNH0pOworICAgICAgICAvLyBjaGVja2luZyBmb3IgcmVmbGV4aXZlIGxhdzoKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGVxdWl2YWxlbmNlIHJlbGF0aW9uIHNob3VsZCBiZSByZWZsZXhpdmUuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHMxLmVxdWFscyhwczEpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJPYmplY3RzIGJ1aWx0IG9uIHRoZSBzYW1lIHBhcmFtZXRlcnMgc2hvdWxkIGJlIGVxdWFsLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzMS5lcXVhbHMocHMyKSk7CisgICAgICAgIC8vIGNoZWNraW5nIGZvciBzeW1tZXRyaWMgbGF3OgorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgZXF1aXZhbGVuY2UgcmVsYXRpb24gc2hvdWxkIGJlIHN5bW1ldHJpYy4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwczIuZXF1YWxzKHBzMSkpOworCisgICAgICAgIGFzc2VydFRydWUoIk9iamVjdHMgYnVpbHQgb24gdGhlIGVxdWFsIHBhcmFtZXRlcnMgc2hvdWxkIGJlIGVxdWFsLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzMi5lcXVhbHMocHMzKSk7CisKKyAgICAgICAgLy8gY2hlY2tpbmcgZm9yIHRyYW5zaXRpdmUgbGF3OgorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgZXF1aXZhbGVuY2UgcmVsYXRpb24gc2hvdWxkIGJlIHRyYW5zaXRpdmUuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHMxLmVxdWFscyhwczMpKTsKKworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIHJldHVybiBub3QgYmUgZXF1YWwgdG8gbnVsbCBvYmplY3QuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHMxLmVxdWFscyhudWxsKSk7CisKKyAgICAgICAgcHMyID0gbmV3IFJDNVBhcmFtZXRlclNwZWModmVyc2lvbisxLCByb3VuZHMsIHdvcmRTaXplLCBpdik7CisgICAgICAgIGFzc2VydEZhbHNlKCJPYmplY3RzIHNob3VsZCBub3QgYmUgZXF1YWwuIiwgcHMxLmVxdWFscyhwczIpKTsKKworICAgICAgICBwczIgPSBuZXcgUkM1UGFyYW1ldGVyU3BlYyh2ZXJzaW9uLCByb3VuZHMrMSwgd29yZFNpemUsIGl2KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIk9iamVjdHMgc2hvdWxkIG5vdCBiZSBlcXVhbC4iLCBwczEuZXF1YWxzKHBzMikpOworCisgICAgICAgIHBzMiA9IG5ldyBSQzVQYXJhbWV0ZXJTcGVjKHZlcnNpb24sIHJvdW5kcywgd29yZFNpemUvMiwgaXYpOworICAgICAgICBhc3NlcnRGYWxzZSgiT2JqZWN0cyBzaG91bGQgbm90IGJlIGVxdWFsLiIsIHBzMS5lcXVhbHMocHMyKSk7CisKKyAgICAgICAgcHMyID0gbmV3IFJDNVBhcmFtZXRlclNwZWModmVyc2lvbiwgcm91bmRzLCB3b3JkU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgYnl0ZVtdIHs0LCAzLCAyLCAxfSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJPYmplY3RzIHNob3VsZCBub3QgYmUgZXF1YWwuIiwgcHMxLmVxdWFscyhwczIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBoYXNoQ29kZSgpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGF0IGZvciBlcXVhbCBvYmplY3RzIGhhc2ggY29kZXMKKyAgICAgKiBhcmUgZXF1YWwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEhhc2hDb2RlKCkgeworICAgICAgICBpbnQgdmVyc2lvbiA9IDE7CisgICAgICAgIGludCByb3VuZHMgPSA1OworICAgICAgICBpbnQgd29yZFNpemUgPSAxNjsKKyAgICAgICAgYnl0ZVtdIGl2ID0gezEsIDIsIDMsIDQsIDUsIDZ9OworCisgICAgICAgIFJDNVBhcmFtZXRlclNwZWMgcHMxID0gbmV3IFJDNVBhcmFtZXRlclNwZWModmVyc2lvbiwgcm91bmRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvcmRTaXplLCBpdik7CisgICAgICAgIFJDNVBhcmFtZXRlclNwZWMgcHMyID0gbmV3IFJDNVBhcmFtZXRlclNwZWModmVyc2lvbiwgcm91bmRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvcmRTaXplLCBpdik7CisgICAgICAgIGFzc2VydFRydWUoIkVxdWFsIG9iamVjdHMgc2hvdWxkIGhhdmUgdGhlIHNhbWUgaGFzaCBjb2Rlcy4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwczEuaGFzaENvZGUoKSA9PSBwczIuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25zdHJ1Y3RvcklJSSgpIHsKKyAgICAgICAgaW50IHZlcnNpb24gPSAxOworICAgICAgICBpbnQgcm91bmRzID0gNTsKKyAgICAgICAgaW50IHdvcmRTaXplID0gMTY7CisgICAgICAgIFJDNVBhcmFtZXRlclNwZWMgcHMxID0gbmV3IFJDNVBhcmFtZXRlclNwZWModmVyc2lvbiwgcm91bmRzLCB3b3JkU2l6ZSk7CisgICAgICAgIFJDNVBhcmFtZXRlclNwZWMgcHMyID0gbmV3IFJDNVBhcmFtZXRlclNwZWModmVyc2lvbiwgcm91bmRzLCB3b3JkU2l6ZSk7CisgICAgICAgIFJDNVBhcmFtZXRlclNwZWMgcHMzID0gbmV3IFJDNVBhcmFtZXRlclNwZWModmVyc2lvbiwgcm91bmRzLCB3b3JkU2l6ZSArIDEpOworCisgICAgICAgIGFzc2VydFRydWUocHMxLmVxdWFscyhwczIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocHMxLmVxdWFscyhwczMpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFRlc3Qgc3VpdGUoKSB7CisgICAgICAgIHJldHVybiBuZXcgVGVzdFN1aXRlKFJDNVBhcmFtZXRlclNwZWNUZXN0LmNsYXNzKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc3BlYy9TZWNyZXRLZXlTcGVjVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY0ODIxM2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc3BlYy9TZWNyZXRLZXlTcGVjVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjY1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5qYXZheC5jcnlwdG8uc3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLlNlY3JldEtleVNwZWM7CisKKy8qKgorICovCitwdWJsaWMgY2xhc3MgU2VjcmV0S2V5U3BlY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBTZWNyZXRLZXlTcGVjKGJ5dGVbXSBrZXksIFN0cmluZyBhbGdvcml0aG0pIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGF0CisgICAgICogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93biBpbiB0aGUgY2FzZSBvZiBpbmFwcHJvcHJpYXRlCisgICAgICogY29uc3RydWN0b3IgcGFyYW1ldGVycyBhbmQgdGhhdCBpbnB1dCBpdiBhcnJheSBpcworICAgICAqIGNvcGllZCB0byBwcm90ZWN0IGFnYWluc3Qgc3Vic2VxdWVudCBtb2RpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNlY3JldEtleVNwZWMxKCkgeworICAgICAgICBieXRlW10ga2V5ID0gbmV3IGJ5dGVbXSB7MSwgMiwgMywgNCwgNX07CisgICAgICAgIFN0cmluZyBhbGdvcml0aG0gPSAiQWxnb3JpdGhtIjsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFNlY3JldEtleVNwZWMobmV3IGJ5dGVbXSB7fSwgYWxnb3JpdGhtKTsKKyAgICAgICAgICAgIGZhaWwoIkFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gdGhlIGNhc2Ugb2YgZW1wdHkga2V5LiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTZWNyZXRLZXlTcGVjKG51bGwsIGFsZ29yaXRobSk7CisgICAgICAgICAgICBmYWlsKCJBbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIG51bGwga2V5LiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTZWNyZXRLZXlTcGVjKGtleSwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJBbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIG51bGwgYWxnb3JpdGhtLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgU2VjcmV0S2V5U3BlYyBrcyA9IG5ldyBTZWNyZXRLZXlTcGVjKGtleSwgYWxnb3JpdGhtKTsKKyAgICAgICAga2V5WzBdICsrOworICAgICAgICBhc3NlcnRGYWxzZSgiVGhlIGNoYW5nZSBvZiBrZXkgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciAiCisgICAgICAgICAgICAgICAgICAgICsgInNob3VsZCBub3QgY2F1c2UgdGhlIGNoYW5nZSBvZiBpbnRlcm5hbCBhcnJheS4iLAorICAgICAgICAgICAgICAgICAgICBrZXlbMF0gPT0ga3MuZ2V0RW5jb2RlZCgpWzBdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWNyZXRLZXlTcGVjKGJ5dGVbXSBrZXksIGludCBvZmZzZXQsIGludCBsZW4sIFN0cmluZyBhbGdvcml0aG0pIG1ldGhvZAorICAgICAqIHRlc3RpbmcuIFRlc3RzIHRoYXQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93biBpbgorICAgICAqIHRoZSBjYXNlIG9mIGluYXBwcm9wcmlhdGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyBhbmQgdGhhdCBpbnB1dCBpdiBhcnJheQorICAgICAqIGlzIGNvcGllZCB0byBwcm90ZWN0IGFnYWluc3Qgc3Vic2VxdWVudCBtb2RpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNlY3JldEtleVNwZWMyKCkgeworICAgICAgICBieXRlW10ga2V5ID0gbmV3IGJ5dGVbXSB7MSwgMiwgMywgNCwgNX07CisgICAgICAgIGludCBvZmZzZXQgPSAxOworICAgICAgICBpbnQgbGVuID0gNDsKKyAgICAgICAgU3RyaW5nIGFsZ29yaXRobSA9ICJBbGdvcml0aG0iOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2VjcmV0S2V5U3BlYyhuZXcgYnl0ZVtdIHt9LCAwLCAwLCBhbGdvcml0aG0pOworICAgICAgICAgICAgZmFpbCgiQW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gIgorICAgICAgICAgICAgICAgICAgICArICJpbiB0aGUgY2FzZSBvZiBlbXB0eSBrZXkuIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFNlY3JldEtleVNwZWMobnVsbCwgMCwgMCwgYWxnb3JpdGhtKTsKKyAgICAgICAgICAgIGZhaWwoIkFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gdGhlIGNhc2Ugb2YgbnVsbCBrZXkuIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFNlY3JldEtleVNwZWMoa2V5LCBvZmZzZXQsIGxlbiwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJBbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIHNob3J0IGtleSBhbGdvcml0aG0uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFNlY3JldEtleVNwZWMoa2V5LCBvZmZzZXQsIGtleS5sZW5ndGgsIGFsZ29yaXRobSk7CisgICAgICAgICAgICBmYWlsKCJBbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIG51bGwga2V5LiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTZWNyZXRLZXlTcGVjKGtleSwgMCwgLTEsIGFsZ29yaXRobSk7CisgICAgICAgICAgICBmYWlsKCJBbiBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIGlsbGVnYWwgbGVuZ3RoLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiTm90IGV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgU2VjcmV0S2V5U3BlYyBrcyA9IG5ldyBTZWNyZXRLZXlTcGVjKGtleSwgYWxnb3JpdGhtKTsKKyAgICAgICAga2V5W29mZnNldF0gKys7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2hhbmdlIG9mIGtleSBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yICIKKyAgICAgICAgICAgICAgICAgICAgKyAic2hvdWxkIG5vdCBjYXVzZSB0aGUgY2hhbmdlIG9mIGludGVybmFsIGFycmF5LiIsCisgICAgICAgICAgICAgICAgICAgIGtleVtvZmZzZXRdID09IGtzLmdldEVuY29kZWQoKVswXSk7CisKKyAgICAgICAgLy8gUmVncmVzc2lvbiB0ZXN0IGZvciBIQVJNT05ZLTEwNzcKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTZWNyZXRLZXlTcGVjKG5ldyBieXRlW10geyAyIH0sIDQsIC0xMDAsICJDQ0MiKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNlY3JldEtleVNwZWMzKCkgeworICAgICAgICBieXRlW10ga2V5ID0gbmV3IGJ5dGVbXSB7MSwgMiwgMywgNCwgNX07CisgICAgICAgIGludCBvZmZzZXQgPSAxOworICAgICAgICBpbnQgbGVuID0gNDsKKyAgICAgICAgU3RyaW5nIGFsZ29yaXRobSA9ICJBbGdvcml0aG0iOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2VjcmV0S2V5U3BlYyhrZXksIC0xLCBrZXkubGVuZ3RoLCBhbGdvcml0aG0pOworICAgICAgICAgICAgZmFpbCgiQW4gQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gIgorICAgICAgICAgICAgICAgICAgICArICJpbiB0aGUgY2FzZSBvZiBpbGxlZ2FsIG9mZnNldC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIk5vdCBleHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGdldEFsZ29yaXRobSgpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGF0IHJldHVybmVkIHZhbHVlIGlzCisgICAgICogZXF1YWwgdG8gdGhlIHZhbHVlIHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgYnl0ZVtdIGtleSA9IG5ldyBieXRlW10gezEsIDIsIDMsIDQsIDV9OworICAgICAgICBTdHJpbmcgYWxnb3JpdGhtID0gIkFsZ29yaXRobSI7CisKKyAgICAgICAgU2VjcmV0S2V5U3BlYyBrcyA9IG5ldyBTZWNyZXRLZXlTcGVjKGtleSwgYWxnb3JpdGhtKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgcmV0dXJuZWQgdmFsdWUgZG9lcyBub3QgZXF1YWwgdG8gdGhlICIKKyAgICAgICAgICAgICAgICArICJ2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yLiIsCisgICAgICAgICAgICAgICAgYWxnb3JpdGhtLCBrcy5nZXRBbGdvcml0aG0oKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0Rm9ybWF0KCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIHRoYXQgcmV0dXJuZWQgdmFsdWUgaXMgIlJBVyIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEZvcm1hdCgpIHsKKyAgICAgICAgYnl0ZVtdIGtleSA9IG5ldyBieXRlW10gezEsIDIsIDMsIDQsIDV9OworICAgICAgICBTdHJpbmcgYWxnb3JpdGhtID0gIkFsZ29yaXRobSI7CisKKyAgICAgICAgU2VjcmV0S2V5U3BlYyBrcyA9IG5ldyBTZWNyZXRLZXlTcGVjKGtleSwgYWxnb3JpdGhtKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIHJldHVybmVkIHZhbHVlIGlzIG5vdCBcIlJBV1wiLiIsCisgICAgICAgICAgICAgICAga3MuZ2V0Rm9ybWF0KCkgPT0gIlJBVyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGdldEVuY29kZWQoKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhhdCByZXR1cm5lZCBhcnJheSBpcyBlcXVhbCB0byB0aGUKKyAgICAgKiBhcnJheSBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yLiBDaGVja3MgdGhhdCBtb2RpZmljYXRpb24KKyAgICAgKiBvZiByZXR1cm5lZCBhcnJheSBkb2VzIG5vdCBhZmZlY3QgdGhlIGludGVybmFsIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRFbmNvZGVkKCkgeworICAgICAgICBieXRlW10ga2V5ID0gbmV3IGJ5dGVbXSB7MSwgMiwgMywgNCwgNX07CisgICAgICAgIFN0cmluZyBhbGdvcml0aG0gPSAiQWxnb3JpdGhtIjsKKworICAgICAgICBTZWNyZXRLZXlTcGVjIGtzID0gbmV3IFNlY3JldEtleVNwZWMoa2V5LCBhbGdvcml0aG0pOworICAgICAgICBieXRlW10gcmVzdWx0ID0ga3MuZ2V0RW5jb2RlZCgpOworICAgICAgICBpZiAoISBBcnJheXMuZXF1YWxzKGtleSwgcmVzdWx0KSkgeworICAgICAgICAgICAgZmFpbCgiVGhlIHJldHVybmVkIGtleSBkb2VzIG5vdCBlcXVhbCB0byB0aGUgc3BlY2lmaWVkICIKKyAgICAgICAgICAgICAgICAgICAgKyAiaW4gdGhlIGNvbnN0cnVjdG9yLiIpOworICAgICAgICB9CisgICAgICAgIHJlc3VsdFswXSArKzsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBjaGFuZ2Ugb2YgcmV0dXJuZWQgYnkgZ2V0RW5jb2RlZCgpIG1ldGhvZCBrZXkgIgorICAgICAgICAgICAgICAgICAgICArICJzaG91bGQgbm90IGNhdXNlIHRoZSBjaGFuZ2Ugb2YgaW50ZXJuYWwgYXJyYXkuIiwKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0WzBdID09IGtzLmdldEVuY29kZWQoKVswXSk7CisKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS03OAorICAgICAgICBpbnQgb2Zmc2V0ID0gMTsKKyAgICAgICAgaW50IGxlbiA9IDQ7CisgICAgICAgIFNlY3JldEtleVNwZWMgc2tzID0gbmV3IFNlY3JldEtleVNwZWMoa2V5LCBvZmZzZXQsIGxlbiwgYWxnb3JpdGhtKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJLZXkgbGVuZ3RoIGlzIGluY29ycmVjdCIsIGxlbiwgc2tzLmdldEVuY29kZWQoKS5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGhhc2hDb2RlKCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIHRoYXQgZm9yIGVxdWFsIG9iamVjdHMgaGFzaCBjb2RlcworICAgICAqIGFyZSBlcXVhbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzaENvZGUoKSB7CisgICAgICAgIGJ5dGVbXSBrZXkgPSBuZXcgYnl0ZVtdIHsxLCAyLCAzLCA0LCA1fTsKKyAgICAgICAgU3RyaW5nIGFsZ29yaXRobSA9ICJBbGdvcml0aG0iOworCisgICAgICAgIFNlY3JldEtleVNwZWMga3MxID0gbmV3IFNlY3JldEtleVNwZWMoa2V5LCBhbGdvcml0aG0pOworICAgICAgICBTZWNyZXRLZXlTcGVjIGtzMiA9IG5ldyBTZWNyZXRLZXlTcGVjKGtleSwgYWxnb3JpdGhtKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRXF1YWwgb2JqZWN0cyBzaG91bGQgaGF2ZSB0aGUgc2FtZSBoYXNoIGNvZGVzLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtzMS5oYXNoQ29kZSgpID09IGtzMi5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBlcXVhbHMoT2JqZWN0IG9iaikgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIHRoZSBjb3JyZWN0bmVzcyBvZiBlcXVhbAorICAgICAqIG9wZXJhdGlvbjogaXQgc2hvdWxkIGJlIHJlZmxleGl2ZSwgc3ltbWV0cmljLCB0cmFuc2l0aXZlLCBjb25zaXN0ZW50CisgICAgICogYW5kIHNob3VsZCBiZSBmYWxzZSBvbiBudWxsIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXF1YWxzKCkgeworICAgICAgICBieXRlW10ga2V5ID0gbmV3IGJ5dGVbXSB7MSwgMiwgMywgNCwgNX07CisgICAgICAgIFN0cmluZyBhbGdvcml0aG0gPSAiQWxnb3JpdGhtIjsKKworICAgICAgICBTZWNyZXRLZXlTcGVjIGtzMSA9IG5ldyBTZWNyZXRLZXlTcGVjKGtleSwgYWxnb3JpdGhtKTsKKyAgICAgICAgU2VjcmV0S2V5U3BlYyBrczIgPSBuZXcgU2VjcmV0S2V5U3BlYyhrZXksIGFsZ29yaXRobSk7CisgICAgICAgIFNlY3JldEtleVNwZWMga3MzID0gbmV3IFNlY3JldEtleVNwZWMoa2V5LCBhbGdvcml0aG0pOworCisgICAgICAgIC8vIGNoZWNraW5nIGZvciByZWZsZXhpdmUgbGF3OgorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgZXF1aXZhbGVuY2UgcmVsYXRpb24gc2hvdWxkIGJlIHJlZmxleGl2ZS4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrczEuZXF1YWxzKGtzMSkpOworCisgICAgICAgIGFzc2VydFRydWUoIk9iamVjdHMgYnVpbHQgb24gdGhlIHNhbWUgcGFyYW1ldGVycyBzaG91bGQgYmUgZXF1YWwuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga3MxLmVxdWFscyhrczIpKTsKKyAgICAgICAgLy8gY2hlY2tpbmcgZm9yIHN5bW1ldHJpYyBsYXc6CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBlcXVpdmFsZW5jZSByZWxhdGlvbiBzaG91bGQgYmUgc3ltbWV0cmljLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtzMi5lcXVhbHMoa3MxKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiT2JqZWN0cyBidWlsdCBvbiB0aGUgZXF1YWwgcGFyYW1ldGVycyBzaG91bGQgYmUgZXF1YWwuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga3MyLmVxdWFscyhrczMpKTsKKyAgICAgICAgLy8gY2hlY2tpbmcgZm9yIHRyYW5zaXRpdmUgbGF3OgorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgZXF1aXZhbGVuY2UgcmVsYXRpb24gc2hvdWxkIGJlIHRyYW5zaXRpdmUuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga3MxLmVxdWFscyhrczMpKTsKKworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIG5vdCBiZSBlcXVhbCB0byBudWxsIG9iamVjdC4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrczEuZXF1YWxzKG51bGwpKTsKKworICAgICAgICBrczIgPSBuZXcgU2VjcmV0S2V5U3BlYyhuZXcgYnl0ZVtdIHsxfSwgYWxnb3JpdGhtKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIk9iamVjdHMgc2hvdWxkIG5vdCBiZSBlcXVhbC4iLCBrczEuZXF1YWxzKGtzMikpOworCisgICAgICAgIGtzMiA9IG5ldyBTZWNyZXRLZXlTcGVjKGtleSwgIkFub3RoZXIgQWxnb3JpdGhtIik7CisgICAgICAgIGFzc2VydEZhbHNlKCJPYmplY3RzIHNob3VsZCBub3QgYmUgZXF1YWwuIiwga3MxLmVxdWFscyhrczIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFRlc3Qgc3VpdGUoKSB7CisgICAgICAgIHJldHVybiBuZXcgVGVzdFN1aXRlKFNlY3JldEtleVNwZWNUZXN0LmNsYXNzKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL3N1cHBvcnQvRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9EYXRhLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9zdXBwb3J0L0VuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNkMzI1NWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9zdXBwb3J0L0VuY3J5cHRlZFByaXZhdGVLZXlJbmZvRGF0YS5qYXZhCkBAIC0wLDAgKzEsMTIyOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKKworLyoqCisgKgorICogU3VwcG9ydCBjbGFzcyBmb3IgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9fSW1wbFRlc3QgYW5kIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvX1Rlc3QKKyAqCisgKiBBbGwgYmluYXJ5IGRhdGEgZm9yIHRoZXNlIHRlc3RzIHdlcmUgZ2VuZXJhdGVkIHVzaW5nCisgKiBCRUEgSlJvY2tpdCBqMnNkazEuNC4yXzA0IChodHRwOi8vd3d3LmJlYS5jb20pIHdpdGgKKyAqIHNlY3VyaXR5IHByb3ZpZGVycyBsaXN0IGV4dGVuZGVkIGJ5IEJvdW5jeSBDYXN0bGUncyBvbmUKKyAqIChodHRwOi8vd3d3LmJvdW5jeWNhc3RsZS5vcmcpCisgKi8KK3B1YmxpYyBjbGFzcyBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0RhdGEgeworCisKKyAgICAvKioKKyAgICAgKiAidmFsaWQiIGVuY29kaW5nIGZvciBEU0Egd2l0aCBhbGcgcGFyYW1zCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIGRzYUVuY3J5cHRlZFByaXZhdGVLZXlJbmZvID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDA1LCAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4MzAsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDJiLCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MDcsCisgICAgICAgICAgICAoYnl0ZSkgMHgyYSwgKGJ5dGUpIDB4ODYsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHhjZSwgKGJ5dGUpIDB4MzgsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDMwLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDEsCisgICAgICAgICAgICAoYnl0ZSkgMHgxZSwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4MDAsCisgICAgICAgICAgICAoYnl0ZSkgMHg5ZiwgKGJ5dGUpIDB4NWUsIChieXRlKSAweDc2LCAoYnl0ZSkgMHgxOSwgKGJ5dGUpIDB4NTksCisgICAgICAgICAgICAoYnl0ZSkgMHhkOCwgKGJ5dGUpIDB4ZjcsIChieXRlKSAweDZiLCAoYnl0ZSkgMHg5MSwgKGJ5dGUpIDB4NmQsCisgICAgICAgICAgICAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4N2UsIChieXRlKSAweDE0LCAoYnl0ZSkgMHgyNywgKGJ5dGUpIDB4MjUsCisgICAgICAgICAgICAoYnl0ZSkgMHg2ZSwgKGJ5dGUpIDB4NTksIChieXRlKSAweDJjLCAoYnl0ZSkgMHhlYywgKGJ5dGUpIDB4MjEsCisgICAgICAgICAgICAoYnl0ZSkgMHg3YSwgKGJ5dGUpIDB4YjcsIChieXRlKSAweGQ0LCAoYnl0ZSkgMHhmNCwgKGJ5dGUpIDB4YTAsCisgICAgICAgICAgICAoYnl0ZSkgMHgyNiwgKGJ5dGUpIDB4NGUsIChieXRlKSAweDcyLCAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4MTgsCisgICAgICAgICAgICAoYnl0ZSkgMHg0YSwgKGJ5dGUpIDB4MWMsIChieXRlKSAweDlhLCAoYnl0ZSkgMHhjOSwgKGJ5dGUpIDB4Y2QsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4MWIsIChieXRlKSAweDM5LCAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4OWUsCisgICAgICAgICAgICAoYnl0ZSkgMHg1OCwgKGJ5dGUpIDB4MTYsIChieXRlKSAweGViLCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4ODQsCisgICAgICAgICAgICAoYnl0ZSkgMHgyOCwgKGJ5dGUpIDB4MmEsIChieXRlKSAweGI5LCAoYnl0ZSkgMHhjZSwgKGJ5dGUpIDB4YzcsCisgICAgICAgICAgICAoYnl0ZSkgMHg2ZCwgKGJ5dGUpIDB4NzQsIChieXRlKSAweDk5LCAoYnl0ZSkgMHhmZSwgKGJ5dGUpIDB4YTUsCisgICAgICAgICAgICAoYnl0ZSkgMHhlOCwgKGJ5dGUpIDB4NjYsIChieXRlKSAweGUxLCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4ZGQsCisgICAgICAgICAgICAoYnl0ZSkgMHgyZSwgKGJ5dGUpIDB4Y2YsIChieXRlKSAweGZlLCAoYnl0ZSkgMHhiOSwgKGJ5dGUpIDB4NmEsCisgICAgICAgICAgICAoYnl0ZSkgMHg4ZSwgKGJ5dGUpIDB4MTIsIChieXRlKSAweDRiLCAoYnl0ZSkgMHhhNCwgKGJ5dGUpIDB4YTgsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NywgKGJ5dGUpIDB4ZDcsIChieXRlKSAweGFiLCAoYnl0ZSkgMHgyNiwgKGJ5dGUpIDB4ZDYsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMywgKGJ5dGUpIDB4ZDEsIChieXRlKSAweDNiLCAoYnl0ZSkgMHg5NSwgKGJ5dGUpIDB4YzQsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NywgKGJ5dGUpIDB4MmMsIChieXRlKSAweGRjLCAoYnl0ZSkgMHhhYiwgKGJ5dGUpIDB4NWQsCisgICAgICAgICAgICAoYnl0ZSkgMHhmNSwgKGJ5dGUpIDB4NTUsIChieXRlKSAweGFlLCAoYnl0ZSkgMHg1OCwgKGJ5dGUpIDB4NjgsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NCwgKGJ5dGUpIDB4NDEsIChieXRlKSAweDk5LCAoYnl0ZSkgMHgxYiwgKGJ5dGUpIDB4ZDMsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMCwgKGJ5dGUpIDB4ZDksIChieXRlKSAweGQzLCAoYnl0ZSkgMHhkZCwgKGJ5dGUpIDB4ZjUsCisgICAgICAgICAgICAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4MDQsIChieXRlKSAweGEyLCAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4NjEsCisgICAgICAgICAgICAoYnl0ZSkgMHhmOCwgKGJ5dGUpIDB4YjEsIChieXRlKSAweGU2LCAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4NjUsCisgICAgICAgICAgICAoYnl0ZSkgMHg4ZiwgKGJ5dGUpIDB4YTQsIChieXRlKSAweDk3LCAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4MWQsCisgICAgICAgICAgICAoYnl0ZSkgMHgzZiwgKGJ5dGUpIDB4MmIsIChieXRlKSAweDg1LCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4ZDUsCisgICAgICAgICAgICAoYnl0ZSkgMHhjYiwgKGJ5dGUpIDB4OGQsIChieXRlKSAweDY2LCAoYnl0ZSkgMHg5YSwgKGJ5dGUpIDB4YWMsCisgICAgICAgICAgICAoYnl0ZSkgMHg3YiwgKGJ5dGUpIDB4NWYsIChieXRlKSAweGM3LCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MTUsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4OWEsIChieXRlKSAweGZiLCAoYnl0ZSkgMHg2ZiwgKGJ5dGUpIDB4NzIsCisgICAgICAgICAgICAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAzLCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4MmEsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNiwgKGJ5dGUpIDB4Y2EsIChieXRlKSAweDYwLCAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4NDcsCisgICAgICAgICAgICAoYnl0ZSkgMHhkZSwgKGJ5dGUpIDB4NGIsIChieXRlKSAweDBmLCAoYnl0ZSkgMHhkNiwgKGJ5dGUpIDB4NzMsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNywgKGJ5dGUpIDB4MDIsIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4NWQsCisgICAgICAgICAgICAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4MjgsIChieXRlKSAweDY0LCAoYnl0ZSkgMHhiMiwgKGJ5dGUpIDB4MmIsCisgICAgICAgICAgICAoYnl0ZSkgMHhlYiwgKGJ5dGUpIDB4ODUsIChieXRlKSAweGI0LCAoYnl0ZSkgMHgxNCwgKGJ5dGUpIDB4MGQsCisgICAgICAgICAgICAoYnl0ZSkgMHhhZCwgKGJ5dGUpIDB4ZWMsIChieXRlKSAweGM4LCAoYnl0ZSkgMHgxZiwgKGJ5dGUpIDB4OTYsCisgICAgICAgICAgICAoYnl0ZSkgMHgxZSwgKGJ5dGUpIDB4NmEsIChieXRlKSAweDUyLCAoYnl0ZSkgMHhkNCwgKGJ5dGUpIDB4MGIsCisgICAgICAgICAgICAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4YjAsIChieXRlKSAweDMzLCAoYnl0ZSkgMHhhMSwgKGJ5dGUpIDB4ZDEsCisgICAgICAgICAgICAoYnl0ZSkgMHhiYywgKGJ5dGUpIDB4NjQsIChieXRlKSAweGQ2LCAoYnl0ZSkgMHg2NCwgKGJ5dGUpIDB4ZWYsCisgICAgICAgICAgICAoYnl0ZSkgMHgyYywgKGJ5dGUpIDB4ODksIChieXRlKSAweGM3LCAoYnl0ZSkgMHgzOSwgKGJ5dGUpIDB4NzUsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NywgKGJ5dGUpIDB4ODIsIChieXRlKSAweDYxLCAoYnl0ZSkgMHhiZSwgKGJ5dGUpIDB4ZDEsCisgICAgICAgICAgICAoYnl0ZSkgMHhjZCwgKGJ5dGUpIDB4NzAsIChieXRlKSAweDQxLCAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4OTksCisgICAgICAgICAgICAoYnl0ZSkgMHg1NSwgKGJ5dGUpIDB4NzUsIChieXRlKSAweDZmLCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4YzAsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4ZjEsIChieXRlKSAweDBjLCAoYnl0ZSkgMHg3OCwgKGJ5dGUpIDB4MWYsCisgICAgICAgICAgICAoYnl0ZSkgMHhlOCwgKGJ5dGUpIDB4NjMsIChieXRlKSAweDVkLCAoYnl0ZSkgMHhmYSwgKGJ5dGUpIDB4MzcsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMSwgKGJ5dGUpIDB4Y2UsIChieXRlKSAweDk3LCAoYnl0ZSkgMHg3NiwgKGJ5dGUpIDB4YTUsCisgICAgICAgICAgICAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4NWIsIChieXRlKSAweDg4LCAoYnl0ZSkgMHhlNCwgKGJ5dGUpIDB4ZDUsCisgICAgICAgICAgICAoYnl0ZSkgMHhiOCwgKGJ5dGUpIDB4MDYsIChieXRlKSAweGY1LCAoYnl0ZSkgMHg3ZiwgKGJ5dGUpIDB4OTIsCisgICAgICAgICAgICAoYnl0ZSkgMHhkYSwgKGJ5dGUpIDB4OTksIChieXRlKSAweGE1LCAoYnl0ZSkgMHg1YSwgKGJ5dGUpIDB4NjQsCisgICAgICAgICAgICAoYnl0ZSkgMHhjOSwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDJjLCAoYnl0ZSkgMHg3NywgKGJ5dGUpIDB4NTgsCisgICAgICAgICAgICAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4YTYsIChieXRlKSAweDM1LCAoYnl0ZSkgMHgxZCwgKGJ5dGUpIDB4NzEsCisgICAgICAgICAgICAoYnl0ZSkgMHhmYiwgKGJ5dGUpIDB4NDksIChieXRlKSAweDI0LCAoYnl0ZSkgMHg2YywgKGJ5dGUpIDB4MzQsCisgICAgICAgICAgICAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4YTAsIChieXRlKSAweDQ3LCAoYnl0ZSkgMHhmMSwgKGJ5dGUpIDB4MTQsCisgICAgICAgICAgICAoYnl0ZSkgMHhhZCwgKGJ5dGUpIDB4YzIsIChieXRlKSAweDg1LCAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4ZGQsCisgICAgICAgICAgICAoYnl0ZSkgMHgyYywgKGJ5dGUpIDB4NzgsIChieXRlKSAweDJhLCAoYnl0ZSkgMHg1YSwgKGJ5dGUpIDB4MjQsCisgICAgICAgICAgICAoYnl0ZSkgMHg3ZiwgKGJ5dGUpIDB4MTksIChieXRlKSAweGY0LCAoYnl0ZSkgMHgwYSwgKGJ5dGUpIDB4MmUsCisgICAgICAgICAgICAoYnl0ZSkgMHgxZCwgKGJ5dGUpIDB4OTIsIChieXRlKSAweDgwLCAoYnl0ZSkgMHhlNSwgKGJ5dGUpIDB4ZTQsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4MjgsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg1YywgLy8gMzgKKyAgICAgICAgICAgIChieXRlKSAweDM0LCAoYnl0ZSkgMHhjOCwgKGJ5dGUpIDB4MjIsIChieXRlKSAweDA0LCAoYnl0ZSkgMHg4MiwKKyAgICAgICAgICAgIChieXRlKSAweDA0LCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIC8vCisgICAgICAgICAgICAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDAzLCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MDUsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MDcsIChieXRlKSAweDA4LCAoYnl0ZSkgMHgwOSwgKGJ5dGUpIDB4MGEsCisgICAgICAgICAgICAoYnl0ZSkgMHgwYiwgKGJ5dGUpIDB4MGMsIChieXRlKSAweDBkLCAoYnl0ZSkgMHgwZSwgKGJ5dGUpIDB4MGYsCisgICAgICAgICAgICAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4MTEsIChieXRlKSAweDEyLCAoYnl0ZSkgMHgxMywgKGJ5dGUpIDB4MTQsCisgICAgICAgICAgICAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4MTYsIChieXRlKSAweDE3LCAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4MTksCisgICAgICAgICAgICAoYnl0ZSkgMHgxYSwgKGJ5dGUpIDB4MWIsIChieXRlKSAweDFjLCAoYnl0ZSkgMHgxZCwgKGJ5dGUpIDB4MWUsCisgICAgICAgICAgICAoYnl0ZSkgMHgxZiwgKGJ5dGUpIDB4MjAsIChieXRlKSAweDIxLCAoYnl0ZSkgMHgyMiwgKGJ5dGUpIDB4MjMsCisgICAgICAgICAgICAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4MjUsIChieXRlKSAweDI2LCAoYnl0ZSkgMHgyNywgKGJ5dGUpIDB4MjgsCisgICAgICAgICAgICAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4MmEsIChieXRlKSAweDJiLCAoYnl0ZSkgMHgyYywgKGJ5dGUpIDB4MmQsCisgICAgICAgICAgICAoYnl0ZSkgMHgyZSwgKGJ5dGUpIDB4MmYsIChieXRlKSAweDMwLCAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4MzIsCisgICAgICAgICAgICAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4MzQsIChieXRlKSAweDM1LCAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4MzcsCisgICAgICAgICAgICAoYnl0ZSkgMHgzOCwgKGJ5dGUpIDB4MzksIChieXRlKSAweDNhLCAoYnl0ZSkgMHgzYiwgKGJ5dGUpIDB4M2MsCisgICAgICAgICAgICAoYnl0ZSkgMHgzZCwgKGJ5dGUpIDB4M2UsIChieXRlKSAweDNmLCAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NDEsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4NDMsIChieXRlKSAweDQ0LCAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4NDYsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NywgKGJ5dGUpIDB4NDgsIChieXRlKSAweDQ5LCAoYnl0ZSkgMHg0YSwgKGJ5dGUpIDB4NGIsCisgICAgICAgICAgICAoYnl0ZSkgMHg0YywgKGJ5dGUpIDB4NGQsIChieXRlKSAweDRlLCAoYnl0ZSkgMHg0ZiwgKGJ5dGUpIDB4NTAsCisgICAgICAgICAgICAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4NTIsIChieXRlKSAweDUzLCAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4NTUsCisgICAgICAgICAgICAoYnl0ZSkgMHg1NiwgKGJ5dGUpIDB4NTcsIChieXRlKSAweDU4LCAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4NWEsCisgICAgICAgICAgICAoYnl0ZSkgMHg1YiwgKGJ5dGUpIDB4NWMsIChieXRlKSAweDVkLCAoYnl0ZSkgMHg1ZSwgKGJ5dGUpIDB4NWYsCisgICAgICAgICAgICAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4NjEsIChieXRlKSAweDYyLCAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4NjQsCisgICAgICAgICAgICAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4NjYsIChieXRlKSAweDY3LCAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4NjksCisgICAgICAgICAgICAoYnl0ZSkgMHg2YSwgKGJ5dGUpIDB4NmIsIChieXRlKSAweDZjLCAoYnl0ZSkgMHg2ZCwgKGJ5dGUpIDB4NmUsCisgICAgICAgICAgICAoYnl0ZSkgMHg2ZiwgKGJ5dGUpIDB4NzAsIChieXRlKSAweDcxLCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4NzMsCisgICAgICAgICAgICAoYnl0ZSkgMHg3NCwgKGJ5dGUpIDB4NzUsIChieXRlKSAweDc2LCAoYnl0ZSkgMHg3NywgKGJ5dGUpIDB4NzgsCisgICAgICAgICAgICAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4N2EsIChieXRlKSAweDdiLCAoYnl0ZSkgMHg3YywgKGJ5dGUpIDB4N2QsCisgICAgICAgICAgICAoYnl0ZSkgMHg3ZSwgKGJ5dGUpIDB4N2YsIChieXRlKSAweDgwLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODIsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MywgKGJ5dGUpIDB4ODQsIChieXRlKSAweDg1LCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4ODcsCisgICAgICAgICAgICAoYnl0ZSkgMHg4OCwgKGJ5dGUpIDB4ODksIChieXRlKSAweDhhLCAoYnl0ZSkgMHg4YiwgKGJ5dGUpIDB4OGMsCisgICAgICAgICAgICAoYnl0ZSkgMHg4ZCwgKGJ5dGUpIDB4OGUsIChieXRlKSAweDhmLCAoYnl0ZSkgMHg5MCwgKGJ5dGUpIDB4OTEsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4OTMsIChieXRlKSAweDk0LCAoYnl0ZSkgMHg5NSwgKGJ5dGUpIDB4OTYsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NywgKGJ5dGUpIDB4OTgsIChieXRlKSAweDk5LCAoYnl0ZSkgMHg5YSwgKGJ5dGUpIDB4OWIsCisgICAgICAgICAgICAoYnl0ZSkgMHg5YywgKGJ5dGUpIDB4OWQsIChieXRlKSAweDllLCAoYnl0ZSkgMHg5ZiwgKGJ5dGUpIDB4YTAsCisgICAgICAgICAgICAoYnl0ZSkgMHhhMSwgKGJ5dGUpIDB4YTIsIChieXRlKSAweGEzLCAoYnl0ZSkgMHhhNCwgKGJ5dGUpIDB4YTUsCisgICAgICAgICAgICAoYnl0ZSkgMHhhNiwgKGJ5dGUpIDB4YTcsIChieXRlKSAweGE4LCAoYnl0ZSkgMHhhOSwgKGJ5dGUpIDB4YWEsCisgICAgICAgICAgICAoYnl0ZSkgMHhhYiwgKGJ5dGUpIDB4YWMsIChieXRlKSAweGFkLCAoYnl0ZSkgMHhhZSwgKGJ5dGUpIDB4YWYsCisgICAgICAgICAgICAoYnl0ZSkgMHhiMCwgKGJ5dGUpIDB4YjEsIChieXRlKSAweGIyLCAoYnl0ZSkgMHhiMywgKGJ5dGUpIDB4YjQsCisgICAgICAgICAgICAoYnl0ZSkgMHhiNSwgKGJ5dGUpIDB4YjYsIChieXRlKSAweGI3LCAoYnl0ZSkgMHhiOCwgKGJ5dGUpIDB4YjksCisgICAgICAgICAgICAoYnl0ZSkgMHhiYSwgKGJ5dGUpIDB4YmIsIChieXRlKSAweGJjLCAoYnl0ZSkgMHhiZCwgKGJ5dGUpIDB4YmUsCisgICAgICAgICAgICAoYnl0ZSkgMHhiZiwgKGJ5dGUpIDB4YzAsIChieXRlKSAweGMxLCAoYnl0ZSkgMHhjMiwgKGJ5dGUpIDB4YzMsCisgICAgICAgICAgICAoYnl0ZSkgMHhjNCwgKGJ5dGUpIDB4YzUsIChieXRlKSAweGM2LCAoYnl0ZSkgMHhjNywgKGJ5dGUpIDB4YzgsCisgICAgICAgICAgICAoYnl0ZSkgMHhjOSwgKGJ5dGUpIDB4Y2EsIChieXRlKSAweGNiLCAoYnl0ZSkgMHhjYywgKGJ5dGUpIDB4Y2QsCisgICAgICAgICAgICAoYnl0ZSkgMHhjZSwgKGJ5dGUpIDB4Y2YsIChieXRlKSAweGQwLCAoYnl0ZSkgMHhkMSwgKGJ5dGUpIDB4ZDIsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMywgKGJ5dGUpIDB4ZDQsIChieXRlKSAweGQ1LCAoYnl0ZSkgMHhkNiwgKGJ5dGUpIDB4ZDcsCisgICAgICAgICAgICAoYnl0ZSkgMHhkOCwgKGJ5dGUpIDB4ZDksIChieXRlKSAweGRhLCAoYnl0ZSkgMHhkYiwgKGJ5dGUpIDB4ZGMsCisgICAgICAgICAgICAoYnl0ZSkgMHhkZCwgKGJ5dGUpIDB4ZGUsIChieXRlKSAweGRmLCAoYnl0ZSkgMHhlMCwgKGJ5dGUpIDB4ZTEsCisgICAgICAgICAgICAoYnl0ZSkgMHhlMiwgKGJ5dGUpIDB4ZTMsIChieXRlKSAweGU0LCAoYnl0ZSkgMHhlNSwgKGJ5dGUpIDB4ZTYsCisgICAgICAgICAgICAoYnl0ZSkgMHhlNywgKGJ5dGUpIDB4ZTgsIChieXRlKSAweGU5LCAoYnl0ZSkgMHhlYSwgKGJ5dGUpIDB4ZWIsCisgICAgICAgICAgICAoYnl0ZSkgMHhlYywgKGJ5dGUpIDB4ZWQsIChieXRlKSAweGVlLCAoYnl0ZSkgMHhlZiwgKGJ5dGUpIDB4ZjAsCisgICAgICAgICAgICAoYnl0ZSkgMHhmMSwgKGJ5dGUpIDB4ZjIsIChieXRlKSAweGYzLCAoYnl0ZSkgMHhmNCwgKGJ5dGUpIDB4ZjUsCisgICAgICAgICAgICAoYnl0ZSkgMHhmNiwgKGJ5dGUpIDB4ZjcsIChieXRlKSAweGY4LCAoYnl0ZSkgMHhmOSwgKGJ5dGUpIDB4ZmEsCisgICAgICAgICAgICAoYnl0ZSkgMHhmYiwgKGJ5dGUpIDB4ZmMsIChieXRlKSAweGZkLCAoYnl0ZSkgMHhmZSwgKGJ5dGUpIDB4ZmYsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MDQsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4MDYsIChieXRlKSAweDA3LCAoYnl0ZSkgMHgwOCwgKGJ5dGUpIDB4MDksCisgICAgICAgICAgICAoYnl0ZSkgMHgwYSwgKGJ5dGUpIDB4MGIsIChieXRlKSAweDBjLCAoYnl0ZSkgMHgwZCwgKGJ5dGUpIDB4MGUsCisgICAgICAgICAgICAoYnl0ZSkgMHgwZiwgKGJ5dGUpIDB4MTAsIChieXRlKSAweDExLCAoYnl0ZSkgMHgxMiwgKGJ5dGUpIDB4MTMsCisgICAgICAgICAgICAoYnl0ZSkgMHgxNCwgKGJ5dGUpIDB4MTUsIChieXRlKSAweDE2LCAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4MTgsCisgICAgICAgICAgICAoYnl0ZSkgMHgxOSwgKGJ5dGUpIDB4MWEsIChieXRlKSAweDFiLCAoYnl0ZSkgMHgxYywgKGJ5dGUpIDB4MWQsCisgICAgICAgICAgICAoYnl0ZSkgMHgxZSwgKGJ5dGUpIDB4MWYsIChieXRlKSAweDIwLCAoYnl0ZSkgMHgyMSwgKGJ5dGUpIDB4MjIsCisgICAgICAgICAgICAoYnl0ZSkgMHgyMywgKGJ5dGUpIDB4MjQsIChieXRlKSAweDI1LCAoYnl0ZSkgMHgyNiwgKGJ5dGUpIDB4MjcsCisgICAgICAgICAgICAoYnl0ZSkgMHgyOCwgKGJ5dGUpIDB4MjksIChieXRlKSAweDJhLCAoYnl0ZSkgMHgyYiwgKGJ5dGUpIDB4MmMsCisgICAgICAgICAgICAoYnl0ZSkgMHgyZCwgKGJ5dGUpIDB4MmUsIChieXRlKSAweDJmLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4MzEsCisgICAgICAgICAgICAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4MzMsIChieXRlKSAweDM0LCAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4MzYsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNywgKGJ5dGUpIDB4MzgsIChieXRlKSAweDM5LCAoYnl0ZSkgMHgzYSwgKGJ5dGUpIDB4M2IsCisgICAgICAgICAgICAoYnl0ZSkgMHgzYywgKGJ5dGUpIDB4M2QsIChieXRlKSAweDNlLCAoYnl0ZSkgMHgzZiwgKGJ5dGUpIDB4NDAsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4NDIsIChieXRlKSAweDQzLCAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4NDUsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NiwgKGJ5dGUpIDB4NDcsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg0OSwgKGJ5dGUpIDB4NGEsCisgICAgICAgICAgICAoYnl0ZSkgMHg0YiwgKGJ5dGUpIDB4NGMsIChieXRlKSAweDRkLCAoYnl0ZSkgMHg0ZSwgKGJ5dGUpIDB4NGYsCisgICAgICAgICAgICAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NTEsIChieXRlKSAweDUyLCAoYnl0ZSkgMHg1MywgKGJ5dGUpIDB4NTQsCisgICAgICAgICAgICAoYnl0ZSkgMHg1NSwgKGJ5dGUpIDB4NTYsIChieXRlKSAweDU3LCAoYnl0ZSkgMHg1OCwgKGJ5dGUpIDB4NTksCisgICAgICAgICAgICAoYnl0ZSkgMHg1YSwgKGJ5dGUpIDB4NWIsIChieXRlKSAweDVjLCAoYnl0ZSkgMHg1ZCwgKGJ5dGUpIDB4NWUsCisgICAgICAgICAgICAoYnl0ZSkgMHg1ZiwgKGJ5dGUpIDB4NjAsIChieXRlKSAweDYxLCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4NjMsCisgICAgICAgICAgICAoYnl0ZSkgMHg2NCwgKGJ5dGUpIDB4NjUsIChieXRlKSAweDY2LCAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4NjgsCisgICAgICAgICAgICAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4NmEsIChieXRlKSAweDZiLCAoYnl0ZSkgMHg2YywgKGJ5dGUpIDB4NmQsCisgICAgICAgICAgICAoYnl0ZSkgMHg2ZSwgKGJ5dGUpIDB4NmYsIChieXRlKSAweDcwLCAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4NzIsCisgICAgICAgICAgICAoYnl0ZSkgMHg3MywgKGJ5dGUpIDB4NzQsIChieXRlKSAweDc1LCAoYnl0ZSkgMHg3NiwgKGJ5dGUpIDB4NzcsCisgICAgICAgICAgICAoYnl0ZSkgMHg3OCwgKGJ5dGUpIDB4NzksIChieXRlKSAweDdhLCAoYnl0ZSkgMHg3YiwgKGJ5dGUpIDB4N2MsCisgICAgICAgICAgICAoYnl0ZSkgMHg3ZCwgKGJ5dGUpIDB4N2UsIChieXRlKSAweDdmLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4ODEsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4ODMsIChieXRlKSAweDg0LCAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4ODYsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NywgKGJ5dGUpIDB4ODgsIChieXRlKSAweDg5LCAoYnl0ZSkgMHg4YSwgKGJ5dGUpIDB4OGIsCisgICAgICAgICAgICAoYnl0ZSkgMHg4YywgKGJ5dGUpIDB4OGQsIChieXRlKSAweDhlLCAoYnl0ZSkgMHg4ZiwgKGJ5dGUpIDB4OTAsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MSwgKGJ5dGUpIDB4OTIsIChieXRlKSAweDkzLCAoYnl0ZSkgMHg5NCwgKGJ5dGUpIDB4OTUsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NiwgKGJ5dGUpIDB4OTcsIChieXRlKSAweDk4LCAoYnl0ZSkgMHg5OSwgKGJ5dGUpIDB4OWEsCisgICAgICAgICAgICAoYnl0ZSkgMHg5YiwgKGJ5dGUpIDB4OWMsIChieXRlKSAweDlkLCAoYnl0ZSkgMHg5ZSwgKGJ5dGUpIDB4OWYsCisgICAgICAgICAgICAoYnl0ZSkgMHhhMCwgKGJ5dGUpIDB4YTEsIChieXRlKSAweGEyLCAoYnl0ZSkgMHhhMywgKGJ5dGUpIDB4YTQsCisgICAgICAgICAgICAoYnl0ZSkgMHhhNSwgKGJ5dGUpIDB4YTYsIChieXRlKSAweGE3LCAoYnl0ZSkgMHhhOCwgKGJ5dGUpIDB4YTksCisgICAgICAgICAgICAoYnl0ZSkgMHhhYSwgKGJ5dGUpIDB4YWIsIChieXRlKSAweGFjLCAoYnl0ZSkgMHhhZCwgKGJ5dGUpIDB4YWUsCisgICAgICAgICAgICAoYnl0ZSkgMHhhZiwgKGJ5dGUpIDB4YjAsIChieXRlKSAweGIxLCAoYnl0ZSkgMHhiMiwgKGJ5dGUpIDB4YjMsCisgICAgICAgICAgICAoYnl0ZSkgMHhiNCwgKGJ5dGUpIDB4YjUsIChieXRlKSAweGI2LCAoYnl0ZSkgMHhiNywgKGJ5dGUpIDB4YjgsCisgICAgICAgICAgICAoYnl0ZSkgMHhiOSwgKGJ5dGUpIDB4YmEsIChieXRlKSAweGJiLCAoYnl0ZSkgMHhiYywgKGJ5dGUpIDB4YmQsCisgICAgICAgICAgICAoYnl0ZSkgMHhiZSwgKGJ5dGUpIDB4YmYsIChieXRlKSAweGMwLCAoYnl0ZSkgMHhjMSwgKGJ5dGUpIDB4YzIsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMywgKGJ5dGUpIDB4YzQsIChieXRlKSAweGM1LCAoYnl0ZSkgMHhjNiwgKGJ5dGUpIDB4YzcsCisgICAgICAgICAgICAoYnl0ZSkgMHhjOCwgKGJ5dGUpIDB4YzksIChieXRlKSAweGNhLCAoYnl0ZSkgMHhjYiwgKGJ5dGUpIDB4Y2MsCisgICAgICAgICAgICAoYnl0ZSkgMHhjZCwgKGJ5dGUpIDB4Y2UsIChieXRlKSAweGNmLCAoYnl0ZSkgMHhkMCwgKGJ5dGUpIDB4ZDEsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMiwgKGJ5dGUpIDB4ZDMsIChieXRlKSAweGQ0LCAoYnl0ZSkgMHhkNSwgKGJ5dGUpIDB4ZDYsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNywgKGJ5dGUpIDB4ZDgsIChieXRlKSAweGQ5LCAoYnl0ZSkgMHhkYSwgKGJ5dGUpIDB4ZGIsCisgICAgICAgICAgICAoYnl0ZSkgMHhkYywgKGJ5dGUpIDB4ZGQsIChieXRlKSAweGRlLCAoYnl0ZSkgMHhkZiwgKGJ5dGUpIDB4ZTAsCisgICAgICAgICAgICAoYnl0ZSkgMHhlMSwgKGJ5dGUpIDB4ZTIsIChieXRlKSAweGUzLCAoYnl0ZSkgMHhlNCwgKGJ5dGUpIDB4ZTUsCisgICAgICAgICAgICAoYnl0ZSkgMHhlNiwgKGJ5dGUpIDB4ZTcsIChieXRlKSAweGU4LCAoYnl0ZSkgMHhlOSwgKGJ5dGUpIDB4ZWEsCisgICAgICAgICAgICAoYnl0ZSkgMHhlYiwgKGJ5dGUpIDB4ZWMsIChieXRlKSAweGVkLCAoYnl0ZSkgMHhlZSwgKGJ5dGUpIDB4ZWYsCisgICAgICAgICAgICAoYnl0ZSkgMHhmMCwgKGJ5dGUpIDB4ZjEsIChieXRlKSAweGYyLCAoYnl0ZSkgMHhmMywgKGJ5dGUpIDB4ZjQsCisgICAgICAgICAgICAoYnl0ZSkgMHhmNSwgKGJ5dGUpIDB4ZjYsIChieXRlKSAweGY3LCAoYnl0ZSkgMHhmOCwgKGJ5dGUpIDB4ZjksCisgICAgICAgICAgICAoYnl0ZSkgMHhmYSwgKGJ5dGUpIDB4ZmIsIChieXRlKSAweGZjLCAoYnl0ZSkgMHhmZCwgKGJ5dGUpIDB4ZmUsCisgICAgICAgICAgICAoYnl0ZSkgMHhmZiwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDMsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MDUsIChieXRlKSAweDA2LCAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4MDgsCisgICAgICAgICAgICAoYnl0ZSkgMHgwOSwgKGJ5dGUpIDB4MGEsIChieXRlKSAweDBiLCAoYnl0ZSkgMHgwYywgKGJ5dGUpIDB4MGQsCisgICAgICAgICAgICAoYnl0ZSkgMHgwZSwgKGJ5dGUpIDB4MGYsIChieXRlKSAweDEwLCAoYnl0ZSkgMHgxMSwgKGJ5dGUpIDB4MTIsCisgICAgICAgICAgICAoYnl0ZSkgMHgxMywgKGJ5dGUpIDB4MTQsIChieXRlKSAweDE1LCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4MTcsCisgICAgICAgICAgICAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4MTksIChieXRlKSAweDFhLCAoYnl0ZSkgMHgxYiwgKGJ5dGUpIDB4MWMsCisgICAgICAgICAgICAoYnl0ZSkgMHgxZCwgKGJ5dGUpIDB4MWUsIChieXRlKSAweDFmLCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4MjEsCisgICAgICAgICAgICAoYnl0ZSkgMHgyMiwgKGJ5dGUpIDB4MjMsIChieXRlKSAweDI0LCAoYnl0ZSkgMHgyNSwgKGJ5dGUpIDB4MjYsCisgICAgICAgICAgICAoYnl0ZSkgMHgyNywgKGJ5dGUpIDB4MjgsIChieXRlKSAweDI5LCAoYnl0ZSkgMHgyYSwgKGJ5dGUpIDB4MmIsCisgICAgICAgICAgICAoYnl0ZSkgMHgyYywgKGJ5dGUpIDB4MmQsIChieXRlKSAweDJlLCAoYnl0ZSkgMHgyZiwgKGJ5dGUpIDB4MzAsCisgICAgICAgICAgICAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4MzIsIChieXRlKSAweDMzLCAoYnl0ZSkgMHgzNCwgKGJ5dGUpIDB4MzUsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4MzcsIChieXRlKSAweDM4LCAoYnl0ZSkgMHgzOSwgKGJ5dGUpIDB4M2EsCisgICAgICAgICAgICAoYnl0ZSkgMHgzYiwgKGJ5dGUpIDB4M2MsIChieXRlKSAweDNkLCAoYnl0ZSkgMHgzZSwgKGJ5dGUpIDB4M2YsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NDEsIChieXRlKSAweDQyLCAoYnl0ZSkgMHg0MywgKGJ5dGUpIDB4NDQsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4NDYsIChieXRlKSAweDQ3LCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4NDksCisgICAgICAgICAgICAoYnl0ZSkgMHg0YSwgKGJ5dGUpIDB4NGIsIChieXRlKSAweDRjLCAoYnl0ZSkgMHg0ZCwgKGJ5dGUpIDB4NGUsCisgICAgICAgICAgICAoYnl0ZSkgMHg0ZiwgKGJ5dGUpIDB4NTAsIChieXRlKSAweDUxLCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4NTMsCisgICAgICAgICAgICAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDU2LCAoYnl0ZSkgMHg1NywgKGJ5dGUpIDB4NTgsCisgICAgICAgICAgICAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4NWEsIChieXRlKSAweDViLCAoYnl0ZSkgMHg1YywgKGJ5dGUpIDB4NWQsCisgICAgICAgICAgICAoYnl0ZSkgMHg1ZSwgKGJ5dGUpIDB4NWYsIChieXRlKSAweDYwLCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4NjIsCisgICAgICAgICAgICAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4NjQsIChieXRlKSAweDY1LCAoYnl0ZSkgMHg2NiwgKGJ5dGUpIDB4NjcsCisgICAgICAgICAgICAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4NjksIChieXRlKSAweDZhLCAoYnl0ZSkgMHg2YiwgKGJ5dGUpIDB4NmMsCisgICAgICAgICAgICAoYnl0ZSkgMHg2ZCwgKGJ5dGUpIDB4NmUsIChieXRlKSAweDZmLCAoYnl0ZSkgMHg3MCwgKGJ5dGUpIDB4NzEsCisgICAgICAgICAgICAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4NzMsIChieXRlKSAweDc0LCAoYnl0ZSkgMHg3NSwgKGJ5dGUpIDB4NzYsCisgICAgICAgICAgICAoYnl0ZSkgMHg3NywgKGJ5dGUpIDB4NzgsIChieXRlKSAweDc5LCAoYnl0ZSkgMHg3YSwgKGJ5dGUpIDB4N2IsCisgICAgICAgICAgICAoYnl0ZSkgMHg3YywgKGJ5dGUpIDB4N2QsIChieXRlKSAweDdlLCAoYnl0ZSkgMHg3ZiwgKGJ5dGUpIDB4ODAsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDgzLCAoYnl0ZSkgMHg4NCwgKGJ5dGUpIDB4ODUsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4ODcsIChieXRlKSAweDg4LCAoYnl0ZSkgMHg4OSwgKGJ5dGUpIDB4OGEsCisgICAgICAgICAgICAoYnl0ZSkgMHg4YiwgKGJ5dGUpIDB4OGMsIChieXRlKSAweDhkLCAoYnl0ZSkgMHg4ZSwgKGJ5dGUpIDB4OGYsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MCwgKGJ5dGUpIDB4OTEsIChieXRlKSAweDkyLCAoYnl0ZSkgMHg5MywgKGJ5dGUpIDB4OTQsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NSwgKGJ5dGUpIDB4OTYsIChieXRlKSAweDk3LCAoYnl0ZSkgMHg5OCwgKGJ5dGUpIDB4OTksCisgICAgICAgICAgICAoYnl0ZSkgMHg5YSwgKGJ5dGUpIDB4OWIsIChieXRlKSAweDljLCAoYnl0ZSkgMHg5ZCwgKGJ5dGUpIDB4OWUsCisgICAgICAgICAgICAoYnl0ZSkgMHg5ZiwgKGJ5dGUpIDB4YTAsIChieXRlKSAweGExLCAoYnl0ZSkgMHhhMiwgKGJ5dGUpIDB4YTMsCisgICAgICAgICAgICAoYnl0ZSkgMHhhNCwgKGJ5dGUpIDB4YTUsIChieXRlKSAweGE2LCAoYnl0ZSkgMHhhNywgKGJ5dGUpIDB4YTgsCisgICAgICAgICAgICAoYnl0ZSkgMHhhOSwgKGJ5dGUpIDB4YWEsIChieXRlKSAweGFiLCAoYnl0ZSkgMHhhYywgKGJ5dGUpIDB4YWQsCisgICAgICAgICAgICAoYnl0ZSkgMHhhZSwgKGJ5dGUpIDB4YWYsIChieXRlKSAweGIwLCAoYnl0ZSkgMHhiMSwgKGJ5dGUpIDB4YjIsCisgICAgICAgICAgICAoYnl0ZSkgMHhiMywgKGJ5dGUpIDB4YjQsIChieXRlKSAweGI1LCAoYnl0ZSkgMHhiNiwgKGJ5dGUpIDB4YjcsCisgICAgICAgICAgICAoYnl0ZSkgMHhiOCwgKGJ5dGUpIDB4YjksIChieXRlKSAweGJhLCAoYnl0ZSkgMHhiYiwgKGJ5dGUpIDB4YmMsCisgICAgICAgICAgICAoYnl0ZSkgMHhiZCwgKGJ5dGUpIDB4YmUsIChieXRlKSAweGJmLCAoYnl0ZSkgMHhjMCwgKGJ5dGUpIDB4YzEsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMiwgKGJ5dGUpIDB4YzMsIChieXRlKSAweGM0LCAoYnl0ZSkgMHhjNSwgKGJ5dGUpIDB4YzYsCisgICAgICAgICAgICAoYnl0ZSkgMHhjNywgKGJ5dGUpIDB4YzgsIChieXRlKSAweGM5LCAoYnl0ZSkgMHhjYSwgKGJ5dGUpIDB4Y2IsCisgICAgICAgICAgICAoYnl0ZSkgMHhjYywgKGJ5dGUpIDB4Y2QsIChieXRlKSAweGNlLCAoYnl0ZSkgMHhjZiwgKGJ5dGUpIDB4ZDAsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMSwgKGJ5dGUpIDB4ZDIsIChieXRlKSAweGQzLCAoYnl0ZSkgMHhkNCwgKGJ5dGUpIDB4ZDUsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNiwgKGJ5dGUpIDB4ZDcsIChieXRlKSAweGQ4LCAoYnl0ZSkgMHhkOSwgKGJ5dGUpIDB4ZGEsCisgICAgICAgICAgICAoYnl0ZSkgMHhkYiwgKGJ5dGUpIDB4ZGMsIChieXRlKSAweGRkLCAoYnl0ZSkgMHhkZSwgKGJ5dGUpIDB4ZGYsCisgICAgICAgICAgICAoYnl0ZSkgMHhlMCwgKGJ5dGUpIDB4ZTEsIChieXRlKSAweGUyLCAoYnl0ZSkgMHhlMywgKGJ5dGUpIDB4ZTQsCisgICAgICAgICAgICAoYnl0ZSkgMHhlNSwgKGJ5dGUpIDB4ZTYsIChieXRlKSAweGU3LCAoYnl0ZSkgMHhlOCwgKGJ5dGUpIDB4ZTksCisgICAgICAgICAgICAoYnl0ZSkgMHhlYSwgKGJ5dGUpIDB4ZWIsIChieXRlKSAweGVjLCAoYnl0ZSkgMHhlZCwgKGJ5dGUpIDB4ZWUsCisgICAgICAgICAgICAoYnl0ZSkgMHhlZiwgKGJ5dGUpIDB4ZjAsIChieXRlKSAweGYxLCAoYnl0ZSkgMHhmMiwgKGJ5dGUpIDB4ZjMsCisgICAgICAgICAgICAoYnl0ZSkgMHhmNCwgKGJ5dGUpIDB4ZjUsIChieXRlKSAweGY2LCAoYnl0ZSkgMHhmNywgKGJ5dGUpIDB4ZjgsCisgICAgICAgICAgICAoYnl0ZSkgMHhmOSwgKGJ5dGUpIDB4ZmEsIChieXRlKSAweGZiLCAoYnl0ZSkgMHhmYywgKGJ5dGUpIDB4ZmQsCisgICAgICAgICAgICAoYnl0ZSkgMHhmZSwgKGJ5dGUpIDB4ZmYsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDIsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MDQsIChieXRlKSAweDA1LCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MDcsCisgICAgICAgICAgICAoYnl0ZSkgMHgwOCwgKGJ5dGUpIDB4MDksIChieXRlKSAweDBhLCAoYnl0ZSkgMHgwYiwgKGJ5dGUpIDB4MGMsCisgICAgICAgICAgICAoYnl0ZSkgMHgwZCwgKGJ5dGUpIDB4MGUsIChieXRlKSAweDBmLCAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4MTEsCisgICAgICAgICAgICAoYnl0ZSkgMHgxMiwgKGJ5dGUpIDB4MTMsIChieXRlKSAweDE0LCAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4MTYsCisgICAgICAgICAgICAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4MTgsIChieXRlKSAweDE5LCAoYnl0ZSkgMHgxYSwgKGJ5dGUpIDB4MWIsCisgICAgICAgICAgICAoYnl0ZSkgMHgxYywgKGJ5dGUpIDB4MWQsIChieXRlKSAweDFlLCAoYnl0ZSkgMHgxZiwgKGJ5dGUpIDB4MjAsCisgICAgICAgICAgICAoYnl0ZSkgMHgyMSwgKGJ5dGUpIDB4MjIsIChieXRlKSAweDIzLCAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4MjUsCisgICAgICAgICAgICAoYnl0ZSkgMHgyNiwgKGJ5dGUpIDB4MjcsIChieXRlKSAweDI4LCAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4MmEsCisgICAgICAgICAgICAoYnl0ZSkgMHgyYiwgKGJ5dGUpIDB4MmMsIChieXRlKSAweDJkLCAoYnl0ZSkgMHgyZSwgKGJ5dGUpIDB4MmYsCisgICAgICAgICAgICAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4MzEsIChieXRlKSAweDMyLCAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4MzQsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4MzYsIChieXRlKSAweDM3LCAoYnl0ZSkgMHgzOCwgKGJ5dGUpIDB4MzksCisgICAgICAgICAgICAoYnl0ZSkgMHgzYSwgKGJ5dGUpIDB4M2IsIChieXRlKSAweDNjLCAoYnl0ZSkgMHgzZCwgKGJ5dGUpIDB4M2UsCisgICAgICAgICAgICAoYnl0ZSkgMHgzZiwgKGJ5dGUpIDB4NDAsIChieXRlKSAweDQxLCAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4NDMsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4NDUsIChieXRlKSAweDQ2LCAoYnl0ZSkgMHg0NywgKGJ5dGUpIDB4NDgsCisgICAgICAgICAgICAoYnl0ZSkgMHg0OSwgKGJ5dGUpIDB4NGEsIChieXRlKSAweDRiLCAoYnl0ZSkgMHg0YywgKGJ5dGUpIDB4NGQsCisgICAgICAgICAgICAoYnl0ZSkgMHg0ZSwgKGJ5dGUpIDB4NGYsIChieXRlKSAweDUwLCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4NTIsCisgICAgICAgICAgICAoYnl0ZSkgMHg1MywgKGJ5dGUpIDB4NTQsIChieXRlKSAweDU1LCAoYnl0ZSkgMHg1NiwgKGJ5dGUpIDB4NTcsCisgICAgICAgICAgICAoYnl0ZSkgMHg1OCwgKGJ5dGUpIDB4NTksIChieXRlKSAweDVhLCAoYnl0ZSkgMHg1YiwgKGJ5dGUpIDB4NWMsCisgICAgICAgICAgICAoYnl0ZSkgMHg1ZCwgKGJ5dGUpIDB4NWUsIChieXRlKSAweDVmLCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4NjEsCisgICAgICAgICAgICAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4NjMsIChieXRlKSAweDY0LCAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4NjYsCisgICAgICAgICAgICAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4NjgsIChieXRlKSAweDY5LCAoYnl0ZSkgMHg2YSwgKGJ5dGUpIDB4NmIsCisgICAgICAgICAgICAoYnl0ZSkgMHg2YywgKGJ5dGUpIDB4NmQsIChieXRlKSAweDZlLCAoYnl0ZSkgMHg2ZiwgKGJ5dGUpIDB4NzAsCisgICAgICAgICAgICAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4NzIsIChieXRlKSAweDczLCAoYnl0ZSkgMHg3NCwgKGJ5dGUpIDB4NzUsCisgICAgICAgICAgICAoYnl0ZSkgMHg3NiwgKGJ5dGUpIDB4NzcsIChieXRlKSAweDc4LCAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4N2EsCisgICAgICAgICAgICAoYnl0ZSkgMHg3YiwgKGJ5dGUpIDB4N2MsIChieXRlKSAweDdkLCAoYnl0ZSkgMHg3ZSwgKGJ5dGUpIDB4N2YsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDgyLCAoYnl0ZSkgMHg4MywgKGJ5dGUpIDB4ODQsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4ODYsIChieXRlKSAweDg3LCAoYnl0ZSkgMHg4OCwgKGJ5dGUpIDB4ODksCisgICAgICAgICAgICAoYnl0ZSkgMHg4YSwgKGJ5dGUpIDB4OGIsIChieXRlKSAweDhjLCAoYnl0ZSkgMHg4ZCwgKGJ5dGUpIDB4OGUsCisgICAgICAgICAgICAoYnl0ZSkgMHg4ZiwgKGJ5dGUpIDB4OTAsIChieXRlKSAweDkxLCAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4OTMsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NCwgKGJ5dGUpIDB4OTUsIChieXRlKSAweDk2LCAoYnl0ZSkgMHg5NywgKGJ5dGUpIDB4OTgsCisgICAgICAgICAgICAoYnl0ZSkgMHg5OSwgKGJ5dGUpIDB4OWEsIChieXRlKSAweDliLCAoYnl0ZSkgMHg5YywgKGJ5dGUpIDB4OWQsCisgICAgICAgICAgICAoYnl0ZSkgMHg5ZSwgKGJ5dGUpIDB4OWYsIChieXRlKSAweGEwLCAoYnl0ZSkgMHhhMSwgKGJ5dGUpIDB4YTIsCisgICAgICAgICAgICAoYnl0ZSkgMHhhMywgKGJ5dGUpIDB4YTQsIChieXRlKSAweGE1LCAoYnl0ZSkgMHhhNiwgKGJ5dGUpIDB4YTcsCisgICAgICAgICAgICAoYnl0ZSkgMHhhOCwgKGJ5dGUpIDB4YTksIChieXRlKSAweGFhLCAoYnl0ZSkgMHhhYiwgKGJ5dGUpIDB4YWMsCisgICAgICAgICAgICAoYnl0ZSkgMHhhZCwgKGJ5dGUpIDB4YWUsIChieXRlKSAweGFmLCAoYnl0ZSkgMHhiMCwgKGJ5dGUpIDB4YjEsCisgICAgICAgICAgICAoYnl0ZSkgMHhiMiwgKGJ5dGUpIDB4YjMsIChieXRlKSAweGI0LCAoYnl0ZSkgMHhiNSwgKGJ5dGUpIDB4YjYsCisgICAgICAgICAgICAoYnl0ZSkgMHhiNywgKGJ5dGUpIDB4YjgsIChieXRlKSAweGI5LCAoYnl0ZSkgMHhiYSwgKGJ5dGUpIDB4YmIsCisgICAgICAgICAgICAoYnl0ZSkgMHhiYywgKGJ5dGUpIDB4YmQsIChieXRlKSAweGJlLCAoYnl0ZSkgMHhiZiwgKGJ5dGUpIDB4YzAsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMSwgKGJ5dGUpIDB4YzIsIChieXRlKSAweGMzLCAoYnl0ZSkgMHhjNCwgKGJ5dGUpIDB4YzUsCisgICAgICAgICAgICAoYnl0ZSkgMHhjNiwgKGJ5dGUpIDB4YzcsIChieXRlKSAweGM4LCAoYnl0ZSkgMHhjOSwgKGJ5dGUpIDB4Y2EsCisgICAgICAgICAgICAoYnl0ZSkgMHhjYiwgKGJ5dGUpIDB4Y2MsIChieXRlKSAweGNkLCAoYnl0ZSkgMHhjZSwgKGJ5dGUpIDB4Y2YsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMCwgKGJ5dGUpIDB4ZDEsIChieXRlKSAweGQyLCAoYnl0ZSkgMHhkMywgKGJ5dGUpIDB4ZDQsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNSwgKGJ5dGUpIDB4ZDYsIChieXRlKSAweGQ3LCAoYnl0ZSkgMHhkOCwgKGJ5dGUpIDB4ZDksCisgICAgICAgICAgICAoYnl0ZSkgMHhkYSwgKGJ5dGUpIDB4ZGIsIChieXRlKSAweGRjLCAoYnl0ZSkgMHhkZCwgKGJ5dGUpIDB4ZGUsCisgICAgICAgICAgICAoYnl0ZSkgMHhkZiwgKGJ5dGUpIDB4ZTAsIChieXRlKSAweGUxLCAoYnl0ZSkgMHhlMiwgKGJ5dGUpIDB4ZTMsCisgICAgICAgICAgICAoYnl0ZSkgMHhlNCwgKGJ5dGUpIDB4ZTUsIChieXRlKSAweGU2LCAoYnl0ZSkgMHhlNywgKGJ5dGUpIDB4ZTgsCisgICAgICAgICAgICAoYnl0ZSkgMHhlOSwgKGJ5dGUpIDB4ZWEsIChieXRlKSAweGViLCAoYnl0ZSkgMHhlYywgKGJ5dGUpIDB4ZWQsCisgICAgICAgICAgICAoYnl0ZSkgMHhlZSwgKGJ5dGUpIDB4ZWYsIChieXRlKSAweGYwLCAoYnl0ZSkgMHhmMSwgKGJ5dGUpIDB4ZjIsCisgICAgICAgICAgICAoYnl0ZSkgMHhmMywgKGJ5dGUpIDB4ZjQsIChieXRlKSAweGY1LCAoYnl0ZSkgMHhmNiwgKGJ5dGUpIDB4ZjcsCisgICAgICAgICAgICAoYnl0ZSkgMHhmOCwgKGJ5dGUpIDB4ZjksIChieXRlKSAweGZhLCAoYnl0ZSkgMHhmYiwgKGJ5dGUpIDB4ZmMsCisgICAgICAgICAgICAoYnl0ZSkgMHhmZCwgKGJ5dGUpIDB4ZmUsIChieXRlKSAweGZmIH07CisKKyAgICAvKioKKyAgICAgKiAidmFsaWQiIGVuY29kaW5nIGZvciBEU0EgLSBubyBhbGcgcGFyYW1zCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIGRzYUVuY3J5cHRlZFByaXZhdGVLZXlJbmZvTlAgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgIChieXRlKSAweDMwLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDQsIChieXRlKSAweDExLCAoYnl0ZSkgMHgzMCwKKyAgICAgICAgICAgIChieXRlKSAweDBiLCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MDcsIChieXRlKSAweDJhLCAoYnl0ZSkgMHg4NiwKKyAgICAgICAgICAgIChieXRlKSAweDQ4LCAoYnl0ZSkgMHhjZSwgKGJ5dGUpIDB4MzgsIChieXRlKSAweDA0LCAoYnl0ZSkgMHgwMSwKKyAgICAgICAgICAgIChieXRlKSAweDA1LCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDQsIChieXRlKSAweDgyLCAoYnl0ZSkgMHgwNCwKKyAgICAgICAgICAgIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwMywKKyAgICAgICAgICAgIChieXRlKSAweDA0LCAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4MDYsIChieXRlKSAweDA3LCAoYnl0ZSkgMHgwOCwKKyAgICAgICAgICAgIChieXRlKSAweDA5LCAoYnl0ZSkgMHgwYSwgKGJ5dGUpIDB4MGIsIChieXRlKSAweDBjLCAoYnl0ZSkgMHgwZCwKKyAgICAgICAgICAgIChieXRlKSAweDBlLCAoYnl0ZSkgMHgwZiwgKGJ5dGUpIDB4MTAsIChieXRlKSAweDExLCAoYnl0ZSkgMHgxMiwKKyAgICAgICAgICAgIChieXRlKSAweDEzLCAoYnl0ZSkgMHgxNCwgKGJ5dGUpIDB4MTUsIChieXRlKSAweDE2LCAoYnl0ZSkgMHgxNywKKyAgICAgICAgICAgIChieXRlKSAweDE4LCAoYnl0ZSkgMHgxOSwgKGJ5dGUpIDB4MWEsIChieXRlKSAweDFiLCAoYnl0ZSkgMHgxYywKKyAgICAgICAgICAgIChieXRlKSAweDFkLCAoYnl0ZSkgMHgxZSwgKGJ5dGUpIDB4MWYsIChieXRlKSAweDIwLCAoYnl0ZSkgMHgyMSwKKyAgICAgICAgICAgIChieXRlKSAweDIyLCAoYnl0ZSkgMHgyMywgKGJ5dGUpIDB4MjQsIChieXRlKSAweDI1LCAoYnl0ZSkgMHgyNiwKKyAgICAgICAgICAgIChieXRlKSAweDI3LCAoYnl0ZSkgMHgyOCwgKGJ5dGUpIDB4MjksIChieXRlKSAweDJhLCAoYnl0ZSkgMHgyYiwKKyAgICAgICAgICAgIChieXRlKSAweDJjLCAoYnl0ZSkgMHgyZCwgKGJ5dGUpIDB4MmUsIChieXRlKSAweDJmLCAoYnl0ZSkgMHgzMCwKKyAgICAgICAgICAgIChieXRlKSAweDMxLCAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4MzMsIChieXRlKSAweDM0LCAoYnl0ZSkgMHgzNSwKKyAgICAgICAgICAgIChieXRlKSAweDM2LCAoYnl0ZSkgMHgzNywgKGJ5dGUpIDB4MzgsIChieXRlKSAweDM5LCAoYnl0ZSkgMHgzYSwKKyAgICAgICAgICAgIChieXRlKSAweDNiLCAoYnl0ZSkgMHgzYywgKGJ5dGUpIDB4M2QsIChieXRlKSAweDNlLCAoYnl0ZSkgMHgzZiwKKyAgICAgICAgICAgIChieXRlKSAweDQwLCAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4NDIsIChieXRlKSAweDQzLCAoYnl0ZSkgMHg0NCwKKyAgICAgICAgICAgIChieXRlKSAweDQ1LCAoYnl0ZSkgMHg0NiwgKGJ5dGUpIDB4NDcsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg0OSwKKyAgICAgICAgICAgIChieXRlKSAweDRhLCAoYnl0ZSkgMHg0YiwgKGJ5dGUpIDB4NGMsIChieXRlKSAweDRkLCAoYnl0ZSkgMHg0ZSwKKyAgICAgICAgICAgIChieXRlKSAweDRmLCAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NTEsIChieXRlKSAweDUyLCAoYnl0ZSkgMHg1MywKKyAgICAgICAgICAgIChieXRlKSAweDU0LCAoYnl0ZSkgMHg1NSwgKGJ5dGUpIDB4NTYsIChieXRlKSAweDU3LCAoYnl0ZSkgMHg1OCwKKyAgICAgICAgICAgIChieXRlKSAweDU5LCAoYnl0ZSkgMHg1YSwgKGJ5dGUpIDB4NWIsIChieXRlKSAweDVjLCAoYnl0ZSkgMHg1ZCwKKyAgICAgICAgICAgIChieXRlKSAweDVlLCAoYnl0ZSkgMHg1ZiwgKGJ5dGUpIDB4NjAsIChieXRlKSAweDYxLCAoYnl0ZSkgMHg2MiwKKyAgICAgICAgICAgIChieXRlKSAweDYzLCAoYnl0ZSkgMHg2NCwgKGJ5dGUpIDB4NjUsIChieXRlKSAweDY2LCAoYnl0ZSkgMHg2NywKKyAgICAgICAgICAgIChieXRlKSAweDY4LCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4NmEsIChieXRlKSAweDZiLCAoYnl0ZSkgMHg2YywKKyAgICAgICAgICAgIChieXRlKSAweDZkLCAoYnl0ZSkgMHg2ZSwgKGJ5dGUpIDB4NmYsIChieXRlKSAweDcwLCAoYnl0ZSkgMHg3MSwKKyAgICAgICAgICAgIChieXRlKSAweDcyLCAoYnl0ZSkgMHg3MywgKGJ5dGUpIDB4NzQsIChieXRlKSAweDc1LCAoYnl0ZSkgMHg3NiwKKyAgICAgICAgICAgIChieXRlKSAweDc3LCAoYnl0ZSkgMHg3OCwgKGJ5dGUpIDB4NzksIChieXRlKSAweDdhLCAoYnl0ZSkgMHg3YiwKKyAgICAgICAgICAgIChieXRlKSAweDdjLCAoYnl0ZSkgMHg3ZCwgKGJ5dGUpIDB4N2UsIChieXRlKSAweDdmLCAoYnl0ZSkgMHg4MCwKKyAgICAgICAgICAgIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4ODMsIChieXRlKSAweDg0LCAoYnl0ZSkgMHg4NSwKKyAgICAgICAgICAgIChieXRlKSAweDg2LCAoYnl0ZSkgMHg4NywgKGJ5dGUpIDB4ODgsIChieXRlKSAweDg5LCAoYnl0ZSkgMHg4YSwKKyAgICAgICAgICAgIChieXRlKSAweDhiLCAoYnl0ZSkgMHg4YywgKGJ5dGUpIDB4OGQsIChieXRlKSAweDhlLCAoYnl0ZSkgMHg4ZiwKKyAgICAgICAgICAgIChieXRlKSAweDkwLCAoYnl0ZSkgMHg5MSwgKGJ5dGUpIDB4OTIsIChieXRlKSAweDkzLCAoYnl0ZSkgMHg5NCwKKyAgICAgICAgICAgIChieXRlKSAweDk1LCAoYnl0ZSkgMHg5NiwgKGJ5dGUpIDB4OTcsIChieXRlKSAweDk4LCAoYnl0ZSkgMHg5OSwKKyAgICAgICAgICAgIChieXRlKSAweDlhLCAoYnl0ZSkgMHg5YiwgKGJ5dGUpIDB4OWMsIChieXRlKSAweDlkLCAoYnl0ZSkgMHg5ZSwKKyAgICAgICAgICAgIChieXRlKSAweDlmLCAoYnl0ZSkgMHhhMCwgKGJ5dGUpIDB4YTEsIChieXRlKSAweGEyLCAoYnl0ZSkgMHhhMywKKyAgICAgICAgICAgIChieXRlKSAweGE0LCAoYnl0ZSkgMHhhNSwgKGJ5dGUpIDB4YTYsIChieXRlKSAweGE3LCAoYnl0ZSkgMHhhOCwKKyAgICAgICAgICAgIChieXRlKSAweGE5LCAoYnl0ZSkgMHhhYSwgKGJ5dGUpIDB4YWIsIChieXRlKSAweGFjLCAoYnl0ZSkgMHhhZCwKKyAgICAgICAgICAgIChieXRlKSAweGFlLCAoYnl0ZSkgMHhhZiwgKGJ5dGUpIDB4YjAsIChieXRlKSAweGIxLCAoYnl0ZSkgMHhiMiwKKyAgICAgICAgICAgIChieXRlKSAweGIzLCAoYnl0ZSkgMHhiNCwgKGJ5dGUpIDB4YjUsIChieXRlKSAweGI2LCAoYnl0ZSkgMHhiNywKKyAgICAgICAgICAgIChieXRlKSAweGI4LCAoYnl0ZSkgMHhiOSwgKGJ5dGUpIDB4YmEsIChieXRlKSAweGJiLCAoYnl0ZSkgMHhiYywKKyAgICAgICAgICAgIChieXRlKSAweGJkLCAoYnl0ZSkgMHhiZSwgKGJ5dGUpIDB4YmYsIChieXRlKSAweGMwLCAoYnl0ZSkgMHhjMSwKKyAgICAgICAgICAgIChieXRlKSAweGMyLCAoYnl0ZSkgMHhjMywgKGJ5dGUpIDB4YzQsIChieXRlKSAweGM1LCAoYnl0ZSkgMHhjNiwKKyAgICAgICAgICAgIChieXRlKSAweGM3LCAoYnl0ZSkgMHhjOCwgKGJ5dGUpIDB4YzksIChieXRlKSAweGNhLCAoYnl0ZSkgMHhjYiwKKyAgICAgICAgICAgIChieXRlKSAweGNjLCAoYnl0ZSkgMHhjZCwgKGJ5dGUpIDB4Y2UsIChieXRlKSAweGNmLCAoYnl0ZSkgMHhkMCwKKyAgICAgICAgICAgIChieXRlKSAweGQxLCAoYnl0ZSkgMHhkMiwgKGJ5dGUpIDB4ZDMsIChieXRlKSAweGQ0LCAoYnl0ZSkgMHhkNSwKKyAgICAgICAgICAgIChieXRlKSAweGQ2LCAoYnl0ZSkgMHhkNywgKGJ5dGUpIDB4ZDgsIChieXRlKSAweGQ5LCAoYnl0ZSkgMHhkYSwKKyAgICAgICAgICAgIChieXRlKSAweGRiLCAoYnl0ZSkgMHhkYywgKGJ5dGUpIDB4ZGQsIChieXRlKSAweGRlLCAoYnl0ZSkgMHhkZiwKKyAgICAgICAgICAgIChieXRlKSAweGUwLCAoYnl0ZSkgMHhlMSwgKGJ5dGUpIDB4ZTIsIChieXRlKSAweGUzLCAoYnl0ZSkgMHhlNCwKKyAgICAgICAgICAgIChieXRlKSAweGU1LCAoYnl0ZSkgMHhlNiwgKGJ5dGUpIDB4ZTcsIChieXRlKSAweGU4LCAoYnl0ZSkgMHhlOSwKKyAgICAgICAgICAgIChieXRlKSAweGVhLCAoYnl0ZSkgMHhlYiwgKGJ5dGUpIDB4ZWMsIChieXRlKSAweGVkLCAoYnl0ZSkgMHhlZSwKKyAgICAgICAgICAgIChieXRlKSAweGVmLCAoYnl0ZSkgMHhmMCwgKGJ5dGUpIDB4ZjEsIChieXRlKSAweGYyLCAoYnl0ZSkgMHhmMywKKyAgICAgICAgICAgIChieXRlKSAweGY0LCAoYnl0ZSkgMHhmNSwgKGJ5dGUpIDB4ZjYsIChieXRlKSAweGY3LCAoYnl0ZSkgMHhmOCwKKyAgICAgICAgICAgIChieXRlKSAweGY5LCAoYnl0ZSkgMHhmYSwgKGJ5dGUpIDB4ZmIsIChieXRlKSAweGZjLCAoYnl0ZSkgMHhmZCwKKyAgICAgICAgICAgIChieXRlKSAweGZlLCAoYnl0ZSkgMHhmZiwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMiwKKyAgICAgICAgICAgIChieXRlKSAweDAzLCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MDUsIChieXRlKSAweDA2LCAoYnl0ZSkgMHgwNywKKyAgICAgICAgICAgIChieXRlKSAweDA4LCAoYnl0ZSkgMHgwOSwgKGJ5dGUpIDB4MGEsIChieXRlKSAweDBiLCAoYnl0ZSkgMHgwYywKKyAgICAgICAgICAgIChieXRlKSAweDBkLCAoYnl0ZSkgMHgwZSwgKGJ5dGUpIDB4MGYsIChieXRlKSAweDEwLCAoYnl0ZSkgMHgxMSwKKyAgICAgICAgICAgIChieXRlKSAweDEyLCAoYnl0ZSkgMHgxMywgKGJ5dGUpIDB4MTQsIChieXRlKSAweDE1LCAoYnl0ZSkgMHgxNiwKKyAgICAgICAgICAgIChieXRlKSAweDE3LCAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4MTksIChieXRlKSAweDFhLCAoYnl0ZSkgMHgxYiwKKyAgICAgICAgICAgIChieXRlKSAweDFjLCAoYnl0ZSkgMHgxZCwgKGJ5dGUpIDB4MWUsIChieXRlKSAweDFmLCAoYnl0ZSkgMHgyMCwKKyAgICAgICAgICAgIChieXRlKSAweDIxLCAoYnl0ZSkgMHgyMiwgKGJ5dGUpIDB4MjMsIChieXRlKSAweDI0LCAoYnl0ZSkgMHgyNSwKKyAgICAgICAgICAgIChieXRlKSAweDI2LCAoYnl0ZSkgMHgyNywgKGJ5dGUpIDB4MjgsIChieXRlKSAweDI5LCAoYnl0ZSkgMHgyYSwKKyAgICAgICAgICAgIChieXRlKSAweDJiLCAoYnl0ZSkgMHgyYywgKGJ5dGUpIDB4MmQsIChieXRlKSAweDJlLCAoYnl0ZSkgMHgyZiwKKyAgICAgICAgICAgIChieXRlKSAweDMwLCAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4MzIsIChieXRlKSAweDMzLCAoYnl0ZSkgMHgzNCwKKyAgICAgICAgICAgIChieXRlKSAweDM1LCAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4MzcsIChieXRlKSAweDM4LCAoYnl0ZSkgMHgzOSwKKyAgICAgICAgICAgIChieXRlKSAweDNhLCAoYnl0ZSkgMHgzYiwgKGJ5dGUpIDB4M2MsIChieXRlKSAweDNkLCAoYnl0ZSkgMHgzZSwKKyAgICAgICAgICAgIChieXRlKSAweDNmLCAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NDEsIChieXRlKSAweDQyLCAoYnl0ZSkgMHg0MywKKyAgICAgICAgICAgIChieXRlKSAweDQ0LCAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4NDYsIChieXRlKSAweDQ3LCAoYnl0ZSkgMHg0OCwKKyAgICAgICAgICAgIChieXRlKSAweDQ5LCAoYnl0ZSkgMHg0YSwgKGJ5dGUpIDB4NGIsIChieXRlKSAweDRjLCAoYnl0ZSkgMHg0ZCwKKyAgICAgICAgICAgIChieXRlKSAweDRlLCAoYnl0ZSkgMHg0ZiwgKGJ5dGUpIDB4NTAsIChieXRlKSAweDUxLCAoYnl0ZSkgMHg1MiwKKyAgICAgICAgICAgIChieXRlKSAweDUzLCAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDU2LCAoYnl0ZSkgMHg1NywKKyAgICAgICAgICAgIChieXRlKSAweDU4LCAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4NWEsIChieXRlKSAweDViLCAoYnl0ZSkgMHg1YywKKyAgICAgICAgICAgIChieXRlKSAweDVkLCAoYnl0ZSkgMHg1ZSwgKGJ5dGUpIDB4NWYsIChieXRlKSAweDYwLCAoYnl0ZSkgMHg2MSwKKyAgICAgICAgICAgIChieXRlKSAweDYyLCAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4NjQsIChieXRlKSAweDY1LCAoYnl0ZSkgMHg2NiwKKyAgICAgICAgICAgIChieXRlKSAweDY3LCAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4NjksIChieXRlKSAweDZhLCAoYnl0ZSkgMHg2YiwKKyAgICAgICAgICAgIChieXRlKSAweDZjLCAoYnl0ZSkgMHg2ZCwgKGJ5dGUpIDB4NmUsIChieXRlKSAweDZmLCAoYnl0ZSkgMHg3MCwKKyAgICAgICAgICAgIChieXRlKSAweDcxLCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4NzMsIChieXRlKSAweDc0LCAoYnl0ZSkgMHg3NSwKKyAgICAgICAgICAgIChieXRlKSAweDc2LCAoYnl0ZSkgMHg3NywgKGJ5dGUpIDB4NzgsIChieXRlKSAweDc5LCAoYnl0ZSkgMHg3YSwKKyAgICAgICAgICAgIChieXRlKSAweDdiLCAoYnl0ZSkgMHg3YywgKGJ5dGUpIDB4N2QsIChieXRlKSAweDdlLCAoYnl0ZSkgMHg3ZiwKKyAgICAgICAgICAgIChieXRlKSAweDgwLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDgzLCAoYnl0ZSkgMHg4NCwKKyAgICAgICAgICAgIChieXRlKSAweDg1LCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4ODcsIChieXRlKSAweDg4LCAoYnl0ZSkgMHg4OSwKKyAgICAgICAgICAgIChieXRlKSAweDhhLCAoYnl0ZSkgMHg4YiwgKGJ5dGUpIDB4OGMsIChieXRlKSAweDhkLCAoYnl0ZSkgMHg4ZSwKKyAgICAgICAgICAgIChieXRlKSAweDhmLCAoYnl0ZSkgMHg5MCwgKGJ5dGUpIDB4OTEsIChieXRlKSAweDkyLCAoYnl0ZSkgMHg5MywKKyAgICAgICAgICAgIChieXRlKSAweDk0LCAoYnl0ZSkgMHg5NSwgKGJ5dGUpIDB4OTYsIChieXRlKSAweDk3LCAoYnl0ZSkgMHg5OCwKKyAgICAgICAgICAgIChieXRlKSAweDk5LCAoYnl0ZSkgMHg5YSwgKGJ5dGUpIDB4OWIsIChieXRlKSAweDljLCAoYnl0ZSkgMHg5ZCwKKyAgICAgICAgICAgIChieXRlKSAweDllLCAoYnl0ZSkgMHg5ZiwgKGJ5dGUpIDB4YTAsIChieXRlKSAweGExLCAoYnl0ZSkgMHhhMiwKKyAgICAgICAgICAgIChieXRlKSAweGEzLCAoYnl0ZSkgMHhhNCwgKGJ5dGUpIDB4YTUsIChieXRlKSAweGE2LCAoYnl0ZSkgMHhhNywKKyAgICAgICAgICAgIChieXRlKSAweGE4LCAoYnl0ZSkgMHhhOSwgKGJ5dGUpIDB4YWEsIChieXRlKSAweGFiLCAoYnl0ZSkgMHhhYywKKyAgICAgICAgICAgIChieXRlKSAweGFkLCAoYnl0ZSkgMHhhZSwgKGJ5dGUpIDB4YWYsIChieXRlKSAweGIwLCAoYnl0ZSkgMHhiMSwKKyAgICAgICAgICAgIChieXRlKSAweGIyLCAoYnl0ZSkgMHhiMywgKGJ5dGUpIDB4YjQsIChieXRlKSAweGI1LCAoYnl0ZSkgMHhiNiwKKyAgICAgICAgICAgIChieXRlKSAweGI3LCAoYnl0ZSkgMHhiOCwgKGJ5dGUpIDB4YjksIChieXRlKSAweGJhLCAoYnl0ZSkgMHhiYiwKKyAgICAgICAgICAgIChieXRlKSAweGJjLCAoYnl0ZSkgMHhiZCwgKGJ5dGUpIDB4YmUsIChieXRlKSAweGJmLCAoYnl0ZSkgMHhjMCwKKyAgICAgICAgICAgIChieXRlKSAweGMxLCAoYnl0ZSkgMHhjMiwgKGJ5dGUpIDB4YzMsIChieXRlKSAweGM0LCAoYnl0ZSkgMHhjNSwKKyAgICAgICAgICAgIChieXRlKSAweGM2LCAoYnl0ZSkgMHhjNywgKGJ5dGUpIDB4YzgsIChieXRlKSAweGM5LCAoYnl0ZSkgMHhjYSwKKyAgICAgICAgICAgIChieXRlKSAweGNiLCAoYnl0ZSkgMHhjYywgKGJ5dGUpIDB4Y2QsIChieXRlKSAweGNlLCAoYnl0ZSkgMHhjZiwKKyAgICAgICAgICAgIChieXRlKSAweGQwLCAoYnl0ZSkgMHhkMSwgKGJ5dGUpIDB4ZDIsIChieXRlKSAweGQzLCAoYnl0ZSkgMHhkNCwKKyAgICAgICAgICAgIChieXRlKSAweGQ1LCAoYnl0ZSkgMHhkNiwgKGJ5dGUpIDB4ZDcsIChieXRlKSAweGQ4LCAoYnl0ZSkgMHhkOSwKKyAgICAgICAgICAgIChieXRlKSAweGRhLCAoYnl0ZSkgMHhkYiwgKGJ5dGUpIDB4ZGMsIChieXRlKSAweGRkLCAoYnl0ZSkgMHhkZSwKKyAgICAgICAgICAgIChieXRlKSAweGRmLCAoYnl0ZSkgMHhlMCwgKGJ5dGUpIDB4ZTEsIChieXRlKSAweGUyLCAoYnl0ZSkgMHhlMywKKyAgICAgICAgICAgIChieXRlKSAweGU0LCAoYnl0ZSkgMHhlNSwgKGJ5dGUpIDB4ZTYsIChieXRlKSAweGU3LCAoYnl0ZSkgMHhlOCwKKyAgICAgICAgICAgIChieXRlKSAweGU5LCAoYnl0ZSkgMHhlYSwgKGJ5dGUpIDB4ZWIsIChieXRlKSAweGVjLCAoYnl0ZSkgMHhlZCwKKyAgICAgICAgICAgIChieXRlKSAweGVlLCAoYnl0ZSkgMHhlZiwgKGJ5dGUpIDB4ZjAsIChieXRlKSAweGYxLCAoYnl0ZSkgMHhmMiwKKyAgICAgICAgICAgIChieXRlKSAweGYzLCAoYnl0ZSkgMHhmNCwgKGJ5dGUpIDB4ZjUsIChieXRlKSAweGY2LCAoYnl0ZSkgMHhmNywKKyAgICAgICAgICAgIChieXRlKSAweGY4LCAoYnl0ZSkgMHhmOSwgKGJ5dGUpIDB4ZmEsIChieXRlKSAweGZiLCAoYnl0ZSkgMHhmYywKKyAgICAgICAgICAgIChieXRlKSAweGZkLCAoYnl0ZSkgMHhmZSwgKGJ5dGUpIDB4ZmYsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMSwKKyAgICAgICAgICAgIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MDQsIChieXRlKSAweDA1LCAoYnl0ZSkgMHgwNiwKKyAgICAgICAgICAgIChieXRlKSAweDA3LCAoYnl0ZSkgMHgwOCwgKGJ5dGUpIDB4MDksIChieXRlKSAweDBhLCAoYnl0ZSkgMHgwYiwKKyAgICAgICAgICAgIChieXRlKSAweDBjLCAoYnl0ZSkgMHgwZCwgKGJ5dGUpIDB4MGUsIChieXRlKSAweDBmLCAoYnl0ZSkgMHgxMCwKKyAgICAgICAgICAgIChieXRlKSAweDExLCAoYnl0ZSkgMHgxMiwgKGJ5dGUpIDB4MTMsIChieXRlKSAweDE0LCAoYnl0ZSkgMHgxNSwKKyAgICAgICAgICAgIChieXRlKSAweDE2LCAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4MTgsIChieXRlKSAweDE5LCAoYnl0ZSkgMHgxYSwKKyAgICAgICAgICAgIChieXRlKSAweDFiLCAoYnl0ZSkgMHgxYywgKGJ5dGUpIDB4MWQsIChieXRlKSAweDFlLCAoYnl0ZSkgMHgxZiwKKyAgICAgICAgICAgIChieXRlKSAweDIwLCAoYnl0ZSkgMHgyMSwgKGJ5dGUpIDB4MjIsIChieXRlKSAweDIzLCAoYnl0ZSkgMHgyNCwKKyAgICAgICAgICAgIChieXRlKSAweDI1LCAoYnl0ZSkgMHgyNiwgKGJ5dGUpIDB4MjcsIChieXRlKSAweDI4LCAoYnl0ZSkgMHgyOSwKKyAgICAgICAgICAgIChieXRlKSAweDJhLCAoYnl0ZSkgMHgyYiwgKGJ5dGUpIDB4MmMsIChieXRlKSAweDJkLCAoYnl0ZSkgMHgyZSwKKyAgICAgICAgICAgIChieXRlKSAweDJmLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4MzEsIChieXRlKSAweDMyLCAoYnl0ZSkgMHgzMywKKyAgICAgICAgICAgIChieXRlKSAweDM0LCAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4MzYsIChieXRlKSAweDM3LCAoYnl0ZSkgMHgzOCwKKyAgICAgICAgICAgIChieXRlKSAweDM5LCAoYnl0ZSkgMHgzYSwgKGJ5dGUpIDB4M2IsIChieXRlKSAweDNjLCAoYnl0ZSkgMHgzZCwKKyAgICAgICAgICAgIChieXRlKSAweDNlLCAoYnl0ZSkgMHgzZiwgKGJ5dGUpIDB4NDAsIChieXRlKSAweDQxLCAoYnl0ZSkgMHg0MiwKKyAgICAgICAgICAgIChieXRlKSAweDQzLCAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4NDUsIChieXRlKSAweDQ2LCAoYnl0ZSkgMHg0NywKKyAgICAgICAgICAgIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg0OSwgKGJ5dGUpIDB4NGEsIChieXRlKSAweDRiLCAoYnl0ZSkgMHg0YywKKyAgICAgICAgICAgIChieXRlKSAweDRkLCAoYnl0ZSkgMHg0ZSwgKGJ5dGUpIDB4NGYsIChieXRlKSAweDUwLCAoYnl0ZSkgMHg1MSwKKyAgICAgICAgICAgIChieXRlKSAweDUyLCAoYnl0ZSkgMHg1MywgKGJ5dGUpIDB4NTQsIChieXRlKSAweDU1LCAoYnl0ZSkgMHg1NiwKKyAgICAgICAgICAgIChieXRlKSAweDU3LCAoYnl0ZSkgMHg1OCwgKGJ5dGUpIDB4NTksIChieXRlKSAweDVhLCAoYnl0ZSkgMHg1YiwKKyAgICAgICAgICAgIChieXRlKSAweDVjLCAoYnl0ZSkgMHg1ZCwgKGJ5dGUpIDB4NWUsIChieXRlKSAweDVmLCAoYnl0ZSkgMHg2MCwKKyAgICAgICAgICAgIChieXRlKSAweDYxLCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4NjMsIChieXRlKSAweDY0LCAoYnl0ZSkgMHg2NSwKKyAgICAgICAgICAgIChieXRlKSAweDY2LCAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4NjgsIChieXRlKSAweDY5LCAoYnl0ZSkgMHg2YSwKKyAgICAgICAgICAgIChieXRlKSAweDZiLCAoYnl0ZSkgMHg2YywgKGJ5dGUpIDB4NmQsIChieXRlKSAweDZlLCAoYnl0ZSkgMHg2ZiwKKyAgICAgICAgICAgIChieXRlKSAweDcwLCAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4NzIsIChieXRlKSAweDczLCAoYnl0ZSkgMHg3NCwKKyAgICAgICAgICAgIChieXRlKSAweDc1LCAoYnl0ZSkgMHg3NiwgKGJ5dGUpIDB4NzcsIChieXRlKSAweDc4LCAoYnl0ZSkgMHg3OSwKKyAgICAgICAgICAgIChieXRlKSAweDdhLCAoYnl0ZSkgMHg3YiwgKGJ5dGUpIDB4N2MsIChieXRlKSAweDdkLCAoYnl0ZSkgMHg3ZSwKKyAgICAgICAgICAgIChieXRlKSAweDdmLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDgyLCAoYnl0ZSkgMHg4MywKKyAgICAgICAgICAgIChieXRlKSAweDg0LCAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4ODYsIChieXRlKSAweDg3LCAoYnl0ZSkgMHg4OCwKKyAgICAgICAgICAgIChieXRlKSAweDg5LCAoYnl0ZSkgMHg4YSwgKGJ5dGUpIDB4OGIsIChieXRlKSAweDhjLCAoYnl0ZSkgMHg4ZCwKKyAgICAgICAgICAgIChieXRlKSAweDhlLCAoYnl0ZSkgMHg4ZiwgKGJ5dGUpIDB4OTAsIChieXRlKSAweDkxLCAoYnl0ZSkgMHg5MiwKKyAgICAgICAgICAgIChieXRlKSAweDkzLCAoYnl0ZSkgMHg5NCwgKGJ5dGUpIDB4OTUsIChieXRlKSAweDk2LCAoYnl0ZSkgMHg5NywKKyAgICAgICAgICAgIChieXRlKSAweDk4LCAoYnl0ZSkgMHg5OSwgKGJ5dGUpIDB4OWEsIChieXRlKSAweDliLCAoYnl0ZSkgMHg5YywKKyAgICAgICAgICAgIChieXRlKSAweDlkLCAoYnl0ZSkgMHg5ZSwgKGJ5dGUpIDB4OWYsIChieXRlKSAweGEwLCAoYnl0ZSkgMHhhMSwKKyAgICAgICAgICAgIChieXRlKSAweGEyLCAoYnl0ZSkgMHhhMywgKGJ5dGUpIDB4YTQsIChieXRlKSAweGE1LCAoYnl0ZSkgMHhhNiwKKyAgICAgICAgICAgIChieXRlKSAweGE3LCAoYnl0ZSkgMHhhOCwgKGJ5dGUpIDB4YTksIChieXRlKSAweGFhLCAoYnl0ZSkgMHhhYiwKKyAgICAgICAgICAgIChieXRlKSAweGFjLCAoYnl0ZSkgMHhhZCwgKGJ5dGUpIDB4YWUsIChieXRlKSAweGFmLCAoYnl0ZSkgMHhiMCwKKyAgICAgICAgICAgIChieXRlKSAweGIxLCAoYnl0ZSkgMHhiMiwgKGJ5dGUpIDB4YjMsIChieXRlKSAweGI0LCAoYnl0ZSkgMHhiNSwKKyAgICAgICAgICAgIChieXRlKSAweGI2LCAoYnl0ZSkgMHhiNywgKGJ5dGUpIDB4YjgsIChieXRlKSAweGI5LCAoYnl0ZSkgMHhiYSwKKyAgICAgICAgICAgIChieXRlKSAweGJiLCAoYnl0ZSkgMHhiYywgKGJ5dGUpIDB4YmQsIChieXRlKSAweGJlLCAoYnl0ZSkgMHhiZiwKKyAgICAgICAgICAgIChieXRlKSAweGMwLCAoYnl0ZSkgMHhjMSwgKGJ5dGUpIDB4YzIsIChieXRlKSAweGMzLCAoYnl0ZSkgMHhjNCwKKyAgICAgICAgICAgIChieXRlKSAweGM1LCAoYnl0ZSkgMHhjNiwgKGJ5dGUpIDB4YzcsIChieXRlKSAweGM4LCAoYnl0ZSkgMHhjOSwKKyAgICAgICAgICAgIChieXRlKSAweGNhLCAoYnl0ZSkgMHhjYiwgKGJ5dGUpIDB4Y2MsIChieXRlKSAweGNkLCAoYnl0ZSkgMHhjZSwKKyAgICAgICAgICAgIChieXRlKSAweGNmLCAoYnl0ZSkgMHhkMCwgKGJ5dGUpIDB4ZDEsIChieXRlKSAweGQyLCAoYnl0ZSkgMHhkMywKKyAgICAgICAgICAgIChieXRlKSAweGQ0LCAoYnl0ZSkgMHhkNSwgKGJ5dGUpIDB4ZDYsIChieXRlKSAweGQ3LCAoYnl0ZSkgMHhkOCwKKyAgICAgICAgICAgIChieXRlKSAweGQ5LCAoYnl0ZSkgMHhkYSwgKGJ5dGUpIDB4ZGIsIChieXRlKSAweGRjLCAoYnl0ZSkgMHhkZCwKKyAgICAgICAgICAgIChieXRlKSAweGRlLCAoYnl0ZSkgMHhkZiwgKGJ5dGUpIDB4ZTAsIChieXRlKSAweGUxLCAoYnl0ZSkgMHhlMiwKKyAgICAgICAgICAgIChieXRlKSAweGUzLCAoYnl0ZSkgMHhlNCwgKGJ5dGUpIDB4ZTUsIChieXRlKSAweGU2LCAoYnl0ZSkgMHhlNywKKyAgICAgICAgICAgIChieXRlKSAweGU4LCAoYnl0ZSkgMHhlOSwgKGJ5dGUpIDB4ZWEsIChieXRlKSAweGViLCAoYnl0ZSkgMHhlYywKKyAgICAgICAgICAgIChieXRlKSAweGVkLCAoYnl0ZSkgMHhlZSwgKGJ5dGUpIDB4ZWYsIChieXRlKSAweGYwLCAoYnl0ZSkgMHhmMSwKKyAgICAgICAgICAgIChieXRlKSAweGYyLCAoYnl0ZSkgMHhmMywgKGJ5dGUpIDB4ZjQsIChieXRlKSAweGY1LCAoYnl0ZSkgMHhmNiwKKyAgICAgICAgICAgIChieXRlKSAweGY3LCAoYnl0ZSkgMHhmOCwgKGJ5dGUpIDB4ZjksIChieXRlKSAweGZhLCAoYnl0ZSkgMHhmYiwKKyAgICAgICAgICAgIChieXRlKSAweGZjLCAoYnl0ZSkgMHhmZCwgKGJ5dGUpIDB4ZmUsIChieXRlKSAweGZmLCAoYnl0ZSkgMHgwMCwKKyAgICAgICAgICAgIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDMsIChieXRlKSAweDA0LCAoYnl0ZSkgMHgwNSwKKyAgICAgICAgICAgIChieXRlKSAweDA2LCAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4MDgsIChieXRlKSAweDA5LCAoYnl0ZSkgMHgwYSwKKyAgICAgICAgICAgIChieXRlKSAweDBiLCAoYnl0ZSkgMHgwYywgKGJ5dGUpIDB4MGQsIChieXRlKSAweDBlLCAoYnl0ZSkgMHgwZiwKKyAgICAgICAgICAgIChieXRlKSAweDEwLCAoYnl0ZSkgMHgxMSwgKGJ5dGUpIDB4MTIsIChieXRlKSAweDEzLCAoYnl0ZSkgMHgxNCwKKyAgICAgICAgICAgIChieXRlKSAweDE1LCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4MTcsIChieXRlKSAweDE4LCAoYnl0ZSkgMHgxOSwKKyAgICAgICAgICAgIChieXRlKSAweDFhLCAoYnl0ZSkgMHgxYiwgKGJ5dGUpIDB4MWMsIChieXRlKSAweDFkLCAoYnl0ZSkgMHgxZSwKKyAgICAgICAgICAgIChieXRlKSAweDFmLCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4MjEsIChieXRlKSAweDIyLCAoYnl0ZSkgMHgyMywKKyAgICAgICAgICAgIChieXRlKSAweDI0LCAoYnl0ZSkgMHgyNSwgKGJ5dGUpIDB4MjYsIChieXRlKSAweDI3LCAoYnl0ZSkgMHgyOCwKKyAgICAgICAgICAgIChieXRlKSAweDI5LCAoYnl0ZSkgMHgyYSwgKGJ5dGUpIDB4MmIsIChieXRlKSAweDJjLCAoYnl0ZSkgMHgyZCwKKyAgICAgICAgICAgIChieXRlKSAweDJlLCAoYnl0ZSkgMHgyZiwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDMxLCAoYnl0ZSkgMHgzMiwKKyAgICAgICAgICAgIChieXRlKSAweDMzLCAoYnl0ZSkgMHgzNCwgKGJ5dGUpIDB4MzUsIChieXRlKSAweDM2LCAoYnl0ZSkgMHgzNywKKyAgICAgICAgICAgIChieXRlKSAweDM4LCAoYnl0ZSkgMHgzOSwgKGJ5dGUpIDB4M2EsIChieXRlKSAweDNiLCAoYnl0ZSkgMHgzYywKKyAgICAgICAgICAgIChieXRlKSAweDNkLCAoYnl0ZSkgMHgzZSwgKGJ5dGUpIDB4M2YsIChieXRlKSAweDQwLCAoYnl0ZSkgMHg0MSwKKyAgICAgICAgICAgIChieXRlKSAweDQyLCAoYnl0ZSkgMHg0MywgKGJ5dGUpIDB4NDQsIChieXRlKSAweDQ1LCAoYnl0ZSkgMHg0NiwKKyAgICAgICAgICAgIChieXRlKSAweDQ3LCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4NDksIChieXRlKSAweDRhLCAoYnl0ZSkgMHg0YiwKKyAgICAgICAgICAgIChieXRlKSAweDRjLCAoYnl0ZSkgMHg0ZCwgKGJ5dGUpIDB4NGUsIChieXRlKSAweDRmLCAoYnl0ZSkgMHg1MCwKKyAgICAgICAgICAgIChieXRlKSAweDUxLCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4NTMsIChieXRlKSAweDU0LCAoYnl0ZSkgMHg1NSwKKyAgICAgICAgICAgIChieXRlKSAweDU2LCAoYnl0ZSkgMHg1NywgKGJ5dGUpIDB4NTgsIChieXRlKSAweDU5LCAoYnl0ZSkgMHg1YSwKKyAgICAgICAgICAgIChieXRlKSAweDViLCAoYnl0ZSkgMHg1YywgKGJ5dGUpIDB4NWQsIChieXRlKSAweDVlLCAoYnl0ZSkgMHg1ZiwKKyAgICAgICAgICAgIChieXRlKSAweDYwLCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4NjIsIChieXRlKSAweDYzLCAoYnl0ZSkgMHg2NCwKKyAgICAgICAgICAgIChieXRlKSAweDY1LCAoYnl0ZSkgMHg2NiwgKGJ5dGUpIDB4NjcsIChieXRlKSAweDY4LCAoYnl0ZSkgMHg2OSwKKyAgICAgICAgICAgIChieXRlKSAweDZhLCAoYnl0ZSkgMHg2YiwgKGJ5dGUpIDB4NmMsIChieXRlKSAweDZkLCAoYnl0ZSkgMHg2ZSwKKyAgICAgICAgICAgIChieXRlKSAweDZmLCAoYnl0ZSkgMHg3MCwgKGJ5dGUpIDB4NzEsIChieXRlKSAweDcyLCAoYnl0ZSkgMHg3MywKKyAgICAgICAgICAgIChieXRlKSAweDc0LCAoYnl0ZSkgMHg3NSwgKGJ5dGUpIDB4NzYsIChieXRlKSAweDc3LCAoYnl0ZSkgMHg3OCwKKyAgICAgICAgICAgIChieXRlKSAweDc5LCAoYnl0ZSkgMHg3YSwgKGJ5dGUpIDB4N2IsIChieXRlKSAweDdjLCAoYnl0ZSkgMHg3ZCwKKyAgICAgICAgICAgIChieXRlKSAweDdlLCAoYnl0ZSkgMHg3ZiwgKGJ5dGUpIDB4ODAsIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4MiwKKyAgICAgICAgICAgIChieXRlKSAweDgzLCAoYnl0ZSkgMHg4NCwgKGJ5dGUpIDB4ODUsIChieXRlKSAweDg2LCAoYnl0ZSkgMHg4NywKKyAgICAgICAgICAgIChieXRlKSAweDg4LCAoYnl0ZSkgMHg4OSwgKGJ5dGUpIDB4OGEsIChieXRlKSAweDhiLCAoYnl0ZSkgMHg4YywKKyAgICAgICAgICAgIChieXRlKSAweDhkLCAoYnl0ZSkgMHg4ZSwgKGJ5dGUpIDB4OGYsIChieXRlKSAweDkwLCAoYnl0ZSkgMHg5MSwKKyAgICAgICAgICAgIChieXRlKSAweDkyLCAoYnl0ZSkgMHg5MywgKGJ5dGUpIDB4OTQsIChieXRlKSAweDk1LCAoYnl0ZSkgMHg5NiwKKyAgICAgICAgICAgIChieXRlKSAweDk3LCAoYnl0ZSkgMHg5OCwgKGJ5dGUpIDB4OTksIChieXRlKSAweDlhLCAoYnl0ZSkgMHg5YiwKKyAgICAgICAgICAgIChieXRlKSAweDljLCAoYnl0ZSkgMHg5ZCwgKGJ5dGUpIDB4OWUsIChieXRlKSAweDlmLCAoYnl0ZSkgMHhhMCwKKyAgICAgICAgICAgIChieXRlKSAweGExLCAoYnl0ZSkgMHhhMiwgKGJ5dGUpIDB4YTMsIChieXRlKSAweGE0LCAoYnl0ZSkgMHhhNSwKKyAgICAgICAgICAgIChieXRlKSAweGE2LCAoYnl0ZSkgMHhhNywgKGJ5dGUpIDB4YTgsIChieXRlKSAweGE5LCAoYnl0ZSkgMHhhYSwKKyAgICAgICAgICAgIChieXRlKSAweGFiLCAoYnl0ZSkgMHhhYywgKGJ5dGUpIDB4YWQsIChieXRlKSAweGFlLCAoYnl0ZSkgMHhhZiwKKyAgICAgICAgICAgIChieXRlKSAweGIwLCAoYnl0ZSkgMHhiMSwgKGJ5dGUpIDB4YjIsIChieXRlKSAweGIzLCAoYnl0ZSkgMHhiNCwKKyAgICAgICAgICAgIChieXRlKSAweGI1LCAoYnl0ZSkgMHhiNiwgKGJ5dGUpIDB4YjcsIChieXRlKSAweGI4LCAoYnl0ZSkgMHhiOSwKKyAgICAgICAgICAgIChieXRlKSAweGJhLCAoYnl0ZSkgMHhiYiwgKGJ5dGUpIDB4YmMsIChieXRlKSAweGJkLCAoYnl0ZSkgMHhiZSwKKyAgICAgICAgICAgIChieXRlKSAweGJmLCAoYnl0ZSkgMHhjMCwgKGJ5dGUpIDB4YzEsIChieXRlKSAweGMyLCAoYnl0ZSkgMHhjMywKKyAgICAgICAgICAgIChieXRlKSAweGM0LCAoYnl0ZSkgMHhjNSwgKGJ5dGUpIDB4YzYsIChieXRlKSAweGM3LCAoYnl0ZSkgMHhjOCwKKyAgICAgICAgICAgIChieXRlKSAweGM5LCAoYnl0ZSkgMHhjYSwgKGJ5dGUpIDB4Y2IsIChieXRlKSAweGNjLCAoYnl0ZSkgMHhjZCwKKyAgICAgICAgICAgIChieXRlKSAweGNlLCAoYnl0ZSkgMHhjZiwgKGJ5dGUpIDB4ZDAsIChieXRlKSAweGQxLCAoYnl0ZSkgMHhkMiwKKyAgICAgICAgICAgIChieXRlKSAweGQzLCAoYnl0ZSkgMHhkNCwgKGJ5dGUpIDB4ZDUsIChieXRlKSAweGQ2LCAoYnl0ZSkgMHhkNywKKyAgICAgICAgICAgIChieXRlKSAweGQ4LCAoYnl0ZSkgMHhkOSwgKGJ5dGUpIDB4ZGEsIChieXRlKSAweGRiLCAoYnl0ZSkgMHhkYywKKyAgICAgICAgICAgIChieXRlKSAweGRkLCAoYnl0ZSkgMHhkZSwgKGJ5dGUpIDB4ZGYsIChieXRlKSAweGUwLCAoYnl0ZSkgMHhlMSwKKyAgICAgICAgICAgIChieXRlKSAweGUyLCAoYnl0ZSkgMHhlMywgKGJ5dGUpIDB4ZTQsIChieXRlKSAweGU1LCAoYnl0ZSkgMHhlNiwKKyAgICAgICAgICAgIChieXRlKSAweGU3LCAoYnl0ZSkgMHhlOCwgKGJ5dGUpIDB4ZTksIChieXRlKSAweGVhLCAoYnl0ZSkgMHhlYiwKKyAgICAgICAgICAgIChieXRlKSAweGVjLCAoYnl0ZSkgMHhlZCwgKGJ5dGUpIDB4ZWUsIChieXRlKSAweGVmLCAoYnl0ZSkgMHhmMCwKKyAgICAgICAgICAgIChieXRlKSAweGYxLCAoYnl0ZSkgMHhmMiwgKGJ5dGUpIDB4ZjMsIChieXRlKSAweGY0LCAoYnl0ZSkgMHhmNSwKKyAgICAgICAgICAgIChieXRlKSAweGY2LCAoYnl0ZSkgMHhmNywgKGJ5dGUpIDB4ZjgsIChieXRlKSAweGY5LCAoYnl0ZSkgMHhmYSwKKyAgICAgICAgICAgIChieXRlKSAweGZiLCAoYnl0ZSkgMHhmYywgKGJ5dGUpIDB4ZmQsIChieXRlKSAweGZlLCAoYnl0ZSkgMHhmZiwgfTsKKworICAgIC8qKgorICAgICAqICJ2YWxpZCIgZW5jb2RpbmcgZm9yIERIIHdpdGggYWxnIHBhcmFtcworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBkaEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDA1LCAoYnl0ZSkgMHgyMiwgKGJ5dGUpIDB4MzAsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDFhLCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MDksCisgICAgICAgICAgICAoYnl0ZSkgMHgyYSwgKGJ5dGUpIDB4ODYsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4ZjcsCisgICAgICAgICAgICAoYnl0ZSkgMHgwZCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAzLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MzAsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDBiLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4ODEsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweGNlLCAoYnl0ZSkgMHgyYywgKGJ5dGUpIDB4NGYsCisgICAgICAgICAgICAoYnl0ZSkgMHhlYSwgKGJ5dGUpIDB4ZjIsIChieXRlKSAweDgzLCAoYnl0ZSkgMHhjNSwgKGJ5dGUpIDB4MzgsCisgICAgICAgICAgICAoYnl0ZSkgMHhjOSwgKGJ5dGUpIDB4YjYsIChieXRlKSAweGQ0LCAoYnl0ZSkgMHhmOCwgKGJ5dGUpIDB4YjgsCisgICAgICAgICAgICAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4YTEsIChieXRlKSAweDdkLCAoYnl0ZSkgMHg0YywgKGJ5dGUpIDB4ZWMsCisgICAgICAgICAgICAoYnl0ZSkgMHg2YiwgKGJ5dGUpIDB4ZDcsIChieXRlKSAweGMyLCAoYnl0ZSkgMHgxYSwgKGJ5dGUpIDB4MzUsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4NTQsIChieXRlKSAweDE0LCAoYnl0ZSkgMHg2YywgKGJ5dGUpIDB4NTIsCisgICAgICAgICAgICAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4YmYsIChieXRlKSAweGU2LCAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4ZDgsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4YWMsIChieXRlKSAweGIzLCAoYnl0ZSkgMHgyOCwgKGJ5dGUpIDB4NGYsCisgICAgICAgICAgICAoYnl0ZSkgMHg3NywgKGJ5dGUpIDB4ZjYsIChieXRlKSAweGZjLCAoYnl0ZSkgMHhlYSwgKGJ5dGUpIDB4ZWEsCisgICAgICAgICAgICAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4Y2YsIChieXRlKSAweDFkLCAoYnl0ZSkgMHg3YiwgKGJ5dGUpIDB4ZTEsCisgICAgICAgICAgICAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4ZmEsIChieXRlKSAweDc3LCAoYnl0ZSkgMHgxMiwgKGJ5dGUpIDB4YTksCisgICAgICAgICAgICAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4YmEsIChieXRlKSAweGM0LCAoYnl0ZSkgMHhmNCwgKGJ5dGUpIDB4ZmIsCisgICAgICAgICAgICAoYnl0ZSkgMHhiZCwgKGJ5dGUpIDB4OWYsIChieXRlKSAweDYzLCAoYnl0ZSkgMHg5YSwgKGJ5dGUpIDB4NTgsCisgICAgICAgICAgICAoYnl0ZSkgMHg2YiwgKGJ5dGUpIDB4YjYsIChieXRlKSAweGEyLCAoYnl0ZSkgMHg2ZSwgKGJ5dGUpIDB4M2EsCisgICAgICAgICAgICAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4ZjMsIChieXRlKSAweDQzLCAoYnl0ZSkgMHg1ZSwgKGJ5dGUpIDB4NmYsCisgICAgICAgICAgICAoYnl0ZSkgMHg4YSwgKGJ5dGUpIDB4ZDAsIChieXRlKSAweGFjLCAoYnl0ZSkgMHhlNSwgKGJ5dGUpIDB4NjAsCisgICAgICAgICAgICAoYnl0ZSkgMHg3NiwgKGJ5dGUpIDB4NTcsIChieXRlKSAweDFmLCAoYnl0ZSkgMHg4MywgKGJ5dGUpIDB4NGQsCisgICAgICAgICAgICAoYnl0ZSkgMHhiYywgKGJ5dGUpIDB4YWEsIChieXRlKSAweGIxLCAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4NDAsCisgICAgICAgICAgICAoYnl0ZSkgMHgxOSwgKGJ5dGUpIDB4YWMsIChieXRlKSAweDMxLCAoYnl0ZSkgMHhkNCwgKGJ5dGUpIDB4ZmMsCisgICAgICAgICAgICAoYnl0ZSkgMHgzOSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDQ2LCAoYnl0ZSkgMHhhYiwgKGJ5dGUpIDB4YWIsCisgICAgICAgICAgICAoYnl0ZSkgMHg1MywgKGJ5dGUpIDB4MTksIChieXRlKSAweDJkLCAoYnl0ZSkgMHhmOCwgKGJ5dGUpIDB4NGMsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMywgKGJ5dGUpIDB4OWYsIChieXRlKSAweDRkLCAoYnl0ZSkgMHhhNiwgKGJ5dGUpIDB4NzEsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4MDYsIChieXRlKSAweGM3LCAoYnl0ZSkgMHg4OSwgKGJ5dGUpIDB4NzAsCisgICAgICAgICAgICAoYnl0ZSkgMHhjNCwgKGJ5dGUpIDB4YzYsIChieXRlKSAweGEyLCAoYnl0ZSkgMHgxZiwgKGJ5dGUpIDB4MDUsCisgICAgICAgICAgICAoYnl0ZSkgMHg0YSwgKGJ5dGUpIDB4NWIsIChieXRlKSAweDg0LCAoYnl0ZSkgMHhmOSwgKGJ5dGUpIDB4ZmIsCisgICAgICAgICAgICAoYnl0ZSkgMHg5OCwgKGJ5dGUpIDB4NjMsIChieXRlKSAweGM5LCAoYnl0ZSkgMHg5YywgKGJ5dGUpIDB4MTMsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDgwLCAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4NTUsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MywgKGJ5dGUpIDB4YjMsIChieXRlKSAweDIyLCAoYnl0ZSkgMHgwYywgKGJ5dGUpIDB4Y2QsCisgICAgICAgICAgICAoYnl0ZSkgMHg3YywgKGJ5dGUpIDB4YzMsIChieXRlKSAweGUzLCAoYnl0ZSkgMHhhMywgKGJ5dGUpIDB4OGEsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNywgKGJ5dGUpIDB4YjQsIChieXRlKSAweGU5LCAoYnl0ZSkgMHhlMCwgKGJ5dGUpIDB4ZmEsCisgICAgICAgICAgICAoYnl0ZSkgMHhhOSwgKGJ5dGUpIDB4YTgsIChieXRlKSAweDY5LCAoYnl0ZSkgMHhkNiwgKGJ5dGUpIDB4YTYsCisgICAgICAgICAgICAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4YjgsIChieXRlKSAweGQ0LCAoYnl0ZSkgMHhlNywgKGJ5dGUpIDB4ODcsCisgICAgICAgICAgICAoYnl0ZSkgMHg0ZSwgKGJ5dGUpIDB4ZjMsIChieXRlKSAweDkwLCAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4ZGQsCisgICAgICAgICAgICAoYnl0ZSkgMHg3NSwgKGJ5dGUpIDB4NWQsIChieXRlKSAweGZmLCAoYnl0ZSkgMHhlZSwgKGJ5dGUpIDB4ZjAsCisgICAgICAgICAgICAoYnl0ZSkgMHhlZiwgKGJ5dGUpIDB4NmEsIChieXRlKSAweDBhLCAoYnl0ZSkgMHhiMCwgKGJ5dGUpIDB4ZjEsCisgICAgICAgICAgICAoYnl0ZSkgMHg4YSwgKGJ5dGUpIDB4YjYsIChieXRlKSAweDdiLCAoYnl0ZSkgMHgzOSwgKGJ5dGUpIDB4OTUsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNSwgKGJ5dGUpIDB4MjQsIChieXRlKSAweDgzLCAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4OTUsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNCwgKGJ5dGUpIDB4MDgsIChieXRlKSAweDc3LCAoYnl0ZSkgMHgxZCwgKGJ5dGUpIDB4YWYsCisgICAgICAgICAgICAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4ZjAsIChieXRlKSAweGI1LCAoYnl0ZSkgMHhkYiwgKGJ5dGUpIDB4MjQsCisgICAgICAgICAgICAoYnl0ZSkgMHg4OSwgKGJ5dGUpIDB4NzIsIChieXRlKSAweGIyLCAoYnl0ZSkgMHgwZCwgKGJ5dGUpIDB4NTcsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NCwgKGJ5dGUpIDB4YjAsIChieXRlKSAweGU4LCAoYnl0ZSkgMHhjMiwgKGJ5dGUpIDB4MzcsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4NWEsIChieXRlKSAweGZjLCAoYnl0ZSkgMHhhMSwgKGJ5dGUpIDB4YTAsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4ZTQsIChieXRlKSAweDBjLCAoYnl0ZSkgMHhhMywgKGJ5dGUpIDB4NDAsCisgICAgICAgICAgICAoYnl0ZSkgMHg4YiwgKGJ5dGUpIDB4OWMsIChieXRlKSAweDE5LCAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4NjEsCisgICAgICAgICAgICAoYnl0ZSkgMHhkOSwgKGJ5dGUpIDB4MDUsIChieXRlKSAweGJmLCAoYnl0ZSkgMHhjNSwgKGJ5dGUpIDB4ZTgsCisgICAgICAgICAgICAoYnl0ZSkgMHhmNywgKGJ5dGUpIDB4YmQsIChieXRlKSAweDNhLCAoYnl0ZSkgMHhmNSwgKGJ5dGUpIDB4NzgsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMiwgKGJ5dGUpIDB4OTIsIChieXRlKSAweGU4LCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4MDcsCisgICAgICAgICAgICAoYnl0ZSkgMHgzZSwgKGJ5dGUpIDB4NTcsIChieXRlKSAweDEyLCAoYnl0ZSkgMHhmNiwgKGJ5dGUpIDB4OTcsCisgICAgICAgICAgICAoYnl0ZSkgMHgxZiwgKGJ5dGUpIDB4ZWEsIChieXRlKSAweDAyLCAoYnl0ZSkgMHhhMywgKGJ5dGUpIDB4MTksCisgICAgICAgICAgICAoYnl0ZSkgMHhhNywgKGJ5dGUpIDB4NWEsIChieXRlKSAweDliLCAoYnl0ZSkgMHhmNiwgKGJ5dGUpIDB4ZDIsCisgICAgICAgICAgICAoYnl0ZSkgMHgwZiwgKGJ5dGUpIDB4ZTksIChieXRlKSAweDZiLCAoYnl0ZSkgMHhlYiwgKGJ5dGUpIDB4ZDcsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MywgKGJ5dGUpIDB4OWEsIChieXRlKSAweDdlLCAoYnl0ZSkgMHg0ZiwgKGJ5dGUpIDB4ZDYsCisgICAgICAgICAgICAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4ZmYsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDA0LCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDAzLCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MDUsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MDcsIChieXRlKSAweDA4LCAoYnl0ZSkgMHgwOSwgKGJ5dGUpIDB4MGEsCisgICAgICAgICAgICAoYnl0ZSkgMHgwYiwgKGJ5dGUpIDB4MGMsIChieXRlKSAweDBkLCAoYnl0ZSkgMHgwZSwgKGJ5dGUpIDB4MGYsCisgICAgICAgICAgICAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4MTEsIChieXRlKSAweDEyLCAoYnl0ZSkgMHgxMywgKGJ5dGUpIDB4MTQsCisgICAgICAgICAgICAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4MTYsIChieXRlKSAweDE3LCAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4MTksCisgICAgICAgICAgICAoYnl0ZSkgMHgxYSwgKGJ5dGUpIDB4MWIsIChieXRlKSAweDFjLCAoYnl0ZSkgMHgxZCwgKGJ5dGUpIDB4MWUsCisgICAgICAgICAgICAoYnl0ZSkgMHgxZiwgKGJ5dGUpIDB4MjAsIChieXRlKSAweDIxLCAoYnl0ZSkgMHgyMiwgKGJ5dGUpIDB4MjMsCisgICAgICAgICAgICAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4MjUsIChieXRlKSAweDI2LCAoYnl0ZSkgMHgyNywgKGJ5dGUpIDB4MjgsCisgICAgICAgICAgICAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4MmEsIChieXRlKSAweDJiLCAoYnl0ZSkgMHgyYywgKGJ5dGUpIDB4MmQsCisgICAgICAgICAgICAoYnl0ZSkgMHgyZSwgKGJ5dGUpIDB4MmYsIChieXRlKSAweDMwLCAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4MzIsCisgICAgICAgICAgICAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4MzQsIChieXRlKSAweDM1LCAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4MzcsCisgICAgICAgICAgICAoYnl0ZSkgMHgzOCwgKGJ5dGUpIDB4MzksIChieXRlKSAweDNhLCAoYnl0ZSkgMHgzYiwgKGJ5dGUpIDB4M2MsCisgICAgICAgICAgICAoYnl0ZSkgMHgzZCwgKGJ5dGUpIDB4M2UsIChieXRlKSAweDNmLCAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NDEsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4NDMsIChieXRlKSAweDQ0LCAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4NDYsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NywgKGJ5dGUpIDB4NDgsIChieXRlKSAweDQ5LCAoYnl0ZSkgMHg0YSwgKGJ5dGUpIDB4NGIsCisgICAgICAgICAgICAoYnl0ZSkgMHg0YywgKGJ5dGUpIDB4NGQsIChieXRlKSAweDRlLCAoYnl0ZSkgMHg0ZiwgKGJ5dGUpIDB4NTAsCisgICAgICAgICAgICAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4NTIsIChieXRlKSAweDUzLCAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4NTUsCisgICAgICAgICAgICAoYnl0ZSkgMHg1NiwgKGJ5dGUpIDB4NTcsIChieXRlKSAweDU4LCAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4NWEsCisgICAgICAgICAgICAoYnl0ZSkgMHg1YiwgKGJ5dGUpIDB4NWMsIChieXRlKSAweDVkLCAoYnl0ZSkgMHg1ZSwgKGJ5dGUpIDB4NWYsCisgICAgICAgICAgICAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4NjEsIChieXRlKSAweDYyLCAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4NjQsCisgICAgICAgICAgICAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4NjYsIChieXRlKSAweDY3LCAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4NjksCisgICAgICAgICAgICAoYnl0ZSkgMHg2YSwgKGJ5dGUpIDB4NmIsIChieXRlKSAweDZjLCAoYnl0ZSkgMHg2ZCwgKGJ5dGUpIDB4NmUsCisgICAgICAgICAgICAoYnl0ZSkgMHg2ZiwgKGJ5dGUpIDB4NzAsIChieXRlKSAweDcxLCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4NzMsCisgICAgICAgICAgICAoYnl0ZSkgMHg3NCwgKGJ5dGUpIDB4NzUsIChieXRlKSAweDc2LCAoYnl0ZSkgMHg3NywgKGJ5dGUpIDB4NzgsCisgICAgICAgICAgICAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4N2EsIChieXRlKSAweDdiLCAoYnl0ZSkgMHg3YywgKGJ5dGUpIDB4N2QsCisgICAgICAgICAgICAoYnl0ZSkgMHg3ZSwgKGJ5dGUpIDB4N2YsIChieXRlKSAweDgwLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODIsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MywgKGJ5dGUpIDB4ODQsIChieXRlKSAweDg1LCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4ODcsCisgICAgICAgICAgICAoYnl0ZSkgMHg4OCwgKGJ5dGUpIDB4ODksIChieXRlKSAweDhhLCAoYnl0ZSkgMHg4YiwgKGJ5dGUpIDB4OGMsCisgICAgICAgICAgICAoYnl0ZSkgMHg4ZCwgKGJ5dGUpIDB4OGUsIChieXRlKSAweDhmLCAoYnl0ZSkgMHg5MCwgKGJ5dGUpIDB4OTEsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4OTMsIChieXRlKSAweDk0LCAoYnl0ZSkgMHg5NSwgKGJ5dGUpIDB4OTYsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NywgKGJ5dGUpIDB4OTgsIChieXRlKSAweDk5LCAoYnl0ZSkgMHg5YSwgKGJ5dGUpIDB4OWIsCisgICAgICAgICAgICAoYnl0ZSkgMHg5YywgKGJ5dGUpIDB4OWQsIChieXRlKSAweDllLCAoYnl0ZSkgMHg5ZiwgKGJ5dGUpIDB4YTAsCisgICAgICAgICAgICAoYnl0ZSkgMHhhMSwgKGJ5dGUpIDB4YTIsIChieXRlKSAweGEzLCAoYnl0ZSkgMHhhNCwgKGJ5dGUpIDB4YTUsCisgICAgICAgICAgICAoYnl0ZSkgMHhhNiwgKGJ5dGUpIDB4YTcsIChieXRlKSAweGE4LCAoYnl0ZSkgMHhhOSwgKGJ5dGUpIDB4YWEsCisgICAgICAgICAgICAoYnl0ZSkgMHhhYiwgKGJ5dGUpIDB4YWMsIChieXRlKSAweGFkLCAoYnl0ZSkgMHhhZSwgKGJ5dGUpIDB4YWYsCisgICAgICAgICAgICAoYnl0ZSkgMHhiMCwgKGJ5dGUpIDB4YjEsIChieXRlKSAweGIyLCAoYnl0ZSkgMHhiMywgKGJ5dGUpIDB4YjQsCisgICAgICAgICAgICAoYnl0ZSkgMHhiNSwgKGJ5dGUpIDB4YjYsIChieXRlKSAweGI3LCAoYnl0ZSkgMHhiOCwgKGJ5dGUpIDB4YjksCisgICAgICAgICAgICAoYnl0ZSkgMHhiYSwgKGJ5dGUpIDB4YmIsIChieXRlKSAweGJjLCAoYnl0ZSkgMHhiZCwgKGJ5dGUpIDB4YmUsCisgICAgICAgICAgICAoYnl0ZSkgMHhiZiwgKGJ5dGUpIDB4YzAsIChieXRlKSAweGMxLCAoYnl0ZSkgMHhjMiwgKGJ5dGUpIDB4YzMsCisgICAgICAgICAgICAoYnl0ZSkgMHhjNCwgKGJ5dGUpIDB4YzUsIChieXRlKSAweGM2LCAoYnl0ZSkgMHhjNywgKGJ5dGUpIDB4YzgsCisgICAgICAgICAgICAoYnl0ZSkgMHhjOSwgKGJ5dGUpIDB4Y2EsIChieXRlKSAweGNiLCAoYnl0ZSkgMHhjYywgKGJ5dGUpIDB4Y2QsCisgICAgICAgICAgICAoYnl0ZSkgMHhjZSwgKGJ5dGUpIDB4Y2YsIChieXRlKSAweGQwLCAoYnl0ZSkgMHhkMSwgKGJ5dGUpIDB4ZDIsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMywgKGJ5dGUpIDB4ZDQsIChieXRlKSAweGQ1LCAoYnl0ZSkgMHhkNiwgKGJ5dGUpIDB4ZDcsCisgICAgICAgICAgICAoYnl0ZSkgMHhkOCwgKGJ5dGUpIDB4ZDksIChieXRlKSAweGRhLCAoYnl0ZSkgMHhkYiwgKGJ5dGUpIDB4ZGMsCisgICAgICAgICAgICAoYnl0ZSkgMHhkZCwgKGJ5dGUpIDB4ZGUsIChieXRlKSAweGRmLCAoYnl0ZSkgMHhlMCwgKGJ5dGUpIDB4ZTEsCisgICAgICAgICAgICAoYnl0ZSkgMHhlMiwgKGJ5dGUpIDB4ZTMsIChieXRlKSAweGU0LCAoYnl0ZSkgMHhlNSwgKGJ5dGUpIDB4ZTYsCisgICAgICAgICAgICAoYnl0ZSkgMHhlNywgKGJ5dGUpIDB4ZTgsIChieXRlKSAweGU5LCAoYnl0ZSkgMHhlYSwgKGJ5dGUpIDB4ZWIsCisgICAgICAgICAgICAoYnl0ZSkgMHhlYywgKGJ5dGUpIDB4ZWQsIChieXRlKSAweGVlLCAoYnl0ZSkgMHhlZiwgKGJ5dGUpIDB4ZjAsCisgICAgICAgICAgICAoYnl0ZSkgMHhmMSwgKGJ5dGUpIDB4ZjIsIChieXRlKSAweGYzLCAoYnl0ZSkgMHhmNCwgKGJ5dGUpIDB4ZjUsCisgICAgICAgICAgICAoYnl0ZSkgMHhmNiwgKGJ5dGUpIDB4ZjcsIChieXRlKSAweGY4LCAoYnl0ZSkgMHhmOSwgKGJ5dGUpIDB4ZmEsCisgICAgICAgICAgICAoYnl0ZSkgMHhmYiwgKGJ5dGUpIDB4ZmMsIChieXRlKSAweGZkLCAoYnl0ZSkgMHhmZSwgKGJ5dGUpIDB4ZmYsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MDQsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4MDYsIChieXRlKSAweDA3LCAoYnl0ZSkgMHgwOCwgKGJ5dGUpIDB4MDksCisgICAgICAgICAgICAoYnl0ZSkgMHgwYSwgKGJ5dGUpIDB4MGIsIChieXRlKSAweDBjLCAoYnl0ZSkgMHgwZCwgKGJ5dGUpIDB4MGUsCisgICAgICAgICAgICAoYnl0ZSkgMHgwZiwgKGJ5dGUpIDB4MTAsIChieXRlKSAweDExLCAoYnl0ZSkgMHgxMiwgKGJ5dGUpIDB4MTMsCisgICAgICAgICAgICAoYnl0ZSkgMHgxNCwgKGJ5dGUpIDB4MTUsIChieXRlKSAweDE2LCAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4MTgsCisgICAgICAgICAgICAoYnl0ZSkgMHgxOSwgKGJ5dGUpIDB4MWEsIChieXRlKSAweDFiLCAoYnl0ZSkgMHgxYywgKGJ5dGUpIDB4MWQsCisgICAgICAgICAgICAoYnl0ZSkgMHgxZSwgKGJ5dGUpIDB4MWYsIChieXRlKSAweDIwLCAoYnl0ZSkgMHgyMSwgKGJ5dGUpIDB4MjIsCisgICAgICAgICAgICAoYnl0ZSkgMHgyMywgKGJ5dGUpIDB4MjQsIChieXRlKSAweDI1LCAoYnl0ZSkgMHgyNiwgKGJ5dGUpIDB4MjcsCisgICAgICAgICAgICAoYnl0ZSkgMHgyOCwgKGJ5dGUpIDB4MjksIChieXRlKSAweDJhLCAoYnl0ZSkgMHgyYiwgKGJ5dGUpIDB4MmMsCisgICAgICAgICAgICAoYnl0ZSkgMHgyZCwgKGJ5dGUpIDB4MmUsIChieXRlKSAweDJmLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4MzEsCisgICAgICAgICAgICAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4MzMsIChieXRlKSAweDM0LCAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4MzYsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNywgKGJ5dGUpIDB4MzgsIChieXRlKSAweDM5LCAoYnl0ZSkgMHgzYSwgKGJ5dGUpIDB4M2IsCisgICAgICAgICAgICAoYnl0ZSkgMHgzYywgKGJ5dGUpIDB4M2QsIChieXRlKSAweDNlLCAoYnl0ZSkgMHgzZiwgKGJ5dGUpIDB4NDAsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4NDIsIChieXRlKSAweDQzLCAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4NDUsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NiwgKGJ5dGUpIDB4NDcsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg0OSwgKGJ5dGUpIDB4NGEsCisgICAgICAgICAgICAoYnl0ZSkgMHg0YiwgKGJ5dGUpIDB4NGMsIChieXRlKSAweDRkLCAoYnl0ZSkgMHg0ZSwgKGJ5dGUpIDB4NGYsCisgICAgICAgICAgICAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NTEsIChieXRlKSAweDUyLCAoYnl0ZSkgMHg1MywgKGJ5dGUpIDB4NTQsCisgICAgICAgICAgICAoYnl0ZSkgMHg1NSwgKGJ5dGUpIDB4NTYsIChieXRlKSAweDU3LCAoYnl0ZSkgMHg1OCwgKGJ5dGUpIDB4NTksCisgICAgICAgICAgICAoYnl0ZSkgMHg1YSwgKGJ5dGUpIDB4NWIsIChieXRlKSAweDVjLCAoYnl0ZSkgMHg1ZCwgKGJ5dGUpIDB4NWUsCisgICAgICAgICAgICAoYnl0ZSkgMHg1ZiwgKGJ5dGUpIDB4NjAsIChieXRlKSAweDYxLCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4NjMsCisgICAgICAgICAgICAoYnl0ZSkgMHg2NCwgKGJ5dGUpIDB4NjUsIChieXRlKSAweDY2LCAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4NjgsCisgICAgICAgICAgICAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4NmEsIChieXRlKSAweDZiLCAoYnl0ZSkgMHg2YywgKGJ5dGUpIDB4NmQsCisgICAgICAgICAgICAoYnl0ZSkgMHg2ZSwgKGJ5dGUpIDB4NmYsIChieXRlKSAweDcwLCAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4NzIsCisgICAgICAgICAgICAoYnl0ZSkgMHg3MywgKGJ5dGUpIDB4NzQsIChieXRlKSAweDc1LCAoYnl0ZSkgMHg3NiwgKGJ5dGUpIDB4NzcsCisgICAgICAgICAgICAoYnl0ZSkgMHg3OCwgKGJ5dGUpIDB4NzksIChieXRlKSAweDdhLCAoYnl0ZSkgMHg3YiwgKGJ5dGUpIDB4N2MsCisgICAgICAgICAgICAoYnl0ZSkgMHg3ZCwgKGJ5dGUpIDB4N2UsIChieXRlKSAweDdmLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4ODEsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4ODMsIChieXRlKSAweDg0LCAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4ODYsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NywgKGJ5dGUpIDB4ODgsIChieXRlKSAweDg5LCAoYnl0ZSkgMHg4YSwgKGJ5dGUpIDB4OGIsCisgICAgICAgICAgICAoYnl0ZSkgMHg4YywgKGJ5dGUpIDB4OGQsIChieXRlKSAweDhlLCAoYnl0ZSkgMHg4ZiwgKGJ5dGUpIDB4OTAsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MSwgKGJ5dGUpIDB4OTIsIChieXRlKSAweDkzLCAoYnl0ZSkgMHg5NCwgKGJ5dGUpIDB4OTUsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NiwgKGJ5dGUpIDB4OTcsIChieXRlKSAweDk4LCAoYnl0ZSkgMHg5OSwgKGJ5dGUpIDB4OWEsCisgICAgICAgICAgICAoYnl0ZSkgMHg5YiwgKGJ5dGUpIDB4OWMsIChieXRlKSAweDlkLCAoYnl0ZSkgMHg5ZSwgKGJ5dGUpIDB4OWYsCisgICAgICAgICAgICAoYnl0ZSkgMHhhMCwgKGJ5dGUpIDB4YTEsIChieXRlKSAweGEyLCAoYnl0ZSkgMHhhMywgKGJ5dGUpIDB4YTQsCisgICAgICAgICAgICAoYnl0ZSkgMHhhNSwgKGJ5dGUpIDB4YTYsIChieXRlKSAweGE3LCAoYnl0ZSkgMHhhOCwgKGJ5dGUpIDB4YTksCisgICAgICAgICAgICAoYnl0ZSkgMHhhYSwgKGJ5dGUpIDB4YWIsIChieXRlKSAweGFjLCAoYnl0ZSkgMHhhZCwgKGJ5dGUpIDB4YWUsCisgICAgICAgICAgICAoYnl0ZSkgMHhhZiwgKGJ5dGUpIDB4YjAsIChieXRlKSAweGIxLCAoYnl0ZSkgMHhiMiwgKGJ5dGUpIDB4YjMsCisgICAgICAgICAgICAoYnl0ZSkgMHhiNCwgKGJ5dGUpIDB4YjUsIChieXRlKSAweGI2LCAoYnl0ZSkgMHhiNywgKGJ5dGUpIDB4YjgsCisgICAgICAgICAgICAoYnl0ZSkgMHhiOSwgKGJ5dGUpIDB4YmEsIChieXRlKSAweGJiLCAoYnl0ZSkgMHhiYywgKGJ5dGUpIDB4YmQsCisgICAgICAgICAgICAoYnl0ZSkgMHhiZSwgKGJ5dGUpIDB4YmYsIChieXRlKSAweGMwLCAoYnl0ZSkgMHhjMSwgKGJ5dGUpIDB4YzIsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMywgKGJ5dGUpIDB4YzQsIChieXRlKSAweGM1LCAoYnl0ZSkgMHhjNiwgKGJ5dGUpIDB4YzcsCisgICAgICAgICAgICAoYnl0ZSkgMHhjOCwgKGJ5dGUpIDB4YzksIChieXRlKSAweGNhLCAoYnl0ZSkgMHhjYiwgKGJ5dGUpIDB4Y2MsCisgICAgICAgICAgICAoYnl0ZSkgMHhjZCwgKGJ5dGUpIDB4Y2UsIChieXRlKSAweGNmLCAoYnl0ZSkgMHhkMCwgKGJ5dGUpIDB4ZDEsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMiwgKGJ5dGUpIDB4ZDMsIChieXRlKSAweGQ0LCAoYnl0ZSkgMHhkNSwgKGJ5dGUpIDB4ZDYsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNywgKGJ5dGUpIDB4ZDgsIChieXRlKSAweGQ5LCAoYnl0ZSkgMHhkYSwgKGJ5dGUpIDB4ZGIsCisgICAgICAgICAgICAoYnl0ZSkgMHhkYywgKGJ5dGUpIDB4ZGQsIChieXRlKSAweGRlLCAoYnl0ZSkgMHhkZiwgKGJ5dGUpIDB4ZTAsCisgICAgICAgICAgICAoYnl0ZSkgMHhlMSwgKGJ5dGUpIDB4ZTIsIChieXRlKSAweGUzLCAoYnl0ZSkgMHhlNCwgKGJ5dGUpIDB4ZTUsCisgICAgICAgICAgICAoYnl0ZSkgMHhlNiwgKGJ5dGUpIDB4ZTcsIChieXRlKSAweGU4LCAoYnl0ZSkgMHhlOSwgKGJ5dGUpIDB4ZWEsCisgICAgICAgICAgICAoYnl0ZSkgMHhlYiwgKGJ5dGUpIDB4ZWMsIChieXRlKSAweGVkLCAoYnl0ZSkgMHhlZSwgKGJ5dGUpIDB4ZWYsCisgICAgICAgICAgICAoYnl0ZSkgMHhmMCwgKGJ5dGUpIDB4ZjEsIChieXRlKSAweGYyLCAoYnl0ZSkgMHhmMywgKGJ5dGUpIDB4ZjQsCisgICAgICAgICAgICAoYnl0ZSkgMHhmNSwgKGJ5dGUpIDB4ZjYsIChieXRlKSAweGY3LCAoYnl0ZSkgMHhmOCwgKGJ5dGUpIDB4ZjksCisgICAgICAgICAgICAoYnl0ZSkgMHhmYSwgKGJ5dGUpIDB4ZmIsIChieXRlKSAweGZjLCAoYnl0ZSkgMHhmZCwgKGJ5dGUpIDB4ZmUsCisgICAgICAgICAgICAoYnl0ZSkgMHhmZiwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDMsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MDUsIChieXRlKSAweDA2LCAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4MDgsCisgICAgICAgICAgICAoYnl0ZSkgMHgwOSwgKGJ5dGUpIDB4MGEsIChieXRlKSAweDBiLCAoYnl0ZSkgMHgwYywgKGJ5dGUpIDB4MGQsCisgICAgICAgICAgICAoYnl0ZSkgMHgwZSwgKGJ5dGUpIDB4MGYsIChieXRlKSAweDEwLCAoYnl0ZSkgMHgxMSwgKGJ5dGUpIDB4MTIsCisgICAgICAgICAgICAoYnl0ZSkgMHgxMywgKGJ5dGUpIDB4MTQsIChieXRlKSAweDE1LCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4MTcsCisgICAgICAgICAgICAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4MTksIChieXRlKSAweDFhLCAoYnl0ZSkgMHgxYiwgKGJ5dGUpIDB4MWMsCisgICAgICAgICAgICAoYnl0ZSkgMHgxZCwgKGJ5dGUpIDB4MWUsIChieXRlKSAweDFmLCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4MjEsCisgICAgICAgICAgICAoYnl0ZSkgMHgyMiwgKGJ5dGUpIDB4MjMsIChieXRlKSAweDI0LCAoYnl0ZSkgMHgyNSwgKGJ5dGUpIDB4MjYsCisgICAgICAgICAgICAoYnl0ZSkgMHgyNywgKGJ5dGUpIDB4MjgsIChieXRlKSAweDI5LCAoYnl0ZSkgMHgyYSwgKGJ5dGUpIDB4MmIsCisgICAgICAgICAgICAoYnl0ZSkgMHgyYywgKGJ5dGUpIDB4MmQsIChieXRlKSAweDJlLCAoYnl0ZSkgMHgyZiwgKGJ5dGUpIDB4MzAsCisgICAgICAgICAgICAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4MzIsIChieXRlKSAweDMzLCAoYnl0ZSkgMHgzNCwgKGJ5dGUpIDB4MzUsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4MzcsIChieXRlKSAweDM4LCAoYnl0ZSkgMHgzOSwgKGJ5dGUpIDB4M2EsCisgICAgICAgICAgICAoYnl0ZSkgMHgzYiwgKGJ5dGUpIDB4M2MsIChieXRlKSAweDNkLCAoYnl0ZSkgMHgzZSwgKGJ5dGUpIDB4M2YsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NDEsIChieXRlKSAweDQyLCAoYnl0ZSkgMHg0MywgKGJ5dGUpIDB4NDQsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4NDYsIChieXRlKSAweDQ3LCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4NDksCisgICAgICAgICAgICAoYnl0ZSkgMHg0YSwgKGJ5dGUpIDB4NGIsIChieXRlKSAweDRjLCAoYnl0ZSkgMHg0ZCwgKGJ5dGUpIDB4NGUsCisgICAgICAgICAgICAoYnl0ZSkgMHg0ZiwgKGJ5dGUpIDB4NTAsIChieXRlKSAweDUxLCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4NTMsCisgICAgICAgICAgICAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDU2LCAoYnl0ZSkgMHg1NywgKGJ5dGUpIDB4NTgsCisgICAgICAgICAgICAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4NWEsIChieXRlKSAweDViLCAoYnl0ZSkgMHg1YywgKGJ5dGUpIDB4NWQsCisgICAgICAgICAgICAoYnl0ZSkgMHg1ZSwgKGJ5dGUpIDB4NWYsIChieXRlKSAweDYwLCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4NjIsCisgICAgICAgICAgICAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4NjQsIChieXRlKSAweDY1LCAoYnl0ZSkgMHg2NiwgKGJ5dGUpIDB4NjcsCisgICAgICAgICAgICAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4NjksIChieXRlKSAweDZhLCAoYnl0ZSkgMHg2YiwgKGJ5dGUpIDB4NmMsCisgICAgICAgICAgICAoYnl0ZSkgMHg2ZCwgKGJ5dGUpIDB4NmUsIChieXRlKSAweDZmLCAoYnl0ZSkgMHg3MCwgKGJ5dGUpIDB4NzEsCisgICAgICAgICAgICAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4NzMsIChieXRlKSAweDc0LCAoYnl0ZSkgMHg3NSwgKGJ5dGUpIDB4NzYsCisgICAgICAgICAgICAoYnl0ZSkgMHg3NywgKGJ5dGUpIDB4NzgsIChieXRlKSAweDc5LCAoYnl0ZSkgMHg3YSwgKGJ5dGUpIDB4N2IsCisgICAgICAgICAgICAoYnl0ZSkgMHg3YywgKGJ5dGUpIDB4N2QsIChieXRlKSAweDdlLCAoYnl0ZSkgMHg3ZiwgKGJ5dGUpIDB4ODAsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDgzLCAoYnl0ZSkgMHg4NCwgKGJ5dGUpIDB4ODUsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4ODcsIChieXRlKSAweDg4LCAoYnl0ZSkgMHg4OSwgKGJ5dGUpIDB4OGEsCisgICAgICAgICAgICAoYnl0ZSkgMHg4YiwgKGJ5dGUpIDB4OGMsIChieXRlKSAweDhkLCAoYnl0ZSkgMHg4ZSwgKGJ5dGUpIDB4OGYsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MCwgKGJ5dGUpIDB4OTEsIChieXRlKSAweDkyLCAoYnl0ZSkgMHg5MywgKGJ5dGUpIDB4OTQsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NSwgKGJ5dGUpIDB4OTYsIChieXRlKSAweDk3LCAoYnl0ZSkgMHg5OCwgKGJ5dGUpIDB4OTksCisgICAgICAgICAgICAoYnl0ZSkgMHg5YSwgKGJ5dGUpIDB4OWIsIChieXRlKSAweDljLCAoYnl0ZSkgMHg5ZCwgKGJ5dGUpIDB4OWUsCisgICAgICAgICAgICAoYnl0ZSkgMHg5ZiwgKGJ5dGUpIDB4YTAsIChieXRlKSAweGExLCAoYnl0ZSkgMHhhMiwgKGJ5dGUpIDB4YTMsCisgICAgICAgICAgICAoYnl0ZSkgMHhhNCwgKGJ5dGUpIDB4YTUsIChieXRlKSAweGE2LCAoYnl0ZSkgMHhhNywgKGJ5dGUpIDB4YTgsCisgICAgICAgICAgICAoYnl0ZSkgMHhhOSwgKGJ5dGUpIDB4YWEsIChieXRlKSAweGFiLCAoYnl0ZSkgMHhhYywgKGJ5dGUpIDB4YWQsCisgICAgICAgICAgICAoYnl0ZSkgMHhhZSwgKGJ5dGUpIDB4YWYsIChieXRlKSAweGIwLCAoYnl0ZSkgMHhiMSwgKGJ5dGUpIDB4YjIsCisgICAgICAgICAgICAoYnl0ZSkgMHhiMywgKGJ5dGUpIDB4YjQsIChieXRlKSAweGI1LCAoYnl0ZSkgMHhiNiwgKGJ5dGUpIDB4YjcsCisgICAgICAgICAgICAoYnl0ZSkgMHhiOCwgKGJ5dGUpIDB4YjksIChieXRlKSAweGJhLCAoYnl0ZSkgMHhiYiwgKGJ5dGUpIDB4YmMsCisgICAgICAgICAgICAoYnl0ZSkgMHhiZCwgKGJ5dGUpIDB4YmUsIChieXRlKSAweGJmLCAoYnl0ZSkgMHhjMCwgKGJ5dGUpIDB4YzEsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMiwgKGJ5dGUpIDB4YzMsIChieXRlKSAweGM0LCAoYnl0ZSkgMHhjNSwgKGJ5dGUpIDB4YzYsCisgICAgICAgICAgICAoYnl0ZSkgMHhjNywgKGJ5dGUpIDB4YzgsIChieXRlKSAweGM5LCAoYnl0ZSkgMHhjYSwgKGJ5dGUpIDB4Y2IsCisgICAgICAgICAgICAoYnl0ZSkgMHhjYywgKGJ5dGUpIDB4Y2QsIChieXRlKSAweGNlLCAoYnl0ZSkgMHhjZiwgKGJ5dGUpIDB4ZDAsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMSwgKGJ5dGUpIDB4ZDIsIChieXRlKSAweGQzLCAoYnl0ZSkgMHhkNCwgKGJ5dGUpIDB4ZDUsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNiwgKGJ5dGUpIDB4ZDcsIChieXRlKSAweGQ4LCAoYnl0ZSkgMHhkOSwgKGJ5dGUpIDB4ZGEsCisgICAgICAgICAgICAoYnl0ZSkgMHhkYiwgKGJ5dGUpIDB4ZGMsIChieXRlKSAweGRkLCAoYnl0ZSkgMHhkZSwgKGJ5dGUpIDB4ZGYsCisgICAgICAgICAgICAoYnl0ZSkgMHhlMCwgKGJ5dGUpIDB4ZTEsIChieXRlKSAweGUyLCAoYnl0ZSkgMHhlMywgKGJ5dGUpIDB4ZTQsCisgICAgICAgICAgICAoYnl0ZSkgMHhlNSwgKGJ5dGUpIDB4ZTYsIChieXRlKSAweGU3LCAoYnl0ZSkgMHhlOCwgKGJ5dGUpIDB4ZTksCisgICAgICAgICAgICAoYnl0ZSkgMHhlYSwgKGJ5dGUpIDB4ZWIsIChieXRlKSAweGVjLCAoYnl0ZSkgMHhlZCwgKGJ5dGUpIDB4ZWUsCisgICAgICAgICAgICAoYnl0ZSkgMHhlZiwgKGJ5dGUpIDB4ZjAsIChieXRlKSAweGYxLCAoYnl0ZSkgMHhmMiwgKGJ5dGUpIDB4ZjMsCisgICAgICAgICAgICAoYnl0ZSkgMHhmNCwgKGJ5dGUpIDB4ZjUsIChieXRlKSAweGY2LCAoYnl0ZSkgMHhmNywgKGJ5dGUpIDB4ZjgsCisgICAgICAgICAgICAoYnl0ZSkgMHhmOSwgKGJ5dGUpIDB4ZmEsIChieXRlKSAweGZiLCAoYnl0ZSkgMHhmYywgKGJ5dGUpIDB4ZmQsCisgICAgICAgICAgICAoYnl0ZSkgMHhmZSwgKGJ5dGUpIDB4ZmYsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDIsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MDQsIChieXRlKSAweDA1LCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MDcsCisgICAgICAgICAgICAoYnl0ZSkgMHgwOCwgKGJ5dGUpIDB4MDksIChieXRlKSAweDBhLCAoYnl0ZSkgMHgwYiwgKGJ5dGUpIDB4MGMsCisgICAgICAgICAgICAoYnl0ZSkgMHgwZCwgKGJ5dGUpIDB4MGUsIChieXRlKSAweDBmLCAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4MTEsCisgICAgICAgICAgICAoYnl0ZSkgMHgxMiwgKGJ5dGUpIDB4MTMsIChieXRlKSAweDE0LCAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4MTYsCisgICAgICAgICAgICAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4MTgsIChieXRlKSAweDE5LCAoYnl0ZSkgMHgxYSwgKGJ5dGUpIDB4MWIsCisgICAgICAgICAgICAoYnl0ZSkgMHgxYywgKGJ5dGUpIDB4MWQsIChieXRlKSAweDFlLCAoYnl0ZSkgMHgxZiwgKGJ5dGUpIDB4MjAsCisgICAgICAgICAgICAoYnl0ZSkgMHgyMSwgKGJ5dGUpIDB4MjIsIChieXRlKSAweDIzLCAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4MjUsCisgICAgICAgICAgICAoYnl0ZSkgMHgyNiwgKGJ5dGUpIDB4MjcsIChieXRlKSAweDI4LCAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4MmEsCisgICAgICAgICAgICAoYnl0ZSkgMHgyYiwgKGJ5dGUpIDB4MmMsIChieXRlKSAweDJkLCAoYnl0ZSkgMHgyZSwgKGJ5dGUpIDB4MmYsCisgICAgICAgICAgICAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4MzEsIChieXRlKSAweDMyLCAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4MzQsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4MzYsIChieXRlKSAweDM3LCAoYnl0ZSkgMHgzOCwgKGJ5dGUpIDB4MzksCisgICAgICAgICAgICAoYnl0ZSkgMHgzYSwgKGJ5dGUpIDB4M2IsIChieXRlKSAweDNjLCAoYnl0ZSkgMHgzZCwgKGJ5dGUpIDB4M2UsCisgICAgICAgICAgICAoYnl0ZSkgMHgzZiwgKGJ5dGUpIDB4NDAsIChieXRlKSAweDQxLCAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4NDMsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4NDUsIChieXRlKSAweDQ2LCAoYnl0ZSkgMHg0NywgKGJ5dGUpIDB4NDgsCisgICAgICAgICAgICAoYnl0ZSkgMHg0OSwgKGJ5dGUpIDB4NGEsIChieXRlKSAweDRiLCAoYnl0ZSkgMHg0YywgKGJ5dGUpIDB4NGQsCisgICAgICAgICAgICAoYnl0ZSkgMHg0ZSwgKGJ5dGUpIDB4NGYsIChieXRlKSAweDUwLCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4NTIsCisgICAgICAgICAgICAoYnl0ZSkgMHg1MywgKGJ5dGUpIDB4NTQsIChieXRlKSAweDU1LCAoYnl0ZSkgMHg1NiwgKGJ5dGUpIDB4NTcsCisgICAgICAgICAgICAoYnl0ZSkgMHg1OCwgKGJ5dGUpIDB4NTksIChieXRlKSAweDVhLCAoYnl0ZSkgMHg1YiwgKGJ5dGUpIDB4NWMsCisgICAgICAgICAgICAoYnl0ZSkgMHg1ZCwgKGJ5dGUpIDB4NWUsIChieXRlKSAweDVmLCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4NjEsCisgICAgICAgICAgICAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4NjMsIChieXRlKSAweDY0LCAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4NjYsCisgICAgICAgICAgICAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4NjgsIChieXRlKSAweDY5LCAoYnl0ZSkgMHg2YSwgKGJ5dGUpIDB4NmIsCisgICAgICAgICAgICAoYnl0ZSkgMHg2YywgKGJ5dGUpIDB4NmQsIChieXRlKSAweDZlLCAoYnl0ZSkgMHg2ZiwgKGJ5dGUpIDB4NzAsCisgICAgICAgICAgICAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4NzIsIChieXRlKSAweDczLCAoYnl0ZSkgMHg3NCwgKGJ5dGUpIDB4NzUsCisgICAgICAgICAgICAoYnl0ZSkgMHg3NiwgKGJ5dGUpIDB4NzcsIChieXRlKSAweDc4LCAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4N2EsCisgICAgICAgICAgICAoYnl0ZSkgMHg3YiwgKGJ5dGUpIDB4N2MsIChieXRlKSAweDdkLCAoYnl0ZSkgMHg3ZSwgKGJ5dGUpIDB4N2YsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDgyLCAoYnl0ZSkgMHg4MywgKGJ5dGUpIDB4ODQsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4ODYsIChieXRlKSAweDg3LCAoYnl0ZSkgMHg4OCwgKGJ5dGUpIDB4ODksCisgICAgICAgICAgICAoYnl0ZSkgMHg4YSwgKGJ5dGUpIDB4OGIsIChieXRlKSAweDhjLCAoYnl0ZSkgMHg4ZCwgKGJ5dGUpIDB4OGUsCisgICAgICAgICAgICAoYnl0ZSkgMHg4ZiwgKGJ5dGUpIDB4OTAsIChieXRlKSAweDkxLCAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4OTMsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NCwgKGJ5dGUpIDB4OTUsIChieXRlKSAweDk2LCAoYnl0ZSkgMHg5NywgKGJ5dGUpIDB4OTgsCisgICAgICAgICAgICAoYnl0ZSkgMHg5OSwgKGJ5dGUpIDB4OWEsIChieXRlKSAweDliLCAoYnl0ZSkgMHg5YywgKGJ5dGUpIDB4OWQsCisgICAgICAgICAgICAoYnl0ZSkgMHg5ZSwgKGJ5dGUpIDB4OWYsIChieXRlKSAweGEwLCAoYnl0ZSkgMHhhMSwgKGJ5dGUpIDB4YTIsCisgICAgICAgICAgICAoYnl0ZSkgMHhhMywgKGJ5dGUpIDB4YTQsIChieXRlKSAweGE1LCAoYnl0ZSkgMHhhNiwgKGJ5dGUpIDB4YTcsCisgICAgICAgICAgICAoYnl0ZSkgMHhhOCwgKGJ5dGUpIDB4YTksIChieXRlKSAweGFhLCAoYnl0ZSkgMHhhYiwgKGJ5dGUpIDB4YWMsCisgICAgICAgICAgICAoYnl0ZSkgMHhhZCwgKGJ5dGUpIDB4YWUsIChieXRlKSAweGFmLCAoYnl0ZSkgMHhiMCwgKGJ5dGUpIDB4YjEsCisgICAgICAgICAgICAoYnl0ZSkgMHhiMiwgKGJ5dGUpIDB4YjMsIChieXRlKSAweGI0LCAoYnl0ZSkgMHhiNSwgKGJ5dGUpIDB4YjYsCisgICAgICAgICAgICAoYnl0ZSkgMHhiNywgKGJ5dGUpIDB4YjgsIChieXRlKSAweGI5LCAoYnl0ZSkgMHhiYSwgKGJ5dGUpIDB4YmIsCisgICAgICAgICAgICAoYnl0ZSkgMHhiYywgKGJ5dGUpIDB4YmQsIChieXRlKSAweGJlLCAoYnl0ZSkgMHhiZiwgKGJ5dGUpIDB4YzAsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMSwgKGJ5dGUpIDB4YzIsIChieXRlKSAweGMzLCAoYnl0ZSkgMHhjNCwgKGJ5dGUpIDB4YzUsCisgICAgICAgICAgICAoYnl0ZSkgMHhjNiwgKGJ5dGUpIDB4YzcsIChieXRlKSAweGM4LCAoYnl0ZSkgMHhjOSwgKGJ5dGUpIDB4Y2EsCisgICAgICAgICAgICAoYnl0ZSkgMHhjYiwgKGJ5dGUpIDB4Y2MsIChieXRlKSAweGNkLCAoYnl0ZSkgMHhjZSwgKGJ5dGUpIDB4Y2YsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMCwgKGJ5dGUpIDB4ZDEsIChieXRlKSAweGQyLCAoYnl0ZSkgMHhkMywgKGJ5dGUpIDB4ZDQsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNSwgKGJ5dGUpIDB4ZDYsIChieXRlKSAweGQ3LCAoYnl0ZSkgMHhkOCwgKGJ5dGUpIDB4ZDksCisgICAgICAgICAgICAoYnl0ZSkgMHhkYSwgKGJ5dGUpIDB4ZGIsIChieXRlKSAweGRjLCAoYnl0ZSkgMHhkZCwgKGJ5dGUpIDB4ZGUsCisgICAgICAgICAgICAoYnl0ZSkgMHhkZiwgKGJ5dGUpIDB4ZTAsIChieXRlKSAweGUxLCAoYnl0ZSkgMHhlMiwgKGJ5dGUpIDB4ZTMsCisgICAgICAgICAgICAoYnl0ZSkgMHhlNCwgKGJ5dGUpIDB4ZTUsIChieXRlKSAweGU2LCAoYnl0ZSkgMHhlNywgKGJ5dGUpIDB4ZTgsCisgICAgICAgICAgICAoYnl0ZSkgMHhlOSwgKGJ5dGUpIDB4ZWEsIChieXRlKSAweGViLCAoYnl0ZSkgMHhlYywgKGJ5dGUpIDB4ZWQsCisgICAgICAgICAgICAoYnl0ZSkgMHhlZSwgKGJ5dGUpIDB4ZWYsIChieXRlKSAweGYwLCAoYnl0ZSkgMHhmMSwgKGJ5dGUpIDB4ZjIsCisgICAgICAgICAgICAoYnl0ZSkgMHhmMywgKGJ5dGUpIDB4ZjQsIChieXRlKSAweGY1LCAoYnl0ZSkgMHhmNiwgKGJ5dGUpIDB4ZjcsCisgICAgICAgICAgICAoYnl0ZSkgMHhmOCwgKGJ5dGUpIDB4ZjksIChieXRlKSAweGZhLCAoYnl0ZSkgMHhmYiwgKGJ5dGUpIDB4ZmMsCisgICAgICAgICAgICAoYnl0ZSkgMHhmZCwgKGJ5dGUpIDB4ZmUsIChieXRlKSAweGZmIH07CisKKyAgICAvKioKKyAgICAgKiAidmFsaWQiIGVuY29kaW5nIGZvciBESCAtIG5vIGFsZyBwYXJhbXMKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gZGhFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb05QID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDA0LCAoYnl0ZSkgMHgxMywgKGJ5dGUpIDB4MzAsCisgICAgICAgICAgICAoYnl0ZSkgMHgwZCwgKGJ5dGUpIDB4MDYsIChieXRlKSAweDA5LCAoYnl0ZSkgMHgyYSwgKGJ5dGUpIDB4ODYsCisgICAgICAgICAgICAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4ODYsIChieXRlKSAweGY3LCAoYnl0ZSkgMHgwZCwgKGJ5dGUpIDB4MDEsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MDEsIChieXRlKSAweDA1LCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDQsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDQsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDEsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDMsIChieXRlKSAweDA0LCAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4MDYsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4MDgsIChieXRlKSAweDA5LCAoYnl0ZSkgMHgwYSwgKGJ5dGUpIDB4MGIsCisgICAgICAgICAgICAoYnl0ZSkgMHgwYywgKGJ5dGUpIDB4MGQsIChieXRlKSAweDBlLCAoYnl0ZSkgMHgwZiwgKGJ5dGUpIDB4MTAsCisgICAgICAgICAgICAoYnl0ZSkgMHgxMSwgKGJ5dGUpIDB4MTIsIChieXRlKSAweDEzLCAoYnl0ZSkgMHgxNCwgKGJ5dGUpIDB4MTUsCisgICAgICAgICAgICAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4MTcsIChieXRlKSAweDE4LCAoYnl0ZSkgMHgxOSwgKGJ5dGUpIDB4MWEsCisgICAgICAgICAgICAoYnl0ZSkgMHgxYiwgKGJ5dGUpIDB4MWMsIChieXRlKSAweDFkLCAoYnl0ZSkgMHgxZSwgKGJ5dGUpIDB4MWYsCisgICAgICAgICAgICAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4MjEsIChieXRlKSAweDIyLCAoYnl0ZSkgMHgyMywgKGJ5dGUpIDB4MjQsCisgICAgICAgICAgICAoYnl0ZSkgMHgyNSwgKGJ5dGUpIDB4MjYsIChieXRlKSAweDI3LCAoYnl0ZSkgMHgyOCwgKGJ5dGUpIDB4MjksCisgICAgICAgICAgICAoYnl0ZSkgMHgyYSwgKGJ5dGUpIDB4MmIsIChieXRlKSAweDJjLCAoYnl0ZSkgMHgyZCwgKGJ5dGUpIDB4MmUsCisgICAgICAgICAgICAoYnl0ZSkgMHgyZiwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDMxLCAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4MzMsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNCwgKGJ5dGUpIDB4MzUsIChieXRlKSAweDM2LCAoYnl0ZSkgMHgzNywgKGJ5dGUpIDB4MzgsCisgICAgICAgICAgICAoYnl0ZSkgMHgzOSwgKGJ5dGUpIDB4M2EsIChieXRlKSAweDNiLCAoYnl0ZSkgMHgzYywgKGJ5dGUpIDB4M2QsCisgICAgICAgICAgICAoYnl0ZSkgMHgzZSwgKGJ5dGUpIDB4M2YsIChieXRlKSAweDQwLCAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4NDIsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MywgKGJ5dGUpIDB4NDQsIChieXRlKSAweDQ1LCAoYnl0ZSkgMHg0NiwgKGJ5dGUpIDB4NDcsCisgICAgICAgICAgICAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4NDksIChieXRlKSAweDRhLCAoYnl0ZSkgMHg0YiwgKGJ5dGUpIDB4NGMsCisgICAgICAgICAgICAoYnl0ZSkgMHg0ZCwgKGJ5dGUpIDB4NGUsIChieXRlKSAweDRmLCAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NTEsCisgICAgICAgICAgICAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4NTMsIChieXRlKSAweDU0LCAoYnl0ZSkgMHg1NSwgKGJ5dGUpIDB4NTYsCisgICAgICAgICAgICAoYnl0ZSkgMHg1NywgKGJ5dGUpIDB4NTgsIChieXRlKSAweDU5LCAoYnl0ZSkgMHg1YSwgKGJ5dGUpIDB4NWIsCisgICAgICAgICAgICAoYnl0ZSkgMHg1YywgKGJ5dGUpIDB4NWQsIChieXRlKSAweDVlLCAoYnl0ZSkgMHg1ZiwgKGJ5dGUpIDB4NjAsCisgICAgICAgICAgICAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4NjIsIChieXRlKSAweDYzLCAoYnl0ZSkgMHg2NCwgKGJ5dGUpIDB4NjUsCisgICAgICAgICAgICAoYnl0ZSkgMHg2NiwgKGJ5dGUpIDB4NjcsIChieXRlKSAweDY4LCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4NmEsCisgICAgICAgICAgICAoYnl0ZSkgMHg2YiwgKGJ5dGUpIDB4NmMsIChieXRlKSAweDZkLCAoYnl0ZSkgMHg2ZSwgKGJ5dGUpIDB4NmYsCisgICAgICAgICAgICAoYnl0ZSkgMHg3MCwgKGJ5dGUpIDB4NzEsIChieXRlKSAweDcyLCAoYnl0ZSkgMHg3MywgKGJ5dGUpIDB4NzQsCisgICAgICAgICAgICAoYnl0ZSkgMHg3NSwgKGJ5dGUpIDB4NzYsIChieXRlKSAweDc3LCAoYnl0ZSkgMHg3OCwgKGJ5dGUpIDB4NzksCisgICAgICAgICAgICAoYnl0ZSkgMHg3YSwgKGJ5dGUpIDB4N2IsIChieXRlKSAweDdjLCAoYnl0ZSkgMHg3ZCwgKGJ5dGUpIDB4N2UsCisgICAgICAgICAgICAoYnl0ZSkgMHg3ZiwgKGJ5dGUpIDB4ODAsIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4ODMsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NCwgKGJ5dGUpIDB4ODUsIChieXRlKSAweDg2LCAoYnl0ZSkgMHg4NywgKGJ5dGUpIDB4ODgsCisgICAgICAgICAgICAoYnl0ZSkgMHg4OSwgKGJ5dGUpIDB4OGEsIChieXRlKSAweDhiLCAoYnl0ZSkgMHg4YywgKGJ5dGUpIDB4OGQsCisgICAgICAgICAgICAoYnl0ZSkgMHg4ZSwgKGJ5dGUpIDB4OGYsIChieXRlKSAweDkwLCAoYnl0ZSkgMHg5MSwgKGJ5dGUpIDB4OTIsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MywgKGJ5dGUpIDB4OTQsIChieXRlKSAweDk1LCAoYnl0ZSkgMHg5NiwgKGJ5dGUpIDB4OTcsCisgICAgICAgICAgICAoYnl0ZSkgMHg5OCwgKGJ5dGUpIDB4OTksIChieXRlKSAweDlhLCAoYnl0ZSkgMHg5YiwgKGJ5dGUpIDB4OWMsCisgICAgICAgICAgICAoYnl0ZSkgMHg5ZCwgKGJ5dGUpIDB4OWUsIChieXRlKSAweDlmLCAoYnl0ZSkgMHhhMCwgKGJ5dGUpIDB4YTEsCisgICAgICAgICAgICAoYnl0ZSkgMHhhMiwgKGJ5dGUpIDB4YTMsIChieXRlKSAweGE0LCAoYnl0ZSkgMHhhNSwgKGJ5dGUpIDB4YTYsCisgICAgICAgICAgICAoYnl0ZSkgMHhhNywgKGJ5dGUpIDB4YTgsIChieXRlKSAweGE5LCAoYnl0ZSkgMHhhYSwgKGJ5dGUpIDB4YWIsCisgICAgICAgICAgICAoYnl0ZSkgMHhhYywgKGJ5dGUpIDB4YWQsIChieXRlKSAweGFlLCAoYnl0ZSkgMHhhZiwgKGJ5dGUpIDB4YjAsCisgICAgICAgICAgICAoYnl0ZSkgMHhiMSwgKGJ5dGUpIDB4YjIsIChieXRlKSAweGIzLCAoYnl0ZSkgMHhiNCwgKGJ5dGUpIDB4YjUsCisgICAgICAgICAgICAoYnl0ZSkgMHhiNiwgKGJ5dGUpIDB4YjcsIChieXRlKSAweGI4LCAoYnl0ZSkgMHhiOSwgKGJ5dGUpIDB4YmEsCisgICAgICAgICAgICAoYnl0ZSkgMHhiYiwgKGJ5dGUpIDB4YmMsIChieXRlKSAweGJkLCAoYnl0ZSkgMHhiZSwgKGJ5dGUpIDB4YmYsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMCwgKGJ5dGUpIDB4YzEsIChieXRlKSAweGMyLCAoYnl0ZSkgMHhjMywgKGJ5dGUpIDB4YzQsCisgICAgICAgICAgICAoYnl0ZSkgMHhjNSwgKGJ5dGUpIDB4YzYsIChieXRlKSAweGM3LCAoYnl0ZSkgMHhjOCwgKGJ5dGUpIDB4YzksCisgICAgICAgICAgICAoYnl0ZSkgMHhjYSwgKGJ5dGUpIDB4Y2IsIChieXRlKSAweGNjLCAoYnl0ZSkgMHhjZCwgKGJ5dGUpIDB4Y2UsCisgICAgICAgICAgICAoYnl0ZSkgMHhjZiwgKGJ5dGUpIDB4ZDAsIChieXRlKSAweGQxLCAoYnl0ZSkgMHhkMiwgKGJ5dGUpIDB4ZDMsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNCwgKGJ5dGUpIDB4ZDUsIChieXRlKSAweGQ2LCAoYnl0ZSkgMHhkNywgKGJ5dGUpIDB4ZDgsCisgICAgICAgICAgICAoYnl0ZSkgMHhkOSwgKGJ5dGUpIDB4ZGEsIChieXRlKSAweGRiLCAoYnl0ZSkgMHhkYywgKGJ5dGUpIDB4ZGQsCisgICAgICAgICAgICAoYnl0ZSkgMHhkZSwgKGJ5dGUpIDB4ZGYsIChieXRlKSAweGUwLCAoYnl0ZSkgMHhlMSwgKGJ5dGUpIDB4ZTIsCisgICAgICAgICAgICAoYnl0ZSkgMHhlMywgKGJ5dGUpIDB4ZTQsIChieXRlKSAweGU1LCAoYnl0ZSkgMHhlNiwgKGJ5dGUpIDB4ZTcsCisgICAgICAgICAgICAoYnl0ZSkgMHhlOCwgKGJ5dGUpIDB4ZTksIChieXRlKSAweGVhLCAoYnl0ZSkgMHhlYiwgKGJ5dGUpIDB4ZWMsCisgICAgICAgICAgICAoYnl0ZSkgMHhlZCwgKGJ5dGUpIDB4ZWUsIChieXRlKSAweGVmLCAoYnl0ZSkgMHhmMCwgKGJ5dGUpIDB4ZjEsCisgICAgICAgICAgICAoYnl0ZSkgMHhmMiwgKGJ5dGUpIDB4ZjMsIChieXRlKSAweGY0LCAoYnl0ZSkgMHhmNSwgKGJ5dGUpIDB4ZjYsCisgICAgICAgICAgICAoYnl0ZSkgMHhmNywgKGJ5dGUpIDB4ZjgsIChieXRlKSAweGY5LCAoYnl0ZSkgMHhmYSwgKGJ5dGUpIDB4ZmIsCisgICAgICAgICAgICAoYnl0ZSkgMHhmYywgKGJ5dGUpIDB4ZmQsIChieXRlKSAweGZlLCAoYnl0ZSkgMHhmZiwgKGJ5dGUpIDB4MDAsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDAzLCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MDUsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MDcsIChieXRlKSAweDA4LCAoYnl0ZSkgMHgwOSwgKGJ5dGUpIDB4MGEsCisgICAgICAgICAgICAoYnl0ZSkgMHgwYiwgKGJ5dGUpIDB4MGMsIChieXRlKSAweDBkLCAoYnl0ZSkgMHgwZSwgKGJ5dGUpIDB4MGYsCisgICAgICAgICAgICAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4MTEsIChieXRlKSAweDEyLCAoYnl0ZSkgMHgxMywgKGJ5dGUpIDB4MTQsCisgICAgICAgICAgICAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4MTYsIChieXRlKSAweDE3LCAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4MTksCisgICAgICAgICAgICAoYnl0ZSkgMHgxYSwgKGJ5dGUpIDB4MWIsIChieXRlKSAweDFjLCAoYnl0ZSkgMHgxZCwgKGJ5dGUpIDB4MWUsCisgICAgICAgICAgICAoYnl0ZSkgMHgxZiwgKGJ5dGUpIDB4MjAsIChieXRlKSAweDIxLCAoYnl0ZSkgMHgyMiwgKGJ5dGUpIDB4MjMsCisgICAgICAgICAgICAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4MjUsIChieXRlKSAweDI2LCAoYnl0ZSkgMHgyNywgKGJ5dGUpIDB4MjgsCisgICAgICAgICAgICAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4MmEsIChieXRlKSAweDJiLCAoYnl0ZSkgMHgyYywgKGJ5dGUpIDB4MmQsCisgICAgICAgICAgICAoYnl0ZSkgMHgyZSwgKGJ5dGUpIDB4MmYsIChieXRlKSAweDMwLCAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4MzIsCisgICAgICAgICAgICAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4MzQsIChieXRlKSAweDM1LCAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4MzcsCisgICAgICAgICAgICAoYnl0ZSkgMHgzOCwgKGJ5dGUpIDB4MzksIChieXRlKSAweDNhLCAoYnl0ZSkgMHgzYiwgKGJ5dGUpIDB4M2MsCisgICAgICAgICAgICAoYnl0ZSkgMHgzZCwgKGJ5dGUpIDB4M2UsIChieXRlKSAweDNmLCAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NDEsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4NDMsIChieXRlKSAweDQ0LCAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4NDYsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NywgKGJ5dGUpIDB4NDgsIChieXRlKSAweDQ5LCAoYnl0ZSkgMHg0YSwgKGJ5dGUpIDB4NGIsCisgICAgICAgICAgICAoYnl0ZSkgMHg0YywgKGJ5dGUpIDB4NGQsIChieXRlKSAweDRlLCAoYnl0ZSkgMHg0ZiwgKGJ5dGUpIDB4NTAsCisgICAgICAgICAgICAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4NTIsIChieXRlKSAweDUzLCAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4NTUsCisgICAgICAgICAgICAoYnl0ZSkgMHg1NiwgKGJ5dGUpIDB4NTcsIChieXRlKSAweDU4LCAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4NWEsCisgICAgICAgICAgICAoYnl0ZSkgMHg1YiwgKGJ5dGUpIDB4NWMsIChieXRlKSAweDVkLCAoYnl0ZSkgMHg1ZSwgKGJ5dGUpIDB4NWYsCisgICAgICAgICAgICAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4NjEsIChieXRlKSAweDYyLCAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4NjQsCisgICAgICAgICAgICAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4NjYsIChieXRlKSAweDY3LCAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4NjksCisgICAgICAgICAgICAoYnl0ZSkgMHg2YSwgKGJ5dGUpIDB4NmIsIChieXRlKSAweDZjLCAoYnl0ZSkgMHg2ZCwgKGJ5dGUpIDB4NmUsCisgICAgICAgICAgICAoYnl0ZSkgMHg2ZiwgKGJ5dGUpIDB4NzAsIChieXRlKSAweDcxLCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4NzMsCisgICAgICAgICAgICAoYnl0ZSkgMHg3NCwgKGJ5dGUpIDB4NzUsIChieXRlKSAweDc2LCAoYnl0ZSkgMHg3NywgKGJ5dGUpIDB4NzgsCisgICAgICAgICAgICAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4N2EsIChieXRlKSAweDdiLCAoYnl0ZSkgMHg3YywgKGJ5dGUpIDB4N2QsCisgICAgICAgICAgICAoYnl0ZSkgMHg3ZSwgKGJ5dGUpIDB4N2YsIChieXRlKSAweDgwLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODIsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MywgKGJ5dGUpIDB4ODQsIChieXRlKSAweDg1LCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4ODcsCisgICAgICAgICAgICAoYnl0ZSkgMHg4OCwgKGJ5dGUpIDB4ODksIChieXRlKSAweDhhLCAoYnl0ZSkgMHg4YiwgKGJ5dGUpIDB4OGMsCisgICAgICAgICAgICAoYnl0ZSkgMHg4ZCwgKGJ5dGUpIDB4OGUsIChieXRlKSAweDhmLCAoYnl0ZSkgMHg5MCwgKGJ5dGUpIDB4OTEsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4OTMsIChieXRlKSAweDk0LCAoYnl0ZSkgMHg5NSwgKGJ5dGUpIDB4OTYsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NywgKGJ5dGUpIDB4OTgsIChieXRlKSAweDk5LCAoYnl0ZSkgMHg5YSwgKGJ5dGUpIDB4OWIsCisgICAgICAgICAgICAoYnl0ZSkgMHg5YywgKGJ5dGUpIDB4OWQsIChieXRlKSAweDllLCAoYnl0ZSkgMHg5ZiwgKGJ5dGUpIDB4YTAsCisgICAgICAgICAgICAoYnl0ZSkgMHhhMSwgKGJ5dGUpIDB4YTIsIChieXRlKSAweGEzLCAoYnl0ZSkgMHhhNCwgKGJ5dGUpIDB4YTUsCisgICAgICAgICAgICAoYnl0ZSkgMHhhNiwgKGJ5dGUpIDB4YTcsIChieXRlKSAweGE4LCAoYnl0ZSkgMHhhOSwgKGJ5dGUpIDB4YWEsCisgICAgICAgICAgICAoYnl0ZSkgMHhhYiwgKGJ5dGUpIDB4YWMsIChieXRlKSAweGFkLCAoYnl0ZSkgMHhhZSwgKGJ5dGUpIDB4YWYsCisgICAgICAgICAgICAoYnl0ZSkgMHhiMCwgKGJ5dGUpIDB4YjEsIChieXRlKSAweGIyLCAoYnl0ZSkgMHhiMywgKGJ5dGUpIDB4YjQsCisgICAgICAgICAgICAoYnl0ZSkgMHhiNSwgKGJ5dGUpIDB4YjYsIChieXRlKSAweGI3LCAoYnl0ZSkgMHhiOCwgKGJ5dGUpIDB4YjksCisgICAgICAgICAgICAoYnl0ZSkgMHhiYSwgKGJ5dGUpIDB4YmIsIChieXRlKSAweGJjLCAoYnl0ZSkgMHhiZCwgKGJ5dGUpIDB4YmUsCisgICAgICAgICAgICAoYnl0ZSkgMHhiZiwgKGJ5dGUpIDB4YzAsIChieXRlKSAweGMxLCAoYnl0ZSkgMHhjMiwgKGJ5dGUpIDB4YzMsCisgICAgICAgICAgICAoYnl0ZSkgMHhjNCwgKGJ5dGUpIDB4YzUsIChieXRlKSAweGM2LCAoYnl0ZSkgMHhjNywgKGJ5dGUpIDB4YzgsCisgICAgICAgICAgICAoYnl0ZSkgMHhjOSwgKGJ5dGUpIDB4Y2EsIChieXRlKSAweGNiLCAoYnl0ZSkgMHhjYywgKGJ5dGUpIDB4Y2QsCisgICAgICAgICAgICAoYnl0ZSkgMHhjZSwgKGJ5dGUpIDB4Y2YsIChieXRlKSAweGQwLCAoYnl0ZSkgMHhkMSwgKGJ5dGUpIDB4ZDIsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMywgKGJ5dGUpIDB4ZDQsIChieXRlKSAweGQ1LCAoYnl0ZSkgMHhkNiwgKGJ5dGUpIDB4ZDcsCisgICAgICAgICAgICAoYnl0ZSkgMHhkOCwgKGJ5dGUpIDB4ZDksIChieXRlKSAweGRhLCAoYnl0ZSkgMHhkYiwgKGJ5dGUpIDB4ZGMsCisgICAgICAgICAgICAoYnl0ZSkgMHhkZCwgKGJ5dGUpIDB4ZGUsIChieXRlKSAweGRmLCAoYnl0ZSkgMHhlMCwgKGJ5dGUpIDB4ZTEsCisgICAgICAgICAgICAoYnl0ZSkgMHhlMiwgKGJ5dGUpIDB4ZTMsIChieXRlKSAweGU0LCAoYnl0ZSkgMHhlNSwgKGJ5dGUpIDB4ZTYsCisgICAgICAgICAgICAoYnl0ZSkgMHhlNywgKGJ5dGUpIDB4ZTgsIChieXRlKSAweGU5LCAoYnl0ZSkgMHhlYSwgKGJ5dGUpIDB4ZWIsCisgICAgICAgICAgICAoYnl0ZSkgMHhlYywgKGJ5dGUpIDB4ZWQsIChieXRlKSAweGVlLCAoYnl0ZSkgMHhlZiwgKGJ5dGUpIDB4ZjAsCisgICAgICAgICAgICAoYnl0ZSkgMHhmMSwgKGJ5dGUpIDB4ZjIsIChieXRlKSAweGYzLCAoYnl0ZSkgMHhmNCwgKGJ5dGUpIDB4ZjUsCisgICAgICAgICAgICAoYnl0ZSkgMHhmNiwgKGJ5dGUpIDB4ZjcsIChieXRlKSAweGY4LCAoYnl0ZSkgMHhmOSwgKGJ5dGUpIDB4ZmEsCisgICAgICAgICAgICAoYnl0ZSkgMHhmYiwgKGJ5dGUpIDB4ZmMsIChieXRlKSAweGZkLCAoYnl0ZSkgMHhmZSwgKGJ5dGUpIDB4ZmYsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MDQsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4MDYsIChieXRlKSAweDA3LCAoYnl0ZSkgMHgwOCwgKGJ5dGUpIDB4MDksCisgICAgICAgICAgICAoYnl0ZSkgMHgwYSwgKGJ5dGUpIDB4MGIsIChieXRlKSAweDBjLCAoYnl0ZSkgMHgwZCwgKGJ5dGUpIDB4MGUsCisgICAgICAgICAgICAoYnl0ZSkgMHgwZiwgKGJ5dGUpIDB4MTAsIChieXRlKSAweDExLCAoYnl0ZSkgMHgxMiwgKGJ5dGUpIDB4MTMsCisgICAgICAgICAgICAoYnl0ZSkgMHgxNCwgKGJ5dGUpIDB4MTUsIChieXRlKSAweDE2LCAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4MTgsCisgICAgICAgICAgICAoYnl0ZSkgMHgxOSwgKGJ5dGUpIDB4MWEsIChieXRlKSAweDFiLCAoYnl0ZSkgMHgxYywgKGJ5dGUpIDB4MWQsCisgICAgICAgICAgICAoYnl0ZSkgMHgxZSwgKGJ5dGUpIDB4MWYsIChieXRlKSAweDIwLCAoYnl0ZSkgMHgyMSwgKGJ5dGUpIDB4MjIsCisgICAgICAgICAgICAoYnl0ZSkgMHgyMywgKGJ5dGUpIDB4MjQsIChieXRlKSAweDI1LCAoYnl0ZSkgMHgyNiwgKGJ5dGUpIDB4MjcsCisgICAgICAgICAgICAoYnl0ZSkgMHgyOCwgKGJ5dGUpIDB4MjksIChieXRlKSAweDJhLCAoYnl0ZSkgMHgyYiwgKGJ5dGUpIDB4MmMsCisgICAgICAgICAgICAoYnl0ZSkgMHgyZCwgKGJ5dGUpIDB4MmUsIChieXRlKSAweDJmLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4MzEsCisgICAgICAgICAgICAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4MzMsIChieXRlKSAweDM0LCAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4MzYsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNywgKGJ5dGUpIDB4MzgsIChieXRlKSAweDM5LCAoYnl0ZSkgMHgzYSwgKGJ5dGUpIDB4M2IsCisgICAgICAgICAgICAoYnl0ZSkgMHgzYywgKGJ5dGUpIDB4M2QsIChieXRlKSAweDNlLCAoYnl0ZSkgMHgzZiwgKGJ5dGUpIDB4NDAsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4NDIsIChieXRlKSAweDQzLCAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4NDUsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NiwgKGJ5dGUpIDB4NDcsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg0OSwgKGJ5dGUpIDB4NGEsCisgICAgICAgICAgICAoYnl0ZSkgMHg0YiwgKGJ5dGUpIDB4NGMsIChieXRlKSAweDRkLCAoYnl0ZSkgMHg0ZSwgKGJ5dGUpIDB4NGYsCisgICAgICAgICAgICAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4NTEsIChieXRlKSAweDUyLCAoYnl0ZSkgMHg1MywgKGJ5dGUpIDB4NTQsCisgICAgICAgICAgICAoYnl0ZSkgMHg1NSwgKGJ5dGUpIDB4NTYsIChieXRlKSAweDU3LCAoYnl0ZSkgMHg1OCwgKGJ5dGUpIDB4NTksCisgICAgICAgICAgICAoYnl0ZSkgMHg1YSwgKGJ5dGUpIDB4NWIsIChieXRlKSAweDVjLCAoYnl0ZSkgMHg1ZCwgKGJ5dGUpIDB4NWUsCisgICAgICAgICAgICAoYnl0ZSkgMHg1ZiwgKGJ5dGUpIDB4NjAsIChieXRlKSAweDYxLCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4NjMsCisgICAgICAgICAgICAoYnl0ZSkgMHg2NCwgKGJ5dGUpIDB4NjUsIChieXRlKSAweDY2LCAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4NjgsCisgICAgICAgICAgICAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4NmEsIChieXRlKSAweDZiLCAoYnl0ZSkgMHg2YywgKGJ5dGUpIDB4NmQsCisgICAgICAgICAgICAoYnl0ZSkgMHg2ZSwgKGJ5dGUpIDB4NmYsIChieXRlKSAweDcwLCAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4NzIsCisgICAgICAgICAgICAoYnl0ZSkgMHg3MywgKGJ5dGUpIDB4NzQsIChieXRlKSAweDc1LCAoYnl0ZSkgMHg3NiwgKGJ5dGUpIDB4NzcsCisgICAgICAgICAgICAoYnl0ZSkgMHg3OCwgKGJ5dGUpIDB4NzksIChieXRlKSAweDdhLCAoYnl0ZSkgMHg3YiwgKGJ5dGUpIDB4N2MsCisgICAgICAgICAgICAoYnl0ZSkgMHg3ZCwgKGJ5dGUpIDB4N2UsIChieXRlKSAweDdmLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4ODEsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4ODMsIChieXRlKSAweDg0LCAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4ODYsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NywgKGJ5dGUpIDB4ODgsIChieXRlKSAweDg5LCAoYnl0ZSkgMHg4YSwgKGJ5dGUpIDB4OGIsCisgICAgICAgICAgICAoYnl0ZSkgMHg4YywgKGJ5dGUpIDB4OGQsIChieXRlKSAweDhlLCAoYnl0ZSkgMHg4ZiwgKGJ5dGUpIDB4OTAsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MSwgKGJ5dGUpIDB4OTIsIChieXRlKSAweDkzLCAoYnl0ZSkgMHg5NCwgKGJ5dGUpIDB4OTUsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NiwgKGJ5dGUpIDB4OTcsIChieXRlKSAweDk4LCAoYnl0ZSkgMHg5OSwgKGJ5dGUpIDB4OWEsCisgICAgICAgICAgICAoYnl0ZSkgMHg5YiwgKGJ5dGUpIDB4OWMsIChieXRlKSAweDlkLCAoYnl0ZSkgMHg5ZSwgKGJ5dGUpIDB4OWYsCisgICAgICAgICAgICAoYnl0ZSkgMHhhMCwgKGJ5dGUpIDB4YTEsIChieXRlKSAweGEyLCAoYnl0ZSkgMHhhMywgKGJ5dGUpIDB4YTQsCisgICAgICAgICAgICAoYnl0ZSkgMHhhNSwgKGJ5dGUpIDB4YTYsIChieXRlKSAweGE3LCAoYnl0ZSkgMHhhOCwgKGJ5dGUpIDB4YTksCisgICAgICAgICAgICAoYnl0ZSkgMHhhYSwgKGJ5dGUpIDB4YWIsIChieXRlKSAweGFjLCAoYnl0ZSkgMHhhZCwgKGJ5dGUpIDB4YWUsCisgICAgICAgICAgICAoYnl0ZSkgMHhhZiwgKGJ5dGUpIDB4YjAsIChieXRlKSAweGIxLCAoYnl0ZSkgMHhiMiwgKGJ5dGUpIDB4YjMsCisgICAgICAgICAgICAoYnl0ZSkgMHhiNCwgKGJ5dGUpIDB4YjUsIChieXRlKSAweGI2LCAoYnl0ZSkgMHhiNywgKGJ5dGUpIDB4YjgsCisgICAgICAgICAgICAoYnl0ZSkgMHhiOSwgKGJ5dGUpIDB4YmEsIChieXRlKSAweGJiLCAoYnl0ZSkgMHhiYywgKGJ5dGUpIDB4YmQsCisgICAgICAgICAgICAoYnl0ZSkgMHhiZSwgKGJ5dGUpIDB4YmYsIChieXRlKSAweGMwLCAoYnl0ZSkgMHhjMSwgKGJ5dGUpIDB4YzIsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMywgKGJ5dGUpIDB4YzQsIChieXRlKSAweGM1LCAoYnl0ZSkgMHhjNiwgKGJ5dGUpIDB4YzcsCisgICAgICAgICAgICAoYnl0ZSkgMHhjOCwgKGJ5dGUpIDB4YzksIChieXRlKSAweGNhLCAoYnl0ZSkgMHhjYiwgKGJ5dGUpIDB4Y2MsCisgICAgICAgICAgICAoYnl0ZSkgMHhjZCwgKGJ5dGUpIDB4Y2UsIChieXRlKSAweGNmLCAoYnl0ZSkgMHhkMCwgKGJ5dGUpIDB4ZDEsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMiwgKGJ5dGUpIDB4ZDMsIChieXRlKSAweGQ0LCAoYnl0ZSkgMHhkNSwgKGJ5dGUpIDB4ZDYsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNywgKGJ5dGUpIDB4ZDgsIChieXRlKSAweGQ5LCAoYnl0ZSkgMHhkYSwgKGJ5dGUpIDB4ZGIsCisgICAgICAgICAgICAoYnl0ZSkgMHhkYywgKGJ5dGUpIDB4ZGQsIChieXRlKSAweGRlLCAoYnl0ZSkgMHhkZiwgKGJ5dGUpIDB4ZTAsCisgICAgICAgICAgICAoYnl0ZSkgMHhlMSwgKGJ5dGUpIDB4ZTIsIChieXRlKSAweGUzLCAoYnl0ZSkgMHhlNCwgKGJ5dGUpIDB4ZTUsCisgICAgICAgICAgICAoYnl0ZSkgMHhlNiwgKGJ5dGUpIDB4ZTcsIChieXRlKSAweGU4LCAoYnl0ZSkgMHhlOSwgKGJ5dGUpIDB4ZWEsCisgICAgICAgICAgICAoYnl0ZSkgMHhlYiwgKGJ5dGUpIDB4ZWMsIChieXRlKSAweGVkLCAoYnl0ZSkgMHhlZSwgKGJ5dGUpIDB4ZWYsCisgICAgICAgICAgICAoYnl0ZSkgMHhmMCwgKGJ5dGUpIDB4ZjEsIChieXRlKSAweGYyLCAoYnl0ZSkgMHhmMywgKGJ5dGUpIDB4ZjQsCisgICAgICAgICAgICAoYnl0ZSkgMHhmNSwgKGJ5dGUpIDB4ZjYsIChieXRlKSAweGY3LCAoYnl0ZSkgMHhmOCwgKGJ5dGUpIDB4ZjksCisgICAgICAgICAgICAoYnl0ZSkgMHhmYSwgKGJ5dGUpIDB4ZmIsIChieXRlKSAweGZjLCAoYnl0ZSkgMHhmZCwgKGJ5dGUpIDB4ZmUsCisgICAgICAgICAgICAoYnl0ZSkgMHhmZiwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDMsCisgICAgICAgICAgICAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MDUsIChieXRlKSAweDA2LCAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4MDgsCisgICAgICAgICAgICAoYnl0ZSkgMHgwOSwgKGJ5dGUpIDB4MGEsIChieXRlKSAweDBiLCAoYnl0ZSkgMHgwYywgKGJ5dGUpIDB4MGQsCisgICAgICAgICAgICAoYnl0ZSkgMHgwZSwgKGJ5dGUpIDB4MGYsIChieXRlKSAweDEwLCAoYnl0ZSkgMHgxMSwgKGJ5dGUpIDB4MTIsCisgICAgICAgICAgICAoYnl0ZSkgMHgxMywgKGJ5dGUpIDB4MTQsIChieXRlKSAweDE1LCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4MTcsCisgICAgICAgICAgICAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4MTksIChieXRlKSAweDFhLCAoYnl0ZSkgMHgxYiwgKGJ5dGUpIDB4MWMsCisgICAgICAgICAgICAoYnl0ZSkgMHgxZCwgKGJ5dGUpIDB4MWUsIChieXRlKSAweDFmLCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4MjEsCisgICAgICAgICAgICAoYnl0ZSkgMHgyMiwgKGJ5dGUpIDB4MjMsIChieXRlKSAweDI0LCAoYnl0ZSkgMHgyNSwgKGJ5dGUpIDB4MjYsCisgICAgICAgICAgICAoYnl0ZSkgMHgyNywgKGJ5dGUpIDB4MjgsIChieXRlKSAweDI5LCAoYnl0ZSkgMHgyYSwgKGJ5dGUpIDB4MmIsCisgICAgICAgICAgICAoYnl0ZSkgMHgyYywgKGJ5dGUpIDB4MmQsIChieXRlKSAweDJlLCAoYnl0ZSkgMHgyZiwgKGJ5dGUpIDB4MzAsCisgICAgICAgICAgICAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4MzIsIChieXRlKSAweDMzLCAoYnl0ZSkgMHgzNCwgKGJ5dGUpIDB4MzUsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4MzcsIChieXRlKSAweDM4LCAoYnl0ZSkgMHgzOSwgKGJ5dGUpIDB4M2EsCisgICAgICAgICAgICAoYnl0ZSkgMHgzYiwgKGJ5dGUpIDB4M2MsIChieXRlKSAweDNkLCAoYnl0ZSkgMHgzZSwgKGJ5dGUpIDB4M2YsCisgICAgICAgICAgICAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NDEsIChieXRlKSAweDQyLCAoYnl0ZSkgMHg0MywgKGJ5dGUpIDB4NDQsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4NDYsIChieXRlKSAweDQ3LCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4NDksCisgICAgICAgICAgICAoYnl0ZSkgMHg0YSwgKGJ5dGUpIDB4NGIsIChieXRlKSAweDRjLCAoYnl0ZSkgMHg0ZCwgKGJ5dGUpIDB4NGUsCisgICAgICAgICAgICAoYnl0ZSkgMHg0ZiwgKGJ5dGUpIDB4NTAsIChieXRlKSAweDUxLCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4NTMsCisgICAgICAgICAgICAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDU2LCAoYnl0ZSkgMHg1NywgKGJ5dGUpIDB4NTgsCisgICAgICAgICAgICAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4NWEsIChieXRlKSAweDViLCAoYnl0ZSkgMHg1YywgKGJ5dGUpIDB4NWQsCisgICAgICAgICAgICAoYnl0ZSkgMHg1ZSwgKGJ5dGUpIDB4NWYsIChieXRlKSAweDYwLCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4NjIsCisgICAgICAgICAgICAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4NjQsIChieXRlKSAweDY1LCAoYnl0ZSkgMHg2NiwgKGJ5dGUpIDB4NjcsCisgICAgICAgICAgICAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4NjksIChieXRlKSAweDZhLCAoYnl0ZSkgMHg2YiwgKGJ5dGUpIDB4NmMsCisgICAgICAgICAgICAoYnl0ZSkgMHg2ZCwgKGJ5dGUpIDB4NmUsIChieXRlKSAweDZmLCAoYnl0ZSkgMHg3MCwgKGJ5dGUpIDB4NzEsCisgICAgICAgICAgICAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4NzMsIChieXRlKSAweDc0LCAoYnl0ZSkgMHg3NSwgKGJ5dGUpIDB4NzYsCisgICAgICAgICAgICAoYnl0ZSkgMHg3NywgKGJ5dGUpIDB4NzgsIChieXRlKSAweDc5LCAoYnl0ZSkgMHg3YSwgKGJ5dGUpIDB4N2IsCisgICAgICAgICAgICAoYnl0ZSkgMHg3YywgKGJ5dGUpIDB4N2QsIChieXRlKSAweDdlLCAoYnl0ZSkgMHg3ZiwgKGJ5dGUpIDB4ODAsCisgICAgICAgICAgICAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDgzLCAoYnl0ZSkgMHg4NCwgKGJ5dGUpIDB4ODUsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4ODcsIChieXRlKSAweDg4LCAoYnl0ZSkgMHg4OSwgKGJ5dGUpIDB4OGEsCisgICAgICAgICAgICAoYnl0ZSkgMHg4YiwgKGJ5dGUpIDB4OGMsIChieXRlKSAweDhkLCAoYnl0ZSkgMHg4ZSwgKGJ5dGUpIDB4OGYsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MCwgKGJ5dGUpIDB4OTEsIChieXRlKSAweDkyLCAoYnl0ZSkgMHg5MywgKGJ5dGUpIDB4OTQsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NSwgKGJ5dGUpIDB4OTYsIChieXRlKSAweDk3LCAoYnl0ZSkgMHg5OCwgKGJ5dGUpIDB4OTksCisgICAgICAgICAgICAoYnl0ZSkgMHg5YSwgKGJ5dGUpIDB4OWIsIChieXRlKSAweDljLCAoYnl0ZSkgMHg5ZCwgKGJ5dGUpIDB4OWUsCisgICAgICAgICAgICAoYnl0ZSkgMHg5ZiwgKGJ5dGUpIDB4YTAsIChieXRlKSAweGExLCAoYnl0ZSkgMHhhMiwgKGJ5dGUpIDB4YTMsCisgICAgICAgICAgICAoYnl0ZSkgMHhhNCwgKGJ5dGUpIDB4YTUsIChieXRlKSAweGE2LCAoYnl0ZSkgMHhhNywgKGJ5dGUpIDB4YTgsCisgICAgICAgICAgICAoYnl0ZSkgMHhhOSwgKGJ5dGUpIDB4YWEsIChieXRlKSAweGFiLCAoYnl0ZSkgMHhhYywgKGJ5dGUpIDB4YWQsCisgICAgICAgICAgICAoYnl0ZSkgMHhhZSwgKGJ5dGUpIDB4YWYsIChieXRlKSAweGIwLCAoYnl0ZSkgMHhiMSwgKGJ5dGUpIDB4YjIsCisgICAgICAgICAgICAoYnl0ZSkgMHhiMywgKGJ5dGUpIDB4YjQsIChieXRlKSAweGI1LCAoYnl0ZSkgMHhiNiwgKGJ5dGUpIDB4YjcsCisgICAgICAgICAgICAoYnl0ZSkgMHhiOCwgKGJ5dGUpIDB4YjksIChieXRlKSAweGJhLCAoYnl0ZSkgMHhiYiwgKGJ5dGUpIDB4YmMsCisgICAgICAgICAgICAoYnl0ZSkgMHhiZCwgKGJ5dGUpIDB4YmUsIChieXRlKSAweGJmLCAoYnl0ZSkgMHhjMCwgKGJ5dGUpIDB4YzEsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMiwgKGJ5dGUpIDB4YzMsIChieXRlKSAweGM0LCAoYnl0ZSkgMHhjNSwgKGJ5dGUpIDB4YzYsCisgICAgICAgICAgICAoYnl0ZSkgMHhjNywgKGJ5dGUpIDB4YzgsIChieXRlKSAweGM5LCAoYnl0ZSkgMHhjYSwgKGJ5dGUpIDB4Y2IsCisgICAgICAgICAgICAoYnl0ZSkgMHhjYywgKGJ5dGUpIDB4Y2QsIChieXRlKSAweGNlLCAoYnl0ZSkgMHhjZiwgKGJ5dGUpIDB4ZDAsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMSwgKGJ5dGUpIDB4ZDIsIChieXRlKSAweGQzLCAoYnl0ZSkgMHhkNCwgKGJ5dGUpIDB4ZDUsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNiwgKGJ5dGUpIDB4ZDcsIChieXRlKSAweGQ4LCAoYnl0ZSkgMHhkOSwgKGJ5dGUpIDB4ZGEsCisgICAgICAgICAgICAoYnl0ZSkgMHhkYiwgKGJ5dGUpIDB4ZGMsIChieXRlKSAweGRkLCAoYnl0ZSkgMHhkZSwgKGJ5dGUpIDB4ZGYsCisgICAgICAgICAgICAoYnl0ZSkgMHhlMCwgKGJ5dGUpIDB4ZTEsIChieXRlKSAweGUyLCAoYnl0ZSkgMHhlMywgKGJ5dGUpIDB4ZTQsCisgICAgICAgICAgICAoYnl0ZSkgMHhlNSwgKGJ5dGUpIDB4ZTYsIChieXRlKSAweGU3LCAoYnl0ZSkgMHhlOCwgKGJ5dGUpIDB4ZTksCisgICAgICAgICAgICAoYnl0ZSkgMHhlYSwgKGJ5dGUpIDB4ZWIsIChieXRlKSAweGVjLCAoYnl0ZSkgMHhlZCwgKGJ5dGUpIDB4ZWUsCisgICAgICAgICAgICAoYnl0ZSkgMHhlZiwgKGJ5dGUpIDB4ZjAsIChieXRlKSAweGYxLCAoYnl0ZSkgMHhmMiwgKGJ5dGUpIDB4ZjMsCisgICAgICAgICAgICAoYnl0ZSkgMHhmNCwgKGJ5dGUpIDB4ZjUsIChieXRlKSAweGY2LCAoYnl0ZSkgMHhmNywgKGJ5dGUpIDB4ZjgsCisgICAgICAgICAgICAoYnl0ZSkgMHhmOSwgKGJ5dGUpIDB4ZmEsIChieXRlKSAweGZiLCAoYnl0ZSkgMHhmYywgKGJ5dGUpIDB4ZmQsCisgICAgICAgICAgICAoYnl0ZSkgMHhmZSwgKGJ5dGUpIDB4ZmYsIH07CisKKyAgICAvKioKKyAgICAgKiBWYWxpZCBEU0EgcGFyYW1ldGVycyBlbmNvZGluZworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBkc2FQYXJhbXNFbmNvZGVkID0geyAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4ODIsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MWUsIChieXRlKSAweDAyLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODEsCisgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4OWYsIChieXRlKSAweDVlLCAoYnl0ZSkgMHg3NiwgKGJ5dGUpIDB4MTksCisgICAgICAgICAgICAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4ZDgsIChieXRlKSAweGY3LCAoYnl0ZSkgMHg2YiwgKGJ5dGUpIDB4OTEsCisgICAgICAgICAgICAoYnl0ZSkgMHg2ZCwgKGJ5dGUpIDB4MTUsIChieXRlKSAweDdlLCAoYnl0ZSkgMHgxNCwgKGJ5dGUpIDB4MjcsCisgICAgICAgICAgICAoYnl0ZSkgMHgyNSwgKGJ5dGUpIDB4NmUsIChieXRlKSAweDU5LCAoYnl0ZSkgMHgyYywgKGJ5dGUpIDB4ZWMsCisgICAgICAgICAgICAoYnl0ZSkgMHgyMSwgKGJ5dGUpIDB4N2EsIChieXRlKSAweGI3LCAoYnl0ZSkgMHhkNCwgKGJ5dGUpIDB4ZjQsCisgICAgICAgICAgICAoYnl0ZSkgMHhhMCwgKGJ5dGUpIDB4MjYsIChieXRlKSAweDRlLCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4MjksCisgICAgICAgICAgICAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4NGEsIChieXRlKSAweDFjLCAoYnl0ZSkgMHg5YSwgKGJ5dGUpIDB4YzksCisgICAgICAgICAgICAoYnl0ZSkgMHhjZCwgKGJ5dGUpIDB4ODUsIChieXRlKSAweDFiLCAoYnl0ZSkgMHgzOSwgKGJ5dGUpIDB4NDEsCisgICAgICAgICAgICAoYnl0ZSkgMHg5ZSwgKGJ5dGUpIDB4NTgsIChieXRlKSAweDE2LCAoYnl0ZSkgMHhlYiwgKGJ5dGUpIDB4MjAsCisgICAgICAgICAgICAoYnl0ZSkgMHg4NCwgKGJ5dGUpIDB4MjgsIChieXRlKSAweDJhLCAoYnl0ZSkgMHhiOSwgKGJ5dGUpIDB4Y2UsCisgICAgICAgICAgICAoYnl0ZSkgMHhjNywgKGJ5dGUpIDB4NmQsIChieXRlKSAweDc0LCAoYnl0ZSkgMHg5OSwgKGJ5dGUpIDB4ZmUsCisgICAgICAgICAgICAoYnl0ZSkgMHhhNSwgKGJ5dGUpIDB4ZTgsIChieXRlKSAweDY2LCAoYnl0ZSkgMHhlMSwgKGJ5dGUpIDB4NDgsCisgICAgICAgICAgICAoYnl0ZSkgMHhkZCwgKGJ5dGUpIDB4MmUsIChieXRlKSAweGNmLCAoYnl0ZSkgMHhmZSwgKGJ5dGUpIDB4YjksCisgICAgICAgICAgICAoYnl0ZSkgMHg2YSwgKGJ5dGUpIDB4OGUsIChieXRlKSAweDEyLCAoYnl0ZSkgMHg0YiwgKGJ5dGUpIDB4YTQsCisgICAgICAgICAgICAoYnl0ZSkgMHhhOCwgKGJ5dGUpIDB4ODcsIChieXRlKSAweGQ3LCAoYnl0ZSkgMHhhYiwgKGJ5dGUpIDB4MjYsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNiwgKGJ5dGUpIDB4YzMsIChieXRlKSAweGQxLCAoYnl0ZSkgMHgzYiwgKGJ5dGUpIDB4OTUsCisgICAgICAgICAgICAoYnl0ZSkgMHhjNCwgKGJ5dGUpIDB4OTcsIChieXRlKSAweDJjLCAoYnl0ZSkgMHhkYywgKGJ5dGUpIDB4YWIsCisgICAgICAgICAgICAoYnl0ZSkgMHg1ZCwgKGJ5dGUpIDB4ZjUsIChieXRlKSAweDU1LCAoYnl0ZSkgMHhhZSwgKGJ5dGUpIDB4NTgsCisgICAgICAgICAgICAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4ODQsIChieXRlKSAweDQxLCAoYnl0ZSkgMHg5OSwgKGJ5dGUpIDB4MWIsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMywgKGJ5dGUpIDB4ZDAsIChieXRlKSAweGQ5LCAoYnl0ZSkgMHhkMywgKGJ5dGUpIDB4ZGQsCisgICAgICAgICAgICAoYnl0ZSkgMHhmNSwgKGJ5dGUpIDB4NDgsIChieXRlKSAweDA0LCAoYnl0ZSkgMHhhMiwgKGJ5dGUpIDB4OTIsCisgICAgICAgICAgICAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4ZjgsIChieXRlKSAweGIxLCAoYnl0ZSkgMHhlNiwgKGJ5dGUpIDB4MjQsCisgICAgICAgICAgICAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4OGYsIChieXRlKSAweGE0LCAoYnl0ZSkgMHg5NywgKGJ5dGUpIDB4NDAsCisgICAgICAgICAgICAoYnl0ZSkgMHgxZCwgKGJ5dGUpIDB4M2YsIChieXRlKSAweDJiLCAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4MDAsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNSwgKGJ5dGUpIDB4Y2IsIChieXRlKSAweDhkLCAoYnl0ZSkgMHg2NiwgKGJ5dGUpIDB4OWEsCisgICAgICAgICAgICAoYnl0ZSkgMHhhYywgKGJ5dGUpIDB4N2IsIChieXRlKSAweDVmLCAoYnl0ZSkgMHhjNywgKGJ5dGUpIDB4MDIsCisgICAgICAgICAgICAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDlhLCAoYnl0ZSkgMHhmYiwgKGJ5dGUpIDB4NmYsCisgICAgICAgICAgICAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4MTUsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MTYsCisgICAgICAgICAgICAoYnl0ZSkgMHgyYSwgKGJ5dGUpIDB4ZDYsIChieXRlKSAweGNhLCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4MTAsCisgICAgICAgICAgICAoYnl0ZSkgMHg0NywgKGJ5dGUpIDB4ZGUsIChieXRlKSAweDRiLCAoYnl0ZSkgMHgwZiwgKGJ5dGUpIDB4ZDYsCisgICAgICAgICAgICAoYnl0ZSkgMHg3MywgKGJ5dGUpIDB4MzcsIChieXRlKSAweDAyLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODAsCisgICAgICAgICAgICAoYnl0ZSkgMHg1ZCwgKGJ5dGUpIDB4NTEsIChieXRlKSAweDI4LCAoYnl0ZSkgMHg2NCwgKGJ5dGUpIDB4YjIsCisgICAgICAgICAgICAoYnl0ZSkgMHgyYiwgKGJ5dGUpIDB4ZWIsIChieXRlKSAweDg1LCAoYnl0ZSkgMHhiNCwgKGJ5dGUpIDB4MTQsCisgICAgICAgICAgICAoYnl0ZSkgMHgwZCwgKGJ5dGUpIDB4YWQsIChieXRlKSAweGVjLCAoYnl0ZSkgMHhjOCwgKGJ5dGUpIDB4MWYsCisgICAgICAgICAgICAoYnl0ZSkgMHg5NiwgKGJ5dGUpIDB4MWUsIChieXRlKSAweDZhLCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4ZDQsCisgICAgICAgICAgICAoYnl0ZSkgMHgwYiwgKGJ5dGUpIDB4NjksIChieXRlKSAweGIwLCAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4YTEsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMSwgKGJ5dGUpIDB4YmMsIChieXRlKSAweDY0LCAoYnl0ZSkgMHhkNiwgKGJ5dGUpIDB4NjQsCisgICAgICAgICAgICAoYnl0ZSkgMHhlZiwgKGJ5dGUpIDB4MmMsIChieXRlKSAweDg5LCAoYnl0ZSkgMHhjNywgKGJ5dGUpIDB4MzksCisgICAgICAgICAgICAoYnl0ZSkgMHg3NSwgKGJ5dGUpIDB4ODcsIChieXRlKSAweDgyLCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4YmUsCisgICAgICAgICAgICAoYnl0ZSkgMHhkMSwgKGJ5dGUpIDB4Y2QsIChieXRlKSAweDcwLCAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4ODUsCisgICAgICAgICAgICAoYnl0ZSkgMHg5OSwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDc1LCAoYnl0ZSkgMHg2ZiwgKGJ5dGUpIDB4MTYsCisgICAgICAgICAgICAoYnl0ZSkgMHhjMCwgKGJ5dGUpIDB4NDAsIChieXRlKSAweGYxLCAoYnl0ZSkgMHgwYywgKGJ5dGUpIDB4NzgsCisgICAgICAgICAgICAoYnl0ZSkgMHgxZiwgKGJ5dGUpIDB4ZTgsIChieXRlKSAweDYzLCAoYnl0ZSkgMHg1ZCwgKGJ5dGUpIDB4ZmEsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNywgKGJ5dGUpIDB4YzEsIChieXRlKSAweGNlLCAoYnl0ZSkgMHg5NywgKGJ5dGUpIDB4NzYsCisgICAgICAgICAgICAoYnl0ZSkgMHhhNSwgKGJ5dGUpIDB4NDgsIChieXRlKSAweDViLCAoYnl0ZSkgMHg4OCwgKGJ5dGUpIDB4ZTQsCisgICAgICAgICAgICAoYnl0ZSkgMHhkNSwgKGJ5dGUpIDB4YjgsIChieXRlKSAweDA2LCAoYnl0ZSkgMHhmNSwgKGJ5dGUpIDB4N2YsCisgICAgICAgICAgICAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4ZGEsIChieXRlKSAweDk5LCAoYnl0ZSkgMHhhNSwgKGJ5dGUpIDB4NWEsCisgICAgICAgICAgICAoYnl0ZSkgMHg2NCwgKGJ5dGUpIDB4YzksIChieXRlKSAweDMwLCAoYnl0ZSkgMHgyYywgKGJ5dGUpIDB4NzcsCisgICAgICAgICAgICAoYnl0ZSkgMHg1OCwgKGJ5dGUpIDB4NjAsIChieXRlKSAweGE2LCAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4MWQsCisgICAgICAgICAgICAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4ZmIsIChieXRlKSAweDQ5LCAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4NmMsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNCwgKGJ5dGUpIDB4MjksIChieXRlKSAweGEwLCAoYnl0ZSkgMHg0NywgKGJ5dGUpIDB4ZjEsCisgICAgICAgICAgICAoYnl0ZSkgMHgxNCwgKGJ5dGUpIDB4YWQsIChieXRlKSAweGMyLCAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4NDEsCisgICAgICAgICAgICAoYnl0ZSkgMHhkZCwgKGJ5dGUpIDB4MmMsIChieXRlKSAweDc4LCAoYnl0ZSkgMHgyYSwgKGJ5dGUpIDB4NWEsCisgICAgICAgICAgICAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4N2YsIChieXRlKSAweDE5LCAoYnl0ZSkgMHhmNCwgKGJ5dGUpIDB4MGEsCisgICAgICAgICAgICAoYnl0ZSkgMHgyZSwgKGJ5dGUpIDB4MWQsIChieXRlKSAweDkyLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4ZTUsCisgICAgICAgICAgICAoYnl0ZSkgMHhlNCwgKGJ5dGUpIDB4MDUsIChieXRlKSAweDI4LCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4NWMsCisgICAgICAgICAgICAoYnl0ZSkgMHgzNCwgKGJ5dGUpIDB4YzgsIChieXRlKSAweDIyIH07CisKKyAgICAvKioKKyAgICAgKiBWYWxpZCBESCBwYXJhbWV0ZXJzIGVuY29kaW5nCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIGRoUGFyYW1zRW5jb2RlZCA9IHsgKGJ5dGUpIDB4MzAsIChieXRlKSAweDgyLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweDBiLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDgxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweGNlLCAoYnl0ZSkgMHgyYywgKGJ5dGUpIDB4NGYsIChieXRlKSAweGVhLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZjIsIChieXRlKSAweDgzLCAoYnl0ZSkgMHhjNSwgKGJ5dGUpIDB4MzgsIChieXRlKSAweGM5LAorICAgICAgICAgICAgKGJ5dGUpIDB4YjYsIChieXRlKSAweGQ0LCAoYnl0ZSkgMHhmOCwgKGJ5dGUpIDB4YjgsIChieXRlKSAweDE3LAorICAgICAgICAgICAgKGJ5dGUpIDB4YTEsIChieXRlKSAweDdkLCAoYnl0ZSkgMHg0YywgKGJ5dGUpIDB4ZWMsIChieXRlKSAweDZiLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZDcsIChieXRlKSAweGMyLCAoYnl0ZSkgMHgxYSwgKGJ5dGUpIDB4MzUsIChieXRlKSAweDg1LAorICAgICAgICAgICAgKGJ5dGUpIDB4NTQsIChieXRlKSAweDE0LCAoYnl0ZSkgMHg2YywgKGJ5dGUpIDB4NTIsIChieXRlKSAweDI0LAorICAgICAgICAgICAgKGJ5dGUpIDB4YmYsIChieXRlKSAweGU2LCAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4ZDgsIChieXRlKSAweDQyLAorICAgICAgICAgICAgKGJ5dGUpIDB4YWMsIChieXRlKSAweGIzLCAoYnl0ZSkgMHgyOCwgKGJ5dGUpIDB4NGYsIChieXRlKSAweDc3LAorICAgICAgICAgICAgKGJ5dGUpIDB4ZjYsIChieXRlKSAweGZjLCAoYnl0ZSkgMHhlYSwgKGJ5dGUpIDB4ZWEsIChieXRlKSAweDcyLAorICAgICAgICAgICAgKGJ5dGUpIDB4Y2YsIChieXRlKSAweDFkLCAoYnl0ZSkgMHg3YiwgKGJ5dGUpIDB4ZTEsIChieXRlKSAweDcyLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZmEsIChieXRlKSAweDc3LCAoYnl0ZSkgMHgxMiwgKGJ5dGUpIDB4YTksIChieXRlKSAweDQyLAorICAgICAgICAgICAgKGJ5dGUpIDB4YmEsIChieXRlKSAweGM0LCAoYnl0ZSkgMHhmNCwgKGJ5dGUpIDB4ZmIsIChieXRlKSAweGJkLAorICAgICAgICAgICAgKGJ5dGUpIDB4OWYsIChieXRlKSAweDYzLCAoYnl0ZSkgMHg5YSwgKGJ5dGUpIDB4NTgsIChieXRlKSAweDZiLAorICAgICAgICAgICAgKGJ5dGUpIDB4YjYsIChieXRlKSAweGEyLCAoYnl0ZSkgMHg2ZSwgKGJ5dGUpIDB4M2EsIChieXRlKSAweDcxLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZjMsIChieXRlKSAweDQzLCAoYnl0ZSkgMHg1ZSwgKGJ5dGUpIDB4NmYsIChieXRlKSAweDhhLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZDAsIChieXRlKSAweGFjLCAoYnl0ZSkgMHhlNSwgKGJ5dGUpIDB4NjAsIChieXRlKSAweDc2LAorICAgICAgICAgICAgKGJ5dGUpIDB4NTcsIChieXRlKSAweDFmLCAoYnl0ZSkgMHg4MywgKGJ5dGUpIDB4NGQsIChieXRlKSAweGJjLAorICAgICAgICAgICAgKGJ5dGUpIDB4YWEsIChieXRlKSAweGIxLCAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4NDAsIChieXRlKSAweDE5LAorICAgICAgICAgICAgKGJ5dGUpIDB4YWMsIChieXRlKSAweDMxLCAoYnl0ZSkgMHhkNCwgKGJ5dGUpIDB4ZmMsIChieXRlKSAweDM5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweDQ2LCAoYnl0ZSkgMHhhYiwgKGJ5dGUpIDB4YWIsIChieXRlKSAweDUzLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTksIChieXRlKSAweDJkLCAoYnl0ZSkgMHhmOCwgKGJ5dGUpIDB4NGMsIChieXRlKSAweGQzLAorICAgICAgICAgICAgKGJ5dGUpIDB4OWYsIChieXRlKSAweDRkLCAoYnl0ZSkgMHhhNiwgKGJ5dGUpIDB4NzEsIChieXRlKSAweDkyLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDYsIChieXRlKSAweGM3LCAoYnl0ZSkgMHg4OSwgKGJ5dGUpIDB4NzAsIChieXRlKSAweGM0LAorICAgICAgICAgICAgKGJ5dGUpIDB4YzYsIChieXRlKSAweGEyLCAoYnl0ZSkgMHgxZiwgKGJ5dGUpIDB4MDUsIChieXRlKSAweDRhLAorICAgICAgICAgICAgKGJ5dGUpIDB4NWIsIChieXRlKSAweDg0LCAoYnl0ZSkgMHhmOSwgKGJ5dGUpIDB4ZmIsIChieXRlKSAweDk4LAorICAgICAgICAgICAgKGJ5dGUpIDB4NjMsIChieXRlKSAweGM5LCAoYnl0ZSkgMHg5YywgKGJ5dGUpIDB4MTMsIChieXRlKSAweDAyLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODEsIChieXRlKSAweDgwLCAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDkzLAorICAgICAgICAgICAgKGJ5dGUpIDB4YjMsIChieXRlKSAweDIyLCAoYnl0ZSkgMHgwYywgKGJ5dGUpIDB4Y2QsIChieXRlKSAweDdjLAorICAgICAgICAgICAgKGJ5dGUpIDB4YzMsIChieXRlKSAweGUzLCAoYnl0ZSkgMHhhMywgKGJ5dGUpIDB4OGEsIChieXRlKSAweGQ3LAorICAgICAgICAgICAgKGJ5dGUpIDB4YjQsIChieXRlKSAweGU5LCAoYnl0ZSkgMHhlMCwgKGJ5dGUpIDB4ZmEsIChieXRlKSAweGE5LAorICAgICAgICAgICAgKGJ5dGUpIDB4YTgsIChieXRlKSAweDY5LCAoYnl0ZSkgMHhkNiwgKGJ5dGUpIDB4YTYsIChieXRlKSAweDIwLAorICAgICAgICAgICAgKGJ5dGUpIDB4YjgsIChieXRlKSAweGQ0LCAoYnl0ZSkgMHhlNywgKGJ5dGUpIDB4ODcsIChieXRlKSAweDRlLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZjMsIChieXRlKSAweDkwLCAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4ZGQsIChieXRlKSAweDc1LAorICAgICAgICAgICAgKGJ5dGUpIDB4NWQsIChieXRlKSAweGZmLCAoYnl0ZSkgMHhlZSwgKGJ5dGUpIDB4ZjAsIChieXRlKSAweGVmLAorICAgICAgICAgICAgKGJ5dGUpIDB4NmEsIChieXRlKSAweDBhLCAoYnl0ZSkgMHhiMCwgKGJ5dGUpIDB4ZjEsIChieXRlKSAweDhhLAorICAgICAgICAgICAgKGJ5dGUpIDB4YjYsIChieXRlKSAweDdiLCAoYnl0ZSkgMHgzOSwgKGJ5dGUpIDB4OTUsIChieXRlKSAweGQ1LAorICAgICAgICAgICAgKGJ5dGUpIDB4MjQsIChieXRlKSAweDgzLCAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4OTUsIChieXRlKSAweDM0LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDgsIChieXRlKSAweDc3LCAoYnl0ZSkgMHgxZCwgKGJ5dGUpIDB4YWYsIChieXRlKSAweDY5LAorICAgICAgICAgICAgKGJ5dGUpIDB4ZjAsIChieXRlKSAweGI1LCAoYnl0ZSkgMHhkYiwgKGJ5dGUpIDB4MjQsIChieXRlKSAweDg5LAorICAgICAgICAgICAgKGJ5dGUpIDB4NzIsIChieXRlKSAweGIyLCAoYnl0ZSkgMHgwZCwgKGJ5dGUpIDB4NTcsIChieXRlKSAweDk0LAorICAgICAgICAgICAgKGJ5dGUpIDB4YjAsIChieXRlKSAweGU4LCAoYnl0ZSkgMHhjMiwgKGJ5dGUpIDB4MzcsIChieXRlKSAweDQ1LAorICAgICAgICAgICAgKGJ5dGUpIDB4NWEsIChieXRlKSAweGZjLCAoYnl0ZSkgMHhhMSwgKGJ5dGUpIDB4YTAsIChieXRlKSAweDQxLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZTQsIChieXRlKSAweDBjLCAoYnl0ZSkgMHhhMywgKGJ5dGUpIDB4NDAsIChieXRlKSAweDhiLAorICAgICAgICAgICAgKGJ5dGUpIDB4OWMsIChieXRlKSAweDE5LCAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4NjEsIChieXRlKSAweGQ5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDUsIChieXRlKSAweGJmLCAoYnl0ZSkgMHhjNSwgKGJ5dGUpIDB4ZTgsIChieXRlKSAweGY3LAorICAgICAgICAgICAgKGJ5dGUpIDB4YmQsIChieXRlKSAweDNhLCAoYnl0ZSkgMHhmNSwgKGJ5dGUpIDB4NzgsIChieXRlKSAweGMyLAorICAgICAgICAgICAgKGJ5dGUpIDB4OTIsIChieXRlKSAweGU4LCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4MDcsIChieXRlKSAweDNlLAorICAgICAgICAgICAgKGJ5dGUpIDB4NTcsIChieXRlKSAweDEyLCAoYnl0ZSkgMHhmNiwgKGJ5dGUpIDB4OTcsIChieXRlKSAweDFmLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZWEsIChieXRlKSAweDAyLCAoYnl0ZSkgMHhhMywgKGJ5dGUpIDB4MTksIChieXRlKSAweGE3LAorICAgICAgICAgICAgKGJ5dGUpIDB4NWEsIChieXRlKSAweDliLCAoYnl0ZSkgMHhmNiwgKGJ5dGUpIDB4ZDIsIChieXRlKSAweDBmLAorICAgICAgICAgICAgKGJ5dGUpIDB4ZTksIChieXRlKSAweDZiLCAoYnl0ZSkgMHhlYiwgKGJ5dGUpIDB4ZDcsIChieXRlKSAweDkzLAorICAgICAgICAgICAgKGJ5dGUpIDB4OWEsIChieXRlKSAweDdlLCAoYnl0ZSkgMHg0ZiwgKGJ5dGUpIDB4ZDYsIChieXRlKSAweDI5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDIsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4ZmYgfTsKKworICAgIC8qKgorICAgICAqIHByZXRlbmRzIHRvIGJlIGVuY3J5cHRlZCBwcml2YXRlIGtleQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZVtdIGVuY3J5cHRlZERhdGE7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBIYXNoTWFwPFN0cmluZywgYnl0ZVtdPiB2YWxpZEVQS0lFbmNvZGluZ3MgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIGJ5dGVbXT4oKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEhhc2hNYXA8U3RyaW5nLCBieXRlW10+IHZhbGlkRVBLSUVuY29kaW5nc05QID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBieXRlW10+KCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBIYXNoTWFwPFN0cmluZywgYnl0ZVtdPiB2YWxpZEFQRW5jb2RpbmdzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBieXRlW10+KCk7CisKKyAgICBzdGF0aWMgeworICAgICAgICB2YWxpZEVQS0lFbmNvZGluZ3MucHV0KCJESCIsIGRoRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8pOworICAgICAgICB2YWxpZEVQS0lFbmNvZGluZ3MucHV0KCJESUZGSUVIRUxMTUFOIiwgZGhFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyk7CisgICAgICAgIHZhbGlkRVBLSUVuY29kaW5ncy5wdXQoIkRJRkZJRS1IRUxMTUFOIiwgZGhFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyk7CisgICAgICAgIHZhbGlkRVBLSUVuY29kaW5ncy5wdXQoIjEuMi44NDAuMTEzNTQ5LjEuMy4xIiwKKyAgICAgICAgICAgICAgICBkaEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvKTsKKyAgICAgICAgdmFsaWRFUEtJRW5jb2RpbmdzTlAucHV0KCJESCIsIGRoRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9OUCk7CisgICAgICAgIHZhbGlkRVBLSUVuY29kaW5nc05QLnB1dCgiRElGRklFSEVMTE1BTiIsIGRoRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9OUCk7CisgICAgICAgIHZhbGlkRVBLSUVuY29kaW5nc05QLnB1dCgiRElGRklFLUhFTExNQU4iLCBkaEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvTlApOworICAgICAgICB2YWxpZEVQS0lFbmNvZGluZ3MucHV0KCJEU0EiLCBkc2FFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyk7CisgICAgICAgIHZhbGlkRVBLSUVuY29kaW5ncy5wdXQoIjEuMi44NDAuMTAwNDAuNC4xIiwgZHNhRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8pOworICAgICAgICB2YWxpZEVQS0lFbmNvZGluZ3NOUC5wdXQoIkRJRkZJRS1IRUxMTUFOIiwgZGhFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb05QKTsKKyAgICAgICAgdmFsaWRFUEtJRW5jb2RpbmdzTlAucHV0KCJEU0EiLCBkc2FFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb05QKTsKKyAgICAgICAgdmFsaWRBUEVuY29kaW5ncy5wdXQoIkRIIiwgZGhQYXJhbXNFbmNvZGVkKTsKKyAgICAgICAgdmFsaWRBUEVuY29kaW5ncy5wdXQoIkRJRkZJRUhFTExNQU4iLCBkaFBhcmFtc0VuY29kZWQpOworICAgICAgICB2YWxpZEFQRW5jb2RpbmdzLnB1dCgiRElGRklFLUhFTExNQU4iLCBkaFBhcmFtc0VuY29kZWQpOworICAgICAgICB2YWxpZEFQRW5jb2RpbmdzLnB1dCgiMS4yLjg0MC4xMTM1NDkuMS4zLjEiLCBkaFBhcmFtc0VuY29kZWQpOworICAgICAgICB2YWxpZEFQRW5jb2RpbmdzLnB1dCgiRFNBIiwgZHNhUGFyYW1zRW5jb2RlZCk7CisgICAgICAgIHZhbGlkQVBFbmNvZGluZ3MucHV0KCIxLjIuODQwLjEwMDQwLjQuMSIsIGRzYVBhcmFtc0VuY29kZWQpOworCisgICAgICAgIGVuY3J5cHRlZERhdGEgPSBuZXcgYnl0ZVsxMDI0XTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbmNyeXB0ZWREYXRhLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBlbmNyeXB0ZWREYXRhW2ldID0gKGJ5dGUpIGk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbGdvcml0aG1fbmFtZXMvc3RhbmRhcmRfbmFtZXMgdG8gYmUgdXNlZCBpbiB0ZXN0cyAiRFNBIiBhbmQgIkRIIiBtdXN0IGJlCisgICAgICogYWx3YXlzIHByZXNlbnRlZAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nW11bXSBhbGdOYW1lMCA9IG5ldyBTdHJpbmdbXVtdIHsKKyAgICAgICAgICAgIHsgIkRTQSIsICJEU0EiIH0sCisgICAgICAgICAgICB7ICJESCIsICJEaWZmaWVIZWxsbWFuIiwgIkRpZmZpZS1IZWxsbWFuIiB9LAorICAgICAgICAgICAgeyAiMS4yLjg0MC4xMDA0MC40LjEiLCAiRFNBIiB9LAorICAgICAgICAgICAgeyAiMS4yLjg0MC4xMTM1NDkuMS4xLjEiLCAiUlNBIiB9LAorICAgICAgICAgICAgeyAiMS4yLjg0MC4xMTM1NDkuMS4zLjEiLCAiRGlmZmllSGVsbG1hbiIgfSwKKyAgICAgICAgICAgIHsgIjEuMi44NDAuMTEzNTQ5LjEuNS4zIiwgInBiZVdpdGhNRDVBbmRERVMtQ0JDIiB9LAorICAgICAgICAgICAgeyAiMS4yLjg0MC4xMTM1NDkuMS4xMi4xLjMiLCAicGJlV2l0aFNIQUFuZDMtS2V5VHJpcGxlREVTLUNCQyIgfSwKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgeyIxLjIuODQwLjExMzU0OS4xLjEyLjEuNiIsICJwYmVXaXRoU0hBQW5kNDBCaXRSQzItQ0JDIn0sCisgICAgICAgICAgICB7ICIxLjIuODQwLjExMzU0OS4zLjIiLCAiUkMyLUNCQyIgfSwKKyAgICAgICAgICAgIHsgIjEuMi44NDAuMTEzNTQ5LjMuMyIsICJSQzItRUJDIiB9LAorICAgICAgICAgICAgeyAiMS4yLjg0MC4xMTM1NDkuMy40IiwgIlJDNCIgfSwKKyAgICAgICAgICAgIHsgIjEuMi44NDAuMTEzNTQ5LjMuNSIsICJSQzRXaXRoTUFDIiB9LAorICAgICAgICAgICAgeyAiMS4yLjg0MC4xMTM1NDkuMy42IiwgIkRFU3gtQ0JDIiB9LAorICAgICAgICAgICAgeyAiMS4yLjg0MC4xMTM1NDkuMy43IiwgIlRyaXBsZURFUy1DQkMiIH0sCisgICAgICAgICAgICB7ICIxLjIuODQwLjExMzU0OS4zLjgiLCAicmM1Q0JDIiB9LAorICAgICAgICAgICAgeyAiMS4yLjg0MC4xMTM1NDkuMy45IiwgIlJDNS1DQkMiIH0sCisgICAgICAgICAgICB7ICIxLjIuODQwLjExMzU0OS4zLjEwIiwgIkRFU0NETUYiIH0sIH07CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHZhbGlkIGVuY29kaW5nIG9mIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIEhvd2V2ZXIgZW5jb2RlZCBwcml2YXRlCisgICAgICoga2V5IGZpZWxkIChlbmNyeXB0ZWREYXRhKSBkb2VzIG5vdCBjb250YWluIHZhbGlkIGVuY3J5cHRlZCBkYXRhLgorICAgICAqCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBnZXRWYWxpZEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRW5jb2RpbmcoCisgICAgICAgICAgICBTdHJpbmcgYWxnTmFtZSwgYm9vbGVhbiBpbmNsdWRpbmdBbGdQYXJhbWV0ZXJzKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBhbGdOYW1lVUMgPSBhbGdOYW1lLnRvVXBwZXJDYXNlKCk7CisgICAgICAgIGJ5dGVbXSByZXQgPSBpbmNsdWRpbmdBbGdQYXJhbWV0ZXJzID8gdmFsaWRFUEtJRW5jb2RpbmdzCisgICAgICAgICAgICAgICAgLmdldChhbGdOYW1lVUMpIDogdmFsaWRFUEtJRW5jb2RpbmdzTlAuZ2V0KGFsZ05hbWVVQyk7CisgICAgICAgIGlmIChyZXQgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHJldC5jbG9uZSgpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oIk5vIGVuY29kaW5nIGF2YWlsYWJsZSBmb3IgIgorICAgICAgICAgICAgICAgICsgYWxnTmFtZSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gZ2V0VmFsaWRFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb0VuY29kaW5nKFN0cmluZyBhbGdOYW1lKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXRWYWxpZEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvRW5jb2RpbmcoYWxnTmFtZSwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB2YWxpZCBlbmNvZGluZyBvZiBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyBIb3dldmVyIGVuY29kZWQgcHJpdmF0ZQorICAgICAqIGtleSBmaWVsZCAoZW5jcnlwdGVkRGF0YSkgZG9lcyBub3QgY29udGFpbiB2YWxpZCBlbmNyeXB0ZWQgZGF0YS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gZ2V0UGFyYW1ldGVyc0VuY29kaW5nKFN0cmluZyBhbGdOYW1lKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBhbGdOYW1lVUMgPSBhbGdOYW1lLnRvVXBwZXJDYXNlKCk7CisgICAgICAgIGJ5dGVbXSByZXQgPSB2YWxpZEFQRW5jb2RpbmdzLmdldChhbGdOYW1lVUMpOworICAgICAgICBpZiAocmV0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiByZXQ7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbigiTm8gQVAgZW5jb2RpbmcgYXZhaWxhYmxlIGZvciAiCisgICAgICAgICAgICAgICAgKyBhbGdOYW1lKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL3N1cHBvcnQvTXlDaXBoZXIuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL3N1cHBvcnQvTXlDaXBoZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOWViMjZlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvc3VwcG9ydC9NeUNpcGhlci5qYXZhCkBAIC0wLDAgKzEsMTIyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisqIEBhdXRob3IgQm9yaXMgVi4gS3V6bmV0c292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LmNyeXB0by50ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uQmFkUGFkZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uQ2lwaGVyU3BpOworaW1wb3J0IGphdmF4LmNyeXB0by5JbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmNyeXB0by5Ob1N1Y2hQYWRkaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmNyeXB0by5TaG9ydEJ1ZmZlckV4Y2VwdGlvbjsKKworLyoqCisgKgorICogQ2lwaGVyIGltcGxlbWVudGF0aW9uIGZvciB0ZXN0aW5nCisgKi8KK3B1YmxpYyBjbGFzcyBNeUNpcGhlciBleHRlbmRzIENpcGhlclNwaSB7CisKKyAgICBwdWJsaWMgTXlDaXBoZXIoKSB7CisgICAgICAgIHN1cGVyKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lU2V0TW9kZShTdHJpbmcgbW9kZSkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lU2V0UGFkZGluZyhTdHJpbmcgcGFkZGluZykKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hQYWRkaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCEiUEtDUzVQYWRkaW5nIi5lcXVhbHMocGFkZGluZykpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyAgTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbihwYWRkaW5nKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgZW5naW5lR2V0QmxvY2tTaXplKCkgeworICAgICAgICByZXR1cm4gMTExOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgZW5naW5lR2V0T3V0cHV0U2l6ZShpbnQgaW5wdXRMZW4pIHsKKyAgICAgICAgcmV0dXJuIGlucHV0TGVuICsgMTA7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVHZXRJVigpIHsKKyAgICAgICAgYnl0ZVtdIGIgPSB7MSwyLDN9OworICAgICAgICByZXR1cm4gYjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgQWxnb3JpdGhtUGFyYW1ldGVycyBlbmdpbmVHZXRQYXJhbWV0ZXJzKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0KGludCBvcG1vZGUsIEtleSBrZXksIFNlY3VyZVJhbmRvbSByYW5kb20pCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChpbnQgb3Btb2RlLCBLZXkga2V5LAorICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMsIFNlY3VyZVJhbmRvbSByYW5kb20pCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChpbnQgb3Btb2RlLCBLZXkga2V5LCBBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtcywKKyAgICAgICAgICAgIFNlY3VyZVJhbmRvbSByYW5kb20pIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVVcGRhdGUoYnl0ZVtdIGlucHV0LCBpbnQgaW5wdXRPZmZzZXQsIGludCBpbnB1dExlbikgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IGVuZ2luZVVwZGF0ZShieXRlW10gaW5wdXQsIGludCBpbnB1dE9mZnNldCwgaW50IGlucHV0TGVuLAorICAgICAgICAgICAgYnl0ZVtdIG91dHB1dCwgaW50IG91dHB1dE9mZnNldCkgdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVEb0ZpbmFsKGJ5dGVbXSBpbnB1dCwgaW50IGlucHV0T2Zmc2V0LCBpbnQgaW5wdXRMZW4pCisgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiwgQmFkUGFkZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgZW5naW5lRG9GaW5hbChieXRlW10gaW5wdXQsIGludCBpbnB1dE9mZnNldCwgaW50IGlucHV0TGVuLAorICAgICAgICAgICAgYnl0ZVtdIG91dHB1dCwgaW50IG91dHB1dE9mZnNldCkgdGhyb3dzIFNob3J0QnVmZmVyRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiwgQmFkUGFkZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvc3VwcG9ydC9NeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvc3VwcG9ydC9NeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQwMTRiNjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9zdXBwb3J0L015RXhlbXB0aW9uTWVjaGFuaXNtU3BpLmphdmEKQEAgLTAsMCArMSwxNDAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKKworaW1wb3J0IGphdmF4LmNyeXB0by5FeGVtcHRpb25NZWNoYW5pc21FeGNlcHRpb247CitpbXBvcnQgamF2YXguY3J5cHRvLkV4ZW1wdGlvbk1lY2hhbmlzbVNwaTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2hvcnRCdWZmZXJFeGNlcHRpb247CisKKy8qKgorICogQWRkaXRpb25hbCBjbGFzcyBmb3IgdmVyaWZpY2F0aW9uIEV4ZW1wdGlvbk1lY2hhbmlzbVNwaQorICogYW5kIEV4ZW1wdGlvbk1lY2hhbmlzbSBjbGFzc2VzCisgKgorICovCisKK3B1YmxpYyBjbGFzcyBNeUV4ZW1wdGlvbk1lY2hhbmlzbVNwaSAgZXh0ZW5kcyBFeGVtcHRpb25NZWNoYW5pc21TcGkgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IGJ5dGVBcnJheUxlbmd0aCA9IDU7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBnZXRMZW5ndGgoKSB7CisgICAgICAgIHJldHVybiBieXRlQXJyYXlMZW5ndGg7CisgICAgfQorICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBieXRlW10gZW5naW5lR2VuRXhlbXB0aW9uQmxvYigpCisgICAgICAgICAgICB0aHJvd3MgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBieXRlW2J5dGVBcnJheUxlbmd0aF07CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBlbmdpbmVHZW5FeGVtcHRpb25CbG9iKGJ5dGVbXSBvdXRwdXQsIGludCBvdXRwdXRPZmZzZXQpCisgICAgICAgICAgICB0aHJvd3MgU2hvcnRCdWZmZXJFeGNlcHRpb24sIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBieXRlQXJyYXlMZW5ndGg7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBlbmdpbmVHZXRPdXRwdXRTaXplKGludCBpbnB1dExlbikgeworICAgICAgICByZXR1cm4gMTA7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChLZXkga2V5KSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oImtleSBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCEoa2V5IGluc3RhbmNlb2YgdG1wS2V5KSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbigiSW5jb3JyZWN0IGtleSIpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChLZXkga2V5LCBBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtcykKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLCBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbigia2V5IGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIShrZXkgaW5zdGFuY2VvZiB0bXBLZXkpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uKCJJbmNvcnJlY3Qga2V5Iik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBhcmFtcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbigicGFyYW1zIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXQoS2V5IGtleSwgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oImtleSBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCEoa2V5IGluc3RhbmNlb2YgdG1wS2V5KSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEV4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvbigiSW5jb3JyZWN0IGtleSIpOworICAgICAgICB9CisgICAgICAgIGlmIChwYXJhbXMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24oInBhcmFtcyBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKKyAgICBwdWJsaWMgY2xhc3MgdG1wS2V5IGltcGxlbWVudHMgS2V5IHsKKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgYWxnOworICAgICAgICBwcml2YXRlIGJ5dGVbXSBlbmM7CisgICAgICAgIHB1YmxpYyB0bXBLZXkoU3RyaW5nIGFsZywgYnl0ZVtdIGVuYykgeworICAgICAgICAgICAgdGhpcy5hbGcgPSBhbGc7CisgICAgICAgICAgICB0aGlzLmVuYyA9IGVuYzsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgICAgIHJldHVybiAidG1wS2V5IjsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgIHJldHVybiBhbGc7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIGVuYzsKKyAgICAgICAgfQorICAgIH0KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKKyAgICBwdWJsaWMgY2xhc3MgdG1wMUtleSBpbXBsZW1lbnRzIEtleSB7CisgICAgICAgIHByaXZhdGUgYnl0ZVtdIGVuYzsKKyAgICAgICAgcHVibGljIHRtcDFLZXkoU3RyaW5nIGFsZywgYnl0ZVtdIGVuYykgeworICAgICAgICAgICAgdGhpcy5lbmMgPSBlbmM7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgICAgICByZXR1cm4gInRtcDFLZXkiOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgcmV0dXJuICJ0bXAxS2V5IjsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gZW5jOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvc3VwcG9ydC9NeUtleUFncmVlbWVudFNwaS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvc3VwcG9ydC9NeUtleUFncmVlbWVudFNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAwYWEwZmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9zdXBwb3J0L015S2V5QWdyZWVtZW50U3BpLmphdmEKQEAgLTAsMCArMSw4NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uS2V5QWdyZWVtZW50U3BpOworaW1wb3J0IGphdmF4LmNyeXB0by5TZWNyZXRLZXk7CitpbXBvcnQgamF2YXguY3J5cHRvLlNob3J0QnVmZmVyRXhjZXB0aW9uOworCisvKioKKyAqIEFkZGl0aW9uYWwgY2xhc3MgZm9yIHZlcmlmaWNhdGlvbiBvZiBLZXlBZ3JlZW1lbnRTcGkKKyAqIGFuZCBLZXlBZ3JlZW1lbnQgZnVuY3Rpb25hbGl0eQorICoKKyAqLworCitwdWJsaWMgY2xhc3MgTXlLZXlBZ3JlZW1lbnRTcGkgZXh0ZW5kcyBLZXlBZ3JlZW1lbnRTcGkgeworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIEtleSBlbmdpbmVEb1BoYXNlKEtleSBrZXksIGJvb2xlYW4gbGFzdFBoYXNlKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24sIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghbGFzdFBoYXNlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJsYXN0IFBoYXNlIGlzIGZhbHNlIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVHZW5lcmF0ZVNlY3JldCgpIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3IGJ5dGVbMF07CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBlbmdpbmVHZW5lcmF0ZVNlY3JldChieXRlW10gc2hhcmVkU2VjcmV0LCBpbnQgb2Zmc2V0KQorICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiwgU2hvcnRCdWZmZXJFeGNlcHRpb24geworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIFNlY3JldEtleSBlbmdpbmVHZW5lcmF0ZVNlY3JldChTdHJpbmcgYWxnb3JpdGhtKQorICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhbGdvcml0aG0ubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbigiQWxnb3JpdGhtIGlzIGVtcHR5Iik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChLZXkga2V5LCBTZWN1cmVSYW5kb20gcmFuZG9tKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIHBhcmFtZXRlciIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXQoS2V5IGtleSwgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMsCisgICAgICAgICAgICBTZWN1cmVSYW5kb20gcmFuZG9tKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIHBhcmFtZXRlciIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL3N1cHBvcnQvTXlLZXlHZW5lcmF0b3JTcGkuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL3N1cHBvcnQvTXlLZXlHZW5lcmF0b3JTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMThjYmFlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvc3VwcG9ydC9NeUtleUdlbmVyYXRvclNwaS5qYXZhCkBAIC0wLDAgKzEsNjQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uS2V5R2VuZXJhdG9yU3BpOworaW1wb3J0IGphdmF4LmNyeXB0by5TZWNyZXRLZXk7CisKKy8qKgorICogQWRkaXRpb25hbCBjbGFzcyBmb3IgdmVyaWZpY2F0aW9uIG9mCisgKiBLZXlHZW5lcmF0b3JTcGkgYW5kIEtleUdlbmVyYXRvciBmdW5jdGlvbmFsaXR5CisgKgorICovCisKK3B1YmxpYyBjbGFzcyBNeUtleUdlbmVyYXRvclNwaSAgZXh0ZW5kcyBLZXlHZW5lcmF0b3JTcGkgeworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIFNlY3JldEtleSBlbmdpbmVHZW5lcmF0ZUtleSgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtcywgU2VjdXJlUmFuZG9tIHJhbmRvbSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBhcmFtcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbigicGFyYW1zIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXQoaW50IGtleXNpemUsIFNlY3VyZVJhbmRvbSByYW5kb20pIHsKKyAgICAgICAgaWYgKGtleXNpemUgPD0gNzcpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQga2V5c2l6ZSIpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChTZWN1cmVSYW5kb20gcmFuZG9tKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgcmFuZG9tIik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvc3VwcG9ydC9NeU1hY1NwaS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvc3VwcG9ydC9NeU1hY1NwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVmZWE0MTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9zdXBwb3J0L015TWFjU3BpLmphdmEKQEAgLTAsMCArMSw3NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5jcnlwdG8udGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CisKK2ltcG9ydCBqYXZheC5jcnlwdG8uTWFjU3BpOworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLlNlY3JldEtleVNwZWM7CisKKy8qKgorICogQWRkaXRpb25hbCBjbGFzcyBmb3IgdmVyaWZpY2F0aW9uIG9mIE1hY0dlbmVyYXRvclNwaSBhbmQgTWFjU3BpCisgKgorICovCisKK3B1YmxpYyBjbGFzcyBNeU1hY1NwaSBleHRlbmRzIE1hY1NwaSB7CisKKyAgICBwcml2YXRlIGludCBsZW5ndGggPSAwOworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgZW5naW5lR2V0TWFjTGVuZ3RoKCkgeworICAgICAgICByZXR1cm4gbGVuZ3RoOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXQoS2V5IGtleSwgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwYXJhbXMgPT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKCEoa2V5IGluc3RhbmNlb2YgU2VjcmV0S2V5U3BlYykpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJwYXJhbXMgaXMgbnVsbCBhbmQga2V5IGlzIFNlY3JldEtleVNwZWMiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShieXRlIGlucHV0KSB7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGVbXSBpbnB1dCwgaW50IG9mZnNldCwgaW50IGxlbikgeworICAgICAgICBpZiAob2Zmc2V0ID49IDAgJiYgbGVuID49IDApIHsKKyAgICAgICAgICAgIGxlbmd0aCA9IGxlbjsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBieXRlW10gZW5naW5lRG9GaW5hbCgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBieXRlW2xlbmd0aF07CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lUmVzZXQoKSB7CisgICAgICAgIGxlbmd0aCsrOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL3N1cHBvcnQvTXlTZWNyZXRLZXlGYWN0b3J5U3BpLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9zdXBwb3J0L015U2VjcmV0S2V5RmFjdG9yeVNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcyZjlmMWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9zdXBwb3J0L015U2VjcmV0S2V5RmFjdG9yeVNwaS5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuY3J5cHRvLnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkludmFsaWRLZXlTcGVjRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5LZXlTcGVjOworCitpbXBvcnQgamF2YXguY3J5cHRvLlNlY3JldEtleTsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2VjcmV0S2V5RmFjdG9yeVNwaTsKKworLyoqCisgKiBBZGRpdGlvbmFsIGNsYXNzIGZvciB2ZXJpZmljYXRpb24gb2YgU2VjcmV0S2V5RmFjdG9yeVNwaQorICogYW5kIFNlY3JldEtleUZhY3RvcnkgZnVuY3Rpb25hbGl0eQorICoKKyAqLworCitwdWJsaWMgY2xhc3MgTXlTZWNyZXRLZXlGYWN0b3J5U3BpICBleHRlbmRzIFNlY3JldEtleUZhY3RvcnlTcGkgeworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBTZWNyZXRLZXkgZW5naW5lR2VuZXJhdGVTZWNyZXQoS2V5U3BlYyBrZXlTcGVjKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIEtleVNwZWMgZW5naW5lR2V0S2V5U3BlYyhTZWNyZXRLZXkga2V5LCBDbGFzcyBrZXlTcGVjKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIFNlY3JldEtleSBlbmdpbmVUcmFuc2xhdGVLZXkoU2VjcmV0S2V5IGtleSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2ludGVybmFsL25ldC93d3cvcHJvdG9jb2wvaHR0cC9IdHRwVVJMQ29ubmVjdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9pbnRlcm5hbC9uZXQvd3d3L3Byb3RvY29sL2h0dHAvSHR0cFVSTENvbm5lY3Rpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGNkNTBiYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9pbnRlcm5hbC9uZXQvd3d3L3Byb3RvY29sL2h0dHAvSHR0cFVSTENvbm5lY3Rpb25UZXN0LmphdmEKQEAgLTAsMCArMSwzMDUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuaW50ZXJuYWwubmV0Lnd3dy5wcm90b2NvbC5odHRwOworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uU2lkZUVmZmVjdDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuQXV0aGVudGljYXRvcjsKK2ltcG9ydCBqYXZhLm5ldC5IdHRwVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0U29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5QYXNzd29yZEF1dGhlbnRpY2F0aW9uOworaW1wb3J0IGphdmEubmV0LlByb3h5OworaW1wb3J0IGphdmEubmV0LlByb3h5U2VsZWN0b3I7CitpbXBvcnQgamF2YS5uZXQuU2VydmVyU29ja2V0OworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNvY2tldFRpbWVvdXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJJOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkhUVFBVUkxDb25uZWN0aW9uPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgSHR0cFVSTENvbm5lY3Rpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgT2JqZWN0IGJvdW5kID0gbmV3IE9iamVjdCgpOworCisgICAgc3RhdGljIGNsYXNzIE1vY2tTZXJ2ZXIgZXh0ZW5kcyBUaHJlYWQgeworICAgICAgICBTZXJ2ZXJTb2NrZXQgc2VydmVyU29ja2V0OworICAgICAgICBib29sZWFuIGFjY2VwdGVkID0gZmFsc2U7CisgICAgICAgIGJvb2xlYW4gc3RhcnRlZCA9IGZhbHNlOworCisgICAgICAgIHB1YmxpYyBNb2NrU2VydmVyKFN0cmluZyBuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIobmFtZSk7CisgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQgPSBuZXcgU2VydmVyU29ja2V0KDApOworICAgICAgICAgICAgc2VydmVyU29ja2V0LnNldFNvVGltZW91dCgxMDAwKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgcG9ydCgpIHsKKyAgICAgICAgICAgIHJldHVybiBzZXJ2ZXJTb2NrZXQuZ2V0TG9jYWxQb3J0KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGJvdW5kKSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXJ0ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICBib3VuZC5ub3RpZnkoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0LmFjY2VwdCgpLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIGFjY2VwdGVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChTb2NrZXRUaW1lb3V0RXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBNb2NrUHJveHlTZXJ2ZXIgZXh0ZW5kcyBNb2NrU2VydmVyIHsKKworICAgICAgICBib29sZWFuIGFjY2VwdGVkQXV0aG9yaXplZFJlcXVlc3Q7CisKKyAgICAgICAgcHVibGljIE1vY2tQcm94eVNlcnZlcihTdHJpbmcgbmFtZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcihuYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFNvY2tldCBzb2NrZXQgPSBzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgICAgICAgICAgc29ja2V0LnNldFNvVGltZW91dCgxMDAwKTsKKyAgICAgICAgICAgICAgICBieXRlW10gYnVmZiA9IG5ldyBieXRlWzEwMjRdOworICAgICAgICAgICAgICAgIGludCBudW0gPSBzb2NrZXQuZ2V0SW5wdXRTdHJlYW0oKS5yZWFkKGJ1ZmYpOworICAgICAgICAgICAgICAgIHNvY2tldC5nZXRPdXRwdXRTdHJlYW0oKS53cml0ZSgoCisgICAgICAgICAgICAgICAgICAgICJIVFRQLzEuMCA0MDcgUHJveHkgYXV0aGVudGljYXRpb24gcmVxdWlyZWRcbiIKKyAgICAgICAgICAgICAgICAgICsgIlByb3h5LWF1dGhlbnRpY2F0ZTogQmFzaWMgcmVhbG09XCJyZW1vdGVob3N0XCJcblxuIikKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRCeXRlcygpKTsKKyAgICAgICAgICAgICAgICBudW0gPSBzb2NrZXQuZ2V0SW5wdXRTdHJlYW0oKS5yZWFkKGJ1ZmYpOworICAgICAgICAgICAgICAgIGlmIChudW0gPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBjb25uZWN0aW9uIHdhcyBjbG9zZWQsIGNyZWF0ZSBuZXcgb25lOgorICAgICAgICAgICAgICAgICAgICBzb2NrZXQgPSBzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgICAgICAgICAgICAgIHNvY2tldC5zZXRTb1RpbWVvdXQoMTAwMCk7CisgICAgICAgICAgICAgICAgICAgIG51bSA9IHNvY2tldC5nZXRJbnB1dFN0cmVhbSgpLnJlYWQoYnVmZik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIFN0cmluZyByZXF1ZXN0ID0gbmV3IFN0cmluZyhidWZmLCAwLCBudW0pOworICAgICAgICAgICAgICAgIGFjY2VwdGVkQXV0aG9yaXplZFJlcXVlc3QgPQorICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LnRvTG93ZXJDYXNlKCkuaW5kZXhPZigicHJveHktYXV0aG9yaXphdGlvbjoiKSA+IDA7CisgICAgICAgICAgICAgICAgaWYgKGFjY2VwdGVkQXV0aG9yaXplZFJlcXVlc3QpIHsKKyAgICAgICAgICAgICAgICAgICAgc29ja2V0LmdldE91dHB1dFN0cmVhbSgpLndyaXRlKCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSFRUUC8xLjEgMjAwIE9LXG5cbiIpLmdldEJ5dGVzKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFByb3h5U2VsZWN0b3IgaW1wbGVtZW50YXRpb24gdXNlZCBpbiB0aGUgdGVzdC4KKyAgICAgKi8KKyAgICBzdGF0aWMgY2xhc3MgVGVzdFByb3h5U2VsZWN0b3IgZXh0ZW5kcyBQcm94eVNlbGVjdG9yIHsKKyAgICAgICAgLy8gcHJveHkgcG9ydAorICAgICAgICBwcml2YXRlIGludCBwcm94eV9wb3J0OworICAgICAgICAvLyBzZXJ2ZXIgcG9ydAorICAgICAgICBwcml2YXRlIGludCBzZXJ2ZXJfcG9ydDsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBwcm94eSBzZWxlY3RvciBpbnN0YW5jZS4KKyAgICAgICAgICogU2VsZWN0b3Igd2lsbCByZXR1cm4gdGhlIHByb3h5LCBvbmx5IGlmIHRoZSBjb25uZWN0aW9uCisgICAgICAgICAqIGlzIG1hZGUgdG8gbG9jYWxob3N0OnNlcnZlcl9wb3J0LiBPdGhlcndpc2UgaXQgd2lsbAorICAgICAgICAgKiByZXR1cm4gTk9fUFJPWFkuCisgICAgICAgICAqIEFkZHJlc3Mgb2YgdGhlIHJldHVybmVkIHByb3h5IHdpbGwgYmUgbG9jYWxob3N0OnByb3h5X3BvcnQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgVGVzdFByb3h5U2VsZWN0b3IoaW50IHNlcnZlcl9wb3J0LCBpbnQgcHJveHlfcG9ydCkgeworICAgICAgICAgICAgdGhpcy5zZXJ2ZXJfcG9ydCA9IHNlcnZlcl9wb3J0OworICAgICAgICAgICAgdGhpcy5wcm94eV9wb3J0ID0gcHJveHlfcG9ydDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8UHJveHk+IHNlbGVjdChVUkkgdXJpKSB7CisgICAgICAgICAgICBQcm94eSBwcm94eSA9IFByb3h5Lk5PX1BST1hZOworICAgICAgICAgICAgaWYgKCgibG9jYWxob3N0Ii5lcXVhbHModXJpLmdldEhvc3QoKSkpCisgICAgICAgICAgICAgICAgICAgICYmIChzZXJ2ZXJfcG9ydCA9PSB1cmkuZ2V0UG9ydCgpKSkgeworICAgICAgICAgICAgICAgIHByb3h5ID0gbmV3IFByb3h5KFByb3h5LlR5cGUuSFRUUCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoImxvY2FsaG9zdCIsIHByb3h5X3BvcnQpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEFycmF5TGlzdDxQcm94eT4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxQcm94eT4oKTsKKyAgICAgICAgICAgIHJlc3VsdC5hZGQocHJveHkpOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjb25uZWN0RmFpbGVkKFVSSSB1cmksIFNvY2tldEFkZHJlc3Mgc2EsIElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgLy8gZG8gbm90aGluZworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkuaW50ZXJuYWwubmV0Lnd3dy5odHRwLmdldE91dHB1dFN0cmVhbSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldE91dHB1dFN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTQ4MgorICAgICAgICBNb2NrU2VydmVyIGh0dHBTZXJ2ZXIgPQorICAgICAgICAgICAgbmV3IE1vY2tTZXJ2ZXIoIlNlcnZlclNvY2tldCBmb3IgSHR0cFVSTENvbm5lY3Rpb25UZXN0Iik7CisgICAgICAgIGh0dHBTZXJ2ZXIuc3RhcnQoKTsKKyAgICAgICAgc3luY2hyb25pemVkKGJvdW5kKSB7CisgICAgICAgICAgICBpZiAoIWh0dHBTZXJ2ZXIuc3RhcnRlZCkgeworICAgICAgICAgICAgICAgIGJvdW5kLndhaXQoNTAwMCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gYyA9IChIdHRwVVJMQ29ubmVjdGlvbikKKyAgICAgICAgICAgIG5ldyBVUkwoImh0dHA6Ly9sb2NhbGhvc3Q6IiArIGh0dHBTZXJ2ZXIucG9ydCgpKS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjLnNldERvT3V0cHV0KHRydWUpOworICAgICAgICAvL3VzZSBuZXcgU3RyaW5nKCJQT1NUIikgaW5zdGVhZCBvZiBzaW1wbGUgIlBPU1QiIHRvIG9idGFpbiBvdGhlcgorICAgICAgICAvL29iamVjdCBpbnN0YW5jZXMgdGhlbiB0aG9zZSB0aGF0IGFyZSBpbiBIdHRwVVJMQ29ubmVjdGlvbiBjbGFzc2VzCisgICAgICAgIGMuc2V0UmVxdWVzdE1ldGhvZChuZXcgU3RyaW5nKCJQT1NUIikpOworICAgICAgICBjLmdldE91dHB1dFN0cmVhbSgpOworICAgICAgICBodHRwU2VydmVyLmpvaW4oKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFRlc3QgY2hlY2tzIGlmIHRoZSBwcm94eSBzcGVjaWZpZWQgaW4gb3BlbkNvbm5lY3Rpb24KKyAgICAgKiBtZXRob2Qgd2lsbCBiZSB1c2VkIGZvciBjb25uZWN0aW9uIHRvIHRoZSBzZXJ2ZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXNpbmdQcm94eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTU3MAorICAgICAgICBNb2NrU2VydmVyIHNlcnZlciA9IG5ldyBNb2NrU2VydmVyKCJzZXJ2ZXIiKTsKKyAgICAgICAgTW9ja1NlcnZlciBwcm94eSA9IG5ldyBNb2NrU2VydmVyKCJwcm94eSIpOworCisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vbG9jYWxob3N0OiIgKyBzZXJ2ZXIucG9ydCgpKTsKKworICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBVUkxDb25uZWN0aW9uKSB1cmwKKyAgICAgICAgICAgICAgICAub3BlbkNvbm5lY3Rpb24obmV3IFByb3h5KFByb3h5LlR5cGUuSFRUUCwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbmV0U29ja2V0QWRkcmVzcygibG9jYWxob3N0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm94eS5wb3J0KCkpKSk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0Q29ubmVjdFRpbWVvdXQoMjAwMCk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0UmVhZFRpbWVvdXQoMjAwMCk7CisKKyAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisgICAgICAgIHN5bmNocm9uaXplZChib3VuZCkgeworICAgICAgICAgICAgaWYgKCFzZXJ2ZXIuc3RhcnRlZCkgYm91bmQud2FpdCg1MDAwKTsKKyAgICAgICAgfQorICAgICAgICBwcm94eS5zdGFydCgpOworICAgICAgICBzeW5jaHJvbml6ZWQoYm91bmQpIHsKKyAgICAgICAgICAgIGlmICghcHJveHkuc3RhcnRlZCkgYm91bmQud2FpdCg1MDAwKTsKKyAgICAgICAgfQorCisgICAgICAgIGNvbm5lY3Rpb24uY29ubmVjdCgpOworCisgICAgICAgIC8vIHdhaXQgd2hpbGUgc2VydmVyIGFuZCBwcm94eSBydW4KKyAgICAgICAgc2VydmVyLmpvaW4oKTsKKyAgICAgICAgcHJveHkuam9pbigpOworCisgICAgICAgIGFzc2VydFRydWUoIkNvbm5lY3Rpb24gZG9lcyBub3QgdXNlIHByb3h5IiwgY29ubmVjdGlvbi51c2luZ1Byb3h5KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJQcm94eSBzZXJ2ZXIgd2FzIG5vdCB1c2VkIiwgcHJveHkuYWNjZXB0ZWQpOworCisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGh1YyA9IChIdHRwVVJMQ29ubmVjdGlvbil1cmwub3BlbkNvbm5lY3Rpb24oUHJveHkuTk9fUFJPWFkpOworICAgICAgICBhc3NlcnRGYWxzZShodWMudXNpbmdQcm94eSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGNoZWNrcyBpZiB0aGUgcHJveHkgcHJvdmlkZWQgYnkgcHJveHkgc2VsZWN0b3IKKyAgICAgKiB3aWxsIGJlIHVzZWQgZm9yIGNvbm5lY3Rpb24gdG8gdGhlIHNlcnZlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVc2luZ1Byb3h5U2VsZWN0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS01NzAKKyAgICAgICAgTW9ja1NlcnZlciBzZXJ2ZXIgPSBuZXcgTW9ja1NlcnZlcigic2VydmVyIik7CisgICAgICAgIE1vY2tTZXJ2ZXIgcHJveHkgPSBuZXcgTW9ja1NlcnZlcigicHJveHkiKTsKKworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovL2xvY2FsaG9zdDoiICsgc2VydmVyLnBvcnQoKSk7CisKKyAgICAgICAgLy8ga2VlcCBkZWZhdWx0IHByb3h5IHNlbGVjdG9yCisgICAgICAgIFByb3h5U2VsZWN0b3IgZGVmUFMgPSBQcm94eVNlbGVjdG9yLmdldERlZmF1bHQoKTsKKyAgICAgICAgLy8gcmVwbGFjZSBzZWxlY3RvcgorICAgICAgICBQcm94eVNlbGVjdG9yLnNldERlZmF1bHQoCisgICAgICAgICAgICAgICAgbmV3IFRlc3RQcm94eVNlbGVjdG9yKHNlcnZlci5wb3J0KCksIHByb3h5LnBvcnQoKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0KKyAgICAgICAgICAgICAgICAoSHR0cFVSTENvbm5lY3Rpb24pIHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICAgICAgY29ubmVjdGlvbi5zZXRDb25uZWN0VGltZW91dCgyMDAwKTsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uc2V0UmVhZFRpbWVvdXQoMjAwMCk7CisKKyAgICAgICAgICAgIHNlcnZlci5zdGFydCgpOworICAgICAgICAgICAgc3luY2hyb25pemVkKGJvdW5kKSB7CisgICAgICAgICAgICAgICAgaWYgKCFzZXJ2ZXIuc3RhcnRlZCkgYm91bmQud2FpdCg1MDAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHByb3h5LnN0YXJ0KCk7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQoYm91bmQpIHsKKyAgICAgICAgICAgICAgICBpZiAoIXByb3h5LnN0YXJ0ZWQpIGJvdW5kLndhaXQoNTAwMCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb25uZWN0aW9uLmNvbm5lY3QoKTsKKworICAgICAgICAgICAgLy8gd2FpdCB3aGlsZSBzZXJ2ZXIgYW5kIHByb3h5IHJ1bgorICAgICAgICAgICAgc2VydmVyLmpvaW4oKTsKKyAgICAgICAgICAgIHByb3h5LmpvaW4oKTsKKworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29ubmVjdGlvbiBkb2VzIG5vdCB1c2UgcHJveHkiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnVzaW5nUHJveHkoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJQcm94eSBzZXJ2ZXIgd2FzIG5vdCB1c2VkIiwgcHJveHkuYWNjZXB0ZWQpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgLy8gcmVzdG9yZSBkZWZhdWx0IHByb3h5IHNlbGVjdG9yCisgICAgICAgICAgICBQcm94eVNlbGVjdG9yLnNldERlZmF1bHQoZGVmUFMpOworICAgICAgICB9CisgICAgfQorICAgIEBTaWRlRWZmZWN0KCJTdWZmZXJzIGZyb20gc2lkZSBlZmZlY3Qgb2Ygb3RoZXIsIGN1cnJlbnRseSB1bmtub3duIHRlc3QiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RQcm94eUF1dGhvcml6YXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gU2V0IHVwIHRlc3QgQXV0aGVudGljYXRvcgorICAgICAgICBBdXRoZW50aWNhdG9yLnNldERlZmF1bHQobmV3IEF1dGhlbnRpY2F0b3IoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHByb3RlY3RlZCBQYXNzd29yZEF1dGhlbnRpY2F0aW9uIGdldFBhc3N3b3JkQXV0aGVudGljYXRpb24oKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBQYXNzd29yZEF1dGhlbnRpY2F0aW9uKAorICAgICAgICAgICAgICAgICAgICAidXNlciIsICJwYXNzd29yZCIudG9DaGFyQXJyYXkoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNb2NrUHJveHlTZXJ2ZXIgcHJveHkgPSBuZXcgTW9ja1Byb3h5U2VydmVyKCJQcm94eVNlcnZlciIpOworCisgICAgICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovL3JlbW90ZWhvc3Q6NTU1NTUvcmVxdWVzdGVkLmRhdGEiKTsKKyAgICAgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPQorICAgICAgICAgICAgICAgIChIdHRwVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb3h5KFByb3h5LlR5cGUuSFRUUCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoImxvY2FsaG9zdCIsIHByb3h5LnBvcnQoKSkpKTsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uc2V0Q29ubmVjdFRpbWVvdXQoMTAwMCk7CisgICAgICAgICAgICBjb25uZWN0aW9uLnNldFJlYWRUaW1lb3V0KDEwMDApOworCisgICAgICAgICAgICBwcm94eS5zdGFydCgpOworCisgICAgICAgICAgICBjb25uZWN0aW9uLmNvbm5lY3QoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygidW5leHBlY3RlZCByZXNwb25zZSBjb2RlIiwKKyAgICAgICAgICAgICAgICAgICAgMjAwLCBjb25uZWN0aW9uLmdldFJlc3BvbnNlQ29kZSgpKTsKKyAgICAgICAgICAgIHByb3h5LmpvaW4oKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkNvbm5lY3Rpb24gZGlkIG5vdCBzZW5kIHByb3h5IGF1dGhvcml6YXRpb24gcmVxdWVzdCIsCisgICAgICAgICAgICAgICAgICAgIHByb3h5LmFjY2VwdGVkQXV0aG9yaXplZFJlcXVlc3QpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgLy8gcmVtb3ZlIHByZXZpb3VzbHkgc2V0IGF1dGhlbnRpY2F0b3IKKyAgICAgICAgICAgIEF1dGhlbnRpY2F0b3Iuc2V0RGVmYXVsdChudWxsKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2ludGVybmFsL25ldC93d3cvcHJvdG9jb2wvaHR0cHMvSHR0cHNVUkxDb25uZWN0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2ludGVybmFsL25ldC93d3cvcHJvdG9jb2wvaHR0cHMvSHR0cHNVUkxDb25uZWN0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM1MTZmNjcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvaW50ZXJuYWwvbmV0L3d3dy9wcm90b2NvbC9odHRwcy9IdHRwc1VSTENvbm5lY3Rpb25UZXN0LmphdmEKQEAgLTAsMCArMSwxMTA4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmludGVybmFsLm5ldC53d3cucHJvdG9jb2wuaHR0cHM7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QcmludFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5BdXRoZW50aWNhdG9yOworaW1wb3J0IGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlBhc3N3b3JkQXV0aGVudGljYXRpb247CitpbXBvcnQgamF2YS5uZXQuUHJveHk7CitpbXBvcnQgamF2YS5uZXQuU2VydmVyU29ja2V0OworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5DYWxsYWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JTZXJ2aWNlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yczsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5GdXR1cmU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5Ib3N0bmFtZVZlcmlmaWVyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuSHR0cHNVUkxDb25uZWN0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleU1hbmFnZXJGYWN0b3J5OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMQ29udGV4dDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTb2NrZXQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTb2NrZXRGYWN0b3J5OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuVHJ1c3RNYW5hZ2VyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuVHJ1c3RNYW5hZ2VyRmFjdG9yeTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgbGliY29yZS5qYXZhLnNlY3VyaXR5LlRlc3RLZXlTdG9yZTsKK2ltcG9ydCBsaWJjb3JlLmphdmF4Lm5ldC5zc2wuVGVzdFRydXN0TWFuYWdlcjsKKworLyoqCisgKiBJbXBsZW1lbnRhdGlvbiBpbmRlcGVuZGVudCB0ZXN0IGZvciBIdHRwc1VSTENvbm5lY3Rpb24uCisgKiBUaGUgdGVzdCBuZWVkcyBjZXJ0c3RvcmUgZmlsZSBwbGFjZWQgaW4gc3lzdGVtIGNsYXNzcGF0aAorICogYW5kIG5hbWVkIGFzICJrZXlfc3RvcmUuIiArIHRoZSB0eXBlIG9mIHRoZQorICogZGVmYXVsdCBLZXlTdG9yZSBpbnN0YWxsZWQgaW4gdGhlIHN5c3RlbSBpbiBsb3dlciBjYXNlLgorICogPGJyPgorICogRm9yIGV4YW1wbGU6IGlmIGRlZmF1bHQgS2V5U3RvcmUgdHlwZSBpbiB0aGUgc3lzdGVtIGlzIEJLUworICogKGkuZS4gamF2YS5zZWN1cml0eSBmaWxlIHNldHMgdXAgdGhlIHByb3BlcnR5IGtleXN0b3JlLnR5cGU9QktTKSwKKyAqIHRodXMgY2xhc3NwYXRoIHNob3VsZCBwb2ludCB0byB0aGUgZGlyZWN0b3J5IHdpdGggImtleV9zdG9yZS5ia3MiCisgKiBmaWxlLgorICogPGJyPgorICogVGhpcyBjZXJ0c3RvcmUgZmlsZSBzaG91bGQgY29udGFpbiBzZWxmLXNpZ25lZCBjZXJ0aWZpY2F0ZQorICogZ2VuZXJhdGVkIGJ5IGtleXRvb2wgdXRpbGl0eSBpbiBhIHVzdWFsIHdheS4KKyAqIDxicj4KKyAqIFRoZSBwYXNzd29yZCB0byB0aGUgY2VydHN0b3JlIHNob3VsZCBiZSAicGFzc3dvcmQiICh3aXRob3V0IHF1b3RlcykuCisgKi8KK3B1YmxpYyBjbGFzcyBIdHRwc1VSTENvbm5lY3Rpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLy8gdGhlIHBhc3N3b3JkIHRvIHRoZSBzdG9yZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBLU19QQVNTV09SRCA9ICJwYXNzd29yZCI7CisKKyAgICAvLyB0dXJuIG9uL29mZiBsb2dnaW5nCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBET19MT0cgPSBmYWxzZTsKKworICAgIC8vIHJlYWQvY29ubmVjdGlvbiB0aW1lb3V0IHZhbHVlCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRJTUVPVVQgPSA1MDAwOworCisgICAgLy8gT0sgcmVzcG9uc2UgY29kZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBPS19DT0RFID0gMjAwOworCisgICAgLy8gTm90IEZvdW5kIHJlc3BvbnNlIGNvZGUKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTk9UX0ZPVU5EX0NPREUgPSA0MDQ7CisKKyAgICAvLyBQcm94eSBhdXRoZW50aWNhdGlvbiByZXF1aXJlZCByZXNwb25zZSBjb2RlCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEFVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEX0NPREUgPSA0MDc7CisKKyAgICBwcml2YXRlIHN0YXRpYyBGaWxlIHN0b3JlOworCisgICAgc3RhdGljIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0b3JlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgia2V5X3N0b3JlIiwgImJrcyIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gaWdub3JlCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgdGhhdCBIdHRwc1VSTENvbm5lY3Rpb24ncyBkZWZhdWx0IFNTTFNvY2tldEZhY3RvcnkgaXMgb3BlcmFibGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldERlZmF1bHRTU0xTb2NrZXRGYWN0b3J5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIHNldCB1cCB0aGUgcHJvcGVydGllcyBkZWZpbmluZyB0aGUgZGVmYXVsdCB2YWx1ZXMgbmVlZGVkIGJ5IFNTTCBzdHVmZgorICAgICAgICBzZXRVcFN0b3JlUHJvcGVydGllcygpOworCisgICAgICAgIFNTTFNvY2tldEZhY3RvcnkgZGVmYXVsdFNTTFNGID0gSHR0cHNVUkxDb25uZWN0aW9uLmdldERlZmF1bHRTU0xTb2NrZXRGYWN0b3J5KCk7CisgICAgICAgIFNlcnZlclNvY2tldCBzcyA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisgICAgICAgIFNvY2tldCBzID0gZGVmYXVsdFNTTFNGLmNyZWF0ZVNvY2tldCgibG9jYWxob3N0Iiwgc3MuZ2V0TG9jYWxQb3J0KCkpOworICAgICAgICBzcy5hY2NlcHQoKTsKKyAgICAgICAgcy5jbG9zZSgpOworICAgICAgICBzcy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RIdHRwc0Nvbm5lY3Rpb24oKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgLy8gc2V0IHVwIHRoZSBwcm9wZXJ0aWVzIGRlZmluaW5nIHRoZSBkZWZhdWx0IHZhbHVlcyBuZWVkZWQgYnkgU1NMIHN0dWZmCisgICAgICAgIHNldFVwU3RvcmVQcm9wZXJ0aWVzKCk7CisKKyAgICAgICAgLy8gY3JlYXRlIHRoZSBTU0wgc2VydmVyIHNvY2tldCBhY3RpbmcgYXMgYSBzZXJ2ZXIKKyAgICAgICAgU1NMQ29udGV4dCBjdHggPSBnZXRDb250ZXh0KCk7CisgICAgICAgIFNlcnZlclNvY2tldCBzcyA9IGN0eC5nZXRTZXJ2ZXJTb2NrZXRGYWN0b3J5KCkuY3JlYXRlU2VydmVyU29ja2V0KDApOworCisgICAgICAgIC8vIGNyZWF0ZSB0aGUgSG9zdG5hbWVWZXJpZmllciB0byBjaGVjayBob3N0bmFtZSB2ZXJpZmljYXRpb24KKyAgICAgICAgVGVzdEhvc3RuYW1lVmVyaWZpZXIgaG52ID0gbmV3IFRlc3RIb3N0bmFtZVZlcmlmaWVyKCk7CisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbi5zZXREZWZhdWx0SG9zdG5hbWVWZXJpZmllcihobnYpOworCisgICAgICAgIC8vIGNyZWF0ZSB1cmwgY29ubmVjdGlvbiB0byBiZSB0ZXN0ZWQKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHBzOi8vbG9jYWxob3N0OiIgKyBzcy5nZXRMb2NhbFBvcnQoKSk7CisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0U1NMU29ja2V0RmFjdG9yeShjdHguZ2V0U29ja2V0RmFjdG9yeSgpKTsKKworICAgICAgICAvLyBwZXJmb3JtIHRoZSBpbnRlcmFjdGlvbiBiZXR3ZWVuIHRoZSBwZWVycworICAgICAgICBTU0xTb2NrZXQgcGVlclNvY2tldCA9IChTU0xTb2NrZXQpIGRvSW50ZXJhY3Rpb24oY29ubmVjdGlvbiwgc3MpOworCisgICAgICAgIC8vIGNoZWNrIHRoZSBjb25uZWN0aW9uIHN0YXRlCisgICAgICAgIGNoZWNrQ29ubmVjdGlvblN0YXRlUGFyYW1ldGVycyhjb25uZWN0aW9uLCBwZWVyU29ja2V0KTsKKworICAgICAgICAvLyBzaG91bGQgc2lsZW50bHkgZXhpdAorICAgICAgICBjb25uZWN0aW9uLmNvbm5lY3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB0aGUgYmVoYXZpb3VyIG9mIEhUVFBTIGNvbm5lY3Rpb24gaW4gY2FzZSBvZiB1bmF2YWlsYWJpbGl0eQorICAgICAqIG9mIHJlcXVlc3RlZCByZXNvdXJjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SHR0cHNDb25uZWN0aW9uX05vdF9Gb3VuZF9SZXNwb25zZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICAvLyBzZXQgdXAgdGhlIHByb3BlcnRpZXMgZGVmaW5pbmcgdGhlIGRlZmF1bHQgdmFsdWVzIG5lZWRlZCBieSBTU0wgc3R1ZmYKKyAgICAgICAgc2V0VXBTdG9yZVByb3BlcnRpZXMoKTsKKworICAgICAgICAvLyBjcmVhdGUgdGhlIFNTTCBzZXJ2ZXIgc29ja2V0IGFjdGluZyBhcyBhIHNlcnZlcgorICAgICAgICBTU0xDb250ZXh0IGN0eCA9IGdldENvbnRleHQoKTsKKyAgICAgICAgU2VydmVyU29ja2V0IHNzID0gY3R4LmdldFNlcnZlclNvY2tldEZhY3RvcnkoKS5jcmVhdGVTZXJ2ZXJTb2NrZXQoMCk7CisKKyAgICAgICAgLy8gY3JlYXRlIHRoZSBIb3N0bmFtZVZlcmlmaWVyIHRvIGNoZWNrIGhvc3RuYW1lIHZlcmlmaWNhdGlvbgorICAgICAgICBUZXN0SG9zdG5hbWVWZXJpZmllciBobnYgPSBuZXcgVGVzdEhvc3RuYW1lVmVyaWZpZXIoKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uLnNldERlZmF1bHRIb3N0bmFtZVZlcmlmaWVyKGhudik7CisKKyAgICAgICAgLy8gY3JlYXRlIHVybCBjb25uZWN0aW9uIHRvIGJlIHRlc3RlZAorICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cHM6Ly9sb2NhbGhvc3Q6IiArIHNzLmdldExvY2FsUG9ydCgpKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXRTU0xTb2NrZXRGYWN0b3J5KGN0eC5nZXRTb2NrZXRGYWN0b3J5KCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkb0ludGVyYWN0aW9uKGNvbm5lY3Rpb24sIHNzLCBOT1RfRk9VTkRfQ09ERSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBleGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAoRE9fTE9HKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFeHBlY3RlZCBleGNlcHRpb24gd2FzIHRocm93bjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gc2hvdWxkIHNpbGVudGx5IGV4aXQKKyAgICAgICAgY29ubmVjdGlvbi5jb25uZWN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgcG9zc2liaWxpdHkgdG8gc2V0IHVwIHRoZSBkZWZhdWx0IFNTTFNvY2tldEZhY3RvcnkKKyAgICAgKiB0byBiZSB1c2VkIGJ5IEh0dHBzVVJMQ29ubmVjdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0RGVmYXVsdFNTTFNvY2tldEZhY3RvcnkoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgLy8gY3JlYXRlIHRoZSBTU0xTZXJ2ZXJTb2NrZXQgd2hpY2ggd2lsbCBiZSB1c2VkIGJ5IHNlcnZlciBzaWRlCisgICAgICAgIFNTTENvbnRleHQgY3R4ID0gZ2V0Q29udGV4dCgpOworICAgICAgICBTU0xTZXJ2ZXJTb2NrZXQgc3MgPSAoU1NMU2VydmVyU29ja2V0KSBjdHguZ2V0U2VydmVyU29ja2V0RmFjdG9yeSgpLmNyZWF0ZVNlcnZlclNvY2tldCgwKTsKKworICAgICAgICBTU0xTb2NrZXRGYWN0b3J5IHNvY2tldEZhY3RvcnkgPSAoU1NMU29ja2V0RmFjdG9yeSkgY3R4LmdldFNvY2tldEZhY3RvcnkoKTsKKyAgICAgICAgLy8gc2V0IHVwIHRoZSBmYWN0b3J5IGFzIGRlZmF1bHQKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uLnNldERlZmF1bHRTU0xTb2NrZXRGYWN0b3J5KHNvY2tldEZhY3RvcnkpOworICAgICAgICAvLyBjaGVjayB0aGUgcmVzdWx0CisgICAgICAgIGFzc2VydFNhbWUoIkRlZmF1bHQgU1NMU29ja2V0RmFjdG9yeSBkaWZmZXJzIGZyb20gZXhwZWN0ZWQiLAorICAgICAgICAgICAgICAgICAgIHNvY2tldEZhY3RvcnksIEh0dHBzVVJMQ29ubmVjdGlvbi5nZXREZWZhdWx0U1NMU29ja2V0RmFjdG9yeSgpKTsKKworICAgICAgICAvLyBjcmVhdGUgdGhlIEhvc3RuYW1lVmVyaWZpZXIgdG8gY2hlY2sgaG9zdG5hbWUgdmVyaWZpY2F0aW9uCisgICAgICAgIFRlc3RIb3N0bmFtZVZlcmlmaWVyIGhudiA9IG5ldyBUZXN0SG9zdG5hbWVWZXJpZmllcigpOworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24uc2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoaG52KTsKKworICAgICAgICAvLyBjcmVhdGUgSHR0cHNVUkxDb25uZWN0aW9uIHRvIGJlIHRlc3RlZAorICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cHM6Ly9sb2NhbGhvc3Q6IiArIHNzLmdldExvY2FsUG9ydCgpKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKworICAgICAgICBUZXN0SG9zdG5hbWVWZXJpZmllciBobnZfbGF0ZSA9IG5ldyBUZXN0SG9zdG5hbWVWZXJpZmllcigpOworICAgICAgICAvLyBsYXRlIGluaXRpYWxpemF0aW9uOiBzaG91bGQgbm90IGJlIHVzZWQgZm9yIGNyZWF0ZWQgY29ubmVjdGlvbgorICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24uc2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoaG52X2xhdGUpOworCisgICAgICAgIC8vIHBlcmZvcm0gdGhlIGludGVyYWN0aW9uIGJldHdlZW4gdGhlIHBlZXJzCisgICAgICAgIFNTTFNvY2tldCBwZWVyU29ja2V0ID0gKFNTTFNvY2tldCkgZG9JbnRlcmFjdGlvbihjb25uZWN0aW9uLCBzcyk7CisgICAgICAgIC8vIGNoZWNrIHRoZSBjb25uZWN0aW9uIHN0YXRlCisgICAgICAgIGNoZWNrQ29ubmVjdGlvblN0YXRlUGFyYW1ldGVycyhjb25uZWN0aW9uLCBwZWVyU29ja2V0KTsKKyAgICAgICAgLy8gY2hlY2sgdGhlIHZlcmlmaWNhdGlvbiBwcm9jZXNzCisgICAgICAgIGFzc2VydFRydWUoIkhvc3RuYW1lIHZlcmlmaWNhdGlvbiB3YXMgbm90IGRvbmUiLCBobnYudmVyaWZpZWQpOworICAgICAgICBhc3NlcnRGYWxzZSgiSG9zdG5hbWUgdmVyaWZpY2F0aW9uIHNob3VsZCBub3QgYmUgZG9uZSBieSB0aGlzIHZlcmlmaWVyIiwKKyAgICAgICAgICAgICAgICAgICAgaG52X2xhdGUudmVyaWZpZWQpOworICAgICAgICAvLyBjaGVjayB0aGUgdXNlZCBTU0xTb2NrZXRGYWN0b3J5CisgICAgICAgIGFzc2VydFNhbWUoIkRlZmF1bHQgU1NMU29ja2V0RmFjdG9yeSBzaG91bGQgYmUgdXNlZCIsCisgICAgICAgICAgICAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uLmdldERlZmF1bHRTU0xTb2NrZXRGYWN0b3J5KCksCisgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbi5nZXRTU0xTb2NrZXRGYWN0b3J5KCkpOworCisgICAgICAgIC8vIHNob3VsZCBzaWxlbnRseSBleGl0CisgICAgICAgIGNvbm5lY3Rpb24uY29ubmVjdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHBvc3NpYmlsaXR5IHRvIHNldCB1cCB0aGUgU1NMU29ja2V0RmFjdG9yeQorICAgICAqIHRvIGJlIHVzZWQgYnkgSHR0cHNVUkxDb25uZWN0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRTU0xTb2NrZXRGYWN0b3J5KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIC8vIGNyZWF0ZSB0aGUgU1NMU2VydmVyU29ja2V0IHdoaWNoIHdpbGwgYmUgdXNlZCBieSBzZXJ2ZXIgc2lkZQorICAgICAgICBTU0xDb250ZXh0IGN0eCA9IGdldENvbnRleHQoKTsKKyAgICAgICAgU1NMU2VydmVyU29ja2V0IHNzID0gKFNTTFNlcnZlclNvY2tldCkgY3R4LmdldFNlcnZlclNvY2tldEZhY3RvcnkoKS5jcmVhdGVTZXJ2ZXJTb2NrZXQoMCk7CisKKyAgICAgICAgLy8gY3JlYXRlIHRoZSBIb3N0bmFtZVZlcmlmaWVyIHRvIGNoZWNrIGhvc3RuYW1lIHZlcmlmaWNhdGlvbgorICAgICAgICBUZXN0SG9zdG5hbWVWZXJpZmllciBobnYgPSBuZXcgVGVzdEhvc3RuYW1lVmVyaWZpZXIoKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uLnNldERlZmF1bHRIb3N0bmFtZVZlcmlmaWVyKGhudik7CisKKyAgICAgICAgLy8gY3JlYXRlIEh0dHBzVVJMQ29ubmVjdGlvbiB0byBiZSB0ZXN0ZWQKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHBzOi8vbG9jYWxob3N0OiIgKyBzcy5nZXRMb2NhbFBvcnQoKSk7CisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCk7CisKKyAgICAgICAgU1NMU29ja2V0RmFjdG9yeSBzb2NrZXRGYWN0b3J5ID0gKFNTTFNvY2tldEZhY3RvcnkpIGN0eC5nZXRTb2NrZXRGYWN0b3J5KCk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0U1NMU29ja2V0RmFjdG9yeShzb2NrZXRGYWN0b3J5KTsKKworICAgICAgICBUZXN0SG9zdG5hbWVWZXJpZmllciBobnZfbGF0ZSA9IG5ldyBUZXN0SG9zdG5hbWVWZXJpZmllcigpOworICAgICAgICAvLyBsYXRlIGluaXRpYWxpemF0aW9uOiBzaG91bGQgbm90IGJlIHVzZWQgZm9yIGNyZWF0ZWQgY29ubmVjdGlvbgorICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24uc2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoaG52X2xhdGUpOworCisgICAgICAgIC8vIHBlcmZvcm0gdGhlIGludGVyYWN0aW9uIGJldHdlZW4gdGhlIHBlZXJzCisgICAgICAgIFNTTFNvY2tldCBwZWVyU29ja2V0ID0gKFNTTFNvY2tldCkgZG9JbnRlcmFjdGlvbihjb25uZWN0aW9uLCBzcyk7CisgICAgICAgIC8vIGNoZWNrIHRoZSBjb25uZWN0aW9uIHN0YXRlCisgICAgICAgIGNoZWNrQ29ubmVjdGlvblN0YXRlUGFyYW1ldGVycyhjb25uZWN0aW9uLCBwZWVyU29ja2V0KTsKKyAgICAgICAgLy8gY2hlY2sgdGhlIHZlcmlmaWNhdGlvbiBwcm9jZXNzCisgICAgICAgIGFzc2VydFRydWUoIkhvc3RuYW1lIHZlcmlmaWNhdGlvbiB3YXMgbm90IGRvbmUiLCBobnYudmVyaWZpZWQpOworICAgICAgICBhc3NlcnRGYWxzZSgiSG9zdG5hbWUgdmVyaWZpY2F0aW9uIHNob3VsZCBub3QgYmUgZG9uZSBieSB0aGlzIHZlcmlmaWVyIiwKKyAgICAgICAgICAgICAgICAgICAgaG52X2xhdGUudmVyaWZpZWQpOworICAgICAgICAvLyBjaGVjayB0aGUgdXNlZCBTU0xTb2NrZXRGYWN0b3J5CisgICAgICAgIGFzc2VydE5vdFNhbWUoIkRlZmF1bHQgU1NMU29ja2V0RmFjdG9yeSBzaG91bGQgbm90IGJlIHVzZWQiLAorICAgICAgICAgICAgICAgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbi5nZXREZWZhdWx0U1NMU29ja2V0RmFjdG9yeSgpLAorICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uZ2V0U1NMU29ja2V0RmFjdG9yeSgpKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiUmVzdWx0IGRpZmZlcnMgZnJvbSBleHBlY3RlZCIsCisgICAgICAgICAgICAgICAgICAgc29ja2V0RmFjdG9yeSwgY29ubmVjdGlvbi5nZXRTU0xTb2NrZXRGYWN0b3J5KCkpOworCisgICAgICAgIC8vIHNob3VsZCBzaWxlbnRseSBleGl0CisgICAgICAgIGNvbm5lY3Rpb24uY29ubmVjdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHRoZSBiZWhhdmlvdXIgb2YgSHR0cHNVUkxDb25uZWN0aW9uIGluIGNhc2Ugb2YgcmV0cmlldmluZworICAgICAqIG9mIHRoZSBjb25uZWN0aW9uIHN0YXRlIHBhcmFtZXRlcnMgYmVmb3JlIGNvbm5lY3Rpb24gaGFzIGJlZW4gbWFkZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VW5jb25uZWN0ZWRTdGF0ZVBhcmFtZXRlcnMoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgLy8gY3JlYXRlIEh0dHBzVVJMQ29ubmVjdGlvbiB0byBiZSB0ZXN0ZWQKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHBzOi8vbG9jYWxob3N0OjU1NTU1Iik7CisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uZ2V0Q2lwaGVyU3VpdGUoKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkge30KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uZ2V0UGVlclByaW5jaXBhbCgpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7fQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5nZXRMb2NhbFByaW5jaXBhbCgpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7fQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uZWN0aW9uLmdldFNlcnZlckNlcnRpZmljYXRlcygpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7fQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5nZXRMb2NhbENlcnRpZmljYXRlcygpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7fQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIGlmIHNldEhvc3RuYW1lVmVyaWZpZXIoKSBtZXRob2QgcmVwbGFjZXMgZGVmYXVsdCB2ZXJpZmllci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0SG9zdG5hbWVWZXJpZmllcigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICAvLyBzZXR0aW5nIHVwIHRoZSBwcm9wZXJ0aWVzIHBvaW50aW5nIHRvIHRoZSBrZXkvdHJ1c3Qgc3RvcmVzCisgICAgICAgIHNldFVwU3RvcmVQcm9wZXJ0aWVzKCk7CisKKyAgICAgICAgLy8gY3JlYXRlIHRoZSBTU0xTZXJ2ZXJTb2NrZXQgd2hpY2ggd2lsbCBiZSB1c2VkIGJ5IHNlcnZlciBzaWRlCisgICAgICAgIFNTTFNlcnZlclNvY2tldCBzcyA9IChTU0xTZXJ2ZXJTb2NrZXQpCisgICAgICAgICAgICAgICAgZ2V0Q29udGV4dCgpLmdldFNlcnZlclNvY2tldEZhY3RvcnkoKS5jcmVhdGVTZXJ2ZXJTb2NrZXQoMCk7CisKKyAgICAgICAgLy8gY3JlYXRlIHRoZSBIb3N0bmFtZVZlcmlmaWVyIHRvIGNoZWNrIHRoYXQgSG9zdG5hbWUgdmVyaWZpY2F0aW9uCisgICAgICAgIC8vIGlzIGRvbmUKKyAgICAgICAgVGVzdEhvc3RuYW1lVmVyaWZpZXIgaG52ID0gbmV3IFRlc3RIb3N0bmFtZVZlcmlmaWVyKCk7CisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbi5zZXREZWZhdWx0SG9zdG5hbWVWZXJpZmllcihobnYpOworCisgICAgICAgIC8vIGNyZWF0ZSBIdHRwc1VSTENvbm5lY3Rpb24gdG8gYmUgdGVzdGVkCisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwczovL2xvY2FsaG9zdDoiICsgc3MuZ2V0TG9jYWxQb3J0KCkpOworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwc1VSTENvbm5lY3Rpb24pIHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICBjb25uZWN0aW9uLnNldFNTTFNvY2tldEZhY3RvcnkoZ2V0Q29udGV4dCgpLmdldFNvY2tldEZhY3RvcnkoKSk7CisKKyAgICAgICAgVGVzdEhvc3RuYW1lVmVyaWZpZXIgaG52X2xhdGUgPSBuZXcgVGVzdEhvc3RuYW1lVmVyaWZpZXIoKTsKKyAgICAgICAgLy8gcmVwbGFjZSBkZWZhdWx0IHZlcmlmaWVyCisgICAgICAgIGNvbm5lY3Rpb24uc2V0SG9zdG5hbWVWZXJpZmllcihobnZfbGF0ZSk7CisKKyAgICAgICAgLy8gcGVyZm9ybSB0aGUgaW50ZXJhY3Rpb24gYmV0d2VlbiB0aGUgcGVlcnMgYW5kIGNoZWNrIHRoZSByZXN1bHRzCisgICAgICAgIFNTTFNvY2tldCBwZWVyU29ja2V0ID0gKFNTTFNvY2tldCkgZG9JbnRlcmFjdGlvbihjb25uZWN0aW9uLCBzcyk7CisgICAgICAgIGFzc2VydFRydWUoIkhvc3RuYW1lIHZlcmlmaWNhdGlvbiB3YXMgbm90IGRvbmUiLCBobnZfbGF0ZS52ZXJpZmllZCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJIb3N0bmFtZSB2ZXJpZmljYXRpb24gc2hvdWxkIG5vdCBiZSBkb25lIGJ5IHRoaXMgdmVyaWZpZXIiLAorICAgICAgICAgICAgICAgICAgICBobnYudmVyaWZpZWQpOworICAgICAgICBjaGVja0Nvbm5lY3Rpb25TdGF0ZVBhcmFtZXRlcnMoY29ubmVjdGlvbiwgcGVlclNvY2tldCk7CisKKyAgICAgICAgLy8gc2hvdWxkIHNpbGVudGx5IGV4aXQKKyAgICAgICAgY29ubmVjdGlvbi5jb25uZWN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgdGhlIGJlaGF2aW91ciBpbiBjYXNlIG9mIHNlbmRpbmcgdGhlIGRhdGEgdG8gdGhlIHNlcnZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RvT3V0cHV0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIC8vIHNldHRpbmcgdXAgdGhlIHByb3BlcnRpZXMgcG9pbnRpbmcgdG8gdGhlIGtleS90cnVzdCBzdG9yZXMKKyAgICAgICAgc2V0VXBTdG9yZVByb3BlcnRpZXMoKTsKKworICAgICAgICAvLyBjcmVhdGUgdGhlIFNTTFNlcnZlclNvY2tldCB3aGljaCB3aWxsIGJlIHVzZWQgYnkgc2VydmVyIHNpZGUKKyAgICAgICAgU1NMU2VydmVyU29ja2V0IHNzID0gKFNTTFNlcnZlclNvY2tldCkKKyAgICAgICAgICAgICAgICBnZXRDb250ZXh0KCkuZ2V0U2VydmVyU29ja2V0RmFjdG9yeSgpLmNyZWF0ZVNlcnZlclNvY2tldCgwKTsKKworICAgICAgICAvLyBjcmVhdGUgdGhlIEhvc3RuYW1lVmVyaWZpZXIgdG8gY2hlY2sgdGhhdCBIb3N0bmFtZSB2ZXJpZmljYXRpb24KKyAgICAgICAgLy8gaXMgZG9uZQorICAgICAgICBUZXN0SG9zdG5hbWVWZXJpZmllciBobnYgPSBuZXcgVGVzdEhvc3RuYW1lVmVyaWZpZXIoKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uLnNldERlZmF1bHRIb3N0bmFtZVZlcmlmaWVyKGhudik7CisKKyAgICAgICAgLy8gY3JlYXRlIEh0dHBzVVJMQ29ubmVjdGlvbiB0byBiZSB0ZXN0ZWQKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHBzOi8vbG9jYWxob3N0OiIgKyBzcy5nZXRMb2NhbFBvcnQoKSk7CisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0U1NMU29ja2V0RmFjdG9yeShnZXRDb250ZXh0KCkuZ2V0U29ja2V0RmFjdG9yeSgpKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXREb091dHB1dCh0cnVlKTsKKworICAgICAgICAvLyBwZXJmb3JtIHRoZSBpbnRlcmFjdGlvbiBiZXR3ZWVuIHRoZSBwZWVycyBhbmQgY2hlY2sgdGhlIHJlc3VsdHMKKyAgICAgICAgU1NMU29ja2V0IHBlZXJTb2NrZXQgPSAoU1NMU29ja2V0KSBkb0ludGVyYWN0aW9uKGNvbm5lY3Rpb24sIHNzKTsKKyAgICAgICAgY2hlY2tDb25uZWN0aW9uU3RhdGVQYXJhbWV0ZXJzKGNvbm5lY3Rpb24sIHBlZXJTb2NrZXQpOworCisgICAgICAgIC8vIHNob3VsZCBzaWxlbnRseSBleGl0CisgICAgICAgIGNvbm5lY3Rpb24uY29ubmVjdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIEhUVFBTIGNvbm5lY3Rpb24gcHJvY2VzcyBtYWRlIHRocm91Z2ggdGhlIHByb3h5IHNlcnZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJveHlDb25uZWN0aW9uKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIC8vIHNldHRpbmcgdXAgdGhlIHByb3BlcnRpZXMgcG9pbnRpbmcgdG8gdGhlIGtleS90cnVzdCBzdG9yZXMKKyAgICAgICAgc2V0VXBTdG9yZVByb3BlcnRpZXMoKTsKKworICAgICAgICAvLyBjcmVhdGUgdGhlIFNTTFNlcnZlclNvY2tldCB3aGljaCB3aWxsIGJlIHVzZWQgYnkgc2VydmVyIHNpZGUKKyAgICAgICAgU2VydmVyU29ja2V0IHNzID0gbmV3IFNlcnZlclNvY2tldCgwKTsKKworICAgICAgICAvLyBjcmVhdGUgdGhlIEhvc3RuYW1lVmVyaWZpZXIgdG8gY2hlY2sgdGhhdCBIb3N0bmFtZSB2ZXJpZmljYXRpb24KKyAgICAgICAgLy8gaXMgZG9uZQorICAgICAgICBUZXN0SG9zdG5hbWVWZXJpZmllciBobnYgPSBuZXcgVGVzdEhvc3RuYW1lVmVyaWZpZXIoKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uLnNldERlZmF1bHRIb3N0bmFtZVZlcmlmaWVyKGhudik7CisKKyAgICAgICAgLy8gY3JlYXRlIEh0dHBzVVJMQ29ubmVjdGlvbiB0byBiZSB0ZXN0ZWQKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHBzOi8vcmVxdWVzdGVkLmhvc3Q6NTU1NTYvcmVxdWVzdGVkLmRhdGEiKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKQorICAgICAgICAgICAgICAgIHVybC5vcGVuQ29ubmVjdGlvbihuZXcgUHJveHkoUHJveHkuVHlwZS5IVFRQLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEluZXRTb2NrZXRBZGRyZXNzKCJsb2NhbGhvc3QiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNzLmdldExvY2FsUG9ydCgpKSkpOworICAgICAgICBjb25uZWN0aW9uLnNldFNTTFNvY2tldEZhY3RvcnkoZ2V0Q29udGV4dCgpLmdldFNvY2tldEZhY3RvcnkoKSk7CisKKyAgICAgICAgLy8gcGVyZm9ybSB0aGUgaW50ZXJhY3Rpb24gYmV0d2VlbiB0aGUgcGVlcnMgYW5kIGNoZWNrIHRoZSByZXN1bHRzCisgICAgICAgIFNTTFNvY2tldCBwZWVyU29ja2V0ID0gKFNTTFNvY2tldCkgZG9JbnRlcmFjdGlvbihjb25uZWN0aW9uLCBzcyk7CisgICAgICAgIGNoZWNrQ29ubmVjdGlvblN0YXRlUGFyYW1ldGVycyhjb25uZWN0aW9uLCBwZWVyU29ja2V0KTsKKworICAgICAgICAvLyBzaG91bGQgc2lsZW50bHkgZXhpdAorICAgICAgICBjb25uZWN0aW9uLmNvbm5lY3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBIVFRQUyBjb25uZWN0aW9uIHByb2Nlc3MgbWFkZSB0aHJvdWdoIHRoZSBwcm94eSBzZXJ2ZXIuCisgICAgICogUHJveHkgc2VydmVyIG5lZWRzIGF1dGhlbnRpY2F0aW9uLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RQcm94eUF1dGhDb25uZWN0aW9uKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIC8vIHNldHRpbmcgdXAgdGhlIHByb3BlcnRpZXMgcG9pbnRpbmcgdG8gdGhlIGtleS90cnVzdCBzdG9yZXMKKyAgICAgICAgc2V0VXBTdG9yZVByb3BlcnRpZXMoKTsKKworICAgICAgICAvLyBjcmVhdGUgdGhlIFNTTFNlcnZlclNvY2tldCB3aGljaCB3aWxsIGJlIHVzZWQgYnkgc2VydmVyIHNpZGUKKyAgICAgICAgU2VydmVyU29ja2V0IHNzID0gbmV3IFNlcnZlclNvY2tldCgwKTsKKworICAgICAgICAvLyBjcmVhdGUgdGhlIEhvc3RuYW1lVmVyaWZpZXIgdG8gY2hlY2sgdGhhdCBIb3N0bmFtZSB2ZXJpZmljYXRpb24KKyAgICAgICAgLy8gaXMgZG9uZQorICAgICAgICBUZXN0SG9zdG5hbWVWZXJpZmllciBobnYgPSBuZXcgVGVzdEhvc3RuYW1lVmVyaWZpZXIoKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uLnNldERlZmF1bHRIb3N0bmFtZVZlcmlmaWVyKGhudik7CisKKyAgICAgICAgQXV0aGVudGljYXRvci5zZXREZWZhdWx0KG5ldyBBdXRoZW50aWNhdG9yKCkgeworCisgICAgICAgICAgICBwcm90ZWN0ZWQgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiBnZXRQYXNzd29yZEF1dGhlbnRpY2F0aW9uKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUGFzc3dvcmRBdXRoZW50aWNhdGlvbigidXNlciIsICJwYXNzd29yZCIKKyAgICAgICAgICAgICAgICAgICAgICAgIC50b0NoYXJBcnJheSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisKKyAgICAgICAgLy8gY3JlYXRlIEh0dHBzVVJMQ29ubmVjdGlvbiB0byBiZSB0ZXN0ZWQKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHBzOi8vcmVxdWVzdGVkLmhvc3Q6NTU1NTUvcmVxdWVzdGVkLmRhdGEiKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKQorICAgICAgICAgICAgICAgIHVybC5vcGVuQ29ubmVjdGlvbihuZXcgUHJveHkoUHJveHkuVHlwZS5IVFRQLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEluZXRTb2NrZXRBZGRyZXNzKCJsb2NhbGhvc3QiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNzLmdldExvY2FsUG9ydCgpKSkpOworICAgICAgICBjb25uZWN0aW9uLnNldFNTTFNvY2tldEZhY3RvcnkoZ2V0Q29udGV4dCgpLmdldFNvY2tldEZhY3RvcnkoKSk7CisKKyAgICAgICAgLy8gcGVyZm9ybSB0aGUgaW50ZXJhY3Rpb24gYmV0d2VlbiB0aGUgcGVlcnMgYW5kIGNoZWNrIHRoZSByZXN1bHRzCisgICAgICAgIFNTTFNvY2tldCBwZWVyU29ja2V0ID0gKFNTTFNvY2tldCkgZG9JbnRlcmFjdGlvbihjb25uZWN0aW9uLCBzcyk7CisgICAgICAgIGNoZWNrQ29ubmVjdGlvblN0YXRlUGFyYW1ldGVycyhjb25uZWN0aW9uLCBwZWVyU29ja2V0KTsKKworICAgICAgICAvLyBzaG91bGQgc2lsZW50bHkgZXhpdAorICAgICAgICBjb25uZWN0aW9uLmNvbm5lY3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBIVFRQUyBjb25uZWN0aW9uIHByb2Nlc3MgbWFkZSB0aHJvdWdoIHRoZSBwcm94eSBzZXJ2ZXIuCisgICAgICogMiBIVFRQUyBjb25uZWN0aW9ucyBhcmUgb3BlbmVkIGZvciBvbmUgVVJMLiBGb3IgdGhlIGZpcnN0IHRpbWUKKyAgICAgKiB0aGUgY29ubmVjdGlvbiBpcyBvcGVuZWQgdGhyb3VnaCBvbmUgcHJveHksCisgICAgICogZm9yIHRoZSBzZWNvbmQgdGltZSB0aHJvdWdoIGFub3RoZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENvbnNlcXVlbnRQcm94eUNvbm5lY3Rpb24oKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgLy8gc2V0dGluZyB1cCB0aGUgcHJvcGVydGllcyBwb2ludGluZyB0byB0aGUga2V5L3RydXN0IHN0b3JlcworICAgICAgICBzZXRVcFN0b3JlUHJvcGVydGllcygpOworCisgICAgICAgIC8vIGNyZWF0ZSB0aGUgU1NMU2VydmVyU29ja2V0IHdoaWNoIHdpbGwgYmUgdXNlZCBieSBzZXJ2ZXIgc2lkZQorICAgICAgICBTZXJ2ZXJTb2NrZXQgc3MgPSBuZXcgU2VydmVyU29ja2V0KDApOworCisgICAgICAgIC8vIGNyZWF0ZSB0aGUgSG9zdG5hbWVWZXJpZmllciB0byBjaGVjayB0aGF0IEhvc3RuYW1lIHZlcmlmaWNhdGlvbgorICAgICAgICAvLyBpcyBkb25lCisgICAgICAgIFRlc3RIb3N0bmFtZVZlcmlmaWVyIGhudiA9IG5ldyBUZXN0SG9zdG5hbWVWZXJpZmllcigpOworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24uc2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoaG52KTsKKworICAgICAgICAvLyBjcmVhdGUgSHR0cHNVUkxDb25uZWN0aW9uIHRvIGJlIHRlc3RlZAorICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cHM6Ly9yZXF1ZXN0ZWQuaG9zdDo1NTU1NS9yZXF1ZXN0ZWQuZGF0YSIpOworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwc1VSTENvbm5lY3Rpb24pCisgICAgICAgICAgICAgICAgdXJsLm9wZW5Db25uZWN0aW9uKG5ldyBQcm94eShQcm94eS5UeXBlLkhUVFAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoImxvY2FsaG9zdCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3MuZ2V0TG9jYWxQb3J0KCkpKSk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0U1NMU29ja2V0RmFjdG9yeShnZXRDb250ZXh0KCkuZ2V0U29ja2V0RmFjdG9yeSgpKTsKKworICAgICAgICAvLyBwZXJmb3JtIHRoZSBpbnRlcmFjdGlvbiBiZXR3ZWVuIHRoZSBwZWVycyBhbmQgY2hlY2sgdGhlIHJlc3VsdHMKKyAgICAgICAgU1NMU29ja2V0IHBlZXJTb2NrZXQgPSAoU1NMU29ja2V0KSBkb0ludGVyYWN0aW9uKGNvbm5lY3Rpb24sIHNzKTsKKyAgICAgICAgY2hlY2tDb25uZWN0aW9uU3RhdGVQYXJhbWV0ZXJzKGNvbm5lY3Rpb24sIHBlZXJTb2NrZXQpOworCisgICAgICAgIC8vIGNyZWF0ZSBhbm90aGVyIFNTTFNlcnZlclNvY2tldCB3aGljaCB3aWxsIGJlIHVzZWQgYnkgc2VydmVyIHNpZGUKKyAgICAgICAgc3MgPSBuZXcgU2VydmVyU29ja2V0KDApOworCisgICAgICAgIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKSB1cmwub3BlbkNvbm5lY3Rpb24obmV3IFByb3h5KAorICAgICAgICAgICAgICAgIFByb3h5LlR5cGUuSFRUUCwgbmV3IEluZXRTb2NrZXRBZGRyZXNzKCJsb2NhbGhvc3QiLCBzcy5nZXRMb2NhbFBvcnQoKSkpKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXRTU0xTb2NrZXRGYWN0b3J5KGdldENvbnRleHQoKS5nZXRTb2NrZXRGYWN0b3J5KCkpOworCisgICAgICAgIC8vIHBlcmZvcm0gdGhlIGludGVyYWN0aW9uIGJldHdlZW4gdGhlIHBlZXJzIGFuZCBjaGVjayB0aGUgcmVzdWx0cworICAgICAgICBwZWVyU29ja2V0ID0gKFNTTFNvY2tldCkgZG9JbnRlcmFjdGlvbihjb25uZWN0aW9uLCBzcyk7CisgICAgICAgIGNoZWNrQ29ubmVjdGlvblN0YXRlUGFyYW1ldGVycyhjb25uZWN0aW9uLCBwZWVyU29ja2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBIVFRQUyBjb25uZWN0aW9uIHByb2Nlc3MgbWFkZSB0aHJvdWdoIHRoZSBwcm94eSBzZXJ2ZXIuCisgICAgICogUHJveHkgc2VydmVyIG5lZWRzIGF1dGhlbnRpY2F0aW9uLgorICAgICAqIENsaWVudCBzZW5kcyBkYXRhIHRvIHRoZSBzZXJ2ZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFByb3h5QXV0aENvbm5lY3Rpb25fZG9PdXRwdXQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgLy8gc2V0dGluZyB1cCB0aGUgcHJvcGVydGllcyBwb2ludGluZyB0byB0aGUga2V5L3RydXN0IHN0b3JlcworICAgICAgICBzZXRVcFN0b3JlUHJvcGVydGllcygpOworCisgICAgICAgIC8vIGNyZWF0ZSB0aGUgU1NMU2VydmVyU29ja2V0IHdoaWNoIHdpbGwgYmUgdXNlZCBieSBzZXJ2ZXIgc2lkZQorICAgICAgICBTZXJ2ZXJTb2NrZXQgc3MgPSBuZXcgU2VydmVyU29ja2V0KDApOworCisgICAgICAgIC8vIGNyZWF0ZSB0aGUgSG9zdG5hbWVWZXJpZmllciB0byBjaGVjayB0aGF0IEhvc3RuYW1lIHZlcmlmaWNhdGlvbgorICAgICAgICAvLyBpcyBkb25lCisgICAgICAgIFRlc3RIb3N0bmFtZVZlcmlmaWVyIGhudiA9IG5ldyBUZXN0SG9zdG5hbWVWZXJpZmllcigpOworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24uc2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoaG52KTsKKworICAgICAgICBBdXRoZW50aWNhdG9yLnNldERlZmF1bHQobmV3IEF1dGhlbnRpY2F0b3IoKSB7CisKKyAgICAgICAgICAgIHByb3RlY3RlZCBQYXNzd29yZEF1dGhlbnRpY2F0aW9uIGdldFBhc3N3b3JkQXV0aGVudGljYXRpb24oKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBQYXNzd29yZEF1dGhlbnRpY2F0aW9uKCJ1c2VyIiwgInBhc3N3b3JkIgorICAgICAgICAgICAgICAgICAgICAgICAgLnRvQ2hhckFycmF5KCkpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKworICAgICAgICAvLyBjcmVhdGUgSHR0cHNVUkxDb25uZWN0aW9uIHRvIGJlIHRlc3RlZAorICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cHM6Ly9yZXF1ZXN0ZWQuaG9zdDo1NTU1NC9yZXF1ZXN0ZWQuZGF0YSIpOworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwc1VSTENvbm5lY3Rpb24pCisgICAgICAgICAgICAgICAgdXJsLm9wZW5Db25uZWN0aW9uKG5ldyBQcm94eShQcm94eS5UeXBlLkhUVFAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW5ldFNvY2tldEFkZHJlc3MoImxvY2FsaG9zdCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3MuZ2V0TG9jYWxQb3J0KCkpKSk7CisgICAgICAgIGNvbm5lY3Rpb24uc2V0U1NMU29ja2V0RmFjdG9yeShnZXRDb250ZXh0KCkuZ2V0U29ja2V0RmFjdG9yeSgpKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXREb091dHB1dCh0cnVlKTsKKworICAgICAgICAvLyBwZXJmb3JtIHRoZSBpbnRlcmFjdGlvbiBiZXR3ZWVuIHRoZSBwZWVycyBhbmQgY2hlY2sgdGhlIHJlc3VsdHMKKyAgICAgICAgU1NMU29ja2V0IHBlZXJTb2NrZXQgPSAoU1NMU29ja2V0KSBkb0ludGVyYWN0aW9uKGNvbm5lY3Rpb24sIHNzLCBPS19DT0RFLCB0cnVlKTsKKyAgICAgICAgY2hlY2tDb25uZWN0aW9uU3RhdGVQYXJhbWV0ZXJzKGNvbm5lY3Rpb24sIHBlZXJTb2NrZXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIEhUVFBTIGNvbm5lY3Rpb24gcHJvY2VzcyBtYWRlIHRocm91Z2ggdGhlIHByb3h5IHNlcnZlci4KKyAgICAgKiBQcm94eSBzZXJ2ZXIgbmVlZHMgYXV0aGVudGljYXRpb24gYnV0IGNsaWVudCBmYWlscyB0byBhdXRoZW50aWNhdGUKKyAgICAgKiAoQXV0aGVudGljYXRvciB3YXMgbm90IHNldCB1cCBpbiB0aGUgc3lzdGVtKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJveHlBdXRoQ29ubmVjdGlvbkZhaWxlZCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICAvLyBzZXR0aW5nIHVwIHRoZSBwcm9wZXJ0aWVzIHBvaW50aW5nIHRvIHRoZSBrZXkvdHJ1c3Qgc3RvcmVzCisgICAgICAgIHNldFVwU3RvcmVQcm9wZXJ0aWVzKCk7CisKKyAgICAgICAgLy8gY3JlYXRlIHRoZSBTU0xTZXJ2ZXJTb2NrZXQgd2hpY2ggd2lsbCBiZSB1c2VkIGJ5IHNlcnZlciBzaWRlCisgICAgICAgIFNlcnZlclNvY2tldCBzcyA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisKKyAgICAgICAgLy8gY3JlYXRlIHRoZSBIb3N0bmFtZVZlcmlmaWVyIHRvIGNoZWNrIHRoYXQgSG9zdG5hbWUgdmVyaWZpY2F0aW9uCisgICAgICAgIC8vIGlzIGRvbmUKKyAgICAgICAgVGVzdEhvc3RuYW1lVmVyaWZpZXIgaG52ID0gbmV3IFRlc3RIb3N0bmFtZVZlcmlmaWVyKCk7CisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbi5zZXREZWZhdWx0SG9zdG5hbWVWZXJpZmllcihobnYpOworCisgICAgICAgIC8vIGNyZWF0ZSBIdHRwc1VSTENvbm5lY3Rpb24gdG8gYmUgdGVzdGVkCisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwczovL3JlcXVlc3RlZC5ob3N0OjU1NTU1L3JlcXVlc3RlZC5kYXRhIik7CisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikKKyAgICAgICAgICAgICAgICB1cmwub3BlbkNvbm5lY3Rpb24obmV3IFByb3h5KFByb3h5LlR5cGUuSFRUUCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbmV0U29ja2V0QWRkcmVzcygibG9jYWxob3N0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcy5nZXRMb2NhbFBvcnQoKSkpKTsKKyAgICAgICAgY29ubmVjdGlvbi5zZXRTU0xTb2NrZXRGYWN0b3J5KGdldENvbnRleHQoKS5nZXRTb2NrZXRGYWN0b3J5KCkpOworCisgICAgICAgIC8vIHBlcmZvcm0gdGhlIGludGVyYWN0aW9uIGJldHdlZW4gdGhlIHBlZXJzIGFuZCBjaGVjayB0aGUgcmVzdWx0cworICAgICAgICB0cnkgeworICAgICAgICAgICAgZG9JbnRlcmFjdGlvbihjb25uZWN0aW9uLCBzcywgQVVUSEVOVElDQVRJT05fUkVRVUlSRURfQ09ERSwgdHJ1ZSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIFNTTCBUdW5uZWxsaW5nIGZhaWxlZAorICAgICAgICAgICAgaWYgKERPX0xPRykgeworICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiR290IGV4cGVjdGVkIElPRXhjZXB0aW9uOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgdGhlIGJlaGF2aW91ciBvZiBIVFRQUyBjb25uZWN0aW9uIGluIGNhc2Ugb2YgdW5hdmFpbGFiaWxpdHkKKyAgICAgKiBvZiByZXF1ZXN0ZWQgcmVzb3VyY2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFByb3h5Q29ubmVjdGlvbl9Ob3RfRm91bmRfUmVzcG9uc2UoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgLy8gc2V0dGluZyB1cCB0aGUgcHJvcGVydGllcyBwb2ludGluZyB0byB0aGUga2V5L3RydXN0IHN0b3JlcworICAgICAgICBzZXRVcFN0b3JlUHJvcGVydGllcygpOworCisgICAgICAgIC8vIGNyZWF0ZSB0aGUgU1NMU2VydmVyU29ja2V0IHdoaWNoIHdpbGwgYmUgdXNlZCBieSBzZXJ2ZXIgc2lkZQorICAgICAgICBTZXJ2ZXJTb2NrZXQgc3MgPSBuZXcgU2VydmVyU29ja2V0KDApOworCisgICAgICAgIC8vIGNyZWF0ZSB0aGUgSG9zdG5hbWVWZXJpZmllciB0byBjaGVjayB0aGF0IEhvc3RuYW1lIHZlcmlmaWNhdGlvbgorICAgICAgICAvLyBpcyBkb25lCisgICAgICAgIFRlc3RIb3N0bmFtZVZlcmlmaWVyIGhudiA9IG5ldyBUZXN0SG9zdG5hbWVWZXJpZmllcigpOworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24uc2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoaG52KTsKKworICAgICAgICAvLyBjcmVhdGUgSHR0cHNVUkxDb25uZWN0aW9uIHRvIGJlIHRlc3RlZAorICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cHM6Ly9sb2NhbGhvc3Q6IiArIHNzLmdldExvY2FsUG9ydCgpKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKQorICAgICAgICAgICAgICAgIHVybC5vcGVuQ29ubmVjdGlvbihuZXcgUHJveHkoUHJveHkuVHlwZS5IVFRQLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEluZXRTb2NrZXRBZGRyZXNzKCJsb2NhbGhvc3QiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNzLmdldExvY2FsUG9ydCgpKSkpOworICAgICAgICBjb25uZWN0aW9uLnNldFNTTFNvY2tldEZhY3RvcnkoZ2V0Q29udGV4dCgpLmdldFNvY2tldEZhY3RvcnkoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRvSW50ZXJhY3Rpb24oY29ubmVjdGlvbiwgc3MsIE5PVF9GT1VORF9DT0RFKTsgLy8gTk9UIEZPVU5ECisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBleGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAoRE9fTE9HKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFeHBlY3RlZCBleGNlcHRpb24gd2FzIHRocm93bjogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIExvZyB0aGUgbmFtZSBvZiB0aGUgdGVzdCBjYXNlIHRvIGJlIGV4ZWN1dGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisKKyAgICAgICAgaWYgKERPX0xPRykgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0gIiArIGdldE5hbWUoKSk7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHN0b3JlICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN0cmluZyBrc0ZpbGVOYW1lID0gKCJvcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9rZXlfc3RvcmUuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpLnRvTG93ZXJDYXNlKCkpOworICAgICAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBnZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbShrc0ZpbGVOYW1lKTsKKyAgICAgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oc3RvcmUpOworICAgICAgICAgICAgQnVmZmVyZWRJbnB1dFN0cmVhbSBidWZJbiA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGluLCA4MTkyKTsKKyAgICAgICAgICAgIHdoaWxlIChidWZJbi5hdmFpbGFibGUoKSA+IDApIHsKKyAgICAgICAgICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbMTI4XTsKKyAgICAgICAgICAgICAgICBpbnQgcmVhZCA9IGJ1ZkluLnJlYWQoYnVmKTsKKyAgICAgICAgICAgICAgICBvdXQud3JpdGUoYnVmLCAwLCByZWFkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ1ZkluLmNsb3NlKCk7CisgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZhaWwoImNvdWxkbid0IHNldCB1cCBrZXkgc3RvcmUiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlYXJEb3duKCkgeworICAgICAgICBpZiAoc3RvcmUgIT0gbnVsbCkgeworICAgICAgICAgICAgc3RvcmUuZGVsZXRlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgdGhlIEh0dHBzVVJMQ29ubmVjdGlvbiBnZXR0ZXIncyB2YWx1ZXMgYW5kIGNvbXBhcmVzCisgICAgICogdGhlbSB3aXRoIGFjdHVhbCBjb3JyZXNwb25kaW5nIHZhbHVlcyBvZiByZW1vdGUgcGVlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgY2hlY2tDb25uZWN0aW9uU3RhdGVQYXJhbWV0ZXJzKAorICAgICAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNsaWVudENvbm5lY3Rpb24sIFNTTFNvY2tldCBzZXJ2ZXJQZWVyKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNTTFNlc3Npb24gc2Vzc2lvbiA9IHNlcnZlclBlZXIuZ2V0U2Vzc2lvbigpOworCisgICAgICAgIGFzc2VydEVxdWFscyhzZXNzaW9uLmdldENpcGhlclN1aXRlKCksIGNsaWVudENvbm5lY3Rpb24uZ2V0Q2lwaGVyU3VpdGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzZXNzaW9uLmdldExvY2FsUHJpbmNpcGFsKCksIGNsaWVudENvbm5lY3Rpb24uZ2V0UGVlclByaW5jaXBhbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNlc3Npb24uZ2V0UGVlclByaW5jaXBhbCgpLCBjbGllbnRDb25uZWN0aW9uLmdldExvY2FsUHJpbmNpcGFsKCkpOworCisgICAgICAgIENlcnRpZmljYXRlW10gc2VydmVyQ2VydGlmaWNhdGVzID0gY2xpZW50Q29ubmVjdGlvbi5nZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKTsKKyAgICAgICAgQ2VydGlmaWNhdGVbXSBsb2NhbENlcnRpZmljYXRlcyA9IHNlc3Npb24uZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2VydmVyIGNlcnRpZmljYXRlcyBkaWZmZXIgZnJvbSBleHBlY3RlZCIsCisgICAgICAgICAgICAgICAgICAgQXJyYXlzLmVxdWFscyhzZXJ2ZXJDZXJ0aWZpY2F0ZXMsIGxvY2FsQ2VydGlmaWNhdGVzKSk7CisKKyAgICAgICAgbG9jYWxDZXJ0aWZpY2F0ZXMgPSBjbGllbnRDb25uZWN0aW9uLmdldExvY2FsQ2VydGlmaWNhdGVzKCk7CisgICAgICAgIHNlcnZlckNlcnRpZmljYXRlcyA9IHNlc3Npb24uZ2V0UGVlckNlcnRpZmljYXRlcygpOworICAgICAgICBhc3NlcnRUcnVlKCJMb2NhbCBjZXJ0aWZpY2F0ZXMgZGlmZmVyIGZyb20gZXhwZWN0ZWQiLAorICAgICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMoc2VydmVyQ2VydGlmaWNhdGVzLCBsb2NhbENlcnRpZmljYXRlcykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGZpbGUgbmFtZSBvZiB0aGUga2V5L3RydXN0IHN0b3JlLiBUaGUga2V5IHN0b3JlIGZpbGUKKyAgICAgKiAobmFtZWQgYXMgImtleV9zdG9yZS4iICsgZXh0ZW5zaW9uIGVxdWFscyB0byB0aGUgZGVmYXVsdCBLZXlTdG9yZQorICAgICAqIHR5cGUgaW5zdGFsbGVkIGluIHRoZSBzeXN0ZW0gaW4gbG93ZXIgY2FzZSkgaXMgc2VhcmNoZWQgaW4gY2xhc3NwYXRoLgorICAgICAqIEB0aHJvd3MganVuaXQuZnJhbWV3b3JrLkFzc2VydGlvbkZhaWxlZEVycm9yIGlmIHByb3BlcnR5IHdhcyBub3Qgc2V0CisgICAgICogb3IgZmlsZSBkb2VzIG5vdCBleGlzdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0S2V5U3RvcmVGaWxlTmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIHN0b3JlLmdldEFic29sdXRlUGF0aCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEJ1aWxkcyBhbmQgcmV0dXJucyB0aGUgY29udGV4dCB1c2VkIGZvciBzZWN1cmUgc29ja2V0IGNyZWF0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFNTTENvbnRleHQgZ2V0Q29udGV4dCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgdHlwZSA9IEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCk7CisgICAgICAgIFN0cmluZyBrZXlTdG9yZSA9IGdldEtleVN0b3JlRmlsZU5hbWUoKTsKKyAgICAgICAgRmlsZSBrZXlTdG9yZUZpbGUgPSBuZXcgRmlsZShrZXlTdG9yZSk7CisgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBmaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGtleVN0b3JlRmlsZSk7CisKKyAgICAgICAgS2V5U3RvcmUga3MgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZSh0eXBlKTsKKyAgICAgICAga3MubG9hZChmaXMsIEtTX1BBU1NXT1JELnRvQ2hhckFycmF5KCkpOworICAgICAgICBmaXMuY2xvc2UoKTsKKyAgICAgICAgaWYgKERPX0xPRyAmJiBmYWxzZSkgeworICAgICAgICAgICAgVGVzdEtleVN0b3JlLmR1bXAoIkh0dHBzVVJMQ29ubmVjdGlvbi5nZXRDb250ZXh0Iiwga3MsIEtTX1BBU1NXT1JELnRvQ2hhckFycmF5KCkpOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGttZkFsZ29yaXRobSA9IEtleU1hbmFnZXJGYWN0b3J5LmdldERlZmF1bHRBbGdvcml0aG0oKTsKKyAgICAgICAgS2V5TWFuYWdlckZhY3Rvcnkga21mID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2Uoa21mQWxnb3JpdGhtKTsKKyAgICAgICAga21mLmluaXQoa3MsIEtTX1BBU1NXT1JELnRvQ2hhckFycmF5KCkpOworICAgICAgICBLZXlNYW5hZ2VyW10ga2V5TWFuYWdlcnMgPSBrbWYuZ2V0S2V5TWFuYWdlcnMoKTsKKworICAgICAgICBTdHJpbmcgdG1mQWxnb3J0aG0gPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldERlZmF1bHRBbGdvcml0aG0oKTsKKyAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeSB0bWYgPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKHRtZkFsZ29ydGhtKTsKKyAgICAgICAgdG1mLmluaXQoa3MpOworICAgICAgICBUcnVzdE1hbmFnZXJbXSB0cnVzdE1hbmFnZXJzID0gdG1mLmdldFRydXN0TWFuYWdlcnMoKTsKKyAgICAgICAgaWYgKERPX0xPRykgeworICAgICAgICAgICAgdHJ1c3RNYW5hZ2VycyA9IFRlc3RUcnVzdE1hbmFnZXIud3JhcCh0cnVzdE1hbmFnZXJzKTsKKyAgICAgICAgfQorCisgICAgICAgIFNTTENvbnRleHQgY3R4ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZSgiVExTdjEiKTsKKyAgICAgICAgY3R4LmluaXQoa2V5TWFuYWdlcnMsIHRydXN0TWFuYWdlcnMsIG51bGwpOworICAgICAgICByZXR1cm4gY3R4OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdXAgdGhlIHByb3BlcnRpZXMgcG9pbnRpbmcgdG8gdGhlIGtleSBzdG9yZSBhbmQgdHJ1c3Qgc3RvcmUKKyAgICAgKiBhbmQgdXNlZCBhcyBkZWZhdWx0IHZhbHVlcyBieSBKU1NFIHN0YWZmLiBUaGlzIGlzIG5lZWRlZCB0byB0ZXN0CisgICAgICogSFRUUFMgYmVoYXZpb3VyIGluIHRoZSBjYXNlIG9mIGRlZmF1bHQgU1NMIFNvY2tldCBGYWN0b3JpZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBzZXRVcFN0b3JlUHJvcGVydGllcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgdHlwZSA9IEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCk7CisKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJqYXZheC5uZXQuc3NsLmtleVN0b3JlVHlwZSIsIHR5cGUpOworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoImphdmF4Lm5ldC5zc2wua2V5U3RvcmUiLCBnZXRLZXlTdG9yZUZpbGVOYW1lKCkpOworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoImphdmF4Lm5ldC5zc2wua2V5U3RvcmVQYXNzd29yZCIsIEtTX1BBU1NXT1JEKTsKKworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoImphdmF4Lm5ldC5zc2wudHJ1c3RTdG9yZVR5cGUiLCB0eXBlKTsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJqYXZheC5uZXQuc3NsLnRydXN0U3RvcmUiLCBnZXRLZXlTdG9yZUZpbGVOYW1lKCkpOworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoImphdmF4Lm5ldC5zc2wudHJ1c3RTdG9yZVBhc3N3b3JkIiwgS1NfUEFTU1dPUkQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGludGVyYWN0aW9uIGJldHdlZW4gY2xpZW50J3MgSHR0cHNVUkxDb25uZWN0aW9uIGFuZAorICAgICAqIHNlcnZlcnMgc2lkZSAoU2VydmVyU29ja2V0KS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNvY2tldCBkb0ludGVyYWN0aW9uKGZpbmFsIEh0dHBzVVJMQ29ubmVjdGlvbiBjbGllbnRDb25uZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU2VydmVyU29ja2V0IHNlcnZlclNvY2tldCkKKyAgICAgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICByZXR1cm4gZG9JbnRlcmFjdGlvbihjbGllbnRDb25uZWN0aW9uLCBzZXJ2ZXJTb2NrZXQsIE9LX0NPREUsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBpbnRlcmFjdGlvbiBiZXR3ZWVuIGNsaWVudCdzIEh0dHBzVVJMQ29ubmVjdGlvbiBhbmQKKyAgICAgKiBzZXJ2ZXJzIHNpZGUgKFNlcnZlclNvY2tldCkuIFNlcnZlciB3aWxsIHJlc3BvbnNlIHdpdGggc3BlY2lmaWVkCisgICAgICogcmVzcG9uc2UgY29kZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNvY2tldCBkb0ludGVyYWN0aW9uKGZpbmFsIEh0dHBzVVJMQ29ubmVjdGlvbiBjbGllbnRDb25uZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU2VydmVyU29ja2V0IHNlcnZlclNvY2tldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCByZXNwb25zZUNvZGUpCisgICAgICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgcmV0dXJuIGRvSW50ZXJhY3Rpb24oY2xpZW50Q29ubmVjdGlvbiwgc2VydmVyU29ja2V0LCByZXNwb25zZUNvZGUsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBpbnRlcmFjdGlvbiBiZXR3ZWVuIGNsaWVudCdzIEh0dHBzVVJMQ29ubmVjdGlvbiBhbmQKKyAgICAgKiBzZXJ2ZXJzIHNpZGUgKFNlcnZlclNvY2tldCkuIFNlcnZlciB3aWxsIHJlc3BvbnNlIHdpdGggc3BlY2lmaWVkCisgICAgICogcmVzcG9uc2UgY29kZS4KKyAgICAgKiBAcGFyYW0gZG9BdXRoZW50aWNhdGlvbiBzcGVjaWZpZXMKKyAgICAgKiBpZiB0aGUgc2VydmVyIG5lZWRzIGNsaWVudCBhdXRoZW50aWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNvY2tldCBkb0ludGVyYWN0aW9uKGZpbmFsIEh0dHBzVVJMQ29ubmVjdGlvbiBjbGllbnRDb25uZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU2VydmVyU29ja2V0IHNlcnZlclNvY2tldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCByZXNwb25zZUNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIGRvQXV0aGVudGljYXRpb24pCisgICAgICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgLy8gc2V0IHVwIHRoZSBjb25uZWN0aW9uCisgICAgICAgIGNsaWVudENvbm5lY3Rpb24uc2V0RG9JbnB1dCh0cnVlKTsKKyAgICAgICAgY2xpZW50Q29ubmVjdGlvbi5zZXRDb25uZWN0VGltZW91dChUSU1FT1VUKTsKKyAgICAgICAgY2xpZW50Q29ubmVjdGlvbi5zZXRSZWFkVGltZW91dChUSU1FT1VUKTsKKworICAgICAgICBTZXJ2ZXJXb3JrIHNlcnZlciA9IG5ldyBTZXJ2ZXJXb3JrKHNlcnZlclNvY2tldCwgcmVzcG9uc2VDb2RlLCBkb0F1dGhlbnRpY2F0aW9uKTsKKworICAgICAgICBDbGllbnRDb25uZWN0aW9uV29yayBjbGllbnQgPSBuZXcgQ2xpZW50Q29ubmVjdGlvbldvcmsoY2xpZW50Q29ubmVjdGlvbik7CisKKyAgICAgICAgRXhlY3V0b3JTZXJ2aWNlIGV4ZWN1dG9yU2VydmljZSA9IEV4ZWN1dG9ycy5uZXdGaXhlZFRocmVhZFBvb2woMik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBGdXR1cmU8Vm9pZD4gc2VydmVyRnV0dXJlID0gZXhlY3V0b3JTZXJ2aWNlLnN1Ym1pdChzZXJ2ZXIpOworICAgICAgICAgICAgRnV0dXJlPFZvaWQ+IGNsaWVudEZ1dHVyZSA9IGV4ZWN1dG9yU2VydmljZS5zdWJtaXQoY2xpZW50KTsKKworICAgICAgICAgICAgVGhyb3dhYmxlIHQgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXJGdXR1cmUuZ2V0KDMwLCBUaW1lVW5pdC5TRUNPTkRTKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4ZWN1dGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdCA9IGUuZ2V0Q2F1c2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2xpZW50RnV0dXJlLmdldCgzMCwgVGltZVVuaXQuU0VDT05EUyk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGVjdXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIHR3byBwcm9ibGVtcz8gbG9nIHRoZSBmaXJzdCBiZWZvcmUgb3ZlcndyaXRpbmcKKyAgICAgICAgICAgICAgICBpZiAodCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHQucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHQgPSBlLmdldENhdXNlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhlY3V0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IGUuZ2V0Q2F1c2UoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGV4ZWN1dG9yU2VydmljZS5zaHV0ZG93bigpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHNlcnZlci5wZWVyU29ja2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBob3N0IG5hbWUgdmVyaWZpZXIgdXNlZCBpbiB0ZXN0LgorICAgICAqLworICAgIHN0YXRpYyBjbGFzcyBUZXN0SG9zdG5hbWVWZXJpZmllciBpbXBsZW1lbnRzIEhvc3RuYW1lVmVyaWZpZXIgeworCisgICAgICAgIGJvb2xlYW4gdmVyaWZpZWQgPSBmYWxzZTsKKworICAgICAgICBwdWJsaWMgYm9vbGVhbiB2ZXJpZnkoU3RyaW5nIGhvc3RuYW1lLCBTU0xTZXNzaW9uIHNlc3Npb24pIHsKKyAgICAgICAgICAgIGlmIChET19MT0cpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIioqKj4gdmVyaWZpY2F0aW9uICIgKyBob3N0bmFtZSArICIgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHNlc3Npb24uZ2V0UGVlckhvc3QoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB2ZXJpZmllZCA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBiYXNlIGNsYXNzIGZvciBtb2NrIENsaWVudCBhbmQgU2VydmVyLgorICAgICAqLworICAgIHN0YXRpYyBjbGFzcyBXb3JrIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGhlYWRlciBvZiBPSyBIVFRQIHJlc3BvbnNlLgorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIFN0cmluZyByZXNwb25zZUhlYWQgPSAiSFRUUC8xLjEgMjAwIE9LXHJcbiI7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSByZXNwb25zZSBtZXNzYWdlIHRvIGJlIHNlbnQgdG8gdGhlIHByb3h5IENPTk5FQ1QgcmVxdWVzdC4KKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgcHJveHlSZXNwb25zZSA9IHJlc3BvbnNlSGVhZCArICJcclxuIjsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGNvbnRlbnQgb2YgdGhlIHJlc3BvbnNlIHRvIGJlIHNlbnQgZHVyaW5nIEhUVFBTIHNlc3Npb24uCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgZmluYWwgU3RyaW5nIGh0dHBzUmVzcG9uc2VDb250ZW50CisgICAgICAgICAgICAgICAgPSAiPEhUTUw+XG4iCisgICAgICAgICAgICAgICAgKyAiPEhFQUQ+PFRJVExFPkhUVFBTIFJlc3BvbnNlIENvbnRlbnQ8L1RJVExFPjwvSEVBRD5cbiIKKyAgICAgICAgICAgICAgICArICI8L0hUTUw+IjsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHRhaWwgb2YgdGhlIHJlc3BvbnNlIHRvIGJlIHNlbnQgZHVyaW5nIEhUVFBTIHNlc3Npb24uCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgZmluYWwgU3RyaW5nIGh0dHBzUmVzcG9uc2VUYWlsCisgICAgICAgICAgICAgICAgPSAiQ29udGVudC10eXBlOiB0ZXh0L2h0bWxcclxuIgorICAgICAgICAgICAgICAgICsgIkNvbnRlbnQtbGVuZ3RoOiAiICsgaHR0cHNSZXNwb25zZUNvbnRlbnQubGVuZ3RoKCkgKyAiXHJcbiIKKyAgICAgICAgICAgICAgICArICJcclxuIgorICAgICAgICAgICAgICAgICsgaHR0cHNSZXNwb25zZUNvbnRlbnQ7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSByZXNwb25zZSByZXF1aXJpbmcgY2xpZW50J3MgcHJveHkgYXV0aGVudGljYXRpb24uCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgZmluYWwgU3RyaW5nIHJlc3BBdXRoZW50aWNhdGlvblJlcXVpcmVkCisgICAgICAgICAgICAgICAgPSAiSFRUUC8xLjAgNDA3IFByb3h5IGF1dGhlbnRpY2F0aW9uIHJlcXVpcmVkXHJcbiIKKyAgICAgICAgICAgICAgICArICJQcm94eS1hdXRoZW50aWNhdGU6IEJhc2ljIHJlYWxtPVwibG9jYWxob3N0XCJcclxuIgorICAgICAgICAgICAgICAgICsgIlxyXG4iOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBUaGUgZGF0YSB0byBiZSBwb3N0ZWQgYnkgY2xpZW50IHRvIHRoZSBzZXJ2ZXIuCisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgZmluYWwgU3RyaW5nIGNsaWVudHNEYXRhID0gIl8uLV4gQ2xpZW50J3MgRGF0YSBeLS5fIjsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIHByaW50IHN0cmVhbSB1c2VkIGZvciBkZWJ1ZyBsb2cuCisgICAgICAgICAqIElmIGl0IGlzIG51bGwgZGVidWcgaW5mbyB3aWxsIG5vdCBiZSBwcmludGVkLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBQcmludFN0cmVhbSBvdXQgPSBTeXN0ZW0ub3V0OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBQcmludHMgbG9nIG1lc3NhZ2UuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgbG9nKFN0cmluZyBtZXNzYWdlKSB7CisgICAgICAgICAgICBpZiAoRE9fTE9HICYmIChvdXQgIT0gbnVsbCkpIHsKKyAgICAgICAgICAgICAgICBvdXQucHJpbnRsbigiWyIgKyB0aGlzICsgIl06ICIgKyBtZXNzYWdlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBjbGFzcyB1c2VkIGZvciBzZXJ2ZXIgc2lkZSB3b3Jrcy4KKyAgICAgKi8KKyAgICBzdGF0aWMgY2xhc3MgU2VydmVyV29yayBleHRlbmRzIFdvcmsgaW1wbGVtZW50cyBDYWxsYWJsZTxWb2lkPiB7CisKKyAgICAgICAgLy8gdGhlIHNlcnZlciBzb2NrZXQgdXNlZCBmb3IgY29ubmVjdGlvbgorICAgICAgICBwcml2YXRlIGZpbmFsIFNlcnZlclNvY2tldCBzZXJ2ZXJTb2NrZXQ7CisKKyAgICAgICAgLy8gaW5kaWNhdGVzIGlmIHRoZSBzZXJ2ZXIgYWN0cyBhcyBwcm94eSBzZXJ2ZXIKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGFjdEFzUHJveHk7CisKKyAgICAgICAgLy8gaW5kaWNhdGVzIGlmIHRoZSBzZXJ2ZXIgbmVlZHMgcHJveHkgYXV0aGVudGljYXRpb24KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIG5lZWRQcm94eUF1dGhlbnRpY2F0aW9uOworCisgICAgICAgIC8vIHJlc3BvbnNlIGNvZGUgdG8gYmUgc2VuZCB0byB0aGUgY2xpZW50IHBlZXIKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgcmVzcG9uc2VDb2RlOworCisgICAgICAgIC8vIHRoZSBzb2NrZXQgY29ubmVjdGVkIHdpdGggY2xpZW50IHBlZXIKKyAgICAgICAgcHJpdmF0ZSBTb2NrZXQgcGVlclNvY2tldDsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyB0aGUgdGhyZWFkIGFjdGluZyBhcyBhIHNlcnZlciBzaWRlLgorICAgICAgICAgKiBAcGFyYW0gc2VydmVyU29ja2V0IHRoZSBzZXJ2ZXIgc29ja2V0IHRvIGJlIHVzZWQgZHVyaW5nIGNvbm5lY3Rpb24KKyAgICAgICAgICogQHBhcmFtIHJlc3BvbnNlQ29kZSB0aGUgcmVzcG9uc2UgY29kZSB0byBiZSBzZW50IHRvIHRoZSBjbGllbnQKKyAgICAgICAgICogQHBhcmFtIG5lZWRQcm94eUF1dGhlbnRpY2F0aW9uCisgICAgICAgICAqIGluZGljYXRlcyBpZiB0aGUgc2VydmVyIG5lZWRzIHByb3h5IGF1dGhlbnRpY2F0aW9uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgU2VydmVyV29yayhTZXJ2ZXJTb2NrZXQgc2VydmVyU29ja2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgcmVzcG9uc2VDb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIG5lZWRQcm94eUF1dGhlbnRpY2F0aW9uKSB7CisgICAgICAgICAgICB0aGlzLnNlcnZlclNvY2tldCA9IHNlcnZlclNvY2tldDsKKyAgICAgICAgICAgIHRoaXMucmVzcG9uc2VDb2RlID0gcmVzcG9uc2VDb2RlOworICAgICAgICAgICAgdGhpcy5uZWVkUHJveHlBdXRoZW50aWNhdGlvbiA9IG5lZWRQcm94eUF1dGhlbnRpY2F0aW9uOworICAgICAgICAgICAgLy8gd2lsbCBhY3QgYXMgYSBwcm94eSBzZXJ2ZXIgaWYgdGhlIHNwZWNpZmllZCBzZXJ2ZXIgc29ja2V0CisgICAgICAgICAgICAvLyBpcyBub3QgYSBzZWN1cmUgc2VydmVyIHNvY2tldAorICAgICAgICAgICAgdGhpcy5hY3RBc1Byb3h5ID0gIShzZXJ2ZXJTb2NrZXQgaW5zdGFuY2VvZiBTU0xTZXJ2ZXJTb2NrZXQpOworICAgICAgICAgICAgaWYgKCFhY3RBc1Byb3h5KSB7CisgICAgICAgICAgICAgICAgLy8gZGVtYW5kIGNsaWVudCB0byBzZW5kIGl0cyBjZXJ0aWZpY2F0ZQorICAgICAgICAgICAgICAgICgoU1NMU2VydmVyU29ja2V0KSBzZXJ2ZXJTb2NrZXQpLnNldE5lZWRDbGllbnRBdXRoKHRydWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENsb3NlcyB0aGUgY29ubmVjdGlvbi4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlU29ja2V0KFNvY2tldCBzb2NrZXQpIHsKKyAgICAgICAgICAgIGlmIChzb2NrZXQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc29ja2V0LmdldElucHV0U3RyZWFtKCkuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHt9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHNvY2tldC5nZXRPdXRwdXRTdHJlYW0oKS5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkge30KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7fQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFBlcmZvcm1zIHRoZSBhY3R1YWwgc2VydmVyIHdvcmsuCisgICAgICAgICAqIElmIHNvbWUgZXhjZXB0aW9uIG9jY3VycyBkdXJpbmcgdGhlIHdvcmsgaXQgd2lsbCBiZQorICAgICAgICAgKiBzdG9yZWQgaW4gdGhlIDxjb2RlPnRocm93bjwvY29kZT4gZmllbGQuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgVm9pZCBjYWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyB0aGUgYnVmZmVyIHVzZWQgZm9yIHJlYWRpbmcgdGhlIG1lc3NhZ2VzCisgICAgICAgICAgICBieXRlW10gYnVmZiA9IG5ldyBieXRlWzIwNDhdOworICAgICAgICAgICAgLy8gdGhlIG51bWJlciBvZiBieXRlcyByZWFkIGludG8gdGhlIGJ1ZmZlcgorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAvLyBjb25maWd1cmUgdGhlIHNlcnZlciBzb2NrZXQgdG8gYXZvaWQgYmxvY2tpbmcKKyAgICAgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQuc2V0U29UaW1lb3V0KFRJTUVPVVQpOworICAgICAgICAgICAgICAgIC8vIGFjY2VwdCBjbGllbnQgY29ubmVjdGlvbgorICAgICAgICAgICAgICAgIHBlZXJTb2NrZXQgPSBzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisgICAgICAgICAgICAgICAgLy8gY29uZmlndXJlIHRoZSBjbGllbnQgY29ubmVjdGlvbiB0byBhdm9pZCBibG9ja2luZworICAgICAgICAgICAgICAgIHBlZXJTb2NrZXQuc2V0U29UaW1lb3V0KFRJTUVPVVQpOworICAgICAgICAgICAgICAgIGxvZygiQ2xpZW50IGNvbm5lY3Rpb24gQUNDRVBURUQiKTsKKworICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gcGVlclNvY2tldC5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgIE91dHB1dFN0cmVhbSBvcyA9IHBlZXJTb2NrZXQuZ2V0T3V0cHV0U3RyZWFtKCk7CisKKyAgICAgICAgICAgICAgICBpbnQgbnVtID0gaXMucmVhZChidWZmKTsKKyAgICAgICAgICAgICAgICBpZiAobnVtID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIGxvZygiVW5leHBlY3RlZCBFT0YiKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgU3RyaW5nIG1lc3NhZ2UgPSBuZXcgU3RyaW5nKGJ1ZmYsIDAsIG51bSk7CisgICAgICAgICAgICAgICAgbG9nKCJHb3QgcmVxdWVzdDpcbiIgKyBtZXNzYWdlKTsKKyAgICAgICAgICAgICAgICBsb2coIi0tLS0tLS0tLS0tLS0tLS0tLSIpOworCisgICAgICAgICAgICAgICAgaWYgKCFhY3RBc1Byb3h5KSB7CisgICAgICAgICAgICAgICAgICAgIC8vIEFjdCBhcyBTZXJ2ZXIgKG5vdCBQcm94eSkgc2lkZQorICAgICAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5zdGFydHNXaXRoKCJQT1NUIikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsaWVudCBjb25uZWN0aW9uIHNlbnQgc29tZSBkYXRhCisgICAgICAgICAgICAgICAgICAgICAgICBsb2coInRyeSB0byByZWFkIGNsaWVudCBkYXRhIik7CisgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZGF0YSA9IG1lc3NhZ2Uuc3Vic3RyaW5nKG1lc3NhZ2UuaW5kZXhPZigiXHJcblxyXG4iKSs0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvZygiY2xpZW50J3MgZGF0YTogJyIgKyBkYXRhICsgIiciKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoZSByZWNlaXZlZCBkYXRhCisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoY2xpZW50c0RhdGEsIGRhdGEpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5lZWRQcm94eUF1dGhlbnRpY2F0aW9uKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBEbyBwcm94eSB3b3JrCisgICAgICAgICAgICAgICAgICAgICAgICBsb2coIkF1dGhlbnRpY2F0aW9uIHJlcXVpcmVkLi4uIik7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBzZW5kIEF1dGhlbnRpY2F0aW9uIFJlcXVlc3QKKyAgICAgICAgICAgICAgICAgICAgICAgIG9zLndyaXRlKHJlc3BBdXRoZW50aWNhdGlvblJlcXVpcmVkLmdldEJ5dGVzKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVhZCByZXF1ZXN0CisgICAgICAgICAgICAgICAgICAgICAgICBudW0gPSBpcy5yZWFkKGJ1ZmYpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG51bSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgY29ubmVjdGlvbiB3YXMgY2xvc2VkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvIGNsZWFuIHVwIGFuZCBjcmVhdGUgbmV3IG9uZToKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9zZVNvY2tldChwZWVyU29ja2V0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZWVyU29ja2V0ID0gc2VydmVyU29ja2V0LmFjY2VwdCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlZXJTb2NrZXQuc2V0U29UaW1lb3V0KFRJTUVPVVQpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZygiTmV3IGNsaWVudCBjb25uZWN0aW9uIEFDQ0VQVEVEIik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgPSBwZWVyU29ja2V0LmdldElucHV0U3RyZWFtKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3MgPSBwZWVyU29ja2V0LmdldE91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bSA9IGlzLnJlYWQoYnVmZik7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFN0cmluZyhidWZmLCAwLCBudW0pOworICAgICAgICAgICAgICAgICAgICAgICAgbG9nKCJHb3QgYXV0aGVudGljYXRlZCByZXF1ZXN0OlxuIiArIG1lc3NhZ2UpOworICAgICAgICAgICAgICAgICAgICAgICAgbG9nKCItLS0tLS0tLS0tLS0tLS0tLS0iKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHByb3ZpZGVkIGF1dGhvcml6YXRpb24gY3JlZGVudGlhbHMKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIm5vIHByb3h5LWF1dGhvcml6YXRpb24gY3JlZGVudGlhbHM6ICIgKyBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnRvTG93ZXJDYXNlKCkuaW5kZXhPZigicHJveHktYXV0aG9yaXphdGlvbjoiKSAhPSAtMSk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKG1lc3NhZ2Uuc3RhcnRzV2l0aCgiQ09OTkVDVCIpKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gcmVxdWVzdCBmb3IgU1NMIHR1bm5lbAorICAgICAgICAgICAgICAgICAgICBsb2coIlNlbmQgcHJveHkgcmVzcG9uc2UiKTsKKyAgICAgICAgICAgICAgICAgICAgb3Mud3JpdGUocHJveHlSZXNwb25zZS5nZXRCeXRlcygpKTsKKworICAgICAgICAgICAgICAgICAgICBsb2coIlBlcmZvcm0gU1NMIEhhbmRzaGFrZS4uLiIpOworICAgICAgICAgICAgICAgICAgICAvLyBjcmVhdGUgc3NsU29ja2V0IGFjdGluZyBhcyBhIHJlbW90ZSBzZXJ2ZXIgcGVlcgorICAgICAgICAgICAgICAgICAgICBTU0xTb2NrZXQgc3NsU29ja2V0ID0gKFNTTFNvY2tldCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRDb250ZXh0KCkuZ2V0U29ja2V0RmFjdG9yeSgpLmNyZWF0ZVNvY2tldChwZWVyU29ja2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJsb2NhbGhvc3QiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlZXJTb2NrZXQuZ2V0UG9ydCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOyAvLyBkbyBhdXRvY2xvc2UKKyAgICAgICAgICAgICAgICAgICAgc3NsU29ja2V0LnNldFVzZUNsaWVudE1vZGUoZmFsc2UpOworICAgICAgICAgICAgICAgICAgICAvLyBkZW1hbmQgY2xpZW50IGF1dGhlbnRpY2F0aW9uCisgICAgICAgICAgICAgICAgICAgIHNzbFNvY2tldC5zZXROZWVkQ2xpZW50QXV0aCh0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgc3NsU29ja2V0LnN0YXJ0SGFuZHNoYWtlKCk7CisgICAgICAgICAgICAgICAgICAgIHBlZXJTb2NrZXQgPSBzc2xTb2NrZXQ7CisgICAgICAgICAgICAgICAgICAgIGlzID0gcGVlclNvY2tldC5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgICAgICBvcyA9IHBlZXJTb2NrZXQuZ2V0T3V0cHV0U3RyZWFtKCk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gcmVhZCB0aGUgSFRUUCByZXF1ZXN0IHNlbnQgYnkgc2VjdXJlIGNvbm5lY3Rpb24KKyAgICAgICAgICAgICAgICAgICAgLy8gKEhUVFBTIHJlcXVlc3QpCisgICAgICAgICAgICAgICAgICAgIG51bSA9IGlzLnJlYWQoYnVmZik7CisgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgU3RyaW5nKGJ1ZmYsIDAsIG51bSk7CisgICAgICAgICAgICAgICAgICAgIGxvZygiW1JlbW90ZSBTZXJ2ZXJdIFJlcXVlc3QgZnJvbSBTU0wgdHVubmVsOlxuIiArIG1lc3NhZ2UpOworICAgICAgICAgICAgICAgICAgICBsb2coIi0tLS0tLS0tLS0tLS0tLS0tLSIpOworCisgICAgICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLnN0YXJ0c1dpdGgoIlBPU1QiKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2xpZW50IGNvbm5lY3Rpb24gc2VudCBzb21lIGRhdGEKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvZygiW1JlbW90ZSBTZXJ2ZXJdIHRyeSB0byByZWFkIGNsaWVudCBkYXRhIik7CisgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZGF0YSA9IG1lc3NhZ2Uuc3Vic3RyaW5nKG1lc3NhZ2UuaW5kZXhPZigiXHJcblxyXG4iKSs0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvZygiW1JlbW90ZSBTZXJ2ZXJdIGNsaWVudCdzIGRhdGE6ICciICsgbWVzc2FnZSArICInIik7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGUgcmVjZWl2ZWQgZGF0YQorICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGNsaWVudHNEYXRhLCBkYXRhKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGxvZygiW1JlbW90ZSBTZXJ2ZXJdIFNlbmRpbmcgdGhlIHJlc3BvbnNlIGJ5IFNTTCB0dW5uZWwuLi4iKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBzZW5kIHRoZSByZXNwb25zZSB3aXRoIHNwZWNpZmllZCByZXNwb25zZSBjb2RlCisgICAgICAgICAgICAgICAgb3Mud3JpdGUoKCJIVFRQLzEuMSAiICsgcmVzcG9uc2VDb2RlCisgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBNZXNzYWdlXHJcbiIgKyBodHRwc1Jlc3BvbnNlVGFpbCkuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICAgICAgb3MuZmx1c2goKTsKKyAgICAgICAgICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICAgICAgICAgIGxvZygiV29yayBpcyBET05FIGFjdEFzUHJveHk9IiArIGFjdEFzUHJveHkpOworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBjbG9zZVNvY2tldChwZWVyU29ja2V0KTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7fQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICByZXR1cm4gYWN0QXNQcm94eSA/ICJQcm94eSBTZXJ2ZXIiIDogIlNlcnZlciI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgY2xhc3MgdXNlZCBmb3IgY2xpZW50IHNpZGUgd29yay4KKyAgICAgKi8KKyAgICBzdGF0aWMgY2xhc3MgQ2xpZW50Q29ubmVjdGlvbldvcmsgZXh0ZW5kcyBXb3JrIGltcGxlbWVudHMgQ2FsbGFibGU8Vm9pZD4geworCisgICAgICAgIC8vIGNvbm5lY3Rpb24gdG8gYmUgdXNlZCB0byBjb250YWN0IHRoZSBzZXJ2ZXIgc2lkZQorICAgICAgICBwcml2YXRlIEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDcmVhdGVzIHRoZSB0aHJlYWQgYWN0aW5nIGFzIGEgY2xpZW50IHNpZGUuCisgICAgICAgICAqIEBwYXJhbSBjb25uZWN0aW9uIGNvbm5lY3Rpb24gdG8gYmUgdXNlZCB0byBjb250YWN0IHRoZSBzZXJ2ZXIgc2lkZQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIENsaWVudENvbm5lY3Rpb25Xb3JrKEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uKSB7CisgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uOworICAgICAgICAgICAgbG9nKCJDcmVhdGVkIG92ZXIgY29ubmVjdGlvbjogIiArIGNvbm5lY3Rpb24uZ2V0Q2xhc3MoKSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUGVyZm9ybXMgdGhlIGFjdHVhbCBjbGllbnQgd29yay4KKyAgICAgICAgICogSWYgc29tZSBleGNlcHRpb24gb2NjdXJzIGR1cmluZyB0aGUgd29yayBpdCB3aWxsIGJlCisgICAgICAgICAqIHN0b3JlZCBpbiB0aGUgPGNvZGU+dGhyb3duPGNvZGU+IGZpZWxkLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFZvaWQgY2FsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgbG9nKCJPcGVuaW5nIHRoZSBjb25uZWN0aW9uIHRvICIgKyBjb25uZWN0aW9uLmdldFVSTCgpKTsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uY29ubmVjdCgpOworICAgICAgICAgICAgbG9nKCJDb25uZWN0aW9uIGhhcyBiZWVuIEVTVEFCTElTSEVELCB1c2luZyBwcm94eTogIiArIGNvbm5lY3Rpb24udXNpbmdQcm94eSgpKTsKKyAgICAgICAgICAgIGlmIChjb25uZWN0aW9uLmdldERvT3V0cHV0KCkpIHsKKyAgICAgICAgICAgICAgICBsb2coIlBvc3RpbmcgZGF0YSIpOworICAgICAgICAgICAgICAgIC8vIGNvbm5lY3Rpb24gY29uZmlndXJlZCB0byBwb3N0IGRhdGEsIGRvIHNvCisgICAgICAgICAgICAgICAgY29ubmVjdGlvbi5nZXRPdXRwdXRTdHJlYW0oKS53cml0ZShjbGllbnRzRGF0YS5nZXRCeXRlcygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIHJlYWQgdGhlIGNvbnRlbnQgb2YgSFRUUChzKSByZXNwb25zZQorICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBjb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCk7CisgICAgICAgICAgICBsb2coIklucHV0IFN0cmVhbSBvYnRhaW5lZCIpOworICAgICAgICAgICAgYnl0ZVtdIGJ1ZmYgPSBuZXcgYnl0ZVsyMDQ4XTsKKyAgICAgICAgICAgIGludCBudW0gPSAwOworICAgICAgICAgICAgaW50IGJ5dCA9IDA7CisgICAgICAgICAgICB3aGlsZSAoKG51bSA8IGJ1ZmYubGVuZ3RoKSAmJiAoKGJ5dCA9IGlzLnJlYWQoKSkgIT0gLTEpKSB7CisgICAgICAgICAgICAgICAgYnVmZltudW0rK10gPSAoYnl0ZSkgYnl0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3RyaW5nIG1lc3NhZ2UgPSBuZXcgU3RyaW5nKGJ1ZmYsIDAsIG51bSk7CisgICAgICAgICAgICBsb2coIkdvdCBjb250ZW50OlxuIiArIG1lc3NhZ2UpOworICAgICAgICAgICAgbG9nKCItLS0tLS0tLS0tLS0tLS0tLS0iKTsKKyAgICAgICAgICAgIGxvZygiUmVzcG9uc2UgY29kZTogIiArIGNvbm5lY3Rpb24uZ2V0UmVzcG9uc2VDb2RlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGh0dHBzUmVzcG9uc2VDb250ZW50LCBtZXNzYWdlKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICByZXR1cm4gIkNsaWVudCBDb25uZWN0aW9uIjsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL2lvL09iamVjdElucHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvaW8vT2JqZWN0SW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTI0MDZmMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL2lvL09iamVjdElucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTExNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5FeHRlcm5hbGl6YWJsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkludmFsaWRPYmplY3RFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5Ob3RBY3RpdmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRWYWxpZGF0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0OworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0U3RyZWFtQ2xhc3M7CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QaXBlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUGlwZWRPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGVQZXJtaXNzaW9uOworaW1wb3J0IGphdmEuaW8uU3RyZWFtQ29ycnVwdGVkRXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlByb3h5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS50ZXN0ZnJhbWV3b3JrLnNlcmlhbGl6YXRpb24uU2VyaWFsaXphdGlvblRlc3Q7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnRlc3RmcmFtZXdvcmsuc2VyaWFsaXphdGlvbi5TZXJpYWxpemF0aW9uVGVzdC5TZXJpYWxpemFibGVBc3NlcnQ7CisKK0BTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQorcHVibGljIGNsYXNzIE9iamVjdElucHV0U3RyZWFtVGVzdCBleHRlbmRzIFRlc3RDYXNlIGltcGxlbWVudHMKKyAgICAgICAgU2VyaWFsaXphYmxlIHsKKworICAgIE9iamVjdElucHV0U3RyZWFtIG9pczsKKworICAgIE9iamVjdE91dHB1dFN0cmVhbSBvb3M7CisKKyAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvOworCisgICAgcHVibGljIGNsYXNzIFNlcmlhbGl6YWJsZVRlc3RIZWxwZXIgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgICAgIHB1YmxpYyBTdHJpbmcgYUZpZWxkMTsKKworICAgICAgICBwdWJsaWMgU3RyaW5nIGFGaWVsZDI7CisKKyAgICAgICAgU2VyaWFsaXphYmxlVGVzdEhlbHBlcigpIHsKKyAgICAgICAgICAgIGFGaWVsZDEgPSBudWxsOworICAgICAgICAgICAgYUZpZWxkMiA9IG51bGw7CisgICAgICAgIH0KKworICAgICAgICBTZXJpYWxpemFibGVUZXN0SGVscGVyKFN0cmluZyBzLCBTdHJpbmcgdCkgeworICAgICAgICAgICAgYUZpZWxkMSA9IHM7CisgICAgICAgICAgICBhRmllbGQyID0gdDsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIG9pcykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBub3RlIGFGaWVsZDIgaXMgbm90IHJlYWQKKyAgICAgICAgICAgIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkIGZpZWxkcyA9IG9pcy5yZWFkRmllbGRzKCk7CisgICAgICAgICAgICBhRmllbGQxID0gKFN0cmluZykgZmllbGRzLmdldCgiYUZpZWxkMSIsICJaYXAiKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gb29zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgLy8gbm90ZSBhRmllbGQyIGlzIG5vdCB3cml0dGVuCisgICAgICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGQgZmllbGRzID0gb29zLnB1dEZpZWxkcygpOworICAgICAgICAgICAgZmllbGRzLnB1dCgiYUZpZWxkMSIsIGFGaWVsZDEpOworICAgICAgICAgICAgb29zLndyaXRlRmllbGRzKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRleHQxKCkgeworICAgICAgICAgICAgcmV0dXJuIGFGaWVsZDE7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXRUZXh0MShTdHJpbmcgcykgeworICAgICAgICAgICAgYUZpZWxkMSA9IHM7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRleHQyKCkgeworICAgICAgICAgICAgcmV0dXJuIGFGaWVsZDI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXRUZXh0MihTdHJpbmcgcykgeworICAgICAgICAgICAgYUZpZWxkMiA9IHM7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEExIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1OTQyNTg0OTEzNDQ2MDc5NjYxTDsKKworICAgICAgICBCMSBiMSA9IG5ldyBCMSgpOworCisgICAgICAgIEIxIGIyID0gYjE7CisKKyAgICAgICAgVmVjdG9yIHYgPSBuZXcgVmVjdG9yKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBCMSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgaW50IGkgPSA1OworCisgICAgICAgIEhhc2h0YWJsZSBoID0gbmV3IEhhc2h0YWJsZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0jcmVhZE9iamVjdCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkT2JqZWN0TWlzc2luZ0NsYXNzZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3QudmVyaWZ5U2VsZihuZXcgQTEoKSwgbmV3IFNlcmlhbGl6YWJsZUFzc2VydCgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFzc2VydERlc2VyaWFsaXplZChTZXJpYWxpemFibGUgaW5pdGlhbCwKKyAgICAgICAgICAgICAgICAgICAgU2VyaWFsaXphYmxlIGRlc2VyaWFsaXplZCkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyg1LCAoKEExKSBkZXNlcmlhbGl6ZWQpLmIxLmkpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtI09iamVjdElucHV0U3RyZWFtKGphdmEuaW8uSW5wdXRTdHJlYW0pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX0lucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb29zLndyaXRlRG91YmxlKERvdWJsZS5NQVhfVkFMVUUpOworICAgICAgICBvb3MuY2xvc2UoKTsKKyAgICAgICAgb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSkpOworICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbOTBdKSk7CisgICAgICAgICAgICBmYWlsKCJTdHJlYW1Db3JydXB0ZWRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU3RyZWFtQ29ycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGxpbmsgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSNyZXNvbHZlUHJveHlDbGFzcyhTdHJpbmdbXSl9CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZXNvbHZlUHJveHlDbGFzcygpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBvb3Mud3JpdGVCeXRlcygiSGVsbG9Xb3JsZCIpOworICAgICAgICBvb3MuY2xvc2UoKTsKKyAgICAgICAgb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSkpOworICAgICAgICBNb2NrT2JqZWN0SW5wdXRTdHJlYW0gbW9ja0luID0gbmV3IE1vY2tPYmplY3RJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgQ2xhc3NbXSBjbGF6enMgPSB7IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0uY2xhc3MsCisgICAgICAgICAgICAgICAgamF2YS5pby5SZWFkZXIuY2xhc3MgfTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjbGF6enMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIENsYXNzIGNsYXp6ID0gY2xhenpzW2ldOworICAgICAgICAgICAgQ2xhc3NbXSBpbnRlcmZhY2VOYW1lcyA9IGNsYXp6LmdldEludGVyZmFjZXMoKTsKKyAgICAgICAgICAgIFN0cmluZ1tdIGludGVyZmFjZXMgPSBuZXcgU3RyaW5nW2ludGVyZmFjZU5hbWVzLmxlbmd0aF07CisgICAgICAgICAgICBpbnQgaW5kZXggPSAwOworICAgICAgICAgICAgZm9yIChDbGFzcyBjIDogaW50ZXJmYWNlTmFtZXMpIHsKKyAgICAgICAgICAgICAgICBpbnRlcmZhY2VzW2luZGV4XSA9IGMuZ2V0TmFtZSgpOworICAgICAgICAgICAgICAgIGluZGV4Kys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBDbGFzczw/PiBzID0gbW9ja0luLnJlc29sdmVQcm94eUNsYXNzKGludGVyZmFjZXMpOworCisgICAgICAgICAgICBpZiAoUHJveHkuaXNQcm94eUNsYXNzKHMpKSB7CisgICAgICAgICAgICAgICAgQ2xhc3NbXSBpbXBsZW1lbnRlZEludGVyZmFjZXMgPSBzLmdldEludGVyZmFjZXMoKTsKKyAgICAgICAgICAgICAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBpbXBsZW1lbnRlZEludGVyZmFjZXMubGVuZ3RoOyBpbmRleCsrKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhpbnRlcmZhY2VOYW1lc1tpbmRleF0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wbGVtZW50ZWRJbnRlcmZhY2VzW2luZGV4XSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJTaG91bGQgcmV0dXJuIGEgcHJveHkgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoZSBpbnRlcmZhY2VzIG5hbWVkIGluIGEgcHJveHkgY2xhc3MgZGVzY3JpcHRvciIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIG1vY2tJbi5jbG9zZSgpOworICAgIH0KKworICAgIGNsYXNzIE1vY2tPYmplY3RJbnB1dFN0cmVhbSBleHRlbmRzIE9iamVjdElucHV0U3RyZWFtIHsKKworICAgICAgICBwdWJsaWMgTW9ja09iamVjdElucHV0U3RyZWFtKElucHV0U3RyZWFtIGlucHV0KQorICAgICAgICAgICAgICAgIHRocm93cyBTdHJlYW1Db3JydXB0ZWRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyKGlucHV0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgQ2xhc3M8Pz4gcmVzb2x2ZVByb3h5Q2xhc3MoU3RyaW5nW10gaW50ZXJmYWNlTmFtZXMpIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIucmVzb2x2ZVByb3h5Q2xhc3MoaW50ZXJmYWNlTmFtZXMpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtI2F2YWlsYWJsZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvb3Mud3JpdGVCeXRlcygiSGVsbG9Xb3JsZCIpOworICAgICAgICBvb3MuY2xvc2UoKTsKKyAgICAgICAgb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJlYWQgaW5jb3JyZWN0IGJ5dGVzIiwgMTAsIG9pcy5hdmFpbGFibGUoKSk7CisgICAgICAgIG9pcy5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0jY2xvc2UoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvb3Mud3JpdGVCeXRlcygiSGVsbG9Xb3JsZCIpOworICAgICAgICBvb3MuY2xvc2UoKTsKKyAgICAgICAgb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSkpOworICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtI2RlZmF1bHRSZWFkT2JqZWN0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RlZmF1bHRSZWFkT2JqZWN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFNNLiBUaGlzIG1ldGhvZCBtYXkgYXMgd2VsbCBiZSBwcml2YXRlLCBhcyBpZiBjYWxsZWQgZGlyZWN0bHkgaXQKKyAgICAgICAgLy8gdGhyb3dzIGFuIGV4Y2VwdGlvbi4KKyAgICAgICAgU3RyaW5nIHMgPSAiSGVsbG9Xb3JsZCI7CisgICAgICAgIG9vcy53cml0ZU9iamVjdChzKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9pcy5kZWZhdWx0UmVhZE9iamVjdCgpOworICAgICAgICAgICAgZmFpbCgiTm90QWN0aXZlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE5vdEFjdGl2ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBEZXNpcmVkIGJlaGF2aW9yCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0jcmVhZCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb29zLndyaXRlKCdUJyk7CisgICAgICAgIG9vcy5jbG9zZSgpOworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhby50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmVhZCBpbmNvcnJlY3QgYnl0ZSB2YWx1ZSIsICdUJywgb2lzLnJlYWQoKSk7CisgICAgICAgIG9pcy5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0jcmVhZChieXRlW10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCRCSUkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbMTBdOworICAgICAgICBvb3Mud3JpdGVCeXRlcygiSGVsbG9Xb3JsZCIpOworICAgICAgICBvb3MuY2xvc2UoKTsKKyAgICAgICAgb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSkpOworICAgICAgICBvaXMucmVhZChidWYsIDAsIDEwKTsKKyAgICAgICAgb2lzLmNsb3NlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmVhZCBpbmNvcnJlY3QgYnl0ZXMiLCAiSGVsbG9Xb3JsZCIsIG5ldyBTdHJpbmcoYnVmLCAwLAorICAgICAgICAgICAgICAgIDEwLCAiVVRGLTgiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSNyZWFkQm9vbGVhbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkQm9vbGVhbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9vcy53cml0ZUJvb2xlYW4odHJ1ZSk7CisgICAgICAgIG9vcy5jbG9zZSgpOworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhby50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJlYWQgaW5jb3JyZWN0IGJvb2xlYW4gdmFsdWUiLCBvaXMucmVhZEJvb2xlYW4oKSk7CisgICAgICAgIG9pcy5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0jcmVhZEJ5dGUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZEJ5dGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvb3Mud3JpdGVCeXRlKDEyNyk7CisgICAgICAgIG9vcy5jbG9zZSgpOworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhby50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmVhZCBpbmNvcnJlY3QgYnl0ZSB2YWx1ZSIsIDEyNywgb2lzLnJlYWRCeXRlKCkpOworICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtI3JlYWRDaGFyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRDaGFyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb29zLndyaXRlQ2hhcignVCcpOworICAgICAgICBvb3MuY2xvc2UoKTsKKyAgICAgICAgb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJlYWQgaW5jb3JyZWN0IGNoYXIgdmFsdWUiLCAnVCcsIG9pcy5yZWFkQ2hhcigpKTsKKyAgICAgICAgb2lzLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSNyZWFkRG91YmxlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWREb3VibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvb3Mud3JpdGVEb3VibGUoRG91YmxlLk1BWF9WQUxVRSk7CisgICAgICAgIG9vcy5jbG9zZSgpOworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhby50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJlYWQgaW5jb3JyZWN0IGRvdWJsZSB2YWx1ZSIsCisgICAgICAgICAgICAgICAgb2lzLnJlYWREb3VibGUoKSA9PSBEb3VibGUuTUFYX1ZBTFVFKTsKKyAgICAgICAgb2lzLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSNyZWFkRmllbGRzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRGaWVsZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBTZXJpYWxpemFibGVUZXN0SGVscGVyIHN0aDsKKworICAgICAgICAvKgorICAgICAgICAgKiAiU2VyaWFsaXphYmxlVGVzdEhlbHBlciIgaXMgYW4gb2JqZWN0IGNyZWF0ZWQgZm9yIHRoZXNlIHRlc3RzIHdpdGgKKyAgICAgICAgICogdHdvIGZpZWxkcyAoU3RyaW5ncykgYW5kIHNpbXBsZSBpbXBsZW1lbnRhdGlvbnMgb2YgcmVhZE9iamVjdCBhbmQKKyAgICAgICAgICogd3JpdGVPYmplY3Qgd2hpY2ggc2ltcGx5IHJlYWQgYW5kIHdyaXRlIHRoZSBmaXJzdCBmaWVsZCBidXQgbm90IHRoZQorICAgICAgICAgKiBzZWNvbmQKKyAgICAgICAgICovCisKKyAgICAgICAgb29zLndyaXRlT2JqZWN0KG5ldyBTZXJpYWxpemFibGVUZXN0SGVscGVyKCJHYWJiYSIsICJKYWJiYSIpKTsKKyAgICAgICAgb29zLmZsdXNoKCk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgc3RoID0gKFNlcmlhbGl6YWJsZVRlc3RIZWxwZXIpIChvaXMucmVhZE9iamVjdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJyZWFkRmllbGRzIC8gd3JpdGVGaWVsZHMgZmFpbGVkLS1maXJzdCBmaWVsZCBub3Qgc2V0IiwKKyAgICAgICAgICAgICAgICAiR2FiYmEiLCBzdGguZ2V0VGV4dDEoKSk7CisgICAgICAgIGFzc2VydE51bGwoCisgICAgICAgICAgICAgICAgInJlYWRGaWVsZHMgLyB3cml0ZUZpZWxkcyBmYWlsZWQtLXNlY29uZCBmaWVsZCBzaG91bGQgbm90IGhhdmUgYmVlbiBzZXQiLAorICAgICAgICAgICAgICAgIHN0aC5nZXRUZXh0MigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtI3JlYWRGbG9hdCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkRmxvYXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvb3Mud3JpdGVGbG9hdChGbG9hdC5NQVhfVkFMVUUpOworICAgICAgICBvb3MuY2xvc2UoKTsKKyAgICAgICAgb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZWFkIGluY29ycmVjdCBmbG9hdCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgb2lzLnJlYWRGbG9hdCgpID09IEZsb2F0Lk1BWF9WQUxVRSk7CisgICAgICAgIG9pcy5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0jcmVhZEZ1bGx5KGJ5dGVbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRGdWxseSRCKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzEwXTsKKyAgICAgICAgb29zLndyaXRlQnl0ZXMoIkhlbGxvV29ybGQiKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgb2lzLnJlYWRGdWxseShidWYpOworICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZWFkIGluY29ycmVjdCBieXRlcyIsICJIZWxsb1dvcmxkIiwgbmV3IFN0cmluZyhidWYsIDAsCisgICAgICAgICAgICAgICAgMTAsICJVVEYtOCIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtI3JlYWRGdWxseShieXRlW10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZEZ1bGx5JEJJSSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgIG9vcy53cml0ZUJ5dGVzKCJIZWxsb1dvcmxkIik7CisgICAgICAgIG9vcy5jbG9zZSgpOworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhby50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIG9pcy5yZWFkRnVsbHkoYnVmLCAwLCAxMCk7CisgICAgICAgIG9pcy5jbG9zZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJlYWQgaW5jb3JyZWN0IGJ5dGVzIiwgIkhlbGxvV29ybGQiLCBuZXcgU3RyaW5nKGJ1ZiwgMCwKKyAgICAgICAgICAgICAgICAxMCwgIlVURi04IikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0jcmVhZEludCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkSW50KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb29zLndyaXRlSW50KEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmVhZCBpbmNvcnJlY3QgaW50IHZhbHVlIiwKKyAgICAgICAgICAgICAgICBvaXMucmVhZEludCgpID09IEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgb2lzLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSNyZWFkTGluZSgpCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRMaW5lKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb29zLndyaXRlQnl0ZXMoIkhlbGxvV29ybGRcblNlY29uZExpbmUiKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgb2lzLnJlYWRMaW5lKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmVhZCBpbmNvcnJlY3Qgc3RyaW5nIHZhbHVlIiwgIlNlY29uZExpbmUiLCBvaXMKKyAgICAgICAgICAgICAgICAucmVhZExpbmUoKSk7CisgICAgICAgIG9pcy5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0jcmVhZExvbmcoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZExvbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvb3Mud3JpdGVMb25nKExvbmcuTUFYX1ZBTFVFKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmVhZCBpbmNvcnJlY3QgbG9uZyB2YWx1ZSIsCisgICAgICAgICAgICAgICAgb2lzLnJlYWRMb25nKCkgPT0gTG9uZy5NQVhfVkFMVUUpOworICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtI3JlYWRPYmplY3QoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZE9iamVjdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgcyA9ICJIZWxsb1dvcmxkIjsKKyAgICAgICAgb29zLndyaXRlT2JqZWN0KHMpOworICAgICAgICBvb3MuY2xvc2UoKTsKKyAgICAgICAgb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJlYWQgaW5jb3JyZWN0IE9iamVjdCB2YWx1ZSIsIHMsIG9pcy5yZWFkT2JqZWN0KCkpOworICAgICAgICBvaXMuY2xvc2UoKTsKKworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTkxCisgICAgICAgIC8vIGR5bmFtaWNhbGx5IGNyZWF0ZSBzZXJpYWxpemF0aW9uIGJ5dGUgYXJyYXkgZm9yIHRoZSBuZXh0IGhpZXJhcmNoeToKKyAgICAgICAgLy8gLSBjbGFzcyBBIGltcGxlbWVudHMgU2VyaWFsaXphYmxlCisgICAgICAgIC8vIC0gY2xhc3MgQyBleHRlbmRzIEEKKworICAgICAgICBieXRlW10gY05hbWUgPSBDLmNsYXNzLmdldE5hbWUoKS5nZXRCeXRlcygiVVRGLTgiKTsKKyAgICAgICAgYnl0ZVtdIGFOYW1lID0gQS5jbGFzcy5nZXROYW1lKCkuZ2V0Qnl0ZXMoIlVURi04Iik7CisKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKworICAgICAgICBieXRlW10gYmVnU3RyZWFtID0gbmV3IGJ5dGVbXSB7IChieXRlKSAweGFjLCAoYnl0ZSkgMHhlZCwgLy8gU1RSRUFNX01BR0lDCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDA1LCAvLyBTVFJFQU1fVkVSU0lPTgorICAgICAgICAgICAgICAgIChieXRlKSAweDczLCAvLyBUQ19PQkpFQ1QKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg3MiwgLy8gVENfQ0xBU1NERVNDCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIC8vIG9ubHkgZmlyc3QgYnl0ZSBmb3IgQyBjbGFzcyBuYW1lIGxlbmd0aAorICAgICAgICB9OworCisgICAgICAgIG91dC53cml0ZShiZWdTdHJlYW0sIDAsIGJlZ1N0cmVhbS5sZW5ndGgpOworICAgICAgICBvdXQud3JpdGUoY05hbWUubGVuZ3RoKTsgLy8gc2Vjb25kIGJ5dGUgZm9yIEMgY2xhc3MgbmFtZSBsZW5ndGgKKyAgICAgICAgb3V0LndyaXRlKGNOYW1lLCAwLCBjTmFtZS5sZW5ndGgpOyAvLyBDIGNsYXNzIG5hbWUKKworICAgICAgICBieXRlW10gbWlkU3RyZWFtID0gbmV3IGJ5dGVbXSB7IChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MjEsIC8vIHNlcmlhbFZlcnNpb25VSUQgPSAzM0wKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwMiwgLy8gZmxhZ3MKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIC8vIGZpZWxkcyA6IG5vbmUKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg3OCwgLy8gVENfRU5EQkxPQ0tEQVRBCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NzIsIC8vIFN1cGVyIGNsYXNzIGZvciBDOiBUQ19DTEFTU0RFU0MgZm9yIEEgY2xhc3MKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgLy8gb25seSBmaXJzdCBieXRlIGZvciBBIGNsYXNzIG5hbWUgbGVuZ3RoCisgICAgICAgIH07CisKKyAgICAgICAgb3V0LndyaXRlKG1pZFN0cmVhbSwgMCwgbWlkU3RyZWFtLmxlbmd0aCk7CisgICAgICAgIG91dC53cml0ZShhTmFtZS5sZW5ndGgpOyAvLyBzZWNvbmQgYnl0ZSBmb3IgQSBjbGFzcyBuYW1lIGxlbmd0aAorICAgICAgICBvdXQud3JpdGUoYU5hbWUsIDAsIGFOYW1lLmxlbmd0aCk7IC8vIEEgY2xhc3MgbmFtZQorCisgICAgICAgIGJ5dGVbXSBlbmRTdHJlYW0gPSBuZXcgYnl0ZVtdIHsgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwYiwgLy8gc2VyaWFsVmVyc2lvblVJRCA9IDExTAorICAgICAgICAgICAgICAgIChieXRlKSAweDAyLCAvLyBmbGFncworICAgICAgICAgICAgICAgIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMSwgLy8gZmllbGRzCisKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg0YywgLy8gZmllbGQgZGVzY3JpcHRpb246IHR5cGUgTCAob2JqZWN0KQorICAgICAgICAgICAgICAgIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwNCwgLy8gbGVuZ3RoCisgICAgICAgICAgICAgICAgLy8gZmllbGQgPSAnbmFtZScKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg2ZSwgKGJ5dGUpIDB4NjEsIChieXRlKSAweDZkLCAoYnl0ZSkgMHg2NSwKKworICAgICAgICAgICAgICAgIChieXRlKSAweDc0LCAvLyBjbGFzc05hbWUxOiBUQ19TVFJJTkcKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MTIsIC8vIGxlbmd0aAorICAgICAgICAgICAgICAgIC8vCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NGMsIChieXRlKSAweDZhLCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4NzYsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NjEsIChieXRlKSAweDJmLCAoYnl0ZSkgMHg2YywgKGJ5dGUpIDB4NjEsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NmUsIChieXRlKSAweDY3LCAoYnl0ZSkgMHgyZiwgKGJ5dGUpIDB4NTMsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NzQsIChieXRlKSAweDcyLCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4NmUsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NjcsIChieXRlKSAweDNiLAorCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NzgsIC8vIFRDX0VOREJMT0NLREFUQQorICAgICAgICAgICAgICAgIChieXRlKSAweDcwLCAvLyBOVUxMIHN1cGVyIGNsYXNzIGZvciBBIGNsYXNzCisKKyAgICAgICAgICAgICAgICAvLyBjbGFzc2RhdGEKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg3NCwgLy8gVENfU1RSSU5HCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDA0LCAvLyBsZW5ndGgKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg2ZSwgKGJ5dGUpIDB4NjEsIChieXRlKSAweDZkLCAoYnl0ZSkgMHg2NSwgLy8gdmFsdWUKKyAgICAgICAgfTsKKworICAgICAgICBvdXQud3JpdGUoZW5kU3RyZWFtLCAwLCBlbmRTdHJlYW0ubGVuZ3RoKTsKKyAgICAgICAgb3V0LmZsdXNoKCk7CisKKyAgICAgICAgLy8gcmVhZCBjcmVhdGVkIHNlcmlhbC4gZm9ybQorICAgICAgICBPYmplY3RJbnB1dFN0cmVhbSBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgIG91dC50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIE9iamVjdCBvID0gb2lzLnJlYWRPYmplY3QoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEMuY2xhc3MsIG8uZ2V0Q2xhc3MoKSk7CisKKwkJLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS04NDYKKyAgICAgICAgYXNzZXJ0TnVsbChuZXcgT2JqZWN0SW5wdXRTdHJlYW0oKSB7fS5yZWFkT2JqZWN0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0jcmVhZE9iamVjdE92ZXJyaWRlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRPYmplY3RPdmVycmlkZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTg0NgorICAgICAgICBhc3NlcnROdWxsKG5ldyBPYmplY3RJbnB1dFN0cmVhbSgpIHsKKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJlYWRPYmplY3RPdmVycmlkZSgpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnJlYWRPYmplY3RPdmVycmlkZSgpOworICAgICAgICAgICAgfQorCisgICAgICAgIH0ucmVhZE9iamVjdE92ZXJyaWRlKCkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTFMOworCisgICAgICAgIHB1YmxpYyBTdHJpbmcgbmFtZSA9ICJuYW1lIjsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEIgZXh0ZW5kcyBBIHt9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEMgZXh0ZW5kcyBCIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzM0w7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSNyZWFkT2JqZWN0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRPYmplY3RDb3JydXB0KCkgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0geyAwMCwgMDAsIDAwLCAweDY0LCAweDQzLCAweDQ4LCAoYnl0ZSkgMHhGRCwgMHg3MSwgMDAsCisgICAgICAgICAgICAgICAgMDAsIDB4MEIsIChieXRlKSAweEI4LCAweDRELCAweDY1IH07CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBPYmplY3RJbnB1dFN0cmVhbSBpbiA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShiaW4pOworICAgICAgICAgICAgaW4ucmVhZE9iamVjdCgpOworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCByZWFkIG9mIGNvcnJ1cHRlZCBzdHJlYW0iKTsKKyAgICAgICAgfSBjYXRjaCAoU3RyZWFtQ29ycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtI3JlYWRTaG9ydCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkU2hvcnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvb3Mud3JpdGVTaG9ydChTaG9ydC5NQVhfVkFMVUUpOworICAgICAgICBvb3MuY2xvc2UoKTsKKyAgICAgICAgb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZWFkIGluY29ycmVjdCBzaG9ydCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgb2lzLnJlYWRTaG9ydCgpID09IFNob3J0Lk1BWF9WQUxVRSk7CisgICAgICAgIG9pcy5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0jcmVhZFVuc2lnbmVkQnl0ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkVW5zaWduZWRCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb29zLndyaXRlQnl0ZSgtMSk7CisgICAgICAgIG9vcy5jbG9zZSgpOworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhby50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmVhZCBpbmNvcnJlY3QgdW5zaWduZWRCeXRlIHZhbHVlIiwgMjU1LCBvaXMKKyAgICAgICAgICAgICAgICAucmVhZFVuc2lnbmVkQnl0ZSgpKTsKKyAgICAgICAgb2lzLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSNyZWFkVW5zaWduZWRTaG9ydCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkVW5zaWduZWRTaG9ydCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9vcy53cml0ZVNob3J0KC0xKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZWFkIGluY29ycmVjdCB1bnNpZ25lZFNob3J0IHZhbHVlIiwgNjU1MzUsIG9pcworICAgICAgICAgICAgICAgIC5yZWFkVW5zaWduZWRTaG9ydCgpKTsKKyAgICAgICAgb2lzLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSNyZWFkVVRGKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRVVEYoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvb3Mud3JpdGVVVEYoIkhlbGxvV29ybGQiKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZWFkIGluY29ycmVjdCB1dGYgdmFsdWUiLCAiSGVsbG9Xb3JsZCIsIG9pcy5yZWFkVVRGKCkpOworICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtI3NraXBCeXRlcyhpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9za2lwQnl0ZXNJKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzEwXTsKKyAgICAgICAgb29zLndyaXRlQnl0ZXMoIkhlbGxvV29ybGQiKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgb2lzLnNraXBCeXRlcyg1KTsKKyAgICAgICAgb2lzLnJlYWQoYnVmLCAwLCA1KTsKKyAgICAgICAgb2lzLmNsb3NlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2tpcHBlZCBpbmNvcnJlY3QgYnl0ZXMiLCAiV29ybGQiLCBuZXcgU3RyaW5nKGJ1ZiwgMCwgNSwgIlVURi04IikpOworCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktODQ0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgT2JqZWN0SW5wdXRTdHJlYW0oKSB7fS5za2lwQnl0ZXMoMCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7fQorICAgIH0KKworICAgIC8vIFJlZ3Jlc3Npb24gVGVzdCBmb3IgSklSQSAyMTkyCisJcHVibGljIHZvaWQgdGVzdF9yZWFkT2JqZWN0X3dpdGhQcmltaXRpdmVDbGFzcygpIHRocm93cyBFeGNlcHRpb24geworCQlGaWxlIGZpbGUgPSBuZXcgRmlsZSgidGVzdC5zZXIiKTsKKwkJZmlsZS5kZWxldGVPbkV4aXQoKTsKKwkJVGVzdCB0ZXN0ID0gbmV3IFRlc3QoKTsKKwkJT2JqZWN0T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oCisJCQkJZmlsZSkpOworCQlvdXQud3JpdGVPYmplY3QodGVzdCk7CisJCW91dC5jbG9zZSgpOworCisJCU9iamVjdElucHV0U3RyZWFtIGluID0gbmV3IE9iamVjdElucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSkpOworCQlUZXN0IGFub3RoZXIgPSAoVGVzdCkgaW4ucmVhZE9iamVjdCgpOworCQlpbi5jbG9zZSgpOworCQlhc3NlcnRFcXVhbHModGVzdCwgYW5vdGhlcik7CisJfQorCisgICAgLy9SZWdyZXNzaW9uIFRlc3QgZm9yIEpJUkEtMjI0OQorICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgT2JqZWN0T3V0cHV0U3RyZWFtV2l0aFdyaXRlRGVzYyBleHRlbmRzCisgICAgICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0geworICAgICAgICBwdWJsaWMgT2JqZWN0T3V0cHV0U3RyZWFtV2l0aFdyaXRlRGVzYyhPdXRwdXRTdHJlYW0gb3MpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyKG9zKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZUNsYXNzRGVzY3JpcHRvcihPYmplY3RTdHJlYW1DbGFzcyBkZXNjKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE9iamVjdEl1dHB1dFN0cmVhbVdpdGhSZWFkRGVzYyBleHRlbmRzCisgICAgICAgICAgICBPYmplY3RJbnB1dFN0cmVhbSB7CisgICAgICAgIHByaXZhdGUgQ2xhc3MgcmV0dXJuQ2xhc3M7CisKKyAgICAgICAgcHVibGljIE9iamVjdEl1dHB1dFN0cmVhbVdpdGhSZWFkRGVzYyhJbnB1dFN0cmVhbSBpcywgQ2xhc3MgcmV0dXJuQ2xhc3MpCisgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyKGlzKTsKKyAgICAgICAgICAgIHRoaXMucmV0dXJuQ2xhc3MgPSByZXR1cm5DbGFzczsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgT2JqZWN0U3RyZWFtQ2xhc3MgcmVhZENsYXNzRGVzY3JpcHRvcigpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBPYmplY3RTdHJlYW1DbGFzcy5sb29rdXAocmV0dXJuQ2xhc3MpOworCisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgVGVzdENsYXNzRm9yU2VyaWFsaXphdGlvbiBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCX0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ2xhc3NEZXNjcmlwdG9yKCkgdGhyb3dzIElPRXhjZXB0aW9uLAorCQkJQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisKKwkJQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisJCU9iamVjdE91dHB1dFN0cmVhbVdpdGhXcml0ZURlc2Mgb29zID0gbmV3IE9iamVjdE91dHB1dFN0cmVhbVdpdGhXcml0ZURlc2MoCisJCQkJYmFvcyk7CisJCW9vcy53cml0ZU9iamVjdChTdHJpbmcuY2xhc3MpOworCQlvb3MuY2xvc2UoKTsKKwkJQ2xhc3MgY2xzID0gVGVzdENsYXNzRm9yU2VyaWFsaXphdGlvbi5jbGFzczsKKwkJQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYW9zLnRvQnl0ZUFycmF5KCkpOworCQlPYmplY3RJdXRwdXRTdHJlYW1XaXRoUmVhZERlc2Mgb2lzID0gbmV3IE9iamVjdEl1dHB1dFN0cmVhbVdpdGhSZWFkRGVzYygKKwkJCQliYWlzLCBjbHMpOworCQlPYmplY3Qgb2JqID0gb2lzLnJlYWRPYmplY3QoKTsKKwkJb2lzLmNsb3NlKCk7CisJCWFzc2VydEVxdWFscyhjbHMsIG9iaik7CisJfQorCisJLy8gUmVncmVzc2lvbiBUZXN0IGZvciBKSVJBLTIzNDAKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE9iamVjdE91dHB1dFN0cmVhbVdpdGhXcml0ZURlc2MxIGV4dGVuZHMKKwkJCU9iamVjdE91dHB1dFN0cmVhbSB7CisJCXB1YmxpYyBPYmplY3RPdXRwdXRTdHJlYW1XaXRoV3JpdGVEZXNjMShPdXRwdXRTdHJlYW0gb3MpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJCXN1cGVyKG9zKTsKKwkJfQorCisJCUBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZUNsYXNzRGVzY3JpcHRvcihPYmplY3RTdHJlYW1DbGFzcyBkZXNjKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJCQlzdXBlci53cml0ZUNsYXNzRGVzY3JpcHRvcihkZXNjKTsKKwkJfQorCX0KKworCXB1YmxpYyBzdGF0aWMgY2xhc3MgT2JqZWN0SXV0cHV0U3RyZWFtV2l0aFJlYWREZXNjMSBleHRlbmRzCisJCQlPYmplY3RJbnB1dFN0cmVhbSB7CisKKwkJcHVibGljIE9iamVjdEl1dHB1dFN0cmVhbVdpdGhSZWFkRGVzYzEoSW5wdXRTdHJlYW0gaXMpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJCXN1cGVyKGlzKTsKKwkJfQorCisJCUBPdmVycmlkZQorICAgICAgICBwdWJsaWMgT2JqZWN0U3RyZWFtQ2xhc3MgcmVhZENsYXNzRGVzY3JpcHRvcigpIHRocm93cyBJT0V4Y2VwdGlvbiwKKwkJCQlDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKwkJCXJldHVybiBzdXBlci5yZWFkQ2xhc3NEZXNjcmlwdG9yKCk7CisJCX0KKwl9CisKKyAgICAvLyBSZWdyZXNzaW9uIHRlc3QgZm9yIEhhcm1vbnktMTkyMQorICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgT2JqZWN0SW5wdXRTdHJlYW1XaXRoUmVzb2x2ZSBleHRlbmRzIE9iamVjdElucHV0U3RyZWFtIHsKKyAgICAgICAgcHVibGljIE9iamVjdElucHV0U3RyZWFtV2l0aFJlc29sdmUoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcihpbik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgICAgIHByb3RlY3RlZCBDbGFzcyByZXNvbHZlQ2xhc3MoT2JqZWN0U3RyZWFtQ2xhc3MgZGVzYykKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKGRlc2MuZ2V0TmFtZSgpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLnBrZzEuVGVzdENsYXNzIikpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMucGtnMi5UZXN0Q2xhc3MuY2xhc3M7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gc3VwZXIucmVzb2x2ZUNsYXNzKGRlc2MpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZXNvbHZlQ2xhc3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMucGtnMS5UZXN0Q2xhc3MgdG8xID0gbmV3IG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLnBrZzEuVGVzdENsYXNzKCk7CisgICAgICAgIHRvMS5pID0gNTU1OworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtIG9vcyA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0oYmFvcyk7CisgICAgICAgIG9vcy53cml0ZU9iamVjdCh0bzEpOworICAgICAgICBvb3MuZmx1c2goKTsKKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0gYmFvcy50b0J5dGVBcnJheSgpOworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiYWlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzKTsKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0gb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtV2l0aFJlc29sdmUoYmFpcyk7CisgICAgICAgIG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLnBrZzIuVGVzdENsYXNzIHRvMiA9IChvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5wa2cyLlRlc3RDbGFzcykgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKworICAgICAgICBpZiAodG8yLmkgIT0gdG8xLmkpIHsKKyAgICAgICAgICAgIGZhaWwoIldyb25nIG9iamVjdCByZWFkLiBFeHBlY3RlZCB2YWw6ICIgKyB0bzEuaSArICIsIGdvdDogIgorICAgICAgICAgICAgICAgICAgICArIHRvMi5pKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBPYmplY3RJbnB1dFN0cmVhbVdpdGhSZXNvbHZlT2JqZWN0IGV4dGVuZHMgT2JqZWN0SW5wdXRTdHJlYW0geworCisgICAgICAgIHB1YmxpYyBzdGF0aWMgSW50ZWdlciBpbnRPYmogPSBJbnRlZ2VyLnZhbHVlT2YoMTAwMCk7CisKKyAgICAgICAgcHVibGljIE9iamVjdElucHV0U3RyZWFtV2l0aFJlc29sdmVPYmplY3QoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcihpbik7CisgICAgICAgICAgICBlbmFibGVSZXNvbHZlT2JqZWN0KHRydWUpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBPYmplY3QgcmVzb2x2ZU9iamVjdChPYmplY3Qgb2JqKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaWYob2JqIGluc3RhbmNlb2YgSW50ZWdlcil7CisgICAgICAgICAgICAgICAgb2JqID0gaW50T2JqOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnJlc29sdmVPYmplY3Qob2JqKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0jcmVzb2x2ZU9iamVjdChPYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZXNvbHZlT2JqZWN0TGphdmFfbGFuZ19PYmplY3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gV3JpdGUgYW4gSW50ZWdlciBvYmplY3QgaW50byBtZW1vcnkKKyAgICAgICAgSW50ZWdlciBvcmlnaW5hbCA9IG5ldyBJbnRlZ2VyKDEwKTsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIE9iamVjdE91dHB1dFN0cmVhbSBvb3MgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKGJhb3MpOworICAgICAgICBvb3Mud3JpdGVPYmplY3Qob3JpZ2luYWwpOworICAgICAgICBvb3MuZmx1c2goKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisKKyAgICAgICAgLy8gUmVhZCB0aGUgb2JqZWN0IGZyb20gbWVtb3J5CisgICAgICAgIGJ5dGVbXSBieXRlcyA9IGJhb3MudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcyk7CisgICAgICAgIE9iamVjdElucHV0U3RyZWFtV2l0aFJlc29sdmVPYmplY3Qgb2lzID0KKyAgICAgICAgICAgIG5ldyBPYmplY3RJbnB1dFN0cmVhbVdpdGhSZXNvbHZlT2JqZWN0KGJhaXMpOworICAgICAgICBJbnRlZ2VyIGFjdHVhbCA9IChJbnRlZ2VyKSBvaXMucmVhZE9iamVjdCgpOworICAgICAgICBvaXMuY2xvc2UoKTsKKworICAgICAgICAvLyBvYmplY3Qgc2hvdWxkIGJlIHJlc29sdmVkIGZyb20gMTAgdG8gMTAwMAorICAgICAgICBhc3NlcnRFcXVhbHMoT2JqZWN0SW5wdXRTdHJlYW1XaXRoUmVzb2x2ZU9iamVjdC5pbnRPYmosIGFjdHVhbCk7CisgICAgfQorCisJcHVibGljIHZvaWQgdGVzdF9yZWFkQ2xhc3NEZXNjcmlwdG9yKCkgdGhyb3dzIElPRXhjZXB0aW9uLAorCQkJQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisKKwkJQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisJCU9iamVjdE91dHB1dFN0cmVhbVdpdGhXcml0ZURlc2MxIG9vcyA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW1XaXRoV3JpdGVEZXNjMSgKKwkJCQliYW9zKTsKKwkJT2JqZWN0U3RyZWFtQ2xhc3MgZGVzYyA9IE9iamVjdFN0cmVhbUNsYXNzCisJCS5sb29rdXAoVGVzdENsYXNzRm9yU2VyaWFsaXphdGlvbi5jbGFzcyk7CisJCW9vcy53cml0ZUNsYXNzRGVzY3JpcHRvcihkZXNjKTsKKwkJb29zLmNsb3NlKCk7CisKKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0gYmFvcy50b0J5dGVBcnJheSgpOworCQlCeXRlQXJyYXlJbnB1dFN0cmVhbSBiYWlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzKTsKKwkJT2JqZWN0SXV0cHV0U3RyZWFtV2l0aFJlYWREZXNjMSBvaXMgPSBuZXcgT2JqZWN0SXV0cHV0U3RyZWFtV2l0aFJlYWREZXNjMSgKKwkJCQliYWlzKTsKKwkJT2JqZWN0IG9iaiA9IG9pcy5yZWFkQ2xhc3NEZXNjcmlwdG9yKCk7CisJCW9pcy5jbG9zZSgpOworCQlhc3NlcnRFcXVhbHMoZGVzYy5nZXRDbGFzcygpLCBvYmouZ2V0Q2xhc3MoKSk7CisKKyAgICAgICAgLy9lb2YKKyAgICAgICAgYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcyk7CisgICAgICAgIEV4Y2VwdGlvbmFsQnVmZmVyZWRJbnB1dFN0cmVhbSBiaXMgPSBuZXcgRXhjZXB0aW9uYWxCdWZmZXJlZElucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgIGJhaXMpOworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SXV0cHV0U3RyZWFtV2l0aFJlYWREZXNjMShiaXMpOworCisgICAgICAgIGJpcy5zZXRFT0YodHJ1ZSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iaiA9IG9pcy5yZWFkQ2xhc3NEZXNjcmlwdG9yKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG9pcy5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgLy90aHJvdyBleGNlcHRpb24KKyAgICAgICAgYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcyk7CisgICAgICAgIGJpcyA9IG5ldyBFeGNlcHRpb25hbEJ1ZmZlcmVkSW5wdXRTdHJlYW0oYmFpcyk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJdXRwdXRTdHJlYW1XaXRoUmVhZERlc2MxKGJpcyk7CisKKyAgICAgICAgYmlzLnNldEV4Y2VwdGlvbihuZXcgSU9FeGNlcHRpb24oKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9iaiA9IG9pcy5yZWFkQ2xhc3NEZXNjcmlwdG9yKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG9pcy5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgLy9jb3JydXB0CisgICAgICAgIGJhaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZXMpOworICAgICAgICBiaXMgPSBuZXcgRXhjZXB0aW9uYWxCdWZmZXJlZElucHV0U3RyZWFtKGJhaXMpOworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SXV0cHV0U3RyZWFtV2l0aFJlYWREZXNjMShiaXMpOworCisgICAgICAgIGJpcy5zZXRDb3JydXB0KHRydWUpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmogPSBvaXMucmVhZENsYXNzRGVzY3JpcHRvcigpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2UucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICAgICAgfQorCX0KKworICAgIHN0YXRpYyBjbGFzcyBFeGNlcHRpb25hbEJ1ZmZlcmVkSW5wdXRTdHJlYW0gZXh0ZW5kcyBCdWZmZXJlZElucHV0U3RyZWFtIHsKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGVvZiA9IGZhbHNlOworICAgICAgICBwcml2YXRlIElPRXhjZXB0aW9uIGV4Y2VwdGlvbiA9IG51bGw7CisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBjb3JydXB0ID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIEV4Y2VwdGlvbmFsQnVmZmVyZWRJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbikgeworICAgICAgICAgICAgc3VwZXIoaW4pOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoZXhjZXB0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBleGNlcHRpb247CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChlb2YpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChjb3JydXB0KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gc3VwZXIucmVhZCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0RU9GKGJvb2xlYW4gZW9mKSB7CisgICAgICAgICAgICB0aGlzLmVvZiA9IGVvZjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldEV4Y2VwdGlvbihJT0V4Y2VwdGlvbiBleGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRoaXMuZXhjZXB0aW9uID0gZXhjZXB0aW9uOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0Q29ycnVwdChib29sZWFuIGNvcnJ1cHQpIHsKKyAgICAgICAgICAgIHRoaXMuY29ycnVwdCA9IGNvcnJ1cHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE9iamVjdEl1dHB1dFN0cmVhbVdpdGhSZWFkRGVzYzIgZXh0ZW5kcworICAgICAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0geworICAgICAgICBwcml2YXRlIENsYXNzIHJldHVybkNsYXNzOworCisgICAgICAgIHB1YmxpYyBPYmplY3RJdXRwdXRTdHJlYW1XaXRoUmVhZERlc2MyKElucHV0U3RyZWFtIGlzLCBDbGFzcyByZXR1cm5DbGFzcykKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIoaXMpOworICAgICAgICAgICAgdGhpcy5yZXR1cm5DbGFzcyA9IHJldHVybkNsYXNzOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBPYmplY3RTdHJlYW1DbGFzcyByZWFkQ2xhc3NEZXNjcmlwdG9yKCkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICAgICAgT2JqZWN0U3RyZWFtQ2xhc3Mgb3NjID0gc3VwZXIucmVhZENsYXNzRGVzY3JpcHRvcigpOworCisgICAgICAgICAgICBpZiAob3NjLmdldE5hbWUoKS5lcXVhbHMocmV0dXJuQ2xhc3MuZ2V0TmFtZSgpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3RTdHJlYW1DbGFzcy5sb29rdXAocmV0dXJuQ2xhc3MpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG9zYzsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogVGVzdGluZyBjbGFzc0Rlc2NyaXB0b3IgcmVwbGFjZW1lbnQgd2l0aCB0aGUgdmFsdWUgZ2VuZXJhdGVkIGJ5CisgICAgICogT2JqZWN0U3RyZWFtQ2xhc3MubG9va3VwKCkgbWV0aG9kLgorICAgICAqIFJlZ3Jlc3Npb24gdGVzdCBmb3IgSEFSTU9OWS00NjM4CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkQ2xhc3NEZXNjcmlwdG9yXzEoKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBBIGEgPSBuZXcgQSgpOworICAgICAgICBhLm5hbWUgPSAiSXQncyBhIHRlc3QiOworICAgICAgICBQaXBlZE91dHB1dFN0cmVhbSBwb3V0ID0gbmV3IFBpcGVkT3V0cHV0U3RyZWFtKCk7CisgICAgICAgIFBpcGVkSW5wdXRTdHJlYW0gcGluID0gbmV3IFBpcGVkSW5wdXRTdHJlYW0ocG91dCk7CisgICAgICAgIE9iamVjdE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKHBvdXQpOworICAgICAgICBPYmplY3RJbnB1dFN0cmVhbSBpbiA9IG5ldyBPYmplY3RJdXRwdXRTdHJlYW1XaXRoUmVhZERlc2MyKHBpbiwgQS5jbGFzcyk7CisKKyAgICAgICAgLy8gdGVzdCBzaW5nbGUgb2JqZWN0CisgICAgICAgIG91dC53cml0ZU9iamVjdChhKTsKKyAgICAgICAgQSBhMSA9IChBKSBpbi5yZWFkT2JqZWN0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2luZ2xlIGNhc2U6IGluY29ycmVjdGx5IHJlYWQgdGhlIGZpZWxkIG9mIEEiLCBhLm5hbWUsIGExLm5hbWUpOworCisgICAgICAgIC8vIHRlc3QgY3ljbGljIHJlZmVyZW5jZQorICAgICAgICBIYXNoTWFwIG0gPSBuZXcgSGFzaE1hcCgpOworICAgICAgICBhID0gbmV3IEEoKTsKKyAgICAgICAgYS5uYW1lID0gIkl0J3MgYSB0ZXN0IDAiOworICAgICAgICBhMSA9IG5ldyBBKCk7CisgICAgICAgIGExLm5hbWUgPSAiSXQncyBhIHRlc3QgMSI7CisgICAgICAgIG0ucHV0KCIwIiwgYSk7CisgICAgICAgIG0ucHV0KCIxIiwgYTEpOworICAgICAgICBvdXQud3JpdGVPYmplY3QobSk7CisgICAgICAgIEhhc2hNYXAgbTEgPSAoSGFzaE1hcCkgaW4ucmVhZE9iamVjdCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdGx5IHJlYWQgdGhlIGZpZWxkIG9mIEEiLCBhLm5hbWUsICgoQSkgbTEuZ2V0KCIwIikpLm5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdGx5IHJlYWQgdGhlIGZpZWxkIG9mIEExIiwgYTEubmFtZSwgKChBKSBtMS5nZXQoIjEiKSkubmFtZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWdpc3RlclZhbGlkYXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gUmVncmVzc2lvbiBUZXN0IGZvciBIYXJtb255LTI0MDIKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIG5ldyBPYmplY3RPdXRwdXRTdHJlYW0oYmFvcyk7CisgICAgICAgIE9iamVjdElucHV0U3RyZWFtIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvcy50b0J5dGVBcnJheSgpKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9pcy5yZWdpc3RlclZhbGlkYXRpb24obnVsbCwgMjU2KTsKKyAgICAgICAgICAgIGZhaWwoIk5vdEFjdGl2ZUV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE5vdEFjdGl2ZUV4Y2VwdGlvbiBuYWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBSZWdyZXNzaW9uIFRlc3QgZm9yIEhhcm1vbnktMzkxNgorICAgICAgICBiYW9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0gb29zID0gbmV3IE9iamVjdE91dHB1dFN0cmVhbShiYW9zKTsKKyAgICAgICAgb29zLndyaXRlT2JqZWN0KG5ldyBSZWdpc3RlclZhbGlkYXRpb25DbGFzcygpKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJhaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvcy50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0gZmlzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKGJhaXMpOworICAgICAgICAvLyBzaG91bGQgbm90IHRocm93IE5vdEFjdGl2ZUV4Y2VwdGlvbgorICAgICAgICBmaXMucmVhZE9iamVjdCgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFJlZ2lzdGVyVmFsaWRhdGlvbkNsYXNzIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgICAgICAgIHByaXZhdGUgQSBhID0gbmV3IEEoKTsKKyAgICAgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICAgICAgc3RyZWFtLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisgICAgICAgICAgICBzdHJlYW0ucmVnaXN0ZXJWYWxpZGF0aW9uKG5ldyBNb2NrT2JqZWN0SW5wdXRWYWxpZGF0aW9uKCksIDApOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTW9ja09iamVjdElucHV0VmFsaWRhdGlvbiBpbXBsZW1lbnRzIE9iamVjdElucHV0VmFsaWRhdGlvbiB7CisgICAgICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlT2JqZWN0KCkgdGhyb3dzIEludmFsaWRPYmplY3RFeGNlcHRpb24geworCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvL1JlZ3Jlc3Npb24gVGVzdCBmb3IgSEFSTU9OWS0zNzI2CisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkT2JqZWN0X2FycmF5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgZmluYWwgU3RyaW5nIHJlc291cmNlUHJlZml4ID0gT2JqZWN0SW5wdXRTdHJlYW1UZXN0LmNsYXNzLmdldFBhY2thZ2UoKS5nZXROYW1lKCkucmVwbGFjZSgnLicsICcvJyk7CisKKy8vICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0gb29zID0gbmV3IE9iamVjdE91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbSgiL3RlbXAvdGVzdF9hcnJheV9zdHJpbmdzLnNlciIpKTsKKy8vICAgICAgICBUZXN0QXJyYXkgdGEgPSBuZXcgVGVzdEFycmF5KG5ldyBTdHJpbmdbXSB7ICJBQUEiLCAiQkJCIiB9KTsKKy8vICAgICAgICBvb3Mud3JpdGVPYmplY3QodGEpOworLy8gICAgICAgIG9vcy5jbG9zZSgpOworLy8gICAgICAgIG9vcyA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oIi90ZW1wL3Rlc3RfYXJyYXlfaW50ZWdlcnMuc2VyIikpOworLy8gICAgICAgIHRhID0gbmV3IFRlc3RBcnJheShuZXcgSW50ZWdlcltdIHsgMTAsIDIwIH0pOworLy8gICAgICAgIG9vcy53cml0ZU9iamVjdCh0YSk7CisvLyAgICAgICAgb29zLmNsb3NlKCk7CisKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0gb2luID0gbmV3IE9iamVjdElucHV0U3RyZWFtKHRoaXMuZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpLmdldFJlc291cmNlQXNTdHJlYW0oCisgICAgICAgICAgICAgICAgInNlcmlhbGl6YXRpb24vIiArIHJlc291cmNlUHJlZml4ICsgIi90ZXN0X2FycmF5X3N0cmluZ3Muc2VyIikpOworICAgICAgICBUZXN0QXJyYXkgdGVzdEFycmF5ID0gKFRlc3RBcnJheSkgb2luLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU3RyaW5nW10gc3RyaW5ncyA9IG5ldyBTdHJpbmdbXSB7ICJBQUEiLCAiQkJCIiB9OworICAgICAgICBhc3NlcnRUcnVlKGphdmEudXRpbC5BcnJheXMuZXF1YWxzKHN0cmluZ3MsIHRlc3RBcnJheS5hcnJheSkpOworCisgICAgICAgIG9pbiA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbSh0aGlzLmdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKAorICAgICAgICAgICAgICAgICJzZXJpYWxpemF0aW9uLyIgKyByZXNvdXJjZVByZWZpeCArICIvdGVzdF9hcnJheV9pbnRlZ2Vycy5zZXIiKSk7CisgICAgICAgIHRlc3RBcnJheSA9IChUZXN0QXJyYXkpIG9pbi5yZWFkT2JqZWN0KCk7CisgICAgICAgIEludGVnZXJbXSBpbnRlZ2VycyA9IG5ldyBJbnRlZ2VyW10geyAxMCwgMjAgfTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyhpbnRlZ2VycywgdGVzdEFycmF5LmFycmF5KSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBUZXN0RXh0T2JqZWN0IGltcGxlbWVudHMgRXh0ZXJuYWxpemFibGUgeworICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZUV4dGVybmFsKE9iamVjdE91dHB1dCBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBvdXQud3JpdGVJbnQoMTApOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcmVhZEV4dGVybmFsKE9iamVjdElucHV0IGluKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICAgICAgaW4ucmVhZEludCgpOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFRlc3RPYmplY3RPdXRwdXRTdHJlYW0gZXh0ZW5kcyBPYmplY3RPdXRwdXRTdHJlYW0geworICAgICAgICBwcml2YXRlIE9iamVjdFN0cmVhbUNsYXNzW10gb2JqczsKKyAgICAgICAgcHJpdmF0ZSBpbnQgcG9zID0gMDsKKworICAgICAgICBwdWJsaWMgVGVzdE9iamVjdE91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3V0LCBPYmplY3RTdHJlYW1DbGFzc1tdIG9ianMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcihvdXQpOworICAgICAgICAgICAgdGhpcy5vYmpzID0gb2JqczsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCB3cml0ZUNsYXNzRGVzY3JpcHRvcihPYmplY3RTdHJlYW1DbGFzcyBvc2MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBvYmpzW3BvcysrXSA9IG9zYzsgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgVGVzdE9iamVjdElucHV0U3RyZWFtIGV4dGVuZHMgT2JqZWN0SW5wdXRTdHJlYW0geworICAgICAgICBwcml2YXRlIE9iamVjdFN0cmVhbUNsYXNzW10gb2JqczsKKyAgICAgICAgcHJpdmF0ZSBpbnQgcG9zID0gMDsKKworICAgICAgICBwdWJsaWMgVGVzdE9iamVjdElucHV0U3RyZWFtKElucHV0U3RyZWFtIGluLCBPYmplY3RTdHJlYW1DbGFzc1tdIG9ianMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcihpbik7CisgICAgICAgICAgICB0aGlzLm9ianMgPSBvYmpzOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBPYmplY3RTdHJlYW1DbGFzcyByZWFkQ2xhc3NEZXNjcmlwdG9yKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBvYmpzW3BvcysrXTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgSEFSTU9OWS00OTk2CisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkT2JqZWN0X3JlcGxhY2VkQ2xhc3NEZXNjcmlwdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdFN0cmVhbUNsYXNzW10gb2JqcyA9IG5ldyBPYmplY3RTdHJlYW1DbGFzc1sxMDAwXTsKKyAgICAgICAgUGlwZWRPdXRwdXRTdHJlYW0gcG91dCA9IG5ldyBQaXBlZE91dHB1dFN0cmVhbSgpOworICAgICAgICBQaXBlZElucHV0U3RyZWFtIHBpbiA9IG5ldyBQaXBlZElucHV0U3RyZWFtKHBvdXQpOworICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0gb291dCA9IG5ldyBUZXN0T2JqZWN0T3V0cHV0U3RyZWFtKHBvdXQsIG9ianMpOworICAgICAgICBvb3V0LndyaXRlT2JqZWN0KG5ldyBUZXN0RXh0T2JqZWN0KCkpOworICAgICAgICBvb3V0LndyaXRlT2JqZWN0KCJ0ZXN0Iik7CisgICAgICAgIG9vdXQuY2xvc2UoKTsKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0gb2luID0gbmV3IFRlc3RPYmplY3RJbnB1dFN0cmVhbShwaW4sIG9ianMpOworICAgICAgICBvaW4ucmVhZE9iamVjdCgpOworICAgICAgICBvaW4ucmVhZE9iamVjdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdXAgdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBvcGVuIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzIG1ldGhvZAorICAgICAqIGlzIGNhbGxlZCBiZWZvcmUgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIG9vcyA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0oYmFvID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpKTsKKyAgICB9Cit9CisKK2NsYXNzIFRlc3RBcnJheSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZQoreworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgcHVibGljIE9iamVjdFtdIGFycmF5OworCisgICAgcHVibGljIFRlc3RBcnJheShPYmplY3RbXSBhcnJheSkgeworICAgICAgICB0aGlzLmFycmF5ID0gYXJyYXk7CisgICAgfQorCit9CisKK2NsYXNzIFRlc3QgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisJQ2xhc3MgY2xhc3Nlc1tdID0gbmV3IENsYXNzW10geyBieXRlLmNsYXNzLCBzaG9ydC5jbGFzcywgaW50LmNsYXNzLAorCQkJbG9uZy5jbGFzcywgYm9vbGVhbi5jbGFzcywgY2hhci5jbGFzcywgZmxvYXQuY2xhc3MsIGRvdWJsZS5jbGFzcyB9OworCisJQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisJCWlmICghKG8gaW5zdGFuY2VvZiBUZXN0KSkgeworCQkJcmV0dXJuIGZhbHNlOworCQl9CisJCXJldHVybiBBcnJheXMuZXF1YWxzKGNsYXNzZXMsICgoVGVzdCkgbykuY2xhc3Nlcyk7CisJfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbmV0L0NvbnRlbnRIYW5kbGVyRmFjdG9yeVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL25ldC9Db250ZW50SGFuZGxlckZhY3RvcnlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzRiMjI3NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL25ldC9Db250ZW50SGFuZGxlckZhY3RvcnlUZXN0LmphdmEKQEAgLTAsMCArMSwxNDcgQEAKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS5uZXQ7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5TaWRlRWZmZWN0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0NvbmZpZ3VyYXRpb247CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkZpZWxkOworaW1wb3J0IGphdmEubmV0LkNvbnRlbnRIYW5kbGVyOworaW1wb3J0IGphdmEubmV0LkNvbnRlbnRIYW5kbGVyRmFjdG9yeTsKK2ltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEubmV0LlVSTENvbm5lY3Rpb247CisKK3B1YmxpYyBjbGFzcyBDb250ZW50SGFuZGxlckZhY3RvcnlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgQ29udGVudEhhbmRsZXJGYWN0b3J5IG9sZEZhY3RvcnkgPSBudWxsOworICAgIEZpZWxkIGZhY3RvcnlGaWVsZCA9IG51bGw7CisKKyAgICBib29sZWFuIGlzVGVzdGFibGUgPSBmYWxzZTsKKworICAgIGJvb2xlYW4gaXNHZXRDb250ZW50Q2FsbGVkID0gZmFsc2U7CisgICAgYm9vbGVhbiBpc0NyZWF0ZUNvbnRlbnRIYW5kbGVyQ2FsbGVkID0gZmFsc2U7CisKKyAgICBAU2lkZUVmZmVjdCgiVGhpcyB0ZXN0IGFmZmVjdHMgdGVzdHMgdGhhdCBhcmUgcnVuIGFmdGVyIHRoaXMgb25lLiIgKworICAgICAgICAgICAgIiBUaGUgcmVhc29uIGFyZSBzaWRlIGVmZmVjdHMgZHVlIHRvIGNhY2hpbmcgaW4gVVJMQ29ubmVjdGlvbi4iICsKKyAgICAgICAgICAgICIgTWF5YmUgdGhpcyB0ZXN0IG5lZWRzIHRvIGJlIHJ1biBpbiBpc29sYXRpb24uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NyZWF0ZUNvbnRlbnRIYW5kbGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBUZXN0Q29udGVudEhhbmRsZXJGYWN0b3J5IGZhY3RvcnkgPSAgbmV3IFRlc3RDb250ZW50SGFuZGxlckZhY3RvcnkoKTsKKworICAgICAgICBpZihpc1Rlc3RhYmxlKSB7CisKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGlzQ3JlYXRlQ29udGVudEhhbmRsZXJDYWxsZWQpOworCisgICAgICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovLyIgKworICAgICAgICAgICAgICAgICAgICBTdXBwb3J0X0NvbmZpZ3VyYXRpb24uU3BlY2lhbEluZXRUZXN0QWRkcmVzcyk7CisKKyAgICAgICAgICAgIFVSTENvbm5lY3Rpb24uc2V0Q29udGVudEhhbmRsZXJGYWN0b3J5KGZhY3RvcnkpOworCisgICAgICAgICAgICBVUkxDb25uZWN0aW9uIGNvbiA9IHVybC5vcGVuQ29ubmVjdGlvbigpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNvbi5nZXRDb250ZW50KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShpc0NyZWF0ZUNvbnRlbnRIYW5kbGVyQ2FsbGVkKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGlzR2V0Q29udGVudENhbGxlZCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpc0dldENvbnRlbnRDYWxsZWQgPSBmYWxzZTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjb24uZ2V0Q29udGVudChuZXcgQ2xhc3NbXSB7fSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShpc0dldENvbnRlbnRDYWxsZWQpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjb24uc2V0Q29udGVudEhhbmRsZXJGYWN0b3J5KGZhY3RvcnkpOworICAgICAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5FcnJvciB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2goamF2YS5sYW5nLkVycm9yIGUpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY29uLnNldENvbnRlbnRIYW5kbGVyRmFjdG9yeShudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuRXJyb3Igd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgICAgICB9IGNhdGNoKGphdmEubGFuZy5FcnJvciBlKSB7CisgICAgICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICAgICAgfQorCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBDb250ZW50SGFuZGxlciBjaCA9IGZhY3RvcnkuY3JlYXRlQ29udGVudEhhbmRsZXIoInRleHQvcGxhaW4iKTsKKyAgICAgICAgICAgIFVSTCB1cmw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHVybCA9IG5ldyBVUkwoImh0dHA6Ly8iICsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN1cHBvcnRfQ29uZmlndXJhdGlvbi5TcGVjaWFsSW5ldFRlc3RBZGRyZXNzKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGNoLmdldENvbnRlbnQodXJsLm9wZW5Db25uZWN0aW9uKCkpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHdhcyB0aHJvd246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgeworICAgICAgICBGaWVsZCBbXSBmaWVsZHMgPSBVUkxDb25uZWN0aW9uLmNsYXNzLmdldERlY2xhcmVkRmllbGRzKCk7CisgICAgICAgIGludCBjb3VudGVyID0gMDsKKyAgICAgICAgZm9yIChGaWVsZCBmaWVsZCA6IGZpZWxkcykgeworICAgICAgICAgICAgaWYgKENvbnRlbnRIYW5kbGVyRmFjdG9yeS5jbGFzcy5lcXVhbHMoZmllbGQuZ2V0VHlwZSgpKSkgeworICAgICAgICAgICAgICAgIGNvdW50ZXIrKzsKKyAgICAgICAgICAgICAgICBmYWN0b3J5RmllbGQgPSBmaWVsZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmKGNvdW50ZXIgPT0gMSkgeworCisgICAgICAgICAgICBpc1Rlc3RhYmxlID0gdHJ1ZTsKKworICAgICAgICAgICAgZmFjdG9yeUZpZWxkLnNldEFjY2Vzc2libGUodHJ1ZSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG9sZEZhY3RvcnkgPSAoQ29udGVudEhhbmRsZXJGYWN0b3J5KSBmYWN0b3J5RmllbGQuZ2V0KG51bGwpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIHRocm93biBkdXJpbmcgc2V0VXA6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiB3YXMgdGhyb3duIGR1cmluZyBzZXRVcDogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgaWYoaXNUZXN0YWJsZSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmYWN0b3J5RmllbGQuc2V0KG51bGwsIG9sZEZhY3RvcnkpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIHRocm93biBkdXJpbmcgdGVhckRvd246ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiB3YXMgdGhyb3duIGR1cmluZyB0ZWFyRG93bjogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdENvbnRlbnRIYW5kbGVyIGV4dGVuZHMgQ29udGVudEhhbmRsZXIgeworCisgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29udGVudChVUkxDb25uZWN0aW9uIHUpIHsKKyAgICAgICAgICAgIGlzR2V0Q29udGVudENhbGxlZCA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0Q29udGVudEhhbmRsZXJGYWN0b3J5IGltcGxlbWVudHMgQ29udGVudEhhbmRsZXJGYWN0b3J5IHsKKworICAgICAgICBwdWJsaWMgQ29udGVudEhhbmRsZXIgY3JlYXRlQ29udGVudEhhbmRsZXIoU3RyaW5nIG1pbWV0eXBlKSB7CisgICAgICAgICAgICBpc0NyZWF0ZUNvbnRlbnRIYW5kbGVyQ2FsbGVkID0gdHJ1ZTsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVGVzdENvbnRlbnRIYW5kbGVyKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9uZXQvQ29udGVudEhhbmRsZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9uZXQvQ29udGVudEhhbmRsZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjc2MGQ0MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL25ldC9Db250ZW50SGFuZGxlclRlc3QuamF2YQpAQCAtMCwwICsxLDc2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUCisgKiBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUKKyAqIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCisgKiB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLmphdmEubmV0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Db250ZW50SGFuZGxlcjsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5uZXQuVVJMQ29ubmVjdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIENvbnRlbnRIYW5kbGVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmEubmV0LkNvbnRlbnRIYW5kbGVyI2dldENvbnRlbnQoamF2YS5uZXQuVVJMQ29ubmVjdGlvbiwKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLkNsYXNzW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDb250ZW50KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uID0gbmV3IFVSTCgiaHR0cDovL3d3dy5hcGFjaGUub3JnIikub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgQ2xhc3NbXSBjbGFzc2VzID0geyBGb28uY2xhc3MsIFN0cmluZy5jbGFzcywgfTsKKyAgICAgICAgQ29udGVudEhhbmRsZXIgaGFuZGxlciA9IG5ldyBDb250ZW50SGFuZGxlckltcGwoKTsKKyAgICAgICAgKChDb250ZW50SGFuZGxlckltcGwpIGhhbmRsZXIpLnNldENvbnRlbnQobmV3IEZvbygpKTsKKyAgICAgICAgT2JqZWN0IGNvbnRlbnQgPSBoYW5kbGVyLmdldENvbnRlbnQoY29ubiwgY2xhc3Nlcyk7CisgICAgICAgIGFzc2VydEVxdWFscygiRm9vIiwgKChGb28pIGNvbnRlbnQpLmdldEZvbygpKTsKKworICAgICAgICAoKENvbnRlbnRIYW5kbGVySW1wbCkgaGFuZGxlcikuc2V0Q29udGVudChuZXcgRm9vU3ViKCkpOworICAgICAgICBjb250ZW50ID0gaGFuZGxlci5nZXRDb250ZW50KGNvbm4sIGNsYXNzZXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZvb1N1YiIsICgoRm9vKSBjb250ZW50KS5nZXRGb28oKSk7CisKKyAgICAgICAgQ2xhc3NbXSBjbGFzc2VzMiA9IHsgRm9vU3ViLmNsYXNzLCBTdHJpbmcuY2xhc3MsIH07CisgICAgICAgICgoQ29udGVudEhhbmRsZXJJbXBsKSBoYW5kbGVyKS5zZXRDb250ZW50KG5ldyBGb28oKSk7CisgICAgICAgIGNvbnRlbnQgPSBoYW5kbGVyLmdldENvbnRlbnQoY29ubiwgY2xhc3NlczIpOworICAgICAgICBhc3NlcnROdWxsKGNvbnRlbnQpOworICAgIH0KK30KKworY2xhc3MgQ29udGVudEhhbmRsZXJJbXBsIGV4dGVuZHMgQ29udGVudEhhbmRsZXIgeworCisgICAgcHJpdmF0ZSBPYmplY3QgY29udGVudDsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29udGVudChVUkxDb25uZWN0aW9uIHVDb25uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gY29udGVudDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50KE9iamVjdCBjb250ZW50KSB7CisgICAgICAgIHRoaXMuY29udGVudCA9IGNvbnRlbnQ7CisgICAgfQorfQorCitjbGFzcyBGb28geworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9vKCkgeworICAgICAgICByZXR1cm4gIkZvbyI7CisgICAgfQorfQorCitjbGFzcyBGb29TdWIgZXh0ZW5kcyBGb28geworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9vKCkgeworICAgICAgICByZXR1cm4gIkZvb1N1YiI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbmV0L0h0dHBSZXRyeUV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL25ldC9IdHRwUmV0cnlFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTZiNTg4NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL25ldC9IdHRwUmV0cnlFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw2MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVAorICogV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlCisgKiBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgorICogdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLm5ldDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEubmV0Lkh0dHBSZXRyeUV4Y2VwdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS50ZXN0ZnJhbWV3b3JrLnNlcmlhbGl6YXRpb24uU2VyaWFsaXphdGlvblRlc3Q7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnRlc3RmcmFtZXdvcmsuc2VyaWFsaXphdGlvbi5TZXJpYWxpemF0aW9uVGVzdC5TZXJpYWxpemFibGVBc3NlcnQ7CisKK3B1YmxpYyBjbGFzcyBIdHRwUmV0cnlFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIExPQ0FUSU9OID0gIkh0dHAgdGVzdCI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVUQUlMID0gImRldGFpbCI7CisKKyAgICAvLyBjb21wYXJhdG9yIGZvciBIdHRwUmV0cnlFeGNlcHRpb24gb2JqZWN0cworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFNlcmlhbGl6YWJsZUFzc2VydCBjb21wYXJhdG9yID0gbmV3IFNlcmlhbGl6YWJsZUFzc2VydCgpIHsKKyAgICAgICAgcHVibGljIHZvaWQgYXNzZXJ0RGVzZXJpYWxpemVkKFNlcmlhbGl6YWJsZSByZWZlcmVuY2UsIFNlcmlhbGl6YWJsZSB0ZXN0KSB7CisKKyAgICAgICAgICAgIEh0dHBSZXRyeUV4Y2VwdGlvbiByZWYgPSAoSHR0cFJldHJ5RXhjZXB0aW9uKSByZWZlcmVuY2U7CisgICAgICAgICAgICBIdHRwUmV0cnlFeGNlcHRpb24gdHN0ID0gKEh0dHBSZXRyeUV4Y2VwdGlvbikgdGVzdDsKKworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRMb2NhdGlvbiIsIHJlZi5nZXRMb2NhdGlvbigpLCB0c3QuZ2V0TG9jYXRpb24oKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInJlc3BvbnNlQ29kZSIsIHJlZi5yZXNwb25zZUNvZGUoKSwgdHN0LnJlc3BvbnNlQ29kZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0UmVhc29uIiwgcmVmLmdldFJlYXNvbigpLCB0c3QuZ2V0UmVhc29uKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRNZXNzYWdlIiwgcmVmLmdldE1lc3NhZ2UoKSwgdHN0LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9OworCisgICAgLyoqCisgICAgICogc2VyaWFsaXphdGlvbi9kZXNlcmlhbGl6YXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6YXRpb25TZWxmKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0LnZlcmlmeVNlbGYobmV3IEh0dHBSZXRyeUV4Y2VwdGlvbihERVRBSUwsIDEwMCwKKyAgICAgICAgICAgICAgICBMT0NBVElPTiksIGNvbXBhcmF0b3IpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHNlcmlhbGl6YXRpb24vZGVzZXJpYWxpemF0aW9uIGNvbXBhdGliaWxpdHkgd2l0aCBSSS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXphdGlvbkNvbXBhdGliaWxpdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3QudmVyaWZ5R29sZGVuKHRoaXMsIG5ldyBIdHRwUmV0cnlFeGNlcHRpb24oREVUQUlMLAorICAgICAgICAgICAgICAgIDEwMCwgTE9DQVRJT04pLCBjb21wYXJhdG9yKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9uZXQvVVJMQ29ubmVjdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL25ldC9VUkxDb25uZWN0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmNDE0YzMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9uZXQvVVJMQ29ubmVjdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDE0MDQgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS5uZXQ7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5Ccm9rZW5UZXN0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfQ29uZmlndXJhdGlvbjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfUG9ydE1hbmFnZXI7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1Rlc3RXZWJEYXRhOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9UZXN0V2ViU2VydmVyOworaW1wb3J0IHRlc3RzLnN1cHBvcnQucmVzb3VyY2UuU3VwcG9ydF9SZXNvdXJjZXM7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyOworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRXcml0ZXI7CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLmlvLkZpbGVXcml0ZXI7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW1Xcml0ZXI7CitpbXBvcnQgamF2YS5uZXQuQ2FjaGVSZXF1ZXN0OworaW1wb3J0IGphdmEubmV0LkNhY2hlUmVzcG9uc2U7CitpbXBvcnQgamF2YS5uZXQuRmlsZU5hbWVNYXA7CitpbXBvcnQgamF2YS5uZXQuSHR0cFVSTENvbm5lY3Rpb247CitpbXBvcnQgamF2YS5uZXQuSmFyVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuUmVzcG9uc2VDYWNoZTsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRQZXJtaXNzaW9uOworaW1wb3J0IGphdmEubmV0LlNvY2tldFRpbWVvdXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJJOworaW1wb3J0IGphdmEubmV0LlVSSVN5bnRheEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5uZXQuVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkxTdHJlYW1IYW5kbGVyOworaW1wb3J0IGphdmEubmV0LlVua25vd25TZXJ2aWNlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnRleHQuUGFyc2VFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlRpbWVab25lOworCitwdWJsaWMgY2xhc3MgVVJMQ29ubmVjdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgdGVzdFN0cmluZyA9ICJIZWxsbyBXb3JsZCI7CisKKyAgICBwcml2YXRlIFVSTENvbm5lY3Rpb24gZmlsZVVSTENvbjsKKworICAgIHByaXZhdGUgVVJMIGZpbGVVUkw7CisKKyAgICBwcml2YXRlIEphclVSTENvbm5lY3Rpb24gamFyVVJMQ29uOworCisgICAgcHJpdmF0ZSBVUkxDb25uZWN0aW9uIGdpZlVSTENvbjsKKworICAgIC8qKgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI2FkZFJlcXVlc3RQcm9wZXJ0eShTdHJpbmcsIFN0cmluZyl9CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRSZXF1ZXN0UHJvcGVydHkoKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLAorICAgICAgICAgICAgSU9FeGNlcHRpb24geworCisKKyAgICAgICAgTW9ja1VSTENvbm5lY3Rpb24gdSA9IG5ldyBNb2NrVVJMQ29ubmVjdGlvbihuZXcgVVJMKAorICAgICAgICAgICAgICAgICJodHRwOi8vd3d3LmFwYWNoZS5vcmciKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktNjA0CisgICAgICAgICAgICB1LmFkZFJlcXVlc3RQcm9wZXJ0eShudWxsLCAic29tZVZhbHVlIik7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdS5jb25uZWN0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBzdGF0ZSBvZiBjb25uZWN0aW9uIGlzIGNoZWNrZWQgZmlyc3QKKyAgICAgICAgICAgIC8vIHNvIG5vIE5QRSBpbiBjYXNlIG9mIG51bGwgJ2ZpZWxkJyBwYXJhbQorICAgICAgICAgICAgdS5hZGRSZXF1ZXN0UHJvcGVydHkobnVsbCwgInNvbWVWYWx1ZSIpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGxpbmsgamF2YS5uZXQuVVJMQ29ubmVjdGlvbiNzZXRSZXF1ZXN0UHJvcGVydHkoU3RyaW5nLCBTdHJpbmcpfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0UmVxdWVzdFByb3BlcnR5KCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwKKyAgICAgICAgICAgIElPRXhjZXB0aW9uIHsKKworICAgICAgICBNb2NrVVJMQ29ubmVjdGlvbiB1ID0gbmV3IE1vY2tVUkxDb25uZWN0aW9uKG5ldyBVUkwoCisgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cuYXBhY2hlLm9yZyIpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHUuc2V0UmVxdWVzdFByb3BlcnR5KG51bGwsICJzb21lVmFsdWUiKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdS5zZXRSZXF1ZXN0UHJvcGVydHkoInVzZXItYWdlbnQiLCAiTW96aWxsYS81LjAgKFdpbmRvd3M7IFU7IFdpbmRvd3MgTlQgNS4wOyBkZS1ERTsgcnY6MS43LjUpIEdlY2tvLzIwMDQxMTIyIEZpcmVmb3gvMS4wIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgRXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICB1LmNvbm5lY3QoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gc3RhdGUgb2YgY29ubmVjdGlvbiBpcyBjaGVja2VkIGZpcnN0CisgICAgICAgICAgICAvLyBzbyBubyBOUEUgaW4gY2FzZSBvZiBudWxsICdmaWVsZCcgcGFyYW0KKyAgICAgICAgICAgIHUuc2V0UmVxdWVzdFByb3BlcnR5KG51bGwsICJzb21lVmFsdWUiKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI3NldFVzZUNhY2hlcyhib29sZWFuKX0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFVzZUNhY2hlc1ooKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS03MQorICAgICAgICBNb2NrVVJMQ29ubmVjdGlvbiB1ID0gbmV3IE1vY2tVUkxDb25uZWN0aW9uKG5ldyBVUkwoCisgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cuYXBhY2hlLm9yZyIpKTsKKyAgICAgICAgdS5jb25uZWN0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB1LnNldFVzZUNhY2hlcyh0cnVlKTsKKyAgICAgICAgICAgIGZhaWwoIkFzc2VydCAwOiBleHBlY3RlZCBhbiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGxpbmsgamF2YS5uZXQuVVJMQ29ubmVjdGlvbiNzZXRBbGxvd1VzZXJJbnRlcmFjdGlvbihib29sZWFuKX0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEFsbG93VXNlckludGVyYWN0aW9uWigpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24sCisgICAgICAgICAgICBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS03MgorICAgICAgICBNb2NrVVJMQ29ubmVjdGlvbiB1ID0gbmV3IE1vY2tVUkxDb25uZWN0aW9uKG5ldyBVUkwoCisgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cuYXBhY2hlLm9yZyIpKTsKKyAgICAgICAgdS5jb25uZWN0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB1LnNldEFsbG93VXNlckludGVyYWN0aW9uKGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoIkFzc2VydCAwOiBleHBlY3RlZCBhbiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgTW9ja1VSTENvbm5lY3Rpb24gZXh0ZW5kcyBVUkxDb25uZWN0aW9uIHsKKworICAgICAgICBwdWJsaWMgTW9ja1VSTENvbm5lY3Rpb24oVVJMIHVybCkgeworICAgICAgICAgICAgc3VwZXIodXJsKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjb25uZWN0KCkgeworICAgICAgICAgICAgY29ubmVjdGVkID0gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBOZXdIYW5kbGVyIGV4dGVuZHMgVVJMU3RyZWFtSGFuZGxlciB7CisgICAgICAgIHByb3RlY3RlZCBVUkxDb25uZWN0aW9uIG9wZW5Db25uZWN0aW9uKFVSTCB1KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG5ldyBIdHRwVVJMQ29ubmVjdGlvbih1KSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgY29ubmVjdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgICAgIGNvbm5lY3RlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgZGlzY29ubmVjdCgpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gZG8gbm90aGluZworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIHVzaW5nUHJveHkoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9OworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHBvcnQ7CisKKyAgICBVUkwgdXJsOworCisgICAgVVJMIHVybDI7CisKKyAgICBVUkxDb25uZWN0aW9uIHVjOworCisgICAgVVJMQ29ubmVjdGlvbiB1YzI7CisKKyAgICBTdXBwb3J0X1Rlc3RXZWJTZXJ2ZXIgc2VydmVyOworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKworLy8gICAgICAgIGZ0cFVSTCA9IG5ldyBVUkwoU3VwcG9ydF9Db25maWd1cmF0aW9uLnRlc3RGVFBVUkwpOworCisgICAgICAgIHBvcnQgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgIHNlcnZlciA9IG5ldyBTdXBwb3J0X1Rlc3RXZWJTZXJ2ZXIoKTsKKyAgICAgICAgc2VydmVyLmluaXRTZXJ2ZXIocG9ydCwgZmFsc2UpOworICAgICAgICB1cmwgPSBuZXcgVVJMKCJodHRwOi8vbG9jYWxob3N0OiIgKyBwb3J0ICsgIi90ZXN0MSIpOworICAgICAgICB1YyA9IHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICB1cmwyID0gIG5ldyBVUkwoImh0dHA6Ly9sb2NhbGhvc3Q6IiArIHBvcnQgKyAiL3Rlc3QyIik7CisgICAgICAgIHVjMiA9IHVybDIub3BlbkNvbm5lY3Rpb24oKTsKKworICAgICAgICBmaWxlVVJMID0gY3JlYXRlVGVtcEhlbGxvV29ybGRGaWxlKCk7CisgICAgICAgIGZpbGVVUkxDb24gPSBmaWxlVVJMLm9wZW5Db25uZWN0aW9uKCk7CisKKyAgICAgICAgamFyVVJMQ29uID0gb3BlbkphclVSTENvbm5lY3Rpb24oKTsKKyAgICAgICAgZ2lmVVJMQ29uID0gb3BlbkdpZlVSTENvbm5lY3Rpb24oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgICAgIHNlcnZlci5jbG9zZSgpOworICAgICAgICAoKEh0dHBVUkxDb25uZWN0aW9uKSB1YykuZGlzY29ubmVjdCgpOworICAgICAgICAoKEh0dHBVUkxDb25uZWN0aW9uKSB1YzIpLmRpc2Nvbm5lY3QoKTsKKy8vICAgICAgICBpZiAoKChGdHBVUkxDb25uZWN0aW9uKSBmdHBVUkxDb24pLmdldElucHV0U3RyZWFtKCkgIT0gIG51bGwpIHsKKy8vICAgICAgICAoKEZ0cFVSTENvbm5lY3Rpb24pIGZ0cFVSTENvbikuZ2V0SW5wdXRTdHJlYW0oKS5jbG9zZSgpOworLy8gICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI2FkZFJlcXVlc3RQcm9wZXJ0eShqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkUmVxdWVzdFByb3BlcnR5TGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZygpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIFVSSVN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIHVjLnNldFJlcXVlc3RQcm9wZXJ0eSgicHJvcCIsICJ5byIpOworICAgICAgICB1Yy5zZXRSZXF1ZXN0UHJvcGVydHkoInByb3AiLCAieW8yIik7CisgICAgICAgIGFzc2VydEVxdWFscygieW8yIiwgdWMuZ2V0UmVxdWVzdFByb3BlcnR5KCJwcm9wIikpOworICAgICAgICBNYXA8U3RyaW5nLCBMaXN0PFN0cmluZz4+IG1hcCA9IHVjLmdldFJlcXVlc3RQcm9wZXJ0aWVzKCk7CisgICAgICAgIExpc3Q8U3RyaW5nPiBwcm9wcyA9IHVjLmdldFJlcXVlc3RQcm9wZXJ0aWVzKCkuZ2V0KCJwcm9wIik7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBwcm9wcy5zaXplKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyB0aGUgbWFwIHNob3VsZCBiZSB1bm1vZGlmaWFibGUKKyAgICAgICAgICAgIG1hcC5wdXQoImhpIiwgQXJyYXlzLmFzTGlzdChuZXcgU3RyaW5nW10geyAiYnllIiB9KSk7CisgICAgICAgICAgICBmYWlsKCJjb3VsZCBtb2RpZnkgbWFwIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIHRoZSBsaXN0IHNob3VsZCBiZSB1bm1vZGlmaWFibGUKKyAgICAgICAgICAgIHByb3BzLmFkZCgiaGkiKTsKKyAgICAgICAgICAgIGZhaWwoImNvdWxkIG1vZGlmeSBsaXN0Iik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBKYXJVUkxDb25uZWN0aW9uIGNvbjEgPSBvcGVuSmFyVVJMQ29ubmVjdGlvbigpOworICAgICAgICBtYXAgPSBjb24xLmdldFJlcXVlc3RQcm9wZXJ0aWVzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwobWFwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG1hcC5zaXplKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gdGhlIG1hcCBzaG91bGQgYmUgdW5tb2RpZmlhYmxlCisgICAgICAgICAgICBtYXAucHV0KCJoaSIsIEFycmF5cy5hc0xpc3QobmV3IFN0cmluZ1tdIHsgImJ5ZSIgfSkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEh0dHBQb3N0SGVhZGVycygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBwYXRoID0gIi8iICsgTWF0aC5yYW5kb20oKTsKKyAgICAgICAgSHR0cFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwVVJMQ29ubmVjdGlvbikKKyAgICAgICAgICAgICAgICBuZXcgVVJMKCJodHRwOi8vbG9jYWxob3N0OiIgKyBwb3J0ICsgcGF0aCkub3BlbkNvbm5lY3Rpb24oKTsKKworICAgICAgICAvLyBwb3N0IGEgcmVxdWVzdAorICAgICAgICBjb25uZWN0aW9uLnNldERvT3V0cHV0KHRydWUpOworICAgICAgICBPdXRwdXRTdHJlYW1Xcml0ZXIgd3JpdGVyCisgICAgICAgICAgICAgICAgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKGNvbm5lY3Rpb24uZ2V0T3V0cHV0U3RyZWFtKCkpOworICAgICAgICB3cml0ZXIud3JpdGUoImhlbGxvIik7CisgICAgICAgIHdyaXRlci5mbHVzaCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMjAwLCBjb25uZWN0aW9uLmdldFJlc3BvbnNlQ29kZSgpKTsKKworICAgICAgICAvLyB2YWxpZGF0ZSB0aGUgcmVxdWVzdCBieSBhc2tpbmcgdGhlIHNlcnZlciB3aGF0IHdhcyByZWNlaXZlZAorICAgICAgICBNYXA8U3RyaW5nLCBTdHJpbmc+IGhlYWRlcnMgPSBzZXJ2ZXIucGF0aFRvUmVxdWVzdCgpLmdldChwYXRoKS5nZXRIZWFkZXJzKCk7CisgICAgICAgIGFzc2VydE51bGwoaGVhZGVycy5nZXQoIkFjY2VwdCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQiLCBoZWFkZXJzLmdldCgiQ29udGVudC1UeXBlIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjUiLCBoZWFkZXJzLmdldCgiQ29udGVudC1MZW5ndGgiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibG9jYWxob3N0OiIgKyBwb3J0LCBoZWFkZXJzLmdldCgiSG9zdCIpKTsKKyAgICAgICAgLy8gVE9ETzogdGVzdCBVc2VyLUFnZW50PworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiB7QGxpbmsgamF2YS5uZXQuVVJMQ29ubmVjdGlvbiNnZXRBbGxvd1VzZXJJbnRlcmFjdGlvbigpfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0QWxsb3dVc2VySW50ZXJhY3Rpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB1Yy5zZXRBbGxvd1VzZXJJbnRlcmFjdGlvbihmYWxzZSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJnZXRBbGxvd1VzZXJJbnRlcmFjdGlvbiBzaG91bGQgaGF2ZSByZXR1cm5lZCBmYWxzZSIsIHVjCisgICAgICAgICAgICAgICAgLmdldEFsbG93VXNlckludGVyYWN0aW9uKCkpOworCisgICAgICAgIHVjLnNldEFsbG93VXNlckludGVyYWN0aW9uKHRydWUpOworICAgICAgICBhc3NlcnRUcnVlKCJnZXRBbGxvd1VzZXJJbnRlcmFjdGlvbiBzaG91bGQgaGF2ZSByZXR1cm5lZCB0cnVlIiwgdWMKKyAgICAgICAgICAgICAgICAuZ2V0QWxsb3dVc2VySW50ZXJhY3Rpb24oKSk7CisKKyAgICAgICAgdWMuY29ubmVjdCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB1Yy5zZXRBbGxvd1VzZXJJbnRlcmFjdGlvbihmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3QgaWYgc2V0QWxsb3dVc2VySW50ZXJhY3Rpb24gd29ya3MKKyAgICAgICAgVVJMIHNlcnZlclVSTCA9IG5ldyBVUkwoImh0dHA6Ly9vbmVhcnRoLmpwbC5uYXNhLmdvdi9sYW5kc2F0LmNnaSIpOworCisgICAgICAgIC8vIGNvbm5lY3QgdG8gc2VydmVyCisgICAgICAgIFVSTENvbm5lY3Rpb24gdWMyID0gc2VydmVyVVJMLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGNvbm4gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHVjMjsKKyAgICAgICAgdWMyLnNldEFsbG93VXNlckludGVyYWN0aW9uKHRydWUpOworCisgICAgICAgIHVjMi5zZXREb0lucHV0KHRydWUpOworICAgICAgICB1YzIuc2V0RG9PdXRwdXQodHJ1ZSk7CisKKyAgICAgICAgLy8gZ2V0IHJlZmVyZW5jZSB0byBzdHJlYW0gdG8gcG9zdCB0bworICAgICAgICBPdXRwdXRTdHJlYW0gb3MgPSB1YzIuZ2V0T3V0cHV0U3RyZWFtKCk7CisKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSB1YzIuZ2V0SW5wdXRTdHJlYW0oKTsKKworCisgICAgICAgIGludCBjb250ZW50TGVuZ3RoID0gdWMyLmdldENvbnRlbnRMZW5ndGgoKTsKKyAgICAgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gdWMyLmdldENvbnRlbnRUeXBlKCk7CisgICAgICAgIGludCBudW1CeXRlc1JlYWQgPSAwOworICAgICAgICBpbnQgYWxsQnl0ZXNSZWFkID0gMDsKKworICAgICAgICBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbNDA5Nl07CisKKyAgICAgICAgZG8geworCisgICAgICAgIG51bUJ5dGVzUmVhZCA9IGluLnJlYWQoYnVmZmVyKTsKKyAgICAgICAgYWxsQnl0ZXNSZWFkICs9IGFsbEJ5dGVzUmVhZCArIG51bUJ5dGVzUmVhZDsKKworICAgICAgICB9IHdoaWxlIChudW1CeXRlc1JlYWQgPiAwKTsKKworICAgICAgICBhc3NlcnRUcnVlKGFsbEJ5dGVzUmVhZCA+IDApOworCisgICAgICAgIHVjMi5jb25uZWN0KCk7CisKKyAgICAgICAgbnVtQnl0ZXNSZWFkID0gaW4ucmVhZChidWZmZXIpOworCisgICAgICAgIGFzc2VydEVxdWFscygtMSwgbnVtQnl0ZXNSZWFkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICoge0BsaW5rIGphdmEubmV0LlVSTENvbm5lY3Rpb24jY29ubmVjdCgpfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY29ubmVjdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgdWMuY29ubmVjdCgpOworICAgICAgICAoKEh0dHBVUkxDb25uZWN0aW9uKSB1YykuZGlzY29ubmVjdCgpOworICAgICAgICB1Yy5jb25uZWN0KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHVjLnNldERvT3V0cHV0KGZhbHNlKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGxpbmsgamF2YS5uZXQuVVJMQ29ubmVjdGlvbiNnZXRDb250ZW50KCl9CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDb250ZW50KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJhID0gbmV3IGJ5dGVbdGVzdFN0cmluZy5nZXRCeXRlcygpLmxlbmd0aF07CisgICAgICAgIFN0cmluZyBidWYgPSBudWxsOworCisgICAgICAgIE9iamVjdCBvYmogPSBmaWxlVVJMQ29uLmdldENvbnRlbnQoKTsKKyAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIFN0cmluZykgeworICAgICAgICAgICAgYnVmID0gKFN0cmluZykgb2JqOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGNvbnRlbnQgcmV0dXJuZWQgZnJvbSBmaWxlVVJMOiAiK2J1ZiwKKyAgICAgICAgICAgICAgICAgICAgdGVzdFN0cmluZy5lcXVhbHMoYnVmLnRyaW0oKSkpOworICAgICAgICB9IGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIElucHV0U3RyZWFtKSB7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBpID0gKElucHV0U3RyZWFtKSBvYmo7CisgICAgICAgICAgICBCdWZmZXJlZFJlYWRlciByID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihpKSx0ZXN0U3RyaW5nLmdldEJ5dGVzKCkubGVuZ3RoKTsKKyAgICAgICAgICAgIGJ1ZiA9IHIucmVhZExpbmUoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBjb250ZW50IHJldHVybmVkIGZyb20gZmlsZVVSTDogIitidWYsCisgICAgICAgICAgICAgICAgICAgIHRlc3RTdHJpbmcuZXF1YWxzKGJ1Zi50cmltKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZhaWwoIlNvbWUgdW5rb3duIHR5cGUgaXMgcmV0dXJuZWQgIitvYmoudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICAvL0V4Y2VwdGlvbiB0ZXN0CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vYS9iL2MvP3kiKTsKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBmYWtlQ29uID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgIGZha2VDb24uZ2V0Q29udGVudCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKworICAgICAgICAoKEh0dHBVUkxDb25uZWN0aW9uKSB1YykuZGlzY29ubmVjdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdWMuZ2V0Q29udGVudCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI2dldENvbnRlbnQoQ2xhc3NbXSl9CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDb250ZW50X0xqYXZhbGFuZ0NsYXNzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJhID0gbmV3IGJ5dGVbNjAwXTsKKworICAgICAgICBmaWxlVVJMQ29uLnNldERvSW5wdXQodHJ1ZSk7CisgICAgICAgIGZpbGVVUkxDb24uY29ubmVjdCgpOworCisgICAgICAgIElucHV0U3RyZWFtICBoZWxsb1dvcmxkMiA9IChJbnB1dFN0cmVhbSkgZmlsZVVSTENvbi5nZXRDb250ZW50KG5ldyBDbGFzc1tdIHtJbnB1dFN0cmVhbS5jbGFzc30pOworICAgICAgICBhc3NlcnROb3ROdWxsKGhlbGxvV29ybGQyKTsKKyAgICAgICAgQnVmZmVyZWRSZWFkZXIgciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaGVsbG9Xb3JsZDIpLHRlc3RTdHJpbmcuZ2V0Qnl0ZXMoKS5sZW5ndGgpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgY29udGVudCByZXR1cm5lZCBmcm9tIGZpbGVVUkwiLAorICAgICAgICAgICAgICAgIHRlc3RTdHJpbmcuZXF1YWxzKHIucmVhZExpbmUoKS50cmltKCkpKTsKKworICAgICAgICBTdHJpbmcgdGVzdCA9IChTdHJpbmcpIGZpbGVVUkxDb24uZ2V0Q29udGVudChuZXcgQ2xhc3NbXSB7U3RyaW5nLmNsYXNzfSApOworICAgICAgICBhc3NlcnROdWxsKHRlc3QpOworCisgICAgICAgIC8vRXhjZXB0aW9uIHRlc3QKKyAgICAgICAgKChIdHRwVVJMQ29ubmVjdGlvbikgdWMpLmRpc2Nvbm5lY3QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHVjLmdldENvbnRlbnQoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICgoSW5wdXRTdHJlYW0pIGZpbGVVUkxDb24uZ2V0Q29udGVudChudWxsKSkucmVhZChiYSwgMCwgNjAwKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICgoSW5wdXRTdHJlYW0pIGZpbGVVUkxDb24uZ2V0Q29udGVudChuZXcgQ2xhc3NbXSB7fSkpLnJlYWQoYmEsIDAsIDYwMCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAoKElucHV0U3RyZWFtKSBmaWxlVVJMQ29uLmdldENvbnRlbnQobmV3IENsYXNzW10geyBDbGFzcy5jbGFzcyB9KSkucmVhZChiYSwKKyAgICAgICAgICAgICAgICAgICAgMCwgNjAwKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI2dldENvbnRlbnRFbmNvZGluZygpfQorICAgICAqLworICAgIEBCcm9rZW5UZXN0KCJGYWlscyBpbiBDVFMsIHBhc3NlcyBpbiBDb3JlVGVzdFJ1bm5lciIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDb250ZW50RW5jb2RpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBmYXVsdHkgc2V0dXAKKyAgICAgICAgdHJ5IHsKKworICAgICAgICBmaWxlVVJMQ29uLmdldENvbnRlbnRFbmNvZGluZygpOworICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorCisgICAgICAgIC8vIHBvc2l0aXZlIGNhc2UKKworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovL3d3dy5hbWF6b24uY29tLyIpOworCisgICAgICAgIFVSTENvbm5lY3Rpb24gY29uID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGNvbi5zZXRSZXF1ZXN0UHJvcGVydHkoIkFjY2VwdC1FbmNvZGluZyIsICJnemlwIik7CisgICAgICAgIGNvbi5jb25uZWN0KCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNvbi5nZXRDb250ZW50RW5jb2RpbmcoKSwgImd6aXAiKTsKKworCisgICAgICAgIHVjMi5zZXRSZXF1ZXN0UHJvcGVydHkoIkFjY2VwdC1FbmNvZGluZyIsICJibGEiKTsKKyAgICAgICAgdWMyLmNvbm5lY3QoKTsKKworICAgICAgICBhc3NlcnROdWxsKHVjMi5nZXRDb250ZW50RW5jb2RpbmcoKSk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGxpbmsgamF2YS5uZXQuVVJMQ29ubmVjdGlvbiNnZXRDb250ZW50TGVuZ3RoKCl9CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDb250ZW50TGVuZ3RoKCkgeworICAgICAgICBhc3NlcnRFcXVhbHModGVzdFN0cmluZy5nZXRCeXRlcygpLmxlbmd0aCwKKyAgICAgICAgICAgICAgICBmaWxlVVJMQ29uLmdldENvbnRlbnRMZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhTdXBwb3J0X1Rlc3RXZWJEYXRhLnRlc3QxLmxlbmd0aCwgdWMuZ2V0Q29udGVudExlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFN1cHBvcnRfVGVzdFdlYkRhdGEudGVzdDIubGVuZ3RoLCB1YzIuZ2V0Q29udGVudExlbmd0aCgpKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKGphclVSTENvbi5nZXRDb250ZW50TGVuZ3RoKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKGdpZlVSTENvbi5nZXRDb250ZW50TGVuZ3RoKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI2dldENvbnRlbnRUeXBlKCl9CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDb250ZW50VHlwZSgpIHRocm93cyBJT0V4Y2VwdGlvbiwgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKworICAgICAgICBhc3NlcnRUcnVlKCJnZXRDb250ZW50VHlwZSBmYWlsZWQ6ICIgKyBmaWxlVVJMQ29uLmdldENvbnRlbnRUeXBlKCksCisgICAgICAgICAgICAgICAgZmlsZVVSTENvbi5nZXRDb250ZW50VHlwZSgpLmNvbnRhaW5zKCJ0ZXh0L3BsYWluIikpOworCisgICAgICAgIFVSTENvbm5lY3Rpb24gaHRtbEZpbGVDb24gPSBvcGVuSFRNTEZpbGUoKTsKKyAgICAgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gaHRtbEZpbGVDb24uZ2V0Q29udGVudFR5cGUoKTsKKyAgICAgICAgaWYgKGNvbnRlbnRUeXBlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoY29udGVudFR5cGUuZXF1YWxzSWdub3JlQ2FzZSgidGV4dC9odG1sIikpOworICAgICAgICB9CisKKworICAgICAgICAvKgorICAgICAgICBjb250ZW50VHlwZSA9IHVjLmdldENvbnRlbnRUeXBlKCk7CisgICAgICAgIGlmIChjb250ZW50VHlwZSAhPSBudWxsKSB7CisgICAgICAgIGFzc2VydFRydWUoY29udGVudFR5cGUuZXF1YWxzSWdub3JlQ2FzZSgidGV4dC9odG1sIikpOworICAgICAgICB9CisKKyAgICAgICAgY29udGVudFR5cGUgPSBnaWZVUkxDb24uZ2V0Q29udGVudFR5cGUoKTsKKyAgICAgICAgaWYgKGNvbnRlbnRUeXBlICE9IG51bGwpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjb250ZW50VHlwZS5lcXVhbHNJZ25vcmVDYXNlKCJpbWFnZS9naWYiKSk7CisgICAgICAgIH0KKyAgICAgICAgKi8KKworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI2dldERhdGUoKX0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERhdGUoKSB7CisgICAgICAgIC8vIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gOTMwMDAwMDAwMDAwTCB3aGljaCByZXByZXNlbnRzIHRoZSBwYXN0CisgICAgICAgIGFzc2VydFRydWUoImdldERhdGUgZ2F2ZSB3cm9uZyBkYXRlOiAiICsgdWMuZ2V0RGF0ZSgpLAorICAgICAgICAgICAgICAgIHVjLmdldERhdGUoKSA+IDkzMDAwMDAwMDAwMEwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiB7QGxpbmsgamF2YS5uZXQuVVJMQ29ubmVjdGlvbiNnZXREZWZhdWx0QWxsb3dVc2VySW50ZXJhY3Rpb24oKX0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERlZmF1bHRBbGxvd1VzZXJJbnRlcmFjdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gb2xkU2V0dGluZyA9IFVSTENvbm5lY3Rpb24uZ2V0RGVmYXVsdEFsbG93VXNlckludGVyYWN0aW9uKCk7CisKKyAgICAgICAgVVJMQ29ubmVjdGlvbi5zZXREZWZhdWx0QWxsb3dVc2VySW50ZXJhY3Rpb24oZmFsc2UpOworICAgICAgICBhc3NlcnRGYWxzZSgKKyAgICAgICAgICAgICAgICAiZ2V0RGVmYXVsdEFsbG93VXNlckludGVyYWN0aW9uIHNob3VsZCBoYXZlIHJldHVybmVkIGZhbHNlIiwKKyAgICAgICAgICAgICAgICBVUkxDb25uZWN0aW9uLmdldERlZmF1bHRBbGxvd1VzZXJJbnRlcmFjdGlvbigpKTsKKworICAgICAgICBVUkxDb25uZWN0aW9uLnNldERlZmF1bHRBbGxvd1VzZXJJbnRlcmFjdGlvbih0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0RGVmYXVsdEFsbG93VXNlckludGVyYWN0aW9uIHNob3VsZCBoYXZlIHJldHVybmVkIHRydWUiLAorICAgICAgICAgICAgICAgIFVSTENvbm5lY3Rpb24uZ2V0RGVmYXVsdEFsbG93VXNlckludGVyYWN0aW9uKCkpOworCisgICAgICAgIFVSTENvbm5lY3Rpb24uc2V0RGVmYXVsdEFsbG93VXNlckludGVyYWN0aW9uKG9sZFNldHRpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI2dldERlZmF1bHRSZXF1ZXN0UHJvcGVydHkoU3RyaW5nKX0KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGVmYXVsdFJlcXVlc3RQcm9wZXJ0eUxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICBVUkxDb25uZWN0aW9uLnNldERlZmF1bHRSZXF1ZXN0UHJvcGVydHkoIlNobW9vIiwgIkJsYWgiKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgic2V0RGVmYXVsdFJlcXVlc3RQcm9wZXJ0eSBzaG91bGQgaGF2ZSByZXR1cm5lZDogbnVsbCIsCisgICAgICAgICAgICAgICAgVVJMQ29ubmVjdGlvbi5nZXREZWZhdWx0UmVxdWVzdFByb3BlcnR5KCJTaG1vbyIpKTsKKworICAgICAgICBVUkxDb25uZWN0aW9uLnNldERlZmF1bHRSZXF1ZXN0UHJvcGVydHkoIlNobW9vIiwgIkJvb20iKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgic2V0RGVmYXVsdFJlcXVlc3RQcm9wZXJ0eSBzaG91bGQgaGF2ZSByZXR1cm5lZDogbnVsbCIsCisgICAgICAgICAgICAgICAgVVJMQ29ubmVjdGlvbi5nZXREZWZhdWx0UmVxdWVzdFByb3BlcnR5KCJTaG1vbyIpKTsKKworICAgICAgICBhc3NlcnROdWxsKCJzZXREZWZhdWx0UmVxdWVzdFByb3BlcnR5IHNob3VsZCBoYXZlIHJldHVybmVkOiBudWxsIiwKKyAgICAgICAgICAgICAgICBVUkxDb25uZWN0aW9uLmdldERlZmF1bHRSZXF1ZXN0UHJvcGVydHkoIkthcG93IikpOworCisgICAgICAgIFVSTENvbm5lY3Rpb24uc2V0RGVmYXVsdFJlcXVlc3RQcm9wZXJ0eSgiU2htb28iLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICoge0BsaW5rIGphdmEubmV0LlVSTENvbm5lY3Rpb24jZ2V0RG9JbnB1dCgpfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RG9JbnB1dCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBiZSBzZXQgdG8gdHJ1ZSBieSBkZWZhdWx0IiwgdWMuZ2V0RG9JbnB1dCgpKTsKKworICAgICAgICBmaWxlVVJMQ29uLnNldERvSW5wdXQodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBoYXZlIGJlZW4gc2V0IHRvIHRydWUiLCBmaWxlVVJMQ29uLmdldERvSW5wdXQoKSk7CisKKyAgICAgICAgdWMyLnNldERvSW5wdXQoZmFsc2UpOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIGhhdmUgYmVlbiBzZXQgdG8gZmFsc2UiLCB1YzIuZ2V0RG9JbnB1dCgpKTsKKworICAgICAgICBmaWxlVVJMQ29uLmNvbm5lY3QoKTsKKyAgICAgICAgZmlsZVVSTENvbi5nZXRJbnB1dFN0cmVhbSgpOworCisgICAgICAgIHVjMi5jb25uZWN0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB1YzIuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiB7QGxpbmsgamF2YS5uZXQuVVJMQ29ubmVjdGlvbiNnZXREb091dHB1dCgpfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RG9PdXRwdXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIGJlIHNldCB0byBmYWxzZSBieSBkZWZhdWx0IiwgdWMuZ2V0RG9PdXRwdXQoKSk7CisKKyAgICAgICAgdWMuc2V0RG9PdXRwdXQodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBoYXZlIGJlZW4gc2V0IHRvIHRydWUiLCB1Yy5nZXREb091dHB1dCgpKTsKKworICAgICAgICB1Yy5jb25uZWN0KCk7CisgICAgICAgIHVjLmdldE91dHB1dFN0cmVhbSgpOworCisgICAgICAgIHVjMi5zZXREb091dHB1dChmYWxzZSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgaGF2ZSBiZWVuIHNldCB0byBmYWxzZSIsIHVjMi5nZXREb091dHB1dCgpKTsKKyAgICAgICAgdWMyLmNvbm5lY3QoKTsKKworICAgICAgICB0cnl7CisgICAgICAgICAgICB1YzIuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICoge0BsaW5rIGphdmEubmV0LlVSTENvbm5lY3Rpb24jZ2V0RXhwaXJhdGlvbigpfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RXhwaXJhdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgdWMuY29ubmVjdCgpOworICAgICAgICAvLyBzaG91bGQgYmUgdW5rbm93bgorICAgICAgICBhc3NlcnRFcXVhbHMoImdldEV4cGlyYXRpb24gcmV0dXJuZWQgd3JvbmcgZXhwaXJhdGlvbiIsIDAsIHVjCisgICAgICAgICAgICAgICAgLmdldEV4cGlyYXRpb24oKSk7CisKKyAgICAgICAgdWMyLmNvbm5lY3QoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0RXhwaXJhdGlvbiByZXR1cm5lZCB3cm9uZyBleHBpcmF0aW9uOiAiICsgdWMyCisgICAgICAgICAgICAgICAgLmdldEV4cGlyYXRpb24oKSwgdWMyLmdldEV4cGlyYXRpb24oKSA+IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI2dldEZpbGVOYW1lTWFwKCl9CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRGaWxlTmFtZU1hcCgpIHsKKyAgICAgICAgLy8gVGVzdHMgZm9yIHRoZSBzdGFuZGFyZCBNSU1FIHR5cGVzIC0tIHVzZXJzIG1heSBvdmVycmlkZSB0aGVzZQorICAgICAgICAvLyBpbiB0aGVpciBKUkUKKworICAgICAgICBGaWxlTmFtZU1hcCBtYXBPbGQgPSBVUkxDb25uZWN0aW9uLmdldEZpbGVOYW1lTWFwKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgLy8gVGhlc2UgdHlwZXMgYXJlIGRlZmF1bHRlZAorICAgICAgICBhc3NlcnRFcXVhbHMoInRleHQvaHRtbCIsIG1hcE9sZC5nZXRDb250ZW50VHlwZUZvcigiLmh0bSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0L2h0bWwiLCBtYXBPbGQuZ2V0Q29udGVudFR5cGVGb3IoIi5odG1sIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRleHQvcGxhaW4iLCBtYXBPbGQuZ2V0Q29udGVudFR5cGVGb3IoIi50ZXh0IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRleHQvcGxhaW4iLCBtYXBPbGQuZ2V0Q29udGVudFR5cGVGb3IoIi50eHQiKSk7CisKKyAgICAgICAgLy8gVGhlc2UgdHlwZXMgY29tZSBmcm9tIHRoZSBwcm9wZXJ0aWVzIGZpbGUgOgorICAgICAgICAvLyBub3QgYmxhY2stYm94IHRlc3RpbmcuIFNwZWNpYWwgdGVzdHMgbW92ZWQgdG8gc2V0Q29udGVudFR5cGUKKyAgICAgICAgLyoKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhcHBsaWNhdGlvbi9wZGYiLCBtYXAuZ2V0Q29udGVudFR5cGVGb3IoIi5wZGYiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYXBwbGljYXRpb24vemlwIiwgbWFwLmdldENvbnRlbnRUeXBlRm9yKCIuemlwIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImltYWdlL2dpZiIsIG1hcC5nZXRDb250ZW50VHlwZUZvcigiZ2lmIikpOworICAgICAgICAqLworCisgICAgICAgIFVSTENvbm5lY3Rpb24uc2V0RmlsZU5hbWVNYXAobmV3IEZpbGVOYW1lTWFwKCkgeworICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRDb250ZW50VHlwZUZvcihTdHJpbmcgZmlsZU5hbWUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gIlNwYW0hIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IEZpbGVOYW1lTWFwIHJldHVybmVkIiwgIlNwYW0hIiwKKyAgICAgICAgICAgICAgICAgICAgVVJMQ29ubmVjdGlvbi5nZXRGaWxlTmFtZU1hcCgpLmdldENvbnRlbnRUeXBlRm9yKG51bGwpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIC8vIHVuc2V0IHRoZSBtYXAgc28gb3RoZXIgdGVzdHMgZG9uJ3QgZmFpbAorICAgICAgICAgICAgVVJMQ29ubmVjdGlvbi5zZXRGaWxlTmFtZU1hcChtYXBPbGQpOworICAgICAgICB9CisgICAgICAgIC8vIFJJIGZhaWxzIHNpbmNlIGl0IGRvZXMgbm90IHN1cHBvcnQgZmlsZU5hbWUgdGhhdCBkb2VzIG5vdCBiZWdpbiB3aXRoCisgICAgICAgIC8vICcuJworCisgICAgfQorCisgICAgLyoqCisgICAgICoge0BsaW5rIGphdmEubmV0LlVSTENvbm5lY3Rpb24jZ2V0SGVhZGVyRmllbGREYXRlKGphdmEubGFuZy5TdHJpbmcsIGxvbmcpfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SGVhZGVyRmllbGREYXRlTGphdmFfbGFuZ19TdHJpbmdKKCkgeworICAgICAgICBTdXBwb3J0X1Rlc3RXZWJEYXRhIHBhcmFtcyA9IFN1cHBvcnRfVGVzdFdlYkRhdGEudGVzdFBhcmFtc1swXTsKKworICAgICAgICBsb25nIGhmOworICAgICAgICBoZiA9IHVjLmdldEhlYWRlckZpZWxkRGF0ZSgiQ29udGVudC1FbmNvZGluZyIsIExvbmcuTUlOX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJMb25nIHZhbHVlIHJldHVybmVkIGZvciBoZWFkZXIgZmllbGQgJ0NvbnRlbnQtRW5jb2RpbmcnOiIsCisgICAgICAgICAgICAgICAgTG9uZy5NSU5fVkFMVUUsIGhmKTsKKyAgICAgICAgaGYgPSB1Yy5nZXRIZWFkZXJGaWVsZERhdGUoIkNvbnRlbnQtTGVuZ3RoIiwgTG9uZy5NSU5fVkFMVUUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkxvbmcgdmFsdWUgcmV0dXJuZWQgZm9yIGhlYWRlciBmaWVsZCAnQ29udGVudC1MZW5ndGgnOiAiLAorICAgICAgICAgICAgICAgIExvbmcuTUlOX1ZBTFVFLCBoZik7CisgICAgICAgIGhmID0gdWMuZ2V0SGVhZGVyRmllbGREYXRlKCJDb250ZW50LVR5cGUiLCBMb25nLk1JTl9WQUxVRSk7CisgICAgICAgIGFzc2VydEVxdWFscygiTG9uZyB2YWx1ZSByZXR1cm5lZCBmb3IgaGVhZGVyIGZpZWxkICdDb250ZW50LVR5cGUnOiAiLAorICAgICAgICAgICAgICAgIExvbmcuTUlOX1ZBTFVFLCBoZik7CisgICAgICAgIGhmID0gdWMuZ2V0SGVhZGVyRmllbGREYXRlKCJjb250ZW50LXR5cGUiLCBMb25nLk1JTl9WQUxVRSk7CisgICAgICAgIGFzc2VydEVxdWFscygiTG9uZyB2YWx1ZSByZXR1cm5lZCBmb3IgaGVhZGVyIGZpZWxkICdjb250ZW50LXR5cGUnOiAiLAorICAgICAgICAgICAgICAgIExvbmcuTUlOX1ZBTFVFLCBoZik7CisgICAgICAgIGhmID0gdWMuZ2V0SGVhZGVyRmllbGREYXRlKCJEYXRlIiwgTG9uZy5NSU5fVkFMVUUpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyB2YWx1ZSByZXR1cm5lZCBmb3IgaGVhZGVyIGZpZWxkICdEYXRlJzogIiArIGhmLAorICAgICAgICAgICAgICAgIG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gaGYgPCA1MDAwKTsKKyAgICAgICAgaGYgPSB1Yy5nZXRIZWFkZXJGaWVsZERhdGUoIlNFUlZFUiIsIExvbmcuTUlOX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJMb25nIHZhbHVlIHJldHVybmVkIGZvciBoZWFkZXIgZmllbGQgJ1NFUlZFUic6ICIsCisgICAgICAgICAgICAgICAgTG9uZy5NSU5fVkFMVUUsIGhmKTsKKyAgICAgICAgaGYgPSB1Yy5nZXRIZWFkZXJGaWVsZERhdGUoIkxhc3QtTW9kaWZpZWQiLCBMb25nLk1JTl9WQUxVRSk7CisgICAgICAgIGFzc2VydEVxdWFscygiTG9uZyB2YWx1ZSByZXR1cm5lZCBmb3IgaGVhZGVyIGZpZWxkICdMYXN0LU1vZGlmaWVkJzogIiwKKyAgICAgICAgICAgICAgICBMb25nLk1JTl9WQUxVRSwgaGYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI2dldEhlYWRlckZpZWxkKGludCl9CisgICAgICovCisgICAgcHVibGljIHZvaWQgRElTQUJMRURfdGVzdF9nZXRIZWFkZXJGaWVsZEkoKSB7CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgU3RyaW5nIGhmOworICAgICAgICBib29sZWFuIGZvdW5kUmVzcG9uc2UgPSBmYWxzZTsKKyAgICAgICAgd2hpbGUgKChoZiA9IHVjLmdldEhlYWRlckZpZWxkKGkrKykpICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChoZi5lcXVhbHMoU3VwcG9ydF9Db25maWd1cmF0aW9uLkhvbWVBZGRyZXNzU29mdHdhcmUpKSB7CisgICAgICAgICAgICAgICAgZm91bmRSZXNwb25zZSA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ291bGQgbm90IGZpbmQgaGVhZGVyIGZpZWxkIGNvbnRhaW5pbmcgXCIiCisgICAgICAgICAgICAgICAgKyBTdXBwb3J0X0NvbmZpZ3VyYXRpb24uSG9tZUFkZHJlc3NTb2Z0d2FyZSArICJcIiIsCisgICAgICAgICAgICAgICAgZm91bmRSZXNwb25zZSk7CisKKyAgICAgICAgaSA9IDA7CisgICAgICAgIGZvdW5kUmVzcG9uc2UgPSBmYWxzZTsKKyAgICAgICAgd2hpbGUgKChoZiA9IHVjLmdldEhlYWRlckZpZWxkKGkrKykpICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChoZi5lcXVhbHMoU3VwcG9ydF9Db25maWd1cmF0aW9uLkhvbWVBZGRyZXNzUmVzcG9uc2UpKSB7CisgICAgICAgICAgICAgICAgZm91bmRSZXNwb25zZSA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ291bGQgbm90IGZpbmQgaGVhZGVyIGZpZWxkIGNvbnRhaW5pbmcgXCIiCisgICAgICAgICAgICAgICAgKyBTdXBwb3J0X0NvbmZpZ3VyYXRpb24uSG9tZUFkZHJlc3NSZXNwb25zZSArICJcIiIsCisgICAgICAgICAgICAgICAgZm91bmRSZXNwb25zZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0BsaW5rIGphdmEubmV0LlVSTENvbm5lY3Rpb24jZ2V0SGVhZGVyRmllbGRLZXkoaW50KX0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBESVNBQkxFRF90ZXN0X2dldEhlYWRlckZpZWxkS2V5SSgpIHsKKyAgICAgICAgU3RyaW5nIGhmOworICAgICAgICBib29sZWFuIGZvdW5kUmVzcG9uc2UgPSBmYWxzZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykgeworICAgICAgICAgICAgaGYgPSB1Yy5nZXRIZWFkZXJGaWVsZEtleShpKTsKKyAgICAgICAgICAgIGlmIChoZiAhPSBudWxsICYmIGhmLnRvTG93ZXJDYXNlKCkuZXF1YWxzKCJjb250ZW50LXR5cGUiKSkgeworICAgICAgICAgICAgICAgIGZvdW5kUmVzcG9uc2UgPSB0cnVlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIkNvdWxkIG5vdCBmaW5kIGhlYWRlciBmaWVsZCBrZXkgY29udGFpbmluZyBcImNvbnRlbnQtdHlwZVwiIiwKKyAgICAgICAgICAgICAgICBmb3VuZFJlc3BvbnNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICoge0BsaW5rIGphdmEubmV0LlVSTENvbm5lY3Rpb24jZ2V0SGVhZGVyRmllbGRJbnQoU3RyaW5nLCBpbnQpfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SGVhZGVyRmllbGRJbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24sIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgICAgU3VwcG9ydF9UZXN0V2ViRGF0YSBwYXJhbXMgPSBTdXBwb3J0X1Rlc3RXZWJEYXRhLnRlc3RQYXJhbXNbMV07CisKKyAgICAgICAgaW50IGhmID0gMDsKKyAgICAgICAgaGYgPSB1YzIuZ2V0SGVhZGVyRmllbGRJbnQoIkNvbnRlbnQtRW5jb2RpbmciLCBJbnRlZ2VyLk1JTl9WQUxVRSk7CisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLk1JTl9WQUxVRSwgaGYpOworICAgICAgICBoZiA9IHVjMi5nZXRIZWFkZXJGaWVsZEludCgiQ29udGVudC1MZW5ndGgiLCBJbnRlZ2VyLk1JTl9WQUxVRSk7CisgICAgICAgIGFzc2VydEVxdWFscyhwYXJhbXMudGVzdExlbmd0aCwgaGYpOworICAgICAgICBoZiA9IHVjMi5nZXRIZWFkZXJGaWVsZEludCgiQ29udGVudC1UeXBlIiwgSW50ZWdlci5NSU5fVkFMVUUpOworICAgICAgICBhc3NlcnRFcXVhbHMoSW50ZWdlci5NSU5fVkFMVUUsIGhmKTsKKyAgICAgICAgaGYgPSB1YzIuZ2V0SGVhZGVyRmllbGRJbnQoIkRhdGUiLCBJbnRlZ2VyLk1JTl9WQUxVRSk7CisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLk1JTl9WQUxVRSwgaGYpOworICAgICAgICBoZiA9IHVjMi5nZXRIZWFkZXJGaWVsZEludCgiRXhwaXJlcyIsIEludGVnZXIuTUlOX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEludGVnZXIuTUlOX1ZBTFVFLCBoZik7CisgICAgICAgIGhmID0gdWMyLmdldEhlYWRlckZpZWxkSW50KCJTRVJWRVIiLCBJbnRlZ2VyLk1JTl9WQUxVRSk7CisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLk1JTl9WQUxVRSwgaGYpOworICAgICAgICBoZiA9IHVjMi5nZXRIZWFkZXJGaWVsZEludCgiTGFzdC1Nb2RpZmllZCIsIEludGVnZXIuTUlOX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEludGVnZXIuTUlOX1ZBTFVFLCBoZik7CisgICAgICAgIGhmID0gdWMyLmdldEhlYWRlckZpZWxkSW50KCJhY2NlcHQtcmFuZ2VzIiwgSW50ZWdlci5NSU5fVkFMVUUpOworICAgICAgICBhc3NlcnRFcXVhbHMoSW50ZWdlci5NSU5fVkFMVUUsIGhmKTsKKyAgICAgICAgaGYgPSB1YzIuZ2V0SGVhZGVyRmllbGRJbnQoIkRvZXNOb3RFeGlzdCIsIEludGVnZXIuTUlOX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEludGVnZXIuTUlOX1ZBTFVFLCBoZik7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGxpbmsgamF2YS5uZXQuVVJMQ29ubmVjdGlvbiNnZXRIZWFkZXJGaWVsZChqYXZhLmxhbmcuU3RyaW5nKX0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEhlYWRlckZpZWxkTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIFN1cHBvcnRfVGVzdFdlYkRhdGEgcGFyYW1zID0gU3VwcG9ydF9UZXN0V2ViRGF0YS50ZXN0UGFyYW1zWzBdOworCisgICAgICAgIFN0cmluZyBoZjsKKyAgICAgICAgaGYgPSB1Yy5nZXRIZWFkZXJGaWVsZCgiQ29udGVudC1FbmNvZGluZyIpOworICAgICAgICBhc3NlcnROdWxsKCJTdHJpbmcgdmFsdWUgcmV0dXJuZWQgZm9yIGhlYWRlciBmaWVsZCAnQ29udGVudC1FbmNvZGluZyc6IiwKKyAgICAgICAgICAgICAgICBoZik7CisgICAgICAgIGhmID0gdWMuZ2V0SGVhZGVyRmllbGQoIkNvbnRlbnQtTGVuZ3RoIik7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgcmV0dXJuZWQgZm9yIGhlYWRlciBmaWVsZCAnQ29udGVudC1MZW5ndGgnOiAiLAorICAgICAgICAgICAgICAgIFN0cmluZy52YWx1ZU9mKHBhcmFtcy50ZXN0TGVuZ3RoKSwgaGYpOworICAgICAgICBoZiA9IHVjLmdldEhlYWRlckZpZWxkKCJDb250ZW50LVR5cGUiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSByZXR1cm5lZCBmb3IgaGVhZGVyIGZpZWxkICdDb250ZW50LVR5cGUnOiAiLAorICAgICAgICAgICAgICAgIHBhcmFtcy50ZXN0VHlwZSwgaGYpOworICAgICAgICBoZiA9IHVjLmdldEhlYWRlckZpZWxkKCJjb250ZW50LXR5cGUiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSByZXR1cm5lZCBmb3IgaGVhZGVyIGZpZWxkICdjb250ZW50LXR5cGUnOiAiLAorICAgICAgICAgICAgICAgIHBhcmFtcy50ZXN0VHlwZSwgaGYpOworICAgICAgICBoZiA9IHVjLmdldEhlYWRlckZpZWxkKCJEYXRlIik7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHN0cmluZyB2YWx1ZSByZXR1cm5lZCBmb3IgaGVhZGVyIGZpZWxkICdEYXRlJzogIgorICAgICAgICAgICAgICAgICsgaGYsIGhmLmxlbmd0aCgpID4gMjApOworICAgICAgICBoZiA9IHVjLmdldEhlYWRlckZpZWxkKCJTRVJWRVIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSByZXR1cm5lZCBmb3IgaGVhZGVyIGZpZWxkICdTRVJWRVInOiAiLAorICAgICAgICAgICAgICAgICJUZXN0V2ViU2VydmVyIiArIHBvcnQsIGhmKTsKKyAgICAgICAgaGYgPSB1Yy5nZXRIZWFkZXJGaWVsZCgiTGFzdC1Nb2RpZmllZCIpOworICAgICAgICBhc3NlcnROdWxsKCJXcm9uZyBzdHJpbmcgdmFsdWUgcmV0dXJuZWQgZm9yICdMYXN0LU1vZGlmaWVkJzogIgorICAgICAgICAgICAgICAgICsgaGYsIGhmKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIFVSSVN5bnRheEV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI2dldEhlYWRlckZpZWxkcygpfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SGVhZGVyRmllbGRzKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLCBVUklTeW50YXhFeGNlcHRpb24geworICAgICAgICBTdXBwb3J0X1Rlc3RXZWJEYXRhIHBhcmFtcyA9IFN1cHBvcnRfVGVzdFdlYkRhdGEudGVzdFBhcmFtc1sxXTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdWMyLmdldElucHV0U3RyZWFtKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkVycm9yIGluIHRlc3Qgc2V0dXA6ICIrZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PiBoZWFkZXJzID0gdWMyLmdldEhlYWRlckZpZWxkcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKGhlYWRlcnMpOworCisgICAgICAgIExpc3Q8U3RyaW5nPiBsaXN0ID0gaGVhZGVycy5nZXQoImNvbnRlbnQtdHlwZSIpOworICAgICAgICBpZiAobGlzdCA9PSBudWxsKSB7CisgICAgICAgICAgICBsaXN0ID0gaGVhZGVycy5nZXQoIkNvbnRlbnQtVHlwZSIpOworICAgICAgICB9CisgICAgICAgIGlmIChsaXN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIGxpc3QgPSBoZWFkZXJzLmdldCgiQ29udGVudC10eXBlIik7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnROb3ROdWxsKGxpc3QpOworICAgICAgICBTdHJpbmcgY29udGVudFR5cGUgPSAoU3RyaW5nKSBsaXN0LmdldCgwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHBhcmFtcy50ZXN0VHlwZSwgY29udGVudFR5cGUpOworCisgICAgICAgIC8vIHRoZXJlIHNob3VsZCBiZSBhdCBsZWFzdCAyIGhlYWRlcnMKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTm90IG1vcmUgdGhhbiBvbmUgaGVhZGVyIGluIFVSTCBjb25uZWN0aW9uIiwKKyAgICAgICAgICAgICAgICBoZWFkZXJzLnNpemUoKSA+IDEpOworCisgICAgICAgIGhlYWRlcnMgPSBqYXJVUkxDb24uZ2V0SGVhZGVyRmllbGRzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoaGVhZGVycyk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBoZWFkZXJzLnNpemUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIHRoZSBtYXAgc2hvdWxkIGJlIHVubW9kaWZpYWJsZQorICAgICAgICAgICAgaGVhZGVycy5wdXQoImhpIiwgQXJyYXlzLmFzTGlzdChuZXcgU3RyaW5nW10geyAiYnllIiB9KSk7CisgICAgICAgICAgICBmYWlsKCJUaGUgbWFwIHNob3VsZCBiZSB1bm1vZGlmaWFibGUiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiB7QGxpbmsgamF2YS5uZXQuVVJMQ29ubmVjdGlvbiNnZXRMYXN0TW9kaWZpZWQoKX0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldExhc3RNb2RpZmllZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgVVJMIHVybDQgPSBuZXcgVVJMKFN1cHBvcnRfQ29uZmlndXJhdGlvbi5oVFRQVVJMd0xhc3RNb2RpZmllZCk7CisgICAgICAgIFVSTENvbm5lY3Rpb24gdWM0ID0gdXJsNC5vcGVuQ29ubmVjdGlvbigpOworCisgICAgICAgIHVjNC5jb25uZWN0KCk7CisKKyAgICAgICAgaWYgKHVjNC5nZXRMYXN0TW9kaWZpZWQoKSA9PSAwKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0CisgICAgICAgICAgICAgICAgICAgIC5wcmludGxuKCJXQVJOSU5HOiBTZXJ2ZXIgZG9lcyBub3Qgc3VwcG9ydCAnTGFzdC1Nb2RpZmllZCcsIHRlc3RfZ2V0TGFzdE1vZGlmaWVkKCkgbm90IHJ1biIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgbG9uZyBtaWxsaXMgPSB1YzQuZ2V0SGVhZGVyRmllbGREYXRlKCJMYXN0LU1vZGlmaWVkIiwgMCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICJSZXR1cm5lZCB3cm9uZyBnZXRMYXN0TW9kaWZpZWQgdmFsdWUuICBXYW50ZWQ6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiBnb3Q6ICIgKyB1YzQuZ2V0TGFzdE1vZGlmaWVkKCksCisgICAgICAgICAgICAgICAgbWlsbGlzLCB1YzQuZ2V0TGFzdE1vZGlmaWVkKCkpOworCisKKyAgICAgICAgKChIdHRwVVJMQ29ubmVjdGlvbikgdWMpLmRpc2Nvbm5lY3QoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBwb3N0ZWQgPSAidGhpcyBpcyBhIHRlc3QiOworICAgICAgICBVUkxDb25uZWN0aW9uIHVjMyA9IG5ldyBVUkwoU3VwcG9ydF9Db25maWd1cmF0aW9uLmhUVFBVUkxnb29nbGUpCisgICAgICAgICAgICAgICAgLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIHVjMy5zZXREb091dHB1dCh0cnVlKTsKKyAgICAgICAgdWMzLmNvbm5lY3QoKTsKKworICAgICAgICBCdWZmZXJlZFdyaXRlciB3ID0gbmV3IEJ1ZmZlcmVkV3JpdGVyKG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIodWMzCisgICAgICAgICAgICAgICAgLmdldE91dHB1dFN0cmVhbSgpKSwgcG9zdGVkLmdldEJ5dGVzKCkubGVuZ3RoKTsKKworICAgICAgICB3LndyaXRlKHBvc3RlZCk7CisgICAgICAgIHcuZmx1c2goKTsKKyAgICAgICAgdy5jbG9zZSgpOworCisgICAgICAgIGludCBjb2RlID0gKChIdHRwVVJMQ29ubmVjdGlvbikgdWMzKS5nZXRSZXNwb25zZUNvZGUoKTsKKworCisgICAgICAgIC8vIHdyaXRpbmcgdG8gdXJsIG5vdCBhbGxvd2VkCisgICAgICAgIGFzc2VydEVxdWFscygiR290IGRpZmZlcmVudCByZXNwb25zZUNvZGUgIiwgNDA1LCBjb2RlKTsKKworCisgICAgICAgIC8vIHRyeSBleGNlcHRpb24gdGVzdGluZworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmlsZVVSTENvbi5zZXREb091dHB1dCh0cnVlKTsKKyAgICAgICAgICAgIGZpbGVVUkxDb24uY29ubmVjdCgpOworICAgICAgICAgICAgZmlsZVVSTENvbi5nZXRPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgfSBjYXRjaCAoVW5rbm93blNlcnZpY2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sgY2Fubm90IHdyaXRlIHRvIGZpbGVVUkwKKyAgICAgICAgfQorCisgICAgICAgICgoSHR0cFVSTENvbm5lY3Rpb24pIHVjMikuZGlzY29ubmVjdCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB1YzIuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI2dldFJlcXVlc3RQcm9wZXJ0aWVzKCl9CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRSZXF1ZXN0UHJvcGVydGllcygpIHsKKyAgICAgICAgdWMuc2V0UmVxdWVzdFByb3BlcnR5KCJ3aGF0ZXZlciIsICJ5b3UgbGlrZSIpOworICAgICAgICBNYXAgaGVhZGVycyA9IHVjLmdldFJlcXVlc3RQcm9wZXJ0aWVzKCk7CisKKyAgICAgICAgLy8gY29udGVudC1sZW5ndGggc2hvdWxkIGFsd2F5cyBhcHBlYXIKKyAgICAgICAgTGlzdCBoZWFkZXIgPSAoTGlzdCkgaGVhZGVycy5nZXQoIndoYXRldmVyIik7CisgICAgICAgIGFzc2VydE5vdE51bGwoaGVhZGVyKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoInlvdSBsaWtlIiwgaGVhZGVyLmdldCgwKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShoZWFkZXJzLnNpemUoKSA+PSAxKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gdGhlIG1hcCBzaG91bGQgYmUgdW5tb2RpZmlhYmxlCisgICAgICAgICAgICBoZWFkZXJzLnB1dCgiaGkiLCAiYnllIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gdGhlIGxpc3Qgc2hvdWxkIGJlIHVubW9kaWZpYWJsZQorICAgICAgICAgICAgaGVhZGVyLmFkZCgiaGkiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGxpbmsgamF2YS5uZXQuVVJMQ29ubmVjdGlvbiNnZXRSZXF1ZXN0UHJvcGVydGllcygpfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UmVxdWVzdFByb3BlcnRpZXNfRXhjZXB0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHAiLCAidGVzdCIsIDgwLCAiaW5kZXguaHRtbCIsIG5ldyBOZXdIYW5kbGVyKCkpOworICAgICAgICBVUkxDb25uZWN0aW9uIHVybENvbiA9IHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICB1cmxDb24uY29ubmVjdCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB1cmxDb24uZ2V0UmVxdWVzdFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI2dldFJlcXVlc3RQcm9wZXJ0eShqYXZhLmxhbmcuU3RyaW5nKX0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFJlcXVlc3RQcm9wZXJ0eV9MU3RyaW5nX0V4Y2VwdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwIiwgInRlc3QiLCA4MCwgImluZGV4Lmh0bWwiLCBuZXcgTmV3SGFuZGxlcigpKTsKKyAgICAgICAgVVJMQ29ubmVjdGlvbiB1cmxDb24gPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgdXJsQ29uLnNldFJlcXVlc3RQcm9wZXJ0eSgidGVzdCIsICJ0ZXN0UHJvcGVydHkiKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh1cmxDb24uZ2V0UmVxdWVzdFByb3BlcnR5KCJ0ZXN0IikpOworCisgICAgICAgIHVybENvbi5jb25uZWN0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB1cmxDb24uZ2V0UmVxdWVzdFByb3BlcnR5KCJ0ZXN0Iik7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICoge0BsaW5rIGphdmEubmV0LlVSTENvbm5lY3Rpb24jZ2V0UmVxdWVzdFByb3BlcnR5KGphdmEubGFuZy5TdHJpbmcpfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UmVxdWVzdFByb3BlcnR5TGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIHVjLnNldFJlcXVlc3RQcm9wZXJ0eSgiWW8iLCAieW8iKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcHJvcGVydHkgcmV0dXJuZWQ6ICIgKyB1Yy5nZXRSZXF1ZXN0UHJvcGVydHkoIllvIiksCisgICAgICAgICAgICAgICAgdWMuZ2V0UmVxdWVzdFByb3BlcnR5KCJZbyIpLmVxdWFscygieW8iKSk7CisgICAgICAgIGFzc2VydE51bGwoIldyb25nIHByb3BlcnR5IHJldHVybmVkOiAiICsgdWMuZ2V0UmVxdWVzdFByb3BlcnR5KCJObyIpLAorICAgICAgICAgICAgICAgIHVjLmdldFJlcXVlc3RQcm9wZXJ0eSgiTm8iKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0BsaW5rIGphdmEubmV0LlVSTENvbm5lY3Rpb24jZ2V0VVJMKCl9CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRVUkwoKSB7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBVUkwgcmV0dXJuZWQiLCB1Yy5nZXRVUkwoKS5lcXVhbHModXJsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI2dldFVzZUNhY2hlcygpfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0VXNlQ2FjaGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdWMyLnNldFVzZUNhY2hlcyhmYWxzZSk7CisgICAgICAgIGFzc2VydFRydWUoImdldFVzZUNhY2hlcyBzaG91bGQgaGF2ZSByZXR1cm5lZCBmYWxzZSIsICF1YzIKKyAgICAgICAgICAgICAgICAuZ2V0VXNlQ2FjaGVzKCkpOworICAgICAgICB1YzIuc2V0VXNlQ2FjaGVzKHRydWUpOworICAgICAgICBhc3NlcnRUcnVlKCJnZXRVc2VDYWNoZXMgc2hvdWxkIGhhdmUgcmV0dXJuZWQgdHJ1ZSIsIHVjMi5nZXRVc2VDYWNoZXMoKSk7CisKKyAgICAgICAgdWMyLmNvbm5lY3QoKTsKKworCisgICAgICAgIHRyeSB7CisgICAgICAgIHVjMi5zZXRVc2VDYWNoZXMoZmFsc2UpOworICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorCisgICAgICAgICgoSHR0cFVSTENvbm5lY3Rpb24pIHVjMikuZGlzY29ubmVjdCgpOworCisgICAgfQorCisgICAgLyoqCisgICAgICoge0BsaW5rIGphdmEubmV0LlVSTENvbm5lY3Rpb24jZ3Vlc3NDb250ZW50VHlwZUZyb21OYW1lKFN0cmluZyl9CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9ndWVzc0NvbnRlbnRUeXBlRnJvbU5hbWUoKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBVUkxDb25uZWN0aW9uIGh0bWxGaWxlQ29uID0gb3BlbkhUTUxGaWxlKCk7CisgICAgICAgIFN0cmluZ1tdIGV4cGVjdGVkID0gbmV3IFN0cmluZ1tdIHsidGV4dC9odG1sIiwKKyAgICAgICAgICAgICAgICAidGV4dC9wbGFpbiIgfTsKKyAgICAgICAgU3RyaW5nW10gcmVzb3VyY2VzID0gbmV3IFN0cmluZ1tdIHsKKyAgICAgICAgICAgICAgICBodG1sRmlsZUNvbi5nZXRVUkwoKS50b1N0cmluZygpLAorICAgICAgICAgICAgICAgIGZpbGVVUkwudG9TdHJpbmcoKQorICAgICAgICAgICAgICAgIH07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVzb3VyY2VzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIG1pbWUgPSBVUkxDb25uZWN0aW9uLmd1ZXNzQ29udGVudFR5cGVGcm9tTmFtZSggcmVzb3VyY2VzW2ldKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImNoZWNraW5nICIgKyByZXNvdXJjZXNbaV0gKyAiIGV4cGVjdGVkICIgKyBleHBlY3RlZFtpXSsiZ290ICIgKyBleHBlY3RlZFtpXSwKKyAgICAgICAgICAgICAgICBleHBlY3RlZFtpXSwgbWltZSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBUcnkgc2ltcGxlIGNhc2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFVSTENvbm5lY3Rpb24uZ3Vlc3NDb250ZW50VHlwZUZyb21TdHJlYW0obnVsbCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI2d1ZXNzQ29udGVudFR5cGVGcm9tU3RyZWFtKGphdmEuaW8uSW5wdXRTdHJlYW0pfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ3Vlc3NDb250ZW50VHlwZUZyb21TdHJlYW1MamF2YV9pb19JbnB1dFN0cmVhbSgpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBhc3NlcnRDb250ZW50VHlwZUVxdWFscygiQVNDSUkiLCAidGV4dC9odG1sIiwgIjxodG1sPiIpOworICAgICAgICBhc3NlcnRDb250ZW50VHlwZUVxdWFscygiQVNDSUkiLCAidGV4dC9odG1sIiwgIjxoZWFkPiIpOworICAgICAgICBhc3NlcnRDb250ZW50VHlwZUVxdWFscygiQVNDSUkiLCAidGV4dC9odG1sIiwgIjxoZWFkICIpOworICAgICAgICBhc3NlcnRDb250ZW50VHlwZUVxdWFscygiQVNDSUkiLCAidGV4dC9odG1sIiwgIjxib2R5Iik7CisgICAgICAgIGFzc2VydENvbnRlbnRUeXBlRXF1YWxzKCJBU0NJSSIsICJ0ZXh0L2h0bWwiLCAiPEJPRFkgIik7CisgICAgICAgIGFzc2VydENvbnRlbnRUeXBlRXF1YWxzKCJBU0NJSSIsICJhcHBsaWNhdGlvbi94bWwiLCAiPD94bWwgIik7CisKKyAgICAgICAgYXNzZXJ0Q29udGVudFR5cGVFcXVhbHMoIlVURi04IiwgInRleHQvaHRtbCIsICI8aHRtbD4iKTsKKyAgICAgICAgYXNzZXJ0Q29udGVudFR5cGVFcXVhbHMoIlVURi04IiwgInRleHQvaHRtbCIsICI8aGVhZD4iKTsKKyAgICAgICAgYXNzZXJ0Q29udGVudFR5cGVFcXVhbHMoIlVURi04IiwgInRleHQvaHRtbCIsICI8aGVhZCAiKTsKKyAgICAgICAgYXNzZXJ0Q29udGVudFR5cGVFcXVhbHMoIlVURi04IiwgInRleHQvaHRtbCIsICI8Ym9keSIpOworICAgICAgICBhc3NlcnRDb250ZW50VHlwZUVxdWFscygiVVRGLTgiLCAidGV4dC9odG1sIiwgIjxCT0RZICIpOworICAgICAgICBhc3NlcnRDb250ZW50VHlwZUVxdWFscygiVVRGLTgiLCAiYXBwbGljYXRpb24veG1sIiwgIjw/eG1sICIpOworCisgICAgICAgIC8vIlVURi0xNkJFIiwgIlVURi0xNkxFIiwgIlVURi0zMkJFIiBhbmQKKyAgICAgICAgLy8iVVRGLTMyTEUiIGFyZSBub3Qgc3VwcG9ydGVkCisKKyAgICAgICAgLy8gVHJ5IHNpbXBsZSBjYXNlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkxDb25uZWN0aW9uLmd1ZXNzQ29udGVudFR5cGVGcm9tU3RyZWFtKG51bGwpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgLyogbm90IHN1cHBvcnRlZAorICAgICAgICAvLyBUZXN0IG1hZ2ljIGJ5dGVzCisgICAgICAgIGJ5dGVbXVtdIGJ5dGVzID0gbmV3IGJ5dGVbXVtdIHsgeyAnUCcsICdLJyB9LCB7ICdHJywgJ0knIH0gfTsKKyAgICAgICAgZXhwZWN0ZWQgPSBuZXcgU3RyaW5nW10geyAiYXBwbGljYXRpb24vemlwIiwgImltYWdlL2dpZiIgfTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRbaV0sIFVSTENvbm5lY3Rpb24KKyAgICAgICAgICAgICAgICAgICAgLmd1ZXNzQ29udGVudFR5cGVGcm9tU3RyZWFtKGlzKSk7CisgICAgICAgIH0KKyAgICAgICAgKi8KKyAgICB9CisKKyAgICB2b2lkIGFzc2VydENvbnRlbnRUeXBlRXF1YWxzKFN0cmluZyBlbmNvZGluZywgU3RyaW5nIGV4cGVjdGVkLAorICAgICAgICAgICAgU3RyaW5nIGhlYWRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgU3RyaW5nIGVuY29kZWRTdHJpbmcgPSBuZXcgU3RyaW5nKGhlYWRlci5nZXRCeXRlcygpLCBlbmNvZGluZyk7CisgICAgICAgIElucHV0U3RyZWFtIGlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGVuY29kZWRTdHJpbmcuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIFN0cmluZyBtaW1lID0gVVJMQ29ubmVjdGlvbi5ndWVzc0NvbnRlbnRUeXBlRnJvbVN0cmVhbShpcyk7CisgICAgICAgIGFzc2VydEVxdWFscygiY2hlY2tpbmcgJyIgKyBoZWFkZXIgKyAiJyB3aXRoICIgKyBlbmNvZGluZywKKyAgICAgICAgICAgICAgICBleHBlY3RlZCwgbWltZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0BsaW5rIGphdmEubmV0LlVSTENvbm5lY3Rpb24jc2V0Q29ubmVjdFRpbWVvdXQoaW50KX0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldENvbm5lY3RUaW1lb3V0SSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkxDb25uZWN0aW9uIHVjID0gbmV3IFVSTCgiaHR0cDovL2xvY2FsaG9zdCIpLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCB1Yy5nZXRDb25uZWN0VGltZW91dCgpKTsKKyAgICAgICAgdWMuc2V0Q29ubmVjdFRpbWVvdXQoMCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCB1Yy5nZXRDb25uZWN0VGltZW91dCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHVjLnNldENvbm5lY3RUaW1lb3V0KC0xMDApOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gY29ycmVjdAorICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygwLCB1Yy5nZXRDb25uZWN0VGltZW91dCgpKTsKKyAgICAgICAgdWMuc2V0Q29ubmVjdFRpbWVvdXQoMTAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEwMCwgdWMuZ2V0Q29ubmVjdFRpbWVvdXQoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB1Yy5zZXRDb25uZWN0VGltZW91dCgtMSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBjb3JyZWN0CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEwMCwgdWMuZ2V0Q29ubmVjdFRpbWVvdXQoKSk7CisKKyAgICAgICAgdWMyLnNldENvbm5lY3RUaW1lb3V0KDIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgIHVjMi5jb25uZWN0KCk7CisgICAgICAgIH0gY2F0Y2ggKFNvY2tldFRpbWVvdXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9vaworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICoge0BsaW5rIGphdmEubmV0LlVSTENvbm5lY3Rpb24jc2V0RmlsZU5hbWVNYXAoamF2YS5uZXQuRmlsZU5hbWVNYXApfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0RmlsZU5hbWVNYXBMamF2YV9uZXRfRmlsZU5hbWVNYXAoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBGaWxlTmFtZU1hcCBtYXBPbGQgPSBVUkxDb25uZWN0aW9uLmdldEZpbGVOYW1lTWFwKCk7CisgICAgICAgIC8vIG5vdGhpbmcgaGFwcGVucyBpZiBzZXQgbnVsbAorICAgICAgICBVUkxDb25uZWN0aW9uLnNldEZpbGVOYW1lTWFwKG51bGwpOworICAgICAgICAvLyB0YWtlIG5vIGVmZmVjdAorICAgICAgICBhc3NlcnROb3ROdWxsKFVSTENvbm5lY3Rpb24uZ2V0RmlsZU5hbWVNYXAoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgVVJMQ29ubmVjdGlvbi5zZXRGaWxlTmFtZU1hcChuZXcgamF2YS5uZXQuRmlsZU5hbWVNYXAoKXsKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29udGVudFR5cGVGb3IoU3RyaW5nIGZpbGVOYW1lKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZU5hbWU9PW51bGwgfHwgZmlsZU5hbWUubGVuZ3RoKCk8MSkKKyAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWU9ZmlsZU5hbWUudG9Mb3dlckNhc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHR5cGU9bnVsbDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUuZW5kc1dpdGgoIi54bWwiKSkKKyAgICAgICAgICAgICAgICAgICAgICB0eXBlPSJ0ZXh0L3htbCI7CisgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZW5kc1dpdGgoIi5kdGQiKSkKKyAgICAgICAgICAgICAgICAgICAgICB0eXBlPSJ0ZXh0L2R0ZCI7CisgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZW5kc1dpdGgoIi5wZGYiKSkKKyAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSAiYXBwbGljYXRpb24vcGRmIjsKKyAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lbmRzV2l0aCgiLnppcCIpKQorICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9ICJhcHBsaWNhdGlvbi96aXAiOworICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVuZHNXaXRoKCIuZ2lmIikpCisgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gImltYWdlL2dpZiI7CisgICAgICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgICB0eXBlPSJhcHBsaWNhdGlvbi91bmtub3duIjsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICB9KTsKKyAgICAgICAgRmlsZU5hbWVNYXAgbWFwTmV3ID0gVVJMQ29ubmVjdGlvbi5nZXRGaWxlTmFtZU1hcCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFwcGxpY2F0aW9uL3BkZiIsIG1hcE5ldy5nZXRDb250ZW50VHlwZUZvcigiLnBkZiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhcHBsaWNhdGlvbi96aXAiLCBtYXBOZXcuZ2V0Q29udGVudFR5cGVGb3IoIi56aXAiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW1hZ2UvZ2lmIiwgbWFwTmV3LmdldENvbnRlbnRUeXBlRm9yKCIuZ2lmIikpOworICAgICAgICB9IGZpbmFsbHkgeworCisgICAgICAgIFVSTENvbm5lY3Rpb24uc2V0RmlsZU5hbWVNYXAobWFwT2xkKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI3NldElmTW9kaWZpZWRTaW5jZShsb25nKX0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldElmTW9kaWZpZWRTaW5jZUooKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cDovL2xvY2FsaG9zdDo4MDgwLyIpOworICAgICAgICBVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKFRpbWVab25lLmdldFRpbWVab25lKCJHTVQiKSk7CisgICAgICAgIGNhbC5jbGVhcigpOworICAgICAgICBjYWwuc2V0KDIwMDAsIENhbGVuZGFyLk1BUkNILCA1KTsKKworICAgICAgICBsb25nIHNpbmNlVGltZSA9IGNhbC5nZXRUaW1lKCkuZ2V0VGltZSgpOworICAgICAgICBjb25uZWN0aW9uLnNldElmTW9kaWZpZWRTaW5jZShzaW5jZVRpbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGRhdGUgc2V0Iiwgc2luY2VUaW1lLCBjb25uZWN0aW9uCisgICAgICAgICAgICAgICAgLmdldElmTW9kaWZpZWRTaW5jZSgpKTsKKworICAgICAgICAvLyBjb250ZW50IHNob3VsZCBiZSByZXR1cm5lZAorCisgICAgICAgIHVjMi5zZXRJZk1vZGlmaWVkU2luY2Uoc2luY2VUaW1lKTsKKyAgICAgICAgdWMyLmNvbm5lY3QoKTsKKworCisgICAgICAgIGFzc2VydEVxdWFscygyMDAsKChIdHRwVVJMQ29ubmVjdGlvbikgdWMyKS5nZXRSZXNwb25zZUNvZGUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHVjMi5zZXRJZk1vZGlmaWVkU2luY2UoMik7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorCisgICAgICAgICgoSHR0cFVSTENvbm5lY3Rpb24pIHVjMikuZGlzY29ubmVjdCgpOworCisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldElmTW9kaWZpZWRTaW5jZUooKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIHVjMi5zZXRJZk1vZGlmaWVkU2luY2UoQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKS5nZXRUaW1lSW5NaWxsaXMoKSk7CisgICAgICAgIHVjMi5jb25uZWN0KCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIwMCwoKEh0dHBVUkxDb25uZWN0aW9uKSB1YzIpLmdldFJlc3BvbnNlQ29kZSgpKTsKKworICAgIH0KKworCisgICAgLyoqCisgICAgICoge0BsaW5rIGphdmEubmV0LlVSTENvbm5lY3Rpb24jc2V0UmVhZFRpbWVvdXQoaW50KX0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFJlYWRUaW1lb3V0SSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgdWMuZ2V0UmVhZFRpbWVvdXQoKSk7CisgICAgICAgIHVjLnNldFJlYWRUaW1lb3V0KDApOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgdWMuZ2V0UmVhZFRpbWVvdXQoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB1Yy5zZXRSZWFkVGltZW91dCgtMTAwKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGNvcnJlY3QKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoMCwgdWMuZ2V0UmVhZFRpbWVvdXQoKSk7CisgICAgICAgIHVjLnNldFJlYWRUaW1lb3V0KDEwMCk7CisgICAgICAgIGFzc2VydEVxdWFscygxMDAsIHVjLmdldFJlYWRUaW1lb3V0KCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdWMuc2V0UmVhZFRpbWVvdXQoLTEpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gY29ycmVjdAorICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygxMDAsIHVjLmdldFJlYWRUaW1lb3V0KCkpOworCisgICAgICAgIGJ5dGVbXSBiYSA9IG5ldyBieXRlWzYwMF07CisKKyAgICAgICAgdWMyLnNldFJlYWRUaW1lb3V0KDUpOworICAgICAgICB1YzIuc2V0RG9JbnB1dCh0cnVlKTsKKyAgICAgICAgdWMyLmNvbm5lY3QoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAoKElucHV0U3RyZWFtKSB1YzIuZ2V0SW5wdXRTdHJlYW0oKSkucmVhZChiYSwgMCwgNjAwKTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0VGltZW91dEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0gY2F0Y2ggKCBVbmtub3duU2VydmljZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCIiK2UuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkxDb25uZWN0aW9uI3RvU3RyaW5nKCl9CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF90b1N0cmluZygpIHsKKworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyB0b1N0cmluZzogIiArIHVjLnRvU3RyaW5nKCksIHVjLnRvU3RyaW5nKCkuaW5kZXhPZigKKyAgICAgICAgICAgICAgICAiVVJMQ29ubmVjdGlvbiIpID4gMCk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHRvU3RyaW5nOiAiICsgdWMudG9TdHJpbmcoKSwgdWMudG9TdHJpbmcoKS5pbmRleE9mKAorICAgICAgICAgICAgICAgIHVjLmdldFVSTCgpLnRvU3RyaW5nKCkpID4gMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9VUkxDb25uZWN0aW9uKCkgeworICAgICAgICBTdHJpbmcgdXJsID0gdWMyLmdldFVSTCgpLnRvU3RyaW5nKCk7CisgICAgICAgIGFzc2VydEVxdWFscyh1cmwyLnRvU3RyaW5nKCksIHVybCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldElucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmlsZVVSTENvbi5zZXREb0lucHV0KHRydWUpOworICAgICAgICBmaWxlVVJMQ29uLmNvbm5lY3QoKTsKKworICAgICAgICBCdWZmZXJlZFJlYWRlciBidWYgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKAorICAgICAgICAgICAgICAgIGZpbGVVUkxDb24uZ2V0SW5wdXRTdHJlYW0oKSksIHRlc3RTdHJpbmcuZ2V0Qnl0ZXMoKS5sZW5ndGgpOworCisgICAgICAgIFN0cmluZyBuZXh0bGluZTsKKyAgICAgICAgd2hpbGUgKChuZXh0bGluZSA9IGJ1Zi5yZWFkTGluZSgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModGVzdFN0cmluZywgbmV4dGxpbmUpOworICAgICAgICB9CisKKyAgICAgICAgYnVmLmNsb3NlKCk7CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh1Yy5nZXRJbnB1dFN0cmVhbSgpKTsKKworICAgICAgICAoKEh0dHBVUkxDb25uZWN0aW9uKSB1YzIpLmRpc2Nvbm5lY3QoKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKHVjMi5nZXRJbnB1dFN0cmVhbSgpKTsKKworICAgIH0KKworICAgIHByaXZhdGUgVVJMQ29ubmVjdGlvbiBvcGVuR2lmVVJMQ29ubmVjdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBjdHMgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaW8udG1wZGlyIik7CisgICAgICAgIEZpbGUgdG1wRGlyID0gbmV3IEZpbGUoY3RzKTsKKyAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUZpbGUodG1wRGlyLCBudWxsLCAiSGFybW9ueS5HSUYiKTsKKyAgICAgICAgVVJMIGZVcmwxID0gbmV3IFVSTCgiZmlsZTovIiArIHRtcERpci5nZXRQYXRoKCkKKyAgICAgICAgICAgICAgICArICIvSGFybW9ueS5HSUYiKTsKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb24xID0gZlVybDEub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgcmV0dXJuIGNvbjE7CisgICAgfQorCisgICAgcHJpdmF0ZSBKYXJVUkxDb25uZWN0aW9uIG9wZW5KYXJVUkxDb25uZWN0aW9uKCkKKyAgICAgICAgICAgIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGN0cyA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKTsKKyAgICAgICAgRmlsZSB0bXBEaXIgPSBuZXcgRmlsZShjdHMpOworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5RmlsZSh0bXBEaXIsIG51bGwsICJoeXRzX2F0dC5qYXIiKTsKKyAgICAgICAgVVJMIGZVcmwxID0gbmV3IFVSTCgiamFyOmZpbGU6IiArIHRtcERpci5nZXRQYXRoKCkKKyAgICAgICAgICAgICAgICArICIvaHl0c19hdHQuamFyIS8iKTsKKyAgICAgICAgSmFyVVJMQ29ubmVjdGlvbiBjb24xID0gKEphclVSTENvbm5lY3Rpb24pIGZVcmwxLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIHJldHVybiBjb24xOworICAgIH0KKworICAgIHByaXZhdGUgVVJMQ29ubmVjdGlvbiBvcGVuSFRNTEZpbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgY3RzID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmlvLnRtcGRpciIpOworICAgICAgICBGaWxlIHRtcERpciA9IG5ldyBGaWxlKGN0cyk7CisgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlGaWxlKHRtcERpciwgbnVsbCwgImh5dHNfaHRtbHRlc3QuaHRtbCIpOworICAgICAgICBVUkwgZlVybDEgPSBuZXcgVVJMKCJmaWxlOi8iICsgdG1wRGlyLmdldFBhdGgoKQorICAgICAgICAgICAgICAgICsgIi9oeXRzX2h0bWx0ZXN0Lmh0bWwiKTsKKyAgICAgICAgVVJMQ29ubmVjdGlvbiBjb24xID0gZlVybDEub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgcmV0dXJuIGNvbjE7CisgICAgfQorCisgICAgcHJpdmF0ZSBVUkwgY3JlYXRlVGVtcEhlbGxvV29ybGRGaWxlKCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIGNyZWF0ZSBjb250ZW50IHRvIHJlYWQKKyAgICAgICAgRmlsZSB0bXBEaXIgPSBuZXcgRmlsZShTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaW8udG1wZGlyIikpOworICAgICAgICBGaWxlIHNhbXBsZUZpbGUgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKHRtcERpci5pc0RpcmVjdG9yeSgpKSB7CisgICAgICAgICAgICAgICAgc2FtcGxlRmlsZSA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoIm9wZW5TdHJlYW1UZXN0IiwgIi50eHQiLAorICAgICAgICAgICAgICAgICAgICAgICAgdG1wRGlyKTsKKyAgICAgICAgICAgICAgICBzYW1wbGVGaWxlLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJFcnJvciBpbiB0ZXN0IHNldHVwIHRtcERpciBkb2VzIG5vdCBleGlzdCIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBGaWxlV3JpdGVyIGZzdHJlYW0gPSBuZXcgRmlsZVdyaXRlcihzYW1wbGVGaWxlKTsKKyAgICAgICAgICAgIEJ1ZmZlcmVkV3JpdGVyIG91dCA9IG5ldyBCdWZmZXJlZFdyaXRlcihmc3RyZWFtLCB0ZXN0U3RyaW5nLmdldEJ5dGVzKCkubGVuZ3RoKTsKKyAgICAgICAgICAgIG91dC53cml0ZSh0ZXN0U3RyaW5nKTsKKyAgICAgICAgICAgIC8vIENsb3NlIHRoZSBvdXRwdXQgc3RyZWFtCisgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsvLyBDYXRjaCBleGNlcHRpb24gaWYgYW55CisgICAgICAgICAgICBmYWlsKCJFcnJvcjogaW4gdGVzdCBzZXR1cCIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyByZWFkIGNvbnRlbnQgZnJvbSBmaWxlCisgICAgICAgIHJldHVybiBzYW1wbGVGaWxlLnRvVVJMKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbmV0L1VSTEVuY29kZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9uZXQvVVJMRW5jb2RlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYzg2MzAzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbmV0L1VSTEVuY29kZXJUZXN0LmphdmEKQEAgLTAsMCArMSw2OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkubHVuaS50ZXN0cy5qYXZhLm5ldDsKKworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkxEZWNvZGVyOworaW1wb3J0IGphdmEubmV0LlVSTEVuY29kZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5VbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Db25maWd1cmF0aW9uOworCitwdWJsaWMgY2xhc3MgVVJMRW5jb2RlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm5ldC5VUkxFbmNvZGVyI2VuY29kZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCisgICAgcHVibGljIHZvaWQgdGVzdF9lbmNvZGVMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIFVSTCA9ICJodHRwOi8vIiArIFN1cHBvcnRfQ29uZmlndXJhdGlvbi5Ib21lQWRkcmVzczsKKyAgICAgICAgZmluYWwgU3RyaW5nIFVSTDIgPSAidGVsbmV0Oi8vanVzdFdhbnRUb0hhdmVGdW4uY29tOjQwMCI7CisgICAgICAgIGZpbmFsIFN0cmluZyBVUkwzID0gImZpbGU6Ly9teVNlcnZlci5vcmcvYSBmaWxlIHdpdGggc3BhY2VzLmpwZyI7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiMS4gSW5jb3JyZWN0IGVuY29kaW5nL2RlY29kaW5nIiwgVVJMRGVjb2Rlci5kZWNvZGUoCisgICAgICAgICAgICAgICAgVVJMRW5jb2Rlci5lbmNvZGUoVVJMKSkuZXF1YWxzKFVSTCkpOworICAgICAgICBhc3NlcnRUcnVlKCIyLiBJbmNvcnJlY3QgZW5jb2RpbmcvZGVjb2RpbmciLCBVUkxEZWNvZGVyLmRlY29kZSgKKyAgICAgICAgICAgICAgICBVUkxFbmNvZGVyLmVuY29kZShVUkwyKSkuZXF1YWxzKFVSTDIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiMy4gSW5jb3JyZWN0IGVuY29kaW5nL2RlY29kaW5nIiwgVVJMRGVjb2Rlci5kZWNvZGUoCisgICAgICAgICAgICAgICAgVVJMRW5jb2Rlci5lbmNvZGUoVVJMMykpLmVxdWFscyhVUkwzKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVVJMRW5jb2RlciNlbmNvZGUoU3RyaW5nLCBTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9lbmNvZGVMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTI0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkxFbmNvZGVyLmVuY29kZSgic3RyIiwgInVua25vd25fZW5jIik7CisgICAgICAgICAgICBmYWlsKCJBc3NlcnQgMDogU2hvdWxkIHRocm93IFVFRSBmb3IgaW52YWxpZCBlbmNvZGluZyIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRDaGFyc2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTEyMzMKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFVSTEVuY29kZXIuZW5jb2RlKG51bGwsICJoYXJtb255Iik7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL25ldC90ZXN0X3Byb3RvY29sL0hhbmRsZXIuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL25ldC90ZXN0X3Byb3RvY29sL0hhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lODY4MzkxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbmV0L3Rlc3RfcHJvdG9jb2wvSGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsMzAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMuamF2YS5uZXQudGVzdF9wcm90b2NvbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEubmV0LlVSTENvbm5lY3Rpb247CitpbXBvcnQgamF2YS5uZXQuVVJMU3RyZWFtSGFuZGxlcjsKKworcHVibGljIGNsYXNzIEhhbmRsZXIgZXh0ZW5kcyBVUkxTdHJlYW1IYW5kbGVyIHsKKyAgICBwcm90ZWN0ZWQgVVJMQ29ubmVjdGlvbiBvcGVuQ29ubmVjdGlvbihVUkwgdSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvcGtnMS9UZXN0Q2xhc3MuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9wa2cxL1Rlc3RDbGFzcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjViZWY5YjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvcGtnMS9UZXN0Q2xhc3MuamF2YQpAQCAtMCwwICsxLDMwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5sdW5pLnRlc3RzLnBrZzE7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworLyoqCisgKiBVc2VkIGZvciBhIHNlcmlhbGl6YXRpb24gdGVzdCwgbXVzdCBoYXZlIGRpZmZlcmVudCBwYWNrYWdlIGFuZCBzYW1lIGJhc2UgbmFtZQorICogYXMgdGhlIFRlc3RDbGFzcyBpbiBvLmEuaC5sLnRlc3RzLnBrZzIKKyAqLworcHVibGljIGNsYXNzIFRlc3RDbGFzcyBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTExMTFMOworCisgICAgcHVibGljIGludCBpID0gMDsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9wa2cyL1Rlc3RDbGFzcy5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL3BrZzIvVGVzdENsYXNzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzFhOWE0ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9wa2cyL1Rlc3RDbGFzcy5qYXZhCkBAIC0wLDAgKzEsMjkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255Lmx1bmkudGVzdHMucGtnMjsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCisvKioKKyAqIFVzZWQgZm9yIGEgc2VyaWFsaXphdGlvbiB0ZXN0LCBtdXN0IGhhdmUgZGlmZmVyZW50IHBhY2thZ2UgYW5kIHNhbWUgYmFzZSBuYW1lCisgKiBhcyB0aGUgVGVzdENsYXNzIGluIG8uYS5oLmwudGVzdHMucGtnMQorICovCitwdWJsaWMgY2xhc3MgVGVzdENsYXNzIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxMTExMUw7CisgICAgcHVibGljIGludCBpID0gMDsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvL3Rlc3RzL2phdmEvbmlvL2NoYW5uZWxzL3NwaS9TZWxlY3RvclByb3ZpZGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvc3BpL1NlbGVjdG9yUHJvdmlkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzFlZGY4MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvL3Rlc3RzL2phdmEvbmlvL2NoYW5uZWxzL3NwaS9TZWxlY3RvclByb3ZpZGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255Lm5pby50ZXN0cy5qYXZhLm5pby5jaGFubmVscy5zcGk7CisKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5zcGkuU2VsZWN0b3JQcm92aWRlcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIFNlbGVjdG9yUHJvdmlkZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogU2VsZWN0b3JQcm92aWRlciNvcGVuRGF0YWdyYW1DaGFubmVsKCkKKyAgICAgKiBTZWxlY3RvclByb3ZpZGVyI29wZW5QaXBlKCkKKyAgICAgKiBTZWxlY3RvclByb3ZpZGVyI29wZW5TZXJ2ZXJTb2NrZXRDaGFubmVsKCkKKyAgICAgKiBTZWxlY3RvclByb3ZpZGVyI29wZW5Tb2NrZXRDaGFubmVsKCkKKyAgICAgKiBTZWxlY3RvclByb3ZpZGVyI29wZW5TZWxlY3RvcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9vcGVuX21ldGhvZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gY2FsbGluZyAjcHJvdmlkZXIgdG8gc2VlIGlmIGl0IHJldHVybnMgd2l0aG91dCBFeGNlcHRpb24uCisgICAgICAgIGFzc2VydE5vdE51bGwoU2VsZWN0b3JQcm92aWRlci5wcm92aWRlcigpKTsKKworICAgICAgICAvLyBjYWxsaW5nICNpbmhlcml0ZWRDaGFubmVsIHRvIHNlZSBpZiB0aGlzIGFscmVhZHkgdGhyb3dzIGFuIGV4Y2VwdGlvbi4KKyAgICAgICAgU2VsZWN0b3JQcm92aWRlci5wcm92aWRlcigpLmluaGVyaXRlZENoYW5uZWwoKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKFNlbGVjdG9yUHJvdmlkZXIucHJvdmlkZXIoKS5vcGVuRGF0YWdyYW1DaGFubmVsKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKFNlbGVjdG9yUHJvdmlkZXIucHJvdmlkZXIoKS5vcGVuUGlwZSgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChTZWxlY3RvclByb3ZpZGVyLnByb3ZpZGVyKCkub3BlblNlcnZlclNvY2tldENoYW5uZWwoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoU2VsZWN0b3JQcm92aWRlci5wcm92aWRlcigpLm9wZW5Tb2NrZXRDaGFubmVsKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKFNlbGVjdG9yUHJvdmlkZXIucHJvdmlkZXIoKS5vcGVuU2VsZWN0b3IoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9yZWdleC90ZXN0cy9qYXZhL3V0aWwvcmVnZXgvTWF0Y2hlcjJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3JlZ2V4L3Rlc3RzL2phdmEvdXRpbC9yZWdleC9NYXRjaGVyMlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYTY0ZGNlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9yZWdleC90ZXN0cy9qYXZhL3V0aWwvcmVnZXgvTWF0Y2hlcjJUZXN0LmphdmEKQEAgLTAsMCArMSwyMzMgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnJlZ2V4LnRlc3RzLmphdmEudXRpbC5yZWdleDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguKjsKKworLyoqCisgKiBUZXN0cyBNYXRjaGVyIG1ldGhvZHMKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBNYXRjaGVyMlRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nKCkgeworICAgICAgICBQYXR0ZXJuIHAgPSBQYXR0ZXJuLmNvbXBpbGUoImZvbyIpOworICAgICAgICBNYXRjaGVyIG0gPSBwLm1hdGNoZXIoImJhciIpOworICAgICAgICBhc3NlcnROb3ROdWxsKG0udG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVycm9yQ29uZGl0aW9ucygpIHRocm93cyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBtYXRjaCBjdXJzb3JzIGluIGFic2VuY2Ugb2YgYSBtYXRjaAorICAgICAgICBQYXR0ZXJuIHAgPSBQYXR0ZXJuLmNvbXBpbGUoImZvbyIpOworICAgICAgICBNYXRjaGVyIG0gPSBwLm1hdGNoZXIoImJhciIpOworICAgICAgICBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG0uc3RhcnQoKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG0uZW5kKCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLmdyb3VwKCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLnN0YXJ0KDEpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbS5lbmQoMSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLmdyb3VwKDEpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICAgICAgICAgLy8gcmVncmVzc2lvbiB0ZXN0IGZvciBIQVJNT05ZLTI0MTgKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG0udXNlUGF0dGVybihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAvLyBQQVNTRUQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFcnJvckNvbmRpdGlvbnMyKCkgdGhyb3dzIFBhdHRlcm5TeW50YXhFeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IG1hdGNoIGN1cnNvcnMgaW4gYWJzZW5jZSBvZiBhIG1hdGNoCisgICAgICAgIFBhdHRlcm4gcCA9IFBhdHRlcm4uY29tcGlsZSgiKGZvb1swLTldKShiYXJbYS16XSkiKTsKKyAgICAgICAgTWF0Y2hlciBtID0gcC5tYXRjaGVyKCJmb28xYmFyemZvbzJiYXJ5Zm9vemJhcjUiKTsKKworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG0uc3RhcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg4LCBtLmVuZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG0uc3RhcnQoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgbS5lbmQoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgbS5zdGFydCgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg4LCBtLmVuZCgyKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG0uc3RhcnQoMyk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG0uZW5kKDMpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLmdyb3VwKDMpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLnN0YXJ0KC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbS5lbmQoLTEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLmdyb3VwKC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDgsIG0uc3RhcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxNiwgbS5lbmQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg4LCBtLnN0YXJ0KDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEyLCBtLmVuZCgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMiwgbS5zdGFydCgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxNiwgbS5lbmQoMikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLnN0YXJ0KDMpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLmVuZCgzKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbS5ncm91cCgzKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbS5zdGFydCgtMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG0uZW5kKC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbS5ncm91cCgtMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5maW5kKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLnN0YXJ0KDMpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbS5lbmQoMyk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLmdyb3VwKDMpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbS5zdGFydCgtMSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLmVuZCgtMSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtLmdyb3VwKC0xKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBSZWdyZXNzaW9uIHRlc3QgZm9yIEhBUk1PTlktOTk3CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFJlcGxhY2VtZW50QmFja1NsYXNoKCkgeworICAgICAgICBTdHJpbmcgc3RyID0gInJlcGxhY2UgbWUiOworICAgICAgICBTdHJpbmcgcmVwbGFjZWRTdHJpbmcgPSAibWUiOworICAgICAgICBTdHJpbmcgc3Vic3RpdHV0aW9uU3RyaW5nID0gIlxcIjsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUocmVwbGFjZWRTdHJpbmcpOworICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKHN0cik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgcmVzID0gbWF0LnJlcGxhY2VBbGwoc3Vic3RpdHV0aW9uU3RyaW5nKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAtICIgKyByZXMpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3JlZ2V4L3Rlc3RzL2phdmEvdXRpbC9yZWdleC9Nb2RlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9yZWdleC90ZXN0cy9qYXZhL3V0aWwvcmVnZXgvTW9kZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NjlkM2U2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9yZWdleC90ZXN0cy9qYXZhL3V0aWwvcmVnZXgvTW9kZVRlc3QuamF2YQpAQCAtMCwwICsxLDExNiBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkucmVnZXgudGVzdHMuamF2YS51dGlsLnJlZ2V4OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOworaW1wb3J0IGphdmEudXRpbC5yZWdleC5NYXRjaGVyOworaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuU3ludGF4RXhjZXB0aW9uOworCisvKioKKyAqIFRlc3RzIFBhdHRlcm4gY29tcGlsYXRpb24gbW9kZXMgYW5kIG1vZGVzIHRyaWdnZXJlZCBpbiBwYXR0ZXJuIHN0cmluZ3MKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBNb2RlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RDYXNlKCkgdGhyb3dzIFBhdHRlcm5TeW50YXhFeGNlcHRpb24geworICAgICAgICBQYXR0ZXJuIHA7CisgICAgICAgIE1hdGNoZXIgbTsKKworICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCIoW2Etel0rKVswLTldKyIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJjQVQxMjMjZG9nMzQ1Iik7CisgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvZyIsIG0uZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRGYWxzZShtLmZpbmQoKSk7CisKKworICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCIoW2Etel0rKVswLTldKyIsIFBhdHRlcm4uQ0FTRV9JTlNFTlNJVElWRSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImNBdDEyMyNkb0czNDUiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiY0F0IiwgbS5ncm91cCgxKSk7CisgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvRyIsIG0uZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRGYWxzZShtLmZpbmQoKSk7CisKKworICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCIoP2kpKFthLXpdKylbMC05XSsiKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiY0F0MTIzI2RvRzM0NSIpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjQXQiLCBtLmdyb3VwKDEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZG9HIiwgbS5ncm91cCgxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdE11bHRpbGluZSgpIHRocm93cyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgUGF0dGVybiBwOworICAgICAgICBNYXRjaGVyIG07CisKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiXmZvbyIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJmb29iYXIiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydFRydWUobS5zdGFydCgpID09IDAgJiYgbS5lbmQoKSA9PSAzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5maW5kKCkpOworCisgICAgICAgIG0gPSBwLm1hdGNoZXIoImJhcmZvbyIpOworICAgICAgICBhc3NlcnRGYWxzZShtLmZpbmQoKSk7CisKKworICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJmb28kIik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImZvb2JhciIpOworICAgICAgICBhc3NlcnRGYWxzZShtLmZpbmQoKSk7CisKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYmFyZm9vIik7CisgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICBhc3NlcnRUcnVlKG0uc3RhcnQoKSA9PSAzICYmIG0uZW5kKCkgPT0gNik7CisgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKworCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIl5mb28oWzAtOV0qKSIsIFBhdHRlcm4uTVVMVElMSU5FKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiZm9vMWJhclxuZm9vMmZvbzNcbmJhcmZvbzQiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMSIsIG0uZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIyIiwgbS5ncm91cCgxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKworCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoImZvbyhbMC05XSopJCIsIFBhdHRlcm4uTVVMVElMSU5FKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiZm9vMWJhclxuZm9vMmZvbzNcbmJhcmZvbzQiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMyIsIG0uZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI0IiwgbS5ncm91cCgxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKworCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIig/bSleZm9vKFswLTldKikiKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiZm9vMWJhclxuZm9vMmZvbzNcbmJhcmZvbzQiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMSIsIG0uZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIyIiwgbS5ncm91cCgxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKworICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCIoP20pZm9vKFswLTldKikkIik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImZvbzFiYXJcbmZvbzJmb28zXG5iYXJmb280Iik7CisgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjMiLCBtLmdyb3VwKDEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiNCIsIG0uZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRGYWxzZShtLmZpbmQoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9yZWdleC90ZXN0cy9qYXZhL3V0aWwvcmVnZXgvUGF0dGVybjJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3JlZ2V4L3Rlc3RzL2phdmEvdXRpbC9yZWdleC9QYXR0ZXJuMlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zODkxOTRhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9yZWdleC90ZXN0cy9qYXZhL3V0aWwvcmVnZXgvUGF0dGVybjJUZXN0LmphdmEKQEAgLTAsMCArMSwxNTc3IEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5yZWdleC50ZXN0cy5qYXZhLnV0aWwucmVnZXg7CisKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguTWF0Y2hlcjsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVyblN5bnRheEV4Y2VwdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBzaW1wbGUgUGF0dGVybiBjb21waWxhdGlvbiBhbmQgTWF0Y2hlciBtZXRob2RzCisgKgorICovCitwdWJsaWMgY2xhc3MgUGF0dGVybjJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdFNpbXBsZU1hdGNoKCkgdGhyb3dzIFBhdHRlcm5TeW50YXhFeGNlcHRpb24geworICAgICAgICBQYXR0ZXJuIHAgPSBQYXR0ZXJuLmNvbXBpbGUoImZvby4qIik7CisKKyAgICAgICAgTWF0Y2hlciBtMSA9IHAubWF0Y2hlcigiZm9vMTIzIik7CisgICAgICAgIGFzc2VydFRydWUobTEubWF0Y2hlcygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtMS5maW5kKDApKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtMS5sb29raW5nQXQoKSk7CisKKyAgICAgICAgTWF0Y2hlciBtMiA9IHAubWF0Y2hlcigiZm94Iik7CisgICAgICAgIGFzc2VydEZhbHNlKG0yLm1hdGNoZXMoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG0yLmZpbmQoMCkpOworICAgICAgICBhc3NlcnRGYWxzZShtMi5sb29raW5nQXQoKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShQYXR0ZXJuLm1hdGNoZXMoImZvby4qIiwgImZvbzEyMyIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoUGF0dGVybi5tYXRjaGVzKCJmb28uKiIsICJmb3giKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoUGF0dGVybi5tYXRjaGVzKCJiYXIiLCAiZm9vYmFyIikpOworCisgICAgICAgIGFzc2VydFRydWUoUGF0dGVybi5tYXRjaGVzKCIiLCAiIikpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q3Vyc29ycygpIHsKKyAgICAgICAgUGF0dGVybiBwOworICAgICAgICBNYXRjaGVyIG07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoImZvbyIpOworCisgICAgICAgICAgICBtID0gcC5tYXRjaGVyKCJmb29iYXIiKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG0uc3RhcnQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMywgbS5lbmQoKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShtLmZpbmQoKSk7CisKKyAgICAgICAgICAgIC8vIE5vdGU6IGFsc28gdGVzdGluZyByZXNldCBoZXJlCisgICAgICAgICAgICBtLnJlc2V0KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBtLnN0YXJ0KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIG0uZW5kKCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UobS5maW5kKCkpOworCisgICAgICAgICAgICBtLnJlc2V0KCJiYXJmb29iYXIiKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIG0uc3RhcnQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNiwgbS5lbmQoKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShtLmZpbmQoKSk7CisKKyAgICAgICAgICAgIG0ucmVzZXQoImJhcmZvbyIpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMywgbS5zdGFydCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyg2LCBtLmVuZCgpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKworICAgICAgICAgICAgbS5yZXNldCgiZm9vYmFyZm9vYmFyZm9vIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBtLnN0YXJ0KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIG0uZW5kKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoNiwgbS5zdGFydCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyg5LCBtLmVuZCgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEyLCBtLnN0YXJ0KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDE1LCBtLmVuZCgpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUobS5maW5kKDApKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBtLnN0YXJ0KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIG0uZW5kKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoNCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDYsIG0uc3RhcnQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoOSwgbS5lbmQoKSk7CisgICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R3JvdXBzKCkgdGhyb3dzIFBhdHRlcm5TeW50YXhFeGNlcHRpb24geworICAgICAgICBQYXR0ZXJuIHA7CisgICAgICAgIE1hdGNoZXIgbTsKKworICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCIocFswLTldKikjPyhxWzAtOV0qKSIpOworCisgICAgICAgIG0gPSBwLm1hdGNoZXIoInAxI3EzcDJxNDJwNXA3MXA2MyNxODg4Iik7CisgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbS5zdGFydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIG0uZW5kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgbS5ncm91cENvdW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbS5zdGFydCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBtLmVuZCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBtLnN0YXJ0KDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIG0uZW5kKDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIG0uc3RhcnQoMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgbS5lbmQoMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoInAxI3EzIiwgbS5ncm91cCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwMSNxMyIsIG0uZ3JvdXAoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInAxIiwgbS5ncm91cCgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygicTMiLCBtLmdyb3VwKDIpKTsKKworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIG0uc3RhcnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMCwgbS5lbmQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBtLmdyb3VwQ291bnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMCwgbS5lbmQoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgbS5zdGFydCgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg3LCBtLmVuZCgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg3LCBtLnN0YXJ0KDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEwLCBtLmVuZCgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygicDJxNDIiLCBtLmdyb3VwKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInAycTQyIiwgbS5ncm91cCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygicDIiLCBtLmdyb3VwKDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJxNDIiLCBtLmdyb3VwKDIpKTsKKworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDE1LCBtLnN0YXJ0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMjMsIG0uZW5kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgbS5ncm91cENvdW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTUsIG0uc3RhcnQoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMjMsIG0uZW5kKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDE1LCBtLnN0YXJ0KDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDE4LCBtLmVuZCgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxOSwgbS5zdGFydCgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyMywgbS5lbmQoMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoInA2MyNxODg4IiwgbS5ncm91cCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwNjMjcTg4OCIsIG0uZ3JvdXAoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInA2MyIsIG0uZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInE4ODgiLCBtLmdyb3VwKDIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5maW5kKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXBsYWNlKCkgdGhyb3dzIFBhdHRlcm5TeW50YXhFeGNlcHRpb24geworICAgICAgICBQYXR0ZXJuIHA7CisgICAgICAgIE1hdGNoZXIgbTsKKworICAgICAgICAvLyBOb3RlOiBleGFtcGxlcyBmcm9tIGJvb2ssCisgICAgICAgIC8vIEhpdGNoZW5zLCBSb24sIDIwMDIsICJKYXZhIE5JTyIsIE8nUmVpbGx5LCBwYWdlIDE3MQorICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJhKmIiKTsKKworICAgICAgICBtID0gcC5tYXRjaGVyKCJhYWJmb29hYWJmb29hYmZvb2IiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLnJlcGxhY2VBbGwoIi0iKS5lcXVhbHMoIi1mb28tZm9vLWZvby0iKSk7CisgICAgICAgIGFzc2VydFRydWUobS5yZXBsYWNlRmlyc3QoIi0iKS5lcXVhbHMoIi1mb29hYWJmb29hYmZvb2IiKSk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogcCA9IFBhdHRlcm4uY29tcGlsZSAoIlxccHtCbGFua30iKTsKKyAgICAgICAgICoKKyAgICAgICAgICogbSA9IHAubWF0Y2hlciAoImZlZSBmaWUgZm9lIGZ1bSIpOyBhc3NlcnRUcnVlCisgICAgICAgICAqIChtLnJlcGxhY2VGaXJzdCgiLSIpLmVxdWFscyAoImZlZS1maWUgZm9lIGZ1bSIpKTsgYXNzZXJ0VHJ1ZQorICAgICAgICAgKiAobS5yZXBsYWNlQWxsKCItIikuZXF1YWxzICgiZmVlLWZpZS1mb2UtZnVtIikpOworICAgICAgICAgKi8KKworICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCIoW2JCXSl5dGUiKTsKKworICAgICAgICBtID0gcC5tYXRjaGVyKCJCeXRlIGZvciBieXRlIik7CisgICAgICAgIGFzc2VydFRydWUobS5yZXBsYWNlRmlyc3QoIiQxaXRlIikuZXF1YWxzKCJCaXRlIGZvciBieXRlIikpOworICAgICAgICBhc3NlcnRUcnVlKG0ucmVwbGFjZUFsbCgiJDFpdGUiKS5lcXVhbHMoIkJpdGUgZm9yIGJpdGUiKSk7CisKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiXFxkXFxkXFxkXFxkKFstIF0pIik7CisKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiY2FyZCAjMTIzNC01Njc4LTEyMzQiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLnJlcGxhY2VGaXJzdCgieHh4eCQxIikuZXF1YWxzKCJjYXJkICN4eHh4LTU2NzgtMTIzNCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLnJlcGxhY2VBbGwoInh4eHgkMSIpLmVxdWFscygiY2FyZCAjeHh4eC14eHh4LTEyMzQiKSk7CisKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiKHVwfGxlZnQpKCAqKShyaWdodHxkb3duKSIpOworCisgICAgICAgIG0gPSBwLm1hdGNoZXIoImxlZnQgcmlnaHQsIHVwIGRvd24iKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLnJlcGxhY2VGaXJzdCgiJDMkMiQxIikuZXF1YWxzKCJyaWdodCBsZWZ0LCB1cCBkb3duIikpOworICAgICAgICBhc3NlcnRUcnVlKG0ucmVwbGFjZUFsbCgiJDMkMiQxIikuZXF1YWxzKCJyaWdodCBsZWZ0LCBkb3duIHVwIikpOworCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIihbQ2NQcF1baGxdZVtlYV1zZSkiKTsKKworICAgICAgICBtID0gcC5tYXRjaGVyKCJJIHdhbnQgY2hlZXNlLiBQbGVhc2UuIik7CisgICAgICAgIGFzc2VydFRydWUobS5yZXBsYWNlRmlyc3QoIjxiPiAkMSA8L2I+IikuZXF1YWxzKAorICAgICAgICAgICAgICAgICJJIHdhbnQgPGI+IGNoZWVzZSA8L2I+LiBQbGVhc2UuIikpOworICAgICAgICBhc3NlcnRUcnVlKG0ucmVwbGFjZUFsbCgiPGI+ICQxIDwvYj4iKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgIkkgd2FudCA8Yj4gY2hlZXNlIDwvYj4uIDxiPiBQbGVhc2UgPC9iPi4iKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVzY2FwZXMoKSB0aHJvd3MgUGF0dGVyblN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIFBhdHRlcm4gcDsKKyAgICAgICAgTWF0Y2hlciBtOworCisgICAgICAgIC8vIFRlc3QgXFwgc2VxdWVuY2UKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiKFthLXpdKylcXFxcKFthLXpdKyk7Iik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImZyZWRcXGdpbmdlcjthYmJvdHRcXGNvc3RlbGxvO2pla2VsbFxcaHlkZTsiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZnJlZCIsIG0uZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdpbmdlciIsIG0uZ3JvdXAoMikpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhYmJvdHQiLCBtLmdyb3VwKDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjb3N0ZWxsbyIsIG0uZ3JvdXAoMikpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJqZWtlbGwiLCBtLmdyb3VwKDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJoeWRlIiwgbS5ncm91cCgyKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKworICAgICAgICAvLyBUZXN0IFxuLCBcdCwgXHIsIFxmLCBcZSwgXGEgc2VxdWVuY2VzCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIihbYS16XSspW1xcblxcdFxcclxcZlxcZVxcYV0rKFthLXpdKykiKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYWFcbmJiO2NjXHUwMDA5XHJkZDtlZVx1MDAwQ1x1MDAxQmZmO2dnXG5cdTAwMDdoaCIpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhYSIsIG0uZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJiIiwgbS5ncm91cCgyKSk7CisgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImNjIiwgbS5ncm91cCgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZGQiLCBtLmdyb3VwKDIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZWUiLCBtLmdyb3VwKDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmZiIsIG0uZ3JvdXAoMikpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZyIsIG0uZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImhoIiwgbS5ncm91cCgyKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKworICAgICAgICAvLyBUZXN0IFxcdSBhbmQgXFx4IHNlcXVlbmNlcworLyogICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIihbMC05XSspW1xcdTAwMjA6XFx4MjFdOyIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCIxMTo7MjIgOzMzLTs0NCE7Iik7CisgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjExIiwgbS5ncm91cCgxKSk7CisgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjIyIiwgbS5ncm91cCgxKSk7CisgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjQ0IiwgbS5ncm91cCgxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKyovCisgICAgICAgIC8vIFRlc3QgaW52YWxpZCB1bmljb2RlIHNlcXVlbmNlcworLyogICAgICAgIHRyeSB7CisgICAgICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJcXHUiKTsKKyAgICAgICAgICAgIGZhaWwoIlBhdHRlcm5TeW50YXhFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiXFx1OyIpOworICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJcXHUwMDIiKTsKKyAgICAgICAgICAgIGZhaWwoIlBhdHRlcm5TeW50YXhFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiXFx1MDAyOyIpOworICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3QgaW52YWxpZCBoZXggc2VxdWVuY2VzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJcXHgiKTsKKyAgICAgICAgICAgIGZhaWwoIlBhdHRlcm5TeW50YXhFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiXFx4OyIpOworICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJcXHhhIik7CisgICAgICAgICAgICBmYWlsKCJQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlxceGE7Iik7CisgICAgICAgICAgICBmYWlsKCJQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICB9CisqLworICAgICAgICAvLyBUZXN0IFwwIChvY3RhbCkgc2VxdWVuY2VzICgxLCAyIGFuZCAzIGRpZ2l0KQorICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCIoWzAtOV0rKVtcXDA3XFwwNDBcXDAxNjBdOyIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCIxMVx1MDAwNzsyMjo7MzMgOzQ0cDsiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTEiLCBtLmdyb3VwKDEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMzMiLCBtLmdyb3VwKDEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiNDQiLCBtLmdyb3VwKDEpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5maW5kKCkpOworCisgICAgICAgIC8vIFRlc3QgaW52YWxpZCBvY3RhbCBzZXF1ZW5jZXMKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlxcMDgiKTsKKyAgICAgICAgICAgIGZhaWwoIlBhdHRlcm5TeW50YXhFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICAvL29yaWdpbmFsbHkgY29udHJpYnV0ZWQgdGVzdCBkaWQgbm90IGNoZWNrIHRoZSByZXN1bHQKKyAgICAgICAgLy9UT0RPOiBjaGVjayB3aGF0IFJJIGRvZXMgaGVyZQorLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlxcMDQ3NyIpOworLy8gICAgICAgICAgICBmYWlsKCJQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGV4cGVjdGVkIik7CisvLyAgICAgICAgfSBjYXRjaCAoUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBlKSB7CisvLyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJcXDAiKTsKKyAgICAgICAgICAgIGZhaWwoIlBhdHRlcm5TeW50YXhFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiXFwwOyIpOworICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisKKyAgICAgICAgLy8gVGVzdCBcYyAoY29udHJvbCBjaGFyYWN0ZXIpIHNlcXVlbmNlCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIihbMC05XSspW1xcY0FcXGNCXFxjQ1xcY0RdOyIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCIxMVx1MDAwMTsyMjo7MzNcdTAwMDI7NDRwOzU1XHUwMDAzOzY2XHUwMDA0OyIpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMSIsIG0uZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIzMyIsIG0uZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI1NSIsIG0uZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI2NiIsIG0uZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRGYWxzZShtLmZpbmQoKSk7CisKKyAgICAgICAgLy8gTW9yZSB0aG9yb3VnaCBjb250cm9sIGVzY2FwZSB0ZXN0CisgICAgICAgIC8vIEVuc3VyZSB0aGF0IGVhY2ggZXNjYXBlIG1hdGNoZXMgZXhhY3RseSB0aGUgY29ycmVzcG9uZGluZworICAgICAgICAvLyBjaGFyYWN0ZXIKKyAgICAgICAgLy8gY29kZSBhbmQgbm8gb3RoZXJzICh3ZWxsLCBmcm9tIDAtMjU1IGF0IGxlYXN0KQorICAgICAgICBpbnQgaSwgajsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IDI2OyBpKyspIHsKKyAgICAgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlxcYyIgKyBDaGFyYWN0ZXIudG9TdHJpbmcoKGNoYXIpICgnQScgKyBpKSkpOworICAgICAgICAgICAgaW50IG1hdGNoX2NoYXIgPSAtMTsKKyAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCAyNTU7IGorKykgeworICAgICAgICAgICAgICAgIG0gPSBwLm1hdGNoZXIoQ2hhcmFjdGVyLnRvU3RyaW5nKChjaGFyKSBqKSk7CisgICAgICAgICAgICAgICAgaWYgKG0ubWF0Y2hlcygpKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygtMSwgbWF0Y2hfY2hhcik7CisgICAgICAgICAgICAgICAgICAgIG1hdGNoX2NoYXIgPSBqOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUobWF0Y2hfY2hhciA9PSBpICsgMSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBUZXN0IGludmFsaWQgY29udHJvbCBlc2NhcGVzCisvLyBCRUdJTiBhbmRyb2lkLXJlbW92ZWQKKy8vIElDVSBkb2Vzbid0IGNvbXBsYWluIGFib3V0IGlsbGVnYWwgY29udHJvbCBzZXF1ZW5jZXMKKy8vICAgICAgICB0cnkgeworLy8gICAgICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJcXGMiKTsKKy8vICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCIpOworLy8gICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworLy8gICAgICAgIH0KKy8vIEVORCBhbmRyb2lkLXJlbW92ZWQKKworICAgICAgICAvL29yaWdpbmFsbHkgY29udHJpYnV0ZWQgdGVzdCBkaWQgbm90IGNoZWNrIHRoZSByZXN1bHQKKyAgICAgICAgLy9UT0RPOiBjaGVjayB3aGF0IFJJIGRvZXMgaGVyZQorLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlxcYzsiKTsKKy8vICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCIpOworLy8gICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworLy8gICAgICAgIH0KKy8vCisvLyAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiXFxjYTsiKTsKKy8vICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCIpOworLy8gICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworLy8gICAgICAgIH0KKy8vCisvLyAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiXFxjNDsiKTsKKy8vICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCIpOworLy8gICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworLy8gICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENoYXJhY3RlckNsYXNzZXMoKSB0aHJvd3MgUGF0dGVyblN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIFBhdHRlcm4gcDsKKyAgICAgICAgTWF0Y2hlciBtOworCisgICAgICAgIC8vIFRlc3Qgb25lIGNoYXJhY3RlciByYW5nZQorICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJbcF0uKltsXSIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJwYXVsIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJwb29sIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJwb25nIik7CisgICAgICAgIGFzc2VydEZhbHNlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigicGwiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisKKyAgICAgICAgLy8gVGVzdCB0d28gY2hhcmFjdGVyIHJhbmdlCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIltwbV0uKltscF0iKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigicHJvcCIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigibWFsbCIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigicG9uZyIpOworICAgICAgICBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoInBpbGwiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisKKyAgICAgICAgLy8gVGVzdCByYW5nZSBpbmNsdWRpbmcgWyBhbmQgXQorICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJbPFxcW10uKltcXF0+XSIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCI8Zm9vPiIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiW2Jhcl0iKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIntmb29iYXJdIik7CisgICAgICAgIGFzc2VydEZhbHNlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiPHBpbGxdIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworCisgICAgICAgIC8vIFRlc3QgcmFuZ2UgdXNpbmcgXgorICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJbXmJjXVthLXpdK1t0cl0iKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigicGF0Iik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJsaWFyIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJjYXIiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJnbmF0Iik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworCisgICAgICAgIC8vIFRlc3QgY2hhcmFjdGVyIHJhbmdlIHVzaW5nIC0KKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiW2Etel1fK1thLXpBLVpdLStbMC05cC16XSIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJkX19GLTgiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImNfYS1xIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJhX19SLWEiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJyX19fX19kLS0tLS01Iik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworCisgICAgICAgIC8vIFRlc3QgcmFuZ2UgdXNpbmcgdW5pY29kZSBjaGFyYWN0ZXJzIGFuZCB1bmljb2RlIGFuZCBoZXggZXNjYXBlcworICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJbXFx1MTIzNC1cXHUyMzQ1XV8rW2Etel0tK1tcdTAwMDEtXFx4MTFdIik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIlx1MjAwMF9xLVx1MDAwNyIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiXHUxMjM0X3otXHUwMDAxIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJyX3AtcSIpOworICAgICAgICBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIlx1MjM0NV9fX19fZC0tLS0tXG4iKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisKKy8vIEJFR0lOIGFuZHJvaWQtcmVtb3ZlZAorLy8gVGhlICItLS0iIGNvbGxpZGVzIHdpdGggSUNVJ3MgIi0tIiBvcGVyYXRvciBhbmQgaXMgbGlrZWx5IHRvIGJlIGEgdXNlciBlcnJvcgorLy8gYW55d2F5LCBzbyB3ZSBzaW1wbHkgY29tbWVudCB0aGlzIG9uZSBvdXQuCisvLyAgICAgICAgLy8gVGVzdCByYW5nZXMgaW5jbHVkaW5nIHRoZSAiLSIgY2hhcmFjdGVyCisvLyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiW1xcKi0vXV8rWy0tLV0hK1stLUFQXSIpOworLy8gICAgICAgIG0gPSBwLm1hdGNoZXIoIi1fLSEhQSIpOworLy8gICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworLy8gICAgICAgIG0gPSBwLm1hdGNoZXIoIlx1MDAyYl8tISEhLSIpOworLy8gICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworLy8gICAgICAgIG0gPSBwLm1hdGNoZXIoIiFfLSFAIik7CisvLyAgICAgICAgYXNzZXJ0RmFsc2UobS5tYXRjaGVzKCkpOworLy8gICAgICAgIG0gPSBwLm1hdGNoZXIoIixfX19fX18tISEhISEhIVAiKTsKKy8vICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKy8vIEVORCBhbmRyb2lkLXJlbW92ZWQKKworICAgICAgICAvLyBUZXN0IG5lc3RlZCByYW5nZXMKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiW3BtW3RdXVthLXpdK1tbcl1scF0iKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigicHJvcCIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigidHNhciIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigicG9uZyIpOworICAgICAgICBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIm1vb3IiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisKKyAgICAgICAgLy8gVGVzdCBjaGFyYWN0ZXIgY2xhc3MgaW50ZXJzZWN0aW9uIHdpdGggJiYKKyAgICAgICAgLy8gVE9ETzogZmlndXJlIG91dCB3aGF0IHgmJnkgb3IgYW55IGNsYXNzIHdpdGggYSBudWxsIGludGVyc2VjdGlvbgorICAgICAgICAvLyBzZXQgKGxpa2UgW1thLWNdJiZbZC1mXV0pIG1pZ2h0IG1lYW4uIEl0IGRvZXNuJ3QgbWVhbiAibWF0Y2gKKyAgICAgICAgLy8gbm90aGluZyIgYW5kIGRvZXNuJ3QgbWVhbiAibWF0Y2ggYW55dGhpbmciIHNvIEknbSBzdHVtcGVkLgorICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJbW2EtcF0mJltnLXpdXSstK1tbYS16XSYmcV0tK1t4JiZbYS16XV0tKyIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJoLS1xLS14LS0iKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImhvZy0tcS14LSIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYXBlLS1xLXgtIik7CisgICAgICAgIGFzc2VydEZhbHNlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigibW9wLS1xLXgtLS0tIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworCisgICAgICAgIC8vIFRlc3QgZXJyb3IgY2FzZXMgd2l0aCAmJgorLy8gQkVHSU4gYW5kcm9pZC1yZW1vdmVkCisvLyBUaGlzIGlzIG1vcmUgb2YgYSBidWcsIGFuZCBJQ1UgZG9lc24ndCBoYXZlIHRoaXMgYmVoYXZpb3IuCisvLyAgICAgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlsmJlt4eXpdXSIpOworLy8gICAgICAgICAgICBtID0gcC5tYXRjaGVyKCImIik7CisvLyAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihtLm1hdGNoZXMoKSk7CisvLyAgICAgICAgICAgIG0gPSBwLm1hdGNoZXIoIngiKTsKKy8vICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKG0ubWF0Y2hlcygpKTsKKy8vICAgICAgICAgICAgbSA9IHAubWF0Y2hlcigieSIpOworLy8gICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4obS5tYXRjaGVzKCkpOworLy8gRU5EIGFuZHJvaWQtcmVtb3ZlZAorICAgICAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiW1t4eXpdJltheHldXSIpOworICAgICAgICAgICAgbSA9IHAubWF0Y2hlcigieCIpOworICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgICAgIG0gPSBwLm1hdGNoZXIoInoiKTsKKyAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihtLm1hdGNoZXMoKSk7CisgICAgICAgICAgICBtID0gcC5tYXRjaGVyKCImIik7CisgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4obS5tYXRjaGVzKCkpOworICAgICAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiW2FiY1sxMjNdJiZbMzQ1XWRlZl0iKTsKKyAgICAgICAgICAgIG0gPSBwLm1hdGNoZXIoImEiKTsKKyAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihtLm1hdGNoZXMoKSk7CisKKy8vIEJFR0lOIGFuZHJvaWQtcmVtb3ZlZAorLy8gVGhpcyBpcyBtb3JlIG9mIGEgYnVnLCBhbmQgSUNVIGRvZXNuJ3QgaGF2ZSB0aGlzIGJlaGF2aW9yLgorLy8gICAgICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJbW3h5el0mJl0iKTsKKy8vIEVORCBhbmRyb2lkLXJlbW92ZWQKKyAgICAgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIltbYWJjXSZdIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIltbYWJjXSYmIik7CisgICAgICAgICAgICBmYWlsKCJQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiW1thYmNdXFwmJlt4eXpdXSIpOworCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIltbYWJjXSZcXCZbeHl6XV0iKTsKKworICAgICAgICAvLyBUZXN0IDMtd2F5IGludGVyc2VjdGlvbgorICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJbW2EtcF0mJltnLXpdJiZbZC1rXV0iKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiZyIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigibSIpOworICAgICAgICBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSk7CisKKyAgICAgICAgLy8gVGVzdCBuZXN0ZWQgaW50ZXJzZWN0aW9uCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIltbW2EtcF0mJltnLXpdXSYmW2Qta11dIik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImciKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIm0iKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5tYXRjaGVzKCkpOworCisgICAgICAgIC8vIFRlc3QgY2hhcmFjdGVyIGNsYXNzIHN1YnRyYWN0aW9uIHdpdGggJiYgYW5kIF4KKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiW1thLXpdJiZbXmFlaW91XV1bYWVpb3VdW1teeHl6XSYmW2Etel1dIik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoInBvcCIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigidGFnIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJlYXQiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJ0YXgiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJ6aXAiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisKKyAgICAgICAgLy8gVGVzdCAuIChET1QpLCB3aXRoIGFuZCB3aXRob3V0IERPVEFMTAorICAgICAgICAvLyBOb3RlOiBET1Qgbm90IGFsbG93ZWQgaW4gY2hhcmFjdGVyIGNsYXNzZXMKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiLisveC56Iik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIiEkL3h5eiIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiJVxuXHIveFxueiIpOworICAgICAgICBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSk7CisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIi4rL3gueiIsIFBhdHRlcm4uRE9UQUxMKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiJVxuXHIveFxueiIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKworICAgICAgICAvLyBUZXN0IFxkIChkaWdpdCkKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiXFxkK1thLXpdW1xcZHhdIik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIjQyYTYiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIjIxengiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImFiNiIpOworICAgICAgICBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIjU2OTEyZjkiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisKKyAgICAgICAgLy8gVGVzdCBcRCAobm90IGEgZGlnaXQpCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlxcRCtbYS16XS1bXFxEM10iKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiemEtcCIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiJSFlLTMiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIjlhLXgiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJcdTEyMzRwcFxueS0zIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworCisgICAgICAgIC8vIFRlc3QgXHMgKHdoaXRlc3BhY2UpCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIjxbYS16QS1aXStcXHMrWzAtOV0rW1xcc3hdW15cXHNdPiIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCI8Y2F0IFx0MVxmeD4iKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIjxjYXQgXHQxXGYgPiIpOworICAgICAgICBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwCisgICAgICAgICAgICAgICAgLm1hdGNoZXIoInh5eiA8Zm9vXG5ccjIyIDU+IDxwcCBcdFxuXGZcciBcdTAwMGI0MXhcdTEyMzQ+PHBwIFxueDdccmM+IHp6eiIpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKworICAgICAgICAvLyBUZXN0IFxTIChub3Qgd2hpdGVzcGFjZSkKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiPFthLXpdIFxcU1swLTldW1xcU1xuXStbXlxcU10yMjE+Iik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIjxmICQwKipcbioqIDIyMT4iKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIjx4IDQ0MVx0MjIxPiIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiPHogXHQ5XG5nIDIyMT4iKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCI8eiA2MFxuZ2dcdTEyMzRcZjIyMT4iKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIjxbYS16XSBcXFNbMC05XVtcXFNcbl0rW15cXFNdMjIxW1xcUyYmW15hYmNdXT4iKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiPGYgJDAqKlxuKiogMjIxeD4iKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIjx4IDQ0MVx0MjIxej4iKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIjx4IDQ0MVx0MjIxID4iKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCI8eCA0NDFcdDIyMWM+Iik7CisgICAgICAgIGFzc2VydEZhbHNlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiPHogXHQ5XG5nIDIyMXg+Iik7CisgICAgICAgIGFzc2VydEZhbHNlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiPHogNjBcbmdnXHUxMjM0XGYyMjFcdTAwMDE+Iik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworCisgICAgICAgIC8vIFRlc3QgXHcgKGFzY2lpIHdvcmQpCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIjxcXHcrXFxzWzAtOV0rO1teXFx3XVxcdysvW1xcdyRdKzsiKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiPGYxIDk5OyFmb281L2EkNzsiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoIjxmJCA5OTshZm9vNS9hJDc7Iik7CisgICAgICAgIGFzc2VydEZhbHNlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAKKyAgICAgICAgICAgICAgICAubWF0Y2hlcigiPGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpfMDEyMzQ1Njc4OSA5OTshZm9vNS9hJDc7Iik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworCisgICAgICAgIC8vIFRlc3QgXFcgKG5vdCBhbiBhc2NpaSB3b3JkKQorICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCI8XFxXXFx3K1xcc1swLTldKztbXFxXX11bXlxcV10rXFxzWzAtOV0rOyIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCI8JGZvbzNcbjk5O19iYXJcdDA7Iik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCI8aGggOTk7X2cgMDsiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCI8Knh4XHQwMDteenpcZjExOyIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKworICAgICAgICAvLyBUZXN0IHh8eSBwYXR0ZXJuCisgICAgICAgIC8vIFRPRE8KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFBPU0lYR3JvdXBzKCkgdGhyb3dzIFBhdHRlcm5TeW50YXhFeGNlcHRpb24geworICAgICAgICBQYXR0ZXJuIHA7CisgICAgICAgIE1hdGNoZXIgbTsKKworICAgICAgICAvLyBUZXN0IFBPU0lYIGdyb3VwcyB1c2luZyBccCBhbmQgXFAgKGluIHRoZSBncm91cCBhbmQgbm90IGluIHRoZSBncm91cCkKKyAgICAgICAgLy8gR3JvdXBzIGFyZSBMb3dlciwgVXBwZXIsIEFTQ0lJLCBBbHBoYSwgRGlnaXQsIFhEaWdpdCwgQWxudW0sIFB1bmN0LAorICAgICAgICAvLyBHcmFwaCwgUHJpbnQsIEJsYW5rLCBTcGFjZSwgQ250cmwKKyAgICAgICAgLy8gVGVzdCBccHtMb3dlcn0KKyAgICAgICAgLyoKKyAgICAgICAgICogRklYTUU6IFJlcXVpcmVzIGNvbXBsZXggcmFuZ2UgcHJvY2Vzc2luZworICAgICAgICAgKiBwID0gUGF0dGVybi5jb21waWxlKCI8XFxwe0xvd2VyfVxcZFxcUHtMb3dlcn06W1xccHtMb3dlcn1aXVxcc1teXFxQe0xvd2VyfV0+Iik7CisgICAgICAgICAqIG0gPSBwLm1hdGNoZXIoIjxhNFA6ZyB4PiIpOyBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsgbSA9CisgICAgICAgICAqIHAubWF0Y2hlcigiPHA0JTpaXHRxPiIpOyBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsgbSA9CisgICAgICAgICAqIHAubWF0Y2hlcigiPEE2IzplIGU+Iik7IGFzc2VydEZhbHNlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgICovCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlxccHtMb3dlcn0rIik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6Iik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworCisgICAgICAgIC8vIEludmFsaWQgdXNlcyBvZiBccHtMb3dlcn0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlxccCIpOworICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJcXHA7Iik7CisgICAgICAgICAgICBmYWlsKCJQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlxccHsiKTsKKyAgICAgICAgICAgIGZhaWwoIlBhdHRlcm5TeW50YXhFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiXFxwezsiKTsKKyAgICAgICAgICAgIGZhaWwoIlBhdHRlcm5TeW50YXhFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiXFxwe0xvd2VyIik7CisgICAgICAgICAgICBmYWlsKCJQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlxccHtMb3dlcjsiKTsKKyAgICAgICAgICAgIGZhaWwoIlBhdHRlcm5TeW50YXhFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICAvLyBUZXN0IFxwe1VwcGVyfQorICAgICAgICAvKgorICAgICAgICAgKiBGSVhNRTogUmVxdWlyZXMgY29tcGxleCByYW5nZSBwcm9jZXNzaW5nCisgICAgICAgICAqIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIjxcXHB7VXBwZXJ9XFxkXFxQe1VwcGVyfTpbXFxwe1VwcGVyfXpdXFxzW15cXFB7VXBwZXJ9XT4iKTsKKyAgICAgICAgICogbSA9IHAubWF0Y2hlcigiPEE0cDpHIFg+Iik7IGFzc2VydFRydWUobS5tYXRjaGVzKCkpOyBtID0KKyAgICAgICAgICogcC5tYXRjaGVyKCI8UDQlOnpcdFE+Iik7IGFzc2VydFRydWUobS5tYXRjaGVzKCkpOyBtID0KKyAgICAgICAgICogcC5tYXRjaGVyKCI8YTYjOkUgRT4iKTsgYXNzZXJ0RmFsc2UobS5tYXRjaGVzKCkpOworICAgICAgICAgKi8KKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiXFxwe1VwcGVyfSsiKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisKKyAgICAgICAgLy8gSW52YWxpZCB1c2VzIG9mIFxwe1VwcGVyfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiXFxwe1VwcGVyIik7CisgICAgICAgICAgICBmYWlsKCJQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlxccHtVcHBlcjsiKTsKKyAgICAgICAgICAgIGZhaWwoIlBhdHRlcm5TeW50YXhFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICAvLyBUZXN0IFxwe0FTQ0lJfQorICAgICAgICAvKgorICAgICAgICAgKiBGSVhNRTogUmVxdWlyZXMgY29tcGxleCByYW5nZSBwcm9jZXNzaW5nIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIjxcXHB7QVNDSUl9XFxkXFxQe0FTQ0lJfTpbXFxwe0FTQ0lJfVx1MTIzNF1cXHNbXlxcUHtBU0NJSX1dPiIpOworICAgICAgICAgKiBtID0gcC5tYXRjaGVyKCI8QTRcdTAwODA6RyBYPiIpOyBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsgbSA9CisgICAgICAgICAqIHAubWF0Y2hlcigiPFA0XHUwMGZmOlx1MTIzNFx0XG4+Iik7IGFzc2VydFRydWUobS5tYXRjaGVzKCkpOyBtID0KKyAgICAgICAgICogcC5tYXRjaGVyKCI8XHUwMDg0NiM6RSBFPiIpOyBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSkKKyAgICAgICAgICovCisgICAgICAgIGludCBpOworICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJcXHB7QVNDSUl9Iik7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCAweDgwOyBpKyspIHsKKyAgICAgICAgICAgIG0gPSBwLm1hdGNoZXIoQ2hhcmFjdGVyLnRvU3RyaW5nKChjaGFyKSBpKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKDsgaSA8IDB4ZmY7IGkrKykgeworICAgICAgICAgICAgbSA9IHAubWF0Y2hlcihDaGFyYWN0ZXIudG9TdHJpbmcoKGNoYXIpIGkpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEludmFsaWQgdXNlcyBvZiBccHtBU0NJSX0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlxccHtBU0NJSSIpOworICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJcXHB7QVNDSUk7Iik7CisgICAgICAgICAgICBmYWlsKCJQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gVGVzdCBccHtBbHBoYX0KKyAgICAgICAgLy8gVE9ETworCisgICAgICAgIC8vIFRlc3QgXHB7RGlnaXR9CisgICAgICAgIC8vIFRPRE8KKworICAgICAgICAvLyBUZXN0IFxwe1hEaWdpdH0KKyAgICAgICAgLy8gVE9ETworCisgICAgICAgIC8vIFRlc3QgXHB7QWxudW19CisgICAgICAgIC8vIFRPRE8KKworICAgICAgICAvLyBUZXN0IFxwe1B1bmN0fQorICAgICAgICAvLyBUT0RPCisKKyAgICAgICAgLy8gVGVzdCBccHtHcmFwaH0KKyAgICAgICAgLy8gVE9ETworCisgICAgICAgIC8vIFRlc3QgXHB7UHJpbnR9CisgICAgICAgIC8vIFRPRE8KKworICAgICAgICAvLyBUZXN0IFxwe0JsYW5rfQorICAgICAgICAvLyBUT0RPCisKKyAgICAgICAgLy8gVGVzdCBccHtTcGFjZX0KKyAgICAgICAgLy8gVE9ETworCisgICAgICAgIC8vIFRlc3QgXHB7Q250cmx9CisgICAgICAgIC8vIFRPRE8KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFVuaWNvZGVDYXRlZ29yaWVzKCkgdGhyb3dzIFBhdHRlcm5TeW50YXhFeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IFVuaWNvZGUgY2F0ZWdvcmllcyB1c2luZyBccCBhbmQgXFAKKyAgICAgICAgLy8gT25lIGxldHRlciBjb2RlczogTCwgTSwgTiwgUCwgUywgWiwgQworICAgICAgICAvLyBUd28gbGV0dGVyIGNvZGVzOiBMdSwgTmQsIFNjLCBTbSwgLi4uCisgICAgICAgIC8vIFNlZSBqYXZhLmxhbmcuQ2hhcmFjdGVyIGFuZCBVbmljb2RlIHN0YW5kYXJkIGZvciBjb21wbGV0ZSBsaXN0CisgICAgICAgIC8vIFRPRE8KKyAgICAgICAgLy8gVGVzdCBccHtMfQorICAgICAgICAvLyBUT0RPCisKKyAgICAgICAgLy8gVGVzdCBccHtOfQorICAgICAgICAvLyBUT0RPCisKKyAgICAgICAgLy8gVGVzdCB0d28gbGV0dGVyIGNvZGVzOgorICAgICAgICAvLyBGcm9tIHVuaWNvZGUub3JnOgorICAgICAgICAvLyBMdQorICAgICAgICAvLyBMbAorICAgICAgICAvLyBMdAorICAgICAgICAvLyBMbQorICAgICAgICAvLyBMbworICAgICAgICAvLyBNbgorICAgICAgICAvLyBNYworICAgICAgICAvLyBNZQorICAgICAgICAvLyBOZAorICAgICAgICAvLyBObAorICAgICAgICAvLyBObworICAgICAgICAvLyBQYworICAgICAgICAvLyBQZAorICAgICAgICAvLyBQcworICAgICAgICAvLyBQZQorICAgICAgICAvLyBQaQorICAgICAgICAvLyBQZgorICAgICAgICAvLyBQbworICAgICAgICAvLyBTbQorICAgICAgICAvLyBTYworICAgICAgICAvLyBTaworICAgICAgICAvLyBTbworICAgICAgICAvLyBacworICAgICAgICAvLyBabAorICAgICAgICAvLyBacAorICAgICAgICAvLyBDYworICAgICAgICAvLyBDZgorICAgICAgICAvLyBDcworICAgICAgICAvLyBDbworICAgICAgICAvLyBDbgorCisgICAgICAgIC8vIFRPRE8gYWRkIG1vcmUgdGVzdHMgcGVyIGNhdGVnb3J5CisgICAgICAgIC8veyJDYyIsICJcdTAwMDAiLCAiLVx1MDA0MSJ9LAorICAgICAgICB0ZXN0Q2F0ZWdvcnkoIkNmIiwgIlx1MjAyQiIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIkNvIiwgIlx1RTAwMCIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIkNzIiwgIlx1RDgwMCIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIkxsIiwgImEiLCAiYiIsICJ4IiwgInkiLCAieiIsICItQSIsICItWiIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIkxtIiwgIlx1MDJCOSIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIkx1IiwgIkIiLCAiQyIsICItYyIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIkxvIiwgIlx1MDVFMiIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIkx0IiwgIlx1MDFDNSIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIk1jIiwgIlx1MDkwMyIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIk1lIiwgIlx1MDQ4OCIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIk1uIiwgIlx1MDMwMCIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIk5kIiwgIlx1MDAzMCIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIk5sIiwgIlx1MjE2NCIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIk5vIiwgIlx1MEJGMCIpOworICAgICAgICAvLyB0ZXN0Q2F0ZWdvcnkoIlBjIiwgIlx1MzBGQiIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIlBkIiwgIlx1MjAxNSIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIlBlIiwgIlx1MjA3RSIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIlBvIiwgIlx1MDBCNyIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIlBzIiwgIlx1MEYzQyIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIlNjIiwgIlx1MjBBMCIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIlNrIiwgIlx1MDBCOCIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIlNtIiwgIlx1MDAyQiIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIlNvIiwgIlx1MEI3MCIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIlpsIiwgIlx1MjAyOCIpOworICAgICAgICAvLyB0ZXN0Q2F0ZWdvcnkoIlBpIiwgIlx1MjAwQyIpOworICAgICAgICB0ZXN0Q2F0ZWdvcnkoIlpwIiwgIlx1MjAyOSIpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0Q2F0ZWdvcnkoU3RyaW5nIGNhdCwgU3RyaW5nLi4uIG1hdGNoZXMpIHsKKyAgICAgICAgU3RyaW5nIHBhID0gInsiK2NhdCsifSI7CisgICAgICAgIFN0cmluZyBwYXQgPSAiXFxwIitwYTsKKyAgICAgICAgU3RyaW5nIG5wYXQgPSAiXFxQIitwYTsKKyAgICAgICAgUGF0dGVybiBwID0gUGF0dGVybi5jb21waWxlKHBhdCk7CisgICAgICAgIFBhdHRlcm4gcG4gPSBQYXR0ZXJuLmNvbXBpbGUobnBhdCk7CisgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbWF0Y2hlcy5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgU3RyaW5nIHQgPSBtYXRjaGVzW2pdOworICAgICAgICAgICAgYm9vbGVhbiBpbnZlcnQgPSB0LnN0YXJ0c1dpdGgoIi0iKTsKKyAgICAgICAgICAgIGlmIChpbnZlcnQpIHsKKyAgICAgICAgICAgICAgICAvLyB0ZXN0IG5lZ2F0aXZlIGNhc2UsIGV4cGVjdGVkIHRvIGZhaWwKKyAgICAgICAgICAgICAgICB0ID0gdC5zdWJzdHJpbmcoMSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoImV4cGVjdGVkICciK3QrIicgdG8gbm90IGJlIG1hdGNoZWQgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAiYnkgcGF0dGVybiAnIitwYXQsIHAubWF0Y2hlcih0KS5tYXRjaGVzKCkpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImV4cGVjdGVkICciK3QrIicgdG8gICIgKworICAgICAgICAgICAgICAgICAgICAgICAgImJlIG1hdGNoZWQgYnkgcGF0dGVybiAnIitucGF0LCBwbi5tYXRjaGVyKHQpLm1hdGNoZXMoKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImV4cGVjdGVkICciK3QrIicgdG8gYmUgbWF0Y2hlZCAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICJieSBwYXR0ZXJuICciK3BhdCwgcC5tYXRjaGVyKHQpLm1hdGNoZXMoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoImV4cGVjdGVkICciK3QrIicgdG8gICIgKworICAgICAgICAgICAgICAgICAgICAgICAgIm5vdCBiZSBtYXRjaGVkIGJ5IHBhdHRlcm4gJyIrbnBhdCwgcG4ubWF0Y2hlcih0KS5tYXRjaGVzKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFVuaWNvZGVCbG9ja3MoKSB0aHJvd3MgUGF0dGVyblN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIFBhdHRlcm4gcDsKKyAgICAgICAgTWF0Y2hlciBtOworICAgICAgICBpbnQgaSwgajsKKworICAgICAgICAvLyBUZXN0IFVuaWNvZGUgYmxvY2tzIHVzaW5nIFxwIGFuZCBcUAorICAgICAgICAvLyBGSVhNRToKKyAgICAgICAgLy8gTm90ZSB0aGF0IExhdGluRXh0ZW5kZWQtQiBhbmQgQXJhYmljUHJlc2VudGF0aW9ucy1CIGFyZSB1bnJlY29nbml6ZWQKKyAgICAgICAgLy8gYnkgdGhlIHJlZmVyZW5jZSBKREsuCisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBVQmxvY2tzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogcCA9IFBhdHRlcm4uY29tcGlsZSgiXFxweyIrVUJsb2Nrc1tpXS5uYW1lKyJ9Iik7CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogaWYgKFVCbG9ja3NbaV0ubG93ID4gMCkgeyBtID0KKyAgICAgICAgICAgICAqIHAubWF0Y2hlcihDaGFyYWN0ZXIudG9TdHJpbmcoKGNoYXIpKFVCbG9ja3NbaV0ubG93LTEpKSk7CisgICAgICAgICAgICAgKiBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSk7IH0gZm9yIChqPVVCbG9ja3NbaV0ubG93OyBqIDw9CisgICAgICAgICAgICAgKiBVQmxvY2tzW2ldLmhpZ2g7IGorKykgeyBtID0KKyAgICAgICAgICAgICAqIHAubWF0Y2hlcihDaGFyYWN0ZXIudG9TdHJpbmcoKGNoYXIpaikpOworICAgICAgICAgICAgICogYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7IH0gaWYgKFVCbG9ja3NbaV0uaGlnaCA8IDB4RkZGRikgeyBtID0KKyAgICAgICAgICAgICAqIHAubWF0Y2hlcihDaGFyYWN0ZXIudG9TdHJpbmcoKGNoYXIpKFVCbG9ja3NbaV0uaGlnaCsxKSkpOworICAgICAgICAgICAgICogYXNzZXJ0RmFsc2UobS5tYXRjaGVzKCkpOyB9CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogcCA9IFBhdHRlcm4uY29tcGlsZSgiXFxQeyIrVUJsb2Nrc1tpXS5uYW1lKyJ9Iik7CisgICAgICAgICAgICAgKgorICAgICAgICAgICAgICogaWYgKFVCbG9ja3NbaV0ubG93ID4gMCkgeyBtID0KKyAgICAgICAgICAgICAqIHAubWF0Y2hlcihDaGFyYWN0ZXIudG9TdHJpbmcoKGNoYXIpKFVCbG9ja3NbaV0ubG93LTEpKSk7CisgICAgICAgICAgICAgKiBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsgfSBmb3IgKGo9VUJsb2Nrc1tpXS5sb3c7IGogPAorICAgICAgICAgICAgICogVUJsb2Nrc1tpXS5oaWdoOyBqKyspIHsgbSA9CisgICAgICAgICAgICAgKiBwLm1hdGNoZXIoQ2hhcmFjdGVyLnRvU3RyaW5nKChjaGFyKWopKTsKKyAgICAgICAgICAgICAqIGFzc2VydEZhbHNlKG0ubWF0Y2hlcygpKTsgfSBpZiAoVUJsb2Nrc1tpXS5oaWdoIDwgMHhGRkZGKSB7IG0gPQorICAgICAgICAgICAgICogcC5tYXRjaGVyKENoYXJhY3Rlci50b1N0cmluZygoY2hhcikoVUJsb2Nrc1tpXS5oaWdoKzEpKSk7CisgICAgICAgICAgICAgKiBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsgfQorICAgICAgICAgICAgICovCisKKyAgICAgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlxccHtJbiIgKyBVQmxvY2tzW2ldLm5hbWUgKyAifSIpOworLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisvLyBBZGRlZCB0aGUgbmFtZSBvZiB0aGUgYmxvY2sgdW5kZXIgdGVzdCB0byB0aGUgYXNzZXJ0aW9uIHRvIGdldCBtb3JlIG91dHB1dC4KKworICAgICAgICAgICAgaWYgKFVCbG9ja3NbaV0ubG93ID4gMCkgeworICAgICAgICAgICAgICAgIG0gPSBwLm1hdGNoZXIoQ2hhcmFjdGVyLnRvU3RyaW5nKChjaGFyKSAoVUJsb2Nrc1tpXS5sb3cgLSAxKSkpOworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKFVCbG9ja3NbaV0ubmFtZSwgbS5tYXRjaGVzKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChqID0gVUJsb2Nrc1tpXS5sb3c7IGogPD0gVUJsb2Nrc1tpXS5oaWdoOyBqKyspIHsKKyAgICAgICAgICAgICAgICBtID0gcC5tYXRjaGVyKENoYXJhY3Rlci50b1N0cmluZygoY2hhcikgaikpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoVUJsb2Nrc1tpXS5uYW1lLCBtLm1hdGNoZXMoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoVUJsb2Nrc1tpXS5oaWdoIDwgMHhGRkZGKSB7CisgICAgICAgICAgICAgICAgbSA9IHAubWF0Y2hlcihDaGFyYWN0ZXIudG9TdHJpbmcoKGNoYXIpIChVQmxvY2tzW2ldLmhpZ2ggKyAxKSkpOworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKFVCbG9ja3NbaV0ubmFtZSwgbS5tYXRjaGVzKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJcXFB7SW4iICsgVUJsb2Nrc1tpXS5uYW1lICsgIn0iKTsKKworICAgICAgICAgICAgaWYgKFVCbG9ja3NbaV0ubG93ID4gMCkgeworICAgICAgICAgICAgICAgIG0gPSBwLm1hdGNoZXIoQ2hhcmFjdGVyLnRvU3RyaW5nKChjaGFyKSAoVUJsb2Nrc1tpXS5sb3cgLSAxKSkpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoVUJsb2Nrc1tpXS5uYW1lLCBtLm1hdGNoZXMoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKGogPSBVQmxvY2tzW2ldLmxvdzsgaiA8IFVCbG9ja3NbaV0uaGlnaDsgaisrKSB7CisgICAgICAgICAgICAgICAgbSA9IHAubWF0Y2hlcihDaGFyYWN0ZXIudG9TdHJpbmcoKGNoYXIpIGopKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShVQmxvY2tzW2ldLm5hbWUsIG0ubWF0Y2hlcygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChVQmxvY2tzW2ldLmhpZ2ggPCAweEZGRkYpIHsKKyAgICAgICAgICAgICAgICBtID0gcC5tYXRjaGVyKENoYXJhY3Rlci50b1N0cmluZygoY2hhcikgKFVCbG9ja3NbaV0uaGlnaCArIDEpKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShVQmxvY2tzW2ldLm5hbWUsIG0ubWF0Y2hlcygpKTsKKyAgICAgICAgICAgIH0KKworLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDYXB0dXJpbmdHcm91cHMoKSB0aHJvd3MgUGF0dGVyblN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIFBhdHRlcm4gcDsKKyAgICAgICAgTWF0Y2hlciBtOworCisgICAgICAgIC8vIFRlc3Qgc2ltcGxlIGNhcHR1cmluZyBncm91cHMKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiKGErKWIiKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYWFhYWFhYWFiIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgbS5ncm91cENvdW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFhYWFhYWFhIiwgbS5ncm91cCgxKSk7CisKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiKChhbikrKSgoYXMpKykiKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYW5hbmFzIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgbS5ncm91cENvdW50KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFuYW5hcyIsIG0uZ3JvdXAoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFuYW4iLCBtLmdyb3VwKDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhbiIsIG0uZ3JvdXAoMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFzIiwgbS5ncm91cCgzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYXMiLCBtLmdyb3VwKDQpKTsKKworICAgICAgICAvLyBUZXN0IGdyb3VwaW5nIHdpdGhvdXQgY2FwdHVyZSAoPzouLi4pCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIig/Oig/OmFuKSspKGFzKSIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJhbmFuYXMiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBtLmdyb3VwQ291bnQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYXMiLCBtLmdyb3VwKDEpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG0uZ3JvdXAoMik7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9vYmUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBUZXN0IGNvbWJpbmF0aW9uIG9mIGdyb3VwaW5nIGFuZCBjYXB0dXJlCisgICAgICAgIC8vIFRPRE8KKworICAgICAgICAvLyBUZXN0IFw8bnVtPiBzZXF1ZW5jZSB3aXRoIGNhcHR1cmluZyBhbmQgbm9uLWNhcHR1cmluZyBncm91cHMKKyAgICAgICAgLy8gVE9ETworCisgICAgICAgIC8vIFRlc3QgXDxudW0+IHdpdGggPG51bT4gb3V0IG9mIHJhbmdlCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIigoYW4pKylhc1xcMSIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJhbmFuYXNhbmFuIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCIoKGFuKSspYXNcXDQiKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIFBhdHRlcm5TeW50YXhFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBwc2UpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVwZWF0cygpIHsKKyAgICAgICAgUGF0dGVybiBwOworICAgICAgICBNYXRjaGVyIG07CisKKyAgICAgICAgLy8gVGVzdCA/CisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIihhYmMpP2MiKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYWJjYyIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYyIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiY2MiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJhYmNhYmNjIik7CisgICAgICAgIGFzc2VydEZhbHNlKG0ubWF0Y2hlcygpKTsKKworICAgICAgICAvLyBUZXN0ICoKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiKGFiYykqYyIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJhYmNjIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJjIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJjYyIpOworICAgICAgICBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImFiY2FiY2MiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisKKyAgICAgICAgLy8gVGVzdCArCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIihhYmMpK2MiKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYWJjYyIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYyIpOworICAgICAgICBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImNjIik7CisgICAgICAgIGFzc2VydEZhbHNlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYWJjYWJjYyIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKworICAgICAgICAvLyBUZXN0IHs8bnVtPn0sIGluY2x1ZGluZyAwLCAxIGFuZCBtb3JlCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIihhYmMpezB9YyIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJhYmNjIik7CisgICAgICAgIGFzc2VydEZhbHNlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYyIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKworICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCIoYWJjKXsxfWMiKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYWJjYyIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYyIpOworICAgICAgICBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImFiY2FiY2MiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5tYXRjaGVzKCkpOworCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIihhYmMpezJ9YyIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJhYmNjIik7CisgICAgICAgIGFzc2VydEZhbHNlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYyIpOworICAgICAgICBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImNjIik7CisgICAgICAgIGFzc2VydEZhbHNlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYWJjYWJjYyIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKworICAgICAgICAvLyBUZXN0IHs8bnVtPix9LCBpbmNsdWRpbmcgMCwgMSBhbmQgbW9yZQorICAgICAgICAvLyBUT0RPCisKKyAgICAgICAgLy8gVGVzdCB7PG4xPiw8bjI+fSwgd2l0aCBuMSA8IG4yLCBuMSA9IG4yIGFuZCBuMSA+IG4yIChpbGxlZ2FsPykKKyAgICAgICAgLy8gVE9ETworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QW5jaG9ycygpIHRocm93cyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgUGF0dGVybiBwOworICAgICAgICBNYXRjaGVyIG07CisKKyAgICAgICAgLy8gVGVzdCBeLCBkZWZhdWx0IGFuZCBNVUxUSUxJTkUKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiXmFiY1xcbl5hYmMiLCBQYXR0ZXJuLk1VTFRJTElORSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImFiY1xuYWJjIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIl5hYmNcXG5eYWJjIik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImFiY1xuYWJjIik7CisgICAgICAgIGFzc2VydEZhbHNlKG0ubWF0Y2hlcygpKTsKKworICAgICAgICAvLyBUZXN0ICQsIGRlZmF1bHQgYW5kIE1VTFRJTElORQorICAgICAgICAvLyBUT0RPCisKKyAgICAgICAgLy8gVGVzdCBcYiAod29yZCBib3VuZGFyeSkKKyAgICAgICAgLy8gVE9ETworCisgICAgICAgIC8vIFRlc3QgXEIgKG5vdCBhIHdvcmQgYm91bmRhcnkpCisgICAgICAgIC8vIFRPRE8KKworICAgICAgICAvLyBUZXN0IFxBIChiZWdpbm5pbmcgb2Ygc3RyaW5nKQorICAgICAgICAvLyBUT0RPCisKKyAgICAgICAgLy8gVGVzdCBcWiAoZW5kIG9mIHN0cmluZykKKyAgICAgICAgLy8gVE9ETworCisgICAgICAgIC8vIFRlc3QgXHogKGVuZCBvZiBzdHJpbmcpCisgICAgICAgIC8vIFRPRE8KKworICAgICAgICAvLyBUZXN0IFxHCisgICAgICAgIC8vIFRPRE8KKworICAgICAgICAvLyBUZXN0IHBvc2l0aXZlIGxvb2thaGVhZCB1c2luZyAoPz0uLi4pCisgICAgICAgIC8vIFRPRE8KKworICAgICAgICAvLyBUZXN0IG5lZ2F0aXZlIGxvb2thaGVhZCB1c2luZyAoPyEuLi4pCisgICAgICAgIC8vIFRPRE8KKworICAgICAgICAvLyBUZXN0IHBvc2l0aXZlIGxvb2tiZWhpbmQgdXNpbmcgKD88PS4uLikKKyAgICAgICAgLy8gVE9ETworCisgICAgICAgIC8vIFRlc3QgbmVnYXRpdmUgbG9va2JlaGluZCB1c2luZyAoPzwhLi4uKQorICAgICAgICAvLyBUT0RPCisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RNaXNjKCkgdGhyb3dzIFBhdHRlcm5TeW50YXhFeGNlcHRpb24geworICAgICAgICBQYXR0ZXJuIHA7CisgICAgICAgIE1hdGNoZXIgbTsKKworICAgICAgICAvLyBUZXN0ICg/Pi4uLikKKyAgICAgICAgLy8gVE9ETworCisgICAgICAgIC8vIFRlc3QgKD9vbmZsYWdzLW9mZmZsYWdzKQorICAgICAgICAvLyBWYWxpZCBmbGFncyBhcmUgaSxtLGQscyx1LHgKKyAgICAgICAgLy8gVE9ETworCisgICAgICAgIC8vIFRlc3QgKD9vbmZsYWdzLW9mZmZsYWdzOi4uLikKKyAgICAgICAgLy8gVE9ETworCisgICAgICAgIC8vIFRlc3QgXFEsIFxFCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlthLXpdKztcXFFbYS16XSs7XFxRKGZvby4qKTtcXEVbMC05XSsiKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYWJjO1thLXpdKztcXFEoZm9vLiopOzQxMSIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgbSA9IHAubWF0Y2hlcigiYWJjO2RlZjtmb280Mjs1NTUiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5tYXRjaGVzKCkpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJhYmM7XFxRZGVmO1xcUWZvbzk5O1xcRTEyMyIpOworICAgICAgICBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSk7CisKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiW2Etel0rOyhmb29bMC05XS1cXFEoLi4uKVxcRSk7WzAtOV0rIik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImFiYztmb281LSguLi4pOzEyMyIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb281LSguLi4pIiwgbS5ncm91cCgxKSk7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImFiYztmb285LSh4eHgpOzc4OSIpOworICAgICAgICBhc3NlcnRGYWxzZShtLm1hdGNoZXMoKSk7CisKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiW2Etel0rOyhiYXJbMC05XS1bYS16XFxRJC1cXEVdKyk7WzAtOV0rIik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImFiYztiYXIwLWRlZiQtOzEyMyIpOworICAgICAgICBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKworICAgICAgICAvLyBGSVhNRToKKyAgICAgICAgLy8gVGhpcyBzaG91bGQgd29yayB0aGUgc2FtZSBhcyB0aGUgcGF0dGVybiBhYm92ZSBidXQgZmFpbHMgd2l0aCB0aGUKKyAgICAgICAgLy8gdGhlIHJlZmVyZW5jZSBKREsKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiW2Etel0rOyhiYXJbMC05XS1bYS16XFxRLSRcXEVdKyk7WzAtOV0rIik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImFiYztiYXIwLWRlZiQtOzEyMyIpOworICAgICAgICAvLyBhc3NlcnRUcnVlKG0ubWF0Y2hlcygpKTsKKworICAgICAgICAvLyBGSVhNRToKKyAgICAgICAgLy8gVGhpcyBzaG91bGQgd29yayB0b28gLi4gaXQgbG9va3MgYXMgaWYganVzdCBhYm91dCBhbnl0aGluZyB0aGF0CisgICAgICAgIC8vIGhhcyBtb3JlCisgICAgICAgIC8vIHRoYW4gb25lIGNoYXJhY3RlciBiZXR3ZWVuIFxRIGFuZCBcRSBpcyBicm9rZW4gaW4gdGhlIHRoZSByZWZlcmVuY2UgSkRLCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlthLXpdKzsoYmFyWzAtOV0tW2EtelxcUVswLTldXFxFXSspO1swLTldKyIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJhYmM7YmFyMC1kZWZbOTldLV0weFs7MTIzIik7CisgICAgICAgIC8vIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworCisgICAgICAgIC8vIFRoaXMgaXMgdGhlIHNhbWUgYXMgYWJvdmUgYnV0IHdpdGggZXhwbGljaXQgZXNjYXBlcyAuLiBhbmQgdGhpcworICAgICAgICAvLyBkb2VzIHdvcmsKKyAgICAgICAgLy8gb24gdGhlIHRoZSByZWZlcmVuY2UgSkRLCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIlthLXpdKzsoYmFyWzAtOV0tW2EtelxcWzBcXC05XFxdXSspO1swLTldKyIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJhYmM7YmFyMC1kZWZbOTldLV0weFs7MTIzIik7CisgICAgICAgIGFzc2VydFRydWUobS5tYXRjaGVzKCkpOworCisgICAgICAgIC8vIFRlc3QgIzxjb21tZW50IHRleHQ+CisgICAgICAgIC8vIFRPRE8KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENvbXBpbGUxKCkgdGhyb3dzIFBhdHRlcm5TeW50YXhFeGNlcHRpb24geworICAgICAgICBQYXR0ZXJuIHBhdHRlcm4gPSBQYXR0ZXJuCisgICAgICAgICAgICAgICAgLmNvbXBpbGUoIlswLTlBLVphLXpdWzAtOUEtWmEtelxceDJlXFx4M2FcXHgyZFxceDVmXSoiKTsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSAiaXNvLTg4NTktMSI7CisgICAgICAgIGFzc2VydFRydWUocGF0dGVybi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDb21waWxlMigpIHRocm93cyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGZpbmRTdHJpbmcgPSAiXFxRaW1wb3J0XFxFIjsKKworICAgICAgICBQYXR0ZXJuIHBhdHRlcm4gPSBQYXR0ZXJuLmNvbXBpbGUoZmluZFN0cmluZywgMCk7CisgICAgICAgIE1hdGNoZXIgbWF0Y2hlciA9IHBhdHRlcm4ubWF0Y2hlcihuZXcgU3RyaW5nKAorICAgICAgICAgICAgICAgICJpbXBvcnQgYS5BO1xuXG4gaW1wb3J0IGIuQjtcbmNsYXNzIEMge30iKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXRjaGVyLmZpbmQoMCkpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29tcGlsZTMoKSB0aHJvd3MgUGF0dGVyblN5bnRheEV4Y2VwdGlvbiB7CisgICAgICAgIFBhdHRlcm4gcDsKKyAgICAgICAgTWF0Y2hlciBtOworICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJhJCIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCJhXG4iKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIG0uZ3JvdXAoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKworICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCIoYSQpIik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIoImFcbiIpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgbS5ncm91cCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgbS5ncm91cCgxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKworICAgICAgICBwID0gUGF0dGVybi5jb21waWxlKCJeLiokIiwgUGF0dGVybi5NVUxUSUxJTkUpOworCisgICAgICAgIG0gPSBwLm1hdGNoZXIoImFcbiIpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJbIittLmdyb3VwKCkrIl0iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgbS5ncm91cCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5maW5kKCkpOworCisgICAgICAgIG0gPSBwLm1hdGNoZXIoImFcbmJcbiIpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJbIittLmdyb3VwKCkrIl0iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgbS5ncm91cCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiWyIrbS5ncm91cCgpKyJdIik7CisgICAgICAgIGFzc2VydEVxdWFscygiYiIsIG0uZ3JvdXAoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKworICAgICAgICBtID0gcC5tYXRjaGVyKCJhXG5iIik7CisgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlsiK20uZ3JvdXAoKSsiXSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBtLmdyb3VwKCkpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiIiwgbS5ncm91cCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5maW5kKCkpOworCisgICAgICAgIG0gPSBwLm1hdGNoZXIoIlxuYWFcclxuYmJccmNjXG5cbiIpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJbIittLmdyb3VwKCkrIl0iKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmdyb3VwKCkuZXF1YWxzKCIiKSk7CisgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlsiK20uZ3JvdXAoKSsiXSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFhIiwgbS5ncm91cCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiWyIrbS5ncm91cCgpKyJdIik7CisgICAgICAgIGFzc2VydEVxdWFscygiYmIiLCBtLmdyb3VwKCkpOworICAgICAgICBhc3NlcnRUcnVlKG0uZmluZCgpKTsKKyAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJbIittLmdyb3VwKCkrIl0iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjYyIsIG0uZ3JvdXAoKSk7CisgICAgICAgIGFzc2VydFRydWUobS5maW5kKCkpOworICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlsiK20uZ3JvdXAoKSsiXSIpOworICAgICAgICBhc3NlcnRUcnVlKG0uZ3JvdXAoKS5lcXVhbHMoIiIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobS5maW5kKCkpOworCisgICAgICAgIG0gPSBwLm1hdGNoZXIoImEiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIG0uZ3JvdXAoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG0uZmluZCgpKTsKKworLy8gQkVHSU4gYW5kcm9pZC1yZW1vdmVkCisvLyBNYWtlcyBubyBzZW5zZSB0byBkdXBsaWNhdGUgdGhpcyB3ZWlyZCBiZWhhdmlvcgorLy8gICAgICAgIG0gPSBwLm1hdGNoZXIoIiIpOworLy8gICAgICAgIC8vIEZJWE1FOiBUaGlzIG1hdGNoZXMgdGhlIHJlZmVyZW5jZSBiZWhhdmlvdXIgYnV0IGlzCisvLyAgICAgICAgLy8gaW5jb25zaXN0ZW50IHdpdGggbWF0Y2hpbmcgImEiIC0gaWUuIHRoZSBlbmQgb2YgdGhlCisvLyAgICAgICAgLy8gdGFyZ2V0IHN0cmluZyBzaG91bGQgbWF0Y2ggYWdhaW5zdCAkIGFsd2F5cyBidXQgdGhpcworLy8gICAgICAgIC8vIGFwcGVhcnMgdG8gd29yayB3aXRoIHRoZSBudWxsIHN0cmluZyBvbmx5IHdoZW4gbm90IGluCisvLyAgICAgICAgLy8gbXVsdGlsaW5lIG1vZGUgKHNlZSBiZWxvdykKKy8vICAgICAgICBhc3NlcnRGYWxzZShtLmZpbmQoKSk7CisvLyBFTkQgYW5kcm9pZC1yZW1vdmVkCisKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiXi4qJCIpOworICAgICAgICBtID0gcC5tYXRjaGVyKCIiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLmZpbmQoKSk7CisgICAgICAgIGFzc2VydFRydWUobS5ncm91cCgpLmVxdWFscygiIikpOworICAgICAgICBhc3NlcnRGYWxzZShtLmZpbmQoKSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDb21waWxlNCgpIHRocm93cyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGZpbmRTdHJpbmcgPSAiXFxRcHVibGljXFxFIjsKKyAgICAgICAgU3RyaW5nQnVmZmVyIHRleHQgPSBuZXcgU3RyaW5nQnVmZmVyKCIgICAgcHVibGljIGNsYXNzIENsYXNzIHtcbiIKKyAgICAgICAgICAgICAgICArICIgICAgcHVibGljIGNsYXNzIENsYXNzIHsiKTsKKworICAgICAgICBQYXR0ZXJuIHBhdHRlcm4gPSBQYXR0ZXJuLmNvbXBpbGUoZmluZFN0cmluZywgMCk7CisgICAgICAgIE1hdGNoZXIgbWF0Y2hlciA9IHBhdHRlcm4ubWF0Y2hlcih0ZXh0KTsKKworICAgICAgICBib29sZWFuIGZvdW5kID0gbWF0Y2hlci5maW5kKCk7CisgICAgICAgIGFzc2VydFRydWUoZm91bmQpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgbWF0Y2hlci5zdGFydCgpKTsKKyAgICAgICAgaWYgKGZvdW5kKSB7CisgICAgICAgICAgICAvLyBtb2RpZnkgdGV4dAorICAgICAgICAgICAgdGV4dC5kZWxldGUoMCwgdGV4dC5sZW5ndGgoKSk7CisgICAgICAgICAgICB0ZXh0LmFwcGVuZCgiVGV4dCBoYXZlIGJlZW4gY2hhbmdlZC4iKTsKKyAgICAgICAgICAgIG1hdGNoZXIucmVzZXQodGV4dCk7CisgICAgICAgIH0KKworICAgICAgICBmb3VuZCA9IG1hdGNoZXIuZmluZCgpOworICAgICAgICBhc3NlcnRGYWxzZShmb3VuZCk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDb21waWxlNSgpIHRocm93cyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgUGF0dGVybiBwID0gUGF0dGVybi5jb21waWxlKCJeWzAtOV0iKTsKKyAgICAgICAgU3RyaW5nIHNbXSA9IHAuc3BsaXQoIjEyIiwgLTEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHNbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoIjIiLCBzWzFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHMubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvLyAgICAgIHB1YmxpYyB2b2lkIHRlc3RDb21waWxlNigpIHsKKyAgICAvLyAgICAgICAgU3RyaW5nIHJlZ2V4ID0gIltcXHB7TH1bXFxwe01ufVtcXHB7UGN9W1xccHtOZH1bXFxwe05sfVtcXHB7U2N9XV1dXV1dKyI7CisgICAgLy8gICAgICAgIFN0cmluZyByZWdleCA9ICJbXFxwe0x9XFxwe01ufVxccHtQY31cXHB7TmR9XFxwe05sfVxccHtTY31dKyI7CisgICAgLy8gICAgICAgIHRyeSB7CisgICAgLy8gICAgICAgICAgICBQYXR0ZXJuIHBhdHRlcm4gPSBQYXR0ZXJuLmNvbXBpbGUocmVnZXgsIFBhdHRlcm4uTVVMVElMSU5FKTsKKyAgICAvLyAgICAgICAgICAgIGFzc2VydFRydWUodHJ1ZSk7CisgICAgLy8gICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworICAgIC8vICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAvLyAgICAgICAgICAgIGFzc2VydFRydWUoZmFsc2UpOworICAgIC8vICAgICAgICB9CisgICAgLy8gICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgVUJJbmZvIHsKKyAgICAgICAgcHVibGljIFVCSW5mbyhpbnQgbG93LCBpbnQgaGlnaCwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgICAgICAgICB0aGlzLmxvdyA9IGxvdzsKKyAgICAgICAgICAgIHRoaXMuaGlnaCA9IGhpZ2g7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIG5hbWU7CisKKyAgICAgICAgcHVibGljIGludCBsb3csIGhpZ2g7CisgICAgfQorCisgICAgLy8gQSB0YWJsZSByZXByZXNlbnRpbmcgdGhlIHVuaWNvZGUgY2F0ZWdvcmllcworICAgIC8vcHJpdmF0ZSBzdGF0aWMgVUJJbmZvW10gVUNhdGVnb3JpZXMgPSB7CisgICAgLy8gTHUKKyAgICAvLyBMbAorICAgIC8vIEx0CisgICAgLy8gTG0KKyAgICAvLyBMbworICAgIC8vIE1uCisgICAgLy8gTWMKKyAgICAvLyBNZQorICAgIC8vIE5kCisgICAgLy8gTmwKKyAgICAvLyBObworICAgIC8vIFBjCisgICAgLy8gUGQKKyAgICAvLyBQcworICAgIC8vIFBlCisgICAgLy8gUGkKKyAgICAvLyBQZgorICAgIC8vIFBvCisgICAgLy8gU20KKyAgICAvLyBTYworICAgIC8vIFNrCisgICAgLy8gU28KKyAgICAvLyBacworICAgIC8vIFpsCisgICAgLy8gWnAKKyAgICAvLyBDYworICAgIC8vIENmCisgICAgLy8gQ3MKKyAgICAvLyBDbworICAgIC8vIENuCisgICAgLy99OworCisgICAgLy8gQSB0YWJsZSByZXByZXNlbnRpbmcgdGhlIHVuaWNvZGUgY2hhcmFjdGVyIGJsb2NrcworICAgIHByaXZhdGUgc3RhdGljIFVCSW5mb1tdIFVCbG9ja3MgPSB7CisgICAgLyogMDAwMDsgMDA3RjsgQmFzaWMgTGF0aW4gKi8KKyAgICBuZXcgVUJJbmZvKDB4MDAwMCwgMHgwMDdGLCAiQmFzaWNMYXRpbiIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkJBU0lDX0xBVElOCisgICAgICAgICAgICAvKiAwMDgwOyAwMEZGOyBMYXRpbi0xIFN1cHBsZW1lbnQgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgwMDgwLCAweDAwRkYsICJMYXRpbi0xU3VwcGxlbWVudCIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkxBVElOXzFfU1VQUExFTUVOVAorICAgICAgICAgICAgLyogMDEwMDsgMDE3RjsgTGF0aW4gRXh0ZW5kZWQtQSAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDAxMDAsIDB4MDE3RiwgIkxhdGluRXh0ZW5kZWQtQSIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkxBVElOX0VYVEVOREVEX0EKKyAgICAgICAgICAgIC8qIDAxODA7IDAyNEY7IExhdGluIEV4dGVuZGVkLUIgKi8KKyAgICAgICAgICAgIC8vIG5ldyBVQkluZm8gKDB4MDE4MCwweDAyNEYsIkluTGF0aW5FeHRlbmRlZC1CIiksIC8vCisgICAgICAgICAgICAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkxBVElOX0VYVEVOREVEX0IKKyAgICAgICAgICAgIC8qIDAyNTA7IDAyQUY7IElQQSBFeHRlbnNpb25zICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MDI1MCwgMHgwMkFGLCAiSVBBRXh0ZW5zaW9ucyIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLklQQV9FWFRFTlNJT05TCisgICAgICAgICAgICAvKiAwMkIwOyAwMkZGOyBTcGFjaW5nIE1vZGlmaWVyIExldHRlcnMgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgwMkIwLCAweDAyRkYsICJTcGFjaW5nTW9kaWZpZXJMZXR0ZXJzIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suU1BBQ0lOR19NT0RJRklFUl9MRVRURVJTCisgICAgICAgICAgICAvKiAwMzAwOyAwMzZGOyBDb21iaW5pbmcgRGlhY3JpdGljYWwgTWFya3MgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgwMzAwLCAweDAzNkYsICJDb21iaW5pbmdEaWFjcml0aWNhbE1hcmtzIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suQ09NQklOSU5HX0RJQUNSSVRJQ0FMX01BUktTCisgICAgICAgICAgICAvKiAwMzcwOyAwM0ZGOyBHcmVlayAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDAzNzAsIDB4MDNGRiwgIkdyZWVrIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suR1JFRUsKKyAgICAgICAgICAgIC8qIDA0MDA7IDA0RkY7IEN5cmlsbGljICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MDQwMCwgMHgwNEZGLCAiQ3lyaWxsaWMiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5DWVJJTExJQworICAgICAgICAgICAgLyogMDUzMDsgMDU4RjsgQXJtZW5pYW4gKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgwNTMwLCAweDA1OEYsICJBcm1lbmlhbiIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkFSTUVOSUFOCisgICAgICAgICAgICAvKiAwNTkwOyAwNUZGOyBIZWJyZXcgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgwNTkwLCAweDA1RkYsICJIZWJyZXciKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5IRUJSRVcKKyAgICAgICAgICAgIC8qIDA2MDA7IDA2RkY7IEFyYWJpYyAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDA2MDAsIDB4MDZGRiwgIkFyYWJpYyIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkFSQUJJQworICAgICAgICAgICAgLyogMDcwMDsgMDc0RjsgU3lyaWFjICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MDcwMCwgMHgwNzRGLCAiU3lyaWFjIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suU1lSSUFDCisgICAgICAgICAgICAvKiAwNzgwOyAwN0JGOyBUaGFhbmEgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgwNzgwLCAweDA3QkYsICJUaGFhbmEiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5USEFBTkEKKyAgICAgICAgICAgIC8qIDA5MDA7IDA5N0Y7IERldmFuYWdhcmkgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgwOTAwLCAweDA5N0YsICJEZXZhbmFnYXJpIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suREVWQU5BR0FSSQorICAgICAgICAgICAgLyogMDk4MDsgMDlGRjsgQmVuZ2FsaSAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDA5ODAsIDB4MDlGRiwgIkJlbmdhbGkiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5CRU5HQUxJCisgICAgICAgICAgICAvKiAwQTAwOyAwQTdGOyBHdXJtdWtoaSAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDBBMDAsIDB4MEE3RiwgIkd1cm11a2hpIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suR1VSTVVLSEkKKyAgICAgICAgICAgIC8qIDBBODA7IDBBRkY7IEd1amFyYXRpICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MEE4MCwgMHgwQUZGLCAiR3VqYXJhdGkiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5HVUpBUkFUSQorICAgICAgICAgICAgLyogMEIwMDsgMEI3RjsgT3JpeWEgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgwQjAwLCAweDBCN0YsICJPcml5YSIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLk9SSVlBCisgICAgICAgICAgICAvKiAwQjgwOyAwQkZGOyBUYW1pbCAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDBCODAsIDB4MEJGRiwgIlRhbWlsIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suVEFNSUwKKyAgICAgICAgICAgIC8qIDBDMDA7IDBDN0Y7IFRlbHVndSAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDBDMDAsIDB4MEM3RiwgIlRlbHVndSIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLlRFTFVHVQorICAgICAgICAgICAgLyogMEM4MDsgMENGRjsgS2FubmFkYSAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDBDODAsIDB4MENGRiwgIkthbm5hZGEiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5LQU5OQURBCisgICAgICAgICAgICAvKiAwRDAwOyAwRDdGOyBNYWxheWFsYW0gKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgwRDAwLCAweDBEN0YsICJNYWxheWFsYW0iKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5NQUxBWUFMQU0KKyAgICAgICAgICAgIC8qIDBEODA7IDBERkY7IFNpbmhhbGEgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgwRDgwLCAweDBERkYsICJTaW5oYWxhIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suU0lOSEFMQQorICAgICAgICAgICAgLyogMEUwMDsgMEU3RjsgVGhhaSAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDBFMDAsIDB4MEU3RiwgIlRoYWkiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5USEFJCisgICAgICAgICAgICAvKiAwRTgwOyAwRUZGOyBMYW8gKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgwRTgwLCAweDBFRkYsICJMYW8iKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5MQU8KKyAgICAgICAgICAgIC8qIDBGMDA7IDBGRkY7IFRpYmV0YW4gKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgwRjAwLCAweDBGRkYsICJUaWJldGFuIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suVElCRVRBTgorICAgICAgICAgICAgLyogMTAwMDsgMTA5RjsgTXlhbm1hciAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDEwMDAsIDB4MTA5RiwgIk15YW5tYXIiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5NWUFOTUFSCisgICAgICAgICAgICAvKiAxMEEwOyAxMEZGOyBHZW9yZ2lhbiAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDEwQTAsIDB4MTBGRiwgIkdlb3JnaWFuIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suR0VPUkdJQU4KKyAgICAgICAgICAgIC8qIDExMDA7IDExRkY7IEhhbmd1bCBKYW1vICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MTEwMCwgMHgxMUZGLCAiSGFuZ3VsSmFtbyIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkhBTkdVTF9KQU1PCisgICAgICAgICAgICAvKiAxMjAwOyAxMzdGOyBFdGhpb3BpYyAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDEyMDAsIDB4MTM3RiwgIkV0aGlvcGljIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suRVRISU9QSUMKKyAgICAgICAgICAgIC8qIDEzQTA7IDEzRkY7IENoZXJva2VlICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MTNBMCwgMHgxM0ZGLCAiQ2hlcm9rZWUiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5DSEVST0tFRQorICAgICAgICAgICAgLyogMTQwMDsgMTY3RjsgVW5pZmllZCBDYW5hZGlhbiBBYm9yaWdpbmFsIFN5bGxhYmljcyAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDE0MDAsIDB4MTY3RiwgIlVuaWZpZWRDYW5hZGlhbkFib3JpZ2luYWxTeWxsYWJpY3MiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5VTklGSUVEX0NBTkFESUFOX0FCT1JJR0lOQUxfU1lMTEFCSUNTCisgICAgICAgICAgICAvKiAxNjgwOyAxNjlGOyBPZ2hhbSAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDE2ODAsIDB4MTY5RiwgIk9naGFtIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suT0dIQU0KKyAgICAgICAgICAgIC8qIDE2QTA7IDE2RkY7IFJ1bmljICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MTZBMCwgMHgxNkZGLCAiUnVuaWMiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5SVU5JQworICAgICAgICAgICAgLyogMTc4MDsgMTdGRjsgS2htZXIgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgxNzgwLCAweDE3RkYsICJLaG1lciIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLktITUVSCisgICAgICAgICAgICAvKiAxODAwOyAxOEFGOyBNb25nb2xpYW4gKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgxODAwLCAweDE4QUYsICJNb25nb2xpYW4iKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5NT05HT0xJQU4KKyAgICAgICAgICAgIC8qIDFFMDA7IDFFRkY7IExhdGluIEV4dGVuZGVkIEFkZGl0aW9uYWwgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgxRTAwLCAweDFFRkYsICJMYXRpbkV4dGVuZGVkQWRkaXRpb25hbCIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkxBVElOX0VYVEVOREVEX0FERElUSU9OQUwKKyAgICAgICAgICAgIC8qIDFGMDA7IDFGRkY7IEdyZWVrIEV4dGVuZGVkICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MUYwMCwgMHgxRkZGLCAiR3JlZWtFeHRlbmRlZCIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkdSRUVLX0VYVEVOREVECisgICAgICAgICAgICAvKiAyMDAwOyAyMDZGOyBHZW5lcmFsIFB1bmN0dWF0aW9uICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MjAwMCwgMHgyMDZGLCAiR2VuZXJhbFB1bmN0dWF0aW9uIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suR0VORVJBTF9QVU5DVFVBVElPTgorICAgICAgICAgICAgLyogMjA3MDsgMjA5RjsgU3VwZXJzY3JpcHRzIGFuZCBTdWJzY3JpcHRzICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MjA3MCwgMHgyMDlGLCAiU3VwZXJzY3JpcHRzYW5kU3Vic2NyaXB0cyIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLlNVUEVSU0NSSVBUU19BTkRfU1VCU0NSSVBUUworICAgICAgICAgICAgLyogMjBBMDsgMjBDRjsgQ3VycmVuY3kgU3ltYm9scyAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDIwQTAsIDB4MjBDRiwgIkN1cnJlbmN5U3ltYm9scyIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkNVUlJFTkNZX1NZTUJPTFMKKyAgICAgICAgICAgIC8qIDIwRDA7IDIwRkY7IENvbWJpbmluZyBNYXJrcyBmb3IgU3ltYm9scyAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDIwRDAsIDB4MjBGRiwgIkNvbWJpbmluZ01hcmtzZm9yU3ltYm9scyIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkNPTUJJTklOR19NQVJLU19GT1JfU1lNQk9MUworICAgICAgICAgICAgLyogMjEwMDsgMjE0RjsgTGV0dGVybGlrZSBTeW1ib2xzICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MjEwMCwgMHgyMTRGLCAiTGV0dGVybGlrZVN5bWJvbHMiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5MRVRURVJMSUtFX1NZTUJPTFMKKyAgICAgICAgICAgIC8qIDIxNTA7IDIxOEY7IE51bWJlciBGb3JtcyAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDIxNTAsIDB4MjE4RiwgIk51bWJlckZvcm1zIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suTlVNQkVSX0ZPUk1TCisgICAgICAgICAgICAvKiAyMTkwOyAyMUZGOyBBcnJvd3MgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgyMTkwLCAweDIxRkYsICJBcnJvd3MiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5BUlJPV1MKKyAgICAgICAgICAgIC8qIDIyMDA7IDIyRkY7IE1hdGhlbWF0aWNhbCBPcGVyYXRvcnMgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgyMjAwLCAweDIyRkYsICJNYXRoZW1hdGljYWxPcGVyYXRvcnMiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5NQVRIRU1BVElDQUxfT1BFUkFUT1JTCisgICAgICAgICAgICAvKiAyMzAwOyAyM0ZGOyBNaXNjZWxsYW5lb3VzIFRlY2huaWNhbCAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDIzMDAsIDB4MjNGRiwgIk1pc2NlbGxhbmVvdXNUZWNobmljYWwiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5NSVNDRUxMQU5FT1VTX1RFQ0hOSUNBTAorICAgICAgICAgICAgLyogMjQwMDsgMjQzRjsgQ29udHJvbCBQaWN0dXJlcyAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDI0MDAsIDB4MjQzRiwgIkNvbnRyb2xQaWN0dXJlcyIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkNPTlRST0xfUElDVFVSRVMKKyAgICAgICAgICAgIC8qIDI0NDA7IDI0NUY7IE9wdGljYWwgQ2hhcmFjdGVyIFJlY29nbml0aW9uICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MjQ0MCwgMHgyNDVGLCAiT3B0aWNhbENoYXJhY3RlclJlY29nbml0aW9uIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suT1BUSUNBTF9DSEFSQUNURVJfUkVDT0dOSVRJT04KKyAgICAgICAgICAgIC8qIDI0NjA7IDI0RkY7IEVuY2xvc2VkIEFscGhhbnVtZXJpY3MgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgyNDYwLCAweDI0RkYsICJFbmNsb3NlZEFscGhhbnVtZXJpY3MiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5FTkNMT1NFRF9BTFBIQU5VTUVSSUNTCisgICAgICAgICAgICAvKiAyNTAwOyAyNTdGOyBCb3ggRHJhd2luZyAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDI1MDAsIDB4MjU3RiwgIkJveERyYXdpbmciKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5CT1hfRFJBV0lORworICAgICAgICAgICAgLyogMjU4MDsgMjU5RjsgQmxvY2sgRWxlbWVudHMgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgyNTgwLCAweDI1OUYsICJCbG9ja0VsZW1lbnRzIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suQkxPQ0tfRUxFTUVOVFMKKyAgICAgICAgICAgIC8qIDI1QTA7IDI1RkY7IEdlb21ldHJpYyBTaGFwZXMgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgyNUEwLCAweDI1RkYsICJHZW9tZXRyaWNTaGFwZXMiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5HRU9NRVRSSUNfU0hBUEVTCisgICAgICAgICAgICAvKiAyNjAwOyAyNkZGOyBNaXNjZWxsYW5lb3VzIFN5bWJvbHMgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgyNjAwLCAweDI2RkYsICJNaXNjZWxsYW5lb3VzU3ltYm9scyIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLk1JU0NFTExBTkVPVVNfU1lNQk9MUworICAgICAgICAgICAgLyogMjcwMDsgMjdCRjsgRGluZ2JhdHMgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgyNzAwLCAweDI3QkYsICJEaW5nYmF0cyIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkRJTkdCQVRTCisgICAgICAgICAgICAvKiAyODAwOyAyOEZGOyBCcmFpbGxlIFBhdHRlcm5zICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MjgwMCwgMHgyOEZGLCAiQnJhaWxsZVBhdHRlcm5zIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suQlJBSUxMRV9QQVRURVJOUworICAgICAgICAgICAgLyogMkU4MDsgMkVGRjsgQ0pLIFJhZGljYWxzIFN1cHBsZW1lbnQgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgyRTgwLCAweDJFRkYsICJDSktSYWRpY2Fsc1N1cHBsZW1lbnQiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5DSktfUkFESUNBTFNfU1VQUExFTUVOVAorICAgICAgICAgICAgLyogMkYwMDsgMkZERjsgS2FuZ3hpIFJhZGljYWxzICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MkYwMCwgMHgyRkRGLCAiS2FuZ3hpUmFkaWNhbHMiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5LQU5HWElfUkFESUNBTFMKKyAgICAgICAgICAgIC8qIDJGRjA7IDJGRkY7IElkZW9ncmFwaGljIERlc2NyaXB0aW9uIENoYXJhY3RlcnMgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgyRkYwLCAweDJGRkYsICJJZGVvZ3JhcGhpY0Rlc2NyaXB0aW9uQ2hhcmFjdGVycyIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLklERU9HUkFQSElDX0RFU0NSSVBUSU9OX0NIQVJBQ1RFUlMKKyAgICAgICAgICAgIC8qIDMwMDA7IDMwM0Y7IENKSyBTeW1ib2xzIGFuZCBQdW5jdHVhdGlvbiAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDMwMDAsIDB4MzAzRiwgIkNKS1N5bWJvbHNhbmRQdW5jdHVhdGlvbiIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkNKS19TWU1CT0xTX0FORF9QVU5DVFVBVElPTgorICAgICAgICAgICAgLyogMzA0MDsgMzA5RjsgSGlyYWdhbmEgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHgzMDQwLCAweDMwOUYsICJIaXJhZ2FuYSIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkhJUkFHQU5BCisgICAgICAgICAgICAvKiAzMEEwOyAzMEZGOyBLYXRha2FuYSAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDMwQTAsIDB4MzBGRiwgIkthdGFrYW5hIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suS0FUQUtBTkEKKyAgICAgICAgICAgIC8qIDMxMDA7IDMxMkY7IEJvcG9tb2ZvICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MzEwMCwgMHgzMTJGLCAiQm9wb21vZm8iKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5CT1BPTU9GTworICAgICAgICAgICAgLyogMzEzMDsgMzE4RjsgSGFuZ3VsIENvbXBhdGliaWxpdHkgSmFtbyAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDMxMzAsIDB4MzE4RiwgIkhhbmd1bENvbXBhdGliaWxpdHlKYW1vIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suSEFOR1VMX0NPTVBBVElCSUxJVFlfSkFNTworICAgICAgICAgICAgLyogMzE5MDsgMzE5RjsgS2FuYnVuICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MzE5MCwgMHgzMTlGLCAiS2FuYnVuIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suS0FOQlVOCisgICAgICAgICAgICAvKiAzMUEwOyAzMUJGOyBCb3BvbW9mbyBFeHRlbmRlZCAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDMxQTAsIDB4MzFCRiwgIkJvcG9tb2ZvRXh0ZW5kZWQiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5CT1BPTU9GT19FWFRFTkRFRAorICAgICAgICAgICAgLyogMzIwMDsgMzJGRjsgRW5jbG9zZWQgQ0pLIExldHRlcnMgYW5kIE1vbnRocyAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweDMyMDAsIDB4MzJGRiwgIkVuY2xvc2VkQ0pLTGV0dGVyc2FuZE1vbnRocyIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkVOQ0xPU0VEX0NKS19MRVRURVJTX0FORF9NT05USFMKKyAgICAgICAgICAgIC8qIDMzMDA7IDMzRkY7IENKSyBDb21wYXRpYmlsaXR5ICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4MzMwMCwgMHgzM0ZGLCAiQ0pLQ29tcGF0aWJpbGl0eSIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkNKS19DT01QQVRJQklMSVRZCisgICAgICAgICAgICAvKiAzNDAwOyA0REI1OyBDSksgVW5pZmllZCBJZGVvZ3JhcGhzIEV4dGVuc2lvbiBBICovCisvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQKKy8vIE1vZGlmaWVkIHRoaXMgdG8gcmVmbGVjdCBjdXJyZW50IFVuaWNvZGUgdGFibGVzIChvciBtYXliZSBpdCB3YXMgYSB0eXBvKQorICAgICAgICAgICAgbmV3IFVCSW5mbygweDM0MDAsIDB4NERCRiwgIkNKS1VuaWZpZWRJZGVvZ3JhcGhzRXh0ZW5zaW9uQSIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkNKS19VTklGSUVEX0lERU9HUkFQSFNfRVhURU5TSU9OX0EKKy8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgICAgIC8qIDRFMDA7IDlGRkY7IENKSyBVbmlmaWVkIElkZW9ncmFwaHMgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHg0RTAwLCAweDlGRkYsICJDSktVbmlmaWVkSWRlb2dyYXBocyIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkNKS19VTklGSUVEX0lERU9HUkFQSFMKKyAgICAgICAgICAgIC8qIEEwMDA7IEE0OEY7IFlpIFN5bGxhYmxlcyAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweEEwMDAsIDB4QTQ4RiwgIllpU3lsbGFibGVzIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suWUlfU1lMTEFCTEVTCisgICAgICAgICAgICAvKiBBNDkwOyBBNENGOyBZaSBSYWRpY2FscyAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweEE0OTAsIDB4QTRDRiwgIllpUmFkaWNhbHMiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5ZSV9SQURJQ0FMUworICAgICAgICAgICAgLyogQUMwMDsgRDdBMzsgSGFuZ3VsIFN5bGxhYmxlcyAqLworLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisvLyBNb2RpZmllZCB0aGlzIHRvIHJlZmxlY3QgY3VycmVudCBVbmljb2RlIHRhYmxlcyAob3IgbWF5YmUgaXQgd2FzIGEgdHlwbykKKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHhBQzAwLCAweEQ3QUYsICJIYW5ndWxTeWxsYWJsZXMiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5IQU5HVUxfU1lMTEFCTEVTCisvLyBFTkQgYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgICAgICAvKiBEODAwOyBEQjdGOyBIaWdoIFN1cnJvZ2F0ZXMgKi8KKyAgICAgICAgICAgIC8qIERCODA7IERCRkY7IEhpZ2ggUHJpdmF0ZSBVc2UgU3Vycm9nYXRlcyAqLworICAgICAgICAgICAgLyogREMwMDsgREZGRjsgTG93IFN1cnJvZ2F0ZXMgKi8KKyAgICAgICAgICAgIC8qIEUwMDA7IEY4RkY7IFByaXZhdGUgVXNlICovCisgICAgICAgICAgICAvKiBGOTAwOyBGQUZGOyBDSksgQ29tcGF0aWJpbGl0eSBJZGVvZ3JhcGhzICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4RjkwMCwgMHhGQUZGLCAiQ0pLQ29tcGF0aWJpbGl0eUlkZW9ncmFwaHMiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5DSktfQ09NUEFUSUJJTElUWV9JREVPR1JBUEhTCisgICAgICAgICAgICAvKiBGQjAwOyBGQjRGOyBBbHBoYWJldGljIFByZXNlbnRhdGlvbiBGb3JtcyAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweEZCMDAsIDB4RkI0RiwgIkFscGhhYmV0aWNQcmVzZW50YXRpb25Gb3JtcyIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkFMUEhBQkVUSUNfUFJFU0VOVEFUSU9OX0ZPUk1TCisgICAgICAgICAgICAvKiBGQjUwOyBGREZGOyBBcmFiaWMgUHJlc2VudGF0aW9uIEZvcm1zLUEgKi8KKyAgICAgICAgICAgIG5ldyBVQkluZm8oMHhGQjUwLCAweEZERkYsICJBcmFiaWNQcmVzZW50YXRpb25Gb3Jtcy1BIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suQVJBQklDX1BSRVNFTlRBVElPTl9GT1JNU19BCisgICAgICAgICAgICAvKiBGRTIwOyBGRTJGOyBDb21iaW5pbmcgSGFsZiBNYXJrcyAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweEZFMjAsIDB4RkUyRiwgIkNvbWJpbmluZ0hhbGZNYXJrcyIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkNPTUJJTklOR19IQUxGX01BUktTCisgICAgICAgICAgICAvKiBGRTMwOyBGRTRGOyBDSksgQ29tcGF0aWJpbGl0eSBGb3JtcyAqLworICAgICAgICAgICAgbmV3IFVCSW5mbygweEZFMzAsIDB4RkU0RiwgIkNKS0NvbXBhdGliaWxpdHlGb3JtcyIpLCAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLkNKS19DT01QQVRJQklMSVRZX0ZPUk1TCisgICAgICAgICAgICAvKiBGRTUwOyBGRTZGOyBTbWFsbCBGb3JtIFZhcmlhbnRzICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4RkU1MCwgMHhGRTZGLCAiU21hbGxGb3JtVmFyaWFudHMiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5TTUFMTF9GT1JNX1ZBUklBTlRTCisgICAgICAgICAgICAvKiBGRTcwOyBGRUZFOyBBcmFiaWMgUHJlc2VudGF0aW9uIEZvcm1zLUIgKi8KKyAgICAgICAgICAgIC8vIG5ldyBVQkluZm8gKDB4RkU3MCwweEZFRkUsIkluQXJhYmljUHJlc2VudGF0aW9uRm9ybXMtQiIpLCAvLworICAgICAgICAgICAgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5BUkFCSUNfUFJFU0VOVEFUSU9OX0ZPUk1TX0IKKyAgICAgICAgICAgIC8qIEZFRkY7IEZFRkY7IFNwZWNpYWxzICovCisvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQKKy8vIE1vZGlmaWVkIHRoaXMgdG8gcmVmbGVjdCBjdXJyZW50IFVuaWNvZGUgdGFibGVzIChvciBtYXliZSBpdCB3YXMgYSB0eXBvKQorLy8gRkVGRiBpcyBhY3R1YWxseSBzdGlsbCBBcmFiaWMgUHJlc2VudGF0aW9uIEZvcm1zIEIKKy8vICAgICAgICAgICAgbmV3IFVCSW5mbygweEZFRkYsIDB4RkVGRiwgIlNwZWNpYWxzIiksIC8vIENoYXJhY3Rlci5Vbmljb2RlQmxvY2suU1BFQ0lBTFMKKy8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgICAgIC8qIEZGMDA7IEZGRUY7IEhhbGZ3aWR0aCBhbmQgRnVsbHdpZHRoIEZvcm1zICovCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4RkYwMCwgMHhGRkVGLCAiSGFsZndpZHRoYW5kRnVsbHdpZHRoRm9ybXMiKSwgLy8gQ2hhcmFjdGVyLlVuaWNvZGVCbG9jay5IQUxGV0lEVEhfQU5EX0ZVTExXSURUSF9GT1JNUworICAgICAgICAgICAgLyogRkZGMDsgRkZGRDsgU3BlY2lhbHMgKi8KKyAgICAgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZAorLy8gTW9kaWZpZWQgdGhpcyB0byByZWZsZWN0IGN1cnJlbnQgVW5pY29kZSB0YWJsZXMgKG9yIG1heWJlIGl0IHdhcyBhIHR5cG8pCisgICAgICAgICAgICBuZXcgVUJJbmZvKDB4RkZGMCwgMHhGRkZGLCAiU3BlY2lhbHMiKSAvLyBDaGFyYWN0ZXIuVW5pY29kZUJsb2NrLlNQRUNJQUxTCisvLyBFTkQgYW5kcm9pZC1jaGFuZ2VkCisgICAgfTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvcmVnZXgvdGVzdHMvamF2YS91dGlsL3JlZ2V4L1BhdHRlcm5FcnJvclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvcmVnZXgvdGVzdHMvamF2YS91dGlsL3JlZ2V4L1BhdHRlcm5FcnJvclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZDJjM2FlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9yZWdleC90ZXN0cy9qYXZhL3V0aWwvcmVnZXgvUGF0dGVybkVycm9yVGVzdC5qYXZhCkBAIC0wLDAgKzEsODMgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnJlZ2V4LnRlc3RzLmphdmEudXRpbC5yZWdleDsKKworaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0IGJvdW5kYXJ5IGFuZCBlcnJvciBjb25kaXRpb25zIGluIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuCisgKgorICovCitwdWJsaWMgY2xhc3MgUGF0dGVybkVycm9yVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29tcGlsZUVycm9ycygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBudWxsIHJlZ2V4IHN0cmluZyAtIHNob3VsZCBnZXQgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFBhdHRlcm4uY29tcGlsZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisKKyAgICAgICAgLy8gZW1wdHkgcmVnZXggc3RyaW5nIC0gbm8gZXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24KKyAgICAgICAgUGF0dGVybi5jb21waWxlKCIiKTsKKworICAgICAgICAvLyBub3RlOiBpbnZhbGlkIHJlZ2V4IHN5bnRheCBjaGVja2VkIGluIFBhdHRlcm5TeW50YXhFeGNlcHRpb25UZXN0CisKKyAgICAgICAgLy8gZmxhZ3MgPSAwIHNob3VsZCByYWlzZSBubyBleGNlcHRpb24KKyAgICAgICAgaW50IGZsYWdzID0gMDsKKyAgICAgICAgUGF0dGVybi5jb21waWxlKCJmb28iLCBmbGFncyk7CisKKyAgICAgICAgLy8gY2hlY2sgdGhhdCBhbGwgdmFsaWQgZmxhZ3MgYWNjZXB0ZWQgd2l0aG91dCBleGNlcHRpb24KKyAgICAgICAgZmxhZ3MgfD0gUGF0dGVybi5VTklYX0xJTkVTOworICAgICAgICBmbGFncyB8PSBQYXR0ZXJuLkNBU0VfSU5TRU5TSVRJVkU7CisgICAgICAgIGZsYWdzIHw9IFBhdHRlcm4uTVVMVElMSU5FOworICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgLy8gV2UgZG9uJ3Qgc3VwcG9ydCB0aGF0IGZsYWcuCisgICAgICAgIC8vIGZsYWdzIHw9IFBhdHRlcm4uQ0FOT05fRVE7CisgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgZmxhZ3MgfD0gUGF0dGVybi5DT01NRU5UUzsKKyAgICAgICAgZmxhZ3MgfD0gUGF0dGVybi5ET1RBTEw7CisgICAgICAgIGZsYWdzIHw9IFBhdHRlcm4uVU5JQ09ERV9DQVNFOworICAgICAgICBQYXR0ZXJuLmNvbXBpbGUoImZvbyIsIGZsYWdzKTsKKworICAgICAgICAvLyBhZGQgaW52YWxpZCBmbGFncyAtIHNob3VsZCBnZXQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICAgIC8qCisgICAgICAgICAqIFRPRE86IEluY29uc2lzdGVuY3kgYmV0d2VlbiB0aGUgcmVmZXJlbmNlIEpESyBiZWhhdmlvdXIgYW5kIHNwZWMgLSBleGNlcHRpb24gaXMKKyAgICAgICAgICogbm90IHRocm93bgorICAgICAgICAgKi8KKyAgICAgICAgLyoKKyAgICAgICAgICogVmFsaWQgdGVzdCBpczoKKyAgICAgICAgICogZmxhZ3MgfD0gMHhGRkZGRkZGRjsKKyAgICAgICAgICogdHJ5IHsKKyAgICAgICAgICogICBQYXR0ZXJuLmNvbXBpbGUoImZvbyIsZmxhZ3MpOworICAgICAgICAgKiB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgKiAgIC8vIFRoaXMgaXMgdGhlIGV4cGVjdGVkIGV4Y2VwdGlvbgorICAgICAgICAgKiB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgKiAgIGZhaWwoKTsKKyAgICAgICAgICogfQorICAgICAgICAgKi8KKworICAgICAgICAvKiBXb3JrYXJvdW5kIHRlc3QgaXM6ICovCisgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICAvLyBXZSBkb24ndCBzdXBwb3J0IHRoYXQgZmxhZy4KKyAgICAgICAgZmxhZ3MgfD0gflBhdHRlcm4uQ0FOT05fRVE7CisgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgLy8gTm8gZXhjZXB0aW9uIGV4cGVjdGVkIHRvIG1hdGNoIGluY29ycmVjdCB0aGUgcmVmZXJlbmNlIGJlaGF2aW91cgorICAgICAgICBQYXR0ZXJuLmNvbXBpbGUoImZvbyIsIGZsYWdzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3JlZ2V4L3Rlc3RzL2phdmEvdXRpbC9yZWdleC9QYXR0ZXJuU3ludGF4RXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9yZWdleC90ZXN0cy9qYXZhL3V0aWwvcmVnZXgvUGF0dGVyblN5bnRheEV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMmQzNTk2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9yZWdleC90ZXN0cy9qYXZhL3V0aWwvcmVnZXgvUGF0dGVyblN5bnRheEV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDg1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkucmVnZXgudGVzdHMuamF2YS51dGlsLnJlZ2V4OworCitpbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm5TeW50YXhFeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXR0ZXJuU3ludGF4RXhjZXB0aW9uKCkgeworICAgICAgICAvLyBOb3JtYWwgY2FzZQorICAgICAgICBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGUgPSBuZXcgUGF0dGVyblN5bnRheEV4Y2VwdGlvbigiRm9vIiwgIkJhciIsIDApOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZvbyIsIGUuZ2V0RGVzY3JpcHRpb24oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQmFyIiwgZS5nZXRQYXR0ZXJuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZS5nZXRJbmRleCgpKTsKKworICAgICAgICBTdHJpbmcgcyA9IGUuZ2V0TWVzc2FnZSgpOworICAgICAgICBhc3NlcnRUcnVlKHMuY29udGFpbnMoIkZvbyIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzLmNvbnRhaW5zKCJCYXIiKSk7CisgICAgICAgIGFzc2VydFRydWUocy5jb250YWlucygiMCIpKTsKKworICAgICAgICAvLyBObyBkZXNjcmlwdGlvbiBzcGVjaWZpZWQKKyAgICAgICAgZSA9IG5ldyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uKG51bGwsICJCYXIiLCAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGUuZ2V0RGVzY3JpcHRpb24oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQmFyIiwgZS5nZXRQYXR0ZXJuKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZS5nZXRJbmRleCgpKTsKKworICAgICAgICBzID0gZS5nZXRNZXNzYWdlKCk7CisgICAgICAgIGFzc2VydEZhbHNlKHMuY29udGFpbnMoIkZvbyIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzLmNvbnRhaW5zKCJCYXIiKSk7CisgICAgICAgIGFzc2VydFRydWUocy5jb250YWlucygiMCIpKTsKKworICAgICAgICAvLyBObyBwYXR0ZXJuIHNwZWNpZmllZAorICAgICAgICBlID0gbmV3IFBhdHRlcm5TeW50YXhFeGNlcHRpb24oIkZvbyIsIG51bGwsIDApOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZvbyIsIGUuZ2V0RGVzY3JpcHRpb24oKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBlLmdldFBhdHRlcm4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBlLmdldEluZGV4KCkpOworCisgICAgICAgIHMgPSBlLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzLmNvbnRhaW5zKCJGb28iKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHMuY29udGFpbnMoIkJhciIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzLmNvbnRhaW5zKCIwIikpOworCisgICAgICAgIC8vIE5laXRoZXIgZGVzY3JpcHRpb24gbm9yIHBhdHRlcm4gc3BlY2lmaWVkCisgICAgICAgIGUgPSBuZXcgUGF0dGVyblN5bnRheEV4Y2VwdGlvbihudWxsLCBudWxsLCAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGUuZ2V0RGVzY3JpcHRpb24oKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBlLmdldFBhdHRlcm4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBlLmdldEluZGV4KCkpOworCisgICAgICAgIHMgPSBlLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uocy5jb250YWlucygiRm9vIikpOworICAgICAgICBhc3NlcnRGYWxzZShzLmNvbnRhaW5zKCJCYXIiKSk7CisgICAgICAgIGFzc2VydFRydWUocy5jb250YWlucygiMCIpKTsKKworICAgICAgICAvLyBObyBpbmRleCBzcGVjaWZpZWQKKyAgICAgICAgZSA9IG5ldyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uKCJGb28iLCAiQmFyIiwgLTEpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGUuZ2V0SW5kZXgoKSk7CisKKyAgICAgICAgcyA9IGUuZ2V0TWVzc2FnZSgpOworICAgICAgICBhc3NlcnRGYWxzZShzLmNvbnRhaW5zKCJeIikpOworCisgICAgICAgIC8vIE5vIHBhdHRlcm4sIGJ1dCBpbmRleCBzcGVjaWZpZWQKKyAgICAgICAgZSA9IG5ldyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uKCJGb28iLCBudWxsLCAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGUuZ2V0SW5kZXgoKSk7CisKKyAgICAgICAgcyA9IGUuZ2V0TWVzc2FnZSgpOworICAgICAgICBhc3NlcnRGYWxzZShzLmNvbnRhaW5zKCJeIikpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9yZWdleC90ZXN0cy9qYXZhL3V0aWwvcmVnZXgvUGF0dGVyblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvcmVnZXgvdGVzdHMvamF2YS91dGlsL3JlZ2V4L1BhdHRlcm5UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmZiZGY5ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvcmVnZXgvdGVzdHMvamF2YS91dGlsL3JlZ2V4L1BhdHRlcm5UZXN0LmphdmEKQEAgLTAsMCArMSwxNzc3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5yZWdleC50ZXN0cy5qYXZhLnV0aWwucmVnZXg7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguTWF0Y2hlcjsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVyblN5bnRheEV4Y2VwdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS50ZXN0ZnJhbWV3b3JrLnNlcmlhbGl6YXRpb24uU2VyaWFsaXphdGlvblRlc3Q7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnRlc3RmcmFtZXdvcmsuc2VyaWFsaXphdGlvbi5TZXJpYWxpemF0aW9uVGVzdC5TZXJpYWxpemFibGVBc3NlcnQ7CisKK3B1YmxpYyBjbGFzcyBQYXR0ZXJuVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBTdHJpbmdbXSB0ZXN0UGF0dGVybnMgPSB7CisgICAgICAgICAgICAiKGF8YikqYWJiIiwKKyAgICAgICAgICAgICIoMSoyKjMqNCopKjU2NyIsCisgICAgICAgICAgICAiKGF8YnxjfGQpKmFhYiIsCisgICAgICAgICAgICAiKDF8MnwzfDR8NXw2fDd8OHw5fDApKDF8MnwzfDR8NXw2fDd8OHw5fDApKiIsCisgICAgICAgICAgICAiKGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVopKiIsCisgICAgICAgICAgICAiKGF8YikqKGF8YikqQShhfGIpKmxpY2UuKiIsCisgICAgICAgICAgICAiKGF8YnxjfGR8ZXxmfGd8aHxpfGp8a3xsfG18bnxvfHB8cXxyfHN8dHx1fHZ8d3x4fHl8eikoYXxifGN8ZHxlfGZ8Z3xofCIKKyAgICAgICAgICAgICAgICAgICAgKyAiaXxqfGt8bHxtfG58b3xwfHF8cnxzfHR8dXx2fHd8eHx5fHopKigxfDJ8M3w0fDV8Nnw3fDh8OXwwKSp8d2hpbGV8Zm9yfHN0cnVjdHxpZnxkbyIsCisvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQKKy8vIFdlIGRvbid0IGhhdmUgY2Fub25pY2FsIGVxdWl2YWxlbmNlLgorLy8gICAgICAgICAgICAieCg/Yyl5IiwgIngoP2NjKXkiCisvLyAgICAgICAgICAgICJ4KD86Yyl5IgorLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorCisgICAgfTsKKworICAgIFN0cmluZ1tdIHRlc3RQYXR0ZXJuc0FsdCA9IHsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBBY2NvcmRpbmcgdG8gSmF2YURvYyAyIGFuZCAzIG9jdCBkaWdpdCBzZXF1ZW5jZXMgbGlrZSBcXG83MFxcbzM0NworICAgICAgICAgICAgICogc2hvdWxkIGJlIE9LLCBidXQgdGVzdCBpcyBmYWlsZWQgZm9yIHRoZW0KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgIlthYl1cXGJcXFxcbzVcXHhGOVxcdTFFN0JcXHRcXG5cXGZcXHJcXGFcXGVbeXpdIiwKKyAgICAgICAgICAgICJeXFxwe0xvd2VyfSpcXHB7VXBwZXJ9KlxccHtBU0NJSX0/XFxwe0FscGhhfT9cXHB7RGlnaXR9KlxccHtBbG51bX1cXHB7UHVuY3R9XFxwe0dyYXBofVxccHtQcmludH1cXHB7Qmxhbmt9XFxwe0NudHJsfVxccHtYRGlnaXR9XFxwe1NwYWNlfSIsCisgICAgICAgICAgICAiJFxccHtqYXZhTG93ZXJDYXNlfVxccHtqYXZhVXBwZXJDYXNlfVxccHtqYXZhV2hpdGVzcGFjZX1cXHB7amF2YU1pcnJvcmVkfSIsCisgICAgICAgICAgICAiXFxwe0luR3JlZWt9XFxwe0x1fVxccHtTY31cXFB7SW5HcmVla31bXFxwe0x9JiZbXlxccHtMdX1dXSIgfTsKKworICAgIFN0cmluZ1tdIHdyb25nVGVzdFBhdHRlcm5zID0geyAiXFxvOUEiLCAiXFxwe0xhd2VyfSIsICJcXHhHMCIgfTsKKworICAgIGZpbmFsIHN0YXRpYyBpbnRbXSBmbGFnc1NldCA9IHsgUGF0dGVybi5DQVNFX0lOU0VOU0lUSVZFLAorICAgICAgICAgICAgUGF0dGVybi5NVUxUSUxJTkUsIFBhdHRlcm4uRE9UQUxMLCBQYXR0ZXJuLlVOSUNPREVfQ0FTRQorICAgICAgICAgICAgLyogLCBQYXR0ZXJuLkNBTk9OX0VRICovIH07CisKKyAgICAvKgorICAgICAqIEJhc2VkIG9uIFJJIGltcGxlbmV0YXRpb24gZG9jdW1lbnRzLiBOZWVkIHRvIGNoZWNrIHRoaXMgc2V0IHJlZ2FyZGluZworICAgICAqIGFjdHVhbCBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKi8KKyAgICBmaW5hbCBzdGF0aWMgaW50W10gd3JvbmdGbGFnc1NldCA9IHsgMjU2LCA1MTIsIDEwMjQgfTsKKworICAgIGZpbmFsIHN0YXRpYyBpbnQgREVGQVVMVF9GTEFHUyA9IDA7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF0Y2hlcigpIHsKKyAgICAgICAgLy8gc29tZSB2ZXJ5IHNpbXBsZSB0ZXN0CisgICAgICAgIFBhdHRlcm4gcCA9IFBhdHRlcm4uY29tcGlsZSgiYSIpOworICAgICAgICBhc3NlcnROb3ROdWxsKHAubWF0Y2hlcigiYmNkZSIpKTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShwLm1hdGNoZXIoImEiKSwgcC5tYXRjaGVyKCJhIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTcGxpdENoYXJTZXF1ZW5jZWludCgpIHsKKyAgICAgICAgLy8gc3BsaXR0aW5nIENoYXJTZXF1ZW5jZSB3aGljaCBlbmRzIHdpdGggcGF0dGVybgorICAgICAgICAvLyBidWc2MTkzCisgICAgICAgIGFzc2VydEVxdWFscygiLCwiLnNwbGl0KCIsIiwgMykubGVuZ3RoLCAzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIsLCIuc3BsaXQoIiwiLCA0KS5sZW5ndGgsIDMpOworICAgICAgICAvLyBidWc2MTkzCisgICAgICAgIC8vIGJ1ZzUzOTEKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFBhdHRlcm4uY29tcGlsZSgibyIpLnNwbGl0KCJib286YW5kOmZvbyIsIDUpLmxlbmd0aCwgNSk7CisgICAgICAgIGFzc2VydEVxdWFscyhQYXR0ZXJuLmNvbXBpbGUoImIiKS5zcGxpdCgiYWIiLCAtMSkubGVuZ3RoLCAyKTsKKyAgICAgICAgLy8gYnVnNTM5MQorICAgICAgICBTdHJpbmcgc1tdOworICAgICAgICBQYXR0ZXJuIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgieCIpOworICAgICAgICBzID0gcGF0LnNwbGl0KCJ6eHg6enp6Onp4eCIsIDEwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMubGVuZ3RoLCA1KTsKKyAgICAgICAgcyA9IHBhdC5zcGxpdCgienh4Onp6ejp6eHgiLCAzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMubGVuZ3RoLCAzKTsKKyAgICAgICAgcyA9IHBhdC5zcGxpdCgienh4Onp6ejp6eHgiLCAtMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzLmxlbmd0aCwgNSk7CisgICAgICAgIHMgPSBwYXQuc3BsaXQoInp4eDp6eno6enh4IiwgMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhzLmxlbmd0aCwgMyk7CisgICAgICAgIC8vIG90aGVyIHNwbGl0dGluZworICAgICAgICAvLyBuZWdhdGl2ZSBsaW1pdAorICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoImIiKTsKKyAgICAgICAgcyA9IHBhdC5zcGxpdCgiYWJjY2JhZGZlYmIiLCAtMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzLmxlbmd0aCwgNSk7CisgICAgICAgIHMgPSBwYXQuc3BsaXQoIiIsIC0xKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMubGVuZ3RoLCAxKTsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKCIiKTsKKyAgICAgICAgcyA9IHBhdC5zcGxpdCgiIiwgLTEpOworICAgICAgICBhc3NlcnRFcXVhbHMocy5sZW5ndGgsIDEpOworICAgICAgICBzID0gcGF0LnNwbGl0KCJhYmNjYmFkZmUiLCAtMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzLmxlbmd0aCwgMTEpOworICAgICAgICAvLyB6ZXJvIGxpbWl0CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiYiIpOworICAgICAgICBzID0gcGF0LnNwbGl0KCJhYmNjYmFkZmViYiIsIDApOworICAgICAgICBhc3NlcnRFcXVhbHMocy5sZW5ndGgsIDMpOworICAgICAgICBzID0gcGF0LnNwbGl0KCIiLCAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMubGVuZ3RoLCAxKTsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKCIiKTsKKyAgICAgICAgcyA9IHBhdC5zcGxpdCgiIiwgMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhzLmxlbmd0aCwgMSk7CisgICAgICAgIHMgPSBwYXQuc3BsaXQoImFiY2NiYWRmZSIsIDApOworICAgICAgICBhc3NlcnRFcXVhbHMocy5sZW5ndGgsIDEwKTsKKyAgICAgICAgLy8gcG9zaXRpdmUgbGltaXQKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKCJiIik7CisgICAgICAgIHMgPSBwYXQuc3BsaXQoImFiY2NiYWRmZWJiIiwgMTIpOworICAgICAgICBhc3NlcnRFcXVhbHMocy5sZW5ndGgsIDUpOworICAgICAgICBzID0gcGF0LnNwbGl0KCIiLCA2KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMubGVuZ3RoLCAxKTsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKCIiKTsKKyAgICAgICAgcyA9IHBhdC5zcGxpdCgiIiwgMTEpOworICAgICAgICBhc3NlcnRFcXVhbHMocy5sZW5ndGgsIDEpOworICAgICAgICBzID0gcGF0LnNwbGl0KCJhYmNjYmFkZmUiLCAxNSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzLmxlbmd0aCwgMTEpOworCisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiYiIpOworICAgICAgICBzID0gcGF0LnNwbGl0KCJhYmNjYmFkZmViYiIsIDUpOworICAgICAgICBhc3NlcnRFcXVhbHMocy5sZW5ndGgsIDUpOworICAgICAgICBzID0gcGF0LnNwbGl0KCIiLCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMubGVuZ3RoLCAxKTsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKCIiKTsKKyAgICAgICAgcyA9IHBhdC5zcGxpdCgiIiwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzLmxlbmd0aCwgMSk7CisgICAgICAgIHMgPSBwYXQuc3BsaXQoImFiY2NiYWRmZSIsIDExKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMubGVuZ3RoLCAxMSk7CisKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKCJiIik7CisgICAgICAgIHMgPSBwYXQuc3BsaXQoImFiY2NiYWRmZWJiIiwgMyk7CisgICAgICAgIGFzc2VydEVxdWFscyhzLmxlbmd0aCwgMyk7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiIik7CisgICAgICAgIHMgPSBwYXQuc3BsaXQoImFiY2NiYWRmZSIsIDUpOworICAgICAgICBhc3NlcnRFcXVhbHMocy5sZW5ndGgsIDUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTcGxpdENoYXJTZXF1ZW5jZSgpIHsKKyAgICAgICAgU3RyaW5nIHNbXTsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoImIiKTsKKyAgICAgICAgcyA9IHBhdC5zcGxpdCgiYWJjY2JhZGZlYmIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMubGVuZ3RoLCAzKTsKKyAgICAgICAgcyA9IHBhdC5zcGxpdCgiIik7CisgICAgICAgIGFzc2VydEVxdWFscyhzLmxlbmd0aCwgMSk7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiIik7CisgICAgICAgIHMgPSBwYXQuc3BsaXQoIiIpOworICAgICAgICBhc3NlcnRFcXVhbHMocy5sZW5ndGgsIDEpOworICAgICAgICBzID0gcGF0LnNwbGl0KCJhYmNjYmFkZmUiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMubGVuZ3RoLCAxMCk7CisgICAgICAgIC8vIGJ1ZzY1NDQKKyAgICAgICAgU3RyaW5nIHMxID0gIiI7CisgICAgICAgIFN0cmluZ1tdIGFyciA9IHMxLnNwbGl0KCI6Iik7CisgICAgICAgIGFzc2VydEVxdWFscyhhcnIubGVuZ3RoLCAxKTsKKyAgICAgICAgLy8gYnVnNjU0NAorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXR0ZXJuKCkgeworICAgICAgICAvKiBQb3NpdGl2ZSBhc3NlcnRpb24gdGVzdC4gKi8KKyAgICAgICAgZm9yIChTdHJpbmcgYVBhdHRlcm4gOiB0ZXN0UGF0dGVybnMpIHsKKyAgICAgICAgICAgIFBhdHRlcm4gcCA9IFBhdHRlcm4uY29tcGlsZShhUGF0dGVybik7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUocC5wYXR0ZXJuKCkuZXF1YWxzKGFQYXR0ZXJuKSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29tcGlsZSgpIHsKKyAgICAgICAgLyogUG9zaXRpdmUgYXNzZXJ0aW9uIHRlc3QuICovCisgICAgICAgIGZvciAoU3RyaW5nIGFQYXR0ZXJuIDogdGVzdFBhdHRlcm5zKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFBhdHRlcm4gcCA9IFBhdHRlcm4uY29tcGlsZShhUGF0dGVybik7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKiBQb3NpdGl2ZSBhc3NlcnRpb24gdGVzdCB3aXRoIGFsdGVybmF0aXZlIHRlbXBsYXRlcy4gKi8KKyAgICAgICAgZm9yIChTdHJpbmcgYVBhdHRlcm4gOiB0ZXN0UGF0dGVybnNBbHQpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgUGF0dGVybiBwID0gUGF0dGVybi5jb21waWxlKGFQYXR0ZXJuKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qIE5lZ2F0aXZlIGFzc2VydGlvbiB0ZXN0LiAqLworICAgICAgICBmb3IgKFN0cmluZyBhUGF0dGVybiA6IHdyb25nVGVzdFBhdHRlcm5zKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFBhdHRlcm4gcCA9IFBhdHRlcm4uY29tcGlsZShhUGF0dGVybik7CisgICAgICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBpcyBleHBlY3RlZCIpOworICAgICAgICAgICAgfSBjYXRjaCAoUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBwc2UpIHsKKyAgICAgICAgICAgICAgICAvKiBPS0FZICovCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmxhZ3MoKSB7CisgICAgICAgIFN0cmluZyBiYXNlU3RyaW5nOworICAgICAgICBTdHJpbmcgdGVzdFN0cmluZzsKKyAgICAgICAgUGF0dGVybiBwYXQ7CisgICAgICAgIE1hdGNoZXIgbWF0OworCisgICAgICAgIGJhc2VTdHJpbmcgPSAiKCg/aSl8YilhIjsKKyAgICAgICAgdGVzdFN0cmluZyA9ICJBIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWF0Lm1hdGNoZXMoKSk7CisKKyAgICAgICAgYmFzZVN0cmluZyA9ICIoP2kpYXxiIjsKKyAgICAgICAgdGVzdFN0cmluZyA9ICJBIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBiYXNlU3RyaW5nID0gIig/aSlhfGIiOworICAgICAgICB0ZXN0U3RyaW5nID0gIkIiOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIGJhc2VTdHJpbmcgPSAiY3woP2kpYXxiIjsKKyAgICAgICAgdGVzdFN0cmluZyA9ICJCIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBiYXNlU3RyaW5nID0gIig/aSlhfCg/cyliIjsKKyAgICAgICAgdGVzdFN0cmluZyA9ICJCIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBiYXNlU3RyaW5nID0gIig/aSlhfCg/LWkpYiI7CisgICAgICAgIHRlc3RTdHJpbmcgPSAiQiI7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nKTsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydEZhbHNlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIGJhc2VTdHJpbmcgPSAiKD9pKWF8KD8taSljfGIiOworICAgICAgICB0ZXN0U3RyaW5nID0gIkIiOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRGYWxzZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBiYXNlU3RyaW5nID0gIig/aSlhfCg/LWkpY3woP2kpYiI7CisgICAgICAgIHRlc3RTdHJpbmcgPSAiQiI7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nKTsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisKKyAgICAgICAgYmFzZVN0cmluZyA9ICIoP2kpYXwoPy1pKWIiOworICAgICAgICB0ZXN0U3RyaW5nID0gIkEiOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIGJhc2VTdHJpbmcgPSAiKCg/aSkpYSI7CisgICAgICAgIHRlc3RTdHJpbmcgPSAiQSI7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nKTsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydEZhbHNlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIGJhc2VTdHJpbmcgPSAifCg/aSl8YSI7CisgICAgICAgIHRlc3RTdHJpbmcgPSAiQSI7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nKTsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisKKyAgICAgICAgYmFzZVN0cmluZyA9ICIoP2kpKCg/cylhLikiOworICAgICAgICB0ZXN0U3RyaW5nID0gIkFcbiI7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nKTsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisKKyAgICAgICAgYmFzZVN0cmluZyA9ICIoP2kpKCg/LWkpYSkiOworICAgICAgICB0ZXN0U3RyaW5nID0gIkEiOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRGYWxzZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBiYXNlU3RyaW5nID0gIig/aSkoP3M6YS4pIjsKKyAgICAgICAgdGVzdFN0cmluZyA9ICJBXG4iOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIGJhc2VTdHJpbmcgPSAiKD9pKWZnaCg/czphYSkiOworICAgICAgICB0ZXN0U3RyaW5nID0gImZnaEFBIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBiYXNlU3RyaW5nID0gIig/aSkoKD8taSkpYSI7CisgICAgICAgIHRlc3RTdHJpbmcgPSAiQSI7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nKTsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisKKyAgICAgICAgYmFzZVN0cmluZyA9ICJhYmMoP2kpZCI7CisgICAgICAgIHRlc3RTdHJpbmcgPSAiQUJDRCI7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nKTsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydEZhbHNlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIHRlc3RTdHJpbmcgPSAiYWJjRCI7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIGJhc2VTdHJpbmcgPSAiYSg/aSlhKD8taSlhKD9pKWEoPy1pKWEiOworICAgICAgICB0ZXN0U3RyaW5nID0gImFBYUFhIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICB0ZXN0U3RyaW5nID0gImFBQUFhIjsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydEZhbHNlKG1hdC5tYXRjaGVzKCkpOworICAgIH0KKworLy8gQkVHSU4gYW5kcm9pZC1yZW1vdmVkCisvLyBUaGUgZmxhZ3MoKSBtZXRob2Qgc2hvdWxkIG9ubHkgcmV0dXJuIHRob3NlIGZsYWdzIHRoYXQgd2VyZSBleHBsaWNpdGx5CisvLyBwYXNzZWQgZHVyaW5nIHRoZSBjb21waWxhdGlvbi4gVGhlIEpESyBhbHNvIGFjY2VwdHMgdGhlIG9uZXMgaW1wbGljaXRseQorLy8gY29udGFpbmVkIGluIHRoZSBwYXR0ZXJuLCBidXQgSUNVIGRvZXNuJ3QgZG8gdGhpcy4KKy8vCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0RmxhZ3NNZXRob2QoKSB7CisvLyAgICAgICAgU3RyaW5nIGJhc2VTdHJpbmc7CisvLyAgICAgICAgUGF0dGVybiBwYXQ7CisvLworLy8gICAgICAgIC8qCisvLyAgICAgICAgICogVGhlc2UgdGVzdHMgYXJlIGZvciBjb21wYXRpYmlsaXR5IHdpdGggUkkgb25seS4gTG9naWNhbGx5IHdlIGhhdmUgdG8KKy8vICAgICAgICAgKiByZXR1cm4gb25seSBmbGFncyBzcGVjaWZpZWQgZHVyaW5nIHRoZSBjb21waWxhdGlvbi4gRm9yIGV4YW1wbGUKKy8vICAgICAgICAgKiBwYXQuZmxhZ3MoKSA9PSAwIHdoZW4gd2UgY29tcGlsZSBQYXR0ZXJuIHBhdCA9CisvLyAgICAgICAgICogUGF0dGVybi5jb21waWxlKCIoP2kpYWJjKD8taSkiKTsgYnV0IHRoZSB3aG9sZSBleHByZXNzaW9uIGlzIGNvbXBpbGVkCisvLyAgICAgICAgICogaW4gYSBjYXNlIGluc2Vuc2l0aXZlIG1hbm5lci4gU28gdGhlcmUgaXMgbGl0dGxlIHNlbnNlIHRvIGRvIGNhbGxzIHRvCisvLyAgICAgICAgICogZmxhZ3MoKSBub3cuCisvLyAgICAgICAgICovCisvLyAgICAgICAgYmFzZVN0cmluZyA9ICIoPy1pKSI7CisvLyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworLy8KKy8vICAgICAgICBiYXNlU3RyaW5nID0gIig/aWRtc3V4KWFiYyg/LWkpdmcoPy1kbXUpIjsKKy8vICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZyk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKHBhdC5mbGFncygpLCBQYXR0ZXJuLkRPVEFMTCB8IFBhdHRlcm4uQ09NTUVOVFMpOworLy8KKy8vICAgICAgICBiYXNlU3RyaW5nID0gIig/aWRtc3V4KWFiY3woPy1pKXZnfCg/LWRtdSkiOworLy8gICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMocGF0LmZsYWdzKCksIFBhdHRlcm4uRE9UQUxMIHwgUGF0dGVybi5DT01NRU5UUyk7CisvLworLy8gICAgICAgIGJhc2VTdHJpbmcgPSAiKD9pcylhKCg/eCliLikiOworLy8gICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMocGF0LmZsYWdzKCksIFBhdHRlcm4uRE9UQUxMIHwgUGF0dGVybi5DQVNFX0lOU0VOU0lUSVZFKTsKKy8vCisvLyAgICAgICAgYmFzZVN0cmluZyA9ICIoP2kpYSgoPy1pKSkiOworLy8gICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMocGF0LmZsYWdzKCksIFBhdHRlcm4uQ0FTRV9JTlNFTlNJVElWRSk7CisvLworLy8gICAgICAgIGJhc2VTdHJpbmcgPSAiKCg/aSlhKSI7CisvLyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworLy8gICAgICAgIGFzc2VydEVxdWFscyhwYXQuZmxhZ3MoKSwgMCk7CisvLworLy8gICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiKD9pcylhYmMiKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMocGF0LmZsYWdzKCksIFBhdHRlcm4uQ0FTRV9JTlNFTlNJVElWRSB8IFBhdHRlcm4uRE9UQUxMKTsKKy8vICAgIH0KKy8vRU5EIGFuZHJvaWQtcmVtb3ZlZAorCisgICAgLyoKKyAgICAgKiBDaGVjayBkZWZhdWx0IGZsYWdzIHdoZW4gdGhleSBhcmUgbm90IHNwZWNpZmllZCBpbiBwYXR0ZXJuLiBCYXNlZCBvbiBSSQorICAgICAqIHNpbmNlIGNvdWxkIG5vdCBmaW5kIHRoYXQgaW5mbworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RGbGFnc0NvbXBpbGVEZWZhdWx0KCkgeworICAgICAgICBmb3IgKFN0cmluZyBwYXQgOiB0ZXN0UGF0dGVybnNBbHQpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgUGF0dGVybiBwID0gUGF0dGVybi5jb21waWxlKHBhdCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHAuZmxhZ3MoKSwgREVGQVVMVF9GTEFHUyk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIENoZWNrIHRoYXQgZmxhZ3Mgc3BlY2lmaWVkIGR1cmluZyBjb21waWxlIGFyZSBzZXQgcHJvcGVybHkgVGhpcyBpcyBhCisgICAgICogc2ltcGxlIGltcGxlbWVudGF0aW9uIHRoYXQgZG9lcyBub3QgdXNlIGZsYWdzIGNvbWJpbmF0aW9ucy4gTmVlZCB0bworICAgICAqIGltcHJvdmUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEZsYWdzQ29tcGlsZVZhbGlkKCkgeworICAgICAgICBmb3IgKFN0cmluZyBwYXQgOiB0ZXN0UGF0dGVybnNBbHQpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGZsYWdzIDogZmxhZ3NTZXQpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBQYXR0ZXJuIHAgPSBQYXR0ZXJuLmNvbXBpbGUocGF0LCBmbGFncyk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhwLmZsYWdzKCksIGZsYWdzKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb21waWxlU3RyaW5naW50KCkgeworICAgICAgICAvKgorICAgICAgICAgKiB0aGVzZSB0ZXN0cyBhcmUgbmVlZGVkIHRvIHZlcmlmeSB0aGF0IGFwcHJvcHJpYXRlIGV4Y2VwdGlvbnMgYXJlCisgICAgICAgICAqIHRocm93bgorICAgICAgICAgKi8KKyAgICAgICAgU3RyaW5nIHBhdHRlcm4gPSAiYilhIjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFBhdHRlcm4uY29tcGlsZShwYXR0ZXJuKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIGEgUGF0dGVyblN5bnRheEV4Y2VwdGlvbiB3aGVuIGNvbXBpbGluZyBwYXR0ZXJuOiAiCisgICAgICAgICAgICAgICAgICAgICsgcGF0dGVybik7CisgICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gcGFzcworICAgICAgICB9CisgICAgICAgIHBhdHRlcm4gPSAiYmNkZSlhIjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFBhdHRlcm4uY29tcGlsZShwYXR0ZXJuKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIGEgUGF0dGVyblN5bnRheEV4Y2VwdGlvbiB3aGVuIGNvbXBpbGluZyBwYXR0ZXJuOiAiCisgICAgICAgICAgICAgICAgICAgICsgcGF0dGVybik7CisgICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gcGFzcworICAgICAgICB9CisgICAgICAgIHBhdHRlcm4gPSAiYmJnKCkpYSI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQYXR0ZXJuIHBhdCA9IFBhdHRlcm4uY29tcGlsZShwYXR0ZXJuKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIGEgUGF0dGVyblN5bnRheEV4Y2VwdGlvbiB3aGVuIGNvbXBpbGluZyBwYXR0ZXJuOiAiCisgICAgICAgICAgICAgICAgICAgICsgcGF0dGVybik7CisgICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gcGFzcworICAgICAgICB9CisKKyAgICAgICAgcGF0dGVybiA9ICJjZGIoP2kpKWEiOworICAgICAgICB0cnkgeworICAgICAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUocGF0dGVybik7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBhIFBhdHRlcm5TeW50YXhFeGNlcHRpb24gd2hlbiBjb21waWxpbmcgcGF0dGVybjogIgorICAgICAgICAgICAgICAgICAgICArIHBhdHRlcm4pOworICAgICAgICB9IGNhdGNoIChQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIHBhc3MKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIFRoaXMgcGF0dGVybiBzaG91bGQgY29tcGlsZSAtIEhBUk1PTlktMjEyNworICAgICAgICAgKi8KKy8vICAgICAgICBwYXR0ZXJuID0gIngoP2MpeSI7CisvLyAgICAgICAgUGF0dGVybi5jb21waWxlKHBhdHRlcm4pOworCisgICAgICAgIC8qCisgICAgICAgICAqIHRoaXMgcGF0dGVybiBkb2Vzbid0IG1hdGNoIGFueSBzdHJpbmcsIGJ1dCBzaG91bGQgYmUgY29tcGlsZWQgYW55d2F5CisgICAgICAgICAqLworICAgICAgICBwYXR0ZXJuID0gIihiXFwxKWEiOworICAgICAgICBQYXR0ZXJuLmNvbXBpbGUocGF0dGVybik7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciBQYXR0ZXJuIGNvbXBpbGUoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RRdWFudENvbXBpbGVOZWcoKSB7CisgICAgICAgIFN0cmluZ1tdIHBhdHRlcm5zID0geyAiNXssMn0iLCAiezVhc2QiLCAie2hnZGhnIiwgIns1LGhqa2giLCAieyw1aGRzaCIsCisgICAgICAgICAgICAgICAgIns1LDNzaGRma2pofSIgfTsKKyAgICAgICAgZm9yIChTdHJpbmcgZWxlbWVudCA6IHBhdHRlcm5zKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFBhdHRlcm4uY29tcGlsZShlbGVtZW50KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIHdhcyBleHBlY3RlZCwgYnV0IGNvbXBpbGF0aW9uIHN1Y2NlZWRzIik7CisgICAgICAgICAgICB9IGNhdGNoIChQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIHBzZSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMTM2NQorLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisvLyBPcmlnaW5hbCByZWdleCBjb250YWluZWQgc29tZSBpbGxlZ2FsIHN0dWZmLiBDaGFuZ2VkIGl0IHNsaWdodGx5LAorLy8gd2hpbGUgbWFpbnRhaW5pbmcgdGhlIHdpY2tlZCBjaGFyYWN0ZXIgb2YgdGhpcyAibW90aGVyIG9mIGFsbAorLy8gcmVnZXhlcyIuCisvLyAgICAgICAgU3RyaW5nIHBhdHRlcm4gPSAiKD8hW15cXDxDXFxmXFwwMTQ2XFwwMjcwXFx9JiZbfFxcMDItXFx4M0VcXH18WC1cXHxdXXs3LH0rKVt8XFxcXFxceDk4XFw8XFw/XFx1NEZDRnJcXCxcXDAwMjVcXH1cXDAwNHxcXDAwMjUtXFwwNTJcMDYxXXwoPzwhW3xcXDAxLVxcdTgyOUVdKXwoPzwhXFxwe0FscGhhfSl8XnwoPy1zOlteXFx4MTVcXFxcXFx4MjRGXFxhXFwsXFxhXFx1OTdEOFtcXHgzOFxcYVtcXDAyMjQtXFwwMzA2W15cXDAwMjAtXFx1NkE1N11dXV0/PykoP3V4aXg6W158XFx7XFxbXFwwMzY3XFx0XFxlXFx4OENcXHtcXFtcXDA3NGNcXF1WW3xiXFxmdVxcclxcMDE3NVxcPFxcMDdmXFwwNjZzW15ELVxceDVEXV1dKSg/eHg6Xns1LH0rKSg/dXV1KSg/PV5cXEQpfCg/IVxcRykoPz5cXEcqPykoPyFbXnxcXF1cXDA3MFxcbmVcXHtcXHRcXFtcXDA1M1xcP1xcXFxcXHg1MVxcYVxcMDc1XFwwMDIzLVxcWyYmW3xcXDAyMi1cXHhFQVxcMDAtXFx1NDFDMiYmW158YS1cXHhDQyYmW15cXDAzN1xcdUVDQjNcXHUzRDlBXFx4MzFcXHxcXDxiXFwwMjA2XFx1RjJFQ1xcMDFtXFwsXFxha1xcYVxcMDMmJlxccHtQdW5jdH1dXV1dKSg/LWR4czpbfFxcMDYtXFwwN3xcXGUtXFx4NjMmJlt8VHBcXHUxOEEzXFwwMFxcfFxceEU0XFwwNVxcMDYxXFwwMTVcXDAxMTZDfFxcclxce1xcfVxcMDA2XFx4RUFcXDAzNjdcXHhDNFxcMDFcXDAwNDJcXDAyNjdcXHhCQlxcMDFUXFx9XFwwMTAwXFw/W3xcXFstXFx1NDU5QnxcXHgyM1xceDkxXFxyRlxcMDM3Nlt8XFw/LVxceDk0XFwwMTEzLVxcXFxcXHNdXV1dezZ9PykoPzw9W15cXHQtXFx4NDJIXFwwNFxcZlxcMDNcXDAxNzJcXD9pXFx1OTdCNlxcZVxcZlxcdURBQzJdKSg/PVxcQiorKSg/PlteXFwwMTZcXHJcXHtcXCxcXHVBMjlEXFwwMzRcXDAyW1xcMDItXFxbfFxcdFxcMDU2XFx1RjU5OVxceDYyXFxlXFw8XFwwMzJcXHVGMEFDXFwwMDI2XFwwMjA1UVxcfFxcXFxcXDA2XFwwMTY0W3xcXDA1Ny1cXHU3QTk4JiZbXFwwNjEtZ3xcXHxcXDAyNzZcXG5cXDA0MlxcMDExXFxlXFx4RThcXHg2NEJcXDA0XFx1NkQwRURXXlxccHtMb3dlcn1dXV1dPykoPzw9W15cXG5cXFxcXFx0XFx1OEUxM1xcLFxcMDExNFxcdTY1NkVcXHhBNVxcXSYmW1xcMDMtXFwwMjZ8XFx1RjM5RFxcMDFcXHtpXFx1M0JDMlxcdTE0RkVdXSkoPzw9W158XFx1QUU2MlxcMDU0SFxcfFxcfSYmXlxccHtTcGFjZX1dKSg/c3h4KSg/PD1bXFxmXFwwMDZcXGFcXHJcXHhCNF0qKyl8KD94LXhkOl57NX0rKSgpIjsKKyAgICAgICAgU3RyaW5nIHBhdHRlcm4gPSAiKD8hW15cXDxDXFxmXFwwMTQ2XFwwMjcwXFx9JiZbfFxcMDItXFx4M0VcXH18WC1cXHxdXXs3LH0rKVt8XFxcXFxceDk4XFw8XFw/XFx1NEZDRnJcXCxcXDAwMjVcXH1cXDAwNHxcXDAwMjUtXFwwNTJcMDYxXXwoPzwhW3xcXDAxLVxcdTgyOUVdKXwoPzwhXFxwe0FscGhhfSl8XnwoPy1zOlteXFx4MTVcXFxcXFx4MjRGXFxhXFwsXFxhXFx1OTdEOFtcXHgzOFxcYVtcXDAyMjQtXFwwMzA2W15cXDAwMjAtXFx1NkE1N11dXV0/PykoP3V4aXg6W158XFx7XFxbXFwwMzY3XFx0XFxlXFx4OENcXHtcXFtcXDA3NGNcXF1WW3xiXFxmdVxcclxcMDE3NVxcPFxcMDdmXFwwNjZzW15ELVxceDVEXV1dKSg/eHg6Xns1LH0rKSg/dXV1KSg/PV5cXEQpfCg/IVxcRykoPz5cXC4qPykoPyFbXnxcXF1cXDA3MFxcbmVcXHtcXHRcXFtcXDA1M1xcP1xcXFxcXHg1MVxcYVxcMDc1XFwwMDIzLVxcWyYmW3xcXDAyMi1cXHhFQVxcMDAtXFx1NDFDMiYmW158YS1cXHhDQyYmW15cXDAzN1xcdUVDQjNcXHUzRDlBXFx4MzFcXHxcXDxiXFwwMjA2XFx1RjJFQ1xcMDFtXFwsXFxha1xcYVxcMDMmJlxccHtQdW5jdH1dXV1dKSg/LWR4czpbfFxcMDYtXFwwN3xcXGUtXFx4NjMmJlt8VHBcXHUxOEEzXFwwMFxcfFxceEU0XFwwNVxcMDYxXFwwMTVcXDAxMTZDfFxcclxce1xcfVxcMDA2XFx4RUFcXDAzNjdcXHhDNFxcMDFcXDAwNDJcXDAyNjdcXHhCQlxcMDFUXFx9XFwwMTAwXFw/W3xcXFstXFx1NDU5QnxcXHgyM1xceDkxXFxyRlxcMDM3Nlt8XFw/LVxceDk0XFwwMTEzLVxcXFxcXHNdXV1dezZ9PykoPzw9W15cXHQtXFx4NDJIXFwwNFxcZlxcMDNcXDAxNzJcXD9pXFx1OTdCNlxcZVxcZlxcdURBQzJdKSg/PVxcLiorKSg/PlteXFwwMTZcXHJcXHtcXCxcXHVBMjlEXFwwMzRcXDAyW1xcMDItXFxbfFxcdFxcMDU2XFx1RjU5OVxceDYyXFxlXFw8XFwwMzJcXHVGMEFDXFwwMDI2XFwwMjA1UVxcfFxcXFxcXDA2XFwwMTY0W3xcXDA1Ny1cXHU3QTk4JiZbXFwwNjEtZ3xcXHxcXDAyNzZcXG5cXDA0MlxcMDExXFxlXFx4RThcXHg2NEJcXDA0XFx1NkQwRURXXlxccHtMb3dlcn1dXV1dPykoPzw9W15cXG5cXFxcXFx0XFx1OEUxM1xcLFxcMDExNFxcdTY1NkVcXHhBNVxcXSYmW1xcMDMtXFwwMjZ8XFx1RjM5RFxcMDFcXHtpXFx1M0JDMlxcdTE0RkVdXSkoPzw9W158XFx1QUU2MlxcMDU0SFxcfFxcfSYmXlxccHtTcGFjZX1dKSg/c3h4KSg/PD1bXFxmXFwwMDZcXGFcXHJcXHhCNF17MSw1fSl8KD94LXhkOl57NX0rKSgpIjsKKy8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChQYXR0ZXJuLmNvbXBpbGUocGF0dGVybikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RRdWFudENvbXBpbGVQb3MoKSB7CisgICAgICAgIFN0cmluZ1tdIHBhdHRlcm5zID0gey8qICIoYWJjKXsxLDN9IiwgKi8iYWJjezIsfSIsICJhYmN7NX0iIH07CisgICAgICAgIGZvciAoU3RyaW5nIGVsZW1lbnQgOiBwYXR0ZXJucykgeworICAgICAgICAgICAgUGF0dGVybi5jb21waWxlKGVsZW1lbnQpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFF1YW50Q29tcG9zaXRpb24oKSB7CisgICAgICAgIFN0cmluZyBwYXR0ZXJuID0gIihhezEsM30pYWFiIjsKKyAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gcGF0ID0gamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZShwYXR0ZXJuKTsKKyAgICAgICAgamF2YS51dGlsLnJlZ2V4Lk1hdGNoZXIgbWF0ID0gcGF0Lm1hdGNoZXIoImFhYWIiKTsKKyAgICAgICAgbWF0Lm1hdGNoZXMoKTsKKyAgICAgICAgbWF0LnN0YXJ0KDEpOworICAgICAgICBtYXQuZ3JvdXAoMSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1hdGNoZXMoKSB7CisgICAgICAgIFN0cmluZ1tdW10gcG9zU2VxID0geworICAgICAgICAgICAgICAgIHsgImFiYiIsICJhYmFiYiIsICJhYmFiYWJiYWJhYmIiLCAiYWJhYmFiYmFiYWJiYWJhYmFiYmJiYmFiYiIgfSwKKyAgICAgICAgICAgICAgICB7ICIyMTM1NjciLCAiMTIzMjQ1NjciLCAiMTIzNDU2NyIsICIyMTMyMTM1NjciLAorICAgICAgICAgICAgICAgICAgICAgICAgIjIxMzEyMzEyMzEyNTY3IiwgIjQ0NDQ0NDU2NyIgfSwKKyAgICAgICAgICAgICAgICB7ICJhYmNkYWFiIiwgImFhYiIsICJhYmFhYiIsICJjZGFhYiIsICJhY2JkYWRjYmFhYiIgfSwKKyAgICAgICAgICAgICAgICB7ICIyMTMyMzQ1NjciLCAiMzQ1OCIsICIwOTg3NjU0IiwgIjc2ODk1NDY0MzIiLCAiMDM5ODU3NiIsCisgICAgICAgICAgICAgICAgICAgICAgICAiOTg0MzIiLCAiNSIgfSwKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgICAiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiIsCisgICAgICAgICAgICAgICAgICAgICAgICAiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiIgfSwKKyAgICAgICAgICAgICAgICB7ICJhYmFiYmFBYWJhYmFiYmxpY2UiLCAiYWJhYmJhQWxpY2VhYmFiYWIiLCAiYWJhYmJBYWJsaWNlYWFhIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJhYmJiQWJiYmxpY2VhYWEiLCAiQWxpY2UiIH0sCisgICAgICAgICAgICAgICAgeyAiYTEyMyIsICJibnhudmdkczE1NiIsICJmb3IiLCAid2hpbGUiLCAiaWYiLCAic3RydWN0IiB9LAorICAgICAgICAgICAgICAgIHsgInh5IiB9LCB7ICJ4eSIgfSwgeyAieGN5IiB9CisKKyAgICAgICAgfTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRlc3RQYXR0ZXJucy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBwb3NTZXFbaV0ubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgbWF0Y2g6ICIgKyB0ZXN0UGF0dGVybnNbaV0gKyAiIHZzICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgcG9zU2VxW2ldW2pdLCBQYXR0ZXJuLm1hdGNoZXModGVzdFBhdHRlcm5zW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgcG9zU2VxW2ldW2pdKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF0Y2hlc0V4Y2VwdGlvbigpIHsKKyAgICAgICAgLyogTmVnYXRpdmUgYXNzZXJ0aW9uIHRlc3QuICovCisgICAgICAgIGZvciAoU3RyaW5nIGFQYXR0ZXJuIDogd3JvbmdUZXN0UGF0dGVybnMpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgUGF0dGVybi5tYXRjaGVzKGFQYXR0ZXJuLCAiRm9vIik7CisgICAgICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBpcyBleHBlY3RlZCIpOworICAgICAgICAgICAgfSBjYXRjaCAoUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBwc2UpIHsKKyAgICAgICAgICAgICAgICAvKiBPS0FZICovCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VGltZVpvbmVJc3N1ZSgpIHsKKyAgICAgICAgUGF0dGVybiBwID0gUGF0dGVybi5jb21waWxlKCJHTVQoXFwrfFxcLSkoXFxkKykoOihcXGQrKSk/Iik7CisgICAgICAgIE1hdGNoZXIgbSA9IHAubWF0Y2hlcigiR01ULTk6NDUiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtLm1hdGNoZXMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLSIsIG0uZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjkiLCBtLmdyb3VwKDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI6NDUiLCBtLmdyb3VwKDMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI0NSIsIG0uZ3JvdXAoNCkpOworICAgIH0KKworLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisvLyBSZW1vdmVkIG9uZSBwYXR0ZXJuIHRoYXQgaXMgYnVnZ3kgb24gdGhlIEpESy4gV2UgZG9uJ3Qgd2FudCB0byBkdXBsaWNhdGUgdGhhdC4KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29tcGlsZVJhbmdlcygpIHsKKyAgICAgICAgU3RyaW5nW10gY29ycmVjdFRlc3RQYXR0ZXJucyA9IHsgIlteXSphYmJdKiIsIC8qICJbXmEtZFtebS1wXV0qYWJiIiwgKi8KKyAgICAgICAgICAgICAgICAiW2EtZFxcZF0qYWJiIiwgIlthYmNdKmFiYiIsICJbYS1lJiZbZGVdXSphYmIiLCAiW15hYmNdKmFiYiIsCisgICAgICAgICAgICAgICAgIlthLWUmJlteZGVdXSphYmIiLCAiW2EteiYmW15tLXBdXSphYmIiLCAiW2EtZFttLXBdXSphYmIiLAorICAgICAgICAgICAgICAgICJbYS16QS1aXSphYmIiLCAiWysqP10qYWJiIiwgIlteKyo/XSphYmIiIH07CisKKyAgICAgICAgU3RyaW5nW10gaW5wdXRTZWN1ZW5jZSA9IHsgImtra2siLCAvKiAiYWRtcGFiYiIsICovICJhYmNhYmNkMTI0NjU0YWJiIiwKKyAgICAgICAgICAgICAgICAiYWJjYWJjY2JhY2FiYWJiIiwgImRlZGVkZWRlZGVkZWRlZWRhYmIiLCAiZ2ZkaGZnaGdkZmdoYWJiIiwKKyAgICAgICAgICAgICAgICAiYWNjYWJhY2JjYmFhYmIiLCAiYWNidmZndHlhYmIiLCAiYWRiY2FjZGJtb3BhYmNvYWJiIiwKKyAgICAgICAgICAgICAgICAiamhma2poYVNERkdISmtkZmhITkpNamtoZmFiYiIsICIrKj8/KyphYmIiLCAic2RmZ2hqa2FiYiIgfTsKKworICAgICAgICBQYXR0ZXJuIHBhdDsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvcnJlY3RUZXN0UGF0dGVybnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoInBhdHRlcm46ICIgKyBjb3JyZWN0VGVzdFBhdHRlcm5zW2ldICsgIiBpbnB1dDogIgorICAgICAgICAgICAgICAgICAgICArIGlucHV0U2VjdWVuY2VbaV0sIFBhdHRlcm4ubWF0Y2hlcyhjb3JyZWN0VGVzdFBhdHRlcm5zW2ldLAorICAgICAgICAgICAgICAgICAgICBpbnB1dFNlY3VlbmNlW2ldKSk7CisKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ1tdIHdyb25nSW5wdXRTZWN1ZW5jZSA9IHsgIl0iLCAvKiAiYWRtcGtrIiwgKi8gICJhYmNhYmNkMTI0azY1NGFiYiIsCisgICAgICAgICAgICAgICAgImFid2NhYmNjYmFjYWJhYmIiLCAiYWJhYmFiZGVhYmFiZGVhYmIiLCAiYWJjYWJjYWNiYWNiYWJiIiwKKyAgICAgICAgICAgICAgICAiYWNkY2JlY2JhYWJiIiwgImFjYm90eWFiYiIsICJhZGJjYWVjZGJtb3BhYmNvYWJiIiwKKyAgICAgICAgICAgICAgICAiamhma2poYVNERkdISms7ZGZoSE5KTWpraGZhYmIiLCAiKyo/YT8rKmFiYiIsICJzZGYrZ2hqa2FiYiIgfTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvcnJlY3RUZXN0UGF0dGVybnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJwYXR0ZXJuOiAiICsgY29ycmVjdFRlc3RQYXR0ZXJuc1tpXSArICIgaW5wdXQ6ICIKKyAgICAgICAgICAgICAgICAgICAgKyB3cm9uZ0lucHV0U2VjdWVuY2VbaV0sIFBhdHRlcm4ubWF0Y2hlcygKKyAgICAgICAgICAgICAgICAgICAgY29ycmVjdFRlc3RQYXR0ZXJuc1tpXSwgd3JvbmdJbnB1dFNlY3VlbmNlW2ldKSk7CisKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSYW5nZXNTcGVjaWFsQ2FzZXMoKSB7CisgICAgICAgIFN0cmluZyBuZWdfcGF0dGVybnNbXSA9IHsgIlthLSYmW2ItY11dIiwgIlthLVxcd10iLCAiW2ItYV0iLCAiW10iIH07CisKKyAgICAgICAgZm9yIChTdHJpbmcgZWxlbWVudCA6IG5lZ19wYXR0ZXJucykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBQYXR0ZXJuLmNvbXBpbGUoZWxlbWVudCk7CisgICAgICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiB3YXMgZXhwZWN0ZWQ6ICIgKyBlbGVtZW50KTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gcHNlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgcG9zX3BhdHRlcm5zW10gPSB7ICJbLV0rIiwgIi0tLS0iLCAiW2EtXSsiLCAiYS1hLWEtYS1hYS0tIiwKKyAgICAgICAgICAgICAgICAiW1xcdy1hXSsiLCAiMTIzLTIzMTItLWFhYS0yMTMiLCAiW2EtXV0rIiwgIi1dXV1dXV1dXV1dXV1dXV0iIH07CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwb3NfcGF0dGVybnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFN0cmluZyBwYXQgPSBwb3NfcGF0dGVybnNbaSsrXTsKKyAgICAgICAgICAgIFN0cmluZyBpbnAgPSBwb3NfcGF0dGVybnNbaV07CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJwYXR0ZXJuOiAiICsgcGF0ICsgIiBpbnB1dDogIiArIGlucCwgUGF0dGVybi5tYXRjaGVzKAorICAgICAgICAgICAgICAgICAgICBwYXQsIGlucCkpOworICAgICAgICB9CisgICAgfQorIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKworICAgIHB1YmxpYyB2b2lkIHRlc3RaZXJvU3ltYm9scygpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShQYXR0ZXJuLm1hdGNoZXMoIltcMF0qYWJiIiwgIlwwXDBcMFwwXDBcMGFiYiIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXNjYXBlcygpIHsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoIlxcUXtdKCkqPyIpOworICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKCJ7XSgpKj8iKTsKKworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RCdWcxODEoKSB7CisgICAgICAgIFBhdHRlcm4uY29tcGlsZSgiW1xcdC1cXHJdIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE9ycGhhblF1YW50aWZpZXJzKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgUGF0dGVybi5jb21waWxlKCIrKysrKyIpOworICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIHBzZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE9ycGhhblF1YW50aWZpZXJzMigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFBhdHRlcm4gcGF0ID0gUGF0dGVybi5jb21waWxlKCJcXGQrKiIpOworICAgICAgICAgICAgZmFpbCgiUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIHBzZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEJ1ZzE5NygpIHsKKyAgICAgICAgT2JqZWN0W10gdmFscyA9IHsgIjoiLCBuZXcgSW50ZWdlcigyKSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geyAiYm9vIiwgImFuZDpmb28iIH0sICI6IiwgbmV3IEludGVnZXIoNSksCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHsgImJvbyIsICJhbmQiLCAiZm9vIiB9LCAiOiIsIG5ldyBJbnRlZ2VyKC0yKSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geyAiYm9vIiwgImFuZCIsICJmb28iIH0sICI6IiwgbmV3IEludGVnZXIoMyksCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHsgImJvbyIsICJhbmQiLCAiZm9vIiB9LCAiOiIsIG5ldyBJbnRlZ2VyKDEpLAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7ICJib286YW5kOmZvbyIgfSwgIm8iLCBuZXcgSW50ZWdlcig1KSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geyAiYiIsICIiLCAiOmFuZDpmIiwgIiIsICIiIH0sICJvIiwKKyAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcig0KSwgbmV3IFN0cmluZ1tdIHsgImIiLCAiIiwgIjphbmQ6ZiIsICJvIiB9LCAibyIsCisgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoLTIpLCBuZXcgU3RyaW5nW10geyAiYiIsICIiLCAiOmFuZDpmIiwgIiIsICIiIH0sCisgICAgICAgICAgICAgICAgIm8iLCBuZXcgSW50ZWdlcigwKSwgbmV3IFN0cmluZ1tdIHsgImIiLCAiIiwgIjphbmQ6ZiIgfSB9OworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFscy5sZW5ndGggLyAzOykgeworICAgICAgICAgICAgU3RyaW5nW10gcmVzID0gUGF0dGVybi5jb21waWxlKHZhbHNbaSsrXS50b1N0cmluZygpKS5zcGxpdCgKKyAgICAgICAgICAgICAgICAgICAgImJvbzphbmQ6Zm9vIiwgKChJbnRlZ2VyKSB2YWxzW2krK10pLmludFZhbHVlKCkpOworICAgICAgICAgICAgU3RyaW5nW10gZXhwZWN0ZWRSZXMgPSAoU3RyaW5nW10pIHZhbHNbaSsrXTsKKworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkUmVzLmxlbmd0aCwgcmVzLmxlbmd0aCk7CisKKyAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgZXhwZWN0ZWRSZXMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRSZXNbal0sIHJlc1tqXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VVJJUGF0dGVybnMoKSB7CisgICAgICAgIFN0cmluZyBVUklfUkVHRVhQX1NUUiA9ICJeKChbXjovPyNdKyk6KT8oLy8oW14vPyNdKikpPyhbXj8jXSopKFxcPyhbXiNdKikpPygjKC4qKSk/IjsKKyAgICAgICAgU3RyaW5nIFNDSEVNRV9SRUdFWFBfU1RSID0gIl5bYS16QS1aXXsxfVtcXHcrLS5dKyQiOworICAgICAgICBTdHJpbmcgUkVMX1VSSV9SRUdFWFBfU1RSID0gIl4oLy8oW14vPyNdKikpPyhbXj8jXSopKFxcPyhbXiNdKikpPygjKC4qKSk/IjsKKyAgICAgICAgU3RyaW5nIElQVjZfUkVHRVhQX1NUUiA9ICJeWzAtOWEtZkEtRlxcOlxcLl0rKFxcJVxcdyspPyQiOworICAgICAgICBTdHJpbmcgSVBWNl9SRUdFWFBfU1RSMiA9ICJeXFxbWzAtOWEtZkEtRlxcOlxcLl0rKFxcJVxcdyspP1xcXSQiOworICAgICAgICBTdHJpbmcgSVBWNF9SRUdFWFBfU1RSID0gIl5bMC05XXsxLDN9XFwuWzAtOV17MSwzfVxcLlswLTldezEsM31cXC5bMC05XXsxLDN9JCI7CisgICAgICAgIFN0cmluZyBIT1NUTkFNRV9SRUdFWFBfU1RSID0gIlxcdytbXFx3XFwtXFwuXSoiOworCisgICAgICAgIFBhdHRlcm4gVVJJX1JFR0VYUCA9IFBhdHRlcm4uY29tcGlsZShVUklfUkVHRVhQX1NUUik7CisgICAgICAgIFBhdHRlcm4gUkVMX1VSSV9SRUdFWFAgPSBQYXR0ZXJuLmNvbXBpbGUoUkVMX1VSSV9SRUdFWFBfU1RSKTsKKyAgICAgICAgUGF0dGVybiBTQ0hFTUVfUkVHRVhQID0gUGF0dGVybi5jb21waWxlKFNDSEVNRV9SRUdFWFBfU1RSKTsKKyAgICAgICAgUGF0dGVybiBJUFY0X1JFR0VYUCA9IFBhdHRlcm4uY29tcGlsZShJUFY0X1JFR0VYUF9TVFIpOworICAgICAgICBQYXR0ZXJuIElQVjZfUkVHRVhQID0gUGF0dGVybi5jb21waWxlKElQVjZfUkVHRVhQX1NUUik7CisgICAgICAgIFBhdHRlcm4gSVBWNl9SRUdFWFAyID0gUGF0dGVybi5jb21waWxlKElQVjZfUkVHRVhQX1NUUjIpOworICAgICAgICBQYXR0ZXJuIEhPU1ROQU1FX1JFR0VYUCA9IFBhdHRlcm4uY29tcGlsZShIT1NUTkFNRV9SRUdFWFBfU1RSKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmluZEJvdW5kYXJ5Q2FzZXMxKCkgeworICAgICAgICBQYXR0ZXJuIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiLipcbiIpOworICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKCJhXG4iKTsKKworICAgICAgICBtYXQuZmluZCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFcbiIsIG1hdC5ncm91cCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmluZEJvdW5kYXJ5Q2FzZXMyKCkgeworICAgICAgICBQYXR0ZXJuIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiLipBIik7CisgICAgICAgIE1hdGNoZXIgbWF0ID0gcGF0Lm1hdGNoZXIoImFBYSIpOworCisgICAgICAgIG1hdC5maW5kKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiYUEiLCBtYXQuZ3JvdXAoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZpbmRCb3VuZGFyeUNhc2VzMygpIHsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoIi4qQSIpOworICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKCJhXG5hQVxuIik7CisKKyAgICAgICAgbWF0LmZpbmQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhQSIsIG1hdC5ncm91cCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmluZEJvdW5kYXJ5Q2FzZXM0KCkgeworICAgICAgICBQYXR0ZXJuIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiQS4qIik7CisgICAgICAgIE1hdGNoZXIgbWF0ID0gcGF0Lm1hdGNoZXIoIkFcbiIpOworCisgICAgICAgIG1hdC5maW5kKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQSIsIG1hdC5ncm91cCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmluZEJvdW5kYXJ5Q2FzZXM1KCkgeworICAgICAgICBQYXR0ZXJuIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiLipBLioiKTsKKyAgICAgICAgTWF0Y2hlciBtYXQgPSBwYXQubWF0Y2hlcigiXG5BXG5hYWFcbkFcbmFhQWFhXG5hYWFBXG4iKTsKKyAgICAgICAgLy8gTWF0Y2hlciBtYXQgPSBwYXQubWF0Y2hlcigiXG5BXG4iKTsKKyAgICAgICAgU3RyaW5nW10gcmVzID0geyAiQSIsICJBIiwgImFhQWFhIiwgImFhYUEiIH07CisgICAgICAgIGludCBrID0gMDsKKyAgICAgICAgZm9yICg7IG1hdC5maW5kKCk7IGsrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc1trXSwgbWF0Lmdyb3VwKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZpbmRCb3VuZGFyeUNhc2VzNigpIHsKKyAgICAgICAgU3RyaW5nW10gcmVzID0geyAiIiwgImEiLCAiIiwgIiIgfTsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoIi4qIik7CisgICAgICAgIE1hdGNoZXIgbWF0ID0gcGF0Lm1hdGNoZXIoIlxuYVxuIik7CisgICAgICAgIGludCBrID0gMDsKKworICAgICAgICBmb3IgKDsgbWF0LmZpbmQoKTsgaysrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMocmVzW2tdLCBtYXQuZ3JvdXAoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QmFja1JlZmVyZW5jZXMoKSB7CisgICAgICAgIFBhdHRlcm4gcGF0ID0gUGF0dGVybi5jb21waWxlKCIoXFwoKFxcdyopOiguKik6KFxcMilcXCkpIik7CisgICAgICAgIE1hdGNoZXIgbWF0ID0gcGF0CisgICAgICAgICAgICAgICAgLm1hdGNoZXIoIihzdGFydDE6IHdvcmQgOnN0YXJ0MSkoc3RhcnQyOiB3b3JkIDpzdGFydDIpIik7CisgICAgICAgIGludCBrID0gMTsKKyAgICAgICAgZm9yICg7IG1hdC5maW5kKCk7IGsrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdGFydCIgKyBrLCBtYXQuZ3JvdXAoMikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCIgd29yZCAiLCBtYXQuZ3JvdXAoMykpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdGFydCIgKyBrLCBtYXQuZ3JvdXAoNCkpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGspOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoIi4qKC4pXFwxIik7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKCJzYWEiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV3TGluZSgpIHsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoIiheJCkqXG4iLCBQYXR0ZXJuLk1VTFRJTElORSk7CisgICAgICAgIE1hdGNoZXIgbWF0ID0gcGF0Lm1hdGNoZXIoIlxyXG5cbiIpOworICAgICAgICBpbnQgY291bnRlciA9IDA7CisgICAgICAgIHdoaWxlIChtYXQuZmluZCgpKSB7CisgICAgICAgICAgICBjb3VudGVyKys7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGNvdW50ZXIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGaW5kR3JlZWR5KCkgeworICAgICAgICBQYXR0ZXJuIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiLiphYWEiLCBQYXR0ZXJuLkRPVEFMTCk7CisgICAgICAgIE1hdGNoZXIgbWF0ID0gcGF0Lm1hdGNoZXIoImFhYWFcbmFhYVxuYWFhYWFhIik7CisgICAgICAgIG1hdC5tYXRjaGVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxNSwgbWF0LmVuZCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXphdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQYXR0ZXJuIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiYSpiYyIpOworICAgICAgICBTZXJpYWxpemFibGVBc3NlcnQgY29tcGFyYXRvciA9IG5ldyBTZXJpYWxpemFibGVBc3NlcnQoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBhc3NlcnREZXNlcmlhbGl6ZWQoU2VyaWFsaXphYmxlIGluaXRpYWwsCisgICAgICAgICAgICAgICAgICAgIFNlcmlhbGl6YWJsZSBkZXNlcmlhbGl6ZWQpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoKChQYXR0ZXJuKSBpbml0aWFsKS50b1N0cmluZygpLAorICAgICAgICAgICAgICAgICAgICAgICAgKChQYXR0ZXJuKSBkZXNlcmlhbGl6ZWQpLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdC52ZXJpZnlHb2xkZW4odGhpcywgcGF0LCBjb21wYXJhdG9yKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3QudmVyaWZ5U2VsZihwYXQsIGNvbXBhcmF0b3IpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTT0xRdWFudCgpIHsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoIiQqIiwgUGF0dGVybi5NVUxUSUxJTkUpOworICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKCJcblxuIik7CisgICAgICAgIGludCBjb3VudGVyID0gMDsKKyAgICAgICAgd2hpbGUgKG1hdC5maW5kKCkpIHsKKyAgICAgICAgICAgIGNvdW50ZXIrKzsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygzLCBjb3VudGVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWxsZWdhbEVzY2FwZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFBhdHRlcm4uY29tcGlsZSgiXFx5Iik7CisgICAgICAgICAgICBmYWlsKCJQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gcHNlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW1wdHlGYW1pbHkoKSB7CisgICAgICAgIFBhdHRlcm4uY29tcGlsZSgiXFxwe0xvd2VyfSIpOworICAgICAgICBTdHJpbmcgYSA9ICIqIjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9uQ2FwdENvbnN0cigpIHsKKyAgICAgICAgLy8gRmxhZ3MKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoIig/aSliKig/LWkpYSoiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwYXQubWF0Y2hlcigiYkJiQmFhYWEiKS5tYXRjaGVzKCkpOworICAgICAgICBhc3NlcnRGYWxzZShwYXQubWF0Y2hlcigiYkJiQkFhQWEiKS5tYXRjaGVzKCkpOworCisgICAgICAgIC8vIE5vbi1jYXB0dXJpbmcgZ3JvdXBzCisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiKD9pOmIqKWEqIik7CisgICAgICAgIGFzc2VydFRydWUocGF0Lm1hdGNoZXIoImJCYkJhYWFhIikubWF0Y2hlcygpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocGF0Lm1hdGNoZXIoImJCYkJBYUFhIikubWF0Y2hlcygpKTsKKworICAgICAgICBwYXQgPSBQYXR0ZXJuCisgICAgICAgIC8vIDEgMiAzIDQgNSA2IDcgOCA5IDEwIDExCisgICAgICAgICAgICAgICAgLmNvbXBpbGUoIig/Oi18KC0/XFxkK1xcZFxcZFxcZCkpPyg/Oi18LShcXGRcXGQpKT8oPzotfC0oXFxkXFxkKSk/KFQpPyg/OihcXGRcXGQpOihcXGRcXGQpOihcXGRcXGQpKFxcLlxcZCspPyk/KD86KD86KCg/OlxcK3xcXC0pXFxkXFxkKTooXFxkXFxkKSl8KFopKT8iKTsKKyAgICAgICAgTWF0Y2hlciBtYXQgPSBwYXQubWF0Y2hlcigiLTEyMzQtMjEtMzFUNDE6NTE6NjEuNzg5KzcxOjgxIik7CisgICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLTEyMzQiLCBtYXQuZ3JvdXAoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjIxIiwgbWF0Lmdyb3VwKDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIzMSIsIG1hdC5ncm91cCgzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVCIsIG1hdC5ncm91cCg0KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiNDEiLCBtYXQuZ3JvdXAoNSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjUxIiwgbWF0Lmdyb3VwKDYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI2MSIsIG1hdC5ncm91cCg3KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiLjc4OSIsIG1hdC5ncm91cCg4KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiKzcxIiwgbWF0Lmdyb3VwKDkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI4MSIsIG1hdC5ncm91cCgxMCkpOworCisgICAgICAgIC8vIHBvc2l0aXZlIGxvb2thaGVhZAorICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoIi4qXFwuKD89bG9nJCkuKiQiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwYXQubWF0Y2hlcigiYS5iLmMubG9nIikubWF0Y2hlcygpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocGF0Lm1hdGNoZXIoImEuYi5jLmxvZy4iKS5tYXRjaGVzKCkpOworCisgICAgICAgIC8vIG5lZ2F0aXZlIGxvb2thaGVhZAorICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoIi4qXFwuKD8hbG9nJCkuKiQiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocGF0Lm1hdGNoZXIoImFiYy5sb2ciKS5tYXRjaGVzKCkpOworICAgICAgICBhc3NlcnRUcnVlKHBhdC5tYXRjaGVyKCJhYmMubG9nZyIpLm1hdGNoZXMoKSk7CisKKyAgICAgICAgLy8gcG9zaXRpdmUgbG9va2JlaGluZAorICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoIi4qKD88PWFiYylcXC5sb2ckIik7CisgICAgICAgIGFzc2VydEZhbHNlKHBhdC5tYXRjaGVyKCJjZGUubG9nIikubWF0Y2hlcygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwYXQubWF0Y2hlcigiYWJjLmxvZyIpLm1hdGNoZXMoKSk7CisKKyAgICAgICAgLy8gbmVnYXRpdmUgbG9va2JlaGluZAorICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoIi4qKD88IWFiYylcXC5sb2ckIik7CisgICAgICAgIGFzc2VydFRydWUocGF0Lm1hdGNoZXIoImNkZS5sb2ciKS5tYXRjaGVzKCkpOworICAgICAgICBhc3NlcnRGYWxzZShwYXQubWF0Y2hlcigiYWJjLmxvZyIpLm1hdGNoZXMoKSk7CisKKyAgICAgICAgLy8gYXRvbWljIGdyb3VwCisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiKD8+YSopYWJiIik7CisgICAgICAgIGFzc2VydEZhbHNlKHBhdC5tYXRjaGVyKCJhYWFiYiIpLm1hdGNoZXMoKSk7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiKD8+YSopYmIiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwYXQubWF0Y2hlcigiYWFhYmIiKS5tYXRjaGVzKCkpOworCisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiKD8+YXxhYSlhYWJiIik7CisgICAgICAgIGFzc2VydFRydWUocGF0Lm1hdGNoZXIoImFhYWJiIikubWF0Y2hlcygpKTsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKCIoPz5hYXxhKWFhYmIiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocGF0Lm1hdGNoZXIoImFhYWJiIikubWF0Y2hlcygpKTsKKworLy8gQkVHSU4gYW5kcm9pZC1yZW1vdmVkCisvLyBRdWVzdGlvbmFibGUgY29uc3RydWN0cyB0aGF0IElDVSBkb2Vzbid0IHN1cHBvcnQuCisvLyAgICAgICAgLy8gcXVhbnRpZmllcnMgb3ZlciBsb29rIGFoZWFkCisvLyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKCIuKig/PD1hYmMpKlxcLmxvZyQiKTsKKy8vICAgICAgICBhc3NlcnRUcnVlKHBhdC5tYXRjaGVyKCJjZGUubG9nIikubWF0Y2hlcygpKTsKKy8vICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoIi4qKD88PWFiYykrXFwubG9nJCIpOworLy8gICAgICAgIGFzc2VydEZhbHNlKHBhdC5tYXRjaGVyKCJjZGUubG9nIikubWF0Y2hlcygpKTsKKy8vIEVORCBhbmRyb2lkLXJlbW92ZWQKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb3JyZWN0UmVwbGFjZW1lbnRCYWNrcmVmZXJlbmNlZEpvaW50U2V0KCkgeworICAgICAgICBQYXR0ZXJuIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiYWIoYSkqXFwxIik7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiYWJjKGNkKWZnIik7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiYWJhKmNkIik7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiYWIoYSkqK2NkIik7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiYWIoYSkqP2NkIik7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiYWIoYSkrY2QiKTsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKCIuKiguKVxcMSIpOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoImFiKChhKXxjfGQpZSIpOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoImFiYygoYShiKSljZCkiKTsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKCJhYihhKSsrY2QiKTsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKCJhYihhKT8oYylkIik7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiYWIoYSk/K2NkIik7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiYWIoYSk/P2NkIik7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiYWIoYSk/P2NkIik7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiYWIoYSl7MSwzfT8oYylkIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbXBpbGVQYXR0ZXJuV2l0aFRlcm1pbmF0b3JNYXJrKCkgeworICAgICAgICBQYXR0ZXJuIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiYVx1MDAwMFx1MDAwMGNkIik7CisgICAgICAgIE1hdGNoZXIgbWF0ID0gcGF0Lm1hdGNoZXIoImFcdTAwMDBcdTAwMDBjZCIpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBbHRlcm5hdGlvbnMoKSB7CisgICAgICAgIFN0cmluZyBiYXNlU3RyaW5nID0gInxhfGJjIjsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZyk7CisgICAgICAgIE1hdGNoZXIgbWF0ID0gcGF0Lm1hdGNoZXIoIiIpOworCisgICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisKKyAgICAgICAgYmFzZVN0cmluZyA9ICJhfHxiYyI7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nKTsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIoIiIpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIGJhc2VTdHJpbmcgPSAiYXxiY3wiOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKCIiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBiYXNlU3RyaW5nID0gImF8YnwiOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKCIiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBiYXNlU3RyaW5nID0gImEofGJ8Y2QpZSI7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nKTsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIoImFlIik7CisgICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisKKyAgICAgICAgYmFzZVN0cmluZyA9ICJhKGJ8fGNkKWUiOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKCJhZSIpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIGJhc2VTdHJpbmcgPSAiYShifGNkfCllIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcigiYWUiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBiYXNlU3RyaW5nID0gImEoYnxjfCllIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcigiYWUiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBiYXNlU3RyaW5nID0gImEofCllIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcigiYWUiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBiYXNlU3RyaW5nID0gInwiOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKCIiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBiYXNlU3RyaW5nID0gImEoPzp8KWUiOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKCJhZSIpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIGJhc2VTdHJpbmcgPSAiYXx8fHxiYyI7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nKTsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIoIiIpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIGJhc2VTdHJpbmcgPSAiKD9pLWlzKXxhIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcigiYSIpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYXRjaFdpdGhHcm91cHMoKSB7CisgICAgICAgIFN0cmluZyBiYXNlU3RyaW5nID0gImp3a2VyaGp3ZWhya3dqZWhya3dqaHJ3a2plaHJqd2tlaHJqa3docmt3ZWhya3docmt3cmh3a2hyd2tqZWhyIjsKKyAgICAgICAgU3RyaW5nIHBhdHRlcm4gPSAiLiooLi4pLipcXDEuKiI7CisgICAgICAgIGFzc2VydFRydWUoUGF0dGVybi5jb21waWxlKHBhdHRlcm4pLm1hdGNoZXIoYmFzZVN0cmluZykubWF0Y2hlcygpKTsKKworICAgICAgICBiYXNlU3RyaW5nID0gInNhYSI7CisgICAgICAgIHBhdHRlcm4gPSAiLiooLilcXDEiOworICAgICAgICBhc3NlcnRUcnVlKFBhdHRlcm4uY29tcGlsZShwYXR0ZXJuKS5tYXRjaGVyKGJhc2VTdHJpbmcpLm1hdGNoZXMoKSk7CisgICAgICAgIGFzc2VydFRydWUoUGF0dGVybi5jb21waWxlKHBhdHRlcm4pLm1hdGNoZXIoYmFzZVN0cmluZykuZmluZCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3BsaXRFbXB0eUNoYXJTZXF1ZW5jZSgpIHsKKyAgICAgICAgU3RyaW5nIHMxID0gIiI7CisgICAgICAgIFN0cmluZ1tdIGFyciA9IHMxLnNwbGl0KCI6Iik7CisgICAgICAgIGFzc2VydEVxdWFscyhhcnIubGVuZ3RoLCAxKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3BsaXRFbmRzV2l0aFBhdHRlcm4oKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiLCwiLnNwbGl0KCIsIiwgMykubGVuZ3RoLCAzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIsLCIuc3BsaXQoIiwiLCA0KS5sZW5ndGgsIDMpOworCisgICAgICAgIGFzc2VydEVxdWFscyhQYXR0ZXJuLmNvbXBpbGUoIm8iKS5zcGxpdCgiYm9vOmFuZDpmb28iLCA1KS5sZW5ndGgsIDUpOworICAgICAgICBhc3NlcnRFcXVhbHMoUGF0dGVybi5jb21waWxlKCJiIikuc3BsaXQoImFiIiwgLTEpLmxlbmd0aCwgMik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENhc2VJbnNlbnNpdGl2ZUZsYWcoKSB7CisgICAgICAgIGFzc2VydFRydWUoUGF0dGVybi5tYXRjaGVzKCIoP2ktOkFiQykiLCAiQUJDIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eUdyb3VwcygpIHsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoImFiKD8+KWNkYSIpOworICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKCJhYmNkYSIpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiYWIoKSIpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcigiYWIiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoImFiYyg/OikoLi4pIik7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKCJhYmNnZiIpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb21waWxlTm9uQ2FwdEdyb3VwKCkgeworICAgICAgICBib29sZWFuIGlzQ29tcGlsZWQgPSBmYWxzZTsKKworICAgICAgICB0cnkgeworLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2UKKy8vIFdlIGRvbid0IGhhdmUgY2Fub25pY2FsIGVxdWl2YWxlbmNlLgorICAgICAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoIig/OikiKTsKKyAgICAgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiKD86KSIsIFBhdHRlcm4uRE9UQUxMKTsKKyAgICAgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZSgiKD86KSIsIFBhdHRlcm4uQ0FTRV9JTlNFTlNJVElWRSk7CisgICAgICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoIig/OikiLCBQYXR0ZXJuLkNPTU1FTlRTIHwgUGF0dGVybi5VTklYX0xJTkVTKTsKKy8vIEVORCBhbmRyb2lkLWNoYW5nZQorICAgICAgICAgICAgaXNDb21waWxlZCA9IHRydWU7CisgICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGUpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoaXNDb21waWxlZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVtYmVkZGVkRmxhZ3MoKSB7CisgICAgICAgIFN0cmluZyBiYXNlU3RyaW5nID0gIig/aSkoKD9zKWEpIjsKKyAgICAgICAgU3RyaW5nIHRlc3RTdHJpbmcgPSAiQSI7CisgICAgICAgIFBhdHRlcm4gcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIGJhc2VTdHJpbmcgPSAiKD94KSg/aSkoP3MpKD9kKWEiOworICAgICAgICB0ZXN0U3RyaW5nID0gIkEiOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIGJhc2VTdHJpbmcgPSAiKD94KSg/aSkoP3MpKD9kKWEuIjsKKyAgICAgICAgdGVzdFN0cmluZyA9ICJhXG4iOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIGJhc2VTdHJpbmcgPSAiYWJjKD94Oig/aSkoP3MpKD9kKWEuKSI7CisgICAgICAgIHRlc3RTdHJpbmcgPSAiYWJjQVxuIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBiYXNlU3RyaW5nID0gImFiYygoP3gpZCkoP2kpKD9zKWEiOworICAgICAgICB0ZXN0U3RyaW5nID0gImFiY2RBIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWx0V2l0aEZsYWdzKCkgeworICAgICAgICBib29sZWFuIGlzQ29tcGlsZWQgPSBmYWxzZTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoInwoP2kteGkpfCgpIik7CisgICAgICAgICAgICBpc0NvbXBpbGVkID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoUGF0dGVyblN5bnRheEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oZSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZShpc0NvbXBpbGVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVzdG9yZUZsYWdzQWZ0ZXJHcm91cCgpIHsKKyAgICAgICAgU3RyaW5nIGJhc2VTdHJpbmcgPSAiYWJjKCg/eClkKSAgIGEiOworICAgICAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJhYmNkICAgYSI7CisgICAgICAgIFBhdHRlcm4gcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcpOworICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworCisgICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBWZXJpZnkgaWYgdGhlIFBhdHRlcm4gc3VwcG9ydCB0aGUgZm9sbG93aW5nIGNoYXJhY3RlciBjbGFzc2VzOgorICAgICAqIFxwe2phdmFMb3dlckNhc2V9IFxwe2phdmFVcHBlckNhc2V9IFxwe2phdmFXaGl0ZXNwYWNlfSBccHtqYXZhTWlycm9yZWR9CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENvbXBpbGVDaGFyYWN0ZXJDbGFzcygpIHsKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS02MDYsIDY5NgorICAgICAgICBQYXR0ZXJuIHBhdHRlcm4gPSBQYXR0ZXJuLmNvbXBpbGUoIlxccHtqYXZhTG93ZXJDYXNlfSIpOworICAgICAgICBhc3NlcnROb3ROdWxsKHBhdHRlcm4pOworCisgICAgICAgIHBhdHRlcm4gPSBQYXR0ZXJuLmNvbXBpbGUoIlxccHtqYXZhVXBwZXJDYXNlfSIpOworICAgICAgICBhc3NlcnROb3ROdWxsKHBhdHRlcm4pOworCisgICAgICAgIHBhdHRlcm4gPSBQYXR0ZXJuLmNvbXBpbGUoIlxccHtqYXZhV2hpdGVzcGFjZX0iKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChwYXR0ZXJuKTsKKworICAgICAgICBwYXR0ZXJuID0gUGF0dGVybi5jb21waWxlKCJcXHB7amF2YU1pcnJvcmVkfSIpOworICAgICAgICBhc3NlcnROb3ROdWxsKHBhdHRlcm4pOworCisgICAgICAgIHBhdHRlcm4gPSBQYXR0ZXJuLmNvbXBpbGUoIlxccHtqYXZhRGVmaW5lZH0iKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChwYXR0ZXJuKTsKKworICAgICAgICBwYXR0ZXJuID0gUGF0dGVybi5jb21waWxlKCJcXHB7amF2YURpZ2l0fSIpOworICAgICAgICBhc3NlcnROb3ROdWxsKHBhdHRlcm4pOworCisgICAgICAgIHBhdHRlcm4gPSBQYXR0ZXJuLmNvbXBpbGUoIlxccHtqYXZhSWRlbnRpZmllcklnbm9yYWJsZX0iKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChwYXR0ZXJuKTsKKworICAgICAgICBwYXR0ZXJuID0gUGF0dGVybi5jb21waWxlKCJcXHB7amF2YUlTT0NvbnRyb2x9Iik7CisgICAgICAgIGFzc2VydE5vdE51bGwocGF0dGVybik7CisKKyAgICAgICAgcGF0dGVybiA9IFBhdHRlcm4uY29tcGlsZSgiXFxwe2phdmFKYXZhSWRlbnRpZmllclBhcnR9Iik7CisgICAgICAgIGFzc2VydE5vdE51bGwocGF0dGVybik7CisKKyAgICAgICAgcGF0dGVybiA9IFBhdHRlcm4uY29tcGlsZSgiXFxwe2phdmFKYXZhSWRlbnRpZmllclN0YXJ0fSIpOworICAgICAgICBhc3NlcnROb3ROdWxsKHBhdHRlcm4pOworCisgICAgICAgIHBhdHRlcm4gPSBQYXR0ZXJuLmNvbXBpbGUoIlxccHtqYXZhTGV0dGVyfSIpOworICAgICAgICBhc3NlcnROb3ROdWxsKHBhdHRlcm4pOworCisgICAgICAgIHBhdHRlcm4gPSBQYXR0ZXJuLmNvbXBpbGUoIlxccHtqYXZhTGV0dGVyT3JEaWdpdH0iKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChwYXR0ZXJuKTsKKworICAgICAgICBwYXR0ZXJuID0gUGF0dGVybi5jb21waWxlKCJcXHB7amF2YVNwYWNlQ2hhcn0iKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChwYXR0ZXJuKTsKKworICAgICAgICBwYXR0ZXJuID0gUGF0dGVybi5jb21waWxlKCJcXHB7amF2YVRpdGxlQ2FzZX0iKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChwYXR0ZXJuKTsKKworICAgICAgICBwYXR0ZXJuID0gUGF0dGVybi5jb21waWxlKCJcXHB7amF2YVVuaWNvZGVJZGVudGlmaWVyUGFydH0iKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChwYXR0ZXJuKTsKKworICAgICAgICBwYXR0ZXJuID0gUGF0dGVybi5jb21waWxlKCJcXHB7amF2YVVuaWNvZGVJZGVudGlmaWVyU3RhcnR9Iik7CisgICAgICAgIGFzc2VydE5vdE51bGwocGF0dGVybik7CisgICAgfQorCisgICAgLyoqCisgICAgICogcyBvcmlnaW5hbCB0ZXN0IHdhcyBmaXhlZCB0byBwYXNzIG9uIFJJCisgICAgICovCisKKy8vIEJFR0lOIGFuZHJvaWQtcmVtb3ZlZAorLy8gV2UgZG9uJ3QgaGF2ZSBjYW5vbmljYWwgZXF1aXZhbGVuY2UuCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2Fub25FcUZsYWcoKSB7CisvLworLy8gICAgICAgIC8qCisvLyAgICAgICAgICogZm9yIGRlY29tcG9zaXRpb25zIHNlZQorLy8gICAgICAgICAqIGh0dHA6Ly93d3cudW5pY29kZS5vcmcvUHVibGljLzQuMC1VcGRhdGUvVW5pY29kZURhdGEtNC4wLjAudHh0CisvLyAgICAgICAgICogaHR0cDovL3d3dy51bmljb2RlLm9yZy9yZXBvcnRzL3RyMTUvI0RlY29tcG9zaXRpb24KKy8vICAgICAgICAgKi8KKy8vICAgICAgICBTdHJpbmcgYmFzZVN0cmluZzsKKy8vICAgICAgICBTdHJpbmcgdGVzdFN0cmluZzsKKy8vICAgICAgICBQYXR0ZXJuIHBhdDsKKy8vICAgICAgICBNYXRjaGVyIG1hdDsKKy8vCisvLyAgICAgICAgYmFzZVN0cmluZyA9ICJhYihhKilcXDEiOworLy8gICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nLCBQYXR0ZXJuLkNBTk9OX0VRKTsKKy8vCisvLyAgICAgICAgYmFzZVN0cmluZyA9ICJhKGFiY2RmKWQiOworLy8gICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nLCBQYXR0ZXJuLkNBTk9OX0VRKTsKKy8vCisvLyAgICAgICAgYmFzZVN0cmluZyA9ICJhYWJjZGZkIjsKKy8vICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZywgUGF0dGVybi5DQU5PTl9FUSk7CisvLworLy8gICAgICAgIC8vIFx1MDFFMCAtPiBcdTAyMjZcdTAzMDQgLT5cdTAwNDFcdTAzMDdcdTAzMDQKKy8vICAgICAgICAvLyBcdTAwQ0MgLT4gXHUwMDQ5XHUwMzAwCisvLworLy8gICAgICAgIC8qCisvLyAgICAgICAgICogYmFzZVN0cmluZyA9ICJcdTAxRTBcdTAwQ0NjZGIoYWMpIjsgdGVzdFN0cmluZyA9CisvLyAgICAgICAgICogIlx1MDIyNlx1MDMwNFx1MDA0OVx1MDMwMGNkYmFjIjsgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcsCisvLyAgICAgICAgICogUGF0dGVybi5DQU5PTl9FUSk7IG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworLy8gICAgICAgICAqIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisvLyAgICAgICAgICovCisvLyAgICAgICAgYmFzZVN0cmluZyA9ICJcdTAxRTBjZGIoYVx1MDBDQ2MpIjsKKy8vICAgICAgICB0ZXN0U3RyaW5nID0gIlx1MDA0MVx1MDMwN1x1MDMwNGNkYmFcdTAwNDlcdTAzMDBjIjsKKy8vICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZywgUGF0dGVybi5DQU5PTl9FUSk7CisvLyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisvLyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKy8vCisvLyAgICAgICAgYmFzZVN0cmluZyA9ICJhXHUwMENDIjsKKy8vICAgICAgICB0ZXN0U3RyaW5nID0gImFcdTAwNDlcdTAzMDAiOworLy8gICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nLCBQYXR0ZXJuLkNBTk9OX0VRKTsKKy8vICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKy8vICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworLy8KKy8vICAgICAgICAvKgorLy8gICAgICAgICAqIGJhc2VTdHJpbmcgPSAiXHUwMjI2XHUwMzA0Y2RiKGFjXHUwMDQ5XHUwMzAwKSI7IHRlc3RTdHJpbmcgPQorLy8gICAgICAgICAqICJcdTAxRTBjZGJhY1x1MDBDQyI7IHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nLAorLy8gICAgICAgICAqIFBhdHRlcm4uQ0FOT05fRVEpOyBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKy8vICAgICAgICAgKiBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworLy8gICAgICAgICAqCisvLyAgICAgICAgICogYmFzZVN0cmluZyA9ICJjZGIoPzpcdTAwNDFcdTAzMDdcdTAzMDRcdTAwQ0MpIjsgdGVzdFN0cmluZyA9CisvLyAgICAgICAgICogImNkYlx1MDIyNlx1MDMwNFx1MDA0OVx1MDMwMCI7IHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nLAorLy8gICAgICAgICAqIFBhdHRlcm4uQ0FOT05fRVEpOyBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKy8vICAgICAgICAgKiBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworLy8gICAgICAgICAqCisvLyAgICAgICAgICogYmFzZVN0cmluZyA9ICJcdTAxRTBbYS1jXVx1MDA0OVx1MDMwMGNkYihhYykiOyB0ZXN0U3RyaW5nID0KKy8vICAgICAgICAgKiAiXHUwMUUwYlx1MDBDQ2NkYmFjIjsgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcsCisvLyAgICAgICAgICogUGF0dGVybi5DQU5PTl9FUSk7IG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworLy8gICAgICAgICAqIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisvLyAgICAgICAgICoKKy8vICAgICAgICAgKiBiYXNlU3RyaW5nID0gIlx1MDFFMHxcdTAwQ0NjZGIoYWMpIjsgdGVzdFN0cmluZyA9CisvLyAgICAgICAgICogIlx1MDA0MVx1MDMwN1x1MDMwNCI7IHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nLAorLy8gICAgICAgICAqIFBhdHRlcm4uQ0FOT05fRVEpOyBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKy8vICAgICAgICAgKiBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworLy8gICAgICAgICAqCisvLyAgICAgICAgICogYmFzZVN0cmluZyA9ICJcdTAwQ0M/Y2RiKGFjKSooXHUwMUUwKSpbYS1jXSI7IHRlc3RTdHJpbmcgPQorLy8gICAgICAgICAqICJjZGJcdTAwNDFcdTAzMDdcdTAzMDRiIjsgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcsCisvLyAgICAgICAgICogUGF0dGVybi5DQU5PTl9FUSk7IG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworLy8gICAgICAgICAqIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisvLyAgICAgICAgICovCisvLyAgICAgICAgYmFzZVN0cmluZyA9ICJhXHUwMzAwIjsKKy8vICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZywgUGF0dGVybi5DQU5PTl9FUSk7CisvLyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIoImFcdTAwRTBhIik7CisvLyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQuZmluZCgpKTsKKy8vCisvLyAgICAgICAgLyoKKy8vICAgICAgICAgKiBiYXNlU3RyaW5nID0gIlx1N0IyMFx1RjlGOGFiYyI7IHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nLAorLy8gICAgICAgICAqIFBhdHRlcm4uQ0FOT05fRVEpOyBtYXQgPSBwYXQubWF0Y2hlcigiXHVGOUY4XHVGOUY4YWJjIik7CisvLyAgICAgICAgICogYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKy8vICAgICAgICAgKgorLy8gICAgICAgICAqIC8vXHUwMUY5IC0+IFx1MDA2RVx1MDMwMCAvL1x1MDBDMyAtPiBcdTAwNDFcdTAzMDMKKy8vICAgICAgICAgKgorLy8gICAgICAgICAqIGJhc2VTdHJpbmcgPSAiY2RiKD86XHUwMEMzXHUwMDZFXHUwMzAwKSI7IHRlc3RTdHJpbmcgPQorLy8gICAgICAgICAqICJjZGJcdTAwNDFcdTAzMDNcdTAxRjkiOyBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZywKKy8vICAgICAgICAgKiBQYXR0ZXJuLkNBTk9OX0VRKTsgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisvLyAgICAgICAgICogYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKy8vICAgICAgICAgKgorLy8gICAgICAgICAqIC8vXHUwMTRDIC0+IFx1MDA0Rlx1MDMwNCAvL1x1MDE2MyAtPiBcdTAwNzRcdTAzMjcKKy8vICAgICAgICAgKgorLy8gICAgICAgICAqIGJhc2VTdHJpbmcgPSAiY2RiKD86XHUwMTYzXHUwMDRGXHUwMzA0KSI7IHRlc3RTdHJpbmcgPQorLy8gICAgICAgICAqICJjZGJcdTAwNzRcdTAzMjdcdTAxNEMiOyBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZywKKy8vICAgICAgICAgKiBQYXR0ZXJuLkNBTk9OX0VRKTsgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisvLyAgICAgICAgICogYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKy8vICAgICAgICAgKi8KKy8vICAgICAgICAvLyBcdTAwRTEtPmFcdTAzMDEKKy8vICAgICAgICAvLyBjYW5vbmljYWwgb3JkZXJpbmcgdGFrZXMgcGxhY2UgXHUwMzAxXHUwMzI3IC0+IFx1MDMyN1x1MDMwMQorLy8gICAgICAgIGJhc2VTdHJpbmcgPSAiY1x1MDMyN1x1MDMwMSI7CisvLyAgICAgICAgdGVzdFN0cmluZyA9ICJjXHUwMzAxXHUwMzI3IjsKKy8vICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZywgUGF0dGVybi5DQU5PTl9FUSk7CisvLyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisvLyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKy8vCisvLyAgICAgICAgLyoKKy8vICAgICAgICAgKiBIYW5ndWwgZGVjb21wb3NpdGlvbnMKKy8vICAgICAgICAgKi8KKy8vICAgICAgICAvLyBcdUQ0REItPlx1MTExMVx1MTE3MVx1MTFCNgorLy8gICAgICAgIC8vIFx1RDIxRS0+XHUxMTEwXHUxMTZEXHUxMUI1CisvLyAgICAgICAgLy8gXHVEMjY0LT5cdTExMTBcdTExNzAKKy8vICAgICAgICAvLyBub3QgSGFuZ3VsOlx1MDQ1My0+XHUwNDMzXHUwMzAxCisvLyAgICAgICAgYmFzZVN0cmluZyA9ICJhXHVENERCXHUxMTExXHUxMTcxXHUxMUI2XHVEMjY0IjsKKy8vICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZywgUGF0dGVybi5DQU5PTl9FUSk7CisvLworLy8gICAgICAgIGJhc2VTdHJpbmcgPSAiXHUwNDUzY1x1RDREQiI7CisvLyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcsIFBhdHRlcm4uQ0FOT05fRVEpOworLy8KKy8vICAgICAgICBiYXNlU3RyaW5nID0gImFcdTExMTBcdTExNkRcdTExQjViXHVEMjFFYmMiOworLy8gICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nLCBQYXR0ZXJuLkNBTk9OX0VRKTsKKy8vCisvLyAgICAgICAgLyoKKy8vICAgICAgICAgKiBiYXNlU3RyaW5nID0gIlx1RDREQlx1RDIxRVx1MTExMFx1MTE3MGNkYihhYykiOyB0ZXN0U3RyaW5nID0KKy8vICAgICAgICAgKiAiXHUxMTExXHUxMTcxXHUxMUI2XHUxMTEwXHUxMTZEXHUxMUI1XHVEMjY0Y2RiYWMiOyBwYXQgPQorLy8gICAgICAgICAqIFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nLCBQYXR0ZXJuLkNBTk9OX0VRKTsgbWF0ID0KKy8vICAgICAgICAgKiBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKy8vICAgICAgICAgKi8KKy8vICAgICAgICBiYXNlU3RyaW5nID0gIlx1RDREQlx1RDI2NGNkYihhXHVEMjFFYykiOworLy8gICAgICAgIHRlc3RTdHJpbmcgPSAiXHUxMTExXHUxMTcxXHUxMUI2XHUxMTEwXHUxMTcwY2RiYVx1MTExMFx1MTE2RFx1MTFCNWMiOworLy8gICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nLCBQYXR0ZXJuLkNBTk9OX0VRKTsKKy8vICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKy8vICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworLy8KKy8vICAgICAgICBiYXNlU3RyaW5nID0gImFcdUQ0REIiOworLy8gICAgICAgIHRlc3RTdHJpbmcgPSAiYVx1MTExMVx1MTE3MVx1MTFCNiI7CisvLyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcsIFBhdHRlcm4uQ0FOT05fRVEpOworLy8gICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworLy8gICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisvLworLy8gICAgICAgIGJhc2VTdHJpbmcgPSAiYVx1RDIxRSI7CisvLyAgICAgICAgdGVzdFN0cmluZyA9ICJhXHUxMTEwXHUxMTZEXHUxMUI1IjsKKy8vICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZywgUGF0dGVybi5DQU5PTl9FUSk7CisvLyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisvLyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKy8vCisvLyAgICAgICAgLyoKKy8vICAgICAgICAgKiBiYXNlU3RyaW5nID0gIlx1MTExMVx1MTE3MVx1MTFCNmNkYihhY1x1MTExMFx1MTE2RFx1MTFCNSkiOworLy8gICAgICAgICAqIHRlc3RTdHJpbmcgPSAiXHVENERCY2RiYWNcdUQyMUUiOyBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZywKKy8vICAgICAgICAgKiBQYXR0ZXJuLkNBTk9OX0VRKTsgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisvLyAgICAgICAgICogYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKy8vICAgICAgICAgKgorLy8gICAgICAgICAqIGJhc2VTdHJpbmcgPSAiY2RiKD86XHUxMTExXHUxMTcxXHUxMUI2XHVEMjFFKSI7IHRlc3RTdHJpbmcgPQorLy8gICAgICAgICAqICJjZGJcdUQ0REJcdTExMTBcdTExNkRcdTExQjUiOyBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZywKKy8vICAgICAgICAgKiBQYXR0ZXJuLkNBTk9OX0VRKTsgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisvLyAgICAgICAgICogYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKy8vICAgICAgICAgKgorLy8gICAgICAgICAqIGJhc2VTdHJpbmcgPSAiXHVENERCW2EtY11cdTExMTBcdTExNkRcdTExQjVjZGIoYWMpIjsgdGVzdFN0cmluZyA9CisvLyAgICAgICAgICogIlx1RDREQmJcdUQyMUVjZGJhYyI7IHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nLAorLy8gICAgICAgICAqIFBhdHRlcm4uQ0FOT05fRVEpOyBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKy8vICAgICAgICAgKiBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworLy8gICAgICAgICAqLworLy8gICAgICAgIGJhc2VTdHJpbmcgPSAiXHVENERCfFx1MDBDQ2NkYihhYykiOworLy8gICAgICAgIHRlc3RTdHJpbmcgPSAiXHUxMTExXHUxMTcxXHUxMUI2IjsKKy8vICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZywgUGF0dGVybi5DQU5PTl9FUSk7CisvLyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisvLyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKy8vCisvLyAgICAgICAgYmFzZVN0cmluZyA9ICJcdUQ0REJ8XHUwMENDY2RiKGFjKSI7CisvLyAgICAgICAgdGVzdFN0cmluZyA9ICJcdTExMTFcdTExNzEiOworLy8gICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nLCBQYXR0ZXJuLkNBTk9OX0VRKTsKKy8vICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKy8vICAgICAgICBhc3NlcnRGYWxzZShtYXQubWF0Y2hlcygpKTsKKy8vCisvLyAgICAgICAgYmFzZVN0cmluZyA9ICJcdTAwQ0M/Y2RiKGFjKSooXHVENERCKSpbYS1jXSI7CisvLyAgICAgICAgdGVzdFN0cmluZyA9ICJjZGJcdTExMTFcdTExNzFcdTExQjZiIjsKKy8vICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZywgUGF0dGVybi5DQU5PTl9FUSk7CisvLyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisvLyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKy8vCisvLyAgICAgICAgYmFzZVN0cmluZyA9ICJcdUQ0REIiOworLy8gICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nLCBQYXR0ZXJuLkNBTk9OX0VRKTsKKy8vICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcigiYVx1MTExMVx1MTE3MVx1MTFCNmEiKTsKKy8vICAgICAgICBhc3NlcnRUcnVlKG1hdC5maW5kKCkpOworLy8KKy8vICAgICAgICBiYXNlU3RyaW5nID0gIlx1MTExMSI7CisvLyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcsIFBhdHRlcm4uQ0FOT05fRVEpOworLy8gICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKCJiY2RhXHVENERCciIpOworLy8gICAgICAgIGFzc2VydEZhbHNlKG1hdC5maW5kKCkpOworLy8gICAgfQorLy8KKy8vICAgIC8qKgorLy8gICAgICogcyBvcmlnaW5hbCB0ZXN0IHdhcyBmaXhlZCB0byBwYXNzIG9uIFJJCisvLyAgICAgKi8KKy8vCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5kZXhlc0Nhbm9uaWNhbEVxKCkgeworLy8gICAgICAgIFN0cmluZyBiYXNlU3RyaW5nOworLy8gICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nOworLy8gICAgICAgIFBhdHRlcm4gcGF0OworLy8gICAgICAgIE1hdGNoZXIgbWF0OworLy8KKy8vICAgICAgICBiYXNlU3RyaW5nID0gIlx1RDREQiI7CisvLyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKGJhc2VTdHJpbmcsIFBhdHRlcm4uQ0FOT05fRVEpOworLy8gICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKCJiY2RhXHUxMTExXHUxMTcxXHUxMUI2YXdyIik7CisvLyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQuZmluZCgpKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMobWF0LnN0YXJ0KCksIDQpOworLy8gICAgICAgIGFzc2VydEVxdWFscyhtYXQuZW5kKCksIDcpOworLy8KKy8vICAgICAgICAvKgorLy8gICAgICAgICAqIGJhc2VTdHJpbmcgPSAiXHVENERCXHUxMTExXHUxMTcxXHUxMUI2IjsgcGF0ID0KKy8vICAgICAgICAgKiBQYXR0ZXJuLmNvbXBpbGUoYmFzZVN0cmluZywgUGF0dGVybi5DQU5PTl9FUSk7IG1hdCA9CisvLyAgICAgICAgICogcGF0Lm1hdGNoZXIoImJjZGFcdTExMTFcdTExNzFcdTExQjZcdUQ0REJhd3IiKTsKKy8vICAgICAgICAgKiBhc3NlcnRUcnVlKG1hdC5maW5kKCkpOyBhc3NlcnRFcXVhbHMobWF0LnN0YXJ0KCksIDQpOworLy8gICAgICAgICAqIGFzc2VydEVxdWFscyhtYXQuZW5kKCksIDgpOworLy8gICAgICAgICAqCisvLyAgICAgICAgICogYmFzZVN0cmluZyA9ICJcdUQ0REJcdUQyMUVcdTExMTBcdTExNzAiOyB0ZXN0U3RyaW5nID0KKy8vICAgICAgICAgKiAiYWJjYWJjXHUxMTExXHUxMTcxXHUxMUI2XHUxMTEwXHUxMTZEXHUxMUI1XHVEMjY0Y2RiYWMiOyBwYXQgPQorLy8gICAgICAgICAqIFBhdHRlcm4uY29tcGlsZShiYXNlU3RyaW5nLCBQYXR0ZXJuLkNBTk9OX0VRKTsgbWF0ID0KKy8vICAgICAgICAgKiBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsgYXNzZXJ0VHJ1ZShtYXQuZmluZCgpKTsKKy8vICAgICAgICAgKiBhc3NlcnRFcXVhbHMobWF0LnN0YXJ0KCksIDYpOyBhc3NlcnRFcXVhbHMobWF0LmVuZCgpLCAxMyk7CisvLyAgICAgICAgICovfQorLy8KKy8vICAgIC8qKgorLy8gICAgICogcyBvcmlnaW5hbCB0ZXN0IHdhcyBmaXhlZCB0byBwYXNzIG9uIFJJCisvLyAgICAgKi8KKy8vCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2Fub25FcUZsYWdXaXRoU3VwcGxlbWVudGFyeUNoYXJhY3RlcnMoKSB7CisvLworLy8gICAgICAgIC8qCisvLyAgICAgICAgICogXHUxRDFCRi0+XHUxRDFCQlx1MUQxNkYtPlx1MUQxQjlcdTFEMTY1XHUxRDE2RiBpbiBVVEYzMgorLy8gICAgICAgICAqIFx1RDgzNFx1RERCRi0+XHVEODM0XHVEREJCXHVEODM0XHVERDZGCisvLyAgICAgICAgICogLT5cdUQ4MzRcdUREQjlcdUQ4MzRcdURENjVcdUQ4MzRcdURENkYgaW4gVVRGMTYKKy8vICAgICAgICAgKi8KKy8vICAgICAgICBTdHJpbmcgcGF0U3RyaW5nID0gImFiY1x1RDgzNFx1RERCRmVmIjsKKy8vICAgICAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJhYmNcdUQ4MzRcdUREQjlcdUQ4MzRcdURENjVcdUQ4MzRcdURENkZlZiI7CisvLyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUocGF0U3RyaW5nLCBQYXR0ZXJuLkNBTk9OX0VRKTsKKy8vICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworLy8gICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisvLyAgICAgICAgLyoKKy8vICAgICAgICAgKiB0ZXN0U3RyaW5nID0gImFiY1x1RDgzNFx1RERCQlx1RDgzNFx1REQ2RmVmIjsgbWF0ID0KKy8vICAgICAgICAgKiBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKy8vICAgICAgICAgKgorLy8gICAgICAgICAqIHBhdFN0cmluZyA9ICJhYmNcdUQ4MzRcdUREQkJcdUQ4MzRcdURENkZlZiI7IHRlc3RTdHJpbmcgPQorLy8gICAgICAgICAqICJhYmNcdUQ4MzRcdUREQkZlZiI7IHBhdCA9IFBhdHRlcm4uY29tcGlsZShwYXRTdHJpbmcsCisvLyAgICAgICAgICogUGF0dGVybi5DQU5PTl9FUSk7IG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworLy8gICAgICAgICAqIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisvLyAgICAgICAgICovCisvLyAgICAgICAgdGVzdFN0cmluZyA9ICJhYmNcdUQ4MzRcdUREQjlcdUQ4MzRcdURENjVcdUQ4MzRcdURENkZlZiI7CisvLyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisvLyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKy8vICAgICAgICAvKgorLy8gICAgICAgICAqIHBhdFN0cmluZyA9ICJhYmNcdUQ4MzRcdUREQjlcdUQ4MzRcdURENjVcdUQ4MzRcdURENkZlZiI7IHRlc3RTdHJpbmcgPQorLy8gICAgICAgICAqICJhYmNcdUQ4MzRcdUREQkZlZiI7IHBhdCA9IFBhdHRlcm4uY29tcGlsZShwYXRTdHJpbmcsCisvLyAgICAgICAgICogUGF0dGVybi5DQU5PTl9FUSk7IG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworLy8gICAgICAgICAqIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisvLyAgICAgICAgICoKKy8vICAgICAgICAgKiB0ZXN0U3RyaW5nID0gImFiY1x1RDgzNFx1RERCQlx1RDgzNFx1REQ2RmVmIjsgbWF0ID0KKy8vICAgICAgICAgKiBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKy8vICAgICAgICAgKi8KKy8vICAgICAgICAvKgorLy8gICAgICAgICAqIHRlc3RTdXBwbGVtZW50YXJ5IGNoYXJhY3RlcnMgd2l0aCBubyBkZWNvbXBvc2l0aW9uCisvLyAgICAgICAgICovCisvLyAgICAgICAgLyoKKy8vICAgICAgICAgKiBwYXRTdHJpbmcgPSAiYVx1RDlBMFx1REU4RWJjXHVEODM0XHVEREJCXHVEODM0XHVERDZGZVx1REU4RWYiOworLy8gICAgICAgICAqIHRlc3RTdHJpbmcgPSAiYVx1RDlBMFx1REU4RWJjXHVEODM0XHVEREJGZVx1REU4RWYiOyBwYXQgPQorLy8gICAgICAgICAqIFBhdHRlcm4uY29tcGlsZShwYXRTdHJpbmcsIFBhdHRlcm4uQ0FOT05fRVEpOyBtYXQgPQorLy8gICAgICAgICAqIHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOyBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworLy8gICAgICAgICAqL30KKy8vIEVORCBhbmRyb2lkLXJlbW92ZWQKKworICAgIHB1YmxpYyB2b2lkIHRlc3RSYW5nZXNXaXRoU3Vycm9nYXRlc1N1cHBsZW1lbnRhcnkoKSB7CisgICAgICAgIFN0cmluZyBwYXRTdHJpbmcgPSAiW2FiY1x1RDhEMl0iOworICAgICAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJcdUQ4RDIiOworICAgICAgICBQYXR0ZXJuIHBhdCA9IFBhdHRlcm4uY29tcGlsZShwYXRTdHJpbmcpOworICAgICAgICBNYXRjaGVyIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIHRlc3RTdHJpbmcgPSAiYSI7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIHRlc3RTdHJpbmcgPSAiZWZcdUQ4RDJcdURENzFnaCI7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRGYWxzZShtYXQuZmluZCgpKTsKKworICAgICAgICB0ZXN0U3RyaW5nID0gImVmXHVEOEQyZ2giOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQuZmluZCgpKTsKKworICAgICAgICBwYXRTdHJpbmcgPSAiW2FiY1x1RDhEMyYmW2NcdUQ4RDNdXSI7CisgICAgICAgIHRlc3RTdHJpbmcgPSAiYyI7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShwYXRTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICB0ZXN0U3RyaW5nID0gImEiOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWF0Lm1hdGNoZXMoKSk7CisKKyAgICAgICAgdGVzdFN0cmluZyA9ICJlZlx1RDhEM1x1REQ3MWdoIjsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydEZhbHNlKG1hdC5maW5kKCkpOworCisgICAgICAgIHRlc3RTdHJpbmcgPSAiZWZcdUQ4RDNnaCI7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5maW5kKCkpOworCisgICAgICAgIHBhdFN0cmluZyA9ICJbYWJjXHVEOEQzXHVEQkVFXHVERjBDJiZbY1x1RDhEM1x1REJFRVx1REYwQ11dIjsKKyAgICAgICAgdGVzdFN0cmluZyA9ICJjIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKHBhdFN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIHRlc3RTdHJpbmcgPSAiXHVEQkVFXHVERjBDIjsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisKKyAgICAgICAgdGVzdFN0cmluZyA9ICJlZlx1RDhEM1x1REQ3MWdoIjsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydEZhbHNlKG1hdC5maW5kKCkpOworCisgICAgICAgIHRlc3RTdHJpbmcgPSAiZWZcdUQ4RDNnaCI7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5maW5kKCkpOworCisgICAgICAgIHBhdFN0cmluZyA9ICJbYWJjXHVEQkZDXVx1RERDMmNkIjsKKyAgICAgICAgdGVzdFN0cmluZyA9ICJcdURCRkNcdUREQzJjZCI7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShwYXRTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWF0Lm1hdGNoZXMoKSk7CisKKyAgICAgICAgdGVzdFN0cmluZyA9ICJhXHVEREMyY2QiOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VxdWVuY2VzV2l0aFN1cnJvZ2F0ZXNTdXBwbGVtZW50YXJ5KCkgeworICAgICAgICBTdHJpbmcgcGF0U3RyaW5nID0gImFiY2RcdUQ4RDMiOworICAgICAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJhYmNkXHVEOEQzXHVERkZDIjsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUocGF0U3RyaW5nKTsKKyAgICAgICAgTWF0Y2hlciBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKy8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZAorLy8gVGhpcyBvbmUgcmVhbGx5IGRvZXNuJ3QgbWFrZSBzZW5zZSwgYXMgdGhlIGFib3ZlIGlzIGEgY29ycnVwdCBzdXJyb2dhdGUuCisvLyBFdmVuIGlmIGl0J3MgbWF0Y2hlZCBieSB0aGUgSkRLLCBpdCdzIG1vcmUgb2YgYSBidWcgdGhhbiBvZiBhIGJlaGF2aW9yIG9uZQorLy8gbWlnaHQgd2FudCB0byBkdXBsaWNhdGUuCisvLyAgICAgICAgYXNzZXJ0RmFsc2UobWF0LmZpbmQoKSk7CisvLyBFTkQgYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIHRlc3RTdHJpbmcgPSAiYWJjZFx1RDhEM2FiYyI7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5maW5kKCkpOworCisgICAgICAgIHBhdFN0cmluZyA9ICJhYlx1REJFRmNkIjsKKyAgICAgICAgdGVzdFN0cmluZyA9ICJhYlx1REJFRmNkIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKHBhdFN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIHBhdFN0cmluZyA9ICJcdURGRkNhYmNkIjsKKyAgICAgICAgdGVzdFN0cmluZyA9ICJcdUQ4RDNcdURGRkNhYmNkIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKHBhdFN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRGYWxzZShtYXQuZmluZCgpKTsKKworICAgICAgICB0ZXN0U3RyaW5nID0gImFiY1x1REZGQ2FiY2RlY2QiOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQuZmluZCgpKTsKKworICAgICAgICBwYXRTdHJpbmcgPSAiXHVEOEQzXHVERkZDYWJjZCI7CisgICAgICAgIHRlc3RTdHJpbmcgPSAiYWJjXHVEOEQzXHVEOEQzXHVERkZDYWJjZCI7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShwYXRTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQuZmluZCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJlZGVmaW5lZENsYXNzZXNXaXRoU3Vycm9nYXRlc1N1cHBsZW1lbnRhcnkoKSB7CisgICAgICAgIFN0cmluZyBwYXRTdHJpbmcgPSAiWzEyM1xcRF0iOworICAgICAgICBTdHJpbmcgdGVzdFN0cmluZyA9ICJhIjsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUocGF0U3RyaW5nKTsKKyAgICAgICAgTWF0Y2hlciBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQuZmluZCgpKTsKKworICAgICAgICB0ZXN0U3RyaW5nID0gIjUiOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWF0LmZpbmQoKSk7CisKKyAgICAgICAgdGVzdFN0cmluZyA9ICIzIjsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydFRydWUobWF0LmZpbmQoKSk7CisKKyAgICAgICAgLy8gbG93IHN1cnJvZ2F0ZQorICAgICAgICB0ZXN0U3RyaW5nID0gIlx1REZDNCI7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5maW5kKCkpOworCisgICAgICAgIC8vIGhpZ2ggc3Vycm9nYXRlCisgICAgICAgIHRlc3RTdHJpbmcgPSAiXHVEQURBIjsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydFRydWUobWF0LmZpbmQoKSk7CisKKyAgICAgICAgdGVzdFN0cmluZyA9ICJcdURBREFcdURGQzQiOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQuZmluZCgpKTsKKworICAgICAgICBwYXRTdHJpbmcgPSAiWzEyM1teXFxwe2phdmFEaWdpdH1dXSI7CisgICAgICAgIHRlc3RTdHJpbmcgPSAiYSI7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShwYXRTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQuZmluZCgpKTsKKworICAgICAgICB0ZXN0U3RyaW5nID0gIjUiOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWF0LmZpbmQoKSk7CisKKyAgICAgICAgdGVzdFN0cmluZyA9ICIzIjsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydFRydWUobWF0LmZpbmQoKSk7CisKKyAgICAgICAgLy8gbG93IHN1cnJvZ2F0ZQorICAgICAgICB0ZXN0U3RyaW5nID0gIlx1REZDNCI7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5maW5kKCkpOworCisgICAgICAgIC8vIGhpZ2ggc3Vycm9nYXRlCisgICAgICAgIHRlc3RTdHJpbmcgPSAiXHVEQURBIjsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydFRydWUobWF0LmZpbmQoKSk7CisKKyAgICAgICAgdGVzdFN0cmluZyA9ICJcdURBREFcdURGQzQiOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQuZmluZCgpKTsKKworICAgICAgICAvLyBzdXJyb2dhdGUgY2hhcmFjdGVycworICAgICAgICBwYXRTdHJpbmcgPSAiXFxwe0NzfSI7CisgICAgICAgIHRlc3RTdHJpbmcgPSAiXHVEOTE2XHVERTI3IjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKHBhdFN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworCisgICAgICAgIC8qCisgICAgICAgICAqIHNlZSBodHRwOi8vd3d3LnVuaWNvZGUub3JnL3JlcG9ydHMvdHIxOC8jU3VwcGxlbWVudGFyeV9DaGFyYWN0ZXJzIHdlCisgICAgICAgICAqIGhhdmUgdG8gdHJlYXQgdGV4dCBhcyBjb2RlIHBvaW50cyBub3QgY29kZSB1bml0cy4gXFxwe0NzfSBtYXRjaGVzIGFueQorICAgICAgICAgKiBzdXJyb2dhdGUgY2hhcmFjdGVyIGJ1dCBoZXJlIHRlc3RTdHJpbmcgaXMgYSBvbmUgY29kZSBwb2ludAorICAgICAgICAgKiBjb25zaXN0aW5nIG9mIHR3byBjb2RlIHVuaXRzICh0d28gc3Vycm9nYXRlIGNoYXJhY3RlcnMpIHNvIHdlIGZpbmQKKyAgICAgICAgICogbm90aGluZworICAgICAgICAgKi8KKyAgICAgICAgLy8gYXNzZXJ0RmFsc2UobWF0LmZpbmQoKSk7CisgICAgICAgIC8vIHN3YXAgbG93IGFuZCBoaWdoIHN1cnJvZ2F0ZXMKKyAgICAgICAgdGVzdFN0cmluZyA9ICJcdURFMjdcdUQ5MTYiOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQuZmluZCgpKTsKKworICAgICAgICBwYXRTdHJpbmcgPSAiW1x1RDkxNlx1REUyNzFcdUQ5MTYyMyYmW15cXHB7Q3N9XV0iOworICAgICAgICB0ZXN0U3RyaW5nID0gIjEiOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUocGF0U3RyaW5nKTsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydFRydWUobWF0LmZpbmQoKSk7CisKKyAgICAgICAgdGVzdFN0cmluZyA9ICJcdUQ5MTYiOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUocGF0U3RyaW5nKTsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydEZhbHNlKG1hdC5maW5kKCkpOworCisgICAgICAgIHRlc3RTdHJpbmcgPSAiXHVEOTE2XHVERTI3IjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKHBhdFN0cmluZyk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5maW5kKCkpOworCisgICAgICAgIC8vIFx1RDlBMFx1REU4RT1cdTc4MjhFCisgICAgICAgIC8vIFx1NzgyODE9XHVEOUEwXHVERTgxCisgICAgICAgIHBhdFN0cmluZyA9ICJbYS1cdUQ5QTBcdURFOEVdIjsKKyAgICAgICAgdGVzdFN0cmluZyA9ICJcdUQ5QTBcdURFODEiOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUocGF0U3RyaW5nKTsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERvdENvbnN0cnVjdGlvbldpdGhTdXJyb2dhdGVzU3VwcGxlbWVudGFyeSgpIHsKKyAgICAgICAgU3RyaW5nIHBhdFN0cmluZyA9ICIuIjsKKyAgICAgICAgU3RyaW5nIHRlc3RTdHJpbmcgPSAiXHVEOUEwXHVERTgxIjsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUocGF0U3RyaW5nKTsKKyAgICAgICAgTWF0Y2hlciBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICB0ZXN0U3RyaW5nID0gIlx1REU4MSI7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIHRlc3RTdHJpbmcgPSAiXHVEOUEwIjsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisKKyAgICAgICAgdGVzdFN0cmluZyA9ICJcbiI7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRGYWxzZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBwYXRTdHJpbmcgPSAiLipcdURFODEiOworICAgICAgICB0ZXN0U3RyaW5nID0gIlx1RDlBMFx1REU4MVx1RDlBMFx1REU4MVx1RDlBMFx1REU4MSI7CisgICAgICAgIHBhdCA9IFBhdHRlcm4uY29tcGlsZShwYXRTdHJpbmcpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWF0Lm1hdGNoZXMoKSk7CisKKyAgICAgICAgdGVzdFN0cmluZyA9ICJcdUQ5QTBcdURFODFcdUQ5QTBcdURFODFcdURFODEiOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICBwYXRTdHJpbmcgPSAiLioiOworICAgICAgICB0ZXN0U3RyaW5nID0gIlx1RDlBMFx1REU4MVxuXHVEOUEwXHVERTgxXHVEOUEwXG5cdURFODEiOworICAgICAgICBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUocGF0U3RyaW5nLCBQYXR0ZXJuLkRPVEFMTCk7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcXVvdGVMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgZm9yIChTdHJpbmcgYVBhdHRlcm4gOiB0ZXN0UGF0dGVybnMpIHsKKyAgICAgICAgICAgIFBhdHRlcm4gcCA9IFBhdHRlcm4uY29tcGlsZShhUGF0dGVybik7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygicXVvdGUgd2FzIHdyb25nIGZvciBwbGFpbiB0ZXh0IiwgIlxcUXRlc3RcXEUiLCBwCisgICAgICAgICAgICAgICAgICAgICAgICAucXVvdGUoInRlc3QiKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJxdW90ZSB3YXMgd3JvbmcgZm9yIHRleHQgd2l0aCBxdW90ZSBzaWduIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJcXFFcXFF0ZXN0XFxFIiwgcC5xdW90ZSgiXFxRdGVzdCIpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInF1b3RlIHdhcyB3cm9uZyBmb3IgcXVvdHRlZCB0ZXh0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJcXFFcXFF0ZXN0XFxFXFxcXEVcXFFcXEUiLCBwLnF1b3RlKCJcXFF0ZXN0XFxFIikpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9tYXRjaGVyTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX0NoYXJTZXF1ZW5jZSgpIHsKKyAgICAgICAgU3RyaW5nW11bXSBwb3NTZXEgPSB7CisgICAgICAgICAgICAgICAgeyAiYWJiIiwgImFiYWJiIiwgImFiYWJhYmJhYmFiYiIsICJhYmFiYWJiYWJhYmJhYmFiYWJiYmJiYWJiIiB9LAorICAgICAgICAgICAgICAgIHsgIjIxMzU2NyIsICIxMjMyNDU2NyIsICIxMjM0NTY3IiwgIjIxMzIxMzU2NyIsCisgICAgICAgICAgICAgICAgICAgICAgICAiMjEzMTIzMTIzMTI1NjciLCAiNDQ0NDQ0NTY3IiB9LAorICAgICAgICAgICAgICAgIHsgImFiY2RhYWIiLCAiYWFiIiwgImFiYWFiIiwgImNkYWFiIiwgImFjYmRhZGNiYWFiIiB9LAorICAgICAgICAgICAgICAgIHsgIjIxMzIzNDU2NyIsICIzNDU4IiwgIjA5ODc2NTQiLCAiNzY4OTU0NjQzMiIsICIwMzk4NTc2IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICI5ODQzMiIsICI1IiB9LAorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaIiB9LAorICAgICAgICAgICAgICAgIHsgImFiYWJiYUFhYmFiYWJibGljZSIsICJhYmFiYmFBbGljZWFiYWJhYiIsICJhYmFiYkFhYmxpY2VhYWEiLAorICAgICAgICAgICAgICAgICAgICAgICAgImFiYmJBYmJibGljZWFhYSIsICJBbGljZSIgfSwKKyAgICAgICAgICAgICAgICB7ICJhMTIzIiwgImJueG52Z2RzMTU2IiwgImZvciIsICJ3aGlsZSIsICJpZiIsICJzdHJ1Y3QiIH0sCisgICAgICAgICAgICAgICAgeyAieHkiIH0sIHsgInh5IiB9LCB7ICJ4Y3kiIH0KKworICAgICAgICB9OworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGVzdFBhdHRlcm5zLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHBvc1NlcVtpXS5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBtYXRjaDogIiArIHRlc3RQYXR0ZXJuc1tpXSArICIgdnMgIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBwb3NTZXFbaV1bal0sIFBhdHRlcm4uY29tcGlsZSh0ZXN0UGF0dGVybnNbaV0pCisgICAgICAgICAgICAgICAgICAgICAgICAubWF0Y2hlcihwb3NTZXFbaV1bal0pLm1hdGNoZXMoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UXVhbnRpZmllcnNXaXRoU3Vycm9nYXRlc1N1cHBsZW1lbnRhcnkoKSB7CisgICAgICAgIFN0cmluZyBwYXRTdHJpbmcgPSAiXHVEOUEwXHVERTgxKmFiYyI7CisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gIlx1RDlBMFx1REU4MVx1RDlBMFx1REU4MWFiYyI7CisgICAgICAgIFBhdHRlcm4gcGF0ID0gUGF0dGVybi5jb21waWxlKHBhdFN0cmluZyk7CisgICAgICAgIE1hdGNoZXIgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisKKyAgICAgICAgdGVzdFN0cmluZyA9ICJhYmMiOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWx0ZXJuYXRpb25zV2l0aFN1cnJvZ2F0ZXNTdXBwbGVtZW50YXJ5KCkgeworICAgICAgICBTdHJpbmcgcGF0U3RyaW5nID0gIlx1REU4MXxcdUQ5QTBcdURFODF8XHVEOUEwIjsKKyAgICAgICAgU3RyaW5nIHRlc3RTdHJpbmcgPSAiXHVEOUEwIjsKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUocGF0U3RyaW5nKTsKKyAgICAgICAgTWF0Y2hlciBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXQubWF0Y2hlcygpKTsKKworICAgICAgICB0ZXN0U3RyaW5nID0gIlx1REU4MSI7CisgICAgICAgIG1hdCA9IHBhdC5tYXRjaGVyKHRlc3RTdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIHRlc3RTdHJpbmcgPSAiXHVEOUEwXHVERTgxIjsKKyAgICAgICAgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydFRydWUobWF0Lm1hdGNoZXMoKSk7CisKKyAgICAgICAgdGVzdFN0cmluZyA9ICJcdURFODFcdUQ5QTAiOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWF0Lm1hdGNoZXMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdyb3Vwc1dpdGhTdXJyb2dhdGVzU3VwcGxlbWVudGFyeSgpIHsKKworICAgICAgICAvL3RoaXMgcGF0dGVybiBtYXRjaGVzIG5vdGhpbmcKKyAgICAgICAgU3RyaW5nIHBhdFN0cmluZyA9ICIoXHVEOUEwKVx1REU4MSI7CisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gIlx1RDlBMFx1REU4MSI7CisgICAgICAgIFBhdHRlcm4gcGF0ID0gUGF0dGVybi5jb21waWxlKHBhdFN0cmluZyk7CisgICAgICAgIE1hdGNoZXIgbWF0ID0gcGF0Lm1hdGNoZXIodGVzdFN0cmluZyk7CisgICAgICAgIGFzc2VydEZhbHNlKG1hdC5tYXRjaGVzKCkpOworCisgICAgICAgIHBhdFN0cmluZyA9ICIoXHVEOUEwKSI7CisgICAgICAgIHRlc3RTdHJpbmcgPSAiXHVEOUEwXHVERTgxIjsKKyAgICAgICAgcGF0ID0gUGF0dGVybi5jb21waWxlKHBhdFN0cmluZywgUGF0dGVybi5ET1RBTEwpOworICAgICAgICBtYXQgPSBwYXQubWF0Y2hlcih0ZXN0U3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWF0LmZpbmQoKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBSZWdyZXNzaW9uIHRlc3QgZm9yIEhBUk1PTlktNjg4CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVuaWNvZGVDYXRlZ29yeVdpdGhTdXJyb2dhdGVzU3VwcGxlbWVudGFyeSgpIHsKKyAgICAgICAgUGF0dGVybiBwID0gUGF0dGVybi5jb21waWxlKCJcXHB7amF2YUxvd2VyQ2FzZX0iKTsKKyAgICAgICAgTWF0Y2hlciBtYXRjaGVyID0gcC5tYXRjaGVyKCJcdUQ4MDFcdURDMjgiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtYXRjaGVyLmZpbmQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNwbGl0RW1wdHkoKSB7CisKKyAgICAgICAgUGF0dGVybiBwYXQgPSBQYXR0ZXJuLmNvbXBpbGUoIiIpOworICAgICAgICBTdHJpbmdbXSBzID0gcGF0LnNwbGl0KCIiLCAtMSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBzWzBdKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9TdHJpbmcoKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGVzdFBhdHRlcm5zLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBQYXR0ZXJuIHAgPSBQYXR0ZXJuLmNvbXBpbGUodGVzdFBhdHRlcm5zW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0ZXN0UGF0dGVybnNbaV0sIHAudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvcmVnZXgvdGVzdHMvamF2YS91dGlsL3JlZ2V4L1JlcGxhY2VUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3JlZ2V4L3Rlc3RzL2phdmEvdXRpbC9yZWdleC9SZXBsYWNlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2MDliYjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3JlZ2V4L3Rlc3RzL2phdmEvdXRpbC9yZWdleC9SZXBsYWNlVGVzdC5qYXZhCkBAIC0wLDAgKzEsODUgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnJlZ2V4LnRlc3RzLmphdmEudXRpbC5yZWdleDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguTWF0Y2hlcjsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVyblN5bnRheEV4Y2VwdGlvbjsKKworcHVibGljIGNsYXNzIFJlcGxhY2VUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RTaW1wbGVSZXBsYWNlKCkgdGhyb3dzIFBhdHRlcm5TeW50YXhFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgdGFyZ2V0LCBwYXR0ZXJuLCByZXBsOworCisgICAgICAgIHRhcmdldCA9ICJmb29iYXJmb2JhcmZvb2ZvMWJhcmZvcnQiOworICAgICAgICBwYXR0ZXJuID0gImZvW15vXSI7CisgICAgICAgIHJlcGwgPSAieHh4IjsKKworICAgICAgICBQYXR0ZXJuIHAgPSBQYXR0ZXJuLmNvbXBpbGUocGF0dGVybik7CisgICAgICAgIE1hdGNoZXIgbSA9IHAubWF0Y2hlcih0YXJnZXQpOworCisgICAgICAgIGFzc2VydEVxdWFscygiZm9vYmFyeHh4YXJmb29mbzFiYXJmb3J0IiwgbS5yZXBsYWNlRmlyc3QocmVwbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZvb2Jhcnh4eGFyZm9veHh4YmFyeHh4dCIsIG0ucmVwbGFjZUFsbChyZXBsKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENhcHR1cmVSZXBsYWNlKCkgeworICAgICAgICBTdHJpbmcgdGFyZ2V0LCBwYXR0ZXJuLCByZXBsLCBzOworICAgICAgICBQYXR0ZXJuIHAgPSBudWxsOworICAgICAgICBNYXRjaGVyIG07CisKKyAgICAgICAgdGFyZ2V0ID0gIlszMV1mb287YmFyWzQyXTtbOTldeHl6IjsKKyAgICAgICAgcGF0dGVybiA9ICJcXFsoWzAtOV0rKVxcXShbYS16XSspIjsKKyAgICAgICAgcmVwbCA9ICIkMlskMV0iOworCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUocGF0dGVybik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIodGFyZ2V0KTsKKyAgICAgICAgcyA9IG0ucmVwbGFjZUZpcnN0KHJlcGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZvb1szMV07YmFyWzQyXTtbOTldeHl6Iiwgcyk7CisgICAgICAgIHMgPSBtLnJlcGxhY2VBbGwocmVwbCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vWzMxXTtiYXJbNDJdO3h5els5OV0iLCBzKTsKKworICAgICAgICB0YXJnZXQgPSAiWzMxXWZvbyg0MiliYXJ7NjN9em9vO1sxMl1hYmMoMzQpZGVmezU2fWdoaTt7OTl9eHl6Wzg4XXh5eig3Nyl4eXo7IjsKKyAgICAgICAgcGF0dGVybiA9ICJcXFsoWzAtOV0rKVxcXShbYS16XSspXFwoKFswLTldKylcXCkoW2Etel0rKVxceyhbMC05XSspXFx9KFthLXpdKykiOworICAgICAgICByZXBsID0gIlskNV0kNigkMykkNHskMX0kMiI7CisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUocGF0dGVybik7CisgICAgICAgIG0gPSBwLm1hdGNoZXIodGFyZ2V0KTsKKyAgICAgICAgcyA9IG0ucmVwbGFjZUZpcnN0KHJlcGwpOworICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4ocyk7CisgICAgICAgIGFzc2VydEVxdWFscygiWzYzXXpvbyg0MiliYXJ7MzF9Zm9vO1sxMl1hYmMoMzQpZGVmezU2fWdoaTt7OTl9eHl6Wzg4XXh5eig3Nyl4eXo7IiwgcworICAgICAgICAgICAgICAgICk7CisgICAgICAgIHMgPSBtLnJlcGxhY2VBbGwocmVwbCk7CisgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJbNjNdem9vKDQyKWJhcnszMX1mb287WzU2XWdoaSgzNClkZWZ7MTJ9YWJjO3s5OX14eXpbODhdeHl6KDc3KXh5ejsiLCBzCisgICAgICAgICAgICAgICAgKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXNjYXBlUmVwbGFjZSgpIHsKKyAgICAgICAgU3RyaW5nIHRhcmdldCwgcGF0dGVybiwgcmVwbCwgczsKKworICAgICAgICB0YXJnZXQgPSAiZm9vJ2JhcicnZm9vIjsKKyAgICAgICAgcGF0dGVybiA9ICInIjsKKyAgICAgICAgcmVwbCA9ICJcXCciOworICAgICAgICBzID0gdGFyZ2V0LnJlcGxhY2VBbGwocGF0dGVybiwgcmVwbCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vJ2JhcicnZm9vIiwgcyk7CisgICAgICAgIHJlcGwgPSAiXFxcXCciOworICAgICAgICBzID0gdGFyZ2V0LnJlcGxhY2VBbGwocGF0dGVybiwgcmVwbCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vXFwnYmFyXFwnXFwnZm9vIiwgcyk7CisgICAgICAgIHJlcGwgPSAiXFwkMyI7CisgICAgICAgIHMgPSB0YXJnZXQucmVwbGFjZUFsbChwYXR0ZXJuLCByZXBsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28kM2JhciQzJDNmb28iLCBzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3JlZ2V4L3Rlc3RzL2phdmEvdXRpbC9yZWdleC9TcGxpdFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvcmVnZXgvdGVzdHMvamF2YS91dGlsL3JlZ2V4L1NwbGl0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE2Y2ExMjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3JlZ2V4L3Rlc3RzL2phdmEvdXRpbC9yZWdleC9TcGxpdFRlc3QuamF2YQpAQCAtMCwwICsxLDE5NyBAQAorcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkucmVnZXgudGVzdHMuamF2YS51dGlsLnJlZ2V4OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGphdmEudXRpbC5yZWdleC4qOworCisvKioKKyAqIFRPRE8gVHlwZSBkZXNjcmlwdGlvbgorICoKKyAqLworcHVibGljIGNsYXNzIFNwbGl0VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2ltcGxlKCkgeworICAgICAgICBQYXR0ZXJuIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIi8iKTsKKyAgICAgICAgU3RyaW5nW10gcmVzdWx0cyA9IHAuc3BsaXQoImhhdmUveW91L2RvbmUvaXQvcmlnaHQiKTsKKyAgICAgICAgU3RyaW5nW10gZXhwZWN0ZWQgPSBuZXcgU3RyaW5nW10geyAiaGF2ZSIsICJ5b3UiLCAiZG9uZSIsICJpdCIsICJyaWdodCIgfTsKKyAgICAgICAgYXNzZXJ0QXJyYXlzRXF1YWwoZXhwZWN0ZWQsIHJlc3VsdHMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eVNwbGl0cygpIHsKKyAgICAgICAgLy8gVHJhaWxpbmcgZW1wdHkgbWF0Y2hlcyBhcmUgcmVtb3ZlZC4KKyAgICAgICAgYXNzZXJ0QXJyYXlzRXF1YWwobmV3IFN0cmluZ1swXSwgImhlbGxvIi5zcGxpdCgiLiIpKTsKKyAgICAgICAgYXNzZXJ0QXJyYXlzRXF1YWwobmV3IFN0cmluZ1tdIHsgIjEiLCAiMiIgfSwgIjE6MjoiLnNwbGl0KCI6IikpOworICAgICAgICAvLyAuLi5pbmNsdWRpbmcgd2hlbiB0aGF0IHJlc3VsdHMgaW4gYW4gZW1wdHkgcmVzdWx0LgorICAgICAgICBhc3NlcnRBcnJheXNFcXVhbChuZXcgU3RyaW5nWzBdLCAiOiIuc3BsaXQoIjoiKSk7CisgICAgICAgIC8vIC4uLmJ1dCBub3Qgd2hlbiBsaW1pdCA8IDAuCisgICAgICAgIGFzc2VydEFycmF5c0VxdWFsKG5ldyBTdHJpbmdbXSB7ICIxIiwgIjIiLCAiIiB9LCAiMToyOiIuc3BsaXQoIjoiLCAtMSkpOworCisgICAgICAgIC8vIExlYWRpbmcgZW1wdHkgbWF0Y2hlcyBhcmUgcmV0YWluZWQuCisgICAgICAgIGFzc2VydEFycmF5c0VxdWFsKG5ldyBTdHJpbmdbXSB7ICIiLCAiIiwgIm8iIH0sICJoZWxsbyIuc3BsaXQoIi4uIikpOworCisgICAgICAgIC8vIEEgc2VwYXJhdG9yIHRoYXQgZG9lc24ndCBvY2N1ciBpbiB0aGUgaW5wdXQgZ2V0cyB5b3UgdGhlIGlucHV0LgorICAgICAgICBhc3NlcnRBcnJheXNFcXVhbChuZXcgU3RyaW5nW10geyAiaGVsbG8iIH0sICJoZWxsbyIuc3BsaXQoIm5vdC1wcmVzZW50LWluLXRlc3QiKSk7CisgICAgICAgIC8vIC4uLmluY2x1ZGluZyB3aGVuIHRoZSBpbnB1dCBpcyB0aGUgZW1wdHkgc3RyaW5nLgorICAgICAgICAvLyAoUGVybCByZXR1cm5zIGFuIGVtcHR5IGxpc3QgaW5zdGVhZC4pCisgICAgICAgIGFzc2VydEFycmF5c0VxdWFsKG5ldyBTdHJpbmdbXSB7ICIiIH0sICIiLnNwbGl0KCJub3QtcHJlc2VudC1pbi10ZXN0IikpOworICAgICAgICBhc3NlcnRBcnJheXNFcXVhbChuZXcgU3RyaW5nW10geyAiIiB9LCAiIi5zcGxpdCgiQT8iKSk7CisKKyAgICAgICAgLy8gVGhlIGxpbWl0IGFyZ3VtZW50IGNvbnRyb2xzIHRoZSBzaXplIG9mIHRoZSByZXN1bHQuCisgICAgICAgIC8vIElmIGwgPT0gMCwgdGhlIHJlc3VsdCBpcyBhcyBsb25nIGFzIG5lZWRlZCwgZXhjZXB0IHRyYWlsaW5nIGVtcHR5IG1hdGNoZXMgYXJlIGRyb3BwZWQuCisgICAgICAgIC8vIElmIGwgPCAwLCB0aGUgcmVzdWx0IGlzIGFzIGxvbmcgYXMgbmVlZGVkLCBhbmQgdHJhaWxpbmcgZW1wdHkgbWF0Y2hlcyBhcmUgcmV0YWluZWQuCisgICAgICAgIC8vIElmIGwgPiAwLCB0aGUgcmVzdWx0IGNvbnRhaW5zIHRoZSBmaXJzdCBsIG1hdGNoZXMsIHBsdXMgb25lIHN0cmluZyBjb250YWluaW5nIHRoZSByZW1haW5pbmcgaW5wdXQuCisgICAgICAgIC8vIEV4YW1wbGVzIHdpdGhvdXQgYSB0cmFpbGluZyBzZXBhcmF0b3IgKGFuZCBoZW5jZSB3aXRob3V0IGEgdHJhaWxpbmcgZW1wdHkgbWF0Y2gpOgorICAgICAgICBhc3NlcnRBcnJheXNFcXVhbChuZXcgU3RyaW5nW10geyAiYSIsICJiIiwgImMiIH0sICJhLGIsYyIuc3BsaXQoIiwiLCAwKSk7CisgICAgICAgIGFzc2VydEFycmF5c0VxdWFsKG5ldyBTdHJpbmdbXSB7ICJhLGIsYyIgfSwgImEsYixjIi5zcGxpdCgiLCIsIDEpKTsKKyAgICAgICAgYXNzZXJ0QXJyYXlzRXF1YWwobmV3IFN0cmluZ1tdIHsgImEiLCAiYixjIiB9LCAiYSxiLGMiLnNwbGl0KCIsIiwgMikpOworICAgICAgICBhc3NlcnRBcnJheXNFcXVhbChuZXcgU3RyaW5nW10geyAiYSIsICJiIiwgImMiIH0sICJhLGIsYyIuc3BsaXQoIiwiLCAzKSk7CisgICAgICAgIGFzc2VydEFycmF5c0VxdWFsKG5ldyBTdHJpbmdbXSB7ICJhIiwgImIiLCAiYyIgfSwgImEsYixjIi5zcGxpdCgiLCIsIEludGVnZXIuTUFYX1ZBTFVFKSk7CisgICAgICAgIC8vIEV4YW1wbGVzIHdpdGggYSB0cmFpbGluZyBzZXBhcmF0b3IgKGFuZCBoZW5jZSBwb3NzaWJseSB3aXRoIGEgdHJhaWxpbmcgZW1wdHkgbWF0Y2gpOgorICAgICAgICBhc3NlcnRBcnJheXNFcXVhbChuZXcgU3RyaW5nW10geyAiYSIsICJiIiwgImMiIH0sICJhLGIsYywiLnNwbGl0KCIsIiwgMCkpOworICAgICAgICBhc3NlcnRBcnJheXNFcXVhbChuZXcgU3RyaW5nW10geyAiYSxiLGMsIiB9LCAiYSxiLGMsIi5zcGxpdCgiLCIsIDEpKTsKKyAgICAgICAgYXNzZXJ0QXJyYXlzRXF1YWwobmV3IFN0cmluZ1tdIHsgImEiLCAiYixjLCIgfSwgImEsYixjLCIuc3BsaXQoIiwiLCAyKSk7CisgICAgICAgIGFzc2VydEFycmF5c0VxdWFsKG5ldyBTdHJpbmdbXSB7ICJhIiwgImIiLCAiYywiIH0sICJhLGIsYywiLnNwbGl0KCIsIiwgMykpOworICAgICAgICBhc3NlcnRBcnJheXNFcXVhbChuZXcgU3RyaW5nW10geyAiYSIsICJiIiwgImMiLCAiIiB9LCAiYSxiLGMsIi5zcGxpdCgiLCIsIEludGVnZXIuTUFYX1ZBTFVFKSk7CisgICAgICAgIGFzc2VydEFycmF5c0VxdWFsKG5ldyBTdHJpbmdbXSB7ICJhIiwgImIiLCAiYyIsICIiIH0sICJhLGIsYywiLnNwbGl0KCIsIiwgLTEpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0QXJyYXlzRXF1YWwoU3RyaW5nW10gZXhwZWN0ZWQsIFN0cmluZ1tdIGFjdHVhbCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQubGVuZ3RoLCBhY3R1YWwubGVuZ3RoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHBlY3RlZC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEludGVnZXIudG9TdHJpbmcoaSksIGV4cGVjdGVkW2ldLCBhY3R1YWxbaV0pOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNwbGl0MSgpIHRocm93cyBQYXR0ZXJuU3ludGF4RXhjZXB0aW9uIHsKKyAgICAgICAgUGF0dGVybiBwID0gUGF0dGVybi5jb21waWxlKCIgIik7CisKKyAgICAgICAgU3RyaW5nIGlucHV0ID0gInBvb2RsZSB6b28iOworICAgICAgICBTdHJpbmcgdG9rZW5zW107CisKKyAgICAgICAgdG9rZW5zID0gcC5zcGxpdChpbnB1dCwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCB0b2tlbnMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0b2tlbnNbMF0uZXF1YWxzKGlucHV0KSk7CisgICAgICAgIHRva2VucyA9IHAuc3BsaXQoaW5wdXQsIDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgdG9rZW5zLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygicG9vZGxlIiwgdG9rZW5zWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ6b28iLCB0b2tlbnNbMV0pOworICAgICAgICB0b2tlbnMgPSBwLnNwbGl0KGlucHV0LCA1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHRva2Vucy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoInBvb2RsZSIsIHRva2Vuc1swXSk7CisgICAgICAgIGFzc2VydEVxdWFscygiem9vIiwgdG9rZW5zWzFdKTsKKyAgICAgICAgdG9rZW5zID0gcC5zcGxpdChpbnB1dCwgLTIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgdG9rZW5zLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygicG9vZGxlIiwgdG9rZW5zWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ6b28iLCB0b2tlbnNbMV0pOworICAgICAgICB0b2tlbnMgPSBwLnNwbGl0KGlucHV0LCAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHRva2Vucy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoInBvb2RsZSIsIHRva2Vuc1swXSk7CisgICAgICAgIGFzc2VydEVxdWFscygiem9vIiwgdG9rZW5zWzFdKTsKKyAgICAgICAgdG9rZW5zID0gcC5zcGxpdChpbnB1dCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCB0b2tlbnMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwb29kbGUiLCB0b2tlbnNbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoInpvbyIsIHRva2Vuc1sxXSk7CisKKyAgICAgICAgcCA9IFBhdHRlcm4uY29tcGlsZSgiZCIpOworCisgICAgICAgIHRva2VucyA9IHAuc3BsaXQoaW5wdXQsIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgdG9rZW5zLmxlbmd0aCk7CisgICAgICAgIGFzc2VydFRydWUodG9rZW5zWzBdLmVxdWFscyhpbnB1dCkpOworICAgICAgICB0b2tlbnMgPSBwLnNwbGl0KGlucHV0LCAyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHRva2Vucy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoInBvbyIsIHRva2Vuc1swXSk7CisgICAgICAgIGFzc2VydEVxdWFscygibGUgem9vIiwgdG9rZW5zWzFdKTsKKyAgICAgICAgdG9rZW5zID0gcC5zcGxpdChpbnB1dCwgNSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCB0b2tlbnMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwb28iLCB0b2tlbnNbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoImxlIHpvbyIsIHRva2Vuc1sxXSk7CisgICAgICAgIHRva2VucyA9IHAuc3BsaXQoaW5wdXQsIC0yKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHRva2Vucy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoInBvbyIsIHRva2Vuc1swXSk7CisgICAgICAgIGFzc2VydEVxdWFscygibGUgem9vIiwgdG9rZW5zWzFdKTsKKyAgICAgICAgdG9rZW5zID0gcC5zcGxpdChpbnB1dCwgMCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCB0b2tlbnMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwb28iLCB0b2tlbnNbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoImxlIHpvbyIsIHRva2Vuc1sxXSk7CisgICAgICAgIHRva2VucyA9IHAuc3BsaXQoaW5wdXQpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgdG9rZW5zLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygicG9vIiwgdG9rZW5zWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJsZSB6b28iLCB0b2tlbnNbMV0pOworCisgICAgICAgIHAgPSBQYXR0ZXJuLmNvbXBpbGUoIm8iKTsKKworICAgICAgICB0b2tlbnMgPSBwLnNwbGl0KGlucHV0LCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHRva2Vucy5sZW5ndGgpOworICAgICAgICBhc3NlcnRUcnVlKHRva2Vuc1swXS5lcXVhbHMoaW5wdXQpKTsKKyAgICAgICAgdG9rZW5zID0gcC5zcGxpdChpbnB1dCwgMik7CisgICAgICAgIGFzc2VydEVxdWFscygyLCB0b2tlbnMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwIiwgdG9rZW5zWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJvZGxlIHpvbyIsIHRva2Vuc1sxXSk7CisgICAgICAgIHRva2VucyA9IHAuc3BsaXQoaW5wdXQsIDUpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgdG9rZW5zLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygicCIsIHRva2Vuc1swXSk7CisgICAgICAgIGFzc2VydFRydWUodG9rZW5zWzFdLmVxdWFscygiIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRsZSB6IiwgdG9rZW5zWzJdKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0b2tlbnNbM10uZXF1YWxzKCIiKSk7CisgICAgICAgIGFzc2VydFRydWUodG9rZW5zWzRdLmVxdWFscygiIikpOworICAgICAgICB0b2tlbnMgPSBwLnNwbGl0KGlucHV0LCAtMik7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCB0b2tlbnMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwIiwgdG9rZW5zWzBdKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0b2tlbnNbMV0uZXF1YWxzKCIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZGxlIHoiLCB0b2tlbnNbMl0pOworICAgICAgICBhc3NlcnRUcnVlKHRva2Vuc1szXS5lcXVhbHMoIiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0b2tlbnNbNF0uZXF1YWxzKCIiKSk7CisgICAgICAgIHRva2VucyA9IHAuc3BsaXQoaW5wdXQsIDApOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgdG9rZW5zLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygicCIsIHRva2Vuc1swXSk7CisgICAgICAgIGFzc2VydFRydWUodG9rZW5zWzFdLmVxdWFscygiIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRsZSB6IiwgdG9rZW5zWzJdKTsKKyAgICAgICAgdG9rZW5zID0gcC5zcGxpdChpbnB1dCk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCB0b2tlbnMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwIiwgdG9rZW5zWzBdKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0b2tlbnNbMV0uZXF1YWxzKCIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZGxlIHoiLCB0b2tlbnNbMl0pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTcGxpdDIoKSB7CisgICAgICAgIFBhdHRlcm4gcCA9IFBhdHRlcm4uY29tcGlsZSgiIik7CisgICAgICAgIFN0cmluZyBzW107CisgICAgICAgIHMgPSBwLnNwbGl0KCJhIiwgLTEpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgcy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHNbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBzWzFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBzWzJdKTsKKworICAgICAgICBzID0gcC5zcGxpdCgiIiwgLTEpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgcy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHNbMF0pOworCisgICAgICAgIHMgPSBwLnNwbGl0KCJhYmNkIiwgLTEpOworICAgICAgICBhc3NlcnRFcXVhbHMoNiwgcy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHNbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBzWzFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiIiwgc1syXSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYyIsIHNbM10pOworICAgICAgICBhc3NlcnRFcXVhbHMoImQiLCBzWzRdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBzWzVdKTsKKworICAgICAgICAvLyBSZWdyZXNzaW9uIHRlc3QgZm9yIEFuZHJvaWQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHT09HLDIzLDUwMCIuc3BsaXQoInwiKS5sZW5ndGgsIDEyKTsKKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3RTcGxpdFN1cHBsZW1lbnRhcnlXaXRoRW1wdHlTdHJpbmcoKSB7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogU2VlIGh0dHA6Ly93d3cudW5pY29kZS5vcmcvcmVwb3J0cy90cjE4LyNTdXBwbGVtZW50YXJ5X0NoYXJhY3RlcnMKKyAgICAgICAgICogV2UgaGF2ZSB0byB0cmVhdCB0ZXh0IGFzIGNvZGUgcG9pbnRzIG5vdCBjb2RlIHVuaXRzLgorICAgICAgICAgKi8KKyAgICAgICAgUGF0dGVybiBwID0gUGF0dGVybi5jb21waWxlKCIiKTsKKyAgICAgICAgU3RyaW5nIHNbXTsKKyAgICAgICAgcyA9IHAuc3BsaXQoImFcdWQ4NjlcdWRlZDZiIiwgLTEpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgcy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIHNbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoImEiLCBzWzFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJcdWQ4NjlcdWRlZDYiLCBzWzJdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiIiwgc1szXSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgc1s0XSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcjFUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yMVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MmFlNThlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcjFUZXN0LmphdmEKQEAgLTAsMCArMSwzOTEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yU3BpOworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuTXlBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JTcGk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuU3BpRW5nVXRpbHM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZAorICogbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IxVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIGludmFsaWRWYWx1ZXMgPSBTcGlFbmdVdGlscy5pbnZhbGlkVmFsdWVzOworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB2YWxpZEFsZ05hbWUgPSAiRFNBIjsKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBhbGdzID0gIHsKKyAgICAgICAgICAgICJEU0EiLCAiZHNhIiwgIkRzYSIsICJEc0EiLCAiZHNBIiB9OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgc3J2QWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yID0gIkFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvciI7CisKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB2YWxpZFByb3ZpZGVyTmFtZSA9IG51bGw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBQcm92aWRlciB2YWxpZFByb3ZpZGVyID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gRFNBU3VwcG9ydGVkID0gZmFsc2U7CisKKyAgICBzdGF0aWMgeworICAgICAgICB2YWxpZFByb3ZpZGVyID0gU3BpRW5nVXRpbHMuaXNTdXBwb3J0KAorICAgICAgICAgICAgICAgIHZhbGlkQWxnTmFtZSwKKyAgICAgICAgICAgICAgICBzcnZBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IpOworICAgICAgICBEU0FTdXBwb3J0ZWQgPSAodmFsaWRQcm92aWRlciAhPSBudWxsKTsKKyAgICAgICAgdmFsaWRQcm92aWRlck5hbWUgPSAoRFNBU3VwcG9ydGVkID8gdmFsaWRQcm92aWRlci5nZXROYW1lKCkgOiBudWxsKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yW10gY3JlYXRlQVBHZW4oKSB7CisgICAgICAgIGlmICghRFNBU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKHZhbGlkQWxnTmFtZSArICIgYWxnb3JpdGhtIGlzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcltdIGFwZyA9IG5ldyBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JbM107CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcGdbMF0gPSBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UodmFsaWRBbGdOYW1lKTsKKyAgICAgICAgICAgIGFwZ1sxXSA9IEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvci5nZXRJbnN0YW5jZSh2YWxpZEFsZ05hbWUsCisgICAgICAgICAgICAgICAgICAgIHZhbGlkUHJvdmlkZXIpOworICAgICAgICAgICAgYXBnWzJdID0gQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yLmdldEluc3RhbmNlKHZhbGlkQWxnTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgdmFsaWRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgcmV0dXJuIGFwZzsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIGlmIGFsZ29yaXRobSBpcyBub3QgYXZhaWxhYmxlCisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yMDEoKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBvciBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvci5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yIGluc3RhbmNlCisgICAgICogd2hlbiBhbGdvcml0aG0gaXMgRFNBCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcjAyKCkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoIURTQVN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbCh2YWxpZEFsZ05hbWUgKyAiIGFsZ29yaXRobSBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yIGFwZzsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhcGcgPSBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoYWxnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBhcGcuZ2V0QWxnb3JpdGhtKCksIGFsZ3NbaV0pOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBwcm92aWRlciBpcyBudWxsIG9yIGVtcHR5CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcjAzKCkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFEU0FTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwodmFsaWRBbGdOYW1lICsgIiBhbGdvcml0aG0gaXMgbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBwcm92aWRlciA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoYWxnc1tpXSwgcHJvdmlkZXIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHByb3ZpZGVyIGlzIG51bGwiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvci5nZXRJbnN0YW5jZShhbGdzW2ldLCAiIik7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gcHJvdmlkZXIgaXMgZW1wdHkiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGlmIHByb3ZpZGVyIGlzIG5vdAorICAgICAqIGF2YWlsYWJsZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IwNCgpCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFEU0FTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwodmFsaWRBbGdOYW1lICsgIiBhbGdvcml0aG0gaXMgbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDE7IGogPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yLmdldEluc3RhbmNlKGFsZ3NbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW52YWxpZFZhbHVlc1tqXSk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIChwcm92aWRlcjogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tqXSkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gaXMgbnVsbAorICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gaWYgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yMDUoKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFEU0FTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwodmFsaWRBbGdOYW1lICsgIiBhbGdvcml0aG0gaXMgbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UobnVsbCwgdmFsaWRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkUHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0uY29uY2F0KCIpIikpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJuIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IwNigpCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghRFNBU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKHZhbGlkQWxnTmFtZSArICIgYWxnb3JpdGhtIGlzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IgYXBnOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFwZyA9IEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvci5nZXRJbnN0YW5jZShhbGdzW2ldLAorICAgICAgICAgICAgICAgICAgICB2YWxpZFByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBhbGdzW2ldLCBhcGcuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBhcGcuZ2V0UHJvdmlkZXIoKS5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgIHZhbGlkUHJvdmlkZXJOYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcjA3KCkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoIURTQVN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbCh2YWxpZEFsZ05hbWUgKyAiIGFsZ29yaXRobSBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIgPSBudWxsOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yLmdldEluc3RhbmNlKGFsZ3NbaV0sIHByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBudWxsIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgUHJvdmlkZXIgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gaXMgbnVsbAorICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gaWYgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yMDgoKSB7CisgICAgICAgIGlmICghRFNBU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKHZhbGlkQWxnTmFtZSArICIgYWxnb3JpdGhtIGlzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yLmdldEluc3RhbmNlKG51bGwsIHZhbGlkUHJvdmlkZXIpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkUHJvdmlkZXIpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBQcm92aWRlciBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvciBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yMDkoKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghRFNBU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKHZhbGlkQWxnTmFtZSArICIgYWxnb3JpdGhtIGlzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IgYXBnOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFwZyA9IEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvci5nZXRJbnN0YW5jZShhbGdzW2ldLAorICAgICAgICAgICAgICAgICAgICB2YWxpZFByb3ZpZGVyKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGFwZy5nZXRBbGdvcml0aG0oKSwgYWxnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsIGFwZy5nZXRQcm92aWRlcigpLCB2YWxpZFByb3ZpZGVyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdlbmVyYXRlUGFyYW1ldGVycygpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgQWxnb3JpdGhtUGFyYW1ldGVycyBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yMTAoKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghRFNBU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKHZhbGlkQWxnTmFtZSArICIgYWxnb3JpdGhtIGlzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IgYXBnID0gQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yCisgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKHZhbGlkQWxnTmFtZSk7CisgICAgICAgIGFwZy5pbml0KDUxMik7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlcnMgYXAgPSBhcGcuZ2VuZXJhdGVQYXJhbWV0ZXJzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGFwLmdldEFsZ29yaXRobSgpLnRvVXBwZXJDYXNlKCksCisgICAgICAgICAgICAgICAgYXBnLmdldEFsZ29yaXRobSgpLnRvVXBwZXJDYXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmluaXQoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbSk8L2NvZGU+IGFuZAorICAgICAqIDxjb2RlPmluaXQoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbSwgU2VjdXJlUmFuZG9tIHJhbmRvbTxjb2RlPgorICAgICAqIG1ldGhvZHMKKyAgICAgKiBBc3NlcnRpb246IHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHdoZW4gcGFyYW0gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IxMigpIHsKKyAgICAgICAgaWYgKCFEU0FTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwodmFsaWRBbGdOYW1lICsgIiBhbGdvcml0aG0gaXMgbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFNlY3VyZVJhbmRvbSByYW5kb20gPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgYXBzID0gbnVsbDsKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yW10gYXBncyA9IGNyZWF0ZUFQR2VuKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvciBvYmplY3RzIHdlcmUgbm90IGNyZWF0ZWQiLAorICAgICAgICAgICAgICAgIGFwZ3MpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFwZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXBnc1tpXS5pbml0KGFwcyk7CisgICAgICAgICAgICAgICAgZmFpbCgiSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBleHBlY3RlZCBmb3IgbnVsbCBhcmd1bWVudC4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhcGdzW2ldLmluaXQoYXBzLCByYW5kb20pOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZXhwZWN0ZWQgZm9yIG51bGwgYXJndW1lbnQuIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3I8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvciBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RydWN0b3IoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFEU0FTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwodmFsaWRBbGdOYW1lICsgIiBhbGdvcml0aG0gaXMgbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaSBzcGkgPSBuZXcgTXlBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JTcGkoKTsKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yIGFwZyA9CisgICAgICAgICAgICAgICAgbmV3IG15QWxnUEcoc3BpLCB2YWxpZFByb3ZpZGVyLCB2YWxpZEFsZ05hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBhcGcuZ2V0QWxnb3JpdGhtKCksIHZhbGlkQWxnTmFtZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIixhcGcuZ2V0UHJvdmlkZXIoKSx2YWxpZFByb3ZpZGVyKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFwZy5pbml0KC0xMCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIGFwZyA9IG5ldyBteUFsZ1BHKG51bGwsIG51bGwsIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwgYXBnLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiSW5jb3JyZWN0IHByb3ZpZGVyIiwgYXBnLmdldFByb3ZpZGVyKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXBnLmluaXQoLTEwLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KK30KKy8qKgorICogQWRkaXRpb25hbCBjbGFzcyB0byB2ZXJpZnkgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yIGNvbnN0cnVjdG9yCisgKi8KK2NsYXNzIG15QWxnUEcgZXh0ZW5kcyBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IgeworICAgIHB1YmxpYyBteUFsZ1BHKEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaSBzcGksIFByb3ZpZGVyIHByb3YsIFN0cmluZyBhbGcpIHsKKyAgICAgICAgc3VwZXIoc3BpLCBwcm92LCBhbGcpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcjJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWViNWVmYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjYwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuU3BpRW5nVXRpbHM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZAorICogbWV0aG9kcy4KKyAqLworcHVibGljIGNsYXNzIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcjJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclByb3ZpZGVyQ2xhc3MgPSAib3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuTXlBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JTcGkiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGRlZmF1bHRBbGcgPSAiQVBHIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGludmFsaWRWYWx1ZXMgPSBTcGlFbmdVdGlscy5pbnZhbGlkVmFsdWVzOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gdmFsaWRWYWx1ZXM7CisKKyAgICBzdGF0aWMgeworICAgICAgICB2YWxpZFZhbHVlcyA9IG5ldyBTdHJpbmdbNF07CisgICAgICAgIHZhbGlkVmFsdWVzWzBdID0gZGVmYXVsdEFsZzsKKyAgICAgICAgdmFsaWRWYWx1ZXNbMV0gPSBkZWZhdWx0QWxnLnRvTG93ZXJDYXNlKCk7CisgICAgICAgIHZhbGlkVmFsdWVzWzJdID0gImFwRyI7CisgICAgICAgIHZhbGlkVmFsdWVzWzNdID0gIkFwRyI7CisgICAgfQorCisgICAgUHJvdmlkZXIgbVByb3Y7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBtUHJvdiA9IChuZXcgU3BpRW5nVXRpbHMoKSkubmV3IE15UHJvdmlkZXIoIk15QVBHUHJvdmlkZXIiLCAiVGVzdGluZyBwcm92aWRlciIsCisgICAgICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yMVRlc3Quc3J2QWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yLmNvbmNhdCgiLiIpLmNvbmNhdChkZWZhdWx0QWxnKSwKKyAgICAgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JQcm92aWRlckNsYXNzKTsKKyAgICAgICAgU2VjdXJpdHkuaW5zZXJ0UHJvdmlkZXJBdChtUHJvdiwgMSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIFRlc3RDYXNlI3RlYXJEb3duKCkKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcihtUHJvdi5nZXROYW1lKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja1Jlc3VsdChBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IgYWxnUGFyR2VuKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtID0gYWxnUGFyR2VuLmdlbmVyYXRlUGFyYW1ldGVycygpOworICAgICAgICBhc3NlcnROdWxsKCJOb3QgbnVsbCBwYXJhbWV0ZXJzIiwgcGFyYW0pOworCisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcHAgPSBudWxsOworICAgICAgICBhbGdQYXJHZW4uaW5pdChwcCwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAgYWxnUGFyR2VuLmluaXQocHApOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWxnUGFyR2VuLmluaXQocHAsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgcHAgPSBuZXcgdG1wQWxnb3JpdGhtUGFyYW1ldGVyU3BlYygiUHJvYmEiKTsKKyAgICAgICAgYWxnUGFyR2VuLmluaXQocHAsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgIGFsZ1Bhckdlbi5pbml0KHBwKTsKKworICAgICAgICBhbGdQYXJHZW4uaW5pdCgwLCBudWxsKTsKKyAgICAgICAgYWxnUGFyR2VuLmluaXQoMCwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWxnUGFyR2VuLmluaXQoLTEwLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhbGdQYXJHZW4uaW5pdCgtMTAsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uczoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gaXMgbnVsbAorICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gaWYgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUKKyAgICAgKiByZXR1cm5zIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvciBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2UwMSgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvci5nZXRJbnN0YW5jZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yLmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yIGFwRzsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXBHID0gQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGFwRy5nZXRBbGdvcml0aG0oKSwKKyAgICAgICAgICAgICAgICAgICAgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBhcEcuZ2V0UHJvdmlkZXIoKSwgbVByb3YpOworICAgICAgICAgICAgY2hlY2tSZXN1bHQoYXBHKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kCisgICAgICogQXNzZXJ0aW9uczoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gaXMgbnVsbAorICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gaWYgYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUKKyAgICAgKiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbDsKKyAgICAgKiB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBhdmFpbGFibGU7CisgICAgICogcmV0dXJucyBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3Igb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlMDIoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yLmdldEluc3RhbmNlKG51bGwsIG1Qcm92LmdldE5hbWUoKSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBvciBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvci5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldLCBtUHJvdgorICAgICAgICAgICAgICAgICAgICAgICAgLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIChhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcHJvdiA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBwcm92KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBudWxsIChhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMTsgaiA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW52YWxpZFZhbHVlc1tqXSk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIChhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiIHByb3ZpZGVyOiAiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tqXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yIGFwRzsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXBHID0gQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBtUHJvdgorICAgICAgICAgICAgICAgICAgICAuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGFwRy5nZXRBbGdvcml0aG0oKSwKKyAgICAgICAgICAgICAgICAgICAgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBhcEcuZ2V0UHJvdmlkZXIoKS5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgIG1Qcm92LmdldE5hbWUoKSk7CisgICAgICAgICAgICBjaGVja1Jlc3VsdChhcEcpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgUHJvdmlkZXIgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbnM6CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIGlmIGFsZ29yaXRobSBpcyBub3QgYXZhaWxhYmxlCisgICAgICogdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aGVuIHByb3ZpZGVyIGlzIG51bGw7CisgICAgICogcmV0dXJucyBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3Igb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlMDMoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UobnVsbCwgbVByb3YpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwgbVByb3YpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgUHJvdmlkZXIgcHJvdiA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBwcm92KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBudWxsIChhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IgYXBHOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhcEcgPSBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIG1Qcm92KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGFwRy5nZXRBbGdvcml0aG0oKSwKKyAgICAgICAgICAgICAgICAgICAgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBhcEcuZ2V0UHJvdmlkZXIoKSwgbVByb3YpOworICAgICAgICAgICAgY2hlY2tSZXN1bHQoYXBHKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBBZGRpdGlvbmFsIGNsYXNzIGZvciBpbml0KC4uLikgbWV0aG9kcyB2ZXJpZmljYXRpb24KKyAgICAgKi8KKyAgICBjbGFzcyB0bXBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIGltcGxlbWVudHMgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyB7CisgICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHR5cGU7CisgICAgICAgIHB1YmxpYyB0bXBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjKFN0cmluZyB0eXBlKSB7CisgICAgICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSgpIHsKKyAgICAgICAgICAgIHJldHVybiB0eXBlOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlcnNTcGlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvQWxnb3JpdGhtUGFyYW1ldGVyc1NwaVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZTlhOTQxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlcnNTcGlUZXN0LmphdmEKQEAgLTAsMCArMSw3NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyc1NwaTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+QWxnb3JpdGhtUGFyYW1ldGVyc1NwaTwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzCisgKiBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBBbGdvcml0aG1QYXJhbWV0ZXJzU3BpVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+QWxnb3JpdGhtUGFyYW1ldGVyc1NwaTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgQWxnb3JpdGhtUGFyYW1ldGVyc1NwaQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RBbGdvcml0aG1QYXJhbWV0ZXJzU3BpKCkgeworICAgICAgICBieXRlW10gYnQgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgIE15QWxnb3JpdGhtUGFyYW1ldGVyc1NwaSBhbGdQYXJTcGkgPSBuZXcgTXlBbGdvcml0aG1QYXJhbWV0ZXJzU3BpKCk7CisgICAgICAgIGFzc2VydFRydWUoYWxnUGFyU3BpIGluc3RhbmNlb2YgQWxnb3JpdGhtUGFyYW1ldGVyc1NwaSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoYWxnUGFyU3BpKTsKKworICAgICAgICBhbGdQYXJTcGkuZW5naW5lSW5pdChuZXcgTXlBbGdvcml0aG1QYXJhbWV0ZXJTcGVjKCkpOworICAgICAgICBhbGdQYXJTcGkuZW5naW5lSW5pdChidCk7CisgICAgICAgIGFsZ1BhclNwaS5lbmdpbmVJbml0KGJ0LCAiRm9ybWF0Iik7CisgICAgICAgIGFsZ1BhclNwaS5lbmdpbmVUb1N0cmluZygpOworICAgICAgICBhbGdQYXJTcGkuZW5naW5lR2V0RW5jb2RlZCgpOworICAgICAgICBhbGdQYXJTcGkuZW5naW5lR2V0RW5jb2RlZCgiRm9ybWF0Iik7CisgICAgICAgIGFsZ1BhclNwaS5lbmdpbmVHZXRQYXJhbWV0ZXJTcGVjKGphdmEubGFuZy5DbGFzcy5jbGFzcyk7CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIE15QWxnb3JpdGhtUGFyYW1ldGVyc1NwaSBleHRlbmRzIEFsZ29yaXRobVBhcmFtZXRlcnNTcGkgeworICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0KEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1TcGVjKSB7CisgICAgICAgIH0KKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChieXRlW10gcGFyYW1zKXsKKyAgICAgICAgfQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0KGJ5dGVbXSBwYXJhbXMsIFN0cmluZyBmb3JtYXQpeworICAgICAgICB9CisgICAgICAgIHByb3RlY3RlZCBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIGVuZ2luZUdldFBhcmFtZXRlclNwZWMoQ2xhc3MgcGFyYW1TcGVjKXsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHByb3RlY3RlZCBieXRlW10gZW5naW5lR2V0RW5jb2RlZCgpeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVHZXRFbmNvZGVkKFN0cmluZyBmb3JtYXQpeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcHJvdGVjdGVkIFN0cmluZyBlbmdpbmVUb1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgTXlBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIGltcGxlbWVudHMgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyB7fQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlcnNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvQWxnb3JpdGhtUGFyYW1ldGVyc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMzE1NDkyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlcnNUZXN0LmphdmEKQEAgLTAsMCArMSw3NDggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEJvcmlzIFYuIEt1em5ldHNvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzU3BpOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRFNBUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuTXlBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JTcGk7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkFsZ29yaXRobVBhcmFtZXRlcnM8L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQKKyAqIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgQWxnb3JpdGhtUGFyYW1ldGVyc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBQcm92aWRlcgorICAgICAqLworICAgIFByb3ZpZGVyIHA7CisKKyAgICAvKgorICAgICAqIEBzZWUgVGVzdENhc2Ujc2V0VXAoKQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHAgPSBuZXcgTXlQcm92aWRlcigpOworICAgICAgICBTZWN1cml0eS5pbnNlcnRQcm92aWRlckF0KHAsIDEpOworICAgIH0KKworICAgIC8qCisgICAgICogQHNlZSBUZXN0Q2FzZSN0ZWFyRG93bigpCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICAgICAgU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIocC5nZXROYW1lKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVycyNnZXRBbGdvcml0aG0oKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0QWxnb3JpdGhtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgLy8gdGVzdDogbnVsbCB2YWx1ZQorICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIGFwID0gbmV3IER1bW15QWxnb3JpdGhtUGFyYW1ldGVycyhudWxsLCBwLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChhcC5nZXRBbGdvcml0aG0oKSk7CisKKyAgICAgICAgLy8gdGVzdDogbm90IG51bGwgdmFsdWUKKyAgICAgICAgYXAgPSBuZXcgRHVtbXlBbGdvcml0aG1QYXJhbWV0ZXJzKG51bGwsIHAsICJBQUEiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQUEiLCBhcC5nZXRBbGdvcml0aG0oKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzI2dldEVuY29kZWQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RW5jb2RlZCgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIGZpbmFsIGJ5dGVbXSBlbmMgPSBuZXcgYnl0ZVtdIHsgMHgwMiwgMHgwMSwgMHgwMyB9OworCisgICAgICAgIE15QWxnb3JpdGhtUGFyYW1ldGVycyBwYXJhbVNwaSA9IG5ldyBNeUFsZ29yaXRobVBhcmFtZXRlcnMoKSB7CisgICAgICAgICAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuZ2luZUdldEVuY29kZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiBlbmM7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVycyBwYXJhbXMgPSBuZXcgRHVtbXlBbGdvcml0aG1QYXJhbWV0ZXJzKHBhcmFtU3BpLCBwLAorICAgICAgICAgICAgICAgICJhbGdvcml0aG0iKTsKKworICAgICAgICAvLworICAgICAgICAvLyB0ZXN0OiBJT0V4Y2VwdGlvbiBpZiBub3QgaW5pdGlhbGl6ZWQKKyAgICAgICAgLy8KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmFtcy5nZXRFbmNvZGVkKCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgbm90IGdldCBlbmNvZGVkIGZyb20gdW4taW5pdGlhbGl6ZWQgaW5zdGFuY2UiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vCisgICAgICAgIC8vIHRlc3Q6IGNvcnJlc3BvbmRpbmcgc3BpIG1ldGhvZCBpcyBpbnZva2VkCisgICAgICAgIC8vCisgICAgICAgIHBhcmFtcy5pbml0KG5ldyBNeUFsZ29yaXRobVBhcmFtZXRlclNwZWMoKSk7CisgICAgICAgIGFzc2VydFNhbWUoZW5jLCBwYXJhbXMuZ2V0RW5jb2RlZCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnMjZ2V0RW5jb2RlZChTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRFbmNvZGVkTGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBmaW5hbCBieXRlW10gZW5jID0gbmV3IGJ5dGVbXSB7IDB4MDIsIDB4MDEsIDB4MDMgfTsKKworICAgICAgICBmaW5hbCBTdHJpbmcgc3RyRm9ybWF0UGFyYW0gPSAiZm9ybWF0IjsKKworICAgICAgICBNeUFsZ29yaXRobVBhcmFtZXRlcnMgcGFyYW1TcGkgPSBuZXcgTXlBbGdvcml0aG1QYXJhbWV0ZXJzKCkgeworICAgICAgICAgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVHZXRFbmNvZGVkKFN0cmluZyBmb3JtYXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHN0ckZvcm1hdFBhcmFtLCBmb3JtYXQpOworICAgICAgICAgICAgICAgIHJldHVybiBlbmM7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVycyBwYXJhbXMgPSBuZXcgRHVtbXlBbGdvcml0aG1QYXJhbWV0ZXJzKHBhcmFtU3BpLCBwLAorICAgICAgICAgICAgICAgICJhbGdvcml0aG0iKTsKKworICAgICAgICAvLworICAgICAgICAvLyB0ZXN0OiBJT0V4Y2VwdGlvbiBpZiBub3QgaW5pdGlhbGl6ZWQKKyAgICAgICAgLy8KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmFtcy5nZXRFbmNvZGVkKHN0ckZvcm1hdFBhcmFtKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCBub3QgZ2V0IGVuY29kZWQgZnJvbSB1bi1pbml0aWFsaXplZCBpbnN0YW5jZSIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8KKyAgICAgICAgLy8gdGVzdDogY29ycmVzcG9uZGluZyBzcGkgbWV0aG9kIGlzIGludm9rZWQKKyAgICAgICAgLy8KKyAgICAgICAgcGFyYW1zLmluaXQobmV3IE15QWxnb3JpdGhtUGFyYW1ldGVyU3BlYygpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShlbmMsIHBhcmFtcy5nZXRFbmNvZGVkKHN0ckZvcm1hdFBhcmFtKSk7CisKKyAgICAgICAgLy8KKyAgICAgICAgLy8gdGVzdDogaWYgZm9ybWF0IHBhcmFtIGlzIG51bGwKKyAgICAgICAgLy8gUmVncmVzc2lvbiB0ZXN0IGZvciBIQVJNT05ZLTI2ODAKKyAgICAgICAgLy8KKyAgICAgICAgcGFyYW1TcGkgPSBuZXcgTXlBbGdvcml0aG1QYXJhbWV0ZXJzKCkgeworICAgICAgICAgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVHZXRFbmNvZGVkKFN0cmluZyBmb3JtYXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChmb3JtYXQpOyAvLyBudWxsIGlzIHBhc3NlZCB0byBzcGktcHJvdmlkZXIKKyAgICAgICAgICAgICAgICByZXR1cm4gZW5jOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHBhcmFtcyA9IG5ldyBEdW1teUFsZ29yaXRobVBhcmFtZXRlcnMocGFyYW1TcGksIHAsICJhbGdvcml0aG0iKTsKKyAgICAgICAgcGFyYW1zLmluaXQobmV3IE15QWxnb3JpdGhtUGFyYW1ldGVyU3BlYygpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShlbmMsIHBhcmFtcy5nZXRFbmNvZGVkKG51bGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnMjZ2V0SW5zdGFuY2UoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nW10gc3RyID0geyIiLCAicXdlcnR5dSIsICIhQCMkJV4mKigpIn07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIGFwID0gQWxnb3JpdGhtUGFyYW1ldGVycy5nZXRJbnN0YW5jZSgiQUJDIik7CisgICAgICAgICAgICBjaGVja1VuaXRpdGlhbGl6ZWQoYXApOworICAgICAgICAgICAgYXAuaW5pdChuZXcgTXlBbGdvcml0aG1QYXJhbWV0ZXJTcGVjKCkpOworICAgICAgICAgICAgY2hlY2tBUChhcCwgcCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIGFwID0gQWxnb3JpdGhtUGFyYW1ldGVycy5nZXRJbnN0YW5jZShzdHJbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3YXMgbm90IHRocm93biBmb3IgcGFyYW1ldGVyICIgKyBzdHJbaV0pOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG5zYWUpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnMjZ2V0SW5zdGFuY2UoU3RyaW5nLCBTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZ1tdIGFsZyA9IHsiIiwgInF3ZXJ0eXUiLCAiIUAjJCVeJiooKSJ9OworICAgICAgICBTdHJpbmdbXSBwcnYgPSB7IiIsIG51bGx9OworICAgICAgICBTdHJpbmdbXSBwcnYxID0geyIxMjM0NTY3ODkwIiwgInF3ZXJ0eXUiLCAiIUAjJCVeJiooKSJ9OworICAgICAgICB0cnkgeworICAgICAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVycyBhcCA9IEFsZ29yaXRobVBhcmFtZXRlcnMuZ2V0SW5zdGFuY2UoIkFCQyIsICJNeVByb3ZpZGVyIik7CisgICAgICAgICAgICBjaGVja1VuaXRpdGlhbGl6ZWQoYXApOworICAgICAgICAgICAgYXAuaW5pdChuZXcgYnl0ZVs2XSk7CisgICAgICAgICAgICBjaGVja0FQKGFwLCBwKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsZy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIGFwID0gQWxnb3JpdGhtUGFyYW1ldGVycy5nZXRJbnN0YW5jZShhbGdbaV0sICJNeVByb3ZpZGVyIik7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIGZvciBwYXJhbWV0ZXIgIiArIGFsZ1tpXSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbnNhZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiSW5jb3JyZWN0IGV4Y2VwdGlvbiAiICsgZSArICIgd2FzIHRocm93biBmb3IgIiArIGFsZ1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBydi5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIGFwID0gQWxnb3JpdGhtUGFyYW1ldGVycy5nZXRJbnN0YW5jZSgiQUJDIiwgcHJ2W2ldKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24gZm9yIHBhcmFtZXRlciAiICsgcHJ2W2ldKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIkluY29ycmVjdCBleGNlcHRpb24gIiArIGUgKyAiIHdhcyB0aHJvd24gZm9yICIgKyBwcnZbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcnYxLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlcnMgYXAgPSBBbGdvcml0aG1QYXJhbWV0ZXJzLmdldEluc3RhbmNlKCJBQkMiLCBwcnYxW2ldKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB3YXMgbm90IHRocm93biBmb3IgcGFyYW1ldGVyICIgKyBwcnYxW2ldKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIG5zcGUpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIkluY29ycmVjdCBleGNlcHRpb24gIiArIGUgKyAiIHdhcyB0aHJvd24gZm9yICIgKyBwcnYxW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVycyNnZXRQYXJhbWV0ZXJTcGVjKENsYXNzKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UGFyYW1ldGVyU3BlY0xqYXZhX2xhbmdfQ2xhc3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBmaW5hbCBNeUFsZ29yaXRobVBhcmFtZXRlclNwZWMgbXlQYXJhbVNwZWMgPSBuZXcgTXlBbGdvcml0aG1QYXJhbWV0ZXJTcGVjKCk7CisKKyAgICAgICAgTXlBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtU3BpID0gbmV3IE15QWxnb3JpdGhtUGFyYW1ldGVycygpIHsKKyAgICAgICAgICAgIHByb3RlY3RlZCBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIGVuZ2luZUdldFBhcmFtZXRlclNwZWMoCisgICAgICAgICAgICAgICAgICAgIENsYXNzIHBhcmFtU3BlYykgeworICAgICAgICAgICAgICAgIHJldHVybiBteVBhcmFtU3BlYzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtcyA9IG5ldyBEdW1teUFsZ29yaXRobVBhcmFtZXRlcnMocGFyYW1TcGksIHAsCisgICAgICAgICAgICAgICAgImFsZ29yaXRobSIpOworCisgICAgICAgIC8vCisgICAgICAgIC8vIHRlc3Q6IEludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uIGlmIG5vdCBpbml0aWFsaXplZAorICAgICAgICAvLworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFyYW1zLmdldFBhcmFtZXRlclNwZWMobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJhbXMuZ2V0UGFyYW1ldGVyU3BlYyhNeUFsZ29yaXRobVBhcmFtZXRlclNwZWMuY2xhc3MpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vCisgICAgICAgIC8vIHRlc3Q6IGNvcnJlc3BvbmRpbmcgc3BpIG1ldGhvZCBpcyBpbnZva2VkCisgICAgICAgIC8vCisgICAgICAgIHBhcmFtcy5pbml0KG5ldyBNeUFsZ29yaXRobVBhcmFtZXRlclNwZWMoKSk7CisgICAgICAgIGFzc2VydFNhbWUobXlQYXJhbVNwZWMsIHBhcmFtcworICAgICAgICAgICAgICAgIC5nZXRQYXJhbWV0ZXJTcGVjKE15QWxnb3JpdGhtUGFyYW1ldGVyU3BlYy5jbGFzcykpOworCisgICAgICAgIC8vCisgICAgICAgIC8vIHRlc3Q6IGlmIHBhcmFtU3BlYyBpcyBudWxsCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgSEFSTU9OWS0yNzMzCisgICAgICAgIC8vCisgICAgICAgIHBhcmFtU3BpID0gbmV3IE15QWxnb3JpdGhtUGFyYW1ldGVycygpIHsKKworICAgICAgICAgICAgcHJvdGVjdGVkIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgZW5naW5lR2V0UGFyYW1ldGVyU3BlYygKKyAgICAgICAgICAgICAgICAgICAgQ2xhc3MgcGFyYW1TcGVjKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChwYXJhbVNwZWMpOyAvLyBudWxsIGlzIHBhc3NlZCB0byBzcGktcHJvdmlkZXIKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBwYXJhbXMgPSBuZXcgRHVtbXlBbGdvcml0aG1QYXJhbWV0ZXJzKHBhcmFtU3BpLCBwLCAiYWxnb3JpdGhtIik7CisgICAgICAgIHBhcmFtcy5pbml0KG5ldyBNeUFsZ29yaXRobVBhcmFtZXRlclNwZWMoKSk7CisgICAgICAgIGFzc2VydE51bGwocGFyYW1zLmdldFBhcmFtZXRlclNwZWMobnVsbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVycyNnZXRJbnN0YW5jZShTdHJpbmcsIFByb3ZpZGVyKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZ0xqYXZhX3NlY3VyaXR5X1Byb3ZpZGVyKCkgeworICAgICAgICBTdHJpbmdbXSBhbGcgPSB7IiIsICJxd2VydHl1IiwgIiFAIyQlXiYqKCkifTsKKyAgICAgICAgUHJvdmlkZXIgcHAgPSBudWxsOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIGFwID0gQWxnb3JpdGhtUGFyYW1ldGVycy5nZXRJbnN0YW5jZSgiQUJDIiwgcCk7CisgICAgICAgICAgICBjaGVja1VuaXRpdGlhbGl6ZWQoYXApOworICAgICAgICAgICAgYXAuaW5pdChuZXcgYnl0ZVs2XSwgImFhYSIpOworICAgICAgICAgICAgY2hlY2tBUChhcCwgcCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKXsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsZy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIGFwID0gQWxnb3JpdGhtUGFyYW1ldGVycy5nZXRJbnN0YW5jZShhbGdbaV0sIHApOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3YXMgbm90IHRocm93biBmb3IgcGFyYW1ldGVyICIgKyBhbGdbaV0pOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG5zYWUpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIkluY29ycmVjdCBleGNlcHRpb24gIiArIGUgKyAiIHdhcyB0aHJvd24gZm9yICIgKyBhbGdbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlcnMgYXAgPSBBbGdvcml0aG1QYXJhbWV0ZXJzLmdldEluc3RhbmNlKCJBQkMiLCBwcCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24gZm9yIE5VTEwgcHJvdmlkZXIiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSl7CisgICAgICAgICAgICBmYWlsKCJJbmNvcnJlY3QgZXhjZXB0aW9uICIgKyBlICsgIiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnMjZ2V0UHJvdmlkZXIoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UHJvdmlkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gdGVzdDogbnVsbCB2YWx1ZQorICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIGFwID0gbmV3IER1bW15QWxnb3JpdGhtUGFyYW1ldGVycyhudWxsLCBudWxsLCAiQUFBIik7CisgICAgICAgIGFzc2VydE51bGwoYXAuZ2V0UHJvdmlkZXIoKSk7CisKKyAgICAgICAgLy8gdGVzdDogbm90IG51bGwgdmFsdWUKKyAgICAgICAgYXAgPSBuZXcgRHVtbXlBbGdvcml0aG1QYXJhbWV0ZXJzKG51bGwsIHAsICJBQUEiKTsKKyAgICAgICAgYXNzZXJ0U2FtZShwLCBhcC5nZXRQcm92aWRlcigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnMjaW5pdChqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luaXRMamF2YV9zZWN1cml0eV9zcGVjX0FsZ29yaXRobVBhcmFtZXRlclNwZWMoKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgLy8KKyAgICAgICAgLy8gdGVzdDogY29ycmVzcG9uZGluZyBzcGkgbWV0aG9kIGlzIGludm9rZWQKKyAgICAgICAgLy8KKyAgICAgICAgZmluYWwgTXlBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHNwZWMgPSBuZXcgTXlBbGdvcml0aG1QYXJhbWV0ZXJTcGVjKCk7CisKKyAgICAgICAgTXlBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtU3BpID0gbmV3IE15QWxnb3JpdGhtUGFyYW1ldGVycygpIHsKKyAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXQoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbVNwZWMpCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgYXNzZXJ0U2FtZShzcGVjLCBwYXJhbVNwZWMpOworICAgICAgICAgICAgICAgIHJ1bkVuZ2luZUluaXRfQWxnUGFyYW1TcGVjID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtcyA9IG5ldyBEdW1teUFsZ29yaXRobVBhcmFtZXRlcnMocGFyYW1TcGksIHAsCisgICAgICAgICAgICAgICAgImFsZ29yaXRobSIpOworCisgICAgICAgIHBhcmFtcy5pbml0KHNwZWMpOworICAgICAgICBhc3NlcnRUcnVlKHBhcmFtU3BpLnJ1bkVuZ2luZUluaXRfQWxnUGFyYW1TcGVjKTsKKworICAgICAgICAvLworICAgICAgICAvLyB0ZXN0OiBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbiBpZiBhbHJlYWR5IGluaXRpYWxpemVkCisgICAgICAgIC8vCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJhbXMuaW5pdChzcGVjKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIEludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBwYXJhbXMgPSBuZXcgRHVtbXlBbGdvcml0aG1QYXJhbWV0ZXJzKHBhcmFtU3BpLCBwLCAiYWxnb3JpdGhtIik7CisgICAgICAgIHBhcmFtcy5pbml0KG5ldyBieXRlWzBdKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmFtcy5pbml0KHNwZWMpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHBhcmFtcyA9IG5ldyBEdW1teUFsZ29yaXRobVBhcmFtZXRlcnMocGFyYW1TcGksIHAsICJhbGdvcml0aG0iKTsKKyAgICAgICAgcGFyYW1zLmluaXQobmV3IGJ5dGVbMF0sICJmb3JtYXQiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmFtcy5pbml0KHNwZWMpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vCisgICAgICAgIC8vIHRlc3Q6IGlmIHBhcmFtU3BlYyBpcyBudWxsCisgICAgICAgIC8vCisgICAgICAgIHBhcmFtU3BpID0gbmV3IE15QWxnb3JpdGhtUGFyYW1ldGVycygpIHsKKworICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtU3BlYykKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKHBhcmFtU3BlYyk7Ly8gbnVsbCBpcyBwYXNzZWQgdG8gc3BpLXByb3ZpZGVyCisgICAgICAgICAgICAgICAgcnVuRW5naW5lSW5pdF9BbGdQYXJhbVNwZWMgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHBhcmFtcyA9IG5ldyBEdW1teUFsZ29yaXRobVBhcmFtZXRlcnMocGFyYW1TcGksIHAsICJhbGdvcml0aG0iKTsKKyAgICAgICAgcGFyYW1zLmluaXQoKEFsZ29yaXRobVBhcmFtZXRlclNwZWMpIG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKHBhcmFtU3BpLnJ1bkVuZ2luZUluaXRfQWxnUGFyYW1TcGVjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnMjaW5pdChieXRlW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pbml0JEIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICAvLworICAgICAgICAvLyB0ZXN0OiBjb3JyZXNwb25kaW5nIHNwaSBtZXRob2QgaXMgaW52b2tlZAorICAgICAgICAvLworICAgICAgICBmaW5hbCBieXRlW10gZW5jID0gbmV3IGJ5dGVbXSB7IDB4MDIsIDB4MDEsIDB4MDMgfTsKKworICAgICAgICBNeUFsZ29yaXRobVBhcmFtZXRlcnMgcGFyYW1TcGkgPSBuZXcgTXlBbGdvcml0aG1QYXJhbWV0ZXJzKCkgeworICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChieXRlW10gcGFyYW1zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJ1bkVuZ2luZUluaXRCJCA9IHRydWU7CisgICAgICAgICAgICAgICAgYXNzZXJ0U2FtZShlbmMsIHBhcmFtcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVycyBwYXJhbXMgPSBuZXcgRHVtbXlBbGdvcml0aG1QYXJhbWV0ZXJzKHBhcmFtU3BpLCBwLAorICAgICAgICAgICAgICAgICJhbGdvcml0aG0iKTsKKworICAgICAgICBwYXJhbXMuaW5pdChlbmMpOworICAgICAgICBhc3NlcnRUcnVlKHBhcmFtU3BpLnJ1bkVuZ2luZUluaXRCJCk7CisKKyAgICAgICAgLy8KKyAgICAgICAgLy8gdGVzdDogSU9FeGNlcHRpb24gaWYgYWxyZWFkeSBpbml0aWFsaXplZAorICAgICAgICAvLworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFyYW1zLmluaXQoZW5jKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIElPRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBwYXJhbXMgPSBuZXcgRHVtbXlBbGdvcml0aG1QYXJhbWV0ZXJzKHBhcmFtU3BpLCBwLCAiYWxnb3JpdGhtIik7CisgICAgICAgIHBhcmFtcy5pbml0KG5ldyBNeUFsZ29yaXRobVBhcmFtZXRlclNwZWMoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJhbXMuaW5pdChlbmMpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHBhcmFtcyA9IG5ldyBEdW1teUFsZ29yaXRobVBhcmFtZXRlcnMocGFyYW1TcGksIHAsICJhbGdvcml0aG0iKTsKKyAgICAgICAgcGFyYW1zLmluaXQoZW5jLCAiZm9ybWF0Iik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJhbXMuaW5pdChlbmMpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vCisgICAgICAgIC8vIHRlc3Q6IGlmIHBhcmFtcyBpcyBudWxsCisgICAgICAgIC8vCisgICAgICAgIHBhcmFtU3BpID0gbmV3IE15QWxnb3JpdGhtUGFyYW1ldGVycygpIHsKKworICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChieXRlW10gcGFyYW1zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJ1bkVuZ2luZUluaXRCJCA9IHRydWU7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChwYXJhbXMpOyAvLyBudWxsIGlzIHBhc3NlZCB0byBzcGktcHJvdmlkZXIKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBwYXJhbXMgPSBuZXcgRHVtbXlBbGdvcml0aG1QYXJhbWV0ZXJzKHBhcmFtU3BpLCBwLCAiYWxnb3JpdGhtIik7CisgICAgICAgIHBhcmFtcy5pbml0KChieXRlW10pIG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKHBhcmFtU3BpLnJ1bkVuZ2luZUluaXRCJCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzI2luaXQoYnl0ZVtdLFN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luaXQkQkxqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgLy8KKyAgICAgICAgLy8gdGVzdDogY29ycmVzcG9uZGluZyBzcGkgbWV0aG9kIGlzIGludm9rZWQKKyAgICAgICAgLy8KKyAgICAgICAgZmluYWwgYnl0ZVtdIGVuYyA9IG5ldyBieXRlW10geyAweDAyLCAweDAxLCAweDAzIH07CisgICAgICAgIGZpbmFsIFN0cmluZyBzdHJGb3JtYXRQYXJhbSA9ICJmb3JtYXQiOworCisgICAgICAgIE15QWxnb3JpdGhtUGFyYW1ldGVycyBwYXJhbVNwaSA9IG5ldyBNeUFsZ29yaXRobVBhcmFtZXRlcnMoKSB7CisgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0KGJ5dGVbXSBwYXJhbXMsIFN0cmluZyBmb3JtYXQpCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgICAgICAgICBydW5FbmdpbmVJbml0QiRTdHJpbmcgPSB0cnVlOworICAgICAgICAgICAgICAgIGFzc2VydFNhbWUoZW5jLCBwYXJhbXMpOworICAgICAgICAgICAgICAgIGFzc2VydFNhbWUoc3RyRm9ybWF0UGFyYW0sIGZvcm1hdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVycyBwYXJhbXMgPSBuZXcgRHVtbXlBbGdvcml0aG1QYXJhbWV0ZXJzKHBhcmFtU3BpLCBwLAorICAgICAgICAgICAgICAgICJhbGdvcml0aG0iKTsKKworICAgICAgICBwYXJhbXMuaW5pdChlbmMsIHN0ckZvcm1hdFBhcmFtKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwYXJhbVNwaS5ydW5FbmdpbmVJbml0QiRTdHJpbmcpOworCisgICAgICAgIC8vCisgICAgICAgIC8vIHRlc3Q6IElPRXhjZXB0aW9uIGlmIGFscmVhZHkgaW5pdGlhbGl6ZWQKKyAgICAgICAgLy8KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmFtcy5pbml0KGVuYywgc3RyRm9ybWF0UGFyYW0pOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHBhcmFtcyA9IG5ldyBEdW1teUFsZ29yaXRobVBhcmFtZXRlcnMocGFyYW1TcGksIHAsICJhbGdvcml0aG0iKTsKKyAgICAgICAgcGFyYW1zLmluaXQobmV3IE15QWxnb3JpdGhtUGFyYW1ldGVyU3BlYygpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmFtcy5pbml0KGVuYywgc3RyRm9ybWF0UGFyYW0pOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHBhcmFtcyA9IG5ldyBEdW1teUFsZ29yaXRobVBhcmFtZXRlcnMocGFyYW1TcGksIHAsICJhbGdvcml0aG0iKTsKKyAgICAgICAgcGFyYW1zLmluaXQoZW5jKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmFtcy5pbml0KGVuYywgc3RyRm9ybWF0UGFyYW0pOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vCisgICAgICAgIC8vIHRlc3Q6IGlmIHBhcmFtcyBhbmQgZm9ybWF0IGFyZSBudWxsCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgSEFSTU9OWS0yNzI0CisgICAgICAgIC8vCisgICAgICAgIHBhcmFtU3BpID0gbmV3IE15QWxnb3JpdGhtUGFyYW1ldGVycygpIHsKKworICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChieXRlW10gcGFyYW1zLCBTdHJpbmcgZm9ybWF0KQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgICAgICAgICAgcnVuRW5naW5lSW5pdEIkU3RyaW5nID0gdHJ1ZTsKKworICAgICAgICAgICAgICAgIC8vIG51bGwgaXMgcGFzc2VkIHRvIHNwaS1wcm92aWRlcgorICAgICAgICAgICAgICAgIGFzc2VydE51bGwocGFyYW1zKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKGZvcm1hdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgcGFyYW1zID0gbmV3IER1bW15QWxnb3JpdGhtUGFyYW1ldGVycyhwYXJhbVNwaSwgcCwgImFsZ29yaXRobSIpOworICAgICAgICBwYXJhbXMuaW5pdChudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwYXJhbVNwaS5ydW5FbmdpbmVJbml0QiRTdHJpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVycyN0b1N0cmluZygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF90b1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIGZpbmFsIFN0cmluZyBzdHIgPSAiQWxnb3JpdGhtUGFyYW1ldGVycyI7CisKKyAgICAgICAgTXlBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtU3BpID0gbmV3IE15QWxnb3JpdGhtUGFyYW1ldGVycygpIHsKKyAgICAgICAgICAgIHByb3RlY3RlZCBTdHJpbmcgZW5naW5lVG9TdHJpbmcoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN0cjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtcyA9IG5ldyBEdW1teUFsZ29yaXRobVBhcmFtZXRlcnMocGFyYW1TcGksIHAsCisgICAgICAgICAgICAgICAgImFsZ29yaXRobSIpOworCisgICAgICAgIGFzc2VydE51bGwoInVuaXRpdGlhbGl6ZWQiLCBwYXJhbXMudG9TdHJpbmcoKSk7CisKKyAgICAgICAgcGFyYW1zLmluaXQobmV3IGJ5dGVbMF0pOworCisgICAgICAgIGFzc2VydFNhbWUoc3RyLCBwYXJhbXMudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgRFNBIEFsZ29yaXRobVBhcmFtZXRlcnMgcHJvdmlkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RFNBUHJvdmlkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVycyBwYXJhbXMgPSBBbGdvcml0aG1QYXJhbWV0ZXJzLmdldEluc3RhbmNlKCJEU0EiKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkFsZ29yaXRobSIsICJEU0EiLCBwYXJhbXMuZ2V0QWxnb3JpdGhtKCkpOworCisgICAgICAgIC8vIGluaXQoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYykKKyAgICAgICAgQmlnSW50ZWdlciBwID0gQmlnSW50ZWdlci5PTkU7CisgICAgICAgIEJpZ0ludGVnZXIgcSA9IEJpZ0ludGVnZXIuVEVOOworICAgICAgICBCaWdJbnRlZ2VyIGcgPSBCaWdJbnRlZ2VyLlpFUk87CisgICAgICAgIHBhcmFtcy5pbml0KG5ldyBEU0FQYXJhbWV0ZXJTcGVjKHAsIHEsIGcpKTsKKworICAgICAgICAvLyBnZXRFbmNvZGVkKCkgYW5kIGdldEVuY29kZWQoU3RyaW5nKSAoVE9ETyB2ZXJpZnkgcmV0dXJuZWQgZW5jb2RpbmcpCisgICAgICAgIGJ5dGVbXSBlbmMgPSBwYXJhbXMuZ2V0RW5jb2RlZCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKGVuYyk7CisgICAgICAgIGFzc2VydE5vdE51bGwocGFyYW1zLmdldEVuY29kZWQoIkFTTi4xIikpOworICAgICAgICAvLyBUT0RPIGFzc2VydE5vdE51bGwocGFyYW1zLmdldEVuY29kZWQobnVsbCkpOyAvLyBIQVJNT05ZLTI2ODAKKworICAgICAgICAvLyBnZXRQYXJhbWV0ZXJTcGVjKENsYXNzKQorICAgICAgICBEU0FQYXJhbWV0ZXJTcGVjIHNwZWMgPSBwYXJhbXMuZ2V0UGFyYW1ldGVyU3BlYyhEU0FQYXJhbWV0ZXJTcGVjLmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwIGlzIHdyb25nICIsIHAsIHNwZWMuZ2V0UCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJxIGlzIHdyb25nICIsIHEsIHNwZWMuZ2V0USgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnIGlzIHdyb25nICIsIGcsIHNwZWMuZ2V0RygpKTsKKworICAgICAgICAvLyBpbml0KGJ5dGVbXSkKKyAgICAgICAgcGFyYW1zID0gQWxnb3JpdGhtUGFyYW1ldGVycy5nZXRJbnN0YW5jZSgiRFNBIik7CisgICAgICAgIHBhcmFtcy5pbml0KGVuYyk7CisgICAgICAgIGFzc2VydFRydWUoInBhcmFtIGVuY29kZWQgaXMgZGlmZmVyZW50IiwgQXJyYXlzLmVxdWFscyhlbmMsIHBhcmFtcworICAgICAgICAgICAgICAgIC5nZXRFbmNvZGVkKCkpKTsKKworICAgICAgICAvLyBpbml0KGJ5dGVbXSwgU3RyaW5nKQorICAgICAgICBwYXJhbXMgPSBBbGdvcml0aG1QYXJhbWV0ZXJzLmdldEluc3RhbmNlKCJEU0EiKTsKKyAgICAgICAgcGFyYW1zLmluaXQoZW5jLCAiQVNOLjEiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgicGFyYW0gZW5jb2RlZCBpcyBkaWZmZXJlbnQiLCBBcnJheXMuZXF1YWxzKGVuYywgcGFyYW1zCisgICAgICAgICAgICAgICAgLmdldEVuY29kZWQoKSkpOworCisgICAgICAgIHBhcmFtcyA9IEFsZ29yaXRobVBhcmFtZXRlcnMuZ2V0SW5zdGFuY2UoIkRTQSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFyYW1zLmluaXQoZW5jLCAiRE9VR0xBU01BV1NPTiIpOworICAgICAgICAgICAgZmFpbCgidW5zdXBwb3J0ZWQgZm9ybWF0IHNob3VsZCBoYXZlIHJhaXNlZCBJT0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgT0FFUCBBbGdvcml0aG1QYXJhbWV0ZXJzIHByb3ZpZGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE9BRVBQcm92aWRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtcyA9IEFsZ29yaXRobVBhcmFtZXRlcnMuZ2V0SW5zdGFuY2UoIk9BRVAiKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkFsZ29yaXRobSIsICJPQUVQIiwgcGFyYW1zLmdldEFsZ29yaXRobSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5BbGdvcml0aG1QYXJhbWV0ZXJzPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBBbGdvcml0aG1QYXJhbWV0ZXJzIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RBbGdvcml0aG1QYXJhbWV0ZXJzQ29uc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVyc1NwaSBzcGkgPSBuZXcgTXlBbGdvcml0aG1QYXJhbWV0ZXJzKCk7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlcnMgYXAgPSBuZXcgbXlBbGdQKHNwaSwgcCwgIkFCQyIpOworCisgICAgICAgIGNoZWNrVW5pdGl0aWFsaXplZChhcCk7CisgICAgICAgIGFwLmluaXQobmV3IGJ5dGVbNl0sICJhYWEiKTsKKyAgICAgICAgY2hlY2tBUChhcCwgcCk7CisKKyAgICAgICAgLy9OVUxMIHBhcmFtZXRlcnMKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFwID0gbmV3IG15QWxnUChudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIHNob3VsZCBiZSBub3QgdGhyb3duIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tVbml0aXRpYWxpemVkKEFsZ29yaXRobVBhcmFtZXRlcnMgYXApIHsKKyAgICAgICAgYXNzZXJ0TnVsbCgiVW5pbml0aWFsaXplZDogdG9TdHJpbmcoKSBmYWlsZWQiLCBhcC50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tBUChBbGdvcml0aG1QYXJhbWV0ZXJzIGFwLCBQcm92aWRlciBwKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBhc3NlcnRTYW1lKCJnZXRQcm92aWRlcigpIGZhaWxlZCIsIHAsIGFwLmdldFByb3ZpZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldEFsZ29yaXRobSgpIGZhaWxlZCIsICJBQkMiLCBhcC5nZXRBbGdvcml0aG0oKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBbGdvcml0aG1QYXJhbWV0ZXJzIiwgYXAudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydFRydWUoInRvU3RyaW5nKCkgZmFpbGVkIiwgTXlBbGdvcml0aG1QYXJhbWV0ZXJzLnJ1bkVuZ2luZVRvU3RyaW5nKTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKKyAgICBwcml2YXRlIGNsYXNzIE15UHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlciB7CisgICAgICAgIE15UHJvdmlkZXIoKSB7CisgICAgICAgICAgICBzdXBlcigiTXlQcm92aWRlciIsIDEuMCwgIlByb3ZpZGVyIGZvciB0ZXN0aW5nIik7CisgICAgICAgICAgICBwdXQoIkFsZ29yaXRobVBhcmFtZXRlcnMuQUJDIiwgTXlBbGdvcml0aG1QYXJhbWV0ZXJzLmNsYXNzCisgICAgICAgICAgICAgICAgICAgIC5nZXROYW1lKCkpOworICAgICAgICB9CisKKyAgICAgICAgTXlQcm92aWRlcihTdHJpbmcgbmFtZSwgZG91YmxlIHZlcnNpb24sIFN0cmluZyBpbmZvKSB7CisgICAgICAgICAgICBzdXBlcihuYW1lLCB2ZXJzaW9uLCBpbmZvKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgTXlBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIGltcGxlbWVudHMgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWN7CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBEdW1teUFsZ29yaXRobVBhcmFtZXRlcnMgZXh0ZW5kcyBBbGdvcml0aG1QYXJhbWV0ZXJzIHsKKyAgICAgICAgcHVibGljIER1bW15QWxnb3JpdGhtUGFyYW1ldGVycyhBbGdvcml0aG1QYXJhbWV0ZXJzU3BpIHBhcmFtU3BpLAorICAgICAgICAgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyLCBTdHJpbmcgYWxnb3JpdGhtKSB7CisgICAgICAgICAgICBzdXBlcihwYXJhbVNwaSwgcHJvdmlkZXIsIGFsZ29yaXRobSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE15QWxnb3JpdGhtUGFyYW1ldGVycyBleHRlbmRzIEFsZ29yaXRobVBhcmFtZXRlcnNTcGkgeworCisgICAgICAgIHB1YmxpYyBib29sZWFuIHJ1bkVuZ2luZUluaXRfQWxnUGFyYW1TcGVjID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gcnVuRW5naW5lSW5pdEIkID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gcnVuRW5naW5lSW5pdEIkU3RyaW5nID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIHN0YXRpYyBib29sZWFuIHJ1bkVuZ2luZVRvU3RyaW5nID0gZmFsc2U7CisKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtU3BlYykKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChieXRlW10gcGFyYW1zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChieXRlW10gcGFyYW1zLCBTdHJpbmcgZm9ybWF0KQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBlbmdpbmVHZXRQYXJhbWV0ZXJTcGVjKENsYXNzIHBhcmFtU3BlYykKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuZ2luZUdldEVuY29kZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuZ2luZUdldEVuY29kZWQoU3RyaW5nIGZvcm1hdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIFN0cmluZyBlbmdpbmVUb1N0cmluZygpIHsKKyAgICAgICAgICAgIHJ1bkVuZ2luZVRvU3RyaW5nID0gdHJ1ZTsKKyAgICAgICAgICAgIHJldHVybiAiQWxnb3JpdGhtUGFyYW1ldGVycyI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRpdGlvbmFsIGNsYXNzIHRvIHZlcmlmeSBBbGdvcml0aG1QYXJhbWV0ZXJzIGNvbnN0cnVjdG9yCisgICAgICovCisgICAgY2xhc3MgbXlBbGdQIGV4dGVuZHMgQWxnb3JpdGhtUGFyYW1ldGVycyB7CisgICAgICAgIHB1YmxpYyBteUFsZ1AoQWxnb3JpdGhtUGFyYW1ldGVyc1NwaSBzcGksIFByb3ZpZGVyIHByb3YsIFN0cmluZyBhbGcpIHsKKyAgICAgICAgICAgIHN1cGVyKHNwaSwgcHJvdiwgYWxnKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9Db2RlU2lnbmVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0NvZGVTaWduZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTRkOTA2YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9Db2RlU2lnbmVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTQyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgVi4gQXN0YXBjaHVrCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkNvZGVTaWduZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5UaW1lc3RhbXA7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuVGVzdENlcnRVdGlsczsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBVbml0IHRlc3QgZm9yIENvZGVTaWduZXIuCisgKi8KK3B1YmxpYyBjbGFzcyBDb2RlU2lnbmVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwcml2YXRlIENlcnRQYXRoIGNwYXRoID0gVGVzdENlcnRVdGlscy5nZW5DZXJ0UGF0aCgzLCAwKTsKKyAgICBwcml2YXRlIERhdGUgbm93ID0gbmV3IERhdGUoKTsKKworICAgIHByaXZhdGUgVGltZXN0YW1wIHRzID0gbmV3IFRpbWVzdGFtcChub3csIGNwYXRoKTsKKworICAgIC8qKgorICAgICAqIG11c3QgdGhyb3cgTlBFIGlmIHNpZ25lckNlcnRQYXRoIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29kZVNpZ25lcl8wMCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBDb2RlU2lnbmVyKG51bGwsIHRzKTsKKyAgICAgICAgICAgIGZhaWwoIm11c3Qgbm90IGFjY2VwdCBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAvKiBpdCdzIG9rICovCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB0aW1lc3RhbXAgY2FuIGJlIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0Q29kZVNpZ25lcl8wMSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvZGVTaWduZXIgY3MgPSBuZXcgQ29kZVNpZ25lcihjcGF0aCwgbnVsbCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGNzKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3QgbnVsbCBwYXJhbWV0ZXJzCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdENvZGVTaWduZXJfMDIoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2RlU2lnbmVyIGNzID0gbmV3IENvZGVTaWduZXIoY3BhdGgsIHRzKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoY3MpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdmFyaW91cyBhc3NlcnRpb25zIGFib3V0IGVxdWFscygpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVxdWFsc09iamVjdCgpIHsKKworICAgICAgICBDb2RlU2lnbmVyIG9uZSA9IG5ldyBDb2RlU2lnbmVyKGNwYXRoLCB0cyk7CisgICAgICAgIENvZGVTaWduZXIgdHdvID0gbmV3IENvZGVTaWduZXIoY3BhdGgsIHRzKTsKKyAgICAgICAgQ29kZVNpZ25lciB0aHJlZSA9IG5ldyBDb2RlU2lnbmVyKGNwYXRoLCBudWxsKTsKKworICAgICAgICBDZXJ0UGF0aCBjcGF0aDIgPSBUZXN0Q2VydFV0aWxzLmdlbkNlcnRQYXRoKDUsIDMpOworICAgICAgICBDb2RlU2lnbmVyIGZvdXIgPSBuZXcgQ29kZVNpZ25lcihjcGF0aDIsIG51bGwpOworCisgICAgICAgIGFzc2VydFRydWUob25lLmVxdWFscyhvbmUpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShvbmUuZXF1YWxzKHR3bykpOworICAgICAgICBhc3NlcnRUcnVlKHR3by5lcXVhbHMob25lKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG9uZS5lcXVhbHModGhyZWUpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UodGhyZWUuZXF1YWxzKG9uZSkpOworICAgICAgICBhc3NlcnRUcnVlKHRocmVlLmVxdWFscyh0aHJlZSkpOworICAgICAgICAvLyBkaWZmZXJlbnQgQ2VydFBhdGhzCisgICAgICAgIGFzc2VydEZhbHNlKCB0aHJlZS5lcXVhbHMoZm91cikpOworICAgICAgICAvLyBzcGVjaWFsIGNhc2VzCisgICAgICAgIGFzc2VydEZhbHNlKCBvbmUuZXF1YWxzKG51bGwpICk7CisgICAgICAgIGFzc2VydEZhbHNlKCBvbmUuZXF1YWxzKG5ldyBPYmplY3QoKSkgKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBDb2RlU2lnbmVyLmdldFNpZ25lckNlcnRQYXRoKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2lnbmVyQ2VydFBhdGgoKSB7CisgICAgICAgIGFzc2VydFNhbWUobmV3IENvZGVTaWduZXIoY3BhdGgsIG51bGwpLmdldFNpZ25lckNlcnRQYXRoKCksIGNwYXRoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBDb2RlU2lnbmVyLmdldFRpbWVTdGFtcCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldFRpbWVzdGFtcCgpIHsKKyAgICAgICAgYXNzZXJ0TnVsbChuZXcgQ29kZVNpZ25lcihjcGF0aCwgbnVsbCkuZ2V0VGltZXN0YW1wKCkpOworICAgICAgICBhc3NlcnRTYW1lKG5ldyBDb2RlU2lnbmVyKGNwYXRoLCB0cykuZ2V0VGltZXN0YW1wKCksIHRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBDb2RlU2lnbmVyLnRvU3RyaW5nKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9TdHJpbmcoKSB7CisgICAgICAgIGFzc2VydFRydWUobmV3IENvZGVTaWduZXIoY3BhdGgsIG51bGwpLnRvU3RyaW5nKCkuY29udGFpbnMoIiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuZXcgQ29kZVNpZ25lcihjcGF0aCwgdHMpLnRvU3RyaW5nKCkuY29udGFpbnMoIiIpKTsKKworICAgICAgICBhc3NlcnRUcnVlKG5ldyBDb2RlU2lnbmVyKGNwYXRoLCBudWxsKS50b1N0cmluZygpLmNvbnRhaW5zKCJTaWduZXIiKSk7CisgICAgICAgIGFzc2VydFRydWUobmV3IENvZGVTaWduZXIoY3BhdGgsIHRzKS50b1N0cmluZygpLmNvbnRhaW5zKHRzLnRvU3RyaW5nKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBDb2RlU2lnbmVyLmhhc2hDb2RlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzaENvZGUoKSB7CisgICAgICAgIENvZGVTaWduZXIgY3MxID0gbmV3IENvZGVTaWduZXIoY3BhdGgsIHRzKTsKKyAgICAgICAgQ29kZVNpZ25lciBjczIgPSBuZXcgQ29kZVNpZ25lcihjcGF0aCwgdHMpOworICAgICAgICBDb2RlU2lnbmVyIGNzMyA9IG5ldyBDb2RlU2lnbmVyKGNwYXRoLCBudWxsKTsKKworICAgICAgICBhc3NlcnRUcnVlKGNzMS5oYXNoQ29kZSgpID09IGNzMi5oYXNoQ29kZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjczIuaGFzaENvZGUoKSAhPSBjczMuaGFzaENvZGUoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvRGlnZXN0RXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0RpZ2VzdEV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45OWRjYzZmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0RpZ2VzdEV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDE3NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5EaWdlc3RFeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkRpZ2VzdEV4Y2VwdGlvbjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIERpZ2VzdEV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgVGhyb3dhYmxlIHRDYXVzZSA9IG5ldyBUaHJvd2FibGUoIlRocm93YWJsZSBmb3IgZXhjZXB0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5EaWdlc3RFeGNlcHRpb24oKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgRGlnZXN0RXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGlnZXN0RXhjZXB0aW9uMDEoKSB7CisgICAgICAgIERpZ2VzdEV4Y2VwdGlvbiB0RSA9IG5ldyBEaWdlc3RFeGNlcHRpb24oKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+RGlnZXN0RXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yIEFzc2VydGlvbjoKKyAgICAgKiBjb25zdHJ1Y3RzIERpZ2VzdEV4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4gUGFyYW1ldGVyCisgICAgICogPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGlnZXN0RXhjZXB0aW9uMDIoKSB7CisgICAgICAgIERpZ2VzdEV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBEaWdlc3RFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5EaWdlc3RFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgRGlnZXN0RXhjZXB0aW9uIHdoZW4gPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdERpZ2VzdEV4Y2VwdGlvbjAzKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICAgICAgRGlnZXN0RXhjZXB0aW9uIHRFID0gbmV3IERpZ2VzdEV4Y2VwdGlvbihtc2cpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5EaWdlc3RFeGNlcHRpb24oVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgRGlnZXN0RXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGlnZXN0RXhjZXB0aW9uMDQoKSB7CisgICAgICAgIFRocm93YWJsZSBjYXVzZSA9IG51bGw7CisgICAgICAgIERpZ2VzdEV4Y2VwdGlvbiB0RSA9IG5ldyBEaWdlc3RFeGNlcHRpb24oY2F1c2UpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5EaWdlc3RFeGNlcHRpb24oVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgRGlnZXN0RXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdERpZ2VzdEV4Y2VwdGlvbjA1KCkgeworICAgICAgICBEaWdlc3RFeGNlcHRpb24gdEUgPSBuZXcgRGlnZXN0RXhjZXB0aW9uKHRDYXVzZSk7CisgICAgICAgIGlmICh0RS5nZXRNZXNzYWdlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgc2hvdWxkIGNvbnRhaW4gIi5jb25jYXQodG9TKSwgKGdldE0KKyAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwgdEUKKyAgICAgICAgICAgICAgICAuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5EaWdlc3RFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBEaWdlc3RFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbAorICAgICAqIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REaWdlc3RFeGNlcHRpb24wNigpIHsKKyAgICAgICAgRGlnZXN0RXhjZXB0aW9uIHRFID0gbmV3IERpZ2VzdEV4Y2VwdGlvbihudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5EaWdlc3RFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBEaWdlc3RFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbAorICAgICAqIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGlnZXN0RXhjZXB0aW9uMDcoKSB7CisgICAgICAgIERpZ2VzdEV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBEaWdlc3RFeGNlcHRpb24obXNnc1tpXSwgbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5EaWdlc3RFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBEaWdlc3RFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90CisgICAgICogbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGlnZXN0RXhjZXB0aW9uMDgoKSB7CisgICAgICAgIERpZ2VzdEV4Y2VwdGlvbiB0RSA9IG5ldyBEaWdlc3RFeGNlcHRpb24obnVsbCwgdENhdXNlKTsKKyAgICAgICAgaWYgKHRFLmdldE1lc3NhZ2UoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IHNob3VsZCAiLmNvbmNhdCh0b1MpLCAoZ2V0TQorICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgIC5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkRpZ2VzdEV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIERpZ2VzdEV4Y2VwdGlvbiB3aGVuIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QKKyAgICAgKiBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGlnZXN0RXhjZXB0aW9uMDkoKSB7CisgICAgICAgIERpZ2VzdEV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBEaWdlc3RFeGNlcHRpb24obXNnc1tpXSwgdENhdXNlKTsKKyAgICAgICAgICAgIFN0cmluZyBnZXRNID0gdEUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgaWYgKG1zZ3NbaV0ubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIG11c3QgY29udGFpbiAiLmNvbmNhdChtc2dzW2ldKSwgZ2V0TQorICAgICAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YobXNnc1tpXSkgIT0gLTEpOworICAgICAgICAgICAgICAgIGlmICghZ2V0TS5lcXVhbHMobXNnc1tpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIHNob3VsZCBjb250YWluICIuY29uY2F0KHRvUyksIGdldE0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLAorICAgICAgICAgICAgICAgICAgICB0RS5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0RpZ2VzdElucHV0U3RyZWFtMlRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9EaWdlc3RJbnB1dFN0cmVhbTJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTA0YTBhOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9EaWdlc3RJbnB1dFN0cmVhbTJUZXN0LmphdmEKQEAgLTAsMCArMSwyMzYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuRGlnZXN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW07CisKK3B1YmxpYyBjbGFzcyBEaWdlc3RJbnB1dFN0cmVhbTJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGluU3RyZWFtOworCisgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gaW5TdHJlYW0xOworCisgICAgTWVzc2FnZURpZ2VzdCBkaWdlc3Q7CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LkRpZ2VzdElucHV0U3RyZWFtI0RpZ2VzdElucHV0U3RyZWFtKGphdmEuaW8uSW5wdXRTdHJlYW0sCisgICAgICogICAgICAgIGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfaW9fSW5wdXRTdHJlYW1MamF2YV9zZWN1cml0eV9NZXNzYWdlRGlnZXN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5zZWN1cml0eS5EaWdlc3RJbnB1dFN0cmVhbShqYXZhLmlvLklucHV0U3RyZWFtLAorICAgICAgICAvLyBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3QpCisgICAgICAgIERpZ2VzdElucHV0U3RyZWFtIGRpcyA9IG5ldyBEaWdlc3RJbnB1dFN0cmVhbShpblN0cmVhbSwgZGlnZXN0KTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ29uc3RydWN0b3IgcmV0dXJuZWQgbnVsbCBpbnN0YW5jZSIsIGRpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5EaWdlc3RJbnB1dFN0cmVhbSNnZXRNZXNzYWdlRGlnZXN0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1lc3NhZ2VEaWdlc3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3QKKyAgICAgICAgLy8gamF2YS5zZWN1cml0eS5EaWdlc3RJbnB1dFN0cmVhbS5nZXRNZXNzYWdlRGlnZXN0KCkKKyAgICAgICAgRGlnZXN0SW5wdXRTdHJlYW0gZGlzID0gbmV3IERpZ2VzdElucHV0U3RyZWFtKGluU3RyZWFtLCBkaWdlc3QpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2VEaWdlc3QgcmV0dXJuZWQgYSBib2d1cyByZXN1bHQiLCBkaWdlc3QsIGRpcworICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlRGlnZXN0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuRGlnZXN0SW5wdXRTdHJlYW0jb24oYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X29uWigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnNlY3VyaXR5LkRpZ2VzdElucHV0U3RyZWFtLm9uKGJvb2xlYW4pCisgICAgICAgIE1lc3NhZ2VEaWdlc3Qgb3JpZ2luYWxEaWdlc3QgPSAoTWVzc2FnZURpZ2VzdCkgKGRpZ2VzdC5jbG9uZSgpKTsKKyAgICAgICAgTWVzc2FnZURpZ2VzdCBub0NoYW5nZURpZ2VzdCA9IChNZXNzYWdlRGlnZXN0KSAoZGlnZXN0LmNsb25lKCkpOworICAgICAgICBEaWdlc3RJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGlnZXN0SW5wdXRTdHJlYW0oaW5TdHJlYW0sIG5vQ2hhbmdlRGlnZXN0KTsKKyAgICAgICAgLy8gdHVybiBvZmYgcHJvY2Vzc2luZworICAgICAgICBkaXMub24oZmFsc2UpOworICAgICAgICAvLyByZWFkIHNvbWUgZGF0YQorICAgICAgICBpbnQgYyA9IGRpcy5yZWFkKCk7CisgICAgICAgIGFzc2VydEVxdWFscygnVCcsIGMpOworCisgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgZGlnZXN0IGZvciB0aGUgcGFydCB3aGVyZSBpdCB3YXMgb2ZmIGhhcyBub3QKKyAgICAgICAgLy8gY2hhbmdlZAorICAgICAgICBhc3NlcnRUcnVlKCJNZXNzYWdlRGlnZXN0IGNoYW5nZWQgZXZlbiB0aG91Z2ggcHJvY2Vzc2luZyB3YXMgb2ZmIiwKKyAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0LmlzRXF1YWwobm9DaGFuZ2VEaWdlc3QuZGlnZXN0KCksIG9yaWdpbmFsRGlnZXN0CisgICAgICAgICAgICAgICAgICAgICAgICAuZGlnZXN0KCkpKTsKKyAgICAgICAgTWVzc2FnZURpZ2VzdCBjaGFuZ2VEaWdlc3QgPSAoTWVzc2FnZURpZ2VzdCkgKGRpZ2VzdC5jbG9uZSgpKTsKKyAgICAgICAgZGlzID0gbmV3IERpZ2VzdElucHV0U3RyZWFtKGluU3RyZWFtLCBkaWdlc3QpOworCisgICAgICAgIC8vIHR1cm4gb24gcHJvY2Vzc2luZworICAgICAgICBkaXMub24odHJ1ZSk7CisgICAgICAgIGMgPSBkaXMucmVhZCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoJ2gnLCBjKTsKKworICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIGRpZ2VzdCBoYXMgY2hhbmdlZAorICAgICAgICBhc3NlcnRUcnVlKCJNZXNzYWdlRGlnZXN0IGRpZCBub3QgY2hhbmdlIHdpdGggcHJvY2Vzc2luZyBvbiIsCisgICAgICAgICAgICAgICAgIU1lc3NhZ2VEaWdlc3QuaXNFcXVhbChkaWdlc3QuZGlnZXN0KCksIGNoYW5nZURpZ2VzdC5kaWdlc3QoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuRGlnZXN0SW5wdXRTdHJlYW0jcmVhZCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnNlY3VyaXR5LkRpZ2VzdElucHV0U3RyZWFtLnJlYWQoKQorICAgICAgICBEaWdlc3RJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGlnZXN0SW5wdXRTdHJlYW0oaW5TdHJlYW0sIGRpZ2VzdCk7CisKKyAgICAgICAgLy8gcmVhZCBhbmQgY29tcGFyZSB0aGUgZGF0YSB0aGF0IHRoZSBpblN0cmVhbSBoYXMKKyAgICAgICAgaW50IGM7CisgICAgICAgIHdoaWxlICgoYyA9IGRpcy5yZWFkKCkpID4gLTEpIHsKKyAgICAgICAgICAgIGludCBkID0gaW5TdHJlYW0xLnJlYWQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhkLCBjKTsKKyAgICAgICAgfS8vIGVuZCB3aGlsZQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuRGlnZXN0SW5wdXRTdHJlYW0jcmVhZChieXRlW10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZCRCSUkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEuc2VjdXJpdHkuRGlnZXN0SW5wdXRTdHJlYW0ucmVhZChieXRlIFtdLAorICAgICAgICAvLyBpbnQsIGludCkKKyAgICAgICAgRGlnZXN0SW5wdXRTdHJlYW0gZGlzID0gbmV3IERpZ2VzdElucHV0U3RyZWFtKGluU3RyZWFtLCBkaWdlc3QpOworICAgICAgICBpbnQgYnl0ZXNUb1JlYWQgPSBpblN0cmVhbS5hdmFpbGFibGUoKTsKKyAgICAgICAgYnl0ZSBidWYxW10gPSBuZXcgYnl0ZVtieXRlc1RvUmVhZCArIDVdOworICAgICAgICBieXRlIGJ1ZjJbXSA9IG5ldyBieXRlW2J5dGVzVG9SZWFkICsgNV07CisgICAgICAgIC8vIG1ha2Ugc3VyZSB3ZSdyZSBhY3R1YWxseSByZWFkaW5nIHNvbWUgZGF0YQorICAgICAgICBhc3NlcnRUcnVlKCJObyBkYXRhIHRvIHJlYWQgZm9yIHRoaXMgdGVzdCIsIGJ5dGVzVG9SZWFkPjApOworCisgICAgICAgIC8vIHJlYWQgYW5kIGNvbXBhcmUgdGhlIGRhdGEgdGhhdCB0aGUgaW5TdHJlYW0gaGFzCisgICAgICAgIGludCBieXRlc1JlYWQxID0gZGlzLnJlYWQoYnVmMSwgNSwgYnl0ZXNUb1JlYWQpOworICAgICAgICBpbnQgYnl0ZXNSZWFkMiA9IGluU3RyZWFtMS5yZWFkKGJ1ZjIsIDUsIGJ5dGVzVG9SZWFkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJEaWRuJ3QgcmVhZCB0aGUgc2FtZSBmcm9tIGVhY2ggc3RyZWFtIiwgYnl0ZXNSZWFkMSwKKyAgICAgICAgICAgICAgICBieXRlc1JlYWQyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJEaWRuJ3QgcmVhZCB0aGUgZW50aXJlIiwgYnl0ZXNSZWFkMSwgYnl0ZXNUb1JlYWQpOworICAgICAgICAvLyBjb21wYXJlIHRoZSBhcnJheXMKKyAgICAgICAgYm9vbGVhbiBzYW1lID0gdHJ1ZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBieXRlc1RvUmVhZCArIDU7IGkrKykgeworICAgICAgICAgICAgaWYgKGJ1ZjFbaV0gIT0gYnVmMltpXSkgeworICAgICAgICAgICAgICAgIHNhbWUgPSBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfS8vIGVuZCBmb3IKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRGlkbid0IGdldCB0aGUgc2FtZSBkYXRhIiwgc2FtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5EaWdlc3RJbnB1dFN0cmVhbSNyZWFkKGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkJEJJSV9FeGNlcHRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBEaWdlc3RJbnB1dFN0cmVhbSBpcyA9IG5ldyBEaWdlc3RJbnB1dFN0cmVhbShpblN0cmVhbSwgZGlnZXN0KTsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZWFkKGJ1ZiwgLTEsIDApOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBidWYgPSBuZXcgYnl0ZVsxMDAwXTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWQoYnVmLCAtMSwgMCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZChidWYsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZWFkKGJ1ZiwgLTEsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcy5yZWFkKGJ1ZiwgMCwgMTAwMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDU6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZChidWYsIDEwMDEsIDApOworICAgICAgICAgICAgZmFpbCgiVGVzdCA2OiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzLnJlYWQoYnVmLCA1MDAsIDUwMSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDc6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBpcy5jbG9zZSgpOworCisgICAgICAgIFN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtIHNpcyA9IG5ldyBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbSh0cnVlKTsKKyAgICAgICAgaXMgPSBuZXcgRGlnZXN0SW5wdXRTdHJlYW0oc2lzLCBkaWdlc3QpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMucmVhZChidWYsIDAsIDEwMCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDk6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICBzaXMudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSBmYWxzZTsKKyAgICAgICAgaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LkRpZ2VzdElucHV0U3RyZWFtI3NldE1lc3NhZ2VEaWdlc3QoamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0TWVzc2FnZURpZ2VzdExqYXZhX3NlY3VyaXR5X01lc3NhZ2VEaWdlc3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkCisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuRGlnZXN0SW5wdXRTdHJlYW0uc2V0TWVzc2FnZURpZ2VzdChqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3QpCisgICAgICAgIERpZ2VzdElucHV0U3RyZWFtIGRpcyA9IG5ldyBEaWdlc3RJbnB1dFN0cmVhbShpblN0cmVhbSwgbnVsbCk7CisKKyAgICAgICAgLy8gbWFrZSBzdXJlIHRoZSBkaWdlc3QgaXMgbnVsbCB3aGVuIGl0J3Mgbm90IGJlZW4gc2V0CisgICAgICAgIGFzc2VydE51bGwoCisgICAgICAgICAgICAgICAgIlVuaW5pdGlhbGlzZWQgTWVzc2FnZURpZ2VzdCBzaG91bGQgaGF2ZSBiZWVuIHJldHVybmVkIGFzIG51bGwiLAorICAgICAgICAgICAgICAgIGRpcy5nZXRNZXNzYWdlRGlnZXN0KCkpOworICAgICAgICBkaXMuc2V0TWVzc2FnZURpZ2VzdChkaWdlc3QpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIE1lc3NhZ2VEaWdlc3Qgd2FzIHJldHVybmVkLiIsIGRpZ2VzdCwgZGlzCisgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2VEaWdlc3QoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIC8vIGNyZWF0ZSBhIEJ5dGVBcnJheUlucHV0U3RyZWFtIHRvIHBlcmZvcm0gZGlnZXN0aW5nIG9uCisgICAgICAgIGluU3RyZWFtID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgICJUaGlzIGlzIGEgdGVzdCBzdHJpbmcgZm9yIGRpZ2VzdGluZyIuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIGluU3RyZWFtMSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICAiVGhpcyBpcyBhIHRlc3Qgc3RyaW5nIGZvciBkaWdlc3RpbmciLmdldEJ5dGVzKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGlnZXN0ID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZSgiU0hBLTEiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuYWJsZSB0byBmaW5kIFNIQS0xIGFsZ29yaXRobSIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0RpZ2VzdElucHV0U3RyZWFtVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0RpZ2VzdElucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIyODQ2MmEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvRGlnZXN0SW5wdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSw1NzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkRpZ2VzdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuTURHb2xkZW5EYXRhOworCisvKioKKyAqIFRlc3RzIGZvciBmaWVsZHMgYW5kIG1ldGhvZHMgb2YgY2xhc3MgPGNvZGU+RGlnZXN0SW5wdXRTdHJlYW08L2NvZGU+CisgKgorICovCitwdWJsaWMgY2xhc3MgRGlnZXN0SW5wdXRTdHJlYW1UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogTWVzc2FnZSBkaWdlc3QgYWxnb3JpdGhtIG5hbWUgdXNlZCBkdXJpbmcgdGVzdGluZworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBhbGdvcml0aG1OYW1lW10gPSB7CisgICAgICAgICAgICAiU0hBLTEiLAorICAgICAgICAgICAgIlNIQSIsCisgICAgICAgICAgICAiU0hBMSIsCisgICAgICAgICAgICAiU0hBLTI1NiIsCisgICAgICAgICAgICAiU0hBLTM4NCIsCisgICAgICAgICAgICAiU0hBLTUxMiIsCisgICAgICAgICAgICAiTUQ1IiwKKyAgICB9OworICAgIC8qKgorICAgICAqIENodW5rIHNpemUgZm9yIHJlYWQoYnl0ZSwgb2ZmLCBsZW4pIHRlc3RzCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENIVU5LX1NJWkUgPSAzMjsKKyAgICAvKioKKyAgICAgKiBUZXN0IG1lc3NhZ2UgZm9yIGRpZ2VzdCBjb21wdXRhdGlvbnMKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gbXlNZXNzYWdlID0gTURHb2xkZW5EYXRhLmdldE1lc3NhZ2UoKTsKKyAgICAvKioKKyAgICAgKiBUaGUgbGVuZ3RoIG9mIHRlc3QgbWVzc2FnZQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNWV9NRVNTQUdFX0xFTiA9IG15TWVzc2FnZS5sZW5ndGg7CisKKyAgICAvLworICAgIC8vIFRlc3RzCisgICAgLy8KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPkRpZ2VzdElucHV0U3RyZWFtPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogY3JlYXRlcyBuZXcgPGNvZGU+RGlnZXN0SW5wdXRTdHJlYW08L2NvZGU+IGluc3RhbmNlCisgICAgICogdXNpbmcgdmFsaWQgcGFyYW1ldGVycyAoYm90aCBub24gPGNvZGU+bnVsbDwvY29kZT4pCisgICAgICoKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3REaWdlc3RJbnB1dFN0cmVhbTAxKCkgIHsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPGFsZ29yaXRobU5hbWUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBtZCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtTmFtZVtpXSk7CisgICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obXlNZXNzYWdlKTsKKyAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGlnZXN0SW5wdXRTdHJlYW0oaXMsIG1kKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGRpcyBpbnN0YW5jZW9mIERpZ2VzdElucHV0U3RyZWFtKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGFsbG93ZWQgZmFpbHVyZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm8gTWVzc2FnZURpZ2VzdCBhbGdvcml0aG1zIGF2YWlsYWJsZSAtIHRlc3Qgbm90IHBlcmZvcm1lZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPkRpZ2VzdElucHV0U3RyZWFtPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogY3JlYXRlcyBuZXcgPGNvZGU+RGlnZXN0SW5wdXRTdHJlYW08L2NvZGU+IGluc3RhbmNlCisgICAgICogdXNpbmcgdmFsaWQgcGFyYW1ldGVycyAoYm90aCA8Y29kZT5udWxsPC9jb2RlPikKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RGlnZXN0SW5wdXRTdHJlYW0wMigpIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gZGlzID0gbmV3IERpZ2VzdElucHV0U3RyZWFtKG51bGwsIG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKGRpcyBpbnN0YW5jZW9mIERpZ2VzdElucHV0U3RyZWFtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5yZWFkKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyB0aGUgYnl0ZSByZWFkPGJyPgorICAgICAqIEFzc2VydGlvbjogdXBkYXRlcyBhc3NvY2lhdGVkIGRpZ2VzdDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UmVhZDAxKCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChpbnQgaWk9MDsgaWk8YWxnb3JpdGhtTmFtZS5sZW5ndGg7IGlpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBtZCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtTmFtZVtpaV0pOworICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG15TWVzc2FnZSk7CisgICAgICAgICAgICAgICAgRGlnZXN0SW5wdXRTdHJlYW0gZGlzID0gbmV3IERpZ2VzdElucHV0U3RyZWFtKGlzLCBtZCk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPE1ZX01FU1NBR0VfTEVOOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCByZWFkKCkgcmV0dXJucyB2YWxpZCB2YWx1ZXMKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgicmV0dmFsIiwgKChieXRlKWRpcy5yZWFkKCkgPT0gbXlNZXNzYWdlW2ldKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgYXNzb2NpYXRlZCBkaWdlc3QgaGFzIGJlZW4gdXBkYXRlZCBwcm9wZXJseQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoInVwZGF0ZSIsCisgICAgICAgICAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXMuZ2V0TWVzc2FnZURpZ2VzdCgpLmRpZ2VzdCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNREdvbGRlbkRhdGEuZ2V0RGlnZXN0KGFsZ29yaXRobU5hbWVbaWldKSkpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gYWxsb3dlZCBmYWlsdXJlCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiOiBubyBNZXNzYWdlRGlnZXN0IGFsZ29yaXRobXMgYXZhaWxhYmxlIC0gdGVzdCBub3QgcGVyZm9ybWVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+cmVhZCgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgLTEgaWYgRU9TIGhhZCBiZWVuCisgICAgICogcmVhY2hlZCBidXQgbm90IHJlYWQgYmVmb3JlIG1ldGhvZCBjYWxsPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBtdXN0IG5vdCB1cGRhdGUgZGlnZXN0IGlmIEVPUyBoYWQgYmVlbgorICAgICAqIHJlYWNoZWQgYnV0IG5vdCByZWFkIGJlZm9yZSBtZXRob2QgY2FsbDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UmVhZDAyKCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChpbnQgaWk9MDsgaWk8YWxnb3JpdGhtTmFtZS5sZW5ndGg7IGlpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBtZCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtTmFtZVtpaV0pOworICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG15TWVzc2FnZSk7CisgICAgICAgICAgICAgICAgRGlnZXN0SW5wdXRTdHJlYW0gZGlzID0gbmV3IERpZ2VzdElucHV0U3RyZWFtKGlzLCBtZCk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPE1ZX01FU1NBR0VfTEVOOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZGlzLnJlYWQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCBzdWJzZXF1ZW50IHJlYWQoKSBjYWxscyByZXR1cm4gLTEgKGVvcykKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInJldHZhbDEiLCAtMSwgZGlzLnJlYWQoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJyZXR2YWwyIiwgLTEsIGRpcy5yZWFkKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygicmV0dmFsMyIsIC0xLCBkaXMucmVhZCgpKTsKKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IDMgcHJldmlvdXMgcmVhZCgpIGNhbGxzIGRpZCBub3QgdXBkYXRlIGRpZ2VzdAorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoInVwZGF0ZSIsCisgICAgICAgICAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKGRpcy5nZXRNZXNzYWdlRGlnZXN0KCkuZGlnZXN0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ER29sZGVuRGF0YS5nZXREaWdlc3QoYWxnb3JpdGhtTmFtZVtpaV0pKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBhbGxvd2VkIGZhaWx1cmUKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IG5vIE1lc3NhZ2VEaWdlc3QgYWxnb3JpdGhtcyBhdmFpbGFibGUgLSB0ZXN0IG5vdCBwZXJmb3JtZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMzIGZvciA8Y29kZT5yZWFkKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5vbihib29sZWFuKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiA8Y29kZT5yZWFkKCk8L2NvZGU+IG11c3Qgbm90IHVwZGF0ZSBkaWdlc3QgaWYgaXQgaXMgb2ZmPGJyPgorICAgICAqIEFzc2VydGlvbjogPGNvZGU+b24oYm9vbGVhbik8L2NvZGU+IHR1cm5zIGRpZ2VzdCBmdW5jdGlvbmFsaXR5IG9uCisgICAgICogKGlmIDxjb2RlPnRydWU8L2NvZGU+IHBhc3NlZCBhcyBhIHBhcmFtZXRlcikgb3Igb2ZmIChpZiA8Y29kZT5mYWxzZTwvY29kZT4KKyAgICAgKiAgcGFzc2VkKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RSZWFkMDMoKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmb3IgKGludCBpaT0wOyBpaTxhbGdvcml0aG1OYW1lLmxlbmd0aDsgaWkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lW2lpXSk7CisgICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obXlNZXNzYWdlKTsKKyAgICAgICAgICAgICAgICBEaWdlc3RJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGlnZXN0SW5wdXRTdHJlYW0oaXMsIG1kKTsKKworICAgICAgICAgICAgICAgIC8vIHR1cm4gZGlnZXN0IG9mZgorICAgICAgICAgICAgICAgIGRpcy5vbihmYWxzZSk7CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8TVlfTUVTU0FHRV9MRU47IGkrKykgeworICAgICAgICAgICAgICAgICAgICBkaXMucmVhZCgpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgZGlnZXN0IHZhbHVlIGhhcyBub3QgYmVlbiB1cGRhdGVkIGJ5IHJlYWQoKQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhkaXMuZ2V0TWVzc2FnZURpZ2VzdCgpLmRpZ2VzdCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgTURHb2xkZW5EYXRhLmdldERpZ2VzdChhbGdvcml0aG1OYW1lW2lpXSsiX05VIikpKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGFsbG93ZWQgZmFpbHVyZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm8gTWVzc2FnZURpZ2VzdCBhbGdvcml0aG1zIGF2YWlsYWJsZSAtIHRlc3Qgbm90IHBlcmZvcm1lZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzQgZm9yIDxjb2RlPnJlYWQoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBicm9rZW4gPGNvZGU+RGlnZXN0SW5wdXRTdHJlYW08L2NvZGU+aW5zdGFuY2U6CisgICAgICogPGNvZGU+SW5wdXRTdHJlYW08L2NvZGU+IG5vdCBzZXQuIDxjb2RlPnJlYWQoKTwvY29kZT4gbXVzdAorICAgICAqIG5vdCB3b3JrCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJlYWQwNCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoaW50IGlpPTA7IGlpPGFsZ29yaXRobU5hbWUubGVuZ3RoOyBpaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QgbWQgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKGFsZ29yaXRobU5hbWVbaWldKTsKKyAgICAgICAgICAgICAgICBEaWdlc3RJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGlnZXN0SW5wdXRTdHJlYW0obnVsbCwgbWQpOworICAgICAgICAgICAgICAgIC8vIG11c3QgcmVzdWx0IGluIGFuIGV4Y2VwdGlvbgorICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxNWV9NRVNTQUdFX0xFTjsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkaXMucmVhZCgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBmYWlsKCJJbnB1dFN0cmVhbSBub3Qgc2V0LiByZWFkKCkgbXVzdCBub3Qgd29yayIpOworCisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGFsbG93ZWQgZmFpbHVyZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm8gTWVzc2FnZURpZ2VzdCBhbGdvcml0aG1zIGF2YWlsYWJsZSAtIHRlc3Qgbm90IHBlcmZvcm1lZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzUgZm9yIDxjb2RlPnJlYWQoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBicm9rZW4gPGNvZGU+RGlnZXN0SW5wdXRTdHJlYW08L2NvZGU+aW5zdGFuY2U6CisgICAgICogYXNzb2NpYXRlZCA8Y29kZT5NZXNzYWdlRGlnZXN0PC9jb2RlPiBub3Qgc2V0LgorICAgICAqIDxjb2RlPnJlYWQoKTwvY29kZT4gbXVzdCBub3Qgd29yayB3aGVuIGRpZ2VzdAorICAgICAqIGZ1bmN0aW9uYWxpdHkgaXMgb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UmVhZDA1KCkgeworICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShteU1lc3NhZ2UpOworICAgICAgICBEaWdlc3RJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGlnZXN0SW5wdXRTdHJlYW0oaXMsIG51bGwpOworCisgICAgICAgIC8vIG11c3QgcmVzdWx0IGluIGFuIGV4Y2VwdGlvbgorICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPE1ZX01FU1NBR0VfTEVOOyBpKyspIHsKKyAgICAgICAgICAgICAgICBkaXMucmVhZCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmFpbCgicmVhZCgpIG11c3Qgbm90IHdvcmsgd2hlbiBkaWdlc3QgZnVuY3Rpb25hbGl0eSBpcyBvbiIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM2IGZvciA8Y29kZT5yZWFkKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5vbihib29sZWFuKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBicm9rZW4gPGNvZGU+RGlnZXN0SW5wdXRTdHJlYW08L2NvZGU+aW5zdGFuY2U6CisgICAgICogYXNzb2NpYXRlZCA8Y29kZT5NZXNzYWdlRGlnZXN0PC9jb2RlPiBub3Qgc2V0LgorICAgICAqIDxjb2RlPnJlYWQoKTwvY29kZT4gbXVzdCB3b3JrIHdoZW4gZGlnZXN0CisgICAgICogZnVuY3Rpb25hbGl0eSBpcyBvZmYKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UmVhZDA2KCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obXlNZXNzYWdlKTsKKyAgICAgICAgLy8gY29uc3RydWN0IG9iamVjdCB3aXRob3V0IGRpZ2VzdAorICAgICAgICBEaWdlc3RJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGlnZXN0SW5wdXRTdHJlYW0oaXMsIG51bGwpOworICAgICAgICAvLyBzZXQgZGlnZXN0IGZ1bmN0aW9uYWxpdHkgdG8gb2ZmCisgICAgICAgIGRpcy5vbihmYWxzZSk7CisgICAgICAgIC8vIHRoZSBmb2xsb3dpbmcgbXVzdCBwYXNzIHdpdGhvdXQgYW55IGV4Y2VwdGlvbgorICAgICAgICBmb3IgKGludCBpPTA7IGk8TVlfTUVTU0FHRV9MRU47IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgoYnl0ZSlkaXMucmVhZCgpID09IG15TWVzc2FnZVtpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5yZWFkKGJ5dGVbXSxpbnQsaW50KTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZDxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogcHV0IGJ5dGVzIHJlYWQgaW50byBzcGVjaWZpZWQgYXJyYXkgYXQgc3BlY2lmaWVkIG9mZnNldDxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogdXBkYXRlcyBhc3NvY2lhdGVkIGRpZ2VzdDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UmVhZGJ5dGVBcnJheWludGludDAxKCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChpbnQgaWk9MDsgaWk8YWxnb3JpdGhtTmFtZS5sZW5ndGg7IGlpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBtZCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtTmFtZVtpaV0pOworICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG15TWVzc2FnZSk7CisgICAgICAgICAgICAgICAgRGlnZXN0SW5wdXRTdHJlYW0gZGlzID0gbmV3IERpZ2VzdElucHV0U3RyZWFtKGlzLCBtZCk7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGJBcnJheSA9IG5ldyBieXRlW01ZX01FU1NBR0VfTEVOXTsKKworICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgcmVhZChieXRlW10saW50LGludCkgcmV0dXJucyB2YWxpZCB2YWx1ZQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoInJldHZhbCIsCisgICAgICAgICAgICAgICAgICAgICAgICBkaXMucmVhZChiQXJyYXksIDAsIGJBcnJheS5sZW5ndGgpID09IE1ZX01FU1NBR0VfTEVOKTsKKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IGJBcnJheSBoYXMgYmVlbiBmaWxsZWQgcHJvcGVybHkKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJiQXJyYXkiLCBBcnJheXMuZXF1YWxzKG15TWVzc2FnZSwgYkFycmF5KSk7CisgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCBhc3NvY2lhdGVkIGRpZ2VzdCBoYXMgYmVlbiB1cGRhdGVkIHByb3Blcmx5CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidXBkYXRlIiwgQXJyYXlzLmVxdWFscyhkaXMuZ2V0TWVzc2FnZURpZ2VzdCgpLmRpZ2VzdCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgTURHb2xkZW5EYXRhLmdldERpZ2VzdChhbGdvcml0aG1OYW1lW2lpXSkpKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGFsbG93ZWQgZmFpbHVyZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm8gTWVzc2FnZURpZ2VzdCBhbGdvcml0aG1zIGF2YWlsYWJsZSAtIHRlc3Qgbm90IHBlcmZvcm1lZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPnJlYWQoYnl0ZVtdLGludCxpbnQpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyByZWFkPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBwdXQgYnl0ZXMgcmVhZCBpbnRvIHNwZWNpZmllZCBhcnJheSBhdCBzcGVjaWZpZWQgb2Zmc2V0PGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiB1cGRhdGVzIGFzc29jaWF0ZWQgZGlnZXN0PGJyPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RSZWFkYnl0ZUFycmF5aW50aW50MDIoKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBjaGVjayBwcmVjb25kaXRpb24KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIE1ZX01FU1NBR0VfTEVOICUgQ0hVTktfU0laRSk7CisKKyAgICAgICAgZm9yIChpbnQgaWk9MDsgaWk8YWxnb3JpdGhtTmFtZS5sZW5ndGg7IGlpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBtZCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtTmFtZVtpaV0pOworICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG15TWVzc2FnZSk7CisgICAgICAgICAgICAgICAgRGlnZXN0SW5wdXRTdHJlYW0gZGlzID0gbmV3IERpZ2VzdElucHV0U3RyZWFtKGlzLCBtZCk7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGJBcnJheSA9IG5ldyBieXRlW01ZX01FU1NBR0VfTEVOXTsKKworICAgICAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxNWV9NRVNTQUdFX0xFTi9DSFVOS19TSVpFOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCByZWFkKGJ5dGVbXSxpbnQsaW50KSByZXR1cm5zIHZhbGlkIHZhbHVlCisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoInJldHZhbCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzLnJlYWQoYkFycmF5LCBpKkNIVU5LX1NJWkUsIENIVU5LX1NJWkUpID09IENIVU5LX1NJWkUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IGJBcnJheSBoYXMgYmVlbiBmaWxsZWQgcHJvcGVybHkKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJiQXJyYXkiLCBBcnJheXMuZXF1YWxzKG15TWVzc2FnZSwgYkFycmF5KSk7CisgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCBhc3NvY2lhdGVkIGRpZ2VzdCBoYXMgYmVlbiB1cGRhdGVkIHByb3Blcmx5CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidXBkYXRlIiwgQXJyYXlzLmVxdWFscyhkaXMuZ2V0TWVzc2FnZURpZ2VzdCgpLmRpZ2VzdCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgTURHb2xkZW5EYXRhLmdldERpZ2VzdChhbGdvcml0aG1OYW1lW2lpXSkpKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGFsbG93ZWQgZmFpbHVyZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm8gTWVzc2FnZURpZ2VzdCBhbGdvcml0aG1zIGF2YWlsYWJsZSAtIHRlc3Qgbm90IHBlcmZvcm1lZCIpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogVGVzdCAjMyBmb3IgPGNvZGU+cmVhZChieXRlW10saW50LGludCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQ8YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHB1dCBieXRlcyByZWFkIGludG8gc3BlY2lmaWVkIGFycmF5IGF0IHNwZWNpZmllZCBvZmZzZXQ8YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHVwZGF0ZXMgYXNzb2NpYXRlZCBkaWdlc3Q8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJlYWRieXRlQXJyYXlpbnRpbnQwMygpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIGNoZWNrIHByZWNvbmRpdGlvbgorICAgICAgICBhc3NlcnRUcnVlKE1ZX01FU1NBR0VfTEVOICUgKENIVU5LX1NJWkUrMSkgIT0gMCk7CisKKyAgICAgICAgZm9yIChpbnQgaWk9MDsgaWk8YWxnb3JpdGhtTmFtZS5sZW5ndGg7IGlpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBtZCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtTmFtZVtpaV0pOworICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG15TWVzc2FnZSk7CisgICAgICAgICAgICAgICAgRGlnZXN0SW5wdXRTdHJlYW0gZGlzID0gbmV3IERpZ2VzdElucHV0U3RyZWFtKGlzLCBtZCk7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGJBcnJheSA9IG5ldyBieXRlW01ZX01FU1NBR0VfTEVOXTsKKworICAgICAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxNWV9NRVNTQUdFX0xFTi8oQ0hVTktfU0laRSsxKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgcmVhZChieXRlW10saW50LGludCkgcmV0dXJucyB2YWxpZCB2YWx1ZQorICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJyZXR2YWwxIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXMucmVhZChiQXJyYXksIGkqKENIVU5LX1NJWkUrMSksIENIVU5LX1NJWkUrMSkgPT0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0hVTktfU0laRSArIDEpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgbGFzdCBjYWxsIHJldHVybnMgcmlnaHQKKyAgICAgICAgICAgICAgICAvLyBudW1iZXIgb2YgcmVtYWluaW5nIGJ5dGVzCisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgicmV0dmFsMiIsCisgICAgICAgICAgICAgICAgICAgICAgICBkaXMucmVhZChiQXJyYXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ZX01FU1NBR0VfTEVOLyhDSFVOS19TSVpFKzEpKihDSFVOS19TSVpFKzEpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNWV9NRVNTQUdFX0xFTiAlIChDSFVOS19TSVpFKzEpKSA9PQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE1ZX01FU1NBR0VfTEVOICUgKENIVU5LX1NJWkUrMSkpKTsKKworICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgYkFycmF5IGhhcyBiZWVuIGZpbGxlZCBwcm9wZXJseQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImJBcnJheSIsIEFycmF5cy5lcXVhbHMobXlNZXNzYWdlLCBiQXJyYXkpKTsKKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IGFzc29jaWF0ZWQgZGlnZXN0IGhhcyBiZWVuIHVwZGF0ZWQgcHJvcGVybHkKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJ1cGRhdGUiLCBBcnJheXMuZXF1YWxzKGRpcy5nZXRNZXNzYWdlRGlnZXN0KCkuZGlnZXN0KCksCisgICAgICAgICAgICAgICAgICAgICAgICBNREdvbGRlbkRhdGEuZ2V0RGlnZXN0KGFsZ29yaXRobU5hbWVbaWldKSkpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gYWxsb3dlZCBmYWlsdXJlCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiOiBubyBNZXNzYWdlRGlnZXN0IGFsZ29yaXRobXMgYXZhaWxhYmxlIC0gdGVzdCBub3QgcGVyZm9ybWVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjNCBmb3IgPGNvZGU+cmVhZChieXRlW10saW50LGludCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQ8YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHVwZGF0ZXMgYXNzb2NpYXRlZCBkaWdlc3Q8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJlYWRieXRlQXJyYXlpbnRpbnQwNCgpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoaW50IGlpPTA7IGlpPGFsZ29yaXRobU5hbWUubGVuZ3RoOyBpaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QgbWQgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKGFsZ29yaXRobU5hbWVbaWldKTsKKyAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShteU1lc3NhZ2UpOworICAgICAgICAgICAgICAgIERpZ2VzdElucHV0U3RyZWFtIGRpcyA9IG5ldyBEaWdlc3RJbnB1dFN0cmVhbShpcywgbWQpOworICAgICAgICAgICAgICAgIGJ5dGVbXSBiQXJyYXkgPSBuZXcgYnl0ZVtNWV9NRVNTQUdFX0xFTl07CisgICAgICAgICAgICAgICAgLy8gcmVhZCBhbGwgYnV0IEVPUworICAgICAgICAgICAgICAgIGRpcy5yZWFkKGJBcnJheSwgMCwgYkFycmF5Lmxlbmd0aCk7CisgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCBzdWJzZXF1ZW50IHJlYWQoYnl0ZVtdLGludCxpbnQpIGNhbGxzIHJldHVybiAtMSAoRU9TKQorICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygicmV0dmFsMSIsIC0xLCBkaXMucmVhZChiQXJyYXksIDAsIDEpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInJldHZhbDIiLCAtMSwgZGlzLnJlYWQoYkFycmF5LCAwLCBiQXJyYXkubGVuZ3RoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJyZXR2YWwzIiwgLTEsIGRpcy5yZWFkKGJBcnJheSwgMCwgMSkpOworICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgMyBwcmV2aW91cyByZWFkKCkgY2FsbHMgZGlkIG5vdCB1cGRhdGUgZGlnZXN0CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidXBkYXRlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMoZGlzLmdldE1lc3NhZ2VEaWdlc3QoKS5kaWdlc3QoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTURHb2xkZW5EYXRhLmdldERpZ2VzdChhbGdvcml0aG1OYW1lW2lpXSkpKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGFsbG93ZWQgZmFpbHVyZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm8gTWVzc2FnZURpZ2VzdCBhbGdvcml0aG1zIGF2YWlsYWJsZSAtIHRlc3Qgbm90IHBlcmZvcm1lZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzUgZm9yIDxjb2RlPnJlYWQoYnl0ZVtdLGludCxpbnQpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyByZWFkPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBwdXQgYnl0ZXMgcmVhZCBpbnRvIHNwZWNpZmllZCBhcnJheSBhdCBzcGVjaWZpZWQgb2Zmc2V0PGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBkb2VzIG5vdCB1cGRhdGUgYXNzb2NpYXRlZCBkaWdlc3QgaWYKKyAgICAgKiBkaWdlc3QgZnVuY3Rpb25hbGl0eSBpcyBvZmY8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJlYWRieXRlQXJyYXlpbnRpbnQwNSgpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIGNoZWNrIHByZWNvbmRpdGlvbgorICAgICAgICBhc3NlcnRFcXVhbHMoMCwgTVlfTUVTU0FHRV9MRU4gJSBDSFVOS19TSVpFKTsKKworICAgICAgICBmb3IgKGludCBpaT0wOyBpaTxhbGdvcml0aG1OYW1lLmxlbmd0aDsgaWkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lW2lpXSk7CisgICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obXlNZXNzYWdlKTsKKyAgICAgICAgICAgICAgICBEaWdlc3RJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGlnZXN0SW5wdXRTdHJlYW0oaXMsIG1kKTsKKyAgICAgICAgICAgICAgICBieXRlW10gYkFycmF5ID0gbmV3IGJ5dGVbTVlfTUVTU0FHRV9MRU5dOworCisgICAgICAgICAgICAgICAgLy8gdHVybiBkaWdlc3Qgb2ZmCisgICAgICAgICAgICAgICAgZGlzLm9uKGZhbHNlKTsKKworICAgICAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxNWV9NRVNTQUdFX0xFTi9DSFVOS19TSVpFOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZGlzLnJlYWQoYkFycmF5LCBpKkNIVU5LX1NJWkUsIENIVU5LX1NJWkUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IGRpZ2VzdCBoYXMgbm90IGJlZW4gdXBkYXRlZAorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhkaXMuZ2V0TWVzc2FnZURpZ2VzdCgpLmRpZ2VzdCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgTURHb2xkZW5EYXRhLmdldERpZ2VzdChhbGdvcml0aG1OYW1lW2lpXSsiX05VIikpKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGFsbG93ZWQgZmFpbHVyZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm8gTWVzc2FnZURpZ2VzdCBhbGdvcml0aG1zIGF2YWlsYWJsZSAtIHRlc3Qgbm90IHBlcmZvcm1lZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldE1lc3NhZ2VEaWdlc3QoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIGFzc29jaWF0ZWQgbWVzc2FnZSBkaWdlc3Q8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldE1lc3NhZ2VEaWdlc3QoKSB7CisgICAgICAgIGZvciAoaW50IGlpPTA7IGlpPGFsZ29yaXRobU5hbWUubGVuZ3RoOyBpaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QgbWQgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKGFsZ29yaXRobU5hbWVbaWldKTsKKyAgICAgICAgICAgICAgICBEaWdlc3RJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGlnZXN0SW5wdXRTdHJlYW0obnVsbCwgbWQpOworCisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShkaXMuZ2V0TWVzc2FnZURpZ2VzdCgpID09IG1kKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGFsbG93ZWQgZmFpbHVyZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm8gTWVzc2FnZURpZ2VzdCBhbGdvcml0aG1zIGF2YWlsYWJsZSAtIHRlc3Qgbm90IHBlcmZvcm1lZCIpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+c2V0TWVzc2FnZURpZ2VzdCgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHNldCBhc3NvY2lhdGVkIG1lc3NhZ2UgZGlnZXN0PGJyPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RTZXRNZXNzYWdlRGlnZXN0KCkgeworICAgICAgICBmb3IgKGludCBpaT0wOyBpaTxhbGdvcml0aG1OYW1lLmxlbmd0aDsgaWkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBEaWdlc3RJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGlnZXN0SW5wdXRTdHJlYW0obnVsbCwgbnVsbCk7CisgICAgICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBtZCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtTmFtZVtpaV0pOworICAgICAgICAgICAgICAgIGRpcy5zZXRNZXNzYWdlRGlnZXN0KG1kKTsKKworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoZGlzLmdldE1lc3NhZ2VEaWdlc3QoKSA9PSBtZCk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBhbGxvd2VkIGZhaWx1cmUKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IG5vIE1lc3NhZ2VEaWdlc3QgYWxnb3JpdGhtcyBhdmFpbGFibGUgLSB0ZXN0IG5vdCBwZXJmb3JtZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5vbigpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiB0dXJucyBkaWdlc3QgZnVuY3Rpb25hbGl0eSBvbiBvciBvZmYKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0T24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmb3IgKGludCBpaT0wOyBpaTxhbGdvcml0aG1OYW1lLmxlbmd0aDsgaWkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lW2lpXSk7CisgICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obXlNZXNzYWdlKTsKKyAgICAgICAgICAgICAgICBEaWdlc3RJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGlnZXN0SW5wdXRTdHJlYW0oaXMsIG1kKTsKKworICAgICAgICAgICAgICAgIC8vIHR1cm4gZGlnZXN0IG9mZgorICAgICAgICAgICAgICAgIGRpcy5vbihmYWxzZSk7CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8TVlfTUVTU0FHRV9MRU4tMTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGRpcy5yZWFkKCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gdHVybiBkaWdlc3Qgb24KKyAgICAgICAgICAgICAgICBkaXMub24odHJ1ZSk7CisKKyAgICAgICAgICAgICAgICAvLyByZWFkIHJlbWFpbmluZyBieXRlCisgICAgICAgICAgICAgICAgZGlzLnJlYWQoKTsKKworICAgICAgICAgICAgICAgIGJ5dGVbXSBkaWdlc3QgPSBkaXMuZ2V0TWVzc2FnZURpZ2VzdCgpLmRpZ2VzdCgpOworCisgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCBkaWdlc3QgdmFsdWUgaGFzIGJlZW4KKyAgICAgICAgICAgICAgICAvLyB1cGRhdGVkIGJ5IHRoZSBsYXN0IHJlYWQoKSBjYWxsCisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKGRpZ2VzdCxNREdvbGRlbkRhdGEuZ2V0RGlnZXN0KGFsZ29yaXRobU5hbWVbaWldKSkgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMoZGlnZXN0LE1ER29sZGVuRGF0YS5nZXREaWdlc3QoYWxnb3JpdGhtTmFtZVtpaV0rIl9OVSIpKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBhbGxvd2VkIGZhaWx1cmUKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IG5vIE1lc3NhZ2VEaWdlc3QgYWxnb3JpdGhtcyBhdmFpbGFibGUgLSB0ZXN0IG5vdCBwZXJmb3JtZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT50b1N0cmluZygpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIDxjb2RlPlN0cmluZzwvY29kZT4gcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0VG9TdHJpbmcoKSB7CisgICAgICAgIGZvciAoaW50IGlpPTA7IGlpPGFsZ29yaXRobU5hbWUubGVuZ3RoOyBpaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QgbWQgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKGFsZ29yaXRobU5hbWVbaWldKTsKKyAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShteU1lc3NhZ2UpOworICAgICAgICAgICAgICAgIERpZ2VzdElucHV0U3RyZWFtIGRpcyA9IG5ldyBEaWdlc3RJbnB1dFN0cmVhbShpcywgbWQpOworCisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChkaXMudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBhbGxvd2VkIGZhaWx1cmUKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IG5vIE1lc3NhZ2VEaWdlc3QgYWxnb3JpdGhtcyBhdmFpbGFibGUgLSB0ZXN0IG5vdCBwZXJmb3JtZWQiKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9EaWdlc3RPdXRwdXRTdHJlYW1UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvRGlnZXN0T3V0cHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ5MGM4ZWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvRGlnZXN0T3V0cHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjE3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkRpZ2VzdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuTURHb2xkZW5EYXRhOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0Lk15TWVzc2FnZURpZ2VzdDE7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X091dHB1dFN0cmVhbTsKKworLyoqCisgKiBUZXN0cyBmb3IgZmllbGRzIGFuZCBtZXRob2RzIG9mIGNsYXNzIDxjb2RlPkRpZ2VzdElucHV0U3RyZWFtPC9jb2RlPgorICoKKyAqLworcHVibGljIGNsYXNzIERpZ2VzdE91dHB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBNZXNzYWdlIGRpZ2VzdCBhbGdvcml0aG0gbmFtZSB1c2VkIGR1cmluZyB0ZXN0aW5nCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGFsZ29yaXRobU5hbWVbXSA9IHsKKyAgICAgICAgICAgICJTSEEtMSIsCisgICAgICAgICAgICAiU0hBIiwKKyAgICAgICAgICAgICJTSEExIiwKKyAgICAgICAgICAgICJTSEEtMjU2IiwKKyAgICAgICAgICAgICJTSEEtMzg0IiwKKyAgICAgICAgICAgICJTSEEtNTEyIiwKKyAgICAgICAgICAgICJNRDUiLAorICAgIH07CisgICAgLyoqCisgICAgICogQ2h1bmsgc2l6ZSBmb3IgcmVhZChieXRlLCBvZmYsIGxlbikgdGVzdHMKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0hVTktfU0laRSA9IDMyOworICAgIC8qKgorICAgICAqIFRlc3QgbWVzc2FnZSBmb3IgZGlnZXN0IGNvbXB1dGF0aW9ucworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBteU1lc3NhZ2UgPSBNREdvbGRlbkRhdGEuZ2V0TWVzc2FnZSgpOworICAgIC8qKgorICAgICAqIFRoZSBsZW5ndGggb2YgdGVzdCBtZXNzYWdlCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1ZX01FU1NBR0VfTEVOID0gbXlNZXNzYWdlLmxlbmd0aDsKKworICAgIC8vCisgICAgLy8gVGVzdHMKKyAgICAvLworCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5EaWdlc3RPdXRwdXRTdHJlYW0jRGlnZXN0T3V0cHV0U3RyZWFtKGphdmEuaW8uT3V0cHV0U3RyZWFtLAorICAgICAqICAgICAgICBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9DdG9yTGphdmFfaW9fT3V0cHV0U3RyZWFtTGphdmFfc2VjdXJpdHlfTWVzc2FnZURpZ2VzdCgpIHsKKworICAgICAgICAvLyBub24tbnVsbCBwYXJhbWV0ZXJzCisgICAgICAgIE1lc3NhZ2VEaWdlc3QgbWQgPSBuZXcgTXlNZXNzYWdlRGlnZXN0MSgpOworICAgICAgICBNeU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgTXlPdXRwdXRTdHJlYW0oKTsKKworICAgICAgICBNeURpZ2VzdE91dHB1dFN0cmVhbSBkb3MgPSBuZXcgTXlEaWdlc3RPdXRwdXRTdHJlYW0ob3V0LCBtZCk7CisgICAgICAgIGFzc2VydFNhbWUob3V0LCBkb3MubXlPdXRwdXRTdHJlYW0oKSk7CisgICAgICAgIGFzc2VydFNhbWUobWQsIGRvcy5teU1lc3NhZ2VEaWdlc3QoKSk7CisKKyAgICAgICAgLy8gbnVsbCBwYXJhbWV0ZXJzCisgICAgICAgIGRvcyA9IG5ldyBNeURpZ2VzdE91dHB1dFN0cmVhbShudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChkb3MubXlPdXRwdXRTdHJlYW0oKSk7CisgICAgICAgIGFzc2VydE51bGwoZG9zLm15TWVzc2FnZURpZ2VzdCgpKTsKKworICAgICAgICBkb3MgPSBuZXcgTXlEaWdlc3RPdXRwdXRTdHJlYW0obnVsbCwgbWQpOworICAgICAgICBhc3NlcnROdWxsKGRvcy5teU91dHB1dFN0cmVhbSgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChkb3MubXlNZXNzYWdlRGlnZXN0KCkpOworCisgICAgICAgIGRvcyA9IG5ldyBNeURpZ2VzdE91dHB1dFN0cmVhbShvdXQsIG51bGwpOworICAgICAgICBhc3NlcnROb3ROdWxsKGRvcy5teU91dHB1dFN0cmVhbSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChkb3MubXlNZXNzYWdlRGlnZXN0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuRGlnZXN0T3V0cHV0U3RyZWFtI2dldE1lc3NhZ2VEaWdlc3QoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TWVzc2FnZURpZ2VzdCgpIHsKKworICAgICAgICBNZXNzYWdlRGlnZXN0IGRpZ2VzdCA9IG5ldyBNeU1lc3NhZ2VEaWdlc3QxKCk7CisgICAgICAgIE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgTXlPdXRwdXRTdHJlYW0oKTsKKworICAgICAgICAvLyBub24tbnVsbCBwYXJhbWV0ZXIKKyAgICAgICAgRGlnZXN0T3V0cHV0U3RyZWFtIGRvcyA9IG5ldyBEaWdlc3RPdXRwdXRTdHJlYW0ob3V0LCBkaWdlc3QpOworICAgICAgICBhc3NlcnRTYW1lKGRpZ2VzdCwgZG9zLmdldE1lc3NhZ2VEaWdlc3QoKSk7CisKKyAgICAgICAgLy8gbnVsbCBwYXJhbWV0ZXIKKyAgICAgICAgZG9zID0gbmV3IERpZ2VzdE91dHB1dFN0cmVhbShvdXQsIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlRGlnZXN0IHNob3VsZCBoYXZlIHJldHVybmVkIG51bGwiLCBkb3MuZ2V0TWVzc2FnZURpZ2VzdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LkRpZ2VzdE91dHB1dFN0cmVhbSNzZXRNZXNzYWdlRGlnZXN0KE1lc3NhZ2VEaWdlc3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRNZXNzYWdlRGlnZXN0TGphdmFfc2VjdXJpdHlfTWVzc2FnZURpZ2VzdCgpIHsKKworICAgICAgICBNZXNzYWdlRGlnZXN0IGRpZ2VzdCA9IG5ldyBNeU1lc3NhZ2VEaWdlc3QxKCk7CisgICAgICAgIE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgTXlPdXRwdXRTdHJlYW0oKTsKKworICAgICAgICBEaWdlc3RPdXRwdXRTdHJlYW0gZG9zID0gbmV3IERpZ2VzdE91dHB1dFN0cmVhbShvdXQsIG51bGwpOworCisgICAgICAgIC8vIG5vbi1udWxsIHBhcmFtZXRlcgorICAgICAgICBkb3Muc2V0TWVzc2FnZURpZ2VzdChkaWdlc3QpOworICAgICAgICBhc3NlcnRTYW1lKGRpZ2VzdCwgZG9zLmdldE1lc3NhZ2VEaWdlc3QoKSk7CisKKyAgICAgICAgLy8gbnVsbCBwYXJhbWV0ZXIKKyAgICAgICAgZG9zLnNldE1lc3NhZ2VEaWdlc3QobnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2VEaWdlc3Qgc2hvdWxkIGhhdmUgcmV0dXJuZWQgbnVsbCIsIGRvcy5nZXRNZXNzYWdlRGlnZXN0KCkpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+d3JpdGUoaW50KTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiB3cml0ZXMgdGhlIGJ5dGUgdG8gdGhlIG91dHB1dCBzdHJlYW08YnI+CisgICAgICogQXNzZXJ0aW9uOiB1cGRhdGVzIGFzc29jaWF0ZWQgZGlnZXN0PGJyPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RXcml0ZWludDAxKCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChpbnQgaz0wOyBrPGFsZ29yaXRobU5hbWUubGVuZ3RoOyBrKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBtZCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtTmFtZVtrXSk7CisgICAgICAgICAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oTVlfTUVTU0FHRV9MRU4pOworICAgICAgICAgICAgICAgIERpZ2VzdE91dHB1dFN0cmVhbSBkb3MgPSBuZXcgRGlnZXN0T3V0cHV0U3RyZWFtKGJvcywgbWQpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxNWV9NRVNTQUdFX0xFTjsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGRvcy53cml0ZShteU1lc3NhZ2VbaV0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IGJ5dGVzIGhhdmUgYmVlbiB3cml0dGVuIGNvcnJlY3RseQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIndyaXRlIiwgQXJyYXlzLmVxdWFscyhNREdvbGRlbkRhdGEuZ2V0TWVzc2FnZSgpLCBib3MudG9CeXRlQXJyYXkoKSkpOworICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgYXNzb2NpYXRlZCBkaWdlc3QgaGFzIGJlZW4gdXBkYXRlZCBwcm9wZXJseQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoInVwZGF0ZSIsIEFycmF5cy5lcXVhbHMoZG9zLmdldE1lc3NhZ2VEaWdlc3QoKS5kaWdlc3QoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ER29sZGVuRGF0YS5nZXREaWdlc3QoYWxnb3JpdGhtTmFtZVtrXSkpKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGFsbG93ZWQgZmFpbHVyZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm8gTWVzc2FnZURpZ2VzdCBhbGdvcml0aG1zIGF2YWlsYWJsZSAtIHRlc3Qgbm90IHBlcmZvcm1lZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPndyaXRlKGludCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5vbihib29sZWFuKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiA8Y29kZT53cml0ZShpbnQpPC9jb2RlPiBtdXN0IG5vdCB1cGRhdGUgZGlnZXN0IGlmIGl0IGlzIG9mZjxicj4KKyAgICAgKiBBc3NlcnRpb246IDxjb2RlPm9uKGJvb2xlYW4pPC9jb2RlPiB0dXJucyBkaWdlc3QgZnVuY3Rpb25hbGl0eSBvbgorICAgICAqIGlmIDxjb2RlPnRydWU8L2NvZGU+IHBhc3NlZCBhcyBhIHBhcmFtZXRlciBvciBvZmYgaWYgPGNvZGU+ZmFsc2U8L2NvZGU+CisgICAgICogcGFzc2VkCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFdyaXRlaW50MDIoKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmb3IgKGludCBrPTA7IGs8YWxnb3JpdGhtTmFtZS5sZW5ndGg7IGsrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lW2tdKTsKKyAgICAgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbShNWV9NRVNTQUdFX0xFTik7CisgICAgICAgICAgICAgICAgRGlnZXN0T3V0cHV0U3RyZWFtIGRvcyA9IG5ldyBEaWdlc3RPdXRwdXRTdHJlYW0oYm9zLCBtZCk7CisKKyAgICAgICAgICAgICAgICAvLyB0dXJuIGRpZ2VzdCBvZmYKKyAgICAgICAgICAgICAgICBkb3Mub24oZmFsc2UpOworCisgICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPE1ZX01FU1NBR0VfTEVOOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZG9zLndyaXRlKG15TWVzc2FnZVtpXSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCBieXRlcyBoYXZlIGJlZW4gd3JpdHRlbiBjb3JyZWN0bHkKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJ3cml0ZSIsIEFycmF5cy5lcXVhbHMoTURHb2xkZW5EYXRhLmdldE1lc3NhZ2UoKSwgYm9zLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IGRpZ2VzdCB2YWx1ZSBoYXMgbm90IGJlZW4gdXBkYXRlZCBieSB3cml0ZSgpCisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidXBkYXRlIiwgQXJyYXlzLmVxdWFscyhkb3MuZ2V0TWVzc2FnZURpZ2VzdCgpLmRpZ2VzdCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTURHb2xkZW5EYXRhLmdldERpZ2VzdChhbGdvcml0aG1OYW1lW2tdKyJfTlUiKSkpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gYWxsb3dlZCBmYWlsdXJlCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiOiBubyBNZXNzYWdlRGlnZXN0IGFsZ29yaXRobXMgYXZhaWxhYmxlIC0gdGVzdCBub3QgcGVyZm9ybWVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMyBmb3IgPGNvZGU+d3JpdGUoaW50KTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBicm9rZW4gPGNvZGU+RGlnZXN0T3V0cHV0U3RyZWFtPC9jb2RlPmluc3RhbmNlOgorICAgICAqIDxjb2RlPk91dHB1dFN0cmVhbTwvY29kZT4gbm90IHNldC4gPGNvZGU+d3JpdGUoaW50KTwvY29kZT4gbXVzdAorICAgICAqIG5vdCB3b3JrCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFdyaXRlaW50MDMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmb3IgKGludCBrPTA7IGs8YWxnb3JpdGhtTmFtZS5sZW5ndGg7IGsrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lW2tdKTsKKyAgICAgICAgICAgICAgICBEaWdlc3RPdXRwdXRTdHJlYW0gZG9zID0gbmV3IERpZ2VzdE91dHB1dFN0cmVhbShudWxsLCBtZCk7CisgICAgICAgICAgICAgICAgLy8gbXVzdCByZXN1bHQgaW4gYW4gZXhjZXB0aW9uCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPE1ZX01FU1NBR0VfTEVOOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRvcy53cml0ZShteU1lc3NhZ2VbaV0pOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIk91dHB1dFN0cmVhbSBub3Qgc2V0LiB3cml0ZShpbnQpIG11c3Qgbm90IHdvcmsiKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBhbGxvd2VkIGZhaWx1cmUKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IG5vIE1lc3NhZ2VEaWdlc3QgYWxnb3JpdGhtcyBhdmFpbGFibGUgLSB0ZXN0IG5vdCBwZXJmb3JtZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM0IGZvciA8Y29kZT53cml0ZShpbnQpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IGJyb2tlbiA8Y29kZT5EaWdlc3RPdXRwdXRTdHJlYW08L2NvZGU+aW5zdGFuY2U6CisgICAgICogYXNzb2NpYXRlZCA8Y29kZT5NZXNzYWdlRGlnZXN0PC9jb2RlPiBub3Qgc2V0LgorICAgICAqIDxjb2RlPndyaXRlKGludCk8L2NvZGU+IG11c3Qgbm90IHdvcmsgd2hlbiBkaWdlc3QKKyAgICAgKiBmdW5jdGlvbmFsaXR5IGlzIG9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFdyaXRlaW50MDQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBPdXRwdXRTdHJlYW0gb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKE1ZX01FU1NBR0VfTEVOKTsKKyAgICAgICAgRGlnZXN0T3V0cHV0U3RyZWFtIGRvcyA9IG5ldyBEaWdlc3RPdXRwdXRTdHJlYW0ob3MsIG51bGwpOworCisgICAgICAgIC8vIG11c3QgcmVzdWx0IGluIGFuIGV4Y2VwdGlvbgorICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPE1ZX01FU1NBR0VfTEVOOyBpKyspIHsKKyAgICAgICAgICAgICAgICBkb3Mud3JpdGUobXlNZXNzYWdlW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZhaWwoIk91dHB1dFN0cmVhbSBub3Qgc2V0LiB3cml0ZShpbnQpIG11c3Qgbm90IHdvcmsiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzUgZm9yIDxjb2RlPndyaXRlKGludCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5vbihib29sZWFuKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBicm9rZW4gPGNvZGU+RGlnZXN0T3V0cHV0U3RyZWFtPC9jb2RlPmluc3RhbmNlOgorICAgICAqIGFzc29jaWF0ZWQgPGNvZGU+TWVzc2FnZURpZ2VzdDwvY29kZT4gbm90IHNldC4KKyAgICAgKiA8Y29kZT53cml0ZShpbnQpPC9jb2RlPiBtdXN0IHdvcmsgd2hlbiBkaWdlc3QKKyAgICAgKiBmdW5jdGlvbmFsaXR5IGlzIG9mZgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RXcml0ZWludDA1KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oTVlfTUVTU0FHRV9MRU4pOworICAgICAgICBEaWdlc3RPdXRwdXRTdHJlYW0gZG9zID0gbmV3IERpZ2VzdE91dHB1dFN0cmVhbShib3MsIG51bGwpOworICAgICAgICAvLyBzZXQgZGlnZXN0IGZ1bmN0aW9uYWxpdHkgdG8gb2ZmCisgICAgICAgIGRvcy5vbihmYWxzZSk7CisgICAgICAgIC8vIHRoZSBmb2xsb3dpbmcgbXVzdCBwYXNzIHdpdGhvdXQgYW55IGV4Y2VwdGlvbgorICAgICAgICBmb3IgKGludCBpPTA7IGk8TVlfTUVTU0FHRV9MRU47IGkrKykgeworICAgICAgICAgICAgZG9zLndyaXRlKG15TWVzc2FnZVtpXSk7CisgICAgICAgIH0KKyAgICAgICAgLy8gY2hlY2sgdGhhdCBieXRlcyBoYXZlIGJlZW4gd3JpdHRlbiBjb3JyZWN0bHkKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKE1ER29sZGVuRGF0YS5nZXRNZXNzYWdlKCksIGJvcy50b0J5dGVBcnJheSgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+d3JpdGUoYnl0ZVtdLGludCxpbnQpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHB1dCBieXRlcyBpbnRvIG91dHB1dCBzdHJlYW08YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHVwZGF0ZXMgYXNzb2NpYXRlZCBkaWdlc3Q8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF93cml0ZSRCSUlfMSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoaW50IGs9MDsgazxhbGdvcml0aG1OYW1lLmxlbmd0aDsgaysrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKE1ZX01FU1NBR0VfTEVOKTsKKyAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lW2tdKTsKKyAgICAgICAgICAgICAgICBEaWdlc3RPdXRwdXRTdHJlYW0gZG9zID0gbmV3IERpZ2VzdE91dHB1dFN0cmVhbShib3MsIG1kKTsKKworICAgICAgICAgICAgICAgIC8vIHdyaXRlIG1lc3NhZ2UgYXQgb25jZQorICAgICAgICAgICAgICAgIGRvcy53cml0ZShteU1lc3NhZ2UsIDAsIE1ZX01FU1NBR0VfTEVOKTsKKworICAgICAgICAgICAgICAgIC8vIGNoZWNrIHdyaXRlCisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgid3JpdGUiLCBBcnJheXMuZXF1YWxzKG15TWVzc2FnZSwgYm9zLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IGFzc29jaWF0ZWQgZGlnZXN0IGhhcyBiZWVuIHVwZGF0ZWQgcHJvcGVybHkKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJ1cGRhdGUiLCBBcnJheXMuZXF1YWxzKGRvcy5nZXRNZXNzYWdlRGlnZXN0KCkuZGlnZXN0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNREdvbGRlbkRhdGEuZ2V0RGlnZXN0KGFsZ29yaXRobU5hbWVba10pKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBhbGxvd2VkIGZhaWx1cmUKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IG5vIE1lc3NhZ2VEaWdlc3QgYWxnb3JpdGhtcyBhdmFpbGFibGUgLSB0ZXN0IG5vdCBwZXJmb3JtZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT53cml0ZShieXRlW10saW50LGludCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogcHV0IGJ5dGVzIGludG8gb3V0cHV0IHN0cmVhbTxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogdXBkYXRlcyBhc3NvY2lhdGVkIGRpZ2VzdDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X3dyaXRlJEJJSV8yKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gY2hlY2sgcHJlY29uZGl0aW9uCisgICAgICAgIGFzc2VydEVxdWFscygwLCBNWV9NRVNTQUdFX0xFTiAlIENIVU5LX1NJWkUpOworICAgICAgICBmb3IgKGludCBrPTA7IGs8YWxnb3JpdGhtTmFtZS5sZW5ndGg7IGsrKykgeworICAgICAgICAgICAgdHJ5IHsKKworICAgICAgICAgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKE1ZX01FU1NBR0VfTEVOKTsKKyAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lW2tdKTsKKyAgICAgICAgICAgICAgICBEaWdlc3RPdXRwdXRTdHJlYW0gZG9zID0gbmV3IERpZ2VzdE91dHB1dFN0cmVhbShib3MsIG1kKTsKKworICAgICAgICAgICAgICAgIC8vIHdyaXRlIG1lc3NhZ2UgYnkgY2h1bmtzCisgICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPE1ZX01FU1NBR0VfTEVOL0NIVU5LX1NJWkU7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBkb3Mud3JpdGUobXlNZXNzYWdlLCBpKkNIVU5LX1NJWkUsIENIVU5LX1NJWkUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBjaGVjayB3cml0ZQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIndyaXRlIiwgQXJyYXlzLmVxdWFscyhteU1lc3NhZ2UsIGJvcy50b0J5dGVBcnJheSgpKSk7CisgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCBhc3NvY2lhdGVkIGRpZ2VzdCBoYXMgYmVlbiB1cGRhdGVkIHByb3Blcmx5CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidXBkYXRlIiwgQXJyYXlzLmVxdWFscyhkb3MuZ2V0TWVzc2FnZURpZ2VzdCgpLmRpZ2VzdCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgTURHb2xkZW5EYXRhLmdldERpZ2VzdChhbGdvcml0aG1OYW1lW2tdKSkpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gYWxsb3dlZCBmYWlsdXJlCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiOiBubyBNZXNzYWdlRGlnZXN0IGFsZ29yaXRobXMgYXZhaWxhYmxlIC0gdGVzdCBub3QgcGVyZm9ybWVkIik7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMzIGZvciA8Y29kZT53cml0ZShieXRlW10saW50LGludCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogcHV0IGJ5dGVzIGludG8gb3V0cHV0IHN0cmVhbTxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogdXBkYXRlcyBhc3NvY2lhdGVkIGRpZ2VzdDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X3dyaXRlJEJJSV8zKCkKKyAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gY2hlY2sgcHJlY29uZGl0aW9uCisgICAgICAgIGFzc2VydFRydWUoTVlfTUVTU0FHRV9MRU4gJSAoQ0hVTktfU0laRSsxKSAhPSAwKTsKKworICAgICAgICBmb3IgKGludCBrPTA7IGs8YWxnb3JpdGhtTmFtZS5sZW5ndGg7IGsrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbShNWV9NRVNTQUdFX0xFTik7CisgICAgICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBtZCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtTmFtZVtrXSk7CisgICAgICAgICAgICAgICAgRGlnZXN0T3V0cHV0U3RyZWFtIGRvcyA9IG5ldyBEaWdlc3RPdXRwdXRTdHJlYW0oYm9zLCBtZCk7CisKKyAgICAgICAgICAgICAgICAvLyB3cml0ZSBtZXNzYWdlIGJ5IGNodW5rcworICAgICAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxNWV9NRVNTQUdFX0xFTi8oQ0hVTktfU0laRSsxKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGRvcy53cml0ZShteU1lc3NhZ2UsIGkqKENIVU5LX1NJWkUrMSksIENIVU5LX1NJWkUrMSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIHdyaXRlIHJlbWFpbmluZyBieXRlcworICAgICAgICAgICAgICAgIGRvcy53cml0ZShteU1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICBNWV9NRVNTQUdFX0xFTi8oQ0hVTktfU0laRSsxKSooQ0hVTktfU0laRSsxKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIE1ZX01FU1NBR0VfTEVOICUgKENIVU5LX1NJWkUrMSkpOworICAgICAgICAgICAgICAgIC8vIGNoZWNrIHdyaXRlCisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgid3JpdGUiLCBBcnJheXMuZXF1YWxzKG15TWVzc2FnZSwgYm9zLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IGFzc29jaWF0ZWQgZGlnZXN0IGhhcyBiZWVuIHVwZGF0ZWQgcHJvcGVybHkKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJ1cGRhdGUiLCBBcnJheXMuZXF1YWxzKGRvcy5nZXRNZXNzYWdlRGlnZXN0KCkuZGlnZXN0KCksCisgICAgICAgICAgICAgICAgICAgICAgICBNREdvbGRlbkRhdGEuZ2V0RGlnZXN0KGFsZ29yaXRobU5hbWVba10pKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBhbGxvd2VkIGZhaWx1cmUKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IG5vIE1lc3NhZ2VEaWdlc3QgYWxnb3JpdGhtcyBhdmFpbGFibGUgLSB0ZXN0IG5vdCBwZXJmb3JtZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM0IGZvciA8Y29kZT53cml0ZShieXRlW10saW50LGludCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogcHV0IGJ5dGVzIGludG8gb3V0cHV0IHN0cmVhbTxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogZG9lcyBub3QgdXBkYXRlIGFzc29jaWF0ZWQgZGlnZXN0IGlmIGRpZ2VzdAorICAgICAqIGZ1bmN0aW9uYWxpdHkgaXMgb2ZmPGJyPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3Rfd3JpdGUkQklJXzQoKQorICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgSU9FeGNlcHRpb24geworICAgICAgICAvLyBjaGVjayBwcmVjb25kaXRpb24KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIE1ZX01FU1NBR0VfTEVOICUgQ0hVTktfU0laRSk7CisKKyAgICAgICAgZm9yIChpbnQgaz0wOyBrPGFsZ29yaXRobU5hbWUubGVuZ3RoOyBrKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oTVlfTUVTU0FHRV9MRU4pOworICAgICAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QgbWQgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKGFsZ29yaXRobU5hbWVba10pOworICAgICAgICAgICAgICAgIERpZ2VzdE91dHB1dFN0cmVhbSBkb3MgPSBuZXcgRGlnZXN0T3V0cHV0U3RyZWFtKGJvcywgbWQpOworCisgICAgICAgICAgICAgICAgLy8gc2V0IGRpZ2VzdCBmdW5jdGlvbmFsaXR5IG9mZgorICAgICAgICAgICAgICAgIGRvcy5vbihmYWxzZSk7CisKKyAgICAgICAgICAgICAgICAvLyB3cml0ZSBtZXNzYWdlIGJ5IGNodW5rcworICAgICAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxNWV9NRVNTQUdFX0xFTi9DSFVOS19TSVpFOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZG9zLndyaXRlKG15TWVzc2FnZSwgaSpDSFVOS19TSVpFLCBDSFVOS19TSVpFKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBjaGVjayB3cml0ZQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIndyaXRlIiwgQXJyYXlzLmVxdWFscyhteU1lc3NhZ2UsIGJvcy50b0J5dGVBcnJheSgpKSk7CisgICAgICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCBhc3NvY2lhdGVkIGRpZ2VzdCBoYXMgbm90IGJlZW4gdXBkYXRlZAorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoInVwZGF0ZSIsIEFycmF5cy5lcXVhbHMoZG9zLmdldE1lc3NhZ2VEaWdlc3QoKS5kaWdlc3QoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIE1ER29sZGVuRGF0YS5nZXREaWdlc3QoYWxnb3JpdGhtTmFtZVtrXSsiX05VIikpKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGFsbG93ZWQgZmFpbHVyZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm8gTWVzc2FnZURpZ2VzdCBhbGdvcml0aG1zIGF2YWlsYWJsZSAtIHRlc3Qgbm90IHBlcmZvcm1lZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuRGlnZXN0T3V0cHV0U3RyZWFtI3dyaXRlKGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZSRCSUlfNigpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9ybSBIQVJNT05ZLTEwOTEuCisgICAgICAgIE1lc3NhZ2VEaWdlc3QgbWQgPSBuZXcgTXlNZXNzYWdlRGlnZXN0MSgpOworICAgICAgICBieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVtdIHsgMSwgMiB9OworICAgICAgICBEaWdlc3RPdXRwdXRTdHJlYW0gZGlnID0gbmV3IERpZ2VzdE91dHB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCksIG1kKTsKKyAgICAgICAgLy8gYnVmID09IG51bGwKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRpZy53cml0ZShudWxsLCAtMSwgMCk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICAvLyBvZmZzZXQgKyBsZW4gPiBidWYubGVuZ3RoCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkaWcud3JpdGUoYnl0ZXMsIDAsIGJ5dGVzLmxlbmd0aCArIDEpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgLy8gb2Zmc2V0IDwgMAorICAgICAgICB0cnkgeworICAgICAgICAgICAgZGlnLndyaXRlKGJ5dGVzLCAtMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIC8vIGxlbiA8IDAKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRpZy53cml0ZShieXRlcywgMCwgLTEpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuaW8uRGlnZXN0T3V0cHV0U3RyZWFtI3dyaXRlKGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF93cml0ZSRCSUlfNygpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgU3VwcG9ydF9PdXRwdXRTdHJlYW0gc29zID0gbmV3IFN1cHBvcnRfT3V0cHV0U3RyZWFtKE1ZX01FU1NBR0VfTEVOKTsKKyAgICAgICAgTWVzc2FnZURpZ2VzdCBtZCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtTmFtZVswXSk7CisgICAgICAgIERpZ2VzdE91dHB1dFN0cmVhbSBkb3MgPSBuZXcgRGlnZXN0T3V0cHV0U3RyZWFtKHNvcywgbWQpOworCisgICAgICAgIGRvcy53cml0ZShteU1lc3NhZ2UsIDAsIE1ZX01FU1NBR0VfTEVOKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gU3VwcG9ydF9PdXRwdXRTdHJlYW0gdGhyb3dzIGFuIElPRXhjZXB0aW9uIGlmIHRoZSBpbnRlcm5hbAorICAgICAgICAgICAgLy8gYnVmZmVyIGlzIGZ1bGwsIHdoaWNoIGl0IHNob3VsZCBiZSBub3cuCisgICAgICAgICAgICBkb3Mud3JpdGUobXlNZXNzYWdlLCAwLCBNWV9NRVNTQUdFX0xFTik7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPm9uKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHR1cm5zIGRpZ2VzdCBmdW5jdGlvbmFsaXR5IG9uIG9yIG9mZgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RPbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoaW50IGs9MDsgazxhbGdvcml0aG1OYW1lLmxlbmd0aDsgaysrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKE1ZX01FU1NBR0VfTEVOKTsKKyAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lW2tdKTsKKyAgICAgICAgICAgICAgICBEaWdlc3RPdXRwdXRTdHJlYW0gZG9zID0gbmV3IERpZ2VzdE91dHB1dFN0cmVhbShib3MsIG1kKTsKKworICAgICAgICAgICAgICAgIC8vIHR1cm4gZGlnZXN0IG9mZgorICAgICAgICAgICAgICAgIGRvcy5vbihmYWxzZSk7CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8TVlfTUVTU0FHRV9MRU4tMTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGRvcy53cml0ZShteU1lc3NhZ2VbaV0pOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIHR1cm4gZGlnZXN0IG9uCisgICAgICAgICAgICAgICAgZG9zLm9uKHRydWUpOworCisgICAgICAgICAgICAgICAgLy8gcmVhZCByZW1haW5pbmcgYnl0ZQorICAgICAgICAgICAgICAgIGRvcy53cml0ZShteU1lc3NhZ2VbTVlfTUVTU0FHRV9MRU4tMV0pOworCisgICAgICAgICAgICAgICAgYnl0ZVtdIGRpZ2VzdCA9IGRvcy5nZXRNZXNzYWdlRGlnZXN0KCkuZGlnZXN0KCk7CisKKyAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IGRpZ2VzdCB2YWx1ZSBoYXMgYmVlbgorICAgICAgICAgICAgICAgIC8vIHVwZGF0ZWQgYnkgdGhlIGxhc3Qgd3JpdGUoaW50KSBjYWxsCisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoQXJyYXlzLmVxdWFscyhkaWdlc3QsTURHb2xkZW5EYXRhLmdldERpZ2VzdChhbGdvcml0aG1OYW1lW2tdKSkpOworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKEFycmF5cy5lcXVhbHMoZGlnZXN0LE1ER29sZGVuRGF0YS5nZXREaWdlc3QoYWxnb3JpdGhtTmFtZVtrXSsiX05VIikpKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGFsbG93ZWQgZmFpbHVyZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm8gTWVzc2FnZURpZ2VzdCBhbGdvcml0aG1zIGF2YWlsYWJsZSAtIHRlc3Qgbm90IHBlcmZvcm1lZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnRvU3RyaW5nKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgPGNvZGU+U3RyaW5nPC9jb2RlPiByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RUb1N0cmluZygpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBmb3IgKGludCBrPTA7IGs8YWxnb3JpdGhtTmFtZS5sZW5ndGg7IGsrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbShNWV9NRVNTQUdFX0xFTik7CisgICAgICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBtZCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtTmFtZVtrXSk7CisgICAgICAgICAgICAgICAgRGlnZXN0T3V0cHV0U3RyZWFtIGRvcyA9IG5ldyBEaWdlc3RPdXRwdXRTdHJlYW0oYm9zLCBtZCk7CisKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGRvcy50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGFsbG93ZWQgZmFpbHVyZQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm8gTWVzc2FnZURpZ2VzdCBhbGdvcml0aG1zIGF2YWlsYWJsZSAtIHRlc3Qgbm90IHBlcmZvcm1lZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuRGlnZXN0T3V0cHV0U3RyZWFtI29uKGJvb2xlYW4pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9vblooKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS5zZWN1cml0eS5EaWdlc3RPdXRwdXRTdHJlYW0ub24oYm9vbGVhbikKKyAgICAgICAgRGlnZXN0T3V0cHV0U3RyZWFtIGRvcyA9IG5ldyBEaWdlc3RPdXRwdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpLCBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJTSEEiKSk7CisgICAgICAgIGRvcy5vbihmYWxzZSk7CisgICAgICAgIGJ5dGUgZGlnZXN0QXJyYXlbXSA9IHsgMjMsIDQzLCA0NCB9OworICAgICAgICBkb3Mud3JpdGUoZGlnZXN0QXJyYXksIDEsIDEpOworICAgICAgICBieXRlIGRpZ2VzdFJlc3VsdFtdID0gZG9zLmdldE1lc3NhZ2VEaWdlc3QoKS5kaWdlc3QoKTsKKyAgICAgICAgYnl0ZSBleHBlY3RlZFtdID0geyAtMzgsIDU3LCAtOTMsIC0xOCwgOTQsIDEwNywgNzUsIDEzLCA1MCwgODUsCisgICAgICAgICAgICAgICAgLTY1LCAtMTcsIC0xMDcsIDk2LCAyNCwgLTExMiwgLTgxLCAtNDAsIDcsIDkgfTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRGlnZXN0IGRpZCBub3QgcmV0dXJuIGV4cGVjdGVkIHJlc3VsdC4iLAorICAgICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMoZGlnZXN0UmVzdWx0LCBleHBlY3RlZCkpOworICAgICAgICAvLyBub3cgdHVybiBvbiBwcm9jZXNzaW5nIGFuZCByZS1ydW4KKyAgICAgICAgZG9zLm9uKHRydWUpOworICAgICAgICBkb3Mud3JpdGUoZGlnZXN0QXJyYXksIDEsIDEpOworICAgICAgICBkaWdlc3RSZXN1bHQgPSBkb3MuZ2V0TWVzc2FnZURpZ2VzdCgpLmRpZ2VzdCgpOworICAgICAgICBieXRlIGV4cGVjdGVkMVtdID0geyAtODcsIDEyMSwgLTE3LCAxNiwgLTUyLCAxMTEsIDEwNiwgNTQsIC0zMywKKyAgICAgICAgICAgICAgICAxMDcsIC0xMTgsIDUwLCA1MSwgNywgLTE4LCA1OSwgLTc4LCAtMzAsIC0zNywgLTEwMCB9OworCisgICAgICAgIGFzc2VydFRydWUoIkRpZ2VzdCBkaWQgbm90IHJldHVybiBleHBlY3RlZCByZXN1bHQuIiwKKyAgICAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKGRpZ2VzdFJlc3VsdCwgZXhwZWN0ZWQxKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5EaWdlc3RPdXRwdXRTdHJlYW0jd3JpdGUoYnl0ZVtdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyaXRlJEJJSV81KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEuc2VjdXJpdHkuRGlnZXN0T3V0cHV0U3RyZWFtLndyaXRlKGJ5dGUgW10sCisgICAgICAgIC8vIGludCwgaW50KQorICAgICAgICAgICAgRGlnZXN0T3V0cHV0U3RyZWFtIGRvcyA9IG5ldyBEaWdlc3RPdXRwdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpLCBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJTSEEiKSk7CisgICAgICAgICAgICBieXRlIGRpZ2VzdEFycmF5W10gPSB7IDIzLCA0MywgNDQgfTsKKyAgICAgICAgICAgIGRvcy53cml0ZShkaWdlc3RBcnJheSwgMSwgMSk7CisgICAgICAgICAgICBieXRlIGRpZ2VzdFJlc3VsdFtdID0gZG9zLmdldE1lc3NhZ2VEaWdlc3QoKS5kaWdlc3QoKTsKKyAgICAgICAgICAgIGJ5dGUgZXhwZWN0ZWRbXSA9IHsgLTg3LCAxMjEsIC0xNywgMTYsIC01MiwgMTExLCAxMDYsIDU0LCAtMzMsIDEwNywKKyAgICAgICAgICAgICAgICAgICAgLTExOCwgNTAsIDUxLCA3LCAtMTgsIDU5LCAtNzgsIC0zMCwgLTM3LCAtMTAwIH07CisKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkRpZ2VzdCBkaWQgbm90IHJldHVybiBleHBlY3RlZCByZXN1bHQuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmVxdWFscyhkaWdlc3RSZXN1bHQsIGV4cGVjdGVkKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5EaWdlc3RPdXRwdXRTdHJlYW0jd3JpdGUoaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JpdGVJKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEuc2VjdXJpdHkuRGlnZXN0T3V0cHV0U3RyZWFtLndyaXRlKGludCkKKyAgICAgICAgICAgIERpZ2VzdE91dHB1dFN0cmVhbSBkb3MgPSBuZXcgRGlnZXN0T3V0cHV0U3RyZWFtKAorICAgICAgICAgICAgICAgIG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSwgTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZSgiU0hBIikpOworICAgICAgICAgICAgZG9zLndyaXRlKChieXRlKSA0Myk7CisgICAgICAgICAgICBieXRlIGRpZ2VzdFJlc3VsdFtdID0gZG9zLmdldE1lc3NhZ2VEaWdlc3QoKS5kaWdlc3QoKTsKKyAgICAgICAgICAgIGJ5dGUgZXhwZWN0ZWRbXSA9IHsgLTg3LCAxMjEsIC0xNywgMTYsIC01MiwgMTExLCAxMDYsIDU0LCAtMzMsIDEwNywKKyAgICAgICAgICAgICAgICAgICAgLTExOCwgNTAsIDUxLCA3LCAtMTgsIDU5LCAtNzgsIC0zMCwgLTM3LCAtMTAwIH07CisKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkRpZ2VzdCBkaWQgbm90IHJldHVybiBleHBlY3RlZCByZXN1bHQuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmVxdWFscyhkaWdlc3RSZXN1bHQsIGV4cGVjdGVkKSk7CisgICAgfQorCisKKyAgICBwcml2YXRlIGNsYXNzIE15T3V0cHV0U3RyZWFtIGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBhcmcwKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBNeURpZ2VzdE91dHB1dFN0cmVhbSBleHRlbmRzIERpZ2VzdE91dHB1dFN0cmVhbSB7CisgICAgICAgIHB1YmxpYyBNeURpZ2VzdE91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3V0LCBNZXNzYWdlRGlnZXN0IGRpZ2VzdCkgeworICAgICAgICAgICAgc3VwZXIob3V0LCBkaWdlc3QpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE1lc3NhZ2VEaWdlc3QgbXlNZXNzYWdlRGlnZXN0KCkgeworICAgICAgICAgICAgcmV0dXJuIGRpZ2VzdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gbXlPdXRwdXRTdHJlYW0oKSB7CisgICAgICAgICAgICByZXR1cm4gb3V0OworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0dlbmVyYWxTZWN1cml0eUV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDA3MzQzMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSwxNzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb248L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQKKyAqIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIG1zZ3MgPSB7CisgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UiIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBUaHJvd2FibGUgdENhdXNlID0gbmV3IFRocm93YWJsZSgiVGhyb3dhYmxlIGZvciBleGNlcHRpb24iKTsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbigpPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246CisgICAgICogY29uc3RydWN0cyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24wMSgpIHsKKyAgICAgICAgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHRFID0gbmV3IEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbigpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHdpdGggZGV0YWlsIG1lc3NhZ2UgbXNnLgorICAgICAqIFBhcmFtZXRlciA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24wMigpIHsKKyAgICAgICAgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbihtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24gd2hlbiA8Y29kZT5tc2c8L2NvZGU+IGlzCisgICAgICogbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24wMygpIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9IG51bGw7CisgICAgICAgIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB0RSA9IG5ldyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24obXNnKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+R2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uKFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB3aGVuIDxjb2RlPmNhdXNlPC9jb2RlPgorICAgICAqIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uMDQoKSB7CisgICAgICAgIFRocm93YWJsZSBjYXVzZSA9IG51bGw7CisgICAgICAgIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB0RSA9IG5ldyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24oY2F1c2UpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5HZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24oVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+CisgICAgICogaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uMDUoKSB7CisgICAgICAgIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB0RSA9IG5ldyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24odENhdXNlKTsKKyAgICAgICAgaWYgKHRFLmdldE1lc3NhZ2UoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBzaG91bGQgY29udGFpbiAiLmNvbmNhdCh0b1MpLCAoZ2V0TQorICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgIC5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbjA2KCkgeworICAgICAgICBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24gdEUgPSBuZXcgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uKG51bGwsIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24wNygpIHsKKyAgICAgICAgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbihtc2dzW2ldLCBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdCBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24wOCgpIHsKKyAgICAgICAgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHRFID0gbmV3IEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbihudWxsLCB0Q2F1c2UpOworICAgICAgICBpZiAodEUuZ2V0TWVzc2FnZSgpICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIFN0cmluZyBnZXRNID0gdEUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIG11c3Qgc2hvdWxkICIuY29uY2F0KHRvUyksIChnZXRNCisgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKHRvUykgIT0gLTEpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiAiLmNvbmNhdCh0Q2F1c2UudG9TdHJpbmcoKSksIHRFCisgICAgICAgICAgICAgICAgLmdldENhdXNlKCksIHRDYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+R2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHdoZW4KKyAgICAgKiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90IG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24wOSgpIHsKKyAgICAgICAgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbihtc2dzW2ldLCB0Q2F1c2UpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBpZiAobXNnc1tpXS5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgbXVzdCBjb250YWluICIuY29uY2F0KG1zZ3NbaV0pLCBnZXRNCisgICAgICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZihtc2dzW2ldKSAhPSAtMSk7CisgICAgICAgICAgICAgICAgaWYgKCFnZXRNLmVxdWFscyhtc2dzW2ldKSkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgc2hvdWxkIGNvbnRhaW4gIi5jb25jYXQodG9TKSwgZ2V0TQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKHRvUykgIT0gLTEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiAiLmNvbmNhdCh0Q2F1c2UudG9TdHJpbmcoKSksCisgICAgICAgICAgICAgICAgICAgIHRFLmdldENhdXNlKCksIHRDYXVzZSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvR3VhcmRlZE9iamVjdFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9HdWFyZGVkT2JqZWN0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ5OGNhNzcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvR3VhcmRlZE9iamVjdFRlc3QuamF2YQpAQCAtMCwwICsxLDY5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4ZXkgVi4gVmFybGFtb3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuR3VhcmQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5HdWFyZGVkT2JqZWN0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5HdWFyZGVkT2JqZWN0PC9jb2RlPgorICoKKyAqLworcHVibGljIGNsYXNzIEd1YXJkZWRPYmplY3RUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqIE51bGwgZ3VhcmQgaW1wb3NlcyBubyByZXN0cmljdGlvbi4gKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9HdWFyZCgpIHsKKyAgICAgICAgT2JqZWN0IG9iaiA9IG51bGw7CisgICAgICAgIEd1YXJkZWRPYmplY3QgZ28gPSBuZXcgR3VhcmRlZE9iamVjdChvYmosIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKGdvLmdldE9iamVjdCgpKTsKKworICAgICAgICBvYmogPSAiZXd0ZSBydHczNDU2IjsKKyAgICAgICAgZ28gPSBuZXcgR3VhcmRlZE9iamVjdChvYmosIG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMob2JqLCBnby5nZXRPYmplY3QoKSk7CisgICAgfQorCisgICAgLyoqIFRlc3QgcmVhbCBndWFyZCBjYW4gYm90aCBhbGxvdyBhbmQgZGVueSBhY2Nlc3MuICovCisgICAgcHVibGljIHZvaWQgdGVzdEd1YXJkKCkgeworICAgICAgICBmaW5hbCBTdHJpbmcgbWVzc2FnZSA9ICJ0ZXN0IG1lc3NhZ2UiOworICAgICAgICBmaW5hbCBTdHJpbmdCdWZmZXIgb2JqQnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigiMjM1MzQ1IHQiKTsKKyAgICAgICAgR3VhcmRlZE9iamVjdCBnbyA9IG5ldyBHdWFyZGVkT2JqZWN0KG9iakJ1ZmZlciwgbmV3IEd1YXJkKCkgeworCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBjaGVja0d1YXJkKE9iamVjdCBvYmplY3QpIHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgaWYgKG9iamVjdCA9PSBvYmpCdWZmZXIgJiYgb2JqQnVmZmVyLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKG1lc3NhZ2UpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIGFzc2VydEVxdWFscyhvYmpCdWZmZXIsIGdvLmdldE9iamVjdCgpKTsKKworICAgICAgICBvYmpCdWZmZXIuc2V0TGVuZ3RoKDApOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZ28uZ2V0T2JqZWN0KCk7CisgICAgICAgICAgICBmYWlsKCJTZWN1cml0eUV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBvaykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsIG9rLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvSWRlbnRpdHkyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0lkZW50aXR5MlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNjI1ZGVlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0lkZW50aXR5MlRlc3QuamF2YQpAQCAtMCwwICsxLDM5NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5BbmRyb2lkT25seTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LklkZW50aXR5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuSWRlbnRpdHlTY29wZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleU1hbmFnZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eS5JZGVudGl0eVNjb3BlMlRlc3QuSWRlbnRpdHlTY29wZVN1YmNsYXNzOworCitAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorcHVibGljIGNsYXNzIElkZW50aXR5MlRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgUHVibGljS2V5IFBVQl9LRVk7CisgICAgcHJpdmF0ZSBzdGF0aWMgUHVibGljS2V5IGdldFB1YktleSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpZiAoUFVCX0tFWSA9PSBudWxsKSB7CisgICAgICAgICAgICBQVUJfS0VZID0gS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZSgiRFNBIikuZ2VuS2V5UGFpcigpLmdldFB1YmxpYygpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBQVUJfS0VZOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQ2VydGlmaWNhdGVJbXBsIGltcGxlbWVudHMgamF2YS5zZWN1cml0eS5DZXJ0aWZpY2F0ZSB7CisKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIGNlcnQ7CisKKyAgICAgICAgcHVibGljIENlcnRpZmljYXRlSW1wbChYNTA5Q2VydGlmaWNhdGUgY2VydCkgeworICAgICAgICAgICAgdGhpcy5jZXJ0ID0gY2VydDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0R3VhcmFudG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIGNlcnQuZ2V0SXNzdWVyRE4oKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGVuY29kZShPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBkZWNvZGUoSW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICByZXR1cm4gIiI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGJvb2xlYW4gYikgeworICAgICAgICAgICAgcmV0dXJuICIiOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRGb3JtYXQoKSB7CisgICAgICAgICAgICByZXR1cm4gY2VydC5nZXRUeXBlKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUHJpbmNpcGFsIGdldFByaW5jaXBhbCgpIHsKKyAgICAgICAgICAgIHJldHVybiBjZXJ0LmdldFN1YmplY3RETigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFB1YmxpY0tleSBnZXRQdWJsaWNLZXkoKSB7CisgICAgICAgICAgICByZXR1cm4gY2VydC5nZXRQdWJsaWNLZXkoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIFN0cmluZyBjZXJ0aWZpY2F0ZSA9ICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICsgIk1JSUNaVENDQWRJQ0JRTDNBQUMyTUEwR0NTcUdTSWIzRFFFQkFnVUFNRjh4Q3pBSkJnTlZCQVlUQWxWVE1TQXdcbiIKKyAgICAgICAgICAgICsgIkhnWURWUVFLRXhkU1UwRWdSR0YwWVNCVFpXTjFjbWwwZVN3Z1NXNWpMakV1TUN3R0ExVUVDeE1sVTJWamRYSmxcbiIKKyAgICAgICAgICAgICsgIklGTmxjblpsY2lCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVEFlRncwNU56QXlNakF3TURBd01EQmFcbiIKKyAgICAgICAgICAgICsgIkZ3MDVPREF5TWpBeU16VTVOVGxhTUlHV01Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZcbiIKKyAgICAgICAgICAgICsgImNtNXBZVEVTTUJBR0ExVUVCeE1KVUdGc2J5QkJiSFJ2TVI4d0hRWURWUVFLRXhaVGRXNGdUV2xqY205emVYTjBcbiIKKyAgICAgICAgICAgICsgIlpXMXpMQ0JKYm1NdU1TRXdId1lEVlFRTEV4aFVaWE4wSUdGdVpDQkZkbUZzZFdGMGFXOXVJRTl1YkhreEdqQVlcbiIKKyAgICAgICAgICAgICsgIkJnTlZCQU1URVdGeVoyOXVMbVZ1Wnk1emRXNHVZMjl0TUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JcbiIKKyAgICAgICAgICAgICsgImlRS0JnUUNvZm1kWStQaVVXTjAxRk96RWV3ZitHYUcrbEZmMTMyVXB6QVRtWUprQTRBRUEvanVXN2pTaStMSmtcbiIKKyAgICAgICAgICAgICsgIndKS2k1R080Unlab3lpbUFMLzV5SVdEVjZsMUtsdnh5S3NscjBSRWhNQmFELzNaM0VzTFRURWY1Z1ZyUVM2c1RcbiIKKyAgICAgICAgICAgICsgIldNb1NaQXl6QjM5a0Zmc0I2b1VYTnRWOCtVS0t4U3hLYnh2aFFuMjY3UGVDejVWWDJRSURBUUFCTUEwR0NTcUdcbiIKKyAgICAgICAgICAgICsgIlNJYjNEUUVCQWdVQUEzNEFYbDNhdDZsdWlWLzdJOU1ONUNYWW9QSllJOEJjZGMxaEJhZ0p2VE1jbWxxTDJ1T1pcbiIKKyAgICAgICAgICAgICsgIkg5VDVoTk1FTDlUazZhSTd5WlBYY3cveEkySzZwT1IvRnJNcDBVd0ptZHhYN2xqVjZadFVaZjdwWTQ5MlVxd0NcbiIKKyAgICAgICAgICAgICsgIjE3NzdYUTlVRVp5cktKdkY1bnRsZWVPMGF5QnFMR1ZLQ1d6V1pYOVlzWENwdjQ3Rk5MWmJ1cEU9XG4iCisgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iOworCisgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gY2VydEFycmF5ID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNlcnRpZmljYXRlLmdldEJ5dGVzKCkpOworCisgICAgU3RyaW5nIGNlcnRpZmljYXRlMiA9ICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICsgIk1JSUNaekNDQWRDZ0F3SUJBZ0lCR3pBTkJna3Foa2lHOXcwQkFRVUZBREJoTVFzd0NRWURWUVFHRXdKVlV6RVlcbiIKKyAgICAgICAgICAgICsgIk1CWUdBMVVFQ2hNUFZTNVRMaUJIYjNabGNtNXRaVzUwTVF3d0NnWURWUVFMRXdORWIwUXhEREFLQmdOVkJBc1RcbiIKKyAgICAgICAgICAgICsgIkExQkxTVEVjTUJvR0ExVUVBeE1UUkc5RUlGQkxTU0JOWldRZ1VtOXZkQ0JEUVRBZUZ3MDVPREE0TURNeU1qQXlcbiIKKyAgICAgICAgICAgICsgIk1qbGFGdzB3T0RBNE1EUXlNakF5TWpsYU1HRXhDekFKQmdOVkJBWVRBbFZUTVJnd0ZnWURWUVFLRXc5VkxsTXVcbiIKKyAgICAgICAgICAgICsgIklFZHZkbVZ5Ym0xbGJuUXhEREFLQmdOVkJBc1RBMFJ2UkRFTU1Bb0dBMVVFQ3hNRFVFdEpNUnd3R2dZRFZRUURcbiIKKyAgICAgICAgICAgICsgIkV4TkViMFFnVUV0SklFMWxaQ0JTYjI5MElFTkJNSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdOQURDQmlRS0JcbiIKKyAgICAgICAgICAgICsgImdRRGJyTS9KOUZySlNYK3p4RlVic0k5Vnc1UWJndVZCSWE5NXJ3Vy8wTTgrc00wcjVnZCtEWTZpdWJtNnduWGtcbiIKKyAgICAgICAgICAgICsgIkNTdmJmUWxGRURTS3I0V1llZUdwK2Q5V2xEblFkdERGTGRBNDV0Q2k1U0hqblcraEdBbVpubGQwcno2d1Fla0ZcbiIKKyAgICAgICAgICAgICsgIjV4UWFhNUE2d2poTWxMT2piaDI3enlzY3Jvck1KMU81RkJPV25FSGNSdjZ4cVFJREFRQUJveTh3TFRBZEJnTlZcbiIKKyAgICAgICAgICAgICsgIkhRNEVGZ1FVVnJtWVI2bTk3MDFjSFEzcjVrWHlHN3pzQ04wd0RBWURWUjBUQkFVd0F3RUIvekFOQmdrcWhraUdcbiIKKyAgICAgICAgICAgICsgIjl3MEJBUVVGQUFPQmdRRFZYMVkwWXFDN3Zla2VaalZ4dHl1QzhNbnhicno2RDEwOUFYMDdMRUlSek5ZendaMHdcbiIKKyAgICAgICAgICAgICsgIk1USW1TcDlzRXpXVyszRnVlQklVN0F4R3lzMk83WDBxbU4zemdzelBmU2lvY0J1UXVYSVlRY3RKaEtqRjVLVmNcbiIKKyAgICAgICAgICAgICsgIlZHUVJZWWx0K215aGwydnk2eVB6RVZDamlLd01FYjFTcHUwaXJDZitsRlcyaHNkanZtU1FNdFp2T3c9PVxuIgorICAgICAgICAgICAgKyAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLVxuIjsKKworICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGNlcnRBcnJheTIgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oY2VydGlmaWNhdGUyLmdldEJ5dGVzKCkpOworCisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIElkZW50aXR5U3ViY2xhc3MgZXh0ZW5kcyBJZGVudGl0eSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgICAgIHB1YmxpYyBJZGVudGl0eVN1YmNsYXNzKCkgeworICAgICAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBJZGVudGl0eVN1YmNsYXNzKFN0cmluZyBuYW1lKSB7CisgICAgICAgICAgICBzdXBlcihuYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBJZGVudGl0eVN1YmNsYXNzKFN0cmluZyBuYW1lLCBJZGVudGl0eVNjb3BlIHNjb3BlKQorICAgICAgICAgICAgICAgIHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN1cGVyKG5hbWUsIHNjb3BlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuSWRlbnRpdHkjSWRlbnRpdHkoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB7CisgICAgICAgIG5ldyBJZGVudGl0eVN1YmNsYXNzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5JZGVudGl0eSNJZGVudGl0eShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nW10gc3RyID0geyJ0ZXN0IiwgIiIsIG51bGx9OworICAgICAgICBJZGVudGl0eVN1YmNsYXNzIGlzOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpcyA9IG5ldyBJZGVudGl0eVN1YmNsYXNzKHN0cltpXSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChpcyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShpcyBpbnN0YW5jZW9mIElkZW50aXR5KTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gZm9yIElkZW50aXR5KGphdmEubGFuZy5TdHJpbmcpIHdpdGggcGFyYW1ldGVyICIKKyAgICAgICAgICAgICAgICAgICAgICsgc3RyW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuSWRlbnRpdHkjSWRlbnRpdHkoamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS5zZWN1cml0eS5JZGVudGl0eVNjb3BlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZ0xqYXZhX3NlY3VyaXR5X0lkZW50aXR5U2NvcGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIG5hbWVOdWxsID0gbnVsbDsKKyAgICAgICAgU3RyaW5nW10gc3RyID0geyJ0ZXN0IiwgIiIsICIhQCMkJV4mKigpIiwgImlkZW50aXR5IG5hbWUifTsKKyAgICAgICAgSWRlbnRpdHlTY29wZVN1YmNsYXNzIGlzcyA9IG5ldyBJZGVudGl0eVNjb3BlU3ViY2xhc3MoIm5hbWUiKTsKKyAgICAgICAgSWRlbnRpdHlTdWJjbGFzcyBpczsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpcyA9IG5ldyBJZGVudGl0eVN1YmNsYXNzKHN0cltpXSwgbmV3IElkZW50aXR5U2NvcGVTdWJjbGFzcygpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGlzKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGlzIGluc3RhbmNlb2YgSWRlbnRpdHkpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oZSk7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gZm9yIHBhcmFtZXRlciAiICsgc3RyW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcyA9IG5ldyBJZGVudGl0eVN1YmNsYXNzKG5hbWVOdWxsLCBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCkpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkluY29ycmVjdCBleGNlcHRpb24gIiArIGUgKyAiIHdhcyB0aHJvd24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcyA9IG5ldyBJZGVudGl0eVN1YmNsYXNzKCJ0ZXN0IiwgaXNzKTsKKyAgICAgICAgICAgIGlzID0gbmV3IElkZW50aXR5U3ViY2xhc3MoInRlc3QiLCBpc3MpOworICAgICAgICAgICAgZmFpbCgiS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LklkZW50aXR5I2dldFNjb3BlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFNjb3BlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElkZW50aXR5U2NvcGUgc2NvcGUgPSBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCk7CisgICAgICAgIElkZW50aXR5U3ViY2xhc3Mgc3ViID0gbmV3IElkZW50aXR5U3ViY2xhc3MoInRlc3QiLCBzY29wZSk7CisgICAgICAgIElkZW50aXR5U2NvcGUgcmV0dXJuZWRTY29wZSA9IHN1Yi5nZXRTY29wZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIFNjb3BlIHJldHVybmVkIiwgc2NvcGUsIHJldHVybmVkU2NvcGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuSWRlbnRpdHkjZ2V0UHVibGljS2V5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFB1YmxpY0tleSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBJZGVudGl0eVN1YmNsYXNzIHN1YiA9IG5ldyBJZGVudGl0eVN1YmNsYXNzKCJ0ZXN0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCkpOworICAgICAgICBzdWIuc2V0UHVibGljS2V5KGdldFB1YktleSgpKTsKKyAgICAgICAgUHVibGljS2V5IHJldHVybmVkUHViS2V5ID0gc3ViLmdldFB1YmxpY0tleSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIFB1YmxpY0tleSByZXR1cm5lZCIsIGdldFB1YktleSgpLCByZXR1cm5lZFB1YktleSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5JZGVudGl0eSNnZXROYW1lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE5hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSAidGVzdCI7CisgICAgICAgIElkZW50aXR5U3ViY2xhc3Mgc3ViID0gbmV3IElkZW50aXR5U3ViY2xhc3MobmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIE5hbWUgcmV0dXJuZWQiLCBuYW1lLCBzdWIuZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LklkZW50aXR5I2dldEluZm8oKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5mbygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgaW5mbyA9ICJUaGlzIGlzIHRoZSBnZW5lcmFsIGluZm9ybWF0aW9uLiI7CisgICAgICAgIElkZW50aXR5U3ViY2xhc3Mgc3ViID0gbmV3IElkZW50aXR5U3ViY2xhc3MoInRlc3QiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJZGVudGl0eVNjb3BlU3ViY2xhc3MoKSk7CisgICAgICAgIHN1Yi5zZXRJbmZvKGluZm8pOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIEluZm8gcmV0dXJuZWQiLCBpbmZvLCBzdWIuZ2V0SW5mbygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LklkZW50aXR5I2NlcnRpZmljYXRlcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jZXJ0aWZpY2F0ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSWRlbnRpdHlTdWJjbGFzcyBzdWIgPSBuZXcgSWRlbnRpdHlTdWJjbGFzcygidGVzdCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IElkZW50aXR5U2NvcGVTdWJjbGFzcygpKTsKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydFtdID0gbmV3IFg1MDlDZXJ0aWZpY2F0ZVsxXTsKKyAgICAgICAgY2VydFswXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5KTsKKyAgICAgICAgc3ViLnNldFB1YmxpY0tleShjZXJ0WzBdLmdldFB1YmxpY0tleSgpKTsKKyAgICAgICAgQ2VydGlmaWNhdGVJbXBsIGNlcnRJbXBsID0gbmV3IENlcnRpZmljYXRlSW1wbChjZXJ0WzBdKTsKKyAgICAgICAgc3ViLmFkZENlcnRpZmljYXRlKGNlcnRJbXBsKTsKKyAgICAgICAgamF2YS5zZWN1cml0eS5DZXJ0aWZpY2F0ZVtdIGNlcnRzID0gc3ViLmNlcnRpZmljYXRlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkNlcnRpZmljYXRlIG5vdCBjb250YWluZWQgaW4gdGhlIGlkZW50aXR5IiwKKyAgICAgICAgICAgICAgICAgICAgIGNlcnRzWzBdLCBjZXJ0SW1wbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5JZGVudGl0eSNyZW1vdmVDZXJ0aWZpY2F0ZShqYXZhLnNlY3VyaXR5LkNlcnRpZmljYXRlKQorICAgICAqLworICAgIEBBbmRyb2lkT25seSgiU3BlYyBzYXlzOiBSZW1vdmluZyB1bmtub3duIGNlcnRpZmljYXRlcyB0aHJvdyBhbiBleGNlcHRpb24uICIKKyAgICAgICAgICAgICsgIlRoZSBSSSBpZ25vcmVzIHVua25vd24gY2VydGlmaWNhdGVzLiIpCisgICAgcHVibGljIHZvaWQgdGVzdF9yZW1vdmVDZXJ0aWZpY2F0ZUxqYXZhX3NlY3VyaXR5X0NlcnRpZmljYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElkZW50aXR5U3ViY2xhc3Mgc3ViID0gbmV3IElkZW50aXR5U3ViY2xhc3MoInRlc3QiLAorICAgICAgICAgICAgICAgIG5ldyBJZGVudGl0eVNjb3BlU3ViY2xhc3MoKSk7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIGNlcnRbXSA9IG5ldyBYNTA5Q2VydGlmaWNhdGVbMV07CisgICAgICAgIGNlcnRbMF0gPSAoWDUwOUNlcnRpZmljYXRlKSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKGNlcnRBcnJheSk7CisgICAgICAgIHN1Yi5zZXRQdWJsaWNLZXkoY2VydFswXS5nZXRQdWJsaWNLZXkoKSk7CisgICAgICAgIENlcnRpZmljYXRlSW1wbCBjZXJ0SW1wbCA9IG5ldyBDZXJ0aWZpY2F0ZUltcGwoY2VydFswXSk7CisgICAgICAgIHN1Yi5hZGRDZXJ0aWZpY2F0ZShjZXJ0SW1wbCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN1Yi5yZW1vdmVDZXJ0aWZpY2F0ZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBDZXJ0aWZpY2F0ZSBzaG91bGQgbm90IGhhdmUgYmVlbiByZW1vdmVkLiIsCisgICAgICAgICAgICAgICAgMSwgc3ViLmNlcnRpZmljYXRlcygpLmxlbmd0aCk7CisKKyAgICAgICAgc3ViLnJlbW92ZUNlcnRpZmljYXRlKGNlcnRJbXBsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDM6IENlcnRpZmljYXRlIGhhcyBub3QgYmVlbiByZW1vdmVkLiIsCisgICAgICAgICAgICAgICAgMCwgc3ViLmNlcnRpZmljYXRlcygpLmxlbmd0aCk7CisKKyAgICAgICAgLy8gUmVtb3ZpbmcgdGhlIHNhbWUgY2VydGlmaWNhdGUgYSBzZWNvbmQgdGltZSBzaG91bGQgZmFpbC4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN1Yi5yZW1vdmVDZXJ0aWZpY2F0ZShjZXJ0SW1wbCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDQ6IEtleU1hbmFnZW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEtleU1hbmFnZW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5JZGVudGl0eSNlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VxdWFsc0xqYXZhX2xhbmdfT2JqZWN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElkZW50aXR5U3ViY2xhc3Mgc3ViID0gbmV3IElkZW50aXR5U3ViY2xhc3MoInRlc3QiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJZGVudGl0eVNjb3BlU3ViY2xhc3MoKSk7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIGNlcnRbXSA9IG5ldyBYNTA5Q2VydGlmaWNhdGVbMV07CisgICAgICAgIGNlcnRbMF0gPSAoWDUwOUNlcnRpZmljYXRlKSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKGNlcnRBcnJheSk7CisgICAgICAgIHN1Yi5zZXRQdWJsaWNLZXkoY2VydFswXS5nZXRQdWJsaWNLZXkoKSk7CisgICAgICAgIENlcnRpZmljYXRlSW1wbCBjZXJ0SW1wbCA9IG5ldyBDZXJ0aWZpY2F0ZUltcGwoY2VydFswXSk7CisgICAgICAgIHN1Yi5hZGRDZXJ0aWZpY2F0ZShjZXJ0SW1wbCk7CisgICAgICAgIElkZW50aXR5U3ViY2xhc3Mgc3ViMiA9IG5ldyBJZGVudGl0eVN1YmNsYXNzKCJ0ZXN0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IElkZW50aXR5U2NvcGVTdWJjbGFzcygpKTsKKyAgICAgICAgSWRlbnRpdHlTdWJjbGFzcyBzdWIzID0gbmV3IElkZW50aXR5U3ViY2xhc3MoImlkZW50aXR5IG5hbWUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRoZSB0d28gSWRlbnRpdHkgb2JqZWN0cyBhcmUgbm90IGVxdWFsIiwgc3ViMiwgc3ViKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHN1Yiwgc3ViMik7CisgICAgICAgIGFzc2VydEZhbHNlKHN1Yi5lcXVhbHMoc3ViMykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuSWRlbnRpdHkjaWRlbnRpdHlFcXVhbHMoamF2YS5zZWN1cml0eS5JZGVudGl0eSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lkZW50aXR5RXF1YWxzTGphdmFfc2VjdXJpdHlfSWRlbnRpdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSWRlbnRpdHlTdWJjbGFzcyBzdWIgPSBuZXcgSWRlbnRpdHlTdWJjbGFzcygidGVzdCIsIG51bGwpOworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0W10gPSBuZXcgWDUwOUNlcnRpZmljYXRlWzFdOworICAgICAgICBjZXJ0WzBdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkpOworICAgICAgICBzdWIuc2V0UHVibGljS2V5KGNlcnRbMF0uZ2V0UHVibGljS2V5KCkpOworICAgICAgICBDZXJ0aWZpY2F0ZUltcGwgY2VydEltcGwgPSBuZXcgQ2VydGlmaWNhdGVJbXBsKGNlcnRbMF0pOworICAgICAgICBzdWIuYWRkQ2VydGlmaWNhdGUoY2VydEltcGwpOworICAgICAgICBJZGVudGl0eVN1YmNsYXNzIHN1YjIgPSBuZXcgSWRlbnRpdHlTdWJjbGFzcygidGVzdCIsIG51bGwpOworICAgICAgICBzdWIyLnNldFB1YmxpY0tleShjZXJ0WzBdLmdldFB1YmxpY0tleSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0aGUgdHdvIElkZW50aXR5IG9iamVjdHMgYXJlIG5vdCBpZGVudGl0eS1lcXVhbCIsCisgICAgICAgICAgICAgICAgICAgICBzdWIyLCBzdWIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuSWRlbnRpdHkjdG9TdHJpbmcoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSWRlbnRpdHlTdWJjbGFzcyBzdWIgPSBuZXcgSWRlbnRpdHlTdWJjbGFzcygidGVzdCIsIG51bGwpOworICAgICAgICBhc3NlcnROb3ROdWxsKHN1Yi50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIFN0cmluZyByZXR1cm5lZCBpcyBub3QgdmFsaWQiLCBzdWIudG9TdHJpbmcoKS5sZW5ndGgoKSA+IDApOworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTE1NjYKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXcgSWRlbnRpdHlTdWJjbGFzcygpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuSWRlbnRpdHkjdG9TdHJpbmcoYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nWigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBJZGVudGl0eVN1YmNsYXNzIHN1YiA9IG5ldyBJZGVudGl0eVN1YmNsYXNzKCJ0ZXN0IiwgbnVsbCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoc3ViLnRvU3RyaW5nKHRydWUpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIFN0cmluZyByZXR1cm5lZCBpcyBub3QgdmFsaWQiLCBzdWIudG9TdHJpbmcodHJ1ZSkubGVuZ3RoKCkgPiAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LklkZW50aXR5I2hhc2hDb2RlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc2hDb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElkZW50aXR5U3ViY2xhc3Mgc3ViID0gbmV3IElkZW50aXR5U3ViY2xhc3MoInRlc3QiLCBudWxsKTsKKyAgICAgICAgSWRlbnRpdHlTdWJjbGFzcyBzdWIyID0gbmV3IElkZW50aXR5U3ViY2xhc3MoInRlc3QiLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgMiBoYXNoIGNvZGVzIGFyZSBub3QgZXF1YWwiLCBzdWIuaGFzaENvZGUoKSwgc3ViMi5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LklkZW50aXR5I3NldEluZm8oU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRJbmZvKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIGluZm8gPSB7IlRoaXMgaXMgdGhlIGdlbmVyYWwgaW5mb3JtYXRpb24uIiwgInRlc3QiLCAiIiwgbnVsbH07CisgICAgICAgIElkZW50aXR5U3ViY2xhc3Mgc3ViID0gbmV3IElkZW50aXR5U3ViY2xhc3MoInRlc3QiLCBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCkpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5mby5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdWIuc2V0SW5mbyhpbmZvW2ldKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIEluZm8gcmV0dXJuZWQiLCBpbmZvW2ldLCBzdWIuZ2V0SW5mbygpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gZm9yIHBhcmFtZXRlciAiICsgaW5mb1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuSWRlbnRpdHkjc2V0UHVibGljS2V5KFB1YmxpY0tleSBrZXkpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNldFB1YmxpY0tleSgpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIElkZW50aXR5U3ViY2xhc3Mgc3ViID0gbmV3IElkZW50aXR5U3ViY2xhc3MoInRlc3QiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJZGVudGl0eVNjb3BlU3ViY2xhc3MoKSk7CisgICAgICAgIHN1Yi5zZXRQdWJsaWNLZXkoZ2V0UHViS2V5KCkpOworICAgICAgICBQdWJsaWNLZXkgcmV0dXJuZWRQdWJLZXkgPSBzdWIuZ2V0UHVibGljS2V5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgUHVibGljS2V5IHJldHVybmVkIiwgZ2V0UHViS2V5KCksIHJldHVybmVkUHViS2V5KTsKKworICAgICAgICBzdWIuc2V0UHVibGljS2V5KG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIFB1YmxpY0tleSByZXR1cm5lZCIsIG51bGwsIHN1Yi5nZXRQdWJsaWNLZXkoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvSWRlbnRpdHlTY29wZTJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvSWRlbnRpdHlTY29wZTJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjY4ZTAzMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9JZGVudGl0eVNjb3BlMlRlc3QuamF2YQpAQCAtMCwwICsxLDMyNiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LklkZW50aXR5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuSWRlbnRpdHlTY29wZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleU1hbmFnZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHkuSWRlbnRpdHkyVGVzdC5JZGVudGl0eVN1YmNsYXNzOworCitAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorcHVibGljIGNsYXNzIElkZW50aXR5U2NvcGUyVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBQdWJsaWNLZXkgUFVCX0tFWTsKKyAgICBwcml2YXRlIHN0YXRpYyBQdWJsaWNLZXkgZ2V0UHViS2V5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChQVUJfS0VZID09IG51bGwpIHsKKyAgICAgICAgICAgIFBVQl9LRVkgPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKCJEU0EiKS5nZW5LZXlQYWlyKCkuZ2V0UHVibGljKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIFBVQl9LRVk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBJZGVudGl0eVNjb3BlU3ViY2xhc3MgZXh0ZW5kcyBJZGVudGl0eVNjb3BlIHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisgICAgICAgIEhhc2h0YWJsZTxJZGVudGl0eSwgSWRlbnRpdHk+IGlkZW50aXRpZXM7CisKKyAgICAgICAgcHVibGljIElkZW50aXR5U2NvcGVTdWJjbGFzcyhTdHJpbmcgbmFtZSwgUHVibGljS2V5IHBrKSB7CisgICAgICAgICAgICBzdXBlcihuYW1lKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2V0UHVibGljS2V5KHBrKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEtleU1hbmFnZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWRlbnRpdGllcyA9IG5ldyBIYXNodGFibGU8SWRlbnRpdHksIElkZW50aXR5PigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIElkZW50aXR5U2NvcGVTdWJjbGFzcygpIHsKKyAgICAgICAgICAgIHN1cGVyKCk7CisgICAgICAgICAgICBpZGVudGl0aWVzID0gbmV3IEhhc2h0YWJsZTxJZGVudGl0eSwgSWRlbnRpdHk+KCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSWRlbnRpdHlTY29wZVN1YmNsYXNzKFN0cmluZyBuYW1lKSB7CisgICAgICAgICAgICBzdXBlcihuYW1lKTsKKyAgICAgICAgICAgIGlkZW50aXRpZXMgPSBuZXcgSGFzaHRhYmxlPElkZW50aXR5LCBJZGVudGl0eT4oKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBJZGVudGl0eVNjb3BlU3ViY2xhc3MoU3RyaW5nIG5hbWUsIElkZW50aXR5U2NvcGUgc2NvcGUpCisgICAgICAgICAgICAgICAgdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIobmFtZSwgc2NvcGUpOworICAgICAgICAgICAgaWRlbnRpdGllcyA9IG5ldyBIYXNodGFibGU8SWRlbnRpdHksIElkZW50aXR5PigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgcmV0dXJuIGlkZW50aXRpZXMuc2l6ZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIElkZW50aXR5IGdldElkZW50aXR5KFN0cmluZyBuYW1lKSB7CisgICAgICAgICAgICBFbnVtZXJhdGlvbjxJZGVudGl0eT4gZW4gPSBpZGVudGl0aWVzKCk7CisgICAgICAgICAgICB3aGlsZSAoZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgICAgICBJZGVudGl0eSBjdXJyZW50ID0gKElkZW50aXR5KSBlbi5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgICAgIGlmIChjdXJyZW50LmdldE5hbWUoKS5lcXVhbHMobmFtZSkpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50OworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSWRlbnRpdHkgZ2V0SWRlbnRpdHkoUHVibGljS2V5IHBrKSB7CisgICAgICAgICAgICBFbnVtZXJhdGlvbjxJZGVudGl0eT4gZW4gPSBpZGVudGl0aWVzKCk7CisgICAgICAgICAgICB3aGlsZSAoZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgICAgICBJZGVudGl0eSBjdXJyZW50ID0gKElkZW50aXR5KSBlbi5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgICAgIGlmIChjdXJyZW50LmdldFB1YmxpY0tleSgpID09IHBrKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEVudW1lcmF0aW9uPElkZW50aXR5PiBpZGVudGl0aWVzKCkgeworICAgICAgICAgICAgcmV0dXJuIGlkZW50aXRpZXMuZWxlbWVudHMoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGFkZElkZW50aXR5KElkZW50aXR5IGlkKSB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoaWRlbnRpdGllcy5jb250YWluc0tleShpZCkpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEtleU1hbmFnZW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAiVGhpcyBJZGVudGl0eSBpcyBhbHJlYWR5IGNvbnRhaW5lZCBpbiB0aGUgc2NvcGUiKTsKKyAgICAgICAgICAgIGlmIChnZXRJZGVudGl0eShpZC5nZXRQdWJsaWNLZXkoKSkgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICJUaGlzIElkZW50aXR5J3MgcHVibGljIGtleSBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgc2NvcGUiKTsKKyAgICAgICAgICAgIGlkZW50aXRpZXMucHV0KGlkLCBpZCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmVJZGVudGl0eShJZGVudGl0eSBpZCkgdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKCFpZGVudGl0aWVzLmNvbnRhaW5zS2V5KGlkKSkKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICJUaGlzIElkZW50aXR5IGlzIG5vdCBjb250YWluZWQgaW4gdGhlIHNjb3BlIik7CisgICAgICAgICAgICBpZGVudGl0aWVzLnJlbW92ZShpZCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LklkZW50aXR5U2NvcGUjSWRlbnRpdHlTY29wZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgbmV3IElkZW50aXR5U2NvcGVTdWJjbGFzcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuSWRlbnRpdHlTY29wZSNJZGVudGl0eVNjb3BlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICBTdHJpbmdbXSBzdHIgPSB7InRlc3QiLCAiIiwgbnVsbH07CisgICAgICAgIElkZW50aXR5U2NvcGVTdWJjbGFzcyBpc3M7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaXNzID0gbmV3IElkZW50aXR5U2NvcGVTdWJjbGFzcyhzdHJbaV0pOworICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoaXNzKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGlzcyBpbnN0YW5jZW9mIElkZW50aXR5U2NvcGUpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiBmb3IgcGFyYW1ldGVyICIgKyBzdHJbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5JZGVudGl0eVNjb3BlI0lkZW50aXR5U2NvcGUoamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS5zZWN1cml0eS5JZGVudGl0eVNjb3BlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZ0xqYXZhX3NlY3VyaXR5X0lkZW50aXR5U2NvcGUoKSB7CisgICAgICAgIFN0cmluZyBuYW1lTnVsbCA9IG51bGw7CisgICAgICAgIFN0cmluZ1tdIHN0ciA9IHsidGVzdCIsICIiLCAiIUAjJCVeJiooKSIsICJpZGVudGl0eSBuYW1lIn07CisgICAgICAgIElkZW50aXR5U2NvcGUgaXM7CisgICAgICAgIElkZW50aXR5U2NvcGUgaXNzID0gbmV3IElkZW50aXR5U2NvcGVTdWJjbGFzcygidGVzdCBzY29wZSIpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlzID0gbmV3IElkZW50aXR5U2NvcGVTdWJjbGFzcyhzdHJbaV0sIG5ldyBJZGVudGl0eVNjb3BlU3ViY2xhc3MoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChpcyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShpcyBpbnN0YW5jZW9mIElkZW50aXR5U2NvcGUpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiBmb3IgcGFyYW1ldGVyICIgKyBzdHJbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlzID0gbmV3IElkZW50aXR5U2NvcGVTdWJjbGFzcyhuYW1lTnVsbCwgbmV3IElkZW50aXR5U2NvcGVTdWJjbGFzcygpKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJbmNvcnJlY3QgZXhjZXB0aW9uICIgKyBlICsgIiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMgPSBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCJ0ZXN0IiwgaXNzKTsKKyAgICAgICAgICAgIGlzID0gbmV3IElkZW50aXR5U2NvcGVTdWJjbGFzcygidGVzdCIsIGlzcyk7CisgICAgICAgICAgICBmYWlsKCJLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEtleU1hbmFnZW1lbnRFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJbmNvcnJlY3QgZXhjZXB0aW9uICIgKyBlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5JZGVudGl0eVNjb3BlI2FkZElkZW50aXR5KGphdmEuc2VjdXJpdHkuSWRlbnRpdHkpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRJZGVudGl0eUxqYXZhX3NlY3VyaXR5X0lkZW50aXR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElkZW50aXR5U2NvcGVTdWJjbGFzcyBzdWIgPSBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCJ0ZXN0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IElkZW50aXR5U2NvcGVTdWJjbGFzcygpKTsKKyAgICAgICAgSWRlbnRpdHkgaWQgPSBuZXcgSWRlbnRpdHlTdWJjbGFzcygiaWQxIik7CisgICAgICAgIGlkLnNldFB1YmxpY0tleShnZXRQdWJLZXkoKSk7CisgICAgICAgIHN1Yi5hZGRJZGVudGl0eShpZCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBJZGVudGl0eSBpZDIgPSBuZXcgSWRlbnRpdHlTdWJjbGFzcygiaWQyIik7CisgICAgICAgICAgICBpZDIuc2V0UHVibGljS2V5KGdldFB1YktleSgpKTsKKyAgICAgICAgICAgIHN1Yi5hZGRJZGVudGl0eShpZDIpOworICAgICAgICAgICAgZmFpbCgiS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiBzaG91bGQgaGF2ZSBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LklkZW50aXR5U2NvcGUjcmVtb3ZlSWRlbnRpdHkoamF2YS5zZWN1cml0eS5JZGVudGl0eSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlbW92ZUlkZW50aXR5TGphdmFfc2VjdXJpdHlfSWRlbnRpdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSWRlbnRpdHlTY29wZVN1YmNsYXNzIHN1YiA9IG5ldyBJZGVudGl0eVNjb3BlU3ViY2xhc3MoInRlc3QiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCkpOworICAgICAgICBJZGVudGl0eSBpZCA9IG5ldyBJZGVudGl0eVN1YmNsYXNzKCk7CisgICAgICAgIGlkLnNldFB1YmxpY0tleShnZXRQdWJLZXkoKSk7CisgICAgICAgIHN1Yi5hZGRJZGVudGl0eShpZCk7CisgICAgICAgIHN1Yi5yZW1vdmVJZGVudGl0eShpZCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdWIucmVtb3ZlSWRlbnRpdHkoaWQpOworICAgICAgICAgICAgZmFpbCgiS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiBzaG91bGQgaGF2ZSBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LklkZW50aXR5U2NvcGUjaWRlbnRpdGllcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pZGVudGl0aWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElkZW50aXR5U2NvcGVTdWJjbGFzcyBzdWIgPSBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCJ0ZXN0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IElkZW50aXR5U2NvcGVTdWJjbGFzcygpKTsKKyAgICAgICAgSWRlbnRpdHkgaWQgPSBuZXcgSWRlbnRpdHlTdWJjbGFzcygpOworICAgICAgICBpZC5zZXRQdWJsaWNLZXkoZ2V0UHViS2V5KCkpOworICAgICAgICBzdWIuYWRkSWRlbnRpdHkoaWQpOworICAgICAgICBFbnVtZXJhdGlvbjxJZGVudGl0eT4gZW4gPSBzdWIuaWRlbnRpdGllcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIG9iamVjdCBjb250YWluZWQgaW4gaWRlbnRpdGllcyIsIGVuLm5leHRFbGVtZW50KCksIGlkKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkNvbnRhaW5zIHRvbyBtYW55IGVsZW1lbnRzIiwgZW4uaGFzTW9yZUVsZW1lbnRzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuSWRlbnRpdHlTY29wZSNnZXRJZGVudGl0eShqYXZhLnNlY3VyaXR5LlByaW5jaXBhbCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldElkZW50aXR5TGphdmFfc2VjdXJpdHlfUHJpbmNpcGFsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElkZW50aXR5IGlkID0gbmV3IElkZW50aXR5U3ViY2xhc3MoInByaW5jaXBhbCBuYW1lIik7CisgICAgICAgIGlkLnNldFB1YmxpY0tleShnZXRQdWJLZXkoKSk7CisgICAgICAgIElkZW50aXR5U2NvcGVTdWJjbGFzcyBzdWIgPSBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCJ0ZXN0IiwKKyAgICAgICAgICAgICAgICBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdWIuZ2V0SWRlbnRpdHkoKGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBzdWIuYWRkSWRlbnRpdHkoaWQpOworICAgICAgICBJZGVudGl0eSByZXR1cm5lZElkID0gc3ViLmdldElkZW50aXR5KGlkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IFJldHVybmVkIElkZW50aXR5IG5vdCB0aGUgc2FtZSBhcyB0aGUgYWRkZWQgb25lOyIsIGlkLCByZXR1cm5lZElkKTsKKworICAgICAgICBJZGVudGl0eSBpZDIgPSBuZXcgSWRlbnRpdHlTdWJjbGFzcygiQW5vdGhlciBpZGVudGl0eSIpOworICAgICAgICBpZDIuc2V0UHVibGljS2V5KGdldFB1YktleSgpKTsKKworICAgICAgICBhc3NlcnROdWxsKCJUZXN0IDM6IE51bGwgdmFsdWUgZXhwZWN0ZWQuIiwgc3ViLmdldElkZW50aXR5KGlkMikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdWIuZ2V0SWRlbnRpdHkoKGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgNDogTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuSWRlbnRpdHlTY29wZSNnZXRJZGVudGl0eShqYXZhLnNlY3VyaXR5LlB1YmxpY0tleSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldElkZW50aXR5TGphdmFfc2VjdXJpdHlfUHVibGljS2V5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElkZW50aXR5U2NvcGVTdWJjbGFzcyBzdWIgPSBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCJ0ZXN0IiwKKyAgICAgICAgICAgICAgICBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCkpOworICAgICAgICBJZGVudGl0eSBpZCA9IG5ldyBJZGVudGl0eVN1YmNsYXNzKCk7CisgICAgICAgIGlkLnNldFB1YmxpY0tleShnZXRQdWJLZXkoKSk7CisgICAgICAgIHN1Yi5hZGRJZGVudGl0eShpZCk7CisgICAgICAgIElkZW50aXR5IHJldHVybmVkSWQgPSBzdWIuZ2V0SWRlbnRpdHkoZ2V0UHViS2V5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogUmV0dXJuZWQgSWRlbnRpdHkgbm90IHRoZSBzYW1lIGFzIHRoZSBhZGRlZCBvbmU7IiwgaWQsIHJldHVybmVkSWQpOworCisgICAgICAgIGFzc2VydE51bGwoIlRlc3QgMjogTnVsbCB2YWx1ZSBleHBlY3RlZC4iLCBzdWIuZ2V0SWRlbnRpdHkoKFB1YmxpY0tleSkgbnVsbCkpOworCisgICAgICAgIFB1YmxpY0tleSBhbm90aGVyS2V5ID0gS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZSgiRFNBIikuZ2VuS2V5UGFpcigpLmdldFB1YmxpYygpOworICAgICAgICBhc3NlcnROdWxsKCJUZXN0IDM6IE51bGwgdmFsdWUgZXhwZWN0ZWQuIiwgc3ViLmdldElkZW50aXR5KGFub3RoZXJLZXkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LklkZW50aXR5U2NvcGUjZ2V0SWRlbnRpdHkoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldElkZW50aXR5TGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgIElkZW50aXR5U2NvcGVTdWJjbGFzcyBzdWIgPSBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCJ0ZXN0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgbmV3IElkZW50aXR5U2NvcGVTdWJjbGFzcygpKTsKKyAgICAgICAgICAgICAgIElkZW50aXR5IGlkID0gbmV3IElkZW50aXR5U3ViY2xhc3MoInRlc3QiKTsKKyAgICAgICAgICAgICAgIGlkLnNldFB1YmxpY0tleShnZXRQdWJLZXkoKSk7CisgICAgICAgICAgICAgICBzdWIuYWRkSWRlbnRpdHkoaWQpOworICAgICAgICAgICAgICAgSWRlbnRpdHkgcmV0dXJuZWRJZCA9IHN1Yi5nZXRJZGVudGl0eSgidGVzdCIpOworICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBJZGVudGl0eSBub3QgdGhlIHNhbWUgYXMgdGhlIGFkZGVkIG9uZSIsIGlkLCByZXR1cm5lZElkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LklkZW50aXR5U2NvcGUjc2l6ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zaXplKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElkZW50aXR5U2NvcGVTdWJjbGFzcyBzdWIgPSBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCJ0ZXN0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IElkZW50aXR5U2NvcGVTdWJjbGFzcygpKTsKKyAgICAgICAgSWRlbnRpdHkgaWQgPSBuZXcgSWRlbnRpdHlTdWJjbGFzcygpOworICAgICAgICBpZC5zZXRQdWJsaWNLZXkoZ2V0UHViS2V5KCkpOworICAgICAgICBzdWIuYWRkSWRlbnRpdHkoaWQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAxLCBzdWIuc2l6ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LklkZW50aXR5U2NvcGUjdG9TdHJpbmcoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSWRlbnRpdHlTY29wZVN1YmNsYXNzIHN1YiA9IG5ldyBJZGVudGl0eVNjb3BlU3ViY2xhc3MoInRlc3QiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSWRlbnRpdHlTY29wZVN1YmNsYXNzKCkpOworICAgICAgICBJZGVudGl0eSBpZCA9IG5ldyBJZGVudGl0eVN1YmNsYXNzKCk7CisgICAgICAgIGlkLnNldFB1YmxpY0tleShnZXRQdWJLZXkoKSk7CisgICAgICAgIHN1Yi5hZGRJZGVudGl0eShpZCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoInRvU3RyaW5nIHJldHVybmVkIGEgbnVsbCIsIHN1Yi50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTm90IGEgdmFsaWQgU3RyaW5nICIsIHN1Yi50b1N0cmluZygpLmxlbmd0aCgpID4gMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJZGVudGl0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvL1JlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMTE3MworICAgICAgICBJZGVudGl0eVNjb3BlIHNjb3BlID0gSWRlbnRpdHlTY29wZS5nZXRTeXN0ZW1TY29wZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2NvcGUuZ2V0SWRlbnRpdHkoKFN0cmluZykgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvSWRlbnRpdHlTY29wZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9JZGVudGl0eVNjb3BlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZkOTdjYWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvSWRlbnRpdHlTY29wZVRlc3QuamF2YQpAQCAtMCwwICsxLDExNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxla3NlaSBZLiBTZW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LklkZW50aXR5U2NvcGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5UGVybWlzc2lvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LklkZW50aXR5U2NvcGVTdHViOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5JZGVudGl0eVNjb3BlPC9jb2RlPgorICoKKyAqLworQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKK3B1YmxpYyBjbGFzcyBJZGVudGl0eVNjb3BlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTXlTZWN1cml0eU1hbmFnZXIgZXh0ZW5kcyBTZWN1cml0eU1hbmFnZXIgeworICAgICAgICBwdWJsaWMgUGVybWlzc2lvbnMgZGVuaWVkID0gbmV3IFBlcm1pc3Npb25zKCk7CisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihQZXJtaXNzaW9uIHBlcm1pc3Npb24peworICAgICAgICAgICAgaWYgKGRlbmllZCE9bnVsbCAmJiBkZW5pZWQuaW1wbGllcyhwZXJtaXNzaW9uKSkgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBJZGVudGl0eVNjb3BlIGlzOworCisgICAgLyoqCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3IgU3RyaW5nIHRvU3RyaW5nKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0VG9TdHJpbmcoKSB7CisgICAgICAgIGFzc2VydE5vdE51bGwobmV3IElkZW50aXR5U2NvcGVTdHViKCJBbGVrc2VpIFNlbWVub3YiKS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB0ZXN0IGRlZmF1bHQgY29uc3RydWN0b3Igdm9pZCBJZGVudGl0eVNjb3BlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0SWRlbnRpdHlTY29wZSgpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXcgSWRlbnRpdHlTY29wZVN0dWIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogY2hlY2sgdGhhdCB2b2lkIElkZW50aXR5U2NvcGUoU3RyaW5nKSBjcmVhdGVzIGluc3RhbmNlIHdpdGggZ2l2ZW4gbmFtZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RJZGVudGl0eVNjb3BlU3RyaW5nKCkgeworICAgICAgICBpcyA9IG5ldyBJZGVudGl0eVNjb3BlU3R1YigiQWxla3NlaSBTZW1lbm92Iik7CisgICAgICAgIGFzc2VydE5vdE51bGwoaXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFsZWtzZWkgU2VtZW5vdiIsIGlzLmdldE5hbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogY2hlY2sgdGhhdCB2b2lkIElkZW50aXR5U2NvcGUoU3RyaW5nLCBJZGVudGl0eVNjb3BlKSBjcmVhdGVzIGluc3RhbmNlIHdpdGggZ2l2ZW4gbmFtZSBhbmQgd2l0aGluIGdpdmVuIHNjb3BlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdElkZW50aXR5U2NvcGVTdHJpbmdJZGVudGl0eVNjb3BlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElkZW50aXR5U2NvcGUgc2NvcGUgPSBuZXcgSWRlbnRpdHlTY29wZVN0dWIoIm15IHNjb3BlIik7CisgICAgICAgIGlzID0gbmV3IElkZW50aXR5U2NvcGVTdHViKCJBbGVrc2VpIFNlbWVub3YiLCBzY29wZSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoaXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFsZWtzZWkgU2VtZW5vdiIsIGlzLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzY29wZS5nZXROYW1lKCksIGlzLmdldFNjb3BlKCkuZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqdXN0IGNhbGwgSWRlbnRpdHlTY29wZS5nZXRTeXN0ZW1TY29wZSgpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFN5c3RlbVNjb3BlKCkgeworICAgICAgICBTdHJpbmcgbmFtZSA9IFNlY3VyaXR5LmdldFByb3BlcnR5KCJzeXN0ZW0uc2NvcGUiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuYW1lKTsKKyAgICAgICAgSWRlbnRpdHlTY29wZSBzY29wZSA9IElkZW50aXR5U2NvcGUuZ2V0U3lzdGVtU2NvcGUoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzY29wZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuYW1lLCBzY29wZS5nZXRDbGFzcygpLmdldE5hbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogY2hlY2sgdGhhdCBpZiBwZXJtaXNzaW9uIGdpdmVuIC0gc2V0L2dldCB3b3JrcworICAgICAqIGlmIHBlcm1pc3Npb24gaXMgZGVuaWVkIHRoYW4gU2VjdXJpdHlFeGNlcHRpb24gaXMgdGhyb3duCisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0U2V0U3lzdGVtU2NvcGUoKSB7CisvLyAgICAgIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gaXMgc3BlY2lmaWVkIGJ5IHNlY3VyaXR5IHByb3BlcnR5IHN5c3RlbS5zY29wZQorICAgICAgICBJZGVudGl0eVNjb3BlIHN5c3RlbVNjb3BlID0gSWRlbnRpdHlTY29wZS5nZXRTeXN0ZW1TY29wZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBhbGwgcGVybWlzc2lvbnMgYXJlIGdyYW50ZWQgLSBzbSBpcyBub3QgaW5zdGFsbGVkCisgICAgICAgICAgICBpcyA9IG5ldyBJZGVudGl0eVNjb3BlU3R1YigiQWxla3NlaSBTZW1lbm92Iik7CisgICAgICAgICAgICBJZGVudGl0eVNjb3BlU3R1Yi5teVNldFN5c3RlbVNjb3BlKGlzKTsKKyAgICAgICAgICAgIGFzc2VydFNhbWUoaXMsIElkZW50aXR5U2NvcGUuZ2V0U3lzdGVtU2NvcGUoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBJZGVudGl0eVNjb3BlU3R1Yi5teVNldFN5c3RlbVNjb3BlKHN5c3RlbVNjb3BlKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0ludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODkwNDE5ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTg4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb248L2NvZGU+IGNsYXNzCisgKiBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgVGhyb3dhYmxlIHRDYXVzZSA9IG5ldyBUaHJvd2FibGUoIlRocm93YWJsZSBmb3IgZXhjZXB0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uKCk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwKKyAgICAgKiBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24wMSgpIHsKKyAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB0RSA9IG5ldyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB3aXRoCisgICAgICogZGV0YWlsIG1lc3NhZ2UgbXNnLiBQYXJhbWV0ZXIgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjAyKCkgeworICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uMDMoKSB7CisgICAgICAgIFN0cmluZyBtc2cgPSBudWxsOworICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHRFID0gbmV3IEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgbXNnKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+SW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbihUaHJvd2FibGUpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHdoZW4KKyAgICAgKiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uMDQoKSB7CisgICAgICAgIFRocm93YWJsZSBjYXVzZSA9IG51bGw7CisgICAgICAgIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gdEUgPSBuZXcgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICBjYXVzZSk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24oVGhyb3dhYmxlKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24wNSgpIHsKKyAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB0RSA9IG5ldyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgIHRDYXVzZSk7CisgICAgICAgIGlmICh0RS5nZXRNZXNzYWdlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgc2hvdWxkIGNvbnRhaW4gIi5jb25jYXQodG9TKSwgKGdldE0KKyAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwgdEUKKyAgICAgICAgICAgICAgICAuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvcgorICAgICAqIDxjb2RlPkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHdoZW4KKyAgICAgKiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjA2KCkgeworICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHRFID0gbmV3IEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IKKyAgICAgKiA8Y29kZT5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uMDcoKSB7CisgICAgICAgIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbihtc2dzW2ldLCBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yCisgICAgICogPGNvZGU+SW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QgbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjA4KCkgeworICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHRFID0gbmV3IEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgbnVsbCwgdENhdXNlKTsKKyAgICAgICAgaWYgKHRFLmdldE1lc3NhZ2UoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IHNob3VsZCAiLmNvbmNhdCh0b1MpLCAoZ2V0TQorICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgIC5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yCisgICAgICogPGNvZGU+SW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QgbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24wOSgpIHsKKyAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uKG1zZ3NbaV0sIHRDYXVzZSk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGlmIChtc2dzW2ldLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IGNvbnRhaW4gIi5jb25jYXQobXNnc1tpXSksIGdldE0KKyAgICAgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKG1zZ3NbaV0pICE9IC0xKTsKKyAgICAgICAgICAgICAgICBpZiAoIWdldE0uZXF1YWxzKG1zZ3NbaV0pKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBzaG91bGQgY29udGFpbiAiLmNvbmNhdCh0b1MpLCBnZXRNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwKKyAgICAgICAgICAgICAgICAgICAgdEUuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9JbnZhbGlkS2V5RXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0ludmFsaWRLZXlFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmE4NTVjZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9JbnZhbGlkS2V5RXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTc2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkludmFsaWRLZXlFeGNlcHRpb248L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBJbnZhbGlkS2V5RXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIG1zZ3MgPSB7CisgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UiIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBUaHJvd2FibGUgdENhdXNlID0gbmV3IFRocm93YWJsZSgiVGhyb3dhYmxlIGZvciBleGNlcHRpb24iKTsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkludmFsaWRLZXlFeGNlcHRpb24oKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgSW52YWxpZEtleUV4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEludmFsaWRLZXlFeGNlcHRpb24wMSgpIHsKKyAgICAgICAgSW52YWxpZEtleUV4Y2VwdGlvbiB0RSA9IG5ldyBJbnZhbGlkS2V5RXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkludmFsaWRLZXlFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgSW52YWxpZEtleUV4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4KKyAgICAgKiBQYXJhbWV0ZXIgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZEtleUV4Y2VwdGlvbjAyKCkgeworICAgICAgICBJbnZhbGlkS2V5RXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IEludmFsaWRLZXlFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5JbnZhbGlkS2V5RXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEludmFsaWRLZXlFeGNlcHRpb24gd2hlbiA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZEtleUV4Y2VwdGlvbjAzKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICAgICAgSW52YWxpZEtleUV4Y2VwdGlvbiB0RSA9IG5ldyBJbnZhbGlkS2V5RXhjZXB0aW9uKG1zZyk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkludmFsaWRLZXlFeGNlcHRpb24oVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgSW52YWxpZEtleUV4Y2VwdGlvbiB3aGVuIDxjb2RlPmNhdXNlPC9jb2RlPiBpcworICAgICAqIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZEtleUV4Y2VwdGlvbjA0KCkgeworICAgICAgICBUaHJvd2FibGUgY2F1c2UgPSBudWxsOworICAgICAgICBJbnZhbGlkS2V5RXhjZXB0aW9uIHRFID0gbmV3IEludmFsaWRLZXlFeGNlcHRpb24oY2F1c2UpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5JbnZhbGlkS2V5RXhjZXB0aW9uKFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEludmFsaWRLZXlFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMKKyAgICAgKiBub3QgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkS2V5RXhjZXB0aW9uMDUoKSB7CisgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24gdEUgPSBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbih0Q2F1c2UpOworICAgICAgICBpZiAodEUuZ2V0TWVzc2FnZSgpICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIFN0cmluZyBnZXRNID0gdEUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIHNob3VsZCBjb250YWluICIuY29uY2F0KHRvUyksIChnZXRNCisgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKHRvUykgIT0gLTEpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiAiLmNvbmNhdCh0Q2F1c2UudG9TdHJpbmcoKSksIHRFCisgICAgICAgICAgICAgICAgLmdldENhdXNlKCksIHRDYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+SW52YWxpZEtleUV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEludmFsaWRLZXlFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkS2V5RXhjZXB0aW9uMDYoKSB7CisgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24gdEUgPSBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbihudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5JbnZhbGlkS2V5RXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgSW52YWxpZEtleUV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkS2V5RXhjZXB0aW9uMDcoKSB7CisgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgSW52YWxpZEtleUV4Y2VwdGlvbihtc2dzW2ldLCBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkludmFsaWRLZXlFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHdoZW4KKyAgICAgKiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90IG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEludmFsaWRLZXlFeGNlcHRpb24wOCgpIHsKKyAgICAgICAgSW52YWxpZEtleUV4Y2VwdGlvbiB0RSA9IG5ldyBJbnZhbGlkS2V5RXhjZXB0aW9uKG51bGwsIHRDYXVzZSk7CisgICAgICAgIGlmICh0RS5nZXRNZXNzYWdlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgbXVzdCBzaG91bGQgIi5jb25jYXQodG9TKSwgKGdldE0KKyAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwgdEUKKyAgICAgICAgICAgICAgICAuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5JbnZhbGlkS2V5RXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgSW52YWxpZEtleUV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdCBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZEtleUV4Y2VwdGlvbjA5KCkgeworICAgICAgICBJbnZhbGlkS2V5RXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IEludmFsaWRLZXlFeGNlcHRpb24obXNnc1tpXSwgdENhdXNlKTsKKyAgICAgICAgICAgIFN0cmluZyBnZXRNID0gdEUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgaWYgKG1zZ3NbaV0ubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIG11c3QgY29udGFpbiAiLmNvbmNhdChtc2dzW2ldKSwgZ2V0TQorICAgICAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YobXNnc1tpXSkgIT0gLTEpOworICAgICAgICAgICAgICAgIGlmICghZ2V0TS5lcXVhbHMobXNnc1tpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIHNob3VsZCBjb250YWluICIuY29uY2F0KHRvUyksIGdldE0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLAorICAgICAgICAgICAgICAgICAgICB0RS5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0ludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZDliOWNjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0ludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw3OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5JbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kCisgKiBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgc3RhdGljIFN0cmluZ1tdIG1zZ3MgPSB7CisgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UiIH07CisKKyAgICBzdGF0aWMgVGhyb3dhYmxlIHRDYXVzZSA9IG5ldyBUaHJvd2FibGUoIlRocm93YWJsZSBmb3IgZXhjZXB0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5JbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKCk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uMDEoKSB7CisgICAgICAgIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gdEUgPSBuZXcgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbigpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5JbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gd2l0aCBkZXRhaWwgbWVzc2FnZSBtc2cuCisgICAgICogUGFyYW1ldGVyIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24wMigpIHsKKyAgICAgICAgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm46ICIuY29uY2F0KG1zZ3NbaV0pLCB0RQorICAgICAgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZSgpLCBtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+SW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIHdoZW4gPGNvZGU+bXNnPC9jb2RlPgorICAgICAqIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbjAzKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICAgICAgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiB0RSA9IG5ldyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKG1zZyk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LU0NhbGxiYWNrSGFuZGxlclByb3RlY3Rpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS1NDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2NzQ0NGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS1NDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKKworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suQ2FsbGJhY2s7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC5jYWxsYmFjay5DYWxsYmFja0hhbmRsZXI7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC5jYWxsYmFjay5VbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQudG1wQ2FsbGJhY2tIYW5kbGVyOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5LZXlTdG9yZS5DYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uPiBjbGFzcyBjb25zdHJ1Y3RvciBhbmQgbWV0aG9kcworICoKKyAqLworcHVibGljIGNsYXNzIEtTQ2FsbGJhY2tIYW5kbGVyUHJvdGVjdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5LZXlTdG9yZS5DYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uKENhbGxiYWNrSGFuZGxlciBoYW5kbGVyKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gaGFuZGxlciBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENhbGxiYWNrSGFuZGxlclByb3RlY3Rpb24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgS2V5U3RvcmUuQ2FsbGJhY2tIYW5kbGVyUHJvdGVjdGlvbihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gaGFuZGxlciBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIGNsYXNzIFRlc3RDYWxsYmFja0hhbmRsZXIgaW1wbGVtZW50cyBDYWxsYmFja0hhbmRsZXIgeworCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBoYW5kbGUoQ2FsbGJhY2tbXSBjYWxsYmFja3MpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgLy8gZG9lcyBub3RoaW5nCisgICAgICAgICAgICB9CisKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgS2V5U3RvcmUuQ2FsbGJhY2tIYW5kbGVyUHJvdGVjdGlvbihuZXcgVGVzdENhbGxiYWNrSGFuZGxlcigpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldENhbGxiYWNrSGFuZGxlcigpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgQ2FsbGJhY2tIYW5kbGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldENhbGxCYWNrSGFuZGxlcigpIHsKKyAgICAgICAgQ2FsbGJhY2tIYW5kbGVyIGNiaCA9IG5ldyB0bXBDYWxsYmFja0hhbmRsZXIoKTsKKyAgICAgICAgS2V5U3RvcmUuQ2FsbGJhY2tIYW5kbGVyUHJvdGVjdGlvbiBrc0NCSCA9IG5ldyBLZXlTdG9yZS5DYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uKGNiaCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IENhbGxiYWNrSGFuZGxlciIsIGNiaCwKKyAgICAgICAgICAgICAgICBrc0NCSC5nZXRDYWxsYmFja0hhbmRsZXIoKSk7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS1NQYXNzd29yZFByb3RlY3Rpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS1NQYXNzd29yZFByb3RlY3Rpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWY4MTFiMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LU1Bhc3N3b3JkUHJvdGVjdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDcxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworCitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC5EZXN0cm95RmFpbGVkRXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5LZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb248L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9yIGFuZCBtZXRob2RzCisgKgorICovCitwdWJsaWMgY2xhc3MgS1NQYXNzd29yZFByb3RlY3Rpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+S2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uKGNoYXJbXSBwYXNzd29yZCk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogYW5kIHRoZSBmb2xsb3dpbmcgbWV0aG9kcworICAgICAqIDxjb2RlPmdldFBhc3N3b3JkKCk8Y29kZT4KKyAgICAgKiA8Y29kZT5kZXN0cm95KCk8Y29kZT4KKyAgICAgKiA8Y29kZT5pc0Rlc3Ryb3llZCgpPGNvZGU+CisgICAgICogQXNzZXJ0aW9uczogY29uc3RydWN0b3IgY3JlYXRlZCBuZXcgUGFzc3dvcmRQcm90ZWN0aW9uIG9iamVjdAorICAgICAqIGdldFBhc3N3b3JkKCkgcmV0dXJucyBwYXNzd29yZCBvciB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICogaWYgUGFzc3dvcmRQcm90ZWN0aW9uIGlzIGRlc3Ryb3llZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQYXNzd29yZCgpIHRocm93cyBEZXN0cm95RmFpbGVkRXhjZXB0aW9uIHsKKyAgICAgICAgY2hhciBbXSBwYXNzID0geydhJywgJ2InLCAnYyd9OworICAgICAgICBLZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb24ga3NQV1AgPSBuZXcgS2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uKHBhc3MpOworICAgICAgICBjaGFyIFtdIHJQYXNzID0ga3NQV1AuZ2V0UGFzc3dvcmQoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlBhc3N3b3JkUHJvdGVjdGlvbiBTaG91bGQgbm90IGJlIGRlc3Ryb3llZCIsIGtzUFdQLmlzRGVzdHJveWVkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwYXNzd29yZCBsZW5ndGgiLCBwYXNzLmxlbmd0aCwgclBhc3MubGVuZ3RoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXNzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwYXNzd29yZCAoaXRlbTogIi5jb25jYXQoSW50ZWdlci50b1N0cmluZyhpKSkKKyAgICAgICAgICAgICAgICAgICAgLmNvbmNhdCgiKSIpLCBwYXNzW2ldLCByUGFzc1tpXSk7CisgICAgICAgIH0KKyAgICAgICAga3NQV1AuZGVzdHJveSgpOworICAgICAgICBhc3NlcnRUcnVlKCJQYXNzd29yZFByb3RlY3Rpb24gbXVzdCBiZSBkZXN0cm95ZWQiLCBrc1BXUC5pc0Rlc3Ryb3llZCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtzUFdQLmdldFBhc3N3b3JkKCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gYmVjYXVzZSBQYXNzd29yZFByb3RlY3Rpb24gaXMgZGVzdHJveWVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAga3NQV1AgPSBuZXcgS2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uKG51bGwpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gZm9yIE5VTEwgcGFyYW1ldGVyIik7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS1NQcml2YXRlS2V5RW50cnlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS1NQcml2YXRlS2V5RW50cnlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTM5NTZlZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LU1ByaXZhdGVLZXlFbnRyeVRlc3QuamF2YQpAQCAtMCwwICsxLDIwMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5NeUNlcnRpZmljYXRlOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+S2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5PC9jb2RlPiAgY2xhc3MgY29uc3RydWN0b3IgYW5kIG1ldGhvZHMKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBLU1ByaXZhdGVLZXlFbnRyeVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIFByaXZhdGVLZXkgdGVzdFByaXZhdGVLZXk7CisgICAgcHJpdmF0ZSBDZXJ0aWZpY2F0ZSBbXSB0ZXN0Q2hhaW47CisKKyAgICBwcml2YXRlIHZvaWQgY3JlYXRlUGFyYW1zKGJvb2xlYW4gZGlmZkNlcnRzLCBib29sZWFuIGRpZmZLZXlzKSB7CisgICAgICAgIGJ5dGVbXSBlbmNvZGVkID0geyhieXRlKTAsIChieXRlKTEsIChieXRlKTIsIChieXRlKTN9OworICAgICAgICB0ZXN0Q2hhaW4gPSBuZXcgQ2VydGlmaWNhdGVbNV07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGVzdENoYWluLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBTdHJpbmcgcyA9IChkaWZmQ2VydHMgPyBJbnRlZ2VyLnRvU3RyaW5nKGkpIDogIk5FVyIpOworICAgICAgICAgICAgdGVzdENoYWluW2ldID0gbmV3IE15Q2VydGlmaWNhdGUoIk1ZX1RFU1RfQ0VSVElGSUNBVEVfIgorICAgICAgICAgICAgICAgICAgICAuY29uY2F0KHMpLCBlbmNvZGVkKTsKKyAgICAgICAgfQorICAgICAgICB0ZXN0UHJpdmF0ZUtleSA9IChkaWZmS2V5cyA/IChQcml2YXRlS2V5KW5ldyB0bXBQcml2YXRlS2V5KCkgOgorICAgICAgICAgICAgKFByaXZhdGVLZXkpbmV3IHRtcFByaXZhdGVLZXkodGVzdENoYWluWzBdLmdldFB1YmxpY0tleSgpLmdldEFsZ29yaXRobSgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+UHJpdmF0ZUtleUVudHJ5KFByaXZhdGVLZXkgcHJpdmF0ZUtleSwgQ2VydGlmaWNhdGVbXSBjaGFpbik8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIHByaXZhdGVLZXkgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RQcml2YXRlS2V5RW50cnkwMSgpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVbXSBjZXJ0cyA9IG5ldyBNeUNlcnRpZmljYXRlWzFdOy8vbmV3IENlcnRpZmljYXRlWzFdOworICAgICAgICBQcml2YXRlS2V5IHBrID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBLZXlTdG9yZS5Qcml2YXRlS2V5RW50cnkocGssIGNlcnRzKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gcHJpdmF0ZUtleSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPlByaXZhdGVLZXlFbnRyeShQcml2YXRlS2V5IHByaXZhdGVLZXksIENlcnRpZmljYXRlW10gY2hhaW4pPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBjaGFpbiBpcyBudWxsCisgICAgICogYW5kIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2hlbiBjaGFpbiBsZW5ndGggaXMgMAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RQcml2YXRlS2V5RW50cnkwMigpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVbXSBjaGFpbiA9IG51bGw7CisgICAgICAgIFByaXZhdGVLZXkgcGsgPSBuZXcgdG1wUHJpdmF0ZUtleSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeShwaywgY2hhaW4pOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBjaGFpbiBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY2hhaW4gPSBuZXcgQ2VydGlmaWNhdGVbMF07CisgICAgICAgICAgICBuZXcgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5KHBrLCBjaGFpbik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBjaGFpbiBsZW5ndGggaXMgMCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPlByaXZhdGVLZXlFbnRyeShQcml2YXRlS2V5IHByaXZhdGVLZXksIENlcnRpZmljYXRlW10gY2hhaW4pPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gY2hhaW4gY29udGFpbnMgY2VydGlmaWNhdGVzCisgICAgICogb2YgZGlmZmVyZW50IHR5cGVzCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFByaXZhdGVLZXlFbnRyeTAzKCkgeworICAgICAgICBjcmVhdGVQYXJhbXModHJ1ZSwgZmFsc2UpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSh0ZXN0UHJpdmF0ZUtleSwgdGVzdENoYWluKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIGNoYWluIGNvbnRhaW5zIGNlcnRpZmljYXRlcyBvZiBkaWZmZXJlbnQgdHlwZXMiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPlByaXZhdGVLZXlFbnRyeShQcml2YXRlS2V5IHByaXZhdGVLZXksIENlcnRpZmljYXRlW10gY2hhaW4pPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIG9mIHByaXZhdGVLZXkKKyAgICAgKiBkb2VzIG5vdCBtYXRjaCB0aGUgYWxnb3JpdGhtIG9mIFB1YmxpY0tleSBpbiB0aGUgZW5kIGNlcnRpZmljYXRlICh3aXRoIDAgaW5kZXgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFByaXZhdGVLZXlFbnRyeTA0KCkgeworICAgICAgICBjcmVhdGVQYXJhbXMoZmFsc2UsIHRydWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSh0ZXN0UHJpdmF0ZUtleSwgdGVzdENoYWluKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIGtleSBhbGdvcml0aG1zIGRvIG5vdCBtYXRjaCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UHJpdmF0ZUtleSgpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgUHJpdmF0ZUtleSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UHJpdmF0ZUtleSgpIHsKKyAgICAgICAgY3JlYXRlUGFyYW1zKGZhbHNlLCBmYWxzZSk7CisgICAgICAgIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSBrc1BLRSA9IG5ldyBLZXlTdG9yZS5Qcml2YXRlS2V5RW50cnkoCisgICAgICAgICAgICAgICAgdGVzdFByaXZhdGVLZXksIHRlc3RDaGFpbik7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IFByaXZhdGVLZXkiLCB0ZXN0UHJpdmF0ZUtleSwga3NQS0UKKyAgICAgICAgICAgICAgICAuZ2V0UHJpdmF0ZUtleSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRDZXJ0aWZpY2F0ZUNoYWluKCk8L2NvZGU+IG1ldGhvZCBBc3NlcnRpb246IHJldHVybnMKKyAgICAgKiBhcnJheSBvZiB0aGUgQ2VydGlmaWNhdGVzIGNvcnJlc3BvbmRpbmcgdG8gY2hhaW4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q2VydGlmaWNhdGVDaGFpbigpIHsKKyAgICAgICAgY3JlYXRlUGFyYW1zKGZhbHNlLCBmYWxzZSk7CisgICAgICAgIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSBrc1BLRSA9IG5ldyBLZXlTdG9yZS5Qcml2YXRlS2V5RW50cnkoCisgICAgICAgICAgICAgICAgdGVzdFByaXZhdGVLZXksIHRlc3RDaGFpbik7CisgICAgICAgIENlcnRpZmljYXRlW10gcmVzID0ga3NQS0UuZ2V0Q2VydGlmaWNhdGVDaGFpbigpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBjaGFpbiBsZW5ndGgiLCB0ZXN0Q2hhaW4ubGVuZ3RoLCByZXMubGVuZ3RoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGNoYWluIGVsZW1lbnQ6ICIKKyAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChJbnRlZ2VyLnRvU3RyaW5nKGkpKSwgdGVzdENoYWluW2ldLCByZXNbaV0pOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0Q2VydGlmaWNhdGUoKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIGVuZCBDZXJ0aWZpY2F0ZSAod2l0aCAwIGluZGV4IGluIGNoYWluKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDZXJ0aWZpY2F0ZSgpIHsKKyAgICAgICAgY3JlYXRlUGFyYW1zKGZhbHNlLCBmYWxzZSk7CisgICAgICAgIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSBrc1BLRSA9IG5ldyBLZXlTdG9yZS5Qcml2YXRlS2V5RW50cnkoCisgICAgICAgICAgICAgICAgdGVzdFByaXZhdGVLZXksIHRlc3RDaGFpbik7CisgICAgICAgIENlcnRpZmljYXRlIHJlcyA9IGtzUEtFLmdldENlcnRpZmljYXRlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGVuZCBjZXJ0aWZpY2F0ZSAobnVtYmVyIDApIiwgdGVzdENoYWluWzBdLCByZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnRvU3RyaW5nKCk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBub24gbnVsbCBTdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9TdHJpbmcoKSB7CisgICAgICAgIGNyZWF0ZVBhcmFtcyhmYWxzZSwgZmFsc2UpOworICAgICAgICBLZXlTdG9yZS5Qcml2YXRlS2V5RW50cnkga3NQS0UgPSBuZXcgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5KAorICAgICAgICAgICAgICAgIHRlc3RQcml2YXRlS2V5LCB0ZXN0Q2hhaW4pOworICAgICAgICBTdHJpbmcgcmVzID0ga3NQS0UudG9TdHJpbmcoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgidG9TdHJpbmcoKSByZXR1cm5zIG51bGwiLCByZXMpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgVGVzdCBzdWl0ZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBUZXN0U3VpdGUoS1NQcml2YXRlS2V5RW50cnlUZXN0LmNsYXNzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyB0bXBQcml2YXRlS2V5IGltcGxlbWVudHMgUHJpdmF0ZUtleSB7CisgICAgICAgIHByaXZhdGUgU3RyaW5nIGFsZyA9ICJNeSBhbGdvcml0aG0iOworCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICAgICAgcmV0dXJuIGFsZzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgcmV0dXJuICJNeSBGb3JtYXQiOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBieXRlWzFdOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHRtcFByaXZhdGVLZXkoKSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdG1wUHJpdmF0ZUtleShTdHJpbmcgYWxnb3JpdGhtKSB7CisgICAgICAgICAgICBzdXBlcigpOworICAgICAgICAgICAgYWxnID0gYWxnb3JpdGhtOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tTU2VjcmV0S2V5RW50cnlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS1NTZWNyZXRLZXlFbnRyeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mODU1OTNlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tTU2VjcmV0S2V5RW50cnlUZXN0LmphdmEKQEAgLTAsMCArMSw5MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKKworaW1wb3J0IGphdmF4LmNyeXB0by5TZWNyZXRLZXk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPktleVN0b3JlLlNlY3JldEtleUVudHJ5PC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvciBhbmQgbWV0aG9kcworICoKKyAqLworcHVibGljIGNsYXNzIEtTU2VjcmV0S2V5RW50cnlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+U2VjcmV0S2V5RW50cnkoU2VjcmV0S2V5IHNlY3JldEtleSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBzZWNyZXRLZXkgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZWNyZXRLZXlFbnRyeSgpIHsKKyAgICAgICAgU2VjcmV0S2V5IHNrID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBLZXlTdG9yZS5TZWNyZXRLZXlFbnRyeShzayk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHNlY3JldEtleSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgc2sgPSBuZXcgdG1wU2VjcmV0S2V5KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZS5TZWNyZXRLZXlFbnRyeSBza2UgPSBuZXcgS2V5U3RvcmUuU2VjcmV0S2V5RW50cnkoc2spOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChza2UpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShza2UgaW5zdGFuY2VvZiBLZXlTdG9yZS5TZWNyZXRLZXlFbnRyeSk7CisgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIHdhcyB0aHJvd24gd2hlbiBzZWNyZXRLZXkgaXMgbm90IG51bGwiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldFNlY3JldEtleSgpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgU2VjcmV0S2V5IGZyb20gdGhlIGdpdmVuIGVudHJ5CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldFNlY3JldEtleSgpIHsKKyAgICAgICAgU2VjcmV0S2V5IHNrID0gbmV3IHRtcFNlY3JldEtleSgpOworICAgICAgICBLZXlTdG9yZS5TZWNyZXRLZXlFbnRyeSBza2UgPSBuZXcgS2V5U3RvcmUuU2VjcmV0S2V5RW50cnkoc2spOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBTZWNyZXRLZXkiLCBzaywgc2tlLmdldFNlY3JldEtleSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT50b1N0cmluZygpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgbm9uIG51bGwgc3RyaW5nCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFRvU3RyaW5nKCkgeworICAgICAgICBTZWNyZXRLZXkgc2sgPSBuZXcgdG1wU2VjcmV0S2V5KCk7CisgICAgICAgIEtleVN0b3JlLlNlY3JldEtleUVudHJ5IHNrZSA9IG5ldyBLZXlTdG9yZS5TZWNyZXRLZXlFbnRyeShzayk7CisgICAgICAgIGFzc2VydE5vdE51bGwoInRvU3RyaW5nKCkgcmV0dXJucyBudWxsIHN0cmluZyIsIHNrZS50b1N0cmluZygpKTsKKyAgICB9Cit9CisKK2NsYXNzIHRtcFNlY3JldEtleSBpbXBsZW1lbnRzIFNlY3JldEtleSB7CisgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiAiTXkgYWxnb3JpdGhtIjsKKyAgICB9CisgICAgcHVibGljIFN0cmluZyBnZXRGb3JtYXQoKSB7CisgICAgICAgIHJldHVybiAiTXkgRm9ybWF0IjsKKyAgICB9CisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICByZXR1cm4gbmV3IGJ5dGVbMV07CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tTVHJ1c3RlZENlcnRpZmljYXRlRW50cnlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS1NUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MzUwNTQyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tTVHJ1c3RlZENlcnRpZmljYXRlRW50cnlUZXN0LmphdmEKQEAgLTAsMCArMSw4NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0Lk15Q2VydGlmaWNhdGU7CisKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+S2V5U3RvcmUuVHJ1c3RlZENlcnRpZmljYXRlRW50cnk8L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9yIGFuZCBtZXRob2RzCisgKgorICovCisKK3B1YmxpYyBjbGFzcyBLU1RydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RmZT5LZXlTdG9yZS5UcnVzdGVkQ2VydGlmaWNhdGVFbnRyeShDZXJ0aWZpY2F0ZSB0cnVzdENlcnQpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiB0cnVzdENlcnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeSgpIHsKKyAgICAgICAgQ2VydGlmaWNhdGUgY2VydCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgS2V5U3RvcmUuVHJ1c3RlZENlcnRpZmljYXRlRW50cnkoY2VydCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHRydXN0Q2VydCBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIGNlcnQgPSBuZXcgTXlDZXJ0aWZpY2F0ZSgiVEVTVCIsIG5ldyBieXRlWzEwXSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZS5UcnVzdGVkQ2VydGlmaWNhdGVFbnRyeSBrc1RDRSA9IG5ldyBLZXlTdG9yZS5UcnVzdGVkQ2VydGlmaWNhdGVFbnRyeShjZXJ0KTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoa3NUQ0UpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShrc1RDRSBpbnN0YW5jZW9mIEtleVN0b3JlLlRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5KTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIHdhcyB0aHJvd24gd2hlbiB0cnVzdENlcnQgaXMgbm90IG51bGwiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RmZT5nZXRUcnVzdGVkQ2VydGlmaWNhdGUoKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHRydXN0ZWQgQ2VydGlmaWNhdGUgZnJvbSBnb3ZlbiBlbnRyeQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRUcnVzdGVkQ2VydGlmaWNhdGUoKSB7CisgICAgICAgIENlcnRpZmljYXRlIGNlcnQgPSBuZXcgTXlDZXJ0aWZpY2F0ZSgiVEVTVCIsIG5ldyBieXRlWzEwXSk7CisgICAgICAgIEtleVN0b3JlLlRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5IGtzVENFID0KKyAgICAgICAgICAgICAgICBuZXcgS2V5U3RvcmUuVHJ1c3RlZENlcnRpZmljYXRlRW50cnkoY2VydCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGNlcnRpZmljYXRlIiwgY2VydCwga3NUQ0UuZ2V0VHJ1c3RlZENlcnRpZmljYXRlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RmZT50b1N0cmluZygpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgbm9uIG51bGwgc3RyaW5nCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFRvU3RyaW5nKCkgeworICAgICAgICBDZXJ0aWZpY2F0ZSBjZXJ0ID0gbmV3IE15Q2VydGlmaWNhdGUoIlRFU1QiLCBuZXcgYnl0ZVsxMF0pOworICAgICAgICBLZXlTdG9yZS5UcnVzdGVkQ2VydGlmaWNhdGVFbnRyeSBrc1RDRSA9CisgICAgICAgICAgICAgICAgbmV3IEtleVN0b3JlLlRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5KGNlcnQpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJ0b1N0cmluZygpIHJldHVybnMgbnVsbCBzdHJpbmciLCBrc1RDRS50b1N0cmluZygpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5RXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleUV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNmU5MTgzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleUV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDE3NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlFeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPktleUV4Y2VwdGlvbjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIEtleUV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgVGhyb3dhYmxlIHRDYXVzZSA9IG5ldyBUaHJvd2FibGUoIlRocm93YWJsZSBmb3IgZXhjZXB0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5LZXlFeGNlcHRpb24oKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzCisgICAgICogS2V5RXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5RXhjZXB0aW9uMDEoKSB7CisgICAgICAgIEtleUV4Y2VwdGlvbiB0RSA9IG5ldyBLZXlFeGNlcHRpb24oKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+S2V5RXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yIEFzc2VydGlvbjoKKyAgICAgKiBjb25zdHJ1Y3RzIEtleUV4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4gUGFyYW1ldGVyCisgICAgICogPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5RXhjZXB0aW9uMDIoKSB7CisgICAgICAgIEtleUV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBLZXlFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5LZXlFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgS2V5RXhjZXB0aW9uIHdoZW4gPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEtleUV4Y2VwdGlvbjAzKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICAgICAgS2V5RXhjZXB0aW9uIHRFID0gbmV3IEtleUV4Y2VwdGlvbihtc2cpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5LZXlFeGNlcHRpb24oVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgS2V5RXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5RXhjZXB0aW9uMDQoKSB7CisgICAgICAgIFRocm93YWJsZSBjYXVzZSA9IG51bGw7CisgICAgICAgIEtleUV4Y2VwdGlvbiB0RSA9IG5ldyBLZXlFeGNlcHRpb24oY2F1c2UpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5LZXlFeGNlcHRpb24oVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgS2V5RXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEtleUV4Y2VwdGlvbjA1KCkgeworICAgICAgICBLZXlFeGNlcHRpb24gdEUgPSBuZXcgS2V5RXhjZXB0aW9uKHRDYXVzZSk7CisgICAgICAgIGlmICh0RS5nZXRNZXNzYWdlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgc2hvdWxkIGNvbnRhaW4gIi5jb25jYXQodG9TKSwgKGdldE0KKyAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwgdEUKKyAgICAgICAgICAgICAgICAuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5LZXlFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBLZXlFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbAorICAgICAqIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlFeGNlcHRpb24wNigpIHsKKyAgICAgICAgS2V5RXhjZXB0aW9uIHRFID0gbmV3IEtleUV4Y2VwdGlvbihudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5LZXlFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBLZXlFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbAorICAgICAqIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5RXhjZXB0aW9uMDcoKSB7CisgICAgICAgIEtleUV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBLZXlFeGNlcHRpb24obXNnc1tpXSwgbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5LZXlFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBLZXlFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKiA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5RXhjZXB0aW9uMDgoKSB7CisgICAgICAgIEtleUV4Y2VwdGlvbiB0RSA9IG5ldyBLZXlFeGNlcHRpb24obnVsbCwgdENhdXNlKTsKKyAgICAgICAgaWYgKHRFLmdldE1lc3NhZ2UoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IHNob3VsZCAiLmNvbmNhdCh0b1MpLCAoZ2V0TQorICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgIC5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPktleUV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEtleUV4Y2VwdGlvbiB3aGVuIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QgbnVsbAorICAgICAqIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5RXhjZXB0aW9uMDkoKSB7CisgICAgICAgIEtleUV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBLZXlFeGNlcHRpb24obXNnc1tpXSwgdENhdXNlKTsKKyAgICAgICAgICAgIFN0cmluZyBnZXRNID0gdEUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgaWYgKG1zZ3NbaV0ubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIG11c3QgY29udGFpbiAiLmNvbmNhdChtc2dzW2ldKSwgZ2V0TQorICAgICAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YobXNnc1tpXSkgIT0gLTEpOworICAgICAgICAgICAgICAgIGlmICghZ2V0TS5lcXVhbHMobXNnc1tpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIHNob3VsZCBjb250YWluICIuY29uY2F0KHRvUyksIGdldE0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLAorICAgICAgICAgICAgICAgICAgICB0RS5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleUZhY3RvcnkyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleUZhY3RvcnkyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFiZTdmYTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5RmFjdG9yeTJUZXN0LmphdmEKQEAgLTAsMCArMSw0MzYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5RmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleUZhY3RvcnlTcGk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkludmFsaWRLZXlTcGVjRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5LZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5QS0NTOEVuY29kZWRLZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5YNTA5RW5jb2RlZEtleVNwZWM7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuU3RhbmRhcmROYW1lczsKKworcHVibGljIGNsYXNzIEtleUZhY3RvcnkyVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgS0VZRkFDVE9SWV9JRCA9ICJLZXlGYWN0b3J5LiI7CisKKyAgICBwcml2YXRlIFN0cmluZ1tdIGtleWZhY3RBbGdzID0gbnVsbDsKKworICAgIHByaXZhdGUgU3RyaW5nIHByb3ZpZGVyTmFtZSA9IG51bGw7CisKKyAgICBzdGF0aWMgY2xhc3MgS2VlcEFsaXZlIGV4dGVuZHMgVGhyZWFkIHsKKyAgICAgICAgaW50IHNsZWVwVGltZSwgaXRlcmF0aW9uczsKKworICAgICAgICBwdWJsaWMgS2VlcEFsaXZlKGludCBzbGVlcFRpbWUsIGludCBpdGVyYXRpb25zKSB7CisgICAgICAgICAgICB0aGlzLnNsZWVwVGltZSA9IHNsZWVwVGltZTsKKyAgICAgICAgICAgIHRoaXMuaXRlcmF0aW9ucyA9IGl0ZXJhdGlvbnM7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgICAgICB0aGlzLm5vdGlmeSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpdGVyYXRpb25zOyBpKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoc2xlZXBUaW1lKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgS2VlcEFsaXZlIGNyZWF0ZUtlZXBBbGl2ZShTdHJpbmcgYWxnKSB7CisgICAgICAgIGlmIChhbGcuZXF1YWxzKCJSU0EiKSkgeworICAgICAgICAgICAgLy8gMzIgbWludXRlcworICAgICAgICAgICAgS2VlcEFsaXZlIGtlZXBhbGl2ZSA9IG5ldyBLZWVwQWxpdmUoMjQwMDAwLCA4KTsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoa2VlcGFsaXZlKSB7CisgICAgICAgICAgICAgICAga2VlcGFsaXZlLnN0YXJ0KCk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAga2VlcGFsaXZlLndhaXQoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBrZWVwYWxpdmU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25zdHJ1Y3RvcigpIHsKKyAgICAgICAgS2V5RmFjdG9yeVNwaSBrZnMgPSBuZXcgS2V5RmFjdG9yeVNwaVN0dWIoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEtleUZhY3RvcnlTdHViKG51bGwsIG51bGwsIG51bGwpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIFByb3ZpZGVyW10gcHJvdmlkZXJzID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKCJLZXlGYWN0b3J5LkRTQSIpOworICAgICAgICBpZiAocHJvdmlkZXJzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdmlkZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgS2V5RmFjdG9yeVN0dWIga2YgPSBuZXcgS2V5RmFjdG9yeVN0dWIoa2ZzLCBwcm92aWRlcnNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAiYWxnb3JpdGhtIG5hbWUiKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImFsZ29yaXRobSBuYW1lIiwga2YuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhwcm92aWRlcnNbaV0sIGtmLmdldFByb3ZpZGVyKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmFpbCgiTm8gcHJvdmlkZXJzIHN1cHBvcnQgS2V5RmFjdG9yeS5EU0EiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2VuZXJhdGVQcml2YXRlTGphdmFfc2VjdXJpdHlfc3BlY19LZXlTcGVjKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5CisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuS2V5RmFjdG9yeS5nZW5lcmF0ZVByaXZhdGUoamF2YS5zZWN1cml0eS5zcGVjLktleVNwZWMpCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga2V5ZmFjdEFsZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5RmFjdG9yeSBmYWN0ID0gS2V5RmFjdG9yeS5nZXRJbnN0YW5jZShrZXlmYWN0QWxnc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICAgICAgS2V5UGFpckdlbmVyYXRvciBrZXlHZW4gPSBLZXlQYWlyR2VuZXJhdG9yCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2Uoa2V5ZmFjdEFsZ3NbaV0pOworICAgICAgICAgICAgICAgIFNlY3VyZVJhbmRvbSByYW5kb20gPSBuZXcgU2VjdXJlUmFuZG9tKCk7IC8vIFdlIGRvbid0IHVzZQorICAgICAgICAgICAgICAgIC8vIGdldEluc3RhbmNlCisgICAgICAgICAgICAgICAga2V5R2VuLmluaXRpYWxpemUoU3RhbmRhcmROYW1lcy5nZXRNaW5pbXVtS2V5U2l6ZShrZXlmYWN0QWxnc1tpXSksIHJhbmRvbSk7CisgICAgICAgICAgICAgICAgS2VlcEFsaXZlIGtlZXBhbGl2ZSA9IGNyZWF0ZUtlZXBBbGl2ZShrZXlmYWN0QWxnc1tpXSk7CisgICAgICAgICAgICAgICAgS2V5UGFpciBrZXlzID0ga2V5R2VuLmdlbmVyYXRlS2V5UGFpcigpOworICAgICAgICAgICAgICAgIGlmIChrZWVwYWxpdmUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBrZWVwYWxpdmUuaW50ZXJydXB0KCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgS2V5U3BlYyBwcml2YXRlS2V5U3BlYyA9IGZhY3QuZ2V0S2V5U3BlYyhrZXlzLmdldFByaXZhdGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0YW5kYXJkTmFtZXMuZ2V0UHJpdmF0ZUtleVNwZWNDbGFzcyhrZXlmYWN0QWxnc1tpXSkpOworICAgICAgICAgICAgICAgIFByaXZhdGVLZXkgcHJpdmF0ZUtleSA9IGZhY3QuZ2VuZXJhdGVQcml2YXRlKHByaXZhdGVLZXlTcGVjKTsKKyAgICAgICAgICAgICAgICBib29sZWFuIHNhbWVQcml2YXRlID0gQXJyYXlzLmVxdWFscyhrZXlzLmdldFByaXZhdGUoKQorICAgICAgICAgICAgICAgICAgICAgICAgLmdldEVuY29kZWQoKSwgcHJpdmF0ZUtleS5nZXRFbmNvZGVkKCkpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICAgICAiZ2VuZXJhdGVQcml2YXRlIGdlbmVyYXRlZCBkaWZmZXJlbnQga2V5IGZvciBhbGdvcml0aG0gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGtleWZhY3RBbGdzW2ldLCBzYW1lUHJpdmF0ZSk7CisgICAgICAgICAgICAgICAgZmFjdC5nZW5lcmF0ZVByaXZhdGUobmV3IFBLQ1M4RW5jb2RlZEtleVNwZWMoa2V5cy5nZXRQcml2YXRlKCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRFbmNvZGVkKCkpKTsKKworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleVNwZWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoImludmFsaWQga2V5IHNwZWMgZm9yIGFsZ29yaXRobSAiICsga2V5ZmFjdEFsZ3NbaV0pOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJnZXRJbnN0YW5jZSBkaWQgbm90IGZpbmQgYWxnb3JpdGhtICIgKyBrZXlmYWN0QWxnc1tpXSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiZ2V0SW5zdGFuY2UgZGlkIG5vdCBmaW5kIHByb3ZpZGVyICIgKyBwcm92aWRlck5hbWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZW5lcmF0ZVB1YmxpY0xqYXZhX3NlY3VyaXR5X3NwZWNfS2V5U3BlYygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEuc2VjdXJpdHkuUHVibGljS2V5CisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuS2V5RmFjdG9yeS5nZW5lcmF0ZVB1YmxpYyhqYXZhLnNlY3VyaXR5LnNwZWMuS2V5U3BlYykKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrZXlmYWN0QWxncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBLZXlGYWN0b3J5IGZhY3QgPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKGtleWZhY3RBbGdzW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGtleUdlbiA9IEtleVBhaXJHZW5lcmF0b3IKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZShrZXlmYWN0QWxnc1tpXSk7CisgICAgICAgICAgICAgICAgLy8gV2UgZG9uJ3QgdXNlIGdldEluc3RhbmNlCisgICAgICAgICAgICAgICAgU2VjdXJlUmFuZG9tIHJhbmRvbSA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgICAgICAgICBrZXlHZW4uaW5pdGlhbGl6ZShTdGFuZGFyZE5hbWVzLmdldE1pbmltdW1LZXlTaXplKGtleWZhY3RBbGdzW2ldKSwgcmFuZG9tKTsKKyAgICAgICAgICAgICAgICBLZWVwQWxpdmUga2VlcGFsaXZlID0gY3JlYXRlS2VlcEFsaXZlKGtleWZhY3RBbGdzW2ldKTsKKyAgICAgICAgICAgICAgICBLZXlQYWlyIGtleXMgPSBrZXlHZW4uZ2VuZXJhdGVLZXlQYWlyKCk7CisgICAgICAgICAgICAgICAgaWYgKGtlZXBhbGl2ZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGtlZXBhbGl2ZS5pbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgS2V5U3BlYyBwdWJsaWNLZXlTcGVjID0gZmFjdC5nZXRLZXlTcGVjKGtleXMuZ2V0UHVibGljKCksCisgICAgICAgICAgICAgICAgICAgICAgICBTdGFuZGFyZE5hbWVzLmdldFB1YmxpY0tleVNwZWNDbGFzcyhrZXlmYWN0QWxnc1tpXSkpOworICAgICAgICAgICAgICAgIFB1YmxpY0tleSBwdWJsaWNLZXkgPSBmYWN0LmdlbmVyYXRlUHVibGljKHB1YmxpY0tleVNwZWMpOworICAgICAgICAgICAgICAgIGJvb2xlYW4gc2FtZVB1YmxpYyA9IEFycmF5cy5lcXVhbHMoa2V5cy5nZXRQdWJsaWMoKQorICAgICAgICAgICAgICAgICAgICAgICAgLmdldEVuY29kZWQoKSwgcHVibGljS2V5LmdldEVuY29kZWQoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICJnZW5lcmF0ZVB1YmxpYyBnZW5lcmF0ZWQgZGlmZmVyZW50IGtleSBmb3IgYWxnb3JpdGhtICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBrZXlmYWN0QWxnc1tpXSwgc2FtZVB1YmxpYyk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoImdldEluc3RhbmNlIGRpZCBub3QgZmluZCBhbGdvcml0aG0gIiArIGtleWZhY3RBbGdzW2ldKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJnZXRJbnN0YW5jZSBkaWQgbm90IGZpbmQgcHJvdmlkZXIgIiArIHByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiaW52YWxpZCBrZXkgc3BlYyBmb3IgYWxnb3JpdGhtICIgKyBrZXlmYWN0QWxnc1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEFsZ29yaXRobSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcKKyAgICAgICAgLy8gamF2YS5zZWN1cml0eS5LZXlGYWN0b3J5LmdldEFsZ29yaXRobSgpCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga2V5ZmFjdEFsZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5RmFjdG9yeSBmYWN0ID0gS2V5RmFjdG9yeS5nZXRJbnN0YW5jZShrZXlmYWN0QWxnc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0QWxnb3JpdGhtIG9rIGZvciBhbGdvcml0aG0gIiArIGtleWZhY3RBbGdzW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgZmFjdC5nZXRBbGdvcml0aG0oKS5lcXVhbHMoa2V5ZmFjdEFsZ3NbaV0pKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiZ2V0SW5zdGFuY2UgZGlkIG5vdCBmaW5kIGFsZ29yaXRobSAiICsga2V5ZmFjdEFsZ3NbaV0pOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoImdldEluc3RhbmNlIGRpZCBub3QgZmluZCBwcm92aWRlciAiICsgcHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfS8vIGVuZCBmb3IKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnNlY3VyaXR5LktleUZhY3RvcnkKKyAgICAgICAgLy8gamF2YS5zZWN1cml0eS5LZXlGYWN0b3J5LmdldEluc3RhbmNlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga2V5ZmFjdEFsZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChLZXlGYWN0b3J5LmdldEluc3RhbmNlKGtleWZhY3RBbGdzW2ldKSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoImdldEluc3RhbmNlIGRpZCBub3QgZmluZCBhbGdvcml0aG0gIiArIGtleWZhY3RBbGdzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfS8vIGVuZCBmb3IKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgLy8gVGVzdDE6IFRlc3QgZm9yIG1ldGhvZCBqYXZhLnNlY3VyaXR5LktleUZhY3RvcnkKKyAgICAgICAgLy8gamF2YS5zZWN1cml0eS5LZXlGYWN0b3J5LmdldEluc3RhbmNlKGphdmEubGFuZy5TdHJpbmcsCisgICAgICAgIC8vIGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQcm92aWRlcltdIHByb3ZpZGVycyA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygiS2V5RmFjdG9yeS5EU0EiKTsKKyAgICAgICAgICAgIGlmIChwcm92aWRlcnMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdmlkZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIEtleUZhY3RvcnkuZ2V0SW5zdGFuY2UoIkRTQSIsIHByb3ZpZGVyc1tpXS5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIH0vLyBlbmQgZm9yCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZhaWwoIk5vIHByb3ZpZGVycyBzdXBwb3J0IEtleUZhY3RvcnkuRFNBIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJnZXRJbnN0YW5jZSBkaWQgbm90IGZpbmQgYWxnb3JpdGhtIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoImdldEluc3RhbmNlIGRpZCBub3QgZmluZCB0aGUgcHJvdmlkZXIiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3QyOiBUZXN0IHdpdGggbnVsbCBwcm92aWRlciBuYW1lCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlGYWN0b3J5LmdldEluc3RhbmNlKCJEU0EiLCAoU3RyaW5nKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgZ290ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZ0xqYXZhX3NlY3VyaXR5X1Byb3ZpZGVyKCkgeworICAgICAgICAvLyBUZXN0MTogVGVzdCBmb3IgbWV0aG9kIGphdmEuc2VjdXJpdHkuS2V5RmFjdG9yeQorICAgICAgICAvLyBqYXZhLnNlY3VyaXR5LktleUZhY3RvcnkuZ2V0SW5zdGFuY2UoamF2YS5sYW5nLlN0cmluZywKKyAgICAgICAgLy8gamF2YS5zZWN1cml0eS5Qcm92aWRlcikKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFByb3ZpZGVyW10gcHJvdmlkZXJzID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKCJLZXlGYWN0b3J5LkRTQSIpOworICAgICAgICAgICAgaWYgKHByb3ZpZGVycyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcm92aWRlcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgS2V5RmFjdG9yeS5nZXRJbnN0YW5jZSgiRFNBIiwgcHJvdmlkZXJzW2ldKTsKKyAgICAgICAgICAgICAgICB9Ly8gZW5kIGZvcgorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJObyBwcm92aWRlcnMgc3VwcG9ydCBLZXlGYWN0b3J5LkRTQSIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiZ2V0SW5zdGFuY2UgZGlkIG5vdCBmaW5kIGFsZ29yaXRobSIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3QyOiBUZXN0IHdpdGggbnVsbCBwcm92aWRlciBuYW1lCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlGYWN0b3J5LmdldEluc3RhbmNlKCJEU0EiLCAoUHJvdmlkZXIpIG51bGwpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBnb3QgIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRLZXlTcGVjTGphdmFfc2VjdXJpdHlfS2V5TGphdmFfbGFuZ19DbGFzcygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEuc2VjdXJpdHkuc3BlYy5LZXlTcGVjCisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuS2V5RmFjdG9yeS5nZXRLZXlTcGVjKGphdmEuc2VjdXJpdHkuS2V5LAorICAgICAgICAvLyBqYXZhLmxhbmcuQ2xhc3MpCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga2V5ZmFjdEFsZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5RmFjdG9yeSBmYWN0ID0gS2V5RmFjdG9yeS5nZXRJbnN0YW5jZShrZXlmYWN0QWxnc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICAgICAgS2V5UGFpckdlbmVyYXRvciBrZXlHZW4gPSBLZXlQYWlyR2VuZXJhdG9yCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2Uoa2V5ZmFjdEFsZ3NbaV0pOworCisgICAgICAgICAgICAgICAgLy8gV2UgZG9uJ3QgdXNlIGdldEluc3RhbmNlCisgICAgICAgICAgICAgICAgU2VjdXJlUmFuZG9tIHJhbmRvbSA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgICAgICAgICBrZXlHZW4uaW5pdGlhbGl6ZShTdGFuZGFyZE5hbWVzLmdldE1pbmltdW1LZXlTaXplKGtleWZhY3RBbGdzW2ldKSwgcmFuZG9tKTsKKyAgICAgICAgICAgICAgICBLZWVwQWxpdmUga2VlcGFsaXZlID0gY3JlYXRlS2VlcEFsaXZlKGtleWZhY3RBbGdzW2ldKTsKKyAgICAgICAgICAgICAgICBLZXlQYWlyIGtleXMgPSBrZXlHZW4uZ2VuZXJhdGVLZXlQYWlyKCk7CisgICAgICAgICAgICAgICAgaWYgKGtlZXBhbGl2ZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGtlZXBhbGl2ZS5pbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgS2V5U3BlYyBwcml2YXRlS2V5U3BlYyA9IGZhY3QuZ2V0S2V5U3BlYyhrZXlzLmdldFByaXZhdGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0YW5kYXJkTmFtZXMuZ2V0UHJpdmF0ZUtleVNwZWNDbGFzcyhrZXlmYWN0QWxnc1tpXSkpOworICAgICAgICAgICAgICAgIEtleVNwZWMgcHVibGljS2V5U3BlYyA9IGZhY3QuZ2V0S2V5U3BlYyhrZXlzLmdldFB1YmxpYygpLAorICAgICAgICAgICAgICAgICAgICAgICAgU3RhbmRhcmROYW1lcy5nZXRQdWJsaWNLZXlTcGVjQ2xhc3Moa2V5ZmFjdEFsZ3NbaV0pKTsKKyAgICAgICAgICAgICAgICBQcml2YXRlS2V5IHByaXZhdGVLZXkgPSBmYWN0LmdlbmVyYXRlUHJpdmF0ZShwcml2YXRlS2V5U3BlYyk7CisgICAgICAgICAgICAgICAgUHVibGljS2V5IHB1YmxpY0tleSA9IGZhY3QuZ2VuZXJhdGVQdWJsaWMocHVibGljS2V5U3BlYyk7CisgICAgICAgICAgICAgICAgYm9vbGVhbiBzYW1lUHVibGljID0gQXJyYXlzLmVxdWFscyhrZXlzLmdldFB1YmxpYygpCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RW5jb2RlZCgpLCBwdWJsaWNLZXkuZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgICAgICAgICBib29sZWFuIHNhbWVQcml2YXRlID0gQXJyYXlzLmVxdWFscyhrZXlzLmdldFByaXZhdGUoKQorICAgICAgICAgICAgICAgICAgICAgICAgLmdldEVuY29kZWQoKSwgcHJpdmF0ZUtleS5nZXRFbmNvZGVkKCkpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICAgICAiZ2VuZXJhdGVQcml2YXRlIGdlbmVyYXRlZCBkaWZmZXJlbnQga2V5IGZvciBhbGdvcml0aG0gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGtleWZhY3RBbGdzW2ldLCBzYW1lUHJpdmF0ZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICJnZW5lcmF0ZVB1YmxpYyBnZW5lcmF0ZWQgZGlmZmVyZW50IGtleSBmb3IgYWxnb3JpdGhtICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBrZXlmYWN0QWxnc1tpXSwgc2FtZVB1YmxpYyk7CisgICAgICAgICAgICAgICAgS2V5U3BlYyBlbmNvZGVkU3BlYyA9IGZhY3QuZ2V0S2V5U3BlYyhrZXlzLmdldFB1YmxpYygpLAorICAgICAgICAgICAgICAgICAgICAgICAgWDUwOUVuY29kZWRLZXlTcGVjLmNsYXNzKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJpbXByb3BlciBrZXkgc3BlYyBmb3IgZW5jb2RlZCBwdWJsaWMga2V5IiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGVuY29kZWRTcGVjLmdldENsYXNzKCkuZXF1YWxzKFg1MDlFbmNvZGVkS2V5U3BlYy5jbGFzcykpOworICAgICAgICAgICAgICAgIGVuY29kZWRTcGVjID0gZmFjdC5nZXRLZXlTcGVjKGtleXMuZ2V0UHJpdmF0ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgUEtDUzhFbmNvZGVkS2V5U3BlYy5jbGFzcyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiaW1wcm9wZXIga2V5IHNwZWMgZm9yIGVuY29kZWQgcHJpdmF0ZSBrZXkiLAorICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2RlZFNwZWMuZ2V0Q2xhc3MoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKFBLQ1M4RW5jb2RlZEtleVNwZWMuY2xhc3MpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiZ2V0SW5zdGFuY2UgZGlkIG5vdCBmaW5kIGFsZ29yaXRobSAiICsga2V5ZmFjdEFsZ3NbaV0pOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoImdldEluc3RhbmNlIGRpZCBub3QgZmluZCBwcm92aWRlciAiICsgcHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJpbnZhbGlkIGtleSBzcGVjIGZvciBhbGdvcml0aG0gIiArIGtleWZhY3RBbGdzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UHJvdmlkZXIoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyCisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuS2V5RmFjdG9yeS5nZXRQcm92aWRlcigpCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga2V5ZmFjdEFsZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5RmFjdG9yeSBmYWN0ID0gS2V5RmFjdG9yeS5nZXRJbnN0YW5jZShrZXlmYWN0QWxnc1tpXSk7CisgICAgICAgICAgICAgICAgUHJvdmlkZXIgcCA9IGZhY3QuZ2V0UHJvdmlkZXIoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJwcm92aWRlciBpcyBudWxsIGZvciBhbGdvcml0aG0gIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBrZXlmYWN0QWxnc1tpXSwgcCk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoImdldEluc3RhbmNlIGRpZCBub3QgZmluZCBhbGdvcml0aG0gIiArIGtleWZhY3RBbGdzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfS8vIGVuZCBmb3IKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RyYW5zbGF0ZUtleUxqYXZhX3NlY3VyaXR5X0tleSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEuc2VjdXJpdHkuS2V5CisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuS2V5RmFjdG9yeS50cmFuc2xhdGVLZXkoamF2YS5zZWN1cml0eS5LZXkpCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga2V5ZmFjdEFsZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5RmFjdG9yeSBmYWN0ID0gS2V5RmFjdG9yeS5nZXRJbnN0YW5jZShrZXlmYWN0QWxnc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICAgICAgS2V5UGFpckdlbmVyYXRvciBrZXlHZW4gPSBLZXlQYWlyR2VuZXJhdG9yCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2Uoa2V5ZmFjdEFsZ3NbaV0pOworCisgICAgICAgICAgICAgICAgLy8gV2UgZG9uJ3QgdXNlIGdldEluc3RhbmNlCisgICAgICAgICAgICAgICAgU2VjdXJlUmFuZG9tIHJhbmRvbSA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgICAgICAgICBrZXlHZW4uaW5pdGlhbGl6ZShTdGFuZGFyZE5hbWVzLmdldE1pbmltdW1LZXlTaXplKGtleWZhY3RBbGdzW2ldKSwgcmFuZG9tKTsKKyAgICAgICAgICAgICAgICBLZWVwQWxpdmUga2VlcGFsaXZlID0gY3JlYXRlS2VlcEFsaXZlKGtleWZhY3RBbGdzW2ldKTsKKyAgICAgICAgICAgICAgICBLZXlQYWlyIGtleXMgPSBrZXlHZW4uZ2VuZXJhdGVLZXlQYWlyKCk7CisgICAgICAgICAgICAgICAgaWYgKGtlZXBhbGl2ZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGtlZXBhbGl2ZS5pbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmFjdC50cmFuc2xhdGVLZXkoa2V5cy5nZXRQcml2YXRlKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJnZXRJbnN0YW5jZSBkaWQgbm90IGZpbmQgYWxnb3JpdGhtICIgKyBrZXlmYWN0QWxnc1tpXSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiZ2V0SW5zdGFuY2UgZGlkIG5vdCBmaW5kIHByb3ZpZGVyICIgKyBwcm92aWRlck5hbWUpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiZ2VuZXJhdGVQdWJsaWMgZGlkIG5vdCBnZW5lcmF0ZSByaWdodCBzcGVjIGZvciBhbGdvcml0aG0gIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBrZXlmYWN0QWxnc1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgaWYgKGtleWZhY3RBbGdzID09IG51bGwpIHsKKyAgICAgICAgICAgIFByb3ZpZGVyW10gcHJvdmlkZXJzID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKCk7CisgICAgICAgICAgICAvLyBBcmJpdHJhcmlseSB1c2UgdGhlIGZpcnN0IHByb3ZpZGVyIHRoYXQgc3VwcG9ydHMKKyAgICAgICAgICAgIC8vIEtleUZhY3RvcnkgYWxnb3JpdGhtcworICAgICAgICAgICAgZm9yIChQcm92aWRlciBwcm92aWRlciA6IHByb3ZpZGVycykgeworICAgICAgICAgICAgICAgIHByb3ZpZGVyTmFtZSA9IHByb3ZpZGVyLmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICBrZXlmYWN0QWxncyA9IGdldEtleUZhY3RvcnlBbGdvcml0aG1zKHByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICAgICAgaWYgKGtleWZhY3RBbGdzLmxlbmd0aCAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogUmV0dXJucyB0aGUga2V5IGFsZ29yaXRobXMgdGhhdCB0aGUgZ2l2ZW4gcHJvdmlkZXIgc3VwcG9ydHMuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmdbXSBnZXRLZXlGYWN0b3J5QWxnb3JpdGhtcyhTdHJpbmcgcHJvdmlkZXJOYW1lKSB7CisgICAgICAgIFZlY3RvcjxTdHJpbmc+IGFsZ3MgPSBuZXcgVmVjdG9yPFN0cmluZz4oKTsKKworICAgICAgICBQcm92aWRlciBwcm92aWRlciA9IFNlY3VyaXR5LmdldFByb3ZpZGVyKHByb3ZpZGVyTmFtZSk7CisgICAgICAgIGlmIChwcm92aWRlciA9PSBudWxsKQorICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdbMF07CisgICAgICAgIEVudW1lcmF0aW9uPE9iamVjdD4gZSA9IHByb3ZpZGVyLmtleXMoKTsKKyAgICAgICAgd2hpbGUgKGUuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIFN0cmluZyBhbGdvcml0aG0gPSAoU3RyaW5nKSBlLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICBpZiAoYWxnb3JpdGhtLnN0YXJ0c1dpdGgoS0VZRkFDVE9SWV9JRCkgJiYgIWFsZ29yaXRobS5jb250YWlucygiICIpKSB7CisgICAgICAgICAgICAgICAgYWxncy5hZGRFbGVtZW50KGFsZ29yaXRobS5zdWJzdHJpbmcoS0VZRkFDVE9SWV9JRC5sZW5ndGgoKSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGFsZ3MudG9BcnJheShuZXcgU3RyaW5nW2FsZ3Muc2l6ZSgpXSk7CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIEtleUZhY3RvcnlTdHViIGV4dGVuZHMgS2V5RmFjdG9yeSB7CisgICAgICAgIHB1YmxpYyBLZXlGYWN0b3J5U3R1YihLZXlGYWN0b3J5U3BpIGtleUZhY1NwaSwgUHJvdmlkZXIgcHJvdmlkZXIsCisgICAgICAgICAgICAgICAgU3RyaW5nIGFsZ29yaXRobSkgeworICAgICAgICAgICAgc3VwZXIoa2V5RmFjU3BpLCBwcm92aWRlciwgYWxnb3JpdGhtKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBLZXlGYWN0b3J5U3BpU3R1YiBleHRlbmRzIEtleUZhY3RvcnlTcGkgeworICAgICAgICBwdWJsaWMgS2V5RmFjdG9yeVNwaVN0dWIoKSB7CisgICAgICAgICAgICBzdXBlcigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFByaXZhdGVLZXkgZW5naW5lR2VuZXJhdGVQcml2YXRlKEtleVNwZWMga2V5U3BlYykgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUHVibGljS2V5IGVuZ2luZUdlbmVyYXRlUHVibGljKEtleVNwZWMga2V5U3BlYykgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgPFQgZXh0ZW5kcyBLZXlTcGVjPiBUIGVuZ2luZUdldEtleVNwZWMoS2V5IGtleSwgQ2xhc3M8VD4ga2V5U3BlYykgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgS2V5IGVuZ2luZVRyYW5zbGF0ZUtleShLZXkga2V5KSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlGYWN0b3J5U3BpVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleUZhY3RvcnlTcGlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzlhMzY3ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlGYWN0b3J5U3BpVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleUZhY3RvcnlTcGk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5LZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5LZXlGYWN0b3J5U3BpPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMKKyAqIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIEtleUZhY3RvcnlTcGlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+S2V5RmFjdG9yeVNwaTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgS2V5RmFjdG9yeVNwaQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlGYWN0b3J5U3BpKCkgeworICAgICAgICBNeUtleUZhY3RvcnlTcGkga2V5RlNwaSA9IG5ldyBNeUtleUZhY3RvcnlTcGkoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShrZXlGU3BpIGluc3RhbmNlb2YgS2V5RmFjdG9yeVNwaSk7CisKKyAgICAgICAgS2V5U3BlYyBrcyA9IG5ldyBNeUtleVNwZWMoKTsKKyAgICAgICAgS2V5U3BlYyBrc3MgPSBuZXcgTXlLZXlTcGVjKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlGU3BpLmVuZ2luZUdlbmVyYXRlUHJpdmF0ZShrcyk7CisgICAgICAgICAgICBrZXlGU3BpLmVuZ2luZUdlbmVyYXRlUHVibGljKGtzKTsKKyAgICAgICAgICAgIGtleUZTcGkuZW5naW5lR2V0S2V5U3BlYyhudWxsLCBqYXZhLmxhbmcuQ2xhc3MuY2xhc3MpOworICAgICAgICAgICAga2V5RlNwaS5lbmdpbmVUcmFuc2xhdGVLZXkobnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIE15S2V5RmFjdG9yeVNwaSBleHRlbmRzIEtleUZhY3RvcnlTcGkgeworICAgICAgICBwcm90ZWN0ZWQgUHJpdmF0ZUtleSBlbmdpbmVHZW5lcmF0ZVByaXZhdGUoS2V5U3BlYyBrZXlTcGVjKXsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHByb3RlY3RlZCBQdWJsaWNLZXkgZW5naW5lR2VuZXJhdGVQdWJsaWMoS2V5U3BlYyBrZXlTcGVjKXsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHByb3RlY3RlZCBLZXlTcGVjIGVuZ2luZUdldEtleVNwZWMoS2V5IGtleSwgQ2xhc3Mga2V5U3BlYyl7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBwcm90ZWN0ZWQgS2V5IGVuZ2luZVRyYW5zbGF0ZUtleShLZXkga2V5KXsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgTXlLZXlTcGVjIGltcGxlbWVudHMgS2V5U3BlYyB7fQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleUZhY3RvcnlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5RmFjdG9yeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NTYxN2UxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleUZhY3RvcnlUZXN0LmphdmEKQEAgLTAsMCArMSw2MDQgQEAKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlGYWN0b3J5U3BpOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRFNBUHVibGljS2V5U3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuSW52YWxpZEtleVNwZWNFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLktleVNwZWM7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworcHVibGljIGNsYXNzIEtleUZhY3RvcnlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgUHJvdmlkZXIgcHJvdmlkZXI7CisgICAgYm9vbGVhbiBleGNlcHRpb25UaHJvd247CisKKyAgICBQcm92aWRlciBleGlzdGluZ1Byb3ZpZGVyOworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgZXhjZXB0aW9uVGhyb3duID0gZmFsc2U7CisKKyAgICAgICAgUHJvdmlkZXJbXSBwcm92aWRlcnMgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoKTsKKyAgICAgICAgaWYgKHByb3ZpZGVycy5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgZmFpbCgibm8gcHJvdmlkZXJzIGZvdW5kIik7CisgICAgICAgIH0KKworICAgICAgICBleGlzdGluZ1Byb3ZpZGVyID0gcHJvdmlkZXJzWzBdOworCisgICAgICAgIHByb3ZpZGVyID0gbmV3IFRlc3RLZXlGYWN0b3J5UHJvdmlkZXIoKTsKKyAgICAgICAgU2VjdXJpdHkuYWRkUHJvdmlkZXIocHJvdmlkZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgICAgIFNlY3VyaXR5LnJlbW92ZVByb3ZpZGVyKHByb3ZpZGVyLmdldE5hbWUoKSk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlU3RyaW5nKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5RmFjdG9yeSBmYWN0b3J5ID0gS2V5RmFjdG9yeS5nZXRJbnN0YW5jZShURVNUX0tFWUZBQ1RPUllfTkFNRSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGZhY3RvcnkpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ1tdIHBhcmFtZXRlcnMgPSB7CisgICAgICAgICAgICAgICAgIlVua25vd25LZXlGYWN0b3J5IiwKKyAgICAgICAgICAgICAgICBudWxsCisgICAgICAgIH07CisKKyAgICAgICAgQ2xhc3NbXSBleGNlcHRpb25zID0geworICAgICAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICAgICBOdWxsUG9pbnRlckV4Y2VwdGlvbi5jbGFzcworICAgICAgICB9OworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyYW1ldGVycy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIGFsZ29yaXRobSA9IHBhcmFtZXRlcnNbaV07CisgICAgICAgICAgICBleGNlcHRpb25UaHJvd24gPSBmYWxzZTsKKyAgICAgICAgICAgIFN0cmluZyBtZXNzYWdlID0gImdldEluc3RhbmNlKCIgKyAoYWxnb3JpdGhtID09IG51bGwgPyAibnVsbCIgOiAiXCIiICsgYWxnb3JpdGhtICsgIlwiIikgKyAiKSI7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEtleUZhY3RvcnkuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgY2hlY2tFeGNlcHRpb24obWVzc2FnZSwgZSwgZXhjZXB0aW9uc1tpXSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGNoZWNrRXhjZXB0aW9uKG1lc3NhZ2UsIG51bGwsIGV4Y2VwdGlvbnNbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2VTdHJpbmdTdHJpbmcoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlGYWN0b3J5IGZhY3RvcnkgPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKFRFU1RfS0VZRkFDVE9SWV9OQU1FLCBURVNUX1BST1ZJREVSX05BTUUpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChmYWN0b3J5KTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdbXVtdIGNvbWJpbmF0aW9ucyA9IHsKKyAgICAgICAgICAgICAgICB7ICJVbmtub3duS2V5RmFjdG9yeSIsIFRFU1RfUFJPVklERVJfTkFNRX0sCisgICAgICAgICAgICAgICAgeyBURVNUX0tFWUZBQ1RPUllfTkFNRSwgIlVua25vd25Qcm92aWRlciJ9LAorICAgICAgICAgICAgICAgIHsgVEVTVF9LRVlGQUNUT1JZX05BTUUsIGV4aXN0aW5nUHJvdmlkZXIuZ2V0TmFtZSgpIH0sCisgICAgICAgICAgICAgICAgeyBudWxsLCBURVNUX1BST1ZJREVSX05BTUUgfSwKKyAgICAgICAgICAgICAgICB7IFRFU1RfS0VZRkFDVE9SWV9OQU1FLCBudWxsIH0sCisgICAgICAgICAgICAgICAgeyBudWxsLCBudWxsfQorICAgICAgICB9OworCisgICAgICAgIENsYXNzW10gZXhjZXB0aW9ucyA9IHsKKyAgICAgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgICAgIE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MKKyAgICAgICAgfTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbWJpbmF0aW9ucy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nW10gY29tYmluYXRpb24gPSBjb21iaW5hdGlvbnNbaV07CisgICAgICAgICAgICBTdHJpbmcgbWVzc2FnZSA9ICJnZXRJbnN0YW5jZShcIiIgKyBjb21iaW5hdGlvblswXSArICJcIiwgXCIiICsgY29tYmluYXRpb25bMV0gKyAiXCIpIjsKKyAgICAgICAgICAgIGV4Y2VwdGlvblRocm93biA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBLZXlGYWN0b3J5LmdldEluc3RhbmNlKGNvbWJpbmF0aW9uWzBdLCBjb21iaW5hdGlvblsxXSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGNoZWNrRXhjZXB0aW9uKG1lc3NhZ2UsIGUsIGV4Y2VwdGlvbnNbaV0pOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBjaGVja0V4Y2VwdGlvbihtZXNzYWdlLCBudWxsLCBleGNlcHRpb25zW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZVN0cmluZ1Byb3ZpZGVyKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5RmFjdG9yeSBmYWN0b3J5ID0gS2V5RmFjdG9yeS5nZXRJbnN0YW5jZShURVNUX0tFWUZBQ1RPUllfTkFNRSwgcHJvdmlkZXIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChmYWN0b3J5KTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdbXSBhbGdvcml0aG1zID0geworICAgICAgICAgICAgICAgICJVbmtub3duS2V5RmFjdG9yeSIsCisgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICBURVNUX0tFWUZBQ1RPUllfTkFNRSwKKyAgICAgICAgICAgICAgICBURVNUX0tFWUZBQ1RPUllfTkFNRQorICAgICAgICB9OworCisgICAgICAgIFByb3ZpZGVyW10gcHJvdmlkZXJzID0geworICAgICAgICAgICAgICAgIHByb3ZpZGVyLAorICAgICAgICAgICAgICAgIHByb3ZpZGVyLAorICAgICAgICAgICAgICAgIGV4aXN0aW5nUHJvdmlkZXIsCisgICAgICAgICAgICAgICAgbnVsbAorICAgICAgICB9OworCisgICAgICAgIENsYXNzW10gZXhjZXB0aW9ucyA9IHsKKyAgICAgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAgICAgTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcworICAgICAgICB9OworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxnb3JpdGhtcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIGFsZ29yaXRobSA9IGFsZ29yaXRobXNbaV07CisgICAgICAgICAgICBQcm92aWRlciBwcm92aWRlciA9IHByb3ZpZGVyc1tpXTsKKyAgICAgICAgICAgIFN0cmluZyBtZXNzYWdlID0gImdldEluc3RhbmNlKCIgKworICAgICAgICAgICAgICAgIChhbGdvcml0aG0gPT0gbnVsbCA/ICJudWxsIiA6ICJcIiIgKyBhbGdvcml0aG0gKyAiXCIiKSArCisgICAgICAgICAgICAgICAgIiwgIiArCisgICAgICAgICAgICAgICAgKHByb3ZpZGVyID09IG51bGwgPyAibnVsbCIgOiAicHJvdmlkZXIiKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvblRocm93biA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBLZXlGYWN0b3J5LmdldEluc3RhbmNlKGFsZ29yaXRobSwgcHJvdmlkZXIpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBjaGVja0V4Y2VwdGlvbihtZXNzYWdlLCBlLCBleGNlcHRpb25zW2ldKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgY2hlY2tFeGNlcHRpb24obWVzc2FnZSwgbnVsbCwgZXhjZXB0aW9uc1tpXSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgfQorICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmF0ZVB1YmxpYygpIHsKKyAgICAgICAgS2V5RmFjdG9yeSBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKFRFU1RfS0VZRkFDVE9SWV9OQU1FKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnROb3ROdWxsKGZhY3RvcnkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUZXN0UHVibGljS2V5IGtleSA9IG5ldyBUZXN0UHVibGljS2V5KCk7CisgICAgICAgICAgICBUZXN0UHVibGljS2V5U3BlYyBrZXlTcGVjID0gbmV3IFRlc3RQdWJsaWNLZXlTcGVjKGtleSk7CisgICAgICAgICAgICBQdWJsaWNLZXkgcHVibGljS2V5ID0gZmFjdG9yeS5nZW5lcmF0ZVB1YmxpYyhrZXlTcGVjKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHVibGljS2V5KTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhrZXkuZW5jb2RlZCwgcHVibGljS2V5LmdldEVuY29kZWQoKSkpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgS2V5U3BlY1tdIGtleVNwZWNzID0geworICAgICAgICAgICAgICAgIG5ldyBUZXN0UHJpdmF0ZUtleVNwZWMobmV3IFRlc3RQcml2YXRlS2V5KCkpLAorICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgbmV3IERTQVB1YmxpY0tleVNwZWMobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCkKKyAgICAgICAgfTsKKworICAgICAgICBDbGFzc1tdIGV4Y2VwdGlvbnMgPSB7CisgICAgICAgICAgICAgICAgSW52YWxpZEtleVNwZWNFeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAgICAgTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAgICAgSW52YWxpZEtleVNwZWNFeGNlcHRpb24uY2xhc3MKKyAgICAgICAgfTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGtleVNwZWNzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBLZXlTcGVjIGtleVNwZWMgPSBrZXlTcGVjc1tpXTsKKyAgICAgICAgICAgIFN0cmluZyBtZXNzYWdlID0gImdlbmVyYXRlUHVibGljKCIgKworICAgICAgICAgICAgICAgIChrZXlTcGVjID09IG51bGwgPyAibnVsbCIgOiBrZXlTcGVjLnRvU3RyaW5nKCkpICsgIikiOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFB1YmxpY0tleSBnZW5lcmF0ZVB1YmxpYyA9IGZhY3RvcnkuZ2VuZXJhdGVQdWJsaWMoa2V5U3BlYyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChnZW5lcmF0ZVB1YmxpYyk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGNoZWNrRXhjZXB0aW9uKG1lc3NhZ2UsIGUsIGV4Y2VwdGlvbnNbaV0pOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBjaGVja0V4Y2VwdGlvbihtZXNzYWdlLCBudWxsLCBleGNlcHRpb25zW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmF0ZVByaXZhdGUoKSB7CisgICAgICAgIEtleUZhY3RvcnkgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gS2V5RmFjdG9yeS5nZXRJbnN0YW5jZShURVNUX0tFWUZBQ1RPUllfTkFNRSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChmYWN0b3J5KTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgVGVzdFByaXZhdGVLZXkga2V5ID0gbmV3IFRlc3RQcml2YXRlS2V5KCk7CisgICAgICAgICAgICBUZXN0UHJpdmF0ZUtleVNwZWMga2V5U3BlYyA9IG5ldyBUZXN0UHJpdmF0ZUtleVNwZWMoa2V5KTsKKyAgICAgICAgICAgIFByaXZhdGVLZXkgcHJpdmF0ZUtleSA9IGZhY3RvcnkuZ2VuZXJhdGVQcml2YXRlKGtleVNwZWMpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwcml2YXRlS2V5KTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhrZXkuZ2V0RW5jb2RlZCgpLCBwcml2YXRlS2V5LmdldEVuY29kZWQoKSkpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgS2V5U3BlY1tdIGtleVNwZWNzID0geworICAgICAgICAgICAgICAgIG5ldyBUZXN0UHVibGljS2V5U3BlYyhuZXcgVGVzdFB1YmxpY0tleSgpKSwKKyAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgIG5ldyBEU0FQdWJsaWNLZXlTcGVjKG51bGwsIG51bGwsIG51bGwsIG51bGwpCisgICAgICAgIH07CisKKyAgICAgICAgQ2xhc3NbXSBleGNlcHRpb25zID0geworICAgICAgICAgICAgICAgIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgICAgIE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgICAgIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uLmNsYXNzCisgICAgICAgIH07CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrZXlTcGVjcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgS2V5U3BlYyBrZXlTcGVjID0ga2V5U3BlY3NbaV07CisgICAgICAgICAgICBleGNlcHRpb25UaHJvd24gPSBmYWxzZTsKKyAgICAgICAgICAgIFN0cmluZyBtZXNzYWdlID0gImdlbmVyYXRlUHJpdmF0ZSgiICsKKyAgICAgICAgICAgICAgICAoa2V5U3BlYyA9PSBudWxsID8gIm51bGwiIDoga2V5U3BlYy50b1N0cmluZygpKSArICIpIjsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZmFjdG9yeS5nZW5lcmF0ZVByaXZhdGUoa2V5U3BlYyk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGNoZWNrRXhjZXB0aW9uKG1lc3NhZ2UsIGUsIGV4Y2VwdGlvbnNbaV0pOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBjaGVja0V4Y2VwdGlvbihtZXNzYWdlLCBudWxsLCBleGNlcHRpb25zW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRLZXlTcGVjKCkgeworICAgICAgICBLZXlGYWN0b3J5IGZhY3RvcnkgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IEtleUZhY3RvcnkuZ2V0SW5zdGFuY2UoVEVTVF9LRVlGQUNUT1JZX05BTUUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydE5vdE51bGwoZmFjdG9yeSk7CisKKyAgICAgICAgeworICAgICAgICAgICAgS2V5W10ga2V5cyA9IHsKKyAgICAgICAgICAgICAgICAgICAgbmV3IFRlc3RQcml2YXRlS2V5KCksCisgICAgICAgICAgICAgICAgICAgIG5ldyBUZXN0UHVibGljS2V5KCksCisgICAgICAgICAgICAgICAgICAgIG5ldyBUZXN0UHJpdmF0ZUtleShuZXcgYnl0ZVtdIHsgNDIsIDQxLCA0MCB9KSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IFRlc3RQdWJsaWNLZXkobmV3IGJ5dGVbXSB7IDQwLCA0MSwgNDIgfSkKKyAgICAgICAgICAgIH07CisKKyAgICAgICAgICAgIENsYXNzW10ga2V5U3BlY3MgPSB7CisgICAgICAgICAgICAgICAgICAgIFRlc3RQcml2YXRlS2V5U3BlYy5jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgVGVzdFB1YmxpY0tleVNwZWMuY2xhc3MsCisgICAgICAgICAgICAgICAgICAgIFRlc3RQcml2YXRlS2V5U3BlYy5jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgVGVzdFB1YmxpY0tleVNwZWMuY2xhc3MsCisgICAgICAgICAgICB9OworCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBLZXkga2V5ID0ga2V5c1tpXTsKKyAgICAgICAgICAgICAgICBDbGFzcyBrZXlTcGVjID0ga2V5U3BlY3NbaV07CisgICAgICAgICAgICAgICAgU3RyaW5nIG1lc3NhZ2UgPSAiZ2V0S2V5U3BlYygiICsga2V5LnRvU3RyaW5nKCkgKyAiLCAiICsga2V5U3BlYy50b1N0cmluZygpICsgIikiOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIEtleVNwZWMgc3BlYyA9IGZhY3RvcnkuZ2V0S2V5U3BlYyhrZXksIGtleVNwZWMpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHNwZWMpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKHNwZWMuZ2V0Q2xhc3MoKSA9PSBrZXlTcGVjKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgeworICAgICAgICAgICAgS2V5W10ga2V5cyA9IHsKKyAgICAgICAgICAgICAgICAgICAgbmV3IEFub3RoZXJLZXkoKSwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgbmV3IFRlc3RQcml2YXRlS2V5KCksCisgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICB9OworCisgICAgICAgICAgICBDbGFzc1tdIGtleVNwZWNzID0geworICAgICAgICAgICAgICAgICAgICBLZXlTcGVjLmNsYXNzLAorICAgICAgICAgICAgICAgICAgICBUZXN0UHJpdmF0ZUtleVNwZWMuY2xhc3MsCisgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICB9OworCisgICAgICAgICAgICBDbGFzc1tdIGV4Y2VwdGlvbnMgPSB7CisgICAgICAgICAgICAgICAgICAgIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgICAgICAgICBOdWxsUG9pbnRlckV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgSW52YWxpZEtleVNwZWNFeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAgICAgICAgIE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzCisgICAgICAgICAgICB9OworCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBLZXkga2V5ID0ga2V5c1tpXTsKKyAgICAgICAgICAgICAgICBDbGFzcyBrZXlTcGVjID0ga2V5U3BlY3NbaV07CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uVGhyb3duID0gZmFsc2U7CisgICAgICAgICAgICAgICAgU3RyaW5nIG1lc3NhZ2UgPSAiZ2V0S2V5U3BlYygiICsKKyAgICAgICAgICAgICAgICAgICAgKGtleSA9PSBudWxsID8gIm51bGwiIDoga2V5LnRvU3RyaW5nKCkpICsKKyAgICAgICAgICAgICAgICAgICAgIiwgIiArCisgICAgICAgICAgICAgICAgICAgIChrZXlTcGVjID09IG51bGwgPyAibnVsbCIgOiBrZXlTcGVjLnRvU3RyaW5nKCkpICsgIikiOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGZhY3RvcnkuZ2V0S2V5U3BlYyhrZXksIGtleVNwZWMpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGNoZWNrRXhjZXB0aW9uKG1lc3NhZ2UsIGUsIGV4Y2VwdGlvbnNbaV0pOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIGNoZWNrRXhjZXB0aW9uKG1lc3NhZ2UsIG51bGwsIGV4Y2VwdGlvbnNbaV0pOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdFRyYW5zbGF0ZUtleSgpIHsKKyAgICAgICAgS2V5RmFjdG9yeSBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKFRFU1RfS0VZRkFDVE9SWV9OQU1FKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnROb3ROdWxsKGZhY3RvcnkpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIEtleVtdIGtleXMgPSB7CisgICAgICAgICAgICAgICAgICAgIG5ldyBUZXN0UHJpdmF0ZUtleSgpLAorICAgICAgICAgICAgICAgICAgICBuZXcgVGVzdFB1YmxpY0tleSgpCisgICAgICAgICAgICB9OworCisgICAgICAgICAgICBDbGFzc1tdIHRyYW5zbGF0ZWQgPSB7CisgICAgICAgICAgICAgICAgICAgIFRlc3RQdWJsaWNLZXkuY2xhc3MsCisgICAgICAgICAgICAgICAgICAgIFRlc3RQcml2YXRlS2V5LmNsYXNzCisgICAgICAgICAgICB9OworCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBLZXkga2V5ID0ga2V5c1tpXTsKKyAgICAgICAgICAgICAgICBDbGFzcyB0cmFuc2xhdGUgPSB0cmFuc2xhdGVkW2ldOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIEtleSB0cmFuc2xhdGVLZXkgPSBmYWN0b3J5LnRyYW5zbGF0ZUtleShrZXkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHRyYW5zbGF0ZUtleSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyh0cmFuc2xhdGUsIHRyYW5zbGF0ZUtleS5nZXRDbGFzcygpKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB7CisgICAgICAgICAgICBLZXlbXSBrZXlzID0geworICAgICAgICAgICAgICAgICAgICBuZXcgQW5vdGhlcktleSgpLAorICAgICAgICAgICAgICAgICAgICBudWxsCisgICAgICAgICAgICB9OworCisgICAgICAgICAgICBDbGFzc1tdIGV4Y2VwdGlvbnMgPSB7CisgICAgICAgICAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAgICAgICAgIE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzCisgICAgICAgICAgICB9OworCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBLZXkga2V5ID0ga2V5c1tpXTsKKyAgICAgICAgICAgICAgICBTdHJpbmcgbWVzc2FnZSA9ICJ0cmFuc2xhdGVLZXkoIiArCisgICAgICAgICAgICAgICAgICAgIChrZXkgPT0gbnVsbCA/ICJudWxsIiA6IGtleS50b1N0cmluZygpKSArICIpIjsKKyAgICAgICAgICAgICAgICBleGNlcHRpb25UaHJvd24gPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBmYWN0b3J5LnRyYW5zbGF0ZUtleShrZXkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGNoZWNrRXhjZXB0aW9uKG1lc3NhZ2UsIGUsIGV4Y2VwdGlvbnNbaV0pOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIGNoZWNrRXhjZXB0aW9uKG1lc3NhZ2UsIG51bGwsIGV4Y2VwdGlvbnNbaV0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBURVNUX1BST1ZJREVSX05BTUUgPSAiVGVzdEtleUZhY3RvcnlQcm92aWRlciI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRFU1RfS0VZRkFDVE9SWV9OQU1FID0gIlRlc3RLZXlGYWN0b3J5IjsKKworICAgIHN0YXRpYyBjbGFzcyBUZXN0S2V5RmFjdG9yeVByb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXIgeworCisgICAgICAgIHByb3RlY3RlZCBUZXN0S2V5RmFjdG9yeVByb3ZpZGVyKCkgeworICAgICAgICAgICAgc3VwZXIoVEVTVF9QUk9WSURFUl9OQU1FLCAxLjEsICJUZXN0IEtleUZhY3RvcnkgUHJvdmlkZXIiKTsKKyAgICAgICAgICAgIHB1dCgiS2V5RmFjdG9yeS4iICsgVEVTVF9LRVlGQUNUT1JZX05BTUUsIFRlc3RLZXlGYWN0b3J5U3BpLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFRlc3RLZXlGYWN0b3J5U3BpIGV4dGVuZHMgS2V5RmFjdG9yeVNwaSB7CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBQcml2YXRlS2V5IGVuZ2luZUdlbmVyYXRlUHJpdmF0ZShLZXlTcGVjIGtleVNwZWMpCisgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChUZXN0UHJpdmF0ZUtleVNwZWMuY2xhc3MgPT0ga2V5U3BlYy5nZXRDbGFzcygpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUZXN0UHJpdmF0ZUtleSgoKFRlc3RQcml2YXRlS2V5U3BlYylrZXlTcGVjKS5lbmNvZGVkKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIFB1YmxpY0tleSBlbmdpbmVHZW5lcmF0ZVB1YmxpYyhLZXlTcGVjIGtleVNwZWMpCisgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChUZXN0UHVibGljS2V5U3BlYy5jbGFzcyA9PSBrZXlTcGVjLmdldENsYXNzKCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFRlc3RQdWJsaWNLZXkoKChUZXN0UHVibGljS2V5U3BlYylrZXlTcGVjKS5lbmNvZGVkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCA8VCBleHRlbmRzIEtleVNwZWM+IFQgZW5naW5lR2V0S2V5U3BlYyhLZXkga2V5LAorICAgICAgICAgICAgICAgIENsYXNzPFQ+IGtleVNwZWMpIHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiB7CisKKyAgICAgICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBDb25zdHJ1Y3RvcjxUPiBjb25zdHJ1Y3RvciA9IG51bGw7CisgICAgICAgICAgICBpZiAoVGVzdFByaXZhdGVLZXlTcGVjLmNsYXNzID09IGtleVNwZWMpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciA9IGtleVNwZWMuZ2V0Q29uc3RydWN0b3IoVGVzdFByaXZhdGVLZXkuY2xhc3MpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgaWYgKFRlc3RQdWJsaWNLZXlTcGVjLmNsYXNzID09IGtleVNwZWMpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciA9IGtleVNwZWMuZ2V0Q29uc3RydWN0b3IoVGVzdFB1YmxpY0tleS5jbGFzcyk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleVNwZWNFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGNvbnN0cnVjdG9yID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEtleVNwZWNFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY29uc3RydWN0b3IubmV3SW5zdGFuY2Uoa2V5KTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfSBjYXRjaCAoSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBLZXkgZW5naW5lVHJhbnNsYXRlS2V5KEtleSBrZXkpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChUZXN0UHJpdmF0ZUtleS5jbGFzcyA9PSBrZXkuZ2V0Q2xhc3MoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVGVzdFB1YmxpY0tleSgpOworICAgICAgICAgICAgfSBlbHNlIGlmIChUZXN0UHVibGljS2V5LmNsYXNzID09IGtleS5nZXRDbGFzcygpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUZXN0UHJpdmF0ZUtleSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRLZXlFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFRlc3RQcml2YXRlS2V5U3BlYyBpbXBsZW1lbnRzIEtleVNwZWMgeworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gZW5jb2RlZDsKKworICAgICAgICBwdWJsaWMgVGVzdFByaXZhdGVLZXlTcGVjKFRlc3RQcml2YXRlS2V5IGtleSkgeworICAgICAgICAgICAgdGhpcy5lbmNvZGVkID0ga2V5LmdldEVuY29kZWQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBUZXN0UHVibGljS2V5U3BlYyBpbXBsZW1lbnRzIEtleVNwZWMgeworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gZW5jb2RlZDsKKworICAgICAgICBwdWJsaWMgVGVzdFB1YmxpY0tleVNwZWMoVGVzdFB1YmxpY0tleSBrZXkpIHsKKyAgICAgICAgICAgIHRoaXMuZW5jb2RlZCA9IGtleS5nZXRFbmNvZGVkKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgVGVzdFByaXZhdGVLZXkgaW1wbGVtZW50cyBQcml2YXRlS2V5IHsKKworICAgICAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBlbmNvZGVkOworCisgICAgICAgIHB1YmxpYyBUZXN0UHJpdmF0ZUtleSgpIHsKKyAgICAgICAgICAgIGVuY29kZWQgPSBuZXcgYnl0ZVtdIHszLCA0LCA1fTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBUZXN0UHJpdmF0ZUtleShieXRlW10gZW5jb2RlZCkgeworICAgICAgICAgICAgdGhpcy5lbmNvZGVkID0gZW5jb2RlZDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICAgICAgcmV0dXJuICJUZXN0UHJpdmF0ZUtleSI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gZW5jb2RlZDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgcmV0dXJuICJUZXN0Rm9ybWF0IjsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBUZXN0UHVibGljS2V5IGltcGxlbWVudHMgUHVibGljS2V5IHsKKworICAgICAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBlbmNvZGVkOworCisgICAgICAgIHB1YmxpYyBUZXN0UHVibGljS2V5KCkgeworICAgICAgICAgICAgZW5jb2RlZCA9IG5ldyBieXRlW10gezMsIDQsIDV9OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFRlc3RQdWJsaWNLZXkoYnl0ZVtdIGVuY29kZWQpIHsKKyAgICAgICAgICAgIHRoaXMuZW5jb2RlZCA9IGVuY29kZWQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgIHJldHVybiAiVGVzdFB1YmxpY0tleSI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gZW5jb2RlZDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgcmV0dXJuICJUZXN0Rm9ybWF0IjsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBBbm90aGVyS2V5IGltcGxlbWVudHMgS2V5IHsKKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgIHJldHVybiAiQW5vdGhlcktleSI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgcmV0dXJuICJBbm90aGVyRm9ybWF0IjsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBFeGNlcHRpb24gdGhyb3duLCBDbGFzczw/IGV4dGVuZHMgRXhjZXB0aW9uPiBleHBlY3RlZCkgeworICAgICAgICBpZiAodGhyb3duID09IG51bGwpIHsKKyAgICAgICAgICAgIGlmICghZXhjZXB0aW9uVGhyb3duKSB7CisgICAgICAgICAgICAgICAgZmFpbChtZXNzYWdlICsgIiwgZXhwZWN0ZWQgIiArIGV4cGVjdGVkLmdldE5hbWUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAoZXhwZWN0ZWQgPT0gdGhyb3duLmdldENsYXNzKCkpIHsKKyAgICAgICAgICAgIGV4Y2VwdGlvblRocm93biA9IHRydWU7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZXhjZXB0aW9uVGhyb3duID0gdHJ1ZTsKKyAgICAgICAgICAgIGZhaWwobWVzc2FnZSArICIsIHVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgdGhyb3duICsgIiwgZXhwZWN0ZWQ6ICIgKyBleHBlY3RlZC5nZXROYW1lKCkpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5TWFuYWdlbWVudEV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlNYW5hZ2VtZW50RXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZiODEwNjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5TWFuYWdlbWVudEV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDE3OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlNYW5hZ2VtZW50RXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5LZXlNYW5hZ2VtZW50RXhjZXB0aW9uPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kCisgKiBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIEtleU1hbmFnZW1lbnRFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gbXNncyA9IHsKKyAgICAgICAgICAgICIiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSIgfTsKKworICAgIHByaXZhdGUgc3RhdGljIFRocm93YWJsZSB0Q2F1c2UgPSBuZXcgVGhyb3dhYmxlKCJUaHJvd2FibGUgZm9yIGV4Y2VwdGlvbiIpOworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+S2V5TWFuYWdlbWVudEV4Y2VwdGlvbigpPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246CisgICAgICogY29uc3RydWN0cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5TWFuYWdlbWVudEV4Y2VwdGlvbjAxKCkgeworICAgICAgICBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHRFID0gbmV3IEtleU1hbmFnZW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+S2V5TWFuYWdlbWVudEV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHdpdGggZGV0YWlsIG1lc3NhZ2UgbXNnLgorICAgICAqIFBhcmFtZXRlciA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlNYW5hZ2VtZW50RXhjZXB0aW9uMDIoKSB7CisgICAgICAgIEtleU1hbmFnZW1lbnRFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbihtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPktleU1hbmFnZW1lbnRFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiB3aGVuIDxjb2RlPm1zZzwvY29kZT4gaXMKKyAgICAgKiBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEtleU1hbmFnZW1lbnRFeGNlcHRpb24wMygpIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9IG51bGw7CisgICAgICAgIEtleU1hbmFnZW1lbnRFeGNlcHRpb24gdEUgPSBuZXcgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbihtc2cpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5LZXlNYW5hZ2VtZW50RXhjZXB0aW9uKFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMKKyAgICAgKiBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEtleU1hbmFnZW1lbnRFeGNlcHRpb24wNCgpIHsKKyAgICAgICAgVGhyb3dhYmxlIGNhdXNlID0gbnVsbDsKKyAgICAgICAgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiB0RSA9IG5ldyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uKGNhdXNlKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+S2V5TWFuYWdlbWVudEV4Y2VwdGlvbihUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzCisgICAgICogbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5TWFuYWdlbWVudEV4Y2VwdGlvbjA1KCkgeworICAgICAgICBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHRFID0gbmV3IEtleU1hbmFnZW1lbnRFeGNlcHRpb24odENhdXNlKTsKKyAgICAgICAgaWYgKHRFLmdldE1lc3NhZ2UoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBzaG91bGQgY29udGFpbiAiLmNvbmNhdCh0b1MpLCAoZ2V0TQorICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgIC5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPktleU1hbmFnZW1lbnRFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHdoZW4KKyAgICAgKiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5TWFuYWdlbWVudEV4Y2VwdGlvbjA2KCkgeworICAgICAgICBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHRFID0gbmV3IEtleU1hbmFnZW1lbnRFeGNlcHRpb24obnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+S2V5TWFuYWdlbWVudEV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5TWFuYWdlbWVudEV4Y2VwdGlvbjA3KCkgeworICAgICAgICBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IEtleU1hbmFnZW1lbnRFeGNlcHRpb24obXNnc1tpXSwgbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5LZXlNYW5hZ2VtZW50RXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdCBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlNYW5hZ2VtZW50RXhjZXB0aW9uMDgoKSB7CisgICAgICAgIEtleU1hbmFnZW1lbnRFeGNlcHRpb24gdEUgPSBuZXcgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbihudWxsLCB0Q2F1c2UpOworICAgICAgICBpZiAodEUuZ2V0TWVzc2FnZSgpICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIFN0cmluZyBnZXRNID0gdEUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIG11c3Qgc2hvdWxkICIuY29uY2F0KHRvUyksIChnZXRNCisgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKHRvUykgIT0gLTEpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiAiLmNvbmNhdCh0Q2F1c2UudG9TdHJpbmcoKSksIHRFCisgICAgICAgICAgICAgICAgLmdldENhdXNlKCksIHRDYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+S2V5TWFuYWdlbWVudEV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QgbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEtleU1hbmFnZW1lbnRFeGNlcHRpb24wOSgpIHsKKyAgICAgICAgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uKG1zZ3NbaV0sIHRDYXVzZSk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGlmIChtc2dzW2ldLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IGNvbnRhaW4gIi5jb25jYXQobXNnc1tpXSksIGdldE0KKyAgICAgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKG1zZ3NbaV0pICE9IC0xKTsKKyAgICAgICAgICAgICAgICBpZiAoIWdldE0uZXF1YWxzKG1zZ3NbaV0pKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBzaG91bGQgY29udGFpbiAiLmNvbmNhdCh0b1MpLCBnZXRNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwKKyAgICAgICAgICAgICAgICAgICAgdEUuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlQYWlyR2VuZXJhdG9yMVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlQYWlyR2VuZXJhdG9yMVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNzA2NjIzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVBhaXJHZW5lcmF0b3IxVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTAxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXJHZW5lcmF0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuTXlLZXlQYWlyR2VuZXJhdG9yMTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5NeUtleVBhaXJHZW5lcmF0b3IyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlNwaUVuZ1V0aWxzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5LZXlQYWlyR2VuZXJhdG9yPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgS2V5UGFpckdlbmVyYXRvcjFUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gaW52YWxpZFZhbHVlcyA9IFNwaUVuZ1V0aWxzLmludmFsaWRWYWx1ZXM7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBzcnZLZXlQYWlyR2VuZXJhdG9yID0gIktleVBhaXJHZW5lcmF0b3IiOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmdbXSBhbGdzID0geworICAgICAgICAgICAgIkRTQSIsICJkc2EiLCAiRHNhIiwgIkRzQSIsICJkc0EiIH07CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB2YWxpZEFsZ05hbWUgPSAiRFNBIjsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB2YWxpZFByb3ZpZGVyTmFtZSA9IG51bGw7CisKKyAgICBwdWJsaWMgc3RhdGljIFByb3ZpZGVyIHZhbGlkUHJvdmlkZXIgPSBudWxsOworCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBEU0FTdXBwb3J0ZWQgPSBmYWxzZTsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIE5vdFN1cHBvcnRNc2cgPSAiIjsKKworICAgIHN0YXRpYyB7CisgICAgICAgIHZhbGlkUHJvdmlkZXIgPSBTcGlFbmdVdGlscy5pc1N1cHBvcnQoCisgICAgICAgICAgICAgICAgdmFsaWRBbGdOYW1lLAorICAgICAgICAgICAgICAgIHNydktleVBhaXJHZW5lcmF0b3IpOworICAgICAgICBEU0FTdXBwb3J0ZWQgPSAodmFsaWRQcm92aWRlciAhPSBudWxsKTsKKyAgICAgICAgaWYgKCFEU0FTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIE5vdFN1cHBvcnRNc2cgPSB2YWxpZEFsZ05hbWUgKyAiIGFsZ29yaXRobSBpcyBub3Qgc3VwcG9ydGVkIiA7CisgICAgICAgIH0KKyAgICAgICAgdmFsaWRQcm92aWRlck5hbWUgPSAoRFNBU3VwcG9ydGVkID8gdmFsaWRQcm92aWRlci5nZXROYW1lKCkgOiBudWxsKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgS2V5UGFpckdlbmVyYXRvciBbXSBjcmVhdGVLUEdlbigpIHsKKyAgICAgICAgaWYgKCFEU0FTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBLZXlQYWlyR2VuZXJhdG9yW10ga3BnID0gbmV3IEtleVBhaXJHZW5lcmF0b3JbM107CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrcGdbMF0gPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKHZhbGlkQWxnTmFtZSk7CisgICAgICAgICAgICBrcGdbMV0gPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKHZhbGlkQWxnTmFtZSwgdmFsaWRQcm92aWRlcik7CisgICAgICAgICAgICBrcGdbMl0gPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKHZhbGlkQWxnTmFtZSwgdmFsaWRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgcmV0dXJuIGtwZzsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICB3aGVuIGFsZ29yaXRobSBpcyBudWxsCisgICAgICogdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBpbmNvcnJlY3Q7CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEtleVBhaXJHZW5lcmF0b3IwMSgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAgd2hlbiBhbGdvcml0aG0gaXMgbnVsbCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGU6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgS2V5UGFpckdlbmVyYXRvciBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5UGFpckdlbmVyYXRvcjAyKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghRFNBU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIEtleVBhaXJHZW5lcmF0b3Iga3BnOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGtwZyA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoYWxnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0gIiwga3BnLmdldEFsZ29yaXRobSgpLnRvVXBwZXJDYXNlKCksCisgICAgICAgICAgICAgICAgICAgIGFsZ3NbaV0udG9VcHBlckNhc2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aGVuIHByb3ZpZGVyIGlzIG51bGwgb3IgZW1wdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5UGFpckdlbmVyYXRvcjAzKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFEU0FTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHByb3ZpZGVyID0gbnVsbDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoYWxnc1tpXSwgcHJvdmlkZXIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHByb3ZpZGVyIGlzIG51bGwiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoYWxnc1tpXSwgIiIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHByb3ZpZGVyIGlzIGVtcHR5Iik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbm90IGF2YWlsYWJsZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlQYWlyR2VuZXJhdG9yMDQoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFEU0FTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMTsgaiA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKGFsZ3NbaV0sIGludmFsaWRWYWx1ZXNbal0pOworICAgICAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChhbGdzW2ldKS5jb25jYXQoIiBwcm92aWRlcjogIikuY29uY2F0KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW52YWxpZFZhbHVlc1tqXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBub3QKKyAgICAgKiBhdmFpbGFibGUKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIGluY29ycmVjdDsKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5UGFpckdlbmVyYXRvcjA1KCkgdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFEU0FTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UobnVsbCwgdmFsaWRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duICB3aGVuIGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGFsZ3NbaV0pLmNvbmNhdCgiIHByb3ZpZGVyOiAiKS5jb25jYXQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkUHJvdmlkZXJOYW1lKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgS2V5UGFpckdlbmVyYXRvciBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5UGFpckdlbmVyYXRvcjA2KCkgdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBpZiAoIURTQVN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGtwZzsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBrcGcgPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKGFsZ3NbaV0sIHZhbGlkUHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGtwZy5nZXRBbGdvcml0aG0oKS50b1VwcGVyQ2FzZSgpLAorICAgICAgICAgICAgICAgICAgICBhbGdzW2ldLnRvVXBwZXJDYXNlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBrcGcuZ2V0UHJvdmlkZXIoKS5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgIHZhbGlkUHJvdmlkZXJOYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEtleVBhaXJHZW5lcmF0b3IwNygpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoIURTQVN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBwcm92aWRlciA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKGFsZ3NbaV0sIHByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBudWxsIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgUHJvdmlkZXIgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIGluY29ycmVjdDsKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5UGFpckdlbmVyYXRvcjA4KCkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghRFNBU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKG51bGwsIHZhbGlkUHJvdmlkZXIpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duICB3aGVuIGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldLCB2YWxpZFByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gKGFsZ29yaXRobTogIgorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChhbGdzW2ldKS5jb25jYXQoIiBwcm92aWRlcjogIikuY29uY2F0KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZFByb3ZpZGVyTmFtZSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgS2V5UGFpckdlbmVyYXRvciBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5UGFpckdlbmVyYXRvcjA5KCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghRFNBU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIEtleVBhaXJHZW5lcmF0b3Iga3BnOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGtwZyA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoYWxnc1tpXSwgdmFsaWRQcm92aWRlcik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBrcGcuZ2V0QWxnb3JpdGhtKCkudG9VcHBlckNhc2UoKSwKKyAgICAgICAgICAgICAgICAgICAgYWxnc1tpXS50b1VwcGVyQ2FzZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwga3BnLmdldFByb3ZpZGVyKCksIHZhbGlkUHJvdmlkZXIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2VuZXJhdGVLZXlQYWlyKCk8L2NvZGU+IGFuZCA8Y29kZT5nZW5LZXlQYWlyKCk8L2NvZGU+CisgICAgICogbWV0aG9kcworICAgICAqIEFzc2VydGlvbjogS2V5UGFpckdlbmVyYXRvciB3YXMgaW5pdGlhbGl6ZWQgYmVmb3JlIHRoZSBpbnZvY2F0aW9uCisgICAgICogb2YgdGhlc2UgbWV0aG9kcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlQYWlyR2VuZXJhdG9yMTAoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoIURTQVN1cHBvcnRlZCkgeworICAgICAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgS2V5UGFpckdlbmVyYXRvcltdIGtwZyA9IGNyZWF0ZUtQR2VuKCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJLZXlQYWlyR2VuZXJhdG9yIG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIGtwZyk7CisgICAgICAgICAgICBLZXlQYWlyIGtwLCBrcDE7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGtwZy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGtwZ1tpXS5pbml0aWFsaXplKDUxMik7CisgICAgICAgICAgICAgICAga3AgPSBrcGdbaV0uZ2VuZXJhdGVLZXlQYWlyKCk7CisgICAgICAgICAgICAgICAga3AxID0ga3BnW2ldLmdlbktleVBhaXIoKTsKKworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKCJJbmNvcnJlY3QgcHJpdmF0ZSBrZXkiLCBrcC5nZXRQcml2YXRlKCkuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAga3AxLmdldFByaXZhdGUoKSkpOworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKCJJbmNvcnJlY3QgcHVibGljIGtleSIsIGtwLmdldFB1YmxpYygpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgIGtwMS5nZXRQdWJsaWMoKSkpOworICAgICAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIG1ldGhvZHM6CisgICAgICogPGNvZGU+aW5pdGlhbGl6ZShpbnQga2V5c2l6ZSk8L2NvZGU+CisgICAgICogPGNvZGU+aW5pdGlhbGl6ZShpbnQga2V5c2l6ZSwgU2VjdXJlUmFuZG9tIHJhbmRvbSk8L2NvZGU+CisgICAgICogPGNvZGU+aW5pdGlhbGl6ZShBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtKTwvY29kZT4KKyAgICAgKiA8Y29kZT5pbml0aWFsaXplKEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW0sIFNlY3VyZVJhbmRvbSByYW5kb20pPC9jb2RlPgorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gb3IKKyAgICAgKiBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHdoZW4gcGFyYW1ldGVycyBrZXlzaXplIG9yIHBhcmFtIGFyZQorICAgICAqIGluY29ycmVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlQYWlyR2VuZXJhdG9yMTEoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAoIURTQVN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpbnRbXSBrZXlzID0gIHsgLTEwMDAwLCAtMTAyNCwgLTEsIDAsIDEwMDAwIH07CisgICAgICAgIEtleVBhaXJHZW5lcmF0b3JbXSBrcGcgPSBjcmVhdGVLUEdlbigpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJLZXlQYWlyR2VuZXJhdG9yIG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIGtwZyk7CisgICAgICAgIFNlY3VyZVJhbmRvbSByYW5kb20gPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgYXBzID0gbnVsbDsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGtwZy5sZW5ndGg7IGkrKykgeworCisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGtleXMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBrcGdbaV0uaW5pdGlhbGl6ZShrZXlzW2pdKTsKKyAgICAgICAgICAgICAgICAgICAga3BnW2ldLmluaXRpYWxpemUoa2V5c1tqXSwgcmFuZG9tKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga3BnW2ldLmluaXRpYWxpemUoYXBzKTsKKyAgICAgICAgICAgICAgICBrcGdbaV0uaW5pdGlhbGl6ZShhcHMsIHJhbmRvbSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIG1ldGhvZHM6IDxjb2RlPmluaXRpYWxpemUoaW50IGtleXNpemUpPC9jb2RlPgorICAgICAqIDxjb2RlPmluaXRpYWxpemUoaW50IGtleXNpemUsIFNlY3VyZVJhbmRvbSByYW5kb20pPC9jb2RlPgorICAgICAqIDxjb2RlPmluaXRpYWxpemUoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbSk8L2NvZGU+CisgICAgICogPGNvZGU+aW5pdGlhbGl6ZShBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtLCBTZWN1cmVSYW5kb20gcmFuZG9tKTwvY29kZT4KKyAgICAgKiA8Y29kZT5nZW5lcmF0ZUtleVBhaXIoKTwvY29kZT4KKyAgICAgKiA8Y29kZT5nZW5LZXlQYWlyKCk8L2NvZGU+CisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBvcgorICAgICAqIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gd2hlbiBwYXJhbWV0ZXJzIGtleXNpemUgb3IgcGFyYW0gYXJlCisgICAgICogaW5jb3JyZWN0IEFzc2VydGlvbjogZ2VuZXJhdGVLZXlQYWlyKCkgYW5kIGdlbktleVBhaXIoKSByZXR1cm4gbnVsbAorICAgICAqIEtleVBhaXIgQWRkaXRpb25hbCBjbGFzcyBNeUtleVBhaXJHZW5lcmF0b3IxIGlzIHVzZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5UGFpckdlbmVyYXRvcjEyKCkgeworICAgICAgICBpbnRbXSBrZXlzID0geyAtMSwgLTI1MCwgMSwgNjQsIDUxMiwgMTAyNCB9OworICAgICAgICBTZWN1cmVSYW5kb20gcmFuZG9tID0gbmV3IFNlY3VyZVJhbmRvbSgpOworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIGFwczsKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvciBtS1BHID0gbmV3IE15S2V5UGFpckdlbmVyYXRvcjEoIiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBtS1BHLmdldEFsZ29yaXRobSgpLAorICAgICAgICAgICAgICAgIE15S2V5UGFpckdlbmVyYXRvcjEuZ2V0UmVzQWxnb3JpdGhtKCkpOworCisgICAgICAgIG1LUEcuZ2VuZXJhdGVLZXlQYWlyKCk7CisgICAgICAgIG1LUEcuZ2VuS2V5UGFpcigpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBtS1BHLmluaXRpYWxpemUoa2V5c1tpXSk7CisgICAgICAgICAgICAgICAgZmFpbCgiSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAoa2V5OiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIEludGVnZXIudG9TdHJpbmcoa2V5c1tpXSkgKyAiKSIpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG1LUEcuaW5pdGlhbGl6ZShrZXlzW2ldLCByYW5kb20pOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gKGtleTogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBJbnRlZ2VyLnRvU3RyaW5nKGtleXNbaV0pICsgIikiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtS1BHLmluaXRpYWxpemUoMTAwLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiByYW5kb20gaXMgbnVsbCIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIG1LUEcuaW5pdGlhbGl6ZSgxMDAsIHJhbmRvbSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHJhbmRvbSIsIHJhbmRvbSwKKyAgICAgICAgICAgICAgICAoKE15S2V5UGFpckdlbmVyYXRvcjEpIG1LUEcpLnNlY3VyZVJhbmRvbSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGtleXNpemUiLCAxMDAsCisgICAgICAgICAgICAgICAgKChNeUtleVBhaXJHZW5lcmF0b3IxKSBtS1BHKS5rZXlTaXplKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1LUEcuaW5pdGlhbGl6ZShudWxsLCByYW5kb20pOworICAgICAgICAgICAgZmFpbCgiSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHBhcmFtIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgaWYgKERTQVN1cHBvcnRlZCkgeworICAgICAgICAgICAgQmlnSW50ZWdlciBiSW50ID0gbmV3IEJpZ0ludGVnZXIoIjEiKTsKKyAgICAgICAgICAgIGFwcyA9IG5ldyBqYXZhLnNlY3VyaXR5LnNwZWMuRFNBUGFyYW1ldGVyU3BlYyhiSW50LCBiSW50LCBiSW50KTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbUtQRy5pbml0aWFsaXplKGFwcywgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHJhbmRvbSBpcyBudWxsIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG1LUEcuaW5pdGlhbGl6ZShhcHMsIHJhbmRvbSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcmFuZG9tIiwgcmFuZG9tLAorICAgICAgICAgICAgICAgICAgICAgICAgKChNeUtleVBhaXJHZW5lcmF0b3IxKSBtS1BHKS5zZWN1cmVSYW5kb20pOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHBhcmFtcyIsIGFwcywKKyAgICAgICAgICAgICAgICAgICAgICAgICgoTXlLZXlQYWlyR2VuZXJhdG9yMSkgbUtQRykucGFyYW1TcGVjKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciBtZXRob2RzOiA8Y29kZT5pbml0aWFsaXplKGludCBrZXlzaXplKTwvY29kZT4KKyAgICAgKiA8Y29kZT5pbml0aWFsaXplKGludCBrZXlzaXplLCBTZWN1cmVSYW5kb20gcmFuZG9tKTwvY29kZT4KKyAgICAgKiA8Y29kZT5pbml0aWFsaXplKEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW0pPC9jb2RlPgorICAgICAqIDxjb2RlPmluaXRpYWxpemUoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbSwgU2VjdXJlUmFuZG9tIHJhbmRvbSk8L2NvZGU+CisgICAgICogPGNvZGU+Z2VuZXJhdGVLZXlQYWlyKCk8L2NvZGU+CisgICAgICogPGNvZGU+Z2VuS2V5UGFpcigpPC9jb2RlPgorICAgICAqIEFzc2VydGlvbjogaW5pdGlhbGl6ZShpbnQgLi4uKSB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiB3aGVuCisgICAgICoga2V5c2l6ZSBpbiBpbmNvcnJlY3QgQXNzZXJ0aW9uOiBpbml0aWFsaXplKEFsZ29yaXRobVBhcmFtZXRlclNwZWMKKyAgICAgKiAuLi4pdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIEFzc2VydGlvbjogZ2VuZXJhdGVLZXlQYWlyKCkgYW5kCisgICAgICogZ2VuS2V5UGFpcigpIHJldHVybiBub3QgbnVsbCBLZXlQYWlyIEFkZGl0aW9uYWwgY2xhc3MgTXlLZXlQYWlyR2VuZXJhdG9yMgorICAgICAqIGlzIHVzZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5UGFpckdlbmVyYXRvcjEzKCkgeworICAgICAgICBpbnRbXSBrZXlzID0geyAtMSwgLTI1MCwgMSwgNjMsIC01MTIsIC0xMDI0IH07CisgICAgICAgIFNlY3VyZVJhbmRvbSByYW5kb20gPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIEtleVBhaXJHZW5lcmF0b3IgbUtQRyA9IG5ldyBNeUtleVBhaXJHZW5lcmF0b3IyKG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFsZ29yaXRobSBtdXN0IGJlIG51bGwiLCBtS1BHLmdldEFsZ29yaXRobSgpLAorICAgICAgICAgICAgICAgIE15S2V5UGFpckdlbmVyYXRvcjIuZ2V0UmVzQWxnb3JpdGhtKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZW5LZXlQYWlyKCkgbXVzdCByZXR1cm4gbnVsbCIsIG1LUEcuZ2VuS2V5UGFpcigpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2VuZXJhdGVLZXlQYWlyKCkgbXV0IHJldHVybiBudWxsIiwgbUtQRy5nZW5lcmF0ZUtleVBhaXIoKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBtS1BHLmluaXRpYWxpemUoa2V5c1tpXSk7CisgICAgICAgICAgICAgICAgZmFpbCgiSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAoa2V5OiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIEludGVnZXIudG9TdHJpbmcoa2V5c1tpXSkgKyAiKSIpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG1LUEcuaW5pdGlhbGl6ZShrZXlzW2ldLCByYW5kb20pOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gKGtleTogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBJbnRlZ2VyLnRvU3RyaW5nKGtleXNbaV0pICsgIikiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtS1BHLmluaXRpYWxpemUoNjQpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1LUEcuaW5pdGlhbGl6ZSg2NCwgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIHdhcyB0aHJvd24iKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbUtQRy5pbml0aWFsaXplKG51bGwsIHJhbmRvbSk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9uIGoyc2UxLjQgdGhpcyBleGNlcHRpb24gaXMgbm90IHRocm93bgorICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5UGFpckdlbmVyYXRvcjJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5UGFpckdlbmVyYXRvcjJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWM4OGEwOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlQYWlyR2VuZXJhdG9yMlRlc3QuamF2YQpAQCAtMCwwICsxLDQzMCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXJHZW5lcmF0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5NeUtleVBhaXJHZW5lcmF0b3IxOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0Lk15S2V5UGFpckdlbmVyYXRvcjI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuU3BpRW5nVXRpbHM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPktleVBhaXJHZW5lcmF0b3I8L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBLZXlQYWlyR2VuZXJhdG9yMlRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHJpdmF0ZSBTdHJpbmcgS2V5UGFpckdlbmVyYXRvclByb3ZpZGVyQ2xhc3MgPSAiIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBLZXlQYWlyR2VuZXJhdG9yUHJvdmlkZXJDbGFzczEgPSAib3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuTXlLZXlQYWlyR2VuZXJhdG9yMSI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEtleVBhaXJHZW5lcmF0b3JQcm92aWRlckNsYXNzMiA9ICJvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5NeUtleVBhaXJHZW5lcmF0b3IyIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgS2V5UGFpckdlbmVyYXRvclByb3ZpZGVyQ2xhc3MzID0gIm9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0Lk15S2V5UGFpckdlbmVyYXRvcjMiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBLZXlQYWlyR2VuZXJhdG9yUHJvdmlkZXJDbGFzczQgPSAib3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuTXlLZXlQYWlyR2VuZXJhdG9yU3BpIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBkZWZhdWx0QWxnID0gIktQR2VuIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGludmFsaWRWYWx1ZXMgPSBTcGlFbmdVdGlscy5pbnZhbGlkVmFsdWVzOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gdmFsaWRWYWx1ZXM7CisKKyAgICBTdHJpbmcgcG9zdDsKKworICAgIHN0YXRpYyB7CisgICAgICAgIHZhbGlkVmFsdWVzID0gbmV3IFN0cmluZ1s0XTsKKyAgICAgICAgdmFsaWRWYWx1ZXNbMF0gPSBkZWZhdWx0QWxnOworICAgICAgICB2YWxpZFZhbHVlc1sxXSA9IGRlZmF1bHRBbGcudG9Mb3dlckNhc2UoKTsKKyAgICAgICAgdmFsaWRWYWx1ZXNbMl0gPSAia3BHRU4iOworICAgICAgICB2YWxpZFZhbHVlc1szXSA9ICJrUEdFbiI7CisgICAgfQorCisgICAgUHJvdmlkZXIgbVByb3Y7CisgICAgU3RyaW5nIHJlc0FsZzsKKworICAgIC8qCisgICAgICogQHNlZSBUZXN0Q2FzZSN0ZWFyRG93bigpCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICAgICAgU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIobVByb3YuZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRQcm92KCkgeworICAgICAgICBtUHJvdiA9IChuZXcgU3BpRW5nVXRpbHMoKSkubmV3IE15UHJvdmlkZXIoIk15S1BHZW5Qcm92aWRlciIuY29uY2F0KHBvc3QpLAorICAgICAgICAgICAgICAgICJUZXN0aW5nIHByb3ZpZGVyIiwgS2V5UGFpckdlbmVyYXRvcjFUZXN0LnNydktleVBhaXJHZW5lcmF0b3IuY29uY2F0KCIuIikKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoZGVmYXVsdEFsZy5jb25jYXQocG9zdCkpLAorICAgICAgICAgICAgICAgIEtleVBhaXJHZW5lcmF0b3JQcm92aWRlckNsYXNzKTsKKyAgICAgICAgU2VjdXJpdHkuaW5zZXJ0UHJvdmlkZXJBdChtUHJvdiwgMSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrUmVzdWx0KEtleVBhaXJHZW5lcmF0b3Iga2V5UGFpckdlbiwgaW50IG1vZGUpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcHAgPSBudWxsOworICAgICAgICBzd2l0Y2ggKG1vZGUpIHsKKyAgICAgICAgY2FzZSAxOgorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlQYWlyR2VuLmluaXRpYWxpemUocHAsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBrZXlQYWlyR2VuLmluaXRpYWxpemUoMTAwMCwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5UGFpckdlbi5pbml0aWFsaXplKC0xMDI0LCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGV4Y2VwdGlvbiIsIGUuZ2V0TWVzc2FnZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgIkluY29ycmVjdCBrZXlzaXplIHBhcmFtZXRlciIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlQYWlyR2VuLmluaXRpYWxpemUoMTAwLCBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBleGNlcHRpb24iLCBlLmdldE1lc3NhZ2UoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICJJbmNvcnJlY3QgcmFuZG9tIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBrZXlQYWlyR2VuLmdlbmVyYXRlS2V5UGFpcigpOworICAgICAgICAgICAga2V5UGFpckdlbi5nZW5LZXlQYWlyKCk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAyOgorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlQYWlyR2VuLmluaXRpYWxpemUocHAsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8ganMyZSBkb2VzIG5vdCB0aHJvdyB0aGlzIGV4Y2VwdGlvbgorICAgICAgICAgICAgfQorICAgICAgICAgICAga2V5UGFpckdlbi5pbml0aWFsaXplKDEwMDAsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVBhaXJHZW4uaW5pdGlhbGl6ZSg2MywgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGtleVBhaXJHZW4uaW5pdGlhbGl6ZSgxMDAsIG51bGwpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiTm90IG51bGwgS2V5UGFpciIsIGtleVBhaXJHZW4uZ2VuZXJhdGVLZXlQYWlyKCkpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiTm90IG51bGwgS2V5UGFpciIsIGtleVBhaXJHZW4uZ2VuS2V5UGFpcigpKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIDM6CisgICAgICAgICAgICBrZXlQYWlyR2VuLmluaXRpYWxpemUocHAsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICBrZXlQYWlyR2VuLmluaXRpYWxpemUocHApOworICAgICAgICAgICAga2V5UGFpckdlbi5pbml0aWFsaXplKDEwMDAsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICBrZXlQYWlyR2VuLmluaXRpYWxpemUoMTAwKTsKKworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTnVsbCBLZXlQYWlyIiwga2V5UGFpckdlbi5nZW5lcmF0ZUtleVBhaXIoKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJOdWxsIEtleVBhaXIiLCBrZXlQYWlyR2VuLmdlbktleVBhaXIoKSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSA0OgorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrZXlQYWlyR2VuLmluaXRpYWxpemUocHAsIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoIlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBrZXlQYWlyR2VuLmluaXRpYWxpemUocHAsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICBrZXlQYWlyR2VuLmluaXRpYWxpemUoMTAxLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAga2V5UGFpckdlbi5pbml0aWFsaXplKDEwMDAwKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5UGFpckdlbi5pbml0aWFsaXplKDEwMSwgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIGZvciBudWxsIHJhbmRvbSIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5UGFpckdlbi5pbml0aWFsaXplKDk5LCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gZm9yIGludmFsaWQga2V5Iik7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5UGFpckdlbi5pbml0aWFsaXplKDk5KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIGZvciBpbnZhbGlkIGtleSIpOworICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleVBhaXJHZW4uaW5pdGlhbGl6ZSgxOTksIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biBmb3IgbnVsbCByYW5kb20iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnROdWxsKCJOb3QgbnVsbCBLZXlQYWlyIiwga2V5UGFpckdlbi5nZW5lcmF0ZUtleVBhaXIoKSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJOb3QgbnVsbCBLZXlQYWlyIiwga2V5UGFpckdlbi5nZW5LZXlQYWlyKCkpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pPC9jb2RlPiBtZXRob2QgQXNzZXJ0aW9uczoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbnVsbCB0aHJvd3MKKyAgICAgKiBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgaW5jb3JyZWN0OyByZXR1cm5zCisgICAgICogS2V5UGFpckdlbmVyYXRvciBvYmplY3QKKyAgICAgKgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBHZXRJbnN0YW5jZTAxKGludCBtb2RlKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgS2V5U3RvcmVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgS2V5UGFpckdlbmVyYXRvciBrcEc7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFN0cmluZyBhbGcgPSB2YWxpZFZhbHVlc1tpXS5jb25jYXQocG9zdCk7CisgICAgICAgICAgICBrcEcgPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKGFsZyk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBrcEcuZ2V0QWxnb3JpdGhtKCkKKyAgICAgICAgICAgICAgICAgICAgLnRvVXBwZXJDYXNlKCksIChtb2RlIDw9IDIgPyByZXNBbGcgOiBhbGcpLnRvVXBwZXJDYXNlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBrcEcuZ2V0UHJvdmlkZXIoKSwgbVByb3YpOworICAgICAgICAgICAgY2hlY2tSZXN1bHQoa3BHLCBtb2RlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kCisgICAgICogQXNzZXJ0aW9uczoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIGluY29ycmVjdDsKKyAgICAgKiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbDsKKyAgICAgKiB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBhdmFpbGFibGU7CisgICAgICogcmV0dXJucworICAgICAqIEtleVBhaXJHZW5lcmF0b3Igb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgR2V0SW5zdGFuY2UwMihpbnQgbW9kZSkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UobnVsbCwgbVByb3YuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIEtleVN0b3JlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldLCBtUHJvdi5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHByb3YgPSBudWxsOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBTdHJpbmcgYWxnID0gdmFsaWRWYWx1ZXNbaV0uY29uY2F0KHBvc3QpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKGFsZywgcHJvdik7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gcHJvdmlkZXIgaXMgbnVsbCAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGFsZykuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBTdHJpbmcgYWxnID0gdmFsaWRWYWx1ZXNbaV0uY29uY2F0KHBvc3QpOworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDE7IGogPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZShhbGcsIGludmFsaWRWYWx1ZXNbal0pOworICAgICAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChhbGcpLmNvbmNhdCgiIHByb3ZpZGVyOiAiKS5jb25jYXQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnZhbGlkVmFsdWVzW2pdKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGtwRzsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIGFsZyA9IHZhbGlkVmFsdWVzW2ldLmNvbmNhdChwb3N0KTsKKyAgICAgICAgICAgIGtwRyA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoYWxnLCBtUHJvdi5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwga3BHLmdldEFsZ29yaXRobSgpCisgICAgICAgICAgICAgICAgICAgIC50b1VwcGVyQ2FzZSgpLCAobW9kZSA8PSAyID8gcmVzQWxnIDogYWxnKS50b1VwcGVyQ2FzZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwga3BHLmdldFByb3ZpZGVyKCkuZ2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICBtUHJvdi5nZXROYW1lKCkpOworICAgICAgICAgICAgY2hlY2tSZXN1bHQoa3BHLCBtb2RlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb25zOgorICAgICAqIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgd2hlbiBhbGdvcml0aG0gaXMgbnVsbAorICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgaW5jb3JyZWN0OworICAgICAqIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBudWxsOworICAgICAqIHJldHVybnMgS2V5UGFpckdlbmVyYXRvciBvYmplY3QKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgR2V0SW5zdGFuY2UwMyhpbnQgbW9kZSkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKG51bGwsIG1Qcm92KTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIEtleVN0b3JlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldLCBtUHJvdik7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIChhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBwcm92ID0gbnVsbDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIGFsZyA9IHZhbGlkVmFsdWVzW2ldLmNvbmNhdChwb3N0KTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZShhbGcsIHByb3YpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHByb3ZpZGVyIGlzIG51bGwgKGFsZ29yaXRobTogIgorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChhbGcpLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgS2V5UGFpckdlbmVyYXRvciBrcEc7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFN0cmluZyBhbGcgPSB2YWxpZFZhbHVlc1tpXS5jb25jYXQocG9zdCk7CisgICAgICAgICAgICBrcEcgPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKGFsZywgbVByb3YpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwga3BHLmdldEFsZ29yaXRobSgpCisgICAgICAgICAgICAgICAgICAgIC50b1VwcGVyQ2FzZSgpLCAobW9kZSA8PSAyID8gcmVzQWxnIDogYWxnKS50b1VwcGVyQ2FzZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwga3BHLmdldFByb3ZpZGVyKCksIG1Qcm92KTsKKyAgICAgICAgICAgIGNoZWNrUmVzdWx0KGtwRywgbW9kZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2UwMSgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvclByb3ZpZGVyQ2xhc3MgPSBLZXlQYWlyR2VuZXJhdG9yUHJvdmlkZXJDbGFzczE7CisgICAgICAgIHJlc0FsZyA9IE15S2V5UGFpckdlbmVyYXRvcjEuZ2V0UmVzQWxnb3JpdGhtKCk7CisgICAgICAgIHBvc3QgPSAiXzEiOworICAgICAgICBzZXRQcm92KCk7CisgICAgICAgIEdldEluc3RhbmNlMDEoMSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlMDIoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBLZXlQYWlyR2VuZXJhdG9yUHJvdmlkZXJDbGFzcyA9IEtleVBhaXJHZW5lcmF0b3JQcm92aWRlckNsYXNzMTsKKyAgICAgICAgcmVzQWxnID0gTXlLZXlQYWlyR2VuZXJhdG9yMS5nZXRSZXNBbGdvcml0aG0oKTsKKyAgICAgICAgcG9zdCA9ICJfMSI7CisgICAgICAgIHNldFByb3YoKTsKKyAgICAgICAgR2V0SW5zdGFuY2UwMigxKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2UwMygpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBLZXlQYWlyR2VuZXJhdG9yUHJvdmlkZXJDbGFzcyA9IEtleVBhaXJHZW5lcmF0b3JQcm92aWRlckNsYXNzMTsKKyAgICAgICAgcmVzQWxnID0gTXlLZXlQYWlyR2VuZXJhdG9yMS5nZXRSZXNBbGdvcml0aG0oKTsKKyAgICAgICAgcG9zdCA9ICJfMSI7CisgICAgICAgIHNldFByb3YoKTsKKyAgICAgICAgR2V0SW5zdGFuY2UwMygxKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2UwNCgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvclByb3ZpZGVyQ2xhc3MgPSBLZXlQYWlyR2VuZXJhdG9yUHJvdmlkZXJDbGFzczI7CisgICAgICAgIHJlc0FsZyA9IE15S2V5UGFpckdlbmVyYXRvcjIuZ2V0UmVzQWxnb3JpdGhtKCk7CisgICAgICAgIHBvc3QgPSAiXzIiOworICAgICAgICBzZXRQcm92KCk7CisgICAgICAgIEdldEluc3RhbmNlMDEoMik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlMDUoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBLZXlQYWlyR2VuZXJhdG9yUHJvdmlkZXJDbGFzcyA9IEtleVBhaXJHZW5lcmF0b3JQcm92aWRlckNsYXNzMjsKKyAgICAgICAgcmVzQWxnID0gTXlLZXlQYWlyR2VuZXJhdG9yMi5nZXRSZXNBbGdvcml0aG0oKTsKKyAgICAgICAgcG9zdCA9ICJfMiI7CisgICAgICAgIHNldFByb3YoKTsKKyAgICAgICAgR2V0SW5zdGFuY2UwMigyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2UwNigpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBLZXlQYWlyR2VuZXJhdG9yUHJvdmlkZXJDbGFzcyA9IEtleVBhaXJHZW5lcmF0b3JQcm92aWRlckNsYXNzMjsKKyAgICAgICAgcmVzQWxnID0gTXlLZXlQYWlyR2VuZXJhdG9yMi5nZXRSZXNBbGdvcml0aG0oKTsKKyAgICAgICAgcG9zdCA9ICJfMiI7CisgICAgICAgIHNldFByb3YoKTsKKyAgICAgICAgR2V0SW5zdGFuY2UwMygyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2UwNygpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvclByb3ZpZGVyQ2xhc3MgPSBLZXlQYWlyR2VuZXJhdG9yUHJvdmlkZXJDbGFzczM7CisgICAgICAgIHJlc0FsZyA9ICIiOworICAgICAgICBwb3N0ID0gIl8zIjsKKyAgICAgICAgc2V0UHJvdigpOworICAgICAgICBHZXRJbnN0YW5jZTAxKDMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZTA4KCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvclByb3ZpZGVyQ2xhc3MgPSBLZXlQYWlyR2VuZXJhdG9yUHJvdmlkZXJDbGFzczM7CisgICAgICAgIHJlc0FsZyA9ICIiOworICAgICAgICBwb3N0ID0gIl8zIjsKKyAgICAgICAgc2V0UHJvdigpOworICAgICAgICBHZXRJbnN0YW5jZTAyKDMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZTA5KCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIEtleVBhaXJHZW5lcmF0b3JQcm92aWRlckNsYXNzID0gS2V5UGFpckdlbmVyYXRvclByb3ZpZGVyQ2xhc3MzOworICAgICAgICByZXNBbGcgPSAiIjsKKyAgICAgICAgcG9zdCA9ICJfMyI7CisgICAgICAgIHNldFByb3YoKTsKKyAgICAgICAgR2V0SW5zdGFuY2UwMygzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2UxMCgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvclByb3ZpZGVyQ2xhc3MgPSBLZXlQYWlyR2VuZXJhdG9yUHJvdmlkZXJDbGFzczQ7CisgICAgICAgIHJlc0FsZyA9ICIiOworICAgICAgICBwb3N0ID0gIl80IjsKKyAgICAgICAgc2V0UHJvdigpOworICAgICAgICBHZXRJbnN0YW5jZTAxKDQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZTExKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvclByb3ZpZGVyQ2xhc3MgPSBLZXlQYWlyR2VuZXJhdG9yUHJvdmlkZXJDbGFzczQ7CisgICAgICAgIHJlc0FsZyA9ICIiOworICAgICAgICBwb3N0ID0gIl80IjsKKyAgICAgICAgc2V0UHJvdigpOworICAgICAgICBHZXRJbnN0YW5jZTAyKDQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZTEyKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIEtleVBhaXJHZW5lcmF0b3JQcm92aWRlckNsYXNzID0gS2V5UGFpckdlbmVyYXRvclByb3ZpZGVyQ2xhc3M0OworICAgICAgICByZXNBbGcgPSAiIjsKKyAgICAgICAgcG9zdCA9ICJfNCI7CisgICAgICAgIHNldFByb3YoKTsKKyAgICAgICAgR2V0SW5zdGFuY2UwMyg0KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5UGFpckdlbmVyYXRvcjNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5UGFpckdlbmVyYXRvcjNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjRlNDUxZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlQYWlyR2VuZXJhdG9yM1Rlc3QuamF2YQpAQCAtMCwwICsxLDE2MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyc1NwaTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnNUZXN0Lk15QWxnb3JpdGhtUGFyYW1ldGVyczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzVGVzdC5teUFsZ1A7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuU3BpRW5nVXRpbHM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIEtleVBhaXJHZW5lcmF0b3IgY2xhc3MKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBLZXlQYWlyR2VuZXJhdG9yM1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgdmFsaWRQcm92aWRlck5hbWUgPSBudWxsOworCisgICAgcHVibGljIHN0YXRpYyBQcm92aWRlciB2YWxpZFByb3ZpZGVyID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gRFNBU3VwcG9ydGVkID0gZmFsc2U7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgTm90U3VwcG9ydE1zZyA9IEtleVBhaXJHZW5lcmF0b3IxVGVzdC5Ob3RTdXBwb3J0TXNnOworCisgICAgc3RhdGljIHsKKyAgICAgICAgdmFsaWRQcm92aWRlciA9IFNwaUVuZ1V0aWxzLmlzU3VwcG9ydCgKKyAgICAgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yMVRlc3QudmFsaWRBbGdOYW1lLAorICAgICAgICAgICAgICAgIEtleVBhaXJHZW5lcmF0b3IxVGVzdC5zcnZLZXlQYWlyR2VuZXJhdG9yKTsKKyAgICAgICAgRFNBU3VwcG9ydGVkID0gKHZhbGlkUHJvdmlkZXIgIT0gbnVsbCk7CisgICAgICAgIHZhbGlkUHJvdmlkZXJOYW1lID0gKERTQVN1cHBvcnRlZCA/IHZhbGlkUHJvdmlkZXIuZ2V0TmFtZSgpIDogbnVsbCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIEtleVBhaXJHZW5lcmF0b3JbXSBjcmVhdGVLUEdlbigpIHsKKyAgICAgICAgaWYgKCFEU0FTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoS2V5UGFpckdlbmVyYXRvcjFUZXN0LnZhbGlkQWxnTmFtZQorICAgICAgICAgICAgICAgICAgICArICIgYWxnb3JpdGhtIGlzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIEtleVBhaXJHZW5lcmF0b3JbXSBrcGcgPSBuZXcgS2V5UGFpckdlbmVyYXRvclszXTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtwZ1swXSA9IEtleVBhaXJHZW5lcmF0b3IKKyAgICAgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKEtleVBhaXJHZW5lcmF0b3IxVGVzdC52YWxpZEFsZ05hbWUpOworICAgICAgICAgICAga3BnWzFdID0gS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZSgKKyAgICAgICAgICAgICAgICAgICAgS2V5UGFpckdlbmVyYXRvcjFUZXN0LnZhbGlkQWxnTmFtZSwgdmFsaWRQcm92aWRlcik7CisgICAgICAgICAgICBrcGdbMl0gPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKAorICAgICAgICAgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yMVRlc3QudmFsaWRBbGdOYW1lLCB2YWxpZFByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICByZXR1cm4ga3BnOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZW5lcmF0ZUtleVBhaXIoKTwvY29kZT4gYW5kIDxjb2RlPmdlbktleVBhaXIoKTwvY29kZT4KKyAgICAgKiBtZXRob2RzCisgICAgICogQXNzZXJ0aW9uOiBLZXlQYWlyR2VuZXJhdG9yIHdhcyBpbml0aWFsaXplZCBiZWZvcmUgdGhlIGludm9jYXRpb24KKyAgICAgKiBvZiB0aGVzZSBtZXRob2RzCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdlbktleVBhaXIwMSgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFEU0FTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgS2V5UGFpckdlbmVyYXRvcltdIGtwZyA9IGNyZWF0ZUtQR2VuKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIktleVBhaXJHZW5lcmF0b3Igb2JqZWN0cyB3ZXJlIG5vdCBjcmVhdGVkIiwga3BnKTsKKyAgICAgICAgS2V5UGFpciBrcCwga3AxOworICAgICAgICBTZWN1cmVSYW5kb20gcnIgPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga3BnLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBrcGdbaV0uaW5pdGlhbGl6ZSg1MTIsIHJyKTsKKyAgICAgICAgICAgIGtwID0ga3BnW2ldLmdlbmVyYXRlS2V5UGFpcigpOworICAgICAgICAgICAga3AxID0ga3BnW2ldLmdlbktleVBhaXIoKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJJbmNvcnJlY3QgcHJpdmF0ZSBrZXkiLCBrcC5nZXRQcml2YXRlKCkuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICBrcDEuZ2V0UHJpdmF0ZSgpKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSgiSW5jb3JyZWN0IHB1YmxpYyBrZXkiLCBrcC5nZXRQdWJsaWMoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgIGtwMS5nZXRQdWJsaWMoKSkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2VuZXJhdGVLZXlQYWlyKCk8L2NvZGU+IGFuZCA8Y29kZT5nZW5LZXlQYWlyKCk8L2NvZGU+CisgICAgICogbWV0aG9kcworICAgICAqIEFzc2VydGlvbjogdGhlc2UgbWV0aG9kcyBhcmUgdXNlZCB3aXRob3V0IHByZXZpb3VzbHkgaW5pdGlhbGl6YXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2VuS2V5UGFpcjAyKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICBpZiAoIURTQVN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBLZXlQYWlyR2VuZXJhdG9yW10ga3BnID0gY3JlYXRlS1BHZW4oKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiS2V5UGFpckdlbmVyYXRvciBvYmplY3RzIHdlcmUgbm90IGNyZWF0ZWQiLCBrcGcpOworICAgICAgICBLZXlQYWlyIGtwLCBrcDE7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga3BnLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBrcCA9IGtwZ1tpXS5nZW5lcmF0ZUtleVBhaXIoKTsKKyAgICAgICAgICAgIGtwMSA9IGtwZ1tpXS5nZW5LZXlQYWlyKCk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSgiSW5jb3JyZWN0IHByaXZhdGUga2V5Iiwga3AuZ2V0UHJpdmF0ZSgpLmVxdWFscygKKyAgICAgICAgICAgICAgICBrcDEuZ2V0UHJpdmF0ZSgpKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSgiSW5jb3JyZWN0IHB1YmxpYyBrZXkiLCBrcC5nZXRQdWJsaWMoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAga3AxLmdldFB1YmxpYygpKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5LZXlQYWlyR2VuZXJhdG9yPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBLZXlQYWlyR2VuZXJhdG9yIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlQYWlyR2VuZXJhdG9yQ29uc3QoKSB7CisgICAgICAgIFN0cmluZ1tdIGFsZyA9IHtudWxsLCAiIiwgIkFzRGZHaCEjJCoiLCAiRFNBIiwgIlJTQSJ9OworICAgICAgICBNeWtleVBHZW4ga3BnOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxnLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtwZyA9IG5ldyBNeWtleVBHZW4oYWxnW2ldKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGtwZyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShrcGcgaW5zdGFuY2VvZiBLZXlQYWlyR2VuZXJhdG9yKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKXsKKyAgICAgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gc2hvdWxkIG5vdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZGl0aW9uYWwgY2xhc3MgdG8gdmVyaWZ5IEtleVBhaXJHZW5lcmF0b3IgY29uc3RydWN0b3IKKyAgICAgKi8KKyAgICBjbGFzcyBNeWtleVBHZW4gZXh0ZW5kcyBLZXlQYWlyR2VuZXJhdG9yIHsKKyAgICAgICAgcHVibGljIE15a2V5UEdlbihTdHJpbmcgYWxnKSB7CisgICAgICAgICAgICBzdXBlcihhbGcpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVBhaXJHZW5lcmF0b3I0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVBhaXJHZW5lcmF0b3I0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIwOTNkNjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5UGFpckdlbmVyYXRvcjRUZXN0LmphdmEKQEAgLTAsMCArMSwxMzggQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRFNBUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuRFNBUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5EU0FQYXJhbXM7CisKK3B1YmxpYyBjbGFzcyBLZXlQYWlyR2VuZXJhdG9yNFRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yI2dlbktleVBhaXIoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2VuS2V5UGFpcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGdlbiA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRTQSIpOworICAgICAgICBnZW4uaW5pdGlhbGl6ZSgxMDI0KTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiS2V5UGFpciBpcyBudWxsIiwgZ2VuLmdlbktleVBhaXIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yI2dldEFsZ29yaXRobSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBbGdvcml0aG0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGFsZyA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRTQSIpLmdldEFsZ29yaXRobSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldEFsZ29yaXRobSByZXR1cm5lZCB1bmV4cGVjdGVkIHZhbHVlIiwgIkRTQSIsIGFsZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yI2dldEluc3RhbmNlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRTQSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvciNnZXRJbnN0YW5jZShqYXZhLmxhbmcuU3RyaW5nLAorICAgICAqICAgICAgICBqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIC8vIFRlc3QxOiBUZXN0IHdpdGggbmFtZWQgcHJvdmlkZXIKKyAgICAgICAgUHJvdmlkZXJbXSBwcm92aWRlcnMgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoIktleVBhaXJHZW5lcmF0b3IuRFNBIik7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcm92aWRlcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRTQSIsIHByb3ZpZGVyc1tpXS5nZXROYW1lKCkpOworICAgICAgICB9Ly8gZW5kIGZvcgorCisgICAgICAgIC8vIFRlc3QyOiBUZXN0IHdpdGggZW1wdHkgcHJvdmlkZXIgbmFtZSAtIHNob3VsZCByYWlzZQorICAgICAgICAvLyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRTQSIsICIiKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LktleVBhaXJHZW5lcmF0b3IjZ2V0UHJvdmlkZXIoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UHJvdmlkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvdmlkZXIgcCA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRTQSIpLmdldFByb3ZpZGVyKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoInByb3ZpZGVyIGlzIG51bGwiLCBwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LktleVBhaXJHZW5lcmF0b3IjaW5pdGlhbGl6ZShpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pbml0aWFsaXplSSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGtleVBhaXIgPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKCJEU0EiKTsKKyAgICAgICAga2V5UGFpci5pbml0aWFsaXplKDEwMjQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvciNpbml0aWFsaXplKGludCwKKyAgICAgKiAgICAgICAgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb20pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pbml0aWFsaXplSUxqYXZhX3NlY3VyaXR5X1NlY3VyZVJhbmRvbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGtleVBhaXIgPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKCJEU0EiKTsKKyAgICAgICAga2V5UGFpci5pbml0aWFsaXplKDEwMjQsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LktleVBhaXJHZW5lcmF0b3IjaW5pdGlhbGl6ZShqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luaXRpYWxpemVMamF2YV9zZWN1cml0eV9zcGVjX0FsZ29yaXRobVBhcmFtZXRlclNwZWMoKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIGNyZWF0ZSBEU0FQYXJhbXMKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvciBrZXlQYWlyR2VuZXJhdG9yID0gS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZSgiRFNBIik7CisgICAgICAgIGtleVBhaXJHZW5lcmF0b3IuaW5pdGlhbGl6ZSgxMDI0KTsKKyAgICAgICAgRFNBUHVibGljS2V5IGtleSA9IChEU0FQdWJsaWNLZXkpIGtleVBhaXJHZW5lcmF0b3IuZ2VuS2V5UGFpcigpCisgICAgICAgICAgICAgICAgLmdldFB1YmxpYygpOworICAgICAgICBEU0FQYXJhbXMgcGFyYW1zID0ga2V5LmdldFBhcmFtcygpOworCisgICAgICAgIEtleVBhaXJHZW5lcmF0b3Iga2V5UGFpciA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRTQSIpOworICAgICAgICBrZXlQYWlyLmluaXRpYWxpemUobmV3IERTQVBhcmFtZXRlclNwZWMocGFyYW1zLmdldFAoKSwgcGFyYW1zLmdldFEoKSwKKyAgICAgICAgICAgICAgICBwYXJhbXMuZ2V0RygpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yI2luaXRpYWxpemUoamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWMsCisgICAgICogICAgICAgIGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5pdGlhbGl6ZUxqYXZhX3NlY3VyaXR5X3NwZWNfQWxnb3JpdGhtUGFyYW1ldGVyU3BlY0xqYXZhX3NlY3VyaXR5X1NlY3VyZVJhbmRvbSgpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gY3JlYXRlIERTQVBhcmFtcworICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGtleVBhaXJHZW5lcmF0b3IgPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKCJEU0EiKTsKKyAgICAgICAga2V5UGFpckdlbmVyYXRvci5pbml0aWFsaXplKDEwMjQpOworICAgICAgICBEU0FQdWJsaWNLZXkga2V5ID0gKERTQVB1YmxpY0tleSkga2V5UGFpckdlbmVyYXRvci5nZW5LZXlQYWlyKCkKKyAgICAgICAgICAgICAgICAuZ2V0UHVibGljKCk7CisgICAgICAgIERTQVBhcmFtcyBwYXJhbXMgPSBrZXkuZ2V0UGFyYW1zKCk7CisKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvciBrZXlQYWlyID0gS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZSgiRFNBIik7CisgICAgICAgIGtleVBhaXIuaW5pdGlhbGl6ZShuZXcgRFNBUGFyYW1ldGVyU3BlYyhwYXJhbXMuZ2V0UCgpLCBwYXJhbXMuZ2V0USgpLAorICAgICAgICAgICAgICAgIHBhcmFtcy5nZXRHKCkpLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlQYWlyR2VuZXJhdG9yU3BpVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVBhaXJHZW5lcmF0b3JTcGlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTEwZGE5OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlQYWlyR2VuZXJhdG9yU3BpVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvclNwaTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0Lk15S2V5UGFpckdlbmVyYXRvclNwaTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+S2V5UGFpckdlbmVyYXRvclNwaTwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIEtleVBhaXJHZW5lcmF0b3JTcGlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+S2V5UGFpckdlbmVyYXRvclNwaTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgS2V5UGFpckdlbmVyYXRvclNwaQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlQYWlyR2VuZXJhdG9yU3BpMDEoKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvclNwaSBrZXlQYWlyR2VuID0gbmV3IE15S2V5UGFpckdlbmVyYXRvclNwaSgpOworCisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcHAgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5UGFpckdlbi5pbml0aWFsaXplKHBwLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIGtleVBhaXJHZW4uaW5pdGlhbGl6ZShwcCwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAga2V5UGFpckdlbi5pbml0aWFsaXplKDEwMjQsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlQYWlyR2VuLmluaXRpYWxpemUoLTEwMjQsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gZm9yIGluY29ycmVjdCBrZXlzaXplIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleVBhaXJHZW4uaW5pdGlhbGl6ZSgxMDI0LCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgZXhjZXB0aW9uIiwgZS5nZXRNZXNzYWdlKCksCisgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIHJhbmRvbSIpOworICAgICAgICB9CisgICAgICAgIEtleVBhaXIga3AgPSBrZXlQYWlyR2VuLmdlbmVyYXRlS2V5UGFpcigpOworICAgICAgICBhc3NlcnROdWxsKCJOb3QgbnVsbCBLZXlQYWlyIiwga3ApOworICAgIH0KKworICAgIGNsYXNzIE15QWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBpbXBsZW1lbnRzIEFsZ29yaXRobVBhcmFtZXRlclNwZWMge30KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVBhaXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5UGFpclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZmRlMGZhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVBhaXJUZXN0LmphdmEKQEAgLTAsMCArMSwxMzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5JbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgZmllbGRzIGFuZCBtZXRob2RzIG9mIGNsYXNzIDxjb2RlPktleVBhaXI8L2NvZGU+CisgKgorICovCitwdWJsaWMgY2xhc3MgS2V5UGFpclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBUZXN0S2V5UGFpciB7CisgICAgICAgIHN0YXRpYyBQdWJsaWNLZXkgZ2V0UHVibGljKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBQdWJsaWNLZXkoKSB7CisgICAgICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAibmV2ZXIgbWluZCI7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gIm5ldmVyIG1pbmQiOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgIH0KKyAgICAgICAgc3RhdGljIFByaXZhdGVLZXkgZ2V0UHJpdmF0ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUHJpdmF0ZUtleSgpIHsKKyAgICAgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJuZXZlciBtaW5kIjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRGb3JtYXQoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAibmV2ZXIgbWluZCI7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+S2V5UGFpcihQdWJsaWNLZXksIFByaXZhdGVLZXkpPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IGNyZWF0ZXMgbmV3IDxjb2RlPktleVBhaXI8L2NvZGU+IGluc3RhbmNlIHVzaW5nIHZhbGlkCisgICAgICogcGFyYW1ldGVycyAoYm90aCA8Y29kZT5udWxsPC9jb2RlPikKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0S2V5UGFpcjAxKCkgeworICAgICAgICBPYmplY3Qga3AgPSBuZXcgS2V5UGFpcihudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShrcCBpbnN0YW5jZW9mIEtleVBhaXIpOworCisgICAgICAgIGtwID0gbmV3IEtleVBhaXIobnVsbCwgVGVzdEtleVBhaXIuZ2V0UHJpdmF0ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShrcCBpbnN0YW5jZW9mIEtleVBhaXIpOworICAgICAgICBrcCA9IG5ldyBLZXlQYWlyKFRlc3RLZXlQYWlyLmdldFB1YmxpYygpLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShrcCBpbnN0YW5jZW9mIEtleVBhaXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPktleVBhaXIoUHVibGljS2V5LCBQcml2YXRlS2V5KTwvY29kZT4gY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiBjcmVhdGVzIG5ldyA8Y29kZT5LZXlQYWlyPC9jb2RlPiBpbnN0YW5jZSB1c2luZyB2YWxpZAorICAgICAqIHBhcmFtZXRlcnMgKGJvdGggdmFsaWQga2V5cykKKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEtleVBhaXIwMigpIHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdCBrcCA9IG5ldyBLZXlQYWlyKFRlc3RLZXlQYWlyLmdldFB1YmxpYygpLCBUZXN0S2V5UGFpci5nZXRQcml2YXRlKCkpOworICAgICAgICBhc3NlcnRUcnVlKGtwIGluc3RhbmNlb2YgS2V5UGFpcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+Z2V0UHJpdmF0ZSgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHByaXZhdGUga2V5ICg8Y29kZT5udWxsPC9jb2RlPiBpbiB0aGlzIGNhc2UpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFByaXZhdGUwMSgpIHsKKyAgICAgICAgS2V5UGFpciBrcCA9IG5ldyBLZXlQYWlyKG51bGwsIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKGtwLmdldFByaXZhdGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+Z2V0UHJpdmF0ZSgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHByaXZhdGUga2V5ICh2YWxpZCBwcml2YXRlIGtleSBpbiB0aGlzIGNhc2UpCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRQcml2YXRlMDIoKSB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24geworICAgICAgICBQcml2YXRlS2V5IHBrID0gVGVzdEtleVBhaXIuZ2V0UHJpdmF0ZSgpOworICAgICAgICBLZXlQYWlyIGtwID0gbmV3IEtleVBhaXIobnVsbCwgcGspOworICAgICAgICBhc3NlcnRTYW1lKHBrLCBrcC5nZXRQcml2YXRlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPmdldFB1YmxpYygpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHB1YmxpYyBrZXkgKDxjb2RlPm51bGw8L2NvZGU+IGluIHRoaXMgY2FzZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0UHVibGljMDEoKSB7CisgICAgICAgIEtleVBhaXIga3AgPSBuZXcgS2V5UGFpcihudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChrcC5nZXRQdWJsaWMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+Z2V0UHVibGljKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgcHVibGljIGtleSAodmFsaWQgcHVibGljIGtleSBpbiB0aGlzIGNhc2UpCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRQdWJsaWMwMigpIHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiB7CisgICAgICAgIFB1YmxpY0tleSBwayA9IFRlc3RLZXlQYWlyLmdldFB1YmxpYygpOworICAgICAgICBLZXlQYWlyIGtwID0gbmV3IEtleVBhaXIocGssIG51bGwpOworICAgICAgICBhc3NlcnRTYW1lKHBrLCBrcC5nZXRQdWJsaWMoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5UmVwVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVJlcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZGFkODI3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVJlcFRlc3QuamF2YQpAQCAtMCwwICsxLDIyNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisgKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0U3RyZWFtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UmVwOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICoKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBLZXlSZXBUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2V0PFN0cmluZz4ga2V5RmFjdG9yeUFsZ29yaXRobTsKKyAgICBzdGF0aWMgeworICAgICAgICBrZXlGYWN0b3J5QWxnb3JpdGhtID0gU2VjdXJpdHkuZ2V0QWxnb3JpdGhtcygiS2V5RmFjdG9yeSIpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RLZXlSZXAwMSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwobmV3IEtleVJlcChLZXlSZXAuVHlwZS5TRUNSRVQsICIiLCAiIiwgbmV3IGJ5dGVbXSB7fSkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG5ldyBLZXlSZXAoS2V5UmVwLlR5cGUuUFVCTElDLCAiIiwgIiIsIG5ldyBieXRlW10ge30pKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXcgS2V5UmVwKEtleVJlcC5UeXBlLlBSSVZBVEUsICIiLCAiIiwgbmV3IGJ5dGVbXSB7fSkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RLZXlSZXAwMigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBLZXlSZXAobnVsbCwgIiIsICIiLCBuZXcgYnl0ZVtdIHt9KTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24gKHR5cGUpIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG9rKSB7CisKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEtleVJlcChLZXlSZXAuVHlwZS5TRUNSRVQsIG51bGwsICIiLCBuZXcgYnl0ZVtdIHt9KTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24gKGFsZykiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gb2spIHsKKworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgS2V5UmVwKEtleVJlcC5UeXBlLlBSSVZBVEUsICIiLCBudWxsLCBuZXcgYnl0ZVtdIHt9KTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24gKGZvcm1hdCkiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gb2spIHsKKworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgS2V5UmVwKEtleVJlcC5UeXBlLlBVQkxJQywgIiIsICIiLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24gKGVuY29kaW5nKSIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBvaykgeworCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UmVhZFJlc29sdmUwMSgpIHRocm93cyBPYmplY3RTdHJlYW1FeGNlcHRpb24geworICAgICAgICBLZXlSZXBDaGlsZCBrciA9IG5ldyBLZXlSZXBDaGlsZChLZXlSZXAuVHlwZS5TRUNSRVQsICIiLCAiIiwKKyAgICAgICAgICAgICAgICBuZXcgYnl0ZVtdIHt9KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtyLnJlYWRSZXNvbHZlKCk7CisgICAgICAgICAgICBmYWlsKCJOb3RTZXJpYWxpemFibGVFeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biAobm8gZm9ybWF0KSIpOworICAgICAgICB9IGNhdGNoIChOb3RTZXJpYWxpemFibGVFeGNlcHRpb24gb2spIHsKKworICAgICAgICB9CisKKyAgICAgICAga3IgPSBuZXcgS2V5UmVwQ2hpbGQoS2V5UmVwLlR5cGUuU0VDUkVULCAiIiwgIlguNTA5IiwgbmV3IGJ5dGVbXSB7fSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrci5yZWFkUmVzb2x2ZSgpOworICAgICAgICAgICAgZmFpbCgiTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24gKHVuYWNjZXB0YWJsZSBmb3JtYXQpIik7CisgICAgICAgIH0gY2F0Y2ggKE5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbiBvaykgeworCisgICAgICAgIH0KKworICAgICAgICBrciA9IG5ldyBLZXlSZXBDaGlsZChLZXlSZXAuVHlwZS5TRUNSRVQsICIiLCAiUkFXIiwgbmV3IGJ5dGVbXSB7fSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrci5yZWFkUmVzb2x2ZSgpOworICAgICAgICAgICAgZmFpbCgiTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24gKGVtcHR5IGtleSkiKTsKKyAgICAgICAgfSBjYXRjaCAoTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uIG9rKSB7CisKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RSZWFkUmVzb2x2ZTAyKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgICAgIEtleVJlcENoaWxkIGtyID0gbmV3IEtleVJlcENoaWxkKEtleVJlcC5UeXBlLlBVQkxJQywgIiIsICIiLAorICAgICAgICAgICAgICAgIG5ldyBieXRlW10ge30pOworICAgICAgICB0cnkgeworICAgICAgICAgICAga3IucmVhZFJlc29sdmUoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIChubyBmb3JtYXQpIik7CisgICAgICAgIH0gY2F0Y2ggKE5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbiBvaykgeworCisgICAgICAgIH0KKworICAgICAgICBrciA9IG5ldyBLZXlSZXBDaGlsZChLZXlSZXAuVHlwZS5QVUJMSUMsICIiLCAiUkFXIiwgbmV3IGJ5dGVbXSB7fSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrci5yZWFkUmVzb2x2ZSgpOworICAgICAgICAgICAgZmFpbCgiTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24gKHVuYWNjZXB0YWJsZSBmb3JtYXQpIik7CisgICAgICAgIH0gY2F0Y2ggKE5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbiBvaykgeworCisgICAgICAgIH0KKworICAgICAgICBrciA9IG5ldyBLZXlSZXBDaGlsZChLZXlSZXAuVHlwZS5QVUJMSUMsICJibGEtYmxhIiwgIlguNTA5IiwKKyAgICAgICAgICAgICAgICBuZXcgYnl0ZVtdIHt9KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtyLnJlYWRSZXNvbHZlKCk7CisgICAgICAgICAgICBmYWlsKCJOb3RTZXJpYWxpemFibGVFeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biAodW5rbm93biBLZXlGYWN0b3J5IGFsZ29yaXRobSkiKTsKKyAgICAgICAgfSBjYXRjaCAoTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uIG9rKSB7CisKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RSZWFkUmVzb2x2ZTAzKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgICAgIEtleVJlcENoaWxkIGtyID0gbmV3IEtleVJlcENoaWxkKEtleVJlcC5UeXBlLlBSSVZBVEUsICIiLCAiIiwKKyAgICAgICAgICAgICAgICBuZXcgYnl0ZVtdIHt9KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtyLnJlYWRSZXNvbHZlKCk7CisgICAgICAgICAgICBmYWlsKCJOb3RTZXJpYWxpemFibGVFeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biAobm8gZm9ybWF0KSIpOworICAgICAgICB9IGNhdGNoIChOb3RTZXJpYWxpemFibGVFeGNlcHRpb24gb2spIHsKKworICAgICAgICB9CisKKyAgICAgICAga3IgPSBuZXcgS2V5UmVwQ2hpbGQoS2V5UmVwLlR5cGUuUFJJVkFURSwgIiIsICJSQVciLCBuZXcgYnl0ZVtdIHt9KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtyLnJlYWRSZXNvbHZlKCk7CisgICAgICAgICAgICBmYWlsKCJOb3RTZXJpYWxpemFibGVFeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biAodW5hY2NlcHRhYmxlIGZvcm1hdCkiKTsKKyAgICAgICAgfSBjYXRjaCAoTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uIG9rKSB7CisKKyAgICAgICAgfQorCisgICAgICAgIGtyID0gbmV3IEtleVJlcENoaWxkKEtleVJlcC5UeXBlLlBSSVZBVEUsICJibGEtYmxhIiwgIlBLQ1MjOCIsCisgICAgICAgICAgICAgICAgbmV3IGJ5dGVbXSB7fSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrci5yZWFkUmVzb2x2ZSgpOworICAgICAgICAgICAgZmFpbCgiTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24gKHVua25vd24gS2V5RmFjdG9yeSBhbGdvcml0aG0pIik7CisgICAgICAgIH0gY2F0Y2ggKE5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbiBvaykgeworCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UmVhZFJlc29sdmUwNCgpIHRocm93cyBPYmplY3RTdHJlYW1FeGNlcHRpb24geworICAgICAgICBpZiAoa2V5RmFjdG9yeUFsZ29yaXRobS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihnZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgKyAiOiBza2lwcGVkIC0gbm8gS2V5RmFjdG9yeSBhbGdvcml0aG1zIGF2YWlsYWJsZSIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9IGVsc2UgeworICAgICAgICB9CisgICAgICAgIGZvciAoSXRlcmF0b3I8U3RyaW5nPiBpID0ga2V5RmFjdG9yeUFsZ29yaXRobS5pdGVyYXRvcigpOyBpLmhhc05leHQoKTspIHsKKyAgICAgICAgICAgIEtleVJlcENoaWxkIGtyID0gbmV3IEtleVJlcENoaWxkKEtleVJlcC5UeXBlLlBVQkxJQywgaS5uZXh0KCksCisgICAgICAgICAgICAgICAgICAgICJYLjUwOSIsIG5ldyBieXRlW10geyAxLCAyLCAzIH0pOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrci5yZWFkUmVzb2x2ZSgpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIChubyBmb3JtYXQpIik7CisgICAgICAgICAgICB9IGNhdGNoIChOb3RTZXJpYWxpemFibGVFeGNlcHRpb24gb2spIHsKKworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJlYWRSZXNvbHZlMDUoKSB0aHJvd3MgT2JqZWN0U3RyZWFtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGtleUZhY3RvcnlBbGdvcml0aG0uaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgICAgICsgIjogc2tpcHBlZCAtIG5vIEtleUZhY3RvcnkgYWxnb3JpdGhtcyBhdmFpbGFibGUiKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKEl0ZXJhdG9yPFN0cmluZz4gaSA9IGtleUZhY3RvcnlBbGdvcml0aG0uaXRlcmF0b3IoKTsgaS5oYXNOZXh0KCk7KSB7CisgICAgICAgICAgICBLZXlSZXBDaGlsZCBrciA9IG5ldyBLZXlSZXBDaGlsZChLZXlSZXAuVHlwZS5QUklWQVRFLCBpLm5leHQoKSwKKyAgICAgICAgICAgICAgICAgICAgIlBLQ1MjOCIsIG5ldyBieXRlW10geyAxLCAyLCAzIH0pOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBrci5yZWFkUmVzb2x2ZSgpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIChubyBmb3JtYXQpIik7CisgICAgICAgICAgICB9IGNhdGNoIChOb3RTZXJpYWxpemFibGVFeGNlcHRpb24gb2spIHsKKworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgS2V5UmVwQ2hpbGQgZXh0ZW5kcyBLZXlSZXAgeworICAgICAgICBwdWJsaWMgS2V5UmVwQ2hpbGQoS2V5UmVwLlR5cGUgdHlwZSwgU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIGZvcm1hdCwKKyAgICAgICAgICAgICAgICBieXRlW10gZW5jb2RlZCkgeworICAgICAgICAgICAgc3VwZXIodHlwZSwgYWxnb3JpdGhtLCBmb3JtYXQsIGVuY29kZWQpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCByZWFkUmVzb2x2ZSgpIHRocm93cyBPYmplY3RTdHJlYW1FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnJlYWRSZXNvbHZlKCk7CisgICAgICAgIH0KKworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlSZXBUeXBlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVJlcFR5cGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDYwOWVmNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlSZXBUeXBlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVJlcDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgS2V5UmVwVHlwZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5LZXlSZXAuVHlwZSN2YWx1ZU9mKFN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmFsdWVPZigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVJlcC5UeXBlLnZhbHVlT2YoInR5cGUiKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5UmVwLlR5cGUudmFsdWVPZihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKEtleVJlcC5UeXBlLlBSSVZBVEUsIEtleVJlcC5UeXBlCisgICAgICAgICAgICAgICAgLnZhbHVlT2YoS2V5UmVwLlR5cGUuUFJJVkFURS50b1N0cmluZygpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhLZXlSZXAuVHlwZS5QVUJMSUMsIEtleVJlcC5UeXBlLnZhbHVlT2YoS2V5UmVwLlR5cGUuUFVCTElDCisgICAgICAgICAgICAgICAgLnRvU3RyaW5nKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEtleVJlcC5UeXBlLlNFQ1JFVCwgS2V5UmVwLlR5cGUudmFsdWVPZihLZXlSZXAuVHlwZS5TRUNSRVQKKyAgICAgICAgICAgICAgICAudG9TdHJpbmcoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuS2V5UmVwLlR5cGUjdmFsdWVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmFsdWVzKCkgeworICAgICAgICBLZXlSZXAuVHlwZVtdIHR5cGVzID0gbmV3IEtleVJlcC5UeXBlW10geyBLZXlSZXAuVHlwZS5TRUNSRVQsCisgICAgICAgICAgICAgICAgS2V5UmVwLlR5cGUuUFVCTElDLCBLZXlSZXAuVHlwZS5QUklWQVRFIH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHModHlwZXMsIEtleVJlcC5UeXBlLnZhbHVlcygpKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5U3RvcmUyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVN0b3JlMlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZDI3ZWRjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVN0b3JlMlRlc3QuamF2YQpAQCAtMCwwICsxLDEwMDAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5RmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5VbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5EU0FQcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5EU0FQcml2YXRlS2V5U3BlYzsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfVGVzdFByb3ZpZGVyOworCitwdWJsaWMgY2xhc3MgS2V5U3RvcmUyVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBQcml2YXRlS2V5IFBSSVZBVEVfS0VZOworCisgICAgcHJpdmF0ZSBzdGF0aWMgUHJpdmF0ZUtleSBnZXRQcml2YXRlS2V5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChQUklWQVRFX0tFWSA9PSBudWxsKSB7CisgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGtleVBhaXJHZW5lcmF0b3IgPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKCJEU0EiKTsKKyAgICAgICAgICAgIGtleVBhaXJHZW5lcmF0b3IuaW5pdGlhbGl6ZSgxMDI0LCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAgS2V5UGFpciBrZXlQYWlyID0ga2V5UGFpckdlbmVyYXRvci5nZW5LZXlQYWlyKCk7CisgICAgICAgICAgICBQUklWQVRFX0tFWSA9IGtleVBhaXIuZ2V0UHJpdmF0ZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBQUklWQVRFX0tFWTsKKyAgICB9CisKKyAgICBmaW5hbCBjaGFyW10gcHNzV29yZCA9IHsgJ2EnLCAnYicsICdjJyB9OworCisgICAgZmluYWwgYnl0ZVtdIHRlc3RFbmNvZGluZyA9IG5ldyBieXRlW10geyAoYnl0ZSkgMSwgKGJ5dGUpIDIsIChieXRlKSAzLAorICAgICAgICAgICAgKGJ5dGUpIDQsIChieXRlKSA1IH07CisKKyAgICBwcml2YXRlIFByb3ZpZGVyIHN1cHBvcnRfVGVzdFByb3ZpZGVyOworCisgICAgLy8gY3JlYXRpbmcgYSBjZXJ0aWZpY2F0ZQorICAgIFN0cmluZyBjZXJ0aWZpY2F0ZSA9ICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICsgIk1JSUNaVENDQWRJQ0JRTDNBQUMyTUEwR0NTcUdTSWIzRFFFQkFnVUFNRjh4Q3pBSkJnTlZCQVlUQWxWVE1TQXdcbiIKKyAgICAgICAgICAgICsgIkhnWURWUVFLRXhkU1UwRWdSR0YwWVNCVFpXTjFjbWwwZVN3Z1NXNWpMakV1TUN3R0ExVUVDeE1sVTJWamRYSmxcbiIKKyAgICAgICAgICAgICsgIklGTmxjblpsY2lCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVEFlRncwNU56QXlNakF3TURBd01EQmFcbiIKKyAgICAgICAgICAgICsgIkZ3MDVPREF5TWpBeU16VTVOVGxhTUlHV01Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZcbiIKKyAgICAgICAgICAgICsgImNtNXBZVEVTTUJBR0ExVUVCeE1KVUdGc2J5QkJiSFJ2TVI4d0hRWURWUVFLRXhaVGRXNGdUV2xqY205emVYTjBcbiIKKyAgICAgICAgICAgICsgIlpXMXpMQ0JKYm1NdU1TRXdId1lEVlFRTEV4aFVaWE4wSUdGdVpDQkZkbUZzZFdGMGFXOXVJRTl1YkhreEdqQVlcbiIKKyAgICAgICAgICAgICsgIkJnTlZCQU1URVdGeVoyOXVMbVZ1Wnk1emRXNHVZMjl0TUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JcbiIKKyAgICAgICAgICAgICsgImlRS0JnUUNvZm1kWStQaVVXTjAxRk96RWV3ZitHYUcrbEZmMTMyVXB6QVRtWUprQTRBRUEvanVXN2pTaStMSmtcbiIKKyAgICAgICAgICAgICsgIndKS2k1R080Unlab3lpbUFMLzV5SVdEVjZsMUtsdnh5S3NscjBSRWhNQmFELzNaM0VzTFRURWY1Z1ZyUVM2c1RcbiIKKyAgICAgICAgICAgICsgIldNb1NaQXl6QjM5a0Zmc0I2b1VYTnRWOCtVS0t4U3hLYnh2aFFuMjY3UGVDejVWWDJRSURBUUFCTUEwR0NTcUdcbiIKKyAgICAgICAgICAgICsgIlNJYjNEUUVCQWdVQUEzNEFYbDNhdDZsdWlWLzdJOU1ONUNYWW9QSllJOEJjZGMxaEJhZ0p2VE1jbWxxTDJ1T1pcbiIKKyAgICAgICAgICAgICsgIkg5VDVoTk1FTDlUazZhSTd5WlBYY3cveEkySzZwT1IvRnJNcDBVd0ptZHhYN2xqVjZadFVaZjdwWTQ5MlVxd0NcbiIKKyAgICAgICAgICAgICsgIjE3NzdYUTlVRVp5cktKdkY1bnRsZWVPMGF5QnFMR1ZLQ1d6V1pYOVlzWENwdjQ3Rk5MWmJ1cEU9XG4iCisgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iOworCisgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gY2VydEFycmF5ID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNlcnRpZmljYXRlLmdldEJ5dGVzKCkpOworCisgICAgU3RyaW5nIGNlcnRpZmljYXRlMiA9ICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICsgIk1JSUNaekNDQWRDZ0F3SUJBZ0lCR3pBTkJna3Foa2lHOXcwQkFRVUZBREJoTVFzd0NRWURWUVFHRXdKVlV6RVlcbiIKKyAgICAgICAgICAgICsgIk1CWUdBMVVFQ2hNUFZTNVRMaUJIYjNabGNtNXRaVzUwTVF3d0NnWURWUVFMRXdORWIwUXhEREFLQmdOVkJBc1RcbiIKKyAgICAgICAgICAgICsgIkExQkxTVEVjTUJvR0ExVUVBeE1UUkc5RUlGQkxTU0JOWldRZ1VtOXZkQ0JEUVRBZUZ3MDVPREE0TURNeU1qQXlcbiIKKyAgICAgICAgICAgICsgIk1qbGFGdzB3T0RBNE1EUXlNakF5TWpsYU1HRXhDekFKQmdOVkJBWVRBbFZUTVJnd0ZnWURWUVFLRXc5VkxsTXVcbiIKKyAgICAgICAgICAgICsgIklFZHZkbVZ5Ym0xbGJuUXhEREFLQmdOVkJBc1RBMFJ2UkRFTU1Bb0dBMVVFQ3hNRFVFdEpNUnd3R2dZRFZRUURcbiIKKyAgICAgICAgICAgICsgIkV4TkViMFFnVUV0SklFMWxaQ0JTYjI5MElFTkJNSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdOQURDQmlRS0JcbiIKKyAgICAgICAgICAgICsgImdRRGJyTS9KOUZySlNYK3p4RlVic0k5Vnc1UWJndVZCSWE5NXJ3Vy8wTTgrc00wcjVnZCtEWTZpdWJtNnduWGtcbiIKKyAgICAgICAgICAgICsgIkNTdmJmUWxGRURTS3I0V1llZUdwK2Q5V2xEblFkdERGTGRBNDV0Q2k1U0hqblcraEdBbVpubGQwcno2d1Fla0ZcbiIKKyAgICAgICAgICAgICsgIjV4UWFhNUE2d2poTWxMT2piaDI3enlzY3Jvck1KMU81RkJPV25FSGNSdjZ4cVFJREFRQUJveTh3TFRBZEJnTlZcbiIKKyAgICAgICAgICAgICsgIkhRNEVGZ1FVVnJtWVI2bTk3MDFjSFEzcjVrWHlHN3pzQ04wd0RBWURWUjBUQkFVd0F3RUIvekFOQmdrcWhraUdcbiIKKyAgICAgICAgICAgICsgIjl3MEJBUVVGQUFPQmdRRFZYMVkwWXFDN3Zla2VaalZ4dHl1QzhNbnhicno2RDEwOUFYMDdMRUlSek5ZendaMHdcbiIKKyAgICAgICAgICAgICsgIk1USW1TcDlzRXpXVyszRnVlQklVN0F4R3lzMk83WDBxbU4zemdzelBmU2lvY0J1UXVYSVlRY3RKaEtqRjVLVmNcbiIKKyAgICAgICAgICAgICsgIlZHUVJZWWx0K215aGwydnk2eVB6RVZDamlLd01FYjFTcHUwaXJDZitsRlcyaHNkanZtU1FNdFp2T3c9PVxuIgorICAgICAgICAgICAgKyAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLVxuIjsKKworICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGNlcnRBcnJheTIgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oY2VydGlmaWNhdGUyLmdldEJ5dGVzKCkpOworCisgICAgU3RyaW5nIGNlcnRpZmljYXRlMyA9ICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICsgIk1JSURYRENDQXNXZ0F3SUJBZ0lCU2pBTkJna3Foa2lHOXcwQkFRVUZBREJXTVFzd0NRWURWUVFHRXdKVlV6RVlcbiIKKyAgICAgICAgICAgICsgIk1CWUdBMVVFQ2hNUFZTNVRMaUJIYjNabGNtNXRaVzUwTVF3d0NnWURWUVFMRXdORWIwUXhEREFLQmdOVkJBc1RcbiIKKyAgICAgICAgICAgICsgIkExQkxTVEVSTUE4R0ExVUVBeE1JVFdWa0lFTkJMVEV3SGhjTk9UZ3dPREF5TVRnd01qUXdXaGNOTURFd09EQXlcbiIKKyAgICAgICAgICAgICsgIk1UZ3dNalF3V2pCME1Rc3dDUVlEVlFRR0V3SlZVekVZTUJZR0ExVUVDaE1QVlM1VExpQkhiM1psY201dFpXNTBcbiIKKyAgICAgICAgICAgICsgIk1Rd3dDZ1lEVlFRTEV3TkViMFF4RERBS0JnTlZCQXNUQTFCTFNURU5NQXNHQTFVRUN4TUVWVk5CUmpFZ01CNEdcbiIKKyAgICAgICAgICAgICsgIkExVUVBeE1YUjNWdFlua3VTbTl6WlhCb0xqQXdNREF3TURVd05EUXdnWjh3RFFZSktvWklodmNOQVFFQkJRQURcbiIKKyAgICAgICAgICAgICsgImdZMEFNSUdKQW9HQkFMVC9SN2JQcXMxYzFZcVhBZzVITnBaTGdXMkh1QWM3UkNhUDA2Y0U0UjQ0R0JMdy9mUWNcbiIKKyAgICAgICAgICAgICsgIlZSTkxuNXBnYlRYc0RuamlaVmQ4cUVnWXFqS0ZRa2E0L3ROaGFGN05vMnRCWkIrb1lML2VQMElXdFAraC9XNkRcbiIKKyAgICAgICAgICAgICsgIktSNStVdklJZGdteDdrM3Q5anAyUTUxSnBIaGhLRWI5V041NHRyQ085WXU3UFlVK0xJODVqRUlCQWdNQkFBR2pcbiIKKyAgICAgICAgICAgICsgImdnRWFNSUlCRmpBV0JnTlZIU0FFRHpBTk1Bc0dDV0NHU0FGbEFnRUxBekFmQmdOVkhTTUVHREFXZ0JRek9oVG9cbiIKKyAgICAgICAgICAgICsgIkNXZGhpR1VrSU94NWNFTFhwcE1lOWpBZEJnTlZIUTRFRmdRVWtMQkpsK2F5S2d6T3Avd3dCWDlNMWxTa0NnNHdcbiIKKyAgICAgICAgICAgICsgIkRnWURWUjBQQVFIL0JBUURBZ2JBTUF3R0ExVWRFd0VCL3dRQ01BQXdnWjBHQTFVZEh3U0JsVENCa2pDQmo2Q0JcbiIKKyAgICAgICAgICAgICsgImpLQ0JpWWFCaG14a1lYQTZMeTlrY3kweExtTm9ZVzFpTG1ScGMyRXViV2xzTDJOdUpUTmtUV1ZrSlRJd1EwRWxcbiIKKyAgICAgICAgICAgICsgIk1tUXhKVEpqYjNVbE0yUlFTMGtsTW1OdmRTVXpaRVJ2UkNVeVkyOGxNMlJWTGxNdUpUSXdSMjkyWlhKdWJXVnVcbiIKKyAgICAgICAgICAgICsgImRDVXlZMk1sTTJSVlV6OWpaWEowYVdacFkyRjBaVkpsZG05allYUnBiMjVNYVhOMEpUTmlZbWx1WVhKNU1BMEdcbiIKKyAgICAgICAgICAgICsgIkNTcUdTSWIzRFFFQkJRVUFBNEdCQUZqYXB1REhNdklkVWVZUnlFWWRTaEJSMUpaQzIwdEozTVFueUJRdmVkZHpcbiIKKyAgICAgICAgICAgICsgIkxHRkRHcElrUkFRVTdULzUvbmU4bE1leHl4VmlDMjF4T2xLOUxkYkpDYlZ5eXd2Yjl1RW0vMWplOXdpZVFRdHJcbiIKKyAgICAgICAgICAgICsgImtqeWt1QitXQjZxVENJc2xBTy9lVW1nemZ6SUVOdm5IOE8rZkg3UVRyMlBka0ZraVBJcUJKWUh2dzdGM1hEcXlcbiIKKyAgICAgICAgICAgICsgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cbiI7CisKKyAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBjZXJ0QXJyYXkzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNlcnRpZmljYXRlMy5nZXRCeXRlcygpKTsKKworICAgIHByaXZhdGUgYnl0ZVtdIGNyZWF0Q2VydGlmaWNhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydFtdID0gbmV3IFg1MDlDZXJ0aWZpY2F0ZVsyXTsKKyAgICAgICAgY2VydFswXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5KTsKKyAgICAgICAgY2VydFsxXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5Mik7CisgICAgICAgIEtleVN0b3JlIGtleVRlc3QgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAga2V5VGVzdC5sb2FkKG51bGwsIG51bGwpOworICAgICAgICAvLyBhbGlhcyAxCisgICAgICAgIGtleVRlc3Quc2V0Q2VydGlmaWNhdGVFbnRyeSgiYWxpYXMxIiwgY2VydFswXSk7CisKKyAgICAgICAgLy8gYWxpYXMgMgorICAgICAgICBrZXlUZXN0LnNldEtleUVudHJ5KCJhbGlhczIiLCBnZXRQcml2YXRlS2V5KCksIHBzc1dvcmQsIGNlcnQpOworCisgICAgICAgIC8vIGFsaWFzIDMKKyAgICAgICAga2V5VGVzdC5zZXRDZXJ0aWZpY2F0ZUVudHJ5KCJhbGlhczMiLCBjZXJ0WzFdKTsKKworICAgICAgICBvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIGtleVRlc3Quc3RvcmUob3V0LCBwc3NXb3JkKTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisKKyAgICAgICAgcmV0dXJuIG91dC50b0J5dGVBcnJheSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuS2V5U3RvcmUjYWxpYXNlcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hbGlhc2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuRW51bWVyYXRpb24KKyAgICAgICAgLy8gamF2YS5zZWN1cml0eS5LZXlTdG9yZS5hbGlhc2VzKCkKKyAgICAgICAgLy8gTk9UIENPTVBBVElCTEUgV0lUSCBQQ1MjMTIKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydFtdID0gbmV3IFg1MDlDZXJ0aWZpY2F0ZVsyXTsKKyAgICAgICAgY2VydFswXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5KTsKKyAgICAgICAgY2VydFsxXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5Mik7CisgICAgICAgIEtleVN0b3JlIGtleVRlc3QgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5VGVzdC5hbGlhc2VzKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBrZXlUZXN0LmxvYWQobnVsbCwgbnVsbCk7CisKKyAgICAgICAgLy8gS2V5U3RvcmUga2V5VGVzdCA9CisgICAgICAgIC8vIEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICAvLyBhbGlhcyAxCisgICAgICAgIGtleVRlc3Quc2V0Q2VydGlmaWNhdGVFbnRyeSgiYWxpYXMxIiwgY2VydFswXSk7CisKKyAgICAgICAgLy8gYWxpYXMgMgorICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMiIsIGNlcnRbMF0pOworCisgICAgICAgIC8vIGFsaWFzIDMKKyAgICAgICAga2V5VGVzdC5zZXRDZXJ0aWZpY2F0ZUVudHJ5KCJhbGlhczMiLCBjZXJ0WzBdKTsKKworICAgICAgICAvLyBvYnRhaW5pbmcgdGhlIGFsaWFzZQorICAgICAgICBFbnVtZXJhdGlvbjxTdHJpbmc+IGFsaWFzZSA9IGtleVRlc3QuYWxpYXNlcygpOworICAgICAgICBTZXQ8U3RyaW5nPiBhbGlhID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgIHdoaWxlIChhbGlhc2UuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIGFsaWEuYWRkKGFsaWFzZS5uZXh0RWxlbWVudCgpKTsKKyAgICAgICAgICAgIGkrKzsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoInRoZSB3cm9uZyBhbGlhc2VzIHdlcmUgcmV0dXJuZWQiLCBpLCAzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhlIHdyb25nIGFsaWFzZXMgd2VyZSByZXR1cm5lZCIsIGFsaWEuY29udGFpbnMoImFsaWFzMSIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhlIHdyb25nIGFsaWFzZXMgd2VyZSByZXR1cm5lZCIsIGFsaWEuY29udGFpbnMoImFsaWFzMiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhlIHdyb25nIGFsaWFzZXMgd2VyZSByZXR1cm5lZCIsIGFsaWEuY29udGFpbnMoImFsaWFzMyIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LktleVN0b3JlI2NvbnRhaW5zQWxpYXMoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbnRhaW5zQWxpYXNMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbgorICAgICAgICAvLyBqYXZhLnNlY3VyaXR5LktleVN0b3JlLmNvbnRhaW5zQWxpYXMoamF2YS5sYW5nLlN0cmluZykKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydFtdID0gbmV3IFg1MDlDZXJ0aWZpY2F0ZVsyXTsKKyAgICAgICAgY2VydFswXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5KTsKKyAgICAgICAgY2VydFsxXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5Mik7CisgICAgICAgIEtleVN0b3JlIGtleVRlc3QgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5VGVzdC5jb250YWluc0FsaWFzKCJhbGlhczEiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGtleVRlc3QubG9hZChudWxsLCBudWxsKTsKKworICAgICAgICAvLyBhbGlhcyAxCisgICAgICAgIGtleVRlc3Quc2V0Q2VydGlmaWNhdGVFbnRyeSgiYWxpYXMxIiwgY2VydFswXSk7CisKKyAgICAgICAgLy8gYWxpYXMgMgorICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMiIsIGNlcnRbMF0pOworCisgICAgICAgIGFzc2VydFRydWUoImFsaWFzMSBkb2VzIG5vdCBleGlzdCIsIGtleVRlc3QuY29udGFpbnNBbGlhcygiYWxpYXMxIikpOworICAgICAgICBhc3NlcnRUcnVlKCJhbGlhczIgZG9lcyBub3QgZXhpc3QiLCBrZXlUZXN0LmNvbnRhaW5zQWxpYXMoImFsaWFzMiIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoImFsaWFzMyBleGlzdHMiLCBrZXlUZXN0LmNvbnRhaW5zQWxpYXMoImFsaWFzMyIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5VGVzdC5jb250YWluc0FsaWFzKG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5LZXlTdG9yZSNnZXRDZXJ0aWZpY2F0ZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Q2VydGlmaWNhdGVMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlCisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuS2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGUoamF2YS5sYW5nLlN0cmluZykKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydFtdID0gbmV3IFg1MDlDZXJ0aWZpY2F0ZVsyXTsKKyAgICAgICAgY2VydFswXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5KTsKKyAgICAgICAgY2VydFsxXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5Mik7CisgICAgICAgIEtleVN0b3JlIGtleVRlc3QgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5VGVzdC5nZXRDZXJ0aWZpY2F0ZSgiYW5BbGlhcyIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAga2V5VGVzdC5sb2FkKG51bGwsIG51bGwpOworCisgICAgICAgIC8vIGFsaWFzIDEKKyAgICAgICAgUHVibGljS2V5IHB1YiA9IGNlcnRbMF0uZ2V0UHVibGljS2V5KCk7CisgICAgICAgIGtleVRlc3Quc2V0Q2VydGlmaWNhdGVFbnRyeSgiYWxpYXMxIiwgY2VydFswXSk7CisKKyAgICAgICAgQ2VydGlmaWNhdGUgY2VydFJlcyA9IGtleVRlc3QuZ2V0Q2VydGlmaWNhdGUoImFsaWFzMSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRoZSBwdWJsaWMga2V5IG9mIHRoZSBjZXJ0aWZpY2F0ZSBmcm9tIGdldENlcnRpZmljYXRlKCkgIgorICAgICAgICAgICAgICAgICAgICAgKyAiZGlkIG5vdCBlcXVhbCB0aGUgb3JpZ2luYWwgY2VydGlmaWNhdGUiLAorICAgICAgICAgICAgICAgICAgICAgcHViLCBjZXJ0UmVzLmdldFB1YmxpY0tleSgpKTsKKworICAgICAgICAvLyBhbGlhcyAyCisgICAgICAgIGtleVRlc3Quc2V0Q2VydGlmaWNhdGVFbnRyeSgiYWxpYXMyIiwgY2VydFswXSk7CisKKyAgICAgICAgLy8gdGVzdGluZyBmb3IgYSBjZXJ0aWZpY2F0ZSBjaGFpbgorICAgICAgICBDZXJ0aWZpY2F0ZSBjZXJ0MiA9IGtleVRlc3QuZ2V0Q2VydGlmaWNhdGUoImFsaWFzMiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRoZSBjZXJ0aWZpY2F0ZSBmb3IgYWxpYXMyIGlzIHN1cHBvc2VkIHRvIGV4aXN0IiwKKyAgICAgICAgICAgICAgICAgICAgIGNlcnQyLCBjZXJ0WzBdKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuS2V5U3RvcmUjZ2V0Q2VydGlmaWNhdGVBbGlhcyhqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDZXJ0aWZpY2F0ZUFsaWFzTGphdmFfc2VjdXJpdHlfY2VydF9DZXJ0aWZpY2F0ZSgpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcKKyAgICAgICAgLy8gamF2YS5zZWN1cml0eS5LZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZUFsaWFzKGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZSkKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydFtdID0gbmV3IFg1MDlDZXJ0aWZpY2F0ZVsyXTsKKyAgICAgICAgY2VydFswXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5KTsKKyAgICAgICAgY2VydFsxXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5Mik7CisgICAgICAgIEtleVN0b3JlIGtleVRlc3QgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAga2V5VGVzdC5sb2FkKG51bGwsIG51bGwpOworCisgICAgICAgIC8vIGNlcnRpZmljYXRlIGVudHJ5CisgICAgICAgIGtleVRlc3Quc2V0Q2VydGlmaWNhdGVFbnRyeSgiYWxpYXMxIiwgY2VydFsxXSk7CisgICAgICAgIFN0cmluZyBhbGlhcyA9IGtleVRlc3QuZ2V0Q2VydGlmaWNhdGVBbGlhcyhjZXJ0WzFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjZXJ0aWZpY2F0ZSBlbnRyeSAtIHRoZSBhbGlhcyByZXR1cm5lZCBmb3IgdGhpcyBjZXJ0aWZpY2F0ZSB3YXMgd3JvbmciLAorICAgICAgICAgICAgICAgICAgICAgImFsaWFzMSIsIGFsaWFzKTsKKworICAgICAgICAvLyBrZXkgZW50cnkKKworICAgICAgICBrZXlUZXN0LnNldEtleUVudHJ5KCJhbGlhczIiLCBnZXRQcml2YXRlS2V5KCksIHBzc1dvcmQsIGNlcnQpOworICAgICAgICBhbGlhcyA9IGtleVRlc3QuZ2V0Q2VydGlmaWNhdGVBbGlhcyhjZXJ0WzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJrZXkgZW50cnkgLSB0aGUgYWxpYXMgcmV0dXJuZWQgZm9yIHRoaXMgY2VydGlmaWNhdGUgd2FzIHdyb25nIiwKKyAgICAgICAgICAgICAgICAgICAgICJhbGlhczIiLCBhbGlhcyk7CisKKyAgICAgICAgLy8gdGVzdGluZyBjYXNlIHdpdGggYSBub25leGlzdGVudCBjZXJ0aWZpY2F0ZQorICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydDIgPSAoWDUwOUNlcnRpZmljYXRlKSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKGNlcnRBcnJheTMpOworICAgICAgICBTdHJpbmcgYWxpYXNOdWxsID0ga2V5VGVzdC5nZXRDZXJ0aWZpY2F0ZUFsaWFzKGNlcnQyKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgidGhlIGFsaWFzIHJldHVybmVkIGZvciB0aGUgbm9uZXhpc3QgY2VydGlmaWNhdGUgd2FzIE5PVCBudWxsIiwgYWxpYXNOdWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LktleVN0b3JlI2dldENlcnRpZmljYXRlQ2hhaW4oamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldENlcnRpZmljYXRlQ2hhaW5MamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlW10KKyAgICAgICAgLy8gamF2YS5zZWN1cml0eS5LZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZUNoYWluKGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIC8vIGNyZWF0Q2VydGlmaWNhdGUoKTsKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydFtdID0gbmV3IFg1MDlDZXJ0aWZpY2F0ZVsyXTsKKyAgICAgICAgY2VydFswXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5KTsKKyAgICAgICAgY2VydFsxXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5Mik7CisgICAgICAgIEtleVN0b3JlIGtleVRlc3QgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5VGVzdC5nZXRDZXJ0aWZpY2F0ZUNoYWluKCJhbkFsaWFzIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBrZXlUZXN0LmxvYWQobnVsbCwgbnVsbCk7CisKKyAgICAgICAgLy8gYWxpYXMgMQorICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMSIsIGNlcnRbMF0pOworCisgICAgICAgIC8vIGFsaWFzIDIKKyAgICAgICAga2V5VGVzdC5zZXRLZXlFbnRyeSgiYWxpYXMyIiwgZ2V0UHJpdmF0ZUtleSgpLCBwc3NXb3JkLCBjZXJ0KTsKKworICAgICAgICBDZXJ0aWZpY2F0ZVtdIGNlcnRSZXMgPSBrZXlUZXN0LmdldENlcnRpZmljYXRlQ2hhaW4oImFsaWFzMiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRoZXJlIGFyZSBtb3JlIHRoYW4gdHdvIGNlcnRpZmljYXRlIHJldHVybmVkIGZyb20gZ2V0Q2VydGlmaWNhdGVDaGFpbiIsCisgICAgICAgICAgICAgICAgICAgICAyLCBjZXJ0UmVzLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygidGhlIGZpcnN0IGNlcnRpZmljYXRlIHJldHVybmVkIGZyb20gZ2V0Q2VydGlmaWNhdGVDaGFpbiBpcyBub3QgY29ycmVjdCIsCisgICAgICAgICAgICAgICAgICAgICBjZXJ0WzBdLmdldFB1YmxpY0tleSgpLCBjZXJ0UmVzWzBdLmdldFB1YmxpY0tleSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0aGUgc2Vjb25kIGNlcnRpZmljYXRlIHJldHVybmVkIGZyb20gZ2V0Q2VydGlmaWNhdGVDaGFpbiBpcyBub3QgY29ycmVjdCIsCisgICAgICAgICAgICAgICAgICAgICBjZXJ0WzFdLmdldFB1YmxpY0tleSgpLCBjZXJ0UmVzWzFdLmdldFB1YmxpY0tleSgpKTsKKyAgICAgICAgQ2VydGlmaWNhdGVbXSBjZXJ0UmVzTnVsbCA9IGtleVRlc3QuZ2V0Q2VydGlmaWNhdGVDaGFpbigiYWxpYXMxIik7CisgICAgICAgIGFzc2VydE51bGwoInRoZSBjZXJ0aWZpY2F0ZSBjaGFpbiByZXR1cm5lZCBmcm9tIGdldENlcnRpZmljYXRlQ2hhaW4gaXMgTk9UIG51bGwiLAorICAgICAgICAgICAgICAgICAgIGNlcnRSZXNOdWxsKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5VGVzdC5nZXRDZXJ0aWZpY2F0ZUNoYWluKG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LktleVN0b3JlI2dldEluc3RhbmNlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnNlY3VyaXR5LktleVN0b3JlCisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuS2V5U3RvcmUuZ2V0SW5zdGFuY2UoamF2YS5sYW5nLlN0cmluZykKKyAgICAgICAgS2V5U3RvcmUga2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRoZSBtZXRob2QgZ2V0SW5zdGFuY2UgZGlkIG5vdCBvYnRhaW4gdGhlIGNvcnJlY3QgdHlwZSIsCisgICAgICAgICAgICAgICAgICAgICBLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpLCBrZXlUZXN0LmdldFR5cGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5LZXlTdG9yZSNnZXRLZXkoamF2YS5sYW5nLlN0cmluZywgY2hhcltdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0S2V5TGphdmFfbGFuZ19TdHJpbmckQygpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnNlY3VyaXR5LktleQorICAgICAgICAvLyBqYXZhLnNlY3VyaXR5LktleVN0b3JlLmdldEtleShqYXZhLmxhbmcuU3RyaW5nLCBjaGFyW10pCisgICAgICAgIC8vIGNyZWF0Q2VydGlmaWNhdGUoKTsKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydFtdID0gbmV3IFg1MDlDZXJ0aWZpY2F0ZVsyXTsKKyAgICAgICAgY2VydFswXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5KTsKKyAgICAgICAgY2VydFsxXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5Mik7CisgICAgICAgIEtleVN0b3JlIGtleVRlc3QgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAga2V5VGVzdC5sb2FkKG51bGwsIG51bGwpOworCisgICAgICAgIGtleVRlc3Quc2V0S2V5RW50cnkoImFsaWFzMiIsIGdldFByaXZhdGVLZXkoKSwgcHNzV29yZCwgY2VydCk7CisgICAgICAgIFByaXZhdGVLZXkgcmV0dXJuZWRLZXkgPSAoUHJpdmF0ZUtleSkga2V5VGVzdC5nZXRLZXkoImFsaWFzMiIsIHBzc1dvcmQpOworICAgICAgICBieXRlW10gcmV0QiA9IHJldHVybmVkS2V5LmdldEVuY29kZWQoKTsKKyAgICAgICAgYnl0ZVtdIHByaUIgPSBnZXRQcml2YXRlS2V5KCkuZ2V0RW5jb2RlZCgpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMocmV0QiwgcHJpQikpOworICAgICAgICBhc3NlcnRFcXVhbHMoZ2V0UHJpdmF0ZUtleSgpLmdldEFsZ29yaXRobSgpLCByZXR1cm5lZEtleS5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhnZXRQcml2YXRlS2V5KCkuZ2V0Rm9ybWF0KCksIHJldHVybmVkS2V5LmdldEZvcm1hdCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5VGVzdC5nZXRLZXkoImFsaWFzMiIsICJ3cm9uZyIudG9DaGFyQXJyYXkoKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGtleVRlc3Quc2V0Q2VydGlmaWNhdGVFbnRyeSgiYWxpYXMxIiwgY2VydFsxXSk7CisgICAgICAgIGFzc2VydE51bGwoInRoZSBwcml2YXRlIGtleSByZXR1cm5lZCBmcm9tIGdldEtleSBmb3IgYSBjZXJ0aWZpY2F0ZSBlbnRyeSBpcyBub3QgbnVsbCIsCisgICAgICAgICAgICAgICAgICAga2V5VGVzdC5nZXRLZXkoImFsaWFzMSIsIHBzc1dvcmQpKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuS2V5U3RvcmUjaXNDZXJ0aWZpY2F0ZUVudHJ5KGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0NlcnRpZmljYXRlRW50cnlMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbgorICAgICAgICAvLyBqYXZhLnNlY3VyaXR5LktleVN0b3JlLmlzQ2VydGlmaWNhdGVFbnRyeShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0W10gPSBuZXcgWDUwOUNlcnRpZmljYXRlWzJdOworICAgICAgICBjZXJ0WzBdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkpOworICAgICAgICBjZXJ0WzFdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkyKTsKKyAgICAgICAgS2V5U3RvcmUga2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlUZXN0LmlzQ2VydGlmaWNhdGVFbnRyeSgiYWxpYXMiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGtleVRlc3QubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgLy8gYWxpYXMgMQorICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMSIsIGNlcnRbMF0pOworCisgICAgICAgIC8vIGFsaWFzIDIKKyAgICAgICAga2V5VGVzdC5zZXRLZXlFbnRyeSgiYWxpYXMyIiwgZ2V0UHJpdmF0ZUtleSgpLCBwc3NXb3JkLCBjZXJ0KTsKKworICAgICAgICBhc3NlcnRUcnVlKCJpc0NlcnRpZmljYXRlRW50cnkgbWV0aG9kIHJldHVybnMgZmFsc2UgZm9yIGEgY2VydGlmaWNhdGUiLAorICAgICAgICAgICAgICAgICAgIGtleVRlc3QuaXNDZXJ0aWZpY2F0ZUVudHJ5KCJhbGlhczEiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJpc0NlcnRpZmljYXRlRW50cnkgbWV0aG9kIHJldHVybnMgdHJ1ZSBmb3Igbm9uY2VydGlmaWNhdGUiLAorICAgICAgICAgICAgICAgICAgICBrZXlUZXN0LmlzQ2VydGlmaWNhdGVFbnRyeSgiYWxpYXMyIikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuS2V5U3RvcmUjaXNLZXlFbnRyeShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNLZXlFbnRyeUxqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuCisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuS2V5U3RvcmUuaXNLZXlFbnRyeShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0W10gPSBuZXcgWDUwOUNlcnRpZmljYXRlWzJdOworICAgICAgICBjZXJ0WzBdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkpOworICAgICAgICBjZXJ0WzFdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkyKTsKKyAgICAgICAgS2V5U3RvcmUga2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlUZXN0LmlzS2V5RW50cnkoImFsaWFzIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBrZXlUZXN0LmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgIC8vIGFsaWFzIDEKKyAgICAgICAga2V5VGVzdC5zZXRDZXJ0aWZpY2F0ZUVudHJ5KCJhbGlhczEiLCBjZXJ0WzBdKTsKKworICAgICAgICAvLyBhbGlhcyAyCisgICAgICAgIGtleVRlc3Quc2V0S2V5RW50cnkoImFsaWFzMiIsIGdldFByaXZhdGVLZXkoKSwgcHNzV29yZCwgY2VydCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaXNLZXlFbnRyeSBtZXRob2QgcmV0dXJucyBmYWxzZSBmb3IgYSBjZXJ0aWZpY2F0ZSIsCisgICAgICAgICAgICAgICAgICAga2V5VGVzdC5pc0tleUVudHJ5KCJhbGlhczIiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJpc0tleUVudHJ5IG1ldGhvZCByZXR1cm5zIHRydWUgZm9yIG5vbmNlcnRpZmljYXRlIiwKKyAgICAgICAgICAgICAgICAgICAga2V5VGVzdC5pc0tleUVudHJ5KCJhbGlhczEiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5LZXlTdG9yZSNsb2FkKGphdmEuaW8uSW5wdXRTdHJlYW0sIGNoYXJbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xvYWRMamF2YV9pb19JbnB1dFN0cmVhbSRDKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEuc2VjdXJpdHkuS2V5U3RvcmUubG9hZChqYXZhLmlvLklucHV0U3RyZWFtLAorICAgICAgICAvLyBjaGFyW10pCisgICAgICAgIGJ5dGVbXSBrZXlTdG9yZSA9IGNyZWF0Q2VydGlmaWNhdGUoKTsKKyAgICAgICAgS2V5U3RvcmUga2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShrZXlTdG9yZSk7CisgICAgICAgIGtleVRlc3QubG9hZChpbiwgcHNzV29yZCk7CisgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIGFzc2VydFRydWUoImFsaWFzMSBpcyBub3QgYSBjZXJ0aWZpY2F0ZSIsIGtleVRlc3QuaXNDZXJ0aWZpY2F0ZUVudHJ5KCJhbGlhczEiKSk7CisgICAgICAgIGFzc2VydFRydWUoImFsaWFzMiBpcyBub3QgYSBrZXlFbnRyeSIsIGtleVRlc3QuaXNLZXlFbnRyeSgiYWxpYXMyIikpOworICAgICAgICBhc3NlcnRUcnVlKCJhbGlhczMgaXMgbm90IGEgY2VydGlmaWNhdGUiLCBrZXlUZXN0LmlzQ2VydGlmaWNhdGVFbnRyeSgiYWxpYXMzIikpOworCisgICAgICAgIC8vIHRlc3Qgd2l0aCBudWxsIHBhc3N3b3JkCisgICAgICAgIGtleVRlc3QgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAgaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oa2V5U3RvcmUpOworICAgICAgICBrZXlUZXN0LmxvYWQoaW4sIG51bGwpOworICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJhbGlhczEgaXMgbm90IGEgY2VydGlmaWNhdGUiLCBrZXlUZXN0LmlzQ2VydGlmaWNhdGVFbnRyeSgiYWxpYXMxIikpOworICAgICAgICBhc3NlcnRUcnVlKCJhbGlhczIgaXMgbm90IGEga2V5RW50cnkiLCBrZXlUZXN0LmlzS2V5RW50cnkoImFsaWFzMiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiYWxpYXMzIGlzIG5vdCBhIGNlcnRpZmljYXRlIiwga2V5VGVzdC5pc0NlcnRpZmljYXRlRW50cnkoImFsaWFzMyIpKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuS2V5U3RvcmUjbG9hZChLZXlTdG9yZS5Mb2FkU3RvcmVQYXJhbWV0ZXIgcGFyYW0pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9sb2FkTGphdmFfc2VjdXJpdHlfS2V5U3RvcmVMb2FkU3RvcmVQYXJhbWV0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5U3RvcmUuZ2V0SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSkubG9hZChudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LktleVN0b3JlI3NldENlcnRpZmljYXRlRW50cnkoamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0Q2VydGlmaWNhdGVFbnRyeUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfc2VjdXJpdHlfY2VydF9DZXJ0aWZpY2F0ZSgpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQKKyAgICAgICAgLy8gamF2YS5zZWN1cml0eS5LZXlTdG9yZS5zZXRDZXJ0aWZpY2F0ZUVudHJ5KGphdmEubGFuZy5TdHJpbmcsCisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZSkKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydCA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5KTsKKyAgICAgICAgS2V5U3RvcmUga2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzIiwgY2VydCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBrZXlUZXN0LmxvYWQobnVsbCwgbnVsbCk7CisKKyAgICAgICAgUHVibGljS2V5IHB1YiA9IGNlcnQuZ2V0UHVibGljS2V5KCk7CisgICAgICAgIGtleVRlc3Quc2V0Q2VydGlmaWNhdGVFbnRyeSgiYWxpYXMxIiwgY2VydCk7CisgICAgICAgIGFzc2VydFRydWUoInRoZSBlbnRyeSBzcGVjaWZpZWQgYnkgdGhlIGFsaWFzIGFsaWFzMSBpcyBub3QgYSBjZXJ0aWZpY2F0ZSIsCisgICAgICAgICAgICAgICAgICAga2V5VGVzdC5pc0NlcnRpZmljYXRlRW50cnkoImFsaWFzMSIpKTsKKyAgICAgICAgQ2VydGlmaWNhdGUgcmVzdWx0Q2VydCA9IGtleVRlc3QuZ2V0Q2VydGlmaWNhdGUoImFsaWFzMSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRoZSBwdWJsaWMga2V5IG9mIHRoZSBjZXJ0aWZpY2F0ZSBmcm9tIGdldENlcnRpZmljYXRlKCkgIgorICAgICAgICAgICAgICAgICAgICAgKyAiZGlkIG5vdCBlcXVhbCB0aGUgb3JpZ2luYWwgY2VydGlmaWNhdGUiLAorICAgICAgICAgICAgICAgICAgICAgcHViLCByZXN1bHRDZXJ0LmdldFB1YmxpY0tleSgpKTsKKworCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5LZXlTdG9yZSNzZXRLZXlFbnRyeShqYXZhLmxhbmcuU3RyaW5nLAorICAgICAqICAgICAgICBqYXZhLnNlY3VyaXR5LktleSwgY2hhcltdLCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEtleUVudHJ5TGphdmFfbGFuZ19TdHJpbmdMamF2YV9zZWN1cml0eV9LZXkkQyRMamF2YV9zZWN1cml0eV9jZXJ0X0NlcnRpZmljYXRlKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkCisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuS2V5U3RvcmUuc2V0S2V5RW50cnkoamF2YS5sYW5nLlN0cmluZywKKyAgICAgICAgLy8gamF2YS5zZWN1cml0eS5LZXksIGNoYXJbXSwgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlW10pCisKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydFtdID0gbmV3IFg1MDlDZXJ0aWZpY2F0ZVsyXTsKKyAgICAgICAgY2VydFswXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5KTsKKyAgICAgICAgY2VydFsxXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5Mik7CisgICAgICAgIEtleVN0b3JlIGtleVRlc3QgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5VGVzdC5zZXRLZXlFbnRyeSgiYWxpYXMzIiwgZ2V0UHJpdmF0ZUtleSgpLCBwc3NXb3JkLCBjZXJ0KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGtleVRlc3QubG9hZChudWxsLCBudWxsKTsKKworICAgICAgICBrZXlUZXN0LnNldEtleUVudHJ5KCJhbGlhczMiLCBnZXRQcml2YXRlS2V5KCksIHBzc1dvcmQsIGNlcnQpOworICAgICAgICBhc3NlcnRUcnVlKCJ0aGUgZW50cnkgc3BlY2lmaWVkIGJ5IHRoZSBhbGlhcyBhbGlhczMgaXMgbm90IGEga2V5RW50cnkiLAorICAgICAgICAgICAgICAgICAgIGtleVRlc3QuaXNLZXlFbnRyeSgiYWxpYXMzIikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlUZXN0LnNldEtleUVudHJ5KCJhbGlhczQiLCBnZXRQcml2YXRlS2V5KCksIHBzc1dvcmQsIG5ldyBDZXJ0aWZpY2F0ZVtdIHt9KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuS2V5U3RvcmUjc2l6ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zaXplKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZS5zaXplKCkKKworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0W10gPSBuZXcgWDUwOUNlcnRpZmljYXRlWzJdOworICAgICAgICBjZXJ0WzBdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkpOworICAgICAgICBjZXJ0WzFdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkyKTsKKyAgICAgICAgS2V5U3RvcmUga2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlUZXN0LnNpemUoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGtleVRlc3QubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgLy8gYWxpYXMgMQorICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMSIsIGNlcnRbMF0pOworCisgICAgICAgIC8vIGFsaWFzIDIKKyAgICAgICAga2V5VGVzdC5zZXRLZXlFbnRyeSgiYWxpYXMyIiwgZ2V0UHJpdmF0ZUtleSgpLCBwc3NXb3JkLCBjZXJ0KTsKKworICAgICAgICAvLyBhbGlhcyAzCisgICAgICAgIGtleVRlc3Quc2V0Q2VydGlmaWNhdGVFbnRyeSgiYWxpYXMzIiwgY2VydFsxXSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0aGUgc2l6ZSBvZiB0aGUga2V5U3RvcmUgaXMgbm90IDMiLCAzLCBrZXlUZXN0LnNpemUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9kZWxldGVFbXB0eUVudHJ5RW1wdHlBbGlhcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBLZXlTdG9yZSBrZXlUZXN0ID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSk7CisgICAgICAgIGtleVRlc3QubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAga2V5VGVzdC5kZWxldGVFbnRyeSgiIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9kZWxldGVFbXB0eUVudHJ5Qm9ndXNBbGlhcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBLZXlTdG9yZSBrZXlUZXN0ID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSk7CisgICAgICAgIGtleVRlc3QubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAga2V5VGVzdC5kZWxldGVFbnRyeSgiYm9ndXMiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LktleVN0b3JlI2RlbGV0ZUVudHJ5KFN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RlbGV0ZUVudHJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZSBrZXlUZXN0ID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSk7CisgICAgICAgICAgICBrZXlUZXN0LmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBrZXlUZXN0LmRlbGV0ZUVudHJ5KG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgS2V5U3RvcmUga2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICBrZXlUZXN0LmxvYWQobnVsbCwgInBhc3N3b3JkIi50b0NoYXJBcnJheSgpKTsKKworICAgICAgICBLZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb24gcHAgPSBuZXcgS2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uKHBzc1dvcmQpOworICAgICAgICBDZXJ0aWZpY2F0ZVtdIGNoYWluID0geyBuZXcgTXlDZXJ0aWZpY2F0ZSgiRFNBIiwgdGVzdEVuY29kaW5nKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE15Q2VydGlmaWNhdGUoIkRTQSIsIHRlc3RFbmNvZGluZykgfTsKKyAgICAgICAgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5IHBrRW50cnkgPSBuZXcgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5KGdldFByaXZhdGVLZXkoKSwgY2hhaW4pOworCisgICAgICAgIGtleVRlc3Quc2V0RW50cnkoInN5bUtleSIsIHBrRW50cnksIHBwKTsKKworICAgICAgICBrZXlUZXN0LmRlbGV0ZUVudHJ5KCJzeW1LZXkiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LktleVN0b3JlI2dldENyZWF0aW9uRGF0ZShTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDcmVhdGlvbkRhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHR5cGUgPSAiRFNBIjsKKworICAgICAgICBLZXlTdG9yZSBrZXlUZXN0ID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleVRlc3QuZ2V0Q3JlYXRpb25EYXRlKCJhbkFsaWFzIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBrZXlUZXN0LmxvYWQobnVsbCwgcHNzV29yZCk7CisKKyAgICAgICAgYXNzZXJ0TnVsbChrZXlUZXN0LmdldENyZWF0aW9uRGF0ZSgiIikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5VGVzdC5nZXRDcmVhdGlvbkRhdGUobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBDZXJ0aWZpY2F0ZVtdIGNoYWluID0geyBuZXcgTXlDZXJ0aWZpY2F0ZSh0eXBlLCB0ZXN0RW5jb2RpbmcpLAorICAgICAgICAgICAgICAgIG5ldyBNeUNlcnRpZmljYXRlKHR5cGUsIHRlc3RFbmNvZGluZykgfTsKKyAgICAgICAgUHJpdmF0ZUtleSBwcml2YXRlS2V5MSA9IEtleUZhY3RvcnkuZ2V0SW5zdGFuY2UodHlwZSkuZ2VuZXJhdGVQcml2YXRlKAorICAgICAgICAgICAgICAgIG5ldyBEU0FQcml2YXRlS2V5U3BlYyhuZXcgQmlnSW50ZWdlcigiMCIpLCBuZXcgQmlnSW50ZWdlcigiMCIpLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjAiKSwgbmV3IEJpZ0ludGVnZXIoIjAiKSkpOworCisgICAgICAgIEtleVN0b3JlLlBhc3N3b3JkUHJvdGVjdGlvbiBwcCA9IG5ldyBLZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb24oCisgICAgICAgICAgICAgICAgcHNzV29yZCk7CisgICAgICAgIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSBwa2UgPSBuZXcgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5KGdldFByaXZhdGVLZXkoKSwKKyAgICAgICAgICAgICAgICBjaGFpbik7CisgICAgICAgIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSBwa2UxID0gbmV3IEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSgKKyAgICAgICAgICAgICAgICBwcml2YXRlS2V5MSwgY2hhaW4pOworCisgICAgICAgIGtleVRlc3Quc2V0RW50cnkoImFsaWFzMSIsIHBrZSwgcHApOworICAgICAgICBrZXlUZXN0LnNldEVudHJ5KCJhbGlhczIiLCBwa2UxLCBwcCk7CisgICAgICAgIENhbGVuZGFyLmdldEluc3RhbmNlKCkuZ2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCk7CisKKyAgICAgICAgaW50IGRheUV4cGVjdGVkID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKS5nZXQoQ2FsZW5kYXIuREFZX09GX01PTlRIKTsKKyAgICAgICAgaW50IG1vbnRoRXhwZWN0ZWQgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpLmdldChDYWxlbmRhci5NT05USCk7CisgICAgICAgIGludCB5ZWFyRXhwZWN0ZWQgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpLmdldChDYWxlbmRhci5ZRUFSKTsKKyAgICAgICAgaW50IGhvdXJFeHBlY3RlZCA9IENhbGVuZGFyLmdldEluc3RhbmNlKCkuZ2V0KENhbGVuZGFyLkhPVVIpOworICAgICAgICBpbnQgbWludXRlRXhwZWN0ZWQgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpLmdldChDYWxlbmRhci5NSU5VVEUpOworCisgICAgICAgIENhbGVuZGFyLmdldEluc3RhbmNlKCkuc2V0VGltZUluTWlsbGlzKGtleVRlc3QuZ2V0Q3JlYXRpb25EYXRlKCJhbGlhczEiKS5nZXRUaW1lKCkpOworICAgICAgICBpbnQgZGF5QWN0dWFsMSA9IENhbGVuZGFyLmdldEluc3RhbmNlKCkuZ2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCk7CisgICAgICAgIGludCBtb250aEFjdHVhbDEgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpLmdldChDYWxlbmRhci5NT05USCk7CisgICAgICAgIGludCB5ZWFyQWN0dWFsMSA9IENhbGVuZGFyLmdldEluc3RhbmNlKCkuZ2V0KENhbGVuZGFyLllFQVIpOworICAgICAgICBpbnQgaG91ckFjdHVhbDEgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpLmdldChDYWxlbmRhci5IT1VSKTsKKyAgICAgICAgaW50IG1pbnV0ZUFjdHVhbDEgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpLmdldChDYWxlbmRhci5NSU5VVEUpOworCisgICAgICAgIGFzc2VydEVxdWFscyhkYXlFeHBlY3RlZCwgZGF5QWN0dWFsMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtb250aEV4cGVjdGVkLCBtb250aEFjdHVhbDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoeWVhckV4cGVjdGVkLCB5ZWFyQWN0dWFsMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhob3VyRXhwZWN0ZWQsIGhvdXJBY3R1YWwxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1pbnV0ZUV4cGVjdGVkLCBtaW51dGVBY3R1YWwxKTsKKworICAgICAgICBDYWxlbmRhci5nZXRJbnN0YW5jZSgpLnNldFRpbWVJbk1pbGxpcygKKyAgICAgICAgICAgICAgICBrZXlUZXN0LmdldENyZWF0aW9uRGF0ZSgiYWxpYXMyIikuZ2V0VGltZSgpKTsKKyAgICAgICAgaW50IGRheUFjdHVhbDIgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpLmdldChDYWxlbmRhci5EQVlfT0ZfTU9OVEgpOworICAgICAgICBpbnQgbW9udGhBY3R1YWwyID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKS5nZXQoQ2FsZW5kYXIuTU9OVEgpOworICAgICAgICBpbnQgeWVhckFjdHVhbDIgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpLmdldChDYWxlbmRhci5ZRUFSKTsKKyAgICAgICAgaW50IGhvdXJBY3R1YWwyID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKS5nZXQoQ2FsZW5kYXIuSE9VUik7CisgICAgICAgIGludCBtaW51dGVBY3R1YWwyID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKS5nZXQoQ2FsZW5kYXIuTUlOVVRFKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoZGF5RXhwZWN0ZWQsIGRheUFjdHVhbDIpOworICAgICAgICBhc3NlcnRFcXVhbHMobW9udGhFeHBlY3RlZCwgbW9udGhBY3R1YWwyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHllYXJFeHBlY3RlZCwgeWVhckFjdHVhbDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoaG91ckV4cGVjdGVkLCBob3VyQWN0dWFsMik7CisgICAgICAgIGFzc2VydEVxdWFscyhtaW51dGVFeHBlY3RlZCwgbWludXRlQWN0dWFsMik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleVRlc3QuZ2V0Q3JlYXRpb25EYXRlKG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5LZXlTdG9yZSNnZXRFbnRyeShTdHJpbmcsCisgICAgICogICAgICAgIEtleVN0b3JlLlByb3RlY3Rpb25QYXJhbWV0ZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRFbnRyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgdHlwZSA9ICJEU0EiOworCisgICAgICAgIEtleVN0b3JlIGtleVRlc3QgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5VGVzdC5nZXRFbnRyeSgiYW5BbGlhcyIsIG5ldyBLZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb24obmV3IGNoYXJbXSB7fSkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAga2V5VGVzdC5sb2FkKG51bGwsIHBzc1dvcmQpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlUZXN0LmdldEVudHJ5KG51bGwsIG5ldyBLZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb24obmV3IGNoYXJbXSB7fSkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAga2V5VGVzdC5nZXRFbnRyeSgiYW5BbGlhcyIsIG51bGwpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlUZXN0LmdldEVudHJ5KG51bGwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKworICAgICAgICBhc3NlcnROdWxsKGtleVRlc3QuZ2V0RW50cnkoImFsaWFzIiwgbnVsbCkpOworCisgICAgICAgIENlcnRpZmljYXRlW10gY2hhaW4gPSB7IG5ldyBNeUNlcnRpZmljYXRlKHR5cGUsIHRlc3RFbmNvZGluZyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBNeUNlcnRpZmljYXRlKHR5cGUsIHRlc3RFbmNvZGluZykgfTsKKworICAgICAgICBEU0FQcml2YXRlS2V5IHByaXZhdGVLZXkxID0gKERTQVByaXZhdGVLZXkpCisgICAgICAgICAgICAgICAgS2V5RmFjdG9yeS5nZXRJbnN0YW5jZSh0eXBlKS5nZW5lcmF0ZVByaXZhdGUoCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRFNBUHJpdmF0ZUtleVNwZWMobmV3IEJpZ0ludGVnZXIoIjEiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMiIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIzIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjQiKSkpOworCisgICAgICAgIEtleVN0b3JlLlBhc3N3b3JkUHJvdGVjdGlvbiBwcCA9IG5ldyBLZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb24ocHNzV29yZCk7CisgICAgICAgIGFzc2VydE51bGwoa2V5VGVzdC5nZXRFbnRyeSgiYWxpYXMiLCBwcCkpOworCisgICAgICAgIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSBwa2UxID0gbmV3IEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeShnZXRQcml2YXRlS2V5KCksIGNoYWluKTsKKyAgICAgICAgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5IHBrZTIgPSBuZXcgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5KHByaXZhdGVLZXkxLCBjaGFpbik7CisKKyAgICAgICAga2V5VGVzdC5zZXRFbnRyeSgiYWxpYXMxIiwgcGtlMSwgcHApOworICAgICAgICBrZXlUZXN0LnNldEVudHJ5KCJhbGlhczIiLCBwa2UyLCBwcCk7CisKKyAgICAgICAgYXNzZXJ0TnVsbChrZXlUZXN0LmdldEVudHJ5KCJhbGlhcyIsIHBwKSk7CisgICAgICAgIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSBwa2VBY3R1YWwxID0gKEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSkga2V5VGVzdC5nZXRFbnRyeSgiYWxpYXMxIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBwKTsKKyAgICAgICAgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5IHBrZUFjdHVhbDIgPSAoS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5KSBrZXlUZXN0LmdldEVudHJ5KCJhbGlhczIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHApOworCisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhjaGFpbiwgcGtlQWN0dWFsMS5nZXRDZXJ0aWZpY2F0ZUNoYWluKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGdldFByaXZhdGVLZXkoKSwgcGtlQWN0dWFsMS5nZXRQcml2YXRlS2V5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IE15Q2VydGlmaWNhdGUodHlwZSwgdGVzdEVuY29kaW5nKSwgcGtlQWN0dWFsMS5nZXRDZXJ0aWZpY2F0ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShrZXlUZXN0LmVudHJ5SW5zdGFuY2VPZigiYWxpYXMxIiwgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5LmNsYXNzKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGNoYWluLCBwa2VBY3R1YWwyLmdldENlcnRpZmljYXRlQ2hhaW4oKSkpOworICAgICAgICBEU0FQcml2YXRlS2V5IGVudHJ5UHJpdmF0ZUtleSA9IChEU0FQcml2YXRlS2V5KSBwa2VBY3R1YWwyLmdldFByaXZhdGVLZXkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHByaXZhdGVLZXkxLmdldFgoKSwgZW50cnlQcml2YXRlS2V5LmdldFgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhwcml2YXRlS2V5MS5nZXRQYXJhbXMoKS5nZXRHKCksIGVudHJ5UHJpdmF0ZUtleS5nZXRQYXJhbXMoKS5nZXRHKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMocHJpdmF0ZUtleTEuZ2V0UGFyYW1zKCkuZ2V0UCgpLCBlbnRyeVByaXZhdGVLZXkuZ2V0UGFyYW1zKCkuZ2V0UCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHByaXZhdGVLZXkxLmdldFBhcmFtcygpLmdldFEoKSwgZW50cnlQcml2YXRlS2V5LmdldFBhcmFtcygpLmdldFEoKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBNeUNlcnRpZmljYXRlKHR5cGUsIHRlc3RFbmNvZGluZyksIHBrZUFjdHVhbDIuZ2V0Q2VydGlmaWNhdGUoKSk7CisgICAgICAgIGFzc2VydFRydWUoa2V5VGVzdC5lbnRyeUluc3RhbmNlT2YoImFsaWFzMiIsIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeS5jbGFzcykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuS2V5U3RvcmUjc2V0RW50cnkoU3RyaW5nLCBLZXlTdG9yZS5FbnRyeSwKKyAgICAgKiAgICAgICAgS2V5U3RvcmUuUHJvdGVjdGlvblBhcmFtZXRlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEVudHJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB0eXBlID0gIkRTQSI7CisKKyAgICAgICAgS2V5U3RvcmUga2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICBrZXlUZXN0LmxvYWQobnVsbCwgcHNzV29yZCk7CisKKyAgICAgICAgQ2VydGlmaWNhdGVbXSBjaGFpbiA9IHsgbmV3IE15Q2VydGlmaWNhdGUodHlwZSwgdGVzdEVuY29kaW5nKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE15Q2VydGlmaWNhdGUodHlwZSwgdGVzdEVuY29kaW5nKSB9OworICAgICAgICBEU0FQcml2YXRlS2V5IHByaXZhdGVLZXkxID0gKERTQVByaXZhdGVLZXkpCisgICAgICAgICAgICAgICAgS2V5RmFjdG9yeS5nZXRJbnN0YW5jZSh0eXBlKS5nZW5lcmF0ZVByaXZhdGUoCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRFNBUHJpdmF0ZUtleVNwZWMobmV3IEJpZ0ludGVnZXIoIjEiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMiIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIzIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjQiKSkpOworCisgICAgICAgIEtleVN0b3JlLlBhc3N3b3JkUHJvdGVjdGlvbiBwcCA9IG5ldyBLZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb24ocHNzV29yZCk7CisgICAgICAgIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSBwa2UgPSBuZXcgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5KGdldFByaXZhdGVLZXkoKSwgY2hhaW4pOworICAgICAgICBLZXlTdG9yZS5Qcml2YXRlS2V5RW50cnkgcGtlMSA9IG5ldyBLZXlTdG9yZS5Qcml2YXRlS2V5RW50cnkocHJpdmF0ZUtleTEsIGNoYWluKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5VGVzdC5zZXRFbnRyeSgiYWxpYXMiLCBwa2UsIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGtleVRlc3Quc2V0RW50cnkoImFsaWFzIiwgcGtlLCBwcCk7CisKKyAgICAgICAgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5IHBrZUFjdHVhbCA9IChLZXlTdG9yZS5Qcml2YXRlS2V5RW50cnkpCisgICAgICAgICAgICAgICAga2V5VGVzdC5nZXRFbnRyeSgiYWxpYXMiLHBwKTsKKworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoY2hhaW4sIHBrZUFjdHVhbC5nZXRDZXJ0aWZpY2F0ZUNoYWluKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGdldFByaXZhdGVLZXkoKSwgcGtlQWN0dWFsLmdldFByaXZhdGVLZXkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgTXlDZXJ0aWZpY2F0ZSh0eXBlLCB0ZXN0RW5jb2RpbmcpLCBwa2VBY3R1YWwuZ2V0Q2VydGlmaWNhdGUoKSk7CisgICAgICAgIGFzc2VydFRydWUoa2V5VGVzdC5lbnRyeUluc3RhbmNlT2YoImFsaWFzIiwgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5LmNsYXNzKSk7CisKKyAgICAgICAga2V5VGVzdC5zZXRFbnRyeSgiYWxpYXMiLCBwa2UxLCBwcCk7CisgICAgICAgIHBrZUFjdHVhbCA9IChLZXlTdG9yZS5Qcml2YXRlS2V5RW50cnkpIGtleVRlc3QuZ2V0RW50cnkoImFsaWFzIiwgcHApOworCisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhjaGFpbiwgcGtlQWN0dWFsLmdldENlcnRpZmljYXRlQ2hhaW4oKSkpOworICAgICAgICBEU0FQcml2YXRlS2V5IGFjdHVhbFByaXZhdGVLZXkgPSAoRFNBUHJpdmF0ZUtleSkgcGtlQWN0dWFsLmdldFByaXZhdGVLZXkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHByaXZhdGVLZXkxLmdldFgoKSwgYWN0dWFsUHJpdmF0ZUtleS5nZXRYKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMocHJpdmF0ZUtleTEuZ2V0UGFyYW1zKCkuZ2V0RygpLCBhY3R1YWxQcml2YXRlS2V5LmdldFBhcmFtcygpLmdldEcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhwcml2YXRlS2V5MS5nZXRQYXJhbXMoKS5nZXRQKCksIGFjdHVhbFByaXZhdGVLZXkuZ2V0UGFyYW1zKCkuZ2V0UCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHByaXZhdGVLZXkxLmdldFBhcmFtcygpLmdldFEoKSwgYWN0dWFsUHJpdmF0ZUtleS5nZXRQYXJhbXMoKS5nZXRRKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IE15Q2VydGlmaWNhdGUodHlwZSwgdGVzdEVuY29kaW5nKSwgcGtlQWN0dWFsLmdldENlcnRpZmljYXRlKCkpOworICAgICAgICBhc3NlcnRUcnVlKGtleVRlc3QuZW50cnlJbnN0YW5jZU9mKCJhbGlhcyIsIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeS5jbGFzcykpOworCisgICAgICAgIGtleVRlc3Quc2V0RW50cnkoImFsaWFzMiIsIHBrZTEsIHBwKTsKKyAgICAgICAgcGtlQWN0dWFsID0gKEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSkga2V5VGVzdC5nZXRFbnRyeSgiYWxpYXMyIiwgcHApOworCisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhjaGFpbiwgcGtlQWN0dWFsLmdldENlcnRpZmljYXRlQ2hhaW4oKSkpOworICAgICAgICBhY3R1YWxQcml2YXRlS2V5ID0gKERTQVByaXZhdGVLZXkpIHBrZUFjdHVhbC5nZXRQcml2YXRlS2V5KCk7CisgICAgICAgIGFzc2VydEVxdWFscyhwcml2YXRlS2V5MS5nZXRYKCksIGFjdHVhbFByaXZhdGVLZXkuZ2V0WCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHByaXZhdGVLZXkxLmdldFBhcmFtcygpLmdldEcoKSwgYWN0dWFsUHJpdmF0ZUtleS5nZXRQYXJhbXMoKS5nZXRHKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMocHJpdmF0ZUtleTEuZ2V0UGFyYW1zKCkuZ2V0UCgpLCBhY3R1YWxQcml2YXRlS2V5LmdldFBhcmFtcygpLmdldFAoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhwcml2YXRlS2V5MS5nZXRQYXJhbXMoKS5nZXRRKCksIGFjdHVhbFByaXZhdGVLZXkuZ2V0UGFyYW1zKCkuZ2V0USgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBNeUNlcnRpZmljYXRlKHR5cGUsIHRlc3RFbmNvZGluZyksIHBrZUFjdHVhbC5nZXRDZXJ0aWZpY2F0ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShrZXlUZXN0LmVudHJ5SW5zdGFuY2VPZigiYWxpYXMyIiwgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5LmNsYXNzKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleVRlc3Quc2V0RW50cnkobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIGphdmEuc2VjdXJpdHkuS2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKFN0cmluZywgQ2xhc3M8PyBleHRlbmRzCisgICAgICogRW50cnk+KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZW50cnlJbnN0YW5jZU9mKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgS2V5U3RvcmUga2V5U3RvcmUgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKCJhbkFsaWFzIiwgS2V5U3RvcmUuU2VjcmV0S2V5RW50cnkuY2xhc3MpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCAicHdkIi50b0NoYXJBcnJheSgpKTsKKworICAgICAgICAvLyBwdXQgdGhlIGtleSBpbnRvIGtleXN0b3JlCisgICAgICAgIFN0cmluZyBhbGlhcyA9ICJhbGlhcyI7CisgICAgICAgIENlcnRpZmljYXRlW10gY2hhaW4gPSB7IG5ldyBNeUNlcnRpZmljYXRlKCJEU0EiLCB0ZXN0RW5jb2RpbmcpLAorICAgICAgICAgICAgICAgIG5ldyBNeUNlcnRpZmljYXRlKCJEU0EiLCB0ZXN0RW5jb2RpbmcpIH07CisKKyAgICAgICAga2V5U3RvcmUuc2V0S2V5RW50cnkoYWxpYXMsIGdldFByaXZhdGVLZXkoKSwgInB3ZCIudG9DaGFyQXJyYXkoKSwgY2hhaW4pOworICAgICAgICBhc3NlcnRUcnVlKGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZihhbGlhcywgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5LmNsYXNzKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZihhbGlhcywgS2V5U3RvcmUuU2VjcmV0S2V5RW50cnkuY2xhc3MpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKGFsaWFzLCBLZXlTdG9yZS5UcnVzdGVkQ2VydGlmaWNhdGVFbnRyeS5jbGFzcykpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlTdG9yZS5lbnRyeUluc3RhbmNlT2YobnVsbCwgS2V5U3RvcmUuU2VjcmV0S2V5RW50cnkuY2xhc3MpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleVN0b3JlLmVudHJ5SW5zdGFuY2VPZigiYW5BbGlhcyIsIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5LZXlTdG9yZSNzdG9yZShLZXlTdG9yZS5Mb2FkU3RvcmVQYXJhbWV0ZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zdG9yZV9qYXZhX3NlY3VyaXR5S2V5U3RvcmVfTG9hZFN0b3JlUGFyYW1ldGVyKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBLZXlTdG9yZSBrZXlTdG9yZSA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICBrZXlTdG9yZS5sb2FkKG51bGwsICJwd2QiLnRvQ2hhckFycmF5KCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5U3RvcmUuc3RvcmUobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LktleVN0b3JlI3N0b3JlKE91dHB1dFN0cmVhbSwgY2hhcltdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3RvcmVfamF2YV9pb19PdXRwdXRTdHJlYW1fY2hhcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBLZXlTdG9yZSBrZXlTdG9yZSA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlTdG9yZS5zdG9yZShuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCksICJwd2QiLnRvQ2hhckFycmF5KCkpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCAicHdkIi50b0NoYXJBcnJheSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleVN0b3JlLnN0b3JlKG51bGwsICJwd2QiLnRvQ2hhckFycmF5KCkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgc3VwcG9ydF9UZXN0UHJvdmlkZXIgPSBuZXcgU3VwcG9ydF9UZXN0UHJvdmlkZXIoKTsKKyAgICAgICAgU2VjdXJpdHkuYWRkUHJvdmlkZXIoc3VwcG9ydF9UZXN0UHJvdmlkZXIpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgICAgIFNlY3VyaXR5LnJlbW92ZVByb3ZpZGVyKHN1cHBvcnRfVGVzdFByb3ZpZGVyLmdldE5hbWUoKSk7CisgICAgfQorCisgICAgY2xhc3MgTXlDZXJ0aWZpY2F0ZSBleHRlbmRzIENlcnRpZmljYXRlIHsKKworICAgICAgICAvLyBNeUNlcnRpZmljYXRlIGVuY29kaW5nCisgICAgICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGVuY29kaW5nOworCisgICAgICAgIHB1YmxpYyBNeUNlcnRpZmljYXRlKFN0cmluZyB0eXBlLCBieXRlW10gZW5jb2RpbmcpIHsKKyAgICAgICAgICAgIHN1cGVyKHR5cGUpOworICAgICAgICAgICAgLy8gZG9uJ3QgY29weSB0byBhbGxvdyBudWxsIHBhcmFtZXRlciBpbiB0ZXN0CisgICAgICAgICAgICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBkbyBjb3B5IHRvIGZvcmNlIE5QRSBpbiB0ZXN0CisgICAgICAgICAgICByZXR1cm4gZW5jb2RpbmcuY2xvbmUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5KSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBJbnZhbGlkS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLCBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgdmVyaWZ5KFB1YmxpY0tleSBrZXksIFN0cmluZyBzaWdQcm92aWRlcikKKyAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBJbnZhbGlkS2V5RXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiAiW015IHRlc3QgQ2VydGlmaWNhdGUsIHR5cGU6ICIgKyBnZXRUeXBlKCkgKyAiXSI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUHVibGljS2V5IGdldFB1YmxpY0tleSgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUHVibGljS2V5KCkgeworICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gIkRTQSI7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7IChieXRlKSAxLCAoYnl0ZSkgMiwgKGJ5dGUpIDMgfTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJURVNUX0ZPUk1BVCI7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfTsKKyAgICAgICAgfQorCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVN0b3JlM1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlTdG9yZTNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzdiZjYyZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlTdG9yZTNUZXN0LmphdmEKQEAgLTAsMCArMSwyNzQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyc1Rlc3QuTXlBbGdvcml0aG1QYXJhbWV0ZXJzOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZVNwaTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworCitwdWJsaWMgY2xhc3MgS2V5U3RvcmUzVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgS2V5U3RvcmUgbW9ja0tleVN0b3JlOworCisgICAgcHJpdmF0ZSBLZXlQYWlyIGtleVBhaXI7CisKKyAgICBwcml2YXRlIENlcnRpZmljYXRlIGNlcnRpZmljYXRlOworCisgICAgcHVibGljIEtleVN0b3JlM1Rlc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvciBrZXlQYWlyR2VuZXJhdG9yID0gS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZSgiRFNBIik7CisgICAgICAgIGtleVBhaXIgPSBrZXlQYWlyR2VuZXJhdG9yLmdlbmVyYXRlS2V5UGFpcigpOworCisgICAgICAgIFN0cmluZyBjZXJ0aWZpY2F0ZURhdGEgPSAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICAgICAgICAgKyAiTUlJQ1pUQ0NBZElDQlFMM0FBQzJNQTBHQ1NxR1NJYjNEUUVCQWdVQU1GOHhDekFKQmdOVkJBWVRBbFZUTVNBd1xuIgorICAgICAgICAgICAgICAgICsgIkhnWURWUVFLRXhkU1UwRWdSR0YwWVNCVFpXTjFjbWwwZVN3Z1NXNWpMakV1TUN3R0ExVUVDeE1sVTJWamRYSmxcbiIKKyAgICAgICAgICAgICAgICArICJJRk5sY25abGNpQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVRBZUZ3MDVOekF5TWpBd01EQXdNREJhXG4iCisgICAgICAgICAgICAgICAgKyAiRncwNU9EQXlNakF5TXpVNU5UbGFNSUdXTVFzd0NRWURWUVFHRXdKVlV6RVRNQkVHQTFVRUNCTUtRMkZzYVdadlxuIgorICAgICAgICAgICAgICAgICsgImNtNXBZVEVTTUJBR0ExVUVCeE1KVUdGc2J5QkJiSFJ2TVI4d0hRWURWUVFLRXhaVGRXNGdUV2xqY205emVYTjBcbiIKKyAgICAgICAgICAgICAgICArICJaVzF6TENCSmJtTXVNU0V3SHdZRFZRUUxFeGhVWlhOMElHRnVaQ0JGZG1Gc2RXRjBhVzl1SUU5dWJIa3hHakFZXG4iCisgICAgICAgICAgICAgICAgKyAiQmdOVkJBTVRFV0Z5WjI5dUxtVnVaeTV6ZFc0dVkyOXRNSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdOQURDQlxuIgorICAgICAgICAgICAgICAgICsgImlRS0JnUUNvZm1kWStQaVVXTjAxRk96RWV3ZitHYUcrbEZmMTMyVXB6QVRtWUprQTRBRUEvanVXN2pTaStMSmtcbiIKKyAgICAgICAgICAgICAgICArICJ3SktpNUdPNFJ5Wm95aW1BTC81eUlXRFY2bDFLbHZ4eUtzbHIwUkVoTUJhRC8zWjNFc0xUVEVmNWdWclFTNnNUXG4iCisgICAgICAgICAgICAgICAgKyAiV01vU1pBeXpCMzlrRmZzQjZvVVhOdFY4K1VLS3hTeEtieHZoUW4yNjdQZUN6NVZYMlFJREFRQUJNQTBHQ1NxR1xuIgorICAgICAgICAgICAgICAgICsgIlNJYjNEUUVCQWdVQUEzNEFYbDNhdDZsdWlWLzdJOU1ONUNYWW9QSllJOEJjZGMxaEJhZ0p2VE1jbWxxTDJ1T1pcbiIKKyAgICAgICAgICAgICAgICArICJIOVQ1aE5NRUw5VGs2YUk3eVpQWGN3L3hJMks2cE9SL0ZyTXAwVXdKbWR4WDdsalY2WnRVWmY3cFk0OTJVcXdDXG4iCisgICAgICAgICAgICAgICAgKyAiMTc3N1hROVVFWnlyS0p2RjVudGxlZU8wYXlCcUxHVktDV3pXWlg5WXNYQ3B2NDdGTkxaYnVwRT1cbiIKKyAgICAgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iOworCisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGNlcnRBcnJheSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICBjZXJ0aWZpY2F0ZURhdGEuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgY2VydGlmaWNhdGUgPSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKGNlcnRBcnJheSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9sb2FkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIE5vIGV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIG91dC4KKyAgICAgICAgbW9ja0tleVN0b3JlLmxvYWQobnVsbCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdG9yZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbW9ja0tleVN0b3JlLnN0b3JlKG51bGwpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IEtleVN0b3JlRXhjZXB0aW9uOiBub3QgaW5pdGlhbGl6ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIE5vIGV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIG91dC4KKyAgICAgICAgbW9ja0tleVN0b3JlLmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgIG1vY2tLZXlTdG9yZS5zdG9yZShudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEtleUVudHJ5X251bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbW9ja0tleVN0b3JlLmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgIC8vIE5vIGV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIG91dC4KKyAgICAgICAgbW9ja0tleVN0b3JlLnNldEtleUVudHJ5KG51bGwsIG51bGwsIG51bGwsIG51bGwpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0S2V5RW50cnlfa2V5X2lzX251bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbW9ja0tleVN0b3JlLmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgIC8vIE5vIGV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIG91dC4KKyAgICAgICAgbW9ja0tleVN0b3JlLnNldEtleUVudHJ5KCJBbGlhcyIsIG51bGwsIG51bGwsIG5ldyBDZXJ0aWZpY2F0ZVtde2NlcnRpZmljYXRlfSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRLZXlFbnRyeV9rZXlfaXNfcHJpdmF0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBtb2NrS2V5U3RvcmUubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgS2V5IGtleSA9IGtleVBhaXIuZ2V0UHJpdmF0ZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbW9ja0tleVN0b3JlLnNldEtleUVudHJ5KCJBbGlhcyIsIGtleSwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1vY2tLZXlTdG9yZS5zZXRLZXlFbnRyeSgiQWxpYXMiLCBrZXksIG51bGwsCisgICAgICAgICAgICAgICAgICAgIG5ldyBDZXJ0aWZpY2F0ZVswXSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgbW9ja0tleVN0b3JlLnNldEtleUVudHJ5KCJBbGlhcyIsIGtleSwgbnVsbCwgbmV3IENlcnRpZmljYXRlW117Y2VydGlmaWNhdGV9KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEtleUVudHJ5X2tleV9pc19wdWJsaWMoKSB0aHJvd3MgRXhjZXB0aW9uCisgICAgeworICAgICAgICBtb2NrS2V5U3RvcmUubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgS2V5IGtleSA9IGtleVBhaXIuZ2V0UHVibGljKCk7CisgICAgICAgIG1vY2tLZXlTdG9yZS5zZXRLZXlFbnRyeSgiQWxpYXMxIiwga2V5LCBudWxsLCBudWxsKTsKKyAgICAgICAgbW9ja0tleVN0b3JlLnNldEtleUVudHJ5KCJBbGlhczIiLCBrZXksIG51bGwsCisgICAgICAgICAgICAgICAgbmV3IENlcnRpZmljYXRlWzBdKTsKKyAgICAgICAgbW9ja0tleVN0b3JlLnNldEtleUVudHJ5KCJBbGlhczMiLCBrZXksIG51bGwsIG5ldyBDZXJ0aWZpY2F0ZVtde2NlcnRpZmljYXRlfSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRDZXJ0aWZpY2F0ZUVudHJ5X251bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbW9ja0tleVN0b3JlLmxvYWQobnVsbCwgbnVsbCk7CisKKyAgICAgICAgbW9ja0tleVN0b3JlLnNldENlcnRpZmljYXRlRW50cnkobnVsbCwgbnVsbCk7CisKKyAgICAgICAgbW9ja0tleVN0b3JlLnNldENlcnRpZmljYXRlRW50cnkobnVsbCwgY2VydGlmaWNhdGUpOworCisgICAgICAgIG1vY2tLZXlTdG9yZS5zZXRDZXJ0aWZpY2F0ZUVudHJ5KCJBbGlhcyIsIG51bGwpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJjYXN0IikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0tleVN0b3JlKCkgeworICAgICAgICBQcm92aWRlciBwID0gbmV3IE15UHJvdmlkZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE15S2V5U3RvcmUga3MgPSBuZXcgTXlLZXlTdG9yZShuZXcgTXlLZXlTdG9yZVNwaSgpLCBwLCAiTXlLZXlTdG9yZSIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChrcyk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGtzIGluc3RhbmNlb2YgS2V5U3RvcmUpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIHNob3VsZCBiZSBub3QgdGhyb3duIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTXlLZXlTdG9yZSBrcyA9IG5ldyBNeUtleVN0b3JlKG51bGwsIG51bGwsIG51bGwpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChrcyk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGtzIGluc3RhbmNlb2YgS2V5U3RvcmUpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIHNob3VsZCBiZSBub3QgdGhyb3duIik7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIG1vY2tLZXlTdG9yZSA9IG5ldyBNeUtleVN0b3JlKG5ldyBNeUtleVN0b3JlU3BpKCksIG51bGwsICJNeUtleVN0b3JlIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTXlLZXlTdG9yZSBleHRlbmRzIEtleVN0b3JlIHsKKworICAgICAgICBwdWJsaWMgTXlLZXlTdG9yZShLZXlTdG9yZVNwaSBrZXlTdG9yZVNwaSwgUHJvdmlkZXIgcHJvdmlkZXIsCisgICAgICAgICAgICAgICAgU3RyaW5nIHR5cGUpIHsKKyAgICAgICAgICAgIHN1cGVyKGtleVN0b3JlU3BpLCBwcm92aWRlciwgdHlwZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBNeUtleVN0b3JlU3BpIGV4dGVuZHMgS2V5U3RvcmVTcGkgeworCisgICAgICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGVuZ2luZUFsaWFzZXMoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGVuZ2luZUNvbnRhaW5zQWxpYXMoU3RyaW5nIGFyZzApIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGVuZ2luZURlbGV0ZUVudHJ5KFN0cmluZyBhcmcwKSB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIENlcnRpZmljYXRlIGVuZ2luZUdldENlcnRpZmljYXRlKFN0cmluZyBhcmcwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZW5naW5lR2V0Q2VydGlmaWNhdGVBbGlhcyhDZXJ0aWZpY2F0ZSBhcmcwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZVtdIGVuZ2luZUdldENlcnRpZmljYXRlQ2hhaW4oU3RyaW5nIGFyZzApIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIERhdGUgZW5naW5lR2V0Q3JlYXRpb25EYXRlKFN0cmluZyBhcmcwKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBLZXkgZW5naW5lR2V0S2V5KFN0cmluZyBhcmcwLCBjaGFyW10gYXJnMSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZW5naW5lSXNDZXJ0aWZpY2F0ZUVudHJ5KFN0cmluZyBhcmcwKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBlbmdpbmVJc0tleUVudHJ5KFN0cmluZyBhcmcwKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBlbmdpbmVMb2FkKElucHV0U3RyZWFtIGFyZzAsIGNoYXJbXSBhcmcxKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGVuZ2luZVNldENlcnRpZmljYXRlRW50cnkoU3RyaW5nIGFyZzAsIENlcnRpZmljYXRlIGFyZzEpCisgICAgICAgICAgICAgICAgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGVuZ2luZVNldEtleUVudHJ5KFN0cmluZyBhcmcwLCBieXRlW10gYXJnMSwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZVtdIGFyZzIpIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBlbmdpbmVTZXRLZXlFbnRyeShTdHJpbmcgYXJnMCwgS2V5IGFyZzEsIGNoYXJbXSBhcmcyLAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlW10gYXJnMykgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZW5naW5lU2l6ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgZW5naW5lU3RvcmUoS2V5U3RvcmUuTG9hZFN0b3JlUGFyYW1ldGVyIHBhcmFtKXsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGVuZ2luZVN0b3JlKE91dHB1dFN0cmVhbSBhcmcwLCBjaGFyW10gYXJnMSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKKyAgICBwcml2YXRlIGNsYXNzIE15UHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlciB7CisgICAgICAgIE15UHJvdmlkZXIoKSB7CisgICAgICAgICAgICBzdXBlcigiTXlQcm92aWRlciIsIDEuMCwgIlByb3ZpZGVyIGZvciB0ZXN0aW5nIik7CisgICAgICAgICAgICBwdXQoIkFsZ29yaXRobVBhcmFtZXRlcnMuQUJDIiwgTXlBbGdvcml0aG1QYXJhbWV0ZXJzLmNsYXNzCisgICAgICAgICAgICAgICAgICAgIC5nZXROYW1lKCkpOworICAgICAgICB9CisKKyAgICAgICAgTXlQcm92aWRlcihTdHJpbmcgbmFtZSwgZG91YmxlIHZlcnNpb24sIFN0cmluZyBpbmZvKSB7CisgICAgICAgICAgICBzdXBlcihuYW1lLCB2ZXJzaW9uLCBpbmZvKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVN0b3JlNFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlTdG9yZTRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDE3OGRiMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlTdG9yZTRUZXN0LmphdmEKQEAgLTAsMCArMSw2MzggQEAKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5NeVByb3ZpZGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlRlc3RLZXlTdG9yZVNwaTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0Lk15Q2VydGlmaWNhdGU7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5VbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5VbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmUuRW50cnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZS5Qcm90ZWN0aW9uUGFyYW1ldGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CisKK3B1YmxpYyBjbGFzcyBLZXlTdG9yZTRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgUHJvdmlkZXIgcHJvdmlkZXIgPSBuZXcgTXlQcm92aWRlcigpOworICAgIEtleVN0b3JlIGtleVN0b3JlOworICAgIEtleVN0b3JlIHVuaW5pdGlhbGl6ZWQ7CisgICAgS2V5U3RvcmUgZmFpbGluZzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEtFWV9TVE9SRV9UWVBFID0gIlRlc3RLZXlTdG9yZSI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisKKyAgICAgICAgU2VjdXJpdHkuYWRkUHJvdmlkZXIobmV3IE15UHJvdmlkZXIoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleVN0b3JlID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoS0VZX1NUT1JFX1RZUEUpOworICAgICAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCAiUEFTU1dPUkQiLnRvQ2hhckFycmF5KCkpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ0ZXN0IGNsYXNzIG5vdCBhdmFpbGFibGUiKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB1bmluaXRpYWxpemVkID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoS0VZX1NUT1JFX1RZUEUpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ0ZXN0IGtleXN0b3JlIG5vdCBhdmFpbGFibGUiKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKworICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcihwcm92aWRlci5nZXROYW1lKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZVN0cmluZygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVN0b3JlIGtzID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoIlRlc3RLZXlTdG9yZSIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgia2V5c3RvcmUgaXMgbnVsbCIsIGtzKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiS2V5U3RvcmUgaXMgbm90IG9mIGV4cGVjdGVkIFR5cGUiLCAiVGVzdEtleVN0b3JlIiwga3MuZ2V0VHlwZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZS5nZXRJbnN0YW5jZSgiVW5rbm93bktleVN0b3JlIik7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBLZXlTdG9yZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVN0b3JlLmdldEluc3RhbmNlKG51bGwpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZVN0cmluZ1N0cmluZygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVN0b3JlIGtzID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoIlRlc3RLZXlTdG9yZSIsIHByb3ZpZGVyLmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJrZXlzdG9yZSBpcyBudWxsIiwga3MpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJLZXlTdG9yZSBpcyBub3Qgb2YgZXhwZWN0ZWQgdHlwZSIsICJUZXN0S2V5U3RvcmUiLCBrcy5nZXRUeXBlKCkpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVN0b3JlLmdldEluc3RhbmNlKCJVbmtub3duS2V5U3RvcmUiLCBwcm92aWRlci5nZXROYW1lKCkpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgS2V5U3RvcmVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZS5nZXRJbnN0YW5jZSgiVGVzdEtleVN0b3JlIiwgKFN0cmluZyludWxsKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZS5nZXRJbnN0YW5jZSgiVGVzdEtleVN0b3JlIiwgIiIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVN0b3JlLmdldEluc3RhbmNlKG51bGwsIHByb3ZpZGVyLmdldE5hbWUoKSk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBLZXlTdG9yZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBhbHNvIG9rCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5U3RvcmUuZ2V0SW5zdGFuY2UoIlRlc3RLZXlTdG9yZSIsICJVbmtub3duUHJvdmlkZXIiKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2VTdHJpbmdQcm92aWRlcigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVN0b3JlIGtzID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoIlRlc3RLZXlTdG9yZSIsIHByb3ZpZGVyKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIktleVN0b3JlIGlzIG51bGwiLCBrcyk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIktleVN0b3JlIGlzIG5vdCBvZiBleHBlY3RlZCB0eXBlIiwgIlRlc3RLZXlTdG9yZSIsIGtzLmdldFR5cGUoKSk7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5U3RvcmUuZ2V0SW5zdGFuY2UoIlVua25vd25LZXlTdG9yZSIsIHByb3ZpZGVyKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIEtleVN0b3JlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVN0b3JlLmdldEluc3RhbmNlKCJUZXN0S2V5U3RvcmUiLCAoUHJvdmlkZXIpbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5U3RvcmUuZ2V0SW5zdGFuY2UobnVsbCwgcHJvdmlkZXIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworCisgICAgcHVibGljIHZvaWQgdGVzdEdldEtleSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleSBrZXkgPSBrZXlTdG9yZS5nZXRLZXkoImtleWFsaWFzIiwgbnVsbCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGtleSk7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5U3RvcmUuZ2V0S2V5KCJjZXJ0YWxpYXMiLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHVuaW5pdGlhbGl6ZWQuZ2V0S2V5KCJrZXlhbGlhcyIsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgS2V5U3RvcmVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlTdG9yZS5nZXRLZXkoInVua25vd25hbGlhcyIsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9IGNhdGNoIChVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5U3RvcmUuZ2V0S2V5KCJ1bmtub3duYWxpYXMiLCAiUEFTU1dPUkQiLnRvQ2hhckFycmF5KCkpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDZXJ0aWZpY2F0ZUFsaWFzKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIGFsaWFzID0ga2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGVBbGlhcyhUZXN0S2V5U3RvcmVTcGkuQ0VSVCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJhbGlhcyBpcyBudWxsIiwgYWxpYXMpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJhbGlhcyBpcyBub3QgZXhwZWN0ZWQiLCAiY2VydGFsaWFzIiwgYWxpYXMpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHVuaW5pdGlhbGl6ZWQuZ2V0Q2VydGlmaWNhdGVBbGlhcyhUZXN0S2V5U3RvcmVTcGkuQ0VSVCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBLZXlTdG9yZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleVN0b3JlLmdldENlcnRpZmljYXRlQWxpYXMobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBjZXJ0aWZpY2F0ZUFsaWFzID0ga2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGVBbGlhcyhuZXcgTXlDZXJ0aWZpY2F0ZSgiZHVtbXkiLCBudWxsKSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJhbGlhcyB3YXMgbm90IG51bGwiLCBjZXJ0aWZpY2F0ZUFsaWFzKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdG9yZU91dHB1dFN0cmVhbUNoYXJBcnJheSgpIHsKKyAgICAgICAgT3V0cHV0U3RyZWFtIG9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBjaGFyW10gcGFzc3dvcmQgPSAiUEFTU1dPUkQiLnRvQ2hhckFycmF5KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleVN0b3JlLnN0b3JlKG9zLCBwYXNzd29yZCk7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleVN0b3JlLnN0b3JlKG9zLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlTdG9yZS5zdG9yZShvcywgIiIudG9DaGFyQXJyYXkoKSk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlTdG9yZS5zdG9yZShudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIElPRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHVuaW5pdGlhbGl6ZWQuc3RvcmUobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBLZXlTdG9yZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisKKworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0b3JlTG9hZFN0b3JlUGFyYW1ldGVyKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5U3RvcmUuc3RvcmUobmV3IEtleVN0b3JlLkxvYWRTdG9yZVBhcmFtZXRlcigpIHsKKworICAgICAgICAgICAgICAgIHB1YmxpYyBQcm90ZWN0aW9uUGFyYW1ldGVyIGdldFByb3RlY3Rpb25QYXJhbWV0ZXIoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgS2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uKCJQQVNTV09SRCIudG9DaGFyQXJyYXkoKSk7CisgICAgICAgICAgICAgICAgfX0pOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlTdG9yZS5zdG9yZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIElPRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleVN0b3JlLnN0b3JlKG5ldyBLZXlTdG9yZS5Mb2FkU3RvcmVQYXJhbWV0ZXIoKSB7CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgUHJvdGVjdGlvblBhcmFtZXRlciBnZXRQcm90ZWN0aW9uUGFyYW1ldGVyKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9fSk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlTdG9yZS5zdG9yZShuZXcgS2V5U3RvcmUuTG9hZFN0b3JlUGFyYW1ldGVyKCkgeworCisgICAgICAgICAgICAgICAgcHVibGljIFByb3RlY3Rpb25QYXJhbWV0ZXIgZ2V0UHJvdGVjdGlvblBhcmFtZXRlcigpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBLZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb24oIiIudG9DaGFyQXJyYXkoKSk7CisgICAgICAgICAgICAgICAgfX0pOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlTdG9yZS5zdG9yZShuZXcgS2V5U3RvcmUuTG9hZFN0b3JlUGFyYW1ldGVyKCkgeworCisgICAgICAgICAgICAgICAgcHVibGljIFByb3RlY3Rpb25QYXJhbWV0ZXIgZ2V0UHJvdGVjdGlvblBhcmFtZXRlcigpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBLZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb24obnVsbCk7CisgICAgICAgICAgICAgICAgfX0gKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdW5pbml0aWFsaXplZC5zdG9yZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIEtleVN0b3JlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdExvYWRJbnB1dFN0cmVhbUNoYXJBcnJheSgpIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oIkRBVEEiLmdldEJ5dGVzKCkpOworICAgICAgICBjaGFyW10gcGFzc3dvcmQgPSAiUEFTU1dPUkQiLnRvQ2hhckFycmF5KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlTdG9yZS5sb2FkKGlzLCBwYXNzd29yZCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGtleVN0b3JlLmNvbnRhaW5zQWxpYXMoImtleWFsaWFzIikpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlTdG9yZS5sb2FkKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgiIi5nZXRCeXRlcygpKSwgcGFzc3dvcmQpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5U3RvcmUubG9hZChpcywgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5U3RvcmUubG9hZChpcywgbmV3IGNoYXJbXSB7fSk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RMb2FkTG9hZFN0b3JlUGFyYW1ldGVyKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5U3RvcmUubG9hZChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlTdG9yZS5sb2FkKG5ldyBLZXlTdG9yZS5Mb2FkU3RvcmVQYXJhbWV0ZXIoKSB7CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgUHJvdGVjdGlvblBhcmFtZXRlciBnZXRQcm90ZWN0aW9uUGFyYW1ldGVyKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEtleVN0b3JlLlBhc3N3b3JkUHJvdGVjdGlvbigiUEFTU1dPUkQiLnRvQ2hhckFycmF5KCkpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgfSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleVN0b3JlLmxvYWQobmV3IEtleVN0b3JlLkxvYWRTdG9yZVBhcmFtZXRlcigpIHsKKworICAgICAgICAgICAgICAgIHB1YmxpYyBQcm90ZWN0aW9uUGFyYW1ldGVyIGdldFByb3RlY3Rpb25QYXJhbWV0ZXIoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgfSk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5U3RvcmUubG9hZChuZXcgS2V5U3RvcmUuTG9hZFN0b3JlUGFyYW1ldGVyKCkgeworCisgICAgICAgICAgICAgICAgcHVibGljIFByb3RlY3Rpb25QYXJhbWV0ZXIgZ2V0UHJvdGVjdGlvblBhcmFtZXRlcigpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBLZXlTdG9yZS5Qcm90ZWN0aW9uUGFyYW1ldGVyKCkge307CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICB9KTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIENlcnRpZmljYXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEVudHJ5KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgRW50cnkgZW50cnkgPSBrZXlTdG9yZS5nZXRFbnRyeSgiY2VydGFsaWFzIiwgbnVsbCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJlbnRyeSBpcyBudWxsIiwgZW50cnkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZW50cnkgaXMgbm90IGNlcnQgZW50cnkiLCBlbnRyeSBpbnN0YW5jZW9mIEtleVN0b3JlLlRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5KTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKFVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVudHJ5IGVudHJ5ID0ga2V5U3RvcmUuZ2V0RW50cnkoImNlcnRhbGlhcyIsIG5ldyBLZXlTdG9yZS5Qcm90ZWN0aW9uUGFyYW1ldGVyKCkge30pOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChlbnRyeSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChVbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnRyeSBlbnRyeSA9IGtleVN0b3JlLmdldEVudHJ5KCJrZXlhbGlhcyIsIG5ldyBLZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb24obmV3IGNoYXJbXSB7fSApKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZW50cnkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShlbnRyeSBpbnN0YW5jZW9mIEtleVN0b3JlLlNlY3JldEtleUVudHJ5KTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKFVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleVN0b3JlLmdldEVudHJ5KCJ1bmtub3duYWxpYXMiLCBuZXcgS2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uKG5ldyBjaGFyW10ge30pKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoVW5yZWNvdmVyYWJsZUVudHJ5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGFsc28gb2sKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlTdG9yZS5nZXRFbnRyeShudWxsLCBuZXcgS2V5U3RvcmUuUHJvdGVjdGlvblBhcmFtZXRlcigpIHt9KTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChVbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VHlwZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEtFWV9TVE9SRV9UWVBFLCBrZXlTdG9yZS5nZXRUeXBlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQcm92aWRlcigpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChrZXlTdG9yZS5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub3QgZXF1YWwiLCBwcm92aWRlciwga2V5U3RvcmUuZ2V0UHJvdmlkZXIoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5U3RvcmVCdWlsZGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVN0b3JlQnVpbGRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMTRjZjIzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVN0b3JlQnVpbGRlclRlc3QuamF2YQpAQCAtMCwwICsxLDUyOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LktleVN0b3JlVGVzdFN1cHBvcnQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQudG1wQ2FsbGJhY2tIYW5kbGVyOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKKworcHVibGljIGNsYXNzIEtleVN0b3JlQnVpbGRlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2hhcltdIHBhc3MgPSB7ICdzJywgJ3QnLCAnbycsICdyJywgJ2UnLCAncCcsICd3JywgJ2QnIH07CisKKyAgICBwcml2YXRlIEtleVN0b3JlLlBhc3N3b3JkUHJvdGVjdGlvbiBwcm90UGFzcyA9IG5ldyBLZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb24oCisgICAgICAgICAgICBwYXNzKTsKKworICAgIHByaXZhdGUgdG1wQ2FsbGJhY2tIYW5kbGVyIHRtcENhbGwgPSBuZXcgdG1wQ2FsbGJhY2tIYW5kbGVyKCk7CisKKyAgICBwcml2YXRlIEtleVN0b3JlLkNhbGxiYWNrSGFuZGxlclByb3RlY3Rpb24gY2FsbGJhY2tIYW5kID0gbmV3IEtleVN0b3JlLkNhbGxiYWNrSGFuZGxlclByb3RlY3Rpb24oCisgICAgICAgICAgICB0bXBDYWxsKTsKKworICAgIHByaXZhdGUgTXlQcm90ZWN0aW9uUGFyYW1ldGVyIG15UHJvdFBhcmFtID0gbmV3IE15UHJvdGVjdGlvblBhcmFtZXRlcigKKyAgICAgICAgICAgIG5ldyBieXRlWzVdKTsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gdmFsaWRWYWx1ZXMgPSBLZXlTdG9yZVRlc3RTdXBwb3J0LnZhbGlkVmFsdWVzOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGRlZmF1bHRUeXBlID0gS2V5U3RvcmVUZXN0U3VwcG9ydC5kZWZhdWx0VHlwZTsKKworCisgICAgcHJpdmF0ZSBzdGF0aWMgUHJvdmlkZXIgZGVmYXVsdFByb3ZpZGVyID0gbnVsbDsKKworICAgIHN0YXRpYyB7CisgICAgICAgIGRlZmF1bHRQcm92aWRlciA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygKKyAgICAgICAgICAgICAgICAiS2V5U3RvcmUuIiArIEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpWzBdOworICAgIH0KKworICAgIC8qCisgICAgICogdGVzdCBmb3IgY29uc3RydWN0b3IgS2V5U3RvcmVCdWlsZGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdG9yKCkgeworICAgICAgICBLZXlTdG9yZUJ1aWxkZXIga3NiOworICAgICAgICB0cnkgeworICAgICAgICAgICAga3NiID0gbmV3IEtleVN0b3JlQnVpbGRlcigpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChrc2IpOworCisgICAgICAgICAgICBrc2IuZ2V0S2V5U3RvcmUoKTsKKyAgICAgICAgICAgIGtzYi5nZXRQcm90ZWN0aW9uUGFyYW1ldGVyKCJ0ZXN0Iik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiB0ZXN0IGZvciBtZXRob2QgbmV3SW5zdGFuY2UoS2V5U3RvcmUsIEtleVN0b3JlLlByb3RlY3Rpb25QYXJhbWV0ZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE5ld0luc3RhbmNlS2V5U3RvcmVQcm90ZWN0aW9uUGFyYW1ldGVyKCkKKyAgICAgICAgICAgIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gZXhjZXB0aW9ucyB2ZXJpZmljYXRpb24KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5U3RvcmUuQnVpbGRlci5uZXdJbnN0YW5jZShudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5U3RvcmUuQnVpbGRlci5uZXdJbnN0YW5jZShudWxsLCBwcm90UGFzcyk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgS2V5U3RvcmUuQnVpbGRlciBrc0I7CisKKyAgICAgICAgS2V5U3RvcmUga3MgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVN0b3JlLkJ1aWxkZXIubmV3SW5zdGFuY2Uoa3MsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBQcm90ZWN0aW9uUGFyYW1ldGVyIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIEtleVN0b3JlLlBhc3N3b3JkUHJvdGVjdGlvbiBwcm90UGFzczEgPSBuZXcgS2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uKAorICAgICAgICAgICAgICAgIHBhc3MpOworICAgICAgICBLZXlTdG9yZS5Qcm90ZWN0aW9uUGFyYW1ldGVyW10gcHAgPSB7IHByb3RQYXNzLCBwcm90UGFzczEsCisgICAgICAgICAgICAgICAgY2FsbGJhY2tIYW5kLCBteVByb3RQYXJhbSB9OworICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHAubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGtzID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEtleVN0b3JlLkJ1aWxkZXIubmV3SW5zdGFuY2Uoa3MsIHBwW2ldKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gYmVjYXVzZSBLZXlTdG9yZSB3YXMgbm90IGluaXRpYWxpemVkIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGtzLmxvYWQobnVsbCwgcGFzcyk7CisgICAgICAgICAgICBrc0IgPSBLZXlTdG9yZS5CdWlsZGVyLm5ld0luc3RhbmNlKGtzLCBwcFtpXSk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IEtleVN0b3JlIiwga3NCLmdldEtleVN0b3JlKCkuc2l6ZSgpLCAwKTsKKworICAgICAgICAgICAga3NCID0gS2V5U3RvcmUuQnVpbGRlci5uZXdJbnN0YW5jZShrcywgcHBbaV0pOworCisgICAgICAgICAgICAvLyB2ZXJpZmljYXRpb24gZ2V0S2V5U3RvcmUoKSBhbmQgZ2V0UHJvdGVjdGlvblBhcmFtZXRlcihTdHJpbmcKKyAgICAgICAgICAgIC8vIGFsaWFzKQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgS2V5U3RvcmUiLCBrcywga3NCLmdldEtleVN0b3JlKCkpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtzQi5nZXRQcm90ZWN0aW9uUGFyYW1ldGVyKG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhrc0IuZ2V0UHJvdGVjdGlvblBhcmFtZXRlcigiYWFhIiksIHBwW2ldKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkOiAiICsgZS50b1N0cmluZygpICsgIiB3YXMgdGhyb3duIik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGtzQi5nZXRQcm90ZWN0aW9uUGFyYW1ldGVyKCJCYWQgYWxpYXMiKSwgcHBbaV0pOworICAgICAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIEtleVN0b3JlRXhjZXB0aW9uIG1pZ2h0IGJlIHRocm93biBiZWNhdXNlIHRoZXJlIGlzIG5vIGVudHJ5CisgICAgICAgICAgICAgICAgLy8gd2l0aCBzdWNoIGFsaWFzCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGtzQi5nZXRQcm90ZWN0aW9uUGFyYW1ldGVyKCIiKSwgcHBbaV0pOworICAgICAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIEtleVN0b3JlRXhjZXB0aW9uIG1pZ2h0IGJlIHRocm93biBiZWNhdXNlIHRoZXJlIGlzIG5vIGVudHJ5CisgICAgICAgICAgICAgICAgLy8gd2l0aCBzdWNoIGFsaWFzCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEtleVN0b3JlLlByb3RlY3Rpb25QYXJhbWV0ZXIgcFBhciA9IGtzQgorICAgICAgICAgICAgICAgICAgICAuZ2V0UHJvdGVjdGlvblBhcmFtZXRlcigiYWFhIik7CisKKyAgICAgICAgICAgIHN3aXRjaCAoaSkgeworICAgICAgICAgICAgY2FzZSAwOgorICAgICAgICAgICAgICAgIGFzc2VydFRydWUocFBhciBpbnN0YW5jZW9mIEtleVN0b3JlLlBhc3N3b3JkUHJvdGVjdGlvbik7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIDE6CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShwUGFyIGluc3RhbmNlb2YgS2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgMjoKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKHBQYXIgaW5zdGFuY2VvZiBLZXlTdG9yZS5DYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgMzoKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKHBQYXIgaW5zdGFuY2VvZiBNeVByb3RlY3Rpb25QYXJhbWV0ZXIpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICBmYWlsKCJJbmNvcnJlY3QgcHJvdGVjdGlvbiBwYXJhbWV0ZXIiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhwUGFyLCBwcFtpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFRlc3QgZm9yIG1ldGhvZHM6IDxjb2RlPm5ld0luc3RhbmNlKFN0cmluZyB0eXBlLCBQcm92aWRlciBwcm92aWRlciwgRmlsZQorICAgICAqIGZpbGUsIFByb3RlY3Rpb25QYXJhbWV0ZXIgcHJvdGVjdGlvblBhcmFtZXRlcik8L2NvZGU+IDxjb2RlPmdldEtleVN0b3JlKCk8L2NvZGU+CisgICAgICogPGNvZGU+Z2V0UHJvdGVjdGlvblBhcmFtZXRlcihTdHJpbmcgYWxpYXMpPC9jb2RlPiBBc3NlcnRpb25zOiB0aHJvd3MKKyAgICAgKiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0eXBlLCBmaWxlIG9yIHByb3RlY3Rpb25QYXJhbWV0ZXIgaXMgbnVsbDsgdGhyb3dzCisgICAgICogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGZpbGUgZG9lcyBub3QgZXhpc3Qgb3IgaXMgbm90IGZpbGU7IHRocm93cworICAgICAqIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBQcm90ZWN0aW9uUGFyYW1ldGVyIGlzIG5vdCBQYXNzd29yZFByb3RlY3Rpb24KKyAgICAgKiBvciBDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uOyByZXR1cm5zIG5ldyBvYmplY3QKKyAgICAgKgorICAgICAqIGdldEtleVN0b3JlKCkgcmV0dXJucyBzcGVjaWZpZWQga2V5c3RvcmU7IGdldFByb3RlY3Rpb25QYXJhbWV0ZXIoU3RyaW5nCisgICAgICogYWxpYXMpIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIGFsaWFzIGlzIG51bGw7IHRocm93cworICAgICAqIEtleVN0b3JlRXhjZXB0aW9uIHdoZW4gYWxpYXMgaXMgbm90IGF2YWlsYWJsZTsgcmV0dXJucworICAgICAqIFByb3RlY3Rpb25QYXJhbWV0ZXIgd2hpY2ggaXMgdXNlZCBpbiBuZXdJbnN0YW5jZSguLi4pCisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV3SW5zdGFuY2VTdHJpbmdQcm92aWRlckZpbGVQcm90ZWN0aW9uUGFyYW1ldGVyKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIEZpbGUgZmwgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJLU0J1aWxkZXJfSW1wbFRlc3QiLCAia2V5c3RvcmUiKTsKKyAgICAgICAgZmwuZGVsZXRlT25FeGl0KCk7CisgICAgICAgIEtleVN0b3JlLkJ1aWxkZXIga3NCOworICAgICAgICBLZXlTdG9yZS5CdWlsZGVyIGtzQjE7CisgICAgICAgIEtleVN0b3JlIGtzID0gbnVsbDsKKyAgICAgICAgS2V5U3RvcmUga3MxID0gbnVsbDsKKworICAgICAgICBNeVByb3RlY3Rpb25QYXJhbWV0ZXIgbXlQUCA9IG5ldyBNeVByb3RlY3Rpb25QYXJhbWV0ZXIobmV3IGJ5dGVbNV0pOworICAgICAgICAvLyBjaGVjayBleGNlcHRpb25zCisgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgIEtleVN0b3JlLkJ1aWxkZXIubmV3SW5zdGFuY2UobnVsbCwgZGVmYXVsdFByb3ZpZGVyLCBmbCwgcHJvdFBhc3MpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiB0eXBlIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZS5CdWlsZGVyLm5ld0luc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCksIGRlZmF1bHRQcm92aWRlciwgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgcHJvdFBhc3MpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBmaWxlIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZS5CdWlsZGVyCisgICAgICAgICAgICAgICAgICAgIC5uZXdJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpLCBkZWZhdWx0UHJvdmlkZXIsIGZsLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gUHJvdGVjdGlvblBhcmFtZXRlciBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5U3RvcmUuQnVpbGRlcgorICAgICAgICAgICAgICAgICAgICAubmV3SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSwgZGVmYXVsdFByb3ZpZGVyLCBmbCwgbXlQUCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBQcm90ZWN0aW9uUGFyYW1ldGVyIGlzIG5vdCBjb3JyZWN0Iik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVN0b3JlLkJ1aWxkZXIubmV3SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSwgZGVmYXVsdFByb3ZpZGVyLAorICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZShmbC5nZXRBYnNvbHV0ZVBhdGgoKS5jb25jYXQoInNob3VsZF9hYnNlbnQiKSksCisgICAgICAgICAgICAgICAgICAgIHByb3RQYXNzKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIGZpbGUgZG9lcyBub3QgZXhpc3QiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gJ2ZpbGUnIHBhcmFtIHBvaW50cyB0byBkaXJlY3RvcnkKKyAgICAgICAgICAgIEtleVN0b3JlLkJ1aWxkZXIubmV3SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSwgZGVmYXVsdFByb3ZpZGVyLCBmbAorICAgICAgICAgICAgICAgICAgICAuZ2V0UGFyZW50RmlsZSgpLCBwcm90UGFzcyk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBmaWxlIGRvZXMgbm90IGV4aXN0Iik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAga3NCID0gS2V5U3RvcmUuQnVpbGRlci5uZXdJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpLCBkZWZhdWx0UHJvdmlkZXIsIGZsLAorICAgICAgICAgICAgICAgIHByb3RQYXNzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtzQi5nZXRLZXlTdG9yZSgpOworICAgICAgICAgICAgZmFpbCgiS2V5U3RvcmVFeGNlcHRpb24gbXVzdCBiZSB0aHJvdyBiZWNhdXNlIGZpbGUgaXMgZW1wdHkiKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgZmwgPSBjcmVhdGVLUygpOworCisgICAgICAgIC8vIEV4Y2VwdGlvbiBUZXN0cyB3aXRoIGN1c3RvbSBQcm90ZWN0aW9uUGFyYW1ldGVyCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZS5CdWlsZGVyLm5ld0luc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCksCisgICAgICAgICAgICAgICAgICAgIG51bGwsIGZsLCBteVBQKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlICIKKyAgICAgICAgICAgICAgICAgICAgKyAidGhyb3duIGZvciBpbmNvcnJlY3QgUHJvdGVjdGlvblBhcmFtZXRlciIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZS5CdWlsZGVyLm5ld0luc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCksCisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlciwgZmwsIG15UFApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgIgorICAgICAgICAgICAgICAgICAgICArICJ0aHJvd24gZm9yIGluY29ycmVjdCBQcm90ZWN0aW9uUGFyYW1ldGVyIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICAvLyBUZXN0cyB3aXRoIFBhc3N3b3JkUHJvdGVjdGlvbgorICAgICAgICBrc0IgPSBLZXlTdG9yZS5CdWlsZGVyLm5ld0luc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCksCisgICAgICAgICAgICAgICAgbnVsbCwgZmwsIHByb3RQYXNzKTsKKyAgICAgICAga3NCMSA9IEtleVN0b3JlLkJ1aWxkZXIubmV3SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSwKKyAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXIsIGZsLCBwcm90UGFzcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrcyA9IGtzQi5nZXRLZXlTdG9yZSgpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIEtleUV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtzMSA9IGtzQjEuZ2V0S2V5U3RvcmUoKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBLZXlFeGNlcHRpb24gd2FzIHRocm93bjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBLZXlTdG9yZSBzaXplIiwga3Muc2l6ZSgpLCBrczEuc2l6ZSgpKTsKKyAgICAgICAgOworCisgICAgICAgIGZvciAoRW51bWVyYXRpb248U3RyaW5nPiBhbGlhc2VzID0ga3MuYWxpYXNlcygpOyBhbGlhc2VzLmhhc01vcmVFbGVtZW50cygpOyApIHsKKyAgICAgICAgICAgIFN0cmluZyBhTmFtZSA9IGFsaWFzZXMubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgUHJvdGVjdGlvblBhcmFtZXRlciIsIGtzQgorICAgICAgICAgICAgICAgICAgICAgICAgLmdldFByb3RlY3Rpb25QYXJhbWV0ZXIoYU5hbWUpLCBwcm90UGFzcyk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQ6ICIgKyBlLnRvU3RyaW5nKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiB3YXMgdGhyb3duIGZvciBhbGlhczogIiArIGFOYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGtzQi5nZXRLZXlTdG9yZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoa3NCLmdldFByb3RlY3Rpb25QYXJhbWV0ZXIoIkJhZCBhbGlhcyIpLCBwcm90UGFzcyk7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEtleVN0b3JlRXhjZXB0aW9uIG1pZ2h0IGJlIHRocm93biBiZWNhdXNlIHRoZXJlIGlzIG5vIGVudHJ5CisgICAgICAgICAgICAvLyB3aXRoIHN1Y2ggYWxpYXMKKyAgICAgICAgfQorCisKKyAgICAgICAgZm9yIChFbnVtZXJhdGlvbjxTdHJpbmc+IGFsaWFzZXMgPSBrczEuYWxpYXNlcygpOyBhbGlhc2VzLmhhc01vcmVFbGVtZW50cygpOyApIHsKKyAgICAgICAgICAgIFN0cmluZyBhTmFtZSA9IGFsaWFzZXMubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IFByb3RlY3Rpb25QYXJhbWV0ZXIiLCBrc0IxCisgICAgICAgICAgICAgICAgICAgIC5nZXRQcm90ZWN0aW9uUGFyYW1ldGVyKGFOYW1lKSwgcHJvdFBhc3MpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhrc0IxLmdldFByb3RlY3Rpb25QYXJhbWV0ZXIoIkJhZCBhbGlhcyIpLCBwcm90UGFzcyk7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEtleVN0b3JlRXhjZXB0aW9uIG1pZ2h0IGJlIHRocm93biBiZWNhdXNlIHRoZXJlIGlzIG5vIGVudHJ5CisgICAgICAgICAgICAvLyB3aXRoIHN1Y2ggYWxpYXMKKyAgICAgICAgfQorCisKKyAgICAgICAgLy8gVGVzdHMgd2l0aCBDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uCisgICAgICAgIGtzQiA9IEtleVN0b3JlLkJ1aWxkZXIubmV3SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSwKKyAgICAgICAgICAgICAgICBudWxsLCBmbCwgY2FsbGJhY2tIYW5kKTsKKyAgICAgICAga3NCMSA9IEtleVN0b3JlLkJ1aWxkZXIubmV3SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSwKKyAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXIsIGZsLCBjYWxsYmFja0hhbmQpOworICAgICAgICB0cnkgeworICAgICAgICAgICAga3MgPSBrc0IuZ2V0S2V5U3RvcmUoKTsKKyAgICAgICAgICAgIGZhaWwoIktleVN0b3JlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIGZvciBpbmNvcnJlY3QgIgorICAgICAgICAgICAgICAgICAgICArICJQcm90ZWN0aW9uUGFyYW1ldGVyIik7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAga3MxID0ga3NCMS5nZXRLZXlTdG9yZSgpOworICAgICAgICAgICAgZmFpbCgiS2V5U3RvcmVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gZm9yIGluY29ycmVjdCAiCisgICAgICAgICAgICAgICAgICAgICsgIlByb3RlY3Rpb25QYXJhbWV0ZXIiKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IEtleVN0b3JlIHNpemUiLCBrcy5zaXplKCksIGtzMS5zaXplKCkpOworCisgICAgICAgIGZvciAoRW51bWVyYXRpb248U3RyaW5nPiBhbGlhc2VzID0ga3MuYWxpYXNlcygpOyBhbGlhc2VzLmhhc01vcmVFbGVtZW50cygpOykgeworICAgICAgICAgICAgU3RyaW5nIGFOYW1lID0gYWxpYXNlcy5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBQcm90ZWN0aW9uUGFyYW1ldGVyIiwga3NCCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0UHJvdGVjdGlvblBhcmFtZXRlcihhTmFtZSksIGNhbGxiYWNrSGFuZCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQ6ICIgKyBlLnRvU3RyaW5nKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiB3YXMgdGhyb3duIGZvciBhbGlhczogIiArIGFOYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoRW51bWVyYXRpb248U3RyaW5nPiBpdGVyID0ga3MxLmFsaWFzZXMoKTsgaXRlci5oYXNNb3JlRWxlbWVudHMoKTspIHsKKyAgICAgICAgICAgIFN0cmluZyBhTmFtZSA9IGl0ZXIubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IFByb3RlY3Rpb25QYXJhbWV0ZXIiLCBrc0IxCisgICAgICAgICAgICAgICAgICAgIC5nZXRQcm90ZWN0aW9uUGFyYW1ldGVyKGFOYW1lKSwgY2FsbGJhY2tIYW5kKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogVGVzdCBmb3IgbWV0aG9kOiA8Y29kZT5uZXdJbnN0YW5jZShTdHJpbmcgdHlwZSwgUHJvdmlkZXIgcHJvdmlkZXIsCisgICAgICogUHJvdGVjdGlvblBhcmFtZXRlciBwcm90ZWN0aW9uUGFyYW1ldGVyKTwvY29kZT4gPGNvZGU+Z2V0S2V5U3RvcmUoKTwvY29kZT4KKyAgICAgKiA8Y29kZT5nZXRQcm90ZWN0aW9uUGFyYW1ldGVyKFN0cmluZyBhbGlhcyk8L2NvZGU+IEFzc2VydGlvbnM6IHRocm93cworICAgICAqIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHR5cGUsIG9yIHByb3RlY3Rpb25QYXJhbWV0ZXIgaXMgbnVsbDsgcmV0dXJucyBuZXcKKyAgICAgKiBvYmplY3QKKyAgICAgKgorICAgICAqIGdldEtleVN0b3JlKCkgcmV0dXJucyBlbXB0eSBrZXlzdG9yZSBnZXRQcm90ZWN0aW9uUGFyYW1ldGVyKFN0cmluZyBhbGlhcykKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBhbGlhcyBpcyBudWxsOyB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24KKyAgICAgKiB3aGVuIGFsaWFzIGlzIG5vdCBhdmFpbGFibGUKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3ROZXdJbnN0YW5jZVN0cmluZ1Byb3ZpZGVyUHJvdGVjdGlvblBhcmFtZXRlcigpCisgICAgICAgICAgICB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZS5CdWlsZGVyLm5ld0luc3RhbmNlKG51bGwsIGRlZmF1bHRQcm92aWRlciwgcHJvdFBhc3MpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiB0eXBlIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZS5CdWlsZGVyLm5ld0luc3RhbmNlKGRlZmF1bHRUeXBlLCBkZWZhdWx0UHJvdmlkZXIsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBQcm90ZWN0aW9uUGFyYW1ldGVyIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIE15UHJvdGVjdGlvblBhcmFtZXRlciBteVBQID0gbmV3IE15UHJvdGVjdGlvblBhcmFtZXRlcihuZXcgYnl0ZVs1XSk7CisgICAgICAgIEtleVN0b3JlLlByb3RlY3Rpb25QYXJhbWV0ZXJbXSBwcCA9IHsgcHJvdFBhc3MsIG15UFAsIGNhbGxiYWNrSGFuZCB9OworICAgICAgICBLZXlTdG9yZS5CdWlsZGVyIGtzQiwga3NCMTsKKyAgICAgICAgS2V5U3RvcmUga3MgPSBudWxsOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBwLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBrc0IgPSBLZXlTdG9yZS5CdWlsZGVyLm5ld0luc3RhbmNlKGRlZmF1bHRUeXBlLCBkZWZhdWx0UHJvdmlkZXIsCisgICAgICAgICAgICAgICAgICAgIHBwW2ldKTsKKyAgICAgICAgICAgIGtzQjEgPSBLZXlTdG9yZS5CdWlsZGVyLm5ld0luc3RhbmNlKGRlZmF1bHRUeXBlLCBudWxsLCBwcFtpXSk7CisgICAgICAgICAgICBzd2l0Y2ggKGkpIHsKKyAgICAgICAgICAgIGNhc2UgMDoKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBrcyA9IGtzQi5nZXRLZXlTdG9yZSgpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJLZXlTdG9yZSBpcyBudWxsIiwga3MpOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGtzQi5nZXRQcm90ZWN0aW9uUGFyYW1ldGVyKCJCYWQgYWxpYXMiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHBbaV0pOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBLZXlTdG9yZUV4Y2VwdGlvbiBtaWdodCBiZSB0aHJvd24gYmVjYXVzZSB0aGVyZSBpcyBubworICAgICAgICAgICAgICAgICAgICAgICAgLy8gZW50cnkgd2l0aCBzdWNoIGFsaWFzCisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBrcyA9IGtzQjEuZ2V0S2V5U3RvcmUoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiS2V5U3RvcmUgaXMgbnVsbCIsIGtzKTsKKworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGtzQjEuZ2V0UHJvdGVjdGlvblBhcmFtZXRlcigiQmFkIGFsaWFzIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBwW2ldKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gS2V5U3RvcmVFeGNlcHRpb24gbWlnaHQgYmUgdGhyb3duIGJlY2F1c2UgdGhlcmUgaXMgbm8KKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVudHJ5IHdpdGggc3VjaCBhbGlhcworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAga3MgPSBrc0IuZ2V0S2V5U3RvcmUoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGV4Y2VwdGlvbiIsIGUuZ2V0TWVzc2FnZSgpLCBlMQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgMToKKyAgICAgICAgICAgIGNhc2UgMjoKKyAgICAgICAgICAgICAgICBFeGNlcHRpb24gZXgxID0gbnVsbDsKKyAgICAgICAgICAgICAgICBFeGNlcHRpb24gZXgyID0gbnVsbDsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBrcyA9IGtzQi5nZXRLZXlTdG9yZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZXgxID0gZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAga3MgPSBrc0IuZ2V0S2V5U3RvcmUoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGV4MiA9IGU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGV4Y2VwdGlvbiIsIGV4MS5nZXRNZXNzYWdlKCksIGV4MgorICAgICAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSk7CisKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBrc0IuZ2V0UHJvdGVjdGlvblBhcmFtZXRlcigiYWFhIik7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biBiZWNhdXNlIGdldEtleVN0b3JlKCkgd2FzIG5vdCBpbnZva2VkIik7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBrcyA9IGtzQjEuZ2V0S2V5U3RvcmUoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGV4MSA9IGU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtzID0ga3NCMS5nZXRLZXlTdG9yZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZXgyID0gZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgZXhjZXB0aW9uIiwgZXgxLmdldE1lc3NhZ2UoKSwgZXgyCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZSgpKTsKKworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtzQjEuZ2V0UHJvdGVjdGlvblBhcmFtZXRlcigiYWFhIik7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biBiZWNhdXNlIGdldEtleVN0b3JlKCkgd2FzIG5vdCBpbnZva2VkIik7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZGl0aW9uYWwgY2xhc3MgZm9yIGNyZWF0aW5nIEtleVN0b3JlQnVpbGRlcgorICAgICAqLworICAgIGNsYXNzIE15UHJvdGVjdGlvblBhcmFtZXRlciBpbXBsZW1lbnRzIEtleVN0b3JlLlByb3RlY3Rpb25QYXJhbWV0ZXIgeworICAgICAgICBwdWJsaWMgTXlQcm90ZWN0aW9uUGFyYW1ldGVyKGJ5dGVbXSBwYXJhbSkgeworICAgICAgICAgICAgaWYgKHBhcmFtID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInBhcmFtIGlzIG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworLy8gICAgIENyZWF0ZXMgZW1wdHkgS2V5U3RvcmUgYW5kIGxvYWRzIGl0IHRvIGZpbGUKKyAgICBwcml2YXRlIEZpbGUgY3JlYXRlS1MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBmb3MgPSBudWxsOworICAgICAgICBGaWxlIGZmID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiS1NCdWlsZGVyX0ltcGxUZXN0IiwgImtleXN0b3JlIik7CisgICAgICAgIGZmLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBLZXlTdG9yZSBrcyA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICAgICAgZm9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZmYpOworICAgICAgICAgICAga3MubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGtzLnN0b3JlKGZvcywgcGFzcyk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoZm9zICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBmb3MuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmZjsKKyAgICB9CisKKyAgICBjbGFzcyBLZXlTdG9yZUJ1aWxkZXIgZXh0ZW5kcyBLZXlTdG9yZS5CdWlsZGVyIHsKKyAgICAgICAgcHVibGljIEtleVN0b3JlQnVpbGRlcigpIHsKKyAgICAgICAgICAgIHN1cGVyKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgS2V5U3RvcmUgZ2V0S2V5U3RvcmUoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBLZXlTdG9yZS5Qcm90ZWN0aW9uUGFyYW1ldGVyIGdldFByb3RlY3Rpb25QYXJhbWV0ZXIoU3RyaW5nIGFsaWFzKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlTdG9yZUV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlTdG9yZUV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NGMzYTkwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVN0b3JlRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTc1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlRXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5LZXlTdG9yZUV4Y2VwdGlvbjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIEtleVN0b3JlRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIG1zZ3MgPSB7CisgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UiIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBUaHJvd2FibGUgdENhdXNlID0gbmV3IFRocm93YWJsZSgiVGhyb3dhYmxlIGZvciBleGNlcHRpb24iKTsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPktleVN0b3JlRXhjZXB0aW9uKCk8L2NvZGU+IGNvbnN0cnVjdG9yIEFzc2VydGlvbjoKKyAgICAgKiBjb25zdHJ1Y3RzIEtleVN0b3JlRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5U3RvcmVFeGNlcHRpb24wMSgpIHsKKyAgICAgICAgS2V5U3RvcmVFeGNlcHRpb24gdEUgPSBuZXcgS2V5U3RvcmVFeGNlcHRpb24oKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+S2V5U3RvcmVFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgS2V5U3RvcmVFeGNlcHRpb24gd2l0aCBkZXRhaWwgbWVzc2FnZSBtc2cuIFBhcmFtZXRlcgorICAgICAqIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEtleVN0b3JlRXhjZXB0aW9uMDIoKSB7CisgICAgICAgIEtleVN0b3JlRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IEtleVN0b3JlRXhjZXB0aW9uKG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm46ICIuY29uY2F0KG1zZ3NbaV0pLCB0RQorICAgICAgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZSgpLCBtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+S2V5U3RvcmVFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgS2V5U3RvcmVFeGNlcHRpb24gd2hlbiA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5U3RvcmVFeGNlcHRpb24wMygpIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9IG51bGw7CisgICAgICAgIEtleVN0b3JlRXhjZXB0aW9uIHRFID0gbmV3IEtleVN0b3JlRXhjZXB0aW9uKG1zZyk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPktleVN0b3JlRXhjZXB0aW9uKFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEtleVN0b3JlRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5U3RvcmVFeGNlcHRpb24wNCgpIHsKKyAgICAgICAgVGhyb3dhYmxlIGNhdXNlID0gbnVsbDsKKyAgICAgICAgS2V5U3RvcmVFeGNlcHRpb24gdEUgPSBuZXcgS2V5U3RvcmVFeGNlcHRpb24oY2F1c2UpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5LZXlTdG9yZUV4Y2VwdGlvbihUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBLZXlTdG9yZUV4Y2VwdGlvbiB3aGVuIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QKKyAgICAgKiBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEtleVN0b3JlRXhjZXB0aW9uMDUoKSB7CisgICAgICAgIEtleVN0b3JlRXhjZXB0aW9uIHRFID0gbmV3IEtleVN0b3JlRXhjZXB0aW9uKHRDYXVzZSk7CisgICAgICAgIGlmICh0RS5nZXRNZXNzYWdlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgc2hvdWxkIGNvbnRhaW4gIi5jb25jYXQodG9TKSwgKGdldE0KKyAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwgdEUKKyAgICAgICAgICAgICAgICAuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5LZXlTdG9yZUV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEtleVN0b3JlRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwKKyAgICAgKiA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5U3RvcmVFeGNlcHRpb24wNigpIHsKKyAgICAgICAgS2V5U3RvcmVFeGNlcHRpb24gdEUgPSBuZXcgS2V5U3RvcmVFeGNlcHRpb24obnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+S2V5U3RvcmVFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBLZXlTdG9yZUV4Y2VwdGlvbiB3aGVuIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBudWxsCisgICAgICogPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlTdG9yZUV4Y2VwdGlvbjA3KCkgeworICAgICAgICBLZXlTdG9yZUV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBLZXlTdG9yZUV4Y2VwdGlvbihtc2dzW2ldLCBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPktleVN0b3JlRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgS2V5U3RvcmVFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90CisgICAgICogbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5U3RvcmVFeGNlcHRpb24wOCgpIHsKKyAgICAgICAgS2V5U3RvcmVFeGNlcHRpb24gdEUgPSBuZXcgS2V5U3RvcmVFeGNlcHRpb24obnVsbCwgdENhdXNlKTsKKyAgICAgICAgaWYgKHRFLmdldE1lc3NhZ2UoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IHNob3VsZCAiLmNvbmNhdCh0b1MpLCAoZ2V0TQorICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgIC5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPktleVN0b3JlRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgS2V5U3RvcmVFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90CisgICAgICogbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEtleVN0b3JlRXhjZXB0aW9uMDkoKSB7CisgICAgICAgIEtleVN0b3JlRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IEtleVN0b3JlRXhjZXB0aW9uKG1zZ3NbaV0sIHRDYXVzZSk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGlmIChtc2dzW2ldLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IGNvbnRhaW4gIi5jb25jYXQobXNnc1tpXSksIGdldE0KKyAgICAgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKG1zZ3NbaV0pICE9IC0xKTsKKyAgICAgICAgICAgICAgICBpZiAoIWdldE0uZXF1YWxzKG1zZ3NbaV0pKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBzaG91bGQgY29udGFpbiAiLmNvbmNhdCh0b1MpLCBnZXRNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwKKyAgICAgICAgICAgICAgICAgICAgdEUuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlTdG9yZUxvYWRTdG9yZVBhcmFtZXRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlTdG9yZUxvYWRTdG9yZVBhcmFtZXRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MWVjMzBkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVN0b3JlTG9hZFN0b3JlUGFyYW1ldGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTUgQEAKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworCitwdWJsaWMgY2xhc3MgS2V5U3RvcmVMb2FkU3RvcmVQYXJhbWV0ZXJUZXN0IHsKKworICAgIGNsYXNzIE15TG9hZFN0b3JlUGFyYW1ldGVyIGltcGxlbWVudHMgS2V5U3RvcmUuTG9hZFN0b3JlUGFyYW1ldGVyIHsKKyAgICAgICBwdWJsaWMgS2V5U3RvcmUuUHJvdGVjdGlvblBhcmFtZXRlciBnZXRQcm90ZWN0aW9uUGFyYW1ldGVyKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgfQorICAgIH0KKworCisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlTdG9yZVByaXZhdGVLZXlFbnRyeVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlTdG9yZVByaXZhdGVLZXlFbnRyeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYmE1YmY2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVN0b3JlUHJpdmF0ZUtleUVudHJ5VGVzdC5qYXZhCkBAIC0wLDAgKzEsNzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBLZXlTdG9yZVByaXZhdGVLZXlFbnRyeVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q2VydGlmaWNhdGVDaGFpbigpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIFN0cmluZyBjZXJ0aWZpY2F0ZURhdGEgPSAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICAgICAgICAgKyAiTUlJQ1pUQ0NBZElDQlFMM0FBQzJNQTBHQ1NxR1NJYjNEUUVCQWdVQU1GOHhDekFKQmdOVkJBWVRBbFZUTVNBd1xuIgorICAgICAgICAgICAgICAgICsgIkhnWURWUVFLRXhkU1UwRWdSR0YwWVNCVFpXTjFjbWwwZVN3Z1NXNWpMakV1TUN3R0ExVUVDeE1sVTJWamRYSmxcbiIKKyAgICAgICAgICAgICAgICArICJJRk5sY25abGNpQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVRBZUZ3MDVOekF5TWpBd01EQXdNREJhXG4iCisgICAgICAgICAgICAgICAgKyAiRncwNU9EQXlNakF5TXpVNU5UbGFNSUdXTVFzd0NRWURWUVFHRXdKVlV6RVRNQkVHQTFVRUNCTUtRMkZzYVdadlxuIgorICAgICAgICAgICAgICAgICsgImNtNXBZVEVTTUJBR0ExVUVCeE1KVUdGc2J5QkJiSFJ2TVI4d0hRWURWUVFLRXhaVGRXNGdUV2xqY205emVYTjBcbiIKKyAgICAgICAgICAgICAgICArICJaVzF6TENCSmJtTXVNU0V3SHdZRFZRUUxFeGhVWlhOMElHRnVaQ0JGZG1Gc2RXRjBhVzl1SUU5dWJIa3hHakFZXG4iCisgICAgICAgICAgICAgICAgKyAiQmdOVkJBTVRFV0Z5WjI5dUxtVnVaeTV6ZFc0dVkyOXRNSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdOQURDQlxuIgorICAgICAgICAgICAgICAgICsgImlRS0JnUUNvZm1kWStQaVVXTjAxRk96RWV3ZitHYUcrbEZmMTMyVXB6QVRtWUprQTRBRUEvanVXN2pTaStMSmtcbiIKKyAgICAgICAgICAgICAgICArICJ3SktpNUdPNFJ5Wm95aW1BTC81eUlXRFY2bDFLbHZ4eUtzbHIwUkVoTUJhRC8zWjNFc0xUVEVmNWdWclFTNnNUXG4iCisgICAgICAgICAgICAgICAgKyAiV01vU1pBeXpCMzlrRmZzQjZvVVhOdFY4K1VLS3hTeEtieHZoUW4yNjdQZUN6NVZYMlFJREFRQUJNQTBHQ1NxR1xuIgorICAgICAgICAgICAgICAgICsgIlNJYjNEUUVCQWdVQUEzNEFYbDNhdDZsdWlWLzdJOU1ONUNYWW9QSllJOEJjZGMxaEJhZ0p2VE1jbWxxTDJ1T1pcbiIKKyAgICAgICAgICAgICAgICArICJIOVQ1aE5NRUw5VGs2YUk3eVpQWGN3L3hJMks2cE9SL0ZyTXAwVXdKbWR4WDdsalY2WnRVWmY3cFk0OTJVcXdDXG4iCisgICAgICAgICAgICAgICAgKyAiMTc3N1hROVVFWnlyS0p2RjVudGxlZU8wYXlCcUxHVktDV3pXWlg5WXNYQ3B2NDdGTkxaYnVwRT1cbiIKKyAgICAgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iOworCisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGNlcnRBcnJheTsKKyAgICAgICAgeworICAgICAgICAgICAgdHJ5eworICAgICAgICAgICAgICAgICBjZXJ0QXJyYXkgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgIGNlcnRpZmljYXRlRGF0YS5nZXRCeXRlcygiVVRGLTgiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBDZXJ0aWZpY2F0ZSBjZXJ0aWZpY2F0ZSA9IGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjZXJ0aWZpY2F0ZSBpbnN0YW5jZW9mIFg1MDlDZXJ0aWZpY2F0ZSk7CisKKyAgICAgICAgU3RyaW5nIGFsZ29yaXRobSA9IGNlcnRpZmljYXRlLmdldFB1YmxpY0tleSgpLmdldEFsZ29yaXRobSgpOworICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGtleVBhaXJHZW5lcmF0b3IgPSBLZXlQYWlyR2VuZXJhdG9yCisgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgIEtleVBhaXIga2V5UGFpciA9IGtleVBhaXJHZW5lcmF0b3IuZ2VuZXJhdGVLZXlQYWlyKCk7CisgICAgICAgIFByaXZhdGVLZXkgcHJpdmF0ZUtleSA9IGtleVBhaXIuZ2V0UHJpdmF0ZSgpOworCisgICAgICAgIC8vIElmIGFsbCB0aGUgY2VydGlmaWNhdGUgaW4gdGhlIGNoYWluIGlzIFg1MDlDZXJ0aWZpY2F0ZSwKKyAgICAgICAgLy8gS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5IHdpbGwgcmV0dXJuIGEgWDUwOUNlcnRpZmljYXRlIGFycmF5LgorICAgICAgICBLZXlTdG9yZS5Qcml2YXRlS2V5RW50cnkgcHJpdmF0ZUtleUVudHJ5ID0gbmV3IEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSgKKyAgICAgICAgICAgICAgICBwcml2YXRlS2V5LCBuZXcgQ2VydGlmaWNhdGVbXSB7IGNlcnRpZmljYXRlIH0pOworICAgICAgICBDZXJ0aWZpY2F0ZVtdIGNoYWluID0gcHJpdmF0ZUtleUVudHJ5LmdldENlcnRpZmljYXRlQ2hhaW4oKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjaGFpbiBpbnN0YW5jZW9mIFg1MDlDZXJ0aWZpY2F0ZVtdKTsKKworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlTdG9yZVNwaVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlTdG9yZVNwaVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZmRkZGJiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVN0b3JlU3BpVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjgxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyAqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5NeUtleVN0b3JlU3BpOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0Lk15TG9hZFN0b3JlUGFyYW1zOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZVNwaTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuVW5yZWNvdmVyYWJsZUVudHJ5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlLkxvYWRTdG9yZVBhcmFtZXRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5LZXlTdG9yZVNwaTwvY29kZT4gY29uc3RydWN0b3IgYW5kIG1ldGhvZHMKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBLZXlTdG9yZVNwaVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiY2FzdCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9LZXlTdG9yZVNwaSgpIHsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTXlLZXlTdG9yZVNwaSBrc1NwaSA9IG5ldyBNeUtleVN0b3JlU3BpKCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGtzU3BpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoa3NTcGkgaW5zdGFuY2VvZiBLZXlTdG9yZVNwaSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogamF2YS5zZWN1cml0eS5LZXlTdG9yZS5lbmdpbmVFbnRyeUluc3RhbmNlT2YoU3RyaW5nLCBDbGFzczw/CisgICAgICogZXh0ZW5kcyBFbnRyeT4pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9lbmdpbmVFbnRyeUluc3RhbmNlT2YoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBLZXlTdG9yZVNwaSBrc1NwaSA9IG5ldyBNeUtleVN0b3JlU3BpKCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShrc1NwaS5lbmdpbmVFbnRyeUluc3RhbmNlT2YoCisgICAgICAgICAgICAgICAgInRlc3RfZW5naW5lRW50cnlJbnN0YW5jZU9mX0FsaWFzMSIsCisgICAgICAgICAgICAgICAgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5LmNsYXNzKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2Uoa3NTcGkuZW5naW5lRW50cnlJbnN0YW5jZU9mKAorICAgICAgICAgICAgICAgICJ0ZXN0X2VuZ2luZUVudHJ5SW5zdGFuY2VPZl9BbGlhczIiLAorICAgICAgICAgICAgICAgIEtleVN0b3JlLlNlY3JldEtleUVudHJ5LmNsYXNzKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2Uoa3NTcGkuZW5naW5lRW50cnlJbnN0YW5jZU9mKAorICAgICAgICAgICAgICAgICJ0ZXN0X2VuZ2luZUVudHJ5SW5zdGFuY2VPZl9BbGlhczMiLAorICAgICAgICAgICAgICAgIEtleVN0b3JlLlRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5LmNsYXNzKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGtzU3BpLmVuZ2luZUVudHJ5SW5zdGFuY2VPZihudWxsLAorICAgICAgICAgICAgICAgICAgICBLZXlTdG9yZS5UcnVzdGVkQ2VydGlmaWNhdGVFbnRyeS5jbGFzcykpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGtzU3BpLmVuZ2luZUVudHJ5SW5zdGFuY2VPZigKKyAgICAgICAgICAgICAgICAgICAgInRlc3RfZW5naW5lRW50cnlJbnN0YW5jZU9mX0FsaWFzMSIsIG51bGwpKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5U3RvdGVTcGkwMSgpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgQ2VydGlmaWNhdGVFeGNlcHRpb24sCisgICAgICAgICAgICBVbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb24sIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5U3RvcmVTcGkga3NTcGkgPSBuZXcgTXlLZXlTdG9yZVNwaSgpOworCisgICAgICAgIHRtcEVudHJ5IGVudHJ5ID0gbmV3IHRtcEVudHJ5KCk7CisgICAgICAgIHRtcFByb3RlY3Rpb24gcFBhciA9IG5ldyB0bXBQcm90ZWN0aW9uKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtzU3BpLmVuZ2luZVN0b3JlKG51bGwpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0TnVsbCgiTm90IG51bGwgZW50cnkiLCBrc1NwaS5lbmdpbmVHZXRFbnRyeSgiYWFhIiwgbnVsbCkpOworICAgICAgICBhc3NlcnROdWxsKCJOb3QgbnVsbCBlbnRyeSIsIGtzU3BpLmVuZ2luZUdldEVudHJ5KG51bGwsIHBQYXIpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiTm90IG51bGwgZW50cnkiLCBrc1NwaS5lbmdpbmVHZXRFbnRyeSgiYWFhIiwgcFBhcikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrc1NwaS5lbmdpbmVTZXRFbnRyeSgiIiwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJLZXlTdG9yZUV4Y2VwdGlvbiBvciBOdWxsUG9pbnRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrc1NwaS5lbmdpbmVTZXRFbnRyeSgiIiwgbmV3IEtleVN0b3JlLlRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5KAorICAgICAgICAgICAgICAgICAgICBuZXcgTXlDZXJ0aWZpY2F0ZSgidHlwZSIsIG5ldyBieXRlWzBdKSksIG51bGwpOworICAgICAgICAgICAgZmFpbCgiS2V5U3RvcmVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtzU3BpLmVuZ2luZVNldEVudHJ5KCJhYWEiLCBlbnRyeSwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJLZXlTdG9yZUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5LZXlTdG9yZVNwaSgpPC9jb2RlPiBjb25zdHJ1Y3RvciBhbmQgYWJzdHJhY3QgZW5naW5lCisgICAgICogbWV0aG9kcy4gQXNzZXJ0aW9uOiBjcmVhdGVzIG5ldyBLZXlTdG9yZVNwaSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEtleVN0b3RlU3BpMDIoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiwgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBLZXlTdG9yZVNwaSBrc1NwaSA9IG5ldyBNeUtleVN0b3JlU3BpKCk7CisgICAgICAgIGFzc2VydE51bGwoImVuZ2luZUdldEtleSguLikgbXVzdCByZXR1cm4gbnVsbCIsIGtzU3BpLmVuZ2luZUdldEtleSgiIiwKKyAgICAgICAgICAgICAgICBuZXcgY2hhclswXSkpOworICAgICAgICBhc3NlcnROdWxsKCJlbmdpbmVHZXRDZXJ0aWZpY2F0ZUNoYWluKC4uKSBtdXN0IHJldHVybiBudWxsIiwga3NTcGkKKyAgICAgICAgICAgICAgICAuZW5naW5lR2V0Q2VydGlmaWNhdGVDaGFpbigiIikpOworICAgICAgICBhc3NlcnROdWxsKCJlbmdpbmVHZXRDZXJ0aWZpY2F0ZSguLikgbXVzdCByZXR1cm4gbnVsbCIsIGtzU3BpCisgICAgICAgICAgICAgICAgLmVuZ2luZUdldENlcnRpZmljYXRlKCIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZW5naW5lR2V0Q3JlYXRpb25EYXRlKC4uKSBtdXN0IHJldHVybiBEYXRlKDApIiwgbmV3IERhdGUoCisgICAgICAgICAgICAgICAgMCksIGtzU3BpLmVuZ2luZUdldENyZWF0aW9uRGF0ZSgiIikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAga3NTcGkuZW5naW5lU2V0S2V5RW50cnkoIiIsIG51bGwsIG5ldyBjaGFyWzBdLCBuZXcgQ2VydGlmaWNhdGVbMF0pOworICAgICAgICAgICAgZmFpbCgiS2V5U3RvcmVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gZnJvbSBlbmdpbmVTZXRLZXlFbnRyeSguLikiKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrc1NwaS5lbmdpbmVTZXRLZXlFbnRyeSgiIiwgbmV3IGJ5dGVbMF0sIG5ldyBDZXJ0aWZpY2F0ZVswXSk7CisgICAgICAgICAgICBmYWlsKCJLZXlTdG9yZUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biBmcm9tIGVuZ2luZVNldEtleUVudHJ5KC4uKSIpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtzU3BpLmVuZ2luZVNldENlcnRpZmljYXRlRW50cnkoIiIsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiS2V5U3RvcmVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gIgorICAgICAgICAgICAgICAgICAgICArICJmcm9tIGVuZ2luZVNldENlcnRpZmljYXRlRW50cnkoLi4pIik7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAga3NTcGkuZW5naW5lRGVsZXRlRW50cnkoIiIpOworICAgICAgICAgICAgZmFpbCgiS2V5U3RvcmVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gZnJvbSBlbmdpbmVEZWxldGVFbnRyeSguLikiKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydE51bGwoImVuZ2luZUFsaWFzZXMoKSBtdXN0IHJldHVybiBudWxsIiwga3NTcGkuZW5naW5lQWxpYXNlcygpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoImVuZ2luZUNvbnRhaW5zQWxpYXMoLi4pIG11c3QgcmV0dXJuIGZhbHNlIiwga3NTcGkKKyAgICAgICAgICAgICAgICAuZW5naW5lQ29udGFpbnNBbGlhcygiIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVuZ2luZVNpemUoKSBtdXN0IHJldHVybiAwIiwgMCwga3NTcGkuZW5naW5lU2l6ZSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtzU3BpLmVuZ2luZVN0b3JlKG51bGwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5LZXlTdG9yZVNwaSNlbmdpbmVMb2FkKEtleVN0b3JlLkxvYWRTdG9yZVBhcmFtZXRlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VuZ2luZUxvYWRMamF2YV9zZWN1cml0eV9LZXlTdG9yZV9Mb2FkU3RvcmVQYXJhbWV0ZXIoKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgZmluYWwgU3RyaW5nIG1zZyA9ICJlcnJvciI7CisKKyAgICAgICAgS2V5U3RvcmVTcGkga3NTcGkgPSBuZXcgTXlLZXlTdG9yZVNwaSgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGVuZ2luZUxvYWQoSW5wdXRTdHJlYW0gc3RyZWFtLCBjaGFyW10gcGFzc3dvcmQpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKHN0cmVhbSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChwYXNzd29yZCk7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24obXNnKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtzU3BpLmVuZ2luZUxvYWQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgZXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0U2FtZShtc2csIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3Q6IHByb3RlY3Rpb24gcGFyYW1ldGVyIGlzIG51bGwKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtzU3BpLmVuZ2luZUxvYWQobmV3IE15TG9hZFN0b3JlUGFyYW1zKG51bGwpKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3Q6IHByb3RlY3Rpb24gcGFyYW1ldGVyIGlzIG5vdCBpbnN0YW5jZW9mCisgICAgICAgIC8vIFBhc3N3b3JkUHJvdGVjdGlvbiBvciBDYWxsYmFja0hhbmRsZXJQcm90ZWN0aW9uCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrc1NwaS5lbmdpbmVMb2FkKG5ldyBNeUxvYWRTdG9yZVBhcmFtcyhuZXcgdG1wUHJvdGVjdGlvbigpKSk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9Cit9CisKKy8qKgorICogQWRkaXRpb25hbCBjbGFzcyBpbXBsZW1lbnRzIEtleVN0b3JlLkVudHJ5IGludGVyZmFjZQorICovCitjbGFzcyB0bXBFbnRyeSBpbXBsZW1lbnRzIEtleVN0b3JlLkVudHJ5IHsKK30KKworY2xhc3MgdG1wUHJvdGVjdGlvbiBpbXBsZW1lbnRzIEtleVN0b3JlLlByb3RlY3Rpb25QYXJhbWV0ZXIgeworfQorCitAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKK2NsYXNzIE15Q2VydGlmaWNhdGUgZXh0ZW5kcyBDZXJ0aWZpY2F0ZSB7CisKKyAgICAvLyBNeUNlcnRpZmljYXRlIGVuY29kaW5nCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gZW5jb2Rpbmc7CisKKyAgICBwdWJsaWMgTXlDZXJ0aWZpY2F0ZShTdHJpbmcgdHlwZSwgYnl0ZVtdIGVuY29kaW5nKSB7CisgICAgICAgIHN1cGVyKHR5cGUpOworICAgICAgICAvLyBkb24ndCBjb3B5IHRvIGFsbG93IG51bGwgcGFyYW1ldGVyIGluIHRlc3QKKyAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gZG8gY29weSB0byBmb3JjZSBOUEUgaW4gdGVzdAorICAgICAgICByZXR1cm4gZW5jb2RpbmcuY2xvbmUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2ZXJpZnkoUHVibGljS2V5IGtleSkgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBJbnZhbGlkS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmVyaWZ5KFB1YmxpY0tleSBrZXksIFN0cmluZyBzaWdQcm92aWRlcikKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEtleUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuICJbTXkgdGVzdCBDZXJ0aWZpY2F0ZSwgdHlwZTogIiArIGdldFR5cGUoKSArICJdIjsKKyAgICB9CisKKyAgICBwdWJsaWMgUHVibGljS2V5IGdldFB1YmxpY0tleSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBQdWJsaWNLZXkoKSB7CisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gIkRTQSI7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7KGJ5dGUpIDEsIChieXRlKSAyLCAoYnl0ZSkgM307CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgICAgIHJldHVybiAiVEVTVF9GT1JNQVQiOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlTdG9yZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlTdG9yZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMTU4YzgzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L0tleVN0b3JlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzY3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5QcmluY2lwYWw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uS2V5R2VuZXJhdG9yOworaW1wb3J0IGphdmF4LmNyeXB0by5TZWNyZXRLZXk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5LZXlTdG9yZVRlc3RTdXBwb3J0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0Lk15TG9hZFN0b3JlUGFyYW1zOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlNwaUVuZ1V0aWxzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5LZXlTdG9yZTwvY29kZT4gY29uc3RydWN0b3IgYW5kIG1ldGhvZHMKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBLZXlTdG9yZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgS2V5U3RvcmVQcm92aWRlckNsYXNzID0gIm9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0Lk15S2V5U3RvcmUiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGRlZmF1bHRUeXBlID0gIktleVN0b3JlIjsKKworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBLU1N1cHBvcnRlZCA9IGZhbHNlOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZGVmYXVsdFByb3ZpZGVyTmFtZSA9IG51bGw7CisKKyAgICBwdWJsaWMgc3RhdGljIFByb3ZpZGVyIGRlZmF1bHRQcm92aWRlciA9IG51bGw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgTm90U3VwcG9ydE1zZyA9ICJEZWZhdWx0IEtleVN0b3JlIHR5cGUgaXMgbm90IHN1cHBvcnRlZCI7CisKKyAgICBQcm92aWRlciBtUHJvdjsKKworICAgIHB1YmxpYyBLZXlTdG9yZVtdIGNyZWF0ZUtTKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoTm90U3VwcG9ydE1zZywgS1NTdXBwb3J0ZWQpOworICAgICAgICBLZXlTdG9yZVtdIGtwZyA9IG5ldyBLZXlTdG9yZVszXTsKKworICAgICAgICBrcGdbMF0gPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShkZWZhdWx0VHlwZSk7CisgICAgICAgIGtwZ1sxXSA9IEtleVN0b3JlLmdldEluc3RhbmNlKGRlZmF1bHRUeXBlLCBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICBrcGdbMl0gPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShkZWZhdWx0VHlwZSwgZGVmYXVsdFByb3ZpZGVyTmFtZSk7CisgICAgICAgIHJldHVybiBrcGc7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgbVByb3YgPSAobmV3IFNwaUVuZ1V0aWxzKCkpLm5ldyBNeVByb3ZpZGVyKCJNeUtTUHJvdmlkZXIiLAorICAgICAgICAgICAgICAgICJUZXN0aW5nIHByb3ZpZGVyIiwgS2V5U3RvcmVUZXN0U3VwcG9ydC5zcnZLZXlTdG9yZS5jb25jYXQoIi4iKQorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChkZWZhdWx0VHlwZSksIEtleVN0b3JlUHJvdmlkZXJDbGFzcyk7CisgICAgICAgIFNlY3VyaXR5Lmluc2VydFByb3ZpZGVyQXQobVByb3YsIDIpOworICAgICAgICBkZWZhdWx0UHJvdmlkZXIgPSBTcGlFbmdVdGlscy5pc1N1cHBvcnQoZGVmYXVsdFR5cGUsCisgICAgICAgICAgICAgICAgS2V5U3RvcmVUZXN0U3VwcG9ydC5zcnZLZXlTdG9yZSk7CisgICAgICAgIEtTU3VwcG9ydGVkID0gKGRlZmF1bHRQcm92aWRlciAhPSBudWxsKTsKKyAgICAgICAgZGVmYXVsdFByb3ZpZGVyTmFtZSA9IChLU1N1cHBvcnRlZCA/IGRlZmF1bHRQcm92aWRlci5nZXROYW1lKCkgOiBudWxsKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEBzZWUgVGVzdENhc2UjdGVhckRvd24oKQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgICAgIFNlY3VyaXR5LnJlbW92ZVByb3ZpZGVyKG1Qcm92LmdldE5hbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+bG9hZChMb2FkU3RvcmVQYXJhbWV0ZXIgcGFyYW0pPC9jb2RlPgorICAgICAqIDxjb2RlPnN0b3JlKExvYWRTdG9yZVBhcmFtZXRlciBwYXJhbSk8L2NvZGU+CisgICAgICogbWV0aG9kcworICAgICAqIEFzc2VydGlvbnM6IHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBwYXJhbSBpcyBudWxsOworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RMb2FkU3RvcmUwMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKE5vdFN1cHBvcnRNc2csIEtTU3VwcG9ydGVkKTsKKworICAgICAgICBLZXlTdG9yZVtdIGtzcyA9IGNyZWF0ZUtTKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIktleVN0b3JlIG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIGtzcyk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrc3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga3NzW2ldLmxvYWQobnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gb3IgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gZm9yIG51bGwgcGFyYW1ldGVyIik7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAga3NzW2ldLmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtzc1tpXS5zdG9yZShudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBvciBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biBmb3IgbnVsbCBwYXJhbWV0ZXIiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgS2V5U3RvcmUuTG9hZFN0b3JlUGFyYW1ldGVyIGxQYXJhbSA9IG5ldyBNeUxvYWRTdG9yZVBhcmFtcygKKyAgICAgICAgICAgICAgICBuZXcgS2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uKG5ldyBjaGFyWzBdKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga3NzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBrc3NbaV0ubG9hZChsUGFyYW0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcmVzdWx0Iiwga3NzW2ldLnNpemUoKSwgMCk7CisgICAgICAgICAgICBrc3NbaV0uc3RvcmUobFBhcmFtKTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+c2V0S2V5RW50cnkoU3RyaW5nIGFsaWFzLCBieXRlW10ga2V5LCBDZXJ0aWZpY2F0ZVtdIGNoYWluKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHN0b3JlcyBLZXlFbnRyeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0S2V5RW50cnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShOb3RTdXBwb3J0TXNnLCBLU1N1cHBvcnRlZCk7CisKKyAgICAgICAgS2V5U3RvcmVbXSBrc3MgPSBjcmVhdGVLUygpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJLZXlTdG9yZSBvYmplY3RzIHdlcmUgbm90IGNyZWF0ZWQiLCBrc3MpOworICAgICAgICBieXRlW10ga2sgPSB7IChieXRlKSAxLCAoYnl0ZSkgMiwgKGJ5dGUpIDEyNywgKGJ5dGUpIDc3IH07CisgICAgICAgIFN0cmluZyBhbGlhcyA9ICJrZXlFbnRyeSI7CisgICAgICAgIGNoYXJbXSBwd2QgPSBuZXcgY2hhclswXTsKKyAgICAgICAgYnl0ZVtdIHJlczsKKyAgICAgICAgQ2VydGlmaWNhdGUgY2VydHNbXSA9IHsKKyAgICAgICAgICAgICAgICBuZXcgS2V5U3RvcmVUZXN0U3VwcG9ydC5NQ2VydGlmaWNhdGUoYWxpYXMsIGtrKSwKKyAgICAgICAgICAgICAgICBuZXcgS2V5U3RvcmVUZXN0U3VwcG9ydC5NQ2VydGlmaWNhdGUoYWxpYXMsIGtrKSB9OworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGtzcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAga3NzW2ldLmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtzc1tpXS5zZXRLZXlFbnRyeSgicHJvYmEiLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJLZXlTdG9yZUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAga3NzW2ldLnNldEtleUVudHJ5KGFsaWFzLCBraywgY2VydHMpOworICAgICAgICAgICAgcmVzID0ga3NzW2ldLmdldEtleShhbGlhcywgcHdkKS5nZXRFbmNvZGVkKCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoa2subGVuZ3RoLCByZXMubGVuZ3RoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgcmVzLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc1tqXSwga2tbal0pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGtzc1tpXS5nZXRDZXJ0aWZpY2F0ZUNoYWluKGFsaWFzKS5sZW5ndGgsIGNlcnRzLmxlbmd0aCk7CisgICAgICAgICAgICBrc3NbaV0uc2V0S2V5RW50cnkoYWxpYXMsIGtrLCBudWxsKTsKKyAgICAgICAgICAgIHJlcyA9IGtzc1tpXS5nZXRLZXkoYWxpYXMsIHB3ZCkuZ2V0RW5jb2RlZCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGtrLmxlbmd0aCwgcmVzLmxlbmd0aCk7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHJlcy5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhyZXNbal0sIGtrW2pdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydE51bGwoa3NzW2ldLmdldENlcnRpZmljYXRlQ2hhaW4oYWxpYXMpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldERlZmF1bHRUeXBlKCk8L2NvZGU+IG1ldGhvZCBBc3NlcnRpb246IHJldHVybnMKKyAgICAgKiBkZWZhdWx0IHNlY3VyaXR5IGtleSBzdG9yZSB0eXBlIG9yICJqa3MiIHN0cmluZworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlTdG9yZTAxKCkgeworICAgICAgICBTdHJpbmcgcHJvcE5hbWUgPSAia2V5c3RvcmUudHlwZSI7CisgICAgICAgIFN0cmluZyBkZWZLU1R5cGUgPSBTZWN1cml0eS5nZXRQcm9wZXJ0eShwcm9wTmFtZSk7CisgICAgICAgIFN0cmluZyBkVHlwZSA9IEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCk7CisgICAgICAgIFN0cmluZyByZXNUeXBlID0gZGVmS1NUeXBlOworICAgICAgICBpZiAocmVzVHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXNUeXBlID0gZGVmYXVsdFR5cGU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiRGVmYXVsdCB0eXBlIGhhdmUgbm90IGJlIG51bGwiLCBkVHlwZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRlZmF1bHQgdHlwZSIsIGRUeXBlLCByZXNUeXBlKTsKKworICAgICAgICBpZiAoZGVmS1NUeXBlID09IG51bGwpIHsKKyAgICAgICAgICAgIFNlY3VyaXR5LnNldFByb3BlcnR5KHByb3BOYW1lLCBkZWZhdWx0VHlwZSk7CisgICAgICAgICAgICBkVHlwZSA9IEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCk7CisgICAgICAgICAgICByZXNUeXBlID0gU2VjdXJpdHkuZ2V0UHJvcGVydHkocHJvcE5hbWUpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiSW5jb3JyZWN0IGRlZmF1bHQgdHlwZSIsIHJlc1R5cGUpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiRGVmYXVsdCB0eXBlIGhhdmUgbm90IGJlIG51bGwiLCBkVHlwZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBkZWZhdWx0IHR5cGUiLCBkVHlwZSwgcmVzVHlwZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgdHlwZSk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiB0eXBlIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24gd2hlbiB0eXBlIGlzIG5vdCBhdmFpbGFibGUKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlTdG9yZTAyKCkgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nW10gaW52YWxpZFZhbHVlcyA9ICBTcGlFbmdVdGlscy5pbnZhbGlkVmFsdWVzOworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5U3RvcmUuZ2V0SW5zdGFuY2UobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHR5cGUgaXMgbnVsbCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEtleVN0b3JlLmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIktleVN0b3JlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duICh0eXBlOiAiLmNvbmNhdCgKKyAgICAgICAgICAgICAgICAgICAgICAgIGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiICkiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGVzdCBqYXZhLnNlY3VyaXR5LktleVN0b3JlLlBhc3N3b3JkUHJvdGVjdGlvbi5nZXRQYXNzd29yZCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEtleVN0b3JlUFBHZXRQYXNzd29yZCgpIHsKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS0xNTM5CisgICAgICAgIC8vIG5vIGV4Y2VwdGlvbiBleHBlY3RlZAorICAgICAgICBhc3NlcnROdWxsKG5ldyBLZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb24obnVsbCkuZ2V0UGFzc3dvcmQoKSk7CisgICAgICAgIGNoYXJbXSBwYXNzd29yZCA9IG5ldyBjaGFyW10geydhJywgJ2InLCAnYyd9OworICAgICAgICBLZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb24gcHAgPSBuZXcgS2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uKHBhc3N3b3JkKTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShwcC5nZXRQYXNzd29yZCgpLCBwYXNzd29yZCk7CisgICAgICAgIGFzc2VydFNhbWUocHAuZ2V0UGFzc3dvcmQoKSwgcHAuZ2V0UGFzc3dvcmQoKSk7CisKKyAgICB9CisKKworICAgIC8qCisgICAgICogamF2YS5zZWN1cml0eS5LZXlTdG9yZVNwaS5lbmdpbmVFbnRyeUluc3RhbmNlT2YoU3RyaW5nLCBDbGFzczw/IGV4dGVuZHMgRW50cnk+KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFbmdpbmVFbnRyeUluc3RhbmNlT2YoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy9SZWdyZXNzaW9uIGZvciBIQVJNT05ZLTYxNQorCisgICAgICAgIC8vIGNyZWF0ZSBhIEtleVN0b3JlCisgICAgICAgIEtleVN0b3JlIGtleVN0b3JlID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSk7CisgICAgICAgIGtleVN0b3JlLmxvYWQobnVsbCwgInB3ZCIudG9DaGFyQXJyYXkoKSk7CisKKyAgICAgICAgLy8gZ2VuZXJhdGUgYSBrZXkKKyAgICAgICAgS2V5R2VuZXJhdG9yIGtleUdlbiA9IEtleUdlbmVyYXRvci5nZXRJbnN0YW5jZSgiREVTIik7CisgICAgICAgIGtleUdlbi5pbml0KDU2KTsKKyAgICAgICAgU2VjcmV0S2V5IHNlY3JldEtleSA9IGtleUdlbi5nZW5lcmF0ZUtleSgpOworCisgICAgICAgIC8vIHB1dCB0aGUga2V5IGludG8ga2V5c3RvcmUKKyAgICAgICAgU3RyaW5nIGFsaWFzID0gImFsaWFzIjsKKyAgICAgICAga2V5U3RvcmUuc2V0S2V5RW50cnkoYWxpYXMsIHNlY3JldEtleSwgInB3ZCIudG9DaGFyQXJyYXkoKSwgbnVsbCk7CisKKyAgICAgICAgLy8gY2hlY2sgaWYgaXQgaXMgYSBzZWNyZXQga2V5CisgICAgICAgIGFzc2VydFRydWUoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKGFsaWFzLAorICAgICAgICAgICAgICAgIEtleVN0b3JlLlNlY3JldEtleUVudHJ5LmNsYXNzKSk7CisKKyAgICAgICAgLy8gY2hlY2sgaWYgaXQgaXMgTk9UIGEgcHJpdmF0ZSBrZXkKKyAgICAgICAgYXNzZXJ0RmFsc2Uoa2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKGFsaWFzLAorICAgICAgICAgICAgICAgIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeS5jbGFzcykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuS2V5U3RvcmUuVHJ1c3RlZENlcnRpZmljYXRlRW50cnkudG9TdHJpbmcoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlTdG9yZVRDVG9TdHJpbmcoKSB7CisgICAgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMTU0MgorICAgICAgICAgICAvLyBubyBleGNlcHRpb24gZXhwZWN0ZWQKKyAgICAgICAgY2xhc3MgVGVzdFg1MDlDZXJ0aWZpY2F0ZSBleHRlbmRzIFg1MDlDZXJ0aWZpY2F0ZSB7CisgICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrVmFsaWRpdHkoKSB0aHJvd3MgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uLENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24ge30KKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrVmFsaWRpdHkoRGF0ZSBwKSB0aHJvd3MgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uIHt9CisgICAgICAgICAgICBwdWJsaWMgaW50IGdldFZlcnNpb24oKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0U2VyaWFsTnVtYmVyKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0SXNzdWVyRE4oKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIFByaW5jaXBhbCBnZXRTdWJqZWN0RE4oKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIERhdGUgZ2V0Tm90QmVmb3JlKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyBEYXRlIGdldE5vdEFmdGVyKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0VEJTQ2VydGlmaWNhdGUoKSB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRTaWduYXR1cmUoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRTaWdBbGdOYW1lKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2lnQWxnT0lEKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0U2lnQWxnUGFyYW1zKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyBib29sZWFuW10gZ2V0SXNzdWVyVW5pcXVlSUQoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIGJvb2xlYW5bXSBnZXRTdWJqZWN0VW5pcXVlSUQoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIGJvb2xlYW5bXSBnZXRLZXlVc2FnZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwdWJsaWMgaW50IGdldEJhc2ljQ29uc3RyYWludHMoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgdGhyb3dzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZlcmlmeShQdWJsaWNLZXkgcCkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgICAgICBTaWduYXR1cmVFeGNlcHRpb24KKyAgICAgICAgICAgIHt9CisgICAgICAgICAgICBwdWJsaWMgdm9pZCB2ZXJpZnkoUHVibGljS2V5IHAwLCBTdHJpbmcgcDEpCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgICAgICBJbnZhbGlkS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgU2lnbmF0dXJlRXhjZXB0aW9uCisgICAgICAgICAgICB7fQorICAgICAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwdWJsaWMgUHVibGljS2V5IGdldFB1YmxpY0tleSgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNVbnN1cHBvcnRlZENyaXRpY2FsRXh0ZW5zaW9uKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwdWJsaWMgU2V0IGdldENyaXRpY2FsRXh0ZW5zaW9uT0lEcygpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwdWJsaWMgU2V0IGdldE5vbkNyaXRpY2FsRXh0ZW5zaW9uT0lEcygpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEV4dGVuc2lvblZhbHVlKFN0cmluZyBwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwobmV3IEtleVN0b3JlLlRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5KG5ldyBUZXN0WDUwOUNlcnRpZmljYXRlKCkpLnRvU3RyaW5nKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9LZXlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY1MzU1YTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvS2V5VGVzdC5qYXZhCkBAIC0wLDAgKzEsNjEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5LZXk8L2NvZGU+IGNsYXNzIGZpZWxkCisgKgorICovCitwdWJsaWMgY2xhc3MgS2V5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnNlcmlhbFZlcnNpb25VSUQ8L2NvZGU+IGZpZWxkCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEZpZWxkKCkgeworICAgICAgICBjaGVja0tleSBtayA9IG5ldyBjaGVja0tleSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBzZXJpYWxWZXJzaW9uVUlEIiwgbWsuZ2V0U2VyVmVyVUlEKCksIC8vS2V5LnNlcmlhbFZlcnNpb25VSUQsCisgICAgICAgICAgICAgICAgNjYwMzM4NDE1Mjc0OTU2NzY1NEwpOworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBjaGVja0tleSBpbXBsZW1lbnRzIEtleSB7CisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICAgICAgcmV0dXJuICJLZXkiOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgcmV0dXJuICJGb3JtYXQiOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVswXTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgbG9uZyBnZXRTZXJWZXJVSUQoKSB7CisgICAgICAgICAgICByZXR1cm4gc2VyaWFsVmVyc2lvblVJRDsKKyAgICAgICAgfQorICAgIH0KKworfQorCisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9NZXNzYWdlRGlnZXN0MVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9NZXNzYWdlRGlnZXN0MVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOGU4ODQ2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L01lc3NhZ2VEaWdlc3QxVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzI2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkRpZ2VzdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0U3BpOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5NeU1lc3NhZ2VEaWdlc3QxOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5NZXNzYWdlRGlnZXN0PC9jb2RlPiBjb25zdHJ1Y3RvciBhbmQgbWV0aG9kcworICovCitwdWJsaWMgY2xhc3MgTWVzc2FnZURpZ2VzdDFUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0I3Jlc2V0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Jlc2V0KCkgeworICAgICAgICBNeU1lc3NhZ2VEaWdlc3QxIG1kID0gbmV3IE15TWVzc2FnZURpZ2VzdDEoIkFCQyIpOworICAgICAgICBtZC5yZXNldCgpOworICAgICAgICBhc3NlcnRUcnVlKG1kLnJ1bkVuZ2luZVJlc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3QjdXBkYXRlKGJ5dGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF91cGRhdGVMQigpIHsKKyAgICAgICAgTXlNZXNzYWdlRGlnZXN0MSBtZCA9IG5ldyBNeU1lc3NhZ2VEaWdlc3QxKCJBQkMiKTsKKyAgICAgICAgbWQudXBkYXRlKChieXRlKSAxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtZC5ydW5FbmdpbmVVcGRhdGUxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3QjdXBkYXRlKGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF91cGRhdGVMQiRMSUxJKCkgeworICAgICAgICBNeU1lc3NhZ2VEaWdlc3QxIG1kID0gbmV3IE15TWVzc2FnZURpZ2VzdDEoIkFCQyIpOworICAgICAgICBmaW5hbCBieXRlW10gYnl0ZXMgPSB7IDEsIDIsIDMsIDQsIDUgfTsKKyAgICAgICAgbWQudXBkYXRlKGJ5dGVzLCAxLCAyKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtZC5ydW5FbmdpbmVVcGRhdGUyKTsKKworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTExMjAKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGJ1ZiA9PSBudWxsCisgICAgICAgICAgICBtZC51cGRhdGUobnVsbCwgMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gb2Zmc2V0ICsgbGVuID4gYnVmLmxlbmd0aAorICAgICAgICAgICAgbWQudXBkYXRlKGJ5dGVzLCAwLCBieXRlcy5sZW5ndGggKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBvZmZzZXQgKyBsZW4gPiBJbnRlZ2VyLk1BWF9WQUxVRQorICAgICAgICAgICAgbWQudXBkYXRlKGJ5dGVzLCBJbnRlZ2VyLk1BWF9WQUxVRSwgMSk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICAvLyBvZmZzZXQ8MCBhbmQgbGVuPDAgYXJlIHBhc3NlZCB0byBwcm92aWRlcgorICAgICAgICBmaW5hbCBpbnQgb2Zmc2V0ID0gLTE7CisgICAgICAgIGZpbmFsIGludCBsZW4gPSAtMTsKKyAgICAgICAgbWQgPSBuZXcgTXlNZXNzYWdlRGlnZXN0MSgiQUJDIikgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZVtdIGFyZzAsIGludCBhcmcxLCBpbnQgYXJnMikgeworICAgICAgICAgICAgICAgIGFzc2VydFNhbWUoImJ1ZiIsIGJ5dGVzLCBhcmcwKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIm9mZnNldCIsIG9mZnNldCwgYXJnMSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJsZW4iLCBsZW4sIGFyZzIpOworICAgICAgICAgICAgICAgIHJ1bkVuZ2luZVVwZGF0ZTIgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBtZC51cGRhdGUoYnl0ZXMsIG9mZnNldCwgbGVuKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtZC5ydW5FbmdpbmVVcGRhdGUyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3QjdXBkYXRlKGJ5dGVbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VwZGF0ZUxCJCgpIHsKKyAgICAgICAgTXlNZXNzYWdlRGlnZXN0MSBtZCA9IG5ldyBNeU1lc3NhZ2VEaWdlc3QxKCJBQkMiKTsKKyAgICAgICAgYnl0ZVtdIGIgPSB7IDEsIDIsIDMsIDQsIDUgfTsKKyAgICAgICAgbWQudXBkYXRlKGIpOworICAgICAgICBhc3NlcnRUcnVlKG1kLnJ1bkVuZ2luZVVwZGF0ZTIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdCN1cGRhdGUoQnl0ZUJ1ZmZlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VwZGF0ZUxqYXZhX25pb19CeXRlQnVmZmVyKCkgeworICAgICAgICBNeU1lc3NhZ2VEaWdlc3QxIG1kID0gbmV3IE15TWVzc2FnZURpZ2VzdDEoIkFCQyIpOworICAgICAgICBieXRlW10gYiA9IHsgMSwgMiwgMywgNCwgNSB9OworICAgICAgICBCeXRlQnVmZmVyIGJ5dGVCdWZmZXIgPSBCeXRlQnVmZmVyLndyYXAoYik7CisKKyAgICAgICAgaW50IGxpbWl0ID0gYnl0ZUJ1ZmZlci5saW1pdCgpOworICAgICAgICBtZC51cGRhdGUoYnl0ZUJ1ZmZlcik7CisgICAgICAgIGFzc2VydFRydWUobWQucnVuRW5naW5lVXBkYXRlMik7CisgICAgICAgIGFzc2VydEVxdWFscyhieXRlQnVmZmVyLmxpbWl0KCksIGJ5dGVCdWZmZXIucG9zaXRpb24oKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhsaW1pdCwgYnl0ZUJ1ZmZlci5saW1pdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3QjZGlnZXN0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RpZ2VzdCgpIHsKKyAgICAgICAgTXlNZXNzYWdlRGlnZXN0MSBtZCA9IG5ldyBNeU1lc3NhZ2VEaWdlc3QxKCJBQkMiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgcmVzdWx0IiwgMCwgbWQuZGlnZXN0KCkubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtZC5ydW5FbmdpbmVEaWdlc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdCNkaWdlc3QoYnl0ZVtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZGlnZXN0TEIkKCkgeworICAgICAgICBNeU1lc3NhZ2VEaWdlc3QxIG1kID0gbmV3IE15TWVzc2FnZURpZ2VzdDEoIkFCQyIpOworICAgICAgICBieXRlW10gYiA9IHsgMSwgMiwgMywgNCwgNSB9OworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCByZXN1bHQiLCAwLCBtZC5kaWdlc3QoYikubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtZC5ydW5FbmdpbmVEaWdlc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdCNkaWdlc3QoYnl0ZVtdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RpZ2VzdExCJExJTEkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTXlNZXNzYWdlRGlnZXN0MSBtZCA9IG5ldyBNeU1lc3NhZ2VEaWdlc3QxKCJBQkMiKTsKKyAgICAgICAgYnl0ZVtdIGIgPSB7IDEsIDIsIDMsIDQsIDUgfTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgcmVzdWx0IiwgMCwgbWQuZGlnZXN0KGIsIDIsIDMpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZGlnZXN0IGZhaWxlZCIsIG1kLnJ1bkVuZ2luZURpZ2VzdCk7CisKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSGFybW9ueS0xMTQ4CisgICAgICAgIG1kID0gbmV3IE15TWVzc2FnZURpZ2VzdDEoKTsKKyAgICAgICAgZmluYWwgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbXSB7IDIsIDQsIDEgfTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGJ1ZiA9PSBudWxsCisgICAgICAgICAgICBtZC5kaWdlc3QobnVsbCwgMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gb2Zmc2V0ICsgbGVuID4gYnVmLmxlbmd0aAorICAgICAgICAgICAgbWQuZGlnZXN0KGJ5dGVzLCAwLCBieXRlcy5sZW5ndGggKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBvZmZzZXQgKyBsZW4gPiBJbnRlZ2VyLk1BWF9WQUxVRQorICAgICAgICAgICAgbWQuZGlnZXN0KGJ5dGVzLCBJbnRlZ2VyLk1BWF9WQUxVRSwgMSk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICAvLyBvZmZzZXQ8MCBhbmQgbGVuPDAgYXJlIHBhc3NlZCB0byBwcm92aWRlcgorICAgICAgICBmaW5hbCBpbnQgb2Zmc2V0ID0gLTE7CisgICAgICAgIGZpbmFsIGludCBsZW4gPSAtMTsKKyAgICAgICAgZmluYWwgaW50IHN0YXR1cyA9IDMzOworICAgICAgICBtZCA9IG5ldyBNeU1lc3NhZ2VEaWdlc3QxKCJBQkMiKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgZW5naW5lRGlnZXN0KGJ5dGVbXSBhcmcwLCBpbnQgYXJnMSwgaW50IGFyZzIpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRTYW1lKCJidWYiLCBieXRlcywgYXJnMCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJvZmZzZXQiLCBvZmZzZXQsIGFyZzEpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygibGVuIiwgbGVuLCBhcmcyKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3RhdHVzOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBhc3NlcnRFcXVhbHMoInJldHVybmVkIHN0YXR1cyIsIHN0YXR1cywgbWQuZGlnZXN0KGJ5dGVzLCBvZmZzZXQsIGxlbikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IGRpZ2VzdCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoIlRlc3REaWdlc3QiLCBuZXcgVGVzdFByb3ZpZGVyKCkpOworICAgICAgICAgICAgZGlnZXN0LmRpZ2VzdChuZXcgYnl0ZVs1XSwgMCwgNSk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBEaWdlc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoRGlnZXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3QjaXNFcXVhbChieXRlW10sYnl0ZVtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNFcXVhbExCJExCJCgpIHsKKyAgICAgICAgYnl0ZVtdIGIxID0geyAxLCAyLCAzLCA0IH07CisgICAgICAgIGJ5dGVbXSBiMiA9IHsgMSwgMiwgMywgNCwgNSB9OworICAgICAgICBieXRlW10gYjMgPSB7IDEsIDMsIDMsIDQgfTsKKyAgICAgICAgYnl0ZVtdIGI0ID0geyAxLCAyLCAzLCA0IH07CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShNZXNzYWdlRGlnZXN0LmlzRXF1YWwoYjEsIGI0KSk7CisgICAgICAgIGFzc2VydEZhbHNlKE1lc3NhZ2VEaWdlc3QuaXNFcXVhbChiMSwgYjIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoTWVzc2FnZURpZ2VzdC5pc0VxdWFsKGIxLCBiMykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdCNnZXRBbGdvcml0aG0oKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICBNeU1lc3NhZ2VEaWdlc3QxIG1kID0gbmV3IE15TWVzc2FnZURpZ2VzdDEoIkFCQyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFCQyIsIG1kLmdldEFsZ29yaXRobSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3QjZ2V0UHJvdmlkZXIoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UHJvdmlkZXIoKSB7CisgICAgICAgIE15TWVzc2FnZURpZ2VzdDEgbWQgPSBuZXcgTXlNZXNzYWdlRGlnZXN0MSgiQUJDIik7CisgICAgICAgIGFzc2VydE51bGwobWQuZ2V0UHJvdmlkZXIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0I2dldERpZ2VzdExlbmd0aCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREaWdlc3RMZW5ndGgoKSB7CisgICAgICAgIE15TWVzc2FnZURpZ2VzdDEgbWQgPSBuZXcgTXlNZXNzYWdlRGlnZXN0MSgiQUJDIik7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBtZC5nZXREaWdlc3RMZW5ndGgoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgU0hBIE1lc3NhZ2VEaWdlc3QgcHJvdmlkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U0hBUHJvdmlkZXIoKSB7CisgICAgICAgIE1lc3NhZ2VEaWdlc3QgbWQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWQgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJTSEEiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbXSB7IDEsIDEsIDEsIDEsIDEgfTsKKworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTExMjAKKyAgICAgICAgLy8gdGVzdGluZyBjb21iaW5hdGlvbiB3aXRoIHByb3ZpZGVyCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBvZmZzZXQgPCAwCisgICAgICAgICAgICBtZC51cGRhdGUoYnl0ZXMsIC0xLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1kLnVwZGF0ZShieXRlcywgMSwgLTEpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vUmVncmVzc2lvbiBmb3IgSGFybW9ueS0xMTQ4CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtZCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoIlNIQSIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gb2Zmc2V0IDwgMAorICAgICAgICAgICAgbWQuZGlnZXN0KGJ5dGVzLCAwLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBEaWdlc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoRGlnZXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gbGVuIDwgMAorICAgICAgICAgICAgbWQuZGlnZXN0KGJ5dGVzLCAtMSwgMCk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBEaWdlc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoRGlnZXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1kID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZSgiVW5rbm93bkRpZ2VzdCIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICB9CisKKyAgICBjbGFzcyBUZXN0UHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlciB7CisgICAgICAgIHB1YmxpYyBUZXN0UHJvdmlkZXIoKSB7CisgICAgICAgICAgICBzdXBlcigiVGVzdFByb3ZpZGVyIiwgMS4wLCAiaW5mbyIpOworICAgICAgICAgICAgcHV0KCJNZXNzYWdlRGlnZXN0LlRlc3REaWdlc3QiLCBUZXN0TWVzc2FnZURpZ2VzdFNwaS5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBUZXN0TWVzc2FnZURpZ2VzdFNwaSBleHRlbmRzIE1lc3NhZ2VEaWdlc3RTcGkgeworCisgICAgICAgIHB1YmxpYyBUZXN0TWVzc2FnZURpZ2VzdFNwaSgpIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuZ2luZURpZ2VzdCgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVtdezMsNCw1LDYsNyw4LDksMyw0NSw2LDcsfTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVSZXNldCgpIHsKKworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShieXRlIGlucHV0KSB7CisKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZVtdIGlucHV0LCBpbnQgb2Zmc2V0LCBpbnQgbGVuKSB7CisKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgaW50IGVuZ2luZUdldERpZ2VzdExlbmd0aCgpIHsKKyAgICAgICAgICAgIHJldHVybiA0MjsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9NZXNzYWdlRGlnZXN0MlRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9NZXNzYWdlRGlnZXN0MlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNTk0NzgwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L01lc3NhZ2VEaWdlc3QyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDg4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkRpZ2VzdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcC5FbnRyeTsKKworcHVibGljIGNsYXNzIE1lc3NhZ2VEaWdlc3QyVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUVTU0FHRURJR0VTVF9JRCA9ICJNZXNzYWdlRGlnZXN0LiI7CisKKyAgICBwcml2YXRlIE1hcDxQcm92aWRlciwgTGlzdDxTdHJpbmc+PiBkaWdlc3RBbGdzID0gbmV3IEhhc2hNYXA8UHJvdmlkZXIsIExpc3Q8U3RyaW5nPj4oKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBBUjEgPSB7IDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDAgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBBUjIgPSB7IDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDAgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBNRVNTQUdFID0gImFiYyI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gTUVTU0FHRV9ESUdFU1QgPSB7IC04NywgLTEwMywgNjIsIDU0LCA3MSwgNiwKKyAgICAgICAgICAgIC0xMjcsIDEwNiwgLTcwLCA2MiwgMzcsIDExMywgMTIwLCA4MCwgLTYyLCAxMDgsIC0xMDAsIC00OCwgLTQwLAorICAgICAgICAgICAgLTk5LCB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIE1FU1NBR0VfRElHRVNUXzYzX0FzID0geyAzLCAtMTYsIC05NywgOTEsIDIxLAorICAgICAgICAgICAgLTExOCwgMTIyLCAtMTE2LCAtMzgsIC0zOSwgMzIsIC02NywgLTM2LCA0MSwgLTcyLCAyOCwgMjQsIC05MSwgODEsCisgICAgICAgICAgICAtMTEsIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gTUVTU0FHRV9ESUdFU1RfNjRfQXMgPSB7IDAsIC0xMDQsIC03MCwgLTEyNiwKKyAgICAgICAgICAgIDc1LCA5MiwgMjIsIDY2LCAxMjMsIC00MSwgLTk1LCAxOCwgNDIsIDkwLCA2OCwgNDIsIDM3LCAtMjAsIDEwMCwKKyAgICAgICAgICAgIDc3LCB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIE1FU1NBR0VfRElHRVNUXzY1X0FzID0geyAxNywgMTAxLCA4MywgMzgsIC01NywKKyAgICAgICAgICAgIDgsIC00MSwgMywgMjUsIC02NiwgMzgsIDE2LCAtMjQsIC05MSwgMTI1LCAtMTAyLCA5MSwgLTEwNywgLTk5LCA1OSwgfTsKKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdCNNZXNzYWdlRGlnZXN0KGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jb25zdHJ1Y3RvcigpIHsKKyAgICAgICAgZm9yIChMaXN0PFN0cmluZz4gYWxnb3JpdGhtcyA6IGRpZ2VzdEFsZ3MudmFsdWVzKCkpIHsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIGFsZ29yaXRobSA6IGFsZ29yaXRobXMpIHsKKyAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0U3R1YiBtZCA9IG5ldyBNZXNzYWdlRGlnZXN0U3R1YihhbGdvcml0aG0pOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhhbGdvcml0aG0sIG1kLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbWQuZ2V0RGlnZXN0TGVuZ3RoKCkpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwobWQuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3QjY2xvbmUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvbmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChFbnRyeTxQcm92aWRlciwgTGlzdDxTdHJpbmc+PiBlIDogZGlnZXN0QWxncy5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICBmb3IgKFN0cmluZyBhbGdvcml0aG0gOiBlLmdldFZhbHVlKCkpIHsKKyAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IGQxID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShhbGdvcml0aG0sIGUuZ2V0S2V5KCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBmb3IgKGJ5dGUgYiA9IDA7IGIgPCA4NDsgYisrKSB7CisgICAgICAgICAgICAgICAgICAgIGQxLnVwZGF0ZShiKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IGQyID0gKE1lc3NhZ2VEaWdlc3QpIGQxLmNsb25lKCk7CisgICAgICAgICAgICAgICAgZDEudXBkYXRlKChieXRlKSAxKTsKKyAgICAgICAgICAgICAgICBkMi51cGRhdGUoKGJ5dGUpIDEpOworCisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiY2xvbmVkIGhhc2ggZGlmZmVycyBmcm9tIG9yaWdpbmFsIGZvciBhbGdvcml0aG0gIiArIGFsZ29yaXRobSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QuaXNFcXVhbChkMS5kaWdlc3QoKSwgZDIuZGlnZXN0KCkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBTSEFfREFUQV8yID0geyA3MCwgLTU0LCAxMjQsIDEyMCwgLTI5LCA1NywgNTYsCisgICAgICAgICAgICAxMTksIC0xMDgsIC01NCwgLTk3LCAtNzYsIC05NywgLTUwLCAtNjMsIC03MywgMiwgODUsIC01MywgLTc5LCB9OworCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RTZXJpYWxpemF0aW9uU0hBX0RBVEFfMihNZXNzYWdlRGlnZXN0IHNoYSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNoYS5yZXNldCgpOworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBEYXRhT3V0cHV0U3RyZWFtIG91dHB1dCA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKG91dCk7CisKKyAgICAgICAgLy8gTWFkZSB1cCBkYXRhCisgICAgICAgIG91dHB1dC53cml0ZVVURigidGVzdHMuYXBpLmphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdFRlc3QkSW5pdGlhbGl6ZXJGaWVsZHNUZXN0MyIpOworICAgICAgICBvdXRwdXQud3JpdGVJbnQoMCk7IC8vIGNsYXNzIG1vZGlmaWVycworICAgICAgICBvdXRwdXQud3JpdGVVVEYoImphdmEuaW8uU2VyaWFsaXphYmxlIik7IC8vIGludGVyZmFjZXMKKworICAgICAgICAvLyBGaWVsZHMKKyAgICAgICAgb3V0cHV0LndyaXRlVVRGKCJzdWJfdG9CZU5vdFNlcmlhbGl6ZWQiKTsgLy8gbmFtZQorICAgICAgICBvdXRwdXQud3JpdGVJbnQoOSk7IC8vIG1vZGlmaWVycworICAgICAgICBvdXRwdXQud3JpdGVVVEYoIkxqYXZhL2xhbmcvU3RyaW5nOyIpOyAvLyBzaWduYXR1cmUKKworICAgICAgICBvdXRwdXQud3JpdGVVVEYoInN1Yl90b0JlTm90U2VyaWFsaXplZDIiKTsgLy8gbmFtZQorICAgICAgICBvdXRwdXQud3JpdGVJbnQoOSk7IC8vIG1vZGlmaWVycworICAgICAgICBvdXRwdXQud3JpdGVVVEYoIkxqYXZhL2xhbmcvU3RyaW5nOyIpOyAvLyBzaWduYXR1cmUKKworICAgICAgICBvdXRwdXQud3JpdGVVVEYoInN1Yl90b0JlU2VyaWFsaXplZCIpOyAvLyBuYW1lCisgICAgICAgIG91dHB1dC53cml0ZUludCgxKTsgLy8gbW9kaWZpZXJzCisgICAgICAgIG91dHB1dC53cml0ZVVURigiTGphdmEvbGFuZy9TdHJpbmc7Iik7IC8vIHNpZ25hdHVyZQorCisgICAgICAgIG91dHB1dC53cml0ZVVURigic3ViX3RvQmVTZXJpYWxpemVkMyIpOyAvLyBuYW1lCisgICAgICAgIG91dHB1dC53cml0ZUludCgxKTsgLy8gbW9kaWZpZXJzCisgICAgICAgIG91dHB1dC53cml0ZVVURigiTGphdmEvbGFuZy9TdHJpbmc7Iik7IC8vIHNpZ25hdHVyZQorCisgICAgICAgIG91dHB1dC53cml0ZVVURigic3ViX3RvQmVTZXJpYWxpemVkNCIpOyAvLyBuYW1lCisgICAgICAgIG91dHB1dC53cml0ZUludCgxKTsgLy8gbW9kaWZpZXJzCisgICAgICAgIG91dHB1dC53cml0ZVVURigiTGphdmEvbGFuZy9TdHJpbmc7Iik7IC8vIHNpZ25hdHVyZQorCisgICAgICAgIG91dHB1dC53cml0ZVVURigic3ViX3RvQmVTZXJpYWxpemVkNSIpOyAvLyBuYW1lCisgICAgICAgIG91dHB1dC53cml0ZUludCgxKTsgLy8gbW9kaWZpZXJzCisgICAgICAgIG91dHB1dC53cml0ZVVURigiTGphdmEvbGFuZy9TdHJpbmc7Iik7IC8vIHNpZ25hdHVyZQorCisgICAgICAgIC8vIGNsaW5pdAorICAgICAgICBvdXRwdXQud3JpdGVVVEYoIjxjbGluaXQ+Iik7IC8vIG5hbWUKKyAgICAgICAgb3V0cHV0LndyaXRlSW50KDgpOyAvLyBtb2RpZmllcnMKKyAgICAgICAgb3V0cHV0LndyaXRlVVRGKCIoKVYiKTsgLy8gc2lnbmF0dXJlCisKKyAgICAgICAgLy8gY29uc3RydWN0b3JzCisgICAgICAgIG91dHB1dC53cml0ZVVURigiPGluaXQ+Iik7IC8vIG5hbWUKKyAgICAgICAgb3V0cHV0LndyaXRlSW50KDApOyAvLyBtb2RpZmllcnMKKyAgICAgICAgb3V0cHV0LndyaXRlVVRGKCIoKVYiKTsgLy8gc2lnbmF0dXJlCisKKyAgICAgICAgLy8gbWV0aG9kcworICAgICAgICBvdXRwdXQud3JpdGVVVEYoImVxdWFscyIpOyAvLyBuYW1lCisgICAgICAgIG91dHB1dC53cml0ZUludCgxKTsgLy8gbW9kaWZpZXJzCisgICAgICAgIG91dHB1dC53cml0ZVVURigiKExqYXZhLmxhbmcuT2JqZWN0OylaIik7IC8vIHNpZ25hdHVyZQorCisgICAgICAgIG91dHB1dC5mbHVzaCgpOworCisgICAgICAgIGJ5dGVbXSBkYXRhID0gb3V0LnRvQnl0ZUFycmF5KCk7CisgICAgICAgIGJ5dGVbXSBoYXNoID0gc2hhLmRpZ2VzdChkYXRhKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU0hBX0RBVEFfMiBOT1Qgb2siLCBBcnJheXMuZXF1YWxzKGhhc2gsIFNIQV9EQVRBXzIpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gU0hBX0RBVEFfMSA9IHsgOTAsIDM2LCAxMTEsIDEwNiwgLTMyLCAzOCwgNCwKKyAgICAgICAgICAgIDEyNiwgMjEsIC01MSwgMTA3LCA0NSwgLTY0LCAtNjgsIC0xMDksIDExMiwgLTMxLCAtNDYsIDM0LCAxMTUsIH07CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdFNlcmlhbGl6YXRpb25TSEFfREFUQV8xKE1lc3NhZ2VEaWdlc3Qgc2hhKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc2hhLnJlc2V0KCk7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIERhdGFPdXRwdXRTdHJlYW0gb3V0cHV0ID0gbmV3IERhdGFPdXRwdXRTdHJlYW0ob3V0KTsKKworICAgICAgICAvLyBNYWRlIHVwIGRhdGEKKyAgICAgICAgb3V0cHV0LndyaXRlVVRGKCJ0ZXN0cy5hcGkuamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0VGVzdCRPcHRpb25hbERhdGFOb3RSZWFkIik7CisgICAgICAgIC8vIG5hbWUKKyAgICAgICAgb3V0cHV0LndyaXRlSW50KDApOyAvLyBjbGFzcyBtb2RpZmllcnMKKyAgICAgICAgb3V0cHV0LndyaXRlVVRGKCJqYXZhLmlvLlNlcmlhbGl6YWJsZSIpOyAvLyBpbnRlcmZhY2VzCisKKyAgICAgICAgLy8gRmllbGRzCisgICAgICAgIG91dHB1dC53cml0ZVVURigiY2xhc3MkMCIpOyAvLyBuYW1lCisgICAgICAgIG91dHB1dC53cml0ZUludCg4KTsgLy8gbW9kaWZpZXJzCisgICAgICAgIG91dHB1dC53cml0ZVVURigiTGphdmEvbGFuZy9DbGFzczsiKTsgLy8gc2lnbmF0dXJlCisKKyAgICAgICAgb3V0cHV0LndyaXRlVVRGKCJmaWVsZDEiKTsgLy8gbmFtZQorICAgICAgICBvdXRwdXQud3JpdGVJbnQoMik7IC8vIG1vZGlmaWVycworICAgICAgICBvdXRwdXQud3JpdGVVVEYoIkkiKTsgLy8gc2lnbmF0dXJlCisKKyAgICAgICAgb3V0cHV0LndyaXRlVVRGKCJmaWVsZDIiKTsgLy8gbmFtZQorICAgICAgICBvdXRwdXQud3JpdGVJbnQoMik7IC8vIG1vZGlmaWVycworICAgICAgICBvdXRwdXQud3JpdGVVVEYoIkkiKTsgLy8gc2lnbmF0dXJlCisKKyAgICAgICAgLy8gY2xpbml0CisgICAgICAgIG91dHB1dC53cml0ZVVURigiPGNsaW5pdD4iKTsgLy8gbmFtZQorICAgICAgICBvdXRwdXQud3JpdGVJbnQoOCk7IC8vIG1vZGlmaWVycworICAgICAgICBvdXRwdXQud3JpdGVVVEYoIigpViIpOyAvLyBzaWduYXR1cmUKKworICAgICAgICAvLyBjb25zdHJ1Y3RvcnMKKyAgICAgICAgb3V0cHV0LndyaXRlVVRGKCI8aW5pdD4iKTsgLy8gbmFtZQorICAgICAgICBvdXRwdXQud3JpdGVJbnQoMSk7IC8vIG1vZGlmaWVycworICAgICAgICBvdXRwdXQud3JpdGVVVEYoIigpViIpOyAvLyBzaWduYXR1cmUKKworICAgICAgICBvdXRwdXQuZmx1c2goKTsKKyAgICAgICAgYnl0ZVtdIGRhdGEgPSBvdXQudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgYnl0ZVtdIGhhc2ggPSBzaGEuZGlnZXN0KGRhdGEpOworICAgICAgICBhc3NlcnRUcnVlKCJTSEFfREFUQV8xIE5PVCBvayIsIEFycmF5cy5lcXVhbHMoaGFzaCwgU0hBX0RBVEFfMSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdCNkaWdlc3QoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZGlnZXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1lc3NhZ2VEaWdlc3Qgc2hhID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZSgiU0hBIik7CisgICAgICAgIGFzc2VydE5vdE51bGwoc2hhKTsKKyAgICAgICAgc2hhLnVwZGF0ZShNRVNTQUdFLmdldEJ5dGVzKCkpOworICAgICAgICBieXRlW10gZGlnZXN0ID0gc2hhLmRpZ2VzdCgpOworICAgICAgICBhc3NlcnRUcnVlKCJidWcgaW4gU0hBIiwgTWVzc2FnZURpZ2VzdC5pc0VxdWFsKGRpZ2VzdCwgTUVTU0FHRV9ESUdFU1QpKTsKKworICAgICAgICBzaGEucmVzZXQoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2MzsgaSsrKSB7CisgICAgICAgICAgICAvLyBqdXN0IHVuZGVyIGJ1ZmZlciBjYXBhY2l0eQorICAgICAgICAgICAgc2hhLnVwZGF0ZSgoYnl0ZSkgJ2EnKTsKKyAgICAgICAgfQorICAgICAgICBkaWdlc3QgPSBzaGEuZGlnZXN0KCk7CisgICAgICAgIGFzc2VydFRydWUoImJ1ZyBpbiBTSEEiLCBNZXNzYWdlRGlnZXN0LmlzRXF1YWwoZGlnZXN0LCBNRVNTQUdFX0RJR0VTVF82M19BcykpOworCisgICAgICAgIHNoYS5yZXNldCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDY0OyBpKyspIHsKKyAgICAgICAgICAgIC8vIGV4YWN0IFNIQSBidWZmZXIgY2FwYWNpdHkKKyAgICAgICAgICAgIHNoYS51cGRhdGUoKGJ5dGUpICdhJyk7CisgICAgICAgIH0KKyAgICAgICAgZGlnZXN0ID0gc2hhLmRpZ2VzdCgpOworICAgICAgICBhc3NlcnRUcnVlKCJidWcgaW4gU0hBIiwgTWVzc2FnZURpZ2VzdC5pc0VxdWFsKGRpZ2VzdCwgTUVTU0FHRV9ESUdFU1RfNjRfQXMpKTsKKworICAgICAgICBzaGEucmVzZXQoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2NTsgaSsrKSB7CisgICAgICAgICAgICAvLyBqdXN0IGFib3ZlIFNIQSBidWZmZXIgY2FwYWNpdHkKKyAgICAgICAgICAgIHNoYS51cGRhdGUoKGJ5dGUpICdhJyk7CisgICAgICAgIH0KKyAgICAgICAgZGlnZXN0ID0gc2hhLmRpZ2VzdCgpOworICAgICAgICBhc3NlcnRUcnVlKCJidWcgaW4gU0hBIiwgTWVzc2FnZURpZ2VzdC5pc0VxdWFsKGRpZ2VzdCwgTUVTU0FHRV9ESUdFU1RfNjVfQXMpKTsKKworICAgICAgICB0ZXN0U2VyaWFsaXphdGlvblNIQV9EQVRBXzEoc2hhKTsKKyAgICAgICAgdGVzdFNlcmlhbGl6YXRpb25TSEFfREFUQV8yKHNoYSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0I2RpZ2VzdChieXRlW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9kaWdlc3QkQigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKEVudHJ5PFByb3ZpZGVyLCBMaXN0PFN0cmluZz4+IGUgOiBkaWdlc3RBbGdzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIGFsZ29yaXRobSA6IGUuZ2V0VmFsdWUoKSkgeworICAgICAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QgZGlnZXN0ID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShhbGdvcml0aG0sIGUuZ2V0S2V5KCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGRpZ2VzdCk7CisgICAgICAgICAgICAgICAgZGlnZXN0LmRpZ2VzdChBUjEpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0I2RpZ2VzdChieXRlW10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZGlnZXN0JEJJSSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKEVudHJ5PFByb3ZpZGVyLCBMaXN0PFN0cmluZz4+IGUgOiBkaWdlc3RBbGdzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIGFsZ29yaXRobSA6IGUuZ2V0VmFsdWUoKSkgeworICAgICAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QgZGlnZXN0ID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShhbGdvcml0aG0sIGUuZ2V0S2V5KCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGRpZ2VzdCk7CisgICAgICAgICAgICAgICAgaW50IGxlbiA9IGRpZ2VzdC5nZXREaWdlc3RMZW5ndGgoKTsKKyAgICAgICAgICAgICAgICBieXRlW10gZGlnZXN0Qnl0ZXMgPSBuZXcgYnl0ZVtsZW5dOworICAgICAgICAgICAgICAgIGRpZ2VzdC5kaWdlc3QoZGlnZXN0Qnl0ZXMsIDAsIGRpZ2VzdEJ5dGVzLmxlbmd0aCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoIlNIQSIpLmRpZ2VzdChuZXcgYnl0ZVtdIHt9LCBJbnRlZ2VyLk1BWF9WQUxVRSwgNzU1KTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdCN1cGRhdGUoYnl0ZVtdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VwZGF0ZSRCSUkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoIlNIQSIpLnVwZGF0ZShuZXcgYnl0ZVtdIHt9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIuTUFYX1ZBTFVFLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0I2dldEFsZ29yaXRobSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBbGdvcml0aG0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChFbnRyeTxQcm92aWRlciwgTGlzdDxTdHJpbmc+PiBlIDogZGlnZXN0QWxncy5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICBmb3IgKFN0cmluZyBhbGdvcml0aG0gOiBlLmdldFZhbHVlKCkpIHsKKyAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShhbGdvcml0aG0sIGUuZ2V0S2V5KCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYWxnb3JpdGhtLCBtZC5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3QjZ2V0RGlnZXN0TGVuZ3RoKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERpZ2VzdExlbmd0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKEVudHJ5PFByb3ZpZGVyLCBMaXN0PFN0cmluZz4+IGUgOiBkaWdlc3RBbGdzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIGFsZ29yaXRobSA6IGUuZ2V0VmFsdWUoKSkgeworICAgICAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QgbWQgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKGFsZ29yaXRobSwgZS5nZXRLZXkoKS5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImxlbmd0aCBub3Qgb2siLCBtZC5nZXREaWdlc3RMZW5ndGgoKSA+IDApOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0I2dldEluc3RhbmNlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoRW50cnk8UHJvdmlkZXIsIExpc3Q8U3RyaW5nPj4gZSA6IGRpZ2VzdEFsZ3MuZW50cnlTZXQoKSkgeworICAgICAgICAgICAgZm9yIChTdHJpbmcgYWxnb3JpdGhtIDogZS5nZXRWYWx1ZSgpKSB7CisgICAgICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBtZCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG1kKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJVbmtub3duRGlnZXN0Iik7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3QjZ2V0SW5zdGFuY2UoamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKEVudHJ5PFByb3ZpZGVyLCBMaXN0PFN0cmluZz4+IGUgOiBkaWdlc3RBbGdzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIGFsZ29yaXRobSA6IGUuZ2V0VmFsdWUoKSkgeworICAgICAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QgbWQgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKGFsZ29yaXRobSwgZS5nZXRLZXkoKS5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwobWQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChMaXN0PFN0cmluZz4gYWxnb3JpdGhtcyA6IGRpZ2VzdEFsZ3MudmFsdWVzKCkpIHsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIGFsZ29yaXRobSA6IGFsZ29yaXRobXMpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKGFsZ29yaXRobSwgIlVua25vd25Qcm92aWRlciIpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChQcm92aWRlciBwcm92aWRlciA6IGRpZ2VzdEFsZ3Mua2V5U2V0KCkpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZSgiVW5rbm93bkRpZ2VzdCIsIHByb3ZpZGVyLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIik7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoUHJvdmlkZXIgcHJvdmlkZXIgOiBkaWdlc3RBbGdzLmtleVNldCgpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UobnVsbCwgcHJvdmlkZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJBbnlEaWdlc3QiLCAoU3RyaW5nKW51bGwpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0I2dldEluc3RhbmNlKGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgICAgIGphdmEuc2VjdXJpdHkuUHJvdmlkZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfc2VjdXJpdHlfUHJvdmlkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChFbnRyeTxQcm92aWRlciwgTGlzdDxTdHJpbmc+PiBlIDogZGlnZXN0QWxncy5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICBmb3IgKFN0cmluZyBhbGdvcml0aG0gOiBlLmdldFZhbHVlKCkpIHsKKyAgICAgICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShhbGdvcml0aG0sIGUuZ2V0S2V5KCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG1kKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKG51bGwsIG5ldyBUZXN0UHJvdmlkZXIoKSk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoIlVua25vd25EaWdlc3QiLCBuZXcgVGVzdFByb3ZpZGVyKCkpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoIkFueURpZ2VzdCIsIChQcm92aWRlciludWxsKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdCNnZXRQcm92aWRlcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQcm92aWRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKEVudHJ5PFByb3ZpZGVyLCBMaXN0PFN0cmluZz4+IGUgOiBkaWdlc3RBbGdzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIGFsZ29yaXRobSA6IGUuZ2V0VmFsdWUoKSkgeworICAgICAgICAgICAgICAgIE1lc3NhZ2VEaWdlc3QgbWQgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKGFsZ29yaXRobSwgZS5nZXRLZXkoKS5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoInByb3ZpZGVyIGlzIG51bGwiLCBtZC5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdCNpc0VxdWFsKGJ5dGVbXSwgYnl0ZVtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNFcXVhbCRCJEIoKSB7CisgICAgICAgIGFzc2VydFRydWUoImlzRXF1YWwgaXMgbm90IGNvcnJlY3QiLCBNZXNzYWdlRGlnZXN0LmlzRXF1YWwoQVIxLCBBUjIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3QjdG9TdHJpbmcoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHN0ciA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoIlNIQSIpLnRvU3RyaW5nKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoInRvU3RyaW5nIGlzIG51bGwiLCBzdHIpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICBQcm92aWRlcltdIHByb3ZpZGVycyA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygiTWVzc2FnZURpZ2VzdC5TSEEiKTsKKyAgICAgICAgZm9yIChQcm92aWRlciBwcm92aWRlciA6IHByb3ZpZGVycykgeworICAgICAgICAgICAgZGlnZXN0QWxncy5wdXQocHJvdmlkZXIsIGdldERpZ2VzdEFsZ29yaXRobXMocHJvdmlkZXIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogUmV0dXJucyB0aGUgZGlnZXN0IGFsZ29yaXRobXMgdGhhdCB0aGUgZ2l2ZW4gcHJvdmlkZXIgc3VwcG9ydHMuCisgICAgICovCisgICAgcHJpdmF0ZSBMaXN0PFN0cmluZz4gZ2V0RGlnZXN0QWxnb3JpdGhtcyhQcm92aWRlciBwcm92aWRlcikgeworICAgICAgICBpZiAocHJvdmlkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbCgiTm8gZGlnZXN0IGFsZ29yaXRobXMgd2VyZSBmb3VuZCIpOworICAgICAgICB9CisKKyAgICAgICAgTGlzdDxTdHJpbmc+IGFsZ3MgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgZm9yIChPYmplY3Qga2V5IDogcHJvdmlkZXIua2V5U2V0KCkpIHsKKyAgICAgICAgICAgIFN0cmluZyBhbGdvcml0aG0gPSAoU3RyaW5nKSBrZXk7CisgICAgICAgICAgICBpZiAoYWxnb3JpdGhtLnN0YXJ0c1dpdGgoTUVTU0FHRURJR0VTVF9JRCkgJiYgIWFsZ29yaXRobS5jb250YWlucygiICIpKSB7CisgICAgICAgICAgICAgICAgYWxncy5hZGQoYWxnb3JpdGhtLnN1YnN0cmluZyhNRVNTQUdFRElHRVNUX0lELmxlbmd0aCgpKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoYWxncy5zaXplKCkgPT0gMCkgeworICAgICAgICAgICAgZmFpbCgiTm8gZGlnZXN0IGFsZ29yaXRobXMgd2VyZSBmb3VuZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBhbGdzOworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgTWVzc2FnZURpZ2VzdFN0dWIgZXh0ZW5kcyBNZXNzYWdlRGlnZXN0IHsKKyAgICAgICAgcHVibGljIE1lc3NhZ2VEaWdlc3RTdHViKFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgICAgIHN1cGVyKGFsZ29yaXRobSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGVuZ2luZURpZ2VzdCgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgZW5naW5lUmVzZXQoKSB7CisKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGVuZ2luZVVwZGF0ZShieXRlIGlucHV0KSB7CisKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGVuZ2luZVVwZGF0ZShieXRlW10gaW5wdXQsIGludCBvZmZzZXQsIGludCBsZW4pIHsKKworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBUZXN0UHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlciB7CisKKyAgICAgICAgcHJvdGVjdGVkIFRlc3RQcm92aWRlcigpIHsKKyAgICAgICAgICAgIHN1cGVyKCJUZXN0UHJvdmlkZXIiLCAxLjAsICJJTkZPIik7CisKKyAgICAgICAgfQorCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L01lc3NhZ2VEaWdlc3RTcGlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdFNwaVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YmU1NTYzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L01lc3NhZ2VEaWdlc3RTcGlUZXN0LmphdmEKQEAgLTAsMCArMSwyMTkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorICogQGF1dGhvciBCb3JpcyBWLiBLdXpuZXRzb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkRpZ2VzdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0U3BpOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5NZXNzYWdlRGlnZXN0U3BpPC9jb2RlPiBjb25zdHJ1Y3RvciBhbmQgbWV0aG9kcworICovCitwdWJsaWMgY2xhc3MgTWVzc2FnZURpZ2VzdFNwaVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAqIGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdFNwaSNNZXNzYWdlRGlnZXN0U3BpKCkKKyAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJjYXN0IikKKyAgIHB1YmxpYyB2b2lkIHRlc3RfY29uc3RydWN0b3IoKSB7CisgICAgICAgIE15TWVzc2FnZURpZ2VzdCBtZHM7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtZHMgPSBuZXcgTXlNZXNzYWdlRGlnZXN0KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKG1kcyBpbnN0YW5jZW9mIE1lc3NhZ2VEaWdlc3RTcGkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtZHMgPSBuZXcgTXlNZXNzYWdlRGlnZXN0KCk7CisgICAgICAgICAgICBieXRlW10gYmEgPSB7MCwgMSwgMiwgMywgNCwgNX07CisKKyAgICAgICAgICAgIG1kcy5lbmdpbmVEaWdlc3QoKTsKKyAgICAgICAgICAgIG1kcy5lbmdpbmVSZXNldCgpOworICAgICAgICAgICAgbWRzLmVuZ2luZVVwZGF0ZShiYVswXSk7CisgICAgICAgICAgICBtZHMuZW5naW5lVXBkYXRlKGJhLCAwLCBiYS5sZW5ndGgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gZm9yIGFic3RyYWN0IG1ldGhvZHMiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdFNwaSNlbmdpbmVEaWdlc3QoYnl0ZVtdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VuZ2luZURpZ2VzdExCJExJTEkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBmaW5hbCBpbnQgRElHRVNUX0xFTkdUSCA9IDI7CisKKyAgICAgICAgTXlNZXNzYWdlRGlnZXN0IG1kID0gbmV3IE15TWVzc2FnZURpZ2VzdCgpIHsKKworICAgICAgICAgICAgcHVibGljIGludCBlbmdpbmVHZXREaWdlc3RMZW5ndGgoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIERJR0VTVF9MRU5HVEg7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZW5naW5lRGlnZXN0KCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVtESUdFU1RfTEVOR1RIXTsgLy8gcmV0dXJuIG5vbi1udWxsIHZhbHVlCisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVs1XTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIHRlc3Q6IG51bGwgb3V0cHV0IGJ1ZmZlcgorICAgICAgICAgICAgbWQuZW5naW5lRGlnZXN0KG51bGwsIDEsIERJR0VTVF9MRU5HVEgpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvL3Rlc3Q6IGxlbiBwYXJhbSA8IGRpZ2VzdCBsZW5ndGgKKyAgICAgICAgICAgIG1kLmVuZ2luZURpZ2VzdChiLCAxLCBESUdFU1RfTEVOR1RIIC0gMSk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBEaWdlc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoRGlnZXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvL3Rlc3Q6IG9mZnNldCBwYXJhbSA+IGRpZ2VzdCBsZW5ndGgKKyAgICAgICAgICAgIG1kLmVuZ2luZURpZ2VzdChiLCBiLmxlbmd0aCArIDEsIGIubGVuZ3RoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIERpZ2VzdEV4Y2VwdGlvbiAtIDEiKTsKKyAgICAgICAgfSBjYXRjaCAoRGlnZXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvL3Rlc3Q6IG5lZ2F0aXZlIHBhcmFtCisgICAgICAgICAgICBtZC5lbmdpbmVEaWdlc3QoYiwgLTEsIGIubGVuZ3RoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIERpZ2VzdEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb24gUkkKKyAgICAgICAgfSBjYXRjaCAoRGlnZXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoImluY29ycmVjdCByZXN1bHQiLCBESUdFU1RfTEVOR1RILCBtZAorICAgICAgICAgICAgICAgIC5lbmdpbmVEaWdlc3QoYiwgMSwgMykpOworCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMzA0NQorICAgICAgICBtZCA9IG5ldyBNeU1lc3NhZ2VEaWdlc3QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1kLmVuZ2luZURpZ2VzdChiLCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0U3BpI2VuZ2luZUdldERpZ2VzdExlbmd0aCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9lbmdpbmVHZXREaWdlc3RMZW5ndGgoKSB7CisgICAgICAgIE15TWVzc2FnZURpZ2VzdCBtZCA9IG5ldyBNeU1lc3NhZ2VEaWdlc3QoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG1kLmVuZ2luZUdldERpZ2VzdExlbmd0aCgpKTsKKworICAgICAgICBNZXNzYWdlRGlnZXN0IG1kNURpZ2VzdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtZDVEaWdlc3QgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJNRDUiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgRXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDE2LCBtZDVEaWdlc3QuZ2V0RGlnZXN0TGVuZ3RoKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdFNwaSNlbmdpbmVVcGRhdGUoQnl0ZUJ1ZmZlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VuZ2luZVVwZGF0ZUxqYXZhX25pb19CeXRlQnVmZmVyKCkgeworICAgICAgICBNeU1lc3NhZ2VEaWdlc3QgbWQgPSBuZXcgTXlNZXNzYWdlRGlnZXN0KCk7CisgICAgICAgIGJ5dGVbXSBiID0geyAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5IH07CisKKyAgICAgICAgQnl0ZUJ1ZmZlciBidWYgPSBCeXRlQnVmZmVyLndyYXAoYiwgMCwgYi5sZW5ndGgpOworICAgICAgICBidWYuZ2V0KGIpOworICAgICAgICBpbnQgbGltaXQgPSBidWYubGltaXQoKTsKKyAgICAgICAgbWQuZW5naW5lVXBkYXRlKGJ1Zik7CisgICAgICAgIGFzc2VydEVxdWFscyhsaW1pdCwgYnVmLmxpbWl0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobGltaXQsIGJ1Zi5wb3NpdGlvbigpKTsKKworICAgICAgICBidWYgPSBCeXRlQnVmZmVyLndyYXAoYiwgMCwgYi5sZW5ndGgpOworICAgICAgICBidWYuZ2V0KCk7CisgICAgICAgIGJ1Zi5nZXQoKTsKKyAgICAgICAgYnVmLmdldCgpOworICAgICAgICBtZC5lbmdpbmVVcGRhdGUoYnVmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxpbWl0LCBidWYubGltaXQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhsaW1pdCwgYnVmLnBvc2l0aW9uKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdFNwaSNjbG9uZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7CisgICAgICAgIE15TWVzc2FnZURpZ2VzdCBtZCA9IG5ldyBNeU1lc3NhZ2VEaWdlc3QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1kLmNsb25lKCk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBNeU1lc3NhZ2VEaWdlc3RDbG9uZWFibGUgbWRjID0gbmV3IE15TWVzc2FnZURpZ2VzdENsb25lYWJsZSgpOworICAgICAgICBhc3NlcnROb3RTYW1lKG1kYywgbWRjLmNsb25lKCkpOworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgTXlNZXNzYWdlRGlnZXN0IGV4dGVuZHMgTWVzc2FnZURpZ2VzdFNwaSB7CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGVuZ2luZVJlc2V0KCkgeworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBieXRlW10gZW5naW5lRGlnZXN0KCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGUgYXJnMCkgeworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGVuZ2luZVVwZGF0ZShieXRlW10gYXJnMCwgaW50IGFyZzEsIGludCBhcmcyKSB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGludCBlbmdpbmVEaWdlc3QoYnl0ZVtdIGJ1ZiwgaW50IG9mZnNldCwgaW50IGxlbikKKyAgICAgICAgICAgICAgICB0aHJvd3MgRGlnZXN0RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5lbmdpbmVEaWdlc3QoYnVmLCBvZmZzZXQsIGxlbik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGludCBlbmdpbmVHZXREaWdlc3RMZW5ndGgoKSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZW5naW5lR2V0RGlnZXN0TGVuZ3RoKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKEJ5dGVCdWZmZXIgaW5wdXQpIHsKKyAgICAgICAgICAgIHN1cGVyLmVuZ2luZVVwZGF0ZShpbnB1dCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIE15TWVzc2FnZURpZ2VzdENsb25lYWJsZSBleHRlbmRzIE15TWVzc2FnZURpZ2VzdCBpbXBsZW1lbnRzCisgICAgICAgICAgICBDbG9uZWFibGUgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4OTdkZDQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTc4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+Tm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kCisgKiBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgVGhyb3dhYmxlIHRDYXVzZSA9IG5ldyBUaHJvd2FibGUoIlRocm93YWJsZSBmb3IgZXhjZXB0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uMDEoKSB7CisgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB0RSA9IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Tm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4KKyAgICAgKiBQYXJhbWV0ZXIgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uMDIoKSB7CisgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gPGNvZGU+bXNnPC9jb2RlPiBpcworICAgICAqIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uMDMoKSB7CisgICAgICAgIFN0cmluZyBtc2cgPSBudWxsOworICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gdEUgPSBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKG1zZyk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbihUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4KKyAgICAgKiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjA0KCkgeworICAgICAgICBUaHJvd2FibGUgY2F1c2UgPSBudWxsOworICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gdEUgPSBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKGNhdXNlKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Tm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIDxjb2RlPmNhdXNlPC9jb2RlPgorICAgICAqIGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjA1KCkgeworICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gdEUgPSBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKHRDYXVzZSk7CisgICAgICAgIGlmICh0RS5nZXRNZXNzYWdlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgc2hvdWxkIGNvbnRhaW4gIi5jb25jYXQodG9TKSwgKGdldE0KKyAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwgdEUKKyAgICAgICAgICAgICAgICAuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3ROb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24wNigpIHsKKyAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHRFID0gbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbihudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uMDcoKSB7CisgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24obXNnc1tpXSwgbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QgbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uMDgoKSB7CisgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB0RSA9IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24obnVsbCwgdENhdXNlKTsKKyAgICAgICAgaWYgKHRFLmdldE1lc3NhZ2UoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IHNob3VsZCAiLmNvbmNhdCh0b1MpLCAoZ2V0TQorICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgIC5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdCBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uMDkoKSB7CisgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24obXNnc1tpXSwgdENhdXNlKTsKKyAgICAgICAgICAgIFN0cmluZyBnZXRNID0gdEUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgaWYgKG1zZ3NbaV0ubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIG11c3QgY29udGFpbiAiLmNvbmNhdChtc2dzW2ldKSwgZ2V0TQorICAgICAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YobXNnc1tpXSkgIT0gLTEpOworICAgICAgICAgICAgICAgIGlmICghZ2V0TS5lcXVhbHMobXNnc1tpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIHNob3VsZCBjb250YWluICIuY29uY2F0KHRvUyksIGdldE0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLAorICAgICAgICAgICAgICAgICAgICB0RS5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L05vU3VjaFByb3ZpZGVyRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L05vU3VjaFByb3ZpZGVyRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk4MzI0ZjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvTm9TdWNoUHJvdmlkZXJFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw3OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+Tm9TdWNoUHJvdmlkZXJFeGNlcHRpb248L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQKKyAqIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgc3RhdGljIFN0cmluZ1tdIG1zZ3MgPSB7CisgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UiIH07CisKKyAgICBzdGF0aWMgVGhyb3dhYmxlIHRDYXVzZSA9IG5ldyBUaHJvd2FibGUoIlRocm93YWJsZSBmb3IgZXhjZXB0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbigpPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246CisgICAgICogY29uc3RydWN0cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uMDEoKSB7CisgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHRFID0gbmV3IE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHdpdGggZGV0YWlsIG1lc3NhZ2UgbXNnLgorICAgICAqIFBhcmFtZXRlciA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3ROb1N1Y2hQcm92aWRlckV4Y2VwdGlvbjAyKCkgeworICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbihtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHdoZW4gPGNvZGU+bXNnPC9jb2RlPiBpcworICAgICAqIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9TdWNoUHJvdmlkZXJFeGNlcHRpb24wMygpIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9IG51bGw7CisgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHRFID0gbmV3IE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uKG1zZyk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9Qcml2YXRlS2V5VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1ByaXZhdGVLZXlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTk1MTkzNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9Qcml2YXRlS2V5VGVzdC5qYXZhCkBAIC0wLDAgKzEsNjIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+UHJpdmF0ZUtleTwvY29kZT4gY2xhc3MgZmllbGQKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBQcml2YXRlS2V5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnNlcmlhbFZlcnNpb25VSUQ8L2NvZGU+IGZpZWxkCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEZpZWxkKCkgeworICAgICAgICBjaGVja1ByaXZhdGVLZXkgY1ByS2V5ID0gbmV3IGNoZWNrUHJpdmF0ZUtleSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBzZXJpYWxWZXJzaW9uVUlEIiwgY1ByS2V5LmdldFNlclZlclVJRCgpLCAvL1ByaXZhdGVLZXkuc2VyaWFsVmVyc2lvblVJRCwKKyAgICAgICAgICAgICAgICA2MDM0MDQ0MzE0NTg5NTEzNDMwTCk7CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIGNoZWNrUHJpdmF0ZUtleSBpbXBsZW1lbnRzIFByaXZhdGVLZXkgeworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgIHJldHVybiAiUHVibGljS2V5IjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgcmV0dXJuICJGb3JtYXQiOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBieXRlWzBdOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGxvbmcgZ2V0U2VyVmVyVUlEKCkgeworICAgICAgICAgICAgcmV0dXJuIHNlcmlhbFZlcnNpb25VSUQ7CisgICAgICAgIH0KKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9Qcml2aWxlZ2VkQWN0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1ByaXZpbGVnZWRBY3Rpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTM0ZDM0YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9Qcml2aWxlZ2VkQWN0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOworCitwdWJsaWMgY2xhc3MgUHJpdmlsZWdlZEFjdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgTXlQcml2aWxlZ2VkQWN0aW9uIGltcGxlbWVudHMgUHJpdmlsZWdlZEFjdGlvbjxTdHJpbmc+IHsKKworICAgICAgICBwcml2YXRlIGJvb2xlYW4gY2FsbGVkPWZhbHNlOworICAgICAgICBwdWJsaWMgU3RyaW5nIHJ1bigpIHsKKyAgICAgICAgICAgIGNhbGxlZCA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gIm9rIjsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgTXlQcml2aWxlZ2VkQWN0aW9uMiBpbXBsZW1lbnRzIFByaXZpbGVnZWRBY3Rpb248U3RyaW5nPiB7CisKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGNhbGxlZD1mYWxzZTsKKyAgICAgICAgcHVibGljIFN0cmluZyBydW4oKSB7CisgICAgICAgICAgICBjYWxsZWQgPSB0cnVlOworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oImZhaWwiKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJ1bigpIHsKKyAgICAgICAgTXlQcml2aWxlZ2VkQWN0aW9uIGFjdGlvbiA9IG5ldyBNeVByaXZpbGVnZWRBY3Rpb24oKTsKKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKGFjdGlvbik7CisgICAgICAgIGFzc2VydEVxdWFscygicmV0dXJuIHZhbHVlIG5vdCBjb3JyZWN0IiwgIm9rIiwgcmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgicnVuIG1ldGhvZCB3YXMgbm90IGNhbGxlZCIsIGFjdGlvbi5jYWxsZWQpOworCisgICAgICAgIE15UHJpdmlsZWdlZEFjdGlvbjIgYWN0aW9uMiA9IG5ldyBNeVByaXZpbGVnZWRBY3Rpb24yKCk7CisKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzdWx0ID0gQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQoYWN0aW9uMik7CisgICAgICAgICAgICBmYWlsKCJleGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZCBleGNlcHRpb24KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9Qcm92aWRlcjJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvUHJvdmlkZXIyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdmOGM3MjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvUHJvdmlkZXIyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTcwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CisKK3B1YmxpYyBjbGFzcyBQcm92aWRlcjJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIGNsYXNzIFRlc3RQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyIHsKKyAgICAgICAgVGVzdFByb3ZpZGVyKFN0cmluZyBuYW1lLCBkb3VibGUgdmVyc2lvbiwgU3RyaW5nIGluZm8pIHsKKyAgICAgICAgICAgIHN1cGVyKG5hbWUsIHZlcnNpb24sIGluZm8pOworICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgTXlFbnRyeSBpbXBsZW1lbnRzIGphdmEudXRpbC5NYXAuRW50cnkgeworICAgICAgICAgcHVibGljIE9iamVjdCBnZXRLZXkoKSB7CisgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICB9CisKKyAgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0VmFsdWUoKSB7CisgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICB9CisKKyAgICAgICAgIHB1YmxpYyBPYmplY3Qgc2V0VmFsdWUoT2JqZWN0IHZhbHVlKSB7CisgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICB9CisgICAgfQorCisgICAgVGVzdFByb3ZpZGVyIHByb3ZUZXN0ID0gbmV3IFRlc3RQcm92aWRlcigicHJvdlRlc3QiLCAxLjIsCisgICAgICAgICAgICAiY29udGFpbnMgbm90aGluZ3MsIHB1cmVseSBmb3IgdGVzdGluZyB0aGUgY2xhc3MiKTsKKworCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5Qcm92aWRlciNlbnRyeVNldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9lbnRyeVNldCgpIHsKKyAgICAgICAgLy8gdGVzdCBtZXRob2Qgb2YgamF2YS5zZWN1cml0eS5wcm92aWRlci5lbnRyeVNldAorICAgICAgICBwcm92VGVzdC5wdXQoInRlc3QucHJvcCIsICJ0aGlzIGlzIGEgdGVzdCBwcm9wZXJ0eSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy9tYWtlIGl0IGNvbXBpbGFibGUgb24gMS41CisgICAgICAgICAgICBwcm92VGVzdC5lbnRyeVNldCgpLmFkZChuZXcgTXlFbnRyeSgpKTsKKyAgICAgICAgICAgIGZhaWwoIndhcyBhYmxlIHRvIG1vZGlmeSB0aGUgZW50cnlTZXQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuUHJvdmlkZXIjZ2V0SW5mbygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbmZvKCkgeworICAgICAgICAvLyB0ZXN0IG1ldGhvZCBvZiBqYXZhLnNlY3VyaXR5LnByb3ZpZGVyLmdldEluZm8KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0aGUgaW5mb3JtYXRpb24gb2YgdGhlIHByb3ZpZGVyIGlzIG5vdCBzdG9yZWQgcHJvcGVybHkiLAorICAgICAgICAgICAgICAgICJjb250YWlucyBub3RoaW5ncywgcHVyZWx5IGZvciB0ZXN0aW5nIHRoZSBjbGFzcyIsIHByb3ZUZXN0CisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0SW5mbygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyI2dldE5hbWUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TmFtZSgpIHsKKyAgICAgICAgLy8gdGVzdCBtZXRob2Qgb2YgamF2YS5zZWN1cml0eS5wcm92aWRlci5nZXROYW1lCisgICAgICAgIGFzc2VydEVxdWFscygidGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIGlzIG5vdCBzdG9yZWQgcHJvcGVybHkiLAorICAgICAgICAgICAgICAgICJwcm92VGVzdCIsIHByb3ZUZXN0LmdldE5hbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5Qcm92aWRlciNnZXRWZXJzaW9uKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFZlcnNpb24oKSB7CisgICAgICAgIC8vIHRlc3QgbWV0aG9kIG9mIGphdmEuc2VjdXJpdHkucHJvdmlkZXIuZ2V0VmVyc2lvbgorICAgICAgICBhc3NlcnRFcXVhbHMoInRoZSB2ZXJzaW9uIG9mIHRoZSBwcm92aWRlciBpcyBub3Qgc3RvcmVkIHByb3Blcmx5IiwKKyAgICAgICAgICAgICAgICAxLjIsIHByb3ZUZXN0LmdldFZlcnNpb24oKSwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5Qcm92aWRlciNrZXlTZXQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfa2V5U2V0KCkgeworICAgICAgICAvLyB0ZXN0IG1ldGhvZCBvZiBqYXZhLnNlY3VyaXR5LnByb3ZpZGVyLmtleVNldAorICAgICAgICBwcm92VGVzdC5wdXQoInRlc3QucHJvcCIsICJ0aGlzIGlzIGEgdGVzdCBwcm9wZXJ0eSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJvdlRlc3Qua2V5U2V0KCkuYWRkKCJhbm90aGVyIHByb3BlcnR5IGtleSIpOworICAgICAgICAgICAgZmFpbCgid2FzIGFibGUgdG8gbW9kaWZ5IHRoZSBrZXlTZXQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuUHJvdmlkZXIjdmFsdWVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3ZhbHVlcygpIHsKKyAgICAgICAgLy8gdGVzdCBtZXRob2Qgb2YgamF2YS5zZWN1cml0eS5wcm92aWRlci52YWx1ZXMKKyAgICAgICAgcHJvdlRlc3QucHV0KCJ0ZXN0LnByb3AiLCAidGhpcyBpcyBhIHRlc3QgcHJvcGVydHkiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByb3ZUZXN0LnZhbHVlcygpLmFkZCgiYW5vdGhlciBwcm9wZXJ0eSB2YWx1ZSIpOworICAgICAgICAgICAgZmFpbCgid2FzIGFibGUgdG8gbW9kaWZ5IHRoZSB2YWx1ZXMgY29sbGVjdGlvbiIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyI3RvU3RyaW5nKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nKCkgeworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTM3MzQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwcm92VGVzdCB2ZXJzaW9uIDEuMiIsIHByb3ZUZXN0LnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8vIFJlZ3Jlc3Npb24gVGVzdCBmb3IgUHJvdmlkZXIuU2VydmljZS5nZXRBbGlhcygpLCB3aGljaCBpcyBhbiBwYWNrYWdlCisgICAgLy8gcHJpdmF0ZSBtZXRob2QgYnV0IHdpbGwgbGVhZCB0byBOUEUgdGhyb3duIGF0CisgICAgLy8gU2VjdXJlLlNlY3VyaXR5RG9yci5nZXRBbGlhc2VzCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBbGlhcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNb2NrUHJvdmlkZXIgbW9ja1Byb3ZpZGVyID0gbmV3IE1vY2tQcm92aWRlcigiTU9DS05BTUUiLCAxLjAsCisgICAgICAgICAgICAgICAgIk1PQ0tJTkZPIik7CisgICAgICAgIFByb3ZpZGVyLlNlcnZpY2Ugc2VydmljZSA9IG5ldyBQcm92aWRlci5TZXJ2aWNlKG1vY2tQcm92aWRlciwKKyAgICAgICAgICAgICAgICAiTU9DS1RZUEUiLCAiTU9DS0FMR09SSVRITSIsICJURVNUQ0xBU1NOQU1FIiwgbnVsbCwgbnVsbCk7CisgICAgICAgIG1vY2tQcm92aWRlci5wdXRTZXJ2aWNlKHNlcnZpY2UpOworICAgICAgICBTZWN1cml0eS5hZGRQcm92aWRlcihtb2NrUHJvdmlkZXIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBtZXNzYWdlRGlnZXN0ID0gTWVzc2FnZURpZ2VzdAorICAgICAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2UoIk5PVEVYSVNUUyIpOworICAgICAgICB9CisKKyAgICAgICAgY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIoIk1PQ0tOQU1FIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE1vY2tQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKworICAgICAgICBwdWJsaWMgTW9ja1Byb3ZpZGVyKFN0cmluZyBuYW1lLCBkb3VibGUgdmVyc2lvbiwgU3RyaW5nIGluZm8pIHsKKyAgICAgICAgICAgIHN1cGVyKG5hbWUsIHZlcnNpb24sIGluZm8pOworCisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBwdXRTZXJ2aWNlKFByb3ZpZGVyLlNlcnZpY2Ugc2VydmljZSkgeworICAgICAgICAgICAgc3VwZXIucHV0U2VydmljZShzZXJ2aWNlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZVNlcnZpY2UoUHJvdmlkZXIuU2VydmljZSBzZXJ2aWNlKSB7CisgICAgICAgICAgICBzdXBlci5yZW1vdmVTZXJ2aWNlKHNlcnZpY2UpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1Byb3ZpZGVyRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1Byb3ZpZGVyRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAzYTg2ZTcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvUHJvdmlkZXJFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSwxNzUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXJFeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlByb3ZpZGVyRXhjZXB0aW9uPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgUHJvdmlkZXJFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gbXNncyA9IHsKKyAgICAgICAgICAgICIiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSIgfTsKKworICAgIHByaXZhdGUgc3RhdGljIFRocm93YWJsZSB0Q2F1c2UgPSBuZXcgVGhyb3dhYmxlKCJUaHJvd2FibGUgZm9yIGV4Y2VwdGlvbiIpOworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+UHJvdmlkZXJFeGNlcHRpb24oKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgUHJvdmlkZXJFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RQcm92aWRlckV4Y2VwdGlvbjAxKCkgeworICAgICAgICBQcm92aWRlckV4Y2VwdGlvbiB0RSA9IG5ldyBQcm92aWRlckV4Y2VwdGlvbigpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5Qcm92aWRlckV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246CisgICAgICogY29uc3RydWN0cyBQcm92aWRlckV4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4gUGFyYW1ldGVyCisgICAgICogPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJvdmlkZXJFeGNlcHRpb24wMigpIHsKKyAgICAgICAgUHJvdmlkZXJFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgUHJvdmlkZXJFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5Qcm92aWRlckV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246CisgICAgICogY29uc3RydWN0cyBQcm92aWRlckV4Y2VwdGlvbiB3aGVuIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RQcm92aWRlckV4Y2VwdGlvbjAzKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICAgICAgUHJvdmlkZXJFeGNlcHRpb24gdEUgPSBuZXcgUHJvdmlkZXJFeGNlcHRpb24obXNnKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+UHJvdmlkZXJFeGNlcHRpb24oVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgUHJvdmlkZXJFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RQcm92aWRlckV4Y2VwdGlvbjA0KCkgeworICAgICAgICBUaHJvd2FibGUgY2F1c2UgPSBudWxsOworICAgICAgICBQcm92aWRlckV4Y2VwdGlvbiB0RSA9IG5ldyBQcm92aWRlckV4Y2VwdGlvbihjYXVzZSk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPlByb3ZpZGVyRXhjZXB0aW9uKFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIFByb3ZpZGVyRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdAorICAgICAqIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJvdmlkZXJFeGNlcHRpb24wNSgpIHsKKyAgICAgICAgUHJvdmlkZXJFeGNlcHRpb24gdEUgPSBuZXcgUHJvdmlkZXJFeGNlcHRpb24odENhdXNlKTsKKyAgICAgICAgaWYgKHRFLmdldE1lc3NhZ2UoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBzaG91bGQgY29udGFpbiAiLmNvbmNhdCh0b1MpLCAoZ2V0TQorICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgIC5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPlByb3ZpZGVyRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgUHJvdmlkZXJFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbAorICAgICAqIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RQcm92aWRlckV4Y2VwdGlvbjA2KCkgeworICAgICAgICBQcm92aWRlckV4Y2VwdGlvbiB0RSA9IG5ldyBQcm92aWRlckV4Y2VwdGlvbihudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5Qcm92aWRlckV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIFByb3ZpZGVyRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwKKyAgICAgKiA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFByb3ZpZGVyRXhjZXB0aW9uMDcoKSB7CisgICAgICAgIFByb3ZpZGVyRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IFByb3ZpZGVyRXhjZXB0aW9uKG1zZ3NbaV0sIG51bGwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm46ICIuY29uY2F0KG1zZ3NbaV0pLCB0RQorICAgICAgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZSgpLCBtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+UHJvdmlkZXJFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBQcm92aWRlckV4Y2VwdGlvbiB3aGVuIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QKKyAgICAgKiBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RQcm92aWRlckV4Y2VwdGlvbjA4KCkgeworICAgICAgICBQcm92aWRlckV4Y2VwdGlvbiB0RSA9IG5ldyBQcm92aWRlckV4Y2VwdGlvbihudWxsLCB0Q2F1c2UpOworICAgICAgICBpZiAodEUuZ2V0TWVzc2FnZSgpICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIFN0cmluZyBnZXRNID0gdEUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIG11c3Qgc2hvdWxkICIuY29uY2F0KHRvUyksIChnZXRNCisgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKHRvUykgIT0gLTEpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiAiLmNvbmNhdCh0Q2F1c2UudG9TdHJpbmcoKSksIHRFCisgICAgICAgICAgICAgICAgLmdldENhdXNlKCksIHRDYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+UHJvdmlkZXJFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBQcm92aWRlckV4Y2VwdGlvbiB3aGVuIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QKKyAgICAgKiBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJvdmlkZXJFeGNlcHRpb24wOSgpIHsKKyAgICAgICAgUHJvdmlkZXJFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgUHJvdmlkZXJFeGNlcHRpb24obXNnc1tpXSwgdENhdXNlKTsKKyAgICAgICAgICAgIFN0cmluZyBnZXRNID0gdEUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgaWYgKG1zZ3NbaV0ubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIG11c3QgY29udGFpbiAiLmNvbmNhdChtc2dzW2ldKSwgZ2V0TQorICAgICAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YobXNnc1tpXSkgIT0gLTEpOworICAgICAgICAgICAgICAgIGlmICghZ2V0TS5lcXVhbHMobXNnc1tpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIHNob3VsZCBjb250YWluICIuY29uY2F0KHRvUyksIGdldE0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLAorICAgICAgICAgICAgICAgICAgICB0RS5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1Byb3ZpZGVyU2VydmljZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9Qcm92aWRlclNlcnZpY2VUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmVmMjdiYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9Qcm92aWRlclNlcnZpY2VUZXN0LmphdmEKQEAgLTAsMCArMSwyMjkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorICogQGF1dGhvciBCb3JpcyBWLiBLdXpuZXRzb3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlci5TZXJ2aWNlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5SYW5kb21JbXBsOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5Qcm92aWRlci5TZXJ2aWNlPC9jb2RlPiBjb25zdHJ1Y3RvciBhbmQgbWV0aG9kcworICoKKyAqLworcHVibGljIGNsYXNzIFByb3ZpZGVyU2VydmljZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VydmljZSgpIHsKKyAgICAgICAgUHJvdmlkZXIgcCA9IG5ldyBNeVByb3ZpZGVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUHJvdmlkZXIuU2VydmljZShudWxsLCAidHlwZSIsICJhbGdvcml0aG0iLCAiY2xhc3NOYW1lIiwgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJwcm92aWRlciBpcyBudWxsOiBObyBleHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBQcm92aWRlci5TZXJ2aWNlKHAsIG51bGwsICJhbGdvcml0aG0iLCAiY2xhc3NOYW1lIiwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJ0eXBlIGlzIG51bGw6IE5vIGV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFByb3ZpZGVyLlNlcnZpY2UocCwgInR5cGUiLCBudWxsLCAiY2xhc3NOYW1lIiwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJhbGdvcml0aG0gaXMgbnVsbDogTm8gZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUHJvdmlkZXIuU2VydmljZShwLCAidHlwZSIsICJhbGdvcml0aG0iLCBudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoImNsYXNzTmFtZSBpcyBudWxsOiBObyBleHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBQcm92aWRlci5TZXJ2aWNlIHMgPSBuZXcgUHJvdmlkZXIuU2VydmljZShwLCAidHlwZSIsICJhbGdvcml0aG0iLAorICAgICAgICAgICAgICAgICJjbGFzc05hbWUiLCBudWxsLCBudWxsKTsKKworICAgICAgICBpZiAoIXMuZ2V0VHlwZSgpLmVxdWFscygidHlwZSIpKSB7CisgICAgICAgICAgICBmYWlsKCJnZXRUeXBlKCkgZmFpbGVkIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFzLmdldEFsZ29yaXRobSgpLmVxdWFscygiYWxnb3JpdGhtIikpIHsKKyAgICAgICAgICAgIGZhaWwoImdldEFsZ29yaXRobSgpIGZhaWxlZCIpOworICAgICAgICB9CisgICAgICAgIGlmIChzLmdldFByb3ZpZGVyKCkgIT0gcCkgeworICAgICAgICAgICAgZmFpbCgiZ2V0UHJvdmlkZXIoKSBmYWlsZWQiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXMuZ2V0Q2xhc3NOYW1lKCkuZXF1YWxzKCJjbGFzc05hbWUiKSkgeworICAgICAgICAgICAgZmFpbCgiZ2V0Q2xhc3NOYW1lKCkgZmFpbGVkIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFzLnN1cHBvcnRzUGFyYW1ldGVyKG5ldyBPYmplY3QoKSkpIHsKKyAgICAgICAgICAgIGZhaWwoInN1cHBvcnRzUGFyYW1ldGVyKCkgZmFpbGVkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0QXR0cmlidXRlKCkgeworICAgICAgICBQcm92aWRlciBwID0gbmV3IE15UHJvdmlkZXIoKTsKKyAgICAgICAgUHJvdmlkZXIuU2VydmljZSBzID0gbmV3IFByb3ZpZGVyLlNlcnZpY2UocCwgInR5cGUiLCAiYWxnb3JpdGhtIiwKKyAgICAgICAgICAgICAgICAiY2xhc3NOYW1lIiwgbnVsbCwgbnVsbCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmdldEF0dHJpYnV0ZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzLmdldEF0dHJpYnV0ZSgiYWFhIikgIT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbCgiZ2V0QXR0cmlidXRlKGFhYSkgZmFpbGVkIik7CisgICAgICAgIH0KKworICAgICAgICBIYXNoTWFwPFN0cmluZywgU3RyaW5nPiBobSA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOworICAgICAgICBobS5wdXQoImF0dHJpYnV0ZSIsICJ2YWx1ZSIpOworICAgICAgICBobS5wdXQoIktleVNpemUiLCAiMTAyNCIpOworICAgICAgICBobS5wdXQoIkFBQSIsICJCQkIiKTsKKworICAgICAgICBzID0gbmV3IFByb3ZpZGVyLlNlcnZpY2UocCwgInR5cGUiLCAiYWxnb3JpdGhtIiwgImNsYXNzTmFtZSIsIG51bGwsIGhtKTsKKyAgICAgICAgaWYgKHMuZ2V0QXR0cmlidXRlKCJiYmIiKSAhPSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKCJnZXRBdHRyaWJ1dGUoYmJiKSBmYWlsZWQiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXMuZ2V0QXR0cmlidXRlKCJhdHRyaWJ1dGUiKS5lcXVhbHMoInZhbHVlIikpIHsKKyAgICAgICAgICAgIGZhaWwoImdldEF0dHJpYnV0ZShhdHRyaWJ1dGUpIGZhaWxlZCIpOworICAgICAgICB9CisgICAgICAgIGlmICghcy5nZXRBdHRyaWJ1dGUoIktleVNpemUiKS5lcXVhbHMoIjEwMjQiKSkgeworICAgICAgICAgICAgZmFpbCgiZ2V0QXR0cmlidXRlKEtleVNpemUpIGZhaWxlZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5ld0luc3RhbmNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFByb3ZpZGVyIHAgPSBuZXcgTXlQcm92aWRlcigpOworICAgICAgICBQcm92aWRlci5TZXJ2aWNlIHMgPSBuZXcgUHJvdmlkZXIuU2VydmljZShwLCAiU2VjdXJlUmFuZG9tIiwKKyAgICAgICAgICAgICAgICAiYWxnb3JpdGhtIiwKKyAgICAgICAgICAgICAgICAib3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuUmFuZG9tSW1wbCIsCisgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7CisKKyAgICAgICAgT2JqZWN0IG8gPSBzLm5ld0luc3RhbmNlKG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJpbmNvcnJlY3QgaW5zdGFuY2UiLCBvIGluc3RhbmNlb2YgUmFuZG9tSW1wbCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG8gPSBzLm5ld0luc3RhbmNlKG5ldyBPYmplY3QoKSk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgUHJvdmlkZXIgcCA9IG5ldyBNeVByb3ZpZGVyKCk7CisgICAgICAgIFByb3ZpZGVyLlNlcnZpY2UgczEgPSBuZXcgUHJvdmlkZXIuU2VydmljZShwLCAidHlwZSIsICJhbGdvcml0aG0iLAorICAgICAgICAgICAgICAgICJjbGFzc05hbWUiLCBudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzMS5nZXRBbGdvcml0aG0oKS5lcXVhbHMoImFsZ29yaXRobSIpKTsKKworICAgICAgICBQcm92aWRlci5TZXJ2aWNlIHMyID0gbmV3IFByb3ZpZGVyLlNlcnZpY2UocCwgIlNlY3VyZVJhbmRvbSIsCisgICAgICAgICAgICAgICAgImFsZ29yaXRobSIsICJ0ZXN0cy5qYXZhLnNlY3VyaXR5LnN1cHBvcnQuUmFuZG9tSW1wbCIsIG51bGwsCisgICAgICAgICAgICAgICAgbnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoczIuZ2V0QWxnb3JpdGhtKCkuZXF1YWxzKCJhbGdvcml0aG0iKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldENsYXNzTmFtZSgpIHsKKyAgICAgICAgUHJvdmlkZXIgcCA9IG5ldyBNeVByb3ZpZGVyKCk7CisgICAgICAgIFByb3ZpZGVyLlNlcnZpY2UgczEgPSBuZXcgUHJvdmlkZXIuU2VydmljZShwLCAidHlwZSIsICJhbGdvcml0aG0iLAorICAgICAgICAgICAgICAgICJjbGFzc05hbWUiLCBudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzMS5nZXRDbGFzc05hbWUoKS5lcXVhbHMoImNsYXNzTmFtZSIpKTsKKworICAgICAgICBQcm92aWRlci5TZXJ2aWNlIHMyID0gbmV3IFByb3ZpZGVyLlNlcnZpY2UocCwgIlNlY3VyZVJhbmRvbSIsCisgICAgICAgICAgICAgICAgImFsZ29yaXRobSIsICJ0ZXN0cy5qYXZhLnNlY3VyaXR5LnN1cHBvcnQuUmFuZG9tSW1wbCIsIG51bGwsCisgICAgICAgICAgICAgICAgbnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoczIuZ2V0Q2xhc3NOYW1lKCkuZXF1YWxzKCJ0ZXN0cy5qYXZhLnNlY3VyaXR5LnN1cHBvcnQuUmFuZG9tSW1wbCIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UHJvdmlkZXIoKSB7CisgICAgICAgIFByb3ZpZGVyIHAgPSBuZXcgTXlQcm92aWRlcigpOworICAgICAgICBQcm92aWRlci5TZXJ2aWNlIHMxID0gbmV3IFByb3ZpZGVyLlNlcnZpY2UocCwgInR5cGUiLCAiYWxnb3JpdGhtIiwKKyAgICAgICAgICAgICAgICAiY2xhc3NOYW1lIiwgbnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoczEuZ2V0UHJvdmlkZXIoKSA9PSBwKTsKKworICAgICAgICBQcm92aWRlci5TZXJ2aWNlIHMyID0gbmV3IFByb3ZpZGVyLlNlcnZpY2UocCwgIlNlY3VyZVJhbmRvbSIsCisgICAgICAgICAgICAgICAgImFsZ29yaXRobSIsICJ0ZXN0cy5qYXZhLnNlY3VyaXR5LnN1cHBvcnQuUmFuZG9tSW1wbCIsIG51bGwsCisgICAgICAgICAgICAgICAgbnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoczIuZ2V0UHJvdmlkZXIoKSA9PSBwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VHlwZSgpIHsKKyAgICAgICAgUHJvdmlkZXIgcCA9IG5ldyBNeVByb3ZpZGVyKCk7CisgICAgICAgIFByb3ZpZGVyLlNlcnZpY2UgczEgPSBuZXcgUHJvdmlkZXIuU2VydmljZShwLCAidHlwZSIsICJhbGdvcml0aG0iLAorICAgICAgICAgICAgICAgICJjbGFzc05hbWUiLCBudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzMS5nZXRUeXBlKCkuZXF1YWxzKCJ0eXBlIikpOworCisgICAgICAgIFByb3ZpZGVyLlNlcnZpY2UgczIgPSBuZXcgUHJvdmlkZXIuU2VydmljZShwLCAiU2VjdXJlUmFuZG9tIiwKKyAgICAgICAgICAgICAgICAiYWxnb3JpdGhtIiwgInRlc3RzLmphdmEuc2VjdXJpdHkuc3VwcG9ydC5SYW5kb21JbXBsIiwgbnVsbCwKKyAgICAgICAgICAgICAgICBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzMi5nZXRUeXBlKCkuZXF1YWxzKCJTZWN1cmVSYW5kb20iKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN1cHBvcnRzUGFyYW1ldGVyKCkgeworICAgICAgICBQcm92aWRlciBwID0gbmV3IE15UHJvdmlkZXIoKTsKKyAgICAgICAgUHJvdmlkZXIuU2VydmljZSBzMSA9IG5ldyBQcm92aWRlci5TZXJ2aWNlKHAsICJ0eXBlIiwgImFsZ29yaXRobSIsCisgICAgICAgICAgICAgICAgImNsYXNzTmFtZSIsIG51bGwsIG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKHMxLnN1cHBvcnRzUGFyYW1ldGVyKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzMS5zdXBwb3J0c1BhcmFtZXRlcihuZXcgT2JqZWN0KCkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9TdHJpbmcoKSB7CisgICAgICAgIFByb3ZpZGVyIHAgPSBuZXcgTXlQcm92aWRlcigpOworICAgICAgICBQcm92aWRlci5TZXJ2aWNlIHMxID0gbmV3IFByb3ZpZGVyLlNlcnZpY2UocCwgInR5cGUiLCAiYWxnb3JpdGhtIiwKKyAgICAgICAgICAgICAgICAiY2xhc3NOYW1lIiwgbnVsbCwgbnVsbCk7CisgICAgICAgIHMxLnRvU3RyaW5nKCk7CisKKyAgICAgICAgUHJvdmlkZXIuU2VydmljZSBzMiA9IG5ldyBQcm92aWRlci5TZXJ2aWNlKHAsICJTZWN1cmVSYW5kb20iLAorICAgICAgICAgICAgICAgICJhbGdvcml0aG0iLCAidGVzdHMuamF2YS5zZWN1cml0eS5zdXBwb3J0LlJhbmRvbUltcGwiLCBudWxsLAorICAgICAgICAgICAgICAgIG51bGwpOworICAgICAgICBzMi50b1N0cmluZygpOworICAgIH0KKworICAgIGNsYXNzIE15UHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlciB7CisgICAgICAgIE15UHJvdmlkZXIoKSB7CisgICAgICAgICAgICBzdXBlcigiTXlQcm92aWRlciIsIDEuMCwgIlByb3ZpZGVyIGZvciB0ZXN0aW5nIik7CisgICAgICAgICAgICBwdXQoIk1lc3NhZ2VEaWdlc3QuU0hBLTEiLCAiU29tZUNsYXNzTmFtZSIpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBjbGFzcyBNeVNlcnZpY2UgZXh0ZW5kcyBQcm92aWRlci5TZXJ2aWNlIHsKKworICAgICAgICBwdWJsaWMgTXlTZXJ2aWNlKFByb3ZpZGVyIHByb3ZpZGVyLCBTdHJpbmcgdHlwZSwgU3RyaW5nIGFsZ29yaXRobSwKKyAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lLCBMaXN0PFN0cmluZz4gYWxpYXNlcywKKyAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBTdHJpbmc+IGF0dHJpYnV0ZXMpIHsKKyAgICAgICAgICAgIHN1cGVyKHByb3ZpZGVyLCB0eXBlLCBhbGdvcml0aG0sIGNsYXNzTmFtZSwgYWxpYXNlcywgYXR0cmlidXRlcyk7CisgICAgICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIGNvbnN0cnVjdG9yIHN0dWIKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c1BhcmFtZXRlcihPYmplY3QgcGFyYW1ldGVyKSB7CisgICAgICAgICAgICBpZiAocGFyYW1ldGVyLmdldENsYXNzKCkgPT0gU3RyaW5nLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvUHJvdmlkZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvUHJvdmlkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWE5MDQyNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9Qcm92aWRlclRlc3QuamF2YQpAQCAtMCwwICsxLDYxNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisgKiBAYXV0aG9yIEJvcmlzIFYuIEt1em5ldHNvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlByaW50U3RyZWFtOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eVBlcm1pc3Npb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlci5TZXJ2aWNlOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLk1hcC5FbnRyeTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+UHJvdmlkZXI8L2NvZGU+IGNvbnN0cnVjdG9yIGFuZCBtZXRob2RzCisgKgorICovCitwdWJsaWMgY2xhc3MgUHJvdmlkZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIC8qCisgICAgICogSW1wbGVtZW50YXRpb24gbm90ZTogVGhlIGFsZ29yaXRobSBuYW1lIEFTSC0xIG1pZ2h0IHNlZW0gYSBiaXQgc3RyYW5nZSwKKyAgICAgKiBidXQgc2luY2UgdGhlIGFsZ29yaXRobXMgY2Fubm90IGJlIHVuaW5zdGFsbGVkIGFueW1vcmUgd2UgbmVlZCB0byBtYWtlCisgICAgICogc3VyZSB0aGVyZSBhcmUgbm90IHNpZGUtZWZmZWN0cyBvbiBvdGhlciB0ZXN0cy4gU2ltcGx5IGluc2VydGluZyBTSEEtMQorICAgICAqIGRlc3Ryb3lzIHRoZSBleGlzdGluZyBwcm92aWRlciBpbmZyYXN0cnVjdHVyZS4KKyAgICAgKi8KKworICAgIFByb3ZpZGVyW10gc3RvcmVkUHJvdmlkZXJzOworCisgICAgUHJvdmlkZXIgcDsKKworICAgIC8qCisgICAgICogQHNlZSBUZXN0Q2FzZSNzZXRVcCgpCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKworICAgICAgICBzdG9yZWRQcm92aWRlcnMgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoKTsKKworICAgICAgICBwID0gbmV3IE15UHJvdmlkZXIoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBwLnJlbW92ZSgiTWVzc2FnZURpZ2VzdC5BU0gtMSIpOworICAgICAgICBwLnJlbW92ZSgiTWVzc2FnZURpZ2VzdC5hYmMiKTsKKyAgICAgICAgcC5yZW1vdmUoIkFsZy5BbGlhcy5NZXNzYWdlRGlnZXN0LkFTSDEiKTsKKworICAgICAgICBmb3IgKFByb3ZpZGVyIHA6IFNlY3VyaXR5LmdldFByb3ZpZGVycygpKSB7CisgICAgICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcihwLmdldE5hbWUoKSk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKFByb3ZpZGVyIHA6IHN0b3JlZFByb3ZpZGVycykgeworICAgICAgICAgICAgU2VjdXJpdHkuYWRkUHJvdmlkZXIocCk7CisgICAgICAgIH0KKworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3Igdm9pZCBQcm92aWRlcigpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFByb3ZpZGVyKCkgeworICAgICAgICBpZiAoIXAuZ2V0UHJvcGVydHkoIlByb3ZpZGVyLmlkIG5hbWUiKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgU3RyaW5nLnZhbHVlT2YocC5nZXROYW1lKCkpKSkgeworICAgICAgICAgICAgZmFpbCgiSW5jb3JyZWN0IFwiUHJvdmlkZXIuaWQgbmFtZVwiIHZhbHVlIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFwLmdldFByb3BlcnR5KCJQcm92aWRlci5pZCB2ZXJzaW9uIikuZXF1YWxzKAorICAgICAgICAgICAgICAgIFN0cmluZy52YWx1ZU9mKHAuZ2V0VmVyc2lvbigpKSkpIHsKKyAgICAgICAgICAgIGZhaWwoIkluY29ycmVjdCBcIlByb3ZpZGVyLmlkIHZlcnNpb25cIiB2YWx1ZSIpOworICAgICAgICB9CisgICAgICAgIGlmICghcC5nZXRQcm9wZXJ0eSgiUHJvdmlkZXIuaWQgaW5mbyIpLmVxdWFscygKKyAgICAgICAgICAgICAgICBTdHJpbmcudmFsdWVPZihwLmdldEluZm8oKSkpKSB7CisgICAgICAgICAgICBmYWlsKCJJbmNvcnJlY3QgXCJQcm92aWRlci5pZCBpbmZvXCIgdmFsdWUiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXAuZ2V0UHJvcGVydHkoIlByb3ZpZGVyLmlkIGNsYXNzTmFtZSIpLmVxdWFscygKKyAgICAgICAgICAgICAgICBwLmdldENsYXNzKCkuZ2V0TmFtZSgpKSkgeworICAgICAgICAgICAgZmFpbCgiSW5jb3JyZWN0IFwiUHJvdmlkZXIuaWQgY2xhc3NOYW1lXCIgdmFsdWUiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RDbGVhcigpIHsKKyAgICAgICAgcC5jbGVhcigpOworICAgICAgICBhc3NlcnROdWxsKHAuZ2V0UHJvcGVydHkoIk1lc3NhZ2VEaWdlc3QuU0hBLTEiKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciB2b2lkIFByb3ZpZGVyKFN0cmluZywgZG91YmxlLCBTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFByb3ZpZGVyU3RyaW5nZG91YmxlU3RyaW5nKCkgeworICAgICAgICBQcm92aWRlciBwID0gbmV3IE15UHJvdmlkZXIoIlByb3ZpZGVyIG5hbWUiLCAxMjMuNDU2LCAiUHJvdmlkZXIgaW5mbyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlByb3ZpZGVyIG5hbWUiLCBwLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMjMuNDU2LCBwLmdldFZlcnNpb24oKSwgMEwpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlByb3ZpZGVyIGluZm8iLCBwLmdldEluZm8oKSk7CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldE5hbWUoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiTXlQcm92aWRlciIsIHAuZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0VmVyc2lvbigpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEuMCwgcC5nZXRWZXJzaW9uKCksIDBMKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0SW5mbygpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJQcm92aWRlciBmb3IgdGVzdGluZyIsIHAuZ2V0SW5mbygpKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIHZvaWQgcHV0QWxsKE1hcCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UHV0QWxsTWFwKCkgeworICAgICAgICBIYXNoTWFwIGhtID0gbmV3IEhhc2hNYXAoKTsKKyAgICAgICAgaG0ucHV0KCJNZXNzYWdlRGlnZXN0LlNIQS0xIiwgImFhYS5iYmIuY2NjLmRkZCIpOworICAgICAgICBobS5wdXQoIlByb3BlcnR5IDEiLCAidmFsdWUgMSIpOworICAgICAgICBobS5wdXQoInNlcnZpY2VOYW1lLmFsZ05hbWUgYXR0ck5hbWUiLCAiYXR0clZhbHVlIik7CisgICAgICAgIGhtLnB1dCgiQWxnLkFsaWFzLmVuZ2luZUNsYXNzTmFtZS5hbGlhc05hbWUiLCAic3RhbmRhcmROYW1lIik7CisgICAgICAgIHAucHV0QWxsKGhtKTsKKyAgICAgICAgaWYgKCEidmFsdWUgMSIuZXF1YWxzKHAuZ2V0UHJvcGVydHkoIlByb3BlcnR5IDEiKS50cmltKCkpIHx8CisgICAgICAgICAgICAgICAgISJhdHRyVmFsdWUiLmVxdWFscyhwLmdldFByb3BlcnR5KCJzZXJ2aWNlTmFtZS5hbGdOYW1lIGF0dHJOYW1lIikudHJpbSgpKSB8fAorICAgICAgICAgICAgICAgICEic3RhbmRhcmROYW1lIi5lcXVhbHMocC5nZXRQcm9wZXJ0eSgiQWxnLkFsaWFzLmVuZ2luZUNsYXNzTmFtZS5hbGlhc05hbWUiKS50cmltKCkpIHx8CisgICAgICAgICAgICAgICAgISJhYWEuYmJiLmNjYy5kZGQiLmVxdWFscyhwLmdldFByb3BlcnR5KCJNZXNzYWdlRGlnZXN0LlNIQS0xIikudHJpbSgpKSApIHsKKyAgICAgICAgICAgIGZhaWwoIkluY29ycmVjdCBwcm9wZXJ0eSB2YWx1ZSIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciBTZXQgZW50cnlTZXQoKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFbnRyeVNldCgpIHsKKyAgICAgICAgcC5wdXQoIk1lc3NhZ2VEaWdlc3QuU0hBLTI1NiIsICJhYWEuYmJiLmNjYy5kZGQiKTsKKworICAgICAgICBTZXQgcyA9IHAuZW50cnlTZXQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMuY2xlYXIoKTsKKyAgICAgICAgICAgIGZhaWwoIk11c3QgcmV0dXJuIHVubW9kaWZpYWJsZSBzZXQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3Qgc2V0IHNpemUiLCA4LCBzLnNpemUoKSk7CisKKyAgICAgICAgZm9yIChJdGVyYXRvciBpdCA9IHMuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOykgeworICAgICAgICAgICAgRW50cnkgZSA9IChFbnRyeSlpdC5uZXh0KCk7CisgICAgICAgICAgICBTdHJpbmcga2V5ID0gKFN0cmluZyllLmdldEtleSgpOworICAgICAgICAgICAgU3RyaW5nIHZhbCA9IChTdHJpbmcpZS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgaWYgKGtleS5lcXVhbHMoIk1lc3NhZ2VEaWdlc3QuU0hBLTEiKSAmJiB2YWwuZXF1YWxzKCJTb21lQ2xhc3NOYW1lIikpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChrZXkuZXF1YWxzKCJBbGcuQWxpYXMuTWVzc2FnZURpZ2VzdC5TSEExIikgJiYgdmFsLmVxdWFscygiU0hBLTEiKSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGtleS5lcXVhbHMoIk1lc3NhZ2VEaWdlc3QuYWJjIikgJiYgdmFsLmVxdWFscygiU29tZUNsYXNzTmFtZSIpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoa2V5LmVxdWFscygiUHJvdmlkZXIuaWQgY2xhc3NOYW1lIikgJiYgdmFsLmVxdWFscyhwLmdldENsYXNzKCkuZ2V0TmFtZSgpKSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGtleS5lcXVhbHMoIlByb3ZpZGVyLmlkIG5hbWUiKSAmJiB2YWwuZXF1YWxzKCJNeVByb3ZpZGVyIikpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChrZXkuZXF1YWxzKCJNZXNzYWdlRGlnZXN0LlNIQS0yNTYiKSAmJiB2YWwuZXF1YWxzKCJhYWEuYmJiLmNjYy5kZGQiKSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGtleS5lcXVhbHMoIlByb3ZpZGVyLmlkIHZlcnNpb24iKSAmJiB2YWwuZXF1YWxzKCIxLjAiKSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGtleS5lcXVhbHMoIlByb3ZpZGVyLmlkIGluZm8iKSAmJiB2YWwuZXF1YWxzKCJQcm92aWRlciBmb3IgdGVzdGluZyIpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmYWlsKCJJbmNvcnJlY3Qgc2V0Iik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIFNldCBrZXlTZXQoKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RLZXlTZXQoKSB7CisgICAgICAgIHAucHV0KCJNZXNzYWdlRGlnZXN0LlNIQS0yNTYiLCAiYWFhLmJiYi5jY2MuZGRkIik7CisKKyAgICAgICAgU2V0PE9iamVjdD4gcyA9IHAua2V5U2V0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmNsZWFyKCk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBTZXQgczEgPSBwLmtleVNldCgpOworCisgICAgICAgIGFzc2VydE5vdFNhbWUocywgczEpOworICAgICAgICBhc3NlcnRGYWxzZShzMS5pc0VtcHR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoOCwgczEuc2l6ZSgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKHMxLmNvbnRhaW5zKCJNZXNzYWdlRGlnZXN0LlNIQS0yNTYiKSk7CisgICAgICAgIGFzc2VydFRydWUoczEuY29udGFpbnMoIk1lc3NhZ2VEaWdlc3QuU0hBLTEiKSk7CisgICAgICAgIGFzc2VydFRydWUoczEuY29udGFpbnMoIkFsZy5BbGlhcy5NZXNzYWdlRGlnZXN0LlNIQTEiKSk7CisgICAgICAgIGFzc2VydFRydWUoczEuY29udGFpbnMoIk1lc3NhZ2VEaWdlc3QuYWJjIikpOworICAgICAgICBhc3NlcnRUcnVlKHMxLmNvbnRhaW5zKCJQcm92aWRlci5pZCBpbmZvIikpOworICAgICAgICBhc3NlcnRUcnVlKHMxLmNvbnRhaW5zKCJQcm92aWRlci5pZCBjbGFzc05hbWUiKSk7CisgICAgICAgIGFzc2VydFRydWUoczEuY29udGFpbnMoIlByb3ZpZGVyLmlkIHZlcnNpb24iKSk7CisgICAgICAgIGFzc2VydFRydWUoczEuY29udGFpbnMoIlByb3ZpZGVyLmlkIG5hbWUiKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciBDb2xsZWN0aW9uIHZhbHVlcygpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFZhbHVlcygpIHsKKyAgICAgICAgcC5wdXQoIk1lc3NhZ2VEaWdlc3QuQVNILTI1NiIsICJhYWEuYmJiLmNjYy5kZGQiKTsKKworICAgICAgICBDb2xsZWN0aW9uPE9iamVjdD4gYyA9IHAudmFsdWVzKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLmNsZWFyKCk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBDb2xsZWN0aW9uIGMxID0gcC52YWx1ZXMoKTsKKworICAgICAgICBhc3NlcnROb3RTYW1lKGMsIGMxKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoYzEuaXNFbXB0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDgsIGMxLnNpemUoKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShjMS5jb250YWlucygiTXlQcm92aWRlciIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjMS5jb250YWlucygiYWFhLmJiYi5jY2MuZGRkIikpOworICAgICAgICBhc3NlcnRUcnVlKGMxLmNvbnRhaW5zKCJQcm92aWRlciBmb3IgdGVzdGluZyIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjMS5jb250YWlucygiMS4wIikpOworICAgICAgICBhc3NlcnRUcnVlKGMxLmNvbnRhaW5zKCJTb21lQ2xhc3NOYW1lIikpOworICAgICAgICBhc3NlcnRUcnVlKGMxLmNvbnRhaW5zKCJTSEEtMSIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjMS5jb250YWlucyhwLmdldENsYXNzKCkuZ2V0TmFtZSgpKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciBPYmplY3QgcHV0KE9iamVjdCwgT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RQdXRPYmplY3RPYmplY3QoKSB7CisgICAgICAgIHAucHV0KCJNZXNzYWdlRGlnZXN0LlNIQS0xIiwgImFhYS5iYmIuY2NjLmRkZCIpOworICAgICAgICBwLnB1dCgiVHlwZS5BbGdvcml0aG0iLCAiY2xhc3NOYW1lIik7CisgICAgICAgIGFzc2VydEVxdWFscygiYWFhLmJiYi5jY2MuZGRkIiwgcC5nZXRQcm9wZXJ0eSgiTWVzc2FnZURpZ2VzdC5TSEEtMSIpCisgICAgICAgICAgICAgICAgLnRyaW0oKSk7CisKKyAgICAgICAgU2V0IHNlcnZpY2VzID0gcC5nZXRTZXJ2aWNlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgc2VydmljZXMuc2l6ZSgpKTsKKworICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0ID0gc2VydmljZXMuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOykgeworICAgICAgICAgICAgUHJvdmlkZXIuU2VydmljZSBzID0gKFByb3ZpZGVyLlNlcnZpY2UpaXQubmV4dCgpOworICAgICAgICAgICAgaWYgKCJUeXBlIi5lcXVhbHMocy5nZXRUeXBlKCkpICYmCisgICAgICAgICAgICAgICAgICAgICJBbGdvcml0aG0iLmVxdWFscyhzLmdldEFsZ29yaXRobSgpKSAmJgorICAgICAgICAgICAgICAgICAgICAiY2xhc3NOYW1lIi5lcXVhbHMocy5nZXRDbGFzc05hbWUoKSkpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICgiTWVzc2FnZURpZ2VzdCIuZXF1YWxzKHMuZ2V0VHlwZSgpKSAmJgorICAgICAgICAgICAgICAgICAgICAiU0hBLTEiLmVxdWFscyhzLmdldEFsZ29yaXRobSgpKSAmJgorICAgICAgICAgICAgICAgICAgICAiYWFhLmJiYi5jY2MuZGRkIi5lcXVhbHMocy5nZXRDbGFzc05hbWUoKSkpIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICgiTWVzc2FnZURpZ2VzdCIuZXF1YWxzKHMuZ2V0VHlwZSgpKSAmJgorICAgICAgICAgICAgICAgICAgICAiYWJjIi5lcXVhbHMocy5nZXRBbGdvcml0aG0oKSkgJiYKKyAgICAgICAgICAgICAgICAgICAgIlNvbWVDbGFzc05hbWUiLmVxdWFscyhzLmdldENsYXNzTmFtZSgpKSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmFpbCgiSW5jb3JyZWN0IHNlcnZpY2UiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3IgT2JqZWN0IHJlbW92ZShPYmplY3QpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJlbW92ZU9iamVjdCgpIHsKKyAgICAgICAgT2JqZWN0IG8gPSBwLnJlbW92ZSgiTWVzc2FnZURpZ2VzdC5TSEEtMSIpOworCisgICAgICAgIGFzc2VydEVxdWFscygiU29tZUNsYXNzTmFtZSIsIG8pOworICAgICAgICBhc3NlcnROdWxsKHAuZ2V0UHJvcGVydHkoIk1lc3NhZ2VEaWdlc3QuU0hBLTEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBwLmdldFNlcnZpY2VzKCkuc2l6ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0U2VydmljZTEoKSB7CisgICAgICAgIHAucHV0KCJNZXNzYWdlRGlnZXN0LlNIQS0xIiwgIkFub3RoZXJDbGFzc05hbWUiKTsKKyAgICAgICAgUHJvdmlkZXIuU2VydmljZSBzID0gcC5nZXRTZXJ2aWNlKCJNZXNzYWdlRGlnZXN0IiwgIlNIQS0xIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQW5vdGhlckNsYXNzTmFtZSIsIHMuZ2V0Q2xhc3NOYW1lKCkpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRTZXJ2aWNlQ2FzZVNlbnNpdGl2aXR5KCkgeworICAgICAgICBwLnB1dCgiaS5JIiwgImZvbyIpOworCisgICAgICAgIExvY2FsZSBkZWZhdWx0TG9jYWxlID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobmV3IExvY2FsZSgidHIiLCAiVFIiKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImZvbyIsIHAuZ2V0U2VydmljZSgiaSIsICJpIikuZ2V0Q2xhc3NOYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBwLmdldFNlcnZpY2UoImkiLCAiSSIpLmdldENsYXNzTmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwocC5nZXRTZXJ2aWNlKCJcdTAxMzAiLCAiXHUwMTMwIikpOyAvLyBUdXJraXNoIGRvdGxlc3MgaSBhbmQgZG90dGVkIEkKKyAgICAgICAgICAgIGFzc2VydE51bGwocC5nZXRTZXJ2aWNlKCJcdTAxMzEiLCAiXHUwMTMxIikpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgTG9jYWxlLnNldERlZmF1bHQoZGVmYXVsdExvY2FsZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTI3NjAuCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdG9yKCkgeworICAgICAgICBNeVByb3ZpZGVyIG15UHJvdmlkZXIgPSBuZXcgTXlQcm92aWRlcihudWxsLCAxLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChteVByb3ZpZGVyLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydE51bGwobXlQcm92aWRlci5nZXRJbmZvKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm51bGwiLCBteVByb3ZpZGVyLmdldFByb3BlcnR5KCJQcm92aWRlci5pZCBuYW1lIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm51bGwiLCBteVByb3ZpZGVyLmdldFByb3BlcnR5KCJQcm92aWRlci5pZCBpbmZvIikpOworICAgIH0KKworICAgIGNsYXNzIE15UHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlciB7CisgICAgICAgIE15UHJvdmlkZXIoKSB7CisgICAgICAgICAgICBzdXBlcigiTXlQcm92aWRlciIsIDEuMCwgIlByb3ZpZGVyIGZvciB0ZXN0aW5nIik7CisgICAgICAgICAgICBwdXQoIk1lc3NhZ2VEaWdlc3QuU0hBLTEiLCAiU29tZUNsYXNzTmFtZSIpOworICAgICAgICAgICAgcHV0KCJNZXNzYWdlRGlnZXN0LmFiYyIsICJTb21lQ2xhc3NOYW1lIik7CisgICAgICAgICAgICBwdXQoIkFsZy5BbGlhcy5NZXNzYWdlRGlnZXN0LlNIQTEiLCAiU0hBLTEiKTsKKyAgICAgICAgfQorCisgICAgICAgIE15UHJvdmlkZXIoU3RyaW5nIG5hbWUsIGRvdWJsZSB2ZXJzaW9uLCBTdHJpbmcgaW5mbykgeworICAgICAgICAgICAgc3VwZXIobmFtZSwgdmVyc2lvbiwgaW5mbyk7CisgICAgICAgIH0KKworICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLWFkZGVkCisgICAgICAgIHB1YmxpYyB2b2lkIHB1dFNlcnZpY2UoUHJvdmlkZXIuU2VydmljZSBzKSB7CisgICAgICAgICAgICBzdXBlci5wdXRTZXJ2aWNlKHMpOworICAgICAgICB9CisgICAgICAgIC8vIEVORCBhbmRyb2lkLWFkZGVkCisKKyAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1hZGRlZAorICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmVTZXJ2aWNlKFByb3ZpZGVyLlNlcnZpY2UgcykgeworICAgICAgICAgICAgc3VwZXIucmVtb3ZlU2VydmljZShzKTsKKyAgICAgICAgfQorICAgICAgICAvLyBFTkQgYW5kcm9pZC1hZGRlZAorCisgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtYWRkZWQKKyAgICAgICAgcHVibGljIGludCBnZXROdW1TZXJ2aWNlcygpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRTZXJ2aWNlcygpLnNpemUoKTsKKyAgICAgICAgfQorICAgICAgICAvLyBFTkQgYW5kcm9pZC1hZGRlZAorICAgIH0KKworICAgIC8vIEJFR0lOIGFuZHJvaWQtYWRkZWQKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0U2VydmljZTIoKSB7CisgICAgICAgIFByb3ZpZGVyW10gcHAgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoIk1lc3NhZ2VEaWdlc3QuQVNILTEiKTsKKyAgICAgICAgaWYgKHBwID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBwMiA9IHBwWzBdOworICAgICAgICBTdHJpbmcgb2xkID0gcDIuZ2V0UHJvcGVydHkoIk1lc3NhZ2VEaWdlc3QuQVNILTEiKTsKKyAgICAgICAgcDIucHV0KCJNZXNzYWdlRGlnZXN0LkFTSC0xIiwgIkFub3RoZXJDbGFzc05hbWUiKTsKKyAgICAgICAgUHJvdmlkZXIuU2VydmljZSBzID0gcDIuZ2V0U2VydmljZSgiTWVzc2FnZURpZ2VzdCIsICJBU0gtMSIpOworICAgICAgICBpZiAoISJBbm90aGVyQ2xhc3NOYW1lIi5lcXVhbHMocy5nZXRDbGFzc05hbWUoKSkpIHsKKyAgICAgICAgICAgIGZhaWwoIkluY29ycmVjdCBjbGFzcyBuYW1lICIgKyBzLmdldENsYXNzTmFtZSgpKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5uZXdJbnN0YW5jZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorICAgIC8vIEVORCBhbmRyb2lkLWFkZGVkCisKKyAgICAvLyBCRUdJTiBhbmRyb2lkLWFkZGVkCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFNlcnZpY2VzKCkgeworICAgICAgICBNeVByb3ZpZGVyIG15UHJvdmlkZXIgPSBuZXcgTXlQcm92aWRlcihudWxsLCAxLCBudWxsKTsKKyAgICAgICAgU2V0PFByb3ZpZGVyLlNlcnZpY2U+IHNlcnZpY2VzID0gbXlQcm92aWRlci5nZXRTZXJ2aWNlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgc2VydmljZXMuc2l6ZSgpKTsKKworICAgICAgICBQcm92aWRlci5TZXJ2aWNlIHNbXSA9IG5ldyBQcm92aWRlci5TZXJ2aWNlWzNdOworCisgICAgICAgIHNbMF0gPSBuZXcgUHJvdmlkZXIuU2VydmljZShwLCAidHlwZTEiLCAiYWxnb3JpdGhtMSIsICJjbGFzc05hbWUxIiwKKyAgICAgICAgICAgICAgICBudWxsLCBudWxsKTsKKyAgICAgICAgc1sxXSA9IG5ldyBQcm92aWRlci5TZXJ2aWNlKHAsICJ0eXBlMiIsICJhbGdvcml0aG0yIiwgImNsYXNzTmFtZTIiLAorICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOworICAgICAgICBzWzJdID0gbmV3IFByb3ZpZGVyLlNlcnZpY2UocCwgInR5cGUzIiwgImFsZ29yaXRobTMiLCAiY2xhc3NOYW1lMyIsCisgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7CisgICAgICAgIG15UHJvdmlkZXIucHV0U2VydmljZShzWzBdKTsKKyAgICAgICAgbXlQcm92aWRlci5wdXRTZXJ2aWNlKHNbMV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgbXlQcm92aWRlci5nZXROdW1TZXJ2aWNlcygpKTsKKyAgICAgICAgU2V0PFNlcnZpY2U+IGFjdHVhbCA9IG15UHJvdmlkZXIuZ2V0U2VydmljZXMoKTsKKworICAgICAgICBhc3NlcnRUcnVlKGFjdHVhbC5jb250YWlucyhzWzBdKSk7CisgICAgICAgIGFzc2VydFRydWUoYWN0dWFsLmNvbnRhaW5zKHNbMV0pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSghYWN0dWFsLmNvbnRhaW5zKHNbMl0pKTsKKworICAgICAgICBteVByb3ZpZGVyLnJlbW92ZVNlcnZpY2Uoc1sxXSk7CisgICAgICAgIGFjdHVhbCA9IG15UHJvdmlkZXIuZ2V0U2VydmljZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG15UHJvdmlkZXIuZ2V0TnVtU2VydmljZXMoKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShhY3R1YWwuY29udGFpbnMoc1swXSkpOworICAgICAgICBhc3NlcnRUcnVlKCFhY3R1YWwuY29udGFpbnMoc1sxXSkpOworICAgICAgICBhc3NlcnRUcnVlKCFhY3R1YWwuY29udGFpbnMoc1syXSkpOworCisgICAgICAgIG15UHJvdmlkZXIucHV0U2VydmljZShzWzJdKTsKKyAgICAgICAgYWN0dWFsID0gbXlQcm92aWRlci5nZXRTZXJ2aWNlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgbXlQcm92aWRlci5nZXROdW1TZXJ2aWNlcygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhY3R1YWwuY29udGFpbnMoc1swXSkpOworICAgICAgICBhc3NlcnRUcnVlKCFhY3R1YWwuY29udGFpbnMoc1sxXSkpOworICAgICAgICBhc3NlcnRUcnVlKGFjdHVhbC5jb250YWlucyhzWzJdKSk7CisgICAgfQorICAgIC8vIEVORCBhbmRyb2lkLWFkZGVkCisKKyAgICAvLyBCRUdJTiBhbmRyb2lkLWFkZGVkCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFB1dFNlcnZpY2UoKSB7CisgICAgICAgIE15UHJvdmlkZXIgbXlQcm92aWRlciA9IG5ldyBNeVByb3ZpZGVyKG51bGwsIDEsIG51bGwpOworICAgICAgICBQcm92aWRlci5TZXJ2aWNlIHNbXSA9IG5ldyBQcm92aWRlci5TZXJ2aWNlWzNdOworCisgICAgICAgIHNbMF0gPSBuZXcgUHJvdmlkZXIuU2VydmljZShwLCAidHlwZTEiLCAiYWxnb3JpdGhtMSIsICJjbGFzc05hbWUxIiwKKyAgICAgICAgICAgICAgICBudWxsLCBudWxsKTsKKyAgICAgICAgc1sxXSA9IG5ldyBQcm92aWRlci5TZXJ2aWNlKHAsICJ0eXBlMiIsICJhbGdvcml0aG0yIiwgImNsYXNzTmFtZTIiLAorICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOworICAgICAgICBzWzJdID0gbmV3IFByb3ZpZGVyLlNlcnZpY2UocCwgInR5cGUzIiwgImFsZ29yaXRobTMiLCAiY2xhc3NOYW1lMyIsCisgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7CisgICAgICAgIG15UHJvdmlkZXIucHV0U2VydmljZShzWzBdKTsKKyAgICAgICAgbXlQcm92aWRlci5wdXRTZXJ2aWNlKHNbMV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgbXlQcm92aWRlci5nZXROdW1TZXJ2aWNlcygpKTsKKyAgICAgICAgU2V0PFNlcnZpY2U+IGFjdHVhbCA9IG15UHJvdmlkZXIuZ2V0U2VydmljZXMoKTsKKworICAgICAgICBhc3NlcnRUcnVlKGFjdHVhbC5jb250YWlucyhzWzBdKSk7CisgICAgICAgIGFzc2VydFRydWUoYWN0dWFsLmNvbnRhaW5zKHNbMV0pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSghYWN0dWFsLmNvbnRhaW5zKHNbMl0pKTsKKworICAgICAgICBteVByb3ZpZGVyLnJlbW92ZVNlcnZpY2Uoc1sxXSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBteVByb3ZpZGVyLmdldE51bVNlcnZpY2VzKCkpOworICAgICAgICBhY3R1YWwgPSBteVByb3ZpZGVyLmdldFNlcnZpY2VzKCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShhY3R1YWwuY29udGFpbnMoc1swXSkpOworICAgICAgICBhc3NlcnRUcnVlKCFhY3R1YWwuY29udGFpbnMoc1sxXSkpOworICAgICAgICBhc3NlcnRUcnVlKCFhY3R1YWwuY29udGFpbnMoc1syXSkpOworCisgICAgICAgIG15UHJvdmlkZXIucHV0U2VydmljZShzWzJdKTsKKyAgICAgICAgYWN0dWFsID0gbXlQcm92aWRlci5nZXRTZXJ2aWNlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgbXlQcm92aWRlci5nZXROdW1TZXJ2aWNlcygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhY3R1YWwuY29udGFpbnMoc1swXSkpOworICAgICAgICBhc3NlcnRUcnVlKCFhY3R1YWwuY29udGFpbnMoc1sxXSkpOworICAgICAgICBhc3NlcnRUcnVlKGFjdHVhbC5jb250YWlucyhzWzJdKSk7CisKKyAgICAgICAgbXlQcm92aWRlci5wdXRTZXJ2aWNlKHNbMl0pOworICAgICAgICBhY3R1YWwgPSBteVByb3ZpZGVyLmdldFNlcnZpY2VzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBteVByb3ZpZGVyLmdldE51bVNlcnZpY2VzKCkpOworICAgICAgICBhc3NlcnRUcnVlKGFjdHVhbC5jb250YWlucyhzWzBdKSk7CisgICAgICAgIGFzc2VydFRydWUoIWFjdHVhbC5jb250YWlucyhzWzFdKSk7CisgICAgICAgIGFzc2VydFRydWUoYWN0dWFsLmNvbnRhaW5zKHNbMl0pKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXlQcm92aWRlci5wdXRTZXJ2aWNlKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKyAgICAvLyBFTkQgYW5kcm9pZC1hZGRlZAorCisgICAgLy8gQkVHSU4gYW5kcm9pZC1hZGRlZAorICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RSZW1vdmVTZXJ2aWNlKCkgeworICAgICAgICBNeVByb3ZpZGVyIG15UHJvdmlkZXIgPSBuZXcgTXlQcm92aWRlcihudWxsLCAxLCBudWxsKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG15UHJvdmlkZXIucmVtb3ZlU2VydmljZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2l0ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIFByb3ZpZGVyLlNlcnZpY2Ugc1tdID0gbmV3IFByb3ZpZGVyLlNlcnZpY2VbM107CisKKyAgICAgICAgc1swXSA9IG5ldyBQcm92aWRlci5TZXJ2aWNlKHAsICJ0eXBlMCIsICJhbGdvcml0aG0wIiwgImNsYXNzTmFtZTAiLAorICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOworICAgICAgICBzWzFdID0gbmV3IFByb3ZpZGVyLlNlcnZpY2UocCwgInR5cGUxIiwgImFsZ29yaXRobTEiLCAiY2xhc3NOYW1lMSIsCisgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7CisgICAgICAgIHNbMl0gPSBuZXcgUHJvdmlkZXIuU2VydmljZShwLCAidHlwZTIiLCAiYWxnb3JpdGhtMiIsICJjbGFzc05hbWUyIiwKKyAgICAgICAgICAgICAgICBudWxsLCBudWxsKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXlQcm92aWRlci5yZW1vdmVTZXJ2aWNlKHNbMF0pOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgbXlQcm92aWRlci5wdXRTZXJ2aWNlKHNbMF0pOworICAgICAgICBteVByb3ZpZGVyLnB1dFNlcnZpY2Uoc1sxXSk7CisgICAgICAgIG15UHJvdmlkZXIucHV0U2VydmljZShzWzJdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIG15UHJvdmlkZXIuZ2V0TnVtU2VydmljZXMoKSk7CisgICAgICAgIFNldDxTZXJ2aWNlPiBhY3R1YWwgPSBteVByb3ZpZGVyLmdldFNlcnZpY2VzKCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShhY3R1YWwuY29udGFpbnMoc1swXSkpOworICAgICAgICBhc3NlcnRUcnVlKGFjdHVhbC5jb250YWlucyhzWzFdKSk7CisgICAgICAgIGFzc2VydFRydWUoYWN0dWFsLmNvbnRhaW5zKHNbMl0pKTsKKworICAgICAgICBteVByb3ZpZGVyLnJlbW92ZVNlcnZpY2Uoc1sxXSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBteVByb3ZpZGVyLmdldE51bVNlcnZpY2VzKCkpOworICAgICAgICBhY3R1YWwgPSBteVByb3ZpZGVyLmdldFNlcnZpY2VzKCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShhY3R1YWwuY29udGFpbnMoc1swXSkpOworICAgICAgICBhc3NlcnRUcnVlKCFhY3R1YWwuY29udGFpbnMoc1sxXSkpOworICAgICAgICBhc3NlcnRUcnVlKGFjdHVhbC5jb250YWlucyhzWzJdKSk7CisKKyAgICAgICAgbXlQcm92aWRlci5yZW1vdmVTZXJ2aWNlKHNbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgbXlQcm92aWRlci5nZXROdW1TZXJ2aWNlcygpKTsKKyAgICAgICAgYWN0dWFsID0gbXlQcm92aWRlci5nZXRTZXJ2aWNlcygpOworCisgICAgICAgIGFzc2VydFRydWUoIWFjdHVhbC5jb250YWlucyhzWzBdKSk7CisgICAgICAgIGFzc2VydFRydWUoIWFjdHVhbC5jb250YWlucyhzWzFdKSk7CisgICAgICAgIGFzc2VydFRydWUoYWN0dWFsLmNvbnRhaW5zKHNbMl0pKTsKKworICAgICAgICBteVByb3ZpZGVyLnJlbW92ZVNlcnZpY2Uoc1syXSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBteVByb3ZpZGVyLmdldE51bVNlcnZpY2VzKCkpOworICAgICAgICBhY3R1YWwgPSBteVByb3ZpZGVyLmdldFNlcnZpY2VzKCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSghYWN0dWFsLmNvbnRhaW5zKHNbMF0pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSghYWN0dWFsLmNvbnRhaW5zKHNbMV0pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSghYWN0dWFsLmNvbnRhaW5zKHNbMl0pKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXlQcm92aWRlci5yZW1vdmVTZXJ2aWNlKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaXRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorICAgIC8vIEVORCBhbmRyb2lkLWFkZGVkCisKKyAgICAvLyBCRUdJTiBhbmRyb2lkLWFkZGVkCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdExvYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSh3cml0ZVByb3BlcnRpZXMoKSk7CisgICAgICAgIE15UHJvdmlkZXIgbXlQcm92aWRlciA9IG5ldyBNeVByb3ZpZGVyKCJuYW1lIiwgMSwgImluZm8iKTsKKyAgICAgICAgbXlQcm92aWRlci5sb2FkKGlzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXN0cy5zZWN1cml0eSIsIG15UHJvdmlkZXIuZ2V0KCJ0ZXN0LnBrZyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJVbml0IFRlc3RzIiwgbXlQcm92aWRlci5nZXQoInRlc3QucHJvaiIpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChteVByb3ZpZGVyLmdldCgiI2NvbW1lbnRlZC5lbnRyeSIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoImluZm8iLCBteVByb3ZpZGVyLmdldCgiUHJvdmlkZXIuaWQgaW5mbyIpKTsKKyAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9IG15UHJvdmlkZXIuZ2V0Q2xhc3MoKS50b1N0cmluZygpOworICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgY2xhc3NOYW1lLnN1YnN0cmluZygiY2xhc3MgIi5sZW5ndGgoKSwgY2xhc3NOYW1lLmxlbmd0aCgpKSwKKyAgICAgICAgICAgICAgICBteVByb3ZpZGVyLmdldCgiUHJvdmlkZXIuaWQgY2xhc3NOYW1lIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEuMCIsIG15UHJvdmlkZXIuZ2V0KCJQcm92aWRlci5pZCB2ZXJzaW9uIikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBteVByb3ZpZGVyLmxvYWQoKElucHV0U3RyZWFtKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisgICAgLy8gRU5EIGFuZHJvaWQtYWRkZWQKKworICAgIC8vIEJFR0lOIGFuZHJvaWQtYWRkZWQKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0TG9hZDIoKSB7CisgICAgICAgIGNsYXNzIFRlc3RJbnB1dFN0cmVhbSBleHRlbmRzIElucHV0U3RyZWFtIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIE15UHJvdmlkZXIgcCA9IG5ldyBNeVByb3ZpZGVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwLmxvYWQobmV3IFRlc3RJbnB1dFN0cmVhbSgpKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIElPRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisgICAgLy8gRU5EIGFuZHJvaWQtYWRkZWQKKworICAgIC8vIEJFR0lOIGFuZHJvaWQtYWRkZWQKKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIHdyaXRlUHJvcGVydGllcygpIHsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIFByaW50U3RyZWFtIHBzID0gbmV3IFByaW50U3RyZWFtKGJvdXQpOworICAgICAgICBwcy5wcmludGxuKCIjY29tbWVudGVkLmVudHJ5PUJvZ3VzIik7CisgICAgICAgIHBzLnByaW50bG4oInRlc3QucGtnPXRlc3RzLnNlY3VyaXR5Iik7CisgICAgICAgIHBzLnByaW50bG4oInRlc3QucHJvaj1Vbml0IFRlc3RzIik7CisgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgIHJldHVybiBib3V0LnRvQnl0ZUFycmF5KCk7CisgICAgfQorICAgIC8vIEVORCBhbmRyb2lkLWFkZGVkCisKKyAgICAvLyBCRUdJTiBhbmRyb2lkLWFkZGVkCisgICAgc3RhdGljIGNsYXNzIFRlc3RTZWN1cml0eU1hbmFnZXIgZXh0ZW5kcyBTZWN1cml0eU1hbmFnZXIgeworICAgICAgICBib29sZWFuIGNhbGxlZCA9IGZhbHNlOworICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBwZXJtaXNzaW9uTmFtZTsKKworICAgICAgICBwdWJsaWMgVGVzdFNlY3VyaXR5TWFuYWdlcihTdHJpbmcgcGVybWlzc2lvbk5hbWUpIHsKKyAgICAgICAgICAgIHRoaXMucGVybWlzc2lvbk5hbWUgPSBwZXJtaXNzaW9uTmFtZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjaGVja1Blcm1pc3Npb24oUGVybWlzc2lvbiBwZXJtaXNzaW9uKSB7CisgICAgICAgICAgICBpZiAocGVybWlzc2lvbiBpbnN0YW5jZW9mIFNlY3VyaXR5UGVybWlzc2lvbikgeworICAgICAgICAgICAgICAgIGlmIChwZXJtaXNzaW9uTmFtZS5lcXVhbHMocGVybWlzc2lvbi5nZXROYW1lKCkpKSB7CisgICAgICAgICAgICAgICAgICAgIGNhbGxlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIC8vIEVORCBhbmRyb2lkLWFkZGVkCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvUHVibGljS2V5VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1B1YmxpY0tleVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NmQwMDNkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1B1YmxpY0tleVRlc3QuamF2YQpAQCAtMCwwICsxLDU4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+UHVibGljS2V5PC9jb2RlPiBjbGFzcyBmaWVsZAorICoKKyAqLworcHVibGljIGNsYXNzIFB1YmxpY0tleVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5zZXJpYWxWZXJzaW9uVUlEPC9jb2RlPiBmaWVsZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RGaWVsZCgpIHsKKyAgICAgICAgY2hlY2tQdWJsaWNLZXkgY1BLID0gbmV3IGNoZWNrUHVibGljS2V5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHNlcmlhbFZlcnNpb25VSUQiLCBjUEsuZ2V0U2VyVmVyVUlEKCksIC8vUHVibGljS2V5LnNlcmlhbFZlcnNpb25VSUQsCisgICAgICAgICAgICAgICAgNzE4NzM5MjQ3MTE1OTE1MTA3MkwpOworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBjaGVja1B1YmxpY0tleSBpbXBsZW1lbnRzIFB1YmxpY0tleSB7CisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICAgICAgcmV0dXJuICJQdWJsaWNLZXkiOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgcmV0dXJuICJGb3JtYXQiOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVswXTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgbG9uZyBnZXRTZXJWZXJVSUQoKSB7CisgICAgICAgICAgICByZXR1cm4gc2VyaWFsVmVyc2lvblVJRDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9TZWN1cmVSYW5kb20yVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1NlY3VyZVJhbmRvbTJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2YwMzBjNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9TZWN1cmVSYW5kb20yVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDMyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbVNwaTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIFNlY3VyZVJhbmRvbTJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIFNFRURfQllURVMgPSB7IChieXRlKSAzMywgKGJ5dGUpIDE1LCAoYnl0ZSkgLTMsCisgICAgICAgICAgICAoYnl0ZSkgMjIsIChieXRlKSA3NywgKGJ5dGUpIC0xNiwgKGJ5dGUpIC0zMywgKGJ5dGUpIDU2IH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0VFRF9TSVpFID0gNTM5OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBTRUVEX1ZBTFVFID0gNTMzNTQ4Njc1OUw7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UHJvdmlkZXIoKSB7CisgICAgICAgIFNlY3VyZVJhbmRvbSBzcjEgPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoc3IxLmdldFByb3ZpZGVyKCkpOworCisgICAgICAgIFNlY3VyZVJhbmRvbSBzcjIgPSBuZXcgU2VjdXJlUmFuZG9tKFNFRURfQllURVMpOworICAgICAgICBhc3NlcnROb3ROdWxsKHNyMi5nZXRQcm92aWRlcigpKTsKKworICAgICAgICBNeVByb3ZpZGVyIHAgPSBuZXcgTXlQcm92aWRlcigpOworCisgICAgICAgIE15U2VjdXJlUmFuZG9tIHNyMyA9IG5ldyBNeVNlY3VyZVJhbmRvbShuZXcgTXlTZWN1cmVSYW5kb21TcGkoKSwgcCk7CisgICAgICAgIGFzc2VydEVxdWFscyhwLCBzcjMuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTZWN1cmVSYW5kb20gcmFuZG9tID0gU2VjdXJlUmFuZG9tLmdldEluc3RhbmNlKCJTSEExUFJORyIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChyYW5kb20uZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb20jU2VjdXJlUmFuZG9tKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb20oKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFNlY3VyZVJhbmRvbSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiQ29uc3RydWN0b3IgdGhyZXcgZXhjZXB0aW9uIDogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb20jU2VjdXJlUmFuZG9tKGJ5dGVbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yJEIoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbShieXRlIFtdKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFNlY3VyZVJhbmRvbShTRUVEX0JZVEVTKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkNvbnN0cnVjdG9yIHRocmV3IGV4Y2VwdGlvbiA6ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2VjdXJlUmFuZG9tKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24gZm9yIE5VTEwgcGFyYW1ldGVyIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tI1NlY3VyZVJhbmRvbShqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbVNwaSwgamF2YS5zZWN1cml0eS5Qcm92aWRlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfc2VjdXJpdHlfU2VjdXJlUmFuZG9tU3BpX2phdmFfc2VjdXJpdHlfUHJvdmlkZXIoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgTXlTZWN1cmVSYW5kb20obnVsbCwgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJDb25zdHJ1Y3RvciB0aHJldyBleGNlcHRpb24gOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTXlQcm92aWRlciBwID0gbmV3IE15UHJvdmlkZXIoKTsKKyAgICAgICAgICAgIE15U2VjdXJlUmFuZG9tIHNyID0gbmV3IE15U2VjdXJlUmFuZG9tKG5ldyBNeVNlY3VyZVJhbmRvbVNwaSgpLCBwKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygidW5rbm93biIsIHNyLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhwLCBzci5nZXRQcm92aWRlcigpKTsKKworICAgICAgICAgICAgc3IgPSBuZXcgTXlTZWN1cmVSYW5kb20obmV3IE15U2VjdXJlUmFuZG9tU3BpKCksIG51bGwpOworICAgICAgICAgICAgc3IgPSBuZXcgTXlTZWN1cmVSYW5kb20obnVsbCwgcCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJDb25zdHJ1Y3RvciB0aHJldyBleGNlcHRpb24gOiAiICsgZSk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tI2dlbmVyYXRlU2VlZChpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZW5lcmF0ZVNlZWRJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYnl0ZSBbXSBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbS5nZW5lcmF0ZVNlZWQoaW50KQorICAgICAgICBieXRlW10gc2VlZCA9IG5ldyBTZWN1cmVSYW5kb20oKS5nZW5lcmF0ZVNlZWQoU0VFRF9TSVpFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzZWVkIGhhcyBpbmNvcnJlY3Qgc2l6ZSIsIFNFRURfU0laRSwgc2VlZC5sZW5ndGgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2VjdXJlUmFuZG9tKCkuZ2VuZXJhdGVTZWVkKC00Mik7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBhbiBleGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgIH0KKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbSNnZXRJbnN0YW5jZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tCisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tLmdldEluc3RhbmNlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTZWN1cmVSYW5kb20uZ2V0SW5zdGFuY2UoIlNIQTFQUk5HIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJnZXRJbnN0YW5jZSBkaWQgbm90IGZpbmQgYSBTSEExUFJORyBhbGdvcml0aG0iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTZWN1cmVSYW5kb20uZ2V0SW5zdGFuY2UoIk1EMiIpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gZm9yIE1EMiBhbGdvcml0aG0iKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tI2dldEluc3RhbmNlKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbQorICAgICAgICAvLyBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbS5nZXRJbnN0YW5jZShqYXZhLmxhbmcuU3RyaW5nLAorICAgICAgICAvLyBqYXZhLmxhbmcuU3RyaW5nKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgUHJvdmlkZXJbXSBwcm92aWRlcnMgPSBTZWN1cml0eQorICAgICAgICAgICAgICAgICAgICAuZ2V0UHJvdmlkZXJzKCJTZWN1cmVSYW5kb20uU0hBMVBSTkciKTsKKyAgICAgICAgICAgIGlmIChwcm92aWRlcnMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdmlkZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIFNlY3VyZVJhbmRvbQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZSgiU0hBMVBSTkciLCBwcm92aWRlcnNbaV0uZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICB9Ly8gZW5kIGZvcgorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJObyBwcm92aWRlcnMgc3VwcG9ydCBTSEExUFJORyIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiZ2V0SW5zdGFuY2UgZGlkIG5vdCBmaW5kIGEgU0hBMVBSTkcgYWxnb3JpdGhtIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoImdldEluc3RhbmNlIGRpZCBub3QgZmluZCB0aGUgcHJvdmlkZXIgZm9yIFNIQTFQUk5HIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbSNnZXRTZWVkKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFNlZWRJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYnl0ZSBbXSBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbS5nZXRTZWVkKGludCkKKyAgICAgICAgYnl0ZVtdIHNlZWQgPSBTZWN1cmVSYW5kb20uZ2V0U2VlZChTRUVEX1NJWkUpOworICAgICAgICBhc3NlcnRFcXVhbHMoInNlZWQgaGFzIGluY29ycmVjdCBzaXplIiwgU0VFRF9TSVpFLCBzZWVkLmxlbmd0aCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTZWN1cmVSYW5kb20oKS5nZXRTZWVkKC00Mik7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBhbiBleGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbSNuZXh0Qnl0ZXMoYnl0ZVtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfbmV4dEJ5dGVzJEIoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tLm5leHRCeXRlcyhieXRlIFtdKQorICAgICAgICBieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVszMTNdOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFNlY3VyZVJhbmRvbSgpLm5leHRCeXRlcyhieXRlcyk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJuZXh0IGJ5dGVzIG5vdCBvayA6ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2VjdXJlUmFuZG9tKCkubmV4dEJ5dGVzKG51bGwpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb20jc2V0U2VlZChieXRlW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRTZWVkJEIoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tLnNldFNlZWQoYnl0ZSBbXSkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTZWN1cmVSYW5kb20oKS5zZXRTZWVkKFNFRURfQllURVMpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgic2VlZCBnZW5lcmF0aW9uIHdpdGggYnl0ZXMgZmFpbGVkIDogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTZWN1cmVSYW5kb20oKS5zZXRTZWVkKG51bGwpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb20jc2V0U2VlZChsb25nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0U2VlZEooKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tLnNldFNlZWQobG9uZykKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTZWN1cmVSYW5kb20oKS5zZXRTZWVkKFNFRURfVkFMVUUpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgic2VlZCBnZW5lcmF0aW9uIHdpdGggbG9uZyBmYWlsZWQgOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFNlY3VyZVJhbmRvbSgpLnNldFNlZWQoLTEpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tI2dldEFsZ29yaXRobSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBbGdvcml0aG0oKSB7CisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktNzUwCisKKyAgICAgICAgU2VjdXJlUmFuZG9tU3BpIHNwaSA9IG5ldyBTZWN1cmVSYW5kb21TcGkoKSB7CisKKyAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVNldFNlZWQoYnl0ZVtdIGFyZykgeworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVOZXh0Qnl0ZXMoYnl0ZVtdIGFyZykgeworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuZ2luZUdlbmVyYXRlU2VlZChpbnQgYXJnKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgU2VjdXJlUmFuZG9tIHNyID0gbmV3IFNlY3VyZVJhbmRvbShzcGksIG51bGwpIHsKKyAgICAgICAgfTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoInVua25vd24iLCBzci5nZXRBbGdvcml0aG0oKSk7CisKKworICAgIH0KKworICAgIC8vIFJlZ3Jlc3Npb24gVGVzdCBmb3IgSEFSTU9OWS0zNTUyLgorICAgIHB1YmxpYyB2b2lkIHRlc3RfbmV4dEooKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTXlTZWN1cmVSYW5kb20gbXlTZWN1cmVSYW5kb20gPSBuZXcgTXlTZWN1cmVSYW5kb20oCisgICAgICAgICAgICAgICAgbmV3IE15U2VjdXJlUmFuZG9tU3BpKCksIG51bGwpOworICAgICAgICBpbnQgbnVtQml0cyA9IDI5OworICAgICAgICBpbnQgcmFuZG9tID0gbXlTZWN1cmVSYW5kb20uZ2V0TmV4dChudW1CaXRzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bUJpdHMsIEludGVnZXIuYml0Q291bnQocmFuZG9tKSk7CisKKyAgICAgICAgbnVtQml0cyA9IDA7CisgICAgICAgIHJhbmRvbSA9IG15U2VjdXJlUmFuZG9tLmdldE5leHQobnVtQml0cyk7CisgICAgICAgIGFzc2VydEVxdWFscyhudW1CaXRzLCBJbnRlZ2VyLmJpdENvdW50KHJhbmRvbSkpOworCisgICAgICAgIG51bUJpdHMgPSA0MDsKKyAgICAgICAgcmFuZG9tID0gbXlTZWN1cmVSYW5kb20uZ2V0TmV4dChudW1CaXRzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMyLCBJbnRlZ2VyLmJpdENvdW50KHJhbmRvbSkpOworCisgICAgICAgIG51bUJpdHMgPSAtMTsKKyAgICAgICAgcmFuZG9tID0gbXlTZWN1cmVSYW5kb20uZ2V0TmV4dChudW1CaXRzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIEludGVnZXIuYml0Q291bnQocmFuZG9tKSk7CisKKworICAgIH0KKworICAgIC8qKgorICAgICAqIFR3byB7QGxpbmsgU2VjdXJlUmFuZG9tfSBvYmplY3RzLCBjcmVhdGVkIHdpdGgKKyAgICAgKiB7QGxpbmsgU2VjdXJlUmFuZG9tI2dldEluc3RhbmNlKFN0cmluZyl9IGFuZCBpbml0aWFsaXplZCBiZWZvcmUgdXNlCisgICAgICogd2l0aCB0aGUgc2FtZSBzZWVkLCBzaG91bGQgcmV0dXJuIHRoZSBzYW1lIHJlc3VsdHMuPHA+CisgICAgICoKKyAgICAgKiBJbiB0aGUgZnV0dXJlLCBpdCBtYXkgc2Vuc2UgdG8gZGlzYWxsb3cgc2VlZGluZyB7QGNvZGUgU2VjdXJlUmFuZG9tfSwKKyAgICAgKiBhcyBpdCB0ZW5kcyB0byBiZSBlcnJvciBwcm9uZSBhbmQgb3BlbiB1cCBzZWN1cml0eSBob2xlcy4KKyAgICAgKiBTZWUge0BsaW5rIFNlY3VyZVJhbmRvbX0gZm9yIG1vcmUgZGV0YWlscyBhYm91dCBpbnNlY3VyZSBzZWVkaW5nLgorICAgICAqCisgICAgICogQHNlZSAjdGVzdFNhbWVTZWVkR2VuZXJhdGVzU2FtZVJlc3VsdHNXaGVuQ29uc3RydWN0b3JJc1VzZWQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTYW1lU2VlZEdlbmVyYXRlc1NhbWVSZXN1bHRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBzZWVkMSA9IHsgJ2EnLCAnYicsICdjJyB9OworICAgICAgICBTZWN1cmVSYW5kb20gc3IxID0gU2VjdXJlUmFuZG9tLmdldEluc3RhbmNlKCJTSEExUFJORyIpOworICAgICAgICBzcjEuc2V0U2VlZChzZWVkMSk7CisKKyAgICAgICAgYnl0ZVtdIHNlZWQyID0geyAnYScsICdiJywgJ2MnIH07CisgICAgICAgIFNlY3VyZVJhbmRvbSBzcjIgPSBTZWN1cmVSYW5kb20uZ2V0SW5zdGFuY2UoIlNIQTFQUk5HIik7CisgICAgICAgIHNyMi5zZXRTZWVkKHNlZWQyKTsKKworICAgICAgICBhc3NlcnRUcnVlKHNyMS5uZXh0TG9uZygpID09IHNyMi5uZXh0TG9uZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTYW1lIHRlc3RzIGFzIHtAbGluayAjdGVzdFNhbWVTZWVkR2VuZXJhdGVzU2FtZVJlc3VsdHMoKX0sIGV4Y2VwdAorICAgICAqIGhlcmUgd2UgdXNlIHRoZSBjb25zdHJ1Y3Rvciwgbm90IHtAbGluayBTZWN1cmVSYW5kb20jZ2V0SW5zdGFuY2UoU3RyaW5nKX0uCisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgQW5kcm9pZCBiZWhhdmVzIGRpZmZlcmVudGx5IHRoYW4gdGhlIHJlZmVyZW5jZSBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKiBUaGlzIHRlc3QgZmFpbHMgb24gdGhlIHJlZmVyZW5jZSBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKgorICAgICAqIEluIHRoZSBmdXR1cmUsIGl0IG1heSBtYWtlIHNlbnNlIHRvIGNoYW5nZSBvdXIgaW1wbGVtZW50YXRpb24gdG8KKyAgICAgKiBtYXRjaCB0aGUgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uLiAgSXQgbWF5IGFsc28gbWFrZSBzZW5zZSB0bworICAgICAqIGRpc2FsbG93IHNlZWRpbmcge0Bjb2RlIFNlY3VyZVJhbmRvbX0gY29tcGxldGVseSwgYXMgaXQgdGVuZHMgdG8KKyAgICAgKiBiZSBlcnJvciBwcm9uZSBhbmQgb3BlbiB1cCBzZWN1cml0eSBob2xlcy4gIFNlZSB7QGxpbmsgU2VjdXJlUmFuZG9tfQorICAgICAqIGZvciBtb3JlIGRldGFpbHMgYWJvdXQgaW5zZWN1cmUgc2VlZGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2FtZVNlZWRHZW5lcmF0ZXNTYW1lUmVzdWx0c1doZW5Db25zdHJ1Y3RvcklzVXNlZCgpIHsKKyAgICAgICAgYnl0ZVtdIHNlZWQxID0geyAnYScsICdiJywgJ2MnIH07CisgICAgICAgIFNlY3VyZVJhbmRvbSBzcjEgPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIHNyMS5zZXRTZWVkKHNlZWQxKTsKKworICAgICAgICBieXRlW10gc2VlZDIgPSB7ICdhJywgJ2InLCAnYycgfTsKKyAgICAgICAgU2VjdXJlUmFuZG9tIHNyMiA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgc3IyLnNldFNlZWQoc2VlZDIpOworCisgICAgICAgIGFzc2VydFRydWUoc3IxLm5leHRMb25nKCkgPT0gc3IyLm5leHRMb25nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFzc2VydCB0aGF0IGEge0BsaW5rIFNlY3VyZVJhbmRvbX0gb2JqZWN0IHNlZWRlZCBmcm9tIGEgY29uc3RhbnQKKyAgICAgKiBzZWVkIGFsd2F5cyByZXR1cm5zIHRoZSBzYW1lIHZhbHVlLCBldmVuIGFjcm9zcyBWTSByZXN0YXJ0cy4KKyAgICAgKgorICAgICAqIEZ1dHVyZSB2ZXJzaW9ucyBvZiBBbmRyb2lkIG1heSBjaGFuZ2UgdGhlIGltcGxlbWVudGF0aW9uIG9mCisgICAgICogU0hBMVBSTkcsIHNvIHVzZXJzIG9mIHtAY29kZSBTZWN1cmVSYW5kb219IHNob3VsZCBub3QgYXNzdW1lCisgICAgICogdGhlIHNhbWUgc2VlZCB3aWxsIGFsd2F5cyBwcm9kdWNlIHRoZSBzYW1lIHZhbHVlLiAgVGhpcyB0ZXN0CisgICAgICogaXMgbm90IGEgZ3VhcmFudGVlIG9mIGZ1dHVyZSBjb21wYXRpYmlsaXR5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RBbHdheXNTYW1lVmFsdWVXaXRoU2FtZVNlZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIHNlZWQxID0geyAnYScsICdiJywgJ2MnIH07CisgICAgICAgIFNlY3VyZVJhbmRvbSBzcjEgPSBTZWN1cmVSYW5kb20uZ2V0SW5zdGFuY2UoIlNIQTFQUk5HIik7CisgICAgICAgIHNyMS5zZXRTZWVkKHNlZWQxKTsKKworICAgICAgICAvLyBUaGlzIGxvbmcgdmFsdWUgaGFzIG5vIHNwZWNpYWwgbWVhbmluZyBhbmQgbWF5IGNoYW5nZSBpbiB0aGUgZnV0dXJlLgorICAgICAgICBhc3NlcnRFcXVhbHMoNjE4MDY5MzY5MTI2NDg3MTUwMGwsIHNyMS5uZXh0TG9uZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWYWxpZGF0ZSB0aGF0IGNhbGxpbmcge0BsaW5rIFNlY3VyZVJhbmRvbSNzZXRTZWVkfSA8Yj5hZnRlcjwvYj4gZ2VuZXJhdGluZworICAgICAqIGEgcmFuZG9tIG51bWJlciBjb21wbGltZW50cywgYnV0IGRvZXNuJ3QgcmVwbGFjZSwgdGhlIGV4aXN0aW5nIHNlZWQuCisgICAgICoKKyAgICAgKiBDb21wYXJlIHRoaXMgdGVzdCB0byB7QGxpbmsgI3Rlc3RBbHdheXNTYW1lVmFsdWVXaXRoU2FtZVNlZWQoKX0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNldFNlZWRDb21wbGltZW50c0FmdGVyRmlyc3RSYW5kb21OdW1iZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIHNlZWQxID0geyAnYScsICdiJywgJ2MnIH07CisgICAgICAgIFNlY3VyZVJhbmRvbSBzcjEgPSBTZWN1cmVSYW5kb20uZ2V0SW5zdGFuY2UoIlNIQTFQUk5HIik7CisgICAgICAgIHNyMS5uZXh0SW50KCk7CisgICAgICAgIHNyMS5zZXRTZWVkKHNlZWQxKTsKKworICAgICAgICAvLyBUaGlzIGxvbmcgdmFsdWUgaGFzIG5vIHNwZWNpYWwgbWVhbmluZworICAgICAgICBhc3NlcnRUcnVlKDYxODA2OTM2OTEyNjQ4NzE1MDBsICE9IHNyMS5uZXh0TG9uZygpKTsKKyAgICB9CisKKyAgICBjbGFzcyBNeVNlY3VyZVJhbmRvbSBleHRlbmRzIFNlY3VyZVJhbmRvbSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgICAgIHB1YmxpYyBNeVNlY3VyZVJhbmRvbShTZWN1cmVSYW5kb21TcGkgc2VjdXJlUmFuZG9tU3BpLCBQcm92aWRlciBwcm92aWRlcikgeworICAgICAgICAgICAgc3VwZXIoc2VjdXJlUmFuZG9tU3BpLCBwcm92aWRlcik7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldE5leHQoaW50IG51bUJpdHMpIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5uZXh0KG51bUJpdHMpOworICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgTXlTZWN1cmVSYW5kb21TcGkgZXh0ZW5kcyBTZWN1cmVSYW5kb21TcGkgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVHZW5lcmF0ZVNlZWQoaW50IGFyZzApIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZU5leHRCeXRlcyhieXRlW10gYnl0ZXMpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBieXRlc1tpXSA9IChieXRlKSAweEZGOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVNldFNlZWQoYnl0ZVtdIGFyZzApIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIE15UHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlciB7CisKKyAgICAgICAgTXlQcm92aWRlcigpIHsKKyAgICAgICAgICAgIHN1cGVyKCJNeVByb3ZpZGVyIiwgMS4wLCAiUHJvdmlkZXIgZm9yIHRlc3RpbmciKTsKKyAgICAgICAgICAgIHB1dCgiTWVzc2FnZURpZ2VzdC5TSEEtMSIsICJTb21lQ2xhc3NOYW1lIik7CisgICAgICAgICAgICBwdXQoIk1lc3NhZ2VEaWdlc3QuYWJjIiwgIlNvbWVDbGFzc05hbWUiKTsKKyAgICAgICAgICAgIHB1dCgiQWxnLkFsaWFzLk1lc3NhZ2VEaWdlc3QuU0hBMSIsICJTSEEtMSIpOworICAgICAgICB9CisKKyAgICAgICAgTXlQcm92aWRlcihTdHJpbmcgbmFtZSwgZG91YmxlIHZlcnNpb24sIFN0cmluZyBpbmZvKSB7CisgICAgICAgICAgICBzdXBlcihuYW1lLCB2ZXJzaW9uLCBpbmZvKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHB1dFNlcnZpY2UoUHJvdmlkZXIuU2VydmljZSBzKSB7CisgICAgICAgICAgICBzdXBlci5wdXRTZXJ2aWNlKHMpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlU2VydmljZShQcm92aWRlci5TZXJ2aWNlIHMpIHsKKyAgICAgICAgICAgIHN1cGVyLnJlbW92ZVNlcnZpY2Uocyk7CisgICAgICAgIH0KKworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9TZWN1cmVSYW5kb21TcGlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvU2VjdXJlUmFuZG9tU3BpVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRkMGYzZDAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvU2VjdXJlUmFuZG9tU3BpVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbVNwaTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlNlY3VyZVJhbmRvbVNwaTwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzCisgKiBhbmQgbWV0aG9kcy4KKyAqLworcHVibGljIGNsYXNzIFNlY3VyZVJhbmRvbVNwaVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5TZWN1cmVSYW5kb21TcGk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIFNlY3VyZVJhbmRvbVNwaQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZWN1cmVSYW5kb21TcGkoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNeVNlY3VyZVJhbmRvbVNwaSBzcnMgPSBuZXcgTXlTZWN1cmVSYW5kb21TcGkoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoc3JzIGluc3RhbmNlb2YgU2VjdXJlUmFuZG9tU3BpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTXlTZWN1cmVSYW5kb21TcGkgc3JzID0gbmV3IE15U2VjdXJlUmFuZG9tU3BpKCk7CisgICAgICAgICAgICBzcnMuZW5naW5lR2VuZXJhdGVTZWVkKDEwKTsKKyAgICAgICAgICAgIHNycy5lbmdpbmVOZXh0Qnl0ZXMobmV3IGJ5dGVbMTBdKTsKKyAgICAgICAgICAgIHNycy5lbmdpbmVTZXRTZWVkKG5ldyBieXRlWzNdKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgTXlTZWN1cmVSYW5kb21TcGkgZXh0ZW5kcyBTZWN1cmVSYW5kb21TcGkgeworICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVTZXRTZWVkKGJ5dGVbXSBzZWVkKSB7fQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVOZXh0Qnl0ZXMoYnl0ZVtdIGJ5dGVzKSB7fQorICAgICAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuZ2luZUdlbmVyYXRlU2VlZChpbnQgbnVtQnl0ZXMpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1NlY3VyaXR5MlRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9TZWN1cml0eTJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDlmNGRkNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9TZWN1cml0eTJUZXN0LmphdmEKQEAgLTAsMCArMSwzMzYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1Byb3ZpZGVyVHJ1c3Q7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1Rlc3RQcm92aWRlcjsKKworcHVibGljIGNsYXNzIFNlY3VyaXR5MlRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TZWN1cml0eSNnZXRQcm92aWRlcnMoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFByb3ZpZGVyc0xqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZAorICAgICAgICAvLyBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5LmdldFByb3ZpZGVycyhqYXZhLmxhbmcuU3RyaW5nKQorCisgICAgICAgIEhhc2h0YWJsZTxTdHJpbmcsIEludGVnZXI+IGFsbFN1cHBvcnRlZCA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBJbnRlZ2VyPigpOworICAgICAgICBQcm92aWRlcltdIGFsbFByb3ZpZGVycyA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygpOworCisgICAgICAgIC8vIEFkZCBhbGwgbm9uLWFsaWFzIGVudHJpZXMgdG8gYWxsU3VwcG9ydGVkCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxsUHJvdmlkZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBQcm92aWRlciBwcm92aWRlciA9IGFsbFByb3ZpZGVyc1tpXTsKKyAgICAgICAgICAgIEl0ZXJhdG9yIGl0ID0gcHJvdmlkZXIuZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIE1hcC5FbnRyeSBlbnRyeSA9IChNYXAuRW50cnkpIGl0Lm5leHQoKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcga2V5ID0gKFN0cmluZykgZW50cnkuZ2V0S2V5KCk7CisgICAgICAgICAgICAgICAgLy8gTm8gYWxpYXNlcyBhbmQgbm8gcHJvdmlkZXIgZGF0YQorICAgICAgICAgICAgICAgIGlmICghaXNBbGlhcyhrZXkpICYmICFpc1Byb3ZpZGVyRGF0YShrZXkpKSB7CisgICAgICAgICAgICAgICAgICAgIGFkZE9ySW5jcmVtZW50VGFibGUoYWxsU3VwcG9ydGVkLCBrZXkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0vLyBlbmQgd2hpbGUgbW9yZSBlbnRyaWVzCisgICAgICAgIH0vLyBlbmQgZm9yIGFsbCBwcm92aWRlcnMKKworICAgICAgICAvLyBOb3cgd2FsayB0aHJvdWdoIGFsaWFzZXMuIElmIGFuIGFsaWFzIGhhcyBhY3R1YWxseSBiZWVuIGFkZGVkCisgICAgICAgIC8vIHRvIHRoZSBhbGxTdXBwb3J0ZWQgdGFibGUgdGhlbiBpbmNyZW1lbnQgdGhlIGNvdW50IG9mIHRoZQorICAgICAgICAvLyBlbnRyeSB0aGF0IGlzIGJlaW5nIGFsaWFzZWQuCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxsUHJvdmlkZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBQcm92aWRlciBwcm92aWRlciA9IGFsbFByb3ZpZGVyc1tpXTsKKyAgICAgICAgICAgIEl0ZXJhdG9yIGl0ID0gcHJvdmlkZXIuZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgICAgIE1hcC5FbnRyeSBlbnRyeSA9IChNYXAuRW50cnkpIGl0Lm5leHQoKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcga2V5ID0gKFN0cmluZykgZW50cnkuZ2V0S2V5KCk7CisgICAgICAgICAgICAgICAgaWYgKGlzQWxpYXMoa2V5KSkgeworICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYWxpYXNWYWwgPSBrZXkuc3Vic3RyaW5nKCJBTEcuQUxJQVMuIi5sZW5ndGgoKSk7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhbGlhc0tleSA9IGFsaWFzVmFsLnN1YnN0cmluZygwLCBhbGlhc1ZhbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKCIuIikgKyAxKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gU2tpcCBvdmVyIG5vbnNlbnNlIGFsaWFzIGRlY2xhcmF0aW9ucyB3aGVyZSBhbGlhcyBhbmQKKyAgICAgICAgICAgICAgICAgICAgLy8gYWxpYXNlZCBhcmUgaWRlbnRpY2FsLiBTdWNoIGVudHJpZXMgY2FuIG9jY3VyLgorICAgICAgICAgICAgICAgICAgICBpZiAoIWFsaWFzVmFsLmVxdWFscyhhbGlhc0tleSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhhcyBhIHJlYWwgZW50cnkgYmVlbiBhZGRlZCBmb3IgYWxpYXNWYWx1ZSA/CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWxsU3VwcG9ydGVkLmNvbnRhaW5zS2V5KGFsaWFzVmFsKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZCAxIHRvIHRoZSBwcm92aWRlciBjb3VudCBvZiB0aGUgdGhpbmcgYmVpbmcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbGlhc2VkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkT3JJbmNyZW1lbnRUYWJsZShhbGxTdXBwb3J0ZWQsIGFsaWFzS2V5KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0vLyBlbmQgd2hpbGUgbW9yZSBlbnRyaWVzCisgICAgICAgIH0vLyBlbmQgZm9yIGFsbCBwcm92aWRlcnMKKworICAgICAgICBQcm92aWRlciBwcm92VGVzdFtdID0gbnVsbDsKKyAgICAgICAgSXRlcmF0b3IgaXQgPSBhbGxTdXBwb3J0ZWQua2V5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgU3RyaW5nIGZpbHRlclN0cmluZyA9IChTdHJpbmcpIGl0Lm5leHQoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHJvdlRlc3QgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoZmlsdGVyU3RyaW5nKTsKKyAgICAgICAgICAgICAgICBpbnQgZXhwZWN0ZWQgPSAoKEludGVnZXIpIGFsbFN1cHBvcnRlZC5nZXQoZmlsdGVyU3RyaW5nKSkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5pbnRWYWx1ZSgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgICJVbmV4cGVjdGVkIG51bWJlciBvZiBwcm92aWRlcnMgcmV0dXJuZWQgZm9yIGZpbHRlciAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZmlsdGVyU3RyaW5nLCBleHBlY3RlZCwgcHJvdlRlc3QubGVuZ3RoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIE5PIE9QCisgICAgICAgICAgICB9CisgICAgICAgIH0vLyBlbmQgd2hpbGUKKworICAgICAgICAvLyBleGNlcHRpb24KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByb3ZUZXN0ID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKCJTaWduYXR1cmUuU0hBMXdpdGhEU0EgOjUxMiIpOworICAgICAgICAgICAgZmFpbCgiSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIDxTaWduYXR1cmUuU0hBMXdpdGhEU0EgOjUxMj4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIGtleQorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNQcm92aWRlckRhdGEoU3RyaW5nIGtleSkgeworICAgICAgICByZXR1cm4ga2V5LnRvVXBwZXJDYXNlKCkuc3RhcnRzV2l0aCgiUFJPVklERVIuIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIGtleQorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNBbGlhcyhTdHJpbmcga2V5KSB7CisgICAgICAgIHJldHVybiBrZXkudG9VcHBlckNhc2UoKS5zdGFydHNXaXRoKCJBTEcuQUxJQVMuIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIHRhYmxlCisgICAgICogQHBhcmFtIGtleQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhZGRPckluY3JlbWVudFRhYmxlKEhhc2h0YWJsZTxTdHJpbmcsIEludGVnZXI+IHRhYmxlLCBTdHJpbmcga2V5KSB7CisgICAgICAgIGlmICh0YWJsZS5jb250YWluc0tleShrZXkpKSB7CisgICAgICAgICAgICBJbnRlZ2VyIGJlZm9yZSA9IChJbnRlZ2VyKSB0YWJsZS5nZXQoa2V5KTsKKyAgICAgICAgICAgIHRhYmxlLnB1dChrZXksIG5ldyBJbnRlZ2VyKGJlZm9yZS5pbnRWYWx1ZSgpICsgMSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGFibGUucHV0KGtleSwgbmV3IEludGVnZXIoMSkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIGZpbHRlck1hcAorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBnZXRQcm92aWRlcnNDb3VudChNYXAgZmlsdGVyTWFwKSB7CisgICAgICAgIGludCByZXN1bHQgPSAwOworICAgICAgICBQcm92aWRlcltdIGFsbFByb3ZpZGVycyA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygpOworCisgICAgICAgIC8vIGZvciBlYWNoIHByb3ZpZGVyCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxsUHJvdmlkZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBQcm92aWRlciBwcm92aWRlciA9IGFsbFByb3ZpZGVyc1tpXTsKKyAgICAgICAgICAgIFNldCBhbGxQcm92aWRlcktleXMgPSBwcm92aWRlci5rZXlTZXQoKTsKKyAgICAgICAgICAgIGJvb2xlYW4gbm9NYXRjaEZvdW5kRm9yRmlsdGVyRW50cnkgPSBmYWxzZTsKKworICAgICAgICAgICAgLy8gZm9yIGVhY2ggZmlsdGVyIGl0ZW0KKyAgICAgICAgICAgIFNldCBhbGxGaWx0ZXJLZXlzID0gZmlsdGVyTWFwLmtleVNldCgpOworICAgICAgICAgICAgSXRlcmF0b3IgZmtJdGVyID0gYWxsRmlsdGVyS2V5cy5pdGVyYXRvcigpOworICAgICAgICAgICAgd2hpbGUgKGZrSXRlci5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgZmlsdGVyU3RyaW5nID0gKChTdHJpbmcpIGZrSXRlci5uZXh0KCkpLnRyaW0oKTsKKworICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBhbnkgIj0iIGNoYXJhY3RlcnMgdGhhdCBtYXkgYmUgb24gdGhlIGVuZCBvZiB0aGUKKyAgICAgICAgICAgICAgICAvLyBtYXAga2V5cyAobm8sIEkgZG9uJ3Qga25vdyB3aHkgdGhleSBtaWdodCBiZSB0aGVyZSBlaXRoZXIKKyAgICAgICAgICAgICAgICAvLyBidXQgSSBoYXZlIHNlZW4gdGhlbSkKKyAgICAgICAgICAgICAgICBpZiAoZmlsdGVyU3RyaW5nLmVuZHNXaXRoKCI9IikpIHsKKyAgICAgICAgICAgICAgICAgICAgZmlsdGVyU3RyaW5nID0gZmlsdGVyU3RyaW5nLnN1YnN0cmluZygwLCBmaWx0ZXJTdHJpbmcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAubGVuZ3RoKCkgLSAxKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoZmlsdGVyU3RyaW5nICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlclN0cmluZy5pbmRleE9mKCIgIikgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIElzIHRoaXMgZmlsdGVyIHN0cmluZyBpbiB0aGUga2V5cyBvZiB0aGUKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGN1cnJlbnQgcHJvdmlkZXIgPworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhbGxQcm92aWRlcktleXMuY29udGFpbnMoZmlsdGVyU3RyaW5nKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgdGhlIGtleSBpcyBub3QgY29udGFpbmVkIGFzIGFuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWxpYXMuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhbGxQcm92aWRlcktleXMuY29udGFpbnMoIkFsZy5BbGlhcy4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGZpbHRlclN0cmluZykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9NYXRjaEZvdW5kRm9yRmlsdGVyRW50cnkgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsgLy8gb3V0IG9mIHdoaWxlIGxvb3AKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBoYW5kbGUgZmlsdGVyIHN0cmluZ3Mgd2l0aCBhdHRyaWJ1dGUgbmFtZXMKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhbGxQcm92aWRlcktleXMuY29udGFpbnMoZmlsdGVyU3RyaW5nKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERvZXMgdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWVzIG1hdGNoID8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZmlsdGVyVmFsID0gKFN0cmluZykgZmlsdGVyTWFwCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0KGZpbHRlclN0cmluZyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHByb3ZpZGVyVmFsID0gKFN0cmluZykgcHJvdmlkZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXQoZmlsdGVyU3RyaW5nKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJvdmlkZXJWYWwgPT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgIXByb3ZpZGVyVmFsLmVxdWFscyhmaWx0ZXJWYWwpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vTWF0Y2hGb3VuZEZvckZpbHRlckVudHJ5ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7IC8vIG91dCBvZiB3aGlsZSBsb29wCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfS8vIGVuZCBpZiBmaWx0ZXIgc3RyaW5nIHdpdGggbmFtZWQgYXR0cmlidXRlIGlzCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3VuZAorICAgICAgICAgICAgICAgICAgICB9Ly8gZW5kIGVsc2UKKyAgICAgICAgICAgICAgICB9Ly8gZW5kIGlmIG5vbi1udWxsIGtleQorICAgICAgICAgICAgfS8vIGVuZCB3aGlsZSB0aGVyZSBhcmUgbW9yZSBmaWx0ZXIgc3RyaW5ncyBmb3IgY3VycmVudCBtYXAKKworICAgICAgICAgICAgaWYgKCFub01hdGNoRm91bmRGb3JGaWx0ZXJFbnRyeSkgeworICAgICAgICAgICAgICAgIC8vIEN1cnJlbnQgcHJvdmlkZXIgaXMgYSBtYXRjaCBmb3IgdGhlIGZpbHRlck1hcAorICAgICAgICAgICAgICAgIHJlc3VsdCsrOworICAgICAgICAgICAgfQorICAgICAgICB9Ly8gZW5kIGZvciBlYWNoIHByb3ZpZGVyCisKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5I2dldFByb3ZpZGVycyhqYXZhLnV0aWwuTWFwKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UHJvdmlkZXJzTGphdmFfdXRpbF9NYXAoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkCisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKGphdmEudXRpbC5NYXApCisKKyAgICAgICAgTWFwPFN0cmluZywgU3RyaW5nPiBmaWx0ZXIgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgU3RyaW5nPigpOworICAgICAgICBmaWx0ZXIucHV0KCJLZXlTdG9yZS5CS1MiLCAiIik7CisgICAgICAgIGZpbHRlci5wdXQoIlNpZ25hdHVyZS5TSEExd2l0aERTQSIsICIiKTsKKyAgICAgICAgUHJvdmlkZXIgcHJvdlRlc3RbXSA9IFNlY3VyaXR5LmdldFByb3ZpZGVycyhmaWx0ZXIpOworICAgICAgICBpZiAocHJvdlRlc3QgPT0gbnVsbCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJGaWx0ZXIgOiA8S2V5U3RvcmUuQktTPiw8U2lnbmF0dXJlLlNIQTF3aXRoRFNBPiIsCisgICAgICAgICAgICAgICAgICAgIDAsIGdldFByb3ZpZGVyc0NvdW50KGZpbHRlcikpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJGaWx0ZXIgOiA8S2V5U3RvcmUuQktTPiw8U2lnbmF0dXJlLlNIQTF3aXRoRFNBPiIsCisgICAgICAgICAgICAgICAgICAgIGdldFByb3ZpZGVyc0NvdW50KGZpbHRlciksIHByb3ZUZXN0Lmxlbmd0aCk7CisgICAgICAgIH0KKworICAgICAgICBmaWx0ZXIgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgU3RyaW5nPigpOworICAgICAgICBmaWx0ZXIucHV0KCJNZXNzYWdlRGlnZXN0LlNIQS0zODQiLCAiIik7CisgICAgICAgIGZpbHRlci5wdXQoIkNlcnRpZmljYXRlRmFjdG9yeS5YLjUwOSIsICIiKTsKKyAgICAgICAgZmlsdGVyLnB1dCgiS2V5RmFjdG9yeS5SU0EiLCAiIik7CisgICAgICAgIHByb3ZUZXN0ID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKGZpbHRlcik7CisgICAgICAgIGlmIChwcm92VGVzdCA9PSBudWxsKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkZpbHRlciA6IDxNZXNzYWdlRGlnZXN0LlNIQS0zODQ+LDxDZXJ0aWZpY2F0ZUZhY3RvcnkuWC41MDk+LDxLZXlGYWN0b3J5LlJTQT4iLAorICAgICAgICAgICAgICAgICAgICAwLCBnZXRQcm92aWRlcnNDb3VudChmaWx0ZXIpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgIkZpbHRlciA6IDxNZXNzYWdlRGlnZXN0LlNIQS0zODQ+LDxDZXJ0aWZpY2F0ZUZhY3RvcnkuWC41MDk+LDxLZXlGYWN0b3J5LlJTQT4iLAorICAgICAgICAgICAgICAgICAgICBnZXRQcm92aWRlcnNDb3VudChmaWx0ZXIpLCBwcm92VGVzdC5sZW5ndGgpOworICAgICAgICB9CisKKyAgICAgICAgZmlsdGVyID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgZmlsdGVyLnB1dCgiTWVzc2FnZURpZ2VzdC5TSEExIiwgIiIpOworICAgICAgICBmaWx0ZXIucHV0KCJUcnVzdE1hbmFnZXJGYWN0b3J5Llg1MDkiLCAiIik7CisgICAgICAgIHByb3ZUZXN0ID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKGZpbHRlcik7CisgICAgICAgIGlmIChwcm92VGVzdCA9PSBudWxsKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkZpbHRlciA6IDxNZXNzYWdlRGlnZXN0LlNIQTE+PFRydXN0TWFuYWdlckZhY3RvcnkuWDUwOT4iLAorICAgICAgICAgICAgICAgICAgICAwLCBnZXRQcm92aWRlcnNDb3VudChmaWx0ZXIpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgIkZpbHRlciA6IDxNZXNzYWdlRGlnZXN0LlNIQTE+PFRydXN0TWFuYWdlckZhY3RvcnkuWDUwOT4iLAorICAgICAgICAgICAgICAgICAgICBnZXRQcm92aWRlcnNDb3VudChmaWx0ZXIpLCBwcm92VGVzdC5sZW5ndGgpOworICAgICAgICB9CisKKyAgICAgICAgZmlsdGVyID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgZmlsdGVyLnB1dCgiQ2VydGlmaWNhdGVGYWN0b3J5Llg1MDkiLCAiIik7CisgICAgICAgIHByb3ZUZXN0ID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKGZpbHRlcik7CisgICAgICAgIGlmIChwcm92VGVzdCA9PSBudWxsKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkZpbHRlciA6IDxDZXJ0aWZpY2F0ZUZhY3RvcnkuWDUwOT4iLAorICAgICAgICAgICAgICAgICAgICAwLCBnZXRQcm92aWRlcnNDb3VudChmaWx0ZXIpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiRmlsdGVyIDogPENlcnRpZmljYXRlRmFjdG9yeS5YNTA5PiIsCisgICAgICAgICAgICAgICAgICAgIGdldFByb3ZpZGVyc0NvdW50KGZpbHRlciksIHByb3ZUZXN0Lmxlbmd0aCk7CisgICAgICAgIH0KKworICAgICAgICBmaWx0ZXIgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgU3RyaW5nPigpOworICAgICAgICBmaWx0ZXIucHV0KCJQcm92aWRlci5pZCBuYW1lIiwgIkRSTENlcnRGYWN0b3J5Iik7CisgICAgICAgIHByb3ZUZXN0ID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKGZpbHRlcik7CisgICAgICAgIGFzc2VydE51bGwoIkZpbHRlciA6IDxQcm92aWRlci5pZCBuYW1lLCBEUkxDZXJ0RmFjdG9yeSA+IiwKKyAgICAgICAgICAgICAgICBwcm92VGVzdCk7CisKKyAgICAgICAgLy8gZXhjZXB0aW9uIC0gbm8gYXR0cmlidXRlIG5hbWUgYWZ0ZXIgdGhlIHNlcnZpY2UuYWxnb3JpdGhtIHlldCB3ZQorICAgICAgICAvLyBzdGlsbCBzdXBwbHkgYW4gZXhwZWN0ZWQgdmFsdWUuIFRoaXMgaXMgbm90IHZhbGlkLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgZmlsdGVyID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgICAgIGZpbHRlci5wdXQoIlNpZ25hdHVyZS5TSEExd2l0aERTQSIsICI1MTIiKTsKKyAgICAgICAgICAgIHByb3ZUZXN0ID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKGZpbHRlcik7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gPFNpZ25hdHVyZS5TSEExd2l0aERTQT48NTEyPiIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBleGNlcHRpb24gLSBzcGFjZSBjaGFyYWN0ZXIgaW4gdGhlIHNlcnZpY2UuYWxnb3JpdGhtIHBhaXIuIE5vdCB2YWxpZC4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbHRlciA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgICAgICAgICBmaWx0ZXIucHV0KCJTaWduYXR1cmUuIEtleVNpemUiLCAiNTEyIik7CisgICAgICAgICAgICBwcm92VGVzdCA9IFNlY3VyaXR5LmdldFByb3ZpZGVycyhmaWx0ZXIpOworICAgICAgICAgICAgZmFpbCgiSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIDxTaWduYXR1cmUuIEtleVNpemU+PDUxMj4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TZWN1cml0eSNyZW1vdmVQcm92aWRlcihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlUHJvdmlkZXJMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQKKyAgICAgICAgLy8gamF2YS5zZWN1cml0eS5TZWN1cml0eS5yZW1vdmVQcm92aWRlcihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAgICBQcm92aWRlciB0ZXN0ID0gbmV3IFN1cHBvcnRfVGVzdFByb3ZpZGVyKCk7CisgICAgICAgIFByb3ZpZGVyIGVudHJ1c3QgPSBuZXcgU3VwcG9ydF9Qcm92aWRlclRydXN0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBNYWtlIHN1cmUgcHJvdmlkZXIgbm90IGFscmVhZHkgbG9hZGVkLiBTaG91bGQgZG8gbm90aGluZworICAgICAgICAgICAgLy8gaWYgbm90IGFscmVhZHkgbG9hZGVkLgorICAgICAgICAgICAgU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIodGVzdC5nZXROYW1lKCkpOworCisgICAgICAgICAgICAvLyBOb3cgYWRkIGl0CisgICAgICAgICAgICBpbnQgYWRkUmVzdWx0ID0gU2VjdXJpdHkuYWRkUHJvdmlkZXIodGVzdCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gYWRkIHByb3ZpZGVyIiwgYWRkUmVzdWx0ICE9IC0xKTsKKworICAgICAgICAgICAgU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIodGVzdC5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgKKyAgICAgICAgICAgICAgICAgICAgInRoZSBwcm92aWRlciBUZXN0UHJvdmlkZXIgaXMgZm91bmQgYWZ0ZXIgaXQgd2FzIHJlbW92ZWQiLAorICAgICAgICAgICAgICAgICAgICBTZWN1cml0eS5nZXRQcm92aWRlcih0ZXN0LmdldE5hbWUoKSkpOworCisgICAgICAgICAgICAvLyBNYWtlIHN1cmUgZW50cnVzdCBwcm92aWRlciBub3QgYWxyZWFkeSBsb2FkZWQuIFNob3VsZCBkbyBub3RoaW5nCisgICAgICAgICAgICAvLyBpZiBub3QgYWxyZWFkeSBsb2FkZWQuCisgICAgICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcihlbnRydXN0LmdldE5hbWUoKSk7CisKKyAgICAgICAgICAgIC8vIE5vdyBhZGQgZW50cnVzdAorICAgICAgICAgICAgYWRkUmVzdWx0ID0gU2VjdXJpdHkuYWRkUHJvdmlkZXIoZW50cnVzdCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gYWRkIHByb3ZpZGVyIiwgYWRkUmVzdWx0ICE9IC0xKTsKKworICAgICAgICAgICAgU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIoZW50cnVzdC5nZXROYW1lKCkpOworICAgICAgICAgICAgUHJvdmlkZXIgcHJvdlRlc3RbXSA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcm92VGVzdC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICAgICAidGhlIHByb3ZpZGVyIGVudHJ1c3QgaXMgZm91bmQgYWZ0ZXIgaXQgd2FzIHJlbW92ZWQiLAorICAgICAgICAgICAgICAgICAgICAgICAgcHJvdlRlc3RbaV0uZ2V0TmFtZSgpICE9IGVudHJ1c3QuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIC8vIFRpZHkgdXAgLSB0aGUgZm9sbG93aW5nIGNhbGxzIGRvIG5vdGhpbmcgaWYgdGhlIHByb3ZpZGVycyB3ZXJlCisgICAgICAgICAgICAvLyBhbHJlYWR5IHJlbW92ZWQgYWJvdmUuCisgICAgICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcih0ZXN0LmdldE5hbWUoKSk7CisgICAgICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcihlbnRydXN0LmdldE5hbWUoKSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvU2VjdXJpdHlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvU2VjdXJpdHlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjUwMzE4ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9TZWN1cml0eVRlc3QuamF2YQpAQCAtMCwwICsxLDQ0MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisgKiBAYXV0aG9yIEJvcmlzIFYuIEt1em5ldHNvdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisKK3B1YmxpYyBjbGFzcyBTZWN1cml0eVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5I2luc2VydFByb3ZpZGVyQXQoUHJvdmlkZXIsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X2luc2VydFByb3ZpZGVyQXRMamF2YV9zZWN1cml0eV9Qcm92aWRlckxJKCkgeworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTZWN1cml0eS5pbnNlcnRQcm92aWRlckF0KG51bGwsIDEpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgUHJvdmlkZXIgcCA9IG5ldyBNeVByb3ZpZGVyKCk7CisgICAgICAgIGludCBpbml0TnVtID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKCkubGVuZ3RoOyAvLyBpbml0aWFsIG51bWJlciBvZgorICAgICAgICAvLyBwcm92aWRlcnMKKyAgICAgICAgUHJvdmlkZXIgaW5pdGlhbFNlY29uZFByb3ZpZGVyTmFtZSA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygpWzFdOworCisgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgIC8vIEluc2VydCBhdCBwb3NpdGlvbiAtMSwgdGhlIHByb3ZpZGVyIGlzIGluc2VydGVkIGF0IHRoZSBlbmQKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpbml0TnVtICsgMSwgU2VjdXJpdHkuaW5zZXJ0UHJvdmlkZXJBdChwLCAtMSkpOworICAgICAgICAgICAgYXNzZXJ0U2FtZShwLCBTZWN1cml0eS5nZXRQcm92aWRlcnMoKVtpbml0TnVtXSk7CisKKyAgICAgICAgICAgIC8vIEEgcHJvdmlkZXIgY2Fubm90IGJlIGFkZGVkIGlmIGl0IGlzIGFscmVhZHkgaW5zdGFsbGVkCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIFNlY3VyaXR5Lmluc2VydFByb3ZpZGVyQXQocCwgMSkpOworCisgICAgICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcihwLmdldE5hbWUoKSk7CisKKyAgICAgICAgICAgIC8vIGluc2VydCBhdCB0aGUgZW5kCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaW5pdE51bSArIDEsIFNlY3VyaXR5Lmluc2VydFByb3ZpZGVyQXQocCwKKyAgICAgICAgICAgICAgICAgICAgaW5pdE51bSArIDEwMCkpOworICAgICAgICAgICAgYXNzZXJ0U2FtZShwLCBTZWN1cml0eS5nZXRQcm92aWRlcnMoKVtpbml0TnVtXSk7CisKKyAgICAgICAgICAgIFNlY3VyaXR5LnJlbW92ZVByb3ZpZGVyKHAuZ2V0TmFtZSgpKTsKKworICAgICAgICAgICAgLy8gaW5zZXJ0IGF0IHRoZSBmaXJzdCBwb3NpdGlvbgorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIFNlY3VyaXR5Lmluc2VydFByb3ZpZGVyQXQocCwgMSkpOworICAgICAgICAgICAgYXNzZXJ0U2FtZShwLCBTZWN1cml0eS5nZXRQcm92aWRlcnMoKVswXSk7CisgICAgICAgICAgICBhc3NlcnRTYW1lKGluaXRpYWxTZWNvbmRQcm92aWRlck5hbWUsIC8vIHByb3ZpZGVyIHNoaWZ0ZWQgZG93bgorICAgICAgICAgICAgICAgICAgICBTZWN1cml0eS5nZXRQcm92aWRlcnMoKVsyXSk7CisgICAgICAgIH0gZmluYWxseSB7IC8vIGNsZWFuIHVwCisgICAgICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcihwLmdldE5hbWUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5I2FkZFByb3ZpZGVyKFByb3ZpZGVyKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfYWRkUHJvdmlkZXJMamF2YV9zZWN1cml0eV9Qcm92aWRlcigpIHsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2VjdXJpdHkuYWRkUHJvdmlkZXIobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBQcm92aWRlciBwID0gbmV3IE15UHJvdmlkZXIoKTsKKyAgICAgICAgaW50IGluaXROdW0gPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoKS5sZW5ndGg7IC8vIGluaXRpYWwgbnVtYmVyIG9mCisgICAgICAgIC8vIHByb3ZpZGVycworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBhZGQKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpbml0TnVtICsgMSwgU2VjdXJpdHkuYWRkUHJvdmlkZXIocCkpOworICAgICAgICAgICAgYXNzZXJ0U2FtZShwLCBTZWN1cml0eS5nZXRQcm92aWRlcnMoKVtpbml0TnVtXSk7CisKKyAgICAgICAgICAgIC8vIEEgcHJvdmlkZXIgY2Fubm90IGJlIGFkZGVkIGlmIGl0IGlzIGFscmVhZHkgaW5zdGFsbGVkCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIFNlY3VyaXR5LmFkZFByb3ZpZGVyKHApKTsKKyAgICAgICAgfSBmaW5hbGx5IHsgLy8gY2xlYW4gdXAKKyAgICAgICAgICAgIFNlY3VyaXR5LnJlbW92ZVByb3ZpZGVyKHAuZ2V0TmFtZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuU2VjdXJpdHkjZ2V0QWxnb3JpdGhtUHJvcGVydHkoU3RyaW5nIGFsZ05hbWUsIFN0cmluZworICAgICAqICAgICAgICBwcm9wTmFtZSkKKyAgICAgKiBAZGlzYWJsZWQgYmVjYXVzZSBTZWN1cml0eS5nZXRBbGdvcml0aG1Qcm9wZXJ0eSBsb29rcyBmb3IKKyAgICAgKiAgICAgICAgICAgInByb3BOYW1lLmFsZ05hbWUiIGluc3RlYWQgb2YgIkFsZy5wcm9wTmFtZS5hbGdOYW1lIgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEFsZ29yaXRobVByb3BlcnR5TGphdmFfbGFuZ19TdHJpbmdfamF2YV9sYW5nX1N0cmluZygpIHsKKworICAgICAgICBQcm92aWRlciBwcm92aWRlciA9IG5ldyBNeVByb3ZpZGVyKCk7CisgICAgICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gbSA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOworICAgICAgICBtLmNsZWFyKCk7CisgICAgICAgIG0ucHV0KCJBbGcucHJvcE5hbWUuYWxnTmFtZSIsICJ2YWx1ZSIpOworICAgICAgICBwcm92aWRlci5wdXRBbGwobSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNlY3VyaXR5LmFkZFByb3ZpZGVyKHByb3ZpZGVyKTsKKworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChTZWN1cml0eS5nZXRBbGdvcml0aG1Qcm9wZXJ0eSgiYWxnTmFtZSIsICJwcm9wTmFtZSIpKTsKKworICAgICAgICAgICAgYXNzZXJ0TnVsbChTZWN1cml0eS5nZXRBbGdvcml0aG1Qcm9wZXJ0eSgiRFNBIiwgbnVsbCkpOworICAgICAgICAgICAgYXNzZXJ0TnVsbChTZWN1cml0eS5nZXRBbGdvcml0aG1Qcm9wZXJ0eSgiRFNBIiwgInByb3BOYW1lIikpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIocHJvdmlkZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuU2VjdXJpdHkjZ2V0QWxnb3JpdGhtcyhTdHJpbmcgc2VydmljZU5hbWUpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEFsZ29yaXRobXNMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nW10gc2VydmljZXNOYW1lcyA9IHsgIlNpZ25hdHVyZSIsICJNZXNzYWdlRGlnZXN0IiwgIkNpcGhlciIsCisgICAgICAgICAgICAgICAgIk1hYyIsICJLZXlTdG9yZSIgfTsKKworICAgICAgICBTdHJpbmdbXSBpbnZhbGlkU2VydmljZU5hbWVzID0geyAiUnViYmlzaCIsICIiLCBudWxsIH07CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZXJ2aWNlc05hbWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBTZXQ8U3RyaW5nPiBhbGdzID0gU2VjdXJpdHkuZ2V0QWxnb3JpdGhtcyhzZXJ2aWNlc05hbWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIm5vIHNlcnZpY2VzIHdpdGggc3BlY2lmaWVkIG5hbWU6ICIgKyBzZXJ2aWNlc05hbWVzW2ldLCBhbGdzLnNpemUoKSA+IDApOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkU2VydmljZU5hbWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBTZXQ8U3RyaW5nPiBhbGdzID0gU2VjdXJpdHkuZ2V0QWxnb3JpdGhtcyhpbnZhbGlkU2VydmljZU5hbWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoInNlcnZpY2VzIHdpdGggc3BlY2lmaWVkIG5hbWU6ICIgKyBpbnZhbGlkU2VydmljZU5hbWVzW2ldLCBhbGdzLnNpemUoKSA9PSAwKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RSZW1vdmVQcm92aWRlcigpIHsKKyAgICAgICAgUHJvdmlkZXJbXSBwcm92aWRlcnM7CisgICAgICAgIFByb3ZpZGVyW10gcHJvdmlkZXJzMTsKKworICAgICAgICBwcm92aWRlcnMgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcm92aWRlcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcihwcm92aWRlcnNbaV0uZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiUHJvdmlkZXJzIG5vdCByZW1vdmVkIiwgMCwKKyAgICAgICAgICAgICAgICAgICAgU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKCkubGVuZ3RoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsgICAgLy8gcmVzdG9yZSBwcm92aWRlcnMKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdmlkZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgU2VjdXJpdHkuYWRkUHJvdmlkZXIocHJvdmlkZXJzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHByb3ZpZGVyczEgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdmlkZXJzMS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiUHJvdmlkZXJzIG5vdCByZXN0b3JlZCBjb3JyZWN0bHkiLCBwcm92aWRlcnNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICBwcm92aWRlcnMxW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuU2VjdXJpdHkjZ2V0UHJvdmlkZXIoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfZ2V0UHJvdmlkZXJMamF2YV9sYW5nX1N0cmluZygpIHsKKworICAgICAgICAvLyBSZXR1cm5zIG51bGwgaWYgbm8gcHJvdmlkZXIgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgaXMgaW5zdGFsbGVkCisgICAgICAgIGFzc2VydE51bGwoU2VjdXJpdHkuZ2V0UHJvdmlkZXIoIlNPTUVJTkNPUlJFQ1RQUk9WSURFUk5BTUUiKSk7CisKKyAgICAgICAgLy8gUmV0dXJucyBudWxsIGlmIG5hbWUgaXMgbnVsbAorICAgICAgICBhc3NlcnROdWxsKFNlY3VyaXR5LmdldFByb3ZpZGVyKG51bGwpKTsKKworICAgICAgICAvLyB0ZXN0IGZvciBleGlzdGluZyBwcm92aWRlcnMKKyAgICAgICAgUHJvdmlkZXJbXSBwcm92aWRlcnMgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0UHJvdmlkZXJzIHJldHVybmVkIHplcm8gbGVuZ3RoIGFycmF5IiwKKyAgICAgICAgICAgICAgICBwcm92aWRlcnMubGVuZ3RoID4gMCk7CisgICAgICAgIGZvciAoUHJvdmlkZXIgcCA6IHByb3ZpZGVycykgeworICAgICAgICAgICAgU3RyaW5nIHByb3ZpZGVyTmFtZSA9IHAuZ2V0TmFtZSgpOworICAgICAgICAgICAgYXNzZXJ0U2FtZShwLCBTZWN1cml0eS5nZXRQcm92aWRlcihwcm92aWRlck5hbWUpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3QgZm9yIG5ld2x5IGluc3RhbGxlZCBwcm92aWRlcgorICAgICAgICBQcm92aWRlciBwID0gbmV3IE15UHJvdmlkZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNlY3VyaXR5LmFkZFByb3ZpZGVyKHApOworCisgICAgICAgICAgICBhc3NlcnRTYW1lKHAsIFNlY3VyaXR5LmdldFByb3ZpZGVyKHAuZ2V0TmFtZSgpKSk7CisgICAgICAgIH0gZmluYWxseSB7IC8vIGNsZWFuIHVwCisgICAgICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcihwLmdldE5hbWUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5I2dldFByb3ZpZGVycyhTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQcm92aWRlcnNMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNlY3VyaXR5LmdldFByb3ZpZGVycygiIik7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNlY3VyaXR5LmdldFByb3ZpZGVycygoU3RyaW5nKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRlc3RHZXRQcm92aWRlcnMoTG9jYWxlLlVTKTsKKyAgICAgICAgdGVzdEdldFByb3ZpZGVycyhuZXcgTG9jYWxlKCJ0ciIsICJUUiIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgU2VjdXJpdHkuZ2V0UHJvdmlkZXJzIGRvZXMgY2FzZSBzZW5zaXRpdmUgb3BlcmF0aW9ucworICAgICAqIGluZGVwZW5kZW50IG9mIGl0cyBsb2NhbGUuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RHZXRQcm92aWRlcnMoTG9jYWxlIGxvY2FsZSkgeworICAgICAgICBMb2NhbGUgZGVmYXVsdExvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KGxvY2FsZSk7CisgICAgICAgIFByb3ZpZGVyIHAgPSBuZXcgTXlQcm92aWRlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2VjdXJpdHkuYWRkUHJvdmlkZXIocCk7CisKKyAgICAgICAgICAgIFN0cmluZyBmaWx0ZXIgPSAiTXlTZXJ2aWNlLk15QWxnb3JpdGhtIjsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZmlsdGVyLCBBcnJheXMuZXF1YWxzKG5ldyBQcm92aWRlcltdIHsgcCB9LCBTZWN1cml0eQorICAgICAgICAgICAgICAgICAgICAuZ2V0UHJvdmlkZXJzKGZpbHRlcikpKTsKKworICAgICAgICAgICAgZmlsdGVyID0gIk15U2VydmljZS5NeUFsZ29yaXRobSBLZXlTaXplOjUxMiI7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGZpbHRlciwgQXJyYXlzLmVxdWFscyhuZXcgUHJvdmlkZXJbXSB7IHAgfSwgU2VjdXJpdHkKKyAgICAgICAgICAgICAgICAgICAgLmdldFByb3ZpZGVycyhmaWx0ZXIpKSk7CisKKyAgICAgICAgICAgIGZpbHRlciA9ICJNeVNlcnZpY2UuTXlBbGdvcml0aG0gS2V5U2l6ZToxMDI1IjsKKyAgICAgICAgICAgIGFzc2VydE51bGwoZmlsdGVyLCBTZWN1cml0eS5nZXRQcm92aWRlcnMoZmlsdGVyKSk7CisKKyAgICAgICAgICAgIC8vIGF0dHJpYnV0ZSBuYW1lIGFuZCB2YWx1ZSBhcmUgY2FzZSBpbnNlbnNpdGl2ZQorICAgICAgICAgICAgZmlsdGVyID0gIk15U2VydmljZS5NeUFsZ29yaXRobSBpbVBMZW1lbnRlZEluOnNvZnRXQVJFIjsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZmlsdGVyLCBBcnJheXMuZXF1YWxzKG5ldyBQcm92aWRlcltdIHsgcCB9LCBTZWN1cml0eQorICAgICAgICAgICAgICAgICAgICAuZ2V0UHJvdmlkZXJzKGZpbHRlcikpKTsKKyAgICAgICAgICAgIGZpbHRlciA9ICJNeVNlcnZpY2UuTXlBbGdvcml0aG0gQVRUcmlidXRlOmF0dHJpYnV0ZVZBTFVFIjsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZmlsdGVyLCBBcnJheXMuZXF1YWxzKG5ldyBQcm92aWRlcltdIHsgcCB9LCBTZWN1cml0eQorICAgICAgICAgICAgICAgICAgICAuZ2V0UHJvdmlkZXJzKGZpbHRlcikpKTsKKyAgICAgICAgICAgIGZpbHRlciA9ICJNeVNlcnZpY2UuTXlBbGdvcml0aG0gXHUwMTMwbVBMZW1lbnRlZFx1MDEzMW46c29mdFdBUkUiOyAvLyBUdXJraXNoIGRvdGxlc3MgaQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShmaWx0ZXIsIEFycmF5cy5lcXVhbHMobmV3IFByb3ZpZGVyW10geyBwIH0sIFNlY3VyaXR5CisgICAgICAgICAgICAgICAgICAgIC5nZXRQcm92aWRlcnMoZmlsdGVyKSkpOworCisgICAgICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTI3NjEKKyAgICAgICAgICAgIGZpbHRlciA9ICJNeVNlcnZpY2UuTm9LZXlTaXplIEtleVNpemU6NTEyIjsKKyAgICAgICAgICAgIGFzc2VydE51bGwoZmlsdGVyLCBTZWN1cml0eS5nZXRQcm92aWRlcnMoZmlsdGVyKSk7CisKKyAgICAgICAgICAgIGZpbHRlciA9ICJNeVNlcnZpY2UuTm9JbXBsZW1lbnRlZEluIEltcGxlbWVudGVkSW46U29mdHdhcmUiOworICAgICAgICAgICAgYXNzZXJ0TnVsbChmaWx0ZXIsIFNlY3VyaXR5LmdldFByb3ZpZGVycyhmaWx0ZXIpKTsKKworICAgICAgICAgICAgZmlsdGVyID0gIkFCQ1NlcnZpY2UuTm9BdHRyaWJ1dGUgQXR0cmlidXRlOkFCQyI7CisgICAgICAgICAgICBhc3NlcnROdWxsKGZpbHRlciwgU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKGZpbHRlcikpOworICAgICAgICB9IGZpbmFsbHkgeyAvLyBjbGVhbiB1cAorICAgICAgICAgICAgU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIocC5nZXROYW1lKCkpOworICAgICAgICAgICAgTG9jYWxlLnNldERlZmF1bHQoZGVmYXVsdExvY2FsZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5I2dldFByb3ZpZGVycyhqYXZhLnV0aWwuTWFwKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UHJvdmlkZXJzTGphdmFfdXRpbF9NYXAoKSB7CisKKyAgICAgICAgTWFwPFN0cmluZywgU3RyaW5nPiBtID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgICAgIFNlY3VyaXR5LmdldFByb3ZpZGVycyhtKTsKKworICAgICAgICBhc3NlcnROdWxsKCJOb3QgbnVsbCByZXN1bHQgb24gZW1wdHkgbWFwIiwgU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKG0pKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKChNYXA8U3RyaW5nLCBTdHJpbmc+KSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIG0ucHV0KCJBQUEuQkJCLkNDQyIsICJhYWFhIik7IC8vIGtleSBoYXMgZG90IGluc3RlYWQgb2Ygc3BhY2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNlY3VyaXR5LmdldFByb3ZpZGVycyhtKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBQcm92aWRlciBwID0gbmV3IE15UHJvdmlkZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNlY3VyaXR5LmFkZFByb3ZpZGVyKHApOworCisgICAgICAgICAgICBtLmNsZWFyKCk7CisgICAgICAgICAgICBtLnB1dCgiTXlTZXJ2aWNlLk15QWxnb3JpdGhtIiwgIiIpOworICAgICAgICAgICAgbS5wdXQoIk1lc3NhZ2VEaWdlc3QuU0hBLTEiLCAiIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJNeVNlcnZpY2UuTXlBbGdvcml0aG0iLCBBcnJheXMuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICBuZXcgUHJvdmlkZXJbXSB7IHAgfSwgU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKG0pKSk7CisKKyAgICAgICAgICAgIG0uY2xlYXIoKTsKKyAgICAgICAgICAgIG0ucHV0KCJNeVNlcnZpY2UuTXlBbGdvcml0aG0gS2V5U2l6ZSIsICI1MTIiKTsKKyAgICAgICAgICAgIG0ucHV0KCJNZXNzYWdlRGlnZXN0LlNIQS0xIiwgIiIpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTXlTZXJ2aWNlLk15QWxnb3JpdGhtIEtleVNpemU6NTEyIiwgQXJyYXlzLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgbmV3IFByb3ZpZGVyW10geyBwIH0sIFNlY3VyaXR5LmdldFByb3ZpZGVycyhtKSkpOworCisgICAgICAgICAgICBtLmNsZWFyKCk7CisgICAgICAgICAgICBtLnB1dCgiTXlTZXJ2aWNlLk15QWxnb3JpdGhtIEtleVNpemUiLCAiMTAyNSIpOworICAgICAgICAgICAgbS5wdXQoIk1lc3NhZ2VEaWdlc3QuU0hBLTEiLCAiIik7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJNeVNlcnZpY2UuTXlBbGdvcml0aG0gS2V5U2l6ZToxMDI1IiwgU2VjdXJpdHkKKyAgICAgICAgICAgICAgICAgICAgLmdldFByb3ZpZGVycyhtKSk7CisKKyAgICAgICAgICAgIC8vIGF0dHJpYnV0ZSBuYW1lIGFuZCB2YWx1ZSBhcmUgY2FzZSBpbnNlbnNpdGl2ZQorICAgICAgICAgICAgbS5jbGVhcigpOworICAgICAgICAgICAgbS5wdXQoIk15U2VydmljZS5NeUFsZ29yaXRobSBpbVBMZW1lbnRlZEluIiwgInNvZnRXQVJFIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMobmV3IFByb3ZpZGVyW10geyBwIH0sIFNlY3VyaXR5CisgICAgICAgICAgICAgICAgICAgIC5nZXRQcm92aWRlcnMobSkpKTsKKyAgICAgICAgICAgIG0uY2xlYXIoKTsKKyAgICAgICAgICAgIG0ucHV0KCJNeVNlcnZpY2UuTXlBbGdvcml0aG0gQVRUcmlidXRlIiwgImF0dHJpYnV0ZVZBTFVFIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMobmV3IFByb3ZpZGVyW10geyBwIH0sIFNlY3VyaXR5CisgICAgICAgICAgICAgICAgICAgIC5nZXRQcm92aWRlcnMobSkpKTsKKworICAgICAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS0yNzYxCisgICAgICAgICAgICBtLmNsZWFyKCk7CisgICAgICAgICAgICBtLnB1dCgiTXlTZXJ2aWNlLk5vS2V5U2l6ZSBLZXlTaXplIiwgIjUxMiIpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiTm8gS2V5U2l6ZSBhdHRyaWJ1dGUiLCBTZWN1cml0eS5nZXRQcm92aWRlcnMobSkpOworCisgICAgICAgICAgICBtLmNsZWFyKCk7CisgICAgICAgICAgICBtLnB1dCgiTXlTZXJ2aWNlLk5vSW1wbGVtZW50ZWRJbiBJbXBsZW1lbnRlZEluIiwgIlNvZnR3YXJlIik7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJObyBJbXBsZW1lbnRlZEluIGF0dHJpYnV0ZSIsIFNlY3VyaXR5LmdldFByb3ZpZGVycyhtKSk7CisKKyAgICAgICAgICAgIG0uY2xlYXIoKTsKKyAgICAgICAgICAgIG0ucHV0KCJBQkNTZXJ2aWNlLk5vQXR0cmlidXRlIEF0dHJpYnV0ZSIsICJBQkMiKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKG0pKTsKKyAgICAgICAgfSBmaW5hbGx5IHsgLy8gY2xlYW4gdXAKKyAgICAgICAgICAgIFNlY3VyaXR5LnJlbW92ZVByb3ZpZGVyKHAuZ2V0TmFtZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuU2VjdXJpdHkjZ2V0UHJvdmlkZXJzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFByb3ZpZGVycygpIHsKKyAgICAgICAgUHJvdmlkZXJbXSBwcnY7CisKKyAgICAgICAgTXlQcm92aWRlciBwcm92aWRlciA9IG5ldyBNeVByb3ZpZGVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcnYgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoKTsKKyAgICAgICAgICAgIGludCBsZW4xID0gcHJ2Lmxlbmd0aDsKKyAgICAgICAgICAgIGlmIChsZW4xID09IDApIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJBcnJheSBvZiBwcm92aWRlcnMgaXMgYW1wdHkiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFNlY3VyaXR5LmFkZFByb3ZpZGVyKHByb3ZpZGVyKTsKKyAgICAgICAgICAgIHBydiA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygpOworICAgICAgICAgICAgaW50IGxlbjIgPSBwcnYubGVuZ3RoOworICAgICAgICAgICAgaWYgKChsZW4yID09IGxlbjEgKyAxKSAmJiAocHJ2W2xlbjItMV0udG9TdHJpbmcoKS5lcXVhbHMoIk15UHJvdmlkZXIgdmVyc2lvbiAxLjAiKSkpIHsKKyAgICAgICAgICAgICAgICAvLyBvaworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJNZXRob2QgZ2V0UHJvdmlkZXJzKCkgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlcyIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICAgICAgZmluYWxseSB7CisgICAgICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcihwcm92aWRlci5nZXROYW1lKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TZWN1cml0eSNnZXRQcm9wZXJ0eShTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQcm9wZXJ0eUxqYXZhX2xhbmdfU3RyaW5nKCkgeworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTZWN1cml0eS5nZXRQcm9wZXJ0eShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBTZWN1cml0eS5zZXRQcm9wZXJ0eSgibXlwcm9wIiwidGVzdCB3aGl0ZSBzcGFjZSAgICAiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXN0IHdoaXRlIHNwYWNlIiwgU2VjdXJpdHkuZ2V0UHJvcGVydHkoIm15cHJvcCIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5I3NldFByb3BlcnR5KFN0cmluZyxTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRQcm9wZXJ0eUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcoKSB7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNlY3VyaXR5LnNldFByb3BlcnR5KG51bGwsICIiKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2VjdXJpdHkuc2V0UHJvcGVydHkoIiIsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIFNlY3VyaXR5LnNldFByb3BlcnR5KCIiLCAiIik7CisgICAgICAgIGFzc2VydEVxdWFscygiRW1wdHkgcHJvcGVydHkiLCAiIiwgU2VjdXJpdHkuZ2V0UHJvcGVydHkoIiIpKTsKKworICAgICAgICBTZWN1cml0eS5zZXRQcm9wZXJ0eSgiTXkgVGVzdCBQcm9wZXJ0eSIsICJNeSBwcm9wZXJ0eSB2YWx1ZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIk15IHByb3BlcnR5IHZhbHVlIiwgU2VjdXJpdHkKKyAgICAgICAgICAgICAgICAuZ2V0UHJvcGVydHkoIk15IFRlc3QgUHJvcGVydHkiKSk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCisgICAgY2xhc3MgTXlQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyIHsKKyAgICAgICAgTXlQcm92aWRlcigpIHsKKyAgICAgICAgICAgIHN1cGVyKCJNeVByb3ZpZGVyIiwgMS4wLCAiUHJvdmlkZXIgZm9yIHRlc3RpbmciKTsKKyAgICAgICAgICAgIHB1dCgiTWVzc2FnZURpZ2VzdC5TSEEtMSIsICJTb21lQ2xhc3NOYW1lIik7CisgICAgICAgICAgICBwdXQoIk15U2VydmljZS5NeUFsZ29yaXRobSIsICJTb21lQ2xhc3NOYW1lIik7CisgICAgICAgICAgICBwdXQoIk15U2VydmljZS5NeUFsZ29yaXRobSBLZXlTaXplIiwgIjEwMjQiKTsKKyAgICAgICAgICAgIHB1dCgiTXlTZXJ2aWNlLk15QWxnb3JpdGhtIEltcGxlbWVudGVkSW4iLCAiU29mdHdhcmUiKTsKKyAgICAgICAgICAgIHB1dCgiTXlTZXJ2aWNlLk15QWxnb3JpdGhtIEF0dHJpYnV0ZSIsICJBdHRyaWJ1dGVWYWx1ZSIpOworCisgICAgICAgICAgICAvLyBzZXJ2aWNlIGhhcyBubyBLZXlTaXplIGF0dHJpYnV0ZQorICAgICAgICAgICAgcHV0KCJNeVNlcnZpY2UuTm9LZXlTaXplIiwgIlNvbWVDbGFzc05hbWUiKTsKKworICAgICAgICAgICAgLy8gc2VydmljZSBoYXMgbm8gSW1wbGVtZW50ZWRJbiBhdHRyaWJ1dGUKKyAgICAgICAgICAgIHB1dCgiTXlTZXJ2aWNlLk5vSW1wbGVtZW50ZWRJbiIsICJTb21lQ2xhc3NOYW1lIik7CisKKyAgICAgICAgICAgIC8vIHNlcnZpY2UgaGFzIG5vICdBdHRyaWJ1dGUnIGF0dHJpYnV0ZQorICAgICAgICAgICAgcHV0KCJBQkNTZXJ2aWNlLk5vQXR0cmlidXRlIiwgIlNvbWVDbGFzc05hbWUiKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9TaWduYXR1cmUyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1NpZ25hdHVyZTJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzk0MjNlZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9TaWduYXR1cmUyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTg0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5EU0FQYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK3B1YmxpYyBjbGFzcyBTaWduYXR1cmUyVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUVTU0FHRSA9ICJhYmMiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgS2V5UGFpciBEU0FfS0VZUzsKKyAgICBwcml2YXRlIHN0YXRpYyBLZXlQYWlyIFJTQV9LRVlTOworCisgICAgcHJpdmF0ZSBzdGF0aWMgS2V5UGFpciBnZXREc2FLZXlzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChEU0FfS0VZUyA9PSBudWxsKSB7CisgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGtleUdlbiA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRTQSIpOworICAgICAgICAgICAga2V5R2VuLmluaXRpYWxpemUoMTAyNCk7CisgICAgICAgICAgICBEU0FfS0VZUyA9IGtleUdlbi5nZW5lcmF0ZUtleVBhaXIoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gRFNBX0tFWVM7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgS2V5UGFpciBnZXRSc2FLZXlzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChSU0FfS0VZUyA9PSBudWxsKSB7CisgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGtleUdlbiA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIlJTQSIpOworICAgICAgICAgICAga2V5R2VuLmluaXRpYWxpemUoMTAyNCk7CisgICAgICAgICAgICBSU0FfS0VZUyA9IGtleUdlbi5nZW5lcmF0ZUtleVBhaXIoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gUlNBX0tFWVM7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TaWduYXR1cmUjY2xvbmUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvbmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2lnbmF0dXJlIHMgPSBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIkRTQSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5jbG9uZSgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TaWduYXR1cmUjZ2V0QWxnb3JpdGhtKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEFsZ29yaXRobSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgYWxnID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCJEU0EiKS5nZXRBbGdvcml0aG0oKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0QWxnb3JpdGhtIGRpZCBub3QgZ2V0IERTQSAoIiArIGFsZyArICIpIiwgYWxnCisgICAgICAgICAgICAgICAgLmluZGV4T2YoIkRTQSIpICE9IC0xKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZSNnZXRJbnN0YW5jZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIkRTQSIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoImJvZ3VzIik7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TaWduYXR1cmUjZ2V0SW5zdGFuY2UoamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS5zZWN1cml0eS5Qcm92aWRlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZ19qYXZhX3NlY3VyaXR5X1Byb3ZpZGVyKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQcm92aWRlcltdIHByb3ZpZGVycyA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygiU2lnbmF0dXJlLkRTQSIpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdmlkZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBTaWduYXR1cmUgc2lnbmF0dXJlID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCJEU0EiLCBwcm92aWRlcnNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJEU0EiLCBzaWduYXR1cmUuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHByb3ZpZGVyc1tpXSwgc2lnbmF0dXJlLmdldFByb3ZpZGVyKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNpZ25hdHVyZS5nZXRJbnN0YW5jZSgoU3RyaW5nKSBudWxsLCAoUHJvdmlkZXIpIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNpZ25hdHVyZS5nZXRJbnN0YW5jZSgiRFNBIiwgKFByb3ZpZGVyKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2lnbmF0dXJlLmdldEluc3RhbmNlKChTdHJpbmcpIG51bGwsIHByb3ZpZGVyc1swXSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2lnbmF0dXJlLmdldEluc3RhbmNlKCJib2d1cyIsIHByb3ZpZGVyc1swXSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TaWduYXR1cmUjZ2V0SW5zdGFuY2UoamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZygpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvdmlkZXJbXSBwcm92aWRlcnMgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoIlNpZ25hdHVyZS5EU0EiKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHByb3ZpZGVycy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU2lnbmF0dXJlLmdldEluc3RhbmNlKCJEU0EiLCBwcm92aWRlcnNbaV0uZ2V0TmFtZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoImJvZ3VzIiwgcHJvdmlkZXJzWzBdLmdldE5hbWUoKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgUHJvdmlkZXJbXSBwcCA9IFNlY3VyaXR5LmdldFByb3ZpZGVycygpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBwLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFNpZ25hdHVyZS5nZXRJbnN0YW5jZSgiRFNBIiwgcHBbaV0udG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgZmFpbChwcFtpXS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdbXSBzcCA9IHtudWxsLCAiIn07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3AubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgU2lnbmF0dXJlLmdldEluc3RhbmNlKCJEU0EiLCBzcFtpXSk7CisgICAgICAgICAgICAgICAgZmFpbChzcFtpXSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlI2dldFBhcmFtZXRlcnMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UGFyYW1ldGVycygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTaWduYXR1cmUgc2lnID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCJEU0EiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZy5nZXRQYXJhbWV0ZXJzKCk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvdWxkIGJlIHRoYXQgdGhlIG9wZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTXlTaWduYXR1cmUgc2lnMiA9IG5ldyBNeVNpZ25hdHVyZSgidGVzdCIpOworICAgICAgICAgICAgc2lnMi5nZXRQYXJhbWV0ZXJzKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBNeVNpZ25hdHVyZSBzaWcyID0gbmV3IE15U2lnbmF0dXJlKCJBQkMiKTsKKyAgICAgICAgc2lnMi5nZXRQYXJhbWV0ZXJzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TaWduYXR1cmUjZ2V0UGFyYW1ldGVyKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFBhcmFtZXRlckxqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNpZ25hdHVyZSBzaWcgPSBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIkRTQSIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaWcuZ2V0UGFyYW1ldGVyKCJyIik7CisgICAgICAgICAgICBzaWcuZ2V0UGFyYW1ldGVyKCJzIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlI2dldFByb3ZpZGVyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFByb3ZpZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFByb3ZpZGVyIHAgPSBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIkRTQSIpLmdldFByb3ZpZGVyKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoInByb3ZpZGVyIGlzIG51bGwiLCBwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZSNpbml0U2lnbihqYXZhLnNlY3VyaXR5LlByaXZhdGVLZXkpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pbml0U2lnbkxqYXZhX3NlY3VyaXR5X1ByaXZhdGVLZXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2lnbmF0dXJlLmdldEluc3RhbmNlKCJEU0EiKS5pbml0U2lnbihnZXREc2FLZXlzKCkuZ2V0UHJpdmF0ZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2lnbmF0dXJlLmdldEluc3RhbmNlKCJEU0EiKS5pbml0U2lnbihnZXRSc2FLZXlzKCkuZ2V0UHJpdmF0ZSgpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9pbml0U2lnbkxqYXZhX3NlY3VyaXR5X1ByaXZhdGVLZXlMamF2YV9zZWN1cml0eV9TZWN1cmVSYW5kb20oKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNpZ25hdHVyZSBzaWcgPSBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIkRTQSIpOworICAgICAgICBzaWcuaW5pdFNpZ24oZ2V0RHNhS2V5cygpLmdldFByaXZhdGUoKSwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luaXRTaWduTGphdmFfc2VjdXJpdHlfUHJpdmF0ZUtleUxqYXZhX3NlY3VyaXR5X1NlY3VyZVJhbmRvbV9taXNtYXRjaCgpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNpZ25hdHVyZSBzaWcgPSBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIkRTQSIpOworICAgICAgICAgICAgc2lnLmluaXRTaWduKGdldFJzYUtleXMoKS5nZXRQcml2YXRlKCksIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlI2luaXRWZXJpZnkoamF2YS5zZWN1cml0eS5QdWJsaWNLZXkpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pbml0VmVyaWZ5TGphdmFfc2VjdXJpdHlfUHVibGljS2V5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNpZ25hdHVyZS5nZXRJbnN0YW5jZSgiRFNBIikuaW5pdFZlcmlmeShnZXREc2FLZXlzKCkuZ2V0UHVibGljKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIkRTQSIpLmluaXRWZXJpZnkoZ2V0UnNhS2V5cygpLmdldFB1YmxpYygpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TaWduYXR1cmUjaW5pdFZlcmlmeShqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pbml0VmVyaWZ5TGphdmFfc2VjdXJpdHlfQ2VydGlmaWNhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvdmlkZXIgcCA9IG5ldyBNeVByb3ZpZGVyKCk7CisgICAgICAgIHAucHV0KCJEU0EiLCAidGVzdHMuamF2YS5zZWN1cml0eS5zdXBwb3J0LmNlcnQuTXlDZXJ0aWZpY2F0ZSQxIik7CisKKyAgICAgICAgUHJvdmlkZXIgbXlQcm92aWRlciA9IG5ldyBNeVByb3ZpZGVyKCk7CisgICAgICAgIFNlY3VyaXR5LmFkZFByb3ZpZGVyKG15UHJvdmlkZXIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQcm92aWRlcltdIHBwID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKCk7CisgICAgICAgICAgICBpZiAocHAgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIkRTQSIpLmluaXRWZXJpZnkoKENlcnRpZmljYXRlKSBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIobXlQcm92aWRlci5nZXROYW1lKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TaWduYXR1cmUjc2V0UGFyYW1ldGVyKGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgICAgIGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFBhcmFtZXRlckxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19PYmplY3QoKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNpZ25hdHVyZSBzaWcgPSBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIkRTQSIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaWcuc2V0UGFyYW1ldGVyKCJyIiwgQmlnSW50ZWdlci5PTkUpOworICAgICAgICAgICAgc2lnLnNldFBhcmFtZXRlcigicyIsIEJpZ0ludGVnZXIuT05FKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3VsZCBiZSB0aGF0IGl0J3MgYW4gaW52YWxpZCBwYXJhbSBmb3IgdGhlIGZvdW5kIGFsZ29yaXRobQorICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3VsZCBiZSB0aGF0IHRoZSBvcGVyYXRpb24gaXMgbm90IHN1cHBvcnRlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TaWduYXR1cmUjc2V0UGFyYW1ldGVyKGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0UGFyYW1ldGVyTGphdmFfc2VjdXJpdHlfc3BlY19BbGdvcml0aG1QYXJhbWV0ZXJTcGVjKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTaWduYXR1cmUgc2lnID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCJEU0EiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgRFNBUGFyYW1ldGVyU3BlYyBzcGVjID0gbmV3IERTQVBhcmFtZXRlclNwZWMoQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLCBCaWdJbnRlZ2VyLk9ORSk7CisgICAgICAgICAgICBzaWcuc2V0UGFyYW1ldGVyKHNwZWMpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvdWxkIGJlIHRoYXQgaXQncyBhbiBpbnZhbGlkIHBhcmFtIGZvciB0aGUgZm91bmQgYWxnb3JpdGhtCisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvdWxkIGJlIHRoYXQgdGhlIG9wZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZSNzaWduKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NpZ24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2lnbmF0dXJlIHNpZyA9IFNpZ25hdHVyZS5nZXRJbnN0YW5jZSgiRFNBIik7CisgICAgICAgIHNpZy5pbml0U2lnbihnZXREc2FLZXlzKCkuZ2V0UHJpdmF0ZSgpKTsKKyAgICAgICAgc2lnLnVwZGF0ZShNRVNTQUdFLmdldEJ5dGVzKCkpOworICAgICAgICBzaWcuc2lnbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlI3RvU3RyaW5nKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzdHIgPSBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIkRTQSIpLnRvU3RyaW5nKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoInRvU3RyaW5nIGlzIG51bGwiLCBzdHIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlI3VwZGF0ZShieXRlW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF91cGRhdGUkQigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTaWduYXR1cmUgc2lnID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCJEU0EiKTsKKyAgICAgICAgc2lnLmluaXRTaWduKGdldERzYUtleXMoKS5nZXRQcml2YXRlKCkpOworCisgICAgICAgIGJ5dGVbXSBieXRlcyA9IE1FU1NBR0UuZ2V0Qnl0ZXMoKTsKKyAgICAgICAgc2lnLnVwZGF0ZShieXRlcyk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNpZ25hdHVyZSBzaWcyID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCJEU0EiKTsKKyAgICAgICAgICAgIHNpZzIudXBkYXRlKE1FU1NBR0UuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNpZ25hdHVyZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5TaWduYXR1cmUjdXBkYXRlKGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF91cGRhdGUkQklJKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNpZ25hdHVyZSBzaWcgPSBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIkRTQSIpOworICAgICAgICBieXRlW10gYnl0ZXMgPSBNRVNTQUdFLmdldEJ5dGVzKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZy51cGRhdGUoYnl0ZXMsIDAsIGJ5dGVzLmxlbmd0aCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKFNpZ25hdHVyZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgc2lnLmluaXRTaWduKGdldERzYUtleXMoKS5nZXRQcml2YXRlKCkpOworCisKKyAgICAgICAgc2lnLnVwZGF0ZShieXRlcywgMCwgYnl0ZXMubGVuZ3RoKTsKKworICAgICAgICBzaWcudXBkYXRlKGJ5dGVzLCBieXRlcy5sZW5ndGggLSAyLCAyKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2lnLnVwZGF0ZShieXRlcywgYnl0ZXMubGVuZ3RoIC0zLCA0KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2lnLnVwZGF0ZShudWxsLCAwLCA1KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZSN1cGRhdGUoYnl0ZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VwZGF0ZUIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2lnbmF0dXJlIHNpZyA9IFNpZ25hdHVyZS5nZXRJbnN0YW5jZSgiRFNBIik7CisgICAgICAgIHNpZy5pbml0U2lnbihnZXREc2FLZXlzKCkuZ2V0UHJpdmF0ZSgpKTsKKworICAgICAgICBzaWcudXBkYXRlKE1FU1NBR0UuZ2V0Qnl0ZXMoKVswXSk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZSN1cGRhdGUoQnl0ZUJ1ZmZlciBkYXRhKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdXBkYXRlTGphdmFfbmlvX0J5dGVCdWZmZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2lnbmF0dXJlIHNpZyA9IFNpZ25hdHVyZS5nZXRJbnN0YW5jZSgiRFNBIik7CisgICAgICAgIEJ5dGVCdWZmZXIgYnVmZmVyID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZy51cGRhdGUoYnVmZmVyKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU2lnbmF0dXJlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBzaWcuaW5pdFNpZ24oZ2V0RHNhS2V5cygpLmdldFByaXZhdGUoKSk7CisgICAgICAgIHNpZy51cGRhdGUoYnVmZmVyKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlI3ZlcmlmeShieXRlW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF92ZXJpZnkkQigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTaWduYXR1cmUgc2lnID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCJEU0EiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2lnLnZlcmlmeShuZXcgYnl0ZVtdIHsgMCwxLDIsMyB9KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU2lnbmF0dXJlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBzaWcuaW5pdFNpZ24oZ2V0RHNhS2V5cygpLmdldFByaXZhdGUoKSk7CisgICAgICAgIHNpZy51cGRhdGUoTUVTU0FHRS5nZXRCeXRlcygpKTsKKyAgICAgICAgYnl0ZVtdIHNpZ25hdHVyZSA9IHNpZy5zaWduKCk7CisKKyAgICAgICAgc2lnLmluaXRWZXJpZnkoZ2V0RHNhS2V5cygpLmdldFB1YmxpYygpKTsKKyAgICAgICAgc2lnLnVwZGF0ZShNRVNTQUdFLmdldEJ5dGVzKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJTaWduL1ZlcmlmeSBkb2VzIG5vdCBwYXNzIiwgc2lnLnZlcmlmeShzaWduYXR1cmUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZSN2ZXJpZnkoYnl0ZVtdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3ZlcmlmeSRCSUkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2lnbmF0dXJlIHNpZyA9IFNpZ25hdHVyZS5nZXRJbnN0YW5jZSgiRFNBIik7CisgICAgICAgIHNpZy5pbml0U2lnbihnZXREc2FLZXlzKCkuZ2V0UHJpdmF0ZSgpKTsKKyAgICAgICAgc2lnLnVwZGF0ZShNRVNTQUdFLmdldEJ5dGVzKCkpOworICAgICAgICBieXRlW10gc2lnbmF0dXJlID0gc2lnLnNpZ24oKTsKKworICAgICAgICBzaWcuaW5pdFZlcmlmeShnZXREc2FLZXlzKCkuZ2V0UHVibGljKCkpOworICAgICAgICBzaWcudXBkYXRlKE1FU1NBR0UuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlNpZ24vVmVyaWZ5IGRvZXMgbm90IHBhc3MiLCBzaWcudmVyaWZ5KHNpZ25hdHVyZSwgMCwKKyAgICAgICAgICAgICAgICBzaWduYXR1cmUubGVuZ3RoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZy52ZXJpZnkobnVsbCwgMCwgc2lnbmF0dXJlLmxlbmd0aCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZy52ZXJpZnkoc2lnbmF0dXJlLCAtNSwgc2lnbmF0dXJlLmxlbmd0aCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZy52ZXJpZnkoc2lnbmF0dXJlLCBzaWduYXR1cmUubGVuZ3RoLCAwKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU2lnbmF0dXJlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2lnLnZlcmlmeShzaWduYXR1cmUsIDAsIHNpZ25hdHVyZS5sZW5ndGggKiAyKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBNeVByb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXIgeworICAgICAgICBwcml2YXRlIFNldDxQcm92aWRlci5TZXJ2aWNlPiBzZXJ2aWNlcyA9IG51bGw7CisKKyAgICAgICAgTXlQcm92aWRlcigpIHsKKyAgICAgICAgICAgIHN1cGVyKCJNeVByb3ZpZGVyIiwgMS4wLCAiUHJvdmlkZXIgZm9yIHRlc3RpbmciKTsKKyAgICAgICAgICAgIHB1dCgiTWVzc2FnZURpZ2VzdC5TSEEtMSIsICJTb21lQ2xhc3NOYW1lIik7CisgICAgICAgICAgICBwdXQoIk1lc3NhZ2VEaWdlc3QuYWJjIiwgIlNvbWVDbGFzc05hbWUiKTsKKyAgICAgICAgICAgIHB1dCgiQWxnLkFsaWFzLk1lc3NhZ2VEaWdlc3QuU0hBMSIsICJTSEEtMSIpOworICAgICAgICAgICAgaWYgKHNlcnZpY2VzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXJ2aWNlcy5jbGVhcigpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzZXJ2aWNlcyA9IG5ldyBIYXNoU2V0PFNlcnZpY2U+KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBNeVByb3ZpZGVyKFN0cmluZyBuYW1lLCBkb3VibGUgdmVyc2lvbiwgU3RyaW5nIGluZm8pIHsKKyAgICAgICAgICAgIHN1cGVyKG5hbWUsIHZlcnNpb24sIGluZm8pOworICAgICAgICAgICAgaWYgKHNlcnZpY2VzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXJ2aWNlcy5jbGVhcigpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzZXJ2aWNlcyA9IG5ldyBIYXNoU2V0PFNlcnZpY2U+KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBwdXRTZXJ2aWNlKFByb3ZpZGVyLlNlcnZpY2UgcykgeworICAgICAgICAgICAgc3VwZXIucHV0U2VydmljZShzKTsKKyAgICAgICAgICAgIHNlcnZpY2VzLmFkZChzKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZVNlcnZpY2UoUHJvdmlkZXIuU2VydmljZSBzKSB7CisgICAgICAgICAgICBzdXBlci5yZW1vdmVTZXJ2aWNlKHMpOworICAgICAgICAgICAgc2VydmljZXMucmVtb3ZlKHMpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXROdW1TZXJ2aWNlcygpIHsKKyAgICAgICAgICAgIHJldHVybiBzZXJ2aWNlcy5zaXplKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBwcml2YXRlIGNsYXNzIE15U2lnbmF0dXJlIGV4dGVuZHMgU2lnbmF0dXJlIHsKKworICAgICAgICBwcm90ZWN0ZWQgTXlTaWduYXR1cmUoU3RyaW5nIGFsZ29yaXRobSkgeworICAgICAgICAgICAgc3VwZXIoYWxnb3JpdGhtKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgT2JqZWN0IGVuZ2luZUdldFBhcmFtZXRlcihTdHJpbmcgcGFyYW0pCisgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdFNpZ24oUHJpdmF0ZUtleSBwcml2YXRlS2V5KQorICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXRWZXJpZnkoUHVibGljS2V5IHB1YmxpY0tleSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lU2V0UGFyYW1ldGVyKFN0cmluZyBwYXJhbSwgT2JqZWN0IHZhbHVlKQorICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIHsKKworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBieXRlW10gZW5naW5lU2lnbigpIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGUgYikgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pCisgICAgICAgICAgICAgICAgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBlbmdpbmVWZXJpZnkoYnl0ZVtdIHNpZ0J5dGVzKQorICAgICAgICAgICAgICAgIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBBbGdvcml0aG1QYXJhbWV0ZXJzIGVuZ2luZUdldFBhcmFtZXRlcnMoKSB7CisgICAgICAgICAgICBpZiAodGhpcy5nZXRBbGdvcml0aG0oKS5lcXVhbHMoInRlc3QiKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5lbmdpbmVHZXRQYXJhbWV0ZXJzKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvU2lnbmF0dXJlRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1NpZ25hdHVyZUV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44N2E5Mzg0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1NpZ25hdHVyZUV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDE3NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmVFeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlNpZ25hdHVyZUV4Y2VwdGlvbjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIFNpZ25hdHVyZUV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgVGhyb3dhYmxlIHRDYXVzZSA9IG5ldyBUaHJvd2FibGUoIlRocm93YWJsZSBmb3IgZXhjZXB0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5TaWduYXR1cmVFeGNlcHRpb24oKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgU2lnbmF0dXJlRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2lnbmF0dXJlRXhjZXB0aW9uMDEoKSB7CisgICAgICAgIFNpZ25hdHVyZUV4Y2VwdGlvbiB0RSA9IG5ldyBTaWduYXR1cmVFeGNlcHRpb24oKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+U2lnbmF0dXJlRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yIEFzc2VydGlvbjoKKyAgICAgKiBjb25zdHJ1Y3RzIFNpZ25hdHVyZUV4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4gUGFyYW1ldGVyCisgICAgICogPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2lnbmF0dXJlRXhjZXB0aW9uMDIoKSB7CisgICAgICAgIFNpZ25hdHVyZUV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBTaWduYXR1cmVFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5TaWduYXR1cmVFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgU2lnbmF0dXJlRXhjZXB0aW9uIHdoZW4gPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNpZ25hdHVyZUV4Y2VwdGlvbjAzKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICAgICAgU2lnbmF0dXJlRXhjZXB0aW9uIHRFID0gbmV3IFNpZ25hdHVyZUV4Y2VwdGlvbihtc2cpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5TaWduYXR1cmVFeGNlcHRpb24oVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgU2lnbmF0dXJlRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzCisgICAgICogbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTaWduYXR1cmVFeGNlcHRpb24wNCgpIHsKKyAgICAgICAgVGhyb3dhYmxlIGNhdXNlID0gbnVsbDsKKyAgICAgICAgU2lnbmF0dXJlRXhjZXB0aW9uIHRFID0gbmV3IFNpZ25hdHVyZUV4Y2VwdGlvbihjYXVzZSk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPlNpZ25hdHVyZUV4Y2VwdGlvbihUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBTaWduYXR1cmVFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90CisgICAgICogbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTaWduYXR1cmVFeGNlcHRpb24wNSgpIHsKKyAgICAgICAgU2lnbmF0dXJlRXhjZXB0aW9uIHRFID0gbmV3IFNpZ25hdHVyZUV4Y2VwdGlvbih0Q2F1c2UpOworICAgICAgICBpZiAodEUuZ2V0TWVzc2FnZSgpICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIFN0cmluZyBnZXRNID0gdEUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIHNob3VsZCBjb250YWluICIuY29uY2F0KHRvUyksIChnZXRNCisgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKHRvUykgIT0gLTEpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiAiLmNvbmNhdCh0Q2F1c2UudG9TdHJpbmcoKSksIHRFCisgICAgICAgICAgICAgICAgLmdldENhdXNlKCksIHRDYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+U2lnbmF0dXJlRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgU2lnbmF0dXJlRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzCisgICAgICogbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2lnbmF0dXJlRXhjZXB0aW9uMDYoKSB7CisgICAgICAgIFNpZ25hdHVyZUV4Y2VwdGlvbiB0RSA9IG5ldyBTaWduYXR1cmVFeGNlcHRpb24obnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+U2lnbmF0dXJlRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgU2lnbmF0dXJlRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzCisgICAgICogbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNpZ25hdHVyZUV4Y2VwdGlvbjA3KCkgeworICAgICAgICBTaWduYXR1cmVFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgU2lnbmF0dXJlRXhjZXB0aW9uKG1zZ3NbaV0sIG51bGwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm46ICIuY29uY2F0KG1zZ3NbaV0pLCB0RQorICAgICAgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZSgpLCBtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+U2lnbmF0dXJlRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgU2lnbmF0dXJlRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdAorICAgICAqIG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNpZ25hdHVyZUV4Y2VwdGlvbjA4KCkgeworICAgICAgICBTaWduYXR1cmVFeGNlcHRpb24gdEUgPSBuZXcgU2lnbmF0dXJlRXhjZXB0aW9uKG51bGwsIHRDYXVzZSk7CisgICAgICAgIGlmICh0RS5nZXRNZXNzYWdlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgbXVzdCBzaG91bGQgIi5jb25jYXQodG9TKSwgKGdldE0KKyAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwgdEUKKyAgICAgICAgICAgICAgICAuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5TaWduYXR1cmVFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBTaWduYXR1cmVFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90CisgICAgICogbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNpZ25hdHVyZUV4Y2VwdGlvbjA5KCkgeworICAgICAgICBTaWduYXR1cmVFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgU2lnbmF0dXJlRXhjZXB0aW9uKG1zZ3NbaV0sIHRDYXVzZSk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGlmIChtc2dzW2ldLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IGNvbnRhaW4gIi5jb25jYXQobXNnc1tpXSksIGdldE0KKyAgICAgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKG1zZ3NbaV0pICE9IC0xKTsKKyAgICAgICAgICAgICAgICBpZiAoIWdldE0uZXF1YWxzKG1zZ3NbaV0pKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBzaG91bGQgY29udGFpbiAiLmNvbmNhdCh0b1MpLCBnZXRNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwKKyAgICAgICAgICAgICAgICAgICAgdEUuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9TaWduYXR1cmVTcGlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvU2lnbmF0dXJlU3BpVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVhMGJkN2YKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvU2lnbmF0dXJlU3BpVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDMxIEBACitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlU3BpOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK3B1YmxpYyBjbGFzcyBTaWduYXR1cmVTcGlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJjYXN0IikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2lnbmF0dXJlU3BpKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgTXlTaWduYXR1cmVTcGkxIHNzMSA9IG5ldyBNeVNpZ25hdHVyZVNwaTEoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc3MxKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoc3MxIGluc3RhbmNlb2YgU2lnbmF0dXJlU3BpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvbmUoKSB7CisgICAgICAgIE15U2lnbmF0dXJlU3BpMSBzczEgPSBuZXcgTXlTaWduYXR1cmVTcGkxKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNeVNpZ25hdHVyZVNwaTEgc3NjMSA9IChNeVNpZ25hdHVyZVNwaTEpIHNzMS5jbG9uZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShzczEgIT0gc3NjMSk7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIE15U2lnbmF0dXJlU3BpMiBzczIgPSBuZXcgTXlTaWduYXR1cmVTcGkyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzczIuY2xvbmUoKTsKKyAgICAgICAgICAgIGZhaWwoIkNsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGV4cGVjdGVkICIpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFic3RyYWN0TWV0aG9kcygpIHsKKyAgICAgICAgTXlTaWduYXR1cmVTcGkxIHNzMSA9IG5ldyBNeVNpZ25hdHVyZVNwaTEoKTsKKyAgICAgICAgYnl0ZVtdIGIgPSB7MCwgMSwgMiwgMywgNCwgNX07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzczEuZW5naW5lR2V0UGFyYW1ldGVyKCJ0ZXN0Iik7CisgICAgICAgICAgICBzczEuZW5naW5lSW5pdFNpZ24obnVsbCk7CisgICAgICAgICAgICBzczEuZW5naW5lSW5pdFZlcmlmeShudWxsKTsKKyAgICAgICAgICAgIHNzMS5lbmdpbmVTZXRQYXJhbWV0ZXIoInRlc3QiLCBudWxsKTsKKyAgICAgICAgICAgIHNzMS5lbmdpbmVTaWduKCk7CisgICAgICAgICAgICBzczEuZW5naW5lVXBkYXRlKGJbMV0pOworICAgICAgICAgICAgc3MxLmVuZ2luZVVwZGF0ZShiLCAwLCBiLmxlbmd0aCk7CisgICAgICAgICAgICBzczEuZW5naW5lVmVyaWZ5KGIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBlbmdpbmVHZXRQYXJhbWV0ZXJzQ2FsbGVkID0gZmFsc2U7CisgICAgcHJpdmF0ZSBib29sZWFuIGVuZ2luZUdldFBhcmFtZXRlcnNFeGNlcHRpb25PY3VycmVkID0gZmFsc2U7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5naW5lR2V0UGFyYW1ldGVycygpIHsKKyAgICAgICAgLy8gb3IgcmF0aGVyIHRlc3QgdGhhdCBubyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpcyB0aHJvd24/CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgICAgICAgIFNpZ25hdHVyZSBzID0gbmV3IFNpZ25hdHVyZSgiZHVtbXkiKSB7CisgICAgICAgICAgICBwcm90ZWN0ZWQgQWxnb3JpdGhtUGFyYW1ldGVycyBlbmdpbmVHZXRQYXJhbWV0ZXJzKCkgeworICAgICAgICAgICAgICAgIGVuZ2luZUdldFBhcmFtZXRlcnNDYWxsZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN1cGVyLmVuZ2luZUdldFBhcmFtZXRlcnMoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGVuZ2luZUdldFBhcmFtZXRlcnNFeGNlcHRpb25PY3VycmVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHJvdGVjdGVkIE9iamVjdCBlbmdpbmVHZXRQYXJhbWV0ZXIoU3RyaW5nIHBhcmFtKQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdFNpZ24oUHJpdmF0ZUtleSBwcml2YXRlS2V5KQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0VmVyaWZ5KFB1YmxpY0tleSBwdWJsaWNLZXkpCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVNldFBhcmFtZXRlcihTdHJpbmcgcGFyYW0sIE9iamVjdCB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24geworCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVTaWduKCkgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGUgYikgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworCisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gZW5naW5lVmVyaWZ5KGJ5dGVbXSBzaWdCeXRlcykKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICAvLyBtdXN0IGNhbGwgZW5naW5lR2V0UGFyYW1ldGVycworICAgICAgICBzLmdldFBhcmFtZXRlcnMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShlbmdpbmVHZXRQYXJhbWV0ZXJzQ2FsbGVkKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShlbmdpbmVHZXRQYXJhbWV0ZXJzRXhjZXB0aW9uT2N1cnJlZCk7CisgICAgfQorCisgICAgY2xhc3MgTXlTaWduYXR1cmVTcGkxIGV4dGVuZHMgU2lnbmF0dXJlU3BpIGltcGxlbWVudHMgQ2xvbmVhYmxlIHsKKworICAgICAgICBwdWJsaWMgT2JqZWN0IGVuZ2luZUdldFBhcmFtZXRlcihTdHJpbmcgcGFyYW0pIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGVuZ2luZUluaXRTaWduKFByaXZhdGVLZXkgcHJpdmF0ZUtleSkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgZW5naW5lSW5pdFZlcmlmeShQdWJsaWNLZXkgcHVibGljS2V5KSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBlbmdpbmVTZXRQYXJhbWV0ZXIoU3RyaW5nIHBhcmFtLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZW5naW5lU2lnbigpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGUgYikgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBlbmdpbmVWZXJpZnkoYnl0ZVtdIHNpZ0J5dGVzKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgIH0KKworICAgIGNsYXNzIE15U2lnbmF0dXJlU3BpMiBleHRlbmRzIFNpZ25hdHVyZVNwaSB7CisgICAgICAgIHB1YmxpYyBPYmplY3QgZW5naW5lR2V0UGFyYW1ldGVyKFN0cmluZyBwYXJhbSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgZW5naW5lSW5pdFNpZ24oUHJpdmF0ZUtleSBwcml2YXRlS2V5KSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBlbmdpbmVJbml0VmVyaWZ5KFB1YmxpY0tleSBwdWJsaWNLZXkpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGVuZ2luZVNldFBhcmFtZXRlcihTdHJpbmcgcGFyYW0sIE9iamVjdCB2YWx1ZSkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBlbmdpbmVTaWduKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZSBiKSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGVuZ2luZVZlcmlmeShieXRlW10gc2lnQnl0ZXMpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgIGNsYXNzIE15U2lnbmF0dXJlIGV4dGVuZHMgU2lnbmF0dXJlIHsKKworICAgICAgICBTZXQ8U3RyaW5nPiBjYWxsZWRNZXRob2RzID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgICBwcm90ZWN0ZWQgTXlTaWduYXR1cmUoU3RyaW5nIGFsZ29yaXRobSkgeworICAgICAgICAgICAgc3VwZXIoYWxnb3JpdGhtKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgT2JqZWN0IGVuZ2luZUdldFBhcmFtZXRlcihTdHJpbmcgcGFyYW0pCisgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICAgICAgbWV0aG9kQ2FsbGVkKCJlbmdpbmVHZXRQYXJhbWV0ZXJfU3RyaW5nIik7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXRTaWduKFByaXZhdGVLZXkgcHJpdmF0ZUtleSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBtZXRob2RDYWxsZWQoImVuZ2luZUluaXRTaWduX1ByaXZhdGVLZXkiKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0VmVyaWZ5KFB1YmxpY0tleSBwdWJsaWNLZXkpCisgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICAgICAgbWV0aG9kQ2FsbGVkKCJlbmdpbmVJbml0VmVyaWZ5X1B1YmxpY0tleSIpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVNldFBhcmFtZXRlcihTdHJpbmcgcGFyYW0sIE9iamVjdCB2YWx1ZSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgICAgICBtZXRob2RDYWxsZWQoImVuZ2luZVNldFBhcmFtZXRlcl9TdHJpbmdfT2JqZWN0Iik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVTaWduKCkgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBtZXRob2RDYWxsZWQoImVuZ2luZVNpZ24iKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShieXRlIGIpIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICAgICAgbWV0aG9kQ2FsbGVkKCJlbmdpbmVVcGRhdGVfW0IiKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pCisgICAgICAgICAgICAgICAgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBtZXRob2RDYWxsZWQoImVuZ2luZVVwZGF0ZV9bQklJIik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gZW5naW5lVmVyaWZ5KGJ5dGVbXSBzaWdCeXRlcykKKyAgICAgICAgICAgICAgICB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIG1ldGhvZENhbGxlZCgiZW5naW5lVmVyaWZ5X1tCIik7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdFNpZ24oUHJpdmF0ZUtleSBwcml2YXRlS2V5LCBTZWN1cmVSYW5kb20gcmFuZG9tKQorICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIG1ldGhvZENhbGxlZCgiZW5naW5lSW5pdFNpZ25fUHJpdmF0ZUtleV9TZWN1cmVSYW5kb20iKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVTZXRQYXJhbWV0ZXIoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbXMpCisgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICAgICAgbWV0aG9kQ2FsbGVkKCJlbmdpbmVTZXRQYXJhbWV0ZXJfQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyIpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBpbnQgZW5naW5lU2lnbihieXRlW10gb3V0YnVmLCBpbnQgb2Zmc2V0LCBpbnQgbGVuKQorICAgICAgICAgICAgICAgIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICAgICAgbWV0aG9kQ2FsbGVkKCJlbmdpbmVTaWduX1tCSUkiKTsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShCeXRlQnVmZmVyIGlucHV0KSB7CisgICAgICAgICAgICBtZXRob2RDYWxsZWQoImVuZ2luZVVwZGF0ZV9CeXRlQnVmZmVyIik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gZW5naW5lVmVyaWZ5KGJ5dGVbXSBzaWdCeXRlcywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIG1ldGhvZENhbGxlZCgiZW5naW5lVmVyaWZ5X1tCSUkiKTsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gd2FzTWV0aG9kQ2FsbGVkKFN0cmluZyBtZXRob2ROYW1lKSB7CisgICAgICAgICAgICByZXR1cm4gY2FsbGVkTWV0aG9kcy5jb250YWlucyhtZXRob2ROYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIHZvaWQgbWV0aG9kQ2FsbGVkKFN0cmluZyBtZXRob2ROYW1lKSB7CisgICAgICAgICAgICBjYWxsZWRNZXRob2RzLmFkZChtZXRob2ROYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbmdpbmVJbml0U2lnbl9Qcml2YXRlS2V5X1NlY3VyZVJhbmRvbSgpIHsKKyAgICAgICAgTXlTaWduYXR1cmUgc2lnbmF0dXJlID0gbmV3IE15U2lnbmF0dXJlKCJkdW1teSIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaWduYXR1cmUuaW5pdFNpZ24obnVsbCwgbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTUEkgbWV0aG9kIG5vdCBjYWxsZWQiLCBzaWduYXR1cmUKKyAgICAgICAgICAgICAgICAgICAgLndhc01ldGhvZENhbGxlZCgiZW5naW5lSW5pdFNpZ25fUHJpdmF0ZUtleV9TZWN1cmVSYW5kb20iKSk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbmdpbmVTZXRQYXJhbWV0ZXIoKQorICAgIHsKKyAgICAgICAgTXlTaWduYXR1cmUgc2lnbmF0dXJlID0gbmV3IE15U2lnbmF0dXJlKCJkdW1teSIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaWduYXR1cmUuc2V0UGFyYW1ldGVyKG51bGwpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlNQSSBtZXRob2Qgbm90IGNhbGxlZCIsCisgICAgICAgICAgICAgICAgICAgIHNpZ25hdHVyZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC53YXNNZXRob2RDYWxsZWQoImVuZ2luZVNldFBhcmFtZXRlcl9BbGdvcml0aG1QYXJhbWV0ZXJTcGVjIikpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5naW5lU2lnbl9CSUkoKSB7CisgICAgICAgIE15U2lnbmF0dXJlIHNpZ25hdHVyZSA9IG5ldyBNeVNpZ25hdHVyZSgiZHVtbXkiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZ25hdHVyZS5pbml0U2lnbihuZXcgUHJpdmF0ZUtleSgpIHsKKworICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsxMF07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaWduYXR1cmUuc2lnbihidWYsIDIsIDEpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU1BJIG1ldGhvZCBub3QgY2FsbGVkIiwgc2lnbmF0dXJlCisgICAgICAgICAgICAgICAgICAgIC53YXNNZXRob2RDYWxsZWQoImVuZ2luZVNpZ25fW0JJSSIpKTsKKyAgICAgICAgfSBjYXRjaCAoU2lnbmF0dXJlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5naW5lVXBkYXRlX0J5dGVCdWZmZXIoKSB7CisgICAgICAgIE15U2lnbmF0dXJlIHNpZ25hdHVyZSA9IG5ldyBNeVNpZ25hdHVyZSgiZHVtbXkiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZ25hdHVyZS5pbml0U2lnbihuZXcgUHJpdmF0ZUtleSgpIHsKKworICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZ25hdHVyZS51cGRhdGUoQnl0ZUJ1ZmZlci53cmFwKCJIZWxsbyIuZ2V0Qnl0ZXMoKSkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU1BJIG1ldGhvZCBub3QgY2FsbGVkIiwgc2lnbmF0dXJlCisgICAgICAgICAgICAgICAgICAgIC53YXNNZXRob2RDYWxsZWQoImVuZ2luZVVwZGF0ZV9CeXRlQnVmZmVyIikpOworICAgICAgICB9IGNhdGNoIChTaWduYXR1cmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbmdpbmVWZXJpZnlfQklJKCkgeworICAgICAgICBNeVNpZ25hdHVyZSBzaWduYXR1cmUgPSBuZXcgTXlTaWduYXR1cmUoImR1bW15Iik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZ25hdHVyZS5pbml0VmVyaWZ5KG5ldyBQdWJsaWNLZXkoKSB7CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsxMF07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZ25hdHVyZS52ZXJpZnkoYnVmLCAyLCA1KTsKKyAgICAgICAgICAgIHNpZ25hdHVyZS53YXNNZXRob2RDYWxsZWQoImVuZ2luZVZlcmlmeV9bQklJIik7CisgICAgICAgIH0gY2F0Y2ggKFNpZ25hdHVyZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvU2lnbmF0dXJlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1NpZ25hdHVyZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMDBlMThhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1NpZ25hdHVyZVRlc3QuamF2YQpAQCAtMCwwICsxLDYzMCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQm9yaXMgVi4gS3V6bmV0c292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5Lbm93bkZhaWx1cmU7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0Lk15U2lnbmF0dXJlMTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+U2lnbmF0dXJlPC9jb2RlPiBjb25zdHJ1Y3RvciBhbmQgbWV0aG9kcworICoKKyAqLworcHVibGljIGNsYXNzIFNpZ25hdHVyZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIFNpZ25hdHVyZShTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdG9yKCkgeworICAgICAgICBTdHJpbmcgW10gYWxnb3JpdGhtcyA9IHsgIlNIQTI1NldJVEhSU0EiLCAiTk9ORVdJVEhEU0EiLCAiU0hBMzg0V0lUSFJTQSIsCisgICAgICAgICAgICAiTUQ1QU5EU0hBMVdJVEhSU0EiLCAiU0hBNTEyV0lUSFJTQSIsCisgICAgICAgICAgICAiU0hBMVdJVEhSU0EiLCAiU0hBMVdJVEhEU0EiLCAiTUQ1V0lUSFJTQSIgfTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGdvcml0aG1zLmxlbmd0aDsgaSArKykgeworICAgICAgICAgICAgTXlTaWduYXR1cmUxIHMgPSBuZXcgTXlTaWduYXR1cmUxKGFsZ29yaXRobXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFsZ29yaXRobXNbaV0scy5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKHMuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgcy5nZXRTdGF0ZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIE15U2lnbmF0dXJlMSBzMSA9IG5ldyBNeVNpZ25hdHVyZTEobnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoczEuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICBhc3NlcnROdWxsKHMxLmdldFByb3ZpZGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgczEuZ2V0U3RhdGUoKSk7CisKKyAgICAgICAgTXlTaWduYXR1cmUxIHMyID0gbmV3IE15U2lnbmF0dXJlMSgiQUJDREAjJl4lJCkoKiYiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJBQkNEQCMmXiUkKSgqJiIsIHMyLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChzMi5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHMyLmdldFN0YXRlKCkpOworICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3IgT2JqZWN0IGNsb25lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvbmUoKSB7CisgICAgICAgIE15U2lnbmF0dXJlMSBzID0gbmV3IE15U2lnbmF0dXJlMSgiQUJDIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmNsb25lKCk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBNeVNpZ25hdHVyZSBzYyA9IG5ldyBNeVNpZ25hdHVyZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2MuY2xvbmUoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFByb3ZpZGVyKCkgeworICAgICAgICBNeVNpZ25hdHVyZTEgcyA9IG5ldyBNeVNpZ25hdHVyZTEoIkFCQyIpOworCisgICAgICAgIGFzc2VydEVxdWFscygic3RhdGUiLCBNeVNpZ25hdHVyZTEuVU5JTklUSUFMSVpFRCwgcy5nZXRTdGF0ZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgicHJvdmlkZXIiLCBzLmdldFByb3ZpZGVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRBbGdvcml0aG0oKSB7CisgICAgICAgIE15U2lnbmF0dXJlMSBzID0gbmV3IE15U2lnbmF0dXJlMSgiQUJDIik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdGF0ZSIsIE15U2lnbmF0dXJlMS5VTklOSVRJQUxJWkVELCBzLmdldFN0YXRlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFsZ29yaXRobSIsICJBQkMiLCBzLmdldEFsZ29yaXRobSgpKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIHZvaWQgaW5pdFZlcmlmeShQdWJsaWNLZXkpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEluaXRWZXJpZnlQdWJsaWNLZXkoKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIE15U2lnbmF0dXJlMSBzID0gbmV3IE15U2lnbmF0dXJlMSgiQUJDIik7CisKKyAgICAgICAgcy5pbml0VmVyaWZ5KG5ldyBNeVB1YmxpY0tleSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdGF0ZSIsIE15U2lnbmF0dXJlMS5WRVJJRlksIHMuZ2V0U3RhdGUoKSk7CisgICAgICAgIGFzc2VydFRydWUoImluaXRWZXJpZnkoKSBmYWlsZWQiLCBzLnJ1bkVuZ2luZUluaXRWZXJpZnkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTaWduYXR1cmUgc2lnID0gZ2V0VGVzdFNpZ25hdHVyZSgpOworICAgICAgICAgICAgc2lnLmluaXRWZXJpZnkoKFB1YmxpY0tleSludWxsKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCA6ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3Igdm9pZCBpbml0VmVyaWZ5KENlcnRpZmljYXRlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbml0VmVyaWZ5Q2VydGlmaWNhdGUoKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIE15U2lnbmF0dXJlMSBzID0gbmV3IE15U2lnbmF0dXJlMSgiQUJDIik7CisKKyAgICAgICAgcy5pbml0VmVyaWZ5KG5ldyBNeUNlcnRpZmljYXRlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInN0YXRlIiwgTXlTaWduYXR1cmUxLlZFUklGWSwgcy5nZXRTdGF0ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaW5pdFZlcmlmeSgpIGZhaWxlZCIsIHMucnVuRW5naW5lSW5pdFZlcmlmeSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNpZ25hdHVyZSBzaWcgPSBnZXRUZXN0U2lnbmF0dXJlKCk7CisgICAgICAgICAgICBzaWcuaW5pdFZlcmlmeShuZXcgTXlDZXJ0aWZpY2F0ZSgpKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIEludmFsaWRLZXlFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCA6ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3Igdm9pZCBpbml0U2lnbihQcml2YXRlS2V5KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbml0U2lnblByaXZhdGVLZXkoKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIE15U2lnbmF0dXJlMSBzID0gbmV3IE15U2lnbmF0dXJlMSgiQUJDIik7CisKKyAgICAgICAgcy5pbml0U2lnbihuZXcgTXlQcml2YXRlS2V5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInN0YXRlIiwgTXlTaWduYXR1cmUxLlNJR04sIHMuZ2V0U3RhdGUoKSk7CisgICAgICAgIGFzc2VydFRydWUoImluaXRTaWduKCkgZmFpbGVkIiwgcy5ydW5FbmdpbmVJbml0U2lnbik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNpZ25hdHVyZSBzaWduYXR1cmUgPSBnZXRUZXN0U2lnbmF0dXJlKCk7CisgICAgICAgICAgICBzaWduYXR1cmUuaW5pdFNpZ24obnVsbCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBJbnZhbGlkS2V5RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQ6ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgU2lnbmF0dXJlIGdldFRlc3RTaWduYXR1cmUoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIgPSBuZXcgTXlQcm92aWRlcigiVGVzdFByb3ZpZGVyIiwgMS4wLCAiVGVzdCBQcm92aWRlciIsICJTaWduYXR1cmUuQUJDIiwgTXlTaWduYXR1cmUuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgU2VjdXJpdHkuaW5zZXJ0UHJvdmlkZXJBdChwcm92aWRlciwgMSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIkFCQyIpOworICAgICAgICB9CisgICAgICAgIGZpbmFsbHkgeworICAgICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcigiVGVzdFByb3ZpZGVyIik7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3Igdm9pZCBpbml0U2lnbihQcml2YXRlS2V5LCBTZWN1cmVSYW5kb20pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEluaXRTaWduUHJpdmF0ZUtleVNlY3VyZVJhbmRvbSgpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgTXlTaWduYXR1cmUxIHMgPSBuZXcgTXlTaWduYXR1cmUxKCJBQkMiKTsKKworICAgICAgICBzLmluaXRTaWduKG5ldyBNeVByaXZhdGVLZXkoKSwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdGF0ZSIsIE15U2lnbmF0dXJlMS5TSUdOLCBzLmdldFN0YXRlKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJpbml0U2lnbigpIGZhaWxlZCIsIHMucnVuRW5naW5lSW5pdFNpZ24pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTaWduYXR1cmUgc2lnID0gZ2V0VGVzdFNpZ25hdHVyZSgpOworICAgICAgICAgICAgc2lnLmluaXRTaWduKG51bGwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSW52YWxpZEtleUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIDogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciBieXRlW10gc2lnbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNpZ24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTXlTaWduYXR1cmUxIHMgPSBuZXcgTXlTaWduYXR1cmUxKCJBQkMiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMuc2lnbigpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgU2lnbmF0dXJlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFNpZ25hdHVyZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBzLmluaXRWZXJpZnkobmV3IE15UHVibGljS2V5KCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLnNpZ24oKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIFNpZ25hdHVyZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTaWduYXR1cmVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgcy5pbml0U2lnbihuZXcgTXlQcml2YXRlS2V5KCkpOworICAgICAgICBzLnNpZ24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdGF0ZSIsIE15U2lnbmF0dXJlMS5TSUdOLCBzLmdldFN0YXRlKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJzaWduKCkgZmFpbGVkIiwgcy5ydW5FbmdpbmVTaWduKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIHNpZ24oYnl0ZVtdLCBvZmZzZXQsIGxlbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2lnbmJ5dGVpbnRpbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTXlTaWduYXR1cmUxIHMgPSBuZXcgTXlTaWduYXR1cmUxKCJBQkMiKTsKKyAgICAgICAgYnl0ZVtdIG91dGJ1ZiA9IG5ldyBieXRlIFsxMF07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLnNpZ24ob3V0YnVmLCAwLCBvdXRidWYubGVuZ3RoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIFNpZ25hdHVyZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTaWduYXR1cmVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgcy5pbml0VmVyaWZ5KG5ldyBNeVB1YmxpY0tleSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5zaWduKG91dGJ1ZiwgMCwgb3V0YnVmLmxlbmd0aCk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBTaWduYXR1cmVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoU2lnbmF0dXJlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHMuaW5pdFNpZ24obmV3IE15UHJpdmF0ZUtleSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMuZ2V0QnVmZmVyTGVuZ3RoKCksIHMuc2lnbihvdXRidWYsIDAsIG91dGJ1Zi5sZW5ndGgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdGF0ZSIsIE15U2lnbmF0dXJlMS5TSUdOLCBzLmdldFN0YXRlKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJzaWduKCkgZmFpbGVkIiwgcy5ydW5FbmdpbmVTaWduKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5pbml0U2lnbihuZXcgTXlQcml2YXRlS2V5KCkpOworICAgICAgICAgICAgcy5zaWduKG91dGJ1Ziwgb3V0YnVmLmxlbmd0aCwgMCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBTaWduYXR1cmVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoU2lnbmF0dXJlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5pbml0U2lnbihuZXcgTXlQcml2YXRlS2V5KCkpOworICAgICAgICAgICAgcy5zaWduKG91dGJ1Ziwgb3V0YnVmLmxlbmd0aCwgMyk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgIH0KKworCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciBib29sZWFuIHZlcmlmeShieXRlW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFZlcmlmeWJ5dGVBcnJheSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNeVNpZ25hdHVyZTEgcyA9IG5ldyBNeVNpZ25hdHVyZTEoIkFCQyIpOworICAgICAgICBieXRlW10gYiA9IHsxLCAyLCAzLCA0fTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMudmVyaWZ5KGIpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgU2lnbmF0dXJlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFNpZ25hdHVyZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBzLmluaXRTaWduKG5ldyBNeVByaXZhdGVLZXkoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLnZlcmlmeShiKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIFNpZ25hdHVyZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTaWduYXR1cmVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgcy5pbml0VmVyaWZ5KG5ldyBNeVB1YmxpY0tleSgpKTsKKyAgICAgICAgcy52ZXJpZnkoYik7CisgICAgICAgIGFzc2VydEVxdWFscygic3RhdGUiLCBNeVNpZ25hdHVyZTEuVkVSSUZZLCBzLmdldFN0YXRlKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJ2ZXJpZnkoKSBmYWlsZWQiLCBzLnJ1bkVuZ2luZVZlcmlmeSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciBib29sZWFuIHZlcmlmeShieXRlW10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RWZXJpZnlieXRlQXJyYXlpbnRpbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTXlTaWduYXR1cmUxIHMgPSBuZXcgTXlTaWduYXR1cmUxKCJBQkMiKTsKKyAgICAgICAgYnl0ZVtdIGIgPSB7MSwgMiwgMywgNH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLnZlcmlmeShiLCAwLCAzKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIFNpZ25hdHVyZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTaWduYXR1cmVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgcy5pbml0U2lnbihuZXcgTXlQcml2YXRlS2V5KCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLnZlcmlmeShiLCAwLCAzKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIFNpZ25hdHVyZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTaWduYXR1cmVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgcy5pbml0VmVyaWZ5KG5ldyBNeVB1YmxpY0tleSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy52ZXJpZnkoYiwgMCwgNSk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHMudmVyaWZ5KGIsIDAsIDMpOworICAgICAgICBhc3NlcnRFcXVhbHMoInN0YXRlIiwgTXlTaWduYXR1cmUxLlZFUklGWSwgcy5nZXRTdGF0ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidmVyaWZ5KCkgZmFpbGVkIiwgcy5ydW5FbmdpbmVWZXJpZnkpOworICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3Igdm9pZCB1cGRhdGUoYnl0ZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXBkYXRlYnl0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNeVNpZ25hdHVyZTEgcyA9IG5ldyBNeVNpZ25hdHVyZTEoIkFCQyIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy51cGRhdGUoKGJ5dGUpMSk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBTaWduYXR1cmVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoU2lnbmF0dXJlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHMuaW5pdFZlcmlmeShuZXcgTXlQdWJsaWNLZXkoKSk7CisgICAgICAgIHMudXBkYXRlKChieXRlKSAxKTsKKyAgICAgICAgcy5pbml0U2lnbihuZXcgTXlQcml2YXRlS2V5KCkpOworICAgICAgICBzLnVwZGF0ZSgoYnl0ZSkgMSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdGF0ZSIsIE15U2lnbmF0dXJlMS5TSUdOLCBzLmdldFN0YXRlKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJ1cGRhdGUoKSBmYWlsZWQiLCBzLnJ1bkVuZ2luZVVwZGF0ZTEpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTaWduYXR1cmUgc2lnID0gZ2V0VGVzdFNpZ25hdHVyZSgpOworICAgICAgICAgICAgc2lnLnVwZGF0ZSgoYnl0ZSkgNDIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgU2lnbmF0dXJlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFNpZ25hdHVyZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciB2b2lkIHVwZGF0ZShieXRlW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVwZGF0ZWJ5dGVBcnJheSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNeVNpZ25hdHVyZTEgcyA9IG5ldyBNeVNpZ25hdHVyZTEoIkFCQyIpOworICAgICAgICBieXRlW10gYiA9IHsxLCAyLCAzLCA0fTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMudXBkYXRlKGIpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgU2lnbmF0dXJlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFNpZ25hdHVyZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBzLmluaXRWZXJpZnkobmV3IE15UHVibGljS2V5KCkpOworICAgICAgICBzLnVwZGF0ZShiKTsKKyAgICAgICAgcy5pbml0U2lnbihuZXcgTXlQcml2YXRlS2V5KCkpOworICAgICAgICBzLnVwZGF0ZShiKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoInN0YXRlIiwgTXlTaWduYXR1cmUxLlNJR04sIHMuZ2V0U3RhdGUoKSk7CisgICAgICAgIGFzc2VydFRydWUoInVwZGF0ZSgpIGZhaWxlZCIsIHMucnVuRW5naW5lVXBkYXRlMik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNpZ25hdHVyZSBzaWcgPSBnZXRUZXN0U2lnbmF0dXJlKCk7CisgICAgICAgICAgICBzaWcudXBkYXRlKGIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgU2lnbmF0dXJlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFNpZ25hdHVyZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNpZ25hdHVyZSBzaWcgPSBnZXRUZXN0U2lnbmF0dXJlKCk7CisgICAgICAgICAgICBzaWcudXBkYXRlKChieXRlW10pbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTaWduYXR1cmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3Igdm9pZCB1cGRhdGUoYnl0ZVtdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXBkYXRlYnl0ZUFycmF5aW50aW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE15U2lnbmF0dXJlMSBzID0gbmV3IE15U2lnbmF0dXJlMSgiQUJDIik7CisgICAgICAgIGJ5dGVbXSBiID0gezEsIDIsIDMsIDR9OworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy51cGRhdGUoYiwgMCwgMyk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBTaWduYXR1cmVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoU2lnbmF0dXJlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHMuaW5pdFZlcmlmeShuZXcgTXlQdWJsaWNLZXkoKSk7CisgICAgICAgIHMudXBkYXRlKGIsIDAsIDMpOworICAgICAgICBzLmluaXRTaWduKG5ldyBNeVByaXZhdGVLZXkoKSk7CisgICAgICAgIHMudXBkYXRlKGIsIDAsIDMpOworCisgICAgICAgIGFzc2VydEVxdWFscygic3RhdGUiLCBNeVNpZ25hdHVyZTEuU0lHTiwgcy5nZXRTdGF0ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidXBkYXRlKCkgZmFpbGVkIiwgcy5ydW5FbmdpbmVVcGRhdGUyKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy51cGRhdGUoYiwgMywgMCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy51cGRhdGUoYiwgMCwgYi5sZW5ndGggKyAxKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLnVwZGF0ZShiLCAtMSwgYi5sZW5ndGgpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIHZvaWQgdXBkYXRlKGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgiQW5kcm9pZCB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBSSSB0aHJvd3MgTnVsbHBvaW50ZXJFeGNlcHRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RVcGRhdGVieXRlQXJyYXlpbnRpbnQyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE15U2lnbmF0dXJlMSBzID0gbmV3IE15U2lnbmF0dXJlMSgiQUJDIik7CisgICAgICAgIGJ5dGVbXSBiID0gezEsIDIsIDMsIDR9OworCisgICAgICAgIHMuaW5pdFZlcmlmeShuZXcgTXlQdWJsaWNLZXkoKSk7CisgICAgICAgIHMudXBkYXRlKGIsIDAsIDMpOworICAgICAgICBzLmluaXRTaWduKG5ldyBNeVByaXZhdGVLZXkoKSk7CisgICAgICAgIHMudXBkYXRlKGIsIDAsIDMpOworCisgICAgICAgIGFzc2VydEVxdWFscygic3RhdGUiLCBNeVNpZ25hdHVyZTEuU0lHTiwgcy5nZXRTdGF0ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidXBkYXRlKCkgZmFpbGVkIiwgcy5ydW5FbmdpbmVVcGRhdGUyKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy51cGRhdGUobnVsbCwgMCwgMyk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciB2b2lkIHNldFBhcmFtZXRlcihTdHJpbmcsIE9iamVjdCkKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRQYXJhbWV0ZXJTdHJpbmdPYmplY3QoKSB7CisgICAgICAgIE15U2lnbmF0dXJlMSBzID0gbmV3IE15U2lnbmF0dXJlMSgiQUJDIik7CisgICAgICAgIHMuc2V0UGFyYW1ldGVyKCJhYWEiLCBuZXcgT2JqZWN0KCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTaWduYXR1cmUgc2lnID0gZ2V0VGVzdFNpZ25hdHVyZSgpOworICAgICAgICAgICAgc2lnLnNldFBhcmFtZXRlcigiVGVzdFBhcmFtIiwgbmV3IEludGVnZXIoNDIpKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZDogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciB2b2lkIHNldFBhcmFtZXRlcihBbGdvcml0aG1QYXJhbWV0ZXJTcGVjKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRQYXJhbWV0ZXJBbGdvcml0aG1QYXJhbWV0ZXJTcGVjKCkgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBNeVNpZ25hdHVyZTEgcyA9IG5ldyBNeVNpZ25hdHVyZTEoIkFCQyIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5zZXRQYXJhbWV0ZXIoKGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjKW51bGwpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSl7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2lnbmF0dXJlIHNpZyA9IGdldFRlc3RTaWduYXR1cmUoKTsKKyAgICAgICAgICAgIHNpZy5zZXRQYXJhbWV0ZXIobmV3IEFsZ29yaXRobVBhcmFtZXRlclNwZWMoKSB7fSk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZDogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZDogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UGFyYW1ldGVyKCkgeworICAgICAgICBNeVNpZ25hdHVyZTEgcyA9IG5ldyBNeVNpZ25hdHVyZTEoIkFCQyIpOworICAgICAgICBzLmdldFBhcmFtZXRlcigiYWFhIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE15U2lnbmF0dXJlIHNlID0gbmV3IE15U2lnbmF0dXJlKCk7CisgICAgICAgICAgICBzZS5nZXRQYXJhbWV0ZXIoInRlc3QiKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIE15S2V5IGltcGxlbWVudHMgS2V5IHsKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRGb3JtYXQoKSB7CisgICAgICAgICAgICByZXR1cm4gIjEyMyI7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgICAgICByZXR1cm4gImFhYSI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIE15UHVibGljS2V5IGV4dGVuZHMgTXlLZXkgaW1wbGVtZW50cyBQdWJsaWNLZXkge30KKworICAgIHByaXZhdGUgY2xhc3MgTXlQcml2YXRlS2V5IGV4dGVuZHMgTXlLZXkgaW1wbGVtZW50cyBQcml2YXRlS2V5IHt9CisKKyAgICBwcml2YXRlIGNsYXNzIE15Q2VydGlmaWNhdGUgZXh0ZW5kcyBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGUgeworICAgICAgICBwdWJsaWMgIE15Q2VydGlmaWNhdGUoKSB7CisgICAgICAgICAgICBzdXBlcigiTXlDZXJ0aWZpY2F0ZVR5cGUiKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBQdWJsaWNLZXkgZ2V0UHVibGljS2V5KCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBNeVB1YmxpY0tleSgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIHZvaWQgdmVyaWZ5KFB1YmxpY0tleSBrZXkpIHt9CisKKyAgICAgICAgcHVibGljIHZvaWQgdmVyaWZ5KFB1YmxpY0tleSBrZXksIFN0cmluZyBzaWdQcm92aWRlcikge30KKworICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuICJNeUNlcnRpZmljYXRlIjsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgIHByb3RlY3RlZCBzdGF0aWMgY2xhc3MgTXlTaWduYXR1cmUgZXh0ZW5kcyBTaWduYXR1cmUgaW1wbGVtZW50cyBDbG9uZWFibGUgeworCisgICAgICAgIHB1YmxpYyBNeVNpZ25hdHVyZSgpIHsKKyAgICAgICAgICAgIHN1cGVyKCJUZXN0U2lnbmF0dXJlIik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIE9iamVjdCBlbmdpbmVHZXRQYXJhbWV0ZXIoU3RyaW5nIHBhcmFtKQorICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdFNpZ24oUHJpdmF0ZUtleSBwcml2YXRlS2V5KQorICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdFZlcmlmeShQdWJsaWNLZXkgcHVibGljS2V5KQorICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lU2V0UGFyYW1ldGVyKFN0cmluZyBwYXJhbSwgT2JqZWN0IHZhbHVlKQorICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVTaWduKCkgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZSBiKSB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTaWduYXR1cmVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pCisgICAgICAgICAgICAgICAgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBlbmdpbmVWZXJpZnkoYnl0ZVtdIHNpZ0J5dGVzKQorICAgICAgICAgICAgICAgIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVNldFBhcmFtZXRlcihBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtcykKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAocGFyYW1zID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBNeVByb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXIgeworCisgICAgICAgIHByb3RlY3RlZCBNeVByb3ZpZGVyKFN0cmluZyBuYW1lLCBkb3VibGUgdmVyc2lvbiwgU3RyaW5nIGluZm8sIFN0cmluZyBzaWduYW1lLCBTdHJpbmcgY2xhc3NOYW1lKSB7CisgICAgICAgICAgICBzdXBlcihuYW1lLCB2ZXJzaW9uLCBpbmZvKTsKKyAgICAgICAgICAgIHB1dChzaWduYW1lLCBjbGFzc05hbWUpOworICAgICAgICB9CisKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvU2lnbmVkT2JqZWN0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1NpZ25lZE9iamVjdFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Yjk4YmUzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1NpZ25lZE9iamVjdFRlc3QuamF2YQpAQCAtMCwwICsxLDcxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduZWRPYmplY3Q7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5UZXN0S2V5UGFpcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduZWRPYmplY3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkludmFsaWRLZXlTcGVjRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5TaWduZWRPYmplY3Q8L2NvZGU+IGNvbnN0cnVjdG9yIGFuZCBtZXRob2RzCisgKi8KK3B1YmxpYyBjbGFzcyBTaWduZWRPYmplY3RUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdFNpZ25lZE9iamVjdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0S2V5UGFpciB0a3AgPSBudWxsOworICAgICAgICBQcm9wZXJ0aWVzIHByb3A7CisgICAgICAgIFNpZ25hdHVyZSBzaWcgPSBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIlNIQTF3aXRoRFNBIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRrcCA9IG5ldyBUZXN0S2V5UGFpcigiRFNBIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHByb3AgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICBwcm9wLnB1dCgiYWFhIiwgImJiYiIpOworCisgICAgICAgIFNpZ25lZE9iamVjdCBzbyA9IG5ldyBTaWduZWRPYmplY3QocHJvcCwgdGtwLmdldFByaXZhdGUoKSwgc2lnKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlNIQTF3aXRoRFNBIiwgc28uZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMocHJvcCwgc28uZ2V0T2JqZWN0KCkpOworCisgICAgICAgIGFzc2VydFRydWUoInZlcmlmeSgpIGZhaWxlZCIsIHNvLnZlcmlmeSh0a3AuZ2V0UHVibGljKCksIHNpZykpOworCisgICAgICAgIGFzc2VydE5vdE51bGwoInNpZ25hdHVyZSBpcyBudWxsIiwgc28uZ2V0U2lnbmF0dXJlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9TaWduZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvU2lnbmVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAxOGMyYzQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvU2lnbmVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTYzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGVrc2VpIFkuIFNlbWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSWRlbnRpdHlTY29wZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlNYW5hZ2VtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5UGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25lcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlByaXZhdGVLZXlTdHViOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlB1YmxpY0tleVN0dWI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuU2lnbmVyU3R1YjsKKworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIHRlc3RzIGZvciBjbGFzcyBTaWduZXIKKyAqCisgKi8KK0BTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCitwdWJsaWMgY2xhc3MgU2lnbmVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTXlTZWN1cml0eU1hbmFnZXIgZXh0ZW5kcyBTZWN1cml0eU1hbmFnZXIgeworICAgICAgICBwdWJsaWMgUGVybWlzc2lvbnMgZGVuaWVkID0gbmV3IFBlcm1pc3Npb25zKCk7CisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihQZXJtaXNzaW9uIHBlcm1pc3Npb24peworICAgICAgICAgICAgaWYgKGRlbmllZCE9bnVsbCAmJiBkZW5pZWQuaW1wbGllcyhwZXJtaXNzaW9uKSkgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LlNpZ25lciN0b1N0cmluZygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF90b1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTaWduZXIgczEgPSBuZXcgU2lnbmVyU3R1YigidGVzdFRvU3RyaW5nMSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIltTaWduZXJddGVzdFRvU3RyaW5nMSIsIHMxLnRvU3RyaW5nKCkpOworCisgICAgICAgIFNpZ25lciBzMiA9IG5ldyBTaWduZXJTdHViKCJ0ZXN0VG9TdHJpbmcyIiwgSWRlbnRpdHlTY29wZS5nZXRTeXN0ZW1TY29wZSgpKTsKKyAgICAgICAgczIudG9TdHJpbmcoKTsKKworICAgICAgICBLZXlQYWlyIGtwID0gbmV3IEtleVBhaXIobmV3IFB1YmxpY0tleVN0dWIoInB1YmxpYyIsICJTaWduZXJUZXN0LnRlc3RUb1N0cmluZyIsIG51bGwpLAorICAgICAgICAgICAgICAgIG5ldyBQcml2YXRlS2V5U3R1YigicHJpdmF0ZSIsICJTaWduZXJUZXN0LnRlc3RUb1N0cmluZyIsIG51bGwpKTsKKyAgICAgICAgczEuc2V0S2V5UGFpcihrcCk7CisgICAgICAgIHMxLnRvU3RyaW5nKCk7CisKKyAgICAgICAgczIuc2V0S2V5UGFpcihrcCk7CisgICAgICAgIHMyLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogdmVyaWZ5IFNpZ25lcigpIGNyZWF0ZXMgaW5zdGFuY2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2lnbmVyKCkgeworICAgICAgICBTaWduZXIgcyA9IG5ldyBTaWduZXJTdHViKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwocyk7CisgICAgICAgIC8vYXNzZXJ0TnVsbChzLmdldE5hbWUoKSwgcy5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnROdWxsKHMuZ2V0UHJpdmF0ZUtleSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB2ZXJpZnkgU2lnbmVyKFN0cmluZykgY3JlYXRlcyBpbnN0YW5jZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTaWduZXJTdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2lnbmVyIHMgPSBuZXcgU2lnbmVyU3R1Yigic3NzMyIpOworICAgICAgICBhc3NlcnROb3ROdWxsKHMpOworICAgICAgICBhc3NlcnRFcXVhbHMoInNzczMiLCBzLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydE51bGwocy5nZXRQcml2YXRlS2V5KCkpOworCisgICAgICAgIFNpZ25lciBzMiA9IG5ldyBTaWduZXJTdHViKG51bGwpOworICAgICAgICBhc3NlcnROdWxsKHMyLmdldE5hbWUoKSk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB2ZXJpZnkgIFNpZ25lcihTdHJpbmcsIElkZW50aXR5U2NvcGUpIGNyZWF0ZXMgaW5zdGFuY2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2lnbmVyU3RyaW5nSWRlbnRpdHlTY29wZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTaWduZXIgcyA9IG5ldyBTaWduZXJTdHViKCJzc3M0IiwgSWRlbnRpdHlTY29wZS5nZXRTeXN0ZW1TY29wZSgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzc3M0Iiwgcy5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRTYW1lKElkZW50aXR5U2NvcGUuZ2V0U3lzdGVtU2NvcGUoKSwgcy5nZXRTY29wZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChzLmdldFByaXZhdGVLZXkoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNpZ25lciBzMiA9IG5ldyBTaWduZXJTdHViKCJzc3M0IiwgSWRlbnRpdHlTY29wZS5nZXRTeXN0ZW1TY29wZSgpKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIEtleU1hbmFnZW1lbnRFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIGUpCisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICBTaWduZXIgczIgPSBuZXcgU2lnbmVyU3R1YihudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChzMi5nZXROYW1lKCkpOworCisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB2ZXJpZnkgU2lnbmVyLmdldFByaXZhdGVLZXkoKSByZXR1cm5zIG51bGwgb3IgcHJpdmF0ZSBrZXkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UHJpdmF0ZUtleSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlIFtdIHByaXZhdGVLZXlEYXRhID0geyAxLCAyLCAzLCA0LCA1fTsKKyAgICAgICAgUHJpdmF0ZUtleVN0dWIgcHJpdmF0ZUtleSA9IG5ldyBQcml2YXRlS2V5U3R1YigicHJpdmF0ZSIsICJmZmYiLCBwcml2YXRlS2V5RGF0YSk7CisgICAgICAgIFB1YmxpY0tleVN0dWIgcHVibGljS2V5ID0gbmV3IFB1YmxpY0tleVN0dWIoInB1YmxpYyIsICJmZmYiLCBudWxsKTsKKyAgICAgICAgS2V5UGFpciBrcCA9IG5ldyBLZXlQYWlyKHB1YmxpY0tleSwgcHJpdmF0ZUtleSk7CisKKyAgICAgICAgU2lnbmVyIHMgPSBuZXcgU2lnbmVyU3R1Yigic3NzNSIpOworCisgICAgICAgIGFzc2VydE51bGwocy5nZXRQcml2YXRlS2V5KCkpOworCisgICAgICAgIHMuc2V0S2V5UGFpcihrcCk7CisgICAgICAgIGFzc2VydFNhbWUocHJpdmF0ZUtleSwgcy5nZXRQcml2YXRlS2V5KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuU2lnbmVyI3NldEtleVBhaXIoamF2YS5zZWN1cml0eS5LZXlQYWlyKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0S2V5UGFpckxqYXZhX3NlY3VyaXR5X0tleVBhaXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTI0MDgKKyAgICAgICAgLy8gdGVzdDogTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgcGFpciBpcyBudWxsCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2lnbmVyU3R1YigibmFtZSIpLnNldEtleVBhaXIobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5UGFpciBrcCA9IG5ldyBLZXlQYWlyKG51bGwsIG51bGwpOworICAgICAgICAgICAgU2lnbmVyU3R1YiBzID0gbmV3IFNpZ25lclN0dWIoIm5hbWUiKTsKKyAgICAgICAgICAgIHMuc2V0S2V5UGFpcihrcCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9UaW1lc3RhbXBUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvVGltZXN0YW1wVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiYTdhNjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvVGltZXN0YW1wVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyAqIEBhdXRob3IgQWxleGFuZGVyIFYuIEFzdGFwY2h1aworICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlRpbWVzdGFtcDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGg7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0Lk15Q2VydFBhdGg7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlRpbWVzdGFtcDwvY29kZT4gY2xhc3MgZmllbGRzIGFuZCBtZXRob2RzCisgKgorICovCisKK3B1YmxpYyBjbGFzcyBUaW1lc3RhbXBUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHByaXZhdGUgRGF0ZSBub3cgPSBuZXcgRGF0ZSgpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIGVuY29kaW5nID0geyAxLCAyLCAzIH07CisKKyAgICBwcml2YXRlIENlcnRQYXRoIGNwYXRoID0gbmV3IE15Q2VydFBhdGgoZW5jb2RpbmcpOworCisgICAgcHVibGljIHZvaWQgdGVzdFRpbWVzdGFtcCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBUaW1lc3RhbXAobnVsbCwgY3BhdGgpOworICAgICAgICAgICAgZmFpbCgibnVsbCB3YXMgYWNjZXB0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXgpIHsgLyogb2sgKi8KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVGltZXN0YW1wKG5vdywgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJudWxsIHdhcyBhY2NlcHRlZCIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleCkgeyAvKiBvayAqLworICAgICAgICB9CisKKyAgICAgICAgVGltZXN0YW1wIHRpbWVzdGFtcCA9IG5ldyBUaW1lc3RhbXAobm93LCBjcGF0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygibm90IGV4cGVjdGVkIHZhbHVlIiwgbm93LCB0aW1lc3RhbXAuZ2V0VGltZXN0YW1wKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5vdCBleHBlY3RlZCBjZXJ0IHBhdGgiLCBjcGF0aCwgdGltZXN0YW1wLmdldFNpZ25lckNlcnRQYXRoKCkpOworICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3IgYm9vbGVhbiBlcXVhbHMoT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHNPYmplY3QoKSB7CisgICAgICAgIFRpbWVzdGFtcCBvbmUgPSBuZXcgVGltZXN0YW1wKG5vdywgY3BhdGgpOworICAgICAgICBUaW1lc3RhbXAgdHdvID0gbmV3IFRpbWVzdGFtcChub3csIGNwYXRoKTsKKworICAgICAgICBhc3NlcnRUcnVlKG9uZS5lcXVhbHMob25lKSk7CisgICAgICAgIGFzc2VydFRydWUob25lLmVxdWFscyh0d28pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0d28uZXF1YWxzKG9uZSkpOworICAgICAgICBhc3NlcnRGYWxzZShvbmUuZXF1YWxzKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uob25lLmVxdWFscyhuZXcgT2JqZWN0KCkpKTsKKworICAgICAgICBUaW1lc3RhbXAgdHdvMSA9IG5ldyBUaW1lc3RhbXAobmV3IERhdGUoOTk5OSksIGNwYXRoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uob25lLmVxdWFscyh0d28xKSk7CisgICAgICAgIGFzc2VydFRydWUodHdvMS5lcXVhbHModHdvMSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRTaWduZXJDZXJ0UGF0aCgpIHsKKyAgICAgICAgYXNzZXJ0U2FtZShuZXcgVGltZXN0YW1wKG5vdywgY3BhdGgpLmdldFNpZ25lckNlcnRQYXRoKCksIGNwYXRoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VGltZXN0YW1wKCkgeworICAgIAlUaW1lc3RhbXAgdCA9IG5ldyBUaW1lc3RhbXAobm93LCBjcGF0aCk7CisgICAgICAgIGFzc2VydEVxdWFscyhub3csIHQuZ2V0VGltZXN0YW1wKCkpOworICAgICAgICBhc3NlcnROb3RTYW1lKG5vdywgdC5nZXRUaW1lc3RhbXAoKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciBTdHJpbmcgdG9TdHJpbmcoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RUb1N0cmluZygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyB0dCA9IG5ldyBUaW1lc3RhbXAobm93LCBjcGF0aCkudG9TdHJpbmcoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIFN0cmluZyBoYXNoQ29kZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEhhc2hDb2RlKCkgeworICAgICAgICBUaW1lc3RhbXAgb25lID0gbmV3IFRpbWVzdGFtcChub3csIGNwYXRoKTsKKyAgICAgICAgVGltZXN0YW1wIHR3byA9IG5ldyBUaW1lc3RhbXAobm93LCBjcGF0aCk7CisgICAgICAgIFRpbWVzdGFtcCB0aHJlZSA9IG5ldyBUaW1lc3RhbXAobm93LCBuZXcgTXlDZXJ0UGF0aChuZXcgYnl0ZVtdIHsgMTAsCisgICAgICAgICAgICAgICAgMjAsIDMwIH0pKTsKKyAgICAgICAgVGltZXN0YW1wIGZvdXIgPSBudWxsOworCisgICAgICAgIGFzc2VydFRydWUob25lLmhhc2hDb2RlKCkgPT0gdHdvLmhhc2hDb2RlKCkpOworICAgICAgICBhc3NlcnRUcnVlKG9uZS5oYXNoQ29kZSgpICE9IHRocmVlLmhhc2hDb2RlKCkpOworICAgICAgICBhc3NlcnRUcnVlKHR3by5oYXNoQ29kZSgpICE9IHRocmVlLmhhc2hDb2RlKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3VyLmhhc2hDb2RlKCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvVW5yZWNvdmVyYWJsZUVudHJ5RXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1VucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ODhiM2EwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9qYXZhL3NlY3VyaXR5L1VucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDY5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+VW5yZWNvdmVyYWJsZUVudHJ5RXhjZXB0aW9uPC9jb2RlPiBjbGFzcworICoKKyAqLworcHVibGljIGNsYXNzIFVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBzdGF0aWMgU3RyaW5nW10gbXNncyA9IHsKKyAgICAgICAgICAgICIiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSIgfTsKKworICAgIHN0YXRpYyBTdHJpbmcgZXJyTm90RXhjID0gIk5vdCBVbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb24gb2JqZWN0IjsKKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3Igdm9pZCBVbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb24oKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb24oKSB7CisgICAgICAgIFVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvbiB0RSA9IG5ldyBVbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb24oKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciB2b2lkIFVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvbihTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvblN0cmluZygpIHsKKyAgICAgICAgVW5yZWNvdmVyYWJsZUVudHJ5RXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IFVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvbihtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0RSA9IG5ldyBVbnJlY292ZXJhYmxlRW50cnlFeGNlcHRpb24obnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gIiArIGUgKyAiIHdhcyB0aHJvd24gZm9yIE5VTEwgcGFyYW1ldGVyIik7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvamF2YS9zZWN1cml0eS9VbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNmYjAyOGYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL2phdmEvc2VjdXJpdHkvVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDgwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLmphdmEuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb248L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQKKyAqIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBzdGF0aWMgU3RyaW5nW10gbXNncyA9IHsKKyAgICAgICAgICAgICIiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSIgfTsKKworICAgIHN0YXRpYyBUaHJvd2FibGUgdENhdXNlID0gbmV3IFRocm93YWJsZSgiVGhyb3dhYmxlIGZvciBleGNlcHRpb24iKTsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPlVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24oKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24wMSgpIHsKKyAgICAgICAgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiB0RSA9IG5ldyBVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPlVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4KKyAgICAgKiBQYXJhbWV0ZXIgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbjAyKCkgeworICAgICAgICBVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5VbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24gd2hlbiA8Y29kZT5tc2c8L2NvZGU+CisgICAgICogaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uMDMoKSB7CisgICAgICAgIFN0cmluZyBtc2cgPSBudWxsOworICAgICAgICBVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uIHRFID0gbmV3IFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24obXNnKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9DaXBoZXJTdWl0ZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0NpcGhlclN1aXRlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdhZGVjYWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9DaXBoZXJTdWl0ZVRlc3QuamF2YQpAQCAtMCwwICsxLDE2NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQucHJvdmlkZXIuanNzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YXguY3J5cHRvLkNpcGhlcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uTWFjOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuU3RhbmRhcmROYW1lczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlLkNpcGhlclN1aXRlOworCitwdWJsaWMgY2xhc3MgQ2lwaGVyU3VpdGVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0QnlOYW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoU3RyaW5nIG5hbWUgOiBTdGFuZGFyZE5hbWVzLkNJUEhFUl9TVUlURVMpIHsKKyAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyhTdGFuZGFyZE5hbWVzLkNJUEhFUl9TVUlURV9TRUNVUkVfUkVORUdPVElBVElPTikpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKENpcGhlclN1aXRlLmdldEJ5TmFtZShuYW1lKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRlc3RfQ2lwaGVyU3VpdGUobmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnROdWxsKENpcGhlclN1aXRlLmdldEJ5TmFtZSgiYm9ndXMiKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDaXBoZXJTdWl0ZS5nZXRCeU5hbWUobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdF9DaXBoZXJTdWl0ZShTdHJpbmcgbmFtZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENpcGhlclN1aXRlIGNzID0gQ2lwaGVyU3VpdGUuZ2V0QnlOYW1lKG5hbWUpOworICAgICAgICBhc3NlcnROb3ROdWxsKG5hbWUsIGNzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5hbWUsIGNzLmdldE5hbWUoKSk7CisgICAgICAgIHRlc3RfQ2lwaGVyU3VpdGUoY3MpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0X0NpcGhlclN1aXRlKENpcGhlclN1aXRlIGNzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjcyk7CisKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBjcy5nZXROYW1lKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwobmFtZSk7CisgICAgICAgIGFzc2VydFNhbWUobmFtZSwgY3MsIENpcGhlclN1aXRlLmdldEJ5TmFtZShuYW1lKSk7CisgICAgICAgIGFzc2VydFRydWUobmFtZSwgU3RhbmRhcmROYW1lcy5DSVBIRVJfU1VJVEVTLmNvbnRhaW5zKG5hbWUpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuYW1lLCBuYW1lLnN0YXJ0c1dpdGgoIlNTTF8iKSB8fCBuYW1lLnN0YXJ0c1dpdGgoIlRMU18iKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNzLmlzQW5vbnltb3VzKCksIG5hbWUuY29udGFpbnMoIl9hbm9uXyIpKTsKKworICAgICAgICBieXRlW10gYnl0ZXMgPSBjcy50b0J5dGVzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwobmFtZSwgYnl0ZXMpOworICAgICAgICBhc3NlcnRFcXVhbHMobmFtZSwgMiwgYnl0ZXMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuYW1lICsgYnl0ZXNbMF0sIGJ5dGVzWzBdID09IChieXRlKSAweDAwIHx8IGJ5dGVzWzBdID09IChieXRlKSAweGMwKTsKKyAgICAgICAgYXNzZXJ0U2FtZShuYW1lLCBjcywgQ2lwaGVyU3VpdGUuZ2V0QnlDb2RlKGJ5dGVzWzBdLCBieXRlc1sxXSkpOworICAgICAgICBhc3NlcnRTYW1lKG5hbWUsIGNzLCBDaXBoZXJTdWl0ZS5nZXRCeUNvZGUoKGJ5dGUpIDAsIGJ5dGVzWzBdLCBieXRlc1sxXSkpOworCisgICAgICAgIGFzc2VydFRydWUobmFtZSwgY3MudG9TdHJpbmcoKS5jb250YWlucyhuYW1lKSk7CisKKyAgICAgICAgU3RyaW5nIGJ1bGtFbmNyeXB0aW9uQWxnb3JpdGhtID0gY3MuZ2V0QnVsa0VuY3J5cHRpb25BbGdvcml0aG0oKTsKKyAgICAgICAgaW50IGJsb2NrU2l6ZSA9IGNzLmdldEJsb2NrU2l6ZSgpOworICAgICAgICBpZiAoYnVsa0VuY3J5cHRpb25BbGdvcml0aG0gPT0gbnVsbCkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShuYW1lLCBuYW1lLmNvbnRhaW5zKCJfTlVMTF8iKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobmFtZSwgMCwgYmxvY2tTaXplKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwobmFtZSwgQ2lwaGVyLmdldEluc3RhbmNlKGNzLmdldEJ1bGtFbmNyeXB0aW9uQWxnb3JpdGhtKCkpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUobmFtZSwgYmxvY2tTaXplID09IDAgfHwgYmxvY2tTaXplID09IDggfHwgYmxvY2tTaXplID09IDE2KTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBobWFjTmFtZSA9IGNzLmdldEhtYWNOYW1lKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwobmFtZSwgaG1hY05hbWUpOworICAgICAgICBhc3NlcnROb3ROdWxsKG5hbWUsIE1hYy5nZXRJbnN0YW5jZShobWFjTmFtZSkpOworCisgICAgICAgIFN0cmluZyBoYXNoTmFtZSA9IGNzLmdldEhhc2hOYW1lKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwobmFtZSwgaGFzaE5hbWUpOworICAgICAgICBhc3NlcnROb3ROdWxsKG5hbWUsIE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoaGFzaE5hbWUpKTsKKworICAgICAgICBpbnQgbWFjTGVuZ3RoID0gY3MuZ2V0TUFDTGVuZ3RoKCk7CisgICAgICAgIGFzc2VydFRydWUobmFtZSwgbWFjTGVuZ3RoID09IDAgfHwgbWFjTGVuZ3RoID09IDE2IHx8IG1hY0xlbmd0aCA9PSAyMCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShuYW1lLAorICAgICAgICAgICAgICAgICAgIGNzLmlzRXhwb3J0YWJsZSgpID09IG5hbWUuY29udGFpbnMoIl9FWFBPUlRfIikKKyAgICAgICAgICAgICAgICAgICB8fCBjcy5pc0V4cG9ydGFibGUoKSA9PSBuYW1lLmNvbnRhaW5zKCJfTlVMTF8iKSk7CisKKyAgICAgICAgU3RyaW5nIGtleVR5cGUgPSBjcy5nZXRTZXJ2ZXJLZXlUeXBlKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhuYW1lLCBjcy5pc0Fub255bW91cygpLCBrZXlUeXBlID09IG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKG5hbWUsIGtleVR5cGUgPT0gbnVsbCB8fCBTdGFuZGFyZE5hbWVzLktFWV9UWVBFUy5jb250YWlucyhrZXlUeXBlKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRCeUNvZGUoKSB7CisgICAgICAgIC8vIENpcGhlclN1aXRlLmdldEJ5Q29kZSBpcyBhbHNvIGNvdmVyZWQgYnkgdGVzdF9DaXBoZXJTdWl0ZQorICAgICAgICBhc3NlcnRVbmtub3duKENpcGhlclN1aXRlLmdldEJ5Q29kZSgoYnl0ZSkgMHgxMiwgKGJ5dGUpIDB4MzQpKTsKKyAgICAgICAgYXNzZXJ0VW5rbm93bihDaXBoZXJTdWl0ZS5nZXRCeUNvZGUoKGJ5dGUpIDB4MTIsIChieXRlKSAweDM0LCAoYnl0ZSkgMHg1NikpOworICAgICAgICBhc3NlcnRVbmtub3duKENpcGhlclN1aXRlLmdldEJ5Q29kZSgoYnl0ZSkgLTEsIChieXRlKSAtMSkpOworICAgICAgICBhc3NlcnRVbmtub3duKENpcGhlclN1aXRlLmdldEJ5Q29kZSgoYnl0ZSkgLTEsIChieXRlKSAtMSwgKGJ5dGUpIC0xKSk7CisgICAgfQorICAgIHByaXZhdGUgdm9pZCBhc3NlcnRVbmtub3duKENpcGhlclN1aXRlIGNzKSB7CisgICAgICAgIGFzc2VydE5vdE51bGwoY3MpOworICAgICAgICBhc3NlcnROb3ROdWxsKGNzLmdldE5hbWUoKS5jb250YWlucygiVU5LTk9XTiIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFN1cHBvcnRlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDaXBoZXJTdWl0ZVtdIHN1aXRlcyA9IENpcGhlclN1aXRlLmdldFN1cHBvcnRlZCgpOworICAgICAgICBMaXN0PFN0cmluZz4gbmFtZXMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oc3VpdGVzLmxlbmd0aCk7CisgICAgICAgIGZvciAoQ2lwaGVyU3VpdGUgY3MgOiBzdWl0ZXMpIHsKKyAgICAgICAgICAgIHRlc3RfQ2lwaGVyU3VpdGUoY3MpOworICAgICAgICAgICAgbmFtZXMuYWRkKGNzLmdldE5hbWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5hc0xpc3QoQ2lwaGVyU3VpdGUuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVOYW1lcygpKSwgbmFtZXMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVOYW1lcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmdbXSBuYW1lcyA9IENpcGhlclN1aXRlLmdldFN1cHBvcnRlZENpcGhlclN1aXRlTmFtZXMoKTsKKyAgICAgICAgU3RhbmRhcmROYW1lcy5hc3NlcnRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoU3RhbmRhcmROYW1lcy5DSVBIRVJfU1VJVEVTX1NTTEVOR0lORSwgbmFtZXMpOworICAgICAgICBmb3IgKFN0cmluZyBuYW1lIDogbmFtZXMpIHsKKyAgICAgICAgICAgIHRlc3RfQ2lwaGVyU3VpdGUobmFtZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldENsaWVudEtleVR5cGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZSBiID0gQnl0ZS5NSU5fVkFMVUU7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIFN0cmluZyBieXRlU3RyaW5nID0gQnl0ZS50b1N0cmluZyhiKTsKKyAgICAgICAgICAgIFN0cmluZyBrZXlUeXBlID0gQ2lwaGVyU3VpdGUuZ2V0Q2xpZW50S2V5VHlwZShiKTsKKyAgICAgICAgICAgIHN3aXRjaCAoYikgeworICAgICAgICAgICAgICAgIGNhc2UgMToKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGJ5dGVTdHJpbmcsICJSU0EiLCBrZXlUeXBlKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAyOgorICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYnl0ZVN0cmluZywgIkRTQSIsIGtleVR5cGUpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIDM6CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhieXRlU3RyaW5nLCAiREhfUlNBIiwga2V5VHlwZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgNDoKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGJ5dGVTdHJpbmcsICJESF9EU0EiLCBrZXlUeXBlKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSA2NDoKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGJ5dGVTdHJpbmcsICJFQyIsIGtleVR5cGUpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIDY1OgorICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYnl0ZVN0cmluZywgIkVDX1JTQSIsIGtleVR5cGUpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIDY2OgorICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYnl0ZVN0cmluZywgIkVDX0VDIiwga2V5VHlwZSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgIGFzc2VydE51bGwoYnl0ZVN0cmluZywga2V5VHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBiKys7CisgICAgICAgIH0gd2hpbGUgKGIgIT0gQnl0ZS5NSU5fVkFMVUUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0NsaWVudFNlc3Npb25Db250ZXh0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvQ2xpZW50U2Vzc2lvbkNvbnRleHRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzM3OGE5YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL0NsaWVudFNlc3Npb25Db250ZXh0VGVzdC5qYXZhCkBAIC0wLDAgKzEsOTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2U7CisKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGxpYmNvcmUuamF2YXgubmV0LnNzbC5GYWtlU1NMU2Vzc2lvbjsKKworcHVibGljIGZpbmFsIGNsYXNzIENsaWVudFNlc3Npb25Db250ZXh0VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRTZXNzaW9uQnlJZCgpIHsKKyAgICAgICAgQ2xpZW50U2Vzc2lvbkNvbnRleHQgY29udGV4dCA9IG5ldyBDbGllbnRTZXNzaW9uQ29udGV4dCgpOworCisgICAgICAgIFNTTFNlc3Npb24gYSA9IG5ldyBWYWxpZFNTTFNlc3Npb24oImEiKTsKKyAgICAgICAgU1NMU2Vzc2lvbiBiID0gbmV3IFZhbGlkU1NMU2Vzc2lvbigiYiIpOworCisgICAgICAgIGNvbnRleHQucHV0U2Vzc2lvbihhKTsKKyAgICAgICAgY29udGV4dC5wdXRTZXNzaW9uKGIpOworCisgICAgICAgIGFzc2VydFNhbWUoYSwgY29udGV4dC5nZXRTZXNzaW9uKCJhIi5nZXRCeXRlcygpKSk7CisgICAgICAgIGFzc2VydFNhbWUoYiwgY29udGV4dC5nZXRTZXNzaW9uKCJiIi5nZXRCeXRlcygpKSk7CisKKyAgICAgICAgYXNzZXJ0U2FtZShhLCBjb250ZXh0LmdldFNlc3Npb24oImEiLCA0NDMpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShiLCBjb250ZXh0LmdldFNlc3Npb24oImIiLCA0NDMpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgY29udGV4dC5zaXplKCkpOworCisgICAgICAgIFNldDxTU0xTZXNzaW9uPiBzZXNzaW9ucyA9IG5ldyBIYXNoU2V0PFNTTFNlc3Npb24+KCk7CisgICAgICAgIEVudW1lcmF0aW9uIGlkcyA9IGNvbnRleHQuZ2V0SWRzKCk7CisgICAgICAgIHdoaWxlIChpZHMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIHNlc3Npb25zLmFkZChjb250ZXh0LmdldFNlc3Npb24oKGJ5dGVbXSkgaWRzLm5leHRFbGVtZW50KCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIFNldDxTU0xTZXNzaW9uPiBleHBlY3RlZCA9IG5ldyBIYXNoU2V0PFNTTFNlc3Npb24+KCk7CisgICAgICAgIGV4cGVjdGVkLmFkZChhKTsKKyAgICAgICAgZXhwZWN0ZWQuYWRkKGIpOworCisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwgc2Vzc2lvbnMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUcmltVG9TaXplKCkgeworICAgICAgICBDbGllbnRTZXNzaW9uQ29udGV4dCBjb250ZXh0ID0gbmV3IENsaWVudFNlc3Npb25Db250ZXh0KCk7CisKKyAgICAgICAgVmFsaWRTU0xTZXNzaW9uIGEgPSBuZXcgVmFsaWRTU0xTZXNzaW9uKCJhIik7CisgICAgICAgIFZhbGlkU1NMU2Vzc2lvbiBiID0gbmV3IFZhbGlkU1NMU2Vzc2lvbigiYiIpOworICAgICAgICBWYWxpZFNTTFNlc3Npb24gYyA9IG5ldyBWYWxpZFNTTFNlc3Npb24oImMiKTsKKyAgICAgICAgVmFsaWRTU0xTZXNzaW9uIGQgPSBuZXcgVmFsaWRTU0xTZXNzaW9uKCJkIik7CisKKyAgICAgICAgY29udGV4dC5wdXRTZXNzaW9uKGEpOworICAgICAgICBjb250ZXh0LnB1dFNlc3Npb24oYik7CisgICAgICAgIGNvbnRleHQucHV0U2Vzc2lvbihjKTsKKyAgICAgICAgY29udGV4dC5wdXRTZXNzaW9uKGQpOworCisgICAgICAgIGNvbnRleHQuc2V0U2Vzc2lvbkNhY2hlU2l6ZSgyKTsKKworICAgICAgICBTZXQ8U1NMU2Vzc2lvbj4gc2Vzc2lvbnMgPSBuZXcgSGFzaFNldDxTU0xTZXNzaW9uPigpOworICAgICAgICBFbnVtZXJhdGlvbiBpZHMgPSBjb250ZXh0LmdldElkcygpOworICAgICAgICB3aGlsZSAoaWRzLmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICBzZXNzaW9ucy5hZGQoY29udGV4dC5nZXRTZXNzaW9uKChieXRlW10pIGlkcy5uZXh0RWxlbWVudCgpKSk7CisgICAgICAgIH0KKworICAgICAgICBTZXQ8U1NMU2Vzc2lvbj4gZXhwZWN0ZWQgPSBuZXcgSGFzaFNldDxTU0xTZXNzaW9uPigpOworICAgICAgICBleHBlY3RlZC5hZGQoYyk7CisgICAgICAgIGV4cGVjdGVkLmFkZChkKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIHNlc3Npb25zKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgVmFsaWRTU0xTZXNzaW9uIGV4dGVuZHMgRmFrZVNTTFNlc3Npb24geworICAgICAgICBWYWxpZFNTTFNlc3Npb24oU3RyaW5nIGhvc3QpIHsKKyAgICAgICAgICAgIHN1cGVyKGhvc3QpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc1ZhbGlkKCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9GaWxlQ2xpZW50U2Vzc2lvbkNhY2hlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvRmlsZUNsaWVudFNlc3Npb25DYWNoZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NzE0Y2MzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvRmlsZUNsaWVudFNlc3Npb25DYWNoZVRlc3QuamF2YQpAQCAtMCwwICsxLDU2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGxpYmNvcmUuamF2YXgubmV0LnNzbC5GYWtlU1NMU2Vzc2lvbjsKKworcHVibGljIGNsYXNzIEZpbGVDbGllbnRTZXNzaW9uQ2FjaGVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHZvaWQgdGVzdE1heFNpemUoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHRtcERpciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKTsKKyAgICAgICAgaWYgKHRtcERpciA9PSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKCJQbGVhc2Ugc2V0ICdqYXZhLmlvLnRtcGRpcicgc3lzdGVtIHByb3BlcnR5LiIpOworICAgICAgICB9CisgICAgICAgIEZpbGUgY2FjaGVEaXIgPSBuZXcgRmlsZSh0bXBEaXIKKyAgICAgICAgICAgICAgICArICIvIiArIEZpbGVDbGllbnRTZXNzaW9uQ2FjaGVUZXN0LmNsYXNzLmdldE5hbWUoKSArICIvY2FjaGUiKTsKKyAgICAgICAgZmluYWwgU1NMQ2xpZW50U2Vzc2lvbkNhY2hlIGNhY2hlCisgICAgICAgICAgICAgICAgPSBGaWxlQ2xpZW50U2Vzc2lvbkNhY2hlLnVzaW5nRGlyZWN0b3J5KGNhY2hlRGlyKTsKKyAgICAgICAgVGhyZWFkW10gdGhyZWFkcyA9IG5ldyBUaHJlYWRbMTBdOworICAgICAgICBmaW5hbCBpbnQgaXRlcmF0aW9ucyA9IEZpbGVDbGllbnRTZXNzaW9uQ2FjaGUuTUFYX1NJWkUgKiAxMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aHJlYWRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgaWQgPSBpOworICAgICAgICAgICAgdGhyZWFkc1tpXSA9IG5ldyBUaHJlYWQoKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGl0ZXJhdGlvbnM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUucHV0U2Vzc2lvbkRhdGEobmV3IEZha2VTU0xTZXNzaW9uKGlkICsgIiIgKyBpKSwgbmV3IGJ5dGVbMTBdKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgIH0KKyAgICAgICAgZm9yIChUaHJlYWQgdGhyZWFkIDogdGhyZWFkcykgeworICAgICAgICAgICAgdGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChUaHJlYWQgdGhyZWFkIDogdGhyZWFkcykgeworICAgICAgICAgICAgdGhyZWFkLmpvaW4oKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoRmlsZUNsaWVudFNlc3Npb25DYWNoZS5NQVhfU0laRSwgY2FjaGVEaXIubGlzdCgpLmxlbmd0aCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvTmF0aXZlQ3J5cHRvVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvTmF0aXZlQ3J5cHRvVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI5MTExOTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9OYXRpdmVDcnlwdG9UZXN0LmphdmEKQEAgLTAsMCArMSwxNzI2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0VGltZW91dEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlLlByaXZhdGVLZXlFbnRyeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5DYWxsYWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JTZXJ2aWNlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yczsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5GdXR1cmU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xQcm90b2NvbEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgbGliY29yZS5qYXZhLnNlY3VyaXR5LlN0YW5kYXJkTmFtZXM7CitpbXBvcnQgbGliY29yZS5qYXZhLnNlY3VyaXR5LlRlc3RLZXlTdG9yZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlLkNpcGhlclN1aXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnByb3ZpZGVyLmpzc2UuTmF0aXZlQ3J5cHRvLlNTTEhhbmRzaGFrZUNhbGxiYWNrczsKKworcHVibGljIGNsYXNzIE5hdGl2ZUNyeXB0b1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTlVMTCA9IDA7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmlsZURlc2NyaXB0b3IgSU5WQUxJRF9GRCA9IG5ldyBGaWxlRGVzY3JpcHRvcigpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFNTTEhhbmRzaGFrZUNhbGxiYWNrcyBEVU1NWV9DQiA9IG5ldyBUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzKC0xLCBudWxsKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgVElNRU9VVF9TRUNPTkRTID0gNTsKKworICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBTRVJWRVJfUFJJVkFURV9LRVk7CisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdW10gU0VSVkVSX0NFUlRJRklDQVRFUzsKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlW10gQ0xJRU5UX1BSSVZBVEVfS0VZOworICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXVtdIENMSUVOVF9DRVJUSUZJQ0FURVM7CisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdW10gQ0FfUFJJTkNJUEFMUzsKKworICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBnZXRTZXJ2ZXJQcml2YXRlS2V5KCkgeworICAgICAgICBpbml0Q2VydHMoKTsKKyAgICAgICAgcmV0dXJuIFNFUlZFUl9QUklWQVRFX0tFWTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlW11bXSBnZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSB7CisgICAgICAgIGluaXRDZXJ0cygpOworICAgICAgICByZXR1cm4gU0VSVkVSX0NFUlRJRklDQVRFUzsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBieXRlW10gZ2V0Q2xpZW50UHJpdmF0ZUtleSgpIHsKKyAgICAgICAgaW5pdENlcnRzKCk7CisgICAgICAgIHJldHVybiBDTElFTlRfUFJJVkFURV9LRVk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdW10gZ2V0Q2xpZW50Q2VydGlmaWNhdGVzKCkgeworICAgICAgICBpbml0Q2VydHMoKTsKKyAgICAgICAgcmV0dXJuIENMSUVOVF9DRVJUSUZJQ0FURVM7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdW10gZ2V0Q2FQcmluY2lwYWxzKCkgeworICAgICAgICBpbml0Q2VydHMoKTsKKyAgICAgICAgcmV0dXJuIENBX1BSSU5DSVBBTFM7CisgICAgfQorCisgICAgLyoqCisgICAgICogTGF6aWx5IGNyZWF0ZSBzaGFyZWQgdGVzdCBjZXJ0aWZpY2F0ZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgc3luY2hyb25pemVkIHZvaWQgaW5pdENlcnRzKCkgeworICAgICAgICBpZiAoU0VSVkVSX1BSSVZBVEVfS0VZICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQcml2YXRlS2V5RW50cnkgc2VydmVyUHJpdmF0ZUtleUVudHJ5CisgICAgICAgICAgICAgICAgICAgID0gVGVzdEtleVN0b3JlLmdldFNlcnZlcigpLmdldFByaXZhdGVLZXkoIlJTQSIsICJSU0EiKTsKKyAgICAgICAgICAgIFNFUlZFUl9QUklWQVRFX0tFWSA9IHNlcnZlclByaXZhdGVLZXlFbnRyeS5nZXRQcml2YXRlS2V5KCkuZ2V0RW5jb2RlZCgpOworICAgICAgICAgICAgU0VSVkVSX0NFUlRJRklDQVRFUyA9IE5hdGl2ZUNyeXB0by5lbmNvZGVDZXJ0aWZpY2F0ZXMoCisgICAgICAgICAgICAgICAgICAgIHNlcnZlclByaXZhdGVLZXlFbnRyeS5nZXRDZXJ0aWZpY2F0ZUNoYWluKCkpOworCisgICAgICAgICAgICBQcml2YXRlS2V5RW50cnkgY2xpZW50UHJpdmF0ZUtleUVudHJ5CisgICAgICAgICAgICAgICAgICAgID0gVGVzdEtleVN0b3JlLmdldENsaWVudENlcnRpZmljYXRlKCkuZ2V0UHJpdmF0ZUtleSgiUlNBIiwgIlJTQSIpOworICAgICAgICAgICAgQ0xJRU5UX1BSSVZBVEVfS0VZID0gY2xpZW50UHJpdmF0ZUtleUVudHJ5LmdldFByaXZhdGVLZXkoKS5nZXRFbmNvZGVkKCk7CisgICAgICAgICAgICBDTElFTlRfQ0VSVElGSUNBVEVTID0gTmF0aXZlQ3J5cHRvLmVuY29kZUNlcnRpZmljYXRlcygKKyAgICAgICAgICAgICAgICAgICAgY2xpZW50UHJpdmF0ZUtleUVudHJ5LmdldENlcnRpZmljYXRlQ2hhaW4oKSk7CisKKyAgICAgICAgICAgIEtleVN0b3JlIGtzID0gVGVzdEtleVN0b3JlLmdldENsaWVudCgpLmtleVN0b3JlOworICAgICAgICAgICAgU3RyaW5nIGNhQ2VydEFsaWFzID0ga3MuYWxpYXNlcygpLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydGlmaWNhdGUgPSAoWDUwOUNlcnRpZmljYXRlKSBrcy5nZXRDZXJ0aWZpY2F0ZShjYUNlcnRBbGlhcyk7CisgICAgICAgICAgICBYNTAwUHJpbmNpcGFsIHByaW5jaXBhbCA9IGNlcnRpZmljYXRlLmdldElzc3Vlclg1MDBQcmluY2lwYWwoKTsKKyAgICAgICAgICAgIENBX1BSSU5DSVBBTFMgPSBuZXcgYnl0ZVtdW10geyBwcmluY2lwYWwuZ2V0RW5jb2RlZCgpIH07CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRFcXVhbFNlc3Npb25zKGludCBleHBlY3RlZCwgaW50IGFjdHVhbCkgeworICAgICAgICBhc3NlcnRFcXVhbEJ5dGVBcnJheXMoTmF0aXZlQ3J5cHRvLlNTTF9TRVNTSU9OX3Nlc3Npb25faWQoZXhwZWN0ZWQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9TRVNTSU9OX3Nlc3Npb25faWQoYWN0dWFsKSk7CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRFcXVhbEJ5dGVBcnJheXMoYnl0ZVtdIGV4cGVjdGVkLCBieXRlW10gYWN0dWFsKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMudG9TdHJpbmcoZXhwZWN0ZWQpLCBBcnJheXMudG9TdHJpbmcoYWN0dWFsKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydEVxdWFsUHJpbmNpcGFscyhieXRlW11bXSBleHBlY3RlZCwgYnl0ZVtdW10gYWN0dWFsKSB7CisgICAgICAgIGFzc2VydEVxdWFsQnl0ZUFycmF5cyhleHBlY3RlZCwgYWN0dWFsKTsKKyAgICB9CisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydEVxdWFsQ2VydGlmaWNhdGVDaGFpbnMoYnl0ZVtdW10gZXhwZWN0ZWQsIGJ5dGVbXVtdIGFjdHVhbCkgeworICAgICAgICBhc3NlcnRFcXVhbEJ5dGVBcnJheXMoZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRFcXVhbEJ5dGVBcnJheXMoYnl0ZVtdW10gZXhwZWN0ZWQsIGJ5dGVbXVtdIGFjdHVhbCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLmRlZXBUb1N0cmluZyhleHBlY3RlZCksIEFycmF5cy5kZWVwVG9TdHJpbmcoYWN0dWFsKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfQ1RYX25ldygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbnQgYyA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICBhc3NlcnRUcnVlKGMgIT0gTlVMTCk7CisgICAgICAgIGludCBjMiA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICBhc3NlcnRUcnVlKGMgIT0gYzIpOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX0NUWF9mcmVlKGMpOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX0NUWF9mcmVlKGMyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTF9DVFhfZnJlZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9DVFhfZnJlZShOVUxMKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoTmF0aXZlQ3J5cHRvLlNTTF9DVFhfbmV3KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX25ldygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbnQgYyA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICBpbnQgcyA9IE5hdGl2ZUNyeXB0by5TU0xfbmV3KGMpOworCisgICAgICAgIGFzc2VydFRydWUocyAhPSBOVUxMKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgoTmF0aXZlQ3J5cHRvLlNTTF9nZXRfb3B0aW9ucyhzKSAmIDB4MDEwMDAwMDBMKSAhPSAwKTsgLy8gU1NMX09QX05PX1NTTHYyCisgICAgICAgIGFzc2VydFRydWUoKE5hdGl2ZUNyeXB0by5TU0xfZ2V0X29wdGlvbnMocykgJiBOYXRpdmVDcnlwdG8uU1NMX09QX05PX1NTTHYzKSA9PSAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgoTmF0aXZlQ3J5cHRvLlNTTF9nZXRfb3B0aW9ucyhzKSAmIE5hdGl2ZUNyeXB0by5TU0xfT1BfTk9fVExTdjEpID09IDApOworCisgICAgICAgIGludCBzMiA9IE5hdGl2ZUNyeXB0by5TU0xfbmV3KGMpOworICAgICAgICBhc3NlcnRUcnVlKHMgIT0gczIpOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2ZyZWUoczIpOworCisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfZnJlZShzKTsKKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9DVFhfZnJlZShjKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTF91c2VfY2VydGlmaWNhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfdXNlX2NlcnRpZmljYXRlKE5VTEwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgaW50IGMgPSBOYXRpdmVDcnlwdG8uU1NMX0NUWF9uZXcoKTsKKyAgICAgICAgaW50IHMgPSBOYXRpdmVDcnlwdG8uU1NMX25ldyhjKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF91c2VfY2VydGlmaWNhdGUocywgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3VzZV9jZXJ0aWZpY2F0ZShzLCBnZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSk7CisKKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9mcmVlKHMpOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX0NUWF9mcmVlKGMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX3VzZV9Qcml2YXRlS2V5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3VzZV9Qcml2YXRlS2V5KE5VTEwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgaW50IGMgPSBOYXRpdmVDcnlwdG8uU1NMX0NUWF9uZXcoKTsKKyAgICAgICAgaW50IHMgPSBOYXRpdmVDcnlwdG8uU1NMX25ldyhjKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF91c2VfUHJpdmF0ZUtleShzLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfdXNlX1ByaXZhdGVLZXkocywgZ2V0U2VydmVyUHJpdmF0ZUtleSgpKTsKKworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2ZyZWUocyk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoYyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfY2hlY2tfcHJpdmF0ZV9rZXlfbnVsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9jaGVja19wcml2YXRlX2tleShOVUxMKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX2NoZWNrX3ByaXZhdGVfa2V5X25vX2tleV9ub19jZXJ0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBjID0gTmF0aXZlQ3J5cHRvLlNTTF9DVFhfbmV3KCk7CisgICAgICAgIGludCBzID0gTmF0aXZlQ3J5cHRvLlNTTF9uZXcoYyk7CisKKyAgICAgICAgLy8gbmVpdGhlciBwcml2YXRlIG9yIGNlcnRpZmljYXRlIHNldAorICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9jaGVja19wcml2YXRlX2tleShzKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU1NMRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2ZyZWUocyk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoYyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfY2hlY2tfcHJpdmF0ZV9rZXlfY2VydF90aGVuX2tleSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbnQgYyA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICBpbnQgcyA9IE5hdGl2ZUNyeXB0by5TU0xfbmV3KGMpOworCisgICAgICAgIC8vIGZpcnN0IGNlcnRpZmljYXRlLCB0aGVuIHByaXZhdGUKKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF91c2VfY2VydGlmaWNhdGUocywgZ2V0U2VydmVyQ2VydGlmaWNhdGVzKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2NoZWNrX3ByaXZhdGVfa2V5KHMpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTU0xFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfdXNlX1ByaXZhdGVLZXkocywgZ2V0U2VydmVyUHJpdmF0ZUtleSgpKTsKKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9jaGVja19wcml2YXRlX2tleShzKTsKKworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2ZyZWUocyk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoYyk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX2NoZWNrX3ByaXZhdGVfa2V5X2tleV90aGVuX2NlcnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGMgPSBOYXRpdmVDcnlwdG8uU1NMX0NUWF9uZXcoKTsKKyAgICAgICAgaW50IHMgPSBOYXRpdmVDcnlwdG8uU1NMX25ldyhjKTsKKworICAgICAgICAvLyBmaXJzdCBwcml2YXRlLCB0aGVuIGNlcnRpZmljYXRlCisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfdXNlX1ByaXZhdGVLZXkocywgZ2V0U2VydmVyUHJpdmF0ZUtleSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9jaGVja19wcml2YXRlX2tleShzKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU1NMRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3VzZV9jZXJ0aWZpY2F0ZShzLCBnZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfY2hlY2tfcHJpdmF0ZV9rZXkocyk7CisKKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9mcmVlKHMpOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX0NUWF9mcmVlKGMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX2dldF9tb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2dldF9tb2RlKE5VTEwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgaW50IGMgPSBOYXRpdmVDcnlwdG8uU1NMX0NUWF9uZXcoKTsKKyAgICAgICAgaW50IHMgPSBOYXRpdmVDcnlwdG8uU1NMX25ldyhjKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShOYXRpdmVDcnlwdG8uU1NMX2dldF9tb2RlKHMpICE9IDApOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2ZyZWUocyk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoYyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfc2V0X21vZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfc2V0X21vZGUoTlVMTCwgMCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBpbnQgYyA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICBpbnQgcyA9IE5hdGl2ZUNyeXB0by5TU0xfbmV3KGMpOworICAgICAgICAvLyBjaGVjayBTU0xfTU9ERV9IQU5EU0hBS0VfQ1VUVEhST1VHSCBvbgorICAgICAgICBhc3NlcnRUcnVlKChOYXRpdmVDcnlwdG8uU1NMX2dldF9tb2RlKHMpCisgICAgICAgICAgICAgICAgICAgICYgTmF0aXZlQ3J5cHRvLlNTTF9NT0RFX0hBTkRTSEFLRV9DVVRUSFJPVUdIKSAhPSAwKTsKKyAgICAgICAgLy8gY2xlYXIgU1NMX01PREVfSEFORFNIQUtFX0NVVFRIUk9VR0ggb2ZmCisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfY2xlYXJfbW9kZShzLCBOYXRpdmVDcnlwdG8uU1NMX01PREVfSEFORFNIQUtFX0NVVFRIUk9VR0gpOworICAgICAgICBhc3NlcnRUcnVlKChOYXRpdmVDcnlwdG8uU1NMX2dldF9tb2RlKHMpCisgICAgICAgICAgICAgICAgICAgICYgTmF0aXZlQ3J5cHRvLlNTTF9NT0RFX0hBTkRTSEFLRV9DVVRUSFJPVUdIKSA9PSAwKTsKKyAgICAgICAgLy8gc2V0IFNTTF9NT0RFX0hBTkRTSEFLRV9DVVRUSFJPVUdIIG9uCisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfc2V0X21vZGUocywgTmF0aXZlQ3J5cHRvLlNTTF9NT0RFX0hBTkRTSEFLRV9DVVRUSFJPVUdIKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgoTmF0aXZlQ3J5cHRvLlNTTF9nZXRfbW9kZShzKQorICAgICAgICAgICAgICAgICAgICAmIE5hdGl2ZUNyeXB0by5TU0xfTU9ERV9IQU5EU0hBS0VfQ1VUVEhST1VHSCkgIT0gMCk7CisKKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9mcmVlKHMpOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX0NUWF9mcmVlKGMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX2NsZWFyX21vZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfY2xlYXJfbW9kZShOVUxMLCAwKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGludCBjID0gTmF0aXZlQ3J5cHRvLlNTTF9DVFhfbmV3KCk7CisgICAgICAgIGludCBzID0gTmF0aXZlQ3J5cHRvLlNTTF9uZXcoYyk7CisgICAgICAgIC8vIGNoZWNrIFNTTF9NT0RFX0hBTkRTSEFLRV9DVVRUSFJPVUdIIG9uCisgICAgICAgIGFzc2VydFRydWUoKE5hdGl2ZUNyeXB0by5TU0xfZ2V0X21vZGUocykKKyAgICAgICAgICAgICAgICAgICAgJiBOYXRpdmVDcnlwdG8uU1NMX01PREVfSEFORFNIQUtFX0NVVFRIUk9VR0gpICE9IDApOworICAgICAgICAvLyBjbGVhciBTU0xfTU9ERV9IQU5EU0hBS0VfQ1VUVEhST1VHSCBvZmYKKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9jbGVhcl9tb2RlKHMsIE5hdGl2ZUNyeXB0by5TU0xfTU9ERV9IQU5EU0hBS0VfQ1VUVEhST1VHSCk7CisgICAgICAgIGFzc2VydFRydWUoKE5hdGl2ZUNyeXB0by5TU0xfZ2V0X21vZGUocykKKyAgICAgICAgICAgICAgICAgICAgJiBOYXRpdmVDcnlwdG8uU1NMX01PREVfSEFORFNIQUtFX0NVVFRIUk9VR0gpID09IDApOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2ZyZWUocyk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoYyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfZ2V0X29wdGlvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfZ2V0X29wdGlvbnMoTlVMTCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBpbnQgYyA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICBpbnQgcyA9IE5hdGl2ZUNyeXB0by5TU0xfbmV3KGMpOworICAgICAgICBhc3NlcnRUcnVlKE5hdGl2ZUNyeXB0by5TU0xfZ2V0X29wdGlvbnMocykgIT0gMCk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfZnJlZShzKTsKKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9DVFhfZnJlZShjKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTF9zZXRfb3B0aW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfb3B0aW9ucyhOVUxMLCAwKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGludCBjID0gTmF0aXZlQ3J5cHRvLlNTTF9DVFhfbmV3KCk7CisgICAgICAgIGludCBzID0gTmF0aXZlQ3J5cHRvLlNTTF9uZXcoYyk7CisgICAgICAgIGFzc2VydFRydWUoKE5hdGl2ZUNyeXB0by5TU0xfZ2V0X29wdGlvbnMocykgJiBOYXRpdmVDcnlwdG8uU1NMX09QX05PX1NTTHYzKSA9PSAwKTsKKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfb3B0aW9ucyhzLCBOYXRpdmVDcnlwdG8uU1NMX09QX05PX1NTTHYzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgoTmF0aXZlQ3J5cHRvLlNTTF9nZXRfb3B0aW9ucyhzKSAmIE5hdGl2ZUNyeXB0by5TU0xfT1BfTk9fU1NMdjMpICE9IDApOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2ZyZWUocyk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoYyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfY2xlYXJfb3B0aW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9jbGVhcl9vcHRpb25zKE5VTEwsIDApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgaW50IGMgPSBOYXRpdmVDcnlwdG8uU1NMX0NUWF9uZXcoKTsKKyAgICAgICAgaW50IHMgPSBOYXRpdmVDcnlwdG8uU1NMX25ldyhjKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgoTmF0aXZlQ3J5cHRvLlNTTF9nZXRfb3B0aW9ucyhzKSAmIE5hdGl2ZUNyeXB0by5TU0xfT1BfTk9fU1NMdjMpID09IDApOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3NldF9vcHRpb25zKHMsIE5hdGl2ZUNyeXB0by5TU0xfT1BfTk9fU1NMdjMpOworICAgICAgICBhc3NlcnRUcnVlKChOYXRpdmVDcnlwdG8uU1NMX2dldF9vcHRpb25zKHMpICYgTmF0aXZlQ3J5cHRvLlNTTF9PUF9OT19TU0x2MykgIT0gMCk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfY2xlYXJfb3B0aW9ucyhzLCBOYXRpdmVDcnlwdG8uU1NMX09QX05PX1NTTHYzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgoTmF0aXZlQ3J5cHRvLlNTTF9nZXRfb3B0aW9ucyhzKSAmIE5hdGl2ZUNyeXB0by5TU0xfT1BfTk9fU1NMdjMpID09IDApOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2ZyZWUocyk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoYyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfc2V0X2NpcGhlcl9saXN0cygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfY2lwaGVyX2xpc3RzKE5VTEwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgaW50IGMgPSBOYXRpdmVDcnlwdG8uU1NMX0NUWF9uZXcoKTsKKyAgICAgICAgaW50IHMgPSBOYXRpdmVDcnlwdG8uU1NMX25ldyhjKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfY2lwaGVyX2xpc3RzKHMsIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfY2lwaGVyX2xpc3RzKHMsIG5ldyBTdHJpbmdbXSB7fSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfc2V0X2NpcGhlcl9saXN0cyhzLCBuZXcgU3RyaW5nW10geyBudWxsIH0pOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gc2VlIE9wZW5TU0wgY2lwaGVycyBtYW4gcGFnZQorICAgICAgICBTdHJpbmdbXSBpbGxlZ2FscyA9IG5ldyBTdHJpbmdbXSB7CisgICAgICAgICAgICAvLyBlbXB0eQorICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAvLyBuZXZlciBzdGFuZGFyZGl6ZWQKKyAgICAgICAgICAgICJFWFAxMDI0LURFUy1DQkMtU0hBIiwgIkVYUDEwMjQtUkM0LVNIQSIsICJESEUtRFNTLVJDNC1TSEEiLAorICAgICAgICAgICAgLy8gSURFQQorICAgICAgICAgICAgIklERUEtQ0JDLVNIQSIsICJJREVBLUNCQy1NRDUiCisgICAgICAgIH07CisKKyAgICAgICAgZm9yIChTdHJpbmcgaWxsZWdhbCA6IGlsbGVnYWxzKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfc2V0X2NpcGhlcl9saXN0cyhzLCBuZXcgU3RyaW5nW10geyBpbGxlZ2FsIH0pOworICAgICAgICAgICAgICAgIGZhaWwoaWxsZWdhbCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIExpc3Q8U3RyaW5nPiBjaXBoZXJzCisgICAgICAgICAgICAgICAgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oTmF0aXZlQ3J5cHRvLk9QRU5TU0xfVE9fU1RBTkRBUkRfQ0lQSEVSX1NVSVRFUy5rZXlTZXQoKSk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfc2V0X2NpcGhlcl9saXN0cyhzLCBjaXBoZXJzLnRvQXJyYXkobmV3IFN0cmluZ1tjaXBoZXJzLnNpemUoKV0pKTsKKworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2ZyZWUocyk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoYyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfc2V0X3ZlcmlmeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfdmVyaWZ5KE5VTEwsIDApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgaW50IGMgPSBOYXRpdmVDcnlwdG8uU1NMX0NUWF9uZXcoKTsKKyAgICAgICAgaW50IHMgPSBOYXRpdmVDcnlwdG8uU1NMX25ldyhjKTsKKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfdmVyaWZ5KHMsIE5hdGl2ZUNyeXB0by5TU0xfVkVSSUZZX05PTkUpOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3NldF92ZXJpZnkocywgTmF0aXZlQ3J5cHRvLlNTTF9WRVJJRllfUEVFUik7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfc2V0X3ZlcmlmeShzLCBOYXRpdmVDcnlwdG8uU1NMX1ZFUklGWV9GQUlMX0lGX05PX1BFRVJfQ0VSVCk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfc2V0X3ZlcmlmeShzLCAoTmF0aXZlQ3J5cHRvLlNTTF9WRVJJRllfUEVFUgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgTmF0aXZlQ3J5cHRvLlNTTF9WRVJJRllfRkFJTF9JRl9OT19QRUVSX0NFUlQpKTsKKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9mcmVlKHMpOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX0NUWF9mcmVlKGMpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSG9va3MgeworICAgICAgICBwdWJsaWMgaW50IGdldENvbnRleHQoKSB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBOYXRpdmVDcnlwdG8uU1NMX0NUWF9uZXcoKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgaW50IGJlZm9yZUhhbmRzaGFrZShpbnQgY29udGV4dCkgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpbnQgcyA9IE5hdGl2ZUNyeXB0by5TU0xfbmV3KGNvbnRleHQpOworICAgICAgICAgICAgLy8gd2l0aG91dCB0aGlzIFNTTF9zZXRfY2lwaGVyX2xpc3RzIGNhbGwgdGhlIHRlc3RzIHdlcmUKKyAgICAgICAgICAgIC8vIG5lZ290aWF0aW5nIERIRS1SU0EtQUVTMjU2LVNIQSBieSBkZWZhdWx0IHdoaWNoIGhhZAorICAgICAgICAgICAgLy8gdmVyeSBzbG93IGVwaGVtZXJhbCBSU0Ega2V5IGdlbmVyYXRpb24KKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfc2V0X2NpcGhlcl9saXN0cyhzLCBuZXcgU3RyaW5nW10geyAiUkM0LU1ENSIgfSk7CisgICAgICAgICAgICByZXR1cm4gczsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgdm9pZCBjbGllbnRDZXJ0aWZpY2F0ZVJlcXVlc3RlZChpbnQgcykge30KKyAgICAgICAgcHVibGljIHZvaWQgYWZ0ZXJIYW5kc2hha2UoaW50IHNlc3Npb24sIGludCBzc2wsIGludCBjb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb2NrZXQgc29ja2V0LCBGaWxlRGVzY3JpcHRvciBmZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGNhbGxiYWNrKQorICAgICAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKHNlc3Npb24gIT0gTlVMTCkgeworICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfU0VTU0lPTl9mcmVlKHNlc3Npb24pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHNzbCAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zaHV0ZG93bihzc2wsIGZkLCBjYWxsYmFjayk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2ZyZWUoc3NsKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjb250ZXh0ICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX0NUWF9mcmVlKGNvbnRleHQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHNvY2tldCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFRlc3RTU0xIYW5kc2hha2VDYWxsYmFja3MgaW1wbGVtZW50cyBTU0xIYW5kc2hha2VDYWxsYmFja3MgeworICAgICAgICBwcml2YXRlIGZpbmFsIGludCBzc2xOYXRpdmVQb2ludGVyOworICAgICAgICBwcml2YXRlIGZpbmFsIEhvb2tzIGhvb2tzOworCisgICAgICAgIHB1YmxpYyBUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzKGludCBzc2xOYXRpdmVQb2ludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIb29rcyBob29rcykgeworICAgICAgICAgICAgdGhpcy5zc2xOYXRpdmVQb2ludGVyID0gc3NsTmF0aXZlUG9pbnRlcjsKKyAgICAgICAgICAgIHRoaXMuaG9va3MgPSBob29rczsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW11bXSBhc24xRGVyRW5jb2RlZENlcnRpZmljYXRlQ2hhaW47CisgICAgICAgIHB1YmxpYyBTdHJpbmcgYXV0aE1ldGhvZDsKKyAgICAgICAgcHVibGljIGJvb2xlYW4gdmVyaWZ5Q2VydGlmaWNhdGVDaGFpbkNhbGxlZDsKKworICAgICAgICBwdWJsaWMgdm9pZCB2ZXJpZnlDZXJ0aWZpY2F0ZUNoYWluKGJ5dGVbXVtdIGFzbjFEZXJFbmNvZGVkQ2VydGlmaWNhdGVDaGFpbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXV0aE1ldGhvZCkKKyAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKERFQlVHKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJzc2w9MHgiICsgSW50ZWdlci50b1N0cmluZyhzc2xOYXRpdmVQb2ludGVyLCAxNikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIHZlcmlmeUNlcnRpZmljYXRlQ2hhaW4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBhc24xRGVyRW5jb2RlZENlcnRpZmljYXRlQ2hhaW49IgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGFzbjFEZXJFbmNvZGVkQ2VydGlmaWNhdGVDaGFpbgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgYXV0aE1ldGhvZD0iICsgYXV0aE1ldGhvZCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aGlzLmFzbjFEZXJFbmNvZGVkQ2VydGlmaWNhdGVDaGFpbiA9IGFzbjFEZXJFbmNvZGVkQ2VydGlmaWNhdGVDaGFpbjsKKyAgICAgICAgICAgIHRoaXMuYXV0aE1ldGhvZCA9IGF1dGhNZXRob2Q7CisgICAgICAgICAgICB0aGlzLnZlcmlmeUNlcnRpZmljYXRlQ2hhaW5DYWxsZWQgPSB0cnVlOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBrZXlUeXBlczsKKyAgICAgICAgcHVibGljIGJ5dGVbXVtdIGFzbjFEZXJFbmNvZGVkWDUwMFByaW5jaXBhbHM7CisgICAgICAgIHB1YmxpYyBib29sZWFuIGNsaWVudENlcnRpZmljYXRlUmVxdWVzdGVkQ2FsbGVkOworICAgICAgICBwdWJsaWMgdm9pZCBjbGllbnRDZXJ0aWZpY2F0ZVJlcXVlc3RlZChieXRlW10ga2V5VHlwZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVbXVtdIGFzbjFEZXJFbmNvZGVkWDUwMFByaW5jaXBhbHMpIHsKKyAgICAgICAgICAgIGlmIChERUJVRykgeworICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3NsPTB4IiArIEludGVnZXIudG9TdHJpbmcoc3NsTmF0aXZlUG9pbnRlciwgMTYpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBjbGllbnRDZXJ0aWZpY2F0ZVJlcXVlc3RlZCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGtleVR5cGVzPSIgKyBrZXlUeXBlcworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgYXNuMURlckVuY29kZWRYNTAwUHJpbmNpcGFscz0iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgYXNuMURlckVuY29kZWRYNTAwUHJpbmNpcGFscyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aGlzLmtleVR5cGVzID0ga2V5VHlwZXM7CisgICAgICAgICAgICB0aGlzLmFzbjFEZXJFbmNvZGVkWDUwMFByaW5jaXBhbHMgPSBhc24xRGVyRW5jb2RlZFg1MDBQcmluY2lwYWxzOworICAgICAgICAgICAgdGhpcy5jbGllbnRDZXJ0aWZpY2F0ZVJlcXVlc3RlZENhbGxlZCA9IHRydWU7CisgICAgICAgICAgICBpZiAoaG9va3MgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICBob29rcy5jbGllbnRDZXJ0aWZpY2F0ZVJlcXVlc3RlZChzc2xOYXRpdmVQb2ludGVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhbmRzaGFrZUNvbXBsZXRlZENhbGxlZDsKKyAgICAgICAgcHVibGljIHZvaWQgaGFuZHNoYWtlQ29tcGxldGVkKCkgeworICAgICAgICAgICAgaWYgKERFQlVHKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJzc2w9MHgiICsgSW50ZWdlci50b1N0cmluZyhzc2xOYXRpdmVQb2ludGVyLCAxNikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGhhbmRzaGFrZUNvbXBsZXRlZCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy5oYW5kc2hha2VDb21wbGV0ZWRDYWxsZWQgPSB0cnVlOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBTZXJ2ZXJIb29rcyBleHRlbmRzIEhvb2tzIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gcHJpdmF0ZUtleTsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBieXRlW11bXSBjZXJ0aWZpY2F0ZXM7CisgICAgICAgIHB1YmxpYyBTZXJ2ZXJIb29rcyhieXRlW10gcHJpdmF0ZUtleSwgYnl0ZVtdW10gY2VydGlmaWNhdGVzKSB7CisgICAgICAgICAgICB0aGlzLnByaXZhdGVLZXkgPSBwcml2YXRlS2V5OworICAgICAgICAgICAgdGhpcy5jZXJ0aWZpY2F0ZXMgPSBjZXJ0aWZpY2F0ZXM7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBiZWZvcmVIYW5kc2hha2UoaW50IGMpIHRocm93cyBTU0xFeGNlcHRpb24geworICAgICAgICAgICAgaW50IHMgPSBzdXBlci5iZWZvcmVIYW5kc2hha2UoYyk7CisgICAgICAgICAgICBpZiAocHJpdmF0ZUtleSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF91c2VfUHJpdmF0ZUtleShzLCBwcml2YXRlS2V5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjZXJ0aWZpY2F0ZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfdXNlX2NlcnRpZmljYXRlKHMsIGNlcnRpZmljYXRlcyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gczsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgdm9pZCBjbGllbnRDZXJ0aWZpY2F0ZVJlcXVlc3RlZChpbnQgcykgeworICAgICAgICAgICAgZmFpbCgiU2VydmVyIGFza2VkIGZvciBjbGllbnQgY2VydGlmaWNhdGVzIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBoYW5kc2hha2UoZmluYWwgU2VydmVyU29ja2V0IGxpc3RlbmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdGltZW91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBjbGllbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEhvb2tzIGhvb2tzKSB7CisgICAgICAgIEV4ZWN1dG9yU2VydmljZSBleGVjdXRvciA9IEV4ZWN1dG9ycy5uZXdTaW5nbGVUaHJlYWRFeGVjdXRvcigpOworICAgICAgICBGdXR1cmUgZnV0dXJlID0gZXhlY3V0b3Iuc3VibWl0KG5ldyBDYWxsYWJsZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGNhbGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBTb2NrZXQgc29ja2V0ID0gKGNsaWVudAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXcgU29ja2V0KGxpc3RlbmVyLmdldEluZXRBZGRyZXNzKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIuZ2V0TG9jYWxQb3J0KCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGxpc3RlbmVyLmFjY2VwdCgpKTsKKyAgICAgICAgICAgICAgICBpZiAodGltZW91dCA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3IgZmQgPSBzb2NrZXQuZ2V0RmlsZURlc2NyaXB0b3IkKCk7CisgICAgICAgICAgICAgICAgaW50IGMgPSBob29rcy5nZXRDb250ZXh0KCk7CisgICAgICAgICAgICAgICAgaW50IHMgPSBob29rcy5iZWZvcmVIYW5kc2hha2UoYyk7CisgICAgICAgICAgICAgICAgVGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcyBjYWxsYmFjayA9IG5ldyBUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzKHMsIGhvb2tzKTsKKyAgICAgICAgICAgICAgICBpZiAoREVCVUcpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJzc2w9MHgiICsgSW50ZWdlci50b1N0cmluZyhzLCAxNikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBoYW5kc2hha2UiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgY29udGV4dD0weCIgKyBJbnRlZ2VyLnRvU3RyaW5nKGMsIDE2KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIHNvY2tldD0iICsgc29ja2V0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgZmQ9IiArIGZkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgdGltZW91dD0iICsgdGltZW91dAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGNsaWVudD0iICsgY2xpZW50KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaW50IHNlc3Npb24gPSBOYXRpdmVDcnlwdG8uU1NMX2RvX2hhbmRzaGFrZShzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVvdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnQpOworICAgICAgICAgICAgICAgIGlmIChERUJVRykgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInNzbD0weCIgKyBJbnRlZ2VyLnRvU3RyaW5nKHMsIDE2KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGhhbmRzaGFrZSIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBzZXNzaW9uPTB4IiArIEludGVnZXIudG9TdHJpbmcoc2Vzc2lvbiwgMTYpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaG9va3MuYWZ0ZXJIYW5kc2hha2Uoc2Vzc2lvbiwgcywgYywgc29ja2V0LCBmZCwgY2FsbGJhY2spOworICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIGV4ZWN1dG9yLnNodXRkb3duKCk7CisgICAgICAgIHJldHVybiBmdXR1cmU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfZG9faGFuZHNoYWtlX05VTExfU1NMKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2RvX2hhbmRzaGFrZShOVUxMLCBudWxsLCBudWxsLCAwLCBmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTF9kb19oYW5kc2hha2VfbnVsbF9hcmdzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBjID0gTmF0aXZlQ3J5cHRvLlNTTF9DVFhfbmV3KCk7CisgICAgICAgIGludCBzID0gTmF0aXZlQ3J5cHRvLlNTTF9uZXcoYyk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfZG9faGFuZHNoYWtlKHMsIG51bGwsIG51bGwsIDAsIHRydWUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9kb19oYW5kc2hha2UocywgSU5WQUxJRF9GRCwgbnVsbCwgMCwgdHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfZnJlZShzKTsKKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9DVFhfZnJlZShjKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTF9kb19oYW5kc2hha2Vfbm9ybWFsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIG5vcm1hbCBjbGllbnQgYW5kIHNlcnZlciBjYXNlCisgICAgICAgIGZpbmFsIFNlcnZlclNvY2tldCBsaXN0ZW5lciA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisgICAgICAgIEhvb2tzIGNIb29rcyA9IG5ldyBIb29rcygpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCBiZWZvcmVIYW5kc2hha2UoaW50IGNvbnRleHQpIHRocm93cyBTU0xFeGNlcHRpb24geworICAgICAgICAgICAgICAgIGludCBzID0gc3VwZXIuYmVmb3JlSGFuZHNoYWtlKGNvbnRleHQpOworICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfY2xlYXJfbW9kZShzLCBOYXRpdmVDcnlwdG8uU1NMX01PREVfSEFORFNIQUtFX0NVVFRIUk9VR0gpOworICAgICAgICAgICAgICAgIHJldHVybiBzOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBIb29rcyBzSG9va3MgPSBuZXcgU2VydmVySG9va3MoZ2V0U2VydmVyUHJpdmF0ZUtleSgpLCBnZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBjbGllbnQgPSBoYW5kc2hha2UobGlzdGVuZXIsIDAsIHRydWUsIGNIb29rcyk7CisgICAgICAgIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBzZXJ2ZXIgPSBoYW5kc2hha2UobGlzdGVuZXIsIDAsIGZhbHNlLCBzSG9va3MpOworICAgICAgICBUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGNsaWVudENhbGxiYWNrID0gY2xpZW50LmdldChUSU1FT1VUX1NFQ09ORFMsIFRpbWVVbml0LlNFQ09ORFMpOworICAgICAgICBUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzIHNlcnZlckNhbGxiYWNrID0gc2VydmVyLmdldChUSU1FT1VUX1NFQ09ORFMsIFRpbWVVbml0LlNFQ09ORFMpOworICAgICAgICBhc3NlcnRUcnVlKGNsaWVudENhbGxiYWNrLnZlcmlmeUNlcnRpZmljYXRlQ2hhaW5DYWxsZWQpOworICAgICAgICBhc3NlcnRFcXVhbENlcnRpZmljYXRlQ2hhaW5zKGdldFNlcnZlckNlcnRpZmljYXRlcygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudENhbGxiYWNrLmFzbjFEZXJFbmNvZGVkQ2VydGlmaWNhdGVDaGFpbik7CisgICAgICAgIGFzc2VydEVxdWFscygiUlNBIiwgY2xpZW50Q2FsbGJhY2suYXV0aE1ldGhvZCk7CisgICAgICAgIGFzc2VydEZhbHNlKHNlcnZlckNhbGxiYWNrLnZlcmlmeUNlcnRpZmljYXRlQ2hhaW5DYWxsZWQpOworICAgICAgICBhc3NlcnRGYWxzZShjbGllbnRDYWxsYmFjay5jbGllbnRDZXJ0aWZpY2F0ZVJlcXVlc3RlZENhbGxlZCk7CisgICAgICAgIGFzc2VydEZhbHNlKHNlcnZlckNhbGxiYWNrLmNsaWVudENlcnRpZmljYXRlUmVxdWVzdGVkQ2FsbGVkKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjbGllbnRDYWxsYmFjay5oYW5kc2hha2VDb21wbGV0ZWRDYWxsZWQpOworICAgICAgICBhc3NlcnRUcnVlKHNlcnZlckNhbGxiYWNrLmhhbmRzaGFrZUNvbXBsZXRlZENhbGxlZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfZG9faGFuZHNoYWtlX29wdGlvbmFsX2NsaWVudF9jZXJ0aWZpY2F0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBvcHRpb25hbCBjbGllbnQgY2VydGlmaWNhdGUgY2FzZQorICAgICAgICBmaW5hbCBTZXJ2ZXJTb2NrZXQgbGlzdGVuZXIgPSBuZXcgU2VydmVyU29ja2V0KDApOworCisgICAgICAgIEhvb2tzIGNIb29rcyA9IG5ldyBIb29rcygpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCBiZWZvcmVIYW5kc2hha2UoaW50IGNvbnRleHQpIHRocm93cyBTU0xFeGNlcHRpb24geworICAgICAgICAgICAgICAgIGludCBzID0gc3VwZXIuYmVmb3JlSGFuZHNoYWtlKGNvbnRleHQpOworICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfY2xlYXJfbW9kZShzLCBOYXRpdmVDcnlwdG8uU1NMX01PREVfSEFORFNIQUtFX0NVVFRIUk9VR0gpOworICAgICAgICAgICAgICAgIHJldHVybiBzOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBjbGllbnRDZXJ0aWZpY2F0ZVJlcXVlc3RlZChpbnQgcykgeworICAgICAgICAgICAgICAgIHN1cGVyLmNsaWVudENlcnRpZmljYXRlUmVxdWVzdGVkKHMpOworICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfdXNlX1ByaXZhdGVLZXkocywgZ2V0Q2xpZW50UHJpdmF0ZUtleSgpKTsKKyAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3VzZV9jZXJ0aWZpY2F0ZShzLCBnZXRDbGllbnRDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIEhvb2tzIHNIb29rcyA9IG5ldyBTZXJ2ZXJIb29rcyhnZXRTZXJ2ZXJQcml2YXRlS2V5KCksIGdldFNlcnZlckNlcnRpZmljYXRlcygpKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgYmVmb3JlSGFuZHNoYWtlKGludCBjKSB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBpbnQgcyA9IHN1cGVyLmJlZm9yZUhhbmRzaGFrZShjKTsKKyAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3NldF9jbGllbnRfQ0FfbGlzdChzLCBnZXRDYVByaW5jaXBhbHMoKSk7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfdmVyaWZ5KHMsIE5hdGl2ZUNyeXB0by5TU0xfVkVSSUZZX1BFRVIpOworICAgICAgICAgICAgICAgIHJldHVybiBzOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gY2xpZW50ID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCB0cnVlLCBjSG9va3MpOworICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gc2VydmVyID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCBmYWxzZSwgc0hvb2tzKTsKKyAgICAgICAgVGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcyBjbGllbnRDYWxsYmFjayA9IGNsaWVudC5nZXQoVElNRU9VVF9TRUNPTkRTLCBUaW1lVW5pdC5TRUNPTkRTKTsKKyAgICAgICAgVGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcyBzZXJ2ZXJDYWxsYmFjayA9IHNlcnZlci5nZXQoVElNRU9VVF9TRUNPTkRTLCBUaW1lVW5pdC5TRUNPTkRTKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjbGllbnRDYWxsYmFjay52ZXJpZnlDZXJ0aWZpY2F0ZUNoYWluQ2FsbGVkKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxDZXJ0aWZpY2F0ZUNoYWlucyhnZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRDYWxsYmFjay5hc24xRGVyRW5jb2RlZENlcnRpZmljYXRlQ2hhaW4pOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJTQSIsIGNsaWVudENhbGxiYWNrLmF1dGhNZXRob2QpOworICAgICAgICBhc3NlcnRUcnVlKHNlcnZlckNhbGxiYWNrLnZlcmlmeUNlcnRpZmljYXRlQ2hhaW5DYWxsZWQpOworICAgICAgICBhc3NlcnRFcXVhbENlcnRpZmljYXRlQ2hhaW5zKGdldENsaWVudENlcnRpZmljYXRlcygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZlckNhbGxiYWNrLmFzbjFEZXJFbmNvZGVkQ2VydGlmaWNhdGVDaGFpbik7CisgICAgICAgIGFzc2VydEVxdWFscygiUlNBIiwgc2VydmVyQ2FsbGJhY2suYXV0aE1ldGhvZCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShjbGllbnRDYWxsYmFjay5jbGllbnRDZXJ0aWZpY2F0ZVJlcXVlc3RlZENhbGxlZCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoY2xpZW50Q2FsbGJhY2sua2V5VHlwZXMpOworICAgICAgICAvLyB0aGlzIGRlcGVuZHMgb24gdGhlIFNTTF9zZXRfY2lwaGVyX2xpc3RzIGNhbGwgaW4gYmVmb3JlSGFuZHNoYWtlCisgICAgICAgIC8vIHRoZSB0aHJlZSByZXR1cm5lZCBhcmUgdGhlIG5vbi1lcGhlbWVyYWwgY2FzZXMuCisgICAgICAgIGFzc2VydEVxdWFscygzLCBjbGllbnRDYWxsYmFjay5rZXlUeXBlcy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJTQSIsIENpcGhlclN1aXRlLmdldENsaWVudEtleVR5cGUoY2xpZW50Q2FsbGJhY2sua2V5VHlwZXNbMF0pKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJEU0EiLCBDaXBoZXJTdWl0ZS5nZXRDbGllbnRLZXlUeXBlKGNsaWVudENhbGxiYWNrLmtleVR5cGVzWzFdKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRUMiLCBDaXBoZXJTdWl0ZS5nZXRDbGllbnRLZXlUeXBlKGNsaWVudENhbGxiYWNrLmtleVR5cGVzWzJdKSk7CisgICAgICAgIGFzc2VydEVxdWFsUHJpbmNpcGFscyhnZXRDYVByaW5jaXBhbHMoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudENhbGxiYWNrLmFzbjFEZXJFbmNvZGVkWDUwMFByaW5jaXBhbHMpOworICAgICAgICBhc3NlcnRGYWxzZShzZXJ2ZXJDYWxsYmFjay5jbGllbnRDZXJ0aWZpY2F0ZVJlcXVlc3RlZENhbGxlZCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShjbGllbnRDYWxsYmFjay5oYW5kc2hha2VDb21wbGV0ZWRDYWxsZWQpOworICAgICAgICBhc3NlcnRUcnVlKHNlcnZlckNhbGxiYWNrLmhhbmRzaGFrZUNvbXBsZXRlZENhbGxlZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfZG9faGFuZHNoYWtlX21pc3NpbmdfcmVxdWlyZWRfY2VydGlmaWNhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gcmVxdWlyZWQgY2xpZW50IGNlcnRpZmljYXRlIG5lZ2F0aXZlIGNhc2UKKyAgICAgICAgZmluYWwgU2VydmVyU29ja2V0IGxpc3RlbmVyID0gbmV3IFNlcnZlclNvY2tldCgwKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEhvb2tzIGNIb29rcyA9IG5ldyBIb29rcygpOworICAgICAgICAgICAgSG9va3Mgc0hvb2tzID0gbmV3IFNlcnZlckhvb2tzKGdldFNlcnZlclByaXZhdGVLZXkoKSwgZ2V0U2VydmVyQ2VydGlmaWNhdGVzKCkpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgaW50IGJlZm9yZUhhbmRzaGFrZShpbnQgYykgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgICAgIGludCBzID0gc3VwZXIuYmVmb3JlSGFuZHNoYWtlKGMpOworICAgICAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3NldF9jbGllbnRfQ0FfbGlzdChzLCBnZXRDYVByaW5jaXBhbHMoKSk7CisgICAgICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfc2V0X3ZlcmlmeShzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9WRVJJRllfUEVFUgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBOYXRpdmVDcnlwdG8uU1NMX1ZFUklGWV9GQUlMX0lGX05PX1BFRVJfQ0VSVCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBzOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gY2xpZW50ID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCB0cnVlLCBjSG9va3MpOworICAgICAgICAgICAgRnV0dXJlPFRlc3RTU0xIYW5kc2hha2VDYWxsYmFja3M+IHNlcnZlciA9IGhhbmRzaGFrZShsaXN0ZW5lciwgMCwgZmFsc2UsIHNIb29rcyk7CisgICAgICAgICAgICBzZXJ2ZXIuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4ZWN1dGlvbkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFNTTFByb3RvY29sRXhjZXB0aW9uLmNsYXNzLCBleHBlY3RlZC5nZXRDYXVzZSgpLmdldENsYXNzKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXN1YWxseSBpZiBhIFJ1bnRpbWVFeGNlcHRpb24gaXMgdGhyb3duIGJ5IHRoZQorICAgICAqIGNsaWVudENlcnRpZmljYXRlUmVxdWVzdGVkQ2FsbGVkIGNhbGxiYWNrLCB0aGUgY2FsbGVyIHNlZXMgaXQKKyAgICAgKiBkdXJpbmcgdGhlIGNhbGwgdG8gTmF0aXZlQ3J5cHRvX1NTTF9kb19oYW5kc2hha2UuICBIb3dldmVyLCBJSVMKKyAgICAgKiBkb2VzIG5vdCByZXF1ZXN0IGNsaWVudCBjZXJ0cyB1bnRpbCBhZnRlciB0aGUgaW5pdGlhbAorICAgICAqIGhhbmRzaGFrZS4gSXQgZG9lcyBhbiBTU0wgcmVuZWdvdGlhdGlvbiwgd2hpY2ggbWVhbnMgd2UgbmVlZCB0bworICAgICAqIGJlIGFibGUgdG8gZGVsaXZlciB0aGUgY2FsbGJhY2sncyBleGNlcHRpb24gaW4gY2FzZXMgbGlrZQorICAgICAqIFNTTF9yZWFkLCBTU0xfd3JpdGUsIGFuZCBTU0xfc2h1dGRvd24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfZG9faGFuZHNoYWtlX2NsaWVudENlcnRpZmljYXRlUmVxdWVzdGVkX3Rocm93c19hZnRlcl9yZW5lZ290aWF0ZSgpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU2VydmVyU29ja2V0IGxpc3RlbmVyID0gbmV3IFNlcnZlclNvY2tldCgwKTsKKworICAgICAgICBIb29rcyBjSG9va3MgPSBuZXcgSG9va3MoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgYmVmb3JlSGFuZHNoYWtlKGludCBjb250ZXh0KSB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBpbnQgcyA9IHN1cGVyLmJlZm9yZUhhbmRzaGFrZShjb250ZXh0KTsKKyAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2NsZWFyX21vZGUocywgTmF0aXZlQ3J5cHRvLlNTTF9NT0RFX0hBTkRTSEFLRV9DVVRUSFJPVUdIKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgYWZ0ZXJIYW5kc2hha2UoaW50IHNlc3Npb24sIGludCBzLCBpbnQgYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvY2tldCBzb2NrLCBGaWxlRGVzY3JpcHRvciBmZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTEhhbmRzaGFrZUNhbGxiYWNrcyBjYWxsYmFjaykKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9yZWFkKHMsIGZkLCBjYWxsYmFjaywgbmV3IGJ5dGVbMV0sIDAsIDEsIDApOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICBzdXBlci5hZnRlckhhbmRzaGFrZShzZXNzaW9uLCBzLCBjLCBzb2NrLCBmZCwgY2FsbGJhY2spOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBjbGllbnRDZXJ0aWZpY2F0ZVJlcXVlc3RlZChpbnQgcykgeworICAgICAgICAgICAgICAgIHN1cGVyLmNsaWVudENlcnRpZmljYXRlUmVxdWVzdGVkKHMpOworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJleHBlY3RlZCIpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBIb29rcyBzSG9va3MgPSBuZXcgU2VydmVySG9va3MoZ2V0U2VydmVyUHJpdmF0ZUtleSgpLCBnZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBhZnRlckhhbmRzaGFrZShpbnQgc2Vzc2lvbiwgaW50IHMsIGludCBjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29ja2V0IHNvY2ssIEZpbGVEZXNjcmlwdG9yIGZkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGNhbGxiYWNrKQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3NldF92ZXJpZnkocywgTmF0aXZlQ3J5cHRvLlNTTF9WRVJJRllfUEVFUik7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9yZW5lZ290aWF0ZShzKTsKKyAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3dyaXRlKHMsIGZkLCBjYWxsYmFjaywgbmV3IGJ5dGVbXSB7IDQyIH0sIDAsIDEpOworICAgICAgICAgICAgICAgIHN1cGVyLmFmdGVySGFuZHNoYWtlKHNlc3Npb24sIHMsIGMsIHNvY2ssIGZkLCBjYWxsYmFjayk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBjbGllbnQgPSBoYW5kc2hha2UobGlzdGVuZXIsIDAsIHRydWUsIGNIb29rcyk7CisgICAgICAgIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBzZXJ2ZXIgPSBoYW5kc2hha2UobGlzdGVuZXIsIDAsIGZhbHNlLCBzSG9va3MpOworICAgICAgICBzZXJ2ZXIuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjbGllbnQuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgICAgIH0gY2F0Y2ggKEV4ZWN1dGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAoISJleHBlY3RlZCIuZXF1YWxzKGUuZ2V0Q2F1c2UoKS5nZXRNZXNzYWdlKCkpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX2RvX2hhbmRzaGFrZV9jbGllbnRfdGltZW91dCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBjbGllbnQgdGltZW91dAorICAgICAgICBmaW5hbCBTZXJ2ZXJTb2NrZXQgbGlzdGVuZXIgPSBuZXcgU2VydmVyU29ja2V0KDApOworICAgICAgICB0cnkgeworICAgICAgICAgICAgSG9va3MgY0hvb2tzID0gbmV3IEhvb2tzKCk7CisgICAgICAgICAgICBIb29rcyBzSG9va3MgPSBuZXcgU2VydmVySG9va3MoZ2V0U2VydmVyUHJpdmF0ZUtleSgpLCBnZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gY2xpZW50ID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAxLCB0cnVlLCBjSG9va3MpOworICAgICAgICAgICAgRnV0dXJlPFRlc3RTU0xIYW5kc2hha2VDYWxsYmFja3M+IHNlcnZlciA9IGhhbmRzaGFrZShsaXN0ZW5lciwgLTEsIGZhbHNlLCBzSG9va3MpOworICAgICAgICAgICAgY2xpZW50LmdldChUSU1FT1VUX1NFQ09ORFMsIFRpbWVVbml0LlNFQ09ORFMpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChFeGVjdXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhTb2NrZXRUaW1lb3V0RXhjZXB0aW9uLmNsYXNzLCBleHBlY3RlZC5nZXRDYXVzZSgpLmdldENsYXNzKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfZG9faGFuZHNoYWtlX3NlcnZlcl90aW1lb3V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIHNlcnZlciB0aW1lb3V0CisgICAgICAgIGZpbmFsIFNlcnZlclNvY2tldCBsaXN0ZW5lciA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBIb29rcyBjSG9va3MgPSBuZXcgSG9va3MoKTsKKyAgICAgICAgICAgIEhvb2tzIHNIb29rcyA9IG5ldyBTZXJ2ZXJIb29rcyhnZXRTZXJ2ZXJQcml2YXRlS2V5KCksIGdldFNlcnZlckNlcnRpZmljYXRlcygpKTsKKyAgICAgICAgICAgIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBjbGllbnQgPSBoYW5kc2hha2UobGlzdGVuZXIsIC0xLCB0cnVlLCBjSG9va3MpOworICAgICAgICAgICAgRnV0dXJlPFRlc3RTU0xIYW5kc2hha2VDYWxsYmFja3M+IHNlcnZlciA9IGhhbmRzaGFrZShsaXN0ZW5lciwgMSwgZmFsc2UsIHNIb29rcyk7CisgICAgICAgICAgICBzZXJ2ZXIuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4ZWN1dGlvbkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFNvY2tldFRpbWVvdXRFeGNlcHRpb24uY2xhc3MsIGV4cGVjdGVkLmdldENhdXNlKCkuZ2V0Q2xhc3MoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTF9zZXRfc2Vzc2lvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfc2Vzc2lvbihOVUxMLCBOVUxMKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHsKKyAgICAgICAgICAgIGludCBjID0gTmF0aXZlQ3J5cHRvLlNTTF9DVFhfbmV3KCk7CisgICAgICAgICAgICBpbnQgcyA9IE5hdGl2ZUNyeXB0by5TU0xfbmV3KGMpOworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfc2Vzc2lvbihzLCBOVUxMKTsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfZnJlZShzKTsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoYyk7CisgICAgICAgIH0KKworICAgICAgICB7CisgICAgICAgICAgICBmaW5hbCBpbnQgY2xpZW50Q29udGV4dCA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICAgICAgZmluYWwgaW50IHNlcnZlckNvbnRleHQgPSBOYXRpdmVDcnlwdG8uU1NMX0NUWF9uZXcoKTsKKyAgICAgICAgICAgIGZpbmFsIFNlcnZlclNvY2tldCBsaXN0ZW5lciA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisgICAgICAgICAgICBmaW5hbCBpbnRbXSBjbGllbnRTZXNzaW9uID0gbmV3IGludFtdIHsgTlVMTCB9OworICAgICAgICAgICAgZmluYWwgaW50W10gc2VydmVyU2Vzc2lvbiA9IG5ldyBpbnRbXSB7IE5VTEwgfTsKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBIb29rcyBjSG9va3MgPSBuZXcgSG9va3MoKSB7CisgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICBwdWJsaWMgaW50IGdldENvbnRleHQoKSB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRDb250ZXh0OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBhZnRlckhhbmRzaGFrZShpbnQgc2Vzc2lvbiwgaW50IHMsIGludCBjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb2NrZXQgc29jaywgRmlsZURlc2NyaXB0b3IgZmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTEhhbmRzaGFrZUNhbGxiYWNrcyBjYWxsYmFjaykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN1cGVyLmFmdGVySGFuZHNoYWtlKE5VTEwsIHMsIE5VTEwsIHNvY2ssIGZkLCBjYWxsYmFjayk7CisgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRTZXNzaW9uWzBdID0gc2Vzc2lvbjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICAgICAgSG9va3Mgc0hvb2tzID0gbmV3IFNlcnZlckhvb2tzKGdldFNlcnZlclByaXZhdGVLZXkoKSwgZ2V0U2VydmVyQ2VydGlmaWNhdGVzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0Q29udGV4dCgpIHRocm93cyBTU0xFeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlcnZlckNvbnRleHQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFmdGVySGFuZHNoYWtlKGludCBzZXNzaW9uLCBpbnQgcywgaW50IGMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvY2tldCBzb2NrLCBGaWxlRGVzY3JpcHRvciBmZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGNhbGxiYWNrKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICAgICAgc3VwZXIuYWZ0ZXJIYW5kc2hha2UoTlVMTCwgcywgTlVMTCwgc29jaywgZmQsIGNhbGxiYWNrKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZlclNlc3Npb25bMF0gPSBzZXNzaW9uOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfTsKKyAgICAgICAgICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gY2xpZW50ID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCB0cnVlLCBjSG9va3MpOworICAgICAgICAgICAgICAgIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBzZXJ2ZXIgPSBoYW5kc2hha2UobGlzdGVuZXIsIDAsIGZhbHNlLCBzSG9va3MpOworICAgICAgICAgICAgICAgIGNsaWVudC5nZXQoVElNRU9VVF9TRUNPTkRTLCBUaW1lVW5pdC5TRUNPTkRTKTsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbFNlc3Npb25zKGNsaWVudFNlc3Npb25bMF0sIHNlcnZlclNlc3Npb25bMF0pOworICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIEhvb2tzIGNIb29rcyA9IG5ldyBIb29rcygpIHsKKyAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0Q29udGV4dCgpIHRocm93cyBTU0xFeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNsaWVudENvbnRleHQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBpbnQgYmVmb3JlSGFuZHNoYWtlKGludCBjKSB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGludCBzID0gTmF0aXZlQ3J5cHRvLlNTTF9uZXcoY2xpZW50Q29udGV4dCk7CisgICAgICAgICAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3NldF9zZXNzaW9uKHMsIGNsaWVudFNlc3Npb25bMF0pOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHM7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFmdGVySGFuZHNoYWtlKGludCBzZXNzaW9uLCBpbnQgcywgaW50IGMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvY2tldCBzb2NrLCBGaWxlRGVzY3JpcHRvciBmZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGNhbGxiYWNrKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxTZXNzaW9ucyhjbGllbnRTZXNzaW9uWzBdLCBzZXNzaW9uKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN1cGVyLmFmdGVySGFuZHNoYWtlKE5VTEwsIHMsIE5VTEwsIHNvY2ssIGZkLCBjYWxsYmFjayk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9OworICAgICAgICAgICAgICAgIEhvb2tzIHNIb29rcyA9IG5ldyBTZXJ2ZXJIb29rcyhnZXRTZXJ2ZXJQcml2YXRlS2V5KCksIGdldFNlcnZlckNlcnRpZmljYXRlcygpKSB7CisgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICBwdWJsaWMgaW50IGdldENvbnRleHQoKSB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzZXJ2ZXJDb250ZXh0OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBhZnRlckhhbmRzaGFrZShpbnQgc2Vzc2lvbiwgaW50IHMsIGludCBjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb2NrZXQgc29jaywgRmlsZURlc2NyaXB0b3IgZmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTEhhbmRzaGFrZUNhbGxiYWNrcyBjYWxsYmFjaykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFsU2Vzc2lvbnMoc2VydmVyU2Vzc2lvblswXSwgc2Vzc2lvbik7CisgICAgICAgICAgICAgICAgICAgICAgICBzdXBlci5hZnRlckhhbmRzaGFrZShOVUxMLCBzLCBOVUxMLCBzb2NrLCBmZCwgY2FsbGJhY2spOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfTsKKyAgICAgICAgICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gY2xpZW50ID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCB0cnVlLCBjSG9va3MpOworICAgICAgICAgICAgICAgIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBzZXJ2ZXIgPSBoYW5kc2hha2UobGlzdGVuZXIsIDAsIGZhbHNlLCBzSG9va3MpOworICAgICAgICAgICAgICAgIGNsaWVudC5nZXQoVElNRU9VVF9TRUNPTkRTLCBUaW1lVW5pdC5TRUNPTkRTKTsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX1NFU1NJT05fZnJlZShjbGllbnRTZXNzaW9uWzBdKTsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfU0VTU0lPTl9mcmVlKHNlcnZlclNlc3Npb25bMF0pOworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9DVFhfZnJlZShzZXJ2ZXJDb250ZXh0KTsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoY2xpZW50Q29udGV4dCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTF9zZXRfc2Vzc2lvbl9jcmVhdGlvbl9lbmFibGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3NldF9zZXNzaW9uX2NyZWF0aW9uX2VuYWJsZWQoTlVMTCwgZmFsc2UpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgeworICAgICAgICAgICAgaW50IGMgPSBOYXRpdmVDcnlwdG8uU1NMX0NUWF9uZXcoKTsKKyAgICAgICAgICAgIGludCBzID0gTmF0aXZlQ3J5cHRvLlNTTF9uZXcoYyk7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3NldF9zZXNzaW9uX2NyZWF0aW9uX2VuYWJsZWQocywgZmFsc2UpOworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfc2Vzc2lvbl9jcmVhdGlvbl9lbmFibGVkKHMsIHRydWUpOworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9mcmVlKHMpOworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9DVFhfZnJlZShjKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIFNlcnZlclNvY2tldCBsaXN0ZW5lciA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisKKyAgICAgICAgLy8gbmVnYXRpdmUgdGVzdCBjYXNlIGZvciBTU0xfc2V0X3Nlc3Npb25fY3JlYXRpb25fZW5hYmxlZChmYWxzZSkgb24gY2xpZW50CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBIb29rcyBjSG9va3MgPSBuZXcgSG9va3MoKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIGludCBiZWZvcmVIYW5kc2hha2UoaW50IGMpIHRocm93cyBTU0xFeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICBpbnQgcyA9IHN1cGVyLmJlZm9yZUhhbmRzaGFrZShjKTsKKyAgICAgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfc2Vzc2lvbl9jcmVhdGlvbl9lbmFibGVkKHMsIGZhbHNlKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHM7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfTsKKyAgICAgICAgICAgIEhvb2tzIHNIb29rcyA9IG5ldyBTZXJ2ZXJIb29rcyhnZXRTZXJ2ZXJQcml2YXRlS2V5KCksIGdldFNlcnZlckNlcnRpZmljYXRlcygpKTsKKyAgICAgICAgICAgIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBjbGllbnQgPSBoYW5kc2hha2UobGlzdGVuZXIsIDAsIHRydWUsIGNIb29rcyk7CisgICAgICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gc2VydmVyID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCBmYWxzZSwgc0hvb2tzKTsKKyAgICAgICAgICAgIGNsaWVudC5nZXQoVElNRU9VVF9TRUNPTkRTLCBUaW1lVW5pdC5TRUNPTkRTKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhlY3V0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoU1NMUHJvdG9jb2xFeGNlcHRpb24uY2xhc3MsIGV4cGVjdGVkLmdldENhdXNlKCkuZ2V0Q2xhc3MoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBuZWdhdGl2ZSB0ZXN0IGNhc2UgZm9yIFNTTF9zZXRfc2Vzc2lvbl9jcmVhdGlvbl9lbmFibGVkKGZhbHNlKSBvbiBzZXJ2ZXIKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEhvb2tzIGNIb29rcyA9IG5ldyBIb29rcygpOworICAgICAgICAgICAgSG9va3Mgc0hvb2tzID0gbmV3IFNlcnZlckhvb2tzKGdldFNlcnZlclByaXZhdGVLZXkoKSwgZ2V0U2VydmVyQ2VydGlmaWNhdGVzKCkpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgaW50IGJlZm9yZUhhbmRzaGFrZShpbnQgYykgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgICAgIGludCBzID0gc3VwZXIuYmVmb3JlSGFuZHNoYWtlKGMpOworICAgICAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3NldF9zZXNzaW9uX2NyZWF0aW9uX2VuYWJsZWQocywgZmFsc2UpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gczsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9OworICAgICAgICAgICAgRnV0dXJlPFRlc3RTU0xIYW5kc2hha2VDYWxsYmFja3M+IGNsaWVudCA9IGhhbmRzaGFrZShsaXN0ZW5lciwgMCwgdHJ1ZSwgY0hvb2tzKTsKKyAgICAgICAgICAgIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBzZXJ2ZXIgPSBoYW5kc2hha2UobGlzdGVuZXIsIDAsIGZhbHNlLCBzSG9va3MpOworICAgICAgICAgICAgY2xpZW50LmdldChUSU1FT1VUX1NFQ09ORFMsIFRpbWVVbml0LlNFQ09ORFMpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChFeGVjdXRpb25FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhTU0xQcm90b2NvbEV4Y2VwdGlvbi5jbGFzcywgZXhwZWN0ZWQuZ2V0Q2F1c2UoKS5nZXRDbGFzcygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX3NldF90bHNleHRfaG9zdF9uYW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIE5VTEwgU1NMCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3NldF90bHNleHRfaG9zdF9uYW1lKE5VTEwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgU3RyaW5nIGhvc3RuYW1lID0gInd3dy5hbmRyb2lkLmNvbSI7CisKKyAgICAgICAgeworICAgICAgICAgICAgaW50IGMgPSBOYXRpdmVDcnlwdG8uU1NMX0NUWF9uZXcoKTsKKyAgICAgICAgICAgIGludCBzID0gTmF0aXZlQ3J5cHRvLlNTTF9uZXcoYyk7CisKKyAgICAgICAgICAgIC8vIG51bGwgaG9zdG5hbWUKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfdGxzZXh0X2hvc3RfbmFtZShzLCBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB0b28gbG9uZyBob3N0bmFtZQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjaGFyW10gbG9uZ0hvc3RuYW1lID0gbmV3IGNoYXJbMjU2XTsKKyAgICAgICAgICAgICAgICBBcnJheXMuZmlsbChsb25nSG9zdG5hbWUsICd3Jyk7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfdGxzZXh0X2hvc3RfbmFtZShzLCBuZXcgU3RyaW5nKGxvbmdIb3N0bmFtZSkpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNTTEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBhc3NlcnROdWxsKE5hdGl2ZUNyeXB0by5TU0xfZ2V0X3NlcnZlcm5hbWUocykpOworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfdGxzZXh0X2hvc3RfbmFtZShzLCBuZXcgU3RyaW5nKGhvc3RuYW1lKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaG9zdG5hbWUsIE5hdGl2ZUNyeXB0by5TU0xfZ2V0X3NlcnZlcm5hbWUocykpOworCisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2ZyZWUocyk7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX0NUWF9mcmVlKGMpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgU2VydmVyU29ja2V0IGxpc3RlbmVyID0gbmV3IFNlcnZlclNvY2tldCgwKTsKKworICAgICAgICAvLyBub3JtYWwKKyAgICAgICAgSG9va3MgY0hvb2tzID0gbmV3IEhvb2tzKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgaW50IGJlZm9yZUhhbmRzaGFrZShpbnQgYykgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgaW50IHMgPSBzdXBlci5iZWZvcmVIYW5kc2hha2UoYyk7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zZXRfdGxzZXh0X2hvc3RfbmFtZShzLCBob3N0bmFtZSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHM7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIEhvb2tzIHNIb29rcyA9IG5ldyBTZXJ2ZXJIb29rcyhnZXRTZXJ2ZXJQcml2YXRlS2V5KCksIGdldFNlcnZlckNlcnRpZmljYXRlcygpKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFmdGVySGFuZHNoYWtlKGludCBzZXNzaW9uLCBpbnQgcywgaW50IGMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb2NrZXQgc29jaywgRmlsZURlc2NyaXB0b3IgZmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xIYW5kc2hha2VDYWxsYmFja3MgY2FsbGJhY2spCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhob3N0bmFtZSwgTmF0aXZlQ3J5cHRvLlNTTF9nZXRfc2VydmVybmFtZShzKSk7CisgICAgICAgICAgICAgICAgc3VwZXIuYWZ0ZXJIYW5kc2hha2Uoc2Vzc2lvbiwgcywgYywgc29jaywgZmQsIGNhbGxiYWNrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgRnV0dXJlPFRlc3RTU0xIYW5kc2hha2VDYWxsYmFja3M+IGNsaWVudCA9IGhhbmRzaGFrZShsaXN0ZW5lciwgMCwgdHJ1ZSwgY0hvb2tzKTsKKyAgICAgICAgRnV0dXJlPFRlc3RTU0xIYW5kc2hha2VDYWxsYmFja3M+IHNlcnZlciA9IGhhbmRzaGFrZShsaXN0ZW5lciwgMCwgZmFsc2UsIHNIb29rcyk7CisgICAgICAgIGNsaWVudC5nZXQoVElNRU9VVF9TRUNPTkRTLCBUaW1lVW5pdC5TRUNPTkRTKTsKKyAgICAgICAgc2VydmVyLmdldChUSU1FT1VUX1NFQ09ORFMsIFRpbWVVbml0LlNFQ09ORFMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX2dldF9zZXJ2ZXJuYW1lX251bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gTlVMTCBTU0wKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfZ2V0X3NlcnZlcm5hbWUoTlVMTCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBpbnQgYyA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICBpbnQgcyA9IE5hdGl2ZUNyeXB0by5TU0xfbmV3KGMpOworICAgICAgICBhc3NlcnROdWxsKE5hdGl2ZUNyeXB0by5TU0xfZ2V0X3NlcnZlcm5hbWUocykpOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2ZyZWUocyk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoYyk7CisKKyAgICAgICAgLy8gYWRkaXRpb25hbCBwb3NpdGl2ZSB0ZXN0aW5nIGJ5IHRlc3RfU1NMX3NldF90bHNleHRfaG9zdF9uYW1lCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfcmVuZWdvdGlhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfcmVuZWdvdGlhdGUoTlVMTCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBTZXJ2ZXJTb2NrZXQgbGlzdGVuZXIgPSBuZXcgU2VydmVyU29ja2V0KDApOworICAgICAgICBIb29rcyBjSG9va3MgPSBuZXcgSG9va3MoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFmdGVySGFuZHNoYWtlKGludCBzZXNzaW9uLCBpbnQgcywgaW50IGMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb2NrZXQgc29jaywgRmlsZURlc2NyaXB0b3IgZmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xIYW5kc2hha2VDYWxsYmFja3MgY2FsbGJhY2spCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVsxXTsKKyAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3JlYWQocywgZmQsIGNhbGxiYWNrLCBidWZmZXIsIDAsIDEsIDApOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyg0MiwgYnVmZmVyWzBdKTsKKyAgICAgICAgICAgICAgICBzdXBlci5hZnRlckhhbmRzaGFrZShzZXNzaW9uLCBzLCBjLCBzb2NrLCBmZCwgY2FsbGJhY2spOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBIb29rcyBzSG9va3MgPSBuZXcgU2VydmVySG9va3MoZ2V0U2VydmVyUHJpdmF0ZUtleSgpLCBnZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBhZnRlckhhbmRzaGFrZShpbnQgc2Vzc2lvbiwgaW50IHMsIGludCBjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29ja2V0IHNvY2ssIEZpbGVEZXNjcmlwdG9yIGZkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGNhbGxiYWNrKQorICAgICAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfcmVuZWdvdGlhdGUocyk7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF93cml0ZShzLCBmZCwgY2FsbGJhY2ssIG5ldyBieXRlW10geyA0MiB9LCAwLCAxKTsKKyAgICAgICAgICAgICAgICBzdXBlci5hZnRlckhhbmRzaGFrZShzZXNzaW9uLCBzLCBjLCBzb2NrLCBmZCwgY2FsbGJhY2spOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gY2xpZW50ID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCB0cnVlLCBjSG9va3MpOworICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gc2VydmVyID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCBmYWxzZSwgc0hvb2tzKTsKKyAgICAgICAgY2xpZW50LmdldChUSU1FT1VUX1NFQ09ORFMsIFRpbWVVbml0LlNFQ09ORFMpOworICAgICAgICBzZXJ2ZXIuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfZ2V0X2NlcnRpZmljYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2dldF9jZXJ0aWZpY2F0ZShOVUxMKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIFNlcnZlclNvY2tldCBsaXN0ZW5lciA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisgICAgICAgIEhvb2tzIGNIb29rcyA9IG5ldyBIb29rcygpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgYWZ0ZXJIYW5kc2hha2UoaW50IHNlc3Npb24sIGludCBzLCBpbnQgYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvY2tldCBzb2NrLCBGaWxlRGVzY3JpcHRvciBmZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTEhhbmRzaGFrZUNhbGxiYWNrcyBjYWxsYmFjaykKKyAgICAgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKE5hdGl2ZUNyeXB0by5TU0xfZ2V0X2NlcnRpZmljYXRlKHMpKTsKKyAgICAgICAgICAgICAgICBzdXBlci5hZnRlckhhbmRzaGFrZShzZXNzaW9uLCBzLCBjLCBzb2NrLCBmZCwgY2FsbGJhY2spOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBIb29rcyBzSG9va3MgPSBuZXcgU2VydmVySG9va3MoZ2V0U2VydmVyUHJpdmF0ZUtleSgpLCBnZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBhZnRlckhhbmRzaGFrZShpbnQgc2Vzc2lvbiwgaW50IHMsIGludCBjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29ja2V0IHNvY2ssIEZpbGVEZXNjcmlwdG9yIGZkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGNhbGxiYWNrKQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbENlcnRpZmljYXRlQ2hhaW5zKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0U2VydmVyQ2VydGlmaWNhdGVzKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2dldF9jZXJ0aWZpY2F0ZShzKSk7CisgICAgICAgICAgICAgICAgc3VwZXIuYWZ0ZXJIYW5kc2hha2Uoc2Vzc2lvbiwgcywgYywgc29jaywgZmQsIGNhbGxiYWNrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgRnV0dXJlPFRlc3RTU0xIYW5kc2hha2VDYWxsYmFja3M+IGNsaWVudCA9IGhhbmRzaGFrZShsaXN0ZW5lciwgMCwgdHJ1ZSwgY0hvb2tzKTsKKyAgICAgICAgRnV0dXJlPFRlc3RTU0xIYW5kc2hha2VDYWxsYmFja3M+IHNlcnZlciA9IGhhbmRzaGFrZShsaXN0ZW5lciwgMCwgZmFsc2UsIHNIb29rcyk7CisgICAgICAgIGNsaWVudC5nZXQoVElNRU9VVF9TRUNPTkRTLCBUaW1lVW5pdC5TRUNPTkRTKTsKKyAgICAgICAgc2VydmVyLmdldChUSU1FT1VUX1NFQ09ORFMsIFRpbWVVbml0LlNFQ09ORFMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX2dldF9wZWVyX2NlcnRfY2hhaW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfZ2V0X3BlZXJfY2VydF9jaGFpbihOVUxMKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIFNlcnZlclNvY2tldCBsaXN0ZW5lciA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisKKyAgICAgICAgSG9va3MgY0hvb2tzID0gbmV3IEhvb2tzKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBhZnRlckhhbmRzaGFrZShpbnQgc2Vzc2lvbiwgaW50IHMsIGludCBjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29ja2V0IHNvY2ssIEZpbGVEZXNjcmlwdG9yIGZkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGNhbGxiYWNrKQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBieXRlW11bXSBjYyA9IE5hdGl2ZUNyeXB0by5TU0xfZ2V0X3BlZXJfY2VydF9jaGFpbihzKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbENlcnRpZmljYXRlQ2hhaW5zKGdldFNlcnZlckNlcnRpZmljYXRlcygpLCBjYyk7CisgICAgICAgICAgICAgICAgc3VwZXIuYWZ0ZXJIYW5kc2hha2Uoc2Vzc2lvbiwgcywgYywgc29jaywgZmQsIGNhbGxiYWNrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgSG9va3Mgc0hvb2tzID0gbmV3IFNlcnZlckhvb2tzKGdldFNlcnZlclByaXZhdGVLZXkoKSwgZ2V0U2VydmVyQ2VydGlmaWNhdGVzKCkpOworICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gY2xpZW50ID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCB0cnVlLCBjSG9va3MpOworICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gc2VydmVyID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCBmYWxzZSwgc0hvb2tzKTsKKyAgICAgICAgY2xpZW50LmdldChUSU1FT1VUX1NFQ09ORFMsIFRpbWVVbml0LlNFQ09ORFMpOworICAgICAgICBzZXJ2ZXIuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgfQorCisgICAgZmluYWwgYnl0ZVtdIEJZVEVTID0gbmV3IGJ5dGVbXSB7IDIsIC0zLCA1LCAxMjcsIDAsIC0xMjggfTsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX3JlYWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICAvLyBOVUxMIHNzbAorICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9yZWFkKE5VTEwsIG51bGwsIG51bGwsIG51bGwsIDAsIDAsIDApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gbnVsbCBGaWxlRGVzY3JpcHRvcgorICAgICAgICB7CisgICAgICAgICAgICBpbnQgYyA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICAgICAgaW50IHMgPSBOYXRpdmVDcnlwdG8uU1NMX25ldyhjKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9yZWFkKHMsIG51bGwsIERVTU1ZX0NCLCBudWxsLCAwLCAwLCAwKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9mcmVlKHMpOworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9DVFhfZnJlZShjKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIG51bGwgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzCisgICAgICAgIHsKKyAgICAgICAgICAgIGludCBjID0gTmF0aXZlQ3J5cHRvLlNTTF9DVFhfbmV3KCk7CisgICAgICAgICAgICBpbnQgcyA9IE5hdGl2ZUNyeXB0by5TU0xfbmV3KGMpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3JlYWQocywgSU5WQUxJRF9GRCwgbnVsbCwgbnVsbCwgMCwgMCwgMCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfZnJlZShzKTsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoYyk7CisgICAgICAgIH0KKworICAgICAgICAvLyBudWxsIGJ5dGUgYXJyYXkKKyAgICAgICAgeworICAgICAgICAgICAgaW50IGMgPSBOYXRpdmVDcnlwdG8uU1NMX0NUWF9uZXcoKTsKKyAgICAgICAgICAgIGludCBzID0gTmF0aXZlQ3J5cHRvLlNTTF9uZXcoYyk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfcmVhZChzLCBJTlZBTElEX0ZELCBEVU1NWV9DQiwgbnVsbCwgMCwgMCwgMCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfZnJlZShzKTsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoYyk7CisgICAgICAgIH0KKworICAgICAgICAvLyBoYW5kc2hha2luZyBub3QgeWV0IHBlcmZvcm1lZAorICAgICAgICB7CisgICAgICAgICAgICBpbnQgYyA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICAgICAgaW50IHMgPSBOYXRpdmVDcnlwdG8uU1NMX25ldyhjKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9yZWFkKHMsIElOVkFMSURfRkQsIERVTU1ZX0NCLCBuZXcgYnl0ZVsxXSwgMCwgMSwgMCk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1NMRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2ZyZWUocyk7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX0NUWF9mcmVlKGMpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgU2VydmVyU29ja2V0IGxpc3RlbmVyID0gbmV3IFNlcnZlclNvY2tldCgwKTsKKworICAgICAgICAvLyBub3JtYWwgY2FzZQorICAgICAgICB7CisgICAgICAgICAgICBIb29rcyBjSG9va3MgPSBuZXcgSG9va3MoKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgYWZ0ZXJIYW5kc2hha2UoaW50IHNlc3Npb24sIGludCBzLCBpbnQgYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb2NrZXQgc29jaywgRmlsZURlc2NyaXB0b3IgZmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGNhbGxiYWNrKQorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBpbiA9IG5ldyBieXRlWzI1Nl07CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhCWVRFUy5sZW5ndGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3JlYWQocywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJZVEVTLmxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKSk7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQllURVMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhCWVRFU1tpXSwgaW5baV0pOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHN1cGVyLmFmdGVySGFuZHNoYWtlKHNlc3Npb24sIHMsIGMsIHNvY2ssIGZkLCBjYWxsYmFjayk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfTsKKyAgICAgICAgICAgIEhvb2tzIHNIb29rcyA9IG5ldyBTZXJ2ZXJIb29rcyhnZXRTZXJ2ZXJQcml2YXRlS2V5KCksIGdldFNlcnZlckNlcnRpZmljYXRlcygpKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgYWZ0ZXJIYW5kc2hha2UoaW50IHNlc3Npb24sIGludCBzLCBpbnQgYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb2NrZXQgc29jaywgRmlsZURlc2NyaXB0b3IgZmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGNhbGxiYWNrKQorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfd3JpdGUocywgZmQsIGNhbGxiYWNrLCBCWVRFUywgMCwgQllURVMubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgc3VwZXIuYWZ0ZXJIYW5kc2hha2Uoc2Vzc2lvbiwgcywgYywgc29jaywgZmQsIGNhbGxiYWNrKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9OworICAgICAgICAgICAgRnV0dXJlPFRlc3RTU0xIYW5kc2hha2VDYWxsYmFja3M+IGNsaWVudCA9IGhhbmRzaGFrZShsaXN0ZW5lciwgMCwgdHJ1ZSwgY0hvb2tzKTsKKyAgICAgICAgICAgIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBzZXJ2ZXIgPSBoYW5kc2hha2UobGlzdGVuZXIsIDAsIGZhbHNlLCBzSG9va3MpOworICAgICAgICAgICAgY2xpZW50LmdldChUSU1FT1VUX1NFQ09ORFMsIFRpbWVVbml0LlNFQ09ORFMpOworICAgICAgICAgICAgc2VydmVyLmdldChUSU1FT1VUX1NFQ09ORFMsIFRpbWVVbml0LlNFQ09ORFMpOworICAgICAgICB9CisKKyAgICAgICAgLy8gdGltZW91dCBjYXNlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBIb29rcyBjSG9va3MgPSBuZXcgSG9va3MoKSB7CisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgYWZ0ZXJIYW5kc2hha2UoaW50IHNlc3Npb24sIGludCBzLCBpbnQgYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb2NrZXQgc29jaywgRmlsZURlc2NyaXB0b3IgZmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGNhbGxiYWNrKQorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfcmVhZChzLCBmZCwgY2FsbGJhY2ssIG5ldyBieXRlWzFdLCAwLCAxLCAxKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgICAgICBIb29rcyBzSG9va3MgPSBuZXcgU2VydmVySG9va3MoZ2V0U2VydmVyUHJpdmF0ZUtleSgpLCBnZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFmdGVySGFuZHNoYWtlKGludCBzZXNzaW9uLCBpbnQgcywgaW50IGMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29ja2V0IHNvY2ssIEZpbGVEZXNjcmlwdG9yIGZkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTEhhbmRzaGFrZUNhbGxiYWNrcyBjYWxsYmFjaykKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3JlYWQocywgZmQsIGNhbGxiYWNrLCBuZXcgYnl0ZVsxXSwgMCwgMSwgMCk7CisgICAgICAgICAgICAgICAgICAgIHN1cGVyLmFmdGVySGFuZHNoYWtlKHNlc3Npb24sIHMsIGMsIHNvY2ssIGZkLCBjYWxsYmFjayk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfTsKKyAgICAgICAgICAgIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBjbGllbnQgPSBoYW5kc2hha2UobGlzdGVuZXIsIDAsIHRydWUsIGNIb29rcyk7CisgICAgICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gc2VydmVyID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCBmYWxzZSwgc0hvb2tzKTsKKyAgICAgICAgICAgIGNsaWVudC5nZXQoVElNRU9VVF9TRUNPTkRTLCBUaW1lVW5pdC5TRUNPTkRTKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhlY3V0aW9uRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoU29ja2V0VGltZW91dEV4Y2VwdGlvbi5jbGFzcywgZXhwZWN0ZWQuZ2V0Q2F1c2UoKS5nZXRDbGFzcygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX3dyaXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3dyaXRlKE5VTEwsIG51bGwsIG51bGwsIG51bGwsIDAsIDApOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gbnVsbCBGaWxlRGVzY3JpcHRvcgorICAgICAgICB7CisgICAgICAgICAgICBpbnQgYyA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICAgICAgaW50IHMgPSBOYXRpdmVDcnlwdG8uU1NMX25ldyhjKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF93cml0ZShzLCBudWxsLCBEVU1NWV9DQiwgbnVsbCwgMCwgMSk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfZnJlZShzKTsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoYyk7CisgICAgICAgIH0KKworICAgICAgICAvLyBudWxsIFNTTEhhbmRzaGFrZUNhbGxiYWNrcworICAgICAgICB7CisgICAgICAgICAgICBpbnQgYyA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICAgICAgaW50IHMgPSBOYXRpdmVDcnlwdG8uU1NMX25ldyhjKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF93cml0ZShzLCBJTlZBTElEX0ZELCBudWxsLCBudWxsLCAwLCAxKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9mcmVlKHMpOworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9DVFhfZnJlZShjKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIG51bGwgYnl0ZSBhcnJheQorICAgICAgICB7CisgICAgICAgICAgICBpbnQgYyA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICAgICAgaW50IHMgPSBOYXRpdmVDcnlwdG8uU1NMX25ldyhjKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF93cml0ZShzLCBJTlZBTElEX0ZELCBEVU1NWV9DQiwgbnVsbCwgMCwgMSk7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfZnJlZShzKTsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoYyk7CisgICAgICAgIH0KKworICAgICAgICAvLyBoYW5kc2hha2luZyBub3QgeWV0IHBlcmZvcm1lZAorICAgICAgICB7CisgICAgICAgICAgICBpbnQgYyA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICAgICAgaW50IHMgPSBOYXRpdmVDcnlwdG8uU1NMX25ldyhjKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF93cml0ZShzLCBJTlZBTElEX0ZELCBEVU1NWV9DQiwgbmV3IGJ5dGVbMV0sIDAsIDEpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNTTEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9mcmVlKHMpOworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9DVFhfZnJlZShjKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHBvc2l0aXZlbHkgdGVzdGVkIGJ5IHRlc3RfU1NMX3JlYWQKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTF9pbnRlcnJ1cHQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gU1NMX2ludGVycnVwdCBpcyBhIHJhcmUgY2FzZSB0aGF0IHRvbGVyYXRlcyBhIG51bGwgU1NMIGFyZ3VtZW50CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfaW50ZXJydXB0KE5VTEwpOworCisgICAgICAgIC8vIGFsc28gd29ya3Mgd2l0aG91dCBoYW5kc2hha2luZworICAgICAgICB7CisgICAgICAgICAgICBpbnQgYyA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICAgICAgaW50IHMgPSBOYXRpdmVDcnlwdG8uU1NMX25ldyhjKTsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfaW50ZXJydXB0KHMpOworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9mcmVlKHMpOworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9DVFhfZnJlZShjKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIFNlcnZlclNvY2tldCBsaXN0ZW5lciA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisKKyAgICAgICAgSG9va3MgY0hvb2tzID0gbmV3IEhvb2tzKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBhZnRlckhhbmRzaGFrZShpbnQgc2Vzc2lvbiwgaW50IHMsIGludCBjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29ja2V0IHNvY2ssIEZpbGVEZXNjcmlwdG9yIGZkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGNhbGxiYWNrKQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3JlYWQocywgZmQsIGNhbGxiYWNrLCBuZXcgYnl0ZVsxXSwgMCwgMSwgMCk7CisgICAgICAgICAgICAgICAgc3VwZXIuYWZ0ZXJIYW5kc2hha2Uoc2Vzc2lvbiwgcywgYywgc29jaywgZmQsIGNhbGxiYWNrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgSG9va3Mgc0hvb2tzID0gbmV3IFNlcnZlckhvb2tzKGdldFNlcnZlclByaXZhdGVLZXkoKSwgZ2V0U2VydmVyQ2VydGlmaWNhdGVzKCkpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgYWZ0ZXJIYW5kc2hha2UoaW50IHNlc3Npb24sIGZpbmFsIGludCBzLCBpbnQgYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvY2tldCBzb2NrLCBGaWxlRGVzY3JpcHRvciBmZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTEhhbmRzaGFrZUNhbGxiYWNrcyBjYWxsYmFjaykKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgbmV3IFRocmVhZCgpIHsKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMSoxMDAwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2ludGVycnVwdChzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9LnN0YXJ0KCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBOYXRpdmVDcnlwdG8uU1NMX3JlYWQocywgZmQsIGNhbGxiYWNrLCBuZXcgYnl0ZVsxXSwgMCwgMSwgMCkpOworICAgICAgICAgICAgICAgIHN1cGVyLmFmdGVySGFuZHNoYWtlKHNlc3Npb24sIHMsIGMsIHNvY2ssIGZkLCBjYWxsYmFjayk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBjbGllbnQgPSBoYW5kc2hha2UobGlzdGVuZXIsIDAsIHRydWUsIGNIb29rcyk7CisgICAgICAgIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBzZXJ2ZXIgPSBoYW5kc2hha2UobGlzdGVuZXIsIDAsIGZhbHNlLCBzSG9va3MpOworICAgICAgICBjbGllbnQuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgICAgIHNlcnZlci5nZXQoVElNRU9VVF9TRUNPTkRTLCBUaW1lVW5pdC5TRUNPTkRTKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTF9zaHV0ZG93bigpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIC8vIG51bGwgRmlsZURlc2NyaXB0b3IKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfc2h1dGRvd24oTlVMTCwgbnVsbCwgRFVNTVlfQ0IpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gbnVsbCBTU0xIYW5kc2hha2VDYWxsYmFja3MKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfc2h1dGRvd24oTlVMTCwgSU5WQUxJRF9GRCwgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICAvLyBTU0xfc2h1dGRvd24gaXMgYSByYXJlIGNhc2UgdGhhdCB0b2xlcmF0ZXMgYSBudWxsIFNTTCBhcmd1bWVudAorICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX3NodXRkb3duKE5VTEwsIElOVkFMSURfRkQsIERVTU1ZX0NCKTsKKworICAgICAgICAvLyBoYW5kc2hha2luZyBub3QgeWV0IHBlcmZvcm1lZAorICAgICAgICBpbnQgYyA9IE5hdGl2ZUNyeXB0by5TU0xfQ1RYX25ldygpOworICAgICAgICBpbnQgcyA9IE5hdGl2ZUNyeXB0by5TU0xfbmV3KGMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9zaHV0ZG93bihzLCBJTlZBTElEX0ZELCBEVU1NWV9DQik7CisgICAgICAgIH0gY2F0Y2ggKFNTTFByb3RvY29sRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9mcmVlKHMpOworICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX0NUWF9mcmVlKGMpOworCisgICAgICAgIC8vIHBvc2l0aXZlbHkgdGVzdGVkIGVsc2V3aGVyZSBiZWNhdXNlIGhhbmRzaGFrZSB1c2VzIHVzZQorICAgICAgICAvLyBTU0xfc2h1dGRvd24gdG8gZW5zdXJlIFNTTF9TRVNTSU9OcyBhcmUgcmV1c2VkLgorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX2ZyZWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfZnJlZShOVUxMKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGludCBjID0gTmF0aXZlQ3J5cHRvLlNTTF9DVFhfbmV3KCk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfZnJlZShOYXRpdmVDcnlwdG8uU1NMX25ldyhjKSk7CisgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfQ1RYX2ZyZWUoYyk7CisKKyAgICAgICAgLy8gYWRkaXRpb25hbCBwb3NpdGl2ZSB0ZXN0aW5nIGVsc2V3aGVyZSBiZWNhdXNlIGhhbmRzaGFrZQorICAgICAgICAvLyB1c2VzIHVzZSBTU0xfZnJlZSB0byBjbGVhbnVwIGluIGFmdGVySGFuZHNoYWtlLgorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX1NFU1NJT05fc2Vzc2lvbl9pZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9TRVNTSU9OX3Nlc3Npb25faWQoTlVMTCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBTZXJ2ZXJTb2NrZXQgbGlzdGVuZXIgPSBuZXcgU2VydmVyU29ja2V0KDApOworCisgICAgICAgIEhvb2tzIGNIb29rcyA9IG5ldyBIb29rcygpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgYWZ0ZXJIYW5kc2hha2UoaW50IHNlc3Npb24sIGludCBzLCBpbnQgYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvY2tldCBzb2NrLCBGaWxlRGVzY3JpcHRvciBmZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTEhhbmRzaGFrZUNhbGxiYWNrcyBjYWxsYmFjaykKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGlkID0gTmF0aXZlQ3J5cHRvLlNTTF9TRVNTSU9OX3Nlc3Npb25faWQoc2Vzc2lvbik7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChpZCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMyLCBpZC5sZW5ndGgpOworICAgICAgICAgICAgICAgIHN1cGVyLmFmdGVySGFuZHNoYWtlKHNlc3Npb24sIHMsIGMsIHNvY2ssIGZkLCBjYWxsYmFjayk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIEhvb2tzIHNIb29rcyA9IG5ldyBTZXJ2ZXJIb29rcyhnZXRTZXJ2ZXJQcml2YXRlS2V5KCksIGdldFNlcnZlckNlcnRpZmljYXRlcygpKTsKKyAgICAgICAgRnV0dXJlPFRlc3RTU0xIYW5kc2hha2VDYWxsYmFja3M+IGNsaWVudCA9IGhhbmRzaGFrZShsaXN0ZW5lciwgMCwgdHJ1ZSwgY0hvb2tzKTsKKyAgICAgICAgRnV0dXJlPFRlc3RTU0xIYW5kc2hha2VDYWxsYmFja3M+IHNlcnZlciA9IGhhbmRzaGFrZShsaXN0ZW5lciwgMCwgZmFsc2UsIHNIb29rcyk7CisgICAgICAgIGNsaWVudC5nZXQoVElNRU9VVF9TRUNPTkRTLCBUaW1lVW5pdC5TRUNPTkRTKTsKKyAgICAgICAgc2VydmVyLmdldChUSU1FT1VUX1NFQ09ORFMsIFRpbWVVbml0LlNFQ09ORFMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX1NFU1NJT05fZ2V0X3RpbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfU0VTU0lPTl9nZXRfdGltZShOVUxMKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIFNlcnZlclNvY2tldCBsaXN0ZW5lciA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisKKyAgICAgICAgeworICAgICAgICAgICAgSG9va3MgY0hvb2tzID0gbmV3IEhvb2tzKCkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFmdGVySGFuZHNoYWtlKGludCBzZXNzaW9uLCBpbnQgcywgaW50IGMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29ja2V0IHNvY2ssIEZpbGVEZXNjcmlwdG9yIGZkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTEhhbmRzaGFrZUNhbGxiYWNrcyBjYWxsYmFjaykKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICBsb25nIHRpbWUgPSBOYXRpdmVDcnlwdG8uU1NMX1NFU1NJT05fZ2V0X3RpbWUoc2Vzc2lvbik7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUodGltZSAhPSAwKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSh0aW1lIDwgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworICAgICAgICAgICAgICAgICAgICBzdXBlci5hZnRlckhhbmRzaGFrZShzZXNzaW9uLCBzLCBjLCBzb2NrLCBmZCwgY2FsbGJhY2spOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgICAgICBIb29rcyBzSG9va3MgPSBuZXcgU2VydmVySG9va3MoZ2V0U2VydmVyUHJpdmF0ZUtleSgpLCBnZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gY2xpZW50ID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCB0cnVlLCBjSG9va3MpOworICAgICAgICAgICAgRnV0dXJlPFRlc3RTU0xIYW5kc2hha2VDYWxsYmFja3M+IHNlcnZlciA9IGhhbmRzaGFrZShsaXN0ZW5lciwgMCwgZmFsc2UsIHNIb29rcyk7CisgICAgICAgICAgICBjbGllbnQuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgICAgICAgICBzZXJ2ZXIuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTF9TRVNTSU9OX2dldF92ZXJzaW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX1NFU1NJT05fZ2V0X3ZlcnNpb24oTlVMTCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBTZXJ2ZXJTb2NrZXQgbGlzdGVuZXIgPSBuZXcgU2VydmVyU29ja2V0KDApOworCisgICAgICAgIEhvb2tzIGNIb29rcyA9IG5ldyBIb29rcygpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgYWZ0ZXJIYW5kc2hha2UoaW50IHNlc3Npb24sIGludCBzLCBpbnQgYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvY2tldCBzb2NrLCBGaWxlRGVzY3JpcHRvciBmZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTEhhbmRzaGFrZUNhbGxiYWNrcyBjYWxsYmFjaykKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHYgPSBOYXRpdmVDcnlwdG8uU1NMX1NFU1NJT05fZ2V0X3ZlcnNpb24oc2Vzc2lvbik7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShTdGFuZGFyZE5hbWVzLlNTTF9TT0NLRVRfUFJPVE9DT0xTLmNvbnRhaW5zKHYpKTsKKyAgICAgICAgICAgICAgICBzdXBlci5hZnRlckhhbmRzaGFrZShzZXNzaW9uLCBzLCBjLCBzb2NrLCBmZCwgY2FsbGJhY2spOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBIb29rcyBzSG9va3MgPSBuZXcgU2VydmVySG9va3MoZ2V0U2VydmVyUHJpdmF0ZUtleSgpLCBnZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSk7CisgICAgICAgIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBjbGllbnQgPSBoYW5kc2hha2UobGlzdGVuZXIsIDAsIHRydWUsIGNIb29rcyk7CisgICAgICAgIEZ1dHVyZTxUZXN0U1NMSGFuZHNoYWtlQ2FsbGJhY2tzPiBzZXJ2ZXIgPSBoYW5kc2hha2UobGlzdGVuZXIsIDAsIGZhbHNlLCBzSG9va3MpOworICAgICAgICBjbGllbnQuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgICAgIHNlcnZlci5nZXQoVElNRU9VVF9TRUNPTkRTLCBUaW1lVW5pdC5TRUNPTkRTKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NTTF9TRVNTSU9OX2NpcGhlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9TRVNTSU9OX2NpcGhlcihOVUxMKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIFNlcnZlclNvY2tldCBsaXN0ZW5lciA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisKKyAgICAgICAgSG9va3MgY0hvb2tzID0gbmV3IEhvb2tzKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBhZnRlckhhbmRzaGFrZShpbnQgc2Vzc2lvbiwgaW50IHMsIGludCBjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29ja2V0IHNvY2ssIEZpbGVEZXNjcmlwdG9yIGZkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGNhbGxiYWNrKQorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgU3RyaW5nIGEgPSBOYXRpdmVDcnlwdG8uU1NMX1NFU1NJT05fY2lwaGVyKHNlc3Npb24pOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoTmF0aXZlQ3J5cHRvLk9QRU5TU0xfVE9fU1RBTkRBUkRfQ0lQSEVSX1NVSVRFUy5jb250YWluc0tleShhKSk7CisgICAgICAgICAgICAgICAgc3VwZXIuYWZ0ZXJIYW5kc2hha2Uoc2Vzc2lvbiwgcywgYywgc29jaywgZmQsIGNhbGxiYWNrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgSG9va3Mgc0hvb2tzID0gbmV3IFNlcnZlckhvb2tzKGdldFNlcnZlclByaXZhdGVLZXkoKSwgZ2V0U2VydmVyQ2VydGlmaWNhdGVzKCkpOworICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gY2xpZW50ID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCB0cnVlLCBjSG9va3MpOworICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gc2VydmVyID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCBmYWxzZSwgc0hvb2tzKTsKKyAgICAgICAgY2xpZW50LmdldChUSU1FT1VUX1NFQ09ORFMsIFRpbWVVbml0LlNFQ09ORFMpOworICAgICAgICBzZXJ2ZXIuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfU0VTU0lPTl9jb21wcmVzc19tZXRoX251bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5TU0xfU0VTU0lPTl9jb21wcmVzc19tZXRoKE5VTEwsIE5VTEwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgeworICAgICAgICAgICAgaW50IGMgPSBOYXRpdmVDcnlwdG8uU1NMX0NUWF9uZXcoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9TRVNTSU9OX2NvbXByZXNzX21ldGgoYywgTlVMTCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9DVFhfZnJlZShjKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMX1NFU1NJT05fY29tcHJlc3NfbWV0aF9OVUxMKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFNlcnZlclNvY2tldCBsaXN0ZW5lciA9IG5ldyBTZXJ2ZXJTb2NrZXQoMCk7CisKKyAgICAgICAgSG9va3MgY0hvb2tzID0gbmV3IEhvb2tzKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBhZnRlckhhbmRzaGFrZShpbnQgc2Vzc2lvbiwgaW50IHMsIGludCBjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29ja2V0IHNvY2ssIEZpbGVEZXNjcmlwdG9yIGZkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMSGFuZHNoYWtlQ2FsbGJhY2tzIGNhbGxiYWNrKQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIk5VTEwiLCBOYXRpdmVDcnlwdG8uU1NMX1NFU1NJT05fY29tcHJlc3NfbWV0aChjLCBzZXNzaW9uKSk7CisgICAgICAgICAgICAgICAgc3VwZXIuYWZ0ZXJIYW5kc2hha2Uoc2Vzc2lvbiwgcywgYywgc29jaywgZmQsIGNhbGxiYWNrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgSG9va3Mgc0hvb2tzID0gbmV3IFNlcnZlckhvb2tzKGdldFNlcnZlclByaXZhdGVLZXkoKSwgZ2V0U2VydmVyQ2VydGlmaWNhdGVzKCkpOworICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gY2xpZW50ID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCB0cnVlLCBjSG9va3MpOworICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gc2VydmVyID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCBmYWxzZSwgc0hvb2tzKTsKKyAgICAgICAgY2xpZW50LmdldChUSU1FT1VUX1NFQ09ORFMsIFRpbWVVbml0LlNFQ09ORFMpOworICAgICAgICBzZXJ2ZXIuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfU0VTU0lPTl9jb21wcmVzc19tZXRoX1pMSUIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU2VydmVyU29ja2V0IGxpc3RlbmVyID0gbmV3IFNlcnZlclNvY2tldCgwKTsKKworICAgICAgICBIb29rcyBjSG9va3MgPSBuZXcgSG9va3MoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgYmVmb3JlSGFuZHNoYWtlKGludCBjKSB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBpbnQgcyA9IHN1cGVyLmJlZm9yZUhhbmRzaGFrZShjKTsKKyAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX2NsZWFyX29wdGlvbnMocywgTmF0aXZlQ3J5cHRvLlNTTF9PUF9OT19DT01QUkVTU0lPTik7CisgICAgICAgICAgICAgICAgcmV0dXJuIHM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFmdGVySGFuZHNoYWtlKGludCBzZXNzaW9uLCBpbnQgcywgaW50IGMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb2NrZXQgc29jaywgRmlsZURlc2NyaXB0b3IgZmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xIYW5kc2hha2VDYWxsYmFja3MgY2FsbGJhY2spCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiWkxJQiIsIE5hdGl2ZUNyeXB0by5TU0xfU0VTU0lPTl9jb21wcmVzc19tZXRoKGMsIHNlc3Npb24pKTsKKyAgICAgICAgICAgICAgICBzdXBlci5hZnRlckhhbmRzaGFrZShzZXNzaW9uLCBzLCBjLCBzb2NrLCBmZCwgY2FsbGJhY2spOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBIb29rcyBzSG9va3MgPSBuZXcgU2VydmVySG9va3MoZ2V0U2VydmVyUHJpdmF0ZUtleSgpLCBnZXRTZXJ2ZXJDZXJ0aWZpY2F0ZXMoKSkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgaW50IGJlZm9yZUhhbmRzaGFrZShpbnQgYykgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgaW50IHMgPSBzdXBlci5iZWZvcmVIYW5kc2hha2UoYyk7CisgICAgICAgICAgICAgICAgTmF0aXZlQ3J5cHRvLlNTTF9jbGVhcl9vcHRpb25zKHMsIE5hdGl2ZUNyeXB0by5TU0xfT1BfTk9fQ09NUFJFU1NJT04pOworICAgICAgICAgICAgICAgIHJldHVybiBzOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gY2xpZW50ID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCB0cnVlLCBjSG9va3MpOworICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gc2VydmVyID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCBmYWxzZSwgc0hvb2tzKTsKKyAgICAgICAgY2xpZW50LmdldChUSU1FT1VUX1NFQ09ORFMsIFRpbWVVbml0LlNFQ09ORFMpOworICAgICAgICBzZXJ2ZXIuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xfU0VTU0lPTl9mcmVlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX1NFU1NJT05fZnJlZShOVUxMKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGFkZGl0aW9uYWwgcG9zaXRpdmUgdGVzdGluZyBlbHNld2hlcmUgYmVjYXVzZSBoYW5kc2hha2UKKyAgICAgICAgLy8gdXNlcyB1c2UgU1NMX1NFU1NJT05fZnJlZSB0byBjbGVhbnVwIGluIGFmdGVySGFuZHNoYWtlLgorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaTJkX1NTTF9TRVNTSU9OKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBOYXRpdmVDcnlwdG8uaTJkX1NTTF9TRVNTSU9OKE5VTEwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgU2VydmVyU29ja2V0IGxpc3RlbmVyID0gbmV3IFNlcnZlclNvY2tldCgwKTsKKworICAgICAgICBIb29rcyBjSG9va3MgPSBuZXcgSG9va3MoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFmdGVySGFuZHNoYWtlKGludCBzZXNzaW9uLCBpbnQgcywgaW50IGMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb2NrZXQgc29jaywgRmlsZURlc2NyaXB0b3IgZmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xIYW5kc2hha2VDYWxsYmFja3MgY2FsbGJhY2spCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgIGJ5dGVbXSBiID0gTmF0aXZlQ3J5cHRvLmkyZF9TU0xfU0VTU0lPTihzZXNzaW9uKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGIpOworICAgICAgICAgICAgICAgIGludCBzZXNzaW9uMiA9IE5hdGl2ZUNyeXB0by5kMmlfU1NMX1NFU1NJT04oYik7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShzZXNzaW9uMiAhPSBOVUxMKTsKKyAgICAgICAgICAgICAgICBOYXRpdmVDcnlwdG8uU1NMX1NFU1NJT05fZnJlZShzZXNzaW9uMik7CisgICAgICAgICAgICAgICAgc3VwZXIuYWZ0ZXJIYW5kc2hha2Uoc2Vzc2lvbiwgcywgYywgc29jaywgZmQsIGNhbGxiYWNrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgSG9va3Mgc0hvb2tzID0gbmV3IFNlcnZlckhvb2tzKGdldFNlcnZlclByaXZhdGVLZXkoKSwgZ2V0U2VydmVyQ2VydGlmaWNhdGVzKCkpOworICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gY2xpZW50ID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCB0cnVlLCBjSG9va3MpOworICAgICAgICBGdXR1cmU8VGVzdFNTTEhhbmRzaGFrZUNhbGxiYWNrcz4gc2VydmVyID0gaGFuZHNoYWtlKGxpc3RlbmVyLCAwLCBmYWxzZSwgc0hvb2tzKTsKKyAgICAgICAgY2xpZW50LmdldChUSU1FT1VUX1NFQ09ORFMsIFRpbWVVbml0LlNFQ09ORFMpOworICAgICAgICBzZXJ2ZXIuZ2V0KFRJTUVPVVRfU0VDT05EUywgVGltZVVuaXQuU0VDT05EUyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9kMmlfU1NMX1NFU1NJT04oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE5hdGl2ZUNyeXB0by5kMmlfU1NMX1NFU1NJT04obnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoTlVMTCwgTmF0aXZlQ3J5cHRvLmQyaV9TU0xfU0VTU0lPTihuZXcgYnl0ZVswXSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoTlVMTCwgTmF0aXZlQ3J5cHRvLmQyaV9TU0xfU0VTU0lPTihuZXcgYnl0ZVsxXSkpOworCisgICAgICAgIC8vIHBvc2l0aXZlbHkgdGVzdGluZyBieSB0ZXN0X2kyZF9TU0xfU0VTU0lPTgorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfWDUwOV9OQU1FX2hhc2hlcygpIHsKKyAgICAgICAgLy8gZW5zdXJlIHRoZXNlIGhhc2ggZnVuY3Rpb25zIGFyZSBzdGFibGUgb3ZlciB0aW1lIHNpbmNlIHRoZQorICAgICAgICAvLyAvc3lzdGVtL2V0Yy9zZWN1cml0eS9jYWNlcnRzIENBIGZpbGVuYW1lcyBoYXZlIHRvIGJlCisgICAgICAgIC8vIGNvbnNpc3RlbnQgd2l0aCB0aGUgb3V0cHV0LgorICAgICAgICBYNTAwUHJpbmNpcGFsIG5hbWUgPSBuZXcgWDUwMFByaW5jaXBhbCgiQ049bG9jYWxob3N0Iik7CisgICAgICAgIGFzc2VydEVxdWFscygtMTM3MjY0MjY1NiwgTmF0aXZlQ3J5cHRvLlg1MDlfTkFNRV9oYXNoKG5hbWUpKTsgLy8gU0hBMQorICAgICAgICBhc3NlcnRFcXVhbHMoLTE2MjYxNzA2NjIsIE5hdGl2ZUNyeXB0by5YNTA5X05BTUVfaGFzaF9vbGQobmFtZSkpOyAvLyBNRDUKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvcHJvdmlkZXIvanNzZS9UcnVzdE1hbmFnZXJJbXBsVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvVHJ1c3RNYW5hZ2VySW1wbFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNmViYzg1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvVHJ1c3RNYW5hZ2VySW1wbFRlc3QuamF2YQpAQCAtMCwwICsxLDkyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlckZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5YNTA5VHJ1c3RNYW5hZ2VyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuVGVzdEtleVN0b3JlOworCitwdWJsaWMgY2xhc3MgVHJ1c3RNYW5hZ2VySW1wbFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBFbnN1cmUgdGhhdCBvdXIgbm9uLXN0YW5kYXJkIGJlaGF2aW9yIG9mIGxlYXJuaW5nIHRvIHRydXN0IG5ldworICAgICAqIGludGVybWVkaWF0ZSBDQXMgZG9lcyBub3QgcmVncmVzcy4gaHR0cDovL2IvMzQwNDkwMgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RMZWFybkludGVybWVkaWF0ZSgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIC8vIGNoYWluMyBzaG91bGQgYmUgc2VydmVyL2ludGVybWVkaWF0ZS9yb290CisgICAgICAgIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSBwa2UgPSBUZXN0S2V5U3RvcmUuZ2V0U2VydmVyKCkuZ2V0UHJpdmF0ZUtleSgiUlNBIiwgIlJTQSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGVbXSBjaGFpbjMgPSAoWDUwOUNlcnRpZmljYXRlW10pcGtlLmdldENlcnRpZmljYXRlQ2hhaW4oKTsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIHJvb3QgPSBjaGFpbjNbMl07CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBpbnRlcm1lZGlhdGUgPSBjaGFpbjNbMV07CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBzZXJ2ZXIgPSBjaGFpbjNbMF07CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIGNoYWluMiA9ICBuZXcgWDUwOUNlcnRpZmljYXRlW10geyBzZXJ2ZXIsIGludGVybWVkaWF0ZSB9OworICAgICAgICBYNTA5Q2VydGlmaWNhdGVbXSBjaGFpbjEgPSAgbmV3IFg1MDlDZXJ0aWZpY2F0ZVtdIHsgc2VydmVyIH07CisKKyAgICAgICAgLy8gTm9ybWFsIGJlaGF2aW9yCisgICAgICAgIGFzc2VydFZhbGlkKGNoYWluMywgICB0cnVzdE1hbmFnZXIocm9vdCkpOworICAgICAgICBhc3NlcnRWYWxpZChjaGFpbjIsICAgdHJ1c3RNYW5hZ2VyKHJvb3QpKTsKKyAgICAgICAgYXNzZXJ0SW52YWxpZChjaGFpbjEsIHRydXN0TWFuYWdlcihyb290KSk7CisgICAgICAgIGFzc2VydFZhbGlkKGNoYWluMywgICB0cnVzdE1hbmFnZXIoaW50ZXJtZWRpYXRlKSk7CisgICAgICAgIGFzc2VydFZhbGlkKGNoYWluMiwgICB0cnVzdE1hbmFnZXIoaW50ZXJtZWRpYXRlKSk7CisgICAgICAgIGFzc2VydFZhbGlkKGNoYWluMSwgICB0cnVzdE1hbmFnZXIoaW50ZXJtZWRpYXRlKSk7CisgICAgICAgIGFzc2VydFZhbGlkKGNoYWluMywgICB0cnVzdE1hbmFnZXIoc2VydmVyKSk7CisgICAgICAgIGFzc2VydFZhbGlkKGNoYWluMiwgICB0cnVzdE1hbmFnZXIoc2VydmVyKSk7CisgICAgICAgIGFzc2VydFZhbGlkKGNoYWluMSwgICB0cnVzdE1hbmFnZXIoc2VydmVyKSk7CisKKyAgICAgICAgLy8gbm9uLXN0YW5kYXJkIGJlaGF2aW9yCisgICAgICAgIFg1MDlUcnVzdE1hbmFnZXIgdG0gPSB0cnVzdE1hbmFnZXIocm9vdCk7CisgICAgICAgIC8vIGZhaWwgb24gc2hvcnQgY2hhaW4gd2l0aCBvbmx5IHJvb3QgdHJ1c3RlZAorICAgICAgICBhc3NlcnRJbnZhbGlkKGNoYWluMSwgdG0pOworICAgICAgICAvLyBzdWNjZWVkIG9uIGxvbmdlciBjaGFpbiwgbGVhcm4gaW50ZXJtZWRpYXRlCisgICAgICAgIGFzc2VydFZhbGlkKGNoYWluMiwgdG0pOworICAgICAgICAvLyBub3cgd2UgY2FuIHZhbGlkYXRlIHRoZSBzaG9ydCBjaGFpbgorICAgICAgICBhc3NlcnRWYWxpZChjaGFpbjEsIHRtKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFg1MDlUcnVzdE1hbmFnZXIgdHJ1c3RNYW5hZ2VyKFg1MDlDZXJ0aWZpY2F0ZSBjYSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEtleVN0b3JlIGtleVN0b3JlID0gVGVzdEtleVN0b3JlLmNyZWF0ZUtleVN0b3JlKCk7CisgICAgICAgIGtleVN0b3JlLnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzIiwgY2EpOworCisgICAgICAgIFN0cmluZyBhbGdvcml0aG0gPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldERlZmF1bHRBbGdvcml0aG0oKTsKKyAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeSB0bWYgPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgIHRtZi5pbml0KGtleVN0b3JlKTsKKyAgICAgICAgcmV0dXJuIChYNTA5VHJ1c3RNYW5hZ2VyKSB0bWYuZ2V0VHJ1c3RNYW5hZ2VycygpWzBdOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRWYWxpZChYNTA5Q2VydGlmaWNhdGVbXSBjaGFpbiwgWDUwOVRydXN0TWFuYWdlciB0bSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRtLmNoZWNrQ2xpZW50VHJ1c3RlZChjaGFpbiwgIlJTQSIpOworICAgICAgICB0bS5jaGVja1NlcnZlclRydXN0ZWQoY2hhaW4sICJSU0EiKTsKKyAgICB9CisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydEludmFsaWQoWDUwOUNlcnRpZmljYXRlW10gY2hhaW4sIFg1MDlUcnVzdE1hbmFnZXIgdG0pIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRtLmNoZWNrQ2xpZW50VHJ1c3RlZChjaGFpbiwgIlJTQSIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0bS5jaGVja1NlcnZlclRydXN0ZWQoY2hhaW4sICJSU0EiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1RydXN0ZWRDZXJ0aWZpY2F0ZVN0b3JlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Byb3ZpZGVyL2pzc2UvVHJ1c3RlZENlcnRpZmljYXRlU3RvcmVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmQwZjUwYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC9wcm92aWRlci9qc3NlL1RydXN0ZWRDZXJ0aWZpY2F0ZVN0b3JlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjMxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDExIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuVGVzdEtleVN0b3JlOworCitwdWJsaWMgY2xhc3MgVHJ1c3RlZENlcnRpZmljYXRlU3RvcmVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmlsZSBESVJfVEVNUCA9IG5ldyBGaWxlKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmlsZSBESVJfVEVTVCA9IG5ldyBGaWxlKERJUl9URU1QLCAidGVzdCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpbGUgRElSX1NZU1RFTSA9IG5ldyBGaWxlKERJUl9URVNULCAic3lzdGVtIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmlsZSBESVJfQURERUQgPSBuZXcgRmlsZShESVJfVEVTVCwgImFkZGVkIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmlsZSBESVJfREVMRVRFRCA9IG5ldyBGaWxlKERJUl9URVNULCAicmVtb3ZlZCIpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgWDUwOUNlcnRpZmljYXRlIENBMTsKKyAgICBwcml2YXRlIHN0YXRpYyBYNTA5Q2VydGlmaWNhdGUgQ0EyOworCisgICAgcHJpdmF0ZSBzdGF0aWMgS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5IFBSSVZBVEU7CisgICAgcHJpdmF0ZSBzdGF0aWMgWDUwOUNlcnRpZmljYXRlW10gQ0hBSU47CisKKyAgICBwcml2YXRlIHN0YXRpYyBYNTA5Q2VydGlmaWNhdGUgQ0EzX1dJVEhfQ0ExX1NVQkpFQ1Q7CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIEFMSUFTX1NZU1RFTV9DQTE7CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIEFMSUFTX1NZU1RFTV9DQTI7CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIEFMSUFTX1VTRVJfQ0ExOworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBBTElBU19VU0VSX0NBMjsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBBTElBU19TWVNURU1fQ0hBSU4wOworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBBTElBU19TWVNURU1fQ0hBSU4xOworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBBTElBU19TWVNURU1fQ0hBSU4yOworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBBTElBU19VU0VSX0NIQUlOMDsKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgQUxJQVNfVVNFUl9DSEFJTjE7CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIEFMSUFTX1VTRVJfQ0hBSU4yOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIEFMSUFTX1NZU1RFTV9DQTM7CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIEFMSUFTX1NZU1RFTV9DQTNfQ09MTElTSU9OOworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBBTElBU19VU0VSX0NBMzsKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgQUxJQVNfVVNFUl9DQTNfQ09MTElTSU9OOworCisgICAgcHJpdmF0ZSBzdGF0aWMgWDUwOUNlcnRpZmljYXRlIGdldENhMSgpIHsKKyAgICAgICAgaW5pdENlcnRzKCk7CisgICAgICAgIHJldHVybiBDQTE7CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIFg1MDlDZXJ0aWZpY2F0ZSBnZXRDYTIoKSB7CisgICAgICAgIGluaXRDZXJ0cygpOworICAgICAgICByZXR1cm4gQ0EyOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIEtleVN0b3JlLlByaXZhdGVLZXlFbnRyeSBnZXRQcml2YXRlKCkgeworICAgICAgICBpbml0Q2VydHMoKTsKKyAgICAgICAgcmV0dXJuIFBSSVZBVEU7CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIFg1MDlDZXJ0aWZpY2F0ZVtdIGdldENoYWluKCkgeworICAgICAgICBpbml0Q2VydHMoKTsKKyAgICAgICAgcmV0dXJuIENIQUlOOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFg1MDlDZXJ0aWZpY2F0ZSBnZXRDYTNXaXRoQ2ExU3ViamVjdCgpIHsKKyAgICAgICAgaW5pdENlcnRzKCk7CisgICAgICAgIHJldHVybiBDQTNfV0lUSF9DQTFfU1VCSkVDVDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0QWxpYXNTeXN0ZW1DYTEoKSB7CisgICAgICAgIGluaXRDZXJ0cygpOworICAgICAgICByZXR1cm4gQUxJQVNfU1lTVEVNX0NBMTsKKyAgICB9CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldEFsaWFzU3lzdGVtQ2EyKCkgeworICAgICAgICBpbml0Q2VydHMoKTsKKyAgICAgICAgcmV0dXJuIEFMSUFTX1NZU1RFTV9DQTI7CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRBbGlhc1VzZXJDYTEoKSB7CisgICAgICAgIGluaXRDZXJ0cygpOworICAgICAgICByZXR1cm4gQUxJQVNfVVNFUl9DQTE7CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRBbGlhc1VzZXJDYTIoKSB7CisgICAgICAgIGluaXRDZXJ0cygpOworICAgICAgICByZXR1cm4gQUxJQVNfVVNFUl9DQTI7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldEFsaWFzU3lzdGVtQ2hhaW4wKCkgeworICAgICAgICBpbml0Q2VydHMoKTsKKyAgICAgICAgcmV0dXJuIEFMSUFTX1NZU1RFTV9DSEFJTjA7CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRBbGlhc1N5c3RlbUNoYWluMSgpIHsKKyAgICAgICAgaW5pdENlcnRzKCk7CisgICAgICAgIHJldHVybiBBTElBU19TWVNURU1fQ0hBSU4xOworICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0QWxpYXNTeXN0ZW1DaGFpbjIoKSB7CisgICAgICAgIGluaXRDZXJ0cygpOworICAgICAgICByZXR1cm4gQUxJQVNfU1lTVEVNX0NIQUlOMjsKKyAgICB9CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldEFsaWFzVXNlckNoYWluMCgpIHsKKyAgICAgICAgaW5pdENlcnRzKCk7CisgICAgICAgIHJldHVybiBBTElBU19VU0VSX0NIQUlOMDsKKyAgICB9CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldEFsaWFzVXNlckNoYWluMSgpIHsKKyAgICAgICAgaW5pdENlcnRzKCk7CisgICAgICAgIHJldHVybiBBTElBU19VU0VSX0NIQUlOMTsKKyAgICB9CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldEFsaWFzVXNlckNoYWluMigpIHsKKyAgICAgICAgaW5pdENlcnRzKCk7CisgICAgICAgIHJldHVybiBBTElBU19VU0VSX0NIQUlOMjsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0QWxpYXNTeXN0ZW1DYTMoKSB7CisgICAgICAgIGluaXRDZXJ0cygpOworICAgICAgICByZXR1cm4gQUxJQVNfU1lTVEVNX0NBMzsKKyAgICB9CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldEFsaWFzU3lzdGVtQ2EzQ29sbGlzaW9uKCkgeworICAgICAgICBpbml0Q2VydHMoKTsKKyAgICAgICAgcmV0dXJuIEFMSUFTX1NZU1RFTV9DQTNfQ09MTElTSU9OOworICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0QWxpYXNVc2VyQ2EzKCkgeworICAgICAgICBpbml0Q2VydHMoKTsKKyAgICAgICAgcmV0dXJuIEFMSUFTX1VTRVJfQ0EzOworICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0QWxpYXNVc2VyQ2EzQ29sbGlzaW9uKCkgeworICAgICAgICBpbml0Q2VydHMoKTsKKyAgICAgICAgcmV0dXJuIEFMSUFTX1VTRVJfQ0EzX0NPTExJU0lPTjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMYXppbHkgY3JlYXRlIHNoYXJlZCB0ZXN0IGNlcnRpZmljYXRlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBzeW5jaHJvbml6ZWQgdm9pZCBpbml0Q2VydHMoKSB7CisgICAgICAgIGlmIChDQTEgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDQTEgPSBUZXN0S2V5U3RvcmUuZ2V0Q2xpZW50KCkuZ2V0Um9vdENlcnRpZmljYXRlKCJSU0EiKTsKKyAgICAgICAgICAgIENBMiA9IFRlc3RLZXlTdG9yZS5nZXRDbGllbnRDQTIoKS5nZXRSb290Q2VydGlmaWNhdGUoIlJTQSIpOworICAgICAgICAgICAgUFJJVkFURSA9IFRlc3RLZXlTdG9yZS5nZXRTZXJ2ZXIoKS5nZXRQcml2YXRlS2V5KCJSU0EiLCAiUlNBIik7CisgICAgICAgICAgICBDSEFJTiA9IChYNTA5Q2VydGlmaWNhdGVbXSkgUFJJVkFURS5nZXRDZXJ0aWZpY2F0ZUNoYWluKCk7CisgICAgICAgICAgICBDQTNfV0lUSF9DQTFfU1VCSkVDVCA9IG5ldyBUZXN0S2V5U3RvcmUuQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5hbGlhc1ByZWZpeCgidW51c2VkIikKKyAgICAgICAgICAgICAgICAgICAgLnN1YmplY3QoQ0ExLmdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCkpCisgICAgICAgICAgICAgICAgICAgIC5jYSh0cnVlKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKS5nZXRSb290Q2VydGlmaWNhdGUoIlJTQSIpOworCisKKyAgICAgICAgICAgIEFMSUFTX1NZU1RFTV9DQTEgPSBhbGlhcyhmYWxzZSwgQ0ExLCAwKTsKKyAgICAgICAgICAgIEFMSUFTX1NZU1RFTV9DQTIgPSBhbGlhcyhmYWxzZSwgQ0EyLCAwKTsKKyAgICAgICAgICAgIEFMSUFTX1VTRVJfQ0ExID0gYWxpYXModHJ1ZSwgQ0ExLCAwKTsKKyAgICAgICAgICAgIEFMSUFTX1VTRVJfQ0EyID0gYWxpYXModHJ1ZSwgQ0EyLCAwKTsKKworICAgICAgICAgICAgQUxJQVNfU1lTVEVNX0NIQUlOMCA9IGFsaWFzKGZhbHNlLCBnZXRDaGFpbigpWzBdLCAwKTsKKyAgICAgICAgICAgIEFMSUFTX1NZU1RFTV9DSEFJTjEgPSBhbGlhcyhmYWxzZSwgZ2V0Q2hhaW4oKVsxXSwgMCk7CisgICAgICAgICAgICBBTElBU19TWVNURU1fQ0hBSU4yID0gYWxpYXMoZmFsc2UsIGdldENoYWluKClbMl0sIDApOworICAgICAgICAgICAgQUxJQVNfVVNFUl9DSEFJTjAgPSBhbGlhcyh0cnVlLCBnZXRDaGFpbigpWzBdLCAwKTsKKyAgICAgICAgICAgIEFMSUFTX1VTRVJfQ0hBSU4xID0gYWxpYXModHJ1ZSwgZ2V0Q2hhaW4oKVsxXSwgMCk7CisgICAgICAgICAgICBBTElBU19VU0VSX0NIQUlOMiA9IGFsaWFzKHRydWUsIGdldENoYWluKClbMl0sIDApOworCisgICAgICAgICAgICBBTElBU19TWVNURU1fQ0EzID0gYWxpYXMoZmFsc2UsIENBM19XSVRIX0NBMV9TVUJKRUNULCAwKTsKKyAgICAgICAgICAgIEFMSUFTX1NZU1RFTV9DQTNfQ09MTElTSU9OID0gYWxpYXMoZmFsc2UsIENBM19XSVRIX0NBMV9TVUJKRUNULCAxKTsKKyAgICAgICAgICAgIEFMSUFTX1VTRVJfQ0EzID0gYWxpYXModHJ1ZSwgQ0EzX1dJVEhfQ0ExX1NVQkpFQ1QsIDApOworICAgICAgICAgICAgQUxJQVNfVVNFUl9DQTNfQ09MTElTSU9OID0gYWxpYXModHJ1ZSwgQ0EzX1dJVEhfQ0ExX1NVQkpFQ1QsIDEpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIFRydXN0ZWRDZXJ0aWZpY2F0ZVN0b3JlIHN0b3JlOworCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICBzZXR1cFN0b3JlKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNldHVwU3RvcmUoKSB7CisgICAgICAgIERJUl9TWVNURU0ubWtkaXJzKCk7CisgICAgICAgIGNyZWF0ZVN0b3JlKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZVN0b3JlKCkgeworICAgICAgICBzdG9yZSA9IG5ldyBUcnVzdGVkQ2VydGlmaWNhdGVTdG9yZShESVJfU1lTVEVNLCBESVJfQURERUQsIERJUl9ERUxFVEVEKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIGNsZWFuU3RvcmUoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2xlYW5TdG9yZSgpIHsKKyAgICAgICAgZm9yIChGaWxlIGRpciA6IG5ldyBGaWxlW10geyBESVJfU1lTVEVNLCBESVJfQURERUQsIERJUl9ERUxFVEVELCBESVJfVEVTVCB9KSB7CisgICAgICAgICAgICBGaWxlW10gZmlsZXMgPSBkaXIubGlzdEZpbGVzKCk7CisgICAgICAgICAgICBpZiAoZmlsZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChGaWxlIGZpbGUgOiBmaWxlcykgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoZmlsZS5kZWxldGUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgc3RvcmUgPSBudWxsOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZXNldFN0b3JlKCkgeworICAgICAgICBjbGVhblN0b3JlKCk7CisgICAgICAgIHNldHVwU3RvcmUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW1wdHlEaXJlY3RvcmllcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFbXB0eSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RPbmVTeXN0ZW1PbmVEZWxldGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGluc3RhbGwoZ2V0Q2ExKCksIGdldEFsaWFzU3lzdGVtQ2ExKCkpOworICAgICAgICBzdG9yZS5kZWxldGVDZXJ0aWZpY2F0ZUVudHJ5KGdldEFsaWFzU3lzdGVtQ2ExKCkpOworICAgICAgICBhc3NlcnRFbXB0eSgpOworICAgICAgICBhc3NlcnREZWxldGVkKGdldENhMSgpLCBnZXRBbGlhc1N5c3RlbUNhMSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VHdvU3lzdGVtVHdvRGVsZXRlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpbnN0YWxsKGdldENhMSgpLCBnZXRBbGlhc1N5c3RlbUNhMSgpKTsKKyAgICAgICAgc3RvcmUuZGVsZXRlQ2VydGlmaWNhdGVFbnRyeShnZXRBbGlhc1N5c3RlbUNhMSgpKTsKKyAgICAgICAgaW5zdGFsbChnZXRDYTIoKSwgZ2V0QWxpYXNTeXN0ZW1DYTIoKSk7CisgICAgICAgIHN0b3JlLmRlbGV0ZUNlcnRpZmljYXRlRW50cnkoZ2V0QWxpYXNTeXN0ZW1DYTIoKSk7CisgICAgICAgIGFzc2VydEVtcHR5KCk7CisgICAgICAgIGFzc2VydERlbGV0ZWQoZ2V0Q2ExKCksIGdldEFsaWFzU3lzdGVtQ2ExKCkpOworICAgICAgICBhc3NlcnREZWxldGVkKGdldENhMigpLCBnZXRBbGlhc1N5c3RlbUNhMigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFydGlhbEZpbGVJc0lnbm9yZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZSBmaWxlID0gZmlsZShnZXRBbGlhc1N5c3RlbUNhMSgpKTsKKyAgICAgICAgT3V0cHV0U3RyZWFtIG9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZSk7CisgICAgICAgIG9zLndyaXRlKDApOworICAgICAgICBvcy5jbG9zZSgpOworICAgICAgICBhc3NlcnRUcnVlKGZpbGUuZXhpc3RzKCkpOworICAgICAgICBhc3NlcnRFbXB0eSgpOworICAgICAgICBhc3NlcnRUcnVlKGZpbGUuZXhpc3RzKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRFbXB0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RvcmUuZ2V0Q2VydGlmaWNhdGUobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0TnVsbChzdG9yZS5nZXRDZXJ0aWZpY2F0ZSgiIikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdG9yZS5nZXRDcmVhdGlvbkRhdGUobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0TnVsbChzdG9yZS5nZXRDcmVhdGlvbkRhdGUoIiIpKTsKKworICAgICAgICBTZXQ8U3RyaW5nPiBzID0gc3RvcmUuYWxpYXNlcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKHMpOworICAgICAgICBhc3NlcnRUcnVlKHMuaXNFbXB0eSgpKTsKKyAgICAgICAgYXNzZXJ0QWxpYXNlcygpOworCisgICAgICAgIFNldDxTdHJpbmc+IHUgPSBzdG9yZS51c2VyQWxpYXNlcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKHUpOworICAgICAgICBhc3NlcnRUcnVlKHUuaXNFbXB0eSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RvcmUuY29udGFpbnNBbGlhcyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZShzdG9yZS5jb250YWluc0FsaWFzKCIiKSk7CisKKyAgICAgICAgYXNzZXJ0TnVsbChzdG9yZS5nZXRDZXJ0aWZpY2F0ZUFsaWFzKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChzdG9yZS5nZXRDZXJ0aWZpY2F0ZUFsaWFzKGdldENhMSgpKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0b3JlLmlzVHJ1c3RBbmNob3IobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2Uoc3RvcmUuaXNUcnVzdEFuY2hvcihnZXRDYTEoKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdG9yZS5maW5kSXNzdWVyKG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydE51bGwoc3RvcmUuZmluZElzc3VlcihnZXRDYTEoKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdG9yZS5pbnN0YWxsQ2VydGlmaWNhdGUobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBzdG9yZS5kZWxldGVDZXJ0aWZpY2F0ZUVudHJ5KG51bGwpOworICAgICAgICBzdG9yZS5kZWxldGVDZXJ0aWZpY2F0ZUVudHJ5KCIiKTsKKworICAgICAgICBTdHJpbmdbXSB1c2VyRmlsZXMgPSBESVJfQURERUQubGlzdCgpOworICAgICAgICBhc3NlcnRUcnVlKHVzZXJGaWxlcyA9PSBudWxsIHx8IHVzZXJGaWxlcy5sZW5ndGggPT0gMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFR3b1N5c3RlbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0VHdvKGdldENhMSgpLCBnZXRBbGlhc1N5c3RlbUNhMSgpLAorICAgICAgICAgICAgICAgIGdldENhMigpLCBnZXRBbGlhc1N5c3RlbUNhMigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VHdvVXNlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0VHdvKGdldENhMSgpLCBnZXRBbGlhc1VzZXJDYTEoKSwKKyAgICAgICAgICAgICAgICBnZXRDYTIoKSwgZ2V0QWxpYXNVc2VyQ2EyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RPbmVTeXN0ZW1PbmVVc2VyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RUd28oZ2V0Q2ExKCksIGdldEFsaWFzU3lzdGVtQ2ExKCksCisgICAgICAgICAgICAgICAgZ2V0Q2EyKCksIGdldEFsaWFzVXNlckNhMigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VHdvU3lzdGVtU2FtZVN1YmplY3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFR3byhnZXRDYTEoKSwgZ2V0QWxpYXNTeXN0ZW1DYTEoKSwKKyAgICAgICAgICAgICAgICBnZXRDYTNXaXRoQ2ExU3ViamVjdCgpLCBnZXRBbGlhc1N5c3RlbUNhM0NvbGxpc2lvbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VHdvVXNlclNhbWVTdWJqZWN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RUd28oZ2V0Q2ExKCksIGdldEFsaWFzVXNlckNhMSgpLAorICAgICAgICAgICAgICAgIGdldENhM1dpdGhDYTFTdWJqZWN0KCksIGdldEFsaWFzVXNlckNhM0NvbGxpc2lvbigpKTsKKworICAgICAgICBzdG9yZS5kZWxldGVDZXJ0aWZpY2F0ZUVudHJ5KGdldEFsaWFzVXNlckNhMSgpKTsKKyAgICAgICAgYXNzZXJ0RGVsZXRlZChnZXRDYTEoKSwgZ2V0QWxpYXNVc2VyQ2ExKCkpOworICAgICAgICBhc3NlcnRUb21ic3RvbmUoZ2V0QWxpYXNVc2VyQ2ExKCkpOworICAgICAgICBhc3NlcnRSb290Q2EoZ2V0Q2EzV2l0aENhMVN1YmplY3QoKSwgZ2V0QWxpYXNVc2VyQ2EzQ29sbGlzaW9uKCkpOworICAgICAgICBhc3NlcnRBbGlhc2VzKGdldEFsaWFzVXNlckNhM0NvbGxpc2lvbigpKTsKKworICAgICAgICBzdG9yZS5kZWxldGVDZXJ0aWZpY2F0ZUVudHJ5KGdldEFsaWFzVXNlckNhM0NvbGxpc2lvbigpKTsKKyAgICAgICAgYXNzZXJ0RGVsZXRlZChnZXRDYTNXaXRoQ2ExU3ViamVjdCgpLCBnZXRBbGlhc1VzZXJDYTNDb2xsaXNpb24oKSk7CisgICAgICAgIGFzc2VydE5vVG9tYnN0b25lKGdldEFsaWFzVXNlckNhM0NvbGxpc2lvbigpKTsKKyAgICAgICAgYXNzZXJ0Tm9Ub21ic3RvbmUoZ2V0QWxpYXNVc2VyQ2ExKCkpOworICAgICAgICBhc3NlcnRFbXB0eSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RPbmVTeXN0ZW1PbmVVc2VyU2FtZVN1YmplY3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFR3byhnZXRDYTEoKSwgZ2V0QWxpYXNTeXN0ZW1DYTEoKSwKKyAgICAgICAgICAgICAgICBnZXRDYTNXaXRoQ2ExU3ViamVjdCgpLCBnZXRBbGlhc1VzZXJDYTMoKSk7CisgICAgICAgIHRlc3RUd28oZ2V0Q2ExKCksIGdldEFsaWFzVXNlckNhMSgpLAorICAgICAgICAgICAgICAgIGdldENhM1dpdGhDYTFTdWJqZWN0KCksIGdldEFsaWFzU3lzdGVtQ2EzKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0VHdvKFg1MDlDZXJ0aWZpY2F0ZSB4MSwgU3RyaW5nIGFsaWFzMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGUgeDIsIFN0cmluZyBhbGlhczIpIHsKKyAgICAgICAgaW5zdGFsbCh4MSwgYWxpYXMxKTsKKyAgICAgICAgaW5zdGFsbCh4MiwgYWxpYXMyKTsKKyAgICAgICAgYXNzZXJ0Um9vdENhKHgxLCBhbGlhczEpOworICAgICAgICBhc3NlcnRSb290Q2EoeDIsIGFsaWFzMik7CisgICAgICAgIGFzc2VydEFsaWFzZXMoYWxpYXMxLCBhbGlhczIpOworICAgIH0KKworCisgICAgcHVibGljIHZvaWQgdGVzdE9uZVN5c3RlbU9uZVVzZXJPbmVEZWxldGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGluc3RhbGwoZ2V0Q2ExKCksIGdldEFsaWFzU3lzdGVtQ2ExKCkpOworICAgICAgICBzdG9yZS5pbnN0YWxsQ2VydGlmaWNhdGUoZ2V0Q2EyKCkpOworICAgICAgICBzdG9yZS5kZWxldGVDZXJ0aWZpY2F0ZUVudHJ5KGdldEFsaWFzU3lzdGVtQ2ExKCkpOworICAgICAgICBhc3NlcnREZWxldGVkKGdldENhMSgpLCBnZXRBbGlhc1N5c3RlbUNhMSgpKTsKKyAgICAgICAgYXNzZXJ0Um9vdENhKGdldENhMigpLCBnZXRBbGlhc1VzZXJDYTIoKSk7CisgICAgICAgIGFzc2VydEFsaWFzZXMoZ2V0QWxpYXNVc2VyQ2EyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RPbmVTeXN0ZW1PbmVVc2VyT25lRGVsZXRlZFNhbWVTdWJqZWN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGluc3RhbGwoZ2V0Q2ExKCksIGdldEFsaWFzU3lzdGVtQ2ExKCkpOworICAgICAgICBzdG9yZS5pbnN0YWxsQ2VydGlmaWNhdGUoZ2V0Q2EzV2l0aENhMVN1YmplY3QoKSk7CisgICAgICAgIHN0b3JlLmRlbGV0ZUNlcnRpZmljYXRlRW50cnkoZ2V0QWxpYXNTeXN0ZW1DYTEoKSk7CisgICAgICAgIGFzc2VydERlbGV0ZWQoZ2V0Q2ExKCksIGdldEFsaWFzU3lzdGVtQ2ExKCkpOworICAgICAgICBhc3NlcnRSb290Q2EoZ2V0Q2EzV2l0aENhMVN1YmplY3QoKSwgZ2V0QWxpYXNVc2VyQ2EzKCkpOworICAgICAgICBhc3NlcnRBbGlhc2VzKGdldEFsaWFzVXNlckNhMygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXNlck1hc2tpbmdTeXN0ZW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaW5zdGFsbChnZXRDYTEoKSwgZ2V0QWxpYXNTeXN0ZW1DYTEoKSk7CisgICAgICAgIGluc3RhbGwoZ2V0Q2ExKCksIGdldEFsaWFzVXNlckNhMSgpKTsKKyAgICAgICAgYXNzZXJ0TWFza2VkKGdldENhMSgpLCBnZXRBbGlhc1N5c3RlbUNhMSgpKTsKKyAgICAgICAgYXNzZXJ0Um9vdENhKGdldENhMSgpLCBnZXRBbGlhc1VzZXJDYTEoKSk7CisgICAgICAgIGFzc2VydEFsaWFzZXMoZ2V0QWxpYXNTeXN0ZW1DYTEoKSwgZ2V0QWxpYXNVc2VyQ2ExKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDaGFpbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0Q2hhaW4oZ2V0QWxpYXNTeXN0ZW1DaGFpbjEoKSwgZ2V0QWxpYXNTeXN0ZW1DaGFpbjIoKSk7CisgICAgICAgIHRlc3RDaGFpbihnZXRBbGlhc1N5c3RlbUNoYWluMSgpLCBnZXRBbGlhc1VzZXJDaGFpbjIoKSk7CisgICAgICAgIHRlc3RDaGFpbihnZXRBbGlhc1VzZXJDaGFpbjEoKSwgZ2V0QWxpYXNTeXN0ZW1DYTEoKSk7CisgICAgICAgIHRlc3RDaGFpbihnZXRBbGlhc1VzZXJDaGFpbjEoKSwgZ2V0QWxpYXNVc2VyQ2hhaW4yKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0Q2hhaW4oU3RyaW5nIGFsaWFzMSwgU3RyaW5nIGFsaWFzMikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGluc3RhbGwoZ2V0Q2hhaW4oKVsxXSwgYWxpYXMxKTsKKyAgICAgICAgaW5zdGFsbChnZXRDaGFpbigpWzJdLCBhbGlhczIpOworICAgICAgICBhc3NlcnRJbnRlcm1lZGlhdGVDYShnZXRDaGFpbigpWzFdLCBhbGlhczEpOworICAgICAgICBhc3NlcnRSb290Q2EoZ2V0Q2hhaW4oKVsyXSwgYWxpYXMyKTsKKyAgICAgICAgYXNzZXJ0QWxpYXNlcyhhbGlhczEsIGFsaWFzMik7CisgICAgICAgIGFzc2VydEVxdWFscyhnZXRDaGFpbigpWzJdLCBzdG9yZS5maW5kSXNzdWVyKGdldENoYWluKClbMV0pKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGdldENoYWluKClbMV0sIHN0b3JlLmZpbmRJc3N1ZXIoZ2V0Q2hhaW4oKVswXSkpOworICAgICAgICByZXNldFN0b3JlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1pc3NpbmdTeXN0ZW1EaXJlY3RvcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2xlYW5TdG9yZSgpOworICAgICAgICBjcmVhdGVTdG9yZSgpOworICAgICAgICBhc3NlcnRFbXB0eSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RXaXRoRXhpc3RpbmdVc2VyRGlyZWN0b3JpZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRElSX0FEREVELm1rZGlycygpOworICAgICAgICBESVJfREVMRVRFRC5ta2RpcnMoKTsKKyAgICAgICAgaW5zdGFsbChnZXRDYTEoKSwgZ2V0QWxpYXNTeXN0ZW1DYTEoKSk7CisgICAgICAgIGFzc2VydFJvb3RDYShnZXRDYTEoKSwgZ2V0QWxpYXNTeXN0ZW1DYTEoKSk7CisgICAgICAgIGFzc2VydEFsaWFzZXMoZ2V0QWxpYXNTeXN0ZW1DYTEoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdElzVHJ1c3RBbmNob3JXaXRoUmVpc3N1ZWRnZXRDYSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQdWJsaWNLZXkgcHVibGljS2V5ID0gZ2V0UHJpdmF0ZSgpLmdldENlcnRpZmljYXRlKCkuZ2V0UHVibGljS2V5KCk7CisgICAgICAgIFByaXZhdGVLZXkgcHJpdmF0ZUtleSA9IGdldFByaXZhdGUoKS5nZXRQcml2YXRlS2V5KCk7CisgICAgICAgIFN0cmluZyBuYW1lID0gIkNOPUNBNCI7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjYTEgPSBUZXN0S2V5U3RvcmUuY3JlYXRlQ2EocHVibGljS2V5LCBwcml2YXRlS2V5LCBuYW1lKTsKKyAgICAgICAgVGhyZWFkLnNsZWVwKDEgKiAxMDAwKTsgLy8gd2FpdCB0byBlbnN1cmUgQ0FzIHZhcnkgYnkgZXhwaXJhdGlvbgorICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2EyID0gVGVzdEtleVN0b3JlLmNyZWF0ZUNhKHB1YmxpY0tleSwgcHJpdmF0ZUtleSwgbmFtZSk7CisgICAgICAgIGFzc2VydEZhbHNlKGNhMS5lcXVhbHMoY2EyKSk7CisKKyAgICAgICAgU3RyaW5nIHN5c3RlbUFsaWFzID0gYWxpYXMoZmFsc2UsIGNhMSwgMCk7CisgICAgICAgIGluc3RhbGwoY2ExLCBzeXN0ZW1BbGlhcyk7CisgICAgICAgIGFzc2VydFJvb3RDYShjYTEsIHN5c3RlbUFsaWFzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzdG9yZS5pc1RydXN0QW5jaG9yKGNhMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoY2ExLCBzdG9yZS5maW5kSXNzdWVyKGNhMikpOworICAgICAgICByZXNldFN0b3JlKCk7CisKKyAgICAgICAgU3RyaW5nIHVzZXJBbGlhcyA9IGFsaWFzKHRydWUsIGNhMSwgMCk7CisgICAgICAgIHN0b3JlLmluc3RhbGxDZXJ0aWZpY2F0ZShjYTEpOworICAgICAgICBhc3NlcnRSb290Q2EoY2ExLCB1c2VyQWxpYXMpOworICAgICAgICBhc3NlcnRUcnVlKHN0b3JlLmlzVHJ1c3RBbmNob3IoY2EyKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjYTEsIHN0b3JlLmZpbmRJc3N1ZXIoY2EyKSk7CisgICAgICAgIHJlc2V0U3RvcmUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5zdGFsbEVtcHR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN0b3JlLmluc3RhbGxDZXJ0aWZpY2F0ZShnZXRDYTEoKSk7CisgICAgICAgIGFzc2VydFJvb3RDYShnZXRDYTEoKSwgZ2V0QWxpYXNVc2VyQ2ExKCkpOworICAgICAgICBhc3NlcnRBbGlhc2VzKGdldEFsaWFzVXNlckNhMSgpKTsKKworICAgICAgICAvLyByZWluc3RhbGxpbmcgc2hvdWxkIG5vdCBjaGFuZ2UgYW55dGhpbmcKKyAgICAgICAgc3RvcmUuaW5zdGFsbENlcnRpZmljYXRlKGdldENhMSgpKTsKKyAgICAgICAgYXNzZXJ0Um9vdENhKGdldENhMSgpLCBnZXRBbGlhc1VzZXJDYTEoKSk7CisgICAgICAgIGFzc2VydEFsaWFzZXMoZ2V0QWxpYXNVc2VyQ2ExKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnN0YWxsRW1wdHlTeXN0ZW1FeGlzdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaW5zdGFsbChnZXRDYTEoKSwgZ2V0QWxpYXNTeXN0ZW1DYTEoKSk7CisgICAgICAgIGFzc2VydFJvb3RDYShnZXRDYTEoKSwgZ2V0QWxpYXNTeXN0ZW1DYTEoKSk7CisgICAgICAgIGFzc2VydEFsaWFzZXMoZ2V0QWxpYXNTeXN0ZW1DYTEoKSk7CisKKyAgICAgICAgLy8gcmVpbnN0YWxsaW5nIHNob3VsZCBub3QgYWZmZWN0IHN5c3RlbSBDQQorICAgICAgICBzdG9yZS5pbnN0YWxsQ2VydGlmaWNhdGUoZ2V0Q2ExKCkpOworICAgICAgICBhc3NlcnRSb290Q2EoZ2V0Q2ExKCksIGdldEFsaWFzU3lzdGVtQ2ExKCkpOworICAgICAgICBhc3NlcnRBbGlhc2VzKGdldEFsaWFzU3lzdGVtQ2ExKCkpOworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEluc3RhbGxFbXB0eURlbGV0ZWRTeXN0ZW1FeGlzdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaW5zdGFsbChnZXRDYTEoKSwgZ2V0QWxpYXNTeXN0ZW1DYTEoKSk7CisgICAgICAgIHN0b3JlLmRlbGV0ZUNlcnRpZmljYXRlRW50cnkoZ2V0QWxpYXNTeXN0ZW1DYTEoKSk7CisgICAgICAgIGFzc2VydEVtcHR5KCk7CisgICAgICAgIGFzc2VydERlbGV0ZWQoZ2V0Q2ExKCksIGdldEFsaWFzU3lzdGVtQ2ExKCkpOworCisgICAgICAgIC8vIGluc3RhbGxpbmcgc2hvdWxkIHJlc3RvcmUgZGVsZXRlZCBzeXN0ZW0gQ0EKKyAgICAgICAgc3RvcmUuaW5zdGFsbENlcnRpZmljYXRlKGdldENhMSgpKTsKKyAgICAgICAgYXNzZXJ0Um9vdENhKGdldENhMSgpLCBnZXRBbGlhc1N5c3RlbUNhMSgpKTsKKyAgICAgICAgYXNzZXJ0QWxpYXNlcyhnZXRBbGlhc1N5c3RlbUNhMSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVsZXRlRW1wdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3RvcmUuZGVsZXRlQ2VydGlmaWNhdGVFbnRyeShnZXRBbGlhc1N5c3RlbUNhMSgpKTsKKyAgICAgICAgYXNzZXJ0RW1wdHkoKTsKKyAgICAgICAgYXNzZXJ0RGVsZXRlZChnZXRDYTEoKSwgZ2V0QWxpYXNTeXN0ZW1DYTEoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERlbGV0ZVVzZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3RvcmUuaW5zdGFsbENlcnRpZmljYXRlKGdldENhMSgpKTsKKyAgICAgICAgYXNzZXJ0Um9vdENhKGdldENhMSgpLCBnZXRBbGlhc1VzZXJDYTEoKSk7CisgICAgICAgIGFzc2VydEFsaWFzZXMoZ2V0QWxpYXNVc2VyQ2ExKCkpOworCisgICAgICAgIHN0b3JlLmRlbGV0ZUNlcnRpZmljYXRlRW50cnkoZ2V0QWxpYXNVc2VyQ2ExKCkpOworICAgICAgICBhc3NlcnRFbXB0eSgpOworICAgICAgICBhc3NlcnREZWxldGVkKGdldENhMSgpLCBnZXRBbGlhc1VzZXJDYTEoKSk7CisgICAgICAgIGFzc2VydE5vVG9tYnN0b25lKGdldEFsaWFzVXNlckNhMSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVsZXRlU3lzdGVtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGluc3RhbGwoZ2V0Q2ExKCksIGdldEFsaWFzU3lzdGVtQ2ExKCkpOworICAgICAgICBhc3NlcnRSb290Q2EoZ2V0Q2ExKCksIGdldEFsaWFzU3lzdGVtQ2ExKCkpOworICAgICAgICBhc3NlcnRBbGlhc2VzKGdldEFsaWFzU3lzdGVtQ2ExKCkpOworCisgICAgICAgIHN0b3JlLmRlbGV0ZUNlcnRpZmljYXRlRW50cnkoZ2V0QWxpYXNTeXN0ZW1DYTEoKSk7CisgICAgICAgIGFzc2VydEVtcHR5KCk7CisgICAgICAgIGFzc2VydERlbGV0ZWQoZ2V0Q2ExKCksIGdldEFsaWFzU3lzdGVtQ2ExKCkpOworCisgICAgICAgIC8vIGRlbGV0aW5nIGFnYWluIHNob3VsZCBub3QgY2hhbmdlIGFueXRoaW5nCisgICAgICAgIHN0b3JlLmRlbGV0ZUNlcnRpZmljYXRlRW50cnkoZ2V0QWxpYXNTeXN0ZW1DYTEoKSk7CisgICAgICAgIGFzc2VydEVtcHR5KCk7CisgICAgICAgIGFzc2VydERlbGV0ZWQoZ2V0Q2ExKCksIGdldEFsaWFzU3lzdGVtQ2ExKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRSb290Q2EoWDUwOUNlcnRpZmljYXRlIHgsIFN0cmluZyBhbGlhcykgeworICAgICAgICBhc3NlcnRJbnRlcm1lZGlhdGVDYSh4LCBhbGlhcyk7CisgICAgICAgIGFzc2VydEVxdWFscyh4LCBzdG9yZS5maW5kSXNzdWVyKHgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0VHJ1c3RlZChYNTA5Q2VydGlmaWNhdGUgeCwgU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIGFzc2VydEVxdWFscyh4LCBzdG9yZS5nZXRDZXJ0aWZpY2F0ZShhbGlhcykpOworICAgICAgICBhc3NlcnRFcXVhbHMoZmlsZShhbGlhcykubGFzdE1vZGlmaWVkKCksIHN0b3JlLmdldENyZWF0aW9uRGF0ZShhbGlhcykuZ2V0VGltZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzdG9yZS5jb250YWluc0FsaWFzKGFsaWFzKSk7CisgICAgICAgIGFzc2VydFRydWUoc3RvcmUuaXNUcnVzdEFuY2hvcih4KSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydEludGVybWVkaWF0ZUNhKFg1MDlDZXJ0aWZpY2F0ZSB4LCBTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgYXNzZXJ0VHJ1c3RlZCh4LCBhbGlhcyk7CisgICAgICAgIGFzc2VydEVxdWFscyhhbGlhcywgc3RvcmUuZ2V0Q2VydGlmaWNhdGVBbGlhcyh4KSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydE1hc2tlZChYNTA5Q2VydGlmaWNhdGUgeCwgU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIGFzc2VydFRydXN0ZWQoeCwgYWxpYXMpOworICAgICAgICBhc3NlcnRGYWxzZShhbGlhcy5lcXVhbHMoc3RvcmUuZ2V0Q2VydGlmaWNhdGVBbGlhcyh4KSkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnREZWxldGVkKFg1MDlDZXJ0aWZpY2F0ZSB4LCBTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgYXNzZXJ0TnVsbChzdG9yZS5nZXRDZXJ0aWZpY2F0ZShhbGlhcykpOworICAgICAgICBhc3NlcnRGYWxzZShzdG9yZS5jb250YWluc0FsaWFzKGFsaWFzKSk7CisgICAgICAgIGFzc2VydE51bGwoc3RvcmUuZ2V0Q2VydGlmaWNhdGVBbGlhcyh4KSk7CisgICAgICAgIGFzc2VydEZhbHNlKHN0b3JlLmlzVHJ1c3RBbmNob3IoeCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoc3RvcmUuYWxsU3lzdGVtQWxpYXNlcygpLmNvbnRhaW5zKGFsaWFzKSwKKyAgICAgICAgICAgICAgICAgICAgIHN0b3JlLmdldENlcnRpZmljYXRlKGFsaWFzLCB0cnVlKSAhPSBudWxsKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0VG9tYnN0b25lKFN0cmluZyBhbGlhcykgeworICAgICAgICBhc3NlcnRUcnVlKFRydXN0ZWRDZXJ0aWZpY2F0ZVN0b3JlLmlzVXNlcihhbGlhcykpOworICAgICAgICBGaWxlIGZpbGUgPSBmaWxlKGFsaWFzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShmaWxlLmV4aXN0cygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGZpbGUubGVuZ3RoKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnROb1RvbWJzdG9uZShTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShUcnVzdGVkQ2VydGlmaWNhdGVTdG9yZS5pc1VzZXIoYWxpYXMpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZmlsZShhbGlhcykuZXhpc3RzKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRBbGlhc2VzKFN0cmluZy4uLiBhbGlhc2VzKSB7CisgICAgICAgIFNldDxTdHJpbmc+IGV4cGVjdGVkID0gbmV3IEhhc2hTZXQ8U3RyaW5nPihBcnJheXMuYXNMaXN0KGFsaWFzZXMpKTsKKyAgICAgICAgU2V0PFN0cmluZz4gYWN0dWFsID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgICBmb3IgKFN0cmluZyBhbGlhcyA6IHN0b3JlLmFsaWFzZXMoKSkgeworICAgICAgICAgICAgYm9vbGVhbiBzeXN0ZW0gPSBUcnVzdGVkQ2VydGlmaWNhdGVTdG9yZS5pc1N5c3RlbShhbGlhcyk7CisgICAgICAgICAgICBib29sZWFuIHVzZXIgPSBUcnVzdGVkQ2VydGlmaWNhdGVTdG9yZS5pc1VzZXIoYWxpYXMpOworICAgICAgICAgICAgaWYgKHN5c3RlbSB8fCB1c2VyKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHN5c3RlbSwgc3RvcmUuYWxsU3lzdGVtQWxpYXNlcygpLmNvbnRhaW5zKGFsaWFzKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHVzZXIsIHN0b3JlLnVzZXJBbGlhc2VzKCkuY29udGFpbnMoYWxpYXMpKTsKKyAgICAgICAgICAgICAgICBhY3R1YWwuYWRkKGFsaWFzKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGFsaWFzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIGFjdHVhbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZm9ybWF0IGEgY2VydGlmaWNhdGUgYWxpYXMKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgYWxpYXMoYm9vbGVhbiB1c2VyLCBYNTA5Q2VydGlmaWNhdGUgeCwgaW50IGluZGV4KSB7CisgICAgICAgIFN0cmluZyBwcmVmaXggPSB1c2VyID8gInVzZXI6IiA6ICJzeXN0ZW06IjsKKworICAgICAgICBYNTAwUHJpbmNpcGFsIHN1YmplY3QgPSB4LmdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCk7CisgICAgICAgIGludCBpbnRIYXNoID0gTmF0aXZlQ3J5cHRvLlg1MDlfTkFNRV9oYXNoX29sZChzdWJqZWN0KTsKKyAgICAgICAgU3RyaW5nIHN0ckhhc2ggPSBJbnRlZ3JhbFRvU3RyaW5nLmludFRvSGV4U3RyaW5nKGludEhhc2gsIGZhbHNlLCA4KTsKKworICAgICAgICByZXR1cm4gcHJlZml4ICsgc3RySGFzaCArICcuJyArIGluZGV4OworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc3RhbGwgY2VydGlmaWNhdGUgdW5kZXIgc3BlY2lmaWVkIGFsaWFzCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBpbnN0YWxsKFg1MDlDZXJ0aWZpY2F0ZSB4LCBTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEZpbGUgZmlsZSA9IGZpbGUoYWxpYXMpOworICAgICAgICAgICAgZmlsZS5nZXRQYXJlbnRGaWxlKCkubWtkaXJzKCk7CisgICAgICAgICAgICBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZSk7CisgICAgICAgICAgICBvdXQud3JpdGUoeC5nZXRFbmNvZGVkKCkpOworICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGUgZmlsZSBmb3IgYW4gYWxpYXMKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBGaWxlIGZpbGUoU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIEZpbGUgZGlyOworICAgICAgICBpZiAoVHJ1c3RlZENlcnRpZmljYXRlU3RvcmUuaXNTeXN0ZW0oYWxpYXMpKSB7CisgICAgICAgICAgICBkaXIgPSBESVJfU1lTVEVNOworICAgICAgICB9IGVsc2UgaWYgKFRydXN0ZWRDZXJ0aWZpY2F0ZVN0b3JlLmlzVXNlcihhbGlhcykpIHsKKyAgICAgICAgICAgIGRpciA9IERJUl9BRERFRDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oYWxpYXMpOworICAgICAgICB9CisKKyAgICAgICAgaW50IGluZGV4ID0gYWxpYXMubGFzdEluZGV4T2YoIjoiKTsKKyAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGFsaWFzKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgZmlsZW5hbWUgPSBhbGlhcy5zdWJzdHJpbmcoaW5kZXgrMSk7CisKKyAgICAgICAgcmV0dXJuIG5ldyBGaWxlKGRpciwgZmlsZW5hbWUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vQmFkUGFkZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLjAuc2VyIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc2VyaWFsaXphdGlvbi9CYWRQYWRkaW5nRXhjZXB0aW9uVGVzdC5nb2xkZW4uMC5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTdkNjMzMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vQmFkUGFkZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLjAuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vQmFkUGFkZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLjEuc2VyIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc2VyaWFsaXphdGlvbi9CYWRQYWRkaW5nRXhjZXB0aW9uVGVzdC5nb2xkZW4uMS5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDQ3YzFmNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vQmFkUGFkZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLjEuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vQmFkUGFkZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLjIuc2VyIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc2VyaWFsaXphdGlvbi9CYWRQYWRkaW5nRXhjZXB0aW9uVGVzdC5nb2xkZW4uMi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWUwMjhiZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vQmFkUGFkZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLjIuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uVGVzdC5nb2xkZW4uMC5zZXIgYi9sdW5pL3NyYy90ZXN0L2phdmEvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zZXJpYWxpemF0aW9uL0V4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvblRlc3QuZ29sZGVuLjAuc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYwYzY3YzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zZXJpYWxpemF0aW9uL0V4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvblRlc3QuZ29sZGVuLjAuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uVGVzdC5nb2xkZW4uMS5zZXIgYi9sdW5pL3NyYy90ZXN0L2phdmEvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zZXJpYWxpemF0aW9uL0V4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvblRlc3QuZ29sZGVuLjEuc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU4YjMwM2YKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zZXJpYWxpemF0aW9uL0V4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvblRlc3QuZ29sZGVuLjEuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vRXhlbXB0aW9uTWVjaGFuaXNtRXhjZXB0aW9uVGVzdC5nb2xkZW4uMi5zZXIgYi9sdW5pL3NyYy90ZXN0L2phdmEvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zZXJpYWxpemF0aW9uL0V4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvblRlc3QuZ29sZGVuLjIuc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVlNDFhZDYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvY3J5cHRvL3Rlc3RzL2phdmF4L2NyeXB0by9zZXJpYWxpemF0aW9uL0V4ZW1wdGlvbk1lY2hhbmlzbUV4Y2VwdGlvblRlc3QuZ29sZGVuLjIuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvblRlc3QuZ29sZGVuLjAuc2VyIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc2VyaWFsaXphdGlvbi9JbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uVGVzdC5nb2xkZW4uMC5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTg4MjNmYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvblRlc3QuZ29sZGVuLjAuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvblRlc3QuZ29sZGVuLjEuc2VyIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc2VyaWFsaXphdGlvbi9JbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uVGVzdC5nb2xkZW4uMS5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTY5YWU1NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvblRlc3QuZ29sZGVuLjEuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvblRlc3QuZ29sZGVuLjIuc2VyIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc2VyaWFsaXphdGlvbi9JbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uVGVzdC5nb2xkZW4uMi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjIzODI2YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvblRlc3QuZ29sZGVuLjIuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vTm9TdWNoUGFkZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLjAuc2VyIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc2VyaWFsaXphdGlvbi9Ob1N1Y2hQYWRkaW5nRXhjZXB0aW9uVGVzdC5nb2xkZW4uMC5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGNkYzA5ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vTm9TdWNoUGFkZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLjAuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vTm9TdWNoUGFkZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLjEuc2VyIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc2VyaWFsaXphdGlvbi9Ob1N1Y2hQYWRkaW5nRXhjZXB0aW9uVGVzdC5nb2xkZW4uMS5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2ExMjE4NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vTm9TdWNoUGFkZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLjEuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vTm9TdWNoUGFkZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLjIuc2VyIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc2VyaWFsaXphdGlvbi9Ob1N1Y2hQYWRkaW5nRXhjZXB0aW9uVGVzdC5nb2xkZW4uMi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTgxOGNkNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vTm9TdWNoUGFkZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLjIuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vU2hvcnRCdWZmZXJFeGNlcHRpb25UZXN0LmdvbGRlbi4wLnNlciBiL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vU2hvcnRCdWZmZXJFeGNlcHRpb25UZXN0LmdvbGRlbi4wLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZjhlNTVmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc2VyaWFsaXphdGlvbi9TaG9ydEJ1ZmZlckV4Y2VwdGlvblRlc3QuZ29sZGVuLjAuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vU2hvcnRCdWZmZXJFeGNlcHRpb25UZXN0LmdvbGRlbi4xLnNlciBiL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vU2hvcnRCdWZmZXJFeGNlcHRpb25UZXN0LmdvbGRlbi4xLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMGZhZGIyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc2VyaWFsaXphdGlvbi9TaG9ydEJ1ZmZlckV4Y2VwdGlvblRlc3QuZ29sZGVuLjEuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vU2hvcnRCdWZmZXJFeGNlcHRpb25UZXN0LmdvbGRlbi4yLnNlciBiL2x1bmkvc3JjL3Rlc3QvamF2YS9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9jcnlwdG8vdGVzdHMvamF2YXgvY3J5cHRvL3NlcmlhbGl6YXRpb24vU2hvcnRCdWZmZXJFeGNlcHRpb25UZXN0LmdvbGRlbi4yLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZWRmMjYwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2NyeXB0by90ZXN0cy9qYXZheC9jcnlwdG8vc2VyaWFsaXphdGlvbi9TaG9ydEJ1ZmZlckV4Y2VwdGlvblRlc3QuZ29sZGVuLjIuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS9zdW4vbWlzYy9VbnNhZmVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvc3VuL21pc2MvVW5zYWZlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2MmQzOWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvc3VuL21pc2MvVW5zYWZlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHN1bi5taXNjOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ2FsbGFibGU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JzOworCitwdWJsaWMgY2xhc3MgVW5zYWZlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0VW5zYWZlRm9yYmlkZGVuKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgVW5zYWZlLmdldFVuc2FmZSgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVncmVzc2lvbiBmb3IgMjA1MzIxNy4gV2UgdXNlZCB0byBsb29rIG9uZSBsZXZlbCBoaWdoZXIgdGhhbiBuZWNlc3NhcnkKKyAgICAgKiBvbiB0aGUgc3RhY2suCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRVbnNhZmVGb3JiaWRkZW5XaXRoU3lzdGVtQ2FsbGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENhbGxhYmxlPE9iamVjdD4gY2FsbGFibGUgPSBFeGVjdXRvcnMuY2FsbGFibGUobmV3IFJ1bm5hYmxlKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIFVuc2FmZS5nZXRVbnNhZmUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNhbGxhYmxlLmNhbGwoKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9pby9Db21wdXRlU2VyaWFsVmVyc2lvblVJRFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9pby9Db21wdXRlU2VyaWFsVmVyc2lvblVJRFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NThjMjdmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2lvL0NvbXB1dGVTZXJpYWxWZXJzaW9uVUlEVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTQ1IEBACitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLmlvOworCitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKKworcHVibGljIGNsYXNzIENvbXB1dGVTZXJpYWxWZXJzaW9uVUlEVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKworICAgIHByaXZhdGUgU3RyaW5nIHBhdGggPSAiL3NlcmlhbGl6YXRpb24vdGVzdHMvYXBpL2phdmEvaW8vIjsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb21wdXRlU1VJRENsYXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdElucHV0U3RyZWFtIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShnZXRDbGFzcygpCisgICAgICAgICAgICAgICAgLmdldFJlc291cmNlQXNTdHJlYW0ocGF0aCArICJ0ZXN0Q29tcHV0ZVNVSURDbGFzcy5zZXIiKSk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdENsYXNzTmFtZTEgbzEgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0Q2xhc3NOYW1lMSkgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0Q2xhc3NOYW1lMlRfVCRUIG8yID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdENsYXNzTmFtZTJUX1QkVCkgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0Q2xhc3NNb2RpZmllclB1YmxpYyBvNiA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RDbGFzc01vZGlmaWVyUHVibGljKSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RDbGFzc01vZGlmaWVyQWJzdHJhY3QgbzMgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0Q2xhc3NNb2RpZmllckFic3RyYWN0KSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RDbGFzc01vZGlmaWVyRmluYWwgbzQgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0Q2xhc3NNb2RpZmllckZpbmFsKSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RDbGFzc01vZGlmaWVySW50ZXJmYWNlIG81ID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdENsYXNzTW9kaWZpZXJJbnRlcmZhY2UpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIG9pcy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb21wdXRlU1VJREludGVyZmFjZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0gb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKGdldENsYXNzKCkKKyAgICAgICAgICAgICAgICAuZ2V0UmVzb3VyY2VBc1N0cmVhbShwYXRoICsgInRlc3RDb21wdXRlU1VJREludGVyZmFjZXMuc2VyIikpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RJbnRlZmFjZXMgbzEgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0SW50ZWZhY2VzKSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RJbnRlZmFjZXNBIG8yID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEludGVmYWNlc0EpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEludGVmYWNlc0FCIG8zID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEludGVmYWNlc0FCKSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RJbnRlZmFjZXNCQSBvNCA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RJbnRlZmFjZXNCQSkgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0SW50ZWZhY2VzQyBvNSA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RJbnRlZmFjZXNDKSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RJbnRlZmFjZXNBQyBvNiA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RJbnRlZmFjZXNBQykgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0SW50ZWZhY2VzQ0EgbzcgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0SW50ZWZhY2VzQ0EpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEludGVmYWNlc0FCQyBvOCA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RJbnRlZmFjZXNBQkMpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEludGVmYWNlc0FDQiBvOSA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RJbnRlZmFjZXNBQ0IpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEludGVmYWNlc0JBQyBvMTAgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0SW50ZWZhY2VzQkFDKSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RJbnRlZmFjZXNCQ0EgbzExID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEludGVmYWNlc0JDQSkgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0SW50ZWZhY2VzQ0FCIG8xMiA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RJbnRlZmFjZXNDQUIpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEludGVmYWNlc0NCQSBvMTMgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0SW50ZWZhY2VzQ0JBKSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29tcHV0ZVNVSURGaWVsZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0gb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKGdldENsYXNzKCkKKyAgICAgICAgICAgICAgICAuZ2V0UmVzb3VyY2VBc1N0cmVhbShwYXRoICsgInRlc3RDb21wdXRlU1VJREZpZWxkcy5zZXIiKSk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEZpZWxkc05vbmUgbzEgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0RmllbGRzTm9uZSkgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0RmllbGRzT25lRmluYWwgbzIgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0RmllbGRzT25lRmluYWwpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEZpZWxkc1R3b0ZpbmFsIG8zID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEZpZWxkc1R3b0ZpbmFsKSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RGaWVsZHNPbmVQcml2YXRlIG80ID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEZpZWxkc09uZVByaXZhdGUpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEZpZWxkc1R3b1ByaXZhdGUgbzUgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0RmllbGRzVHdvUHJpdmF0ZSkgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0RmllbGRzT25lUHJvdGVjdGVkIG82ID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEZpZWxkc09uZVByb3RlY3RlZCkgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0RmllbGRzVHdvUHJvdGVjdGVkIG83ID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEZpZWxkc1R3b1Byb3RlY3RlZCkgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0RmllbGRzT25lUHVibGljIG84ID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEZpZWxkc09uZVB1YmxpYykgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0RmllbGRzVHdvUHVibGljIG85ID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEZpZWxkc1R3b1B1YmxpYykgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0RmllbGRzT25lU3RhdGljIG8xMCA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RGaWVsZHNPbmVTdGF0aWMpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEZpZWxkc1R3b1N0YXRpYyBvMTEgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0RmllbGRzVHdvU3RhdGljKSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RGaWVsZHNPbmVUcmFuc2llbnQgbzEyID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEZpZWxkc09uZVRyYW5zaWVudCkgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0RmllbGRzVHdvVHJhbnNpZW50IG8xMyA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RGaWVsZHNUd29UcmFuc2llbnQpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEZpZWxkc09uZVZvbGF0aWxlIG8xNCA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RGaWVsZHNPbmVWb2xhdGlsZSkgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0RmllbGRzVHdvVm9sYXRpbGUgbzE1ID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEZpZWxkc1R3b1ZvbGF0aWxlKSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RGaWVsZFNpZ25hdHVyZXMgbzE2ID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdEZpZWxkU2lnbmF0dXJlcykgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgb2lzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENvbXB1dGVTVUlEQ29uc3RydWN0b3JzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE9iamVjdElucHV0U3RyZWFtIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShnZXRDbGFzcygpCisgICAgICAgICAgICAgICAgLmdldFJlc291cmNlQXNTdHJlYW0ocGF0aCArICJ0ZXN0Q29tcHV0ZVNVSURDb25zdHJ1Y3RvcnMuc2VyIikpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RDb25zdHJ1Y3Rvck5vbmUgbzEgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0Q29uc3RydWN0b3JOb25lKSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RDb25zdHJ1Y3Rvck9uZSBvMiA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RDb25zdHJ1Y3Rvck9uZSkgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0Q29uc3RydWN0b3JQcml2YXRlIG8zID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdENvbnN0cnVjdG9yUHJpdmF0ZSkgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0Q29uc3RydWN0b3JQcm90ZWN0ZWQgbzQgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0Q29uc3RydWN0b3JQcm90ZWN0ZWQpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdENvbnN0cnVjdG9yUHVibGljIG81ID0gKFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdENvbnN0cnVjdG9yUHVibGljKSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RDb25zdHJ1Y3RvclNpZ25hdHVyZSBvNiA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RDb25zdHJ1Y3RvclNpZ25hdHVyZSkgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0Q29uc3RydWN0b3JUd28gbzcgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0Q29uc3RydWN0b3JUd28pIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdENvbnN0cnVjdG9yVHdvUmV2ZXJzZSBvOCA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RDb25zdHJ1Y3RvclR3b1JldmVyc2UpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIG9pcy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb21wdXRlU1VJRE1ldGhvZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0gb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKGdldENsYXNzKCkKKyAgICAgICAgICAgICAgICAuZ2V0UmVzb3VyY2VBc1N0cmVhbShwYXRoICsgInRlc3RDb21wdXRlU1VJRE1ldGhvZHMuc2VyIikpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RNZWhvZFByaXZhdGUgbzEgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0TWVob2RQcml2YXRlKSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RNZXRob2RBYnN0cmFjdCBvMiA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RNZXRob2RBYnN0cmFjdCkgb2lzCisgICAgICAgICAgICAgICAgLnJlYWRPYmplY3QoKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0TWV0aG9kRmluYWwgbzMgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0TWV0aG9kRmluYWwpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdE1ldGhvZE5hdGl2ZSBvNCA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RNZXRob2ROYXRpdmUpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdE1ldGhvZFByb3RlY3RlZCBvNSA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RNZXRob2RQcm90ZWN0ZWQpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdE1ldGhvZFB1YmxpYyBvNiA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RNZXRob2RQdWJsaWMpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdE1ldGhvZFN0YXRpYyBvNyA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RNZXRob2RTdGF0aWMpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdE1ldGhvZFNpZ25hdHVyZSBvOSA9IChTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RNZXRob2RTaWduYXR1cmUpIG9pcworICAgICAgICAgICAgICAgIC5yZWFkT2JqZWN0KCk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0Q2xhc3MuVGVzdE1ldGhvZFJldHVyblNpZ25hdHVyZSBvMTAgPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0TWV0aG9kUmV0dXJuU2lnbmF0dXJlKSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdENsYXNzLlRlc3RNZXRob2RTeW5jaHJvbml6ZWQgbzggPSAoU2VyaWFsaXphdGlvblRlc3RDbGFzcy5UZXN0TWV0aG9kU3luY2hyb25pemVkKSBvaXMKKyAgICAgICAgICAgICAgICAucmVhZE9iamVjdCgpOworICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvaW8vT2JqZWN0SW5wdXRTdHJlYW1UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvaW8vT2JqZWN0SW5wdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDM0ZDMxYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9pby9PYmplY3RJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDY4NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5FT0ZFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1DbGFzczsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLmlvLlN0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkudGVzdGZyYW1ld29yay5zZXJpYWxpemF0aW9uLlNlcmlhbGl6YXRpb25UZXN0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS50ZXN0ZnJhbWV3b3JrLnNlcmlhbGl6YXRpb24uU2VyaWFsaXphdGlvblRlc3QuU2VyaWFsaXphYmxlQXNzZXJ0OworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW07CisKK3B1YmxpYyBjbGFzcyBPYmplY3RJbnB1dFN0cmVhbVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgaW1wbGVtZW50cworICAgICAgICBTZXJpYWxpemFibGUgeworCisgICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgT2JqZWN0SW5wdXRTdHJlYW0gb2lzOworCisgICAgT2JqZWN0T3V0cHV0U3RyZWFtIG9vczsKKworICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW87CisKKyAgICBib29sZWFuIHJlYWRTdHJlYW1IZWFkZXJDYWxsZWQ7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyB0ZXN0U3RyaW5nID0gIkxvcmVtIGlwc3VtLi4uIjsKKworICAgIHByaXZhdGUgZmluYWwgaW50IHRlc3RMZW5ndGggPSB0ZXN0U3RyaW5nLmxlbmd0aCgpOworCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2lvX0lucHV0U3RyZWFtX0lPRXhjZXB0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb29zLndyaXRlT2JqZWN0KHRlc3RTdHJpbmcpOworICAgICAgICBvb3MuY2xvc2UoKTsKKworICAgICAgICBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbSBzaXMgPSBuZXcgU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpOworICAgICAgICBzaXMudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKHNpcyk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICBzaXMudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NsYXNzRGVzY3JpcHRvcigpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworCisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW1XaXRoV3JpdGVEZXNjIG9vcyA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW1XaXRoV3JpdGVEZXNjKAorICAgICAgICAgICAgICAgIGJhb3MpOworICAgICAgICBvb3Mud3JpdGVPYmplY3QoU3RyaW5nLmNsYXNzKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisgICAgICAgIENsYXNzPD8+IGNscyA9IFRlc3RDbGFzc0ZvclNlcmlhbGl6YXRpb24uY2xhc3M7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJhaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvcy50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW1XaXRoUmVhZERlc2Mgb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtV2l0aFJlYWREZXNjKAorICAgICAgICAgICAgICAgIGJhaXMsIGNscyk7CisgICAgICAgIE9iamVjdCBvYmogPSBvaXMucmVhZE9iamVjdCgpOworICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNscywgb2JqKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2F2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbS5hdmFpbGFibGUoKQorICAgICAgICBvb3Mud3JpdGVCeXRlcyh0ZXN0U3RyaW5nKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisKKyAgICAgICAgU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW0gc2lzID0gbmV3IFN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtKGJhby50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKHNpcyk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgbnVtYmVyIG9mIGJ5dGVzOyIsIHRlc3RMZW5ndGgsIG9pcy5hdmFpbGFibGUoKSk7CisgICAgICAgIG9pcy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYXZhaWxhYmxlX0lPRXhjZXB0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb29zLndyaXRlT2JqZWN0KHRlc3RTdHJpbmcpOworICAgICAgICBvb3MuY2xvc2UoKTsKKworICAgICAgICBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbSBzaXMgPSBuZXcgU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpOworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0oc2lzKTsKKyAgICAgICAgc2lzLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9pcy5hdmFpbGFibGUoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIHNpcy50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IGZhbHNlOworICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb3NlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0uY2xvc2UoKQorICAgICAgICBvb3Mud3JpdGVPYmplY3QodGVzdFN0cmluZyk7CisgICAgICAgIG9vcy5jbG9zZSgpOworCisgICAgICAgIFN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtIHNpcyA9IG5ldyBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShzaXMpOworICAgICAgICBzaXMudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2lzLmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICBzaXMudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSBmYWxzZTsKKyAgICAgICAgb2lzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9lbmFibGVSZXNvbHZlT2JqZWN0QigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFN0YXJ0IHRlc3Rpbmcgd2l0aG91dCBhIFNlY3VyaXR5TWFuYWdlci4KKyAgICAgICAgQmFzaWNPYmplY3RJbnB1dFN0cmVhbSBib2lzID0gbmV3IEJhc2ljT2JqZWN0SW5wdXRTdHJlYW0oKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRlc3QgMTogT2JqZWN0IHJlc29sdmluZyBtdXN0IGJlIGRpc2FibGVkIGJ5IGRlZmF1bHQuIiwKKyAgICAgICAgICAgICAgICBib2lzLmVuYWJsZVJlc29sdmVPYmplY3QodHJ1ZSkpOworCisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMjogZW5hYmxlUmVzb2x2ZU9iamVjdCBkaWQgbm90IHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUuIiwKKyAgICAgICAgICAgICAgICBib2lzLmVuYWJsZVJlc29sdmVPYmplY3QoZmFsc2UpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRfSU9FeGNlcHRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvb3Mud3JpdGVPYmplY3QodGVzdFN0cmluZyk7CisgICAgICAgIG9vcy5jbG9zZSgpOworCisgICAgICAgIFN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtIHNpcyA9IG5ldyBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShzaXMpOworICAgICAgICBzaXMudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2lzLnJlYWQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIHNpcy50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IGZhbHNlOworICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWQkQklJKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtLnJlYWQoYnl0ZSBbXSwgaW50LCBpbnQpCisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVt0ZXN0TGVuZ3RoXTsKKyAgICAgICAgb29zLndyaXRlQnl0ZXModGVzdFN0cmluZyk7CisgICAgICAgIG9vcy5jbG9zZSgpOworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhby50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIG9pcy5yZWFkKGJ1ZiwgMCwgdGVzdExlbmd0aCk7CisgICAgICAgIG9pcy5jbG9zZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJlYWQgaW5jb3JyZWN0IGJ5dGVzIiwgdGVzdFN0cmluZywgbmV3IFN0cmluZyhidWYpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWQkQklJX0V4Y2VwdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVt0ZXN0TGVuZ3RoXTsKKyAgICAgICAgb29zLndyaXRlT2JqZWN0KHRlc3RTdHJpbmcpOworICAgICAgICBvb3MuY2xvc2UoKTsKKworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhby50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvaXMucmVhZChidWYsIDAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgb2lzLnJlYWQoYnVmLCAtMSwxKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgb2lzLnJlYWQoYnVmLCB0ZXN0TGVuZ3RoLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBvaXMuY2xvc2UoKTsKKworCisgICAgICAgIFN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtIHNpcyA9IG5ldyBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShzaXMpOworICAgICAgICBzaXMudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2lzLnJlYWQoYnVmLCAwLCB0ZXN0TGVuZ3RoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIHNpcy50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IGZhbHNlOworICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRGdWxseSRCKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlW3Rlc3RMZW5ndGhdOworICAgICAgICBvb3Mud3JpdGVCeXRlcyh0ZXN0U3RyaW5nKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgb2lzLnJlYWRGdWxseShidWYpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IGJ5dGVzIHJlYWQ7IiwKKyAgICAgICAgICAgICAgICB0ZXN0U3RyaW5nLCBuZXcgU3RyaW5nKGJ1ZikpOworICAgICAgICBvaXMuY2xvc2UoKTsKKworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhby50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIG9pcy5yZWFkKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvaXMucmVhZEZ1bGx5KGJ1Zik7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IEVPRkV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkRnVsbHkkQl9FeGNlcHRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbdGVzdExlbmd0aF07CisgICAgICAgIG9vcy53cml0ZU9iamVjdCh0ZXN0U3RyaW5nKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisKKyAgICAgICAgU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW0gc2lzID0gbmV3IFN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtKGJhby50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKHNpcyk7CisgICAgICAgIHNpcy50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvaXMucmVhZEZ1bGx5KGJ1Zik7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICBzaXMudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSBmYWxzZTsKKyAgICAgICAgb2lzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkRnVsbHkkQklJKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbS5yZWFkRnVsbHkoYnl0ZSBbXSwKKyAgICAgICAgLy8gaW50LCBpbnQpCisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVt0ZXN0TGVuZ3RoXTsKKyAgICAgICAgb29zLndyaXRlQnl0ZXModGVzdFN0cmluZyk7CisgICAgICAgIG9vcy5jbG9zZSgpOworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhby50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIG9pcy5yZWFkRnVsbHkoYnVmLCAwLCB0ZXN0TGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZWFkIGluY29ycmVjdCBieXRlcyIsIHRlc3RTdHJpbmcsIG5ldyBTdHJpbmcoYnVmKSk7CisgICAgICAgIG9pcy5jbG9zZSgpOworCisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgb2lzLnJlYWQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9pcy5yZWFkRnVsbHkoYnVmKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogRU9GRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRGdWxseSRCSUlfRXhjZXB0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlW3Rlc3RMZW5ndGhdOworICAgICAgICBvb3Mud3JpdGVPYmplY3QodGVzdFN0cmluZyk7CisgICAgICAgIG9vcy5jbG9zZSgpOworCisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFvLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9pcy5yZWFkRnVsbHkoYnVmLCAwLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9pcy5yZWFkRnVsbHkoYnVmLCAtMSwxKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgb2lzLnJlYWRGdWxseShidWYsIHRlc3RMZW5ndGgsIDEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIG9pcy5jbG9zZSgpOworCisgICAgICAgIFN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtIHNpcyA9IG5ldyBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShzaXMpOworICAgICAgICBzaXMudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2lzLnJlYWRGdWxseShidWYsIDAsIDEpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAxOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICAgICAgc2lzLnRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gZmFsc2U7CisgICAgICAgIG9pcy5jbG9zZSgpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkTGluZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBsaW5lOworICAgICAgICBvb3Mud3JpdGVCeXRlcygiTG9yZW1cbmlwc3VtXHJkb2xvciBzaXQgYW1ldC4uLiIpOworICAgICAgICBvb3MuY2xvc2UoKTsKKworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhby50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIGxpbmUgPSBvaXMucmVhZExpbmUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBJbmNvcnJlY3QgbGluZSB3cml0dGVuIG9yIHJlYWQ6ICIgKyBsaW5lLAorICAgICAgICAgICAgICAgIGxpbmUuZXF1YWxzKCJMb3JlbSIpKTsKKyAgICAgICAgbGluZSA9IG9pcy5yZWFkTGluZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDI6IEluY29ycmVjdCBsaW5lIHdyaXR0ZW4gb3IgcmVhZDogIiArIGxpbmUsCisgICAgICAgICAgICAgICAgbGluZS5lcXVhbHMoImlwc3VtIikpOworICAgICAgICBsaW5lID0gb2lzLnJlYWRMaW5lKCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMzogSW5jb3JyZWN0IGxpbmUgd3JpdHRlbiBvciByZWFkOiAiICsgbGluZSwKKyAgICAgICAgICAgICAgICBsaW5lLmVxdWFscygiZG9sb3Igc2l0IGFtZXQuLi4iKSk7CisgICAgICAgIG9pcy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZExpbmVfSU9FeGNlcHRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvb3Mud3JpdGVPYmplY3QodGVzdFN0cmluZyk7CisgICAgICAgIG9vcy5jbG9zZSgpOworCisgICAgICAgIFN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtIHNpcyA9IG5ldyBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShzaXMpOworICAgICAgICBzaXMudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2lzLnJlYWRMaW5lKCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDE6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgICAgICBzaXMudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSBmYWxzZTsKKyAgICAgICAgb2lzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGZpbGxTdHJlYW1IZWFkZXIoYnl0ZVtdIGJ1ZmZlcikgeworICAgICAgICBzaG9ydCBtYWdpYyA9IGphdmEuaW8uT2JqZWN0U3RyZWFtQ29uc3RhbnRzLlNUUkVBTV9NQUdJQzsKKyAgICAgICAgc2hvcnQgdmVyc2lvbiA9IGphdmEuaW8uT2JqZWN0U3RyZWFtQ29uc3RhbnRzLlNUUkVBTV9WRVJTSU9OOworCisgICAgICAgIGlmIChidWZmZXIubGVuZ3RoIDwgNCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVGhlIGJ1ZmZlcidzIG1pbmltYWwgbGVuZ3RoIG11c3QgYmUgNC4iKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEluaXRpYWxpemUgdGhlIGJ1ZmZlciB3aXRoIHRoZSBjb3JyZWN0IGhlYWRlciBmb3Igb2JqZWN0IHN0cmVhbXMKKyAgICAgICAgYnVmZmVyWzBdID0gKGJ5dGUpIChtYWdpYyA+PiA4KTsKKyAgICAgICAgYnVmZmVyWzFdID0gKGJ5dGUpIG1hZ2ljOworICAgICAgICBidWZmZXJbMl0gPSAoYnl0ZSkgKHZlcnNpb24gPj4gOCk7CisgICAgICAgIGJ1ZmZlclszXSA9IChieXRlKSAodmVyc2lvbik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkT2JqZWN0T3ZlcnJpZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlWzRdOworCisgICAgICAgIC8vIEluaXRpYWxpemUgdGhlIGJ1ZmZlciB3aXRoIHRoZSBjb3JyZWN0IGhlYWRlciBmb3Igb2JqZWN0IHN0cmVhbXMKKyAgICAgICAgZmlsbFN0cmVhbUhlYWRlcihidWZmZXIpOworCisgICAgICAgIC8vIFRlc3QgMTogQ2hlY2sgdGhhdCByZWFkT2JqZWN0T3ZlcnJpZGUoKSByZXR1cm5zIG51bGwgaWYgdGhlcmUKKyAgICAgICAgLy8gaXMgbm8gaW5wdXQgc3RyZWFtLgorICAgICAgICBCYXNpY09iamVjdElucHV0U3RyZWFtIGJvaXMgPSBuZXcgQmFzaWNPYmplY3RJbnB1dFN0cmVhbSgpOworICAgICAgICBhc3NlcnROdWxsKCJUZXN0IDE6IiwgYm9pcy5yZWFkT2JqZWN0T3ZlcnJpZGUoKSk7CisKKyAgICAgICAgLy8gVGVzdCAyOiBDaGVjayB0aGF0IHJlYWRPYmplY3RPdmVycmlkZSgpIHRocm93cyBhbiBJT0V4Y2VwdGlvbgorICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbiBpbnB1dCBzdHJlYW0uCisgICAgICAgIGJvaXMgPSBuZXcgQmFzaWNPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnVmZmVyKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBib2lzLnJlYWRPYmplY3RPdmVycmlkZSgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBJT0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkge30KKworICAgICAgICBib2lzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkT2JqZWN0TWlzc2luZ0NsYXNzZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3QudmVyaWZ5U2VsZihuZXcgQTEoKSwgbmV3IFNlcmlhbGl6YWJsZUFzc2VydCgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFzc2VydERlc2VyaWFsaXplZChTZXJpYWxpemFibGUgaW5pdGlhbCwKKyAgICAgICAgICAgICAgICAgICAgU2VyaWFsaXphYmxlIGRlc2VyaWFsaXplZCkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyg1LCAoKEExKSBkZXNlcmlhbGl6ZWQpLmIxLmkpOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlYWRPYmplY3RDb3JydXB0KCkgeworICAgICAgICBieXRlW10gYnl0ZXMgPSB7IDAwLCAwMCwgMDAsIDB4NjQsIDB4NDMsIDB4NDgsIChieXRlKSAweEZELCAweDcxLCAwMCwKKyAgICAgICAgICAgICAgICAwMCwgMHgwQiwgKGJ5dGUpIDB4QjgsIDB4NEQsIDB4NjUgfTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzKTsKKyAgICAgICAgYm9vbGVhbiBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE9iamVjdElucHV0U3RyZWFtIGluID0gbmV3IE9iamVjdElucHV0U3RyZWFtKGJpbik7CisgICAgICAgICAgICBpbi5yZWFkT2JqZWN0KCk7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIHJlYWQgb2YgY29ycnVwdGVkIHN0cmVhbSIpOworICAgICAgICB9IGNhdGNoIChTdHJlYW1Db3JydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZDogIiArIGUpOworICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQ6ICIgKyBlKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJFeHBlY3RlZCBTdHJlYW1Db3JydXB0ZWRFeGNlcHRpb24iLCBleGNlcHRpb24pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZFN0cmVhbUhlYWRlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB0ZXN0U3RyaW5nID0gIkxvcmVtIGlwc3VtIjsKKyAgICAgICAgQmFzaWNPYmplY3RJbnB1dFN0cmVhbSBib2lzOworICAgICAgICBzaG9ydCBtYWdpYyA9IGphdmEuaW8uT2JqZWN0U3RyZWFtQ29uc3RhbnRzLlNUUkVBTV9NQUdJQzsKKyAgICAgICAgc2hvcnQgdmVyc2lvbiA9IGphdmEuaW8uT2JqZWN0U3RyZWFtQ29uc3RhbnRzLlNUUkVBTV9WRVJTSU9OOworICAgICAgICBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbMjBdOworCisgICAgICAgIC8vIEluaXRpYWxpemUgdGhlIGJ1ZmZlciB3aXRoIHRoZSBjb3JyZWN0IGhlYWRlciBmb3Igb2JqZWN0IHN0cmVhbXMKKyAgICAgICAgZmlsbFN0cmVhbUhlYWRlcihidWZmZXIpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRlc3RTdHJpbmcuZ2V0Qnl0ZXMoKSwgMCwgYnVmZmVyLCA0LCB0ZXN0U3RyaW5nLmxlbmd0aCgpKTsKKworICAgICAgICAvLyBUZXN0IDE6IHJlYWRTdHJlYW1IZWFkZXIgc2hvdWxkIG5vdCB0aHJvdyBhIFN0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbi4KKyAgICAgICAgLy8gSXQgc2hvdWxkIGdldCBjYWxsZWQgYnkgdGhlIE9iamVjdElucHV0U3RyZWFtIGNvbnN0cnVjdG9yLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZFN0cmVhbUhlYWRlckNhbGxlZCA9IGZhbHNlOworICAgICAgICAgICAgYm9pcyA9IG5ldyBCYXNpY09iamVjdElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShidWZmZXIpKTsKKyAgICAgICAgICAgIGJvaXMuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoU3RyZWFtQ29ycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogVW5leHBlY3RlZCBTdHJlYW1Db3JydXB0ZWRFeGNlcHRpb24uIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiByZWFkU3RyZWFtSGVhZGVyKCkgaGFzIG5vdCBiZWVuIGNhbGxlZC4iLAorICAgICAgICAgICAgICAgICAgICByZWFkU3RyZWFtSGVhZGVyQ2FsbGVkKTsKKworICAgICAgICAvLyBUZXN0IDI6IE1ha2UgdGhlIHN0cmVhbSBtYWdpYyBudW1iZXIgaW52YWxpZCBhbmQgY2hlY2sgdGhhdAorICAgICAgICAvLyByZWFkU3RyZWFtSGVhZGVyKCkgdGhyb3dzIGFuIGV4Y2VwdGlvbi4KKyAgICAgICAgYnVmZmVyWzBdID0gKGJ5dGUpbWFnaWM7CisgICAgICAgIGJ1ZmZlclsxXSA9IChieXRlKShtYWdpYyA+PiA4KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRTdHJlYW1IZWFkZXJDYWxsZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIGJvaXMgPSBuZXcgQmFzaWNPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnVmZmVyKSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDI6IFN0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgICAgIGJvaXMuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoU3RyZWFtQ29ycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDI6IHJlYWRTdHJlYW1IZWFkZXIoKSBoYXMgbm90IGJlZW4gY2FsbGVkLiIsCisgICAgICAgICAgICAgICAgICAgIHJlYWRTdHJlYW1IZWFkZXJDYWxsZWQpOworCisgICAgICAgIC8vIFRlc3QgMzogTWFrZSB0aGUgc3RyZWFtIHZlcnNpb24gaW52YWxpZCBhbmQgY2hlY2sgdGhhdAorICAgICAgICAvLyByZWFkU3RyZWFtSGVhZGVyKCkgdGhyb3dzIGFuIGV4Y2VwdGlvbi4KKyAgICAgICAgYnVmZmVyWzBdID0gKGJ5dGUpKG1hZ2ljID4+IDgpOworICAgICAgICBidWZmZXJbMV0gPSAoYnl0ZSltYWdpYzsKKyAgICAgICAgYnVmZmVyWzJdID0gKGJ5dGUpKHZlcnNpb24pOworICAgICAgICBidWZmZXJbM10gPSAoYnl0ZSkodmVyc2lvbiA+PiA4KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWRTdHJlYW1IZWFkZXJDYWxsZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIGJvaXMgPSBuZXcgQmFzaWNPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnVmZmVyKSk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IFN0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgICAgIGJvaXMuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoU3RyZWFtQ29ycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDM6IHJlYWRTdHJlYW1IZWFkZXIoKSBoYXMgbm90IGJlZW4gY2FsbGVkLiIsCisgICAgICAgICAgICAgICAgICAgIHJlYWRTdHJlYW1IZWFkZXJDYWxsZWQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZFVuc2lnbmVkQnl0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9vcy53cml0ZUJ5dGUoLTEpOworICAgICAgICBvb3MuY2xvc2UoKTsKKworICAgICAgICBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhby50b0J5dGVBcnJheSgpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgdW5zaWduZWQgYnl0ZSB3cml0dGVuIG9yIHJlYWQuIiwKKyAgICAgICAgICAgICAgICAyNTUsIG9pcy5yZWFkVW5zaWduZWRCeXRlKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvaXMucmVhZFVuc2lnbmVkQnl0ZSgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBFT0ZFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIG9pcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2lzLnJlYWRVbnNpZ25lZEJ5dGUoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWFkVW5zaWduZWRTaG9ydCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbS5yZWFkVW5zaWduZWRTaG9ydCgpCisgICAgICAgIG9vcy53cml0ZVNob3J0KC0xKTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisKKyAgICAgICAgb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTogSW5jb3JyZWN0IHVuc2lnbmVkIHNob3J0IHdyaXR0ZW4gb3IgcmVhZC4iLAorICAgICAgICAgICAgICAgIDY1NTM1LCBvaXMucmVhZFVuc2lnbmVkU2hvcnQoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9pcy5yZWFkVW5zaWduZWRTaG9ydCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAyOiBFT0ZFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorCisgICAgICAgIG9pcy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2lzLnJlYWRVbnNpZ25lZFNob3J0KCk7CisgICAgICAgICAgICBmYWlsKCJUZXN0IDM6IElPRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVzb2x2ZVByb3h5Q2xhc3MoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBCYXNpY09iamVjdElucHV0U3RyZWFtIGJvaXM7CisgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVsxMF07CisKKyAgICAgICAgLy8gSW5pdGlhbGl6ZSB0aGUgYnVmZmVyIHdpdGggdGhlIGhlYWRlciBmb3Igb2JqZWN0IHN0cmVhbXMKKyAgICAgICAgZmlsbFN0cmVhbUhlYWRlcihidWZmZXIpOworICAgICAgICBib2lzID0gbmV3IEJhc2ljT2JqZWN0SW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ1ZmZlcikpOworCisgICAgICAgIC8vIFRlc3QgMTogQ2hlY2sgdGhhdCBhIE51bGxQb2ludGVyRXhjZXB0aW9uIGlzIHRocm93bgorICAgICAgICAvLyBpZiBudWxsIGlzIHBhc3NlZCB0byB0aGUgbWV0aG9kLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgYm9pcy5yZXNvbHZlUHJveHlDbGFzcyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0KKyAgICAgICAgY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICB9CisgICAgICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogVW5leHBlY3RlZCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLiIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVGVzdCAyOiBDaGVjayB0aGF0IHZpc2libGUgaW50ZXJmYWNlcyBhcmUgZm91bmQuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmdbXSBpbnRlcmZhY2VzID0geyAiamF2YS5pby5DbG9zZWFibGUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEubGFuZy5DbG9uZWFibGUiIH07CisgICAgICAgICAgICBib2lzLnJlc29sdmVQcm94eUNsYXNzKGludGVyZmFjZXMpOworICAgICAgICB9CisgICAgICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogVW5leHBlY3RlZCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLiIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVGVzdCAzOiBDaGVjayB0aGF0IGEgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBpcyB0aHJvd24gaWYgdGhlCisgICAgICAgIC8vIGFycmF5IG9mIGludGVyZmFjZXMgaXMgbm90IHZhbGlkLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nW10gaW50ZXJmYWNlcyA9IHsgImphdmEuaW8uQ2xvc2VhYmxlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLmlvLkNsb3NlYWJsZSIgfTsKKyAgICAgICAgICAgIGJvaXMucmVzb2x2ZVByb3h5Q2xhc3MoaW50ZXJmYWNlcyk7CisgICAgICAgICAgICBmYWlsICgiVGVzdCAzOiBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9CisgICAgICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpIHsKKyAgICAgICAgfQorCisgICAgICAgIGJvaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NraXBCeXRlc0lfSU9FeGNlcHRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvb3Mud3JpdGVPYmplY3QodGVzdFN0cmluZyk7CisgICAgICAgIG9vcy5jbG9zZSgpOworCisgICAgICAgIFN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtIHNpcyA9IG5ldyBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbShiYW8udG9CeXRlQXJyYXkoKSk7CisgICAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShzaXMpOworICAgICAgICBzaXMudGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2lzLnNraXBCeXRlcyg1KTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMTogSU9FeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgICAgIHNpcy50aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IGZhbHNlOworICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEEgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDExTDsKKworICAgICAgICBwdWJsaWMgU3RyaW5nIG5hbWUgPSAibmFtZSI7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBCIGV4dGVuZHMgQSB7fQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBDIGV4dGVuZHMgQiB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzNMOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQTEgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1OTQyNTg0OTEzNDQ2MDc5NjYxTDsKKworICAgICAgICBCMSBiMSA9IG5ldyBCMSgpOworCisgICAgICAgIEIxIGIyID0gYjE7CisKKyAgICAgICAgVmVjdG9yIHYgPSBuZXcgVmVjdG9yKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBCMSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgaW50IGkgPSA1OworCisgICAgICAgIEhhc2h0YWJsZSBoID0gbmV3IEhhc2h0YWJsZSgpOworICAgIH0KKworICAgIGNsYXNzIEJhc2ljT2JqZWN0SW5wdXRTdHJlYW0gZXh0ZW5kcyBPYmplY3RJbnB1dFN0cmVhbSB7CisgICAgICAgIHB1YmxpYyBCYXNpY09iamVjdElucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBTZWN1cml0eUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEJhc2ljT2JqZWN0SW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaW5wdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcihpbnB1dCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBlbmFibGVSZXNvbHZlT2JqZWN0KGJvb2xlYW4gZW5hYmxlKQorICAgICAgICAgICAgICAgIHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZW5hYmxlUmVzb2x2ZU9iamVjdChlbmFibGUpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCByZWFkT2JqZWN0T3ZlcnJpZGUoKSB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnJlYWRPYmplY3RPdmVycmlkZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcmVhZFN0cmVhbUhlYWRlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZWFkU3RyZWFtSGVhZGVyQ2FsbGVkID0gdHJ1ZTsKKyAgICAgICAgICAgIHN1cGVyLnJlYWRTdHJlYW1IZWFkZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBDbGFzczw/PiByZXNvbHZlUHJveHlDbGFzcyhTdHJpbmdbXSBpbnRlcmZhY2VOYW1lcykKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnJlc29sdmVQcm94eUNsYXNzKGludGVyZmFjZU5hbWVzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vUmVncmVzc2lvbiBUZXN0IGZvciBKSVJBLTIyNDkKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE9iamVjdE91dHB1dFN0cmVhbVdpdGhXcml0ZURlc2MgZXh0ZW5kcworICAgICAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtIHsKKyAgICAgICAgcHVibGljIE9iamVjdE91dHB1dFN0cmVhbVdpdGhXcml0ZURlc2MoT3V0cHV0U3RyZWFtIG9zKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcihvcyk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZUNsYXNzRGVzY3JpcHRvcihPYmplY3RTdHJlYW1DbGFzcyBkZXNjKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE9iamVjdElucHV0U3RyZWFtV2l0aFJlYWREZXNjIGV4dGVuZHMKKyAgICAgICAgICAgIE9iamVjdElucHV0U3RyZWFtIHsKKyAgICAgICAgcHJpdmF0ZSBDbGFzcyByZXR1cm5DbGFzczsKKworICAgICAgICBwdWJsaWMgT2JqZWN0SW5wdXRTdHJlYW1XaXRoUmVhZERlc2MoSW5wdXRTdHJlYW0gaXMsIENsYXNzIHJldHVybkNsYXNzKQorICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcihpcyk7CisgICAgICAgICAgICB0aGlzLnJldHVybkNsYXNzID0gcmV0dXJuQ2xhc3M7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0U3RyZWFtQ2xhc3MgcmVhZENsYXNzRGVzY3JpcHRvcigpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBPYmplY3RTdHJlYW1DbGFzcy5sb29rdXAocmV0dXJuQ2xhc3MpOworCisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgVGVzdENsYXNzRm9yU2VyaWFsaXphdGlvbiBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIG9vcyA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0oYmFvID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpKTsKKyAgICB9Cit9CisKK2NsYXNzIFRlc3QgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgQ2xhc3M8Pz4gY2xhc3Nlc1tdID0gbmV3IENsYXNzW10geyBieXRlLmNsYXNzLCBzaG9ydC5jbGFzcywgaW50LmNsYXNzLAorICAgICAgICAgICAgbG9uZy5jbGFzcywgYm9vbGVhbi5jbGFzcywgY2hhci5jbGFzcywgZmxvYXQuY2xhc3MsIGRvdWJsZS5jbGFzcyB9OworCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBUZXN0KSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBBcnJheXMuZXF1YWxzKGNsYXNzZXMsICgoVGVzdCkgbykuY2xhc3Nlcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2lvL1NlcmlhbGl6YXRpb25UZXN0Q2xhc3MuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9pby9TZXJpYWxpemF0aW9uVGVzdENsYXNzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzJjNGQwYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9pby9TZXJpYWxpemF0aW9uVGVzdENsYXNzLmphdmEKQEAgLTAsMCArMSwzMzUgQEAKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEuaW87CisKK3B1YmxpYyBjbGFzcyBTZXJpYWxpemF0aW9uVGVzdENsYXNzIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworCisgICAgLy8gVGVzdCBjbGFzcyBuYW1lcworICAgIHB1YmxpYyBjbGFzcyBUZXN0Q2xhc3NOYW1lMSBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdENsYXNzTmFtZTJUX1QkVCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICAvLyBUZXN0IE1vZGlmaWVycworICAgIHB1YmxpYyBjbGFzcyBUZXN0Q2xhc3NNb2RpZmllclB1YmxpYyBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBpbnRlcmZhY2UgVGVzdENsYXNzTW9kaWZpZXJJbnRlcmZhY2VIZWxwZXIgZXh0ZW5kcyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIFRlc3RDbGFzc01vZGlmaWVySW50ZXJmYWNlIGltcGxlbWVudHMKKyAgICAgICAgICAgIFRlc3RDbGFzc01vZGlmaWVySW50ZXJmYWNlSGVscGVyIHsKKyAgICB9CisKKyAgICBmaW5hbCBjbGFzcyBUZXN0Q2xhc3NNb2RpZmllckZpbmFsIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIGFic3RyYWN0IGNsYXNzIFRlc3RDbGFzc01vZGlmaWVyQWJzdHJhY3RIZWxwZXIgaW1wbGVtZW50cworICAgICAgICAgICAgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0Q2xhc3NNb2RpZmllckFic3RyYWN0IGV4dGVuZHMKKyAgICAgICAgICAgIFRlc3RDbGFzc01vZGlmaWVyQWJzdHJhY3RIZWxwZXIgeworICAgIH0KKworCisgICAgLy8gVE9ETyBBcnJheXMgYWx3YXlzIGFyZSBhYnN0cmFjdAorCisgICAgLy8gVE9ETyBOb24gcHVibGljIGludGVyZmFjZSBoYXMgbm8gYWJzdHJhY3QgbW9kaWZpZXIKKworCisgICAgLy8gVGVzdCBpbnRlcmZhY2VzCisgICAgaW50ZXJmYWNlIEEgZXh0ZW5kcyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgfQorCisgICAgaW50ZXJmYWNlIEIgZXh0ZW5kcyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgfQorCisgICAgaW50ZXJmYWNlIEMgZXh0ZW5kcyBBIHsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdEludGVmYWNlcyBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdEludGVmYWNlc0EgaW1wbGVtZW50cyBBIHsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdEludGVmYWNlc0FCIGltcGxlbWVudHMgQSwgQiB7CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIFRlc3RJbnRlZmFjZXNCQSBpbXBsZW1lbnRzIEIsIEEgeworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0SW50ZWZhY2VzQyBpbXBsZW1lbnRzIEMgeworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0SW50ZWZhY2VzQUMgaW1wbGVtZW50cyBBLCBDIHsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdEludGVmYWNlc0NBIGltcGxlbWVudHMgQywgQSB7CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIFRlc3RJbnRlZmFjZXNBQkMgaW1wbGVtZW50cyBBLCBCLCBDIHsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdEludGVmYWNlc0FDQiBpbXBsZW1lbnRzIEEsIEMsIEIgeworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0SW50ZWZhY2VzQkFDIGltcGxlbWVudHMgQiwgQSwgQyB7CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIFRlc3RJbnRlZmFjZXNCQ0EgaW1wbGVtZW50cyBCLCBDLCBBIHsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdEludGVmYWNlc0NBQiBpbXBsZW1lbnRzIEMsIEEsIEIgeworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0SW50ZWZhY2VzQ0JBIGltcGxlbWVudHMgQywgQiwgQSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogTW9kaWZpZXIuUFVCTElDIHwgTW9kaWZpZXIuUFJJVkFURSB8IE1vZGlmaWVyLlBST1RFQ1RFRCB8IE1vZGlmaWVyLlNUQVRJQyB8CisgICAgICogTW9kaWZpZXIuRklOQUwgfCBNb2RpZmllci5WT0xBVElMRSB8IE1vZGlmaWVyLlRSQU5TSUVOVAorICAgICAqLworICAgIC8vIFRlc3QgRmllbGRzCisgICAgcHVibGljIGNsYXNzIFRlc3RGaWVsZHNOb25lIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0RmllbGRzT25lUHVibGljIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgICBwdWJsaWMgaW50IG9uZTsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdEZpZWxkc1R3b1B1YmxpYyBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHVibGljIGludCBvbmU7CisgICAgICAgIHB1YmxpYyBpbnQgdHdvOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgIHB1YmxpYyBjbGFzcyBUZXN0RmllbGRzT25lUHJpdmF0ZSBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBpbnQgb25lOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgIHB1YmxpYyBjbGFzcyBUZXN0RmllbGRzVHdvUHJpdmF0ZSBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBpbnQgb25lOworICAgICAgICBwcml2YXRlIGludCB0d287CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIFRlc3RGaWVsZHNPbmVQcm90ZWN0ZWQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICAgIHByb3RlY3RlZCBpbnQgb25lOworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0RmllbGRzVHdvUHJvdGVjdGVkIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgICBwcm90ZWN0ZWQgaW50IG9uZTsKKyAgICAgICAgcHJvdGVjdGVkIGludCB0d287CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBUZXN0RmllbGRzT25lU3RhdGljIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgICBzdGF0aWMgaW50IG9uZTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFRlc3RGaWVsZHNUd29TdGF0aWMgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICAgIHN0YXRpYyBpbnQgb25lOworICAgICAgICBzdGF0aWMgaW50IHR3bzsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdEZpZWxkc09uZUZpbmFsIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgICBmaW5hbCBpbnQgb25lID0gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdEZpZWxkc1R3b0ZpbmFsIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgICBmaW5hbCBpbnQgb25lID0gMDsKKyAgICAgICAgZmluYWwgaW50IHR3byA9IDA7CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIFRlc3RGaWVsZHNPbmVWb2xhdGlsZSBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgICAgdm9sYXRpbGUgaW50IG9uZTsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdEZpZWxkc1R3b1ZvbGF0aWxlIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgICB2b2xhdGlsZSBpbnQgb25lOworICAgICAgICB2b2xhdGlsZSBpbnQgdHdvOworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0RmllbGRzT25lVHJhbnNpZW50IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgICB0cmFuc2llbnQgaW50IG9uZTsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdEZpZWxkc1R3b1RyYW5zaWVudCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgICAgdHJhbnNpZW50IGludCBvbmU7CisgICAgICAgIHRyYW5zaWVudCBpbnQgdHdvOworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0RmllbGRTaWduYXR1cmVzIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgICBPYmplY3QgbDsKKyAgICAgICAgaW50IGk7CisgICAgICAgIHNob3J0IHM7CisgICAgICAgIGxvbmcgajsKKyAgICAgICAgYm9vbGVhbiB6OworICAgICAgICBjaGFyIGM7CisgICAgICAgIGRvdWJsZSBkOworICAgICAgICBmbG9hdCBmOworICAgICAgICBieXRlIGI7CisgICAgfQorCisKKyAgICAvLyBUZXN0IENvbnN0cnVjdG9ycworICAgIHB1YmxpYyBjbGFzcyBUZXN0Q29uc3RydWN0b3JOb25lIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0Q29uc3RydWN0b3JPbmUgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICAgIHB1YmxpYyBUZXN0Q29uc3RydWN0b3JPbmUoKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdENvbnN0cnVjdG9yVHdvIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgICBwdWJsaWMgVGVzdENvbnN0cnVjdG9yVHdvKGJ5dGUgYikgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFRlc3RDb25zdHJ1Y3RvclR3byhjaGFyIGMpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0Q29uc3RydWN0b3JUd29SZXZlcnNlIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgICBwdWJsaWMgVGVzdENvbnN0cnVjdG9yVHdvUmV2ZXJzZShjaGFyIGMpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBUZXN0Q29uc3RydWN0b3JUd29SZXZlcnNlKGJ5dGUgYikgeworICAgICAgICB9CisgICAgfQorCisKKyAgICAvLyBUZXN0IENvbnN0cnVjdG9yIE1vZGlmaWVycworICAgIHB1YmxpYyBjbGFzcyBUZXN0Q29uc3RydWN0b3JQdWJsaWMgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICAgIHB1YmxpYyBUZXN0Q29uc3RydWN0b3JQdWJsaWMoKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdENvbnN0cnVjdG9yUHJpdmF0ZSBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBUZXN0Q29uc3RydWN0b3JQcml2YXRlKCkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFRlc3RDb25zdHJ1Y3RvclByaXZhdGUoaW50IGkpIHsKKyAgICAgICAgICAgIHRoaXMoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0Q29uc3RydWN0b3JQcm90ZWN0ZWQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICAgIHByb3RlY3RlZCBUZXN0Q29uc3RydWN0b3JQcm90ZWN0ZWQoKSB7CisgICAgICAgIH0KKyAgICB9CisgICAgLy8gVE9ETyBjb25zdHJ1Y3RvciBtb2RpZmllciBzdHJpY3Q/CisgICAgLy8gVE9ETyBjb25zdHJ1Y3RvciBtb2RpZmllciBzdGF0aWM/CisgICAgLy8gVE9ETyBjb25zdHJ1Y3RvciBtb2RpZmllciBmaW5hbD8KKyAgICAvLyBUT0RPIGNvbnN0cnVjdG9yIG1vZGlmaWVyIHN5bmNocm9uaXplZD8KKyAgICAvLyBUT0RPIGNvbnN0cnVjdG9yIG1vZGlmaWVyIG5hdGl2ZT8KKyAgICAvLyBUT0RPIGNvbnN0cnVjdG9yIG1vZGlmaWVyIGFic3RyYWN0PworCisKKyAgICAvLyBUZXN0IGNvbnN0cnVjdG9yIHNpZ25hdHVyZQorICAgIHB1YmxpYyBjbGFzcyBUZXN0Q29uc3RydWN0b3JTaWduYXR1cmUgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICAgIHB1YmxpYyBUZXN0Q29uc3RydWN0b3JTaWduYXR1cmUoYm9vbGVhbiB6LCBieXRlIGIsIGNoYXIgYywgc2hvcnQgcywKKyAgICAgICAgICAgICAgICBpbnQgaSwgZmxvYXQgZiwgZG91YmxlIGosIE9iamVjdCBsKSB7CisgICAgICAgIH0KKyAgICB9CisKKworICAgIC8vIFRlc3QgTWV0aG9kIE1vZGlmaWVycworICAgIHB1YmxpYyBjbGFzcyBUZXN0TWV0aG9kUHVibGljIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgICBwdWJsaWMgdm9pZCBtZXRob2QoKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBwdWJsaWMgY2xhc3MgVGVzdE1laG9kUHJpdmF0ZSBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHJpdmF0ZSB2b2lkIG1ldGhvZCgpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0TWV0aG9kUHJvdGVjdGVkIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgICBwcm90ZWN0ZWQgdm9pZCBtZXRob2QoKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdE1ldGhvZFN0cmljdCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgICAgc3RyaWN0ZnAgdm9pZCBtZXRob2QoKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFRlc3RNZXRob2RTdGF0aWMgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICAgIHN0YXRpYyB2b2lkIG1ldGhvZCgpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0TWV0aG9kRmluYWwgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICAgIGZpbmFsIHZvaWQgbWV0aG9kKCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIFRlc3RNZXRob2RTeW5jaHJvbml6ZWQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICAgIHN5bmNocm9uaXplZCB2b2lkIG1ldGhvZCgpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0TWV0aG9kTmF0aXZlIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgICBuYXRpdmUgdm9pZCBtZXRob2QoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYWJzdHJhY3QgY2xhc3MgVGVzdE1ldGhvZEFic3RyYWN0SGVscGVyIGltcGxlbWVudHMKKyAgICAgICAgICAgIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgICAgYWJzdHJhY3Qgdm9pZCBtZXRob2QoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdE1ldGhvZEFic3RyYWN0IGV4dGVuZHMgVGVzdE1ldGhvZEFic3RyYWN0SGVscGVyIGltcGxlbWVudHMKKyAgICAgICAgICAgIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHZvaWQgbWV0aG9kKCkgeworICAgICAgICB9CisgICAgfQorCisKKyAgICAvLyBUZXN0IG1ldGhvZCBzaWduYXR1cmUKKyAgICBwdWJsaWMgY2xhc3MgVGVzdE1ldGhvZFNpZ25hdHVyZSBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgICAgcHVibGljIHZvaWQgbWV0aG9kKGJvb2xlYW4geiwgYnl0ZSBiLCBjaGFyIGMsIHNob3J0IHMsIGludCBpLCBmbG9hdCBmLAorICAgICAgICAgICAgICAgIGRvdWJsZSBqLCBPYmplY3QgbCkgeworICAgICAgICB9CisgICAgfQorCisKKyAgICAvLyBUZXN0IG1ldGhvZCByZXR1cm4gc2lnbmF0dXJlCisgICAgcHVibGljIGNsYXNzIFRlc3RNZXRob2RSZXR1cm5TaWduYXR1cmUgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICAgIHB1YmxpYyB2b2lkIG1ldGhvZFYoKSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBtZXRob2RaKCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGUgbWV0aG9kQigpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGNoYXIgbWV0aG9kQygpIHsKKyAgICAgICAgICAgIHJldHVybiAnMCc7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc2hvcnQgbWV0aG9kUygpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBtZXRob2RJKCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgZmxvYXQgbWV0aG9kRigpIHsKKyAgICAgICAgICAgIHJldHVybiAwRjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBkb3VibGUgbWV0aG9kRCgpIHsKKyAgICAgICAgICAgIHJldHVybiAwRDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBPYmplY3QgbWV0aG9kTCgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvUHJvY2VzczJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9Qcm9jZXNzMlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZDE4ZDYxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvUHJvY2VzczJUZXN0LmphdmEKQEAgLTAsMCArMSw4NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS5sYW5nOworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uQW5kcm9pZE9ubHk7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CdWZmZXJlZE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfRXhlYzsKK2ltcG9ydCBzdGF0aWMgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0V4ZWMuamF2YVByb2Nlc3NCdWlsZGVyOworCitwdWJsaWMgY2xhc3MgUHJvY2VzczJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcuUHJvY2VzcyNnZXRJbnB1dFN0cmVhbSgpLAorICAgICAqICAgICAgICBqYXZhLmxhbmcuUHJvY2VzcyNnZXRFcnJvclN0cmVhbSgpCisgICAgICogICAgICAgIGphdmEubGFuZy5Qcm9jZXNzI2dldE91dHB1dFN0cmVhbSgpCisgICAgICogVGVzdHMgaWYgdGhlc2UgbWV0aG9kcyByZXR1cm4gYnVmZmVyZWQgc3RyZWFtcy4KKyAgICAgKi8KKyAgICBAQW5kcm9pZE9ubHkoImRhbHZpa3ZtIHNwZWNpZmljIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N0cmVhbXMoKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIFByb2Nlc3MgcCA9IGphdmFQcm9jZXNzQnVpbGRlcigpLnN0YXJ0KCk7CisgICAgICAgIGFzc2VydE5vdE51bGwocC5nZXRJbnB1dFN0cmVhbSgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChwLmdldEVycm9yU3RyZWFtKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHAuZ2V0T3V0cHV0U3RyZWFtKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RXJyb3JTdHJlYW0oKSB7CisgICAgICAgIFN0cmluZ1tdIGNvbW1hbmRzID0geyJscyJ9OworICAgICAgICBQcm9jZXNzIHByb2Nlc3MgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJvY2VzcyA9IFJ1bnRpbWUuZ2V0UnVudGltZSgpLmV4ZWMoY29tbWFuZHMsIG51bGwsIG51bGwpOworICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBwcm9jZXNzLmdldEVycm9yU3RyZWFtKCk7CisgICAgICAgICAgICBTdHJpbmdCdWZmZXIgbXNnID0gbmV3IFN0cmluZ0J1ZmZlcigiIik7CisgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgIGludCBjID0gaXMucmVhZCgpOworICAgICAgICAgICAgICAgIGlmIChjID09IC0xKQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBtc2cuYXBwZW5kKChjaGFyKSBjKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiIiwgbXNnLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgcHJvY2Vzcy5kZXN0cm95KCk7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdbXSB1bmtub3duQ29tbWFuZHMgPSB7Im1rZGlyIiwgIi11IiwgInRlc3QifTsKKyAgICAgICAgUHJvY2VzcyBlclByb2Nlc3MgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZXJQcm9jZXNzID0gUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyh1bmtub3duQ29tbWFuZHMsIG51bGwsIG51bGwpOworICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBlclByb2Nlc3MuZ2V0RXJyb3JTdHJlYW0oKTsKKyAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBtc2cgPSBuZXcgU3RyaW5nQnVmZmVyKCIiKTsKKyAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgaW50IGMgPSBpcy5yZWFkKCk7CisgICAgICAgICAgICAgICAgaWYgKGMgPT0gLTEpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIG1zZy5hcHBlbmQoKGNoYXIpIGMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRXJyb3Igc3RyZWFtIHNob3VsZCBub3QgYmUgZW1wdHkiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgISIiLmVxdWFscyhtc2cudG9TdHJpbmcoKSkpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZXJQcm9jZXNzLmRlc3Ryb3koKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL1Byb2Nlc3NNYW5hZ2VyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvUHJvY2Vzc01hbmFnZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTllMWRmMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL1Byb2Nlc3NNYW5hZ2VyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjIzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS5sYW5nOworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uQnJva2VuVGVzdDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCitwdWJsaWMgY2xhc3MgUHJvY2Vzc01hbmFnZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgVGhyZWFkIHRocmVhZCA9IG51bGw7CisgICAgUHJvY2VzcyBwcm9jZXNzID0gbnVsbDsKKyAgICBib29sZWFuIGlzVGhyb3duID0gZmFsc2U7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2F0KCkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIGNvbW1hbmRzID0geyAiY2F0IiB9OworICAgICAgICBQcm9jZXNzIHByb2Nlc3MgPSBSdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKGNvbW1hbmRzLCBudWxsLCBudWxsKTsKKworICAgICAgICBPdXRwdXRTdHJlYW0gb3V0ID0gcHJvY2Vzcy5nZXRPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgU3RyaW5nIGdyZWV0aW5nID0gIkhlbGxvLCBXb3JsZCEiOworICAgICAgICBvdXQud3JpdGUoZ3JlZXRpbmcuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIG91dC53cml0ZSgnXG4nKTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGdyZWV0aW5nLCByZWFkTGluZShwcm9jZXNzKSk7CisgICAgfQorCisgICAgQEJyb2tlblRlc3QoIlNwb3JhZGljIGZhaWx1cmVzIGluIENUUywgYnV0IG5vdCBpbiBDb3JlVGVzdFJ1bm5lciIpCisgICAgcHVibGljIHZvaWQgdGVzdFNsZWVwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nW10gY29tbWFuZHMgPSB7ICJzbGVlcCIsICIxIiB9OworICAgICAgICBwcm9jZXNzID0gUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhjb21tYW5kcywgbnVsbCwgbnVsbCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgcHJvY2Vzcy53YWl0Rm9yKCkpOworCisgICAgICAgIH0gY2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gaWUpIHsKKyAgICAgICAgICAgIGZhaWwoIkludGVycnVwdGVkRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKworICAgICAgICBpc1Rocm93biA9IGZhbHNlOworICAgICAgICB0aHJlYWQgPSBuZXcgVGhyZWFkKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIFN0cmluZ1tdIGNvbW1hbmRzID0geyAic2xlZXAiLCAiMTAwMCJ9OworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHByb2Nlc3MgPSBSdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKGNvbW1hbmRzLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlMSkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLndhaXRGb3IoKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiSW50ZXJydXB0ZWRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgICAgICAgICAgfSBjYXRjaChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSkgeworICAgICAgICAgICAgICAgICAgICBpc1Rocm93biA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIFRocmVhZCBpbnRlcnJ1cHRUaHJlYWQgPSBuZXcgVGhyZWFkKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHNsZWVwKDEwKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoKEludGVycnVwdGVkRXhjZXB0aW9uIGllKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIkludGVycnVwdGVkRXhjZXB0aW9uIHdhcyB0aHJvd24gaW4gIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRoZSBpbnRlcnJ1cHRUaHJlYWQuIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRocmVhZC5pbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgdGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIGludGVycnVwdFRocmVhZC5zdGFydCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50ZXJydXB0VGhyZWFkLmpvaW4oKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSW50ZXJydXB0ZWRFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMCk7CisgICAgICAgIH0gY2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gaWUpIHsKKworICAgICAgICB9CisKKyAgICAgICAgdGhyZWFkLmludGVycnVwdCgpOworICAgICAgICAvL3Byb2Nlc3MuZGVzdHJveSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMCk7CisgICAgICAgIH0gY2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gaWUpIHsKKworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShpc1Rocm93bik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFB3ZCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBTdHJpbmdbXSBjb21tYW5kcyA9IHsgInNoIiwgIi1jIiwgInB3ZCIgfTsKKyAgICAgICAgUHJvY2VzcyBwcm9jZXNzID0gUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYygKKyAgICAgICAgICAgICAgICBjb21tYW5kcywgbnVsbCwgbmV3IEZpbGUoIi8iKSk7CisgICAgICAgIGxvZ0Vycm9ycyhwcm9jZXNzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIvIiwgcmVhZExpbmUocHJvY2VzcykpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbnZpcm9ubWVudCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBTdHJpbmdbXSBjb21tYW5kcyA9IHsgInNoIiwgIi1jIiwgImVjaG8gJEZPTyIgfTsKKworICAgICAgICAvLyBSZW1lbWJlciB0byBzZXQgdGhlIHBhdGggc28gd2UgY2FuIGZpbmQgc2guCisgICAgICAgIFN0cmluZ1tdIGVudmlyb25tZW50ID0geyAiRk9PPWZvbyIsICJQQVRIPSIgKyBTeXN0ZW0uZ2V0ZW52KCJQQVRIIikgfTsKKyAgICAgICAgUHJvY2VzcyBwcm9jZXNzID0gUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYygKKyAgICAgICAgICAgICAgICBjb21tYW5kcywgZW52aXJvbm1lbnQsIG51bGwpOworICAgICAgICBsb2dFcnJvcnMocHJvY2Vzcyk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgcmVhZExpbmUocHJvY2VzcykpOworICAgIH0KKworICAgIFN0cmluZyByZWFkTGluZShQcm9jZXNzIHByb2Nlc3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gcHJvY2Vzcy5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICBCdWZmZXJlZFJlYWRlciByZWFkZXIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKGluKSk7CisgICAgICAgIHJldHVybiByZWFkZXIucmVhZExpbmUoKTsKKyAgICB9CisKKyAgICB2b2lkIGxvZ0Vycm9ycyhmaW5hbCBQcm9jZXNzIHByb2Nlc3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFRocmVhZCB0aHJlYWQgPSBuZXcgVGhyZWFkKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGluID0gcHJvY2Vzcy5nZXRFcnJvclN0cmVhbSgpOworICAgICAgICAgICAgICAgIEJ1ZmZlcmVkUmVhZGVyIHJlYWRlcgorICAgICAgICAgICAgICAgICAgICAgICAgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKGluKSk7CisgICAgICAgICAgICAgICAgU3RyaW5nIGxpbmU7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChsaW5lID0gcmVhZGVyLnJlYWRMaW5lKCkpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihsaW5lKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIHRocmVhZC5zZXREYWVtb24odHJ1ZSk7CisgICAgICAgIHRocmVhZC5zdGFydCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RIZWF2eUxvYWQoKSB7CisgICAgICAgIGludCBpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMTAwOyBpKyspCisgICAgICAgICAgICBzdHVmZigpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgc3R1ZmYoKSB7CisgICAgICAgIFJ1bnRpbWUgcnQgPSBSdW50aW1lLmdldFJ1bnRpbWUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFByb2Nlc3MgcHJvYyA9IHJ0LmV4ZWMoImxzIik7CisgICAgICAgICAgICBwcm9jLndhaXRGb3IoKTsKKyAgICAgICAgICAgIHByb2MgPSBudWxsOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiRmFpbHVyZTogIiArIGV4KTsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGV4KTsKKyAgICAgICAgfQorICAgICAgICBydC5nYygpOworICAgICAgICBydCA9IG51bGw7CisgICAgfQorCisgICAgSW5wdXRTdHJlYW0gaW47CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvc2VOb25TdGFuZGFyZEZkcygpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nW10gY29tbWFuZHMgPSB7ICJscyIsICIvcHJvYy9zZWxmL2ZkIiB9OworCisgICAgICAgIFByb2Nlc3MgcHJvY2VzcyA9IFJ1bnRpbWUuZ2V0UnVudGltZSgpLmV4ZWMoY29tbWFuZHMsIG51bGwsIG51bGwpOworICAgICAgICBpbnQgYmVmb3JlID0gY291bnRMaW5lcyhwcm9jZXNzKTsKKworICAgICAgICAvLyBPcGVuIGEgbmV3IGZkLgorICAgICAgICB0aGlzLmluID0gbmV3IEZpbGVJbnB1dFN0cmVhbSgiL3Byb2MvdmVyc2lvbiIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcm9jZXNzID0gUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhjb21tYW5kcywgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICBpbnQgYWZ0ZXIgPSBjb3VudExpbmVzKHByb2Nlc3MpOworCisgICAgICAgICAgICAvLyBBc3NlcnQgdGhhdCB0aGUgbmV3IGZkIHdhc24ndCBvcGVuIGluIHRoZSBzZWNvbmQgcnVuLgorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGJlZm9yZSwgYWZ0ZXIpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdGhpcy5pbiA9IG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3VudHMgbGluZXMgb2YgaW5wdXQgZnJvbSB0aGUgZ2l2ZW4gcHJvY2Vzcy4gRXF1aXZhbGVudCB0byAid2MgLWwiLgorICAgICAqLworICAgIHByaXZhdGUgaW50IGNvdW50TGluZXMoUHJvY2VzcyBwcm9jZXNzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBsb2dFcnJvcnMocHJvY2Vzcyk7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gcHJvY2Vzcy5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICBCdWZmZXJlZFJlYWRlciByZWFkZXIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKGluKSk7CisgICAgICAgIGludCBjb3VudCA9IDA7CisgICAgICAgIHdoaWxlIChyZWFkZXIucmVhZExpbmUoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBjb3VudCsrOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb3VudDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZENvbW1hbmQoKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmdbXSBjb21tYW5kcyA9IHsgImRvZXNub3RleGlzdCIgfTsKKyAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLmV4ZWMoY29tbWFuZHMsIG51bGwsIG51bGwpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7IC8qIGV4cGVjdGVkICovIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9Qcm9jZXNzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvUHJvY2Vzc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mODc1ZGMwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvUHJvY2Vzc1Rlc3QuamF2YQpAQCAtMCwwICsxLDIwOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS5sYW5nOworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uQnJva2VuVGVzdDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworcHVibGljIGNsYXNzIFByb2Nlc3NUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5Qcm9jZXNzI2dldElucHV0U3RyZWFtKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldElucHV0U3RyZWFtKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gVGVzdCBmb3I6CisgICAgICAgICAgICAvL09iamVjdFtdIGV4ZWNBcmdzID0gU3VwcG9ydF9FeGVjLmV4ZWNKYXZhMigKKyAgICAgICAgICAgIC8vICAgICAgICBuZXcgU3RyaW5nW10geyAidGVzdHMuc3VwcG9ydC5TdXBwb3J0X0F2YWlsVGVzdCIgfSwgbnVsbCwKKyAgICAgICAgICAgIC8vICAgICAgICB0cnVlKTsKKyAgICAgICAgICAgIC8vUHJvY2VzcyBwcm9jID0gKFByb2Nlc3MpIGV4ZWNBcmdzWzBdOworCisgICAgICAgICAgICBTdHJpbmdbXSBjb21tYW5kcyA9IHsgInNsZWVwIiwgIjEifTsKKyAgICAgICAgICAgIFByb2Nlc3MgcHJvYyA9IFJ1bnRpbWUuZ2V0UnVudGltZSgpLmV4ZWMoY29tbWFuZHMsIG51bGwsIG51bGwpOworCisgICAgICAgICAgICBPdXRwdXRTdHJlYW0gb3MgPSBwcm9jLmdldE91dHB1dFN0cmVhbSgpOworCisgICAgICAgICAgICAvLyBmaXJzdCBudW1iZXIgaW5kaWNhdGVzIHRvdGFsIHN0cmVhbSBsZW5ndGgKKyAgICAgICAgICAgIC8vIHNlY29uZCBudW1iZXIgaW5kaWNhdGVzIGxlbmd0aCBvZiBkYXRhIGFmdGVyIHNlY29uZCBzcGFjZQorICAgICAgICAgICAgLy8gdGhpcyB3aWxsIGFsbG93IHVzIHRvIHZlcmlmeSBsZW5ndGggYXQgc3RhcnQsIG1pZGRsZSwgYW5kIGVuZAorICAgICAgICAgICAgb3Mud3JpdGUoIjEwIDUgYWJjZGUiLmdldEJ5dGVzKCkpOworICAgICAgICAgICAgb3MuY2xvc2UoKTsKKworICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBwcm9jLmdldElucHV0U3RyZWFtKCk7CisgICAgICAgICAgICBTdHJpbmdCdWZmZXIgbXNnID0gbmV3IFN0cmluZ0J1ZmZlcigiIik7CisgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgIGludCBjID0gaXMucmVhZCgpOworICAgICAgICAgICAgICAgIGlmIChjID09IC0xKQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBtc2cuYXBwZW5kKChjaGFyKSBjKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgICAgICBwcm9jLndhaXRGb3IoKTsKKyAgICAgICAgICAgIC8vU3VwcG9ydF9FeGVjLmNoZWNrU3RkZXJyKGV4ZWNBcmdzKTsKKyAgICAgICAgICAgIHByb2MuZGVzdHJveSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0cnVlIiwgbXNnLnRvU3RyaW5nKCksIG1zZy50b1N0cmluZygpKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gZXhlY3V0aW5nIGF2YWlsIHRlc3Q6ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSW50ZXJydXB0ZWRFeGNlcHRpb24gZXhlY3V0aW5nIGF2YWlsIHRlc3Q6ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5Qcm9jZXNzI2dldE91dHB1dFN0cmVhbSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRPdXRwdXRTdHJlYW0oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmdbXSBjb21tYW5kcyA9IHsgInNsZWVwIiwgIjEifTsKKyAgICAgICAgICAgIFByb2Nlc3MgcHJvYyA9IFJ1bnRpbWUuZ2V0UnVudGltZSgpLmV4ZWMoY29tbWFuZHMsIG51bGwsIG51bGwpOworICAgICAgICAgICAgT3V0cHV0U3RyZWFtIG9zID0gcHJvYy5nZXRPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIC8vIHNlbmQgZGF0YSwgYW5kIGNoZWNrIGlmIGl0IGlzIGVjaG9lZCBiYWNrIGNvcnJlY3RseQorICAgICAgICAgICAgU3RyaW5nIHN0cjEgPSAiU29tZSBkYXRhIGZvciB0ZXN0aW5nIGNvbW11bmljYXRpb24gYmV0d2VlbiBwcm9jZXNzZXNcbiI7CisgICAgICAgICAgICBTdHJpbmcgc3RyMiA9ICJNb3JlIGRhdGEgdGhhdCBzZXJ2ZXMgdGhlIHNhbWUgcHVycG9zZS5cbiI7CisgICAgICAgICAgICBTdHJpbmcgc3RyMyA9ICJIZXJlIGlzIHNvbWUgbW9yZSBkYXRhLlxuIjsKKyAgICAgICAgICAgIG9zLndyaXRlKHN0cjEuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCgyMDAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgb3MuY2xvc2UoKTsKKyAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gcHJvYy5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICAgICAgU3RyaW5nQnVmZmVyIG1zZyA9IG5ldyBTdHJpbmdCdWZmZXIoIiIpOworICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICBpbnQgYyA9IGlzLnJlYWQoKTsKKyAgICAgICAgICAgICAgICBpZiAoYyA9PSAtMSkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgbXNnLmFwcGVuZCgoY2hhcikgYyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICAgICAgcHJvYy53YWl0Rm9yKCk7CisgICAgICAgICAgICAvL1N1cHBvcnRfRXhlYy5jaGVja1N0ZGVycihleGVjQXJncyk7CisgICAgICAgICAgICBwcm9jLmRlc3Ryb3koKTsKKyAgICAgICAgICAgIFN0cmluZyBvcmcgPSBzdHIxOworICAgICAgICAgICAgU3RyaW5nIHJlY3ZkID0gbXNnLnRvU3RyaW5nKCk7CisgICAgICAgICAgICAvLyBEb2Vzbid0IHBhc3Mgb24gUkkKKyAgICAgICAgICAgIC8vIGFzc2VydFRydWUoIkRhdGEgcmV0dXJuZWQgZGlkIG5vdCBtYXRjaCBkYXRhIHNlbnQuIFJlY2VpdmVkOiAnIgorICAgICAgICAgICAgLy8gICAgICAgICsgcmVjdmQgKyAiJyBzZW50OiAnIiArIG9yZyArICInIiwgcmVjdmQuZXF1YWxzKG9yZykpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleGVjdXRpbmcgYXZhaWwgdGVzdDogIiArIGUpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleGVjdXRpbmcgYXZhaWwgdGVzdDogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9leGl0VmFsdWUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmdbXSBjb21tYW5kcyA9IHsgImxzIiB9OworICAgICAgICAgICAgUHJvY2VzcyBwcm9jZXNzID0gUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhjb21tYW5kcywgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCg1MDAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGUpIHsKKworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShwcm9jZXNzLmV4aXRWYWx1ZSgpID09IDApOworCisgICAgICAgICAgICBTdHJpbmdbXSBjb21tYW5kc1NsZWVwID0geyAic2xlZXAiLCAiMyIgfTsKKyAgICAgICAgICAgIHByb2Nlc3MgPSBSdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKGNvbW1hbmRzU2xlZXAsIG51bGwsIG51bGwpOworICAgICAgICAgICAgcHJvY2Vzcy5kZXN0cm95KCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCg1MDAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7fQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShwcm9jZXNzLmV4aXRWYWx1ZSgpICE9IDApOworCisgICAgICAgICAgICBwcm9jZXNzID0gUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhjb21tYW5kc1NsZWVwLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcHJvY2Vzcy5leGl0VmFsdWUoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsVGhyZWFkU3RhdGVFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgICAgICB9IGNhdGNoKElsbGVnYWxUaHJlYWRTdGF0ZUV4Y2VwdGlvbiBpdHNlKSB7CisgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICBQcm9jZXNzQ2xhc3MgcGMgPSBuZXcgUHJvY2Vzc0NsYXNzKCk7CisgICAgICAgIGFzc2VydFRydWUocGMuZXhpdFZhbHVlKCkgPT0gMCk7CisgICAgfQorCisgICAgQEJyb2tlblRlc3QoIlNwb3JhZGljIHRpbWVvdXRzIGluIENUUywgYnV0IG5vdCBpbiBDb3JlVGVzdFJ1bm5lciIpCisgICAgcHVibGljIHZvaWQgdGVzdF9kZXN0cm95KCkgeworICAgICAgICBTdHJpbmdbXSBjb21tYW5kcyA9IHsgImxzIn07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQcm9jZXNzIHByb2Nlc3MgPSBSdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKGNvbW1hbmRzLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgIHByb2Nlc3MuZGVzdHJveSgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgZG9uZVN1aXRlKCkgeworICAgIH0KKworICAgIGNsYXNzIFByb2Nlc3NDbGFzcyBleHRlbmRzIFByb2Nlc3MgeworCisgICAgICAgIFByb2Nlc3NDbGFzcygpIHsKKyAgICAgICAgICAgIHN1cGVyKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgZGVzdHJveSgpIHsKKworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgZXhpdFZhbHVlKCkgeworICAgICAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIElucHV0U3RyZWFtIGdldEVycm9yU3RyZWFtKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHdhaXRGb3IoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL1N0cmluZ1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL1N0cmluZ1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZTk5MzNkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvU3RyaW5nVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLmxhbmc7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIHRoZSBjbGFzcyB7QGxpbmsgU3RyaW5nfS4KKyAqLworcHVibGljIGNsYXNzIFN0cmluZ1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHVibGljIHZvaWQgdGVzdF9jb250YWlucygpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiYWFiYyIuY29udGFpbnMoImFiYyIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiYWJjZCIuY29udGFpbnMoImFiYyIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoImFiY2QiLmNvbnRhaW5zKCJjYmEiKSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RfY2hhckF0KCkgeworICAgICAgICBhc3NlcnRUcnVlKCJhYmNkIi5jaGFyQXQoMCkgPT0gJ2EnKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiYWJjZCIuY2hhckF0KDMpID09ICdkJyk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RfU3RhcnRzV2l0aCgpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiYWJjZCIuc3RhcnRzV2l0aCgiYWJjIikpOworICAgICAgICBhc3NlcnRGYWxzZSgiYWJjZCIuc3RhcnRzV2l0aCgiYWFiYyIpKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdF9FbmRzV2l0aCgpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiYWJjZCIuZW5kc1dpdGgoImJjZCIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoImFiY2QiLmVuZHNXaXRoKCJiY2RlIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ0FTRV9JTlNFTlNJVElWRV9PUkRFUigpIHsKKyAgICAgICAgU3RyaW5nICBzMSA9ICJBQkNERUZHIjsKKyAgICAgICAgU3RyaW5nICBzMiA9ICJhYmNkZWZnIjsKKworICAgICAgICBhc3NlcnRUcnVlKFN0cmluZy5DQVNFX0lOU0VOU0lUSVZFX09SREVSLmNvbXBhcmUoczEsIHMyKSA9PSAwKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWYvUGhhbnRvbVJlZmVyZW5jZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZi9QaGFudG9tUmVmZXJlbmNlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA2MjIxYzkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWYvUGhhbnRvbVJlZmVyZW5jZVRlc3QuamF2YQpAQCAtMCwwICsxLDE0MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS5sYW5nLnJlZjsKKworaW1wb3J0IGphdmEubGFuZy5yZWYuUGhhbnRvbVJlZmVyZW5jZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmLlJlZmVyZW5jZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmLlJlZmVyZW5jZVF1ZXVlOworCisvL1RPRE86IHdyaXRlIGEgdGVzdCB0byB2ZXJpZnkgdGhhdCB0aGUgcmVmZXJlbnQncyBmaW5hbGl6ZSgpIGhhcHBlbnMKKy8vICAgICAgYmVmb3JlIHRoZSBQaGFudG9tUmVmZXJlbmNlIGlzIGVucXVldWVkLgorCitwdWJsaWMgY2xhc3MgUGhhbnRvbVJlZmVyZW5jZVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIHN0YXRpYyBCb29sZWFuIGJvb2w7CisgICAgcHVibGljIGJvb2xlYW4gaXNDYWxsZWQgPSBmYWxzZTsKKyAgICBwcm90ZWN0ZWQgdm9pZCBkb25lU3VpdGUoKSB7CisgICAgICAgIGJvb2wgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWYuUGhhbnRvbVJlZmVyZW5jZSNnZXQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0KCkgeworICAgICAgICBSZWZlcmVuY2VRdWV1ZSBycSA9IG5ldyBSZWZlcmVuY2VRdWV1ZSgpOworICAgICAgICBib29sID0gbmV3IEJvb2xlYW4oZmFsc2UpOworICAgICAgICBQaGFudG9tUmVmZXJlbmNlIHByID0gbmV3IFBoYW50b21SZWZlcmVuY2UoYm9vbCwgcnEpOworICAgICAgICBhc3NlcnROdWxsKCJnZXQoKSBzaG91bGQgcmV0dXJuIG51bGwuIiwgcHIuZ2V0KCkpOworICAgICAgICBwci5lbnF1ZXVlKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldCgpIHNob3VsZCByZXR1cm4gbnVsbC4iLCBwci5nZXQoKSk7CisgICAgICAgIHByLmNsZWFyKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldCgpIHNob3VsZCByZXR1cm4gbnVsbC4iLCBwci5nZXQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLlJ1bnRpbWUjZ2MoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2NJbnRlcmFjdGlvbigpIHsKKyAgICAgICAgY2xhc3MgVGVzdFBoYW50b21SZWZlcmVuY2U8VD4gZXh0ZW5kcyBQaGFudG9tUmVmZXJlbmNlPFQ+IHsKKyAgICAgICAgICAgIHB1YmxpYyBUZXN0UGhhbnRvbVJlZmVyZW5jZShUIHJlZmVyZW50LAorICAgICAgICAgICAgICAgICAgICBSZWZlcmVuY2VRdWV1ZTw/IHN1cGVyIFQ+IHEpIHsKKyAgICAgICAgICAgICAgICBzdXBlcihyZWZlcmVudCwgcSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBlbnF1ZXVlKCkgeworICAgICAgICAgICAgICAgIC8vIEluaXRpYXRlIGFub3RoZXIgR0MgZnJvbSBpbnNpZGUgZW5xdWV1ZSgpIHRvCisgICAgICAgICAgICAgICAgLy8gc2VlIGlmIGl0IGNhdXNlcyBhbnkgcHJvYmxlbXMgaW5zaWRlIHRoZSBWTS4KKyAgICAgICAgICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5nYygpOworICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5lbnF1ZXVlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBSZWZlcmVuY2VRdWV1ZSBycSA9IG5ldyBSZWZlcmVuY2VRdWV1ZSgpOworICAgICAgICBmaW5hbCBQaGFudG9tUmVmZXJlbmNlW10gdHBycyA9IG5ldyBQaGFudG9tUmVmZXJlbmNlWzRdOworCisgICAgICAgIGNsYXNzIFRlc3RUaHJlYWQgZXh0ZW5kcyBUaHJlYWQgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgb2JqZWN0IGluIGEgc2VwYXJhdGUgdGhyZWFkIHRvIGVuc3VyZQorICAgICAgICAgICAgICAgIC8vIGl0IHdpbGwgYmUgZ2MnZWQuCisgICAgICAgICAgICAgICAgT2JqZWN0IG9iaiA9IG5ldyBPYmplY3QoKTsKKyAgICAgICAgICAgICAgICB0cHJzWzBdID0gbmV3IFRlc3RQaGFudG9tUmVmZXJlbmNlKG9iaiwgcnEpOworICAgICAgICAgICAgICAgIHRwcnNbMV0gPSBuZXcgVGVzdFBoYW50b21SZWZlcmVuY2Uob2JqLCBycSk7CisgICAgICAgICAgICAgICAgdHByc1syXSA9IG5ldyBUZXN0UGhhbnRvbVJlZmVyZW5jZShvYmosIHJxKTsKKyAgICAgICAgICAgICAgICB0cHJzWzNdID0gbmV3IFRlc3RQaGFudG9tUmVmZXJlbmNlKG9iaiwgcnEpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRocmVhZCB0ID0gbmV3IFRlc3RUaHJlYWQoKTsKKyAgICAgICAgICAgIHQuc3RhcnQoKTsKKyAgICAgICAgICAgIHQuam9pbigpOworICAgICAgICAgICAgU3lzdGVtLmdjKCk7CisgICAgICAgICAgICBTeXN0ZW0ucnVuRmluYWxpemF0aW9uKCk7CisKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldCgpIHNob3VsZCByZXR1cm4gbnVsbC4iLCB0cHJzWzBdLmdldCgpKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldCgpIHNob3VsZCByZXR1cm4gbnVsbC4iLCB0cHJzWzFdLmdldCgpKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldCgpIHNob3VsZCByZXR1cm4gbnVsbC4iLCB0cHJzWzJdLmdldCgpKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldCgpIHNob3VsZCByZXR1cm4gbnVsbC4iLCB0cHJzWzNdLmdldCgpKTsKKworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA0OyBpKyspIHsKKyAgICAgICAgICAgICAgICBSZWZlcmVuY2UgciA9IHJxLnJlbW92ZSgxMDBMKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJSZWZlcmVuY2Ugc2hvdWxkIGhhdmUgYmVlbiBlbnF1ZXVlZC4iLCByKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gVGhlc2UgYXJlIHRvIG1ha2Ugc3VyZSB0aGF0IHRwcnMgYW5kIGl0cyBlbGVtZW50cyBkb24ndCBnZXQKKyAgICAgICAgICAgIC8vIG9wdGltaXplZCBvdXQuCisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXQoKSBzaG91bGQgcmV0dXJuIG51bGwuIiwgdHByc1swXS5nZXQoKSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXQoKSBzaG91bGQgcmV0dXJuIG51bGwuIiwgdHByc1sxXS5nZXQoKSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXQoKSBzaG91bGQgcmV0dXJuIG51bGwuIiwgdHByc1syXS5nZXQoKSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXQoKSBzaG91bGQgcmV0dXJuIG51bGwuIiwgdHByc1szXS5nZXQoKSk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkludGVycnVwdGVkRXhjZXB0aW9uIDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWYuUGhhbnRvbVJlZmVyZW5jZSNQaGFudG9tUmVmZXJlbmNlKGphdmEubGFuZy5PYmplY3QsCisgICAgICogICAgICAgIGphdmEubGFuZy5yZWYuUmVmZXJlbmNlUXVldWUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfT2JqZWN0TGphdmFfbGFuZ19yZWZfUmVmZXJlbmNlUXVldWUoKSB7CisgICAgICAgIFJlZmVyZW5jZVF1ZXVlIHJxID0gbmV3IFJlZmVyZW5jZVF1ZXVlKCk7CisgICAgICAgIGJvb2wgPSBuZXcgQm9vbGVhbih0cnVlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFBoYW50b21SZWZlcmVuY2UgcHIgPSBuZXcgUGhhbnRvbVJlZmVyZW5jZShib29sLCBycSk7CisgICAgICAgICAgICAvLyBBbGxvdyB0aGUgZmluYWxpemVyIHRvIHJ1biB0byBwb3RlbnRpYWxseSBlbnF1ZXVlCisgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbml0aWFsaXphdGlvbiBmYWlsZWQuIiwgIXByLmlzRW5xdWV1ZWQoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIC8vIG5lZWQgYSByZWZlcmVuY2UgdG8gYm9vbCBzbyB0aGUgaml0IGRvZXMgbm90IG9wdGltaXplIGl0IGF3YXkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgic2hvdWxkIGFsd2F5cyBwYXNzIiwgYm9vbC5ib29sZWFuVmFsdWUoKSk7CisKKyAgICAgICAgYm9vbGVhbiBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBQaGFudG9tUmVmZXJlbmNlKGJvb2wsIG51bGwpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBub3QgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iLCAhZXhjZXB0aW9uKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWYvUmVmZXJlbmNlUXVldWVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWYvUmVmZXJlbmNlUXVldWVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGM3ZTczOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZi9SZWZlcmVuY2VRdWV1ZVRlc3QuamF2YQpAQCAtMCwwICsxLDI1MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS5sYW5nLnJlZjsKKworaW1wb3J0IGphdmEubGFuZy5yZWYuUGhhbnRvbVJlZmVyZW5jZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmLlJlZmVyZW5jZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmLlJlZmVyZW5jZVF1ZXVlOworaW1wb3J0IGphdmEubGFuZy5yZWYuU29mdFJlZmVyZW5jZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmLldlYWtSZWZlcmVuY2U7CisKK3B1YmxpYyBjbGFzcyBSZWZlcmVuY2VRdWV1ZVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIHN0YXRpYyBCb29sZWFuIGI7CisKKyAgICBzdGF0aWMgSW50ZWdlciBpbnRlZ2VyOworICAgIGJvb2xlYW4gaXNUaHJvd24gPSBmYWxzZTsKKworICAgIHByb3RlY3RlZCB2b2lkIGRvbmVTdWl0ZSgpIHsKKyAgICAgICAgYiA9IG51bGw7CisgICAgICAgIGludGVnZXIgPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBDaGlsZFRocmVhZCBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKyAgICAgICAgcHVibGljIENoaWxkVGhyZWFkKCkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBycS53YWl0KDEwMDApOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAocnEpIHsKKyAgICAgICAgICAgICAgICAvLyBzdG9yZSBpbiBhIHN0YXRpYyBzbyBpdCB3b24ndCBiZSBnYydlZCBiZWNhdXNlIHRoZSBqaXQKKyAgICAgICAgICAgICAgICAvLyBvcHRpbWl6ZWQgaXQgb3V0CisgICAgICAgICAgICAgICAgaW50ZWdlciA9IG5ldyBJbnRlZ2VyKDY2Nyk7CisgICAgICAgICAgICAgICAgU29mdFJlZmVyZW5jZSBzciA9IG5ldyBTb2Z0UmVmZXJlbmNlKGludGVnZXIsIHJxKTsKKyAgICAgICAgICAgICAgICBzci5lbnF1ZXVlKCk7CisgICAgICAgICAgICAgICAgcnEubm90aWZ5KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBSZWZlcmVuY2VRdWV1ZSBycTsKKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWYuUmVmZXJlbmNlUXVldWUjcG9sbCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wb2xsKCkgeworICAgICAgICAvLyBzdG9yZSBpbiBhIHN0YXRpYyBzbyBpdCB3b24ndCBiZSBnYydlZCBiZWNhdXNlIHRoZSBqaXQKKyAgICAgICAgLy8gb3B0aW1pemVkIGl0IG91dAorICAgICAgICBiID0gbmV3IEJvb2xlYW4odHJ1ZSk7CisgICAgICAgIE9iamVjdCBvYmogPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIFN0cmluZyBzdHIgPSAiVGVzdCI7CisKKyAgICAgICAgU29mdFJlZmVyZW5jZSBzciA9IG5ldyBTb2Z0UmVmZXJlbmNlKGIsIHJxKTsKKyAgICAgICAgV2Vha1JlZmVyZW5jZSB3ciA9IG5ldyBXZWFrUmVmZXJlbmNlKG9iaiwgcnEpOworICAgICAgICBQaGFudG9tUmVmZXJlbmNlIHByID0gbmV3IFBoYW50b21SZWZlcmVuY2Uoc3RyLCBycSk7CisgICAgICAgIGFzc2VydE51bGwocnEucG9sbCgpKTsKKyAgICAgICAgc3IuZW5xdWV1ZSgpOworICAgICAgICB3ci5lbnF1ZXVlKCk7CisgICAgICAgIHByLmVucXVldWUoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiUmVtb3ZlIGZhaWxlZC4iLCBycS5wb2xsKCkuZ2V0KCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyB0aGUgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZW1vdmUgZmFpbGVkLiIsIG9iaiwgKHJxLnBvbGwoKS5nZXQoKSkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyB0aGUgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmVtb3ZlIGZhaWxlZC4iLCAoKEJvb2xlYW4pIHJxLnBvbGwoKS5nZXQoKSkKKyAgICAgICAgICAgICAgICAgICAgLmJvb2xlYW5WYWx1ZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgdGhlIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE51bGwocnEucG9sbCgpKTsKKworICAgICAgICBzci5lbnF1ZXVlKCk7CisgICAgICAgIHdyLmVucXVldWUoKTsKKworICAgICAgICBTeXN0ZW0uZ2MoKTsKKyAgICAgICAgU3lzdGVtLnJ1bkZpbmFsaXphdGlvbigpOworCisgICAgICAgIGFzc2VydE51bGwocnEucG9sbCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmLlJlZmVyZW5jZVF1ZXVlI3JlbW92ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZW1vdmUoKSB7CisgICAgICAgIC8vIHN0b3JlIGluIGEgc3RhdGljIHNvIGl0IHdvbid0IGJlIGdjJ2VkIGJlY2F1c2UgdGhlIGppdAorICAgICAgICAvLyBvcHRpbWl6ZWQgaXQgb3V0CisgICAgICAgIGIgPSBuZXcgQm9vbGVhbih0cnVlKTsKKworICAgICAgICBTb2Z0UmVmZXJlbmNlIHNyID0gbmV3IFNvZnRSZWZlcmVuY2UoYiwgcnEpOworICAgICAgICBzci5lbnF1ZXVlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZW1vdmUgZmFpbGVkLiIsICgoQm9vbGVhbikgcnEucmVtb3ZlKCkuZ2V0KCkpCisgICAgICAgICAgICAgICAgICAgIC5ib29sZWFuVmFsdWUoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHRoZSB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydE51bGwocnEucG9sbCgpKTsKKworICAgICAgICBzci5lbnF1ZXVlKCk7CisKKyAgICAgICAgY2xhc3MgUmVtb3ZlVGhyZWFkIGV4dGVuZHMgVGhyZWFkIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBycS5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoKEludGVycnVwdGVkRXhjZXB0aW9uIGllKSB7CisgICAgICAgICAgICAgICAgICAgIGlzVGhyb3duID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgUmVtb3ZlVGhyZWFkIHJ0ID0gbmV3IFJlbW92ZVRocmVhZCgpOworICAgICAgICBydC5zdGFydCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMCk7CisgICAgICAgIH0gY2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gaWUpIHsKKworICAgICAgICB9CisgICAgICAgIHJ0LmludGVycnVwdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMCk7CisgICAgICAgIH0gY2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gaWUpIHsKKworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoaXNUaHJvd24pOworICAgICAgICBhc3NlcnROdWxsKHJxLnBvbGwoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZi5SZWZlcmVuY2VRdWV1ZSNyZW1vdmUobG9uZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlbW92ZUooKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJRdWV1ZSBzaG91bGQgYmUgZW1wdHkuIChwb2xsKSIsIHJxLnBvbGwoKSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJRdWV1ZSBzaG91bGQgYmUgZW1wdHkuIChyZW1vdmUoMSkpIiwKKyAgICAgICAgICAgICAgICAgICAgcnEucmVtb3ZlKChsb25nKSAxKSk7CisgICAgICAgICAgICBUaHJlYWQgY3QgPSBuZXcgVGhyZWFkKG5ldyBDaGlsZFRocmVhZCgpKTsKKyAgICAgICAgICAgIGN0LnN0YXJ0KCk7CisgICAgICAgICAgICBSZWZlcmVuY2UgcmV0ID0gcnEucmVtb3ZlKDBMKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIkRlbGF5ZWQgcmVtb3ZlIGZhaWxlZC4iLCByZXQpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJbnRlcnJ1cHRlZEV4ZUV4Y2VwdGlvbiBkdXJpbmcgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgT2JqZWN0IG9iaiA9IG5ldyBPYmplY3QoKTsKKyAgICAgICAgV2Vha1JlZmVyZW5jZSB3ciA9IG5ldyBXZWFrUmVmZXJlbmNlKG9iaiwgcnEpOworICAgICAgICBCb29sZWFuIGIgPSBuZXcgQm9vbGVhbih0cnVlKTsKKyAgICAgICAgU29mdFJlZmVyZW5jZSBzciA9IG5ldyBTb2Z0UmVmZXJlbmNlKGIsIHJxKTsKKyAgICAgICAgU3RyaW5nIHN0ciA9ICJUZXN0IjsKKyAgICAgICAgUGhhbnRvbVJlZmVyZW5jZSBwciA9IG5ldyBQaGFudG9tUmVmZXJlbmNlKHN0ciwgcnEpOworCisgICAgICAgIHByLmVucXVldWUoKTsKKyAgICAgICAgd3IuZW5xdWV1ZSgpOworICAgICAgICBzci5lbnF1ZXVlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJlZmVyZW5jZSByZXN1bHQgPSBycS5yZW1vdmUoMUwpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgoQm9vbGVhbilyZXN1bHQuZ2V0KCkpOworICAgICAgICAgICAgcmVzdWx0ID0gcnEucmVtb3ZlKDFMKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhvYmosIHJlc3VsdC5nZXQoKSk7CisgICAgICAgICAgICByZXN1bHQgPSBycS5yZW1vdmUoMUwpOworICAgICAgICAgICAgYXNzZXJ0TnVsbChyZXN1bHQuZ2V0KCkpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZTEpIHsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlMSkgeworICAgICAgICAgICAgZmFpbCgiSW50ZXJydXB0ZWRFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBycSA9IG5ldyBSZWZlcmVuY2VRdWV1ZSgpOworICAgICAgICBpc1Rocm93biA9IGZhbHNlOworICAgICAgICBhc3NlcnROdWxsKHJxLnBvbGwoKSk7CisKKyAgICAgICAgY2xhc3MgUmVtb3ZlVGhyZWFkIGV4dGVuZHMgVGhyZWFkIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBycS5yZW1vdmUoMTAwMEwpOworICAgICAgICAgICAgICAgIH0gY2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gaWUpIHsKKyAgICAgICAgICAgICAgICAgICAgaXNUaHJvd24gPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBSZW1vdmVUaHJlYWQgcnQgPSBuZXcgUmVtb3ZlVGhyZWFkKCk7CisgICAgICAgIHJ0LnN0YXJ0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTApOworICAgICAgICB9IGNhdGNoKEludGVycnVwdGVkRXhjZXB0aW9uIGllKSB7CisKKyAgICAgICAgfQorICAgICAgICBydC5pbnRlcnJ1cHQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxMCk7CisgICAgICAgIH0gY2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gaWUpIHsKKworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoaXNUaHJvd24pOworICAgICAgICBhc3NlcnROdWxsKHJxLnBvbGwoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJxLnJlbW92ZSgtMSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQuIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIEludGVycnVwdGVkRXhjZXB0aW9uLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZi5SZWZlcmVuY2VRdWV1ZSNSZWZlcmVuY2VRdWV1ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgUmVmZXJlbmNlUXVldWUgcnEgPSBuZXcgUmVmZXJlbmNlUXVldWUoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChycS5wb2xsKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcnEucmVtb3ZlKDEwMEwpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIHJxID0gbmV3IFJlZmVyZW5jZVF1ZXVlKCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvcmVmL1JlZmVyZW5jZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZi9SZWZlcmVuY2VUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTFhN2E4YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZi9SZWZlcmVuY2VUZXN0LmphdmEKQEAgLTAsMCArMSwzNDQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLmxhbmcucmVmOworCitpbXBvcnQgamF2YS5sYW5nLnJlZi5QaGFudG9tUmVmZXJlbmNlOworaW1wb3J0IGphdmEubGFuZy5yZWYuUmVmZXJlbmNlOworaW1wb3J0IGphdmEubGFuZy5yZWYuUmVmZXJlbmNlUXVldWU7CitpbXBvcnQgamF2YS5sYW5nLnJlZi5Tb2Z0UmVmZXJlbmNlOworaW1wb3J0IGphdmEubGFuZy5yZWYuV2Vha1JlZmVyZW5jZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0aW9uRmFpbGVkRXJyb3I7CisKK3B1YmxpYyBjbGFzcyBSZWZlcmVuY2VUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICBPYmplY3QgdG1wQSwgdG1wQiwgdG1wQywgb2JqOworCisgICAgdm9sYXRpbGUgUmVmZXJlbmNlIHI7CisKKyAgICAvKgorICAgICAqIEZvciB0ZXN0X3N1YmNsYXNzKCkuCisgICAgICovCisgICAgc3RhdGljIFRlc3RXZWFrUmVmZXJlbmNlIHR3cjsKKyAgICBzdGF0aWMgQXNzZXJ0aW9uRmFpbGVkRXJyb3IgZXJyb3I7CisgICAgc3RhdGljIGJvb2xlYW4gdGVzdE9iamVjdEZpbmFsaXplZDsKKyAgICBzdGF0aWMgY2xhc3MgVGVzdFdlYWtSZWZlcmVuY2U8VD4gZXh0ZW5kcyBXZWFrUmVmZXJlbmNlPFQ+IHsKKyAgICAgICAgcHVibGljIHZvbGF0aWxlIGJvb2xlYW4gY2xlYXJTZWVuID0gZmFsc2U7CisgICAgICAgIHB1YmxpYyB2b2xhdGlsZSBib29sZWFuIGVucXVldWVTZWVuID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIFRlc3RXZWFrUmVmZXJlbmNlKFQgcmVmZXJlbnQpIHsKKyAgICAgICAgICAgIHN1cGVyKHJlZmVyZW50KTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBUZXN0V2Vha1JlZmVyZW5jZShUIHJlZmVyZW50LCBSZWZlcmVuY2VRdWV1ZTw/IHN1cGVyIFQ+IHEpIHsKKyAgICAgICAgICAgIHN1cGVyKHJlZmVyZW50LCBxKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICAgICAgY2xlYXJTZWVuID0gdHJ1ZTsKKyAgICAgICAgICAgIGlmICh0ZXN0T2JqZWN0RmluYWxpemVkKSB7CisgICAgICAgICAgICAgICAgZXJyb3IgPSBuZXcgQXNzZXJ0aW9uRmFpbGVkRXJyb3IoIkNsZWFyIHNob3VsZCBoYXBwZW4gIiArCisgICAgICAgICAgICAgICAgICAgICAgICAiYmVmb3JlIGZpbmFsaXphdGlvbi4iKTsKKyAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChlbnF1ZXVlU2VlbikgeworICAgICAgICAgICAgICAgIGVycm9yID0gbmV3IEFzc2VydGlvbkZhaWxlZEVycm9yKCJDbGVhciBzaG91bGQgaGFwcGVuICIgKworICAgICAgICAgICAgICAgICAgICAgICAgImJlZm9yZSBlbnF1ZXVlLiIpOworICAgICAgICAgICAgICAgIHRocm93IGVycm9yOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc3VwZXIuY2xlYXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGVucXVldWUoKSB7CisgICAgICAgICAgICBlbnF1ZXVlU2VlbiA9IHRydWU7CisgICAgICAgICAgICBpZiAoIWNsZWFyU2VlbikgeworICAgICAgICAgICAgICAgIGVycm9yID0gbmV3IEFzc2VydGlvbkZhaWxlZEVycm9yKCJDbGVhciBzaG91bGQgaGFwcGVuICIgKworICAgICAgICAgICAgICAgICAgICAgICAgImJlZm9yZSBlbnF1ZXVlLiIpOworICAgICAgICAgICAgICAgIHRocm93IGVycm9yOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvKiBEbyB0aGlzIGxhc3Q7ICBpdCBtYXkgbm90aWZ5IHRoZSBtYWluIHRlc3QgdGhyZWFkLAorICAgICAgICAgICAgICogYW5kIGFueXRoaW5nIHdlJ2QgZG8gYWZ0ZXIgaXQgKGUuZy4sIHNldHRpbmcgY2xlYXJTZWVuKQorICAgICAgICAgICAgICogd291bGRuJ3QgYmUgc2Vlbi4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVucXVldWUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGRvbmVTdWl0ZSgpIHsKKyAgICAgICAgdG1wQSA9IHRtcEIgPSBvYmogPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWYuUmVmZXJlbmNlI2NsZWFyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NsZWFyKCkgeworICAgICAgICB0bXBBID0gbmV3IE9iamVjdCgpOworICAgICAgICB0bXBCID0gbmV3IE9iamVjdCgpOworICAgICAgICB0bXBDID0gbmV3IE9iamVjdCgpOworICAgICAgICBTb2Z0UmVmZXJlbmNlIHNyID0gbmV3IFNvZnRSZWZlcmVuY2UodG1wQSwgbmV3IFJlZmVyZW5jZVF1ZXVlKCkpOworICAgICAgICBXZWFrUmVmZXJlbmNlIHdyID0gbmV3IFdlYWtSZWZlcmVuY2UodG1wQiwgbmV3IFJlZmVyZW5jZVF1ZXVlKCkpOworICAgICAgICBQaGFudG9tUmVmZXJlbmNlIHByID0gbmV3IFBoYW50b21SZWZlcmVuY2UodG1wQywgbmV3IFJlZmVyZW5jZVF1ZXVlKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJTdGFydDogT2JqZWN0IG5vdCBjbGVhcmVkLiIsIChzci5nZXQoKSAhPSBudWxsKQorICAgICAgICAgICAgICAgICYmICh3ci5nZXQoKSAhPSBudWxsKSk7CisgICAgICAgIGFzc2VydE51bGwoIlJlZmVyZW50IGlzIG5vdCBudWxsLiIsIHByLmdldCgpKTsKKyAgICAgICAgc3IuY2xlYXIoKTsKKyAgICAgICAgd3IuY2xlYXIoKTsKKyAgICAgICAgcHIuY2xlYXIoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRW5kOiBPYmplY3QgY2xlYXJlZC4iLCAoc3IuZ2V0KCkgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAmJiAod3IuZ2V0KCkgPT0gbnVsbCkpOworICAgICAgICBhc3NlcnROdWxsKCJSZWZlcmVudCBpcyBub3QgbnVsbC4iLCBwci5nZXQoKSk7CisgICAgICAgIC8vIE11c3QgcmVmZXJlbmNlIHRtcEEgYW5kIHRtcEIgc28gdGhlIGppdCBkb2VzIG5vdCBvcHRpbWl6ZSB0aGVtIGF3YXkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgic2hvdWxkIGFsd2F5cyBwYXNzIiwgdG1wQSAhPSBzci5nZXQoKSAmJiB0bXBCICE9IHdyLmdldCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmLlJlZmVyZW5jZSNlbnF1ZXVlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VucXVldWUoKSB7CisgICAgICAgIFJlZmVyZW5jZVF1ZXVlIHJxID0gbmV3IFJlZmVyZW5jZVF1ZXVlKCk7CisgICAgICAgIG9iaiA9IG5ldyBPYmplY3QoKTsKKyAgICAgICAgUmVmZXJlbmNlIHJlZiA9IG5ldyBTb2Z0UmVmZXJlbmNlKG9iaiwgcnEpOworICAgICAgICBhc3NlcnRUcnVlKCJFbnF1ZXVlIGZhaWxlZC4iLCAoIXJlZi5pc0VucXVldWVkKCkpCisgICAgICAgICAgICAgICAgJiYgKChyZWYuZW5xdWV1ZSgpKSAmJiAocmVmLmlzRW5xdWV1ZWQoKSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTm90IHByb3Blcmx5IGVucXVldWVkLiIsIHJxLnBvbGwoKS5nZXQoKSA9PSBvYmopOworICAgICAgICAvLyBUaGlzIGZhaWxzLi4uCisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCByZW1haW4gZW5xdWV1ZWQuIiwgIXJlZi5pc0VucXVldWVkKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJDYW4gbm90IGVucXVldWUgdHdpY2UuIiwgKCFyZWYuZW5xdWV1ZSgpKQorICAgICAgICAgICAgICAgICYmIChycS5wb2xsKCkgPT0gbnVsbCkpOworCisgICAgICAgIHJxID0gbmV3IFJlZmVyZW5jZVF1ZXVlKCk7CisgICAgICAgIG9iaiA9IG5ldyBPYmplY3QoKTsKKworICAgICAgICByZWYgPSBuZXcgV2Vha1JlZmVyZW5jZShvYmosIHJxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRW5xdWV1ZSBmYWlsZWQyLiIsICghcmVmLmlzRW5xdWV1ZWQoKSkKKyAgICAgICAgICAgICAgICAmJiAoKHJlZi5lbnF1ZXVlKCkpICYmIChyZWYuaXNFbnF1ZXVlZCgpKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJOb3QgcHJvcGVybHkgZW5xdWV1ZWQyLiIsIHJxLnBvbGwoKS5nZXQoKSA9PSBvYmopOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmVtYWluIGVucXVldWVkMi4iLCAhcmVmLmlzRW5xdWV1ZWQoKSk7IC8vIFRoaXMKKyAgICAgICAgLy8gZmFpbHMuCisgICAgICAgIGFzc2VydFRydWUoIkNhbiBub3QgZW5xdWV1ZSB0d2ljZTIuIiwgKCFyZWYuZW5xdWV1ZSgpKQorICAgICAgICAgICAgICAgICYmIChycS5wb2xsKCkgPT0gbnVsbCkpOworCisgICAgICAgIHJlZiA9IG5ldyBQaGFudG9tUmVmZXJlbmNlKG9iaiwgcnEpOworICAgICAgICBhc3NlcnRUcnVlKCJFbnF1ZXVlIGZhaWxlZDMuIiwgKCFyZWYuaXNFbnF1ZXVlZCgpKQorICAgICAgICAgICAgICAgICYmICgocmVmLmVucXVldWUoKSkgJiYgKHJlZi5pc0VucXVldWVkKCkpKSk7CisgICAgICAgIGFzc2VydE51bGwoIk5vdCBwcm9wZXJseSBlbnF1ZXVlZDMuIiwgcnEucG9sbCgpLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJlbWFpbiBlbnF1ZXVlZDMuIiwgIXJlZi5pc0VucXVldWVkKCkpOyAvLyBUaGlzCisgICAgICAgIC8vIGZhaWxzLgorICAgICAgICBhc3NlcnRUcnVlKCJDYW4gbm90IGVucXVldWUgdHdpY2UzLiIsICghcmVmLmVucXVldWUoKSkKKyAgICAgICAgICAgICAgICAmJiAocnEucG9sbCgpID09IG51bGwpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldF9XZWFrUmVmZXJlbmNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgdGhlIGdlbmVyYWwvb3ZlcmFsbCBmdW5jdGlvbmFsaXR5IG9mIFJlZmVyZW5jZS4KKyAgICAgICAgUmVmZXJlbmNlUXVldWU8T2JqZWN0PiBxdWV1ZSA9IG5ldyBSZWZlcmVuY2VRdWV1ZTxPYmplY3Q+KCk7CisKKyAgICAgICAgciA9IG5ld1dlYWtSZWZlcmVuY2UocXVldWUpOworICAgICAgICBTeXN0ZW0uZ2MoKTsKKyAgICAgICAgU3lzdGVtLnJ1bkZpbmFsaXphdGlvbigpOworICAgICAgICBSZWZlcmVuY2UgcmVmID0gcXVldWUucmVtb3ZlKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIk9iamVjdCBub3QgZW5xdWV1ZWQuIiwgcmVmKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiVW5leHBlY3RlZCByZWYxIiwgcmVmLCByKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiT2JqZWN0IGNvdWxkIG5vdCBiZSByZWNsYWltZWQxLiIsIHIuZ2V0KCkpOworCisgICAgICAgIHIgPSBuZXdXZWFrUmVmZXJlbmNlKHF1ZXVlKTsKKyAgICAgICAgU3lzdGVtLmdjKCk7CisgICAgICAgIFN5c3RlbS5ydW5GaW5hbGl6YXRpb24oKTsKKworICAgICAgICAvLyB3YWl0IGZvciB0aGUgcmVmZXJlbmNlIHF1ZXVlIHRocmVhZCB0byBlbnF1ZXVlIHRoZSBuZXdseS1maW5hbGl6ZWQgb2JqZWN0CisgICAgICAgIFRocmVhZC55aWVsZCgpOworICAgICAgICBUaHJlYWQuc2xlZXAoMjAwKTsKKworICAgICAgICByZWYgPSBxdWV1ZS5wb2xsKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIk9iamVjdCBub3QgZW5xdWV1ZWQuIiwgcmVmKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiVW5leHBlY3RlZCByZWYyIiwgcmVmLCByKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiT2JqZWN0IGNvdWxkIG5vdCBiZSByZWNsYWltZWQuIiwgcmVmLmdldCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiT2JqZWN0IGNvdWxkIG5vdCBiZSByZWNsYWltZWQuIiwgci5nZXQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFrZXMgc3VyZSB0aGF0IG92ZXJyaWRkZW4gdmVyc2lvbnMgb2YgY2xlYXIoKSBhbmQgZW5xdWV1ZSgpCisgICAgICogZ2V0IGNhbGxlZCwgYW5kIHRoYXQgY2xlYXIvZW5xdWV1ZS9maW5hbGl6ZSBoYXBwZW4gaW4gdGhlCisgICAgICogcmlnaHQgb3JkZXIgZm9yIFdlYWtSZWZlcmVuY2VzLgorICAgICAqCisgICAgICogamF2YS5sYW5nLnJlZi5SZWZlcmVuY2UjY2xlYXIoKQorICAgICAqIGphdmEubGFuZy5yZWYuUmVmZXJlbmNlI2VucXVldWUoKQorICAgICAqIGphdmEubGFuZy5PYmplY3QjZmluYWxpemUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3ViY2xhc3MoKSB7CisgICAgICAgIGVycm9yID0gbnVsbDsKKyAgICAgICAgdGVzdE9iamVjdEZpbmFsaXplZCA9IGZhbHNlOworICAgICAgICB0d3IgPSBudWxsOworCisgICAgICAgIGNsYXNzIFRlc3RPYmplY3QgeworICAgICAgICAgICAgcHVibGljIFRlc3RXZWFrUmVmZXJlbmNlIHRlc3RXZWFrUmVmZXJlbmNlID0gbnVsbDsKKworICAgICAgICAgICAgcHVibGljIHZvaWQgc2V0VGVzdFdlYWtSZWZlcmVuY2UoVGVzdFdlYWtSZWZlcmVuY2UgdHdyKSB7CisgICAgICAgICAgICAgICAgdGVzdFdlYWtSZWZlcmVuY2UgPSB0d3I7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgeworICAgICAgICAgICAgICAgIHRlc3RPYmplY3RGaW5hbGl6ZWQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZmluYWwgUmVmZXJlbmNlUXVldWUgcnEgPSBuZXcgUmVmZXJlbmNlUXVldWUoKTsKKworICAgICAgICBjbGFzcyBUZXN0VGhyZWFkIGV4dGVuZHMgVGhyZWFkIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICAvLyBDcmVhdGUgdGhlIG9iamVjdCBpbiBhIHNlcGFyYXRlIHRocmVhZCB0byBlbnN1cmUgaXQgd2lsbCBiZQorICAgICAgICAgICAgICAgIC8vIGdjJ2VkCisgICAgICAgICAgICAgICAgVGVzdE9iamVjdCB0ZXN0T2JqID0gbmV3IFRlc3RPYmplY3QoKTsKKyAgICAgICAgICAgICAgICB0d3IgPSBuZXcgVGVzdFdlYWtSZWZlcmVuY2UodGVzdE9iaiwgcnEpOworICAgICAgICAgICAgICAgIHRlc3RPYmouc2V0VGVzdFdlYWtSZWZlcmVuY2UodHdyKTsKKyAgICAgICAgICAgICAgICB0ZXN0T2JqID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFJlZmVyZW5jZSByZWY7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRocmVhZCB0ID0gbmV3IFRlc3RUaHJlYWQoKTsKKyAgICAgICAgICAgIHQuc3RhcnQoKTsKKyAgICAgICAgICAgIHQuam9pbigpOworICAgICAgICAgICAgU3lzdGVtLmdjKCk7CisgICAgICAgICAgICBTeXN0ZW0ucnVuRmluYWxpemF0aW9uKCk7CisgICAgICAgICAgICByZWYgPSBycS5yZW1vdmUoNTAwMEwpOyAgICAvLyBHaXZlIHVwIGFmdGVyIGZpdmUgc2Vjb25kcy4KKworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiT2JqZWN0IG5vdCBnYXJiYWdlIGNvbGxlY3RlZC4iLCByZWYpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVW5leHBlY3RlZCByZWZlcmVuY2UuIiwgcmVmID09IHR3cik7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJPYmplY3QgY291bGQgbm90IGJlIHJlY2xhaW1lZC4iLCB0d3IuZ2V0KCkpOworICAgICAgICAgICAgLy9hc3NlcnRUcnVlKCJPdmVycmlkZGVuIGNsZWFyKCkgc2hvdWxkIGhhdmUgYmVlbiBjYWxsZWQuIiwKKyAgICAgICAgICAgIC8vICAgICAgIHR3ci5jbGVhclNlZW4pOworICAgICAgICAgICAgLy9hc3NlcnRUcnVlKCJPdmVycmlkZGVuIGVucXVldWUoKSBzaG91bGQgaGF2ZSBiZWVuIGNhbGxlZC4iLAorICAgICAgICAgICAgLy8gICAgICAgIHR3ci5lbnF1ZXVlU2Vlbik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJmaW5hbGl6ZSgpIHNob3VsZCBoYXZlIGJlZW4gY2FsbGVkLiIsCisgICAgICAgICAgICAgICAgICAgIHRlc3RPYmplY3RGaW5hbGl6ZWQpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJbnRlcnJ1cHRlZEV4Y2VwdGlvbiA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWYuUmVmZXJlbmNlI2dldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXQoKSB7CisgICAgICAgIFdlYWtSZWZlcmVuY2UgcmVmID0gbmV3V2Vha1JlZmVyZW5jZShudWxsKTsKKworICAgICAgICBTeXN0ZW0uZ2MoKTsKKyAgICAgICAgU3lzdGVtLnJ1bkZpbmFsaXphdGlvbigpOworICAgICAgICBhc3NlcnROdWxsKCJnZXQoKSBkb2Vzbid0IHJldHVybiBudWxsIGFmdGVyIGdjIGZvciBXZWFrUmVmZXJlbmNlIiwgcmVmLmdldCgpKTsKKworICAgICAgICBvYmogPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIHJlZiA9IG5ldyBXZWFrUmVmZXJlbmNlPE9iamVjdD4ob2JqLCBuZXcgUmVmZXJlbmNlUXVldWU8T2JqZWN0PigpKTsKKyAgICAgICAgcmVmLmNsZWFyKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldCgpIGRvZXNuJ3QgcmV0dXJuIG51bGwgYWZ0ZXIgY2xlYXIgZm9yIFdlYWtSZWZlcmVuY2UiLCByZWYuZ2V0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhlbHBlciBtZXRob2QgdG8gcHJldmVudCBsaXZlLXByZWNpc2UgYnVncyBmcm9tIGludGVyZmVyaW5nIHdpdGggYW5hbHlzaXMKKyAgICAgKiBvZiB3aGF0IGlzIHJlYWNoYWJsZS4gRG8gbm90IGlubGluZSB0aGlzIG1ldGhvZDsgb3RoZXJ3aXNlIHRlc3RzIG1heSBmYWlsCisgICAgICogb24gVk1zIHRoYXQgYXJlIG5vdCBsaXZlLXByZWNpc2UuIGh0dHA6Ly9iLzQxOTEzNDUKKyAgICAgKi8KKyAgICBwcml2YXRlIFdlYWtSZWZlcmVuY2U8T2JqZWN0PiBuZXdXZWFrUmVmZXJlbmNlKFJlZmVyZW5jZVF1ZXVlPE9iamVjdD4gcXVldWUpIHsKKyAgICAgICAgT2JqZWN0IG8gPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIFdlYWtSZWZlcmVuY2U8T2JqZWN0PiByZWYgPSBuZXcgV2Vha1JlZmVyZW5jZTxPYmplY3Q+KG8sIHF1ZXVlKTsKKyAgICAgICAgYXNzZXJ0U2FtZShvLCByZWYuZ2V0KCkpOworICAgICAgICByZXR1cm4gcmVmOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWYuUmVmZXJlbmNlI2lzRW5xdWV1ZWQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNFbnF1ZXVlZCgpIHsKKyAgICAgICAgUmVmZXJlbmNlUXVldWUgcnEgPSBuZXcgUmVmZXJlbmNlUXVldWUoKTsKKyAgICAgICAgb2JqID0gbmV3IE9iamVjdCgpOworICAgICAgICBSZWZlcmVuY2UgcmVmID0gbmV3IFNvZnRSZWZlcmVuY2Uob2JqLCBycSk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBzdGFydCBvZmYgbm90IGVucXVldWVkLiIsICFyZWYuaXNFbnF1ZXVlZCgpKTsKKyAgICAgICAgcmVmLmVucXVldWUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIG5vdyBiZSBlbnF1ZXVlZC4iLCByZWYuaXNFbnF1ZXVlZCgpKTsKKyAgICAgICAgcmVmLmVucXVldWUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHN0aWxsIGJlIGVucXVldWVkLiIsIHJlZi5pc0VucXVldWVkKCkpOworICAgICAgICBycS5wb2xsKCk7CisgICAgICAgIC8vIFRoaXMgZmFpbHMgLi4uCisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBub3cgYmUgbm90IGVucXVldWVkLiIsICFyZWYuaXNFbnF1ZXVlZCgpKTsKKyAgICB9CisKKyAgICAvKiBDb250cml2ZXMgYSBzaXR1YXRpb24gd2hlcmUgdGhlIG9ubHkgcmVmZXJlbmNlIHRvIGEgc3RyaW5nCisgICAgICogaXMgYSBXZWFrUmVmZXJlbmNlIGZyb20gYW4gb2JqZWN0IHRoYXQgaXMgYmVpbmcgZmluYWxpemVkLgorICAgICAqIENoZWNrcyB0byBtYWtlIHN1cmUgdGhhdCB0aGUgcmVmZXJlbnQgb2YgdGhlIFdlYWtSZWZlcmVuY2UKKyAgICAgKiBpcyBzdGlsbCBwb2ludGluZyB0byBhIHZhbGlkIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ZpbmFsaXplUmVmZXJlbmNlSW50ZXJhY3Rpb24oKSB7CisgICAgICAgIGVycm9yID0gbnVsbDsKKyAgICAgICAgdGVzdE9iamVjdEZpbmFsaXplZCA9IGZhbHNlOworCisgICAgICAgIGNsYXNzIFRlc3RPYmplY3QgeworICAgICAgICAgICAgV2Vha1JlZmVyZW5jZTxTdHJpbmc+IHN0cmluZ1JlZjsKKworICAgICAgICAgICAgcHVibGljIFRlc3RPYmplY3QoU3RyaW5nIHJlZmVyZW50KSB7CisgICAgICAgICAgICAgICAgc3RyaW5nUmVmID0gbmV3IFdlYWtSZWZlcmVuY2U8U3RyaW5nPihyZWZlcmVudCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIC8qIElmIGEgVk0gYnVnIGhhcyBjYXVzZWQgdGhlIHJlZmVyZW50IHRvIGdldAorICAgICAgICAgICAgICAgICAgICAgKiBmcmVlZCB3aXRob3V0IHRoZSByZWZlcmVuY2UgZ2V0dGluZyBjbGVhcmVkLAorICAgICAgICAgICAgICAgICAgICAgKiBsb29raW5nIGl0IHVwLCBhc3NpZ25pbmcgaXQgdG8gYSBsb2NhbCBhbmQKKyAgICAgICAgICAgICAgICAgICAgICogZG9pbmcgYSBHQyBzaG91bGQgY2F1c2Ugc29tZSBzb3J0IG9mIGV4Y2VwdGlvbi4KKyAgICAgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzID0gc3RyaW5nUmVmLmdldCgpOworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZ2MoKTsKKyAgICAgICAgICAgICAgICAgICAgdGVzdE9iamVjdEZpbmFsaXplZCA9IHRydWU7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBuZXcgQXNzZXJ0aW9uRmFpbGVkRXJyb3IoInNvbWV0aGluZyB0aHJldyAnIiArIHQgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICInIGluIGZpbmFsaXplKCkiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBjbGFzcyBUZXN0VGhyZWFkIGV4dGVuZHMgVGhyZWFkIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICAvLyBDcmVhdGUgdGhlIG9iamVjdCBpbiBhIHNlcGFyYXRlIHRocmVhZCB0byBlbnN1cmUgaXQgd2lsbCBiZQorICAgICAgICAgICAgICAgIC8vIGdjJ2VkCisgICAgICAgICAgICAgICAgVGVzdE9iamVjdCB0ZXN0T2JqID0gbmV3IFRlc3RPYmplY3QobmV3IFN0cmluZygic3VwIC9iLyIpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUaHJlYWQgdCA9IG5ldyBUZXN0VGhyZWFkKCk7CisgICAgICAgICAgICB0LnN0YXJ0KCk7CisgICAgICAgICAgICB0LmpvaW4oKTsKKyAgICAgICAgICAgIFN5c3RlbS5nYygpOworICAgICAgICAgICAgU3lzdGVtLnJ1bkZpbmFsaXphdGlvbigpOworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgICAgICAgaWYgKGVycm9yICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoImZpbmFsaXplKCkgc2hvdWxkIGhhdmUgYmVlbiBjYWxsZWQuIiwKKyAgICAgICAgICAgICAgICAgICAgdGVzdE9iamVjdEZpbmFsaXplZCk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkludGVycnVwdGVkRXhjZXB0aW9uIDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvcmVmL1NvZnRSZWZlcmVuY2VUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWYvU29mdFJlZmVyZW5jZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43N2M2NTM2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvcmVmL1NvZnRSZWZlcmVuY2VUZXN0LmphdmEKQEAgLTAsMCArMSwxNDMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLmxhbmcucmVmOworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uU2lkZUVmZmVjdDsKKworaW1wb3J0IGphdmEubGFuZy5yZWYuUmVmZXJlbmNlOworaW1wb3J0IGphdmEubGFuZy5yZWYuUmVmZXJlbmNlUXVldWU7CitpbXBvcnQgamF2YS5sYW5nLnJlZi5Tb2Z0UmVmZXJlbmNlOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKK3B1YmxpYyBjbGFzcyBTb2Z0UmVmZXJlbmNlVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgc3RhdGljIEJvb2xlYW4gYm9vbDsKKyAgICBTb2Z0UmVmZXJlbmNlIHI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBkb25lU3VpdGUoKSB7CisgICAgICAgIGJvb2wgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWYuU29mdFJlZmVyZW5jZSNTb2Z0UmVmZXJlbmNlKGphdmEubGFuZy5PYmplY3QsCisgICAgICogICAgICAgIGphdmEubGFuZy5yZWYuUmVmZXJlbmNlUXVldWUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfT2JqZWN0TGphdmFfbGFuZ19yZWZfUmVmZXJlbmNlUXVldWUoKSB7CisgICAgICAgIFJlZmVyZW5jZVF1ZXVlIHJxID0gbmV3IFJlZmVyZW5jZVF1ZXVlKCk7CisgICAgICAgIGJvb2wgPSBuZXcgQm9vbGVhbih0cnVlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvZnRSZWZlcmVuY2Ugc3IgPSBuZXcgU29mdFJlZmVyZW5jZShib29sLCBycSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbml0aWFsaXphdGlvbiBmYWlsZWQuIiwgKChCb29sZWFuKSBzci5nZXQoKSkKKyAgICAgICAgICAgICAgICAgICAgLmJvb2xlYW5WYWx1ZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFNvZnRSZWZlcmVuY2UoYm9vbCwgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIG5vdCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIsICFleGNlcHRpb24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWYuU29mdFJlZmVyZW5jZSNTb2Z0UmVmZXJlbmNlKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICBib29sID0gbmV3IEJvb2xlYW4odHJ1ZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTb2Z0UmVmZXJlbmNlIHNyID0gbmV3IFNvZnRSZWZlcmVuY2UoYm9vbCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbml0aWFsaXphdGlvbiBmYWlsZWQuIiwgKChCb29sZWFuKSBzci5nZXQoKSkKKyAgICAgICAgICAgICAgICAgICAgLmJvb2xlYW5WYWx1ZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmLlNvZnRSZWZlcmVuY2UjZ2V0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldCgpIHsKKyAgICAgICAgYm9vbCA9IG5ldyBCb29sZWFuKGZhbHNlKTsKKyAgICAgICAgU29mdFJlZmVyZW5jZSBzciA9IG5ldyBTb2Z0UmVmZXJlbmNlKGJvb2wpOworICAgICAgICBhc3NlcnRUcnVlKCJTYW1lIG9iamVjdCBub3QgcmV0dXJuZWQuIiwgYm9vbCA9PSBzci5nZXQoKSk7CisgICAgfQorCisgICAgQFNpZGVFZmZlY3QoIkNhdXNlcyBPdXRPZk1lbW9yeUVycm9yIHRvIHRlc3QgZmluYWxpemF0aW9uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldF9Tb2Z0UmVmZXJlbmNlKCkgeworCisgICAgICAgIGNsYXNzIFRlc3RPYmplY3QgeworICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gZmluYWxpemVkOworICAgICAgICAgICAgICAgIHB1YmxpYyBUZXN0T2JqZWN0KCkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbGl6ZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWxpemVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBSZWZlcmVuY2VRdWV1ZSBycSA9IG5ldyBSZWZlcmVuY2VRdWV1ZSgpOworCisgICAgICAgIGNsYXNzIFRlc3RUaHJlYWQgZXh0ZW5kcyBUaHJlYWQgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIE9iamVjdCB0ZXN0T2JqID0gbmV3IFRlc3RPYmplY3QoKTsKKyAgICAgICAgICAgICAgICByID0gbmV3IFNvZnRSZWZlcmVuY2UodGVzdE9iaiwgcnEpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFJlZmVyZW5jZSByZWY7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUZXN0VGhyZWFkIHQgPSBuZXcgVGVzdFRocmVhZCgpOworICAgICAgICAgICAgdC5zdGFydCgpOworICAgICAgICAgICAgdC5qb2luKCk7CisgICAgICAgICAgICBWZWN0b3I8U3RyaW5nQnVmZmVyPiB2ID0gbmV3IFZlY3RvcjxTdHJpbmdCdWZmZXI+KCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHdoaWxlKHRydWUpIHsKKyAgICAgICAgICAgICAgICAgICAgdi5hZGQobmV3IFN0cmluZ0J1ZmZlcigxMDAwMCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2goT3V0T2ZNZW1vcnlFcnJvciBvZm1lKSB7CisgICAgICAgICAgICAgICAgdiA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkludGVycnVwdGVkRXhjZXB0aW9uIDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydE51bGwoImdldCgpIHNob3VsZCByZXR1cm4gbnVsbCAiICsKKyAgICAgICAgICAgICAgICAiaWYgT3V0T2ZNZW1vcnlFcnJvciBpcyB0aHJvd24uIiwgci5nZXQoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRlc3RUaHJlYWQgdCA9IG5ldyBUZXN0VGhyZWFkKCk7CisgICAgICAgICAgICB0LnN0YXJ0KCk7CisgICAgICAgICAgICB0LmpvaW4oKTsKKyAgICAgICAgICAgIFN5c3RlbS5nYygpOworICAgICAgICAgICAgU3lzdGVtLnJ1bkZpbmFsaXphdGlvbigpOworICAgICAgICAgICAgcmVmID0gcnEucG9sbCgpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiT2JqZWN0IG5vdCBnYXJiYWdlIGNvbGxlY3RlZC4iLCByZWYpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiT2JqZWN0IGlzIG5vdCBudWxsLiIsIHJlZi5nZXQoKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJPYmplY3QgY291bGQgbm90IGJlIHJlY2xhaW1lZC4iLCByLmdldCgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWYvV2Vha1JlZmVyZW5jZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZi9XZWFrUmVmZXJlbmNlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiZGRjMWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWYvV2Vha1JlZmVyZW5jZVRlc3QuamF2YQpAQCAtMCwwICsxLDgwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLmxhbmcucmVmOworCitpbXBvcnQgamF2YS5sYW5nLnJlZi5SZWZlcmVuY2VRdWV1ZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmLldlYWtSZWZlcmVuY2U7CisKK3B1YmxpYyBjbGFzcyBXZWFrUmVmZXJlbmNlVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgc3RhdGljIEJvb2xlYW4gYm9vbDsKKworICAgIHByb3RlY3RlZCB2b2lkIGRvbmVTdWl0ZSgpIHsKKyAgICAgICAgYm9vbCA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZi5XZWFrUmVmZXJlbmNlI1dlYWtSZWZlcmVuY2UoamF2YS5sYW5nLk9iamVjdCwKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLnJlZi5SZWZlcmVuY2VRdWV1ZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19PYmplY3RMamF2YV9sYW5nX3JlZl9SZWZlcmVuY2VRdWV1ZSgpIHsKKyAgICAgICAgUmVmZXJlbmNlUXVldWUgcnEgPSBuZXcgUmVmZXJlbmNlUXVldWUoKTsKKyAgICAgICAgYm9vbCA9IG5ldyBCb29sZWFuKHRydWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gQWxsb3cgdGhlIGZpbmFsaXplciB0byBydW4gdG8gcG90ZW50aWFsbHkgZW5xdWV1ZQorICAgICAgICAgICAgV2Vha1JlZmVyZW5jZSB3ciA9IG5ldyBXZWFrUmVmZXJlbmNlKGJvb2wsIHJxKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkluaXRpYWxpemF0aW9uIGZhaWxlZC4iLCAoKEJvb2xlYW4pIHdyLmdldCgpKQorICAgICAgICAgICAgICAgICAgICAuYm9vbGVhblZhbHVlKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICAvLyBuZWVkIGEgcmVmZXJlbmNlIHRvIGJvb2wgc28gdGhlIGppdCBkb2VzIG5vdCBvcHRpbWl6ZSBpdCBhd2F5CisgICAgICAgIGFzc2VydFRydWUoInNob3VsZCBhbHdheXMgcGFzcyIsIGJvb2wuYm9vbGVhblZhbHVlKCkpOworCisgICAgICAgIGJvb2xlYW4gZXhjZXB0aW9uID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgV2Vha1JlZmVyZW5jZShib29sLCBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgbm90IHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIiwgIWV4Y2VwdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZi5XZWFrUmVmZXJlbmNlI1dlYWtSZWZlcmVuY2UoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIGJvb2wgPSBuZXcgQm9vbGVhbih0cnVlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFdlYWtSZWZlcmVuY2Ugd3IgPSBuZXcgV2Vha1JlZmVyZW5jZShib29sKTsKKyAgICAgICAgICAgIC8vIEFsbG93IHRoZSBmaW5hbGl6ZXIgdG8gcnVuIHRvIHBvdGVudGlhbGx5IGVucXVldWUKKyAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxMDAwKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkluaXRpYWxpemF0aW9uIGZhaWxlZC4iLCAoKEJvb2xlYW4pIHdyLmdldCgpKQorICAgICAgICAgICAgICAgICAgICAuYm9vbGVhblZhbHVlKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICAvLyBuZWVkIGEgcmVmZXJlbmNlIHRvIGJvb2wgc28gdGhlIGppdCBkb2VzIG5vdCBvcHRpbWl6ZSBpdCBhd2F5CisgICAgICAgIGFzc2VydFRydWUoInNob3VsZCBhbHdheXMgcGFzcyIsIGJvb2wuYm9vbGVhblZhbHVlKCkpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvQWNjZXNzaWJsZU9iamVjdFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvQWNjZXNzaWJsZU9iamVjdFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MWM5Nzk4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvcmVmbGVjdC9BY2Nlc3NpYmxlT2JqZWN0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjE1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLmxhbmcucmVmbGVjdDsKKworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uSW5oZXJpdGVkOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3k7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkFjY2Vzc2libGVPYmplY3Q7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXI7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworcHVibGljIGNsYXNzIEFjY2Vzc2libGVPYmplY3RUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHB1YmxpYyBjbGFzcyBUZXN0Q2xhc3MgeworICAgICAgICBwdWJsaWMgT2JqZWN0IGFGaWVsZDsKKworICAgICAgICBASW5oZXJpdGVkUnVudGltZQorICAgICAgICBwdWJsaWMgdm9pZCBhbm5vdGF0ZWRNZXRob2QoKXt9CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIFN1YlRlc3RDbGFzcyBleHRlbmRzIFRlc3RDbGFzc3sKKyAgICAgICAgQEFubm90YXRpb25SdW50aW1lMAorICAgICAgICBAQW5ub3RhdGlvblJ1bnRpbWUxCisgICAgICAgIEBBbm5vdGF0aW9uQ2xhc3MwCisgICAgICAgIEBBbm5vdGF0aW9uU291cmNlMAorICAgICAgICBwdWJsaWMgdm9pZCBhbm5vdGF0ZWRNZXRob2QoKXt9CisgICAgfQorCisKKyAgICBAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorICAgIEBUYXJnZXQoIHtFbGVtZW50VHlwZS5NRVRIT0R9KQorICAgIHN0YXRpYyBAaW50ZXJmYWNlIEFubm90YXRpb25SdW50aW1lMCB7CisgICAgfQorCisgICAgQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKKyAgICBAVGFyZ2V0KCB7IEVsZW1lbnRUeXBlLk1FVEhPRH0pCisgICAgc3RhdGljIEBpbnRlcmZhY2UgQW5ub3RhdGlvblJ1bnRpbWUxIHsKKyAgICB9CisKKyAgICBAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5DTEFTUykKKyAgICBAVGFyZ2V0KCB7IEVsZW1lbnRUeXBlLk1FVEhPRH0pCisgICAgc3RhdGljIEBpbnRlcmZhY2UgQW5ub3RhdGlvbkNsYXNzMCB7CisgICAgfQorCisgICAgQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuU09VUkNFKQorICAgIEBUYXJnZXQoIHtFbGVtZW50VHlwZS5NRVRIT0R9KQorICAgIHN0YXRpYyBAaW50ZXJmYWNlIEFubm90YXRpb25Tb3VyY2UwIHsKKyAgICB9CisKKyAgICBASW5oZXJpdGVkCisgICAgQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKKyAgICBAVGFyZ2V0KCB7RWxlbWVudFR5cGUuTUVUSE9EfSkKKyAgICBzdGF0aWMgQGludGVyZmFjZSBJbmhlcml0ZWRSdW50aW1lIHsKKyAgICB9CisKKyAgICAvL3VzZWQgZm9yIGNvbnN0cnVjdG9yIHRlc3QKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBNeUFjY2Vzc2libGVPYmplY3QgZXh0ZW5kcyBBY2Nlc3NpYmxlT2JqZWN0eworICAgICAgICBwdWJsaWMgTXlBY2Nlc3NpYmxlT2JqZWN0KCkgeworICAgICAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkFjY2Vzc2libGVPYmplY3QjQWNjZXNzaWJsZU9iamVjdCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXcgTXlBY2Nlc3NpYmxlT2JqZWN0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkFjY2Vzc2libGVPYmplY3QjaXNBY2Nlc3NpYmxlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzQWNjZXNzaWJsZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4KKyAgICAgICAgLy8gamF2YS5sYW5nLnJlZmxlY3QuQWNjZXNzaWJsZU9iamVjdC5pc0FjY2Vzc2libGUoKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgQWNjZXNzaWJsZU9iamVjdCBhbyA9IFRlc3RDbGFzcy5jbGFzcy5nZXRGaWVsZCgiYUZpZWxkIik7CisgICAgICAgICAgICBhby5zZXRBY2Nlc3NpYmxlKHRydWUpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgdG8gaXNBY2Nlc3NpYmxlIiwgYW8uaXNBY2Nlc3NpYmxlKCkpOworICAgICAgICAgICAgYW8uc2V0QWNjZXNzaWJsZShmYWxzZSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCB0cnVlIHRvIGlzQWNjZXNzaWJsZSIsICFhby5pc0FjY2Vzc2libGUoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuQWNjZXNzaWJsZU9iamVjdCNzZXRBY2Nlc3NpYmxlKGphdmEubGFuZy5yZWZsZWN0LkFjY2Vzc2libGVPYmplY3RbXSwKKyAgICAgKiAgICAgICAgYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEFjY2Vzc2libGUkTGphdmFfbGFuZ19yZWZsZWN0X0FjY2Vzc2libGVPYmplY3RaKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgQWNjZXNzaWJsZU9iamVjdCBhbyA9IFRlc3RDbGFzcy5jbGFzcy5nZXRGaWVsZCgiYUZpZWxkIik7CisgICAgICAgICAgICBBY2Nlc3NpYmxlT2JqZWN0W10gYW9hID0gbmV3IEFjY2Vzc2libGVPYmplY3RbXSB7IGFvIH07CisgICAgICAgICAgICBBY2Nlc3NpYmxlT2JqZWN0LnNldEFjY2Vzc2libGUoYW9hLCB0cnVlKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIHRvIGlzQWNjZXNzaWJsZSIsIGFvLmlzQWNjZXNzaWJsZSgpKTsKKyAgICAgICAgICAgIEFjY2Vzc2libGVPYmplY3Quc2V0QWNjZXNzaWJsZShhb2EsIGZhbHNlKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHRydWUgdG8gaXNBY2Nlc3NpYmxlIiwgIWFvLmlzQWNjZXNzaWJsZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5BY2Nlc3NpYmxlT2JqZWN0I3NldEFjY2Vzc2libGUoYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEFjY2Vzc2libGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQWNjZXNzaWJsZU9iamVjdCBhbyA9IFRlc3RDbGFzcy5jbGFzcy5nZXRGaWVsZCgiYUZpZWxkIik7CisgICAgICAgIGFvLnNldEFjY2Vzc2libGUodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIHRvIGlzQWNjZXNzaWJsZSIsIGFvLmlzQWNjZXNzaWJsZSgpKTsKKyAgICAgICAgYW8uc2V0QWNjZXNzaWJsZShmYWxzZSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIHRvIGlzQWNjZXNzaWJsZSIsIGFvLmlzQWNjZXNzaWJsZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEFubm90YXRpb24oKSB0aHJvd3MgRXhjZXB0aW9ueworICAgICAgICBBY2Nlc3NpYmxlT2JqZWN0IGFvID0gU3ViVGVzdENsYXNzLmNsYXNzLmdldE1ldGhvZCgiYW5ub3RhdGVkTWV0aG9kIik7CisgICAgICAgIC8vdGVzdCBlcnJvciBjYXNlCisgICAgICAgIGJvb2xlYW4gbnBlVGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgYW8uZ2V0QW5ub3RhdGlvbihudWxsKTsKKyAgICAgICAgICBmYWlsKCJOUEUgZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgbnBlVGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJOUEUgZXhwZWN0ZWQiLCBucGVUaHJvd24pOworCisgICAgICAgIC8vdGVzdCBpbmhlcml0ZWQgb24gbWV0aG9kIGhhcyBubyBlZmZlY3QKKyAgICAgICAgSW5oZXJpdGVkUnVudGltZSBpciA9IGFvLmdldEFubm90YXRpb24oSW5oZXJpdGVkUnVudGltZS5jbGFzcyk7CisgICAgICAgIGFzc2VydE51bGwoIkluaGVyaXRlZCBBbm5vdGF0aW9ucyBzaG91bGQgaGF2ZSBubyBlZmZlY3QiLCBpcik7CisKKyAgICAgICAgLy90ZXN0IG9yZGluYXJ5IHJ1bnRpbWUgYW5ub3RhdGlvbgorICAgICAgICBBbm5vdGF0aW9uUnVudGltZTAgcnQwID0gYW8uZ2V0QW5ub3RhdGlvbihBbm5vdGF0aW9uUnVudGltZTAuY2xhc3MpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJBbm5vdGF0aW9uUnVudGltZTAgaW5zdGFuY2UgZXhwZWN0ZWQiLCBydDApOworICAgIH0KKworICAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEFubm90YXRpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEFjY2Vzc2libGVPYmplY3QgYW8gPSBTdWJUZXN0Q2xhc3MuY2xhc3MuZ2V0TWV0aG9kKCJhbm5vdGF0ZWRNZXRob2QiKTsKKyAgICAgICAgQW5ub3RhdGlvbltdIGFubm90YXRpb25zID0gYW8uZ2V0QW5ub3RhdGlvbnMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGFubm90YXRpb25zLmxlbmd0aCk7CisKKyAgICAgICAgU2V0PENsYXNzPD8+PiBpZ25vcmVPcmRlciA9IG5ldyBIYXNoU2V0PENsYXNzPD8+PigpOworICAgICAgICBpZ25vcmVPcmRlci5hZGQoYW5ub3RhdGlvbnNbMF0uYW5ub3RhdGlvblR5cGUoKSk7CisgICAgICAgIGlnbm9yZU9yZGVyLmFkZChhbm5vdGF0aW9uc1sxXS5hbm5vdGF0aW9uVHlwZSgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJNaXNzaW5nIEBBbm5vdGF0aW9uUnVudGltZTAiLAorICAgICAgICAgICAgICAgIGlnbm9yZU9yZGVyLmNvbnRhaW5zKEFubm90YXRpb25SdW50aW1lMC5jbGFzcykpOworICAgICAgICBhc3NlcnRUcnVlKCJNaXNzaW5nIEBBbm5vdGF0aW9uUnVudGltZTEiLAorICAgICAgICAgICAgICAgIGlnbm9yZU9yZGVyLmNvbnRhaW5zKEFubm90YXRpb25SdW50aW1lMS5jbGFzcykpOworICAgIH0KKworICAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERlY2xhcmVkQW5ub3RhdGlvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQWNjZXNzaWJsZU9iamVjdCBhbyA9IFN1YlRlc3RDbGFzcy5jbGFzcy5nZXRNZXRob2QoImFubm90YXRlZE1ldGhvZCIpOworICAgICAgICBBbm5vdGF0aW9uW10gYW5ub3RhdGlvbnMgPSBhby5nZXREZWNsYXJlZEFubm90YXRpb25zKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBhbm5vdGF0aW9ucy5sZW5ndGgpOworCisgICAgICAgIFNldDxDbGFzczw/Pj4gaWdub3JlT3JkZXIgPSBuZXcgSGFzaFNldDxDbGFzczw/Pj4oKTsKKyAgICAgICAgaWdub3JlT3JkZXIuYWRkKGFubm90YXRpb25zWzBdLmFubm90YXRpb25UeXBlKCkpOworICAgICAgICBpZ25vcmVPcmRlci5hZGQoYW5ub3RhdGlvbnNbMV0uYW5ub3RhdGlvblR5cGUoKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTWlzc2luZyBAQW5ub3RhdGlvblJ1bnRpbWUwIiwKKyAgICAgICAgICAgICAgICBpZ25vcmVPcmRlci5jb250YWlucyhBbm5vdGF0aW9uUnVudGltZTAuY2xhc3MpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTWlzc2luZyBAQW5ub3RhdGlvblJ1bnRpbWUxIiwKKyAgICAgICAgICAgICAgICBpZ25vcmVPcmRlci5jb250YWlucyhBbm5vdGF0aW9uUnVudGltZTEuY2xhc3MpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzQW5ub3RhdGlvblByZXNlbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQWNjZXNzaWJsZU9iamVjdCBhbyA9IFN1YlRlc3RDbGFzcy5jbGFzcy5nZXRNZXRob2QoImFubm90YXRlZE1ldGhvZCIpOworICAgICAgICBhc3NlcnRUcnVlKCJNaXNzaW5nIEBBbm5vdGF0aW9uUnVudGltZTAiLAorICAgICAgICAgICAgICAgIGFvLmlzQW5ub3RhdGlvblByZXNlbnQoQW5ub3RhdGlvblJ1bnRpbWUwLmNsYXNzKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJBbm5vdGF0aW9uU291cmNlMCBzaG91bGQgbm90IGJlIHZpc2libGUgYXQgcnVudGltZSIsCisgICAgICAgICAgICAgICAgYW8uaXNBbm5vdGF0aW9uUHJlc2VudChBbm5vdGF0aW9uU291cmNlMC5jbGFzcykpOworICAgICAgICBib29sZWFuIG5wZVRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgIGFvLmlzQW5ub3RhdGlvblByZXNlbnQobnVsbCk7CisgICAgICAgICAgZmFpbCgiTlBFIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIG5wZVRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTlBFIGV4cGVjdGVkIiwgbnBlVGhyb3duKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFNldHMgdXAgdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBvcGVuIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzIG1ldGhvZAorICAgICAqIGlzIGNhbGxlZCBiZWZvcmUgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvQXJyYXlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L0FycmF5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ5ZTA1ZmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L0FycmF5VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTAwMSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5BcnJheTsKKworcHVibGljIGNsYXNzIEFycmF5VGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5BcnJheSNnZXQoamF2YS5sYW5nLk9iamVjdCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TGphdmFfbGFuZ19PYmplY3RJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdAorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5BcnJheS5nZXQoamF2YS5sYW5nLk9iamVjdCwgaW50KQorCisgICAgICAgIGludFtdIHggPSB7IDEgfTsKKyAgICAgICAgT2JqZWN0IHJldCA9IG51bGw7CisgICAgICAgIGJvb2xlYW4gdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXQgPSBBcnJheS5nZXQoeCwgMCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldCB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIkdldCByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLAorICAgICAgICAgICAgICAgIDEsICgoSW50ZWdlcikgcmV0KS5pbnRWYWx1ZSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldCA9IEFycmF5LmdldChuZXcgT2JqZWN0KCksIDApOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24pIHsKKyAgICAgICAgICAgIGZhaWwoIlBhc3Npbmcgbm9uLWFycmF5IGZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldCA9IEFycmF5LmdldCh4LCA0KTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkIGluZGV4IGZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vc2FtZSB0ZXN0IHdpdGggbm9uIHByaW1pdGl2ZSBjb21wb25lbnQgdHlwZQorICAgICAgICBJbnRlZ2VyW10geSA9IG5ldyBJbnRlZ2VyW117IDEgfTsKKyAgICAgICAgcmV0ID0gbnVsbDsKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXQgPSBBcnJheS5nZXQoeSwgMCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldCB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIkdldCByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLAorICAgICAgICAgICAgICAgIDEsICgoSW50ZWdlcikgcmV0KS5pbnRWYWx1ZSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldCA9IEFycmF5LmdldChuZXcgT2JqZWN0KCksIDApOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24pIHsKKyAgICAgICAgICAgIGZhaWwoIlBhc3Npbmcgbm9uLWFycmF5IGZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldCA9IEFycmF5LmdldCh5LCA0KTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkIGluZGV4IGZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkFycmF5I2dldEJvb2xlYW4oamF2YS5sYW5nLk9iamVjdCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Qm9vbGVhbkxqYXZhX2xhbmdfT2JqZWN0SSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4KKyAgICAgICAgLy8gamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkuZ2V0Qm9vbGVhbihqYXZhLmxhbmcuT2JqZWN0LCBpbnQpCisgICAgICAgIGJvb2xlYW5bXSB4ID0geyB0cnVlIH07CisgICAgICAgIGJvb2xlYW4gcmV0ID0gZmFsc2U7CisgICAgICAgIGJvb2xlYW4gdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXQgPSBBcnJheS5nZXRCb29sZWFuKHgsIDApOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXQgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiR2V0IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIHJldCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXQgPSBBcnJheS5nZXRCb29sZWFuKG5ldyBPYmplY3QoKSwgMCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiUGFzc2luZyBub24tYXJyYXkgZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0ID0gQXJyYXkuZ2V0Qm9vbGVhbih4LCA0KTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkIGluZGV4IGZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldCA9IEFycmF5LmdldEJvb2xlYW4obnVsbCwgMCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJOdWxsIGFyZ3VtZW50IGZhaWxlZCB0byB0aHJvdyBOUEUiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkFycmF5I2dldEJ5dGUoamF2YS5sYW5nLk9iamVjdCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Qnl0ZUxqYXZhX2xhbmdfT2JqZWN0SSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJ5dGUKKyAgICAgICAgLy8gamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkuZ2V0Qnl0ZShqYXZhLmxhbmcuT2JqZWN0LCBpbnQpCisgICAgICAgIGJ5dGVbXSB4ID0geyAxIH07CisgICAgICAgIGJ5dGUgcmV0ID0gMDsKKyAgICAgICAgYm9vbGVhbiB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldCA9IEFycmF5LmdldEJ5dGUoeCwgMCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldCB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIkdldCByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAxLCByZXQpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0ID0gQXJyYXkuZ2V0Qnl0ZShuZXcgT2JqZWN0KCksIDApOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24pIHsKKyAgICAgICAgICAgIGZhaWwoIlBhc3Npbmcgbm9uLWFycmF5IGZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldCA9IEFycmF5LmdldEJ5dGUoeCwgNCk7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiSW52YWxpZCBpbmRleCBmYWlsZWQgdG8gdGhyb3cgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXQgPSBBcnJheS5nZXRCeXRlKG51bGwsIDApOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiTnVsbCBhcmd1bWVudCBmYWlsZWQgdG8gdGhyb3cgTlBFIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5BcnJheSNnZXRDaGFyKGphdmEubGFuZy5PYmplY3QsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldENoYXJMamF2YV9sYW5nX09iamVjdEkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBjaGFyCisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0LkFycmF5LmdldENoYXIoamF2YS5sYW5nLk9iamVjdCwgaW50KQorICAgICAgICBjaGFyW10geCA9IHsgMSB9OworICAgICAgICBjaGFyIHJldCA9IDA7CisgICAgICAgIGJvb2xlYW4gdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXQgPSBBcnJheS5nZXRDaGFyKHgsIDApOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXQgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHZXQgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgMSwgcmV0KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldCA9IEFycmF5LmdldENoYXIobmV3IE9iamVjdCgpLCAwKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJQYXNzaW5nIG5vbi1hcnJheSBmYWlsZWQgdG8gdGhyb3cgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXQgPSBBcnJheS5nZXRDaGFyKHgsIDQpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24pIHsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWQgaW5kZXggZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0ID0gQXJyYXkuZ2V0Q2hhcihudWxsLCAwKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24pIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGwgYXJndW1lbnQgZmFpbGVkIHRvIHRocm93IE5QRSIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkjZ2V0RG91YmxlKGphdmEubGFuZy5PYmplY3QsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERvdWJsZUxqYXZhX2xhbmdfT2JqZWN0SSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZQorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5BcnJheS5nZXREb3VibGUoamF2YS5sYW5nLk9iamVjdCwgaW50KQorICAgICAgICBkb3VibGVbXSB4ID0geyAxIH07CisgICAgICAgIGRvdWJsZSByZXQgPSAwOworICAgICAgICBib29sZWFuIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0ID0gQXJyYXkuZ2V0RG91YmxlKHgsIDApOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXQgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHZXQgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgMSwgcmV0LCAwLjApOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0ID0gQXJyYXkuZ2V0RG91YmxlKG5ldyBPYmplY3QoKSwgMCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJQYXNzaW5nIG5vbi1hcnJheSBmYWlsZWQgdG8gdGhyb3cgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXQgPSBBcnJheS5nZXREb3VibGUoeCwgNCk7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiSW52YWxpZCBpbmRleCBmYWlsZWQgdG8gdGhyb3cgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXQgPSBBcnJheS5nZXREb3VibGUobnVsbCwgMCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJOdWxsIGFyZ3VtZW50IGZhaWxlZCB0byB0aHJvdyBOUEUiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkFycmF5I2dldEZsb2F0KGphdmEubGFuZy5PYmplY3QsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEZsb2F0TGphdmFfbGFuZ19PYmplY3RJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgZmxvYXQKKyAgICAgICAgLy8gamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkuZ2V0RmxvYXQoamF2YS5sYW5nLk9iamVjdCwgaW50KQorICAgICAgICBmbG9hdFtdIHggPSB7IDEgfTsKKyAgICAgICAgZmxvYXQgcmV0ID0gMDsKKyAgICAgICAgYm9vbGVhbiB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldCA9IEFycmF5LmdldEZsb2F0KHgsIDApOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXQgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHZXQgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgMSwgcmV0LCAwLjApOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0ID0gQXJyYXkuZ2V0RmxvYXQobmV3IE9iamVjdCgpLCAwKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJQYXNzaW5nIG5vbi1hcnJheSBmYWlsZWQgdG8gdGhyb3cgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXQgPSBBcnJheS5nZXRGbG9hdCh4LCA0KTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkIGluZGV4IGZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldCA9IEFycmF5LmdldEZsb2F0KG51bGwsIDApOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiTnVsbCBhcmd1bWVudCBmYWlsZWQgdG8gdGhyb3cgTlBFIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5BcnJheSNnZXRJbnQoamF2YS5sYW5nLk9iamVjdCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW50TGphdmFfbGFuZ19PYmplY3RJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEubGFuZy5yZWZsZWN0LkFycmF5LmdldEludChqYXZhLmxhbmcuT2JqZWN0LAorICAgICAgICAvLyBpbnQpCisgICAgICAgIGludFtdIHggPSB7IDEgfTsKKyAgICAgICAgaW50IHJldCA9IDA7CisgICAgICAgIGJvb2xlYW4gdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXQgPSBBcnJheS5nZXRJbnQoeCwgMCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldCB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIkdldCByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAxLCByZXQpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0ID0gQXJyYXkuZ2V0SW50KG5ldyBPYmplY3QoKSwgMCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiUGFzc2luZyBub24tYXJyYXkgZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0ID0gQXJyYXkuZ2V0SW50KHgsIDQpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24pIHsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWQgaW5kZXggZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0ID0gQXJyYXkuZ2V0SW50KG51bGwsIDApOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiTnVsbCBhcmd1bWVudCBmYWlsZWQgdG8gdGhyb3cgTlBFIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5BcnJheSNnZXRMZW5ndGgoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldExlbmd0aExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50CisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0LkFycmF5LmdldExlbmd0aChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBsb25nW10geCA9IHsgMSB9OworCisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGxlbmd0aCIsIDEsIEFycmF5LmdldExlbmd0aCh4KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGxlbmd0aCIsIDEwMDAwLCBBcnJheQorICAgICAgICAgICAgICAgIC5nZXRMZW5ndGgobmV3IE9iamVjdFsxMDAwMF0pKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5LmdldExlbmd0aChuZXcgT2JqZWN0KCkpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdAorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGZhaWwoIkZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24gd2hlbiBwYXNzZWQgbm9uLWFycmF5Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkjZ2V0TG9uZyhqYXZhLmxhbmcuT2JqZWN0LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRMb25nTGphdmFfbGFuZ19PYmplY3RJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgbG9uZworICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5BcnJheS5nZXRMb25nKGphdmEubGFuZy5PYmplY3QsIGludCkKKyAgICAgICAgbG9uZ1tdIHggPSB7IDEgfTsKKyAgICAgICAgbG9uZyByZXQgPSAwOworICAgICAgICBib29sZWFuIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0ID0gQXJyYXkuZ2V0TG9uZyh4LCAwKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0IHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiR2V0IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIDEsIHJldCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXQgPSBBcnJheS5nZXRMb25nKG5ldyBPYmplY3QoKSwgMCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiUGFzc2luZyBub24tYXJyYXkgZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0ID0gQXJyYXkuZ2V0TG9uZyh4LCA0KTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkIGluZGV4IGZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldCA9IEFycmF5LmdldExvbmcobnVsbCwgMCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJOdWxsIGFyZ3VtZW50IGZhaWxlZCB0byB0aHJvdyBOUEUiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkFycmF5I2dldFNob3J0KGphdmEubGFuZy5PYmplY3QsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFNob3J0TGphdmFfbGFuZ19PYmplY3RJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgc2hvcnQKKyAgICAgICAgLy8gamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkuZ2V0U2hvcnQoamF2YS5sYW5nLk9iamVjdCwgaW50KQorICAgICAgICBzaG9ydFtdIHggPSB7IDEgfTsKKyAgICAgICAgc2hvcnQgcmV0ID0gMDsKKyAgICAgICAgYm9vbGVhbiB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldCA9IEFycmF5LmdldFNob3J0KHgsIDApOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXQgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHZXQgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgMSwgcmV0KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldCA9IEFycmF5LmdldFNob3J0KG5ldyBPYmplY3QoKSwgMCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiUGFzc2luZyBub24tYXJyYXkgZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0ID0gQXJyYXkuZ2V0U2hvcnQoeCwgNCk7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiSW52YWxpZCBpbmRleCBmYWlsZWQgdG8gdGhyb3cgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXQgPSBBcnJheS5nZXRTaG9ydChudWxsLCAwKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24pIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGwgYXJndW1lbnQgZmFpbGVkIHRvIHRocm93IE5QRSIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkjbmV3SW5zdGFuY2UoamF2YS5sYW5nLkNsYXNzLCBpbnRbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X25ld0luc3RhbmNlTGphdmFfbGFuZ19DbGFzcyRJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdAorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5BcnJheS5uZXdJbnN0YW5jZShqYXZhLmxhbmcuQ2xhc3MsIGludCBbXSkKKyAgICAgICAgaW50W11bXSB4OworICAgICAgICBpbnRbXSB5ID0geyAyIH07CisKKyAgICAgICAgeCA9IChpbnRbXVtdKSBBcnJheS5uZXdJbnN0YW5jZShpbnRbXS5jbGFzcywgeSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHRvIGluc3RhbnRpYXRlIGFycmF5IHByb3Blcmx5IiwgMiwgeC5sZW5ndGgpOworCisgICAgICAgIGJvb2xlYW4gdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB4ID0gKGludFtdW10pIEFycmF5Lm5ld0luc3RhbmNlKG51bGwsIHkpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiTnVsbCBhcmd1bWVudCBmYWlsZWQgdG8gdGhyb3cgTlBFIik7CisgICAgICAgIH0KKworICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5Lm5ld0luc3RhbmNlKGludFtdLmNsYXNzLCBuZXcgaW50W117MSwtMX0pOworICAgICAgICB9IGNhdGNoIChOZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiTmVnYXRpdmUgYXJyYXkgc2l6ZSBmYWlsZWQgdG8gdGhyb3cgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXkubmV3SW5zdGFuY2UoaW50W10uY2xhc3MsIG5ldyBpbnRbXXt9KTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJaZXJvIGFycmF5IHNpemUgZmFpbGVkIHRvIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkjbmV3SW5zdGFuY2UoamF2YS5sYW5nLkNsYXNzLCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9uZXdJbnN0YW5jZUxqYXZhX2xhbmdfQ2xhc3NJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdAorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5BcnJheS5uZXdJbnN0YW5jZShqYXZhLmxhbmcuQ2xhc3MsIGludCkKKyAgICAgICAgaW50W10geDsKKworICAgICAgICB4ID0gKGludFtdKSBBcnJheS5uZXdJbnN0YW5jZShpbnQuY2xhc3MsIDEwMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHRvIGluc3RhbnRpYXRlIGFycmF5IHByb3Blcmx5IiwgMTAwLCB4Lmxlbmd0aCk7CisKKyAgICAgICAgYm9vbGVhbiB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5Lm5ld0luc3RhbmNlKG51bGwsIDEwMCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJOdWxsIGFyZ3VtZW50IGZhaWxlZCB0byB0aHJvdyBOUEUiKTsKKyAgICAgICAgfQorCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICBBcnJheS5uZXdJbnN0YW5jZShpbnRbXS5jbGFzcywgLTEpOworICAgICAgICB9IGNhdGNoIChOZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiTmVnYXRpdmUgYXJyYXkgc2l6ZSBmYWlsZWQgdG8gdGhyb3cgTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkFycmF5I3NldChqYXZhLmxhbmcuT2JqZWN0LCBpbnQsCisgICAgICogICAgICAgIGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRMamF2YV9sYW5nX09iamVjdElMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkuc2V0KGphdmEubGFuZy5PYmplY3QsCisgICAgICAgIC8vIGludCwgamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgaW50W10geCA9IHsgMCB9OworICAgICAgICBib29sZWFuIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXkuc2V0KHgsIDAsIG5ldyBJbnRlZ2VyKDEpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0IHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiR2V0IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIDEsICgoSW50ZWdlcikgQXJyYXkuZ2V0KHgsIDApKQorICAgICAgICAgICAgICAgIC5pbnRWYWx1ZSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5LnNldChuZXcgT2JqZWN0KCksIDAsIG5ldyBPYmplY3QoKSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiUGFzc2luZyBub24tYXJyYXkgZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXkuc2V0KHgsIDQsIG5ldyBJbnRlZ2VyKDEpKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkIGluZGV4IGZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRyeWluZyB0byBwdXQgbnVsbCBpbiBhIHByaW1pdGl2ZSBhcnJheSBjYXVzZXMKKyAgICAgICAgLy8gYSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaW4gNS4wCisgICAgICAgIGJvb2xlYW4gZXhjZXB0aW9uID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheS5zZXQobmV3IGludFsxXSwgMCwgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoImV4cGVjdGVkIGV4Y2VwdGlvbiBub3QgdGhyb3duIiwgZXhjZXB0aW9uKTsKKworICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgQXJyYXkuc2V0KG51bGwsIDAsIDIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiTnVsbCBhcmd1bWVudCBmYWlsZWQgdG8gdGhyb3cgTlBFIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5BcnJheSNzZXRCb29sZWFuKGphdmEubGFuZy5PYmplY3QsIGludCwgYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEJvb2xlYW5MamF2YV9sYW5nX09iamVjdElaKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZAorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5BcnJheS5zZXRCb29sZWFuKGphdmEubGFuZy5PYmplY3QsIGludCwgYm9vbGVhbikKKyAgICAgICAgYm9vbGVhbltdIHggPSB7IGZhbHNlIH07CisgICAgICAgIGJvb2xlYW4gdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheS5zZXRCb29sZWFuKHgsIDAsIHRydWUpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXQgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIHNldCBjb3JyZWN0IHZhbHVlIiwgQXJyYXkuZ2V0Qm9vbGVhbih4LCAwKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheS5zZXRCb29sZWFuKG5ldyBPYmplY3QoKSwgMCwgZmFsc2UpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24peworICAgICAgICAgICAgZmFpbCgiUGFzc2luZyBub24tYXJyYXkgZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXkuc2V0Qm9vbGVhbih4LCA0LCBmYWxzZSk7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiSW52YWxpZCBpbmRleCBmYWlsZWQgdG8gdGhyb3cgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgQXJyYXkuc2V0Qm9vbGVhbihudWxsLCAwLCB0cnVlKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24pIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGwgYXJndW1lbnQgZmFpbGVkIHRvIHRocm93IE5QRSIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkjc2V0Qnl0ZShqYXZhLmxhbmcuT2JqZWN0LCBpbnQsIGJ5dGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRCeXRlTGphdmFfbGFuZ19PYmplY3RJQigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQKKyAgICAgICAgLy8gamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkuc2V0Qnl0ZShqYXZhLmxhbmcuT2JqZWN0LCBpbnQsIGJ5dGUpCisgICAgICAgIGJ5dGVbXSB4ID0geyAwIH07CisgICAgICAgIGJvb2xlYW4gdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheS5zZXRCeXRlKHgsIDAsIChieXRlKSAxKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0IHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiR2V0IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIDEsIEFycmF5LmdldEJ5dGUoeCwgMCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXkuc2V0Qnl0ZShuZXcgT2JqZWN0KCksIDAsIChieXRlKSA5KTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJQYXNzaW5nIG5vbi1hcnJheSBmYWlsZWQgdG8gdGhyb3cgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheS5zZXRCeXRlKHgsIDQsIChieXRlKSA5KTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkIGluZGV4IGZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICBBcnJheS5zZXRCeXRlKG51bGwsIDAsIChieXRlKTApOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiTnVsbCBhcmd1bWVudCBmYWlsZWQgdG8gdGhyb3cgTlBFIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5BcnJheSNzZXRDaGFyKGphdmEubGFuZy5PYmplY3QsIGludCwgY2hhcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldENoYXJMamF2YV9sYW5nX09iamVjdElDKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZAorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5BcnJheS5zZXRDaGFyKGphdmEubGFuZy5PYmplY3QsIGludCwgY2hhcikKKyAgICAgICAgY2hhcltdIHggPSB7IDAgfTsKKyAgICAgICAgYm9vbGVhbiB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5LnNldENoYXIoeCwgMCwgKGNoYXIpIDEpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXQgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHZXQgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgMSwgQXJyYXkuZ2V0Q2hhcih4LCAwKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheS5zZXRDaGFyKG5ldyBPYmplY3QoKSwgMCwgKGNoYXIpIDkpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24pIHsKKyAgICAgICAgICAgIGZhaWwoIlBhc3Npbmcgbm9uLWFycmF5IGZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5LnNldENoYXIoeCwgNCwgKGNoYXIpIDkpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24pIHsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWQgaW5kZXggZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgIEFycmF5LnNldENoYXIobnVsbCwgMCwgKGNoYXIpMCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJOdWxsIGFyZ3VtZW50IGZhaWxlZCB0byB0aHJvdyBOUEUiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkFycmF5I3NldERvdWJsZShqYXZhLmxhbmcuT2JqZWN0LCBpbnQsIGRvdWJsZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldERvdWJsZUxqYXZhX2xhbmdfT2JqZWN0SUQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkCisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0LkFycmF5LnNldERvdWJsZShqYXZhLmxhbmcuT2JqZWN0LCBpbnQsIGRvdWJsZSkKKyAgICAgICAgZG91YmxlW10geCA9IHsgMCB9OworICAgICAgICBib29sZWFuIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXkuc2V0RG91YmxlKHgsIDAsIDEpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXQgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHZXQgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgMSwgQXJyYXkuZ2V0RG91YmxlKHgsIDApLCAwLjApOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXkuc2V0RG91YmxlKG5ldyBPYmplY3QoKSwgMCwgOSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiUGFzc2luZyBub24tYXJyYXkgZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXkuc2V0RG91YmxlKHgsIDQsIDkpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24pIHsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWQgaW5kZXggZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgIEFycmF5LnNldERvdWJsZShudWxsLCAwLCAwKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24pIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGwgYXJndW1lbnQgZmFpbGVkIHRvIHRocm93IE5QRSIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkjc2V0RmxvYXQoamF2YS5sYW5nLk9iamVjdCwgaW50LCBmbG9hdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEZsb2F0TGphdmFfbGFuZ19PYmplY3RJRigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQKKyAgICAgICAgLy8gamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkuc2V0RmxvYXQoamF2YS5sYW5nLk9iamVjdCwgaW50LCBmbG9hdCkKKyAgICAgICAgZmxvYXRbXSB4ID0geyAwLjBmIH07CisgICAgICAgIGJvb2xlYW4gdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheS5zZXRGbG9hdCh4LCAwLCAoZmxvYXQpIDEpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXQgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHZXQgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgMSwgQXJyYXkuZ2V0RmxvYXQoeCwgMCksIDAuMCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheS5zZXRGbG9hdChuZXcgT2JqZWN0KCksIDAsIChmbG9hdCkgOSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiUGFzc2luZyBub24tYXJyYXkgZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXkuc2V0RmxvYXQoeCwgNCwgKGZsb2F0KSA5KTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkIGluZGV4IGZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICBBcnJheS5zZXRGbG9hdChudWxsLCAwLCAwKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24pIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGwgYXJndW1lbnQgZmFpbGVkIHRvIHRocm93IE5QRSIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkjc2V0SW50KGphdmEubGFuZy5PYmplY3QsIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0SW50TGphdmFfbGFuZ19PYmplY3RJSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkuc2V0SW50KGphdmEubGFuZy5PYmplY3QsCisgICAgICAgIC8vIGludCwgaW50KQorICAgICAgICBpbnRbXSB4ID0geyAwIH07CisgICAgICAgIGJvb2xlYW4gdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheS5zZXRJbnQoeCwgMCwgKGludCkgMSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldCB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIkdldCByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAxLCBBcnJheS5nZXRJbnQoeCwgMCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXkuc2V0SW50KG5ldyBPYmplY3QoKSwgMCwgKGludCkgOSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiUGFzc2luZyBub24tYXJyYXkgZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXkuc2V0SW50KHgsIDQsIChpbnQpIDkpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24pIHsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWQgaW5kZXggZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgIEFycmF5LnNldEludChudWxsLCAwLCAwKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCF0aHJvd24pIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGwgYXJndW1lbnQgZmFpbGVkIHRvIHRocm93IE5QRSIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkjc2V0TG9uZyhqYXZhLmxhbmcuT2JqZWN0LCBpbnQsIGxvbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRMb25nTGphdmFfbGFuZ19PYmplY3RJSigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQKKyAgICAgICAgLy8gamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkuc2V0TG9uZyhqYXZhLmxhbmcuT2JqZWN0LCBpbnQsIGxvbmcpCisgICAgICAgIGxvbmdbXSB4ID0geyAwIH07CisgICAgICAgIGJvb2xlYW4gdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheS5zZXRMb25nKHgsIDAsIDEpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXQgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHZXQgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgMSwgQXJyYXkuZ2V0TG9uZyh4LCAwKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheS5zZXRMb25nKG5ldyBPYmplY3QoKSwgMCwgOSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiUGFzc2luZyBub24tYXJyYXkgZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXkuc2V0TG9uZyh4LCA0LCA5KTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkIGluZGV4IGZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICBBcnJheS5zZXRMb25nKG51bGwsIDAsIDApOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiTnVsbCBhcmd1bWVudCBmYWlsZWQgdG8gdGhyb3cgTlBFIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5BcnJheSNzZXRTaG9ydChqYXZhLmxhbmcuT2JqZWN0LCBpbnQsIHNob3J0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0U2hvcnRMamF2YV9sYW5nX09iamVjdElTKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZAorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5BcnJheS5zZXRTaG9ydChqYXZhLmxhbmcuT2JqZWN0LCBpbnQsIHNob3J0KQorICAgICAgICBzaG9ydFtdIHggPSB7IDAgfTsKKyAgICAgICAgYm9vbGVhbiB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5LnNldFNob3J0KHgsIDAsIChzaG9ydCkgMSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldCB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIkdldCByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAxLCBBcnJheS5nZXRTaG9ydCh4LCAwKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheS5zZXRTaG9ydChuZXcgT2JqZWN0KCksIDAsIChzaG9ydCkgOSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IGJlaGF2aW91cgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRocm93bikgeworICAgICAgICAgICAgZmFpbCgiUGFzc2luZyBub24tYXJyYXkgZmFpbGVkIHRvIHRocm93IGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXkuc2V0U2hvcnQoeCwgNCwgKHNob3J0KSA5KTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkIGluZGV4IGZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICBBcnJheS5zZXRTaG9ydChudWxsLCAwLCAoc2hvcnQpMCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmICghdGhyb3duKSB7CisgICAgICAgICAgICBmYWlsKCJOdWxsIGFyZ3VtZW50IGZhaWxlZCB0byB0aHJvdyBOUEUiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdXAgdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBvcGVuIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzIG1ldGhvZAorICAgICAqIGlzIGNhbGxlZCBiZWZvcmUgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvQm91bmRlZEdlbmVyaWNNZXRob2RzVGVzdHMuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvQm91bmRlZEdlbmVyaWNNZXRob2RzVGVzdHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OTQ5YTMwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvcmVmbGVjdC9Cb3VuZGVkR2VuZXJpY01ldGhvZHNUZXN0cy5qYXZhCkBAIC0wLDAgKzEsMTI4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5UeXBlVmFyaWFibGU7CisKKy8qKgorICogVGVzdHMgYm91bmRlZCB0eXBlIHBhcmFtZXRlcnMgZGVjbGFyZWQgb24gbWV0aG9kcy4KKyAqLworcHVibGljIGNsYXNzIEJvdW5kZWRHZW5lcmljTWV0aG9kc1Rlc3RzIGV4dGVuZHMgR2VuZXJpY1JlZmxlY3Rpb25UZXN0c0Jhc2UgeworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHN0YXRpYyBjbGFzcyBCb3VuZGVkR2VuZXJpY01ldGhvZHM8Uz4geworCisgICAgICAgIHB1YmxpYyA8VCBleHRlbmRzIEJvdW5kZWRHZW5lcmljTWV0aG9kcz4gdm9pZCBub1BhcmFtTm9SZXR1cm4oKSB7fQorICAgICAgICBwdWJsaWMgPFQgZXh0ZW5kcyBCb3VuZGVkR2VuZXJpY01ldGhvZHM+IHZvaWQgcGFyYW1Ob1JldHVybihUIHBhcmFtKSB7fQorCisgICAgICAgIHB1YmxpYyA8VCBleHRlbmRzIEJvdW5kZWRHZW5lcmljTWV0aG9kcz4gVCBub1BhcmFtUmV0dXJuKCkgeworICAgICAgICAgICAgcmV0dXJuIChUKSBuZXcgT2JqZWN0KCk7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIDxUIGV4dGVuZHMgQm91bmRlZEdlbmVyaWNNZXRob2RzPiBUIHBhcmFtUmV0dXJuKFQgdCkgeworICAgICAgICAgICAgcmV0dXJuIHQ7CisgICAgICAgIH0KKyAgICB9CisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHJpdmF0ZSBzdGF0aWMgQ2xhc3M8PyBleHRlbmRzIEJvdW5kZWRHZW5lcmljTWV0aG9kcz4gY2xhenogPSBCb3VuZGVkR2VuZXJpY01ldGhvZHNUZXN0cy5Cb3VuZGVkR2VuZXJpY01ldGhvZHMuY2xhc3M7CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB3aGV0aGVyIHRoZSB0eXBlIHBhcmFtZXRlciBpcyB1cHBlciBib3VuZGVkIGJ5IEJvdW5kZWRHZW5lcmljTWV0aG9kcy4KKyAgICAgKiA8VCBleHRlbmRzIEJvdW5kZWRHZW5lcmljTWV0aG9kcz4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWV0aG9kCisgICAgICogICAgICAgICAgICB0aGUgZGVjbGFyaW5nIG1ldGhvZAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjaGVja0JvdW5kZWRUeXBlUGFyYW1ldGVyKE1ldGhvZCBtZXRob2QpIHsKKyAgICAgICAgVHlwZVZhcmlhYmxlPE1ldGhvZD4gdHlwZVBhcmFtZXRlciA9IGdldFR5cGVQYXJhbWV0ZXIobWV0aG9kKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUIiwgdHlwZVBhcmFtZXRlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobWV0aG9kLCB0eXBlUGFyYW1ldGVyLmdldEdlbmVyaWNEZWNsYXJhdGlvbigpKTsKKworICAgICAgICBUeXBlW10gYm91bmRzID0gdHlwZVBhcmFtZXRlci5nZXRCb3VuZHMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGJvdW5kcyk7CisgICAgICAgIFR5cGUgYm91bmQgPSBib3VuZHNbMF07CisgICAgICAgIGFzc2VydEVxdWFscyhCb3VuZGVkR2VuZXJpY01ldGhvZHMuY2xhc3MsIGJvdW5kKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgbWV0aG9kIGRlY2xhcmVzIGEgcGFyYW1ldGVyIHdpdGggdGhlIHR5cGUgb2YKKyAgICAgKiB0aGUgdHlwZSBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWV0aG9kCisgICAgICogICAgICAgICAgICB0aGUgZGVjbGFyaW5nIG1ldGhvZAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwYXJhbWV0ZXJUeXBlKE1ldGhvZCBtZXRob2QpIHsKKyAgICAgICAgVHlwZVZhcmlhYmxlPE1ldGhvZD4gdHlwZVBhcmFtZXRlciA9IGdldFR5cGVQYXJhbWV0ZXIobWV0aG9kKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKG1ldGhvZC5nZXRHZW5lcmljUGFyYW1ldGVyVHlwZXMoKSk7CisgICAgICAgIFR5cGUgZ2VuZXJpY1BhcmFtZXRlclR5cGUgPSBtZXRob2QuZ2V0R2VuZXJpY1BhcmFtZXRlclR5cGVzKClbMF07CisgICAgICAgIGFzc2VydEVxdWFscyh0eXBlUGFyYW1ldGVyLCBnZW5lcmljUGFyYW1ldGVyVHlwZSk7CisgICAgICAgIGFzc2VydFRydWUoZ2VuZXJpY1BhcmFtZXRlclR5cGUgaW5zdGFuY2VvZiBUeXBlVmFyaWFibGUpOworICAgICAgICBUeXBlVmFyaWFibGU8Pz4gdHlwZVZhcmlhYmxlID0gKFR5cGVWYXJpYWJsZTw/PikgZ2VuZXJpY1BhcmFtZXRlclR5cGU7CisgICAgICAgIGFzc2VydEVxdWFscyhtZXRob2QsIHR5cGVWYXJpYWJsZS5nZXRHZW5lcmljRGVjbGFyYXRpb24oKSk7CisKKyAgICAgICAgVHlwZVtdIHBhcmFtQm91bmRzID0gdHlwZVZhcmlhYmxlLmdldEJvdW5kcygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUocGFyYW1Cb3VuZHMpOworICAgICAgICBUeXBlIHBhcmFtQm91bmQgPSBwYXJhbUJvdW5kc1swXTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJvdW5kZWRHZW5lcmljTWV0aG9kcy5jbGFzcywgcGFyYW1Cb3VuZCk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrUmV0dXJuVHlwZShNZXRob2QgbWV0aG9kKSB7CisgICAgICAgIFR5cGUgZ2VuZXJpY1JldHVyblR5cGUgPSBtZXRob2QuZ2V0R2VuZXJpY1JldHVyblR5cGUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGdldFR5cGVQYXJhbWV0ZXIobWV0aG9kKSwgZ2VuZXJpY1JldHVyblR5cGUpOworICAgICAgICBhc3NlcnRUcnVlKGdlbmVyaWNSZXR1cm5UeXBlIGluc3RhbmNlb2YgVHlwZVZhcmlhYmxlKTsKKworICAgICAgICBUeXBlVmFyaWFibGU8TWV0aG9kPiByZXR1cm5UeXBlVmFyaWFibGUgPSAoVHlwZVZhcmlhYmxlPE1ldGhvZD4pIGdlbmVyaWNSZXR1cm5UeXBlOworICAgICAgICBhc3NlcnRFcXVhbHMobWV0aG9kLCByZXR1cm5UeXBlVmFyaWFibGUuZ2V0R2VuZXJpY0RlY2xhcmF0aW9uKCkpOworCisgICAgICAgIFR5cGVbXSBib3VuZHMgPSByZXR1cm5UeXBlVmFyaWFibGUuZ2V0Qm91bmRzKCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZShib3VuZHMpOworICAgICAgICBUeXBlIGJvdW5kID0gYm91bmRzWzBdOworCisgICAgICAgIGFzc2VydEVxdWFscyhCb3VuZGVkR2VuZXJpY01ldGhvZHMuY2xhc3MsIGJvdW5kKTsKKyAgICB9CisKKworCisgICAgLyoqCisgICAgICogVGVzdHMgdGhhdCB0aGVyZSBhcmUgaXMgb25lIFR5cGUgUGFyYW1ldGVyIG9uIHRoZSBDbGFzcyBpdHNlbGYuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEJvdW5kZWRHZW5lcmljTWV0aG9kcygpIHsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGNsYXp6LmdldFR5cGVQYXJhbWV0ZXJzKCkpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9QYXJhbU5vUmV0dXJuKCkgdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uLCBOb1N1Y2hNZXRob2RFeGNlcHRpb24geworICAgICAgICBNZXRob2QgbWV0aG9kID0gY2xhenouZ2V0TWV0aG9kKCJub1BhcmFtTm9SZXR1cm4iKTsKKyAgICAgICAgY2hlY2tCb3VuZGVkVHlwZVBhcmFtZXRlcihtZXRob2QpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VW5ib3VuZGVkUGFyYW1Ob1JldHVybigpIHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiwgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IGNsYXp6LmdldE1ldGhvZCgicGFyYW1Ob1JldHVybiIsIEJvdW5kZWRHZW5lcmljTWV0aG9kcy5jbGFzcyk7CisgICAgICAgIGNoZWNrQm91bmRlZFR5cGVQYXJhbWV0ZXIobWV0aG9kKTsKKyAgICAgICAgcGFyYW1ldGVyVHlwZShtZXRob2QpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9QYXJhbVJldHVybigpIHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiwgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IGNsYXp6LmdldE1ldGhvZCgibm9QYXJhbVJldHVybiIpOworICAgICAgICBjaGVja0JvdW5kZWRUeXBlUGFyYW1ldGVyKG1ldGhvZCk7CisgICAgICAgIGFzc2VydExlbmdodFplcm8obWV0aG9kLmdldEdlbmVyaWNQYXJhbWV0ZXJUeXBlcygpKTsKKyAgICAgICAgY2hlY2tSZXR1cm5UeXBlKG1ldGhvZCk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RVbmJvdW5kZWRQYXJhbVJldHVybigpIHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiwgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IGNsYXp6LmdldE1ldGhvZCgicGFyYW1SZXR1cm4iLCBCb3VuZGVkR2VuZXJpY01ldGhvZHMuY2xhc3MpOworICAgICAgICBjaGVja0JvdW5kZWRUeXBlUGFyYW1ldGVyKG1ldGhvZCk7CisgICAgICAgIHBhcmFtZXRlclR5cGUobWV0aG9kKTsKKyAgICAgICAgY2hlY2tSZXR1cm5UeXBlKG1ldGhvZCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvcmVmbGVjdC9Db25zdHJ1Y3RvclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvQ29uc3RydWN0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTMyMzE1YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvQ29uc3RydWN0b3JUZXN0LmphdmEKQEAgLTAsMCArMSw0NDMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEubGFuZy5yZWZsZWN0OworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5OworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5UeXBlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGVWYXJpYWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK3B1YmxpYyBjbGFzcyBDb25zdHJ1Y3RvclRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisKKyAgICBAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorICAgIEBUYXJnZXQoIHtFbGVtZW50VHlwZS5DT05TVFJVQ1RPUiwgRWxlbWVudFR5cGUuUEFSQU1FVEVSfSkKKyAgICBzdGF0aWMgQGludGVyZmFjZSBDb25zdHJ1Y3RvclRlc3RBbm5vdGF0aW9uUnVudGltZTAgeworICAgIH0KKworICAgIEBSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCisgICAgQFRhcmdldCgge0VsZW1lbnRUeXBlLkNPTlNUUlVDVE9SLCBFbGVtZW50VHlwZS5QQVJBTUVURVJ9KQorICAgIHN0YXRpYyBAaW50ZXJmYWNlIENvbnN0cnVjdG9yVGVzdEFubm90YXRpb25SdW50aW1lMSB7CisgICAgfQorCisgICAgQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuQ0xBU1MpCisgICAgQFRhcmdldCgge0VsZW1lbnRUeXBlLkNPTlNUUlVDVE9SLCBFbGVtZW50VHlwZS5QQVJBTUVURVJ9KQorICAgIHN0YXRpYyBAaW50ZXJmYWNlIENvbnN0cnVjdG9yVGVzdEFubm90YXRpb25DbGFzczAgeworICAgIH0KKworICAgIEBSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlNPVVJDRSkKKyAgICBAVGFyZ2V0KCB7RWxlbWVudFR5cGUuQ09OU1RSVUNUT1IsIEVsZW1lbnRUeXBlLlBBUkFNRVRFUn0pCisgICAgc3RhdGljIEBpbnRlcmZhY2UgQ29uc3RydWN0b3JUZXN0QW5ub3RhdGlvblNvdXJjZTAgeworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBDb25zdHJ1Y3RvclRlc3RIZWxwZXIgZXh0ZW5kcyBPYmplY3QgeworICAgICAgICBpbnQgY3ZhbDsKKworICAgICAgICBAQ29uc3RydWN0b3JUZXN0QW5ub3RhdGlvblJ1bnRpbWUwCisgICAgICAgIEBDb25zdHJ1Y3RvclRlc3RBbm5vdGF0aW9uUnVudGltZTEKKyAgICAgICAgQENvbnN0cnVjdG9yVGVzdEFubm90YXRpb25DbGFzczAKKyAgICAgICAgQENvbnN0cnVjdG9yVGVzdEFubm90YXRpb25Tb3VyY2UwCisgICAgICAgIHB1YmxpYyBDb25zdHJ1Y3RvclRlc3RIZWxwZXIoKSB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBjdmFsID0gOTk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgQ29uc3RydWN0b3JUZXN0SGVscGVyKAorICAgICAgICAgICAgICAgIEBDb25zdHJ1Y3RvclRlc3RBbm5vdGF0aW9uUnVudGltZTAKKyAgICAgICAgICAgICAgICBAQ29uc3RydWN0b3JUZXN0QW5ub3RhdGlvblJ1bnRpbWUxCisgICAgICAgICAgICAgICAgQENvbnN0cnVjdG9yVGVzdEFubm90YXRpb25DbGFzczAKKyAgICAgICAgICAgICAgICBAQ29uc3RydWN0b3JUZXN0QW5ub3RhdGlvblNvdXJjZTAgT2JqZWN0IHgpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBDb25zdHJ1Y3RvclRlc3RIZWxwZXIoU3RyaW5nLi4uIHgpIHsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgQ29uc3RydWN0b3JUZXN0SGVscGVyKGludCBhKSB7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgQ29uc3RydWN0b3JUZXN0SGVscGVyKGxvbmcgYSkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBjaGVjaygpIHsKKyAgICAgICAgICAgIHJldHVybiBjdmFsOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIEdlbmVyaWNDb25zdHJ1Y3RvclRlc3RIZWxwZXI8VCwgUyBleHRlbmRzIFQsIEUgZXh0ZW5kcyBFeGNlcHRpb24+IHsKKyAgICAgICAgcHVibGljIEdlbmVyaWNDb25zdHJ1Y3RvclRlc3RIZWxwZXIoVCB0LCBTIHMpIHt9CisgICAgICAgIHB1YmxpYyBHZW5lcmljQ29uc3RydWN0b3JUZXN0SGVscGVyKCkgdGhyb3dzIEV7fQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBOb1B1YmxpY0NvbnN0cnVjdG9yVGVzdEhlbHBlciB7CisgICAgICAgIC8vIFRoaXMgY2xhc3MgaGFzIG5vIHB1YmxpYyBjb25zdHJ1Y3Rvci4KKyAgICB9CisKKy8vICAgIFVzZWQgdG8gdGVzdCBzeW50aGV0aWMgY29uc3RydWN0b3IuCisvLworLy8gICAgc3RhdGljIGNsYXNzIE91dGVyIHsKKy8vICAgICAgICBwcml2YXRlIE91dGVyKCl7fQorLy8gICAgICAgIGNsYXNzIElubmVyIHsKKy8vICAgICAgICAgICAge25ldyBPdXRlcigpO30KKy8vICAgICAgICB9CisvLyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFBhcmFtZXRlckFubm90YXRpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENvbnN0cnVjdG9yPENvbnN0cnVjdG9yVGVzdEhlbHBlcj4gY3RvcjEgPSBDb25zdHJ1Y3RvclRlc3RIZWxwZXIuY2xhc3MKKyAgICAgICAgICAgICAgICAuZ2V0Q29uc3RydWN0b3IoT2JqZWN0LmNsYXNzKTsKKyAgICAgICAgQW5ub3RhdGlvbltdW10gcGFyYW1Bbm5vdGF0aW9ucyA9IGN0b3IxLmdldFBhcmFtZXRlckFubm90YXRpb25zKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQW5ub3RhdGlvbnMgZm9yIHdyb25nIG51bWJlciBvZiBwYXJhbWV0ZXJzIHJldHVybmVkIiwgMSwKKyAgICAgICAgICAgICAgICBwYXJhbUFubm90YXRpb25zLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGFubm90YXRpb25zIHJldHVybmVkIiwgMiwKKyAgICAgICAgICAgICAgICBwYXJhbUFubm90YXRpb25zWzBdLmxlbmd0aCk7CisKKyAgICAgICAgU2V0PENsYXNzPD8+PiBpZ25vcmVPcmRlciA9IG5ldyBIYXNoU2V0PENsYXNzPD8+PigpOworICAgICAgICBpZ25vcmVPcmRlci5hZGQocGFyYW1Bbm5vdGF0aW9uc1swXVswXS5hbm5vdGF0aW9uVHlwZSgpKTsKKyAgICAgICAgaWdub3JlT3JkZXIuYWRkKHBhcmFtQW5ub3RhdGlvbnNbMF1bMV0uYW5ub3RhdGlvblR5cGUoKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTWlzc2luZyBDb25zdHJ1Y3RvclRlc3RBbm5vdGF0aW9uUnVudGltZTAiLCBpZ25vcmVPcmRlcgorICAgICAgICAgICAgICAgIC5jb250YWlucyhDb25zdHJ1Y3RvclRlc3RBbm5vdGF0aW9uUnVudGltZTAuY2xhc3MpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTWlzc2luZyBDb25zdHJ1Y3RvclRlc3RBbm5vdGF0aW9uUnVudGltZTEiLCBpZ25vcmVPcmRlcgorICAgICAgICAgICAgICAgIC5jb250YWlucyhDb25zdHJ1Y3RvclRlc3RBbm5vdGF0aW9uUnVudGltZTEuY2xhc3MpKTsKKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGVjbGFyZWRBbm5vdGF0aW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDb25zdHJ1Y3RvcjxDb25zdHJ1Y3RvclRlc3RIZWxwZXI+IGN0b3IxID0gbnVsbDsKKyAgICAgICAgY3RvcjEgPSBDb25zdHJ1Y3RvclRlc3RIZWxwZXIuY2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzWzBdKTsKKyAgICAgICAgQW5ub3RhdGlvbltdIGFubm90YXRpb25zID0gY3RvcjEuZ2V0RGVjbGFyZWRBbm5vdGF0aW9ucygpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBhbm5vdGF0aW9ucyByZXR1cm5lZCIsIDIsCisgICAgICAgICAgICAgICAgYW5ub3RhdGlvbnMubGVuZ3RoKTsKKyAgICAgICAgU2V0PENsYXNzPD8+PiBpZ25vcmVPcmRlciA9IG5ldyBIYXNoU2V0PENsYXNzPD8+PigpOworICAgICAgICBpZ25vcmVPcmRlci5hZGQoYW5ub3RhdGlvbnNbMF0uYW5ub3RhdGlvblR5cGUoKSk7CisgICAgICAgIGlnbm9yZU9yZGVyLmFkZChhbm5vdGF0aW9uc1sxXS5hbm5vdGF0aW9uVHlwZSgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJNaXNzaW5nIENvbnN0cnVjdG9yVGVzdEFubm90YXRpb25SdW50aW1lMCIsIGlnbm9yZU9yZGVyCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKENvbnN0cnVjdG9yVGVzdEFubm90YXRpb25SdW50aW1lMC5jbGFzcykpOworICAgICAgICBhc3NlcnRUcnVlKCJNaXNzaW5nIENvbnN0cnVjdG9yVGVzdEFubm90YXRpb25SdW50aW1lMSIsIGlnbm9yZU9yZGVyCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKENvbnN0cnVjdG9yVGVzdEFubm90YXRpb25SdW50aW1lMS5jbGFzcykpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNWYXJBcmdzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENvbnN0cnVjdG9yPENvbnN0cnVjdG9yVGVzdEhlbHBlcj4gdmFyQXJnQ3RvciA9IENvbnN0cnVjdG9yVGVzdEhlbHBlci5jbGFzcworICAgICAgICAgICAgICAgIC5nZXRDb25zdHJ1Y3RvcihTdHJpbmdbXS5jbGFzcyk7CisgICAgICAgIGFzc2VydFRydWUoIlZhcmFyZyBjb25zdHJ1Y3RvciBub3QgcmVjb2duaXplZCIsIHZhckFyZ0N0b3IuaXNWYXJBcmdzKCkpOworCisgICAgICAgIENvbnN0cnVjdG9yPENvbnN0cnVjdG9yVGVzdEhlbHBlcj4gbm9uVmFyQXJnQ3RvciA9IENvbnN0cnVjdG9yVGVzdEhlbHBlci5jbGFzcworICAgICAgICAgICAgICAgIC5nZXRDb25zdHJ1Y3RvcihPYmplY3QuY2xhc3MpOworICAgICAgICBhc3NlcnRGYWxzZSgiTm9uIHZhcmFyZyBjb25zdHJ1Y3RvciByZWNvZ25pemVkIGFzIHZhcmFyZyBjb25zdHJ1Y3RvciIsCisgICAgICAgICAgICAgICAgbm9uVmFyQXJnQ3Rvci5pc1ZhckFyZ3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDb25zdHJ1Y3RvcjxDb25zdHJ1Y3RvclRlc3RIZWxwZXI+IGNvbnN0cnVjdG9yID0gQ29uc3RydWN0b3JUZXN0SGVscGVyLmNsYXNzCisgICAgICAgICAgICAgICAgLmdldENvbnN0cnVjdG9yKCk7CisgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAiVGhlIGNvbnN0cnVjdG9yJ3MgaGFzaENvZGUgaXMgbm90IGVxdWFsIHRvIHRoZSBoYXNoQ29kZSBvZiB0aGUgbmFtZSBvZiB0aGUgZGVjbGFyaW5nIGNsYXNzIiwKKyAgICAgICAgICAgICAgICBDb25zdHJ1Y3RvclRlc3RIZWxwZXIuY2xhc3MuZ2V0TmFtZSgpLmhhc2hDb2RlKCksIGNvbnN0cnVjdG9yCisgICAgICAgICAgICAgICAgICAgICAgICAuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdF90b0dlbmVyaWNTdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ29uc3RydWN0b3I8R2VuZXJpY0NvbnN0cnVjdG9yVGVzdEhlbHBlcj4gZ2VuZXJpY0N0b3IgPSBHZW5lcmljQ29uc3RydWN0b3JUZXN0SGVscGVyLmNsYXNzCisgICAgICAgICAgICAgICAgLmdldENvbnN0cnVjdG9yKE9iamVjdC5jbGFzcywgT2JqZWN0LmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICJXcm9uZyBnZW5lcmljIHN0cmluZyByZXR1cm5lZCIsCisgICAgICAgICAgICAgICAgInB1YmxpYyB0ZXN0cy5hcGkuamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3JUZXN0JEdlbmVyaWNDb25zdHJ1Y3RvclRlc3RIZWxwZXIoVCxTKSIsCisgICAgICAgICAgICAgICAgZ2VuZXJpY0N0b3IudG9HZW5lcmljU3RyaW5nKCkpOworICAgICAgICBDb25zdHJ1Y3RvcjxHZW5lcmljQ29uc3RydWN0b3JUZXN0SGVscGVyPiBjdG9yID0gR2VuZXJpY0NvbnN0cnVjdG9yVGVzdEhlbHBlci5jbGFzcworICAgICAgICAgICAgICAgIC5nZXRDb25zdHJ1Y3RvcigpOworICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgIldyb25nIGdlbmVyaWMgc3RyaW5nIHJldHVybmVkIiwKKyAgICAgICAgICAgICAgICAicHVibGljIHRlc3RzLmFwaS5qYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvclRlc3QkR2VuZXJpY0NvbnN0cnVjdG9yVGVzdEhlbHBlcigpIHRocm93cyBFIiwKKyAgICAgICAgICAgICAgICBjdG9yLnRvR2VuZXJpY1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VxdWFsc0xqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICBDb25zdHJ1Y3RvcjxDb25zdHJ1Y3RvclRlc3RIZWxwZXI+IGN0b3IxID0gbnVsbCwgY3RvcjIgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY3RvcjEgPSBDb25zdHJ1Y3RvclRlc3RIZWxwZXIuY2xhc3MuZ2V0Q29uc3RydWN0b3IoCisgICAgICAgICAgICAgICAgICAgIG5ldyBDbGFzc1swXSk7CisgICAgICAgICAgICBjdG9yMiA9IENvbnN0cnVjdG9yVGVzdEhlbHBlci5jbGFzcy5nZXRDb25zdHJ1Y3RvcihPYmplY3QuY2xhc3MpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBlcXVhbHMgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRGlmZmVyZW50IENvbnRydWN0b3JzIHJldHVybmVkIGVxdWFsIiwgIWN0b3IxLmVxdWFscyhjdG9yMikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGVjbGFyaW5nQ2xhc3MoKSB7CisgICAgICAgIGJvb2xlYW4gdmFsID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDbGFzczw/IGV4dGVuZHMgQ29uc3RydWN0b3JUZXN0SGVscGVyPiBwY2xhc3MgPSBuZXcgQ29uc3RydWN0b3JUZXN0SGVscGVyKCkuZ2V0Q2xhc3MoKTsKKyAgICAgICAgICAgIENvbnN0cnVjdG9yPD8gZXh0ZW5kcyBDb25zdHJ1Y3RvclRlc3RIZWxwZXI+IGN0b3IgPSBwY2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzWzBdKTsKKyAgICAgICAgICAgIHZhbCA9IGN0b3IuZ2V0RGVjbGFyaW5nQ2xhc3MoKS5lcXVhbHMocGNsYXNzKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGRlY2xhcmluZyBjbGFzcyIsIHZhbCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRFeGNlcHRpb25UeXBlcygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5DbGFzcyBbXQorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3Rvci5nZXRFeGNlcHRpb25UeXBlcygpCisgICAgICAgIENsYXNzW10gZXhjZXB0aW9ucyA9IG51bGw7CisgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uPiBleCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb25zdHJ1Y3Rvcjw/IGV4dGVuZHMgQ29uc3RydWN0b3JUZXN0SGVscGVyPiBjdG9yID0gbmV3IENvbnN0cnVjdG9yVGVzdEhlbHBlcigpLmdldENsYXNzKCkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1swXSk7CisgICAgICAgICAgICBleGNlcHRpb25zID0gY3Rvci5nZXRFeGNlcHRpb25UeXBlcygpOworICAgICAgICAgICAgZXggPSBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpLmdldENsYXNzKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgZXhjZXB0aW9uIGxpc3Qgb2YgaW5jb3JyZWN0IGxlbmd0aCIsCisgICAgICAgICAgICAgICAgMSwgZXhjZXB0aW9ucy5sZW5ndGgpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgZXhjZXB0aW9uIiwgZXhjZXB0aW9uc1swXS5lcXVhbHMoZXgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1vZGlmaWVycygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3Rvci5nZXRNb2RpZmllcnMoKQorICAgICAgICBpbnQgbW9kID0gMDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbnN0cnVjdG9yPD8gZXh0ZW5kcyBDb25zdHJ1Y3RvclRlc3RIZWxwZXI+IGN0b3IgPSBuZXcgQ29uc3RydWN0b3JUZXN0SGVscGVyKCkuZ2V0Q2xhc3MoKQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzWzBdKTsKKyAgICAgICAgICAgIG1vZCA9IGN0b3IuZ2V0TW9kaWZpZXJzKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgbW9kaWZlcnMgZm9yIHB1YmxpYyBjdG9yIiwKKyAgICAgICAgICAgICAgICAgICAgKChtb2QgJiBNb2RpZmllci5QVUJMSUMpID09IE1vZGlmaWVyLlBVQkxJQykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAoKG1vZCAmIE1vZGlmaWVyLlBSSVZBVEUpID09IDApKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENsYXNzW10gY2wgPSB7IGludC5jbGFzcyB9OworICAgICAgICAgICAgQ29uc3RydWN0b3I8PyBleHRlbmRzIENvbnN0cnVjdG9yVGVzdEhlbHBlcj4gY3RvciA9IG5ldyBDb25zdHJ1Y3RvclRlc3RIZWxwZXIoKS5nZXRDbGFzcygpCisgICAgICAgICAgICAgICAgICAgIC5nZXREZWNsYXJlZENvbnN0cnVjdG9yKGNsKTsKKyAgICAgICAgICAgIG1vZCA9IGN0b3IuZ2V0TW9kaWZpZXJzKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgbW9kaWZlcnMgZm9yIHByaXZhdGUgY3RvciIsCisgICAgICAgICAgICAgICAgICAgICgobW9kICYgTW9kaWZpZXIuUFJJVkFURSkgPT0gTW9kaWZpZXIuUFJJVkFURSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAoKG1vZCAmIE1vZGlmaWVyLlBVQkxJQykgPT0gMCkpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3NbXSBjbCA9IHsgbG9uZy5jbGFzcyB9OworICAgICAgICAgICAgQ29uc3RydWN0b3I8PyBleHRlbmRzIENvbnN0cnVjdG9yVGVzdEhlbHBlcj4gY3RvciA9IG5ldyBDb25zdHJ1Y3RvclRlc3RIZWxwZXIoKS5nZXRDbGFzcygpCisgICAgICAgICAgICAgICAgICAgIC5nZXREZWNsYXJlZENvbnN0cnVjdG9yKGNsKTsKKyAgICAgICAgICAgIG1vZCA9IGN0b3IuZ2V0TW9kaWZpZXJzKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgbW9kaWZlcnMgZm9yIHByaXZhdGUgY3RvciIsCisgICAgICAgICAgICAgICAgICAgICgobW9kICYgTW9kaWZpZXIuUFJPVEVDVEVEKSA9PSBNb2RpZmllci5QUk9URUNURUQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKChtb2QgJiBNb2RpZmllci5QVUJMSUMpID09IDApKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBkdXJpbmcgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE5hbWUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuU3RyaW5nCisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yLmdldE5hbWUoKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29uc3RydWN0b3I8PyBleHRlbmRzIENvbnN0cnVjdG9yVGVzdEhlbHBlcj4gY3RvciA9IG5ldyBDb25zdHJ1Y3RvclRlc3RIZWxwZXIoKS5nZXRDbGFzcygpCisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbMF0pOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlJldHVybmVkIGluY29ycmVjdCBuYW1lOiAiICsgY3Rvci5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgIGN0b3IKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0ZXN0cy5hcGkuamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3JUZXN0JENvbnN0cnVjdG9yVGVzdEhlbHBlciIpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBvYnRhaW5pbmcgY29udHJ1Y3RvciA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFBhcmFtZXRlclR5cGVzKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLkNsYXNzIFtdCisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yLmdldFBhcmFtZXRlclR5cGVzKCkKKyAgICAgICAgQ2xhc3NbXSB0eXBlcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb25zdHJ1Y3Rvcjw/IGV4dGVuZHMgQ29uc3RydWN0b3JUZXN0SGVscGVyPiBjdG9yID0gbmV3IENvbnN0cnVjdG9yVGVzdEhlbHBlcigpLmdldENsYXNzKCkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1swXSk7CisgICAgICAgICAgICB0eXBlcyA9IGN0b3IuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0UGFyYW1ldGVyVHlwZXMgdGVzdDoiCisgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwYXJhbWV0ZXIgcmV0dXJuZWQiLCAwLCB0eXBlcy5sZW5ndGgpOworCisgICAgICAgIENsYXNzW10gcGFybXMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFybXMgPSBuZXcgQ2xhc3NbMV07CisgICAgICAgICAgICBwYXJtc1swXSA9IG5ldyBPYmplY3QoKS5nZXRDbGFzcygpOworICAgICAgICAgICAgQ29uc3RydWN0b3I8PyBleHRlbmRzIENvbnN0cnVjdG9yVGVzdEhlbHBlcj4gY3RvciA9IG5ldyBDb25zdHJ1Y3RvclRlc3RIZWxwZXIoKS5nZXRDbGFzcygpCisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25zdHJ1Y3RvcihwYXJtcyk7CisgICAgICAgICAgICB0eXBlcyA9IGN0b3IuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0UGFyYW1ldGVyVHlwZXMgdGVzdDoiCisgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcGFyYW1ldGVyIHJldHVybmVkIiwgdHlwZXNbMF0uZXF1YWxzKHBhcm1zWzBdKSk7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRHZW5lcmljUGFyYW1ldGVyVHlwZXMoKSB7CisgICAgICAgIFR5cGVbXSB0eXBlcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb25zdHJ1Y3Rvcjw/IGV4dGVuZHMgQ29uc3RydWN0b3JUZXN0SGVscGVyPiBjdG9yID0gbmV3IENvbnN0cnVjdG9yVGVzdEhlbHBlcigpCisgICAgICAgICAgICAgICAgICAgIC5nZXRDbGFzcygpLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1swXSk7CisgICAgICAgICAgICB0eXBlcyA9IGN0b3IuZ2V0R2VuZXJpY1BhcmFtZXRlclR5cGVzKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldFBhcmFtZXRlclR5cGVzIHRlc3Q6IiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcGFyYW1ldGVyIHJldHVybmVkIiwgMCwgdHlwZXMubGVuZ3RoKTsKKworICAgICAgICBDbGFzczw/PltdIHBhcm1zID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcm1zID0gbmV3IENsYXNzW10ge09iamVjdC5jbGFzc307CisgICAgICAgICAgICBDb25zdHJ1Y3Rvcjw/IGV4dGVuZHMgQ29uc3RydWN0b3JUZXN0SGVscGVyPiBjdG9yID0gbmV3IENvbnN0cnVjdG9yVGVzdEhlbHBlcigpCisgICAgICAgICAgICAgICAgICAgIC5nZXRDbGFzcygpLmdldENvbnN0cnVjdG9yKHBhcm1zKTsKKyAgICAgICAgICAgIHR5cGVzID0gY3Rvci5nZXRHZW5lcmljUGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0UGFyYW1ldGVyVHlwZXMgdGVzdDoiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcGFyYW1ldGVyIHJldHVybmVkIiwgdHlwZXNbMF0uZXF1YWxzKHBhcm1zWzBdKSk7CisKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29uc3RydWN0b3I8R2VuZXJpY0NvbnN0cnVjdG9yVGVzdEhlbHBlcj4gY29uc3RydWN0b3IgPSBHZW5lcmljQ29uc3RydWN0b3JUZXN0SGVscGVyLmNsYXNzCisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25zdHJ1Y3RvcihPYmplY3QuY2xhc3MsIE9iamVjdC5jbGFzcyk7CisgICAgICAgICAgICB0eXBlcyA9IGNvbnN0cnVjdG9yLmdldEdlbmVyaWNQYXJhbWV0ZXJUeXBlcygpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXRQYXJhbWV0ZXJUeXBlcyB0ZXN0OiIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcGFyYW1ldGVyIHR5cGVzIHJldHVybmVkIiwgMiwKKyAgICAgICAgICAgICAgICB0eXBlcy5sZW5ndGgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIHBhcmFtZXRlciB0eXBlcyByZXR1cm5lZCIsICJUIiwKKyAgICAgICAgICAgICAgICAoKFR5cGVWYXJpYWJsZSl0eXBlc1swXSkuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcGFyYW1ldGVyIHR5cGVzIHJldHVybmVkIiwgIlMiLAorICAgICAgICAgICAgICAgICgoVHlwZVZhcmlhYmxlKXR5cGVzWzFdKS5nZXROYW1lKCkpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0R2VuZXJpY0V4Y2VwdGlvblR5cGVzKCkgeworICAgICAgICBUeXBlW10gdHlwZXMgPSBudWxsOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb25zdHJ1Y3Rvcjw/IGV4dGVuZHMgQ29uc3RydWN0b3JUZXN0SGVscGVyPiBjdG9yID0gbmV3IENvbnN0cnVjdG9yVGVzdEhlbHBlcigpCisgICAgICAgICAgICAgICAgICAgIC5nZXRDbGFzcygpLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1swXSk7CisgICAgICAgICAgICB0eXBlcyA9IGN0b3IuZ2V0R2VuZXJpY0V4Y2VwdGlvblR5cGVzKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldEdlbmVyaWNFeGNlcHRpb25UeXBlcyB0ZXN0OiIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGV4Y2VwdGlvbiB0eXBlcyByZXR1cm5lZCIsIDEsIHR5cGVzLmxlbmd0aCk7CisKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29uc3RydWN0b3I8R2VuZXJpY0NvbnN0cnVjdG9yVGVzdEhlbHBlcj4gY29uc3RydWN0b3IgPSBHZW5lcmljQ29uc3RydWN0b3JUZXN0SGVscGVyLmNsYXNzCisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25zdHJ1Y3RvcigpOworICAgICAgICAgICAgdHlwZXMgPSBjb25zdHJ1Y3Rvci5nZXRHZW5lcmljRXhjZXB0aW9uVHlwZXMoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0R2VuZXJpY0V4Y2VwdGlvblR5cGVzIHRlc3Q6IgorICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBleGNlcHRpb24gdHlwZXMgcmV0dXJuZWQiLCAxLAorICAgICAgICAgICAgICAgIHR5cGVzLmxlbmd0aCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBleGNlcHRpb24gbmFtZSByZXR1cm5lZC4iLCAiRSIsCisgICAgICAgICAgICAgICAgKChUeXBlVmFyaWFibGUpdHlwZXNbMF0pLmdldE5hbWUoKSk7CisKKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbmV3SW5zdGFuY2UkTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0CisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yLm5ld0luc3RhbmNlKGphdmEubGFuZy5PYmplY3QgW10pCisKKyAgICAgICAgQ29uc3RydWN0b3JUZXN0SGVscGVyIHRlc3QgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29uc3RydWN0b3I8PyBleHRlbmRzIENvbnN0cnVjdG9yVGVzdEhlbHBlcj4gY3RvciA9IG5ldyBDb25zdHJ1Y3RvclRlc3RIZWxwZXIoKS5nZXRDbGFzcygpCisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25zdHJ1Y3RvcihuZXcgQ2xhc3NbMF0pOworICAgICAgICAgICAgdGVzdCA9IGN0b3IubmV3SW5zdGFuY2UoKE9iamVjdFtdKW51bGwpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRmFpbGVkIHRvIGNyZWF0ZSBpbnN0YW5jZSA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbXByb3BlciBpbnN0YW5jZSBjcmVhdGVkIiwgOTksIHRlc3QuY2hlY2soKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90b1N0cmluZygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcKKyAgICAgICAgLy8gamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3IudG9TdHJpbmcoKQorICAgICAgICBDbGFzc1tdIHBhcm1zID0gbnVsbDsKKyAgICAgICAgQ29uc3RydWN0b3I8PyBleHRlbmRzIENvbnN0cnVjdG9yVGVzdEhlbHBlcj4gY3RvciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJtcyA9IG5ldyBDbGFzc1sxXTsKKyAgICAgICAgICAgIHBhcm1zWzBdID0gbmV3IE9iamVjdCgpLmdldENsYXNzKCk7CisgICAgICAgICAgICBjdG9yID0gbmV3IENvbnN0cnVjdG9yVGVzdEhlbHBlcigpLmdldENsYXNzKCkuZ2V0Q29uc3RydWN0b3IocGFybXMpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXRQYXJhbWV0ZXJUeXBlcyB0ZXN0OiIKKyAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIlJldHVybmVkIGluY29ycmVjdCBzdHJpbmcgcmVwcmVzZW50YXRpb246ICIgKyBjdG9yLnRvU3RyaW5nKCksCisgICAgICAgICAgICAgICAgY3RvcgorICAgICAgICAgICAgICAgICAgICAgICAgLnRvU3RyaW5nKCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwdWJsaWMgdGVzdHMuYXBpLmphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yVGVzdCRDb25zdHJ1Y3RvclRlc3RIZWxwZXIoamF2YS5sYW5nLk9iamVjdCkiKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDb25zdHJ1Y3RvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBQYXNzaW5nIG5ldyBDbGFzc1swXSBzaG91bGQgYmUgZXF1aXZhbGVudCB0byAoQ2xhc3NbXSkgbnVsbC4KKyAgICAgICAgQ2xhc3M8Q29uc3RydWN0b3JUZXN0SGVscGVyPiBjMiA9IENvbnN0cnVjdG9yVGVzdEhlbHBlci5jbGFzczsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGMyLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1swXSksIGMyLmdldENvbnN0cnVjdG9yKChDbGFzc1tdKSBudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjMi5nZXREZWNsYXJlZENvbnN0cnVjdG9yKG5ldyBDbGFzc1swXSksCisgICAgICAgICAgICAgICAgICAgICBjMi5nZXREZWNsYXJlZENvbnN0cnVjdG9yKChDbGFzc1tdKSBudWxsKSk7CisKKyAgICAgICAgLy8gV2UgY2FuIGdldCBhIG5vbi1wdWJsaWMgY29uc3RydWN0b3IgdmlhIGdldERlY2xhcmVkQ29uc3RydWN0b3IuLi4KKyAgICAgICAgQ2xhc3M8Tm9QdWJsaWNDb25zdHJ1Y3RvclRlc3RIZWxwZXI+IGMxID0gTm9QdWJsaWNDb25zdHJ1Y3RvclRlc3RIZWxwZXIuY2xhc3M7CisgICAgICAgIGMxLmdldERlY2xhcmVkQ29uc3RydWN0b3IoKENsYXNzW10pIG51bGwpOworICAgICAgICAvLyAuLi5idXQgbm90IHdpdGggZ2V0Q29uc3RydWN0b3IgKHdoaWNoIG9ubHkgcmV0dXJucyBwdWJsaWMgY29uc3RydWN0b3JzKS4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMxLmdldENvbnN0cnVjdG9yKChDbGFzc1tdKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOb1N1Y2hNZXRob2RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdXAgdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBvcGVuIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzIG1ldGhvZAorICAgICAqIGlzIGNhbGxlZCBiZWZvcmUgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvRmllbGRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L0ZpZWxkVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmExY2ExNTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L0ZpZWxkVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTg2OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfRmllbGQ7CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5Bbm5vdGF0aW9uOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkluaGVyaXRlZDsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5OworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5UeXBlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGVWYXJpYWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCitwdWJsaWMgY2xhc3MgRmllbGRUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIC8vIEJFR0lOIGFuZHJvaWQtbm90ZQorICAgIC8vIFRoaXMgdGVzdCBoYWQgYSBjb3VwbGUgb2YgYnVncyBpbiBpdC4gU29tZSBwYXJ0cyBvZiB0aGUgY29kZSB3ZXJlCisgICAgLy8gdW5yZWFjaGFibGUgYmVmb3JlLiBBbHNvIHNvbWUgdGVzdHMgZXhwZWN0ZWQgdGhlIHdyb25nIGV4Y3BldGlvbnMKKyAgICAvLyB0byBiZSB0aHJvd24uIFRoaXMgdmVyc2lvbiBoYXMgYmVlbiB2YWxpZGF0ZWQgdG8gcGFzcyBvbiBhIHN0YW5kYXJkCisgICAgLy8gSkRLIDEuNS4KKyAgICAvLyBFTkQgYW5kcm9pZC1ub3RlCisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdENsYXNzIHsKKyAgICAgICAgQEFubm90YXRpb25SdW50aW1lMAorICAgICAgICBAQW5ub3RhdGlvblJ1bnRpbWUxCisgICAgICAgIEBBbm5vdGF0aW9uQ2xhc3MwCisgICAgICAgIEBBbm5vdGF0aW9uU291cmNlMAorICAgICAgICBwdWJsaWMgaW50IGFubm90YXRlZEZpZWxkOworICAgICAgICBjbGFzcyBJbm5lcnt9CisgICAgfQorCisKKyAgICBAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorICAgIEBUYXJnZXQoIHtFbGVtZW50VHlwZS5GSUVMRH0pCisgICAgc3RhdGljIEBpbnRlcmZhY2UgQW5ub3RhdGlvblJ1bnRpbWUwIHsKKyAgICB9CisKKyAgICBAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorICAgIEBUYXJnZXQoIHsgRWxlbWVudFR5cGUuRklFTER9KQorICAgIHN0YXRpYyBAaW50ZXJmYWNlIEFubm90YXRpb25SdW50aW1lMSB7CisgICAgfQorCisgICAgQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuQ0xBU1MpCisgICAgQFRhcmdldCggeyBFbGVtZW50VHlwZS5GSUVMRH0pCisgICAgc3RhdGljIEBpbnRlcmZhY2UgQW5ub3RhdGlvbkNsYXNzMCB7CisgICAgfQorCisgICAgQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuU09VUkNFKQorICAgIEBUYXJnZXQoIHtFbGVtZW50VHlwZS5GSUVMRH0pCisgICAgc3RhdGljIEBpbnRlcmZhY2UgQW5ub3RhdGlvblNvdXJjZTAgeworICAgIH0KKworICAgIEBJbmhlcml0ZWQKKyAgICBAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorICAgIEBUYXJnZXQoIHtFbGVtZW50VHlwZS5GSUVMRH0pCisgICAgc3RhdGljIEBpbnRlcmZhY2UgSW5oZXJpdGVkUnVudGltZSB7CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIEdlbmVyaWNGaWVsZDxTLCBUIGV4dGVuZHMgTnVtYmVyPiB7CisgICAgICAgIFMgZmllbGQ7CisgICAgICAgIFQgYm91bmRlZEZpZWxkOworICAgICAgICBpbnQgaW50RmllbGQ7CisgICAgfQorCisKKyAgICBzdGF0aWMgY2xhc3MgVGVzdEZpZWxkIHsKKyAgICAgICAgcHVibGljIHN0YXRpYyBpbnQgcHViZmllbGQxOworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGludCBwcml2ZmllbGQxID0gMTIzOworCisgICAgICAgIHByb3RlY3RlZCBpbnQgaW50RmllbGQgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgICAgICAgcHJvdGVjdGVkIGZpbmFsIGludCBpbnRGRmllbGQgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgICAgICAgcHJvdGVjdGVkIHN0YXRpYyBpbnQgaW50U0ZpZWxkID0gSW50ZWdlci5NQVhfVkFMVUU7CisgICAgICAgIHByaXZhdGUgZmluYWwgaW50IGludFBGRmllbGQgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKKworICAgICAgICBwcm90ZWN0ZWQgc2hvcnQgc2hvcnRGaWVsZCA9IFNob3J0Lk1BWF9WQUxVRTsKKyAgICAgICAgcHJvdGVjdGVkIGZpbmFsIHNob3J0IHNob3J0RkZpZWxkID0gU2hvcnQuTUFYX1ZBTFVFOworICAgICAgICBwcm90ZWN0ZWQgc3RhdGljIHNob3J0IHNob3J0U0ZpZWxkID0gU2hvcnQuTUFYX1ZBTFVFOworICAgICAgICBwcml2YXRlIGZpbmFsIHNob3J0IHNob3J0UEZGaWVsZCA9IFNob3J0Lk1BWF9WQUxVRTsKKworICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBib29sZWFuRmllbGQgPSB0cnVlOworICAgICAgICBwcm90ZWN0ZWQgc3RhdGljIGJvb2xlYW4gYm9vbGVhblNGaWVsZCA9IHRydWU7CisgICAgICAgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIGJvb2xlYW5GRmllbGQgPSB0cnVlOworICAgICAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gYm9vbGVhblBGRmllbGQgPSB0cnVlOworCisgICAgICAgIHByb3RlY3RlZCBieXRlIGJ5dGVGaWVsZCA9IEJ5dGUuTUFYX1ZBTFVFOworICAgICAgICBwcm90ZWN0ZWQgc3RhdGljIGJ5dGUgYnl0ZVNGaWVsZCA9IEJ5dGUuTUFYX1ZBTFVFOworICAgICAgICBwcm90ZWN0ZWQgZmluYWwgYnl0ZSBieXRlRkZpZWxkID0gQnl0ZS5NQVhfVkFMVUU7CisgICAgICAgIHByaXZhdGUgZmluYWwgYnl0ZSBieXRlUEZGaWVsZCA9IEJ5dGUuTUFYX1ZBTFVFOworCisgICAgICAgIHByb3RlY3RlZCBsb25nIGxvbmdGaWVsZCA9IExvbmcuTUFYX1ZBTFVFOworICAgICAgICBwcm90ZWN0ZWQgZmluYWwgbG9uZyBsb25nRkZpZWxkID0gTG9uZy5NQVhfVkFMVUU7CisgICAgICAgIHByb3RlY3RlZCBzdGF0aWMgbG9uZyBsb25nU0ZpZWxkID0gTG9uZy5NQVhfVkFMVUU7CisgICAgICAgIHByaXZhdGUgZmluYWwgbG9uZyBsb25nUEZGaWVsZCA9IExvbmcuTUFYX1ZBTFVFOworCisgICAgICAgIHByb3RlY3RlZCBkb3VibGUgZG91YmxlRmllbGQgPSBEb3VibGUuTUFYX1ZBTFVFOworICAgICAgICBwcm90ZWN0ZWQgc3RhdGljIGRvdWJsZSBkb3VibGVTRmllbGQgPSBEb3VibGUuTUFYX1ZBTFVFOworICAgICAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGRvdWJsZSBkb3VibGVTRkZpZWxkID0gRG91YmxlLk1BWF9WQUxVRTsKKyAgICAgICAgcHJvdGVjdGVkIGZpbmFsIGRvdWJsZSBkb3VibGVGRmllbGQgPSBEb3VibGUuTUFYX1ZBTFVFOworICAgICAgICBwcml2YXRlIGZpbmFsIGRvdWJsZSBkb3VibGVQRkZpZWxkID0gRG91YmxlLk1BWF9WQUxVRTsKKworICAgICAgICBwcm90ZWN0ZWQgZmxvYXQgZmxvYXRGaWVsZCA9IEZsb2F0Lk1BWF9WQUxVRTsKKyAgICAgICAgcHJvdGVjdGVkIGZpbmFsIGZsb2F0IGZsb2F0RkZpZWxkID0gRmxvYXQuTUFYX1ZBTFVFOworICAgICAgICBwcm90ZWN0ZWQgc3RhdGljIGZsb2F0IGZsb2F0U0ZpZWxkID0gRmxvYXQuTUFYX1ZBTFVFOworICAgICAgICBwcml2YXRlIGZpbmFsIGZsb2F0IGZsb2F0UEZGaWVsZCA9IEZsb2F0Lk1BWF9WQUxVRTsKKworICAgICAgICBwcm90ZWN0ZWQgY2hhciBjaGFyRmllbGQgPSAnVCc7CisgICAgICAgIHByb3RlY3RlZCBzdGF0aWMgY2hhciBjaGFyU0ZpZWxkID0gJ1QnOworICAgICAgICBwcml2YXRlIGZpbmFsIGNoYXIgY2hhclBGRmllbGQgPSAnVCc7CisKKyAgICAgICAgcHJvdGVjdGVkIGZpbmFsIGNoYXIgY2hhckZGaWVsZCA9ICdUJzsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgeCA9IDE7CisKKyAgICAgICAgcHVibGljIHZvbGF0aWxlIHRyYW5zaWVudCBpbnQgeSA9IDA7CisKKyAgICAgICAgcHJvdGVjdGVkIHN0YXRpYyB0cmFuc2llbnQgdm9sYXRpbGUgaW50IHByc3R0cnZvbCA9IDk5OworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBUZXN0RmllbGRTdWIxIGV4dGVuZHMgVGVzdEZpZWxkIHsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgVGVzdEZpZWxkU3ViMiBleHRlbmRzIFRlc3RGaWVsZCB7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIEEgeworICAgICAgICBwcm90ZWN0ZWQgc2hvcnQgc2hvcnRGaWVsZCA9IFNob3J0Lk1BWF9WQUxVRTsKKyAgICB9CisKKyAgICBzdGF0aWMgZW51bSBUZXN0RW51bSB7CisgICAgICAgIEEsIEIsIEM7CisgICAgICAgIGludCBmaWVsZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VxdWFsc0xqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbgorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZC5lcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgVGVzdEZpZWxkIHggPSBuZXcgVGVzdEZpZWxkKCk7CisgICAgICAgIEZpZWxkIGYgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJzaG9ydEZpZWxkIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldFR5cGUgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlNhbWUgRmllbGQgcmV0dXJuZWQgZmFsc2UiLCBmLmVxdWFscyhmKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmhlcml0ZWQgRmllbGQgcmV0dXJuZWQgZmFsc2UiLCBmLmVxdWFscyh4LmdldENsYXNzKCkKKyAgICAgICAgICAgICAgICAgICAgLmdldERlY2xhcmVkRmllbGQoInNob3J0RmllbGQiKSkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSWRlbnRpY2FsIEZpZWxkIGZyb20gZGlmZmVyZW50IGNsYXNzIHJldHVybmVkIHRydWUiLCAhZgorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKEEuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgic2hvcnRGaWVsZCIpKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldFR5cGUgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNnZXQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldExqYXZhX2xhbmdfT2JqZWN0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0CisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkLmdldChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBUZXN0RmllbGQgeCA9IG5ldyBUZXN0RmllbGQoKTsKKyAgICAgICAgRmllbGQgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJkb3VibGVGaWVsZCIpOworICAgICAgICBEb3VibGUgdmFsID0gKERvdWJsZSkgZi5nZXQoeCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGRvdWJsZSBmaWVsZCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgdmFsLmRvdWJsZVZhbHVlKCkgPT0gRG91YmxlLk1BWF9WQUxVRSk7CisgICAgICAgIC8vIFRlc3QgZ2V0dGluZyBhIHN0YXRpYyBmaWVsZDsKKyAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJkb3VibGVTRmllbGQiKTsKKyAgICAgICAgZi5zZXQoeCwgbmV3IERvdWJsZSgxLjApKTsKKyAgICAgICAgdmFsID0gKERvdWJsZSkgZi5nZXQoeCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGRvdWJsZSBmaWVsZCB2YWx1ZSIsIDEuMCwgdmFsCisgICAgICAgICAgICAgICAgLmRvdWJsZVZhbHVlKCkpOworCisgICAgICAgIC8vIFRyeSBhIGdldCBvbiBhIHByaXZhdGUgZmllbGQKKyAgICAgICAgYm9vbGVhbiB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSBUZXN0QWNjZXNzLmNsYXNzLmdldERlY2xhcmVkRmllbGQoInh4eCIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChmKTsKKyAgICAgICAgICAgIGYuZ2V0KG51bGwpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIG9rKSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIklsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vIFRyeSBhIGdldCBvbiBhIHByaXZhdGUgZmllbGQgaW4gbmVzdGVkIG1lbWJlcgorICAgICAgICAvLyB0ZW1wb3JhcmlseSBjb21tZW50ZWQgYmVjYXVzZSBpdCBicmVha3MgSjkgVk0KKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS0xMzA5CisgICAgICAgIC8vZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJwcml2ZmllbGQxIik7CisgICAgICAgIC8vYXNzZXJ0RXF1YWxzKHgucHJpdmZpZWxkMSwgZi5nZXQoeCkpOworCisgICAgICAgIC8vIFRyeSBhIGdldCB1c2luZyBhbiBpbnZhbGlkIGNsYXNzLgorICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiZG91YmxlRmllbGQiKTsKKyAgICAgICAgICAgIGYuZ2V0KG5ldyBTdHJpbmcoKSk7CisgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4YykgeworICAgICAgICAgICAgLy8gQ29ycmVjdCAtIFBhc3NlZCBhbiBPYmplY3QgdGhhdCBkb2VzIG5vdCBkZWNsYXJlIG9yIGluaGVyaXQgZgorICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vVGVzdCBOUEUKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0gVGVzdEZpZWxkLmNsYXNzLmdldERlY2xhcmVkRmllbGQoImludEZpZWxkIik7CisgICAgICAgICAgICBmLmdldChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhjKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0IC0gUGFzc2VkIGFuIE9iamVjdCB0aGF0IGRvZXMgbm90IGRlY2xhcmUgb3IgaW5oZXJpdCBmCisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICAvL1Rlc3Qgbm8gTlBFIG9uIHN0YXRpYyBmaWVsZHMKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0gVGVzdEZpZWxkLmNsYXNzLmdldERlY2xhcmVkRmllbGQoImRvdWJsZVNGaWVsZCIpOworICAgICAgICAgICAgZi5nZXQobnVsbCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJFeGNlcHRpb24gdGhyb3duIiwgdHJ1ZSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleGMpIHsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgU3VwcG9ydFN1YkNsYXNzIGV4dGVuZHMgU3VwcG9ydF9GaWVsZCB7CisKKyAgICAgICAgT2JqZWN0IGdldEZpZWxkKGNoYXIgcHJpbWl0aXZlVHlwZSwgT2JqZWN0IG8sIEZpZWxkIGYsCisgICAgICAgICAgICAgICAgQ2xhc3MgZXhwZWN0ZWRFeGNlcHRpb24pIHsKKyAgICAgICAgICAgIE9iamVjdCByZXMgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcmltaXRpdmVUeXBlID0gQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKHByaW1pdGl2ZVR5cGUpOworICAgICAgICAgICAgICAgIHN3aXRjaCAocHJpbWl0aXZlVHlwZSkgeworICAgICAgICAgICAgICAgIGNhc2UgJ0knOiAvLyBpbnQKKyAgICAgICAgICAgICAgICAgICAgcmVzID0gbmV3IEludGVnZXIoZi5nZXRJbnQobykpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdKJzogLy8gbG9uZworICAgICAgICAgICAgICAgICAgICByZXMgPSBuZXcgTG9uZyhmLmdldExvbmcobykpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdaJzogLy8gYm9vbGVhbgorICAgICAgICAgICAgICAgICAgICByZXMgPSBuZXcgQm9vbGVhbihmLmdldEJvb2xlYW4obykpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdTJzogLy8gc2hvcnQKKyAgICAgICAgICAgICAgICAgICAgcmVzID0gbmV3IFNob3J0KGYuZ2V0U2hvcnQobykpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdCJzogLy8gYnl0ZQorICAgICAgICAgICAgICAgICAgICByZXMgPSBuZXcgQnl0ZShmLmdldEJ5dGUobykpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdDJzogLy8gY2hhcgorICAgICAgICAgICAgICAgICAgICByZXMgPSBuZXcgQ2hhcmFjdGVyKGYuZ2V0Q2hhcihvKSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ0QnOiAvLyBkb3VibGUKKyAgICAgICAgICAgICAgICAgICAgcmVzID0gbmV3IERvdWJsZShmLmdldERvdWJsZShvKSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ0YnOiAvLyBmbG9hdAorICAgICAgICAgICAgICAgICAgICByZXMgPSBuZXcgRmxvYXQoZi5nZXRGbG9hdChvKSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgIHJlcyA9IGYuZ2V0KG8pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoZXhwZWN0ZWRFeGNlcHRpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBleGNlcHRpb24gIiArIGV4cGVjdGVkRXhjZXB0aW9uLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBpZiAoZXhwZWN0ZWRFeGNlcHRpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZXhwZWN0ZWQgZXhjZXB0aW9uICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGV4cGVjdGVkRXhjZXB0aW9uLmdldE5hbWUoKSArICIgYW5kIGdvdCAiICsgZSwgZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRDbGFzcygpLmVxdWFscyhleHBlY3RlZEV4Y2VwdGlvbikpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiByZXM7CisgICAgICAgIH0KKworICAgICAgICB2b2lkIHNldEZpZWxkKGNoYXIgcHJpbWl0aXZlVHlwZSwgT2JqZWN0IG8sIEZpZWxkIGYsCisgICAgICAgICAgICAgICAgQ2xhc3MgZXhwZWN0ZWRFeGNlcHRpb24sIE9iamVjdCB2YWx1ZSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBwcmltaXRpdmVUeXBlID0gQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKHByaW1pdGl2ZVR5cGUpOworICAgICAgICAgICAgICAgIHN3aXRjaCAocHJpbWl0aXZlVHlwZSkgeworICAgICAgICAgICAgICAgIGNhc2UgJ0knOiAvLyBpbnQKKyAgICAgICAgICAgICAgICAgICAgZi5zZXRJbnQobywgKChJbnRlZ2VyKSB2YWx1ZSkuaW50VmFsdWUoKSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ0onOiAvLyBsb25nCisgICAgICAgICAgICAgICAgICAgIGYuc2V0TG9uZyhvLCAoKExvbmcpIHZhbHVlKS5sb25nVmFsdWUoKSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ1onOiAvLyBib29sZWFuCisgICAgICAgICAgICAgICAgICAgIGYuc2V0Qm9vbGVhbihvLCAoKEJvb2xlYW4pIHZhbHVlKS5ib29sZWFuVmFsdWUoKSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ1MnOiAvLyBzaG9ydAorICAgICAgICAgICAgICAgICAgICBmLnNldFNob3J0KG8sICgoU2hvcnQpIHZhbHVlKS5zaG9ydFZhbHVlKCkpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdCJzogLy8gYnl0ZQorICAgICAgICAgICAgICAgICAgICBmLnNldEJ5dGUobywgKChCeXRlKSB2YWx1ZSkuYnl0ZVZhbHVlKCkpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdDJzogLy8gY2hhcgorICAgICAgICAgICAgICAgICAgICBmLnNldENoYXIobywgKChDaGFyYWN0ZXIpIHZhbHVlKS5jaGFyVmFsdWUoKSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ0QnOiAvLyBkb3VibGUKKyAgICAgICAgICAgICAgICAgICAgZi5zZXREb3VibGUobywgKChEb3VibGUpIHZhbHVlKS5kb3VibGVWYWx1ZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAnRic6IC8vIGZsb2F0CisgICAgICAgICAgICAgICAgICAgIGYuc2V0RmxvYXQobywgKChGbG9hdCkgdmFsdWUpLmZsb2F0VmFsdWUoKSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgIGYuc2V0KG8sIHZhbHVlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGV4cGVjdGVkRXhjZXB0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBleHBlY3RlZEV4Y2VwdGlvbi5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgZm9yIGZpZWxkICIgKyBmLmdldE5hbWUoKSArICIsIHZhbHVlICIgKyB2YWx1ZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBpZiAoZXhwZWN0ZWRFeGNlcHRpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZSArICIgZm9yIGZpZWxkICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGYuZ2V0TmFtZSgpICsgIiwgdmFsdWUgIiArIHZhbHVlKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJleHBlY3RlZCBleGNlcHRpb24gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZXhwZWN0ZWRFeGNlcHRpb24uZ2V0TmFtZSgpICsgIiBhbmQgZ290ICIgKyBlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGZvciBmaWVsZCAiICsgZi5nZXROYW1lKCkgKyAiLCB2YWx1ZSAiICsgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5nZXRDbGFzcygpLmVxdWFscyhleHBlY3RlZEV4Y2VwdGlvbikpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkI2dldChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkI2dldEJ5dGUoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNnZXRCb29sZWFuKGphdmEubGFuZy5PYmplY3QpCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjZ2V0U2hvcnQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNnZXRJbnQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNnZXRMb25nKGphdmEubGFuZy5PYmplY3QpCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjZ2V0RmxvYXQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNnZXREb3VibGUoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNnZXRDaGFyKGphdmEubGFuZy5PYmplY3QpCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjc2V0KGphdmEubGFuZy5PYmplY3QsIGphdmEubGFuZy5PYmplY3QpCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjc2V0Qnl0ZShqYXZhLmxhbmcuT2JqZWN0LCBieXRlKQorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkI3NldEJvb2xlYW4oamF2YS5sYW5nLk9iamVjdCwgYm9vbGVhbikKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNzZXRTaG9ydChqYXZhLmxhbmcuT2JqZWN0LCBzaG9ydCkKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNzZXRJbnQoamF2YS5sYW5nLk9iamVjdCwgaW50KQorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkI3NldExvbmcoamF2YS5sYW5nLk9iamVjdCwgbG9uZykKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNzZXRGbG9hdChqYXZhLmxhbmcuT2JqZWN0LCBmbG9hdCkKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNzZXREb3VibGUoamF2YS5sYW5nLk9iamVjdCwgZG91YmxlKQorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkI3NldENoYXIoamF2YS5sYW5nLk9iamVjdCwgY2hhcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJvdGVjdGVkRmllbGRBY2Nlc3MoKSB7CisgICAgICAgIENsYXNzIGZpZWxkQ2xhc3MgPSBuZXcgU3VwcG9ydF9GaWVsZCgpLmdldENsYXNzKCk7CisgICAgICAgIFN0cmluZyBmaWVsZE5hbWUgPSBudWxsOworICAgICAgICBGaWVsZCBvYmplY3RGaWVsZCA9IG51bGw7CisgICAgICAgIEZpZWxkIGJvb2xlYW5GaWVsZCA9IG51bGw7CisgICAgICAgIEZpZWxkIGJ5dGVGaWVsZCA9IG51bGw7CisgICAgICAgIEZpZWxkIGNoYXJGaWVsZCA9IG51bGw7CisgICAgICAgIEZpZWxkIHNob3J0RmllbGQgPSBudWxsOworICAgICAgICBGaWVsZCBpbnRGaWVsZCA9IG51bGw7CisgICAgICAgIEZpZWxkIGxvbmdGaWVsZCA9IG51bGw7CisgICAgICAgIEZpZWxkIGZsb2F0RmllbGQgPSBudWxsOworICAgICAgICBGaWVsZCBkb3VibGVGaWVsZCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaWVsZE5hbWUgPSAib2JqZWN0RmllbGQiOworICAgICAgICAgICAgb2JqZWN0RmllbGQgPSBmaWVsZENsYXNzLmdldERlY2xhcmVkRmllbGQoZmllbGROYW1lKTsKKworICAgICAgICAgICAgZmllbGROYW1lID0gImJvb2xlYW5GaWVsZCI7CisgICAgICAgICAgICBib29sZWFuRmllbGQgPSBmaWVsZENsYXNzLmdldERlY2xhcmVkRmllbGQoZmllbGROYW1lKTsKKworICAgICAgICAgICAgZmllbGROYW1lID0gImJ5dGVGaWVsZCI7CisgICAgICAgICAgICBieXRlRmllbGQgPSBmaWVsZENsYXNzLmdldERlY2xhcmVkRmllbGQoZmllbGROYW1lKTsKKworICAgICAgICAgICAgZmllbGROYW1lID0gImNoYXJGaWVsZCI7CisgICAgICAgICAgICBjaGFyRmllbGQgPSBmaWVsZENsYXNzLmdldERlY2xhcmVkRmllbGQoZmllbGROYW1lKTsKKworICAgICAgICAgICAgZmllbGROYW1lID0gInNob3J0RmllbGQiOworICAgICAgICAgICAgc2hvcnRGaWVsZCA9IGZpZWxkQ2xhc3MuZ2V0RGVjbGFyZWRGaWVsZChmaWVsZE5hbWUpOworCisgICAgICAgICAgICBmaWVsZE5hbWUgPSAiaW50RmllbGQiOworICAgICAgICAgICAgaW50RmllbGQgPSBmaWVsZENsYXNzLmdldERlY2xhcmVkRmllbGQoZmllbGROYW1lKTsKKworICAgICAgICAgICAgZmllbGROYW1lID0gImxvbmdGaWVsZCI7CisgICAgICAgICAgICBsb25nRmllbGQgPSBmaWVsZENsYXNzLmdldERlY2xhcmVkRmllbGQoZmllbGROYW1lKTsKKworICAgICAgICAgICAgZmllbGROYW1lID0gImZsb2F0RmllbGQiOworICAgICAgICAgICAgZmxvYXRGaWVsZCA9IGZpZWxkQ2xhc3MuZ2V0RGVjbGFyZWRGaWVsZChmaWVsZE5hbWUpOworCisgICAgICAgICAgICBmaWVsZE5hbWUgPSAiZG91YmxlRmllbGQiOworICAgICAgICAgICAgZG91YmxlRmllbGQgPSBmaWVsZENsYXNzLmdldERlY2xhcmVkRmllbGQoZmllbGROYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRmllbGRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgibWlzc2luZyBmaWVsZCAiICsgZmllbGROYW1lICsgIiBpbiB0ZXN0IHN1cHBvcnQgY2xhc3MgIgorICAgICAgICAgICAgICAgICAgICArIGZpZWxkQ2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNyZWF0ZSB0aGUgdmFyaW91cyBvYmplY3RzIHRoYXQgbWlnaHQgb3IgbWlnaHQgbm90IGhhdmUgYW4gaW5zdGFuY2UKKyAgICAgICAgLy8gb2YgdGhlIGZpZWxkCisgICAgICAgIFN1cHBvcnRfRmllbGQgcGFyZW50Q2xhc3MgPSBuZXcgU3VwcG9ydF9GaWVsZCgpOworICAgICAgICBTdXBwb3J0U3ViQ2xhc3Mgc3ViY2xhc3MgPSBuZXcgU3VwcG9ydFN1YkNsYXNzKCk7CisgICAgICAgIFN1cHBvcnRTdWJDbGFzcyBvdGhlclN1YmNsYXNzID0gbmV3IFN1cHBvcnRTdWJDbGFzcygpOworICAgICAgICBPYmplY3QgcGxhaW5PYmplY3QgPSBuZXcgT2JqZWN0KCk7CisKKyAgICAgICAgQ2xhc3MgaWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbkNsYXNzID0gbmV3IElsbGVnYWxBY2Nlc3NFeGNlcHRpb24oKQorICAgICAgICAgICAgICAgIC5nZXRDbGFzcygpOworICAgICAgICBDbGFzcyBpbGxlZ2FsQXJndW1lbnRFeGNlcHRpb25DbGFzcyA9IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKQorICAgICAgICAgICAgICAgIC5nZXRDbGFzcygpOworCisgICAgICAgIC8vIFRoZSB0ZXN0IHdpbGwgYXR0ZW1wdCB0byB1c2UgcGFzcyBhbiBvYmplY3QgdG8gc2V0IGZvciBvYmplY3QsIGJ5dGUsCisgICAgICAgIC8vIHNob3J0LCAuLi4sIGZsb2F0IGFuZCBkb3VibGUgZmllbGRzCisgICAgICAgIC8vIGFuZCBwYXNzIGEgYnl0ZSB0byB0byBzZXRCeXRlIGZvciBieXRlLCBzaG9ydCwgLi4uLCBmbG9hdCBhbmQgZG91YmxlCisgICAgICAgIC8vIGZpZWxkcyBhbmQgc28gb24uCisgICAgICAgIC8vIEl0IHdpbGwgYWxzbyB0ZXN0IGlmIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyB0aHJvd24gd2hlbiB0aGUKKyAgICAgICAgLy8gZmllbGQgZG9lcyBub3QgZXhpc3QgaW4gdGhlIGdpdmVuIG9iamVjdCBhbmQgdGhhdAorICAgICAgICAvLyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGlzIHRocm93biB3aGVuIHRyeWluZyB0byBhY2Nlc3MgYW4KKyAgICAgICAgLy8gaW5hY2Nlc3NpYmxlIHByb3RlY3RlZCBmaWVsZC4KKyAgICAgICAgLy8gVGhlIHRlc3Qgd2lsbCBhbHNvIGNoZWNrIHRoYXQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93biBmb3IKKyAgICAgICAgLy8gYWxsIG90aGVyIGF0dGVtcHRzLgorCisgICAgICAgIC8vIE9yZGVyZWQgYnkgd2lkZW5pbmcgY29udmVyc2lvbiwgZXhjZXB0IGZvciAnTCcgYXQgdGhlIGJlZyAod2hpY2gKKyAgICAgICAgLy8gc3RhbmRzIGZvciBPYmplY3QpLgorICAgICAgICAvLyBJZiB0aGUgb2JqZWN0IHByb3ZpZGVkIHRvIHNldCBjYW4gYmUgdW53cmFwcGVkIHRvIGEgcHJpbWl0aXZlLCB0aGVuCisgICAgICAgIC8vIHRoZSBzZXQgbWV0aG9kIGNhbiBzZXQKKyAgICAgICAgLy8gcHJpbWl0aXZlIGZpZWxkcy4KKyAgICAgICAgY2hhciB0eXBlc1tdID0geyAnTCcsICdCJywgJ1MnLCAnQycsICdJJywgJ0onLCAnRicsICdEJyB9OworICAgICAgICBGaWVsZCBmaWVsZHNbXSA9IHsgb2JqZWN0RmllbGQsIGJ5dGVGaWVsZCwgc2hvcnRGaWVsZCwgY2hhckZpZWxkLAorICAgICAgICAgICAgICAgIGludEZpZWxkLCBsb25nRmllbGQsIGZsb2F0RmllbGQsIGRvdWJsZUZpZWxkIH07CisgICAgICAgIE9iamVjdCB2YWx1ZXNbXSA9IHsgbmV3IEJ5dGUoKGJ5dGUpIDEpLCBuZXcgQnl0ZSgoYnl0ZSkgMSksCisgICAgICAgICAgICAgICAgbmV3IFNob3J0KChzaG9ydCkgMSksIG5ldyBDaGFyYWN0ZXIoKGNoYXIpIDEpLCBuZXcgSW50ZWdlcigxKSwKKyAgICAgICAgICAgICAgICBuZXcgTG9uZygxKSwgbmV3IEZsb2F0KDEpLCBuZXcgRG91YmxlKDEpIH07CisKKyAgICAgICAgLy8gdGVzdCBzZXQgbWV0aG9kcworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjaGFyIHR5cGUgPSB0eXBlc1tpXTsKKyAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IHZhbHVlc1tpXTsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSBpOyBqIDwgZmllbGRzLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgRmllbGQgZmllbGQgPSBmaWVsZHNbal07CisgICAgICAgICAgICAgICAgZmllbGROYW1lID0gZmllbGQuZ2V0TmFtZSgpOworCisgICAgICAgICAgICAgICAgaWYgKGZpZWxkID09IGNoYXJGaWVsZCAmJiB0eXBlICE9ICdDJykgeworICAgICAgICAgICAgICAgICAgICAvLyB0aGUgZXhjZXB0aW9uIGlzIHRoYXQgYnl0ZXMgYW5kIHNob3J0cyBDQU5OT1QgYmUKKyAgICAgICAgICAgICAgICAgICAgLy8gY29udmVydGVkIGludG8gY2hhcnMgZXZlbiB0aG91Z2ggY2hhcnMgQ0FOIGJlCisgICAgICAgICAgICAgICAgICAgIC8vIGNvbnZlcnRlZCBpbnRvIGludHMsIGxvbmdzLCBmbG9hdHMgYW5kIGRvdWJsZXMKKyAgICAgICAgICAgICAgICAgICAgc3ViY2xhc3Muc2V0RmllbGQodHlwZSwgc3ViY2xhc3MsIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbkNsYXNzLCB2YWx1ZSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gc2V0dGluZyB0eXBlIGludG8gZmllbGQpOworICAgICAgICAgICAgICAgICAgICBzdWJjbGFzcy5zZXRGaWVsZCh0eXBlLCBzdWJjbGFzcywgZmllbGQsIG51bGwsIHZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgc3ViY2xhc3Muc2V0RmllbGQodHlwZSwgb3RoZXJTdWJjbGFzcywgZmllbGQsIG51bGwsIHZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgc3ViY2xhc3Muc2V0RmllbGQodHlwZSwgcGFyZW50Q2xhc3MsIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlsbGVnYWxBY2Nlc3NFeGNlcHRpb25DbGFzcywgdmFsdWUpOworICAgICAgICAgICAgICAgICAgICBzdWJjbGFzcy5zZXRGaWVsZCh0eXBlLCBwbGFpbk9iamVjdCwgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmFpbGVkIG9uIEpESy4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbGxlZ2FsQWNjZXNzRXhjZXB0aW9uQ2xhc3MsIHZhbHVlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGk7IGorKykgeworICAgICAgICAgICAgICAgIEZpZWxkIGZpZWxkID0gZmllbGRzW2pdOworICAgICAgICAgICAgICAgIGZpZWxkTmFtZSA9IGZpZWxkLmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICAvLyBub3Qgc2V0dGluZyB0eXBlIGludG8gZmllbGQpOworICAgICAgICAgICAgICAgIHN1YmNsYXNzLnNldEZpZWxkKHR5cGUsIHN1YmNsYXNzLCBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGlsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbkNsYXNzLCB2YWx1ZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyB0ZXN0IHNldEJvb2xlYW4KKyAgICAgICAgQm9vbGVhbiBib29sZWFuVmFsdWUgPSBCb29sZWFuLlRSVUU7CisgICAgICAgIHN1YmNsYXNzLnNldEZpZWxkKCdaJywgc3ViY2xhc3MsIGJvb2xlYW5GaWVsZCwgbnVsbCwgYm9vbGVhblZhbHVlKTsKKyAgICAgICAgc3ViY2xhc3Muc2V0RmllbGQoJ1onLCBvdGhlclN1YmNsYXNzLCBib29sZWFuRmllbGQsIG51bGwsIGJvb2xlYW5WYWx1ZSk7CisgICAgICAgIHN1YmNsYXNzLnNldEZpZWxkKCdaJywgcGFyZW50Q2xhc3MsIGJvb2xlYW5GaWVsZCwKKyAgICAgICAgICAgICAgICBpbGxlZ2FsQWNjZXNzRXhjZXB0aW9uQ2xhc3MsIGJvb2xlYW5WYWx1ZSk7CisgICAgICAgIHN1YmNsYXNzLnNldEZpZWxkKCdaJywgcGxhaW5PYmplY3QsIGJvb2xlYW5GaWVsZCwKKyAgICAgICAgICAgICAgICAvLyBGYWlsZWQgb24gSkRLCisgICAgICAgICAgICAgICAgaWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbkNsYXNzLCBib29sZWFuVmFsdWUpOworICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGZpZWxkcy5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgRmllbGQgbGlzdGVkRmllbGQgPSBmaWVsZHNbal07CisgICAgICAgICAgICBmaWVsZE5hbWUgPSBsaXN0ZWRGaWVsZC5nZXROYW1lKCk7CisgICAgICAgICAgICAvLyBub3Qgc2V0dGluZyBib29sZWFuIGludG8gbGlzdGVkRmllbGQKKyAgICAgICAgICAgIHN1YmNsYXNzLnNldEZpZWxkKCdaJywgc3ViY2xhc3MsIGxpc3RlZEZpZWxkLAorICAgICAgICAgICAgICAgICAgICBpbGxlZ2FsQXJndW1lbnRFeGNlcHRpb25DbGFzcywgYm9vbGVhblZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjaGFyIHR5cGUgPSB0eXBlc1tpXTsKKyAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IHZhbHVlc1tpXTsKKyAgICAgICAgICAgIHN1YmNsYXNzLnNldEZpZWxkKHR5cGUsIHN1YmNsYXNzLCBib29sZWFuRmllbGQsCisgICAgICAgICAgICAgICAgICAgIGlsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbkNsYXNzLCB2YWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBXZSBwZXJmb3JtIHRoZSBhbmFsYWdvdXMgdGVzdCBvbiB0aGUgZ2V0IG1ldGhvZHMuCisKKyAgICAgICAgLy8gb3JkZXJlZCBieSB3aWRlbmluZyBjb252ZXJzaW9uLCBleGNlcHQgZm9yICdMJyBhdCB0aGUgZW5kICh3aGljaAorICAgICAgICAvLyBzdGFuZHMgZm9yIE9iamVjdCksIHRvIHdoaWNoIGFsbCBwcmltaXRpdmVzIGNhbiBiZSBjb252ZXJ0ZWQgYnkKKyAgICAgICAgLy8gd3JhcHBpbmcKKyAgICAgICAgY2hhciBuZXdUeXBlc1tdID0gbmV3IGNoYXJbXSB7ICdCJywgJ1MnLCAnQycsICdJJywgJ0onLCAnRicsICdEJywgJ0wnIH07CisgICAgICAgIEZpZWxkIG5ld0ZpZWxkc1tdID0geyBieXRlRmllbGQsIHNob3J0RmllbGQsIGNoYXJGaWVsZCwgaW50RmllbGQsCisgICAgICAgICAgICAgICAgbG9uZ0ZpZWxkLCBmbG9hdEZpZWxkLCBkb3VibGVGaWVsZCwgb2JqZWN0RmllbGQgfTsKKyAgICAgICAgZmllbGRzID0gbmV3RmllbGRzOworICAgICAgICB0eXBlcyA9IG5ld1R5cGVzOworICAgICAgICAvLyB0ZXN0IGdldCBtZXRob2RzCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdHlwZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNoYXIgdHlwZSA9IHR5cGVzW2ldOworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPD0gaTsgaisrKSB7CisgICAgICAgICAgICAgICAgRmllbGQgZmllbGQgPSBmaWVsZHNbal07CisgICAgICAgICAgICAgICAgZmllbGROYW1lID0gZmllbGQuZ2V0TmFtZSgpOworICAgICAgICAgICAgICAgIGlmICh0eXBlID09ICdDJyAmJiBmaWVsZCAhPSBjaGFyRmllbGQpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGV4Y2VwdGlvbiBpcyB0aGF0IGJ5dGVzIGFuZCBzaG9ydHMgQ0FOTk9UIGJlCisgICAgICAgICAgICAgICAgICAgIC8vIGNvbnZlcnRlZCBpbnRvIGNoYXJzIGV2ZW4gdGhvdWdoIGNoYXJzIENBTiBiZQorICAgICAgICAgICAgICAgICAgICAvLyBjb252ZXJ0ZWQgaW50byBpbnRzLCBsb25ncywgZmxvYXRzIGFuZCBkb3VibGVzCisgICAgICAgICAgICAgICAgICAgIHN1YmNsYXNzLmdldEZpZWxkKHR5cGUsIHN1YmNsYXNzLCBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbGxlZ2FsQXJndW1lbnRFeGNlcHRpb25DbGFzcyk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gZ2V0dGluZyB0eXBlIGZyb20gZmllbGQKKyAgICAgICAgICAgICAgICAgICAgc3ViY2xhc3MuZ2V0RmllbGQodHlwZSwgc3ViY2xhc3MsIGZpZWxkLCBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgc3ViY2xhc3MuZ2V0RmllbGQodHlwZSwgb3RoZXJTdWJjbGFzcywgZmllbGQsIG51bGwpOworICAgICAgICAgICAgICAgICAgICBzdWJjbGFzcy5nZXRGaWVsZCh0eXBlLCBwYXJlbnRDbGFzcywgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbkNsYXNzKTsKKyAgICAgICAgICAgICAgICAgICAgc3ViY2xhc3MuZ2V0RmllbGQodHlwZSwgcGxhaW5PYmplY3QsIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlsbGVnYWxBY2Nlc3NFeGNlcHRpb25DbGFzcyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChpbnQgaiA9IGkgKyAxOyBqIDwgZmllbGRzLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgRmllbGQgZmllbGQgPSBmaWVsZHNbal07CisgICAgICAgICAgICAgICAgZmllbGROYW1lID0gZmllbGQuZ2V0TmFtZSgpOworICAgICAgICAgICAgICAgIHN1YmNsYXNzLmdldEZpZWxkKHR5cGUsIHN1YmNsYXNzLCBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGlsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbkNsYXNzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3QgZ2V0Qm9vbGVhbgorICAgICAgICBzdWJjbGFzcy5nZXRGaWVsZCgnWicsIHN1YmNsYXNzLCBib29sZWFuRmllbGQsIG51bGwpOworICAgICAgICBzdWJjbGFzcy5nZXRGaWVsZCgnWicsIG90aGVyU3ViY2xhc3MsIGJvb2xlYW5GaWVsZCwgbnVsbCk7CisgICAgICAgIHN1YmNsYXNzLmdldEZpZWxkKCdaJywgcGFyZW50Q2xhc3MsIGJvb2xlYW5GaWVsZCwKKyAgICAgICAgICAgICAgICBpbGxlZ2FsQWNjZXNzRXhjZXB0aW9uQ2xhc3MpOworICAgICAgICBzdWJjbGFzcy5nZXRGaWVsZCgnWicsIHBsYWluT2JqZWN0LCBib29sZWFuRmllbGQsCisgICAgICAgICAgICAgICAgaWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbkNsYXNzKTsKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBmaWVsZHMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgIEZpZWxkIGxpc3RlZEZpZWxkID0gZmllbGRzW2pdOworICAgICAgICAgICAgZmllbGROYW1lID0gbGlzdGVkRmllbGQuZ2V0TmFtZSgpOworICAgICAgICAgICAgLy8gbm90IGdldHRpbmcgYm9vbGVhbiBmcm9tIGxpc3RlZEZpZWxkCisgICAgICAgICAgICBzdWJjbGFzcy5nZXRGaWVsZCgnWicsIHN1YmNsYXNzLCBsaXN0ZWRGaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgaWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uQ2xhc3MpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdHlwZXMubGVuZ3RoIC0gMTsgaSsrKSB7CisgICAgICAgICAgICBjaGFyIHR5cGUgPSB0eXBlc1tpXTsKKyAgICAgICAgICAgIHN1YmNsYXNzLmdldEZpZWxkKHR5cGUsIHN1YmNsYXNzLCBib29sZWFuRmllbGQsCisgICAgICAgICAgICAgICAgICAgIGlsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbkNsYXNzKTsKKyAgICAgICAgfQorICAgICAgICBPYmplY3QgcmVzID0gc3ViY2xhc3MuZ2V0RmllbGQoJ0wnLCBzdWJjbGFzcywgYm9vbGVhbkZpZWxkLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidW5leHBlY3RlZCBvYmplY3QgIiArIHJlcywgcmVzIGluc3RhbmNlb2YgQm9vbGVhbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjZ2V0Qm9vbGVhbihqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Qm9vbGVhbkxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICBUZXN0RmllbGQgeCA9IG5ldyBUZXN0RmllbGQoKTsKKyAgICAgICAgRmllbGQgZiA9IG51bGw7CisgICAgICAgIGJvb2xlYW4gdmFsID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImJvb2xlYW5GaWVsZCIpOworICAgICAgICAgICAgdmFsID0gZi5nZXRCb29sZWFuKHgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXRCb29sZWFuIHRlc3Q6ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBib29sZWFuIGZpZWxkIHZhbHVlIiwgdmFsKTsKKworICAgICAgICBib29sZWFuIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJkb3VibGVGaWVsZCIpOworICAgICAgICAgICAgZi5nZXRCb29sZWFuKHgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJib29sZWFuUEZGaWVsZCIpOworICAgICAgICAgICAgZi5nZXRCb29sZWFuKHgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iCisgICAgICAgICAgICAgICAgICAgICsgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICAvL1Rlc3QgTlBFCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJib29sZWFuRmllbGQiKTsKKyAgICAgICAgICAgIGYuZ2V0Qm9vbGVhbihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vVGVzdCBubyBOUEUgb24gc3RhdGljIGZpZWxkCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJib29sZWFuU0ZpZWxkIik7CisgICAgICAgICAgICBib29sZWFuIHN0YXRpY1ZhbHVlID0gZi5nZXRCb29sZWFuKG51bGwpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgdmFsdWUgcmV0dXJuZWQiLCBzdGF0aWNWYWx1ZSk7CisgICAgICAgIH0gIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNnZXRCeXRlKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRCeXRlTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBieXRlCisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkLmdldEJ5dGUoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgVGVzdEZpZWxkIHggPSBuZXcgVGVzdEZpZWxkKCk7CisgICAgICAgIEZpZWxkIGYgPSBudWxsOworICAgICAgICBieXRlIHZhbCA9IDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImJ5dGVGaWVsZCIpOworICAgICAgICAgICAgdmFsID0gZi5nZXRCeXRlKHgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXRieXRlIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBieXRlIGZpZWxkIHZhbHVlIiwgdmFsID09IEJ5dGUuTUFYX1ZBTFVFKTsKKworICAgICAgICBib29sZWFuIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJkb3VibGVGaWVsZCIpOworICAgICAgICAgICAgZi5nZXRCeXRlKHgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJieXRlUEZGaWVsZCIpOworICAgICAgICAgICAgZi5nZXRCeXRlKHgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iCisgICAgICAgICAgICAgICAgICAgICsgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICAvL1Rlc3QgTlBFCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJieXRlRmllbGQiKTsKKyAgICAgICAgICAgIGYuZ2V0Qnl0ZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vVGVzdCBubyBOUEUgb24gc3RhdGljIGZpZWxkCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJieXRlU0ZpZWxkIik7CisgICAgICAgICAgICBieXRlIHN0YXRpY1ZhbHVlID0gZi5nZXRCeXRlKG51bGwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSByZXR1cm5lZCIsIEJ5dGUuTUFYX1ZBTFVFLCBzdGF0aWNWYWx1ZSk7CisgICAgICAgIH0gIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4Y2VwdGlvbiBleHBlY3RlZCAiKyBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjZ2V0Q2hhcihqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Q2hhckxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgY2hhcgorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZC5nZXRDaGFyKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIFRlc3RGaWVsZCB4ID0gbmV3IFRlc3RGaWVsZCgpOworICAgICAgICBGaWVsZCBmID0gbnVsbDsKKyAgICAgICAgY2hhciB2YWwgPSAwOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJjaGFyRmllbGQiKTsKKyAgICAgICAgICAgIHZhbCA9IGYuZ2V0Q2hhcih4KTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0Q2hhcmFjdGVyIHRlc3Q6ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGNoYXIgZmllbGQgdmFsdWUiLCAnVCcsIHZhbCk7CisKKyAgICAgICAgYm9vbGVhbiB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiZG91YmxlRmllbGQiKTsKKyAgICAgICAgICAgIGYuZ2V0Q2hhcih4KTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiY2hhclBGRmllbGQiKTsKKyAgICAgICAgICAgIGYuZ2V0Q2hhcih4KTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIgorICAgICAgICAgICAgICAgICAgICArIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIsIHRocm93bik7CisKKyAgICAgICAgLy9UZXN0IE5QRQorICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiY2hhckZpZWxkIik7CisgICAgICAgICAgICBmLmdldENoYXIobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICAvL1Rlc3Qgbm8gTlBFIG9uIHN0YXRpYyBmaWVsZAorICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiY2hhclNGaWVsZCIpOworICAgICAgICAgICAgY2hhciBzdGF0aWNWYWx1ZSA9IGYuZ2V0Q2hhcihudWxsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgcmV0dXJuZWQiLCAnVCcsIHN0YXRpY1ZhbHVlKTsKKyAgICAgICAgfSAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiTm8gZXhjZXB0aW9uIGV4cGVjdGVkICIrIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNnZXREZWNsYXJpbmdDbGFzcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREZWNsYXJpbmdDbGFzcygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5DbGFzcworICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZC5nZXREZWNsYXJpbmdDbGFzcygpCisgICAgICAgIEZpZWxkW10gZmllbGRzOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaWVsZHMgPSBuZXcgVGVzdEZpZWxkKCkuZ2V0Q2xhc3MoKS5nZXRGaWVsZHMoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBkZWNsYXJpbmcgY2xhc3MiLCBmaWVsZHNbMF0KKyAgICAgICAgICAgICAgICAgICAgLmdldERlY2xhcmluZ0NsYXNzKCkuZXF1YWxzKG5ldyBUZXN0RmllbGQoKS5nZXRDbGFzcygpKSk7CisKKyAgICAgICAgICAgIC8vIENoZWNrIHRoZSBjYXNlIHdoZXJlIHRoZSBmaWVsZCBpcyBpbmhlcml0ZWQgdG8gYmUgc3VyZSB0aGUgcGFyZW50CisgICAgICAgICAgICAvLyBpcyByZXR1cm5lZCBhcyB0aGUgZGVjbGFyYXRvcgorICAgICAgICAgICAgZmllbGRzID0gbmV3IFRlc3RGaWVsZFN1YjEoKS5nZXRDbGFzcygpLmdldEZpZWxkcygpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGRlY2xhcmluZyBjbGFzcyIsIGZpZWxkc1swXQorICAgICAgICAgICAgICAgICAgICAuZ2V0RGVjbGFyaW5nQ2xhc3MoKS5lcXVhbHMobmV3IFRlc3RGaWVsZCgpLmdldENsYXNzKCkpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNnZXREb3VibGUoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERvdWJsZUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgZG91YmxlCisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkLmdldERvdWJsZShqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBUZXN0RmllbGQgeCA9IG5ldyBUZXN0RmllbGQoKTsKKyAgICAgICAgRmllbGQgZiA9IG51bGw7CisgICAgICAgIGRvdWJsZSB2YWwgPSAwLjA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImRvdWJsZUZpZWxkIik7CisgICAgICAgICAgICB2YWwgPSBmLmdldERvdWJsZSh4KTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0RG91YmxlIHRlc3Q6ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBkb3VibGUgZmllbGQgdmFsdWUiLAorICAgICAgICAgICAgICAgIHZhbCA9PSBEb3VibGUuTUFYX1ZBTFVFKTsKKworICAgICAgICBib29sZWFuIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJib29sZWFuRmllbGQiKTsKKyAgICAgICAgICAgIGYuZ2V0RG91YmxlKHgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24gIgorICAgICAgICAgICAgICAgICAgICArIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiZG91YmxlUEZGaWVsZCIpOworICAgICAgICAgICAgZi5nZXREb3VibGUoeCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIKKyAgICAgICAgICAgICAgICAgICAgKyBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIklsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vVGVzdCBOUEUKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImRvdWJsZUZpZWxkIik7CisgICAgICAgICAgICBmLmdldERvdWJsZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vVGVzdCBubyBOUEUgb24gc3RhdGljIGZpZWxkCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJkb3VibGVTRkZpZWxkIik7CisgICAgICAgICAgICBkb3VibGUgc3RhdGljVmFsdWUgPSBmLmdldERvdWJsZShudWxsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgcmV0dXJuZWQiLCBEb3VibGUuTUFYX1ZBTFVFLCBzdGF0aWNWYWx1ZSk7CisgICAgICAgIH0gIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4Y2VwdGlvbiBleHBlY3RlZCAiKyBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjZ2V0RmxvYXQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEZsb2F0TGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBmbG9hdAorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZC5nZXRGbG9hdChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBUZXN0RmllbGQgeCA9IG5ldyBUZXN0RmllbGQoKTsKKyAgICAgICAgRmllbGQgZiA9IG51bGw7CisgICAgICAgIGZsb2F0IHZhbCA9IDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImZsb2F0RmllbGQiKTsKKyAgICAgICAgICAgIHZhbCA9IGYuZ2V0RmxvYXQoeCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldEZsb2F0IHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBmbG9hdCBmaWVsZCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgdmFsID09IEZsb2F0Lk1BWF9WQUxVRSk7CisKKyAgICAgICAgYm9vbGVhbiB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiYm9vbGVhbkZpZWxkIik7CisgICAgICAgICAgICBmLmdldEZsb2F0KHgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24gIgorICAgICAgICAgICAgICAgICAgICArIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiZmxvYXRQRkZpZWxkIik7CisgICAgICAgICAgICBmLmdldEZsb2F0KHgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iCisgICAgICAgICAgICAgICAgICAgICsgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICAvL1Rlc3QgTlBFCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJmbG9hdEZpZWxkIik7CisgICAgICAgICAgICBmLmdldEZsb2F0KG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIsIHRocm93bik7CisKKyAgICAgICAgLy9UZXN0IG5vIE5QRSBvbiBzdGF0aWMgZmllbGQKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImZsb2F0U0ZpZWxkIik7CisgICAgICAgICAgICBmbG9hdCBzdGF0aWNWYWx1ZSA9IGYuZ2V0RmxvYXQobnVsbCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIHJldHVybmVkIiwgRmxvYXQuTUFYX1ZBTFVFLCBzdGF0aWNWYWx1ZSk7CisgICAgICAgIH0gIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4Y2VwdGlvbiBleHBlY3RlZCAiKyBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjZ2V0SW50KGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnRMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZC5nZXRJbnQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgVGVzdEZpZWxkIHggPSBuZXcgVGVzdEZpZWxkKCk7CisgICAgICAgIEZpZWxkIGYgPSBudWxsOworICAgICAgICBpbnQgdmFsID0gMDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiaW50RmllbGQiKTsKKyAgICAgICAgICAgIHZhbCA9IGYuZ2V0SW50KHgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXRJbnQgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IEludCBmaWVsZCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgdmFsID09IEludGVnZXIuTUFYX1ZBTFVFKTsKKworICAgICAgICBib29sZWFuIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJib29sZWFuRmllbGQiKTsKKyAgICAgICAgICAgIGYuZ2V0SW50KHgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24gIgorICAgICAgICAgICAgICAgICAgICArIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiaW50UEZGaWVsZCIpOworICAgICAgICAgICAgZi5nZXRJbnQoeCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIKKyAgICAgICAgICAgICAgICAgICAgKyBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIklsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vVGVzdCBOUEUKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImludEZpZWxkIik7CisgICAgICAgICAgICBmLmdldEludChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vVGVzdCBubyBOUEUgb24gc3RhdGljIGZpZWxkCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJpbnRTRmllbGQiKTsKKyAgICAgICAgICAgIGludCBzdGF0aWNWYWx1ZSA9IGYuZ2V0SW50KG51bGwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSByZXR1cm5lZCIsIEludGVnZXIuTUFYX1ZBTFVFLCBzdGF0aWNWYWx1ZSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiTm8gZXhjZXB0aW9uIGV4cGVjdGVkICIgKyBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNnZXRMb25nKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRMb25nTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBsb25nCisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkLmdldExvbmcoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgVGVzdEZpZWxkIHggPSBuZXcgVGVzdEZpZWxkKCk7CisgICAgICAgIEZpZWxkIGYgPSBudWxsOworICAgICAgICBsb25nIHZhbCA9IDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImxvbmdGaWVsZCIpOworICAgICAgICAgICAgdmFsID0gZi5nZXRMb25nKHgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXRMb25nIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiYm9vbGVhbkZpZWxkIik7CisgICAgICAgICAgICBmLmdldExvbmcoeCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biAiCisgICAgICAgICAgICAgICAgICAgICsgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJsb25nUEZGaWVsZCIpOworICAgICAgICAgICAgZi5nZXRMb25nKHgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iCisgICAgICAgICAgICAgICAgICAgICsgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICAvL1Rlc3QgTlBFCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJsb25nRmllbGQiKTsKKyAgICAgICAgICAgIGYuZ2V0TG9uZyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vVGVzdCBubyBOUEUgb24gc3RhdGljIGZpZWxkCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJsb25nU0ZpZWxkIik7CisgICAgICAgICAgICBsb25nIHN0YXRpY1ZhbHVlID0gZi5nZXRMb25nKG51bGwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSByZXR1cm5lZCIsIExvbmcuTUFYX1ZBTFVFLCBzdGF0aWNWYWx1ZSk7CisgICAgICAgIH0gIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4Y2VwdGlvbiBleHBlY3RlZCAiKyBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjZ2V0TW9kaWZpZXJzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1vZGlmaWVycygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZC5nZXRNb2RpZmllcnMoKQorICAgICAgICBUZXN0RmllbGQgeCA9IG5ldyBUZXN0RmllbGQoKTsKKyAgICAgICAgRmllbGQgZiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoInByc3R0cnZvbCIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXRNb2RpZmllcnMgdGVzdDogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgICAgaW50IG1vZCA9IGYuZ2V0TW9kaWZpZXJzKCk7CisgICAgICAgIGludCBtYXNrID0gKE1vZGlmaWVyLlBST1RFQ1RFRCB8IE1vZGlmaWVyLlNUQVRJQykKKyAgICAgICAgICAgICAgICB8IChNb2RpZmllci5UUkFOU0lFTlQgfCBNb2RpZmllci5WT0xBVElMRSk7CisgICAgICAgIGludCBubWFzayA9IChNb2RpZmllci5QVUJMSUMgfCBNb2RpZmllci5OQVRJVkUpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgZmllbGQgbW9kaWZpZXJzOiAiLAorICAgICAgICAgICAgICAgICgobW9kICYgbWFzaykgPT0gbWFzaykgJiYgKChtb2QgJiBubWFzaykgPT0gMCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkI2dldE5hbWUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TmFtZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcgamF2YS5sYW5nLnJlZmxlY3QuRmllbGQuZ2V0TmFtZSgpCisgICAgICAgIFRlc3RGaWVsZCB4ID0gbmV3IFRlc3RGaWVsZCgpOworICAgICAgICBGaWVsZCBmID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgic2hvcnRGaWVsZCIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXRUeXBlIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGZpZWxkIG5hbWUiLAorICAgICAgICAgICAgICAgICJzaG9ydEZpZWxkIiwgZi5nZXROYW1lKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkI2dldFNob3J0KGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTaG9ydExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgc2hvcnQKKyAgICAgICAgLy8gamF2YS5sYW5nLnJlZmxlY3QuRmllbGQuZ2V0U2hvcnQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgVGVzdEZpZWxkIHggPSBuZXcgVGVzdEZpZWxkKCk7CisgICAgICAgIEZpZWxkIGYgPSBudWxsOworICAgICAgICBzaG9ydCB2YWwgPSAwOworICAgICAgICA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoInNob3J0RmllbGQiKTsKKyAgICAgICAgICAgIHZhbCA9IGYuZ2V0U2hvcnQoeCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldFNob3J0IHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBzaG9ydCBmaWVsZCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgdmFsID09IFNob3J0Lk1BWF9WQUxVRSk7CisKKyAgICAgICAgYm9vbGVhbiB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiYm9vbGVhbkZpZWxkIik7CisgICAgICAgICAgICBmLmdldFNob3J0KHgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24gIgorICAgICAgICAgICAgICAgICAgICArIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgic2hvcnRQRkZpZWxkIik7CisgICAgICAgICAgICBmLmdldFNob3J0KHgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iCisgICAgICAgICAgICAgICAgICAgICsgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICAvL1Rlc3QgTlBFCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJzaG9ydEZpZWxkIik7CisgICAgICAgICAgICBmLmdldFNob3J0KG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIsIHRocm93bik7CisKKyAgICAgICAgLy9UZXN0IG5vIE5QRSBvbiBzdGF0aWMgZmllbGQKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoInNob3J0U0ZpZWxkIik7CisgICAgICAgICAgICBzaG9ydCBzdGF0aWNWYWx1ZSA9IGYuZ2V0U2hvcnQobnVsbCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIHJldHVybmVkIiwgU2hvcnQuTUFYX1ZBTFVFLCBzdGF0aWNWYWx1ZSk7CisgICAgICAgIH0gIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4Y2VwdGlvbiBleHBlY3RlZCAiKyBleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjZ2V0VHlwZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRUeXBlKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLkNsYXNzIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkLmdldFR5cGUoKQorICAgICAgICBUZXN0RmllbGQgeCA9IG5ldyBUZXN0RmllbGQoKTsKKyAgICAgICAgRmllbGQgZiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoInNob3J0RmllbGQiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0VHlwZSB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgZmllbGQgdHlwZTogIiArIGYuZ2V0VHlwZSgpLnRvU3RyaW5nKCksCisgICAgICAgICAgICAgICAgZi5nZXRUeXBlKCkuZXF1YWxzKHNob3J0LmNsYXNzKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjc2V0KGphdmEubGFuZy5PYmplY3QsIGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRMamF2YV9sYW5nX09iamVjdExqYXZhX2xhbmdfT2JqZWN0KCkgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS5sYW5nLnJlZmxlY3QuRmllbGQuc2V0KGphdmEubGFuZy5PYmplY3QsCisgICAgICAgIC8vIGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIFRlc3RGaWVsZCB4ID0gbmV3IFRlc3RGaWVsZCgpOworICAgICAgICBGaWVsZCBmID0gbnVsbDsKKyAgICAgICAgZG91YmxlIHZhbCA9IDAuMDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiZG91YmxlRmllbGQiKTsKKyAgICAgICAgICAgIGYuc2V0KHgsIG5ldyBEb3VibGUoMS4wKSk7CisgICAgICAgICAgICB2YWwgPSBmLmdldERvdWJsZSh4KTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgc2V0IHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGRvdWJsZSBmaWVsZCB2YWx1ZSIsIDEuMCwgdmFsKTsKKworICAgICAgICAvL3Rlc3Qgd3JvbmcgdHlwZQorICAgICAgICBib29sZWFuIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJib29sZWFuRmllbGQiKTsKKyAgICAgICAgICAgIGYuc2V0KHgsIG5ldyBEb3VibGUoMS4wKSk7CisgICAgICAgICAgICBmYWlsKCJBY2Nlc3NlZCBmaWVsZCBvZiBpbnZhbGlkIHR5cGUiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIsIHRocm93bik7CisKKyAgICAgICAgLy90ZXN0IG5vdCBhY2Nlc3NpYmxlCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJkb3VibGVGRmllbGQiKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGYuaXNBY2Nlc3NpYmxlKCkpOworICAgICAgICAgICAgZi5zZXQoeCwgbmV3IERvdWJsZSgxLjApKTsKKyAgICAgICAgICAgIGZhaWwoIkFjY2Vzc2VkIGluYWNjZXNzaWJsZSBmaWVsZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIklsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAvL1Rlc3QgTlBFCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJib29sZWFuRmllbGQiKTsKKyAgICAgICAgICAgIGYuc2V0KG51bGwsIHRydWUpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIsIHRocm93bik7CisKKyAgICAgICAgLy8gVGVzdCBzZXR0aW5nIGEgc3RhdGljIGZpZWxkOworICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImRvdWJsZVNGaWVsZCIpOworICAgICAgICBmLnNldChudWxsLCBuZXcgRG91YmxlKDEuMCkpOworICAgICAgICB2YWwgPSBmLmdldERvdWJsZSh4KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgZG91YmxlIGZpZWxkIHZhbHVlIiwgMS4wLCB2YWwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkI3NldEJvb2xlYW4oamF2YS5sYW5nLk9iamVjdCwgYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEJvb2xlYW5MamF2YV9sYW5nX09iamVjdFooKSB0aHJvd3MgRXhjZXB0aW9ueworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZAorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZC5zZXRCb29sZWFuKGphdmEubGFuZy5PYmplY3QsIGJvb2xlYW4pCisgICAgICAgIFRlc3RGaWVsZCB4ID0gbmV3IFRlc3RGaWVsZCgpOworICAgICAgICBGaWVsZCBmID0gbnVsbDsKKyAgICAgICAgYm9vbGVhbiB2YWwgPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiYm9vbGVhbkZpZWxkIik7CisgICAgICAgICAgICBmLnNldEJvb2xlYW4oeCwgZmFsc2UpOworICAgICAgICAgICAgdmFsID0gZi5nZXRCb29sZWFuKHgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBzZXRib29sZWFuIHRlc3Q6ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBmbG9hdCBmaWVsZCB2YWx1ZSIsICF2YWwpOworCisgICAgICAvL3Rlc3Qgd3JvbmcgdHlwZQorICAgICAgICBib29sZWFuIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJkb3VibGVGaWVsZCIpOworICAgICAgICAgICAgZi5zZXRCb29sZWFuKHgsIGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoIkFjY2Vzc2VkIGZpZWxkIG9mIGludmFsaWQgdHlwZSIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICAvL3Rlc3Qgbm90IGFjY2Vzc2libGUKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImJvb2xlYW5QRkZpZWxkIik7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShmLmlzQWNjZXNzaWJsZSgpKTsKKyAgICAgICAgICAgIGYuc2V0Qm9vbGVhbih4LCB0cnVlKTsKKyAgICAgICAgICAgIGZhaWwoIkFjY2Vzc2VkIGluYWNjZXNzaWJsZSBmaWVsZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIklsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAvL1Rlc3QgTlBFCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJib29sZWFuRmllbGQiKTsKKyAgICAgICAgICAgIGYuc2V0Qm9vbGVhbihudWxsLCB0cnVlKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vIFRlc3Qgc2V0dGluZyBhIHN0YXRpYyBmaWVsZDsKKyAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJib29sZWFuU0ZpZWxkIik7CisgICAgICAgIGYuc2V0Qm9vbGVhbihudWxsLCBmYWxzZSk7CisgICAgICAgIHZhbCA9IGYuZ2V0Qm9vbGVhbih4KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIGluY29ycmVjdCBib29sZWFuIGZpZWxkIHZhbHVlIiwgdmFsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNzZXRCeXRlKGphdmEubGFuZy5PYmplY3QsIGJ5dGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRCeXRlTGphdmFfbGFuZ19PYmplY3RCKCkgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQKKyAgICAgICAgLy8gamF2YS5sYW5nLnJlZmxlY3QuRmllbGQuc2V0Qnl0ZShqYXZhLmxhbmcuT2JqZWN0LCBieXRlKQorICAgICAgICBUZXN0RmllbGQgeCA9IG5ldyBUZXN0RmllbGQoKTsKKyAgICAgICAgRmllbGQgZiA9IG51bGw7CisgICAgICAgIGJ5dGUgdmFsID0gMDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiYnl0ZUZpZWxkIik7CisgICAgICAgICAgICBmLnNldEJ5dGUoeCwgKGJ5dGUpIDEpOworICAgICAgICAgICAgdmFsID0gZi5nZXRCeXRlKHgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBzZXRCeXRlIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGZsb2F0IGZpZWxkIHZhbHVlIiwgMSwgdmFsKTsKKworICAgICAgICAvL3Rlc3Qgd3JvbmcgdHlwZQorICAgICAgICBib29sZWFuIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJib29sZWFuRmllbGQiKTsKKyAgICAgICAgICAgIGYuc2V0Qnl0ZSh4LCBCeXRlLk1JTl9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJBY2Nlc3NlZCBmaWVsZCBvZiBpbnZhbGlkIHR5cGUiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIsIHRocm93bik7CisKKyAgICAgICAgLy90ZXN0IG5vdCBhY2Nlc3NpYmxlCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJieXRlUEZGaWVsZCIpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZi5pc0FjY2Vzc2libGUoKSk7CisgICAgICAgICAgICBmLnNldEJ5dGUoeCwgQnl0ZS5NSU5fVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiQWNjZXNzZWQgaW5hY2Nlc3NpYmxlIGZpZWxkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIsIHRocm93bik7CisKKyAgICAgIC8vVGVzdCBOUEUKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImJ5dGVGaWVsZCIpOworICAgICAgICAgICAgZi5zZXRCeXRlKG51bGwsIEJ5dGUuTUlOX1ZBTFVFKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vIFRlc3Qgc2V0dGluZyBhIHN0YXRpYyBmaWVsZDsKKyAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJieXRlU0ZpZWxkIik7CisgICAgICAgIGYuc2V0Qnl0ZShudWxsLCBCeXRlLk1JTl9WQUxVRSk7CisgICAgICAgIHZhbCA9IGYuZ2V0Qnl0ZSh4KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgYnl0ZSBmaWVsZCB2YWx1ZSIsIEJ5dGUuTUlOX1ZBTFVFLAorICAgICAgICAgICAgICAgIHZhbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjc2V0Q2hhcihqYXZhLmxhbmcuT2JqZWN0LCBjaGFyKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0Q2hhckxqYXZhX2xhbmdfT2JqZWN0QygpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkCisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkLnNldENoYXIoamF2YS5sYW5nLk9iamVjdCwgY2hhcikKKyAgICAgICAgVGVzdEZpZWxkIHggPSBuZXcgVGVzdEZpZWxkKCk7CisgICAgICAgIEZpZWxkIGYgPSBudWxsOworICAgICAgICBjaGFyIHZhbCA9IDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImNoYXJGaWVsZCIpOworICAgICAgICAgICAgZi5zZXRDaGFyKHgsIChjaGFyKSAxKTsKKyAgICAgICAgICAgIHZhbCA9IGYuZ2V0Q2hhcih4KTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgc2V0Q2hhciB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBmbG9hdCBmaWVsZCB2YWx1ZSIsIDEsIHZhbCk7CisKKyAgICAgIC8vdGVzdCB3cm9uZyB0eXBlCisgICAgICAgIGJvb2xlYW4gdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImJvb2xlYW5GaWVsZCIpOworICAgICAgICAgICAgZi5zZXRDaGFyKHgsIENoYXJhY3Rlci5NSU5fVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiQWNjZXNzZWQgZmllbGQgb2YgaW52YWxpZCB0eXBlIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vdGVzdCBub3QgYWNjZXNzaWJsZQorICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiY2hhclBGRmllbGQiKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGYuaXNBY2Nlc3NpYmxlKCkpOworICAgICAgICAgICAgZi5zZXRDaGFyKHgsIENoYXJhY3Rlci5NSU5fVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiQWNjZXNzZWQgaW5hY2Nlc3NpYmxlIGZpZWxkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIsIHRocm93bik7CisKKyAgICAgIC8vVGVzdCBOUEUKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImNoYXJGaWVsZCIpOworICAgICAgICAgICAgZi5zZXRDaGFyKG51bGwsIENoYXJhY3Rlci5NSU5fVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIsIHRocm93bik7CisKKyAgICAgICAgLy8gVGVzdCBzZXR0aW5nIGEgc3RhdGljIGZpZWxkOworICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImNoYXJTRmllbGQiKTsKKyAgICAgICAgZi5zZXRDaGFyKG51bGwsIENoYXJhY3Rlci5NSU5fVkFMVUUpOworICAgICAgICB2YWwgPSBmLmdldENoYXIoeCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGNoYXIgZmllbGQgdmFsdWUiLAorICAgICAgICAgICAgICAgIENoYXJhY3Rlci5NSU5fVkFMVUUsIHZhbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjc2V0RG91YmxlKGphdmEubGFuZy5PYmplY3QsIGRvdWJsZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldERvdWJsZUxqYXZhX2xhbmdfT2JqZWN0RCgpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkCisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkLnNldERvdWJsZShqYXZhLmxhbmcuT2JqZWN0LCBkb3VibGUpCisgICAgICAgIFRlc3RGaWVsZCB4ID0gbmV3IFRlc3RGaWVsZCgpOworICAgICAgICBGaWVsZCBmID0gbnVsbDsKKyAgICAgICAgZG91YmxlIHZhbCA9IDAuMDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiZG91YmxlRmllbGQiKTsKKyAgICAgICAgICAgIGYuc2V0RG91YmxlKHgsIERvdWJsZS5NSU5fVkFMVUUpOworICAgICAgICAgICAgdmFsID0gZi5nZXREb3VibGUoeCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHNldERvdWJsZSB0ZXN0OiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBkb3VibGUgZmllbGQgdmFsdWUiLCBEb3VibGUuTUlOX1ZBTFVFLAorICAgICAgICAgICAgICAgIHZhbCk7CisKKyAgICAgIC8vdGVzdCB3cm9uZyB0eXBlCisgICAgICAgIGJvb2xlYW4gdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImJvb2xlYW5GaWVsZCIpOworICAgICAgICAgICAgZi5zZXREb3VibGUoeCwgRG91YmxlLk1JTl9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJBY2Nlc3NlZCBmaWVsZCBvZiBpbnZhbGlkIHR5cGUiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIsIHRocm93bik7CisKKyAgICAgICAgLy90ZXN0IG5vdCBhY2Nlc3NpYmxlCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJkb3VibGVQRkZpZWxkIik7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShmLmlzQWNjZXNzaWJsZSgpKTsKKyAgICAgICAgICAgIGYuc2V0RG91YmxlKHgsIERvdWJsZS5NSU5fVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiQWNjZXNzZWQgaW5hY2Nlc3NpYmxlIGZpZWxkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIsIHRocm93bik7CisKKyAgICAgIC8vVGVzdCBOUEUKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImRvdWJsZUZpZWxkIik7CisgICAgICAgICAgICBmLnNldERvdWJsZShudWxsLCBEb3VibGUuTUlOX1ZBTFVFKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vIFRlc3Qgc2V0dGluZyBhIHN0YXRpYyBmaWVsZDsKKyAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJkb3VibGVTRmllbGQiKTsKKyAgICAgICAgZi5zZXREb3VibGUobnVsbCwgRG91YmxlLk1JTl9WQUxVRSk7CisgICAgICAgIHZhbCA9IGYuZ2V0RG91YmxlKHgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBkb3VibGUgZmllbGQgdmFsdWUiLAorICAgICAgICAgICAgICAgIERvdWJsZS5NSU5fVkFMVUUsIHZhbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjc2V0RmxvYXQoamF2YS5sYW5nLk9iamVjdCwgZmxvYXQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRGbG9hdExqYXZhX2xhbmdfT2JqZWN0RigpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkCisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkLnNldEZsb2F0KGphdmEubGFuZy5PYmplY3QsIGZsb2F0KQorICAgICAgICBUZXN0RmllbGQgeCA9IG5ldyBUZXN0RmllbGQoKTsKKyAgICAgICAgRmllbGQgZiA9IG51bGw7CisgICAgICAgIGZsb2F0IHZhbCA9IDAuMEY7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImZsb2F0RmllbGQiKTsKKyAgICAgICAgICAgIGYuc2V0RmxvYXQoeCwgRmxvYXQuTUlOX1ZBTFVFKTsKKyAgICAgICAgICAgIHZhbCA9IGYuZ2V0RmxvYXQoeCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHNldEZsb2F0IHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGZsb2F0IGZpZWxkIHZhbHVlIiwgRmxvYXQuTUlOX1ZBTFVFLAorICAgICAgICAgICAgICAgIHZhbCwgMC4wKTsKKworICAgICAgICAvL3Rlc3Qgd3JvbmcgdHlwZQorICAgICAgICBib29sZWFuIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJib29sZWFuRmllbGQiKTsKKyAgICAgICAgICAgIGYuc2V0RmxvYXQoeCwgRmxvYXQuTUlOX1ZBTFVFKTsKKyAgICAgICAgICAgIGZhaWwoIkFjY2Vzc2VkIGZpZWxkIG9mIGludmFsaWQgdHlwZSIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICAvL3Rlc3Qgbm90IGFjY2Vzc2libGUKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImZsb2F0UEZGaWVsZCIpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZi5pc0FjY2Vzc2libGUoKSk7CisgICAgICAgICAgICBmLnNldEZsb2F0KHgsIEZsb2F0Lk1JTl9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJBY2Nlc3NlZCBpbmFjY2Vzc2libGUgZmllbGQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgLy9UZXN0IE5QRQorICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiZmxvYXRGaWVsZCIpOworICAgICAgICAgICAgZi5zZXRGbG9hdChudWxsLCBGbG9hdC5NSU5fVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIsIHRocm93bik7CisKKyAgICAgICAgLy8gVGVzdCBzZXR0aW5nIGEgc3RhdGljIGZpZWxkOworICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImZsb2F0U0ZpZWxkIik7CisgICAgICAgIGYuc2V0RmxvYXQobnVsbCwgRmxvYXQuTUlOX1ZBTFVFKTsKKyAgICAgICAgdmFsID0gZi5nZXRGbG9hdCh4KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgZmxvYXQgZmllbGQgdmFsdWUiLAorICAgICAgICAgICAgICAgIEZsb2F0Lk1JTl9WQUxVRSwgdmFsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCNzZXRJbnQoamF2YS5sYW5nLk9iamVjdCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0SW50TGphdmFfbGFuZ19PYmplY3RJKCkgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS5sYW5nLnJlZmxlY3QuRmllbGQuc2V0SW50KGphdmEubGFuZy5PYmplY3QsCisgICAgICAgIC8vIGludCkKKyAgICAgICAgVGVzdEZpZWxkIHggPSBuZXcgVGVzdEZpZWxkKCk7CisgICAgICAgIEZpZWxkIGYgPSBudWxsOworICAgICAgICBpbnQgdmFsID0gMDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiaW50RmllbGQiKTsKKyAgICAgICAgICAgIGYuc2V0SW50KHgsIEludGVnZXIuTUlOX1ZBTFVFKTsKKyAgICAgICAgICAgIHZhbCA9IGYuZ2V0SW50KHgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBzZXRJbnRlZ2VyIHRlc3Q6ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGludCBmaWVsZCB2YWx1ZSIsIEludGVnZXIuTUlOX1ZBTFVFLAorICAgICAgICAgICAgICAgIHZhbCk7CisKKyAgICAgICAgLy8gdGVzdCB3cm9uZyB0eXBlCisgICAgICAgIGJvb2xlYW4gdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImJvb2xlYW5GaWVsZCIpOworICAgICAgICAgICAgZi5zZXRJbnQoeCwgSW50ZWdlci5NSU5fVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiQWNjZXNzZWQgZmllbGQgb2YgaW52YWxpZCB0eXBlIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vIHRlc3Qgbm90IGFjY2Vzc2libGUKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImludFBGRmllbGQiKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGYuaXNBY2Nlc3NpYmxlKCkpOworICAgICAgICAgICAgZi5zZXRJbnQoeCwgSW50ZWdlci5NSU5fVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiQWNjZXNzZWQgaW5hY2Nlc3NpYmxlIGZpZWxkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIsIHRocm93bik7CisKKyAgICAgICAgLy8gVGVzdCBOUEUKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoImludEZpZWxkIik7CisgICAgICAgICAgICBmLnNldEludChudWxsLCBJbnRlZ2VyLk1JTl9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICAvLyBUZXN0IHNldHRpbmcgYSBzdGF0aWMgZmllbGQ7CisgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgiaW50U0ZpZWxkIik7CisgICAgICAgIGYuc2V0SW50KG51bGwsIEludGVnZXIuTUlOX1ZBTFVFKTsKKyAgICAgICAgdmFsID0gZi5nZXRJbnQoeCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGludCBmaWVsZCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgSW50ZWdlci5NSU5fVkFMVUUsIHZhbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjc2V0TG9uZyhqYXZhLmxhbmcuT2JqZWN0LCBsb25nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0TG9uZ0xqYXZhX2xhbmdfT2JqZWN0SigpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkCisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkLnNldExvbmcoamF2YS5sYW5nLk9iamVjdCwgbG9uZykKKyAgICAgICAgVGVzdEZpZWxkIHggPSBuZXcgVGVzdEZpZWxkKCk7CisgICAgICAgIEZpZWxkIGYgPSBudWxsOworICAgICAgICBsb25nIHZhbCA9IDBMOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJsb25nRmllbGQiKTsKKyAgICAgICAgICAgIGYuc2V0TG9uZyh4LCBMb25nLk1JTl9WQUxVRSk7CisgICAgICAgICAgICB2YWwgPSBmLmdldExvbmcoeCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIHNldExvbmcgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgbG9uZyBmaWVsZCB2YWx1ZSIsIExvbmcuTUlOX1ZBTFVFLCB2YWwpOworCisgICAgICAgIC8vIHRlc3Qgd3JvbmcgdHlwZQorICAgICAgICBib29sZWFuIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJib29sZWFuRmllbGQiKTsKKyAgICAgICAgICAgIGYuc2V0TG9uZyh4LCBMb25nLk1JTl9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJBY2Nlc3NlZCBmaWVsZCBvZiBpbnZhbGlkIHR5cGUiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIsIHRocm93bik7CisKKyAgICAgICAgLy8gdGVzdCBub3QgYWNjZXNzaWJsZQorICAgICAgICB0aHJvd24gPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgibG9uZ1BGRmllbGQiKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGYuaXNBY2Nlc3NpYmxlKCkpOworICAgICAgICAgICAgZi5zZXRMb25nKHgsIExvbmcuTUlOX1ZBTFVFKTsKKyAgICAgICAgICAgIGZhaWwoIkFjY2Vzc2VkIGluYWNjZXNzaWJsZSBmaWVsZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIklsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vIFRlc3QgTlBFCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJsb25nRmllbGQiKTsKKyAgICAgICAgICAgIGYuc2V0TG9uZyhudWxsLCBMb25nLk1JTl9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICAvLyBUZXN0IHNldHRpbmcgYSBzdGF0aWMgZmllbGQ7CisgICAgICAgIGYgPSB4LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgibG9uZ1NGaWVsZCIpOworICAgICAgICBmLnNldExvbmcobnVsbCwgTG9uZy5NSU5fVkFMVUUpOworICAgICAgICB2YWwgPSBmLmdldExvbmcoeCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGxvbmcgZmllbGQgdmFsdWUiLAorICAgICAgICAgICAgICAgIExvbmcuTUlOX1ZBTFVFLCB2YWwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkI3NldFNob3J0KGphdmEubGFuZy5PYmplY3QsIHNob3J0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0U2hvcnRMamF2YV9sYW5nX09iamVjdFMoKSB0aHJvd3MgRXhjZXB0aW9ueworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZAorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZC5zZXRTaG9ydChqYXZhLmxhbmcuT2JqZWN0LCBzaG9ydCkKKyAgICAgICAgVGVzdEZpZWxkIHggPSBuZXcgVGVzdEZpZWxkKCk7CisgICAgICAgIEZpZWxkIGYgPSBudWxsOworICAgICAgICBzaG9ydCB2YWwgPSAwOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJzaG9ydEZpZWxkIik7CisgICAgICAgICAgICBmLnNldFNob3J0KHgsIFNob3J0Lk1JTl9WQUxVRSk7CisgICAgICAgICAgICB2YWwgPSBmLmdldFNob3J0KHgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBzZXRTaG9ydCB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBzaG9ydCBmaWVsZCB2YWx1ZSIsIFNob3J0Lk1JTl9WQUxVRSwKKyAgICAgICAgICAgICAgICB2YWwpOworCisgICAgICAgIC8vIHRlc3Qgd3JvbmcgdHlwZQorICAgICAgICBib29sZWFuIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJib29sZWFuRmllbGQiKTsKKyAgICAgICAgICAgIGYuc2V0U2hvcnQoeCwgU2hvcnQuTUlOX1ZBTFVFKTsKKyAgICAgICAgICAgIGZhaWwoIkFjY2Vzc2VkIGZpZWxkIG9mIGludmFsaWQgdHlwZSIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIiwgdGhyb3duKTsKKworICAgICAgICAvLyB0ZXN0IG5vdCBhY2Nlc3NpYmxlCisgICAgICAgIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJzaG9ydFBGRmllbGQiKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGYuaXNBY2Nlc3NpYmxlKCkpOworICAgICAgICAgICAgZi5zZXRTaG9ydCh4LCBTaG9ydC5NSU5fVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiQWNjZXNzZWQgaW5hY2Nlc3NpYmxlIGZpZWxkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93biA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleHBlY3RlZCBidXQgbm90IHRocm93biIsIHRocm93bik7CisKKyAgICAgICAgLy8gVGVzdCBOUEUKKyAgICAgICAgdGhyb3duID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmID0geC5nZXRDbGFzcygpLmdldERlY2xhcmVkRmllbGQoInNob3J0RmllbGQiKTsKKyAgICAgICAgICAgIGYuc2V0U2hvcnQobnVsbCwgU2hvcnQuTUlOX1ZBTFVFKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvd24gPSB0cnVlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQgYnV0IG5vdCB0aHJvd24iLCB0aHJvd24pOworCisgICAgICAgIC8vIFRlc3Qgc2V0dGluZyBhIHN0YXRpYyBmaWVsZDsKKyAgICAgICAgZiA9IHguZ2V0Q2xhc3MoKS5nZXREZWNsYXJlZEZpZWxkKCJzaG9ydFNGaWVsZCIpOworICAgICAgICBmLnNldFNob3J0KG51bGwsIFNob3J0Lk1JTl9WQUxVRSk7CisgICAgICAgIHZhbCA9IGYuZ2V0U2hvcnQoeCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHNob3J0IGZpZWxkIHZhbHVlIiwKKyAgICAgICAgICAgICAgICBTaG9ydC5NSU5fVkFMVUUsIHZhbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuRmllbGQjdG9TdHJpbmcoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9TdHJpbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuU3RyaW5nIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkLnRvU3RyaW5nKCkKKyAgICAgICAgRmllbGQgZiA9IG51bGw7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGYgPSBUZXN0RmllbGQuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgieCIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGdldHRpbmcgZmllbGQgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiRmllbGQgcmV0dXJuZWQgaW5jb3JyZWN0IHN0cmluZyIsCisgICAgICAgICAgICAgICAgInByaXZhdGUgc3RhdGljIGZpbmFsIGludCB0ZXN0cy5hcGkuamF2YS5sYW5nLnJlZmxlY3QuRmllbGRUZXN0JFRlc3RGaWVsZC54IiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGYudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREZWNsYXJlZEFubm90YXRpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpZWxkIGZpZWxkID0gVGVzdENsYXNzLmNsYXNzLmdldEZpZWxkKCJhbm5vdGF0ZWRGaWVsZCIpOworICAgICAgICBBbm5vdGF0aW9uW10gYW5ub3RhdGlvbnMgPSBmaWVsZC5nZXREZWNsYXJlZEFubm90YXRpb25zKCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBhbm5vdGF0aW9ucy5sZW5ndGgpOworCisgICAgICAgIFNldDxDbGFzczw/Pj4gaWdub3JlT3JkZXIgPSBuZXcgSGFzaFNldDxDbGFzczw/Pj4oKTsKKyAgICAgICAgaWdub3JlT3JkZXIuYWRkKGFubm90YXRpb25zWzBdLmFubm90YXRpb25UeXBlKCkpOworICAgICAgICBpZ25vcmVPcmRlci5hZGQoYW5ub3RhdGlvbnNbMV0uYW5ub3RhdGlvblR5cGUoKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTWlzc2luZyBAQW5ub3RhdGlvblJ1bnRpbWUwIiwgaWdub3JlT3JkZXIKKyAgICAgICAgICAgICAgICAuY29udGFpbnMoQW5ub3RhdGlvblJ1bnRpbWUwLmNsYXNzKSk7CisgICAgICAgIGFzc2VydFRydWUoIk1pc3NpbmcgQEFubm90YXRpb25SdW50aW1lMSIsIGlnbm9yZU9yZGVyCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKEFubm90YXRpb25SdW50aW1lMS5jbGFzcykpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNFbnVtQ29uc3RhbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmllbGQgZmllbGQgPSBUZXN0RW51bS5jbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJBIik7CisgICAgICAgIGFzc2VydFRydWUoIkVudW0gY29uc3RhbnQgbm90IHJlY29nbml6ZWQiLCBmaWVsZC5pc0VudW1Db25zdGFudCgpKTsKKworICAgICAgICBmaWVsZCA9IFRlc3RFbnVtLmNsYXNzLmdldERlY2xhcmVkRmllbGQoImZpZWxkIik7CisgICAgICAgIGFzc2VydEZhbHNlKCJOb24gZW51bSBjb25zdGFudCB3cm9uZ2x5IHN0YXRlZCBhcyBlbnVtIGNvbnN0YW50IiwgZmllbGQKKyAgICAgICAgICAgICAgICAuaXNFbnVtQ29uc3RhbnQoKSk7CisKKyAgICAgICAgZmllbGQgPSBUZXN0Q2xhc3MuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgiYW5ub3RhdGVkRmllbGQiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIk5vbiBlbnVtIGNvbnN0YW50IHdyb25nbHkgc3RhdGVkIGFzIGVudW0gY29uc3RhbnQiLCBmaWVsZAorICAgICAgICAgICAgICAgIC5pc0VudW1Db25zdGFudCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzU3ludGhldGljKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpZWxkW10gZmllbGRzID0gVGVzdENsYXNzLklubmVyLmNsYXNzLmdldERlY2xhcmVkRmllbGRzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiTm90IGV4YWN0bHkgb25lIGZpZWxkIHJldHVybmVkIiwgMSwgZmllbGRzLmxlbmd0aCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRW51bSBjb25zdGFudCBub3QgcmVjb2duaXplZCIsIGZpZWxkc1swXS5pc1N5bnRoZXRpYygpKTsKKworICAgICAgICBGaWVsZCBmaWVsZCA9IFRlc3RFbnVtLmNsYXNzLmdldERlY2xhcmVkRmllbGQoImZpZWxkIik7CisgICAgICAgIGFzc2VydEZhbHNlKCJOb24gc3ludGhldGljIGZpZWxkIHdyb25nbHkgc3RhdGVkIGFzIHN5bnRoZXRpYyIsIGZpZWxkCisgICAgICAgICAgICAgICAgLmlzU3ludGhldGljKCkpOworCisgICAgICAgIGZpZWxkID0gVGVzdENsYXNzLmNsYXNzLmdldERlY2xhcmVkRmllbGQoImFubm90YXRlZEZpZWxkIik7CisgICAgICAgIGFzc2VydEZhbHNlKCJOb24gc3ludGhldGljIGZpZWxkIHdyb25nbHkgc3RhdGVkIGFzIHN5bnRoZXRpYyIsIGZpZWxkCisgICAgICAgICAgICAgICAgLmlzU3ludGhldGljKCkpOworICAgIH0KKworCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRHZW5lcmljVHlwZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBGaWVsZCBmaWVsZCA9IEdlbmVyaWNGaWVsZC5jbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJmaWVsZCIpOworICAgICAgICBUeXBlIHR5cGUgPSBmaWVsZC5nZXRHZW5lcmljVHlwZSgpOworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgVHlwZVZhcmlhYmxlIHR5cGVWYXIgPSAoVHlwZVZhcmlhYmxlKSB0eXBlOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHR5cGUgbmFtZSByZXR1cm5lZCIsICJTIiwgdHlwZVZhci5nZXROYW1lKCkpOworCisgICAgICAgIEZpZWxkIGJvdW5kZWRGaWVsZCA9IEdlbmVyaWNGaWVsZC5jbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJib3VuZGVkRmllbGQiKTsKKyAgICAgICAgVHlwZSBib3VuZGVkVHlwZSA9IGJvdW5kZWRGaWVsZC5nZXRHZW5lcmljVHlwZSgpOworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgVHlwZVZhcmlhYmxlIGJvdW5kZWRUeXBlVmFyID0gKFR5cGVWYXJpYWJsZSkgYm91bmRlZFR5cGU7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdHlwZSBuYW1lIHJldHVybmVkIiwgIlQiLCBib3VuZGVkVHlwZVZhci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIk1vcmUgdGhhbiBvbmUgYm91bmQgZm91bmQiLCAxLAorICAgICAgICAgICAgICAgIGJvdW5kZWRUeXBlVmFyLmdldEJvdW5kcygpLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgYm91bmQgcmV0dXJuZWQiLCBOdW1iZXIuY2xhc3MsCisgICAgICAgICAgICAgICAgYm91bmRlZFR5cGVWYXIuZ2V0Qm91bmRzKClbMF0pOworICAgIH0KKworCisgICAgcHVibGljIHZvaWQgdGVzdF90b0dlbmVyaWNTdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmllbGQgZmllbGQgPSBHZW5lcmljRmllbGQuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgiZmllbGQiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBnZW5lcmljIHN0cmluZyByZXR1cm5lZCIsCisgICAgICAgICAgICAgICAgIlMgdGVzdHMuYXBpLmphdmEubGFuZy5yZWZsZWN0LkZpZWxkVGVzdCRHZW5lcmljRmllbGQuZmllbGQiLAorICAgICAgICAgICAgICAgIGZpZWxkLnRvR2VuZXJpY1N0cmluZygpKTsKKworICAgICAgICBGaWVsZCBib3VuZGVkRmllbGQgPSBHZW5lcmljRmllbGQuY2xhc3MKKyAgICAgICAgICAgICAgICAuZ2V0RGVjbGFyZWRGaWVsZCgiYm91bmRlZEZpZWxkIik7CisgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAiV3JvbmcgZ2VuZXJpYyBzdHJpbmcgcmV0dXJuZWQiLAorICAgICAgICAgICAgICAgICJUIHRlc3RzLmFwaS5qYXZhLmxhbmcucmVmbGVjdC5GaWVsZFRlc3QkR2VuZXJpY0ZpZWxkLmJvdW5kZWRGaWVsZCIsCisgICAgICAgICAgICAgICAgYm91bmRlZEZpZWxkLnRvR2VuZXJpY1N0cmluZygpKTsKKworICAgICAgICBGaWVsZCBvcmRpbmFyeSA9IEdlbmVyaWNGaWVsZC5jbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJpbnRGaWVsZCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgIldyb25nIGdlbmVyaWMgc3RyaW5nIHJldHVybmVkIiwKKyAgICAgICAgICAgICAgICAiaW50IHRlc3RzLmFwaS5qYXZhLmxhbmcucmVmbGVjdC5GaWVsZFRlc3QkR2VuZXJpY0ZpZWxkLmludEZpZWxkIiwKKyAgICAgICAgICAgICAgICBvcmRpbmFyeS50b0dlbmVyaWNTdHJpbmcoKSk7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc2hDb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpZWxkIGZpZWxkID0gVGVzdENsYXNzLmNsYXNzLmdldERlY2xhcmVkRmllbGQoImFubm90YXRlZEZpZWxkIik7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgaGFzaENvZGUgcmV0dXJuZWQiLCBmaWVsZC5nZXROYW1lKCkuaGFzaENvZGUoKQorICAgICAgICAgICAgICAgIF4gZmllbGQuZ2V0RGVjbGFyaW5nQ2xhc3MoKS5nZXROYW1lKCkuaGFzaENvZGUoKSwgZmllbGQKKyAgICAgICAgICAgICAgICAuaGFzaENvZGUoKSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWFycyBkb3duIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgY2xvc2UgYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMKKyAgICAgKiBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICB9Cit9CisKK2NsYXNzIFRlc3RBY2Nlc3MgeworICAgIHByaXZhdGUgc3RhdGljIGludCB4eHg7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L0dlbmVyaWNBcnJheVR5cGVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L0dlbmVyaWNBcnJheVR5cGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTQ4ZTU4NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvR2VuZXJpY0FycmF5VHlwZVRlc3QuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5HZW5lcmljQXJyYXlUeXBlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlBhcmFtZXRlcml6ZWRUeXBlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVHlwZVZhcmlhYmxlOworCisvKioKKyAqIFRlc3RzIGdlbmVyaWMgcmVmbGVjdGlvbiBvbiBhcnJheXMgd2l0aCBnZW5lcmljIG9yIHBhcmFtZXRlcml6ZWQgY29tcG9uZW50IHR5cGVzLgorICovCitwdWJsaWMgY2xhc3MgR2VuZXJpY0FycmF5VHlwZVRlc3QgZXh0ZW5kcyBHZW5lcmljUmVmbGVjdGlvblRlc3RzQmFzZSB7CisKKyAgICBzdGF0aWMgY2xhc3MgQTxUPiB7CisgICAgICAgIFRbXSBhcnJheTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldEdlbmVyaWNDb21wb25lbnRUeXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICBDbGFzczw/IGV4dGVuZHMgQT4gY2xhenogPSBHZW5lcmljQXJyYXlUeXBlVGVzdC5BLmNsYXNzOworICAgICAgICBGaWVsZCBmaWVsZCA9IGNsYXp6LmdldERlY2xhcmVkRmllbGQoImFycmF5Iik7CisgICAgICAgIFR5cGUgZ2VuZXJpY1R5cGUgPSBmaWVsZC5nZXRHZW5lcmljVHlwZSgpOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKEdlbmVyaWNBcnJheVR5cGUuY2xhc3MsIGdlbmVyaWNUeXBlKTsKKyAgICAgICAgVHlwZSBjb21wb25lbnRUeXBlID0gKChHZW5lcmljQXJyYXlUeXBlKSBnZW5lcmljVHlwZSkuZ2V0R2VuZXJpY0NvbXBvbmVudFR5cGUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGdldFR5cGVQYXJhbWV0ZXIoY2xhenopLCBjb21wb25lbnRUeXBlKTsKKyAgICAgICAgYXNzZXJ0SW5zdGFuY2VPZihUeXBlVmFyaWFibGUuY2xhc3MsIGNvbXBvbmVudFR5cGUpOworICAgICAgICBUeXBlVmFyaWFibGU8Pz4gY29tcG9uZW50VHlwZVZhcmlhYmxlID0gKFR5cGVWYXJpYWJsZTw/PikgY29tcG9uZW50VHlwZTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUIiwgY29tcG9uZW50VHlwZVZhcmlhYmxlLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjbGF6eiwgY29tcG9uZW50VHlwZVZhcmlhYmxlLmdldEdlbmVyaWNEZWNsYXJhdGlvbigpKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgQjxUPiB7CisgICAgICAgIEI8VD5bXSBhcnJheTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFBhcmFtZXRlcml6ZWRDb21wb25lbnRUeXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICBDbGFzczw/IGV4dGVuZHMgQj4gY2xhenogPSBHZW5lcmljQXJyYXlUeXBlVGVzdC5CLmNsYXNzOworICAgICAgICBGaWVsZCBmaWVsZCA9IGNsYXp6LmdldERlY2xhcmVkRmllbGQoImFycmF5Iik7CisgICAgICAgIFR5cGUgZ2VuZXJpY1R5cGUgPSBmaWVsZC5nZXRHZW5lcmljVHlwZSgpOworCisgICAgICAgIGFzc2VydEluc3RhbmNlT2YoR2VuZXJpY0FycmF5VHlwZS5jbGFzcywgZ2VuZXJpY1R5cGUpOworICAgICAgICBHZW5lcmljQXJyYXlUeXBlIGFycmF5VHlwZSA9IChHZW5lcmljQXJyYXlUeXBlKSBnZW5lcmljVHlwZTsKKyAgICAgICAgVHlwZSBjb21wb25lbnRUeXBlID0gYXJyYXlUeXBlLmdldEdlbmVyaWNDb21wb25lbnRUeXBlKCk7CisgICAgICAgIGFzc2VydEluc3RhbmNlT2YoUGFyYW1ldGVyaXplZFR5cGUuY2xhc3MsIGNvbXBvbmVudFR5cGUpOworICAgICAgICBQYXJhbWV0ZXJpemVkVHlwZSBwYXJhbWV0ZXJpZXpkVHlwZSA9IChQYXJhbWV0ZXJpemVkVHlwZSkgY29tcG9uZW50VHlwZTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNsYXp6LCBwYXJhbWV0ZXJpZXpkVHlwZS5nZXRSYXdUeXBlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoY2xhenouZ2V0VHlwZVBhcmFtZXRlcnMoKVswXSwgcGFyYW1ldGVyaWV6ZFR5cGUuZ2V0QWN0dWFsVHlwZUFyZ3VtZW50cygpWzBdKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L0dlbmVyaWNNZXRob2RzVGVzdHMuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvR2VuZXJpY01ldGhvZHNUZXN0cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBiZmMxODgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L0dlbmVyaWNNZXRob2RzVGVzdHMuamF2YQpAQCAtMCwwICsxLDEyMSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEubGFuZy5yZWZsZWN0OworCisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5UeXBlVmFyaWFibGU7CisKKworLyoqCisgKiBUZXN0cyB1bmJvdW5kZWQgdHlwZSBwYXJhbWV0ZXJzIGRlY2xhcmVkIG9uIG1ldGhvZHMuCisgKi8KK3B1YmxpYyBjbGFzcyBHZW5lcmljTWV0aG9kc1Rlc3RzIGV4dGVuZHMgR2VuZXJpY1JlZmxlY3Rpb25UZXN0c0Jhc2V7CisKKyAgICBzdGF0aWMgY2xhc3MgR2VuZXJpY01ldGhvZHMgeworCisgICAgICAgIHB1YmxpYyA8VD4gdm9pZCBub1BhcmFtTm9SZXR1cm4oKSB7fQorCisgICAgICAgIHB1YmxpYyA8VD4gdm9pZCBwYXJhbU5vUmV0dXJuKFQgcGFyYW0pIHt9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgICAgIHB1YmxpYyA8VD4gVCBub1BhcmFtUmV0dXJuKCkgeyByZXR1cm4gKFQpIG5ldyBPYmplY3QoKTsgfQorCisgICAgICAgIHB1YmxpYyA8VD4gVCBwYXJhbVJldHVybihUIHBhcmFtKSB7cmV0dXJuIHBhcmFtO30KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBDbGFzczw/IGV4dGVuZHMgR2VuZXJpY01ldGhvZHM+IGNsYXp6ID0gR2VuZXJpY01ldGhvZHNUZXN0cy5HZW5lcmljTWV0aG9kcy5jbGFzczsKKworICAgIC8qKgorICAgICAqIFRlc3RzIHRoYXQgdGhlcmUgYXJlIG5vIFR5cGUgUGFyYW1ldGVycyBvbiB0aGUgQ2xhc3MgaXRzZWxmLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmljTWV0aG9kcygpIHsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0WmVybyhjbGF6ei5nZXRUeXBlUGFyYW1ldGVycygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgbWV0aG9kIGRlY2xhcmVzIGEgdHlwZSBwYXJhbWV0ZXIgVC4KKyAgICAgKiBAcGFyYW0gbWV0aG9kIHRoZSBtZXRob2QKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY2hlY2tUeXBlUGFyYW1ldGVyKE1ldGhvZCBtZXRob2QpIHsKKyAgICAgICAgVHlwZVZhcmlhYmxlPE1ldGhvZD4gdHlwZVBhcmFtZXRlciA9IGdldFR5cGVQYXJhbWV0ZXIobWV0aG9kKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUIiwgdHlwZVBhcmFtZXRlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobWV0aG9kLCB0eXBlUGFyYW1ldGVyLmdldEdlbmVyaWNEZWNsYXJhdGlvbigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgbWV0aG9kIGRlY2xhcmVzIGEgcGFyYW1ldGVyIHdpdGggdGhlCisgICAgICogdHlwZSBvZiB0aGUgdHlwZSBwYXJhbWV0ZXIuCisgICAgICogQHBhcmFtIG1ldGhvZCB0aGUgbWV0aG9kCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrUGFyYW1ldGVyVHlwZShNZXRob2QgbWV0aG9kKSB7CisgICAgICAgIFR5cGVWYXJpYWJsZTxNZXRob2Q+IHR5cGVQYXJhbWV0ZXIgPSBnZXRUeXBlUGFyYW1ldGVyKG1ldGhvZCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZShtZXRob2QuZ2V0R2VuZXJpY1BhcmFtZXRlclR5cGVzKCkpOworICAgICAgICBUeXBlIGdlbmVyaWNQYXJhbWV0ZXJUeXBlID0gbWV0aG9kLmdldEdlbmVyaWNQYXJhbWV0ZXJUeXBlcygpWzBdOworICAgICAgICBhc3NlcnRFcXVhbHModHlwZVBhcmFtZXRlciwgZ2VuZXJpY1BhcmFtZXRlclR5cGUpOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKFR5cGVWYXJpYWJsZS5jbGFzcywgZ2VuZXJpY1BhcmFtZXRlclR5cGUpOworICAgICAgICBhc3NlcnRFcXVhbHMobWV0aG9kLCAoKFR5cGVWYXJpYWJsZTw/PikgZ2VuZXJpY1BhcmFtZXRlclR5cGUpLmdldEdlbmVyaWNEZWNsYXJhdGlvbigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB3aGV0aGVyIHRoZSB0eXBlIG9mIHRoZSByZXR1cm4gdHlwZSBpcyB0aGUgZGVjbGFyZWQgdHlwZSBwYXJhbWV0ZXIuCisgICAgICogQHBhcmFtIG1ldGhvZCB0aGUgZGVjbGFyaW5nIG1ldGhvZAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjaGVja1JldHVyblR5cGUoTWV0aG9kIG1ldGhvZCkgeworICAgICAgICBUeXBlVmFyaWFibGU8TWV0aG9kPiB0eXBlUGFyYW1ldGVyID0gZ2V0VHlwZVBhcmFtZXRlcihtZXRob2QpOworICAgICAgICBUeXBlIGdlbmVyaWNSZXR1cm5UeXBlID0gbWV0aG9kLmdldEdlbmVyaWNSZXR1cm5UeXBlKCk7CisgICAgICAgIGFzc2VydEVxdWFscyh0eXBlUGFyYW1ldGVyLCBnZW5lcmljUmV0dXJuVHlwZSk7CisgICAgICAgIGFzc2VydEluc3RhbmNlT2YoVHlwZVZhcmlhYmxlLmNsYXNzLCBnZW5lcmljUmV0dXJuVHlwZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtZXRob2QsICgoVHlwZVZhcmlhYmxlPD8+KSBnZW5lcmljUmV0dXJuVHlwZSkuZ2V0R2VuZXJpY0RlY2xhcmF0aW9uKCkpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9QYXJhbU5vUmV0dXJuKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBjbGF6ei5nZXRNZXRob2QoIm5vUGFyYW1Ob1JldHVybiIpOworICAgICAgICBjaGVja1R5cGVQYXJhbWV0ZXIobWV0aG9kKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyYW1Ob1JldHVybigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNZXRob2QgbWV0aG9kID0gY2xhenouZ2V0TWV0aG9kKCJwYXJhbU5vUmV0dXJuIiwgT2JqZWN0LmNsYXNzKTsKKyAgICAgICAgY2hlY2tUeXBlUGFyYW1ldGVyKG1ldGhvZCk7CisgICAgICAgIGNoZWNrUGFyYW1ldGVyVHlwZShtZXRob2QpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROb1BhcmFtUmV0dXJuKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBjbGF6ei5nZXRNZXRob2QoIm5vUGFyYW1SZXR1cm4iKTsKKyAgICAgICAgY2hlY2tUeXBlUGFyYW1ldGVyKG1ldGhvZCk7CisgICAgICAgIGFzc2VydExlbmdodFplcm8obWV0aG9kLmdldEdlbmVyaWNQYXJhbWV0ZXJUeXBlcygpKTsKKyAgICAgICAgY2hlY2tSZXR1cm5UeXBlKG1ldGhvZCk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJhbVJldHVybigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNZXRob2QgbWV0aG9kID0gY2xhenouZ2V0TWV0aG9kKCJwYXJhbVJldHVybiIsIE9iamVjdC5jbGFzcyk7CisgICAgICAgIGNoZWNrVHlwZVBhcmFtZXRlcihtZXRob2QpOworICAgICAgICBjaGVja1BhcmFtZXRlclR5cGUobWV0aG9kKTsKKyAgICAgICAgY2hlY2tSZXR1cm5UeXBlKG1ldGhvZCk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbmRlcGVuZGVuY3lPZk1ldGhvZFR5cGVQYXJhbWV0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZCBtZXRob2QwID0gY2xhenouZ2V0TWV0aG9kKCJwYXJhbU5vUmV0dXJuIiwgT2JqZWN0LmNsYXNzKTsKKyAgICAgICAgVHlwZVZhcmlhYmxlPE1ldGhvZD4gdHlwZVBhcmFtZXRlcjAgPSBtZXRob2QwLmdldFR5cGVQYXJhbWV0ZXJzKClbMF07CisKKyAgICAgICAgTWV0aG9kIG1ldGhvZDEgPSBjbGF6ei5nZXRNZXRob2QoIm5vUGFyYW1Ob1JldHVybiIpOworICAgICAgICBUeXBlVmFyaWFibGU8TWV0aG9kPiB0eXBlUGFyYW1ldGVyMSA9IG1ldGhvZDEuZ2V0VHlwZVBhcmFtZXRlcnMoKVswXTsKKworICAgICAgICAvL0dlbmVyaWMgbWV0aG9kIHR5cGUgcGFyYW1ldGVycyBOQU1FUyBhcmUgZXF1YWwKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHR5cGVQYXJhbWV0ZXIwLmdldE5hbWUoKSwgdHlwZVBhcmFtZXRlcjEuZ2V0TmFtZSgpKTsKKyAgICAgICAgLy9HZW5lcmljIG1ldGhvZCB0eXBlIFBBUkFNRVRFUlMgYXJlIG5vdCBlcXVhbAorICAgICAgICBhc3NlcnROb3RFcXVhbHModHlwZVBhcmFtZXRlcjAsIHR5cGVQYXJhbWV0ZXIxKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L0dlbmVyaWNSZWZsZWN0aW9uVGVzdHNCYXNlLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L0dlbmVyaWNSZWZsZWN0aW9uVGVzdHNCYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDk1YmI3MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvR2VuZXJpY1JlZmxlY3Rpb25UZXN0c0Jhc2UuamF2YQpAQCAtMCwwICsxLDc0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVHlwZVZhcmlhYmxlOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgR2VuZXJpY1JlZmxlY3Rpb25UZXN0c0Jhc2UgZXh0ZW5kcyBUZXN0Q2FzZXsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHR5cGUgcGFyYW1ldGVyIG9mIHRoZSBkZWNsYXJpbmcgbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIG1ldGhvZAorICAgICAqICAgICAgICAgICAgdGhlIGRlY2xhcmluZyBtZXRob2QKKyAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIHBhcmFtZXRlciBvZiB0aGUgbWV0aG9kCisgICAgICovCisgICAgcHVibGljIFR5cGVWYXJpYWJsZTxNZXRob2Q+IGdldFR5cGVQYXJhbWV0ZXIoTWV0aG9kIG1ldGhvZCkgeworICAgICAgICBUeXBlVmFyaWFibGU8TWV0aG9kPltdIHR5cGVQYXJhbWV0ZXJzID0gbWV0aG9kLmdldFR5cGVQYXJhbWV0ZXJzKCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZSh0eXBlUGFyYW1ldGVycyk7CisgICAgICAgIFR5cGVWYXJpYWJsZTxNZXRob2Q+IHR5cGVQYXJhbWV0ZXIgPSB0eXBlUGFyYW1ldGVyc1swXTsKKyAgICAgICAgcmV0dXJuIHR5cGVQYXJhbWV0ZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdHlwZSBwYXJhbWV0ZXIgb2YgdGhlIGRlY2xhcmluZyBjbGFzcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXRob2QKKyAgICAgKiAgICAgICAgICAgIHRoZSBkZWNsYXJpbmcgbWV0aG9kLgorICAgICAqIEByZXR1cm4gdGhlIHR5cGUgcGFyYW1ldGVyIG9mIHRoZSBtZXRob2QuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIFR5cGVWYXJpYWJsZTxDbGFzcz4gZ2V0VHlwZVBhcmFtZXRlcihDbGFzczw/PiBjbGF6eikgeworICAgICAgICBUeXBlVmFyaWFibGVbXSB0eXBlUGFyYW1ldGVycyA9IGNsYXp6LmdldFR5cGVQYXJhbWV0ZXJzKCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZSh0eXBlUGFyYW1ldGVycyk7CisgICAgICAgIFR5cGVWYXJpYWJsZTxDbGFzcz4gdHlwZVZhcmlhYmxlID0gdHlwZVBhcmFtZXRlcnNbMF07CisgICAgICAgIGFzc2VydEVxdWFscyhjbGF6eiwgdHlwZVZhcmlhYmxlLmdldEdlbmVyaWNEZWNsYXJhdGlvbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUIiwgdHlwZVZhcmlhYmxlLmdldE5hbWUoKSk7CisgICAgICAgIHJldHVybiB0eXBlVmFyaWFibGU7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydExlbmdodE9uZShPYmplY3RbXSBhcnJheSkgeworICAgICAgICBUZXN0Q2FzZS5hc3NlcnRFcXVhbHMoIkFycmF5IGRvZXMgTk9UIGNvbnRhaW4gZXhhY3RseSBvbmUgZWxlbWVudC4iLCAxLCBhcnJheS5sZW5ndGgpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRMZW5naHRaZXJvKE9iamVjdFtdIGFycmF5KSB7CisgICAgICAgIFRlc3RDYXNlLmFzc2VydEVxdWFscygiQXJyYXkgaGFzIG1vcmUgdGhhbiB6ZXJvIGVsZW1lbnRzLiIsIDAsIGFycmF5Lmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydEluc3RhbmNlT2YoQ2xhc3M8Pz4gZXhwZWN0ZWRDbGFzcywgT2JqZWN0IGFjdHVhbCkgeworICAgICAgICBUZXN0Q2FzZS5hc3NlcnRUcnVlKGFjdHVhbC5nZXRDbGFzcygpLmdldE5hbWUoKSArICIgaXMgbm90IGluc3RhbmNlIG9mIDoiICsgZXhwZWN0ZWRDbGFzcy5nZXROYW1lKCksIGV4cGVjdGVkQ2xhc3MKKyAgICAgICAgICAgICAgICAuaXNJbnN0YW5jZShhY3R1YWwpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYXNzZXJ0Tm90RXF1YWxzKE9iamVjdCBleHBlY3RlZCwgT2JqZWN0IGFjdHVhbCkgeworICAgICAgICBUZXN0Q2FzZS5hc3NlcnRGYWxzZShhY3R1YWwudG9TdHJpbmcoKSArICIgaGFzIG5vdCB0byBiZSBlcXVhbCB0byAiICsgZXhwZWN0ZWQudG9TdHJpbmcoKSwgZXhwZWN0ZWQuZXF1YWxzKGFjdHVhbCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvcmVmbGVjdC9HZW5lcmljU2lnbmF0dXJlRm9ybWF0RXJyb3JUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L0dlbmVyaWNTaWduYXR1cmVGb3JtYXRFcnJvclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NTQwNzNjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvcmVmbGVjdC9HZW5lcmljU2lnbmF0dXJlRm9ybWF0RXJyb3JUZXN0LmphdmEKQEAgLTAsMCArMSwxMDEgQEAKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEubGFuZy5yZWZsZWN0OworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uQW5kcm9pZE9ubHk7CitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uU2lkZUVmZmVjdDsKK2ltcG9ydCBkYWx2aWsuc3lzdGVtLkRleEZpbGU7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5HZW5lcmljU2lnbmF0dXJlRm9ybWF0RXJyb3I7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVHlwZVZhcmlhYmxlOworCitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0NsYXNzTG9hZGVyOworCitwdWJsaWMgY2xhc3MgR2VuZXJpY1NpZ25hdHVyZUZvcm1hdEVycm9yVGVzdCBleHRlbmRzIFRlc3RDYXNleworCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXcgR2VuZXJpY1NpZ25hdHVyZUZvcm1hdEVycm9yKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVhZFJlc291cmNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgdGYgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJjbGFzc2VzIiwgIi5kZXgiKTsKKyAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJHZW5lcmljU2lnbmF0dXJlRm9ybWF0RXJyb3JUZXN0OiIKKyAgICAgICAgLy8gICAgICAgICArdGYuZ2V0QWJzb2x1dGVQYXRoKCkrIiwgY2FuUmVhZDogIit0Zi5jYW5SZWFkKCkKKyAgICAgICAgLy8gICAgICAgICArIiwgY2FuV3JpdGU6ICIrdGYuY2FuV3JpdGUoKSk7CisgICAgICAgIElucHV0U3RyZWFtIGlzID0gdGhpcy5nZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oImRleDEuYnl0ZXMiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChpcyk7CisgICAgfQorCisKKyAgICBAQW5kcm9pZE9ubHkoIlVzZXMgQW5kcm9pZCBzcGVjaWZpYyBjbGFzcyBkYWx2aWsuc3lzdGVtLkRleEZpbGUgIiArCisgICAgICAgICAgICAiZm9yIGxvYWRpbmcgY2xhc3Nlcy4iKQorICAgIEBTaWRlRWZmZWN0KCJzdHJhbmdlIGlzc3VlIChleGNlcHRpb246ICdjb3VsZCBub3Qgb3BlbiBkZXggZmlsZScsICIgKworICAgICAgICAgICAgImRhbHZpa3ZtOiAnd2FpdHBpZCBmYWlsZWQnIGxvZyBtc2cgIC0gb25seSBvY2N1cnMgd2hlbiBAU2lkZUVmZmVjdCBpcyByZW1vdmVkICIgKworICAgICAgICAgICAgImFuZCB0aGlzIHRlc3QgaXMgcnVuIHZpYSBydW5uaW5nIHRlc3RzLmx1bmkuQWxsVGVzdHNMYW5nIFRlc3RTdWl0ZSIpCisgICAgcHVibGljIHZvaWQgdGVzdF9zaWduYXR1cmVGb3JtYXRFcnJvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvKgorICAgICAgICAgKiBkZXgxLmJ5dGVzIGlzIGEgamFyIGZpbGUgd2l0aCBhIGNsYXNzZXMuZGV4IGluIGl0LgorICAgICAgICAgKiB0aGUgY2xhc3Nlcy5kZXggd2FzIGphdmFjJ2VkLCBkeCdlZCBhbmQgcGF0Y2hlZAorICAgICAgICAgKiB3aXRoIHRoZSBmb2xsb3dpbmcgamF2YSBmaWxlOgorICAgICAgICAgKgorICAgICAgICAgKiBwYWNrYWdlIGRlbW87CisgICAgICAgICAqICBwdWJsaWMgY2xhc3MgSGVsbG9Xb3JsZDxVPiB7CisgICAgICAgICAqICAgICAgcHVibGljIEhlbGxvV29ybGQoVSB0KSB7fQorICAgICAgICAgKiAgfQorICAgICAgICAgKgorICAgICAgICAgKiBwYXRjaDoKKyAgICAgICAgICogdGhlIHN0cmluZyBjb25zdGFudCAoY2xhc3MgZ2VuZXJpY3Mgc2lnbmF0dXJlIHN0cmluZykKKyAgICAgICAgICogICI8VToiIHdhcyBjaGFuZ2VkIHRvICI8PDoiCisgICAgICAgICAqCisgICAgICAgICAqLworCisgICAgICAgIEZpbGUgdGYgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJjbGFzc2VzIiwgIi5kZXgiKTsKKyAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJHZW5lcmljU2lnbmF0dXJlRm9ybWF0RXJyb3JUZXN0OiIgKworICAgICAgICAvLyAgICAgICAgIHRmLmdldEFic29sdXRlUGF0aCgpICsgIiwgY2FuUmVhZDogIiArIHRmLmNhblJlYWQoKSArCisgICAgICAgIC8vICAgICAgICAgIiwgY2FuV3JpdGU6ICIrdGYuY2FuV3JpdGUoKSk7CisgICAgICAgIElucHV0U3RyZWFtIGlzID0gdGhpcy5nZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oImRleDEuYnl0ZXMiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChpcyk7CisgICAgICAgIE91dHB1dFN0cmVhbSBmb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbSh0Zik7CisgICAgICAgIGNvcHkoaXMsIGZvcyk7CisgICAgICAgIGZvcy5mbHVzaCgpOworICAgICAgICBmb3MuY2xvc2UoKTsKKworCisgICAgICAgIC8vIGNsYXNzIHNpZ25hdHVyZSBzdHJpbmcgIjxVOiIgd2FzIGNoYW5nZWQgdG8gIjw8OiIKKyAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oImZpbGUgbGVuZ3RoOiIrdGYubGVuZ3RoKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gV2FzOgorICAgICAgICAgICAgLy8gRGV4RmlsZSBkZiA9IG5ldyBEZXhGaWxlKHRmKTsKKyAgICAgICAgICAgIC8vIENsYXNzIGNsYXp6ID0gZGYubG9hZENsYXNzKCJkZW1vL0hlbGxvV29ybGQiLCB0aGlzLmdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKSk7CisKKyAgICAgICAgICAgIENsYXNzTG9hZGVyIGNsID0gU3VwcG9ydF9DbGFzc0xvYWRlci5nZXRJbnN0YW5jZSh0Zi50b1VSTCgpLAorICAgICAgICAgICAgICAgICAgICBnZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCkpOworCisgICAgICAgICAgICBDbGFzcyBjbGF6eiA9IGNsLmxvYWRDbGFzcygiZGVtby9IZWxsb1dvcmxkIik7CisgICAgICAgICAgICBUeXBlVmFyaWFibGVbXSB0dnMgPSBjbGF6ei5nZXRUeXBlUGFyYW1ldGVycygpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0aW5nIGEgR2VuZXJpY1NpZ25hdHVyZUZvcm1hdEVycm9yIik7CisgICAgICAgICAgICAvLyBmb3IgKFR5cGVWYXJpYWJsZSB0diA6IHR2cykgeworICAgICAgICAgICAgLy8gICAgIFN5c3RlbS5vdXQucHJpbnRsbigidHY6Iit0di50b1N0cmluZygpKTsKKyAgICAgICAgICAgIC8vIH0KKyAgICAgICAgfSBjYXRjaCAoR2VuZXJpY1NpZ25hdHVyZUZvcm1hdEVycm9yIGdzZmUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY29weShJbnB1dFN0cmVhbSBpcywgT3V0cHV0U3RyZWFtIG9zKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgYjsKKyAgICAgICAgICAgIHdoaWxlICgoYiA9IGlzLnJlYWQoKSkgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICBvcy53cml0ZShiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlzLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiaW8gZXJyb3IiLCBleCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWU2OTlhOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDMwNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS5sYW5nLnJlZmxlY3Q7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkNoYXJBcnJheVdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLlByaW50U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXI7CisKK3B1YmxpYyBjbGFzcyBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBzdGF0aWMgY2xhc3MgVGVzdE1ldGhvZCB7CisgICAgICAgIHB1YmxpYyBUZXN0TWV0aG9kKCkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgdm9pZE1ldGhvZCgpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcGFybVRlc3QoaW50IHgsIHNob3J0IHksIFN0cmluZyBzLCBib29sZWFuIGJvb2wsIE9iamVjdCBvLAorICAgICAgICAgICAgICAgIGxvbmcgbCwgYnl0ZSBiLCBjaGFyIGMsIGRvdWJsZSBkLCBmbG9hdCBmKSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGludE1ldGhvZCgpIHsKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCB2b2lkIHByaW50VGVzdChpbnQgeCwgc2hvcnQgeSwgU3RyaW5nIHMsCisgICAgICAgICAgICAgICAgYm9vbGVhbiBib29sLCBPYmplY3QgbywgbG9uZyBsLCBieXRlIGIsIGNoYXIgYywgZG91YmxlIGQsCisgICAgICAgICAgICAgICAgZmxvYXQgZikgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGRvdWJsZSBkb3VibGVNZXRob2QoKSB7CisgICAgICAgICAgICByZXR1cm4gMS4wOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHNob3J0IHNob3J0TWV0aG9kKCkgeworICAgICAgICAgICAgcmV0dXJuIChzaG9ydCkgMTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlIGJ5dGVNZXRob2QoKSB7CisgICAgICAgICAgICByZXR1cm4gKGJ5dGUpIDE7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgZmxvYXQgZmxvYXRNZXRob2QoKSB7CisgICAgICAgICAgICByZXR1cm4gMS4wZjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBsb25nIGxvbmdNZXRob2QoKSB7CisgICAgICAgICAgICByZXR1cm4gMWw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgY2hhciBjaGFyTWV0aG9kKCkgeworICAgICAgICAgICAgcmV0dXJuICdUJzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBPYmplY3Qgb2JqZWN0TWV0aG9kKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBPYmplY3QoKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcHJzdGF0aWMoKSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3RhdGljIHZvaWQgcHVzdGF0aWMoKSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCB2b2lkIHB1c3RhdHN5bmNoKCkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN0YXRpYyBpbnQgaW52b2tlU3RhdGljVGVzdCgpIHsKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBpbnZva2VJbnN0YW5jZVRlc3QoKSB7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgaW50IHByaXZhdGVJbnZva2VUZXN0KCkgeworICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGludm9rZUV4Y2VwdGlvblRlc3QoKSB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24geworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBuYXRpdmUgdm9pZCBwdXN0YXRzeW5jaG5hdCgpOworCisgICAgfQorCisgICAgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RUZXN0TWV0aG9kIHsKKyAgICAgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcHVhYnMoKTsKKyAgICB9CisKKyAgICBjbGFzcyBTdWJJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGV4dGVuZHMgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiB7fQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiNJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENvbnN0cnVjdG9yPEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24+IGN0b3IgPSBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uLmNsYXNzCisgICAgICAgICAgICAgICAgLmdldERlY2xhcmVkQ29uc3RydWN0b3IoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiUGFyYW1ldGVybGVzcyBjb25zdHJ1Y3RvciBkb2VzIG5vdCBleGlzdC4iLCBjdG9yKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29uc3RydWN0b3IgaXMgbm90IHByb3RlY3RlZCIsIE1vZGlmaWVyLmlzUHJvdGVjdGVkKGN0b3IKKyAgICAgICAgICAgICAgICAuZ2V0TW9kaWZpZXJzKCkpKTsKKyAgICAgICAgLy9jcmVhdGUgYW4gaW5zdGFuY2Ugb2YgYSBzdWJ0eXBlIHVzaW5nIHRoaXMgY29uc3RydWN0b3IKKyAgICAgICAgU3ViSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBzdWJFeGNlcHRpb24gPSBuZXcgU3ViSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb24jSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbihqYXZhLmxhbmcuVGhyb3dhYmxlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1Rocm93YWJsZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kCisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb24oamF2YS5sYW5nLlRocm93YWJsZSkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE1ldGhvZCBtdGggPSBUZXN0TWV0aG9kLmNsYXNzLmdldERlY2xhcmVkTWV0aG9kKAorICAgICAgICAgICAgICAgICAgICAiaW52b2tlRXhjZXB0aW9uVGVzdCIsIG5ldyBDbGFzc1swXSk7CisgICAgICAgICAgICBPYmplY3RbXSBhcmdzID0geyBPYmplY3QuY2xhc3MgfTsKKyAgICAgICAgICAgIE9iamVjdCByZXQgPSBtdGguaW52b2tlKG5ldyBUZXN0TWV0aG9kKCksIG5ldyBPYmplY3RbMF0pOworICAgICAgICB9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZhaWwoIkZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uI0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb24oamF2YS5sYW5nLlRocm93YWJsZSwKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19UaHJvd2FibGVMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kCisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb24oamF2YS5sYW5nLlRocm93YWJsZSwKKyAgICAgICAgLy8gamF2YS5sYW5nLlN0cmluZykKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE1ldGhvZCBtdGggPSBUZXN0TWV0aG9kLmNsYXNzLmdldERlY2xhcmVkTWV0aG9kKAorICAgICAgICAgICAgICAgICAgICAiaW52b2tlRXhjZXB0aW9uVGVzdCIsIG5ldyBDbGFzc1swXSk7CisgICAgICAgICAgICBPYmplY3RbXSBhcmdzID0geyBPYmplY3QuY2xhc3MgfTsKKyAgICAgICAgICAgIE9iamVjdCByZXQgPSBtdGguaW52b2tlKG5ldyBUZXN0TWV0aG9kKCksIG5ldyBPYmplY3RbMF0pOworICAgICAgICB9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICA7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZhaWwoIkZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uI2dldFRhcmdldEV4Y2VwdGlvbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRUYXJnZXRFeGNlcHRpb24oKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuVGhyb3dhYmxlCisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb24uZ2V0VGFyZ2V0RXhjZXB0aW9uKCkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE1ldGhvZCBtdGggPSBUZXN0TWV0aG9kLmNsYXNzLmdldERlY2xhcmVkTWV0aG9kKAorICAgICAgICAgICAgICAgICAgICAiaW52b2tlRXhjZXB0aW9uVGVzdCIsIG5ldyBDbGFzc1swXSk7CisgICAgICAgICAgICBPYmplY3RbXSBhcmdzID0geyBPYmplY3QuY2xhc3MgfTsKKyAgICAgICAgICAgIE9iamVjdCByZXQgPSBtdGguaW52b2tlKG5ldyBUZXN0TWV0aG9kKCksIG5ldyBPYmplY3RbMF0pOworICAgICAgICB9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgdGFyZ2V0IGV4Y2VwdGlvbiIsIGUKKyAgICAgICAgICAgICAgICAgICAgLmdldFRhcmdldEV4Y2VwdGlvbigpIGluc3RhbmNlb2YgTnVsbFBvaW50ZXJFeGNlcHRpb24pOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBjb25zdHJ1Y3RvciB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBmYWlsKCJGYWlsZWQgdG8gdGhyb3cgZXhjZXB0aW9uIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiNnZXRDYXVzZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDYXVzZSgpIHsKKyAgICAgICAgLy8gamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbi5nZXRDYXVzZSgpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNZXRob2QgbXRoID0gVGVzdE1ldGhvZC5jbGFzcy5nZXREZWNsYXJlZE1ldGhvZCgKKyAgICAgICAgICAgICAgICAgICAgImludm9rZUV4Y2VwdGlvblRlc3QiLCBuZXcgQ2xhc3NbMF0pOworICAgICAgICAgICAgT2JqZWN0W10gYXJncyA9IHtPYmplY3QuY2xhc3N9OworICAgICAgICAgICAgT2JqZWN0IHJldCA9IG10aC5pbnZva2UobmV3IFRlc3RNZXRob2QoKSwgbmV3IE9iamVjdFswXSk7CisgICAgICAgIH0gY2F0Y2ggKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBjYXVzZSIsCisgICAgICAgICAgICAgICAgICAgIGUuZ2V0Q2F1c2UoKSBpbnN0YW5jZW9mIE51bGxQb2ludGVyRXhjZXB0aW9uKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiB0ZXN0IDogIgorICAgICAgICAgICAgICAgICAgICArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBmYWlsKCJGYWlsZWQgdG8gdGhyb3cgZXhjZXB0aW9uIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiNwcmludFN0YWNrVHJhY2UoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcHJpbnRTdGFja1RyYWNlKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZAorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uLnByaW50U3RhY2tUcmFjZSgpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgUHJpbnRTdHJlYW0gcHMgPSBuZXcgUHJpbnRTdHJlYW0oYmFvKTsKKyAgICAgICAgICAgIFByaW50U3RyZWFtIG9sZEVyciA9IFN5c3RlbS5lcnI7CisgICAgICAgICAgICBTeXN0ZW0uc2V0RXJyKHBzKTsKKyAgICAgICAgICAgIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gaXRlID0gbmV3IEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24obnVsbCk7CisgICAgICAgICAgICBpdGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBTeXN0ZW0uc2V0RXJyKG9sZEVycik7CisKKyAgICAgICAgICAgIFN0cmluZyBzID0gbmV3IFN0cmluZyhiYW8udG9CeXRlQXJyYXkoKSk7CisKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBTdGFjayB0cmFjZTogIiArIHMsIHMgIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAmJiBzLmxlbmd0aCgpID4gMzAwKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInByaW50U3RhY2tUcmFjZSgpIGNhdXNlZCBleGNlcHRpb24gOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiNwcmludFN0YWNrVHJhY2UoamF2YS5pby5QcmludFN0cmVhbSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3ByaW50U3RhY2tUcmFjZUxqYXZhX2lvX1ByaW50U3RyZWFtKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZAorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uLnByaW50U3RhY2tUcmFjZShqYXZhLmlvLlByaW50U3RyZWFtKQorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0ZWQgdmlhIHRlc3RfcHJpbnRTdGFja1RyYWNlKCkuIiwgdHJ1ZSk7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW8gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIFByaW50U3RyZWFtIHBzID0gbmV3IFByaW50U3RyZWFtKGJhbyk7CisgICAgICAgIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gaXRlID0gbmV3IEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgbmV3IEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24obnVsbCkpOworICAgICAgICBpdGUucHJpbnRTdGFja1RyYWNlKHBzKTsKKyAgICAgICAgU3RyaW5nIHMgPSBiYW8udG9TdHJpbmcoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgicHJpbnRTdGFja1RyYWNlIGZhaWxlZC4iICsgcy5sZW5ndGgoKSwgcyAhPSBudWxsCisgICAgICAgICAgICAgICAgJiYgcy5sZW5ndGgoKSA+IDQwMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiNwcmludFN0YWNrVHJhY2UoamF2YS5pby5QcmludFdyaXRlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3ByaW50U3RhY2tUcmFjZUxqYXZhX2lvX1ByaW50V3JpdGVyKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZAorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uLnByaW50U3RhY2tUcmFjZShqYXZhLmlvLlByaW50V3JpdGVyKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgUHJpbnRXcml0ZXIgcHc7CisgICAgICAgICAgICBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGl0ZTsKKyAgICAgICAgICAgIFN0cmluZyBzOworICAgICAgICAgICAgQ2hhckFycmF5V3JpdGVyIGNhdyA9IG5ldyBDaGFyQXJyYXlXcml0ZXIoKTsKKyAgICAgICAgICAgIHB3ID0gbmV3IFByaW50V3JpdGVyKGNhdyk7CisgICAgICAgICAgICBpdGUgPSBuZXcgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbihuZXcgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgbnVsbCkpOworICAgICAgICAgICAgaXRlLnByaW50U3RhY2tUcmFjZShwdyk7CisKKyAgICAgICAgICAgIHMgPSBjYXcudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoInByaW50U3RhY2tUcmFjZSBmYWlsZWQuIiArIHMubGVuZ3RoKCksIHMgIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAmJiBzLmxlbmd0aCgpID4gNDAwKTsKKyAgICAgICAgICAgIHB3LmNsb3NlKCk7CisKKyAgICAgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW8gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICBwdyA9IG5ldyBQcmludFdyaXRlcihiYW8pOworICAgICAgICAgICAgaXRlID0gbmV3IEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24obmV3IEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgIG51bGwpKTsKKyAgICAgICAgICAgIGl0ZS5wcmludFN0YWNrVHJhY2UocHcpOworCisgICAgICAgICAgICBwdy5mbHVzaCgpOyAvLyBUZXN0IHdpbGwgZmFpbCBpZiB0aGlzIGxpbmUgcmVtb3ZlZC4KKyAgICAgICAgICAgIHMgPSBiYW8udG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoInByaW50U3RhY2tUcmFjZSBmYWlsZWQuIiArIHMubGVuZ3RoKCksIHMgIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAmJiBzLmxlbmd0aCgpID4gNDAwKTsKKworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdXAgdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBvcGVuIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzIG1ldGhvZAorICAgICAqIGlzIGNhbGxlZCBiZWZvcmUgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvTWFsZm9ybWVkUGFyYW1ldGVyaXplZFR5cGVFeGNlcHRpb25UZXN0cy5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvcmVmbGVjdC9NYWxmb3JtZWRQYXJhbWV0ZXJpemVkVHlwZUV4Y2VwdGlvblRlc3RzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjg2NDAzZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvTWFsZm9ybWVkUGFyYW1ldGVyaXplZFR5cGVFeGNlcHRpb25UZXN0cy5qYXZhCkBAIC0wLDAgKzEsMjEgQEAKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEubGFuZy5yZWZsZWN0OworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWFsZm9ybWVkUGFyYW1ldGVyaXplZFR5cGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXI7CisKK3B1YmxpYyBjbGFzcyBNYWxmb3JtZWRQYXJhbWV0ZXJpemVkVHlwZUV4Y2VwdGlvblRlc3RzICBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5NYWxmb3JtZWRQYXJhbWV0ZXJpemVkVHlwZUV4Y2VwdGlvbiNNYWxmb3JtZWRQYXJhbWV0ZXJpemVkVHlwZUV4Y2VwdGlvbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDb25zdHJ1Y3RvcjxNYWxmb3JtZWRQYXJhbWV0ZXJpemVkVHlwZUV4Y2VwdGlvbj4gY3RvciA9IE1hbGZvcm1lZFBhcmFtZXRlcml6ZWRUeXBlRXhjZXB0aW9uLmNsYXNzCisgICAgICAgICAgICAgICAgLmdldERlY2xhcmVkQ29uc3RydWN0b3IoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiUGFyYW1ldGVybGVzcyBjb25zdHJ1Y3RvciBkb2VzIG5vdCBleGlzdC4iLCBjdG9yKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29uc3RydWN0b3IgaXMgbm90IHByb3RlY3RlZCIsIE1vZGlmaWVyLmlzUHVibGljKGN0b3IKKyAgICAgICAgICAgICAgICAuZ2V0TW9kaWZpZXJzKCkpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjdG9yLm5ld0luc3RhbmNlKCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvcmVmbGVjdC9NZXRob2RUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L01ldGhvZFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lODI4OGQ2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvcmVmbGVjdC9NZXRob2RUZXN0LmphdmEKQEAgLTAsMCArMSw4ODEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEubGFuZy5yZWZsZWN0OworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5OworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5UeXBlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGVWYXJpYWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCitwdWJsaWMgY2xhc3MgTWV0aG9kVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBzdGF0aWMgY2xhc3MgVGVzdE1ldGhvZCB7CisgICAgICAgIHB1YmxpYyBUZXN0TWV0aG9kKCkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgdm9pZE1ldGhvZCgpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcGFybVRlc3QoaW50IHgsIHNob3J0IHksIFN0cmluZyBzLCBib29sZWFuIGJvb2wsIE9iamVjdCBvLAorICAgICAgICAgICAgICAgIGxvbmcgbCwgYnl0ZSBiLCBjaGFyIGMsIGRvdWJsZSBkLCBmbG9hdCBmKSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGludE1ldGhvZCgpIHsKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCB2b2lkIHByaW50VGVzdChpbnQgeCwgc2hvcnQgeSwgU3RyaW5nIHMsCisgICAgICAgICAgICAgICAgYm9vbGVhbiBib29sLCBPYmplY3QgbywgbG9uZyBsLCBieXRlIGIsIGNoYXIgYywgZG91YmxlIGQsCisgICAgICAgICAgICAgICAgZmxvYXQgZikgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGRvdWJsZSBkb3VibGVNZXRob2QoKSB7CisgICAgICAgICAgICByZXR1cm4gMS4wOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHNob3J0IHNob3J0TWV0aG9kKCkgeworICAgICAgICAgICAgcmV0dXJuIChzaG9ydCkgMTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlIGJ5dGVNZXRob2QoKSB7CisgICAgICAgICAgICByZXR1cm4gKGJ5dGUpIDE7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgZmxvYXQgZmxvYXRNZXRob2QoKSB7CisgICAgICAgICAgICByZXR1cm4gMS4wZjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBsb25nIGxvbmdNZXRob2QoKSB7CisgICAgICAgICAgICByZXR1cm4gMWw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgY2hhciBjaGFyTWV0aG9kKCkgeworICAgICAgICAgICAgcmV0dXJuICdUJzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBPYmplY3Qgb2JqZWN0TWV0aG9kKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBPYmplY3QoKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcHJzdGF0aWMoKSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3RhdGljIHZvaWQgcHVzdGF0aWMoKSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCB2b2lkIHB1c3RhdHN5bmNoKCkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN0YXRpYyBpbnQgaW52b2tlU3RhdGljVGVzdCgpIHsKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBpbnZva2VJbnN0YW5jZVRlc3QoKSB7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgaW50IHByaXZhdGVJbnZva2VUZXN0KCkgeworICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGludm9rZUV4Y2VwdGlvblRlc3QoKSB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24geworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBuYXRpdmUgdm9pZCBwdXN0YXRzeW5jaG5hdCgpOworCisgICAgICAgIHB1YmxpYyB2b2lkIHB1YmxpY1ZvaWRWYXJhcmdzKE9iamVjdC4uLiBwYXJhbSl7fQorICAgICAgICBwdWJsaWMgdm9pZCBwdWJsaWNWb2lkQXJyYXkoT2JqZWN0W10gcGFyYW0pe30KKworICAgICAgICBwdWJsaWMgdm9pZCBhbm5vdGF0ZWRQYXJhbWV0ZXIoQFRlc3RBbm5vIEBEZXByZWNhdGVkIGludCBhLAorICAgICAgICAgICAgICAgIEBEZXByZWNhdGVkIGludCBiLCBpbnQgYykgeworICAgICAgICB9CisKKyAgICAgICAgQERlcHJlY2F0ZWQKKyAgICAgICAgQFRlc3RBbm5vCisgICAgICAgIHB1YmxpYyB2b2lkIGFubm90YXRlZE1ldGhvZCgpe30KKworICAgICAgICBwdWJsaWMgdm9pZCBoYXNoQ29kZVRlc3QoaW50IGkpe30KKyAgICAgICAgcHVibGljIHZvaWQgaGFzaENvZGVUZXN0KFN0cmluZyBzKXt9CisKKyAgICAgICAgcHVibGljIHZvaWQgaW52b2tlQ2FzdFRlc3QxKGJ5dGUgcGFyYW0pIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGludm9rZUNhc3RUZXN0MShzaG9ydCBwYXJhbSkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgaW52b2tlQ2FzdFRlc3QxKGludCBwYXJhbSkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgaW52b2tlQ2FzdFRlc3QxKGxvbmcgcGFyYW0pIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGludm9rZUNhc3RUZXN0MShmbG9hdCBwYXJhbSkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgaW52b2tlQ2FzdFRlc3QxKGRvdWJsZSBwYXJhbSkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgaW52b2tlQ2FzdFRlc3QxKGNoYXIgcGFyYW0pIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGludm9rZUNhc3RUZXN0MShib29sZWFuIHBhcmFtKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorICAgIEBUYXJnZXQoe0VsZW1lbnRUeXBlLlBBUkFNRVRFUiwgRWxlbWVudFR5cGUuTUVUSE9EfSkKKyAgICBwdWJsaWMgc3RhdGljIEBpbnRlcmZhY2UgVGVzdEFubm97CisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfVkFMVUUgPSAiREVGQVVMVF9WQUxVRSI7CisKKyAgICAgICAgU3RyaW5nIHZhbHVlKCkgZGVmYXVsdCBERUZBVUxUX1ZBTFVFOworICAgIH0KKworICAgIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0VGVzdE1ldGhvZCB7CisgICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHB1YWJzKCk7CisgICAgfQorCisgICAgY2xhc3MgVGVzdE1ldGhvZFN1YiBleHRlbmRzIFRlc3RNZXRob2QgeworICAgICAgICBwdWJsaWMgaW50IGludm9rZUluc3RhbmNlVGVzdCgpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGludGVyZmFjZSBJQnJpZ2VUZXN0PFQ+eworICAgICAgICBUIG0oKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgQnJpZ2VUZXN0IGltcGxlbWVudHMgSUJyaWdlVGVzdDxTdHJpbmc+IHsKKyAgICAgICAgcHVibGljIFN0cmluZyBtKCl7IHJldHVybiBudWxsOyB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIEV4Y2VwdGlvblRlc3Q8VCBleHRlbmRzIEV4Y2VwdGlvbj57CisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgICAgICB2b2lkIGV4Y2VwdGlvblRlc3QoKSB0aHJvd3MgVHt9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIEdlbmVyaWNSZXR1cm5UeXBlPFQ+IHsKKyAgICAgICAgVCByZXR1cm5HZW5lcmljKCl7cmV0dXJuIG51bGw7fQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBHZW5lcmljU3RyaW5nPFQ+IHsKKyAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFTkVSSUMgPQorICAgICAgIlQgdGVzdHMuYXBpLmphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZFRlc3QkR2VuZXJpY1N0cmluZy5nZW5lcmljU3RyaW5nKFQpIjsKKyAgICAgICAgVCBnZW5lcmljU3RyaW5nKFQgdCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QjZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9lcXVhbHNMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4KKyAgICAgICAgLy8gamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kLmVxdWFscyhqYXZhLmxhbmcuT2JqZWN0KQorCisgICAgICAgIE1ldGhvZCBtMSA9IG51bGwsIG0yID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG0xID0gVGVzdE1ldGhvZC5jbGFzcy5nZXRNZXRob2QoImludm9rZUluc3RhbmNlVGVzdCIsIG5ldyBDbGFzc1swXSk7CisgICAgICAgICAgICBtMiA9IFRlc3RNZXRob2RTdWIuY2xhc3MuZ2V0TWV0aG9kKCJpbnZva2VJbnN0YW5jZVRlc3QiLAorICAgICAgICAgICAgICAgICAgICBuZXcgQ2xhc3NbMF0pOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBlcXVhbHMgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiT3ZlcnJpZGVuIG1ldGhvZCByZXR1cm5lZCBlcXVhbCIsICFtMS5lcXVhbHMobTIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2FtZSBtZXRob2QgcmV0dXJuZWQgbm90LWVxdWFsIiwgbTEuZXF1YWxzKG0xKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtMSA9IFRlc3RNZXRob2QuY2xhc3MuZ2V0TWV0aG9kKCJpbnZva2VTdGF0aWNUZXN0IiwgbmV3IENsYXNzWzBdKTsKKyAgICAgICAgICAgIG0yID0gVGVzdE1ldGhvZFN1Yi5jbGFzcworICAgICAgICAgICAgICAgICAgICAuZ2V0TWV0aG9kKCJpbnZva2VTdGF0aWNUZXN0IiwgbmV3IENsYXNzWzBdKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZXF1YWxzIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkluaGVyaXRlZCBtZXRob2QgcmV0dXJuZWQgbm90LWVxdWFsIiwgbTEuZXF1YWxzKG0yKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLkNsYXNzI2dldE1ldGhvZChqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQ2xhc3NbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1ldGhvZCgpIHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24sIFNlY3VyaXR5RXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQ2hlY2sgdGhhdCBnZXRNZXRob2QgdHJlYXRzIG51bGwgcGFyYW1ldGVyVHlwZXMgdGhlIHNhbWUgYXMgYW4gZW1wdHkgYXJyYXkuCisgICAgICAgIE1ldGhvZCBtMSA9IFRlc3RNZXRob2QuY2xhc3MuZ2V0TWV0aG9kKCJpbnZva2VJbnN0YW5jZVRlc3QiLCBuZXcgQ2xhc3NbMF0pOworICAgICAgICBNZXRob2QgbTIgPSBUZXN0TWV0aG9kLmNsYXNzLmdldE1ldGhvZCgiaW52b2tlSW5zdGFuY2VUZXN0IiwgKENsYXNzW10pIG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMobTEsIG0yKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcuQ2xhc3MjZ2V0RGVjbGFyZWRNZXRob2QoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkNsYXNzW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREZWNsYXJlZE1ldGhvZCgpIHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24sIFNlY3VyaXR5RXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQ2hlY2sgdGhhdCBnZXREZWNsYXJlZE1ldGhvZCB0cmVhdHMgbnVsbCBwYXJhbWV0ZXJUeXBlcyB0aGUgc2FtZSBhcyBhbiBlbXB0eSBhcnJheS4KKyAgICAgICAgTWV0aG9kIG0xID0gVGVzdE1ldGhvZC5jbGFzcy5nZXREZWNsYXJlZE1ldGhvZCgiaW52b2tlSW5zdGFuY2VUZXN0IiwgbmV3IENsYXNzWzBdKTsKKyAgICAgICAgTWV0aG9kIG0yID0gVGVzdE1ldGhvZC5jbGFzcy5nZXREZWNsYXJlZE1ldGhvZCgiaW52b2tlSW5zdGFuY2VUZXN0IiwgKENsYXNzW10pIG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMobTEsIG0yKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QjZ2V0RGVjbGFyaW5nQ2xhc3MoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGVjbGFyaW5nQ2xhc3MoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuQ2xhc3MKKyAgICAgICAgLy8gamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kLmdldERlY2xhcmluZ0NsYXNzKCkKKworICAgICAgICBNZXRob2RbXSBtdGhzOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtdGhzID0gVGVzdE1ldGhvZC5jbGFzcy5nZXREZWNsYXJlZE1ldGhvZHMoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBkZWNsYXJpbmcgY2xhc3M6ICIKKyAgICAgICAgICAgICAgICAgICAgKyBtdGhzWzBdLmdldERlY2xhcmluZ0NsYXNzKCkudG9TdHJpbmcoKSwgbXRoc1swXQorICAgICAgICAgICAgICAgICAgICAuZ2V0RGVjbGFyaW5nQ2xhc3MoKS5lcXVhbHMoVGVzdE1ldGhvZC5jbGFzcykpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXREZWNsYXJpbmdDbGFzcyB0ZXN0OiAiCisgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCNnZXRFeGNlcHRpb25UeXBlcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRFeGNlcHRpb25UeXBlcygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5DbGFzcyBbXQorICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QuZ2V0RXhjZXB0aW9uVHlwZXMoKQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNZXRob2QgbXRoID0gVGVzdE1ldGhvZC5jbGFzcy5nZXRNZXRob2QoInZvaWRNZXRob2QiLCBuZXcgQ2xhc3NbMF0pOworICAgICAgICAgICAgQ2xhc3NbXSBleCA9IG10aC5nZXRFeGNlcHRpb25UeXBlcygpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgbnVtYmVyIG9mIGV4Y2VwdGlvbnMiLAorICAgICAgICAgICAgICAgICAgICAxLCBleC5sZW5ndGgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGV4Y2VwdGlvbiB0eXBlIiwgZXhbMF0KKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MpKTsKKyAgICAgICAgICAgIG10aCA9IFRlc3RNZXRob2QuY2xhc3MuZ2V0TWV0aG9kKCJpbnRNZXRob2QiLCBuZXcgQ2xhc3NbMF0pOworICAgICAgICAgICAgZXggPSBtdGguZ2V0RXhjZXB0aW9uVHlwZXMoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IG51bWJlciBvZiBleGNlcHRpb25zIiwKKyAgICAgICAgICAgICAgICAgICAgMCwgZXgubGVuZ3RoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0RXhjZXB0aW9uVHlwZXM6ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QjZ2V0TW9kaWZpZXJzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1vZGlmaWVycygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QuZ2V0TW9kaWZpZXJzKCkKKworICAgICAgICBDbGFzcyBjbCA9IFRlc3RNZXRob2QuY2xhc3M7CisgICAgICAgIGludCBtb2RzID0gMDsKKyAgICAgICAgTWV0aG9kIG10aCA9IG51bGw7CisgICAgICAgIGludCBtYXNrID0gMDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG10aCA9IGNsLmdldE1ldGhvZCgicHVzdGF0aWMiLCBuZXcgQ2xhc3NbMF0pOworICAgICAgICAgICAgbW9kcyA9IG10aC5nZXRNb2RpZmllcnMoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0TW9kZmllcnMgdGVzdDogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgICAgbWFzayA9IE1vZGlmaWVyLlBVQkxJQyB8IE1vZGlmaWVyLlNUQVRJQzsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG1vZGlmaWVycyByZXR1cm5lZCIsIChtb2RzIHwgbWFzaykgPT0gbWFzayk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtdGggPSBjbC5nZXREZWNsYXJlZE1ldGhvZCgicHJzdGF0aWMiLCBuZXcgQ2xhc3NbMF0pOworICAgICAgICAgICAgbW9kcyA9IG10aC5nZXRNb2RpZmllcnMoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0TW9kZmllcnMgdGVzdDogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgICAgbWFzayA9IE1vZGlmaWVyLlBSSVZBVEUgfCBNb2RpZmllci5TVEFUSUM7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBtb2RpZmllcnMgcmV0dXJuZWQiLCAobW9kcyB8IG1hc2spID09IG1hc2spOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXRoID0gY2wuZ2V0RGVjbGFyZWRNZXRob2QoInB1c3RhdHN5bmNoIiwgbmV3IENsYXNzWzBdKTsKKyAgICAgICAgICAgIG1vZHMgPSBtdGguZ2V0TW9kaWZpZXJzKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldE1vZGZpZXJzIHRlc3Q6ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIG1hc2sgPSAoTW9kaWZpZXIuUFVCTElDIHwgTW9kaWZpZXIuU1RBVElDKSB8IE1vZGlmaWVyLlNZTkNIUk9OSVpFRDsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG1vZGlmaWVycyByZXR1cm5lZCIsIChtb2RzIHwgbWFzaykgPT0gbWFzayk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtdGggPSBjbC5nZXREZWNsYXJlZE1ldGhvZCgicHVzdGF0c3luY2huYXQiLCBuZXcgQ2xhc3NbMF0pOworICAgICAgICAgICAgbW9kcyA9IG10aC5nZXRNb2RpZmllcnMoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0TW9kZmllcnMgdGVzdDogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgICAgbWFzayA9ICgoTW9kaWZpZXIuUFVCTElDIHwgTW9kaWZpZXIuU1RBVElDKSB8IE1vZGlmaWVyLlNZTkNIUk9OSVpFRCkKKyAgICAgICAgICAgICAgICB8IE1vZGlmaWVyLk5BVElWRTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG1vZGlmaWVycyByZXR1cm5lZCIsIChtb2RzIHwgbWFzaykgPT0gbWFzayk7CisgICAgICAgIGNsID0gQWJzdHJhY3RUZXN0TWV0aG9kLmNsYXNzOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXRoID0gY2wuZ2V0RGVjbGFyZWRNZXRob2QoInB1YWJzIiwgbmV3IENsYXNzWzBdKTsKKyAgICAgICAgICAgIG1vZHMgPSBtdGguZ2V0TW9kaWZpZXJzKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldE1vZGZpZXJzIHRlc3Q6ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIG1hc2sgPSBNb2RpZmllci5QVUJMSUMgfCBNb2RpZmllci5BQlNUUkFDVDsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG1vZGlmaWVycyByZXR1cm5lZCIsIChtb2RzIHwgbWFzaykgPT0gbWFzayk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kI2dldE5hbWUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TmFtZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kLmdldE5hbWUoKQorICAgICAgICBNZXRob2QgbXRoID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG10aCA9IFRlc3RNZXRob2QuY2xhc3MuZ2V0TWV0aG9kKCJ2b2lkTWV0aG9kIiwgbmV3IENsYXNzWzBdKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0TWV0aG9kTmFtZSgpOiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBtZXRob2QgbmFtZSIsCisgICAgICAgICAgICAgICAgInZvaWRNZXRob2QiLCBtdGguZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QjaXNWYXJBcmdzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzVmFyQXJncygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNZXRob2QgbXRoID0gVGVzdE1ldGhvZC5jbGFzcy5nZXRNZXRob2QoInB1YmxpY1ZvaWRWYXJhcmdzIiwKKyAgICAgICAgICAgICAgICBPYmplY3RbXS5jbGFzcyk7CisgICAgICAgIGFzc2VydFRydWUoIlZhcmFyZ3MgbWV0aG9kIHN0YXRlZCBhcyBub24gdmFyYXJnLiIsIG10aC5pc1ZhckFyZ3MoKSk7CisKKyAgICAgICAgbXRoID0gVGVzdE1ldGhvZC5jbGFzcy5nZXREZWNsYXJlZE1ldGhvZCgicHVibGljVm9pZEFycmF5IiwKKyAgICAgICAgICAgICAgICBPYmplY3RbXS5jbGFzcyk7CisgICAgICAgIGFzc2VydEZhbHNlKCJOb24gdmFyYXJncyBtZXRob2Qgc3RhdGVkIGFzIHZhcmFyZy4iLCBtdGguaXNWYXJBcmdzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCNpc0JyaWRnZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0JyaWRnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNZXRob2RbXSBkZWNsYXJlZE1ldGhvZHMgPSBCcmlnZVRlc3QuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2RzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQnJpZGdlIG1ldGhvZCBub3QgZ2VuZXJhdGVkLiIsIDIsIGRlY2xhcmVkTWV0aG9kcy5sZW5ndGgpOworICAgICAgICBib29sZWFuIGZvdW5kQnJpZGdlTWV0aG9kID0gZmFsc2U7CisgICAgICAgIGZvciAoTWV0aG9kIG1ldGhvZCA6IGRlY2xhcmVkTWV0aG9kcykgeworICAgICAgICAgICAgaWYgKG1ldGhvZC5nZXRSZXR1cm5UeXBlKCkuZXF1YWxzKE9iamVjdC5jbGFzcykpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJCcmlkZ2UgbWV0aG9kIG5vdCBzdGF0ZWQgYXMgYnJpZGdlLiIsIG1ldGhvZAorICAgICAgICAgICAgICAgICAgICAgICAgLmlzQnJpZGdlKCkpOworICAgICAgICAgICAgICAgIGZvdW5kQnJpZGdlTWV0aG9kID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJCcmlkZ2UgbWV0aG9kIG5vdCBmb3VuZC4iLCBmb3VuZEJyaWRnZU1ldGhvZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kI2lzU3ludGhldGljKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzU3ludGhldGljKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZFtdIGRlY2xhcmVkTWV0aG9kcyA9IEJyaWdlVGVzdC5jbGFzcy5nZXREZWNsYXJlZE1ldGhvZHMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTeW50aGV0aWMgbWV0aG9kIG5vdCBnZW5lcmF0ZWQuIiwgMiwKKyAgICAgICAgICAgICAgICBkZWNsYXJlZE1ldGhvZHMubGVuZ3RoKTsKKyAgICAgICAgYm9vbGVhbiBmb3VuZFN5bnRoZXRpY01ldGhvZCA9IGZhbHNlOworICAgICAgICBmb3IgKE1ldGhvZCBtZXRob2QgOiBkZWNsYXJlZE1ldGhvZHMpIHsKKyAgICAgICAgICAgIGlmIChtZXRob2QuZ2V0UmV0dXJuVHlwZSgpLmVxdWFscyhPYmplY3QuY2xhc3MpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU3ludGhldGljIG1ldGhvZCBub3Qgc3RhdGVkIGFzIHN5bnRoZXRpYy4iLCBtZXRob2QKKyAgICAgICAgICAgICAgICAgICAgICAgIC5pc1N5bnRoZXRpYygpKTsKKyAgICAgICAgICAgICAgICBmb3VuZFN5bnRoZXRpY01ldGhvZCA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU3ludGhldGljIG1ldGhvZCBub3QgZm91bmQuIiwgZm91bmRTeW50aGV0aWNNZXRob2QpOworICAgIH0KKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QjZ2V0UGFyYW1ldGVyQW5ub3RhdGlvbnMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UGFyYW1ldGVyQW5ub3RhdGlvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IFRlc3RNZXRob2QuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoCisgICAgICAgICAgICAgICAgImFubm90YXRlZFBhcmFtZXRlciIsIG5ldyBDbGFzc1tdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGludC5jbGFzcywgaW50LmNsYXNzLCBpbnQuY2xhc3N9KTsKKyAgICAgICAgQW5ub3RhdGlvbltdW10gYW5ub3RhdGlvbnMgPSBtZXRob2QuZ2V0UGFyYW1ldGVyQW5ub3RhdGlvbnMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGFubm90YXRpb25zLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAiV3JvbmcgbnVtYmVyIG9mIGFubm90YXRpb25zIHJldHVybmVkIGZvciBmaXJzdCBwYXJhbWV0ZXIiLCAyLAorICAgICAgICAgICAgICAgIGFubm90YXRpb25zWzBdLmxlbmd0aCk7CisgICAgICAgIFNldDxDbGFzczw/Pj4gYW5ub3RhdGlvblNldCA9IG5ldyBIYXNoU2V0PENsYXNzPD8+PigpOworICAgICAgICBhbm5vdGF0aW9uU2V0LmFkZChhbm5vdGF0aW9uc1swXVswXS5hbm5vdGF0aW9uVHlwZSgpKTsKKyAgICAgICAgYW5ub3RhdGlvblNldC5hZGQoYW5ub3RhdGlvbnNbMF1bMV0uYW5ub3RhdGlvblR5cGUoKSk7CisgICAgICAgIGFzc2VydFRydWUoIk1pc3NpbmcgVGVzdEFubm8gYW5ub3RhdGlvbiIsIGFubm90YXRpb25TZXQKKyAgICAgICAgICAgICAgICAuY29udGFpbnMoVGVzdEFubm8uY2xhc3MpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTWlzc2luZyBEZXByZWNhdGVkIGFubm90YXRpb24iLCBhbm5vdGF0aW9uU2V0CisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKERlcHJlY2F0ZWQuY2xhc3MpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgIldyb25nIG51bWJlciBvZiBhbm5vdGF0aW9ucyByZXR1cm5lZCBmb3Igc2Vjb25kIHBhcmFtZXRlciIsCisgICAgICAgICAgICAgICAgMSwgYW5ub3RhdGlvbnNbMV0ubGVuZ3RoKTsKKyAgICAgICAgYW5ub3RhdGlvblNldCA9IG5ldyBIYXNoU2V0PENsYXNzPD8+PigpOworICAgICAgICBhbm5vdGF0aW9uU2V0LmFkZChhbm5vdGF0aW9uc1sxXVswXS5hbm5vdGF0aW9uVHlwZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTWlzc2luZyBEZXByZWNhdGVkIGFubm90YXRpb24iLCBhbm5vdGF0aW9uU2V0CisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKERlcHJlY2F0ZWQuY2xhc3MpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICJXcm9uZyBudW1iZXIgb2YgYW5ub3RhdGlvbnMgcmV0dXJuZWQgZm9yIHRoaXJkIHBhcmFtZXRlciIsIDAsCisgICAgICAgICAgICAgICAgYW5ub3RhdGlvbnNbMl0ubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QjZ2V0RGVjbGFyZWRBbm5vdGF0aW9ucygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREZWNsYXJlZEFubm90YXRpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBUZXN0TWV0aG9kLmNsYXNzLmdldERlY2xhcmVkTWV0aG9kKCJhbm5vdGF0ZWRNZXRob2QiKTsKKyAgICAgICAgQW5ub3RhdGlvbltdIGRlY2xhcmVkQW5ub3RhdGlvbnMgPSBtZXRob2QuZ2V0RGVjbGFyZWRBbm5vdGF0aW9ucygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgZGVjbGFyZWRBbm5vdGF0aW9ucy5sZW5ndGgpOworCisgICAgICAgIFNldDxDbGFzczw/Pj4gYW5ub3RhdGlvblNldCA9IG5ldyBIYXNoU2V0PENsYXNzPD8+PigpOworICAgICAgICBhbm5vdGF0aW9uU2V0LmFkZChkZWNsYXJlZEFubm90YXRpb25zWzBdLmFubm90YXRpb25UeXBlKCkpOworICAgICAgICBhbm5vdGF0aW9uU2V0LmFkZChkZWNsYXJlZEFubm90YXRpb25zWzFdLmFubm90YXRpb25UeXBlKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJNaXNzaW5nIFRlc3RBbm5vIGFubm90YXRpb24iLCBhbm5vdGF0aW9uU2V0CisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKFRlc3RBbm5vLmNsYXNzKSk7CisgICAgICAgIGFzc2VydFRydWUoIk1pc3NpbmcgRGVwcmVjYXRlZCBhbm5vdGF0aW9uIiwgYW5ub3RhdGlvblNldAorICAgICAgICAgICAgICAgIC5jb250YWlucyhEZXByZWNhdGVkLmNsYXNzKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kI2dldERlZmF1bHRWYWx1ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREZWZhdWx0VmFsdWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IFRlc3RBbm5vLmNsYXNzLmdldERlY2xhcmVkTWV0aG9kKCJ2YWx1ZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGRlZmF1bHQgdmFsdWUgcmV0dXJuZWQiLCBUZXN0QW5uby5ERUZBVUxUX1ZBTFVFLAorICAgICAgICAgICAgICAgIG1ldGhvZC5nZXREZWZhdWx0VmFsdWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kI2dldERlZmF1bHRWYWx1ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRHZW5lcmljRXhjZXB0aW9uVHlwZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IEV4Y2VwdGlvblRlc3QuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoImV4Y2VwdGlvblRlc3QiKTsKKyAgICAgICAgVHlwZVtdIGdlbmVyaWNFeGNlcHRpb25UeXBlcyA9IG1ldGhvZC5nZXRHZW5lcmljRXhjZXB0aW9uVHlwZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGdlbmVyaWNFeGNlcHRpb25UeXBlcy5sZW5ndGgpOworICAgICAgICBhc3NlcnRUcnVlKGdlbmVyaWNFeGNlcHRpb25UeXBlc1swXSBpbnN0YW5jZW9mIFR5cGVWYXJpYWJsZTw/Pik7CisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICBUeXBlVmFyaWFibGU8Q2xhc3M8RXhjZXB0aW9uVGVzdDw/Pj4+IHR2ID0KKyAgICAgICAgICAgIChUeXBlVmFyaWFibGU8Q2xhc3M8RXhjZXB0aW9uVGVzdDw/Pj4+KSBnZW5lcmljRXhjZXB0aW9uVHlwZXNbMF07CisgICAgICAgIGFzc2VydEVxdWFscygiVCIsIHR2LmdldE5hbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kI2dldEdlbmVyaWNSZXR1cm5UeXBlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEdlbmVyaWNSZXR1cm5UeXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBHZW5lcmljUmV0dXJuVHlwZS5jbGFzcworICAgICAgICAgICAgICAgIC5nZXREZWNsYXJlZE1ldGhvZCgicmV0dXJuR2VuZXJpYyIpOworICAgICAgICBUeXBlIHJldHVyblR5cGUgPSBtZXRob2QuZ2V0R2VuZXJpY1JldHVyblR5cGUoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0R2VuZXJpY1JldHVyblR5cGUgcmV0dXJuZWQgbnVsbCIsIHJldHVyblR5cGUpOworICAgICAgICBhc3NlcnRUcnVlKHJldHVyblR5cGUgaW5zdGFuY2VvZiBUeXBlVmFyaWFibGU8Pz4pOworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgVHlwZVZhcmlhYmxlPENsYXNzPEV4Y2VwdGlvblRlc3Q8Pz4+PiB0diA9CisgICAgICAgICAgICAoVHlwZVZhcmlhYmxlPENsYXNzPEV4Y2VwdGlvblRlc3Q8Pz4+PikgcmV0dXJuVHlwZTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUIiwgdHYuZ2V0TmFtZSgpKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCN0b0dlbmVyaWNTdHJpbmcoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9HZW5lcmljU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBHZW5lcmljU3RyaW5nLmNsYXNzLmdldERlY2xhcmVkTWV0aG9kKCJnZW5lcmljU3RyaW5nIiwKKyAgICAgICAgICAgICAgICBPYmplY3QuY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGdlbmVyaWMgU3RyaW5nIHJldHVybmVkIiwgR2VuZXJpY1N0cmluZy5HRU5FUklDLAorICAgICAgICAgICAgICAgIG1ldGhvZC50b0dlbmVyaWNTdHJpbmcoKSk7CisgICAgfQorCisKKworCisKKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCNoYXNoQ29kZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNZXRob2QgbXRoMCA9IFRlc3RNZXRob2QuY2xhc3MuZ2V0TWV0aG9kKCJoYXNoQ29kZVRlc3QiLCBTdHJpbmcuY2xhc3MpOworICAgICAgICBNZXRob2QgbXRoMSA9IFRlc3RNZXRob2QuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoImhhc2hDb2RlVGVzdCIsCisgICAgICAgICAgICAgICAgaW50LmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJNZXRob2RzIHdpdGggc2FtZSBuYW1lIGRpZCBub3QgcmV0dXJuIHNhbWUgaGFzaENvZGUuIiwKKyAgICAgICAgICAgICAgICBtdGgwLmhhc2hDb2RlKCksIG10aDEuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kI2dldFBhcmFtZXRlclR5cGVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFBhcmFtZXRlclR5cGVzKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLkNsYXNzIFtdCisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZC5nZXRQYXJhbWV0ZXJUeXBlcygpCisgICAgICAgIENsYXNzIGNsID0gVGVzdE1ldGhvZC5jbGFzczsKKyAgICAgICAgTWV0aG9kIG10aCA9IG51bGw7CisgICAgICAgIENsYXNzW10gcGFybXMgPSBudWxsOworICAgICAgICBNZXRob2RbXSBtZXRob2RzID0gbnVsbDsKKyAgICAgICAgQ2xhc3NbXSBwbGlzdCA9IHsgaW50LmNsYXNzLCBzaG9ydC5jbGFzcywgU3RyaW5nLmNsYXNzLCBib29sZWFuLmNsYXNzLAorICAgICAgICAgICAgICAgIE9iamVjdC5jbGFzcywgbG9uZy5jbGFzcywgYnl0ZS5jbGFzcywgY2hhci5jbGFzcywgZG91YmxlLmNsYXNzLAorICAgICAgICAgICAgICAgIGZsb2F0LmNsYXNzIH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtdGggPSBjbC5nZXRNZXRob2QoInZvaWRNZXRob2QiLCBuZXcgQ2xhc3NbMF0pOworICAgICAgICAgICAgcGFybXMgPSBtdGguZ2V0UGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0UGFyYW1ldGVyVHlwZXMgdGVzdDogIgorICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgcGFyYW1ldGVyVHlwZXMiLCAwLCBwYXJtcy5sZW5ndGgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXRoID0gY2wuZ2V0TWV0aG9kKCJwYXJtVGVzdCIsIHBsaXN0KTsKKyAgICAgICAgICAgIHBhcm1zID0gbXRoLmdldFBhcmFtZXRlclR5cGVzKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldFBhcmFtZXRlclR5cGVzIHRlc3Q6ICIKKyAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkludmFsaWQgbnVtYmVyIG9mIHBhcmFtZXRlcnMgcmV0dXJuZWQiLAorICAgICAgICAgICAgICAgIHBsaXN0Lmxlbmd0aCA9PSBwYXJtcy5sZW5ndGgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBsaXN0Lmxlbmd0aDsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHBhcmFtZXRlciByZXR1cm5lZCIsIHBsaXN0W2ldCisgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMocGFybXNbaV0pKTsKKworICAgICAgICAvLyBUZXN0IHNhbWUgbWV0aG9kLiBidXQgdGhpcyB0aW1lIHB1bGwgaXQgZnJvbSB0aGUgbGlzdCBvZiBtZXRob2RzCisgICAgICAgIC8vIHJhdGhlciB0aGFuIGFza2luZyBmb3IgaXQgZXhwbGljaXRseQorICAgICAgICBtZXRob2RzID0gY2wuZ2V0RGVjbGFyZWRNZXRob2RzKCk7CisKKyAgICAgICAgaW50IGk7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBtZXRob2RzLmxlbmd0aDsgaSsrKQorICAgICAgICAgICAgaWYgKG1ldGhvZHNbaV0uZ2V0TmFtZSgpLmVxdWFscygicGFybVRlc3QiKSkgeworICAgICAgICAgICAgICAgIG10aCA9IG1ldGhvZHNbaV07CisgICAgICAgICAgICAgICAgaSA9IG1ldGhvZHMubGVuZ3RoICsgMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgaWYgKGkgPCBtZXRob2RzLmxlbmd0aCkgeworICAgICAgICAgICAgcGFybXMgPSBtdGguZ2V0UGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBudW1iZXIgb2YgcGFyYW1ldGVycyByZXR1cm5lZCIsCisgICAgICAgICAgICAgICAgICAgIHBhcm1zLmxlbmd0aCA9PSBwbGlzdC5sZW5ndGgpOworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHBsaXN0Lmxlbmd0aDsgaSsrKQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBwYXJhbWV0ZXIgcmV0dXJuZWQiLCBwbGlzdFtpXQorICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhwYXJtc1tpXSkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kI2dldFJldHVyblR5cGUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UmV0dXJuVHlwZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5DbGFzcworICAgICAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QuZ2V0UmV0dXJuVHlwZSgpCisgICAgICAgIENsYXNzIGNsID0gVGVzdE1ldGhvZC5jbGFzczsKKyAgICAgICAgTWV0aG9kIG10aCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtdGggPSBjbC5nZXRNZXRob2QoImNoYXJNZXRob2QiLCBuZXcgQ2xhc3NbMF0pOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXRSZXR1cm5UeXBlIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkdhdmUgaW5jb3JyZWN0IHJldHVybmUgdHlwZSwgd2FudGVkIGNoYXIiLCBtdGgKKyAgICAgICAgICAgICAgICAuZ2V0UmV0dXJuVHlwZSgpLmVxdWFscyhjaGFyLmNsYXNzKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtdGggPSBjbC5nZXRNZXRob2QoImxvbmdNZXRob2QiLCBuZXcgQ2xhc3NbMF0pOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXRSZXR1cm5UeXBlIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkdhdmUgaW5jb3JyZWN0IHJldHVybmUgdHlwZSwgd2FudGVkIGxvbmciLCBtdGgKKyAgICAgICAgICAgICAgICAuZ2V0UmV0dXJuVHlwZSgpLmVxdWFscyhsb25nLmNsYXNzKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtdGggPSBjbC5nZXRNZXRob2QoInNob3J0TWV0aG9kIiwgbmV3IENsYXNzWzBdKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0UmV0dXJuVHlwZSB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJHYXZlIGluY29ycmVjdCByZXR1cm5lIHR5cGUsIHdhbnRlZCBzaG9ydCIsIG10aAorICAgICAgICAgICAgICAgIC5nZXRSZXR1cm5UeXBlKCkuZXF1YWxzKHNob3J0LmNsYXNzKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtdGggPSBjbC5nZXRNZXRob2QoImludE1ldGhvZCIsIG5ldyBDbGFzc1swXSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldFJldHVyblR5cGUgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiR2F2ZSBpbmNvcnJlY3QgcmV0dXJuZSB0eXBlLCB3YW50ZWQgaW50OiAiCisgICAgICAgICAgICAgICAgKyBtdGguZ2V0UmV0dXJuVHlwZSgpLCBtdGguZ2V0UmV0dXJuVHlwZSgpLmVxdWFscyhpbnQuY2xhc3MpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG10aCA9IGNsLmdldE1ldGhvZCgiZG91YmxlTWV0aG9kIiwgbmV3IENsYXNzWzBdKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgZ2V0UmV0dXJuVHlwZSB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJHYXZlIGluY29ycmVjdCByZXR1cm5lIHR5cGUsIHdhbnRlZCBkb3VibGUiLCBtdGgKKyAgICAgICAgICAgICAgICAuZ2V0UmV0dXJuVHlwZSgpLmVxdWFscyhkb3VibGUuY2xhc3MpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG10aCA9IGNsLmdldE1ldGhvZCgiYnl0ZU1ldGhvZCIsIG5ldyBDbGFzc1swXSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldFJldHVyblR5cGUgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiR2F2ZSBpbmNvcnJlY3QgcmV0dXJuZSB0eXBlLCB3YW50ZWQgYnl0ZSIsIG10aAorICAgICAgICAgICAgICAgIC5nZXRSZXR1cm5UeXBlKCkuZXF1YWxzKGJ5dGUuY2xhc3MpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG10aCA9IGNsLmdldE1ldGhvZCgiYnl0ZU1ldGhvZCIsIG5ldyBDbGFzc1swXSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGdldFJldHVyblR5cGUgdGVzdDoiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJHYXZlIGluY29ycmVjdCByZXR1cm5lIHR5cGUsIHdhbnRlZCBieXRlIiwgbXRoCisgICAgICAgICAgICAgICAgLmdldFJldHVyblR5cGUoKS5lcXVhbHMoYnl0ZS5jbGFzcykpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXRoID0gY2wuZ2V0TWV0aG9kKCJvYmplY3RNZXRob2QiLCBuZXcgQ2xhc3NbMF0pOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXRSZXR1cm5UeXBlIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkdhdmUgaW5jb3JyZWN0IHJldHVybmUgdHlwZSwgd2FudGVkIE9iamVjdCIsIG10aAorICAgICAgICAgICAgICAgIC5nZXRSZXR1cm5UeXBlKCkuZXF1YWxzKE9iamVjdC5jbGFzcykpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtdGggPSBjbC5nZXRNZXRob2QoInZvaWRNZXRob2QiLCBuZXcgQ2xhc3NbMF0pOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyBnZXRSZXR1cm5UeXBlIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkdhdmUgaW5jb3JyZWN0IHJldHVybmUgdHlwZSwgd2FudGVkIHZvaWQiLCBtdGgKKyAgICAgICAgICAgICAgICAuZ2V0UmV0dXJuVHlwZSgpLmVxdWFscyh2b2lkLmNsYXNzKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kI2ludm9rZShqYXZhLmxhbmcuT2JqZWN0LAorICAgICAqICAgICAgICBqYXZhLmxhbmcuT2JqZWN0W10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pbnZva2VMamF2YV9sYW5nX09iamVjdCRMamF2YV9sYW5nX09iamVjdCgpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0CisgICAgICAgIC8vIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZC5pbnZva2UoamF2YS5sYW5nLk9iamVjdCwgamF2YS5sYW5nLk9iamVjdAorICAgICAgICAvLyBbXSkKKyAgICAgICAgQ2xhc3MgY2wgPSBUZXN0TWV0aG9kLmNsYXNzOworICAgICAgICBDbGFzc1tdIGRjbCA9IG5ldyBDbGFzc1swXTsKKworICAgICAgICAvLyBHZXQgYW5kIGludm9rZSBhIHN0YXRpYyBtZXRob2QKKyAgICAgICAgTWV0aG9kIG10aCA9IGNsLmdldERlY2xhcmVkTWV0aG9kKCJpbnZva2VTdGF0aWNUZXN0IiwgZGNsKTsKKyAgICAgICAgT2JqZWN0IHJldCA9IG10aC5pbnZva2UobnVsbCwgbmV3IE9iamVjdFswXSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW52b2tlIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIDEsICgoSW50ZWdlcikgcmV0KQorICAgICAgICAgICAgICAgIC5pbnRWYWx1ZSgpKTsKKworICAgICAgICAvLyBHZXQgYW5kIGludm9rZSBhbiBpbnN0YW5jZSBtZXRob2QKKyAgICAgICAgbXRoID0gY2wuZ2V0RGVjbGFyZWRNZXRob2QoImludm9rZUluc3RhbmNlVGVzdCIsIGRjbCk7CisgICAgICAgIHJldCA9IG10aC5pbnZva2UobmV3IFRlc3RNZXRob2QoKSwgbmV3IE9iamVjdFswXSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW52b2tlIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIDEsICgoSW50ZWdlcikgcmV0KQorICAgICAgICAgICAgICAgIC5pbnRWYWx1ZSgpKTsKKworICAgICAgICAvLyBHZXQgYW5kIGF0dGVtcHQgdG8gaW52b2tlIGEgcHJpdmF0ZSBtZXRob2QKKyAgICAgICAgbXRoID0gY2wuZ2V0RGVjbGFyZWRNZXRob2QoInByaXZhdGVJbnZva2VUZXN0IiwgZGNsKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldCA9IG10aC5pbnZva2UobmV3IFRlc3RNZXRob2QoKSwgbmV3IE9iamVjdFswXSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgaW52b2tlIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIC8vIEdlbmVyYXRlIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgICAgICBtdGggPSBjbC5nZXREZWNsYXJlZE1ldGhvZCgiaW52b2tlSW5zdGFuY2VUZXN0IiwgZGNsKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgT2JqZWN0W10gYXJncyA9IHsgT2JqZWN0LmNsYXNzIH07CisgICAgICAgICAgICByZXQgPSBtdGguaW52b2tlKG5ldyBUZXN0TWV0aG9kKCksIGFyZ3MpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgaW52b2tlIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gR2VuZXJhdGUgYSBOdWxsUG9pbnRlckV4Y2VwdGlvbgorICAgICAgICBtdGggPSBjbC5nZXREZWNsYXJlZE1ldGhvZCgiaW52b2tlSW5zdGFuY2VUZXN0IiwgZGNsKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0ID0gbXRoLmludm9rZShudWxsLCBuZXcgT2JqZWN0WzBdKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdCBiZWhhdmlvdXIKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgaW52b2tlIHRlc3QgOiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gR2VuZXJhdGUgYW4gSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgorICAgICAgICBtdGggPSBjbC5nZXREZWNsYXJlZE1ldGhvZCgiaW52b2tlRXhjZXB0aW9uVGVzdCIsIGRjbCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXQgPSBtdGguaW52b2tlKG5ldyBUZXN0TWV0aG9kKCksIG5ldyBPYmplY3RbMF0pOworICAgICAgICB9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QgYmVoYXZpb3VyCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gZHVyaW5nIGludm9rZSB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIFRlc3RNZXRob2QgdGVzdE1ldGhvZCA9IG5ldyBUZXN0TWV0aG9kKCk7CisgICAgICAgIE1ldGhvZCBtZXRob2RzW10gPSBjbC5nZXRNZXRob2RzKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKG1ldGhvZHNbaV0uZ2V0TmFtZSgpLnN0YXJ0c1dpdGgoImludm9rZUNhc3RUZXN0MSIpKSB7CisgICAgICAgICAgICAgICAgQ2xhc3MgcGFyYW0gPSBtZXRob2RzW2ldLmdldFBhcmFtZXRlclR5cGVzKClbMF07CisKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBtZXRob2RzW2ldLmludm9rZSh0ZXN0TWV0aG9kLCBuZXcgT2JqZWN0W10geyBuZXcgQnl0ZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkgMSkgfSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImludmFsaWQgaW52b2tlIHdpdGggQnl0ZTogIiArIG1ldGhvZHNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW0gPT0gQnl0ZS5UWVBFIHx8IHBhcmFtID09IFNob3J0LlRZUEUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHBhcmFtID09IEludGVnZXIuVFlQRQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgcGFyYW0gPT0gTG9uZy5UWVBFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBwYXJhbSA9PSBGbG9hdC5UWVBFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBwYXJhbSA9PSBEb3VibGUuVFlQRSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQnl0ZSBpbnZhbGlkIGV4Y2VwdGlvbjogIiArIGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZSBpbnN0YW5jZW9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbik7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIkJ5dGUgaW52YWxpZCBmYWlsdXJlOiAiICsgbWV0aG9kc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbSA9PSBCb29sZWFuLlRZUEUgfHwgcGFyYW0gPT0gQ2hhcmFjdGVyLlRZUEUpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIG1ldGhvZHNbaV0uaW52b2tlKHRlc3RNZXRob2QsIG5ldyBPYmplY3RbXSB7IG5ldyBTaG9ydCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc2hvcnQpIDEpIH0pOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJpbnZhbGlkIGludm9rZSB3aXRoIFNob3J0OiAiICsgbWV0aG9kc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbSA9PSBTaG9ydC5UWVBFIHx8IHBhcmFtID09IEludGVnZXIuVFlQRQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgcGFyYW0gPT0gTG9uZy5UWVBFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBwYXJhbSA9PSBGbG9hdC5UWVBFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBwYXJhbSA9PSBEb3VibGUuVFlQRSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvcnQgaW52YWxpZCBleGNlcHRpb246ICIgKyBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUgaW5zdGFuY2VvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24pOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJTaG9ydCBpbnZhbGlkIGZhaWx1cmU6ICIgKyBtZXRob2RzW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtID09IEJ5dGUuVFlQRSB8fCBwYXJhbSA9PSBCb29sZWFuLlRZUEUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHBhcmFtID09IENoYXJhY3Rlci5UWVBFKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBtZXRob2RzW2ldLmludm9rZSh0ZXN0TWV0aG9kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5ldyBJbnRlZ2VyKDEpIH0pOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJpbnZhbGlkIGludm9rZSB3aXRoIEludGVnZXI6ICIgKyBtZXRob2RzW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtID09IEludGVnZXIuVFlQRSB8fCBwYXJhbSA9PSBMb25nLlRZUEUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHBhcmFtID09IEZsb2F0LlRZUEUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHBhcmFtID09IERvdWJsZS5UWVBFKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbnRlZ2VyIGludmFsaWQgZXhjZXB0aW9uOiAiICsgZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBlIGluc3RhbmNlb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW50ZWdlciBpbnZhbGlkIGZhaWx1cmU6ICIgKyBtZXRob2RzW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtID09IEJ5dGUuVFlQRSB8fCBwYXJhbSA9PSBTaG9ydC5UWVBFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBwYXJhbSA9PSBCb29sZWFuLlRZUEUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHBhcmFtID09IENoYXJhY3Rlci5UWVBFKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBtZXRob2RzW2ldLmludm9rZSh0ZXN0TWV0aG9kLCBuZXcgT2JqZWN0W10geyBuZXcgTG9uZygxKSB9KTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiaW52YWxpZCBpbnZva2Ugd2l0aCBMb25nOiAiICsgbWV0aG9kc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbSA9PSBMb25nLlRZUEUgfHwgcGFyYW0gPT0gRmxvYXQuVFlQRQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgcGFyYW0gPT0gRG91YmxlLlRZUEUpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIkxvbmcgaW52YWxpZCBleGNlcHRpb246ICIgKyBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUgaW5zdGFuY2VvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24pOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJMb25nIGludmFsaWQgZmFpbHVyZTogIiArIG1ldGhvZHNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW0gPT0gQnl0ZS5UWVBFIHx8IHBhcmFtID09IFNob3J0LlRZUEUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHBhcmFtID09IEludGVnZXIuVFlQRQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgcGFyYW0gPT0gQm9vbGVhbi5UWVBFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBwYXJhbSA9PSBDaGFyYWN0ZXIuVFlQRSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgbWV0aG9kc1tpXS5pbnZva2UodGVzdE1ldGhvZCwgbmV3IE9iamVjdFtdIHsgbmV3IENoYXJhY3RlcigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYScpIH0pOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJpbnZhbGlkIGludm9rZSB3aXRoIENoYXJhY3RlcjogIiArIG1ldGhvZHNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW0gPT0gQ2hhcmFjdGVyLlRZUEUgfHwgcGFyYW0gPT0gSW50ZWdlci5UWVBFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBwYXJhbSA9PSBMb25nLlRZUEUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHBhcmFtID09IEZsb2F0LlRZUEUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHBhcmFtID09IERvdWJsZS5UWVBFKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJDaGFyYWN0ZXIgaW52YWxpZCBleGNlcHRpb246ICIgKyBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUgaW5zdGFuY2VvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24pOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJDaGFyYWN0ZXIgaW52YWxpZCBmYWlsdXJlOiAiICsgbWV0aG9kc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbSA9PSBCeXRlLlRZUEUgfHwgcGFyYW0gPT0gU2hvcnQuVFlQRQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgcGFyYW0gPT0gQm9vbGVhbi5UWVBFKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBtZXRob2RzW2ldCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmludm9rZSh0ZXN0TWV0aG9kLCBuZXcgT2JqZWN0W10geyBuZXcgRmxvYXQoMSkgfSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImludmFsaWQgaW52b2tlIHdpdGggRmxvYXQ6ICIgKyBtZXRob2RzW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtID09IEZsb2F0LlRZUEUgfHwgcGFyYW0gPT0gRG91YmxlLlRZUEUpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIkZsb2F0IGludmFsaWQgZXhjZXB0aW9uOiAiICsgZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBlIGluc3RhbmNlb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmxvYXQgaW52YWxpZCBmYWlsdXJlOiAiICsgbWV0aG9kc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbSA9PSBCeXRlLlRZUEUgfHwgcGFyYW0gPT0gU2hvcnQuVFlQRQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgcGFyYW0gPT0gSW50ZWdlci5UWVBFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBwYXJhbSA9PSBMb25nLlRZUEUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHBhcmFtID09IEJvb2xlYW4uVFlQRQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgcGFyYW0gPT0gQ2hhcmFjdGVyLlRZUEUpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIG1ldGhvZHNbaV0uaW52b2tlKHRlc3RNZXRob2QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmV3IERvdWJsZSgxKSB9KTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiaW52YWxpZCBpbnZva2Ugd2l0aCBEb3VibGU6ICIgKyBtZXRob2RzW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtID09IERvdWJsZS5UWVBFKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJEb3VibGUgaW52YWxpZCBleGNlcHRpb246ICIgKyBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUgaW5zdGFuY2VvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24pOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJEb3VibGUgaW52YWxpZCBmYWlsdXJlOiAiICsgbWV0aG9kc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbSA9PSBCeXRlLlRZUEUgfHwgcGFyYW0gPT0gU2hvcnQuVFlQRQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgcGFyYW0gPT0gSW50ZWdlci5UWVBFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBwYXJhbSA9PSBMb25nLlRZUEUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHBhcmFtID09IEJvb2xlYW4uVFlQRQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgcGFyYW0gPT0gQ2hhcmFjdGVyLlRZUEUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHBhcmFtID09IEZsb2F0LlRZUEUpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIG1ldGhvZHNbaV0uaW52b2tlKHRlc3RNZXRob2QsIG5ldyBPYmplY3RbXSB7IG5ldyBCb29sZWFuKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpIH0pOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJpbnZhbGlkIGludm9rZSB3aXRoIEJvb2xlYW46ICIgKyBtZXRob2RzW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtID09IEJvb2xlYW4uVFlQRSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQm9vbGVhbiBpbnZhbGlkIGV4Y2VwdGlvbjogIiArIGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZSBpbnN0YW5jZW9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbik7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIkJvb2xlYW4gaW52YWxpZCBmYWlsdXJlOiAiICsgbWV0aG9kc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbSA9PSBCeXRlLlRZUEUgfHwgcGFyYW0gPT0gU2hvcnQuVFlQRQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgcGFyYW0gPT0gSW50ZWdlci5UWVBFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBwYXJhbSA9PSBMb25nLlRZUEUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHBhcmFtID09IENoYXJhY3Rlci5UWVBFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBwYXJhbSA9PSBGbG9hdC5UWVBFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBwYXJhbSA9PSBEb3VibGUuVFlQRSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kI3RvU3RyaW5nKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLlN0cmluZyBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QudG9TdHJpbmcoKQorICAgICAgICBNZXRob2QgbXRoID0gbnVsbDsKKyAgICAgICAgQ2xhc3NbXSBwYXJtcyA9IHsgaW50LmNsYXNzLCBzaG9ydC5jbGFzcywgU3RyaW5nLmNsYXNzLCBib29sZWFuLmNsYXNzLAorICAgICAgICAgICAgICAgIE9iamVjdC5jbGFzcywgbG9uZy5jbGFzcywgYnl0ZS5jbGFzcywgY2hhci5jbGFzcywgZG91YmxlLmNsYXNzLAorICAgICAgICAgICAgICAgIGZsb2F0LmNsYXNzIH07CisgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgIG10aCA9IFRlc3RNZXRob2QuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoInByaW50VGVzdCIsIHBhcm1zKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgdG9TdHJpbmcgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJSZXR1cm5lZCBpbmNvcnJlY3Qgc3RyaW5nIGZvciBtZXRob2Q6ICIgKyBtdGgudG9TdHJpbmcoKSwKKyAgICAgICAgICAgICAgICBtdGgKKyAgICAgICAgICAgICAgICAgICAgICAgIC50b1N0cmluZygpCisgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicHVibGljIHN0YXRpYyBmaW5hbCB2b2lkIHRlc3RzLmFwaS5qYXZhLmxhbmcucmVmbGVjdC5NZXRob2RUZXN0JFRlc3RNZXRob2QucHJpbnRUZXN0KGludCxzaG9ydCxqYXZhLmxhbmcuU3RyaW5nLGJvb2xlYW4samF2YS5sYW5nLk9iamVjdCxsb25nLGJ5dGUsY2hhcixkb3VibGUsZmxvYXQpIikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdXAgdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBvcGVuIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzIG1ldGhvZAorICAgICAqIGlzIGNhbGxlZCBiZWZvcmUgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvUGFyYW1ldGVyaXplZFR5cGVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L1BhcmFtZXRlcml6ZWRUeXBlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZjYjkwNDIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L1BhcmFtZXRlcml6ZWRUeXBlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLmxhbmcucmVmbGVjdDsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkZpZWxkOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlBhcmFtZXRlcml6ZWRUeXBlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGU7CisKKy8qKgorICogVGVzdHMgcGFyYW1ldGVyaXplZCB0eXBlcyBhbmQgdGhlaXIgcHJvcGVydGllcy4KKyAqLworcHVibGljIGNsYXNzIFBhcmFtZXRlcml6ZWRUeXBlVGVzdCBleHRlbmRzIEdlbmVyaWNSZWZsZWN0aW9uVGVzdHNCYXNlIHsKKworICAgIHN0YXRpYyBjbGFzcyBBPFQ+e30KKyAgICBzdGF0aWMgY2xhc3MgQiBleHRlbmRzIEE8U3RyaW5nPnt9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RyaW5nUGFyYW1ldGVyaXplZFN1cGVyQ2xhc3MoKSB7CisgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBCPiBjbGF6eiA9IEIuY2xhc3M7CisgICAgICAgIFR5cGUgZ2VuZXJpY1N1cGVyY2xhc3MgPSBjbGF6ei5nZXRHZW5lcmljU3VwZXJjbGFzcygpOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKFBhcmFtZXRlcml6ZWRUeXBlLmNsYXNzLCBnZW5lcmljU3VwZXJjbGFzcyk7CisgICAgICAgIFBhcmFtZXRlcml6ZWRUeXBlIHBhcmFtZXRlcml6ZWRUeXBlID0gKFBhcmFtZXRlcml6ZWRUeXBlKSBnZW5lcmljU3VwZXJjbGFzczsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFBhcmFtZXRlcml6ZWRUeXBlVGVzdC5jbGFzcywgcGFyYW1ldGVyaXplZFR5cGUuZ2V0T3duZXJUeXBlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQS5jbGFzcywgcGFyYW1ldGVyaXplZFR5cGUuZ2V0UmF3VHlwZSgpKTsKKworICAgICAgICBUeXBlW10gYWN0dWFsVHlwZUFyZ3VtZW50cyA9IHBhcmFtZXRlcml6ZWRUeXBlLmdldEFjdHVhbFR5cGVBcmd1bWVudHMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGFjdHVhbFR5cGVBcmd1bWVudHMpOworICAgICAgICBhc3NlcnRFcXVhbHMoU3RyaW5nLmNsYXNzLCBhY3R1YWxUeXBlQXJndW1lbnRzWzBdKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgQzxUPnt9CisgICAgc3RhdGljIGNsYXNzIEQ8VD4gZXh0ZW5kcyBDPFQ+e30KKworICAgIHB1YmxpYyB2b2lkIHRlc3RUeXBlUGFyYW1ldGVyaXplZFN1cGVyQ2xhc3MoKSB7CisgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBEPiBjbGF6eiA9IEQuY2xhc3M7CisgICAgICAgIFR5cGUgZ2VuZXJpY1N1cGVyY2xhc3MgPSBjbGF6ei5nZXRHZW5lcmljU3VwZXJjbGFzcygpOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKFBhcmFtZXRlcml6ZWRUeXBlLmNsYXNzLCBnZW5lcmljU3VwZXJjbGFzcyk7CisgICAgICAgIFBhcmFtZXRlcml6ZWRUeXBlIHBhcmFtZXRlcml6ZWRUeXBlID0gKFBhcmFtZXRlcml6ZWRUeXBlKSBnZW5lcmljU3VwZXJjbGFzczsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFBhcmFtZXRlcml6ZWRUeXBlVGVzdC5jbGFzcywgcGFyYW1ldGVyaXplZFR5cGUuZ2V0T3duZXJUeXBlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQy5jbGFzcywgcGFyYW1ldGVyaXplZFR5cGUuZ2V0UmF3VHlwZSgpKTsKKworICAgICAgICBUeXBlW10gYWN0dWFsVHlwZUFyZ3VtZW50cyA9IHBhcmFtZXRlcml6ZWRUeXBlLmdldEFjdHVhbFR5cGVBcmd1bWVudHMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGFjdHVhbFR5cGVBcmd1bWVudHMpOworICAgICAgICBhc3NlcnRFcXVhbHMoZ2V0VHlwZVBhcmFtZXRlcihELmNsYXNzKSwgYWN0dWFsVHlwZUFyZ3VtZW50c1swXSk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIEU8VD57fQorICAgIHN0YXRpYyBjbGFzcyBGPFQ+eworICAgICAgICBFPFQ+IGU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcmFtZXRlcml6ZWRNZW1lYmVyKCkgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICAgICAgQ2xhc3M8PyBleHRlbmRzIEY+IGNsYXp6ID0gRi5jbGFzczsKKyAgICAgICAgRmllbGQgZmllbGQgPSBjbGF6ei5nZXREZWNsYXJlZEZpZWxkKCJlIik7CisgICAgICAgIGFzc2VydEluc3RhbmNlT2YoUGFyYW1ldGVyaXplZFR5cGUuY2xhc3MsIGZpZWxkLmdldEdlbmVyaWNUeXBlKCkpOworICAgICAgICBQYXJhbWV0ZXJpemVkVHlwZSBwYXJhbWV0ZXJpemVkVHlwZSA9IChQYXJhbWV0ZXJpemVkVHlwZSkgZmllbGQuZ2V0R2VuZXJpY1R5cGUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFBhcmFtZXRlcml6ZWRUeXBlVGVzdC5jbGFzcywgcGFyYW1ldGVyaXplZFR5cGUuZ2V0T3duZXJUeXBlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRS5jbGFzcywgcGFyYW1ldGVyaXplZFR5cGUuZ2V0UmF3VHlwZSgpKTsKKworICAgICAgICBUeXBlW10gYWN0dWFsVHlwZUFyZ3VtZW50cyA9IHBhcmFtZXRlcml6ZWRUeXBlLmdldEFjdHVhbFR5cGVBcmd1bWVudHMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGFjdHVhbFR5cGVBcmd1bWVudHMpOworICAgICAgICBhc3NlcnRFcXVhbHMoZ2V0VHlwZVBhcmFtZXRlcihjbGF6eiksIGFjdHVhbFR5cGVBcmd1bWVudHNbMF0pOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvUHJveHlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L1Byb3h5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRkNDk2YjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L1Byb3h5VGVzdC5qYXZhCkBAIC0wLDAgKzEsMzE5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLmxhbmcucmVmbGVjdDsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25IYW5kbGVyOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Qcm94eTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5VbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9uOworCitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1Byb3h5X0kxOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Qcm94eV9JMjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfUHJveHlfUGFyZW50RXhjZXB0aW9uOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Qcm94eV9TdWJFeGNlcHRpb247CisKK3B1YmxpYyBjbGFzcyBQcm94eVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgLyoKKyAgICAgKiBXaGVuIG11bHRpcGxlIGludGVyZmFjZXMgZGVmaW5lIHRoZSBzYW1lIG1ldGhvZCwgdGhlIGxpc3Qgb2YgdGhyb3duCisgICAgICogZXhjZXB0aW9ucyBhcmUgdGhvc2Ugd2hpY2ggY2FuIGJlIG1hcHBlZCB0byBhbm90aGVyIGV4Y2VwdGlvbiBpbiB0aGUKKyAgICAgKiBvdGhlciBtZXRob2Q6CisgICAgICoKKyAgICAgKiBTdHJpbmcgZm9vKFN0cmluZyBzKSB0aHJvd3MgU3ViRXhjZXB0aW9uLCBMaW5rYWdlRXJyb3I7CisgICAgICoKKyAgICAgKiBVbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9uIHdyYXBwZXJzIGFueSBjaGVja2VkIGV4Y2VwdGlvbiB3aGljaCBpcyBub3QKKyAgICAgKiBpbiB0aGUgbWVyZ2VkIGxpc3QuIFNvIFBhcmVudEV4Y2VwdGlvbiB3b3VsZCBiZSB3cmFwcGVkLCBCVVQgTGlua2FnZUVycm9yCisgICAgICogd291bGQgbm90IGJlIHNpbmNlIGl0cyBub3QgYW4gRXJyb3IvUnVudGltZUV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIGludGVyZmFjZSBJMSB7IFN0cmluZyBmb28oU3RyaW5nIHMpIHRocm93cyBQYXJlbnRFeGNlcHRpb24sIExpbmthZ2VFcnJvcjsgfQorICAgICAqIGludGVyZmFjZSBJMiB7IFN0cmluZyBmb28oU3RyaW5nIHMpIHRocm93cyBTdWJFeGNlcHRpb24sIEVycm9yOyB9CisgICAgICovCisKKyAgICBpbnRlcmZhY2UgQnJva2VuMSB7CisgICAgICAgIHB1YmxpYyBmbG9hdCBtZXRob2QoZmxvYXQgX251bWJlcjAsIGZsb2F0IF9udW1iZXIxKTsKKyAgICB9CisKKyAgICBjbGFzcyBCcm9rZW4xSW52b2tlIGltcGxlbWVudHMgSW52b2NhdGlvbkhhbmRsZXIgeworICAgICAgICBwdWJsaWMgT2JqZWN0IGludm9rZShPYmplY3QgcHJveHksIE1ldGhvZCBtZXRob2QsIE9iamVjdFtdIGFyZ3MpCisgICAgICAgICAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgICAgICByZXR1cm4gYXJnc1sxXTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIFByb3h5Q29vbnN0cnVjdG9yVGVzdCBleHRlbmRzIFByb3h5IHsKKyAgICAgICAgcHJvdGVjdGVkIFByb3h5Q29vbnN0cnVjdG9yVGVzdChJbnZvY2F0aW9uSGFuZGxlciBoKSB7CisgICAgICAgICAgICBzdXBlcihoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LlByb3h5I2dldFByb3h5Q2xhc3MoamF2YS5sYW5nLkNsYXNzTG9hZGVyLAorICAgICAqICAgICAgICBqYXZhLmxhbmcuQ2xhc3NbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFByb3h5Q2xhc3NMamF2YV9sYW5nX0NsYXNzTG9hZGVyJExqYXZhX2xhbmdfQ2xhc3MoKSB7CisgICAgICAgIENsYXNzIHByb3h5ID0gUHJveHkuZ2V0UHJveHlDbGFzcyhTdXBwb3J0X1Byb3h5X0kxLmNsYXNzCisgICAgICAgICAgICAgICAgLmdldENsYXNzTG9hZGVyKCksIG5ldyBDbGFzc1tdIHsgU3VwcG9ydF9Qcm94eV9JMS5jbGFzcyB9KTsKKworICAgICAgICBhc3NlcnRUcnVlKCJEaWQgbm90IGNyZWF0ZSBhIFByb3h5IHN1YmNsYXNzICIsCisgICAgICAgICAgICAgICAgcHJveHkuZ2V0U3VwZXJjbGFzcygpID09IFByb3h5LmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRG9lcyBub3QgYmVsaWV2ZSBpdHMgYSBQcm94eSBjbGFzcyAiLCBQcm94eQorICAgICAgICAgICAgICAgIC5pc1Byb3h5Q2xhc3MocHJveHkpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJEb2VzIG5vdCBiZWxpZXZlIGl0J3MgYSBQcm94eSBjbGFzcyAiLCBQcm94eQorICAgICAgICAgICAgICAgIC5pc1Byb3h5Q2xhc3MoUHJveHkuZ2V0UHJveHlDbGFzcyhudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IENsYXNzW10geyBDb21wYXJhYmxlLmNsYXNzIH0pKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFByb3h5LmdldFByb3h5Q2xhc3MoU3VwcG9ydF9Qcm94eV9JMS5jbGFzcy5nZXRDbGFzc0xvYWRlcigpLAorICAgICAgICAgICAgICAgICAgICAoQ2xhc3M8Pz5bXSkgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOUEUgZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQcm94eS5nZXRQcm94eUNsYXNzKFN1cHBvcnRfUHJveHlfSTEuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IENsYXNzPD8+W10ge1N1cHBvcnRfUHJveHlfSTEuY2xhc3MsIG51bGx9KTsKKyAgICAgICAgICAgIGZhaWwoIk5QRSBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuUHJveHkjUHJveHkoamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvbkhhbmRsZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Qcm94eUxqYXZhX2xhbmdfcmVmbGVjdF9JbnZvY2F0aW9uSGFuZGxlcigpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXcgUHJveHlDb29uc3RydWN0b3JUZXN0KG5ldyBJbnZvY2F0aW9uSGFuZGxlcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgaW52b2tlKE9iamVjdCBwcm94eSwgTWV0aG9kIG1ldGhvZCwgT2JqZWN0W10gYXJncykKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0pKTsKKyAgICB9CisKKworCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuUHJveHkjbmV3UHJveHlJbnN0YW5jZShqYXZhLmxhbmcuQ2xhc3NMb2FkZXIsCisgICAgICogICAgICAgIGphdmEubGFuZy5DbGFzc1tdLCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uSGFuZGxlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X25ld1Byb3h5SW5zdGFuY2VMamF2YV9sYW5nX0NsYXNzTG9hZGVyJExqYXZhX2xhbmdfQ2xhc3NMamF2YV9sYW5nX3JlZmxlY3RfSW52b2NhdGlvbkhhbmRsZXIoKSB7CisgICAgICAgIE9iamVjdCBwID0gUHJveHkubmV3UHJveHlJbnN0YW5jZShTdXBwb3J0X1Byb3h5X0kxLmNsYXNzCisgICAgICAgICAgICAgICAgLmdldENsYXNzTG9hZGVyKCksIG5ldyBDbGFzc1tdIHsgU3VwcG9ydF9Qcm94eV9JMS5jbGFzcywKKyAgICAgICAgICAgICAgICBTdXBwb3J0X1Byb3h5X0kyLmNsYXNzIH0sIG5ldyBJbnZvY2F0aW9uSGFuZGxlcigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgaW52b2tlKE9iamVjdCBwcm94eSwgTWV0aG9kIG1ldGhvZCwgT2JqZWN0W10gYXJncykKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgICAgICAgICAgaWYgKG1ldGhvZC5nZXROYW1lKCkuZXF1YWxzKCJlcXVhbHMiKSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBCb29sZWFuKHByb3h5ID09IGFyZ3NbMF0pOworICAgICAgICAgICAgICAgIGlmIChtZXRob2QuZ2V0TmFtZSgpLmVxdWFscygiYXJyYXkiKSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBpbnRbXSB7IChpbnQpICgobG9uZ1tdKSBhcmdzWzBdKVsxXSwgLTEgfTsKKyAgICAgICAgICAgICAgICBpZiAobWV0aG9kLmdldE5hbWUoKS5lcXVhbHMoInN0cmluZyIpKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICgiIi5lcXVhbHMoYXJnc1swXSkpCisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3VwcG9ydF9Qcm94eV9TdWJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCJjbG9uZSIuZXF1YWxzKGFyZ3NbMF0pKQorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN1cHBvcnRfUHJveHlfUGFyZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgIGlmICgiZXJyb3IiLmVxdWFscyhhcmdzWzBdKSkKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBcnJheVN0b3JlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgIGlmICgiYW55Ii5lcXVhbHMoYXJnc1swXSkpCisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisKKyAgICAgICAgU3VwcG9ydF9Qcm94eV9JMSBwcm94eSA9IChTdXBwb3J0X1Byb3h5X0kxKSBwOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgaWRlbnRpdHkgdGVzdCAiLCBwcm94eS5lcXVhbHMocHJveHkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIG5vdCBlcXVhbHMgdGVzdCAiLCAhcHJveHkuZXF1YWxzKCIiKSk7CisgICAgICAgIGludFtdIHJlc3VsdCA9IChpbnRbXSkgcHJveHkuYXJyYXkobmV3IGxvbmdbXSB7IDEwMEwsIC0yMDBMIH0pOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCBwcmltaXRpdmUgdHlwZSBjb252ZXJzaW9uIHRlc3QgIiwgLTIwMCwgcmVzdWx0WzBdKTsKKworICAgICAgICBib29sZWFuIHdvcmtlZCA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJveHkuc3RyaW5nKCIiKTsKKyAgICAgICAgfSBjYXRjaCAoU3VwcG9ydF9Qcm94eV9TdWJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgd29ya2VkID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoU3VwcG9ydF9Qcm94eV9QYXJlbnRFeGNlcHRpb24gZSkgeyAvLyBpcyBuZXZlciB0aHJvd24KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJQcm9ibGVtIGNvbnZlcnRpbmcgZXhjZXB0aW9uICIsIHdvcmtlZCk7CisKKyAgICAgICAgd29ya2VkID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcm94eS5zdHJpbmcoImNsb25lIik7CisgICAgICAgIH0gY2F0Y2ggKFN1cHBvcnRfUHJveHlfUGFyZW50RXhjZXB0aW9uIGUpIHsgLy8gaXMgbmV2ZXIgdGhyb3duCisgICAgICAgIH0gY2F0Y2ggKFVuZGVjbGFyZWRUaHJvd2FibGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgd29ya2VkID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJQcm9ibGVtIGNvbnZlcnRpbmcgZXhjZXB0aW9uICIsIHdvcmtlZCk7CisKKyAgICAgICAgd29ya2VkID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcm94eS5zdHJpbmcoImVycm9yIik7CisgICAgICAgIH0gY2F0Y2ggKFN1cHBvcnRfUHJveHlfUGFyZW50RXhjZXB0aW9uIGUpIHsgLy8gaXMgbmV2ZXIgdGhyb3duCisgICAgICAgIH0gY2F0Y2ggKFVuZGVjbGFyZWRUaHJvd2FibGVFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHdvcmtlZCA9IGUuZ2V0Q2xhc3MoKSA9PSBBcnJheVN0b3JlRXhjZXB0aW9uLmNsYXNzOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlByb2JsZW0gY29udmVydGluZyBleGNlcHRpb24gIiwgd29ya2VkKTsKKworICAgICAgICB3b3JrZWQgPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByb3h5LnN0cmluZygiYW55Iik7CisgICAgICAgIH0gY2F0Y2ggKFN1cHBvcnRfUHJveHlfUGFyZW50RXhjZXB0aW9uIGUpIHsgLy8gaXMgbmV2ZXIgdGhyb3duCisgICAgICAgIH0gY2F0Y2ggKFVuZGVjbGFyZWRUaHJvd2FibGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgd29ya2VkID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJQcm9ibGVtIGNvbnZlcnRpbmcgZXhjZXB0aW9uICIsIHdvcmtlZCk7CisKKyAgICAgICAgQnJva2VuMSBwcm94eU9iamVjdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcm94eU9iamVjdCA9IChCcm9rZW4xKSBQcm94eS5uZXdQcm94eUluc3RhbmNlKEJyb2tlbjEuY2xhc3MKKyAgICAgICAgICAgICAgICAgICAgLmdldENsYXNzTG9hZGVyKCksIG5ldyBDbGFzc1tdIHsgQnJva2VuMS5jbGFzcyB9LAorICAgICAgICAgICAgICAgICAgICBuZXcgQnJva2VuMUludm9rZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkZhaWxlZCB0byBjcmVhdGUgcHJveHkgZm9yIGNsYXNzOiAiICsgQnJva2VuMS5jbGFzcyArICIgLSAiCisgICAgICAgICAgICAgICAgICAgICsgZSk7CisgICAgICAgIH0KKyAgICAgICAgZmxvYXQgYnJva2VuUmVzdWx0ID0gcHJveHlPYmplY3QubWV0aG9kKDIuMWYsIDUuOGYpOworICAgICAgICBhc3NlcnRUcnVlKCJJbnZhbGlkIGludm9rZSByZXN1bHQiLCBicm9rZW5SZXN1bHQgPT0gNS44Zik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuUHJveHkjaXNQcm94eUNsYXNzKGphdmEubGFuZy5DbGFzcykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzUHJveHlDbGFzc0xqYXZhX2xhbmdfQ2xhc3MoKSB7CisgICAgICAgIENsYXNzIHByb3h5ID0gUHJveHkuZ2V0UHJveHlDbGFzcyhTdXBwb3J0X1Byb3h5X0kxLmNsYXNzCisgICAgICAgICAgICAgICAgLmdldENsYXNzTG9hZGVyKCksIG5ldyBDbGFzc1tdIHsgU3VwcG9ydF9Qcm94eV9JMS5jbGFzcyB9KTsKKworICAgICAgICBjbGFzcyBGYWtlIGV4dGVuZHMgUHJveHkgeworICAgICAgICAgICAgRmFrZSgpIHsKKyAgICAgICAgICAgICAgICBzdXBlcihudWxsKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFByb3h5IGZha2UgPSBuZXcgUHJveHkobmV3IEludm9jYXRpb25IYW5kbGVyKCkgeworICAgICAgICAgICAgcHVibGljIE9iamVjdCBpbnZva2UoT2JqZWN0IHByb3h5LCBNZXRob2QgbWV0aG9kLCBPYmplY3RbXSBhcmdzKQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSkgeworICAgICAgICB9OworCisgICAgICAgIGFzc2VydFRydWUoIkRvZXMgbm90IGJlbGlldmUgaXRzIGEgUHJveHkgY2xhc3MgIiwgUHJveHkKKyAgICAgICAgICAgICAgICAuaXNQcm94eUNsYXNzKHByb3h5KSk7CisgICAgICAgIGFzc2VydFRydWUoIlByb3h5IHN1YmNsYXNzZXMgZG8gbm90IGNvdW50ICIsICFQcm94eQorICAgICAgICAgICAgICAgIC5pc1Byb3h5Q2xhc3MoRmFrZS5jbGFzcykpOworICAgICAgICBhc3NlcnRUcnVlKCJJcyBub3QgYSBydW50aW1lIGdlbmVyYXRlZCBQcm94eSBjbGFzcyAiLCAhUHJveHkKKyAgICAgICAgICAgICAgICAuaXNQcm94eUNsYXNzKGZha2UuZ2V0Q2xhc3MoKSkpOworICAgICAgICBib29sZWFuIHRocm93biA9IGZhbHNlOworICAgICAgICB0cnl7CisgICAgICAgIFByb3h5LmlzUHJveHlDbGFzcyhudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXgpeworICAgICAgICAgICAgdGhyb3duID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJOUEUgbm90IHRocm93bi4iLCB0aHJvd24pOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubGFuZy5yZWZsZWN0LlByb3h5I2dldEludm9jYXRpb25IYW5kbGVyKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnZvY2F0aW9uSGFuZGxlckxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICBJbnZvY2F0aW9uSGFuZGxlciBoYW5kbGVyID0gbmV3IEludm9jYXRpb25IYW5kbGVyKCkgeworICAgICAgICAgICAgcHVibGljIE9iamVjdCBpbnZva2UoT2JqZWN0IHByb3h5LCBNZXRob2QgbWV0aG9kLCBPYmplY3RbXSBhcmdzKQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBPYmplY3QgcCA9IFByb3h5Lm5ld1Byb3h5SW5zdGFuY2UoU3VwcG9ydF9Qcm94eV9JMS5jbGFzcworICAgICAgICAgICAgICAgIC5nZXRDbGFzc0xvYWRlcigpLCBuZXcgQ2xhc3NbXSB7IFN1cHBvcnRfUHJveHlfSTEuY2xhc3MgfSwKKyAgICAgICAgICAgICAgICBoYW5kbGVyKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJEaWQgbm90IHJldHVybiBpbnZvY2F0aW9uIGhhbmRsZXIgIiwgUHJveHkKKyAgICAgICAgICAgICAgICAuZ2V0SW52b2NhdGlvbkhhbmRsZXIocCkgPT0gaGFuZGxlcik7CisgICAgICAgIGJvb2xlYW4gYWJvcnRlZCA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgUHJveHkuZ2V0SW52b2NhdGlvbkhhbmRsZXIoIiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYWJvcnRlZCA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRGlkIG5vdCBkZXRlY3Qgbm9uIHByb3h5IG9iamVjdCAiLCBhYm9ydGVkKTsKKyAgICB9CisKKyAgICAvL1JlZ3Jlc3Npb24gVGVzdCBmb3IgSEFSTU9OWS0yMzU1CisgICAgcHVibGljIHZvaWQgdGVzdF9uZXdQcm94eUluc3RhbmNlX3dpdGhDb21wYXRpYmxlUmV0dXJuVHlwZXMoKSB7CisgICAgICAgIE9iamVjdCBvID0gUHJveHkKKyAgICAgICAgICAgICAgICAubmV3UHJveHlJbnN0YW5jZSh0aGlzLmdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDbGFzc1tdIHsgSVRlc3RSZXR1cm5PYmplY3QuY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElUZXN0UmV0dXJuU3RyaW5nLmNsYXNzIH0sCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVGVzdFByb3h5SGFuZGxlcihuZXcgVGVzdFByb3h5SW1wbCgpKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwobyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9uZXdQcm94eUluc3RhbmNlX3dpdGhOb25Db21wYXRpYmxlUmV0dXJuVHlwZXMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQcm94eS5uZXdQcm94eUluc3RhbmNlKHRoaXMuZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpLAorICAgICAgICAgICAgICAgICAgICBuZXcgQ2xhc3NbXSB7IElUZXN0UmV0dXJuSW50ZWdlci5jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBJVGVzdFJldHVyblN0cmluZy5jbGFzcyB9LCBuZXcgVGVzdFByb3h5SGFuZGxlcigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVGVzdFByb3h5SW1wbCgpKSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGludGVyZmFjZSBJVGVzdFJldHVybk9iamVjdCB7CisgICAgICAgIE9iamVjdCBmKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBpbnRlcmZhY2UgSVRlc3RSZXR1cm5TdHJpbmcgeworICAgICAgICBTdHJpbmcgZigpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgaW50ZXJmYWNlIElUZXN0UmV0dXJuSW50ZWdlciB7CisgICAgICAgIEludGVnZXIgZigpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgVGVzdFByb3h5SW1wbCBpbXBsZW1lbnRzIElUZXN0UmV0dXJuT2JqZWN0LAorICAgICAgICAgICAgSVRlc3RSZXR1cm5TdHJpbmcgeworICAgICAgICBwdWJsaWMgU3RyaW5nIGYoKSB7CisgICAgICAgICAgICAvLyBkbyBub3RoaW5nCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgVGVzdFByb3h5SGFuZGxlciBpbXBsZW1lbnRzIEludm9jYXRpb25IYW5kbGVyIHsKKyAgICAgICAgcHJpdmF0ZSBPYmplY3QgcHJveGllZDsKKworICAgICAgICBwdWJsaWMgVGVzdFByb3h5SGFuZGxlcihPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICBwcm94aWVkID0gb2JqZWN0OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBpbnZva2UoT2JqZWN0IG9iamVjdCwgTWV0aG9kIG1ldGhvZCwgT2JqZWN0W10gYXJncykKKyAgICAgICAgICAgICAgICB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKKyAgICAgICAgICAgIHJldHVybiBtZXRob2QuaW52b2tlKHByb3hpZWQsIGFyZ3MpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L1R5cGVWYXJpYWJsZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvVHlwZVZhcmlhYmxlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjMjI4NTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L1R5cGVWYXJpYWJsZVRlc3QuamF2YQpAQCAtMCwwICsxLDE1MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEubGFuZy5yZWZsZWN0OworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVHlwZVZhcmlhYmxlOworCisvKioKKyAqIFRlc3RzIHR5cGUgdmFyaWFibGVzIGFuZCB0aGVpciBwcm9wZXJ0aWVzLgorICovCitwdWJsaWMgY2xhc3MgVHlwZVZhcmlhYmxlVGVzdCBleHRlbmRzIEdlbmVyaWNSZWZsZWN0aW9uVGVzdHNCYXNlIHsKKworICAgIHN0YXRpYyBjbGFzcyBBPFQ+e30KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2ltcGxlVHlwZVZhcmlhYmxlT25DbGFzcygpeworICAgICAgICBDbGFzczw/IGV4dGVuZHMgQT4gY2xhenogPSBBLmNsYXNzOworICAgICAgICBUeXBlVmFyaWFibGVbXSB0eXBlUGFyYW1ldGVycyA9IGNsYXp6LmdldFR5cGVQYXJhbWV0ZXJzKCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZSh0eXBlUGFyYW1ldGVycyk7CisgICAgICAgIFR5cGVWYXJpYWJsZTxDbGFzcz4gdHlwZVZhcmlhYmxlID0gdHlwZVBhcmFtZXRlcnNbMF07CisgICAgICAgIGFzc2VydEVxdWFscyhjbGF6eiwgdHlwZVZhcmlhYmxlLmdldEdlbmVyaWNEZWNsYXJhdGlvbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUIiwgdHlwZVZhcmlhYmxlLmdldE5hbWUoKSk7CisgICAgICAgIFR5cGVbXSBib3VuZHMgPSB0eXBlVmFyaWFibGUuZ2V0Qm91bmRzKCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZShib3VuZHMpOworICAgICAgICBhc3NlcnRFcXVhbHMoT2JqZWN0LmNsYXNzLCBib3VuZHNbMF0pOworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBCeworICAgICAgICA8VD4gdm9pZCBiKCl7fTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFNpbXBsZVR5cGVWYXJpYWJsZU9uTWV0aG9kKCkgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICAgICAgQ2xhc3M8PyBleHRlbmRzIEI+IGNsYXp6ID0gQi5jbGFzczsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IGNsYXp6LmdldERlY2xhcmVkTWV0aG9kKCJiIik7CisgICAgICAgIFR5cGVWYXJpYWJsZTxNZXRob2Q+W10gdHlwZVBhcmFtZXRlcnMgPSBtZXRob2QuZ2V0VHlwZVBhcmFtZXRlcnMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKHR5cGVQYXJhbWV0ZXJzKTsKKyAgICAgICAgVHlwZVZhcmlhYmxlPE1ldGhvZD4gdHlwZVZhcmlhYmxlID0gdHlwZVBhcmFtZXRlcnNbMF07CisgICAgICAgIGFzc2VydEVxdWFscyhtZXRob2QsIHR5cGVWYXJpYWJsZS5nZXRHZW5lcmljRGVjbGFyYXRpb24oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVCIsIHR5cGVWYXJpYWJsZS5nZXROYW1lKCkpOworICAgICAgICBUeXBlW10gYm91bmRzID0gdHlwZVZhcmlhYmxlLmdldEJvdW5kcygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUoYm91bmRzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE9iamVjdC5jbGFzcywgYm91bmRzWzBdKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgQyB7CisgICAgICAgIDxUPkMoKXt9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RTaW1wbGVUeXBlVmFyaWFibGVPbkNvbnN0cnVjdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICAgICAgQ2xhc3M8PyBleHRlbmRzIEM+IGNsYXp6ID0gQy5jbGFzczsKKyAgICAgICAgQ29uc3RydWN0b3I8Pz4gY29uc3RydWN0b3IgPSBjbGF6ei5nZXREZWNsYXJlZENvbnN0cnVjdG9yKCk7CisgICAgICAgIFR5cGVWYXJpYWJsZTw/PltdIHR5cGVQYXJhbWV0ZXJzID0gY29uc3RydWN0b3IuZ2V0VHlwZVBhcmFtZXRlcnMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKHR5cGVQYXJhbWV0ZXJzKTsKKyAgICAgICAgVHlwZVZhcmlhYmxlPD8+IHR5cGVWYXJpYWJsZSA9IHR5cGVQYXJhbWV0ZXJzWzBdOworICAgICAgICBhc3NlcnRFcXVhbHMoY29uc3RydWN0b3IsIHR5cGVWYXJpYWJsZS5nZXRHZW5lcmljRGVjbGFyYXRpb24oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVCIsIHR5cGVWYXJpYWJsZS5nZXROYW1lKCkpOworICAgICAgICBUeXBlW10gYm91bmRzID0gdHlwZVZhcmlhYmxlLmdldEJvdW5kcygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUoYm91bmRzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE9iamVjdC5jbGFzcywgYm91bmRzWzBdKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgRDxRLFIsUz57fQorICAgIHB1YmxpYyB2b2lkIHRlc3RNdWx0aXBsZVR5cGVWYXJpYWJsZXNPbkNsYXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBEPiBjbGF6eiA9IEQuY2xhc3M7CisgICAgICAgIFR5cGVWYXJpYWJsZTw/PltdIHR5cGVQYXJhbWV0ZXJzID0gY2xhenouZ2V0VHlwZVBhcmFtZXRlcnMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHR5cGVQYXJhbWV0ZXJzLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUSIsIHR5cGVQYXJhbWV0ZXJzWzBdLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjbGF6eiwgdHlwZVBhcmFtZXRlcnNbMF0uZ2V0R2VuZXJpY0RlY2xhcmF0aW9uKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiUiIsIHR5cGVQYXJhbWV0ZXJzWzFdLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjbGF6eiwgdHlwZVBhcmFtZXRlcnNbMV0uZ2V0R2VuZXJpY0RlY2xhcmF0aW9uKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiUyIsIHR5cGVQYXJhbWV0ZXJzWzJdLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjbGF6eiwgdHlwZVBhcmFtZXRlcnNbMl0uZ2V0R2VuZXJpY0RlY2xhcmF0aW9uKCkpOworCisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIEUgeworICAgICAgICA8USxSLFM+IHZvaWQgZSgpe30KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdE11bHRpcGxlVHlwZVZhcmlhYmxlc09uTWV0aG9kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBFPiBjbGF6eiA9IEUuY2xhc3M7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBjbGF6ei5nZXREZWNsYXJlZE1ldGhvZCgiZSIpOworCisgICAgICAgIFR5cGVWYXJpYWJsZTw/PltdIHR5cGVQYXJhbWV0ZXJzID0gbWV0aG9kLmdldFR5cGVQYXJhbWV0ZXJzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCB0eXBlUGFyYW1ldGVycy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlEiLCB0eXBlUGFyYW1ldGVyc1swXS5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobWV0aG9kLCB0eXBlUGFyYW1ldGVyc1swXS5nZXRHZW5lcmljRGVjbGFyYXRpb24oKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSIiwgdHlwZVBhcmFtZXRlcnNbMV0uZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1ldGhvZCwgdHlwZVBhcmFtZXRlcnNbMV0uZ2V0R2VuZXJpY0RlY2xhcmF0aW9uKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiUyIsIHR5cGVQYXJhbWV0ZXJzWzJdLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtZXRob2QsIHR5cGVQYXJhbWV0ZXJzWzJdLmdldEdlbmVyaWNEZWNsYXJhdGlvbigpKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgRiB7CisgICAgICAgIDxRLFIsUz4gRigpe30KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdE11bHRpcGxlVHlwZVZhcmlhYmxlc09uQ29uc3RydWN0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2xhc3M8PyBleHRlbmRzIEY+IGNsYXp6ID0gRi5jbGFzczsKKyAgICAgICAgQ29uc3RydWN0b3I8Pz4gY29uc3RydWN0b3IgPSBjbGF6ei5nZXREZWNsYXJlZENvbnN0cnVjdG9yKCk7CisKKyAgICAgICAgVHlwZVZhcmlhYmxlPD8+W10gdHlwZVBhcmFtZXRlcnMgPSBjb25zdHJ1Y3Rvci5nZXRUeXBlUGFyYW1ldGVycygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgdHlwZVBhcmFtZXRlcnMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJRIiwgdHlwZVBhcmFtZXRlcnNbMF0uZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNvbnN0cnVjdG9yLCB0eXBlUGFyYW1ldGVyc1swXS5nZXRHZW5lcmljRGVjbGFyYXRpb24oKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSIiwgdHlwZVBhcmFtZXRlcnNbMV0uZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNvbnN0cnVjdG9yLCB0eXBlUGFyYW1ldGVyc1sxXS5nZXRHZW5lcmljRGVjbGFyYXRpb24oKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTIiwgdHlwZVBhcmFtZXRlcnNbMl0uZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNvbnN0cnVjdG9yLCB0eXBlUGFyYW1ldGVyc1syXS5nZXRHZW5lcmljRGVjbGFyYXRpb24oKSk7CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIEcgPFQgZXh0ZW5kcyBOdW1iZXI+e30KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTaW5nbGVCb3VuZCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDbGFzczw/IGV4dGVuZHMgRz4gY2xhenogPSBHLmNsYXNzOworICAgICAgICBUeXBlVmFyaWFibGVbXSB0eXBlUGFyYW1ldGVycyA9IGNsYXp6LmdldFR5cGVQYXJhbWV0ZXJzKCk7CisgICAgICAgIFR5cGVWYXJpYWJsZTxDbGFzcz4gdHlwZVZhcmlhYmxlID0gdHlwZVBhcmFtZXRlcnNbMF07CisgICAgICAgIFR5cGVbXSBib3VuZHMgPSB0eXBlVmFyaWFibGUuZ2V0Qm91bmRzKCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZShib3VuZHMpOworICAgICAgICBhc3NlcnRFcXVhbHMoTnVtYmVyLmNsYXNzLCBib3VuZHNbMF0pOworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBIIDxUIGV4dGVuZHMgTnVtYmVyICYgU2VyaWFsaXphYmxlID57fQorICAgIHB1YmxpYyB2b2lkIHRlc3RNdWx0aXBsZUJvdW5kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBIPiBjbGF6eiA9IEguY2xhc3M7CisgICAgICAgIFR5cGVWYXJpYWJsZVtdIHR5cGVQYXJhbWV0ZXJzID0gY2xhenouZ2V0VHlwZVBhcmFtZXRlcnMoKTsKKyAgICAgICAgVHlwZVZhcmlhYmxlPENsYXNzPiB0eXBlVmFyaWFibGUgPSB0eXBlUGFyYW1ldGVyc1swXTsKKyAgICAgICAgVHlwZVtdIGJvdW5kcyA9IHR5cGVWYXJpYWJsZS5nZXRCb3VuZHMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGJvdW5kcy5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoTnVtYmVyLmNsYXNzLCBib3VuZHNbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoU2VyaWFsaXphYmxlLmNsYXNzLCBib3VuZHNbMV0pOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvblRlc3RzLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L1VuZGVjbGFyZWRUaHJvd2FibGVFeGNlcHRpb25UZXN0cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhmZDJmZjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvbGFuZy9yZWZsZWN0L1VuZGVjbGFyZWRUaHJvd2FibGVFeGNlcHRpb25UZXN0cy5qYXZhCkBAIC0wLDAgKzEsNTMgQEAKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEubGFuZy5yZWZsZWN0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5pby5FT0ZFeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbjsKKworcHVibGljIGNsYXNzIFVuZGVjbGFyZWRUaHJvd2FibGVFeGNlcHRpb25UZXN0cyBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIEVPRkV4Y2VwdGlvbiB0aHJvd2FibGUgPSBuZXcgRU9GRXhjZXB0aW9uKCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIG1zZyA9ICJURVNUX01TRyI7CisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbiNnZXRDYXVzZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDYXVzZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9uIHV0ZSA9IG5ldyBVbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgIHRocm93YWJsZSk7CisgICAgICAgIGFzc2VydFNhbWUoIldyb25nIGNhdXNlIHJldHVybmVkIiwgdGhyb3dhYmxlLCB1dGUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbiNnZXRVbmRlY2xhcmVkVGhyb3dhYmxlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFVuZGVjbGFyZWRUaHJvd2FibGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbiB1dGUgPSBuZXcgVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICB0aHJvd2FibGUpOworICAgICAgICBhc3NlcnRTYW1lKCJXcm9uZyB1bmRlY2xhcmVkIHRocm93YWJsZSByZXR1cm5lZCIsIHRocm93YWJsZSwgdXRlCisgICAgICAgICAgICAgICAgLmdldFVuZGVjbGFyZWRUaHJvd2FibGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5sYW5nLnJlZmxlY3QuVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbiNVbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9uKGphdmEubGFuZy5UaHJvd2FibGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3Rvcl9UaHJvd2FibGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbiBlID0gbmV3IFVuZGVjbGFyZWRUaHJvd2FibGVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgdGhyb3dhYmxlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBjYXVzZSByZXR1cm5lZCIsIHRocm93YWJsZSwgZS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB0aHJvd2FibGUgcmV0dXJuZWQiLCB0aHJvd2FibGUsIGUKKyAgICAgICAgICAgICAgICAuZ2V0VW5kZWNsYXJlZFRocm93YWJsZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLmxhbmcucmVmbGVjdC5VbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9uI1VuZGVjbGFyZWRUaHJvd2FibGVFeGNlcHRpb24oamF2YS5sYW5nLlRocm93YWJsZSwgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yX1Rocm93YWJsZV9TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICBVbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9uIGUgPSBuZXcgVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICB0aHJvd2FibGUsIG1zZyk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgY2F1c2UgcmV0dXJuZWQiLCB0aHJvd2FibGUsIGUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdGhyb3dhYmxlIHJldHVybmVkIiwgdGhyb3dhYmxlLCBlCisgICAgICAgICAgICAgICAgLmdldFVuZGVjbGFyZWRUaHJvd2FibGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgbWVzc2FnZSByZXR1cm5lZCIsIG1zZywgZS5nZXRNZXNzYWdlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvV2lsZGNhcmRUeXBlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL2xhbmcvcmVmbGVjdC9XaWxkY2FyZFR5cGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWY4YmFlYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvV2lsZGNhcmRUeXBlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTUxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA4IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS5sYW5nLnJlZmxlY3Q7CisKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5QYXJhbWV0ZXJpemVkVHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5UeXBlOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlR5cGVWYXJpYWJsZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5XaWxkY2FyZFR5cGU7CisKKy8qKgorICogVGVzdHMgYm91bmRlZCB0eXBlIHBhcmFtZXRlcnMgZGVjbGFyZWQgb24gbWV0aG9kcyBhbmQgYm91bmRlZCB3aWxkY2FyZHMuCisgKi8KK3B1YmxpYyBjbGFzcyBXaWxkY2FyZFR5cGVUZXN0IGV4dGVuZHMgR2VuZXJpY1JlZmxlY3Rpb25UZXN0c0Jhc2UgeworICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW5jaGVja2VkIiwgImhpZGluZyJ9KQorICAgIHN0YXRpYyBjbGFzcyBCb3VuZGVkV2lsZGNhcmRzR2VuZXJpY01ldGhvZHM8VD4geworCisgICAgICAgIHB1YmxpYyA8VCBleHRlbmRzIEJvdW5kZWRXaWxkY2FyZHNHZW5lcmljTWV0aG9kcz4gdm9pZCBsb3dlckJvdW5kZWRQYXJhbU5vUmV0dXJuKCBCb3VuZGVkV2lsZGNhcmRzR2VuZXJpY01ldGhvZHM8PyBzdXBlciBUPiBwYXJhbSkge30KKworICAgICAgICBwdWJsaWMgPFQgZXh0ZW5kcyBCb3VuZGVkV2lsZGNhcmRzR2VuZXJpY01ldGhvZHM+IHZvaWQgdXBwZXJCb3VuZGVkUGFyYW1Ob1JldHVybiggQm91bmRlZFdpbGRjYXJkc0dlbmVyaWNNZXRob2RzPD8gZXh0ZW5kcyBUPiBwYXJhbSkge30KKworICAgICAgICBwdWJsaWMgPFQgZXh0ZW5kcyBCb3VuZGVkV2lsZGNhcmRzR2VuZXJpY01ldGhvZHM+IFQgbG93ZXJCb3VuZGVkUGFyYW1SZXR1cm4oQm91bmRlZFdpbGRjYXJkc0dlbmVyaWNNZXRob2RzPD8gc3VwZXIgVD4gcGFyYW0pIHsgcmV0dXJuIChUKSBuZXcgT2JqZWN0KCk7IH0KKworICAgICAgICBwdWJsaWMgPFQgZXh0ZW5kcyBCb3VuZGVkV2lsZGNhcmRzR2VuZXJpY01ldGhvZHM+IFQgdXBwZXJCb3VuZGVkUGFyYW1SZXR1cm4oQm91bmRlZFdpbGRjYXJkc0dlbmVyaWNNZXRob2RzPD8gZXh0ZW5kcyBUPiBwYXJhbSkgeyByZXR1cm4gKFQpIG5ldyBPYmplY3QoKTt9CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHJpdmF0ZSBzdGF0aWMgQ2xhc3M8PyBleHRlbmRzIEJvdW5kZWRXaWxkY2FyZHNHZW5lcmljTWV0aG9kcz4gY2xhenogPSBCb3VuZGVkV2lsZGNhcmRzR2VuZXJpY01ldGhvZHMuY2xhc3M7CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB0aGF0IHRoZXJlIGFyZSBpcyBvbmUgVHlwZSBQYXJhbWV0ZXIgb24gdGhlIENsYXNzIGl0c2VsZi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qm91bmRlZEdlbmVyaWNNZXRob2RzKCkgeworICAgICAgICBhc3NlcnRMZW5naHRPbmUoY2xhenouZ2V0VHlwZVBhcmFtZXRlcnMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgd2hldGhlciB0aGUgdHlwZSBwYXJhbWV0ZXIgaXMgYm91bmRlZCBieSBCb3VuZGVkR2VuZXJpY01ldGhvZHMgbGlrZToKKyAgICAgKiA8VCBleHRlbmRzIEJvdW5kZWRHZW5lcmljTWV0aG9kcz4uCisgICAgICogQHBhcmFtIG1ldGhvZCB0aGUgZGVjbGFyaW5nIG1ldGhvZAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjaGVja0JvdW5kZWRUeXBlUGFyYW1ldGVyKE1ldGhvZCBtZXRob2QpIHsKKyAgICAgICAgVHlwZVZhcmlhYmxlPE1ldGhvZD4gdHlwZVBhcmFtZXRlciA9IGdldFR5cGVQYXJhbWV0ZXIobWV0aG9kKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUIiwgdHlwZVBhcmFtZXRlci5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobWV0aG9kLCB0eXBlUGFyYW1ldGVyLmdldEdlbmVyaWNEZWNsYXJhdGlvbigpKTsKKworICAgICAgICBUeXBlW10gYm91bmRzID0gdHlwZVBhcmFtZXRlci5nZXRCb3VuZHMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGJvdW5kcyk7CisgICAgICAgIFR5cGUgYm91bmQgPSBib3VuZHNbMF07CisgICAgICAgIGFzc2VydEVxdWFscyhCb3VuZGVkV2lsZGNhcmRzR2VuZXJpY01ldGhvZHMuY2xhc3MsIGJvdW5kKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tMb3dlckJvdW5kZWRQYXJhbWV0ZXIoTWV0aG9kIG1ldGhvZCkgeworICAgICAgICBUeXBlIGdlbmVyaWNQYXJhbWV0ZXJUeXBlID0gbWV0aG9kLmdldEdlbmVyaWNQYXJhbWV0ZXJUeXBlcygpWzBdOworICAgICAgICBhc3NlcnRJbnN0YW5jZU9mKFBhcmFtZXRlcml6ZWRUeXBlLmNsYXNzLCBnZW5lcmljUGFyYW1ldGVyVHlwZSk7CisKKyAgICAgICAgUGFyYW1ldGVyaXplZFR5cGUgcGFyYW1ldGVyaXplZFR5cGUgPSAoUGFyYW1ldGVyaXplZFR5cGUpIGdlbmVyaWNQYXJhbWV0ZXJUeXBlOworCisgICAgICAgIFR5cGVbXSBhY3R1YWxUeXBlQXJndW1lbnRzID0gcGFyYW1ldGVyaXplZFR5cGUuZ2V0QWN0dWFsVHlwZUFyZ3VtZW50cygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUoYWN0dWFsVHlwZUFyZ3VtZW50cyk7CisgICAgICAgIGFzc2VydEluc3RhbmNlT2YoV2lsZGNhcmRUeXBlLmNsYXNzLCBhY3R1YWxUeXBlQXJndW1lbnRzWzBdKTsKKworICAgICAgICBXaWxkY2FyZFR5cGUgd2lsZGNhcmRUeXBlID0gKFdpbGRjYXJkVHlwZSkgYWN0dWFsVHlwZUFyZ3VtZW50c1swXTsKKworICAgICAgICBUeXBlW10gbG93ZXJCb3VuZHMgPSB3aWxkY2FyZFR5cGUuZ2V0TG93ZXJCb3VuZHMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGxvd2VyQm91bmRzKTsKKyAgICAgICAgVHlwZSBsb3dlckJvdW5kID0gbG93ZXJCb3VuZHNbMF07CisgICAgICAgIGFzc2VydEVxdWFscyhnZXRUeXBlUGFyYW1ldGVyKG1ldGhvZCksIGxvd2VyQm91bmQpOworCisgICAgICAgIFR5cGVbXSB1cHBlckJvdW5kcyA9IHdpbGRjYXJkVHlwZS5nZXRVcHBlckJvdW5kcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoT2JqZWN0LmNsYXNzLCB1cHBlckJvdW5kc1swXSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrVXBwZXJCb3VuZGVkUGFyYW1ldGVyKE1ldGhvZCBtZXRob2QpIHsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKG1ldGhvZC5nZXRHZW5lcmljUGFyYW1ldGVyVHlwZXMoKSk7CisgICAgICAgIFR5cGUgZ2VuZXJpY1BhcmFtZXRlclR5cGUgPSBtZXRob2QuZ2V0R2VuZXJpY1BhcmFtZXRlclR5cGVzKClbMF07CisgICAgICAgIGFzc2VydEluc3RhbmNlT2YoUGFyYW1ldGVyaXplZFR5cGUuY2xhc3MsIGdlbmVyaWNQYXJhbWV0ZXJUeXBlKTsKKworICAgICAgICBQYXJhbWV0ZXJpemVkVHlwZSBwYXJhbWV0ZXJpemVkVHlwZSA9IChQYXJhbWV0ZXJpemVkVHlwZSkgZ2VuZXJpY1BhcmFtZXRlclR5cGU7CisgICAgICAgIFR5cGVbXSBhY3R1YWxUeXBlQXJndW1lbnRzID0gcGFyYW1ldGVyaXplZFR5cGUuZ2V0QWN0dWFsVHlwZUFyZ3VtZW50cygpOworICAgICAgICBhc3NlcnRMZW5naHRPbmUoYWN0dWFsVHlwZUFyZ3VtZW50cyk7CisgICAgICAgIGFzc2VydEluc3RhbmNlT2YoV2lsZGNhcmRUeXBlLmNsYXNzLCBhY3R1YWxUeXBlQXJndW1lbnRzWzBdKTsKKworICAgICAgICBXaWxkY2FyZFR5cGUgd2lsZGNhcmRUeXBlID0gKFdpbGRjYXJkVHlwZSkgYWN0dWFsVHlwZUFyZ3VtZW50c1swXTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0WmVybyh3aWxkY2FyZFR5cGUuZ2V0TG93ZXJCb3VuZHMoKSk7CisKKyAgICAgICAgVHlwZVtdIHVwcGVyQm91bmRzID0gd2lsZGNhcmRUeXBlLmdldFVwcGVyQm91bmRzKCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZSh1cHBlckJvdW5kcyk7CisgICAgICAgIFR5cGUgdXBwZXJCb3VuZCA9IHVwcGVyQm91bmRzWzBdOworICAgICAgICBhc3NlcnRFcXVhbHMoZ2V0VHlwZVBhcmFtZXRlcihtZXRob2QpLCB1cHBlckJvdW5kKTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tSZXR1cm5UeXBlKE1ldGhvZCBtZXRob2QpIHsKKyAgICAgICAgVHlwZSBnZW5lcmljUmV0dXJuVHlwZSA9IG1ldGhvZC5nZXRHZW5lcmljUmV0dXJuVHlwZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoZ2V0VHlwZVBhcmFtZXRlcihtZXRob2QpLCBnZW5lcmljUmV0dXJuVHlwZSk7CisgICAgICAgIGFzc2VydFRydWUoZ2VuZXJpY1JldHVyblR5cGUgaW5zdGFuY2VvZiBUeXBlVmFyaWFibGUpOworCisgICAgICAgIFR5cGVWYXJpYWJsZTxNZXRob2Q+IHJldHVyblR5cGVWYXJpYWJsZSA9IChUeXBlVmFyaWFibGU8TWV0aG9kPikgZ2VuZXJpY1JldHVyblR5cGU7CisgICAgICAgIGFzc2VydEVxdWFscyhtZXRob2QsIHJldHVyblR5cGVWYXJpYWJsZS5nZXRHZW5lcmljRGVjbGFyYXRpb24oKSk7CisKKyAgICAgICAgVHlwZVtdIGJvdW5kcyA9IHJldHVyblR5cGVWYXJpYWJsZS5nZXRCb3VuZHMoKTsKKyAgICAgICAgYXNzZXJ0TGVuZ2h0T25lKGJvdW5kcyk7CisgICAgICAgIFR5cGUgYm91bmQgPSBib3VuZHNbMF07CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJvdW5kZWRXaWxkY2FyZHNHZW5lcmljTWV0aG9kcy5jbGFzcywgYm91bmQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVcHBlckJvdW5kZWRQYXJhbU5vUmV0dXJuKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBjbGF6ei5nZXRNZXRob2QoInVwcGVyQm91bmRlZFBhcmFtTm9SZXR1cm4iLCBCb3VuZGVkV2lsZGNhcmRzR2VuZXJpY01ldGhvZHMuY2xhc3MpOworICAgICAgICBjaGVja0JvdW5kZWRUeXBlUGFyYW1ldGVyKG1ldGhvZCk7CisgICAgICAgIGNoZWNrVXBwZXJCb3VuZGVkUGFyYW1ldGVyKG1ldGhvZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdExvd2VyQm91bmRlZFBhcmFtUmV0dXJuKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBjbGF6ei5nZXRNZXRob2QoImxvd2VyQm91bmRlZFBhcmFtUmV0dXJuIiwgQm91bmRlZFdpbGRjYXJkc0dlbmVyaWNNZXRob2RzLmNsYXNzKTsKKyAgICAgICAgY2hlY2tCb3VuZGVkVHlwZVBhcmFtZXRlcihtZXRob2QpOworICAgICAgICBjaGVja0xvd2VyQm91bmRlZFBhcmFtZXRlcihtZXRob2QpOworICAgICAgICBjaGVja1JldHVyblR5cGUobWV0aG9kKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXBwZXJCb3VuZGVkUGFyYW1SZXR1cm4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWV0aG9kIG1ldGhvZCA9IGNsYXp6LmdldE1ldGhvZCgidXBwZXJCb3VuZGVkUGFyYW1SZXR1cm4iLCBCb3VuZGVkV2lsZGNhcmRzR2VuZXJpY01ldGhvZHMuY2xhc3MpOworICAgICAgICBjaGVja0JvdW5kZWRUeXBlUGFyYW1ldGVyKG1ldGhvZCk7CisgICAgICAgIGNoZWNrVXBwZXJCb3VuZGVkUGFyYW1ldGVyKG1ldGhvZCk7CisgICAgICAgIGNoZWNrUmV0dXJuVHlwZShtZXRob2QpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RMb3dlckJvdW5kZWRQYXJhbU5vUmV0dXJuKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPSBjbGF6ei5nZXRNZXRob2QoImxvd2VyQm91bmRlZFBhcmFtTm9SZXR1cm4iLCBCb3VuZGVkV2lsZGNhcmRzR2VuZXJpY01ldGhvZHMuY2xhc3MpOworICAgICAgICBjaGVja0JvdW5kZWRUeXBlUGFyYW1ldGVyKG1ldGhvZCk7CisgICAgICAgIGFzc2VydExlbmdodE9uZShtZXRob2QuZ2V0R2VuZXJpY1BhcmFtZXRlclR5cGVzKCkpOworICAgICAgICBjaGVja0xvd2VyQm91bmRlZFBhcmFtZXRlcihtZXRob2QpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL21hdGgvQmlnSW50ZWdlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9tYXRoL0JpZ0ludGVnZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmMyYzI1YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9tYXRoL0JpZ0ludGVnZXJUZXN0LmphdmEKQEAgLTAsMCArMSwxMTg1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLm1hdGg7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworCitwdWJsaWMgY2xhc3MgQmlnSW50ZWdlclRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgQmlnSW50ZWdlciBtaW51c1R3byA9IG5ldyBCaWdJbnRlZ2VyKCItMiIsIDEwKTsKKworICAgIEJpZ0ludGVnZXIgbWludXNPbmUgPSBuZXcgQmlnSW50ZWdlcigiLTEiLCAxMCk7CisKKyAgICBCaWdJbnRlZ2VyIHplcm8gPSBuZXcgQmlnSW50ZWdlcigiMCIsIDEwKTsKKworICAgIEJpZ0ludGVnZXIgb25lID0gbmV3IEJpZ0ludGVnZXIoIjEiLCAxMCk7CisKKyAgICBCaWdJbnRlZ2VyIHR3byA9IG5ldyBCaWdJbnRlZ2VyKCIyIiwgMTApOworCisgICAgQmlnSW50ZWdlciB0ZW4gPSBuZXcgQmlnSW50ZWdlcigiMTAiLCAxMCk7CisKKyAgICBCaWdJbnRlZ2VyIHNpeHRlZW4gPSBuZXcgQmlnSW50ZWdlcigiMTYiLCAxMCk7CisKKyAgICBCaWdJbnRlZ2VyIG9uZVRob3VzYW5kID0gbmV3IEJpZ0ludGVnZXIoIjEwMDAiLCAxMCk7CisKKyAgICBCaWdJbnRlZ2VyIGFaaWxsaW9uID0gbmV3IEJpZ0ludGVnZXIoCisgICAgICAgICAgICAiMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIiwgMTApOworCisgICAgQmlnSW50ZWdlciB0d29Ub1RoZVRlbiA9IG5ldyBCaWdJbnRlZ2VyKCIxMDI0IiwgMTApOworCisgICAgQmlnSW50ZWdlciB0d29Ub1RoZVNldmVudHkgPSB0d28ucG93KDcwKTsKKworICAgIFJhbmRvbSByYW5kID0gbmV3IFJhbmRvbSgpOworCisgICAgQmlnSW50ZWdlciBiaTsKKworICAgIEJpZ0ludGVnZXIgYmkxOworCisgICAgQmlnSW50ZWdlciBiaTI7CisKKyAgICBCaWdJbnRlZ2VyIGJpMzsKKworICAgIEJpZ0ludGVnZXIgYmkxMTsKKworICAgIEJpZ0ludGVnZXIgYmkyMjsKKworICAgIEJpZ0ludGVnZXIgYmkzMzsKKworICAgIEJpZ0ludGVnZXIgYmkxMjsKKworICAgIEJpZ0ludGVnZXIgYmkyMzsKKworICAgIEJpZ0ludGVnZXIgYmkxMzsKKworICAgIEJpZ0ludGVnZXIgbGFyZ2VQb3M7CisKKyAgICBCaWdJbnRlZ2VyIHNtYWxsUG9zOworCisgICAgQmlnSW50ZWdlciBsYXJnZU5lZzsKKworICAgIEJpZ0ludGVnZXIgc21hbGxOZWc7CisKKyAgICBCaWdJbnRlZ2VyW11bXSBib29sZWFuUGFpcnM7CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm1hdGguQmlnSW50ZWdlciNCaWdJbnRlZ2VyKGludCwgamF2YS51dGlsLlJhbmRvbSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySUxqYXZhX3V0aWxfUmFuZG9tKCkgeworICAgICAgICAvLyByZWdyZXNzaW9uIHRlc3QgZm9yIEhBUk1PTlktMTA0NworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoSW50ZWdlci5NQVhfVkFMVUUsIChSYW5kb20pbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOZWdhdGl2ZUFycmF5U2l6ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBQQVNTRUQKKyAgICAgICAgfQorCisgICAgICAgIGJpID0gbmV3IEJpZ0ludGVnZXIoNzAsIHJhbmQpOworICAgICAgICBiaTIgPSBuZXcgQmlnSW50ZWdlcig3MCwgcmFuZCk7CisgICAgICAgIGFzc2VydFRydWUoIlJhbmRvbSBudW1iZXIgaXMgbmVnYXRpdmUiLCBiaS5jb21wYXJlVG8oemVybykgPj0gMCk7CisgICAgICAgIGFzc2VydFRydWUoIlJhbmRvbSBudW1iZXIgaXMgdG9vIGJpZyIsCisgICAgICAgICAgICAgICAgYmkuY29tcGFyZVRvKHR3b1RvVGhlU2V2ZW50eSkgPCAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiVHdvIHJhbmRvbSBudW1iZXJzIGluIGEgcm93IGFyZSB0aGUgc2FtZSAobWlnaHQgbm90IGJlIGEgYnVnIGJ1dCBpdCB2ZXJ5IGxpa2VseSBpcykiLAorICAgICAgICAgICAgICAgICFiaS5lcXVhbHMoYmkyKSk7CisgICAgICAgIGFzc2VydFRydWUoIk5vdCB6ZXJvIiwgbmV3IEJpZ0ludGVnZXIoMCwgcmFuZCkuZXF1YWxzKEJpZ0ludGVnZXIuWkVSTykpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigtMSwgKFJhbmRvbSludWxsKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gUEFTU0VECisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm1hdGguQmlnSW50ZWdlciNCaWdJbnRlZ2VyKGludCwgaW50LCBqYXZhLnV0aWwuUmFuZG9tKQorICAgICAqLworICAgIC8vIEJJR05VTSByZXR1cm5zIG5vIFByaW1lcyBzbWFsbGVyIHRoYW4gMTYgYml0cy4KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySUlMamF2YV91dGlsX1JhbmRvbSgpIHsKKyAgICAgICAgYmkgPSBuZXcgQmlnSW50ZWdlcigxMCwgNSwgcmFuZCk7CisgICAgICAgIGJpMiA9IG5ldyBCaWdJbnRlZ2VyKDEwLCA1LCByYW5kKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmFuZG9tIG51bWJlciBvbmUgaXMgbmVnYXRpdmUiLCBiaS5jb21wYXJlVG8oemVybykgPj0gMCk7CisgICAgICAgIGFzc2VydFRydWUoIlJhbmRvbSBudW1iZXIgb25lIGlzIHRvbyBiaWciLAorICAgICAgICAgICAgICAgIGJpLmNvbXBhcmVUbyh0d29Ub1RoZVRlbikgPCAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmFuZG9tIG51bWJlciB0d28gaXMgbmVnYXRpdmUiLCBiaTIuY29tcGFyZVRvKHplcm8pID49IDApOworICAgICAgICBhc3NlcnRUcnVlKCJSYW5kb20gbnVtYmVyIHR3byBpcyB0b28gYmlnIiwKKyAgICAgICAgICAgICAgICBiaTIuY29tcGFyZVRvKHR3b1RvVGhlVGVuKSA8IDApOworCisgICAgICAgIFJhbmRvbSByYW5kID0gbmV3IFJhbmRvbSgpOworICAgICAgICBCaWdJbnRlZ2VyIGJpOworICAgICAgICBpbnQgY2VydGFpbnR5W10gPSB7IDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLAorICAgICAgICAgICAgICAgIEludGVnZXIuTUlOX1ZBTFVFLCBJbnRlZ2VyLk1JTl9WQUxVRSArIDEsIC0yLCAtMSB9OworICAgICAgICBmb3IgKGludCBpID0gMjsgaSA8PSAyMDsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGludCBjID0gMDsgYyA8IGNlcnRhaW50eS5sZW5ndGg7IGMrKykgeworICAgICAgICAgICAgICAgIGJpID0gbmV3IEJpZ0ludGVnZXIoaSwgYywgcmFuZCk7IC8vIENyZWF0ZSBCaWdJbnRlZ2VyCisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQml0IGxlbmd0aCBpbmNvcnJlY3QiLCBiaS5iaXRMZW5ndGgoKSA9PSBpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigxLCA4MCwgKFJhbmRvbSludWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkFyaXRobWV0aWNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBQQVNTRUQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigtMSwgKFJhbmRvbSludWxsKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gUEFTU0VECisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm1hdGguQmlnSW50ZWdlciNCaWdJbnRlZ2VyKGJ5dGVbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yJEIoKSB7CisgICAgICAgIGJ5dGVbXSBteUJ5dGVBcnJheTsKKyAgICAgICAgbXlCeXRlQXJyYXkgPSBuZXcgYnl0ZVtdIHsgKGJ5dGUpIDB4MDAsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGRSB9OworICAgICAgICBiaSA9IG5ldyBCaWdJbnRlZ2VyKG15Qnl0ZUFycmF5KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHZhbHVlIGZvciBwb3MgbnVtYmVyIiwgYmkuZXF1YWxzKEJpZ0ludGVnZXIuWkVSTworICAgICAgICAgICAgICAgIC5zZXRCaXQoMTYpLnN1YnRyYWN0KHR3bykpKTsKKyAgICAgICAgbXlCeXRlQXJyYXkgPSBuZXcgYnl0ZVtdIHsgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZFIH07CisgICAgICAgIGJpID0gbmV3IEJpZ0ludGVnZXIobXlCeXRlQXJyYXkpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgdmFsdWUgZm9yIG5lZyBudW1iZXIiLCBiaS5lcXVhbHMobWludXNUd28pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm1hdGguQmlnSW50ZWdlciNCaWdJbnRlZ2VyKGludCwgYnl0ZVtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JJJEIoKSB7CisgICAgICAgIGJ5dGVbXSBteUJ5dGVBcnJheTsKKyAgICAgICAgbXlCeXRlQXJyYXkgPSBuZXcgYnl0ZVtdIHsgKGJ5dGUpIDB4RkYsIChieXRlKSAweEZFIH07CisgICAgICAgIGJpID0gbmV3IEJpZ0ludGVnZXIoMSwgbXlCeXRlQXJyYXkpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgdmFsdWUgZm9yIHBvcyBudW1iZXIiLCBiaS5lcXVhbHMoQmlnSW50ZWdlci5aRVJPCisgICAgICAgICAgICAgICAgLnNldEJpdCgxNikuc3VidHJhY3QodHdvKSkpOworICAgICAgICBiaSA9IG5ldyBCaWdJbnRlZ2VyKC0xLCBteUJ5dGVBcnJheSk7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCB2YWx1ZSBmb3IgbmVnIG51bWJlciIsIGJpLmVxdWFscyhCaWdJbnRlZ2VyLlpFUk8KKyAgICAgICAgICAgICAgICAuc2V0Qml0KDE2KS5zdWJ0cmFjdCh0d28pLm5lZ2F0ZSgpKSk7CisgICAgICAgIG15Qnl0ZUFycmF5ID0gbmV3IGJ5dGVbXSB7IChieXRlKSAwLCAoYnl0ZSkgMCB9OworICAgICAgICBiaSA9IG5ldyBCaWdJbnRlZ2VyKDAsIG15Qnl0ZUFycmF5KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHZhbHVlIGZvciB6ZXJvIiwgYmkuZXF1YWxzKHplcm8pKTsKKyAgICAgICAgbXlCeXRlQXJyYXkgPSBuZXcgYnl0ZVtdIHsgKGJ5dGUpIDEgfTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKDAsIG15Qnl0ZUFycmF5KTsKKyAgICAgICAgICAgIGZhaWwoIkZhaWxlZCB0byB0aHJvdyBOdW1iZXJGb3JtYXRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGNvcnJlY3QKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI0JpZ0ludGVnZXIoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbnN0cnVjdG9yX1N0cmluZ19lbXB0eSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIiKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bWJlckZvcm1hdEV4Y2VwdGlvbiBmb3IgbmV3IEJpZ0ludGVnZXIoXCJcIikiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI3RvQnl0ZUFycmF5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvQnl0ZUFycmF5KCkgeworICAgICAgICBieXRlW10gbXlCeXRlQXJyYXksIGFub3RoZXJCeXRlQXJyYXk7CisgICAgICAgIG15Qnl0ZUFycmF5ID0gbmV3IGJ5dGVbXSB7IDk3LCAzMywgMTIwLCAxMjQsIDUwLCAyLCAwLCAwLCAwLCAxMiwgMTI0LAorICAgICAgICAgICAgICAgIDQyIH07CisgICAgICAgIGFub3RoZXJCeXRlQXJyYXkgPSBuZXcgQmlnSW50ZWdlcihteUJ5dGVBcnJheSkudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGJ5dGUgYXJyYXkgcmV0dXJuZWQiLAorICAgICAgICAgICAgICAgIG15Qnl0ZUFycmF5Lmxlbmd0aCA9PSBhbm90aGVyQnl0ZUFycmF5Lmxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSBteUJ5dGVBcnJheS5sZW5ndGggLSAxOyBjb3VudGVyID49IDA7IGNvdW50ZXItLSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHZhbHVlcyBpbiByZXR1cm5lZCBieXRlIGFycmF5IiwKKyAgICAgICAgICAgICAgICAgICAgbXlCeXRlQXJyYXlbY291bnRlcl0gPT0gYW5vdGhlckJ5dGVBcnJheVtjb3VudGVyXSk7CisgICAgICAgIH0KKyAgICB9CisKKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RfU3BlY2lhbFByaW1lcygpIHsKKy8vICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInRlc3RfU3BlY2lhbFByaW1lcyIpOworLy8gICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgVFdPID0gQmlnSW50ZWdlci52YWx1ZU9mKDIpOworLy8gICAgICAgIEJpZ0ludGVnZXIgcCwgcTsKKy8vICAgICAgICBmb3IgKDs7KSB7CisvLyAgICAgICAgICAgIHAgPSBuZXcgQmlnSW50ZWdlcigxMDI0LCAyMywgbmV3IFJhbmRvbSgpKTsKKy8vICAgICAgICAgICAgcSA9IHAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpLmRpdmlkZShUV08pOworLy8gICAgICAgICAgICBpZiAocS5pc1Byb2JhYmxlUHJpbWUoMjApKSB7CisvLyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4ocSk7CisvLyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4ocCk7CisvLyAgICAgICAgICAgICAgICBicmVhazsKKy8vICAgICAgICAgICAgfQorLy8gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIuIik7CisvLyAgICAgICAgfQorLy8gICAgICAgIGZhaWwoImlzUHJvYmFibGVQcmltZSBmYWlsZWQgZm9yOiAiICsgYmkpOworLy8gICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0ludGVnZXIjaXNQcm9iYWJsZVByaW1lKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzUHJvYmFibGVQcmltZUkoKSB7CisgICAgICAgIGludCBmYWlscyA9IDA7CisgICAgICAgIGJpID0gbmV3IEJpZ0ludGVnZXIoMjAsIDIwLCByYW5kKTsKKyAgICAgICAgaWYgKCFiaS5pc1Byb2JhYmxlUHJpbWUoMTcpKSB7CisgICAgICAgICAgICBmYWlscysrOworICAgICAgICB9CisgICAgICAgIGJpID0gbmV3IEJpZ0ludGVnZXIoIjQiLCAxMCk7CisgICAgICAgIGlmIChiaS5pc1Byb2JhYmxlUHJpbWUoMTcpKSB7CisgICAgICAgICAgICBmYWlsKCJpc1Byb2JhYmxlUHJpbWUgZmFpbGVkIGZvcjogIiArIGJpKTsKKyAgICAgICAgfQorICAgICAgICBiaSA9IEJpZ0ludGVnZXIudmFsdWVPZigxN0wgKiAxM0wpOworICAgICAgICBpZiAoYmkuaXNQcm9iYWJsZVByaW1lKDE3KSkgeworICAgICAgICAgICAgZmFpbCgiaXNQcm9iYWJsZVByaW1lIGZhaWxlZCBmb3I6ICIgKyBiaSk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChsb25nIGEgPSAyOyBhIDwgMTAwMDsgYSsrKSB7CisgICAgICAgICAgICBpZiAoaXNQcmltZShhKSkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImZhbHNlIG5lZ2F0aXZlIG9uIHByaW1lIG51bWJlciA8MTAwMCIsIEJpZ0ludGVnZXIKKyAgICAgICAgICAgICAgICAgICAgICAgIC52YWx1ZU9mKGEpLmlzUHJvYmFibGVQcmltZSg1KSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKEJpZ0ludGVnZXIudmFsdWVPZihhKS5pc1Byb2JhYmxlUHJpbWUoMTcpKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJpc1Byb2JhYmxlUHJpbWUgZmFpbGVkIGZvcjogIiArIGEpOworICAgICAgICAgICAgICAgIGZhaWxzKys7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgYSA9IDA7IGEgPCAxMDAwOyBhKyspIHsKKyAgICAgICAgICAgIGJpID0gQmlnSW50ZWdlci52YWx1ZU9mKHJhbmQubmV4dEludCgxMDAwMDAwKSkubXVsdGlwbHkoCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZihyYW5kLm5leHRJbnQoMTAwMDAwMCkpKTsKKyAgICAgICAgICAgIGlmIChiaS5pc1Byb2JhYmxlUHJpbWUoMTcpKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJpc1Byb2JhYmxlUHJpbWUgZmFpbGVkIGZvcjogIiArIGJpKTsKKyAgICAgICAgICAgICAgICBmYWlscysrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGEgPSAwOyBhIDwgMjAwOyBhKyspIHsKKyAgICAgICAgICAgIGJpID0gbmV3IEJpZ0ludGVnZXIoNzAsIHJhbmQpLm11bHRpcGx5KG5ldyBCaWdJbnRlZ2VyKDcwLCByYW5kKSk7CisgICAgICAgICAgICBpZiAoYmkuaXNQcm9iYWJsZVByaW1lKDE3KSkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiaXNQcm9iYWJsZVByaW1lIGZhaWxlZCBmb3I6ICIgKyBiaSk7CisgICAgICAgICAgICAgICAgZmFpbHMrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUb28gbWFueSBmYWxzZSBwb3NpdGl2ZXMgLSBtYXkgaW5kaWNhdGUgYSBwcm9ibGVtIiwKKyAgICAgICAgICAgICAgICBmYWlscyA8PSAxKTsKKworICAgICAgICAvLworICAgICAgICAvLyBBbmQgbm93IHNvbWUgdGVzdHMgb24gcmVhbCBiaWcgaW50ZWdlcnM6CisgICAgICAgIC8vCisgICAgICAgIGJpID0gbmV3IEJpZ0ludGVnZXIoIjE1Mzg5MDk3MjE5MTIwMjI1NjE1MDMxMDgzMDE1NDkyMjE2MzgwNzMxNjUyNTM1ODQ1NTIxNTUxNjA2NzcyNzA3NjIzNTAxNjkzMjcyNjkyMjA5Mzg4ODc3MDU1MjEyODc2NzQ1ODg4Mjk2Mzg2OTQyMTQ0MDU4NTM2OTc0MyIsIDEwKTsKKyAgICAgICAgaWYgKCFiaS5pc1Byb2JhYmxlUHJpbWUoODApKSB7CisgICAgICAgICAgICBmYWlsKCJpc1Byb2JhYmxlUHJpbWUgZmFpbGVkIGZvcjogIiArIGJpKTsKKyAgICAgICAgfQorICAgICAgICBiaSA9IG5ldyBCaWdJbnRlZ2VyKCIyMDkwNTc1NDE2MjY5MTQxNzY3MjQ2NDkxOTgzNzk3NDIyMTIzNzQxMjUyNDc2NTYwMzcxNjQ5Nzk4MDY2MTM0MTIzODkzNTI0MDE0OTExODI1MTg4ODkwNDU4MjcwNDI2MDc2NDY4NjY0MDQ2NTY4NzUyODkwMTIyNDE1MDYxMzc3MzA4ODE3MzQ2MzAzNTQ2Njg4MjgyOTU3ODk3NTA0MDAwMjE2MjQxNDk3NTUwMjQzMDEwMjU3OTExMjE0MzI5NjQ2ODc3ODEwNjU1MTY0NjU4NDcwMjc4OTAxMDMwNTExMTU3MzcyNDQwNzUxMjU5Njc0MjQ3MzEwMzk2MTU4MjM4NTg4NDYzMjg0NzAyNzM3MTgxNjUzIiwgMTApOworICAgICAgICBpZiAoIWJpLmlzUHJvYmFibGVQcmltZSg4MCkpIHsKKyAgICAgICAgICAgIGZhaWwoImlzUHJvYmFibGVQcmltZSBmYWlsZWQgZm9yOiAiICsgYmkpOworICAgICAgICB9CisgICAgICAgIC8vCisgICAgICAgIGZvciAoaW50IGJpdExlbmd0aCA9IDEwMDsgYml0TGVuZ3RoIDw9IDYwMDsgYml0TGVuZ3RoICs9IDEwMCkgeworICAgICAgICAgICAgQmlnSW50ZWdlciBhID0gQmlnSW50ZWdlci5wcm9iYWJsZVByaW1lKGJpdExlbmd0aCwgcmFuZCk7CisgICAgICAgICAgICBCaWdJbnRlZ2VyIGIgPSBCaWdJbnRlZ2VyLnByb2JhYmxlUHJpbWUoYml0TGVuZ3RoLCByYW5kKTsKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgYyA9IGEubXVsdGlwbHkoYik7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSgiaXNQcm9iYWJsZVByaW1lIGZhaWxlZCBmb3IgcHJvZHVjdCBvZiB0d28gbGFyZ2UgcHJpbWVzIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSArICIgKiAiICsgYiArICIgPSAiICsgYyArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAoYml0TGVuZ3RoID0gIiArIGJpdExlbmd0aCArICIpIiwKKyAgICAgICAgICAgICAgICAgICAgYy5pc1Byb2JhYmxlUHJpbWUoODApICk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm1hdGguQmlnSW50ZWdlciNuZXh0UHJvYmFibGVQcmltZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9uZXh0UHJvYmFibGVQcmltZSgpIHsKKyAgICAgICAgbGFyZ2VQcmltZXNQcm9kdWN0KAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIyNTM3ODk1OTg0MDQzNDQ3NDI5MjM4NzE3MzU4NDU1Mzc3OTI5MDA5MTI2MzUzODc0OTI1MDQ5MzI1Mjg3MzI5Mjk1NjM1MTk4MjUyMDQ2MTU4NjE5OTk5MjE3NDUzMjMzODg5Mzc4NjE5NjE5MDA4MzU5MDExNzg5IiksCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjE3MTE1MDE0NTE2MDI2ODgzMzc4NzM4MzM0MjM1MzQ4NDk2Nzg1MjQwNTkzOTMyMzE5OTk2NzA4MDY1ODU2MzAxNzkzNzQ2ODkxNTIzNjYwMjk5Mzk5NTI3MzU3MTg3MTg3MDk0MzY0MjczMzc3NjIwODI2MTQ3MTAwOTMiKSwKKyAgICAgICAgICAgICAgICAiNDM0MzYxMjY2MDcwNjk5MzQzNDUwNDEwNjc4NzU2MjEwNjA4NDAzODM1NzI1ODEzMDg2MjU0NTQ3NzQ4MTQzMzYzOTU3NTg1MDIzNzM0Njc4NDc5ODg1MTEwMjUzNjYxNjc0OTMzNDc3MjU0MTk4NzUwMjEyMDU1MjI2NDkyMDA0MDYyOTUyNjAyODU0MDIwNDY5ODMzNDc0MTgxNTUzNjA5OTM3MzkxNzM1MTE5NDQyMzY4MTEyODM3NDE4NDk3MTg0NjA5OTI1NzA1Njk5NjYyNjM0MzA1MTgzMjEzMTM0MDU2ODEyMDYxMjIwNDI4NzEyMyIKKyAgICAgICAgKTsKKworICAgICAgICBsYXJnZVByaW1lc1Byb2R1Y3QoCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjQ2MTc5NzQ3MzA2MTEyMDg0NjMyMDA2NzUyODI5MzQ2NDEwODIxMjk4MTc0MDQ3NDk5MjUzMDg4ODcyODcwMTcyMTcxNTg1NDU3NjUxOTA0MzMzNjk4NDI5MzI3NzAxOTczNDEwMzIwMzE2ODIyMjI0MDUwNzQ1NjQ1ODY0NjI4MDIwNzIxODQwNDcxOTgyMTQzMTIxNDI4NDc4MDkyNTk0Mzc0NzczODc1Mjc0NjY3NjIyNTEwODc1MDAxNzA1ODg5NjIyNzc1MTQ4NTg1NTczMDkwMzY1NTA0OTk4OTY5NjE3MzU3MDE0ODUwMjA4NTEiKSwKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiNDMxMzE1ODk2NDQwNTcyODE1ODA1Nzk4MDg2NzAxNTc1ODQxOTUzMDE0MjIxNTc5OTM4NjMzMTI2NTgzNzIyNDA1MTgzMDgzODU4MzI2NjI3NDQ0MzEwNTcxNTAyMjE5NjIzODE2NTE5NjcyNzQ2NzA2NjkwMTQ5NTcwMTcwODU5MDE2Nzc1MDgxODA0MDExMjU0NDAzMTY5NDUwNjUyODc1OTE2OTY2OTQ0MjQ5MzAyOTk5OTE1NDA3NDk2MjU2NjE2NTI5MzI1NDY3MTE3NjY3MDcxOTUxODg5ODY4NDY5ODI1NTA2ODMxMzIxNjI5NDMzMyIpLAorICAgICAgICAgICAgICAgICIxOTkxODA1OTEwNjczNDg2MTM2MzMzNTg0MjczMDEwODkwNTQ2NjIxMDc2MjU2NDc2NTI5NzQwOTYxOTkyMDA0MTYyMTM3OTAwODY4NTUzMDczODkxODE0NTYwNDA5MjExMTMwNjk3MjUyNDU2NTgwMzIzNjAzMTU3MTg1ODI4MDAzMjQyMDE0MDMzMTgzODczNzYyMTE1MjYzMDc4MDI2MTgxNTAxNTE1NzY5NjM2MjU1MDEzODE2MTc3NDQ2NjgxNDY2MTA2OTg5Mjk3NTAwMzQ0MDY1NDk5ODg4MDU4Nzk2MDAzNzAxMzI5NDEzNzM3MjcwOTA5Njc4ODg5MjQ3MzM4NTAwMzQ1NzM2MTczNjU2MzkyNzI1NjU2MjY3ODE4MTE3NzI4Nzk5ODEyMTEzMTE3OTkwNzc2MjI4NTA0ODY1OTA3NTg0Mzk5NTUyNTgzMDk0NTY1OTkwNTU3MzE3NDg0OTAwNjc2ODkyMDYxODQ0MjM3MTAyNzU3NTMwODg1NDY0MTc4OTUzMzIxMTEzMjMxMzkxNjgzNjIwNTM1Nzk3Njk4ODk3Nzg0OTAyNDY4NzgwNTIxMjMwNDAzODI2MDIwNzgyMDY3OTk2NDIwMTIxMTMwOTM4NDA1NzQ1ODEzNzg1MSIKKyAgICAgICAgKTsKKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBsYXJnZVByaW1lc1Byb2R1Y3QoQmlnSW50ZWdlciBhLCBCaWdJbnRlZ2VyIGIsIFN0cmluZyBjKSB7CisgICAgICAgIEJpZ0ludGVnZXIgd3AgPSBhLm11bHRpcGx5KGIpOworICAgICAgICBhc3NlcnRGYWxzZSgiaXNQcm9iYWJsZVByaW1lIGZhaWxlZCBmb3IgcHJvZHVjdCBvZiB0d28gbGFyZ2UgcHJpbWVzIiArCisgICAgICAgICAgICAgICAgICAgICAgICBhICsgIiAqICIgKyBiICsgIiA9ICIgKyBjLAorICAgICAgICAgICAgICAgIHdwLmlzUHJvYmFibGVQcmltZSg4MCkgKTsKKyAgICAgICAgQmlnSW50ZWdlciB3cE1pbnVzT25lID0gd3Auc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpOworICAgICAgICBCaWdJbnRlZ2VyIG5leHQgPSB3cE1pbnVzT25lLm5leHRQcm9iYWJsZVByaW1lKCk7CisvLyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGMpOworLy8gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihuZXh0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibmV4dFByb2JhYmxlUHJpbWUgcmV0dXJucyB3cm9uZyBudW1iZXI6ICIgKyBuZXh0ICsKKyAgICAgICAgICAgICAgICAgICAgICAgICJpbnN0ZWFkIG9mIGV4cGVjdGVkOiAiICsgYywKKyAgICAgICAgICAgICAgICBuZXh0LnRvU3RyaW5nKCkuZXF1YWxzKGMpICk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0ludGVnZXIjcHJvYmFibGVQcmltZShpbnQsIGphdmEudXRpbC5SYW5kb20pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wcm9iYWJsZVByaW1lKCkgeworICAgICAgICBmb3IgKGludCBiaXRMZW5ndGggPSA1MDsgYml0TGVuZ3RoIDw9IDEwNTA7IGJpdExlbmd0aCArPSAxMDApIHsKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgYSA9IEJpZ0ludGVnZXIucHJvYmFibGVQcmltZShiaXRMZW5ndGgsIHJhbmQpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiaXNQcm9iYWJsZVByaW1lKHByb2JhYmxlUHJpbWUoKSkgZmFpbGVkIGZvcjogIiArIGJpLAorICAgICAgICAgICAgICAgICAgICBhLmlzUHJvYmFibGVQcmltZSg4MCkpOworLy8gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oYSk7CisvLyAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWUgPSBhLm5leHRQcm9iYWJsZVByaW1lKCk7CisvLyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIk5leHQgUHJvYmFibGUgUHJpbWUgaXMgIik7CisvLyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihwcmltZSk7CisgICAgICAgIH0KKyAgICB9CisKKy8vIEJFR0lOIGFuZHJvaWQtYWRkZWQKKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RNb2RQb3dQZXJmb3JtYW5jZSgpIHsKKy8vICAgICAgICBSYW5kb20gcm5kID0gbmV3IFJhbmRvbSgpOworLy8gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworLy8gICAgICAgICAgICBCaWdJbnRlZ2VyIGEgPSBuZXcgQmlnSW50ZWdlcig1MTIsIHJuZCk7CisvLyAgICAgICAgICAgIEJpZ0ludGVnZXIgbSA9IG5ldyBCaWdJbnRlZ2VyKDEwMjQsIHJuZCk7CisvLyAgICAgICAgICAgIEJpZ0ludGVnZXIgcCA9IG5ldyBCaWdJbnRlZ2VyKDI1Niwgcm5kKTsKKy8vICAgICAgICAgICAgQmlnSW50ZWdlciBtcCA9IGEubW9kUG93KHAsIG0pOworLy8gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obXApOworLy8gICAgICAgIH0KKy8vICAgIH0KKworLy8gc2hvd3MgZmFjdG9yIDIwIHNwZWVkIHVwIChCSUdOVU0gdG8gSGFybW9ueSBKYXZhKToKKy8vICAgIHB1YmxpYyB2b2lkIHRlc3ROZXh0UHJvYmFibGVQcmltZSgpIHsKKy8vICAgICAgICBSYW5kb20gcm5kID0gbmV3IFJhbmRvbSgpOworLy8gICAgICAgIHJuZC5zZXRTZWVkKDApOworLy8gICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IDMyOyBpICs9IDEpIHsKKy8vICAgICAgICAgICAgQmlnSW50ZWdlciBhID0gbmV3IEJpZ0ludGVnZXIoaSwgcm5kKTsKKy8vICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGEpOworLy8gICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lID0gYS5uZXh0UHJvYmFibGVQcmltZSgpOworLy8gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJOZXh0IFByb2JhYmxlIFByaW1lIGlzICIpOworLy8gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4ocHJpbWUpOworLy8gICAgICAgIH0KKy8vICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSAzMjsgaSArPSA0KSB7CisvLyAgICAgICAgICAgIEJpZ0ludGVnZXIgYSA9IG5ldyBCaWdJbnRlZ2VyKDMyICogaSwgcm5kKTsKKy8vICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGEpOworLy8gICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lID0gYS5uZXh0UHJvYmFibGVQcmltZSgpOworLy8gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJOZXh0IFByb2JhYmxlIFByaW1lIGlzICIpOworLy8gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4ocHJpbWUpOworLy8gICAgICAgIH0KKy8vICAgIH0KKworLy8gc2hvd3MgZmFjdG9yIDIwIHNwZWVkIHVwIChCSUdOVU0gdG8gSGFybW9ueSBKYXZhKToKKy8vIHNob3dzIHRoYXQgY2VydGFpbnR5IDgwIGlzICJwcmFjdGljYWxseSBhcXVpdmFsZW50IiB0byBjZXJ0YWludHkgMTAwCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJpbWVHZW5QZXJmb3JtYW5jZSgpIHsKKy8vICAgICAgICBSYW5kb20gcm5kID0gbmV3IFJhbmRvbSgpOworLy8gICAgICAgIHJuZC5zZXRTZWVkKDApOworLy8gICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IDMyOyBpICs9OCApIHsKKy8vICAgICAgICAgICAgQmlnSW50ZWdlciBhID0gbmV3IEJpZ0ludGVnZXIoMzIgKiBpLCA4MCwgcm5kKTsKKy8vICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGEpOworLy8gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk5vdyB0ZXN0aW5nIGl0IGFnYWluOiIpOworLy8gICAgICAgICAgICBpZiAoYS5pc1Byb2JhYmxlUHJpbWUoMTAwKSkgeworLy8gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIqKioqKioqKioqKioqKioqKioqKioqKiogUEFTU0VEISAqKioqKioqKioqKioqKioqKioqKioqKioqKiIpOworLy8gICAgICAgICAgICB9IGVsc2UgeworLy8gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIqKioqKioqKioqKioqKioqKioqKioqKiogRkFJTEVEISEhICoqKioqKioqKioqKioqKioqKioqKioqKioqIik7CisvLyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIioqKioqKioqKioqKioqKioqKioqKioqKiBGQUlMRUQhISEgKioqKioqKioqKioqKioqKioqKioqKioqKioiKTsKKy8vICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiKioqKioqKioqKioqKioqKioqKioqKioqIEZBSUxFRCEhISAqKioqKioqKioqKioqKioqKioqKioqKioqKiIpOworLy8gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIqKioqKioqKioqKioqKioqKioqKioqKiogRkFJTEVEISEhICoqKioqKioqKioqKioqKioqKioqKioqKioqIik7CisvLyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIioqKioqKioqKioqKioqKioqKioqKioqKiBGQUlMRUQhISEgKioqKioqKioqKioqKioqKioqKioqKioqKioiKTsKKy8vICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiKioqKioqKioqKioqKioqKioqKioqKioqIEZBSUxFRCEhISAqKioqKioqKioqKioqKioqKioqKioqKioqKiIpOworLy8gICAgICAgICAgICB9CisvLyAgICAgICAgfQorLy8gICAgfQorLy8gRU5EIGFuZHJvaWQtYWRkZWQKKworCisKKyAgICAvKioKKyAgICAgKiBqYXZhLm1hdGguQmlnSW50ZWdlciNlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VxdWFsc0xqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICBhc3NlcnRUcnVlKCIwPTAiLCB6ZXJvLmVxdWFscyhCaWdJbnRlZ2VyLnZhbHVlT2YoMCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiLTEyMz0tMTIzIiwgQmlnSW50ZWdlci52YWx1ZU9mKC0xMjMpLmVxdWFscygKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoLTEyMykpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiMD0xIiwgIXplcm8uZXF1YWxzKG9uZSkpOworICAgICAgICBhc3NlcnRUcnVlKCIwPS0xIiwgIXplcm8uZXF1YWxzKG1pbnVzT25lKSk7CisgICAgICAgIGFzc2VydFRydWUoIjE9LTEiLCAhb25lLmVxdWFscyhtaW51c09uZSkpOworICAgICAgICBhc3NlcnRUcnVlKCJiaTM9YmkzIiwgYmkzLmVxdWFscyhiaTMpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiYmkzPWNvcHkgb2YgYmkzIiwgYmkzLmVxdWFscyhiaTMubmVnYXRlKCkubmVnYXRlKCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiYmkzPWJpMiIsICFiaTMuZXF1YWxzKGJpMikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI2NvbXBhcmVUbyhqYXZhLm1hdGguQmlnSW50ZWdlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbXBhcmVUb0xqYXZhX21hdGhfQmlnSW50ZWdlcigpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU21hbGxlciBudW1iZXIgcmV0dXJuZWQgPj0gMCIsIG9uZS5jb21wYXJlVG8odHdvKSA8IDApOworICAgICAgICBhc3NlcnRUcnVlKCJMYXJnZXIgbnVtYmVyIHJldHVybmVkID49IDAiLCB0d28uY29tcGFyZVRvKG9uZSkgPiAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRXF1YWwgbnVtYmVycyBkaWQgbm90IHJldHVybiAwIiwgb25lLmNvbXBhcmVUbyhvbmUpID09IDApOworICAgICAgICBhc3NlcnRUcnVlKCJOZWcgbnVtYmVyIG1lc3NlZCB0aGluZ3MgdXAiLAorICAgICAgICAgICAgICAgIHR3by5uZWdhdGUoKS5jb21wYXJlVG8ob25lKSA8IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI2ludFZhbHVlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ludFZhbHVlKCkgeworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgaW50VmFsdWUgZm9yIDIqKjcwIiwKKyAgICAgICAgICAgICAgICB0d29Ub1RoZVNldmVudHkuaW50VmFsdWUoKSA9PSAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGludFZhbHVlIGZvciAyIiwgdHdvLmludFZhbHVlKCkgPT0gMik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0ludGVnZXIjbG9uZ1ZhbHVlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xvbmdWYWx1ZSgpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGxvbmdWYWx1ZSBmb3IgMioqNzAiLAorICAgICAgICAgICAgICAgIHR3b1RvVGhlU2V2ZW50eS5sb25nVmFsdWUoKSA9PSAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGxvbmdWYWx1ZSBmb3IgMiIsIHR3by5sb25nVmFsdWUoKSA9PSAyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm1hdGguQmlnSW50ZWdlciN2YWx1ZU9mKGxvbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF92YWx1ZU9mSigpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jdXJyZWQgbnVtYmVyIHJldHVybmVkIGZvciAyIiwgQmlnSW50ZWdlci52YWx1ZU9mKDJMKQorICAgICAgICAgICAgICAgIC5lcXVhbHModHdvKSk7CisgICAgICAgIGFzc2VydFRydWUoIkluY3VycmVkIG51bWJlciByZXR1cm5lZCBmb3IgMjAwIiwgQmlnSW50ZWdlci52YWx1ZU9mKDIwMEwpCisgICAgICAgICAgICAgICAgLmVxdWFscyhCaWdJbnRlZ2VyLnZhbHVlT2YoMTM5KS5hZGQoQmlnSW50ZWdlci52YWx1ZU9mKDYxKSkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm1hdGguQmlnSW50ZWdlciNhZGQoamF2YS5tYXRoLkJpZ0ludGVnZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRMamF2YV9tYXRoX0JpZ0ludGVnZXIoKSB7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBzdW0tLXdhbnRlZCBhIHppbGxpb24iLCBhWmlsbGlvbi5hZGQoYVppbGxpb24pCisgICAgICAgICAgICAgICAgLmFkZChhWmlsbGlvbi5uZWdhdGUoKSkuZXF1YWxzKGFaaWxsaW9uKSk7CisgICAgICAgIGFzc2VydFRydWUoIjArMCIsIHplcm8uYWRkKHplcm8pLmVxdWFscyh6ZXJvKSk7CisgICAgICAgIGFzc2VydFRydWUoIjArMSIsIHplcm8uYWRkKG9uZSkuZXF1YWxzKG9uZSkpOworICAgICAgICBhc3NlcnRUcnVlKCIxKzAiLCBvbmUuYWRkKHplcm8pLmVxdWFscyhvbmUpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiMSsxIiwgb25lLmFkZChvbmUpLmVxdWFscyh0d28pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiMCsoLTEpIiwgemVyby5hZGQobWludXNPbmUpLmVxdWFscyhtaW51c09uZSkpOworICAgICAgICBhc3NlcnRUcnVlKCIoLTEpKzAiLCBtaW51c09uZS5hZGQoemVybykuZXF1YWxzKG1pbnVzT25lKSk7CisgICAgICAgIGFzc2VydFRydWUoIigtMSkrKC0xKSIsIG1pbnVzT25lLmFkZChtaW51c09uZSkuZXF1YWxzKG1pbnVzVHdvKSk7CisgICAgICAgIGFzc2VydFRydWUoIjErKC0xKSIsIG9uZS5hZGQobWludXNPbmUpLmVxdWFscyh6ZXJvKSk7CisgICAgICAgIGFzc2VydFRydWUoIigtMSkrMSIsIG1pbnVzT25lLmFkZChvbmUpLmVxdWFscyh6ZXJvKSk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDA7IGkrKykgeworICAgICAgICAgICAgQmlnSW50ZWdlciBtaWRiaXQgPSB6ZXJvLnNldEJpdChpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImFkZCBmYWlscyB0byBjYXJyeSBvbiBiaXQgIiArIGksIG1pZGJpdC5hZGQobWlkYml0KQorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKHplcm8uc2V0Qml0KGkgKyAxKSkpOworICAgICAgICB9CisgICAgICAgIEJpZ0ludGVnZXIgYmkycDMgPSBiaTIuYWRkKGJpMyk7CisgICAgICAgIEJpZ0ludGVnZXIgYmkzcDIgPSBiaTMuYWRkKGJpMik7CisgICAgICAgIGFzc2VydFRydWUoImJpMnAzPWJpM3AyIiwgYmkycDMuZXF1YWxzKGJpM3AyKSk7CisKKworICAgICAgICAvLyBCRVNTRVIgVUVCRVJHUkVJRkVOREUgVEVTVFMgTUFDSEVOIElOIEZPUk0gVk9OIFNUUkVTUyBURVNULgorICAgICAgICAvLyBhZGQgbGFyZ2UgcG9zaXRpdmUgKyBzbWFsbCBwb3NpdGl2ZQorICAgICAgICBCaWdJbnRlZ2VyIHN1bSA9IGFaaWxsaW9uOworICAgICAgICBCaWdJbnRlZ2VyIGluY3JlbWVudCA9IG9uZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDsgaSsrKSB7CisKKyAgICAgICAgfQorCisgICAgICAgIC8vIGFkZCBsYXJnZSBwb3NpdGl2ZSArIHNtYWxsIG5lZ2F0aXZlCisKKyAgICAgICAgLy8gYWRkIGxhcmdlIG5lZ2F0aXZlICsgc21hbGwgcG9zaXRpdmUKKworICAgICAgICAvLyBhZGQgbGFyZ2UgbmVnYXRpdmUgKyBzbWFsbCBuZWdhdGl2ZQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI25lZ2F0ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9uZWdhdGUoKSB7CisgICAgICAgIGFzc2VydFRydWUoIlNpbmdsZSBuZWdhdGlvbiBvZiB6ZXJvIGRpZCBub3QgcmVzdWx0IGluIHplcm8iLCB6ZXJvCisgICAgICAgICAgICAgICAgLm5lZ2F0ZSgpLmVxdWFscyh6ZXJvKSk7CisgICAgICAgIGFzc2VydFRydWUoIlNpbmdsZSBuZWdhdGlvbiByZXN1bHRlZCBpbiBvcmlnaW5hbCBub256ZXJvIG51bWJlciIsCisgICAgICAgICAgICAgICAgIWFaaWxsaW9uLm5lZ2F0ZSgpLmVxdWFscyhhWmlsbGlvbikpOworICAgICAgICBhc3NlcnRUcnVlKCJEb3VibGUgbmVnYXRpb24gZGlkIG5vdCByZXN1bHQgaW4gb3JpZ2luYWwgbnVtYmVyIiwKKyAgICAgICAgICAgICAgICBhWmlsbGlvbi5uZWdhdGUoKS5uZWdhdGUoKS5lcXVhbHMoYVppbGxpb24pKTsKKworICAgICAgICBhc3NlcnRUcnVlKCIwLm5lZyIsIHplcm8ubmVnYXRlKCkuZXF1YWxzKHplcm8pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiMS5uZWciLCBvbmUubmVnYXRlKCkuZXF1YWxzKG1pbnVzT25lKSk7CisgICAgICAgIGFzc2VydFRydWUoIjIubmVnIiwgdHdvLm5lZ2F0ZSgpLmVxdWFscyhtaW51c1R3bykpOworICAgICAgICBhc3NlcnRUcnVlKCItMS5uZWciLCBtaW51c09uZS5uZWdhdGUoKS5lcXVhbHMob25lKSk7CisgICAgICAgIGFzc2VydFRydWUoIi0yLm5lZyIsIG1pbnVzVHdvLm5lZ2F0ZSgpLmVxdWFscyh0d28pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiMHg2MkVCNDBGRUY4NUFBOUVCTCoyLm5lZyIsIEJpZ0ludGVnZXIudmFsdWVPZigKKyAgICAgICAgICAgICAgICAweDYyRUI0MEZFRjg1QUE5RUJMICogMikubmVnYXRlKCkuZXF1YWxzKAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZigtMHg2MkVCNDBGRUY4NUFBOUVCTCAqIDIpKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjAwOyBpKyspIHsKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgbWlkYml0ID0gemVyby5zZXRCaXQoaSk7CisgICAgICAgICAgICBCaWdJbnRlZ2VyIG5lZ2F0ZSA9IG1pZGJpdC5uZWdhdGUoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIm5lZ2F0ZSBuZWdhdGUiLCBuZWdhdGUubmVnYXRlKCkuZXF1YWxzKG1pZGJpdCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgibmVnIGZhaWxzIG9uIGJpdCAiICsgaSwgbWlkYml0Lm5lZ2F0ZSgpLmFkZChtaWRiaXQpCisgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoemVybykpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0ludGVnZXIjc2lnbnVtKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NpZ251bSgpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcG9zaXRpdmUgc2lnbnVtIiwgdHdvLnNpZ251bSgpID09IDEpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyB6ZXJvIHNpZ251bSIsIHplcm8uc2lnbnVtKCkgPT0gMCk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIG5lZyB6ZXJvIHNpZ251bSIsIHplcm8ubmVnYXRlKCkuc2lnbnVtKCkgPT0gMCk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIG5lZyBzaWdudW0iLCB0d28ubmVnYXRlKCkuc2lnbnVtKCkgPT0gLTEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI2FicygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hYnMoKSB7CisgICAgICAgIGFzc2VydFRydWUoIkludmFsaWQgbnVtYmVyIHJldHVybmVkIGZvciB6aWxsaW9uIiwgYVppbGxpb24ubmVnYXRlKCkKKyAgICAgICAgICAgICAgICAuYWJzKCkuZXF1YWxzKGFaaWxsaW9uLmFicygpKSk7CisgICAgICAgIGFzc2VydFRydWUoIkludmFsaWQgbnVtYmVyIHJldHVybmVkIGZvciB6ZXJvIG5lZyIsIHplcm8ubmVnYXRlKCkuYWJzKCkKKyAgICAgICAgICAgICAgICAuZXF1YWxzKHplcm8pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW52YWxpZCBudW1iZXIgcmV0dXJuZWQgZm9yIHplcm8iLCB6ZXJvLmFicygpLmVxdWFscyh6ZXJvKSk7CisgICAgICAgIGFzc2VydFRydWUoIkludmFsaWQgbnVtYmVyIHJldHVybmVkIGZvciB0d28iLCB0d28ubmVnYXRlKCkuYWJzKCkKKyAgICAgICAgICAgICAgICAuZXF1YWxzKHR3bykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI3BvdyhpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wb3dJKCkgeworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZXhwb25lbnQgcmV0dXJuZWQgZm9yIDIqKjEwIiwgdHdvLnBvdygxMCkuZXF1YWxzKAorICAgICAgICAgICAgICAgIHR3b1RvVGhlVGVuKSk7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBleHBvbmVudCByZXR1cm5lZCBmb3IgMioqNzAiLCB0d28ucG93KDMwKQorICAgICAgICAgICAgICAgIC5tdWx0aXBseSh0d28ucG93KDQwKSkuZXF1YWxzKHR3b1RvVGhlU2V2ZW50eSkpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZXhwb25lbnQgcmV0dXJuZWQgZm9yIDEwKio1MCIsIHRlbi5wb3coNTApCisgICAgICAgICAgICAgICAgLmVxdWFscyhhWmlsbGlvbikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI21vZEludmVyc2UoamF2YS5tYXRoLkJpZ0ludGVnZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9tb2RJbnZlcnNlTGphdmFfbWF0aF9CaWdJbnRlZ2VyKCkgeworICAgICAgICBCaWdJbnRlZ2VyIGEgPSB6ZXJvLCBtb2QsIGludjsKKyAgICAgICAgZm9yIChpbnQgaiA9IDM7IGogPCA1MDsgaisrKSB7CisgICAgICAgICAgICBtb2QgPSBCaWdJbnRlZ2VyLnZhbHVlT2Yoaik7CisgICAgICAgICAgICBmb3IgKGludCBpID0gLWogKyAxOyBpIDwgajsgaSsrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgYSA9IEJpZ0ludGVnZXIudmFsdWVPZihpKTsKKyAgICAgICAgICAgICAgICAgICAgaW52ID0gYS5tb2RJbnZlcnNlKG1vZCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImJhZCBpbnZlcnNlOiAiICsgYSArICIgaW52IG1vZCAiICsgbW9kCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGVxdWFscyAiICsgaW52LCBvbmUuZXF1YWxzKGEubXVsdGlwbHkoaW52KS5tb2QoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kKSkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJpbnZlcnNlIGdyZWF0ZXIgdGhhbiBtb2R1bG86ICIgKyBhCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGludiBtb2QgIiArIG1vZCArICIgZXF1YWxzICIgKyBpbnYsIGludgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb21wYXJlVG8obW9kKSA8IDApOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJpbnZlcnNlIGxlc3MgdGhhbiB6ZXJvOiAiICsgYSArICIgaW52IG1vZCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBtb2QgKyAiIGVxdWFscyAiICsgaW52LCBpbnYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgPj0gMCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoInNob3VsZCBoYXZlIGZvdW5kIGludmVyc2UgZm9yICIgKyBhICsgIiBtb2QgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgbW9kLCAhb25lLmVxdWFscyhhLmdjZChtb2QpKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGogPSAxOyBqIDwgMTA7IGorKykgeworICAgICAgICAgICAgbW9kID0gYmkyLmFkZChCaWdJbnRlZ2VyLnZhbHVlT2YoaikpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDsgaSsrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgYSA9IGJpMy5hZGQoQmlnSW50ZWdlci52YWx1ZU9mKGkpKTsKKyAgICAgICAgICAgICAgICAgICAgaW52ID0gYS5tb2RJbnZlcnNlKG1vZCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImJhZCBpbnZlcnNlOiAiICsgYSArICIgaW52IG1vZCAiICsgbW9kCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGVxdWFscyAiICsgaW52LCBvbmUuZXF1YWxzKGEubXVsdGlwbHkoaW52KS5tb2QoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kKSkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJpbnZlcnNlIGdyZWF0ZXIgdGhhbiBtb2R1bG86ICIgKyBhCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGludiBtb2QgIiArIG1vZCArICIgZXF1YWxzICIgKyBpbnYsIGludgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb21wYXJlVG8obW9kKSA8IDApOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJpbnZlcnNlIGxlc3MgdGhhbiB6ZXJvOiAiICsgYSArICIgaW52IG1vZCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBtb2QgKyAiIGVxdWFscyAiICsgaW52LCBpbnYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgPj0gMCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoInNob3VsZCBoYXZlIGZvdW5kIGludmVyc2UgZm9yICIgKyBhICsgIiBtb2QgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgbW9kLCAhb25lLmVxdWFscyhhLmdjZChtb2QpKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0ludGVnZXIjc2hpZnRSaWdodChpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zaGlmdFJpZ2h0SSgpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiMSA+PiAwIiwgQmlnSW50ZWdlci52YWx1ZU9mKDEpLnNoaWZ0UmlnaHQoMCkuZXF1YWxzKAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FKSk7CisgICAgICAgIGFzc2VydFRydWUoIjEgPj4gMSIsIEJpZ0ludGVnZXIudmFsdWVPZigxKS5zaGlmdFJpZ2h0KDEpLmVxdWFscygKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLlpFUk8pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiMSA+PiA2MyIsIEJpZ0ludGVnZXIudmFsdWVPZigxKS5zaGlmdFJpZ2h0KDYzKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5aRVJPKSk7CisgICAgICAgIGFzc2VydFRydWUoIjEgPj4gNjQiLCBCaWdJbnRlZ2VyLnZhbHVlT2YoMSkuc2hpZnRSaWdodCg2NCkuZXF1YWxzKAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuWkVSTykpOworICAgICAgICBhc3NlcnRUcnVlKCIxID4+IDY1IiwgQmlnSW50ZWdlci52YWx1ZU9mKDEpLnNoaWZ0UmlnaHQoNjUpLmVxdWFscygKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLlpFUk8pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiMSA+PiAxMDAwIiwgQmlnSW50ZWdlci52YWx1ZU9mKDEpLnNoaWZ0UmlnaHQoMTAwMCkuZXF1YWxzKAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuWkVSTykpOworICAgICAgICBhc3NlcnRUcnVlKCItMSA+PiAwIiwgQmlnSW50ZWdlci52YWx1ZU9mKC0xKS5zaGlmdFJpZ2h0KDApLmVxdWFscygKKyAgICAgICAgICAgICAgICBtaW51c09uZSkpOworICAgICAgICBhc3NlcnRUcnVlKCItMSA+PiAxIiwgQmlnSW50ZWdlci52YWx1ZU9mKC0xKS5zaGlmdFJpZ2h0KDEpLmVxdWFscygKKyAgICAgICAgICAgICAgICBtaW51c09uZSkpOworICAgICAgICBhc3NlcnRUcnVlKCItMSA+PiA2MyIsIEJpZ0ludGVnZXIudmFsdWVPZigtMSkuc2hpZnRSaWdodCg2MykuZXF1YWxzKAorICAgICAgICAgICAgICAgIG1pbnVzT25lKSk7CisgICAgICAgIGFzc2VydFRydWUoIi0xID4+IDY0IiwgQmlnSW50ZWdlci52YWx1ZU9mKC0xKS5zaGlmdFJpZ2h0KDY0KS5lcXVhbHMoCisgICAgICAgICAgICAgICAgbWludXNPbmUpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiLTEgPj4gNjUiLCBCaWdJbnRlZ2VyLnZhbHVlT2YoLTEpLnNoaWZ0UmlnaHQoNjUpLmVxdWFscygKKyAgICAgICAgICAgICAgICBtaW51c09uZSkpOworICAgICAgICBhc3NlcnRUcnVlKCItMSA+PiAxMDAwIiwgQmlnSW50ZWdlci52YWx1ZU9mKC0xKS5zaGlmdFJpZ2h0KDEwMDApCisgICAgICAgICAgICAgICAgLmVxdWFscyhtaW51c09uZSkpOworCisgICAgICAgIEJpZ0ludGVnZXIgYSA9IEJpZ0ludGVnZXIuT05FOworICAgICAgICBCaWdJbnRlZ2VyIGMgPSBiaTM7CisgICAgICAgIEJpZ0ludGVnZXIgRSA9IGJpMy5uZWdhdGUoKTsKKyAgICAgICAgQmlnSW50ZWdlciBlID0gRTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDA7IGkrKykgeworICAgICAgICAgICAgQmlnSW50ZWdlciBiID0gQmlnSW50ZWdlci5aRVJPLnNldEJpdChpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImE9PWIiLCBhLmVxdWFscyhiKSk7CisgICAgICAgICAgICBhID0gYS5zaGlmdExlZnQoMSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJhIG5vbi1uZWciLCBhLnNpZ251bSgpID49IDApOworCisgICAgICAgICAgICBCaWdJbnRlZ2VyIGQgPSBiaTMuc2hpZnRSaWdodChpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImM9PWQiLCBjLmVxdWFscyhkKSk7CisgICAgICAgICAgICBjID0gYy5zaGlmdFJpZ2h0KDEpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiPj4xID09IC8yIiwgZC5kaXZpZGUodHdvKS5lcXVhbHMoYykpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiYyBub24tbmVnIiwgYy5zaWdudW0oKSA+PSAwKTsKKworICAgICAgICAgICAgQmlnSW50ZWdlciBmID0gRS5zaGlmdFJpZ2h0KGkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZT09ZiIsIGUuZXF1YWxzKGYpKTsKKyAgICAgICAgICAgIGUgPSBlLnNoaWZ0UmlnaHQoMSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCI+PjEgPT0gLzIiLCBmLnN1YnRyYWN0KG9uZSkuZGl2aWRlKHR3bykuZXF1YWxzKGUpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImUgbmVnYXRpdmUiLCBlLnNpZ251bSgpID09IC0xKTsKKworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiYiA+PiBpIiwgYi5zaGlmdFJpZ2h0KGkpLmVxdWFscyhvbmUpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImIgPj4gaSsxIiwgYi5zaGlmdFJpZ2h0KGkgKyAxKS5lcXVhbHMoemVybykpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiYiA+PiBpLTEiLCBiLnNoaWZ0UmlnaHQoaSAtIDEpLmVxdWFscyh0d28pKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI3NoaWZ0TGVmdChpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zaGlmdExlZnRJKCkgeworICAgICAgICBhc3NlcnRUcnVlKCIxIDw8IDAiLCBvbmUuc2hpZnRMZWZ0KDApLmVxdWFscyhvbmUpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiMSA8PCAxIiwgb25lLnNoaWZ0TGVmdCgxKS5lcXVhbHModHdvKSk7CisgICAgICAgIGFzc2VydFRydWUoIjEgPDwgNjMiLCBvbmUuc2hpZnRMZWZ0KDYzKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjgwMDAwMDAwMDAwMDAwMDAiLCAxNikpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiMSA8PCA2NCIsIG9uZS5zaGlmdExlZnQoNjQpLmVxdWFscygKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMTAwMDAwMDAwMDAwMDAwMDAiLCAxNikpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiMSA8PCA2NSIsIG9uZS5zaGlmdExlZnQoNjUpLmVxdWFscygKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMjAwMDAwMDAwMDAwMDAwMDAiLCAxNikpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiLTEgPDwgMCIsIG1pbnVzT25lLnNoaWZ0TGVmdCgwKS5lcXVhbHMobWludXNPbmUpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiLTEgPDwgMSIsIG1pbnVzT25lLnNoaWZ0TGVmdCgxKS5lcXVhbHMobWludXNUd28pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiLTEgPDwgNjMiLCBtaW51c09uZS5zaGlmdExlZnQoNjMpLmVxdWFscygKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiLTkyMjMzNzIwMzY4NTQ3NzU4MDgiKSkpOworICAgICAgICBhc3NlcnRUcnVlKCItMSA8PCA2NCIsIG1pbnVzT25lLnNoaWZ0TGVmdCg2NCkuZXF1YWxzKAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCItMTg0NDY3NDQwNzM3MDk1NTE2MTYiKSkpOworICAgICAgICBhc3NlcnRUcnVlKCItMSA8PCA2NSIsIG1pbnVzT25lLnNoaWZ0TGVmdCg2NSkuZXF1YWxzKAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCItMzY4OTM0ODgxNDc0MTkxMDMyMzIiKSkpOworCisgICAgICAgIEJpZ0ludGVnZXIgYSA9IGJpMzsKKyAgICAgICAgQmlnSW50ZWdlciBjID0gbWludXNPbmU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjAwOyBpKyspIHsKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgYiA9IGJpMy5zaGlmdExlZnQoaSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJhPT1iIiwgYS5lcXVhbHMoYikpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiYSA+PiBpID09IGJpMyIsIGEuc2hpZnRSaWdodChpKS5lcXVhbHMoYmkzKSk7CisgICAgICAgICAgICBhID0gYS5zaGlmdExlZnQoMSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCI8PDEgPT0gKjIiLCBiLm11bHRpcGx5KHR3bykuZXF1YWxzKGEpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImEgbm9uLW5lZyIsIGEuc2lnbnVtKCkgPj0gMCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJhLmJpdENvdW50PT1iLmJpdENvdW50IiwgYS5iaXRDb3VudCgpID09IGIuYml0Q291bnQoKSk7CisKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgZCA9IG1pbnVzT25lLnNoaWZ0TGVmdChpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImM9PWQiLCBjLmVxdWFscyhkKSk7CisgICAgICAgICAgICBjID0gYy5zaGlmdExlZnQoMSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCI8PDEgPT0gKjIgbmVnYXRpdmUiLCBkLm11bHRpcGx5KHR3bykuZXF1YWxzKGMpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImMgbmVnYXRpdmUiLCBjLnNpZ251bSgpID09IC0xKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImQgPj4gaSA9PSBtaW51c09uZSIsIGQuc2hpZnRSaWdodChpKS5lcXVhbHMobWludXNPbmUpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI211bHRpcGx5KGphdmEubWF0aC5CaWdJbnRlZ2VyKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfbXVsdGlwbHlMamF2YV9tYXRoX0JpZ0ludGVnZXIoKSB7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBzdW0tLXdhbnRlZCB0aHJlZSB6aWxsaW9uIiwgYVppbGxpb24KKyAgICAgICAgICAgICAgICAuYWRkKGFaaWxsaW9uKS5hZGQoYVppbGxpb24pLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgIGFaaWxsaW9uLm11bHRpcGx5KG5ldyBCaWdJbnRlZ2VyKCIzIiwgMTApKSkpOworCisgICAgICAgIGFzc2VydFRydWUoIjAqMCIsIHplcm8ubXVsdGlwbHkoemVybykuZXF1YWxzKHplcm8pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiMCoxIiwgemVyby5tdWx0aXBseShvbmUpLmVxdWFscyh6ZXJvKSk7CisgICAgICAgIGFzc2VydFRydWUoIjEqMCIsIG9uZS5tdWx0aXBseSh6ZXJvKS5lcXVhbHMoemVybykpOworICAgICAgICBhc3NlcnRUcnVlKCIxKjEiLCBvbmUubXVsdGlwbHkob25lKS5lcXVhbHMob25lKSk7CisgICAgICAgIGFzc2VydFRydWUoIjAqKC0xKSIsIHplcm8ubXVsdGlwbHkobWludXNPbmUpLmVxdWFscyh6ZXJvKSk7CisgICAgICAgIGFzc2VydFRydWUoIigtMSkqMCIsIG1pbnVzT25lLm11bHRpcGx5KHplcm8pLmVxdWFscyh6ZXJvKSk7CisgICAgICAgIGFzc2VydFRydWUoIigtMSkqKC0xKSIsIG1pbnVzT25lLm11bHRpcGx5KG1pbnVzT25lKS5lcXVhbHMob25lKSk7CisgICAgICAgIGFzc2VydFRydWUoIjEqKC0xKSIsIG9uZS5tdWx0aXBseShtaW51c09uZSkuZXF1YWxzKG1pbnVzT25lKSk7CisgICAgICAgIGFzc2VydFRydWUoIigtMSkqMSIsIG1pbnVzT25lLm11bHRpcGx5KG9uZSkuZXF1YWxzKG1pbnVzT25lKSk7CisKKyAgICAgICAgdGVzdEFsbE11bHRzKGJpMSwgYmkxLCBiaTExKTsKKyAgICAgICAgdGVzdEFsbE11bHRzKGJpMiwgYmkyLCBiaTIyKTsKKyAgICAgICAgdGVzdEFsbE11bHRzKGJpMywgYmkzLCBiaTMzKTsKKyAgICAgICAgdGVzdEFsbE11bHRzKGJpMSwgYmkyLCBiaTEyKTsKKyAgICAgICAgdGVzdEFsbE11bHRzKGJpMSwgYmkzLCBiaTEzKTsKKyAgICAgICAgdGVzdEFsbE11bHRzKGJpMiwgYmkzLCBiaTIzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm1hdGguQmlnSW50ZWdlciNkaXZpZGUoamF2YS5tYXRoLkJpZ0ludGVnZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9kaXZpZGVMamF2YV9tYXRoX0JpZ0ludGVnZXIoKSB7CisgICAgICAgIHRlc3RBbGxEaXZzKGJpMzMsIGJpMyk7CisgICAgICAgIHRlc3RBbGxEaXZzKGJpMjIsIGJpMik7CisgICAgICAgIHRlc3RBbGxEaXZzKGJpMTEsIGJpMSk7CisgICAgICAgIHRlc3RBbGxEaXZzKGJpMTMsIGJpMSk7CisgICAgICAgIHRlc3RBbGxEaXZzKGJpMTMsIGJpMyk7CisgICAgICAgIHRlc3RBbGxEaXZzKGJpMTIsIGJpMSk7CisgICAgICAgIHRlc3RBbGxEaXZzKGJpMTIsIGJpMik7CisgICAgICAgIHRlc3RBbGxEaXZzKGJpMjMsIGJpMik7CisgICAgICAgIHRlc3RBbGxEaXZzKGJpMjMsIGJpMyk7CisgICAgICAgIHRlc3RBbGxEaXZzKGxhcmdlUG9zLCBiaTEpOworICAgICAgICB0ZXN0QWxsRGl2cyhsYXJnZVBvcywgYmkyKTsKKyAgICAgICAgdGVzdEFsbERpdnMobGFyZ2VQb3MsIGJpMyk7CisgICAgICAgIHRlc3RBbGxEaXZzKGxhcmdlTmVnLCBiaTEpOworICAgICAgICB0ZXN0QWxsRGl2cyhsYXJnZU5lZywgYmkyKTsKKyAgICAgICAgdGVzdEFsbERpdnMobGFyZ2VOZWcsIGJpMyk7CisgICAgICAgIHRlc3RBbGxEaXZzKGxhcmdlTmVnLCBsYXJnZVBvcyk7CisgICAgICAgIHRlc3RBbGxEaXZzKGxhcmdlUG9zLCBsYXJnZU5lZyk7CisgICAgICAgIHRlc3RBbGxEaXZzKGJpMywgYmkzKTsKKyAgICAgICAgdGVzdEFsbERpdnMoYmkyLCBiaTIpOworICAgICAgICB0ZXN0QWxsRGl2cyhiaTEsIGJpMSk7CisgICAgICAgIHRlc3REaXZSYW5nZXMoYmkxKTsKKyAgICAgICAgdGVzdERpdlJhbmdlcyhiaTIpOworICAgICAgICB0ZXN0RGl2UmFuZ2VzKGJpMyk7CisgICAgICAgIHRlc3REaXZSYW5nZXMoc21hbGxQb3MpOworICAgICAgICB0ZXN0RGl2UmFuZ2VzKGxhcmdlUG9zKTsKKyAgICAgICAgdGVzdERpdlJhbmdlcyhuZXcgQmlnSW50ZWdlcigiNjJFQjQwRkVGODVBQTlFQiIsIDE2KSk7CisgICAgICAgIHRlc3RBbGxEaXZzKEJpZ0ludGVnZXIudmFsdWVPZigweENDMDIyNTk1M0NMKSwgQmlnSW50ZWdlcgorICAgICAgICAgICAgICAgIC52YWx1ZU9mKDB4MUI5MzdCNzY1TCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsYXJnZVBvcy5kaXZpZGUoemVybyk7CisgICAgICAgICAgICBmYWlsKCJBcml0aG1ldGljRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJpMS5kaXZpZGUoemVybyk7CisgICAgICAgICAgICBmYWlsKCJBcml0aG1ldGljRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJpMy5uZWdhdGUoKS5kaXZpZGUoemVybyk7CisgICAgICAgICAgICBmYWlsKCJBcml0aG1ldGljRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHplcm8uZGl2aWRlKHplcm8pOworICAgICAgICAgICAgZmFpbCgiQXJpdGhtZXRpY0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI3JlbWFpbmRlcihqYXZhLm1hdGguQmlnSW50ZWdlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlbWFpbmRlckxqYXZhX21hdGhfQmlnSW50ZWdlcigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxhcmdlUG9zLnJlbWFpbmRlcih6ZXJvKTsKKyAgICAgICAgICAgIGZhaWwoIkFyaXRobWV0aWNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmkxLnJlbWFpbmRlcih6ZXJvKTsKKyAgICAgICAgICAgIGZhaWwoIkFyaXRobWV0aWNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmkzLm5lZ2F0ZSgpLnJlbWFpbmRlcih6ZXJvKTsKKyAgICAgICAgICAgIGZhaWwoIkFyaXRobWV0aWNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgemVyby5yZW1haW5kZXIoemVybyk7CisgICAgICAgICAgICBmYWlsKCJBcml0aG1ldGljRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0ludGVnZXIjbW9kKGphdmEubWF0aC5CaWdJbnRlZ2VyKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfbW9kTGphdmFfbWF0aF9CaWdJbnRlZ2VyKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbGFyZ2VQb3MubW9kKHplcm8pOworICAgICAgICAgICAgZmFpbCgiQXJpdGhtZXRpY0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiaTEubW9kKHplcm8pOworICAgICAgICAgICAgZmFpbCgiQXJpdGhtZXRpY0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiaTMubmVnYXRlKCkubW9kKHplcm8pOworICAgICAgICAgICAgZmFpbCgiQXJpdGhtZXRpY0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB6ZXJvLm1vZCh6ZXJvKTsKKyAgICAgICAgICAgIGZhaWwoIkFyaXRobWV0aWNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJpdGhtZXRpY0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm1hdGguQmlnSW50ZWdlciNkaXZpZGVBbmRSZW1haW5kZXIoamF2YS5tYXRoLkJpZ0ludGVnZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9kaXZpZGVBbmRSZW1haW5kZXJMamF2YV9tYXRoX0JpZ0ludGVnZXIoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsYXJnZVBvcy5kaXZpZGVBbmRSZW1haW5kZXIoemVybyk7CisgICAgICAgICAgICBmYWlsKCJBcml0aG1ldGljRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJpMS5kaXZpZGVBbmRSZW1haW5kZXIoemVybyk7CisgICAgICAgICAgICBmYWlsKCJBcml0aG1ldGljRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJpMy5uZWdhdGUoKS5kaXZpZGVBbmRSZW1haW5kZXIoemVybyk7CisgICAgICAgICAgICBmYWlsKCJBcml0aG1ldGljRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHplcm8uZGl2aWRlQW5kUmVtYWluZGVyKHplcm8pOworICAgICAgICAgICAgZmFpbCgiQXJpdGhtZXRpY0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI0JpZ0ludGVnZXIoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIGFzc2VydFRydWUoIm5ldygwKSIsIG5ldyBCaWdJbnRlZ2VyKCIwIikuZXF1YWxzKEJpZ0ludGVnZXIudmFsdWVPZigwKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJuZXcoMSkiLCBuZXcgQmlnSW50ZWdlcigiMSIpLmVxdWFscyhCaWdJbnRlZ2VyLnZhbHVlT2YoMSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibmV3KDEyMzQ1Njc4OTAxMjM0KSIsIG5ldyBCaWdJbnRlZ2VyKCIxMjM0NTY3ODkwMTIzNCIpCisgICAgICAgICAgICAgICAgLmVxdWFscyhCaWdJbnRlZ2VyLnZhbHVlT2YoMTIzNDU2Nzg5MDEyMzRMKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJuZXcoLTEpIiwgbmV3IEJpZ0ludGVnZXIoIi0xIikuZXF1YWxzKEJpZ0ludGVnZXIKKyAgICAgICAgICAgICAgICAudmFsdWVPZigtMSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibmV3KC0xMjM0NTY3ODkwMTIzNCkiLCBuZXcgQmlnSW50ZWdlcigiLTEyMzQ1Njc4OTAxMjM0IikKKyAgICAgICAgICAgICAgICAuZXF1YWxzKEJpZ0ludGVnZXIudmFsdWVPZigtMTIzNDU2Nzg5MDEyMzRMKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI0JpZ0ludGVnZXIoamF2YS5sYW5nLlN0cmluZywgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZ0koKSB7CisgICAgICAgIGFzc2VydFRydWUoIm5ldygwLDE2KSIsIG5ldyBCaWdJbnRlZ2VyKCIwIiwgMTYpLmVxdWFscyhCaWdJbnRlZ2VyCisgICAgICAgICAgICAgICAgLnZhbHVlT2YoMCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibmV3KDEsMTYpIiwgbmV3IEJpZ0ludGVnZXIoIjEiLCAxNikuZXF1YWxzKEJpZ0ludGVnZXIKKyAgICAgICAgICAgICAgICAudmFsdWVPZigxKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJuZXcoQUJGMzQ1Njc4OTAxMjM0LDE2KSIsIG5ldyBCaWdJbnRlZ2VyKCJBQkYzNDU2Nzg5MDEyMzQiLAorICAgICAgICAgICAgICAgIDE2KS5lcXVhbHMoQmlnSW50ZWdlci52YWx1ZU9mKDB4QUJGMzQ1Njc4OTAxMjM0TCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibmV3KGFiZjM0NTY3ODkwMTIzNCwxNikiLCBuZXcgQmlnSW50ZWdlcigiYWJmMzQ1Njc4OTAxMjM0IiwKKyAgICAgICAgICAgICAgICAxNikuZXF1YWxzKEJpZ0ludGVnZXIudmFsdWVPZigweEFCRjM0NTY3ODkwMTIzNEwpKSk7CisgICAgICAgIGFzc2VydFRydWUoIm5ldygtMSwxNikiLCBuZXcgQmlnSW50ZWdlcigiLTEiLCAxNikuZXF1YWxzKEJpZ0ludGVnZXIKKyAgICAgICAgICAgICAgICAudmFsdWVPZigtMSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibmV3KC1BQkYzNDU2Nzg5MDEyMzQsMTYpIiwgbmV3IEJpZ0ludGVnZXIoCisgICAgICAgICAgICAgICAgIi1BQkYzNDU2Nzg5MDEyMzQiLCAxNikuZXF1YWxzKEJpZ0ludGVnZXIKKyAgICAgICAgICAgICAgICAudmFsdWVPZigtMHhBQkYzNDU2Nzg5MDEyMzRMKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJuZXcoLWFiZjM0NTY3ODkwMTIzNCwxNikiLCBuZXcgQmlnSW50ZWdlcigKKyAgICAgICAgICAgICAgICAiLWFiZjM0NTY3ODkwMTIzNCIsIDE2KS5lcXVhbHMoQmlnSW50ZWdlcgorICAgICAgICAgICAgICAgIC52YWx1ZU9mKC0weEFCRjM0NTY3ODkwMTIzNEwpKSk7CisgICAgICAgIGFzc2VydFRydWUoIm5ldygtMTAxMDEwMTAxLDIpIiwgbmV3IEJpZ0ludGVnZXIoIi0xMDEwMTAxMDEiLCAyKQorICAgICAgICAgICAgICAgIC5lcXVhbHMoQmlnSW50ZWdlci52YWx1ZU9mKC0zNDEpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0ludGVnZXIjdG9TdHJpbmcoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9TdHJpbmcoKSB7CisgICAgICAgIGFzc2VydFRydWUoIjAudG9TdHJpbmciLCAiMCIuZXF1YWxzKEJpZ0ludGVnZXIudmFsdWVPZigwKS50b1N0cmluZygpKSk7CisgICAgICAgIGFzc2VydFRydWUoIjEudG9TdHJpbmciLCAiMSIuZXF1YWxzKEJpZ0ludGVnZXIudmFsdWVPZigxKS50b1N0cmluZygpKSk7CisgICAgICAgIGFzc2VydFRydWUoIjEyMzQ1Njc4OTAxMjM0LnRvU3RyaW5nIiwgIjEyMzQ1Njc4OTAxMjM0IgorICAgICAgICAgICAgICAgIC5lcXVhbHMoQmlnSW50ZWdlci52YWx1ZU9mKDEyMzQ1Njc4OTAxMjM0TCkudG9TdHJpbmcoKSkpOworICAgICAgICBhc3NlcnRUcnVlKCItMS50b1N0cmluZyIsICItMSIKKyAgICAgICAgICAgICAgICAuZXF1YWxzKEJpZ0ludGVnZXIudmFsdWVPZigtMSkudG9TdHJpbmcoKSkpOworICAgICAgICBhc3NlcnRUcnVlKCItMTIzNDU2Nzg5MDEyMzQudG9TdHJpbmciLCAiLTEyMzQ1Njc4OTAxMjM0IgorICAgICAgICAgICAgICAgIC5lcXVhbHMoQmlnSW50ZWdlci52YWx1ZU9mKC0xMjM0NTY3ODkwMTIzNEwpLnRvU3RyaW5nKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLm1hdGguQmlnSW50ZWdlciN0b1N0cmluZyhpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF90b1N0cmluZ0koKSB7CisgICAgICAgIGFzc2VydFRydWUoIjAudG9TdHJpbmcoMTYpIiwgIjAiLmVxdWFscyhCaWdJbnRlZ2VyLnZhbHVlT2YoMCkudG9TdHJpbmcoCisgICAgICAgICAgICAgICAgMTYpKSk7CisgICAgICAgIGFzc2VydFRydWUoIjEudG9TdHJpbmcoMTYpIiwgIjEiLmVxdWFscyhCaWdJbnRlZ2VyLnZhbHVlT2YoMSkudG9TdHJpbmcoCisgICAgICAgICAgICAgICAgMTYpKSk7CisgICAgICAgIGFzc2VydFRydWUoIkFCRjM0NTY3ODkwMTIzNC50b1N0cmluZygxNikiLCAiYWJmMzQ1Njc4OTAxMjM0IgorICAgICAgICAgICAgICAgIC5lcXVhbHMoQmlnSW50ZWdlci52YWx1ZU9mKDB4QUJGMzQ1Njc4OTAxMjM0TCkudG9TdHJpbmcoMTYpKSk7CisgICAgICAgIGFzc2VydFRydWUoIi0xLnRvU3RyaW5nKDE2KSIsICItMSIuZXF1YWxzKEJpZ0ludGVnZXIudmFsdWVPZigtMSkKKyAgICAgICAgICAgICAgICAudG9TdHJpbmcoMTYpKSk7CisgICAgICAgIGFzc2VydFRydWUoIi1BQkYzNDU2Nzg5MDEyMzQudG9TdHJpbmcoMTYpIiwgIi1hYmYzNDU2Nzg5MDEyMzQiCisgICAgICAgICAgICAgICAgLmVxdWFscyhCaWdJbnRlZ2VyLnZhbHVlT2YoLTB4QUJGMzQ1Njc4OTAxMjM0TCkudG9TdHJpbmcoMTYpKSk7CisgICAgICAgIGFzc2VydFRydWUoIi0xMDEwMTAxMDEudG9TdHJpbmcoMikiLCAiLTEwMTAxMDEwMSIuZXF1YWxzKEJpZ0ludGVnZXIKKyAgICAgICAgICAgICAgICAudmFsdWVPZigtMzQxKS50b1N0cmluZygyKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI2FuZChqYXZhLm1hdGguQmlnSW50ZWdlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FuZExqYXZhX21hdGhfQmlnSW50ZWdlcigpIHsKKyAgICAgICAgZm9yIChCaWdJbnRlZ2VyW10gZWxlbWVudCA6IGJvb2xlYW5QYWlycykgeworICAgICAgICAgICAgQmlnSW50ZWdlciBpMSA9IGVsZW1lbnRbMF0sIGkyID0gZWxlbWVudFsxXTsKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgcmVzID0gaTEuYW5kKGkyKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoInN5bW1ldHJ5IG9mIGFuZCIsIHJlcy5lcXVhbHMoaTIuYW5kKGkxKSkpOworICAgICAgICAgICAgaW50IGxlbiA9IE1hdGgubWF4KGkxLmJpdExlbmd0aCgpLCBpMi5iaXRMZW5ndGgoKSkgKyA2NjsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJhbmQiLCAoaTEudGVzdEJpdChpKSAmJiBpMi50ZXN0Qml0KGkpKSA9PSByZXMKKyAgICAgICAgICAgICAgICAgICAgICAgIC50ZXN0Qml0KGkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI29yKGphdmEubWF0aC5CaWdJbnRlZ2VyKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfb3JMamF2YV9tYXRoX0JpZ0ludGVnZXIoKSB7CisgICAgICAgIGZvciAoQmlnSW50ZWdlcltdIGVsZW1lbnQgOiBib29sZWFuUGFpcnMpIHsKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgaTEgPSBlbGVtZW50WzBdLCBpMiA9IGVsZW1lbnRbMV07CisgICAgICAgICAgICBCaWdJbnRlZ2VyIHJlcyA9IGkxLm9yKGkyKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoInN5bW1ldHJ5IG9mIG9yIiwgcmVzLmVxdWFscyhpMi5vcihpMSkpKTsKKyAgICAgICAgICAgIGludCBsZW4gPSBNYXRoLm1heChpMS5iaXRMZW5ndGgoKSwgaTIuYml0TGVuZ3RoKCkpICsgNjY7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgib3IiLCAoaTEudGVzdEJpdChpKSB8fCBpMi50ZXN0Qml0KGkpKSA9PSByZXMKKyAgICAgICAgICAgICAgICAgICAgICAgIC50ZXN0Qml0KGkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5CaWdJbnRlZ2VyI3hvcihqYXZhLm1hdGguQmlnSW50ZWdlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3hvckxqYXZhX21hdGhfQmlnSW50ZWdlcigpIHsKKyAgICAgICAgZm9yIChCaWdJbnRlZ2VyW10gZWxlbWVudCA6IGJvb2xlYW5QYWlycykgeworICAgICAgICAgICAgQmlnSW50ZWdlciBpMSA9IGVsZW1lbnRbMF0sIGkyID0gZWxlbWVudFsxXTsKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgcmVzID0gaTEueG9yKGkyKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoInN5bW1ldHJ5IG9mIHhvciIsIHJlcy5lcXVhbHMoaTIueG9yKGkxKSkpOworICAgICAgICAgICAgaW50IGxlbiA9IE1hdGgubWF4KGkxLmJpdExlbmd0aCgpLCBpMi5iaXRMZW5ndGgoKSkgKyA2NjsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJ4b3IiLCAoaTEudGVzdEJpdChpKSBeIGkyLnRlc3RCaXQoaSkpID09IHJlcworICAgICAgICAgICAgICAgICAgICAgICAgLnRlc3RCaXQoaSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0ludGVnZXIjbm90KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X25vdCgpIHsKKyAgICAgICAgZm9yIChCaWdJbnRlZ2VyW10gZWxlbWVudCA6IGJvb2xlYW5QYWlycykgeworICAgICAgICAgICAgQmlnSW50ZWdlciBpMSA9IGVsZW1lbnRbMF07CisgICAgICAgICAgICBCaWdJbnRlZ2VyIHJlcyA9IGkxLm5vdCgpOworICAgICAgICAgICAgaW50IGxlbiA9IGkxLmJpdExlbmd0aCgpICsgNjY7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgibm90IiwgIWkxLnRlc3RCaXQoaSkgPT0gcmVzLnRlc3RCaXQoaSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5tYXRoLkJpZ0ludGVnZXIjYW5kTm90KGphdmEubWF0aC5CaWdJbnRlZ2VyKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYW5kTm90TGphdmFfbWF0aF9CaWdJbnRlZ2VyKCkgeworICAgICAgICBmb3IgKEJpZ0ludGVnZXJbXSBlbGVtZW50IDogYm9vbGVhblBhaXJzKSB7CisgICAgICAgICAgICBCaWdJbnRlZ2VyIGkxID0gZWxlbWVudFswXSwgaTIgPSBlbGVtZW50WzFdOworICAgICAgICAgICAgQmlnSW50ZWdlciByZXMgPSBpMS5hbmROb3QoaTIpOworICAgICAgICAgICAgaW50IGxlbiA9IE1hdGgubWF4KGkxLmJpdExlbmd0aCgpLCBpMi5iaXRMZW5ndGgoKSkgKyA2NjsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJhbmROb3QiLCAoaTEudGVzdEJpdChpKSAmJiAhaTIudGVzdEJpdChpKSkgPT0gcmVzCisgICAgICAgICAgICAgICAgICAgICAgICAudGVzdEJpdChpKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBhc3ltbWV0cmljYWwKKyAgICAgICAgICAgIGkxID0gZWxlbWVudFsxXTsKKyAgICAgICAgICAgIGkyID0gZWxlbWVudFswXTsKKyAgICAgICAgICAgIHJlcyA9IGkxLmFuZE5vdChpMik7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiYW5kTm90IHJldmVyc2VkIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIChpMS50ZXN0Qml0KGkpICYmICFpMi50ZXN0Qml0KGkpKSA9PSByZXMudGVzdEJpdChpKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvL3JlZ3Jlc3Npb24gZm9yIEhBUk1PTlktNDY1MworICAgICAgICB0cnl7CisgICAgICAgICAgICBCaWdJbnRlZ2VyLlpFUk8uYW5kTm90KG51bGwpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE5QRSIpOworICAgICAgICB9Y2F0Y2goRXhjZXB0aW9uIGUpeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgICAgIEJpZ0ludGVnZXIgYmkgPSBuZXcgQmlnSW50ZWdlcigwLCBuZXcgYnl0ZVtde30pOworICAgICAgICBhc3NlcnRFcXVhbHMoQmlnSW50ZWdlci5aRVJPLCBiaS5hbmROb3QoQmlnSW50ZWdlci5aRVJPKSk7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvbmUoKSB7CisgICAgICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgSEFSTU9OWS0xNzcwCisgICAgICAgIE15QmlnSW50ZWdlciBteUJpZ0ludGVnZXIgPSBuZXcgTXlCaWdJbnRlZ2VyKCIxMjM0NSIpOworICAgICAgICBteUJpZ0ludGVnZXIgPSAoTXlCaWdJbnRlZ2VyKSBteUJpZ0ludGVnZXIuY2xvbmUoKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgTXlCaWdJbnRlZ2VyIGV4dGVuZHMgQmlnSW50ZWdlciBpbXBsZW1lbnRzIENsb25lYWJsZSB7CisgICAgICAgIHB1YmxpYyBNeUJpZ0ludGVnZXIoU3RyaW5nIHZhbCkgeworICAgICAgICAgICAgc3VwZXIodmFsKTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7IC8vIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIGJpMSA9IG5ldyBCaWdJbnRlZ2VyKCIyNDM2Nzk4MzI0NzY4OTc4IiwgMTYpOworICAgICAgICBiaTIgPSBuZXcgQmlnSW50ZWdlcigiNDU3NjgyOTQ3NTcyNDM4NzU4NDM3ODU0Mzc2NDU1NSIsIDE2KTsKKyAgICAgICAgYmkzID0gbmV3IEJpZ0ludGVnZXIoIjQzOTg3Mjk4MzYzMjc4NTc0MzY1NzMyNjQ1ODcyNjQzNTg3NjI0Mzg3NTYzMjQ1IiwKKyAgICAgICAgICAgICAgICAxNik7CisKKyAgICAgICAgYmkzMyA9IG5ldyBCaWdJbnRlZ2VyKAorICAgICAgICAgICAgICAgICIxMDczMDg0NjY5NDcwMTMxOTEyMDYwOTg5ODYyNTczMzk3NjA5MDg2NTMyNzU0NDc5MDEzNjY2Nzk0NDgwNTkzNDE3NTU0Mzg4ODY5MTQwMDU1OTI0OTA0MTA5NDQ3NDg4NTM0NzkyMjc2OTgwNzAwMSIsCisgICAgICAgICAgICAgICAgMTApOworICAgICAgICBiaTIyID0gbmV3IEJpZ0ludGVnZXIoCisgICAgICAgICAgICAgICAgIjMzMzAxNjA2OTMyMTcxNTA5NTE3MTU4MDU5NDg3Nzk1NjY5MDI1ODE3OTEyODUyMjE5OTYyNzgyMjMwNjI5NjMyMjI0NDU2MjQ5IiwKKyAgICAgICAgICAgICAgICAxMCk7CisgICAgICAgIGJpMTEgPSBuZXcgQmlnSW50ZWdlcigiNjgwOTAwMzAwMzgzMjk2MTMwNjA0ODc2MTI1ODcxMTI5NjA2NCIsIDEwKTsKKyAgICAgICAgYmkyMyA9IG5ldyBCaWdJbnRlZ2VyKAorICAgICAgICAgICAgICAgICI1OTc3OTEzMDAyNjgxOTE1NzM1MTM4ODgwNDU3NzE1OTQyMzU5MzI4MDk4OTA5NjMxMzg4NDAwODYwODM1OTU3MDY1NjU2OTU5NDMxNjAyOTM2MTA1MjcyMTQwNTciLAorICAgICAgICAgICAgICAgIDEwKTsKKyAgICAgICAgYmkxMyA9IG5ldyBCaWdJbnRlZ2VyKAorICAgICAgICAgICAgICAgICIyNzAzMDc5MTIxNjI5NDg1MDgzODc2NjY3MDMyMTMwMzg2MDAwMzEwNDEwNDM5NjYyMTUyNzk0ODI5NDA3MzExNTg5Njg0MzQwMDgiLAorICAgICAgICAgICAgICAgIDEwKTsKKyAgICAgICAgYmkxMiA9IG5ldyBCaWdJbnRlZ2VyKAorICAgICAgICAgICAgICAgICIxNTA1ODI0NDk3MTg5NTY0MTcxNzQ1MzE3NjQ3NzY5Nzc2NzA1MDQ4Mjk0NzE2MTY1NjQ1ODQ1NiIsIDEwKTsKKworICAgICAgICBsYXJnZVBvcyA9IG5ldyBCaWdJbnRlZ2VyKAorICAgICAgICAgICAgICAgICI4MzQ3NTk4MTQzNzk4NTczMTQ5ODY3NDMyOTg2NzU2ODc1Njk4NDU5ODY3MzY1Nzg1NzYzNzU2NzU2Nzg5OTg2MTI3NDM4Njc0Mzg2MzI5ODYyNDM5ODIwOTg0Mzc2MjA5ODM0NzY5MjQzNzYiLAorICAgICAgICAgICAgICAgIDE2KTsKKyAgICAgICAgc21hbGxQb3MgPSBuZXcgQmlnSW50ZWdlcigiNDg3NTMyNjk4NzU5NzMyODQ3NjU4NzQ1OTg2MzA5NjA5ODYyNzYiLCAxNik7CisgICAgICAgIGxhcmdlTmVnID0gbmV3IEJpZ0ludGVnZXIoCisgICAgICAgICAgICAgICAgIi04Nzg4MjQzOTc0MzI2NTE0ODE4OTEzNTMyNDc5ODc4OTE0MjM3Njg1MzQzMjEzODc4NjQzNjExNDM1NDgzNjQ0NTc2OTg0ODcyNjQzODc1Njg3NDM1Njg3NDMyNjU4NzMyNDY1NzY0Njc2NDM3NTY0Mzc2NTc0MzY1ODc0MzYiLAorICAgICAgICAgICAgICAgIDE2KTsKKyAgICAgICAgc21hbGxOZWcgPSBuZXcgQmlnSW50ZWdlcigiLTU2Nzg2MzI1NDM0Mzc5ODYwOTg1NzQ1NjI3MzQ1ODc2OTg0MyIsIDE2KTsKKyAgICAgICAgYm9vbGVhblBhaXJzID0gbmV3IEJpZ0ludGVnZXJbXVtdIHsgeyBsYXJnZVBvcywgc21hbGxQb3MgfSwKKyAgICAgICAgICAgICAgICB7IGxhcmdlUG9zLCBzbWFsbE5lZyB9LCB7IGxhcmdlTmVnLCBzbWFsbFBvcyB9LAorICAgICAgICAgICAgICAgIHsgbGFyZ2VOZWcsIHNtYWxsTmVnIH0gfTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdERpdihCaWdJbnRlZ2VyIGkxLCBCaWdJbnRlZ2VyIGkyKSB7CisgICAgICAgIEJpZ0ludGVnZXIgcSA9IGkxLmRpdmlkZShpMik7CisgICAgICAgIEJpZ0ludGVnZXIgciA9IGkxLnJlbWFpbmRlcihpMik7CisgICAgICAgIEJpZ0ludGVnZXJbXSB0ZW1wID0gaTEuZGl2aWRlQW5kUmVtYWluZGVyKGkyKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJkaXZpZGUgYW5kIGRpdmlkZUFuZFJlbWFpbmRlciBkbyBub3QgYWdyZWUiLCBxCisgICAgICAgICAgICAgICAgLmVxdWFscyh0ZW1wWzBdKSk7CisgICAgICAgIGFzc2VydFRydWUoInJlbWFpbmRlciBhbmQgZGl2aWRlQW5kUmVtYWluZGVyIGRvIG5vdCBhZ3JlZSIsIHIKKyAgICAgICAgICAgICAgICAuZXF1YWxzKHRlbXBbMV0pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgic2lnbnVtIGFuZCBlcXVhbHMoemVybykgZG8gbm90IGFncmVlIG9uIHF1b3RpZW50IiwgcQorICAgICAgICAgICAgICAgIC5zaWdudW0oKSAhPSAwCisgICAgICAgICAgICAgICAgfHwgcS5lcXVhbHMoemVybykpOworICAgICAgICBhc3NlcnRUcnVlKCJzaWdudW0gYW5kIGVxdWFscyh6ZXJvKSBkbyBub3QgYWdyZWUgb24gcmVtYWluZGVyIiwgcgorICAgICAgICAgICAgICAgIC5zaWdudW0oKSAhPSAwCisgICAgICAgICAgICAgICAgfHwgci5lcXVhbHMoemVybykpOworICAgICAgICBhc3NlcnRUcnVlKCJ3cm9uZyBzaWduIG9uIHF1b3RpZW50IiwgcS5zaWdudW0oKSA9PSAwCisgICAgICAgICAgICAgICAgfHwgcS5zaWdudW0oKSA9PSBpMS5zaWdudW0oKSAqIGkyLnNpZ251bSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgid3Jvbmcgc2lnbiBvbiByZW1haW5kZXIiLCByLnNpZ251bSgpID09IDAKKyAgICAgICAgICAgICAgICB8fCByLnNpZ251bSgpID09IGkxLnNpZ251bSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgicmVtYWluZGVyIG91dCBvZiByYW5nZSIsIHIuYWJzKCkuY29tcGFyZVRvKGkyLmFicygpKSA8IDApOworICAgICAgICBhc3NlcnRUcnVlKCJxdW90aWVudCB0b28gc21hbGwiLCBxLmFicygpLmFkZChvbmUpLm11bHRpcGx5KGkyLmFicygpKQorICAgICAgICAgICAgICAgIC5jb21wYXJlVG8oaTEuYWJzKCkpID4gMCk7CisgICAgICAgIGFzc2VydFRydWUoInF1b3RpZW50IHRvbyBsYXJnZSIsIHEuYWJzKCkubXVsdGlwbHkoaTIuYWJzKCkpLmNvbXBhcmVUbygKKyAgICAgICAgICAgICAgICBpMS5hYnMoKSkgPD0gMCk7CisgICAgICAgIEJpZ0ludGVnZXIgcCA9IHEubXVsdGlwbHkoaTIpOworICAgICAgICBCaWdJbnRlZ2VyIGEgPSBwLmFkZChyKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiKGEvYikqYisoYSViKSAhPSBhIiwgYS5lcXVhbHMoaTEpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEJpZ0ludGVnZXIgbW9kID0gaTEubW9kKGkyKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIm1vZCBpcyBuZWdhdGl2ZSIsIG1vZC5zaWdudW0oKSA+PSAwKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIm1vZCBvdXQgb2YgcmFuZ2UiLCBtb2QuYWJzKCkuY29tcGFyZVRvKGkyLmFicygpKSA8IDApOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgicG9zaXRpdmUgcmVtYWluZGVyID09IG1vZCIsIHIuc2lnbnVtKCkgPCAwCisgICAgICAgICAgICAgICAgICAgIHx8IHIuZXF1YWxzKG1vZCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgibmVnYXRpdmUgcmVtYWluZGVyID09IG1vZCAtIGRpdmlzb3IiLCByLnNpZ251bSgpID49IDAKKyAgICAgICAgICAgICAgICAgICAgfHwgci5lcXVhbHMobW9kLnN1YnRyYWN0KGkyKSkpOworICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIm1vZCBmYWlscyBvbiBuZWdhdGl2ZSBkaXZpc29yIG9ubHkiLCBpMi5zaWdudW0oKSA8PSAwKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0RGl2UmFuZ2VzKEJpZ0ludGVnZXIgaSkgeworICAgICAgICBCaWdJbnRlZ2VyIGJvdW5kID0gaS5tdWx0aXBseSh0d28pOworICAgICAgICBmb3IgKEJpZ0ludGVnZXIgaiA9IGJvdW5kLm5lZ2F0ZSgpOyBqLmNvbXBhcmVUbyhib3VuZCkgPD0gMDsgaiA9IGoKKyAgICAgICAgICAgICAgICAuYWRkKGkpKSB7CisgICAgICAgICAgICBCaWdJbnRlZ2VyIGlubmVyYm91bmQgPSBqLmFkZCh0d28pOworICAgICAgICAgICAgQmlnSW50ZWdlciBrID0gai5zdWJ0cmFjdCh0d28pOworICAgICAgICAgICAgZm9yICg7IGsuY29tcGFyZVRvKGlubmVyYm91bmQpIDw9IDA7IGsgPSBrLmFkZChvbmUpKSB7CisgICAgICAgICAgICAgICAgdGVzdERpdihrLCBpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBpc1ByaW1lKGxvbmcgYikgeworICAgICAgICBpZiAoYiA9PSAyKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICAvLyBjaGVjayBmb3IgZGl2IGJ5IDIKKyAgICAgICAgaWYgKChiICYgMUwpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBsb25nIG1heGxlbiA9ICgobG9uZykgTWF0aC5zcXJ0KGIpKSArIDI7CisgICAgICAgIGZvciAobG9uZyB4ID0gMzsgeCA8IG1heGxlbjsgeCArPSAyKSB7CisgICAgICAgICAgICBpZiAoYiAlIHggPT0gMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdEFsbE11bHRzKEJpZ0ludGVnZXIgaTEsIEJpZ0ludGVnZXIgaTIsIEJpZ0ludGVnZXIgYW5zKSB7CisgICAgICAgIGFzc2VydFRydWUoImkxKmkyPWFucyIsIGkxLm11bHRpcGx5KGkyKS5lcXVhbHMoYW5zKSk7CisgICAgICAgIGFzc2VydFRydWUoImkyKmkxPWFucyIsIGkyLm11bHRpcGx5KGkxKS5lcXVhbHMoYW5zKSk7CisgICAgICAgIGFzc2VydFRydWUoIi1pMSppMj0tYW5zIiwgaTEubmVnYXRlKCkubXVsdGlwbHkoaTIpLmVxdWFscyhhbnMubmVnYXRlKCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiLWkyKmkxPS1hbnMiLCBpMi5uZWdhdGUoKS5tdWx0aXBseShpMSkuZXF1YWxzKGFucy5uZWdhdGUoKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJpMSotaTI9LWFucyIsIGkxLm11bHRpcGx5KGkyLm5lZ2F0ZSgpKS5lcXVhbHMoYW5zLm5lZ2F0ZSgpKSk7CisgICAgICAgIGFzc2VydFRydWUoImkyKi1pMT0tYW5zIiwgaTIubXVsdGlwbHkoaTEubmVnYXRlKCkpLmVxdWFscyhhbnMubmVnYXRlKCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiLWkxKi1pMj1hbnMiLCBpMS5uZWdhdGUoKS5tdWx0aXBseShpMi5uZWdhdGUoKSkuZXF1YWxzKGFucykpOworICAgICAgICBhc3NlcnRUcnVlKCItaTIqLWkxPWFucyIsIGkyLm5lZ2F0ZSgpLm11bHRpcGx5KGkxLm5lZ2F0ZSgpKS5lcXVhbHMoYW5zKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RBbGxEaXZzKEJpZ0ludGVnZXIgaTEsIEJpZ0ludGVnZXIgaTIpIHsKKyAgICAgICAgdGVzdERpdihpMSwgaTIpOworICAgICAgICB0ZXN0RGl2KGkxLm5lZ2F0ZSgpLCBpMik7CisgICAgICAgIHRlc3REaXYoaTEsIGkyLm5lZ2F0ZSgpKTsKKyAgICAgICAgdGVzdERpdihpMS5uZWdhdGUoKSwgaTIubmVnYXRlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9tYXRoL01hdGhDb250ZXh0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL21hdGgvTWF0aENvbnRleHRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWUwNDM0MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9tYXRoL01hdGhDb250ZXh0VGVzdC5qYXZhCkBAIC0wLDAgKzEsNzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEubWF0aDsKKworaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOworaW1wb3J0IGphdmEubWF0aC5NYXRoQ29udGV4dDsKK2ltcG9ydCBqYXZhLm1hdGguUm91bmRpbmdNb2RlOworCitwdWJsaWMgY2xhc3MgTWF0aENvbnRleHRUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5NYXRoQ29udGV4dCNNYXRoQ29udGV4dCguLi4pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9NYXRoQ29udGV4dENvbnN0cnVjdGlvbigpIHsKKyAgICAgICAgU3RyaW5nIGEgPSAiLTEyMzgwOTQ1RSs2MSI7CisgICAgICAgIEJpZ0RlY2ltYWwgYU51bWJlciA9IG5ldyBCaWdEZWNpbWFsKGEpOworICAgICAgICBNYXRoQ29udGV4dCBtY0ludFJtNmhkID0gbmV3IE1hdGhDb250ZXh0KDYsIFJvdW5kaW5nTW9kZS5IQUxGX0RPV04pOworICAgICAgICBNYXRoQ29udGV4dCBtY1N0cjZoZCA9IG5ldyBNYXRoQ29udGV4dCgicHJlY2lzaW9uPTYgcm91bmRpbmdNb2RlPUhBTEZfRE9XTiIpOworICAgICAgICBNYXRoQ29udGV4dCBtY0ludDYgPSBuZXcgTWF0aENvbnRleHQoNik7CisgICAgICAgIE1hdGhDb250ZXh0IG1jSW50MTM0ID0gbmV3IE1hdGhDb250ZXh0KDEzNCk7CisKKyAgICAgICAgLy8gZ2V0UHJlY2lzaW9uKCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJNYXRoQ29udGV4dC5nZXRQcmVjaXNpb24oKSByZXR1cm5zIGluY29ycmVjdCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgNiwgbWNJbnRSbTZoZC5nZXRQcmVjaXNpb24oKSApOworICAgICAgICBhc3NlcnRFcXVhbHMoIk1hdGhDb250ZXh0LmdldFByZWNpc2lvbigpIHJldHVybnMgaW5jb3JyZWN0IHZhbHVlIiwKKyAgICAgICAgICAgICAgICAxMzQsIG1jSW50MTM0LmdldFByZWNpc2lvbigpICk7CisKKyAgICAgICAgLy8gZ2V0Um91bmRpbmdNb2RlKCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJNYXRoQ29udGV4dC5nZXRSb3VuZGluZ01vZGUoKSByZXR1cm5zIGluY29ycmVjdCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgUm91bmRpbmdNb2RlLkhBTEZfVVAsCisgICAgICAgICAgICAgICAgbWNJbnQ2LmdldFJvdW5kaW5nTW9kZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJNYXRoQ29udGV4dC5nZXRSb3VuZGluZ01vZGUoKSByZXR1cm5zIGluY29ycmVjdCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgUm91bmRpbmdNb2RlLkhBTEZfRE9XTiwgbWNJbnRSbTZoZC5nZXRSb3VuZGluZ01vZGUoKSApOworCisgICAgICAgIC8vIHRvU3RyaW5nKCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJNYXRoQ29udGV4dC50b1N0cmluZygpIHJldHVybmluZyBpbmNvcnJlY3QgdmFsdWUiLAorICAgICAgICAgICAgICAgICJwcmVjaXNpb249NiByb3VuZGluZ01vZGU9SEFMRl9ET1dOIiwgbWNJbnRSbTZoZC50b1N0cmluZygpICk7CisgICAgICAgIGFzc2VydEVxdWFscygiTWF0aENvbnRleHQudG9TdHJpbmcoKSByZXR1cm5pbmcgaW5jb3JyZWN0IHZhbHVlIiwKKyAgICAgICAgICAgICAgICAicHJlY2lzaW9uPTYgcm91bmRpbmdNb2RlPUhBTEZfVVAiLCBtY0ludDYudG9TdHJpbmcoKSApOworCisgICAgICAgIC8vIGVxdWFscyguKQorICAgICAgICBhc3NlcnRFcXVhbHMoIkVxdWFsIE1hdGhDb250ZXh0cyBhcmUgbm90IGVxdWFsICIsCisgICAgICAgICAgICAgICAgbWNJbnRSbTZoZCwgbWNTdHI2aGQgKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkRpZmZlcmVudCBNYXRoQ29udGV4dHMgYXJlIHJlcG9ydGVkIGFzIGVxdWFsICIsCisgICAgICAgICAgICAgICAgbWNJbnQ2LmVxdWFscyhtY1N0cjZoZCkgKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkRpZmZlcmVudCBNYXRoQ29udGV4dHMgYXJlIHJlcG9ydGVkIGFzIGVxdWFsICIsCisgICAgICAgICAgICAgICAgbWNJbnQ2LmVxdWFscyhtY0ludDEzNCkgKTsKKworICAgICAgICAvLyBoYXNoQ29kZSguKQorICAgICAgICBhc3NlcnRFcXVhbHMoIkVxdWFsIE1hdGhDb250ZXh0cyBoYXZlIGRpZmZlcmVudCBoYXNoY29kZXMgIiwKKyAgICAgICAgICAgICAgICBtY0ludFJtNmhkLmhhc2hDb2RlKCksIG1jU3RyNmhkLmhhc2hDb2RlKCkgKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkRpZmZlcmVudCBNYXRoQ29udGV4dHMgaGF2ZSBlcXVhbCBoYXNoY29kZXMgIiwKKyAgICAgICAgICAgICAgICBtY0ludDYuaGFzaENvZGUoKSA9PSBtY1N0cjZoZC5oYXNoQ29kZSgpICk7CisgICAgICAgIGFzc2VydEZhbHNlKCJEaWZmZXJlbnQgTWF0aENvbnRleHRzIGhhdmUgZXF1YWwgaGFzaGNvZGVzICIsCisgICAgICAgICAgICAgICAgbWNJbnQ2Lmhhc2hDb2RlKCkgPT0gbWNJbnQxMzQuaGFzaENvZGUoKSApOworCisgICAgICAgIC8vIG90aGVyOgorICAgICAgICBCaWdEZWNpbWFsIHJlcyA9IGFOdW1iZXIuYWJzKG1jSW50Nik7CisgICAgICAgIGFzc2VydEVxdWFscygiTWF0aENvbnRleHQgQ29uc3RydWN0b3Igd2l0aCBpbnQgcHJlY2lzaW9uIGZhaWxlZCIsCisgICAgICAgICAgICAgICAgbmV3IEJpZ0RlY2ltYWwoIjEuMjM4MDlFKzY4IiksCisgICAgICAgICAgICAgICAgcmVzKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9tYXRoL1JvdW5kaW5nTW9kZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS9tYXRoL1JvdW5kaW5nTW9kZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MGE3N2RmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL21hdGgvUm91bmRpbmdNb2RlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEubWF0aDsKKworaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOworaW1wb3J0IGphdmEubWF0aC5Sb3VuZGluZ01vZGU7CisKK3B1YmxpYyBjbGFzcyBSb3VuZGluZ01vZGVUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmEubWF0aC5Sb3VuZGluZ01vZGUjdmFsdWVPZihpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF92YWx1ZU9mSSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZU9mIGZhaWxlZCBmb3IgUk9VTkRfQ0VJTElORyIsIFJvdW5kaW5nTW9kZS52YWx1ZU9mKEJpZ0RlY2ltYWwuUk9VTkRfQ0VJTElORyksIFJvdW5kaW5nTW9kZS5DRUlMSU5HKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZU9mIGZhaWxlZCBmb3IgUk9VTkRfRE9XTiIsIFJvdW5kaW5nTW9kZS52YWx1ZU9mKEJpZ0RlY2ltYWwuUk9VTkRfRE9XTiksIFJvdW5kaW5nTW9kZS5ET1dOKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZU9mIGZhaWxlZCBmb3IgUk9VTkRfRkxPT1IiLCBSb3VuZGluZ01vZGUudmFsdWVPZihCaWdEZWNpbWFsLlJPVU5EX0ZMT09SKSwgUm91bmRpbmdNb2RlLkZMT09SKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZU9mIGZhaWxlZCBmb3IgUk9VTkRfSEFMRl9ET1dOIiwgUm91bmRpbmdNb2RlLnZhbHVlT2YoQmlnRGVjaW1hbC5ST1VORF9IQUxGX0RPV04pLCBSb3VuZGluZ01vZGUuSEFMRl9ET1dOKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZU9mIGZhaWxlZCBmb3IgUk9VTkRfSEFMRl9FVkVOIiwgUm91bmRpbmdNb2RlLnZhbHVlT2YoQmlnRGVjaW1hbC5ST1VORF9IQUxGX0VWRU4pLCBSb3VuZGluZ01vZGUuSEFMRl9FVkVOKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZU9mIGZhaWxlZCBmb3IgUk9VTkRfSEFMRl9VUCIsIFJvdW5kaW5nTW9kZS52YWx1ZU9mKEJpZ0RlY2ltYWwuUk9VTkRfSEFMRl9VUCksIFJvdW5kaW5nTW9kZS5IQUxGX1VQKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZU9mIGZhaWxlZCBmb3IgUk9VTkRfVU5ORUNFU1NBUlkiLCBSb3VuZGluZ01vZGUudmFsdWVPZihCaWdEZWNpbWFsLlJPVU5EX1VOTkVDRVNTQVJZKSwgUm91bmRpbmdNb2RlLlVOTkVDRVNTQVJZKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZU9mIGZhaWxlZCBmb3IgUk9VTkRfVVAiLCBSb3VuZGluZ01vZGUudmFsdWVPZihCaWdEZWNpbWFsLlJPVU5EX1VQKSwgUm91bmRpbmdNb2RlLlVQKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJvdW5kaW5nTW9kZS52YWx1ZU9mKDEzKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCBmb3IgUm91bmRpbmdNb2RlKDEzKSIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSb3VuZGluZ01vZGUudmFsdWVPZigtMSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQgZm9yIFJvdW5kaW5nTW9kZSgtMSkiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQWJzdHJhY3RMaXN0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQWJzdHJhY3RMaXN0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNjZGEzMGYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9BYnN0cmFjdExpc3RUZXN0LmphdmEKQEAgLTAsMCArMSwyOTMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdExpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdEl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5SYW5kb21BY2Nlc3M7CisKK3B1YmxpYyBjbGFzcyBBYnN0cmFjdExpc3RUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBjbGFzcyBTaW1wbGVMaXN0IGV4dGVuZHMgQWJzdHJhY3RMaXN0IHsKKyAgICAgICAgQXJyYXlMaXN0IGFycmF5TGlzdDsKKworICAgICAgICBTaW1wbGVMaXN0KCkgeworICAgICAgICAgICAgdGhpcy5hcnJheUxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IGdldChpbnQgaW5kZXgpIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzLmFycmF5TGlzdC5nZXQoaW5kZXgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgYWRkKGludCBpLCBPYmplY3QgbykgeworICAgICAgICAgICAgdGhpcy5hcnJheUxpc3QuYWRkKGksIG8pOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCByZW1vdmUoaW50IGkpIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzLmFycmF5TGlzdC5yZW1vdmUoaSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpcy5hcnJheUxpc3Quc2l6ZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFic3RyYWN0TGlzdCNoYXNoQ29kZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSgpIHsKKworICAgICAgICBMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGxpc3QuYWRkKG5ldyBJbnRlZ2VyKDMpKTsKKyAgICAgICAgbGlzdC5hZGQobmV3IEludGVnZXIoMTUpKTsKKyAgICAgICAgbGlzdC5hZGQobmV3IEludGVnZXIoNSkpOworICAgICAgICBsaXN0LmFkZChuZXcgSW50ZWdlcigxKSk7CisgICAgICAgIGxpc3QuYWRkKG5ldyBJbnRlZ2VyKDcpKTsKKyAgICAgICAgaW50IGhhc2hDb2RlID0gMTsKKyAgICAgICAgSXRlcmF0b3IgaSA9IGxpc3QuaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGkuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBPYmplY3Qgb2JqID0gaS5uZXh0KCk7CisgICAgICAgICAgICBoYXNoQ29kZSA9IDMxICogaGFzaENvZGUgKyAob2JqID09IG51bGwgPyAwIDogb2JqLmhhc2hDb2RlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBoYXNoQ29kZSByZXR1cm5lZC4gIFdhbnRlZDogIiArIGhhc2hDb2RlCisgICAgICAgICAgICAgICAgKyAiIGdvdDogIiArIGxpc3QuaGFzaENvZGUoKSwgaGFzaENvZGUgPT0gbGlzdC5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQWJzdHJhY3RMaXN0I2l0ZXJhdG9yKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2l0ZXJhdG9yKCkgeworICAgICAgICBTaW1wbGVMaXN0IGxpc3QgPSBuZXcgU2ltcGxlTGlzdCgpOworICAgICAgICBsaXN0LmFkZChuZXcgT2JqZWN0KCkpOworICAgICAgICBsaXN0LmFkZChuZXcgT2JqZWN0KCkpOworICAgICAgICBJdGVyYXRvciBpdCA9IGxpc3QuaXRlcmF0b3IoKTsKKyAgICAgICAgaXQubmV4dCgpOworICAgICAgICBpdC5yZW1vdmUoKTsKKyAgICAgICAgaXQubmV4dCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BYnN0cmFjdExpc3QjbGlzdEl0ZXJhdG9yKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xpc3RJdGVyYXRvcigpIHsKKyAgICAgICAgSW50ZWdlciB0ZW1wVmFsdWU7CisgICAgICAgIExpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgbGlzdC5hZGQobmV3IEludGVnZXIoMykpOworICAgICAgICBsaXN0LmFkZChuZXcgSW50ZWdlcigxNSkpOworICAgICAgICBsaXN0LmFkZChuZXcgSW50ZWdlcig1KSk7CisgICAgICAgIGxpc3QuYWRkKG5ldyBJbnRlZ2VyKDEpKTsKKyAgICAgICAgbGlzdC5hZGQobmV3IEludGVnZXIoNykpOworICAgICAgICBMaXN0SXRlcmF0b3IgbGl0ID0gbGlzdC5saXN0SXRlcmF0b3IoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIG5vdCBoYXZlIHByZXZpb3VzIiwgIWxpdC5oYXNQcmV2aW91cygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGhhdmUgbmV4dCIsIGxpdC5oYXNOZXh0KCkpOworICAgICAgICB0ZW1wVmFsdWUgPSAoSW50ZWdlcikgbGl0Lm5leHQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibmV4dCByZXR1cm5lZCB3cm9uZyB2YWx1ZS4gIFdhbnRlZCAzLCBnb3Q6ICIgKyB0ZW1wVmFsdWUsCisgICAgICAgICAgICAgICAgdGVtcFZhbHVlLmludFZhbHVlKCkgPT0gMyk7CisgICAgICAgIHRlbXBWYWx1ZSA9IChJbnRlZ2VyKSBsaXQucHJldmlvdXMoKTsKKworICAgICAgICBTaW1wbGVMaXN0IGxpc3QyID0gbmV3IFNpbXBsZUxpc3QoKTsKKyAgICAgICAgbGlzdDIuYWRkKG5ldyBPYmplY3QoKSk7CisgICAgICAgIExpc3RJdGVyYXRvciBsaXQyID0gbGlzdDIubGlzdEl0ZXJhdG9yKCk7CisgICAgICAgIGxpdDIuYWRkKG5ldyBPYmplY3QoKSk7CisgICAgICAgIGxpdDIubmV4dCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BYnN0cmFjdExpc3Qjc3ViTGlzdChpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1Ykxpc3RJSSgpIHsKKyAgICAgICAgLy8gVGVzdCBlYWNoIG9mIHRoZSBTdWJMaXN0IG9wZXJhdGlvbnMgdG8gZW5zdXJlIGEKKyAgICAgICAgLy8gQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbiBkb2VzIG5vdCBvY2N1ciBvbiBhbiBBYnN0cmFjdExpc3QKKyAgICAgICAgLy8gd2hpY2ggZG9lcyBub3QgdXBkYXRlIG1vZENvdW50CisgICAgICAgIFNpbXBsZUxpc3QgbUxpc3QgPSBuZXcgU2ltcGxlTGlzdCgpOworICAgICAgICBtTGlzdC5hZGQobmV3IE9iamVjdCgpKTsKKyAgICAgICAgbUxpc3QuYWRkKG5ldyBPYmplY3QoKSk7CisgICAgICAgIExpc3Qgc0xpc3QgPSBtTGlzdC5zdWJMaXN0KDAsIDIpOworICAgICAgICBzTGlzdC5hZGQobmV3IE9iamVjdCgpKTsgLy8gY2FsbHMgYWRkKGludCwgT2JqZWN0KQorICAgICAgICBzTGlzdC5nZXQoMCk7CisKKyAgICAgICAgc0xpc3QuYWRkKDAsIG5ldyBPYmplY3QoKSk7CisgICAgICAgIHNMaXN0LmdldCgwKTsKKworICAgICAgICBzTGlzdC5hZGRBbGwoQXJyYXlzLmFzTGlzdChuZXcgU3RyaW5nW10geyAiMSIsICIyIiB9KSk7CisgICAgICAgIHNMaXN0LmdldCgwKTsKKworICAgICAgICBzTGlzdC5hZGRBbGwoMCwgQXJyYXlzLmFzTGlzdChuZXcgU3RyaW5nW10geyAiMyIsICI0IiB9KSk7CisgICAgICAgIHNMaXN0LmdldCgwKTsKKworICAgICAgICBzTGlzdC5yZW1vdmUoMCk7CisgICAgICAgIHNMaXN0LmdldCgwKTsKKworICAgICAgICBMaXN0SXRlcmF0b3IgbGl0ID0gc0xpc3QubGlzdEl0ZXJhdG9yKCk7CisgICAgICAgIGxpdC5hZGQobmV3IE9iamVjdCgpKTsKKyAgICAgICAgbGl0Lm5leHQoKTsKKyAgICAgICAgbGl0LnJlbW92ZSgpOworICAgICAgICBsaXQubmV4dCgpOworCisgICAgICAgIHNMaXN0LmNsZWFyKCk7IC8vIGNhbGxzIHJlbW92ZVJhbmdlKCkKKyAgICAgICAgc0xpc3QuYWRkKG5ldyBPYmplY3QoKSk7CisKKyAgICAgICAgLy8gdGVzdCB0aGUgdHlwZSBvZiBzdWJsaXN0IHRoYXQgaXMgcmV0dXJuZWQKKyAgICAgICAgTGlzdCBhbCA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgICAgICAgICBhbC5hZGQobmV3IEludGVnZXIoaSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIlN1Ymxpc3QgcmV0dXJuZWQgc2hvdWxkIGhhdmUgaW1wbGVtZW50ZWQgUmFuZG9tIEFjY2VzcyBpbnRlcmZhY2UiLAorICAgICAgICAgICAgICAgIGFsLnN1Ykxpc3QoMywgNykgaW5zdGFuY2VvZiBSYW5kb21BY2Nlc3MpOworCisgICAgICAgIExpc3QgbGwgPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICAgICAgICAgIGxsLmFkZChuZXcgSW50ZWdlcihpKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiU3VibGlzdCByZXR1cm5lZCBzaG91bGQgbm90IGhhdmUgaW1wbGVtZW50ZWQgUmFuZG9tIEFjY2VzcyBpbnRlcmZhY2UiLAorICAgICAgICAgICAgICAgICEobGwuc3ViTGlzdCgzLCA3KSBpbnN0YW5jZW9mIFJhbmRvbUFjY2VzcykpOworCisgICAgICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BYnN0cmFjdExpc3Qjc3ViTGlzdChpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1Ykxpc3RfZW1wdHkoKSB7CisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMzg5CisgICAgICAgIExpc3QgYWwgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGFsLmFkZCgib25lIik7CisgICAgICAgIExpc3QgZW1wdHlTdWJMaXN0ID0gYWwuc3ViTGlzdCgwLCAwKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW1wdHlTdWJMaXN0LmdldCgwKTsKKyAgICAgICAgICAgIGZhaWwoImVtcHR5U3ViTGlzdC5nZXQoMCkgc2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVtcHR5U3ViTGlzdC5zZXQoMCwgIm9uZSIpOworICAgICAgICAgICAgZmFpbCgiZW1wdHlTdWJMaXN0LnNldCgwLE9iamVjdCkgc2hvdWxkIHRocm93IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVtcHR5U3ViTGlzdC5yZW1vdmUoMCk7CisgICAgICAgICAgICBmYWlsKCJlbXB0eVN1Ykxpc3QucmVtb3ZlKDApIHNob3VsZCB0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BYnN0cmFjdExpc3Qjc3ViTGlzdChpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1Ykxpc3RfYWRkQWxsKCkgeworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTM5MAorICAgICAgICBMaXN0IG1haW5MaXN0ID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBPYmplY3RbXSBtYWluT2JqZWN0cyA9IHsgImEiLCAiYiIsICJjIiB9OworICAgICAgICBtYWluTGlzdC5hZGRBbGwoQXJyYXlzLmFzTGlzdChtYWluT2JqZWN0cykpOworICAgICAgICBMaXN0IHN1Ykxpc3QgPSBtYWluTGlzdC5zdWJMaXN0KDEsIDIpOworICAgICAgICBhc3NlcnRGYWxzZSgic3ViTGlzdCBzaG91bGQgbm90IGNvbnRhaW4gXCJhXCIiLCBzdWJMaXN0LmNvbnRhaW5zKCJhIikpOworICAgICAgICBhc3NlcnRGYWxzZSgic3ViTGlzdCBzaG91bGQgbm90IGNvbnRhaW4gXCJjXCIiLCBzdWJMaXN0LmNvbnRhaW5zKCJjIikpOworICAgICAgICBhc3NlcnRUcnVlKCJzdWJMaXN0IHNob3VsZCBjb250YWluIFwiYlwiIiwgc3ViTGlzdC5jb250YWlucygiYiIpKTsKKworICAgICAgICBPYmplY3RbXSBzdWJPYmplY3RzID0geyAib25lIiwgInR3byIsICJ0aHJlZSIgfTsKKyAgICAgICAgc3ViTGlzdC5hZGRBbGwoQXJyYXlzLmFzTGlzdChzdWJPYmplY3RzKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJzdWJMaXN0IHNob3VsZCBub3QgY29udGFpbiBcImFcIiIsIHN1Ykxpc3QuY29udGFpbnMoImEiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJzdWJMaXN0IHNob3VsZCBub3QgY29udGFpbiBcImNcIiIsIHN1Ykxpc3QuY29udGFpbnMoImMiKSk7CisKKyAgICAgICAgT2JqZWN0W10gZXhwZWN0ZWQgPSB7ICJiIiwgIm9uZSIsICJ0d28iLCAidGhyZWUiIH07CisgICAgICAgIExpc3RJdGVyYXRvciBpdGVyID0gc3ViTGlzdC5saXN0SXRlcmF0b3IoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHBlY3RlZC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgic3ViTGlzdCBzaG91bGQgY29udGFpbiAiICsgZXhwZWN0ZWRbaV0sIHN1Ykxpc3QKKyAgICAgICAgICAgICAgICAgICAgLmNvbnRhaW5zKGV4cGVjdGVkW2ldKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJzaG91bGQgYmUgbW9yZSBlbGVtZW50cyIsIGl0ZXIuaGFzTmV4dCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZWxlbWVudCBpbiBpbmNvcnJlY3QgcG9zaXRpb24iLCBleHBlY3RlZFtpXSwgaXRlcgorICAgICAgICAgICAgICAgICAgICAubmV4dCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5kZXhPZkxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICBBYnN0cmFjdExpc3QgYWwgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGFsLmFkZCgwKTsKKyAgICAgICAgYWwuYWRkKDEpOworICAgICAgICBhbC5hZGQoMik7CisgICAgICAgIGFsLmFkZCgzKTsKKyAgICAgICAgYWwuYWRkKDQpOworCisgICAgICAgIGFzc2VydEVxdWFscygtMSwgYWwuaW5kZXhPZig1KSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBhbC5pbmRleE9mKDIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xhc3RJbmRleE9mTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIEFic3RyYWN0TGlzdCBhbCA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgYWwuYWRkKDApOworICAgICAgICBhbC5hZGQoMSk7CisgICAgICAgIGFsLmFkZCgyKTsKKyAgICAgICAgYWwuYWRkKDIpOworICAgICAgICBhbC5hZGQoMik7CisgICAgICAgIGFsLmFkZCgyKTsKKyAgICAgICAgYWwuYWRkKDIpOworICAgICAgICBhbC5hZGQoMyk7CisgICAgICAgIGFsLmFkZCg0KTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGFsLmxhc3RJbmRleE9mKDUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDYsIGFsLmxhc3RJbmRleE9mKDIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xpc3RJdGVyYXRvckkoKSB7CisgICAgICAgIEFic3RyYWN0TGlzdCBhbDEgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIEFic3RyYWN0TGlzdCBhbDIgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGFsMS5hZGQoMCk7CisgICAgICAgIGFsMS5hZGQoMSk7CisgICAgICAgIGFsMS5hZGQoMik7CisgICAgICAgIGFsMS5hZGQoMyk7CisgICAgICAgIGFsMS5hZGQoNCk7CisgICAgICAgIGFsMi5hZGQoMik7CisgICAgICAgIGFsMi5hZGQoMyk7CisgICAgICAgIGFsMi5hZGQoNCk7CisKKyAgICAgICAgSXRlcmF0b3IgbGkxID0gYWwxLmxpc3RJdGVyYXRvcigyKTsKKyAgICAgICAgSXRlcmF0b3IgbGkyID0gYWwyLmxpc3RJdGVyYXRvcigpOworCisgICAgICAgIHdoaWxlKGxpMS5oYXNOZXh0KCkmJmxpMi5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhsaTEubmV4dCgpLCBsaTIubmV4dCgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRTYW1lKGxpMS5oYXNOZXh0KCksbGkyLmhhc05leHQoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFsMS5saXN0SXRlcmF0b3IoLTEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWwxLmxpc3RJdGVyYXRvcihhbDEuc2l6ZSgpICsgMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGRvbmVTdWl0ZSgpIHt9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9BYnN0cmFjdE1hcFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0Fic3RyYWN0TWFwVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4ZjljZTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9BYnN0cmFjdE1hcFRlc3QuamF2YQpAQCAtMCwwICsxLDMyNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkFic3RyYWN0TWFwOworaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKK2ltcG9ydCBqYXZhLnV0aWwuV2Vha0hhc2hNYXA7CisKK3B1YmxpYyBjbGFzcyBBYnN0cmFjdE1hcFRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBzcGVjaWFsS2V5ID0gInNwZWNpYWxLZXkiLmludGVybigpOworCisgICAgc3RhdGljIGZpbmFsIFN0cmluZyBzcGVjaWFsVmFsdWUgPSAic3BlY2lhbFZhbHVlIi5pbnRlcm4oKTsKKworICAgIC8vIFRoZSBpbXBsIG9mIE15TWFwIGlzIG5vdCByZWFsaXN0aWMsIGJ1dCBzZXJ2ZXMgdG8gY3JlYXRlIGEgdHlwZQorICAgIC8vIHRoYXQgdXNlcyB0aGUgZGVmYXVsdCByZW1vdmUgYmVoYXZpb3IuCisgICAgY2xhc3MgTXlNYXAgZXh0ZW5kcyBBYnN0cmFjdE1hcCB7CisgICAgICAgIGZpbmFsIFNldCBteVNldCA9IG5ldyBIYXNoU2V0KDEpOworCisgICAgICAgIE15TWFwKCkgeworICAgICAgICAgICAgbXlTZXQuYWRkKG5ldyBNYXAuRW50cnkoKSB7CisgICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBnZXRLZXkoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBzcGVjaWFsS2V5OworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0VmFsdWUoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBzcGVjaWFsVmFsdWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBzZXRWYWx1ZShPYmplY3Qgb2JqZWN0KSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBwdXQoT2JqZWN0IGtleSwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTZXQgZW50cnlTZXQoKSB7CisgICAgICAgICAgICByZXR1cm4gbXlTZXQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQWJzdHJhY3RNYXAja2V5U2V0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2tleVNldCgpIHsKKyAgICAgICAgQWJzdHJhY3RNYXAgbWFwMSA9IG5ldyBIYXNoTWFwKDApOworICAgICAgICBhc3NlcnRTYW1lKCJIYXNoTWFwKDApIiwgbWFwMS5rZXlTZXQoKSwgbWFwMS5rZXlTZXQoKSk7CisKKyAgICAgICAgQWJzdHJhY3RNYXAgbWFwMiA9IG5ldyBIYXNoTWFwKDEwKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiSGFzaE1hcCgxMCkiLCBtYXAyLmtleVNldCgpLCBtYXAyLmtleVNldCgpKTsKKworICAgICAgICBNYXAgbWFwMyA9IENvbGxlY3Rpb25zLkVNUFRZX01BUDsKKyAgICAgICAgYXNzZXJ0U2FtZSgiRU1QVFlfTUFQIiwgbWFwMy5rZXlTZXQoKSwgbWFwMy5rZXlTZXQoKSk7CisKKyAgICAgICAgQWJzdHJhY3RNYXAgbWFwNCA9IG5ldyBJZGVudGl0eUhhc2hNYXAoMSk7CisgICAgICAgIGFzc2VydFNhbWUoIklkZW50aXR5SGFzaE1hcCIsIG1hcDQua2V5U2V0KCksIG1hcDQua2V5U2V0KCkpOworCisgICAgICAgIEFic3RyYWN0TWFwIG1hcDUgPSBuZXcgTGlua2VkSGFzaE1hcCgxMjIpOworICAgICAgICBhc3NlcnRTYW1lKCJMaW5rZWRIYXNoTWFwIiwgbWFwNS5rZXlTZXQoKSwgbWFwNS5rZXlTZXQoKSk7CisKKyAgICAgICAgQWJzdHJhY3RNYXAgbWFwNiA9IG5ldyBUcmVlTWFwKCk7CisgICAgICAgIGFzc2VydFNhbWUoIlRyZWVNYXAiLCBtYXA2LmtleVNldCgpLCBtYXA2LmtleVNldCgpKTsKKworICAgICAgICBBYnN0cmFjdE1hcCBtYXA3ID0gbmV3IFdlYWtIYXNoTWFwKCk7CisgICAgICAgIGFzc2VydFNhbWUoIldlYWtIYXNoTWFwIiwgbWFwNy5rZXlTZXQoKSwgbWFwNy5rZXlTZXQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFic3RyYWN0TWFwI3JlbW92ZShqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIE9iamVjdCBrZXkgPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIE9iamVjdCB2YWx1ZSA9IG5ldyBPYmplY3QoKTsKKworICAgICAgICBBYnN0cmFjdE1hcCBtYXAxID0gbmV3IEhhc2hNYXAoMCk7CisgICAgICAgIG1hcDEucHV0KCJrZXkiLCB2YWx1ZSk7CisgICAgICAgIGFzc2VydFNhbWUoIkhhc2hNYXAoMCkiLCBtYXAxLnJlbW92ZSgia2V5IiksIHZhbHVlKTsKKworICAgICAgICBBYnN0cmFjdE1hcCBtYXA0ID0gbmV3IElkZW50aXR5SGFzaE1hcCgxKTsKKyAgICAgICAgbWFwNC5wdXQoa2V5LCB2YWx1ZSk7CisgICAgICAgIGFzc2VydFNhbWUoIklkZW50aXR5SGFzaE1hcCIsIG1hcDQucmVtb3ZlKGtleSksIHZhbHVlKTsKKworICAgICAgICBBYnN0cmFjdE1hcCBtYXA1ID0gbmV3IExpbmtlZEhhc2hNYXAoMTIyKTsKKyAgICAgICAgbWFwNS5wdXQoa2V5LCB2YWx1ZSk7CisgICAgICAgIGFzc2VydFNhbWUoIkxpbmtlZEhhc2hNYXAiLCBtYXA1LnJlbW92ZShrZXkpLCB2YWx1ZSk7CisKKyAgICAgICAgQWJzdHJhY3RNYXAgbWFwNiA9IG5ldyBUcmVlTWFwKG5ldyBDb21wYXJhdG9yKCkgeworICAgICAgICAgICAgLy8gQm9ndXMgY29tcGFyYXRvcgorICAgICAgICAgICAgcHVibGljIGludCBjb21wYXJlKE9iamVjdCBvYmplY3QxLCBPYmplY3Qgb2JqZWN0MikgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAgICAgbWFwNi5wdXQoa2V5LCB2YWx1ZSk7CisgICAgICAgIGFzc2VydFNhbWUoIlRyZWVNYXAiLCBtYXA2LnJlbW92ZShrZXkpLCB2YWx1ZSk7CisKKyAgICAgICAgQWJzdHJhY3RNYXAgbWFwNyA9IG5ldyBXZWFrSGFzaE1hcCgpOworICAgICAgICBtYXA3LnB1dChrZXksIHZhbHVlKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiV2Vha0hhc2hNYXAiLCBtYXA3LnJlbW92ZShrZXkpLCB2YWx1ZSk7CisKKyAgICAgICAgQWJzdHJhY3RNYXAgYVNwZWNpYWxNYXAgPSBuZXcgTXlNYXAoKTsKKyAgICAgICAgYVNwZWNpYWxNYXAucHV0KHNwZWNpYWxLZXksIHNwZWNpYWxWYWx1ZSk7CisgICAgICAgIE9iamVjdCB2YWx1ZU91dCA9IGFTcGVjaWFsTWFwLnJlbW92ZShzcGVjaWFsS2V5KTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiTXlNYXAiLCB2YWx1ZU91dCwgc3BlY2lhbFZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQWJzdHJhY3RNYXAjdmFsdWVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3ZhbHVlcygpIHsKKyAgICAgICAgQWJzdHJhY3RNYXAgbWFwMSA9IG5ldyBIYXNoTWFwKDApOworICAgICAgICBhc3NlcnRTYW1lKCJIYXNoTWFwKDApIiwgbWFwMS52YWx1ZXMoKSwgbWFwMS52YWx1ZXMoKSk7CisKKyAgICAgICAgQWJzdHJhY3RNYXAgbWFwMiA9IG5ldyBIYXNoTWFwKDEwKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiSGFzaE1hcCgxMCkiLCBtYXAyLnZhbHVlcygpLCBtYXAyLnZhbHVlcygpKTsKKworICAgICAgICBNYXAgbWFwMyA9IENvbGxlY3Rpb25zLkVNUFRZX01BUDsKKyAgICAgICAgYXNzZXJ0U2FtZSgiRU1QVFlfTUFQIiwgbWFwMy52YWx1ZXMoKSwgbWFwMy52YWx1ZXMoKSk7CisKKyAgICAgICAgQWJzdHJhY3RNYXAgbWFwNCA9IG5ldyBJZGVudGl0eUhhc2hNYXAoMSk7CisgICAgICAgIGFzc2VydFNhbWUoIklkZW50aXR5SGFzaE1hcCIsIG1hcDQudmFsdWVzKCksIG1hcDQudmFsdWVzKCkpOworCisgICAgICAgIEFic3RyYWN0TWFwIG1hcDUgPSBuZXcgTGlua2VkSGFzaE1hcCgxMjIpOworICAgICAgICBhc3NlcnRTYW1lKCJJZGVudGl0eUhhc2hNYXAiLCBtYXA1LnZhbHVlcygpLCBtYXA1LnZhbHVlcygpKTsKKworICAgICAgICBBYnN0cmFjdE1hcCBtYXA2ID0gbmV3IFRyZWVNYXAoKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiVHJlZU1hcCIsIG1hcDYudmFsdWVzKCksIG1hcDYudmFsdWVzKCkpOworCisgICAgICAgIEFic3RyYWN0TWFwIG1hcDcgPSBuZXcgV2Vha0hhc2hNYXAoKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiV2Vha0hhc2hNYXAiLCBtYXA3LnZhbHVlcygpLCBtYXA3LnZhbHVlcygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQWJzdHJhY3RNYXAjY2xvbmUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvbmUoKSB7CisgICAgICAgIGNsYXNzIE15TWFwIGV4dGVuZHMgQWJzdHJhY3RNYXAgaW1wbGVtZW50cyBDbG9uZWFibGUgeworICAgICAgICAgICAgcHJpdmF0ZSBNYXAgbWFwID0gbmV3IEhhc2hNYXAoKTsKKworICAgICAgICAgICAgcHVibGljIFNldCBlbnRyeVNldCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbWFwLmVudHJ5U2V0KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcHV0KE9iamVjdCBrZXksIE9iamVjdCB2YWx1ZSkgeworICAgICAgICAgICAgICAgIHJldHVybiBtYXAucHV0KGtleSwgdmFsdWUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgTWFwIGdldE1hcCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbWFwOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGUpOyAvLyBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgOworICAgICAgICBNeU1hcCBtYXAgPSBuZXcgTXlNYXAoKTsKKyAgICAgICAgbWFwLnB1dCgib25lIiwgIjEiKTsKKyAgICAgICAgTWFwLkVudHJ5IGVudHJ5ID0gKE1hcC5FbnRyeSkgbWFwLmVudHJ5U2V0KCkuaXRlcmF0b3IoKS5uZXh0KCk7CisgICAgICAgIGFzc2VydFRydWUoImVudHJ5IG5vdCBhZGRlZCIsIGVudHJ5LmdldEtleSgpID09ICJvbmUiCisgICAgICAgICAgICAgICAgJiYgZW50cnkuZ2V0VmFsdWUoKSA9PSAiMSIpOworICAgICAgICBNeU1hcCBtYXBDbG9uZSA9IChNeU1hcCkgbWFwLmNsb25lKCk7CisgICAgICAgIGFzc2VydFRydWUoImNsb25lIG5vdCBzaGFsbG93IiwgbWFwLmdldE1hcCgpID09IG1hcENsb25lLmdldE1hcCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgQU1UIGV4dGVuZHMgQWJzdHJhY3RNYXAgeworCisgICAgICAgIC8vIFZlcnkgY3J1ZGUgQWJzdHJhY3RNYXAgaW1wbGVtZW50YXRpb24KKyAgICAgICAgVmVjdG9yIHZhbHVlcyA9IG5ldyBWZWN0b3IoKTsKKyAgICAgICAgVmVjdG9yIGtleXMgICA9IG5ldyBWZWN0b3IoKTsKKworICAgICAgICBwdWJsaWMgU2V0IGVudHJ5U2V0KCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBBYnN0cmFjdFNldCgpIHsKKyAgICAgICAgICAgICAgICBwdWJsaWMgSXRlcmF0b3IgaXRlcmF0b3IoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSAwOworCisgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbmRleCA8IHZhbHVlcy5zaXplKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgbmV4dCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPCB2YWx1ZXMuc2l6ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcC5FbnRyeSBtZSA9IG5ldyBNYXAuRW50cnkoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgdiA9IHZhbHVlcy5lbGVtZW50QXQoaW5kZXgpOworCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgayA9IGtleXMuZWxlbWVudEF0KGluZGV4KTsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBnZXRLZXkoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGs7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0VmFsdWUoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHY7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3Qgc2V0VmFsdWUoT2JqZWN0IHZhbHVlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4Kys7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBtZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZXMuc2l6ZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IHB1dChPYmplY3QgaywgT2JqZWN0IHYpIHsKKyAgICAgICAgICAgIGtleXMuYWRkKGspOworICAgICAgICAgICAgdmFsdWVzLmFkZCh2KTsKKyAgICAgICAgICAgIHJldHVybiB2OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICoge0BsaW5rIGphdmEudXRpbC5BYnN0cmFjdE1hcCNwdXRBbGwoTWFwKX0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3B1dEFsbExNYXAoKSB7CisgICAgICAgIEhhc2h0YWJsZSBodCAgPSBuZXcgSGFzaHRhYmxlKCk7CisgICAgICAgIEFNVCBhbXQgPSBuZXcgQU1UKCk7CisgICAgICAgIGh0LnB1dCgidGhpcyIsICJ0aGF0Iik7CisgICAgICAgIGFtdC5wdXRBbGwoaHQpOworCisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIGJlIGVxdWFsIiwgYW10LCBodCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVxdWFsc1dpdGhOdWxsVmFsdWVzKCkgeworICAgICAgICBNYXA8U3RyaW5nLCBTdHJpbmc+IGEgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgYS5wdXQoImEiLCBudWxsKTsKKyAgICAgICAgYS5wdXQoImIiLCBudWxsKTsKKworICAgICAgICBNYXA8U3RyaW5nLCBTdHJpbmc+IGIgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgYS5wdXQoImMiLCAiY2F0Iik7CisgICAgICAgIGEucHV0KCJkIiwgImRvZyIpOworCisgICAgICAgIGFzc2VydEZhbHNlKGEuZXF1YWxzKGIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoYi5lcXVhbHMoYSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROdWxsc09uVmlld3MoKSB7CisgICAgICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gbnVsbEhvc3RpbGUgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgU3RyaW5nPigpOworCisgICAgICAgIG51bGxIb3N0aWxlLnB1dCgiYSIsICJhcHBsZSIpOworICAgICAgICB0ZXN0TnVsbHNPblZpZXcobnVsbEhvc3RpbGUuZW50cnlTZXQoKSk7CisKKyAgICAgICAgbnVsbEhvc3RpbGUucHV0KCJhIiwgImFwcGxlIik7CisgICAgICAgIHRlc3ROdWxsc09uVmlldyhudWxsSG9zdGlsZS5rZXlTZXQoKSk7CisKKyAgICAgICAgbnVsbEhvc3RpbGUucHV0KCJhIiwgImFwcGxlIik7CisgICAgICAgIHRlc3ROdWxsc09uVmlldyhudWxsSG9zdGlsZS52YWx1ZXMoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3ROdWxsc09uVmlldyhDb2xsZWN0aW9uPD8+IHZpZXcpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHZpZXcuY29udGFpbnMobnVsbCkpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBvcHRpb25hbCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHZpZXcucmVtb3ZlKG51bGwpKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gb3B0aW9uYWwpIHsKKyAgICAgICAgfQorCisgICAgICAgIFNldDxPYmplY3Q+IHNldE9mTnVsbCA9IENvbGxlY3Rpb25zLnNpbmdsZXRvbihudWxsKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uodmlldy5lcXVhbHMoc2V0T2ZOdWxsKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHZpZXcucmVtb3ZlQWxsKHNldE9mTnVsbCkpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBvcHRpb25hbCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydFRydWUodmlldy5yZXRhaW5BbGwoc2V0T2ZOdWxsKSk7IC8vIGRlc3RydWN0aXZlCisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG9wdGlvbmFsKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9BYnN0cmFjdFF1ZXVlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQWJzdHJhY3RRdWV1ZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YWU0OTBjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQWJzdHJhY3RRdWV1ZVRlc3QuamF2YQpAQCAtMCwwICsxLDMyMyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdFF1ZXVlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIEFic3RyYWN0UXVldWVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBNb2NrQWJzdHJhY3RRdWV1ZTxPYmplY3Q+IHF1ZXVlOworCisgICAgcHJpdmF0ZSBjbGFzcyBNb2NrQWJzdHJhY3RRdWV1ZTxFPiBleHRlbmRzIEFic3RyYWN0UXVldWU8RT4geworCisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgQ0FQQUNJVFkgPSAxMDsKKworICAgICAgICBwcml2YXRlIGludCBzaXplID0gMDsKKworICAgICAgICBwcml2YXRlIE9iamVjdFtdIGVsZW1lbnRzID0gbmV3IE9iamVjdFtDQVBBQ0lUWV07CisKKyAgICAgICAgcHVibGljIEl0ZXJhdG9yPEU+IGl0ZXJhdG9yKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcjxFPigpIHsKKworICAgICAgICAgICAgICAgIHByaXZhdGUgaW50IGN1cnJlbnRJbmRleCA9IC0xOworCisgICAgICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNpemUgPiAwICYmIGN1cnJlbnRJbmRleCA8IHNpemU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcHVibGljIEUgbmV4dCgpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFoYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgY3VycmVudEluZGV4Kys7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAoRSkgZWxlbWVudHNbY3VycmVudEluZGV4XTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICgtMSA9PSBjdXJyZW50SW5kZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gY3VycmVudEluZGV4OyBpIDwgc2l6ZSAtIDE7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudHNbaV0gPSBlbGVtZW50c1tpICsgMV07CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgc2l6ZS0tOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gc2l6ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIG9mZmVyKEUgbykgeworICAgICAgICAgICAgaWYgKG51bGwgPT0gbykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoc2l6ZSA+PSBDQVBBQ0lUWSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZWxlbWVudHNbc2l6ZSsrXSA9IG87CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFIHBvbGwoKSB7CisgICAgICAgICAgICBpZiAoaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBFIGUgPSAoRSkgZWxlbWVudHNbMF07CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemUgLSAxOyBpKyspIHsKKyAgICAgICAgICAgICAgICBlbGVtZW50c1tpXSA9IGVsZW1lbnRzW2kgKyAxXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNpemUtLTsKKyAgICAgICAgICAgIHJldHVybiBlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEUgcGVlaygpIHsKKyAgICAgICAgICAgIGlmIChpc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAoRSkgZWxlbWVudHNbMF07CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BYnN0cmFjdFF1ZXVlLmFkZChFKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkTEVfbnVsbCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHF1ZXVlLmFkZChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFic3RyYWN0UXVldWUuYWRkKEUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRMRV9GdWxsKCkgeworICAgICAgICBPYmplY3QgbyA9IG5ldyBPYmplY3QoKTsKKworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgTW9ja0Fic3RyYWN0UXVldWUuQ0FQQUNJVFk7IGkrKyApIHsKKyAgICAgICAgICAgIHF1ZXVlLmFkZChvKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBxdWV1ZS5hZGQobyk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQWJzdHJhY3RRdWV1ZSNhZGQoRSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZExFKCkgeworICAgICAgICBPYmplY3QgbyA9IG5ldyBPYmplY3QoKTsKKyAgICAgICAgZmluYWwgaW50IExBU1RfSU5ERVggPSA0OworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IExBU1RfSU5ERVg7IGkrKykgeworICAgICAgICAgICAgcXVldWUuYWRkKG8pOworICAgICAgICB9CisgICAgICAgIEludGVnZXIgSSA9IG5ldyBJbnRlZ2VyKDEyMzQ1Nik7CisgICAgICAgIHF1ZXVlLmFkZChJKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShxdWV1ZS5jb250YWlucyhJKSk7CisgICAgICAgIEl0ZXJhdG9yIGl0ZXIgPSBxdWV1ZS5pdGVyYXRvcigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IExBU1RfSU5ERVg7IGkrKykgeworICAgICAgICAgICAgaXRlci5uZXh0KCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZShJID09IGl0ZXIubmV4dCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQWJzdHJhY3RRdWV1ZSNhZGRBbGwoRSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZEFsbExFX251bGwoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBxdWV1ZS5hZGRBbGwobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BYnN0cmFjdFF1ZXVlI2FkZEFsbChFKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkQWxsTEVfd2l0aF9udWxsKCkgeworICAgICAgICBMaXN0IGxpc3QgPSBBcnJheXMuYXNMaXN0KCJNWVRFU1RTVFJJTkciLCBudWxsLCBuZXcgRmxvYXQoMTIzLjQ1NikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcXVldWUuYWRkQWxsKGxpc3QpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQWJzdHJhY3RRdWV1ZSNhZGRBbGwoRSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZEFsbExFX2Z1bGwoKSB7CisgICAgICAgIExpc3QgbGlzdCA9IEFycmF5cy5hc0xpc3QoMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHF1ZXVlLmFkZEFsbChsaXN0KTsKKyAgICAgICAgICAgIGZhaWwoInNob3VsZCB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQWJzdHJhY3RRdWV1ZSNhZGRBbGwoRSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZEFsbExFX2VtcHR5KCkgeworICAgICAgICAvLyBSZWdyZXNzaW9uIHRlc3QgZm9yIEhBUk1PTlktMTE3OAorICAgICAgICBMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0PE9iamVjdD4oMCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJOb24gbW9kaWZpY2F0aW9uIHRvIHF1ZXVlIHNob3VsZCByZXR1cm4gZmFsc2UiLCBxdWV1ZS5hZGRBbGwobGlzdCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BYnN0cmFjdFF1ZXVlI2FkZEFsbChFKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkQWxsTEVfdGhpcygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHF1ZXVlLmFkZEFsbChxdWV1ZSk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkQWxsTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIENvbGxlY3Rpb24gYyA9IG5ldyBWZWN0b3IoKTsKKworICAgICAgICBjLmFkZCgwKTsKKyAgICAgICAgYy5hZGQoMSk7CisgICAgICAgIGMuYWRkKDIpOworICAgICAgICBjLmFkZCgzKTsKKyAgICAgICAgYy5hZGQoNCk7CisgICAgICAgIGMuYWRkKDUpOworCisgICAgICAgIGFzc2VydFRydWUocXVldWUuYWRkQWxsKGMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDYsIHF1ZXVlLnNpemUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFic3RyYWN0UXVldWUjY2xlYXIoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xlYXJfZW1wdHkoKSB7CisgICAgICAgIHF1ZXVlLmNsZWFyKCk7CisgICAgICAgIGFzc2VydFRydWUocXVldWUuaXNFbXB0eSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChxdWV1ZS5wZWVrKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BYnN0cmFjdFF1ZXVlI2NsZWFyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NsZWFyKCkgeworICAgICAgICBMaXN0IGxpc3QgPSBBcnJheXMuYXNMaXN0KDEyMy40NTYsICJNWVRFU1RTVFJJTkciLCBuZXcgT2JqZWN0KCksICdjJyk7CisgICAgICAgIHF1ZXVlLmFkZEFsbChsaXN0KTsKKyAgICAgICAgcXVldWUuY2xlYXIoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShxdWV1ZS5pc0VtcHR5KCkpOworICAgICAgICBhc3NlcnROdWxsKHF1ZXVlLnBlZWsoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFic3RyYWN0UXVldWUjQWJzdHJhY3RRdWV1ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgTW9ja0Fic3RyYWN0UXVldWUgcXVldWUgPSBuZXcgTW9ja0Fic3RyYWN0UXVldWUoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChxdWV1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFic3RyYWN0UXVldWUjcmVtb3ZlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlbW92ZV9udWxsKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcXVldWUucmVtb3ZlKCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BYnN0cmFjdFF1ZXVlI3JlbW92ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZW1vdmUoKSB7CisgICAgICAgIGNoYXIgYyA9ICdhJzsKKyAgICAgICAgcXVldWUuYWRkKGMpOworICAgICAgICBjID0gJ2InOworICAgICAgICBxdWV1ZS5hZGQoYyk7CisgICAgICAgIGFzc2VydEVxdWFscygnYScsIHF1ZXVlLnJlbW92ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCdiJywgcXVldWUucmVtb3ZlKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcXVldWUucmVtb3ZlKCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQWJzdHJhY3RRdWV1ZSNlbGVtZW50KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VsZW1lbnRfZW1wdHkoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBxdWV1ZS5lbGVtZW50KCk7CisgICAgICAgICAgICBmYWlsKCJzaG91bGQgdGhyb3cgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQWJzdHJhY3RRdWV1ZSNlbGVtZW50KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VsZW1lbnQoKSB7CisgICAgICAgIFN0cmluZyBzID0gIk1ZVEVTVFNUUklOR19PTkUiOworICAgICAgICBxdWV1ZS5hZGQocyk7CisgICAgICAgIHMgPSAiTVlURVNUU1RSSU5HX1RXTyI7CisgICAgICAgIHF1ZXVlLmFkZChzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJNWVRFU1RTVFJJTkdfT05FIiwgcXVldWUuZWxlbWVudCgpKTsKKyAgICAgICAgLy8gc3RpbGwgdGhlIGZpcnN0IGVsZW1lbnQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJNWVRFU1RTVFJJTkdfT05FIiwgcXVldWUuZWxlbWVudCgpKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBxdWV1ZSA9IG5ldyBNb2NrQWJzdHJhY3RRdWV1ZTxPYmplY3Q+KCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICAgICAgcXVldWUgPSBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0Fic3RyYWN0U2VxdWVudGlhbExpc3RUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9BYnN0cmFjdFNlcXVlbnRpYWxMaXN0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIwNjhmMWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9BYnN0cmFjdFNlcXVlbnRpYWxMaXN0VGVzdC5qYXZhCkBAIC0wLDAgKzEsNjAzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkFic3RyYWN0U2VxdWVudGlhbExpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpbmtlZExpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3RJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgY2xhc3MgQVNMVDxFPiBleHRlbmRzIEFic3RyYWN0U2VxdWVudGlhbExpc3Q8RT4geworCisgICAgICAgIExpbmtlZExpc3Q8RT4gbCA9IG5ldyBMaW5rZWRMaXN0PEU+KCk7CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBMaXN0SXRlcmF0b3I8RT4gbGlzdEl0ZXJhdG9yKGludCBpbmRleCkgeworICAgICAgICAgICAgcmV0dXJuIGwubGlzdEl0ZXJhdG9yKGluZGV4KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gbC5zaXplKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGxpbmsgamF2YS51dGlsLkFic3RyYWN0U2VxdWVudGlhbExpc3QjYWRkQWxsKGludCwgamF2YS51dGlsLkNvbGxlY3Rpb24pfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkQWxsX0lMQ29sbGVjdGlvbigpIHsKKyAgICAgICAgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdDxTdHJpbmc+IGFsID0gbmV3IEFTTFQ8U3RyaW5nPigpOworICAgICAgICBTdHJpbmdbXSBzb21lTGlzdCA9IHsgIkFhcmR2YXJrIiAgLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJlYXIiICAgICAgLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNoaW1wYW56ZWUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkR1Y2siICAgICAgfTsKKyAgICAgICAgQ29sbGVjdGlvbjxTdHJpbmc+IGMgPSBBcnJheXMuYXNMaXN0KHNvbWVMaXN0KTsKKyAgICAgICAgYWwuYWRkQWxsKGMpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIHRydWUiLCBhbC5hZGRBbGwoMiwgYykpOworICAgIH0KKworICAgIGNsYXNzIE1vY2tfdW5zdXBwb3J0ZWRMaXN0SXRlcmF0b3IgaW1wbGVtZW50cyBMaXN0SXRlcmF0b3IgeworICAgICAgICBwdWJsaWMgdm9pZCBhZGQoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzUHJldmlvdXMoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IG5leHQoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgbmV4dEluZGV4KCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IHByZXZpb3VzKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IHByZXZpb3VzSW5kZXgoKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldChPYmplY3QgbykgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBNb2NrX0xpc3RJdGVyYXRvcjxFPiBpbXBsZW1lbnRzIExpc3RJdGVyYXRvcjxFPiB7CisgICAgICAgIGZpbmFsIFN0cmluZyB3cm9uZ0VsZW1lbnQgPSAiU3RyaW5nIjsKKyAgICAgICAgcHVibGljIHZvaWQgYWRkKEUgbykgeworICAgICAgICAgICAgaWYgKG8uZXF1YWxzKHdyb25nRWxlbWVudCkpIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIGlmIChvID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc1ByZXZpb3VzKCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEUgbmV4dCgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBuZXh0SW5kZXgoKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFIHByZXZpb3VzKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IHByZXZpb3VzSW5kZXgoKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldChFIG8pIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkQWxsSUxqYXZhX3V0aWxfQ29sbGVjdGlvbigpIHsKKyAgICAgICAgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdCBhc2wgPSBuZXcgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdCgpIHsKKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIExpc3RJdGVyYXRvciBsaXN0SXRlcmF0b3IoaW50IGluZGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNb2NrX3Vuc3VwcG9ydGVkTGlzdEl0ZXJhdG9yKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIENvbGxlY3Rpb24gc3RyViA9IG5ldyBWZWN0b3I8U3RyaW5nPigpOworCisgICAgICAgIHN0clYuYWRkKCJTdHJpbmciKTsKKyAgICAgICAgc3RyVi5hZGQoIjEiKTsKKyAgICAgICAgc3RyVi5hZGQoIjMuMTQiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNsLmFkZEFsbCgwLCBzdHJWKTsKKyAgICAgICAgICAgIGZhaWwoIlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc2wuYWRkQWxsKDAsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vQ2xhc3NDYXN0RXhjZXB0aW9uIGNhbiBub3QgYmUgY2hlY2tlZCBmb3IgdGhpcyBtZXRob2QuCisKKyAgICAgICAgYXNsID0gbmV3IEFic3RyYWN0U2VxdWVudGlhbExpc3QoKSB7CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBMaXN0SXRlcmF0b3IgbGlzdEl0ZXJhdG9yKGludCBpbmRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTW9ja19MaXN0SXRlcmF0b3IoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNsLmFkZEFsbCgwLCBzdHJWKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgc3RyVi5yZW1vdmUoIlN0cmluZyIpOworICAgICAgICBzdHJWLmFkZChudWxsKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNsLmFkZEFsbCgwLCBzdHJWKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHN0clYucmVtb3ZlKG51bGwpOworICAgICAgICBhc2wuYWRkQWxsKDAsIHN0clYpOworCisgICAgICAgIGFzbCA9IG5ldyBMaW5rZWRMaXN0KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzbC5hZGRBbGwoLTEwLCBzdHJWKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNsLmFkZEFsbCgxLCBzdHJWKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZElMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdCBhc2wgPSBuZXcgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdCgpIHsKKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIExpc3RJdGVyYXRvciBsaXN0SXRlcmF0b3IoaW50IGluZGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNb2NrX3Vuc3VwcG9ydGVkTGlzdEl0ZXJhdG9yKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzbC5hZGQoMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBhc2wgPSBuZXcgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdCgpIHsKKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIExpc3RJdGVyYXRvciBsaXN0SXRlcmF0b3IoaW50IGluZGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNb2NrX0xpc3RJdGVyYXRvcigpOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc2wuYWRkKDAsICJTdHJpbmciKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc2wuYWRkKDAsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vQ2xhc3NDYXN0RXhjZXB0aW9uIGNhbiBub3QgYmUgY2hlY2tlZCBmb3IgdGhpcyBtZXRob2QuCisKKyAgICAgICAgYXNsLmFkZCgwLCAxKTsKKworICAgICAgICBhc2wgPSBuZXcgTGlua2VkTGlzdCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc2wuYWRkKC0xLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYXNsLmFkZCgwLCAxKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNsLmFkZCgyLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJKCkgeworICAgICAgICBmaW5hbCBTdHJpbmcgYnVmZltdID0geyIwIiwgIjEiLCAiMiIsICIzIiwgIjQiLCAiNSJ9OworICAgICAgICBBYnN0cmFjdFNlcXVlbnRpYWxMaXN0IGFzbCA9IG5ldyBBYnN0cmFjdFNlcXVlbnRpYWxMaXN0KCkgeworICAgICAgICAgICAgaW50IGN1cnJQb3MgPSAwOworCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYnVmZi5sZW5ndGg7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIExpc3RJdGVyYXRvciBsaXN0SXRlcmF0b3IoaW50IGluZGV4KSB7CisgICAgICAgICAgICAgICAgY3VyclBvcyA9IGluZGV4OworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTGlzdEl0ZXJhdG9yKCkgeworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBhZGQoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc1ByZXZpb3VzKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBuZXh0KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJ1ZmZbY3VyclBvc107CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgaW50IG5leHRJbmRleCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBwcmV2aW91cygpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIGludCBwcmV2aW91c0luZGV4KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBzZXQoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBidWZmLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYnVmZltpXSwgYXNsLmdldChpKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNsLmdldChhc2wuc2l6ZSgpICsgMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzbC5nZXQoLTEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXRlcnJhdG9yKCkgeworICAgICAgICBBYnN0cmFjdFNlcXVlbnRpYWxMaXN0IGFzbCA9IG5ldyBBYnN0cmFjdFNlcXVlbnRpYWxMaXN0KCkgeworCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgTGlzdEl0ZXJhdG9yIGxpc3RJdGVyYXRvcihpbnQgaW5kZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1vY2tfdW5zdXBwb3J0ZWRMaXN0SXRlcmF0b3IoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBhc3NlcnRUcnVlKGFzbC5pdGVyYXRvcigpLmdldENsYXNzKCkudG9TdHJpbmcoKS5jb250YWlucygiTW9ja191bnN1cHBvcnRlZExpc3RJdGVyYXRvciIpKTsKKworICAgICAgICBhc2wgPSBuZXcgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdCgpIHsKKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIExpc3RJdGVyYXRvciBsaXN0SXRlcmF0b3IoaW50IGluZGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNb2NrX0xpc3RJdGVyYXRvcigpOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIGFzc2VydFRydWUoYXNsLml0ZXJhdG9yKCkuZ2V0Q2xhc3MoKS50b1N0cmluZygpLmNvbnRhaW5zKCJNb2NrX0xpc3RJdGVyYXRvciIpKTsKKworICAgICAgICBhc2wgPSBuZXcgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdCgpIHsKKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIExpc3RJdGVyYXRvciBsaXN0SXRlcmF0b3IoaW50IGluZGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIGFzc2VydE51bGwoYXNsLml0ZXJhdG9yKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlSSgpIHsKKyAgICAgICAgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdCBhc2wgPSBuZXcgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdCgpIHsKKyAgICAgICAgICAgIFN0cmluZyBidWZmW10gPSB7IjAiLCAiMSIsICIyIiwgIjMiLCAiNCIsICI1In07CisgICAgICAgICAgICBpbnQgY3VyclBvcyA9IDA7CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBidWZmLmxlbmd0aDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgTGlzdEl0ZXJhdG9yIGxpc3RJdGVyYXRvcihpbnQgaW5kZXgpIHsKKyAgICAgICAgICAgICAgICBjdXJyUG9zID0gaW5kZXg7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBMaXN0SXRlcmF0b3IoKSB7CisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFkZChPYmplY3QgbykgeworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzUHJldmlvdXMoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IG5leHQoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYnVmZltjdXJyUG9zXTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBpbnQgbmV4dEluZGV4KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHByZXZpb3VzKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgaW50IHByZXZpb3VzSW5kZXgoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZbY3VyclBvc10gPSAicmVtb3ZlZCBlbGVtZW50IjsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHNldChPYmplY3QgbykgeworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNsLnJlbW92ZShhc2wuc2l6ZSgpICsgMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzbC5yZW1vdmUoLTEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBhc2wuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGFzbC5nZXQoaSkudG9TdHJpbmcoKS5jb250YWlucygicmVtb3ZlZCBlbGVtZW50IikpOworICAgICAgICAgICAgYXNsLnJlbW92ZShpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoYXNsLmdldChpKS50b1N0cmluZygpLmNvbnRhaW5zKCJyZW1vdmVkIGVsZW1lbnQiKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldElMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdCBhc2wgPSBuZXcgQWJzdHJhY3RTZXF1ZW50aWFsTGlzdCgpIHsKKyAgICAgICAgICAgIFN0cmluZyBidWZmW10gPSB7IjAiLCAiMSIsICIyIiwgIjMiLCAiNCIsICI1In07CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgaWxsZWdhbFN0ciA9ICJJbGxlZ2FsIGVsZW1lbnQiOworICAgICAgICAgICAgaW50IGN1cnJQb3MgPSAwOworCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYnVmZi5sZW5ndGg7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIExpc3RJdGVyYXRvciBsaXN0SXRlcmF0b3IoaW50IGluZGV4KSB7CisgICAgICAgICAgICAgICAgY3VyclBvcyA9IGluZGV4OworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTGlzdEl0ZXJhdG9yKCkgeworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBhZGQoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc1ByZXZpb3VzKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBuZXh0KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJ1ZmZbY3VyclBvc107CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgaW50IG5leHRJbmRleCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBwcmV2aW91cygpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIGludCBwcmV2aW91c0luZGV4KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBidWZmW2N1cnJQb3NdID0gInJlbW92ZWQgZWxlbWVudCI7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBzZXQoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG8uZXF1YWxzKGlsbGVnYWxTdHIpKSB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBidWZmW2N1cnJQb3NdID0gKFN0cmluZykgbzsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH07CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzbC5zZXQoYXNsLnNpemUoKSArIDEsICJuZXcgZWxlbWVudCIpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc2wuc2V0KC0xLCAibmV3IGVsZW1lbnQiKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgYXNsLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShhc2wuZ2V0KGkpLnRvU3RyaW5nKCkuY29udGFpbnMoIm5ldyBlbGVtZW50IikpOworICAgICAgICAgICAgYXNsLnNldChpLCAibmV3IGVsZW1lbnQiKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoYXNsLmdldChpKS50b1N0cmluZygpLmNvbnRhaW5zKCJuZXcgZWxlbWVudCIpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc2wuc2V0KDEsIG5ldyBEb3VibGUoMSkpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzbC5zZXQoMSwgIklsbGVnYWwgZWxlbWVudCIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzbC5zZXQoMSwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYXNsID0gbmV3IEFic3RyYWN0U2VxdWVudGlhbExpc3QoKSB7CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBMaXN0SXRlcmF0b3IgbGlzdEl0ZXJhdG9yKGludCBpbmRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTW9ja191bnN1cHBvcnRlZExpc3RJdGVyYXRvcigpOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc2wuc2V0KDAsICJOZXcgZWxlbWVudCIpOworICAgICAgICAgICAgZmFpbCgiVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQXJyYXlMaXN0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQXJyYXlMaXN0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUwZDlhYTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9BcnJheUxpc3RUZXN0LmphdmEKQEAgLTAsMCArMSw2OTkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLkNvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKKworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9MaXN0VGVzdDsKKworcHVibGljIGNsYXNzIEFycmF5TGlzdFRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgTGlzdCBhbGlzdDsKKworICAgIE9iamVjdFtdIG9iakFycmF5OworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5TGlzdCNBcnJheUxpc3QoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuQXJyYXlMaXN0KCkKKyAgICAgICAgbmV3IFN1cHBvcnRfTGlzdFRlc3QoIiIsIGFsaXN0KS5ydW5UZXN0KCk7CisKKyAgICAgICAgQXJyYXlMaXN0IHN1Ykxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAtNTA7IGkgPCAxNTA7IGkrKykKKyAgICAgICAgICAgIHN1Ykxpc3QuYWRkKG5ldyBJbnRlZ2VyKGkpKTsKKyAgICAgICAgbmV3IFN1cHBvcnRfTGlzdFRlc3QoIiIsIHN1Ykxpc3Quc3ViTGlzdCg1MCwgMTUwKSkucnVuVGVzdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheUxpc3QjQXJyYXlMaXN0KGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5BcnJheUxpc3QoaW50KQorICAgICAgICBBcnJheUxpc3QgYWwgPSBuZXcgQXJyYXlMaXN0KDUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhcnJheUxpc3QgY3JlYXRlZCIsIDAsIGFsLnNpemUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBBcnJheUxpc3QoLTEwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5TGlzdCNBcnJheUxpc3QoamF2YS51dGlsLkNvbGxlY3Rpb24pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX3V0aWxfQ29sbGVjdGlvbigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5BcnJheUxpc3QoamF2YS51dGlsLkNvbGxlY3Rpb24pCisgICAgICAgIEFycmF5TGlzdCBhbCA9IG5ldyBBcnJheUxpc3QoQXJyYXlzLmFzTGlzdChvYmpBcnJheSkpOworICAgICAgICBhc3NlcnRUcnVlKCJhcnJheUxpc3QgY3JlYXRlZCBmcm9tIGNvbGxlY3Rpb24gaGFzIGluY29ycmVjdCBzaXplIiwgYWwKKyAgICAgICAgICAgICAgICAuc2l6ZSgpID09IG9iakFycmF5Lmxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgb2JqQXJyYXkubGVuZ3RoOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiYXJyYXlMaXN0IGNyZWF0ZWQgZnJvbSBjb2xsZWN0aW9uIGhhcyBpbmNvcnJlY3QgZWxlbWVudHMiLAorICAgICAgICAgICAgICAgICAgICBhbC5nZXQoY291bnRlcikgPT0gb2JqQXJyYXlbY291bnRlcl0pOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEFycmF5TGlzdChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5TGlzdCNhZGQoaW50LCBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkSUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlMaXN0LmFkZChpbnQsIGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIE9iamVjdCBvOworICAgICAgICBhbGlzdC5hZGQoNTAsIG8gPSBuZXcgT2JqZWN0KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gYWRkIE9iamVjdCIsIGFsaXN0LmdldCg1MCkgPT0gbyk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBmaXggdXAgbGlzdCBhZnRlciBpbnNlcnQiLAorICAgICAgICAgICAgICAgIGFsaXN0LmdldCg1MSkgPT0gb2JqQXJyYXlbNTBdCisgICAgICAgICAgICAgICAgICAgICAgICAmJiAoYWxpc3QuZ2V0KDUyKSA9PSBvYmpBcnJheVs1MV0pKTsKKyAgICAgICAgT2JqZWN0IG9sZEl0ZW0gPSBhbGlzdC5nZXQoMjUpOworICAgICAgICBhbGlzdC5hZGQoMjUsIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJTaG91bGQgaGF2ZSByZXR1cm5lZCBudWxsIiwgYWxpc3QuZ2V0KDI1KSk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBoYXZlIHJldHVybmVkIHRoZSBvbGQgaXRlbSBmcm9tIHNsb3QgMjUiLCBhbGlzdAorICAgICAgICAgICAgICAgIC5nZXQoMjYpID09IG9sZEl0ZW0pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhbGlzdC5hZGQoLTEsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhbGlzdC5hZGQoYWxpc3Quc2l6ZSgpICsgMSwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5TGlzdCNhZGQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuQXJyYXlMaXN0LmFkZChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBPYmplY3QgbyA9IG5ldyBPYmplY3QoKTsKKyAgICAgICAgYWxpc3QuYWRkKG8pOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gYWRkIE9iamVjdCIsIGFsaXN0LmdldChhbGlzdC5zaXplKCkgLSAxKSA9PSBvKTsKKyAgICAgICAgYWxpc3QuYWRkKG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJGYWlsZWQgdG8gYWRkIG51bGwiLCBhbGlzdC5nZXQoYWxpc3Quc2l6ZSgpIC0gMSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheUxpc3QjYWRkQWxsKGludCwgamF2YS51dGlsLkNvbGxlY3Rpb24pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRBbGxJTGphdmFfdXRpbF9Db2xsZWN0aW9uKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuQXJyYXlMaXN0LmFkZEFsbChpbnQsCisgICAgICAgIC8vIGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAgICBhbGlzdC5hZGRBbGwoNTAsIGFsaXN0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3Qgc2l6ZSBhZnRlciBhZGRpbmcgdG8gZXhpc3RpbmcgbGlzdCIsCisgICAgICAgICAgICAgICAgMjAwLCBhbGlzdC5zaXplKCkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDUwOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJNYW5pcHVsYXRlZCBlbGVtZW50cyA8IGluZGV4IiwKKyAgICAgICAgICAgICAgICAgICAgYWxpc3QuZ2V0KGkpID09IG9iakFycmF5W2ldKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPj0gNTAgJiYgKGkgPCAxNTApOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gYWQgZWxlbWVudHMgcHJvcGVybHkiLAorICAgICAgICAgICAgICAgICAgICBhbGlzdC5nZXQoaSkgPT0gb2JqQXJyYXlbaSAtIDUwXSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpID49IDE1MCAmJiAoaSA8IDIwMCk7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBhZCBlbGVtZW50cyBwcm9wZXJseSIsCisgICAgICAgICAgICAgICAgICAgIGFsaXN0LmdldChpKSA9PSBvYmpBcnJheVtpIC0gMTAwXSk7CisgICAgICAgIEFycmF5TGlzdCBsaXN0V2l0aE51bGxzID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBsaXN0V2l0aE51bGxzLmFkZChudWxsKTsKKyAgICAgICAgbGlzdFdpdGhOdWxscy5hZGQobnVsbCk7CisgICAgICAgIGxpc3RXaXRoTnVsbHMuYWRkKCJ5b2luayIpOworICAgICAgICBsaXN0V2l0aE51bGxzLmFkZCgia2F6b28iKTsKKyAgICAgICAgbGlzdFdpdGhOdWxscy5hZGQobnVsbCk7CisgICAgICAgIGFsaXN0LmFkZEFsbCgxMDAsIGxpc3RXaXRoTnVsbHMpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3Qgc2l6ZTogIiArIGFsaXN0LnNpemUoKSwgYWxpc3Quc2l6ZSgpID09IDIwNSk7CisgICAgICAgIGFzc2VydE51bGwoIkl0ZW0gYXQgc2xvdCAxMDAgc2hvdWxkIGJlIG51bGwiLCBhbGlzdC5nZXQoMTAwKSk7CisgICAgICAgIGFzc2VydE51bGwoIkl0ZW0gYXQgc2xvdCAxMDEgc2hvdWxkIGJlIG51bGwiLCBhbGlzdC5nZXQoMTAxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSXRlbSBhdCBzbG90IDEwMiBzaG91bGQgYmUgJ3lvaW5rJyIsCisgICAgICAgICAgICAgICAgInlvaW5rIiwgYWxpc3QuZ2V0KDEwMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkl0ZW0gYXQgc2xvdCAxMDMgc2hvdWxkIGJlICdrYXpvbyciLAorICAgICAgICAgICAgICAgICJrYXpvbyIsIGFsaXN0LmdldCgxMDMpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiSXRlbSBhdCBzbG90IDEwNCBzaG91bGQgYmUgbnVsbCIsIGFsaXN0LmdldCgxMDQpKTsKKyAgICAgICAgYWxpc3QuYWRkQWxsKDIwNSwgbGlzdFdpdGhOdWxscyk7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBzaXplMjogIiArIGFsaXN0LnNpemUoKSwgYWxpc3Quc2l6ZSgpID09IDIxMCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFsaXN0LmFkZEFsbCgtMSwgbGlzdFdpdGhOdWxscyk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFsaXN0LmFkZEFsbChhbGlzdC5zaXplKCkgKyAxLCBsaXN0V2l0aE51bGxzKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWxpc3QuYWRkQWxsKDAsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisvLyBCRUdJTiBhbmRyb2lkLXJlbW92ZWQKKy8vIFRoZSBzcGVjIGRvZXMgbm90IG1hbmRhdGUgdGhhdCBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGJlIHRocm93biBpbgorLy8gcHJlZmVyZW5jZSB0byBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIHRoZSBjYWxsZXIgZGVzc2VydmVzIGJvdGguCisvLworLy8gICAgLyoqCisvLyAgICAgKiBqYXZhLnV0aWwuQXJyYXlMaXN0I2FkZEFsbChpbnQsIGphdmEudXRpbC5Db2xsZWN0aW9uKQorLy8gICAgICovCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZEFsbElMamF2YV91dGlsX0NvbGxlY3Rpb25fMigpIHsKKy8vICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTQ2NworLy8gICAgICAgIEFycmF5TGlzdCBvYmogPSBuZXcgQXJyYXlMaXN0KCk7CisvLyAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgb2JqLmFkZEFsbCgoaW50KSAtMSwgKENvbGxlY3Rpb24pIG51bGwpOworLy8gICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisvLyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisvLyAgICAgICAgfQorLy8gICAgfQorLy8gRU5EIGFuZHJvaWQtcmVtb3ZlZAorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5TGlzdCNhZGRBbGwoamF2YS51dGlsLkNvbGxlY3Rpb24pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRBbGxMamF2YV91dGlsX0NvbGxlY3Rpb24oKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuCisgICAgICAgIC8vIGphdmEudXRpbC5BcnJheUxpc3QuYWRkQWxsKGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAgICBMaXN0IGwgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGwuYWRkQWxsKGFsaXN0KTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGlzdC5zaXplKCk7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBhZGQgZWxlbWVudHMgcHJvcGVybHkiLCBsLmdldChpKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgIGFsaXN0LmdldChpKSkpOworICAgICAgICBhbGlzdC5hZGRBbGwoYWxpc3QpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBzaXplIGFmdGVyIGFkZGluZyB0byBleGlzdGluZyBsaXN0IiwKKyAgICAgICAgICAgICAgICAyMDAsIGFsaXN0LnNpemUoKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFkZGVkIHRvIGxpc3QgaW4gaW5jb3JyZWN0IG9yZGVyIiwgYWxpc3QuZ2V0KGkpCisgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMobC5nZXQoaSkpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBhZGQgdG8gZXhpc3RpbmcgbGlzdCIsIGFsaXN0LmdldChpICsgMTAwKQorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKGwuZ2V0KGkpKSk7CisgICAgICAgIH0KKyAgICAgICAgU2V0IHNldFdpdGhOdWxscyA9IG5ldyBIYXNoU2V0KCk7CisgICAgICAgIHNldFdpdGhOdWxscy5hZGQobnVsbCk7CisgICAgICAgIHNldFdpdGhOdWxscy5hZGQobnVsbCk7CisgICAgICAgIHNldFdpdGhOdWxscy5hZGQoInlvaW5rIik7CisgICAgICAgIHNldFdpdGhOdWxscy5hZGQoImthem9vIik7CisgICAgICAgIHNldFdpdGhOdWxscy5hZGQobnVsbCk7CisgICAgICAgIGFsaXN0LmFkZEFsbCgxMDAsIHNldFdpdGhOdWxscyk7CisgICAgICAgIEl0ZXJhdG9yIGkgPSBzZXRXaXRoTnVsbHMuaXRlcmF0b3IoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSXRlbSBhdCBzbG90IDEwMCBpcyB3cm9uZzogIiArIGFsaXN0LmdldCgxMDApLCBhbGlzdAorICAgICAgICAgICAgICAgIC5nZXQoMTAwKSA9PSBpLm5leHQoKSk7CisgICAgICAgIGFzc2VydFRydWUoIkl0ZW0gYXQgc2xvdCAxMDEgaXMgd3Jvbmc6ICIgKyBhbGlzdC5nZXQoMTAxKSwgYWxpc3QKKyAgICAgICAgICAgICAgICAuZ2V0KDEwMSkgPT0gaS5uZXh0KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJJdGVtIGF0IHNsb3QgMTAzIGlzIHdyb25nOiAiICsgYWxpc3QuZ2V0KDEwMiksIGFsaXN0CisgICAgICAgICAgICAgICAgLmdldCgxMDIpID09IGkubmV4dCgpKTsKKworCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgSGFybW9ueS0zNDgxCisgICAgICAgIEFycmF5TGlzdDxJbnRlZ2VyPiBvcmlnaW5hbExpc3QgPSBuZXcgQXJyYXlMaXN0PEludGVnZXI+KDEyKTsKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCAxMjsgaisrKSB7CisgICAgICAgICAgICBvcmlnaW5hbExpc3QuYWRkKGopOworICAgICAgICB9CisKKyAgICAgICAgb3JpZ2luYWxMaXN0LnJlbW92ZSgwKTsKKyAgICAgICAgb3JpZ2luYWxMaXN0LnJlbW92ZSgwKTsKKworICAgICAgICBBcnJheUxpc3Q8SW50ZWdlcj4gYWRkaXRpb25hbExpc3QgPSBuZXcgQXJyYXlMaXN0PEludGVnZXI+KDExKTsKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCAxMTsgaisrKSB7CisgICAgICAgICAgICBhZGRpdGlvbmFsTGlzdC5hZGQoaik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZShvcmlnaW5hbExpc3QuYWRkQWxsKGFkZGl0aW9uYWxMaXN0KSk7CisgICAgICAgIGFzc2VydEVxdWFscygyMSwgb3JpZ2luYWxMaXN0LnNpemUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFsaXN0LmFkZEFsbChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheUxpc3QjY2xlYXIoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xlYXIoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5BcnJheUxpc3QuY2xlYXIoKQorICAgICAgICBhbGlzdC5jbGVhcigpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkxpc3QgZGlkIG5vdCBjbGVhciIsIDAsIGFsaXN0LnNpemUoKSk7CisgICAgICAgIGFsaXN0LmFkZChudWxsKTsKKyAgICAgICAgYWxpc3QuYWRkKG51bGwpOworICAgICAgICBhbGlzdC5hZGQobnVsbCk7CisgICAgICAgIGFsaXN0LmFkZCgiYmFtIik7CisgICAgICAgIGFsaXN0LmNsZWFyKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiTGlzdCB3aXRoIG51bGxzIGRpZCBub3QgY2xlYXIiLCAwLCBhbGlzdC5zaXplKCkpOworICAgICAgICAvKgorICAgICAgICAgKiBmb3IgKGludCBpID0gMDsgaSA8IGFsaXN0LnNpemUoKTsgaSsrKSBhc3NlcnROdWxsKCJGYWlsZWQgdG8gY2xlYXIKKyAgICAgICAgICogbGlzdCIsIGFsaXN0LmdldChpKSk7CisgICAgICAgICAqLworCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5TGlzdCNjbG9uZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jbG9uZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QgamF2YS51dGlsLkFycmF5TGlzdC5jbG9uZSgpCisgICAgICAgIEFycmF5TGlzdCB4ID0gKEFycmF5TGlzdCkgKCgoQXJyYXlMaXN0KSAoYWxpc3QpKS5jbG9uZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2xvbmVkIGxpc3Qgd2FzIGluZXF1YWwgdG8gb3JpZ2luYWwiLCB4LmVxdWFscyhhbGlzdCkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsaXN0LnNpemUoKTsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2xvbmVkIGxpc3QgY29udGFpbnMgaW5jb3JyZWN0IGVsZW1lbnRzIiwKKyAgICAgICAgICAgICAgICAgICAgYWxpc3QuZ2V0KGkpID09IHguZ2V0KGkpKTsKKworICAgICAgICBhbGlzdC5hZGQobnVsbCk7CisgICAgICAgIGFsaXN0LmFkZCgyNSwgbnVsbCk7CisgICAgICAgIHggPSAoQXJyYXlMaXN0KSAoKChBcnJheUxpc3QpIChhbGlzdCkpLmNsb25lKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJudWxscyB0ZXN0IC0gQ2xvbmVkIGxpc3Qgd2FzIGluZXF1YWwgdG8gb3JpZ2luYWwiLCB4CisgICAgICAgICAgICAgICAgLmVxdWFscyhhbGlzdCkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsaXN0LnNpemUoKTsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgibnVsbHMgdGVzdCAtIENsb25lZCBsaXN0IGNvbnRhaW5zIGluY29ycmVjdCBlbGVtZW50cyIsCisgICAgICAgICAgICAgICAgICAgIGFsaXN0LmdldChpKSA9PSB4LmdldChpKSk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlMaXN0I2NvbnRhaW5zKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jb250YWluc0xqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbgorICAgICAgICAvLyBqYXZhLnV0aWwuQXJyYXlMaXN0LmNvbnRhaW5zKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciB2YWxpZCBlbGVtZW50IiwgYWxpc3QKKyAgICAgICAgICAgICAgICAuY29udGFpbnMob2JqQXJyYXlbOTldKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciBlcXVhbCBlbGVtZW50IiwgYWxpc3QKKyAgICAgICAgICAgICAgICAuY29udGFpbnMobmV3IEludGVnZXIoOCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgaW52YWxpZCBlbGVtZW50IiwgIWFsaXN0CisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKG5ldyBPYmplY3QoKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCB0cnVlIGZvciBudWxsIGJ1dCBzaG91bGQgaGF2ZSByZXR1cm5lZCBmYWxzZSIsCisgICAgICAgICAgICAgICAgIWFsaXN0LmNvbnRhaW5zKG51bGwpKTsKKyAgICAgICAgYWxpc3QuYWRkKG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgbnVsbCBidXQgc2hvdWxkIGhhdmUgcmV0dXJuZWQgdHJ1ZSIsCisgICAgICAgICAgICAgICAgYWxpc3QuY29udGFpbnMobnVsbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheUxpc3QjZW5zdXJlQ2FwYWNpdHkoaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZW5zdXJlQ2FwYWNpdHlJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlMaXN0LmVuc3VyZUNhcGFjaXR5KGludCkKKyAgICAgICAgLy8gVE9ETyA6IFRoZXJlIGlzIG5vIGdvb2Qgd2F5IHRvIHRlc3QgdGhpcyBhcyBpdCBvbmx5IHJlYWxseSBpbXBhY3RzIG9uCisgICAgICAgIC8vIHRoZSBwcml2YXRlIGltcGxlbWVudGF0aW9uLgorCisgICAgICAgIE9iamVjdCB0ZXN0T2JqZWN0ID0gbmV3IE9iamVjdCgpOworICAgICAgICBpbnQgY2FwYWNpdHkgPSAyMDsKKyAgICAgICAgQXJyYXlMaXN0IGFsID0gbmV3IEFycmF5TGlzdChjYXBhY2l0eSk7CisgICAgICAgIGludCBpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY2FwYWNpdHkgLyAyOyBpKyspIHsKKyAgICAgICAgICAgIGFsLmFkZChpLCBuZXcgT2JqZWN0KCkpOworICAgICAgICB9CisgICAgICAgIGFsLmFkZChpLCB0ZXN0T2JqZWN0KTsKKyAgICAgICAgaW50IGxvY2F0aW9uID0gYWwuaW5kZXhPZih0ZXN0T2JqZWN0KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFsLmVuc3VyZUNhcGFjaXR5KGNhcGFjaXR5KTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkVuc3VyZUNhcGFjaXR5IG1vdmVkIG9iamVjdHMgYXJvdW5kIGluIGFycmF5MS4iLAorICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbiA9PSBhbC5pbmRleE9mKHRlc3RPYmplY3QpKTsKKyAgICAgICAgICAgIGFsLnJlbW92ZSgwKTsKKyAgICAgICAgICAgIGFsLmVuc3VyZUNhcGFjaXR5KGNhcGFjaXR5KTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkVuc3VyZUNhcGFjaXR5IG1vdmVkIG9iamVjdHMgYXJvdW5kIGluIGFycmF5Mi4iLAorICAgICAgICAgICAgICAgICAgICAtLWxvY2F0aW9uID09IGFsLmluZGV4T2YodGVzdE9iamVjdCkpOworICAgICAgICAgICAgYWwuZW5zdXJlQ2FwYWNpdHkoY2FwYWNpdHkgKyAyKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkVuc3VyZUNhcGFjaXR5IGRpZCBub3QgY2hhbmdlIGxvY2F0aW9uLiIsCisgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uID09IGFsLmluZGV4T2YodGVzdE9iamVjdCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGR1cmluZyB0ZXN0IDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheUxpc3QjZ2V0KGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IGphdmEudXRpbC5BcnJheUxpc3QuZ2V0KGludCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGVsZW1lbnQiLCBhbGlzdC5nZXQoMjIpID09IG9iakFycmF5WzIyXSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhbGlzdC5nZXQoODc2NSk7CisgICAgICAgICAgICBmYWlsKCJGYWlsZWQgdG8gdGhyb3cgZXhwZWN0ZWQgZXhjZXB0aW9uIGZvciBpbmRleCA+IHNpemUiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlMaXN0I2luZGV4T2YoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luZGV4T2ZMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuQXJyYXlMaXN0LmluZGV4T2YoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgaW5kZXgiLAorICAgICAgICAgICAgICAgIDg3LCBhbGlzdC5pbmRleE9mKG9iakFycmF5Wzg3XSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluZGV4IGZvciBpbnZhbGlkIE9iamVjdCIsIC0xLCBhbGlzdAorICAgICAgICAgICAgICAgIC5pbmRleE9mKG5ldyBPYmplY3QoKSkpOworICAgICAgICBhbGlzdC5hZGQoMjUsIG51bGwpOworICAgICAgICBhbGlzdC5hZGQoNTAsIG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBpbmRleE9mIGZvciBudWxsLiAgV2FudGVkIDI1IGdvdDogIgorICAgICAgICAgICAgICAgICsgYWxpc3QuaW5kZXhPZihudWxsKSwgYWxpc3QuaW5kZXhPZihudWxsKSA9PSAyNSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5TGlzdCNpc0VtcHR5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzRW1wdHkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEudXRpbC5BcnJheUxpc3QuaXNFbXB0eSgpCisgICAgICAgIGFzc2VydFRydWUoImlzRW1wdHkgcmV0dXJuZWQgZmFsc2UgZm9yIG5ldyBsaXN0IiwgbmV3IEFycmF5TGlzdCgpCisgICAgICAgICAgICAgICAgLmlzRW1wdHkoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHRydWUgZm9yIGV4aXN0aW5nIGxpc3Qgd2l0aCBlbGVtZW50cyIsICFhbGlzdAorICAgICAgICAgICAgICAgIC5pc0VtcHR5KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheUxpc3QjbGFzdEluZGV4T2YoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xhc3RJbmRleE9mTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLkFycmF5TGlzdC5sYXN0SW5kZXhPZihqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBhbGlzdC5hZGQobmV3IEludGVnZXIoOTkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgaW5kZXgiLAorICAgICAgICAgICAgICAgIDEwMCwgYWxpc3QubGFzdEluZGV4T2Yob2JqQXJyYXlbOTldKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5kZXggZm9yIGludmFsaWQgT2JqZWN0IiwgLTEsIGFsaXN0CisgICAgICAgICAgICAgICAgLmxhc3RJbmRleE9mKG5ldyBPYmplY3QoKSkpOworICAgICAgICBhbGlzdC5hZGQoMjUsIG51bGwpOworICAgICAgICBhbGlzdC5hZGQoNTAsIG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBsYXN0SW5kZXhPZiBmb3IgbnVsbC4gIFdhbnRlZCA1MCBnb3Q6ICIKKyAgICAgICAgICAgICAgICArIGFsaXN0Lmxhc3RJbmRleE9mKG51bGwpLCBhbGlzdC5sYXN0SW5kZXhPZihudWxsKSA9PSA1MCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5TGlzdCNyZW1vdmUoaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QgamF2YS51dGlsLkFycmF5TGlzdC5yZW1vdmUoaW50KQorICAgICAgICBhbGlzdC5yZW1vdmUoMTApOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCB0byByZW1vdmUgZWxlbWVudCIsCisgICAgICAgICAgICAgICAgLTEsIGFsaXN0LmluZGV4T2Yob2JqQXJyYXlbMTBdKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhbGlzdC5yZW1vdmUoOTk5KTsKKyAgICAgICAgICAgIGZhaWwoIkZhaWxlZCB0byB0aHJvdyBleGNlcHRpb24gd2hlbiBpbmRleCBvdXQgb2YgcmFuZ2UiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBBcnJheUxpc3QgbXlMaXN0ID0gKEFycmF5TGlzdCkgKCgoQXJyYXlMaXN0KSAoYWxpc3QpKS5jbG9uZSgpKTsKKyAgICAgICAgYWxpc3QuYWRkKDI1LCBudWxsKTsKKyAgICAgICAgYWxpc3QuYWRkKDUwLCBudWxsKTsKKyAgICAgICAgYWxpc3QucmVtb3ZlKDUwKTsKKyAgICAgICAgYWxpc3QucmVtb3ZlKDI1KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmVtb3ZpbmcgbnVsbHMgZGlkIG5vdCB3b3JrIiwgYWxpc3QuZXF1YWxzKG15TGlzdCkpOworCisgICAgICAgIExpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoQXJyYXlzLmFzTGlzdChuZXcgU3RyaW5nW10geyAiYSIsICJiIiwgImMiLAorICAgICAgICAgICAgICAgICJkIiwgImUiLCAiZiIsICJnIiB9KSk7CisgICAgICAgIGFzc2VydFRydWUoIlJlbW92ZWQgd3JvbmcgZWxlbWVudCAxIiwgbGlzdC5yZW1vdmUoMCkgPT0gImEiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmVtb3ZlZCB3cm9uZyBlbGVtZW50IDIiLCBsaXN0LnJlbW92ZSg0KSA9PSAiZiIpOworICAgICAgICBTdHJpbmdbXSByZXN1bHQgPSBuZXcgU3RyaW5nWzVdOworICAgICAgICBsaXN0LnRvQXJyYXkocmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmVtb3ZlZCB3cm9uZyBlbGVtZW50IDMiLCBBcnJheXMuZXF1YWxzKHJlc3VsdCwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geyAiYiIsICJjIiwgImQiLCAiZSIsICJnIiB9KSk7CisKKyAgICAgICAgTGlzdCBsID0gbmV3IEFycmF5TGlzdCgwKTsKKyAgICAgICAgbC5hZGQobmV3IE9iamVjdCgpKTsKKyAgICAgICAgbC5hZGQobmV3IE9iamVjdCgpKTsKKyAgICAgICAgbC5yZW1vdmUoMCk7CisgICAgICAgIGwucmVtb3ZlKDApOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbC5yZW1vdmUoLTEpOworICAgICAgICAgICAgZmFpbCgiLTEgc2hvdWxkIGNhdXNlIGV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbC5yZW1vdmUoMCk7CisgICAgICAgICAgICBmYWlsKCIwIHNob3VsZCBjYXNlIGV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheUxpc3Qjc2V0KGludCwgamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldElMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QgamF2YS51dGlsLkFycmF5TGlzdC5zZXQoaW50LAorICAgICAgICAvLyBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBPYmplY3Qgb2JqOworICAgICAgICBhbGlzdC5zZXQoNjUsIG9iaiA9IG5ldyBPYmplY3QoKSk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBzZXQgb2JqZWN0IiwgYWxpc3QuZ2V0KDY1KSA9PSBvYmopOworICAgICAgICBhbGlzdC5zZXQoNTAsIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJTZXR0aW5nIHRvIG51bGwgZGlkIG5vdCB3b3JrIiwgYWxpc3QuZ2V0KDUwKSk7CisgICAgICAgIGFzc2VydFRydWUoIlNldHRpbmcgaW5jcmVhc2VkIHRoZSBsaXN0J3Mgc2l6ZSB0bzogIiArIGFsaXN0LnNpemUoKSwKKyAgICAgICAgICAgICAgICBhbGlzdC5zaXplKCkgPT0gMTAwKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWxpc3Quc2V0KC0xLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWxpc3Quc2V0KGFsaXN0LnNpemUoKSArIDEsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheUxpc3Qjc2l6ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zaXplKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudXRpbC5BcnJheUxpc3Quc2l6ZSgpCisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHNpemUgZm9yIGV4aXRpbmcgbGlzdCIsCisgICAgICAgICAgICAgICAgMTAwLCBhbGlzdC5zaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBzaXplIGZvciBuZXcgbGlzdCIsIDAsIG5ldyBBcnJheUxpc3QoKQorICAgICAgICAgICAgICAgIC5zaXplKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheUxpc3QjdG9BcnJheSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF90b0FycmF5KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdCBbXSBqYXZhLnV0aWwuQXJyYXlMaXN0LnRvQXJyYXkoKQorICAgICAgICBhbGlzdC5zZXQoMjUsIG51bGwpOworICAgICAgICBhbGlzdC5zZXQoNzUsIG51bGwpOworICAgICAgICBPYmplY3RbXSBvYmogPSBhbGlzdC50b0FycmF5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgYXJyYXkgb2YgaW5jb3JyZWN0IHNpemUiLCBvYmpBcnJheS5sZW5ndGgsCisgICAgICAgICAgICAgICAgb2JqLmxlbmd0aCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmICgoaSA9PSAyNSkgfHwgKGkgPT0gNzUpKQorICAgICAgICAgICAgICAgIGFzc2VydE51bGwoIlNob3VsZCBiZSBudWxsIGF0OiAiICsgaSArICIgYnV0IGluc3RlYWQgZ290OiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIG9ialtpXSwgb2JqW2ldKTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgYXJyYXk6ICIgKyBpLAorICAgICAgICAgICAgICAgICAgICAgICAgb2JqW2ldID09IG9iakFycmF5W2ldKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5TGlzdCN0b0FycmF5KGphdmEubGFuZy5PYmplY3RbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvQXJyYXkkTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IFtdCisgICAgICAgIC8vIGphdmEudXRpbC5BcnJheUxpc3QudG9BcnJheShqYXZhLmxhbmcuT2JqZWN0IFtdKQorICAgICAgICBhbGlzdC5zZXQoMjUsIG51bGwpOworICAgICAgICBhbGlzdC5zZXQoNzUsIG51bGwpOworICAgICAgICBJbnRlZ2VyW10gYXJnQXJyYXkgPSBuZXcgSW50ZWdlclsxMDBdOworICAgICAgICBPYmplY3RbXSByZXRBcnJheTsKKyAgICAgICAgcmV0QXJyYXkgPSBhbGlzdC50b0FycmF5KGFyZ0FycmF5KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZGlmZmVyZW50IGFycmF5IHRoYW4gcGFzc2VkIiwgcmV0QXJyYXkgPT0gYXJnQXJyYXkpOworICAgICAgICBhcmdBcnJheSA9IG5ldyBJbnRlZ2VyWzEwMDBdOworICAgICAgICByZXRBcnJheSA9IGFsaXN0LnRvQXJyYXkoYXJnQXJyYXkpOworICAgICAgICBhc3NlcnROdWxsKCJGYWlsZWQgdG8gc2V0IGZpcnN0IGV4dHJhIGVsZW1lbnQgdG8gbnVsbCIsIGFyZ0FycmF5W2FsaXN0CisgICAgICAgICAgICAgICAgLnNpemUoKV0pOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoKGkgPT0gMjUpIHx8IChpID09IDc1KSkKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKCJTaG91bGQgYmUgbnVsbDogIiArIGksIHJldEFycmF5W2ldKTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgYXJyYXk6ICIgKyBpLAorICAgICAgICAgICAgICAgICAgICAgICAgcmV0QXJyYXlbaV0gPT0gb2JqQXJyYXlbaV0pOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nW10gc3RyQXJyYXkgPSBuZXcgU3RyaW5nWzEwMF07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhbGlzdC50b0FycmF5KHN0ckFycmF5KTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5U3RvcmVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlMaXN0I3RyaW1Ub1NpemUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdHJpbVRvU2l6ZV8wMSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkFycmF5TGlzdC50cmltVG9TaXplKCkKKyAgICAgICAgZm9yIChpbnQgaSA9IDk5OyBpID4gMjQ7IGktLSkKKyAgICAgICAgICAgIGFsaXN0LnJlbW92ZShpKTsKKyAgICAgICAgKChBcnJheUxpc3QpIGFsaXN0KS50cmltVG9TaXplKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHNpemUgYWZ0ZXIgdHJpbSIsIDI1LCBhbGlzdC5zaXplKCkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFsaXN0LnNpemUoKTsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVHJpbW1lZCBsaXN0IGNvbnRhaW5lZCBpbmNvcnJlY3QgZWxlbWVudHMiLCBhbGlzdAorICAgICAgICAgICAgICAgICAgICAuZ2V0KGkpID09IG9iakFycmF5W2ldKTsKKyAgICAgICAgVmVjdG9yIHYgPSBuZXcgVmVjdG9yKCk7CisgICAgICAgIHYuYWRkKCJhIik7CisgICAgdi5hZGQoImIiKTsKKyAgICAgICAgQXJyYXlMaXN0IGFsID0gbmV3IEFycmF5TGlzdCh2KTsKKyAgICAgICAgSXRlcmF0b3IgaXQgPSBhbC5pdGVyYXRvcigpOworICAgIGFsLnJlbW92ZSgwKTsKKyAgICAgICAgYWwudHJpbVRvU2l6ZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXQubmV4dCgpOworICAgICAgICAgICAgZmFpbCgic2hvdWxkIHRocm93IGEgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uIGlvb2JlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF90cmltVG9TaXplXzAyKCkgeworICAgICAgICBBcnJheUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoQXJyYXlzLmFzTGlzdChuZXcgU3RyaW5nW10geyAiYSIsICJiIiwgImMiLAorICAgICAgICAgICAgICAgICJkIiwgImUiLCAiZiIsICJnIiB9KSk7CisgICAgICAgIGxpc3QucmVtb3ZlKCJhIik7CisgICAgICAgIGxpc3QucmVtb3ZlKCJmIik7CisgICAgICAgIGxpc3QudHJpbVRvU2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0ZXN0IGphdmEudXRpbC5BcnJheUxpc3QjYWRkQWxsKGludCwgQ29sbGVjdGlvbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZEFsbCgpIHsKKyAgICAgICAgQXJyYXlMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGxpc3QuYWRkKCJvbmUiKTsKKyAgICAgICAgbGlzdC5hZGQoInR3byIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgbGlzdC5zaXplKCkpOworCisgICAgICAgIGxpc3QucmVtb3ZlKDApOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgbGlzdC5zaXplKCkpOworCisgICAgICAgIEFycmF5TGlzdCBjb2xsZWN0aW9uID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBjb2xsZWN0aW9uLmFkZCgiMSIpOworICAgICAgICBjb2xsZWN0aW9uLmFkZCgiMiIpOworICAgICAgICBjb2xsZWN0aW9uLmFkZCgiMyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgY29sbGVjdGlvbi5zaXplKCkpOworCisgICAgICAgIGxpc3QuYWRkQWxsKDAsIGNvbGxlY3Rpb24pOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgbGlzdC5zaXplKCkpOworCisgICAgICAgIGxpc3QucmVtb3ZlKDApOworICAgICAgICBsaXN0LnJlbW92ZSgwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGxpc3Quc2l6ZSgpKTsKKworICAgICAgICBjb2xsZWN0aW9uLmFkZCgiNCIpOworICAgICAgICBjb2xsZWN0aW9uLmFkZCgiNSIpOworICAgICAgICBjb2xsZWN0aW9uLmFkZCgiNiIpOworICAgICAgICBjb2xsZWN0aW9uLmFkZCgiNyIpOworICAgICAgICBjb2xsZWN0aW9uLmFkZCgiOCIpOworICAgICAgICBjb2xsZWN0aW9uLmFkZCgiOSIpOworICAgICAgICBjb2xsZWN0aW9uLmFkZCgiMTAiKTsKKyAgICAgICAgY29sbGVjdGlvbi5hZGQoIjExIik7CisgICAgICAgIGNvbGxlY3Rpb24uYWRkKCIxMiIpOworCisgICAgICAgIGFzc2VydEVxdWFscygxMiwgY29sbGVjdGlvbi5zaXplKCkpOworCisgICAgICAgIGxpc3QuYWRkQWxsKDAsIGNvbGxlY3Rpb24pOworICAgICAgICBhc3NlcnRFcXVhbHMoMTQsIGxpc3Quc2l6ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlbW92ZUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICBMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KEFycmF5cy5hc0xpc3QobmV3IFN0cmluZ1tdIHsgImEiLCAiYiIsICJjIiwKKyAgICAgICAgICAgICAgICAiZCIsICJlIiwgImYiLCAiZyIgfSkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZW1vdmVkIHdyb25nIGVsZW1lbnQgMSIsIGxpc3QucmVtb3ZlKCJhIikpOworICAgICAgICBhc3NlcnRUcnVlKCJSZW1vdmVkIHdyb25nIGVsZW1lbnQgMiIsIGxpc3QucmVtb3ZlKCJmIikpOworICAgICAgICBTdHJpbmdbXSByZXN1bHQgPSBuZXcgU3RyaW5nWzVdOworICAgICAgICBsaXN0LnRvQXJyYXkocmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmVtb3ZlZCB3cm9uZyBlbGVtZW50IDMiLCBBcnJheXMuZXF1YWxzKHJlc3VsdCwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geyAiYiIsICJjIiwgImQiLCAiZSIsICJnIiB9KSk7CisgICAgfQorCisgICAgY2xhc3MgTW9ja19BcnJheUxpc3QgZXh0ZW5kcyBBcnJheUxpc3QgeworICAgICAgICBwdWJsaWMgTW9ja19BcnJheUxpc3QoKSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmVSYW5nZShpbnQgYmVnaW4sIGludCBlbmQpIHsKKyAgICAgICAgICAgIHN1cGVyLnJlbW92ZVJhbmdlKGJlZ2luLCBlbmQpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZW1vdmVSYW5nZUlJKCkgeworICAgICAgICBNb2NrX0FycmF5TGlzdCBtYWwgPSBuZXcgTW9ja19BcnJheUxpc3QoKTsKKyAgICAgICAgbWFsLmFkZCgiYSIpOworICAgICAgICBtYWwuYWRkKCJiIik7CisgICAgICAgIG1hbC5hZGQoImMiKTsKKyAgICAgICAgbWFsLmFkZCgiZCIpOworICAgICAgICBtYWwuYWRkKCJlIik7CisgICAgICAgIG1hbC5hZGQoImYiKTsKKyAgICAgICAgbWFsLmFkZCgiZyIpOworICAgICAgICBtYWwuYWRkKCJoIik7CisKKyAgICAgICAgbWFsLnJlbW92ZVJhbmdlKDIsIDQpOworCisgICAgICAgIFN0cmluZ1tdIHJlc3VsdCA9IG5ldyBTdHJpbmdbNl07CisgICAgICAgIG1hbC50b0FycmF5KHJlc3VsdCk7CisgICAgICAgIGFzc2VydFRydWUoIlJlbW92ZWQgd3JvbmcgZWxlbWVudCAzIiwgQXJyYXlzLmVxdWFscyhyZXN1bHQsCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHsgImEiLCAiYiIsICJlIiwgImYiLCAiZyIsICJoIn0pKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFNldHMgdXAgdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBvcGVuIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzIG1ldGhvZAorICAgICAqIGlzIGNhbGxlZCBiZWZvcmUgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisKKyAgICAgICAgb2JqQXJyYXkgPSBuZXcgT2JqZWN0WzEwMF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2JqQXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG9iakFycmF5W2ldID0gbmV3IEludGVnZXIoaSk7CisgICAgICAgIH0KKworICAgICAgICBhbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvYmpBcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYWxpc3QuYWRkKG9iakFycmF5W2ldKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG9iakFycmF5ID0gbnVsbDsKKyAgICAgICAgYWxpc3QgPSBudWxsOworCisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQXJyYXlzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQXJyYXlzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJjYThlNzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9BcnJheXNUZXN0LmphdmEKQEAgLTAsMCArMSwyNDAzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29tcGFyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworCitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1VubW9kaWZpYWJsZUNvbGxlY3Rpb25UZXN0OworCitwdWJsaWMgY2xhc3MgQXJyYXlzVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFJldmVyc2VkSW50ZWdlckNvbXBhcmF0b3IgaW1wbGVtZW50cyBDb21wYXJhdG9yIHsKKyAgICAgICAgcHVibGljIGludCBjb21wYXJlKE9iamVjdCBvMSwgT2JqZWN0IG8yKSB7CisgICAgICAgICAgICByZXR1cm4gLSgoKEludGVnZXIpIG8xKS5jb21wYXJlVG8oKEludGVnZXIpIG8yKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8xLCBPYmplY3QgbzIpIHsKKyAgICAgICAgICAgIHJldHVybiAoKEludGVnZXIpIG8xKS5jb21wYXJlVG8oKEludGVnZXIpIG8yKSA9PSAwOworICAgICAgICB9CisgICAgfQorCisgICAgZmluYWwgc3RhdGljIGludCBhcnJheVNpemUgPSAxMDA7CisKKyAgICBPYmplY3RbXSBvYmpBcnJheTsKKworICAgIGJvb2xlYW5bXSBib29sZWFuQXJyYXk7CisKKyAgICBieXRlW10gYnl0ZUFycmF5OworCisgICAgY2hhcltdIGNoYXJBcnJheTsKKworICAgIGRvdWJsZVtdIGRvdWJsZUFycmF5OworCisgICAgZmxvYXRbXSBmbG9hdEFycmF5OworCisgICAgaW50W10gaW50QXJyYXk7CisKKyAgICBsb25nW10gbG9uZ0FycmF5OworCisgICAgT2JqZWN0W10gb2JqZWN0QXJyYXk7CisKKyAgICBzaG9ydFtdIHNob3J0QXJyYXk7CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI2FzTGlzdChqYXZhLmxhbmcuT2JqZWN0W10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hc0xpc3QkTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuTGlzdAorICAgICAgICAvLyBqYXZhLnV0aWwuQXJyYXlzLmFzTGlzdChqYXZhLmxhbmcuT2JqZWN0IFtdKQorICAgICAgICBMaXN0IGNvbnZlcnRlZExpc3QgPSBBcnJheXMuYXNMaXN0KG9iamVjdEFycmF5KTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIkFycmF5IGFuZCBMaXN0IGNvbnZlcnRlZCBmcm9tIGFycmF5IGRvIG5vdCBjb250YWluIGlkZW50aWNhbCBlbGVtZW50cyIsCisgICAgICAgICAgICAgICAgICAgIGNvbnZlcnRlZExpc3QuZ2V0KGNvdW50ZXIpID09IG9iamVjdEFycmF5W2NvdW50ZXJdKTsKKyAgICAgICAgfQorICAgICAgICBjb252ZXJ0ZWRMaXN0LnNldCg1MCwgbmV3IEludGVnZXIoMTAwMCkpOworICAgICAgICBhc3NlcnRUcnVlKCJzZXQvZ2V0IGRpZCBub3Qgd29yayBvbiBjb3ZlcnRlZCBsaXN0IiwgY29udmVydGVkTGlzdC5nZXQoCisgICAgICAgICAgICAgICAgNTApLmVxdWFscyhuZXcgSW50ZWdlcigxMDAwKSkpOworICAgICAgICBjb252ZXJ0ZWRMaXN0LnNldCg1MCwgbmV3IEludGVnZXIoNTApKTsKKyAgICAgICAgbmV3IFN1cHBvcnRfVW5tb2RpZmlhYmxlQ29sbGVjdGlvblRlc3QoIiIsIGNvbnZlcnRlZExpc3QpLnJ1blRlc3QoKTsKKworICAgICAgICBPYmplY3RbXSBteUFycmF5ID0gKE9iamVjdFtdKSAob2JqZWN0QXJyYXkuY2xvbmUoKSk7CisgICAgICAgIG15QXJyYXlbMzBdID0gbnVsbDsKKyAgICAgICAgbXlBcnJheVs2MF0gPSBudWxsOworICAgICAgICBjb252ZXJ0ZWRMaXN0ID0gQXJyYXlzLmFzTGlzdChteUFycmF5KTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIkFycmF5IGFuZCBMaXN0IGNvbnZlcnRlZCBmcm9tIGFycmF5IGRvIG5vdCBjb250YWluIGlkZW50aWNhbCBlbGVtZW50cyIsCisgICAgICAgICAgICAgICAgICAgIGNvbnZlcnRlZExpc3QuZ2V0KGNvdW50ZXIpID09IG15QXJyYXlbY291bnRlcl0pOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5hc0xpc3QoKE9iamVjdFtdKW51bGwpOworICAgICAgICAgICAgZmFpbCgiYXNMaXN0IHdpdGggbnVsbCBhcmcgZGlkbid0IHRocm93IE5QRSIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNiaW5hcnlTZWFyY2goYnl0ZVtdLCBieXRlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYmluYXJ5U2VhcmNoJEJCKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudXRpbC5BcnJheXMuYmluYXJ5U2VhcmNoKGJ5dGUgW10sIGJ5dGUpCisgICAgICAgIGZvciAoYnl0ZSBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQmluYXJ5IHNlYXJjaCBvbiBieXRlW10gYW5zd2VyZWQgaW5jb3JyZWN0IHBvc2l0aW9uIiwKKyAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmJpbmFyeVNlYXJjaChieXRlQXJyYXksIGNvdW50ZXIpID09IGNvdW50ZXIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkJpbmFyeSBzZWFyY2ggc3VjY2VlZGVkIGZvciB2YWx1ZSBub3QgcHJlc2VudCBpbiBhcnJheSAxIiwKKyAgICAgICAgICAgICAgICAtMSwgQXJyYXlzLmJpbmFyeVNlYXJjaChpbnRBcnJheSwgKGJ5dGUpIC0xKSk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIkJpbmFyeSBzZWFyY2ggc3VjY2VlZGVkIGZvciB2YWx1ZSBub3QgcHJlc2VudCBpbiBhcnJheSAyIiwKKyAgICAgICAgICAgICAgICBBcnJheXMuYmluYXJ5U2VhcmNoKGludEFycmF5LCAoYnl0ZSkgYXJyYXlTaXplKSA9PSAtKGFycmF5U2l6ZSArIDEpKTsKKyAgICAgICAgZm9yIChieXRlIGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgYXJyYXlTaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBieXRlQXJyYXlbY291bnRlcl0gLT0gNTA7CisgICAgICAgIGZvciAoYnl0ZSBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIkJpbmFyeSBzZWFyY2ggb24gYnl0ZVtdIGludm9sdmluZyBuZWdhdGl2ZSBudW1iZXJzIGFuc3dlcmVkIGluY29ycmVjdCBwb3NpdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIEFycmF5cy5iaW5hcnlTZWFyY2goYnl0ZUFycmF5LCAoYnl0ZSkgKGNvdW50ZXIgLSA1MCkpID09IGNvdW50ZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjYmluYXJ5U2VhcmNoKGNoYXJbXSwgY2hhcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2JpbmFyeVNlYXJjaCRDQygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuQXJyYXlzLmJpbmFyeVNlYXJjaChjaGFyIFtdLCBjaGFyKQorICAgICAgICBmb3IgKGNoYXIgY291bnRlciA9IDA7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJCaW5hcnkgc2VhcmNoIG9uIGNoYXJbXSBhbnN3ZXJlZCBpbmNvcnJlY3QgcG9zaXRpb24iLAorICAgICAgICAgICAgICAgICAgICBBcnJheXMuYmluYXJ5U2VhcmNoKGNoYXJBcnJheSwgKGNoYXIpIChjb3VudGVyICsgMSkpID09IGNvdW50ZXIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkJpbmFyeSBzZWFyY2ggc3VjY2VlZGVkIGZvciB2YWx1ZSBub3QgcHJlc2VudCBpbiBhcnJheSAxIiwKKyAgICAgICAgICAgICAgICAtMSwgQXJyYXlzLmJpbmFyeVNlYXJjaChjaGFyQXJyYXksICdcdTAwMDAnKSk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIkJpbmFyeSBzZWFyY2ggc3VjY2VlZGVkIGZvciB2YWx1ZSBub3QgcHJlc2VudCBpbiBhcnJheSAyIiwKKyAgICAgICAgICAgICAgICBBcnJheXMuYmluYXJ5U2VhcmNoKGNoYXJBcnJheSwgKGNoYXIpIChhcnJheVNpemUgKyAxKSkgPT0gLShhcnJheVNpemUgKyAxKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNiaW5hcnlTZWFyY2goZG91YmxlW10sIGRvdWJsZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2JpbmFyeVNlYXJjaCRERCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuQXJyYXlzLmJpbmFyeVNlYXJjaChkb3VibGUgW10sIGRvdWJsZSkKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJCaW5hcnkgc2VhcmNoIG9uIGRvdWJsZVtdIGFuc3dlcmVkIGluY29ycmVjdCBwb3NpdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIEFycmF5cy5iaW5hcnlTZWFyY2goZG91YmxlQXJyYXksIChkb3VibGUpIGNvdW50ZXIpID09IChkb3VibGUpIGNvdW50ZXIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkJpbmFyeSBzZWFyY2ggc3VjY2VlZGVkIGZvciB2YWx1ZSBub3QgcHJlc2VudCBpbiBhcnJheSAxIiwKKyAgICAgICAgICAgICAgICAtMSwgQXJyYXlzLmJpbmFyeVNlYXJjaChkb3VibGVBcnJheSwgKGRvdWJsZSkgLTEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiQmluYXJ5IHNlYXJjaCBzdWNjZWVkZWQgZm9yIHZhbHVlIG5vdCBwcmVzZW50IGluIGFycmF5IDIiLAorICAgICAgICAgICAgICAgIEFycmF5cy5iaW5hcnlTZWFyY2goZG91YmxlQXJyYXksIChkb3VibGUpIGFycmF5U2l6ZSkgPT0gLShhcnJheVNpemUgKyAxKSk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgYXJyYXlTaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBkb3VibGVBcnJheVtjb3VudGVyXSAtPSAoZG91YmxlKSA1MDsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJCaW5hcnkgc2VhcmNoIG9uIGRvdWJsZVtdIGludm9sdmluZyBuZWdhdGl2ZSBudW1iZXJzIGFuc3dlcmVkIGluY29ycmVjdCBwb3NpdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIEFycmF5cy5iaW5hcnlTZWFyY2goZG91YmxlQXJyYXksIChkb3VibGUpIChjb3VudGVyIC0gNTApKSA9PSAoZG91YmxlKSBjb3VudGVyKTsKKworICAgICAgICBkb3VibGVbXSBzcGVjaWFscyA9IG5ldyBkb3VibGVbXSB7IERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSwKKyAgICAgICAgICAgICAgICAtRG91YmxlLk1BWF9WQUxVRSwgLTJkLCAtRG91YmxlLk1JTl9WQUxVRSwgLTBkLCAwZCwKKyAgICAgICAgICAgICAgICBEb3VibGUuTUlOX1ZBTFVFLCAyZCwgRG91YmxlLk1BWF9WQUxVRSwKKyAgICAgICAgICAgICAgICBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFksIERvdWJsZS5OYU4gfTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzcGVjaWFscy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaW50IHJlc3VsdCA9IEFycmF5cy5iaW5hcnlTZWFyY2goc3BlY2lhbHMsIHNwZWNpYWxzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoc3BlY2lhbHNbaV0gKyAiIGludmFsaWQ6ICIgKyByZXN1bHQsIHJlc3VsdCA9PSBpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIi0xZCIsIC00LCBBcnJheXMuYmluYXJ5U2VhcmNoKHNwZWNpYWxzLCAtMWQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxZCIsIC04LCBBcnJheXMuYmluYXJ5U2VhcmNoKHNwZWNpYWxzLCAxZCkpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNiaW5hcnlTZWFyY2goZmxvYXRbXSwgZmxvYXQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9iaW5hcnlTZWFyY2gkRkYoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLkFycmF5cy5iaW5hcnlTZWFyY2goZmxvYXQgW10sIGZsb2F0KQorICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIkJpbmFyeSBzZWFyY2ggb24gZmxvYXRbXSBhbnN3ZXJlZCBpbmNvcnJlY3QgcG9zaXRpb24iLAorICAgICAgICAgICAgICAgICAgICBBcnJheXMuYmluYXJ5U2VhcmNoKGZsb2F0QXJyYXksIChmbG9hdCkgY291bnRlcikgPT0gKGZsb2F0KSBjb3VudGVyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCaW5hcnkgc2VhcmNoIHN1Y2NlZWRlZCBmb3IgdmFsdWUgbm90IHByZXNlbnQgaW4gYXJyYXkgMSIsCisgICAgICAgICAgICAgICAgLTEsIEFycmF5cy5iaW5hcnlTZWFyY2goZmxvYXRBcnJheSwgKGZsb2F0KSAtMSkpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJCaW5hcnkgc2VhcmNoIHN1Y2NlZWRlZCBmb3IgdmFsdWUgbm90IHByZXNlbnQgaW4gYXJyYXkgMiIsCisgICAgICAgICAgICAgICAgQXJyYXlzLmJpbmFyeVNlYXJjaChmbG9hdEFycmF5LCAoZmxvYXQpIGFycmF5U2l6ZSkgPT0gLShhcnJheVNpemUgKyAxKSk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgYXJyYXlTaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBmbG9hdEFycmF5W2NvdW50ZXJdIC09IChmbG9hdCkgNTA7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgYXJyYXlTaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiQmluYXJ5IHNlYXJjaCBvbiBmbG9hdFtdIGludm9sdmluZyBuZWdhdGl2ZSBudW1iZXJzIGFuc3dlcmVkIGluY29ycmVjdCBwb3NpdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIEFycmF5cy5iaW5hcnlTZWFyY2goZmxvYXRBcnJheSwgKGZsb2F0KSBjb3VudGVyIC0gNTApID09IChmbG9hdCkgY291bnRlcik7CisKKyAgICAgICAgZmxvYXRbXSBzcGVjaWFscyA9IG5ldyBmbG9hdFtdIHsgRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFksCisgICAgICAgICAgICAgICAgLUZsb2F0Lk1BWF9WQUxVRSwgLTJmLCAtRmxvYXQuTUlOX1ZBTFVFLCAtMGYsIDBmLAorICAgICAgICAgICAgICAgIEZsb2F0Lk1JTl9WQUxVRSwgMmYsIEZsb2F0Lk1BWF9WQUxVRSwgRmxvYXQuUE9TSVRJVkVfSU5GSU5JVFksCisgICAgICAgICAgICAgICAgRmxvYXQuTmFOIH07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3BlY2lhbHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGludCByZXN1bHQgPSBBcnJheXMuYmluYXJ5U2VhcmNoKHNwZWNpYWxzLCBzcGVjaWFsc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHNwZWNpYWxzW2ldICsgIiBpbnZhbGlkOiAiICsgcmVzdWx0LCByZXN1bHQgPT0gaSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCItMWYiLCAtNCwgQXJyYXlzLmJpbmFyeVNlYXJjaChzcGVjaWFscywgLTFmKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiMWYiLCAtOCwgQXJyYXlzLmJpbmFyeVNlYXJjaChzcGVjaWFscywgMWYpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI2JpbmFyeVNlYXJjaChpbnRbXSwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYmluYXJ5U2VhcmNoJElJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudXRpbC5BcnJheXMuYmluYXJ5U2VhcmNoKGludCBbXSwgaW50KQorICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQmluYXJ5IHNlYXJjaCBvbiBpbnRbXSBhbnN3ZXJlZCBpbmNvcnJlY3QgcG9zaXRpb24iLAorICAgICAgICAgICAgICAgICAgICBBcnJheXMuYmluYXJ5U2VhcmNoKGludEFycmF5LCBjb3VudGVyKSA9PSBjb3VudGVyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCaW5hcnkgc2VhcmNoIHN1Y2NlZWRlZCBmb3IgdmFsdWUgbm90IHByZXNlbnQgaW4gYXJyYXkgMSIsCisgICAgICAgICAgICAgICAgLTEsIEFycmF5cy5iaW5hcnlTZWFyY2goaW50QXJyYXksIC0xKSk7CisgICAgICAgIGFzc2VydFRydWUoIkJpbmFyeSBzZWFyY2ggc3VjY2VlZGVkIGZvciB2YWx1ZSBub3QgcHJlc2VudCBpbiBhcnJheSAyIiwKKyAgICAgICAgICAgICAgICBBcnJheXMuYmluYXJ5U2VhcmNoKGludEFycmF5LCBhcnJheVNpemUpID09IC0oYXJyYXlTaXplICsgMSkpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgaW50QXJyYXlbY291bnRlcl0gLT0gNTA7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgYXJyYXlTaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiQmluYXJ5IHNlYXJjaCBvbiBpbnRbXSBpbnZvbHZpbmcgbmVnYXRpdmUgbnVtYmVycyBhbnN3ZXJlZCBpbmNvcnJlY3QgcG9zaXRpb24iLAorICAgICAgICAgICAgICAgICAgICBBcnJheXMuYmluYXJ5U2VhcmNoKGludEFycmF5LCBjb3VudGVyIC0gNTApID09IGNvdW50ZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjYmluYXJ5U2VhcmNoKGxvbmdbXSwgbG9uZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2JpbmFyeVNlYXJjaCRKSigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuQXJyYXlzLmJpbmFyeVNlYXJjaChsb25nIFtdLCBsb25nKQorICAgICAgICBmb3IgKGxvbmcgY291bnRlciA9IDA7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkJpbmFyeSBzZWFyY2ggb24gbG9uZ1tdIGFuc3dlcmVkIGluY29ycmVjdCBwb3NpdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIEFycmF5cy5iaW5hcnlTZWFyY2gobG9uZ0FycmF5LCBjb3VudGVyKSA9PSBjb3VudGVyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCaW5hcnkgc2VhcmNoIHN1Y2NlZWRlZCBmb3IgdmFsdWUgbm90IHByZXNlbnQgaW4gYXJyYXkgMSIsCisgICAgICAgICAgICAgICAgLTEsIEFycmF5cy5iaW5hcnlTZWFyY2gobG9uZ0FycmF5LCAobG9uZykgLTEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiQmluYXJ5IHNlYXJjaCBzdWNjZWVkZWQgZm9yIHZhbHVlIG5vdCBwcmVzZW50IGluIGFycmF5IDIiLAorICAgICAgICAgICAgICAgIEFycmF5cy5iaW5hcnlTZWFyY2gobG9uZ0FycmF5LCAobG9uZykgYXJyYXlTaXplKSA9PSAtKGFycmF5U2l6ZSArIDEpKTsKKyAgICAgICAgZm9yIChsb25nIGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgYXJyYXlTaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBsb25nQXJyYXlbKGludCkgY291bnRlcl0gLT0gKGxvbmcpIDUwOworICAgICAgICBmb3IgKGxvbmcgY291bnRlciA9IDA7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJCaW5hcnkgc2VhcmNoIG9uIGxvbmdbXSBpbnZvbHZpbmcgbmVnYXRpdmUgbnVtYmVycyBhbnN3ZXJlZCBpbmNvcnJlY3QgcG9zaXRpb24iLAorICAgICAgICAgICAgICAgICAgICBBcnJheXMuYmluYXJ5U2VhcmNoKGxvbmdBcnJheSwgY291bnRlciAtIChsb25nKSA1MCkgPT0gY291bnRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNiaW5hcnlTZWFyY2goamF2YS5sYW5nLk9iamVjdFtdLAorICAgICAqICAgICAgICBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYmluYXJ5U2VhcmNoJExqYXZhX2xhbmdfT2JqZWN0TGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLkFycmF5cy5iaW5hcnlTZWFyY2goamF2YS5sYW5nLk9iamVjdAorICAgICAgICAvLyBbXSwgamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICJCaW5hcnkgc2VhcmNoIHN1Y2NlZWRlZCBmb3Igbm9uLWNvbXBhcmFibGUgdmFsdWUgaW4gZW1wdHkgYXJyYXkiLAorICAgICAgICAgICAgICAgIC0xLCBBcnJheXMuYmluYXJ5U2VhcmNoKG5ldyBPYmplY3RbXSB7fSwgbmV3IE9iamVjdCgpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAiQmluYXJ5IHNlYXJjaCBzdWNjZWVkZWQgZm9yIGNvbXBhcmFibGUgdmFsdWUgaW4gZW1wdHkgYXJyYXkiLAorICAgICAgICAgICAgICAgIC0xLCBBcnJheXMuYmluYXJ5U2VhcmNoKG5ldyBPYmplY3RbXSB7fSwgbmV3IEludGVnZXIoLTEpKSk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgYXJyYXlTaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiQmluYXJ5IHNlYXJjaCBvbiBPYmplY3RbXSBhbnN3ZXJlZCBpbmNvcnJlY3QgcG9zaXRpb24iLAorICAgICAgICAgICAgICAgICAgICBBcnJheXMuYmluYXJ5U2VhcmNoKG9iamVjdEFycmF5LCBvYmpBcnJheVtjb3VudGVyXSkgPT0gY291bnRlcik7CisgICAgICAgIGFzc2VydEVxdWFscygiQmluYXJ5IHNlYXJjaCBzdWNjZWVkZWQgZm9yIHZhbHVlIG5vdCBwcmVzZW50IGluIGFycmF5IDEiLAorICAgICAgICAgICAgICAgIC0xLCBBcnJheXMuYmluYXJ5U2VhcmNoKG9iamVjdEFycmF5LCBuZXcgSW50ZWdlcigtMSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiQmluYXJ5IHNlYXJjaCBzdWNjZWVkZWQgZm9yIHZhbHVlIG5vdCBwcmVzZW50IGluIGFycmF5IDIiLAorICAgICAgICAgICAgICAgIEFycmF5cy5iaW5hcnlTZWFyY2gob2JqZWN0QXJyYXksIG5ldyBJbnRlZ2VyKGFycmF5U2l6ZSkpID09IC0oYXJyYXlTaXplICsgMSkpOworCisgICAgICAgIFN0cmluZ1tdIHNBcnJheSA9IG5ldyBTdHJpbmdbXXsiMSIsICIyIiwgIjMiLCAiNCIsICIifTsKKyAgICAgICAgT2JqZWN0W10gb0FycmF5ID0gc0FycmF5OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuYmluYXJ5U2VhcmNoKG9BcnJheSwgbmV3IEludGVnZXIoMTApKTsKKyAgICAgICAgICAgIGZhaWwoIkNsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNiaW5hcnlTZWFyY2goamF2YS5sYW5nLk9iamVjdFtdLAorICAgICAqICAgICAgICBqYXZhLmxhbmcuT2JqZWN0LCBqYXZhLnV0aWwuQ29tcGFyYXRvcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2JpbmFyeVNlYXJjaCRMamF2YV9sYW5nX09iamVjdExqYXZhX2xhbmdfT2JqZWN0TGphdmFfdXRpbF9Db21wYXJhdG9yKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudXRpbC5BcnJheXMuYmluYXJ5U2VhcmNoKGphdmEubGFuZy5PYmplY3QKKyAgICAgICAgLy8gW10sIGphdmEubGFuZy5PYmplY3QsIGphdmEudXRpbC5Db21wYXJhdG9yKQorICAgICAgICBDb21wYXJhdG9yIGNvbXAgPSBuZXcgUmV2ZXJzZWRJbnRlZ2VyQ29tcGFyYXRvcigpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgb2JqZWN0QXJyYXlbY291bnRlcl0gPSBvYmpBcnJheVthcnJheVNpemUgLSBjb3VudGVyIC0gMV07CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIkJpbmFyeSBzZWFyY2ggc3VjY2VlZGVkIGZvciB2YWx1ZSBub3QgcHJlc2VudCBpbiBhcnJheSAxIiwKKyAgICAgICAgICAgICAgICBBcnJheXMuYmluYXJ5U2VhcmNoKG9iamVjdEFycmF5LCBuZXcgSW50ZWdlcigtMSksIGNvbXApID09IC0oYXJyYXlTaXplICsgMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkJpbmFyeSBzZWFyY2ggc3VjY2VlZGVkIGZvciB2YWx1ZSBub3QgcHJlc2VudCBpbiBhcnJheSAyIiwKKyAgICAgICAgICAgICAgICAtMSwgQXJyYXlzLmJpbmFyeVNlYXJjaChvYmplY3RBcnJheSwgbmV3IEludGVnZXIoYXJyYXlTaXplKSwgY29tcCkpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIkJpbmFyeSBzZWFyY2ggb24gT2JqZWN0W10gd2l0aCBjdXN0b20gY29tcGFyYXRvciBhbnN3ZXJlZCBpbmNvcnJlY3QgcG9zaXRpb24iLAorICAgICAgICAgICAgICAgICAgICBBcnJheXMuYmluYXJ5U2VhcmNoKG9iamVjdEFycmF5LCBvYmpBcnJheVtjb3VudGVyXSwgY29tcCkgPT0gYXJyYXlTaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBjb3VudGVyIC0gMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNiaW5hcnlTZWFyY2goc2hvcnRbXSwgc2hvcnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9iaW5hcnlTZWFyY2gkU1MoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLkFycmF5cy5iaW5hcnlTZWFyY2goc2hvcnQgW10sIHNob3J0KQorICAgICAgICBmb3IgKHNob3J0IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgYXJyYXlTaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJCaW5hcnkgc2VhcmNoIG9uIHNob3J0W10gYW5zd2VyZWQgaW5jb3JyZWN0IHBvc2l0aW9uIiwKKyAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmJpbmFyeVNlYXJjaChzaG9ydEFycmF5LCBjb3VudGVyKSA9PSBjb3VudGVyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCaW5hcnkgc2VhcmNoIHN1Y2NlZWRlZCBmb3IgdmFsdWUgbm90IHByZXNlbnQgaW4gYXJyYXkgMSIsCisgICAgICAgICAgICAgICAgLTEsIEFycmF5cy5iaW5hcnlTZWFyY2goaW50QXJyYXksIChzaG9ydCkgLTEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiQmluYXJ5IHNlYXJjaCBzdWNjZWVkZWQgZm9yIHZhbHVlIG5vdCBwcmVzZW50IGluIGFycmF5IDIiLAorICAgICAgICAgICAgICAgIEFycmF5cy5iaW5hcnlTZWFyY2goaW50QXJyYXksIChzaG9ydCkgYXJyYXlTaXplKSA9PSAtKGFycmF5U2l6ZSArIDEpKTsKKyAgICAgICAgZm9yIChzaG9ydCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgc2hvcnRBcnJheVtjb3VudGVyXSAtPSA1MDsKKyAgICAgICAgZm9yIChzaG9ydCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIkJpbmFyeSBzZWFyY2ggb24gc2hvcnRbXSBpbnZvbHZpbmcgbmVnYXRpdmUgbnVtYmVycyBhbnN3ZXJlZCBpbmNvcnJlY3QgcG9zaXRpb24iLAorICAgICAgICAgICAgICAgICAgICBBcnJheXMuYmluYXJ5U2VhcmNoKHNob3J0QXJyYXksIChzaG9ydCkgKGNvdW50ZXIgLSA1MCkpID09IGNvdW50ZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjZmlsbChieXRlW10sIGJ5dGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9maWxsJEJCKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlzLmZpbGwoYnl0ZSBbXSwgYnl0ZSkKKworICAgICAgICBieXRlIGRbXSA9IG5ldyBieXRlWzEwMDBdOworICAgICAgICBBcnJheXMuZmlsbChkLCBCeXRlLk1BWF9WQUxVRSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZC5sZW5ndGg7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBmaWxsIGJ5dGUgYXJyYXkgY29ycmVjdGx5IiwKKyAgICAgICAgICAgICAgICAgICAgZFtpXSA9PSBCeXRlLk1BWF9WQUxVRSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNmaWxsKGJ5dGVbXSwgaW50LCBpbnQsIGJ5dGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9maWxsJEJJSUIoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5BcnJheXMuZmlsbChieXRlIFtdLCBpbnQsIGludCwgYnl0ZSkKKyAgICAgICAgYnl0ZSB2YWwgPSBCeXRlLk1BWF9WQUxVRTsKKyAgICAgICAgYnl0ZSBkW10gPSBuZXcgYnl0ZVsxMDAwXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZCwgNDAwLCBkLmxlbmd0aCwgdmFsKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA0MDA7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZpbGxlZCBlbGVtZW50cyBub3QgaW4gcmFuZ2UiLCAhKGRbaV0gPT0gdmFsKSk7CisgICAgICAgIGZvciAoaW50IGkgPSA0MDA7IGkgPCBkLmxlbmd0aDsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGZpbGwgYnl0ZSBhcnJheSBjb3JyZWN0bHkiLCBkW2ldID09IHZhbCk7CisKKyAgICAgICAgaW50IHJlc3VsdDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5maWxsKG5ldyBieXRlWzJdLCAyLCAxLCAoYnl0ZSkgMjcpOworICAgICAgICAgICAgcmVzdWx0ID0gMDsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IDE7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXN1bHQgPSAyOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgZXhjZXB0aW9uMSIsIDIsIHJlc3VsdCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuZmlsbChuZXcgYnl0ZVsyXSwgLTEsIDEsIChieXRlKSAyNyk7CisgICAgICAgICAgICByZXN1bHQgPSAwOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmVzdWx0ID0gMTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IDI7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBleGNlcHRpb24yIiwgMSwgcmVzdWx0KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5maWxsKG5ldyBieXRlWzJdLCAxLCA0LCAoYnl0ZSkgMjcpOworICAgICAgICAgICAgcmVzdWx0ID0gMDsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IDE7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXN1bHQgPSAyOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgZXhjZXB0aW9uIiwgMSwgcmVzdWx0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI2ZpbGwoc2hvcnRbXSwgc2hvcnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9maWxsJFNTKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlzLmZpbGwoc2hvcnQgW10sIHNob3J0KQorCisgICAgICAgIHNob3J0IGRbXSA9IG5ldyBzaG9ydFsxMDAwXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZCwgU2hvcnQuTUFYX1ZBTFVFKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkLmxlbmd0aDsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGZpbGwgc2hvcnQgYXJyYXkgY29ycmVjdGx5IiwKKyAgICAgICAgICAgICAgICAgICAgZFtpXSA9PSBTaG9ydC5NQVhfVkFMVUUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjZmlsbChzaG9ydFtdLCBpbnQsIGludCwgc2hvcnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9maWxsJFNJSVMoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5BcnJheXMuZmlsbChzaG9ydCBbXSwgaW50LCBpbnQsIHNob3J0KQorICAgICAgICBzaG9ydCB2YWwgPSBTaG9ydC5NQVhfVkFMVUU7CisgICAgICAgIHNob3J0IGRbXSA9IG5ldyBzaG9ydFsxMDAwXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZCwgNDAwLCBkLmxlbmd0aCwgdmFsKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA0MDA7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZpbGxlZCBlbGVtZW50cyBub3QgaW4gcmFuZ2UiLCAhKGRbaV0gPT0gdmFsKSk7CisgICAgICAgIGZvciAoaW50IGkgPSA0MDA7IGkgPCBkLmxlbmd0aDsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGZpbGwgc2hvcnQgYXJyYXkgY29ycmVjdGx5IiwgZFtpXSA9PSB2YWwpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuZmlsbChkLCAxMCwgMCwgdmFsKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5maWxsKGQsIC0xMCwgMCwgdmFsKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5maWxsKGQsIDEwLCBkLmxlbmd0aCsxLCB2YWwpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI2ZpbGwoY2hhcltdLCBjaGFyKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmlsbCRDQygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkFycmF5cy5maWxsKGNoYXIgW10sIGNoYXIpCisKKyAgICAgICAgY2hhciBkW10gPSBuZXcgY2hhclsxMDAwXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZCwgJ1YnKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkLmxlbmd0aDsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gZmlsbCBjaGFyIGFycmF5IGNvcnJlY3RseSIsICdWJywgZFtpXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNmaWxsKGNoYXJbXSwgaW50LCBpbnQsIGNoYXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9maWxsJENJSUMoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5BcnJheXMuZmlsbChjaGFyIFtdLCBpbnQsIGludCwgY2hhcikKKyAgICAgICAgY2hhciB2YWwgPSAnVCc7CisgICAgICAgIGNoYXIgZFtdID0gbmV3IGNoYXJbMTAwMF07CisgICAgICAgIEFycmF5cy5maWxsKGQsIDQwMCwgZC5sZW5ndGgsIHZhbCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNDAwOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGaWxsZWQgZWxlbWVudHMgbm90IGluIHJhbmdlIiwgIShkW2ldID09IHZhbCkpOworICAgICAgICBmb3IgKGludCBpID0gNDAwOyBpIDwgZC5sZW5ndGg7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBmaWxsIGNoYXIgYXJyYXkgY29ycmVjdGx5IiwgZFtpXSA9PSB2YWwpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuZmlsbChkLCAxMCwgMCwgdmFsKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5maWxsKGQsIC0xMCwgMCwgdmFsKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5maWxsKGQsIDEwLCBkLmxlbmd0aCsxLCB2YWwpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI2ZpbGwoaW50W10sIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ZpbGwkSUkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5BcnJheXMuZmlsbChpbnQgW10sIGludCkKKworICAgICAgICBpbnQgZFtdID0gbmV3IGludFsxMDAwXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZCwgSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGQubGVuZ3RoOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmlsbCBpbnQgYXJyYXkgY29ycmVjdGx5IiwKKyAgICAgICAgICAgICAgICAgICAgZFtpXSA9PSBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNmaWxsKGludFtdLCBpbnQsIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmlsbCRJSUlJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlzLmZpbGwoaW50IFtdLCBpbnQsIGludCwgaW50KQorICAgICAgICBpbnQgdmFsID0gSW50ZWdlci5NQVhfVkFMVUU7CisgICAgICAgIGludCBkW10gPSBuZXcgaW50WzEwMDBdOworICAgICAgICBBcnJheXMuZmlsbChkLCA0MDAsIGQubGVuZ3RoLCB2YWwpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDQwMDsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmlsbGVkIGVsZW1lbnRzIG5vdCBpbiByYW5nZSIsICEoZFtpXSA9PSB2YWwpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDQwMDsgaSA8IGQubGVuZ3RoOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmlsbCBpbnQgYXJyYXkgY29ycmVjdGx5IiwgZFtpXSA9PSB2YWwpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuZmlsbChkLCAxMCwgMCwgdmFsKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5maWxsKGQsIC0xMCwgMCwgdmFsKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5maWxsKGQsIDEwLCBkLmxlbmd0aCsxLCB2YWwpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI2ZpbGwobG9uZ1tdLCBsb25nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmlsbCRKSigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkFycmF5cy5maWxsKGxvbmcgW10sIGxvbmcpCisKKyAgICAgICAgbG9uZyBkW10gPSBuZXcgbG9uZ1sxMDAwXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZCwgTG9uZy5NQVhfVkFMVUUpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGQubGVuZ3RoOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmlsbCBsb25nIGFycmF5IGNvcnJlY3RseSIsCisgICAgICAgICAgICAgICAgICAgIGRbaV0gPT0gTG9uZy5NQVhfVkFMVUUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjZmlsbChsb25nW10sIGludCwgaW50LCBsb25nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmlsbCRKSUlKKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlzLmZpbGwobG9uZyBbXSwgaW50LCBpbnQsIGxvbmcpCisgICAgICAgIGxvbmcgZFtdID0gbmV3IGxvbmdbMTAwMF07CisgICAgICAgIEFycmF5cy5maWxsKGQsIDQwMCwgZC5sZW5ndGgsIExvbmcuTUFYX1ZBTFVFKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA0MDA7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZpbGxlZCBlbGVtZW50cyBub3QgaW4gcmFuZ2UiLCAhKGRbaV0gPT0gTG9uZy5NQVhfVkFMVUUpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDQwMDsgaSA8IGQubGVuZ3RoOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmlsbCBsb25nIGFycmF5IGNvcnJlY3RseSIsCisgICAgICAgICAgICAgICAgICAgIGRbaV0gPT0gTG9uZy5NQVhfVkFMVUUpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuZmlsbChkLCAxMCwgMCwgTG9uZy5NSU5fVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLmZpbGwoZCwgLTEwLCAwLCBMb25nLk1BWF9WQUxVRSk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuZmlsbChkLCAxMCwgZC5sZW5ndGgrMSwgTG9uZy5NQVhfVkFMVUUpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI2ZpbGwoZmxvYXRbXSwgZmxvYXQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9maWxsJEZGKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlzLmZpbGwoZmxvYXQgW10sIGZsb2F0KQorICAgICAgICBmbG9hdCBkW10gPSBuZXcgZmxvYXRbMTAwMF07CisgICAgICAgIEFycmF5cy5maWxsKGQsIEZsb2F0Lk1BWF9WQUxVRSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZC5sZW5ndGg7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBmaWxsIGZsb2F0IGFycmF5IGNvcnJlY3RseSIsCisgICAgICAgICAgICAgICAgICAgIGRbaV0gPT0gRmxvYXQuTUFYX1ZBTFVFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI2ZpbGwoZmxvYXRbXSwgaW50LCBpbnQsIGZsb2F0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmlsbCRGSUlGKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlzLmZpbGwoZmxvYXQgW10sIGludCwgaW50LCBmbG9hdCkKKyAgICAgICAgZmxvYXQgdmFsID0gRmxvYXQuTUFYX1ZBTFVFOworICAgICAgICBmbG9hdCBkW10gPSBuZXcgZmxvYXRbMTAwMF07CisgICAgICAgIEFycmF5cy5maWxsKGQsIDQwMCwgZC5sZW5ndGgsIHZhbCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNDAwOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGaWxsZWQgZWxlbWVudHMgbm90IGluIHJhbmdlIiwgIShkW2ldID09IHZhbCkpOworICAgICAgICBmb3IgKGludCBpID0gNDAwOyBpIDwgZC5sZW5ndGg7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBmaWxsIGZsb2F0IGFycmF5IGNvcnJlY3RseSIsIGRbaV0gPT0gdmFsKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLmZpbGwoZCwgMTAsIDAsIHZhbCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuZmlsbChkLCAtMTAsIDAsIHZhbCk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuZmlsbChkLCAxMCwgZC5sZW5ndGgrMSwgdmFsKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNmaWxsKGRvdWJsZVtdLCBkb3VibGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9maWxsJEREKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlzLmZpbGwoZG91YmxlIFtdLCBkb3VibGUpCisKKyAgICAgICAgZG91YmxlIGRbXSA9IG5ldyBkb3VibGVbMTAwMF07CisgICAgICAgIEFycmF5cy5maWxsKGQsIERvdWJsZS5NQVhfVkFMVUUpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGQubGVuZ3RoOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmlsbCBkb3VibGUgYXJyYXkgY29ycmVjdGx5IiwKKyAgICAgICAgICAgICAgICAgICAgZFtpXSA9PSBEb3VibGUuTUFYX1ZBTFVFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI2ZpbGwoZG91YmxlW10sIGludCwgaW50LCBkb3VibGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9maWxsJERJSUQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5BcnJheXMuZmlsbChkb3VibGUgW10sIGludCwgaW50LAorICAgICAgICAvLyBkb3VibGUpCisgICAgICAgIGRvdWJsZSB2YWwgPSBEb3VibGUuTUFYX1ZBTFVFOworICAgICAgICBkb3VibGUgZFtdID0gbmV3IGRvdWJsZVsxMDAwXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZCwgNDAwLCBkLmxlbmd0aCwgdmFsKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA0MDA7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZpbGxlZCBlbGVtZW50cyBub3QgaW4gcmFuZ2UiLCAhKGRbaV0gPT0gdmFsKSk7CisgICAgICAgIGZvciAoaW50IGkgPSA0MDA7IGkgPCBkLmxlbmd0aDsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGZpbGwgZG91YmxlIGFycmF5IGNvcnJlY3RseSIsIGRbaV0gPT0gdmFsKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLmZpbGwoZCwgMTAsIDAsIHZhbCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuZmlsbChkLCAtMTAsIDAsIHZhbCk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuZmlsbChkLCAxMCwgZC5sZW5ndGgrMSwgdmFsKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNmaWxsKGJvb2xlYW5bXSwgYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2ZpbGwkWlooKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5BcnJheXMuZmlsbChib29sZWFuIFtdLCBib29sZWFuKQorCisgICAgICAgIGJvb2xlYW4gZFtdID0gbmV3IGJvb2xlYW5bMTAwMF07CisgICAgICAgIEFycmF5cy5maWxsKGQsIHRydWUpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGQubGVuZ3RoOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmlsbCBib29sZWFuIGFycmF5IGNvcnJlY3RseSIsIGRbaV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjZmlsbChib29sZWFuW10sIGludCwgaW50LCBib29sZWFuKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmlsbCRaSUlaKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlzLmZpbGwoYm9vbGVhbiBbXSwgaW50LCBpbnQsCisgICAgICAgIC8vIGJvb2xlYW4pCisgICAgICAgIGJvb2xlYW4gdmFsID0gdHJ1ZTsKKyAgICAgICAgYm9vbGVhbiBkW10gPSBuZXcgYm9vbGVhblsxMDAwXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZCwgNDAwLCBkLmxlbmd0aCwgdmFsKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA0MDA7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZpbGxlZCBlbGVtZW50cyBub3QgaW4gcmFuZ2UiLCAhKGRbaV0gPT0gdmFsKSk7CisgICAgICAgIGZvciAoaW50IGkgPSA0MDA7IGkgPCBkLmxlbmd0aDsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGZpbGwgYm9vbGVhbiBhcnJheSBjb3JyZWN0bHkiLCBkW2ldID09IHZhbCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5maWxsKGQsIDEwLCAwLCB2YWwpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLmZpbGwoZCwgLTEwLCAwLCB2YWwpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLmZpbGwoZCwgMTAsIGQubGVuZ3RoKzEsIHZhbCk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjZmlsbChqYXZhLmxhbmcuT2JqZWN0W10sIGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9maWxsJExqYXZhX2xhbmdfT2JqZWN0TGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5BcnJheXMuZmlsbChqYXZhLmxhbmcuT2JqZWN0IFtdLAorICAgICAgICAvLyBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBPYmplY3QgdmFsID0gbmV3IE9iamVjdCgpOworICAgICAgICBPYmplY3QgZFtdID0gbmV3IE9iamVjdFsxMDAwXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZCwgMCwgZC5sZW5ndGgsIHZhbCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZC5sZW5ndGg7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBmaWxsIE9iamVjdCBhcnJheSBjb3JyZWN0bHkiLCBkW2ldID09IHZhbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNmaWxsKGphdmEubGFuZy5PYmplY3RbXSwgaW50LCBpbnQsCisgICAgICogICAgICAgIGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9maWxsJExqYXZhX2xhbmdfT2JqZWN0SUlMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkFycmF5cy5maWxsKGphdmEubGFuZy5PYmplY3QgW10sIGludCwKKyAgICAgICAgLy8gaW50LCBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBPYmplY3QgdmFsID0gbmV3IE9iamVjdCgpOworICAgICAgICBPYmplY3QgZFtdID0gbmV3IE9iamVjdFsxMDAwXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZCwgNDAwLCBkLmxlbmd0aCwgdmFsKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA0MDA7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZpbGxlZCBlbGVtZW50cyBub3QgaW4gcmFuZ2UiLCAhKGRbaV0gPT0gdmFsKSk7CisgICAgICAgIGZvciAoaW50IGkgPSA0MDA7IGkgPCBkLmxlbmd0aDsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGZpbGwgT2JqZWN0IGFycmF5IGNvcnJlY3RseSIsIGRbaV0gPT0gdmFsKTsKKworICAgICAgICBBcnJheXMuZmlsbChkLCA0MDAsIGQubGVuZ3RoLCBudWxsKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDQwMDsgaSA8IGQubGVuZ3RoOyBpKyspCisgICAgICAgICAgICBhc3NlcnROdWxsKCJGYWlsZWQgdG8gZmlsbCBPYmplY3QgYXJyYXkgY29ycmVjdGx5IHdpdGggbnVsbHMiLAorICAgICAgICAgICAgICAgICAgICBkW2ldKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLmZpbGwoZCwgMTAsIDAsIHZhbCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuZmlsbChkLCAtMTAsIDAsIHZhbCk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuZmlsbChkLCAxMCwgZC5sZW5ndGgrMSwgdmFsKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNlcXVhbHMoYnl0ZVtdLCBieXRlW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9lcXVhbHMkQiRCKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyhieXRlIFtdLCBieXRlIFtdKQorICAgICAgICBieXRlIGRbXSA9IG5ldyBieXRlWzEwMDBdOworICAgICAgICBieXRlIHhbXSA9IG5ldyBieXRlWzEwMDBdOworICAgICAgICBBcnJheXMuZmlsbChkLCBCeXRlLk1BWF9WQUxVRSk7CisgICAgICAgIEFycmF5cy5maWxsKHgsIEJ5dGUuTUlOX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5lcXVhbCBhcnJheXMgcmV0dXJuZWQgdHJ1ZSIsICFBcnJheXMuZXF1YWxzKGQsIHgpKTsKKyAgICAgICAgQXJyYXlzLmZpbGwoeCwgQnl0ZS5NQVhfVkFMVUUpOworICAgICAgICBhc3NlcnRUcnVlKCJlcXVhbCBhcnJheXMgcmV0dXJuZWQgZmFsc2UiLCBBcnJheXMuZXF1YWxzKGQsIHgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI2VxdWFscyhzaG9ydFtdLCBzaG9ydFtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzJFMkUygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4gamF2YS51dGlsLkFycmF5cy5lcXVhbHMoc2hvcnQgW10sIHNob3J0IFtdKQorICAgICAgICBzaG9ydCBkW10gPSBuZXcgc2hvcnRbMTAwMF07CisgICAgICAgIHNob3J0IHhbXSA9IG5ldyBzaG9ydFsxMDAwXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZCwgU2hvcnQuTUFYX1ZBTFVFKTsKKyAgICAgICAgQXJyYXlzLmZpbGwoeCwgU2hvcnQuTUlOX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5lcXVhbCBhcnJheXMgcmV0dXJuZWQgdHJ1ZSIsICFBcnJheXMuZXF1YWxzKGQsIHgpKTsKKyAgICAgICAgQXJyYXlzLmZpbGwoeCwgU2hvcnQuTUFYX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZXF1YWwgYXJyYXlzIHJldHVybmVkIGZhbHNlIiwgQXJyYXlzLmVxdWFscyhkLCB4KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNlcXVhbHMoY2hhcltdLCBjaGFyW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9lcXVhbHMkQyRDKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyhjaGFyIFtdLCBjaGFyIFtdKQorICAgICAgICBjaGFyIGRbXSA9IG5ldyBjaGFyWzEwMDBdOworICAgICAgICBjaGFyIHhbXSA9IG5ldyBjaGFyWzEwMDBdOworICAgICAgICBjaGFyIGMgPSAnVCc7CisgICAgICAgIEFycmF5cy5maWxsKGQsIGMpOworICAgICAgICBBcnJheXMuZmlsbCh4LCAnTCcpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmVxdWFsIGFycmF5cyByZXR1cm5lZCB0cnVlIiwgIUFycmF5cy5lcXVhbHMoZCwgeCkpOworICAgICAgICBBcnJheXMuZmlsbCh4LCBjKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZXF1YWwgYXJyYXlzIHJldHVybmVkIGZhbHNlIiwgQXJyYXlzLmVxdWFscyhkLCB4KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNlcXVhbHMoaW50W10sIGludFtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzJEkkSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4gamF2YS51dGlsLkFycmF5cy5lcXVhbHMoaW50IFtdLCBpbnQgW10pCisgICAgICAgIGludCBkW10gPSBuZXcgaW50WzEwMDBdOworICAgICAgICBpbnQgeFtdID0gbmV3IGludFsxMDAwXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZCwgSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICBBcnJheXMuZmlsbCh4LCBJbnRlZ2VyLk1JTl9WQUxVRSk7CisgICAgICAgIGFzc2VydFRydWUoIkluZXF1YWwgYXJyYXlzIHJldHVybmVkIHRydWUiLCAhQXJyYXlzLmVxdWFscyhkLCB4KSk7CisgICAgICAgIEFycmF5cy5maWxsKHgsIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZXF1YWwgYXJyYXlzIHJldHVybmVkIGZhbHNlIiwgQXJyYXlzLmVxdWFscyhkLCB4KSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgid3JvbmcgcmVzdWx0IGZvciBudWxsIGFycmF5MSIsICFBcnJheXMuZXF1YWxzKG5ldyBpbnRbMl0sCisgICAgICAgICAgICAgICAgbnVsbCkpOworICAgICAgICBhc3NlcnRUcnVlKCJ3cm9uZyByZXN1bHQgZm9yIG51bGwgYXJyYXkyIiwgIUFycmF5cy5lcXVhbHMobnVsbCwKKyAgICAgICAgICAgICAgICBuZXcgaW50WzJdKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNlcXVhbHMobG9uZ1tdLCBsb25nW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9lcXVhbHMkSiRKKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyhsb25nIFtdLCBsb25nIFtdKQorICAgICAgICBsb25nIGRbXSA9IG5ldyBsb25nWzEwMDBdOworICAgICAgICBsb25nIHhbXSA9IG5ldyBsb25nWzEwMDBdOworICAgICAgICBBcnJheXMuZmlsbChkLCBMb25nLk1BWF9WQUxVRSk7CisgICAgICAgIEFycmF5cy5maWxsKHgsIExvbmcuTUlOX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5lcXVhbCBhcnJheXMgcmV0dXJuZWQgdHJ1ZSIsICFBcnJheXMuZXF1YWxzKGQsIHgpKTsKKyAgICAgICAgQXJyYXlzLmZpbGwoeCwgTG9uZy5NQVhfVkFMVUUpOworICAgICAgICBhc3NlcnRUcnVlKCJlcXVhbCBhcnJheXMgcmV0dXJuZWQgZmFsc2UiLCBBcnJheXMuZXF1YWxzKGQsIHgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJzaG91bGQgYmUgZmFsc2UiLCAhQXJyYXlzLmVxdWFscygKKyAgICAgICAgICAgICAgICBuZXcgbG9uZ1tdIHsgMHgxMDAwMDAwMDBMIH0sIG5ldyBsb25nW10geyAweDIwMDAwMDAwMEwgfSkpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNlcXVhbHMoZmxvYXRbXSwgZmxvYXRbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VxdWFscyRGJEYoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEudXRpbC5BcnJheXMuZXF1YWxzKGZsb2F0IFtdLCBmbG9hdCBbXSkKKyAgICAgICAgZmxvYXQgZFtdID0gbmV3IGZsb2F0WzEwMDBdOworICAgICAgICBmbG9hdCB4W10gPSBuZXcgZmxvYXRbMTAwMF07CisgICAgICAgIEFycmF5cy5maWxsKGQsIEZsb2F0Lk1BWF9WQUxVRSk7CisgICAgICAgIEFycmF5cy5maWxsKHgsIEZsb2F0Lk1JTl9WQUxVRSk7CisgICAgICAgIGFzc2VydFRydWUoIkluZXF1YWwgYXJyYXlzIHJldHVybmVkIHRydWUiLCAhQXJyYXlzLmVxdWFscyhkLCB4KSk7CisgICAgICAgIEFycmF5cy5maWxsKHgsIEZsb2F0Lk1BWF9WQUxVRSk7CisgICAgICAgIGFzc2VydFRydWUoImVxdWFsIGFycmF5cyByZXR1cm5lZCBmYWxzZSIsIEFycmF5cy5lcXVhbHMoZCwgeCkpOworCisgICAgICAgIGFzc2VydFRydWUoIk5hTiBub3QgZXF1YWxzIiwgQXJyYXlzLmVxdWFscyhuZXcgZmxvYXRbXSB7IEZsb2F0Lk5hTiB9LAorICAgICAgICAgICAgICAgIG5ldyBmbG9hdFtdIHsgRmxvYXQuTmFOIH0pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiMGYgZXF1YWxzIC0wZiIsICFBcnJheXMuZXF1YWxzKG5ldyBmbG9hdFtdIHsgMGYgfSwKKyAgICAgICAgICAgICAgICBuZXcgZmxvYXRbXSB7IC0wZiB9KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNlcXVhbHMoZG91YmxlW10sIGRvdWJsZVtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzJEQkRCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4gamF2YS51dGlsLkFycmF5cy5lcXVhbHMoZG91YmxlIFtdLCBkb3VibGUgW10pCisgICAgICAgIGRvdWJsZSBkW10gPSBuZXcgZG91YmxlWzEwMDBdOworICAgICAgICBkb3VibGUgeFtdID0gbmV3IGRvdWJsZVsxMDAwXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZCwgRG91YmxlLk1BWF9WQUxVRSk7CisgICAgICAgIEFycmF5cy5maWxsKHgsIERvdWJsZS5NSU5fVkFMVUUpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmVxdWFsIGFycmF5cyByZXR1cm5lZCB0cnVlIiwgIUFycmF5cy5lcXVhbHMoZCwgeCkpOworICAgICAgICBBcnJheXMuZmlsbCh4LCBEb3VibGUuTUFYX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZXF1YWwgYXJyYXlzIHJldHVybmVkIGZhbHNlIiwgQXJyYXlzLmVxdWFscyhkLCB4KSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgic2hvdWxkIGJlIGZhbHNlIiwgIUFycmF5cy5lcXVhbHMobmV3IGRvdWJsZVtdIHsgMS4wIH0sCisgICAgICAgICAgICAgICAgbmV3IGRvdWJsZVtdIHsgMi4wIH0pKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJOYU4gbm90IGVxdWFscyIsIEFycmF5cy5lcXVhbHMobmV3IGRvdWJsZVtdIHsgRG91YmxlLk5hTiB9LAorICAgICAgICAgICAgICAgIG5ldyBkb3VibGVbXSB7IERvdWJsZS5OYU4gfSkpOworICAgICAgICBhc3NlcnRUcnVlKCIwZCBlcXVhbHMgLTBkIiwgIUFycmF5cy5lcXVhbHMobmV3IGRvdWJsZVtdIHsgMGQgfSwKKyAgICAgICAgICAgICAgICBuZXcgZG91YmxlW10geyAtMGQgfSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjZXF1YWxzKGJvb2xlYW5bXSwgYm9vbGVhbltdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzJFokWigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4gamF2YS51dGlsLkFycmF5cy5lcXVhbHMoYm9vbGVhbiBbXSwgYm9vbGVhbgorICAgICAgICAvLyBbXSkKKyAgICAgICAgYm9vbGVhbiBkW10gPSBuZXcgYm9vbGVhblsxMDAwXTsKKyAgICAgICAgYm9vbGVhbiB4W10gPSBuZXcgYm9vbGVhblsxMDAwXTsKKyAgICAgICAgQXJyYXlzLmZpbGwoZCwgdHJ1ZSk7CisgICAgICAgIEFycmF5cy5maWxsKHgsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5lcXVhbCBhcnJheXMgcmV0dXJuZWQgdHJ1ZSIsICFBcnJheXMuZXF1YWxzKGQsIHgpKTsKKyAgICAgICAgQXJyYXlzLmZpbGwoeCwgdHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoImVxdWFsIGFycmF5cyByZXR1cm5lZCBmYWxzZSIsIEFycmF5cy5lcXVhbHMoZCwgeCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjZXF1YWxzKGphdmEubGFuZy5PYmplY3RbXSwgamF2YS5sYW5nLk9iamVjdFtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzJExqYXZhX2xhbmdfT2JqZWN0JExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyhqYXZhLmxhbmcuT2JqZWN0IFtdLAorICAgICAgICAvLyBqYXZhLmxhbmcuT2JqZWN0IFtdKQorICAgICAgICBPYmplY3QgZFtdID0gbmV3IE9iamVjdFsxMDAwXTsKKyAgICAgICAgT2JqZWN0IHhbXSA9IG5ldyBPYmplY3RbMTAwMF07CisgICAgICAgIE9iamVjdCBvID0gbmV3IE9iamVjdCgpOworICAgICAgICBBcnJheXMuZmlsbChkLCBvKTsKKyAgICAgICAgQXJyYXlzLmZpbGwoeCwgbmV3IE9iamVjdCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5lcXVhbCBhcnJheXMgcmV0dXJuZWQgdHJ1ZSIsICFBcnJheXMuZXF1YWxzKGQsIHgpKTsKKyAgICAgICAgQXJyYXlzLmZpbGwoeCwgbyk7CisgICAgICAgIGRbNTBdID0gbnVsbDsKKyAgICAgICAgeFs1MF0gPSBudWxsOworICAgICAgICBhc3NlcnRUcnVlKCJlcXVhbCBhcnJheXMgcmV0dXJuZWQgZmFsc2UiLCBBcnJheXMuZXF1YWxzKGQsIHgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI3NvcnQoYnl0ZVtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc29ydCRCKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlzLnNvcnQoYnl0ZSBbXSkKKyAgICAgICAgYnl0ZVtdIHJldmVyc2VkQXJyYXkgPSBuZXcgYnl0ZVthcnJheVNpemVdOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgcmV2ZXJzZWRBcnJheVtjb3VudGVyXSA9IChieXRlKSAoYXJyYXlTaXplIC0gY291bnRlciAtIDEpOworICAgICAgICBBcnJheXMuc29ydChyZXZlcnNlZEFycmF5KTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJlc3VsdGluZyBhcnJheSBub3Qgc29ydGVkIiwKKyAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZWRBcnJheVtjb3VudGVyXSA9PSAoYnl0ZSkgY291bnRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zb3J0JEJJSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkFycmF5cy5zb3J0KGJ5dGUgW10sIGludCwgaW50KQorICAgICAgICBpbnQgc3RhcnRJbmRleCA9IGFycmF5U2l6ZSAvIDQ7CisgICAgICAgIGludCBlbmRJbmRleCA9IDMgKiBhcnJheVNpemUgLyA0OworICAgICAgICBieXRlW10gcmV2ZXJzZWRBcnJheSA9IG5ldyBieXRlW2FycmF5U2l6ZV07CisgICAgICAgIGJ5dGVbXSBvcmlnaW5hbFJldmVyc2VkQXJyYXkgPSBuZXcgYnl0ZVthcnJheVNpemVdOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKSB7CisgICAgICAgICAgICByZXZlcnNlZEFycmF5W2NvdW50ZXJdID0gKGJ5dGUpIChhcnJheVNpemUgLSBjb3VudGVyIC0gMSk7CisgICAgICAgICAgICBvcmlnaW5hbFJldmVyc2VkQXJyYXlbY291bnRlcl0gPSByZXZlcnNlZEFycmF5W2NvdW50ZXJdOworICAgICAgICB9CisgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXksIHN0YXJ0SW5kZXgsIGVuZEluZGV4KTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBzdGFydEluZGV4OyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJBcnJheSBtb2RpZmllZCBvdXRzaWRlIG9mIGJvdW5kcyIsCisgICAgICAgICAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPT0gb3JpZ2luYWxSZXZlcnNlZEFycmF5W2NvdW50ZXJdKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IHN0YXJ0SW5kZXg7IGNvdW50ZXIgPCBlbmRJbmRleCAtIDE7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFycmF5IG5vdCBzb3J0ZWQgd2l0aGluIGJvdW5kcyIsCisgICAgICAgICAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPD0gcmV2ZXJzZWRBcnJheVtjb3VudGVyICsgMV0pOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gZW5kSW5kZXg7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFycmF5IG1vZGlmaWVkIG91dHNpZGUgb2YgYm91bmRzIiwKKyAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZWRBcnJheVtjb3VudGVyXSA9PSBvcmlnaW5hbFJldmVyc2VkQXJyYXlbY291bnRlcl0pOworCisgICAgICAgIC8vZXhjZXB0aW9uIHRlc3RpbmcKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXksIHN0YXJ0SW5kZXggKyAxLCBzdGFydEluZGV4KTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSwgLTEsIHN0YXJ0SW5kZXgpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkICgxKSIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSwgc3RhcnRJbmRleCwgcmV2ZXJzZWRBcnJheS5sZW5ndGggKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCAoMikiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KGNoYXJbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NvcnQkQygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkFycmF5cy5zb3J0KGNoYXIgW10pCisgICAgICAgIGNoYXJbXSByZXZlcnNlZEFycmF5ID0gbmV3IGNoYXJbYXJyYXlTaXplXTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPSAoY2hhcikgKGFycmF5U2l6ZSAtIGNvdW50ZXIgLSAxKTsKKyAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgYXJyYXlTaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXN1bHRpbmcgYXJyYXkgbm90IHNvcnRlZCIsCisgICAgICAgICAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPT0gKGNoYXIpIGNvdW50ZXIpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KGNoYXJbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zb3J0JENJSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkFycmF5cy5zb3J0KGNoYXIgW10sIGludCwgaW50KQorICAgICAgICBpbnQgc3RhcnRJbmRleCA9IGFycmF5U2l6ZSAvIDQ7CisgICAgICAgIGludCBlbmRJbmRleCA9IDMgKiBhcnJheVNpemUgLyA0OworICAgICAgICBjaGFyW10gcmV2ZXJzZWRBcnJheSA9IG5ldyBjaGFyW2FycmF5U2l6ZV07CisgICAgICAgIGNoYXJbXSBvcmlnaW5hbFJldmVyc2VkQXJyYXkgPSBuZXcgY2hhclthcnJheVNpemVdOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKSB7CisgICAgICAgICAgICByZXZlcnNlZEFycmF5W2NvdW50ZXJdID0gKGNoYXIpIChhcnJheVNpemUgLSBjb3VudGVyIC0gMSk7CisgICAgICAgICAgICBvcmlnaW5hbFJldmVyc2VkQXJyYXlbY291bnRlcl0gPSByZXZlcnNlZEFycmF5W2NvdW50ZXJdOworICAgICAgICB9CisgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXksIHN0YXJ0SW5kZXgsIGVuZEluZGV4KTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBzdGFydEluZGV4OyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJBcnJheSBtb2RpZmllZCBvdXRzaWRlIG9mIGJvdW5kcyIsCisgICAgICAgICAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPT0gb3JpZ2luYWxSZXZlcnNlZEFycmF5W2NvdW50ZXJdKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IHN0YXJ0SW5kZXg7IGNvdW50ZXIgPCBlbmRJbmRleCAtIDE7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFycmF5IG5vdCBzb3J0ZWQgd2l0aGluIGJvdW5kcyIsCisgICAgICAgICAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPD0gcmV2ZXJzZWRBcnJheVtjb3VudGVyICsgMV0pOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gZW5kSW5kZXg7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFycmF5IG1vZGlmaWVkIG91dHNpZGUgb2YgYm91bmRzIiwKKyAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZWRBcnJheVtjb3VudGVyXSA9PSBvcmlnaW5hbFJldmVyc2VkQXJyYXlbY291bnRlcl0pOworCisgICAgICAgIC8vZXhjZXB0aW9uIHRlc3RpbmcKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXksIHN0YXJ0SW5kZXggKyAxLCBzdGFydEluZGV4KTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSwgLTEsIHN0YXJ0SW5kZXgpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkICgxKSIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSwgc3RhcnRJbmRleCwgcmV2ZXJzZWRBcnJheS5sZW5ndGggKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCAoMikiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KGRvdWJsZVtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc29ydCREKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlzLnNvcnQoZG91YmxlIFtdKQorICAgICAgICBkb3VibGVbXSByZXZlcnNlZEFycmF5ID0gbmV3IGRvdWJsZVthcnJheVNpemVdOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgcmV2ZXJzZWRBcnJheVtjb3VudGVyXSA9IChkb3VibGUpIChhcnJheVNpemUgLSBjb3VudGVyIC0gMSk7CisgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXkpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmVzdWx0aW5nIGFycmF5IG5vdCBzb3J0ZWQiLAorICAgICAgICAgICAgICAgICAgICByZXZlcnNlZEFycmF5W2NvdW50ZXJdID09IChkb3VibGUpIGNvdW50ZXIpOworCisgICAgICAgIGRvdWJsZVtdIHNwZWNpYWxzMSA9IG5ldyBkb3VibGVbXSB7IERvdWJsZS5OYU4sIERvdWJsZS5NQVhfVkFMVUUsCisgICAgICAgICAgICAgICAgRG91YmxlLk1JTl9WQUxVRSwgMGQsIC0wZCwgRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLAorICAgICAgICAgICAgICAgIERvdWJsZS5ORUdBVElWRV9JTkZJTklUWSB9OworICAgICAgICBkb3VibGVbXSBzcGVjaWFsczIgPSBuZXcgZG91YmxlW10geyAwZCwgRG91YmxlLlBPU0lUSVZFX0lORklOSVRZLCAtMGQsCisgICAgICAgICAgICAgICAgRG91YmxlLk5FR0FUSVZFX0lORklOSVRZLCBEb3VibGUuTUlOX1ZBTFVFLCBEb3VibGUuTmFOLAorICAgICAgICAgICAgICAgIERvdWJsZS5NQVhfVkFMVUUgfTsKKyAgICAgICAgZG91YmxlW10gYW5zd2VyID0gbmV3IGRvdWJsZVtdIHsgRG91YmxlLk5FR0FUSVZFX0lORklOSVRZLCAtMGQsIDBkLAorICAgICAgICAgICAgICAgIERvdWJsZS5NSU5fVkFMVUUsIERvdWJsZS5NQVhfVkFMVUUsIERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSwKKyAgICAgICAgICAgICAgICBEb3VibGUuTmFOIH07CisKKyAgICAgICAgQXJyYXlzLnNvcnQoc3BlY2lhbHMxKTsKKyAgICAgICAgT2JqZWN0W10gcHJpbnQxID0gbmV3IE9iamVjdFtzcGVjaWFsczEubGVuZ3RoXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzcGVjaWFsczEubGVuZ3RoOyBpKyspCisgICAgICAgICAgICBwcmludDFbaV0gPSBuZXcgRG91YmxlKHNwZWNpYWxzMVtpXSk7CisgICAgICAgIGFzc2VydFRydWUoInNwZWNpYWxzIHNvcnQgaW5jb3JyZWN0bHkgMTogIiArIEFycmF5cy5hc0xpc3QocHJpbnQxKSwKKyAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKHNwZWNpYWxzMSwgYW5zd2VyKSk7CisKKyAgICAgICAgQXJyYXlzLnNvcnQoc3BlY2lhbHMyKTsKKyAgICAgICAgT2JqZWN0W10gcHJpbnQyID0gbmV3IE9iamVjdFtzcGVjaWFsczIubGVuZ3RoXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzcGVjaWFsczIubGVuZ3RoOyBpKyspCisgICAgICAgICAgICBwcmludDJbaV0gPSBuZXcgRG91YmxlKHNwZWNpYWxzMltpXSk7CisgICAgICAgIGFzc2VydFRydWUoInNwZWNpYWxzIHNvcnQgaW5jb3JyZWN0bHkgMjogIiArIEFycmF5cy5hc0xpc3QocHJpbnQyKSwKKyAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKHNwZWNpYWxzMiwgYW5zd2VyKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KGRvdWJsZVtdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NvcnQkRElJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlzLnNvcnQoZG91YmxlIFtdLCBpbnQsIGludCkKKyAgICAgICAgaW50IHN0YXJ0SW5kZXggPSBhcnJheVNpemUgLyA0OworICAgICAgICBpbnQgZW5kSW5kZXggPSAzICogYXJyYXlTaXplIC8gNDsKKyAgICAgICAgZG91YmxlW10gcmV2ZXJzZWRBcnJheSA9IG5ldyBkb3VibGVbYXJyYXlTaXplXTsKKyAgICAgICAgZG91YmxlW10gb3JpZ2luYWxSZXZlcnNlZEFycmF5ID0gbmV3IGRvdWJsZVthcnJheVNpemVdOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKSB7CisgICAgICAgICAgICByZXZlcnNlZEFycmF5W2NvdW50ZXJdID0gKGRvdWJsZSkgKGFycmF5U2l6ZSAtIGNvdW50ZXIgLSAxKTsKKyAgICAgICAgICAgIG9yaWdpbmFsUmV2ZXJzZWRBcnJheVtjb3VudGVyXSA9IHJldmVyc2VkQXJyYXlbY291bnRlcl07CisgICAgICAgIH0KKyAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSwgc3RhcnRJbmRleCwgZW5kSW5kZXgpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IHN0YXJ0SW5kZXg7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFycmF5IG1vZGlmaWVkIG91dHNpZGUgb2YgYm91bmRzIiwKKyAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZWRBcnJheVtjb3VudGVyXSA9PSBvcmlnaW5hbFJldmVyc2VkQXJyYXlbY291bnRlcl0pOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gc3RhcnRJbmRleDsgY291bnRlciA8IGVuZEluZGV4IC0gMTsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQXJyYXkgbm90IHNvcnRlZCB3aXRoaW4gYm91bmRzIiwKKyAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZWRBcnJheVtjb3VudGVyXSA8PSByZXZlcnNlZEFycmF5W2NvdW50ZXIgKyAxXSk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSBlbmRJbmRleDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQXJyYXkgbW9kaWZpZWQgb3V0c2lkZSBvZiBib3VuZHMiLAorICAgICAgICAgICAgICAgICAgICByZXZlcnNlZEFycmF5W2NvdW50ZXJdID09IG9yaWdpbmFsUmV2ZXJzZWRBcnJheVtjb3VudGVyXSk7CisKKyAgICAgICAgLy9leGNlcHRpb24gdGVzdGluZworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSwgc3RhcnRJbmRleCArIDEsIHN0YXJ0SW5kZXgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZ25vcmUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuc29ydChyZXZlcnNlZEFycmF5LCAtMSwgc3RhcnRJbmRleCk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQgKDEpIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZ25vcmUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuc29ydChyZXZlcnNlZEFycmF5LCBzdGFydEluZGV4LCByZXZlcnNlZEFycmF5Lmxlbmd0aCArIDEpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkICgyKSIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI3NvcnQoZmxvYXRbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NvcnQkRigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkFycmF5cy5zb3J0KGZsb2F0IFtdKQorICAgICAgICBmbG9hdFtdIHJldmVyc2VkQXJyYXkgPSBuZXcgZmxvYXRbYXJyYXlTaXplXTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPSAoZmxvYXQpIChhcnJheVNpemUgLSBjb3VudGVyIC0gMSk7CisgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXkpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmVzdWx0aW5nIGFycmF5IG5vdCBzb3J0ZWQiLAorICAgICAgICAgICAgICAgICAgICByZXZlcnNlZEFycmF5W2NvdW50ZXJdID09IChmbG9hdCkgY291bnRlcik7CisKKyAgICAgICAgZmxvYXRbXSBzcGVjaWFsczEgPSBuZXcgZmxvYXRbXSB7IEZsb2F0Lk5hTiwgRmxvYXQuTUFYX1ZBTFVFLAorICAgICAgICAgICAgICAgIEZsb2F0Lk1JTl9WQUxVRSwgMGYsIC0wZiwgRmxvYXQuUE9TSVRJVkVfSU5GSU5JVFksCisgICAgICAgICAgICAgICAgRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFkgfTsKKyAgICAgICAgZmxvYXRbXSBzcGVjaWFsczIgPSBuZXcgZmxvYXRbXSB7IDBmLCBGbG9hdC5QT1NJVElWRV9JTkZJTklUWSwgLTBmLAorICAgICAgICAgICAgICAgIEZsb2F0Lk5FR0FUSVZFX0lORklOSVRZLCBGbG9hdC5NSU5fVkFMVUUsIEZsb2F0Lk5hTiwKKyAgICAgICAgICAgICAgICBGbG9hdC5NQVhfVkFMVUUgfTsKKyAgICAgICAgZmxvYXRbXSBhbnN3ZXIgPSBuZXcgZmxvYXRbXSB7IEZsb2F0Lk5FR0FUSVZFX0lORklOSVRZLCAtMGYsIDBmLAorICAgICAgICAgICAgICAgIEZsb2F0Lk1JTl9WQUxVRSwgRmxvYXQuTUFYX1ZBTFVFLCBGbG9hdC5QT1NJVElWRV9JTkZJTklUWSwKKyAgICAgICAgICAgICAgICBGbG9hdC5OYU4gfTsKKworICAgICAgICBBcnJheXMuc29ydChzcGVjaWFsczEpOworICAgICAgICBPYmplY3RbXSBwcmludDEgPSBuZXcgT2JqZWN0W3NwZWNpYWxzMS5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNwZWNpYWxzMS5sZW5ndGg7IGkrKykKKyAgICAgICAgICAgIHByaW50MVtpXSA9IG5ldyBGbG9hdChzcGVjaWFsczFbaV0pOworICAgICAgICBhc3NlcnRUcnVlKCJzcGVjaWFscyBzb3J0IGluY29ycmVjdGx5IDE6ICIgKyBBcnJheXMuYXNMaXN0KHByaW50MSksCisgICAgICAgICAgICAgICAgQXJyYXlzLmVxdWFscyhzcGVjaWFsczEsIGFuc3dlcikpOworCisgICAgICAgIEFycmF5cy5zb3J0KHNwZWNpYWxzMik7CisgICAgICAgIE9iamVjdFtdIHByaW50MiA9IG5ldyBPYmplY3Rbc3BlY2lhbHMyLmxlbmd0aF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3BlY2lhbHMyLmxlbmd0aDsgaSsrKQorICAgICAgICAgICAgcHJpbnQyW2ldID0gbmV3IEZsb2F0KHNwZWNpYWxzMltpXSk7CisgICAgICAgIGFzc2VydFRydWUoInNwZWNpYWxzIHNvcnQgaW5jb3JyZWN0bHkgMjogIiArIEFycmF5cy5hc0xpc3QocHJpbnQyKSwKKyAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKHNwZWNpYWxzMiwgYW5zd2VyKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KGZsb2F0W10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc29ydCRGSUkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5BcnJheXMuc29ydChmbG9hdCBbXSwgaW50LCBpbnQpCisgICAgICAgIGludCBzdGFydEluZGV4ID0gYXJyYXlTaXplIC8gNDsKKyAgICAgICAgaW50IGVuZEluZGV4ID0gMyAqIGFycmF5U2l6ZSAvIDQ7CisgICAgICAgIGZsb2F0W10gcmV2ZXJzZWRBcnJheSA9IG5ldyBmbG9hdFthcnJheVNpemVdOworICAgICAgICBmbG9hdFtdIG9yaWdpbmFsUmV2ZXJzZWRBcnJheSA9IG5ldyBmbG9hdFthcnJheVNpemVdOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKSB7CisgICAgICAgICAgICByZXZlcnNlZEFycmF5W2NvdW50ZXJdID0gKGZsb2F0KSAoYXJyYXlTaXplIC0gY291bnRlciAtIDEpOworICAgICAgICAgICAgb3JpZ2luYWxSZXZlcnNlZEFycmF5W2NvdW50ZXJdID0gcmV2ZXJzZWRBcnJheVtjb3VudGVyXTsKKyAgICAgICAgfQorICAgICAgICBBcnJheXMuc29ydChyZXZlcnNlZEFycmF5LCBzdGFydEluZGV4LCBlbmRJbmRleCk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgc3RhcnRJbmRleDsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQXJyYXkgbW9kaWZpZWQgb3V0c2lkZSBvZiBib3VuZHMiLAorICAgICAgICAgICAgICAgICAgICByZXZlcnNlZEFycmF5W2NvdW50ZXJdID09IG9yaWdpbmFsUmV2ZXJzZWRBcnJheVtjb3VudGVyXSk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSBzdGFydEluZGV4OyBjb3VudGVyIDwgZW5kSW5kZXggLSAxOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJBcnJheSBub3Qgc29ydGVkIHdpdGhpbiBib3VuZHMiLAorICAgICAgICAgICAgICAgICAgICByZXZlcnNlZEFycmF5W2NvdW50ZXJdIDw9IHJldmVyc2VkQXJyYXlbY291bnRlciArIDFdKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IGVuZEluZGV4OyBjb3VudGVyIDwgYXJyYXlTaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJBcnJheSBtb2RpZmllZCBvdXRzaWRlIG9mIGJvdW5kcyIsCisgICAgICAgICAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPT0gb3JpZ2luYWxSZXZlcnNlZEFycmF5W2NvdW50ZXJdKTsKKworICAgICAgICAvL2V4Y2VwdGlvbiB0ZXN0aW5nCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuc29ydChyZXZlcnNlZEFycmF5LCBzdGFydEluZGV4ICsgMSwgc3RhcnRJbmRleCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXksIC0xLCBzdGFydEluZGV4KTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCAoMSkiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXksIHN0YXJ0SW5kZXgsIHJldmVyc2VkQXJyYXkubGVuZ3RoICsgMSk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQgKDIpIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZ25vcmUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjc29ydChpbnRbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NvcnQkSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkFycmF5cy5zb3J0KGludCBbXSkKKyAgICAgICAgaW50W10gcmV2ZXJzZWRBcnJheSA9IG5ldyBpbnRbYXJyYXlTaXplXTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPSBhcnJheVNpemUgLSBjb3VudGVyIC0gMTsKKyAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgYXJyYXlTaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXN1bHRpbmcgYXJyYXkgbm90IHNvcnRlZCIsCisgICAgICAgICAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPT0gY291bnRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KGludFtdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NvcnQkSUlJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlzLnNvcnQoaW50IFtdLCBpbnQsIGludCkKKyAgICAgICAgaW50IHN0YXJ0SW5kZXggPSBhcnJheVNpemUgLyA0OworICAgICAgICBpbnQgZW5kSW5kZXggPSAzICogYXJyYXlTaXplIC8gNDsKKyAgICAgICAgaW50W10gcmV2ZXJzZWRBcnJheSA9IG5ldyBpbnRbYXJyYXlTaXplXTsKKyAgICAgICAgaW50W10gb3JpZ2luYWxSZXZlcnNlZEFycmF5ID0gbmV3IGludFthcnJheVNpemVdOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKSB7CisgICAgICAgICAgICByZXZlcnNlZEFycmF5W2NvdW50ZXJdID0gYXJyYXlTaXplIC0gY291bnRlciAtIDE7CisgICAgICAgICAgICBvcmlnaW5hbFJldmVyc2VkQXJyYXlbY291bnRlcl0gPSByZXZlcnNlZEFycmF5W2NvdW50ZXJdOworICAgICAgICB9CisgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXksIHN0YXJ0SW5kZXgsIGVuZEluZGV4KTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBzdGFydEluZGV4OyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJBcnJheSBtb2RpZmllZCBvdXRzaWRlIG9mIGJvdW5kcyIsCisgICAgICAgICAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPT0gb3JpZ2luYWxSZXZlcnNlZEFycmF5W2NvdW50ZXJdKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IHN0YXJ0SW5kZXg7IGNvdW50ZXIgPCBlbmRJbmRleCAtIDE7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFycmF5IG5vdCBzb3J0ZWQgd2l0aGluIGJvdW5kcyIsCisgICAgICAgICAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPD0gcmV2ZXJzZWRBcnJheVtjb3VudGVyICsgMV0pOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gZW5kSW5kZXg7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFycmF5IG1vZGlmaWVkIG91dHNpZGUgb2YgYm91bmRzIiwKKyAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZWRBcnJheVtjb3VudGVyXSA9PSBvcmlnaW5hbFJldmVyc2VkQXJyYXlbY291bnRlcl0pOworCisgICAgICAgIC8vZXhjZXB0aW9uIHRlc3RpbmcKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXksIHN0YXJ0SW5kZXggKyAxLCBzdGFydEluZGV4KTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSwgLTEsIHN0YXJ0SW5kZXgpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkICgxKSIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSwgc3RhcnRJbmRleCwgcmV2ZXJzZWRBcnJheS5sZW5ndGggKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCAoMikiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KGxvbmdbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NvcnQkSigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkFycmF5cy5zb3J0KGxvbmcgW10pCisgICAgICAgIGxvbmdbXSByZXZlcnNlZEFycmF5ID0gbmV3IGxvbmdbYXJyYXlTaXplXTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPSAobG9uZykgKGFycmF5U2l6ZSAtIGNvdW50ZXIgLSAxKTsKKyAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgYXJyYXlTaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXN1bHRpbmcgYXJyYXkgbm90IHNvcnRlZCIsCisgICAgICAgICAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPT0gKGxvbmcpIGNvdW50ZXIpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KGxvbmdbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zb3J0JEpJSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkFycmF5cy5zb3J0KGxvbmcgW10sIGludCwgaW50KQorICAgICAgICBpbnQgc3RhcnRJbmRleCA9IGFycmF5U2l6ZSAvIDQ7CisgICAgICAgIGludCBlbmRJbmRleCA9IDMgKiBhcnJheVNpemUgLyA0OworICAgICAgICBsb25nW10gcmV2ZXJzZWRBcnJheSA9IG5ldyBsb25nW2FycmF5U2l6ZV07CisgICAgICAgIGxvbmdbXSBvcmlnaW5hbFJldmVyc2VkQXJyYXkgPSBuZXcgbG9uZ1thcnJheVNpemVdOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKSB7CisgICAgICAgICAgICByZXZlcnNlZEFycmF5W2NvdW50ZXJdID0gKGxvbmcpIChhcnJheVNpemUgLSBjb3VudGVyIC0gMSk7CisgICAgICAgICAgICBvcmlnaW5hbFJldmVyc2VkQXJyYXlbY291bnRlcl0gPSByZXZlcnNlZEFycmF5W2NvdW50ZXJdOworICAgICAgICB9CisgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXksIHN0YXJ0SW5kZXgsIGVuZEluZGV4KTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBzdGFydEluZGV4OyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJBcnJheSBtb2RpZmllZCBvdXRzaWRlIG9mIGJvdW5kcyIsCisgICAgICAgICAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPT0gb3JpZ2luYWxSZXZlcnNlZEFycmF5W2NvdW50ZXJdKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IHN0YXJ0SW5kZXg7IGNvdW50ZXIgPCBlbmRJbmRleCAtIDE7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFycmF5IG5vdCBzb3J0ZWQgd2l0aGluIGJvdW5kcyIsCisgICAgICAgICAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPD0gcmV2ZXJzZWRBcnJheVtjb3VudGVyICsgMV0pOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gZW5kSW5kZXg7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFycmF5IG1vZGlmaWVkIG91dHNpZGUgb2YgYm91bmRzIiwKKyAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZWRBcnJheVtjb3VudGVyXSA9PSBvcmlnaW5hbFJldmVyc2VkQXJyYXlbY291bnRlcl0pOworCisgICAgICAgIC8vZXhjZXB0aW9uIHRlc3RpbmcKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXksIHN0YXJ0SW5kZXggKyAxLCBzdGFydEluZGV4KTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSwgLTEsIHN0YXJ0SW5kZXgpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkICgxKSIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSwgc3RhcnRJbmRleCwgcmV2ZXJzZWRBcnJheS5sZW5ndGggKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCAoMikiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KGphdmEubGFuZy5PYmplY3RbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NvcnQkTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5BcnJheXMuc29ydChqYXZhLmxhbmcuT2JqZWN0IFtdKQorICAgICAgICBPYmplY3RbXSByZXZlcnNlZEFycmF5ID0gbmV3IE9iamVjdFthcnJheVNpemVdOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgcmV2ZXJzZWRBcnJheVtjb3VudGVyXSA9IG9iamVjdEFycmF5W2FycmF5U2l6ZSAtIGNvdW50ZXIgLSAxXTsKKyAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgYXJyYXlTaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXN1bHRpbmcgYXJyYXkgbm90IHNvcnRlZCIsCisgICAgICAgICAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPT0gb2JqZWN0QXJyYXlbY291bnRlcl0pOworCisgICAgICAgIEFycmF5cy5maWxsKHJldmVyc2VkQXJyYXksIDAsIHJldmVyc2VkQXJyYXkubGVuZ3RoLzIsICJTdHJpbmciKTsKKyAgICAgICAgQXJyYXlzLmZpbGwocmV2ZXJzZWRBcnJheSwgcmV2ZXJzZWRBcnJheS5sZW5ndGgvMiwgcmV2ZXJzZWRBcnJheS5sZW5ndGgsIG5ldyBJbnRlZ2VyKDEpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSk7CisgICAgICAgICAgICBmYWlsKCJDbGFzc0Nhc3RFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjc29ydChqYXZhLmxhbmcuT2JqZWN0W10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc29ydCRMamF2YV9sYW5nX09iamVjdElJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlzLnNvcnQoamF2YS5sYW5nLk9iamVjdCBbXSwgaW50LAorICAgICAgICAvLyBpbnQpCisgICAgICAgIGludCBzdGFydEluZGV4ID0gYXJyYXlTaXplIC8gNDsKKyAgICAgICAgaW50IGVuZEluZGV4ID0gMyAqIGFycmF5U2l6ZSAvIDQ7CisgICAgICAgIE9iamVjdFtdIHJldmVyc2VkQXJyYXkgPSBuZXcgT2JqZWN0W2FycmF5U2l6ZV07CisgICAgICAgIE9iamVjdFtdIG9yaWdpbmFsUmV2ZXJzZWRBcnJheSA9IG5ldyBPYmplY3RbYXJyYXlTaXplXTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykgeworICAgICAgICAgICAgcmV2ZXJzZWRBcnJheVtjb3VudGVyXSA9IG9iamVjdEFycmF5W2FycmF5U2l6ZSAtIGNvdW50ZXIgLSAxXTsKKyAgICAgICAgICAgIG9yaWdpbmFsUmV2ZXJzZWRBcnJheVtjb3VudGVyXSA9IHJldmVyc2VkQXJyYXlbY291bnRlcl07CisgICAgICAgIH0KKyAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSwgc3RhcnRJbmRleCwgZW5kSW5kZXgpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IHN0YXJ0SW5kZXg7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFycmF5IG1vZGlmaWVkIG91dHNpZGUgb2YgYm91bmRzIiwKKyAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZWRBcnJheVtjb3VudGVyXSA9PSBvcmlnaW5hbFJldmVyc2VkQXJyYXlbY291bnRlcl0pOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gc3RhcnRJbmRleDsgY291bnRlciA8IGVuZEluZGV4IC0gMTsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQXJyYXkgbm90IHNvcnRlZCB3aXRoaW4gYm91bmRzIiwKKyAgICAgICAgICAgICAgICAgICAgKChDb21wYXJhYmxlKSByZXZlcnNlZEFycmF5W2NvdW50ZXJdKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb21wYXJlVG8ocmV2ZXJzZWRBcnJheVtjb3VudGVyICsgMV0pIDw9IDApOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gZW5kSW5kZXg7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFycmF5IG1vZGlmaWVkIG91dHNpZGUgb2YgYm91bmRzIiwKKyAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZWRBcnJheVtjb3VudGVyXSA9PSBvcmlnaW5hbFJldmVyc2VkQXJyYXlbY291bnRlcl0pOworCisgICAgICAgIC8vZXhjZXB0aW9uIHRlc3RpbmcKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXksIHN0YXJ0SW5kZXggKyAxLCBzdGFydEluZGV4KTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSwgLTEsIHN0YXJ0SW5kZXgpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkICgxKSIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSwgc3RhcnRJbmRleCwgcmV2ZXJzZWRBcnJheS5sZW5ndGggKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCAoMikiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICB9CisKKyAgICAgICAgQXJyYXlzLmZpbGwocmV2ZXJzZWRBcnJheSwgMCwgcmV2ZXJzZWRBcnJheS5sZW5ndGgvMiwgIlN0cmluZyIpOworICAgICAgICBBcnJheXMuZmlsbChyZXZlcnNlZEFycmF5LCByZXZlcnNlZEFycmF5Lmxlbmd0aC8yLCByZXZlcnNlZEFycmF5Lmxlbmd0aCwgbmV3IEludGVnZXIoMSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuc29ydChyZXZlcnNlZEFycmF5LCByZXZlcnNlZEFycmF5Lmxlbmd0aC80LCAzKnJldmVyc2VkQXJyYXkubGVuZ3RoLzQpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBBcnJheXMuc29ydChyZXZlcnNlZEFycmF5LCAwLCByZXZlcnNlZEFycmF5Lmxlbmd0aC80KTsKKyAgICAgICAgQXJyYXlzLnNvcnQocmV2ZXJzZWRBcnJheSwgMypyZXZlcnNlZEFycmF5Lmxlbmd0aC80LCByZXZlcnNlZEFycmF5Lmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KGphdmEubGFuZy5PYmplY3RbXSwgaW50LCBpbnQsCisgICAgICogICAgICAgIGphdmEudXRpbC5Db21wYXJhdG9yKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc29ydCRMamF2YV9sYW5nX09iamVjdElJTGphdmFfdXRpbF9Db21wYXJhdG9yKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlzLnNvcnQoamF2YS5sYW5nLk9iamVjdCBbXSwgaW50LAorICAgICAgICAvLyBpbnQsIGphdmEudXRpbC5Db21wYXJhdG9yKQorICAgICAgICBpbnQgc3RhcnRJbmRleCA9IGFycmF5U2l6ZSAvIDQ7CisgICAgICAgIGludCBlbmRJbmRleCA9IDMgKiBhcnJheVNpemUgLyA0OworICAgICAgICBSZXZlcnNlZEludGVnZXJDb21wYXJhdG9yIGNvbXAgPSBuZXcgUmV2ZXJzZWRJbnRlZ2VyQ29tcGFyYXRvcigpOworICAgICAgICBPYmplY3RbXSBvcmlnaW5hbEFycmF5ID0gbmV3IE9iamVjdFthcnJheVNpemVdOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgb3JpZ2luYWxBcnJheVtjb3VudGVyXSA9IG9iamVjdEFycmF5W2NvdW50ZXJdOworICAgICAgICBBcnJheXMuc29ydChvYmplY3RBcnJheSwgc3RhcnRJbmRleCwgZW5kSW5kZXgsIGNvbXApOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IHN0YXJ0SW5kZXg7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFycmF5IG1vZGlmaWVkIG91dHNpZGUgb2YgYm91bmRzIiwKKyAgICAgICAgICAgICAgICAgICAgb2JqZWN0QXJyYXlbY291bnRlcl0gPT0gb3JpZ2luYWxBcnJheVtjb3VudGVyXSk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSBzdGFydEluZGV4OyBjb3VudGVyIDwgZW5kSW5kZXggLSAxOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJBcnJheSBub3Qgc29ydGVkIHdpdGhpbiBib3VuZHMiLCBjb21wLmNvbXBhcmUoCisgICAgICAgICAgICAgICAgICAgIG9iamVjdEFycmF5W2NvdW50ZXJdLCBvYmplY3RBcnJheVtjb3VudGVyICsgMV0pIDw9IDApOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gZW5kSW5kZXg7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFycmF5IG1vZGlmaWVkIG91dHNpZGUgb2YgYm91bmRzIiwKKyAgICAgICAgICAgICAgICAgICAgb2JqZWN0QXJyYXlbY291bnRlcl0gPT0gb3JpZ2luYWxBcnJheVtjb3VudGVyXSk7CisKKyAgICAgICAgQXJyYXlzLmZpbGwob3JpZ2luYWxBcnJheSwgMCwgb3JpZ2luYWxBcnJheS5sZW5ndGgvMiwgIlN0cmluZyIpOworICAgICAgICBBcnJheXMuZmlsbChvcmlnaW5hbEFycmF5LCBvcmlnaW5hbEFycmF5Lmxlbmd0aC8yLCBvcmlnaW5hbEFycmF5Lmxlbmd0aCwgbmV3IEludGVnZXIoMSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuc29ydChvcmlnaW5hbEFycmF5LCBzdGFydEluZGV4LCBlbmRJbmRleCwgY29tcCk7CisgICAgICAgICAgICBmYWlsKCJDbGFzc0Nhc3RFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIEFycmF5cy5zb3J0KG9yaWdpbmFsQXJyYXksIGVuZEluZGV4LCBvcmlnaW5hbEFycmF5Lmxlbmd0aCwgY29tcCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5zb3J0KG9yaWdpbmFsQXJyYXksIGVuZEluZGV4LCBvcmlnaW5hbEFycmF5Lmxlbmd0aCArIDEsIGNvbXApOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2goQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuc29ydChvcmlnaW5hbEFycmF5LCAtMSwgc3RhcnRJbmRleCwgY29tcCk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5zb3J0KG9yaWdpbmFsQXJyYXksIG9yaWdpbmFsQXJyYXkubGVuZ3RoLCBlbmRJbmRleCwgY29tcCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KGphdmEubGFuZy5PYmplY3RbXSwgamF2YS51dGlsLkNvbXBhcmF0b3IpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zb3J0JExqYXZhX2xhbmdfT2JqZWN0TGphdmFfdXRpbF9Db21wYXJhdG9yKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQXJyYXlzLnNvcnQoamF2YS5sYW5nLk9iamVjdCBbXSwKKyAgICAgICAgLy8gamF2YS51dGlsLkNvbXBhcmF0b3IpCisgICAgICAgIFJldmVyc2VkSW50ZWdlckNvbXBhcmF0b3IgY29tcCA9IG5ldyBSZXZlcnNlZEludGVnZXJDb21wYXJhdG9yKCk7CisgICAgICAgIEFycmF5cy5zb3J0KG9iamVjdEFycmF5LCBjb21wKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBhcnJheVNpemUgLSAxOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJBcnJheSBub3Qgc29ydGVkIGNvcnJlY3RseSB3aXRoIGN1c3RvbSBjb21wYXJhdG9yIiwKKyAgICAgICAgICAgICAgICAgICAgY29tcAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb21wYXJlKG9iamVjdEFycmF5W2NvdW50ZXJdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0QXJyYXlbY291bnRlciArIDFdKSA8PSAwKTsKKworICAgICAgICBBcnJheXMuZmlsbChvYmplY3RBcnJheSwgMCwgb2JqZWN0QXJyYXkubGVuZ3RoLzIsICJTdHJpbmciKTsKKyAgICAgICAgQXJyYXlzLmZpbGwob2JqZWN0QXJyYXksIG9iamVjdEFycmF5Lmxlbmd0aC8yLCBvYmplY3RBcnJheS5sZW5ndGgsIG5ldyBJbnRlZ2VyKDEpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXJyYXlzLnNvcnQob2JqZWN0QXJyYXksIGNvbXApOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI3NvcnQoc2hvcnRbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NvcnQkUygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkFycmF5cy5zb3J0KHNob3J0IFtdKQorICAgICAgICBzaG9ydFtdIHJldmVyc2VkQXJyYXkgPSBuZXcgc2hvcnRbYXJyYXlTaXplXTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBhcnJheVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPSAoc2hvcnQpIChhcnJheVNpemUgLSBjb3VudGVyIC0gMSk7CisgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXkpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmVzdWx0aW5nIGFycmF5IG5vdCBzb3J0ZWQiLAorICAgICAgICAgICAgICAgICAgICByZXZlcnNlZEFycmF5W2NvdW50ZXJdID09IChzaG9ydCkgY291bnRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KHNob3J0W10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc29ydCRTSUkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5BcnJheXMuc29ydChzaG9ydCBbXSwgaW50LCBpbnQpCisgICAgICAgIGludCBzdGFydEluZGV4ID0gYXJyYXlTaXplIC8gNDsKKyAgICAgICAgaW50IGVuZEluZGV4ID0gMyAqIGFycmF5U2l6ZSAvIDQ7CisgICAgICAgIHNob3J0W10gcmV2ZXJzZWRBcnJheSA9IG5ldyBzaG9ydFthcnJheVNpemVdOworICAgICAgICBzaG9ydFtdIG9yaWdpbmFsUmV2ZXJzZWRBcnJheSA9IG5ldyBzaG9ydFthcnJheVNpemVdOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlcisrKSB7CisgICAgICAgICAgICByZXZlcnNlZEFycmF5W2NvdW50ZXJdID0gKHNob3J0KSAoYXJyYXlTaXplIC0gY291bnRlciAtIDEpOworICAgICAgICAgICAgb3JpZ2luYWxSZXZlcnNlZEFycmF5W2NvdW50ZXJdID0gcmV2ZXJzZWRBcnJheVtjb3VudGVyXTsKKyAgICAgICAgfQorICAgICAgICBBcnJheXMuc29ydChyZXZlcnNlZEFycmF5LCBzdGFydEluZGV4LCBlbmRJbmRleCk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgc3RhcnRJbmRleDsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQXJyYXkgbW9kaWZpZWQgb3V0c2lkZSBvZiBib3VuZHMiLAorICAgICAgICAgICAgICAgICAgICByZXZlcnNlZEFycmF5W2NvdW50ZXJdID09IG9yaWdpbmFsUmV2ZXJzZWRBcnJheVtjb3VudGVyXSk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSBzdGFydEluZGV4OyBjb3VudGVyIDwgZW5kSW5kZXggLSAxOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJBcnJheSBub3Qgc29ydGVkIHdpdGhpbiBib3VuZHMiLAorICAgICAgICAgICAgICAgICAgICByZXZlcnNlZEFycmF5W2NvdW50ZXJdIDw9IHJldmVyc2VkQXJyYXlbY291bnRlciArIDFdKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IGVuZEluZGV4OyBjb3VudGVyIDwgYXJyYXlTaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJBcnJheSBtb2RpZmllZCBvdXRzaWRlIG9mIGJvdW5kcyIsCisgICAgICAgICAgICAgICAgICAgIHJldmVyc2VkQXJyYXlbY291bnRlcl0gPT0gb3JpZ2luYWxSZXZlcnNlZEFycmF5W2NvdW50ZXJdKTsKKworICAgICAgICAvL2V4Y2VwdGlvbiB0ZXN0aW5nCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBcnJheXMuc29ydChyZXZlcnNlZEFycmF5LCBzdGFydEluZGV4ICsgMSwgc3RhcnRJbmRleCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXksIC0xLCBzdGFydEluZGV4KTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCAoMSkiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEFycmF5cy5zb3J0KHJldmVyc2VkQXJyYXksIHN0YXJ0SW5kZXgsIHJldmVyc2VkQXJyYXkubGVuZ3RoICsgMSk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQgKDIpIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZ25vcmUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjc29ydChieXRlW10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfamF2YV91dGlsX0FycmF5c19zb3J0X2J5dGVfYXJyYXlfTlBFKCkgeworICAgICAgICBieXRlW10gYnl0ZV9hcnJheV9udWxsID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGphdmEudXRpbC5BcnJheXMuc29ydChieXRlX2FycmF5X251bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTM3OAorICAgICAgICAgICAgamF2YS51dGlsLkFycmF5cy5zb3J0KGJ5dGVfYXJyYXlfbnVsbCwgKGludCkgLTEsIChpbnQpIDEpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KGNoYXJbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9qYXZhX3V0aWxfQXJyYXlzX3NvcnRfY2hhcl9hcnJheV9OUEUoKSB7CisgICAgICAgIGNoYXJbXSBjaGFyX2FycmF5X251bGwgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgamF2YS51dGlsLkFycmF5cy5zb3J0KGNoYXJfYXJyYXlfbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMzc4CisgICAgICAgICAgICBqYXZhLnV0aWwuQXJyYXlzLnNvcnQoY2hhcl9hcnJheV9udWxsLCAoaW50KSAtMSwgKGludCkgMSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI3NvcnQoZG91YmxlW10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfamF2YV91dGlsX0FycmF5c19zb3J0X2RvdWJsZV9hcnJheV9OUEUoKSB7CisgICAgICAgIGRvdWJsZVtdIGRvdWJsZV9hcnJheV9udWxsID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGphdmEudXRpbC5BcnJheXMuc29ydChkb3VibGVfYXJyYXlfbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMzc4CisgICAgICAgICAgICBqYXZhLnV0aWwuQXJyYXlzLnNvcnQoZG91YmxlX2FycmF5X251bGwsIChpbnQpIC0xLCAoaW50KSAxKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjc29ydChmbG9hdFtdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2phdmFfdXRpbF9BcnJheXNfc29ydF9mbG9hdF9hcnJheV9OUEUoKSB7CisgICAgICAgIGZsb2F0W10gZmxvYXRfYXJyYXlfbnVsbCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBqYXZhLnV0aWwuQXJyYXlzLnNvcnQoZmxvYXRfYXJyYXlfbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMzc4CisgICAgICAgICAgICBqYXZhLnV0aWwuQXJyYXlzLnNvcnQoZmxvYXRfYXJyYXlfbnVsbCwgKGludCkgLTEsIChpbnQpIDEpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KGludFtdLCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2phdmFfdXRpbF9BcnJheXNfc29ydF9pbnRfYXJyYXlfTlBFKCkgeworICAgICAgICBpbnRbXSBpbnRfYXJyYXlfbnVsbCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBqYXZhLnV0aWwuQXJyYXlzLnNvcnQoaW50X2FycmF5X251bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTM3OAorICAgICAgICAgICAgamF2YS51dGlsLkFycmF5cy5zb3J0KGludF9hcnJheV9udWxsLCAoaW50KSAtMSwgKGludCkgMSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI3NvcnQoT2JqZWN0W10sIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfamF2YV91dGlsX0FycmF5c19zb3J0X29iamVjdF9hcnJheV9OUEUoKSB7CisgICAgICAgIE9iamVjdFtdIG9iamVjdF9hcnJheV9udWxsID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGphdmEudXRpbC5BcnJheXMuc29ydChvYmplY3RfYXJyYXlfbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMzc4CisgICAgICAgICAgICBqYXZhLnV0aWwuQXJyYXlzLnNvcnQob2JqZWN0X2FycmF5X251bGwsIChpbnQpIC0xLCAoaW50KSAxKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS0zNzgKKyAgICAgICAgICAgIGphdmEudXRpbC5BcnJheXMuc29ydChvYmplY3RfYXJyYXlfbnVsbCwgKGludCkgLTEsIChpbnQpIDEsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNzb3J0KGxvbmdbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9qYXZhX3V0aWxfQXJyYXlzX3NvcnRfbG9uZ19hcnJheV9OUEUoKSB7CisgICAgICAgIGxvbmdbXSBsb25nX2FycmF5X251bGwgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgamF2YS51dGlsLkFycmF5cy5zb3J0KGxvbmdfYXJyYXlfbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMzc4CisgICAgICAgICAgICBqYXZhLnV0aWwuQXJyYXlzLnNvcnQobG9uZ19hcnJheV9udWxsLCAoaW50KSAtMSwgKGludCkgMSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI3NvcnQoc2hvcnRbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9qYXZhX3V0aWxfQXJyYXlzX3NvcnRfc2hvcnRfYXJyYXlfTlBFKCkgeworICAgICAgICBzaG9ydFtdIHNob3J0X2FycmF5X251bGwgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgamF2YS51dGlsLkFycmF5cy5zb3J0KHNob3J0X2FycmF5X251bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTM3OAorICAgICAgICAgICAgamF2YS51dGlsLkFycmF5cy5zb3J0KHNob3J0X2FycmF5X251bGwsIChpbnQpIC0xLCAoaW50KSAxKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIExlbmdodHMgb2YgYXJyYXlzIHRvIHRlc3QgaW4gdGVzdF9zb3J0OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludFtdIExFTkdUSFMgPSB7IDAsIDEsIDIsIDMsIDUsIDgsIDEzLCAyMSwgMzQsIDU1LCAxMDAsIDEwMDAsIDEwMDAwIH07CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI3NvcnQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc29ydCgpIHsKKyAgICAgICAgZm9yIChpbnQgbGVuIDogTEVOR1RIUykgeworICAgICAgICAgICAgUHJpbWl0aXZlVHlwZUFycmF5QnVpbGRlci5yZXNldCgpOworICAgICAgICAgICAgaW50W10gZ29sZGVuID0gbmV3IGludFtsZW5dOworICAgICAgICAgICAgZm9yIChpbnQgbSA9IDE7IG0gPCAyICogbGVuOyBtICo9IDIpIHsKKyAgICAgICAgICAgICAgICBmb3IgKFByaW1pdGl2ZVR5cGVBcnJheUJ1aWxkZXIgYnVpbGRlciA6IFByaW1pdGl2ZVR5cGVBcnJheUJ1aWxkZXIudmFsdWVzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgYnVpbGRlci5idWlsZChnb2xkZW4sIG0pOworICAgICAgICAgICAgICAgICAgICBpbnRbXSB0ZXN0ID0gZ29sZGVuLmNsb25lKCk7CisKKyAgICAgICAgICAgICAgICAgICAgZm9yIChQcmltaXRpdmVUeXBlQ29udmVydGVyIGNvbnZlcnRlciA6IFByaW1pdGl2ZVR5cGVDb252ZXJ0ZXIudmFsdWVzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdCBjb252ZXJ0ZWRHb2xkZW4gPSBjb252ZXJ0ZXIuY29udmVydChnb2xkZW4pOworICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IGNvbnZlcnRlZFRlc3QgPSBjb252ZXJ0ZXIuY29udmVydCh0ZXN0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNvcnQoY29udmVydGVkVGVzdCk7CisgICAgICAgICAgICAgICAgICAgICAgICBjaGVja1NvcnRlZChjb252ZXJ0ZWRUZXN0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhjaGVja1N1bShjb252ZXJ0ZWRHb2xkZW4pLCBjaGVja1N1bShjb252ZXJ0ZWRUZXN0KSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc29ydChPYmplY3QgYXJyYXkpIHsKKyAgICAgICAgaWYgKGFycmF5IGluc3RhbmNlb2YgaW50W10pIHsKKyAgICAgICAgICAgIEFycmF5cy5zb3J0KChpbnRbXSkgYXJyYXkpOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKGFycmF5IGluc3RhbmNlb2YgbG9uZ1tdKSB7CisgICAgICAgICAgICBBcnJheXMuc29ydCgobG9uZ1tdKSBhcnJheSk7CisgICAgICAgIH0gZWxzZSBpZiAoYXJyYXkgaW5zdGFuY2VvZiBzaG9ydFtdKSB7CisgICAgICAgICAgICBBcnJheXMuc29ydCgoc2hvcnRbXSkgYXJyYXkpOworICAgICAgICB9IGVsc2UgaWYgKGFycmF5IGluc3RhbmNlb2YgYnl0ZVtdKSB7CisgICAgICAgICAgICBBcnJheXMuc29ydCgoYnl0ZVtdKSBhcnJheSk7CisgICAgICAgIH0gZWxzZSBpZiAoYXJyYXkgaW5zdGFuY2VvZiBjaGFyW10pIHsKKyAgICAgICAgICAgIEFycmF5cy5zb3J0KChjaGFyW10pIGFycmF5KTsKKyAgICAgICAgfSBlbHNlIGlmIChhcnJheSBpbnN0YW5jZW9mIGZsb2F0W10pIHsKKyAgICAgICAgICAgIEFycmF5cy5zb3J0KChmbG9hdFtdKSBhcnJheSk7CisgICAgICAgIH0gZWxzZSBpZiAoYXJyYXkgaW5zdGFuY2VvZiBkb3VibGVbXSkgeworICAgICAgICAgICAgQXJyYXlzLnNvcnQoKGRvdWJsZVtdKSBhcnJheSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmYWlsKCJVbmtub3cgdHlwZSBvZiBhcnJheTogIiArIGFycmF5LmdldENsYXNzKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrU29ydGVkKE9iamVjdCBhcnJheSkgeworICAgICAgICBpZiAoYXJyYXkgaW5zdGFuY2VvZiBpbnRbXSkgeworICAgICAgICAgICAgY2hlY2tTb3J0ZWQoKGludFtdKSBhcnJheSk7CisgICAgICAgIH0gZWxzZSBpZiAoYXJyYXkgaW5zdGFuY2VvZiBsb25nW10pIHsKKyAgICAgICAgICAgIGNoZWNrU29ydGVkKChsb25nW10pIGFycmF5KTsKKyAgICAgICAgfSBlbHNlIGlmIChhcnJheSBpbnN0YW5jZW9mIHNob3J0W10pIHsKKyAgICAgICAgICAgIGNoZWNrU29ydGVkKChzaG9ydFtdKSBhcnJheSk7CisgICAgICAgIH0gZWxzZSBpZiAoYXJyYXkgaW5zdGFuY2VvZiBieXRlW10pIHsKKyAgICAgICAgICAgIGNoZWNrU29ydGVkKChieXRlW10pIGFycmF5KTsKKyAgICAgICAgfSBlbHNlIGlmIChhcnJheSBpbnN0YW5jZW9mIGNoYXJbXSkgeworICAgICAgICAgICAgY2hlY2tTb3J0ZWQoKGNoYXJbXSkgYXJyYXkpOworICAgICAgICB9IGVsc2UgaWYgKGFycmF5IGluc3RhbmNlb2YgZmxvYXRbXSkgeworICAgICAgICAgICAgY2hlY2tTb3J0ZWQoKGZsb2F0W10pIGFycmF5KTsKKyAgICAgICAgfSBlbHNlIGlmIChhcnJheSBpbnN0YW5jZW9mIGRvdWJsZVtdKSB7CisgICAgICAgICAgICBjaGVja1NvcnRlZCgoZG91YmxlW10pIGFycmF5KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZhaWwoIlVua25vdyB0eXBlIG9mIGFycmF5OiAiICsgYXJyYXkuZ2V0Q2xhc3MoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tTb3J0ZWQoaW50W10gYSkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGEubGVuZ3RoIC0gMTsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYVtpXSA+IGFbaSArIDFdKSB7CisgICAgICAgICAgICAgICAgb3JkZXJGYWlsKGksICIiICsgYVtpXSwgIiIgKyBhW2kgKyAxXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tTb3J0ZWQobG9uZ1tdIGEpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhLmxlbmd0aCAtIDE7IGkrKykgeworICAgICAgICAgICAgaWYgKGFbaV0gPiBhW2kgKyAxXSkgeworICAgICAgICAgICAgICAgIG9yZGVyRmFpbChpLCAiIiArIGFbaV0sICIiICsgYVtpICsgMV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrU29ydGVkKHNob3J0W10gYSkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGEubGVuZ3RoIC0gMTsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYVtpXSA+IGFbaSArIDFdKSB7CisgICAgICAgICAgICAgICAgb3JkZXJGYWlsKGksICIiICsgYVtpXSwgIiIgKyBhW2kgKyAxXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tTb3J0ZWQoYnl0ZVtdIGEpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhLmxlbmd0aCAtIDE7IGkrKykgeworICAgICAgICAgICAgaWYgKGFbaV0gPiBhW2kgKyAxXSkgeworICAgICAgICAgICAgICAgIG9yZGVyRmFpbChpLCAiIiArIGFbaV0sICIiICsgYVtpICsgMV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrU29ydGVkKGNoYXJbXSBhKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYS5sZW5ndGggLSAxOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChhW2ldID4gYVtpICsgMV0pIHsKKyAgICAgICAgICAgICAgICBvcmRlckZhaWwoaSwgIiIgKyBhW2ldLCAiIiArIGFbaSArIDFdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja1NvcnRlZChmbG9hdFtdIGEpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhLmxlbmd0aCAtIDE7IGkrKykgeworICAgICAgICAgICAgaWYgKGFbaV0gPiBhW2kgKyAxXSkgeworICAgICAgICAgICAgICAgIG9yZGVyRmFpbChpLCAiIiArIGFbaV0sICIiICsgYVtpICsgMV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrU29ydGVkKGRvdWJsZVtdIGEpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhLmxlbmd0aCAtIDE7IGkrKykgeworICAgICAgICAgICAgaWYgKGFbaV0gPiBhW2kgKyAxXSkgeworICAgICAgICAgICAgICAgIG9yZGVyRmFpbChpLCAiIiArIGFbaV0sICIiICsgYVtpICsgMV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisKKyAgICBwcml2YXRlIHZvaWQgb3JkZXJGYWlsKGludCBpbmRleCwgU3RyaW5nIHZhbHVlMSwgU3RyaW5nIHZhbHVlMikgeworICAgICAgICBmYWlsKCJBcnJheSBpcyBub3Qgc29ydGVkIGF0ICIgKyBpbmRleCArICItdGggcG9zaXRpb246ICIgKyB2YWx1ZTEgKyAiIGFuZCAiICsgdmFsdWUyKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBjaGVja1N1bShPYmplY3QgYXJyYXkpIHsKKyAgICAgICAgaWYgKGFycmF5IGluc3RhbmNlb2YgaW50W10pIHsKKyAgICAgICAgICAgIHJldHVybiBjaGVja1N1bSgoaW50W10pIGFycmF5KTsKKyAgICAgICAgfSBlbHNlIGlmIChhcnJheSBpbnN0YW5jZW9mIGxvbmdbXSkgeworICAgICAgICAgICAgcmV0dXJuIGNoZWNrU3VtKChsb25nW10pIGFycmF5KTsKKyAgICAgICAgfSBlbHNlIGlmIChhcnJheSBpbnN0YW5jZW9mIHNob3J0W10pIHsKKyAgICAgICAgICAgIHJldHVybiBjaGVja1N1bSgoc2hvcnRbXSkgYXJyYXkpOworICAgICAgICB9IGVsc2UgaWYgKGFycmF5IGluc3RhbmNlb2YgYnl0ZVtdKSB7CisgICAgICAgICAgICByZXR1cm4gY2hlY2tTdW0oKGJ5dGVbXSkgYXJyYXkpOworICAgICAgICB9IGVsc2UgaWYgKGFycmF5IGluc3RhbmNlb2YgY2hhcltdKSB7CisgICAgICAgICAgICByZXR1cm4gY2hlY2tTdW0oKGNoYXJbXSkgYXJyYXkpOworICAgICAgICB9IGVsc2UgaWYgKGFycmF5IGluc3RhbmNlb2YgZmxvYXRbXSkgeworICAgICAgICAgICAgcmV0dXJuIGNoZWNrU3VtKChmbG9hdFtdKSBhcnJheSk7CisgICAgICAgIH0gZWxzZSBpZiAoYXJyYXkgaW5zdGFuY2VvZiBkb3VibGVbXSkgeworICAgICAgICAgICAgcmV0dXJuIGNoZWNrU3VtKChkb3VibGVbXSkgYXJyYXkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmFpbCgiVW5rbm93IHR5cGUgb2YgYXJyYXk6ICIgKyBhcnJheS5nZXRDbGFzcygpKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsgLy8gTmVlZGVkIHRvIHNodXQgdXAgY29tcGlsZXIKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBjaGVja1N1bShpbnRbXSBhKSB7CisgICAgICAgIGludCBjaGVja1N1bSA9IDA7CisKKyAgICAgICAgZm9yIChpbnQgZSA6IGEpIHsKKyAgICAgICAgICAgIGNoZWNrU3VtIF49IGU7IC8vIHhvcgorICAgICAgICB9CisgICAgICAgIHJldHVybiBjaGVja1N1bTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBjaGVja1N1bShsb25nW10gYSkgeworICAgICAgICBsb25nIGNoZWNrU3VtID0gMDsKKworICAgICAgICBmb3IgKGxvbmcgZSA6IGEpIHsKKyAgICAgICAgICAgIGNoZWNrU3VtIF49IGU7IC8vIHhvcgorICAgICAgICB9CisgICAgICAgIHJldHVybiAoaW50KSBjaGVja1N1bTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBjaGVja1N1bShzaG9ydFtdIGEpIHsKKyAgICAgICAgc2hvcnQgY2hlY2tTdW0gPSAwOworCisgICAgICAgIGZvciAoc2hvcnQgZSA6IGEpIHsKKyAgICAgICAgICAgIGNoZWNrU3VtIF49IGU7IC8vIHhvcgorICAgICAgICB9CisgICAgICAgIHJldHVybiAoaW50KSBjaGVja1N1bTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBjaGVja1N1bShieXRlW10gYSkgeworICAgICAgICBieXRlIGNoZWNrU3VtID0gMDsKKworICAgICAgICBmb3IgKGJ5dGUgZSA6IGEpIHsKKyAgICAgICAgICAgIGNoZWNrU3VtIF49IGU7IC8vIHhvcgorICAgICAgICB9CisgICAgICAgIHJldHVybiAoaW50KSBjaGVja1N1bTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBjaGVja1N1bShjaGFyW10gYSkgeworICAgICAgICBjaGFyIGNoZWNrU3VtID0gMDsKKworICAgICAgICBmb3IgKGNoYXIgZSA6IGEpIHsKKyAgICAgICAgICAgIGNoZWNrU3VtIF49IGU7IC8vIHhvcgorICAgICAgICB9CisgICAgICAgIHJldHVybiAoaW50KSBjaGVja1N1bTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBjaGVja1N1bShmbG9hdFtdIGEpIHsKKyAgICAgICAgaW50IGNoZWNrU3VtID0gMDsKKworICAgICAgICBmb3IgKGZsb2F0IGUgOiBhKSB7CisgICAgICAgICAgICBjaGVja1N1bSBePSAoaW50KSBlOyAvLyB4b3IKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2hlY2tTdW07CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgY2hlY2tTdW0oZG91YmxlW10gYSkgeworICAgICAgICBpbnQgY2hlY2tTdW0gPSAwOworCisgICAgICAgIGZvciAoZG91YmxlIGUgOiBhKSB7CisgICAgICAgICAgICBjaGVja1N1bSBePSAoaW50KSBlOyAvLyB4b3IKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY2hlY2tTdW07CisgICAgfQorCisgICAgcHJpdmF0ZSBlbnVtIFByaW1pdGl2ZVR5cGVBcnJheUJ1aWxkZXIgeworCisgICAgICAgIFJBTkRPTSB7CisgICAgICAgICAgICB2b2lkIGJ1aWxkKGludFtdIGEsIGludCBtKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGFbaV0gPSBvdXJSYW5kb20ubmV4dEludCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSwKKworICAgICAgICBBU0NFTkRJTkcgeworICAgICAgICAgICAgdm9pZCBidWlsZChpbnRbXSBhLCBpbnQgbSkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBhW2ldID0gbSArIGk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9LAorCisgICAgICAgIERFU0NFTkRJTkcgeworICAgICAgICAgICAgdm9pZCBidWlsZChpbnRbXSBhLCBpbnQgbSkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBhW2ldID0gYS5sZW5ndGggLSBtIC0gaTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0sCisKKyAgICAgICAgQUxMX0VRVUFMIHsKKyAgICAgICAgICAgIHZvaWQgYnVpbGQoaW50W10gYSwgaW50IG0pIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgYVtpXSA9IG07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9LAorCisgICAgICAgIFNBVyB7CisgICAgICAgICAgICB2b2lkIGJ1aWxkKGludFtdIGEsIGludCBtKSB7CisgICAgICAgICAgICAgICAgaW50IGluY0NvdW50ID0gMTsKKyAgICAgICAgICAgICAgICBpbnQgZGVjQ291bnQgPSBhLmxlbmd0aDsKKyAgICAgICAgICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgICAgICAgICAgaW50IHBlcmlvZCA9IG07CisgICAgICAgICAgICAgICAgbS0tOworCisgICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgayA9IDE7IGsgPD0gcGVyaW9kOyBrKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID49IGEubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgYVtpKytdID0gaW5jQ291bnQrKzsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBwZXJpb2QgKz0gbTsKKworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBrID0gMTsgayA8PSBwZXJpb2Q7IGsrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPj0gYS5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBhW2krK10gPSBkZWNDb3VudC0tOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHBlcmlvZCArPSBtOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSwKKworICAgICAgICBSRVBFQVRFRCB7CisgICAgICAgICAgICB2b2lkIGJ1aWxkKGludFtdIGEsIGludCBtKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGFbaV0gPSBpICUgbTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0sCisKKyAgICAgICAgRFVQTElDQVRFRCB7CisgICAgICAgICAgICB2b2lkIGJ1aWxkKGludFtdIGEsIGludCBtKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGFbaV0gPSBvdXJSYW5kb20ubmV4dEludChtKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0sCisKKyAgICAgICAgT1JHQU5fUElQRVMgeworICAgICAgICAgICAgdm9pZCBidWlsZChpbnRbXSBhLCBpbnQgbSkgeworICAgICAgICAgICAgICAgIGludCBtaWRkbGUgPSBhLmxlbmd0aCAvIChtICsgMSk7CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1pZGRsZTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGFbaV0gPSBpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gbWlkZGxlOyBpIDwgYS5sZW5ndGggOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgYVtpXSA9IGEubGVuZ3RoIC0gaSAtIDE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9LAorCisgICAgICAgIFNUQUdHRVIgeworICAgICAgICAgICAgdm9pZCBidWlsZChpbnRbXSBhLCBpbnQgbSkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBhW2ldID0gKGkgKiBtICsgaSkgJSBhLmxlbmd0aDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0sCisKKyAgICAgICAgUExBVEVBVSB7CisgICAgICAgICAgICB2b2lkIGJ1aWxkKGludFtdIGEsIGludCBtKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGFbaV0gPSAgTWF0aC5taW4oaSwgbSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9LAorCisgICAgICAgIFNIVUZGTEUgeworICAgICAgICAgICAgdm9pZCBidWlsZChpbnRbXSBhLCBpbnQgbSkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBhW2ldID0gb3VyUmFuZG9tLm5leHRCb29sZWFuKCkgPyAob3VyRmlyc3QgKz0gMikgOiAob3VyU2Vjb25kICs9IDIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBhYnN0cmFjdCB2b2lkIGJ1aWxkKGludFtdIGEsIGludCBtKTsKKworICAgICAgICBzdGF0aWMgdm9pZCByZXNldCgpIHsKKyAgICAgICAgICAgIG91clJhbmRvbSA9IG5ldyBSYW5kb20oNjY2KTsKKyAgICAgICAgICAgIG91ckZpcnN0ID0gMDsKKyAgICAgICAgICAgIG91clNlY29uZCA9IDA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIFN0cmluZyBuYW1lID0gbmFtZSgpOworCisgICAgICAgICAgICBmb3IgKGludCBpID0gbmFtZS5sZW5ndGgoKTsgaSA8IDEyOyBpKyspIHsKKyAgICAgICAgICAgICAgICBuYW1lICs9ICIgIiA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbmFtZTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgc3RhdGljIGludCBvdXJGaXJzdDsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgaW50IG91clNlY29uZDsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgUmFuZG9tIG91clJhbmRvbSA9IG5ldyBSYW5kb20oNjY2KTsKKyAgICB9CisKKyAgICBwcml2YXRlIGVudW0gUHJpbWl0aXZlVHlwZUNvbnZlcnRlciB7CisKKyAgICAgICAgSU5UIHsKKyAgICAgICAgICAgIE9iamVjdCBjb252ZXJ0KGludFtdIGEpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSwKKworICAgICAgICBMT05HIHsKKyAgICAgICAgICAgIE9iamVjdCBjb252ZXJ0KGludFtdIGEpIHsKKyAgICAgICAgICAgICAgICBsb25nW10gYiA9IG5ldyBsb25nW2EubGVuZ3RoXTsKKworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBiW2ldID0gKGludCkgYVtpXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGI7CisgICAgICAgICAgICB9CisgICAgICAgIH0sCisKKyAgICAgICAgQllURSB7CisgICAgICAgICAgICBPYmplY3QgY29udmVydChpbnRbXSBhKSB7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVthLmxlbmd0aF07CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgYltpXSA9IChieXRlKSBhW2ldOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gYjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSwKKworICAgICAgICBTSE9SVCB7CisgICAgICAgICAgICBPYmplY3QgY29udmVydChpbnRbXSBhKSB7CisgICAgICAgICAgICAgICAgc2hvcnRbXSBiID0gbmV3IHNob3J0W2EubGVuZ3RoXTsKKworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBiW2ldID0gKHNob3J0KSBhW2ldOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gYjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSwKKworICAgICAgICBDSEFSIHsKKyAgICAgICAgICAgIE9iamVjdCBjb252ZXJ0KGludFtdIGEpIHsKKyAgICAgICAgICAgICAgICBjaGFyW10gYiA9IG5ldyBjaGFyW2EubGVuZ3RoXTsKKworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBiW2ldID0gKGNoYXIpIGFbaV07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBiOworICAgICAgICAgICAgfQorICAgICAgICB9LAorCisgICAgICAgIEZMT0FUIHsKKyAgICAgICAgICAgIE9iamVjdCBjb252ZXJ0KGludFtdIGEpIHsKKyAgICAgICAgICAgICAgICBmbG9hdFtdIGIgPSBuZXcgZmxvYXRbYS5sZW5ndGhdOworCisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGJbaV0gPSAoZmxvYXQpIGFbaV07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBiOworICAgICAgICAgICAgfQorICAgICAgICB9LAorCisgICAgICAgIERPVUJMRSB7CisgICAgICAgICAgICBPYmplY3QgY29udmVydChpbnRbXSBhKSB7CisgICAgICAgICAgICAgICAgZG91YmxlW10gYiA9IG5ldyBkb3VibGVbYS5sZW5ndGhdOworCisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGJbaV0gPSAoZG91YmxlKSBhW2ldOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gYjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBhYnN0cmFjdCBPYmplY3QgY29udmVydChpbnRbXSBhKTsKKworICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBuYW1lKCk7CisKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBuYW1lLmxlbmd0aCgpOyBpIDwgOTsgaSsrKSB7CisgICAgICAgICAgICAgICAgbmFtZSArPSAiICIgOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjZGVlcEVxdWFscyhPYmplY3RbXSwgT2JqZWN0W10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9kZWVwRXF1YWxzJExqYXZhX2xhbmdfT2JqZWN0TGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgaW50IFtdIGExID0gezEsIDIsIDN9OworICAgICAgIHNob3J0IFtdIGEyID0gezAsIDF9OworICAgICAgIE9iamVjdCBbXSBhMyA9IHtuZXcgSW50ZWdlcigxKSwgYTJ9OworICAgICAgIGludCBbXSBhNCA9IHs2LCA1LCA0fTsKKworICAgICAgIGludCBbXSBiMSA9IHsxLCAyLCAzfTsKKyAgICAgICBzaG9ydCBbXSBiMiA9IHswLCAxfTsKKyAgICAgICBPYmplY3QgW10gYjMgPSB7bmV3IEludGVnZXIoMSksIGIyfTsKKworICAgICAgIE9iamVjdCBhIFtdID0ge2ExLCBhMiwgYTN9OworICAgICAgIE9iamVjdCBiIFtdID0ge2IxLCBiMiwgYjN9OworCisgICAgICAgYXNzZXJ0RmFsc2UoQXJyYXlzLmVxdWFscyhhLCBiKSk7CisgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZGVlcEVxdWFscyhhLGIpKTsKKworICAgICAgIGFbMl0gPSBhNDsKKworICAgICAgIGFzc2VydEZhbHNlKEFycmF5cy5kZWVwRXF1YWxzKGEsIGIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI2RlZXBIYXNoQ29kZShPYmplY3RbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RlZXBIYXNoQ29kZSRMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgaW50IFtdIGExID0gezEsIDIsIDN9OworICAgICAgICBzaG9ydCBbXSBhMiA9IHswLCAxfTsKKyAgICAgICAgT2JqZWN0IFtdIGEzID0ge25ldyBJbnRlZ2VyKDEpLCBhMn07CisKKyAgICAgICAgaW50IFtdIGIxID0gezEsIDIsIDN9OworICAgICAgICBzaG9ydCBbXSBiMiA9IHswLCAxfTsKKyAgICAgICAgT2JqZWN0IFtdIGIzID0ge25ldyBJbnRlZ2VyKDEpLCBiMn07CisKKyAgICAgICAgT2JqZWN0IGEgW10gPSB7YTEsIGEyLCBhM307CisgICAgICAgIE9iamVjdCBiIFtdID0ge2IxLCBiMiwgYjN9OworCisgICAgICAgIGludCBkZWVwX2hhc2hfYSA9IEFycmF5cy5kZWVwSGFzaENvZGUoYSk7CisgICAgICAgIGludCBkZWVwX2hhc2hfYiA9IEFycmF5cy5kZWVwSGFzaENvZGUoYik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGRlZXBfaGFzaF9hLCBkZWVwX2hhc2hfYik7CisgICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjaGFzaENvZGUoYm9vbGVhbltdIGEpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSRMWigpIHsKKyAgICAgICAgaW50IGxpc3RIYXNoQ29kZTsKKyAgICAgICAgaW50IGFycmF5SGFzaENvZGU7CisKKyAgICAgICAgYm9vbGVhbiBbXSBib29sQXJyID0ge3RydWUsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgZmFsc2V9OworICAgICAgICBMaXN0IGxpc3RPZkJvb2xlYW4gPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJvb2xBcnIubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGxpc3RPZkJvb2xlYW4uYWRkKG5ldyBCb29sZWFuKGJvb2xBcnJbaV0pKTsKKyAgICAgICAgfQorICAgICAgICBsaXN0SGFzaENvZGUgPSBsaXN0T2ZCb29sZWFuLmhhc2hDb2RlKCk7CisgICAgICAgIGFycmF5SGFzaENvZGUgPSBBcnJheXMuaGFzaENvZGUoYm9vbEFycik7CisgICAgICAgIGFzc2VydEVxdWFscyhsaXN0SGFzaENvZGUsIGFycmF5SGFzaENvZGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjaGFzaENvZGUoaW50W10gYSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc2hDb2RlJExJKCkgeworICAgICAgICBpbnQgbGlzdEhhc2hDb2RlOworICAgICAgICBpbnQgYXJyYXlIYXNoQ29kZTsKKworICAgICAgICBpbnQgW10gaW50QXJyID0gezEwLCA1LCAxMzQsIDcsIDE5fTsKKyAgICAgICAgTGlzdCBsaXN0T2ZJbnRlZ2VyID0gbmV3IExpbmtlZExpc3QoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludEFyci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbGlzdE9mSW50ZWdlci5hZGQobmV3IEludGVnZXIoaW50QXJyW2ldKSk7CisgICAgICAgIH0KKyAgICAgICAgbGlzdEhhc2hDb2RlID0gbGlzdE9mSW50ZWdlci5oYXNoQ29kZSgpOworICAgICAgICBhcnJheUhhc2hDb2RlID0gQXJyYXlzLmhhc2hDb2RlKGludEFycik7CisgICAgICAgIGFzc2VydEVxdWFscyhsaXN0SGFzaENvZGUsIGFycmF5SGFzaENvZGUpOworCisgICAgICAgIGludCBbXSBpbnRBcnIyID0gezEwLCA1LCAxMzQsIDcsIDE5fTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5oYXNoQ29kZShpbnRBcnIyKSwgQXJyYXlzLmhhc2hDb2RlKGludEFycikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjaGFzaENvZGUoY2hhcltdIGEpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSRMQygpIHsKKyAgICAgICAgaW50IGxpc3RIYXNoQ29kZTsKKyAgICAgICAgaW50IGFycmF5SGFzaENvZGU7CisKKyAgICAgICAgY2hhciBbXSBjaGFyQXJyID0geydhJywgJ2cnLCAneCcsICdjJywgJ20nfTsKKyAgICAgICAgTGlzdCBsaXN0T2ZDaGFyYWN0ZXIgPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoYXJBcnIubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGxpc3RPZkNoYXJhY3Rlci5hZGQobmV3IENoYXJhY3RlcihjaGFyQXJyW2ldKSk7CisgICAgICAgIH0KKyAgICAgICAgbGlzdEhhc2hDb2RlID0gbGlzdE9mQ2hhcmFjdGVyLmhhc2hDb2RlKCk7CisgICAgICAgIGFycmF5SGFzaENvZGUgPSBBcnJheXMuaGFzaENvZGUoY2hhckFycik7CisgICAgICAgIGFzc2VydEVxdWFscyhsaXN0SGFzaENvZGUsIGFycmF5SGFzaENvZGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5BcnJheXMjaGFzaENvZGUoYnl0ZVtdIGEpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSRMQigpIHsKKyAgICAgICAgaW50IGxpc3RIYXNoQ29kZTsKKyAgICAgICAgaW50IGFycmF5SGFzaENvZGU7CisKKyAgICAgICAgYnl0ZSBbXSBieXRlQXJyID0gezUsIDksIDcsIDYsIDE3fTsKKyAgICAgICAgTGlzdCBsaXN0T2ZCeXRlID0gbmV3IExpbmtlZExpc3QoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBieXRlQXJyLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBsaXN0T2ZCeXRlLmFkZChuZXcgQnl0ZShieXRlQXJyW2ldKSk7CisgICAgICAgIH0KKyAgICAgICAgbGlzdEhhc2hDb2RlID0gbGlzdE9mQnl0ZS5oYXNoQ29kZSgpOworICAgICAgICBhcnJheUhhc2hDb2RlID0gQXJyYXlzLmhhc2hDb2RlKGJ5dGVBcnIpOworICAgICAgICBhc3NlcnRFcXVhbHMobGlzdEhhc2hDb2RlLCBhcnJheUhhc2hDb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI2hhc2hDb2RlKGxvbmdbXSBhKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGFzaENvZGUkTEooKSB7CisgICAgICAgIGludCBsaXN0SGFzaENvZGU7CisgICAgICAgIGludCBhcnJheUhhc2hDb2RlOworCisgICAgICAgIGxvbmcgW10gbG9uZ0FyciA9IHs2Nzg5MDIzNDUxMmwsIDk3NTg3MjM2OTIzNDI1bCwgMjU3NDIxOTEyOTEybCwKKyAgICAgICAgICAgICAgICA2NzU0MjY4MTAwbCwgNX07CisgICAgICAgIExpc3QgbGlzdE9mTG9uZyA9IG5ldyBMaW5rZWRMaXN0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbG9uZ0Fyci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbGlzdE9mTG9uZy5hZGQobmV3IExvbmcobG9uZ0FycltpXSkpOworICAgICAgICB9CisgICAgICAgIGxpc3RIYXNoQ29kZSA9IGxpc3RPZkxvbmcuaGFzaENvZGUoKTsKKyAgICAgICAgYXJyYXlIYXNoQ29kZSA9IEFycmF5cy5oYXNoQ29kZShsb25nQXJyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxpc3RIYXNoQ29kZSwgYXJyYXlIYXNoQ29kZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNoYXNoQ29kZShmbG9hdFtdIGEpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSRMRigpIHsKKyAgICAgICAgaW50IGxpc3RIYXNoQ29kZTsKKyAgICAgICAgaW50IGFycmF5SGFzaENvZGU7CisKKyAgICAgICAgZmxvYXQgW10gZmxvYXRBcnIgPSB7MC4xMzQ5N2YsIDAuMjY4OTM0ZiwgMTJlLTVmLCAtM2UrMmYsIDEwZS00Zn07CisgICAgICAgIExpc3QgbGlzdE9mRmxvYXQgPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZsb2F0QXJyLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBsaXN0T2ZGbG9hdC5hZGQobmV3IEZsb2F0KGZsb2F0QXJyW2ldKSk7CisgICAgICAgIH0KKyAgICAgICAgbGlzdEhhc2hDb2RlID0gbGlzdE9mRmxvYXQuaGFzaENvZGUoKTsKKyAgICAgICAgYXJyYXlIYXNoQ29kZSA9IEFycmF5cy5oYXNoQ29kZShmbG9hdEFycik7CisgICAgICAgIGFzc2VydEVxdWFscyhsaXN0SGFzaENvZGUsIGFycmF5SGFzaENvZGUpOworCisgICAgICAgIGZsb2F0IFtdIGZsb2F0QXJyMiA9IHswLjEzNDk3ZiwgMC4yNjg5MzRmLCAxMmUtNWYsIC0zZSsyZiwgMTBlLTRmfTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy5oYXNoQ29kZShmbG9hdEFycjIpLCBBcnJheXMuaGFzaENvZGUoZmxvYXRBcnIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI2hhc2hDb2RlKGRvdWJsZVtdIGEpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSRMRCgpIHsKKyAgICAgICAgaW50IGxpc3RIYXNoQ29kZTsKKyAgICAgICAgaW50IGFycmF5SGFzaENvZGU7CisKKyAgICAgICAgZG91YmxlIFtdIGRvdWJsZUFyciA9IHswLjEzNDk0NTY1NywgMC4wMDM4NzU0LCAxMWUtMTUwLCAtMzBlLTMwMCwgMTBlLTR9OworICAgICAgICBMaXN0IGxpc3RPZkRvdWJsZSA9IG5ldyBMaW5rZWRMaXN0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZG91YmxlQXJyLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBsaXN0T2ZEb3VibGUuYWRkKG5ldyBEb3VibGUoZG91YmxlQXJyW2ldKSk7CisgICAgICAgIH0KKyAgICAgICAgbGlzdEhhc2hDb2RlID0gbGlzdE9mRG91YmxlLmhhc2hDb2RlKCk7CisgICAgICAgIGFycmF5SGFzaENvZGUgPSBBcnJheXMuaGFzaENvZGUoZG91YmxlQXJyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxpc3RIYXNoQ29kZSwgYXJyYXlIYXNoQ29kZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkFycmF5cyNoYXNoQ29kZShzaG9ydFtdIGEpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSRMUygpIHsKKyAgICAgICAgaW50IGxpc3RIYXNoQ29kZTsKKyAgICAgICAgaW50IGFycmF5SGFzaENvZGU7CisKKyAgICAgICAgc2hvcnQgW10gc2hvcnRBcnIgPSB7MzUsIDEzLCA0NSwgMiwgOTF9OworICAgICAgICBMaXN0IGxpc3RPZlNob3J0ID0gbmV3IExpbmtlZExpc3QoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaG9ydEFyci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbGlzdE9mU2hvcnQuYWRkKG5ldyBTaG9ydChzaG9ydEFycltpXSkpOworICAgICAgICB9CisgICAgICAgIGxpc3RIYXNoQ29kZSA9IGxpc3RPZlNob3J0Lmhhc2hDb2RlKCk7CisgICAgICAgIGFycmF5SGFzaENvZGUgPSBBcnJheXMuaGFzaENvZGUoc2hvcnRBcnIpOworICAgICAgICBhc3NlcnRFcXVhbHMobGlzdEhhc2hDb2RlLCBhcnJheUhhc2hDb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQXJyYXlzI2hhc2hDb2RlKE9iamVjdFtdIGEpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSRMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgaW50IGxpc3RIYXNoQ29kZTsKKyAgICAgICAgaW50IGFycmF5SGFzaENvZGU7CisKKyAgICAgICAgT2JqZWN0W10gb2JqZWN0QXJyID0ge25ldyBJbnRlZ2VyKDEpLCBuZXcgRmxvYXQoMTBlLTEyZiksIG51bGx9OworICAgICAgICBMaXN0IGxpc3RPZk9iamVjdD0gbmV3IExpbmtlZExpc3QoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvYmplY3RBcnIubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGxpc3RPZk9iamVjdC5hZGQob2JqZWN0QXJyW2ldKTsKKyAgICAgICAgfQorICAgICAgICBsaXN0SGFzaENvZGUgPSBsaXN0T2ZPYmplY3QuaGFzaENvZGUoKTsKKyAgICAgICAgYXJyYXlIYXNoQ29kZSA9IEFycmF5cy5oYXNoQ29kZShvYmplY3RBcnIpOworICAgICAgICBhc3NlcnRFcXVhbHMobGlzdEhhc2hDb2RlLCBhcnJheUhhc2hDb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgb2JqQXJyYXkgPSBuZXcgT2JqZWN0W2FycmF5U2l6ZV07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2JqQXJyYXkubGVuZ3RoOyBpKyspCisgICAgICAgICAgICBvYmpBcnJheVtpXSA9IG5ldyBJbnRlZ2VyKGkpOworCisgICAgICAgIGJvb2xlYW5BcnJheSA9IG5ldyBib29sZWFuW2FycmF5U2l6ZV07CisgICAgICAgIGJ5dGVBcnJheSA9IG5ldyBieXRlW2FycmF5U2l6ZV07CisgICAgICAgIGNoYXJBcnJheSA9IG5ldyBjaGFyW2FycmF5U2l6ZV07CisgICAgICAgIGRvdWJsZUFycmF5ID0gbmV3IGRvdWJsZVthcnJheVNpemVdOworICAgICAgICBmbG9hdEFycmF5ID0gbmV3IGZsb2F0W2FycmF5U2l6ZV07CisgICAgICAgIGludEFycmF5ID0gbmV3IGludFthcnJheVNpemVdOworICAgICAgICBsb25nQXJyYXkgPSBuZXcgbG9uZ1thcnJheVNpemVdOworICAgICAgICBvYmplY3RBcnJheSA9IG5ldyBPYmplY3RbYXJyYXlTaXplXTsKKyAgICAgICAgc2hvcnRBcnJheSA9IG5ldyBzaG9ydFthcnJheVNpemVdOworCisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgYXJyYXlTaXplOyBjb3VudGVyKyspIHsKKyAgICAgICAgICAgIGJ5dGVBcnJheVtjb3VudGVyXSA9IChieXRlKSBjb3VudGVyOworICAgICAgICAgICAgY2hhckFycmF5W2NvdW50ZXJdID0gKGNoYXIpIChjb3VudGVyICsgMSk7CisgICAgICAgICAgICBkb3VibGVBcnJheVtjb3VudGVyXSA9IGNvdW50ZXI7CisgICAgICAgICAgICBmbG9hdEFycmF5W2NvdW50ZXJdID0gY291bnRlcjsKKyAgICAgICAgICAgIGludEFycmF5W2NvdW50ZXJdID0gY291bnRlcjsKKyAgICAgICAgICAgIGxvbmdBcnJheVtjb3VudGVyXSA9IGNvdW50ZXI7CisgICAgICAgICAgICBvYmplY3RBcnJheVtjb3VudGVyXSA9IG9iakFycmF5W2NvdW50ZXJdOworICAgICAgICAgICAgc2hvcnRBcnJheVtjb3VudGVyXSA9IChzaG9ydCkgY291bnRlcjsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGFycmF5U2l6ZTsgY291bnRlciArPSAyKSB7CisgICAgICAgICAgICBib29sZWFuQXJyYXlbY291bnRlcl0gPSBmYWxzZTsKKyAgICAgICAgICAgIGJvb2xlYW5BcnJheVtjb3VudGVyICsgMV0gPSB0cnVlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVhcnMgZG93biB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIGNsb3NlIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzCisgICAgICogbWV0aG9kIGlzIGNhbGxlZCBhZnRlciBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIG9iakFycmF5ID0gbnVsbDsKKyAgICAgICAgYm9vbGVhbkFycmF5ID0gbnVsbDsKKyAgICAgICAgYnl0ZUFycmF5ID0gbnVsbDsKKyAgICAgICAgY2hhckFycmF5ID0gbnVsbDsKKyAgICAgICAgZG91YmxlQXJyYXkgPSBudWxsOworICAgICAgICBmbG9hdEFycmF5ID0gbnVsbDsKKyAgICAgICAgaW50QXJyYXkgPSBudWxsOworICAgICAgICBsb25nQXJyYXkgPSBudWxsOworICAgICAgICBvYmplY3RBcnJheSA9IG51bGw7CisgICAgICAgIHNob3J0QXJyYXkgPSBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0JpdFNldFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0JpdFNldFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNzJjNmQxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQml0U2V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTI1MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkJpdFNldDsKKworcHVibGljIGNsYXNzIEJpdFNldFRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgQml0U2V0IGVpZ2h0YnM7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICBCaXRTZXQgYnMgPSBuZXcgQml0U2V0KCk7CisgICAgICAgIC8vIERlZmF1bHQgc2l6ZSBmb3IgYSBCaXRTZXQgc2hvdWxkIGJlIDY0IGVsZW1lbnRzOworICAgICAgICBhc3NlcnRFcXVhbHMoIkNyZWF0ZWQgQml0U2V0IG9mIGluY29ycmVjdCBzaXplIiwgNjQsIGJzLnNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiTmV3IEJpdFNldCBoYWQgaW52YWxpZCBzdHJpbmcgcmVwcmVzZW50YXRpb24iLCAie30iLCBicy50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySSgpIHsKKyAgICAgICAgQml0U2V0IGJzID0gbmV3IEJpdFNldCgxMjgpOworICAgICAgICAvLyBEZWZhdWx0IHNpemUgZm9yIGEgQml0U2V0IHNob3VsZCBiZSA2NCBlbGVtZW50czsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkNyZWF0ZWQgQml0U2V0IG9mIGluY29ycmVjdCBzaXplIiwgMTI4LCBicy5zaXplKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJOZXcgQml0U2V0IGhhZCBpbnZhbGlkIHN0cmluZyByZXByZXNlbnRhdGlvbjogIgorICAgICAgICAgICAgICAgICsgYnMudG9TdHJpbmcoKSwgYnMudG9TdHJpbmcoKS5lcXVhbHMoInt9IikpOworCisgICAgICAgIC8vIEFsbCBCaXRTZXRzIGFyZSBjcmVhdGVkIHdpdGggZWxlbWVudHMgb2YgbXVsdGlwbGVzIG9mIDY0CisKKyAgICAgICAgYnMgPSBuZXcgQml0U2V0KDg5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gcm91bmQgQml0U2V0IGVsZW1lbnQgc2l6ZSIsIDEyOCwgYnMuc2l6ZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnMgPSBuZXcgQml0U2V0KC05KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvbmUoKSB7CisgICAgICAgIEJpdFNldCBicyA9IChCaXRTZXQpIGVpZ2h0YnMuY2xvbmUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2xvbmUgZmFpbGVkIHRvIHJldHVybiBlcXVhbCBCaXRTZXQiLCBlaWdodGJzLmVxdWFscyhicykpOworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9lcXVhbHNMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgQml0U2V0IGJzOworCisgICAgICAgIGJzID0gKEJpdFNldCkgZWlnaHRicy5jbG9uZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJTYW1lIEJpdFNldCByZXR1cm5lZCBmYWxzZSIsIGVpZ2h0YnMuZXF1YWxzKGVpZ2h0YnMpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSWRlbnRpY2FsIEJpdFNldHMgcmV0dXJuZWQgZmFsc2UiLCBlaWdodGJzLmVxdWFscyhicykpOworICAgICAgICBicy5jbGVhcig2KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRGlmZmVyZW50IEJpdFNldHMgcmV0dXJuZWQgdHJ1ZSIsICFlaWdodGJzLmVxdWFscyhicykpOworICAgICAgICAvLyBHcm93IHRoZSBCaXRTZXQKKyAgICAgICAgYnMgPSAoQml0U2V0KSBlaWdodGJzLmNsb25lKCk7CisgICAgICAgIGJzLnNldCgxMjgpOworICAgICAgICBhc3NlcnRGYWxzZShlaWdodGJzLmVxdWFscyhicykpOworICAgICAgICBicy5jbGVhcigxMjgpOworICAgICAgICBhc3NlcnRUcnVlKGVpZ2h0YnMuZXF1YWxzKGJzKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSgpIHsKKyAgICAgICAgQml0U2V0IGJzID0gKEJpdFNldCkgZWlnaHRicy5jbG9uZSgpOworICAgICAgICBicy5jbGVhcigyKTsKKyAgICAgICAgYnMuY2xlYXIoNik7CisgICAgICAgIGFzc2VydEVxdWFscygiQml0U2V0IHJldHVybnMgd3JvbmcgaGFzaCB2YWx1ZSIsIDExMjksIGJzLmhhc2hDb2RlKCkpOworICAgICAgICBicy5zZXQoMTApOworICAgICAgICBicy5jbGVhcigzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJCaXRTZXQgcmV0dXJucyB3cm9uZyBoYXNoIHZhbHVlIiwgOTcsIGJzLmhhc2hDb2RlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xlYXIoKSB7CisgICAgICAgIGVpZ2h0YnMuY2xlYXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA4OyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkNsZWFyIGRpZG4ndCBjbGVhciBiaXQgIiArIGksICFlaWdodGJzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0MTogV3JvbmcgbGVuZ3RoIiwgMCwgZWlnaHRicy5sZW5ndGgoKSk7CisKKyAgICAgICAgQml0U2V0IGJzID0gbmV3IEJpdFNldCgzNDAwKTsKKyAgICAgICAgYnMuc2V0KDAsIGJzLnNpemUoKSAtIDEpOyAvLyBlbnN1cmUgYWxsIGJpdHMgYXJlIDEncworICAgICAgICBicy5zZXQoYnMuc2l6ZSgpIC0gMSk7CisgICAgICAgIGJzLmNsZWFyKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBicy5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydFRydWUoYnMuaXNFbXB0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGJzLmNhcmRpbmFsaXR5KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xlYXJJKCkgeworICAgICAgICBlaWdodGJzLmNsZWFyKDcpOworICAgICAgICBhc3NlcnRGYWxzZSgiRmFpbGVkIHRvIGNsZWFyIGJpdCIsIGVpZ2h0YnMuZ2V0KDcpKTsKKworICAgICAgICAvLyBDaGVjayB0byBzZWUgYWxsIG90aGVyIGJpdHMgYXJlIHN0aWxsIHNldAorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDc7IGkrKykKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2xlYXIgY2xlYXJlZCBpbmNvcnJlY3QgYml0cyIsIGVpZ2h0YnMuZ2V0KGkpKTsKKworICAgICAgICBlaWdodGJzLmNsZWFyKDE2NSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJGYWlsZWQgdG8gY2xlYXIgYml0IiwgZWlnaHRicy5nZXQoMTY1KSk7CisgICAgICAgIC8vIFRyeSBvdXQgb2YgcmFuZ2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVpZ2h0YnMuY2xlYXIoLTEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBCaXRTZXQgYnMgPSBuZXcgQml0U2V0KDApOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QxOiBXcm9uZyBsZW5ndGgsIiwgMCwgYnMubGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QxOiBXcm9uZyBzaXplLCIsIDAsIGJzLnNpemUoKSk7CisKKyAgICAgICAgYnMuY2xlYXIoMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDI6IFdyb25nIGxlbmd0aCwiLCAwLCBicy5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDI6IFdyb25nIHNpemUsIiwgMCwgYnMuc2l6ZSgpKTsKKworICAgICAgICBicy5jbGVhcig2MCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDM6IFdyb25nIGxlbmd0aCwiLCAwLCBicy5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDM6IFdyb25nIHNpemUsIiwgMCwgYnMuc2l6ZSgpKTsKKworICAgICAgICBicy5jbGVhcigxMjApOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3Q0OiBXcm9uZyBzaXplLCIsIDAsIGJzLnNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDQ6IFdyb25nIGxlbmd0aCwiLCAwLCBicy5sZW5ndGgoKSk7CisKKyAgICAgICAgYnMuc2V0KDI1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0NTogV3Jvbmcgc2l6ZSwiLCA2NCwgYnMuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0NTogV3JvbmcgbGVuZ3RoLCIsIDI2LCBicy5sZW5ndGgoKSk7CisKKyAgICAgICAgYnMuY2xlYXIoODApOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3Q2OiBXcm9uZyBzaXplLCIsIDY0LCBicy5zaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3Q2OiBXcm9uZyBsZW5ndGgsIiwgMjYsIGJzLmxlbmd0aCgpKTsKKworICAgICAgICBicy5jbGVhcigyNSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDc6IFdyb25nIHNpemUsIiwgNjQsIGJzLnNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDc6IFdyb25nIGxlbmd0aCwiLCAwLCBicy5sZW5ndGgoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jbGVhcklJKCkgeworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTk4CisgICAgICAgIEJpdFNldCBiaXRzZXQgPSBuZXcgQml0U2V0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjA7IGkrKykgeworICAgICAgICAgICAgYml0c2V0LnNldChpKTsKKyAgICAgICAgfQorICAgICAgICBiaXRzZXQuY2xlYXIoMTAsIDEwKTsKKworICAgICAgICAvLyBwb3MxIGFuZCBwb3MyIGFyZSBpbiB0aGUgc2FtZSBiaXRzZXQgZWxlbWVudAorICAgICAgICBCaXRTZXQgYnMgPSBuZXcgQml0U2V0KDE2KTsKKyAgICAgICAgaW50IGluaXRpYWxTaXplID0gYnMuc2l6ZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoNjQsIGluaXRpYWxTaXplKTsKKyAgICAgICAgYnMuc2V0KDAsIGluaXRpYWxTaXplKTsKKyAgICAgICAgYnMuY2xlYXIoNSk7CisgICAgICAgIGJzLmNsZWFyKDE1KTsKKyAgICAgICAgYnMuY2xlYXIoNywgMTEpOworICAgICAgICBhc3NlcnRFcXVhbHMoInswLCAxLCAyLCAzLCA0LCA2LCAxMSwgMTIsIDEzLCAxNCwgMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsICIgKworICAgICAgICAgICAgICAgICIyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLCAzMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsICIgKworICAgICAgICAgICAgICAgICI0NiwgNDcsIDQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgNjIsIDYzfSIsIGJzLnRvU3RyaW5nKCkpOworICAgICAgICBmb3IgKGludCBpID0gaW5pdGlhbFNpemU7IGkgPCBicy5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZG4ndCBoYXZlIGZsaXBwZWQgYml0ICIgKyBpLCBicy5nZXQoaSkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gcG9zMSBhbmQgcG9zMiBpcyBpbiB0aGUgc2FtZSBiaXRzZXQgZWxlbWVudCwgYm91bmRyeSB0ZXN0aW5nCisgICAgICAgIGJzID0gbmV3IEJpdFNldCgxNik7CisgICAgICAgIGluaXRpYWxTaXplID0gYnMuc2l6ZSgpOworICAgICAgICBicy5zZXQoMCwgaW5pdGlhbFNpemUpOworICAgICAgICBicy5jbGVhcig3LCA2NCk7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHRvIGdyb3cgQml0U2V0IiwgNjQsIGJzLnNpemUoKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNzsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGRuJ3QgaGF2ZSBjbGVhcmVkIGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gNzsgaSA8IDY0OyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJGYWlsZWQgdG8gY2xlYXIgYml0ICIgKyBpLCBicy5nZXQoaSkpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSA2NDsgaSA8IGJzLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGRuJ3QgaGF2ZSBmbGlwcGVkIGJpdCAiICsgaSwgIWJzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgLy8gbW9yZSBib3VuZGFyeSB0ZXN0aW5nCisgICAgICAgIGJzID0gbmV3IEJpdFNldCgzMik7CisgICAgICAgIGluaXRpYWxTaXplID0gYnMuc2l6ZSgpOworICAgICAgICBicy5zZXQoMCwgaW5pdGlhbFNpemUpOworICAgICAgICBicy5jbGVhcigwLCA2NCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNjQ7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIkZhaWxlZCB0byBjbGVhciBiaXQgIiArIGksIGJzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDY0OyBpIDwgYnMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGRuJ3QgaGF2ZSBmbGlwcGVkIGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGJzID0gbmV3IEJpdFNldCgzMik7CisgICAgICAgIGluaXRpYWxTaXplID0gYnMuc2l6ZSgpOworICAgICAgICBicy5zZXQoMCwgaW5pdGlhbFNpemUpOworICAgICAgICBicy5jbGVhcigwLCA2NSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNjU7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIkZhaWxlZCB0byBjbGVhciBiaXQgIiArIGksIGJzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDY1OyBpIDwgYnMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGRuJ3QgaGF2ZSBmbGlwcGVkIGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHBvczEgYW5kIHBvczIgYXJlIGluIHR3byBzZXF1ZW50aWFsIGJpdHNldCBlbGVtZW50cworICAgICAgICBicyA9IG5ldyBCaXRTZXQoMTI4KTsKKyAgICAgICAgaW5pdGlhbFNpemUgPSBicy5zaXplKCk7CisgICAgICAgIGJzLnNldCgwLCBpbml0aWFsU2l6ZSk7CisgICAgICAgIGJzLmNsZWFyKDcpOworICAgICAgICBicy5jbGVhcigxMTApOworICAgICAgICBicy5jbGVhcig5LCA3NCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgOTsgaSsrKSB7CisgICAgICAgICAgICBpZiAoaSA9PSA3KSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZG4ndCBoYXZlIGZsaXBwZWQgYml0ICIgKyBpLCBicy5nZXQoaSkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGRuJ3QgaGF2ZSBjbGVhcmVkIGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gOTsgaSA8IDc0OyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJGYWlsZWQgdG8gY2xlYXIgYml0ICIgKyBpLCBicy5nZXQoaSkpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSA3NDsgaSA8IGluaXRpYWxTaXplOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChpID09IDExMCkgeworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGRuJ3QgaGF2ZSBmbGlwcGVkIGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkbid0IGhhdmUgY2xlYXJlZCBiaXQgIiArIGksIGJzLmdldChpKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IGluaXRpYWxTaXplOyBpIDwgYnMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGRuJ3QgaGF2ZSBmbGlwcGVkIGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHBvczEgYW5kIHBvczIgYXJlIGluIHR3byBub24tc2VxdWVudGlhbCBiaXRzZXQgZWxlbWVudHMKKyAgICAgICAgYnMgPSBuZXcgQml0U2V0KDI1Nik7CisgICAgICAgIGJzLnNldCgwLCAyNTYpOworICAgICAgICBicy5jbGVhcig3KTsKKyAgICAgICAgYnMuY2xlYXIoMjU1KTsKKyAgICAgICAgYnMuY2xlYXIoOSwgMjE5KTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA5OyBpKyspIHsKKyAgICAgICAgICAgIGlmIChpID09IDcpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkbid0IGhhdmUgZmxpcHBlZCBiaXQgIiArIGksIGJzLmdldChpKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIlNob3VsZG4ndCBoYXZlIGNsZWFyZWQgYml0ICIgKyBpLCBicy5nZXQoaSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDk7IGkgPCAyMTk7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoImZhaWxlZCB0byBjbGVhciBiaXQgIiArIGksIGJzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDIxOTsgaSA8IDI1NTsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGRuJ3QgaGF2ZSBjbGVhcmVkIGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMjU1OyBpIDwgYnMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGRuJ3QgaGF2ZSBmbGlwcGVkIGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3QgaWxsZWdhbCBhcmdzCisgICAgICAgIGJzID0gbmV3IEJpdFNldCgxMCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBicy5jbGVhcigtMSwgMyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBicy5jbGVhcigyLCAtMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGJzLnNldCgyLCA0KTsKKyAgICAgICAgYnMuY2xlYXIoMiwgMik7CisgICAgICAgIGFzc2VydFRydWUoIkJpdCBnb3QgY2xlYXJlZCBpbmNvcnJlY3RseSAiLCBicy5nZXQoMikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBicy5jbGVhcig0LCAyKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgYnMgPSBuZXcgQml0U2V0KDApOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QxOiBXcm9uZyBsZW5ndGgsIiwgMCwgYnMubGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QxOiBXcm9uZyBzaXplLCIsIDAsIGJzLnNpemUoKSk7CisKKyAgICAgICAgYnMuY2xlYXIoMCwgMik7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDI6IFdyb25nIGxlbmd0aCwiLCAwLCBicy5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDI6IFdyb25nIHNpemUsIiwgMCwgYnMuc2l6ZSgpKTsKKworICAgICAgICBicy5jbGVhcig2MCwgNjQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QzOiBXcm9uZyBsZW5ndGgsIiwgMCwgYnMubGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QzOiBXcm9uZyBzaXplLCIsIDAsIGJzLnNpemUoKSk7CisKKyAgICAgICAgYnMuY2xlYXIoNjQsIDEyMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDQ6IFdyb25nIGxlbmd0aCwiLCAwLCBicy5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDQ6IFdyb25nIHNpemUsIiwgMCwgYnMuc2l6ZSgpKTsKKworICAgICAgICBicy5zZXQoMjUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3Q1OiBXcm9uZyBsZW5ndGgsIiwgMjYsIGJzLmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0NTogV3Jvbmcgc2l6ZSwiLCA2NCwgYnMuc2l6ZSgpKTsKKworICAgICAgICBicy5jbGVhcig2MCwgNjQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3Q2OiBXcm9uZyBsZW5ndGgsIiwgMjYsIGJzLmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0NjogV3Jvbmcgc2l6ZSwiLCA2NCwgYnMuc2l6ZSgpKTsKKworICAgICAgICBicy5jbGVhcig2NCwgMTIwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0NzogV3Jvbmcgc2l6ZSwiLCA2NCwgYnMuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0NzogV3JvbmcgbGVuZ3RoLCIsIDI2LCBicy5sZW5ndGgoKSk7CisKKyAgICAgICAgYnMuY2xlYXIoODApOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3Q4OiBXcm9uZyBzaXplLCIsIDY0LCBicy5zaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3Q4OiBXcm9uZyBsZW5ndGgsIiwgMjYsIGJzLmxlbmd0aCgpKTsKKworICAgICAgICBicy5jbGVhcigyNSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDk6IFdyb25nIHNpemUsIiwgNjQsIGJzLnNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDk6IFdyb25nIGxlbmd0aCwiLCAwLCBicy5sZW5ndGgoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJKCkgeworICAgICAgICBCaXRTZXQgYnMgPSBuZXcgQml0U2V0KCk7CisgICAgICAgIGJzLnNldCg4KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkdldCByZXR1cm5lZCB0cnVlIGZvciBpbmRleCBvdXQgb2YgcmFuZ2UiLCBlaWdodGJzLmdldCg5OSkpOworICAgICAgICBhc3NlcnRUcnVlKCJHZXQgcmV0dXJuZWQgZmFsc2UgZm9yIHNldCB2YWx1ZSIsIGVpZ2h0YnMuZ2V0KDMpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkdldCByZXR1cm5lZCB0cnVlIGZvciBhIG5vbiBzZXQgdmFsdWUiLCBicy5nZXQoMCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBicy5nZXQoLTEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBicyA9IG5ldyBCaXRTZXQoMSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJBY2Nlc3MgZ3JlYXRlciB0aGFuIHNpemUiLCBicy5nZXQoNjQpKTsKKworICAgICAgICBicyA9IG5ldyBCaXRTZXQoKTsKKyAgICAgICAgYnMuc2V0KDYzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCBoaWdoZXN0IGJpdCIsIGJzLmdldCg2MykpOworCisgICAgICAgIGJzID0gbmV3IEJpdFNldCgwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0MTogV3JvbmcgbGVuZ3RoLCIsIDAsIGJzLmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0MTogV3Jvbmcgc2l6ZSwiLCAwLCBicy5zaXplKCkpOworCisgICAgICAgIGJzLmdldCgyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0MjogV3JvbmcgbGVuZ3RoLCIsIDAsIGJzLmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0MjogV3Jvbmcgc2l6ZSwiLCAwLCBicy5zaXplKCkpOworCisgICAgICAgIGJzLmdldCg3MCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDM6IFdyb25nIGxlbmd0aCwiLCAwLCBicy5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDM6IFdyb25nIHNpemUsIiwgMCwgYnMuc2l6ZSgpKTsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SUkoKSB7CisgICAgICAgIEJpdFNldCBiaXRzZXQgPSBuZXcgQml0U2V0KDMwKTsKKyAgICAgICAgYml0c2V0LmdldCgzLCAzKTsKKworICAgICAgICBCaXRTZXQgYnMsIHJlc3VsdGJzLCBjb3JyZWN0YnM7CisgICAgICAgIGJzID0gbmV3IEJpdFNldCg1MTIpOworICAgICAgICBicy5zZXQoMywgOSk7CisgICAgICAgIGJzLnNldCgxMCwgMjApOworICAgICAgICBicy5zZXQoNjAsIDc1KTsKKyAgICAgICAgYnMuc2V0KDEyMSk7CisgICAgICAgIGJzLnNldCgxMzAsIDE0MCk7CisKKyAgICAgICAgLy8gcG9zMSBhbmQgcG9zMiBhcmUgaW4gdGhlIHNhbWUgYml0c2V0IGVsZW1lbnQsIGF0IGluZGV4MAorICAgICAgICByZXN1bHRicyA9IGJzLmdldCgzLCA2KTsKKyAgICAgICAgY29ycmVjdGJzID0gbmV3IEJpdFNldCgzKTsKKyAgICAgICAgY29ycmVjdGJzLnNldCgwLCAzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0MTogUmV0dXJuZWQgaW5jb3JyZWN0IEJpdFNldCIsIGNvcnJlY3RicywgcmVzdWx0YnMpOworCisgICAgICAgIC8vIHBvczEgYW5kIHBvczIgYXJlIGluIHRoZSBzYW1lIGJpdHNldCBlbGVtZW50LCBhdCBpbmRleCAxCisgICAgICAgIHJlc3VsdGJzID0gYnMuZ2V0KDEwMCwgMTI1KTsKKyAgICAgICAgY29ycmVjdGJzID0gbmV3IEJpdFNldCgyNSk7CisgICAgICAgIGNvcnJlY3Ricy5zZXQoMjEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QyOiBSZXR1cm5lZCBpbmNvcnJlY3QgQml0U2V0IiwgY29ycmVjdGJzLCByZXN1bHRicyk7CisKKyAgICAgICAgLy8gcG9zMSBpbiBiaXRzZXQgZWxlbWVudCBhdCBpbmRleCAwLCBhbmQgcG9zMiBpbiBiaXRzZXQgZWxlbWVudCBhdAorICAgICAgICAvLyBpbmRleCAxCisgICAgICAgIHJlc3VsdGJzID0gYnMuZ2V0KDE1LCAxMjUpOworICAgICAgICBjb3JyZWN0YnMgPSBuZXcgQml0U2V0KDI1KTsKKyAgICAgICAgY29ycmVjdGJzLnNldCgwLCA1KTsKKyAgICAgICAgY29ycmVjdGJzLnNldCg0NSwgNjApOworICAgICAgICBjb3JyZWN0YnMuc2V0KDEyMSAtIDE1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0MzogUmV0dXJuZWQgaW5jb3JyZWN0IEJpdFNldCIsIGNvcnJlY3RicywgcmVzdWx0YnMpOworCisgICAgICAgIC8vIHBvczEgaW4gYml0c2V0IGVsZW1lbnQgYXQgaW5kZXggMSwgYW5kIHBvczIgaW4gYml0c2V0IGVsZW1lbnQgYXQKKyAgICAgICAgLy8gaW5kZXggMgorICAgICAgICByZXN1bHRicyA9IGJzLmdldCg3MCwgMTQ1KTsKKyAgICAgICAgY29ycmVjdGJzID0gbmV3IEJpdFNldCg3NSk7CisgICAgICAgIGNvcnJlY3Ricy5zZXQoMCwgNSk7CisgICAgICAgIGNvcnJlY3Ricy5zZXQoNTEpOworICAgICAgICBjb3JyZWN0YnMuc2V0KDYwLCA3MCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDQ6IFJldHVybmVkIGluY29ycmVjdCBCaXRTZXQiLCBjb3JyZWN0YnMsIHJlc3VsdGJzKTsKKworICAgICAgICAvLyBwb3MxIGluIGJpdHNldCBlbGVtZW50IGF0IGluZGV4IDAsIGFuZCBwb3MyIGluIGJpdHNldCBlbGVtZW50IGF0CisgICAgICAgIC8vIGluZGV4IDIKKyAgICAgICAgcmVzdWx0YnMgPSBicy5nZXQoNSwgMTQ1KTsKKyAgICAgICAgY29ycmVjdGJzID0gbmV3IEJpdFNldCgxNDApOworICAgICAgICBjb3JyZWN0YnMuc2V0KDAsIDQpOworICAgICAgICBjb3JyZWN0YnMuc2V0KDUsIDE1KTsKKyAgICAgICAgY29ycmVjdGJzLnNldCg1NSwgNzApOworICAgICAgICBjb3JyZWN0YnMuc2V0KDExNik7CisgICAgICAgIGNvcnJlY3Ricy5zZXQoMTI1LCAxMzUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3Q1OiBSZXR1cm5lZCBpbmNvcnJlY3QgQml0U2V0IiwgY29ycmVjdGJzLCByZXN1bHRicyk7CisKKyAgICAgICAgLy8gcG9zMSBpbiBiaXRzZXQgZWxlbWVudCBhdCBpbmRleCAwLCBhbmQgcG9zMiBpbiBiaXRzZXQgZWxlbWVudCBhdAorICAgICAgICAvLyBpbmRleCAzCisgICAgICAgIHJlc3VsdGJzID0gYnMuZ2V0KDUsIDI1MCk7CisgICAgICAgIGNvcnJlY3RicyA9IG5ldyBCaXRTZXQoMjAwKTsKKyAgICAgICAgY29ycmVjdGJzLnNldCgwLCA0KTsKKyAgICAgICAgY29ycmVjdGJzLnNldCg1LCAxNSk7CisgICAgICAgIGNvcnJlY3Ricy5zZXQoNTUsIDcwKTsKKyAgICAgICAgY29ycmVjdGJzLnNldCgxMTYpOworICAgICAgICBjb3JyZWN0YnMuc2V0KDEyNSwgMTM1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0NjogUmV0dXJuZWQgaW5jb3JyZWN0IEJpdFNldCIsIGNvcnJlY3RicywgcmVzdWx0YnMpOworCisgICAgICAgIGFzc2VydEVxdWFscygiZXF1YWxpdHkgcHJpbmNpcGxlIDEgIiwgYnMuZ2V0KDAsIGJzLnNpemUoKSksIGJzKTsKKworICAgICAgICAvLyBtb3JlIHRlc3RzCisgICAgICAgIEJpdFNldCBiczIgPSBuZXcgQml0U2V0KDEyOSk7CisgICAgICAgIGJzMi5zZXQoMCwgMjApOworICAgICAgICBiczIuc2V0KDYyLCA2NSk7CisgICAgICAgIGJzMi5zZXQoMTIxLCAxMjMpOworICAgICAgICByZXN1bHRicyA9IGJzMi5nZXQoMSwgMTI0KTsKKyAgICAgICAgY29ycmVjdGJzID0gbmV3IEJpdFNldCgxMjkpOworICAgICAgICBjb3JyZWN0YnMuc2V0KDAsIDE5KTsKKyAgICAgICAgY29ycmVjdGJzLnNldCg2MSwgNjQpOworICAgICAgICBjb3JyZWN0YnMuc2V0KDEyMCwgMTIyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0NzogUmV0dXJuZWQgaW5jb3JyZWN0IEJpdFNldCIsIGNvcnJlY3RicywgcmVzdWx0YnMpOworCisgICAgICAgIC8vIGVxdWFsaXR5IHByaW5jaXBsZSB3aXRoIHNvbWUgYm91bmRhcnkgY29uZGl0aW9ucworICAgICAgICBiczIgPSBuZXcgQml0U2V0KDEyOCk7CisgICAgICAgIGJzMi5zZXQoMiwgMjApOworICAgICAgICBiczIuc2V0KDYyKTsKKyAgICAgICAgYnMyLnNldCgxMjEsIDEyMyk7CisgICAgICAgIGJzMi5zZXQoMTI3KTsKKyAgICAgICAgcmVzdWx0YnMgPSBiczIuZ2V0KDAsIGJzMi5zaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVxdWFsaXR5IHByaW5jaXBsZSAyICIsIHJlc3VsdGJzLCBiczIpOworCisgICAgICAgIGJzMiA9IG5ldyBCaXRTZXQoMTI4KTsKKyAgICAgICAgYnMyLnNldCgyLCAyMCk7CisgICAgICAgIGJzMi5zZXQoNjIpOworICAgICAgICBiczIuc2V0KDEyMSwgMTIzKTsKKyAgICAgICAgYnMyLnNldCgxMjcpOworICAgICAgICBiczIuZmxpcCgwLCAxMjgpOworICAgICAgICByZXN1bHRicyA9IGJzMi5nZXQoMCwgYnMuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlcXVhbGl0eSBwcmluY2lwbGUgMyAiLCByZXN1bHRicywgYnMyKTsKKworICAgICAgICBicyA9IG5ldyBCaXRTZXQoMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDE6IFdyb25nIGxlbmd0aCwiLCAwLCBicy5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDE6IFdyb25nIHNpemUsIiwgMCwgYnMuc2l6ZSgpKTsKKworICAgICAgICBicy5nZXQoMCwgMik7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDI6IFdyb25nIGxlbmd0aCwiLCAwLCBicy5sZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDI6IFdyb25nIHNpemUsIiwgMCwgYnMuc2l6ZSgpKTsKKworICAgICAgICBicy5nZXQoNjAsIDY0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0MzogV3JvbmcgbGVuZ3RoLCIsIDAsIGJzLmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0MzogV3Jvbmcgc2l6ZSwiLCAwLCBicy5zaXplKCkpOworCisgICAgICAgIGJzLmdldCg2NCwgMTIwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0NDogV3JvbmcgbGVuZ3RoLCIsIDAsIGJzLmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0NDogV3Jvbmcgc2l6ZSwiLCAwLCBicy5zaXplKCkpOworCisgICAgICAgIGJzLnNldCgyNSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDU6IFdyb25nIGxlbmd0aCwiLCAyNiwgYnMubGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3Q1OiBXcm9uZyBzaXplLCIsIDY0LCBicy5zaXplKCkpOworCisgICAgICAgIGJzLmdldCg2MCwgNjQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3Q2OiBXcm9uZyBsZW5ndGgsIiwgMjYsIGJzLmxlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0NjogV3Jvbmcgc2l6ZSwiLCA2NCwgYnMuc2l6ZSgpKTsKKworICAgICAgICBicy5nZXQoNjQsIDEyMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDc6IFdyb25nIHNpemUsIiwgNjQsIGJzLnNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDc6IFdyb25nIGxlbmd0aCwiLCAyNiwgYnMubGVuZ3RoKCkpOworCisgICAgICAgIGJzLmdldCg4MCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDg6IFdyb25nIHNpemUsIiwgNjQsIGJzLnNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDg6IFdyb25nIGxlbmd0aCwiLCAyNiwgYnMubGVuZ3RoKCkpOworCisgICAgICAgIGJzLmdldCgyNSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDk6IFdyb25nIHNpemUsIiwgNjQsIGJzLnNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDk6IFdyb25nIGxlbmd0aCwiLCAyNiwgYnMubGVuZ3RoKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBiczIuZ2V0KC0xLCAwKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJzMi5nZXQoYnMyLnNpemUoKS8yLCAwKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJzMi5nZXQoYnMyLnNpemUoKS8yLCAtMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0SSgpIHsKKyAgICAgICAgQml0U2V0IGJzID0gbmV3IEJpdFNldCgpOworICAgICAgICBicy5zZXQoOCk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBzZXQgYml0IiwgYnMuZ2V0KDgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnMuc2V0KC0xKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gVHJ5IHNldHRpbmcgYSBiaXQgb24gYSA2NCBib3VuZGFyeQorICAgICAgICBicy5zZXQoMTI4KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gZ3JvdyBCaXRTZXQiLCAxOTIsIGJzLnNpemUoKSk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBzZXQgYml0IiwgYnMuZ2V0KDEyOCkpOworCisgICAgICAgIGJzID0gbmV3IEJpdFNldCg2NCk7CisgICAgICAgIGZvciAoaW50IGkgPSBicy5zaXplKCk7IC0taSA+PSAwOykgeworICAgICAgICAgICAgYnMuc2V0KGkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0bHkgc2V0IiwgYnMuZ2V0KGkpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBsZW5ndGgiLCBicy5sZW5ndGgoKSA9PSAoaSArIDEpKTsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSBicy5zaXplKCk7IC0taiA+IGk7KQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdGx5IHNldCBiaXQgIiArIGosICFicy5nZXQoaikpOworICAgICAgICAgICAgZm9yIChpbnQgaiA9IGk7IC0taiA+PSAwOykKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3RseSBzZXQgYml0ICIgKyBqLCAhYnMuZ2V0KGopKTsKKyAgICAgICAgICAgIGJzLmNsZWFyKGkpOworICAgICAgICB9CisKKyAgICAgICAgYnMgPSBuZXcgQml0U2V0KDApOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0MTogV3JvbmcgbGVuZ3RoLCAiICsgYnMuc2l6ZSgpLCBicy5sZW5ndGgoKSA9PSAwKTsKKyAgICAgICAgYnMuc2V0KDApOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0MjogV3JvbmcgbGVuZ3RoIiArIGJzLnNpemUoKSwgYnMubGVuZ3RoKCkgPT0gMSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRJWigpIHsKKyAgICAgICAgZWlnaHRicy5zZXQoNSwgZmFsc2UpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgaGF2ZSBzZXQgYml0IDUgdG8gdHJ1ZSIsICFlaWdodGJzLmdldCg1KSk7CisKKyAgICAgICAgZWlnaHRicy5zZXQoNSwgdHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBoYXZlIHNldCBiaXQgNSB0byBmYWxzZSIsIGVpZ2h0YnMuZ2V0KDUpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZWlnaHRicy5zZXQoLTUsIGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRJSSgpIHsKKyAgICAgICAgQml0U2V0IGJpdHNldCA9IG5ldyBCaXRTZXQoMzApOworICAgICAgICBiaXRzZXQuc2V0KDI5LCAyOSk7CisKKyAgICAgICAgLy8gcG9zMSBhbmQgcG9zMiBhcmUgaW4gdGhlIHNhbWUgYml0c2V0IGVsZW1lbnQKKyAgICAgICAgQml0U2V0IGJzID0gbmV3IEJpdFNldCgxNik7CisgICAgICAgIGJzLnNldCg1KTsKKyAgICAgICAgYnMuc2V0KDE1KTsKKyAgICAgICAgYnMuc2V0KDcsIDExKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ7NSwgNywgOCwgOSwgMTAsIDE1fSIsIGJzLnRvU3RyaW5nKCkpOworICAgICAgICBmb3IgKGludCBpID0gMTY7IGkgPCBicy5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZG4ndCBoYXZlIHNldCBiaXQgIiArIGksIGJzLmdldChpKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBwb3MxIGFuZCBwb3MyIGlzIGluIHRoZSBzYW1lIGJpdHNldCBlbGVtZW50LCBib3VuZHJ5IHRlc3RpbmcKKyAgICAgICAgYnMgPSBuZXcgQml0U2V0KDE2KTsKKyAgICAgICAgYnMuc2V0KDcsIDY0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gZ3JvdyBCaXRTZXQiLCA2NCwgYnMuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA3OyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGRuJ3QgaGF2ZSBzZXQgYml0ICIgKyBpLCBicy5nZXQoaSkpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSA3OyBpIDwgNjQ7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIHNldCBiaXQgIiArIGksIGJzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZG4ndCBoYXZlIHNldCBiaXQgNjQiLCBicy5nZXQoNjQpKTsKKworICAgICAgICAvLyBtb3JlIGJvdW5kYXJ5IHRlc3RpbmcKKyAgICAgICAgYnMgPSBuZXcgQml0U2V0KDMyKTsKKyAgICAgICAgYnMuc2V0KDAsIDY0KTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2NDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gc2V0IGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkbid0IGhhdmUgc2V0IGJpdCA2NCIsIGJzLmdldCg2NCkpOworCisgICAgICAgIGJzID0gbmV3IEJpdFNldCgzMik7CisgICAgICAgIGJzLnNldCgwLCA2NSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNjU7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIHNldCBiaXQgIiArIGksIGJzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZG4ndCBoYXZlIHNldCBiaXQgNjUiLCBicy5nZXQoNjUpKTsKKworICAgICAgICAvLyBwb3MxIGFuZCBwb3MyIGFyZSBpbiB0d28gc2VxdWVudGlhbCBiaXRzZXQgZWxlbWVudHMKKyAgICAgICAgYnMgPSBuZXcgQml0U2V0KDEyOCk7CisgICAgICAgIGJzLnNldCg3KTsKKyAgICAgICAgYnMuc2V0KDExMCk7CisgICAgICAgIGJzLnNldCg5LCA3NCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgOTsgaSsrKSB7CisgICAgICAgICAgICBpZiAoaSA9PSA3KSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkbid0IGhhdmUgZmxpcHBlZCBiaXQgIiArIGksIGJzLmdldChpKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGRuJ3QgaGF2ZSBzZXQgYml0ICIgKyBpLCBicy5nZXQoaSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSA5OyBpIDwgNzQ7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIHNldCBiaXQgIiArIGksIGJzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDc0OyBpIDwgYnMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChpID09IDExMCkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIlNob3VsZG4ndCBoYXZlIGZsaXBwZWQgYml0ICIgKyBpLCBicy5nZXQoaSkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkbid0IGhhdmUgc2V0IGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHBvczEgYW5kIHBvczIgYXJlIGluIHR3byBub24tc2VxdWVudGlhbCBiaXRzZXQgZWxlbWVudHMKKyAgICAgICAgYnMgPSBuZXcgQml0U2V0KDI1Nik7CisgICAgICAgIGJzLnNldCg3KTsKKyAgICAgICAgYnMuc2V0KDI1NSk7CisgICAgICAgIGJzLnNldCg5LCAyMTkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDk7IGkrKykgeworICAgICAgICAgICAgaWYgKGkgPT0gNykgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIlNob3VsZG4ndCBoYXZlIHNldCBmbGlwcGVkICIgKyBpLCBicy5nZXQoaSkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkbid0IGhhdmUgc2V0IGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSA5OyBpIDwgMjE5OyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImZhaWxlZCB0byBzZXQgYml0ICIgKyBpLCBicy5nZXQoaSkpOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDIxOTsgaSA8IDI1NTsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkbid0IGhhdmUgc2V0IGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZG4ndCBoYXZlIGZsaXBwZWQgYml0IDI1NSIsIGJzLmdldCgyNTUpKTsKKworICAgICAgICAvLyB0ZXN0IGlsbGVnYWwgYXJncworICAgICAgICBicyA9IG5ldyBCaXRTZXQoMTApOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnMuc2V0KC0xLCAzKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJzLnNldCgyLCAtMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGJzLnNldCgyLCAyKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkJpdCBnb3Qgc2V0IGluY29ycmVjdGx5ICIsIGJzLmdldCgyKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJzLnNldCg0LCAyKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRJSVooKSB7CisgICAgICAgIGVpZ2h0YnMuc2V0KDMsIDYsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGhhdmUgc2V0IGJpdHMgMywgNCwgYW5kIDUgdG8gZmFsc2UiLCAhZWlnaHRicy5nZXQoMykKKyAgICAgICAgICAgICAgICAmJiAhZWlnaHRicy5nZXQoNCkgJiYgIWVpZ2h0YnMuZ2V0KDUpKTsKKworICAgICAgICBlaWdodGJzLnNldCgzLCA2LCB0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGhhdmUgc2V0IGJpdHMgMywgNCwgYW5kIDUgdG8gdHJ1ZSIsIGVpZ2h0YnMuZ2V0KDMpCisgICAgICAgICAgICAgICAgJiYgZWlnaHRicy5nZXQoNCkgJiYgZWlnaHRicy5nZXQoNSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlaWdodGJzLnNldCgtMywgNiwgZmFsc2UpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZWlnaHRicy5zZXQoMywgLTYsIGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVpZ2h0YnMuc2V0KDYsIDMsIGZhbHNlKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9mbGlwSSgpIHsKKyAgICAgICAgQml0U2V0IGJzID0gbmV3IEJpdFNldCgpOworICAgICAgICBicy5jbGVhcig4KTsKKyAgICAgICAgYnMuY2xlYXIoOSk7CisgICAgICAgIGJzLnNldCgxMCk7CisgICAgICAgIGJzLmZsaXAoOSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJGYWlsZWQgdG8gZmxpcCBiaXQiLCBicy5nZXQoOCkpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmxpcCBiaXQiLCBicy5nZXQoOSkpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmxpcCBiaXQiLCBicy5nZXQoMTApKTsKKworICAgICAgICBicy5zZXQoOCk7CisgICAgICAgIGJzLnNldCg5KTsKKyAgICAgICAgYnMuY2xlYXIoMTApOworICAgICAgICBicy5mbGlwKDkpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmxpcCBiaXQiLCBicy5nZXQoOCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiRmFpbGVkIHRvIGZsaXAgYml0IiwgYnMuZ2V0KDkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkZhaWxlZCB0byBmbGlwIGJpdCIsIGJzLmdldCgxMCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBicy5mbGlwKC0xKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gVHJ5IHNldHRpbmcgYSBiaXQgb24gYSA2NCBib3VuZGFyeQorICAgICAgICBicy5mbGlwKDEyOCk7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHRvIGdyb3cgQml0U2V0IiwgMTkyLCBicy5zaXplKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmxpcCBiaXQiLCBicy5nZXQoMTI4KSk7CisKKyAgICAgICAgYnMgPSBuZXcgQml0U2V0KDY0KTsKKyAgICAgICAgZm9yIChpbnQgaSA9IGJzLnNpemUoKTsgLS1pID49IDA7KSB7CisgICAgICAgICAgICBicy5mbGlwKGkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdDE6IEluY29ycmVjdGx5IGZsaXBwZWQgYml0IiArIGksIGJzLmdldChpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBsZW5ndGgiLCBpKzEsIGJzLmxlbmd0aCgpKTsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSBicy5zaXplKCk7IC0taiA+IGk7KSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdDI6IEluY29ycmVjdGx5IGZsaXBwZWQgYml0IiArIGosICFicy5nZXQoaikpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChpbnQgaiA9IGk7IC0taiA+PSAwOykgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIlRlc3QzOiBJbmNvcnJlY3RseSBmbGlwcGVkIGJpdCIgKyBqLCAhYnMuZ2V0KGopKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJzLmZsaXAoaSk7CisgICAgICAgIH0KKworICAgICAgICBCaXRTZXQgYnMwID0gbmV3IEJpdFNldCgwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0MTogV3Jvbmcgc2l6ZSIsIDAsIGJzMC5zaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QxOiBXcm9uZyBsZW5ndGgiLCAwLCBiczAubGVuZ3RoKCkpOworCisgICAgICAgIGJzMC5mbGlwKDApOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QyOiBXcm9uZyBzaXplIiwgNjQsIGJzMC5zaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QyOiBXcm9uZyBsZW5ndGgiLCAxLCBiczAubGVuZ3RoKCkpOworCisgICAgICAgIGJzMC5mbGlwKDYzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0MzogV3Jvbmcgc2l6ZSIsIDY0LCBiczAuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0MzogV3JvbmcgbGVuZ3RoIiwgNjQsIGJzMC5sZW5ndGgoKSk7CisKKyAgICAgICAgZWlnaHRicy5mbGlwKDcpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmxpcCBiaXQgNyIsICFlaWdodGJzLmdldCg3KSk7CisKKyAgICAgICAgLy8gQ2hlY2sgdG8gc2VlIGFsbCBvdGhlciBiaXRzIGFyZSBzdGlsbCBzZXQKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA3OyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZsaXAgZmxpcHBlZCBpbmNvcnJlY3QgYml0cyIsIGVpZ2h0YnMuZ2V0KGkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGVpZ2h0YnMuZmxpcCgxMjcpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmxpcCBiaXQgMTI3IiwgZWlnaHRicy5nZXQoMTI3KSk7CisKKyAgICAgICAgZWlnaHRicy5mbGlwKDEyNyk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBmbGlwIGJpdCAxMjciLCAhZWlnaHRicy5nZXQoMTI3KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9mbGlwSUkoKSB7CisgICAgICAgIEJpdFNldCBiaXRzZXQgPSBuZXcgQml0U2V0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjA7IGkrKykgeworICAgICAgICAgICAgYml0c2V0LnNldChpKTsKKyAgICAgICAgfQorICAgICAgICBiaXRzZXQuZmxpcCgxMCwgMTApOworCisgICAgICAgIC8vIHBvczEgYW5kIHBvczIgYXJlIGluIHRoZSBzYW1lIGJpdHNldCBlbGVtZW50CisgICAgICAgIEJpdFNldCBicyA9IG5ldyBCaXRTZXQoMTYpOworICAgICAgICBicy5zZXQoNyk7CisgICAgICAgIGJzLnNldCgxMCk7CisgICAgICAgIGJzLmZsaXAoNywgMTEpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDc7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkbid0IGhhdmUgZmxpcHBlZCBiaXQgIiArIGksICFicy5nZXQoaSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEZhbHNlKCJGYWlsZWQgdG8gZmxpcCBiaXQgNyIsIGJzLmdldCg3KSk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBmbGlwIGJpdCA4IiwgYnMuZ2V0KDgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGZsaXAgYml0IDkiLCBicy5nZXQoOSkpOworICAgICAgICBhc3NlcnRGYWxzZSgiRmFpbGVkIHRvIGZsaXAgYml0IDEwIiwgYnMuZ2V0KDEwKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAxMTsgaSA8IGJzLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGRuJ3QgaGF2ZSBmbGlwcGVkIGJpdCAiICsgaSwgIWJzLmdldChpKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBwb3MxIGFuZCBwb3MyIGlzIGluIHRoZSBzYW1lIGJpdHNldCBlbGVtZW50LCBib3VuZHJ5IHRlc3RpbmcKKyAgICAgICAgYnMgPSBuZXcgQml0U2V0KDE2KTsKKyAgICAgICAgYnMuc2V0KDcpOworICAgICAgICBicy5zZXQoMTApOworICAgICAgICBicy5mbGlwKDcsIDY0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gZ3JvdyBCaXRTZXQiLCA2NCwgYnMuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA3OyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlNob3VsZG4ndCBoYXZlIGZsaXBwZWQgYml0ICIgKyBpLCAhYnMuZ2V0KGkpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZSgiRmFpbGVkIHRvIGZsaXAgYml0IDciLCBicy5nZXQoNykpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmxpcCBiaXQgOCIsIGJzLmdldCg4KSk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBmbGlwIGJpdCA5IiwgYnMuZ2V0KDkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkZhaWxlZCB0byBmbGlwIGJpdCAxMCIsIGJzLmdldCgxMCkpOworICAgICAgICBmb3IgKGludCBpID0gMTE7IGkgPCA2NDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJmYWlsZWQgdG8gZmxpcCBiaXQgIiArIGksIGJzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZG4ndCBoYXZlIGZsaXBwZWQgYml0IDY0IiwgYnMuZ2V0KDY0KSk7CisKKyAgICAgICAgLy8gbW9yZSBib3VuZGFyeSB0ZXN0aW5nCisgICAgICAgIGJzID0gbmV3IEJpdFNldCgzMik7CisgICAgICAgIGJzLmZsaXAoMCwgNjQpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDY0OyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBmbGlwIGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkbid0IGhhdmUgZmxpcHBlZCBiaXQgNjQiLCBicy5nZXQoNjQpKTsKKworICAgICAgICBicyA9IG5ldyBCaXRTZXQoMzIpOworICAgICAgICBicy5mbGlwKDAsIDY1KTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2NTsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmxpcCBiaXQgIiArIGksIGJzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZG4ndCBoYXZlIGZsaXBwZWQgYml0IDY1IiwgYnMuZ2V0KDY1KSk7CisKKyAgICAgICAgLy8gcG9zMSBhbmQgcG9zMiBhcmUgaW4gdHdvIHNlcXVlbnRpYWwgYml0c2V0IGVsZW1lbnRzCisgICAgICAgIGJzID0gbmV3IEJpdFNldCgxMjgpOworICAgICAgICBicy5zZXQoNyk7CisgICAgICAgIGJzLnNldCgxMCk7CisgICAgICAgIGJzLnNldCg3Mik7CisgICAgICAgIGJzLnNldCgxMTApOworICAgICAgICBicy5mbGlwKDksIDc0KTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA3OyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGRuJ3QgaGF2ZSBmbGlwcGVkIGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGRuJ3QgaGF2ZSBmbGlwcGVkIGJpdCA3IiwgYnMuZ2V0KDcpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZG4ndCBoYXZlIGZsaXBwZWQgYml0IDgiLCBicy5nZXQoOCkpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmxpcCBiaXQgOSIsIGJzLmdldCg5KSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJGYWlsZWQgdG8gZmxpcCBiaXQgMTAiLCBicy5nZXQoMTApKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDExOyBpIDwgNzI7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZmFpbGVkIHRvIGZsaXAgYml0ICIgKyBpLCBicy5nZXQoaSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEZhbHNlKCJGYWlsZWQgdG8gZmxpcCBiaXQgNzIiLCBicy5nZXQoNzIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGZsaXAgYml0IDczIiwgYnMuZ2V0KDczKSk7CisgICAgICAgIGZvciAoaW50IGkgPSA3NDsgaSA8IDExMDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkbid0IGhhdmUgZmxpcHBlZCBiaXQgIiArIGksIGJzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkbid0IGhhdmUgZmxpcHBlZCBiaXQgMTEwIiwgYnMuZ2V0KDExMCkpOworICAgICAgICBmb3IgKGludCBpID0gMTExOyBpIDwgYnMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGRuJ3QgaGF2ZSBmbGlwcGVkIGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHBvczEgYW5kIHBvczIgYXJlIGluIHR3byBub24tc2VxdWVudGlhbCBiaXRzZXQgZWxlbWVudHMKKyAgICAgICAgYnMgPSBuZXcgQml0U2V0KDI1Nik7CisgICAgICAgIGJzLnNldCg3KTsKKyAgICAgICAgYnMuc2V0KDEwKTsKKyAgICAgICAgYnMuc2V0KDcyKTsKKyAgICAgICAgYnMuc2V0KDExMCk7CisgICAgICAgIGJzLnNldCgxODEpOworICAgICAgICBicy5zZXQoMjIwKTsKKyAgICAgICAgYnMuZmxpcCg5LCAyMTkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDc7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZG4ndCBoYXZlIGZsaXBwZWQgYml0ICIgKyBpLCBicy5nZXQoaSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZG4ndCBoYXZlIGZsaXBwZWQgYml0IDciLCBicy5nZXQoNykpOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkbid0IGhhdmUgZmxpcHBlZCBiaXQgOCIsIGJzLmdldCg4KSk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBmbGlwIGJpdCA5IiwgYnMuZ2V0KDkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkZhaWxlZCB0byBmbGlwIGJpdCAxMCIsIGJzLmdldCgxMCkpOworICAgICAgICBmb3IgKGludCBpID0gMTE7IGkgPCA3MjsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJmYWlsZWQgdG8gZmxpcCBiaXQgIiArIGksIGJzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoIkZhaWxlZCB0byBmbGlwIGJpdCA3MiIsIGJzLmdldCg3MikpOworICAgICAgICBmb3IgKGludCBpID0gNzM7IGkgPCAxMTA7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZmFpbGVkIHRvIGZsaXAgYml0ICIgKyBpLCBicy5nZXQoaSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEZhbHNlKCJGYWlsZWQgdG8gZmxpcCBiaXQgMTEwIiwgYnMuZ2V0KDExMCkpOworICAgICAgICBmb3IgKGludCBpID0gMTExOyBpIDwgMTgxOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImZhaWxlZCB0byBmbGlwIGJpdCAiICsgaSwgYnMuZ2V0KGkpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZSgiRmFpbGVkIHRvIGZsaXAgYml0IDE4MSIsIGJzLmdldCgxODEpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE4MjsgaSA8IDIxOTsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJmYWlsZWQgdG8gZmxpcCBiaXQgIiArIGksIGJzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZG4ndCBoYXZlIGZsaXBwZWQgYml0IDIxOSIsIGJzLmdldCgyMTkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkbid0IGhhdmUgZmxpcHBlZCBiaXQgMjIwIiwgYnMuZ2V0KDIyMCkpOworICAgICAgICBmb3IgKGludCBpID0gMjIxOyBpIDwgYnMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlNob3VsZG4ndCBoYXZlIGZsaXBwZWQgYml0ICIgKyBpLCAhYnMuZ2V0KGkpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3QgaWxsZWdhbCBhcmdzCisgICAgICAgIGJzID0gbmV3IEJpdFNldCgxMCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBicy5mbGlwKC0xLCAzKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJzLmZsaXAoMiwgLTEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnMuZmxpcCg0LCAyKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF8xMTE0NzgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQml0U2V0IHNob3VsZG4ndCBiZSBtb2RpZmllZCBieSBhbnkgb2YgdGhlIG9wZXJhdGlvbnMgYmVsb3csCisgICAgICAgIC8vIHNpbmNlIHRoZSBhZmZlY3RlZCBiaXRzIGZvciB0aGVzZSBtZXRob2RzIGFyZSBkZWZpbmVkIGFzIGluY2x1c2l2ZSBvZgorICAgICAgICAvLyBwb3MxLCBleGNsdXNpdmUgb2YgcG9zMi4KKyAgICAgICAgZWlnaHRicy5mbGlwKDAsIDApOworICAgICAgICBhc3NlcnRUcnVlKCJCaXQgZ290IGZsaXBwZWQgaW5jb3JyZWN0bHkgIiwgZWlnaHRicy5nZXQoMCkpOworCisgICAgICAgIEJpdFNldCBic25ldyA9IGVpZ2h0YnMuZ2V0KDIsIDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYnNuZXcuY2FyZGluYWxpdHkoKSk7CisKKyAgICAgICAgZWlnaHRicy5zZXQoMTAsIDEwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQml0IGdvdCBzZXQgaW5jb3JyZWN0bHkgIiwgIWVpZ2h0YnMuZ2V0KDEwKSk7CisKKyAgICAgICAgZWlnaHRicy5jbGVhcigzLCAzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQml0IGNsZWFyZWQgaW5jb3JyZWN0bHkgIiwgZWlnaHRicy5nZXQoMykpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW50ZXJzZWN0c0xqYXZhX3V0aWxfQml0U2V0KCkgeworICAgICAgICBCaXRTZXQgYnMgPSBuZXcgQml0U2V0KDUwMCk7CisgICAgICAgIGJzLnNldCg1KTsKKyAgICAgICAgYnMuc2V0KDYzKTsKKyAgICAgICAgYnMuc2V0KDY0KTsKKyAgICAgICAgYnMuc2V0KDcxLCAxMTApOworICAgICAgICBicy5zZXQoMTI3LCAxMzApOworICAgICAgICBicy5zZXQoMTkyKTsKKyAgICAgICAgYnMuc2V0KDQ1MCk7CisKKyAgICAgICAgQml0U2V0IGJzMiA9IG5ldyBCaXRTZXQoOCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUZXN0MTogaW50ZXJzZWN0cygpIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIGJzLmludGVyc2VjdHMoYnMyKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUZXN0MTogaW50ZXJzZWN0cygpIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIGJzMi5pbnRlcnNlY3RzKGJzKSk7CisKKyAgICAgICAgYnMyLnNldCg0KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRlc3QyOiBpbnRlcnNlY3RzKCkgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgYnMuaW50ZXJzZWN0cyhiczIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRlc3QyOiBpbnRlcnNlY3RzKCkgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgYnMyLmludGVyc2VjdHMoYnMpKTsKKworICAgICAgICBiczIuY2xlYXIoKTsKKyAgICAgICAgYnMyLnNldCg1KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdDM6IGludGVyc2VjdHMoKSByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBicy5pbnRlcnNlY3RzKGJzMikpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0MzogaW50ZXJzZWN0cygpIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIGJzMi5pbnRlcnNlY3RzKGJzKSk7CisKKyAgICAgICAgYnMyLmNsZWFyKCk7CisgICAgICAgIGJzMi5zZXQoNjMpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0NDogaW50ZXJzZWN0cygpIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIGJzLmludGVyc2VjdHMoYnMyKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3Q0OiBpbnRlcnNlY3RzKCkgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgYnMyLmludGVyc2VjdHMoYnMpKTsKKworICAgICAgICBiczIuY2xlYXIoKTsKKyAgICAgICAgYnMyLnNldCg4MCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3Q1OiBpbnRlcnNlY3RzKCkgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgYnMuaW50ZXJzZWN0cyhiczIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdDU6IGludGVyc2VjdHMoKSByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBiczIuaW50ZXJzZWN0cyhicykpOworCisgICAgICAgIGJzMi5jbGVhcigpOworICAgICAgICBiczIuc2V0KDEyNyk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3Q2OiBpbnRlcnNlY3RzKCkgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgYnMuaW50ZXJzZWN0cyhiczIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdDY6IGludGVyc2VjdHMoKSByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBiczIuaW50ZXJzZWN0cyhicykpOworCisgICAgICAgIGJzMi5jbGVhcigpOworICAgICAgICBiczIuc2V0KDE5Mik7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3Q3OiBpbnRlcnNlY3RzKCkgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgYnMuaW50ZXJzZWN0cyhiczIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdDc6IGludGVyc2VjdHMoKSByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBiczIuaW50ZXJzZWN0cyhicykpOworCisgICAgICAgIGJzMi5jbGVhcigpOworICAgICAgICBiczIuc2V0KDQ1MCk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3Q4OiBpbnRlcnNlY3RzKCkgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgYnMuaW50ZXJzZWN0cyhiczIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdDg6IGludGVyc2VjdHMoKSByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCBiczIuaW50ZXJzZWN0cyhicykpOworCisgICAgICAgIGJzMi5jbGVhcigpOworICAgICAgICBiczIuc2V0KDUwMCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUZXN0OTogaW50ZXJzZWN0cygpIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIGJzLmludGVyc2VjdHMoYnMyKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUZXN0OTogaW50ZXJzZWN0cygpIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIGJzMi5pbnRlcnNlY3RzKGJzKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9hbmRMamF2YV91dGlsX0JpdFNldCgpIHsKKyAgICAgICAgQml0U2V0IGJzID0gbmV3IEJpdFNldCgxMjgpOworICAgICAgICAvLyBJbml0aWFsaXplIHRoZSBib3R0b20gaGFsZiBvZiB0aGUgQml0U2V0CisgICAgICAgIGZvciAoaW50IGkgPSA2NDsgaSA8IDEyODsgaSsrKSB7CisgICAgICAgICAgICBicy5zZXQoaSk7CisgICAgICAgIH0KKyAgICAgICAgZWlnaHRicy5hbmQoYnMpOworICAgICAgICBhc3NlcnRUcnVlKCJBTkQgZmFpbGVkIHRvIGNsZWFyIGJpdHMiLCAhZWlnaHRicy5lcXVhbHMoYnMpKTsKKyAgICAgICAgZWlnaHRicy5zZXQoMyk7CisgICAgICAgIGJzLnNldCgzKTsKKyAgICAgICAgZWlnaHRicy5hbmQoYnMpOworICAgICAgICBhc3NlcnRUcnVlKCJBTkQgZmFpbGVkIHRvIG1haW50YWluIHNldCBiaXRzIiwgYnMuZ2V0KDMpKTsKKyAgICAgICAgYnMuYW5kKGVpZ2h0YnMpOworICAgICAgICBmb3IgKGludCBpID0gNjQ7IGkgPCAxMjg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGNsZWFyIGV4dHJhIGJpdHMgaW4gdGhlIHJlY2VpdmVyIEJpdFNldCIsICFicy5nZXQoaSkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9hbmROb3RMamF2YV91dGlsX0JpdFNldCgpIHsKKyAgICAgICAgQml0U2V0IGJzID0gKEJpdFNldCkgZWlnaHRicy5jbG9uZSgpOworICAgICAgICBicy5jbGVhcig1KTsKKyAgICAgICAgQml0U2V0IGJzMiA9IG5ldyBCaXRTZXQoKTsKKyAgICAgICAgYnMyLnNldCgyKTsKKyAgICAgICAgYnMyLnNldCgzKTsKKyAgICAgICAgYnMuYW5kTm90KGJzMik7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGJpdHNldCBhZnRlciBhbmROb3QiLAorICAgICAgICAgICAgICAgICJ7MCwgMSwgNCwgNiwgN30iLCBicy50b1N0cmluZygpKTsKKworICAgICAgICBicyA9IG5ldyBCaXRTZXQoMCk7CisgICAgICAgIGJzLmFuZE5vdChiczIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBzaXplIiwgMCwgYnMuc2l6ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X29yTGphdmFfdXRpbF9CaXRTZXQoKSB7CisgICAgICAgIEJpdFNldCBicyA9IG5ldyBCaXRTZXQoMTI4KTsKKyAgICAgICAgYnMub3IoZWlnaHRicyk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgODsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJPUiBmYWlsZWQgdG8gc2V0IGJpdHMiLCBicy5nZXQoaSkpOworICAgICAgICB9CisgICAgICAgIGJzID0gbmV3IEJpdFNldCgwKTsKKyAgICAgICAgYnMub3IoZWlnaHRicyk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgODsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJPUigwKSBmYWlsZWQgdG8gc2V0IGJpdHMiLCBicy5nZXQoaSkpOworICAgICAgICB9CisgICAgICAgIGVpZ2h0YnMuY2xlYXIoNSk7CisgICAgICAgIGJzID0gbmV3IEJpdFNldCgxMjgpOworICAgICAgICBicy5vcihlaWdodGJzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiT1Igc2V0IGEgYml0IHdoaWNoIHNob3VsZCBiZSBvZmYiLCAhYnMuZ2V0KDUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3hvckxqYXZhX3V0aWxfQml0U2V0KCkgeworICAgICAgICBCaXRTZXQgYnMgPSAoQml0U2V0KSBlaWdodGJzLmNsb25lKCk7CisgICAgICAgIGJzLnhvcihlaWdodGJzKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA4OyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlhPUiBmYWlsZWQgdG8gY2xlYXIgYml0ICIgKyBpICsgYnMsICFicy5nZXQoaSkpOworICAgICAgICB9CisgICAgICAgIGJzLnhvcihlaWdodGJzKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA4OyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlhPUiBmYWlsZWQgdG8gc2V0IGJpdCAiICsgaSArIGJzLCBicy5nZXQoaSkpOworICAgICAgICB9CisgICAgICAgIGJzID0gbmV3IEJpdFNldCgwKTsKKyAgICAgICAgYnMueG9yKGVpZ2h0YnMpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiWE9SKDApIGZhaWxlZCB0byBzZXQgYml0ICIgKyBpICsgYnMsIGJzLmdldChpKSk7CisgICAgICAgIH0KKyAgICAgICAgYnMgPSBuZXcgQml0U2V0KCk7CisgICAgICAgIGJzLnNldCg2Myk7CisgICAgICAgIGFzc2VydEVxdWFscygiezYzfSIsIGJzLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2l6ZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3Qgc2l6ZSIsIDY0LCBlaWdodGJzLnNpemUoKSk7CisgICAgICAgIGVpZ2h0YnMuc2V0KDEyOSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBzaXplIiwgZWlnaHRicy5zaXplKCkgPj0gMTI5KTsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9TdHJpbmcoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHN0cmluZyByZXByZXNlbnRhdGlvbiIsICJ7MCwgMSwgMiwgMywgNCwgNSwgNiwgN30iLCBlaWdodGJzLnRvU3RyaW5nKCkpOworICAgICAgICBlaWdodGJzLmNsZWFyKDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBzdHJpbmcgcmVwcmVzZW50YXRpb24iLCAiezAsIDEsIDMsIDQsIDUsIDYsIDd9IiwgZWlnaHRicy50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xlbmd0aCgpIHsKKyAgICAgICAgQml0U2V0IGJzID0gbmV3IEJpdFNldCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoYnMudG9TdHJpbmcoKSwgMCwgYnMubGVuZ3RoKCkpOworICAgICAgICBicy5zZXQoNSk7CisgICAgICAgIGFzc2VydEVxdWFscyhicy50b1N0cmluZygpLCA2LCBicy5sZW5ndGgoKSk7CisgICAgICAgIGJzLnNldCgxMCk7CisgICAgICAgIGFzc2VydEVxdWFscyhicy50b1N0cmluZygpLCAxMSwgYnMubGVuZ3RoKCkpOworICAgICAgICBicy5zZXQoNDMyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJzLnRvU3RyaW5nKCksIDQzMywgYnMubGVuZ3RoKCkpOworICAgICAgICBicy5zZXQoMzAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJzLnRvU3RyaW5nKCksIDQzMywgYnMubGVuZ3RoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbmV4dFNldEJpdEkoKSB7CisgICAgICAgIEJpdFNldCBicyA9IG5ldyBCaXRTZXQoNTAwKTsKKyAgICAgICAgYnMuc2V0KDUpOworICAgICAgICBicy5zZXQoMzIpOworICAgICAgICBicy5zZXQoNjMpOworICAgICAgICBicy5zZXQoNjQpOworICAgICAgICBicy5zZXQoNzEsIDExMCk7CisgICAgICAgIGJzLnNldCgxMjcsIDEzMCk7CisgICAgICAgIGJzLnNldCgxOTMpOworICAgICAgICBicy5zZXQoNDUwKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJzLm5leHRTZXRCaXQoLTEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIGJzLm5leHRTZXRCaXQoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgYnMubmV4dFNldEJpdCg1KSk7CisgICAgICAgIGFzc2VydEVxdWFscygzMiwgYnMubmV4dFNldEJpdCg2KSk7CisgICAgICAgIGFzc2VydEVxdWFscygzMiwgYnMubmV4dFNldEJpdCgzMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoNjMsIGJzLm5leHRTZXRCaXQoMzMpKTsKKworICAgICAgICAvLyBib3VuZGFyeSB0ZXN0cworICAgICAgICBhc3NlcnRFcXVhbHMoNjMsIGJzLm5leHRTZXRCaXQoNjMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDY0LCBicy5uZXh0U2V0Qml0KDY0KSk7CisKKyAgICAgICAgLy8gYXQgYml0c2V0IGVsZW1lbnQgMQorICAgICAgICBhc3NlcnRFcXVhbHMoNzEsIGJzLm5leHRTZXRCaXQoNjUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDcxLCBicy5uZXh0U2V0Qml0KDcxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg3MiwgYnMubmV4dFNldEJpdCg3MikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMTI3LCBicy5uZXh0U2V0Qml0KDExMCkpOworCisgICAgICAgIC8vIGJvdW5kYXJ5IHRlc3RzCisgICAgICAgIGFzc2VydEVxdWFscygxMjcsIGJzLm5leHRTZXRCaXQoMTI3KSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMjgsIGJzLm5leHRTZXRCaXQoMTI4KSk7CisKKyAgICAgICAgLy8gYXQgYml0c2V0IGVsZW1lbnQgMgorICAgICAgICBhc3NlcnRFcXVhbHMoMTkzLCBicy5uZXh0U2V0Qml0KDEzMCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygxOTMsIGJzLm5leHRTZXRCaXQoMTkxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxOTMsIGJzLm5leHRTZXRCaXQoMTkyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxOTMsIGJzLm5leHRTZXRCaXQoMTkzKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg0NTAsIGJzLm5leHRTZXRCaXQoMTk0KSk7CisgICAgICAgIGFzc2VydEVxdWFscyg0NTAsIGJzLm5leHRTZXRCaXQoMjU1KSk7CisgICAgICAgIGFzc2VydEVxdWFscyg0NTAsIGJzLm5leHRTZXRCaXQoMjU2KSk7CisgICAgICAgIGFzc2VydEVxdWFscyg0NTAsIGJzLm5leHRTZXRCaXQoNDUwKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBicy5uZXh0U2V0Qml0KDQ1MSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGJzLm5leHRTZXRCaXQoNTExKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgYnMubmV4dFNldEJpdCg1MTIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBicy5uZXh0U2V0Qml0KDgwMCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbmV4dENsZWFyQml0SSgpIHsKKyAgICAgICAgQml0U2V0IGJzID0gbmV3IEJpdFNldCg1MDApOworICAgICAgICAvLyBlbnN1cmUgYWxsIHRoZSBiaXRzIGZyb20gMCB0byBicy5zaXplKCkgLSAxIGFyZSBzZXQgdG8gdHJ1ZQorICAgICAgICBicy5zZXQoMCwgYnMuc2l6ZSgpIC0gMSk7CisgICAgICAgIGJzLnNldChicy5zaXplKCkgLSAxKTsKKyAgICAgICAgYnMuY2xlYXIoNSk7CisgICAgICAgIGJzLmNsZWFyKDMyKTsKKyAgICAgICAgYnMuY2xlYXIoNjMpOworICAgICAgICBicy5jbGVhcig2NCk7CisgICAgICAgIGJzLmNsZWFyKDcxLCAxMTApOworICAgICAgICBicy5jbGVhcigxMjcsIDEzMCk7CisgICAgICAgIGJzLmNsZWFyKDE5Myk7CisgICAgICAgIGJzLmNsZWFyKDQ1MCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBicy5uZXh0Q2xlYXJCaXQoLTEpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIGJzLm5leHRDbGVhckJpdCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBicy5uZXh0Q2xlYXJCaXQoNSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMzIsIGJzLm5leHRDbGVhckJpdCg2KSk7CisgICAgICAgIGFzc2VydEVxdWFscygzMiwgYnMubmV4dENsZWFyQml0KDMyKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg2MywgYnMubmV4dENsZWFyQml0KDMzKSk7CisKKyAgICAgICAgLy8gYm91bmRhcnkgdGVzdHMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDYzLCBicy5uZXh0Q2xlYXJCaXQoNjMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDY0LCBicy5uZXh0Q2xlYXJCaXQoNjQpKTsKKworICAgICAgICAvLyBhdCBiaXRzZXQgZWxlbWVudCAxCisgICAgICAgIGFzc2VydEVxdWFscyg3MSwgYnMubmV4dENsZWFyQml0KDY1KSk7CisgICAgICAgIGFzc2VydEVxdWFscyg3MSwgYnMubmV4dENsZWFyQml0KDcxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg3MiwgYnMubmV4dENsZWFyQml0KDcyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMjcsIGJzLm5leHRDbGVhckJpdCgxMTApKTsKKworICAgICAgICAvLyBib3VuZGFyeSB0ZXN0cworICAgICAgICBhc3NlcnRFcXVhbHMoMTI3LCBicy5uZXh0Q2xlYXJCaXQoMTI3KSk7CisgICAgICAgIGFzc2VydEVxdWFscygxMjgsIGJzLm5leHRDbGVhckJpdCgxMjgpKTsKKworICAgICAgICAvLyBhdCBiaXRzZXQgZWxlbWVudCAyCisgICAgICAgIGFzc2VydEVxdWFscygxOTMsIGJzLm5leHRDbGVhckJpdCgxMzApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDE5MywgYnMubmV4dENsZWFyQml0KDE5MSkpOworCisgICAgICAgIGFzc2VydEVxdWFscygxOTMsIGJzLm5leHRDbGVhckJpdCgxOTIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDE5MywgYnMubmV4dENsZWFyQml0KDE5MykpOworICAgICAgICBhc3NlcnRFcXVhbHMoNDUwLCBicy5uZXh0Q2xlYXJCaXQoMTk0KSk7CisgICAgICAgIGFzc2VydEVxdWFscyg0NTAsIGJzLm5leHRDbGVhckJpdCgyNTUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQ1MCwgYnMubmV4dENsZWFyQml0KDI1NikpOworICAgICAgICBhc3NlcnRFcXVhbHMoNDUwLCBicy5uZXh0Q2xlYXJCaXQoNDUwKSk7CisKKyAgICAgICAgLy8gYml0c2V0IGhhcyAxIHN0aWxsIHRoZSBlbmQgb2YgYnMuc2l6ZSgpIC0xLCBidXQgY2FsbGluZyBuZXh0Q2xlYXJCaXQKKyAgICAgICAgLy8gd2l0aCBhbnkgaW5kZXggdmFsdWUgYWZ0ZXIgdGhlIGxhc3QgdHJ1ZSBiaXQgc2hvdWxkIHJldHVybiBicy5zaXplKCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUxMiwgYnMubmV4dENsZWFyQml0KDQ1MSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNTEyLCBicy5uZXh0Q2xlYXJCaXQoNTExKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg1MTIsIGJzLm5leHRDbGVhckJpdCg1MTIpKTsKKworICAgICAgICAvLyBpZiB0aGUgaW5kZXggaXMgbGFyZ2VyIHRoYW4gYnMuc2l6ZSgpLCBuZXh0Q2xlYXJCaXQgc2hvdWxkIHJldHVybiBpbmRleAorICAgICAgICBhc3NlcnRFcXVhbHMoNTEzLCBicy5uZXh0Q2xlYXJCaXQoNTEzKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg4MDAsIGJzLm5leHRDbGVhckJpdCg4MDApKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzRW1wdHkoKSB7CisgICAgICAgIEJpdFNldCBicyA9IG5ldyBCaXRTZXQoNTAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdDogaXNFbXB0eSgpIHJldHVybmVkIHdyb25nIHZhbHVlIiwgYnMuaXNFbXB0eSgpKTsKKworICAgICAgICAvLyBhdCBiaXRzZXQgZWxlbWVudCAwCisgICAgICAgIGJzLnNldCgzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRlc3QwOiBpc0VtcHR5KCkgcmV0dXJuZWQgd3JvbmcgdmFsdWUiLCBicy5pc0VtcHR5KCkpOworCisgICAgICAgIC8vIGF0IGJpdHNldCBlbGVtZW50IDEKKyAgICAgICAgYnMuY2xlYXIoKTsKKyAgICAgICAgYnMuc2V0KDEyKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRlc3QxOiBpc0VtcHR5KCkgcmV0dXJuZWQgd3JvbmcgdmFsdWUiLCBicy5pc0VtcHR5KCkpOworCisgICAgICAgIC8vIGF0IGJpdHNldCBlbGVtZW50IDIKKyAgICAgICAgYnMuY2xlYXIoKTsKKyAgICAgICAgYnMuc2V0KDEyOCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUZXN0MjogaXNFbXB0eSgpIHJldHVybmVkIHdyb25nIHZhbHVlIiwgYnMuaXNFbXB0eSgpKTsKKworICAgICAgICAvLyBib3VuZGFyeSB0ZXN0aW5nCisgICAgICAgIGJzLmNsZWFyKCk7CisgICAgICAgIGJzLnNldCg0NTkpOworICAgICAgICBhc3NlcnRGYWxzZSgiVGVzdDM6IGlzRW1wdHkoKSByZXR1cm5lZCB3cm9uZyB2YWx1ZSIsIGJzLmlzRW1wdHkoKSk7CisKKyAgICAgICAgYnMuY2xlYXIoKTsKKyAgICAgICAgYnMuc2V0KDUxMSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUZXN0NDogaXNFbXB0eSgpIHJldHVybmVkIHdyb25nIHZhbHVlIiwgYnMuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NhcmRpbmFsaXR5KCkgeworICAgICAgICBCaXRTZXQgYnMgPSBuZXcgQml0U2V0KDUwMCk7CisgICAgICAgIGJzLnNldCg1KTsKKyAgICAgICAgYnMuc2V0KDMyKTsKKyAgICAgICAgYnMuc2V0KDYzKTsKKyAgICAgICAgYnMuc2V0KDY0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJzLnRvU3RyaW5nKCksIDQsIGJzLmNhcmRpbmFsaXR5KCkpOworICAgICAgICBicy5zZXQoNzEsIDExMCk7CisgICAgICAgIGJzLnNldCgxMjcsIDEzMCk7CisgICAgICAgIGJzLnNldCgxOTMpOworICAgICAgICBicy5zZXQoNDUwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGJzLnRvU3RyaW5nKCksIDQ4LCBicy5jYXJkaW5hbGl0eSgpKTsKKworICAgICAgICBicy5mbGlwKDAsIDUwMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiY2FyZGluYWxpdHkoKSByZXR1cm5lZCB3cm9uZyB2YWx1ZSIsIDQ1MiwgYnMKKyAgICAgICAgICAgICAgICAuY2FyZGluYWxpdHkoKSk7CisKKyAgICAgICAgYnMuY2xlYXIoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjYXJkaW5hbGl0eSgpIHJldHVybmVkIHdyb25nIHZhbHVlIiwgMCwgYnMuY2FyZGluYWxpdHkoKSk7CisKKyAgICAgICAgYnMuc2V0KDAsIDUwMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiY2FyZGluYWxpdHkoKSByZXR1cm5lZCB3cm9uZyB2YWx1ZSIsIDUwMCwgYnMKKyAgICAgICAgICAgICAgICAuY2FyZGluYWxpdHkoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludEJpdHNldChCaXRTZXQgYnMpIHsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7CisgICAgICAgIGZvciAoaW50IGkgPSBicy5zaXplKCkgLSAxOyBpID49IDA7IGktLSkgeworICAgICAgICAgICAgaWYgKGJzLmdldChpKSkKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KDEpOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoMCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgZWlnaHRicyA9IG5ldyBCaXRTZXQoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA4OyBpKyspIHsKKyAgICAgICAgICAgIGVpZ2h0YnMuc2V0KGkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQ2FsZW5kYXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9DYWxlbmRhclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZTMxMjE2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQ2FsZW5kYXJUZXN0LmphdmEKQEAgLTAsMCArMSwxMDk5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLnRleHQuRGF0ZUZvcm1hdFN5bWJvbHM7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkudGVzdGZyYW1ld29yay5zZXJpYWxpemF0aW9uLlNlcmlhbGl6YXRpb25UZXN0OworCitwdWJsaWMgY2xhc3MgQ2FsZW5kYXJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKwkKKwlMb2NhbGUgZGVmYXVsdExvY2FsZTsKKworCS8qKgorCSAqIGphdmEudXRpbC5DYWxlbmRhciNzZXQoaW50LCBpbnQpCisJICovCisJcHVibGljIHZvaWQgdGVzdF9zZXRJSSgpIHsKKwkJLy8gVGVzdCBmb3IgY29ycmVjdCByZXN1bHQgZGVmaW5lZCBieSB0aGUgbGFzdCBzZXQgZmllbGQKKwkJQ2FsZW5kYXIgY2FsID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkVTVCIpKTsKKworCQljYWwuY2xlYXIoKTsKKwkJY2FsLnNldChDYWxlbmRhci5ZRUFSLCAyMDAyKTsKKwkJYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHJlc3VsdCAwOiAiICsgY2FsLmdldFRpbWUoKS5nZXRUaW1lKCksIGNhbAorCQkJCS5nZXRUaW1lKCkuZ2V0VGltZSgpID09IDEwMDk4NjEyMDAwMDBMKTsKKworCQljYWwuY2xlYXIoKTsKKwkJY2FsLnNldChDYWxlbmRhci5ZRUFSLCAyMDAyKTsKKwkJY2FsLnNldChDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuTUFSQ0gpOworCQlhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcmVzdWx0IDBhOiAiICsgY2FsLmdldFRpbWUoKSwgY2FsLmdldFRpbWUoKQorCQkJCS5nZXRUaW1lKCkgPT0gMTAxNDk1ODgwMDAwMEwpOworCisJCWNhbC5jbGVhcigpOworCQljYWwuc2V0KENhbGVuZGFyLllFQVIsIDIwMDIpOworCQljYWwuc2V0KENhbGVuZGFyLkRBVEUsIDI0KTsKKwkJYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHJlc3VsdCAwYjogIiArIGNhbC5nZXRUaW1lKCksIGNhbC5nZXRUaW1lKCkKKwkJCQkuZ2V0VGltZSgpID09IDEwMTE4NDg0MDAwMDBMKTsKKworCQljYWwuc2V0KENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5PQ1RPQkVSKTsKKwkJY2FsLnNldChDYWxlbmRhci5EQVRFLCAzMSk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuTU9OVEgsIENhbGVuZGFyLk5PVkVNQkVSKTsKKwkJY2FsLnNldChDYWxlbmRhci5EQVRFLCAyNik7CisJCWFzc2VydFRydWUoIkluY29ycmVjdCBtb250aDogIiArIGNhbC5nZXQoQ2FsZW5kYXIuTU9OVEgpLCBjYWwKKwkJCQkuZ2V0KENhbGVuZGFyLk1PTlRIKSA9PSBDYWxlbmRhci5OT1ZFTUJFUik7CisKKwkJaW50IGRvdyA9IGNhbC5nZXQoQ2FsZW5kYXIuREFZX09GX1dFRUspOworCQljYWwuc2V0KENhbGVuZGFyLkRBVEUsIDI3KTsKKwkJYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IERBWV9PRl9XRUVLOiAiICsgY2FsLmdldChDYWxlbmRhci5EQVlfT0ZfV0VFSykKKwkJCQkrICIgZXhwZWN0ZWQ6ICIgKyBkb3csIGNhbC5nZXQoQ2FsZW5kYXIuREFZX09GX1dFRUspICE9IGRvdyk7CisKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1dFRUssIENhbGVuZGFyLk1PTkRBWSk7CisJCWFzc2VydFRydWUoIkluY29ycmVjdCByZXN1bHQgMGMxOiAiICsgY2FsLmdldFRpbWUoKS5nZXRUaW1lKCksIGNhbAorCQkJCS5nZXRUaW1lKCkuZ2V0VGltZSgpID09IDEwMTAzNzk2MDAwMDBMKTsKKworCQljYWwuY2xlYXIoKTsKKwkJY2FsLnNldChDYWxlbmRhci5ZRUFSLCAyMDAyKTsKKwkJY2FsLnNldChDYWxlbmRhci5EQVlfT0ZfV0VFSywgQ2FsZW5kYXIuVFVFU0RBWSk7CisJCWFzc2VydFRydWUoIkluY29ycmVjdCByZXN1bHQgMGMyOiAiICsgY2FsLmdldFRpbWUoKS5nZXRUaW1lKCksIGNhbAorCQkJCS5nZXRUaW1lKCkuZ2V0VGltZSgpID09IDEwMDk4NjEyMDAwMDBMKTsKKworCQljYWwuY2xlYXIoKTsKKwkJY2FsLnNldChDYWxlbmRhci5ZRUFSLCAyMDAyKTsKKwkJY2FsLnNldChDYWxlbmRhci5EQVlfT0ZfV0VFSywgQ2FsZW5kYXIuVEhVUlNEQVkpOworCQlhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcmVzdWx0IDBjMzogIiArIGNhbC5nZXRUaW1lKCksIGNhbC5nZXRUaW1lKCkKKwkJCQkuZ2V0VGltZSgpID09IDEwMTAwMzQwMDAwMDBMKTsKKworCQljYWwuY2xlYXIoKTsKKwkJY2FsLnNldChDYWxlbmRhci5ZRUFSLCAyMDAyKTsKKwkJY2FsLnNldChDYWxlbmRhci5XRUVLX09GX01PTlRILCAyKTsKKwkJYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHJlc3VsdCAwZDogIiArIGNhbC5nZXRUaW1lKCksIGNhbC5nZXRUaW1lKCkKKwkJCQkuZ2V0VGltZSgpID09IDEwMTAyOTMyMDAwMDBMKTsKKworCQljYWwuY2xlYXIoKTsKKwkJY2FsLnNldChDYWxlbmRhci5ZRUFSLCAyMDAyKTsKKwkJY2FsLnNldChDYWxlbmRhci5EQVlfT0ZfV0VFS19JTl9NT05USCwgMik7CisJCWFzc2VydFRydWUoIkluY29ycmVjdCByZXN1bHQgMGU6ICIgKyBjYWwuZ2V0VGltZSgpLCBjYWwuZ2V0VGltZSgpCisJCQkJLmdldFRpbWUoKSA9PSAxMDEwODk4MDAwMDAwTCk7CisKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuV0VFS19PRl9ZRUFSLCAxMSk7CisJCWFzc2VydFRydWUoIkluY29ycmVjdCByZXN1bHQgMGY6ICIgKyBjYWwuZ2V0VGltZSgpLCBjYWwuZ2V0VGltZSgpCisJCQkJLmdldFRpbWUoKSA9PSAxMDE1NzM2NDAwMDAwTCk7CisKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFURSwgMjQpOworCQljYWwuc2V0KENhbGVuZGFyLldFRUtfT0ZfWUVBUiwgMTEpOworCQlhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcmVzdWx0IDBnOiAiICsgY2FsLmdldFRpbWUoKSwgY2FsLmdldFRpbWUoKQorCQkJCS5nZXRUaW1lKCkgPT0gMTAxMTg0ODQwMDAwMEwpOworCisJCWNhbC5jbGVhcigpOworCQljYWwuc2V0KENhbGVuZGFyLllFQVIsIDIwMDIpOworCQljYWwuZ2V0KENhbGVuZGFyLldFRUtfT0ZfWUVBUik7IC8vIEZvcmNlIGZpZWxkcyB0byBjb21wdXRlCisJCWNhbC5zZXQoQ2FsZW5kYXIuV0VFS19PRl9ZRUFSLCAxMSk7CisJCWFzc2VydFRydWUoIkluY29ycmVjdCByZXN1bHQgMGg6ICIgKyBjYWwuZ2V0VGltZSgpLCBjYWwuZ2V0VGltZSgpCisJCQkJLmdldFRpbWUoKSA9PSAxMDE1OTA5MjAwMDAwTCk7CisKKwkJLy8gV0VFS19PRl9ZRUFSIGhhcyBwcmlvcml0eSBvdmVyIE1PTlRIL0RBVEUKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1lFQVIsIDE3MCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuV0VFS19PRl9ZRUFSLCAxMSk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuTU9OVEgsIENhbGVuZGFyLkpBTlVBUlkpOworCQljYWwuc2V0KENhbGVuZGFyLkRBVEUsIDUpOworCQljYWwuc2V0KENhbGVuZGFyLkRBWV9PRl9XRUVLLCBDYWxlbmRhci5NT05EQVkpOworCQlhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcmVzdWx0IDE6ICIgKyBjYWwuZ2V0VGltZSgpLCBjYWwuZ2V0VGltZSgpCisJCQkJLmdldFRpbWUoKSA9PSAxMDE1ODIyODAwMDAwTCk7CisKKwkJLy8gV0VFS19PRl9ZRUFSIGhhcyBwcmlvcml0eSBvdmVyIE1PTlRIL0RBVEUKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuV0VFS19PRl9ZRUFSLCAxMSk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuTU9OVEgsIENhbGVuZGFyLkpBTlVBUlkpOworCQljYWwuc2V0KENhbGVuZGFyLkRBVEUsIDUpOworCQljYWwuc2V0KENhbGVuZGFyLkRBWV9PRl9ZRUFSLCAxNzApOworCQljYWwuc2V0KENhbGVuZGFyLkRBWV9PRl9XRUVLLCBDYWxlbmRhci5NT05EQVkpOworCQlhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcmVzdWx0IDFhOiAiICsgY2FsLmdldFRpbWUoKSwgY2FsLmdldFRpbWUoKQorCQkJCS5nZXRUaW1lKCkgPT0gMTAxNTgyMjgwMDAwMEwpOworCisJCS8vIERBWV9PRl9XRUVLIGhhcyBubyBlZmZlY3Qgd2hlbiBvdGhlciBmaWVsZHMgbm90IHNldAorCQljYWwuY2xlYXIoKTsKKwkJY2FsLnNldChDYWxlbmRhci5ZRUFSLCAyMDAyKTsKKwkJY2FsLnNldChDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuTUFSQ0gpOworCQljYWwuc2V0KENhbGVuZGFyLkRBVEUsIDExKTsKKwkJY2FsLnNldChDYWxlbmRhci5EQVlfT0ZfV0VFSywgQ2FsZW5kYXIuVFVFU0RBWSk7CisJCWFzc2VydFRydWUoIkluY29ycmVjdCByZXN1bHQgMWI6ICIgKyBjYWwuZ2V0VGltZSgpLCBjYWwuZ2V0VGltZSgpCisJCQkJLmdldFRpbWUoKSA9PSAxMDE1ODIyODAwMDAwTCk7CisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktNDM4NAorICAgICAgICAvLyBTZXQgREFZX09GX1dFRUsgd2l0aG91dCBEQVRFCisgICAgICAgIGNhbC5jbGVhcigpOworICAgICAgICBjYWwuc2V0KENhbGVuZGFyLllFQVIsIDIwMDIpOworICAgICAgICBjYWwuc2V0KENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5NQVJDSCk7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1dFRUssIENhbGVuZGFyLlRVRVNEQVkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCByZXN1bHQgMWI6ICIgKyBjYWwuZ2V0VGltZSgpLCAxMDE1MzA0NDAwMDAwTCwgY2FsLmdldFRpbWUoKQorICAgICAgICAgICAgICAgIC5nZXRUaW1lKCkpOworCisKKwkJLy8gV0VFS19PRl9NT05USCBoYXMgcHJpb3JpdHkKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuV0VFS19PRl9ZRUFSLCAxMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1dFRUtfSU5fTU9OVEgsIDEpOworCQljYWwuc2V0KENhbGVuZGFyLldFRUtfT0ZfTU9OVEgsIDMpOworCQljYWwuc2V0KENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5NQVJDSCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFURSwgNSk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1dFRUssIENhbGVuZGFyLk1PTkRBWSk7CisJCWFzc2VydFRydWUoIkluY29ycmVjdCByZXN1bHQgMjogIiArIGNhbC5nZXRUaW1lKCksIGNhbC5nZXRUaW1lKCkKKwkJCQkuZ2V0VGltZSgpID09IDEwMTU4MjI4MDAwMDBMKTsKKworCQkvLyBEQVlfT0ZfV0VFS19JTl9NT05USCBoYXMgcHJpb3JpdHkgb3ZlciBXRUVLX09GX1lFQVIKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuV0VFS19PRl9ZRUFSLCAxMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1dFRUtfSU5fTU9OVEgsIDIpOworCQljYWwuc2V0KENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5NQVJDSCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFURSwgNSk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1dFRUssIENhbGVuZGFyLk1PTkRBWSk7CisJCWFzc2VydFRydWUoIkluY29ycmVjdCByZXN1bHQgMzogIiArIGNhbC5nZXRUaW1lKCksIGNhbC5nZXRUaW1lKCkKKwkJCQkuZ2V0VGltZSgpID09IDEwMTU4MjI4MDAwMDBMKTsKKworCQkvLyBXRUVLX09GX01PTlRIIGhhcyBwcmlvcml0eSwgTU9OVEggbm90IHNldAorCQljYWwuY2xlYXIoKTsKKwkJY2FsLnNldChDYWxlbmRhci5ZRUFSLCAyMDAyKTsKKwkJY2FsLnNldChDYWxlbmRhci5XRUVLX09GX1lFQVIsIDEyKTsKKwkJY2FsLnNldChDYWxlbmRhci5EQVlfT0ZfV0VFS19JTl9NT05USCwgMSk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuV0VFS19PRl9NT05USCwgMyk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFURSwgMjUpOworCQljYWwuc2V0KENhbGVuZGFyLkRBWV9PRl9XRUVLLCBDYWxlbmRhci5NT05EQVkpOworCQlhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcmVzdWx0IDQ6ICIgKyBjYWwuZ2V0VGltZSgpLCBjYWwuZ2V0VGltZSgpCisJCQkJLmdldFRpbWUoKSA9PSAxMDEwOTg0NDAwMDAwTCk7CisKKwkJLy8gV0VFS19PRl9ZRUFSIGhhcyBwcmlvcml0eSB3aGVuIE1PTlRIIHNldCBsYXN0IGFuZCBEQVlfT0ZfV0VFSyBzZXQKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuV0VFS19PRl9ZRUFSLCAxMSk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFURSwgMjUpOworCQljYWwuc2V0KENhbGVuZGFyLkRBWV9PRl9XRUVLLCBDYWxlbmRhci5NT05EQVkpOworCQljYWwuc2V0KENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5KQU5VQVJZKTsKKwkJYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHJlc3VsdCA1OiAiICsgY2FsLmdldFRpbWUoKSwgY2FsLmdldFRpbWUoKQorCQkJCS5nZXRUaW1lKCkgPT0gMTAxNTgyMjgwMDAwMEwpOworCisJCS8vIFVzZSBNT05USC9EQVRFIHdoZW4gV0VFS19PRl9ZRUFSIHNldCBidXQgbm90IERBWV9PRl9XRUVLCisJCWNhbC5jbGVhcigpOworCQljYWwuc2V0KENhbGVuZGFyLllFQVIsIDIwMDIpOworCQljYWwuc2V0KENhbGVuZGFyLldFRUtfT0ZfWUVBUiwgMTIpOworCQljYWwuc2V0KENhbGVuZGFyLkRBVEUsIDExKTsKKwkJY2FsLnNldChDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuTUFSQ0gpOworCQlhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcmVzdWx0IDVhOiAiICsgY2FsLmdldFRpbWUoKSwgY2FsLmdldFRpbWUoKQorCQkJCS5nZXRUaW1lKCkgPT0gMTAxNTgyMjgwMDAwMEwpOworCisJCS8vIFVzZSBNT05USC9EQVRFIHdoZW4gREFZX09GX1dFRUsgaXMgbm90IHNldAorCQljYWwuY2xlYXIoKTsKKwkJY2FsLnNldChDYWxlbmRhci5ZRUFSLCAyMDAyKTsKKwkJY2FsLnNldChDYWxlbmRhci5XRUVLX09GX1lFQVIsIDEyKTsKKwkJY2FsLnNldChDYWxlbmRhci5EQVRFLCAxMSk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuV0VFS19PRl9NT05USCwgMSk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuTU9OVEgsIENhbGVuZGFyLk1BUkNIKTsKKwkJYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHJlc3VsdCA1YjogIiArIGNhbC5nZXRUaW1lKCksIGNhbC5nZXRUaW1lKCkKKwkJCQkuZ2V0VGltZSgpID09IDEwMTU4MjI4MDAwMDBMKTsKKworCQkvLyBXRUVLX09GX01PTlRIIGhhcyBwcmlvcml0eQorCQljYWwuY2xlYXIoKTsKKwkJY2FsLnNldChDYWxlbmRhci5ZRUFSLCAyMDAyKTsKKwkJY2FsLnNldChDYWxlbmRhci5XRUVLX09GX1lFQVIsIDEyKTsKKwkJY2FsLnNldChDYWxlbmRhci5EQVRFLCA1KTsKKwkJY2FsLnNldChDYWxlbmRhci5XRUVLX09GX01PTlRILCAzKTsKKwkJY2FsLnNldChDYWxlbmRhci5EQVlfT0ZfV0VFSywgQ2FsZW5kYXIuTU9OREFZKTsKKwkJY2FsLnNldChDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuTUFSQ0gpOworCQlhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcmVzdWx0IDVjOiAiICsgY2FsLmdldFRpbWUoKSwgY2FsLmdldFRpbWUoKQorCQkJCS5nZXRUaW1lKCkgPT0gMTAxNTgyMjgwMDAwMEwpOworCisJCS8vIERBVEUgaGFzIHByaW9yaXR5IHdoZW4gc2V0IGxhc3QKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuV0VFS19PRl9ZRUFSLCAxMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1dFRUssIENhbGVuZGFyLk1PTkRBWSk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuTU9OVEgsIENhbGVuZGFyLk1BUkNIKTsKKwkJY2FsLnNldChDYWxlbmRhci5EQVRFLCAxMSk7CisJCWFzc2VydFRydWUoIkluY29ycmVjdCByZXN1bHQgNjogIiArIGNhbC5nZXRUaW1lKCksIGNhbC5nZXRUaW1lKCkKKwkJCQkuZ2V0VGltZSgpID09IDEwMTU4MjI4MDAwMDBMKTsKKworCQkvLyBEQVRFIGhhcyBwcmlvcml0eSB3aGVuIHNldCBsYXN0LCBNT05USCBub3Qgc2V0CisJCWNhbC5jbGVhcigpOworCQljYWwuc2V0KENhbGVuZGFyLllFQVIsIDIwMDIpOworCQljYWwuc2V0KENhbGVuZGFyLldFRUtfT0ZfWUVBUiwgMTIpOworCQljYWwuc2V0KENhbGVuZGFyLkRBWV9PRl9XRUVLLCBDYWxlbmRhci5NT05EQVkpOworCQljYWwuc2V0KENhbGVuZGFyLkRBVEUsIDE0KTsKKwkJYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHJlc3VsdCA3OiAiICsgY2FsLmdldFRpbWUoKSwgY2FsLmdldFRpbWUoKQorCQkJCS5nZXRUaW1lKCkgPT0gMTAxMDk4NDQwMDAwMEwpOworCisJCS8vIERBWV9PRl9ZRUFSIGhhcyBwcmlvcml0eSB3aGVuIE1PTlRIIHNldCBsYXN0IGFuZCBEQVRFIG5vdCBzZXQKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1lFQVIsIDcwKTsKKwkJY2FsLnNldChDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuSkFOVUFSWSk7CisJCWFzc2VydFRydWUoIkluY29ycmVjdCByZXN1bHQgODogIiArIGNhbC5nZXRUaW1lKCksIGNhbC5nZXRUaW1lKCkKKwkJCQkuZ2V0VGltZSgpID09IDEwMTU4MjI4MDAwMDBMKTsKKworCQkvLyBEQVkvTU9OVEggaGFzIHByaW9yaXR5IHdoZW4gREFURSBzZXQgYWZ0ZXIgREFZX09GX1lFQVIKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1lFQVIsIDE3MCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFURSwgMTEpOworCQljYWwuc2V0KENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5NQVJDSCk7CisJCWFzc2VydFRydWUoIkluY29ycmVjdCByZXN1bHQgOGE6ICIgKyBjYWwuZ2V0VGltZSgpLCBjYWwuZ2V0VGltZSgpCisJCQkJLmdldFRpbWUoKSA9PSAxMDE1ODIyODAwMDAwTCk7CisKKwkJLy8gREFZX09GX1lFQVIgaGFzIHByaW9yaXR5IHdoZW4gc2V0IGFmdGVyIERBVEUKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFURSwgMTUpOworCQljYWwuc2V0KENhbGVuZGFyLkRBWV9PRl9ZRUFSLCA3MCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuTU9OVEgsIENhbGVuZGFyLkpBTlVBUlkpOworCQlhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcmVzdWx0IDhiOiAiICsgY2FsLmdldFRpbWUoKSwgY2FsLmdldFRpbWUoKQorCQkJCS5nZXRUaW1lKCkgPT0gMTAxNTgyMjgwMDAwMEwpOworCisJCS8vIERBVEUgaGFzIHByaW9yaXR5IHdoZW4gc2V0IGxhc3QKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1lFQVIsIDcwKTsKKwkJY2FsLnNldChDYWxlbmRhci5EQVRFLCAxNCk7CisJCWFzc2VydFRydWUoIkluY29ycmVjdCByZXN1bHQgOTogIiArIGNhbC5nZXRUaW1lKCksIGNhbC5nZXRUaW1lKCkKKwkJCQkuZ2V0VGltZSgpID09IDEwMTA5ODQ0MDAwMDBMKTsKKworCQkvLyBEQVRFIGhhcyBwcmlvcml0eSB3aGVuIHNldCBsYXN0CisJCWNhbC5jbGVhcigpOworCQljYWwuc2V0KENhbGVuZGFyLllFQVIsIDIwMDIpOworCQljYWwuc2V0KENhbGVuZGFyLldFRUtfT0ZfWUVBUiwgMTUpOworCQljYWwuc2V0KENhbGVuZGFyLkRBWV9PRl9XRUVLLCBDYWxlbmRhci5USFVSU0RBWSk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFURSwgMTQpOworCQlhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcmVzdWx0IDlhOiAiICsgY2FsLmdldFRpbWUoKSwgY2FsLmdldFRpbWUoKQorCQkJCS5nZXRUaW1lKCkgPT0gMTAxMDk4NDQwMDAwMEwpOworCisJCWNhbC5jbGVhcigpOworCQljYWwuc2V0KENhbGVuZGFyLllFQVIsIDIwMDIpOworCQljYWwuc2V0KENhbGVuZGFyLkRBWV9PRl9XRUVLLCBDYWxlbmRhci5NT05EQVkpOworCQljYWwuc2V0KENhbGVuZGFyLkRBVEUsIDE0KTsKKwkJY2FsLnNldChDYWxlbmRhci5XRUVLX09GX1lFQVIsIDExKTsKKwkJYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHJlc3VsdCA5YjogIiArIGNhbC5nZXRUaW1lKCksIGNhbC5nZXRUaW1lKCkKKwkJCQkuZ2V0VGltZSgpID09IDEwMTU4MjI4MDAwMDBMKTsKKworCQljYWwuY2xlYXIoKTsKKwkJY2FsLnNldChDYWxlbmRhci5ZRUFSLCAyMDAyKTsKKwkJY2FsLnNldChDYWxlbmRhci5EQVRFLCAxNCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuV0VFS19PRl9ZRUFSLCAxMSk7CisJCWFzc2VydFRydWUoIkluY29ycmVjdCByZXN1bHQgOWM6ICIgKyBjYWwuZ2V0VGltZSgpLCBjYWwuZ2V0VGltZSgpCisJCQkJLmdldFRpbWUoKSA9PSAxMDEwOTg0NDAwMDAwTCk7CisKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuV0VFS19PRl9NT05USCwgMSk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1dFRUssIENhbGVuZGFyLlRIVVJTREFZKTsKKwkJY2FsLnNldChDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuTUFSQ0gpOworCQljYWwuc2V0KENhbGVuZGFyLkRBVEUsIDExKTsKKwkJYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHJlc3VsdCA5ZDogIiArIGNhbC5nZXRUaW1lKCksIGNhbC5nZXRUaW1lKCkKKwkJCQkuZ2V0VGltZSgpID09IDEwMTU4MjI4MDAwMDBMKTsKKworCQkvLyBEQVlfT0ZfWUVBUiBoYXMgcHJpb3JpdHkgd2hlbiBEQVlfT0ZfTU9OVEggc2V0IGxhc3QgYW5kIG90aGVyIGZpZWxkcworCQkvLyBub3Qgc2V0CisJCWNhbC5jbGVhcigpOworCQljYWwuc2V0KENhbGVuZGFyLllFQVIsIDIwMDIpOworCQljYWwuc2V0KENhbGVuZGFyLkRBWV9PRl9ZRUFSLCA3MCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1dFRUssIENhbGVuZGFyLlRVRVNEQVkpOworCQlhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcmVzdWx0IDEwOiAiICsgY2FsLmdldFRpbWUoKSwgY2FsLmdldFRpbWUoKQorCQkJCS5nZXRUaW1lKCkgPT0gMTAxNTgyMjgwMDAwMEwpOworCisJCS8vIE1PTlRIL0RBVEUgaGFzIHByaW9yaXR5IHdoZW4gREFZX09GX1dFRUtfSU5fTU9OVEggc2V0IGxhc3QgYnV0CisJCS8vIERBWV9PRl9XRUVLIG5vdCBzZXQKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFURSwgMTEpOworCQljYWwuc2V0KENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5NQVJDSCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1dFRUtfSU5fTU9OVEgsIDEpOworCQlhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcmVzdWx0IDExOiAiICsgY2FsLmdldFRpbWUoKSwgY2FsLmdldFRpbWUoKQorCQkJCS5nZXRUaW1lKCkgPT0gMTAxNTgyMjgwMDAwMEwpOworCisJCS8vIE1PTlRIL0RBVEUgaGFzIHByaW9yaXR5IHdoZW4gV0VFS19PRl9ZRUFSIHNldCBsYXN0IGJ1dCBEQVlfT0ZfV0VFSworCQkvLyBub3Qgc2V0CisJCWNhbC5jbGVhcigpOworCQljYWwuc2V0KENhbGVuZGFyLllFQVIsIDIwMDIpOworCQljYWwuc2V0KENhbGVuZGFyLkRBVEUsIDExKTsKKwkJY2FsLnNldChDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuTUFSQ0gpOworCQljYWwuc2V0KENhbGVuZGFyLldFRUtfT0ZfWUVBUiwgMTUpOworCQlhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcmVzdWx0IDEyOiAiICsgY2FsLmdldFRpbWUoKSwgY2FsLmdldFRpbWUoKQorCQkJCS5nZXRUaW1lKCkgPT0gMTAxNTgyMjgwMDAwMEwpOworCisJCS8vIE1PTlRIL0RBVEUgaGFzIHByaW9yaXR5IHdoZW4gV0VFS19PRl9NT05USCBzZXQgbGFzdCBidXQgREFZX09GX1dFRUsKKwkJLy8gbm90IHNldAorCQljYWwuY2xlYXIoKTsKKwkJY2FsLnNldChDYWxlbmRhci5ZRUFSLCAyMDAyKTsKKwkJY2FsLnNldChDYWxlbmRhci5EQVRFLCAxMSk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuTU9OVEgsIENhbGVuZGFyLk1BUkNIKTsKKwkJY2FsLnNldChDYWxlbmRhci5XRUVLX09GX01PTlRILCAxKTsKKwkJYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHJlc3VsdCAxMzogIiArIGNhbC5nZXRUaW1lKCksIGNhbC5nZXRUaW1lKCkKKwkJCQkuZ2V0VGltZSgpID09IDEwMTU4MjI4MDAwMDBMKTsKKworCQkvLyBFbnN1cmUgbGFzdCBkYXRlIGZpZWxkIHNldCBpcyByZXNldCBhZnRlciBjb21wdXRpbmcKKwkJY2FsLmNsZWFyKCk7CisJCWNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgMjAwMik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1lFQVIsIDExMSk7CisJCWNhbC5nZXQoQ2FsZW5kYXIuWUVBUik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuTU9OVEgsIENhbGVuZGFyLk1BUkNIKTsKKwkJY2FsLnNldChDYWxlbmRhci5BTV9QTSwgQ2FsZW5kYXIuQU0pOworCQlhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcmVzdWx0IDE0OiAiICsgY2FsLmdldFRpbWUoKSwgY2FsLmdldFRpbWUoKQorCQkJCS5nZXRUaW1lKCkgPT0gMTAxNjY4NjgwMDAwMEwpOworCisJCWludCBob3VyID0gY2FsLmdldChDYWxlbmRhci5IT1VSKTsKKwkJY2FsLnNldChDYWxlbmRhci5IT1VSLCBob3VyKTsKKwkJY2FsLnNldChDYWxlbmRhci5BTV9QTSwgQ2FsZW5kYXIuUE0pOworCQlhc3NlcnRFcXVhbHMoIkFNX1BNIG5vdCBjaGFuZ2VkIiwgQ2FsZW5kYXIuUE0sIGNhbC5nZXQoQ2FsZW5kYXIuQU1fUE0pKTsKKwkJLy8gc2V0dGluZyBBTV9QTSB3aXRob3V0IEhPVVIgc2hvdWxkIG5vdCBoYXZlIGFueSBhZmZlY3QKKwkJY2FsLnNldChDYWxlbmRhci5BTV9QTSwgQ2FsZW5kYXIuQU0pOworCQlhc3NlcnRFcXVhbHMoIkFNX1BNIHdhcyBjaGFuZ2VkIDEiLAorCQkJCUNhbGVuZGFyLkFNLCBjYWwuZ2V0KENhbGVuZGFyLkFNX1BNKSk7CisJCWludCBob3VyT2ZEYXkgPSBjYWwuZ2V0KENhbGVuZGFyLkhPVVJfT0ZfREFZKTsKKwkJaG91ciA9IGNhbC5nZXQoQ2FsZW5kYXIuSE9VUik7CisJCWNhbC5zZXQoQ2FsZW5kYXIuQU1fUE0sIENhbGVuZGFyLlBNKTsKKwkJYXNzZXJ0RXF1YWxzKCJBTV9QTSB3YXMgY2hhbmdlZCAyIiwKKwkJCQlDYWxlbmRhci5QTSwgY2FsLmdldChDYWxlbmRhci5BTV9QTSkpOworCQlhc3NlcnRFcXVhbHMoaG91ciwgY2FsLmdldChDYWxlbmRhci5IT1VSKSk7CisJCWFzc2VydEVxdWFscyhob3VyT2ZEYXkgKyAxMiwgY2FsLmdldChDYWxlbmRhci5IT1VSX09GX0RBWSkpOworCisgICAgICAgIC8vIHJlZ3Jlc3Npb24gdGVzdCBmb3IgSGFybW9ueS0yMTIyCisgICAgICAgIGNhbCA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7CisgICAgICAgIGludCBvbGRWYWx1ZSA9IGNhbC5nZXQoQ2FsZW5kYXIuQU1fUE0pOworICAgICAgICBpbnQgbmV3VmFsdWUgPSAob2xkVmFsdWUgPT0gQ2FsZW5kYXIuQU0pID8gQ2FsZW5kYXIuUE0gOiBDYWxlbmRhci5BTTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5BTV9QTSwgbmV3VmFsdWUpOworICAgICAgICBuZXdWYWx1ZSA9IGNhbC5nZXQoQ2FsZW5kYXIuQU1fUE0pOworICAgICAgICBhc3NlcnRUcnVlKG5ld1ZhbHVlICE9IG9sZFZhbHVlKTsKKwl9CisKKwkvKioKKwkgKiBqYXZhLnV0aWwuQ2FsZW5kYXIjc2V0VGltZShqYXZhLnV0aWwuRGF0ZSkKKwkgKi8KKwlwdWJsaWMgdm9pZCB0ZXN0X3NldFRpbWVMamF2YV91dGlsX0RhdGUoKSB7CisJCUNhbGVuZGFyIGNhbCA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7CisJCS8vIFVzZSBtaWxsaXNlY29uZCB0aW1lIGZvciB0ZXN0aW5nIGluIENvcmUKKwkJY2FsLnNldFRpbWUobmV3IERhdGUoODg0NTgxMjAwMDAwTCkpOyAvLyAoOTgsIENhbGVuZGFyLkpBTlVBUlksIDEyKQorCQlhc3NlcnRFcXVhbHMoImluY29ycmVjdCBtaWxsaXMiLCA4ODQ1ODEyMDAwMDBMLCBjYWwuZ2V0VGltZSgpLmdldFRpbWUoKSk7CisJCWNhbC5zZXRUaW1lWm9uZShUaW1lWm9uZS5nZXRUaW1lWm9uZSgiRVNUIikpOworCQljYWwuc2V0VGltZShuZXcgRGF0ZSg5NDM1MDYwMDAwMDBMKSk7IC8vICg5OSwgQ2FsZW5kYXIuTk9WRU1CRVIsIDI1KQorCQlhc3NlcnRUcnVlKCJpbmNvcnJlY3QgZmllbGRzIiwgY2FsLmdldChDYWxlbmRhci5ZRUFSKSA9PSAxOTk5CisJCQkJJiYgY2FsLmdldChDYWxlbmRhci5NT05USCkgPT0gQ2FsZW5kYXIuTk9WRU1CRVIKKwkJCQkmJiBjYWwuZ2V0KENhbGVuZGFyLkRBVEUpID09IDI1KTsKKwl9CisKKwkvKioKKwkgKiBqYXZhLnV0aWwuQ2FsZW5kYXIjY29tcGFyZVRvKENhbGVuZGFyKQorCSAqLworCXB1YmxpYyB2b2lkIHRlc3RfY29tcGFyZVRvTGphdmFfdXRpbF9DYWxlbmRhcl9udWxsKCkgeworCQlDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOworCQl0cnkgeworCQkJY2FsLmNvbXBhcmVUbyhudWxsKTsKKwkJCWZhaWwoInNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworCQl9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisJCQkvLyBleHBlY3RlZAorCQl9CisJfQorCisJLyoqCisJICogamF2YS51dGlsLkNhbGVuZGFyI2NvbXBhcmVUbyhDYWxlbmRhcikKKwkgKi8KKwlwdWJsaWMgdm9pZCB0ZXN0X2NvbXBhcmVUb0xqYXZhX3V0aWxfQ2FsZW5kYXIoKSB7CisgICAgICAgIENhbGVuZGFyIGNhbCA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7CisgICAgICAgIGNhbC5jbGVhcigpOworICAgICAgICBjYWwuc2V0KDE5OTcsIDEyLCAxMywgMjMsIDU3KTsKKworICAgICAgICBDYWxlbmRhciBhbm90aGVyQ2FsID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgYW5vdGhlckNhbC5jbGVhcigpOworICAgICAgICBhbm90aGVyQ2FsLnNldCgxOTk3LCAxMiwgMTMsIDIzLCA1Nyk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBjYWwuY29tcGFyZVRvKGFub3RoZXJDYWwpKTsKKworICAgICAgICBhbm90aGVyQ2FsID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgYW5vdGhlckNhbC5jbGVhcigpOworICAgICAgICBhbm90aGVyQ2FsLnNldCgxOTk3LCAxMSwgMTMsIDI0LCA1Nyk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBjYWwuY29tcGFyZVRvKGFub3RoZXJDYWwpKTsKKworICAgICAgICBhbm90aGVyQ2FsID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgYW5vdGhlckNhbC5jbGVhcigpOworICAgICAgICBhbm90aGVyQ2FsLnNldCgxOTk3LCAxMiwgMTMsIDIzLCA1OCk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgY2FsLmNvbXBhcmVUbyhhbm90aGVyQ2FsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNhbGVuZGFyI2Nsb25lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb25lKCkgeworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTQ3NQorICAgICAgICBDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOworICAgICAgICBjYWwuc2V0KDIwMDYsIDUsIDYsIDExLCAzNSk7CisgICAgICAgIENhbGVuZGFyIGFub3RoZXJDYWwgPSAoQ2FsZW5kYXIpIGNhbC5jbG9uZSgpOworICAgICAgICAvLyBzaG91bGQgYmUgZGVlcCBjbG9uZQorICAgICAgICBhc3NlcnROb3RTYW1lKCJnZXRUaW1lWm9uZSIsIGNhbC5nZXRUaW1lWm9uZSgpLCBhbm90aGVyQ2FsCisgICAgICAgICAgICAgICAgLmdldFRpbWVab25lKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5DYWxlbmRhciNnZXRUaW1lSW5NaWxsaXMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0VGltZUluTWlsbGlzKCkgeworICAgICAgICBDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOworCisgICAgICAgIGludCB5ZWFyID0gSW50ZWdlci5NSU5fVkFMVUUgKyA3MTsKKwkJY2FsLnNldFRpbWVab25lKFRpbWVab25lLmdldFRpbWVab25lKCJHTVQiKSk7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuWUVBUiwgeWVhciArIDE5MDApOworICAgICAgICBjYWwuc2V0KENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5KQU5VQVJZKTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5EQVRFLCAxKTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5IT1VSX09GX0RBWSwgMCk7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuTUlOVVRFLCAwKTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5TRUNPTkQsIDApOworICAgICAgICBjYWwuc2V0KENhbGVuZGFyLk1JTExJU0VDT05ELCAwKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoNjAxNzU0NjM1NzM3MjYwNjQ2NEwsIGNhbC5nZXRUaW1lSW5NaWxsaXMoKSk7CisgICAgfQorCisJcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9jYWxlW10gbG9jYWxlcyA9IG5ldyBMb2NhbGVbXSB7IExvY2FsZS5nZXREZWZhdWx0KCksCisJCQlMb2NhbGUuVVMsIExvY2FsZS5VSywgTG9jYWxlLlRBSVdBTiwgTG9jYWxlLlBSQywgTG9jYWxlLktPUkVBLAorCQkJTG9jYWxlLkpBUEFOLCBMb2NhbGUuSVRBTElBTiwgTG9jYWxlLkdFUk1BTiwgTG9jYWxlLkVOR0xJU0gsCisJCQlMb2NhbGUuQ0hJTkEsIExvY2FsZS5DQU5BREEsIExvY2FsZS5GUkFOQ0UgfTsKKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5DYWxlbmRhciNiZWZvcmUoT2JqZWN0KQorICAgICAqIGphdmEudXRpbC5DYWxlbmRhciNhZnRlcihPYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9iZWZvcmVfYWZ0ZXIoKSB7CisgICAgICAgIENhbGVuZGFyIGVhcmx5ID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgQ2FsZW5kYXIgbGF0ZSA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7CisgICAgICAgIC8vIHRlc3QgYnkgc2Vjb25kCisgICAgICAgIGVhcmx5LnNldCgyMDA4LCAzLCAyMCwgMTcsIDI4LCAxMik7CisgICAgICAgIGxhdGUuc2V0KDIwMDgsIDMsIDIwLCAxNywgMjgsIDIyKTsKKyAgICAgICAgLy8gdGVzdCBiZWZvcmUoKQorICAgICAgICBhc3NlcnRUcnVlKGVhcmx5LmJlZm9yZShsYXRlKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGVhcmx5LmJlZm9yZShlYXJseSkpOworICAgICAgICBhc3NlcnRGYWxzZShsYXRlLmJlZm9yZShlYXJseSkpOworICAgICAgICAvLyB0ZXN0IGFmdGVyKCk7CisgICAgICAgIGFzc2VydFRydWUobGF0ZS5hZnRlcihlYXJseSkpOworICAgICAgICBhc3NlcnRGYWxzZShsYXRlLmFmdGVyKGxhdGUpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZWFybHkuYWZ0ZXIobGF0ZSkpOworCisgICAgICAgIC8vIHRlc3QgYnkgbWludXRlCisgICAgICAgIGVhcmx5LnNldCgyMDA4LCAzLCAyMCwgMTcsIDE4LCAxMik7CisgICAgICAgIGxhdGUuc2V0KDIwMDgsIDMsIDIwLCAxNywgMjgsIDEyKTsKKyAgICAgICAgLy8gdGVzdCBiZWZvcmUoKQorICAgICAgICBhc3NlcnRUcnVlKGVhcmx5LmJlZm9yZShsYXRlKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGVhcmx5LmJlZm9yZShlYXJseSkpOworICAgICAgICBhc3NlcnRGYWxzZShsYXRlLmJlZm9yZShlYXJseSkpOworICAgICAgICAvLyB0ZXN0IGFmdGVyKCk7CisgICAgICAgIGFzc2VydFRydWUobGF0ZS5hZnRlcihlYXJseSkpOworICAgICAgICBhc3NlcnRGYWxzZShsYXRlLmFmdGVyKGxhdGUpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZWFybHkuYWZ0ZXIobGF0ZSkpOworCisgICAgICAgIC8vIHRlc3QgYnkgaG91cgorICAgICAgICBlYXJseS5zZXQoMjAwOCwgMywgMjAsIDE3LCAyOCwgMTIpOworICAgICAgICBsYXRlLnNldCgyMDA4LCAzLCAyMCwgMjcsIDI4LCAxMik7CisgICAgICAgIC8vIHRlc3QgYmVmb3JlKCkKKyAgICAgICAgYXNzZXJ0VHJ1ZShlYXJseS5iZWZvcmUobGF0ZSkpOworICAgICAgICBhc3NlcnRGYWxzZShlYXJseS5iZWZvcmUoZWFybHkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobGF0ZS5iZWZvcmUoZWFybHkpKTsKKyAgICAgICAgLy8gdGVzdCBhZnRlcigpOworICAgICAgICBhc3NlcnRUcnVlKGxhdGUuYWZ0ZXIoZWFybHkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobGF0ZS5hZnRlcihsYXRlKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGVhcmx5LmFmdGVyKGxhdGUpKTsKKworICAgICAgICAvLyB0ZXN0IGJ5IGRheQorICAgICAgICBlYXJseS5zZXQoMjAwOCwgMywgMTAsIDE3LCAyOCwgMTIpOworICAgICAgICBsYXRlLnNldCgyMDA4LCAzLCAyMCwgMTcsIDI4LCAxMik7CisgICAgICAgIC8vIHRlc3QgYmVmb3JlKCkKKyAgICAgICAgYXNzZXJ0VHJ1ZShlYXJseS5iZWZvcmUobGF0ZSkpOworICAgICAgICBhc3NlcnRGYWxzZShlYXJseS5iZWZvcmUoZWFybHkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobGF0ZS5iZWZvcmUoZWFybHkpKTsKKyAgICAgICAgLy8gdGVzdCBhZnRlcigpOworICAgICAgICBhc3NlcnRUcnVlKGxhdGUuYWZ0ZXIoZWFybHkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobGF0ZS5hZnRlcihsYXRlKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGVhcmx5LmFmdGVyKGxhdGUpKTsKKworICAgICAgICAvLyB0ZXN0IGJ5IG1vbnRoCisgICAgICAgIGVhcmx5LnNldCgyMDA4LCAyLCAyMCwgMTcsIDI4LCAxMik7CisgICAgICAgIGxhdGUuc2V0KDIwMDgsIDMsIDIwLCAxNywgMjgsIDEyKTsKKyAgICAgICAgLy8gdGVzdCBiZWZvcmUoKQorICAgICAgICBhc3NlcnRUcnVlKGVhcmx5LmJlZm9yZShsYXRlKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGVhcmx5LmJlZm9yZShlYXJseSkpOworICAgICAgICBhc3NlcnRGYWxzZShsYXRlLmJlZm9yZShlYXJseSkpOworICAgICAgICAvLyB0ZXN0IGFmdGVyKCk7CisgICAgICAgIGFzc2VydFRydWUobGF0ZS5hZnRlcihlYXJseSkpOworICAgICAgICBhc3NlcnRGYWxzZShsYXRlLmFmdGVyKGxhdGUpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZWFybHkuYWZ0ZXIobGF0ZSkpOworCisgICAgICAgIC8vIHRlc3QgYnkgeWVhcgorICAgICAgICBlYXJseS5zZXQoMjAwNywgMywgMjAsIDE3LCAyOCwgMTIpOworICAgICAgICBsYXRlLnNldCgyMDA4LCAzLCAyMCwgMTcsIDI4LCAxMik7CisgICAgICAgIC8vIHRlc3QgYmVmb3JlKCkKKyAgICAgICAgYXNzZXJ0VHJ1ZShlYXJseS5iZWZvcmUobGF0ZSkpOworICAgICAgICBhc3NlcnRGYWxzZShlYXJseS5iZWZvcmUoZWFybHkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobGF0ZS5iZWZvcmUoZWFybHkpKTsKKyAgICAgICAgLy8gdGVzdCBhZnRlcigpOworICAgICAgICBhc3NlcnRUcnVlKGxhdGUuYWZ0ZXIoZWFybHkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobGF0ZS5hZnRlcihsYXRlKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGVhcmx5LmFmdGVyKGxhdGUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ2FsZW5kYXIjY2xlYXIoKQorICAgICAqIGphdmEudXRpbC5DYWxlbmRhciNjbGVhcihpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jbGVhcigpIHsKKyAgICAgICAgQ2FsZW5kYXIgY2FsZW5kYXIgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOworCisgICAgICAgIGludCBjb3VudCA9IDY7CisgICAgICAgIGludFtdIGZpZWxkcyA9IG5ldyBpbnRbY291bnRdOworICAgICAgICBpbnRbXSBkZWZhdWx0cyA9IG5ldyBpbnRbY291bnRdOworCisgICAgICAgIGZpZWxkc1swXSA9IENhbGVuZGFyLllFQVI7CisgICAgICAgIGZpZWxkc1sxXSA9IENhbGVuZGFyLk1PTlRIOworICAgICAgICBmaWVsZHNbMl0gPSBDYWxlbmRhci5EQVRFOworICAgICAgICBmaWVsZHNbM10gPSBDYWxlbmRhci5IT1VSX09GX0RBWTsKKyAgICAgICAgZmllbGRzWzRdID0gQ2FsZW5kYXIuTUlOVVRFOworICAgICAgICBmaWVsZHNbNV0gPSBDYWxlbmRhci5TRUNPTkQ7CisKKyAgICAgICAgZGVmYXVsdHNbMF0gPSAxOTcwOworICAgICAgICBkZWZhdWx0c1sxXSA9IDA7CisgICAgICAgIGRlZmF1bHRzWzJdID0gMTsKKyAgICAgICAgZGVmYXVsdHNbM10gPSAwOworICAgICAgICBkZWZhdWx0c1s0XSA9IDA7CisgICAgICAgIGRlZmF1bHRzWzVdID0gMDsKKworICAgICAgICBjYWxlbmRhci5zZXQoMjAwOCwgMywgMjAsIDE3LCAyOCwgMTIpOworCisgICAgICAgIC8vIHRlc3QgY2xlYXIoaW50KQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaW50IGluZGV4ID0gZmllbGRzW2ldOworICAgICAgICAgICAgY2FsZW5kYXIuY2xlYXIoaW5kZXgpOworICAgICAgICAgICAgaWYgKDUgPT0gaW5kZXgpIHsKKyAgICAgICAgICAgICAgICAvLyBSSSBhbHNvIGRvZXNuJ3QgY2hhbmdlIHRoZSB2YWx1ZSBvZiBEQVRFCisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJGaWVsZCAiICsgaW5kZXggKyAiIFNob3VsZCBlcXVhbCB0byAyMC4iLCAyMCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhbGVuZGFyLmdldChpbmRleCkpOworICAgICAgICAgICAgfSBlbHNlIGlmICgxMSA9PSBpbmRleCkgeworICAgICAgICAgICAgICAgIC8vIFJJIGFsc28gZG9lc24ndCBjaGFuZ2UgdGhlIHZhbHVlIG9mIEhPVVIKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkZpZWxkICIgKyBpbmRleCArICIgU2hvdWxkIGVxdWFsIHRvIDE3LiIsIDE3LAorICAgICAgICAgICAgICAgICAgICAgICAgY2FsZW5kYXIuZ2V0KGluZGV4KSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIE90aGVyIGhhdmUgYmVlbiBzZXQgdG8gZGVmYXVsdCB2YWx1ZXMKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkZpZWxkICIgKyBpbmRleCArICIgU2hvdWxkIGVxdWFsIHRvICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgZGVmYXVsdHNbaV0gKyAiLiIsIGRlZmF1bHRzW2ldLCBjYWxlbmRhci5nZXQoaW5kZXgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3QgY2xlYXIoKQorICAgICAgICBjYWxlbmRhci5zZXQoMjAwOCwgMywgMjAsIDE3LCAyOCwgMTIpOworCisgICAgICAgIGNhbGVuZGFyLmNsZWFyKCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGludCBpbmRleCA9IGZpZWxkc1tpXTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiRmllbGQgIiArIGluZGV4ICsgIiBTaG91bGQgZXF1YWwgdG8gIgorICAgICAgICAgICAgICAgICAgICArIGRlZmF1bHRzW2ldICsgIi4iLCBkZWZhdWx0c1tpXSwgY2FsZW5kYXIuZ2V0KGluZGV4KSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ2FsZW5kYXIjaXNTZXQoaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNTZXQoKSB7CisgICAgICAgIENhbGVuZGFyIGNhbGVuZGFyID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgY2FsZW5kYXIuY2xlYXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBDYWxlbmRhci5GSUVMRF9DT1VOVDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShjYWxlbmRhci5pc1NldChpKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ2FsZW5kYXIjZ2V0QXZhaWxhYmxlTG9jYWxlcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBdmFpbGFibGVMb2NhbGVzKCkgeworICAgICAgICBMb2NhbGVbXSBsb2NhbGVzID0gQ2FsZW5kYXIuZ2V0QXZhaWxhYmxlTG9jYWxlcygpOworICAgICAgICBib29sZWFuIGV4aXN0ID0gZmFsc2U7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbG9jYWxlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgTG9jYWxlIGwgPSBsb2NhbGVzW2ldOworICAgICAgICAgICAgaWYgKExvY2FsZS5VUy5lcXVhbHMobCkpIHsKKyAgICAgICAgICAgICAgICBleGlzdCA9IHRydWU7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZShleGlzdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNhbGVuZGFyI2dldEluc3RhbmNlKExvY2FsZSkKKyAgICAgKiBqYXZhLnV0aWwuQ2FsZW5kYXIjZ2V0SW5zdGFuY2UoVGltZVpvbmUsIExvY2FsZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlKCkgeworICAgICAgICAvLyB0ZXN0IGdldEluc3RhbmNlKExvY2FsZSkKKyAgICAgICAgQ2FsZW5kYXIgdXNfY2FsZW5kYXIgPSBDYWxlbmRhci5nZXRJbnN0YW5jZShMb2NhbGUuVVMpOworICAgICAgICBDYWxlbmRhciBjaF9jYWxlbmRhciA9IENhbGVuZGFyLmdldEluc3RhbmNlKExvY2FsZS5DSElORVNFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENhbGVuZGFyLlNVTkRBWSwgdXNfY2FsZW5kYXIKKyAgICAgICAgICAgICAgICAuZ2V0Rmlyc3REYXlPZldlZWsoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDYWxlbmRhci5NT05EQVksIGNoX2NhbGVuZGFyCisgICAgICAgICAgICAgICAgLmdldEZpcnN0RGF5T2ZXZWVrKCkpOworCisgICAgICAgIC8vIHRlc3QgZ2V0SW5zdGFuY2UoTG9jYWxlLCBUaW1lWm9uZSkKKyAgICAgICAgQ2FsZW5kYXIgZ210X2NhbGVuZGFyID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoVGltZVpvbmUKKyAgICAgICAgICAgICAgICAuZ2V0VGltZVpvbmUoIkdNVCIpLCBMb2NhbGUuVVMpOworICAgICAgICBhc3NlcnRFcXVhbHMoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkdNVCIpLAorICAgICAgICAgICAgICAgIGdtdF9jYWxlbmRhci5nZXRUaW1lWm9uZSgpKTsKKyAgICAgICAgQ2FsZW5kYXIgZXN0X2NhbGVuZGFyID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoVGltZVpvbmUKKyAgICAgICAgICAgICAgICAuZ2V0VGltZVpvbmUoIkVTVCIpLCBMb2NhbGUuVVMpOworICAgICAgICBhc3NlcnRFcXVhbHMoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkVTVCIpCisgICAgICAgICAgICAgICAgLmdldElEKCksIGVzdF9jYWxlbmRhci5nZXRUaW1lWm9uZSgpLmdldElEKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5DYWxlbmRhciNpbnRlcm5hbEdldChpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pbnRlcm5hbEdldCgpIHsKKyAgICAgICAgTW9ja0dyZWdvcmlhbkNhbGVuZGFyIGMgPSBuZXcgTW9ja0dyZWdvcmlhbkNhbGVuZGFyKCk7CisgICAgICAgIGMuY2xlYXIoQ2FsZW5kYXIuWUVBUik7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBjLmludGVybmFsX2dldChDYWxlbmRhci5ZRUFSKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNhbGVuZGFyI2hhc2hDb2RlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc2hjb2RlKCkgeworICAgICAgICBDYWxlbmRhciBjYWxlbmRhciA9IENhbGVuZGFyLmdldEluc3RhbmNlKExvY2FsZS5KQVBBTik7CisgICAgICAgIGFzc2VydFRydWUoY2FsZW5kYXIuaGFzaENvZGUoKSA9PSBjYWxlbmRhci5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ2FsZW5kYXIjcm9sbChpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JvbGwoKSB7CisgICAgICAgIENhbGVuZGFyIGNhbGVuZGFyID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgY2FsZW5kYXIuc2V0KDIwMDgsIDMsIDIwLCAxNywgMjgsIDEyKTsKKworICAgICAgICAvLyByb2xsIHVwCisgICAgICAgIGNhbGVuZGFyLnJvbGwoQ2FsZW5kYXIuREFURSwgNSk7CisgICAgICAgIGFzc2VydEVxdWFscygyNSwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRBVEUpKTsKKworICAgICAgICAvLyByb2xsIGRvd24KKyAgICAgICAgY2FsZW5kYXIucm9sbChDYWxlbmRhci5EQVRFLCAtNSk7CisgICAgICAgIGFzc2VydEVxdWFscygyMCwgY2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRBVEUpKTsKKworICAgICAgICAvLyByb2xsIDAKKyAgICAgICAgY2FsZW5kYXIucm9sbChDYWxlbmRhci5EQVRFLCAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIwLCBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuREFURSkpOworCisgICAgICAgIC8vIHJvbGwgb3ZlcndlaWdodAorICAgICAgICBjYWxlbmRhci5zZXQoMjAwOCwgMSwgMzEsIDE3LCAyOCwgMTIpOworICAgICAgICBjYWxlbmRhci5yb2xsKENhbGVuZGFyLk1PTlRILCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGNhbGVuZGFyLmdldChDYWxlbmRhci5EQVRFKSk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ2FsZW5kYXIjdG9TdHJpbmcoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9TdHJpbmcoKSB7CisgICAgICAgIENhbGVuZGFyIGNhbGVuZGFyID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgLy9TaG91bGQgYmUgdGhlIGN1cnJlbnQgdGltZSB3aXRoIG5vIGludGVycm9nYXRpb24gaW4gdGhlIHN0cmluZy4KKyAgICAgICAgYXNzZXJ0VHJ1ZShjYWxlbmRhci50b1N0cmluZygpIGluc3RhbmNlb2YgU3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBjYWxlbmRhci50b1N0cmluZygpLmluZGV4T2YoIj8iKSk7CisgICAgICAgIGNhbGVuZGFyLmNsZWFyKCk7CisgICAgICAgIGFzc2VydFRydWUoY2FsZW5kYXIudG9TdHJpbmcoKSBpbnN0YW5jZW9mIFN0cmluZyk7CisgICAgICAgIGFzc2VydFRydWUoMCA8PSBjYWxlbmRhci50b1N0cmluZygpLmluZGV4T2YoIj8iKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogc2VyaWFsaXphdGlvbi9kZXNlcmlhbGl6YXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6YXRpb25TZWxmKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENhbGVuZGFyIGNhbGVuZGFyID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgY2FsZW5kYXIuc2V0KDIwMDgsIDMsIDIwLCAxNywgMjgsIDEyKTsKKworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdC52ZXJpZnlTZWxmKGNhbGVuZGFyKTsKKyAgICB9CisKKworICAgIHByaXZhdGUgY2xhc3MgTW9ja0dyZWdvcmlhbkNhbGVuZGFyIGV4dGVuZHMgR3JlZ29yaWFuQ2FsZW5kYXIgeworICAgICAgICBwdWJsaWMgaW50IGludGVybmFsX2dldChpbnQgZmllbGQpIHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5pbnRlcm5hbEdldChmaWVsZCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIE1vY2tDYWxlbmRhciBleHRlbmRzIENhbGVuZGFyIHsKKworCQlwdWJsaWMgTW9ja0NhbGVuZGFyKCkgeworCQkJc3VwZXIoKTsKKwkJfQorCisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBhZGQoaW50IGZpZWxkLCBpbnQgdmFsdWUpIHsKKwkJfQorCisJCUBPdmVycmlkZQorCQlwcm90ZWN0ZWQgdm9pZCBjb21wdXRlRmllbGRzKCkgeworCQl9CisKKwkJQE92ZXJyaWRlCisJCXByb3RlY3RlZCB2b2lkIGNvbXB1dGVUaW1lKCkgeworCQl9CisKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyBpbnQgZ2V0R3JlYXRlc3RNaW5pbXVtKGludCBmaWVsZCkgeworCQkJcmV0dXJuIDA7CisJCX0KKworCQlAT3ZlcnJpZGUKKwkJcHVibGljIGludCBnZXRMZWFzdE1heGltdW0oaW50IGZpZWxkKSB7CisJCQlyZXR1cm4gMDsKKwkJfQorCisJCUBPdmVycmlkZQorCQlwdWJsaWMgaW50IGdldE1heGltdW0oaW50IGZpZWxkKSB7CisJCQlyZXR1cm4gMDsKKwkJfQorCisJCUBPdmVycmlkZQorCQlwdWJsaWMgaW50IGdldE1pbmltdW0oaW50IGZpZWxkKSB7CisJCQlyZXR1cm4gMDsKKwkJfQorCisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCByb2xsKGludCBmaWVsZCwgYm9vbGVhbiBpbmNyZW1lbnQpIHsKKwkJfQorICAgIH0KKworCS8qKgorCSAqIHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjZ2V0RGlzcGxheU5hbWUoaW50LCBpbnQsIExvY2FsZSl9CisJICogQHNpbmNlIDEuNgorCSAqLworCXB1YmxpYyB2b2lkIHRlc3RfZ2V0RGlzcGxheU5hbWVJSUxqYXZhX3V0aWxfTG9jYWxlKCkgeworCQlDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOworCQlmb3IgKGludCBmaWVsZCA9IDA7IGZpZWxkIDwgQ2FsZW5kYXIuRklFTERfQ09VTlQ7IGZpZWxkKyspIHsKKwkJCWZvciAoTG9jYWxlIGxvY2FsZSA6IGxvY2FsZXMpIHsKKwkJCQlEYXRlRm9ybWF0U3ltYm9scyBzeW1ib2xzID0gbmV3IERhdGVGb3JtYXRTeW1ib2xzKGxvY2FsZSk7CisJCQkJU3RyaW5nIHZhbHVlID0gbnVsbDsKKwkJCQlzd2l0Y2ggKGZpZWxkKSB7CisJCQkJY2FzZSBDYWxlbmRhci5BTV9QTToKKwkJCQkJY2FsLnNldChDYWxlbmRhci5BTV9QTSwgQ2FsZW5kYXIuQU0pOworCQkJCQl2YWx1ZSA9IHN5bWJvbHMuZ2V0QW1QbVN0cmluZ3MoKVswXTsKKwkJCQkJYXNzZXJ0RXF1YWxzKGNhbC5nZXREaXNwbGF5TmFtZShmaWVsZCwgQ2FsZW5kYXIuU0hPUlQsCisJCQkJCQkJbG9jYWxlKSwgdmFsdWUpOworCQkJCQlhc3NlcnRFcXVhbHMoY2FsLmdldERpc3BsYXlOYW1lKGZpZWxkLCBDYWxlbmRhci5MT05HLAorCQkJCQkJCWxvY2FsZSksIHZhbHVlKTsKKwkJCQkJY2FsLnNldChDYWxlbmRhci5BTV9QTSwgQ2FsZW5kYXIuUE0pOworCQkJCQl2YWx1ZSA9IHN5bWJvbHMuZ2V0QW1QbVN0cmluZ3MoKVsxXTsKKwkJCQkJYXNzZXJ0RXF1YWxzKGNhbC5nZXREaXNwbGF5TmFtZShmaWVsZCwgQ2FsZW5kYXIuU0hPUlQsCisJCQkJCQkJbG9jYWxlKSwgdmFsdWUpOworCQkJCQlhc3NlcnRFcXVhbHMoY2FsLmdldERpc3BsYXlOYW1lKGZpZWxkLCBDYWxlbmRhci5MT05HLAorCQkJCQkJCWxvY2FsZSksIHZhbHVlKTsKKwkJCQkJYnJlYWs7CisJCQkJY2FzZSBDYWxlbmRhci5FUkE6CisJCQkJCWNhbC5zZXQoQ2FsZW5kYXIuRVJBLCBHcmVnb3JpYW5DYWxlbmRhci5CQyk7CisJCQkJCXZhbHVlID0gc3ltYm9scy5nZXRFcmFzKClbMF07CisJCQkJCWFzc2VydEVxdWFscyhjYWwuZ2V0RGlzcGxheU5hbWUoZmllbGQsIENhbGVuZGFyLlNIT1JULAorCQkJCQkJCWxvY2FsZSksIHZhbHVlKTsKKwkJCQkJYXNzZXJ0RXF1YWxzKGNhbC5nZXREaXNwbGF5TmFtZShmaWVsZCwgQ2FsZW5kYXIuTE9ORywKKwkJCQkJCQlsb2NhbGUpLCB2YWx1ZSk7CisJCQkJCWNhbC5zZXQoQ2FsZW5kYXIuRVJBLCBHcmVnb3JpYW5DYWxlbmRhci5BRCk7CisJCQkJCXZhbHVlID0gc3ltYm9scy5nZXRFcmFzKClbMV07CisJCQkJCWFzc2VydEVxdWFscyhjYWwuZ2V0RGlzcGxheU5hbWUoZmllbGQsIENhbGVuZGFyLlNIT1JULAorCQkJCQkJCWxvY2FsZSksIHZhbHVlKTsKKwkJCQkJYXNzZXJ0RXF1YWxzKGNhbC5nZXREaXNwbGF5TmFtZShmaWVsZCwgQ2FsZW5kYXIuTE9ORywKKwkJCQkJCQlsb2NhbGUpLCB2YWx1ZSk7CisJCQkJCWJyZWFrOworCQkJCWNhc2UgQ2FsZW5kYXIuTU9OVEg6CisJCQkJCWNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX01PTlRILCAxKTsKKwkJCQkJZm9yIChpbnQgbW9udGggPSAwOyBtb250aCA8PSAxMTsgbW9udGgrKykgeworCQkJCQkJY2FsLnNldChDYWxlbmRhci5NT05USCwgbW9udGgpOworCQkJCQkJdmFsdWUgPSBzeW1ib2xzLmdldFNob3J0TW9udGhzKClbbW9udGhdOworCQkJCQkJYXNzZXJ0RXF1YWxzKGNhbC5nZXREaXNwbGF5TmFtZShmaWVsZCwgQ2FsZW5kYXIuU0hPUlQsCisJCQkJCQkJCWxvY2FsZSksIHZhbHVlKTsKKwkJCQkJCXZhbHVlID0gc3ltYm9scy5nZXRNb250aHMoKVttb250aF07CisJCQkJCQlhc3NlcnRFcXVhbHMoY2FsLmdldERpc3BsYXlOYW1lKGZpZWxkLCBDYWxlbmRhci5MT05HLAorCQkJCQkJCQlsb2NhbGUpLCB2YWx1ZSk7CisJCQkJCX0KKwkJCQkJYnJlYWs7CisJCQkJY2FzZSBDYWxlbmRhci5EQVlfT0ZfV0VFSzoKKwkJCQkJZm9yIChpbnQgZGF5ID0gMTsgZGF5IDw9IDc7IGRheSsrKSB7CisJCQkJCQljYWwuc2V0KENhbGVuZGFyLkRBWV9PRl9XRUVLLCBkYXkpOworCQkJCQkJdmFsdWUgPSBzeW1ib2xzLmdldFNob3J0V2Vla2RheXMoKVtkYXldOworCQkJCQkJYXNzZXJ0RXF1YWxzKGNhbC5nZXREaXNwbGF5TmFtZShmaWVsZCwgQ2FsZW5kYXIuU0hPUlQsCisJCQkJCQkJCWxvY2FsZSksIHZhbHVlKTsKKwkJCQkJCXZhbHVlID0gc3ltYm9scy5nZXRXZWVrZGF5cygpW2RheV07CisJCQkJCQlhc3NlcnRFcXVhbHMoY2FsLmdldERpc3BsYXlOYW1lKGZpZWxkLCBDYWxlbmRhci5MT05HLAorCQkJCQkJCQlsb2NhbGUpLCB2YWx1ZSk7CisJCQkJCX0KKwkJCQkJYnJlYWs7CisJCQkJZGVmYXVsdDoKKwkJCQkJYXNzZXJ0TnVsbChjYWwKKwkJCQkJCQkuZ2V0RGlzcGxheU5hbWUoZmllbGQsIENhbGVuZGFyLlNIT1JULCBsb2NhbGUpKTsKKwkJCQkJYXNzZXJ0TnVsbChjYWwuZ2V0RGlzcGxheU5hbWUoZmllbGQsIENhbGVuZGFyLkxPTkcsIGxvY2FsZSkpOworCQkJCX0KKwkJCX0KKwkJfQorCisJCWNhbC5zZXRMZW5pZW50KHRydWUpOworCisJCXRyeSB7CisJCQljYWwuZ2V0RGlzcGxheU5hbWUoLTEsIENhbGVuZGFyLlNIT1JULCBMb2NhbGUuVVMpOworCQkJZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworCQl9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworCQkJLy8gZXhwZWN0ZWQKKwkJfQorCQl0cnkgeworCQkJY2FsLmdldERpc3BsYXlOYW1lKENhbGVuZGFyLkZJRUxEX0NPVU5ULCBDYWxlbmRhci5MT05HLCBMb2NhbGUuVVMpOworCQkJZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworCQl9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworCQkJLy8gZXhwZWN0ZWQKKwkJfQorCQl0cnkgeworCQkJY2FsLmdldERpc3BsYXlOYW1lKENhbGVuZGFyLk1PTlRILCAtMSwgTG9jYWxlLlVTKTsKKwkJCWZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKwkJfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKwkJCS8vIGV4cGVjdGVkCisJCX0KKwkJdHJ5IHsKKwkJCWNhbC5nZXREaXNwbGF5TmFtZShDYWxlbmRhci5NT05USCwgMywgTG9jYWxlLlVTKTsKKwkJCWZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKwkJfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKwkJCS8vIGV4cGVjdGVkCisJCX0KKwkJdHJ5IHsKKwkJCWNhbC5nZXREaXNwbGF5TmFtZShDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuU0hPUlQsIG51bGwpOworCQkJZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisJCX0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKwkJCS8vIGV4cGVjdGVkCisJCX0KKwkJdHJ5IHsKKwkJCWNhbC5nZXREaXNwbGF5TmFtZSgtMSwgQ2FsZW5kYXIuU0hPUlQsIG51bGwpOworCQkJZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworCQl9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworCQkJLy8gZXhwZWN0ZWQKKwkJfQorCQl0cnkgeworCQkJY2FsLmdldERpc3BsYXlOYW1lKENhbGVuZGFyLk1PTlRILCAtMSwgbnVsbCk7CisJCQlmYWlsKCJTaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisJCX0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisJCQkvLyBleHBlY3RlZAorCQl9CisJCS8vIGluIGxlbmllbnQgbW9kZSwgZm9sbG93aW5nIGNhc2VzIHBhc3MKKwkJY2FsLnNldChDYWxlbmRhci5TRUNPTkQsIDk5OSk7CisJCWNhbC5nZXREaXNwbGF5TmFtZShDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuU0hPUlQsIExvY2FsZS5VUyk7CisJCS8vIHRlc3QgZm9yIEFMTF9TVFlMRVMsIGl0IGlzIGVxdWFsIHRvIHVzZSBTSE9SVAorCQlmb3IgKGludCBmaWVsZCA9IDA7IGZpZWxkIDwgQ2FsZW5kYXIuRklFTERfQ09VTlQ7IGZpZWxkKyspIHsKKwkJCWZvciAoTG9jYWxlIGxvY2FsZSA6IGxvY2FsZXMpIHsKKwkJCQlTdHJpbmcgcmVzdWx0ID0gY2FsLmdldERpc3BsYXlOYW1lKGZpZWxkLCBDYWxlbmRhci5BTExfU1RZTEVTLAorCQkJCQkJbG9jYWxlKTsKKwkJCQlpZiAoZmllbGQgPT0gQ2FsZW5kYXIuQU1fUE0gfHwgZmllbGQgPT0gQ2FsZW5kYXIuRVJBCisJCQkJCQl8fCBmaWVsZCA9PSBDYWxlbmRhci5NT05USAorCQkJCQkJfHwgZmllbGQgPT0gQ2FsZW5kYXIuREFZX09GX1dFRUspIHsKKwkJCQkJYXNzZXJ0RXF1YWxzKHJlc3VsdCwgY2FsLmdldERpc3BsYXlOYW1lKGZpZWxkLAorCQkJCQkJCUNhbGVuZGFyLlNIT1JULCBsb2NhbGUpKTsKKwkJCQl9IGVsc2UgeworCQkJCQlhc3NlcnROdWxsKHJlc3VsdCk7CisJCQkJfQorCQkJfQorCQl9CisKKwkJLy8gaW52YWxpZCB2YWx1ZSBmb3IgYW4gdW4tcmVsYXRlZCBmaWVsZCB3aGVuIHRoZSBjYWxlbmRhciBpcyBub3QKKwkJLy8gbGVuaWVudAorCQljYWwuc2V0TGVuaWVudChmYWxzZSk7CisJCWFzc2VydE5vdE51bGwoY2FsLmdldERpc3BsYXlOYW1lKENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5TSE9SVCwKKwkJCQlMb2NhbGUuVVMpKTsKKwkJY2FsLnNldChDYWxlbmRhci5TRUNPTkQsIDk5OSk7CisJCXRyeSB7CisJCQljYWwuZ2V0RGlzcGxheU5hbWUoQ2FsZW5kYXIuTU9OVEgsIENhbGVuZGFyLlNIT1JULCBMb2NhbGUuVVMpOworCQkJZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworCQl9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworCQkJLy8gZXhwZWN0ZWQKKwkJfQorCQl0cnkgeworCQkJY2FsLmdldERpc3BsYXlOYW1lKENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5BTExfU1RZTEVTLCBMb2NhbGUuVVMpOworCQkJZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworCQl9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworCQkJLy8gZXhwZWN0ZWQKKwkJfQorCX0KKworCS8qKgorCSAqIHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjZ2V0RGlzcGxheU5hbWVzKGludCwgaW50LCBMb2NhbGUpfQorCSAqIEBzaW5jZSAxLjYKKwkgKi8KKwlwdWJsaWMgdm9pZCB0ZXN0X2dldERpc3BsYXlOYW1lc0lJTGphdmFfdXRpbF9Mb2NhbGUoKSB7CisJCWFzc2VydEVxdWFscygwLCBDYWxlbmRhci5BTExfU1RZTEVTKTsKKwkJYXNzZXJ0RXF1YWxzKDEsIENhbGVuZGFyLlNIT1JUKTsKKwkJYXNzZXJ0RXF1YWxzKDIsIENhbGVuZGFyLkxPTkcpOworCisJCUNhbGVuZGFyIGNhbCA9IENhbGVuZGFyLmdldEluc3RhbmNlKExvY2FsZS5VUyk7CisKKwkJZm9yIChpbnQgZmllbGQgPSAwOyBmaWVsZCA8IENhbGVuZGFyLkZJRUxEX0NPVU5UOyBmaWVsZCsrKSB7CisJCQlmb3IgKExvY2FsZSBsb2NhbGUgOiBsb2NhbGVzKSB7CisJCQkJTWFwPFN0cmluZywgSW50ZWdlcj4gc2hvcnRSZXN1bHQgPSBjYWwuZ2V0RGlzcGxheU5hbWVzKGZpZWxkLAorCQkJCQkJQ2FsZW5kYXIuU0hPUlQsIGxvY2FsZSk7CisJCQkJTWFwPFN0cmluZywgSW50ZWdlcj4gbG9uZ1Jlc3VsdCA9IGNhbC5nZXREaXNwbGF5TmFtZXMoZmllbGQsCisJCQkJCQlDYWxlbmRhci5MT05HLCBsb2NhbGUpOworCQkJCU1hcDxTdHJpbmcsIEludGVnZXI+IGFsbFJlc3VsdCA9IGNhbC5nZXREaXNwbGF5TmFtZXMoZmllbGQsCisJCQkJCQlDYWxlbmRhci5BTExfU1RZTEVTLCBsb2NhbGUpOworCQkJCURhdGVGb3JtYXRTeW1ib2xzIHN5bWJvbHMgPSBuZXcgRGF0ZUZvcm1hdFN5bWJvbHMobG9jYWxlKTsKKwkJCQlTdHJpbmdbXSB2YWx1ZXMgPSBudWxsOworCQkJCXN3aXRjaCAoZmllbGQpIHsKKwkJCQljYXNlIENhbGVuZGFyLkFNX1BNOgorCQkJCWNhc2UgQ2FsZW5kYXIuRVJBOgorCQkJCQl2YWx1ZXMgPSAoZmllbGQgPT0gQ2FsZW5kYXIuQU1fUE0pID8gc3ltYm9scworCQkJCQkJCS5nZXRBbVBtU3RyaW5ncygpIDogc3ltYm9scy5nZXRFcmFzKCk7CisJCQkJCWFzc2VydERpc3BsYXlOYW1lTWFwKHZhbHVlcywgc2hvcnRSZXN1bHQsIDApOworCQkJCQlhc3NlcnREaXNwbGF5TmFtZU1hcCh2YWx1ZXMsIGxvbmdSZXN1bHQsIDApOworCQkJCQlhc3NlcnREaXNwbGF5TmFtZU1hcCh2YWx1ZXMsIGFsbFJlc3VsdCwgMCk7CisJCQkJCWJyZWFrOworCQkJCWNhc2UgQ2FsZW5kYXIuTU9OVEg6CisJCQkJCXZhbHVlcyA9IHN5bWJvbHMuZ2V0U2hvcnRNb250aHMoKTsKKwkJCQkJYXNzZXJ0RGlzcGxheU5hbWVNYXAodmFsdWVzLCBzaG9ydFJlc3VsdCwgMCk7CisJCQkJCXZhbHVlcyA9IHN5bWJvbHMuZ2V0TW9udGhzKCk7CisJCQkJCWFzc2VydERpc3BsYXlOYW1lTWFwKHZhbHVlcywgbG9uZ1Jlc3VsdCwgMCk7CisJCQkJCWFzc2VydFRydWUoYWxsUmVzdWx0LnNpemUoKSA+PSBzaG9ydFJlc3VsdC5zaXplKCkpOworCQkJCQlhc3NlcnRUcnVlKGFsbFJlc3VsdC5zaXplKCkgPj0gbG9uZ1Jlc3VsdC5zaXplKCkpOworCQkJCQlhc3NlcnRUcnVlKGFsbFJlc3VsdC5zaXplKCkgPD0gc2hvcnRSZXN1bHQuc2l6ZSgpCisJCQkJCQkJKyBsb25nUmVzdWx0LnNpemUoKSk7CisJCQkJCWJyZWFrOworCQkJCWNhc2UgQ2FsZW5kYXIuREFZX09GX1dFRUs6CisJCQkJCXZhbHVlcyA9IHN5bWJvbHMuZ2V0U2hvcnRXZWVrZGF5cygpOworCQkJCQlhc3NlcnREaXNwbGF5TmFtZU1hcCh2YWx1ZXMsIHNob3J0UmVzdWx0LCAxKTsKKwkJCQkJdmFsdWVzID0gc3ltYm9scy5nZXRXZWVrZGF5cygpOworCQkJCQlhc3NlcnREaXNwbGF5TmFtZU1hcCh2YWx1ZXMsIGxvbmdSZXN1bHQsIDEpOworCQkJCQlhc3NlcnRUcnVlKGFsbFJlc3VsdC5zaXplKCkgPj0gc2hvcnRSZXN1bHQuc2l6ZSgpKTsKKwkJCQkJYXNzZXJ0VHJ1ZShhbGxSZXN1bHQuc2l6ZSgpID49IGxvbmdSZXN1bHQuc2l6ZSgpKTsKKwkJCQkJYXNzZXJ0VHJ1ZShhbGxSZXN1bHQuc2l6ZSgpIDw9IHNob3J0UmVzdWx0LnNpemUoKQorCQkJCQkJCSsgbG9uZ1Jlc3VsdC5zaXplKCkpOworCQkJCQlicmVhazsKKwkJCQlkZWZhdWx0OgorCQkJCQlhc3NlcnROdWxsKHNob3J0UmVzdWx0KTsKKwkJCQkJYXNzZXJ0TnVsbChsb25nUmVzdWx0KTsKKwkJCQkJYXNzZXJ0TnVsbChhbGxSZXN1bHQpOworCQkJCX0KKwkJCX0KKwkJfQorCisJCWNhbC5zZXRMZW5pZW50KHRydWUpOworCisJCXRyeSB7CisJCQljYWwuZ2V0RGlzcGxheU5hbWVzKC0xLCBDYWxlbmRhci5TSE9SVCwgTG9jYWxlLlVTKTsKKwkJCWZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKwkJfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKwkJCS8vIGV4cGVjdGVkCisJCX0KKwkJdHJ5IHsKKwkJCWNhbC5nZXREaXNwbGF5TmFtZXMoQ2FsZW5kYXIuRklFTERfQ09VTlQsIENhbGVuZGFyLkxPTkcsIExvY2FsZS5VUyk7CisJCQlmYWlsKCJTaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisJCX0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisJCQkvLyBleHBlY3RlZAorCQl9CisJCXRyeSB7CisJCQljYWwuZ2V0RGlzcGxheU5hbWVzKENhbGVuZGFyLk1PTlRILCAtMSwgTG9jYWxlLlVTKTsKKwkJCWZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKwkJfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKwkJCS8vIGV4cGVjdGVkCisJCX0KKwkJdHJ5IHsKKwkJCWNhbC5nZXREaXNwbGF5TmFtZXMoQ2FsZW5kYXIuTU9OVEgsIDMsIExvY2FsZS5VUyk7CisJCQlmYWlsKCJTaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisJCX0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisJCQkvLyBleHBlY3RlZAorCQl9CisJCXRyeSB7CisJCQljYWwuZ2V0RGlzcGxheU5hbWVzKENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5TSE9SVCwgbnVsbCk7CisJCQlmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKwkJfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworCQkJLy8gZXhwZWN0ZWQKKwkJfQorCQl0cnkgeworCQkJY2FsLmdldERpc3BsYXlOYW1lcygtMSwgQ2FsZW5kYXIuU0hPUlQsIG51bGwpOworCQkJZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworCQl9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworCQkJLy8gZXhwZWN0ZWQKKwkJfQorCQl0cnkgeworCQkJY2FsLmdldERpc3BsYXlOYW1lcyhDYWxlbmRhci5NT05USCwgLTEsIG51bGwpOworCQkJZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworCQl9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworCQkJLy8gZXhwZWN0ZWQKKwkJfQorCQljYWwuc2V0KENhbGVuZGFyLlNFQ09ORCwgOTk5KTsKKwkJY2FsLmdldERpc3BsYXlOYW1lcyhDYWxlbmRhci5NT05USCwgQ2FsZW5kYXIuU0hPUlQsIExvY2FsZS5VUyk7CisKKwkJLy8gUkkgZmFpbHMgaGVyZQorCQkvLyBpbnZhbGlkIHZhbHVlIGZvciBhbiB1bi1yZWxhdGVkIGZpZWxkIHdoZW4gdGhlIGNhbGVuZGFyIGlzIG5vdAorCQkvLyBsZW5pZW50CisJCWNhbC5zZXRMZW5pZW50KGZhbHNlKTsKKwkJY2FsLnNldChDYWxlbmRhci5TRUNPTkQsIDk5OSk7CisJCXRyeSB7CisJCQljYWwuZ2V0RGlzcGxheU5hbWVzKENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5TSE9SVCwgTG9jYWxlLlVTKTsKKwkJCWZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKwkJfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKwkJCS8vIGV4cGVjdGVkCisJCX0KKwl9CisKKwlwcml2YXRlIHZvaWQgYXNzZXJ0RGlzcGxheU5hbWVNYXAoU3RyaW5nW10gdmFsdWVzLAorCQkJTWFwPFN0cmluZywgSW50ZWdlcj4gcmVzdWx0LCBpbnQgc2hpZnQpIHsKKwkJTGlzdDxTdHJpbmc+IHRyaW1WYWx1ZSA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworCQlmb3IgKFN0cmluZyB2YWx1ZSA6IHZhbHVlcykgeworCQkJaWYgKHZhbHVlLnRyaW0oKS5sZW5ndGgoKSA+IDApIHsKKwkJCQl0cmltVmFsdWUuYWRkKHZhbHVlKTsKKwkJCX0KKwkJfQorCQlhc3NlcnRFcXVhbHModHJpbVZhbHVlLnNpemUoKSwgcmVzdWx0LnNpemUoKSk7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgdHJpbVZhbHVlLnNpemUoKTsgaSsrKSB7CisJCQlhc3NlcnRFcXVhbHMoaSArIHNoaWZ0LCByZXN1bHQuZ2V0KHRyaW1WYWx1ZS5nZXQoaSkpLmludFZhbHVlKCkpOworCQl9CisJfQorCisJLyoqCisJICoge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNnZXRBY3R1YWxNYXhpbXVtKGludCl9CisJICovCisJcHVibGljIHZvaWQgdGVzdF9nZXRBY3R1YWxNYXhpbXVtX0koKSB7CisJCUNhbGVuZGFyIGMgPSBuZXcgTW9ja0NhbGVuZGFyKCk7CisJCWFzc2VydEVxdWFscygic2hvdWxkIGJlIGVxdWFsIHRvIDAiLCAwLCBjLmdldEFjdHVhbE1heGltdW0oMCkpOworCX0KKworCS8qKgorCSAqIHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjZ2V0QWN0dWFsTWluaW11bShpbnQpfQorCSAqLworCXB1YmxpYyB2b2lkIHRlc3RfZ2V0QWN0dWFsTWluaW11bV9JKCkgeworCQlDYWxlbmRhciBjID0gbmV3IE1vY2tDYWxlbmRhcigpOworCQlhc3NlcnRFcXVhbHMoInNob3VsZCBiZSBlcXVhbCB0byAwIiwgMCwgYy5nZXRBY3R1YWxNaW5pbXVtKDApKTsKKwl9CisKKwlwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKwkJZGVmYXVsdExvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisJCUxvY2FsZS5zZXREZWZhdWx0KExvY2FsZS5VUyk7CisJfQorCisJcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisJCUxvY2FsZS5zZXREZWZhdWx0KGRlZmF1bHRMb2NhbGUpOworCX0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0NvbGxlY3Rpb25zVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQ29sbGVjdGlvbnNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzMwOGNmOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0NvbGxlY3Rpb25zVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjIyNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdEl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tQWNjZXNzOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlNvcnRlZFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZVNldDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0NvbGxlY3Rpb25UZXN0OworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9MaXN0VGVzdDsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfU2V0VGVzdDsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfVW5tb2RpZmlhYmxlQ29sbGVjdGlvblRlc3Q7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1VubW9kaWZpYWJsZU1hcFRlc3Q7CisKK3B1YmxpYyBjbGFzcyBDb2xsZWN0aW9uc1Rlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBMaW5rZWRMaXN0IGxsOworCisgICAgcHJpdmF0ZSBMaW5rZWRMaXN0IG15bGw7CisKKyAgICBwcml2YXRlIExpbmtlZExpc3QgcmV2ZXJzZWRMaW5rZWRMaXN0OworCisgICAgcHJpdmF0ZSBMaW5rZWRMaXN0IG15UmV2ZXJzZWRMaW5rZWRMaXN0OworCisgICAgcHJpdmF0ZSBTZXQgczsKKworICAgIHByaXZhdGUgU2V0IG15czsKKworICAgIHByaXZhdGUgSGFzaE1hcCBobTsKKworICAgIHByaXZhdGUgT2JqZWN0W10gb2JqQXJyYXk7CisKKyAgICBwcml2YXRlIE9iamVjdFtdIG15b2JqQXJyYXk7CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFJldmVyc2VkTXlJbnRDb21wYXJhdG9yIGltcGxlbWVudHMgQ29tcGFyYXRvciB7CisgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShPYmplY3QgbzEsIE9iamVjdCBvMikgeworICAgICAgICAgICAgcmV0dXJuIC0oKE15SW50KSBvMSkuY29tcGFyZVRvKChNeUludCkgbzIpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBlcXVhbHMoT2JqZWN0IG8xLCBPYmplY3QgbzIpIHsKKyAgICAgICAgICAgIHJldHVybiAoKE15SW50KSBvMSkuY29tcGFyZVRvKChNeUludCkgbzIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBTeW5jaENvbGxlY3Rpb25DaGVja2VyIGltcGxlbWVudHMgUnVubmFibGUgeworICAgICAgICBDb2xsZWN0aW9uIGNvbDsKKworICAgICAgICBpbnQgY29sU2l6ZTsKKworICAgICAgICBpbnQgdG90YWxUb1J1bjsKKworICAgICAgICBib29sZWFuIG9mZnNldDsKKworICAgICAgICB2b2xhdGlsZSBpbnQgbnVtYmVyT2ZDaGVja3MgPSAwOworCisgICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gdHJ1ZTsKKworICAgICAgICBBcnJheUxpc3Qgbm9ybWFsQ291bnRpbmdMaXN0OworCisgICAgICAgIEFycmF5TGlzdCBvZmZzZXRDb3VudGluZ0xpc3Q7CisKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgLy8gZW5zdXJlIHRoZSBsaXN0IGVpdGhlciBjb250YWlucyB0aGUgbnVtYmVycyBmcm9tIDAgdG8gc2l6ZS0xIG9yCisgICAgICAgICAgICAvLyB0aGUgbnVtYmVycyBmcm9tIHNpemUgdG8gMipzaXplIC0xCisgICAgICAgICAgICB3aGlsZSAobnVtYmVyT2ZDaGVja3MgPCB0b3RhbFRvUnVuKSB7CisgICAgICAgICAgICAgICAgc3luY2hyb25pemVkIChjb2wpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCEoY29sLmlzRW1wdHkoKSB8fCBjb2wuY29udGFpbnNBbGwobm9ybWFsQ291bnRpbmdMaXN0KSB8fCBjb2wKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29udGFpbnNBbGwob2Zmc2V0Q291bnRpbmdMaXN0KSkpCisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgY29sLmNsZWFyKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChvZmZzZXQpCisgICAgICAgICAgICAgICAgICAgIGNvbC5hZGRBbGwob2Zmc2V0Q291bnRpbmdMaXN0KTsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIGNvbC5hZGRBbGwobm9ybWFsQ291bnRpbmdMaXN0KTsKKyAgICAgICAgICAgICAgICBudW1iZXJPZkNoZWNrcysrOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN5bmNoQ29sbGVjdGlvbkNoZWNrZXIoQ29sbGVjdGlvbiBjLCBib29sZWFuIG9mZnNldCwKKyAgICAgICAgICAgICAgICBpbnQgdG90YWxDaGVja3MpIHsKKyAgICAgICAgICAgIC8vIFRoZSBjb2xsZWN0aW9uIHRvIHRlc3QsIHdoZXRoZXIgdG8gb2Zmc2V0IHRoZSBmaWxsZXIgdmFsdWVzIGJ5CisgICAgICAgICAgICAvLyBzaXplIG9yIG5vdCwgYW5kIHRoZSBtaW4gbnVtYmVyIG9mIGl0ZXJhdGlvbnMgdG8gcnVuCisgICAgICAgICAgICB0b3RhbFRvUnVuID0gdG90YWxDaGVja3M7CisgICAgICAgICAgICBjb2wgPSBjOworICAgICAgICAgICAgY29sU2l6ZSA9IGMuc2l6ZSgpOworICAgICAgICAgICAgbm9ybWFsQ291bnRpbmdMaXN0ID0gbmV3IEFycmF5TGlzdChjb2xTaXplKTsKKyAgICAgICAgICAgIG9mZnNldENvdW50aW5nTGlzdCA9IG5ldyBBcnJheUxpc3QoY29sU2l6ZSk7CisgICAgICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGNvbFNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgICAgICBub3JtYWxDb3VudGluZ0xpc3QuYWRkKG5ldyBJbnRlZ2VyKGNvdW50ZXIpKTsKKyAgICAgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgY29sU2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgICAgIG9mZnNldENvdW50aW5nTGlzdC5hZGQobmV3IEludGVnZXIoY291bnRlciArIGNvbFNpemUpKTsKKyAgICAgICAgICAgIGNvbC5jbGVhcigpOworICAgICAgICAgICAgaWYgKG9mZnNldCkKKyAgICAgICAgICAgICAgICBjb2wuYWRkQWxsKG9mZnNldENvdW50aW5nTGlzdCk7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgY29sLmFkZEFsbChub3JtYWxDb3VudGluZ0xpc3QpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gb2Zmc2V0KCkgeworICAgICAgICAgICAgLy8gYW5zd2VyIHRydWUgaWZmIHRoZSBsaXN0IGlzIGZpbGxlZCB3aXRoIGEgY291bnRpbmcgc2VxdWVuY2UKKyAgICAgICAgICAgIC8vIHN0YXJ0aW5nIGF0IHRoZSB2YWx1ZSBzaXplIHRvIDIqc2l6ZSAtIDEKKyAgICAgICAgICAgIC8vIGVsc2UgdGhlIGxpc3Qgd2l0aCBiZSBmaWxsZWQgc3RhcnRpbmcgYXQgMCB0byBzaXplIC0gMQorICAgICAgICAgICAgcmV0dXJuIG9mZnNldDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGdldFJlc3VsdCgpIHsKKyAgICAgICAgICAgIC8vIGFuc3dlciB0cnVlIGlmZiBubyBjb3JydXB0aW9uIGhhcyBiZWVuIGZvdW5kIGluIHRoZSBjb2xsZWN0aW9uCisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXROdW1iZXJPZkNoZWNrcygpIHsKKyAgICAgICAgICAgIC8vIGFuc3dlciB0aGUgbnVtYmVyIG9mIGNoZWNrcyB0aGF0IGhhdmUgYmVlbiBwZXJmb3JtZWQgb24gdGhlIGxpc3QKKyAgICAgICAgICAgIHJldHVybiBudW1iZXJPZkNoZWNrczsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgU3luY2hNYXBDaGVja2VyIGltcGxlbWVudHMgUnVubmFibGUgeworICAgICAgICBNYXAgbWFwOworCisgICAgICAgIGludCBtYXBTaXplOworCisgICAgICAgIGludCB0b3RhbFRvUnVuOworCisgICAgICAgIGJvb2xlYW4gb2Zmc2V0OworCisgICAgICAgIHZvbGF0aWxlIGludCBudW1iZXJPZkNoZWNrcyA9IDA7CisKKyAgICAgICAgYm9vbGVhbiByZXN1bHQgPSB0cnVlOworCisgICAgICAgIE1hcCBub3JtYWxDb3VudGluZ01hcDsKKworICAgICAgICBNYXAgb2Zmc2V0Q291bnRpbmdNYXA7CisKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgT2JqZWN0IGZpcnN0Tm9ybWFsVmFsdWUgPSBub3JtYWxDb3VudGluZ01hcC5nZXQobmV3IEludGVnZXIoMCkpOworICAgICAgICAgICAgT2JqZWN0IGxhc3ROb3JtYWxWYWx1ZSA9IG5vcm1hbENvdW50aW5nTWFwLmdldChuZXcgSW50ZWdlcigKKyAgICAgICAgICAgICAgICAgICAgbWFwU2l6ZSAtIDEpKTsKKyAgICAgICAgICAgIE9iamVjdCBmaXJzdE9mZnNldFZhbHVlID0gb2Zmc2V0Q291bnRpbmdNYXAKKyAgICAgICAgICAgICAgICAgICAgLmdldChuZXcgSW50ZWdlcihtYXBTaXplKSk7CisgICAgICAgICAgICBPYmplY3QgbGFzdE9mZnNldFZhbHVlID0gb2Zmc2V0Q291bnRpbmdNYXAuZ2V0KG5ldyBJbnRlZ2VyKAorICAgICAgICAgICAgICAgICAgICAyICogbWFwU2l6ZSAtIDEpKTsKKyAgICAgICAgICAgIC8vIGVuc3VyZSB0aGUgbGlzdCBlaXRoZXIgY29udGFpbnMgdGhlIG51bWJlcnMgZnJvbSAwIHRvIHNpemUtMSBvcgorICAgICAgICAgICAgLy8gdGhlIG51bWJlcnMgZnJvbSBzaXplIHRvIDIqc2l6ZSAtMQorICAgICAgICAgICAgd2hpbGUgKG51bWJlck9mQ2hlY2tzIDwgdG90YWxUb1J1bikgeworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAobWFwKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICghKG1hcC5pc0VtcHR5KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAobWFwLmNvbnRhaW5zVmFsdWUoZmlyc3ROb3JtYWxWYWx1ZSkgJiYgbWFwCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29udGFpbnNWYWx1ZShsYXN0Tm9ybWFsVmFsdWUpKSB8fCAobWFwCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbnRhaW5zVmFsdWUoZmlyc3RPZmZzZXRWYWx1ZSkgJiYgbWFwCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbnRhaW5zVmFsdWUobGFzdE9mZnNldFZhbHVlKSkpKQorICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIG1hcC5jbGVhcigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAob2Zmc2V0KQorICAgICAgICAgICAgICAgICAgICBtYXAucHV0QWxsKG9mZnNldENvdW50aW5nTWFwKTsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIG1hcC5wdXRBbGwobm9ybWFsQ291bnRpbmdNYXApOworICAgICAgICAgICAgICAgIG51bWJlck9mQ2hlY2tzKys7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3luY2hNYXBDaGVja2VyKE1hcCBtLCBib29sZWFuIG9mZnNldCwgaW50IHRvdGFsQ2hlY2tzKSB7CisgICAgICAgICAgICAvLyBUaGUgY29sbGVjdGlvbiB0byB0ZXN0LCB3aGV0aGVyIHRvIG9mZnNldCB0aGUgZmlsbGVyIHZhbHVlcyBieQorICAgICAgICAgICAgLy8gc2l6ZSBvciBub3QsIGFuZCB0aGUgbWluIG51bWJlciBvZiBpdGVyYXRpb25zIHRvIHJ1bgorICAgICAgICAgICAgSW50ZWdlciBteUludDsKKyAgICAgICAgICAgIHRvdGFsVG9SdW4gPSB0b3RhbENoZWNrczsKKyAgICAgICAgICAgIG1hcCA9IG07CisgICAgICAgICAgICBtYXBTaXplID0gbS5zaXplKCk7CisgICAgICAgICAgICBub3JtYWxDb3VudGluZ01hcCA9IG5ldyBIYXNoTWFwKG1hcFNpemUpOworICAgICAgICAgICAgb2Zmc2V0Q291bnRpbmdNYXAgPSBuZXcgSGFzaE1hcChtYXBTaXplKTsKKyAgICAgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgbWFwU2l6ZTsgY291bnRlcisrKSB7CisgICAgICAgICAgICAgICAgbXlJbnQgPSBuZXcgSW50ZWdlcihjb3VudGVyKTsKKyAgICAgICAgICAgICAgICBub3JtYWxDb3VudGluZ01hcC5wdXQobXlJbnQsIG15SW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgbWFwU2l6ZTsgY291bnRlcisrKSB7CisgICAgICAgICAgICAgICAgbXlJbnQgPSBuZXcgSW50ZWdlcihjb3VudGVyICsgbWFwU2l6ZSk7CisgICAgICAgICAgICAgICAgb2Zmc2V0Q291bnRpbmdNYXAucHV0KG15SW50LCBteUludCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtYXAuY2xlYXIoKTsKKyAgICAgICAgICAgIGlmIChvZmZzZXQpCisgICAgICAgICAgICAgICAgbWFwLnB1dEFsbChvZmZzZXRDb3VudGluZ01hcCk7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgbWFwLnB1dEFsbChub3JtYWxDb3VudGluZ01hcCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBvZmZzZXQoKSB7CisgICAgICAgICAgICAvLyBhbnN3ZXIgdHJ1ZSBpZmYgdGhlIGxpc3QgaXMgZmlsbGVkIHdpdGggYSBjb3VudGluZyBzZXF1ZW5jZQorICAgICAgICAgICAgLy8gc3RhcnRpbmcgYXQgdGhlIHZhbHVlIHNpemUgdG8gMipzaXplIC0gMQorICAgICAgICAgICAgLy8gZWxzZSB0aGUgbGlzdCB3aXRoIGJlIGZpbGxlZCBzdGFydGluZyBhdCAwIHRvIHNpemUgLSAxCisgICAgICAgICAgICByZXR1cm4gb2Zmc2V0OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZ2V0UmVzdWx0KCkgeworICAgICAgICAgICAgLy8gYW5zd2VyIHRydWUgaWZmIG5vIGNvcnJ1cHRpb24gaGFzIGJlZW4gZm91bmQgaW4gdGhlIGNvbGxlY3Rpb24KKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldE51bWJlck9mQ2hlY2tzKCkgeworICAgICAgICAgICAgLy8gYW5zd2VyIHRoZSBudW1iZXIgb2YgY2hlY2tzIHRoYXQgaGF2ZSBiZWVuIHBlcmZvcm1lZCBvbiB0aGUgbGlzdAorICAgICAgICAgICAgcmV0dXJuIG51bWJlck9mQ2hlY2tzOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBDb2xsZWN0aW9uVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICAgICAgQ29sbGVjdGlvbiBjb2w7IC8vIG11c3QgY29udGFpbiB0aGUgSW50ZWdlcnMgMCB0byA5OQorCisgICAgICAgIHB1YmxpYyBDb2xsZWN0aW9uVGVzdChTdHJpbmcgcDEpIHsKKyAgICAgICAgICAgIHN1cGVyKHAxKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBDb2xsZWN0aW9uVGVzdChTdHJpbmcgcDEsIENvbGxlY3Rpb24gYykgeworICAgICAgICAgICAgc3VwZXIocDEpOworICAgICAgICAgICAgY29sID0gYzsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIE15SW50IHsKKyAgICAgICAgaW50IGRhdGE7CisKKyAgICAgICAgcHVibGljIE15SW50KGludCB2YWx1ZSkgeworICAgICAgICAgICAgZGF0YSA9IHZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBjb21wYXJlVG8oTXlJbnQgb2JqZWN0KSB7CisgICAgICAgICAgICByZXR1cm4gZGF0YSA+IG9iamVjdC5kYXRhID8gMSA6IChkYXRhIDwgb2JqZWN0LmRhdGEgPyAtMSA6IDApOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI2JpbmFyeVNlYXJjaChqYXZhLnV0aWwuTGlzdCwKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2JpbmFyeVNlYXJjaExqYXZhX3V0aWxfTGlzdExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50CisgICAgICAgIC8vIGphdmEudXRpbC5Db2xsZWN0aW9ucy5iaW5hcnlTZWFyY2goamF2YS51dGlsLkxpc3QsIGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIC8vIGFzc3VtZXMgbGwgaXMgc29ydGVkIGFuZCBoYXMgbm8gZHVwbGljYXRlIGtleXMKKyAgICAgICAgZmluYWwgaW50IGxsU2l6ZSA9IGxsLnNpemUoKTsKKyAgICAgICAgLy8gRW5zdXJlIGEgTlBFIGlzIHRocm93biBpZiB0aGUgbGlzdCBpcyBOVUxMCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5iaW5hcnlTZWFyY2gobnVsbCwgbmV3IE9iamVjdCgpKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIGZvciBudWxsIGxpc3QgcGFyYW1ldGVyIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGxsU2l6ZTsgY291bnRlcisrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgYmluYXJ5IHNlYXJjaCBpdGVtIHBvc2l0aW9uIiwgbGwKKyAgICAgICAgICAgICAgICAgICAgLmdldChDb2xsZWN0aW9ucy5iaW5hcnlTZWFyY2gobGwsIGxsLmdldChjb3VudGVyKSkpID09IGxsCisgICAgICAgICAgICAgICAgICAgIC5nZXQoY291bnRlcikpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI2JpbmFyeVNlYXJjaChqYXZhLnV0aWwuTGlzdCwKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLk9iamVjdCwgamF2YS51dGlsLkNvbXBhcmF0b3IpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9iaW5hcnlTZWFyY2hMamF2YV91dGlsX0xpc3RMamF2YV9sYW5nX09iamVjdExqYXZhX3V0aWxfQ29tcGFyYXRvcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludAorICAgICAgICAvLyBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuYmluYXJ5U2VhcmNoKGphdmEudXRpbC5MaXN0LCBqYXZhLmxhbmcuT2JqZWN0LAorICAgICAgICAvLyBqYXZhLnV0aWwuQ29tcGFyYXRvcikKKyAgICAgICAgLy8gYXNzdW1lcyByZXZlcnNlZExpbmtlZExpc3QgaXMgc29ydGVkIGluIHJldmVyc2VkIG9yZGVyIGFuZCBoYXMgbm8KKyAgICAgICAgLy8gZHVwbGljYXRlIGtleXMKKyAgICAgICAgZmluYWwgaW50IHJTaXplID0gbXlSZXZlcnNlZExpbmtlZExpc3Quc2l6ZSgpOworICAgICAgICBSZXZlcnNlZE15SW50Q29tcGFyYXRvciBjb21wID0gbmV3IFJldmVyc2VkTXlJbnRDb21wYXJhdG9yKCk7CisgICAgICAgIC8vIEVuc3VyZSBhIE5QRSBpcyB0aHJvd24gaWYgdGhlIGxpc3QgaXMgTlVMTAorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMuYmluYXJ5U2VhcmNoKG51bGwsIG5ldyBPYmplY3QoKSwgY29tcCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiBmb3IgbnVsbCBsaXN0IHBhcmFtZXRlciIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCByU2l6ZTsgY291bnRlcisrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiUmV0dXJuZWQgaW5jb3JyZWN0IGJpbmFyeSBzZWFyY2ggaXRlbSBwb3NpdGlvbiB1c2luZyBjdXN0b20gY29tcGFyYXRvciIsCisgICAgICAgICAgICAgICAgICAgIG15UmV2ZXJzZWRMaW5rZWRMaXN0LmdldChDb2xsZWN0aW9ucy5iaW5hcnlTZWFyY2goCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXlSZXZlcnNlZExpbmtlZExpc3QsIG15UmV2ZXJzZWRMaW5rZWRMaXN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0KGNvdW50ZXIpLCBjb21wKSkgPT0gbXlSZXZlcnNlZExpbmtlZExpc3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0KGNvdW50ZXIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIE1vY2tfQXJyYXlMaXN0IGV4dGVuZHMgQXJyYXlMaXN0IHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYworICAgICAgICBPYmplY3Qgc2V0IChpbnQgaW5kZXgsIE9iamVjdCBvKXsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI2NvcHkoamF2YS51dGlsLkxpc3QsIGphdmEudXRpbC5MaXN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY29weUxqYXZhX3V0aWxfTGlzdExqYXZhX3V0aWxfTGlzdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkNvbGxlY3Rpb25zLmNvcHkoamF2YS51dGlsLkxpc3QsCisgICAgICAgIC8vIGphdmEudXRpbC5MaXN0KQorICAgICAgICAvLyBFbnN1cmUgYSBOUEUgaXMgdGhyb3duIGlmIHRoZSBsaXN0IGlzIE5VTEwKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLmNvcHkobnVsbCwgbGwpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gZm9yIG51bGwgbGlzdCBmaXJzdCBwYXJhbWV0ZXIiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5jb3B5KGxsLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIGZvciBudWxsIGxpc3Qgc2Vjb25kIHBhcmFtZXRlciIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgaW50IGxsU2l6ZSA9IGxsLnNpemUoKTsKKyAgICAgICAgbGwuc2V0KDI1LCBudWxsKTsKKyAgICAgICAgQXJyYXlMaXN0IGFsID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBJbnRlZ2VyIGV4dHJhRWxlbWVudCA9IG5ldyBJbnRlZ2VyKDEpOworICAgICAgICBJbnRlZ2VyIGV4dHJhRWxlbWVudDIgPSBuZXcgSW50ZWdlcigyKTsKKyAgICAgICAgYWwuYWRkQWxsKG15UmV2ZXJzZWRMaW5rZWRMaXN0KTsKKyAgICAgICAgYWwuYWRkKGV4dHJhRWxlbWVudCk7CisgICAgICAgIGFsLmFkZChleHRyYUVsZW1lbnQyKTsKKyAgICAgICAgQ29sbGVjdGlvbnMuY29weShhbCwgbGwpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGxsU2l6ZTsgY291bnRlcisrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJFbGVtZW50cyBkbyBub3QgbWF0Y2ggYWZ0ZXIgY29weWluZyBjb2xsZWN0aW9uIiwgYWwKKyAgICAgICAgICAgICAgICAgICAgLmdldChjb3VudGVyKSA9PSBsbC5nZXQoY291bnRlcikpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkVsZW1lbnRzIGFmdGVyIGNvcGllZCBlbGVtZW50cyBhZmZlY3RlZCBieSBjb3B5IiwKKyAgICAgICAgICAgICAgICBleHRyYUVsZW1lbnQgPT0gYWwuZ2V0KGxsU2l6ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIGV4dHJhRWxlbWVudDIgPT0gYWwuZ2V0KGxsU2l6ZSArIDEpKTsKKworICAgICAgICBBcnJheUxpc3QgYXIxID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBBcnJheUxpc3QgYXIyID0gbmV3IEFycmF5TGlzdCgpOworCisgICAgICAgIGludCBpOworCisgICAgICAgIGZvcihpID0gMDsgaSA8IDU7IGkgKyspIHsKKyAgICAgICAgICAgIGFyMi5hZGQobmV3IEludGVnZXIoaSkpOworICAgICAgICB9CisKKyAgICAgICAgZm9yKGkgPSAwOyBpIDwgMTA7IGkgKyspIHsKKyAgICAgICAgICAgIGFyMS5hZGQobmV3IEludGVnZXIoaSkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLmNvcHkoYXIyLCBhcjEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIE1vY2tfQXJyYXlMaXN0IG1hbDEgPSBuZXcgTW9ja19BcnJheUxpc3QoKTsKKyAgICAgICAgTW9ja19BcnJheUxpc3QgbWFsMiA9IG5ldyBNb2NrX0FycmF5TGlzdCgpOworCisgICAgICAgIGZvcihpID0gMDsgaSA8IDEwOyBpICsrKSB7CisgICAgICAgICAgICBtYWwxLmFkZChuZXcgSW50ZWdlcihpKSk7CisgICAgICAgICAgICBtYWwyLmFkZChuZXcgSW50ZWdlcigxMCAtIGkpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5jb3B5KG1hbDEsIG1hbDIpOworICAgICAgICAgICAgZmFpbCgiVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI2NvcHkoamF2YS51dGlsLkxpc3QsIGphdmEudXRpbC5MaXN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY29weV9jaGVja19pbmRleCgpIHsKKyAgICAgICAgQXJyYXlMaXN0IGExID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBhMS5hZGQoIm9uZSIpOworICAgICAgICBhMS5hZGQoInR3byIpOworCisgICAgICAgIEFycmF5TGlzdCBhMiA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgYTIuYWRkKCJhYSIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5jb3B5KGEyLCBhMSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhYSIsIGEyLmdldCgwKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI2VudW1lcmF0aW9uKGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZW51bWVyYXRpb25MamF2YV91dGlsX0NvbGxlY3Rpb24oKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuRW51bWVyYXRpb24KKyAgICAgICAgLy8gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVudW1lcmF0aW9uKGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAgICBUcmVlU2V0IHRzID0gbmV3IFRyZWVTZXQoKTsKKyAgICAgICAgdHMuYWRkQWxsKHMpOworICAgICAgICBFbnVtZXJhdGlvbiBlID0gQ29sbGVjdGlvbnMuZW51bWVyYXRpb24odHMpOworICAgICAgICBpbnQgY291bnQgPSAwOworICAgICAgICB3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBlbnVtZXJhdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIGUubmV4dEVsZW1lbnQoKSA9PSBvYmpBcnJheVtjb3VudCsrXSk7CisgICAgICAgIGFzc2VydFRydWUoIkVudW1lcmF0aW9uIG1pc3NpbmcgZWxlbWVudHM6ICIgKyBjb3VudCwKKyAgICAgICAgICAgICAgICBjb3VudCA9PSBvYmpBcnJheS5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Db2xsZWN0aW9ucyNmaWxsKGphdmEudXRpbC5MaXN0LCBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZmlsbExqYXZhX3V0aWxfTGlzdExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZmlsbChqYXZhLnV0aWwuTGlzdCwKKyAgICAgICAgLy8gamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLmZpbGwobnVsbCwgbmV3IE9iamVjdCgpKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIGZvciBudWxsIGxpc3QgcGFyYW1ldGVyIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBpbnQgc2l6ZSA9IGxsLnNpemUoKTsKKyAgICAgICAgQ29sbGVjdGlvbnMuZmlsbChsbCwgImsiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmlsbCBtb2RpZmllZCBsaXN0IHNpemUiLCBzaXplID09IGxsLnNpemUoKSk7CisgICAgICAgIEl0ZXJhdG9yIGkgPSBsbC5pdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoaS5oYXNOZXh0KCkpCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCB0byBmaWxsIGVsZW1lbnRzIiwgImsiLCBpLm5leHQoKSk7CisKKyAgICAgICAgQ29sbGVjdGlvbnMuZmlsbChsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoIkZpbGwgd2l0aCBudWxscyBtb2RpZmllZCBsaXN0IHNpemUiLCBzaXplID09IGxsLnNpemUoKSk7CisgICAgICAgIGkgPSBsbC5pdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoaS5oYXNOZXh0KCkpCisgICAgICAgICAgICBhc3NlcnROdWxsKCJGYWlsZWQgdG8gZmlsbCB3aXRoIG51bGxzIiwgaS5uZXh0KCkpOworCisgICAgICAgIE1vY2tfQXJyYXlMaXN0IG1hbCA9IG5ldyBNb2NrX0FycmF5TGlzdCgpOworCisgICAgICAgIG1hbC5hZGQoIm9uZSIpOworICAgICAgICBtYWwuYWRkKCJ0d28iKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMuZmlsbChtYWwsICJ2YWx1ZSIpOworICAgICAgICAgICAgZmFpbCgiVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZWNwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI21heChqYXZhLnV0aWwuQ29sbGVjdGlvbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X21heExqYXZhX3V0aWxfQ29sbGVjdGlvbigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QKKyAgICAgICAgLy8gamF2YS51dGlsLkNvbGxlY3Rpb25zLm1heChqYXZhLnV0aWwuQ29sbGVjdGlvbikKKyAgICAgICAgLy8gYXNzdW1lcyBzLCBvYmpBcnJheSBhcmUgc29ydGVkCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBtYXggZWxlbWVudCIsCisgICAgICAgICAgICAgICAgQ29sbGVjdGlvbnMubWF4KHMpID09IG9iakFycmF5W29iakFycmF5Lmxlbmd0aCAtIDFdKTsKKworICAgICAgICBBcnJheUxpc3QgYWwgPSBuZXcgQXJyYXlMaXN0KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLm1heChhbCk7CisgICAgICAgICAgICBmYWlsKCJOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYWwuYWRkKCJTdHJpbmciKTsKKyAgICAgICAgYWwuYWRkKG5ldyBJbnRlZ2VyKDEpKTsKKyAgICAgICAgYWwuYWRkKG5ldyBEb3VibGUoMy4xNCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5tYXgoYWwpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjbWF4KGphdmEudXRpbC5Db2xsZWN0aW9uLAorICAgICAqICAgICAgICBqYXZhLnV0aWwuQ29tcGFyYXRvcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X21heExqYXZhX3V0aWxfQ29sbGVjdGlvbkxqYXZhX3V0aWxfQ29tcGFyYXRvcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QKKyAgICAgICAgLy8gamF2YS51dGlsLkNvbGxlY3Rpb25zLm1heChqYXZhLnV0aWwuQ29sbGVjdGlvbiwgamF2YS51dGlsLkNvbXBhcmF0b3IpCisgICAgICAgIC8vIGFzc3VtZXMgcywgb2JqQXJyYXkgYXJlIHNvcnRlZAorCisgICAgICAgIC8vIFdpdGggdGhpcyBjdXN0b20gKGJhY2t3YXJkcykgY29tcGFyYXRvciB0aGUgJ21heCcgZWxlbWVudCBzaG91bGQgYmUKKyAgICAgICAgLy8gdGhlIHNtYWxsZXN0IGluIHRoZSBsaXN0CisgICAgICAgIFJldmVyc2VkTXlJbnRDb21wYXJhdG9yIHJtaWMgPSBuZXcgUmV2ZXJzZWRNeUludENvbXBhcmF0b3IoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiUmV0dXJuZWQgaW5jb3JyZWN0IG1heCBlbGVtZW50IHVzaW5nIGN1c3RvbSBjb21wYXJhdG9yIiwKKyAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy5tYXgobXlzLCBybWljKSA9PSBteW9iakFycmF5WzBdKTsKKworICAgICAgICBBcnJheUxpc3QgYWwgPSBuZXcgQXJyYXlMaXN0KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLm1heChhbCwgcm1pYyk7CisgICAgICAgICAgICBmYWlsKCJOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYWwuYWRkKCJTdHJpbmciKTsKKyAgICAgICAgYWwuYWRkKG5ldyBJbnRlZ2VyKDEpKTsKKyAgICAgICAgYWwuYWRkKG5ldyBEb3VibGUoMy4xNCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5tYXgoYWwsIHJtaWMpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjbWluKGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfbWluTGphdmFfdXRpbF9Db2xsZWN0aW9uKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdAorICAgICAgICAvLyBqYXZhLnV0aWwuQ29sbGVjdGlvbnMubWluKGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAgICAvLyBhc3N1bWVzIHMsIG9iakFycmF5IGFyZSBzb3J0ZWQKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IG1pbiBlbGVtZW50IiwKKyAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy5taW4ocykgPT0gb2JqQXJyYXlbMF0pOworICAgICAgICBBcnJheUxpc3QgYWwgPSBuZXcgQXJyYXlMaXN0KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLm1pbihhbCk7CisgICAgICAgICAgICBmYWlsKCJOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYWwuYWRkKCJTdHJpbmciKTsKKyAgICAgICAgYWwuYWRkKG5ldyBJbnRlZ2VyKDEpKTsKKyAgICAgICAgYWwuYWRkKG5ldyBEb3VibGUoMy4xNCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5taW4oYWwpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjbWluKGphdmEudXRpbC5Db2xsZWN0aW9uLAorICAgICAqICAgICAgICBqYXZhLnV0aWwuQ29tcGFyYXRvcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X21pbkxqYXZhX3V0aWxfQ29sbGVjdGlvbkxqYXZhX3V0aWxfQ29tcGFyYXRvcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QKKyAgICAgICAgLy8gamF2YS51dGlsLkNvbGxlY3Rpb25zLm1pbihqYXZhLnV0aWwuQ29sbGVjdGlvbiwgamF2YS51dGlsLkNvbXBhcmF0b3IpCisgICAgICAgIC8vIGFzc3VtZXMgcywgb2JqQXJyYXkgYXJlIHNvcnRlZAorCisgICAgICAgIC8vIFdpdGggdGhpcyBjdXN0b20gKGJhY2t3YXJkcykgY29tcGFyYXRvciB0aGUgJ21pbicgZWxlbWVudCBzaG91bGQgYmUKKyAgICAgICAgLy8gdGhlIGxhcmdlc3QgaW4gdGhlIGxpc3QKKyAgICAgICAgUmV2ZXJzZWRNeUludENvbXBhcmF0b3Igcm1pYyA9IG5ldyBSZXZlcnNlZE15SW50Q29tcGFyYXRvcigpOworCisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIlJldHVybmVkIGluY29ycmVjdCBtaW4gZWxlbWVudCB1c2luZyBjdXN0b20gY29tcGFyYXRvciIsCisgICAgICAgICAgICAgICAgQ29sbGVjdGlvbnMubWluKG15cywgcm1pYykgPT0gbXlvYmpBcnJheVtvYmpBcnJheS5sZW5ndGggLSAxXSk7CisKKyAgICAgICAgQXJyYXlMaXN0IGFsID0gbmV3IEFycmF5TGlzdCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5taW4oYWwsIHJtaWMpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGFsLmFkZCgiU3RyaW5nIik7CisgICAgICAgIGFsLmFkZChuZXcgSW50ZWdlcigxKSk7CisgICAgICAgIGFsLmFkZChuZXcgRG91YmxlKDMuMTQpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMubWluKGFsLCBybWljKTsKKyAgICAgICAgICAgIGZhaWwoIkNsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI25Db3BpZXMoaW50LCBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfbkNvcGllc0lMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5MaXN0IGphdmEudXRpbC5Db2xsZWN0aW9ucy5uQ29waWVzKGludCwKKyAgICAgICAgLy8gamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgT2JqZWN0IG8gPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIExpc3QgbCA9IENvbGxlY3Rpb25zLm5Db3BpZXMoMTAwLCBvKTsKKyAgICAgICAgSXRlcmF0b3IgaSA9IGwuaXRlcmF0b3IoKTsKKyAgICAgICAgT2JqZWN0IGZpcnN0ID0gaS5uZXh0KCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGxpc3QgY29uc2lzdHMgb2YgY29waWVzIG5vdCByZWZzIiwgZmlyc3QgPT0gbyk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgbGlzdCBvZiBpbmNvcnJlY3Qgc2l6ZSIsIDEwMCwgbC5zaXplKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJDb250YWlucyIsIGwuY29udGFpbnMobykpOworICAgICAgICBhc3NlcnRUcnVlKCJDb250YWlucyBudWxsIiwgIWwuY29udGFpbnMobnVsbCkpOworICAgICAgICBhc3NlcnRUcnVlKCJudWxsIG5Db3BpZXMgY29udGFpbnMiLCAhQ29sbGVjdGlvbnMubkNvcGllcygyLCBudWxsKQorICAgICAgICAgICAgICAgIC5jb250YWlucyhvKSk7CisgICAgICAgIGFzc2VydFRydWUoIm51bGwgbkNvcGllcyBjb250YWlucyBudWxsIiwgQ29sbGVjdGlvbnMubkNvcGllcygyLCBudWxsKQorICAgICAgICAgICAgICAgIC5jb250YWlucyhudWxsKSk7CisgICAgICAgIGwgPSBDb2xsZWN0aW9ucy5uQ29waWVzKDIwLCBudWxsKTsKKyAgICAgICAgaSA9IGwuaXRlcmF0b3IoKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGkuaGFzTmV4dCgpOyBjb3VudGVyKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkxpc3QgaXMgdG9vIGxhcmdlIiwgY291bnRlciA8IDIwKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoIkVsZW1lbnQgc2hvdWxkIGJlIG51bGw6ICIgKyBjb3VudGVyLCBpLm5leHQoKSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGwuYWRkKG8pOworICAgICAgICAgICAgZmFpbCgiUmV0dXJuZWQgbGlzdCBpcyBub3QgaW1tdXRhYmxlIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMubkNvcGllcygtMiwgbmV3IEhhc2hTZXQoKSk7CisgICAgICAgICAgICBmYWlsKCJuQ29waWVzIHdpdGggbmVnYXRpdmUgYXJnIGRpZG4ndCB0aHJvdyBJQUUiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjcmV2ZXJzZShqYXZhLnV0aWwuTGlzdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JldmVyc2VMamF2YV91dGlsX0xpc3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5Db2xsZWN0aW9ucy5yZXZlcnNlKGphdmEudXRpbC5MaXN0KQorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMucmV2ZXJzZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIGZvciBudWxsIGxpc3QgcGFyYW1ldGVyIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBDb2xsZWN0aW9ucy5yZXZlcnNlKGxsKTsKKyAgICAgICAgSXRlcmF0b3IgaSA9IGxsLml0ZXJhdG9yKCk7CisgICAgICAgIGludCBjb3VudCA9IG9iakFycmF5Lmxlbmd0aCAtIDE7CisgICAgICAgIHdoaWxlIChpLmhhc05leHQoKSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIHJldmVyc2UgY29sbGVjdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIGkubmV4dCgpID09IG9iakFycmF5W2NvdW50XSk7CisgICAgICAgICAgICAtLWNvdW50OworICAgICAgICB9CisgICAgICAgIEFycmF5TGlzdCBteUxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIG15TGlzdC5hZGQobnVsbCk7CisgICAgICAgIG15TGlzdC5hZGQobmV3IEludGVnZXIoMjApKTsKKyAgICAgICAgQ29sbGVjdGlvbnMucmV2ZXJzZShteUxpc3QpOworICAgICAgICBhc3NlcnRUcnVlKCJEaWQgbm90IHJldmVyc2UgY29ycmVjdGx5LS1maXJzdCBlbGVtZW50IGlzOiAiCisgICAgICAgICAgICAgICAgKyBteUxpc3QuZ2V0KDApLCBteUxpc3QuZ2V0KDApLmVxdWFscyhuZXcgSW50ZWdlcigyMCkpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiRGlkIG5vdCByZXZlcnNlIGNvcnJlY3RseS0tc2Vjb25kIGVsZW1lbnQgaXM6ICIKKyAgICAgICAgICAgICAgICArIG15TGlzdC5nZXQoMSksIG15TGlzdC5nZXQoMSkpOworCisgICAgICAgIE1vY2tfQXJyYXlMaXN0IG1hbCA9IG5ldyBNb2NrX0FycmF5TGlzdCgpOworCisgICAgICAgIG1hbC5hZGQoIkZpcnN0Iik7CisgICAgICAgIG1hbC5hZGQoIlNlY29uZCIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5yZXZlcnNlKG1hbCk7CisgICAgICAgICAgICBmYWlsKCJVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjcmV2ZXJzZU9yZGVyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JldmVyc2VPcmRlcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5Db21wYXJhdG9yCisgICAgICAgIC8vIGphdmEudXRpbC5Db2xsZWN0aW9ucy5yZXZlcnNlT3JkZXIoKQorICAgICAgICAvLyBhc3N1bWVzIG5vIGR1cGxpY2F0ZXMgaW4gbGwKKyAgICAgICAgQ29tcGFyYXRvciBjb21wID0gQ29sbGVjdGlvbnMucmV2ZXJzZU9yZGVyKCk7CisgICAgICAgIExpbmtlZExpc3QgbGlzdDIgPSBuZXcgTGlua2VkTGlzdChsbCk7CisgICAgICAgIENvbGxlY3Rpb25zLnNvcnQobGlzdDIsIGNvbXApOworICAgICAgICBmaW5hbCBpbnQgbGxTaXplID0gbGwuc2l6ZSgpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGxsU2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTmV3IGNvbXBhcmF0b3IgZG9lcyBub3QgcmV2ZXJzZSBzb3J0aW5nIG9yZGVyIiwgbGwKKyAgICAgICAgICAgICAgICAgICAgLmdldChjb3VudGVyKSA9PSBsaXN0Mi5nZXQobGxTaXplIC0gY291bnRlciAtIDEpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjc2h1ZmZsZShqYXZhLnV0aWwuTGlzdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NodWZmbGVMamF2YV91dGlsX0xpc3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5Db2xsZWN0aW9ucy5zaHVmZmxlKGphdmEudXRpbC5MaXN0KQorICAgICAgICAvLyBBc3N1bWVzIGxsIGlzIHNvcnRlZCBhbmQgaGFzIG5vIGR1cGxpY2F0ZSBrZXlzIGFuZCBpcyBsYXJnZSAoID4gMjAKKyAgICAgICAgLy8gZWxlbWVudHMpCisKKyAgICAgICAgLy8gdGVzdCBzaHVmZmxpbmcgYSBTZXF1ZW50aWFsIEFjY2VzcyBMaXN0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5zaHVmZmxlKG51bGwpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gZm9yIG51bGwgbGlzdCBwYXJhbWV0ZXIiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIEFycmF5TGlzdCBhbCA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgYWwuYWRkQWxsKGxsKTsKKyAgICAgICAgdGVzdFNodWZmbGUoYWwsICJTZXF1ZW50aWFsIEFjY2VzcyIsIGZhbHNlKTsKKworICAgICAgICAvLyB0ZXN0IHNodWZmbGluZyBhIFJhbmRvbSBBY2Nlc3MgTGlzdAorICAgICAgICBMaW5rZWRMaXN0IGxsMiA9IG5ldyBMaW5rZWRMaXN0KCk7CisgICAgICAgIGxsMi5hZGRBbGwobGwpOworICAgICAgICB0ZXN0U2h1ZmZsZShsbDIsICJSYW5kb20gQWNjZXNzIiwgZmFsc2UpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTaHVmZmxlUmFuZG9tQWNjZXNzV2l0aFNlZWRlZFJhbmRvbSgpIHsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGxpc3QgPSBBcnJheXMuYXNMaXN0KCJBIiwgIkIiLCAiQyIsICJEIiwgIkUiLCAiRiIsICJHIik7CisgICAgICAgIENvbGxlY3Rpb25zLnNodWZmbGUobGlzdCwgbmV3IFJhbmRvbSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KCJCIiwgIkEiLCAiRCIsICJDIiwgIkciLCAiRSIsICJGIiksIGxpc3QpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTaHVmZmxlV2l0aFNlZWRlZFJhbmRvbSgpIHsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGxpc3QgPSBuZXcgTGlua2VkTGlzdDxTdHJpbmc+KEFycmF5cy5hc0xpc3QoCisgICAgICAgICAgICAgICAgIkEiLCAiQiIsICJDIiwgIkQiLCAiRSIsICJGIiwgIkciKSk7CisgICAgICAgIENvbGxlY3Rpb25zLnNodWZmbGUobGlzdCwgbmV3IFJhbmRvbSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhBcnJheXMuYXNMaXN0KCJCIiwgIkEiLCAiRCIsICJDIiwgIkciLCAiRSIsICJGIiksIGxpc3QpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0U2h1ZmZsZShMaXN0IGxpc3QsIFN0cmluZyB0eXBlLCBib29sZWFuIHJhbmRvbSkgeworICAgICAgICBib29sZWFuIHNvcnRlZCA9IHRydWU7CisgICAgICAgIGJvb2xlYW4gYWxsTWF0Y2ggPSB0cnVlOworICAgICAgICBpbnQgaW5kZXggPSAwOworICAgICAgICBmaW5hbCBpbnQgc2l6ZSA9IGxpc3Quc2l6ZSgpOworCisgICAgICAgIGlmIChyYW5kb20pCisgICAgICAgICAgICBDb2xsZWN0aW9ucy5zaHVmZmxlKGxpc3QpOworICAgICAgICBlbHNlCisgICAgICAgICAgICBDb2xsZWN0aW9ucy5zaHVmZmxlKGxpc3QsIG5ldyBSYW5kb20oMjAwKSk7CisKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBzaXplIC0gMTsgY291bnRlcisrKSB7CisgICAgICAgICAgICBpZiAoKChJbnRlZ2VyKSBsaXN0LmdldChjb3VudGVyKSkuY29tcGFyZVRvKChJbnRlZ2VyKWxpc3QuZ2V0KGNvdW50ZXIgKyAxKSkgPiAwKSB7CisgICAgICAgICAgICAgICAgc29ydGVkID0gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNodWZmbGluZyBzb3J0ZWQgIiArIHR5cGUKKyAgICAgICAgICAgICAgICArICIgbGlzdCByZXN1bHRlZCBpbiBzb3J0ZWQgbGlzdCAoc2hvdWxkIGJlIHVubGlrZWx5KSIsIHNvcnRlZCk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgMjA7IGNvdW50ZXIrKykgeworICAgICAgICAgICAgaW5kZXggPSAzMDAzMSAqIGNvdW50ZXIgJSAoc2l6ZSArIDEpOyAvLyAzMDAzMSBpcyBhIGxhcmdlIHByaW1lCisgICAgICAgICAgICBpZiAobGlzdC5nZXQoaW5kZXgpICE9IGxsLmdldChpbmRleCkpCisgICAgICAgICAgICAgICAgYWxsTWF0Y2ggPSBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZSgiVG9vIG1hbnkgZWxlbWVudCBwb3NpdGlvbnMgbWF0Y2ggaW4gc2h1ZmZsZWQgIiArIHR5cGUKKyAgICAgICAgICAgICAgICArICIgbGlzdCIsIGFsbE1hdGNoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjc2h1ZmZsZShqYXZhLnV0aWwuTGlzdCwgamF2YS51dGlsLlJhbmRvbSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NodWZmbGVMamF2YV91dGlsX0xpc3RMamF2YV91dGlsX1JhbmRvbSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkNvbGxlY3Rpb25zLnNodWZmbGUoamF2YS51dGlsLkxpc3QsCisgICAgICAgIC8vIGphdmEudXRpbC5SYW5kb20pCisgICAgICAgIC8vIEFzc3VtZXMgbGwgaXMgc29ydGVkIGFuZCBoYXMgbm8gZHVwbGljYXRlIGtleXMgYW5kIGlzIGxhcmdlICggPiAyMAorICAgICAgICAvLyBlbGVtZW50cykKKworICAgICAgICAvLyB0ZXN0IHNodWZmbGluZyBhIFNlcXVlbnRpYWwgQWNjZXNzIExpc3QKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLnNodWZmbGUobnVsbCwgbmV3IFJhbmRvbSgyMDApKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIGZvciBudWxsIGxpc3QgcGFyYW1ldGVyIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBBcnJheUxpc3QgYWwgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGFsLmFkZEFsbChsbCk7CisgICAgICAgIHRlc3RTaHVmZmxlKGFsLCAiU2VxdWVudGlhbCBBY2Nlc3MiLCB0cnVlKTsKKworICAgICAgICAvLyB0ZXN0IHNodWZmbGluZyBhIFJhbmRvbSBBY2Nlc3MgTGlzdAorICAgICAgICBMaW5rZWRMaXN0IGxsMiA9IG5ldyBMaW5rZWRMaXN0KCk7CisgICAgICAgIGxsMi5hZGRBbGwobGwpOworICAgICAgICB0ZXN0U2h1ZmZsZShsbDIsICJSYW5kb20gQWNjZXNzIiwgdHJ1ZSk7CisKKworICAgICAgICBNb2NrX0FycmF5TGlzdCBtYWwgPSBuZXcgTW9ja19BcnJheUxpc3QoKTsKKworICAgICAgICBtYWwuYWRkKCJGaXJzdCIpOworICAgICAgICBtYWwuYWRkKCJTZWNvbmQiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMuc2h1ZmZsZShtYWwsIG5ldyBSYW5kb20oMjAwKSk7CisgICAgICAgICAgICBmYWlsKCJVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KK30KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Db2xsZWN0aW9ucyNzaW5nbGV0b24oamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NpbmdsZXRvbkxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlNldAorICAgICAgICAvLyBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuc2luZ2xldG9uKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIE9iamVjdCBvID0gbmV3IE9iamVjdCgpOworICAgICAgICBTZXQgc2luZ2xlID0gQ29sbGVjdGlvbnMuc2luZ2xldG9uKG8pOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAxLCBzaW5nbGUuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29udGFpbnMiLCBzaW5nbGUuY29udGFpbnMobykpOworICAgICAgICBhc3NlcnRUcnVlKCJDb250YWlucyBudWxsIiwgIXNpbmdsZS5jb250YWlucyhudWxsKSk7CisgICAgICAgIGFzc2VydFRydWUoIm51bGwgbkNvcGllcyBjb250YWlucyIsICFDb2xsZWN0aW9ucy5zaW5nbGV0b24obnVsbCkKKyAgICAgICAgICAgICAgICAuY29udGFpbnMobykpOworICAgICAgICBhc3NlcnRUcnVlKCJudWxsIG5Db3BpZXMgY29udGFpbnMgbnVsbCIsIENvbGxlY3Rpb25zLnNpbmdsZXRvbihudWxsKQorICAgICAgICAgICAgICAgIC5jb250YWlucyhudWxsKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaW5nbGUuYWRkKCJsIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmYWlsKCJBbGxvd2VkIG1vZGlmaWNhdGlvbiBvZiBzaW5nbGV0b24iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjc29ydChqYXZhLnV0aWwuTGlzdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NvcnRMamF2YV91dGlsX0xpc3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5Db2xsZWN0aW9ucy5zb3J0KGphdmEudXRpbC5MaXN0KQorICAgICAgICAvLyBhc3N1bWVzIG5vIGR1cGxpY2F0ZSBrZXlzIGluIGxsCisgICAgICAgIGZpbmFsIGludCBsbFNpemUgPSBsbC5zaXplKCk7CisgICAgICAgIGZpbmFsIGludCBybGxTaXplID0gcmV2ZXJzZWRMaW5rZWRMaXN0LnNpemUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb25zLnNvcnQoKExpc3QpbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiBmb3IgbnVsbCBsaXN0IHBhcmFtZXRlciIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgQ29sbGVjdGlvbnMuc2h1ZmZsZShsbCk7CisgICAgICAgIENvbGxlY3Rpb25zLnNvcnQobGwpOworICAgICAgICBDb2xsZWN0aW9ucy5zb3J0KHJldmVyc2VkTGlua2VkTGlzdCk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgbGxTaXplIC0gMTsgY291bnRlcisrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiU29ydGluZyBzaHVmZmxlZCBsaXN0IHJlc3VsdGVkIGluIHVuc29ydGVkIGxpc3QiLAorICAgICAgICAgICAgICAgICAgICAoKEludGVnZXIpIGxsLmdldChjb3VudGVyKSkuY29tcGFyZVRvKChJbnRlZ2VyKWxsLmdldChjb3VudGVyICsgMSkpIDwgMCk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IHJsbFNpemUgLSAxOyBjb3VudGVyKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlNvcnRpbmcgcmV2ZXJzZWQgbGlzdCByZXN1bHRlZCBpbiB1bnNvcnRlZCBsaXN0IiwKKyAgICAgICAgICAgICAgICAgICAgKChJbnRlZ2VyKSByZXZlcnNlZExpbmtlZExpc3QuZ2V0KGNvdW50ZXIpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb21wYXJlVG8oKEludGVnZXIpcmV2ZXJzZWRMaW5rZWRMaXN0LmdldChjb3VudGVyICsgMSkpIDwgMCk7CisgICAgICAgIH0KKworICAgICAgICBBcnJheUxpc3QgYWwgPSBuZXcgQXJyYXlMaXN0KCk7CisKKyAgICAgICAgYWwuYWRkKCJTdHJpbmciKTsKKyAgICAgICAgYWwuYWRkKG5ldyBJbnRlZ2VyKDEpKTsKKyAgICAgICAgYWwuYWRkKG5ldyBEb3VibGUoMy4xNCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5zb3J0KGFsKTsKKyAgICAgICAgICAgIGZhaWwoIkNsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgTW9ja19BcnJheUxpc3QgbWFsID0gbmV3IE1vY2tfQXJyYXlMaXN0KCk7CisKKyAgICAgICAgbWFsLmFkZCgiRmlyc3QiKTsKKyAgICAgICAgbWFsLmFkZCgiU2Vjb25kIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLnNvcnQobWFsKTsKKyAgICAgICAgICAgIGZhaWwoIlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI3NvcnQoamF2YS51dGlsLkxpc3QsIGphdmEudXRpbC5Db21wYXJhdG9yKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc29ydExqYXZhX3V0aWxfTGlzdExqYXZhX3V0aWxfQ29tcGFyYXRvcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkNvbGxlY3Rpb25zLnNvcnQoamF2YS51dGlsLkxpc3QsCisgICAgICAgIC8vIGphdmEudXRpbC5Db21wYXJhdG9yKQorICAgICAgICBDb21wYXJhdG9yIGNvbXAgPSBuZXcgUmV2ZXJzZWRNeUludENvbXBhcmF0b3IoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLnNvcnQobnVsbCwgY29tcCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiBmb3IgbnVsbCBsaXN0IHBhcmFtZXRlciIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgQ29sbGVjdGlvbnMuc2h1ZmZsZShteWxsKTsKKyAgICAgICAgQ29sbGVjdGlvbnMuc29ydChteWxsLCBjb21wKTsKKyAgICAgICAgZmluYWwgaW50IGxsU2l6ZSA9IG15bGwuc2l6ZSgpOworCisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgbGxTaXplIC0gMTsgY291bnRlcisrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiU29ydGluZyBzaHVmZmxlZCBsaXN0IHdpdGggY3VzdG9tIGNvbXBhcmF0b3IgcmVzdWx0ZWQgaW4gdW5zb3J0ZWQgbGlzdCIsCisgICAgICAgICAgICAgICAgICAgICgoTXlJbnQpIG15bGwuZ2V0KGNvdW50ZXIpKS5jb21wYXJlVG8oKE15SW50KSBteWxsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldChjb3VudGVyICsgMSkpID49IDApOworICAgICAgICB9CisKKyAgICAgICAgQXJyYXlMaXN0IGFsID0gbmV3IEFycmF5TGlzdCgpOworCisgICAgICAgIGFsLmFkZCgiU3RyaW5nIik7CisgICAgICAgIGFsLmFkZChuZXcgSW50ZWdlcigxKSk7CisgICAgICAgIGFsLmFkZChuZXcgRG91YmxlKDMuMTQpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMuc29ydChhbCwgY29tcCk7CisgICAgICAgICAgICBmYWlsKCJDbGFzc0Nhc3RFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIE1vY2tfQXJyYXlMaXN0IG1hbCA9IG5ldyBNb2NrX0FycmF5TGlzdCgpOworCisgICAgICAgIG1hbC5hZGQobmV3IE15SW50KDEpKTsKKyAgICAgICAgbWFsLmFkZChuZXcgTXlJbnQoMikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5zb3J0KG1hbCwgY29tcCk7CisgICAgICAgICAgICBmYWlsKCJVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjc3dhcChqYXZhLnV0aWwuTGlzdCwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zd2FwTGphdmFfdXRpbF9MaXN0SUkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBzd2FwKGphdmEudXRpbC5MaXN0LCBpbnQsIGludCkKKworICAgICAgICBMaW5rZWRMaXN0IHNtYWxsTGlzdCA9IG5ldyBMaW5rZWRMaXN0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgICAgICAgICAgc21hbGxMaXN0LmFkZChvYmpBcnJheVtpXSk7CisgICAgICAgIH0KKworICAgICAgICAvLyB0ZXN0IGV4Y2VwdGlvbiBjYXNlcworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMuc3dhcChzbWFsbExpc3QsIC0xLCA2KTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZm9yIC0xIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLnN3YXAoc21hbGxMaXN0LCA2LCAtMSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGZvciAtMSIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5zd2FwKHNtYWxsTGlzdCwgNiwgMTEpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBmb3IgMTEiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMuc3dhcChzbWFsbExpc3QsIDExLCA2KTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZm9yIDExIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gRW5zdXJlIGEgTlBFIGlzIHRocm93biBpZiB0aGUgbGlzdCBpcyBOVUxMCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5zd2FwKG51bGwsIDEsIDEpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gZm9yIG51bGwgbGlzdCBwYXJhbWV0ZXIiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gdGVzdCB3aXRoIHZhbGlkIHBhcmFtZXRlcnMKKyAgICAgICAgQ29sbGVjdGlvbnMuc3dhcChzbWFsbExpc3QsIDQsIDcpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkRpZG4ndCBTd2FwIHRoZSBlbGVtZW50IGF0IHBvc2l0aW9uIDQgIiwgbmV3IEludGVnZXIoNyksCisgICAgICAgICAgICAgICAgc21hbGxMaXN0LmdldCg0KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRGlkbid0IFN3YXAgdGhlIGVsZW1lbnQgYXQgcG9zaXRpb24gNyAiLCBuZXcgSW50ZWdlcig0KSwKKyAgICAgICAgICAgICAgICBzbWFsbExpc3QuZ2V0KDcpKTsKKworICAgICAgICAvLyBtYWtlIHN1cmUgb3RoZXIgZWxlbWVudHMgZGlkbid0IGdldCBzd2FwcGVkIGJ5IG1pc3Rha2UKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoaSAhPSA0ICYmIGkgIT0gNykKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInNob3VsZG4ndCBoYXZlIHN3YXBwZWQgdGhlIGVsZW1lbnQgYXQgcG9zaXRpb24gIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBpLCBuZXcgSW50ZWdlcihpKSwgc21hbGxMaXN0LmdldChpKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjcmVwbGFjZUFsbChqYXZhLnV0aWwuTGlzdCwgamF2YS5sYW5nLk9iamVjdCwKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlcGxhY2VBbGxMamF2YV91dGlsX0xpc3RMamF2YV9sYW5nX09iamVjdExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgcmVwbGFjZUFsbChqYXZhLnV0aWwuTGlzdCwgamF2YS5sYW5nLk9iamVjdCwKKyAgICAgICAgLy8gamF2YS5sYW5nLk9iamVjdCkKKworICAgICAgICBTdHJpbmcgc3RyaW5nMSA9ICJBLUItQy1ELUUtUy1KRi1TVUItRy1ILUktSi1TVUJMLUstTC1MSVNULU0tTi0tUy1TLU8tU1VCTElTLVAtUS1SLVNVQkxJU1QtUy1ULVUtVi1XLVgtWS1aIjsKKyAgICAgICAgY2hhcltdIGNoYXJzID0gc3RyaW5nMS50b0NoYXJBcnJheSgpOworICAgICAgICBMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2hhcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGxpc3QuYWRkKG5ldyBDaGFyYWN0ZXIoY2hhcnNbaV0pKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9ucy5yZXBsYWNlQWxsKG51bGwsIG5ldyBPYmplY3QoKSwgbmV3IE9iamVjdCgpKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIGZvciBudWxsIGxpc3QgcGFyYW1ldGVyIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3QgcmVwbGFjZSBmb3IgYW4gZWxlbWVudCB0aGF0IGlzIG5vdCBpbiB0aGUgbGlzdAorICAgICAgICBib29sZWFuIHJlc3VsdCA9IENvbGxlY3Rpb25zLnJlcGxhY2VBbGwobGlzdCwgbmV3IENoYXJhY3RlcignMScpLAorICAgICAgICAgICAgICAgIG5ldyBDaGFyYWN0ZXIoJ1onKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUZXN0MTogQ29sbGVjdGlvbnMucmVwbGFjZUFsbCgpIHJldHVybmVkIHdyb25nIHJlc3VsdCIsCisgICAgICAgICAgICAgICAgcmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0MiA6IFJlcGxhY2VBbGwgbW9kaWZpZWQgdGhlIGxpc3QgaW5jb3JyZWN0bHkiLAorICAgICAgICAgICAgICAgIHN0cmluZzEsIGdldFN0cmluZyhsaXN0KSk7CisKKyAgICAgICAgLy8gdGVzdCByZXBsYWNlIGZvciBhbiBlbGVtZW50IHRoYXQgaXMgaW4gdGhlIGxpc3QKKyAgICAgICAgcmVzdWx0ID0gQ29sbGVjdGlvbnMucmVwbGFjZUFsbChsaXN0LCBuZXcgQ2hhcmFjdGVyKCdTJyksCisgICAgICAgICAgICAgICAgbmV3IENoYXJhY3RlcignSycpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdDM6IENvbGxlY3Rpb25zLnJlcGxhY2VBbGwoKSByZXR1cm5lZCB3cm9uZyByZXN1bHQiLAorICAgICAgICAgICAgICAgIHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDQ6IFJlcGxhY2VBbGwgbW9kaWZpZWQgdGhlIGxpc3QgaW5jb3JyZWN0bHkiLAorICAgICAgICAgICAgICAgIChzdHJpbmcxID0gc3RyaW5nMS5yZXBsYWNlKCdTJywgJ0snKSksIGdldFN0cmluZyhsaXN0KSk7CisKKyAgICAgICAgLy8gdGVzdCByZXBsYWNlIGZvciB0aGUgbGFzdCBlbGVtZW50IGluIHRoZSBsaXN0CisgICAgICAgIHJlc3VsdCA9IENvbGxlY3Rpb25zLnJlcGxhY2VBbGwobGlzdCwgbmV3IENoYXJhY3RlcignWicpLAorICAgICAgICAgICAgICAgIG5ldyBDaGFyYWN0ZXIoJ04nKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3Q1OiBDb2xsZWN0aW9ucy5yZXBsYWNlQWxsKCkgcmV0dXJuZWQgd3JvbmcgcmVzdWx0IiwKKyAgICAgICAgICAgICAgICByZXN1bHQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3Q2OiBSZXBsYWNlQWxsIG1vZGlmaWVkIHRoZSBsaXN0IGluY29ycmVjdGx5IiwKKyAgICAgICAgICAgICAgICAoc3RyaW5nMSA9IHN0cmluZzEucmVwbGFjZSgnWicsICdOJykpLCBnZXRTdHJpbmcobGlzdCkpOworCisgICAgICAgIC8vIHRlc3QgcmVwbGFjZSBmb3IgdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIGxpc3QKKyAgICAgICAgcmVzdWx0ID0gQ29sbGVjdGlvbnMucmVwbGFjZUFsbChsaXN0LCBuZXcgQ2hhcmFjdGVyKCdBJyksCisgICAgICAgICAgICAgICAgbmV3IENoYXJhY3RlcignQicpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdDc6IENvbGxlY3Rpb25zLnJlcGxhY2VBbGwoKSByZXR1cm5lZCB3cm9uZyByZXN1bHQiLAorICAgICAgICAgICAgICAgIHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDg6IFJlcGxhY2VBbGwgbW9kaWZpZWQgdGhlIGxpc3QgaW5jb3JyZWN0bHkiLAorICAgICAgICAgICAgICAgIChzdHJpbmcxID0gc3RyaW5nMS5yZXBsYWNlKCdBJywgJ0InKSksIGdldFN0cmluZyhsaXN0KSk7CisKKyAgICAgICAgLy8gdGVzdCByZXBsYWNpbmcgZWxlbWVudHMgd2l0aCBudWxsCisgICAgICAgIExpbmtlZExpc3Qgc21hbGxMaXN0ID0gbmV3IExpbmtlZExpc3QoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgICAgICAgICBzbWFsbExpc3QuYWRkKG9iakFycmF5W2ldKTsKKyAgICAgICAgfQorICAgICAgICBzbWFsbExpc3Quc2V0KDQsIG5ldyBJbnRlZ2VyKDUpKTsKKyAgICAgICAgcmVzdWx0ID0gQ29sbGVjdGlvbnMucmVwbGFjZUFsbChzbWFsbExpc3QsIG5ldyBJbnRlZ2VyKDUpLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdDk6IENvbGxlY3Rpb25zLnJlcGxhY2VBbGwoKSByZXR1cm5lZCB3cm9uZyByZXN1bHQiLAorICAgICAgICAgICAgICAgIHJlc3VsdCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc21hbGxMaXN0LnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICBpZiAoaSA9PSA0IHx8IGkgPT0gNSkKKyAgICAgICAgICAgICAgICBhc3NlcnRTYW1lKCJUZXN0OTogUmVwbGFjZUFsbCBkaWRuJ3QgcmVwbGFjZSBlbGVtZW50IGF0ICIgKyBpLAorICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgc21hbGxMaXN0LmdldChpKSk7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgIlRlc3Q5OiBSZXBsYWNlQWxsIHNob3VsZG4ndCBoYXZlIHJlcGxhY2VkIGVsZW1lbnQgYXQgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGksIG5ldyBJbnRlZ2VyKGkpLCBzbWFsbExpc3QuZ2V0KGkpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3QgcmVwbGFjaW5nIG51bGwgZWxlbWVudHMgd2l0aCBhbm90aGVyIHZhbHVlCisgICAgICAgIHJlc3VsdCA9IENvbGxlY3Rpb25zLnJlcGxhY2VBbGwoc21hbGxMaXN0LCBudWxsLCBuZXcgSW50ZWdlcig5OSkpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0MTA6IENvbGxlY3Rpb25zLnJlcGxhY2VBbGwoKSByZXR1cm5lZCB3cm9uZyByZXN1bHQiLAorICAgICAgICAgICAgICAgIHJlc3VsdCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzbWFsbExpc3Quc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChpID09IDQgfHwgaSA9PSA1KQorICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDEwOiBSZXBsYWNlQWxsIGRpZG4ndCByZXBsYWNlIGVsZW1lbnQgYXQgIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBpLCBuZXcgSW50ZWdlcig5OSksIHNtYWxsTGlzdC5nZXQoaSkpOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgICJUZXN0MTA6IFJlcGxhY2VBbGwgc2hvdWxkbid0IGhhdmUgcmVwbGFjZWQgZWxlbWVudCBhdCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgaSwgbmV3IEludGVnZXIoaSksIHNtYWxsTGlzdC5nZXQoaSkpOworICAgICAgICB9CisKKyAgICAgICAgTW9ja19BcnJheUxpc3QgbWFsID0gbmV3IE1vY2tfQXJyYXlMaXN0KCk7CisKKyAgICAgICAgbWFsLmFkZCgiRmlyc3QiKTsKKyAgICAgICAgbWFsLmFkZCgiU2Vjb25kIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLnJlcGxhY2VBbGwobWFsLCAiU2Vjb25kIiwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjcm90YXRlKGphdmEudXRpbC5MaXN0LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yb3RhdGVMamF2YV91dGlsX0xpc3RJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgcm90YXRlKGphdmEudXRpbC5MaXN0LCBpbnQpCisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLnJvdGF0ZShudWxsLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIGZvciBudWxsIGxpc3QgcGFyYW1ldGVyIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3Qgcm90YXRpbmcgYSBTZXF1ZW50aWFsIEFjY2VzcyBMaXN0CisgICAgICAgIExpbmtlZExpc3QgbGlzdDEgPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICAgICAgICAgIGxpc3QxLmFkZChvYmpBcnJheVtpXSk7CisgICAgICAgIH0KKyAgICAgICAgdGVzdFJvdGF0ZShsaXN0MSwgIlNlcXVlbnRpYWwgQWNjZXNzIik7CisKKyAgICAgICAgLy8gVGVzdCByb3RhdGluZyBhIFJhbmRvbSBBY2Nlc3MgTGlzdAorICAgICAgICBBcnJheUxpc3QgbGlzdDIgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgICAgICAgICAgbGlzdDIuYWRkKG9iakFycmF5W2ldKTsKKyAgICAgICAgfQorICAgICAgICB0ZXN0Um90YXRlKGxpc3QyLCAiUmFuZG9tIEFjY2VzcyIpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0Um90YXRlKExpc3QgbGlzdCwgU3RyaW5nIHR5cGUpIHsKKyAgICAgICAgLy8gcm90YXRlIHdpdGggcG9zaXRpdmUgZGlzdGFuY2UKKyAgICAgICAgQ29sbGVjdGlvbnMucm90YXRlKGxpc3QsIDcpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QxOiByb3RhdGUgbW9kaWZpZWQgdGhlICIgKyB0eXBlCisgICAgICAgICAgICAgICAgKyAiIGxpc3QgaW5jb3JyZWN0bHksIiwgIjM0NTY3ODkwMTIiLCBnZXRTdHJpbmcobGlzdCkpOworCisgICAgICAgIC8vIHJvdGF0ZSB3aXRoIG5lZ2F0aXZlIGRpc3RhbmNlCisgICAgICAgIENvbGxlY3Rpb25zLnJvdGF0ZShsaXN0LCAtMik7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDI6IHJvdGF0ZSBtb2RpZmllZCB0aGUgIiArIHR5cGUKKyAgICAgICAgICAgICAgICArICIgbGlzdCBpbmNvcnJlY3RseSwiLCAiNTY3ODkwMTIzNCIsIGdldFN0cmluZyhsaXN0KSk7CisKKyAgICAgICAgLy8gcm90YXRlIHN1Ymxpc3Qgd2l0aCBuZWdhdGl2ZSBkaXN0YW5jZQorICAgICAgICBMaXN0IHN1Ykxpc3QgPSBsaXN0LnN1Ykxpc3QoMSwgNSk7CisgICAgICAgIENvbGxlY3Rpb25zLnJvdGF0ZShzdWJMaXN0LCAtMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDM6IHJvdGF0ZSBtb2RpZmllZCB0aGUgIiArIHR5cGUKKyAgICAgICAgICAgICAgICArICIgbGlzdCBpbmNvcnJlY3RseSwiLCAiNTc4OTYwMTIzNCIsIGdldFN0cmluZyhsaXN0KSk7CisKKyAgICAgICAgLy8gcm90YXRlIHN1Ymxpc3Qgd2l0aCBwb3NpdGl2ZSBkaXN0YW5jZQorICAgICAgICBDb2xsZWN0aW9ucy5yb3RhdGUoc3ViTGlzdCwgMik7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdDQ6IHJvdGF0ZSBtb2RpZmllZCB0aGUgIiArIHR5cGUKKyAgICAgICAgICAgICAgICArICIgbGlzdCBpbmNvcnJlY3RseSwiLCAiNTk2NzgwMTIzNCIsIGdldFN0cmluZyhsaXN0KSk7CisKKyAgICAgICAgLy8gcm90YXRlIHdpdGggcG9zaXRpdmUgZGlzdGFuY2UgdGhhdCBpcyBsYXJnZXIgdGhhbiBsaXN0IHNpemUKKyAgICAgICAgQ29sbGVjdGlvbnMucm90YXRlKGxpc3QsIDIzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0NTogcm90YXRlIG1vZGlmaWVkIHRoZSAiICsgdHlwZQorICAgICAgICAgICAgICAgICsgIiBsaXN0IGluY29ycmVjdGx5LCIsICIyMzQ1OTY3ODAxIiwgZ2V0U3RyaW5nKGxpc3QpKTsKKworICAgICAgICAvLyByb3RhdGUgd2l0aCBuZWdhdGl2ZSBkaXN0YW5jZSB0aGF0IGlzIGxhcmdlciB0aGFuIGxpc3Qgc2l6ZQorICAgICAgICBDb2xsZWN0aW9ucy5yb3RhdGUobGlzdCwgLTIzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0Njogcm90YXRlIG1vZGlmaWVkIHRoZSAiICsgdHlwZQorICAgICAgICAgICAgICAgICsgIiBsaXN0IGluY29ycmVjdGx5LCIsICI1OTY3ODAxMjM0IiwgZ2V0U3RyaW5nKGxpc3QpKTsKKworICAgICAgICAvLyByb3RhdGUgd2l0aCAwIGFuZCBlcXVpdmFsZW50IGRpc3RhbmNlcywgdGhpcyBzaG91bGQgbWFrZSBubworICAgICAgICAvLyBtb2RpZmljYXRpb25zIHRvIHRoZSBsaXN0CisgICAgICAgIENvbGxlY3Rpb25zLnJvdGF0ZShsaXN0LCAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0Nzogcm90YXRlIG1vZGlmaWVkIHRoZSAiICsgdHlwZQorICAgICAgICAgICAgICAgICsgIiBsaXN0IGluY29ycmVjdGx5LCIsICI1OTY3ODAxMjM0IiwgZ2V0U3RyaW5nKGxpc3QpKTsKKworICAgICAgICBDb2xsZWN0aW9ucy5yb3RhdGUobGlzdCwgLTMwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0ODogcm90YXRlIG1vZGlmaWVkIHRoZSAiICsgdHlwZQorICAgICAgICAgICAgICAgICsgIiBsaXN0IGluY29ycmVjdGx5LCIsICI1OTY3ODAxMjM0IiwgZ2V0U3RyaW5nKGxpc3QpKTsKKworICAgICAgICBDb2xsZWN0aW9ucy5yb3RhdGUobGlzdCwgMzApOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3Q5OiByb3RhdGUgbW9kaWZpZWQgdGhlICIgKyB0eXBlCisgICAgICAgICAgICAgICAgKyAiIGxpc3QgaW5jb3JyZWN0bHksIiwgIjU5Njc4MDEyMzQiLCBnZXRTdHJpbmcobGlzdCkpOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGdldFN0cmluZyhMaXN0IGxpc3QpIHsKKyAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsaXN0LnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGxpc3QuZ2V0KGkpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI3JvdGF0ZShqYXZhLnV0aWwuTGlzdCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfcm90YXRlMigpIHsKKyAgICAgICAgTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMucm90YXRlKGxpc3QsIDUpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGZvciBlbXB0eSBsaXN0LCAiCisgICAgICAgICAgICAgICAgICAgICsgZSk7CisgICAgICAgIH0KKworICAgICAgICBsaXN0LmFkZCgwLCAiemVybyIpOworICAgICAgICBsaXN0LmFkZCgxLCAib25lIik7CisgICAgICAgIGxpc3QuYWRkKDIsICJ0d28iKTsKKyAgICAgICAgbGlzdC5hZGQoMywgInRocmVlIik7CisgICAgICAgIGxpc3QuYWRkKDQsICJmb3VyIik7CisKKyAgICAgICAgQ29sbGVjdGlvbnMucm90YXRlKGxpc3QsIEludGVnZXIuTUlOX1ZBTFVFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSb3RhdGVkIGluY29ycmVjdGx5IGF0IHBvc2l0aW9uIDAsICIsICJ0aHJlZSIsCisgICAgICAgICAgICAgICAgKFN0cmluZykgbGlzdC5nZXQoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJvdGF0ZWQgaW5jb3JyZWN0bHkgYXQgcG9zaXRpb24gMSwgIiwgImZvdXIiLAorICAgICAgICAgICAgICAgIChTdHJpbmcpIGxpc3QuZ2V0KDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSb3RhdGVkIGluY29ycmVjdGx5IGF0IHBvc2l0aW9uIDIsICIsICJ6ZXJvIiwKKyAgICAgICAgICAgICAgICAoU3RyaW5nKSBsaXN0LmdldCgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUm90YXRlZCBpbmNvcnJlY3RseSBhdCBwb3NpdGlvbiAzLCAiLCAib25lIiwKKyAgICAgICAgICAgICAgICAoU3RyaW5nKSBsaXN0LmdldCgzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUm90YXRlZCBpbmNvcnJlY3RseSBhdCBwb3NpdGlvbiA0LCAiLCAidHdvIiwKKyAgICAgICAgICAgICAgICAoU3RyaW5nKSBsaXN0LmdldCg0KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI2luZGV4T2ZTdWJMaXN0KGphdmEudXRpbC5MaXN0LAorICAgICAqICAgICAgICBqYXZhLnV0aWwuTGlzdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luZGV4T2ZTdWJMaXN0TGphdmFfdXRpbF9MaXN0TGphdmFfdXRpbF9MaXN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGluZGV4T2ZTdWJMaXN0KGphdmEudXRpbC5MaXN0LCBqYXZhLnV0aWwuTGlzdCkKKyAgICAgICAgTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMuaW5kZXhPZlN1Ykxpc3QobnVsbCwgbGlzdCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiBmb3IgbnVsbCBsaXN0IGZpcnN0IHBhcmFtZXRlciIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLmluZGV4T2ZTdWJMaXN0KGxpc3QsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gZm9yIG51bGwgbGlzdCBzZWNvbmQgcGFyYW1ldGVyIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBzdHJpbmcxID0gIkEtQi1DLUQtRS1TLUpGLVNVQi1HLUgtSS1KLVNVQkwtSy1MLUxJU1QtTS1OLS1TLVMtTy1TVUJMSVMtUC1RLVItU1VCTElTVC1TLVQtVS1WLVctWC1ZLVoiOworCisgICAgICAgIHRlc3R3aXRoQ2hhckxpc3QoMSwgc3RyaW5nMSwgIkIiLCB0cnVlKTsKKyAgICAgICAgdGVzdHdpdGhDaGFyTGlzdCgyLCBzdHJpbmcxLCAiTElTVCIsIHRydWUpOworICAgICAgICB0ZXN0d2l0aENoYXJMaXN0KDMsIHN0cmluZzEsICJTVUJMSVNUIiwgdHJ1ZSk7CisgICAgICAgIHRlc3R3aXRoQ2hhckxpc3QoNCwgc3RyaW5nMSwgIk5PTkUiLCB0cnVlKTsKKyAgICAgICAgdGVzdHdpdGhDaGFyTGlzdCg1LCBzdHJpbmcxLCAiRU5EIiwgdHJ1ZSk7CisKKyAgICAgICAgLy8gdGVzdCBib3VuZGFyeSBjb25kaXRpb25zOgorICAgICAgICB0ZXN0d2l0aENoYXJMaXN0KDYsICIiLCAiIiwgdHJ1ZSk7CisgICAgICAgIHRlc3R3aXRoQ2hhckxpc3QoNywgIkxJU1QiLCAiIiwgdHJ1ZSk7CisgICAgICAgIHRlc3R3aXRoQ2hhckxpc3QoOCwgIiIsICJTVUJMSVNUIiwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI2luZGV4T2ZTdWJMaXN0KGphdmEudXRpbC5MaXN0LAorICAgICAqICAgICAgICBqYXZhLnV0aWwuTGlzdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luZGV4T2ZTdWJMaXN0MigpIHsKKyAgICAgICAgQXJyYXlMaXN0IHN1YiA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgc3ViLmFkZChuZXcgSW50ZWdlcigxKSk7CisgICAgICAgIHN1Yi5hZGQobmV3IEludGVnZXIoMikpOworICAgICAgICBzdWIuYWRkKG5ldyBJbnRlZ2VyKDMpKTsKKworICAgICAgICBBcnJheUxpc3Qgc3ViMiA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgc3ViMi5hZGQobmV3IEludGVnZXIoNykpOworICAgICAgICBzdWIyLmFkZChuZXcgSW50ZWdlcig4KSk7CisKKyAgICAgICAgQXJyYXlMaXN0IHNyYyA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgc3JjLmFkZEFsbChzdWIpOworICAgICAgICBzcmMuYWRkQWxsKHN1Yik7CisgICAgICAgIHNyYy5hZGRBbGwoc3ViKTsKKyAgICAgICAgc3JjLmFkZChuZXcgSW50ZWdlcig1KSk7CisgICAgICAgIHNyYy5hZGQobmV3IEludGVnZXIoNikpOworCisgICAgICAgIC8vIHNvIHNyYyBiZWNvbWVzIGEgbGlzdCBsaWtlIHRoaXM6CisgICAgICAgIC8vIFsxLCAyLCAzLCAxLCAyLCAzLCAxLCAyLCAzLCA1LCA2XQorCisgICAgICAgIHN1YiA9IG5ldyBBcnJheUxpc3Qoc3JjLnN1Ykxpc3QoMywgMTEpKTsKKyAgICAgICAgLy8gWzEsIDIsIDMsIDEsIDIsIDMsIDUsIDZdCisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdEEgOiBSZXR1cm5lZCB3cm9uZyBpbmRleE9mU3ViTGlzdCwgIiwgMywgQ29sbGVjdGlvbnMKKyAgICAgICAgICAgICAgICAuaW5kZXhPZlN1Ykxpc3Qoc3JjLCBzdWIpKTsKKworICAgICAgICBzdWIgPSBuZXcgQXJyYXlMaXN0KHNyYy5zdWJMaXN0KDYsIDExKSk7CisgICAgICAgIC8vIFsxLCAyLCAzLCA1LCA2XQorICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3RCIDogUmV0dXJuZWQgd3JvbmcgaW5kZXhPZlN1Ykxpc3QsICIsIDYsIENvbGxlY3Rpb25zCisgICAgICAgICAgICAgICAgLmluZGV4T2ZTdWJMaXN0KHNyYywgc3ViKSk7CisKKyAgICAgICAgc3ViID0gbmV3IEFycmF5TGlzdChzcmMuc3ViTGlzdCgwLCAzKSk7CisgICAgICAgIC8vIFsxLCAyLCAzXQorICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3RDQyA6IFJldHVybmVkIHdyb25nIGluZGV4T2ZTdWJMaXN0LCAiLCAwLCBDb2xsZWN0aW9ucworICAgICAgICAgICAgICAgIC5pbmRleE9mU3ViTGlzdChzcmMsIHN1YikpOworCisgICAgICAgIHN1YiA9IG5ldyBBcnJheUxpc3Qoc3JjLnN1Ykxpc3QoOSwgMTEpKTsKKyAgICAgICAgLy8gWzUsIDZdCisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdEQgOiBSZXR1cm5lZCB3cm9uZyBpbmRleE9mU3ViTGlzdCwgIiwgOSwgQ29sbGVjdGlvbnMKKyAgICAgICAgICAgICAgICAuaW5kZXhPZlN1Ykxpc3Qoc3JjLCBzdWIpKTsKKworICAgICAgICBzdWIgPSBuZXcgQXJyYXlMaXN0KHNyYy5zdWJMaXN0KDEwLCAxMSkpOworICAgICAgICAvLyBbNl0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0RSA6IFJldHVybmVkIHdyb25nIGluZGV4T2ZTdWJMaXN0LCAiLCAxMCwgQ29sbGVjdGlvbnMKKyAgICAgICAgICAgICAgICAuaW5kZXhPZlN1Ykxpc3Qoc3JjLCBzdWIpKTsKKworICAgICAgICBzdWIgPSBuZXcgQXJyYXlMaXN0KHNyYy5zdWJMaXN0KDAsIDExKSk7CisgICAgICAgIC8vIHRoZSB3aG9sZSBsaXN0CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdEggOiBSZXR1cm5lZCB3cm9uZyBpbmRleEluZGV4T2ZTdWJMaXN0LCAiLCAwLAorICAgICAgICAgICAgICAgIENvbGxlY3Rpb25zLmluZGV4T2ZTdWJMaXN0KHNyYywgc3ViKSk7CisKKyAgICAgICAgLy8gYSBub24tbWF0Y2hpbmcgbGlzdAorICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3RJIDogUmV0dXJuZWQgd3JvbmcgaW5kZXhPZlN1Ykxpc3QsICIsIC0xLCBDb2xsZWN0aW9ucworICAgICAgICAgICAgICAgIC5pbmRleE9mU3ViTGlzdChzcmMsIHN1YjIpKTsKKyAgICB9CisKKworICAgIHByaXZhdGUgdm9pZCB0ZXN0d2l0aENoYXJMaXN0KGludCBjb3VudCwgU3RyaW5nIHN0cmluZzEsIFN0cmluZyBzdHJpbmcyLAorICAgICAgICAgICAgYm9vbGVhbiBmaXJzdCkgeworICAgICAgICBjaGFyW10gY2hhcnMgPSBzdHJpbmcxLnRvQ2hhckFycmF5KCk7CisgICAgICAgIExpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaGFycy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbGlzdC5hZGQobmV3IENoYXJhY3RlcihjaGFyc1tpXSkpOworICAgICAgICB9CisgICAgICAgIGNoYXJzID0gc3RyaW5nMi50b0NoYXJBcnJheSgpOworICAgICAgICBMaXN0IHN1Ymxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2hhcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHN1Ymxpc3QuYWRkKG5ldyBDaGFyYWN0ZXIoY2hhcnNbaV0pKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChmaXJzdCkKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAiICsgY291bnQgKyAiOiBSZXR1cm5lZCB3cm9uZyBpbmRleDoiLCBzdHJpbmcxCisgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKHN0cmluZzIpLCBDb2xsZWN0aW9ucworICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZlN1Ykxpc3QobGlzdCwgc3VibGlzdCkpOworICAgICAgICBlbHNlCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgIiArIGNvdW50ICsgIjogUmV0dXJuZWQgd3JvbmcgaW5kZXg6Iiwgc3RyaW5nMQorICAgICAgICAgICAgICAgICAgICAubGFzdEluZGV4T2Yoc3RyaW5nMiksIENvbGxlY3Rpb25zLmxhc3RJbmRleE9mU3ViTGlzdChsaXN0LAorICAgICAgICAgICAgICAgICAgICBzdWJsaXN0KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI2xhc3RJbmRleE9mU3ViTGlzdChqYXZhLnV0aWwuTGlzdCwKKyAgICAgKiAgICAgICAgamF2YS51dGlsLkxpc3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9sYXN0SW5kZXhPZlN1Ykxpc3RMamF2YV91dGlsX0xpc3RMamF2YV91dGlsX0xpc3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgbGFzdEluZGV4T2ZTdWJMaXN0KGphdmEudXRpbC5MaXN0LAorICAgICAgICAvLyBqYXZhLnV0aWwuTGlzdCkKKyAgICAgICAgU3RyaW5nIHN0cmluZzEgPSAiQS1CLUMtRC1FLVMtSkYtU1VCLUctSC1JLUotU1VCTC1LLUwtTElTVC1NLU4tLVMtUy1PLVNVQkxJUy1QLVEtUi1TVUJMSVNULVMtVC1VLVYtVy1YLVktWi1FTkQiOworCisgICAgICAgIExpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLmxhc3RJbmRleE9mU3ViTGlzdChudWxsLCBsaXN0KTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIGZvciBudWxsIGxpc3QgZmlyc3QgcGFyYW1ldGVyIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMubGFzdEluZGV4T2ZTdWJMaXN0KGxpc3QsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gZm9yIG51bGwgbGlzdCBzZWNvbmQgcGFyYW1ldGVyIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRlc3R3aXRoQ2hhckxpc3QoMSwgc3RyaW5nMSwgIkIiLCBmYWxzZSk7CisgICAgICAgIHRlc3R3aXRoQ2hhckxpc3QoMiwgc3RyaW5nMSwgIkxJU1QiLCBmYWxzZSk7CisgICAgICAgIHRlc3R3aXRoQ2hhckxpc3QoMywgc3RyaW5nMSwgIlNVQkxJU1QiLCBmYWxzZSk7CisgICAgICAgIHRlc3R3aXRoQ2hhckxpc3QoNCwgc3RyaW5nMSwgIkVORCIsIGZhbHNlKTsKKyAgICAgICAgdGVzdHdpdGhDaGFyTGlzdCg1LCBzdHJpbmcxLCAiTk9ORSIsIGZhbHNlKTsKKworICAgICAgICAvLyB0ZXN0IGJvdW5kYXJ5IGNvbmRpdGlvbnMKKyAgICAgICAgdGVzdHdpdGhDaGFyTGlzdCg2LCAiIiwgIiIsIGZhbHNlKTsKKyAgICAgICAgdGVzdHdpdGhDaGFyTGlzdCg3LCAiTElTVCIsICIiLCBmYWxzZSk7CisgICAgICAgIHRlc3R3aXRoQ2hhckxpc3QoOCwgIiIsICJTVUJMSVNUIiwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Db2xsZWN0aW9ucyNsYXN0SW5kZXhPZlN1Ykxpc3QoamF2YS51dGlsLkxpc3QsCisgICAgICogICAgICAgIGphdmEudXRpbC5MaXN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGFzdEluZGV4T2ZTdWJMaXN0MigpIHsKKyAgICAgICAgQXJyYXlMaXN0IHN1YiA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgc3ViLmFkZChuZXcgSW50ZWdlcigxKSk7CisgICAgICAgIHN1Yi5hZGQobmV3IEludGVnZXIoMikpOworICAgICAgICBzdWIuYWRkKG5ldyBJbnRlZ2VyKDMpKTsKKworICAgICAgICBBcnJheUxpc3Qgc3ViMiA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgc3ViMi5hZGQobmV3IEludGVnZXIoNykpOworICAgICAgICBzdWIyLmFkZChuZXcgSW50ZWdlcig4KSk7CisKKyAgICAgICAgQXJyYXlMaXN0IHNyYyA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgc3JjLmFkZEFsbChzdWIpOworICAgICAgICBzcmMuYWRkQWxsKHN1Yik7CisgICAgICAgIHNyYy5hZGRBbGwoc3ViKTsKKyAgICAgICAgc3JjLmFkZChuZXcgSW50ZWdlcig1KSk7CisgICAgICAgIHNyYy5hZGQobmV3IEludGVnZXIoNikpOworCisgICAgICAgIC8vIHNvIHNyYyBpcyBhIGxpc3QgbGlrZSB0aGlzOgorICAgICAgICAvLyBbMSwgMiwgMywgMSwgMiwgMywgMSwgMiwgMywgNSwgNl0KKworICAgICAgICBDb2xsZWN0aW9ucy5yZXZlcnNlKHNyYyk7CisgICAgICAgIC8vIGl0IGJlY29tZXMgbGlrZSB0aGlzIDoKKyAgICAgICAgLy8gWzYsIDUsIDMsIDIsIDEsIDMsIDIsIDEsIDMsIDIsIDFdCisKKyAgICAgICAgc3ViID0gbmV3IEFycmF5TGlzdChzcmMuc3ViTGlzdCgwLCA4KSk7CisgICAgICAgIC8vIFs2LCA1LCAzLCAyLCAxLCAzLCAyLCAxXQorICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3RBIDogUmV0dXJuZWQgd3JvbmcgbGFzdEluZGV4T2ZTdWJMaXN0LCAiLCAwLAorICAgICAgICAgICAgICAgIENvbGxlY3Rpb25zLmxhc3RJbmRleE9mU3ViTGlzdChzcmMsIHN1YikpOworCisgICAgICAgIHN1YiA9IG5ldyBBcnJheUxpc3Qoc3JjLnN1Ykxpc3QoMCwgNSkpOworICAgICAgICAvLyBbNiwgNSwgMywgMiwgMV0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0QiA6IFJldHVybmVkIHdyb25nIGxhc3RJbmRleE9mU3ViTGlzdCwgIiwgMCwKKyAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy5sYXN0SW5kZXhPZlN1Ykxpc3Qoc3JjLCBzdWIpKTsKKworICAgICAgICBzdWIgPSBuZXcgQXJyYXlMaXN0KHNyYy5zdWJMaXN0KDIsIDUpKTsKKyAgICAgICAgLy8gWzMsIDIsIDFdCisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdEMgOiBSZXR1cm5lZCB3cm9uZyBsYXN0SW5kZXhPZlN1Ykxpc3QsICIsIDgsCisgICAgICAgICAgICAgICAgQ29sbGVjdGlvbnMubGFzdEluZGV4T2ZTdWJMaXN0KHNyYywgc3ViKSk7CisKKyAgICAgICAgc3ViID0gbmV3IEFycmF5TGlzdChzcmMuc3ViTGlzdCg5LCAxMSkpOworICAgICAgICAvLyBbMiwgMV0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0RCA6IFJldHVybmVkIHdyb25nIGxhc3RJbmRleE9mU3ViTGlzdCwgIiwgOSwKKyAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy5sYXN0SW5kZXhPZlN1Ykxpc3Qoc3JjLCBzdWIpKTsKKworICAgICAgICBzdWIgPSBuZXcgQXJyYXlMaXN0KHNyYy5zdWJMaXN0KDEwLCAxMSkpOworICAgICAgICAvLyBbMV0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0RSA6IFJldHVybmVkIHdyb25nIGxhc3RJbmRleE9mU3ViTGlzdCwgIiwgMTAsCisgICAgICAgICAgICAgICAgQ29sbGVjdGlvbnMubGFzdEluZGV4T2ZTdWJMaXN0KHNyYywgc3ViKSk7CisKKyAgICAgICAgc3ViID0gbmV3IEFycmF5TGlzdChzcmMuc3ViTGlzdCgwLCAyKSk7CisgICAgICAgIC8vIFs2LCA1XQorICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3RGIDogUmV0dXJuZWQgd3JvbmcgbGFzdEluZGV4T2ZTdWJMaXN0LCAiLCAwLAorICAgICAgICAgICAgICAgIENvbGxlY3Rpb25zLmxhc3RJbmRleE9mU3ViTGlzdChzcmMsIHN1YikpOworCisgICAgICAgIHN1YiA9IG5ldyBBcnJheUxpc3Qoc3JjLnN1Ykxpc3QoMCwgMSkpOworICAgICAgICAvLyBbNl0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0RyA6IFJldHVybmVkIHdyb25nIGxhc3RJbmRleE9mU3ViTGlzdCwgIiwgMCwKKyAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy5sYXN0SW5kZXhPZlN1Ykxpc3Qoc3JjLCBzdWIpKTsKKworICAgICAgICBzdWIgPSBuZXcgQXJyYXlMaXN0KHNyYy5zdWJMaXN0KDAsIDExKSk7CisgICAgICAgIC8vIHRoZSB3aG9sZSBsaXN0CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdEggOiBSZXR1cm5lZCB3cm9uZyBsYXN0SW5kZXhPZlN1Ykxpc3QsICIsIDAsCisgICAgICAgICAgICAgICAgQ29sbGVjdGlvbnMubGFzdEluZGV4T2ZTdWJMaXN0KHNyYywgc3ViKSk7CisKKyAgICAgICAgLy8gYSBub24tbWF0Y2hpbmcgbGlzdAorICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3RJIDogUmV0dXJuZWQgd3JvbmcgbGFzdEluZGV4T2ZTdWJMaXN0LCAiLCAtMSwKKyAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy5sYXN0SW5kZXhPZlN1Ykxpc3Qoc3JjLCBzdWIyKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI2xpc3QoamF2YS51dGlsLkVudW1lcmF0aW9uKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGlzdExqYXZhX3V0aWxfRW51bWVyYXRpb24oKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuQXJyYXlMaXN0IGxpc3QoamF2YS51dGlsLkVudW1lcmF0aW9uKQorCisgICAgICAgIEVudW1lcmF0aW9uIGUgPSBDb2xsZWN0aW9ucy5lbnVtZXJhdGlvbihsbCk7CisgICAgICAgIEFycmF5TGlzdCBhbCA9IENvbGxlY3Rpb25zLmxpc3QoZSk7CisKKyAgICAgICAgaW50IHNpemUgPSBhbC5zaXplKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIGxsLnNpemUoKSwgc2l6ZSk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygid3JvbmcgZWxlbWVudCBhdCBwb3NpdGlvbiAiICsgaSArICIsIiwgbGwuZ2V0KGkpLCBhbAorICAgICAgICAgICAgICAgICAgICAuZ2V0KGkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Db2xsZWN0aW9ucyNzeW5jaHJvbml6ZWRDb2xsZWN0aW9uKGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3luY2hyb25pemVkQ29sbGVjdGlvbkxqYXZhX3V0aWxfQ29sbGVjdGlvbigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5Db2xsZWN0aW9uCisgICAgICAgIC8vIGphdmEudXRpbC5Db2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRDb2xsZWN0aW9uKGphdmEudXRpbC5Db2xsZWN0aW9uKQorCisgICAgICAgIExpbmtlZExpc3Qgc21hbGxMaXN0ID0gbmV3IExpbmtlZExpc3QoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA1MDsgaSsrKSB7CisgICAgICAgICAgICBzbWFsbExpc3QuYWRkKG9iakFycmF5W2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGludCBudW1iZXJPZkxvb3BzID0gMjAwOworICAgICAgICBDb2xsZWN0aW9uIHN5bmNoQ29sID0gQ29sbGVjdGlvbnMuc3luY2hyb25pemVkQ29sbGVjdGlvbihzbWFsbExpc3QpOworICAgICAgICAvLyBSZXBsYWNpbmcgdGhlIHByZXZpb3VzIGxpbmUgd2l0aCB0aGUgbGluZSBiZWxvdyAqc2hvdWxkKiBjYXVzZSB0aGUKKyAgICAgICAgLy8gdGVzdCB0byBmYWlsLS10aGUgY29sbGVjaW9uIGJlbG93IGlzbid0IHN5bmNocm9uaXplZAorICAgICAgICAvLyBDb2xsZWN0aW9uIHN5bmNoQ29sID0gc21hbGxMaXN0OworCisgICAgICAgIFN5bmNoQ29sbGVjdGlvbkNoZWNrZXIgbm9ybWFsU3luY2hDaGVja2VyID0gbmV3IFN5bmNoQ29sbGVjdGlvbkNoZWNrZXIoCisgICAgICAgICAgICAgICAgc3luY2hDb2wsIGZhbHNlLCBudW1iZXJPZkxvb3BzKTsKKyAgICAgICAgU3luY2hDb2xsZWN0aW9uQ2hlY2tlciBvZmZzZXRTeW5jaENoZWNrZXIgPSBuZXcgU3luY2hDb2xsZWN0aW9uQ2hlY2tlcigKKyAgICAgICAgICAgICAgICBzeW5jaENvbCwgdHJ1ZSwgbnVtYmVyT2ZMb29wcyk7CisgICAgICAgIFRocmVhZCBub3JtYWxUaHJlYWQgPSBuZXcgVGhyZWFkKG5vcm1hbFN5bmNoQ2hlY2tlcik7CisgICAgICAgIFRocmVhZCBvZmZzZXRUaHJlYWQgPSBuZXcgVGhyZWFkKG9mZnNldFN5bmNoQ2hlY2tlcik7CisgICAgICAgIG5vcm1hbFRocmVhZC5zdGFydCgpOworICAgICAgICBvZmZzZXRUaHJlYWQuc3RhcnQoKTsKKyAgICAgICAgd2hpbGUgKChub3JtYWxTeW5jaENoZWNrZXIuZ2V0TnVtYmVyT2ZDaGVja3MoKSA8IG51bWJlck9mTG9vcHMpCisgICAgICAgICAgICAgICAgfHwgKG9mZnNldFN5bmNoQ2hlY2tlci5nZXROdW1iZXJPZkNoZWNrcygpIDwgbnVtYmVyT2ZMb29wcykpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBjb2xsZWN0aW9uIGNvcnJ1cHRlZCBieSBtdWx0aXBsZSB0aHJlYWQgYWNjZXNzIiwKKyAgICAgICAgICAgICAgICBub3JtYWxTeW5jaENoZWNrZXIuZ2V0UmVzdWx0KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIG9mZnNldFN5bmNoQ2hlY2tlci5nZXRSZXN1bHQoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBub3JtYWxUaHJlYWQuam9pbig1MDAwKTsKKyAgICAgICAgICAgIG9mZnNldFRocmVhZC5qb2luKDUwMDApOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJqb2luKCkgaW50ZXJydXB0ZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIHN5bmNoQ29sLmFkZChudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVHJ5aW5nIHRvIHVzZSBudWxscyBpbiBjb2xsZWN0aW9uIGZhaWxlZCIsIHN5bmNoQ29sCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKG51bGwpKTsKKworICAgICAgICBzbWFsbExpc3QgPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKSB7CisgICAgICAgICAgICBzbWFsbExpc3QuYWRkKG9iakFycmF5W2ldKTsKKyAgICAgICAgfQorICAgICAgICBuZXcgU3VwcG9ydF9Db2xsZWN0aW9uVGVzdCgiIiwgQ29sbGVjdGlvbnMKKyAgICAgICAgICAgICAgICAuc3luY2hyb25pemVkQ29sbGVjdGlvbihzbWFsbExpc3QpKS5ydW5UZXN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI3N5bmNocm9uaXplZExpc3QoamF2YS51dGlsLkxpc3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zeW5jaHJvbml6ZWRMaXN0TGphdmFfdXRpbF9MaXN0KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbnMuc3luY2hyb25pemVkTGlzdChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIGZvciBudWxsIGxpc3QgcGFyYW1ldGVyIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3Qgd2l0aCBhIFNlcXVlbnRpYWwgQWNjZXNzIExpc3QKKyAgICAgICAgTGlzdCBzbWFsbExpc3QgPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICB0ZXN0U3luY2hyb25pemVkTGlzdChzbWFsbExpc3QsICJTZXF1ZW50aWFsIEFjY2VzcyIpOworCisgICAgICAgIHNtYWxsTGlzdCA9IG5ldyBMaW5rZWRMaXN0KCk7CisgICAgICAgIExpc3QgbXlMaXN0OworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKSB7CisgICAgICAgICAgICBzbWFsbExpc3QuYWRkKG9iakFycmF5W2ldKTsKKyAgICAgICAgfQorICAgICAgICBteUxpc3QgPSBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRMaXN0KHNtYWxsTGlzdCk7CisgICAgICAgIG5ldyBTdXBwb3J0X0xpc3RUZXN0KCIiLCBteUxpc3QpLnJ1blRlc3QoKTsKKworICAgICAgICAvLyB0ZXN0IHdpdGggYSBSYW5kb20gQWNjZXNzIExpc3QKKyAgICAgICAgc21hbGxMaXN0ID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICB0ZXN0U3luY2hyb25pemVkTGlzdChzbWFsbExpc3QsICJSYW5kb20gQWNjZXNzIik7CisKKyAgICAgICAgc21hbGxMaXN0ID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKSB7CisgICAgICAgICAgICBzbWFsbExpc3QuYWRkKG9iakFycmF5W2ldKTsKKyAgICAgICAgfQorICAgICAgICBteUxpc3QgPSBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRMaXN0KHNtYWxsTGlzdCk7CisgICAgICAgIG5ldyBTdXBwb3J0X0xpc3RUZXN0KCIiLCBteUxpc3QpLnJ1blRlc3QoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdFN5bmNocm9uaXplZExpc3QoTGlzdCBzbWFsbExpc3QsIFN0cmluZyB0eXBlKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNTA7IGkrKykgeworICAgICAgICAgICAgc21hbGxMaXN0LmFkZChvYmpBcnJheVtpXSk7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgaW50IG51bWJlck9mTG9vcHMgPSAyMDA7CisgICAgICAgIExpc3Qgc3luY2hMaXN0ID0gQ29sbGVjdGlvbnMuc3luY2hyb25pemVkTGlzdChzbWFsbExpc3QpOworICAgICAgICBpZiAodHlwZS5lcXVhbHMoIlJhbmRvbSBBY2Nlc3MiKSkKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJSZXR1cm5lZCBzeW5jaHJvbml6ZWQgbGlzdCBzaG91bGQgaW1wbGVtZW50IHRoZSBSYW5kb20gQWNjZXNzIGludGVyZmFjZSIsCisgICAgICAgICAgICAgICAgICAgIHN5bmNoTGlzdCBpbnN0YW5jZW9mIFJhbmRvbUFjY2Vzcyk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJSZXR1cm5lZCBzeW5jaHJvbml6ZWQgbGlzdCBzaG91bGQgbm90IGltcGxlbWVudCB0aGUgUmFuZG9tIEFjY2VzcyBpbnRlcmZhY2UiLAorICAgICAgICAgICAgICAgICAgICAhKHN5bmNoTGlzdCBpbnN0YW5jZW9mIFJhbmRvbUFjY2VzcykpOworCisgICAgICAgIC8vIFJlcGxhY2luZyB0aGUgcHJldmlvdXMgbGluZSB3aXRoIHRoZSBsaW5lIGJlbG93ICpzaG91bGQqIGNhdXNlIHRoZQorICAgICAgICAvLyB0ZXN0IHRvIGZhaWwtLXRoZSBsaXN0IGJlbG93IGlzbid0IHN5bmNocm9uaXplZAorICAgICAgICAvLyBMaXN0IHN5bmNoTGlzdCA9IHNtYWxsTGlzdDsKKyAgICAgICAgU3luY2hDb2xsZWN0aW9uQ2hlY2tlciBub3JtYWxTeW5jaENoZWNrZXIgPSBuZXcgU3luY2hDb2xsZWN0aW9uQ2hlY2tlcigKKyAgICAgICAgICAgICAgICBzeW5jaExpc3QsIGZhbHNlLCBudW1iZXJPZkxvb3BzKTsKKyAgICAgICAgU3luY2hDb2xsZWN0aW9uQ2hlY2tlciBvZmZzZXRTeW5jaENoZWNrZXIgPSBuZXcgU3luY2hDb2xsZWN0aW9uQ2hlY2tlcigKKyAgICAgICAgICAgICAgICBzeW5jaExpc3QsIHRydWUsIG51bWJlck9mTG9vcHMpOworICAgICAgICBUaHJlYWQgbm9ybWFsVGhyZWFkID0gbmV3IFRocmVhZChub3JtYWxTeW5jaENoZWNrZXIpOworICAgICAgICBUaHJlYWQgb2Zmc2V0VGhyZWFkID0gbmV3IFRocmVhZChvZmZzZXRTeW5jaENoZWNrZXIpOworICAgICAgICBub3JtYWxUaHJlYWQuc3RhcnQoKTsKKyAgICAgICAgb2Zmc2V0VGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIHdoaWxlICgobm9ybWFsU3luY2hDaGVja2VyLmdldE51bWJlck9mQ2hlY2tzKCkgPCBudW1iZXJPZkxvb3BzKQorICAgICAgICAgICAgICAgIHx8IChvZmZzZXRTeW5jaENoZWNrZXIuZ2V0TnVtYmVyT2ZDaGVja3MoKSA8IG51bWJlck9mTG9vcHMpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxMCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICB0eXBlCisgICAgICAgICAgICAgICAgICAgICAgICArICIgbGlzdCB0ZXN0czogUmV0dXJuZWQgbGlzdCBjb3JydXB0ZWQgYnkgbXVsdGlwbGUgdGhyZWFkIGFjY2VzcyIsCisgICAgICAgICAgICAgICAgbm9ybWFsU3luY2hDaGVja2VyLmdldFJlc3VsdCgpCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBvZmZzZXRTeW5jaENoZWNrZXIuZ2V0UmVzdWx0KCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbm9ybWFsVGhyZWFkLmpvaW4oNTAwMCk7CisgICAgICAgICAgICBvZmZzZXRUaHJlYWQuam9pbig1MDAwKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCh0eXBlICsgIiBsaXN0IHRlc3RzOiBqb2luKCkgaW50ZXJydXB0ZWQiKTsKKyAgICAgICAgfQorICAgICAgICBzeW5jaExpc3Quc2V0KDI1LCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh0eXBlICsgIiBsaXN0IHRlc3RzOiBUcnlpbmcgdG8gdXNlIG51bGxzIGluIGxpc3QgZmFpbGVkIiwKKyAgICAgICAgICAgICAgICBzeW5jaExpc3QuZ2V0KDI1KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI3N5bmNocm9uaXplZE1hcChqYXZhLnV0aWwuTWFwKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3luY2hyb25pemVkTWFwTGphdmFfdXRpbF9NYXAoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuTWFwCisgICAgICAgIC8vIGphdmEudXRpbC5Db2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRNYXAoamF2YS51dGlsLk1hcCkKKyAgICAgICAgSGFzaE1hcCBzbWFsbE1hcCA9IG5ldyBIYXNoTWFwKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNTA7IGkrKykgeworICAgICAgICAgICAgc21hbGxNYXAucHV0KG9iakFycmF5W2ldLCBvYmpBcnJheVtpXSk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBpbnQgbnVtYmVyT2ZMb29wcyA9IDIwMDsKKyAgICAgICAgTWFwIHN5bmNoTWFwID0gQ29sbGVjdGlvbnMuc3luY2hyb25pemVkTWFwKHNtYWxsTWFwKTsKKyAgICAgICAgLy8gUmVwbGFjaW5nIHRoZSBwcmV2aW91cyBsaW5lIHdpdGggdGhlIGxpbmUgYmVsb3cgc2hvdWxkIGNhdXNlIHRoZSB0ZXN0CisgICAgICAgIC8vIHRvIGZhaWwtLXRoZSBsaXN0IGJlbG93IGlzbid0IHN5bmNocm9uaXplZAorICAgICAgICAvLyBNYXAgc3luY2hNYXAgPSBzbWFsbE1hcDsKKworICAgICAgICBTeW5jaE1hcENoZWNrZXIgbm9ybWFsU3luY2hDaGVja2VyID0gbmV3IFN5bmNoTWFwQ2hlY2tlcihzeW5jaE1hcCwKKyAgICAgICAgICAgICAgICBmYWxzZSwgbnVtYmVyT2ZMb29wcyk7CisgICAgICAgIFN5bmNoTWFwQ2hlY2tlciBvZmZzZXRTeW5jaENoZWNrZXIgPSBuZXcgU3luY2hNYXBDaGVja2VyKHN5bmNoTWFwLAorICAgICAgICAgICAgICAgIHRydWUsIG51bWJlck9mTG9vcHMpOworICAgICAgICBUaHJlYWQgbm9ybWFsVGhyZWFkID0gbmV3IFRocmVhZChub3JtYWxTeW5jaENoZWNrZXIpOworICAgICAgICBUaHJlYWQgb2Zmc2V0VGhyZWFkID0gbmV3IFRocmVhZChvZmZzZXRTeW5jaENoZWNrZXIpOworICAgICAgICBub3JtYWxUaHJlYWQuc3RhcnQoKTsKKyAgICAgICAgb2Zmc2V0VGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIHdoaWxlICgobm9ybWFsU3luY2hDaGVja2VyLmdldE51bWJlck9mQ2hlY2tzKCkgPCBudW1iZXJPZkxvb3BzKQorICAgICAgICAgICAgICAgIHx8IChvZmZzZXRTeW5jaENoZWNrZXIuZ2V0TnVtYmVyT2ZDaGVja3MoKSA8IG51bWJlck9mTG9vcHMpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxMCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgbWFwIGNvcnJ1cHRlZCBieSBtdWx0aXBsZSB0aHJlYWQgYWNjZXNzIiwKKyAgICAgICAgICAgICAgICBub3JtYWxTeW5jaENoZWNrZXIuZ2V0UmVzdWx0KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIG9mZnNldFN5bmNoQ2hlY2tlci5nZXRSZXN1bHQoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBub3JtYWxUaHJlYWQuam9pbig1MDAwKTsKKyAgICAgICAgICAgIG9mZnNldFRocmVhZC5qb2luKDUwMDApOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJqb2luKCkgaW50ZXJydXB0ZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHN5bmNocm9uaXplZCBtYXAgZG9lcyBub3QgaGF2ZSB0byBwZXJtaXQgbnVsbCBrZXlzIG9yIHZhbHVlcworICAgICAgICBzeW5jaE1hcC5wdXQobmV3IExvbmcoMjUpLCBudWxsKTsKKyAgICAgICAgc3luY2hNYXAucHV0KG51bGwsIG5ldyBMb25nKDMwKSk7CisgICAgICAgIGFzc2VydE51bGwoIlRyeWluZyB0byB1c2UgYSBudWxsIHZhbHVlIGluIG1hcCBmYWlsZWQiLCBzeW5jaE1hcAorICAgICAgICAgICAgICAgIC5nZXQobmV3IExvbmcoMjUpKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRyeWluZyB0byB1c2UgYSBudWxsIGtleSBpbiBtYXAgZmFpbGVkIiwgc3luY2hNYXAuZ2V0KG51bGwpCisgICAgICAgICAgICAgICAgLmVxdWFscyhuZXcgTG9uZygzMCkpKTsKKworICAgICAgICBzbWFsbE1hcCA9IG5ldyBIYXNoTWFwKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspIHsKKyAgICAgICAgICAgIHNtYWxsTWFwLnB1dChvYmpBcnJheVtpXS50b1N0cmluZygpLCBvYmpBcnJheVtpXSk7CisgICAgICAgIH0KKyAgICAgICAgc3luY2hNYXAgPSBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRNYXAoc21hbGxNYXApOworICAgICAgICBuZXcgU3VwcG9ydF9Vbm1vZGlmaWFibGVNYXBUZXN0KCIiLCBzeW5jaE1hcCkucnVuVGVzdCgpOworICAgICAgICBzeW5jaE1hcC5rZXlTZXQoKS5yZW1vdmUob2JqQXJyYXlbNTBdLnRvU3RyaW5nKCkpOworICAgICAgICBhc3NlcnROdWxsKAorICAgICAgICAgICAgICAgICJSZW1vdmluZyBhIGtleSBmcm9tIHRoZSBrZXlTZXQgb2YgdGhlIHN5bmNocm9uaXplZCBtYXAgZGlkIG5vdCByZW1vdmUgaXQgZnJvbSB0aGUgc3luY2hyb25pemVkIG1hcDogIiwKKyAgICAgICAgICAgICAgICBzeW5jaE1hcC5nZXQob2JqQXJyYXlbNTBdLnRvU3RyaW5nKCkpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgKKyAgICAgICAgICAgICAgICAiUmVtb3ZpbmcgYSBrZXkgZnJvbSB0aGUga2V5U2V0IG9mIHRoZSBzeW5jaHJvbml6ZWQgbWFwIGRpZCBub3QgcmVtb3ZlIGl0IGZyb20gdGhlIG9yaWdpbmFsIG1hcCIsCisgICAgICAgICAgICAgICAgc21hbGxNYXAuZ2V0KG9iakFycmF5WzUwXS50b1N0cmluZygpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI3N5bmNocm9uaXplZFNldChqYXZhLnV0aWwuU2V0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3luY2hyb25pemVkU2V0TGphdmFfdXRpbF9TZXQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuU2V0CisgICAgICAgIC8vIGphdmEudXRpbC5Db2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRTZXQoamF2YS51dGlsLlNldCkKKyAgICAgICAgSGFzaFNldCBzbWFsbFNldCA9IG5ldyBIYXNoU2V0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNTA7IGkrKykgeworICAgICAgICAgICAgc21hbGxTZXQuYWRkKG9iakFycmF5W2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGludCBudW1iZXJPZkxvb3BzID0gMjAwOworICAgICAgICBTZXQgc3luY2hTZXQgPSBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRTZXQoc21hbGxTZXQpOworICAgICAgICAvLyBSZXBsYWNpbmcgdGhlIHByZXZpb3VzIGxpbmUgd2l0aCB0aGUgbGluZSBiZWxvdyBzaG91bGQgY2F1c2UgdGhlIHRlc3QKKyAgICAgICAgLy8gdG8gZmFpbC0tdGhlIHNldCBiZWxvdyBpc24ndCBzeW5jaHJvbml6ZWQKKyAgICAgICAgLy8gU2V0IHN5bmNoU2V0ID0gc21hbGxTZXQ7CisKKyAgICAgICAgU3luY2hDb2xsZWN0aW9uQ2hlY2tlciBub3JtYWxTeW5jaENoZWNrZXIgPSBuZXcgU3luY2hDb2xsZWN0aW9uQ2hlY2tlcigKKyAgICAgICAgICAgICAgICBzeW5jaFNldCwgZmFsc2UsIG51bWJlck9mTG9vcHMpOworICAgICAgICBTeW5jaENvbGxlY3Rpb25DaGVja2VyIG9mZnNldFN5bmNoQ2hlY2tlciA9IG5ldyBTeW5jaENvbGxlY3Rpb25DaGVja2VyKAorICAgICAgICAgICAgICAgIHN5bmNoU2V0LCB0cnVlLCBudW1iZXJPZkxvb3BzKTsKKyAgICAgICAgVGhyZWFkIG5vcm1hbFRocmVhZCA9IG5ldyBUaHJlYWQobm9ybWFsU3luY2hDaGVja2VyKTsKKyAgICAgICAgVGhyZWFkIG9mZnNldFRocmVhZCA9IG5ldyBUaHJlYWQob2Zmc2V0U3luY2hDaGVja2VyKTsKKyAgICAgICAgbm9ybWFsVGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIG9mZnNldFRocmVhZC5zdGFydCgpOworICAgICAgICB3aGlsZSAoKG5vcm1hbFN5bmNoQ2hlY2tlci5nZXROdW1iZXJPZkNoZWNrcygpIDwgbnVtYmVyT2ZMb29wcykKKyAgICAgICAgICAgICAgICB8fCAob2Zmc2V0U3luY2hDaGVja2VyLmdldE51bWJlck9mQ2hlY2tzKCkgPCBudW1iZXJPZkxvb3BzKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTApOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHNldCBjb3JydXB0ZWQgYnkgbXVsdGlwbGUgdGhyZWFkIGFjY2VzcyIsCisgICAgICAgICAgICAgICAgbm9ybWFsU3luY2hDaGVja2VyLmdldFJlc3VsdCgpCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBvZmZzZXRTeW5jaENoZWNrZXIuZ2V0UmVzdWx0KCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbm9ybWFsVGhyZWFkLmpvaW4oNTAwMCk7CisgICAgICAgICAgICBvZmZzZXRUaHJlYWQuam9pbig1MDAwKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiam9pbigpIGludGVycnVwdGVkIik7CisgICAgICAgIH0KKworICAgICAgICBTZXQgbXlTZXQgPSBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRTZXQoc21hbGxTZXQpOworICAgICAgICBteVNldC5hZGQobnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoIlRyeWluZyB0byB1c2UgbnVsbHMgaW4gbGlzdCBmYWlsZWQiLCBteVNldC5jb250YWlucyhudWxsKSk7CisKKyAgICAgICAgc21hbGxTZXQgPSBuZXcgSGFzaFNldCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKSB7CisgICAgICAgICAgICBzbWFsbFNldC5hZGQob2JqQXJyYXlbaV0pOworICAgICAgICB9CisgICAgICAgIG5ldyBTdXBwb3J0X1NldFRlc3QoIiIsIENvbGxlY3Rpb25zLnN5bmNocm9uaXplZFNldChzbWFsbFNldCkpCisgICAgICAgICAgICAgICAgLnJ1blRlc3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjc3luY2hyb25pemVkU29ydGVkTWFwKGphdmEudXRpbC5Tb3J0ZWRNYXApCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zeW5jaHJvbml6ZWRTb3J0ZWRNYXBMamF2YV91dGlsX1NvcnRlZE1hcCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5Tb3J0ZWRNYXAKKyAgICAgICAgLy8gamF2YS51dGlsLkNvbGxlY3Rpb25zLnN5bmNocm9uaXplZFNvcnRlZE1hcChqYXZhLnV0aWwuU29ydGVkTWFwKQorICAgICAgICBUcmVlTWFwIHNtYWxsTWFwID0gbmV3IFRyZWVNYXAoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA1MDsgaSsrKSB7CisgICAgICAgICAgICBzbWFsbE1hcC5wdXQob2JqQXJyYXlbaV0sIG9iakFycmF5W2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGludCBudW1iZXJPZkxvb3BzID0gMjAwOworICAgICAgICBNYXAgc3luY2hNYXAgPSBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRNYXAoc21hbGxNYXApOworICAgICAgICAvLyBSZXBsYWNpbmcgdGhlIHByZXZpb3VzIGxpbmUgd2l0aCB0aGUgbGluZSBiZWxvdyBzaG91bGQgY2F1c2UgdGhlIHRlc3QKKyAgICAgICAgLy8gdG8gZmFpbC0tdGhlIGxpc3QgYmVsb3cgaXNuJ3Qgc3luY2hyb25pemVkCisgICAgICAgIC8vIE1hcCBzeW5jaE1hcCA9IHNtYWxsTWFwOworCisgICAgICAgIFN5bmNoTWFwQ2hlY2tlciBub3JtYWxTeW5jaENoZWNrZXIgPSBuZXcgU3luY2hNYXBDaGVja2VyKHN5bmNoTWFwLAorICAgICAgICAgICAgICAgIGZhbHNlLCBudW1iZXJPZkxvb3BzKTsKKyAgICAgICAgU3luY2hNYXBDaGVja2VyIG9mZnNldFN5bmNoQ2hlY2tlciA9IG5ldyBTeW5jaE1hcENoZWNrZXIoc3luY2hNYXAsCisgICAgICAgICAgICAgICAgdHJ1ZSwgbnVtYmVyT2ZMb29wcyk7CisgICAgICAgIFRocmVhZCBub3JtYWxUaHJlYWQgPSBuZXcgVGhyZWFkKG5vcm1hbFN5bmNoQ2hlY2tlcik7CisgICAgICAgIFRocmVhZCBvZmZzZXRUaHJlYWQgPSBuZXcgVGhyZWFkKG9mZnNldFN5bmNoQ2hlY2tlcik7CisgICAgICAgIG5vcm1hbFRocmVhZC5zdGFydCgpOworICAgICAgICBvZmZzZXRUaHJlYWQuc3RhcnQoKTsKKyAgICAgICAgd2hpbGUgKChub3JtYWxTeW5jaENoZWNrZXIuZ2V0TnVtYmVyT2ZDaGVja3MoKSA8IG51bWJlck9mTG9vcHMpCisgICAgICAgICAgICAgICAgfHwgKG9mZnNldFN5bmNoQ2hlY2tlci5nZXROdW1iZXJPZkNoZWNrcygpIDwgbnVtYmVyT2ZMb29wcykpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBtYXAgY29ycnVwdGVkIGJ5IG11bHRpcGxlIHRocmVhZCBhY2Nlc3MiLAorICAgICAgICAgICAgICAgIG5vcm1hbFN5bmNoQ2hlY2tlci5nZXRSZXN1bHQoKQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgb2Zmc2V0U3luY2hDaGVja2VyLmdldFJlc3VsdCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5vcm1hbFRocmVhZC5qb2luKDUwMDApOworICAgICAgICAgICAgb2Zmc2V0VGhyZWFkLmpvaW4oNTAwMCk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoImpvaW4oKSBpbnRlcnJ1cHRlZCIpOworICAgICAgICB9CisKKyAgICAgICAgc21hbGxNYXAgPSBuZXcgVHJlZU1hcCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKSB7CisgICAgICAgICAgICBzbWFsbE1hcC5wdXQob2JqQXJyYXlbaV0udG9TdHJpbmcoKSwgb2JqQXJyYXlbaV0pOworICAgICAgICB9CisgICAgICAgIHN5bmNoTWFwID0gQ29sbGVjdGlvbnMuc3luY2hyb25pemVkU29ydGVkTWFwKHNtYWxsTWFwKTsKKyAgICAgICAgbmV3IFN1cHBvcnRfVW5tb2RpZmlhYmxlTWFwVGVzdCgiIiwgc3luY2hNYXApLnJ1blRlc3QoKTsKKyAgICAgICAgc3luY2hNYXAua2V5U2V0KCkucmVtb3ZlKG9iakFycmF5WzUwXS50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgKKyAgICAgICAgICAgICAgICAiUmVtb3ZpbmcgYSBrZXkgZnJvbSB0aGUga2V5U2V0IG9mIHRoZSBzeW5jaHJvbml6ZWQgbWFwIGRpZCBub3QgcmVtb3ZlIGl0IGZyb20gdGhlIHN5bmNocm9uaXplZCBtYXAiLAorICAgICAgICAgICAgICAgIHN5bmNoTWFwLmdldChvYmpBcnJheVs1MF0udG9TdHJpbmcoKSkpOworICAgICAgICBhc3NlcnROdWxsKAorICAgICAgICAgICAgICAgICJSZW1vdmluZyBhIGtleSBmcm9tIHRoZSBrZXlTZXQgb2YgdGhlIHN5bmNocm9uaXplZCBtYXAgZGlkIG5vdCByZW1vdmUgaXQgZnJvbSB0aGUgb3JpZ2luYWwgbWFwIiwKKyAgICAgICAgICAgICAgICBzbWFsbE1hcC5nZXQob2JqQXJyYXlbNTBdLnRvU3RyaW5nKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjc3luY2hyb25pemVkU29ydGVkU2V0KGphdmEudXRpbC5Tb3J0ZWRTZXQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zeW5jaHJvbml6ZWRTb3J0ZWRTZXRMamF2YV91dGlsX1NvcnRlZFNldCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5Tb3J0ZWRTZXQKKyAgICAgICAgLy8gamF2YS51dGlsLkNvbGxlY3Rpb25zLnN5bmNocm9uaXplZFNvcnRlZFNldChqYXZhLnV0aWwuU29ydGVkU2V0KQorICAgICAgICBUcmVlU2V0IHNtYWxsU2V0ID0gbmV3IFRyZWVTZXQoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA1MDsgaSsrKSB7CisgICAgICAgICAgICBzbWFsbFNldC5hZGQob2JqQXJyYXlbaV0pOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgaW50IG51bWJlck9mTG9vcHMgPSAyMDA7CisgICAgICAgIFNldCBzeW5jaFNldCA9IENvbGxlY3Rpb25zLnN5bmNocm9uaXplZFNldChzbWFsbFNldCk7CisgICAgICAgIC8vIFJlcGxhY2luZyB0aGUgcHJldmlvdXMgbGluZSB3aXRoIHRoZSBsaW5lIGJlbG93IHNob3VsZCBjYXVzZSB0aGUgdGVzdAorICAgICAgICAvLyB0byBmYWlsLS10aGUgbGlzdCBiZWxvdyBpc24ndCBzeW5jaHJvbml6ZWQKKyAgICAgICAgLy8gU2V0IHN5bmNoU2V0ID0gc21hbGxTZXQ7CisKKyAgICAgICAgU3luY2hDb2xsZWN0aW9uQ2hlY2tlciBub3JtYWxTeW5jaENoZWNrZXIgPSBuZXcgU3luY2hDb2xsZWN0aW9uQ2hlY2tlcigKKyAgICAgICAgICAgICAgICBzeW5jaFNldCwgZmFsc2UsIG51bWJlck9mTG9vcHMpOworICAgICAgICBTeW5jaENvbGxlY3Rpb25DaGVja2VyIG9mZnNldFN5bmNoQ2hlY2tlciA9IG5ldyBTeW5jaENvbGxlY3Rpb25DaGVja2VyKAorICAgICAgICAgICAgICAgIHN5bmNoU2V0LCB0cnVlLCBudW1iZXJPZkxvb3BzKTsKKyAgICAgICAgVGhyZWFkIG5vcm1hbFRocmVhZCA9IG5ldyBUaHJlYWQobm9ybWFsU3luY2hDaGVja2VyKTsKKyAgICAgICAgVGhyZWFkIG9mZnNldFRocmVhZCA9IG5ldyBUaHJlYWQob2Zmc2V0U3luY2hDaGVja2VyKTsKKyAgICAgICAgbm9ybWFsVGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIG9mZnNldFRocmVhZC5zdGFydCgpOworICAgICAgICB3aGlsZSAoKG5vcm1hbFN5bmNoQ2hlY2tlci5nZXROdW1iZXJPZkNoZWNrcygpIDwgbnVtYmVyT2ZMb29wcykKKyAgICAgICAgICAgICAgICB8fCAob2Zmc2V0U3luY2hDaGVja2VyLmdldE51bWJlck9mQ2hlY2tzKCkgPCBudW1iZXJPZkxvb3BzKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTApOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHNldCBjb3JydXB0ZWQgYnkgbXVsdGlwbGUgdGhyZWFkIGFjY2VzcyIsCisgICAgICAgICAgICAgICAgbm9ybWFsU3luY2hDaGVja2VyLmdldFJlc3VsdCgpCisgICAgICAgICAgICAgICAgICAgICAgICAmJiBvZmZzZXRTeW5jaENoZWNrZXIuZ2V0UmVzdWx0KCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbm9ybWFsVGhyZWFkLmpvaW4oNTAwMCk7CisgICAgICAgICAgICBvZmZzZXRUaHJlYWQuam9pbig1MDAwKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiam9pbigpIGludGVycnVwdGVkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjdW5tb2RpZmlhYmxlQ29sbGVjdGlvbihqYXZhLnV0aWwuQ29sbGVjdGlvbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VubW9kaWZpYWJsZUNvbGxlY3Rpb25MamF2YV91dGlsX0NvbGxlY3Rpb24oKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuQ29sbGVjdGlvbgorICAgICAgICAvLyBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlQ29sbGVjdGlvbihqYXZhLnV0aWwuQ29sbGVjdGlvbikKKyAgICAgICAgYm9vbGVhbiBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgQ29sbGVjdGlvbiBjID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlQ29sbGVjdGlvbihsbCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGNvbGxlY3Rpb24gaXMgb2YgaW5jb3JyZWN0IHNpemUiLCBjLnNpemUoKSA9PSBsbAorICAgICAgICAgICAgICAgIC5zaXplKCkpOworICAgICAgICBJdGVyYXRvciBpID0gbGwuaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGkuaGFzTmV4dCgpKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgbGlzdCBtaXNzaW5nIGVsZW1lbnRzIiwgYy5jb250YWlucyhpLm5leHQoKSkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5hZGQobmV3IE9iamVjdCgpKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIC8vIENvcnJlY3QKKyAgICAgICAgfQorICAgICAgICBpZiAoIWV4Y2VwdGlvbikgeworICAgICAgICAgICAgZmFpbCgiQWxsb3dlZCBtb2RpZmljYXRpb24gb2YgY29sbGVjdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMucmVtb3ZlKG5ldyBPYmplY3QoKSk7CisgICAgICAgICAgICBmYWlsKCJBbGxvd2VkIG1vZGlmaWNhdGlvbiBvZiBjb2xsZWN0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QKKyAgICAgICAgfQorCisgICAgICAgIENvbGxlY3Rpb24gbXlDb2xsZWN0aW9uID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBteUNvbGxlY3Rpb24uYWRkKG5ldyBJbnRlZ2VyKDIwKSk7CisgICAgICAgIG15Q29sbGVjdGlvbi5hZGQobnVsbCk7CisgICAgICAgIGMgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVDb2xsZWN0aW9uKG15Q29sbGVjdGlvbik7CisgICAgICAgIGFzc2VydFRydWUoIkNvbGxlY3Rpb24gc2hvdWxkIGNvbnRhaW4gbnVsbCIsIGMuY29udGFpbnMobnVsbCkpOworICAgICAgICBhc3NlcnRUcnVlKCJDb2xsZWN0aW9uIHNob3VsZCBjb250YWluIEludGVnZXIoMjApIiwgYworICAgICAgICAgICAgICAgIC5jb250YWlucyhuZXcgSW50ZWdlcigyMCkpKTsKKworICAgICAgICBteUNvbGxlY3Rpb24gPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgMTAwOyBjb3VudGVyKyspIHsKKyAgICAgICAgICAgIG15Q29sbGVjdGlvbi5hZGQob2JqQXJyYXlbY291bnRlcl0pOworICAgICAgICB9CisgICAgICAgIG5ldyBTdXBwb3J0X1VubW9kaWZpYWJsZUNvbGxlY3Rpb25UZXN0KCIiLCBDb2xsZWN0aW9ucworICAgICAgICAgICAgICAgIC51bm1vZGlmaWFibGVDb2xsZWN0aW9uKG15Q29sbGVjdGlvbikpLnJ1blRlc3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjdW5tb2RpZmlhYmxlTGlzdChqYXZhLnV0aWwuTGlzdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VubW9kaWZpYWJsZUxpc3RMamF2YV91dGlsX0xpc3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuTGlzdAorICAgICAgICAvLyBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChqYXZhLnV0aWwuTGlzdCkKKworICAgICAgICAvLyB0ZXN0IHdpdGggYSBTZXF1ZW50aWFsIEFjY2VzcyBMaXN0CisgICAgICAgIGJvb2xlYW4gZXhjZXB0aW9uID0gZmFsc2U7CisgICAgICAgIExpc3QgYyA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QobGwpOworICAgICAgICAvLyBFbnN1cmUgYSBOUEUgaXMgdGhyb3duIGlmIHRoZSBsaXN0IGlzIE5VTEwKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiBmb3IgbnVsbCBsaXN0IHBhcmFtZXRlciIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBsaXN0IGlzIG9mIGluY29ycmVjdCBzaXplIiwgYy5zaXplKCkgPT0gbGwuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiUmV0dXJuZWQgTGlzdCBzaG91bGQgbm90IGltcGxlbWVudCBSYW5kb20gQWNjZXNzIGludGVyZmFjZSIsCisgICAgICAgICAgICAgICAgIShjIGluc3RhbmNlb2YgUmFuZG9tQWNjZXNzKSk7CisKKyAgICAgICAgSXRlcmF0b3IgaSA9IGxsLml0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpLmhhc05leHQoKSkKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGxpc3QgbWlzc2luZyBlbGVtZW50cyIsIGMuY29udGFpbnMoaS5uZXh0KCkpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMuYWRkKG5ldyBPYmplY3QoKSk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IHRydWU7CisgICAgICAgICAgICAvLyBDb3JyZWN0CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFleGNlcHRpb24pIHsKKyAgICAgICAgICAgIGZhaWwoIkFsbG93ZWQgbW9kaWZpY2F0aW9uIG9mIGxpc3QiKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLnJlbW92ZShuZXcgT2JqZWN0KCkpOworICAgICAgICAgICAgZmFpbCgiQWxsb3dlZCBtb2RpZmljYXRpb24gb2YgbGlzdCIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0CisgICAgICAgIH0KKworICAgICAgICAvLyB0ZXN0IHdpdGggYSBSYW5kb20gQWNjZXNzIExpc3QKKyAgICAgICAgTGlzdCBzbWFsbExpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIHNtYWxsTGlzdC5hZGQobnVsbCk7CisgICAgICAgIHNtYWxsTGlzdC5hZGQoInlvaW5rIik7CisgICAgICAgIGMgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHNtYWxsTGlzdCk7CisgICAgICAgIGFzc2VydE51bGwoIkZpcnN0IGVsZW1lbnQgc2hvdWxkIGJlIG51bGwiLCBjLmdldCgwKSk7CisgICAgICAgIGFzc2VydFRydWUoIkxpc3Qgc2hvdWxkIGNvbnRhaW4gbnVsbCIsIGMuY29udGFpbnMobnVsbCkpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJUMS4gUmV0dXJuZWQgTGlzdCBzaG91bGQgaW1wbGVtZW50IFJhbmRvbSBBY2Nlc3MgaW50ZXJmYWNlIiwKKyAgICAgICAgICAgICAgICBjIGluc3RhbmNlb2YgUmFuZG9tQWNjZXNzKTsKKworICAgICAgICBzbWFsbExpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgMTAwOyBjb3VudGVyKyspIHsKKyAgICAgICAgICAgIHNtYWxsTGlzdC5hZGQob2JqQXJyYXlbY291bnRlcl0pOworICAgICAgICB9CisgICAgICAgIExpc3QgbXlMaXN0ID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChzbWFsbExpc3QpOworICAgICAgICBhc3NlcnRUcnVlKCJMaXN0IHNob3VsZCBub3QgY29udGFpbiBudWxsIiwgIW15TGlzdC5jb250YWlucyhudWxsKSk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIlQyLiBSZXR1cm5lZCBMaXN0IHNob3VsZCBpbXBsZW1lbnQgUmFuZG9tIEFjY2VzcyBpbnRlcmZhY2UiLAorICAgICAgICAgICAgICAgIG15TGlzdCBpbnN0YW5jZW9mIFJhbmRvbUFjY2Vzcyk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0IGZhaWxlZCBvbiB1bm1vZGlmaWFibGUgbGlzdCIsIG15TGlzdC5nZXQoNTApLmVxdWFscygKKyAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcig1MCkpKTsKKyAgICAgICAgTGlzdEl0ZXJhdG9yIGxpc3RJdGVyYXRvciA9IG15TGlzdC5saXN0SXRlcmF0b3IoKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGxpc3RJdGVyYXRvci5oYXNOZXh0KCk7IGNvdW50ZXIrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTGlzdCBoYXMgd3JvbmcgZWxlbWVudHMiLCAoKEludGVnZXIpIGxpc3RJdGVyYXRvcgorICAgICAgICAgICAgICAgICAgICAubmV4dCgpKS5pbnRWYWx1ZSgpID09IGNvdW50ZXIpOworICAgICAgICB9CisgICAgICAgIG5ldyBTdXBwb3J0X1VubW9kaWZpYWJsZUNvbGxlY3Rpb25UZXN0KCIiLCBzbWFsbExpc3QpLnJ1blRlc3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjdW5tb2RpZmlhYmxlTWFwKGphdmEudXRpbC5NYXApCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF91bm1vZGlmaWFibGVNYXBMamF2YV91dGlsX01hcCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5NYXAKKyAgICAgICAgLy8gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChqYXZhLnV0aWwuTWFwKQorICAgICAgICBib29sZWFuIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICBNYXAgYyA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChobSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIG1hcCBpcyBvZiBpbmNvcnJlY3Qgc2l6ZSIsIGMuc2l6ZSgpID09IGhtLnNpemUoKSk7CisgICAgICAgIEl0ZXJhdG9yIGkgPSBobS5rZXlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoaS5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIE9iamVjdCB4ID0gaS5uZXh0KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBtYXAgbWlzc2luZyBlbGVtZW50cyIsIGMuZ2V0KHgpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgaG0uZ2V0KHgpKSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMucHV0KG5ldyBPYmplY3QoKSwgIiIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICAgICAgLy8gQ29ycmVjdAorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkFsbG93ZWQgbW9kaWZpY2F0aW9uIG9mIG1hcCIsIGV4Y2VwdGlvbik7CisKKyAgICAgICAgZXhjZXB0aW9uID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjLnJlbW92ZShuZXcgT2JqZWN0KCkpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0CisgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkFsbG93ZWQgbW9kaWZpY2F0aW9uIG9mIG1hcCIsIGV4Y2VwdGlvbik7CisKKyAgICAgICAgZXhjZXB0aW9uID0gZmFsc2U7CisgICAgICAgIEl0ZXJhdG9yIGl0ID0gYy5lbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgIE1hcC5FbnRyeSBlbnRyeSA9IChNYXAuRW50cnkpIGl0Lm5leHQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVudHJ5LnNldFZhbHVlKCJtb2RpZmllZCIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0CisgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkFsbG93ZWQgbW9kaWZpY2F0aW9uIG9mIGVudHJ5IiwgZXhjZXB0aW9uKTsKKworICAgICAgICBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgT2JqZWN0W10gYXJyYXkgPSBjLmVudHJ5U2V0KCkudG9BcnJheSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgKChNYXAuRW50cnkpIGFycmF5WzBdKS5zZXRWYWx1ZSgibW9kaWZpZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdAorICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJBbGxvd2VkIG1vZGlmaWNhdGlvbiBvZiBhcnJheSBlbnRyeSIsIGV4Y2VwdGlvbik7CisKKyAgICAgICAgZXhjZXB0aW9uID0gZmFsc2U7CisgICAgICAgIE1hcC5FbnRyeVtdIGFycmF5MiA9IChNYXAuRW50cnlbXSkgYy5lbnRyeVNldCgpLnRvQXJyYXkoCisgICAgICAgICAgICAgICAgbmV3IE1hcC5FbnRyeVswXSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhcnJheTJbMF0uc2V0VmFsdWUoIm1vZGlmaWVkIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQWxsb3dlZCBtb2RpZmljYXRpb24gb2YgYXJyYXkgZW50cnkyIiwgZXhjZXB0aW9uKTsKKworICAgICAgICBIYXNoTWFwIHNtYWxsTWFwID0gbmV3IEhhc2hNYXAoKTsKKyAgICAgICAgc21hbGxNYXAucHV0KG51bGwsIG5ldyBMb25nKDMwKSk7CisgICAgICAgIHNtYWxsTWFwLnB1dChuZXcgTG9uZygyNSksIG51bGwpOworICAgICAgICBNYXAgdW5tb2RNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAoc21hbGxNYXApOworCisgICAgICAgIGFzc2VydE51bGwoIlRyeWluZyB0byB1c2UgYSBudWxsIHZhbHVlIGluIG1hcCBmYWlsZWQiLCB1bm1vZE1hcAorICAgICAgICAgICAgICAgIC5nZXQobmV3IExvbmcoMjUpKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRyeWluZyB0byB1c2UgYSBudWxsIGtleSBpbiBtYXAgZmFpbGVkIiwgdW5tb2RNYXAuZ2V0KG51bGwpCisgICAgICAgICAgICAgICAgLmVxdWFscyhuZXcgTG9uZygzMCkpKTsKKworICAgICAgICBzbWFsbE1hcCA9IG5ldyBIYXNoTWFwKCk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgMTAwOyBjb3VudGVyKyspIHsKKyAgICAgICAgICAgIHNtYWxsTWFwLnB1dChvYmpBcnJheVtjb3VudGVyXS50b1N0cmluZygpLCBvYmpBcnJheVtjb3VudGVyXSk7CisgICAgICAgIH0KKyAgICAgICAgdW5tb2RNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAoc21hbGxNYXApOworICAgICAgICBuZXcgU3VwcG9ydF9Vbm1vZGlmaWFibGVNYXBUZXN0KCIiLCB1bm1vZE1hcCkucnVuVGVzdCgpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI3VubW9kaWZpYWJsZVNldChqYXZhLnV0aWwuU2V0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdW5tb2RpZmlhYmxlU2V0TGphdmFfdXRpbF9TZXQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuU2V0CisgICAgICAgIC8vIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVTZXQoamF2YS51dGlsLlNldCkKKyAgICAgICAgYm9vbGVhbiBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgU2V0IGMgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVTZXQocyk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHNldCBpcyBvZiBpbmNvcnJlY3Qgc2l6ZSIsIGMuc2l6ZSgpID09IHMuc2l6ZSgpKTsKKyAgICAgICAgSXRlcmF0b3IgaSA9IGxsLml0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpLmhhc05leHQoKSkKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHNldCBtaXNzaW5nIGVsZW1lbnRzIiwgYy5jb250YWlucyhpLm5leHQoKSkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5hZGQobmV3IE9iamVjdCgpKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIC8vIENvcnJlY3QKKyAgICAgICAgfQorICAgICAgICBpZiAoIWV4Y2VwdGlvbikgeworICAgICAgICAgICAgZmFpbCgiQWxsb3dlZCBtb2RpZmljYXRpb24gb2Ygc2V0Iik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMucmVtb3ZlKG5ldyBPYmplY3QoKSk7CisgICAgICAgICAgICBmYWlsKCJBbGxvd2VkIG1vZGlmaWNhdGlvbiBvZiBzZXQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gQ29ycmVjdAorICAgICAgICB9CisKKyAgICAgICAgU2V0IG15U2V0ID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KG5ldyBIYXNoU2V0KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgbm90IGNvbnRhaW4gbnVsbCIsICFteVNldC5jb250YWlucyhudWxsKSk7CisgICAgICAgIG15U2V0ID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KENvbGxlY3Rpb25zLnNpbmdsZXRvbihudWxsKSk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBjb250YWluIG51bGwiLCBteVNldC5jb250YWlucyhudWxsKSk7CisKKyAgICAgICAgbXlTZXQgPSBuZXcgVHJlZVNldCgpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IDEwMDsgY291bnRlcisrKSB7CisgICAgICAgICAgICBteVNldC5hZGQob2JqQXJyYXlbY291bnRlcl0pOworICAgICAgICB9CisgICAgICAgIG5ldyBTdXBwb3J0X1VubW9kaWZpYWJsZUNvbGxlY3Rpb25UZXN0KCIiLCBDb2xsZWN0aW9ucworICAgICAgICAgICAgICAgIC51bm1vZGlmaWFibGVTZXQobXlTZXQpKS5ydW5UZXN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbGxlY3Rpb25zI3VubW9kaWZpYWJsZVNvcnRlZE1hcChqYXZhLnV0aWwuU29ydGVkTWFwKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdW5tb2RpZmlhYmxlU29ydGVkTWFwTGphdmFfdXRpbF9Tb3J0ZWRNYXAoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuU29ydGVkTWFwCisgICAgICAgIC8vIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVTb3J0ZWRNYXAoamF2YS51dGlsLlNvcnRlZE1hcCkKKyAgICAgICAgYm9vbGVhbiBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgVHJlZU1hcCB0bSA9IG5ldyBUcmVlTWFwKCk7CisgICAgICAgIHRtLnB1dEFsbChobSk7CisgICAgICAgIE1hcCBjID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU29ydGVkTWFwKHRtKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgbWFwIGlzIG9mIGluY29ycmVjdCBzaXplIiwgYy5zaXplKCkgPT0gdG0uc2l6ZSgpKTsKKyAgICAgICAgSXRlcmF0b3IgaSA9IGhtLmtleVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpLmhhc05leHQoKSkgeworICAgICAgICAgICAgT2JqZWN0IHggPSBpLm5leHQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIG1hcCBtaXNzaW5nIGVsZW1lbnRzIiwgYy5nZXQoeCkuZXF1YWxzKAorICAgICAgICAgICAgICAgICAgICB0bS5nZXQoeCkpKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5wdXQobmV3IE9iamVjdCgpLCAiIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IHRydWU7CisgICAgICAgICAgICAvLyBDb3JyZWN0CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWV4Y2VwdGlvbikgeworICAgICAgICAgICAgZmFpbCgiQWxsb3dlZCBtb2RpZmljYXRpb24gb2YgbWFwIik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMucmVtb3ZlKG5ldyBPYmplY3QoKSk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmYWlsKCJBbGxvd2VkIG1vZGlmaWNhdGlvbiBvZiBtYXAiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMjdW5tb2RpZmlhYmxlU29ydGVkU2V0KGphdmEudXRpbC5Tb3J0ZWRTZXQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF91bm1vZGlmaWFibGVTb3J0ZWRTZXRMamF2YV91dGlsX1NvcnRlZFNldCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5Tb3J0ZWRTZXQKKyAgICAgICAgLy8gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNvcnRlZFNldChqYXZhLnV0aWwuU29ydGVkU2V0KQorICAgICAgICBib29sZWFuIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICBTb3J0ZWRTZXQgc3MgPSBuZXcgVHJlZVNldCgpOworICAgICAgICBzcy5hZGRBbGwocyk7CisgICAgICAgIFNvcnRlZFNldCBjID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU29ydGVkU2V0KHNzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgc2V0IGlzIG9mIGluY29ycmVjdCBzaXplIiwgYy5zaXplKCkgPT0gc3Muc2l6ZSgpKTsKKyAgICAgICAgSXRlcmF0b3IgaSA9IGxsLml0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpLmhhc05leHQoKSkKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHNldCBtaXNzaW5nIGVsZW1lbnRzIiwgYy5jb250YWlucyhpLm5leHQoKSkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYy5hZGQobmV3IE9iamVjdCgpKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIC8vIENvcnJlY3QKKyAgICAgICAgfQorICAgICAgICBpZiAoIWV4Y2VwdGlvbikgeworICAgICAgICAgICAgZmFpbCgiQWxsb3dlZCBtb2RpZmljYXRpb24gb2Ygc2V0Iik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGMucmVtb3ZlKG5ldyBPYmplY3QoKSk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIENvcnJlY3QKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmYWlsKCJBbGxvd2VkIG1vZGlmaWNhdGlvbiBvZiBzZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHVubW9kaWZpYWJsZSBvYmplY3RzIHRvU3RyaW5nIG1ldGhvZHMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3VubW9kaWZpYWJsZV90b1N0cmluZ19tZXRob2RzKCkgeworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTU1MgorICAgICAgICBBcnJheUxpc3QgYWwgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGFsLmFkZCgiYSIpOworICAgICAgICBhbC5hZGQoImIiKTsKKyAgICAgICAgQ29sbGVjdGlvbiB1YyA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUNvbGxlY3Rpb24oYWwpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlthLCBiXSIsIHVjLnRvU3RyaW5nKCkpOworICAgICAgICBIYXNoTWFwIG0gPSBuZXcgSGFzaE1hcCgpOworICAgICAgICBtLnB1dCgib25lIiwgIjEiKTsKKyAgICAgICAgbS5wdXQoInR3byIsICIyIik7CisgICAgICAgIE1hcCB1bSA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChtKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgie29uZT0xLCB0d289Mn0iLmVxdWFscyh1bS50b1N0cmluZygpKSB8fAorICAgICAgICAgICAgICAgICAgICJ7dHdvPTIsIG9uZT0xfSIuZXF1YWxzKHVtLnRvU3RyaW5nKCkpKTsKKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2luZ2xldG9uTGlzdExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlNldAorICAgICAgICAvLyBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuc2luZ2xldG9uKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIFN0cmluZyBzdHIgPSAiU2luZ2xldG9uIjsKKworICAgICAgICBMaXN0IHNpbmdsZSA9IENvbGxlY3Rpb25zLnNpbmdsZXRvbkxpc3Qoc3RyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHNpbmdsZS5zaXplKCkpOworICAgICAgICBhc3NlcnRUcnVlKHNpbmdsZS5jb250YWlucyhzdHIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2luZ2xlLmNvbnRhaW5zKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoQ29sbGVjdGlvbnMuc2luZ2xldG9uTGlzdChudWxsKS5jb250YWlucyhzdHIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KG51bGwpLmNvbnRhaW5zKG51bGwpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2luZ2xlLmFkZCgiTmV3IGVsZW1lbnQiKTsKKyAgICAgICAgICAgIGZhaWwoIlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2luZ2xldG9uTWFwTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuU2V0CisgICAgICAgIC8vIGphdmEudXRpbC5Db2xsZWN0aW9ucy5zaW5nbGV0b24oamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgRG91YmxlIGtleSA9IG5ldyBEb3VibGUgKDMuMTQpOworICAgICAgICBTdHJpbmcgdmFsdWUgPSAiRnVuZGFtZW50YWwgY29uc3RhbnQiOworCisgICAgICAgIE1hcCBzaW5nbGUgPSBDb2xsZWN0aW9ucy5zaW5nbGV0b25NYXAoa2V5LCB2YWx1ZSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBzaW5nbGUuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzaW5nbGUuY29udGFpbnNLZXkoa2V5KSk7CisgICAgICAgIGFzc2VydFRydWUoc2luZ2xlLmNvbnRhaW5zVmFsdWUodmFsdWUpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2luZ2xlLmNvbnRhaW5zS2V5KG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2luZ2xlLmNvbnRhaW5zVmFsdWUobnVsbCkpOworICAgICAgICBhc3NlcnRGYWxzZShDb2xsZWN0aW9ucy5zaW5nbGV0b25NYXAobnVsbCwgbnVsbCkuY29udGFpbnNLZXkoa2V5KSk7CisgICAgICAgIGFzc2VydEZhbHNlKENvbGxlY3Rpb25zLnNpbmdsZXRvbk1hcChudWxsLCBudWxsKS5jb250YWluc1ZhbHVlKHZhbHVlKSk7CisgICAgICAgIGFzc2VydFRydWUoQ29sbGVjdGlvbnMuc2luZ2xldG9uTWFwKG51bGwsIG51bGwpLmNvbnRhaW5zS2V5KG51bGwpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShDb2xsZWN0aW9ucy5zaW5nbGV0b25NYXAobnVsbCwgbnVsbCkuY29udGFpbnNWYWx1ZShudWxsKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpbmdsZS5jbGVhcigpOworICAgICAgICAgICAgZmFpbCgiVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpbmdsZS5wdXQobmV3IERvdWJsZSgxKSwgIm9uZSB3cm9uZyB2YWx1ZSIpOworICAgICAgICAgICAgZmFpbCgiVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIG9iakFycmF5ID0gbmV3IE9iamVjdFsxMDAwXTsKKyAgICAgICAgbXlvYmpBcnJheSA9IG5ldyBPYmplY3RbMTAwMF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2JqQXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG9iakFycmF5W2ldID0gbmV3IEludGVnZXIoaSk7CisgICAgICAgICAgICBteW9iakFycmF5W2ldID0gbmV3IE15SW50KGkpOworICAgICAgICB9CisKKyAgICAgICAgbGwgPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICBteWxsID0gbmV3IExpbmtlZExpc3QoKTsKKyAgICAgICAgcyA9IG5ldyBIYXNoU2V0KCk7CisgICAgICAgIG15cyA9IG5ldyBIYXNoU2V0KCk7CisgICAgICAgIHJldmVyc2VkTGlua2VkTGlzdCA9IG5ldyBMaW5rZWRMaXN0KCk7IC8vIHRvIGJlIHNvcnRlZCBpbiByZXZlcnNlIG9yZGVyCisgICAgICAgIG15UmV2ZXJzZWRMaW5rZWRMaXN0ID0gbmV3IExpbmtlZExpc3QoKTsgLy8gdG8gYmUgc29ydGVkIGluIHJldmVyc2UKKyAgICAgICAgLy8gb3JkZXIKKyAgICAgICAgaG0gPSBuZXcgSGFzaE1hcCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iakFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBsbC5hZGQob2JqQXJyYXlbaV0pOworICAgICAgICAgICAgbXlsbC5hZGQobXlvYmpBcnJheVtpXSk7CisgICAgICAgICAgICBzLmFkZChvYmpBcnJheVtpXSk7CisgICAgICAgICAgICBteXMuYWRkKG15b2JqQXJyYXlbaV0pOworICAgICAgICAgICAgcmV2ZXJzZWRMaW5rZWRMaXN0LmFkZChvYmpBcnJheVtvYmpBcnJheS5sZW5ndGggLSBpIC0gMV0pOworICAgICAgICAgICAgbXlSZXZlcnNlZExpbmtlZExpc3QuYWRkKG15b2JqQXJyYXlbbXlvYmpBcnJheS5sZW5ndGggLSBpIC0gMV0pOworICAgICAgICAgICAgaG0ucHV0KG9iakFycmF5W2ldLnRvU3RyaW5nKCksIG9iakFycmF5W2ldKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgICAgICBvYmpBcnJheSA9IG51bGw7CisgICAgICAgIG15b2JqQXJyYXkgPSBudWxsOworCisgICAgICAgIGxsID0gbnVsbDsKKyAgICAgICAgbXlsbCA9IG51bGw7CisgICAgICAgIHJldmVyc2VkTGlua2VkTGlzdCA9IG51bGw7CisgICAgICAgIG15UmV2ZXJzZWRMaW5rZWRMaXN0ID0gbnVsbDsKKyAgICAgICAgcyA9IG51bGw7CisgICAgICAgIG15cyA9IG51bGw7CisgICAgICAgIGhtID0gbnVsbDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBkb25lU3VpdGUoKSB7CisgICAgICAgIG9iakFycmF5ID0gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9Db25jdXJyZW50TW9kVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQ29uY3VycmVudE1vZFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNzUwZTgxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQ29uY3VycmVudE1vZFRlc3QuamF2YQpAQCAtMCwwICsxLDY2NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkFic3RyYWN0TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBDb25jdXJyZW50TW9kVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qCisgICAgICogVGVzdCBtZXRob2QgZm9yICdqYXZhLnV0aWwuQWJzdHJhY3RMaXN0LnN1Ykxpc3QoaW50LCBpbnQpJworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXQoKSB7CisgICAgICAgIEFic3RyYWN0TGlzdCBhbCA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgRG91YmxlIG9uZSA9IG5ldyBEb3VibGUoMS4wKTsKKyAgICAgICAgRG91YmxlIHR3byA9IG5ldyBEb3VibGUoMi4wKTsKKyAgICAgICAgRG91YmxlIHRocmVlID0gbmV3IERvdWJsZSgzLjApOworICAgICAgICBEb3VibGUgZm91ciA9IG5ldyBEb3VibGUoNC4wKTsKKyAgICAgICAgYWwuYWRkKG9uZSk7CisgICAgICAgIGFsLmFkZCh0d28pOworICAgICAgICBhbC5hZGQodGhyZWUpOworICAgICAgICBhbC5hZGQoZm91cik7CisgICAgICAgIExpc3Qgc3ViID0gYWwuc3ViTGlzdCgxLCAzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHN1Yi5zaXplKCkpOworICAgICAgICAvLyB0aGUgc3ViLmdldCgxKSBpcyAzLjAKKyAgICAgICAgYXNzZXJ0VHJ1ZSgoKERvdWJsZSkgc3ViLmdldCgxKSkuZG91YmxlVmFsdWUoKSA8PSAzLjApOworICAgICAgICBhc3NlcnRUcnVlKCgoRG91YmxlKSBzdWIuZ2V0KDEpKS5kb3VibGVWYWx1ZSgpID4gMi4wKTsKKworICAgICAgICBhbC5yZW1vdmUoMSk7IC8vIHJlbW92ZSB0aGUgMi4wCisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGlsbGVnYWwgY2FsbCB0aGUgc3ViTGlzdCdzIG1ldGhvZCBnZXQoaW50KS4KKyAgICAgICAgICAgIHN1Yi5nZXQoMSk7CisgICAgICAgICAgICBmYWlsKCJJdCBzaG91bGQgdGhyb3dzIENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24uIik7CisgICAgICAgIH0gY2F0Y2ggKENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFsLmdldCgtMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhbC5nZXQoYWwuc2l6ZSgpKzEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFRlc3QgbWV0aG9kIGZvciAnamF2YS51dGlsLkFic3RyYWN0TGlzdC5zdWJMaXN0KGludCwgaW50KScKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0KCkgeworICAgICAgICBBYnN0cmFjdExpc3QgYWwgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIERvdWJsZSBvbmUgPSBuZXcgRG91YmxlKDEuMCk7CisgICAgICAgIERvdWJsZSB0d28gPSBuZXcgRG91YmxlKDIuMCk7CisgICAgICAgIERvdWJsZSB0aHJlZSA9IG5ldyBEb3VibGUoMy4wKTsKKyAgICAgICAgRG91YmxlIGZvdXIgPSBuZXcgRG91YmxlKDQuMCk7CisgICAgICAgIGFsLmFkZChvbmUpOworICAgICAgICBhbC5hZGQodHdvKTsKKyAgICAgICAgYWwuYWRkKHRocmVlKTsKKyAgICAgICAgYWwuYWRkKGZvdXIpOworICAgICAgICBMaXN0IHN1YiA9IGFsLnN1Ykxpc3QoMSwgMyk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBzdWIuc2l6ZSgpKTsKKyAgICAgICAgLy8gdGhlIHN1Yi5nZXQoMSkgaXMgMy4wCisgICAgICAgIGFzc2VydFRydWUoKChEb3VibGUpIHN1Yi5nZXQoMSkpLmRvdWJsZVZhbHVlKCkgPD0gMy4wKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgoKERvdWJsZSkgc3ViLmdldCgxKSkuZG91YmxlVmFsdWUoKSA+IDIuMCk7CisKKyAgICAgICAgYWwucmVtb3ZlKDEpOyAvLyByZW1vdmUgdGhlIDIuMAorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBpbGxlZ2FsIGNhbGwgdGhlIHN1Ykxpc3QncyBtZXRob2Qgc2V0KGludCxPYmplY3QpLgorICAgICAgICAgICAgc3ViLnNldCgxLCB0d28pOworICAgICAgICAgICAgZmFpbCgiSXQgc2hvdWxkIHRocm93cyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uLiIpOworICAgICAgICB9IGNhdGNoIChDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogVGVzdCBtZXRob2QgZm9yICdqYXZhLnV0aWwuQWJzdHJhY3RMaXN0LnN1Ykxpc3QoaW50LCBpbnQpJworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGQoKSB7CisgICAgICAgIEFic3RyYWN0TGlzdCBhbCA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgRG91YmxlIG9uZSA9IG5ldyBEb3VibGUoMS4wKTsKKyAgICAgICAgRG91YmxlIHR3byA9IG5ldyBEb3VibGUoMi4wKTsKKyAgICAgICAgRG91YmxlIHRocmVlID0gbmV3IERvdWJsZSgzLjApOworICAgICAgICBEb3VibGUgZm91ciA9IG5ldyBEb3VibGUoNC4wKTsKKyAgICAgICAgYWwuYWRkKG9uZSk7CisgICAgICAgIGFsLmFkZCh0d28pOworICAgICAgICBhbC5hZGQodGhyZWUpOworICAgICAgICBhbC5hZGQoZm91cik7CisgICAgICAgIExpc3Qgc3ViID0gYWwuc3ViTGlzdCgxLCAzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHN1Yi5zaXplKCkpOworICAgICAgICAvLyB0aGUgc3ViLmdldCgxKSBpcyAzLjAKKyAgICAgICAgYXNzZXJ0VHJ1ZSgoKERvdWJsZSkgc3ViLmdldCgxKSkuZG91YmxlVmFsdWUoKSA8PSAzLjApOworICAgICAgICBhc3NlcnRUcnVlKCgoRG91YmxlKSBzdWIuZ2V0KDEpKS5kb3VibGVWYWx1ZSgpID4gMi4wKTsKKworICAgICAgICBhbC5yZW1vdmUoMSk7IC8vIHJlbW92ZSB0aGUgMi4wCisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGlsbGVnYWwgY2FsbCB0aGUgc3ViTGlzdCdzIG1ldGhvZCBBZGQoaW50LE9iamVjdCkuCisgICAgICAgICAgICBzdWIuYWRkKDEsIHR3byk7CisgICAgICAgICAgICBmYWlsKCJJdCBzaG91bGQgdGhyb3dzIENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24uIik7CisgICAgICAgIH0gY2F0Y2ggKENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2phdmEudXRpbC5BYnN0cmFjdExpc3Quc3ViTGlzdChpbnQsIGludCknCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZSgpIHsKKyAgICAgICAgQWJzdHJhY3RMaXN0IGFsID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBEb3VibGUgb25lID0gbmV3IERvdWJsZSgxLjApOworICAgICAgICBEb3VibGUgdHdvID0gbmV3IERvdWJsZSgyLjApOworICAgICAgICBEb3VibGUgdGhyZWUgPSBuZXcgRG91YmxlKDMuMCk7CisgICAgICAgIERvdWJsZSBmb3VyID0gbmV3IERvdWJsZSg0LjApOworICAgICAgICBhbC5hZGQob25lKTsKKyAgICAgICAgYWwuYWRkKHR3byk7CisgICAgICAgIGFsLmFkZCh0aHJlZSk7CisgICAgICAgIGFsLmFkZChmb3VyKTsKKyAgICAgICAgTGlzdCBzdWIgPSBhbC5zdWJMaXN0KDEsIDMpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgc3ViLnNpemUoKSk7CisgICAgICAgIC8vIHRoZSBzdWIuZ2V0KDEpIGlzIDMuMAorICAgICAgICBhc3NlcnRUcnVlKCgoRG91YmxlKSBzdWIuZ2V0KDEpKS5kb3VibGVWYWx1ZSgpIDw9IDMuMCk7CisgICAgICAgIGFzc2VydFRydWUoKChEb3VibGUpIHN1Yi5nZXQoMSkpLmRvdWJsZVZhbHVlKCkgPiAyLjApOworCisgICAgICAgIGFsLnJlbW92ZSgxKTsgLy8gcmVtb3ZlIHRoZSAyLjAKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gaWxsZWdhbCBjYWxsIHRoZSBzdWJMaXN0J3MgbWV0aG9kIHJlbW92ZShpbnQpLgorICAgICAgICAgICAgc3ViLnJlbW92ZSgxKTsKKyAgICAgICAgICAgIGZhaWwoIkl0IHNob3VsZCB0aHJvd3MgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbi4iKTsKKyAgICAgICAgfSBjYXRjaCAoQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3ViLnJlbW92ZSgtMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdWIucmVtb3ZlKHN1Yi5zaXplKCkgKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYWwgPSBuZXcgQWJzdHJhY3RMaXN0KCkgeworCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0KGludCBpbmRleCkgeworICAgICAgICAgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhbC5yZW1vdmUoMSk7CisgICAgICAgICAgICBmYWlsKCJVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2phdmEudXRpbC5BYnN0cmFjdExpc3Quc3ViTGlzdChpbnQsIGludCknCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEFkZEFsbCgpIHsKKyAgICAgICAgQWJzdHJhY3RMaXN0IGFsID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBEb3VibGUgb25lID0gbmV3IERvdWJsZSgxLjApOworICAgICAgICBEb3VibGUgdHdvID0gbmV3IERvdWJsZSgyLjApOworICAgICAgICBEb3VibGUgdGhyZWUgPSBuZXcgRG91YmxlKDMuMCk7CisgICAgICAgIERvdWJsZSBmb3VyID0gbmV3IERvdWJsZSg0LjApOworICAgICAgICBhbC5hZGQob25lKTsKKyAgICAgICAgYWwuYWRkKHR3byk7CisgICAgICAgIGFsLmFkZCh0aHJlZSk7CisgICAgICAgIGFsLmFkZChmb3VyKTsKKyAgICAgICAgTGlzdCBzdWIgPSBhbC5zdWJMaXN0KDEsIDMpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgc3ViLnNpemUoKSk7CisgICAgICAgIC8vIHRoZSBzdWIuZ2V0KDEpIGlzIDMuMAorICAgICAgICBhc3NlcnRUcnVlKCgoRG91YmxlKSBzdWIuZ2V0KDEpKS5kb3VibGVWYWx1ZSgpIDw9IDMuMCk7CisgICAgICAgIGFzc2VydFRydWUoKChEb3VibGUpIHN1Yi5nZXQoMSkpLmRvdWJsZVZhbHVlKCkgPiAyLjApOworCisgICAgICAgIGFsLnJlbW92ZSgxKTsgLy8gcmVtb3ZlIHRoZSAyLjAKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gaWxsZWdhbCBjYWxsIHRoZSBzdWJMaXN0J3MgbWV0aG9kIGFkZEFsbChpbnQsQ29sbGVjdGlvbikuCisgICAgICAgICAgICBDb2xsZWN0aW9uIGMgPSBuZXcgVmVjdG9yKCk7CisgICAgICAgICAgICBEb3VibGUgZml2ZSA9IG5ldyBEb3VibGUoNS4wKTsKKyAgICAgICAgICAgIGMuYWRkKGZpdmUpOworICAgICAgICAgICAgc3ViLmFkZEFsbCgxLCBjKTsKKyAgICAgICAgICAgIGZhaWwoIkl0IHNob3VsZCB0aHJvd3MgQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbi4iKTsKKyAgICAgICAgfSBjYXRjaCAoQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICBBYnN0cmFjdExpc3QgYWJzdHIgPSBuZXcgQWJzdHJhY3RMaXN0KCkgeworCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0KGludCBhcmcwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorCisgICAgICAgIH07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFic3RyLmFkZChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZWNwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBhYnN0ciA9IG5ldyBBYnN0cmFjdExpc3Q8RG91YmxlPigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gYWRkKERvdWJsZSB2YWx1ZSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBEb3VibGUgZ2V0KGludCBpbmRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWJzdHIuYWRkKDEpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYWJzdHIgPSBuZXcgQWJzdHJhY3RMaXN0PEludGVnZXI+KCkgeworICAgICAgICAgICAgZmluYWwgaW50IGZvcmJpZGRlblZhbHVlID0gMzM7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGFkZChJbnRlZ2VyIHZhbHVlKSB7CisgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IGZvcmJpZGRlblZhbHVlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIEludGVnZXIgZ2V0KGludCBpbmRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBhYnN0ci5hZGQoMSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhYnN0ci5hZGQoMzMpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRJTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIEFic3RyYWN0TGlzdCBhYnN0ciA9IG5ldyBBYnN0cmFjdExpc3QoKSB7CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIE9iamVjdCBnZXQoaW50IGFyZzApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgfTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWJzdHIuYWRkKDEsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9lY3BlY3RlZAorICAgICAgICB9CisgICAgICAgIGFic3RyID0gbmV3IEFic3RyYWN0TGlzdDxEb3VibGU+KCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBhZGQoaW50IGluZGV4LCBEb3VibGUgdmFsdWUpIHsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgRG91YmxlIGdldChpbnQgaW5kZXgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFic3RyLmFkZCgxLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIkNsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGFic3RyID0gbmV3IEFic3RyYWN0TGlzdDxJbnRlZ2VyPigpIHsKKyAgICAgICAgICAgIGZpbmFsIGludCBmb3JiaWRkZW5WYWx1ZSA9IDMzOworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBhZGQoaW50IGluZGV4LCBJbnRlZ2VyIHZhbHVlKSB7CisgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IGZvcmJpZGRlblZhbHVlKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIEludGVnZXIgZ2V0KGludCBpbmRleCkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBhYnN0ci5hZGQoMSwgMSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhYnN0ci5hZGQoMSwgMzMpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYWJzdHIgPSBuZXcgQXJyYXlMaXN0KCk7CisKKyAgICAgICAgYWJzdHIuYWRkKDAsICJlbGVtZW50Iik7CisgICAgICAgIGFic3RyLmFkZCgxLCBudWxsKTsKKyAgICAgICAgYWJzdHIuYWRkKDIsIDEpOworICAgICAgICBhYnN0ci5hZGQoMywgbmV3IERvdWJsZSgzMykpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhYnN0ci5hZGQoLTMsIG5ldyBEb3VibGUoMzMpKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFic3RyLmFkZChhYnN0ci5zaXplKCkgKyAxLCBuZXcgRG91YmxlKDMzKSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkQWxsSUxqYXZhX3V0aWxfQ29sbGVjdGlvbigpIHsKKyAgICAgICAgQ29sbGVjdGlvbiBjID0gbmV3IFZlY3RvcigpOworICAgICAgICBjLmFkZChuZXcgRG91YmxlKDMzKSk7CisgICAgICAgIGMuYWRkKDEwKTsKKyAgICAgICAgYy5hZGQoIlN0cmluZyIpOworCisgICAgICAgIEFic3RyYWN0TGlzdCBhYnN0ciA9IG5ldyBBYnN0cmFjdExpc3QoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0KGludCBhcmcwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhYnN0ci5hZGRBbGwoMCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFic3RyLmFkZEFsbCgwLCBjKTsKKyAgICAgICAgICAgIGZhaWwoIlVuc3Vwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGFic3RyID0gbmV3IEFic3RyYWN0TGlzdDxEb3VibGU+KCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBhZGQoaW50IGluZGV4LCBEb3VibGUgdmFsdWUpIHsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgRG91YmxlIGdldChpbnQgYXJnMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWJzdHIuYWRkQWxsKDAsIGMpOworICAgICAgICAgICAgZmFpbCgiQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RkCisgICAgICAgIH0KKworICAgICAgICBhYnN0ciA9IG5ldyBBYnN0cmFjdExpc3Q8SW50ZWdlcj4oKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgZm9yYmlkZGVuVmFsdWUgPSAzMzsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgYWRkKGludCBpbmRleCwgSW50ZWdlciB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBmb3JiaWRkZW5WYWx1ZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBJbnRlZ2VyIGdldChpbnQgYXJnMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgYy5jbGVhcigpOworICAgICAgICBjLmFkZChuZXcgSW50ZWdlcigxKSk7CisgICAgICAgIGMuYWRkKG5ldyBJbnRlZ2VyKDIpKTsKKyAgICAgICAgYy5hZGQobmV3IEludGVnZXIoMykpOworICAgICAgICBjLmFkZChuZXcgSW50ZWdlcig0KSk7CisgICAgICAgIGMuYWRkKG5ldyBJbnRlZ2VyKDUpKTsKKworICAgICAgICBhYnN0ci5hZGRBbGwoMCwgYyk7CisKKyAgICAgICAgYy5hZGQobmV3IEludGVnZXIoMzMpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWJzdHIuYWRkQWxsKDAsIGMpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgICAgIGFic3RyID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBhYnN0ci5hZGRBbGwoMCwgYyk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFic3RyLmFkZEFsbCgtMSwgYyk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhYnN0ci5hZGRBbGwoYWJzdHIuc2l6ZSgpICsgMSwgYyk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xlYXIoKSB7CisgICAgICAgIEFic3RyYWN0TGlzdCBhYnN0ciA9IG5ldyBBcnJheUxpc3QoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYWJzdHIuc2l6ZSgpKTsKKyAgICAgICAgYWJzdHIuYWRkKCJTdHJpbmciKTsKKyAgICAgICAgYWJzdHIuYWRkKCIxIik7CisgICAgICAgIGFic3RyLmFkZCgyKTsKKyAgICAgICAgYWJzdHIuYWRkKG5ldyBEb3VibGUoMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgYWJzdHIuc2l6ZSgpKTsKKyAgICAgICAgYWJzdHIuY2xlYXIoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGFic3RyLnNpemUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9lcXVhbHNMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgQ29sbGVjdGlvbiBjID0gbmV3IFZlY3RvcigpOworICAgICAgICBjLmFkZChuZXcgRG91YmxlKDMzKSk7CisgICAgICAgIGMuYWRkKDEwKTsKKyAgICAgICAgYy5hZGQoIlN0cmluZyIpOworCisgICAgICAgIEFic3RyYWN0TGlzdCBhYnN0ciA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgQWJzdHJhY3RMaXN0IGFic3RyMSA9IG5ldyBBcnJheUxpc3QoKTsKKworICAgICAgICBhc3NlcnRGYWxzZShhYnN0ci5lcXVhbHModGhpcykpOworICAgICAgICBhYnN0ci5hZGQobmV3IERvdWJsZSgzMykpOworICAgICAgICBhYnN0ci5hZGQoMTApOworICAgICAgICBhYnN0ci5hZGQoIlN0cmluZyIpOworICAgICAgICBhc3NlcnRUcnVlKGFic3RyLmVxdWFscyhjKSk7CisgICAgICAgIGFic3RyMS5hZGRBbGwoYyk7CisgICAgICAgIGFzc2VydFRydWUoYWJzdHIuZXF1YWxzKGFic3RyMSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0SUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICBDb2xsZWN0aW9uIGMgPSBuZXcgVmVjdG9yKCk7CisgICAgICAgIGMuYWRkKG5ldyBEb3VibGUoMzMpKTsKKyAgICAgICAgYy5hZGQoMTApOworICAgICAgICBjLmFkZCgiU3RyaW5nIik7CisKKyAgICAgICAgQWJzdHJhY3RMaXN0IGFic3RyMSA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgQWJzdHJhY3RMaXN0IGFic3RyMiA9IG5ldyBBcnJheUxpc3QoKTsKKworICAgICAgICBhYnN0cjEuYWRkQWxsKGMpOworICAgICAgICBhYnN0cjIuYWRkQWxsKGMpOworICAgICAgICBhc3NlcnRUcnVlKGFic3RyMS5lcXVhbHMoYWJzdHIyKSk7CisgICAgICAgIGFic3RyMS5zZXQoMSwgMSk7CisgICAgICAgIGFzc2VydEZhbHNlKGFic3RyMS5lcXVhbHMoYWJzdHIyKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFic3RyMS5zZXQoYWJzdHIxLnNpemUoKSArIDEsIDEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWJzdHIxLnNldCgtMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIEFic3RyYWN0TGlzdCBhYnN0ciA9IG5ldyBBYnN0cmFjdExpc3QoKSB7CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIE9iamVjdCBnZXQoaW50IGluZGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorCisgICAgICAgIH07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFic3RyLnNldCgwLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBhYnN0ciA9IG5ldyBBYnN0cmFjdExpc3Q8RG91YmxlPigpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIERvdWJsZSBzZXQoaW50IGluZGV4LCBEb3VibGUgdmFsdWUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIERvdWJsZSBnZXQoaW50IGluZGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhYnN0ci5zZXQoMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJDbGFzc0Nhc3RFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBhYnN0ciA9IG5ldyBBYnN0cmFjdExpc3Q8SW50ZWdlcj4oKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgZm9yYmlkZGVuVmFsdWUgPSAzMzsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIEludGVnZXIgc2V0KGludCBpbmRleCwgSW50ZWdlciB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBmb3JiaWRkZW5WYWx1ZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgSW50ZWdlciBnZXQoaW50IGluZGV4KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhYnN0ci5zZXQoMCwgMzMpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorICAgIGNsYXNzIE1vY2tfQXJyYXlMaXN0IGV4dGVuZHMgQXJyYXlMaXN0IHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZVJhbmdlKGludCBmcm9tSW5kZXgsIGludCB0b0luZGV4KSB7CisgICAgICAgICAgICBzdXBlci5yZW1vdmVSYW5nZShmcm9tSW5kZXgsIHRvSW5kZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZW1vdmVSYW5nZUlJKCkgeworICAgICAgICBNb2NrX0FycmF5TGlzdCBhbDEgPSBuZXcgTW9ja19BcnJheUxpc3QoKTsKKyAgICAgICAgYWwxLmFkZCgxKTsKKyAgICAgICAgYWwxLmFkZCgyKTsKKyAgICAgICAgYWwxLmFkZCgzKTsKKyAgICAgICAgYWwxLmFkZCg0KTsKKyAgICAgICAgYWwxLmFkZCg1KTsKKyAgICAgICAgTW9ja19BcnJheUxpc3QgYWwyID0gbmV3IE1vY2tfQXJyYXlMaXN0KCk7CisKKyAgICAgICAgYWwyLmFkZCgxKTsKKyAgICAgICAgYWwyLmFkZCg1KTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShhbDEsYWwyKTsKKyAgICAgICAgYWwxLnJlbW92ZVJhbmdlKDEsIDQpOworICAgICAgICBhc3NlcnRFcXVhbHMoYWwxLGFsMik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0NvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGNkNDA3NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0NvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSwxMDcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKKworcHVibGljIGNsYXNzIENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb25UZXN0IGV4dGVuZHMKKyAgICAgICAganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBwdWJsaWMgY2xhc3MgQ29sbGVjdGlvbk1vZGlmaWVyIGltcGxlbWVudHMgUnVubmFibGUgeworICAgICAgICBDb2xsZWN0aW9uIGNvbDsKKworICAgICAgICBib29sZWFuIGtlZXBHb2luZyA9IHRydWU7CisKKyAgICAgICAgcHVibGljIENvbGxlY3Rpb25Nb2RpZmllcihDb2xsZWN0aW9uIGMpIHsKKyAgICAgICAgICAgIGNvbCA9IGM7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzdG9wTm93KCkgeworICAgICAgICAgICAga2VlcEdvaW5nID0gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICBPYmplY3Qgc29tZUl0ZW0gPSBuZXcgSW50ZWdlcigtMSk7CisgICAgICAgICAgICB3aGlsZSAoa2VlcEdvaW5nKSB7CisgICAgICAgICAgICAgICAgY29sLmFkZChzb21lSXRlbSk7CisgICAgICAgICAgICAgICAgY29sLnJlbW92ZShzb21lSXRlbSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbiNDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLkNvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24oKQorICAgICAgICBDb2xsZWN0aW9uIG15Q29sbGVjdGlvbiA9IG5ldyBMaW5rZWRMaXN0KCk7CisgICAgICAgIEl0ZXJhdG9yIG15SXRlcmF0b3IgPSBteUNvbGxlY3Rpb24uaXRlcmF0b3IoKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCA1MDsgY291bnRlcisrKQorICAgICAgICAgICAgbXlDb2xsZWN0aW9uLmFkZChuZXcgSW50ZWdlcihjb3VudGVyKSk7CisgICAgICAgIENvbGxlY3Rpb25Nb2RpZmllciBjbSA9IG5ldyBDb2xsZWN0aW9uTW9kaWZpZXIobXlDb2xsZWN0aW9uKTsKKyAgICAgICAgVGhyZWFkIGNvbGxlY3Rpb25TbGFwcGVyID0gbmV3IFRocmVhZChjbSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb2xsZWN0aW9uU2xhcHBlci5zdGFydCgpOworICAgICAgICAgICAgd2hpbGUgKG15SXRlcmF0b3IuaGFzTmV4dCgpKQorICAgICAgICAgICAgICAgIG15SXRlcmF0b3IubmV4dCgpOworICAgICAgICB9IGNhdGNoIChDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGNtLnN0b3BOb3coKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBjbS5zdG9wTm93KCk7CisgICAgICAgIC8vIFRoZSBleGNlcHRpb24gc2hvdWxkIGhhdmUgYmVlbiB0aHJvd24tLWlmIHRoZSBjb2RlIGZsb3cgbWFrZXMgaXQgaGVyZQorICAgICAgICAvLyB0aGUgdGVzdCBoYXMgZmFpbGVkCisgICAgICAgIGZhaWwoIkZhaWxlZCB0byB0aHJvdyBleHBlY3RlZCBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkNvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24jQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kCisgICAgICAgIC8vIGphdmEudXRpbC5Db25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIFN0cmluZyBlcnJvck1lc3NhZ2UgPSAiVGhpcyBpcyBhbiBlcnJvciBtZXNzYWdlIjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIFRoaXMgaXMgaGVyZSB0byBzdG9wICJ1bnJlYWNoYWJsZSBjb2RlIiB1bnJlc29sdmVkIHByb2JsZW0KKyAgICAgICAgICAgIGlmICh0cnVlKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uKGVycm9yTWVzc2FnZSk7CisgICAgICAgIH0gY2F0Y2ggKENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRXhjZXB0aW9uIHRocm93biB3aXRob3V0IGVycm9yIG1lc3NhZ2UiLCBlLmdldE1lc3NhZ2UoKQorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKGVycm9yTWVzc2FnZSkpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGZhaWwoIkZhaWxlZCB0byB0aHJvdyBleHBlY3RlZCBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVhcnMgZG93biB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIGNsb3NlIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzCisgICAgICogbWV0aG9kIGlzIGNhbGxlZCBhZnRlciBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQ3VycmVuY3lUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9DdXJyZW5jeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NTcxYjczCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvQ3VycmVuY3lUZXN0LmphdmEKQEAgLTAsMCArMSw0MzEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbDsKKworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Mb2NhbGU7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkN1cnJlbmN5OworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK3B1YmxpYyBjbGFzcyBDdXJyZW5jeVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgTG9jYWxlIGRlZmF1bHRMb2NhbGUgPSBMb2NhbGUuZ2V0RGVmYXVsdCgpOworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkN1cnJlbmN5I2dldEluc3RhbmNlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICAvLyBzZWUgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX3V0aWxfTG9jYWxlKCkgdGVzdHMKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ3VycmVuY3kjZ2V0SW5zdGFuY2UoamF2YS51dGlsLkxvY2FsZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfdXRpbF9Mb2NhbGUoKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIHRoZSBiZWhhdmlvdXIgaW4gYWxsIHRoZXNlIHRocmVlIGNhc2VzIHNob3VsZCBiZSB0aGUgc2FtZSBzaW5jZSB0aGlzCisgICAgICAgICAqIG1ldGhvZCBpZ25vcmVzIGxhbmd1YWdlIGFuZCB2YXJpYW50IGNvbXBvbmVudCBvZiB0aGUgbG9jYWxlLgorICAgICAgICAgKi8KKyAgICAgICAgQ3VycmVuY3kgYzAgPSBDdXJyZW5jeS5nZXRJbnN0YW5jZSgiQ0FEIik7CisgICAgICAgIEN1cnJlbmN5IGMxID0gQ3VycmVuY3kuZ2V0SW5zdGFuY2UobmV3IExvY2FsZSgiZW4iLCAiQ0EiKSk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIkN1cnJlbmN5LmdldEluc3RhbmNlKG5ldyBMb2NhbGUoXCJlblwiLFwiQ0FcIikpIGlzbid0IGVxdWFsIHRvIEN1cnJlbmN5LmdldEluc3RhbmNlKFwiQ0FEXCIpIiwKKyAgICAgICAgICAgICAgICBjMSA9PSBjMCk7CisgICAgICAgIEN1cnJlbmN5IGMyID0gQ3VycmVuY3kuZ2V0SW5zdGFuY2UobmV3IExvY2FsZSgiZnIiLCAiQ0EiKSk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIkN1cnJlbmN5LmdldEluc3RhbmNlKG5ldyBMb2NhbGUoXCJmclwiLFwiQ0FcIikpIGlzbid0IGVxdWFsIHRvIEN1cnJlbmN5LmdldEluc3RhbmNlKFwiQ0FEXCIpIiwKKyAgICAgICAgICAgICAgICBjMiA9PSBjMCk7CisgICAgICAgIEN1cnJlbmN5IGMzID0gQ3VycmVuY3kuZ2V0SW5zdGFuY2UobmV3IExvY2FsZSgiIiwgIkNBIikpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJDdXJyZW5jeS5nZXRJbnN0YW5jZShuZXcgTG9jYWxlKFwiXCIsXCJDQVwiKSkgaXNuJ3QgZXF1YWwgdG8gQ3VycmVuY3kuZ2V0SW5zdGFuY2UoXCJDQURcIikiLAorICAgICAgICAgICAgICAgIGMzID09IGMwKTsKKworICAgICAgICBjMCA9IEN1cnJlbmN5LmdldEluc3RhbmNlKCJKUFkiKTsKKyAgICAgICAgYzEgPSBDdXJyZW5jeS5nZXRJbnN0YW5jZShuZXcgTG9jYWxlKCJqYSIsICJKUCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiQ3VycmVuY3kuZ2V0SW5zdGFuY2UobmV3IExvY2FsZShcImphXCIsXCJKUFwiKSkgaXNuJ3QgZXF1YWwgdG8gQ3VycmVuY3kuZ2V0SW5zdGFuY2UoXCJKUFlcIikiLAorICAgICAgICAgICAgICAgIGMxID09IGMwKTsKKyAgICAgICAgYzIgPSBDdXJyZW5jeS5nZXRJbnN0YW5jZShuZXcgTG9jYWxlKCIiLCAiSlAiKSk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIkN1cnJlbmN5LmdldEluc3RhbmNlKG5ldyBMb2NhbGUoXCJcIixcIkpQXCIpKSBpc24ndCBlcXVhbCB0byBDdXJyZW5jeS5nZXRJbnN0YW5jZShcIkpQWVwiKSIsCisgICAgICAgICAgICAgICAgYzIgPT0gYzApOworICAgICAgICBjMyA9IEN1cnJlbmN5LmdldEluc3RhbmNlKG5ldyBMb2NhbGUoImJvZ3VzIiwgIkpQIikpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJDdXJyZW5jeS5nZXRJbnN0YW5jZShuZXcgTG9jYWxlKFwiYm9ndXNcIixcIkpQXCIpKSBpc24ndCBlcXVhbCB0byBDdXJyZW5jeS5nZXRJbnN0YW5jZShcIkpQWVwiKSIsCisgICAgICAgICAgICAgICAgYzMgPT0gYzApOworCisgICAgICAgIExvY2FsZSBsb2NhbGVHdSA9IG5ldyBMb2NhbGUoImd1IiwgIklOIik7CisgICAgICAgIEN1cnJlbmN5IGNHdSA9IEN1cnJlbmN5LmdldEluc3RhbmNlKGxvY2FsZUd1KTsKKyAgICAgICAgTG9jYWxlIGxvY2FsZUtuID0gbmV3IExvY2FsZSgia24iLCAiSU4iKTsKKyAgICAgICAgQ3VycmVuY3kgY0tuID0gQ3VycmVuY3kuZ2V0SW5zdGFuY2UobG9jYWxlS24pOworICAgICAgICBhc3NlcnRUcnVlKCJDdXJyZW5jeS5nZXRJbnN0YW5jZShMb2NhbGVfIiArIGxvY2FsZUd1LnRvU3RyaW5nKCkgKyAiKSkiCisgICAgICAgICAgICAgICAgKyAiaXNuJ3QgZXF1YWwgdG8gIiArICJDdXJyZW5jeS5nZXRJbnN0YW5jZShMb2NhbGVfIgorICAgICAgICAgICAgICAgICsgbG9jYWxlS24udG9TdHJpbmcoKSArICIpKSIsIGNHdSA9PSBjS24pOworCisgICAgICAgIC8vIHNvbWUgdGVyaXRvcmllcyBkbyBub3QgaGF2ZSBjdXJyZW5jaWVzLCBsaWtlIEFudGFyY3RpY2EKKyAgICAgICAgTG9jYWxlIGxvYyA9IG5ldyBMb2NhbGUoIiIsICJBUSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ3VycmVuY3kgY3VyciA9IEN1cnJlbmN5LmdldEluc3RhbmNlKGxvYyk7CisgICAgICAgICAgICBhc3NlcnROdWxsKAorICAgICAgICAgICAgICAgICAgICAiQ3VycmVuY3kuZ2V0SW5zdGFuY2UobmV3IExvY2FsZShcIlwiLCBcIkFRXCIpKSBkaWQgbm90IHJldHVybiBudWxsIiwKKyAgICAgICAgICAgICAgICAgICAgY3Vycik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICAvLyB1bnN1cHBvcnRlZC9sZWdhY3kgaXNvMyBjb3VudHJpZXMKKyAgICAgICAgbG9jID0gbmV3IExvY2FsZSgiIiwgIlpSIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDdXJyZW5jeSBjdXJyID0gQ3VycmVuY3kuZ2V0SW5zdGFuY2UobG9jKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgbG9jID0gbmV3IExvY2FsZSgiIiwgIlpBUiIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ3VycmVuY3kgY3VyciA9IEN1cnJlbmN5LmdldEluc3RhbmNlKGxvYyk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIGxvYyA9IG5ldyBMb2NhbGUoIiIsICJGWCIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ3VycmVuY3kgY3VyciA9IEN1cnJlbmN5LmdldEluc3RhbmNlKGxvYyk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIGxvYyA9IG5ldyBMb2NhbGUoIiIsICJGWFgiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEN1cnJlbmN5IGN1cnIgPSBDdXJyZW5jeS5nZXRJbnN0YW5jZShsb2MpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ3VycmVuY3kjZ2V0U3ltYm9sKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFN5bWJvbCgpIHsKKyAgICAgICAgQ3VycmVuY3kgY3VycksgPSBDdXJyZW5jeS5nZXRJbnN0YW5jZSgiS1JXIik7CisgICAgICAgIEN1cnJlbmN5IGN1cnJJID0gQ3VycmVuY3kuZ2V0SW5zdGFuY2UoIklFUCIpOworICAgICAgICBDdXJyZW5jeSBjdXJyVVMgPSBDdXJyZW5jeS5nZXRJbnN0YW5jZSgiVVNEIik7CisKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQoTG9jYWxlLlVTKTsKKyAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIC8vIEtSVyBjdXJyZW5jeSBzeW1ib2wgaXMgXHUyMGE5IHNpbmNlIENMRFIxLjcgcmVsZWFzZS4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjdXJySy5nZXRTeW1ib2woKSIsICJcdTIwYTkiLCBjdXJySy5nZXRTeW1ib2woKSk7CisgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjdXJySS5nZXRTeW1ib2woKSIsICJJUlx1MDBhMyIsIGN1cnJJLmdldFN5bWJvbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjdXJyVVMuZ2V0U3ltYm9sKCkiLCAiJCIsIGN1cnJVUy5nZXRTeW1ib2woKSk7CisKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobmV3IExvY2FsZSgiZW4iLCAiSUUiKSk7CisgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICBhc3NlcnRFcXVhbHMoImN1cnJLLmdldFN5bWJvbCgpIiwgIlx1MjBhOSIsIGN1cnJLLmdldFN5bWJvbCgpKTsKKyAgICAgICAgLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICBhc3NlcnRFcXVhbHMoImN1cnJJLmdldFN5bWJvbCgpIiwgIklSXHUwMGEzIiwgY3VyckkuZ2V0U3ltYm9sKCkpOworICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjdXJyVVMuZ2V0U3ltYm9sKCkiLCAiJCIsIGN1cnJVUy5nZXRTeW1ib2woKSk7CisgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKworICAgICAgICAvLyB0ZXN0IHdoYXQgaGFwcGVucyBpZiB0aGlzIGlzIGFuIGludmFsaWQgbG9jYWxlLAorICAgICAgICAvLyBvbmUgd2l0aCBLb3JlYW4gY291bnRyeSBidXQgYW4gSW5kaWEgbGFuZ3VhZ2UKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobmV3IExvY2FsZSgia3IiLCAiS1IiKSk7CisgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICBhc3NlcnRFcXVhbHMoImN1cnJLLmdldFN5bWJvbCgpIiwgIlx1MjBhOSIsIGN1cnJLLmdldFN5bWJvbCgpKTsKKyAgICAgICAgLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICBhc3NlcnRFcXVhbHMoImN1cnJJLmdldFN5bWJvbCgpIiwgIklSXHUwMGEzIiwgY3VyckkuZ2V0U3ltYm9sKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImN1cnJVUy5nZXRTeW1ib2woKSIsICIkIiwgY3VyclVTLmdldFN5bWJvbCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuQ3VycmVuY3kjZ2V0U3ltYm9sKGphdmEudXRpbC5Mb2NhbGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTeW1ib2xMamF2YV91dGlsX0xvY2FsZSgpIHsKKyAgICAgICAgLy9UZXN0cyB3YXMgc2ltcGxpZmllZCBiZWNhdXNlIGphdmEgc3BlY2lmaWNhdGlvbiBub3QKKyAgICAgICAgLy8gaW5jbHVkZXMgc3Ryb25nIHJlcXVpcmVtZW50cyBmb3IgcmV0dXJuaWcgc3ltYm9sLgorICAgICAgICAvLyBvbiBhbmRyb2lkIHBsYXRmb3JtIHVzZWQgd3JvbmcgY2hhcmFjdGVyIGZvciB5ZW4KKyAgICAgICAgLy8gc2lnbjogXHUwMGE1IGluc3RlYWQgb2YgXHVmZmU1CisgICAgICAgIExvY2FsZVtdIGRlc2lyZWRMb2NhbGVzID0gbmV3IExvY2FsZVtdeworICAgICAgICAgICAgICAgIExvY2FsZS5KQVBBTiwgIExvY2FsZS5KQVBBTkVTRSwKKyAgICAgICAgICAgICAgICBMb2NhbGUuRlJBTkNFLCBMb2NhbGUuRlJFTkNILAorICAgICAgICAgICAgICAgIExvY2FsZS5VUywgICAgIExvY2FsZS5VSywKKyAgICAgICAgICAgICAgICBMb2NhbGUuQ0FOQURBLCBMb2NhbGUuQ0FOQURBX0ZSRU5DSCwKKyAgICAgICAgICAgICAgICBMb2NhbGUuRU5HTElTSCwKKyAgICAgICAgICAgICAgICBuZXcgTG9jYWxlKCJqYSIsICJKUCIpLCBuZXcgTG9jYWxlKCIiLCAiSlAiKSwKKworICAgICAgICAgICAgICAgIG5ldyBMb2NhbGUoImZyIiwgIkZSIiksIG5ldyBMb2NhbGUoIiIsICJGUiIpLAorCisgICAgICAgICAgICAgICAgbmV3IExvY2FsZSgiZW4iLCAiVVMiKSwgbmV3IExvY2FsZSgiIiwgIlVTIiksCisgICAgICAgICAgICAgICAgbmV3IExvY2FsZSgiZXMiLCAiVVMiKSwgbmV3IExvY2FsZSgiYXIiLCAiVVMiKSwKKyAgICAgICAgICAgICAgICBuZXcgTG9jYWxlKCJqYSIsICJVUyIpLAorCisgICAgICAgICAgICAgICAgbmV3IExvY2FsZSgiZW4iLCAiQ0EiKSwgbmV3IExvY2FsZSgiZnIiLCAiQ0EiKSwKKyAgICAgICAgICAgICAgICBuZXcgTG9jYWxlKCIiLCAiQ0EiKSwgICBuZXcgTG9jYWxlKCJhciIsICJDQSIpLAorCisgICAgICAgICAgICAgICAgbmV3IExvY2FsZSgiamEiLCAiSlAiKSwgbmV3IExvY2FsZSgiIiwgIkpQIiksCisgICAgICAgICAgICAgICAgbmV3IExvY2FsZSgiYXIiLCAiSlAiKSwKKworICAgICAgICAgICAgICAgIG5ldyBMb2NhbGUoImphIiwgIkFFIiksIG5ldyBMb2NhbGUoImVuIiwgIkFFIiksCisgICAgICAgICAgICAgICAgbmV3IExvY2FsZSgiYXIiLCAiQUUiKSwKKworICAgICAgICAgICAgICAgIG5ldyBMb2NhbGUoImRhIiwgIkRLIiksIG5ldyBMb2NhbGUoIiIsICJESyIpLAorCisgICAgICAgICAgICAgICAgbmV3IExvY2FsZSgiZGEiLCAiIiksIG5ldyBMb2NhbGUoImphIiwgIiIpLAorICAgICAgICAgICAgICAgIG5ldyBMb2NhbGUoImVuIiwgIiIpfTsKKworICAgICAgICBTZXQ8TG9jYWxlPiBhdmFpbGFibGVMb2NhbGVzID0gbmV3IEhhc2hTZXQ8TG9jYWxlPihBcnJheXMuYXNMaXN0KExvY2FsZS5nZXRBdmFpbGFibGVMb2NhbGVzKCkpKTsKKworICAgICAgICBBcnJheUxpc3Q8TG9jYWxlPiBsb2NhbGVzID0gbmV3IEFycmF5TGlzdDxMb2NhbGU+KCk7CisgICAgICAgIGZvciAoTG9jYWxlIGRlc2lyZWRMb2NhbGUgOiBkZXNpcmVkTG9jYWxlcykgeworICAgICAgICAgICAgaWYgKGF2YWlsYWJsZUxvY2FsZXMuY29udGFpbnMoZGVzaXJlZExvY2FsZSkpIHsKKyAgICAgICAgICAgICAgICBsb2NhbGVzLmFkZChkZXNpcmVkTG9jYWxlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIExvY2FsZVtdIGxvYzEgPSBsb2NhbGVzLnRvQXJyYXkobmV3IExvY2FsZVtsb2NhbGVzLnNpemUoKV0pOworCisgICAgICAgIFN0cmluZ1tdIGV1cm8gICAgPSBuZXcgU3RyaW5nW10geyJFVVIiLCAiXHUyMGFjIn07CisgICAgICAgIC8vIFx1MDBhNSBhbmQgXHVmZmU1IGFyZSBhY3R1YWxseSB0aGUgc2FtZSBzeW1ib2wsIGp1c3QgZGlmZmVyZW50IGNvZGUgcG9pbnRzLgorICAgICAgICAvLyBCdXQgdGhlIFJJIHJldHVybnMgdGhlIFx1ZmZlNSBhbmQgQW5kcm9pZCByZXR1cm5zIHRob3NlIHdpdGggXHUwMGE1CisgICAgICAgIFN0cmluZ1tdIHllbiAgICAgPSBuZXcgU3RyaW5nW10geyJKUFkiLCAiXHUwMGE1IiwgIlx1MDBhNUpQIiwgIkpQXHUwMGE1IiwgIlx1ZmZlNSIsICJcdWZmZTVKUCIsICJKUFx1ZmZlNSJ9OworICAgICAgICBTdHJpbmdbXSBkb2xsYXIgID0gbmV3IFN0cmluZ1tdIHsiVVNEIiwgIiQiLCAiVVMkIiwgIiRVUyJ9OworICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgLy8gU3RhcnRpbmcgQ0xEUiAxLjcgcmVsZWFzZSwgY3VycmVuY3kgc3ltYm9sIGZvciBDQUQgY2hhbmdlZCB0byBDQSQgaW4gc29tZSBsb2NhbGVzIHN1Y2ggYXMgamEuCisgICAgICAgIFN0cmluZ1tdIGNEb2xsYXIgPSBuZXcgU3RyaW5nW10geyJDQSQiLCAiQ0FEIiwgIiQiLCAiQ2FuJCIsICIkQ0EifTsKKyAgICAgICAgLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorCisgICAgICAgIEN1cnJlbmN5IGN1cnJFICAgPSBDdXJyZW5jeS5nZXRJbnN0YW5jZSgiRVVSIik7CisgICAgICAgIEN1cnJlbmN5IGN1cnJKICAgPSBDdXJyZW5jeS5nZXRJbnN0YW5jZSgiSlBZIik7CisgICAgICAgIEN1cnJlbmN5IGN1cnJVUyAgPSBDdXJyZW5jeS5nZXRJbnN0YW5jZSgiVVNEIik7CisgICAgICAgIEN1cnJlbmN5IGN1cnJDQSAgPSBDdXJyZW5jeS5nZXRJbnN0YW5jZSgiQ0FEIik7CisKKyAgICAgICAgaW50IGksIGosIGs7CisgICAgICAgIGJvb2xlYW4gZmxhZzsKKworICAgICAgICBmb3IoayA9IDA7IGsgPCBsb2MxLmxlbmd0aDsgaysrKSB7CisgICAgICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChsb2MxW2tdKTsKKworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxvYzEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBmbGFnID0gZmFsc2U7CisgICAgICAgICAgICAgICAgZm9yICAoaiA9IDA7IGogPCBldXJvLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyRS5nZXRTeW1ib2wobG9jMVtpXSkuZXF1YWxzKGV1cm9bal0pKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmbGFnID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIkRlZmF1bHQgTG9jYWxlIGlzOiAiICsgTG9jYWxlLmdldERlZmF1bHQoKQorICAgICAgICAgICAgICAgICAgICAgICAgKyAiLiBGb3IgbG9jYWxlICIgKyBsb2MxW2ldCisgICAgICAgICAgICAgICAgICAgICAgICArICIgdGhlIEV1cm8gY3VycmVuY3kgcmV0dXJuZWQgIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBjdXJyRS5nZXRTeW1ib2wobG9jMVtpXSkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIi4gRXhwZWN0ZWQgd2FzIG9uZSBvZiB0aGVzZTogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBBcnJheXMudG9TdHJpbmcoZXVybyksIGZsYWcpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbG9jMS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGZsYWcgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBmb3IgIChqID0gMDsgaiA8IHllbi5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgICAgICBieXRlW10gYjEgPSBudWxsOworICAgICAgICAgICAgICAgICAgICBieXRlW10gYjIgPSBudWxsOworICAgICAgICAgICAgICAgICAgICBpZiAoY3VyckouZ2V0U3ltYm9sKGxvYzFbaV0pLmVxdWFscyh5ZW5bal0pKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmbGFnID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIkRlZmF1bHQgTG9jYWxlIGlzOiAiICsgTG9jYWxlLmdldERlZmF1bHQoKQorICAgICAgICAgICAgICAgICAgICAgICAgKyAiLiBGb3IgbG9jYWxlICIgKyBsb2MxW2ldCisgICAgICAgICAgICAgICAgICAgICAgICArICIgdGhlIFllbiBjdXJyZW5jeSByZXR1cm5lZCAiCisgICAgICAgICAgICAgICAgICAgICAgICArIGN1cnJKLmdldFN5bWJvbChsb2MxW2ldKQorICAgICAgICAgICAgICAgICAgICAgICAgKyAiLiBFeHBlY3RlZCB3YXMgb25lIG9mIHRoZXNlOiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIEFycmF5cy50b1N0cmluZyh5ZW4pLCBmbGFnKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxvYzEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBmbGFnID0gZmFsc2U7CisgICAgICAgICAgICAgICAgZm9yICAoaiA9IDA7IGogPCBkb2xsYXIubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJVUy5nZXRTeW1ib2wobG9jMVtpXSkuZXF1YWxzKGRvbGxhcltqXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZsYWcgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRGVmYXVsdCBMb2NhbGUgaXM6ICIgKyBMb2NhbGUuZ2V0RGVmYXVsdCgpCisgICAgICAgICAgICAgICAgICAgICAgICArICIuIEZvciBsb2NhbGUgIiArIGxvYzFbaV0KKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiB0aGUgRG9sbGFyIGN1cnJlbmN5IHJldHVybmVkICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgY3VyclVTLmdldFN5bWJvbChsb2MxW2ldKQorICAgICAgICAgICAgICAgICAgICAgICAgKyAiLiBFeHBlY3RlZCB3YXMgb25lIG9mIHRoZXNlOiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIEFycmF5cy50b1N0cmluZyhkb2xsYXIpLCBmbGFnKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxvYzEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBmbGFnID0gZmFsc2U7CisgICAgICAgICAgICAgICAgZm9yICAoaiA9IDA7IGogPCBjRG9sbGFyLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyQ0EuZ2V0U3ltYm9sKGxvYzFbaV0pLmVxdWFscyhjRG9sbGFyW2pdKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZmxhZyA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJEZWZhdWx0IExvY2FsZSBpczogIiArIExvY2FsZS5nZXREZWZhdWx0KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIi4gRm9yIGxvY2FsZSAiICsgbG9jMVtpXQorICAgICAgICAgICAgICAgICAgICAgICAgKyAiIHRoZSBDYW5hZGlhbiBEb2xsYXIgY3VycmVuY3kgcmV0dXJuZWQgIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBjdXJyQ0EuZ2V0U3ltYm9sKGxvYzFbaV0pCisgICAgICAgICAgICAgICAgICAgICAgICArICIuIEV4cGVjdGVkIHdhcyBvbmUgb2YgdGhlc2U6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgQXJyYXlzLnRvU3RyaW5nKGNEb2xsYXIpLCBmbGFnKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5DdXJyZW5jeSNnZXREZWZhdWx0RnJhY3Rpb25EaWdpdHMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGVmYXVsdEZyYWN0aW9uRGlnaXRzKCkgeworCisgICAgICAgIEN1cnJlbmN5IGMxID0gQ3VycmVuY3kuZ2V0SW5zdGFuY2UoIlRORCIpOworICAgICAgICBjMS5nZXREZWZhdWx0RnJhY3Rpb25EaWdpdHMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIgQ3VycmVuY3kuZ2V0SW5zdGFuY2UoXCIiICsgYzEKKyAgICAgICAgICAgICAgICArICJcIikgcmV0dXJuZWQgaW5jb3JyZWN0IG51bWJlciBvZiBkaWdpdHMuICIsIDMsIGMxCisgICAgICAgICAgICAgICAgLmdldERlZmF1bHRGcmFjdGlvbkRpZ2l0cygpKTsKKworICAgICAgICBDdXJyZW5jeSBjMiA9IEN1cnJlbmN5LmdldEluc3RhbmNlKCJFVVIiKTsKKyAgICAgICAgYzIuZ2V0RGVmYXVsdEZyYWN0aW9uRGlnaXRzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiIEN1cnJlbmN5LmdldEluc3RhbmNlKFwiIiArIGMyCisgICAgICAgICAgICAgICAgKyAiXCIpIHJldHVybmVkIGluY29ycmVjdCBudW1iZXIgb2YgZGlnaXRzLiAiLCAyLCBjMgorICAgICAgICAgICAgICAgIC5nZXREZWZhdWx0RnJhY3Rpb25EaWdpdHMoKSk7CisKKyAgICAgICAgQ3VycmVuY3kgYzMgPSBDdXJyZW5jeS5nZXRJbnN0YW5jZSgiSlBZIik7CisgICAgICAgIGMzLmdldERlZmF1bHRGcmFjdGlvbkRpZ2l0cygpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiBDdXJyZW5jeS5nZXRJbnN0YW5jZShcIiIgKyBjMworICAgICAgICAgICAgICAgICsgIlwiKSByZXR1cm5lZCBpbmNvcnJlY3QgbnVtYmVyIG9mIGRpZ2l0cy4gIiwgMCwgYzMKKyAgICAgICAgICAgICAgICAuZ2V0RGVmYXVsdEZyYWN0aW9uRGlnaXRzKCkpOworCisgICAgICAgIEN1cnJlbmN5IGM0ID0gQ3VycmVuY3kuZ2V0SW5zdGFuY2UoIlhYWCIpOworICAgICAgICBjNC5nZXREZWZhdWx0RnJhY3Rpb25EaWdpdHMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIgQ3VycmVuY3kuZ2V0SW5zdGFuY2UoXCIiICsgYzQKKyAgICAgICAgICAgICAgICArICJcIikgcmV0dXJuZWQgaW5jb3JyZWN0IG51bWJlciBvZiBkaWdpdHMuICIsIC0xLCBjNAorICAgICAgICAgICAgICAgIC5nZXREZWZhdWx0RnJhY3Rpb25EaWdpdHMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkN1cnJlbmN5I2dldEN1cnJlbmN5Q29kZSgpIE5vdGU6IGxpbmVzIHVuZGVyIHJlbWFya3MKKyAgICAgKiAgICAgICAgKExvY2FsZS5DSElORVNFLCBMb2NhbGUuRU5HTElTSCwgTG9jYWxlLkZSRU5DSCwgTG9jYWxlLkdFUk1BTiwKKyAgICAgKiAgICAgICAgTG9jYWxlLklUQUxJQU4sIExvY2FsZS5KQVBBTkVTRSwgTG9jYWxlLktPUkVBTikgcmFpc2VzIGV4Y2VwdGlvbgorICAgICAqICAgICAgICBvbiBTVU4gVk0KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEN1cnJlbmN5Q29kZSgpIHsKKyAgICAgICAgZmluYWwgQ29sbGVjdGlvbjxMb2NhbGU+IGxvY1ZhbCA9IEFycmF5cy5hc0xpc3QoCisgICAgICAgICAgICAgICAgTG9jYWxlLkNBTkFEQSwKKyAgICAgICAgICAgICAgICBMb2NhbGUuQ0FOQURBX0ZSRU5DSCwKKyAgICAgICAgICAgICAgICBMb2NhbGUuQ0hJTkEsCisgICAgICAgICAgICAgICAgLy8gTG9jYWxlLkNISU5FU0UsCisgICAgICAgICAgICAgICAgLy8gTG9jYWxlLkVOR0xJU0gsCisgICAgICAgICAgICAgICAgTG9jYWxlLkZSQU5DRSwKKyAgICAgICAgICAgICAgICAvLyBMb2NhbGUuRlJFTkNILAorICAgICAgICAgICAgICAgIC8vIExvY2FsZS5HRVJNQU4sCisgICAgICAgICAgICAgICAgTG9jYWxlLkdFUk1BTlksCisgICAgICAgICAgICAgICAgLy8gTG9jYWxlLklUQUxJQU4sCisgICAgICAgICAgICAgICAgTG9jYWxlLklUQUxZLCBMb2NhbGUuSkFQQU4sCisgICAgICAgICAgICAgICAgLy8gTG9jYWxlLkpBUEFORVNFLAorICAgICAgICAgICAgICAgIExvY2FsZS5LT1JFQSwKKyAgICAgICAgICAgICAgICAvLyBMb2NhbGUuS09SRUFOLAorICAgICAgICAgICAgICAgIExvY2FsZS5QUkMsIExvY2FsZS5TSU1QTElGSUVEX0NISU5FU0UsIExvY2FsZS5UQUlXQU4sIExvY2FsZS5UUkFESVRJT05BTF9DSElORVNFLAorICAgICAgICAgICAgICAgIExvY2FsZS5VSywgTG9jYWxlLlVTKTsKKyAgICAgICAgZmluYWwgQ29sbGVjdGlvbjxTdHJpbmc+IGxvY0RhdCA9IEFycmF5cy5hc0xpc3QoIkNBRCIsICJDQUQiLCAiQ05ZIiwgIkVVUiIsICJFVVIiLCAiRVVSIiwKKyAgICAgICAgICAgICAgICAiSlBZIiwgIktSVyIsICJDTlkiLCAiQ05ZIiwgIlRXRCIsICJUV0QiLCAiR0JQIiwgIlVTRCIpOworCisgICAgICAgIEl0ZXJhdG9yPFN0cmluZz4gZGF0ID0gbG9jRGF0Lml0ZXJhdG9yKCk7CisgICAgICAgIGZvciAoTG9jYWxlIGwgOiBsb2NWYWwpIHsKKyAgICAgICAgICAgIFN0cmluZyBkID0gZGF0Lm5leHQoKS50cmltKCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkZvciBsb2NhbGUgIiArIGwgKyAiIGN1cnJlbmN5IGNvZGUgd3JvbmciLCBDdXJyZW5jeS5nZXRJbnN0YW5jZShsKQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q3VycmVuY3lDb2RlKCksIGQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkN1cnJlbmN5I3RvU3RyaW5nKCkgTm90ZTogbGluZXMgdW5kZXIgcmVtYXJrcworICAgICAqICAgICAgICAoTG9jYWxlLkNISU5FU0UsIExvY2FsZS5FTkdMSVNILCBMb2NhbGUuRlJFTkNILCBMb2NhbGUuR0VSTUFOLAorICAgICAqICAgICAgICBMb2NhbGUuSVRBTElBTiwgTG9jYWxlLkpBUEFORVNFLCBMb2NhbGUuS09SRUFOKSByYWlzZXMgZXhjZXB0aW9uCisgICAgICogICAgICAgIG9uIFNVTiBWTQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9TdHJpbmcoKSB7CisgICAgICAgIGZpbmFsIENvbGxlY3Rpb248TG9jYWxlPiBsb2NWYWwgPSBBcnJheXMuYXNMaXN0KAorICAgICAgICAgICAgICAgIExvY2FsZS5DQU5BREEsCisgICAgICAgICAgICAgICAgTG9jYWxlLkNBTkFEQV9GUkVOQ0gsCisgICAgICAgICAgICAgICAgTG9jYWxlLkNISU5BLAorICAgICAgICAgICAgICAgIC8vIExvY2FsZS5DSElORVNFLAorICAgICAgICAgICAgICAgIC8vIExvY2FsZS5FTkdMSVNILAorICAgICAgICAgICAgICAgIExvY2FsZS5GUkFOQ0UsCisgICAgICAgICAgICAgICAgLy8gTG9jYWxlLkZSRU5DSCwKKyAgICAgICAgICAgICAgICAvLyBMb2NhbGUuR0VSTUFOLAorICAgICAgICAgICAgICAgIExvY2FsZS5HRVJNQU5ZLAorICAgICAgICAgICAgICAgIC8vIExvY2FsZS5JVEFMSUFOLAorICAgICAgICAgICAgICAgIExvY2FsZS5JVEFMWSwgTG9jYWxlLkpBUEFOLAorICAgICAgICAgICAgICAgIC8vIExvY2FsZS5KQVBBTkVTRSwKKyAgICAgICAgICAgICAgICBMb2NhbGUuS09SRUEsCisgICAgICAgICAgICAgICAgLy8gTG9jYWxlLktPUkVBTiwKKyAgICAgICAgICAgICAgICBMb2NhbGUuUFJDLCBMb2NhbGUuU0lNUExJRklFRF9DSElORVNFLCBMb2NhbGUuVEFJV0FOLCBMb2NhbGUuVFJBRElUSU9OQUxfQ0hJTkVTRSwKKyAgICAgICAgICAgICAgICBMb2NhbGUuVUssIExvY2FsZS5VUyk7CisgICAgICAgIGZpbmFsIENvbGxlY3Rpb248U3RyaW5nPiBsb2NEYXQgPSBBcnJheXMuYXNMaXN0KCJDQUQiLCAiQ0FEIiwgIkNOWSIsICJFVVIiLCAiRVVSIiwgIkVVUiIsCisgICAgICAgICAgICAgICAgIkpQWSIsICJLUlciLCAiQ05ZIiwgIkNOWSIsICJUV0QiLCAiVFdEIiwgIkdCUCIsICJVU0QiKTsKKworICAgICAgICBJdGVyYXRvcjxTdHJpbmc+IGRhdCA9IGxvY0RhdC5pdGVyYXRvcigpOworICAgICAgICBmb3IgKExvY2FsZSBsIDogbG9jVmFsKSB7CisgICAgICAgICAgICBTdHJpbmcgZCA9IGRhdC5uZXh0KCkudHJpbSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJGb3IgbG9jYWxlICIgKyBsICsgIiBDdXJyZW5jeS50b1N0cmluZyBtZXRob2QgcmV0dXJucyB3cm9uZyB2YWx1ZSIsCisgICAgICAgICAgICAgICAgICAgIEN1cnJlbmN5LmdldEluc3RhbmNlKGwpLnRvU3RyaW5nKCksIGQpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KGRlZmF1bHRMb2NhbGUpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEhlbHBlciBtZXRob2QgdG8gZGlzcGxheSBDdXJyZW5jeSBpbmZvCisgICAgICoKKyAgICAgKiBAcGFyYW0gYworICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwcmludEN1cnJlbmN5KEN1cnJlbmN5IGMpIHsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihjLmdldEN1cnJlbmN5Q29kZSgpKTsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGMuZ2V0U3ltYm9sKCkpOworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oYy5nZXREZWZhdWx0RnJhY3Rpb25EaWdpdHMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogaGVscGVyIG1ldGhvZCB0byBkaXNwbGF5IExvY2FsZSBpbmZvCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludExvY2FsZShMb2NhbGUgbG9jKSB7CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obG9jLmdldERpc3BsYXlOYW1lKCkpOworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obG9jLmdldENvdW50cnkoKSk7CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihsb2MuZ2V0TGFuZ3VhZ2UoKSk7CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihsb2MuZ2V0RGlzcGxheUNvdW50cnkoKSk7CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihsb2MuZ2V0RGlzcGxheUxhbmd1YWdlKCkpOworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obG9jLmdldERpc3BsYXlOYW1lKCkpOworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obG9jLmdldElTTzNDb3VudHJ5KCkpOworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obG9jLmdldElTTzNMYW5ndWFnZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9EYXRlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvRGF0ZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MTAwNTI3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvRGF0ZVRlc3QuamF2YQpAQCAtMCwwICsxLDUxNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5UaW1lWm9uZTsKKworcHVibGljIGNsYXNzIERhdGVUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5EYXRlI0RhdGUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuRGF0ZSgpCisgICAgICAgIEdyZWdvcmlhbkNhbGVuZGFyIGdjID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTgsIENhbGVuZGFyLk9DVE9CRVIsCisgICAgICAgICAgICAgICAgMTMsIDE5LCA5KTsKKyAgICAgICAgbG9uZyBvbGRUaW1lID0gZ2MuZ2V0VGltZSgpLmdldFRpbWUoKTsKKyAgICAgICAgbG9uZyBub3cgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ3JlYXRlZCBpbmNvcnJlY3QgZGF0ZTogIiArIG9sZFRpbWUgKyAiIG5vdzogIiArIG5vdywKKyAgICAgICAgICAgICAgICBvbGRUaW1lIDwgbm93KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRGF0ZSNEYXRlKGludCwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcklJSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5EYXRlKGludCwgaW50LCBpbnQpCisgICAgICAgIERhdGUgZDEgPSBuZXcgRGF0ZSg3MCwgMCwgMSk7IC8vIHRoZSBlcG9jaCArIGxvY2FsIHRpbWUKKworICAgICAgICAvLyB0aGUgZXBvY2ggKyBsb2NhbCB0aW1lCisgICAgICAgIERhdGUgZDIgPSBuZXcgRGF0ZSgwICsgZDEuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwICogMTAwMCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ3JlYXRlZCBpbmNvcnJlY3QgZGF0ZSIsIGQxLmVxdWFscyhkMikpOworCisgICAgICAgIERhdGUgZGF0ZSA9IG5ldyBEYXRlKDk5LCA1LCAyMik7CisgICAgICAgIENhbGVuZGFyIGNhbCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk5LCBDYWxlbmRhci5KVU5FLCAyMik7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHRpbWUgem9uZSIsIGRhdGUuZXF1YWxzKGNhbC5nZXRUaW1lKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRGF0ZSNEYXRlKGludCwgaW50LCBpbnQsIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JJSUlJSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5EYXRlKGludCwgaW50LCBpbnQsIGludCwgaW50KQorCisgICAgICAgIC8vIHRoZSBlcG9jaCArIGxvY2FsIHRpbWUgKyAoMSBob3VyIGFuZCAxIG1pbnV0ZSkKKyAgICAgICAgRGF0ZSBkMSA9IG5ldyBEYXRlKDcwLCAwLCAxLCAxLCAxKTsKKworICAgICAgICAvLyB0aGUgZXBvY2ggKyBsb2NhbCB0aW1lICsgKDEgaG91ciBhbmQgMSBtaW51dGUpCisgICAgICAgIERhdGUgZDIgPSBuZXcgRGF0ZSgwICsgZDEuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwICogMTAwMCArIDYwICogNjAKKyAgICAgICAgICAgICAgICAqIDEwMDAgKyA2MCAqIDEwMDApOworCisgICAgICAgIGFzc2VydFRydWUoIkNyZWF0ZWQgaW5jb3JyZWN0IGRhdGUiLCBkMS5lcXVhbHMoZDIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRGF0ZSNEYXRlKGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcklJSUlJSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5EYXRlKGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQpCisKKyAgICAgICAgLy8gdGhlIGVwb2NoICsgbG9jYWwgdGltZSArICgxIGhvdXIgYW5kIDEgbWludXRlICsgMSBzZWNvbmQpCisgICAgICAgIERhdGUgZDEgPSBuZXcgRGF0ZSg3MCwgMCwgMSwgMSwgMSwgMSk7CisKKyAgICAgICAgLy8gdGhlIGVwb2NoICsgbG9jYWwgdGltZSArICgxIGhvdXIgYW5kIDEgbWludXRlICsgMSBzZWNvbmQpCisgICAgICAgIERhdGUgZDIgPSBuZXcgRGF0ZSgwICsgZDEuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwICogMTAwMCArIDYwICogNjAKKyAgICAgICAgICAgICAgICAqIDEwMDAgKyA2MCAqIDEwMDAgKyAxMDAwKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJDcmVhdGVkIGluY29ycmVjdCBkYXRlIiwgZDEuZXF1YWxzKGQyKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkRhdGUjRGF0ZShsb25nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JKKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLkRhdGUobG9uZykKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVXNlZCB0byB0ZXN0IiwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkRhdGUjRGF0ZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5EYXRlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIERhdGUgZDEgPSBuZXcgRGF0ZSgiSmFudWFyeSAxLCAxOTcwLCAwMDowMDowMCBHTVQiKTsgLy8gdGhlIGVwb2NoCisgICAgICAgIERhdGUgZDIgPSBuZXcgRGF0ZSgwKTsgLy8gdGhlIGVwb2NoCisgICAgICAgIGFzc2VydFRydWUoIkNyZWF0ZWQgaW5jb3JyZWN0IGRhdGUiLCBkMS5lcXVhbHMoZDIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS0yMzgKKyAgICAgICAgICAgIG5ldyBEYXRlKG51bGwpOworICAgICAgICAgICAgZmFpbCgiQ29uc3RydWN0b3IgRGF0ZSgoU3RyaW5nKW51bGwpIHNob3VsZCAiCisgICAgICAgICAgICAgICAgKyAidGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkRhdGUjYWZ0ZXIoamF2YS51dGlsLkRhdGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZnRlckxqYXZhX3V0aWxfRGF0ZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4gamF2YS51dGlsLkRhdGUuYWZ0ZXIoamF2YS51dGlsLkRhdGUpCisgICAgICAgIERhdGUgZDEgPSBuZXcgRGF0ZSgwKTsKKyAgICAgICAgRGF0ZSBkMiA9IG5ldyBEYXRlKDE5MDAwMDApOworICAgICAgICBhc3NlcnRUcnVlKCJPbGRlciB3YXMgcmV0dXJuZWQgYXMgbmV3ZXIiLCBkMi5hZnRlcihkMSkpOworICAgICAgICBhc3NlcnRUcnVlKCJOZXdlciB3YXMgcmV0dXJuZWQgYXMgb2xkZXIiLCAhZDEuYWZ0ZXIoZDIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZDEuYWZ0ZXIobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRGF0ZSNiZWZvcmUoamF2YS51dGlsLkRhdGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9iZWZvcmVMamF2YV91dGlsX0RhdGUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEudXRpbC5EYXRlLmJlZm9yZShqYXZhLnV0aWwuRGF0ZSkKKyAgICAgICAgRGF0ZSBkMSA9IG5ldyBEYXRlKDApOworICAgICAgICBEYXRlIGQyID0gbmV3IERhdGUoMTkwMDAwMCk7CisgICAgICAgIGFzc2VydFRydWUoIk9sZGVyIHdhcyByZXR1cm5lZCBhcyBuZXdlciIsICFkMi5iZWZvcmUoZDEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTmV3ZXIgd2FzIHJldHVybmVkIGFzIG9sZGVyIiwgZDEuYmVmb3JlKGQyKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGQxLmJlZm9yZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5EYXRlI2Nsb25lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb25lKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdCBqYXZhLnV0aWwuRGF0ZS5jbG9uZSgpCisgICAgICAgIERhdGUgZDEgPSBuZXcgRGF0ZSgxMDAwMDApOworICAgICAgICBEYXRlIGQyID0gKERhdGUpIGQxLmNsb25lKCk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIkNsb25pbmcgZGF0ZSByZXN1bHRzIGluIHNhbWUgcmVmZXJlbmNlLS1uZXcgZGF0ZSBpcyBlcXVpdmFsZW50IiwKKyAgICAgICAgICAgICAgICBkMSAhPSBkMik7CisgICAgICAgIGFzc2VydFRydWUoIkNsb25pbmcgZGF0ZSByZXN1bHRzIHVuZXF1YWwgZGF0ZSIsIGQxLmVxdWFscyhkMikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5EYXRlI2NvbXBhcmVUbyhqYXZhLnV0aWwuRGF0ZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbXBhcmVUb0xqYXZhX3V0aWxfRGF0ZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuRGF0ZS5jb21wYXJlVG8oamF2YS51dGlsLkRhdGUpCisgICAgICAgIGZpbmFsIGludCBzb21lTnVtYmVyID0gMTAwMDA7CisgICAgICAgIERhdGUgZDEgPSBuZXcgRGF0ZShzb21lTnVtYmVyKTsKKyAgICAgICAgRGF0ZSBkMiA9IG5ldyBEYXRlKHNvbWVOdW1iZXIpOworICAgICAgICBEYXRlIGQzID0gbmV3IERhdGUoc29tZU51bWJlciArIDEpOworICAgICAgICBEYXRlIGQ0ID0gbmV3IERhdGUoc29tZU51bWJlciAtIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkNvbXBhcmluZyBhIGRhdGUgdG8gaXRzZWxmIGRpZCBub3QgYW5zd2VyIHplcm8iLCAwLCBkMQorICAgICAgICAgICAgICAgIC5jb21wYXJlVG8oZDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDb21wYXJpbmcgZXF1YWwgZGF0ZXMgZGlkIG5vdCBhbnN3ZXIgemVybyIsIDAsIGQxCisgICAgICAgICAgICAgICAgLmNvbXBhcmVUbyhkMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRhdGUxLmNvbXBhcmVUbyhkYXRlMiksIHdoZXJlIGRhdGUxID4gZGF0ZTIsIGRpZCBub3QgcmVzdWx0IGluIDEiLAorICAgICAgICAgICAgICAgIDEsIGQxLmNvbXBhcmVUbyhkNCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRhdGUxLmNvbXBhcmVUbyhkYXRlMiksIHdoZXJlIGRhdGUxIDwgZGF0ZTIsIGRpZCBub3QgcmVzdWx0IGluIC0xIiwKKyAgICAgICAgICAgICAgICAtMSwgZDEuY29tcGFyZVRvKGQzKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGQxLmNvbXBhcmVUbyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5EYXRlI2VxdWFscyhqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEudXRpbC5EYXRlLmVxdWFscyhqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBEYXRlIGQxID0gbmV3IERhdGUoMCk7CisgICAgICAgIERhdGUgZDIgPSBuZXcgRGF0ZSgxOTAwMDAwKTsKKyAgICAgICAgRGF0ZSBkMyA9IG5ldyBEYXRlKDE5MDAwMDApOworICAgICAgICBhc3NlcnRUcnVlKCJFcXVhbGl0eSB0ZXN0IGZhaWxlZCIsIGQyLmVxdWFscyhkMykpOworICAgICAgICBhc3NlcnRUcnVlKCJFcXVhbGl0eSB0ZXN0IGZhaWxlZCIsICFkMS5lcXVhbHMoZDIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRGF0ZSNnZXREYXRlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERhdGUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLkRhdGUuZ2V0RGF0ZSgpCisgICAgICAgIERhdGUgZCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk4LCBDYWxlbmRhci5PQ1RPQkVSLCAxMywgMTksIDkpCisgICAgICAgICAgICAgICAgLmdldFRpbWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgZGF0ZSIsIDEzLCBkLmdldERhdGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkRhdGUjZ2V0RGF5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERheSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuRGF0ZS5nZXREYXkoKQorICAgICAgICBEYXRlIGQgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OCwgQ2FsZW5kYXIuT0NUT0JFUiwgMTMsIDE5LCA5KQorICAgICAgICAgICAgICAgIC5nZXRUaW1lKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGRheSIsIDIsIGQuZ2V0RGF5KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5EYXRlI2dldEhvdXJzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEhvdXJzKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudXRpbC5EYXRlLmdldEhvdXJzKCkKKyAgICAgICAgRGF0ZSBkID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTgsIENhbGVuZGFyLk9DVE9CRVIsIDEzLCAxOSwgOSkKKyAgICAgICAgICAgICAgICAuZ2V0VGltZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBob3VycyIsIDE5LCBkLmdldEhvdXJzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5EYXRlI2dldE1pbnV0ZXMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TWludXRlcygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuRGF0ZS5nZXRNaW51dGVzKCkKKyAgICAgICAgRGF0ZSBkID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTgsIENhbGVuZGFyLk9DVE9CRVIsIDEzLCAxOSwgOSkKKyAgICAgICAgICAgICAgICAuZ2V0VGltZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBtaW51dGVzIiwgOSwgZC5nZXRNaW51dGVzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5EYXRlI2dldE1vbnRoKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1vbnRoKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudXRpbC5EYXRlLmdldE1vbnRoKCkKKyAgICAgICAgRGF0ZSBkID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTgsIENhbGVuZGFyLk9DVE9CRVIsIDEzLCAxOSwgOSkKKyAgICAgICAgICAgICAgICAuZ2V0VGltZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBtb250aCIsIDksIGQuZ2V0TW9udGgoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkRhdGUjZ2V0U2Vjb25kcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTZWNvbmRzKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudXRpbC5EYXRlLmdldFNlY29uZHMoKQorICAgICAgICBEYXRlIGQgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OCwgQ2FsZW5kYXIuT0NUT0JFUiwgMTMsIDE5LCA5KQorICAgICAgICAgICAgICAgIC5nZXRUaW1lKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHNlY29uZHMiLCAwLCBkLmdldFNlY29uZHMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkRhdGUjZ2V0VGltZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRUaW1lKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgbG9uZyBqYXZhLnV0aWwuRGF0ZS5nZXRUaW1lKCkKKyAgICAgICAgRGF0ZSBkMSA9IG5ldyBEYXRlKDApOworICAgICAgICBEYXRlIGQyID0gbmV3IERhdGUoMTkwMDAwMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHRpbWUiLCAxOTAwMDAwLCBkMi5nZXRUaW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCB0aW1lIiwgMCwgZDEuZ2V0VGltZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRGF0ZSNnZXRUaW1lem9uZU9mZnNldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRUaW1lem9uZU9mZnNldCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuRGF0ZS5nZXRUaW1lem9uZU9mZnNldCgpCisgICAgICAgIGFzc2VydFRydWUoIlVzZWQgdG8gdGVzdCIsIHRydWUpOworICAgICAgICBpbnQgb2Zmc2V0ID0gbmV3IERhdGUoOTYsIDEsIDE0KS5nZXRUaW1lem9uZU9mZnNldCgpOworICAgICAgICBhc3NlcnRUcnVlKG9mZnNldCA+IC03MjAgJiYgb2Zmc2V0IDwgNzIwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRGF0ZSNnZXRZZWFyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFllYXIoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLkRhdGUuZ2V0WWVhcigpCisgICAgICAgIERhdGUgZCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk4LCBDYWxlbmRhci5PQ1RPQkVSLCAxMywgMTksIDkpCisgICAgICAgICAgICAgICAgLmdldFRpbWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgeWVhciIsIDk4LCBkLmdldFllYXIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkRhdGUjaGFzaENvZGUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGFzaENvZGUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLkRhdGUuaGFzaENvZGUoKQorICAgICAgICBEYXRlIGQxID0gbmV3IERhdGUoMCk7CisgICAgICAgIERhdGUgZDIgPSBuZXcgRGF0ZSgxOTAwMDAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgaGFzaCIsIDE5MDAwMDAsIGQyLmhhc2hDb2RlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIGluY29ycmVjdCBoYXNoIiwgMCwgZDEuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkRhdGUjcGFyc2UoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BhcnNlTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBsb25nIGphdmEudXRpbC5EYXRlLnBhcnNlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIERhdGUgZCA9IG5ldyBEYXRlKERhdGUucGFyc2UoIjEzIE9jdG9iZXIgMTk5OCIpKTsKKyAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKCk7CisgICAgICAgIGNhbC5zZXRUaW1lKGQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlBhcnNlZCBpbmNvcnJlY3QgbW9udGgiLCA5LCBjYWwuZ2V0KENhbGVuZGFyLk1PTlRIKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUGFyc2VkIGluY29ycmVjdCB5ZWFyIiwgMTk5OCwgY2FsLmdldChDYWxlbmRhci5ZRUFSKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUGFyc2VkIGluY29ycmVjdCBkYXRlIiwgMTMsIGNhbC5nZXQoQ2FsZW5kYXIuREFURSkpOworCisgICAgICAgIGQgPSBuZXcgRGF0ZShEYXRlLnBhcnNlKCJKYW4tMTIgMTk5OSIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcGFyc2VkIGRhdGUgMSIsIGQuZXF1YWxzKG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk5LAorICAgICAgICAgICAgICAgIDAsIDEyKS5nZXRUaW1lKCkpKTsKKyAgICAgICAgZCA9IG5ldyBEYXRlKERhdGUucGFyc2UoIkphbjEyLTE5OTkiKSk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHBhcnNlZCBkYXRlIDIiLCBkLmVxdWFscyhuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OSwKKyAgICAgICAgICAgICAgICAwLCAxMikuZ2V0VGltZSgpKSk7CisgICAgICAgIGQgPSBuZXcgRGF0ZShEYXRlLnBhcnNlKCJKYW4xMiA2OS0xIikpOworICAgICAgICBjYWwuc2V0VGltZVpvbmUoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkdNVCIpKTsKKyAgICAgICAgY2FsLmNsZWFyKCk7CisgICAgICAgIGNhbC5zZXQoMTk2OSwgQ2FsZW5kYXIuSkFOVUFSWSwgMTIsIDEsIDApOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBwYXJzZWQgZGF0ZSAzIiwgZC5lcXVhbHMoY2FsLmdldFRpbWUoKSkpOworICAgICAgICBkID0gbmV3IERhdGUoRGF0ZS5wYXJzZSgiNjo0NToxMyAzLzIvMTIwMCBNU1QiKSk7CisgICAgICAgIGNhbC5zZXRUaW1lWm9uZShUaW1lWm9uZS5nZXRUaW1lWm9uZSgiTVNUIikpOworICAgICAgICBjYWwuY2xlYXIoKTsKKyAgICAgICAgY2FsLnNldCgxMjAwLCAyLCAyLCA2LCA0NSwgMTMpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBwYXJzZWQgZGF0ZSA0IiwgZC5lcXVhbHMoY2FsLmdldFRpbWUoKSkpOworICAgICAgICBkID0gbmV3IERhdGUoRGF0ZS5wYXJzZSgiTW9uLCAyMiBOb3YgMTk5OSAxMjo1MjowNiBHTVQiKSk7CisgICAgICAgIGNhbC5zZXRUaW1lWm9uZShUaW1lWm9uZS5nZXRUaW1lWm9uZSgiR01UIikpOworICAgICAgICBjYWwuY2xlYXIoKTsKKyAgICAgICAgY2FsLnNldCgxOTk5LCBDYWxlbmRhci5OT1ZFTUJFUiwgMjIsIDEyLCA1MiwgMDYpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBwYXJzZWQgZGF0ZSA1IiwgZC5lcXVhbHMoY2FsLmdldFRpbWUoKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTI1OQorICAgICAgICAgICAgRGF0ZS5wYXJzZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkRhdGUucGFyc2UobnVsbCkgc2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5EYXRlI3NldERhdGUoaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0RGF0ZUkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5EYXRlLnNldERhdGUoaW50KQorICAgICAgICBEYXRlIGQgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OCwgQ2FsZW5kYXIuT0NUT0JFUiwgMTMsIDE5LCA5KQorICAgICAgICAgICAgICAgIC5nZXRUaW1lKCk7CisgICAgICAgIGQuc2V0RGF0ZSgyMyk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2V0IGluY29ycmVjdCBkYXRlIiwgMjMsIGQuZ2V0RGF0ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRGF0ZSNzZXRIb3VycyhpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRIb3Vyc0koKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5EYXRlLnNldEhvdXJzKGludCkKKyAgICAgICAgRGF0ZSBkID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTgsIENhbGVuZGFyLk9DVE9CRVIsIDEzLCAxOSwgOSkKKyAgICAgICAgICAgICAgICAuZ2V0VGltZSgpOworICAgICAgICBkLnNldEhvdXJzKDIzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTZXQgaW5jb3JyZWN0IGhvdXJzIiwgMjMsIGQuZ2V0SG91cnMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkRhdGUjc2V0TWludXRlcyhpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRNaW51dGVzSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkRhdGUuc2V0TWludXRlcyhpbnQpCisgICAgICAgIERhdGUgZCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk4LCBDYWxlbmRhci5PQ1RPQkVSLCAxMywgMTksIDkpCisgICAgICAgICAgICAgICAgLmdldFRpbWUoKTsKKyAgICAgICAgZC5zZXRNaW51dGVzKDQ1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTZXQgaW5jb3JyZWN0IG1pbnMiLCA0NSwgZC5nZXRNaW51dGVzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5EYXRlI3NldE1vbnRoKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldE1vbnRoSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkRhdGUuc2V0TW9udGgoaW50KQorICAgICAgICBEYXRlIGQgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OCwgQ2FsZW5kYXIuT0NUT0JFUiwgMTMsIDE5LCA5KQorICAgICAgICAgICAgICAgIC5nZXRUaW1lKCk7CisgICAgICAgIGQuc2V0TW9udGgoMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2V0IGluY29ycmVjdCBtb250aCIsIDAsIGQuZ2V0TW9udGgoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkRhdGUjc2V0U2Vjb25kcyhpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRTZWNvbmRzSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkRhdGUuc2V0U2Vjb25kcyhpbnQpCisgICAgICAgIERhdGUgZCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk4LCBDYWxlbmRhci5PQ1RPQkVSLCAxMywgMTksIDkpCisgICAgICAgICAgICAgICAgLmdldFRpbWUoKTsKKyAgICAgICAgZC5zZXRTZWNvbmRzKDEzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTZXQgaW5jb3JyZWN0IHNlY29uZHMiLCAxMywgZC5nZXRTZWNvbmRzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5EYXRlI3NldFRpbWUobG9uZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFRpbWVKKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuRGF0ZS5zZXRUaW1lKGxvbmcpCisgICAgICAgIERhdGUgZDEgPSBuZXcgRGF0ZSgwKTsKKyAgICAgICAgRGF0ZSBkMiA9IG5ldyBEYXRlKDE5MDAwMDApOworICAgICAgICBkMS5zZXRUaW1lKDkwMCk7CisgICAgICAgIGQyLnNldFRpbWUoODkwMDAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdGltZSIsIDg5MDAwMCwgZDIuZ2V0VGltZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgdGltZSIsIDkwMCwgZDEuZ2V0VGltZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRGF0ZSNzZXRZZWFyKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFllYXJJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuRGF0ZS5zZXRZZWFyKGludCkKKyAgICAgICAgRGF0ZSBkID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTgsIENhbGVuZGFyLk9DVE9CRVIsIDEzLCAxOSwgOSkKKyAgICAgICAgICAgICAgICAuZ2V0VGltZSgpOworICAgICAgICBkLnNldFllYXIoOCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2V0IGluY29ycmVjdCB5ZWFyIiwgOCwgZC5nZXRZZWFyKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5EYXRlI3RvR01UU3RyaW5nKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvR01UU3RyaW5nKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLlN0cmluZyBqYXZhLnV0aWwuRGF0ZS50b0dNVFN0cmluZygpCisgICAgICAgIGFzc2VydEVxdWFscygiRGlkIG5vdCBjb252ZXJ0IGVwb2NoIHRvIEdNVCBzdHJpbmcgY29ycmVjdGx5IiwgIjEgSmFuIDE5NzAgMDA6MDA6MDAgR01UIiwgbmV3IERhdGUoMCkKKyAgICAgICAgICAgICAgICAudG9HTVRTdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRGlkIG5vdCBjb252ZXJ0IGVwb2NoICsgMXlyIHRvIEdNVCBzdHJpbmcgY29ycmVjdGx5IiwKKyAgICAgICAgICAgICAgICAiMSBKYW4gMTk3MSAwMDowMDowMCBHTVQiLCBuZXcgRGF0ZSgobG9uZykgMzY1ICogMjQgKiA2MCAqIDYwICogMTAwMCkudG9HTVRTdHJpbmcoKQorICAgICAgICAgICAgICAgICAgICAgICAgKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRGF0ZSN0b1N0cmluZygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF90b1N0cmluZygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcgamF2YS51dGlsLkRhdGUudG9TdHJpbmcoKQorICAgICAgICBDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOworICAgICAgICBjYWwuc2V0KENhbGVuZGFyLkRBVEUsIDEpOworICAgICAgICBjYWwuc2V0KENhbGVuZGFyLk1PTlRILCBDYWxlbmRhci5KQU5VQVJZKTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5ZRUFSLCAxOTcwKTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5IT1VSX09GX0RBWSwgMCk7CisgICAgICAgIGNhbC5zZXQoQ2FsZW5kYXIuTUlOVVRFLCAwKTsKKyAgICAgICAgY2FsLnNldChDYWxlbmRhci5TRUNPTkQsIDApOworICAgICAgICBEYXRlIGQgPSBjYWwuZ2V0VGltZSgpOworICAgICAgICBTdHJpbmcgcmVzdWx0ID0gZC50b1N0cmluZygpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcmVzdWx0OiAiICsgZCwgcmVzdWx0CisgICAgICAgICAgICAgICAgLnN0YXJ0c1dpdGgoIlRodSBKYW4gMDEgMDA6MDA6MDAiKQorICAgICAgICAgICAgICAgICYmIHJlc3VsdC5lbmRzV2l0aCgiMTk3MCIpKTsKKworICAgICAgICBUaW1lWm9uZSB0eiA9IFRpbWVab25lLmdldERlZmF1bHQoKTsKKyAgICAgICAgVGltZVpvbmUuc2V0RGVmYXVsdChUaW1lWm9uZS5nZXRUaW1lWm9uZSgiR01ULTUiKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEYXRlIGQxID0gbmV3IERhdGUoMCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3Qgc3RyaW5nOiAiICsgZDEsIGQxLnRvU3RyaW5nKCkKKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscygiV2VkIERlYyAzMSAxOTowMDowMCBHTVQtMDU6MDAgMTk2OSIpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIFRpbWVab25lLnNldERlZmF1bHQodHopOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkRhdGUjVVRDKGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9VVENJSUlJSUkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBsb25nIGphdmEudXRpbC5EYXRlLlVUQyhpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50KQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgVVRDIHZhbHVlIGZvciBlcG9jaCIsIERhdGUuVVRDKDcwLCAwLCAxLAorICAgICAgICAgICAgICAgIDAsIDAsIDApID09IChsb25nKSAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IFVUQyB2YWx1ZSBmb3IgZXBvY2ggKzF5ciIsIERhdGUuVVRDKDcxLAorICAgICAgICAgICAgICAgIDAsIDEsIDAsIDAsIDApID09IChsb25nKSAzNjUgKiAyNCAqIDYwICogNjAgKiAxMDAwKTsKKyAgICB9CisgICAgLyoqCisgICAgICogamF2YS51dGlsLkRhdGUjdG9Mb2NhbGVTdHJpbmcoKSBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLlN0cmluZworICAgICAqICAgICAgICBqYXZhLnV0aWwuRGF0ZS50b0dNVFN0cmluZygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF90b0xvY2FsZVN0cmluZygpIHsKKyAgICAgICAgTG9jYWxlIGxvYyA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KExvY2FsZS5VUyk7CisgICAgVGltZVpvbmUgdHogPSBUaW1lWm9uZS5nZXREZWZhdWx0KCk7CisgICAgVGltZVpvbmUuc2V0RGVmYXVsdChUaW1lWm9uZS5nZXRUaW1lWm9uZSgiR01UIikpOworICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkRpZCBub3QgY29udmVydCBlcG9jaCB0byBHTVQgc3RyaW5nIGNvcnJlY3RseSIsICJKYW4gMSwgMTk3MCAxMjowMDowMCBBTSIsCisgICAgICAgICAgICAgICAgbmV3IERhdGUoMCkudG9Mb2NhbGVTdHJpbmcoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkRpZCBub3QgY29udmVydCBlcG9jaCArIDF5ciB0byBHTVQgc3RyaW5nIGNvcnJlY3RseSIsCisgICAgICAgICAgICAgICAgIkphbiAxLCAxOTcxIDEyOjAwOjAwIEFNIiwgbmV3IERhdGUoKGxvbmcpMzY1ICogMjQgKiA2MCAqIDYwICogMTAwMCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC50b0xvY2FsZVN0cmluZygpKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobG9jKTsKKyAgICAgICAgVGltZVpvbmUuc2V0RGVmYXVsdCh0eik7CisgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdXAgdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBvcGVuIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzIG1ldGhvZAorICAgICAqIGlzIGNhbGxlZCBiZWZvcmUgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0VtcHR5U3RhY2tFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9FbXB0eVN0YWNrRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMxZWUxZTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9FbXB0eVN0YWNrRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5FbXB0eVN0YWNrRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5TdGFjazsKKworcHVibGljIGNsYXNzIEVtcHR5U3RhY2tFeGNlcHRpb25UZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIE9iamVjdFtdIG9iakFycmF5ID0gbmV3IE9iamVjdFsxMF07CisgICAgU3RhY2sgczsKKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbXB0eVN0YWNrRXhjZXB0aW9uI0VtcHR5U3RhY2tFeGNlcHRpb24oKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuRW1wdHlTdGFja0V4Y2VwdGlvbigpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IG9iakFycmF5Lmxlbmd0aCArIDE7IGNvdW50ZXIrKykKKyAgICAgICAgICAgICAgICBzLnBvcCgpOworICAgICAgICB9IGNhdGNoIChFbXB0eVN0YWNrRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmYWlsKCJFeHBlY3RlZCBFbXB0eVN0YWNrRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBvYmpBcnJheS5sZW5ndGg7IGNvdW50ZXIrKykgeworICAgICAgICAgICAgb2JqQXJyYXlbY291bnRlcl0gPSBuZXcgSW50ZWdlcihjb3VudGVyKTsKKyAgICAgICAgfQorCisgICAgICAgIHMgPSBuZXcgU3RhY2soKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBvYmpBcnJheS5sZW5ndGg7IGNvdW50ZXIrKykgeworICAgICAgICAgICAgcy5wdXNoKG9iakFycmF5W2NvdW50ZXJdKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgICAgICBvYmpBcnJheSA9IG51bGw7CisgICAgICAgIHMgPSBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0VudW1NYXBUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9FbnVtTWFwVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA1ODI2ZDEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9FbnVtTWFwVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTE3NSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uQW5kcm9pZE9ubHk7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5FbnVtTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkudGVzdGZyYW1ld29yay5zZXJpYWxpemF0aW9uLlNlcmlhbGl6YXRpb25UZXN0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgRW51bU1hcFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgZW51bSBTaXplIHsKKyAgICAgICAgU21hbGwsIE1pZGRsZSwgQmlnIHt9OworICAgIH0KKworICAgIGVudW0gQ29sb3IgeworICAgICAgICBSZWQsIEdyZWVuLCBCbHVlIHt9OworICAgIH0KKworICAgIGVudW0gRW1wdHkgeworICAgICAgICAvL0VtcHR5CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTW9ja0VudHJ5PEssIFY+IGltcGxlbWVudHMgTWFwLkVudHJ5PEssIFY+IHsKKyAgICAgICAgcHJpdmF0ZSBLIGtleTsKKworICAgICAgICBwcml2YXRlIFYgdmFsdWU7CisKKyAgICAgICAgcHVibGljIE1vY2tFbnRyeShLIGtleSwgViB2YWx1ZSkgeworICAgICAgICAgICAgdGhpcy5rZXkgICA9IGtleTsKKyAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgcmV0dXJuIChrZXkgPT0gbnVsbCA/IDAgOiBrZXkuaGFzaENvZGUoKSkKKyAgICAgICAgICAgICAgICAgICAgXiAodmFsdWUgPT0gbnVsbCA/IDAgOiB2YWx1ZS5oYXNoQ29kZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBLIGdldEtleSgpIHsKKyAgICAgICAgICAgIHJldHVybiBrZXk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgViBnZXRWYWx1ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBWIHNldFZhbHVlKFYgb2JqZWN0KSB7CisgICAgICAgICAgICBWIG9sZFZhbHVlID0gdmFsdWU7CisgICAgICAgICAgICB2YWx1ZSA9IG9iamVjdDsKKyAgICAgICAgICAgIHJldHVybiBvbGRWYWx1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtTWFwI0VudW1NYXAoQ2xhc3MpCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoeyAidW5jaGVja2VkIiwgImJveGluZyIgfSkKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19DbGFzcygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFbnVtTWFwKChDbGFzcykgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEVudW1NYXAoU2l6ZS5CaWcuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFbnVtTWFwKEludGVnZXIuY2xhc3MpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIEVudW1NYXAgZW51bUNvbG9yTWFwID0gbmV3IEVudW1NYXA8Q29sb3IsIERvdWJsZT4oQ29sb3IuY2xhc3MpOworICAgICAgICBhc3NlcnROdWxsKCJSZXR1cm4gbm9uLW51bGwgZm9yIG5vbiBtYXBwZWQga2V5IiwgZW51bUNvbG9yTWFwLnB1dCgKKyAgICAgICAgICAgICAgICBDb2xvci5HcmVlbiwgMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkdldCByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUgZm9yIGdpdmVuIGtleSIsIDIsCisgICAgICAgICAgICAgICAgZW51bUNvbG9yTWFwLmdldChDb2xvci5HcmVlbikpOworCisgICAgICAgIEVudW1NYXAgZW51bUVtcHR5TWFwID0gbmV3IEVudW1NYXA8RW1wdHksIERvdWJsZT4oRW1wdHkuY2xhc3MpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW51bUVtcHR5TWFwLnB1dChDb2xvci5SZWQsIDIpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgQ2xhc3NDYXN0RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgRW51bU1hcCBlbnVtU2l6ZU1hcCA9IG5ldyBFbnVtTWFwKFNpemUuY2xhc3MpOworICAgICAgICBhc3NlcnROdWxsKCJSZXR1cm4gbm9uLW51bGwgZm9yIG5vbiBtYXBwZWQga2V5IiwgZW51bVNpemVNYXAucHV0KAorICAgICAgICAgICAgICAgIFNpemUuQmlnLCAyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiR2V0IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSBmb3IgZ2l2ZW4ga2V5IiwgMiwKKyAgICAgICAgICAgICAgICBlbnVtU2l6ZU1hcC5nZXQoU2l6ZS5CaWcpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVudW1TaXplTWFwLnB1dChDb2xvci5SZWQsIDIpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgQ2xhc3NDYXN0RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgZW51bVNpemVNYXAgPSBuZXcgRW51bU1hcChTaXplLk1pZGRsZS5nZXRDbGFzcygpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiUmV0dXJuIG5vbi1udWxsIGZvciBub24gbWFwcGVkIGtleSIsIGVudW1TaXplTWFwLnB1dCgKKyAgICAgICAgICAgICAgICBTaXplLlNtYWxsLCAxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiR2V0IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSBmb3IgZ2l2ZW4ga2V5IiwgMSwKKyAgICAgICAgICAgICAgICBlbnVtU2l6ZU1hcC5nZXQoU2l6ZS5TbWFsbCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW51bVNpemVNYXAucHV0KENvbG9yLlJlZCwgMik7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBDbGFzc0Nhc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRW51bU1hcCNFbnVtTWFwKEVudW1NYXApCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoeyAidW5jaGVja2VkIiwgImJveGluZyIgfSkKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfdXRpbF9FbnVtTWFwKCkgeworICAgICAgICBFbnVtTWFwIGVudW1NYXA7CisgICAgICAgIEVudW1NYXAgZW51bUNvbG9yTWFwID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVudW1NYXAgPSBuZXcgRW51bU1hcChlbnVtQ29sb3JNYXApOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGVudW1Db2xvck1hcCA9IG5ldyBFbnVtTWFwPENvbG9yLCBEb3VibGU+KENvbG9yLmNsYXNzKTsKKyAgICAgICAgRG91YmxlIGRvdWJsZTEgPSBuZXcgRG91YmxlKDEpOworICAgICAgICBlbnVtQ29sb3JNYXAucHV0KENvbG9yLkdyZWVuLCAyKTsKKyAgICAgICAgZW51bUNvbG9yTWFwLnB1dChDb2xvci5CbHVlLCBkb3VibGUxKTsKKworICAgICAgICBlbnVtTWFwID0gbmV3IEVudW1NYXAoZW51bUNvbG9yTWFwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDb25zdHJ1Y3RvciBmYWlscyIsIDIsIGVudW1NYXAuZ2V0KENvbG9yLkdyZWVuKSk7CisgICAgICAgIGFzc2VydFNhbWUoIkNvbnN0cnVjdG9yIGZhaWxzIiwgZG91YmxlMSwgZW51bU1hcC5nZXQoQ29sb3IuQmx1ZSkpOworICAgICAgICBhc3NlcnROdWxsKCJDb25zdHJ1Y3RvciBmYWlscyIsIGVudW1NYXAuZ2V0KENvbG9yLlJlZCkpOworICAgICAgICBlbnVtTWFwLnB1dChDb2xvci5SZWQsIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIiwgMSwgZW51bU1hcC5nZXQoQ29sb3IuUmVkKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVudW1NYXAucHV0KFNpemUuTWlkZGxlLCAyKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIENsYXNzQ2FzdEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtTWFwI0VudW1NYXAoTWFwKQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsgInVuY2hlY2tlZCIsICJib3hpbmciIH0pCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX3V0aWxfTWFwKCkgeworICAgICAgICBFbnVtTWFwIGVudW1NYXA7CisgICAgICAgIE1hcCBlbnVtQ29sb3JNYXAgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW51bU1hcCA9IG5ldyBFbnVtTWFwKGVudW1Db2xvck1hcCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIGVudW1Db2xvck1hcCA9IG5ldyBFbnVtTWFwPENvbG9yLCBEb3VibGU+KENvbG9yLmNsYXNzKTsKKyAgICAgICAgZW51bU1hcCAgICAgID0gbmV3IEVudW1NYXAoZW51bUNvbG9yTWFwKTsKKyAgICAgICAgZW51bUNvbG9yTWFwLnB1dChDb2xvci5CbHVlLCAzKTsKKyAgICAgICAgZW51bU1hcCAgICAgID0gbmV3IEVudW1NYXAoZW51bUNvbG9yTWFwKTsKKworICAgICAgICBIYXNoTWFwIGhhc2hDb2xvck1hcCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbnVtTWFwID0gbmV3IEVudW1NYXAoaGFzaENvbG9yTWFwKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBoYXNoQ29sb3JNYXAgPSBuZXcgSGFzaE1hcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW51bU1hcCA9IG5ldyBFbnVtTWFwKGhhc2hDb2xvck1hcCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBoYXNoQ29sb3JNYXAucHV0KENvbG9yLkdyZWVuLCAyKTsKKyAgICAgICAgZW51bU1hcCA9IG5ldyBFbnVtTWFwKGhhc2hDb2xvck1hcCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQ29uc3RydWN0b3IgZmFpbHMiLCAyLCBlbnVtTWFwLmdldChDb2xvci5HcmVlbikpOworICAgICAgICBhc3NlcnROdWxsKCJDb25zdHJ1Y3RvciBmYWlscyIsIGVudW1NYXAuZ2V0KENvbG9yLlJlZCkpOworICAgICAgICBlbnVtTWFwLnB1dChDb2xvci5SZWQsIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIiwgMSwgZW51bU1hcC5nZXQoQ29sb3IuUmVkKSk7CisgICAgICAgIGhhc2hDb2xvck1hcC5wdXQoU2l6ZS5CaWcsIDMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW51bU1hcCA9IG5ldyBFbnVtTWFwKGhhc2hDb2xvck1hcCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBDbGFzc0Nhc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBoYXNoQ29sb3JNYXAgPSBuZXcgSGFzaE1hcCgpOworICAgICAgICBoYXNoQ29sb3JNYXAucHV0KG5ldyBJbnRlZ2VyKDEpLCAxKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVudW1NYXAgPSBuZXcgRW51bU1hcChoYXNoQ29sb3JNYXApOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgQ2xhc3NDYXN0RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkVudW1NYXAjY2xlYXIoKQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsgInVuY2hlY2tlZCIsICJib3hpbmciIH0pCisgICAgcHVibGljIHZvaWQgdGVzdF9jbGVhcigpIHsKKyAgICAgICAgRW51bU1hcCBlbnVtU2l6ZU1hcCA9IG5ldyBFbnVtTWFwKFNpemUuY2xhc3MpOworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5TbWFsbCwgMSk7CisgICAgICAgIGVudW1TaXplTWFwLmNsZWFyKCk7CisgICAgICAgIGFzc2VydE51bGwoIkZhaWxlZCB0byBjbGVhciBhbGwgZWxlbWVudHMiLCBlbnVtU2l6ZU1hcC5nZXQoU2l6ZS5TbWFsbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtTWFwI2NvbnRhaW5zS2V5KE9iamVjdCkKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncyggeyAidW5jaGVja2VkIiwgImJveGluZyIgfSkKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbnRhaW5zS2V5TGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIEVudW1NYXAgZW51bVNpemVNYXAgPSBuZXcgRW51bU1hcChTaXplLmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIHVuY29udGFpbmVkIGtleSIsIGVudW1TaXplTWFwCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zS2V5KFNpemUuU21hbGwpKTsKKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuU21hbGwsIDEpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgY29udGFpbmVkIGtleSIsIGVudW1TaXplTWFwCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zS2V5KFNpemUuU21hbGwpKTsKKworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5CaWcsIG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgY29udGFpbmVkIGtleSIsIGVudW1TaXplTWFwCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zS2V5KFNpemUuQmlnKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIHVuY29udGFpbmVkIGtleSIsIGVudW1TaXplTWFwCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zS2V5KENvbG9yLlJlZCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgdW5jb250YWluZWQga2V5IiwgZW51bVNpemVNYXAKKyAgICAgICAgICAgICAgICAuY29udGFpbnNLZXkobmV3IEludGVnZXIoIjMiKSkpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgdW5jb250YWluZWQga2V5IiwgZW51bVNpemVNYXAKKyAgICAgICAgICAgICAgICAuY29udGFpbnNLZXkobnVsbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtTWFwI2Nsb25lKCkKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncyggeyAidW5jaGVja2VkIiwgImJveGluZyIgfSkKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb25lKCkgeworICAgICAgICBFbnVtTWFwIGVudW1TaXplTWFwID0gbmV3IEVudW1NYXAoU2l6ZS5jbGFzcyk7CisgICAgICAgIEludGVnZXIgaW50ZWdlciA9IG5ldyBJbnRlZ2VyKCIzIik7CisgICAgICAgIGVudW1TaXplTWFwLnB1dChTaXplLlNtYWxsLCBpbnRlZ2VyKTsKKyAgICAgICAgRW51bU1hcCBlbnVtU2l6ZU1hcENsb25lID0gZW51bVNpemVNYXAuY2xvbmUoKTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZSgiU2hvdWxkIG5vdCBiZSBzYW1lIiwgZW51bVNpemVNYXAsIGVudW1TaXplTWFwQ2xvbmUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkNsb25lIGFuc3dlcmVkIHVuZXF1YWwgRW51bU1hcCIsIGVudW1TaXplTWFwLAorICAgICAgICAgICAgICAgIGVudW1TaXplTWFwQ2xvbmUpOworCisgICAgICAgIGFzc2VydFNhbWUoIlNob3VsZCBiZSBzYW1lIiwgZW51bVNpemVNYXAuZ2V0KFNpemUuU21hbGwpLAorICAgICAgICAgICAgICAgIGVudW1TaXplTWFwQ2xvbmUuZ2V0KFNpemUuU21hbGwpKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiQ2xvbmUgaXMgbm90IHNoYWxsb3cgY2xvbmUiLCBpbnRlZ2VyLCBlbnVtU2l6ZU1hcENsb25lCisgICAgICAgICAgICAgICAgLmdldChTaXplLlNtYWxsKSk7CisgICAgICAgIGVudW1TaXplTWFwLnJlbW92ZShTaXplLlNtYWxsKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiQ2xvbmUgaXMgbm90IHNoYWxsb3cgY2xvbmUiLCBpbnRlZ2VyLCBlbnVtU2l6ZU1hcENsb25lCisgICAgICAgICAgICAgICAgLmdldChTaXplLlNtYWxsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkVudW1NYXAjY29udGFpbnNWYWx1ZShPYmplY3QpCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoIHsgInVuY2hlY2tlZCIsICJib3hpbmciIH0pCisgICAgcHVibGljIHZvaWQgdGVzdF9jb250YWluc1ZhbHVlTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIEVudW1NYXAgZW51bVNpemVNYXAgPSBuZXcgRW51bU1hcChTaXplLmNsYXNzKTsKKyAgICAgICAgRG91YmxlIGRvdWJsZTEgPSBuZXcgRG91YmxlKDMpOworICAgICAgICBEb3VibGUgZG91YmxlMiA9IG5ldyBEb3VibGUoMyk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIHVuY29udGFpbmVkIHZhbHVlIiwgZW51bVNpemVNYXAKKyAgICAgICAgICAgICAgICAuY29udGFpbnNWYWx1ZShkb3VibGUxKSk7CisgICAgICAgIGVudW1TaXplTWFwLnB1dChTaXplLk1pZGRsZSwgMik7CisgICAgICAgIGVudW1TaXplTWFwLnB1dChTaXplLlNtYWxsLCBkb3VibGUxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIGNvbnRhaW5lZCB2YWx1ZSIsIGVudW1TaXplTWFwCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zVmFsdWUoZG91YmxlMSkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgY29udGFpbmVkIHZhbHVlIiwgZW51bVNpemVNYXAKKyAgICAgICAgICAgICAgICAuY29udGFpbnNWYWx1ZShkb3VibGUyKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciBjb250YWluZWQgdmFsdWUiLCBlbnVtU2l6ZU1hcAorICAgICAgICAgICAgICAgIC5jb250YWluc1ZhbHVlKDIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIHVuY29udGFpbmVkIHZhbHVlIiwgZW51bVNpemVNYXAKKyAgICAgICAgICAgICAgICAuY29udGFpbnNWYWx1ZSgxKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIHVuY29udGFpbmVkIHZhbHVlIiwgZW51bVNpemVNYXAKKyAgICAgICAgICAgICAgICAuY29udGFpbnNWYWx1ZShudWxsKSk7CisgICAgICAgIGVudW1TaXplTWFwLnB1dChTaXplLkJpZywgbnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciBjb250YWluZWQgdmFsdWUiLCBlbnVtU2l6ZU1hcAorICAgICAgICAgICAgICAgIC5jb250YWluc1ZhbHVlKG51bGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRW51bU1hcCNlbnRyeVNldCgpCisgICAgICovCisgICAgQEFuZHJvaWRPbmx5KCJNYXAuRW50cnkgaXMgaW5kaXJlY3RseSBtb2RpZmllZCBvbiBSSSB3aGVuIEl0ZXJhdG9yLm5leHQoKSBpcyBpbnZva2VkIikKKyAgICBAU3VwcHJlc3NXYXJuaW5ncyh7ICJ1bmNoZWNrZWQiLCAiYm94aW5nIiB9KQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZW50cnlTZXQoKSB7CisgICAgICAgIEVudW1NYXAgZW51bVNpemVNYXAgPSBuZXcgRW51bU1hcChTaXplLmNsYXNzKTsKKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuTWlkZGxlLCAxKTsKKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuQmlnLCBudWxsKTsKKyAgICAgICAgTW9ja0VudHJ5IG1vY2tFbnRyeSA9IG5ldyBNb2NrRW50cnkoU2l6ZS5NaWRkbGUsIDEpOworICAgICAgICBTZXQgc2V0ID0gZW51bVNpemVNYXAuZW50cnlTZXQoKTsKKworICAgICAgICBTZXQgc2V0MSA9IGVudW1TaXplTWFwLmVudHJ5U2V0KCk7CisgICAgICAgIGFzc2VydFNhbWUoIlNob3VsZCBiZSBzYW1lIiwgc2V0MSwgc2V0KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldC5hZGQobW9ja0VudHJ5KTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIGNvbnRhaW5lZCBvYmplY3QiLCBzZXQKKyAgICAgICAgICAgICAgICAuY29udGFpbnMobW9ja0VudHJ5KSk7CisgICAgICAgIG1vY2tFbnRyeSA9IG5ldyBNb2NrRW50cnkoU2l6ZS5NaWRkbGUsIG51bGwpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgdW5jb250YWluZWQgb2JqZWN0Iiwgc2V0CisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKG1vY2tFbnRyeSkpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgdW5jb250YWluZWQgb2JqZWN0Iiwgc2V0CisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKFNpemUuU21hbGwpKTsKKyAgICAgICAgbW9ja0VudHJ5ID0gbmV3IE1vY2tFbnRyeShuZXcgSW50ZWdlcigxKSwgMSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIGZvciB1bmNvbnRhaW5lZCBvYmplY3QiLCBzZXQKKyAgICAgICAgICAgICAgICAuY29udGFpbnMobW9ja0VudHJ5KSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIGZvciB1bmNvbnRhaW5lZCBvYmplY3QiLCBzZXQKKyAgICAgICAgICAgICAgICAuY29udGFpbnMobmV3IEludGVnZXIoMSkpKTsKKworICAgICAgICBtb2NrRW50cnkgPSBuZXcgTW9ja0VudHJ5KFNpemUuQmlnLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIGNvbnRhaW5lZCBvYmplY3QiLCBzZXQKKyAgICAgICAgICAgICAgICAuY29udGFpbnMobW9ja0VudHJ5KSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIHdoZW4gdGhlIG9iamVjdCBjYW4gYmUgcmVtb3ZlZCIsIHNldAorICAgICAgICAgICAgICAgIC5yZW1vdmUobW9ja0VudHJ5KSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIGZvciB1bmNvbnRhaW5lZCBvYmplY3QiLCBzZXQKKyAgICAgICAgICAgICAgICAuY29udGFpbnMobW9ja0VudHJ5KSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIHdoZW4gdGhlIG9iamVjdCBjYW4gbm90IGJlIHJlbW92ZWQiLCBzZXQKKyAgICAgICAgICAgICAgICAucmVtb3ZlKG1vY2tFbnRyeSkpOworICAgICAgICBtb2NrRW50cnkgPSBuZXcgTW9ja0VudHJ5KG5ldyBJbnRlZ2VyKDEpLCAxKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgd2hlbiB0aGUgb2JqZWN0IGNhbiBub3QgYmUgcmVtb3ZlZCIsIHNldAorICAgICAgICAgICAgICAgIC5yZW1vdmUobW9ja0VudHJ5KSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIHdoZW4gdGhlIG9iamVjdCBjYW4gbm90IGJlIHJlbW92ZWQiLCBzZXQKKyAgICAgICAgICAgICAgICAucmVtb3ZlKG5ldyBJbnRlZ2VyKDEpKSk7CisKKyAgICAgICAgLy8gVGhlIHNldCBpcyBiYWNrZWQgYnkgdGhlIG1hcCBzbyBjaGFuZ2VzIHRvIG9uZSBhcmUgcmVmbGVjdGVkIGJ5IHRoZQorICAgICAgICAvLyBvdGhlci4KKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuQmlnLCAzKTsKKyAgICAgICAgbW9ja0VudHJ5ID0gbmV3IE1vY2tFbnRyeShTaXplLkJpZywgMyk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciBjb250YWluZWQgb2JqZWN0Iiwgc2V0CisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKG1vY2tFbnRyeSkpOworICAgICAgICBlbnVtU2l6ZU1hcC5yZW1vdmUoU2l6ZS5CaWcpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgdW5jb250YWluZWQgb2JqZWN0Iiwgc2V0CisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKG1vY2tFbnRyeSkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDEsIHNldC5zaXplKCkpOworICAgICAgICBzZXQuY2xlYXIoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzaXplIiwgMCwgc2V0LnNpemUoKSk7CisKKyAgICAgICAgZW51bVNpemVNYXAgPSBuZXcgRW51bU1hcChTaXplLmNsYXNzKTsKKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuTWlkZGxlLCAxKTsKKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuQmlnLCBudWxsKTsKKyAgICAgICAgc2V0ID0gZW51bVNpemVNYXAuZW50cnlTZXQoKTsKKyAgICAgICAgQ29sbGVjdGlvbiBjID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBjLmFkZChuZXcgTW9ja0VudHJ5KFNpemUuTWlkZGxlLCAxKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybiB3cm9uZyB2YWx1ZSIsIHNldC5jb250YWluc0FsbChjKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJlbW92ZSBkb2VzIG5vdCBzdWNjZXNzIiwgc2V0LnJlbW92ZUFsbChjKSk7CisKKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuTWlkZGxlLCAxKTsKKyAgICAgICAgYy5hZGQobmV3IE1vY2tFbnRyeShTaXplLkJpZywgMykpOworICAgICAgICBhc3NlcnRUcnVlKCJSZW1vdmUgZG9lcyBub3Qgc3VjY2VzcyIsIHNldC5yZW1vdmVBbGwoYykpOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIHJldHVybiBmYWxzZSIsIHNldC5yZW1vdmVBbGwoYykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAxLCBzZXQuc2l6ZSgpKTsKKworICAgICAgICBlbnVtU2l6ZU1hcCA9IG5ldyBFbnVtTWFwKFNpemUuY2xhc3MpOworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5NaWRkbGUsIDEpOworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5CaWcsIG51bGwpOworICAgICAgICBzZXQgPSBlbnVtU2l6ZU1hcC5lbnRyeVNldCgpOworICAgICAgICBjID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBjLmFkZChuZXcgTW9ja0VudHJ5KFNpemUuTWlkZGxlLCAxKSk7CisgICAgICAgIGMuYWRkKG5ldyBNb2NrRW50cnkoU2l6ZS5CaWcsIDMpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJSZXRhaW4gZG9lcyBub3Qgc3VjY2VzcyIsIHNldC5yZXRhaW5BbGwoYykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAxLCBzZXQuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCByZXR1cm4gZmFsc2UiLCBzZXQucmV0YWluQWxsKGMpKTsKKworICAgICAgICBlbnVtU2l6ZU1hcCA9IG5ldyBFbnVtTWFwKFNpemUuY2xhc3MpOworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5NaWRkbGUsIDEpOworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5CaWcsIG51bGwpOworCisgICAgICAgIHNldCA9IGVudW1TaXplTWFwLmVudHJ5U2V0KCk7CisgICAgICAgIE9iamVjdFtdIGFycmF5ID0gc2V0LnRvQXJyYXkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBsZW5ndGgiLCAyLCBhcnJheS5sZW5ndGgpOworICAgICAgICBNYXAuRW50cnkgZW50cnkgPSAoTWFwLkVudHJ5KSBhcnJheVswXTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBrZXkiLCBTaXplLk1pZGRsZSwgZW50cnkuZ2V0S2V5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIiwgMSwgZW50cnkuZ2V0VmFsdWUoKSk7CisKKyAgICAgICAgT2JqZWN0W10gYXJyYXkxID0gbmV3IE9iamVjdFsxMF07CisgICAgICAgIGFycmF5MSA9IHNldC50b0FycmF5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgbGVuZ3RoIiwgMiwgYXJyYXkxLmxlbmd0aCk7CisgICAgICAgIGVudHJ5ID0gKE1hcC5FbnRyeSkgYXJyYXlbMF07CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcga2V5IiwgU2l6ZS5NaWRkbGUsIGVudHJ5LmdldEtleSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSIsIDEsIGVudHJ5LmdldFZhbHVlKCkpOworCisgICAgICAgIGFycmF5MSA9IG5ldyBPYmplY3RbMTBdOworICAgICAgICBhcnJheTEgPSBzZXQudG9BcnJheShhcnJheTEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGxlbmd0aCIsIDEwLCBhcnJheTEubGVuZ3RoKTsKKyAgICAgICAgZW50cnkgPSAoTWFwLkVudHJ5KSBhcnJheVsxXTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBrZXkiLCBTaXplLkJpZywgZW50cnkuZ2V0S2V5KCkpOworICAgICAgICBhc3NlcnROdWxsKCJTaG91bGQgYmUgbnVsbCIsIGFycmF5MVsyXSk7CisKKyAgICAgICAgc2V0ID0gZW51bVNpemVNYXAuZW50cnlTZXQoKTsKKyAgICAgICAgSW50ZWdlciBpbnRlZ2VyID0gbmV3IEludGVnZXIoIjEiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgd2hlbiB0aGUgb2JqZWN0IGNhbiBub3QgYmUgcmVtb3ZlZCIsIHNldAorICAgICAgICAgICAgICAgIC5yZW1vdmUoaW50ZWdlcikpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSB3aGVuIHRoZSBvYmplY3QgY2FuIGJlIHJlbW92ZWQiLCBzZXQKKyAgICAgICAgICAgICAgICAucmVtb3ZlKGVudHJ5KSk7CisKKyAgICAgICAgZW51bVNpemVNYXAgPSBuZXcgRW51bU1hcChTaXplLmNsYXNzKTsKKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuTWlkZGxlLCAxKTsKKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuQmlnLCBudWxsKTsKKyAgICAgICAgc2V0ID0gZW51bVNpemVNYXAuZW50cnlTZXQoKTsKKyAgICAgICAgSXRlcmF0b3IgaXRlciA9IHNldC5pdGVyYXRvcigpOworICAgICAgICBlbnRyeSA9IChNYXAuRW50cnkpIGl0ZXIubmV4dCgpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgY29udGFpbmVkIG9iamVjdCIsIHNldC5jb250YWlucyhlbnRyeSkpOworICAgICAgICBtb2NrRW50cnkgPSBuZXcgTW9ja0VudHJ5KFNpemUuTWlkZGxlLCAyKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIHVuY29udGFpbmVkIG9iamVjdCIsIHNldAorICAgICAgICAgICAgICAgIC5jb250YWlucyhtb2NrRW50cnkpKTsKKyAgICAgICAgbW9ja0VudHJ5ID0gbmV3IE1vY2tFbnRyeShuZXcgSW50ZWdlcigyKSwgMik7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIGZvciB1bmNvbnRhaW5lZCBvYmplY3QiLCBzZXQKKyAgICAgICAgICAgICAgICAuY29udGFpbnMobW9ja0VudHJ5KSk7CisgICAgICAgIGVudHJ5ID0gKE1hcC5FbnRyeSkgaXRlci5uZXh0KCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciBjb250YWluZWQgb2JqZWN0Iiwgc2V0LmNvbnRhaW5zKGVudHJ5KSk7CisKKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuTWlkZGxlLCAxKTsKKyAgICAgICAgZW51bVNpemVNYXAucmVtb3ZlKFNpemUuQmlnKTsKKyAgICAgICAgbW9ja0VudHJ5ID0gbmV3IE1vY2tFbnRyeShTaXplLkJpZywgbnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDEsIHNldC5zaXplKCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgdW5jb250YWluZWQgb2JqZWN0Iiwgc2V0LmNvbnRhaW5zKG1vY2tFbnRyeSkpOworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5CaWcsIDIpOworICAgICAgICBtb2NrRW50cnkgPSBuZXcgTW9ja0VudHJ5KFNpemUuQmlnLCAyKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIGNvbnRhaW5lZCBvYmplY3QiLCBzZXQKKyAgICAgICAgICAgICAgICAuY29udGFpbnMobW9ja0VudHJ5KSk7CisKKyAgICAgICAgaXRlci5yZW1vdmUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGl0ZXIucmVtb3ZlKCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbnRyeS5zZXRWYWx1ZSgyKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldC5jb250YWlucyhlbnRyeSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgZW51bVNpemVNYXAgPSBuZXcgRW51bU1hcChTaXplLmNsYXNzKTsKKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuTWlkZGxlLCAxKTsKKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuQmlnLCBudWxsKTsKKyAgICAgICAgc2V0ID0gZW51bVNpemVNYXAuZW50cnlTZXQoKTsKKyAgICAgICAgaXRlciA9IHNldC5pdGVyYXRvcigpOworICAgICAgICBlbnRyeSA9IChNYXAuRW50cnkpIGl0ZXIubmV4dCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGtleSIsIFNpemUuTWlkZGxlLCBlbnRyeS5nZXRLZXkoKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIGNvbnRhaW5lZCBvYmplY3QiLCBzZXQuY29udGFpbnMoZW50cnkpKTsKKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuTWlkZGxlLCAzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIGNvbnRhaW5lZCBvYmplY3QiLCBzZXQuY29udGFpbnMoZW50cnkpKTsKKyAgICAgICAgZW50cnkuc2V0VmFsdWUoMik7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciBjb250YWluZWQgb2JqZWN0Iiwgc2V0LmNvbnRhaW5zKGVudHJ5KSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIGZvciB1bmNvbnRhaW5lZCBvYmplY3QiLCBzZXQKKyAgICAgICAgICAgICAgICAucmVtb3ZlKG5ldyBJbnRlZ2VyKDEpKSk7CisKKyAgICAgICAgaXRlci5uZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcga2V5IiwgU2l6ZS5NaWRkbGUsIGVudHJ5LmdldEtleSgpKTsKKyAgICAgICAgc2V0LmNsZWFyKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDAsIHNldC5zaXplKCkpOworCisgICAgICAgIGVudW1TaXplTWFwID0gbmV3IEVudW1NYXAoU2l6ZS5jbGFzcyk7CisgICAgICAgIGVudW1TaXplTWFwLnB1dChTaXplLk1pZGRsZSwgMSk7CisgICAgICAgIGVudW1TaXplTWFwLnB1dChTaXplLkJpZywgbnVsbCk7CisgICAgICAgIHNldCA9IGVudW1TaXplTWFwLmVudHJ5U2V0KCk7CisgICAgICAgIGl0ZXIgPSBzZXQuaXRlcmF0b3IoKTsKKyAgICAgICAgbW9ja0VudHJ5ID0gbmV3IE1vY2tFbnRyeShTaXplLk1pZGRsZSwgMSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoIldyb25nIHJlc3VsdCIsIGVudHJ5LmVxdWFscyhtb2NrRW50cnkpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGl0ZXIucmVtb3ZlKCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIGVudHJ5ID0gKE1hcC5FbnRyeSkgaXRlci5uZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcga2V5IiwgU2l6ZS5NaWRkbGUsIGVudHJ5LmdldEtleSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiB0cnVlIiwgZW50cnkuZXF1YWxzKG1vY2tFbnRyeSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCBiZSBlcXVhbCIsIG1vY2tFbnRyeS5oYXNoQ29kZSgpLCBlbnRyeS5oYXNoQ29kZSgpKTsKKyAgICAgICAgbW9ja0VudHJ5ID0gbmV3IE1vY2tFbnRyeShTaXplLkJpZywgMSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJXcm9uZyByZXN1bHQiLCBlbnRyeS5lcXVhbHMobW9ja0VudHJ5KSk7CisKKyAgICAgICAgZW50cnkgPSAoTWFwLkVudHJ5KSBpdGVyLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIldyb25nIHJlc3VsdCIsIGVudHJ5LmVxdWFscyhtb2NrRW50cnkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBrZXkiLCBTaXplLkJpZywgZW50cnkuZ2V0S2V5KCkpOworICAgICAgICBpdGVyLnJlbW92ZSgpOworICAgICAgICBhc3NlcnRGYWxzZSgiV3JvbmcgcmVzdWx0IiwgZW50cnkuZXF1YWxzKG1vY2tFbnRyeSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAxLCBzZXQuc2l6ZSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGl0ZXIucmVtb3ZlKCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpdGVyLm5leHQoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtTWFwI2VxdWFscyhPYmplY3QpCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoIHsgInVuY2hlY2tlZCIsICJib3hpbmciIH0pCisgICAgcHVibGljIHZvaWQgdGVzdF9lcXVhbHNMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgRW51bU1hcCBlbnVtTWFwID0gbmV3IEVudW1NYXAoU2l6ZS5jbGFzcyk7CisgICAgICAgIGVudW1NYXAucHV0KFNpemUuU21hbGwsIDEpOworCisgICAgICAgIEVudW1NYXAgZW51bVNpemVNYXAgPSBuZXcgRW51bU1hcChTaXplLmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIHVuZXF1YWwgRW51bU1hcCIsIGVudW1TaXplTWFwCisgICAgICAgICAgICAgICAgLmVxdWFscyhlbnVtTWFwKSk7CisgICAgICAgIGVudW1TaXplTWFwLnB1dChTaXplLlNtYWxsLCAxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIGVxdWFsIEVudW1NYXAiLCBlbnVtU2l6ZU1hcAorICAgICAgICAgICAgICAgIC5lcXVhbHMoZW51bU1hcCkpOworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5CaWcsIG51bGwpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgdW5lcXVhbCBFbnVtTWFwIiwgZW51bVNpemVNYXAKKyAgICAgICAgICAgICAgICAuZXF1YWxzKGVudW1NYXApKTsKKworICAgICAgICBlbnVtTWFwLnB1dChTaXplLk1pZGRsZSwgbnVsbCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIGZvciB1bmVxdWFsIEVudW1NYXAiLCBlbnVtU2l6ZU1hcAorICAgICAgICAgICAgICAgIC5lcXVhbHMoZW51bU1hcCkpOworICAgICAgICBlbnVtTWFwLnJlbW92ZShTaXplLk1pZGRsZSk7CisgICAgICAgIGVudW1NYXAucHV0KFNpemUuQmlnLCAzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIHVuZXF1YWwgRW51bU1hcCIsIGVudW1TaXplTWFwCisgICAgICAgICAgICAgICAgLmVxdWFscyhlbnVtTWFwKSk7CisgICAgICAgIGVudW1NYXAucHV0KFNpemUuQmlnLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIGVxdWFsIEVudW1NYXAiLCBlbnVtU2l6ZU1hcAorICAgICAgICAgICAgICAgIC5lcXVhbHMoZW51bU1hcCkpOworCisgICAgICAgIEhhc2hNYXAgaGFzaE1hcCA9IG5ldyBIYXNoTWFwKCk7CisgICAgICAgIGhhc2hNYXAucHV0KFNpemUuU21hbGwsIDEpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgdW5lcXVhbCBFbnVtTWFwIiwgaGFzaE1hcAorICAgICAgICAgICAgICAgIC5lcXVhbHMoZW51bU1hcCkpOworICAgICAgICBoYXNoTWFwLnB1dChTaXplLkJpZywgbnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciBlcXVhbCBFbnVtTWFwIiwgZW51bU1hcC5lcXVhbHMoaGFzaE1hcCkpOworCisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgZW51bVNpemVNYXAKKyAgICAgICAgICAgICAgICAuZXF1YWxzKG5ldyBJbnRlZ2VyKDEpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkVudW1NYXAja2V5U2V0KCkKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncyggeyAidW5jaGVja2VkIiwgImJveGluZyIgfSkKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2tleVNldCgpIHsKKyAgICAgICAgRW51bU1hcCBlbnVtU2l6ZU1hcCA9IG5ldyBFbnVtTWFwKFNpemUuY2xhc3MpOworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5NaWRkbGUsIDIpOworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5CaWcsIG51bGwpOworICAgICAgICBTZXQgc2V0ID0gZW51bVNpemVNYXAua2V5U2V0KCk7CisKKyAgICAgICAgU2V0IHNldDEgPSBlbnVtU2l6ZU1hcC5rZXlTZXQoKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiU2hvdWxkIGJlIHNhbWUiLCBzZXQxLCBzZXQpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2V0LmFkZChTaXplLkJpZyk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciBjb250YWluZWQgb2JqZWN0Iiwgc2V0CisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKFNpemUuTWlkZGxlKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciBjb250YWluZWQgb2JqZWN0Iiwgc2V0CisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKFNpemUuQmlnKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIGZvciB1bmNvbnRhaW5lZCBvYmplY3QiLCBzZXQKKyAgICAgICAgICAgICAgICAuY29udGFpbnMoU2l6ZS5TbWFsbCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgdW5jb250YWluZWQgb2JqZWN0Iiwgc2V0CisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKG5ldyBJbnRlZ2VyKDEpKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIHdoZW4gdGhlIG9iamVjdCBjYW4gYmUgcmVtb3ZlZCIsIHNldAorICAgICAgICAgICAgICAgIC5yZW1vdmUoU2l6ZS5CaWcpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIHVuY29udGFpbmVkIG9iamVjdCIsIHNldAorICAgICAgICAgICAgICAgIC5jb250YWlucyhTaXplLkJpZykpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSB3aGVuIHRoZSBvYmplY3QgY2FuIG5vdCBiZSByZW1vdmVkIiwgc2V0CisgICAgICAgICAgICAgICAgLnJlbW92ZShTaXplLkJpZykpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSB3aGVuIHRoZSBvYmplY3QgY2FuIG5vdCBiZSByZW1vdmVkIiwgc2V0CisgICAgICAgICAgICAgICAgLnJlbW92ZShuZXcgSW50ZWdlcigxKSkpOworCisgICAgICAgIC8vIFRoZSBzZXQgaXMgYmFja2VkIGJ5IHRoZSBtYXAgc28gY2hhbmdlcyB0byBvbmUgYXJlIHJlZmxlY3RlZCBieSB0aGUKKyAgICAgICAgLy8gb3RoZXIuCisgICAgICAgIGVudW1TaXplTWFwLnB1dChTaXplLkJpZywgMyk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciBjb250YWluZWQgb2JqZWN0Iiwgc2V0CisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKFNpemUuQmlnKSk7CisgICAgICAgIGVudW1TaXplTWFwLnJlbW92ZShTaXplLkJpZyk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIGZvciB1bmNvbnRhaW5lZCBvYmplY3QiLCBzZXQKKyAgICAgICAgICAgICAgICAuY29udGFpbnMoU2l6ZS5CaWcpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAxLCBzZXQuc2l6ZSgpKTsKKyAgICAgICAgc2V0LmNsZWFyKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDAsIHNldC5zaXplKCkpOworCisgICAgICAgIGVudW1TaXplTWFwID0gbmV3IEVudW1NYXAoU2l6ZS5jbGFzcyk7CisgICAgICAgIGVudW1TaXplTWFwLnB1dChTaXplLk1pZGRsZSwgMSk7CisgICAgICAgIGVudW1TaXplTWFwLnB1dChTaXplLkJpZywgbnVsbCk7CisgICAgICAgIHNldCA9IGVudW1TaXplTWFwLmtleVNldCgpOworICAgICAgICBDb2xsZWN0aW9uIGMgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGMuYWRkKFNpemUuQmlnKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiB0cnVlIiwgc2V0LmNvbnRhaW5zQWxsKGMpKTsKKyAgICAgICAgYy5hZGQoU2l6ZS5TbWFsbCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgc2V0LmNvbnRhaW5zQWxsKGMpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiB0cnVlIiwgc2V0LnJlbW92ZUFsbChjKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDEsIHNldC5zaXplKCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIHJldHVybiBmYWxzZSIsIHNldC5yZW1vdmVBbGwoYykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAxLCBzZXQuc2l6ZSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldC5hZGRBbGwoYyk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGVudW1TaXplTWFwLnB1dChTaXplLkJpZywgbnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDIsIHNldC5zaXplKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIHRydWUiLCBzZXQucmV0YWluQWxsKGMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzaXplIiwgMSwgc2V0LnNpemUoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgc2V0LnJldGFpbkFsbChjKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBzZXQuc2l6ZSgpKTsKKyAgICAgICAgT2JqZWN0W10gYXJyYXkgPSBzZXQudG9BcnJheSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGxlbmd0aCIsIDEsIGFycmF5Lmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcga2V5IiwgU2l6ZS5CaWcsIGFycmF5WzBdKTsKKworICAgICAgICBlbnVtU2l6ZU1hcCA9IG5ldyBFbnVtTWFwKFNpemUuY2xhc3MpOworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5NaWRkbGUsIDEpOworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5CaWcsIG51bGwpOworICAgICAgICBzZXQgPSBlbnVtU2l6ZU1hcC5rZXlTZXQoKTsKKyAgICAgICAgYyA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgYy5hZGQoQ29sb3IuQmx1ZSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgc2V0LnJlbW92ZShjKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDIsIHNldC5zaXplKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIHRydWUiLCBzZXQucmV0YWluQWxsKGMpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzaXplIiwgMCwgc2V0LnNpemUoKSk7CisKKyAgICAgICAgZW51bVNpemVNYXAgPSBuZXcgRW51bU1hcChTaXplLmNsYXNzKTsKKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuTWlkZGxlLCAxKTsKKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuQmlnLCBudWxsKTsKKyAgICAgICAgc2V0ID0gZW51bVNpemVNYXAua2V5U2V0KCk7CisKKyAgICAgICAgSXRlcmF0b3IgaXRlciA9IHNldC5pdGVyYXRvcigpOworICAgICAgICBFbnVtIGVudW1LZXkgPSAoRW51bSkgaXRlci5uZXh0KCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciBjb250YWluZWQgb2JqZWN0Iiwgc2V0LmNvbnRhaW5zKGVudW1LZXkpKTsKKyAgICAgICAgZW51bUtleSA9IChFbnVtKSBpdGVyLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIGNvbnRhaW5lZCBvYmplY3QiLCBzZXQuY29udGFpbnMoZW51bUtleSkpOworCisgICAgICAgIGVudW1TaXplTWFwLnJlbW92ZShTaXplLkJpZyk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIGZvciB1bmNvbnRhaW5lZCBvYmplY3QiLCBzZXQKKyAgICAgICAgICAgICAgICAuY29udGFpbnMoZW51bUtleSkpOworICAgICAgICBpdGVyLnJlbW92ZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXRlci5yZW1vdmUoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIHVuY29udGFpbmVkIG9iamVjdCIsIHNldAorICAgICAgICAgICAgICAgIC5jb250YWlucyhlbnVtS2V5KSk7CisKKyAgICAgICAgaXRlciA9IHNldC5pdGVyYXRvcigpOworICAgICAgICBlbnVtS2V5ID0gKEVudW0pIGl0ZXIubmV4dCgpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgY29udGFpbmVkIG9iamVjdCIsIHNldC5jb250YWlucyhlbnVtS2V5KSk7CisgICAgICAgIGVudW1TaXplTWFwLnB1dChTaXplLk1pZGRsZSwgMyk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciBjb250YWluZWQgb2JqZWN0Iiwgc2V0LmNvbnRhaW5zKGVudW1LZXkpKTsKKworICAgICAgICBlbnVtU2l6ZU1hcCA9IG5ldyBFbnVtTWFwKFNpemUuY2xhc3MpOworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5NaWRkbGUsIDEpOworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5CaWcsIG51bGwpOworICAgICAgICBzZXQgPSBlbnVtU2l6ZU1hcC5rZXlTZXQoKTsKKyAgICAgICAgaXRlciA9IHNldC5pdGVyYXRvcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXRlci5yZW1vdmUoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgZW51bUtleSA9IChFbnVtKSBpdGVyLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBrZXkiLCBTaXplLk1pZGRsZSwgZW51bUtleSk7CisgICAgICAgIGFzc2VydFNhbWUoIldyb25nIGtleSIsIFNpemUuTWlkZGxlLCBlbnVtS2V5KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIHVuZXF1YWwgb2JqZWN0IiwgaXRlci5lcXVhbHMoZW51bUtleSkpOworICAgICAgICBpdGVyLnJlbW92ZSgpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgdW5jb250YWluZWQgb2JqZWN0Iiwgc2V0CisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKGVudW1LZXkpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGl0ZXIucmVtb3ZlKCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzaXplIiwgMSwgc2V0LnNpemUoKSk7CisgICAgICAgIGVudW1LZXkgPSAoRW51bSkgaXRlci5uZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcga2V5IiwgU2l6ZS5CaWcsIGVudW1LZXkpOworICAgICAgICBpdGVyLnJlbW92ZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXRlci5uZXh0KCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRW51bU1hcCNnZXQoT2JqZWN0KQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsgInVuY2hlY2tlZCIsICJib3hpbmciIH0pCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgRW51bU1hcCBlbnVtU2l6ZU1hcCA9IG5ldyBFbnVtTWFwKFNpemUuY2xhc3MpOworICAgICAgICBhc3NlcnROdWxsKCJHZXQgcmV0dXJuZWQgbm9uLW51bGwgZm9yIG5vbiBtYXBwZWQga2V5IiwgZW51bVNpemVNYXAKKyAgICAgICAgICAgICAgICAuZ2V0KFNpemUuQmlnKSk7CisgICAgICAgIGVudW1TaXplTWFwLnB1dChTaXplLkJpZywgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiR2V0IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSBmb3IgZ2l2ZW4ga2V5IiwgMSwKKyAgICAgICAgICAgICAgICBlbnVtU2l6ZU1hcC5nZXQoU2l6ZS5CaWcpKTsKKworICAgICAgICBhc3NlcnROdWxsKCJHZXQgcmV0dXJuZWQgbm9uLW51bGwgZm9yIG5vbiBtYXBwZWQga2V5IiwgZW51bVNpemVNYXAKKyAgICAgICAgICAgICAgICAuZ2V0KFNpemUuU21hbGwpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiR2V0IHJldHVybmVkIG5vbi1udWxsIGZvciBub24gZXhpc3RlbnQga2V5IiwgZW51bVNpemVNYXAKKyAgICAgICAgICAgICAgICAuZ2V0KENvbG9yLlJlZCkpOworICAgICAgICBhc3NlcnROdWxsKCJHZXQgcmV0dXJuZWQgbm9uLW51bGwgZm9yIG5vbiBleGlzdGVudCBrZXkiLCBlbnVtU2l6ZU1hcAorICAgICAgICAgICAgICAgIC5nZXQobmV3IEludGVnZXIoMSkpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiR2V0IHJldHVybmVkIG5vbi1udWxsIGZvciBub24gZXhpc3RlbnQga2V5IiwgZW51bVNpemVNYXAKKyAgICAgICAgICAgICAgICAuZ2V0KG51bGwpKTsKKworICAgICAgICBFbnVtTWFwIGVudW1Db2xvck1hcCA9IG5ldyBFbnVtTWFwPENvbG9yLCBEb3VibGU+KENvbG9yLmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiR2V0IHJldHVybmVkIG5vbi1udWxsIGZvciBub24gbWFwcGVkIGtleSIsIGVudW1Db2xvck1hcAorICAgICAgICAgICAgICAgIC5nZXQoQ29sb3IuR3JlZW4pKTsKKyAgICAgICAgZW51bUNvbG9yTWFwLnB1dChDb2xvci5HcmVlbiwgMik7CisgICAgICAgIGFzc2VydEVxdWFscygiR2V0IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSBmb3IgZ2l2ZW4ga2V5IiwgMiwKKyAgICAgICAgICAgICAgICBlbnVtQ29sb3JNYXAuZ2V0KENvbG9yLkdyZWVuKSk7CisgICAgICAgIGFzc2VydE51bGwoIkdldCByZXR1cm5lZCBub24tbnVsbCBmb3Igbm9uIG1hcHBlZCBrZXkiLCBlbnVtQ29sb3JNYXAKKyAgICAgICAgICAgICAgICAuZ2V0KENvbG9yLkJsdWUpKTsKKworICAgICAgICBlbnVtQ29sb3JNYXAucHV0KENvbG9yLkdyZWVuLCBuZXcgRG91YmxlKDQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJHZXQgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIGZvciBnaXZlbiBrZXkiLAorICAgICAgICAgICAgICAgIG5ldyBEb3VibGUoNCksIGVudW1Db2xvck1hcC5nZXQoQ29sb3IuR3JlZW4pKTsKKyAgICAgICAgZW51bUNvbG9yTWFwLnB1dChDb2xvci5HcmVlbiwgbmV3IEludGVnZXIoIjMiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiR2V0IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSBmb3IgZ2l2ZW4ga2V5IiwgbmV3IEludGVnZXIoCisgICAgICAgICAgICAgICAgIjMiKSwgZW51bUNvbG9yTWFwLmdldChDb2xvci5HcmVlbikpOworICAgICAgICBlbnVtQ29sb3JNYXAucHV0KENvbG9yLkdyZWVuLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiQ2FuIG5vdCBoYW5kbGUgbnVsbCB2YWx1ZSIsIGVudW1Db2xvck1hcC5nZXQoQ29sb3IuR3JlZW4pKTsKKyAgICAgICAgRmxvYXQgZiA9IG5ldyBGbG9hdCgiMy40Iik7CisgICAgICAgIGVudW1Db2xvck1hcC5wdXQoQ29sb3IuR3JlZW4sIGYpOworICAgICAgICBhc3NlcnRTYW1lKCJHZXQgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIGZvciBnaXZlbiBrZXkiLCBmLAorICAgICAgICAgICAgICAgIGVudW1Db2xvck1hcC5nZXQoQ29sb3IuR3JlZW4pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRW51bU1hcCNwdXQoT2JqZWN0LE9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3B1dExqYXZhX2xhbmdfT2JqZWN0TGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIEVudW1NYXAgZW51bVNpemVNYXAgPSBuZXcgRW51bU1hcChTaXplLmNsYXNzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVudW1TaXplTWFwLnB1dChDb2xvci5SZWQsIDIpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgQ2xhc3NDYXN0RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIGFzc2VydE51bGwoIlJldHVybiBub24tbnVsbCBmb3Igbm9uIG1hcHBlZCBrZXkiLCBlbnVtU2l6ZU1hcC5wdXQoCisgICAgICAgICAgICAgICAgU2l6ZS5TbWFsbCwgMSkpOworCisgICAgICAgIEVudW1NYXAgZW51bUNvbG9yTWFwID0gbmV3IEVudW1NYXA8Q29sb3IsIERvdWJsZT4oQ29sb3IuY2xhc3MpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW51bUNvbG9yTWFwLnB1dChTaXplLkJpZywgMik7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBDbGFzc0Nhc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVudW1Db2xvck1hcC5wdXQobnVsbCwgMik7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIGFzc2VydE51bGwoIlJldHVybiBub24tbnVsbCBmb3Igbm9uIG1hcHBlZCBrZXkiLCBlbnVtQ29sb3JNYXAucHV0KAorICAgICAgICAgICAgICAgIENvbG9yLkdyZWVuLCAyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuIHdyb25nIHZhbHVlIiwgMiwgZW51bUNvbG9yTWFwLnB1dChDb2xvci5HcmVlbiwKKyAgICAgICAgICAgICAgICBuZXcgRG91YmxlKDQpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuIHdyb25nIHZhbHVlIiwgbmV3IERvdWJsZSg0KSwgZW51bUNvbG9yTWFwLnB1dCgKKyAgICAgICAgICAgICAgICBDb2xvci5HcmVlbiwgbmV3IEludGVnZXIoIjMiKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybiB3cm9uZyB2YWx1ZSIsIG5ldyBJbnRlZ2VyKCIzIiksIGVudW1Db2xvck1hcC5wdXQoCisgICAgICAgICAgICAgICAgQ29sb3IuR3JlZW4sIG51bGwpKTsKKyAgICAgICAgRmxvYXQgZiA9IG5ldyBGbG9hdCgiMy40Iik7CisgICAgICAgIGFzc2VydE51bGwoIlJldHVybiBub24tbnVsbCBmb3Igbm9uIG1hcHBlZCBrZXkiLCBlbnVtQ29sb3JNYXAucHV0KAorICAgICAgICAgICAgICAgIENvbG9yLkdyZWVuLCBmKSk7CisgICAgICAgIGFzc2VydE51bGwoIlJldHVybiBub24tbnVsbCBmb3Igbm9uIG1hcHBlZCBrZXkiLCBlbnVtQ29sb3JNYXAucHV0KAorICAgICAgICAgICAgICAgIENvbG9yLkJsdWUsIDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm4gd3JvbmcgdmFsdWUiLCAyLCBlbnVtQ29sb3JNYXAucHV0KENvbG9yLkJsdWUsCisgICAgICAgICAgICAgICAgbmV3IERvdWJsZSg0KSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtTWFwI3B1dEFsbChNYXApCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoeyAidW5jaGVja2VkIiwgImJveGluZyIgfSkKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3B1dEFsbExqYXZhX3V0aWxfTWFwKCkgeworICAgICAgICBFbnVtTWFwIGVudW1Db2xvck1hcCA9IG5ldyBFbnVtTWFwPENvbG9yLCBEb3VibGU+KENvbG9yLmNsYXNzKTsKKyAgICAgICAgZW51bUNvbG9yTWFwLnB1dChDb2xvci5HcmVlbiwgMik7CisKKyAgICAgICAgRW51bU1hcCBlbnVtU2l6ZU1hcCA9IG5ldyBFbnVtTWFwKFNpemUuY2xhc3MpOworICAgICAgICBlbnVtQ29sb3JNYXAucHV0QWxsKGVudW1TaXplTWFwKTsKKworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5CaWcsIDEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW51bUNvbG9yTWFwLnB1dEFsbChlbnVtU2l6ZU1hcCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBDbGFzc0Nhc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBFbnVtTWFwIGVudW1Db2xvck1hcDEgPSBuZXcgRW51bU1hcDxDb2xvciwgRG91YmxlPihDb2xvci5jbGFzcyk7CisgICAgICAgIGVudW1Db2xvck1hcDEucHV0KENvbG9yLkJsdWUsIDMpOworICAgICAgICBlbnVtQ29sb3JNYXAucHV0QWxsKGVudW1Db2xvck1hcDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkdldCByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUgZm9yIGdpdmVuIGtleSIsIDMsCisgICAgICAgICAgICAgICAgZW51bUNvbG9yTWFwLmdldChDb2xvci5CbHVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgU2l6ZSIsIDIsIGVudW1Db2xvck1hcC5zaXplKCkpOworCisgICAgICAgIGVudW1Db2xvck1hcCA9IG5ldyBFbnVtTWFwPENvbG9yLCBEb3VibGU+KENvbG9yLmNsYXNzKTsKKworICAgICAgICBIYXNoTWFwIGhhc2hDb2xvck1hcCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbnVtQ29sb3JNYXAucHV0QWxsKGhhc2hDb2xvck1hcCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgaGFzaENvbG9yTWFwID0gbmV3IEhhc2hNYXAoKTsKKyAgICAgICAgZW51bUNvbG9yTWFwLnB1dEFsbChoYXNoQ29sb3JNYXApOworCisgICAgICAgIGhhc2hDb2xvck1hcC5wdXQoQ29sb3IuR3JlZW4sIDIpOworICAgICAgICBlbnVtQ29sb3JNYXAucHV0QWxsKGhhc2hDb2xvck1hcCk7CisgICAgICAgIGFzc2VydEVxdWFscygiR2V0IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSBmb3IgZ2l2ZW4ga2V5IiwgMiwKKyAgICAgICAgICAgICAgICBlbnVtQ29sb3JNYXAuZ2V0KENvbG9yLkdyZWVuKSk7CisgICAgICAgIGFzc2VydE51bGwoIkdldCByZXR1cm5lZCBub24tbnVsbCBmb3Igbm9uIG1hcHBlZCBrZXkiLCBlbnVtQ29sb3JNYXAKKyAgICAgICAgICAgICAgICAuZ2V0KENvbG9yLlJlZCkpOworICAgICAgICBoYXNoQ29sb3JNYXAucHV0KENvbG9yLlJlZCwgbmV3IEludGVnZXIoMSkpOworICAgICAgICBlbnVtQ29sb3JNYXAucHV0QWxsKGhhc2hDb2xvck1hcCk7CisgICAgICAgIGFzc2VydEVxdWFscygiR2V0IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSBmb3IgZ2l2ZW4ga2V5IiwgbmV3IEludGVnZXIoCisgICAgICAgICAgICAgICAgMiksIGVudW1Db2xvck1hcC5nZXQoQ29sb3IuR3JlZW4pKTsKKyAgICAgICAgaGFzaENvbG9yTWFwLnB1dChTaXplLkJpZywgMyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbnVtQ29sb3JNYXAucHV0QWxsKGhhc2hDb2xvck1hcCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBDbGFzc0Nhc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBoYXNoQ29sb3JNYXAgPSBuZXcgSGFzaE1hcCgpOworICAgICAgICBoYXNoQ29sb3JNYXAucHV0KG5ldyBJbnRlZ2VyKDEpLCAxKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVudW1Db2xvck1hcC5wdXRBbGwoaGFzaENvbG9yTWFwKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIENsYXNzQ2FzdEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtTWFwI3JlbW92ZShPYmplY3QpCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoeyAidW5jaGVja2VkIiwgImJveGluZyIgfSkKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlbW92ZUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICBFbnVtTWFwIGVudW1TaXplTWFwID0gbmV3IEVudW1NYXAoU2l6ZS5jbGFzcyk7CisgICAgICAgIGFzc2VydE51bGwoIlJlbW92ZSBvZiBub24tbWFwcGVkIGtleSByZXR1cm5lZCBub24tbnVsbCIsIGVudW1TaXplTWFwCisgICAgICAgICAgICAgICAgLnJlbW92ZShTaXplLkJpZykpOworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5CaWcsIDMpOworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5NaWRkbGUsIDIpOworCisgICAgICAgIGFzc2VydE51bGwoIkdldCByZXR1cm5lZCBub24tbnVsbCBmb3Igbm9uIG1hcHBlZCBrZXkiLCBlbnVtU2l6ZU1hcAorICAgICAgICAgICAgICAgIC5nZXQoU2l6ZS5TbWFsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJlbW92ZSByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAzLCBlbnVtU2l6ZU1hcAorICAgICAgICAgICAgICAgIC5yZW1vdmUoU2l6ZS5CaWcpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiR2V0IHJldHVybmVkIG5vbi1udWxsIGZvciBub24gbWFwcGVkIGtleSIsIGVudW1TaXplTWFwCisgICAgICAgICAgICAgICAgLmdldChTaXplLkJpZykpOworICAgICAgICBhc3NlcnROdWxsKCJSZW1vdmUgb2Ygbm9uLW1hcHBlZCBrZXkgcmV0dXJuZWQgbm9uLW51bGwiLCBlbnVtU2l6ZU1hcAorICAgICAgICAgICAgICAgIC5yZW1vdmUoU2l6ZS5CaWcpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiUmVtb3ZlIG9mIG5vbi1leGlzdGVudCBrZXkgcmV0dXJuZWQgbm9uLW51bGwiLCBlbnVtU2l6ZU1hcAorICAgICAgICAgICAgICAgIC5yZW1vdmUoQ29sb3IuUmVkKSk7CisgICAgICAgIGFzc2VydE51bGwoIlJlbW92ZSBvZiBub24tZXhpc3RlbnQga2V5IHJldHVybmVkIG5vbi1udWxsIiwgZW51bVNpemVNYXAKKyAgICAgICAgICAgICAgICAucmVtb3ZlKG5ldyBEb3VibGUoNCkpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiUmVtb3ZlIG9mIG5vbi1leGlzdGVudCBrZXkgcmV0dXJuZWQgbm9uLW51bGwiLCBlbnVtU2l6ZU1hcAorICAgICAgICAgICAgICAgIC5yZW1vdmUobnVsbCkpOworCisgICAgICAgIEVudW1NYXAgZW51bUNvbG9yTWFwID0gbmV3IEVudW1NYXA8Q29sb3IsIERvdWJsZT4oQ29sb3IuY2xhc3MpOworICAgICAgICBhc3NlcnROdWxsKCJHZXQgcmV0dXJuZWQgbm9uLW51bGwgZm9yIG5vbiBtYXBwZWQga2V5IiwgZW51bUNvbG9yTWFwCisgICAgICAgICAgICAgICAgLmdldChDb2xvci5HcmVlbikpOworICAgICAgICBlbnVtQ29sb3JNYXAucHV0KENvbG9yLkdyZWVuLCBuZXcgRG91YmxlKDQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZW1vdmUgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgbmV3IERvdWJsZSg0KSwKKyAgICAgICAgICAgICAgICBlbnVtQ29sb3JNYXAucmVtb3ZlKENvbG9yLkdyZWVuKSk7CisgICAgICAgIGFzc2VydE51bGwoIkdldCByZXR1cm5lZCBub24tbnVsbCBmb3Igbm9uIG1hcHBlZCBrZXkiLCBlbnVtQ29sb3JNYXAKKyAgICAgICAgICAgICAgICAuZ2V0KENvbG9yLkdyZWVuKSk7CisgICAgICAgIGVudW1Db2xvck1hcC5wdXQoQ29sb3IuR3JlZW4sIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJDYW4gbm90IGhhbmRsZSBudWxsIHZhbHVlIiwgZW51bUNvbG9yTWFwCisgICAgICAgICAgICAgICAgLnJlbW92ZShDb2xvci5HcmVlbikpOworICAgICAgICBhc3NlcnROdWxsKCJHZXQgcmV0dXJuZWQgbm9uLW51bGwgZm9yIG5vbiBtYXBwZWQga2V5IiwgZW51bUNvbG9yTWFwCisgICAgICAgICAgICAgICAgLmdldChDb2xvci5HcmVlbikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtTWFwI3NpemUoKQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsgInVuY2hlY2tlZCIsICJib3hpbmciIH0pCisgICAgcHVibGljIHZvaWQgdGVzdF9zaXplKCkgeworICAgICAgICBFbnVtTWFwIGVudW1TaXplTWFwID0gbmV3IEVudW1NYXAoU2l6ZS5jbGFzcyk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDAsIGVudW1TaXplTWFwLnNpemUoKSk7CisgICAgICAgIGVudW1TaXplTWFwLnB1dChTaXplLlNtYWxsLCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzaXplIiwgMSwgZW51bVNpemVNYXAuc2l6ZSgpKTsKKyAgICAgICAgZW51bVNpemVNYXAucHV0KFNpemUuU21hbGwsIDApOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAxLCBlbnVtU2l6ZU1hcC5zaXplKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZW51bVNpemVNYXAucHV0KENvbG9yLlJlZCwgMik7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBDbGFzc0Nhc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzaXplIiwgMSwgZW51bVNpemVNYXAuc2l6ZSgpKTsKKworICAgICAgICBlbnVtU2l6ZU1hcC5wdXQoU2l6ZS5NaWRkbGUsIG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAyLCBlbnVtU2l6ZU1hcC5zaXplKCkpOworICAgICAgICBlbnVtU2l6ZU1hcC5yZW1vdmUoU2l6ZS5CaWcpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAyLCBlbnVtU2l6ZU1hcC5zaXplKCkpOworICAgICAgICBlbnVtU2l6ZU1hcC5yZW1vdmUoU2l6ZS5NaWRkbGUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAxLCBlbnVtU2l6ZU1hcC5zaXplKCkpOworICAgICAgICBlbnVtU2l6ZU1hcC5yZW1vdmUoQ29sb3IuR3JlZW4pOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAxLCBlbnVtU2l6ZU1hcC5zaXplKCkpOworCisgICAgICAgIEVudW1NYXAgZW51bUNvbG9yTWFwID0gbmV3IEVudW1NYXA8Q29sb3IsIERvdWJsZT4oQ29sb3IuY2xhc3MpOworICAgICAgICBlbnVtQ29sb3JNYXAucHV0KENvbG9yLkdyZWVuLCAyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzaXplIiwgMSwgZW51bUNvbG9yTWFwLnNpemUoKSk7CisgICAgICAgIGVudW1Db2xvck1hcC5yZW1vdmUoQ29sb3IuR3JlZW4pOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAwLCBlbnVtQ29sb3JNYXAuc2l6ZSgpKTsKKworICAgICAgICBFbnVtTWFwIGVudW1FbXB0eU1hcCA9IG5ldyBFbnVtTWFwPEVtcHR5LCBEb3VibGU+KEVtcHR5LmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzaXplIiwgMCwgZW51bUVtcHR5TWFwLnNpemUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkVudW1NYXAjdmFsdWVzKCkKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncyggeyAidW5jaGVja2VkIiwgImJveGluZyIgfSkKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3ZhbHVlcygpIHsKKyAgICAgICAgRW51bU1hcCBlbnVtQ29sb3JNYXAgPSBuZXcgRW51bU1hcDxDb2xvciwgRG91YmxlPihDb2xvci5jbGFzcyk7CisgICAgICAgIGVudW1Db2xvck1hcC5wdXQoQ29sb3IuUmVkLCAxKTsKKyAgICAgICAgZW51bUNvbG9yTWFwLnB1dChDb2xvci5CbHVlLCBudWxsKTsKKyAgICAgICAgQ29sbGVjdGlvbiBjb2xsZWN0aW9uID0gZW51bUNvbG9yTWFwLnZhbHVlcygpOworCisgICAgICAgIENvbGxlY3Rpb24gY29sbGVjdGlvbjEgPSBlbnVtQ29sb3JNYXAudmFsdWVzKCk7CisgICAgICAgIGFzc2VydFNhbWUoIlNob3VsZCBiZSBzYW1lIiwgY29sbGVjdGlvbjEsIGNvbGxlY3Rpb24pOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29sbGVjdGlvbi5hZGQobmV3IEludGVnZXIoMSkpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgY29udGFpbmVkIG9iamVjdCIsIGNvbGxlY3Rpb24KKyAgICAgICAgICAgICAgICAuY29udGFpbnMoMSkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgY29udGFpbmVkIG9iamVjdCIsIGNvbGxlY3Rpb24KKyAgICAgICAgICAgICAgICAuY29udGFpbnMobnVsbCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgdW5jb250YWluZWQgb2JqZWN0IiwgY29sbGVjdGlvbgorICAgICAgICAgICAgICAgIC5jb250YWlucygyKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2Ugd2hlbiB0aGUgb2JqZWN0IGNhbiBiZSByZW1vdmVkIiwgY29sbGVjdGlvbgorICAgICAgICAgICAgICAgIC5yZW1vdmUobnVsbCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgdW5jb250YWluZWQgb2JqZWN0IiwgY29sbGVjdGlvbgorICAgICAgICAgICAgICAgIC5jb250YWlucyhudWxsKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIHdoZW4gdGhlIG9iamVjdCBjYW4gbm90IGJlIHJlbW92ZWQiLAorICAgICAgICAgICAgICAgIGNvbGxlY3Rpb24ucmVtb3ZlKG51bGwpKTsKKworICAgICAgICAvLyBUaGUgc2V0IGlzIGJhY2tlZCBieSB0aGUgbWFwIHNvIGNoYW5nZXMgdG8gb25lIGFyZSByZWZsZWN0ZWQgYnkgdGhlCisgICAgICAgIC8vIG90aGVyLgorICAgICAgICBlbnVtQ29sb3JNYXAucHV0KENvbG9yLkJsdWUsIDMpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgY29udGFpbmVkIG9iamVjdCIsIGNvbGxlY3Rpb24KKyAgICAgICAgICAgICAgICAuY29udGFpbnMoMykpOworICAgICAgICBlbnVtQ29sb3JNYXAucmVtb3ZlKENvbG9yLkJsdWUpOworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgdW5jb250YWluZWQgb2JqZWN0IiwgY29sbGVjdGlvbgorICAgICAgICAgICAgICAgIC5jb250YWlucygzKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzaXplIiwgMSwgY29sbGVjdGlvbi5zaXplKCkpOworICAgICAgICBjb2xsZWN0aW9uLmNsZWFyKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDAsIGNvbGxlY3Rpb24uc2l6ZSgpKTsKKworICAgICAgICBlbnVtQ29sb3JNYXAgPSBuZXcgRW51bU1hcDxDb2xvciwgRG91YmxlPihDb2xvci5jbGFzcyk7CisgICAgICAgIGVudW1Db2xvck1hcC5wdXQoQ29sb3IuUmVkLCAxKTsKKyAgICAgICAgZW51bUNvbG9yTWFwLnB1dChDb2xvci5CbHVlLCBudWxsKTsKKyAgICAgICAgY29sbGVjdGlvbiA9IGVudW1Db2xvck1hcC52YWx1ZXMoKTsKKyAgICAgICAgQ29sbGVjdGlvbiBjID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICBjLmFkZChuZXcgSW50ZWdlcigxKSk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCByZXR1cm4gdHJ1ZSIsIGNvbGxlY3Rpb24uY29udGFpbnNBbGwoYykpOworICAgICAgICBjLmFkZChuZXcgRG91YmxlKDMuNCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIHJldHVybiBmYWxzZSIsIGNvbGxlY3Rpb24uY29udGFpbnNBbGwoYykpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIHRydWUiLCBjb2xsZWN0aW9uLnJlbW92ZUFsbChjKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDEsIGNvbGxlY3Rpb24uc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCByZXR1cm4gZmFsc2UiLCBjb2xsZWN0aW9uLnJlbW92ZUFsbChjKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDEsIGNvbGxlY3Rpb24uc2l6ZSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbGxlY3Rpb24uYWRkQWxsKGMpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBlbnVtQ29sb3JNYXAucHV0KENvbG9yLlJlZCwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDIsIGNvbGxlY3Rpb24uc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiB0cnVlIiwgY29sbGVjdGlvbi5yZXRhaW5BbGwoYykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAxLCBjb2xsZWN0aW9uLnNpemUoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgY29sbGVjdGlvbi5yZXRhaW5BbGwoYykpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY29sbGVjdGlvbi5zaXplKCkpOworICAgICAgICBPYmplY3RbXSBhcnJheSA9IGNvbGxlY3Rpb24udG9BcnJheSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGxlbmd0aCIsIDEsIGFycmF5Lmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcga2V5IiwgMSwgYXJyYXlbMF0pOworCisgICAgICAgIGVudW1Db2xvck1hcCA9IG5ldyBFbnVtTWFwPENvbG9yLCBEb3VibGU+KENvbG9yLmNsYXNzKTsKKyAgICAgICAgZW51bUNvbG9yTWFwLnB1dChDb2xvci5SZWQsIDEpOworICAgICAgICBlbnVtQ29sb3JNYXAucHV0KENvbG9yLkJsdWUsIG51bGwpOworICAgICAgICBjb2xsZWN0aW9uID0gZW51bUNvbG9yTWFwLnZhbHVlcygpOworCisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDIsIGNvbGxlY3Rpb24uc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgd2hlbiB0aGUgb2JqZWN0IGNhbiBub3QgYmUgcmVtb3ZlZCIsCisgICAgICAgICAgICAgICAgY29sbGVjdGlvbi5yZW1vdmUobmV3IEludGVnZXIoIjEwIikpKTsKKworICAgICAgICBJdGVyYXRvciBpdGVyID0gZW51bUNvbG9yTWFwLnZhbHVlcygpLml0ZXJhdG9yKCk7CisgICAgICAgIE9iamVjdCB2YWx1ZSA9IGl0ZXIubmV4dCgpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgY29udGFpbmVkIG9iamVjdCIsIGNvbGxlY3Rpb24KKyAgICAgICAgICAgICAgICAuY29udGFpbnModmFsdWUpKTsKKyAgICAgICAgdmFsdWUgPSBpdGVyLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIGNvbnRhaW5lZCBvYmplY3QiLCBjb2xsZWN0aW9uCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKHZhbHVlKSk7CisKKyAgICAgICAgZW51bUNvbG9yTWFwLnB1dChDb2xvci5HcmVlbiwgMSk7CisgICAgICAgIGVudW1Db2xvck1hcC5yZW1vdmUoQ29sb3IuQmx1ZSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm5lZCB0cnVlIGZvciB1bmNvbnRhaW5lZCBvYmplY3QiLCBjb2xsZWN0aW9uCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKHZhbHVlKSk7CisgICAgICAgIGl0ZXIucmVtb3ZlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpdGVyLnJlbW92ZSgpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgdW5jb250YWluZWQgb2JqZWN0IiwgY29sbGVjdGlvbgorICAgICAgICAgICAgICAgIC5jb250YWlucyh2YWx1ZSkpOworCisgICAgICAgIGl0ZXIgPSBlbnVtQ29sb3JNYXAudmFsdWVzKCkuaXRlcmF0b3IoKTsKKyAgICAgICAgdmFsdWUgPSBpdGVyLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIGNvbnRhaW5lZCBvYmplY3QiLCBjb2xsZWN0aW9uCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKHZhbHVlKSk7CisgICAgICAgIGVudW1Db2xvck1hcC5wdXQoQ29sb3IuR3JlZW4sIDMpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgY29udGFpbmVkIG9iamVjdCIsIGNvbGxlY3Rpb24KKyAgICAgICAgICAgICAgICAuY29udGFpbnModmFsdWUpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIGNvbnRhaW5lZCBvYmplY3QiLCBjb2xsZWN0aW9uCisgICAgICAgICAgICAgICAgLnJlbW92ZShuZXcgSW50ZWdlcigiMSIpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDEsIGNvbGxlY3Rpb24uc2l6ZSgpKTsKKyAgICAgICAgY29sbGVjdGlvbi5jbGVhcigpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAwLCBjb2xsZWN0aW9uLnNpemUoKSk7CisKKyAgICAgICAgZW51bUNvbG9yTWFwID0gbmV3IEVudW1NYXA8Q29sb3IsIERvdWJsZT4oQ29sb3IuY2xhc3MpOworICAgICAgICBJbnRlZ2VyIGludGVnZXIxID0gbmV3IEludGVnZXIoMSk7CisgICAgICAgIGVudW1Db2xvck1hcC5wdXQoQ29sb3IuR3JlZW4sIGludGVnZXIxKTsKKyAgICAgICAgZW51bUNvbG9yTWFwLnB1dChDb2xvci5CbHVlLCBudWxsKTsKKyAgICAgICAgY29sbGVjdGlvbiA9IGVudW1Db2xvck1hcC52YWx1ZXMoKTsKKyAgICAgICAgaXRlciA9IGVudW1Db2xvck1hcC52YWx1ZXMoKS5pdGVyYXRvcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXRlci5yZW1vdmUoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdmFsdWUgPSBpdGVyLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSIsIGludGVnZXIxLCB2YWx1ZSk7CisgICAgICAgIGFzc2VydFNhbWUoIldyb25nIHZhbHVlIiwgaW50ZWdlcjEsIHZhbHVlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIHVuZXF1YWwgb2JqZWN0IiwgaXRlci5lcXVhbHModmFsdWUpKTsKKyAgICAgICAgaXRlci5yZW1vdmUoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIHVuZXF1YWwgb2JqZWN0IiwgaXRlci5lcXVhbHModmFsdWUpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGl0ZXIucmVtb3ZlKCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDEsIGNvbGxlY3Rpb24uc2l6ZSgpKTsKKyAgICAgICAgdmFsdWUgPSBpdGVyLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlJldHVybmVkIHRydWUgZm9yIHVuZXF1YWwgb2JqZWN0IiwgaXRlci5lcXVhbHModmFsdWUpKTsKKyAgICAgICAgaXRlci5yZW1vdmUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGl0ZXIubmV4dCgpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogc2VyaWFsaXphdGlvbi9kZXNlcmlhbGl6YXRpb24uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoeyAidW5jaGVja2VkIiwgImJveGluZyIgfSkKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXphdGlvblNlbGYoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRW51bU1hcCBlbnVtQ29sb3JNYXAgPSBuZXcgRW51bU1hcDxDb2xvciwgRG91YmxlPihDb2xvci5jbGFzcyk7CisgICAgICAgIGVudW1Db2xvck1hcC5wdXQoQ29sb3IuQmx1ZSwgMyk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0LnZlcmlmeVNlbGYoZW51bUNvbG9yTWFwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBzZXJpYWxpemF0aW9uL2Rlc2VyaWFsaXphdGlvbiBjb21wYXRpYmlsaXR5IHdpdGggUkkuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoeyAidW5jaGVja2VkIiwgImJveGluZyIgfSkKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXphdGlvbkNvbXBhdGliaWxpdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRW51bU1hcCBlbnVtQ29sb3JNYXAgPSBuZXcgRW51bU1hcDxDb2xvciwgRG91YmxlPihDb2xvci5jbGFzcyk7CisgICAgICAgIGVudW1Db2xvck1hcC5wdXQoQ29sb3IuUmVkLCAxKTsKKyAgICAgICAgZW51bUNvbG9yTWFwLnB1dChDb2xvci5CbHVlLCAzKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3QudmVyaWZ5R29sZGVuKHRoaXMsIGVudW1Db2xvck1hcCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9ueworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0VudW1TZXRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9FbnVtU2V0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiMzM4NzcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9FbnVtU2V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjAwMyBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS50ZXN0ZnJhbWV3b3JrLnNlcmlhbGl6YXRpb24uU2VyaWFsaXphdGlvblRlc3Q7CisKK3B1YmxpYyBjbGFzcyBFbnVtU2V0VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBzdGF0aWMgZmluYWwgYm9vbGVhbiBkaXNhYmxlUklCdWdzID0gdHJ1ZTsKKworICAgIHN0YXRpYyBlbnVtIEVudW1XaXRoSW5uZXJDbGFzcyB7CisgICAgICAgIGEsIGIsIGMsIGQsIGUsIGYgeworICAgICAgICB9LAorICAgIH0KKworICAgIGVudW0gRW51bVdpdGhBbGxJbm5lckNsYXNzIHsKKyAgICAgICAgYSB7fSwKKyAgICAgICAgYiB7fSwKKyAgICB9CisKKyAgICBzdGF0aWMgZW51bSBFbnVtRm9vIHsKKyAgICAgICAgYSwgYixjLCBkLCBlLCBmLCBnLCBoLCBpLCBqLCBrLCBsLCBtLCBuLCBvLCBwLCBxLCByLCBzLCB0LCB1LCB2LCB3LCB4LCB5LCB6LCBBLCBCLCBDLCBELCBFLCBGLCBHLCBILCBJLCBKLCBLLCBMLCBNLCBOLCBPLCBQLCBRLCBSLCBTLCBULCBVLCBWLCBXLCBYLCBZLCBaLCBhYSwgYmIsIGNjLCBkZCwgZWUsIGZmLCBnZywgaGgsIGlpLCBqaiwga2ssIGxsLAorICAgIH0KKworICAgIHN0YXRpYyBlbnVtIEVtcHR5RW51bSB7CisgICAgICAgIC8vIGV4cGVjdGVkCisgICAgfQorCisgICAgc3RhdGljIGVudW0gSHVnZUVudW1XaXRoSW5uZXJDbGFzcyB7CisgICAgICAgIGF7fSwgYnt9LCBje30sIGR7fSwgZXt9LCBme30sIGd7fSwgaHt9LCBpe30sIGp7fSwga3t9LCBse30sIG17fSwgbnt9LCBve30sIHB7fSwgcXt9LCBye30sIHN7fSwgdHt9LCB1e30sIHZ7fSwgd3t9LCB4e30sIHl7fSwgent9LCBBe30sIEJ7fSwgQ3t9LCBEe30sIEV7fSwgRnt9LCBHe30sIEh7fSwgSXt9LCBKe30sIEt7fSwgTHt9LCBNe30sIE57fSwgT3t9LCBQe30sIFF7fSwgUnt9LCBTe30sIFR7fSwgVXt9LCBWe30sIFd7fSwgWHt9LCBZe30sIFp7fSwgYWF7fSwgYmJ7fSwgY2N7fSwgZGR7fSwgZWV7fSwgZmZ7fSwgZ2d7fSwgaGh7fSwgaWl7fSwgamp7fSwga2t7fSwgbGx7fSwgbW17fSwKKyAgICB9CisKKyAgICBzdGF0aWMgZW51bSBIdWdlRW51bSB7CisgICAgICAgIGEsIGIsIGMsIGQsIGUsIGYsIGcsIGgsIGksIGosIGssIGwsIG0sIG4sIG8sIHAsIHEsIHIsIHMsIHQsIHUsIHYsIHcsIHgsIHksIHosIEEsIEIsIEMsIEQsIEUsIEYsIEcsIEgsIEksIEosIEssIEwsIE0sIE4sIE8sIFAsIFEsIFIsIFMsIFQsIFUsIFYsIFcsIFgsIFksIFosIGFhLCBiYiwgY2MsIGRkLCBlZSwgZmYsIGdnLCBoaCwgaWksIGpqLCBraywgbGwsIG1tLAorICAgIH0KKworICAgIHN0YXRpYyBlbnVtIEh1Z2VFbnVtQ291bnQgeworICAgICAgICBOTzEsIE5PMiwgTk8zLCBOTzQsIE5PNSwgTk82LCBOTzcsIE5POCwgTk85LCBOTzEwLCBOTzExLCBOTzEyLCBOTzEzLCBOTzE0LCBOTzE1LCBOTzE2LCBOTzE3LCBOTzE4LCBOTzE5LCBOTzIwLAorICAgICAgICBOTzIxLCBOTzIyLCBOTzIzLCBOTzI0LCBOTzI1LCBOTzI2LCBOTzI3LCBOTzI4LCBOTzI5LCBOTzMwLCBOTzMxLCBOTzMyLCBOTzMzLCBOTzM0LCBOTzM1LCBOTzM2LCBOTzM3LCBOTzM4LCBOTzM5LCBOTzQwLAorICAgICAgICBOTzQxLCBOTzQyLCBOTzQzLCBOTzQ0LCBOTzQ1LCBOTzQ2LCBOTzQ3LCBOTzQ4LCBOTzQ5LCBOTzUwLCBOTzUxLCBOTzUyLCBOTzUzLCBOTzU0LCBOTzU1LCBOTzU2LCBOTzU3LCBOTzU4LCBOTzU5LCBOTzYwLAorICAgICAgICBOTzYxLCBOTzYyLCBOTzYzLCBOTzY0LCBOTzY1LCBOTzY2LCBOTzY3LCBOTzY4LCBOTzY5LCBOTzcwLCBOTzcxLCBOTzcyLCBOTzczLCBOTzc0LCBOTzc1LCBOTzc2LCBOTzc3LCBOTzc4LCBOTzc5LCBOTzgwLAorICAgICAgICBOTzgxLCBOTzgyLCBOTzgzLCBOTzg0LCBOTzg1LCBOTzg2LCBOTzg3LCBOTzg4LCBOTzg5LCBOTzkwLCBOTzkxLCBOTzkyLCBOTzkzLCBOTzk0LCBOTzk1LCBOTzk2LCBOTzk3LCBOTzk4LCBOTzk5LCBOTzEwMCwKKyAgICAgICAgTk8xMDEsIE5PMTAyLCBOTzEwMywgTk8xMDQsIE5PMTA1LCBOTzEwNiwgTk8xMDcsIE5PMTA4LCBOTzEwOSwgTk8xMTAsIE5PMTExLCBOTzExMiwgTk8xMTMsIE5PMTE0LCBOTzExNSwgTk8xMTYsIE5PMTE3LCBOTzExOCwgTk8xMTksIE5PMTIwLAorICAgICAgICBOTzEyMSwgTk8xMjIsIE5PMTIzLCBOTzEyNCwgTk8xMjUsIE5PMTI2LCBOTzEyNywgTk8xMjgsIE5PMTI5LCBOTzEzMCwKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRW51bVNldCNub25lT2YoamF2YS5sYW5nLkNsYXNzKQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfTm9uZU9mX0xDbGFzcygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVudW1TZXQubm9uZU9mKChDbGFzcykgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0Lm5vbmVPZihFbnVtLmNsYXNzKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBDbGFzc0Nhc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGNjZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIENsYXNzPEVudW1XaXRoQWxsSW5uZXJDbGFzcz4gYyA9IChDbGFzczxFbnVtV2l0aEFsbElubmVyQ2xhc3M+KSBFbnVtV2l0aEFsbElubmVyQ2xhc3MuYQorICAgICAgICAgICAgICAgIC5nZXRDbGFzcygpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgRW51bVNldC5ub25lT2YoYyk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgQ2xhc3NDYXN0RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgRW51bVNldDxFbnVtV2l0aEFsbElubmVyQ2xhc3M+IHNldFdpdGhJbm5lckNsYXNzID0gRW51bVNldAorICAgICAgICAgICAgICAgIC5ub25lT2YoRW51bVdpdGhBbGxJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzZXRXaXRoSW5uZXJDbGFzcyk7CisKKyAgICAgICAgLy8gdGVzdCBlbnVtIHR5cGUgd2l0aCBtb3JlIHRoYW4gNjQgZWxlbWVudHMKKyAgICAgICAgQ2xhc3M8SHVnZUVudW1XaXRoSW5uZXJDbGFzcz4gaGMgPSAoQ2xhc3M8SHVnZUVudW1XaXRoSW5uZXJDbGFzcz4pIEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYQorICAgICAgICAgICAgLmdldENsYXNzKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0Lm5vbmVPZihoYyk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgQ2xhc3NDYXN0RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgRW51bVNldDxIdWdlRW51bVdpdGhJbm5lckNsYXNzPiBodWdlU2V0V2l0aElubmVyQ2xhc3MgPSBFbnVtU2V0CisgICAgICAgICAgICAubm9uZU9mKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuY2xhc3MpOworICAgICAgICBhc3NlcnROb3ROdWxsKGh1Z2VTZXRXaXRoSW5uZXJDbGFzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkh1Z2VFbnVtU2V0I2l0ZXJhdG9yKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2l0ZXJhdG9yX0h1Z2VFbnVtU2V0KCkgeworICAgICAgICBFbnVtU2V0PEh1Z2VFbnVtQ291bnQ+IHNldDsKKyAgICAgICAgT2JqZWN0W10gYXJyYXk7CisKKyAgICAgICAgLy8gVGVzdCBIdWdlRW51bVNldCB3aXRoIDY1IGVsZW1lbnRzCisgICAgICAgIC8vIHdoaWNoIGlzIG1vcmUgdGhhbiB0aGUgYml0cyBvZiBMb25nCisgICAgICAgIHNldCA9IEVudW1TZXQucmFuZ2UoSHVnZUVudW1Db3VudC5OTzEsIEh1Z2VFbnVtQ291bnQuTk82NSk7CisgICAgICAgIGFycmF5ID0gc2V0LnRvQXJyYXkoKTsKKyAgICAgICAgZm9yIChIdWdlRW51bUNvdW50IGNvdW50IDogc2V0KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoY291bnQsIChIdWdlRW51bUNvdW50KSBhcnJheVtjb3VudC5vcmRpbmFsKCldKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3QgSHVnZUVudW1TZXQgd2l0aCAxMzAgZWxlbWVudHMKKyAgICAgICAgLy8gd2hpY2ggaXMgbW9yZSB0aGFuIHR3aWNlIG9mIHRoZSBiaXRzIG9mIExvbmcKKyAgICAgICAgc2V0ID0gRW51bVNldC5yYW5nZShIdWdlRW51bUNvdW50Lk5PMSwgSHVnZUVudW1Db3VudC5OTzEzMCk7CisgICAgICAgIGFycmF5ID0gc2V0LnRvQXJyYXkoKTsKKyAgICAgICAgZm9yIChIdWdlRW51bUNvdW50IGNvdW50IDogc2V0KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoY291bnQsIChIdWdlRW51bUNvdW50KSBhcnJheVtjb3VudC5vcmRpbmFsKCldKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVJdGVyYXRvclJlbW92ZUZyb21IdWdlRW51bVNldCgpIHsKKyAgICAgICAgRW51bVNldDxIdWdlRW51bUNvdW50PiBzZXQgPSBFbnVtU2V0Lm5vbmVPZihIdWdlRW51bUNvdW50LmNsYXNzKTsKKyAgICAgICAgc2V0LmFkZChIdWdlRW51bUNvdW50Lk5PNjQpOworICAgICAgICBzZXQuYWRkKEh1Z2VFbnVtQ291bnQuTk82NSk7CisgICAgICAgIHNldC5hZGQoSHVnZUVudW1Db3VudC5OTzEyOCk7CisgICAgICAgIEl0ZXJhdG9yPEh1Z2VFbnVtQ291bnQ+IGl0ZXJhdG9yID0gc2V0Lml0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydFRydWUoaXRlcmF0b3IuaGFzTmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEh1Z2VFbnVtQ291bnQuTk82NCwgaXRlcmF0b3IubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShpdGVyYXRvci5oYXNOZXh0KCkpOworICAgICAgICBpdGVyYXRvci5yZW1vdmUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEh1Z2VFbnVtQ291bnQuTk82NSwgaXRlcmF0b3IubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShpdGVyYXRvci5oYXNOZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoSHVnZUVudW1Db3VudC5OTzEyOCwgaXRlcmF0b3IubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoaXRlcmF0b3IuaGFzTmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEVudW1TZXQub2YoSHVnZUVudW1Db3VudC5OTzY1LCBIdWdlRW51bUNvdW50Lk5PMTI4KSwgc2V0KTsKKyAgICAgICAgaXRlcmF0b3IucmVtb3ZlKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhFbnVtU2V0Lm9mKEh1Z2VFbnVtQ291bnQuTk82NSksIHNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkVudW1TZXQjYWxsT2YoamF2YS5sYW5nLkNsYXNzKQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfQWxsT2ZfTENsYXNzKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgRW51bVNldC5hbGxPZigoQ2xhc3MpIG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgRW51bVNldC5hbGxPZihFbnVtLmNsYXNzKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBDbGFzc0Nhc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGNjZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIEVudW1TZXQ8RW51bUZvbz4gZW51bVNldCA9IEVudW1TZXQuYWxsT2YoRW51bUZvby5jbGFzcyk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBvZiBlbnVtU2V0IHNob3VsZCBiZSA2NCIsIDY0LCBlbnVtU2V0LnNpemUoKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgICAgICAgImVudW1TZXQgc2hvdWxkIG5vdCBjb250YWluIG51bGwgdmFsdWUiLCBlbnVtU2V0LmNvbnRhaW5zKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiZW51bVNldCBzaG91bGQgY29udGFpbiBFbnVtRm9vLmEiLCBlbnVtU2V0LmNvbnRhaW5zKEVudW1Gb28uYSkpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJlbnVtU2V0IHNob3VsZCBjb250YWluIEVudW1Gb28uYiIsIGVudW1TZXQuY29udGFpbnMoRW51bUZvby5iKSk7CisKKyAgICAgICAgZW51bVNldC5hZGQoRW51bUZvby5hKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgYmUgZXF1YWwiLCA2NCwgZW51bVNldC5zaXplKCkpOworCisgICAgICAgIEVudW1TZXQ8RW51bUZvbz4gYW5vdGhlclNldCA9IEVudW1TZXQuYWxsT2YoRW51bUZvby5jbGFzcyk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIGJlIGVxdWFsIiwgZW51bVNldCwgYW5vdGhlclNldCk7CisgICAgICAgIGFzc2VydE5vdFNhbWUoIlNob3VsZCBub3QgYmUgaWRlbnRpY2FsIiwgZW51bVNldCwgYW5vdGhlclNldCk7CisKKyAgICAgICAgLy8gdGVzdCBlbnVtIHdpdGggbW9yZSB0aGFuIDY0IGVsZW1lbnRzCisgICAgICAgIEVudW1TZXQ8SHVnZUVudW0+IGh1Z2VFbnVtU2V0ID0gRW51bVNldC5hbGxPZihIdWdlRW51bS5jbGFzcyk7CisgICAgICAgIGFzc2VydEVxdWFscyg2NSwgaHVnZUVudW1TZXQuc2l6ZSgpKTsKKworICAgICAgICBhc3NlcnRGYWxzZShodWdlRW51bVNldC5jb250YWlucyhudWxsKSk7CisgICAgICAgIGFzc2VydFRydWUoaHVnZUVudW1TZXQuY29udGFpbnMoSHVnZUVudW0uYSkpOworICAgICAgICBhc3NlcnRUcnVlKGh1Z2VFbnVtU2V0LmNvbnRhaW5zKEh1Z2VFbnVtLmIpKTsKKworICAgICAgICBodWdlRW51bVNldC5hZGQoSHVnZUVudW0uYSk7CisgICAgICAgIGFzc2VydEVxdWFscyg2NSwgaHVnZUVudW1TZXQuc2l6ZSgpKTsKKworICAgICAgICBFbnVtU2V0PEh1Z2VFbnVtPiBhbm90aGVySHVnZVNldCA9IEVudW1TZXQuYWxsT2YoSHVnZUVudW0uY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoaHVnZUVudW1TZXQsIGFub3RoZXJIdWdlU2V0KTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShodWdlRW51bVNldCwgYW5vdGhlckh1Z2VTZXQpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkVudW1TZXQjYWRkKEUpCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRfRSgpIHsKKyAgICAgICAgU2V0PEVudW1Gb28+IHNldCA9IEVudW1TZXQubm9uZU9mKEVudW1Gb28uY2xhc3MpOworICAgICAgICBzZXQuYWRkKEVudW1Gb28uYSk7CisgICAgICAgIHNldC5hZGQoRW51bUZvby5iKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2V0LmFkZChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gdGVzdCBlbnVtIHR5cGUgd2l0aCBtb3JlIHRoYW4gNjQgZWxlbWVudHMKKyAgICAgICAgU2V0IHJhd1NldCA9IHNldDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhd1NldC5hZGQoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5iKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBDbGFzc0Nhc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBzZXQuY2xlYXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldC5hZGQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gc2V0LmFkZChFbnVtRm9vLmEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNpemUgc2hvdWxkIGJlIDE6IiwgMSwgc2V0LnNpemUoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybiB2YWx1ZSBzaG91bGQgYmUgdHJ1ZSIsIHJlc3VsdCk7CisKKyAgICAgICAgcmVzdWx0ID0gc2V0LmFkZChFbnVtRm9vLmEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNpemUgc2hvdWxkIGJlIDE6IiwgMSwgc2V0LnNpemUoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm4gdmFsdWUgc2hvdWxkIGJlIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICBzZXQuYWRkKEVudW1Gb28uYik7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBzaG91bGQgYmUgMjoiLCAyLCBzZXQuc2l6ZSgpKTsKKworICAgICAgICByYXdTZXQgPSBzZXQ7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYXdTZXQuYWRkKEVudW1XaXRoQWxsSW5uZXJDbGFzcy5hKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBDbGFzc0Nhc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYXdTZXQuYWRkKEVudW1XaXRoSW5uZXJDbGFzcy5hKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBDbGFzc0Nhc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYXdTZXQuYWRkKG5ldyBPYmplY3QoKSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgQ2xhc3NDYXN0RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2goQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyB0ZXN0IGVudW0gdHlwZSB3aXRoIG1vcmUgdGhhbiA2NCBlbGVtZW50cworICAgICAgICBTZXQ8SHVnZUVudW0+IGh1Z2VTZXQgPSBFbnVtU2V0Lm5vbmVPZihIdWdlRW51bS5jbGFzcyk7CisgICAgICAgIHJlc3VsdCA9IGh1Z2VTZXQuYWRkKEh1Z2VFbnVtLmEpOworICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCk7CisKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5hZGQoSHVnZUVudW0uYSk7CisgICAgICAgIGFzc2VydEZhbHNlKHJlc3VsdCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGh1Z2VTZXQuYWRkKG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICByYXdTZXQgPSBodWdlU2V0OworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmF3U2V0LmFkZChIdWdlRW51bVdpdGhJbm5lckNsYXNzLmIpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IENsYXNzQ2FzdEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByYXdTZXQuYWRkKG5ldyBPYmplY3QoKSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgQ2xhc3NDYXN0RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5hZGQoSHVnZUVudW0ubW0pOworICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCk7CisgICAgICAgIHJlc3VsdCA9IGh1Z2VTZXQuYWRkKEh1Z2VFbnVtLm1tKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGh1Z2VTZXQuc2l6ZSgpKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtU2V0I2FkZEFsbChDb2xsZWN0aW9uKQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCB7ICJ1bmNoZWNrZWQiLCAiYm94aW5nIiB9KQorICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkQWxsX0xDb2xsZWN0aW9uKCkgeworCisgICAgICAgIFNldDxFbnVtRm9vPiBzZXQgPSBFbnVtU2V0Lm5vbmVPZihFbnVtRm9vLmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIHNob3VsZCBiZSAwOiIsIDAsIHNldC5zaXplKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXQuYWRkQWxsKG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBTZXQgZW1wdHlTZXQgPSBFbnVtU2V0Lm5vbmVPZihFbXB0eUVudW0uY2xhc3MpOworICAgICAgICBFbnVtW10gZWxlbWVudHMgPSBFbXB0eUVudW0uY2xhc3MuZ2V0RW51bUNvbnN0YW50cygpOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGVtcHR5U2V0LmFkZChlbGVtZW50c1tpXSk7CisgICAgICAgIH0KKyAgICAgICAgYm9vbGVhbiByZXN1bHQgPSBzZXQuYWRkQWxsKGVtcHR5U2V0KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKworICAgICAgICBDb2xsZWN0aW9uPEVudW1Gb28+IGNvbGxlY3Rpb24gPSBuZXcgQXJyYXlMaXN0PEVudW1Gb28+KCk7CisgICAgICAgIGNvbGxlY3Rpb24uYWRkKEVudW1Gb28uYSk7CisgICAgICAgIGNvbGxlY3Rpb24uYWRkKEVudW1Gb28uYik7CisgICAgICAgIHJlc3VsdCA9IHNldC5hZGRBbGwoY29sbGVjdGlvbik7CisgICAgICAgIGFzc2VydFRydWUoImFkZEFsbCBzaG91bGQgYmUgc3VjY2Vzc2Z1bCIsIHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBzaG91bGQgYmUgMjoiLCAyLCBzZXQuc2l6ZSgpKTsKKworICAgICAgICBzZXQgPSBFbnVtU2V0Lm5vbmVPZihFbnVtRm9vLmNsYXNzKTsKKworICAgICAgICBDb2xsZWN0aW9uIHJhd0NvbGxlY3Rpb24gPSBuZXcgQXJyYXlMaXN0PEludGVnZXI+KCk7CisgICAgICAgIHJlc3VsdCA9IHNldC5hZGRBbGwocmF3Q29sbGVjdGlvbik7CisgICAgICAgIGFzc2VydEZhbHNlKHJlc3VsdCk7CisgICAgICAgIHJhd0NvbGxlY3Rpb24uYWRkKDEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2V0LmFkZEFsbChyYXdDb2xsZWN0aW9uKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBDbGFzc0Nhc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBTZXQ8RW51bUZvbz4gZnVsbFNldCA9IEVudW1TZXQubm9uZU9mKEVudW1Gb28uY2xhc3MpOworICAgICAgICBmdWxsU2V0LmFkZChFbnVtRm9vLmEpOworICAgICAgICBmdWxsU2V0LmFkZChFbnVtRm9vLmIpOworICAgICAgICByZXN1bHQgPSBzZXQuYWRkQWxsKGZ1bGxTZXQpOworICAgICAgICBhc3NlcnRUcnVlKCJhZGRBbGwgc2hvdWxkIGJlIHN1Y2Nlc3NmdWwiLCByZXN1bHQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNpemUgb2Ygc2V0IHNob3VsZCBiZSAyIiwgMiwgc2V0LnNpemUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZ1bGxTZXQuYWRkQWxsKG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBTZXQgZnVsbFNldFdpdGhTdWJjbGFzcyA9IEVudW1TZXQubm9uZU9mKEVudW1XaXRoSW5uZXJDbGFzcy5jbGFzcyk7CisgICAgICAgIGVsZW1lbnRzID0gRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzLmdldEVudW1Db25zdGFudHMoKTsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBmdWxsU2V0V2l0aFN1YmNsYXNzLmFkZChlbGVtZW50c1tpXSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldC5hZGRBbGwoZnVsbFNldFdpdGhTdWJjbGFzcyk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgQ2xhc3NDYXN0RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIFNldDxFbnVtV2l0aElubmVyQ2xhc3M+IHNldFdpdGhTdWJjbGFzcyA9IGZ1bGxTZXRXaXRoU3ViY2xhc3M7CisgICAgICAgIHJlc3VsdCA9IHNldFdpdGhTdWJjbGFzcy5hZGRBbGwoc2V0V2l0aFN1YmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCByZXR1cm4gZmFsc2UiLCByZXN1bHQpOworCisgICAgICAgIFNldDxFbnVtV2l0aElubmVyQ2xhc3M+IGFub3RoZXJTZXRXaXRoU3ViY2xhc3MgPSBFbnVtU2V0CisgICAgICAgICAgICAgICAgLm5vbmVPZihFbnVtV2l0aElubmVyQ2xhc3MuY2xhc3MpOworICAgICAgICBlbGVtZW50cyA9IEVudW1XaXRoSW5uZXJDbGFzcy5jbGFzcy5nZXRFbnVtQ29uc3RhbnRzKCk7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYW5vdGhlclNldFdpdGhTdWJjbGFzcy5hZGQoKEVudW1XaXRoSW5uZXJDbGFzcykgZWxlbWVudHNbaV0pOworICAgICAgICB9CisgICAgICAgIHJlc3VsdCA9IHNldFdpdGhTdWJjbGFzcy5hZGRBbGwoYW5vdGhlclNldFdpdGhTdWJjbGFzcyk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICBhbm90aGVyU2V0V2l0aFN1YmNsYXNzLnJlbW92ZShFbnVtV2l0aElubmVyQ2xhc3MuYSk7CisgICAgICAgIHJlc3VsdCA9IHNldFdpdGhTdWJjbGFzcy5hZGRBbGwoYW5vdGhlclNldFdpdGhTdWJjbGFzcyk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICAvLyB0ZXN0IGVudW0gdHlwZSB3aXRoIG1vcmUgdGhhbiA2NCBlbGVtZW50cworICAgICAgICBTZXQ8SHVnZUVudW0+IGh1Z2VTZXQgPSBFbnVtU2V0Lm5vbmVPZihIdWdlRW51bS5jbGFzcyk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBodWdlU2V0LnNpemUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGh1Z2VTZXQuYWRkQWxsKG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBodWdlU2V0ID0gRW51bVNldC5hbGxPZihIdWdlRW51bS5jbGFzcyk7CisgICAgICAgIHJlc3VsdCA9IGh1Z2VTZXQuYWRkQWxsKGh1Z2VTZXQpOworICAgICAgICBhc3NlcnRGYWxzZShyZXN1bHQpOworCisgICAgICAgIGh1Z2VTZXQgPSBFbnVtU2V0Lm5vbmVPZihIdWdlRW51bS5jbGFzcyk7CisgICAgICAgIENvbGxlY3Rpb248SHVnZUVudW0+IGh1Z2VDb2xsZWN0aW9uID0gbmV3IEFycmF5TGlzdDxIdWdlRW51bT4oKTsKKyAgICAgICAgaHVnZUNvbGxlY3Rpb24uYWRkKEh1Z2VFbnVtLmEpOworICAgICAgICBodWdlQ29sbGVjdGlvbi5hZGQoSHVnZUVudW0uYik7CisgICAgICAgIHJlc3VsdCA9IGh1Z2VTZXQuYWRkQWxsKGh1Z2VDb2xsZWN0aW9uKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgc2V0LnNpemUoKSk7CisKKyAgICAgICAgaHVnZVNldCA9IEVudW1TZXQubm9uZU9mKEh1Z2VFbnVtLmNsYXNzKTsKKworICAgICAgICByYXdDb2xsZWN0aW9uID0gbmV3IEFycmF5TGlzdDxJbnRlZ2VyPigpOworICAgICAgICByZXN1bHQgPSBodWdlU2V0LmFkZEFsbChyYXdDb2xsZWN0aW9uKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKyAgICAgICAgcmF3Q29sbGVjdGlvbi5hZGQoMSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBodWdlU2V0LmFkZEFsbChyYXdDb2xsZWN0aW9uKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBDbGFzc0Nhc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBFbnVtU2V0PEh1Z2VFbnVtPiBhSHVnZVNldCA9IEVudW1TZXQubm9uZU9mKEh1Z2VFbnVtLmNsYXNzKTsKKyAgICAgICAgYUh1Z2VTZXQuYWRkKEh1Z2VFbnVtLmEpOworICAgICAgICBhSHVnZVNldC5hZGQoSHVnZUVudW0uYik7CisgICAgICAgIHJlc3VsdCA9IGh1Z2VTZXQuYWRkQWxsKGFIdWdlU2V0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgaHVnZVNldC5zaXplKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhSHVnZVNldC5hZGRBbGwobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIFNldCBodWdlU2V0V2l0aFN1YmNsYXNzID0gRW51bVNldC5hbGxPZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGh1Z2VTZXQuYWRkQWxsKGh1Z2VTZXRXaXRoU3ViY2xhc3MpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IENsYXNzQ2FzdEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBTZXQ8SHVnZUVudW1XaXRoSW5uZXJDbGFzcz4gaHVnZVNldFdpdGhJbm5lclN1YmNsYXNzID0gaHVnZVNldFdpdGhTdWJjbGFzczsKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldFdpdGhJbm5lclN1YmNsYXNzLmFkZEFsbChodWdlU2V0V2l0aElubmVyU3ViY2xhc3MpOworICAgICAgICBhc3NlcnRGYWxzZShyZXN1bHQpOworCisgICAgICAgIFNldDxIdWdlRW51bVdpdGhJbm5lckNsYXNzPiBhbm90aGVySHVnZVNldFdpdGhTdWJjbGFzcyA9IEVudW1TZXQKKyAgICAgICAgICAgICAgICAuYWxsT2YoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5jbGFzcyk7CisgICAgICAgIHJlc3VsdCA9IGh1Z2VTZXRXaXRoU3ViY2xhc3MuYWRkQWxsKGFub3RoZXJIdWdlU2V0V2l0aFN1YmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKworICAgICAgICBhbm90aGVySHVnZVNldFdpdGhTdWJjbGFzcy5yZW1vdmUoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5hKTsKKyAgICAgICAgcmVzdWx0ID0gc2V0V2l0aFN1YmNsYXNzLmFkZEFsbChhbm90aGVyU2V0V2l0aFN1YmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtU2V0I3JlbW92ZShPYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZW1vdmVfTE9qZWN0KCkgeworICAgICAgICBTZXQ8RW51bUZvbz4gc2V0ID0gRW51bVNldC5ub25lT2YoRW51bUZvby5jbGFzcyk7CisgICAgICAgIEVudW1bXSBlbGVtZW50cyA9IEVudW1Gb28uY2xhc3MuZ2V0RW51bUNvbnN0YW50cygpOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHNldC5hZGQoKEVudW1Gb28pIGVsZW1lbnRzW2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gc2V0LnJlbW92ZShudWxsKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIidzZXQnIGRvZXMgbm90IGNvbnRhaW4gbnVsbCIsIHJlc3VsdCk7CisKKyAgICAgICAgcmVzdWx0ID0gc2V0LnJlbW92ZShFbnVtRm9vLmEpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIHRydWUiLCByZXN1bHQpOworICAgICAgICByZXN1bHQgPSBzZXQucmVtb3ZlKEVudW1Gb28uYSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlNpemUgb2Ygc2V0IHNob3VsZCBiZSA2MzoiLCA2Mywgc2V0LnNpemUoKSk7CisKKyAgICAgICAgcmVzdWx0ID0gc2V0LnJlbW92ZShFbnVtV2l0aElubmVyQ2xhc3MuYSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKyAgICAgICAgcmVzdWx0ID0gc2V0LnJlbW92ZShFbnVtV2l0aElubmVyQ2xhc3MuZik7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICAvLyB0ZXN0IGVudW0gd2l0aCBtb3JlIHRoYW4gNjQgZWxlbWVudHMKKyAgICAgICAgU2V0PEh1Z2VFbnVtPiBodWdlU2V0ID0gRW51bVNldC5hbGxPZihIdWdlRW51bS5jbGFzcyk7CisKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5yZW1vdmUobnVsbCk7CisgICAgICAgIGFzc2VydEZhbHNlKCInc2V0JyBkb2VzIG5vdCBjb250YWluIG51bGwiLCByZXN1bHQpOworCisgICAgICAgIHJlc3VsdCA9IGh1Z2VTZXQucmVtb3ZlKEh1Z2VFbnVtLmEpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIHRydWUiLCByZXN1bHQpOworICAgICAgICByZXN1bHQgPSBodWdlU2V0LnJlbW92ZShIdWdlRW51bS5hKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCByZXR1cm4gZmFsc2UiLCByZXN1bHQpOworCisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBvZiBzZXQgc2hvdWxkIGJlIDY0OiIsIDY0LCBodWdlU2V0LnNpemUoKSk7CisKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5yZW1vdmUoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5hKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCByZXR1cm4gZmFsc2UiLCByZXN1bHQpOworICAgICAgICByZXN1bHQgPSBodWdlU2V0LnJlbW92ZShIdWdlRW51bVdpdGhJbm5lckNsYXNzLmYpOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIHJldHVybiBmYWxzZSIsIHJlc3VsdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkVudW1TZXQjZXF1YWxzKE9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VxdWFsc19MT2JqZWN0KCkgeworICAgICAgICBTZXQ8RW51bUZvbz4gc2V0ID0gRW51bVNldC5ub25lT2YoRW51bUZvby5jbGFzcyk7CisgICAgICAgIEVudW1bXSBlbGVtZW50cyA9IEVudW1Gb28uY2xhc3MuZ2V0RW51bUNvbnN0YW50cygpOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHNldC5hZGQoKEVudW1Gb28pIGVsZW1lbnRzW2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgc2V0LmVxdWFscyhudWxsKSk7CisgICAgICAgIGFzc2VydEZhbHNlKAorICAgICAgICAgICAgICAgICJTaG91bGQgcmV0dXJuIGZhbHNlIiwgc2V0LmVxdWFscyhuZXcgT2JqZWN0KCkpKTsKKworICAgICAgICBTZXQ8RW51bUZvbz4gYW5vdGhlclNldCA9IEVudW1TZXQubm9uZU9mKEVudW1Gb28uY2xhc3MpOworICAgICAgICBlbGVtZW50cyA9IEVudW1Gb28uY2xhc3MuZ2V0RW51bUNvbnN0YW50cygpOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFub3RoZXJTZXQuYWRkKChFbnVtRm9vKSBlbGVtZW50c1tpXSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiB0cnVlIiwgc2V0LmVxdWFscyhhbm90aGVyU2V0KSk7CisKKyAgICAgICAgYW5vdGhlclNldC5yZW1vdmUoRW51bUZvby5hKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgICAgICAgIlNob3VsZCByZXR1cm4gZmFsc2UiLCBzZXQuZXF1YWxzKGFub3RoZXJTZXQpKTsKKworICAgICAgICBTZXQ8RW51bVdpdGhJbm5lckNsYXNzPiBzZXRXaXRoSW5uZXJDbGFzcyA9IEVudW1TZXQKKyAgICAgICAgICAgICAgICAubm9uZU9mKEVudW1XaXRoSW5uZXJDbGFzcy5jbGFzcyk7CisgICAgICAgIGVsZW1lbnRzID0gRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzLmdldEVudW1Db25zdGFudHMoKTsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBzZXRXaXRoSW5uZXJDbGFzcy5hZGQoKEVudW1XaXRoSW5uZXJDbGFzcykgZWxlbWVudHNbaV0pOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgICAgICAgIlNob3VsZCByZXR1cm4gZmFsc2UiLCBzZXQuZXF1YWxzKHNldFdpdGhJbm5lckNsYXNzKSk7CisKKyAgICAgICAgc2V0V2l0aElubmVyQ2xhc3MuY2xlYXIoKTsKKyAgICAgICAgc2V0LmNsZWFyKCk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBiZSBlcXVhbCIsIHNldC5lcXVhbHMoc2V0V2l0aElubmVyQ2xhc3MpKTsKKworICAgICAgICAvLyB0ZXN0IGVudW0gdHlwZSB3aXRoIG1vcmUgdGhhbiA2NCBlbGVtZW50cworICAgICAgICBTZXQ8SHVnZUVudW0+IGh1Z2VTZXQgPSBFbnVtU2V0Lm5vbmVPZihIdWdlRW51bS5jbGFzcyk7CisgICAgICAgIGFzc2VydFRydWUoaHVnZVNldC5lcXVhbHMoc2V0KSk7CisKKyAgICAgICAgaHVnZVNldCA9IEVudW1TZXQuYWxsT2YoSHVnZUVudW0uY2xhc3MpOworICAgICAgICBhc3NlcnRGYWxzZShodWdlU2V0LmVxdWFscyhudWxsKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGh1Z2VTZXQuZXF1YWxzKG5ldyBPYmplY3QoKSkpOworCisgICAgICAgIFNldDxIdWdlRW51bT4gYW5vdGhlckh1Z2VTZXQgPSBFbnVtU2V0LmFsbE9mKEh1Z2VFbnVtLmNsYXNzKTsKKyAgICAgICAgYW5vdGhlckh1Z2VTZXQucmVtb3ZlKEh1Z2VFbnVtLmEpOworICAgICAgICBhc3NlcnRGYWxzZShodWdlU2V0LmVxdWFscyhhbm90aGVySHVnZVNldCkpOworCisgICAgICAgIFNldDxIdWdlRW51bVdpdGhJbm5lckNsYXNzPiBodWdlU2V0V2l0aElubmVyQ2xhc3MgPSBFbnVtU2V0CisgICAgICAgICAgICAgICAgLmFsbE9mKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuY2xhc3MpOworICAgICAgICBhc3NlcnRGYWxzZShodWdlU2V0LmVxdWFscyhodWdlU2V0V2l0aElubmVyQ2xhc3MpKTsKKyAgICAgICAgaHVnZVNldFdpdGhJbm5lckNsYXNzLmNsZWFyKCk7CisgICAgICAgIGh1Z2VTZXQuY2xlYXIoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShodWdlU2V0LmVxdWFscyhodWdlU2V0V2l0aElubmVyQ2xhc3MpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRW51bVNldCNjbGVhcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jbGVhcigpIHsKKyAgICAgICAgU2V0PEVudW1Gb28+IHNldCA9IEVudW1TZXQubm9uZU9mKEVudW1Gb28uY2xhc3MpOworICAgICAgICBzZXQuYWRkKEVudW1Gb28uYSk7CisgICAgICAgIHNldC5hZGQoRW51bUZvby5iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIHNob3VsZCBiZSAyIiwgMiwgc2V0LnNpemUoKSk7CisKKyAgICAgICAgc2V0LmNsZWFyKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIHNob3VsZCBiZSAwIiwgMCwgc2V0LnNpemUoKSk7CisKKyAgICAgICAgLy8gdGVzdCBlbnVtIHR5cGUgd2l0aCBtb3JlIHRoYW4gNjQgZWxlbWVudHMKKyAgICAgICAgU2V0PEh1Z2VFbnVtPiBodWdlU2V0ID0gRW51bVNldC5hbGxPZihIdWdlRW51bS5jbGFzcyk7CisgICAgICAgIGFzc2VydEVxdWFscyg2NSwgaHVnZVNldC5zaXplKCkpOworCisgICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gaHVnZVNldC5jb250YWlucyhIdWdlRW51bS5hYSk7CisgICAgICAgIGFzc2VydFRydWUocmVzdWx0KTsKKworICAgICAgICBodWdlU2V0LmNsZWFyKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBodWdlU2V0LnNpemUoKSk7CisgICAgICAgIHJlc3VsdCA9IGh1Z2VTZXQuY29udGFpbnMoSHVnZUVudW0uYWEpOworICAgICAgICBhc3NlcnRGYWxzZShyZXN1bHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtU2V0I3NpemUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2l6ZSgpIHsKKyAgICAgICAgU2V0PEVudW1Gb28+IHNldCA9IEVudW1TZXQubm9uZU9mKEVudW1Gb28uY2xhc3MpOworICAgICAgICBzZXQuYWRkKEVudW1Gb28uYSk7CisgICAgICAgIHNldC5hZGQoRW51bUZvby5iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIHNob3VsZCBiZSAyIiwgMiwgc2V0LnNpemUoKSk7CisKKyAgICAgICAgLy8gdGVzdCBlbnVtIHR5cGUgd2l0aCBtb3JlIHRoYW4gNjQgZWxlbWVudHMKKyAgICAgICAgU2V0PEh1Z2VFbnVtPiBodWdlU2V0ID0gRW51bVNldC5ub25lT2YoSHVnZUVudW0uY2xhc3MpOworICAgICAgICBodWdlU2V0LmFkZChIdWdlRW51bS5hKTsKKyAgICAgICAgaHVnZVNldC5hZGQoSHVnZUVudW0uYmIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNpemUgc2hvdWxkIGJlIDIiLCAyLCBodWdlU2V0LnNpemUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkVudW1TZXQjY29tcGxlbWVudE9mKGphdmEudXRpbC5FbnVtU2V0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29tcGxlbWVudE9mX0xFbnVtU2V0KCkgeworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0LmNvbXBsZW1lbnRPZigoRW51bVNldDxFbnVtRm9vPikgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgRW51bVNldDxFbnVtV2l0aElubmVyQ2xhc3M+IHNldCA9IEVudW1TZXQKKyAgICAgICAgICAgICAgICAubm9uZU9mKEVudW1XaXRoSW5uZXJDbGFzcy5jbGFzcyk7CisgICAgICAgIHNldC5hZGQoRW51bVdpdGhJbm5lckNsYXNzLmQpOworICAgICAgICBzZXQuYWRkKEVudW1XaXRoSW5uZXJDbGFzcy5lKTsKKyAgICAgICAgc2V0LmFkZChFbnVtV2l0aElubmVyQ2xhc3MuZik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIHNob3VsZCBiZSAzOiIsIDMsIHNldC5zaXplKCkpOworCisgICAgICAgIEVudW1TZXQ8RW51bVdpdGhJbm5lckNsYXNzPiBjb21wbGVtZW50T2ZFID0gRW51bVNldC5jb21wbGVtZW50T2Yoc2V0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzZXQuY29udGFpbnMoRW51bVdpdGhJbm5lckNsYXNzLmQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICJjb21wbGVtZW50T2ZFIHNob3VsZCBoYXZlIHNpemUgMyIsIDMsIGNvbXBsZW1lbnRPZkUuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiY29tcGxlbWVudE9mRSBzaG91bGQgY29udGFpbiBFbnVtV2l0aFN1YmNsYXNzLmE6IiwKKyAgICAgICAgICAgICAgICBjb21wbGVtZW50T2ZFLmNvbnRhaW5zKEVudW1XaXRoSW5uZXJDbGFzcy5hKSk7CisgICAgICAgIGFzc2VydFRydWUoImNvbXBsZW1lbnRPZkUgc2hvdWxkIGNvbnRhaW4gRW51bVdpdGhTdWJjbGFzcy5iOiIsCisgICAgICAgICAgICAgICAgY29tcGxlbWVudE9mRS5jb250YWlucyhFbnVtV2l0aElubmVyQ2xhc3MuYikpOworICAgICAgICBhc3NlcnRUcnVlKCJjb21wbGVtZW50T2ZFIHNob3VsZCBjb250YWluIEVudW1XaXRoU3ViY2xhc3MuYzoiLAorICAgICAgICAgICAgICAgIGNvbXBsZW1lbnRPZkUuY29udGFpbnMoRW51bVdpdGhJbm5lckNsYXNzLmMpKTsKKworICAgICAgICAvLyB0ZXN0IGVudW0gdHlwZSB3aXRoIG1vcmUgdGhhbiA2NCBlbGVtZW50cworICAgICAgICBFbnVtU2V0PEh1Z2VFbnVtPiBodWdlU2V0ID0gRW51bVNldC5ub25lT2YoSHVnZUVudW0uY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaHVnZVNldC5zaXplKCkpOworICAgICAgICBTZXQ8SHVnZUVudW0+IGNvbXBsZW1lbnRIdWdlU2V0ID0gRW51bVNldC5jb21wbGVtZW50T2YoaHVnZVNldCk7CisgICAgICAgIGFzc2VydEVxdWFscyg2NSwgY29tcGxlbWVudEh1Z2VTZXQuc2l6ZSgpKTsKKworICAgICAgICBodWdlU2V0LmFkZChIdWdlRW51bS5BKTsKKyAgICAgICAgaHVnZVNldC5hZGQoSHVnZUVudW0ubW0pOworICAgICAgICBjb21wbGVtZW50SHVnZVNldCA9IEVudW1TZXQuY29tcGxlbWVudE9mKGh1Z2VTZXQpOworICAgICAgICBhc3NlcnRFcXVhbHMoNjMsIGNvbXBsZW1lbnRIdWdlU2V0LnNpemUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVudW1TZXQuY29tcGxlbWVudE9mKChFbnVtU2V0PEh1Z2VFbnVtPikgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkVudW1TZXQjY29udGFpbnMoT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY29udGFpbnNfTE9iamVjdCgpIHsKKyAgICAgICAgU2V0PEVudW1Gb28+IHNldCA9IEVudW1TZXQubm9uZU9mKEVudW1Gb28uY2xhc3MpOworICAgICAgICBFbnVtW10gZWxlbWVudHMgPSBFbnVtRm9vLmNsYXNzLmdldEVudW1Db25zdGFudHMoKTsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBzZXQuYWRkKChFbnVtRm9vKWVsZW1lbnRzW2ldKTsKKyAgICAgICAgfQorICAgICAgICBib29sZWFuIHJlc3VsdCA9IHNldC5jb250YWlucyhudWxsKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCBub3QgY29udGFpbiBudWxsOiIsIHJlc3VsdCk7CisKKyAgICAgICAgcmVzdWx0ID0gc2V0LmNvbnRhaW5zKEVudW1Gb28uYSk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBjb250YWluIEVudW1Gb28uYSIsIHJlc3VsdCk7CisgICAgICAgIHJlc3VsdCA9IHNldC5jb250YWlucyhFbnVtRm9vLmxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGNvbnRhaW4gRW51bUZvby5sbCIsIHJlc3VsdCk7CisKKyAgICAgICAgcmVzdWx0ID0gc2V0LmNvbnRhaW5zKEVudW1Gb28uYik7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBjb250YWluIEVudW1Gb28uYiIsIHJlc3VsdCk7CisKKyAgICAgICAgcmVzdWx0ID0gc2V0LmNvbnRhaW5zKG5ldyBPYmplY3QoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgbm90IGNvbnRhaW4gT2JqZWN0IGluc3RhbmNlIiwgcmVzdWx0KTsKKworICAgICAgICByZXN1bHQgPSBzZXQuY29udGFpbnMoRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIG5vdCBjb250YWluIEVudW1XaXRoU3ViY2xhc3MuYSIsIHJlc3VsdCk7CisKKyAgICAgICAgc2V0ID0gRW51bVNldC5ub25lT2YoRW51bUZvby5jbGFzcyk7CisgICAgICAgIHNldC5hZGQoRW51bUZvby5hYSk7CisgICAgICAgIHNldC5hZGQoRW51bUZvby5iYik7CisgICAgICAgIHNldC5hZGQoRW51bUZvby5jYyk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIG9mIHNldCBzaG91bGQgYmUgMyIsIDMsIHNldC5zaXplKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJzZXQgc2hvdWxkIGNvbnRhaW4gRW51bUZvby5hYSIsIHNldC5jb250YWlucyhFbnVtRm9vLmFhKSk7CisKKyAgICAgICAgU2V0PEVudW1XaXRoSW5uZXJDbGFzcz4gc2V0V2l0aFN1YmNsYXNzID0gRW51bVNldAorICAgICAgICAgICAgICAgIC5ub25lT2YoRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgc2V0V2l0aFN1YmNsYXNzLmFkZChFbnVtV2l0aElubmVyQ2xhc3MuYSk7CisgICAgICAgIHNldFdpdGhTdWJjbGFzcy5hZGQoRW51bVdpdGhJbm5lckNsYXNzLmIpOworICAgICAgICBzZXRXaXRoU3ViY2xhc3MuYWRkKEVudW1XaXRoSW5uZXJDbGFzcy5jKTsKKyAgICAgICAgc2V0V2l0aFN1YmNsYXNzLmFkZChFbnVtV2l0aElubmVyQ2xhc3MuZCk7CisgICAgICAgIHNldFdpdGhTdWJjbGFzcy5hZGQoRW51bVdpdGhJbm5lckNsYXNzLmUpOworICAgICAgICBzZXRXaXRoU3ViY2xhc3MuYWRkKEVudW1XaXRoSW5uZXJDbGFzcy5mKTsKKyAgICAgICAgcmVzdWx0ID0gc2V0V2l0aFN1YmNsYXNzLmNvbnRhaW5zKEVudW1XaXRoSW5uZXJDbGFzcy5mKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGNvbnRhaW4gRW51bVdpdGhTdWJjbGFzcy5mIiwgcmVzdWx0KTsKKworICAgICAgICAvLyB0ZXN0IGVudW0gdHlwZSB3aXRoIG1vcmUgdGhhbiA2NCBlbGVtZW50cworICAgICAgICBTZXQ8SHVnZUVudW0+IGh1Z2VTZXQgPSBFbnVtU2V0LmFsbE9mKEh1Z2VFbnVtLmNsYXNzKTsKKyAgICAgICAgaHVnZVNldC5hZGQoSHVnZUVudW0uYSk7CisgICAgICAgIHJlc3VsdCA9IGh1Z2VTZXQuY29udGFpbnMoSHVnZUVudW0uYSk7CisgICAgICAgIGFzc2VydFRydWUocmVzdWx0KTsKKworICAgICAgICByZXN1bHQgPSBodWdlU2V0LmNvbnRhaW5zKEh1Z2VFbnVtLmIpOworICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCk7CisKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5jb250YWlucyhudWxsKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKworICAgICAgICByZXN1bHQgPSBodWdlU2V0LmNvbnRhaW5zKEh1Z2VFbnVtLmEpOworICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCk7CisKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5jb250YWlucyhIdWdlRW51bS5sbCk7CisgICAgICAgIGFzc2VydFRydWUocmVzdWx0KTsKKworICAgICAgICByZXN1bHQgPSBodWdlU2V0LmNvbnRhaW5zKG5ldyBPYmplY3QoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHJlc3VsdCk7CisKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5jb250YWlucyhFbnVtLmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtU2V0I2NvbnRhaW5zQWxsKENvbGxlY3Rpb24pCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoIHsgInVuY2hlY2tlZCIsICJib3hpbmciIH0pCisgICAgcHVibGljIHZvaWQgdGVzdF9jb250YWluc0FsbF9MQ29sbGVjdGlvbigpIHsKKyAgICAgICAgRW51bVNldDxFbnVtRm9vPiBzZXQgPSBFbnVtU2V0Lm5vbmVPZihFbnVtRm9vLmNsYXNzKTsKKyAgICAgICAgRW51bVtdIGVsZW1lbnRzID0gRW51bUZvby5jbGFzcy5nZXRFbnVtQ29uc3RhbnRzKCk7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc2V0LmFkZCgoRW51bUZvbyllbGVtZW50c1tpXSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldC5jb250YWluc0FsbChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgRW51bVNldDxFbXB0eUVudW0+IGVtcHR5U2V0ID0gRW51bVNldC5ub25lT2YoRW1wdHlFbnVtLmNsYXNzKTsKKyAgICAgICAgZWxlbWVudHMgPSBFbXB0eUVudW0uY2xhc3MuZ2V0RW51bUNvbnN0YW50cygpOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGVtcHR5U2V0LmFkZCgoRW1wdHlFbnVtKWVsZW1lbnRzW2ldKTsKKyAgICAgICAgfQorICAgICAgICBib29sZWFuIHJlc3VsdCA9IHNldC5jb250YWluc0FsbChlbXB0eVNldCk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCByZXR1cm4gdHJ1ZSIsIHJlc3VsdCk7CisKKyAgICAgICAgQ29sbGVjdGlvbiByYXdDb2xsZWN0aW9uID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICByZXN1bHQgPSBzZXQuY29udGFpbnNBbGwocmF3Q29sbGVjdGlvbik7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBjb250YWluIGVtcHR5IGNvbGxlY3Rpb246IiwgcmVzdWx0KTsKKworICAgICAgICByYXdDb2xsZWN0aW9uLmFkZCgxKTsKKyAgICAgICAgcmVzdWx0ID0gc2V0LmNvbnRhaW5zQWxsKHJhd0NvbGxlY3Rpb24pOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIHJldHVybiBmYWxzZSIsIHJlc3VsdCk7CisKKyAgICAgICAgcmF3Q29sbGVjdGlvbi5hZGQoRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICByZXN1bHQgPSBzZXQuY29udGFpbnNBbGwocmF3Q29sbGVjdGlvbik7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICBFbnVtU2V0IHJhd1NldCA9IEVudW1TZXQubm9uZU9mKEVudW1Gb28uY2xhc3MpOworICAgICAgICByZXN1bHQgPSBzZXQuY29udGFpbnNBbGwocmF3U2V0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGNvbnRhaW4gZW1wdHkgc2V0IiwgcmVzdWx0KTsKKworICAgICAgICBlbXB0eVNldCA9IEVudW1TZXQubm9uZU9mKEVtcHR5RW51bS5jbGFzcyk7CisgICAgICAgIHJlc3VsdCA9IHNldC5jb250YWluc0FsbChlbXB0eVNldCk7CisgICAgICAgIGFzc2VydFRydWUoIk5vIGNsYXNzIGNhc3Qgc2hvdWxkIGJlIHBlcmZvcm1lZCBvbiBlbXB0eSBzZXQiLCByZXN1bHQpOworCisgICAgICAgIENvbGxlY3Rpb248RW51bUZvbz4gY29sbGVjdGlvbiA9IG5ldyBBcnJheUxpc3Q8RW51bUZvbz4oKTsKKyAgICAgICAgY29sbGVjdGlvbi5hZGQoRW51bUZvby5hKTsKKyAgICAgICAgcmVzdWx0ID0gc2V0LmNvbnRhaW5zQWxsKGNvbGxlY3Rpb24pOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgY29udGFpbiBhbGwgZWxlbWVudHMgaW4gY29sbGVjdGlvbiIsIHJlc3VsdCk7CisKKyAgICAgICAgRW51bVNldDxFbnVtRm9vPiBmb29TZXQgPSBFbnVtU2V0Lm5vbmVPZihFbnVtRm9vLmNsYXNzKTsKKyAgICAgICAgZm9vU2V0LmFkZChFbnVtRm9vLmEpOworICAgICAgICByZXN1bHQgPSBzZXQuY29udGFpbnNBbGwoZm9vU2V0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiB0cnVlIiwgcmVzdWx0KTsKKworICAgICAgICBzZXQuY2xlYXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldC5jb250YWluc0FsbChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgQ29sbGVjdGlvbjxFbnVtV2l0aElubmVyQ2xhc3M+IGNvbGxlY3Rpb25XaXRoU3ViY2xhc3MgPSBuZXcgQXJyYXlMaXN0PEVudW1XaXRoSW5uZXJDbGFzcz4oKTsKKyAgICAgICAgY29sbGVjdGlvbldpdGhTdWJjbGFzcy5hZGQoRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICByZXN1bHQgPSBzZXQuY29udGFpbnNBbGwoY29sbGVjdGlvbldpdGhTdWJjbGFzcyk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICBFbnVtU2V0PEVudW1XaXRoSW5uZXJDbGFzcz4gc2V0V2l0aFN1YmNsYXNzID0gRW51bVNldAorICAgICAgICAgICAgICAgIC5ub25lT2YoRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgc2V0V2l0aFN1YmNsYXNzLmFkZChFbnVtV2l0aElubmVyQ2xhc3MuYSk7CisgICAgICAgIHJlc3VsdCA9IHNldC5jb250YWluc0FsbChzZXRXaXRoU3ViY2xhc3MpOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIHJldHVybiBmYWxzZSIsIHJlc3VsdCk7CisKKyAgICAgICAgLy8gdGVzdCBlbnVtIHR5cGUgd2l0aCBtb3JlIHRoYW4gNjQgZWxlbWVudHMKKyAgICAgICAgU2V0PEh1Z2VFbnVtPiBodWdlU2V0ID0gRW51bVNldC5ub25lT2YoSHVnZUVudW0uY2xhc3MpOworICAgICAgICBodWdlU2V0LmFkZChIdWdlRW51bS5hKTsKKyAgICAgICAgaHVnZVNldC5hZGQoSHVnZUVudW0uYik7CisgICAgICAgIGh1Z2VTZXQuYWRkKEh1Z2VFbnVtLmFhKTsKKyAgICAgICAgaHVnZVNldC5hZGQoSHVnZUVudW0uYmIpOworICAgICAgICBodWdlU2V0LmFkZChIdWdlRW51bS5jYyk7CisgICAgICAgIGh1Z2VTZXQuYWRkKEh1Z2VFbnVtLmRkKTsKKworICAgICAgICBTZXQ8SHVnZUVudW0+IGFub3RoZXJIdWdlU2V0ID0gRW51bVNldC5ub25lT2YoSHVnZUVudW0uY2xhc3MpOworICAgICAgICBodWdlU2V0LmFkZChIdWdlRW51bS5iKTsKKyAgICAgICAgaHVnZVNldC5hZGQoSHVnZUVudW0uY2MpOworICAgICAgICByZXN1bHQgPSBodWdlU2V0LmNvbnRhaW5zQWxsKGFub3RoZXJIdWdlU2V0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBodWdlU2V0LmNvbnRhaW5zQWxsKG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIFNldDxIdWdlRW51bVdpdGhJbm5lckNsYXNzPiBodWdlU2V0V2l0aElubmVyQ2xhc3MgPSBFbnVtU2V0CisgICAgICAgICAgICAgICAgLm5vbmVPZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgaHVnZVNldFdpdGhJbm5lckNsYXNzLmFkZChIdWdlRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICBodWdlU2V0V2l0aElubmVyQ2xhc3MuYWRkKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYik7CisgICAgICAgIHJlc3VsdCA9IGh1Z2VTZXRXaXRoSW5uZXJDbGFzcy5jb250YWluc0FsbChodWdlU2V0V2l0aElubmVyQ2xhc3MpOworICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCk7CisgICAgICAgIHJlc3VsdCA9IGh1Z2VTZXQuY29udGFpbnNBbGwoaHVnZVNldFdpdGhJbm5lckNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKworICAgICAgICByYXdDb2xsZWN0aW9uID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICByZXN1bHQgPSBodWdlU2V0LmNvbnRhaW5zQWxsKHJhd0NvbGxlY3Rpb24pOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgY29udGFpbiBlbXB0eSBjb2xsZWN0aW9uOiIsIHJlc3VsdCk7CisKKyAgICAgICAgcmF3Q29sbGVjdGlvbi5hZGQoMSk7CisgICAgICAgIHJlc3VsdCA9IGh1Z2VTZXQuY29udGFpbnNBbGwocmF3Q29sbGVjdGlvbik7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICByYXdDb2xsZWN0aW9uLmFkZChFbnVtV2l0aElubmVyQ2xhc3MuYSk7CisgICAgICAgIHJlc3VsdCA9IHNldC5jb250YWluc0FsbChyYXdDb2xsZWN0aW9uKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCByZXR1cm4gZmFsc2UiLCByZXN1bHQpOworCisgICAgICAgIHJhd1NldCA9IEVudW1TZXQubm9uZU9mKEh1Z2VFbnVtLmNsYXNzKTsKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5jb250YWluc0FsbChyYXdTZXQpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgY29udGFpbiBlbXB0eSBzZXQiLCByZXN1bHQpOworCisgICAgICAgIEVudW1TZXQ8SHVnZUVudW1XaXRoSW5uZXJDbGFzcz4gZW1wdHlIdWdlU2V0CisgICAgICAgICAgICA9IEVudW1TZXQubm9uZU9mKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuY2xhc3MpOworICAgICAgICByZXN1bHQgPSBodWdlU2V0LmNvbnRhaW5zQWxsKGVtcHR5SHVnZVNldCk7CisgICAgICAgIGFzc2VydFRydWUoIk5vIGNsYXNzIGNhc3Qgc2hvdWxkIGJlIHBlcmZvcm1lZCBvbiBlbXB0eSBzZXQiLCByZXN1bHQpOworCisgICAgICAgIENvbGxlY3Rpb248SHVnZUVudW0+IGh1Z2VDb2xsZWN0aW9uID0gbmV3IEFycmF5TGlzdDxIdWdlRW51bT4oKTsKKyAgICAgICAgaHVnZUNvbGxlY3Rpb24uYWRkKEh1Z2VFbnVtLmEpOworICAgICAgICByZXN1bHQgPSBodWdlU2V0LmNvbnRhaW5zQWxsKGh1Z2VDb2xsZWN0aW9uKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGNvbnRhaW4gYWxsIGVsZW1lbnRzIGluIGNvbGxlY3Rpb24iLCByZXN1bHQpOworCisgICAgICAgIGh1Z2VTZXQuY2xlYXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGh1Z2VTZXQuY29udGFpbnNBbGwobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIENvbGxlY3Rpb248SHVnZUVudW1XaXRoSW5uZXJDbGFzcz4gaHVnZUNvbGxlY3Rpb25XaXRoU3ViY2xhc3MgPSBuZXcgQXJyYXlMaXN0PEh1Z2VFbnVtV2l0aElubmVyQ2xhc3M+KCk7CisgICAgICAgIGh1Z2VDb2xsZWN0aW9uV2l0aFN1YmNsYXNzLmFkZChIdWdlRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICByZXN1bHQgPSBodWdlU2V0LmNvbnRhaW5zQWxsKGh1Z2VDb2xsZWN0aW9uV2l0aFN1YmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCByZXR1cm4gZmFsc2UiLCByZXN1bHQpOworCisgICAgICAgIEVudW1TZXQ8SHVnZUVudW1XaXRoSW5uZXJDbGFzcz4gaHVnZVNldFdpdGhTdWJjbGFzcyA9IEVudW1TZXQKKyAgICAgICAgICAgICAgICAubm9uZU9mKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuY2xhc3MpOworICAgICAgICBodWdlU2V0V2l0aFN1YmNsYXNzLmFkZChIdWdlRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICByZXN1bHQgPSBodWdlU2V0LmNvbnRhaW5zQWxsKGh1Z2VTZXRXaXRoU3ViY2xhc3MpOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIHJldHVybiBmYWxzZSIsIHJlc3VsdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkVudW1TZXQjY29weU9mKGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29weU9mX0xDb2xsZWN0aW9uKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgRW51bVNldC5jb3B5T2YoKENvbGxlY3Rpb24pIG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIENvbGxlY3Rpb24gY29sbGVjdGlvbiA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVudW1TZXQuY29weU9mKGNvbGxlY3Rpb24pOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGNvbGxlY3Rpb24uYWRkKG5ldyBPYmplY3QoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0LmNvcHlPZihjb2xsZWN0aW9uKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBDbGFzc0Nhc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBDb2xsZWN0aW9uPEVudW1Gb28+IGVudW1Db2xsZWN0aW9uID0gbmV3IEFycmF5TGlzdDxFbnVtRm9vPigpOworICAgICAgICBlbnVtQ29sbGVjdGlvbi5hZGQoRW51bUZvby5iKTsKKworICAgICAgICBFbnVtU2V0PEVudW1Gb28+IGNvcHlPZkVudW1Db2xsZWN0aW9uID0gRW51bVNldC5jb3B5T2YoZW51bUNvbGxlY3Rpb24pOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNpemUgb2YgY29weU9mRW51bUNvbGxlY3Rpb24gc2hvdWxkIGJlIDE6IiwKKyAgICAgICAgICAgICAgICAxLCBjb3B5T2ZFbnVtQ29sbGVjdGlvbi5zaXplKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJjb3B5T2ZFbnVtQ29sbGVjdGlvbiBzaG91bGQgY29udGFpbiBFbnVtRm9vLmI6IiwKKyAgICAgICAgICAgICAgICBjb3B5T2ZFbnVtQ29sbGVjdGlvbi5jb250YWlucyhFbnVtRm9vLmIpKTsKKworICAgICAgICBlbnVtQ29sbGVjdGlvbi5hZGQobnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBvZiBlbnVtQ29sbGVjdGlvbiBzaG91bGQgYmUgMjoiLAorICAgICAgICAgICAgICAgIDIsIGVudW1Db2xsZWN0aW9uLnNpemUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvcHlPZkVudW1Db2xsZWN0aW9uID0gRW51bVNldC5jb3B5T2YoZW51bUNvbGxlY3Rpb24pOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIENvbGxlY3Rpb24gcmF3RW51bUNvbGxlY3Rpb24gPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIHJhd0VudW1Db2xsZWN0aW9uLmFkZChFbnVtRm9vLmEpOworICAgICAgICByYXdFbnVtQ29sbGVjdGlvbi5hZGQoRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgRW51bVNldC5jb3B5T2YocmF3RW51bUNvbGxlY3Rpb24pOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IENsYXNzQ2FzdEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gdGVzdCBlbnVtIHR5cGUgd2l0aCBtb3JlIHRoYW4gNjQgZWxlbWVudHMKKyAgICAgICAgQ29sbGVjdGlvbjxIdWdlRW51bT4gaHVnZUVudW1Db2xsZWN0aW9uID0gbmV3IEFycmF5TGlzdDxIdWdlRW51bT4oKTsKKyAgICAgICAgaHVnZUVudW1Db2xsZWN0aW9uLmFkZChIdWdlRW51bS5iKTsKKworICAgICAgICBFbnVtU2V0PEh1Z2VFbnVtPiBjb3B5T2ZIdWdlRW51bUNvbGxlY3Rpb24gPSBFbnVtU2V0LmNvcHlPZihodWdlRW51bUNvbGxlY3Rpb24pOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY29weU9mSHVnZUVudW1Db2xsZWN0aW9uLnNpemUoKSk7CisgICAgICAgIGFzc2VydFRydWUoY29weU9mSHVnZUVudW1Db2xsZWN0aW9uLmNvbnRhaW5zKEh1Z2VFbnVtLmIpKTsKKworICAgICAgICBodWdlRW51bUNvbGxlY3Rpb24uYWRkKG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgaHVnZUVudW1Db2xsZWN0aW9uLnNpemUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvcHlPZkh1Z2VFbnVtQ29sbGVjdGlvbiA9IEVudW1TZXQuY29weU9mKGh1Z2VFbnVtQ29sbGVjdGlvbik7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcmF3RW51bUNvbGxlY3Rpb24gPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIHJhd0VudW1Db2xsZWN0aW9uLmFkZChIdWdlRW51bS5hKTsKKyAgICAgICAgcmF3RW51bUNvbGxlY3Rpb24uYWRkKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0LmNvcHlPZihyYXdFbnVtQ29sbGVjdGlvbik7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgQ2xhc3NDYXN0RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2goQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRW51bVNldCNjb3B5T2YoamF2YS51dGlsLkVudW1TZXQpCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9Db3B5T2ZfTEVudW1TZXQoKSB7CisgICAgICAgIEVudW1TZXQ8RW51bVdpdGhJbm5lckNsYXNzPiBlbnVtU2V0ID0gRW51bVNldAorICAgICAgICAgICAgICAgIC5ub25lT2YoRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgZW51bVNldC5hZGQoRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICBlbnVtU2V0LmFkZChFbnVtV2l0aElubmVyQ2xhc3MuZik7CisgICAgICAgIEVudW1TZXQ8RW51bVdpdGhJbm5lckNsYXNzPiBjb3B5T2ZFID0gRW51bVNldC5jb3B5T2YoZW51bVNldCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBvZiBlbnVtU2V0IGFuZCBjb3B5T2ZFIHNob3VsZCBiZSBlcXVhbCIsCisgICAgICAgICAgICAgICAgZW51bVNldC5zaXplKCksIGNvcHlPZkUuc2l6ZSgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJFbnVtV2l0aFN1YmNsYXNzLmEgc2hvdWxkIGJlIGNvbnRhaW5lZCBpbiBjb3B5T2ZFIiwKKyAgICAgICAgICAgICAgICBjb3B5T2ZFLmNvbnRhaW5zKEVudW1XaXRoSW5uZXJDbGFzcy5hKSk7CisgICAgICAgIGFzc2VydFRydWUoIkVudW1XaXRoU3ViY2xhc3MuZiBzaG91bGQgYmUgY29udGFpbmVkIGluIGNvcHlPZkUiLAorICAgICAgICAgICAgICAgIGNvcHlPZkUuY29udGFpbnMoRW51bVdpdGhJbm5lckNsYXNzLmYpKTsKKworICAgICAgICBPYmplY3RbXSBlbnVtVmFsdWUgPSBjb3B5T2ZFLnRvQXJyYXkoKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiZW51bVZhbHVlWzBdIHNob3VsZCBiZSBpZGVudGljYWwgd2l0aCBFbnVtV2l0aFN1YmNsYXNzLmEiLAorICAgICAgICAgICAgICAgIGVudW1WYWx1ZVswXSwgRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICBhc3NlcnRTYW1lKCJlbnVtVmFsdWVbMV0gc2hvdWxkIGJlIGlkZW50aWNhbCB3aXRoIEVudW1XaXRoU3ViY2xhc3MuZiIsCisgICAgICAgICAgICAgICAgZW51bVZhbHVlWzFdLCBFbnVtV2l0aElubmVyQ2xhc3MuZik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVudW1TZXQuY29weU9mKChFbnVtU2V0KSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyB0ZXN0IGVudW0gdHlwZSB3aXRoIG1vcmUgdGhhbiA2NCBlbGVtZW50cworICAgICAgICBFbnVtU2V0PEh1Z2VFbnVtV2l0aElubmVyQ2xhc3M+IGh1Z2VFbnVtU2V0ID0gRW51bVNldAorICAgICAgICAgICAgLm5vbmVPZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgaHVnZUVudW1TZXQuYWRkKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYSk7CisgICAgICAgIGh1Z2VFbnVtU2V0LmFkZChIdWdlRW51bVdpdGhJbm5lckNsYXNzLmYpOworICAgICAgICBFbnVtU2V0PEh1Z2VFbnVtV2l0aElubmVyQ2xhc3M+IGNvcHlPZkh1Z2VFbnVtID0gRW51bVNldC5jb3B5T2YoaHVnZUVudW1TZXQpOworICAgICAgICBhc3NlcnRFcXVhbHMoZW51bVNldC5zaXplKCksIGNvcHlPZkUuc2l6ZSgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKGNvcHlPZkh1Z2VFbnVtLmNvbnRhaW5zKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYSkpOworICAgICAgICBhc3NlcnRUcnVlKGNvcHlPZkh1Z2VFbnVtLmNvbnRhaW5zKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuZikpOworCisgICAgICAgIE9iamVjdFtdIGh1Z2VFbnVtVmFsdWUgPSBjb3B5T2ZIdWdlRW51bS50b0FycmF5KCk7CisgICAgICAgIGFzc2VydFNhbWUoaHVnZUVudW1WYWx1ZVswXSwgSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5hKTsKKyAgICAgICAgYXNzZXJ0U2FtZShodWdlRW51bVZhbHVlWzFdLCBIdWdlRW51bVdpdGhJbm5lckNsYXNzLmYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtU2V0I3JlbW92ZUFsbChDb2xsZWN0aW9uKQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlQWxsX0xDb2xsZWN0aW9uKCkgeworICAgICAgICBTZXQ8RW51bUZvbz4gc2V0ID0gRW51bVNldC5ub25lT2YoRW51bUZvby5jbGFzcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXQucmVtb3ZlQWxsKG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBzZXQgPSBFbnVtU2V0LmFsbE9mKEVudW1Gb28uY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNpemUgb2Ygc2V0IHNob3VsZCBiZSA2NDoiLCA2NCwgc2V0LnNpemUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldC5yZW1vdmVBbGwobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIENvbGxlY3Rpb248RW51bUZvbz4gY29sbGVjdGlvbiA9IG5ldyBBcnJheUxpc3Q8RW51bUZvbz4oKTsKKyAgICAgICAgY29sbGVjdGlvbi5hZGQoRW51bUZvby5hKTsKKworICAgICAgICBib29sZWFuIHJlc3VsdCA9IHNldC5yZW1vdmVBbGwoY29sbGVjdGlvbik7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCByZXR1cm4gdHJ1ZSIsIHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBvZiBzZXQgc2hvdWxkIGJlIDYzIiwgNjMsIHNldC5zaXplKCkpOworCisgICAgICAgIGNvbGxlY3Rpb24gPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIHJlc3VsdCA9IHNldC5yZW1vdmVBbGwoY29sbGVjdGlvbik7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICBTZXQ8RW1wdHlFbnVtPiBlbXB0eVNldCA9IEVudW1TZXQubm9uZU9mKEVtcHR5RW51bS5jbGFzcyk7CisgICAgICAgIHJlc3VsdCA9IHNldC5yZW1vdmVBbGwoZW1wdHlTZXQpOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIHJldHVybiBmYWxzZSIsIHJlc3VsdCk7CisKKyAgICAgICAgRW51bVNldDxFbnVtRm9vPiBlbXB0eUZvb1NldCA9IEVudW1TZXQubm9uZU9mKEVudW1Gb28uY2xhc3MpOworICAgICAgICByZXN1bHQgPSBzZXQucmVtb3ZlQWxsKGVtcHR5Rm9vU2V0KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCByZXR1cm4gZmFsc2UiLCByZXN1bHQpOworCisgICAgICAgIGVtcHR5Rm9vU2V0LmFkZChFbnVtRm9vLmEpOworICAgICAgICByZXN1bHQgPSBzZXQucmVtb3ZlQWxsKGVtcHR5Rm9vU2V0KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCByZXR1cm4gZmFsc2UiLCByZXN1bHQpOworCisgICAgICAgIFNldDxFbnVtV2l0aElubmVyQ2xhc3M+IHNldFdpdGhTdWJjbGFzcyA9IEVudW1TZXQKKyAgICAgICAgICAgICAgICAubm9uZU9mKEVudW1XaXRoSW5uZXJDbGFzcy5jbGFzcyk7CisgICAgICAgIHJlc3VsdCA9IHNldC5yZW1vdmVBbGwoc2V0V2l0aFN1YmNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCByZXR1cm4gZmFsc2UiLCByZXN1bHQpOworCisgICAgICAgIHNldFdpdGhTdWJjbGFzcy5hZGQoRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICByZXN1bHQgPSBzZXQucmVtb3ZlQWxsKHNldFdpdGhTdWJjbGFzcyk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICBTZXQ8RW51bUZvbz4gYW5vdGhlclNldCA9IEVudW1TZXQubm9uZU9mKEVudW1Gb28uY2xhc3MpOworICAgICAgICBhbm90aGVyU2V0LmFkZChFbnVtRm9vLmEpOworCisgICAgICAgIHNldCA9IEVudW1TZXQuYWxsT2YoRW51bUZvby5jbGFzcyk7CisgICAgICAgIHJlc3VsdCA9IHNldC5yZW1vdmVBbGwoYW5vdGhlclNldCk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCByZXR1cm4gdHJ1ZSIsIHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBvZiBzZXQgc2hvdWxkIGJlIDYzOiIsIDYzLCBzZXQuc2l6ZSgpKTsKKworICAgICAgICBTZXQ8RW51bVdpdGhJbm5lckNsYXNzPiBzZXRXaXRoSW5uZXJDbGFzcyA9IEVudW1TZXQKKyAgICAgICAgICAgICAgICAubm9uZU9mKEVudW1XaXRoSW5uZXJDbGFzcy5jbGFzcyk7CisgICAgICAgIHNldFdpdGhJbm5lckNsYXNzLmFkZChFbnVtV2l0aElubmVyQ2xhc3MuYSk7CisgICAgICAgIHNldFdpdGhJbm5lckNsYXNzLmFkZChFbnVtV2l0aElubmVyQ2xhc3MuYik7CisKKyAgICAgICAgU2V0PEVudW1XaXRoSW5uZXJDbGFzcz4gYW5vdGhlclNldFdpdGhJbm5lckNsYXNzID0gRW51bVNldAorICAgICAgICAgICAgICAgIC5ub25lT2YoRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgYW5vdGhlclNldFdpdGhJbm5lckNsYXNzLmFkZChFbnVtV2l0aElubmVyQ2xhc3MuYyk7CisgICAgICAgIGFub3RoZXJTZXRXaXRoSW5uZXJDbGFzcy5hZGQoRW51bVdpdGhJbm5lckNsYXNzLmQpOworICAgICAgICByZXN1bHQgPSBhbm90aGVyU2V0V2l0aElubmVyQ2xhc3MucmVtb3ZlQWxsKHNldFdpdGhJbm5lckNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCByZXR1cm4gZmFsc2UiLCByZXN1bHQpOworCisgICAgICAgIGFub3RoZXJTZXRXaXRoSW5uZXJDbGFzcy5hZGQoRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICByZXN1bHQgPSBhbm90aGVyU2V0V2l0aElubmVyQ2xhc3MucmVtb3ZlQWxsKHNldFdpdGhJbm5lckNsYXNzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiB0cnVlIiwgcmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIG9mIGFub3RoZXJTZXRXaXRoSW5uZXJDbGFzcyBzaG91bGQgcmVtYWluIDIiLAorICAgICAgICAgICAgICAgIDIsIGFub3RoZXJTZXRXaXRoSW5uZXJDbGFzcy5zaXplKCkpOworCisgICAgICAgIGFub3RoZXJTZXRXaXRoSW5uZXJDbGFzcy5yZW1vdmUoRW51bVdpdGhJbm5lckNsYXNzLmMpOworICAgICAgICBhbm90aGVyU2V0V2l0aElubmVyQ2xhc3MucmVtb3ZlKEVudW1XaXRoSW5uZXJDbGFzcy5kKTsKKyAgICAgICAgcmVzdWx0ID0gYW5vdGhlclNldFdpdGhJbm5lckNsYXNzLnJlbW92ZShzZXRXaXRoSW5uZXJDbGFzcyk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICBTZXQgcmF3U2V0ID0gRW51bVNldC5hbGxPZihFbnVtV2l0aEFsbElubmVyQ2xhc3MuY2xhc3MpOworICAgICAgICByZXN1bHQgPSByYXdTZXQucmVtb3ZlQWxsKEVudW1TZXQuYWxsT2YoRW51bUZvby5jbGFzcykpOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIHJldHVybiBmYWxzZSIsIHJlc3VsdCk7CisKKyAgICAgICAgc2V0V2l0aElubmVyQ2xhc3MgPSBFbnVtU2V0LmFsbE9mKEVudW1XaXRoSW5uZXJDbGFzcy5jbGFzcyk7CisgICAgICAgIGFub3RoZXJTZXRXaXRoSW5uZXJDbGFzcyA9IEVudW1TZXQuYWxsT2YoRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgc2V0V2l0aElubmVyQ2xhc3MucmVtb3ZlKEVudW1XaXRoSW5uZXJDbGFzcy5hKTsKKyAgICAgICAgYW5vdGhlclNldFdpdGhJbm5lckNsYXNzLnJlbW92ZShFbnVtV2l0aElubmVyQ2xhc3MuZik7CisgICAgICAgIHJlc3VsdCA9IHNldFdpdGhJbm5lckNsYXNzLnJlbW92ZUFsbChhbm90aGVyU2V0V2l0aElubmVyQ2xhc3MpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIHRydWUiLCByZXN1bHQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNpemUgb2Ygc2V0V2l0aElubmVyQ2xhc3Mgc2hvdWxkIGJlIDEiLCAxLCBzZXRXaXRoSW5uZXJDbGFzcy5zaXplKCkpOworCisgICAgICAgIHJlc3VsdCA9IHNldFdpdGhJbm5lckNsYXNzLmNvbnRhaW5zKEVudW1XaXRoSW5uZXJDbGFzcy5mKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiB0cnVlIiwgcmVzdWx0KTsKKworICAgICAgICAvLyB0ZXN0IGVudW0gdHlwZSB3aXRoIG1vcmUgdGhhbiA2NCBlbGVtZW50cworICAgICAgICBTZXQ8SHVnZUVudW0+IGh1Z2VTZXQgPSBFbnVtU2V0LmFsbE9mKEh1Z2VFbnVtLmNsYXNzKTsKKworICAgICAgICBDb2xsZWN0aW9uPEh1Z2VFbnVtPiBodWdlQ29sbGVjdGlvbiA9IG5ldyBBcnJheUxpc3Q8SHVnZUVudW0+KCk7CisgICAgICAgIGh1Z2VDb2xsZWN0aW9uLmFkZChIdWdlRW51bS5hKTsKKworICAgICAgICByZXN1bHQgPSBodWdlU2V0LnJlbW92ZUFsbChodWdlQ29sbGVjdGlvbik7CisgICAgICAgIGFzc2VydFRydWUocmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDY0LCBodWdlU2V0LnNpemUoKSk7CisKKyAgICAgICAgY29sbGVjdGlvbiA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5yZW1vdmVBbGwoY29sbGVjdGlvbik7CisgICAgICAgIGFzc2VydEZhbHNlKHJlc3VsdCk7CisKKyAgICAgICAgU2V0PEh1Z2VFbnVtPiBlbXB0eUh1Z2VTZXQgPSBFbnVtU2V0Lm5vbmVPZihIdWdlRW51bS5jbGFzcyk7CisgICAgICAgIHJlc3VsdCA9IGh1Z2VTZXQucmVtb3ZlQWxsKGVtcHR5SHVnZVNldCk7CisgICAgICAgIGFzc2VydEZhbHNlKHJlc3VsdCk7CisKKyAgICAgICAgU2V0PEh1Z2VFbnVtV2l0aElubmVyQ2xhc3M+IGh1Z2VTZXRXaXRoU3ViY2xhc3MgPSBFbnVtU2V0CisgICAgICAgICAgICAgICAgLm5vbmVPZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5yZW1vdmVBbGwoaHVnZVNldFdpdGhTdWJjbGFzcyk7CisgICAgICAgIGFzc2VydEZhbHNlKHJlc3VsdCk7CisKKyAgICAgICAgaHVnZVNldFdpdGhTdWJjbGFzcy5hZGQoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5hKTsKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5yZW1vdmVBbGwoaHVnZVNldFdpdGhTdWJjbGFzcyk7CisgICAgICAgIGFzc2VydEZhbHNlKHJlc3VsdCk7CisKKyAgICAgICAgU2V0PEh1Z2VFbnVtPiBhbm90aGVySHVnZVNldCA9IEVudW1TZXQubm9uZU9mKEh1Z2VFbnVtLmNsYXNzKTsKKyAgICAgICAgYW5vdGhlckh1Z2VTZXQuYWRkKEh1Z2VFbnVtLmEpOworCisgICAgICAgIGh1Z2VTZXQgPSBFbnVtU2V0LmFsbE9mKEh1Z2VFbnVtLmNsYXNzKTsKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5yZW1vdmVBbGwoYW5vdGhlckh1Z2VTZXQpOworICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscyg2Mywgc2V0LnNpemUoKSk7CisKKyAgICAgICAgU2V0PEh1Z2VFbnVtV2l0aElubmVyQ2xhc3M+IGh1Z2VTZXRXaXRoSW5uZXJDbGFzcyA9IEVudW1TZXQKKyAgICAgICAgICAgICAgICAubm9uZU9mKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuY2xhc3MpOworICAgICAgICBodWdlU2V0V2l0aElubmVyQ2xhc3MuYWRkKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYSk7CisgICAgICAgIGh1Z2VTZXRXaXRoSW5uZXJDbGFzcy5hZGQoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5iKTsKKworICAgICAgICBTZXQ8SHVnZUVudW1XaXRoSW5uZXJDbGFzcz4gYW5vdGhlckh1Z2VTZXRXaXRoSW5uZXJDbGFzcyA9IEVudW1TZXQKKyAgICAgICAgICAgICAgICAubm9uZU9mKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuY2xhc3MpOworICAgICAgICBhbm90aGVySHVnZVNldFdpdGhJbm5lckNsYXNzLmFkZChIdWdlRW51bVdpdGhJbm5lckNsYXNzLmMpOworICAgICAgICBhbm90aGVySHVnZVNldFdpdGhJbm5lckNsYXNzLmFkZChIdWdlRW51bVdpdGhJbm5lckNsYXNzLmQpOworICAgICAgICByZXN1bHQgPSBhbm90aGVySHVnZVNldFdpdGhJbm5lckNsYXNzLnJlbW92ZUFsbChzZXRXaXRoSW5uZXJDbGFzcyk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICBhbm90aGVySHVnZVNldFdpdGhJbm5lckNsYXNzLmFkZChIdWdlRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICByZXN1bHQgPSBhbm90aGVySHVnZVNldFdpdGhJbm5lckNsYXNzLnJlbW92ZUFsbChodWdlU2V0V2l0aElubmVyQ2xhc3MpOworICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBhbm90aGVySHVnZVNldFdpdGhJbm5lckNsYXNzLnNpemUoKSk7CisKKyAgICAgICAgYW5vdGhlckh1Z2VTZXRXaXRoSW5uZXJDbGFzcy5yZW1vdmUoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5jKTsKKyAgICAgICAgYW5vdGhlckh1Z2VTZXRXaXRoSW5uZXJDbGFzcy5yZW1vdmUoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5kKTsKKyAgICAgICAgcmVzdWx0ID0gYW5vdGhlckh1Z2VTZXRXaXRoSW5uZXJDbGFzcy5yZW1vdmUoaHVnZVNldFdpdGhJbm5lckNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKworICAgICAgICByYXdTZXQgPSBFbnVtU2V0LmFsbE9mKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuY2xhc3MpOworICAgICAgICByZXN1bHQgPSByYXdTZXQucmVtb3ZlQWxsKEVudW1TZXQuYWxsT2YoSHVnZUVudW0uY2xhc3MpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKworICAgICAgICBodWdlU2V0V2l0aElubmVyQ2xhc3MgPSBFbnVtU2V0LmFsbE9mKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuY2xhc3MpOworICAgICAgICBhbm90aGVySHVnZVNldFdpdGhJbm5lckNsYXNzID0gRW51bVNldC5hbGxPZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgaHVnZVNldFdpdGhJbm5lckNsYXNzLnJlbW92ZShIdWdlRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICBhbm90aGVySHVnZVNldFdpdGhJbm5lckNsYXNzLnJlbW92ZShIdWdlRW51bVdpdGhJbm5lckNsYXNzLmYpOworICAgICAgICByZXN1bHQgPSBodWdlU2V0V2l0aElubmVyQ2xhc3MucmVtb3ZlQWxsKGFub3RoZXJIdWdlU2V0V2l0aElubmVyQ2xhc3MpOworICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBodWdlU2V0V2l0aElubmVyQ2xhc3Muc2l6ZSgpKTsKKworICAgICAgICByZXN1bHQgPSBodWdlU2V0V2l0aElubmVyQ2xhc3MuY29udGFpbnMoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5mKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtU2V0I3JldGFpbkFsbChDb2xsZWN0aW9uKQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfcmV0YWluQWxsX0xDb2xsZWN0aW9uKCkgeworICAgICAgICBTZXQ8RW51bUZvbz4gc2V0ID0gRW51bVNldC5hbGxPZihFbnVtRm9vLmNsYXNzKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2V0LnJldGFpbkFsbChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgc2V0LmNsZWFyKCk7CisgICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gc2V0LnJldGFpbkFsbChudWxsKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCByZXR1cm4gZmFsc2UiLCByZXN1bHQpOworCisgICAgICAgIENvbGxlY3Rpb24gcmF3Q29sbGVjdGlvbiA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgcmVzdWx0ID0gc2V0LnJldGFpbkFsbChyYXdDb2xsZWN0aW9uKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCByZXR1cm4gZmFsc2UiLCByZXN1bHQpOworCisgICAgICAgIHJhd0NvbGxlY3Rpb24uYWRkKEVudW1Gb28uYSk7CisgICAgICAgIHJlc3VsdCA9IHNldC5yZXRhaW5BbGwocmF3Q29sbGVjdGlvbik7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICByYXdDb2xsZWN0aW9uLmFkZChFbnVtV2l0aElubmVyQ2xhc3MuYSk7CisgICAgICAgIHJlc3VsdCA9IHNldC5yZXRhaW5BbGwocmF3Q29sbGVjdGlvbik7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIG9mIHNldCBzaG91bGQgYmUgMDoiLCAwLCBzZXQuc2l6ZSgpKTsKKworICAgICAgICByYXdDb2xsZWN0aW9uLnJlbW92ZShFbnVtRm9vLmEpOworICAgICAgICByZXN1bHQgPSBzZXQucmV0YWluQWxsKHJhd0NvbGxlY3Rpb24pOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIHJldHVybiBmYWxzZSIsIHJlc3VsdCk7CisKKyAgICAgICAgU2V0PEVudW1Gb28+IGFub3RoZXJTZXQgPSBFbnVtU2V0LmFsbE9mKEVudW1Gb28uY2xhc3MpOworICAgICAgICByZXN1bHQgPSBzZXQucmV0YWluQWxsKGFub3RoZXJTZXQpOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIHJldHVybiBmYWxzZSIsIHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBvZiBzZXQgc2hvdWxkIGJlIDAiLCAwLCBzZXQuc2l6ZSgpKTsKKworICAgICAgICBTZXQ8RW51bVdpdGhJbm5lckNsYXNzPiBzZXRXaXRoSW5uZXJDbGFzcyA9IEVudW1TZXQKKyAgICAgICAgICAgICAgICAuYWxsT2YoRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgcmVzdWx0ID0gc2V0LnJldGFpbkFsbChzZXRXaXRoSW5uZXJDbGFzcyk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIG9mIHNldCBzaG91bGQgYmUgMCIsIDAsIHNldC5zaXplKCkpOworCisgICAgICAgIHNldFdpdGhJbm5lckNsYXNzID0gRW51bVNldC5ub25lT2YoRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgcmVzdWx0ID0gc2V0LnJldGFpbkFsbChzZXRXaXRoSW5uZXJDbGFzcyk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICBTZXQ8RW1wdHlFbnVtPiBlbXB0eVNldCA9IEVudW1TZXQuYWxsT2YoRW1wdHlFbnVtLmNsYXNzKTsKKyAgICAgICAgcmVzdWx0ID0gc2V0LnJldGFpbkFsbChlbXB0eVNldCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICBTZXQ8RW51bVdpdGhBbGxJbm5lckNsYXNzPiBzZXRXaXRoQWxsSW5uZXJDbGFzcyA9IEVudW1TZXQKKyAgICAgICAgICAgICAgICAuYWxsT2YoRW51bVdpdGhBbGxJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgcmVzdWx0ID0gc2V0LnJldGFpbkFsbChzZXRXaXRoQWxsSW5uZXJDbGFzcyk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICBzZXQuYWRkKEVudW1Gb28uYSk7CisgICAgICAgIHJlc3VsdCA9IHNldC5yZXRhaW5BbGwoc2V0V2l0aElubmVyQ2xhc3MpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIHRydWUiLCByZXN1bHQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNpemUgb2Ygc2V0IHNob3VsZCBiZSAwIiwgMCwgc2V0LnNpemUoKSk7CisKKyAgICAgICAgc2V0V2l0aElubmVyQ2xhc3MgPSBFbnVtU2V0LmFsbE9mKEVudW1XaXRoSW5uZXJDbGFzcy5jbGFzcyk7CisgICAgICAgIHNldFdpdGhJbm5lckNsYXNzLnJlbW92ZShFbnVtV2l0aElubmVyQ2xhc3MuZik7CisgICAgICAgIFNldDxFbnVtV2l0aElubmVyQ2xhc3M+IGFub3RoZXJTZXRXaXRoSW5uZXJDbGFzcyA9IEVudW1TZXQKKyAgICAgICAgICAgICAgICAubm9uZU9mKEVudW1XaXRoSW5uZXJDbGFzcy5jbGFzcyk7CisgICAgICAgIGFub3RoZXJTZXRXaXRoSW5uZXJDbGFzcy5hZGQoRW51bVdpdGhJbm5lckNsYXNzLmUpOworICAgICAgICBhbm90aGVyU2V0V2l0aElubmVyQ2xhc3MuYWRkKEVudW1XaXRoSW5uZXJDbGFzcy5mKTsKKworICAgICAgICByZXN1bHQgPSBzZXRXaXRoSW5uZXJDbGFzcy5yZXRhaW5BbGwoYW5vdGhlclNldFdpdGhJbm5lckNsYXNzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiB0cnVlIiwgcmVzdWx0KTsKKyAgICAgICAgcmVzdWx0ID0gc2V0V2l0aElubmVyQ2xhc3MuY29udGFpbnMoRW51bVdpdGhJbm5lckNsYXNzLmUpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgY29udGFpbiBFbnVtV2l0aElubmVyQ2xhc3MuZSIsIHJlc3VsdCk7CisgICAgICAgIHJlc3VsdCA9IHNldFdpdGhJbm5lckNsYXNzLmNvbnRhaW5zKEVudW1XaXRoSW5uZXJDbGFzcy5iKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCBub3QgY29udGFpbiBFbnVtV2l0aElubmVyQ2xhc3MuYiIsIHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBvZiBzZXQgc2hvdWxkIGJlIDE6IiwgMSwgc2V0V2l0aElubmVyQ2xhc3Muc2l6ZSgpKTsKKworICAgICAgICBhbm90aGVyU2V0V2l0aElubmVyQ2xhc3MgPSBFbnVtU2V0LmFsbE9mKEVudW1XaXRoSW5uZXJDbGFzcy5jbGFzcyk7CisgICAgICAgIHJlc3VsdCA9IHNldFdpdGhJbm5lckNsYXNzLnJldGFpbkFsbChhbm90aGVyU2V0V2l0aElubmVyQ2xhc3MpOworCisgICAgICAgIGFzc2VydEZhbHNlKCJSZXR1cm4gdmFsdWUgc2hvdWxkIGJlIGZhbHNlIiwgcmVzdWx0KTsKKworICAgICAgICByYXdDb2xsZWN0aW9uID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICByYXdDb2xsZWN0aW9uLmFkZChFbnVtV2l0aElubmVyQ2xhc3MuZSk7CisgICAgICAgIHJhd0NvbGxlY3Rpb24uYWRkKEVudW1XaXRoSW5uZXJDbGFzcy5mKTsKKyAgICAgICAgcmVzdWx0ID0gc2V0V2l0aElubmVyQ2xhc3MucmV0YWluQWxsKHJhd0NvbGxlY3Rpb24pOworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIHJldHVybiBmYWxzZSIsIHJlc3VsdCk7CisKKyAgICAgICAgc2V0ID0gRW51bVNldC5hbGxPZihFbnVtRm9vLmNsYXNzKTsKKyAgICAgICAgc2V0LnJlbW92ZShFbnVtRm9vLmEpOworICAgICAgICBhbm90aGVyU2V0ID0gRW51bVNldC5ub25lT2YoRW51bUZvby5jbGFzcyk7CisgICAgICAgIGFub3RoZXJTZXQuYWRkKEVudW1Gb28uYSk7CisgICAgICAgIHJlc3VsdCA9IHNldC5yZXRhaW5BbGwoYW5vdGhlclNldCk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCByZXR1cm4gdHJ1ZSIsIHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscygic2l6ZSBzaG91bGQgYmUgMCIsIDAsIHNldC5zaXplKCkpOworCisgICAgICAgIC8vIHRlc3QgZW51bSB0eXBlIHdpdGggbW9yZSB0aGFuIDY0IGVsZW1lbnRzCisgICAgICAgIFNldDxIdWdlRW51bT4gaHVnZVNldCA9IEVudW1TZXQuYWxsT2YoSHVnZUVudW0uY2xhc3MpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBodWdlU2V0LnJldGFpbkFsbChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgaHVnZVNldC5jbGVhcigpOworICAgICAgICByZXN1bHQgPSBodWdlU2V0LnJldGFpbkFsbChudWxsKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKworICAgICAgICByYXdDb2xsZWN0aW9uID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgICByZXN1bHQgPSBodWdlU2V0LnJldGFpbkFsbChyYXdDb2xsZWN0aW9uKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKworICAgICAgICByYXdDb2xsZWN0aW9uLmFkZChIdWdlRW51bS5hKTsKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5yZXRhaW5BbGwocmF3Q29sbGVjdGlvbik7CisgICAgICAgIGFzc2VydEZhbHNlKHJlc3VsdCk7CisKKyAgICAgICAgcmF3Q29sbGVjdGlvbi5hZGQoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5hKTsKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5yZXRhaW5BbGwocmF3Q29sbGVjdGlvbik7CisgICAgICAgIGFzc2VydEZhbHNlKHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBzZXQuc2l6ZSgpKTsKKworICAgICAgICByYXdDb2xsZWN0aW9uLnJlbW92ZShIdWdlRW51bS5hKTsKKyAgICAgICAgcmVzdWx0ID0gc2V0LnJldGFpbkFsbChyYXdDb2xsZWN0aW9uKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKworICAgICAgICBTZXQ8SHVnZUVudW0+IGFub3RoZXJIdWdlU2V0ID0gRW51bVNldC5hbGxPZihIdWdlRW51bS5jbGFzcyk7CisgICAgICAgIHJlc3VsdCA9IGh1Z2VTZXQucmV0YWluQWxsKGFub3RoZXJIdWdlU2V0KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGh1Z2VTZXQuc2l6ZSgpKTsKKworICAgICAgICBTZXQ8SHVnZUVudW1XaXRoSW5uZXJDbGFzcz4gaHVnZVNldFdpdGhJbm5lckNsYXNzID0gRW51bVNldAorICAgICAgICAgICAgICAgIC5hbGxPZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5yZXRhaW5BbGwoaHVnZVNldFdpdGhJbm5lckNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGh1Z2VTZXQuc2l6ZSgpKTsKKworICAgICAgICBodWdlU2V0V2l0aElubmVyQ2xhc3MgPSBFbnVtU2V0Lm5vbmVPZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5yZXRhaW5BbGwoaHVnZVNldFdpdGhJbm5lckNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKworICAgICAgICBTZXQ8SHVnZUVudW1XaXRoSW5uZXJDbGFzcz4gaHVnZVNldFdpdGhBbGxJbm5lckNsYXNzID0gRW51bVNldAorICAgICAgICAgICAgICAgIC5hbGxPZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5yZXRhaW5BbGwoaHVnZVNldFdpdGhBbGxJbm5lckNsYXNzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKworICAgICAgICBodWdlU2V0LmFkZChIdWdlRW51bS5hKTsKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldC5yZXRhaW5BbGwoaHVnZVNldFdpdGhJbm5lckNsYXNzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaHVnZVNldC5zaXplKCkpOworCisgICAgICAgIGh1Z2VTZXRXaXRoSW5uZXJDbGFzcyA9IEVudW1TZXQuYWxsT2YoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5jbGFzcyk7CisgICAgICAgIGh1Z2VTZXRXaXRoSW5uZXJDbGFzcy5yZW1vdmUoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5mKTsKKyAgICAgICAgU2V0PEh1Z2VFbnVtV2l0aElubmVyQ2xhc3M+IGFub3RoZXJIdWdlU2V0V2l0aElubmVyQ2xhc3MgPSBFbnVtU2V0CisgICAgICAgICAgICAgICAgLm5vbmVPZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgYW5vdGhlckh1Z2VTZXRXaXRoSW5uZXJDbGFzcy5hZGQoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5lKTsKKyAgICAgICAgYW5vdGhlckh1Z2VTZXRXaXRoSW5uZXJDbGFzcy5hZGQoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5mKTsKKworICAgICAgICByZXN1bHQgPSBodWdlU2V0V2l0aElubmVyQ2xhc3MucmV0YWluQWxsKGFub3RoZXJIdWdlU2V0V2l0aElubmVyQ2xhc3MpOworICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCk7CisgICAgICAgIHJlc3VsdCA9IGh1Z2VTZXRXaXRoSW5uZXJDbGFzcy5jb250YWlucyhIdWdlRW51bVdpdGhJbm5lckNsYXNzLmUpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgY29udGFpbiBIdWdlRW51bVdpdGhJbm5lckNsYXNzLmUiLCByZXN1bHQpOworICAgICAgICByZXN1bHQgPSBodWdlU2V0V2l0aElubmVyQ2xhc3MuY29udGFpbnMoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5iKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCBub3QgY29udGFpbiBIdWdlRW51bVdpdGhJbm5lckNsYXNzLmIiLCByZXN1bHQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNpemUgb2YgaHVnZVNldCBzaG91bGQgYmUgMToiLCAxLCBodWdlU2V0V2l0aElubmVyQ2xhc3Muc2l6ZSgpKTsKKworICAgICAgICBhbm90aGVySHVnZVNldFdpdGhJbm5lckNsYXNzID0gRW51bVNldC5hbGxPZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldFdpdGhJbm5lckNsYXNzLnJldGFpbkFsbChhbm90aGVySHVnZVNldFdpdGhJbm5lckNsYXNzKTsKKworICAgICAgICBhc3NlcnRGYWxzZSgiUmV0dXJuIHZhbHVlIHNob3VsZCBiZSBmYWxzZSIsIHJlc3VsdCk7CisKKyAgICAgICAgcmF3Q29sbGVjdGlvbiA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgcmF3Q29sbGVjdGlvbi5hZGQoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5lKTsKKyAgICAgICAgcmF3Q29sbGVjdGlvbi5hZGQoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5mKTsKKyAgICAgICAgcmVzdWx0ID0gaHVnZVNldFdpdGhJbm5lckNsYXNzLnJldGFpbkFsbChyYXdDb2xsZWN0aW9uKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0KTsKKworICAgICAgICBodWdlU2V0ID0gRW51bVNldC5hbGxPZihIdWdlRW51bS5jbGFzcyk7CisgICAgICAgIGh1Z2VTZXQucmVtb3ZlKEh1Z2VFbnVtLmEpOworICAgICAgICBhbm90aGVySHVnZVNldCA9IEVudW1TZXQubm9uZU9mKEh1Z2VFbnVtLmNsYXNzKTsKKyAgICAgICAgYW5vdGhlckh1Z2VTZXQuYWRkKEh1Z2VFbnVtLmEpOworICAgICAgICByZXN1bHQgPSBodWdlU2V0LnJldGFpbkFsbChhbm90aGVySHVnZVNldCk7CisgICAgICAgIGFzc2VydFRydWUocmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGh1Z2VTZXQuc2l6ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRW51bVNldCNpdGVyYXRvcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pdGVyYXRvcigpIHsKKyAgICAgICAgU2V0PEVudW1Gb28+IHNldCA9IEVudW1TZXQubm9uZU9mKEVudW1Gb28uY2xhc3MpOworICAgICAgICBzZXQuYWRkKEVudW1Gb28uYSk7CisgICAgICAgIHNldC5hZGQoRW51bUZvby5iKTsKKworICAgICAgICBJdGVyYXRvcjxFbnVtRm9vPiBpdGVyYXRvciA9IHNldC5pdGVyYXRvcigpOworICAgICAgICBJdGVyYXRvcjxFbnVtRm9vPiBhbm90aGVySXRlcmF0b3IgPSBzZXQuaXRlcmF0b3IoKTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZSgiU2hvdWxkIG5vdCBiZSBzYW1lIiwgaXRlcmF0b3IsIGFub3RoZXJJdGVyYXRvcik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpdGVyYXRvci5yZW1vdmUoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkZAorICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGhhcyBuZXh0IGVsZW1lbnQ6IiwgaXRlcmF0b3IuaGFzTmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiU2hvdWxkIGJlIGlkZW50aWNhbCIsIEVudW1Gb28uYSwgaXRlcmF0b3IubmV4dCgpKTsKKyAgICAgICAgaXRlcmF0b3IucmVtb3ZlKCk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBoYXMgbmV4dCBlbGVtZW50OiIsIGl0ZXJhdG9yLmhhc05leHQoKSk7CisgICAgICAgIGFzc2VydFNhbWUoIlNob3VsZCBiZSBpZGVudGljYWwiLCBFbnVtRm9vLmIsIGl0ZXJhdG9yLm5leHQoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgbm90IGhhcyBuZXh0IGVsZW1lbnQ6IiwgaXRlcmF0b3IuaGFzTmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCBub3QgaGFzIG5leHQgZWxlbWVudDoiLCBpdGVyYXRvci5oYXNOZXh0KCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBzaG91bGQgYmUgMToiLCAxLCBzZXQuc2l6ZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaXRlcmF0b3IubmV4dCgpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHNldCA9IEVudW1TZXQubm9uZU9mKEVudW1Gb28uY2xhc3MpOworICAgICAgICBzZXQuYWRkKEVudW1Gb28uYSk7CisgICAgICAgIGl0ZXJhdG9yID0gc2V0Lml0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIGJlIGVxdWFsIiwgRW51bUZvby5hLCBpdGVyYXRvci5uZXh0KCkpOworICAgICAgICBpdGVyYXRvci5yZW1vdmUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGl0ZXJhdG9yLnJlbW92ZSgpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgU2V0PEVtcHR5RW51bT4gZW1wdHlTZXQgPSBFbnVtU2V0LmFsbE9mKEVtcHR5RW51bS5jbGFzcyk7CisgICAgICAgIEl0ZXJhdG9yPEVtcHR5RW51bT4gZW1wdHlJdGVyYXRvciA9IGVtcHR5U2V0Lml0ZXJhdG9yKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbXB0eUl0ZXJhdG9yLm5leHQoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIFNldDxFbnVtV2l0aElubmVyQ2xhc3M+IHNldFdpdGhTdWJjbGFzcyA9IEVudW1TZXQKKyAgICAgICAgICAgICAgICAuYWxsT2YoRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgc2V0V2l0aFN1YmNsYXNzLnJlbW92ZShFbnVtV2l0aElubmVyQ2xhc3MuZSk7CisgICAgICAgIEl0ZXJhdG9yPEVudW1XaXRoSW5uZXJDbGFzcz4gaXRlcmF0b3JXaXRoU3ViY2xhc3MgPSBzZXRXaXRoU3ViY2xhc3MKKyAgICAgICAgICAgICAgICAuaXRlcmF0b3IoKTsKKyAgICAgICAgYXNzZXJ0U2FtZSgiU2hvdWxkIGJlIHNhbWUiLCBFbnVtV2l0aElubmVyQ2xhc3MuYSwgaXRlcmF0b3JXaXRoU3ViY2xhc3MubmV4dCgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIHRydWUiLCBpdGVyYXRvcldpdGhTdWJjbGFzcy5oYXNOZXh0KCkpOworICAgICAgICBhc3NlcnRTYW1lKCJTaG91bGQgYmUgc2FtZSIsIEVudW1XaXRoSW5uZXJDbGFzcy5iLCBpdGVyYXRvcldpdGhTdWJjbGFzcy5uZXh0KCkpOworCisgICAgICAgIHNldFdpdGhTdWJjbGFzcy5yZW1vdmUoRW51bVdpdGhJbm5lckNsYXNzLmMpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIHRydWUiLCBpdGVyYXRvcldpdGhTdWJjbGFzcy5oYXNOZXh0KCkpOworICAgICAgICBhc3NlcnRTYW1lKCJTaG91bGQgYmUgc2FtZSIsIEVudW1XaXRoSW5uZXJDbGFzcy5jLCBpdGVyYXRvcldpdGhTdWJjbGFzcy5uZXh0KCkpOworCisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCByZXR1cm4gdHJ1ZSIsIGl0ZXJhdG9yV2l0aFN1YmNsYXNzLmhhc05leHQoKSk7CisgICAgICAgIGFzc2VydFNhbWUoIlNob3VsZCBiZSBzYW1lIiwgRW51bVdpdGhJbm5lckNsYXNzLmQsIGl0ZXJhdG9yV2l0aFN1YmNsYXNzLm5leHQoKSk7CisKKyAgICAgICAgc2V0V2l0aFN1YmNsYXNzLmFkZChFbnVtV2l0aElubmVyQ2xhc3MuZSk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCByZXR1cm4gdHJ1ZSIsIGl0ZXJhdG9yV2l0aFN1YmNsYXNzLmhhc05leHQoKSk7CisgICAgICAgIGFzc2VydFNhbWUoIlNob3VsZCBiZSBzYW1lIiwgRW51bVdpdGhJbm5lckNsYXNzLmYsIGl0ZXJhdG9yV2l0aFN1YmNsYXNzLm5leHQoKSk7CisKKyAgICAgICAgc2V0ID0gRW51bVNldC5ub25lT2YoRW51bUZvby5jbGFzcyk7CisgICAgICAgIGl0ZXJhdG9yID0gc2V0Lml0ZXJhdG9yKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpdGVyYXRvci5uZXh0KCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBzZXQuYWRkKEVudW1Gb28uYSk7CisgICAgICAgIGl0ZXJhdG9yID0gc2V0Lml0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIHJldHVybiBFbnVtRm9vLmEiLCBFbnVtRm9vLmEsIGl0ZXJhdG9yLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBvZiBzZXQgc2hvdWxkIGJlIDEiLCAxLCBzZXQuc2l6ZSgpKTsKKyAgICAgICAgaXRlcmF0b3IucmVtb3ZlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBvZiBzZXQgc2hvdWxkIGJlIDAiLCAwLCBzZXQuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCByZXR1cm4gZmFsc2UiLCBzZXQuY29udGFpbnMoRW51bUZvby5hKSk7CisKKyAgICAgICAgc2V0LmFkZChFbnVtRm9vLmEpOworICAgICAgICBzZXQuYWRkKEVudW1Gb28uYik7CisgICAgICAgIGl0ZXJhdG9yID0gc2V0Lml0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIGJlIGVxdWFscyIsIEVudW1Gb28uYSwgaXRlcmF0b3IubmV4dCgpKTsKKyAgICAgICAgaXRlcmF0b3IucmVtb3ZlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpdGVyYXRvci5yZW1vdmUoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBoYXZlIG5leHQgZWxlbWVudCIsIGl0ZXJhdG9yLmhhc05leHQoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpdGVyYXRvci5yZW1vdmUoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIG9mIHNldCBzaG91bGQgYmUgMSIsIDEsIHNldC5zaXplKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgaGF2ZSBuZXh0IGVsZW1lbnQiLCBpdGVyYXRvci5oYXNOZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCByZXR1cm4gRW51bUZvby5iIiwgRW51bUZvby5iLCBpdGVyYXRvci5uZXh0KCkpOworICAgICAgICBzZXQucmVtb3ZlKEVudW1Gb28uYik7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBvZiBzZXQgc2hvdWxkIGJlIDAiLCAwLCBzZXQuc2l6ZSgpKTsKKyAgICAgICAgaXRlcmF0b3IucmVtb3ZlKCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgc2V0LmNvbnRhaW5zKEVudW1Gb28uYSkpOworCisgICAgICAgIC8vIFJJJ3MgYnVnLCBFbnVtRm9vLmIgc2hvdWxkIG5vdCBleGlzdCBhdCB0aGUgbW9tZW50LgorICAgICAgICBpZiAoIWRpc2FibGVSSUJ1Z3MpIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJTaG91bGQgcmV0dXJuIGZhbHNlIiwgc2V0LmNvbnRhaW5zKEVudW1Gb28uYikpOworICAgICAgICB9CisKKyAgICAgICAgLy8gdGVzdCBlbnVtIHR5cGUgd2l0aCBtb3JlIHRoYW4gNjQgZWxlbWVudHMKKyAgICAgICAgU2V0PEh1Z2VFbnVtPiBodWdlU2V0ID0gRW51bVNldC5ub25lT2YoSHVnZUVudW0uY2xhc3MpOworICAgICAgICBodWdlU2V0LmFkZChIdWdlRW51bS5hKTsKKyAgICAgICAgaHVnZVNldC5hZGQoSHVnZUVudW0uYik7CisKKyAgICAgICAgSXRlcmF0b3I8SHVnZUVudW0+IGhJdGVyYXRvciA9IGh1Z2VTZXQuaXRlcmF0b3IoKTsKKyAgICAgICAgSXRlcmF0b3I8SHVnZUVudW0+IGFub3RoZXJIdWdlSXRlcmF0b3IgPSBodWdlU2V0Lml0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydE5vdFNhbWUoaEl0ZXJhdG9yLCBhbm90aGVySHVnZUl0ZXJhdG9yKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGhJdGVyYXRvci5yZW1vdmUoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkZAorICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShoSXRlcmF0b3IuaGFzTmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShIdWdlRW51bS5hLCBoSXRlcmF0b3IubmV4dCgpKTsKKyAgICAgICAgaEl0ZXJhdG9yLnJlbW92ZSgpOworICAgICAgICBhc3NlcnRUcnVlKGhJdGVyYXRvci5oYXNOZXh0KCkpOworICAgICAgICBhc3NlcnRTYW1lKEh1Z2VFbnVtLmIsIGhJdGVyYXRvci5uZXh0KCkpOworICAgICAgICBhc3NlcnRGYWxzZShoSXRlcmF0b3IuaGFzTmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoaEl0ZXJhdG9yLmhhc05leHQoKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGh1Z2VTZXQuc2l6ZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaEl0ZXJhdG9yLm5leHQoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIFNldDxIdWdlRW51bVdpdGhJbm5lckNsYXNzPiBodWdlU2V0V2l0aFN1YmNsYXNzID0gRW51bVNldAorICAgICAgICAgICAgICAgIC5hbGxPZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmNsYXNzKTsKKyAgICAgICAgaHVnZVNldFdpdGhTdWJjbGFzcy5yZW1vdmUoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5lKTsKKyAgICAgICAgSXRlcmF0b3I8SHVnZUVudW1XaXRoSW5uZXJDbGFzcz4gaHVnZUl0ZXJhdG9yV2l0aFN1YmNsYXNzID0gaHVnZVNldFdpdGhTdWJjbGFzcworICAgICAgICAgICAgICAgIC5pdGVyYXRvcigpOworICAgICAgICBhc3NlcnRTYW1lKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYSwgaHVnZUl0ZXJhdG9yV2l0aFN1YmNsYXNzLm5leHQoKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShodWdlSXRlcmF0b3JXaXRoU3ViY2xhc3MuaGFzTmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShIdWdlRW51bVdpdGhJbm5lckNsYXNzLmIsIGh1Z2VJdGVyYXRvcldpdGhTdWJjbGFzcy5uZXh0KCkpOworCisgICAgICAgIHNldFdpdGhTdWJjbGFzcy5yZW1vdmUoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5jKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShodWdlSXRlcmF0b3JXaXRoU3ViY2xhc3MuaGFzTmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShIdWdlRW51bVdpdGhJbm5lckNsYXNzLmMsIGh1Z2VJdGVyYXRvcldpdGhTdWJjbGFzcy5uZXh0KCkpOworCisgICAgICAgIGFzc2VydFRydWUoaHVnZUl0ZXJhdG9yV2l0aFN1YmNsYXNzLmhhc05leHQoKSk7CisgICAgICAgIGFzc2VydFNhbWUoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5kLCBodWdlSXRlcmF0b3JXaXRoU3ViY2xhc3MubmV4dCgpKTsKKworICAgICAgICBodWdlU2V0V2l0aFN1YmNsYXNzLmFkZChIdWdlRW51bVdpdGhJbm5lckNsYXNzLmUpOworICAgICAgICBhc3NlcnRUcnVlKGh1Z2VJdGVyYXRvcldpdGhTdWJjbGFzcy5oYXNOZXh0KCkpOworICAgICAgICBhc3NlcnRTYW1lKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuZiwgaHVnZUl0ZXJhdG9yV2l0aFN1YmNsYXNzLm5leHQoKSk7CisKKyAgICAgICAgaHVnZVNldCA9IEVudW1TZXQubm9uZU9mKEh1Z2VFbnVtLmNsYXNzKTsKKyAgICAgICAgaEl0ZXJhdG9yID0gaHVnZVNldC5pdGVyYXRvcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaEl0ZXJhdG9yLm5leHQoKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGh1Z2VTZXQuYWRkKEh1Z2VFbnVtLmEpOworICAgICAgICBoSXRlcmF0b3IgPSBodWdlU2V0Lml0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhIdWdlRW51bS5hLCBoSXRlcmF0b3IubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGh1Z2VTZXQuc2l6ZSgpKTsKKyAgICAgICAgaEl0ZXJhdG9yLnJlbW92ZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaHVnZVNldC5zaXplKCkpOworICAgICAgICBhc3NlcnRGYWxzZShodWdlU2V0LmNvbnRhaW5zKEh1Z2VFbnVtLmEpKTsKKworICAgICAgICBodWdlU2V0LmFkZChIdWdlRW51bS5hKTsKKyAgICAgICAgaHVnZVNldC5hZGQoSHVnZUVudW0uYik7CisgICAgICAgIGhJdGVyYXRvciA9IGh1Z2VTZXQuaXRlcmF0b3IoKTsKKyAgICAgICAgaEl0ZXJhdG9yLm5leHQoKTsKKyAgICAgICAgaEl0ZXJhdG9yLnJlbW92ZSgpOworCisgICAgICAgIGFzc2VydFRydWUoaEl0ZXJhdG9yLmhhc05leHQoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBoSXRlcmF0b3IucmVtb3ZlKCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygxLCBodWdlU2V0LnNpemUoKSk7CisgICAgICAgIGFzc2VydFRydWUoaEl0ZXJhdG9yLmhhc05leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhIdWdlRW51bS5iLCBoSXRlcmF0b3IubmV4dCgpKTsKKyAgICAgICAgaHVnZVNldC5yZW1vdmUoSHVnZUVudW0uYik7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBodWdlU2V0LnNpemUoKSk7CisgICAgICAgIGhJdGVyYXRvci5yZW1vdmUoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoaHVnZVNldC5jb250YWlucyhIdWdlRW51bS5hKSk7CisgICAgICAgIC8vIFJJJ3MgYnVnLCBFbnVtRm9vLmIgc2hvdWxkIG5vdCBleGlzdCBhdCB0aGUgbW9tZW50LgorICAgICAgICBpZighZGlzYWJsZVJJQnVncykgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCByZXR1cm4gZmFsc2UiLCBzZXQuY29udGFpbnMoRW51bUZvby5iKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRW51bVNldCNvZihFKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfT2ZfRSgpIHsKKyAgICAgICAgRW51bVNldDxFbnVtV2l0aElubmVyQ2xhc3M+IGVudW1TZXQgPSBFbnVtU2V0Lm9mKEVudW1XaXRoSW5uZXJDbGFzcy5hKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbnVtU2V0IHNob3VsZCBoYXZlIGxlbmd0aCAxOiIsIDEsIGVudW1TZXQuc2l6ZSgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJlbnVtU2V0IHNob3VsZCBjb250YWluIEVudW1XaXRoU3ViY2xhc3MuYToiLAorICAgICAgICAgICAgICAgIGVudW1TZXQuY29udGFpbnMoRW51bVdpdGhJbm5lckNsYXNzLmEpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgRW51bVNldC5vZigoRW51bVdpdGhJbm5lckNsYXNzKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyB0ZXN0IGVudW0gdHlwZSB3aXRoIG1vcmUgdGhhbiA2NCBlbGVtZW50cworICAgICAgICBFbnVtU2V0PEh1Z2VFbnVtV2l0aElubmVyQ2xhc3M+IGh1Z2VFbnVtU2V0ID0gRW51bVNldC5vZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaHVnZUVudW1TZXQuc2l6ZSgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKGh1Z2VFbnVtU2V0LmNvbnRhaW5zKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtU2V0I29mKEUsIEUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9PZl9FRSgpIHsKKyAgICAgICAgRW51bVNldDxFbnVtV2l0aElubmVyQ2xhc3M+IGVudW1TZXQgPSBFbnVtU2V0Lm9mKEVudW1XaXRoSW5uZXJDbGFzcy5hLAorICAgICAgICAgICAgICAgIEVudW1XaXRoSW5uZXJDbGFzcy5iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbnVtU2V0IHNob3VsZCBoYXZlIGxlbmd0aCAyOiIsIDIsIGVudW1TZXQuc2l6ZSgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJlbnVtU2V0IHNob3VsZCBjb250YWluIEVudW1XaXRoU3ViY2xhc3MuYToiLAorICAgICAgICAgICAgICAgIGVudW1TZXQuY29udGFpbnMoRW51bVdpdGhJbm5lckNsYXNzLmEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZW51bVNldCBzaG91bGQgY29udGFpbiBFbnVtV2l0aFN1YmNsYXNzLmI6IiwKKyAgICAgICAgICAgICAgICBlbnVtU2V0LmNvbnRhaW5zKEVudW1XaXRoSW5uZXJDbGFzcy5iKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVudW1TZXQub2YoKEVudW1XaXRoSW5uZXJDbGFzcykgbnVsbCwgRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0Lm9mKCBFbnVtV2l0aElubmVyQ2xhc3MuYSwgKEVudW1XaXRoSW5uZXJDbGFzcykgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVudW1TZXQub2YoIChFbnVtV2l0aElubmVyQ2xhc3MpIG51bGwsIChFbnVtV2l0aElubmVyQ2xhc3MpIG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGVudW1TZXQgPSBFbnVtU2V0Lm9mKEVudW1XaXRoSW5uZXJDbGFzcy5hLCBFbnVtV2l0aElubmVyQ2xhc3MuYSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBvZiBlbnVtU2V0IHNob3VsZCBiZSAxIiwKKyAgICAgICAgICAgICAgICAxLCBlbnVtU2V0LnNpemUoKSk7CisKKyAgICAgICAgLy8gdGVzdCBlbnVtIHR5cGUgd2l0aCBtb3JlIHRoYW4gNjQgZWxlbWVudHMKKyAgICAgICAgRW51bVNldDxIdWdlRW51bVdpdGhJbm5lckNsYXNzPiBodWdlRW51bVNldCA9IEVudW1TZXQub2YoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5hLAorICAgICAgICAgICAgICAgIEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYik7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBodWdlRW51bVNldC5zaXplKCkpOworCisgICAgICAgIGFzc2VydFRydWUoaHVnZUVudW1TZXQuY29udGFpbnMoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5hKSk7CisgICAgICAgIGFzc2VydFRydWUoaHVnZUVudW1TZXQuY29udGFpbnMoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5iKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVudW1TZXQub2YoKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MpIG51bGwsIEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVudW1TZXQub2YoIEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYSwgKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MpIG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0Lm9mKCAoSHVnZUVudW1XaXRoSW5uZXJDbGFzcykgbnVsbCwgKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MpIG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGh1Z2VFbnVtU2V0ID0gRW51bVNldC5vZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmEsIEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBodWdlRW51bVNldC5zaXplKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtU2V0I29mKEUsIEUsIEUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9PZl9FRUUoKSB7CisgICAgICAgIEVudW1TZXQ8RW51bVdpdGhJbm5lckNsYXNzPiBlbnVtU2V0ID0gRW51bVNldC5vZihFbnVtV2l0aElubmVyQ2xhc3MuYSwKKyAgICAgICAgICAgICAgICBFbnVtV2l0aElubmVyQ2xhc3MuYiwgRW51bVdpdGhJbm5lckNsYXNzLmMpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNpemUgb2YgZW51bVNldCBzaG91bGQgYmUgMzoiLCAzLCBlbnVtU2V0LnNpemUoKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiZW51bVNldCBzaG91bGQgY29udGFpbiBFbnVtV2l0aFN1YmNsYXNzLmE6IiwgZW51bVNldC5jb250YWlucyhFbnVtV2l0aElubmVyQ2xhc3MuYSkpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgcmV0dXJuIHRydWUiLCBlbnVtU2V0LmNvbnRhaW5zKEVudW1XaXRoSW5uZXJDbGFzcy5jKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVudW1TZXQub2YoKEVudW1XaXRoSW5uZXJDbGFzcykgbnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgZW51bVNldCA9IEVudW1TZXQub2YoRW51bVdpdGhJbm5lckNsYXNzLmEsIEVudW1XaXRoSW5uZXJDbGFzcy5iLAorICAgICAgICAgICAgICAgIEVudW1XaXRoSW5uZXJDbGFzcy5iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbnVtU2V0IHNob3VsZCBjb250YWluIDIgZWxlbWVudHM6IiwgMiwgZW51bVNldC5zaXplKCkpOworCisgICAgICAgIC8vIHRlc3QgZW51bSB0eXBlIHdpdGggbW9yZSB0aGFuIDY0IGVsZW1lbnRzCisgICAgICAgIEVudW1TZXQ8SHVnZUVudW1XaXRoSW5uZXJDbGFzcz4gaHVnZUVudW1TZXQgPSBFbnVtU2V0Lm9mKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYSwKKyAgICAgICAgICAgICAgICBIdWdlRW51bVdpdGhJbm5lckNsYXNzLmIsIEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYyk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBodWdlRW51bVNldC5zaXplKCkpOworCisgICAgICAgIGFzc2VydFRydWUoaHVnZUVudW1TZXQuY29udGFpbnMoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5hKSk7CisgICAgICAgIGFzc2VydFRydWUoaHVnZUVudW1TZXQuY29udGFpbnMoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5jKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVudW1TZXQub2YoKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MpIG51bGwsIG51bGwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGh1Z2VFbnVtU2V0ID0gRW51bVNldC5vZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmEsIEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYiwKKyAgICAgICAgICAgICAgICBIdWdlRW51bVdpdGhJbm5lckNsYXNzLmIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgaHVnZUVudW1TZXQuc2l6ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRW51bVNldCNvZihFLCBFLCBFLCBFKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfT2ZfRUVFRSgpIHsKKyAgICAgICAgRW51bVNldDxFbnVtV2l0aElubmVyQ2xhc3M+IGVudW1TZXQgPSBFbnVtU2V0Lm9mKEVudW1XaXRoSW5uZXJDbGFzcy5hLAorICAgICAgICAgICAgICAgIEVudW1XaXRoSW5uZXJDbGFzcy5iLCBFbnVtV2l0aElubmVyQ2xhc3MuYywKKyAgICAgICAgICAgICAgICBFbnVtV2l0aElubmVyQ2xhc3MuZCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBvZiBlbnVtU2V0IHNob3VsZCBiZSA0IiwgNCwgZW51bVNldC5zaXplKCkpOworCisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgImVudW1TZXQgc2hvdWxkIGNvbnRhaW4gRW51bVdpdGhTdWJjbGFzcy5hOiIsIGVudW1TZXQuY29udGFpbnMoRW51bVdpdGhJbm5lckNsYXNzLmEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZW51bVNldCBzaG91bGQgY29udGFpbiBFbnVtV2l0aFN1YmNsYXNzLmQ6IiwgZW51bVNldAorICAgICAgICAgICAgICAgIC5jb250YWlucyhFbnVtV2l0aElubmVyQ2xhc3MuZCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0Lm9mKChFbnVtV2l0aElubmVyQ2xhc3MpIG51bGwsIG51bGwsIG51bGwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3QgZW51bSB0eXBlIHdpdGggbW9yZSB0aGFuIDY0IGVsZW1lbnRzCisgICAgICAgIEVudW1TZXQ8SHVnZUVudW1XaXRoSW5uZXJDbGFzcz4gaHVnZUVudW1TZXQgPSBFbnVtU2V0Lm9mKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYSwKKyAgICAgICAgICAgICAgICBIdWdlRW51bVdpdGhJbm5lckNsYXNzLmIsIEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYywKKyAgICAgICAgICAgICAgICBIdWdlRW51bVdpdGhJbm5lckNsYXNzLmQpOworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgaHVnZUVudW1TZXQuc2l6ZSgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKGh1Z2VFbnVtU2V0LmNvbnRhaW5zKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYSkpOworICAgICAgICBhc3NlcnRUcnVlKGh1Z2VFbnVtU2V0LmNvbnRhaW5zKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuZCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0Lm9mKChIdWdlRW51bVdpdGhJbm5lckNsYXNzKSBudWxsLCBudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRW51bVNldCNvZihFLCBFLCBFLCBFLCBFKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfT2ZfRUVFRUUoKSB7CisgICAgICAgIEVudW1TZXQ8RW51bVdpdGhJbm5lckNsYXNzPiBlbnVtU2V0ID0gRW51bVNldC5vZihFbnVtV2l0aElubmVyQ2xhc3MuYSwKKyAgICAgICAgICAgICAgICBFbnVtV2l0aElubmVyQ2xhc3MuYiwgRW51bVdpdGhJbm5lckNsYXNzLmMsCisgICAgICAgICAgICAgICAgRW51bVdpdGhJbm5lckNsYXNzLmQsIEVudW1XaXRoSW5uZXJDbGFzcy5lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIG9mIGVudW1TZXQgc2hvdWxkIGJlIDU6IiwgNSwgZW51bVNldC5zaXplKCkpOworCisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCByZXR1cm4gdHJ1ZSIsIGVudW1TZXQuY29udGFpbnMoRW51bVdpdGhJbm5lckNsYXNzLmEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiB0cnVlIiwgZW51bVNldC5jb250YWlucyhFbnVtV2l0aElubmVyQ2xhc3MuZSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0Lm9mKChFbnVtV2l0aElubmVyQ2xhc3MpIG51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRlc3QgZW51bSB3aXRoIG1vcmUgdGhhbiA2NCBlbGVtZW50cworICAgICAgICBFbnVtU2V0PEh1Z2VFbnVtV2l0aElubmVyQ2xhc3M+IGh1Z2VFbnVtU2V0ID0gRW51bVNldC5vZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmEsCisgICAgICAgICAgICAgICAgSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5iLCBIdWdlRW51bVdpdGhJbm5lckNsYXNzLmMsCisgICAgICAgICAgICAgICAgSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5kLCBIdWdlRW51bVdpdGhJbm5lckNsYXNzLmUpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgaHVnZUVudW1TZXQuc2l6ZSgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKGh1Z2VFbnVtU2V0LmNvbnRhaW5zKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYSkpOworICAgICAgICBhc3NlcnRUcnVlKGh1Z2VFbnVtU2V0LmNvbnRhaW5zKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuZSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0Lm9mKChIdWdlRW51bVdpdGhJbm5lckNsYXNzKSBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRW51bVNldCNvZihFLCBFLi4uKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfT2ZfRUVBcnJheSgpIHsKKyAgICAgICAgRW51bVdpdGhJbm5lckNsYXNzW10gZW51bUFycmF5ID0gbmV3IEVudW1XaXRoSW5uZXJDbGFzc1tdIHsKKyAgICAgICAgICAgICAgICBFbnVtV2l0aElubmVyQ2xhc3MuYiwgRW51bVdpdGhJbm5lckNsYXNzLmMgfTsKKyAgICAgICAgRW51bVNldDxFbnVtV2l0aElubmVyQ2xhc3M+IGVudW1TZXQgPSBFbnVtU2V0Lm9mKEVudW1XaXRoSW5uZXJDbGFzcy5hLAorICAgICAgICAgICAgICAgIGVudW1BcnJheSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIGJlIGVxdWFsIiwgMywgZW51bVNldC5zaXplKCkpOworCisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCByZXR1cm4gdHJ1ZSIsIGVudW1TZXQuY29udGFpbnMoRW51bVdpdGhJbm5lckNsYXNzLmEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIHJldHVybiB0cnVlIiwgZW51bVNldC5jb250YWlucyhFbnVtV2l0aElubmVyQ2xhc3MuYykpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0Lm9mKEVudW1XaXRoSW5uZXJDbGFzcy5hLCAoRW51bVdpdGhJbm5lckNsYXNzW10pbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgRW51bUZvb1tdIGZvb3MgPSB7RW51bUZvby5hLCBFbnVtRm9vLmMsIEVudW1Gb28uZH07CisgICAgICAgIEVudW1TZXQ8RW51bUZvbz4gc2V0ID0gRW51bVNldC5vZihFbnVtRm9vLmMsIGZvb3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoInNpemUgb2Ygc2V0IHNob3VsZCBiZSAxIiwgMywgc2V0LnNpemUoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBjb250YWluIEVudW1Gb28uYSIsIHNldC5jb250YWlucyhFbnVtRm9vLmEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGNvbnRhaW4gRW51bUZvby5jIiwgc2V0LmNvbnRhaW5zKEVudW1Gb28uYykpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgY29udGFpbiBFbnVtRm9vLmQiLCBzZXQuY29udGFpbnMoRW51bUZvby5kKSk7CisKKyAgICAgICAgLy8gdGVzdCBlbnVtIHR5cGUgd2l0aCBtb3JlIHRoYW4gNjQgZWxlbWVudHMKKyAgICAgICAgSHVnZUVudW1XaXRoSW5uZXJDbGFzc1tdIGh1Z2VFbnVtQXJyYXkgPSBuZXcgSHVnZUVudW1XaXRoSW5uZXJDbGFzc1tdIHsKKyAgICAgICAgICAgICAgICBIdWdlRW51bVdpdGhJbm5lckNsYXNzLmIsIEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYyB9OworICAgICAgICBFbnVtU2V0PEh1Z2VFbnVtV2l0aElubmVyQ2xhc3M+IGh1Z2VFbnVtU2V0ID0gRW51bVNldC5vZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmEsCisgICAgICAgICAgICAgICAgaHVnZUVudW1BcnJheSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBodWdlRW51bVNldC5zaXplKCkpOworCisgICAgICAgIGFzc2VydFRydWUoaHVnZUVudW1TZXQuY29udGFpbnMoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5hKSk7CisgICAgICAgIGFzc2VydFRydWUoaHVnZUVudW1TZXQuY29udGFpbnMoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5jKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVudW1TZXQub2YoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5hLCAoSHVnZUVudW1XaXRoSW5uZXJDbGFzc1tdKW51bGwpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIEh1Z2VFbnVtV2l0aElubmVyQ2xhc3NbXSBodWdlcyA9IHtIdWdlRW51bVdpdGhJbm5lckNsYXNzLmEsIEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYywgSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5kfTsKKyAgICAgICAgRW51bVNldDxIdWdlRW51bVdpdGhJbm5lckNsYXNzPiBodWdlU2V0ID0gRW51bVNldC5vZihIdWdlRW51bVdpdGhJbm5lckNsYXNzLmMsIGh1Z2VzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGh1Z2VTZXQuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShodWdlU2V0LmNvbnRhaW5zKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYSkpOworICAgICAgICBhc3NlcnRUcnVlKGh1Z2VTZXQuY29udGFpbnMoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5jKSk7CisgICAgICAgIGFzc2VydFRydWUoaHVnZVNldC5jb250YWlucyhIdWdlRW51bVdpdGhJbm5lckNsYXNzLmQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuRW51bVNldCNyYW5nZShFLCBFKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfUmFuZ2VfRUUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0LnJhbmdlKEVudW1XaXRoSW5uZXJDbGFzcy5jLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVudW1TZXQucmFuZ2UobnVsbCwgRW51bVdpdGhJbm5lckNsYXNzLmMpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgRW51bVNldC5yYW5nZShudWxsLCAoRW51bVdpdGhJbm5lckNsYXNzKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVudW1TZXQucmFuZ2UoRW51bVdpdGhJbm5lckNsYXNzLmIsIEVudW1XaXRoSW5uZXJDbGFzcy5hKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBFbnVtU2V0PEVudW1XaXRoSW5uZXJDbGFzcz4gZW51bVNldCA9IEVudW1TZXQucmFuZ2UoCisgICAgICAgICAgICAgICAgRW51bVdpdGhJbm5lckNsYXNzLmEsIEVudW1XaXRoSW5uZXJDbGFzcy5hKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIG9mIGVudW1TZXQgc2hvdWxkIGJlIDEiLCAxLCBlbnVtU2V0LnNpemUoKSk7CisKKyAgICAgICAgZW51bVNldCA9IEVudW1TZXQucmFuZ2UoCisgICAgICAgICAgICAgICAgRW51bVdpdGhJbm5lckNsYXNzLmEsIEVudW1XaXRoSW5uZXJDbGFzcy5jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIG9mIGVudW1TZXQgc2hvdWxkIGJlIDMiLCAzLCBlbnVtU2V0LnNpemUoKSk7CisKKyAgICAgICAgLy8gdGVzdCBlbnVtIHdpdGggbW9yZSB0aGFuIDY0IGVsZW1lbnRzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0LnJhbmdlKEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYywgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0LnJhbmdlKG51bGwsIEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYyk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBFbnVtU2V0LnJhbmdlKG51bGwsIChIdWdlRW51bVdpdGhJbm5lckNsYXNzKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEVudW1TZXQucmFuZ2UoSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5iLCBIdWdlRW51bVdpdGhJbm5lckNsYXNzLmEpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIEVudW1TZXQ8SHVnZUVudW1XaXRoSW5uZXJDbGFzcz4gaHVnZUVudW1TZXQgPSBFbnVtU2V0LnJhbmdlKAorICAgICAgICAgICAgICAgIEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYSwgSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5hKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGh1Z2VFbnVtU2V0LnNpemUoKSk7CisKKyAgICAgICAgaHVnZUVudW1TZXQgPSBFbnVtU2V0LnJhbmdlKAorICAgICAgICAgICAgICAgIEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MuYywgSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5hYSk7CisgICAgICAgIGFzc2VydEVxdWFscyg1MSwgaHVnZUVudW1TZXQuc2l6ZSgpKTsKKworICAgICAgICBodWdlRW51bVNldCA9IEVudW1TZXQucmFuZ2UoCisgICAgICAgICAgICAgICAgSHVnZUVudW1XaXRoSW5uZXJDbGFzcy5hLCBIdWdlRW51bVdpdGhJbm5lckNsYXNzLm1tKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDY1LCBodWdlRW51bVNldC5zaXplKCkpOworCisgICAgICAgIGh1Z2VFbnVtU2V0ID0gRW51bVNldC5yYW5nZSgKKyAgICAgICAgICAgICAgICBIdWdlRW51bVdpdGhJbm5lckNsYXNzLmIsIEh1Z2VFbnVtV2l0aElubmVyQ2xhc3MubW0pOworICAgICAgICBhc3NlcnRFcXVhbHMoNjQsIGh1Z2VFbnVtU2V0LnNpemUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkVudW1TZXQjY2xvbmUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ2xvbmUoKSB7CisgICAgICAgIEVudW1TZXQ8RW51bUZvbz4gZW51bVNldCA9IEVudW1TZXQuYWxsT2YoRW51bUZvby5jbGFzcyk7CisgICAgICAgIEVudW1TZXQ8RW51bUZvbz4gY2xvbmVkRW51bVNldCA9IGVudW1TZXQuY2xvbmUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGVudW1TZXQsIGNsb25lZEVudW1TZXQpOworICAgICAgICBhc3NlcnROb3RTYW1lKGVudW1TZXQsIGNsb25lZEVudW1TZXQpOworICAgICAgICBhc3NlcnRUcnVlKGNsb25lZEVudW1TZXQuY29udGFpbnMoRW51bUZvby5hKSk7CisgICAgICAgIGFzc2VydFRydWUoY2xvbmVkRW51bVNldC5jb250YWlucyhFbnVtRm9vLmIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDY0LCBjbG9uZWRFbnVtU2V0LnNpemUoKSk7CisKKyAgICAgICAgLy8gdGVzdCBlbnVtIHR5cGUgd2l0aCBtb3JlIHRoYW4gNjQgZWxlbWVudHMKKyAgICAgICAgRW51bVNldDxIdWdlRW51bT4gaHVnZUVudW1TZXQgPSBFbnVtU2V0LmFsbE9mKEh1Z2VFbnVtLmNsYXNzKTsKKyAgICAgICAgRW51bVNldDxIdWdlRW51bT4gaHVnZUNsb25lZEVudW1TZXQgPSBodWdlRW51bVNldC5jbG9uZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoaHVnZUVudW1TZXQsIGh1Z2VDbG9uZWRFbnVtU2V0KTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShodWdlRW51bVNldCwgaHVnZUNsb25lZEVudW1TZXQpOworICAgICAgICBhc3NlcnRUcnVlKGh1Z2VDbG9uZWRFbnVtU2V0LmNvbnRhaW5zKEh1Z2VFbnVtLmEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShodWdlQ2xvbmVkRW51bVNldC5jb250YWlucyhIdWdlRW51bS5iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg2NSwgaHVnZUNsb25lZEVudW1TZXQuc2l6ZSgpKTsKKworICAgICAgICBodWdlQ2xvbmVkRW51bVNldC5yZW1vdmUoSHVnZUVudW0uYSk7CisgICAgICAgIGFzc2VydEVxdWFscyg2NCwgaHVnZUNsb25lZEVudW1TZXQuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoaHVnZUNsb25lZEVudW1TZXQuY29udGFpbnMoSHVnZUVudW0uYSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNjUsIGh1Z2VFbnVtU2V0LnNpemUoKSk7CisgICAgICAgIGFzc2VydFRydWUoaHVnZUVudW1TZXQuY29udGFpbnMoSHVnZUVudW0uYSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5FbnVtU2V0I1NlcmlhbGl6YXRpb24oKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2VyaWFsaXphdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBFbnVtU2V0PEVudW1Gb28+IHNldCA9IEVudW1TZXQuYWxsT2YoRW51bUZvby5jbGFzcyk7CisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0LnZlcmlmeVNlbGYoc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBzZXJpYWxpemF0aW9uL2Rlc2VyaWFsaXphdGlvbiBjb21wYXRpYmlsaXR5IHdpdGggUkkuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoIHsgInVuY2hlY2tlZCIsICJib3hpbmciIH0pCisgICAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6YXRpb25Db21wYXRpYmlsaXR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEVudW1TZXQ8RW51bUZvbz4gc2V0ID0gRW51bVNldC5hbGxPZihFbnVtRm9vLmNsYXNzKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3QudmVyaWZ5R29sZGVuKHRoaXMsIHNldCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvRm9ybWF0dGFibGVGbGFnc1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0Zvcm1hdHRhYmxlRmxhZ3NUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmFhNDk1NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0Zvcm1hdHRhYmxlRmxhZ3NUZXN0LmphdmEKQEAgLTAsMCArMSwzMSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5Gb3JtYXR0YWJsZUZsYWdzOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIEZvcm1hdHRhYmxlRmxhZ3NUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogQHRlc3QgamF2YS51dGlsLkZvcm1hdHRhYmxlRmxhZ3MgQ29uc3RhbnRGaWVsZFZhbHVlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RhbnRGaWVsZFZhbHVlcygpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIEZvcm1hdHRhYmxlRmxhZ3MuTEVGVF9KVVNUSUZZKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIEZvcm1hdHRhYmxlRmxhZ3MuVVBQRVJDQVNFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIEZvcm1hdHRhYmxlRmxhZ3MuQUxURVJOQVRFKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9IYXNoTWFwVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvSGFzaE1hcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMzdlODEzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvSGFzaE1hcFRlc3QuamF2YQpAQCAtMCwwICsxLDU1OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLio7CisKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfTWFwVGVzdDI7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1VubW9kaWZpYWJsZUNvbGxlY3Rpb25UZXN0OworCitwdWJsaWMgY2xhc3MgSGFzaE1hcFRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIGNsYXNzIE1vY2tNYXAgZXh0ZW5kcyBBYnN0cmFjdE1hcCB7CisgICAgICAgIHB1YmxpYyBTZXQgZW50cnlTZXQoKSB7CisgICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuRU1QVFlfU0VUOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBNb2NrTWFwTnVsbCBleHRlbmRzIEFic3RyYWN0TWFwIHsKKyAgICAgICAgcHVibGljIFNldCBlbnRyeVNldCgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICAgICAgcmV0dXJuIDEwOworICAgICAgICB9CisgICAgfQorCisgICAgSGFzaE1hcCBobTsKKworICAgIGZpbmFsIHN0YXRpYyBpbnQgaG1TaXplID0gMTAwMDsKKworICAgIE9iamVjdFtdIG9iakFycmF5OworCisgICAgT2JqZWN0W10gb2JqQXJyYXkyOworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2hNYXAjSGFzaE1hcCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5IYXNoTWFwKCkKKyAgICAgICAgbmV3IFN1cHBvcnRfTWFwVGVzdDIobmV3IEhhc2hNYXAoKSkucnVuVGVzdCgpOworCisgICAgICAgIEhhc2hNYXAgaG0yID0gbmV3IEhhc2hNYXAoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDcmVhdGVkIGluY29ycmVjdCBIYXNoTWFwIiwgMCwgaG0yLnNpemUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2hNYXAjSGFzaE1hcChpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuSGFzaE1hcChpbnQpCisgICAgICAgIEhhc2hNYXAgaG0yID0gbmV3IEhhc2hNYXAoNSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQ3JlYXRlZCBpbmNvcnJlY3QgSGFzaE1hcCIsIDAsIGhtMi5zaXplKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEhhc2hNYXAoLTEpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBIYXNoTWFwIGVtcHR5ID0gbmV3IEhhc2hNYXAoMCk7CisgICAgICAgIGFzc2VydE51bGwoIkVtcHR5IGhhc2htYXAgYWNjZXNzIiwgZW1wdHkuZ2V0KCJub3RoaW5nIikpOworICAgICAgICBlbXB0eS5wdXQoInNvbWV0aGluZyIsICJoZXJlIik7CisgICAgICAgIGFzc2VydFRydWUoImNhbm5vdCBnZXQgZWxlbWVudCIsIGVtcHR5LmdldCgic29tZXRoaW5nIikgPT0gImhlcmUiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaE1hcCNIYXNoTWFwKGludCwgZmxvYXQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcklGKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLkhhc2hNYXAoaW50LCBmbG9hdCkKKyAgICAgICAgSGFzaE1hcCBobTIgPSBuZXcgSGFzaE1hcCg1LCAoZmxvYXQpIDAuNSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQ3JlYXRlZCBpbmNvcnJlY3QgSGFzaE1hcCIsIDAsIGhtMi5zaXplKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEhhc2hNYXAoMCwgMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIEhhc2hNYXAgZW1wdHkgPSBuZXcgSGFzaE1hcCgwLCAwLjc1Zik7CisgICAgICAgIGFzc2VydE51bGwoIkVtcHR5IGhhc2h0YWJsZSBhY2Nlc3MiLCBlbXB0eS5nZXQoIm5vdGhpbmciKSk7CisgICAgICAgIGVtcHR5LnB1dCgic29tZXRoaW5nIiwgImhlcmUiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiY2Fubm90IGdldCBlbGVtZW50IiwgZW1wdHkuZ2V0KCJzb21ldGhpbmciKSA9PSAiaGVyZSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNoTWFwI0hhc2hNYXAoamF2YS51dGlsLk1hcCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfdXRpbF9NYXAoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuSGFzaE1hcChqYXZhLnV0aWwuTWFwKQorICAgICAgICBNYXAgbXlNYXAgPSBuZXcgVHJlZU1hcCgpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGhtU2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgbXlNYXAucHV0KG9iakFycmF5Mltjb3VudGVyXSwgb2JqQXJyYXlbY291bnRlcl0pOworICAgICAgICBIYXNoTWFwIGhtMiA9IG5ldyBIYXNoTWFwKG15TWFwKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBobVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBjb25zdHJ1Y3QgY29ycmVjdCBIYXNoTWFwIiwgaG0KKyAgICAgICAgICAgICAgICAgICAgLmdldChvYmpBcnJheTJbY291bnRlcl0pID09IGhtMi5nZXQob2JqQXJyYXkyW2NvdW50ZXJdKSk7CisKKyAgICAgICAgTWFwIG1vY2tNYXAgPSBuZXcgTW9ja01hcCgpOworICAgICAgICBobSA9IG5ldyBIYXNoTWFwKG1vY2tNYXApOworICAgICAgICBhc3NlcnRFcXVhbHMoaG0sIG1vY2tNYXApOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNoTWFwI2NsZWFyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NsZWFyKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuSGFzaE1hcC5jbGVhcigpCisgICAgICAgIGhtLmNsZWFyKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQ2xlYXIgZmFpbGVkIHRvIHJlc2V0IHNpemUiLCAwLCBobS5zaXplKCkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGhtU2l6ZTsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIGNsZWFyIGFsbCBlbGVtZW50cyIsCisgICAgICAgICAgICAgICAgICAgIGhtLmdldChvYmpBcnJheTJbaV0pKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNoTWFwI2Nsb25lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb25lKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdCBqYXZhLnV0aWwuSGFzaE1hcC5jbG9uZSgpCisgICAgICAgIEhhc2hNYXAgaG0yID0gKEhhc2hNYXApIGhtLmNsb25lKCk7CisgICAgICAgIGFzc2VydFRydWUoIkNsb25lIGFuc3dlcmVkIGVxdWl2YWxlbnQgSGFzaE1hcCIsIGhtMiAhPSBobSk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgaG1TaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJDbG9uZSBhbnN3ZXJlZCB1bmVxdWFsIEhhc2hNYXAiLCBobQorICAgICAgICAgICAgICAgICAgICAuZ2V0KG9iakFycmF5Mltjb3VudGVyXSkgPT0gaG0yLmdldChvYmpBcnJheTJbY291bnRlcl0pKTsKKworICAgICAgICBIYXNoTWFwIG1hcCA9IG5ldyBIYXNoTWFwKCk7CisgICAgICAgIG1hcC5wdXQoImtleSIsICJ2YWx1ZSIpOworICAgICAgICAvLyBnZXQgdGhlIGtleVNldCgpIGFuZCB2YWx1ZXMoKSBvbiB0aGUgb3JpZ2luYWwgTWFwCisgICAgICAgIFNldCBrZXlzID0gbWFwLmtleVNldCgpOworICAgICAgICBDb2xsZWN0aW9uIHZhbHVlcyA9IG1hcC52YWx1ZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZXMoKSBkb2VzIG5vdCB3b3JrIiwKKyAgICAgICAgICAgICAgICAidmFsdWUiLCB2YWx1ZXMuaXRlcmF0b3IoKS5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImtleVNldCgpIGRvZXMgbm90IHdvcmsiLAorICAgICAgICAgICAgICAgICJrZXkiLCBrZXlzLml0ZXJhdG9yKCkubmV4dCgpKTsKKyAgICAgICAgQWJzdHJhY3RNYXAgbWFwMiA9IChBYnN0cmFjdE1hcCkgbWFwLmNsb25lKCk7CisgICAgICAgIG1hcDIucHV0KCJrZXkiLCAidmFsdWUyIik7CisgICAgICAgIENvbGxlY3Rpb24gdmFsdWVzMiA9IG1hcDIudmFsdWVzKCk7CisgICAgICAgIGFzc2VydFRydWUoInZhbHVlcygpIGlzIGlkZW50aWNhbCIsIHZhbHVlczIgIT0gdmFsdWVzKTsKKyAgICAgICAgLy8gdmFsdWVzKCkgYW5kIGtleVNldCgpIG9uIHRoZSBjbG9uZWQoKSBtYXAgc2hvdWxkIGJlIGRpZmZlcmVudAorICAgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlcygpIHdhcyBub3QgY2xvbmVkIiwKKyAgICAgICAgICAgICAgICAidmFsdWUyIiwgdmFsdWVzMi5pdGVyYXRvcigpLm5leHQoKSk7CisgICAgICAgIG1hcDIuY2xlYXIoKTsKKyAgICAgICAgbWFwMi5wdXQoImtleTIiLCAidmFsdWUzIik7CisgICAgICAgIFNldCBrZXkyID0gbWFwMi5rZXlTZXQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgia2V5U2V0KCkgaXMgaWRlbnRpY2FsIiwga2V5MiAhPSBrZXlzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJrZXlTZXQoKSB3YXMgbm90IGNsb25lZCIsCisgICAgICAgICAgICAgICAgImtleTIiLCBrZXkyLml0ZXJhdG9yKCkubmV4dCgpKTsKKworICAgICAgICAvLyByZWdyZXNpb24gdGVzdCBmb3IgSEFSTU9OWS00NjAzCisgICAgICAgIEhhc2hNYXAgaGFzaG1hcCA9IG5ldyBIYXNoTWFwKCk7CisgICAgICAgIE1vY2tDbG9uYWJsZSBtb2NrID0gbmV3IE1vY2tDbG9uYWJsZSgxKTsKKyAgICAgICAgaGFzaG1hcC5wdXQoMSwgbW9jayk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCAoKE1vY2tDbG9uYWJsZSkgaGFzaG1hcC5nZXQoMSkpLmkpOworICAgICAgICBIYXNoTWFwIGhtMyA9IChIYXNoTWFwKWhhc2htYXAuY2xvbmUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsICgoTW9ja0Nsb25hYmxlKSBobTMuZ2V0KDEpKS5pKTsKKyAgICAgICAgbW9jay5pID0gMDsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsICgoTW9ja0Nsb25hYmxlKSBoYXNobWFwLmdldCgxKSkuaSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCAoKE1vY2tDbG9uYWJsZSkgaG0zLmdldCgxKSkuaSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2hNYXAjY29udGFpbnNLZXkoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbnRhaW5zS2V5TGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuCisgICAgICAgIC8vIGphdmEudXRpbC5IYXNoTWFwLmNvbnRhaW5zS2V5KGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciB2YWxpZCBrZXkiLCBobS5jb250YWluc0tleShuZXcgSW50ZWdlcigKKyAgICAgICAgICAgICAgICA4NzYpLnRvU3RyaW5nKCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgaW52YWxpZCBrZXkiLCAhaG0uY29udGFpbnNLZXkoIktLREtES0QiKSk7CisKKyAgICAgICAgSGFzaE1hcCBtID0gbmV3IEhhc2hNYXAoKTsKKyAgICAgICAgbS5wdXQobnVsbCwgInRlc3QiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHdpdGggbnVsbCBrZXkiLCBtLmNvbnRhaW5zS2V5KG51bGwpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHdpdGggbWlzc2luZyBrZXkgbWF0Y2hpbmcgbnVsbCBoYXNoIiwgIW0KKyAgICAgICAgICAgICAgICAuY29udGFpbnNLZXkobmV3IEludGVnZXIoMCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaE1hcCNjb250YWluc1ZhbHVlKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jb250YWluc1ZhbHVlTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuCisgICAgICAgIC8vIGphdmEudXRpbC5IYXNoTWFwLmNvbnRhaW5zVmFsdWUoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIHZhbGlkIHZhbHVlIiwgaG0KKyAgICAgICAgICAgICAgICAuY29udGFpbnNWYWx1ZShuZXcgSW50ZWdlcig4NzUpKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHRydWUgZm9yIGludmFsaWQgdmFsaWUiLCAhaG0KKyAgICAgICAgICAgICAgICAuY29udGFpbnNWYWx1ZShuZXcgSW50ZWdlcigtOSkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaE1hcCNlbnRyeVNldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9lbnRyeVNldCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5TZXQgamF2YS51dGlsLkhhc2hNYXAuZW50cnlTZXQoKQorICAgICAgICBTZXQgcyA9IGhtLmVudHJ5U2V0KCk7CisgICAgICAgIEl0ZXJhdG9yIGkgPSBzLml0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHNldCBvZiBpbmNvcnJlY3Qgc2l6ZSIsIGhtLnNpemUoKSA9PSBzLnNpemUoKSk7CisgICAgICAgIHdoaWxlIChpLmhhc05leHQoKSkgeworICAgICAgICAgICAgTWFwLkVudHJ5IG0gPSAoTWFwLkVudHJ5KSBpLm5leHQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBlbnRyeSBzZXQiLCBobS5jb250YWluc0tleShtCisgICAgICAgICAgICAgICAgICAgIC5nZXRLZXkoKSkKKyAgICAgICAgICAgICAgICAgICAgJiYgaG0uY29udGFpbnNWYWx1ZShtLmdldFZhbHVlKCkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNoTWFwI2VudHJ5U2V0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VudHJ5U2V0RXF1YWxzKCkgeworICAgICAgICBTZXQgczEgPSBobS5lbnRyeVNldCgpOworICAgICAgICBTZXQgczIgPSBuZXcgSGFzaE1hcChobSkuZW50cnlTZXQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHMxLCBzMik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2hNYXAjZW50cnlTZXQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlRnJvbVZpZXdzKCkgeworICAgICAgICBobS5wdXQoIkEiLCBudWxsKTsKKyAgICAgICAgaG0ucHV0KCJCIiwgbnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoaG0ua2V5U2V0KCkucmVtb3ZlKCJBIikpOworCisgICAgICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gbTIgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgbTIucHV0KCJCIiwgbnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoaG0uZW50cnlTZXQoKS5yZW1vdmUobTIuZW50cnlTZXQoKS5pdGVyYXRvcigpLm5leHQoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNoTWFwI2dldChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0CisgICAgICAgIC8vIGphdmEudXRpbC5IYXNoTWFwLmdldChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBhc3NlcnROdWxsKCJHZXQgcmV0dXJuZWQgbm9uLW51bGwgZm9yIG5vbiBleGlzdGVudCBrZXkiLAorICAgICAgICAgICAgICAgIGhtLmdldCgiVCIpKTsKKyAgICAgICAgaG0ucHV0KCJUIiwgIkhFTExPIik7CisgICAgICAgIGFzc2VydEVxdWFscygiR2V0IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSBmb3IgZXhpc3Rpbmcga2V5IiwgIkhFTExPIiwgaG0uZ2V0KCJUIikKKyAgICAgICAgICAgICAgICApOworCisgICAgICAgIEhhc2hNYXAgbSA9IG5ldyBIYXNoTWFwKCk7CisgICAgICAgIG0ucHV0KG51bGwsICJ0ZXN0Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHdpdGggbnVsbCBrZXkiLCAidGVzdCIsIG0uZ2V0KG51bGwpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiRmFpbGVkIHdpdGggbWlzc2luZyBrZXkgbWF0Y2hpbmcgbnVsbCBoYXNoIiwgbQorICAgICAgICAgICAgICAgIC5nZXQobmV3IEludGVnZXIoMCkpKTsKKworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTIwNgorICAgICAgICBSZXVzYWJsZUtleSBrID0gbmV3IFJldXNhYmxlS2V5KCk7CisgICAgICAgIEhhc2hNYXAgbWFwID0gbmV3IEhhc2hNYXAoKTsKKyAgICAgICAgay5zZXRLZXkoMSk7CisgICAgICAgIG1hcC5wdXQoaywgInZhbHVlMSIpOworCisgICAgICAgIGsuc2V0S2V5KDE4KTsKKyAgICAgICAgYXNzZXJ0TnVsbChtYXAuZ2V0KGspKTsKKworICAgICAgICBrLnNldEtleSgxNyk7CisgICAgICAgIGFzc2VydE51bGwobWFwLmdldChrKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2hNYXAjaXNFbXB0eSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0VtcHR5KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuSGFzaE1hcC5pc0VtcHR5KCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIG5ldyBtYXAiLCBuZXcgSGFzaE1hcCgpLmlzRW1wdHkoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHRydWUgZm9yIG5vbi1lbXB0eSIsICFobS5pc0VtcHR5KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNoTWFwI2tleVNldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9rZXlTZXQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuU2V0IGphdmEudXRpbC5IYXNoTWFwLmtleVNldCgpCisgICAgICAgIFNldCBzID0gaG0ua2V5U2V0KCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHNldCBvZiBpbmNvcnJlY3Qgc2l6ZSgpIiwgcy5zaXplKCkgPT0gaG0uc2l6ZSgpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvYmpBcnJheS5sZW5ndGg7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHNldCBkb2VzIG5vdCBjb250YWluIGFsbCBrZXlzIiwgcworICAgICAgICAgICAgICAgICAgICAuY29udGFpbnMob2JqQXJyYXlbaV0udG9TdHJpbmcoKSkpOworCisgICAgICAgIEhhc2hNYXAgbSA9IG5ldyBIYXNoTWFwKCk7CisgICAgICAgIG0ucHV0KG51bGwsICJ0ZXN0Iik7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB3aXRoIG51bGwga2V5IiwgbS5rZXlTZXQoKS5jb250YWlucyhudWxsKSk7CisgICAgICAgIGFzc2VydE51bGwoIkZhaWxlZCB3aXRoIG51bGwga2V5IiwgbS5rZXlTZXQoKS5pdGVyYXRvcigpLm5leHQoKSk7CisKKyAgICAgICAgTWFwIG1hcCA9IG5ldyBIYXNoTWFwKDEwMSk7CisgICAgICAgIG1hcC5wdXQobmV3IEludGVnZXIoMSksICIxIik7CisgICAgICAgIG1hcC5wdXQobmV3IEludGVnZXIoMTAyKSwgIjEwMiIpOworICAgICAgICBtYXAucHV0KG5ldyBJbnRlZ2VyKDIwMyksICIyMDMiKTsKKyAgICAgICAgSXRlcmF0b3IgaXQgPSBtYXAua2V5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgICAgSW50ZWdlciByZW1vdmUxID0gKEludGVnZXIpIGl0Lm5leHQoKTsKKyAgICAgICAgaXQuaGFzTmV4dCgpOworICAgICAgICBpdC5yZW1vdmUoKTsKKyAgICAgICAgSW50ZWdlciByZW1vdmUyID0gKEludGVnZXIpIGl0Lm5leHQoKTsKKyAgICAgICAgaXQucmVtb3ZlKCk7CisgICAgICAgIEFycmF5TGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdChBcnJheXMuYXNMaXN0KG5ldyBJbnRlZ2VyW10geworICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKDEpLCBuZXcgSW50ZWdlcigxMDIpLCBuZXcgSW50ZWdlcigyMDMpIH0pKTsKKyAgICAgICAgbGlzdC5yZW1vdmUocmVtb3ZlMSk7CisgICAgICAgIGxpc3QucmVtb3ZlKHJlbW92ZTIpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyByZXN1bHQiLCBpdC5uZXh0KCkuZXF1YWxzKGxpc3QuZ2V0KDApKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDEsIG1hcC5zaXplKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBjb250ZW50cyIsIG1hcC5rZXlTZXQoKS5pdGVyYXRvcigpLm5leHQoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgbGlzdC5nZXQoMCkpKTsKKworICAgICAgICBNYXAgbWFwMiA9IG5ldyBIYXNoTWFwKDEwMSk7CisgICAgICAgIG1hcDIucHV0KG5ldyBJbnRlZ2VyKDEpLCAiMSIpOworICAgICAgICBtYXAyLnB1dChuZXcgSW50ZWdlcig0KSwgIjQiKTsKKyAgICAgICAgSXRlcmF0b3IgaXQyID0gbWFwMi5rZXlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICBJbnRlZ2VyIHJlbW92ZTMgPSAoSW50ZWdlcikgaXQyLm5leHQoKTsKKyAgICAgICAgSW50ZWdlciBuZXh0OworICAgICAgICBpZiAocmVtb3ZlMy5pbnRWYWx1ZSgpID09IDEpCisgICAgICAgICAgICBuZXh0ID0gbmV3IEludGVnZXIoNCk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIG5leHQgPSBuZXcgSW50ZWdlcigxKTsKKyAgICAgICAgaXQyLmhhc05leHQoKTsKKyAgICAgICAgaXQyLnJlbW92ZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyByZXN1bHQgMiIsIGl0Mi5uZXh0KCkuZXF1YWxzKG5leHQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzaXplIDIiLCAxLCBtYXAyLnNpemUoKSk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIGNvbnRlbnRzIDIiLCBtYXAyLmtleVNldCgpLml0ZXJhdG9yKCkubmV4dCgpLmVxdWFscygKKyAgICAgICAgICAgICAgICBuZXh0KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2hNYXAjcHV0KGphdmEubGFuZy5PYmplY3QsIGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wdXRMamF2YV9sYW5nX09iamVjdExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdAorICAgICAgICAvLyBqYXZhLnV0aWwuSGFzaE1hcC5wdXQoamF2YS5sYW5nLk9iamVjdCwgamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgaG0ucHV0KCJLRVkiLCAiVkFMVUUiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gaW5zdGFsbCBrZXkvdmFsdWUgcGFpciIsCisgICAgICAgICAgICAgICAgIlZBTFVFIiwgaG0uZ2V0KCJLRVkiKSk7CisKKyAgICAgICAgSGFzaE1hcCBtID0gbmV3IEhhc2hNYXAoKTsKKyAgICAgICAgbS5wdXQobmV3IFNob3J0KChzaG9ydCkgMCksICJzaG9ydCIpOworICAgICAgICBtLnB1dChudWxsLCAidGVzdCIpOworICAgICAgICBtLnB1dChuZXcgSW50ZWdlcigwKSwgImludCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCBhZGRpbmcgdG8gYnVja2V0IGNvbnRhaW5pbmcgbnVsbCIsICJzaG9ydCIsIG0uZ2V0KAorICAgICAgICAgICAgICAgIG5ldyBTaG9ydCgoc2hvcnQpIDApKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIGFkZGluZyB0byBidWNrZXQgY29udGFpbmluZyBudWxsMiIsICJpbnQiLCBtLmdldCgKKyAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcigwKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNoTWFwI3B1dEFsbChqYXZhLnV0aWwuTWFwKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcHV0QWxsTGphdmFfdXRpbF9NYXAoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5IYXNoTWFwLnB1dEFsbChqYXZhLnV0aWwuTWFwKQorICAgICAgICBIYXNoTWFwIGhtMiA9IG5ldyBIYXNoTWFwKCk7CisgICAgICAgIGhtMi5wdXRBbGwoaG0pOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDA7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBjbGVhciBhbGwgZWxlbWVudHMiLCBobTIuZ2V0KAorICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihpKS50b1N0cmluZygpKS5lcXVhbHMoKG5ldyBJbnRlZ2VyKGkpKSkpOworCisgICAgICAgIE1hcCBtb2NrTWFwID0gbmV3IE1vY2tNYXAoKTsKKyAgICAgICAgaG0yID0gbmV3IEhhc2hNYXAoKTsKKyAgICAgICAgaG0yLnB1dEFsbChtb2NrTWFwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIHNob3VsZCBiZSAwIiwgMCwgaG0yLnNpemUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2hNYXAjcHV0QWxsKGphdmEudXRpbC5NYXApCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wdXRBbGxMamF2YV91dGlsX01hcF9OdWxsKCkgeworICAgICAgICBIYXNoTWFwIGhhc2hNYXAgPSBuZXcgSGFzaE1hcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaGFzaE1hcC5wdXRBbGwobmV3IE1vY2tNYXBOdWxsKCkpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkLgorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGhhc2hNYXAgPSBuZXcgSGFzaE1hcChuZXcgTW9ja01hcE51bGwoKSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3B1dEFsbExqYXZhX3V0aWxfTWFwX1Jlc2l6ZSgpIHsKKyAgICAgICAgUmFuZG9tIHJuZCA9IG5ldyBSYW5kb20oNjY2KTsKKworICAgICAgICBNYXA8SW50ZWdlcixJbnRlZ2VyPiBtMSA9IG5ldyBIYXNoTWFwPEludGVnZXIsIEludGVnZXI+KCk7CisgICAgICAgIGludCBNSUQgPSAxMDAwMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBNSUQ7IGkrKykgeworICAgICAgICAgICAgSW50ZWdlciBqID0gcm5kLm5leHRJbnQoKTsKKyAgICAgICAgICAgIG0xLnB1dChqLCBqKTsKKyAgICAgICAgfQorCisgICAgICAgIE1hcDxJbnRlZ2VyLEludGVnZXI+IG0yID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgSW50ZWdlcj4oKTsKKyAgICAgICAgaW50IEhJID0gMzAwMDA7CisgICAgICAgIGZvciAoaW50IGkgPSBNSUQ7IGkgPCBISTsgaSsrKSB7CisgICAgICAgICAgICBJbnRlZ2VyIGogPSBybmQubmV4dEludCgpOworICAgICAgICAgICAgbTIucHV0KGosIGopOworICAgICAgICB9CisKKyAgICAgICAgbTEucHV0QWxsKG0yKTsKKworICAgICAgICBybmQgPSBuZXcgUmFuZG9tKDY2Nik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgSEk7IGkrKykgeworICAgICAgICAgICAgSW50ZWdlciBqID0gcm5kLm5leHRJbnQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhqLCBtMS5nZXQoaikpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2hNYXAjcmVtb3ZlKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZW1vdmVMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QKKyAgICAgICAgLy8gamF2YS51dGlsLkhhc2hNYXAucmVtb3ZlKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIGludCBzaXplID0gaG0uc2l6ZSgpOworICAgICAgICBJbnRlZ2VyIHkgPSBuZXcgSW50ZWdlcig5KTsKKyAgICAgICAgSW50ZWdlciB4ID0gKChJbnRlZ2VyKSBobS5yZW1vdmUoeS50b1N0cmluZygpKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJlbW92ZSByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCB4LmVxdWFscyhuZXcgSW50ZWdlcig5KSkpOworICAgICAgICBhc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVtb3ZlIGdpdmVuIGtleSIsIGhtLmdldChuZXcgSW50ZWdlcig5KSkpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZGVjcmVtZW50IHNpemUiLCBobS5zaXplKCkgPT0gKHNpemUgLSAxKSk7CisgICAgICAgIGFzc2VydE51bGwoIlJlbW92ZSBvZiBub24tZXhpc3RlbnQga2V5IHJldHVybmVkIG5vbi1udWxsIiwgaG0KKyAgICAgICAgICAgICAgICAucmVtb3ZlKCJMQ0xDTEMiKSk7CisKKyAgICAgICAgSGFzaE1hcCBtID0gbmV3IEhhc2hNYXAoKTsKKyAgICAgICAgbS5wdXQobnVsbCwgInRlc3QiKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiRmFpbGVkIHdpdGggc2FtZSBoYXNoIGFzIG51bGwiLAorICAgICAgICAgICAgICAgIG0ucmVtb3ZlKG5ldyBJbnRlZ2VyKDApKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHdpdGggbnVsbCBrZXkiLCAidGVzdCIsIG0ucmVtb3ZlKG51bGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaE1hcCNzaXplKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NpemUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLkhhc2hNYXAuc2l6ZSgpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBzaXplIiwKKyAgICAgICAgICAgICAgICBobS5zaXplKCkgPT0gKG9iakFycmF5Lmxlbmd0aCArIDIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaE1hcCN2YWx1ZXMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdmFsdWVzKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLkNvbGxlY3Rpb24gamF2YS51dGlsLkhhc2hNYXAudmFsdWVzKCkKKyAgICAgICAgQ29sbGVjdGlvbiBjID0gaG0udmFsdWVzKCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGNvbGxlY3Rpb24gb2YgaW5jb3JyZWN0IHNpemUoKSIsIGMuc2l6ZSgpID09IGhtCisgICAgICAgICAgICAgICAgLnNpemUoKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2JqQXJyYXkubGVuZ3RoOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBjb2xsZWN0aW9uIGRvZXMgbm90IGNvbnRhaW4gYWxsIGtleXMiLCBjCisgICAgICAgICAgICAgICAgICAgIC5jb250YWlucyhvYmpBcnJheVtpXSkpOworCisgICAgICAgIEhhc2hNYXAgbXlIYXNoTWFwID0gbmV3IEhhc2hNYXAoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykKKyAgICAgICAgICAgIG15SGFzaE1hcC5wdXQob2JqQXJyYXkyW2ldLCBvYmpBcnJheVtpXSk7CisgICAgICAgIENvbGxlY3Rpb24gdmFsdWVzID0gbXlIYXNoTWFwLnZhbHVlcygpOworICAgICAgICBuZXcgU3VwcG9ydF9Vbm1vZGlmaWFibGVDb2xsZWN0aW9uVGVzdCgKKyAgICAgICAgICAgICAgICAiVGVzdCBSZXR1cm5lZCBDb2xsZWN0aW9uIEZyb20gSGFzaE1hcC52YWx1ZXMoKSIsIHZhbHVlcykKKyAgICAgICAgICAgICAgICAucnVuVGVzdCgpOworICAgICAgICB2YWx1ZXMucmVtb3ZlKG5ldyBJbnRlZ2VyKDApKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiUmVtb3ZpbmcgZnJvbSB0aGUgdmFsdWVzIGNvbGxlY3Rpb24gc2hvdWxkIHJlbW92ZSBmcm9tIHRoZSBvcmlnaW5hbCBtYXAiLAorICAgICAgICAgICAgICAgICFteUhhc2hNYXAuY29udGFpbnNWYWx1ZShuZXcgSW50ZWdlcigwKSkpOworCisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFJldXNhYmxlS2V5IHsKKyAgICAgICAgcHJpdmF0ZSBpbnQga2V5ID0gMDsKKworICAgICAgICBwdWJsaWMgdm9pZCBzZXRLZXkoaW50IGtleSkgeworICAgICAgICAgICAgdGhpcy5rZXkgPSBrZXk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgcmV0dXJuIGtleTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICAgICAgaWYgKG8gPT0gdGhpcykgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCEobyBpbnN0YW5jZW9mIFJldXNhYmxlS2V5KSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBrZXkgPT0gKChSZXVzYWJsZUtleSkgbykua2V5OworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RfTWFwX0VudHJ5X2hhc2hDb2RlKCkgeworICAgICAgICAvL1JlbGF0ZWQgdG8gSEFSTU9OWS00MDMKKyAgICAgICAgSGFzaE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBtYXAgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPigxMCk7CisgICAgICAgIEludGVnZXIga2V5ID0gbmV3IEludGVnZXIoMSk7CisgICAgICAgIEludGVnZXIgdmFsID0gbmV3IEludGVnZXIoMik7CisgICAgICAgIG1hcC5wdXQoa2V5LCB2YWwpOworICAgICAgICBpbnQgZXhwZWN0ZWQgPSBrZXkuaGFzaENvZGUoKSBeIHZhbC5oYXNoQ29kZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIG1hcC5oYXNoQ29kZSgpKTsKKyAgICAgICAga2V5ID0gbmV3IEludGVnZXIoNCk7CisgICAgICAgIHZhbCA9IG5ldyBJbnRlZ2VyKDgpOworICAgICAgICBtYXAucHV0KGtleSwgdmFsKTsKKyAgICAgICAgZXhwZWN0ZWQgKz0ga2V5Lmhhc2hDb2RlKCkgXiB2YWwuaGFzaENvZGUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBtYXAuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgY2xhc3MgTW9ja0Nsb25hYmxlIGltcGxlbWVudHMgQ2xvbmVhYmxleworICAgICAgICBwdWJsaWMgaW50IGk7CisKKyAgICAgICAgcHVibGljIE1vY2tDbG9uYWJsZShpbnQgaSkgeworICAgICAgICAgICAgdGhpcy5pID0gaTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgTW9ja0Nsb25hYmxlKGkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIG9iakFycmF5ID0gbmV3IE9iamVjdFtobVNpemVdOworICAgICAgICBvYmpBcnJheTIgPSBuZXcgT2JqZWN0W2htU2l6ZV07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2JqQXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG9iakFycmF5W2ldID0gbmV3IEludGVnZXIoaSk7CisgICAgICAgICAgICBvYmpBcnJheTJbaV0gPSBvYmpBcnJheVtpXS50b1N0cmluZygpOworICAgICAgICB9CisKKyAgICAgICAgaG0gPSBuZXcgSGFzaE1hcCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iakFycmF5Lmxlbmd0aDsgaSsrKQorICAgICAgICAgICAgaG0ucHV0KG9iakFycmF5MltpXSwgb2JqQXJyYXlbaV0pOworICAgICAgICBobS5wdXQoInRlc3QiLCBudWxsKTsKKyAgICAgICAgaG0ucHV0KG51bGwsICJ0ZXN0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVhcnMgZG93biB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIGNsb3NlIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzCisgICAgICogbWV0aG9kIGlzIGNhbGxlZCBhZnRlciBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIGhtID0gbnVsbDsKKyAgICAgICAgb2JqQXJyYXkgPSBudWxsOworICAgICAgICBvYmpBcnJheTIgPSBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0hhc2hTZXRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9IYXNoU2V0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU0YTY1YjcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9IYXNoU2V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjUzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkudGVzdGZyYW1ld29yay5zZXJpYWxpemF0aW9uLlNlcmlhbGl6YXRpb25UZXN0OworCitwdWJsaWMgY2xhc3MgSGFzaFNldFRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgSGFzaFNldCBoczsKKworICAgIE9iamVjdFtdIG9iakFycmF5OworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2hTZXQjSGFzaFNldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5IYXNoU2V0KCkKKyAgICAgICAgSGFzaFNldCBoczIgPSBuZXcgSGFzaFNldCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkNyZWF0ZWQgaW5jb3JyZWN0IEhhc2hTZXQiLCAwLCBoczIuc2l6ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaFNldCNIYXNoU2V0KGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5IYXNoU2V0KGludCkKKyAgICAgICAgSGFzaFNldCBoczIgPSBuZXcgSGFzaFNldCg1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDcmVhdGVkIGluY29ycmVjdCBIYXNoU2V0IiwgMCwgaHMyLnNpemUoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSGFzaFNldCgtMSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZmFpbCgKKyAgICAgICAgICAgICAgICAiRmFpbGVkIHRvIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBmb3IgY2FwYWNpdHkgPCAwIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2hTZXQjSGFzaFNldChpbnQsIGZsb2F0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JJRigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5IYXNoU2V0KGludCwgZmxvYXQpCisgICAgICAgIEhhc2hTZXQgaHMyID0gbmV3IEhhc2hTZXQoNSwgKGZsb2F0KSAwLjUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkNyZWF0ZWQgaW5jb3JyZWN0IEhhc2hTZXQiLCAwLCBoczIuc2l6ZSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBIYXNoU2V0KDAsIDApOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGZhaWwoCisgICAgICAgICAgICAgICAgIkZhaWxlZCB0byB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZm9yIGluaXRpYWwgbG9hZCBmYWN0b3IgPD0gMCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNoU2V0I0hhc2hTZXQoamF2YS51dGlsLkNvbGxlY3Rpb24pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX3V0aWxfQ29sbGVjdGlvbigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5IYXNoU2V0KGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAgICBIYXNoU2V0IGhzMiA9IG5ldyBIYXNoU2V0KEFycmF5cy5hc0xpc3Qob2JqQXJyYXkpKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBvYmpBcnJheS5sZW5ndGg7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkhhc2hTZXQgZG9lcyBub3QgY29udGFpbiBjb3JyZWN0IGVsZW1lbnRzIiwgaHMKKyAgICAgICAgICAgICAgICAgICAgLmNvbnRhaW5zKG9iakFycmF5W2NvdW50ZXJdKSk7CisgICAgICAgIGFzc2VydFRydWUoIkhhc2hTZXQgY3JlYXRlZCBmcm9tIGNvbGxlY3Rpb24gaW5jb3JyZWN0IHNpemUiLAorICAgICAgICAgICAgICAgIGhzMi5zaXplKCkgPT0gb2JqQXJyYXkubGVuZ3RoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEhhc2hTZXQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaFNldCNhZGQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuSGFzaFNldC5hZGQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgaW50IHNpemUgPSBocy5zaXplKCk7CisgICAgICAgIGhzLmFkZChuZXcgSW50ZWdlcig4KSk7CisgICAgICAgIGFzc2VydFRydWUoIkFkZGVkIGVsZW1lbnQgYWxyZWFkeSBjb250YWluZWQgYnkgc2V0IiwgaHMuc2l6ZSgpID09IHNpemUpOworICAgICAgICBocy5hZGQobmV3IEludGVnZXIoLTkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGluY3JlbWVudCBzZXQgc2l6ZSBhZnRlciBhZGQiLAorICAgICAgICAgICAgICAgIGhzLnNpemUoKSA9PSBzaXplICsgMSk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBhZGQgZWxlbWVudCB0byBzZXQiLCBocy5jb250YWlucyhuZXcgSW50ZWdlcigtOSkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaFNldCNjbGVhcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jbGVhcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkhhc2hTZXQuY2xlYXIoKQorICAgICAgICBTZXQgb3JnU2V0ID0gKFNldCkgaHMuY2xvbmUoKTsKKyAgICAgICAgaHMuY2xlYXIoKTsKKyAgICAgICAgSXRlcmF0b3IgaSA9IG9yZ1NldC5pdGVyYXRvcigpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIG5vbi16ZXJvIHNpemUgYWZ0ZXIgY2xlYXIiLCAwLCBocy5zaXplKCkpOworICAgICAgICB3aGlsZSAoaS5oYXNOZXh0KCkpCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gY2xlYXIgc2V0IiwgIWhzLmNvbnRhaW5zKGkubmV4dCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2hTZXQjY2xvbmUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvbmUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IGphdmEudXRpbC5IYXNoU2V0LmNsb25lKCkKKyAgICAgICAgSGFzaFNldCBoczIgPSAoSGFzaFNldCkgaHMuY2xvbmUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiY2xvbmUgcmV0dXJuZWQgYW4gZXF1aXZhbGVudCBIYXNoU2V0IiwgaHMgIT0gaHMyKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiY2xvbmUgZGlkIG5vdCByZXR1cm4gYW4gZXF1YWwgSGFzaFNldCIsIGhzLmVxdWFscyhoczIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaFNldCNjb250YWlucyhqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY29udGFpbnNMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4gamF2YS51dGlsLkhhc2hTZXQuY29udGFpbnMoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIHZhbGlkIG9iamVjdCIsIGhzLmNvbnRhaW5zKG9iakFycmF5WzkwXSkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCB0cnVlIGZvciBpbnZhbGlkIE9iamVjdCIsICFocworICAgICAgICAgICAgICAgIC5jb250YWlucyhuZXcgT2JqZWN0KCkpKTsKKworICAgICAgICBIYXNoU2V0IHMgPSBuZXcgSGFzaFNldCgpOworICAgICAgICBzLmFkZChudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2Fubm90IGhhbmRsZSBudWxsIiwgcy5jb250YWlucyhudWxsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2hTZXQjaXNFbXB0eSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0VtcHR5KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuSGFzaFNldC5pc0VtcHR5KCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRW1wdHkgc2V0IHJldHVybmVkIGZhbHNlIiwgbmV3IEhhc2hTZXQoKS5pc0VtcHR5KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJOb24tZW1wdHkgc2V0IHJldHVybmVkIHRydWUiLCAhaHMuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaFNldCNpdGVyYXRvcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pdGVyYXRvcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5JdGVyYXRvciBqYXZhLnV0aWwuSGFzaFNldC5pdGVyYXRvcigpCisgICAgICAgIEl0ZXJhdG9yIGkgPSBocy5pdGVyYXRvcigpOworICAgICAgICBpbnQgeCA9IDA7CisgICAgICAgIHdoaWxlIChpLmhhc05leHQoKSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGl0ZXJhdGUgb3ZlciBhbGwgZWxlbWVudHMiLCBocy5jb250YWlucyhpCisgICAgICAgICAgICAgICAgICAgIC5uZXh0KCkpKTsKKyAgICAgICAgICAgICsreDsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpdGVyYXRpb24gb2YgaW5jb3JyZWN0IHNpemUiLCBocy5zaXplKCkgPT0geCk7CisKKyAgICAgICAgSGFzaFNldCBzID0gbmV3IEhhc2hTZXQoKTsKKyAgICAgICAgcy5hZGQobnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoIkNhbm5vdCBoYW5kbGUgbnVsbCIsIHMuaXRlcmF0b3IoKS5uZXh0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNoU2V0I3JlbW92ZShqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEudXRpbC5IYXNoU2V0LnJlbW92ZShqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBpbnQgc2l6ZSA9IGhzLnNpemUoKTsKKyAgICAgICAgaHMucmVtb3ZlKG5ldyBJbnRlZ2VyKDk4KSk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byByZW1vdmUgZWxlbWVudCIsICFocy5jb250YWlucyhuZXcgSW50ZWdlcig5OCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGRlY3JlbWVudCBzZXQgc2l6ZSIsIGhzLnNpemUoKSA9PSBzaXplIC0gMSk7CisKKyAgICAgICAgSGFzaFNldCBzID0gbmV3IEhhc2hTZXQoKTsKKyAgICAgICAgcy5hZGQobnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoIkNhbm5vdCBoYW5kbGUgbnVsbCIsIHMucmVtb3ZlKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoaHMucmVtb3ZlKG5ldyBJbnRlZ2VyKC05OCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaFNldCNzaXplKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NpemUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLkhhc2hTZXQuc2l6ZSgpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBzaXplIiwgaHMuc2l6ZSgpID09IChvYmpBcnJheS5sZW5ndGggKyAxKSk7CisgICAgICAgIGhzLmNsZWFyKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQ2xlYXJlZCBzZXQgcmV0dXJuZWQgbm9uLXplcm8gc2l6ZSIsIDAsIGhzLnNpemUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2hTZXQjU2VyaWFsaXphdGlvblRlc3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NlcmlhbGl6YXRpb24oKSB0aHJvd3MgRXhjZXB0aW9ueworICAgICAgICBIYXNoU2V0PFN0cmluZz4gaHMgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7CisgICAgICAgIGhzLmFkZCgiaGVsbG8iKTsKKyAgICAgICAgaHMuYWRkKCJ3b3JsZCIpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdC52ZXJpZnlTZWxmKGhzLCBjb21wYXJhdG9yKTsKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3QudmVyaWZ5R29sZGVuKHRoaXMsIGhzLCBjb21wYXJhdG9yKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgb2JqQXJyYXkgPSBuZXcgT2JqZWN0WzEwMDBdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iakFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBvYmpBcnJheVtpXSA9IG5ldyBJbnRlZ2VyKGkpOworICAgICAgICB9CisKKyAgICAgICAgaHMgPSBuZXcgSGFzaFNldCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iakFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBocy5hZGQob2JqQXJyYXlbaV0pOworICAgICAgICB9CisKKyAgICAgICAgaHMuYWRkKG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgICAgICBocyA9IG51bGw7CisgICAgICAgIG9iakFycmF5ID0gbnVsbDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTZXJpYWxpemF0aW9uVGVzdC5TZXJpYWxpemFibGVBc3NlcnQgY29tcGFyYXRvciA9IG5ldworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VyaWFsaXphdGlvblRlc3QuU2VyaWFsaXphYmxlQXNzZXJ0KCkgeworICAgICAgICBwdWJsaWMgdm9pZCBhc3NlcnREZXNlcmlhbGl6ZWQoU2VyaWFsaXphYmxlIGluaXRpYWwsIFNlcmlhbGl6YWJsZSBkZXNlcmlhbGl6ZWQpIHsKKyAgICAgICAgICAgIEhhc2hTZXQ8U3RyaW5nPiBpbml0aWFsSHMgPSAoSGFzaFNldDxTdHJpbmc+KSBpbml0aWFsOworICAgICAgICAgICAgSGFzaFNldDxTdHJpbmc+IGRlc2VyaWFIcyA9IChIYXNoU2V0PFN0cmluZz4pIGRlc2VyaWFsaXplZDsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygic2hvdWxkIGJlIGVxdWFsIiwgaW5pdGlhbEhzLnNpemUoKSwgZGVzZXJpYUhzLnNpemUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInNob3VsZCBiZSBlcXVhbCIsIGluaXRpYWxIcywgZGVzZXJpYUhzKTsKKyAgICAgICAgfQorCisgICAgfTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0hhc2h0YWJsZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0hhc2h0YWJsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45Yzk3YzdiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvSGFzaHRhYmxlVGVzdC5qYXZhCkBAIC0wLDAgKzEsODM4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKKworaW1wb3J0IHRlc3RzLmFwaS5qYXZhLnV0aWwuSGFzaE1hcFRlc3QuUmV1c2FibGVLZXk7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X01hcFRlc3QyOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Vbm1vZGlmaWFibGVDb2xsZWN0aW9uVGVzdDsKKworcHVibGljIGNsYXNzIEhhc2h0YWJsZVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBIYXNodGFibGUgaHQxMDsKKworICAgIHByaXZhdGUgSGFzaHRhYmxlIGh0MTAwOworCisgICAgcHJpdmF0ZSBIYXNodGFibGUgaHRmdWxsOworCisgICAgcHJpdmF0ZSBWZWN0b3Iga2V5VmVjdG9yOworCisgICAgcHJpdmF0ZSBWZWN0b3IgZWxtVmVjdG9yOworCisgICAgcHJpdmF0ZSBTdHJpbmcgaDEwc1ZhbDsKKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNodGFibGUjSGFzaHRhYmxlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLkhhc2h0YWJsZSgpCisgICAgICAgIG5ldyBTdXBwb3J0X01hcFRlc3QyKG5ldyBIYXNodGFibGUoKSkucnVuVGVzdCgpOworCisgICAgICAgIEhhc2h0YWJsZSBoID0gbmV3IEhhc2h0YWJsZSgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiQ3JlYXRlZCBpbmNvcnJlY3QgaGFzaHRhYmxlIiwgMCwgaC5zaXplKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNodGFibGUjSGFzaHRhYmxlKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5IYXNodGFibGUoaW50KQorICAgICAgICBIYXNodGFibGUgaCA9IG5ldyBIYXNodGFibGUoOSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDcmVhdGVkIGluY29ycmVjdCBoYXNodGFibGUiLCAwLCBoLnNpemUoKSk7CisKKyAgICAgICAgSGFzaHRhYmxlIGVtcHR5ID0gbmV3IEhhc2h0YWJsZSgwKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiRW1wdHkgaGFzaHRhYmxlIGFjY2VzcyIsIGVtcHR5LmdldCgibm90aGluZyIpKTsKKyAgICAgICAgZW1wdHkucHV0KCJzb21ldGhpbmciLCAiaGVyZSIpOworICAgICAgICBhc3NlcnRUcnVlKCJjYW5ub3QgZ2V0IGVsZW1lbnQiLCBlbXB0eS5nZXQoInNvbWV0aGluZyIpID09ICJoZXJlIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBIYXNodGFibGUoLTEpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaHRhYmxlI0hhc2h0YWJsZShpbnQsIGZsb2F0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JJRigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5IYXNodGFibGUoaW50LCBmbG9hdCkKKyAgICAgICAgSGFzaHRhYmxlIGggPSBuZXcgamF2YS51dGlsLkhhc2h0YWJsZSgxMCwgMC41Zik7CisgICAgICAgIGFzc2VydEVxdWFscygiQ3JlYXRlZCBpbmNvcnJlY3QgaGFzaHRhYmxlIiwgMCwgaC5zaXplKCkpOworCisgICAgICAgIEhhc2h0YWJsZSBlbXB0eSA9IG5ldyBIYXNodGFibGUoMCwgMC43NWYpOworICAgICAgICBhc3NlcnROdWxsKCJFbXB0eSBoYXNodGFibGUgYWNjZXNzIiwgZW1wdHkuZ2V0KCJub3RoaW5nIikpOworICAgICAgICBlbXB0eS5wdXQoInNvbWV0aGluZyIsICJoZXJlIik7CisgICAgICAgIGFzc2VydFRydWUoImNhbm5vdCBnZXQgZWxlbWVudCIsIGVtcHR5LmdldCgic29tZXRoaW5nIikgPT0gImhlcmUiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEhhc2h0YWJsZSgtMSwgMC43NWYpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEhhc2h0YWJsZSgwLCAtMC43NWYpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaHRhYmxlI0hhc2h0YWJsZShqYXZhLnV0aWwuTWFwKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV91dGlsX01hcCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5IYXNodGFibGUoamF2YS51dGlsLk1hcCkKKyAgICAgICAgTWFwIG1hcCA9IG5ldyBUcmVlTWFwKCk7CisgICAgICAgIE9iamVjdCBmaXJzdFZhbCA9ICJHYWJiYSI7CisgICAgICAgIE9iamVjdCBzZWNvbmRWYWwgPSBuZXcgSW50ZWdlcig1KTsKKyAgICAgICAgbWFwLnB1dCgiR2FoIiwgZmlyc3RWYWwpOworICAgICAgICBtYXAucHV0KCJPb2dhIiwgc2Vjb25kVmFsKTsKKyAgICAgICAgSGFzaHRhYmxlIGh0ID0gbmV3IEhhc2h0YWJsZShtYXApOworICAgICAgICBhc3NlcnRUcnVlKCJhKSBJbmNvcnJlY3QgSGFzaHRhYmxlIGNvbnN0cnVjdGVkIiwKKyAgICAgICAgICAgICAgICBodC5nZXQoIkdhaCIpID09IGZpcnN0VmFsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiYikgSW5jb3JyZWN0IEhhc2h0YWJsZSBjb25zdHJ1Y3RlZCIsCisgICAgICAgICAgICAgICAgaHQuZ2V0KCJPb2dhIikgPT0gc2Vjb25kVmFsKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEhhc2h0YWJsZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNodGFibGUjSGFzaHRhYmxlKGphdmEudXRpbC5NYXApCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db252ZXJzaW9uQ29uc3RydWN0b3JOdWxsVmFsdWUoKSB7CisgICAgICAgIE1hcDxTdHJpbmcsIFZvaWQ+IG1hcCA9IENvbGxlY3Rpb25zLnNpbmdsZXRvbk1hcCgiRG9nIiwgbnVsbCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSGFzaHRhYmxlPFN0cmluZywgVm9pZD4obWFwKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaHRhYmxlI2NsZWFyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NsZWFyKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuSGFzaHRhYmxlLmNsZWFyKCkKKyAgICAgICAgSGFzaHRhYmxlIGggPSBoYXNodGFibGVDbG9uZShodGZ1bGwpOworICAgICAgICBoLmNsZWFyKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSGFzaHRhYmxlIHdhcyBub3QgY2xlYXJlZCIsIDAsIGguc2l6ZSgpKTsKKyAgICAgICAgRW51bWVyYXRpb24gZWwgPSBoLmVsZW1lbnRzKCk7CisgICAgICAgIEVudW1lcmF0aW9uIGtleXMgPSBoLmtleXMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSGFzaHRhYmxlIGltcHJvcGVybHkgY2xlYXJlZCIsICFlbC5oYXNNb3JlRWxlbWVudHMoKQorICAgICAgICAgICAgICAgICYmICEoa2V5cy5oYXNNb3JlRWxlbWVudHMoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNodGFibGUjY2xvbmUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvbmUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IGphdmEudXRpbC5IYXNodGFibGUuY2xvbmUoKQorCisgICAgICAgIEhhc2h0YWJsZSBoID0gKEhhc2h0YWJsZSkgaHRmdWxsLmNsb25lKCk7CisgICAgICAgIGFzc2VydFRydWUoIkNsb25lIGRpZmZlcmVudCBzaXplIHRoYW4gb3JpZ2luYWwiLCBoLnNpemUoKSA9PSBodGZ1bGwKKyAgICAgICAgICAgICAgICAuc2l6ZSgpKTsKKworICAgICAgICBFbnVtZXJhdGlvbiBvcmcgPSBodGZ1bGwua2V5cygpOworICAgICAgICBFbnVtZXJhdGlvbiBjcHkgPSBoLmtleXMoKTsKKworICAgICAgICBTdHJpbmcgb2tleSwgY2tleTsKKyAgICAgICAgd2hpbGUgKG9yZy5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiS2V5IGNvbXBhcmlzb24gZmFpbGVkIiwgKG9rZXkgPSAoU3RyaW5nKSBvcmcKKyAgICAgICAgICAgICAgICAgICAgLm5leHRFbGVtZW50KCkpLmVxdWFscyhja2V5ID0gKFN0cmluZykgY3B5Lm5leHRFbGVtZW50KCkpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlZhbHVlIGNvbXBhcmlzb24gZmFpbGVkIiwgKChTdHJpbmcpIGh0ZnVsbC5nZXQob2tleSkpCisgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoKFN0cmluZykgaC5nZXQoY2tleSkpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJDb3B5IGhhcyBtb3JlIGtleXMgdGhhbiBvcmlnaW5hbCIsICFjcHkuaGFzTW9yZUVsZW1lbnRzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNodGFibGUjY29udGFpbnMoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbnRhaW5zTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuCisgICAgICAgIC8vIGphdmEudXRpbC5IYXNodGFibGUuY29udGFpbnMoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRWxlbWVudCBub3QgZm91bmQiLCBodDEwLmNvbnRhaW5zKCJWYWwgNyIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW52YWxpZCBlbGVtZW50IGZvdW5kIiwgIWh0MTAuY29udGFpbnMoIlpaWlpaWlpaWlpaWlpaWloiKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGh0MTAuY29udGFpbnMobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaHRhYmxlI2NvbnRhaW5zS2V5KGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jb250YWluc0tleUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbgorICAgICAgICAvLyBqYXZhLnV0aWwuSGFzaHRhYmxlLmNvbnRhaW5zS2V5KGphdmEubGFuZy5PYmplY3QpCisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGZpbmQga2V5IiwgaHRmdWxsLmNvbnRhaW5zS2V5KCJGS2V5IDQiKSk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBmaW5kIGtleSIsICFodGZ1bGwuY29udGFpbnNLZXkoIkZLZXkgOTkiKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGh0ZnVsbC5jb250YWluc0tleShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNodGFibGUjY29udGFpbnNWYWx1ZShqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY29udGFpbnNWYWx1ZUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbgorICAgICAgICAvLyBqYXZhLnV0aWwuSGFzaHRhYmxlLmNvbnRhaW5zVmFsdWUoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgRW51bWVyYXRpb24gZSA9IGVsbVZlY3Rvci5lbGVtZW50cygpOworICAgICAgICB3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciB2YWxpZCB2YWx1ZSIsIGh0MTAuY29udGFpbnNWYWx1ZShlCisgICAgICAgICAgICAgICAgICAgIC5uZXh0RWxlbWVudCgpKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHRydWUgZm9yIGludmFsaWQgdmFsdWUiLCAhaHQxMAorICAgICAgICAgICAgICAgIC5jb250YWluc1ZhbHVlKG5ldyBPYmplY3QoKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBodDEwLmNvbnRhaW5zVmFsdWUobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2h0YWJsZSNlbGVtZW50cygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9lbGVtZW50cygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5FbnVtZXJhdGlvbiBqYXZhLnV0aWwuSGFzaHRhYmxlLmVsZW1lbnRzKCkKKyAgICAgICAgRW51bWVyYXRpb24gZWxtcyA9IGh0MTAuZWxlbWVudHMoKTsKKyAgICAgICAgaW50IGkgPSAwOworICAgICAgICB3aGlsZSAoZWxtcy5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgU3RyaW5nIHMgPSAoU3RyaW5nKSBlbG1zLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJNaXNzaW5nIGtleSBmcm9tIGVudW1lcmF0aW9uIiwgZWxtVmVjdG9yLmNvbnRhaW5zKHMpKTsKKyAgICAgICAgICAgICsraTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygiQWxsIGtleXMgbm90IHJldHJpZXZlZCIsIDEwLCBodDEwLnNpemUoKSk7CisgICAgfQorCisvLyBCRUdJTiBhbmRyb2lkLXJlbW92ZWQKKy8vIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudAorLy8gICAgLyoqCisvLyAgICAgKiBqYXZhLnV0aWwuSGFzaHRhYmxlI2VsZW1lbnRzKCkKKy8vICAgICAqLworLy8gICAgcHVibGljIHZvaWQgdGVzdF9lbGVtZW50c19zdWJ0ZXN0MCgpIHsKKy8vICAgICAgICAvLyB0aGlzIGlzIHRoZSByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24gYmVoYXZpb3IKKy8vICAgICAgICBmaW5hbCBIYXNodGFibGUgaHQgPSBuZXcgSGFzaHRhYmxlKDcpOworLy8gICAgICAgIGh0LnB1dCgiMSIsICJhIik7CisvLyAgICAgICAgLy8gdGhlc2UgdGhyZWUgZWxlbWVudHMgaGFzaCB0byB0aGUgc2FtZSBidWNrZXQgaW4gYSA3IGVsZW1lbnQgSGFzaHRhYmxlCisvLyAgICAgICAgaHQucHV0KCIyIiwgImIiKTsKKy8vICAgICAgICBodC5wdXQoIjkiLCAiYyIpOworLy8gICAgICAgIGh0LnB1dCgiMTIiLCAiZCIpOworLy8gICAgICAgIC8vIEhhc2h0YWJsZSBsb29rcyBsaWtlOgorLy8gICAgICAgIC8vIDA6ICIxIgorLy8gICAgICAgIC8vIDE6ICIxMiIgLT4gIjkiIC0+ICIyIgorLy8gICAgICAgIEVudW1lcmF0aW9uIGVuID0gaHQuZWxlbWVudHMoKTsKKy8vICAgICAgICAvLyBjYWNoZSB0aGUgZmlyc3QgZW50cnkKKy8vICAgICAgICBlbi5oYXNNb3JlRWxlbWVudHMoKTsKKy8vICAgICAgICBodC5yZW1vdmUoIjEyIik7CisvLyAgICAgICAgaHQucmVtb3ZlKCI5Iik7CisvLyAgICAgICAgYm9vbGVhbiBleGNlcHRpb24gPSBmYWxzZTsKKy8vICAgICAgICB0cnkgeworLy8gICAgICAgICAgICAvLyBjYWNoZWQgIjEyIgorLy8gICAgICAgICAgICBPYmplY3QgcmVzdWx0ID0gZW4ubmV4dEVsZW1lbnQoKTsKKy8vICAgICAgICAgICAgYXNzZXJ0TnVsbCgidW5leHBlY3RlZDogIiArIHJlc3VsdCwgcmVzdWx0KTsKKy8vICAgICAgICAgICAgLy8gbmV4dCBpcyByZW1vdmVkICI5IgorLy8gICAgICAgICAgICByZXN1bHQgPSBlbi5uZXh0RWxlbWVudCgpOworLy8gICAgICAgICAgICBhc3NlcnROdWxsKCJ1bmV4cGVjdGVkOiAiICsgcmVzdWx0LCByZXN1bHQpOworLy8gICAgICAgICAgICByZXN1bHQgPSBlbi5uZXh0RWxlbWVudCgpOworLy8gICAgICAgICAgICBhc3NlcnRUcnVlKCJ1bmV4cGVjdGVkOiAiICsgcmVzdWx0LCAiYiIuZXF1YWxzKHJlc3VsdCkpOworLy8gICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworLy8gICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworLy8gICAgICAgIH0KKy8vICAgICAgICBhc3NlcnRUcnVlKCJ1bmV4cGVjdGVkIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24iLCAhZXhjZXB0aW9uKTsKKy8vICAgIH0KKy8vIEVORCBhbmRyb2lkLXJlbW92ZWQKKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNodGFibGUjZW50cnlTZXQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZW50cnlTZXQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuU2V0IGphdmEudXRpbC5IYXNodGFibGUuZW50cnlTZXQoKQorICAgICAgICBTZXQgcyA9IGh0MTAuZW50cnlTZXQoKTsKKyAgICAgICAgU2V0IHMyID0gbmV3IEhhc2hTZXQoKTsKKyAgICAgICAgSXRlcmF0b3IgaSA9IHMuaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGkuaGFzTmV4dCgpKQorICAgICAgICAgICAgczIuYWRkKCgoTWFwLkVudHJ5KSBpLm5leHQoKSkuZ2V0VmFsdWUoKSk7CisgICAgICAgIEVudW1lcmF0aW9uIGUgPSBlbG1WZWN0b3IuZWxlbWVudHMoKTsKKyAgICAgICAgd2hpbGUgKGUuaGFzTW9yZUVsZW1lbnRzKCkpCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgZW50cnkgc2V0IiwgczIuY29udGFpbnMoZQorICAgICAgICAgICAgICAgICAgICAubmV4dEVsZW1lbnQoKSkpOworLy8gQkVHSU4gYW5kcm9pZC1yZW1vdmVkCisvLyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoIk5vdCBzeW5jaHJvbml6ZWQiLAorLy8gICAgICAgICAgICAgICAgImphdmEudXRpbC5Db2xsZWN0aW9ucyRTeW5jaHJvbml6ZWRTZXQiLCBzLmdldENsYXNzKCkuZ2V0TmFtZSgpKTsKKy8vIEVORCBhbmRyb2lkLXJlbW92ZWQKKworICAgICAgICBib29sZWFuIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgKChNYXAuRW50cnkpIGh0MTAuZW50cnlTZXQoKS5pdGVyYXRvcigpLm5leHQoKSkuc2V0VmFsdWUobnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUxKSB7CisgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIlNob3VsZCBub3QgYmUgYWJsZSB0byBhc3NpZ24gbnVsbCB0byBhIEhhc2h0YWJsZSBlbnRyeVNldCgpIE1hcC5FbnRyeSIsCisgICAgICAgICAgICAgICAgZXhjZXB0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaHRhYmxlI2VxdWFscyhqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEudXRpbC5IYXNodGFibGUuZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIEhhc2h0YWJsZSBoID0gaGFzaHRhYmxlQ2xvbmUoaHQxMCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciBlcXVhbCB0YWJsZXMiLCBodDEwLmVxdWFscyhoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHRydWUgZm9yIHVuZXF1YWwgdGFibGVzIiwgIWh0MTAuZXF1YWxzKGh0ZnVsbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNodGFibGUjZ2V0KGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QKKyAgICAgICAgLy8gamF2YS51dGlsLkhhc2h0YWJsZS5nZXQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgSGFzaHRhYmxlIGggPSBoYXNodGFibGVDbG9uZShodGZ1bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkNvdWxkIG5vdCByZXRyaWV2ZSBlbGVtZW50IiwgIkZWYWwgMiIsICgoU3RyaW5nKSBoLmdldCgiRktleSAyIikpCisgICAgICAgICAgICAgICAgKTsKKworLy8gQkVHSU4gYW5kcm9pZC1yZW1vdmVkCisvLyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQKKy8vICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTI2MgorLy8gICAgICAgIFJldXNhYmxlS2V5IGsgPSBuZXcgUmV1c2FibGVLZXkoKTsKKy8vICAgICAgICBIYXNodGFibGUgaDIgPSBuZXcgSGFzaHRhYmxlKCk7CisvLyAgICAgICAgay5zZXRLZXkoMSk7CisvLyAgICAgICAgaDIucHV0KGssICJ2YWx1ZTEiKTsKKy8vCisvLyAgICAgICAgay5zZXRLZXkoMTMpOworLy8gICAgICAgIGFzc2VydE51bGwoaDIuZ2V0KGspKTsKKy8vCisvLyAgICAgICAgay5zZXRLZXkoMTIpOworLy8gICAgICAgIGFzc2VydE51bGwoaDIuZ2V0KGspKTsKKy8vCisvLyAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgaDIuZ2V0KG51bGwpOworLy8gICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworLy8gICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKy8vICAgICAgICAgICAgLy9leHBlY3RlZAorLy8gICAgICAgIH0KKy8vIEVORCBhbmRyb2lkLXJlbW92ZWQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaHRhYmxlI2hhc2hDb2RlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc2hDb2RlKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudXRpbC5IYXNodGFibGUuaGFzaENvZGUoKQorICAgICAgICBTZXQgZW50cnlTZXQgPSBodDEwLmVudHJ5U2V0KCk7CisgICAgICAgIEl0ZXJhdG9yIGl0ZXJhdG9yID0gZW50cnlTZXQuaXRlcmF0b3IoKTsKKyAgICAgICAgaW50IGV4cGVjdGVkSGFzaDsKKyAgICAgICAgZm9yIChleHBlY3RlZEhhc2ggPSAwOyBpdGVyYXRvci5oYXNOZXh0KCk7IGV4cGVjdGVkSGFzaCArPSBpdGVyYXRvcgorICAgICAgICAgICAgICAgIC5uZXh0KCkuaGFzaENvZGUoKSkKKyAgICAgICAgICAgIDsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGhhc2hDb2RlIHJldHVybmVkLiAgV2FudGVkOiAiICsgZXhwZWN0ZWRIYXNoCisgICAgICAgICAgICAgICAgKyAiIGdvdDogIiArIGh0MTAuaGFzaENvZGUoKSwgZXhwZWN0ZWRIYXNoID09IGh0MTAuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2h0YWJsZSNpc0VtcHR5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzRW1wdHkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEudXRpbC5IYXNodGFibGUuaXNFbXB0eSgpCisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaXNFbXB0eSByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAhaHQxMC5pc0VtcHR5KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJpc0VtcHR5IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgbmV3IGphdmEudXRpbC5IYXNodGFibGUoKS5pc0VtcHR5KCkpOworCisgICAgICAgIGZpbmFsIEhhc2h0YWJsZSBodCA9IG5ldyBIYXNodGFibGUoKTsKKyAgICAgICAgaHQucHV0KCIwIiwgIiIpOworICAgICAgICBUaHJlYWQgdDEgPSBuZXcgVGhyZWFkKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHdoaWxlICghaHQuaXNFbXB0eSgpKQorICAgICAgICAgICAgICAgICAgICA7CisgICAgICAgICAgICAgICAgaHQucHV0KCJmaW5hbCIsICIiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgdDEuc3RhcnQoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCAxMDAwMDsgaSsrKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGh0KSB7CisgICAgICAgICAgICAgICAgaHQucmVtb3ZlKFN0cmluZy52YWx1ZU9mKGkgLSAxKSk7CisgICAgICAgICAgICAgICAgaHQucHV0KFN0cmluZy52YWx1ZU9mKGkpLCAiIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgc2l6ZTsKKyAgICAgICAgICAgIGlmICgoc2l6ZSA9IGh0LnNpemUoKSkgIT0gMSkgeworICAgICAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSAiU2l6ZSBpcyBub3QgMTogIiArIHNpemUgKyAiICIgKyBodDsKKyAgICAgICAgICAgICAgICAvLyB0ZXJtaW5hdGUgdGhlIHRocmVhZAorICAgICAgICAgICAgICAgIGh0LmNsZWFyKCk7CisgICAgICAgICAgICAgICAgZmFpbChyZXN1bHQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIHRlcm1pbmF0ZSB0aGUgdGhyZWFkCisgICAgICAgIGh0LmNsZWFyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2h0YWJsZSNrZXlzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2tleXMoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuRW51bWVyYXRpb24gamF2YS51dGlsLkhhc2h0YWJsZS5rZXlzKCkKKworICAgICAgICBFbnVtZXJhdGlvbiBrZXlzID0gaHQxMC5rZXlzKCk7CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgd2hpbGUgKGtleXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIFN0cmluZyBzID0gKFN0cmluZykga2V5cy5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTWlzc2luZyBrZXkgZnJvbSBlbnVtZXJhdGlvbiIsIGtleVZlY3Rvci5jb250YWlucyhzKSk7CisgICAgICAgICAgICArK2k7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoIkFsbCBrZXlzIG5vdCByZXRyaWV2ZWQiLCAxMCwgaHQxMC5zaXplKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNodGFibGUja2V5cygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9rZXlzX3N1YnRlc3QwKCkgeworICAgICAgICAvLyB0aGlzIGlzIHRoZSByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24gYmVoYXZpb3IKKyAgICAgICAgZmluYWwgSGFzaHRhYmxlIGh0ID0gbmV3IEhhc2h0YWJsZSgzKTsKKyAgICAgICAgaHQucHV0KCJpbml0aWFsIiwgIiIpOworICAgICAgICBFbnVtZXJhdGlvbiBlbiA9IGh0LmtleXMoKTsKKyAgICAgICAgZW4uaGFzTW9yZUVsZW1lbnRzKCk7CisgICAgICAgIGh0LnJlbW92ZSgiaW5pdGlhbCIpOworICAgICAgICBib29sZWFuIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgT2JqZWN0IHJlc3VsdCA9IGVuLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ1bmV4cGVjdGVkOiAiICsgcmVzdWx0LCAiaW5pdGlhbCIuZXF1YWxzKHJlc3VsdCkpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgidW5leHBlY3RlZCBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIiwgIWV4Y2VwdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkhhc2h0YWJsZSNrZXlTZXQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfa2V5U2V0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlNldCBqYXZhLnV0aWwuSGFzaHRhYmxlLmtleVNldCgpCisgICAgICAgIFNldCBzID0gaHQxMC5rZXlTZXQoKTsKKyAgICAgICAgRW51bWVyYXRpb24gZSA9IGtleVZlY3Rvci5lbGVtZW50cygpOworICAgICAgICB3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBrZXkgc2V0IiwgcworICAgICAgICAgICAgICAgICAgICAuY29udGFpbnMoZS5uZXh0RWxlbWVudCgpKSk7CisKKy8vIEJFR0lOIGFuZHJvaWQtcmVtb3ZlZAorLy8gaW1wbGVtZW50YXRpb24gZGVwZW5kZW50CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJOb3Qgc3luY2hyb25pemVkIiwKKy8vICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuQ29sbGVjdGlvbnMkU3luY2hyb25pemVkU2V0Iiwgcy5nZXRDbGFzcygpLmdldE5hbWUoKSk7CisvLyBFTkQgYW5kcm9pZC1yZW1vdmVkCisKKyAgICAgICAgTWFwIG1hcCA9IG5ldyBIYXNodGFibGUoMTAxKTsKKyAgICAgICAgbWFwLnB1dChuZXcgSW50ZWdlcigxKSwgIjEiKTsKKyAgICAgICAgbWFwLnB1dChuZXcgSW50ZWdlcigxMDIpLCAiMTAyIik7CisgICAgICAgIG1hcC5wdXQobmV3IEludGVnZXIoMjAzKSwgIjIwMyIpOworICAgICAgICBJdGVyYXRvciBpdCA9IG1hcC5rZXlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICBJbnRlZ2VyIHJlbW92ZTEgPSAoSW50ZWdlcikgaXQubmV4dCgpOworICAgICAgICBpdC5yZW1vdmUoKTsKKyAgICAgICAgSW50ZWdlciByZW1vdmUyID0gKEludGVnZXIpIGl0Lm5leHQoKTsKKyAgICAgICAgaXQucmVtb3ZlKCk7CisgICAgICAgIEFycmF5TGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdChBcnJheXMuYXNMaXN0KG5ldyBJbnRlZ2VyW10geworICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKDEpLCBuZXcgSW50ZWdlcigxMDIpLCBuZXcgSW50ZWdlcigyMDMpIH0pKTsKKyAgICAgICAgbGlzdC5yZW1vdmUocmVtb3ZlMSk7CisgICAgICAgIGxpc3QucmVtb3ZlKHJlbW92ZTIpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyByZXN1bHQiLCBpdC5uZXh0KCkuZXF1YWxzKGxpc3QuZ2V0KDApKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSIsIDEsIG1hcC5zaXplKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBjb250ZW50cyIsIG1hcC5rZXlTZXQoKS5pdGVyYXRvcigpLm5leHQoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgbGlzdC5nZXQoMCkpKTsKKworICAgICAgICBNYXAgbWFwMiA9IG5ldyBIYXNodGFibGUoMTAxKTsKKyAgICAgICAgbWFwMi5wdXQobmV3IEludGVnZXIoMSksICIxIik7CisgICAgICAgIG1hcDIucHV0KG5ldyBJbnRlZ2VyKDQpLCAiNCIpOworICAgICAgICBJdGVyYXRvciBpdDIgPSBtYXAyLmtleVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgIEludGVnZXIgcmVtb3ZlMyA9IChJbnRlZ2VyKSBpdDIubmV4dCgpOworICAgICAgICBJbnRlZ2VyIG5leHQ7CisgICAgICAgIGlmIChyZW1vdmUzLmludFZhbHVlKCkgPT0gMSkKKyAgICAgICAgICAgIG5leHQgPSBuZXcgSW50ZWdlcig0KTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgbmV4dCA9IG5ldyBJbnRlZ2VyKDEpOworICAgICAgICBpdDIuaGFzTmV4dCgpOworICAgICAgICBpdDIucmVtb3ZlKCk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHJlc3VsdCAyIiwgaXQyLm5leHQoKS5lcXVhbHMobmV4dCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUgMiIsIDEsIG1hcDIuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgY29udGVudHMgMiIsIG1hcDIua2V5U2V0KCkuaXRlcmF0b3IoKS5uZXh0KCkuZXF1YWxzKAorICAgICAgICAgICAgICAgIG5leHQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaHRhYmxlI2tleVNldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9rZXlTZXRfc3VidGVzdDAoKSB7CisgICAgICAgIFNldCBzMSA9IGh0MTAua2V5U2V0KCk7CisgICAgICAgIGFzc2VydFRydWUoInNob3VsZCBjb250YWluIGtleSIsIHMxLnJlbW92ZSgiS2V5IDAiKSk7CisgICAgICAgIGFzc2VydFRydWUoInNob3VsZCBub3QgY29udGFpbiBrZXkiLCAhczEucmVtb3ZlKCJLZXkgMCIpKTsKKworICAgICAgICBmaW5hbCBpbnQgaXRlcmF0aW9ucyA9IDEwMDAwOworICAgICAgICBmaW5hbCBIYXNodGFibGUgaHQgPSBuZXcgSGFzaHRhYmxlKCk7CisgICAgICAgIFRocmVhZCB0MSA9IG5ldyBUaHJlYWQoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpdGVyYXRpb25zOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaHQucHV0KFN0cmluZy52YWx1ZU9mKGkpLCAiIik7CisgICAgICAgICAgICAgICAgICAgIGh0LnJlbW92ZShTdHJpbmcudmFsdWVPZihpKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICB0MS5zdGFydCgpOworICAgICAgICBTZXQgc2V0ID0gaHQua2V5U2V0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaXRlcmF0aW9uczsgaSsrKSB7CisgICAgICAgICAgICBJdGVyYXRvciBpdCA9IHNldC5pdGVyYXRvcigpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgaXQucmVtb3ZlKCk7CisgICAgICAgICAgICAgICAgaW50IHNpemU7CisgICAgICAgICAgICAgICAgLy8gZW5zdXJlIHJlbW92aW5nIHdpdGggdGhlIGl0ZXJhdG9yIGRvZXNuJ3QgY29ycnVwdCB0aGUKKyAgICAgICAgICAgICAgICAvLyBIYXNodGFibGUKKyAgICAgICAgICAgICAgICBpZiAoKHNpemUgPSBodC5zaXplKCkpIDwgMCkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKCJpbnZhbGlkIHNpemU6ICIgKyBzaXplKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisvLyBCRUdJTiBhbmRyb2lkLXJlbW92ZWQKKy8vIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudAorLy8gICAgLyoqCisvLyAgICAgKiBqYXZhLnV0aWwuSGFzaHRhYmxlI2tleVNldCgpCisvLyAgICAgKi8KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3Rfa2V5U2V0X3N1YnRlc3QxKCkgeworLy8gICAgICAgIC8vIHRoaXMgaXMgdGhlIHJlZmVyZW5jZSBpbXBsZW1lbnRhdGlvbiBiZWhhdmlvcgorLy8gICAgICAgIGZpbmFsIEhhc2h0YWJsZSBodCA9IG5ldyBIYXNodGFibGUoNyk7CisvLyAgICAgICAgaHQucHV0KCIxIiwgImEiKTsKKy8vICAgICAgICAvLyB0aGVzZSB0aHJlZSBlbGVtZW50cyBoYXNoIHRvIHRoZSBzYW1lIGJ1Y2tldCBpbiBhIDcgZWxlbWVudCBIYXNodGFibGUKKy8vICAgICAgICBodC5wdXQoIjIiLCAiYiIpOworLy8gICAgICAgIGh0LnB1dCgiOSIsICJjIik7CisvLyAgICAgICAgaHQucHV0KCIxMiIsICJkIik7CisvLyAgICAgICAgLy8gSGFzaHRhYmxlIGxvb2tzIGxpa2U6CisvLyAgICAgICAgLy8gMDogIjEiCisvLyAgICAgICAgLy8gMTogIjEyIiAtPiAiOSIgLT4gIjIiCisvLyAgICAgICAgRW51bWVyYXRpb24gZW4gPSBodC5lbGVtZW50cygpOworLy8gICAgICAgIC8vIGNhY2hlIHRoZSBmaXJzdCBlbnRyeQorLy8gICAgICAgIGVuLmhhc01vcmVFbGVtZW50cygpOworLy8gICAgICAgIEl0ZXJhdG9yIGl0ID0gaHQua2V5U2V0KCkuaXRlcmF0b3IoKTsKKy8vICAgICAgICAvLyB0aGlzIGlzIG1vc3RseSBhIGNvcHkgb2YgdGhlIHRlc3QgaW4gdGVzdF9lbGVtZW50c19zdWJ0ZXN0MCgpCisvLyAgICAgICAgLy8gdGVzdCByZW1vdmluZyB3aXRoIHRoZSBpdGVyYXRvciBkb2VzIG5vdCBudWxsIHRoZSB2YWx1ZXMKKy8vICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisvLyAgICAgICAgICAgIFN0cmluZyBrZXkgPSAoU3RyaW5nKSBpdC5uZXh0KCk7CisvLyAgICAgICAgICAgIGlmICgiMTIiLmVxdWFscyhrZXkpIHx8ICI5Ii5lcXVhbHMoa2V5KSkgeworLy8gICAgICAgICAgICAgICAgaXQucmVtb3ZlKCk7CisvLyAgICAgICAgICAgIH0KKy8vICAgICAgICB9CisvLyAgICAgICAgaXQucmVtb3ZlKCk7CisvLyAgICAgICAgYm9vbGVhbiBleGNlcHRpb24gPSBmYWxzZTsKKy8vICAgICAgICB0cnkgeworLy8gICAgICAgICAgICAvLyBjYWNoZWQgIjEyIgorLy8gICAgICAgICAgICBPYmplY3QgcmVzdWx0ID0gZW4ubmV4dEVsZW1lbnQoKTsKKy8vICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidW5leHBlY3RlZDogIiArIHJlc3VsdCwgImQiLmVxdWFscyhyZXN1bHQpKTsKKy8vICAgICAgICAgICAgLy8gbmV4dCBpcyByZW1vdmVkICI5IgorLy8gICAgICAgICAgICByZXN1bHQgPSBlbi5uZXh0RWxlbWVudCgpOworLy8gICAgICAgICAgICBhc3NlcnRUcnVlKCJ1bmV4cGVjdGVkOiAiICsgcmVzdWx0LCAiYyIuZXF1YWxzKHJlc3VsdCkpOworLy8gICAgICAgICAgICByZXN1bHQgPSBlbi5uZXh0RWxlbWVudCgpOworLy8gICAgICAgICAgICBhc3NlcnRUcnVlKCJ1bmV4cGVjdGVkOiAiICsgcmVzdWx0LCAiYiIuZXF1YWxzKHJlc3VsdCkpOworLy8gICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworLy8gICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworLy8gICAgICAgIH0KKy8vICAgICAgICBhc3NlcnRUcnVlKCJ1bmV4cGVjdGVkIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24iLCAhZXhjZXB0aW9uKTsKKy8vICAgIH0KKy8vIEVORCBhbmRyb2lkLXJlbW92ZWQKKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNodGFibGUjcHV0KGphdmEubGFuZy5PYmplY3QsIGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wdXRMamF2YV9sYW5nX09iamVjdExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdAorICAgICAgICAvLyBqYXZhLnV0aWwuSGFzaHRhYmxlLnB1dChqYXZhLmxhbmcuT2JqZWN0LCBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBIYXNodGFibGUgaCA9IGhhc2h0YWJsZUNsb25lKGh0MTAwKTsKKyAgICAgICAgSW50ZWdlciBrZXkgPSBuZXcgSW50ZWdlcigxMDApOworICAgICAgICBoLnB1dCgiVmFsdWUgMTAwIiwga2V5KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiS2V5L1ZhbHVlIG5vdCBpbnNlcnRlZCIsIGguc2l6ZSgpID09IDEgJiYgKGguY29udGFpbnMoa2V5KSkpOworCisgICAgICAgIC8vIFB1dCBpbnRvICJmdWxsIiB0YWJsZQorICAgICAgICBoID0gaGFzaHRhYmxlQ2xvbmUoaHRmdWxsKTsKKyAgICAgICAgaC5wdXQoIlZhbHVlIDEwMCIsIGtleSk7CisgICAgICAgIGFzc2VydFRydWUoIktleS9WYWx1ZSBub3QgaW5zZXJ0ZWQgaW50byBmdWxsIHRhYmxlIiwgaC5zaXplKCkgPT0gOAorICAgICAgICAgICAgICAgICYmIChoLmNvbnRhaW5zKGtleSkpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaC5wdXQobnVsbCwga2V5KTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBoLnB1dCgiVmFsdWUgMTAwIiwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaHRhYmxlI3B1dEFsbChqYXZhLnV0aWwuTWFwKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcHV0QWxsTGphdmFfdXRpbF9NYXAoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5IYXNodGFibGUucHV0QWxsKGphdmEudXRpbC5NYXApCisgICAgICAgIEhhc2h0YWJsZSBoID0gbmV3IEhhc2h0YWJsZSgpOworICAgICAgICBoLnB1dEFsbChodDEwKTsKKyAgICAgICAgRW51bWVyYXRpb24gZSA9IGtleVZlY3Rvci5lbGVtZW50cygpOworICAgICAgICB3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgT2JqZWN0IHggPSBlLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gcHV0IGFsbCBlbGVtZW50cyIsIGguZ2V0KHgpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgaHQxMC5nZXQoeCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBoLnB1dEFsbChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaHRhYmxlI3JlbW92ZShqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0CisgICAgICAgIC8vIGphdmEudXRpbC5IYXNodGFibGUucmVtb3ZlKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIEhhc2h0YWJsZSBoID0gaGFzaHRhYmxlQ2xvbmUoaHRmdWxsKTsKKyAgICAgICAgT2JqZWN0IGsgPSBoLnJlbW92ZSgiRktleSAwIik7CisgICAgICAgIGFzc2VydFRydWUoIlJlbW92ZSBmYWlsZWQiLCAhaC5jb250YWluc0tleSgiRktleSAwIikgfHwgayA9PSBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChoLnJlbW92ZSgiRktleSAwIikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBoLnJlbW92ZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5IYXNodGFibGUjc2l6ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zaXplKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudXRpbC5IYXNodGFibGUuc2l6ZSgpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGludmFsaWQgc2l6ZSIsIGh0MTAuc2l6ZSgpID09IDEwCisgICAgICAgICAgICAgICAgJiYgKGh0MTAwLnNpemUoKSA9PSAwKSk7CisKKyAgICAgICAgZmluYWwgSGFzaHRhYmxlIGh0ID0gbmV3IEhhc2h0YWJsZSgpOworICAgICAgICBodC5wdXQoIjAiLCAiIik7CisgICAgICAgIFRocmVhZCB0MSA9IG5ldyBUaHJlYWQoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgd2hpbGUgKGh0LnNpemUoKSA+IDApCisgICAgICAgICAgICAgICAgICAgIDsKKyAgICAgICAgICAgICAgICBodC5wdXQoImZpbmFsIiwgIiIpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICB0MS5zdGFydCgpOworICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IDEwMDAwOyBpKyspIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoaHQpIHsKKyAgICAgICAgICAgICAgICBodC5yZW1vdmUoU3RyaW5nLnZhbHVlT2YoaSAtIDEpKTsKKyAgICAgICAgICAgICAgICBodC5wdXQoU3RyaW5nLnZhbHVlT2YoaSksICIiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCBzaXplOworICAgICAgICAgICAgaWYgKChzaXplID0gaHQuc2l6ZSgpKSAhPSAxKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHJlc3VsdCA9ICJTaXplIGlzIG5vdCAxOiAiICsgc2l6ZSArICIgIiArIGh0OworICAgICAgICAgICAgICAgIC8vIHRlcm1pbmF0ZSB0aGUgdGhyZWFkCisgICAgICAgICAgICAgICAgaHQuY2xlYXIoKTsKKyAgICAgICAgICAgICAgICBmYWlsKHJlc3VsdCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gdGVybWluYXRlIHRoZSB0aHJlYWQKKyAgICAgICAgaHQuY2xlYXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaHRhYmxlI3RvU3RyaW5nKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLlN0cmluZyBqYXZhLnV0aWwuSGFzaHRhYmxlLnRvU3RyaW5nKCkKKyAgICAgICAgSGFzaHRhYmxlIGggPSBuZXcgSGFzaHRhYmxlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHRvU3RyaW5nIGZvciBFbXB0eSB0YWJsZSIsCisgICAgICAgICAgICAgICAgInt9IiwgaC50b1N0cmluZygpKTsKKworICAgICAgICBoLnB1dCgib25lIiwgIjEiKTsKKyAgICAgICAgaC5wdXQoInR3byIsIGgpOworICAgICAgICBoLnB1dChoLCAiMyIpOworICAgICAgICBoLnB1dChoLCBoKTsKKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGgudG9TdHJpbmcoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgic2hvdWxkIGNvbnRhaW4gc2VsZiByZWYiLCByZXN1bHQuaW5kZXhPZigiKHRoaXMiKSA+IC0xKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSGFzaHRhYmxlI3ZhbHVlcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF92YWx1ZXMoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuQ29sbGVjdGlvbiBqYXZhLnV0aWwuSGFzaHRhYmxlLnZhbHVlcygpCisgICAgICAgIENvbGxlY3Rpb24gYyA9IGh0MTAudmFsdWVzKCk7CisgICAgICAgIEVudW1lcmF0aW9uIGUgPSBlbG1WZWN0b3IuZWxlbWVudHMoKTsKKyAgICAgICAgd2hpbGUgKGUuaGFzTW9yZUVsZW1lbnRzKCkpCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWVzIiwgYy5jb250YWlucyhlLm5leHRFbGVtZW50KCkpKTsKKworLy8gQkVHSU4gYW5kcm9pZC1yZW1vdmVkCisvLyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoIk5vdCBzeW5jaHJvbml6ZWQiLAorLy8gICAgICAgICAgICAgICAgImphdmEudXRpbC5Db2xsZWN0aW9ucyRTeW5jaHJvbml6ZWRDb2xsZWN0aW9uIiwgYy5nZXRDbGFzcygpLmdldE5hbWUoKSk7CisvLyBFTkQgYW5kcm9pZC1yZW1vdmVkCisKKyAgICAgICAgSGFzaHRhYmxlIG15SGFzaHRhYmxlID0gbmV3IEhhc2h0YWJsZSgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKQorICAgICAgICAgICAgbXlIYXNodGFibGUucHV0KG5ldyBJbnRlZ2VyKGkpLCBuZXcgSW50ZWdlcihpKSk7CisgICAgICAgIENvbGxlY3Rpb24gdmFsdWVzID0gbXlIYXNodGFibGUudmFsdWVzKCk7CisgICAgICAgIG5ldyBTdXBwb3J0X1VubW9kaWZpYWJsZUNvbGxlY3Rpb25UZXN0KAorICAgICAgICAgICAgICAgICJUZXN0IFJldHVybmVkIENvbGxlY3Rpb24gRnJvbSBIYXNodGFibGUudmFsdWVzKCkiLCB2YWx1ZXMpCisgICAgICAgICAgICAgICAgLnJ1blRlc3QoKTsKKyAgICAgICAgdmFsdWVzLnJlbW92ZShuZXcgSW50ZWdlcigwKSk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIlJlbW92aW5nIGZyb20gdGhlIHZhbHVlcyBjb2xsZWN0aW9uIHNob3VsZCByZW1vdmUgZnJvbSB0aGUgb3JpZ2luYWwgbWFwIiwKKyAgICAgICAgICAgICAgICAhbXlIYXNodGFibGUuY29udGFpbnNWYWx1ZShuZXcgSW50ZWdlcigwKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlZ3Jlc3Npb24gVGVzdCBmb3IgSklSQSAyMTgxCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9lbnRyeVNldF9yZW1vdmUoKQorICAgIHsKKyAgICAgICAgSGFzaHRhYmxlPFN0cmluZyxTdHJpbmc+IGhhc2h0YWJsZSA9IG5ldyBIYXNodGFibGU8U3RyaW5nLFN0cmluZz4oKTsKKyAgICAgICAgaGFzaHRhYmxlLnB1dCgibXkubm9uZXhpc3RlbnQucHJvcCIsICJBQUEiKTsKKyAgICAgICAgaGFzaHRhYmxlLnB1dCggInBhcnNlLmVycm9yIiwgIkJCQiIgKTsKKyAgICAgICAgSXRlcmF0b3I8TWFwLkVudHJ5PFN0cmluZyxTdHJpbmc+PiBpdGVyYXRvciA9CisgICAgICAgICAgICBoYXNodGFibGUuZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICB3aGlsZShpdGVyYXRvci5oYXNOZXh0KCkpCisgICAgICAgIHsKKyAgICAgICAgICAgIE1hcC5FbnRyeSBlbnRyeSA9IGl0ZXJhdG9yLm5leHQoKTsKKyAgICAgICAgICAgIGZpbmFsIE9iamVjdCB2YWx1ZSA9IGVudHJ5LmdldFZhbHVlKCk7CisgICAgICAgICAgICBpZih2YWx1ZS5lcXVhbHMoIkFBQSIpKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgaXRlcmF0b3IucmVtb3ZlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoaGFzaHRhYmxlLmNvbnRhaW5zS2V5KCJteS5ub25leGlzdGVudC5wcm9wIikpOworICAgIH0KKworICAgIGNsYXNzIE1vY2tfSGFzaHRhYmxlIGV4dGVuZHMgSGFzaHRhYmxlIHsKKyAgICAgICAgYm9vbGVhbiBmbGFnID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIE1vY2tfSGFzaHRhYmxlKGludCBpKSB7CisgICAgICAgICAgICBzdXBlcihpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZWhhc2goKSB7CisgICAgICAgICAgICBmbGFnID0gdHJ1ZTsKKyAgICAgICAgICAgIHN1cGVyLnJlaGFzaCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNSZWhhc2hlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBmbGFnOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZWhhc2goKSB7CisgICAgICAgIE1vY2tfSGFzaHRhYmxlIG1odCA9IG5ldyBNb2NrX0hhc2h0YWJsZSg1KTsKKworICAgICAgICBhc3NlcnRGYWxzZShtaHQuaXNSZWhhc2hlZCgpKTsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICAgICAgICAgIG1odC5wdXQoaSwgIk5ldyB2YWx1ZSIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUobWh0LmlzUmVoYXNoZWQoKSk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIEhhc2h0YWJsZSBoYXNodGFibGVDbG9uZShIYXNodGFibGUgcykgeworICAgICAgICByZXR1cm4gKEhhc2h0YWJsZSkgcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdXAgdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBvcGVuIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzIG1ldGhvZAorICAgICAqIGlzIGNhbGxlZCBiZWZvcmUgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworCisgICAgICAgIGh0MTAgPSBuZXcgSGFzaHRhYmxlKDEwKTsKKyAgICAgICAgaHQxMDAgPSBuZXcgSGFzaHRhYmxlKDEwMCk7CisgICAgICAgIGh0ZnVsbCA9IG5ldyBIYXNodGFibGUoMTApOworICAgICAgICBrZXlWZWN0b3IgPSBuZXcgVmVjdG9yKDEwKTsKKyAgICAgICAgZWxtVmVjdG9yID0gbmV3IFZlY3RvcigxMCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgICAgICAgICBodDEwLnB1dCgiS2V5ICIgKyBpLCAiVmFsICIgKyBpKTsKKyAgICAgICAgICAgIGtleVZlY3Rvci5hZGRFbGVtZW50KCJLZXkgIiArIGkpOworICAgICAgICAgICAgZWxtVmVjdG9yLmFkZEVsZW1lbnQoIlZhbCAiICsgaSk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDc7IGkrKykKKyAgICAgICAgICAgIGh0ZnVsbC5wdXQoIkZLZXkgIiArIGksICJGVmFsICIgKyBpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWFycyBkb3duIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgY2xvc2UgYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMKKyAgICAgKiBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgaHQxMCA9IG51bGw7CisgICAgICAgIGh0MTAwID0gbnVsbDsKKyAgICAgICAgaHRmdWxsID0gbnVsbDsKKyAgICAgICAga2V5VmVjdG9yID0gbnVsbDsKKyAgICAgICAgZWxtVmVjdG9yID0gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9JZGVudGl0eUhhc2hNYXBUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9JZGVudGl0eUhhc2hNYXBUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2JmMTI1NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0lkZW50aXR5SGFzaE1hcFRlc3QuamF2YQpAQCAtMCwwICsxLDQ5NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS51dGlsLkFic3RyYWN0TWFwOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CisKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfTWFwVGVzdDI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkudGVzdGZyYW1ld29yay5zZXJpYWxpemF0aW9uLlNlcmlhbGl6YXRpb25UZXN0OworCitwdWJsaWMgY2xhc3MgSWRlbnRpdHlIYXNoTWFwVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIElEID0gImhlbGxvIjsKKworICAgIGNsYXNzIE1vY2tNYXAgZXh0ZW5kcyBBYnN0cmFjdE1hcCB7CisgICAgICAgIHB1YmxpYyBTZXQgZW50cnlTZXQoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgaW50IHNpemUoKXsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfQorICAgIC8qCisgICAgICogVE9ETzogY2hhbmdlIGFsbCB0aGUgc3RhdGVtZW50cyB0ZXN0aW5nIHRoZSBrZXlzIGFuZCB2YWx1ZXMgd2l0aCBlcXVhbHMoKQorICAgICAqIG1ldGhvZCB0byBjaGVjayBmb3IgcmVmZXJlbmNlIGVxdWFsaXR5IGluc3RlYWQKKyAgICAgKi8KKworICAgIElkZW50aXR5SGFzaE1hcCBobTsKKworICAgIGZpbmFsIHN0YXRpYyBpbnQgaG1TaXplID0gMTAwMDsKKworICAgIE9iamVjdFtdIG9iakFycmF5OworCisgICAgT2JqZWN0W10gb2JqQXJyYXkyOworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLklkZW50aXR5SGFzaE1hcCNJZGVudGl0eUhhc2hNYXAoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwKCkKKyAgICAgICAgbmV3IFN1cHBvcnRfTWFwVGVzdDIobmV3IElkZW50aXR5SGFzaE1hcCgpKS5ydW5UZXN0KCk7CisKKyAgICAgICAgSWRlbnRpdHlIYXNoTWFwIGhtMiA9IG5ldyBJZGVudGl0eUhhc2hNYXAoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDcmVhdGVkIGluY29ycmVjdCBJZGVudGl0eUhhc2hNYXAiLCAwLCBobTIuc2l6ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwI0lkZW50aXR5SGFzaE1hcChpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwKGludCkKKyAgICAgICAgSWRlbnRpdHlIYXNoTWFwIGhtMiA9IG5ldyBJZGVudGl0eUhhc2hNYXAoNSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQ3JlYXRlZCBpbmNvcnJlY3QgSWRlbnRpdHlIYXNoTWFwIiwgMCwgaG0yLnNpemUoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSWRlbnRpdHlIYXNoTWFwKC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkZhaWxlZCB0byB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZm9yIGluaXRpYWwgY2FwYWNpdHkgPCAwIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBJZGVudGl0eUhhc2hNYXAgZW1wdHkgPSBuZXcgSWRlbnRpdHlIYXNoTWFwKDApOworICAgICAgICBhc3NlcnROdWxsKCJFbXB0eSBJZGVudGl0eUhhc2hNYXAgYWNjZXNzIiwgZW1wdHkuZ2V0KCJub3RoaW5nIikpOworICAgICAgICBlbXB0eS5wdXQoInNvbWV0aGluZyIsICJoZXJlIik7CisgICAgICAgIGFzc2VydFRydWUoImNhbm5vdCBnZXQgZWxlbWVudCIsIGVtcHR5LmdldCgic29tZXRoaW5nIikgPT0gImhlcmUiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwI0lkZW50aXR5SGFzaE1hcChqYXZhLnV0aWwuTWFwKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV91dGlsX01hcCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5JZGVudGl0eUhhc2hNYXAoamF2YS51dGlsLk1hcCkKKyAgICAgICAgTWFwIG15TWFwID0gbmV3IFRyZWVNYXAoKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCBobVNpemU7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIG15TWFwLnB1dChvYmpBcnJheTJbY291bnRlcl0sIG9iakFycmF5W2NvdW50ZXJdKTsKKyAgICAgICAgSWRlbnRpdHlIYXNoTWFwIGhtMiA9IG5ldyBJZGVudGl0eUhhc2hNYXAobXlNYXApOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGhtU2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGNvbnN0cnVjdCBjb3JyZWN0IElkZW50aXR5SGFzaE1hcCIsIGhtCisgICAgICAgICAgICAgICAgICAgIC5nZXQob2JqQXJyYXkyW2NvdW50ZXJdKSA9PSBobTIuZ2V0KG9iakFycmF5Mltjb3VudGVyXSkpOworCisgICAgICAgIE1hcCBtb2NrTWFwID0gbmV3IE1vY2tNYXAoKTsKKyAgICAgICAgaG0yID0gbmV3IElkZW50aXR5SGFzaE1hcChtb2NrTWFwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIHNob3VsZCBiZSAwIiwgMCwgaG0yLnNpemUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBJZGVudGl0eUhhc2hNYXAobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwI2NsZWFyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NsZWFyKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwLmNsZWFyKCkKKyAgICAgICAgaG0uY2xlYXIoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDbGVhciBmYWlsZWQgdG8gcmVzZXQgc2l6ZSIsIDAsIGhtLnNpemUoKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaG1TaXplOyBpKyspCisgICAgICAgICAgICBhc3NlcnROdWxsKCJGYWlsZWQgdG8gY2xlYXIgYWxsIGVsZW1lbnRzIiwKKyAgICAgICAgICAgICAgICAgICAgaG0uZ2V0KG9iakFycmF5MltpXSkpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLklkZW50aXR5SGFzaE1hcCNjbG9uZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jbG9uZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QgamF2YS51dGlsLklkZW50aXR5SGFzaE1hcC5jbG9uZSgpCisgICAgICAgIElkZW50aXR5SGFzaE1hcCBobTIgPSAoSWRlbnRpdHlIYXNoTWFwKSBobS5jbG9uZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJDbG9uZSBhbnN3ZXJlZCBlcXVpdmFsZW50IElkZW50aXR5SGFzaE1hcCIsIGhtMiAhPSBobSk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgaG1TaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJDbG9uZSBhbnN3ZXJlZCB1bmVxdWFsIElkZW50aXR5SGFzaE1hcCIsIGhtCisgICAgICAgICAgICAgICAgICAgIC5nZXQob2JqQXJyYXkyW2NvdW50ZXJdKSA9PSBobTIuZ2V0KG9iakFycmF5Mltjb3VudGVyXSkpOworCisgICAgICAgIElkZW50aXR5SGFzaE1hcCBtYXAgPSBuZXcgSWRlbnRpdHlIYXNoTWFwKCk7CisgICAgICAgIG1hcC5wdXQoImtleSIsICJ2YWx1ZSIpOworICAgICAgICAvLyBnZXQgdGhlIGtleVNldCgpIGFuZCB2YWx1ZXMoKSBvbiB0aGUgb3JpZ2luYWwgTWFwCisgICAgICAgIFNldCBrZXlzID0gbWFwLmtleVNldCgpOworICAgICAgICBDb2xsZWN0aW9uIHZhbHVlcyA9IG1hcC52YWx1ZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZXMoKSBkb2VzIG5vdCB3b3JrIiwKKyAgICAgICAgICAgICAgICAidmFsdWUiLCB2YWx1ZXMuaXRlcmF0b3IoKS5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImtleVNldCgpIGRvZXMgbm90IHdvcmsiLAorICAgICAgICAgICAgICAgICJrZXkiLCBrZXlzLml0ZXJhdG9yKCkubmV4dCgpKTsKKyAgICAgICAgQWJzdHJhY3RNYXAgbWFwMiA9IChBYnN0cmFjdE1hcCkgbWFwLmNsb25lKCk7CisgICAgICAgIG1hcDIucHV0KCJrZXkiLCAidmFsdWUyIik7CisgICAgICAgIENvbGxlY3Rpb24gdmFsdWVzMiA9IG1hcDIudmFsdWVzKCk7CisgICAgICAgIGFzc2VydFRydWUoInZhbHVlcygpIGlzIGlkZW50aWNhbCIsIHZhbHVlczIgIT0gdmFsdWVzKTsKKyAgICAgICAgLy8gdmFsdWVzKCkgYW5kIGtleVNldCgpIG9uIHRoZSBjbG9uZWQoKSBtYXAgc2hvdWxkIGJlIGRpZmZlcmVudAorICAgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlcygpIHdhcyBub3QgY2xvbmVkIiwKKyAgICAgICAgICAgICAgICAidmFsdWUyIiwgdmFsdWVzMi5pdGVyYXRvcigpLm5leHQoKSk7CisgICAgICAgIG1hcDIuY2xlYXIoKTsKKyAgICAgICAgbWFwMi5wdXQoImtleTIiLCAidmFsdWUzIik7CisgICAgICAgIFNldCBrZXkyID0gbWFwMi5rZXlTZXQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgia2V5U2V0KCkgaXMgaWRlbnRpY2FsIiwga2V5MiAhPSBrZXlzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJrZXlTZXQoKSB3YXMgbm90IGNsb25lZCIsCisgICAgICAgICAgICAgICAgImtleTIiLCBrZXkyLml0ZXJhdG9yKCkubmV4dCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwI2NvbnRhaW5zS2V5KGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jb250YWluc0tleUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbgorICAgICAgICAvLyBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwLmNvbnRhaW5zS2V5KGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciB2YWxpZCBrZXkiLCBobQorICAgICAgICAgICAgICAgIC5jb250YWluc0tleShvYmpBcnJheTJbMjNdKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHRydWUgZm9yIGNvcHkgb2YgdmFsaWQga2V5IiwgIWhtCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zS2V5KG5ldyBJbnRlZ2VyKDIzKS50b1N0cmluZygpKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHRydWUgZm9yIGludmFsaWQga2V5IiwgIWhtLmNvbnRhaW5zS2V5KCJLS0RLREtEIikpOworCisgICAgICAgIElkZW50aXR5SGFzaE1hcCBtID0gbmV3IElkZW50aXR5SGFzaE1hcCgpOworICAgICAgICBtLnB1dChudWxsLCAidGVzdCIpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgd2l0aCBudWxsIGtleSIsIG0uY29udGFpbnNLZXkobnVsbCkpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgd2l0aCBtaXNzaW5nIGtleSBtYXRjaGluZyBudWxsIGhhc2giLCAhbQorICAgICAgICAgICAgICAgIC5jb250YWluc0tleShuZXcgSW50ZWdlcigwKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5JZGVudGl0eUhhc2hNYXAjY29udGFpbnNWYWx1ZShqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY29udGFpbnNWYWx1ZUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbgorICAgICAgICAvLyBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwLmNvbnRhaW5zVmFsdWUoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIHZhbGlkIHZhbHVlIiwgaG0KKyAgICAgICAgICAgICAgICAuY29udGFpbnNWYWx1ZShvYmpBcnJheVsxOV0pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgaW52YWxpZCB2YWxpZSIsICFobQorICAgICAgICAgICAgICAgIC5jb250YWluc1ZhbHVlKG5ldyBJbnRlZ2VyKC05KSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5JZGVudGl0eUhhc2hNYXAjZW50cnlTZXQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZW50cnlTZXQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuU2V0IGphdmEudXRpbC5JZGVudGl0eUhhc2hNYXAuZW50cnlTZXQoKQorICAgICAgICBTZXQgcyA9IGhtLmVudHJ5U2V0KCk7CisgICAgICAgIEl0ZXJhdG9yIGkgPSBzLml0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHNldCBvZiBpbmNvcnJlY3Qgc2l6ZSIsIGhtLnNpemUoKSA9PSBzLnNpemUoKSk7CisgICAgICAgIHdoaWxlIChpLmhhc05leHQoKSkgeworICAgICAgICAgICAgTWFwLkVudHJ5IG0gPSAoTWFwLkVudHJ5KSBpLm5leHQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBlbnRyeSBzZXQiLCBobS5jb250YWluc0tleShtCisgICAgICAgICAgICAgICAgICAgIC5nZXRLZXkoKSkKKyAgICAgICAgICAgICAgICAgICAgJiYgaG0uY29udGFpbnNWYWx1ZShtLmdldFZhbHVlKCkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5JZGVudGl0eUhhc2hNYXAjZ2V0KGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QKKyAgICAgICAgLy8gamF2YS51dGlsLklkZW50aXR5SGFzaE1hcC5nZXQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgYXNzZXJ0TnVsbCgiR2V0IHJldHVybmVkIG5vbi1udWxsIGZvciBub24gZXhpc3RlbnQga2V5IiwKKyAgICAgICAgICAgICAgICBobS5nZXQoIlQiKSk7CisgICAgICAgIGhtLnB1dCgiVCIsICJIRUxMTyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkdldCByZXR1cm5lZCBpbmNvcmVjY3QgdmFsdWUgZm9yIGV4aXN0aW5nIGtleSIsICJIRUxMTyIsIGhtLmdldCgiVCIpCisgICAgICAgICAgICAgICAgKTsKKworICAgICAgICBJZGVudGl0eUhhc2hNYXAgbSA9IG5ldyBJZGVudGl0eUhhc2hNYXAoKTsKKyAgICAgICAgbS5wdXQobnVsbCwgInRlc3QiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgd2l0aCBudWxsIGtleSIsICJ0ZXN0IiwgbS5nZXQobnVsbCkpOworICAgICAgICBhc3NlcnROdWxsKCJGYWlsZWQgd2l0aCBtaXNzaW5nIGtleSBtYXRjaGluZyBudWxsIGhhc2giLCBtCisgICAgICAgICAgICAgICAgLmdldChuZXcgSW50ZWdlcigwKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5JZGVudGl0eUhhc2hNYXAjaXNFbXB0eSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0VtcHR5KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwLmlzRW1wdHkoKQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgbmV3IG1hcCIsIG5ldyBJZGVudGl0eUhhc2hNYXAoKQorICAgICAgICAgICAgICAgIC5pc0VtcHR5KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCB0cnVlIGZvciBub24tZW1wdHkiLCAhaG0uaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwI2tleVNldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9rZXlTZXQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuU2V0IGphdmEudXRpbC5JZGVudGl0eUhhc2hNYXAua2V5U2V0KCkKKyAgICAgICAgU2V0IHMgPSBobS5rZXlTZXQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgc2V0IG9mIGluY29ycmVjdCBzaXplKCkiLCBzLnNpemUoKSA9PSBobS5zaXplKCkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iakFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBzZXQgZG9lcyBub3QgY29udGFpbiBhbGwga2V5cyIsIHMKKyAgICAgICAgICAgICAgICAgICAgLmNvbnRhaW5zKG9iakFycmF5MltpXSkpOworICAgICAgICB9CisKKyAgICAgICAgSWRlbnRpdHlIYXNoTWFwIG0gPSBuZXcgSWRlbnRpdHlIYXNoTWFwKCk7CisgICAgICAgIG0ucHV0KG51bGwsICJ0ZXN0Iik7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB3aXRoIG51bGwga2V5IiwgbS5rZXlTZXQoKS5jb250YWlucyhudWxsKSk7CisgICAgICAgIGFzc2VydE51bGwoIkZhaWxlZCB3aXRoIG51bGwga2V5IiwgbS5rZXlTZXQoKS5pdGVyYXRvcigpLm5leHQoKSk7CisKKyAgICAgICAgTWFwIG1hcCA9IG5ldyBJZGVudGl0eUhhc2hNYXAoMTAxKTsKKyAgICAgICAgbWFwLnB1dChuZXcgSW50ZWdlcigxKSwgIjEiKTsKKyAgICAgICAgbWFwLnB1dChuZXcgSW50ZWdlcigxMDIpLCAiMTAyIik7CisgICAgICAgIG1hcC5wdXQobmV3IEludGVnZXIoMjAzKSwgIjIwMyIpOworICAgICAgICBJdGVyYXRvciBpdCA9IG1hcC5rZXlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICBJbnRlZ2VyIHJlbW92ZTEgPSAoSW50ZWdlcikgaXQubmV4dCgpOworICAgICAgICBpdC5oYXNOZXh0KCk7CisgICAgICAgIGl0LnJlbW92ZSgpOworICAgICAgICBJbnRlZ2VyIHJlbW92ZTIgPSAoSW50ZWdlcikgaXQubmV4dCgpOworICAgICAgICBpdC5yZW1vdmUoKTsKKyAgICAgICAgQXJyYXlMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KEFycmF5cy5hc0xpc3QobmV3IEludGVnZXJbXSB7CisgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoMSksIG5ldyBJbnRlZ2VyKDEwMiksIG5ldyBJbnRlZ2VyKDIwMykgfSkpOworICAgICAgICBsaXN0LnJlbW92ZShyZW1vdmUxKTsKKyAgICAgICAgbGlzdC5yZW1vdmUocmVtb3ZlMik7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHJlc3VsdCIsIGl0Lm5leHQoKS5lcXVhbHMobGlzdC5nZXQoMCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzaXplIiwgMSwgbWFwLnNpemUoKSk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIGNvbnRlbnRzIiwgbWFwLmtleVNldCgpLml0ZXJhdG9yKCkubmV4dCgpLmVxdWFscygKKyAgICAgICAgICAgICAgICBsaXN0LmdldCgwKSkpOworCisgICAgICAgIE1hcCBtYXAyID0gbmV3IElkZW50aXR5SGFzaE1hcCgxMDEpOworICAgICAgICBtYXAyLnB1dChuZXcgSW50ZWdlcigxKSwgIjEiKTsKKyAgICAgICAgbWFwMi5wdXQobmV3IEludGVnZXIoNCksICI0Iik7CisgICAgICAgIEl0ZXJhdG9yIGl0MiA9IG1hcDIua2V5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgICAgSW50ZWdlciByZW1vdmUzID0gKEludGVnZXIpIGl0Mi5uZXh0KCk7CisgICAgICAgIEludGVnZXIgbmV4dDsKKyAgICAgICAgaWYgKHJlbW92ZTMuaW50VmFsdWUoKSA9PSAxKQorICAgICAgICAgICAgbmV4dCA9IG5ldyBJbnRlZ2VyKDQpOworICAgICAgICBlbHNlCisgICAgICAgICAgICBuZXh0ID0gbmV3IEludGVnZXIoMSk7CisgICAgICAgIGl0Mi5oYXNOZXh0KCk7CisgICAgICAgIGl0Mi5yZW1vdmUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcmVzdWx0IDIiLCBpdDIubmV4dCgpLmVxdWFscyhuZXh0KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSAyIiwgMSwgbWFwMi5zaXplKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBjb250ZW50cyAyIiwgbWFwMi5rZXlTZXQoKS5pdGVyYXRvcigpLm5leHQoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgbmV4dCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5JZGVudGl0eUhhc2hNYXAjcHV0KGphdmEubGFuZy5PYmplY3QsIGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wdXRMamF2YV9sYW5nX09iamVjdExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdAorICAgICAgICAvLyBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwLnB1dChqYXZhLmxhbmcuT2JqZWN0LCBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBobS5wdXQoIktFWSIsICJWQUxVRSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCB0byBpbnN0YWxsIGtleS92YWx1ZSBwYWlyIiwKKyAgICAgICAgICAgICAgICAiVkFMVUUiLCBobS5nZXQoIktFWSIpKTsKKworICAgICAgICBJZGVudGl0eUhhc2hNYXAgbSA9IG5ldyBJZGVudGl0eUhhc2hNYXAoKTsKKyAgICAgICAgU2hvcnQgczAgPSBuZXcgU2hvcnQoKHNob3J0KSAwKTsKKyAgICAgICAgbS5wdXQoczAsICJzaG9ydCIpOworICAgICAgICBtLnB1dChudWxsLCAidGVzdCIpOworICAgICAgICBJbnRlZ2VyIGkwID0gbmV3IEludGVnZXIoMCk7CisgICAgICAgIG0ucHV0KGkwLCAiaW50Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIGFkZGluZyB0byBidWNrZXQgY29udGFpbmluZyBudWxsIiwKKyAgICAgICAgICAgICAgICAic2hvcnQiLCBtLmdldChzMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCBhZGRpbmcgdG8gYnVja2V0IGNvbnRhaW5pbmcgbnVsbDIiLCAiaW50IiwgbS5nZXQoaTApCisgICAgICAgICAgICAgICAgKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwI3B1dEFsbChqYXZhLnV0aWwuTWFwKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcHV0QWxsTGphdmFfdXRpbF9NYXAoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5JZGVudGl0eUhhc2hNYXAucHV0QWxsKGphdmEudXRpbC5NYXApCisgICAgICAgIElkZW50aXR5SGFzaE1hcCBobTIgPSBuZXcgSWRlbnRpdHlIYXNoTWFwKCk7CisgICAgICAgIGhtMi5wdXRBbGwoaG0pOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDA7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBjbGVhciBhbGwgZWxlbWVudHMiLCBobTIuZ2V0KG9iakFycmF5MltpXSkKKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscygobmV3IEludGVnZXIoaSkpKSk7CisKKyAgICAgICAgaG0yID0gbmV3IElkZW50aXR5SGFzaE1hcCgpOworICAgICAgICBNYXAgbW9ja01hcCA9IG5ldyBNb2NrTWFwKCk7CisgICAgICAgIGhtMi5wdXRBbGwobW9ja01hcCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBzaG91bGQgYmUgMCIsIDAsIGhtMi5zaXplKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBobTIucHV0QWxsKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLklkZW50aXR5SGFzaE1hcCNyZW1vdmUoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlbW92ZUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdAorICAgICAgICAvLyBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwLnJlbW92ZShqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBpbnQgc2l6ZSA9IGhtLnNpemUoKTsKKyAgICAgICAgSW50ZWdlciB4ID0gKChJbnRlZ2VyKSBobS5yZW1vdmUob2JqQXJyYXkyWzldKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJlbW92ZSByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCB4LmVxdWFscyhuZXcgSW50ZWdlcig5KSkpOworICAgICAgICBhc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVtb3ZlIGdpdmVuIGtleSIsIGhtLmdldChvYmpBcnJheTJbOV0pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGRlY3JlbWVudCBzaXplIiwgaG0uc2l6ZSgpID09IChzaXplIC0gMSkpOworICAgICAgICBhc3NlcnROdWxsKCJSZW1vdmUgb2Ygbm9uLWV4aXN0ZW50IGtleSByZXR1cm5lZCBub24tbnVsbCIsIGhtCisgICAgICAgICAgICAgICAgLnJlbW92ZSgiTENMQ0xDIikpOworCisgICAgICAgIElkZW50aXR5SGFzaE1hcCBtID0gbmV3IElkZW50aXR5SGFzaE1hcCgpOworICAgICAgICBtLnB1dChudWxsLCAidGVzdCIpOworICAgICAgICBhc3NlcnROdWxsKCJGYWlsZWQgd2l0aCBzYW1lIGhhc2ggYXMgbnVsbCIsCisgICAgICAgICAgICAgICAgbS5yZW1vdmUob2JqQXJyYXlbMF0pKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgd2l0aCBudWxsIGtleSIsICJ0ZXN0IiwgbS5yZW1vdmUobnVsbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5JZGVudGl0eUhhc2hNYXAjc2l6ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zaXplKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudXRpbC5JZGVudGl0eUhhc2hNYXAuc2l6ZSgpCisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHNpemUsICIsIChvYmpBcnJheS5sZW5ndGggKyAyKSwgaG0KKyAgICAgICAgICAgICAgICAuc2l6ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwI2VxdWFscyhqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIElkZW50aXR5SGFzaE1hcCBtYXBPbmUgPSBuZXcgSWRlbnRpdHlIYXNoTWFwKCk7CisgICAgICAgIElkZW50aXR5SGFzaE1hcCBtYXBUd28gPSBuZXcgSWRlbnRpdHlIYXNoTWFwKCk7CisgICAgICAgIElkZW50aXR5SGFzaE1hcCBtYXBUaHJlZSA9IG5ldyBJZGVudGl0eUhhc2hNYXAoKTsKKyAgICAgICAgSWRlbnRpdHlIYXNoTWFwIG1hcEZvdXIgPSBuZXcgSWRlbnRpdHlIYXNoTWFwKCk7CisKKyAgICAgICAgU3RyaW5nIG9uZSA9ICJvbmUiOworICAgICAgICBTdHJpbmcgYWxzb09uZSA9IG5ldyBTdHJpbmcob25lKTsgLy8gdXNlIHRoZSBuZXcgb3BlcmF0b3IgdG8gZW5zdXJlIGEKKyAgICAgICAgLy8gbmV3IHJlZmVyZW5jZSBpcyBjb25zdHJ1Y3RlZAorICAgICAgICBTdHJpbmcgdHdvID0gInR3byI7CisgICAgICAgIFN0cmluZyBhbHNvVHdvID0gbmV3IFN0cmluZyh0d28pOyAvLyB1c2UgdGhlIG5ldyBvcGVyYXRvciB0byBlbnN1cmUgYQorICAgICAgICAvLyBuZXcgcmVmZXJlbmNlIGlzIGNvbnN0cnVjdGVkCisKKyAgICAgICAgbWFwT25lLnB1dChvbmUsIHR3byk7CisgICAgICAgIG1hcEZvdXIucHV0KG9uZSwgdHdvKTsKKworICAgICAgICAvLyB0aGVzZSB0d28gYXJlIG5vdCBlcXVhbCB0byB0aGUgYWJvdmUgdHdvCisgICAgICAgIG1hcFR3by5wdXQoYWxzb09uZSwgdHdvKTsKKyAgICAgICAgbWFwVGhyZWUucHV0KG9uZSwgYWxzb1R3byk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmYWlsdXJlIG9mIGVxdWFsaXR5IG9mIElkZW50aXR5SGFzaE1hcHMiLCBtYXBPbmUsIG1hcEZvdXIpOworICAgICAgICBhc3NlcnRUcnVlKCJmYWlsdXJlIG9mIG5vbi1lcXVhbGl0eSBvZiBJZGVudGl0eUhhc2hNYXBzIG9uZSBhbmQgdHdvIiwKKyAgICAgICAgICAgICAgICAhbWFwT25lLmVxdWFscyhtYXBUd28pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZmFpbHVyZSBvZiBub24tZXF1YWxpdHkgb2YgSWRlbnRpdHlIYXNoTWFwcyBvbmUgYW5kIHRocmVlIiwKKyAgICAgICAgICAgICAgICAhbWFwT25lLmVxdWFscyhtYXBUaHJlZSkpOworICAgICAgICBhc3NlcnRUcnVlKCJmYWlsdXJlIG9mIG5vbi1lcXVhbGl0eSBvZiBJZGVudGl0eUhhc2hNYXBzIHR3byBhbmQgdGhyZWUiLAorICAgICAgICAgICAgICAgICFtYXBUd28uZXF1YWxzKG1hcFRocmVlKSk7CisKKyAgICAgICAgSGFzaE1hcCBoYXNoTWFwVHdvID0gbmV3IEhhc2hNYXAoKTsKKyAgICAgICAgSGFzaE1hcCBoYXNoTWFwVGhyZWUgPSBuZXcgSGFzaE1hcCgpOworICAgICAgICBoYXNoTWFwVHdvLnB1dChhbHNvT25lLCB0d28pOworICAgICAgICBoYXNoTWFwVGhyZWUucHV0KG9uZSwgYWxzb1R3byk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiZmFpbHVyZSBvZiBub24tZXF1YWxpdHkgb2YgSWRlbnRpdHlIYXNoTWFwcyBvbmUgYW5kIEhhc2htYXAgdHdvIiwKKyAgICAgICAgICAgICAgICAhbWFwT25lLmVxdWFscyhoYXNoTWFwVHdvKSk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgImZhaWx1cmUgb2Ygbm9uLWVxdWFsaXR5IG9mIElkZW50aXR5SGFzaE1hcHMgb25lIGFuZCBIYXNobWFwIHRocmVlIiwKKyAgICAgICAgICAgICAgICAhbWFwT25lLmVxdWFscyhoYXNoTWFwVGhyZWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwI3ZhbHVlcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF92YWx1ZXMoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuQ29sbGVjdGlvbgorICAgICAgICAvLyBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwLnZhbHVlcygpCisgICAgICAgIENvbGxlY3Rpb24gYyA9IGhtLnZhbHVlcygpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBjb2xsZWN0aW9uIG9mIGluY29ycmVjdCBzaXplKCkiLCBjLnNpemUoKSA9PSBobQorICAgICAgICAgICAgICAgIC5zaXplKCkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iakFycmF5Lmxlbmd0aDsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgY29sbGVjdGlvbiBkb2VzIG5vdCBjb250YWluIGFsbCBrZXlzIiwgYworICAgICAgICAgICAgICAgICAgICAuY29udGFpbnMob2JqQXJyYXlbaV0pKTsKKworICAgICAgICBJZGVudGl0eUhhc2hNYXAgbXlJZGVudGl0eUhhc2hNYXAgPSBuZXcgSWRlbnRpdHlIYXNoTWFwKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspCisgICAgICAgICAgICBteUlkZW50aXR5SGFzaE1hcC5wdXQob2JqQXJyYXkyW2ldLCBvYmpBcnJheVtpXSk7CisgICAgICAgIENvbGxlY3Rpb24gdmFsdWVzID0gbXlJZGVudGl0eUhhc2hNYXAudmFsdWVzKCk7CisgICAgICAgIHZhbHVlcy5yZW1vdmUob2JqQXJyYXlbMF0pOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJSZW1vdmluZyBmcm9tIHRoZSB2YWx1ZXMgY29sbGVjdGlvbiBzaG91bGQgcmVtb3ZlIGZyb20gdGhlIG9yaWdpbmFsIG1hcCIsCisgICAgICAgICAgICAgICAgIW15SWRlbnRpdHlIYXNoTWFwLmNvbnRhaW5zVmFsdWUob2JqQXJyYXkyWzBdKSk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwI1NlcmlhbGl6YXRpb24oKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfU2VyaWFsaXphdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBJZGVudGl0eUhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IG1hcCA9IG5ldyBJZGVudGl0eUhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgICAgIG1hcC5wdXQoSUQsICJ3b3JsZCIpOworICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLWFkZGVkCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgbnVsbCBrZXkgaW4gc2VyaWFsaXplZCBJZGVudGl0eUhhc2hNYXAgKDExNzg1NDkpCisgICAgICAgIC8vIFRvZ2V0aGVyIHdpdGggdGhpcyBjaGFuZ2UgdGhlIElkZW50aXR5SGFzaE1hcC5nb2xkZW4uc2VyIHJlc291cmNlCisgICAgICAgIC8vIHdhcyByZXBsYWNlZCBieSBhIHZlcnNpb24gdGhhdCBjb250YWlucyBhIG1hcCB3aXRoIGEgbnVsbCBrZXkuCisgICAgICAgIG1hcC5wdXQobnVsbCwgIm51bGwiKTsKKyAgICAgICAgLy8gRU5EIGFuZHJvaWQtYWRkZWQKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3QudmVyaWZ5U2VsZihtYXAsIGNvbXBhcmF0b3IpOworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdC52ZXJpZnlHb2xkZW4odGhpcywgbWFwLCBjb21wYXJhdG9yKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgb2JqQXJyYXkgPSBuZXcgT2JqZWN0W2htU2l6ZV07CisgICAgICAgIG9iakFycmF5MiA9IG5ldyBPYmplY3RbaG1TaXplXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvYmpBcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgb2JqQXJyYXlbaV0gPSBuZXcgSW50ZWdlcihpKTsKKyAgICAgICAgICAgIC8vIGFuZHJvaWQtY2hhbmdlZDogdGhlIGNvbnRhaW5zS2V5IHRlc3QgcmVxdWlyZXMgdW5pcXVlIHN0cmluZ3MuCisgICAgICAgICAgICBvYmpBcnJheTJbaV0gPSBuZXcgU3RyaW5nKG9iakFycmF5W2ldLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgaG0gPSBuZXcgSWRlbnRpdHlIYXNoTWFwKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2JqQXJyYXkubGVuZ3RoOyBpKyspCisgICAgICAgICAgICBobS5wdXQob2JqQXJyYXkyW2ldLCBvYmpBcnJheVtpXSk7CisgICAgICAgIGhtLnB1dCgidGVzdCIsIG51bGwpOworICAgICAgICBobS5wdXQobnVsbCwgInRlc3QiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWFycyBkb3duIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgY2xvc2UgYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMKKyAgICAgKiBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgb2JqQXJyYXkgPSBudWxsOworICAgICAgICBvYmpBcnJheTIgPSBudWxsOworICAgICAgICBobSA9IG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2VyaWFsaXphdGlvblRlc3QuU2VyaWFsaXphYmxlQXNzZXJ0IGNvbXBhcmF0b3IgPSBuZXcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VyaWFsaXphdGlvblRlc3QuU2VyaWFsaXphYmxlQXNzZXJ0KCkgeworCisgICAgICAgIHB1YmxpYyB2b2lkIGFzc2VydERlc2VyaWFsaXplZChTZXJpYWxpemFibGUgaW5pdGlhbCwgU2VyaWFsaXphYmxlIGRlc2VyaWFsaXplZCkgeworICAgICAgICAgICAgSWRlbnRpdHlIYXNoTWFwPFN0cmluZywgU3RyaW5nPiBpbml0aWFsTWFwID0gKElkZW50aXR5SGFzaE1hcDxTdHJpbmcsIFN0cmluZz4pIGluaXRpYWw7CisgICAgICAgICAgICBJZGVudGl0eUhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IGRlc2VyaWFNYXAgPSAoSWRlbnRpdHlIYXNoTWFwPFN0cmluZywgU3RyaW5nPikgZGVzZXJpYWxpemVkOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJzaG91bGQgYmUgZXF1YWwiLCBpbml0aWFsTWFwLnNpemUoKSwgZGVzZXJpYU1hcC5zaXplKCkpOworICAgICAgICB9CisKKyAgICB9OworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvSW52YWxpZFByb3BlcnRpZXNGb3JtYXRFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9JbnZhbGlkUHJvcGVydGllc0Zvcm1hdEV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYjE0NGE0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvSW52YWxpZFByb3BlcnRpZXNGb3JtYXRFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSwzOSBAQAorLyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEuaW8uTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5JbnZhbGlkUHJvcGVydGllc0Zvcm1hdEV4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS50ZXN0ZnJhbWV3b3JrLnNlcmlhbGl6YXRpb24uU2VyaWFsaXphdGlvblRlc3Q7CisKK3B1YmxpYyBjbGFzcyBJbnZhbGlkUHJvcGVydGllc0Zvcm1hdEV4Y2VwdGlvblRlc3QgZXh0ZW5kcworICAgICAgICBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkludmFsaWRQcm9wZXJ0aWVzRm9ybWF0RXhjZXB0aW9uI1NlcmlhbGl6YXRpb25UZXN0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NlcmlhbGl6YXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSW52YWxpZFByb3BlcnRpZXNGb3JtYXRFeGNlcHRpb24gaXBmZSA9IG5ldyBJbnZhbGlkUHJvcGVydGllc0Zvcm1hdEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiSGV5LCB0aGlzIGlzIEludmFsaWRQcm9wZXJ0aWVzRm9ybWF0RXhjZXB0aW9uIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTZXJpYWxpemF0aW9uVGVzdC52ZXJpZnlTZWxmKGlwZmUpOworICAgICAgICB9IGNhdGNoIChOb3RTZXJpYWxpemFibGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvTGlua2VkSGFzaE1hcFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0xpbmtlZEhhc2hNYXBUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWZmOTQ5MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0xpbmtlZEhhc2hNYXBUZXN0LmphdmEKQEAgLTAsMCArMSw3MzYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKKworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9NYXBUZXN0MjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfVW5tb2RpZmlhYmxlQ29sbGVjdGlvblRlc3Q7CisKKy8qKgorICogamF2YS51dGlsLkxpbmtlZEhhc2hNYXAKKyAqLworcHVibGljIGNsYXNzIExpbmtlZEhhc2hNYXBUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIExpbmtlZEhhc2hNYXAgaG07CisKKyAgICBmaW5hbCBzdGF0aWMgaW50IGhtU2l6ZSA9IDEwMDA7CisKKyAgICBPYmplY3RbXSBvYmpBcnJheTsKKworICAgIE9iamVjdFtdIG9iakFycmF5MjsKKworICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBDYWNoZU1hcCBleHRlbmRzIExpbmtlZEhhc2hNYXAgeworICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiByZW1vdmVFbGRlc3RFbnRyeShNYXAuRW50cnkgZSkgeworICAgICAgICAgICAgcmV0dXJuIHNpemUoKSA+IDU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBNb2NrTWFwTnVsbCBleHRlbmRzIEFic3RyYWN0TWFwIHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTZXQgZW50cnlTZXQoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgICAgICByZXR1cm4gMTA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcCNMaW5rZWRIYXNoTWFwKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLkxpbmtlZEhhc2hNYXAoKQorICAgICAgICBuZXcgU3VwcG9ydF9NYXBUZXN0MihuZXcgTGlua2VkSGFzaE1hcCgpKS5ydW5UZXN0KCk7CisKKyAgICAgICAgTGlua2VkSGFzaE1hcCBobTIgPSBuZXcgTGlua2VkSGFzaE1hcCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkNyZWF0ZWQgaW5jb3JyZWN0IExpbmtlZEhhc2hNYXAiLCAwLCBobTIuc2l6ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcCNMaW5rZWRIYXNoTWFwKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5MaW5rZWRIYXNoTWFwKGludCkKKyAgICAgICAgTGlua2VkSGFzaE1hcCBobTIgPSBuZXcgTGlua2VkSGFzaE1hcCg1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDcmVhdGVkIGluY29ycmVjdCBMaW5rZWRIYXNoTWFwIiwgMCwgaG0yLnNpemUoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgTGlua2VkSGFzaE1hcCgtMSk7CisgICAgICAgICAgICBmYWlsKCJGYWlsZWQgdG8gdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGZvciBpbml0aWFsICIgKworICAgICAgICAgICAgICAgICAgICAiY2FwYWNpdHkgPCAwIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBMaW5rZWRIYXNoTWFwIGVtcHR5ID0gbmV3IExpbmtlZEhhc2hNYXAoMCk7CisgICAgICAgIGFzc2VydE51bGwoIkVtcHR5IExpbmtlZEhhc2hNYXAgYWNjZXNzIiwgZW1wdHkuZ2V0KCJub3RoaW5nIikpOworICAgICAgICBlbXB0eS5wdXQoInNvbWV0aGluZyIsICJoZXJlIik7CisgICAgICAgIGFzc2VydFRydWUoImNhbm5vdCBnZXQgZWxlbWVudCIsIGVtcHR5LmdldCgic29tZXRoaW5nIikgPT0gImhlcmUiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcCNMaW5rZWRIYXNoTWFwKGludCwgZmxvYXQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcklGKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLkxpbmtlZEhhc2hNYXAoaW50LCBmbG9hdCkKKyAgICAgICAgTGlua2VkSGFzaE1hcCBobTIgPSBuZXcgTGlua2VkSGFzaE1hcCg1LCAoZmxvYXQpIDAuNSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQ3JlYXRlZCBpbmNvcnJlY3QgTGlua2VkSGFzaE1hcCIsIDAsIGhtMi5zaXplKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IExpbmtlZEhhc2hNYXAoMCwgMCk7CisgICAgICAgICAgICBmYWlsKCJGYWlsZWQgdG8gdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGZvciBpbml0aWFsICIgKworICAgICAgICAgICAgICAgICAgICAibG9hZCBmYWN0b3IgPD0gMCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgTGlua2VkSGFzaE1hcCBlbXB0eSA9IG5ldyBMaW5rZWRIYXNoTWFwKDAsIDAuNzVmKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiRW1wdHkgaGFzaHRhYmxlIGFjY2VzcyIsIGVtcHR5LmdldCgibm90aGluZyIpKTsKKyAgICAgICAgZW1wdHkucHV0KCJzb21ldGhpbmciLCAiaGVyZSIpOworICAgICAgICBhc3NlcnRUcnVlKCJjYW5ub3QgZ2V0IGVsZW1lbnQiLCBlbXB0eS5nZXQoInNvbWV0aGluZyIpID09ICJoZXJlIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxpbmtlZEhhc2hNYXAjTGlua2VkSGFzaE1hcChqYXZhLnV0aWwuTWFwKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV91dGlsX01hcCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5MaW5rZWRIYXNoTWFwKGphdmEudXRpbC5NYXApCisgICAgICAgIE1hcCBteU1hcCA9IG5ldyBUcmVlTWFwKCk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgaG1TaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBteU1hcC5wdXQob2JqQXJyYXkyW2NvdW50ZXJdLCBvYmpBcnJheVtjb3VudGVyXSk7CisgICAgICAgIExpbmtlZEhhc2hNYXAgaG0yID0gbmV3IExpbmtlZEhhc2hNYXAobXlNYXApOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IGhtU2l6ZTsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGNvbnN0cnVjdCBjb3JyZWN0IExpbmtlZEhhc2hNYXAiLCBobQorICAgICAgICAgICAgICAgICAgICAuZ2V0KG9iakFycmF5Mltjb3VudGVyXSkgPT0gaG0yLmdldChvYmpBcnJheTJbY291bnRlcl0pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcCNnZXQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdAorICAgICAgICAvLyBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcC5nZXQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgYXNzZXJ0TnVsbCgiR2V0IHJldHVybmVkIG5vbi1udWxsIGZvciBub24gZXhpc3RlbnQga2V5IiwKKyAgICAgICAgICAgICAgICBobS5nZXQoIlQiKSk7CisgICAgICAgIGhtLnB1dCgiVCIsICJIRUxMTyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkdldCByZXR1cm5lZCBpbmNvcmVjY3QgdmFsdWUgZm9yIGV4aXN0aW5nIGtleSIsICJIRUxMTyIsIGhtLmdldCgiVCIpCisgICAgICAgICAgICAgICAgKTsKKworICAgICAgICBMaW5rZWRIYXNoTWFwIG0gPSBuZXcgTGlua2VkSGFzaE1hcCgpOworICAgICAgICBtLnB1dChudWxsLCAidGVzdCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCB3aXRoIG51bGwga2V5IiwgInRlc3QiLCBtLmdldChudWxsKSk7CisgICAgICAgIGFzc2VydE51bGwoIkZhaWxlZCB3aXRoIG1pc3Npbmcga2V5IG1hdGNoaW5nIG51bGwgaGFzaCIsIG0KKyAgICAgICAgICAgICAgICAuZ2V0KG5ldyBJbnRlZ2VyKDApKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxpbmtlZEhhc2hNYXAjcHV0KGphdmEubGFuZy5PYmplY3QsIGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wdXRMamF2YV9sYW5nX09iamVjdExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdAorICAgICAgICAvLyBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcC5wdXQoamF2YS5sYW5nLk9iamVjdCwgamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgaG0ucHV0KCJLRVkiLCAiVkFMVUUiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gaW5zdGFsbCBrZXkvdmFsdWUgcGFpciIsCisgICAgICAgICAgICAgICAgIlZBTFVFIiwgaG0uZ2V0KCJLRVkiKSk7CisKKyAgICAgICAgTGlua2VkSGFzaE1hcCBtID0gbmV3IExpbmtlZEhhc2hNYXAoKTsKKyAgICAgICAgbS5wdXQobmV3IFNob3J0KChzaG9ydCkgMCksICJzaG9ydCIpOworICAgICAgICBtLnB1dChudWxsLCAidGVzdCIpOworICAgICAgICBtLnB1dChuZXcgSW50ZWdlcigwKSwgImludCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCBhZGRpbmcgdG8gYnVja2V0IGNvbnRhaW5pbmcgbnVsbCIsICJzaG9ydCIsIG0uZ2V0KAorICAgICAgICAgICAgICAgIG5ldyBTaG9ydCgoc2hvcnQpIDApKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIGFkZGluZyB0byBidWNrZXQgY29udGFpbmluZyBudWxsMiIsICJpbnQiLCBtLmdldCgKKyAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcigwKSkpOworICAgIH0KKworCisgICAgcHVibGljIHZvaWQgdGVzdF9wdXRQcmVzZW50KCkgeworICAgICAgICBNYXA8U3RyaW5nLCBTdHJpbmc+IG0gPSBuZXcgTGlua2VkSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oOCwgLjc1ZiwgdHJ1ZSk7CisgICAgICAgIG0ucHV0KCJLRVkiLCAiVkFMVUUiKTsKKyAgICAgICAgbS5wdXQoIldPTUJBVCIsICJDT01CQVQiKTsKKyAgICAgICAgbS5wdXQoIktFWSIsICJWQUxVRSIpOworICAgICAgICBNYXAuRW50cnkgbmV3ZXN0ID0gbnVsbDsKKyAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBTdHJpbmc+IGUgOiBtLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIG5ld2VzdCA9IGU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJLRVkiLCBuZXdlc3QuZ2V0S2V5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlZBTFVFIiwgbmV3ZXN0LmdldFZhbHVlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRIYXNoTWFwI3B1dEFsbChqYXZhLnV0aWwuTWFwKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcHV0QWxsTGphdmFfdXRpbF9NYXAoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5MaW5rZWRIYXNoTWFwLnB1dEFsbChqYXZhLnV0aWwuTWFwKQorICAgICAgICBMaW5rZWRIYXNoTWFwIGhtMiA9IG5ldyBMaW5rZWRIYXNoTWFwKCk7CisgICAgICAgIGhtMi5wdXRBbGwoaG0pOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDA7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBjbGVhciBhbGwgZWxlbWVudHMiLCBobTIuZ2V0KAorICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihpKS50b1N0cmluZygpKS5lcXVhbHMoKG5ldyBJbnRlZ2VyKGkpKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRIYXNoTWFwI3B1dEFsbChqYXZhLnV0aWwuTWFwKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcHV0QWxsX0xqYXZhX3V0aWxfTWFwX051bGwoKSB7CisgICAgICAgIExpbmtlZEhhc2hNYXAgbGlua2VkSGFzaE1hcCA9IG5ldyBMaW5rZWRIYXNoTWFwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsaW5rZWRIYXNoTWFwLnB1dEFsbChuZXcgTW9ja01hcE51bGwoKSk7CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbGlua2VkSGFzaE1hcCA9IG5ldyBMaW5rZWRIYXNoTWFwKG5ldyBNb2NrTWFwTnVsbCgpKTsKKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRIYXNoTWFwI2VudHJ5U2V0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VudHJ5U2V0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlNldCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcC5lbnRyeVNldCgpCisgICAgICAgIFNldCBzID0gaG0uZW50cnlTZXQoKTsKKyAgICAgICAgSXRlcmF0b3IgaSA9IHMuaXRlcmF0b3IoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgc2V0IG9mIGluY29ycmVjdCBzaXplIiwgaG0uc2l6ZSgpID09IHMuc2l6ZSgpKTsKKyAgICAgICAgd2hpbGUgKGkuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBNYXAuRW50cnkgbSA9IChNYXAuRW50cnkpIGkubmV4dCgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGVudHJ5IHNldCIsIGhtLmNvbnRhaW5zS2V5KG0KKyAgICAgICAgICAgICAgICAgICAgLmdldEtleSgpKQorICAgICAgICAgICAgICAgICAgICAmJiBobS5jb250YWluc1ZhbHVlKG0uZ2V0VmFsdWUoKSkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9lbnRyeVNldFJlbW92ZSgpIHsKKyAgICAgICAgZW50cnlTZXRSZW1vdmVIZWxwZXIoIm1pbGl0YXJ5IiwgImludGVsbGlnZW5jZSIpOworICAgICAgICBlbnRyeVNldFJlbW92ZUhlbHBlcihudWxsLCAiaHlwb3RoZXNpcyIpOworICAgIH0KKyAgICBwcml2YXRlIHZvaWQgZW50cnlTZXRSZW1vdmVIZWxwZXIoU3RyaW5nIGtleSwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gbTEgPSBuZXcgTGlua2VkSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgbTEucHV0KGtleSwgdmFsdWUpOworICAgICAgICBtMS5wdXQoImp1bWJvIiwgInNocmltcCIpOworICAgICAgICBMaW5rZWRIYXNoTWFwPFN0cmluZywgU3RyaW5nPiBtMiA9IG5ldyBMaW5rZWRIYXNoTWFwPFN0cmluZywgU3RyaW5nPihtMSk7CisgICAgICAgIFNldDxNYXAuRW50cnk8U3RyaW5nLCBTdHJpbmc+PiBzMSA9IG0xLmVudHJ5U2V0KCk7CisgICAgICAgIHMxLnJlbW92ZShtMi5lbnRyeVNldCgpLml0ZXJhdG9yKCkubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJqdW1ibyIsIHMxLml0ZXJhdG9yKCkubmV4dCgpLmdldEtleSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcCNrZXlTZXQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfa2V5U2V0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlNldCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcC5rZXlTZXQoKQorICAgICAgICBTZXQgcyA9IGhtLmtleVNldCgpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBzZXQgb2YgaW5jb3JyZWN0IHNpemUoKSIsIHMuc2l6ZSgpID09IGhtLnNpemUoKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2JqQXJyYXkubGVuZ3RoOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBzZXQgZG9lcyBub3QgY29udGFpbiBhbGwga2V5cyIsIHMKKyAgICAgICAgICAgICAgICAgICAgLmNvbnRhaW5zKG9iakFycmF5W2ldLnRvU3RyaW5nKCkpKTsKKworICAgICAgICBMaW5rZWRIYXNoTWFwIG0gPSBuZXcgTGlua2VkSGFzaE1hcCgpOworICAgICAgICBtLnB1dChudWxsLCAidGVzdCIpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgd2l0aCBudWxsIGtleSIsIG0ua2V5U2V0KCkuY29udGFpbnMobnVsbCkpOworICAgICAgICBhc3NlcnROdWxsKCJGYWlsZWQgd2l0aCBudWxsIGtleSIsIG0ua2V5U2V0KCkuaXRlcmF0b3IoKS5uZXh0KCkpOworCisgICAgICAgIE1hcCBtYXAgPSBuZXcgTGlua2VkSGFzaE1hcCgxMDEpOworICAgICAgICBtYXAucHV0KG5ldyBJbnRlZ2VyKDEpLCAiMSIpOworICAgICAgICBtYXAucHV0KG5ldyBJbnRlZ2VyKDEwMiksICIxMDIiKTsKKyAgICAgICAgbWFwLnB1dChuZXcgSW50ZWdlcigyMDMpLCAiMjAzIik7CisgICAgICAgIEl0ZXJhdG9yIGl0ID0gbWFwLmtleVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgIEludGVnZXIgcmVtb3ZlMSA9IChJbnRlZ2VyKSBpdC5uZXh0KCk7CisgICAgICAgIGl0Lmhhc05leHQoKTsKKyAgICAgICAgaXQucmVtb3ZlKCk7CisgICAgICAgIEludGVnZXIgcmVtb3ZlMiA9IChJbnRlZ2VyKSBpdC5uZXh0KCk7CisgICAgICAgIGl0LnJlbW92ZSgpOworICAgICAgICBBcnJheUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoQXJyYXlzLmFzTGlzdChuZXcgSW50ZWdlcltdIHsKKyAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcigxKSwgbmV3IEludGVnZXIoMTAyKSwgbmV3IEludGVnZXIoMjAzKSB9KSk7CisgICAgICAgIGxpc3QucmVtb3ZlKHJlbW92ZTEpOworICAgICAgICBsaXN0LnJlbW92ZShyZW1vdmUyKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcmVzdWx0IiwgaXQubmV4dCgpLmVxdWFscyhsaXN0LmdldCgwKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUiLCAxLCBtYXAuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgY29udGVudHMiLCBtYXAua2V5U2V0KCkuaXRlcmF0b3IoKS5uZXh0KCkuZXF1YWxzKAorICAgICAgICAgICAgICAgIGxpc3QuZ2V0KDApKSk7CisKKyAgICAgICAgTWFwIG1hcDIgPSBuZXcgTGlua2VkSGFzaE1hcCgxMDEpOworICAgICAgICBtYXAyLnB1dChuZXcgSW50ZWdlcigxKSwgIjEiKTsKKyAgICAgICAgbWFwMi5wdXQobmV3IEludGVnZXIoNCksICI0Iik7CisgICAgICAgIEl0ZXJhdG9yIGl0MiA9IG1hcDIua2V5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgICAgSW50ZWdlciByZW1vdmUzID0gKEludGVnZXIpIGl0Mi5uZXh0KCk7CisgICAgICAgIEludGVnZXIgbmV4dDsKKyAgICAgICAgaWYgKHJlbW92ZTMuaW50VmFsdWUoKSA9PSAxKQorICAgICAgICAgICAgbmV4dCA9IG5ldyBJbnRlZ2VyKDQpOworICAgICAgICBlbHNlCisgICAgICAgICAgICBuZXh0ID0gbmV3IEludGVnZXIoMSk7CisgICAgICAgIGl0Mi5oYXNOZXh0KCk7CisgICAgICAgIGl0Mi5yZW1vdmUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcmVzdWx0IDIiLCBpdDIubmV4dCgpLmVxdWFscyhuZXh0KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSAyIiwgMSwgbWFwMi5zaXplKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBjb250ZW50cyAyIiwgbWFwMi5rZXlTZXQoKS5pdGVyYXRvcigpLm5leHQoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgbmV4dCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRIYXNoTWFwI3ZhbHVlcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF92YWx1ZXMoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuQ29sbGVjdGlvbiBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcC52YWx1ZXMoKQorICAgICAgICBDb2xsZWN0aW9uIGMgPSBobS52YWx1ZXMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgY29sbGVjdGlvbiBvZiBpbmNvcnJlY3Qgc2l6ZSgpIiwgYy5zaXplKCkgPT0gaG0KKyAgICAgICAgICAgICAgICAuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvYmpBcnJheS5sZW5ndGg7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGNvbGxlY3Rpb24gZG9lcyBub3QgY29udGFpbiBhbGwga2V5cyIsIGMKKyAgICAgICAgICAgICAgICAgICAgLmNvbnRhaW5zKG9iakFycmF5W2ldKSk7CisKKyAgICAgICAgTGlua2VkSGFzaE1hcCBteUxpbmtlZEhhc2hNYXAgPSBuZXcgTGlua2VkSGFzaE1hcCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKQorICAgICAgICAgICAgbXlMaW5rZWRIYXNoTWFwLnB1dChvYmpBcnJheTJbaV0sIG9iakFycmF5W2ldKTsKKyAgICAgICAgQ29sbGVjdGlvbiB2YWx1ZXMgPSBteUxpbmtlZEhhc2hNYXAudmFsdWVzKCk7CisgICAgICAgIG5ldyBTdXBwb3J0X1VubW9kaWZpYWJsZUNvbGxlY3Rpb25UZXN0KAorICAgICAgICAgICAgICAgICJUZXN0IFJldHVybmVkIENvbGxlY3Rpb24gRnJvbSBMaW5rZWRIYXNoTWFwLnZhbHVlcygpIiwgdmFsdWVzKQorICAgICAgICAgICAgICAgIC5ydW5UZXN0KCk7CisgICAgICAgIHZhbHVlcy5yZW1vdmUobmV3IEludGVnZXIoMCkpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJSZW1vdmluZyBmcm9tIHRoZSB2YWx1ZXMgY29sbGVjdGlvbiBzaG91bGQgcmVtb3ZlIGZyb20gdGhlIG9yaWdpbmFsIG1hcCIsCisgICAgICAgICAgICAgICAgIW15TGlua2VkSGFzaE1hcC5jb250YWluc1ZhbHVlKG5ldyBJbnRlZ2VyKDApKSk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcCNyZW1vdmUoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlbW92ZUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdAorICAgICAgICAvLyBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcC5yZW1vdmUoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgaW50IHNpemUgPSBobS5zaXplKCk7CisgICAgICAgIEludGVnZXIgeSA9IG5ldyBJbnRlZ2VyKDkpOworICAgICAgICBJbnRlZ2VyIHggPSAoKEludGVnZXIpIGhtLnJlbW92ZSh5LnRvU3RyaW5nKCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmVtb3ZlIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIHguZXF1YWxzKG5ldyBJbnRlZ2VyKDkpKSk7CisgICAgICAgIGFzc2VydE51bGwoIkZhaWxlZCB0byByZW1vdmUgZ2l2ZW4ga2V5IiwgaG0uZ2V0KG5ldyBJbnRlZ2VyKDkpKSk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBkZWNyZW1lbnQgc2l6ZSIsIGhtLnNpemUoKSA9PSAoc2l6ZSAtIDEpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiUmVtb3ZlIG9mIG5vbi1leGlzdGVudCBrZXkgcmV0dXJuZWQgbm9uLW51bGwiLCBobQorICAgICAgICAgICAgICAgIC5yZW1vdmUoIkxDTENMQyIpKTsKKworICAgICAgICBMaW5rZWRIYXNoTWFwIG0gPSBuZXcgTGlua2VkSGFzaE1hcCgpOworICAgICAgICBtLnB1dChudWxsLCAidGVzdCIpOworICAgICAgICBhc3NlcnROdWxsKCJGYWlsZWQgd2l0aCBzYW1lIGhhc2ggYXMgbnVsbCIsCisgICAgICAgICAgICAgICAgbS5yZW1vdmUobmV3IEludGVnZXIoMCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgd2l0aCBudWxsIGtleSIsICJ0ZXN0IiwgbS5yZW1vdmUobnVsbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRIYXNoTWFwI2NsZWFyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NsZWFyKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcC5jbGVhcigpCisgICAgICAgIGhtLmNsZWFyKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiQ2xlYXIgZmFpbGVkIHRvIHJlc2V0IHNpemUiLCAwLCBobS5zaXplKCkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGhtU2l6ZTsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIGNsZWFyIGFsbCBlbGVtZW50cyIsCisgICAgICAgICAgICAgICAgICAgIGhtLmdldChvYmpBcnJheTJbaV0pKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRIYXNoTWFwI2Nsb25lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb25lKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcC5jbG9uZSgpCisgICAgICAgIExpbmtlZEhhc2hNYXAgaG0yID0gKExpbmtlZEhhc2hNYXApIGhtLmNsb25lKCk7CisgICAgICAgIGFzc2VydFRydWUoIkNsb25lIGFuc3dlcmVkIGVxdWl2YWxlbnQgTGlua2VkSGFzaE1hcCIsIGhtMiAhPSBobSk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgaG1TaXplOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJDbG9uZSBhbnN3ZXJlZCB1bmVxdWFsIExpbmtlZEhhc2hNYXAiLCBobQorICAgICAgICAgICAgICAgICAgICAuZ2V0KG9iakFycmF5Mltjb3VudGVyXSkgPT0gaG0yLmdldChvYmpBcnJheTJbY291bnRlcl0pKTsKKworICAgICAgICBMaW5rZWRIYXNoTWFwIG1hcCA9IG5ldyBMaW5rZWRIYXNoTWFwKCk7CisgICAgICAgIG1hcC5wdXQoImtleSIsICJ2YWx1ZSIpOworICAgICAgICAvLyBnZXQgdGhlIGtleVNldCgpIGFuZCB2YWx1ZXMoKSBvbiB0aGUgb3JpZ2luYWwgTWFwCisgICAgICAgIFNldCBrZXlzID0gbWFwLmtleVNldCgpOworICAgICAgICBDb2xsZWN0aW9uIHZhbHVlcyA9IG1hcC52YWx1ZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZXMoKSBkb2VzIG5vdCB3b3JrIiwKKyAgICAgICAgICAgICAgICAidmFsdWUiLCB2YWx1ZXMuaXRlcmF0b3IoKS5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImtleVNldCgpIGRvZXMgbm90IHdvcmsiLAorICAgICAgICAgICAgICAgICJrZXkiLCBrZXlzLml0ZXJhdG9yKCkubmV4dCgpKTsKKyAgICAgICAgQWJzdHJhY3RNYXAgbWFwMiA9IChBYnN0cmFjdE1hcCkgbWFwLmNsb25lKCk7CisgICAgICAgIG1hcDIucHV0KCJrZXkiLCAidmFsdWUyIik7CisgICAgICAgIENvbGxlY3Rpb24gdmFsdWVzMiA9IG1hcDIudmFsdWVzKCk7CisgICAgICAgIGFzc2VydFRydWUoInZhbHVlcygpIGlzIGlkZW50aWNhbCIsIHZhbHVlczIgIT0gdmFsdWVzKTsKKworICAgICAgICAvLyB2YWx1ZXMoKSBhbmQga2V5U2V0KCkgb24gdGhlIGNsb25lZCgpIG1hcCBzaG91bGQgYmUgZGlmZmVyZW50CisgICAgICAgIGFzc2VydEVxdWFscygidmFsdWVzKCkgd2FzIG5vdCBjbG9uZWQiLAorICAgICAgICAgICAgICAgICJ2YWx1ZTIiLCB2YWx1ZXMyLml0ZXJhdG9yKCkubmV4dCgpKTsKKyAgICAgICAgbWFwMi5jbGVhcigpOworICAgICAgICBtYXAyLnB1dCgia2V5MiIsICJ2YWx1ZTMiKTsKKyAgICAgICAgU2V0IGtleTIgPSBtYXAyLmtleVNldCgpOworICAgICAgICBhc3NlcnRUcnVlKCJrZXlTZXQoKSBpcyBpZGVudGljYWwiLCBrZXkyICE9IGtleXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoImtleVNldCgpIHdhcyBub3QgY2xvbmVkIiwKKyAgICAgICAgICAgICAgICAia2V5MiIsIGtleTIuaXRlcmF0b3IoKS5uZXh0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRIYXNoTWFwI2Nsb25lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb25lX29yZGVyZWQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IGphdmEudXRpbC5MaW5rZWRIYXNoTWFwLmNsb25lKCkKKyAgICAgICAgTGlua2VkSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4gaG0xID0gbmV3IExpbmtlZEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KDEwLCAwLjc1ZiwgdHJ1ZSk7CisgICAgICAgIGhtMS5wdXQoImEiLCAiYSIpOworICAgICAgICBobTEucHV0KCJiIiwgImIiKTsKKyAgICAgICAgaG0xLnB1dCgiYyIsICJjIik7CisgICAgICAgIExpbmtlZEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IGhtMiA9IChMaW5rZWRIYXNoTWFwPFN0cmluZywgU3RyaW5nPikgaG0xLmNsb25lKCk7CisgICAgICAgIGhtMS5nZXQoImEiKTsKKworICAgICAgICBNYXAuRW50cnk8U3RyaW5nLCBTdHJpbmc+W10gc2V0ID0gbmV3IE1hcC5FbnRyeVszXTsKKyAgICAgICAgSXRlcmF0b3I8TWFwLkVudHJ5PFN0cmluZyxTdHJpbmc+PiBpdGVyYXRvciA9IGhtMS5lbnRyeVNldCgpLml0ZXJhdG9yKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiIiwgaXRlcmF0b3IubmV4dCgpLmdldEtleSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjIiwgaXRlcmF0b3IubmV4dCgpLmdldEtleSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhIiwgaXRlcmF0b3IubmV4dCgpLmdldEtleSgpKTsKKworICAgICAgICBpdGVyYXRvciA9IGhtMi5lbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSIsIGl0ZXJhdG9yLm5leHQoKS5nZXRLZXkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYiIsIGl0ZXJhdG9yLm5leHQoKS5nZXRLZXkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYyIsIGl0ZXJhdG9yLm5leHQoKS5nZXRLZXkoKSk7CisgICAgfQorCisgICAgLy8gcmVncmVzaW9uIHRlc3QgZm9yIEhBUk1PTlktNDYwMworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvbmVfTW9jaygpIHsKKyAgICAgICAgTGlua2VkSGFzaE1hcCBoYXNoTWFwID0gbmV3IE1vY2tNYXAoKTsKKyAgICAgICAgU3RyaW5nIHZhbHVlID0gInZhbHVlIGEiOworICAgICAgICBoYXNoTWFwLnB1dCgia2V5IiwgdmFsdWUpOworICAgICAgICBNb2NrTWFwIGNsb25lTWFwID0gKE1vY2tNYXApIGhhc2hNYXAuY2xvbmUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHZhbHVlLCBjbG9uZU1hcC5nZXQoImtleSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGhhc2hNYXAsIGNsb25lTWFwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGNsb25lTWFwLm51bSk7CisKKyAgICAgICAgaGFzaE1hcC5wdXQoImtleSIsICJ2YWx1ZSBiIik7CisgICAgICAgIGFzc2VydEZhbHNlKGhhc2hNYXAuZXF1YWxzKGNsb25lTWFwKSk7CisgICAgfQorCisgICAgY2xhc3MgTW9ja01hcCBleHRlbmRzIExpbmtlZEhhc2hNYXAgeworICAgICAgICBpbnQgbnVtOworCisgICAgICAgIHB1YmxpYyBPYmplY3QgcHV0KE9iamVjdCBrLCBPYmplY3QgdikgeworICAgICAgICAgICAgbnVtKys7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIucHV0KGssIHYpOworICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gcmVtb3ZlRWxkZXN0RW50cnkoTWFwLkVudHJ5IGUpIHsKKyAgICAgICAgICAgIHJldHVybiBudW0gPiAxOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogcHV0L2dldCBpbnRlcmFjdGlvbiBpbiBhY2Nlc3Mtb3JkZXIgbWFwIHdoZXJlIHJlbW92ZUVsZGVzdAorICAgICAqIHJldHVybnMgdHJ1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlbW92ZUVsZGVzdEZyb21TYW1lQnVja2V0QXNOZXdFbnRyeSgpIHsKKyAgICAgICAgTGlua2VkSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4gbWFwCisgICAgICAgICAgICAgICAgPSBuZXcgTGlua2VkSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oNiwgMC43NUYsIHRydWUpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gcmVtb3ZlRWxkZXN0RW50cnkoRW50cnk8U3RyaW5nLCBTdHJpbmc+IGUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgbWFwLnB1dCgiTiIsICJFIik7CisgICAgICAgIG1hcC5wdXQoIkYiLCAiSSIpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbWFwLmdldCgiTiIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcCNjb250YWluc0tleShqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY29udGFpbnNLZXlMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4KKyAgICAgICAgLy8gamF2YS51dGlsLkxpbmtlZEhhc2hNYXAuY29udGFpbnNLZXkoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIHZhbGlkIGtleSIsIGhtLmNvbnRhaW5zS2V5KG5ldyBJbnRlZ2VyKAorICAgICAgICAgICAgICAgIDg3NikudG9TdHJpbmcoKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCB0cnVlIGZvciBpbnZhbGlkIGtleSIsICFobS5jb250YWluc0tleSgiS0tES0RLRCIpKTsKKworICAgICAgICBMaW5rZWRIYXNoTWFwIG0gPSBuZXcgTGlua2VkSGFzaE1hcCgpOworICAgICAgICBtLnB1dChudWxsLCAidGVzdCIpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgd2l0aCBudWxsIGtleSIsIG0uY29udGFpbnNLZXkobnVsbCkpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgd2l0aCBtaXNzaW5nIGtleSBtYXRjaGluZyBudWxsIGhhc2giLCAhbQorICAgICAgICAgICAgICAgIC5jb250YWluc0tleShuZXcgSW50ZWdlcigwKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRIYXNoTWFwI2NvbnRhaW5zVmFsdWUoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbnRhaW5zVmFsdWVMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4KKyAgICAgICAgLy8gamF2YS51dGlsLkxpbmtlZEhhc2hNYXAuY29udGFpbnNWYWx1ZShqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgdmFsaWQgdmFsdWUiLCBobQorICAgICAgICAgICAgICAgIC5jb250YWluc1ZhbHVlKG5ldyBJbnRlZ2VyKDg3NSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgaW52YWxpZCB2YWxpZSIsICFobQorICAgICAgICAgICAgICAgIC5jb250YWluc1ZhbHVlKG5ldyBJbnRlZ2VyKC05KSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRIYXNoTWFwI2lzRW1wdHkoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNFbXB0eSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4gamF2YS51dGlsLkxpbmtlZEhhc2hNYXAuaXNFbXB0eSgpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciBuZXcgbWFwIiwgbmV3IExpbmtlZEhhc2hNYXAoKS5pc0VtcHR5KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCB0cnVlIGZvciBub24tZW1wdHkiLCAhaG0uaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcCNzaXplKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NpemUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLkxpbmtlZEhhc2hNYXAuc2l6ZSgpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBzaXplIiwKKyAgICAgICAgICAgICAgICBobS5zaXplKCkgPT0gKG9iakFycmF5Lmxlbmd0aCArIDIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcCNlbnRyeVNldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9vcmRlcmVkX2VudHJ5U2V0KCkgeworICAgICAgICBpbnQgaTsKKyAgICAgICAgaW50IHN6ID0gMTAwOworICAgICAgICBMaW5rZWRIYXNoTWFwIGxobSA9IG5ldyBMaW5rZWRIYXNoTWFwKCk7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBzejsgaSsrKSB7CisgICAgICAgICAgICBJbnRlZ2VyIGlpID0gbmV3IEludGVnZXIoaSk7CisgICAgICAgICAgICBsaG0ucHV0KGlpLCBpaS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIFNldCBzMSA9IGxobS5lbnRyeVNldCgpOworICAgICAgICBJdGVyYXRvciBpdDEgPSBzMS5pdGVyYXRvcigpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBzZXQgb2YgaW5jb3JyZWN0IHNpemUgMSIsIGxobS5zaXplKCkgPT0gczEuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChpID0gMDsgaXQxLmhhc05leHQoKTsgaSsrKSB7CisgICAgICAgICAgICBNYXAuRW50cnkgbSA9IChNYXAuRW50cnkpIGl0MS5uZXh0KCk7CisgICAgICAgICAgICBJbnRlZ2VyIGpqID0gKEludGVnZXIpIG0uZ2V0S2V5KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgZW50cnkgc2V0IDEiLCBqai5pbnRWYWx1ZSgpID09IGkpOworICAgICAgICB9CisKKyAgICAgICAgTGlua2VkSGFzaE1hcCBscnVobSA9IG5ldyBMaW5rZWRIYXNoTWFwKDIwMCwgLjc1ZiwgdHJ1ZSk7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBzejsgaSsrKSB7CisgICAgICAgICAgICBJbnRlZ2VyIGlpID0gbmV3IEludGVnZXIoaSk7CisgICAgICAgICAgICBscnVobS5wdXQoaWksIGlpLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgU2V0IHMzID0gbHJ1aG0uZW50cnlTZXQoKTsKKyAgICAgICAgSXRlcmF0b3IgaXQzID0gczMuaXRlcmF0b3IoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgc2V0IG9mIGluY29ycmVjdCBzaXplIDIiLCBscnVobS5zaXplKCkgPT0gczMKKyAgICAgICAgICAgICAgICAuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IHN6ICYmIGl0My5oYXNOZXh0KCk7IGkrKykgeworICAgICAgICAgICAgTWFwLkVudHJ5IG0gPSAoTWFwLkVudHJ5KSBpdDMubmV4dCgpOworICAgICAgICAgICAgSW50ZWdlciBqaiA9IChJbnRlZ2VyKSBtLmdldEtleSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGVudHJ5IHNldCAyIiwgamouaW50VmFsdWUoKSA9PSBpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qIGZldGNoIHRoZSBldmVuIG51bWJlcmVkIGVudHJpZXMgdG8gYWZmZWN0IHRyYXZlcnNhbCBvcmRlciAqLworICAgICAgICBpbnQgcCA9IDA7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBzejsgaSArPSAyKSB7CisgICAgICAgICAgICBTdHJpbmcgaWkgPSAoU3RyaW5nKSBscnVobS5nZXQobmV3IEludGVnZXIoaSkpOworICAgICAgICAgICAgcCA9IHAgKyBJbnRlZ2VyLnBhcnNlSW50KGlpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoImludmFsaWQgc3VtIG9mIGV2ZW4gbnVtYmVycyIsIDI0NTAsIHApOworCisgICAgICAgIFNldCBzMiA9IGxydWhtLmVudHJ5U2V0KCk7CisgICAgICAgIEl0ZXJhdG9yIGl0MiA9IHMyLml0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHNldCBvZiBpbmNvcnJlY3Qgc2l6ZSAzIiwgbHJ1aG0uc2l6ZSgpID09IHMyCisgICAgICAgICAgICAgICAgLnNpemUoKSk7CisgICAgICAgIGZvciAoaSA9IDE7IGkgPCBzeiAmJiBpdDIuaGFzTmV4dCgpOyBpICs9IDIpIHsKKyAgICAgICAgICAgIE1hcC5FbnRyeSBtID0gKE1hcC5FbnRyeSkgaXQyLm5leHQoKTsKKyAgICAgICAgICAgIEludGVnZXIgamogPSAoSW50ZWdlcikgbS5nZXRLZXkoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBlbnRyeSBzZXQgMyIsIGpqLmludFZhbHVlKCkgPT0gaSk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpID0gMDsgaSA8IHN6ICYmIGl0Mi5oYXNOZXh0KCk7IGkgKz0gMikgeworICAgICAgICAgICAgTWFwLkVudHJ5IG0gPSAoTWFwLkVudHJ5KSBpdDIubmV4dCgpOworICAgICAgICAgICAgSW50ZWdlciBqaiA9IChJbnRlZ2VyKSBtLmdldEtleSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGVudHJ5IHNldCA0IiwgamouaW50VmFsdWUoKSA9PSBpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJFbnRyaWVzIGxlZnQgdG8gaXRlcmF0ZSBvbiIsICFpdDIuaGFzTmV4dCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcCNrZXlTZXQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfb3JkZXJlZF9rZXlTZXQoKSB7CisgICAgICAgIGludCBpOworICAgICAgICBpbnQgc3ogPSAxMDA7CisgICAgICAgIExpbmtlZEhhc2hNYXAgbGhtID0gbmV3IExpbmtlZEhhc2hNYXAoKTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IHN6OyBpKyspIHsKKyAgICAgICAgICAgIEludGVnZXIgaWkgPSBuZXcgSW50ZWdlcihpKTsKKyAgICAgICAgICAgIGxobS5wdXQoaWksIGlpLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgU2V0IHMxID0gbGhtLmtleVNldCgpOworICAgICAgICBJdGVyYXRvciBpdDEgPSBzMS5pdGVyYXRvcigpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBzZXQgb2YgaW5jb3JyZWN0IHNpemUiLCBsaG0uc2l6ZSgpID09IHMxLnNpemUoKSk7CisgICAgICAgIGZvciAoaSA9IDA7IGl0MS5oYXNOZXh0KCk7IGkrKykgeworICAgICAgICAgICAgSW50ZWdlciBqaiA9IChJbnRlZ2VyKSBpdDEubmV4dCgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGVudHJ5IHNldCIsIGpqLmludFZhbHVlKCkgPT0gaSk7CisgICAgICAgIH0KKworICAgICAgICBMaW5rZWRIYXNoTWFwIGxydWhtID0gbmV3IExpbmtlZEhhc2hNYXAoMjAwLCAuNzVmLCB0cnVlKTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IHN6OyBpKyspIHsKKyAgICAgICAgICAgIEludGVnZXIgaWkgPSBuZXcgSW50ZWdlcihpKTsKKyAgICAgICAgICAgIGxydWhtLnB1dChpaSwgaWkudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICBTZXQgczMgPSBscnVobS5rZXlTZXQoKTsKKyAgICAgICAgSXRlcmF0b3IgaXQzID0gczMuaXRlcmF0b3IoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgc2V0IG9mIGluY29ycmVjdCBzaXplIiwgbHJ1aG0uc2l6ZSgpID09IHMzLnNpemUoKSk7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBzeiAmJiBpdDMuaGFzTmV4dCgpOyBpKyspIHsKKyAgICAgICAgICAgIEludGVnZXIgamogPSAoSW50ZWdlcikgaXQzLm5leHQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBlbnRyeSBzZXQiLCBqai5pbnRWYWx1ZSgpID09IGkpOworICAgICAgICB9CisKKyAgICAgICAgLyogZmV0Y2ggdGhlIGV2ZW4gbnVtYmVyZWQgZW50cmllcyB0byBhZmZlY3QgdHJhdmVyc2FsIG9yZGVyICovCisgICAgICAgIGludCBwID0gMDsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IHN6OyBpICs9IDIpIHsKKyAgICAgICAgICAgIFN0cmluZyBpaSA9IChTdHJpbmcpIGxydWhtLmdldChuZXcgSW50ZWdlcihpKSk7CisgICAgICAgICAgICBwID0gcCArIEludGVnZXIucGFyc2VJbnQoaWkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiaW52YWxpZCBzdW0gb2YgZXZlbiBudW1iZXJzIiwgMjQ1MCwgcCk7CisKKyAgICAgICAgU2V0IHMyID0gbHJ1aG0ua2V5U2V0KCk7CisgICAgICAgIEl0ZXJhdG9yIGl0MiA9IHMyLml0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHNldCBvZiBpbmNvcnJlY3Qgc2l6ZSIsIGxydWhtLnNpemUoKSA9PSBzMi5zaXplKCkpOworICAgICAgICBmb3IgKGkgPSAxOyBpIDwgc3ogJiYgaXQyLmhhc05leHQoKTsgaSArPSAyKSB7CisgICAgICAgICAgICBJbnRlZ2VyIGpqID0gKEludGVnZXIpIGl0Mi5uZXh0KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgZW50cnkgc2V0IiwgamouaW50VmFsdWUoKSA9PSBpKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc3ogJiYgaXQyLmhhc05leHQoKTsgaSArPSAyKSB7CisgICAgICAgICAgICBJbnRlZ2VyIGpqID0gKEludGVnZXIpIGl0Mi5uZXh0KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgZW50cnkgc2V0IiwgamouaW50VmFsdWUoKSA9PSBpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJFbnRyaWVzIGxlZnQgdG8gaXRlcmF0ZSBvbiIsICFpdDIuaGFzTmV4dCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcCN2YWx1ZXMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfb3JkZXJlZF92YWx1ZXMoKSB7CisgICAgICAgIGludCBpOworICAgICAgICBpbnQgc3ogPSAxMDA7CisgICAgICAgIExpbmtlZEhhc2hNYXAgbGhtID0gbmV3IExpbmtlZEhhc2hNYXAoKTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IHN6OyBpKyspIHsKKyAgICAgICAgICAgIEludGVnZXIgaWkgPSBuZXcgSW50ZWdlcihpKTsKKyAgICAgICAgICAgIGxobS5wdXQoaWksIG5ldyBJbnRlZ2VyKGkgKiAyKSk7CisgICAgICAgIH0KKworICAgICAgICBDb2xsZWN0aW9uIHMxID0gbGhtLnZhbHVlcygpOworICAgICAgICBJdGVyYXRvciBpdDEgPSBzMS5pdGVyYXRvcigpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBzZXQgb2YgaW5jb3JyZWN0IHNpemUgMSIsIGxobS5zaXplKCkgPT0gczEuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChpID0gMDsgaXQxLmhhc05leHQoKTsgaSsrKSB7CisgICAgICAgICAgICBJbnRlZ2VyIGpqID0gKEludGVnZXIpIGl0MS5uZXh0KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgZW50cnkgc2V0IDEiLCBqai5pbnRWYWx1ZSgpID09IGkgKiAyKTsKKyAgICAgICAgfQorCisgICAgICAgIExpbmtlZEhhc2hNYXAgbHJ1aG0gPSBuZXcgTGlua2VkSGFzaE1hcCgyMDAsIC43NWYsIHRydWUpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc3o7IGkrKykgeworICAgICAgICAgICAgSW50ZWdlciBpaSA9IG5ldyBJbnRlZ2VyKGkpOworICAgICAgICAgICAgbHJ1aG0ucHV0KGlpLCBuZXcgSW50ZWdlcihpICogMikpOworICAgICAgICB9CisKKyAgICAgICAgQ29sbGVjdGlvbiBzMyA9IGxydWhtLnZhbHVlcygpOworICAgICAgICBJdGVyYXRvciBpdDMgPSBzMy5pdGVyYXRvcigpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBzZXQgb2YgaW5jb3JyZWN0IHNpemUiLCBscnVobS5zaXplKCkgPT0gczMuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IHN6ICYmIGl0My5oYXNOZXh0KCk7IGkrKykgeworICAgICAgICAgICAgSW50ZWdlciBqaiA9IChJbnRlZ2VyKSBpdDMubmV4dCgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGVudHJ5IHNldCIsIGpqLmludFZhbHVlKCkgPT0gaSAqIDIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gZmV0Y2ggdGhlIGV2ZW4gbnVtYmVyZWQgZW50cmllcyB0byBhZmZlY3QgdHJhdmVyc2FsIG9yZGVyCisgICAgICAgIGludCBwID0gMDsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IHN6OyBpICs9IDIpIHsKKyAgICAgICAgICAgIEludGVnZXIgaWkgPSAoSW50ZWdlcikgbHJ1aG0uZ2V0KG5ldyBJbnRlZ2VyKGkpKTsKKyAgICAgICAgICAgIHAgPSBwICsgaWkuaW50VmFsdWUoKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJpbnZhbGlkIHN1bSBvZiBldmVuIG51bWJlcnMiLCBwID09IDI0NTAgKiAyKTsKKworICAgICAgICBDb2xsZWN0aW9uIHMyID0gbHJ1aG0udmFsdWVzKCk7CisgICAgICAgIEl0ZXJhdG9yIGl0MiA9IHMyLml0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHNldCBvZiBpbmNvcnJlY3Qgc2l6ZSIsIGxydWhtLnNpemUoKSA9PSBzMi5zaXplKCkpOworICAgICAgICBmb3IgKGkgPSAxOyBpIDwgc3ogJiYgaXQyLmhhc05leHQoKTsgaSArPSAyKSB7CisgICAgICAgICAgICBJbnRlZ2VyIGpqID0gKEludGVnZXIpIGl0Mi5uZXh0KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgZW50cnkgc2V0IiwgamouaW50VmFsdWUoKSA9PSBpICogMik7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpID0gMDsgaSA8IHN6ICYmIGl0Mi5oYXNOZXh0KCk7IGkgKz0gMikgeworICAgICAgICAgICAgSW50ZWdlciBqaiA9IChJbnRlZ2VyKSBpdDIubmV4dCgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGVudHJ5IHNldCIsIGpqLmludFZhbHVlKCkgPT0gaSAqIDIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkVudHJpZXMgbGVmdCB0byBpdGVyYXRlIG9uIiwgIWl0Mi5oYXNOZXh0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRIYXNoTWFwI3JlbW92ZUVsZGVzdEVudHJ5KGphdmEudXRpbC5NYXAkRW50cnkpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZW1vdmVfZWxkZXN0KCkgeworICAgICAgICBpbnQgaTsKKyAgICAgICAgaW50IHN6ID0gMTA7CisgICAgICAgIENhY2hlTWFwIGxobSA9IG5ldyBDYWNoZU1hcCgpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc3o7IGkrKykgeworICAgICAgICAgICAgSW50ZWdlciBpaSA9IG5ldyBJbnRlZ2VyKGkpOworICAgICAgICAgICAgbGhtLnB1dChpaSwgbmV3IEludGVnZXIoaSAqIDIpKTsKKyAgICAgICAgfQorCisgICAgICAgIENvbGxlY3Rpb24gczEgPSBsaG0udmFsdWVzKCk7CisgICAgICAgIEl0ZXJhdG9yIGl0MSA9IHMxLml0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHNldCBvZiBpbmNvcnJlY3Qgc2l6ZSAxIiwgbGhtLnNpemUoKSA9PSBzMS5zaXplKCkpOworICAgICAgICBmb3IgKGkgPSA1OyBpdDEuaGFzTmV4dCgpOyBpKyspIHsKKyAgICAgICAgICAgIEludGVnZXIgamogPSAoSW50ZWdlcikgaXQxLm5leHQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBlbnRyeSBzZXQgMSIsIGpqLmludFZhbHVlKCkgPT0gaSAqIDIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkVudHJpZXMgbGVmdCBpbiBtYXAiLCAhaXQxLmhhc05leHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIG9iakFycmF5ID0gbmV3IE9iamVjdFtobVNpemVdOworICAgICAgICBvYmpBcnJheTIgPSBuZXcgT2JqZWN0W2htU2l6ZV07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2JqQXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIG9iakFycmF5W2ldID0gbmV3IEludGVnZXIoaSk7CisgICAgICAgICAgICBvYmpBcnJheTJbaV0gPSBvYmpBcnJheVtpXS50b1N0cmluZygpOworICAgICAgICB9CisKKyAgICAgICAgaG0gPSBuZXcgTGlua2VkSGFzaE1hcCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iakFycmF5Lmxlbmd0aDsgaSsrKQorICAgICAgICAgICAgaG0ucHV0KG9iakFycmF5MltpXSwgb2JqQXJyYXlbaV0pOworICAgICAgICBobS5wdXQoInRlc3QiLCBudWxsKTsKKyAgICAgICAgaG0ucHV0KG51bGwsICJ0ZXN0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVhcnMgZG93biB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIGNsb3NlIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzCisgICAgICogbWV0aG9kIGlzIGNhbGxlZCBhZnRlciBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgICAgIG9iakFycmF5ID0gbnVsbDsKKyAgICAgICAgb2JqQXJyYXkyID0gbnVsbDsKKyAgICAgICAgaG0gPSBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL0xpbmtlZEhhc2hTZXRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9MaW5rZWRIYXNoU2V0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1NGQwMWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9MaW5rZWRIYXNoU2V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMzUxIEBACisvKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKKy8qKgorICogamF2YS51dGlsLkxpbmtlZEhhc2hTZXQKKyAqLworCitwdWJsaWMgY2xhc3MgTGlua2VkSGFzaFNldFRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgTGlua2VkSGFzaFNldCBoczsKKworICAgIE9iamVjdFtdIG9iakFycmF5OworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxpbmtlZEhhc2hTZXQjTGlua2VkSGFzaFNldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5MaW5rZWRIYXNoU2V0KCkKKyAgICAgICAgTGlua2VkSGFzaFNldCBoczIgPSBuZXcgTGlua2VkSGFzaFNldCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkNyZWF0ZWQgaW5jb3JyZWN0IExpbmtlZEhhc2hTZXQiLCAwLCBoczIuc2l6ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaFNldCNMaW5rZWRIYXNoU2V0KGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5MaW5rZWRIYXNoU2V0KGludCkKKyAgICAgICAgTGlua2VkSGFzaFNldCBoczIgPSBuZXcgTGlua2VkSGFzaFNldCg1KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDcmVhdGVkIGluY29ycmVjdCBMaW5rZWRIYXNoU2V0IiwgMCwgaHMyLnNpemUoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgTGlua2VkSGFzaFNldCgtMSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRIYXNoU2V0I0xpbmtlZEhhc2hTZXQoaW50LCBmbG9hdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySUYoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuTGlua2VkSGFzaFNldChpbnQsIGZsb2F0KQorICAgICAgICBMaW5rZWRIYXNoU2V0IGhzMiA9IG5ldyBMaW5rZWRIYXNoU2V0KDUsIChmbG9hdCkgMC41KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDcmVhdGVkIGluY29ycmVjdCBMaW5rZWRIYXNoU2V0IiwgMCwgaHMyLnNpemUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBMaW5rZWRIYXNoU2V0KC0xLCAwLjVmKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBMaW5rZWRIYXNoU2V0KDEsIC0wLjVmKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBMaW5rZWRIYXNoU2V0KDEsIDBmKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxpbmtlZEhhc2hTZXQjTGlua2VkSGFzaFNldChqYXZhLnV0aWwuQ29sbGVjdGlvbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfdXRpbF9Db2xsZWN0aW9uKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLkxpbmtlZEhhc2hTZXQoamF2YS51dGlsLkNvbGxlY3Rpb24pCisgICAgICAgIExpbmtlZEhhc2hTZXQgaHMyID0gbmV3IExpbmtlZEhhc2hTZXQoQXJyYXlzLmFzTGlzdChvYmpBcnJheSkpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IG9iakFycmF5Lmxlbmd0aDsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTGlua2VkSGFzaFNldCBkb2VzIG5vdCBjb250YWluIGNvcnJlY3QgZWxlbWVudHMiLCBocworICAgICAgICAgICAgICAgICAgICAuY29udGFpbnMob2JqQXJyYXlbY291bnRlcl0pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTGlua2VkSGFzaFNldCBjcmVhdGVkIGZyb20gY29sbGVjdGlvbiBpbmNvcnJlY3Qgc2l6ZSIsIGhzMgorICAgICAgICAgICAgICAgIC5zaXplKCkgPT0gb2JqQXJyYXkubGVuZ3RoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IExpbmtlZEhhc2hTZXQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaFNldCNhZGQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuTGlua2VkSGFzaFNldC5hZGQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgaW50IHNpemUgPSBocy5zaXplKCk7CisgICAgICAgIGhzLmFkZChuZXcgSW50ZWdlcig4KSk7CisgICAgICAgIGFzc2VydFRydWUoIkFkZGVkIGVsZW1lbnQgYWxyZWFkeSBjb250YWluZWQgYnkgc2V0IiwgaHMuc2l6ZSgpID09IHNpemUpOworICAgICAgICBocy5hZGQobmV3IEludGVnZXIoLTkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGluY3JlbWVudCBzZXQgc2l6ZSBhZnRlciBhZGQiLAorICAgICAgICAgICAgICAgIGhzLnNpemUoKSA9PSBzaXplICsgMSk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBhZGQgZWxlbWVudCB0byBzZXQiLCBocy5jb250YWlucyhuZXcgSW50ZWdlcigtOSkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaFNldCNjbGVhcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jbGVhcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkxpbmtlZEhhc2hTZXQuY2xlYXIoKQorICAgICAgICBTZXQgb3JnU2V0ID0gKFNldCkgaHMuY2xvbmUoKTsKKyAgICAgICAgaHMuY2xlYXIoKTsKKyAgICAgICAgSXRlcmF0b3IgaSA9IG9yZ1NldC5pdGVyYXRvcigpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIG5vbi16ZXJvIHNpemUgYWZ0ZXIgY2xlYXIiLCAwLCBocy5zaXplKCkpOworICAgICAgICB3aGlsZSAoaS5oYXNOZXh0KCkpCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gY2xlYXIgc2V0IiwgIWhzLmNvbnRhaW5zKGkubmV4dCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxpbmtlZEhhc2hTZXQjY2xvbmUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvbmUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IGphdmEudXRpbC5MaW5rZWRIYXNoU2V0LmNsb25lKCkKKyAgICAgICAgTGlua2VkSGFzaFNldCBoczIgPSAoTGlua2VkSGFzaFNldCkgaHMuY2xvbmUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiY2xvbmUgcmV0dXJuZWQgYW4gZXF1aXZhbGVudCBMaW5rZWRIYXNoU2V0IiwgaHMgIT0gaHMyKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiY2xvbmUgZGlkIG5vdCByZXR1cm4gYW4gZXF1YWwgTGlua2VkSGFzaFNldCIsIGhzCisgICAgICAgICAgICAgICAgLmVxdWFscyhoczIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaFNldCNjb250YWlucyhqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY29udGFpbnNMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4KKyAgICAgICAgLy8gamF2YS51dGlsLkxpbmtlZEhhc2hTZXQuY29udGFpbnMoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZmFsc2UgZm9yIHZhbGlkIG9iamVjdCIsIGhzLmNvbnRhaW5zKG9iakFycmF5WzkwXSkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCB0cnVlIGZvciBpbnZhbGlkIE9iamVjdCIsICFocworICAgICAgICAgICAgICAgIC5jb250YWlucyhuZXcgT2JqZWN0KCkpKTsKKworICAgICAgICBMaW5rZWRIYXNoU2V0IHMgPSBuZXcgTGlua2VkSGFzaFNldCgpOworICAgICAgICBzLmFkZChudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2Fubm90IGhhbmRsZSBudWxsIiwgcy5jb250YWlucyhudWxsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxpbmtlZEhhc2hTZXQjaXNFbXB0eSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0VtcHR5KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuTGlua2VkSGFzaFNldC5pc0VtcHR5KCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRW1wdHkgc2V0IHJldHVybmVkIGZhbHNlIiwgbmV3IExpbmtlZEhhc2hTZXQoKS5pc0VtcHR5KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJOb24tZW1wdHkgc2V0IHJldHVybmVkIHRydWUiLCAhaHMuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkSGFzaFNldCNpdGVyYXRvcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pdGVyYXRvcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5JdGVyYXRvciBqYXZhLnV0aWwuTGlua2VkSGFzaFNldC5pdGVyYXRvcigpCisgICAgICAgIEl0ZXJhdG9yIGkgPSBocy5pdGVyYXRvcigpOworICAgICAgICBpbnQgeCA9IDA7CisgICAgICAgIGludCBqOworICAgICAgICBmb3IgKGogPSAwOyBpLmhhc05leHQoKTsgaisrKSB7CisgICAgICAgICAgICBPYmplY3Qgb28gPSBpLm5leHQoKTsKKyAgICAgICAgICAgIGlmIChvbyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgSW50ZWdlciBpaSA9IChJbnRlZ2VyKSBvbzsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZWxlbWVudCBmb3VuZCIsIGlpLmludFZhbHVlKCkgPT0gaik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIkNhbm5vdCBmaW5kIG51bGwiLCBocy5jb250YWlucyhvbykpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgKyt4OworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGl0ZXJhdGlvbiBvZiBpbmNvcnJlY3Qgc2l6ZSIsIGhzLnNpemUoKSA9PSB4KTsKKworICAgICAgICBMaW5rZWRIYXNoU2V0IHMgPSBuZXcgTGlua2VkSGFzaFNldCgpOworICAgICAgICBzLmFkZChudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiQ2Fubm90IGhhbmRsZSBudWxsIiwgcy5pdGVyYXRvcigpLm5leHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxpbmtlZEhhc2hTZXQjcmVtb3ZlKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZW1vdmVMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4KKyAgICAgICAgLy8gamF2YS51dGlsLkxpbmtlZEhhc2hTZXQucmVtb3ZlKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIGludCBzaXplID0gaHMuc2l6ZSgpOworICAgICAgICBocy5yZW1vdmUobmV3IEludGVnZXIoOTgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIHJlbW92ZSBlbGVtZW50IiwgIWhzLmNvbnRhaW5zKG5ldyBJbnRlZ2VyKDk4KSkpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZGVjcmVtZW50IHNldCBzaXplIiwgaHMuc2l6ZSgpID09IHNpemUgLSAxKTsKKworICAgICAgICBMaW5rZWRIYXNoU2V0IHMgPSBuZXcgTGlua2VkSGFzaFNldCgpOworICAgICAgICBzLmFkZChudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2Fubm90IGhhbmRsZSBudWxsIiwgcy5yZW1vdmUobnVsbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRIYXNoU2V0I3NpemUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2l6ZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuTGlua2VkSGFzaFNldC5zaXplKCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IHNpemUiLCBocy5zaXplKCkgPT0gKG9iakFycmF5Lmxlbmd0aCArIDEpKTsKKyAgICAgICAgaHMuY2xlYXIoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJDbGVhcmVkIHNldCByZXR1cm5lZCBub24temVybyBzaXplIiwgMCwgaHMuc2l6ZSgpKTsKKyAgICB9CisKKyAgICBjbGFzcyBNb2NrX0xpbmtlZEhhc2hTZXQgZXh0ZW5kcyBMaW5rZWRIYXNoU2V0IHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIHJldGFpbkFsbChDb2xsZWN0aW9uIGMpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9yZXRhaW5BbGxMamF2YV91dGlsX0NvbGxlY3Rpb24oKSB7CisgICAgICAgIExpbmtlZEhhc2hTZXQ8SW50ZWdlcj4gbGhzID0gbmV3IExpbmtlZEhhc2hTZXQ8SW50ZWdlcj4oKTsKKyAgICAgICAgVmVjdG9yIHYgPSBuZXcgVmVjdG9yPEZsb2F0PigpOworICAgICAgICB2LmFkZChuZXcgRmxvYXQoMy4xNCkpOworICAgICAgICBsaHMuYWRkKG5ldyBJbnRlZ2VyKDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGxocy5zaXplKCkpOworICAgICAgICBsaHMucmV0YWluQWxsKHYpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbGhzLnNpemUoKSk7CisgICAgICAgIHYgPSBuZXcgVmVjdG9yPEludGVnZXI+KCk7CisgICAgICAgIHYuYWRkKG5ldyBJbnRlZ2VyKDEpKTsKKyAgICAgICAgdi5hZGQobmV3IEludGVnZXIoMikpOworICAgICAgICB2LmFkZChuZXcgSW50ZWdlcigzKSk7CisgICAgICAgIHYuYWRkKG5ldyBJbnRlZ2VyKDQpKTsKKyAgICAgICAgdi5hZGQobmV3IEludGVnZXIoNSkpOworICAgICAgICB2LmFkZChuZXcgSW50ZWdlcig2KSk7CisgICAgICAgIGxocy5hZGQobmV3IEludGVnZXIoMSkpOworICAgICAgICBsaHMuYWRkKG5ldyBJbnRlZ2VyKDYpKTsKKyAgICAgICAgbGhzLmFkZChuZXcgSW50ZWdlcig3KSk7CisgICAgICAgIGxocy5hZGQobmV3IEludGVnZXIoOCkpOworICAgICAgICBsaHMuYWRkKG5ldyBJbnRlZ2VyKDkpKTsKKyAgICAgICAgbGhzLmFkZChuZXcgSW50ZWdlcigxMCkpOworICAgICAgICBsaHMuYWRkKG5ldyBJbnRlZ2VyKDExKSk7CisgICAgICAgIGxocy5hZGQobmV3IEludGVnZXIoMTIpKTsKKyAgICAgICAgbGhzLmFkZChuZXcgSW50ZWdlcigxMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoOSwgbGhzLnNpemUoKSk7CisgICAgICAgIGxocy5yZXRhaW5BbGwodik7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBsaHMuc2l6ZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbGhzLnJldGFpbkFsbChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIGxocyA9IG5ldyBNb2NrX0xpbmtlZEhhc2hTZXQoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbGhzLnJldGFpbkFsbCh2KTsKKyAgICAgICAgICAgIGZhaWwoIlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9BcnJheSgpIHsKKyAgICAgICAgTGlua2VkSGFzaFNldDxJbnRlZ2VyPiBsaHMgPSBuZXcgTGlua2VkSGFzaFNldDxJbnRlZ2VyPigpOworICAgICAgICBsaHMuYWRkKG5ldyBJbnRlZ2VyKDEpKTsKKyAgICAgICAgbGhzLmFkZChuZXcgSW50ZWdlcig2KSk7CisgICAgICAgIGxocy5hZGQobmV3IEludGVnZXIoNykpOworICAgICAgICBsaHMuYWRkKG5ldyBJbnRlZ2VyKDgpKTsKKyAgICAgICAgbGhzLmFkZChuZXcgSW50ZWdlcig5KSk7CisgICAgICAgIGxocy5hZGQobmV3IEludGVnZXIoMTApKTsKKyAgICAgICAgbGhzLmFkZChuZXcgSW50ZWdlcigxMSkpOworICAgICAgICBsaHMuYWRkKG5ldyBJbnRlZ2VyKDEyKSk7CisgICAgICAgIGxocy5hZGQobmV3IEludGVnZXIoMTMpKTsKKworICAgICAgICBPYmplY3RbXSBvID0gbGhzLnRvQXJyYXkoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGxocy5jb250YWlucyhvW2ldKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxocy5zaXplKCksIG8ubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvQXJyYXkkTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIExpbmtlZEhhc2hTZXQ8SW50ZWdlcj4gbGhzID0gbmV3IExpbmtlZEhhc2hTZXQ8SW50ZWdlcj4oKTsKKyAgICAgICAgbGhzLmFkZChuZXcgSW50ZWdlcigxKSk7CisgICAgICAgIGxocy5hZGQobmV3IEludGVnZXIoNikpOworICAgICAgICBsaHMuYWRkKG5ldyBJbnRlZ2VyKDcpKTsKKyAgICAgICAgbGhzLmFkZChuZXcgSW50ZWdlcig4KSk7CisgICAgICAgIGxocy5hZGQobmV3IEludGVnZXIoOSkpOworICAgICAgICBsaHMuYWRkKG5ldyBJbnRlZ2VyKDEwKSk7CisgICAgICAgIGxocy5hZGQobmV3IEludGVnZXIoMTEpKTsKKyAgICAgICAgbGhzLmFkZChuZXcgSW50ZWdlcigxMikpOworICAgICAgICBsaHMuYWRkKG5ldyBJbnRlZ2VyKDEzKSk7CisKKyAgICAgICAgT2JqZWN0W10gbzEgPSBuZXcgT2JqZWN0W2xocy5zaXplKCldOworICAgICAgICBPYmplY3RbXSBvMiA9IG5ldyBEb3VibGVbbGhzLnNpemUoKV07CisgICAgICAgIGxocy50b0FycmF5KG8xKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvMS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShsaHMuY29udGFpbnMobzFbaV0pKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsaHMudG9BcnJheShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsaHMudG9BcnJheShvMik7CisgICAgICAgICAgICBmYWlsKCJBcnJheVN0b3JlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIG9iakFycmF5ID0gbmV3IE9iamVjdFsxMDAwXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvYmpBcnJheS5sZW5ndGg7IGkrKykKKyAgICAgICAgICAgIG9iakFycmF5W2ldID0gbmV3IEludGVnZXIoaSk7CisKKyAgICAgICAgaHMgPSBuZXcgTGlua2VkSGFzaFNldCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iakFycmF5Lmxlbmd0aDsgaSsrKQorICAgICAgICAgICAgaHMuYWRkKG9iakFycmF5W2ldKTsKKyAgICAgICAgaHMuYWRkKG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgICAgICBvYmpBcnJheSA9IG51bGw7CisgICAgICAgIGhzID0gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9MaW5rZWRMaXN0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvTGlua2VkTGlzdFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMGNlYzQ1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvTGlua2VkTGlzdFRlc3QuamF2YQpAQCAtMCwwICsxLDY1OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdEl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworCisKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfTGlzdFRlc3Q7CisKK3B1YmxpYyBjbGFzcyBMaW5rZWRMaXN0VGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBMaW5rZWRMaXN0IGxsOworCisgICAgT2JqZWN0W10gb2JqQXJyYXk7CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkTGlzdCNMaW5rZWRMaXN0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLkxpbmtlZExpc3QoKQorICAgICAgICBuZXcgU3VwcG9ydF9MaXN0VGVzdCgiIiwgbGwpLnJ1blRlc3QoKTsKKworICAgICAgICBMaW5rZWRMaXN0IHN1Ykxpc3QgPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICBmb3IgKGludCBpID0gLTUwOyBpIDwgMTUwOyBpKyspCisgICAgICAgICAgICBzdWJMaXN0LmFkZChuZXcgSW50ZWdlcihpKSk7CisgICAgICAgIG5ldyBTdXBwb3J0X0xpc3RUZXN0KCIiLCBzdWJMaXN0LnN1Ykxpc3QoNTAsIDE1MCkpLnJ1blRlc3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkTGlzdCNMaW5rZWRMaXN0KGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV91dGlsX0NvbGxlY3Rpb24oKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuTGlua2VkTGlzdChqYXZhLnV0aWwuQ29sbGVjdGlvbikKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IExpbmtlZExpc3QgY29uc3RydWN0ZWQiLCBuZXcgTGlua2VkTGlzdChsbCkKKyAgICAgICAgICAgICAgICAuZXF1YWxzKGxsKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBMaW5rZWRMaXN0KG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxpbmtlZExpc3QjYWRkKGludCwgamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZElMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkxpbmtlZExpc3QuYWRkKGludCwgamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgT2JqZWN0IG87CisgICAgICAgIGxsLmFkZCg1MCwgbyA9ICJUZXN0Iik7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBhZGQgT2JqZWN0PjogIiArIGxsLmdldCg1MCkudG9TdHJpbmcoKSwgbGwKKyAgICAgICAgICAgICAgICAuZ2V0KDUwKSA9PSBvKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGZpeCB1cCBsaXN0IGFmdGVyIGluc2VydCIsCisgICAgICAgICAgICAgICAgbGwuZ2V0KDUxKSA9PSBvYmpBcnJheVs1MF0gJiYgKGxsLmdldCg1MikgPT0gb2JqQXJyYXlbNTFdKSk7CisgICAgICAgIGxsLmFkZCg1MCwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoIkRpZCBub3QgYWRkIG51bGwgY29ycmVjdGx5IiwgbGwuZ2V0KDUwKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxpbmtlZExpc3QjYWRkKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4gamF2YS51dGlsLkxpbmtlZExpc3QuYWRkKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIE9iamVjdCBvOworICAgICAgICBsbC5hZGQobyA9IG5ldyBPYmplY3QoKSk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBhZGQgT2JqZWN0IiwgbGwuZ2V0TGFzdCgpID09IG8pOworICAgICAgICBsbC5hZGQobnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoIkRpZCBub3QgYWRkIG51bGwgY29ycmVjdGx5IiwgbGwuZ2V0KGxsLnNpemUoKSAtIDEpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkTGlzdCNhZGRBbGwoaW50LCBqYXZhLnV0aWwuQ29sbGVjdGlvbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZEFsbElMamF2YV91dGlsX0NvbGxlY3Rpb24oKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEudXRpbC5MaW5rZWRMaXN0LmFkZEFsbChpbnQsCisgICAgICAgIC8vIGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAgICBsbC5hZGRBbGwoNTAsIChDb2xsZWN0aW9uKSBsbC5jbG9uZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3Qgc2l6ZSBhZnRlciBhZGRpbmcgdG8gZXhpc3RpbmcgbGlzdCIsIDIwMCwgbGwKKyAgICAgICAgICAgICAgICAuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA1MDsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTWFuaXB1bGF0ZWQgZWxlbWVudHMgPCBpbmRleCIsIGxsLmdldChpKSA9PSBvYmpBcnJheVtpXSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpID49IDUwICYmIChpIDwgMTUwKTsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGFkIGVsZW1lbnRzIHByb3Blcmx5IiwKKyAgICAgICAgICAgICAgICAgICAgbGwuZ2V0KGkpID09IG9iakFycmF5W2kgLSA1MF0pOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA+PSAxNTAgJiYgKGkgPCAyMDApOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gYWQgZWxlbWVudHMgcHJvcGVybHkiLAorICAgICAgICAgICAgICAgICAgICBsbC5nZXQoaSkgPT0gb2JqQXJyYXlbaSAtIDEwMF0pOworICAgICAgICBMaXN0IG15TGlzdCA9IG5ldyBMaW5rZWRMaXN0KCk7CisgICAgICAgIG15TGlzdC5hZGQobnVsbCk7CisgICAgICAgIG15TGlzdC5hZGQoIkJsYWgiKTsKKyAgICAgICAgbXlMaXN0LmFkZChudWxsKTsKKyAgICAgICAgbXlMaXN0LmFkZCgiQm9vZ2EiKTsKKyAgICAgICAgbXlMaXN0LmFkZChudWxsKTsKKyAgICAgICAgbGwuYWRkQWxsKDUwLCBteUxpc3QpOworICAgICAgICBhc3NlcnROdWxsKCJhKSBMaXN0IHcvbnVsbHMgbm90IGFkZGVkIGNvcnJlY3RseSIsIGxsLmdldCg1MCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImIpIExpc3Qgdy9udWxscyBub3QgYWRkZWQgY29ycmVjdGx5IiwKKyAgICAgICAgICAgICAgICAiQmxhaCIsIGxsLmdldCg1MSkpOworICAgICAgICBhc3NlcnROdWxsKCJjKSBMaXN0IHcvbnVsbHMgbm90IGFkZGVkIGNvcnJlY3RseSIsIGxsLmdldCg1MikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImQpIExpc3Qgdy9udWxscyBub3QgYWRkZWQgY29ycmVjdGx5IiwKKyAgICAgICAgICAgICAgICAiQm9vZ2EiLCBsbC5nZXQoNTMpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZSkgTGlzdCB3L251bGxzIG5vdCBhZGRlZCBjb3JyZWN0bHkiLCBsbC5nZXQoNTQpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbGwuYWRkQWxsKC0xLCAoQ29sbGVjdGlvbikgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxsLmFkZEFsbChsbC5zaXplKCkgKyAxLCAoQ29sbGVjdGlvbikgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxsLmFkZEFsbCgwLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRMaXN0I2FkZEFsbChpbnQsIGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkQWxsSUxqYXZhX3V0aWxfQ29sbGVjdGlvbl8yKCkgeworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTQ2NworICAgICAgICBMaW5rZWRMaXN0IG9iaiA9IG5ldyBMaW5rZWRMaXN0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmouYWRkQWxsKC0xLCAoQ29sbGVjdGlvbikgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxpbmtlZExpc3QjYWRkQWxsKGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkQWxsTGphdmFfdXRpbF9Db2xsZWN0aW9uKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbgorICAgICAgICAvLyBqYXZhLnV0aWwuTGlua2VkTGlzdC5hZGRBbGwoamF2YS51dGlsLkNvbGxlY3Rpb24pCisgICAgICAgIExpc3QgbCA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgbC5hZGRBbGwoKENvbGxlY3Rpb24pIGxsLmNsb25lKCkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxsLnNpemUoKTsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGFkZCBlbGVtZW50cyBwcm9wZXJseSIsIGwuZ2V0KGkpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgbGwuZ2V0KGkpKSk7CisgICAgICAgIGxsLmFkZEFsbCgoQ29sbGVjdGlvbikgbGwuY2xvbmUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IHNpWmUgYWZ0ZXIgYWRkaW5nIHRvIGV4aXN0aW5nIGxpc3QiLCAyMDAsIGxsCisgICAgICAgICAgICAgICAgLnNpemUoKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFkZGVkIHRvIGxpc3QgaW4gaW5jb3JyZWN0IG9yZGVyIiwgbGwuZ2V0KGkpLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgbC5nZXQoaSkpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBhZGQgdG8gZXhpc3RpbmcgbGlzdCIsIGxsLmdldChpICsgMTAwKQorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKGwuZ2V0KGkpKSk7CisgICAgICAgIH0KKyAgICAgICAgTGlzdCBteUxpc3QgPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICBteUxpc3QuYWRkKG51bGwpOworICAgICAgICBteUxpc3QuYWRkKCJCbGFoIik7CisgICAgICAgIG15TGlzdC5hZGQobnVsbCk7CisgICAgICAgIG15TGlzdC5hZGQoIkJvb2dhIik7CisgICAgICAgIG15TGlzdC5hZGQobnVsbCk7CisgICAgICAgIGxsLmFkZEFsbChteUxpc3QpOworICAgICAgICBhc3NlcnROdWxsKCJhKSBMaXN0IHcvbnVsbHMgbm90IGFkZGVkIGNvcnJlY3RseSIsIGxsLmdldCgyMDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiKSBMaXN0IHcvbnVsbHMgbm90IGFkZGVkIGNvcnJlY3RseSIsCisgICAgICAgICAgICAgICAgIkJsYWgiLCBsbC5nZXQoMjAxKSk7CisgICAgICAgIGFzc2VydE51bGwoImMpIExpc3Qgdy9udWxscyBub3QgYWRkZWQgY29ycmVjdGx5IiwgbGwuZ2V0KDIwMikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImQpIExpc3Qgdy9udWxscyBub3QgYWRkZWQgY29ycmVjdGx5IiwKKyAgICAgICAgICAgICAgICAiQm9vZ2EiLCBsbC5nZXQoMjAzKSk7CisgICAgICAgIGFzc2VydE51bGwoImUpIExpc3Qgdy9udWxscyBub3QgYWRkZWQgY29ycmVjdGx5IiwgbGwuZ2V0KDIwNCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsbC5hZGRBbGwobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkTGlzdCNhZGRGaXJzdChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkRmlyc3RMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLkxpbmtlZExpc3QuYWRkRmlyc3QoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgT2JqZWN0IG87CisgICAgICAgIGxsLmFkZEZpcnN0KG8gPSBuZXcgT2JqZWN0KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gYWRkIE9iamVjdCIsIGxsLmdldEZpcnN0KCkgPT0gbyk7CisgICAgICAgIGxsLmFkZEZpcnN0KG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJGYWlsZWQgdG8gYWRkIG51bGwiLCBsbC5nZXRGaXJzdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkTGlzdCNhZGRMYXN0KGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRMYXN0TGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5MaW5rZWRMaXN0LmFkZExhc3QoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgT2JqZWN0IG87CisgICAgICAgIGxsLmFkZExhc3QobyA9IG5ldyBPYmplY3QoKSk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBhZGQgT2JqZWN0IiwgbGwuZ2V0TGFzdCgpID09IG8pOworICAgICAgICBsbC5hZGRMYXN0KG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJGYWlsZWQgdG8gYWRkIG51bGwiLCBsbC5nZXRMYXN0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRMaXN0I2NsZWFyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NsZWFyKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuTGlua2VkTGlzdC5jbGVhcigpCisgICAgICAgIGxsLmNsZWFyKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGwuc2l6ZSgpOyBpKyspCisgICAgICAgICAgICBhc3NlcnROdWxsKCJGYWlsZWQgdG8gY2xlYXIgbGlzdCIsIGxsLmdldChpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxpbmtlZExpc3QjY2xvbmUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvbmUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IGphdmEudXRpbC5MaW5rZWRMaXN0LmNsb25lKCkKKyAgICAgICAgT2JqZWN0IHggPSBsbC5jbG9uZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJDbG9uZWQgbGlzdCB3YXMgaW5lcXVhbCB0byBjbG9uZWQiLCB4LmVxdWFscyhsbCkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxsLnNpemUoKTsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2xvbmVkIGxpc3QgY29udGFpbnMgaW5jb3JyZWN0IGVsZW1lbnRzIiwgbGwuZ2V0KGkpCisgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoKChMaW5rZWRMaXN0KSB4KS5nZXQoaSkpKTsKKyAgICAgICAgbGwuYWRkRmlyc3QobnVsbCk7CisgICAgICAgIHggPSBsbC5jbG9uZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJMaXN0IHdpdGggYSBudWxsIGRpZCBub3QgY2xvbmUgcHJvcGVybHkiLCBsbC5lcXVhbHMoeCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRMaXN0I2NvbnRhaW5zKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jb250YWluc0xqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbgorICAgICAgICAvLyBqYXZhLnV0aWwuTGlua2VkTGlzdC5jb250YWlucyhqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgdmFsaWQgZWxlbWVudCIsIGxsCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKG9iakFycmF5Wzk5XSkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgZXF1YWwgZWxlbWVudCIsIGxsLmNvbnRhaW5zKG5ldyBJbnRlZ2VyKAorICAgICAgICAgICAgICAgIDgpKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHRydWUgZm9yIGludmFsaWQgZWxlbWVudCIsICFsbAorICAgICAgICAgICAgICAgIC5jb250YWlucyhuZXcgT2JqZWN0KCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIG5vdCBjb250YWluIG51bGwiLCAhbGwuY29udGFpbnMobnVsbCkpOworICAgICAgICBsbC5hZGQoMjUsIG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgY29udGFpbiBudWxsIiwgbGwuY29udGFpbnMobnVsbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRMaXN0I2dldChpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdCBqYXZhLnV0aWwuTGlua2VkTGlzdC5nZXQoaW50KQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgZWxlbWVudCIsIGxsLmdldCgyMikgPT0gb2JqQXJyYXlbMjJdKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxsLmdldCg4NzY1KTsKKyAgICAgICAgICAgIGZhaWwoIkZhaWxlZCB0byB0aHJvdyBleHBlY3RlZCBleGNlcHRpb24gZm9yIGluZGV4ID4gc2l6ZSIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRMaXN0I2dldEZpcnN0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEZpcnN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdCBqYXZhLnV0aWwuTGlua2VkTGlzdC5nZXRGaXJzdCgpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBmaXJzdCBlbGVtZW50IiwgbGwuZ2V0Rmlyc3QoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgb2JqQXJyYXlbMF0pKTsKKworICAgICAgICBsbC5jbGVhcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbGwuZ2V0Rmlyc3QoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkTGlzdCNnZXRMYXN0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldExhc3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IGphdmEudXRpbC5MaW5rZWRMaXN0LmdldExhc3QoKQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgZmlyc3QgZWxlbWVudCIsIGxsLmdldExhc3QoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgb2JqQXJyYXlbb2JqQXJyYXkubGVuZ3RoIC0gMV0pKTsKKworICAgICAgICBsbC5jbGVhcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbGwuZ2V0TGFzdCgpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRMaXN0I2luZGV4T2YoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luZGV4T2ZMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuTGlua2VkTGlzdC5pbmRleE9mKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGluZGV4IiwgODcsIGxsLmluZGV4T2Yob2JqQXJyYXlbODddKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5kZXggZm9yIGludmFsaWQgT2JqZWN0IiwgLTEsIGxsCisgICAgICAgICAgICAgICAgLmluZGV4T2YobmV3IE9iamVjdCgpKSk7CisgICAgICAgIGxsLmFkZCgyMCwgbnVsbCk7CisgICAgICAgIGxsLmFkZCgyNCwgbnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoIkluZGV4IG9mIG51bGwgc2hvdWxkIGJlIDIwLCBidXQgZ290OiAiICsgbGwuaW5kZXhPZihudWxsKSwKKyAgICAgICAgICAgICAgICBsbC5pbmRleE9mKG51bGwpID09IDIwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkTGlzdCNsYXN0SW5kZXhPZihqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfbGFzdEluZGV4T2ZMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludAorICAgICAgICAvLyBqYXZhLnV0aWwuTGlua2VkTGlzdC5sYXN0SW5kZXhPZihqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBsbC5hZGQobmV3IEludGVnZXIoOTkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgaW5kZXgiLAorICAgICAgICAgICAgICAgIDEwMCwgbGwubGFzdEluZGV4T2Yob2JqQXJyYXlbOTldKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5kZXggZm9yIGludmFsaWQgT2JqZWN0IiwgLTEsIGxsCisgICAgICAgICAgICAgICAgLmxhc3RJbmRleE9mKG5ldyBPYmplY3QoKSkpOworICAgICAgICBsbC5hZGQoMjAsIG51bGwpOworICAgICAgICBsbC5hZGQoMjQsIG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJMYXN0IGluZGV4IG9mIG51bGwgc2hvdWxkIGJlIDIwLCBidXQgZ290OiAiCisgICAgICAgICAgICAgICAgKyBsbC5sYXN0SW5kZXhPZihudWxsKSwgbGwubGFzdEluZGV4T2YobnVsbCkgPT0gMjQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRMaXN0I2xpc3RJdGVyYXRvcihpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9saXN0SXRlcmF0b3JJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLkxpc3RJdGVyYXRvcgorICAgICAgICAvLyBqYXZhLnV0aWwuTGlua2VkTGlzdC5saXN0SXRlcmF0b3IoaW50KQorICAgICAgICBMaXN0SXRlcmF0b3IgaTEgPSBsbC5saXN0SXRlcmF0b3IoKTsKKyAgICAgICAgTGlzdEl0ZXJhdG9yIGkyID0gbGwubGlzdEl0ZXJhdG9yKDApOworICAgICAgICBPYmplY3QgZWxtOworICAgICAgICBpbnQgbiA9IDA7CisgICAgICAgIHdoaWxlIChpMi5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIGlmIChuID09IDAgfHwgbiA9PSBvYmpBcnJheS5sZW5ndGggLSAxKSB7CisgICAgICAgICAgICAgICAgaWYgKG4gPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmlyc3QgZWxlbWVudCBjbGFpbWVkIHRvIGhhdmUgYSBwcmV2aW91cyIsICFpMgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5oYXNQcmV2aW91cygpKTsKKyAgICAgICAgICAgICAgICBpZiAobiA9PSBvYmpBcnJheS5sZW5ndGgpCisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIkxhc3QgZWxlbWVudCBjbGFpbWVkIHRvIGhhdmUgbmV4dCIsICFpMgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5oYXNOZXh0KCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxtID0gaTIubmV4dCgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSXRlcmF0b3IgcmV0dXJuZWQgZWxlbWVudHMgaW4gd3Jvbmcgb3JkZXIiLAorICAgICAgICAgICAgICAgICAgICBlbG0gPT0gb2JqQXJyYXlbbl0pOworICAgICAgICAgICAgaWYgKG4gPiAwICYmIG4gPCBvYmpBcnJheS5sZW5ndGggLSAxKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTmV4dCBpbmRleCByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLAorICAgICAgICAgICAgICAgICAgICAgICAgaTIubmV4dEluZGV4KCkgPT0gbiArIDEpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoInByZXZpb3VzSW5kZXggcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIDogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBpMi5wcmV2aW91c0luZGV4KCkgKyAiLCBuIHZhbDogIiArIG4sIGkyCisgICAgICAgICAgICAgICAgICAgICAgICAucHJldmlvdXNJbmRleCgpID09IG4pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxtID0gaTEubmV4dCgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSXRlcmF0b3IgcmV0dXJuZWQgZWxlbWVudHMgaW4gd3Jvbmcgb3JkZXIiLAorICAgICAgICAgICAgICAgICAgICBlbG0gPT0gb2JqQXJyYXlbbl0pOworICAgICAgICAgICAgKytuOworICAgICAgICB9CisKKyAgICAgICAgaTIgPSBsbC5saXN0SXRlcmF0b3IobGwuc2l6ZSgpLzIpOworICAgICAgICBhc3NlcnRUcnVlKChJbnRlZ2VyKWkyLm5leHQoKSA9PSBsbC5zaXplKCkvMik7CisgICAgICAgIExpc3QgbXlMaXN0ID0gbmV3IExpbmtlZExpc3QoKTsKKyAgICAgICAgbXlMaXN0LmFkZChudWxsKTsKKyAgICAgICAgbXlMaXN0LmFkZCgiQmxhaCIpOworICAgICAgICBteUxpc3QuYWRkKG51bGwpOworICAgICAgICBteUxpc3QuYWRkKCJCb29nYSIpOworICAgICAgICBteUxpc3QuYWRkKG51bGwpOworICAgICAgICBMaXN0SXRlcmF0b3IgbGkgPSBteUxpc3QubGlzdEl0ZXJhdG9yKCk7CisgICAgICAgIGFzc2VydFRydWUoImxpLmhhc1ByZXZpb3VzKCkgc2hvdWxkIGJlIGZhbHNlIiwgIWxpLmhhc1ByZXZpb3VzKCkpOworICAgICAgICBhc3NlcnROdWxsKCJsaS5uZXh0KCkgc2hvdWxkIGJlIG51bGwiLCBsaS5uZXh0KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJsaS5oYXNQcmV2aW91cygpIHNob3VsZCBiZSB0cnVlIiwgbGkuaGFzUHJldmlvdXMoKSk7CisgICAgICAgIGFzc2VydE51bGwoImxpLnByZXYoKSBzaG91bGQgYmUgbnVsbCIsIGxpLnByZXZpb3VzKCkpOworICAgICAgICBhc3NlcnROdWxsKCJsaS5uZXh0KCkgc2hvdWxkIGJlIG51bGwiLCBsaS5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImxpLm5leHQoKSBzaG91bGQgYmUgQmxhaCIsICJCbGFoIiwgbGkubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgibGkubmV4dCgpIHNob3VsZCBiZSBudWxsIiwgbGkubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJsaS5uZXh0KCkgc2hvdWxkIGJlIEJvb2dhIiwgIkJvb2dhIiwgbGkubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibGkuaGFzTmV4dCgpIHNob3VsZCBiZSB0cnVlIiwgbGkuaGFzTmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgibGkubmV4dCgpIHNob3VsZCBiZSBudWxsIiwgbGkubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibGkuaGFzTmV4dCgpIHNob3VsZCBiZSBmYWxzZSIsICFsaS5oYXNOZXh0KCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsbC5saXN0SXRlcmF0b3IoLTEpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsbC5saXN0SXRlcmF0b3IobGwuc2l6ZSgpICsgMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxpbmtlZExpc3QjcmVtb3ZlKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlbW92ZUkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IGphdmEudXRpbC5MaW5rZWRMaXN0LnJlbW92ZShpbnQpCisgICAgICAgIGxsLnJlbW92ZSgxMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHRvIHJlbW92ZSBlbGVtZW50IiwgLTEsIGxsLmluZGV4T2Yob2JqQXJyYXlbMTBdKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsbC5yZW1vdmUoOTk5KTsKKyAgICAgICAgICAgIGZhaWwoIkZhaWxlZCB0byB0aHJvdyBleHBlY3RlZCBleGNlcHRpb24gd2hlbiBpbmRleCBvdXQgb2YgcmFuZ2UiKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBDb3JyZWN0CisgICAgICAgIH0KKworICAgICAgICBsbC5hZGQoMjAsIG51bGwpOworICAgICAgICBsbC5yZW1vdmUoMjApOworICAgICAgICBhc3NlcnROb3ROdWxsKCJTaG91bGQgaGF2ZSByZW1vdmVkIG51bGwiLCBsbC5nZXQoMjApKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkTGlzdCNyZW1vdmUoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlbW92ZUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuTGlua2VkTGlzdC5yZW1vdmUoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIHJlbW92ZSB2YWxpZCBPYmplY3QiLCBsbC5yZW1vdmUob2JqQXJyYXlbODddKSk7CisgICAgICAgIGFzc2VydFRydWUoIlJlbW92ZWQgaW52YWxpZCBvYmplY3QiLCAhbGwucmVtb3ZlKG5ldyBPYmplY3QoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZvdW5kIE9iamVjdCBhZnRlciByZW1vdmFsIiwgLTEsIGxsLmluZGV4T2Yob2JqQXJyYXlbODddKSk7CisgICAgICAgIGxsLmFkZChudWxsKTsKKyAgICAgICAgbGwucmVtb3ZlKG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgbm90IGNvbnRhaW4gbnVsbCBhZnJlciByZW1vdmFsIiwgIWxsLmNvbnRhaW5zKG51bGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkTGlzdCNyZW1vdmVGaXJzdCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZW1vdmVGaXJzdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QgamF2YS51dGlsLkxpbmtlZExpc3QucmVtb3ZlRmlyc3QoKQorICAgICAgICBsbC5yZW1vdmVGaXJzdCgpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gcmVtb3ZlIGZpcnN0IGVsZW1lbnQiLAorICAgICAgICAgICAgICAgIGxsLmdldEZpcnN0KCkgIT0gb2JqQXJyYXlbMF0pOworCisgICAgICAgIGxsLmNsZWFyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsbC5yZW1vdmVGaXJzdCgpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRMaXN0I3JlbW92ZUxhc3QoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlTGFzdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QgamF2YS51dGlsLkxpbmtlZExpc3QucmVtb3ZlTGFzdCgpCisgICAgICAgIGxsLnJlbW92ZUxhc3QoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIHJlbW92ZSBsYXN0IGVsZW1lbnQiLAorICAgICAgICAgICAgICAgIGxsLmdldExhc3QoKSAhPSBvYmpBcnJheVtvYmpBcnJheS5sZW5ndGggLSAxXSk7CisKKyAgICAgICAgbGwuY2xlYXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxsLnJlbW92ZUxhc3QoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkTGlzdCNzZXQoaW50LCBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0SUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdCBqYXZhLnV0aWwuTGlua2VkTGlzdC5zZXQoaW50LAorICAgICAgICAvLyBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBPYmplY3Qgb2JqOworICAgICAgICBsbC5zZXQoNjUsIG9iaiA9IG5ldyBPYmplY3QoKSk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBzZXQgb2JqZWN0IiwgbGwuZ2V0KDY1KSA9PSBvYmopOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsbC5zZXQoLTEsIG9iaiA9IG5ldyBPYmplY3QoKSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxsLnNldChsbC5zaXplKCkgKyAxLCBvYmogPSBuZXcgT2JqZWN0KCkpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5MaW5rZWRMaXN0I3NpemUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2l6ZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuTGlua2VkTGlzdC5zaXplKCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IHNpemUiLCBsbC5zaXplKCkgPT0gb2JqQXJyYXkubGVuZ3RoKTsKKyAgICAgICAgbGwucmVtb3ZlRmlyc3QoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IHNpemUiLCBsbC5zaXplKCkgPT0gb2JqQXJyYXkubGVuZ3RoIC0gMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxpbmtlZExpc3QjdG9BcnJheSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF90b0FycmF5KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdCBbXSBqYXZhLnV0aWwuTGlua2VkTGlzdC50b0FycmF5KCkKKyAgICAgICAgbGwuYWRkKG51bGwpOworICAgICAgICBPYmplY3RbXSBvYmogPSBsbC50b0FycmF5KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgYXJyYXkgb2YgaW5jb3JyZWN0IHNpemUiLCBvYmpBcnJheS5sZW5ndGggKyAxLCBvYmoubGVuZ3RoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iai5sZW5ndGggLSAxOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgYXJyYXk6ICIgKyBpLCBvYmpbaV0gPT0gb2JqQXJyYXlbaV0pOworICAgICAgICBhc3NlcnROdWxsKCJSZXR1cm5lZCBpbmNvcnJlY3QgYXJyYXktLWVuZCBpc24ndCBudWxsIiwKKyAgICAgICAgICAgICAgICBvYmpbb2JqLmxlbmd0aCAtIDFdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTGlua2VkTGlzdCN0b0FycmF5KGphdmEubGFuZy5PYmplY3RbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvQXJyYXkkTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IFtdCisgICAgICAgIC8vIGphdmEudXRpbC5MaW5rZWRMaXN0LnRvQXJyYXkoamF2YS5sYW5nLk9iamVjdCBbXSkKKyAgICAgICAgSW50ZWdlcltdIGFyZ0FycmF5ID0gbmV3IEludGVnZXJbMTAwXTsKKyAgICAgICAgT2JqZWN0W10gcmV0QXJyYXk7CisgICAgICAgIHJldEFycmF5ID0gbGwudG9BcnJheShhcmdBcnJheSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGRpZmZlcmVudCBhcnJheSB0aGFuIHBhc3NlZCIsIHJldEFycmF5ID09IGFyZ0FycmF5KTsKKyAgICAgICAgTGlzdCByZXRMaXN0ID0gbmV3IExpbmtlZExpc3QoQXJyYXlzLmFzTGlzdChyZXRBcnJheSkpOworICAgICAgICBJdGVyYXRvciBsaSA9IGxsLml0ZXJhdG9yKCk7CisgICAgICAgIEl0ZXJhdG9yIHJpID0gcmV0TGlzdC5pdGVyYXRvcigpOworICAgICAgICB3aGlsZSAobGkuaGFzTmV4dCgpKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTGlzdHMgYXJlIG5vdCBlcXVhbCIsIGxpLm5leHQoKSA9PSByaS5uZXh0KCkpOworICAgICAgICBhcmdBcnJheSA9IG5ldyBJbnRlZ2VyWzEwMDBdOworICAgICAgICByZXRBcnJheSA9IGxsLnRvQXJyYXkoYXJnQXJyYXkpOworICAgICAgICBhc3NlcnROdWxsKCJGYWlsZWQgdG8gc2V0IGZpcnN0IGV4dHJhIGVsZW1lbnQgdG8gbnVsbCIsIGFyZ0FycmF5W2xsCisgICAgICAgICAgICAgICAgLnNpemUoKV0pOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxsLnNpemUoKTsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGFycmF5OiAiICsgaSwKKyAgICAgICAgICAgICAgICAgICAgcmV0QXJyYXlbaV0gPT0gb2JqQXJyYXlbaV0pOworICAgICAgICBsbC5hZGQoNTAsIG51bGwpOworICAgICAgICBhcmdBcnJheSA9IG5ldyBJbnRlZ2VyWzEwMV07CisgICAgICAgIHJldEFycmF5ID0gbGwudG9BcnJheShhcmdBcnJheSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGRpZmZlcmVudCBhcnJheSB0aGFuIHBhc3NlZCIsIHJldEFycmF5ID09IGFyZ0FycmF5KTsKKyAgICAgICAgcmV0QXJyYXkgPSBsbC50b0FycmF5KGFyZ0FycmF5KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgZGlmZmVyZW50IGFycmF5IHRoYW4gcGFzc2VkIiwgcmV0QXJyYXkgPT0gYXJnQXJyYXkpOworICAgICAgICByZXRMaXN0ID0gbmV3IExpbmtlZExpc3QoQXJyYXlzLmFzTGlzdChyZXRBcnJheSkpOworICAgICAgICBsaSA9IGxsLml0ZXJhdG9yKCk7CisgICAgICAgIHJpID0gcmV0TGlzdC5pdGVyYXRvcigpOworICAgICAgICB3aGlsZSAobGkuaGFzTmV4dCgpKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTGlzdHMgYXJlIG5vdCBlcXVhbCIsIGxpLm5leHQoKSA9PSByaS5uZXh0KCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsbC50b0FycmF5KG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgTGlua2VkTGlzdDxTdHJpbmc+IGxscyA9IG5ldyBMaW5rZWRMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgbGxzLmFkZCgiRmlyc3QiKTsKKyAgICAgICAgbGxzLmFkZCgiU2Vjb25kIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxscy50b0FycmF5KGFyZ0FycmF5KTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5U3RvcmVFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdF9vZmZlcigpIHsKKyAgICAgICAgaW50IG9yaWdTaXplID0gbGwuc2l6ZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJvZmZlcigpIHNob3VsZCByZXR1cm4gdHJ1ZSciLCBsbC5vZmZlcihvYmpBcnJheVswXSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm9mZmVyKCkgc2hvdWxkIGFkZCBhbiBlbGVtZW50IGFzIHRoZSBsYXN0IG9uZSIsIG9yaWdTaXplLCBsbC5sYXN0SW5kZXhPZihvYmpBcnJheVswXSkpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BvbGwoKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2JqQXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygic2hvdWxkIHJlbW92ZSB0aGUgaGVhZCIsIG9iakFycmF5W2ldLCBsbC5wb2xsKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygic2hvdWxkIGJlIGVtcHR5IiwgMCwgbGwuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgic2hvdWxkIHJldHVybiAnbnVsbCcgaWYgbGlzdCBpcyBlbXB0eSIsIGxsLnBvbGwoKSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlKCkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iakFycmF5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInNob3VsZCByZW1vdmUgdGhlIGhlYWQiLCBvYmpBcnJheVtpXSwgbGwucmVtb3ZlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygic2hvdWxkIGJlIGVtcHR5IiwgMCwgbGwuc2l6ZSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxsLnJlbW92ZSgpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBpcyBleHBlY3RlZCB3aGVuIHJlbW92aW5nIGZyb20gdGhlIGVtcHR5IGxpc3QiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLy0tIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdF9lbGVtZW50KCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoInNob3VsZCByZXR1cm4gdGhlIGhlYWQiLCBvYmpBcnJheVswXSwgbGwuZWxlbWVudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50KCkgc2hvdWxkIHJlbW92ZSBub3RoaW5nIiwgb2JqQXJyYXkubGVuZ3RoLCBsbC5zaXplKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IExpbmtlZExpc3QoKS5yZW1vdmUoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaEVsZW1lbnRFeGNlcHRpb24gaXMgZXhwZWN0ZWQgd2hlbiB0aGUgbGlzdCBpcyBlbXB0eSIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vLS0gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcGVlaygpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzaG91bGQgcmVtb3ZlIHRoZSBoZWFkIiwgb2JqQXJyYXlbMF0sIGxsLnBlZWsoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygic2hvdWxkIHJlbW92ZSB0aGUgaGVhZCIsIG9iakFycmF5WzBdLCBsbC5wZWVrKCkpOworCisgICAgICAgIGxsLmNsZWFyKCk7CisKKyAgICAgICAgYXNzZXJ0TnVsbCgic2hvdWxkIHJldHVybiAnbnVsbCcgaWYgbGlzdCBpcyBlbXB0eSIsIGxsLnBlZWsoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKworICAgICAgICBvYmpBcnJheSA9IG5ldyBPYmplY3RbMTAwXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvYmpBcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgb2JqQXJyYXlbaV0gPSBuZXcgSW50ZWdlcihpKTsKKyAgICAgICAgfQorCisgICAgICAgIGxsID0gbmV3IExpbmtlZExpc3QoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvYmpBcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgbGwuYWRkKG9iakFycmF5W2ldKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG9iakFycmF5ID0gbnVsbDsKKyAgICAgICAgbGwgPSBudWxsOworCisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvTGlzdFJlc291cmNlQnVuZGxlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvTGlzdFJlc291cmNlQnVuZGxlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhiZTA0ZGIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9MaXN0UmVzb3VyY2VCdW5kbGVUZXN0LmphdmEKQEAgLTAsMCArMSw3OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKKworcHVibGljIGNsYXNzIExpc3RSZXNvdXJjZUJ1bmRsZVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZSNnZXRLZXlzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEtleXMoKSB7CisgICAgICAgIFJlc291cmNlQnVuZGxlIGJ1bmRsZTsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSAidGVzdHMuc3VwcG9ydC5TdXBwb3J0X1Rlc3RSZXNvdXJjZSI7CisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KG5ldyBMb2NhbGUoImVuIiwgIlVTIikpOworICAgICAgICBidW5kbGUgPSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUobmFtZSwgbmV3IExvY2FsZSgiZnIiLCAiRlIiLCAiVkFSIikpOworICAgICAgICBFbnVtZXJhdGlvbiBrZXlzID0gYnVuZGxlLmdldEtleXMoKTsKKyAgICAgICAgVmVjdG9yIHJlc3VsdCA9IG5ldyBWZWN0b3IoKTsKKyAgICAgICAgd2hpbGUgKGtleXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hZGRFbGVtZW50KGtleXMubmV4dEVsZW1lbnQoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTWlzc2luZyBrZXkgcGFyZW50MSIsIHJlc3VsdC5jb250YWlucygicGFyZW50MSIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTWlzc2luZyBrZXkgcGFyZW50MiIsIHJlc3VsdC5jb250YWlucygicGFyZW50MiIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTWlzc2luZyBrZXkgcGFyZW50MyIsIHJlc3VsdC5jb250YWlucygicGFyZW50MyIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTWlzc2luZyBrZXkgcGFyZW50NCIsIHJlc3VsdC5jb250YWlucygicGFyZW50NCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTWlzc2luZyBrZXkgY2hpbGQxIiwgcmVzdWx0LmNvbnRhaW5zKCJjaGlsZDEiKSk7CisgICAgICAgIGFzc2VydFRydWUoIk1pc3Npbmcga2V5IGNoaWxkMiIsIHJlc3VsdC5jb250YWlucygiY2hpbGQyIikpOworICAgICAgICBhc3NlcnRUcnVlKCJNaXNzaW5nIGtleSBjaGlsZDMiLCByZXN1bHQuY29udGFpbnMoImNoaWxkMyIpKTsKKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGFuZGxlR2V0T2JqZWN0TGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIExpc3RSZXNvdXJjZUJ1bmRsZSBidW5kbGU7CisgICAgICAgIFN0cmluZyBuYW1lID0gInRlc3RzLnN1cHBvcnQuU3VwcG9ydF9UZXN0UmVzb3VyY2UiOworICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChuZXcgTG9jYWxlKCJlbiIsICJVUyIpKTsKKyAgICAgICAgYnVuZGxlID0gKExpc3RSZXNvdXJjZUJ1bmRsZSlSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUobmFtZSwgbmV3IExvY2FsZSgiZnIiLCAiRlIiLCAiVkFSIikpOworICAgICAgICBFbnVtZXJhdGlvbiBrZXlzID0gYnVuZGxlLmdldEtleXMoKTsKKyAgICAgICAgU3RyaW5nIGtleVZhbHVlID0gbnVsbDsKKyAgICAgICAgVmVjdG9yIHJlc3VsdCA9IG5ldyBWZWN0b3IoKTsKKyAgICAgICAgd2hpbGUgKGtleXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hZGRFbGVtZW50KGJ1bmRsZS5oYW5kbGVHZXRPYmplY3QoKFN0cmluZylrZXlzLm5leHRFbGVtZW50KCkpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoOSwgcmVzdWx0LnNpemUoKSk7CisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LmNvbnRhaW5zKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQuY29udGFpbnMoImZyRlJWQVJWYWx1ZTQiKSk7CisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LmNvbnRhaW5zKCJmckZSVkFSQ2hpbGRWYWx1ZTEiKSk7CisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LmNvbnRhaW5zKCJmckZSVkFSQ2hpbGRWYWx1ZTIiKSk7CisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LmNvbnRhaW5zKCJmckZSVkFSQ2hpbGRWYWx1ZTMiKSk7CisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LnJlbW92ZShudWxsKSk7CisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LnJlbW92ZShudWxsKSk7CisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LnJlbW92ZShudWxsKSk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvTG9jYWxlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvTG9jYWxlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU1MjU1ZTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9Mb2NhbGVUZXN0LmphdmEKQEAgLTAsMCArMSw0NjcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbDsKKworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLkFuZHJvaWRPbmx5OworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Mb2NhbGU7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworcHVibGljIGNsYXNzIExvY2FsZVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgTG9jYWxlIHRlc3RMb2NhbGU7CisKKyAgICBMb2NhbGUgbDsKKworICAgIExvY2FsZSBkZWZhdWx0TG9jYWxlOworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxvY2FsZSNMb2NhbGUoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuTG9jYWxlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIExvY2FsZSB4ID0gbmV3IExvY2FsZSgieHgiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGNyZWF0ZSBMb2NhbGUiLCB4LmdldFZhcmlhbnQoKS5lcXVhbHMoIiIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IExvY2FsZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Mb2NhbGUjTG9jYWxlKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuTG9jYWxlKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIExvY2FsZSB4ID0gbmV3IExvY2FsZSgieHgiLCAiQ1YiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGNyZWF0ZSBMb2NhbGUiLCB4LmdldENvdW50cnkoKS5lcXVhbHMoIkNWIikKKyAgICAgICAgICAgICAgICAmJiB4LmdldFZhcmlhbnQoKS5lcXVhbHMoIiIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IExvY2FsZSgieHgiLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgTG9jYWxlKG51bGwsICJDViIpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxvY2FsZSNMb2NhbGUoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLkxvY2FsZShqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nLAorICAgICAgICAvLyBqYXZhLmxhbmcuU3RyaW5nKQorICAgICAgICBMb2NhbGUgeCA9IG5ldyBMb2NhbGUoInh4IiwgIkNWIiwgIlpaIik7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBjcmVhdGUgTG9jYWxlIiwgeC5nZXRMYW5ndWFnZSgpLmVxdWFscygieHgiKQorICAgICAgICAgICAgICAgICYmICh4LmdldENvdW50cnkoKS5lcXVhbHMoIkNWIikgJiYgeC5nZXRWYXJpYW50KCkuZXF1YWxzKCJaWiIpKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgIG5ldyBMb2NhbGUobnVsbCwgIkNWIiwgIlpaIik7CisgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIHdpdGggMXN0IHBhcmFtZXRlciA9PSBudWxsIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgbmV3IExvY2FsZSgieHgiLCBudWxsLCAiWloiKTsKKyAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2l0aCAybmQgcGFyYW1ldGVyID09IG51bGwiKTsKKyAgICAgICAgfSBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICBuZXcgTG9jYWxlKCJ4eCIsICJDViIsIG51bGwpOworICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aXRoIDNyZCBwYXJhbWV0ZXIgPT0gbnVsbCIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Mb2NhbGUjY2xvbmUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvbmUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IGphdmEudXRpbC5Mb2NhbGUuY2xvbmUoKQorICAgICAgICBhc3NlcnRUcnVlKCJDbG9uZSBmYWlsZWQiLCBsLmNsb25lKCkuZXF1YWxzKGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTG9jYWxlI2VxdWFscyhqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEudXRpbC5Mb2NhbGUuZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIExvY2FsZSBsMiA9IG5ldyBMb2NhbGUoImVuIiwgIkNBIiwgIldJTjMyIik7CisgICAgICAgIGFzc2VydFRydWUoIlNhbWUgb2JqZWN0IHJldHVybmVkIGZhbHNlIiwgdGVzdExvY2FsZS5lcXVhbHModGVzdExvY2FsZSkpOworICAgICAgICBhc3NlcnRUcnVlKCJTYW1lIHZhbHVlcyByZXR1cm5lZCBmYWxzZSIsIHRlc3RMb2NhbGUuZXF1YWxzKGwyKSk7CisgICAgICAgIGFzc2VydFRydWUoIkRpZmZlcmVudCBsb2NhbGVzIHJldHVybmVkIHRydWUiLCAhdGVzdExvY2FsZS5lcXVhbHMobCkpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxvY2FsZSNnZXRBdmFpbGFibGVMb2NhbGVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEF2YWlsYWJsZUxvY2FsZXMoKSB7CisvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5Mb2NhbGUgW10KKyAgICAgICAgLy8gamF2YS51dGlsLkxvY2FsZS5nZXRBdmFpbGFibGVMb2NhbGVzKCkKKyAgICAgICAgLy8gQXNzdW1lcyB0aGVyZSB3aWxsIGdlbmVyYWxseSBiZSBhYm91dCAxMCsgYXZhaWxhYmxlIGxvY2FsZXMuLi4KKyAgICAgICAgLy8gZXZlbiBpbiBtaW5pbWFsIGNvbmZpZ3VyYXRpb25zIGZvciBhbmRyb2lkCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMb2NhbGVbXSBsb2NhbGVzID0gTG9jYWxlLmdldEF2YWlsYWJsZUxvY2FsZXMoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIldyb25nIG51bWJlciBvZiBsb2NhbGVzOiAiICsgbG9jYWxlcy5sZW5ndGgsIGxvY2FsZXMubGVuZ3RoID4gMTApOworICAgICAgICAgICAgLy8gcmVncmVzc2lvbiB0ZXN0IGZvciBIQVJNT05ZLTE1MTQKKyAgICAgICAgICAgIC8vIEhhc2hTZXQgY2FuIGZpbHRlciBkdXBsaWNhdGUgbG9jYWxlcworICAgICAgICAgICAgU2V0PExvY2FsZT4gbG9jYWxlc1NldCA9IG5ldyBIYXNoU2V0PExvY2FsZT4oQXJyYXlzLmFzTGlzdChsb2NhbGVzKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobG9jYWxlc1NldC5zaXplKCksIGxvY2FsZXMubGVuZ3RoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKy8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTG9jYWxlI2dldENvdW50cnkoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Q291bnRyeSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcgamF2YS51dGlsLkxvY2FsZS5nZXRDb3VudHJ5KCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGNvdW50cnk6ICIgKyB0ZXN0TG9jYWxlLmdldENvdW50cnkoKSwKKyAgICAgICAgICAgICAgICB0ZXN0TG9jYWxlLmdldENvdW50cnkoKS5lcXVhbHMoIkNBIikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Mb2NhbGUjZ2V0RGVmYXVsdCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREZWZhdWx0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLkxvY2FsZSBqYXZhLnV0aWwuTG9jYWxlLmdldERlZmF1bHQoKQorICAgICAgICBhc3NlcnRUcnVlKCJyZXR1cm5zIGNvcHkiLCBMb2NhbGUuZ2V0RGVmYXVsdCgpID09IExvY2FsZS5nZXREZWZhdWx0KCkpOworICAgICAgICBMb2NhbGUgb3JnID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobCk7CisgICAgICAgIExvY2FsZSB4ID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQob3JnKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gZ2V0IGxvY2FsZSIsICJmcl9DQV9XSU4zMiIsIHgudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxvY2FsZSNnZXREaXNwbGF5Q291bnRyeSgpCisgICAgICovCisgICAgQEFuZHJvaWRPbmx5KCJJQ1UgaGFzIGRpZmZlcmVudCBkaXNwbGF5IG5hbWUgZm9yIGNvdW50cmllcyIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREaXNwbGF5Q291bnRyeSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcgamF2YS51dGlsLkxvY2FsZS5nZXREaXNwbGF5Q291bnRyeSgpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBjb3VudHJ5OiAiCisgICAgICAgICAgICAgICAgKyB0ZXN0TG9jYWxlLmdldERpc3BsYXlDb3VudHJ5KCksIHRlc3RMb2NhbGUKKyAgICAgICAgICAgICAgICAuZ2V0RGlzcGxheUNvdW50cnkoKS5lcXVhbHMoIkNhbmFkYSIpKTsKKworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIYXJtb255LTExNDYKKyAgICAgICAgTG9jYWxlIGxfY291bnRyeUNEID0gbmV3IExvY2FsZSgiIiwgIkNEIik7CisvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQKKy8vIElDVSBoYXMgZGlmZmVyZW50IGRpc3BsYXkgbmFtZSBmb3IgY291bnRyaWVzCisvLyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSBEZW1vY3JhdGljIFJlcHVibGljIE9mIENvbmdvIiwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgbF9jb3VudHJ5Q0QuZ2V0RGlzcGxheUNvdW50cnkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQ29uZ28gLSBLaW5zaGFzYSIsCisgICAgICAgICAgICAgIGxfY291bnRyeUNELmdldERpc3BsYXlDb3VudHJ5KCkpOworLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGlzcGxheUNvdW50cnlMamF2YV91dGlsX0xvY2FsZSgpIHsKKyAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKExvY2FsZS5JVEFMWSkpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiUmV0dXJuZWQgaW5jb3JyZWN0IGNvdW50cnkiLCAiSXRhbGllIiwgTG9jYWxlLklUQUxZLmdldERpc3BsYXlDb3VudHJ5KGwpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Mb2NhbGUjZ2V0RGlzcGxheUxhbmd1YWdlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERpc3BsYXlMYW5ndWFnZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcKKyAgICAgICAgLy8gamF2YS51dGlsLkxvY2FsZS5nZXREaXNwbGF5TGFuZ3VhZ2UoKQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgbGFuZ3VhZ2U6ICIKKyAgICAgICAgICAgICAgICArIHRlc3RMb2NhbGUuZ2V0RGlzcGxheUxhbmd1YWdlKCksIHRlc3RMb2NhbGUKKyAgICAgICAgICAgICAgICAuZ2V0RGlzcGxheUxhbmd1YWdlKCkuZXF1YWxzKCJFbmdsaXNoIikpOworCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhhcm1vbnktMTE0NgorICAgICAgICBMb2NhbGUgbF9sYW5ndWFnZUFFID0gbmV3IExvY2FsZSgiYWUiLCAiIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQXZlc3RhbiIsIGxfbGFuZ3VhZ2VBRS5nZXREaXNwbGF5TGFuZ3VhZ2UoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREaXNwbGF5TGFuZ3VhZ2VMamF2YV91dGlsX0xvY2FsZSgpIHsKKyAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKHRlc3RMb2NhbGUpKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImFuZ2xhaXMiLCB0ZXN0TG9jYWxlLmdldERpc3BsYXlMYW5ndWFnZShsKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERpc3BsYXlOYW1lKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIkVuZ2xpc2ggKENhbmFkYSxXSU4zMikiLCB0ZXN0TG9jYWxlLmdldERpc3BsYXlOYW1lKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGlzcGxheU5hbWVMamF2YV91dGlsX0xvY2FsZSgpIHsKKyAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKHRlc3RMb2NhbGUpKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImFuZ2xhaXMgKENhbmFkYSxXSU4zMikiLCB0ZXN0TG9jYWxlLmdldERpc3BsYXlOYW1lKGwpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Mb2NhbGUjZ2V0RGlzcGxheVZhcmlhbnQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGlzcGxheVZhcmlhbnQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuU3RyaW5nIGphdmEudXRpbC5Mb2NhbGUuZ2V0RGlzcGxheVZhcmlhbnQoKQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgdmFyaWFudDogIgorICAgICAgICAgICAgICAgICsgdGVzdExvY2FsZS5nZXREaXNwbGF5VmFyaWFudCgpLCB0ZXN0TG9jYWxlCisgICAgICAgICAgICAgICAgLmdldERpc3BsYXlWYXJpYW50KCkuZXF1YWxzKCJXSU4zMiIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTG9jYWxlI2dldERpc3BsYXlWYXJpYW50KGphdmEudXRpbC5Mb2NhbGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREaXNwbGF5VmFyaWFudExqYXZhX3V0aWxfTG9jYWxlKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLlN0cmluZworICAgICAgICAvLyBqYXZhLnV0aWwuTG9jYWxlLmdldERpc3BsYXlWYXJpYW50KGphdmEudXRpbC5Mb2NhbGUpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCB2YXJpYW50OiAiCisgICAgICAgICAgICAgICAgKyB0ZXN0TG9jYWxlLmdldERpc3BsYXlWYXJpYW50KGwpLCB0ZXN0TG9jYWxlCisgICAgICAgICAgICAgICAgLmdldERpc3BsYXlWYXJpYW50KGwpLmVxdWFscygiV0lOMzIiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxvY2FsZSNnZXRJU08zQ291bnRyeSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJU08zQ291bnRyeSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcgamF2YS51dGlsLkxvY2FsZS5nZXRJU08zQ291bnRyeSgpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBJU08zIGNvdW50cnk6ICIKKyAgICAgICAgICAgICAgICArIHRlc3RMb2NhbGUuZ2V0SVNPM0NvdW50cnkoKSwgdGVzdExvY2FsZS5nZXRJU08zQ291bnRyeSgpCisgICAgICAgICAgICAgICAgLmVxdWFscygiQ0FOIikpOworCisgICAgICAgIExvY2FsZSBsID0gbmV3IExvY2FsZSgiIiwgIkNEIik7CisgICAgICAgIGFzc2VydEVxdWFscygiQ09EIiwgbC5nZXRJU08zQ291bnRyeSgpKTsKKworICAgICAgICBMb2NhbGUgeCA9IG5ldyBMb2NhbGUoInh4IiwgIkMiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHguZ2V0SVNPM0NvdW50cnkoKTsKKyAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Mb2NhbGUjZ2V0SVNPM0xhbmd1YWdlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldElTTzNMYW5ndWFnZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcgamF2YS51dGlsLkxvY2FsZS5nZXRJU08zTGFuZ3VhZ2UoKQorICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgSVNPMyBsYW5ndWFnZTogIgorICAgICAgICAgICAgICAgICsgdGVzdExvY2FsZS5nZXRJU08zTGFuZ3VhZ2UoKSwgdGVzdExvY2FsZS5nZXRJU08zTGFuZ3VhZ2UoKQorICAgICAgICAgICAgICAgIC5lcXVhbHMoImVuZyIpKTsKKworICAgICAgICBMb2NhbGUgbCA9IG5ldyBMb2NhbGUoImFlIik7CisgICAgICAgIGFzc2VydEVxdWFscygiYXZlIiwgbC5nZXRJU08zTGFuZ3VhZ2UoKSk7CisKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSGFybW9ueS0xMTQ2CisgICAgICAgIExvY2FsZSBsX0NvdW50cnlDUyA9IG5ldyBMb2NhbGUoIiIsICJDUyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNDRyIsIGxfQ291bnRyeUNTLmdldElTTzNDb3VudHJ5KCkpOworCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhhcm1vbnktMTEyOQorICAgICAgICBsID0gbmV3IExvY2FsZSgiYWsiLCAiIik7CisgICAgICAgIGFzc2VydEVxdWFscygiYWthIiwgbC5nZXRJU08zTGFuZ3VhZ2UoKSk7CisKKyAgICAgICAgTG9jYWxlIHggPSBuZXcgTG9jYWxlKCJ4eCIsICJDIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB4LmdldElTTzNMYW5ndWFnZSgpOworICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxvY2FsZSNnZXRJU09Db3VudHJpZXMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SVNPQ291bnRyaWVzKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLlN0cmluZyBbXQorICAgICAgICAvLyBqYXZhLnV0aWwuTG9jYWxlLmdldElTT0NvdW50cmllcygpCisgICAgICAgIC8vIEFzc3VtZXMgYWxsIGNvdW50cmllcyBhcmUgMiBkaWdpdHMsIGFuZCB0aGF0IHRoZXJlIHdpbGwgYWx3YXlzIGJlCisgICAgICAgIC8vIDIzMCBjb3VudHJpZXMgb24gdGhlIGxpc3QuLi4KKyAgICAgICAgU3RyaW5nW10gaXNvQ291bnRyaWVzID0gTG9jYWxlLmdldElTT0NvdW50cmllcygpOworICAgICAgICBpbnQgbGVuZ3RoID0gaXNvQ291bnRyaWVzLmxlbmd0aDsKKyAgICAgICAgaW50IGZhbWlsaWFyQ291bnQgPSAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoaXNvQ291bnRyaWVzW2ldLmxlbmd0aCgpICE9IDIpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJXcm9uZyBmb3JtYXQgZm9yIElTT0NvdW50cmllcy4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChpc29Db3VudHJpZXNbaV0uZXF1YWxzKCJDQSIpIHx8IGlzb0NvdW50cmllc1tpXS5lcXVhbHMoIkJCIikKKyAgICAgICAgICAgICAgICAgICAgfHwgaXNvQ291bnRyaWVzW2ldLmVxdWFscygiVVMiKQorICAgICAgICAgICAgICAgICAgICB8fCBpc29Db3VudHJpZXNbaV0uZXF1YWxzKCJLUiIpKQorICAgICAgICAgICAgICAgIGZhbWlsaWFyQ291bnQrKzsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJU09Db3VudHJpZXMgbWlzc2luZy4iLCBmYW1pbGlhckNvdW50ID09IDQgJiYgbGVuZ3RoID4gMjMwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTG9jYWxlI2dldElTT0xhbmd1YWdlcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJU09MYW5ndWFnZXMoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuU3RyaW5nIFtdCisgICAgICAgIC8vIGphdmEudXRpbC5Mb2NhbGUuZ2V0SVNPTGFuZ3VhZ2VzKCkKKyAgICAgICAgLy8gQXNzdW1lcyBhbHdheXMgYXQgbGVhc3QgMTMxIElTT2xhbmd1YWdlcy4uLgorICAgICAgICBTdHJpbmdbXSBpc29MYW5nID0gTG9jYWxlLmdldElTT0xhbmd1YWdlcygpOworICAgICAgICBpbnQgbGVuZ3RoID0gaXNvTGFuZy5sZW5ndGg7CisKKyAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIC8vIExhbmd1YWdlIGNvZGVzIGFyZSAyLSBhbmQgMy1sZXR0ZXIsIHdpdGggcHJlZmVyZW5jZSBnaXZlbgorICAgICAgICAvLyB0byAyLWxldHRlciBjb2RlcyB3aGVyZSBwb3NzaWJsZS4gMy1sZXR0ZXIgY29kZXMgYXJlIHVzZWQKKyAgICAgICAgLy8gd2hlbiBsYWNrIGEgMi1sZXR0ZXIgZXF1aXZhbGVudC4KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmFuZG9tIGVsZW1lbnQgaW4gd3JvbmcgZm9ybWF0LiIsCisgICAgICAgICAgICAgICAgICAgKGlzb0xhbmdbbGVuZ3RoIC8gMl0ubGVuZ3RoKCkgPT0gMiB8fCBpc29MYW5nW2xlbmd0aCAvIDJdLmxlbmd0aCgpID09IDMpCisgICAgICAgICAgICAgICAgICAgJiYgaXNvTGFuZ1tsZW5ndGggLyAyXS50b0xvd2VyQ2FzZSgpLmVxdWFscyhpc29MYW5nW2xlbmd0aCAvIDJdKSk7CisgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyBudW1iZXIgb2YgSVNPTGFuZ3VhZ2VzLiIsIGxlbmd0aCA+IDEzMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxvY2FsZSNnZXRMYW5ndWFnZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRMYW5ndWFnZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcgamF2YS51dGlsLkxvY2FsZS5nZXRMYW5ndWFnZSgpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBsYW5ndWFnZTogIiArIHRlc3RMb2NhbGUuZ2V0TGFuZ3VhZ2UoKSwKKyAgICAgICAgICAgICAgICB0ZXN0TG9jYWxlLmdldExhbmd1YWdlKCkuZXF1YWxzKCJlbiIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTG9jYWxlI2dldFZhcmlhbnQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0VmFyaWFudCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcgamF2YS51dGlsLkxvY2FsZS5nZXRWYXJpYW50KCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IHZhcmlhbnQ6ICIgKyB0ZXN0TG9jYWxlLmdldFZhcmlhbnQoKSwKKyAgICAgICAgICAgICAgICB0ZXN0TG9jYWxlLmdldFZhcmlhbnQoKS5lcXVhbHMoIldJTjMyIikpOworICAgIH0KKworICAgIFNlY3VyaXR5TWFuYWdlciBzbSA9IG5ldyBTZWN1cml0eU1hbmFnZXIoKSB7CisgICAgICAgIGZpbmFsIFN0cmluZyBmb3JiaWRlblBlcm1pc3Npb25OYW1lID0gInVzZXIubGFuZ3VhZ2UiOworCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihQZXJtaXNzaW9uIHBlcm0pIHsKKyAgICAgICAgICAgIGlmIChwZXJtLmdldE5hbWUoKS5lcXVhbHMoZm9yYmlkZW5QZXJtaXNzaW9uTmFtZSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH07CisgICAgLyoqCisgICAgICogamF2YS51dGlsLkxvY2FsZSNzZXREZWZhdWx0KGphdmEudXRpbC5Mb2NhbGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXREZWZhdWx0TGphdmFfdXRpbF9Mb2NhbGUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5Mb2NhbGUuc2V0RGVmYXVsdChqYXZhLnV0aWwuTG9jYWxlKQorCisgICAgICAgIExvY2FsZSBvcmcgPSBMb2NhbGUuZ2V0RGVmYXVsdCgpOworICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChsKTsKKyAgICAgICAgTG9jYWxlIHggPSBMb2NhbGUuZ2V0RGVmYXVsdCgpOworICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChvcmcpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCB0byBzZXQgbG9jYWxlIiwgImZyX0NBX1dJTjMyIiwgeC50b1N0cmluZygpKTsKKworICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChuZXcgTG9jYWxlKCJ0ciIsICIiKSk7CisgICAgICAgIFN0cmluZyByZXMxID0gIlx1MDA2OSIudG9VcHBlckNhc2UoKTsKKyAgICAgICAgU3RyaW5nIHJlczIgPSAiXHUwMDQ5Ii50b0xvd2VyQ2FzZSgpOworICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChvcmcpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHRvVXBwZXJjYXNlIGNvbnZlcnNpb24iLCAiXHUwMTMwIiwgcmVzMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdG9Mb3dlcmNhc2UgY29udmVyc2lvbiIsICJcdTAxMzEiLCByZXMyKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTG9jYWxlI3RvU3RyaW5nKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLlN0cmluZyBqYXZhLnV0aWwuTG9jYWxlLnRvU3RyaW5nKCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3Qgc3RyaW5nIHJlcHJlc2VudGF0aW9uIiwgImVuX0NBX1dJTjMyIiwgdGVzdExvY2FsZQorICAgICAgICAgICAgICAgIC50b1N0cmluZygpKTsKKworICAgICAgICBMb2NhbGUgbCA9IG5ldyBMb2NhbGUoImVuIiwgIiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHJlcHJlc2VudGF0aW9uIDEiLCAiZW4iLCBsLnRvU3RyaW5nKCkpOworICAgICAgICBsID0gbmV3IExvY2FsZSgiIiwgIkNBIik7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcmVwcmVzZW50YXRpb24gMiIsICJfQ0EiLCBsLnRvU3RyaW5nKCkpOworICAgICAgICBsID0gbmV3IExvY2FsZSgiIiwgIkNBIiwgInZhciIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHJlcHJlc2VudGF0aW9uIDIuNSIsICJfQ0FfdmFyIiwgbC50b1N0cmluZygpKTsKKyAgICAgICAgbCA9IG5ldyBMb2NhbGUoImVuIiwgIiIsICJXSU4iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXByZXNlbnRhdGlvbiA0IiwgImVuX19XSU4iLCBsLnRvU3RyaW5nKCkpOworICAgICAgICBsID0gbmV3IExvY2FsZSgiZW4iLCAiQ0EiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXByZXNlbnRhdGlvbiA2IiwgImVuX0NBIiwgbC50b1N0cmluZygpKTsKKyAgICAgICAgbCA9IG5ldyBMb2NhbGUoImVuIiwgIkNBIiwgIlZBUiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHJlcHJlc2VudGF0aW9uIDciLCAiZW5fQ0FfVkFSIiwgbC50b1N0cmluZygpKTsKKworICAgICAgICBsID0gbmV3IExvY2FsZSgiIiwgIiIsICJ2YXIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXByZXNlbnRhdGlvbiA4IiwgIiIsIGwudG9TdHJpbmcoKSk7CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc2hDb2RlKCkgeworICAgICAgICBMb2NhbGUgbDEgPSBuZXcgTG9jYWxlKCJlbiIsICJVUyIpOworICAgICAgICBMb2NhbGUgbDIgPSBuZXcgTG9jYWxlKCJmciIsICJDQSIpOworCisgICAgICAgIGFzc2VydFRydWUobDEuaGFzaENvZGUoKSAhPSBsMi5oYXNoQ29kZSgpKTsKKyAgICB9CisKKy8vIEJFR0lOIGFuZHJvaWQtcmVtb3ZlZAorLy8gVGhlc2UgbG9jYWxlcyBhcmUgbm90IHBhcnQgb2YgdGhlIGFuZHJvaWQgcmVmZXJlbmNlIGltcGwKKy8vICAgIC8vIFJlZ3Jlc3Npb24gVGVzdCBmb3IgSEFSTU9OWS0yOTUzCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldElTTygpIHsKKy8vICAgICAgICBMb2NhbGUgbG9jYWxlID0gbmV3IExvY2FsZSgiYW4iKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImFyZyIsIGxvY2FsZS5nZXRJU08zTGFuZ3VhZ2UoKSk7CisvLworLy8gICAgICAgIGxvY2FsZSA9IG5ldyBMb2NhbGUoIlBTIik7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwdXMiLCBsb2NhbGUuZ2V0SVNPM0xhbmd1YWdlKCkpOworLy8KKy8vICAgICAgICBMaXN0PFN0cmluZz4gbGFuZ3VhZ2VzID0gQXJyYXlzLmFzTGlzdChMb2NhbGUuZ2V0SVNPTGFuZ3VhZ2VzKCkpOworLy8gICAgICAgIGFzc2VydFRydWUobGFuZ3VhZ2VzLmNvbnRhaW5zKCJhayIpKTsKKy8vCisvLyAgICAgICAgTGlzdDxTdHJpbmc+IGNvdW50cmllcyA9IEFycmF5cy5hc0xpc3QoTG9jYWxlLmdldElTT0NvdW50cmllcygpKTsKKy8vICAgICAgICBhc3NlcnRUcnVlKGNvdW50cmllcy5jb250YWlucygiQ1MiKSk7CisvLyAgICB9CisvLyBFTkQgYW5kcm9pZC1yZW1vdmVkCisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgZGVmYXVsdExvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KExvY2FsZS5VUyk7CisgICAgICAgIHRlc3RMb2NhbGUgPSBuZXcgTG9jYWxlKCJlbiIsICJDQSIsICJXSU4zMiIpOworICAgICAgICBsID0gbmV3IExvY2FsZSgiZnIiLCAiQ0EiLCAiV0lOMzIiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWFycyBkb3duIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgY2xvc2UgYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMKKyAgICAgKiBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQoZGVmYXVsdExvY2FsZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZjNzE4OWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw4NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKKworcHVibGljIGNsYXNzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiNNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbihqYXZhLmxhbmcuU3RyaW5nLAorICAgICAgICAvLyBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nKQorICAgICAgICBhc3NlcnROb3ROdWxsKG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oIkRldGFpbCBzdHJpbmciLCAiQ2xhc3MgbmFtZSBzdHJpbmciLCAiS2V5IHN0cmluZyIpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXcgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uKG51bGwsICJDbGFzcyBuYW1lIHN0cmluZyIsICJLZXkgc3RyaW5nIikpOworICAgICAgICBhc3NlcnROb3ROdWxsKG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oIkRldGFpbCBzdHJpbmciLCBudWxsLCAiS2V5IHN0cmluZyIpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXcgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uKCJEZXRhaWwgc3RyaW5nIiwgIkNsYXNzIG5hbWUgc3RyaW5nIiwgbnVsbCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKCJOb24tRXhpc3RlbnRCdW5kbGUiKTsKKyAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmYWlsKCJGYWlsZWQgdG8gZ2VuZXJhdGUgZXhwZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiNnZXRDbGFzc05hbWUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Q2xhc3NOYW1lKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLlN0cmluZworICAgICAgICAvLyBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uLmdldENsYXNzTmFtZSgpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUoIk5vbi1FeGlzdGVudEJ1bmRsZSIpOworICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgY2xhc3MgbmFtZSIsICJOb24tRXhpc3RlbnRCdW5kbGUiCisgICAgICAgICAgICAgICAgICAgICsgJ18nICsgTG9jYWxlLmdldERlZmF1bHQoKSwgZS5nZXRDbGFzc05hbWUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uI2dldEtleSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRLZXkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuU3RyaW5nCisgICAgICAgIC8vIGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24uZ2V0S2V5KCkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZSgiTm9uLUV4aXN0ZW50QnVuZGxlIik7CisgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgY2xhc3MgbmFtZSIsIGUuZ2V0S2V5KCkuZXF1YWxzKCIiKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWFycyBkb3duIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgY2xvc2UgYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMKKyAgICAgKiBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvTm9TdWNoRWxlbWVudEV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZmRhOTQxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvTm9TdWNoRWxlbWVudEV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDczIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworCitwdWJsaWMgY2xhc3MgTm9TdWNoRWxlbWVudEV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb24jTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uKCkKKworICAgICAgICBhc3NlcnROb3ROdWxsKG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoKTsKKyAgICAgICAgICAgIHYuZWxlbWVudHMoKS5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uI05vU3VjaEVsZW1lbnRFeGNlcHRpb24oamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbihqYXZhLmxhbmcuU3RyaW5nKQorCisgICAgICAgIGFzc2VydE5vdE51bGwobmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oIlN0cmluZyIpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbihudWxsKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFZlY3RvciB2ID0gbmV3IFZlY3RvcigpOworICAgICAgICAgICAgdi5maXJzdEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWFycyBkb3duIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgY2xvc2UgYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMKKyAgICAgKiBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9PYnNlcnZhYmxlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvT2JzZXJ2YWJsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYTBkMzFjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvT2JzZXJ2YWJsZVRlc3QuamF2YQpAQCAtMCwwICsxLDI0NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLk9ic2VydmFibGU7CitpbXBvcnQgamF2YS51dGlsLk9ic2VydmVyOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKK3B1YmxpYyBjbGFzcyBPYnNlcnZhYmxlVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBzdGF0aWMgY2xhc3MgVGVzdE9ic2VydmVyIGltcGxlbWVudHMgT2JzZXJ2ZXIgeworICAgICAgICBwdWJsaWMgVmVjdG9yIG9ianYgPSBuZXcgVmVjdG9yKCk7CisKKyAgICAgICAgaW50IHVwZGF0ZUNvdW50ID0gMDsKKworICAgICAgICBwdWJsaWMgdm9pZCB1cGRhdGUoT2JzZXJ2YWJsZSBvYnNlcnZlZCwgT2JqZWN0IGFyZykgeworICAgICAgICAgICAgKyt1cGRhdGVDb3VudDsKKyAgICAgICAgICAgIG9ianYuYWRkKGFyZyk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IHVwZGF0ZUNvdW50KCkgeworICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZUNvdW50OworICAgICAgICB9CisKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgRGVsZXRlVGVzdE9ic2VydmVyIGltcGxlbWVudHMgT2JzZXJ2ZXIgeworICAgICAgICBpbnQgdXBkYXRlQ291bnQgPSAwOworCisgICAgICAgIGJvb2xlYW4gZGVsZXRlQWxsID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIERlbGV0ZVRlc3RPYnNlcnZlcihib29sZWFuIGFsbCkgeworICAgICAgICAgICAgZGVsZXRlQWxsID0gYWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgdXBkYXRlKE9ic2VydmFibGUgb2JzZXJ2ZWQsIE9iamVjdCBhcmcpIHsKKyAgICAgICAgICAgICsrdXBkYXRlQ291bnQ7CisgICAgICAgICAgICBpZiAoZGVsZXRlQWxsKQorICAgICAgICAgICAgICAgIG9ic2VydmVkLmRlbGV0ZU9ic2VydmVycygpOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIG9ic2VydmVkLmRlbGV0ZU9ic2VydmVyKHRoaXMpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCB1cGRhdGVDb3VudCgpIHsKKyAgICAgICAgICAgIHJldHVybiB1cGRhdGVDb3VudDsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIFRlc3RPYnNlcnZhYmxlIGV4dGVuZHMgT2JzZXJ2YWJsZSB7CisgICAgICAgIHB1YmxpYyB2b2lkIGRvQ2hhbmdlKCkgeworICAgICAgICAgICAgc2V0Q2hhbmdlZCgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgY2xlYXJDaGFuZ2UoKSB7CisgICAgICAgICAgICBjbGVhckNoYW5nZWQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIE9ic2VydmVyIG9ic2VydmVyOworCisgICAgVGVzdE9ic2VydmFibGUgb2JzZXJ2YWJsZTsKKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5PYnNlcnZhYmxlI09ic2VydmFibGUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuT2JzZXJ2YWJsZSgpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBPYnNlcnZhYmxlIG92ID0gbmV3IE9ic2VydmFibGUoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIldyb25nIGluaXRpYWwgdmFsdWVzLiIsICFvdi5oYXNDaGFuZ2VkKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBpbml0aWFsIHZhbHVlcy4iLCAwLCBvdi5jb3VudE9ic2VydmVycygpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkV4Y2VwdGlvbiBkdXJpbmcgdGVzdCA6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuT2JzZXJ2YWJsZSNhZGRPYnNlcnZlcihqYXZhLnV0aWwuT2JzZXJ2ZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRPYnNlcnZlckxqYXZhX3V0aWxfT2JzZXJ2ZXIoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkCisgICAgICAgIC8vIGphdmEudXRpbC5PYnNlcnZhYmxlLmFkZE9ic2VydmVyKGphdmEudXRpbC5PYnNlcnZlcikKKyAgICAgICAgVGVzdE9ic2VydmVyIHRlc3QgPSBuZXcgVGVzdE9ic2VydmVyKCk7CisgICAgICAgIG9ic2VydmFibGUuYWRkT2JzZXJ2ZXIodGVzdCk7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHRvIGFkZCBvYnNlcnZlciIsIDEsIG9ic2VydmFibGUuY291bnRPYnNlcnZlcnMoKSk7CisgICAgICAgIG9ic2VydmFibGUuYWRkT2JzZXJ2ZXIodGVzdCk7CisgICAgICAgIGFzc2VydEVxdWFscygiRHVwbGljYXRlIG9ic2VydmVyIiwgMSwgb2JzZXJ2YWJsZS5jb3VudE9ic2VydmVycygpKTsKKworICAgICAgICBPYnNlcnZhYmxlIG8gPSBuZXcgT2JzZXJ2YWJsZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgby5hZGRPYnNlcnZlcihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIGFkZGluZyBhIG51bGwgb2JzZXJ2ZXIgdG8gdGhyb3cgYSBOUEUuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZDsKKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJEaWQgbm90IGV4cGVjdCBhZGRpbmcgYSBuZXcgb2JzZXJ2ZXIgdG8gdGhyb3cgYSAiCisgICAgICAgICAgICAgICAgICAgICsgZXguZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLk9ic2VydmFibGUjY291bnRPYnNlcnZlcnMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY291bnRPYnNlcnZlcnMoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLk9ic2VydmFibGUuY291bnRPYnNlcnZlcnMoKQorICAgICAgICBhc3NlcnRFcXVhbHMoIk5ldyBvYnNlcnZhYmxlIGhhZCA+IDAgb2JzZXJ2ZXJzIiwgMCwgb2JzZXJ2YWJsZQorICAgICAgICAgICAgICAgIC5jb3VudE9ic2VydmVycygpKTsKKyAgICAgICAgb2JzZXJ2YWJsZS5hZGRPYnNlcnZlcihuZXcgVGVzdE9ic2VydmVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIk9ic2VydmFibGUgd2l0aCBvYnNlcnZlciByZXR1cm5lZCBvdGhlciB0aGFuIDEiLCAxLCBvYnNlcnZhYmxlCisgICAgICAgICAgICAgICAgLmNvdW50T2JzZXJ2ZXJzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5PYnNlcnZhYmxlI2RlbGV0ZU9ic2VydmVyKGphdmEudXRpbC5PYnNlcnZlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RlbGV0ZU9ic2VydmVyTGphdmFfdXRpbF9PYnNlcnZlcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQKKyAgICAgICAgLy8gamF2YS51dGlsLk9ic2VydmFibGUuZGVsZXRlT2JzZXJ2ZXIoamF2YS51dGlsLk9ic2VydmVyKQorICAgICAgICBvYnNlcnZhYmxlLmFkZE9ic2VydmVyKG9ic2VydmVyID0gbmV3IFRlc3RPYnNlcnZlcigpKTsKKyAgICAgICAgb2JzZXJ2YWJsZS5kZWxldGVPYnNlcnZlcihvYnNlcnZlcik7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHRvIGRlbGV0ZSBvYnNlcnZlciIsCisgICAgICAgICAgICAgICAgMCwgb2JzZXJ2YWJsZS5jb3VudE9ic2VydmVycygpKTsKKyAgICAgICAgb2JzZXJ2YWJsZS5kZWxldGVPYnNlcnZlcihvYnNlcnZlcik7CisgICAgICAgIG9ic2VydmFibGUuZGVsZXRlT2JzZXJ2ZXIobnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLk9ic2VydmFibGUjZGVsZXRlT2JzZXJ2ZXJzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RlbGV0ZU9ic2VydmVycygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLk9ic2VydmFibGUuZGVsZXRlT2JzZXJ2ZXJzKCkKKyAgICAgICAgb2JzZXJ2YWJsZS5hZGRPYnNlcnZlcihuZXcgVGVzdE9ic2VydmVyKCkpOworICAgICAgICBvYnNlcnZhYmxlLmFkZE9ic2VydmVyKG5ldyBUZXN0T2JzZXJ2ZXIoKSk7CisgICAgICAgIG9ic2VydmFibGUuYWRkT2JzZXJ2ZXIobmV3IFRlc3RPYnNlcnZlcigpKTsKKyAgICAgICAgb2JzZXJ2YWJsZS5hZGRPYnNlcnZlcihuZXcgVGVzdE9ic2VydmVyKCkpOworICAgICAgICBvYnNlcnZhYmxlLmFkZE9ic2VydmVyKG5ldyBUZXN0T2JzZXJ2ZXIoKSk7CisgICAgICAgIG9ic2VydmFibGUuYWRkT2JzZXJ2ZXIobmV3IFRlc3RPYnNlcnZlcigpKTsKKyAgICAgICAgb2JzZXJ2YWJsZS5hZGRPYnNlcnZlcihuZXcgVGVzdE9ic2VydmVyKCkpOworICAgICAgICBvYnNlcnZhYmxlLmFkZE9ic2VydmVyKG5ldyBUZXN0T2JzZXJ2ZXIoKSk7CisgICAgICAgIG9ic2VydmFibGUuZGVsZXRlT2JzZXJ2ZXJzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHRvIGRlbGV0ZSBvYnNlcnZlcnMiLAorICAgICAgICAgICAgICAgIDAsIG9ic2VydmFibGUuY291bnRPYnNlcnZlcnMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLk9ic2VydmFibGUjaGFzQ2hhbmdlZCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNDaGFuZ2VkKCkgeworICAgICAgICBhc3NlcnRGYWxzZShvYnNlcnZhYmxlLmhhc0NoYW5nZWQoKSk7CisgICAgICAgIG9ic2VydmFibGUuYWRkT2JzZXJ2ZXIob2JzZXJ2ZXIgPSBuZXcgVGVzdE9ic2VydmVyKCkpOworICAgICAgICBvYnNlcnZhYmxlLmRvQ2hhbmdlKCk7CisgICAgICAgIGFzc2VydFRydWUob2JzZXJ2YWJsZS5oYXNDaGFuZ2VkKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xlYXJDaGFuZ2VkKCkgeworICAgICAgICBhc3NlcnRGYWxzZShvYnNlcnZhYmxlLmhhc0NoYW5nZWQoKSk7CisgICAgICAgIG9ic2VydmFibGUuYWRkT2JzZXJ2ZXIob2JzZXJ2ZXIgPSBuZXcgVGVzdE9ic2VydmVyKCkpOworICAgICAgICBvYnNlcnZhYmxlLmRvQ2hhbmdlKCk7CisgICAgICAgIGFzc2VydFRydWUob2JzZXJ2YWJsZS5oYXNDaGFuZ2VkKCkpOworICAgICAgICBvYnNlcnZhYmxlLmNsZWFyQ2hhbmdlKCk7CisgICAgICAgIGFzc2VydEZhbHNlKG9ic2VydmFibGUuaGFzQ2hhbmdlZCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuT2JzZXJ2YWJsZSNub3RpZnlPYnNlcnZlcnMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfbm90aWZ5T2JzZXJ2ZXJzKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnMoKQorICAgICAgICBvYnNlcnZhYmxlLmFkZE9ic2VydmVyKG9ic2VydmVyID0gbmV3IFRlc3RPYnNlcnZlcigpKTsKKyAgICAgICAgb2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJOb3RpZmllZCB3aGVuIHVuY2huYWdlZCIsIDAsICgoVGVzdE9ic2VydmVyKSBvYnNlcnZlcikKKyAgICAgICAgICAgICAgICAudXBkYXRlQ291bnQoKSk7CisgICAgICAgICgoVGVzdE9ic2VydmFibGUpIG9ic2VydmFibGUpLmRvQ2hhbmdlKCk7CisgICAgICAgIG9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHRvIG5vdGlmeSIsCisgICAgICAgICAgICAgICAgMSwgKChUZXN0T2JzZXJ2ZXIpIG9ic2VydmVyKS51cGRhdGVDb3VudCgpKTsKKworICAgICAgICBEZWxldGVUZXN0T2JzZXJ2ZXIgb2JzZXJ2ZXIxLCBvYnNlcnZlcjI7CisgICAgICAgIG9ic2VydmFibGUuZGVsZXRlT2JzZXJ2ZXJzKCk7CisgICAgICAgIG9ic2VydmFibGUuYWRkT2JzZXJ2ZXIob2JzZXJ2ZXIxID0gbmV3IERlbGV0ZVRlc3RPYnNlcnZlcihmYWxzZSkpOworICAgICAgICBvYnNlcnZhYmxlLmFkZE9ic2VydmVyKG9ic2VydmVyMiA9IG5ldyBEZWxldGVUZXN0T2JzZXJ2ZXIoZmFsc2UpKTsKKyAgICAgICAgb2JzZXJ2YWJsZS5kb0NoYW5nZSgpOworICAgICAgICBvYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycygpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gbm90aWZ5IGFsbCIsIG9ic2VydmVyMS51cGRhdGVDb3VudCgpID09IDEKKyAgICAgICAgICAgICAgICAmJiBvYnNlcnZlcjIudXBkYXRlQ291bnQoKSA9PSAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gZGVsZXRlIGFsbCIsIDAsIG9ic2VydmFibGUuY291bnRPYnNlcnZlcnMoKSk7CisKKyAgICAgICAgb2JzZXJ2YWJsZS5hZGRPYnNlcnZlcihvYnNlcnZlcjEgPSBuZXcgRGVsZXRlVGVzdE9ic2VydmVyKGZhbHNlKSk7CisgICAgICAgIG9ic2VydmFibGUuYWRkT2JzZXJ2ZXIob2JzZXJ2ZXIyID0gbmV3IERlbGV0ZVRlc3RPYnNlcnZlcihmYWxzZSkpOworICAgICAgICBvYnNlcnZhYmxlLmRvQ2hhbmdlKCk7CisgICAgICAgIG9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKCk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBub3RpZnkgYWxsIDIiLCBvYnNlcnZlcjEudXBkYXRlQ291bnQoKSA9PSAxCisgICAgICAgICAgICAgICAgJiYgb2JzZXJ2ZXIyLnVwZGF0ZUNvdW50KCkgPT0gMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHRvIGRlbGV0ZSBhbGwgMiIsIDAsIG9ic2VydmFibGUuY291bnRPYnNlcnZlcnMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLk9ic2VydmFibGUjbm90aWZ5T2JzZXJ2ZXJzKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9ub3RpZnlPYnNlcnZlcnNMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQKKyAgICAgICAgLy8gamF2YS51dGlsLk9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIE9iamVjdCBvYmo7CisgICAgICAgIG9ic2VydmFibGUuYWRkT2JzZXJ2ZXIob2JzZXJ2ZXIgPSBuZXcgVGVzdE9ic2VydmVyKCkpOworICAgICAgICBvYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycygpOworICAgICAgICBhc3NlcnRFcXVhbHMoIk5vdGlmaWVkIHdoZW4gdW5jaGFuZ2VkIiwgMCwgKChUZXN0T2JzZXJ2ZXIpIG9ic2VydmVyKQorICAgICAgICAgICAgICAgIC51cGRhdGVDb3VudCgpKTsKKyAgICAgICAgKChUZXN0T2JzZXJ2YWJsZSkgb2JzZXJ2YWJsZSkuZG9DaGFuZ2UoKTsKKyAgICAgICAgb2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnMob2JqID0gbmV3IE9iamVjdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gbm90aWZ5IiwKKyAgICAgICAgICAgICAgICAxLCAoKFRlc3RPYnNlcnZlcikgb2JzZXJ2ZXIpLnVwZGF0ZUNvdW50KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gcGFzcyBPYmplY3QgYXJnIiwgKChUZXN0T2JzZXJ2ZXIpIG9ic2VydmVyKS5vYmp2CisgICAgICAgICAgICAgICAgLmVsZW1lbnRBdCgwKS5lcXVhbHMob2JqKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIG9ic2VydmFibGUgPSBuZXcgVGVzdE9ic2VydmFibGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWFycyBkb3duIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgY2xvc2UgYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMKKyAgICAgKiBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9Qcm9wZXJ0eVJlc291cmNlQnVuZGxlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvUHJvcGVydHlSZXNvdXJjZUJ1bmRsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYzZhNGZlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvUHJvcGVydHlSZXNvdXJjZUJ1bmRsZVRlc3QuamF2YQpAQCAtMCwwICsxLDk4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydHlSZXNvdXJjZUJ1bmRsZTsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworCitwdWJsaWMgY2xhc3MgUHJvcGVydHlSZXNvdXJjZUJ1bmRsZVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgc3RhdGljIFByb3BlcnR5UmVzb3VyY2VCdW5kbGUgcHJiOworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlByb3BlcnR5UmVzb3VyY2VCdW5kbGUjUHJvcGVydHlSZXNvdXJjZUJ1bmRsZShqYXZhLmlvLklucHV0U3RyZWFtKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9pb19JbnB1dFN0cmVhbSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5Qcm9wZXJ0eVJlc291cmNlQnVuZGxlKGphdmEuaW8uSW5wdXRTdHJlYW0pCisgICAgICAgIGFzc2VydFRydWUoIlVzZWQgdG8gdGVzdCIsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Qcm9wZXJ0eVJlc291cmNlQnVuZGxlI2dldEtleXMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0S2V5cygpIHsKKyAgICAgICAgRW51bWVyYXRpb24ga2V5RW51bSA9IHByYi5nZXRLZXlzKCk7CisgICAgICAgIFZlY3RvciB0ZXN0ID0gbmV3IFZlY3RvcigpOworICAgICAgICBpbnQga2V5Q291bnQgPSAwOworICAgICAgICB3aGlsZSAoa2V5RW51bS5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgdGVzdC5hZGRFbGVtZW50KGtleUVudW0ubmV4dEVsZW1lbnQoKSk7CisgICAgICAgICAgICBrZXlDb3VudCsrOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCB0aGUgd3JvbmcgbnVtYmVyIG9mIGtleXMiLCAyLCBrZXlDb3VudCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIHRoZSB3cm9uZyBrZXlzIiwgdGVzdC5jb250YWlucygicDEiKQorICAgICAgICAgICAgICAgICYmIHRlc3QuY29udGFpbnMoInAyIikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Qcm9wZXJ0eVJlc291cmNlQnVuZGxlI2hhbmRsZUdldE9iamVjdChqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGFuZGxlR2V0T2JqZWN0TGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0CisgICAgICAgIC8vIGphdmEudXRpbC5Qcm9wZXJ0eVJlc291cmNlQnVuZGxlLmhhbmRsZUdldE9iamVjdChqYXZhLmxhbmcuU3RyaW5nKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IG9iamVjdHMiLCBwcmIuZ2V0T2JqZWN0KCJwMSIpCisgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoIm9uZSIpCisgICAgICAgICAgICAgICAgICAgICYmIHByYi5nZXRPYmplY3QoInAyIikuZXF1YWxzKCJ0d28iKSk7CisgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAiVGhyZXcgTWlzaW5nUmVzb3VyY2VFeGNlcHRpb24gZm9yIGEga2V5IGNvbnRhaW5lZCBpbiB0aGUgYnVuZGxlIik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHByYi5nZXRPYmplY3QoIk5vdCBpbiB0aGUgYnVuZGxlIik7CisgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZmFpbCgKKyAgICAgICAgICAgICAgICAiRmFpbGVkIHRvIHRocm93IE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBmb3Igb2JqZWN0IG5vdCBpbiB0aGUgYnVuZGxlIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gcHJvcGVydGllc1N0cmVhbSA9IG5ldyBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgICJwMT1vbmVcbnAyPXR3byIuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwcmIgPSBuZXcgUHJvcGVydHlSZXNvdXJjZUJ1bmRsZShwcm9wZXJ0aWVzU3RyZWFtKTsKKyAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAiQ29udHJ1Y3Rpb24gb2YgUHJvcGVydHlSZXNvdXJjZUJ1bmRsZSB0aHJldyBJT0V4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVhcnMgZG93biB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIGNsb3NlIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzCisgICAgICogbWV0aG9kIGlzIGNhbGxlZCBhZnRlciBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvUmFuZG9tVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvUmFuZG9tVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJiNzIxOTEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9SYW5kb21UZXN0LmphdmEKQEAgLTAsMCArMSwyOTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CisKK3B1YmxpYyBjbGFzcyBSYW5kb21UZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIFJhbmRvbSByOworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlJhbmRvbSNSYW5kb20oKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuUmFuZG9tKCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVXNlZCB0byB0ZXN0IiwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlJhbmRvbSNSYW5kb20obG9uZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySigpIHsKKyAgICAgICAgUmFuZG9tIHIgPSBuZXcgUmFuZG9tKDg0MDkyMzhMKTsKKyAgICAgICAgUmFuZG9tIHIyID0gbmV3IFJhbmRvbSg4NDA5MjM4TCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJWYWx1ZXMgZnJvbSByYW5kb21zIHdpdGggc2FtZSBzZWVkIGRvbid0IG1hdGNoIiwgcgorICAgICAgICAgICAgICAgICAgICAubmV4dEludCgpID09IHIyLm5leHRJbnQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlJhbmRvbSNuZXh0Qm9vbGVhbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9uZXh0Qm9vbGVhbigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4gamF2YS51dGlsLlJhbmRvbS5uZXh0Qm9vbGVhbigpCisgICAgICAgIGJvb2xlYW4gZmFsc2VBcHBlYXJlZCA9IGZhbHNlLCB0cnVlQXBwZWFyZWQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCAxMDA7IGNvdW50ZXIrKykKKyAgICAgICAgICAgIGlmIChyLm5leHRCb29sZWFuKCkpCisgICAgICAgICAgICAgICAgdHJ1ZUFwcGVhcmVkID0gdHJ1ZTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBmYWxzZUFwcGVhcmVkID0gdHJ1ZTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2FsbGluZyBuZXh0Qm9vbGVhbigpIDEwMCB0aW1lcyByZXN1bHRlZCBpbiBhbGwgdHJ1ZXMiLAorICAgICAgICAgICAgICAgIGZhbHNlQXBwZWFyZWQpOworICAgICAgICBhc3NlcnRUcnVlKCJDYWxsaW5nIG5leHRCb29sZWFuKCkgMTAwIHRpbWVzIHJlc3VsdGVkIGluIGFsbCBmYWxzZXMiLAorICAgICAgICAgICAgICAgIHRydWVBcHBlYXJlZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlJhbmRvbSNuZXh0Qnl0ZXMoYnl0ZVtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfbmV4dEJ5dGVzJEIoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5SYW5kb20ubmV4dEJ5dGVzKGJ5dGUgW10pCisgICAgICAgIGJvb2xlYW4gc29tZURpZmZlcmVudCA9IGZhbHNlOworICAgICAgICBieXRlW10gcmFuZG9tQnl0ZXMgPSBuZXcgYnl0ZVsxMDBdOworICAgICAgICByLm5leHRCeXRlcyhyYW5kb21CeXRlcyk7CisgICAgICAgIGJ5dGUgZmlyc3RCeXRlID0gcmFuZG9tQnl0ZXNbMF07CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAxOyBjb3VudGVyIDwgcmFuZG9tQnl0ZXMubGVuZ3RoOyBjb3VudGVyKyspCisgICAgICAgICAgICBpZiAocmFuZG9tQnl0ZXNbY291bnRlcl0gIT0gZmlyc3RCeXRlKQorICAgICAgICAgICAgICAgIHNvbWVEaWZmZXJlbnQgPSB0cnVlOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJuZXh0Qnl0ZXMoKSByZXR1cm5lZCBhbiBhcnJheSBvZiBsZW5ndGggMTAwIG9mIHRoZSBzYW1lIGJ5dGUiLAorICAgICAgICAgICAgICAgIHNvbWVEaWZmZXJlbnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5SYW5kb20jbmV4dERvdWJsZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9uZXh0RG91YmxlKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgZG91YmxlIGphdmEudXRpbC5SYW5kb20ubmV4dERvdWJsZSgpCisgICAgICAgIGRvdWJsZSBsYXN0TnVtID0gci5uZXh0RG91YmxlKCk7CisgICAgICAgIGRvdWJsZSBuZXh0TnVtOworICAgICAgICBib29sZWFuIHNvbWVEaWZmZXJlbnQgPSBmYWxzZTsKKyAgICAgICAgYm9vbGVhbiBpblJhbmdlID0gdHJ1ZTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCAxMDA7IGNvdW50ZXIrKykgeworICAgICAgICAgICAgbmV4dE51bSA9IHIubmV4dERvdWJsZSgpOworICAgICAgICAgICAgaWYgKG5leHROdW0gIT0gbGFzdE51bSkKKyAgICAgICAgICAgICAgICBzb21lRGlmZmVyZW50ID0gdHJ1ZTsKKyAgICAgICAgICAgIGlmICghKDAgPD0gbmV4dE51bSAmJiBuZXh0TnVtIDwgMS4wKSkKKyAgICAgICAgICAgICAgICBpblJhbmdlID0gZmFsc2U7CisgICAgICAgICAgICBsYXN0TnVtID0gbmV4dE51bTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJDYWxsaW5nIG5leHREb3VibGUgMTAwIHRpbWVzIHJlc3VsdGVkIGluIHNhbWUgbnVtYmVyIiwKKyAgICAgICAgICAgICAgICBzb21lRGlmZmVyZW50KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiQ2FsbGluZyBuZXh0RG91YmxlIHJlc3VsdGVkIGluIGEgbnVtYmVyIG91dCBvZiByYW5nZSBbMCwxKSIsCisgICAgICAgICAgICAgICAgaW5SYW5nZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlJhbmRvbSNuZXh0RmxvYXQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfbmV4dEZsb2F0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgZmxvYXQgamF2YS51dGlsLlJhbmRvbS5uZXh0RmxvYXQoKQorICAgICAgICBmbG9hdCBsYXN0TnVtID0gci5uZXh0RmxvYXQoKTsKKyAgICAgICAgZmxvYXQgbmV4dE51bTsKKyAgICAgICAgYm9vbGVhbiBzb21lRGlmZmVyZW50ID0gZmFsc2U7CisgICAgICAgIGJvb2xlYW4gaW5SYW5nZSA9IHRydWU7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgMTAwOyBjb3VudGVyKyspIHsKKyAgICAgICAgICAgIG5leHROdW0gPSByLm5leHRGbG9hdCgpOworICAgICAgICAgICAgaWYgKG5leHROdW0gIT0gbGFzdE51bSkKKyAgICAgICAgICAgICAgICBzb21lRGlmZmVyZW50ID0gdHJ1ZTsKKyAgICAgICAgICAgIGlmICghKDAgPD0gbmV4dE51bSAmJiBuZXh0TnVtIDwgMS4wKSkKKyAgICAgICAgICAgICAgICBpblJhbmdlID0gZmFsc2U7CisgICAgICAgICAgICBsYXN0TnVtID0gbmV4dE51bTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJDYWxsaW5nIG5leHRGbG9hdCAxMDAgdGltZXMgcmVzdWx0ZWQgaW4gc2FtZSBudW1iZXIiLAorICAgICAgICAgICAgICAgIHNvbWVEaWZmZXJlbnQpOworICAgICAgICBhc3NlcnRUcnVlKCJDYWxsaW5nIG5leHRGbG9hdCByZXN1bHRlZCBpbiBhIG51bWJlciBvdXQgb2YgcmFuZ2UgWzAsMSkiLAorICAgICAgICAgICAgICAgIGluUmFuZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5SYW5kb20jbmV4dEdhdXNzaWFuKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X25leHRHYXVzc2lhbigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGRvdWJsZSBqYXZhLnV0aWwuUmFuZG9tLm5leHRHYXVzc2lhbigpCisgICAgICAgIGRvdWJsZSBsYXN0TnVtID0gci5uZXh0R2F1c3NpYW4oKTsKKyAgICAgICAgZG91YmxlIG5leHROdW07CisgICAgICAgIGJvb2xlYW4gc29tZURpZmZlcmVudCA9IGZhbHNlOworICAgICAgICBib29sZWFuIHNvbWVJbnNpZGVTdGQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCAxMDA7IGNvdW50ZXIrKykgeworICAgICAgICAgICAgbmV4dE51bSA9IHIubmV4dEdhdXNzaWFuKCk7CisgICAgICAgICAgICBpZiAobmV4dE51bSAhPSBsYXN0TnVtKQorICAgICAgICAgICAgICAgIHNvbWVEaWZmZXJlbnQgPSB0cnVlOworICAgICAgICAgICAgaWYgKC0xLjAgPD0gbmV4dE51bSAmJiBuZXh0TnVtIDw9IDEuMCkKKyAgICAgICAgICAgICAgICBzb21lSW5zaWRlU3RkID0gdHJ1ZTsKKyAgICAgICAgICAgIGxhc3ROdW0gPSBuZXh0TnVtOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkNhbGxpbmcgbmV4dEdhdXNzaWFuIDEwMCB0aW1lcyByZXN1bHRlZCBpbiBzYW1lIG51bWJlciIsCisgICAgICAgICAgICAgICAgc29tZURpZmZlcmVudCk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIkNhbGxpbmcgbmV4dEdhdXNzaWFuIDEwMCB0aW1lcyByZXN1bHRlZCBpbiBubyBudW1iZXIgd2l0aGluIDEgc3RkLiBkZXZpYXRpb24gb2YgbWVhbiIsCisgICAgICAgICAgICAgICAgc29tZUluc2lkZVN0ZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlJhbmRvbSNuZXh0SW50KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X25leHRJbnQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLlJhbmRvbS5uZXh0SW50KCkKKyAgICAgICAgaW50IGxhc3ROdW0gPSByLm5leHRJbnQoKTsKKyAgICAgICAgaW50IG5leHROdW07CisgICAgICAgIGJvb2xlYW4gc29tZURpZmZlcmVudCA9IGZhbHNlOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IDEwMDsgY291bnRlcisrKSB7CisgICAgICAgICAgICBuZXh0TnVtID0gci5uZXh0SW50KCk7CisgICAgICAgICAgICBpZiAobmV4dE51bSAhPSBsYXN0TnVtKQorICAgICAgICAgICAgICAgIHNvbWVEaWZmZXJlbnQgPSB0cnVlOworICAgICAgICAgICAgbGFzdE51bSA9IG5leHROdW07CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2FsbGluZyBuZXh0SW50IDEwMCB0aW1lcyByZXN1bHRlZCBpbiBzYW1lIG51bWJlciIsCisgICAgICAgICAgICAgICAgc29tZURpZmZlcmVudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlJhbmRvbSNuZXh0SW50KGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X25leHRJbnRJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudXRpbC5SYW5kb20ubmV4dEludChpbnQpCisgICAgICAgIGZpbmFsIGludCByYW5nZSA9IDEwOworICAgICAgICBpbnQgbGFzdE51bSA9IHIubmV4dEludChyYW5nZSk7CisgICAgICAgIGludCBuZXh0TnVtOworICAgICAgICBib29sZWFuIHNvbWVEaWZmZXJlbnQgPSBmYWxzZTsKKyAgICAgICAgYm9vbGVhbiBpblJhbmdlID0gdHJ1ZTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCAxMDA7IGNvdW50ZXIrKykgeworICAgICAgICAgICAgbmV4dE51bSA9IHIubmV4dEludChyYW5nZSk7CisgICAgICAgICAgICBpZiAobmV4dE51bSAhPSBsYXN0TnVtKQorICAgICAgICAgICAgICAgIHNvbWVEaWZmZXJlbnQgPSB0cnVlOworICAgICAgICAgICAgaWYgKCEoMCA8PSBuZXh0TnVtICYmIG5leHROdW0gPCByYW5nZSkpCisgICAgICAgICAgICAgICAgaW5SYW5nZSA9IGZhbHNlOworICAgICAgICAgICAgbGFzdE51bSA9IG5leHROdW07CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2FsbGluZyBuZXh0SW50IChyYW5nZSkgMTAwIHRpbWVzIHJlc3VsdGVkIGluIHNhbWUgbnVtYmVyIiwKKyAgICAgICAgICAgICAgICBzb21lRGlmZmVyZW50KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiQ2FsbGluZyBuZXh0SW50IChyYW5nZSkgcmVzdWx0ZWQgaW4gYSBudW1iZXIgb3V0c2lkZSBvZiBbMCwgcmFuZ2UpIiwKKyAgICAgICAgICAgICAgICBpblJhbmdlKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5SYW5kb20jbmV4dExvbmcoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfbmV4dExvbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBsb25nIGphdmEudXRpbC5SYW5kb20ubmV4dExvbmcoKQorICAgICAgICBsb25nIGxhc3ROdW0gPSByLm5leHRMb25nKCk7CisgICAgICAgIGxvbmcgbmV4dE51bTsKKyAgICAgICAgYm9vbGVhbiBzb21lRGlmZmVyZW50ID0gZmFsc2U7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgMTAwOyBjb3VudGVyKyspIHsKKyAgICAgICAgICAgIG5leHROdW0gPSByLm5leHRMb25nKCk7CisgICAgICAgICAgICBpZiAobmV4dE51bSAhPSBsYXN0TnVtKQorICAgICAgICAgICAgICAgIHNvbWVEaWZmZXJlbnQgPSB0cnVlOworICAgICAgICAgICAgbGFzdE51bSA9IG5leHROdW07CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2FsbGluZyBuZXh0TG9uZyAxMDAgdGltZXMgcmVzdWx0ZWQgaW4gc2FtZSBudW1iZXIiLAorICAgICAgICAgICAgICAgIHNvbWVEaWZmZXJlbnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5SYW5kb20jc2V0U2VlZChsb25nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0U2VlZEooKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5SYW5kb20uc2V0U2VlZChsb25nKQorICAgICAgICBsb25nW10gcmFuZG9tQXJyYXkgPSBuZXcgbG9uZ1sxMDBdOworICAgICAgICBib29sZWFuIHNvbWVEaWZmZXJlbnQgPSBmYWxzZTsKKyAgICAgICAgZmluYWwgbG9uZyBmaXJzdFNlZWQgPSAxMDAwOworICAgICAgICBsb25nIGFMb25nLCBhbm90aGVyTG9uZywgeWV0QW5vdGhlckxvbmc7CisgICAgICAgIFJhbmRvbSBhUmFuZG9tID0gbmV3IFJhbmRvbSgpOworICAgICAgICBSYW5kb20gYW5vdGhlclJhbmRvbSA9IG5ldyBSYW5kb20oKTsKKyAgICAgICAgUmFuZG9tIHlldEFub3RoZXJSYW5kb20gPSBuZXcgUmFuZG9tKCk7CisgICAgICAgIGFSYW5kb20uc2V0U2VlZChmaXJzdFNlZWQpOworICAgICAgICBhbm90aGVyUmFuZG9tLnNldFNlZWQoZmlyc3RTZWVkKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IDA7IGNvdW50ZXIgPCByYW5kb21BcnJheS5sZW5ndGg7IGNvdW50ZXIrKykgeworICAgICAgICAgICAgYUxvbmcgPSBhUmFuZG9tLm5leHRMb25nKCk7CisgICAgICAgICAgICBhbm90aGVyTG9uZyA9IGFub3RoZXJSYW5kb20ubmV4dExvbmcoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJUd28gcmFuZG9tcyB3aXRoIHNhbWUgc2VlZHMgZ2F2ZSBkaWZmZXJpbmcgbmV4dExvbmcgdmFsdWVzIiwKKyAgICAgICAgICAgICAgICAgICAgYUxvbmcgPT0gYW5vdGhlckxvbmcpOworICAgICAgICAgICAgeWV0QW5vdGhlckxvbmcgPSB5ZXRBbm90aGVyUmFuZG9tLm5leHRMb25nKCk7CisgICAgICAgICAgICByYW5kb21BcnJheVtjb3VudGVyXSA9IGFMb25nOworICAgICAgICAgICAgaWYgKGFMb25nICE9IHlldEFub3RoZXJMb25nKQorICAgICAgICAgICAgICAgIHNvbWVEaWZmZXJlbnQgPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIlR3byByYW5kb21zIHdpdGggdGhlIGRpZmZlcmVudCBzZWVkcyBnYXZlIHRoZSBzYW1lIGNoYWluIG9mIHZhbHVlcyIsCisgICAgICAgICAgICAgICAgc29tZURpZmZlcmVudCk7CisgICAgICAgIGFSYW5kb20uc2V0U2VlZChmaXJzdFNlZWQpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgY291bnRlciA8IHJhbmRvbUFycmF5Lmxlbmd0aDsgY291bnRlcisrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlJlc2V0aW5nIGEgcmFuZG9tIHRvIGl0cyBvbGQgc2VlZCBkaWQgbm90IHJlc3VsdCBpbiB0aGUgc2FtZSBjaGFpbiBvZiB2YWx1ZXMgYXMgaXQgZ2F2ZSBiZWZvcmUiLAorICAgICAgICAgICAgICAgICAgICBhUmFuZG9tLm5leHRMb25nKCkgPT0gcmFuZG9tQXJyYXlbY291bnRlcl0pOworICAgIH0KKworICAgIGNsYXNzIE1vY2tfUmFuZG9tIGV4dGVuZHMgUmFuZG9tIHsKKyAgICAgICAgYm9vbGVhbiBuZXh0Q2FsbGVkID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmxhZyAoKSB7CisgICAgICAgICAgICBib29sZWFuIHJldFZhbCA9IG5leHRDYWxsZWQ7CisgICAgICAgICAgICBuZXh0Q2FsbGVkID0gZmFsc2U7CisgICAgICAgICAgICByZXR1cm4gcmV0VmFsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBpbnQgbmV4dChpbnQgYml0cykgeworICAgICAgICAgICAgbmV4dENhbGxlZCA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIubmV4dChiaXRzKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbmV4dCgpIHsKKyAgICAgICAgTW9ja19SYW5kb20gbXIgPSBuZXcgTW9ja19SYW5kb20oKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobXIuZ2V0RmxhZygpKTsKKyAgICAgICAgbXIubmV4dEJvb2xlYW4oKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtci5nZXRGbGFnKCkpOworICAgICAgICBtci5uZXh0Qnl0ZXMobmV3IGJ5dGVbMTBdKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtci5nZXRGbGFnKCkpOworICAgICAgICBtci5uZXh0RG91YmxlKCk7CisgICAgICAgIGFzc2VydFRydWUobXIuZ2V0RmxhZygpKTsKKyAgICAgICAgbXIubmV4dEZsb2F0KCk7CisgICAgICAgIGFzc2VydFRydWUobXIuZ2V0RmxhZygpKTsKKyAgICAgICAgbXIubmV4dEdhdXNzaWFuKCk7CisgICAgICAgIGFzc2VydFRydWUobXIuZ2V0RmxhZygpKTsKKyAgICAgICAgbXIubmV4dEludCgpOworICAgICAgICBhc3NlcnRUcnVlKG1yLmdldEZsYWcoKSk7CisgICAgICAgIG1yLm5leHRJbnQoMTApOworICAgICAgICBhc3NlcnRUcnVlKG1yLmdldEZsYWcoKSk7CisgICAgICAgIG1yLm5leHRMb25nKCk7CisgICAgICAgIGFzc2VydFRydWUobXIuZ2V0RmxhZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgciA9IG5ldyBSYW5kb20oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWFycyBkb3duIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgY2xvc2UgYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMKKyAgICAgKiBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9SZXNvdXJjZUJ1bmRsZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL1Jlc291cmNlQnVuZGxlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYxZmQ0ODQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9SZXNvdXJjZUJ1bmRsZVRlc3QuamF2YQpAQCAtMCwwICsxLDM5MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uS25vd25GYWlsdXJlOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEubmV0LlVSTENsYXNzTG9hZGVyOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKK2ltcG9ydCB0ZXN0cy5hcGkuamF2YS51dGlsLnN1cHBvcnQuQjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LnJlc291cmNlLlN1cHBvcnRfUmVzb3VyY2VzOworCitwdWJsaWMgY2xhc3MgUmVzb3VyY2VCdW5kbGVUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZSNnZXRCdW5kbGUoamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS51dGlsLkxvY2FsZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEJ1bmRsZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfdXRpbF9Mb2NhbGUoKSB7CisgICAgICAgIFJlc291cmNlQnVuZGxlIGJ1bmRsZTsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSAidGVzdHMuc3VwcG9ydC5TdXBwb3J0X1Rlc3RSZXNvdXJjZSI7CisgICAgICAgIExvY2FsZSBkZWZMb2NhbGUgPSBMb2NhbGUuZ2V0RGVmYXVsdCgpOworCisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KG5ldyBMb2NhbGUoImVuIiwgIlVTIikpOworICAgICAgICBidW5kbGUgPSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUobmFtZSwgbmV3IExvY2FsZSgiZnIiLCAiRlIiLCAiVkFSIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGJ1bmRsZSBmcl9GUl9WQVIiLCAiZnJGUlZBUlZhbHVlNCIsIGJ1bmRsZS5nZXRTdHJpbmcoInBhcmVudDQiKSk7CisKKyAgICAgICAgYnVuZGxlID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKG5hbWUsIG5ldyBMb2NhbGUoImZyIiwgIkZSIiwgInYxIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGJ1bmRsZSBmcl9GUl92MSIsICJmckZSVmFsdWU0IiwgYnVuZGxlLmdldFN0cmluZygicGFyZW50NCIpKTsKKworICAgICAgICBidW5kbGUgPSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUobmFtZSwgbmV3IExvY2FsZSgiZnIiLCAiVVMiLCAiVkFSIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGJ1bmRsZSBmcl9VU192YXIiLCAiZnJWYWx1ZTQiLCBidW5kbGUuZ2V0U3RyaW5nKCJwYXJlbnQ0IikpOworCisgICAgICAgIGJ1bmRsZSA9IFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShuYW1lLCBuZXcgTG9jYWxlKCJkZSIsICJGUiIsICJWQVIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgYnVuZGxlIGRlX0ZSX3ZhciIsICJlblVTVmFsdWU0IiwgYnVuZGxlLmdldFN0cmluZygicGFyZW50NCIpKTsKKworICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChuZXcgTG9jYWxlKCJmciIsICJGUiIsICJWQVIiKSk7CisgICAgICAgIGJ1bmRsZSA9IFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShuYW1lLCBuZXcgTG9jYWxlKCJkZSIsICJGUiIsICJ2MSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBidW5kbGUgZGVfRlJfdmFyIDIiLCAiZnJGUlZBUlZhbHVlNCIsIGJ1bmRsZS5nZXRTdHJpbmcoInBhcmVudDQiKSk7CisKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobmV3IExvY2FsZSgiZGUiLCAiVVMiKSk7CisgICAgICAgIGJ1bmRsZSA9IFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShuYW1lLCBuZXcgTG9jYWxlKCJkZSIsICJGUiIsICJ2YXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgYnVuZGxlIGRlX0ZSX3ZhciAyIiwgInBhcmVudFZhbHVlNCIsIGJ1bmRsZS5nZXRTdHJpbmcoInBhcmVudDQiKQorICAgICAgICAgICAgICAgICk7CisKKyAgICAgICAgLy8gVGVzdCB3aXRoIGEgc2VjdXJpdHkgbWFuYWdlcgorICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChuZXcgTG9jYWxlKCJlbiIsICJVUyIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKG51bGwsIExvY2FsZS5nZXREZWZhdWx0KCkpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUoIiIsIG5ldyBMb2NhbGUoInh4IiwgInl5IikpOworICAgICAgICAgICAgZmFpbCgiTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQoZGVmTG9jYWxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGUjZ2V0QnVuZGxlKGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgICAgIGphdmEudXRpbC5Mb2NhbGUsIGphdmEubGFuZy5DbGFzc0xvYWRlcikKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJJdCdzIG5vdCBhbGxvd2VkIHRvIHBhc3MgbnVsbCBhcyBwYXJlbnQgY2xhc3MgbG9hZGVyIHRvIgorICAgICAgICAgICAgKyAiIGEgbmV3IENsYXNzTG9hZGVyIGFueW1vcmUuIE1heWJlIHdlIG5lZWQgdG8gY2hhbmdlIgorICAgICAgICAgICAgKyAiIFVSTENsYXNzTG9hZGVyIHRvIGFsbG93IHRoaXM/IEl0J3Mgbm90IHNwZWNpZmllZC4iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0QnVuZGxlTGphdmFfbGFuZ19TdHJpbmdMamF2YV91dGlsX0xvY2FsZUxqYXZhX2xhbmdfQ2xhc3NMb2FkZXIoKSB7CisgICAgICAgIFN0cmluZyBjbGFzc1BhdGggPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuY2xhc3MucGF0aCIpOworICAgICAgICBTdHJpbmdUb2tlbml6ZXIgdG9rID0gbmV3IFN0cmluZ1Rva2VuaXplcihjbGFzc1BhdGgsIEZpbGUucGF0aFNlcGFyYXRvcik7CisgICAgICAgIFZlY3RvcjxVUkw+IHVybFZlYyA9IG5ldyBWZWN0b3I8VVJMPigpOworICAgICAgICBTdHJpbmcgcmVzUGFja2FnZSA9IFN1cHBvcnRfUmVzb3VyY2VzLlJFU09VUkNFX1BBQ0tBR0U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3aGlsZSAodG9rLmhhc01vcmVUb2tlbnMoKSkgeworICAgICAgICAgICAgICAgIFN0cmluZyBwYXRoID0gdG9rLm5leHRUb2tlbigpOworICAgICAgICAgICAgICAgIFN0cmluZyB1cmw7CisgICAgICAgICAgICAgICAgaWYgKG5ldyBGaWxlKHBhdGgpLmlzRGlyZWN0b3J5KCkpCisgICAgICAgICAgICAgICAgICAgIHVybCA9ICJmaWxlOiIgKyBwYXRoICsgcmVzUGFja2FnZSArICJzdWJmb2xkZXIvIjsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIHVybCA9ICJqYXI6ZmlsZToiICsgcGF0aCArICIhIiArIHJlc1BhY2thZ2UgKyAic3ViZm9sZGVyLyI7CisgICAgICAgICAgICAgICAgdXJsVmVjLmFkZEVsZW1lbnQobmV3IFVSTCh1cmwpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBVUkxbXSB1cmxzID0gbmV3IFVSTFt1cmxWZWMuc2l6ZSgpXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1cmxWZWMuc2l6ZSgpOyBpKyspCisgICAgICAgICAgICB1cmxzW2ldID0gdXJsVmVjLmVsZW1lbnRBdChpKTsKKyAgICAgICAgVVJMQ2xhc3NMb2FkZXIgbG9hZGVyID0gbmV3IFVSTENsYXNzTG9hZGVyKHVybHMsIG51bGwpOworCisgICAgICAgIFN0cmluZyBuYW1lID0gU3VwcG9ydF9SZXNvdXJjZXMuUkVTT1VSQ0VfUEFDS0FHRV9OQU1FCisgICAgICAgICAgICAgICAgKyAiLmh5dHNfcmVzb3VyY2UiOworICAgICAgICBSZXNvdXJjZUJ1bmRsZSBidW5kbGUgPSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUobmFtZSwgTG9jYWxlCisgICAgICAgICAgICAgICAgLmdldERlZmF1bHQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIHJlYWQiLCAicGFyZW50IiwgYnVuZGxlLmdldFN0cmluZygicHJvcGVydHkiKSk7CisgICAgICAgIGJ1bmRsZSA9IFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShuYW1lLCBMb2NhbGUuZ2V0RGVmYXVsdCgpLCBsb2FkZXIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGNhY2hlZCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgInJlc291cmNlIiwgYnVuZGxlLmdldFN0cmluZygicHJvcGVydHkiKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShudWxsLCBMb2NhbGUuZ2V0RGVmYXVsdCgpLCBsb2FkZXIpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUobmFtZSwgbnVsbCwgbG9hZGVyKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKG5hbWUsIExvY2FsZS5nZXREZWZhdWx0KCksIChDbGFzc0xvYWRlcikgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZSgiIiwgTG9jYWxlLmdldERlZmF1bHQoKSwgbG9hZGVyKTsKKyAgICAgICAgICAgIGZhaWwoIk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgSGFybW9ueS0zODIzCisgICAgICAgIEIgYmIgPSBuZXcgQigpOworICAgICAgICBTdHJpbmcgcyA9IGJiLmZpbmQoIm5vbmV4aXN0ZW50Iik7CisgICAgICAgIHMgPSBiYi5maW5kKCJuYW1lIik7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcHJvcGVydHkgZ290IiwgIk5hbWUiLCBzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGUjZ2V0U3RyaW5nKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTdHJpbmdMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgUmVzb3VyY2VCdW5kbGUgYnVuZGxlOworICAgICAgICBTdHJpbmcgbmFtZSA9ICJ0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfVGVzdFJlc291cmNlIjsKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobmV3IExvY2FsZSgiZW4iLCAiVVMiKSk7CisgICAgICAgIGJ1bmRsZSA9IFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShuYW1lLCBuZXcgTG9jYWxlKCJmciIsICJGUiIsICJWQVIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgcGFyZW50NCIsCisgICAgICAgICAgICAgICAgImZyRlJWQVJWYWx1ZTQiLCBidW5kbGUuZ2V0U3RyaW5nKCJwYXJlbnQ0IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIHBhcmVudDMiLAorICAgICAgICAgICAgICAgICJmckZSVmFsdWUzIiwgYnVuZGxlLmdldFN0cmluZygicGFyZW50MyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSBwYXJlbnQyIiwKKyAgICAgICAgICAgICAgICAiZnJWYWx1ZTIiLCBidW5kbGUuZ2V0U3RyaW5nKCJwYXJlbnQyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIHBhcmVudDEiLAorICAgICAgICAgICAgICAgICJwYXJlbnRWYWx1ZTEiLCBidW5kbGUuZ2V0U3RyaW5nKCJwYXJlbnQxIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIGNoaWxkMyIsCisgICAgICAgICAgICAgICAgImZyRlJWQVJDaGlsZFZhbHVlMyIsIGJ1bmRsZS5nZXRTdHJpbmcoImNoaWxkMyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSBjaGlsZDIiLAorICAgICAgICAgICAgICAgICJmckZSVkFSQ2hpbGRWYWx1ZTIiLCBidW5kbGUuZ2V0U3RyaW5nKCJjaGlsZDIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgY2hpbGQxIiwKKyAgICAgICAgICAgICAgICAiZnJGUlZBUkNoaWxkVmFsdWUxIiwgYnVuZGxlLmdldFN0cmluZygiY2hpbGQxIikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidW5kbGUuZ2V0U3RyaW5nKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidW5kbGUuZ2V0U3RyaW5nKCIiKTsKKyAgICAgICAgICAgIGZhaWwoIk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidW5kbGUuZ2V0U3RyaW5nKCJJbnRlZ2VyVmFsIik7CisgICAgICAgICAgICBmYWlsKCJDbGFzc0Nhc3RFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRCdW5kbGVfZ2V0Q2xhc3NOYW1lKCkgeworICAgICAgICAvLyBSZWdyZXNzaW9uIHRlc3QgZm9yIEhhcm1vbnktMTc1OQorICAgICAgICBMb2NhbGUgbG9jYWxlID0gTG9jYWxlLkdFUk1BTjsKKyAgICAgICAgU3RyaW5nIG5vbkV4aXN0ZW50QnVuZGxlID0gIk5vbi1FeGlzdGVudEJ1bmRsZSI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUobm9uRXhpc3RlbnRCdW5kbGUsIGxvY2FsZSwgdGhpcy5nZXRDbGFzcygpCisgICAgICAgICAgICAgICAgICAgIC5nZXRDbGFzc0xvYWRlcigpKTsKKyAgICAgICAgICAgIGZhaWwoIk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBleHBlY3RlZCEiKTsKKyAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhub25FeGlzdGVudEJ1bmRsZSArICJfIiArIGxvY2FsZSwgZS5nZXRDbGFzc05hbWUoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKG5vbkV4aXN0ZW50QnVuZGxlLCBsb2NhbGUpOworICAgICAgICAgICAgZmFpbCgiTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGV4cGVjdGVkISIpOworICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG5vbkV4aXN0ZW50QnVuZGxlICsgIl8iICsgbG9jYWxlLCBlLmdldENsYXNzTmFtZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGxvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUobm9uRXhpc3RlbnRCdW5kbGUpOworICAgICAgICAgICAgZmFpbCgiTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGV4cGVjdGVkISIpOworICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG5vbkV4aXN0ZW50QnVuZGxlICsgIl8iICsgbG9jYWxlLCBlLmdldENsYXNzTmFtZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIE1vY2tfUmVzb3VyY2VCdW5kbGUgZXh0ZW5kcyBSZXNvdXJjZUJ1bmRsZSB7CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXRLZXlzKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIE9iamVjdCBoYW5kbGVHZXRPYmplY3QoU3RyaW5nIGtleSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbnN0cnVjdG9yKCkgeworICAgICAgICBhc3NlcnROb3ROdWxsKG5ldyBNb2NrX1Jlc291cmNlQnVuZGxlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TG9jYWxlKCkgeworICAgICAgICBSZXNvdXJjZUJ1bmRsZSBidW5kbGU7CisgICAgICAgIFN0cmluZyBuYW1lID0gInRlc3RzLnN1cHBvcnQuU3VwcG9ydF9UZXN0UmVzb3VyY2UiOworICAgICAgICBMb2NhbGUgbG9jID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKyAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobmV3IExvY2FsZSgiZW4iLCAiVVMiKSk7CisKKyAgICAgICAgYnVuZGxlID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKG5hbWUsIG5ldyBMb2NhbGUoImZyIiwgIkZSIiwgIlZBUiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmcl9GUl9WQVIiLCBidW5kbGUuZ2V0TG9jYWxlKCkudG9TdHJpbmcoKSk7CisKKyAgICAgICAgYnVuZGxlID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKG5hbWUsIG5ldyBMb2NhbGUoImZyIiwgIkZSIiwgInYxIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZyX0ZSIiwgYnVuZGxlLmdldExvY2FsZSgpLnRvU3RyaW5nKCkpOworCisgICAgICAgIGJ1bmRsZSA9IFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShuYW1lLCBuZXcgTG9jYWxlKCJmciIsICJVUyIsICJWQVIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZnIiLCBidW5kbGUuZ2V0TG9jYWxlKCkudG9TdHJpbmcoKSk7CisKKyAgICAgICAgYnVuZGxlID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKG5hbWUsIG5ldyBMb2NhbGUoImRlIiwgIkZSIiwgIlZBUiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbl9VUyIsIGJ1bmRsZS5nZXRMb2NhbGUoKS50b1N0cmluZygpKTsKKworICAgICAgICBidW5kbGUgPSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUobmFtZSwgbmV3IExvY2FsZSgiZGUiLCAiRlIiLCAidjEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZW5fVVMiLCBidW5kbGUuZ2V0TG9jYWxlKCkudG9TdHJpbmcoKSk7CisKKyAgICAgICAgYnVuZGxlID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKG5hbWUsIG5ldyBMb2NhbGUoImRlIiwgIkZSIiwgInZhciIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbl9VUyIsIGJ1bmRsZS5nZXRMb2NhbGUoKS50b1N0cmluZygpKTsKKworICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChsb2MpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0T2JqZWN0TGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIFJlc291cmNlQnVuZGxlIGJ1bmRsZTsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSAidGVzdHMuc3VwcG9ydC5TdXBwb3J0X1Rlc3RSZXNvdXJjZSI7CisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KG5ldyBMb2NhbGUoImVuIiwgIlVTIikpOworICAgICAgICBidW5kbGUgPSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUobmFtZSwgbmV3IExvY2FsZSgiZnIiLCAiRlIiLCAiVkFSIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIHBhcmVudDQiLAorICAgICAgICAgICAgICAgICJmckZSVkFSVmFsdWU0IiwgKFN0cmluZylidW5kbGUuZ2V0T2JqZWN0KCJwYXJlbnQ0IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIHBhcmVudDMiLAorICAgICAgICAgICAgICAgICJmckZSVmFsdWUzIiwgKFN0cmluZylidW5kbGUuZ2V0T2JqZWN0KCJwYXJlbnQzIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIHBhcmVudDIiLAorICAgICAgICAgICAgICAgICJmclZhbHVlMiIsIChTdHJpbmcpIGJ1bmRsZS5nZXRPYmplY3QoInBhcmVudDIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgcGFyZW50MSIsCisgICAgICAgICAgICAgICAgInBhcmVudFZhbHVlMSIsIChTdHJpbmcpYnVuZGxlLmdldE9iamVjdCgicGFyZW50MSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSBjaGlsZDMiLAorICAgICAgICAgICAgICAgICJmckZSVkFSQ2hpbGRWYWx1ZTMiLCAoU3RyaW5nKWJ1bmRsZS5nZXRPYmplY3QoImNoaWxkMyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSBjaGlsZDIiLAorICAgICAgICAgICAgICAgICJmckZSVkFSQ2hpbGRWYWx1ZTIiLCAoU3RyaW5nKSBidW5kbGUuZ2V0T2JqZWN0KCJjaGlsZDIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgY2hpbGQxIiwKKyAgICAgICAgICAgICAgICAiZnJGUlZBUkNoaWxkVmFsdWUxIiwgKFN0cmluZylidW5kbGUuZ2V0T2JqZWN0KCJjaGlsZDEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgSW50ZWdlclZhbCIsCisgICAgICAgICAgICAgICAgMSwgYnVuZGxlLmdldE9iamVjdCgiSW50ZWdlclZhbCIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnVuZGxlLmdldE9iamVjdChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnVuZGxlLmdldE9iamVjdCgiIik7CisgICAgICAgICAgICBmYWlsKCJNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFN0cmluZ0FycmF5TGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIFJlc291cmNlQnVuZGxlIGJ1bmRsZTsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSAidGVzdHMuc3VwcG9ydC5TdXBwb3J0X1Rlc3RSZXNvdXJjZSI7CisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KG5ldyBMb2NhbGUoImVuIiwgIlVTIikpOworICAgICAgICBidW5kbGUgPSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUobmFtZSwgbmV3IExvY2FsZSgiZnIiLCAiRlIiLCAiVkFSIikpOworCisgICAgICAgIFN0cmluZ1tdIGFycmF5ID0gYnVuZGxlLmdldFN0cmluZ0FycmF5KCJTdHJpbmdBcnJheSIpOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiU3RyIiArIChpICsgMSksIGFycmF5W2ldKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidW5kbGUuZ2V0U3RyaW5nQXJyYXkobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ1bmRsZS5nZXRTdHJpbmdBcnJheSgiIik7CisgICAgICAgICAgICBmYWlsKCJNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnVuZGxlLmdldFN0cmluZ0FycmF5KCJJbnRlZ2VyVmFsIik7CisgICAgICAgICAgICBmYWlsKCJDbGFzc0Nhc3RFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEJ1bmRsZUxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICBSZXNvdXJjZUJ1bmRsZSBidW5kbGU7CisgICAgICAgIFN0cmluZyBuYW1lID0gInRlc3RzLnN1cHBvcnQuU3VwcG9ydF9UZXN0UmVzb3VyY2UiOworICAgICAgICBMb2NhbGUgZGVmTG9jYWxlID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKworICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChuZXcgTG9jYWxlKCJlbiIsICJVUyIpKTsKKyAgICAgICAgYnVuZGxlID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKG5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVuVVNWYWx1ZTQiLCBidW5kbGUuZ2V0U3RyaW5nKCJwYXJlbnQ0IikpOworCisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KG5ldyBMb2NhbGUoImZyIiwgIkZSIiwgInYxIikpOworICAgICAgICBidW5kbGUgPSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUobmFtZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgYnVuZGxlIGZyX0ZSX3YxIiwgImZyRlJWYWx1ZTQiLCBidW5kbGUuZ2V0U3RyaW5nKCJwYXJlbnQ0IikpOworCisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KG5ldyBMb2NhbGUoImZyIiwgIlVTIiwgIlZBUiIpKTsKKyAgICAgICAgYnVuZGxlID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKG5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGJ1bmRsZSBmcl9VU192YXIiLCAiZnJWYWx1ZTQiLCBidW5kbGUuZ2V0U3RyaW5nKCJwYXJlbnQ0IikpOworCisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KG5ldyBMb2NhbGUoImRlIiwgIkZSIiwgIlZBUiIpKTsKKyAgICAgICAgYnVuZGxlID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKG5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGJ1bmRsZSBkZV9GUl92YXIiLCAicGFyZW50VmFsdWU0IiwgYnVuZGxlLmdldFN0cmluZygicGFyZW50NCIpKTsKKworICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChuZXcgTG9jYWxlKCJkZSIsICJGUiIsICJ2MSIpKTsKKyAgICAgICAgYnVuZGxlID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKG5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGJ1bmRsZSBkZV9GUl92YXIgMiIsICJwYXJlbnRWYWx1ZTQiLCBidW5kbGUuZ2V0U3RyaW5nKCJwYXJlbnQ0IikpOworCisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KG5ldyBMb2NhbGUoImRlIiwgIkZSIiwgInZhciIpKTsKKyAgICAgICAgYnVuZGxlID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKG5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGJ1bmRsZSBkZV9GUl92YXIgMiIsICJwYXJlbnRWYWx1ZTQiLCBidW5kbGUuZ2V0U3RyaW5nKCJwYXJlbnQ0IikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZSgiIik7CisgICAgICAgICAgICBmYWlsKCJNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGVlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChkZWZMb2NhbGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL1NhbXBsZUJ1bmRsZUNsYXNzLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9TYW1wbGVCdW5kbGVDbGFzcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNlYjA5MDEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9TYW1wbGVCdW5kbGVDbGFzcy5qYXZhCkBAIC0wLDAgKzEsNDMgQEAKKy8qIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOworCisvKioKKyAqIFBhcnQgb2YgdGhlIFJlc291cmNlQnVuZGxlVGVzdAorICovCitwdWJsaWMgY2xhc3MgU2FtcGxlQnVuZGxlQ2xhc3MgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgU2FtcGxlQnVuZGxlQ2xhc3Mgc2luZ2xldG9uOworICAgIHByaXZhdGUgc3RhdGljIFJlc291cmNlQnVuZGxlIGJ1bmRsZTsKKworICAgIHB1YmxpYyBTYW1wbGVCdW5kbGVDbGFzcygpIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgaWYgKHNpbmdsZXRvbiAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHNpbmdsZXRvbiA9IHRoaXM7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidW5kbGUgPSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUoInRlc3RzLmFwaS5zaW1wbGUuU2FtcGxlQnVuZGxlQ2xhc3MiKTsKKyAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIHgpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTWlzc2luZyByZXNvdXJjZSIpOworICAgICAgICAgICAgYnVuZGxlID0gbnVsbDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL1NpbXBsZVRpbWVab25lVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvU2ltcGxlVGltZVpvbmVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTI3ZWMwZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL1NpbXBsZVRpbWVab25lVGVzdC5qYXZhCkBAIC0wLDAgKzEsODI3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZTsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CisKK3B1YmxpYyBjbGFzcyBTaW1wbGVUaW1lWm9uZVRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgU2ltcGxlVGltZVpvbmUgc3QxOworCisgICAgU2ltcGxlVGltZVpvbmUgc3QyOworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlNpbXBsZVRpbWVab25lI1NpbXBsZVRpbWVab25lKGludCwgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySUxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlNpbXBsZVRpbWVab25lKGludCwgamF2YS5sYW5nLlN0cmluZykKKworICAgICAgICBTaW1wbGVUaW1lWm9uZSBzdCA9IG5ldyBTaW1wbGVUaW1lWm9uZSgxMDAwLCAiVEVTVCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBUWiBjb25zdHJ1Y3RlZCIsICJURVNUIiwgc3QuZ2V0SUQoKSk7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBUWiBjb25zdHJ1Y3RlZDogIiArICJyZXR1cm5lZCB3cm9uZyBvZmZzZXQiLCBzdAorICAgICAgICAgICAgICAgIC5nZXRSYXdPZmZzZXQoKSA9PSAxMDAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IFRaIGNvbnN0cnVjdGVkIiArICJ1c2luZyBkYXlsaWdodCBzYXZpbmdzIiwgIXN0CisgICAgICAgICAgICAgICAgLnVzZURheWxpZ2h0VGltZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuU2ltcGxlVGltZVpvbmUjU2ltcGxlVGltZVpvbmUoaW50LCBqYXZhLmxhbmcuU3RyaW5nLAorICAgICAqICAgICAgICBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySUxqYXZhX2xhbmdfU3RyaW5nSUlJSUlJSUkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuU2ltcGxlVGltZVpvbmUoaW50LCBqYXZhLmxhbmcuU3RyaW5nLCBpbnQsCisgICAgICAgIC8vIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCkKKyAgICAgICAgU2ltcGxlVGltZVpvbmUgc3QgPSBuZXcgU2ltcGxlVGltZVpvbmUoMTAwMCwgIlRFU1QiLCBDYWxlbmRhci5OT1ZFTUJFUiwKKyAgICAgICAgICAgICAgICAxLCBDYWxlbmRhci5TVU5EQVksIDAsIENhbGVuZGFyLk5PVkVNQkVSLCAtMSwgQ2FsZW5kYXIuU1VOREFZLAorICAgICAgICAgICAgICAgIDApOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgVFogY29uc3RydWN0ZWQiLCBzdAorICAgICAgICAgICAgICAgIC5pbkRheWxpZ2h0VGltZShuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OCwgQ2FsZW5kYXIuTk9WRU1CRVIsCisgICAgICAgICAgICAgICAgICAgICAgICAxMykuZ2V0VGltZSgpKSk7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBUWiBjb25zdHJ1Y3RlZCIsICEoc3QKKyAgICAgICAgICAgICAgICAuaW5EYXlsaWdodFRpbWUobmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTgsIENhbGVuZGFyLk9DVE9CRVIsCisgICAgICAgICAgICAgICAgICAgICAgICAxMykuZ2V0VGltZSgpKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBUWiBjb25zdHJ1Y3RlZCIsICJURVNUIiwgc3QuZ2V0SUQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IFRaIGNvbnN0cnVjdGVkIiwgMTAwMCwgc3QuZ2V0UmF3T2Zmc2V0KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgVFogY29uc3RydWN0ZWQiLCBzdC51c2VEYXlsaWdodFRpbWUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTaW1wbGVUaW1lWm9uZSgxMDAwLCAiVEVTVCIsIDEyLAorICAgICAgICAgICAgICAgICAgICAxLCBDYWxlbmRhci5TVU5EQVksIDAsIENhbGVuZGFyLk5PVkVNQkVSLCAtMSwgQ2FsZW5kYXIuU1VOREFZLAorICAgICAgICAgICAgICAgICAgICAwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTaW1wbGVUaW1lWm9uZSgxMDAwLCAiVEVTVCIsIENhbGVuZGFyLk5PVkVNQkVSLAorICAgICAgICAgICAgICAgICAgICAxMCwgQ2FsZW5kYXIuU1VOREFZLCAwLCBDYWxlbmRhci5OT1ZFTUJFUiwgLTEsIENhbGVuZGFyLlNVTkRBWSwKKyAgICAgICAgICAgICAgICAgICAgMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2ltcGxlVGltZVpvbmUoMTAwMCwgIlRFU1QiLCBDYWxlbmRhci5OT1ZFTUJFUiwKKyAgICAgICAgICAgICAgICAgICAgMSwgMTAsIDAsIENhbGVuZGFyLk5PVkVNQkVSLCAtMSwgQ2FsZW5kYXIuU1VOREFZLAorICAgICAgICAgICAgICAgICAgICAwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTaW1wbGVUaW1lWm9uZSgxMDAwLCAiVEVTVCIsIENhbGVuZGFyLkRFQ0VNQkVSLAorICAgICAgICAgICAgICAgICAgICAxLCBDYWxlbmRhci5TVU5EQVksIDAsIENhbGVuZGFyLk5PVkVNQkVSLCAtMTAsIENhbGVuZGFyLlNVTkRBWSwKKyAgICAgICAgICAgICAgICAgICAgMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZSNTaW1wbGVUaW1lWm9uZShpbnQsIGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgICAgIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcklMamF2YV9sYW5nX1N0cmluZ0lJSUlJSUlJSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZShpbnQsIGphdmEubGFuZy5TdHJpbmcsIGludCwKKyAgICAgICAgLy8gaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQpCisgICAgICAgIFNpbXBsZVRpbWVab25lIHN0ID0gbmV3IFNpbXBsZVRpbWVab25lKDEwMDAsICJURVNUIiwgQ2FsZW5kYXIuTk9WRU1CRVIsCisgICAgICAgICAgICAgICAgMSwgQ2FsZW5kYXIuU1VOREFZLCAwLCBDYWxlbmRhci5OT1ZFTUJFUiwgLTEsIENhbGVuZGFyLlNVTkRBWSwKKyAgICAgICAgICAgICAgICAwLCAxMDAwICogNjAgKiA2MCk7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBUWiBjb25zdHJ1Y3RlZCIsIHN0CisgICAgICAgICAgICAgICAgLmluRGF5bGlnaHRUaW1lKG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk4LCBDYWxlbmRhci5OT1ZFTUJFUiwKKyAgICAgICAgICAgICAgICAgICAgICAgIDEzKS5nZXRUaW1lKCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IFRaIGNvbnN0cnVjdGVkIiwgIShzdAorICAgICAgICAgICAgICAgIC5pbkRheWxpZ2h0VGltZShuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OCwgQ2FsZW5kYXIuT0NUT0JFUiwKKyAgICAgICAgICAgICAgICAgICAgICAgIDEzKS5nZXRUaW1lKCkpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IFRaIGNvbnN0cnVjdGVkIiwgIlRFU1QiLCBzdC5nZXRJRCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgVFogY29uc3RydWN0ZWQiLCAxMDAwLCBzdC5nZXRSYXdPZmZzZXQoKSk7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBUWiBjb25zdHJ1Y3RlZCIsIHN0LnVzZURheWxpZ2h0VGltZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IFRaIGNvbnN0cnVjdGVkIiwKKyAgICAgICAgICAgICAgICBzdC5nZXREU1RTYXZpbmdzKCkgPT0gMTAwMCAqIDYwICogNjApOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2ltcGxlVGltZVpvbmUoMTAwMCwgIlRFU1QiLCAxMiwKKyAgICAgICAgICAgICAgICAgICAgMSwgQ2FsZW5kYXIuU1VOREFZLCAwLCBDYWxlbmRhci5OT1ZFTUJFUiwgLTEsIENhbGVuZGFyLlNVTkRBWSwKKyAgICAgICAgICAgICAgICAgICAgMCwgMTAwMCAqIDYwICogNjApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFNpbXBsZVRpbWVab25lKDEwMDAsICJURVNUIiwgQ2FsZW5kYXIuTk9WRU1CRVIsCisgICAgICAgICAgICAgICAgICAgIDEwLCBDYWxlbmRhci5TVU5EQVksIDAsIENhbGVuZGFyLk5PVkVNQkVSLCAtMSwgQ2FsZW5kYXIuU1VOREFZLAorICAgICAgICAgICAgICAgICAgICAwLCAxMDAwICogNjAgKiA2MCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2ltcGxlVGltZVpvbmUoMTAwMCwgIlRFU1QiLCBDYWxlbmRhci5OT1ZFTUJFUiwKKyAgICAgICAgICAgICAgICAgICAgMSwgMTAsIDAsIENhbGVuZGFyLk5PVkVNQkVSLCAtMSwgQ2FsZW5kYXIuU1VOREFZLAorICAgICAgICAgICAgICAgICAgICAwLCAxMDAwICogNjAgKiA2MCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2ltcGxlVGltZVpvbmUoMTAwMCwgIlRFU1QiLCBDYWxlbmRhci5ERUNFTUJFUiwKKyAgICAgICAgICAgICAgICAgICAgMSwgQ2FsZW5kYXIuU1VOREFZLCAwLCBDYWxlbmRhci5OT1ZFTUJFUiwgLTEwLCBDYWxlbmRhci5TVU5EQVksCisgICAgICAgICAgICAgICAgICAgIDAsIDEwMDAgKiA2MCAqIDYwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlNpbXBsZVRpbWVab25lI1NpbXBsZVRpbWVab25lKGludCwgamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcklMamF2YV9sYW5nX1N0cmluZ0lJSUlJSUlJSUlJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlNpbXBsZVRpbWVab25lKGludCwgamF2YS5sYW5nLlN0cmluZywgaW50LAorICAgICAgICAvLyBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50LCBpbnQpCisgICAgICAgIC8vIFRPRE8gOiBJbXBsZW1lbnQgdGVzdAorICAgICAgICAvL1JlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMTI0MQorICAgICAgICBhc3NlcnROb3ROdWxsKG5ldyBTaW1wbGVUaW1lWm9uZSgKKyAgICAgICAgICAgICAgICBUaW1lWm9uZS5MT05HLAorICAgICAgICAgICAgICAgICJFdXJvcGUvUGFyaXMiLAorICAgICAgICAgICAgICAgIFNpbXBsZVRpbWVab25lLlNUQU5EQVJEX1RJTUUsCisgICAgICAgICAgICAgICAgU2ltcGxlVGltZVpvbmUuU1RBTkRBUkRfVElNRSwKKyAgICAgICAgICAgICAgICBTaW1wbGVUaW1lWm9uZS5VVENfVElNRSwKKyAgICAgICAgICAgICAgICBTaW1wbGVUaW1lWm9uZS5XQUxMX1RJTUUsCisgICAgICAgICAgICAgICAgU2ltcGxlVGltZVpvbmUuV0FMTF9USU1FLAorICAgICAgICAgICAgICAgIFRpbWVab25lLlNIT1JULAorICAgICAgICAgICAgICAgIFNpbXBsZVRpbWVab25lLlNUQU5EQVJEX1RJTUUsCisgICAgICAgICAgICAgICAgVGltZVpvbmUuTE9ORywKKyAgICAgICAgICAgICAgICBTaW1wbGVUaW1lWm9uZS5VVENfVElNRSwKKyAgICAgICAgICAgICAgICBTaW1wbGVUaW1lWm9uZS5TVEFOREFSRF9USU1FLAorICAgICAgICAgICAgICAgIFRpbWVab25lLkxPTkcpKTsKKyAgICAgICAgLy9zZWVtcyBSSSBkb2Vzbid0IGNoZWNrIHRoZSBzdGFydFRpbWVNb2RlIGFuZCBlbmRUaW1lTW9kZSBhdCBhbGwKKyAgICAgICAgLy90aGlzIGJlaGF2aW9yIGlzIGNvbnRyYWRpY3RzIHdpdGggc3BlYworICAgICAgICBhc3NlcnROb3ROdWxsKG5ldyBTaW1wbGVUaW1lWm9uZSgKKyAgICAgICAgICAgICAgICBUaW1lWm9uZS5MT05HLAorICAgICAgICAgICAgICAgICJFdXJvcGUvUGFyaXMiLAorICAgICAgICAgICAgICAgIFNpbXBsZVRpbWVab25lLlNUQU5EQVJEX1RJTUUsCisgICAgICAgICAgICAgICAgU2ltcGxlVGltZVpvbmUuU1RBTkRBUkRfVElNRSwKKyAgICAgICAgICAgICAgICBTaW1wbGVUaW1lWm9uZS5VVENfVElNRSwKKyAgICAgICAgICAgICAgICBTaW1wbGVUaW1lWm9uZS5XQUxMX1RJTUUsCisgICAgICAgICAgICAgICAgSW50ZWdlci5NQVhfVkFMVUUsCisgICAgICAgICAgICAgICAgVGltZVpvbmUuU0hPUlQsCisgICAgICAgICAgICAgICAgU2ltcGxlVGltZVpvbmUuU1RBTkRBUkRfVElNRSwKKyAgICAgICAgICAgICAgICBUaW1lWm9uZS5MT05HLAorICAgICAgICAgICAgICAgIFNpbXBsZVRpbWVab25lLlVUQ19USU1FLAorICAgICAgICAgICAgICAgIEludGVnZXIuTUlOX1ZBTFVFLAorICAgICAgICAgICAgICAgIFRpbWVab25lLkxPTkcpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFNpbXBsZVRpbWVab25lKDEwMDAsICJURVNUIiwgMTIsCisgICAgICAgICAgICAgICAgICAgIDEsIENhbGVuZGFyLlNVTkRBWSwgMCwgSW50ZWdlci5NQVhfVkFMVUUsIENhbGVuZGFyLk5PVkVNQkVSLCAtMSwgQ2FsZW5kYXIuU1VOREFZLAorICAgICAgICAgICAgICAgICAgICAwLCAgSW50ZWdlci5NQVhfVkFMVUUsIDEwMDAgKiA2MCAqIDYwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTaW1wbGVUaW1lWm9uZSgxMDAwLCAiVEVTVCIsIENhbGVuZGFyLk5PVkVNQkVSLAorICAgICAgICAgICAgICAgICAgICAxMCwgQ2FsZW5kYXIuU1VOREFZLCAwLCBJbnRlZ2VyLk1BWF9WQUxVRSwgQ2FsZW5kYXIuTk9WRU1CRVIsIC0xLCBDYWxlbmRhci5TVU5EQVksCisgICAgICAgICAgICAgICAgICAgIDAsIEludGVnZXIuTUFYX1ZBTFVFLCAxMDAwICogNjAgKiA2MCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU2ltcGxlVGltZVpvbmUoMTAwMCwgIlRFU1QiLCBDYWxlbmRhci5OT1ZFTUJFUiwKKyAgICAgICAgICAgICAgICAgICAgMSwgMTAsIDAsIENhbGVuZGFyLk5PVkVNQkVSLCBJbnRlZ2VyLk1BWF9WQUxVRSwgLTEsIENhbGVuZGFyLlNVTkRBWSwKKyAgICAgICAgICAgICAgICAgICAgMCwgSW50ZWdlci5NQVhfVkFMVUUsIDEwMDAgKiA2MCAqIDYwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTaW1wbGVUaW1lWm9uZSgxMDAwLCAiVEVTVCIsIENhbGVuZGFyLkRFQ0VNQkVSLAorICAgICAgICAgICAgICAgICAgICAxLCBDYWxlbmRhci5TVU5EQVksIDAsIENhbGVuZGFyLk5PVkVNQkVSLCBJbnRlZ2VyLk1BWF9WQUxVRSwgLTEwLCBDYWxlbmRhci5TVU5EQVksCisgICAgICAgICAgICAgICAgICAgIDAsIEludGVnZXIuTUFYX1ZBTFVFLCAxMDAwICogNjAgKiA2MCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZSNjbG9uZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jbG9uZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QgamF2YS51dGlsLlNpbXBsZVRpbWVab25lLmNsb25lKCkKKyAgICAgICAgU2ltcGxlVGltZVpvbmUgc3QxID0gbmV3IFNpbXBsZVRpbWVab25lKDEwMDAsICJURVNUIiwKKyAgICAgICAgICAgICAgICBDYWxlbmRhci5OT1ZFTUJFUiwgMSwgQ2FsZW5kYXIuU1VOREFZLCAwLCBDYWxlbmRhci5OT1ZFTUJFUiwKKyAgICAgICAgICAgICAgICAtMSwgQ2FsZW5kYXIuU1VOREFZLCAwKTsKKyAgICAgICAgU2ltcGxlVGltZVpvbmUgc3RBID0gbmV3IFNpbXBsZVRpbWVab25lKDEsICJHYWgiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2xvbmUgcmVzdWx0ZWQgaW4gc2FtZSByZWZlcmVuY2UiLCBzdDEuY2xvbmUoKSAhPSBzdDEpOworICAgICAgICBhc3NlcnRUcnVlKCJDbG9uZSByZXN1bHRlZCBpbiB1bmVxdWFsIG9iamVjdCIsICgoU2ltcGxlVGltZVpvbmUpIHN0MQorICAgICAgICAgICAgICAgIC5jbG9uZSgpKS5lcXVhbHMoc3QxKSk7CisgICAgICAgIGFzc2VydFRydWUoIkNsb25lIHJlc3VsdGVkIGluIHNhbWUgcmVmZXJlbmNlIiwgc3RBLmNsb25lKCkgIT0gc3RBKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ2xvbmUgcmVzdWx0ZWQgaW4gdW5lcXVhbCBvYmplY3QiLCAoKFNpbXBsZVRpbWVab25lKSBzdEEKKyAgICAgICAgICAgICAgICAuY2xvbmUoKSkuZXF1YWxzKHN0QSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZSNlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VxdWFsc0xqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbgorICAgICAgICAvLyBqYXZhLnV0aWwuU2ltcGxlVGltZVpvbmUuZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIFRpbWVab25lIHR6ID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkVTVCIpOworICAgICAgICBzdDEgPSBuZXcgU2ltcGxlVGltZVpvbmUodHouZ2V0UmF3T2Zmc2V0KCksICJFU1QiKTsKKyAgICAgICAgc3QyID0gbmV3IFNpbXBsZVRpbWVab25lKDAsICJFU1QiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc3QxLmVxdWFscyhzdDIpKTsKKyAgICAgICAgc3QxLnNldFJhd09mZnNldChzdDIuZ2V0UmF3T2Zmc2V0KCkpOworICAgICAgICBhc3NlcnRUcnVlKHN0MS5lcXVhbHMoc3QyKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlNpbXBsZVRpbWVab25lI2dldERTVFNhdmluZ3MoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RFNUU2F2aW5ncygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuU2ltcGxlVGltZVpvbmUuZ2V0RFNUU2F2aW5ncygpCisgICAgICAgIHN0MSA9IG5ldyBTaW1wbGVUaW1lWm9uZSgwLCAiVEVTVCIpOworCisgICAgICAgIGFzc2VydEVxdWFscygiTm9uLXplcm8gZGVmYXVsdCBkYXlsaWdodCBzYXZpbmdzIiwKKyAgICAgICAgICAgICAgICAwLCBzdDEuZ2V0RFNUU2F2aW5ncygpKTsKKyAgICAgICAgc3QxLnNldFN0YXJ0UnVsZSgwLCAxLCAxLCAxKTsKKyAgICAgICAgc3QxLnNldEVuZFJ1bGUoMTEsIDEsIDEsIDEpOworCisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRlZmF1bHQgZGF5bGlnaHQgc2F2aW5ncyIsCisgICAgICAgICAgICAgICAgMzYwMDAwMCwgc3QxLmdldERTVFNhdmluZ3MoKSk7CisgICAgICAgIHN0MSA9IG5ldyBTaW1wbGVUaW1lWm9uZSgtNSAqIDM2MDAwMDAsICJFU1QiLCBDYWxlbmRhci5BUFJJTCwgMSwKKyAgICAgICAgICAgICAgICAtQ2FsZW5kYXIuU1VOREFZLCAyICogMzYwMDAwMCwgQ2FsZW5kYXIuT0NUT0JFUiwgLTEsCisgICAgICAgICAgICAgICAgQ2FsZW5kYXIuU1VOREFZLCAyICogMzYwMDAwMCwgNzIwMDAwMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRheWxpZ2h0IHNhdmluZ3MgZnJvbSBjb25zdHJ1Y3RvciIsIDcyMDAwMDAsIHN0MQorICAgICAgICAgICAgICAgIC5nZXREU1RTYXZpbmdzKCkpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlNpbXBsZVRpbWVab25lI2dldE9mZnNldChpbnQsIGludCwgaW50LCBpbnQsIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0T2Zmc2V0SUlJSUlJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZS5nZXRPZmZzZXQoaW50LCBpbnQsIGludCwKKyAgICAgICAgLy8gaW50LCBpbnQsIGludCkKKy8vICAgICAgICBUaW1lWm9uZSBzdDEgPSBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiRVNUIik7CisgICAgICAgIHN0MSA9IG5ldyBTaW1wbGVUaW1lWm9uZShUaW1lWm9uZS5nZXRUaW1lWm9uZSgiRVNUIikuZ2V0UmF3T2Zmc2V0KCksICJFU1QiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG9mZnNldCByZXR1cm5lZCIsIHN0MS5nZXRPZmZzZXQoCisgICAgICAgICAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIuQUQsIDE5OTgsIENhbGVuZGFyLk5PVkVNQkVSLCAxMSwKKyAgICAgICAgICAgICAgICBDYWxlbmRhci5XRURORVNEQVksIDApID09IC0oNSAqIDYwICogNjAgKiAxMDAwKSk7CisKKyAgICAgICAgc3QxID0gbmV3IFNpbXBsZVRpbWVab25lKFRpbWVab25lLmdldFRpbWVab25lKCJFU1QiKS5nZXRSYXdPZmZzZXQoKSwgIkVTVCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBvZmZzZXQgcmV0dXJuZWQiLCAtKDUgKiA2MCAqIDYwICogMTAwMCksIHN0MQorICAgICAgICAgICAgICAgIC5nZXRPZmZzZXQoR3JlZ29yaWFuQ2FsZW5kYXIuQUQsIDE5OTgsIENhbGVuZGFyLkpVTkUsIDExLAorICAgICAgICAgICAgICAgICAgICAgICAgQ2FsZW5kYXIuVEhVUlNEQVksIDApKTsKKworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTU0NTkKKyAgICAgICAgc3QxID0gbmV3IFNpbXBsZVRpbWVab25lKFRpbWVab25lLmdldERlZmF1bHQoKS5nZXRSYXdPZmZzZXQoKSwgVGltZVpvbmUuZ2V0RGVmYXVsdCgpLmdldElEKCkpOworICAgICAgICBpbnQgZm91ckhvdXJzID0gNCo2MCo2MCoxMDAwOworICAgICAgICBzdDEuc2V0UmF3T2Zmc2V0KGZvdXJIb3Vycyk7CisgICAgICAgIGFzc2VydEVxdWFscyhmb3VySG91cnMsIHN0MS5nZXRPZmZzZXQoMSwgMjA5OSwgMDEsIDEsIDUsIDApKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QxLmdldE9mZnNldCgtMSwgMjA5OSwgMDEsIDEsIDUsIDApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QxLmdldE9mZnNldCgxLCAyMDk5LCAxNSwgMSwgNSwgMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdDEuZ2V0T2Zmc2V0KDEsIDIwOTksIDAxLCAxMDAsIDUsIDApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QxLmdldE9mZnNldCgxLCAyMDk5LCAwMSwgMSwgNTAsIDApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QxLmdldE9mZnNldCgxLCAyMDk5LCAwMSwgMSwgNSwgLTEwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlNpbXBsZVRpbWVab25lI2dldFJhd09mZnNldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRSYXdPZmZzZXQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLlNpbXBsZVRpbWVab25lLmdldFJhd09mZnNldCgpCisgICAgICAgIHN0MSA9IG5ldyBTaW1wbGVUaW1lWm9uZShUaW1lWm9uZS5nZXRUaW1lWm9uZSgiRVNUIikuZ2V0UmF3T2Zmc2V0KCksICJFU1QiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG9mZnNldCByZXR1cm5lZCIsCisgICAgICAgICAgICAgICAgc3QxLmdldFJhd09mZnNldCgpID09IC0oNSAqIDYwICogNjAgKiAxMDAwKSk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuU2ltcGxlVGltZVpvbmUjaGFzaENvZGUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGFzaENvZGUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLlNpbXBsZVRpbWVab25lLmhhc2hDb2RlKCkKKyAgICAgICAgLy8gRm9yIGxhY2sgb2YgYSBiZXR0ZXIgdGVzdC4KKyAgICAgICAgc3QxID0gbmV3IFNpbXBsZVRpbWVab25lKC01ICogMzYwMDAwMCwgIkVTVCIsIENhbGVuZGFyLkFQUklMLCAxLAorICAgICAgICAgICAgICAgIC1DYWxlbmRhci5TVU5EQVksIDIgKiAzNjAwMDAwLCBDYWxlbmRhci5PQ1RPQkVSLCAtMSwKKyAgICAgICAgICAgICAgICBDYWxlbmRhci5TVU5EQVksIDIgKiAzNjAwMDAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShUaW1lWm9uZS5nZXRUaW1lWm9uZSgiRVNUIikuaGFzaENvZGUoKSAhPSAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzdDEuaGFzaENvZGUoKSAhPSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuU2ltcGxlVGltZVpvbmUjaGFzU2FtZVJ1bGVzKGphdmEudXRpbC5UaW1lWm9uZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc1NhbWVSdWxlc0xqYXZhX3V0aWxfVGltZVpvbmUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuCisgICAgICAgIC8vIGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZS5oYXNTYW1lUnVsZXMoamF2YS51dGlsLlRpbWVab25lKQorICAgICAgICBTaW1wbGVUaW1lWm9uZSBzdCA9IG5ldyBTaW1wbGVUaW1lWm9uZSgxMDAwLCAiVEVTVCIsIENhbGVuZGFyLk5PVkVNQkVSLAorICAgICAgICAgICAgICAgIDEsIENhbGVuZGFyLlNVTkRBWSwgMCwgQ2FsZW5kYXIuTk9WRU1CRVIsIC0xLCBDYWxlbmRhci5TVU5EQVksCisgICAgICAgICAgICAgICAgMCk7CisgICAgICAgIFNpbXBsZVRpbWVab25lIHNhbWVBc1N0ID0gbmV3IFNpbXBsZVRpbWVab25lKDEwMDAsICJSRVNUIiwKKyAgICAgICAgICAgICAgICBDYWxlbmRhci5OT1ZFTUJFUiwgMSwgQ2FsZW5kYXIuU1VOREFZLCAwLCBDYWxlbmRhci5OT1ZFTUJFUiwKKyAgICAgICAgICAgICAgICAtMSwgQ2FsZW5kYXIuU1VOREFZLCAwKTsKKyAgICAgICAgU2ltcGxlVGltZVpvbmUgbm90U2FtZUFzU3QgPSBuZXcgU2ltcGxlVGltZVpvbmUoMTAwMCwgIlBFU1QiLAorICAgICAgICAgICAgICAgIENhbGVuZGFyLk5PVkVNQkVSLCAyLCBDYWxlbmRhci5TVU5EQVksIDAsIENhbGVuZGFyLk5PVkVNQkVSLAorICAgICAgICAgICAgICAgIC0xLCBDYWxlbmRhci5TVU5EQVksIDApOworICAgICAgICBhc3NlcnRUcnVlKCJUaW1lIHpvbmVzIGhhdmUgc2FtZSBydWxlcyBidXQgcmV0dXJuIGZhbHNlIiwgc3QKKyAgICAgICAgICAgICAgICAuaGFzU2FtZVJ1bGVzKHNhbWVBc1N0KSk7CisgICAgICAgIGFzc2VydFRydWUoIlRpbWUgem9uZXMgaGF2ZSBkaWZmZXJlbnQgcnVsZXMgYnV0IHJldHVybiB0cnVlIiwgIXN0CisgICAgICAgICAgICAgICAgLmhhc1NhbWVSdWxlcyhub3RTYW1lQXNTdCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZSNpbkRheWxpZ2h0VGltZShqYXZhLnV0aWwuRGF0ZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luRGF5bGlnaHRUaW1lTGphdmFfdXRpbF9EYXRlKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbgorICAgICAgICAvLyBqYXZhLnV0aWwuU2ltcGxlVGltZVpvbmUuaW5EYXlsaWdodFRpbWUoamF2YS51dGlsLkRhdGUpCisgICAgICAgIFRpbWVab25lIHR6ID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkVTVCIpOworICAgICAgICBTaW1wbGVUaW1lWm9uZSB6b25lID0gbmV3IFNpbXBsZVRpbWVab25lKHR6LmdldFJhd09mZnNldCgpLCAiRVNUIiwKKyAgICAgICAgICAgICAgICBDYWxlbmRhci5BUFJJTCwgMSwgLUNhbGVuZGFyLlNVTkRBWSwgNzIwMDAwMCwgQ2FsZW5kYXIuT0NUT0JFUiwgLTEsIENhbGVuZGFyLlNVTkRBWSwgNzIwMDAwMCwgMzYwMDAwMCk7CisgICAgICAgIEdyZWdvcmlhbkNhbGVuZGFyIGdjID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTgsIENhbGVuZGFyLkpVTkUsIDExKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgZGF5bGlnaHQgdmFsdWUxIiwgem9uZS5pbkRheWxpZ2h0VGltZShnYworICAgICAgICAgICAgICAgIC5nZXRUaW1lKCkpKTsKKyAgICAgICAgZ2MgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OCwgQ2FsZW5kYXIuTk9WRU1CRVIsIDExKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGRheWxpZ2h0IHZhbHVlMiIsICEoem9uZQorICAgICAgICAgICAgICAgIC5pbkRheWxpZ2h0VGltZShnYy5nZXRUaW1lKCkpKSk7CisgICAgICAgIGdjID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKHpvbmUpOworICAgICAgICBnYy5zZXQoMTk5OSwgQ2FsZW5kYXIuQVBSSUwsIDQsIDEsIDU5LCA1OSk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBkYXlsaWdodCB2YWx1ZTMiLCAhKHpvbmUKKyAgICAgICAgICAgICAgICAuaW5EYXlsaWdodFRpbWUoZ2MuZ2V0VGltZSgpKSkpOworICAgICAgICBEYXRlIGRhdGUgPSBuZXcgRGF0ZShnYy5nZXRUaW1lKCkuZ2V0VGltZSgpICsgMTAwMCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBkYXlsaWdodCB2YWx1ZTQiLCB6b25lCisgICAgICAgICAgICAgICAgLmluRGF5bGlnaHRUaW1lKGRhdGUpKTsKKyAgICAgICAgZ2Muc2V0KDE5OTksIENhbGVuZGFyLk9DVE9CRVIsIDMxLCAxLCAwLCAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGRheWxpZ2h0IHZhbHVlNSIsICEoem9uZQorICAgICAgICAgICAgICAgIC5pbkRheWxpZ2h0VGltZShnYy5nZXRUaW1lKCkpKSk7CisgICAgICAgIGRhdGUgPSBuZXcgRGF0ZShnYy5nZXRUaW1lKCkuZ2V0VGltZSgpIC0gMTAwMCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBkYXlsaWdodCB2YWx1ZTYiLCB6b25lCisgICAgICAgICAgICAgICAgLmluRGF5bGlnaHRUaW1lKGRhdGUpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgZGF5bGlnaHQgdmFsdWU3IiwgIXpvbmUKKyAgICAgICAgICAgICAgICAuaW5EYXlsaWdodFRpbWUobmV3IERhdGUoODkxNzUyNDAwMDAwTCArIDcyMDAwMDAgLSAxKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgZGF5bGlnaHQgdmFsdWU4Iiwgem9uZQorICAgICAgICAgICAgICAgIC5pbkRheWxpZ2h0VGltZShuZXcgRGF0ZSg4OTE3NTI0MDAwMDBMICsgNzIwMDAwMCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGRheWxpZ2h0IHZhbHVlOSIsIHpvbmUKKyAgICAgICAgICAgICAgICAuaW5EYXlsaWdodFRpbWUobmV3IERhdGUoOTA5Mjg4MDAwMDAwTCArIDcyMDAwMDAgLSAxKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBpbmNvcnJlY3QgZGF5bGlnaHQgdmFsdWUxMCIsICF6b25lCisgICAgICAgICAgICAgICAgLmluRGF5bGlnaHRUaW1lKG5ldyBEYXRlKDkwOTI4ODAwMDAwMEwgKyA3MjAwMDAwKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZSNzZXREU1RTYXZpbmdzKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldERTVFNhdmluZ3NJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuU2ltcGxlVGltZVpvbmUuc2V0RFNUU2F2aW5ncyhpbnQpCisgICAgICAgIFNpbXBsZVRpbWVab25lIHN0ID0gbmV3IFNpbXBsZVRpbWVab25lKDEwMDAsICJUZXN0X1RaIik7CisgICAgICAgIHN0LnNldFN0YXJ0UnVsZSgwLCAxLCAxLCAxKTsKKyAgICAgICAgc3Quc2V0RW5kUnVsZSgxMSwgMSwgMSwgMSk7CisgICAgICAgIHN0LnNldERTVFNhdmluZ3MoMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRGF5bGlnaHQgc2F2aW5ncyBhbW91bnQgbm90IHNldCIsIDEsIHN0LmdldERTVFNhdmluZ3MoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlNpbXBsZVRpbWVab25lI3NldEVuZFJ1bGUoaW50LCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEVuZFJ1bGVJSUkoKSB7CisgICAgICAgIFNpbXBsZVRpbWVab25lIHN0ID0gbmV3IFNpbXBsZVRpbWVab25lKDEwMDAsICJUZXN0X1RaIik7CisgICAgICAgIHN0LnNldFN0YXJ0UnVsZShDYWxlbmRhci5OT1ZFTUJFUiwgMSwgMCk7CisgICAgICAgIHN0LnNldEVuZFJ1bGUoQ2FsZW5kYXIuTk9WRU1CRVIsIDIwLCAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RhcnRSdWxlIGltcHJvcGVybHkgc2V0MSIsIHN0LnVzZURheWxpZ2h0VGltZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RhcnRSdWxlIGltcHJvcGVybHkgc2V0MiIsIHN0LmluRGF5bGlnaHRUaW1lKAorICAgICAgICAgICAgICAgIG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk4LCBDYWxlbmRhci5OT1ZFTUJFUiwKKyAgICAgICAgICAgICAgICAgICAgICAgIDEzKS5nZXRUaW1lKCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RhcnRSdWxlIGltcHJvcGVybHkgc2V0MyIsICEoc3QKKyAgICAgICAgICAgICAgICAuaW5EYXlsaWdodFRpbWUobmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTgsIENhbGVuZGFyLk9DVE9CRVIsCisgICAgICAgICAgICAgICAgICAgICAgICAxMykuZ2V0VGltZSgpKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5zZXRFbmRSdWxlKDEzLCAyMCwgMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3Quc2V0RW5kUnVsZSgxLCAzMiwgMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3Quc2V0RW5kUnVsZSgxLCAzMCwgMTApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlNpbXBsZVRpbWVab25lI3NldEVuZFJ1bGUoaW50LCBpbnQsIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0RW5kUnVsZUlJSUkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZS5zZXRFbmRSdWxlKGludCwgaW50LAorICAgICAgICAvLyBpbnQsIGludCkKKyAgICAgICAgU2ltcGxlVGltZVpvbmUgc3QgPSBuZXcgU2ltcGxlVGltZVpvbmUoMTAwMCwgIlRlc3RfVFoiKTsKKyAgICAgICAgLy8gU3BlYyBpbmRpY2F0ZXMgdGhhdCBib3RoIGVuZCBhbmQgc3RhcnQgbXVzdCBiZSBzZXQgb3IgcmVzdWx0IGlzCisgICAgICAgIC8vIHVuZGVmaW5lZAorICAgICAgICBzdC5zZXRTdGFydFJ1bGUoQ2FsZW5kYXIuTk9WRU1CRVIsIDEsIENhbGVuZGFyLlNVTkRBWSwgMCk7CisgICAgICAgIHN0LnNldEVuZFJ1bGUoQ2FsZW5kYXIuTk9WRU1CRVIsIC0xLCBDYWxlbmRhci5TVU5EQVksIDApOworICAgICAgICBhc3NlcnRUcnVlKCJTdGFydFJ1bGUgaW1wcm9wZXJseSBzZXQxIiwgc3QudXNlRGF5bGlnaHRUaW1lKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJTdGFydFJ1bGUgaW1wcm9wZXJseSBzZXQyIiwgc3QKKyAgICAgICAgICAgICAgICAuaW5EYXlsaWdodFRpbWUobmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTgsIENhbGVuZGFyLk5PVkVNQkVSLAorICAgICAgICAgICAgICAgICAgICAgICAgMTMpLmdldFRpbWUoKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJTdGFydFJ1bGUgaW1wcm9wZXJseSBzZXQzIiwgIShzdAorICAgICAgICAgICAgICAgIC5pbkRheWxpZ2h0VGltZShuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OCwgQ2FsZW5kYXIuT0NUT0JFUiwKKyAgICAgICAgICAgICAgICAgICAgICAgIDEzKS5nZXRUaW1lKCkpKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LnNldEVuZFJ1bGUoMTIsIC0xLCBDYWxlbmRhci5TVU5EQVksIDApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LnNldEVuZFJ1bGUoQ2FsZW5kYXIuTk9WRU1CRVIsIDEwLCBDYWxlbmRhci5TVU5EQVksIDApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LnNldEVuZFJ1bGUoQ2FsZW5kYXIuTk9WRU1CRVIsIC0xLCA4LCAwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5zZXRFbmRSdWxlKENhbGVuZGFyLk5PVkVNQkVSLCAtMSwgQ2FsZW5kYXIuU1VOREFZLCAtMTApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlNpbXBsZVRpbWVab25lI3NldEVuZFJ1bGUoaW50LCBpbnQsIGludCwgaW50LCBib29sZWFuKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0RW5kUnVsZUlJSUlaKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuU2ltcGxlVGltZVpvbmUuc2V0RW5kUnVsZShpbnQsIGludCwKKyAgICAgICAgLy8gaW50LCBpbnQsIGJvb2xlYW4pCisgICAgICAgIFNpbXBsZVRpbWVab25lIHN0ID0gbmV3IFNpbXBsZVRpbWVab25lKDEwMDAsICJUZXN0X1RaIik7CisgICAgICAgIC8vIFNwZWMgaW5kaWNhdGVzIHRoYXQgYm90aCBlbmQgYW5kIHN0YXJ0IG11c3QgYmUgc2V0IG9yIHJlc3VsdCBpcworICAgICAgICAvLyB1bmRlZmluZWQKKyAgICAgICAgc3Quc2V0U3RhcnRSdWxlKENhbGVuZGFyLk5PVkVNQkVSLCA4LCBDYWxlbmRhci5TVU5EQVksIDEsIGZhbHNlKTsKKyAgICAgICAgc3Quc2V0RW5kUnVsZShDYWxlbmRhci5OT1ZFTUJFUiwgMTUsIENhbGVuZGFyLlNVTkRBWSwgMSwgdHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoIlN0YXJ0UnVsZSBpbXByb3Blcmx5IHNldDEiLCBzdC51c2VEYXlsaWdodFRpbWUoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlN0YXJ0UnVsZSBpbXByb3Blcmx5IHNldDIiLCBzdAorICAgICAgICAgICAgICAgIC5pbkRheWxpZ2h0VGltZSgobmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLk5PVkVNQkVSLAorICAgICAgICAgICAgICAgICAgICAgICAgNywgMTIsIDApLmdldFRpbWUoKSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RhcnRSdWxlIGltcHJvcGVybHkgc2V0MyIsIHN0CisgICAgICAgICAgICAgICAgLmluRGF5bGlnaHRUaW1lKChuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OSwgQ2FsZW5kYXIuTk9WRU1CRVIsCisgICAgICAgICAgICAgICAgICAgICAgICAyMCwgMTIsIDApLmdldFRpbWUoKSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RhcnRSdWxlIGltcHJvcGVybHkgc2V0NCIsICEoc3QKKyAgICAgICAgICAgICAgICAuaW5EYXlsaWdodFRpbWUobmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLk5PVkVNQkVSLAorICAgICAgICAgICAgICAgICAgICAgICAgNiwgMTIsIDApLmdldFRpbWUoKSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RhcnRSdWxlIGltcHJvcGVybHkgc2V0NSIsICEoc3QKKyAgICAgICAgICAgICAgICAuaW5EYXlsaWdodFRpbWUobmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLk5PVkVNQkVSLAorICAgICAgICAgICAgICAgICAgICAgICAgMjEsIDEyLCAwKS5nZXRUaW1lKCkpKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LnNldEVuZFJ1bGUoMjAsIDE1LCBDYWxlbmRhci5TVU5EQVksIDEsIHRydWUpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LnNldEVuZFJ1bGUoQ2FsZW5kYXIuTk9WRU1CRVIsIDM1LCBDYWxlbmRhci5TVU5EQVksIDEsIHRydWUpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LnNldEVuZFJ1bGUoQ2FsZW5kYXIuTk9WRU1CRVIsIDE1LCAxMiwgMSwgdHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3Quc2V0RW5kUnVsZShDYWxlbmRhci5OT1ZFTUJFUiwgMTUsIENhbGVuZGFyLlNVTkRBWSwgLTEsIHRydWUpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlNpbXBsZVRpbWVab25lI3NldFJhd09mZnNldChpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRSYXdPZmZzZXRJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuU2ltcGxlVGltZVpvbmUuc2V0UmF3T2Zmc2V0KGludCkKKworICAgICAgICBzdDEgPSBuZXcgU2ltcGxlVGltZVpvbmUoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkVTVCIpLmdldFJhd09mZnNldCgpLCAiRVNUIik7CisgICAgICAgIGludCBvZmYgPSBzdDEuZ2V0UmF3T2Zmc2V0KCk7CisgICAgICAgIHN0MS5zZXRSYXdPZmZzZXQoMTAwMCk7CisgICAgICAgIGJvb2xlYW4gdmFsID0gc3QxLmdldFJhd09mZnNldCgpID09IDEwMDA7CisgICAgICAgIHN0MS5zZXRSYXdPZmZzZXQob2ZmKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG9mZnNldCBzZXQiLCB2YWwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZSNzZXRTdGFydFJ1bGUoaW50LCBpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFN0YXJ0UnVsZUlJSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLlNpbXBsZVRpbWVab25lLnNldFN0YXJ0UnVsZShpbnQsIGludCwKKyAgICAgICAgLy8gaW50KQorICAgICAgICBTaW1wbGVUaW1lWm9uZSBzdCA9IG5ldyBTaW1wbGVUaW1lWm9uZSgxMDAwLCAiVGVzdF9UWiIpOworICAgICAgICAvLyBTcGVjIGluZGljYXRlcyB0aGF0IGJvdGggZW5kIGFuZCBzdGFydCBtdXN0IGJlIHNldCBvciByZXN1bHQgaXMKKyAgICAgICAgLy8gdW5kZWZpbmVkCisgICAgICAgIHN0LnNldFN0YXJ0UnVsZShDYWxlbmRhci5OT1ZFTUJFUiwgMSwgMSk7CisgICAgICAgIHN0LnNldEVuZFJ1bGUoQ2FsZW5kYXIuREVDRU1CRVIsIDEsIDEpOworICAgICAgICBhc3NlcnRUcnVlKCJTdGFydFJ1bGUgaW1wcm9wZXJseSBzZXQiLCBzdC51c2VEYXlsaWdodFRpbWUoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlN0YXJ0UnVsZSBpbXByb3Blcmx5IHNldCIsIHN0CisgICAgICAgICAgICAgICAgLmluRGF5bGlnaHRUaW1lKChuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OCwgQ2FsZW5kYXIuTk9WRU1CRVIsCisgICAgICAgICAgICAgICAgICAgICAgICAxMykuZ2V0VGltZSgpKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJTdGFydFJ1bGUgaW1wcm9wZXJseSBzZXQiLCAhKHN0CisgICAgICAgICAgICAgICAgLmluRGF5bGlnaHRUaW1lKG5ldyBHcmVnb3JpYW5DYWxlbmRhcigxOTk4LCBDYWxlbmRhci5PQ1RPQkVSLAorICAgICAgICAgICAgICAgICAgICAgICAgMTMpLmdldFRpbWUoKSkpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3Quc2V0U3RhcnRSdWxlKDEzLCAyMCwgMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3Quc2V0U3RhcnRSdWxlKDEsIDMyLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5zZXRTdGFydFJ1bGUoMSwgMzAsIDEwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZSNzZXRTdGFydFJ1bGUoaW50LCBpbnQsIGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0U3RhcnRSdWxlSUlJSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLlNpbXBsZVRpbWVab25lLnNldFN0YXJ0UnVsZShpbnQsIGludCwKKyAgICAgICAgLy8gaW50LCBpbnQpCisgICAgICAgIFNpbXBsZVRpbWVab25lIHN0ID0gbmV3IFNpbXBsZVRpbWVab25lKDEwMDAsICJUZXN0X1RaIik7CisgICAgICAgIC8vIFNwZWMgaW5kaWNhdGVzIHRoYXQgYm90aCBlbmQgYW5kIHN0YXJ0IG11c3QgYmUgc2V0IG9yIHJlc3VsdCBpcworICAgICAgICAvLyB1bmRlZmluZWQKKyAgICAgICAgc3Quc2V0U3RhcnRSdWxlKENhbGVuZGFyLk5PVkVNQkVSLCAxLCBDYWxlbmRhci5TVU5EQVksIDApOworICAgICAgICBzdC5zZXRFbmRSdWxlKENhbGVuZGFyLk5PVkVNQkVSLCAtMSwgQ2FsZW5kYXIuU1VOREFZLCAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RhcnRSdWxlIGltcHJvcGVybHkgc2V0MSIsIHN0LnVzZURheWxpZ2h0VGltZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RhcnRSdWxlIGltcHJvcGVybHkgc2V0MiIsIHN0CisgICAgICAgICAgICAgICAgLmluRGF5bGlnaHRUaW1lKChuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OCwgQ2FsZW5kYXIuTk9WRU1CRVIsCisgICAgICAgICAgICAgICAgICAgICAgICAxMykuZ2V0VGltZSgpKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJTdGFydFJ1bGUgaW1wcm9wZXJseSBzZXQzIiwgIShzdAorICAgICAgICAgICAgICAgIC5pbkRheWxpZ2h0VGltZShuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OCwgQ2FsZW5kYXIuT0NUT0JFUiwKKyAgICAgICAgICAgICAgICAgICAgICAgIDEzKS5nZXRUaW1lKCkpKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LnNldFN0YXJ0UnVsZSgxMiwgLTEsIENhbGVuZGFyLlNVTkRBWSwgMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3Quc2V0U3RhcnRSdWxlKENhbGVuZGFyLk5PVkVNQkVSLCAxMCwgQ2FsZW5kYXIuU1VOREFZLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5zZXRTdGFydFJ1bGUoQ2FsZW5kYXIuTk9WRU1CRVIsIC0xLCA4LCAwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5zZXRTdGFydFJ1bGUoQ2FsZW5kYXIuTk9WRU1CRVIsIC0xLCBDYWxlbmRhci5TVU5EQVksIC0xMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuU2ltcGxlVGltZVpvbmUjc2V0U3RhcnRSdWxlKGludCwgaW50LCBpbnQsIGludCwgYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFN0YXJ0UnVsZUlJSUlaKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuU2ltcGxlVGltZVpvbmUuc2V0U3RhcnRSdWxlKGludCwgaW50LAorICAgICAgICAvLyBpbnQsIGludCwgYm9vbGVhbikKKyAgICAgICAgU2ltcGxlVGltZVpvbmUgc3QgPSBuZXcgU2ltcGxlVGltZVpvbmUoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkVTVCIpLmdldFJhd09mZnNldCgpLCAiRVNUIik7CisgICAgICAgIC8vIFNwZWMgaW5kaWNhdGVzIHRoYXQgYm90aCBlbmQgYW5kIHN0YXJ0IG11c3QgYmUgc2V0IG9yIHJlc3VsdCBpcworICAgICAgICAvLyB1bmRlZmluZWQKKyAgICAgICAgc3Quc2V0U3RhcnRSdWxlKENhbGVuZGFyLk5PVkVNQkVSLCAxLCBDYWxlbmRhci5TVU5EQVksIDEsIHRydWUpOworICAgICAgICBzdC5zZXRFbmRSdWxlKENhbGVuZGFyLk5PVkVNQkVSLCAxNSwgQ2FsZW5kYXIuU1VOREFZLCAxLCBmYWxzZSk7CisgICAgICAgIGFzc2VydFRydWUoIlN0YXJ0UnVsZSBpbXByb3Blcmx5IHNldDEiLCBzdC51c2VEYXlsaWdodFRpbWUoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlN0YXJ0UnVsZSBpbXByb3Blcmx5IHNldDIiLCBzdAorICAgICAgICAgICAgICAgIC5pbkRheWxpZ2h0VGltZSgobmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLk5PVkVNQkVSLAorICAgICAgICAgICAgICAgICAgICAgICAgNywgMTIsIDApLmdldFRpbWUoKSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RhcnRSdWxlIGltcHJvcGVybHkgc2V0MyIsIHN0CisgICAgICAgICAgICAgICAgLmluRGF5bGlnaHRUaW1lKChuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OSwgQ2FsZW5kYXIuTk9WRU1CRVIsCisgICAgICAgICAgICAgICAgICAgICAgICAxMywgMTIsIDApLmdldFRpbWUoKSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RhcnRSdWxlIGltcHJvcGVybHkgc2V0NCIsICEoc3QKKyAgICAgICAgICAgICAgICAuaW5EYXlsaWdodFRpbWUobmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLk5PVkVNQkVSLAorICAgICAgICAgICAgICAgICAgICAgICAgNiwgMTIsIDApLmdldFRpbWUoKSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RhcnRSdWxlIGltcHJvcGVybHkgc2V0NSIsICEoc3QKKyAgICAgICAgICAgICAgICAuaW5EYXlsaWdodFRpbWUobmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLk5PVkVNQkVSLAorICAgICAgICAgICAgICAgICAgICAgICAgMTQsIDEyLCAwKS5nZXRUaW1lKCkpKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0LnNldFN0YXJ0UnVsZSgyMCwgMTUsIENhbGVuZGFyLlNVTkRBWSwgMSwgdHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3Quc2V0U3RhcnRSdWxlKENhbGVuZGFyLk5PVkVNQkVSLCAzNSwgQ2FsZW5kYXIuU1VOREFZLCAxLCB0cnVlKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5zZXRTdGFydFJ1bGUoQ2FsZW5kYXIuTk9WRU1CRVIsIDE1LCAxMiwgMSwgdHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3Quc2V0U3RhcnRSdWxlKENhbGVuZGFyLk5PVkVNQkVSLCAxNSwgQ2FsZW5kYXIuU1VOREFZLCAtMSwgdHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuU2ltcGxlVGltZVpvbmUjc2V0U3RhcnRZZWFyKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFN0YXJ0WWVhckkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZS5zZXRTdGFydFllYXIoaW50KQorICAgICAgICBTaW1wbGVUaW1lWm9uZSBzdCA9IG5ldyBTaW1wbGVUaW1lWm9uZSgxMDAwLCAiVGVzdF9UWiIpOworICAgICAgICBzdC5zZXRTdGFydFJ1bGUoQ2FsZW5kYXIuTk9WRU1CRVIsIDEsIENhbGVuZGFyLlNVTkRBWSwgMCk7CisgICAgICAgIHN0LnNldEVuZFJ1bGUoQ2FsZW5kYXIuTk9WRU1CRVIsIC0xLCBDYWxlbmRhci5TVU5EQVksIDApOworICAgICAgICBzdC5zZXRTdGFydFllYXIoMTk5OSk7CisgICAgICAgIGFzc2VydFRydWUoInNldCB5ZWFyIGltcHJvcGVybHkgc2V0MSIsICEoc3QKKyAgICAgICAgICAgICAgICAuaW5EYXlsaWdodFRpbWUobmV3IEdyZWdvcmlhbkNhbGVuZGFyKDE5OTksIENhbGVuZGFyLkpVTFksIDEyKQorICAgICAgICAgICAgICAgICAgICAgICAgLmdldFRpbWUoKSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgic2V0IHllYXIgaW1wcm9wZXJseSBzZXQyIiwgIShzdAorICAgICAgICAgICAgICAgIC5pbkRheWxpZ2h0VGltZShuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OCwgQ2FsZW5kYXIuT0NUT0JFUiwKKyAgICAgICAgICAgICAgICAgICAgICAgIDEzKS5nZXRUaW1lKCkpKSk7CisgICAgICAgIGFzc2VydFRydWUoInNldCB5ZWFyIGltcHJvcGVybHkgc2V0MyIsIChzdAorICAgICAgICAgICAgICAgIC5pbkRheWxpZ2h0VGltZShuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMTk5OSwgQ2FsZW5kYXIuTk9WRU1CRVIsCisgICAgICAgICAgICAgICAgICAgICAgICAxMykuZ2V0VGltZSgpKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZSN0b1N0cmluZygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF90b1N0cmluZygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcgamF2YS51dGlsLlNpbXBsZVRpbWVab25lLnRvU3RyaW5nKCkKKyAgICAgICAgU3RyaW5nIHN0cmluZyA9IFRpbWVab25lLmdldFRpbWVab25lKCJFU1QiKS50b1N0cmluZygpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJ0b1N0cmluZygpIHJldHVybmVkIG51bGwiLCBzdHJpbmcpOworICAgICAgICBhc3NlcnRUcnVlKCJ0b1N0cmluZygpIGlzIGVtcHR5Iiwgc3RyaW5nLmxlbmd0aCgpICE9IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5TaW1wbGVUaW1lWm9uZSN1c2VEYXlsaWdodFRpbWUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdXNlRGF5bGlnaHRUaW1lKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuU2ltcGxlVGltZVpvbmUudXNlRGF5bGlnaHRUaW1lKCkKKyAgICAgICAgU2ltcGxlVGltZVpvbmUgc3QgPSBuZXcgU2ltcGxlVGltZVpvbmUoMTAwMCwgIlRlc3RfVFoiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidXNlRGF5bGlnaHRUaW1lIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsICFzdAorICAgICAgICAgICAgICAgIC51c2VEYXlsaWdodFRpbWUoKSk7CisgICAgICAgIC8vIFNwZWMgaW5kaWNhdGVzIHRoYXQgYm90aCBlbmQgYW5kIHN0YXJ0IG11c3QgYmUgc2V0IG9yIHJlc3VsdCBpcworICAgICAgICAvLyB1bmRlZmluZWQKKyAgICAgICAgc3Quc2V0U3RhcnRSdWxlKENhbGVuZGFyLk5PVkVNQkVSLCAxLCBDYWxlbmRhci5TVU5EQVksIDApOworICAgICAgICBzdC5zZXRFbmRSdWxlKENhbGVuZGFyLk5PVkVNQkVSLCAtMSwgQ2FsZW5kYXIuU1VOREFZLCAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidXNlRGF5bGlnaHRUaW1lIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsIHN0CisgICAgICAgICAgICAgICAgLnVzZURheWxpZ2h0VGltZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE9mZnNldEooKSB7CisgICAgICAgIENhbGVuZGFyIGNhbCA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7CisgICAgICAgIGNhbC5zZXQoMTk5OCwgQ2FsZW5kYXIuTk9WRU1CRVIsIDExLCAwLCAwKTsKKyAgICAgICAgc3QxID0gbmV3IFNpbXBsZVRpbWVab25lKFRpbWVab25lLmdldFRpbWVab25lKCJFU1QiKS5nZXRSYXdPZmZzZXQoKSwgIkVTVCIpOworCisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBvZmZzZXQgcmV0dXJuZWQiLCBzdDEuZ2V0T2Zmc2V0KGNhbC5nZXRUaW1lSW5NaWxsaXMoKSkgPT0KKyAgICAgICAgICAgIC0oNSAqIDYwICogNjAgKiAxMDAwKSk7CisKKyAgICAgICAgc3QxID0gbmV3IFNpbXBsZVRpbWVab25lKFRpbWVab25lLmdldFRpbWVab25lKCJFU1QiKS5nZXRSYXdPZmZzZXQoKSwgIkVTVCIpOworICAgICAgICBjYWwuc2V0KDE5OTgsIENhbGVuZGFyLkpVTkUsIDExLCAwLCAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3Qgb2Zmc2V0IHJldHVybmVkIiwgLSg1ICogNjAgKiA2MCAqIDEwMDApLCBzdDEKKyAgICAgICAgICAgICAgICAuZ2V0T2Zmc2V0KGNhbC5nZXRUaW1lSW5NaWxsaXMoKSkpOworCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktNTQ1OQorICAgICAgICBzdDEgPSBuZXcgU2ltcGxlVGltZVpvbmUoVGltZVpvbmUuZ2V0RGVmYXVsdCgpLmdldFJhd09mZnNldCgpLCBUaW1lWm9uZS5nZXREZWZhdWx0KCkuZ2V0SUQoKSk7CisgICAgICAgIGludCBmb3VySG91cnMgPSA0KjYwKjYwKjEwMDA7CisgICAgICAgIHN0MS5zZXRSYXdPZmZzZXQoZm91ckhvdXJzKTsKKyAgICAgICAgY2FsLnNldCgyMDk5LCAwMSwgMSwgMCwgMCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZvdXJIb3Vycywgc3QxLmdldE9mZnNldChjYWwuZ2V0VGltZUluTWlsbGlzKCkpKTsKKworICAgIH0KKworCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVhcnMgZG93biB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIGNsb3NlIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzCisgICAgICogbWV0aG9kIGlzIGNhbGxlZCBhZnRlciBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvU3RhY2tUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9TdGFja1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NjVkZjEzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvU3RhY2tUZXN0LmphdmEKQEAgLTAsMCArMSwxODggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5FbXB0eVN0YWNrRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5TdGFjazsKKworcHVibGljIGNsYXNzIFN0YWNrVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBTdGFjayBzOworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlN0YWNrI1N0YWNrKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlN0YWNrKCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTdGFjayBjcmVhdGlvbiBmYWlsZWQiLCAwLCBzLnNpemUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlN0YWNrI2VtcHR5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VtcHR5KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuU3RhY2suZW1wdHkoKQorICAgICAgICBhc3NlcnRUcnVlKCJOZXcgc3RhY2sgYW5zd2VycyBub24tZW1wdHkiLCBzLmVtcHR5KCkpOworICAgICAgICBzLnB1c2goImJsYWgiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU3RhY2sgc2hvdWxkIG5vdCBiZSBlbXB0eSBidXQgYW5zd2VycyBlbXB0eSIsICFzLmVtcHR5KCkpOworICAgICAgICBzLnBvcCgpOworICAgICAgICBhc3NlcnRUcnVlKCJTdGFjayBzaG91bGQgYmUgZW1wdHkgYnV0IGFuc3dlcnMgbm9uLWVtcHR5Iiwgcy5lbXB0eSgpKTsKKyAgICAgICAgcy5wdXNoKG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJTdGFjayB3aXRoIG51bGwgc2hvdWxkIG5vdCBiZSBlbXB0eSBidXQgYW5zd2VycyBlbXB0eSIsICFzCisgICAgICAgICAgICAgICAgLmVtcHR5KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5TdGFjayNwZWVrKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BlZWsoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IGphdmEudXRpbC5TdGFjay5wZWVrKCkKKyAgICAgICAgU3RyaW5nIGl0ZW0xID0gIkljaGkiOworICAgICAgICBTdHJpbmcgaXRlbTIgPSAiTmkiOworICAgICAgICBTdHJpbmcgaXRlbTMgPSAiU2FuIjsKKyAgICAgICAgcy5wdXNoKGl0ZW0xKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUGVlayBkaWQgbm90IHJldHVybiB0b3AgaXRlbSB3aGVuIGl0IHdhcyB0aGUgb25seSBpdGVtIiwgcworICAgICAgICAgICAgICAgIC5wZWVrKCkgPT0gaXRlbTEpOworICAgICAgICBzLnB1c2goaXRlbTIpOworICAgICAgICBzLnB1c2goaXRlbTMpOworICAgICAgICBhc3NlcnRUcnVlKCJQZWVrIGRpZCBub3QgcmV0dXJuIHRvcCBpdGVtIGFtb3VuZyBtYW55IG90aGVyIGl0ZW1zIiwgcworICAgICAgICAgICAgICAgIC5wZWVrKCkgPT0gaXRlbTMpOworICAgICAgICBzLnBvcCgpOworICAgICAgICBhc3NlcnRUcnVlKCJQZWVrIGRpZCBub3QgcmV0dXJuIHRvcCBpdGVtIGFmdGVyIGEgcG9wIiwgcy5wb3AoKSA9PSBpdGVtMik7CisgICAgICAgIHMucHVzaChudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiUGVlayBkaWQgbm90IHJldHVybiB0b3AgaXRlbSAod2FudGVkOiBudWxsKSIsCisgICAgICAgICAgICAgICAgcy5wZWVrKCkpOworICAgICAgICBzLnBvcCgpOworICAgICAgICBzLnBvcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5wb3AoKTsKKyAgICAgICAgICAgIGZhaWwoIkVtcHR5U3RhY2tFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoRW1wdHlTdGFja0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuU3RhY2sjcG9wKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BvcCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QgamF2YS51dGlsLlN0YWNrLnBvcCgpCisgICAgICAgIFN0cmluZyBpdGVtMSA9ICJJY2hpIjsKKyAgICAgICAgU3RyaW5nIGl0ZW0yID0gIk5pIjsKKyAgICAgICAgT2JqZWN0IGxhc3RQb3BwZWQ7CisgICAgICAgIHMucHVzaChpdGVtMSk7CisgICAgICAgIHMucHVzaChpdGVtMik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxhc3RQb3BwZWQgPSBzLnBvcCgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiYSkgUG9wIGRpZCBub3QgcmV0dXJuIHRvcCBpdGVtIiwgbGFzdFBvcHBlZCA9PSBpdGVtMik7CisgICAgICAgIH0gY2F0Y2ggKEVtcHR5U3RhY2tFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgKKyAgICAgICAgICAgICAgICAgICAgImEpIFBvcCB0aHJldyBFbXB0eVN0YWNrRXhjZXB0aW9uIHdoZW4gc3RhY2sgc2hvdWxkIG5vdCBoYXZlIGJlZW4gZW1wdHkiKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsYXN0UG9wcGVkID0gcy5wb3AoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImIpIFBvcCBkaWQgbm90IHJldHVybiB0b3AgaXRlbSIsIGxhc3RQb3BwZWQgPT0gaXRlbTEpOworICAgICAgICB9IGNhdGNoIChFbXB0eVN0YWNrRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoCisgICAgICAgICAgICAgICAgICAgICJiKSBQb3AgdGhyZXcgRW1wdHlTdGFja0V4Y2VwdGlvbiB3aGVuIHN0YWNrIHNob3VsZCBub3QgaGF2ZSBiZWVuIGVtcHR5Iik7CisgICAgICAgIH0KKworICAgICAgICBzLnB1c2gobnVsbCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsYXN0UG9wcGVkID0gcy5wb3AoKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImMpIFBvcCBkaWQgbm90IHJldHVybiB0b3AgaXRlbSIsIGxhc3RQb3BwZWQpOworICAgICAgICB9IGNhdGNoIChFbXB0eVN0YWNrRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoCisgICAgICAgICAgICAgICAgICAgICJjKSBQb3AgdGhyZXcgRW1wdHlTdGFja0V4Y2VwdGlvbiB3aGVuIHN0YWNrIHNob3VsZCBub3QgaGF2ZSBiZWVuIGVtcHR5Iik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbGFzdFBvcHBlZCA9IHMucG9wKCk7CisgICAgICAgICAgICBmYWlsKAorICAgICAgICAgICAgICAgICAgICAiZCkgUG9wIGRpZCBub3QgdGhyb3cgRW1wdHlTdGFja0V4Y2VwdGlvbiB3aGVuIHN0YWNrIHNob3VsZCBoYXZlIGJlZW4gZW1wdHkiKTsKKyAgICAgICAgfSBjYXRjaCAoRW1wdHlTdGFja0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5TdGFjayNwdXNoKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wdXNoTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIE9iamVjdCBbXSBhcnJheSA9IHtuZXcgSW50ZWdlcigwKSwgbmV3IE9iamVjdCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEZsb2F0KDApLCBuZXcgU3RyaW5nKCl9OworCisgICAgICAgIFN0YWNrPE9iamVjdD4gc3RhY2sgPSBuZXcgU3RhY2s8T2JqZWN0PigpOworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHN0YWNrLnB1c2goYXJyYXlbaV0pOworICAgICAgICB9CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFycmF5Lmxlbmd0aCAtIGksIHN0YWNrLnNlYXJjaChhcnJheVtpXSkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlN0YWNrI3NlYXJjaChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2VhcmNoTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLlN0YWNrLnNlYXJjaChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBTdHJpbmcgaXRlbTEgPSAiSWNoaSI7CisgICAgICAgIFN0cmluZyBpdGVtMiA9ICJOaSI7CisgICAgICAgIFN0cmluZyBpdGVtMyA9ICJTYW4iOworICAgICAgICBzLnB1c2goaXRlbTEpOworICAgICAgICBzLnB1c2goaXRlbTIpOworICAgICAgICBzLnB1c2goaXRlbTMpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNlYXJjaCByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUgZm9yIGVxdWl2YWxlbnQgb2JqZWN0IiwgMywgcworICAgICAgICAgICAgICAgIC5zZWFyY2goaXRlbTEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTZWFyY2ggcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIGZvciBlcXVhbCBvYmplY3QiLCAzLCBzCisgICAgICAgICAgICAgICAgLnNlYXJjaCgiSWNoaSIpKTsKKyAgICAgICAgcy5wb3AoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTZWFyY2ggcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIGZvciBlcXVpdmFsZW50IG9iamVjdCBhdCB0b3Agb2Ygc3RhY2siLAorICAgICAgICAgICAgICAgIDEsIHMuc2VhcmNoKGl0ZW0yKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2VhcmNoIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSBmb3IgZXF1YWwgb2JqZWN0IGF0IHRvcCBvZiBzdGFjayIsCisgICAgICAgICAgICAgICAgMSwgcy5zZWFyY2goIk5pIikpOworICAgICAgICBzLnB1c2gobnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2VhcmNoIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSBmb3Igc2VhcmNoIGZvciBudWxsIGF0IHRvcCBvZiBzdGFjayIsCisgICAgICAgICAgICAgICAgMSwgcy5zZWFyY2gobnVsbCkpOworICAgICAgICBzLnB1c2goIlNoaSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNlYXJjaCByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUgZm9yIHNlYXJjaCBmb3IgbnVsbCIsIDIsIHMKKyAgICAgICAgICAgICAgICAuc2VhcmNoKG51bGwpKTsKKyAgICAgICAgcy5wb3AoKTsKKyAgICAgICAgcy5wb3AoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTZWFyY2ggcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIGZvciBzZWFyY2ggZm9yIG51bGwtLXdhbnRlZCAtMSIsCisgICAgICAgICAgICAgICAgLTEsIHMuc2VhcmNoKG51bGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgcyA9IG5ldyBTdGFjaygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUsIGZvciBleGFtcGxlLCBjbG9zZSBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgYSB0ZXN0IGlzIGV4ZWN1dGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL1N0cmluZ1Rva2VuaXplclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL1N0cmluZ1Rva2VuaXplclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MDllZDk5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvU3RyaW5nVG9rZW5pemVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjI1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLnV0aWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOworCitwdWJsaWMgY2xhc3MgU3RyaW5nVG9rZW5pemVyVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyI1N0cmluZ1Rva2VuaXplcihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXIoamF2YS5sYW5nLlN0cmluZykKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTdHJpbmdUb2tlbml6ZXIobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXIjU3RyaW5nVG9rZW5pemVyKGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgICAgIGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyKGphdmEubGFuZy5TdHJpbmcsCisgICAgICAgIC8vIGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoIlRoaXM6aXM6YTp0ZXN0OlN0cmluZyIsICI6Iik7CisgICAgICAgIGFzc2VydFRydWUoIkNyZWF0ZWQgaW5jb3JyZWN0IHRva2VuaXplciIsIHN0LmNvdW50VG9rZW5zKCkgPT0gNQorICAgICAgICAgICAgICAgICYmIChzdC5uZXh0RWxlbWVudCgpLmVxdWFscygiVGhpcyIpKSk7CisgICAgICAgIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcigiVGhpczppczphOnRlc3Q6U3RyaW5nIiwgbnVsbCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTdHJpbmdUb2tlbml6ZXIobnVsbCwgIjoiKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXIjU3RyaW5nVG9rZW5pemVyKGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGJvb2xlYW4pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdaKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcihqYXZhLmxhbmcuU3RyaW5nLAorICAgICAgICAvLyBqYXZhLmxhbmcuU3RyaW5nLCBib29sZWFuKQorICAgICAgICBTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKCJUaGlzOmlzOmE6dGVzdDpTdHJpbmciLCAiOiIsCisgICAgICAgICAgICAgICAgdHJ1ZSk7CisgICAgICAgIHN0Lm5leHRFbGVtZW50KCk7CisgICAgICAgIGFzc2VydFRydWUoIkNyZWF0ZWQgaW5jb3JyZWN0IHRva2VuaXplciIsIHN0LmNvdW50VG9rZW5zKCkgPT0gOAorICAgICAgICAgICAgICAgICYmIChzdC5uZXh0RWxlbWVudCgpLmVxdWFscygiOiIpKSk7CisgICAgICAgIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcigiVGhpczppczphOnRlc3Q6U3RyaW5nIiwgbnVsbCwgdHJ1ZSk7CisgICAgICAgIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcigiVGhpczppczphOnRlc3Q6U3RyaW5nIiwgbnVsbCwgZmFsc2UpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU3RyaW5nVG9rZW5pemVyKG51bGwsICI6IiwgdHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyI2NvdW50VG9rZW5zKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvdW50VG9rZW5zKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXIuY291bnRUb2tlbnMoKQorICAgICAgICBTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKCJUaGlzIGlzIGEgdGVzdCBTdHJpbmciKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB0b2tlbiBjb3VudCByZXR1cm5lZCIsIDUsIHN0LmNvdW50VG9rZW5zKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXIjaGFzTW9yZUVsZW1lbnRzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc01vcmVFbGVtZW50cygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4gamF2YS51dGlsLlN0cmluZ1Rva2VuaXplci5oYXNNb3JlRWxlbWVudHMoKQorCisgICAgICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoIlRoaXMgaXMgYSB0ZXN0IFN0cmluZyIpOworICAgICAgICBzdC5uZXh0RWxlbWVudCgpOworICAgICAgICBhc3NlcnRUcnVlKCJoYXNNb3JlRWxlbWVudHMgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgc3QKKyAgICAgICAgICAgICAgICAuaGFzTW9yZUVsZW1lbnRzKCkpOworICAgICAgICBzdC5uZXh0RWxlbWVudCgpOworICAgICAgICBzdC5uZXh0RWxlbWVudCgpOworICAgICAgICBzdC5uZXh0RWxlbWVudCgpOworICAgICAgICBzdC5uZXh0RWxlbWVudCgpOworICAgICAgICBhc3NlcnRUcnVlKCJoYXNNb3JlRWxlbWVudHMgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgIXN0CisgICAgICAgICAgICAgICAgLmhhc01vcmVFbGVtZW50cygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyI2hhc01vcmVUb2tlbnMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaGFzTW9yZVRva2VucygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4gamF2YS51dGlsLlN0cmluZ1Rva2VuaXplci5oYXNNb3JlVG9rZW5zKCkKKyAgICAgICAgU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcigiVGhpcyBpcyBhIHRlc3QgU3RyaW5nIik7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgNTsgY291bnRlcisrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiU3RyaW5nVG9rZW5pemVyIGluY29ycmVjdGx5IHJlcG9ydHMgaXQgaGFzIG5vIG1vcmUgdG9rZW5zIiwKKyAgICAgICAgICAgICAgICAgICAgc3QuaGFzTW9yZVRva2VucygpKTsKKyAgICAgICAgICAgIHN0Lm5leHRUb2tlbigpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlN0cmluZ1Rva2VuaXplciBpbmNvcnJlY3RseSByZXBvcnRzIGl0IGhhcyBtb3JlIHRva2VucyIsCisgICAgICAgICAgICAgICAgIXN0Lmhhc01vcmVUb2tlbnMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlN0cmluZ1Rva2VuaXplciNuZXh0RWxlbWVudCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9uZXh0RWxlbWVudCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QKKyAgICAgICAgLy8gamF2YS51dGlsLlN0cmluZ1Rva2VuaXplci5uZXh0RWxlbWVudCgpCisgICAgICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoIlRoaXMgaXMgYSB0ZXN0IFN0cmluZyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5leHRFbGVtZW50IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsICJUaGlzIiwgKChTdHJpbmcpIHN0CisgICAgICAgICAgICAgICAgLm5leHRFbGVtZW50KCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuZXh0RWxlbWVudCByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAiaXMiLCAoKFN0cmluZykgc3QKKyAgICAgICAgICAgICAgICAubmV4dEVsZW1lbnQoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5leHRFbGVtZW50IHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsICJhIiwgKChTdHJpbmcpIHN0CisgICAgICAgICAgICAgICAgLm5leHRFbGVtZW50KCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuZXh0RWxlbWVudCByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLCAidGVzdCIsICgoU3RyaW5nKSBzdAorICAgICAgICAgICAgICAgIC5uZXh0RWxlbWVudCgpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibmV4dEVsZW1lbnQgcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwgIlN0cmluZyIsICgoU3RyaW5nKSBzdAorICAgICAgICAgICAgICAgIC5uZXh0RWxlbWVudCgpKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgZmFpbCgKKyAgICAgICAgICAgICAgICAgICAgIm5leHRFbGVtZW50IGZhaWxlZCB0byB0aHJvdyBhIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gd2hlbiBpdCBzaG91bGQgaGF2ZSBiZWVuIG91dCBvZiBlbGVtZW50cyIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXIjbmV4dFRva2VuKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X25leHRUb2tlbigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcKKyAgICAgICAgLy8gamF2YS51dGlsLlN0cmluZ1Rva2VuaXplci5uZXh0VG9rZW4oKQorICAgICAgICBTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKCJUaGlzIGlzIGEgdGVzdCBTdHJpbmciKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuZXh0VG9rZW4gcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwKKyAgICAgICAgICAgICAgICAiVGhpcyIsIHN0Lm5leHRUb2tlbigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuZXh0VG9rZW4gcmV0dXJuZWQgaW5jb3JyZWN0IHZhbHVlIiwKKyAgICAgICAgICAgICAgICAiaXMiLCBzdC5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibmV4dFRva2VuIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgImEiLCBzdC5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibmV4dFRva2VuIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgInRlc3QiLCBzdC5uZXh0VG9rZW4oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibmV4dFRva2VuIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSIsCisgICAgICAgICAgICAgICAgIlN0cmluZyIsIHN0Lm5leHRUb2tlbigpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0Lm5leHRUb2tlbigpOworICAgICAgICAgICAgZmFpbCgKKyAgICAgICAgICAgICAgICAgICAgIm5leHRUb2tlbiBmYWlsZWQgdG8gdGhyb3cgYSBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIHdoZW4gaXQgc2hvdWxkIGhhdmUgYmVlbiBvdXQgb2YgZWxlbWVudHMiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyI25leHRUb2tlbihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfbmV4dFRva2VuTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuU3RyaW5nCisgICAgICAgIC8vIGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXIubmV4dFRva2VuKGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoIlRoaXMgaXMgYSB0ZXN0IFN0cmluZyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5leHRUb2tlbihTdHJpbmcpIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSB3aXRoIG5vcm1hbCB0b2tlbiBTdHJpbmciLAorICAgICAgICAgICAgICAgICJUaGlzIiwgc3QubmV4dFRva2VuKCIgIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5leHRUb2tlbihTdHJpbmcpIHJldHVybmVkIGluY29ycmVjdCB2YWx1ZSB3aXRoIGN1c3RvbSB0b2tlbiBTdHJpbmciLAorICAgICAgICAgICAgICAgICIgaXMgYSAiLCBzdC5uZXh0VG9rZW4oInRyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImNhbGxpbmcgbmV4dFRva2VuKCkgZGlkIG5vdCB1c2UgdGhlIG5ldyBkZWZhdWx0IGRlbGltaXRlciBsaXN0IiwKKyAgICAgICAgICAgICAgICAiZXMiLCBzdC5uZXh0VG9rZW4oKSk7CisgICAgICAgIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcigiVGhpczppczphOnRlc3Q6U3RyaW5nIiwgIiAiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzdC5uZXh0VG9rZW4oIjoiKS5lcXVhbHMoIlRoaXMiKSk7CisgICAgICAgIGFzc2VydFRydWUoc3QubmV4dFRva2VuKCI6IikuZXF1YWxzKCJpcyIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzdC5uZXh0VG9rZW4oIjoiKS5lcXVhbHMoImEiKSk7CisgICAgICAgIGFzc2VydFRydWUoc3QubmV4dFRva2VuKCI6IikuZXF1YWxzKCJ0ZXN0IikpOworICAgICAgICBhc3NlcnRUcnVlKHN0Lm5leHRUb2tlbigiOiIpLmVxdWFscygiU3RyaW5nIikpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdC5uZXh0VG9rZW4oIjoiKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3QubmV4dFRva2VuKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVhcnMgZG93biB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIGNsb3NlIGEgbmV0d29yayBjb25uZWN0aW9uLiBUaGlzCisgICAgICogbWV0aG9kIGlzIGNhbGxlZCBhZnRlciBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvVGltZXJUYXNrVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvVGltZXJUYXNrVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk3ZmY4ZWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9UaW1lclRhc2tUZXN0LmphdmEKQEAgLTAsMCArMSwyNDggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5UaW1lcjsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZXJUYXNrOworCitwdWJsaWMgY2xhc3MgVGltZXJUYXNrVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisgICAgLyoqCisgICAgICogV2FybmluZzogVGhlc2UgdGVzdHMgaGF2ZSB0aGUgcG9zc2liaWxpdHkgdG8gbGVhdmUgYSBWTSBoYW5naW5nIGlmIHRoZQorICAgICAqIFRpbWVyIGlzIG5vdCBjYW5jZWxsZWQuCisgICAgICovCisgICAgY2xhc3MgVGltZXJUZXN0VGFzayBleHRlbmRzIFRpbWVyVGFzayB7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3Qgc3luYyA9IG5ldyBPYmplY3QoKTsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3Qgc3RhcnQgPSBuZXcgT2JqZWN0KCk7CisKKyAgICAgICAgcHJpdmF0ZSBpbnQgd2FzUnVuID0gMDsKKworICAgICAgICAvLyBTZXQgdGhpcyB0byB0cnVlIHRvIHNlZSBub3JtYWwgdGVzdHMgZmFpbCAob3IgaGFuZyBwb3NzaWJseSkKKyAgICAgICAgLy8gVGhlIGRlZmF1bHQgaXMgZmFsc2UgYW5kIG5lZWRzIHRvIGJlIHNldCBieSBzb21lIHRlc3RzCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBzbGVlcEluUnVuID0gZmFsc2U7CisKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICAgICAgd2FzUnVuKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHN0YXJ0KSB7CisgICAgICAgICAgICAgICAgc3RhcnQubm90aWZ5KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc2xlZXBJblJ1bikgeworCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDIwMCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoc3luYykgeworICAgICAgICAgICAgICAgIHN5bmMubm90aWZ5KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCB3YXNSdW4oKSB7CisgICAgICAgICAgICByZXR1cm4gd2FzUnVuOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2xlZXBJblJ1bihib29sZWFuIHZhbHVlKSB7CisgICAgICAgICAgICBzbGVlcEluUnVuID0gdmFsdWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVGltZXJUYXNrI1RpbWVyVGFzaygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgLy8gRW5zdXJlIHRoZSBjb25zdHJ1Y3RvciBkb2VzIG5vdCBmYWlsCisgICAgICAgIG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlRpbWVyVGFzayNjYW5jZWwoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2FuY2VsKCkgeworICAgICAgICBUaW1lciB0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIEVuc3VyZSBjYW5jZWwgcmV0dXJucyBmYWxzZSBpZiBuZXZlciBzY2hlZHVsZWQKKyAgICAgICAgICAgIFRpbWVyVGVzdFRhc2sgdGVzdFRhc2sgPSBuZXcgVGltZXJUZXN0VGFzaygpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVW5zaGVkdWxlZCB0YXNrcyBzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBjYW5jZWwoKSIsCisgICAgICAgICAgICAgICAgICAgICF0ZXN0VGFzay5jYW5jZWwoKSk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBjYW5jZWxsZWQgdGFzayBuZXZlciBydW5zCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCA1MDApOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVGltZXJUYXNrIHNob3VsZCBub3QgaGF2ZSBydW4geWV0IiwgdGVzdFRhc2suY2FuY2VsKCkpOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKworICAgICAgICAgICAgLy8gRW5zdXJlIGNhbmNlbGxpbmcgYSB0YXNrIHdoaWNoIGhhcyBhbHJlYWR5IHJ1biByZXR1cm5zIHRydWUKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIDUwKTsKKyAgICAgICAgICAgIHdoaWxlICh0ZXN0VGFzay53YXNSdW4oKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDE1MCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEZhbHNlKAorICAgICAgICAgICAgICAgICAgICAiVGltZXJUYXNrLmNhbmNlbCgpIHNob3VsZCByZXR1cm4gZmFsc2UgaWYgdGFzayBoYXMgcnVuIiwKKyAgICAgICAgICAgICAgICAgICAgdGVzdFRhc2suY2FuY2VsKCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgICAgICAgICAgICJUaW1lclRhc2suY2FuY2VsKCkgc2hvdWxkIHJldHVybiBmYWxzZSBpZiBjYWxsZWQgYSBzZWNvbmQgdGltZSIsCisgICAgICAgICAgICAgICAgICAgIHRlc3RUYXNrLmNhbmNlbCgpKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBjYW5jZWxsaW5nIGEgcmVwZWF0ZWQgZXhlY3V0aW9uIHRhc2sgd2hpY2ggaGFzIG5ldmVyIHJ1bgorICAgICAgICAgICAgLy8gcmV0dXJucyB0cnVlCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCA1MDAsIDUwMCk7IC8vIHNob3VsZCBuZXZlciBydW4KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJUaW1lclRhc2suY2FuY2VsKCkgc2hvdWxkIHJldHVybiB0cnVlIGlmIHNoZWR1bGVkIGZvciByZXBlYXRlZCBleGVjdXRpb24gZXZlbiBpZiBub3QgcnVuIiwKKyAgICAgICAgICAgICAgICAgICAgdGVzdFRhc2suY2FuY2VsKCkpOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKworICAgICAgICAgICAgLy8gRW5zdXJlIGNhbmNlbGxpbmcgYSByZXBlYXRlZCBleGVjdXRpb24gdGFzayB3aGljaCBIQVMgcnVuIHJldHVybnMKKyAgICAgICAgICAgIC8vIHRydWUKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIDUwLCA1MCk7CisgICAgICAgICAgICB3aGlsZSAodGVzdFRhc2sud2FzUnVuKCkgPT0gMCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxMDApOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiVGltZXJUYXNrLmNhbmNlbCgpIHNob3VsZCByZXR1cm4gdHJ1ZSBpZiBzaGVkdWxlZCBmb3IgcmVwZWF0ZWQgZXhlY3V0aW9uIGFuZCBydW4iLAorICAgICAgICAgICAgICAgICAgICB0ZXN0VGFzay5jYW5jZWwoKSk7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworCisgICAgICAgICAgICAvLyBFbnN1cmUgY2FsbGluZyBjYW5jZWwgYSBzZWNvbmQgcmV0dXJucyBmYWxzZQorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgdGVzdFRhc2sgPSBuZXcgVGltZXJUZXN0VGFzaygpOworICAgICAgICAgICAgdC5zY2hlZHVsZSh0ZXN0VGFzaywgNTAwMCk7IC8vIFNob3VsZCBuZXZlciBydW4KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJUaW1lclRhc2suY2FuY2VsKCkgc2hvdWxkIHJldHVybiB0cnVlIGlmIHRhc2sgaGFzIG5ldmVyIHJ1biIsCisgICAgICAgICAgICAgICAgICAgIHRlc3RUYXNrLmNhbmNlbCgpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKAorICAgICAgICAgICAgICAgICAgICAiVGltZXJUYXNrLmNhbmNlbCgpIHNob3VsZCByZXR1cm4gZmFsc2UgaWYgY2FsbGVkIGEgc2Vjb25kIHRpbWUiLAorICAgICAgICAgICAgICAgICAgICB0ZXN0VGFzay5jYW5jZWwoKSk7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworCisgICAgICAgICAgICAvLyBFbnN1cmUgY2FuY2VsbGluZyBhIHRhc2sgd29uJ3QgY2F1c2UgZGVhZGxvY2sKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIHRlc3RUYXNrLnNsZWVwSW5SdW4odHJ1ZSk7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRlc3RUYXNrLnN0YXJ0KSB7CisgICAgICAgICAgICAgICAgdC5zY2hlZHVsZSh0ZXN0VGFzaywgMCk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgdGVzdFRhc2suc3RhcnQud2FpdCgpOworICAgICAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoNTApOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRGYWxzZSgiVGltZXJUYXNrIHNob3VsZCBoYXZlIGJlZW4gY2FuY2VsbGVkIiwgdGVzdFRhc2sKKyAgICAgICAgICAgICAgICAgICAgLmNhbmNlbCgpKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKQorICAgICAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVGltZXJUYXNrI3NjaGVkdWxlZEV4ZWN1dGlvblRpbWUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2NoZWR1bGVkRXhlY3V0aW9uVGltZSgpIHsKKyAgICAgICAgVGltZXIgdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBFbnN1cmUgc2NoZWR1bGVkRXhlY3V0aW9uVGltZSBpcyByb3VnaGx5IHJpZ2h0CisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICBUaW1lclRlc3RUYXNrIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIDEwMCk7CisgICAgICAgICAgICBsb25nIHRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIDEwMDsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGVzdFRhc2suc3luYykgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHRlc3RUYXNrLnN5bmMud2FpdCg1MDApOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsb25nIHNjaGVkdWxlZEV4ZWN1dGlvblRpbWUgPSB0ZXN0VGFzay5zY2hlZHVsZWRFeGVjdXRpb25UaW1lKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHNjaGVkdWxlZEV4ZWN1dGlvblRpbWUgPD0gdGltZSk7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworCisgICAgICAgICAgICAvLyBFbnN1cmUgc2NoZWR1bGVkRXhlY3V0aW9uVGltZSBpcyB0aGUgbGFzdCBzY2hlZHVsZWQgdGltZQorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgdGVzdFRhc2sgPSBuZXcgVGltZXJUZXN0VGFzaygpOworICAgICAgICAgICAgdC5zY2hlZHVsZSh0ZXN0VGFzaywgMTAwLCA1MDApOworICAgICAgICAgICAgbG9uZyBlc3ROb3cgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIDEwMDsKKyAgICAgICAgICAgIC8vIFdpbGwgd2FrZSBpbiAxMDAsIGFuZCBldmVyeSA1MDAgcnVuIGFnYWluCisgICAgICAgICAgICAvLyBXZSB3YW50IHRvIHRyeSB0byBnZXQgaXQgYWZ0ZXIgaXQncyBydW4gYXQgbGVhc3Qgb25jZSBidXQgbm90CisgICAgICAgICAgICAvLyB0d2ljZQorICAgICAgICAgICAgc3luY2hyb25pemVkICh0ZXN0VGFzay5zeW5jKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgdGVzdFRhc2suc3luYy53YWl0KDUwMCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNjaGVkdWxlZEV4ZWN1dGlvblRpbWUgPSB0ZXN0VGFzay5zY2hlZHVsZWRFeGVjdXRpb25UaW1lKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHNjaGVkdWxlZEV4ZWN1dGlvblRpbWUgPD0gZXN0Tm93KTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKQorICAgICAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5UaW1lclRhc2sjcnVuKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3J1bigpIHsKKyAgICAgICAgVGltZXIgdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBFbnN1cmUgYSBuZXcgdGFzayBpcyBuZXZlciBydW4KKyAgICAgICAgICAgIFRpbWVyVGVzdFRhc2sgdGVzdFRhc2sgPSBuZXcgVGltZXJUZXN0VGFzaygpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMjAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGltZXJUYXNrLnJ1bigpIG1ldGhvZCBzaG91bGQgbm90IGhhdmUgYmVlbiBjYWxsZWQiLAorICAgICAgICAgICAgICAgICAgICAwLCB0ZXN0VGFzay53YXNSdW4oKSk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBhIHRhc2sgaXMgcnVuCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCAyMDApOworICAgICAgICAgICAgd2hpbGUodGVzdFRhc2sud2FzUnVuKCkgPCAxKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDQwMCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHRlc3RUYXNrLmNhbmNlbCgpKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKQorICAgICAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgIH0KKworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL1RpbWVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvVGltZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjZkODhiYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL1RpbWVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTIxOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS5sYW5nLlRocmVhZC5VbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXI7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLlRpbWVyOworaW1wb3J0IGphdmEudXRpbC5UaW1lclRhc2s7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY1JlZmVyZW5jZTsKKworcHVibGljIGNsYXNzIFRpbWVyVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBpbnQgdGltZXJDb3VudGVyID0gMDsKKworICAgIE9iamVjdCBzeW5jID0gbmV3IE9iamVjdCgpOworCisgICAgLyoqCisgICAgICogV2FybmluZzogVGhlc2UgdGVzdHMgaGF2ZSB0aGUgcG9zc2liaWxpdHkgdG8gbGVhdmUgYSBWTSBoYW5naW5nIGlmIHRoZQorICAgICAqIFRpbWVyIGlzIG5vdCBjYW5jZWxsZWQuCisgICAgICovCisgICAgY2xhc3MgVGltZXJUZXN0VGFzayBleHRlbmRzIFRpbWVyVGFzayB7CisgICAgICAgIGludCB3YXNSdW4gPSAwOworCisgICAgICAgIC8vIFNob3VsZCB3ZSBzbGVlcCBmb3IgMjAwIG1zIGVhY2ggcnVuKCk/CisgICAgICAgIGJvb2xlYW4gc2xlZXBJblJ1biA9IGZhbHNlOworCisgICAgICAgIC8vIFNob3VsZCB3ZSBpbmNyZW1lbnQgdGhlIHRpbWVyQ291bnRlcj8KKyAgICAgICAgYm9vbGVhbiBpbmNyZW1lbnRDb3VudCA9IGZhbHNlOworCisgICAgICAgIC8vIFNob3VsZCB3ZSB0ZXJtaW5hdGUgdGhlIHRpbWVyIGF0IGEgc3BlY2lmaWMgdGltZXJDb3VudGVyPworICAgICAgICBpbnQgdGVybWluYXRlQ291bnQgPSAtMTsKKworICAgICAgICAvLyBUaGUgdGltZXIgd2UgYmVsb25nIHRvCisgICAgICAgIFRpbWVyIHRpbWVyID0gbnVsbDsKKworICAgICAgICBwdWJsaWMgVGltZXJUZXN0VGFzaygpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBUaW1lclRlc3RUYXNrKFRpbWVyIHQpIHsKKyAgICAgICAgICAgIHRpbWVyID0gdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgICAgIHdhc1J1bisrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGluY3JlbWVudENvdW50KQorICAgICAgICAgICAgICAgIHRpbWVyQ291bnRlcisrOworICAgICAgICAgICAgaWYgKHRlcm1pbmF0ZUNvdW50ID09IHRpbWVyQ291bnRlciAmJiB0aW1lciAhPSBudWxsKQorICAgICAgICAgICAgICAgIHRpbWVyLmNhbmNlbCgpOworICAgICAgICAgICAgaWYgKHNsZWVwSW5SdW4pIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMjAwKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgc3luY2hyb25pemVkIChzeW5jKSB7CisgICAgICAgICAgICAgICAgc3luYy5ub3RpZnkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IHdhc1J1bigpIHsKKyAgICAgICAgICAgIHJldHVybiB3YXNSdW47CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzbGVlcEluUnVuKGJvb2xlYW4gc2xlZXBJblJ1bikgeworICAgICAgICAgICAgdGhpcy5zbGVlcEluUnVuID0gc2xlZXBJblJ1bjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGluY3JlbWVudENvdW50KGJvb2xlYW4gaW5jcmVtZW50Q291bnQpIHsKKyAgICAgICAgICAgIHRoaXMuaW5jcmVtZW50Q291bnQgPSBpbmNyZW1lbnRDb3VudDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHRlcm1pbmF0ZUNvdW50KGludCB0ZXJtaW5hdGVDb3VudCkgeworICAgICAgICAgICAgdGhpcy50ZXJtaW5hdGVDb3VudCA9IHRlcm1pbmF0ZUNvdW50OworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlRpbWVyI1RpbWVyKGJvb2xlYW4pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvclooKSB7CisgICAgICAgIFRpbWVyIHQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gRW5zdXJlIGEgdGFzayBpcyBydW4KKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIodHJ1ZSk7CisgICAgICAgICAgICBUaW1lclRlc3RUYXNrIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIDIwMCk7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHN5bmMpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzeW5jLndhaXQoMTAwMCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGltZXJUYXNrLnJ1bigpIG1ldGhvZCBub3QgY2FsbGVkIGFmdGVyIDIwMG1zIiwKKyAgICAgICAgICAgICAgICAgICAgMSwgdGVzdFRhc2sud2FzUnVuKCkpOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICh0ICE9IG51bGwpCisgICAgICAgICAgICAgICAgdC5jYW5jZWwoKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlRpbWVyI1RpbWVyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICBUaW1lciB0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIEVuc3VyZSBhIHRhc2sgaXMgcnVuCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICBUaW1lclRlc3RUYXNrIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIDIwMCk7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHN5bmMpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzeW5jLndhaXQoMTAwMCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGltZXJUYXNrLnJ1bigpIG1ldGhvZCBub3QgY2FsbGVkIGFmdGVyIDIwMG1zIiwKKyAgICAgICAgICAgICAgICAgICAgMSwgdGVzdFRhc2sud2FzUnVuKCkpOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICh0ICE9IG51bGwpCisgICAgICAgICAgICAgICAgdC5jYW5jZWwoKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlRpbWVyI1RpbWVyKFN0cmluZywgYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yU1ooKSB7CisgICAgICAgIFRpbWVyIHQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gRW5zdXJlIGEgdGFzayBpcyBydW4KKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoInRlc3RfQ29uc3RydWN0b3JTWlRocmVhZCIsIHRydWUpOworICAgICAgICAgICAgVGltZXJUZXN0VGFzayB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCAyMDApOworICAgICAgICAgICAgc3luY2hyb25pemVkIChzeW5jKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3luYy53YWl0KDEwMDApOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHt9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRpbWVyVGFzay5ydW4oKSBtZXRob2Qgbm90IGNhbGxlZCBhZnRlciAyMDBtcyIsIDEsCisgICAgICAgICAgICAgICAgICAgIHRlc3RUYXNrLndhc1J1bigpKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKQorICAgICAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFRpbWVyKG51bGwsIHRydWUpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBUaW1lcihudWxsLCBmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVGltZXIjVGltZXIoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JTKCkgeworICAgICAgICBUaW1lciB0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIEVuc3VyZSBhIHRhc2sgaXMgcnVuCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCJ0ZXN0X0NvbnN0cnVjdG9yU1RocmVhZCIpOworICAgICAgICAgICAgVGltZXJUZXN0VGFzayB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCAyMDApOworICAgICAgICAgICAgc3luY2hyb25pemVkIChzeW5jKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3luYy53YWl0KDEwMDApOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHt9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRpbWVyVGFzay5ydW4oKSBtZXRob2Qgbm90IGNhbGxlZCBhZnRlciAyMDBtcyIsIDEsCisgICAgICAgICAgICAgICAgICAgIHRlc3RUYXNrLndhc1J1bigpKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKQorICAgICAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFRpbWVyKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlRpbWVyI2NhbmNlbCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jYW5jZWwoKSB7CisgICAgICAgIFRpbWVyIHQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gRW5zdXJlIGEgdGFzayB0aHJvd3MgYW4gSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGFmdGVyIGNhbmNlbGxlZAorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgVGltZXJUZXN0VGFzayB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworICAgICAgICAgICAgYm9vbGVhbiBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdC5zY2hlZHVsZSh0ZXN0VGFzaywgMTAwLCAyMDApOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlNjaGVkdWxpbmcgYSB0YXNrIGFmdGVyIFRpbWVyLmNhbmNlbCgpIHNob3VsZCB0aHJvdyBleGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24pOworCisgICAgICAgICAgICAvLyBFbnN1cmUgYSB0YXNrIGlzIHJ1biBidXQgbm90IGFmdGVyIGNhbmNlbAorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgdGVzdFRhc2sgPSBuZXcgVGltZXJUZXN0VGFzaygpOworICAgICAgICAgICAgdC5zY2hlZHVsZSh0ZXN0VGFzaywgMTAwLCA1MDApOworICAgICAgICAgICAgc3luY2hyb25pemVkIChzeW5jKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc3luYy53YWl0KDEwMDApOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRpbWVyVGFzay5ydW4oKSBtZXRob2Qgbm90IGNhbGxlZCBhZnRlciAyMDBtcyIsCisgICAgICAgICAgICAgICAgICAgIDEsIHRlc3RUYXNrLndhc1J1bigpKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHN5bmMpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzeW5jLndhaXQoNTAwKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaW1lclRhc2sucnVuKCkgbWV0aG9kIHNob3VsZCBub3QgaGF2ZSBiZWVuIGNhbGxlZCBhZnRlciBjYW5jZWwiLAorICAgICAgICAgICAgICAgICAgICAxLCB0ZXN0VGFzay53YXNSdW4oKSk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSB5b3UgY2FuIGNhbGwgY2FuY2VsIG1vcmUgdGhhbiBvbmNlCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCAxMDAsIDUwMCk7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHN5bmMpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzeW5jLndhaXQoNTAwKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaW1lclRhc2sucnVuKCkgbWV0aG9kIG5vdCBjYWxsZWQgYWZ0ZXIgMjAwbXMiLAorICAgICAgICAgICAgICAgICAgICAxLCB0ZXN0VGFzay53YXNSdW4oKSk7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHN5bmMpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzeW5jLndhaXQoNTAwKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaW1lclRhc2sucnVuKCkgbWV0aG9kIHNob3VsZCBub3QgaGF2ZSBiZWVuIGNhbGxlZCBhZnRlciBjYW5jZWwiLAorICAgICAgICAgICAgICAgICAgICAxLCB0ZXN0VGFzay53YXNSdW4oKSk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSB0aGF0IGEgY2FsbCB0byBjYW5jZWwgZnJvbSB3aXRoaW4gYSB0aW1lciBlbnN1cmVzIG5vIG1vcmUKKyAgICAgICAgICAgIC8vIHJ1bgorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgdGVzdFRhc2sgPSBuZXcgVGltZXJUZXN0VGFzayh0KTsKKyAgICAgICAgICAgIHRlc3RUYXNrLmluY3JlbWVudENvdW50KHRydWUpOworICAgICAgICAgICAgdGVzdFRhc2sudGVybWluYXRlQ291bnQoNSk7IC8vIFRlcm1pbmF0ZSBhZnRlciA1IHJ1bnMKKyAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIDEwMCwgMTAwKTsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoc3luYykgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN5bmMud2FpdCgyMDApOworICAgICAgICAgICAgICAgICAgICBzeW5jLndhaXQoMjAwKTsKKyAgICAgICAgICAgICAgICAgICAgc3luYy53YWl0KDIwMCk7CisgICAgICAgICAgICAgICAgICAgIHN5bmMud2FpdCgyMDApOworICAgICAgICAgICAgICAgICAgICBzeW5jLndhaXQoMjAwKTsKKyAgICAgICAgICAgICAgICAgICAgc3luYy53YWl0KDIwMCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoIlRpbWVyVGFzay5ydW4oKSBtZXRob2Qgc2hvdWxkIGJlIGNhbGxlZCA1IHRpbWVzIG5vdCAiCisgICAgICAgICAgICAgICAgICAgICsgdGVzdFRhc2sud2FzUnVuKCksIHRlc3RUYXNrLndhc1J1bigpID09IDUpOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDIwMCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKQorICAgICAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5UaW1lciNwdXJnZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wdXJnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUaW1lciB0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCB0LnB1cmdlKCkpOworCisgICAgICAgICAgICBUaW1lclRlc3RUYXNrW10gdGFza3MgPSBuZXcgVGltZXJUZXN0VGFza1sxMDBdOworICAgICAgICAgICAgaW50W10gZGVsYXlUaW1lID0geyA1MCwgODAsIDIwLCA3MCwgNDAsIDEwLCA5MCwgMzAsIDYwIH07CisKKyAgICAgICAgICAgIGludCBqID0gMDsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspIHsKKyAgICAgICAgICAgICAgICB0YXNrc1tpXSA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICAgICAgdC5zY2hlZHVsZSh0YXNrc1tpXSwgZGVsYXlUaW1lW2orK10sIDIwMCk7CisgICAgICAgICAgICAgICAgaWYgKGogPT0gOSkgeworICAgICAgICAgICAgICAgICAgICBqID0gMDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNTA7IGkrKykgeworICAgICAgICAgICAgICAgIHRhc2tzW2ldLmNhbmNlbCgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBhc3NlcnRUcnVlKHQucHVyZ2UoKSA8PSA1MCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgdC5wdXJnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICh0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0LmNhbmNlbCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlRpbWVyI3NjaGVkdWxlKGphdmEudXRpbC5UaW1lclRhc2ssIGphdmEudXRpbC5EYXRlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2NoZWR1bGVMamF2YV91dGlsX1RpbWVyVGFza0xqYXZhX3V0aWxfRGF0ZSgpIHsKKyAgICAgICAgVGltZXIgdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBFbnN1cmUgYSBUaW1lciB0aHJvd3MgYW4gSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGFmdGVyIGNhbmNlbGxlZAorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgVGltZXJUZXN0VGFzayB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICBEYXRlIGQgPSBuZXcgRGF0ZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIDEwMCk7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworICAgICAgICAgICAgYm9vbGVhbiBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdC5zY2hlZHVsZSh0ZXN0VGFzaywgZCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiU2NoZWR1bGluZyBhIHRhc2sgYWZ0ZXIgVGltZXIuY2FuY2VsKCkgc2hvdWxkIHRocm93IGV4Y2VwdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbik7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBhIFRpbWVyIHRocm93cyBhbiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGFzayBhbHJlYWR5CisgICAgICAgICAgICAvLyBjYW5jZWxsZWQKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIGQgPSBuZXcgRGF0ZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIDEwMCk7CisgICAgICAgICAgICB0ZXN0VGFzay5jYW5jZWwoKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCBkKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJTY2hlZHVsaW5nIGEgdGFzayBhZnRlciBjYW5jZWxsaW5nIGl0IHNob3VsZCB0aHJvdyBleGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24pOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKworICAgICAgICAgICAgLy8gRW5zdXJlIGEgVGltZXIgdGhyb3dzIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBkZWxheSBpcworICAgICAgICAgICAgLy8gbmVnYXRpdmUKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIGQgPSBuZXcgRGF0ZSgtMTAwKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCBkKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJTY2hlZHVsaW5nIGEgdGFzayB3aXRoIG5lZ2F0aXZlIGRhdGUgc2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbik7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworCisgICAgICAgICAgICAvLyBFbnN1cmUgYSBUaW1lciB0aHJvd3MgYSBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgdGFzayBpcyBudWxsCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgICAgIGQgPSBuZXcgRGF0ZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIDEwMCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHQuc2NoZWR1bGUobnVsbCwgZCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJTY2hlZHVsaW5nIGEgbnVsbCB0YXNrIHNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbik7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworCisgICAgICAgICAgICAvLyBFbnN1cmUgYSBUaW1lciB0aHJvd3MgYSBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgZGF0ZSBpcyBudWxsCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdC5zY2hlZHVsZSh0ZXN0VGFzaywgbnVsbCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJTY2hlZHVsaW5nIGEgbnVsbCBkYXRlIHNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbik7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworCisgICAgICAgICAgICAvLyBFbnN1cmUgcHJvcGVyIHNlcXVlbmNlIG9mIGV4Y2VwdGlvbnMKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIGQgPSBuZXcgRGF0ZSgtMTAwKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LnNjaGVkdWxlKG51bGwsIGQpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlNjaGVkdWxpbmcgYSBudWxsIHRhc2sgd2l0aCBuZWdhdGl2ZSBkYXRlIHNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZmlyc3QiLAorICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24pOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKworICAgICAgICAgICAgLy8gRW5zdXJlIGEgdGFzayBpcyBydW4KKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIGQgPSBuZXcgRGF0ZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIDIwMCk7CisgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCBkKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDQwMCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRpbWVyVGFzay5ydW4oKSBtZXRob2Qgbm90IGNhbGxlZCBhZnRlciAyMDBtcyIsCisgICAgICAgICAgICAgICAgICAgIDEsIHRlc3RUYXNrLndhc1J1bigpKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBtdWx0aXBsZSB0YXNrcyBhcmUgcnVuCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0ZXN0VGFzay5pbmNyZW1lbnRDb3VudCh0cnVlKTsKKyAgICAgICAgICAgIGQgPSBuZXcgRGF0ZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIDEwMCk7CisgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCBkKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIHRlc3RUYXNrLmluY3JlbWVudENvdW50KHRydWUpOworICAgICAgICAgICAgZCA9IG5ldyBEYXRlKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpICsgMTUwKTsKKyAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIGQpOworICAgICAgICAgICAgdGVzdFRhc2sgPSBuZXcgVGltZXJUZXN0VGFzaygpOworICAgICAgICAgICAgdGVzdFRhc2suaW5jcmVtZW50Q291bnQodHJ1ZSk7CisgICAgICAgICAgICBkID0gbmV3IERhdGUoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgKyA3MCk7CisgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCBkKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIHRlc3RUYXNrLmluY3JlbWVudENvdW50KHRydWUpOworICAgICAgICAgICAgZCA9IG5ldyBEYXRlKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpICsgMTApOworICAgICAgICAgICAgdC5zY2hlZHVsZSh0ZXN0VGFzaywgZCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCg0MDApOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIk11bHRpcGxlIHRhc2tzIHNob3VsZCBoYXZlIGluY3JlbWVudGVkIGNvdW50ZXIgNCB0aW1lcyBub3QgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdGltZXJDb3VudGVyLCB0aW1lckNvdW50ZXIgPT0gNCk7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0LmNhbmNlbCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlRpbWVyI3NjaGVkdWxlKGphdmEudXRpbC5UaW1lclRhc2ssIGxvbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zY2hlZHVsZUxqYXZhX3V0aWxfVGltZXJUYXNrSigpIHsKKyAgICAgICAgVGltZXIgdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBFbnN1cmUgYSBUaW1lciB0aHJvd3MgYW4gSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGFmdGVyIGNhbmNlbGxlZAorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgVGltZXJUZXN0VGFzayB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworICAgICAgICAgICAgYm9vbGVhbiBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdC5zY2hlZHVsZSh0ZXN0VGFzaywgMTAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJTY2hlZHVsaW5nIGEgdGFzayBhZnRlciBUaW1lci5jYW5jZWwoKSBzaG91bGQgdGhyb3cgZXhjZXB0aW9uIiwKKyAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uKTsKKworICAgICAgICAgICAgLy8gRW5zdXJlIGEgVGltZXIgdGhyb3dzIGFuIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0YXNrIGFscmVhZHkKKyAgICAgICAgICAgIC8vIGNhbmNlbGxlZAorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgdGVzdFRhc2sgPSBuZXcgVGltZXJUZXN0VGFzaygpOworICAgICAgICAgICAgdGVzdFRhc2suY2FuY2VsKCk7CisgICAgICAgICAgICBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdC5zY2hlZHVsZSh0ZXN0VGFzaywgMTAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJTY2hlZHVsaW5nIGEgdGFzayBhZnRlciBjYW5jZWxsaW5nIGl0IHNob3VsZCB0aHJvdyBleGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24pOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKworICAgICAgICAgICAgLy8gRW5zdXJlIGEgVGltZXIgdGhyb3dzIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBkZWxheSBpcworICAgICAgICAgICAgLy8gbmVnYXRpdmUKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCAtMTAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJTY2hlZHVsaW5nIGEgdGFzayB3aXRoIG5lZ2F0aXZlIGRlbGF5IHNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24pOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKworICAgICAgICAgICAgLy8gRW5zdXJlIGEgVGltZXIgdGhyb3dzIGEgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHRhc2sgaXMgbnVsbAorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgZXhjZXB0aW9uID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHQuc2NoZWR1bGUobnVsbCwgMTApOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiU2NoZWR1bGluZyBhIG51bGwgdGFzayBzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24pOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKworICAgICAgICAgICAgLy8gRW5zdXJlIHByb3BlciBzZXF1ZW5jZSBvZiBleGNlcHRpb25zCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdC5zY2hlZHVsZShudWxsLCAtMTApOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlNjaGVkdWxpbmcgYSBudWxsIHRhc2sgd2l0aCBuZWdhdGl2ZSBkZWxheXMgc2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBmaXJzdCIsCisgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbik7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworCisgICAgICAgICAgICAvLyBFbnN1cmUgYSB0YXNrIGlzIHJ1bgorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgdGVzdFRhc2sgPSBuZXcgVGltZXJUZXN0VGFzaygpOworICAgICAgICAgICAgdC5zY2hlZHVsZSh0ZXN0VGFzaywgMjAwKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDQwMCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRpbWVyVGFzay5ydW4oKSBtZXRob2Qgbm90IGNhbGxlZCBhZnRlciAyMDBtcyIsCisgICAgICAgICAgICAgICAgICAgIDEsIHRlc3RUYXNrLndhc1J1bigpKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBtdWx0aXBsZSB0YXNrcyBhcmUgcnVuCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0ZXN0VGFzay5pbmNyZW1lbnRDb3VudCh0cnVlKTsKKyAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIDEwMCk7CisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0ZXN0VGFzay5pbmNyZW1lbnRDb3VudCh0cnVlKTsKKyAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIDE1MCk7CisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0ZXN0VGFzay5pbmNyZW1lbnRDb3VudCh0cnVlKTsKKyAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIDcwKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIHRlc3RUYXNrLmluY3JlbWVudENvdW50KHRydWUpOworICAgICAgICAgICAgdC5zY2hlZHVsZSh0ZXN0VGFzaywgMTApOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoNDAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJNdWx0aXBsZSB0YXNrcyBzaG91bGQgaGF2ZSBpbmNyZW1lbnRlZCBjb3VudGVyIDQgdGltZXMgbm90ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHRpbWVyQ291bnRlciwgdGltZXJDb3VudGVyID09IDQpOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICh0ICE9IG51bGwpCisgICAgICAgICAgICAgICAgdC5jYW5jZWwoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5UaW1lciNzY2hlZHVsZShqYXZhLnV0aWwuVGltZXJUYXNrLCBsb25nLCBsb25nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2NoZWR1bGVMamF2YV91dGlsX1RpbWVyVGFza0pKKCkgeworICAgICAgICBUaW1lciB0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIEVuc3VyZSBhIFRpbWVyIHRocm93cyBhbiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gYWZ0ZXIgY2FuY2VsbGVkCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICBUaW1lclRlc3RUYXNrIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgICAgICBib29sZWFuIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCAxMDAsIDEwMCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiU2NoZWR1bGluZyBhIHRhc2sgYWZ0ZXIgVGltZXIuY2FuY2VsKCkgc2hvdWxkIHRocm93IGV4Y2VwdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbik7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBhIFRpbWVyIHRocm93cyBhbiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGFzayBhbHJlYWR5CisgICAgICAgICAgICAvLyBjYW5jZWxsZWQKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIHRlc3RUYXNrLmNhbmNlbCgpOworICAgICAgICAgICAgZXhjZXB0aW9uID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIDEwMCwgMTAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJTY2hlZHVsaW5nIGEgdGFzayBhZnRlciBjYW5jZWxsaW5nIGl0IHNob3VsZCB0aHJvdyBleGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24pOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKworICAgICAgICAgICAgLy8gRW5zdXJlIGEgVGltZXIgdGhyb3dzIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBkZWxheSBpcworICAgICAgICAgICAgLy8gbmVnYXRpdmUKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCAtMTAwLCAxMDApOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlNjaGVkdWxpbmcgYSB0YXNrIHdpdGggbmVnYXRpdmUgZGVsYXkgc2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbik7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworCisgICAgICAgICAgICAvLyBFbnN1cmUgYSBUaW1lciB0aHJvd3MgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHBlcmlvZCBpcworICAgICAgICAgICAgLy8gbmVnYXRpdmUKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCAxMDAsIC0xMDApOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlNjaGVkdWxpbmcgYSB0YXNrIHdpdGggbmVnYXRpdmUgcGVyaW9kIHNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24pOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKworICAgICAgICAgICAgLy8gRW5zdXJlIGEgVGltZXIgdGhyb3dzIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBwZXJpb2QgaXMKKyAgICAgICAgICAgIC8vIHplcm8KKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCAxMDAsIDApOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlNjaGVkdWxpbmcgYSB0YXNrIHdpdGggMCBwZXJpb2Qgc2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbik7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworCisgICAgICAgICAgICAvLyBFbnN1cmUgYSBUaW1lciB0aHJvd3MgYSBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgdGFzayBpcyBudWxsCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdC5zY2hlZHVsZShudWxsLCAxMCwgMTApOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiU2NoZWR1bGluZyBhIG51bGwgdGFzayBzaG91bGQgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24pOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKworICAgICAgICAgICAgLy8gRW5zdXJlIHByb3BlciBzZXF1ZW5jZSBvZiBleGNlcHRpb25zCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdC5zY2hlZHVsZShudWxsLCAtMTAsIC0xMCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiU2NoZWR1bGluZyBhIG51bGwgdGFzayB3aXRoIG5lZ2F0aXZlIGRlbGF5cyBzaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGZpcnN0IiwKKyAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBhIHRhc2sgaXMgcnVuIGF0IGxlYXN0IHR3aWNlCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCAxMDAsIDEwMCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCg0MDApOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlRpbWVyVGFzay5ydW4oKSBtZXRob2Qgc2hvdWxkIGhhdmUgYmVlbiBjYWxsZWQgYXQgbGVhc3QgdHdpY2UgKCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHRlc3RUYXNrLndhc1J1bigpICsgIikiLCB0ZXN0VGFzay53YXNSdW4oKSA+PSAyKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBtdWx0aXBsZSB0YXNrcyBhcmUgcnVuCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0ZXN0VGFzay5pbmNyZW1lbnRDb3VudCh0cnVlKTsKKyAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIDEwMCwgMTAwKTsgLy8gYXQgbGVhc3QgOSB0aW1lcworICAgICAgICAgICAgdGVzdFRhc2sgPSBuZXcgVGltZXJUZXN0VGFzaygpOworICAgICAgICAgICAgdGVzdFRhc2suaW5jcmVtZW50Q291bnQodHJ1ZSk7CisgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCAyMDAsIDEwMCk7IC8vIGF0IGxlYXN0IDcgdGltZXMKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIHRlc3RUYXNrLmluY3JlbWVudENvdW50KHRydWUpOworICAgICAgICAgICAgdC5zY2hlZHVsZSh0ZXN0VGFzaywgMzAwLCAyMDApOyAvLyBhdCBsZWFzdCA0IHRpbWVzCisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0ZXN0VGFzay5pbmNyZW1lbnRDb3VudCh0cnVlKTsKKyAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIDEwMCwgMjAwKTsgLy8gYXQgbGVhc3QgNCB0aW1lcworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTIwMCk7IC8vIEFsbG93ZWQgbW9yZSByb29tIGZvciBlcnJvcgorICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIk11bHRpcGxlIHRhc2tzIHNob3VsZCBoYXZlIGluY3JlbWVudGVkIGNvdW50ZXIgMjQgdGltZXMgbm90ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHRpbWVyQ291bnRlciwgdGltZXJDb3VudGVyID49IDI0KTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKQorICAgICAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVGltZXIjc2NoZWR1bGUoamF2YS51dGlsLlRpbWVyVGFzaywgamF2YS51dGlsLkRhdGUsCisgICAgICogICAgICAgIGxvbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zY2hlZHVsZUxqYXZhX3V0aWxfVGltZXJUYXNrTGphdmFfdXRpbF9EYXRlSigpIHsKKyAgICAgICAgVGltZXIgdCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBFbnN1cmUgYSBUaW1lciB0aHJvd3MgYW4gSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGFmdGVyIGNhbmNlbGxlZAorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgVGltZXJUZXN0VGFzayB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICBEYXRlIGQgPSBuZXcgRGF0ZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIDEwMCk7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworICAgICAgICAgICAgYm9vbGVhbiBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdC5zY2hlZHVsZSh0ZXN0VGFzaywgZCwgMTAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJTY2hlZHVsaW5nIGEgdGFzayBhZnRlciBUaW1lci5jYW5jZWwoKSBzaG91bGQgdGhyb3cgZXhjZXB0aW9uIiwKKyAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uKTsKKworICAgICAgICAgICAgLy8gRW5zdXJlIGEgVGltZXIgdGhyb3dzIGFuIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0YXNrIGFscmVhZHkKKyAgICAgICAgICAgIC8vIGNhbmNlbGxlZAorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgZCA9IG5ldyBEYXRlKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpICsgMTAwKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIHRlc3RUYXNrLmNhbmNlbCgpOworICAgICAgICAgICAgZXhjZXB0aW9uID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIGQsIDEwMCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiU2NoZWR1bGluZyBhIHRhc2sgYWZ0ZXIgY2FuY2VsbGluZyBpdCBzaG91bGQgdGhyb3cgZXhjZXB0aW9uIiwKKyAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBhIFRpbWVyIHRocm93cyBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgZGVsYXkgaXMKKyAgICAgICAgICAgIC8vIG5lZ2F0aXZlCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICBkID0gbmV3IERhdGUoLTEwMCk7CisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdC5zY2hlZHVsZSh0ZXN0VGFzaywgZCwgMTAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJTY2hlZHVsaW5nIGEgdGFzayB3aXRoIG5lZ2F0aXZlIGRlbGF5IHNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24pOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKworICAgICAgICAgICAgLy8gRW5zdXJlIGEgVGltZXIgdGhyb3dzIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBwZXJpb2QgaXMKKyAgICAgICAgICAgIC8vIG5lZ2F0aXZlCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICBkID0gbmV3IERhdGUoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgKyAxMDApOworICAgICAgICAgICAgdGVzdFRhc2sgPSBuZXcgVGltZXJUZXN0VGFzaygpOworICAgICAgICAgICAgZXhjZXB0aW9uID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIGQsIC0xMDApOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlNjaGVkdWxpbmcgYSB0YXNrIHdpdGggbmVnYXRpdmUgcGVyaW9kIHNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24pOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKworICAgICAgICAgICAgLy8gRW5zdXJlIGEgVGltZXIgdGhyb3dzIGEgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHRhc2sgaXMgbnVsbAorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgZCA9IG5ldyBEYXRlKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpICsgMTAwKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LnNjaGVkdWxlKG51bGwsIGQsIDEwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlNjaGVkdWxpbmcgYSBudWxsIHRhc2sgc2hvdWxkIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIiwKKyAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBhIFRpbWVyIHRocm93cyBhIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBkYXRlIGlzIG51bGwKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCBudWxsLCAxMCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJTY2hlZHVsaW5nIGEgbnVsbCB0YXNrIHNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbik7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworCisgICAgICAgICAgICAvLyBFbnN1cmUgcHJvcGVyIHNlcXVlbmNlIG9mIGV4Y2VwdGlvbnMKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIGQgPSBuZXcgRGF0ZSgtMTAwKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LnNjaGVkdWxlKG51bGwsIGQsIDEwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJTY2hlZHVsaW5nIGEgbnVsbCB0YXNrIHdpdGggbmVnYXRpdmUgZGF0ZXMgc2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBmaXJzdCIsCisgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbik7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworCisgICAgICAgICAgICAvLyBFbnN1cmUgYSB0YXNrIGlzIHJ1biBhdCBsZWFzdCB0d2ljZQorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgZCA9IG5ldyBEYXRlKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpICsgMTAwKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIHQuc2NoZWR1bGUodGVzdFRhc2ssIGQsIDEwMCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCg4MDApOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlRpbWVyVGFzay5ydW4oKSBtZXRob2Qgc2hvdWxkIGhhdmUgYmVlbiBjYWxsZWQgYXQgbGVhc3QgdHdpY2UgKCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHRlc3RUYXNrLndhc1J1bigpICsgIikiLCB0ZXN0VGFzay53YXNSdW4oKSA+PSAyKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBtdWx0aXBsZSB0YXNrcyBhcmUgcnVuCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0ZXN0VGFzay5pbmNyZW1lbnRDb3VudCh0cnVlKTsKKyAgICAgICAgICAgIGQgPSBuZXcgRGF0ZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIDEwMCk7CisgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCBkLCAxMDApOyAvLyBhdCBsZWFzdCA5IHRpbWVzCisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0ZXN0VGFzay5pbmNyZW1lbnRDb3VudCh0cnVlKTsKKyAgICAgICAgICAgIGQgPSBuZXcgRGF0ZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIDIwMCk7CisgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCBkLCAxMDApOyAvLyBhdCBsZWFzdCA3IHRpbWVzCisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0ZXN0VGFzay5pbmNyZW1lbnRDb3VudCh0cnVlKTsKKyAgICAgICAgICAgIGQgPSBuZXcgRGF0ZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIDMwMCk7CisgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCBkLCAyMDApOyAvLyBhdCBsZWFzdCA0IHRpbWVzCisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0ZXN0VGFzay5pbmNyZW1lbnRDb3VudCh0cnVlKTsKKyAgICAgICAgICAgIGQgPSBuZXcgRGF0ZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIDEwMCk7CisgICAgICAgICAgICB0LnNjaGVkdWxlKHRlc3RUYXNrLCBkLCAyMDApOyAvLyBhdCBsZWFzdCA0IHRpbWVzCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCgzMDAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJNdWx0aXBsZSB0YXNrcyBzaG91bGQgaGF2ZSBpbmNyZW1lbnRlZCBjb3VudGVyIDI0IHRpbWVzIG5vdCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyB0aW1lckNvdW50ZXIsIHRpbWVyQ291bnRlciA+PSAyNCk7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICB0LmNhbmNlbCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlRpbWVyI3NjaGVkdWxlQXRGaXhlZFJhdGUoamF2YS51dGlsLlRpbWVyVGFzaywgbG9uZywKKyAgICAgKiAgICAgICAgbG9uZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NjaGVkdWxlQXRGaXhlZFJhdGVMamF2YV91dGlsX1RpbWVyVGFza0pKKCkgeworICAgICAgICBUaW1lciB0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIEVuc3VyZSBhIFRpbWVyIHRocm93cyBhbiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gYWZ0ZXIgY2FuY2VsbGVkCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICBUaW1lclRlc3RUYXNrIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgICAgICBib29sZWFuIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LnNjaGVkdWxlQXRGaXhlZFJhdGUodGVzdFRhc2ssIDEwMCwgMTAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJzY2hlZHVsZUF0Rml4ZWRSYXRlIGFmdGVyIFRpbWVyLmNhbmNlbCgpIHNob3VsZCB0aHJvdyBleGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24pOworCisgICAgICAgICAgICAvLyBFbnN1cmUgYSBUaW1lciB0aHJvd3MgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGRlbGF5IGlzCisgICAgICAgICAgICAvLyBuZWdhdGl2ZQorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgdGVzdFRhc2sgPSBuZXcgVGltZXJUZXN0VGFzaygpOworICAgICAgICAgICAgZXhjZXB0aW9uID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHQuc2NoZWR1bGVBdEZpeGVkUmF0ZSh0ZXN0VGFzaywgLTEwMCwgMTAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJzY2hlZHVsZUF0Rml4ZWRSYXRlIHdpdGggbmVnYXRpdmUgZGVsYXkgc2hvdWxkIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbik7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworCisgICAgICAgICAgICAvLyBFbnN1cmUgYSBUaW1lciB0aHJvd3MgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHBlcmlvZCBpcworICAgICAgICAgICAgLy8gbmVnYXRpdmUKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LnNjaGVkdWxlQXRGaXhlZFJhdGUodGVzdFRhc2ssIDEwMCwgLTEwMCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAic2NoZWR1bGVBdEZpeGVkUmF0ZSB3aXRoIG5lZ2F0aXZlIHBlcmlvZCBzaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIiwKKyAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBhIHRhc2sgaXMgcnVuIGF0IGxlYXN0IHR3aWNlCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICB0LnNjaGVkdWxlQXRGaXhlZFJhdGUodGVzdFRhc2ssIDEwMCwgMTAwKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDQwMCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiVGltZXJUYXNrLnJ1bigpIG1ldGhvZCBzaG91bGQgaGF2ZSBiZWVuIGNhbGxlZCBhdCBsZWFzdCB0d2ljZSAoIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdGVzdFRhc2sud2FzUnVuKCkgKyAiKSIsIHRlc3RUYXNrLndhc1J1bigpID49IDIpOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKworICAgICAgICAgICAgY2xhc3MgU2xvd1RoZW5GYXN0VGFzayBleHRlbmRzIFRpbWVyVGFzayB7CisgICAgICAgICAgICAgICAgaW50IHdhc1J1biA9IDA7CisKKyAgICAgICAgICAgICAgICBsb25nIHN0YXJ0ZWRBdDsKKworICAgICAgICAgICAgICAgIGxvbmcgbGFzdERlbHRhOworCisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgICAgICBpZiAod2FzUnVuID09IDApCisgICAgICAgICAgICAgICAgICAgICAgICBzdGFydGVkQXQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgICAgICAgICAgICAgbGFzdERlbHRhID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIChzdGFydGVkQXQgKyAoMTAwICogd2FzUnVuKSk7CisgICAgICAgICAgICAgICAgICAgIHdhc1J1bisrOworICAgICAgICAgICAgICAgICAgICBpZiAod2FzUnVuID09IDIpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDIwMCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgbG9uZyBsYXN0RGVsdGEoKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBsYXN0RGVsdGE7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcHVibGljIGludCB3YXNSdW4oKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB3YXNSdW47CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBFbnN1cmUgbXVsdGlwbGUgdGFza3MgYXJlIHJ1bgorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgU2xvd1RoZW5GYXN0VGFzayBzbG93VGhlbkZhc3RUYXNrID0gbmV3IFNsb3dUaGVuRmFzdFRhc2soKTsKKworICAgICAgICAgICAgLy8gYXQgbGVhc3QgOSB0aW1lcyBldmVuIHdoZW4gYXNsZWVwCisgICAgICAgICAgICB0LnNjaGVkdWxlQXRGaXhlZFJhdGUoc2xvd1RoZW5GYXN0VGFzaywgMTAwLCAxMDApOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsb25nIGxhc3REZWx0YSA9IHNsb3dUaGVuRmFzdFRhc2subGFzdERlbHRhKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGaXhlZCBSYXRlIFNjaGVkdWxlIHNob3VsZCBjYXRjaCB1cCwgYnV0IGlzIG9mZiBieSAiCisgICAgICAgICAgICAgICAgICAgICsgbGFzdERlbHRhICsgIiBtcyIsIHNsb3dUaGVuRmFzdFRhc2subGFzdERlbHRhIDwgMzAwKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAodCAhPSBudWxsKQorICAgICAgICAgICAgICAgIHQuY2FuY2VsKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVGltZXIjc2NoZWR1bGVBdEZpeGVkUmF0ZShqYXZhLnV0aWwuVGltZXJUYXNrLAorICAgICAqICAgICAgICBqYXZhLnV0aWwuRGF0ZSwgbG9uZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NjaGVkdWxlQXRGaXhlZFJhdGVMamF2YV91dGlsX1RpbWVyVGFza0xqYXZhX3V0aWxfRGF0ZUooKSB7CisgICAgICAgIFRpbWVyIHQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gRW5zdXJlIGEgVGltZXIgdGhyb3dzIGFuIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBhZnRlciBjYW5jZWxsZWQKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIFRpbWVyVGVzdFRhc2sgdGVzdFRhc2sgPSBuZXcgVGltZXJUZXN0VGFzaygpOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKyAgICAgICAgICAgIGJvb2xlYW4gZXhjZXB0aW9uID0gZmFsc2U7CisgICAgICAgICAgICBEYXRlIGQgPSBuZXcgRGF0ZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIDEwMCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHQuc2NoZWR1bGVBdEZpeGVkUmF0ZSh0ZXN0VGFzaywgZCwgMTAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJzY2hlZHVsZUF0Rml4ZWRSYXRlIGFmdGVyIFRpbWVyLmNhbmNlbCgpIHNob3VsZCB0aHJvdyBleGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24pOworCisgICAgICAgICAgICAvLyBFbnN1cmUgYSBUaW1lciB0aHJvd3MgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGRlbGF5IGlzCisgICAgICAgICAgICAvLyBuZWdhdGl2ZQorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgdGVzdFRhc2sgPSBuZXcgVGltZXJUZXN0VGFzaygpOworICAgICAgICAgICAgZXhjZXB0aW9uID0gZmFsc2U7CisgICAgICAgICAgICBkID0gbmV3IERhdGUoLTEwMCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHQuc2NoZWR1bGVBdEZpeGVkUmF0ZSh0ZXN0VGFzaywgZCwgMTAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJzY2hlZHVsZUF0Rml4ZWRSYXRlIHdpdGggbmVnYXRpdmUgRGF0ZSBzaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIiwKKyAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBhIFRpbWVyIHRocm93cyBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgcGVyaW9kIGlzCisgICAgICAgICAgICAvLyBuZWdhdGl2ZQorICAgICAgICAgICAgdCA9IG5ldyBUaW1lcigpOworICAgICAgICAgICAgdGVzdFRhc2sgPSBuZXcgVGltZXJUZXN0VGFzaygpOworICAgICAgICAgICAgZXhjZXB0aW9uID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHQuc2NoZWR1bGVBdEZpeGVkUmF0ZSh0ZXN0VGFzaywgZCwgLTEwMCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAic2NoZWR1bGVBdEZpeGVkUmF0ZSB3aXRoIG5lZ2F0aXZlIHBlcmlvZCBzaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIiwKKyAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBhIFRpbWVyIHRocm93cyBhbiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBkYXRlIGlzIE51bGwKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIHRlc3RUYXNrID0gbmV3IFRpbWVyVGVzdFRhc2soKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LnNjaGVkdWxlQXRGaXhlZFJhdGUodGVzdFRhc2ssIG51bGwsIDEwMCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJzY2hlZHVsZUF0Rml4ZWRSYXRlIHdpdGggbnVsbCBkYXRlIHNob3VsZCB0aHJvdyBOdWxsUG9pbnRlckV4Y2VwdGlvbiIsCisgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbik7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworCisgICAgICAgICAgICAvLyBFbnN1cmUgcHJvcGVyIHNlcXVlbmNlIG9mIGV4Y2VwdGlvbnMKKyAgICAgICAgICAgIHQgPSBuZXcgVGltZXIoKTsKKyAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICAgICAgZCA9IG5ldyBEYXRlKC0xMDApOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LnNjaGVkdWxlQXRGaXhlZFJhdGUobnVsbCwgZCwgMTApOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlNjaGVkdWxpbmcgYSBudWxsIHRhc2sgd2l0aCBuZWdhdGl2ZSBkYXRlIHNob3VsZCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZmlyc3QiLAorICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24pOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKworICAgICAgICAgICAgLy8gRW5zdXJlIHByb3BlciBzZXF1ZW5jZSBvZiBleGNlcHRpb25zCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdC5zY2hlZHVsZUF0Rml4ZWRSYXRlKG51bGwsIG51bGwsIC0xMCk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiU2NoZWR1bGluZyBhIG51bGwgdGFzayAmIG51bGwgZGF0ZSAmIG5lZ2F0aXZlIHBlcmlvZCBzaG91bGQgdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGZpcnN0IiwKKyAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uKTsKKyAgICAgICAgICAgIHQuY2FuY2VsKCk7CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBhIHRhc2sgaXMgcnVuIGF0IGxlYXN0IHR3aWNlCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICB0ZXN0VGFzayA9IG5ldyBUaW1lclRlc3RUYXNrKCk7CisgICAgICAgICAgICBkID0gbmV3IERhdGUoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgKyAxMDApOworICAgICAgICAgICAgdC5zY2hlZHVsZUF0Rml4ZWRSYXRlKHRlc3RUYXNrLCBkLCAxMDApOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoNDAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJUaW1lclRhc2sucnVuKCkgbWV0aG9kIHNob3VsZCBoYXZlIGJlZW4gY2FsbGVkIGF0IGxlYXN0IHR3aWNlICgiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyB0ZXN0VGFzay53YXNSdW4oKSArICIpIiwgdGVzdFRhc2sud2FzUnVuKCkgPj0gMik7CisgICAgICAgICAgICB0LmNhbmNlbCgpOworCisgICAgICAgICAgICBjbGFzcyBTbG93VGhlbkZhc3RUYXNrIGV4dGVuZHMgVGltZXJUYXNrIHsKKyAgICAgICAgICAgICAgICBpbnQgd2FzUnVuID0gMDsKKworICAgICAgICAgICAgICAgIGxvbmcgc3RhcnRlZEF0OworCisgICAgICAgICAgICAgICAgbG9uZyBsYXN0RGVsdGE7CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICh3YXNSdW4gPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0ZWRBdCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICAgICAgICAgICAgICBsYXN0RGVsdGEgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gKHN0YXJ0ZWRBdCArICgxMDAgKiB3YXNSdW4pKTsKKyAgICAgICAgICAgICAgICAgICAgd2FzUnVuKys7CisgICAgICAgICAgICAgICAgICAgIGlmICh3YXNSdW4gPT0gMikgeworICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMjAwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHB1YmxpYyBsb25nIGxhc3REZWx0YSgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxhc3REZWx0YTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBwdWJsaWMgaW50IHdhc1J1bigpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdhc1J1bjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIEVuc3VyZSBtdWx0aXBsZSB0YXNrcyBhcmUgcnVuCisgICAgICAgICAgICB0ID0gbmV3IFRpbWVyKCk7CisgICAgICAgICAgICBTbG93VGhlbkZhc3RUYXNrIHNsb3dUaGVuRmFzdFRhc2sgPSBuZXcgU2xvd1RoZW5GYXN0VGFzaygpOworICAgICAgICAgICAgZCA9IG5ldyBEYXRlKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpICsgMTAwKTsKKworICAgICAgICAgICAgLy8gYXQgbGVhc3QgOSB0aW1lcyBldmVuIHdoZW4gYXNsZWVwCisgICAgICAgICAgICB0LnNjaGVkdWxlQXRGaXhlZFJhdGUoc2xvd1RoZW5GYXN0VGFzaywgZCwgMTAwKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgbG9uZyBsYXN0RGVsdGEgPSBzbG93VGhlbkZhc3RUYXNrLmxhc3REZWx0YSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRml4ZWQgUmF0ZSBTY2hlZHVsZSBzaG91bGQgY2F0Y2ggdXAsIGJ1dCBpcyBvZmYgYnkgIgorICAgICAgICAgICAgICAgICAgICArIGxhc3REZWx0YSArICIgbXMiLCBsYXN0RGVsdGEgPCAzMDApOworICAgICAgICAgICAgdC5jYW5jZWwoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICh0ICE9IG51bGwpCisgICAgICAgICAgICAgICAgdC5jYW5jZWwoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdlIHVzZWQgdG8gc3dhbGxvdyBSdW50aW1lRXhjZXB0aW9ucyB0aHJvd24gYnkgdGFza3MuIEluc3RlYWQsIHdlIG5lZWQgdG8KKyAgICAgKiBsZXQgdGhvc2UgZXhjZXB0aW9ucyBidWJibGUgdXAsIHdoZXJlIHRoZXkgd2lsbCBib3RoIG5vdGlmeSB0aGUgdGhyZWFkJ3MKKyAgICAgKiB1bmNhdWdodCBleGNlcHRpb24gaGFuZGxlciBhbmQgdGVybWluYXRlIHRoZSB0aW1lcidzIHRocmVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VGhyb3dpbmdUYXNrS2lsbHNUaW1lclRocmVhZCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIEF0b21pY1JlZmVyZW5jZTxUaHJlYWQ+IHRocmVhZFJlZiA9IG5ldyBBdG9taWNSZWZlcmVuY2U8VGhyZWFkPigpOworICAgICAgICBuZXcgVGltZXIoKS5zY2hlZHVsZShuZXcgVGltZXJUYXNrKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLnNldFVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlcihuZXcgVW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyKCkgeworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCB1bmNhdWdodEV4Y2VwdGlvbihUaHJlYWQgdGhyZWFkLCBUaHJvd2FibGUgZXgpIHt9CisgICAgICAgICAgICAgICAgfSk7CisgICAgICAgICAgICAgICAgdGhyZWFkUmVmLnNldChUaHJlYWQuY3VycmVudFRocmVhZCgpKTsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigidGFzayBmYWlsdXJlISIpOworICAgICAgICAgICAgfQorICAgICAgICB9LCAxKTsKKworICAgICAgICBUaHJlYWQuc2xlZXAoNDAwKTsKKyAgICAgICAgVGhyZWFkIHRpbWVyVGhyZWFkID0gdGhyZWFkUmVmLmdldCgpOworICAgICAgICBhc3NlcnRGYWxzZSh0aW1lclRocmVhZC5pc0FsaXZlKCkpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICB0aW1lckNvdW50ZXIgPSAwOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgeworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL1Rvb01hbnlMaXN0ZW5lcnNFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9Ub29NYW55TGlzdGVuZXJzRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ4ZGY1ZmQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9Ub29NYW55TGlzdGVuZXJzRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5Ub29NYW55TGlzdGVuZXJzRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgVG9vTWFueUxpc3RlbmVyc0V4Y2VwdGlvblRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlRvb01hbnlMaXN0ZW5lcnNFeGNlcHRpb24jVG9vTWFueUxpc3RlbmVyc0V4Y2VwdGlvbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5Ub29NYW55TGlzdGVuZXJzRXhjZXB0aW9uKCkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRocm93IG5ldyBUb29NYW55TGlzdGVuZXJzRXhjZXB0aW9uKCk7CisgICAgICAgIH0gY2F0Y2ggKFRvb01hbnlMaXN0ZW5lcnNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbCgKKyAgICAgICAgICAgICAgICAgICAgIk1lc3NhZ2UgdGhyb3duIHdpdGggZXhjZXB0aW9uIGNvbnN0cnVjdGVkIHdpdGggbm8gbWVzc2FnZSIsCisgICAgICAgICAgICAgICAgICAgIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5Ub29NYW55TGlzdGVuZXJzRXhjZXB0aW9uI1Rvb01hbnlMaXN0ZW5lcnNFeGNlcHRpb24oamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuVG9vTWFueUxpc3RlbmVyc0V4Y2VwdGlvbihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFRvb01hbnlMaXN0ZW5lcnNFeGNlcHRpb24oIkdhaCIpOworICAgICAgICB9IGNhdGNoIChUb29NYW55TGlzdGVuZXJzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IG1lc3NhZ2UgdGhyb3duIHdpdGggZXhjZXB0aW9uIiwgIkdhaCIsIGUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWFycyBkb3duIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgY2xvc2UgYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMKKyAgICAgKiBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9WZWN0b3JUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9WZWN0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjIyOGNiMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL1ZlY3RvclRlc3QuamF2YQpAQCAtMCwwICsxLDExOTggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworCitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0xpc3RUZXN0OworCitwdWJsaWMgY2xhc3MgVmVjdG9yVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIFZlY3RvciB0VmVjdG9yID0gbmV3IFZlY3RvcigpOworCisgICAgT2JqZWN0W10gb2JqQXJyYXk7CisKKyAgICBwcml2YXRlIFN0cmluZyB2U3RyaW5nID0gIltUZXN0IDAsIFRlc3QgMSwgVGVzdCAyLCBUZXN0IDMsIFRlc3QgNCwgVGVzdCA1LCBUZXN0IDYsIFRlc3QgNywgVGVzdCA4LCBUZXN0IDksIFRlc3QgMTAsIFRlc3QgMTEsIFRlc3QgMTIsIFRlc3QgMTMsIFRlc3QgMTQsIFRlc3QgMTUsIFRlc3QgMTYsIFRlc3QgMTcsIFRlc3QgMTgsIFRlc3QgMTksIFRlc3QgMjAsIFRlc3QgMjEsIFRlc3QgMjIsIFRlc3QgMjMsIFRlc3QgMjQsIFRlc3QgMjUsIFRlc3QgMjYsIFRlc3QgMjcsIFRlc3QgMjgsIFRlc3QgMjksIFRlc3QgMzAsIFRlc3QgMzEsIFRlc3QgMzIsIFRlc3QgMzMsIFRlc3QgMzQsIFRlc3QgMzUsIFRlc3QgMzYsIFRlc3QgMzcsIFRlc3QgMzgsIFRlc3QgMzksIFRlc3QgNDAsIFRlc3QgNDEsIFRlc3QgNDIsIFRlc3QgNDMsIFRlc3QgNDQsIFRlc3QgNDUsIFRlc3QgNDYsIFRlc3QgNDcsIFRlc3QgNDgsIFRlc3QgNDksIFRlc3QgNTAsIFRlc3QgNTEsIFRlc3QgNTIsIFRlc3QgNTMsIFRlc3QgNTQsIFRlc3QgNTUsIFRlc3QgNTYsIFRlc3QgNTcsIFRlc3QgNTgsIFRlc3QgNTksIFRlc3QgNjAsIFRlc3QgNjEsIFRlc3QgNjIsIFRlc3QgNjMsIFRlc3QgNjQsIFRlc3QgNjUsIFRlc3QgNjYsIFRlc3QgNjcsIFRlc3QgNjgsIFRlc3QgNjksIFRlc3QgNzAsIFRlc3QgNzEsIFRlc3QgNzIsIFRlc3QgNzMsIFRlc3QgNzQsIFRlc3QgNzUsIFRlc3QgNzYsIFRlc3QgNzcsIFRlc3QgNzgsIFRlc3QgNzksIFRlc3QgODAsIFRlc3QgODEsIFRlc3QgODIsIFRlc3QgODMsIFRlc3QgODQsIFRlc3QgODUsIFRlc3QgODYsIFRlc3QgODcsIFRlc3QgODgsIFRlc3QgODksIFRlc3QgOTAsIFRlc3QgOTEsIFRlc3QgOTIsIFRlc3QgOTMsIFRlc3QgOTQsIFRlc3QgOTUsIFRlc3QgOTYsIFRlc3QgOTcsIFRlc3QgOTgsIFRlc3QgOTldIjsKKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5WZWN0b3IjVmVjdG9yKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlZlY3RvcigpCisKKyAgICAgICAgVmVjdG9yIHR2ID0gbmV3IFZlY3RvcigxMDApOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKQorICAgICAgICAgICAgdHYuYWRkRWxlbWVudChuZXcgSW50ZWdlcihpKSk7CisgICAgICAgIG5ldyBTdXBwb3J0X0xpc3RUZXN0KCIiLCB0dikucnVuVGVzdCgpOworCisgICAgICAgIHR2ID0gbmV3IFZlY3RvcigyMDApOworICAgICAgICBmb3IgKGludCBpID0gLTUwOyBpIDwgMTUwOyBpKyspCisgICAgICAgICAgICB0di5hZGRFbGVtZW50KG5ldyBJbnRlZ2VyKGkpKTsKKyAgICAgICAgbmV3IFN1cHBvcnRfTGlzdFRlc3QoIiIsIHR2LnN1Ykxpc3QoNTAsIDE1MCkpLnJ1blRlc3QoKTsKKworICAgICAgICBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJWZWN0b3IgY3JlYXRpb24gZmFpbGVkIiwgMCwgdi5zaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGNhcGFjaXR5IiwgMTAsIHYuY2FwYWNpdHkoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlZlY3RvciNWZWN0b3IoaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlZlY3RvcihpbnQpCisKKyAgICAgICAgVmVjdG9yIHYgPSBuZXcgVmVjdG9yKDEwMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVmVjdG9yIGNyZWF0aW9uIGZhaWxlZCIsIDAsIHYuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBjYXBhY2l0eSIsIDEwMCwgdi5jYXBhY2l0eSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFZlY3RvcigtMSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5WZWN0b3IjVmVjdG9yKGludCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JJSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5WZWN0b3IoaW50LCBpbnQpCisKKyAgICAgICAgVmVjdG9yIHYgPSBuZXcgVmVjdG9yKDIsIDEwKTsKKyAgICAgICAgdi5hZGRFbGVtZW50KG5ldyBPYmplY3QoKSk7CisgICAgICAgIHYuYWRkRWxlbWVudChuZXcgT2JqZWN0KCkpOworICAgICAgICB2LmFkZEVsZW1lbnQobmV3IE9iamVjdCgpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCB0byBpbmMgY2FwYWNpdHkgYnkgcHJvcGVyIGFtb3VudCIsCisgICAgICAgICAgICAgICAgMTIsIHYuY2FwYWNpdHkoKSk7CisKKyAgICAgICAgVmVjdG9yIGdyb3cgPSBuZXcgVmVjdG9yKDMsIC0xKTsKKyAgICAgICAgZ3Jvdy5hZGRFbGVtZW50KCJvbmUiKTsKKyAgICAgICAgZ3Jvdy5hZGRFbGVtZW50KCJ0d28iKTsKKyAgICAgICAgZ3Jvdy5hZGRFbGVtZW50KCJ0aHJlZSIpOworICAgICAgICBncm93LmFkZEVsZW1lbnQoImZvdXIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzaXplIiwgNCwgZ3Jvdy5zaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGNhcGFjaXR5IiwgNiwgZ3Jvdy5jYXBhY2l0eSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFZlY3RvcigtMSwgMSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5WZWN0b3IjVmVjdG9yKGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV91dGlsX0NvbGxlY3Rpb24oKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuVmVjdG9yKGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAgICBDb2xsZWN0aW9uIGwgPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKQorICAgICAgICAgICAgbC5hZGQoIlRlc3QgIiArIGkpOworICAgICAgICBWZWN0b3IgbXlWZWN0b3IgPSBuZXcgVmVjdG9yKGwpOworICAgICAgICBhc3NlcnRUcnVlKCJWZWN0b3IgaXMgbm90IGNvcnJlY3Qgc2l6ZSIsCisgICAgICAgICAgICAgICAgbXlWZWN0b3Iuc2l6ZSgpID09IG9iakFycmF5Lmxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgb2JqQXJyYXkubGVuZ3RoOyBjb3VudGVyKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJWZWN0b3IgZG9lcyBub3QgY29udGFpbiBjb3JyZWN0IGVsZW1lbnRzIiwgbXlWZWN0b3IKKyAgICAgICAgICAgICAgICAgICAgLmNvbnRhaW5zKCgoTGlzdCkgbCkuZ2V0KGNvdW50ZXIpKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBWZWN0b3IobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2FkZChpbnQsIGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRJTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5WZWN0b3IuYWRkKGludCwgamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgT2JqZWN0IG8gPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIE9iamVjdCBwcmV2ID0gdFZlY3Rvci5nZXQoNDUpOworICAgICAgICB0VmVjdG9yLmFkZCg0NSwgbyk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBhZGQgT2JqZWN0IiwgdFZlY3Rvci5nZXQoNDUpID09IG8pOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZml4LXVwIGV4aXN0aW5nIGluZGljZXMiLCB0VmVjdG9yLmdldCg0NikgPT0gcHJldik7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSBhZnRlciBhZGQiLCAxMDEsIHRWZWN0b3Iuc2l6ZSgpKTsKKworICAgICAgICBwcmV2ID0gdFZlY3Rvci5nZXQoNTApOworICAgICAgICB0VmVjdG9yLmFkZCg1MCwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoIkZhaWxlZCB0byBhZGQgbnVsbCIsIHRWZWN0b3IuZ2V0KDUwKSk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBmaXgtdXAgZXhpc3RpbmcgaW5kaWNlcyBhZnRlciBhZGRpbmcgbnVsbCIsCisgICAgICAgICAgICAgICAgdFZlY3Rvci5nZXQoNTEpID09IHByZXYpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHNpemUgYWZ0ZXIgYWRkIiwgMTAyLCB0VmVjdG9yLnNpemUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3IuYWRkKC01LCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdFZlY3Rvci5hZGQodFZlY3Rvci5zaXplKCkgKyAxLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2FkZChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEudXRpbC5WZWN0b3IuYWRkKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIE9iamVjdCBvID0gbmV3IE9iamVjdCgpOworICAgICAgICB0VmVjdG9yLmFkZChvKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGFkZCBPYmplY3QiLCB0VmVjdG9yLmxhc3RFbGVtZW50KCkgPT0gbyk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc2l6ZSBhZnRlciBhZGQiLCAxMDEsIHRWZWN0b3Iuc2l6ZSgpKTsKKworICAgICAgICB0VmVjdG9yLmFkZChudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIGFkZCBudWxsIiwgdFZlY3Rvci5sYXN0RWxlbWVudCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzaXplIGFmdGVyIGFkZCIsIDEwMiwgdFZlY3Rvci5zaXplKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5WZWN0b3IjYWRkQWxsKGludCwgamF2YS51dGlsLkNvbGxlY3Rpb24pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRBbGxJTGphdmFfdXRpbF9Db2xsZWN0aW9uKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuVmVjdG9yLmFkZEFsbChpbnQsCisgICAgICAgIC8vIGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAgICBDb2xsZWN0aW9uIGwgPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKQorICAgICAgICAgICAgbC5hZGQoIlRlc3QgIiArIGkpOworICAgICAgICBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoKTsKKyAgICAgICAgdFZlY3Rvci5hZGRBbGwoNTAsIGwpOworICAgICAgICBmb3IgKGludCBpID0gNTA7IGkgPCAxMDA7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBhZGQgYWxsIGVsZW1lbnRzIiwKKyAgICAgICAgICAgICAgICAgICAgdFZlY3Rvci5nZXQoaSkgPT0gKChMaXN0KSBsKS5nZXQoaSAtIDUwKSk7CisgICAgICAgIHYgPSBuZXcgVmVjdG9yKCk7CisgICAgICAgIHYuYWRkKCJvbmUiKTsKKyAgICAgICAgaW50IHIgPSAwOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdi5hZGRBbGwoMywgQXJyYXlzLmFzTGlzdChuZXcgU3RyaW5nW10geyAidHdvIiwgInRocmVlIiB9KSk7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByID0gMTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByID0gMjsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJJbnZhbGlkIGFkZDogIiArIHIsIHIgPT0gMSk7CisgICAgICAgIGwgPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICBsLmFkZChudWxsKTsKKyAgICAgICAgbC5hZGQoImdhaCIpOworICAgICAgICBsLmFkZChudWxsKTsKKyAgICAgICAgdFZlY3Rvci5hZGRBbGwoNTAsIGwpOworICAgICAgICBhc3NlcnROdWxsKCJXcm9uZyBlbGVtZW50IGF0IHBvc2l0aW9uIDUwLS13YW50ZWQgbnVsbCIsCisgICAgICAgICAgICAgICAgdFZlY3Rvci5nZXQoNTApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBlbGVtZW50IGF0IHBvc2l0aW9uIDUxLS13YW50ZWQgJ2dhaCciLCAiZ2FoIiwgdFZlY3RvcgorICAgICAgICAgICAgICAgIC5nZXQoNTEpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiV3JvbmcgZWxlbWVudCBhdCBwb3NpdGlvbiA1Mi0td2FudGVkIG51bGwiLAorICAgICAgICAgICAgICAgIHRWZWN0b3IuZ2V0KDUyKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3IuYWRkQWxsKC01LCBBcnJheXMuYXNMaXN0KG5ldyBTdHJpbmdbXSB7ICJ0d28iLCAidGhyZWUiIH0pKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdFZlY3Rvci5hZGRBbGwodFZlY3Rvci5zaXplKCkgKyAxLCBBcnJheXMuYXNMaXN0KG5ldyBTdHJpbmdbXSB7ICJ0d28iLCAidGhyZWUiIH0pKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdFZlY3Rvci5hZGRBbGwodFZlY3Rvci5zaXplKCkgLyAyLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlZlY3RvciNhZGRBbGwoamF2YS51dGlsLkNvbGxlY3Rpb24pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRBbGxMamF2YV91dGlsX0NvbGxlY3Rpb24oKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEudXRpbC5WZWN0b3IuYWRkQWxsKGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAgICBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoKTsKKyAgICAgICAgQ29sbGVjdGlvbiBsID0gbmV3IExpbmtlZExpc3QoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykKKyAgICAgICAgICAgIGwuYWRkKCJUZXN0ICIgKyBpKTsKKyAgICAgICAgdi5hZGRBbGwobCk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBhZGQgYWxsIGVsZW1lbnRzIiwgdFZlY3Rvci5lcXVhbHModikpOworCisgICAgICAgIHYuYWRkQWxsKGwpOworICAgICAgICBpbnQgdlNpemUgPSB0VmVjdG9yLnNpemUoKTsKKyAgICAgICAgZm9yIChpbnQgY291bnRlciA9IHZTaXplIC0gMTsgY291bnRlciA+PSAwOyBjb3VudGVyLS0pCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gYWRkIGVsZW1lbnRzIGNvcnJlY3RseSIsIHYuZ2V0KGNvdW50ZXIpID09IHYKKyAgICAgICAgICAgICAgICAgICAgLmdldChjb3VudGVyICsgdlNpemUpKTsKKworICAgICAgICBsID0gbmV3IExpbmtlZExpc3QoKTsKKyAgICAgICAgbC5hZGQobnVsbCk7CisgICAgICAgIGwuYWRkKCJnYWgiKTsKKyAgICAgICAgbC5hZGQobnVsbCk7CisgICAgICAgIHRWZWN0b3IuYWRkQWxsKGwpOworICAgICAgICBhc3NlcnROdWxsKCJXcm9uZyBlbGVtZW50IGF0IDNyZCBsYXN0IHBvc2l0aW9uLS13YW50ZWQgbnVsbCIsIHRWZWN0b3IKKyAgICAgICAgICAgICAgICAuZ2V0KHZTaXplKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgZWxlbWVudCBhdCAybmQgbGFzdCBwb3NpdGlvbi0td2FudGVkICdnYWgnIiwgImdhaCIsIHRWZWN0b3IKKyAgICAgICAgICAgICAgICAuZ2V0KHZTaXplICsgMSkpOworICAgICAgICBhc3NlcnROdWxsKCJXcm9uZyBlbGVtZW50IGF0IGxhc3QgcG9zaXRpb24tLXdhbnRlZCBudWxsIiwgdFZlY3RvcgorICAgICAgICAgICAgICAgIC5nZXQodlNpemUgKyAyKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3IuYWRkQWxsKHRWZWN0b3Iuc2l6ZSgpIC8gMiwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5WZWN0b3IjYWRkRWxlbWVudChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkRWxlbWVudExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuVmVjdG9yLmFkZEVsZW1lbnQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgVmVjdG9yIHYgPSB2ZWN0b3JDbG9uZSh0VmVjdG9yKTsKKyAgICAgICAgdi5hZGRFbGVtZW50KCJBZGRlZCBFbGVtZW50Iik7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBhZGQgZWxlbWVudCIsIHYuY29udGFpbnMoIkFkZGVkIEVsZW1lbnQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQWRkZWQgRWxlbWVudCB0byB3cm9uZyBzbG90IiwgIkFkZGVkIEVsZW1lbnQiLCAoKFN0cmluZykgdi5lbGVtZW50QXQoMTAwKSkKKyAgICAgICAgICAgICAgICApOworICAgICAgICB2LmFkZEVsZW1lbnQobnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBhZGQgbnVsbCIsIHYuY29udGFpbnMobnVsbCkpOworICAgICAgICBhc3NlcnROdWxsKCJBZGRlZCBudWxsIHRvIHdyb25nIHNsb3QiLCB2LmVsZW1lbnRBdCgxMDEpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2FkZEVsZW1lbnQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZEVsZW1lbnRMamF2YV9sYW5nX09iamVjdF9zdWJ0ZXN0MCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLlZlY3Rvci5hZGRFbGVtZW50KGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIFZlY3RvciB2ID0gdmVjdG9yQ2xvbmUodFZlY3Rvcik7CisgICAgICAgIHYuYWRkRWxlbWVudCgiQWRkZWQgRWxlbWVudCIpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gYWRkIGVsZW1lbnQiLCB2LmNvbnRhaW5zKCJBZGRlZCBFbGVtZW50IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkFkZGVkIEVsZW1lbnQgdG8gd3Jvbmcgc2xvdCIsICJBZGRlZCBFbGVtZW50IiwgKChTdHJpbmcpIHYuZWxlbWVudEF0KDEwMCkpCisgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgdi5hZGRFbGVtZW50KG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gYWRkIG51bGwiLCB2LmNvbnRhaW5zKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiQWRkZWQgbnVsbCB0byB3cm9uZyBzbG90Iiwgdi5lbGVtZW50QXQoMTAxKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlZlY3RvciNjYXBhY2l0eSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jYXBhY2l0eSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuVmVjdG9yLmNhcGFjaXR5KCkKKworICAgICAgICBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoOSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGNhcGFjaXR5IHJldHVybmVkIiwgOSwgdi5jYXBhY2l0eSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2NsZWFyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NsZWFyKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuVmVjdG9yLmNsZWFyKCkKKyAgICAgICAgVmVjdG9yIG9yZ1ZlY3RvciA9IHZlY3RvckNsb25lKHRWZWN0b3IpOworICAgICAgICB0VmVjdG9yLmNsZWFyKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiYSkgQ2xlYXJlZCBWZWN0b3IgaGFzIG5vbi16ZXJvIHNpemUiLCAwLCB0VmVjdG9yLnNpemUoKSk7CisgICAgICAgIEVudW1lcmF0aW9uIGUgPSBvcmdWZWN0b3IuZWxlbWVudHMoKTsKKyAgICAgICAgd2hpbGUgKGUuaGFzTW9yZUVsZW1lbnRzKCkpCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJhKSBDbGVhcmVkIHZlY3RvciBjb250YWluZWQgZWxlbWVudHMiLCAhdFZlY3RvcgorICAgICAgICAgICAgICAgICAgICAuY29udGFpbnMoZS5uZXh0RWxlbWVudCgpKSk7CisKKyAgICAgICAgdFZlY3Rvci5hZGQobnVsbCk7CisgICAgICAgIHRWZWN0b3IuY2xlYXIoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJiKSBDbGVhcmVkIFZlY3RvciBoYXMgbm9uLXplcm8gc2l6ZSIsIDAsIHRWZWN0b3Iuc2l6ZSgpKTsKKyAgICAgICAgZSA9IG9yZ1ZlY3Rvci5lbGVtZW50cygpOworICAgICAgICB3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkKKyAgICAgICAgICAgIGFzc2VydFRydWUoImIpIENsZWFyZWQgdmVjdG9yIGNvbnRhaW5lZCBlbGVtZW50cyIsICF0VmVjdG9yCisgICAgICAgICAgICAgICAgICAgIC5jb250YWlucyhlLm5leHRFbGVtZW50KCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2Nsb25lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb25lKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdCBqYXZhLnV0aWwuVmVjdG9yLmNsb25lKCkKKyAgICAgICAgdFZlY3Rvci5hZGQoMjUsIG51bGwpOworICAgICAgICB0VmVjdG9yLmFkZCg3NSwgbnVsbCk7CisgICAgICAgIFZlY3RvciB2ID0gKFZlY3RvcikgdFZlY3Rvci5jbG9uZSgpOworICAgICAgICBFbnVtZXJhdGlvbiBvcmdOdW0gPSB0VmVjdG9yLmVsZW1lbnRzKCk7CisgICAgICAgIEVudW1lcmF0aW9uIGNudW0gPSB2LmVsZW1lbnRzKCk7CisKKyAgICAgICAgd2hpbGUgKG9yZ051bS5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTm90IGVub3VnaCBlbGVtZW50cyBjb3BpZWQiLCBjbnVtLmhhc01vcmVFbGVtZW50cygpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlZlY3RvciBjbG9uZWQgaW1wcm9wZXJseSwgZWxlbWVudHMgZG8gbm90IG1hdGNoIiwKKyAgICAgICAgICAgICAgICAgICAgb3JnTnVtLm5leHRFbGVtZW50KCkgPT0gY251bS5uZXh0RWxlbWVudCgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJOb3QgZW5vdWdoIGVsZW1lbnRzIGNvcGllZCIsICFjbnVtLmhhc01vcmVFbGVtZW50cygpKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5WZWN0b3IjY29udGFpbnMoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbnRhaW5zTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEudXRpbC5WZWN0b3IuY29udGFpbnMoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRGlkIG5vdCBmaW5kIGVsZW1lbnQiLCB0VmVjdG9yLmNvbnRhaW5zKCJUZXN0IDQyIikpOworICAgICAgICBhc3NlcnRUcnVlKCJGb3VuZCBib2d1cyBlbGVtZW50IiwgIXRWZWN0b3IuY29udGFpbnMoIkhlbGxvIikpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJSZXR1cm5lZCB0cnVlIGxvb2tpbmcgZm9yIG51bGwgaW4gdmVjdG9yIHdpdGhvdXQgbnVsbCBlbGVtZW50IiwKKyAgICAgICAgICAgICAgICAhdFZlY3Rvci5jb250YWlucyhudWxsKSk7CisgICAgICAgIHRWZWN0b3IuaW5zZXJ0RWxlbWVudEF0KG51bGwsIDIwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiUmV0dXJuZWQgZmFsc2UgbG9va2luZyBmb3IgbnVsbCBpbiB2ZWN0b3Igd2l0aCBudWxsIGVsZW1lbnQiLAorICAgICAgICAgICAgICAgIHRWZWN0b3IuY29udGFpbnMobnVsbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5WZWN0b3IjY29udGFpbnNBbGwoamF2YS51dGlsLkNvbGxlY3Rpb24pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jb250YWluc0FsbExqYXZhX3V0aWxfQ29sbGVjdGlvbigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4KKyAgICAgICAgLy8gamF2YS51dGlsLlZlY3Rvci5jb250YWluc0FsbChqYXZhLnV0aWwuQ29sbGVjdGlvbikKKyAgICAgICAgQ29sbGVjdGlvbiBzID0gbmV3IEhhc2hTZXQoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykKKyAgICAgICAgICAgIHMuYWRkKCJUZXN0ICIgKyBpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCBmYWxzZSBmb3IgdmFsaWQgY29sbGVjdGlvbiIsIHRWZWN0b3IKKyAgICAgICAgICAgICAgICAuY29udGFpbnNBbGwocykpOworICAgICAgICBzLmFkZChudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgdHJ1ZSBmb3IgaW52bGFpZCBjb2xsZWN0aW9uIGNvbnRhaW5pbmcgbnVsbCIsCisgICAgICAgICAgICAgICAgIXRWZWN0b3IuY29udGFpbnNBbGwocykpOworICAgICAgICB0VmVjdG9yLmFkZCgyNSwgbnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGZhbHNlIGZvciB2YWxpZCBjb2xsZWN0aW9uIGNvbnRhaW5pbmcgbnVsbCIsCisgICAgICAgICAgICAgICAgdFZlY3Rvci5jb250YWluc0FsbChzKSk7CisgICAgICAgIHMgPSBuZXcgSGFzaFNldCgpOworICAgICAgICBzLmFkZChuZXcgT2JqZWN0KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXR1cm5lZCB0cnVlIGZvciBpbnZhbGlkIGNvbGxlY3Rpb24iLCAhdFZlY3RvcgorICAgICAgICAgICAgICAgIC5jb250YWluc0FsbChzKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3IuY29udGFpbnNBbGwobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2NvcHlJbnRvKGphdmEubGFuZy5PYmplY3RbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvcHlJbnRvJExqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuVmVjdG9yLmNvcHlJbnRvKGphdmEubGFuZy5PYmplY3QgW10pCisKKyAgICAgICAgT2JqZWN0W10gYSA9IG5ldyBPYmplY3RbMTAwXTsKKyAgICAgICAgdFZlY3Rvci5zZXRFbGVtZW50QXQobnVsbCwgMjApOworICAgICAgICB0VmVjdG9yLmNvcHlJbnRvKGEpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJjb3B5SW50byBmYWlsZWQiLCBhW2ldID09IHRWZWN0b3IuZWxlbWVudEF0KGkpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdFZlY3Rvci5jb3B5SW50byhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5WZWN0b3IjZWxlbWVudEF0KGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VsZW1lbnRBdEkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IGphdmEudXRpbC5WZWN0b3IuZWxlbWVudEF0KGludCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgZWxlbWVudCByZXR1cm5lZCIsICJUZXN0IDE4IiwgKChTdHJpbmcpIHRWZWN0b3IKKyAgICAgICAgICAgICAgICAuZWxlbWVudEF0KDE4KSkpOworICAgICAgICB0VmVjdG9yLnNldEVsZW1lbnRBdChudWxsLCAyMCk7CisgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCBlbGVtZW50IHJldHVybmVkLS13YW50ZWQgbnVsbCIsIHRWZWN0b3IKKyAgICAgICAgICAgICAgICAuZWxlbWVudEF0KDIwKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3IuZWxlbWVudEF0KC01KTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdFZlY3Rvci5lbGVtZW50QXQodFZlY3Rvci5zaXplKCkgKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2VsZW1lbnRzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VsZW1lbnRzKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLkVudW1lcmF0aW9uIGphdmEudXRpbC5WZWN0b3IuZWxlbWVudHMoKQorICAgICAgICB0VmVjdG9yLmluc2VydEVsZW1lbnRBdChudWxsLCAyMCk7CisgICAgICAgIEVudW1lcmF0aW9uIGUgPSB0VmVjdG9yLmVsZW1lbnRzKCk7CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgd2hpbGUgKGUuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkVudW1lcmF0aW9uIHJldHVybmVkIGluY29ycmVjdCBlbGVtZW50IGF0IHBvczogIiArIGksIGUKKyAgICAgICAgICAgICAgICAgICAgLm5leHRFbGVtZW50KCkgPT0gdFZlY3Rvci5lbGVtZW50QXQoaSkpOworICAgICAgICAgICAgaSsrOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkludmFsaWQgZW51bWVyYXRpb24iLCBpID09IHRWZWN0b3Iuc2l6ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2VsZW1lbnRzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VsZW1lbnRzX3N1YnRlc3QwKCkgeworICAgICAgICBmaW5hbCBpbnQgaXRlcmF0aW9ucyA9IDEwMDAwOworICAgICAgICBmaW5hbCBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoKTsKKyAgICAgICAgVGhyZWFkIHQxID0gbmV3IFRocmVhZCgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGl0ZXJhdGlvbnM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHYpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHYuYWRkRWxlbWVudChTdHJpbmcudmFsdWVPZihpKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB2LnJlbW92ZUVsZW1lbnRBdCgwKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgdDEuc3RhcnQoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpdGVyYXRpb25zOyBpKyspIHsKKyAgICAgICAgICAgIEVudW1lcmF0aW9uIGVuID0gdi5lbGVtZW50cygpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgICAgICBPYmplY3QgcmVzdWx0ID0gZW4ubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKCJOdWxsIHJlc3VsdDogIiArIGkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2Vuc3VyZUNhcGFjaXR5KGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Vuc3VyZUNhcGFjaXR5SSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIHZvaWQgamF2YS51dGlsLlZlY3Rvci5lbnN1cmVDYXBhY2l0eShpbnQpCisKKyAgICAgICAgVmVjdG9yIHYgPSBuZXcgVmVjdG9yKDkpOworICAgICAgICB2LmVuc3VyZUNhcGFjaXR5KDIwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbnN1cmVDYXBhY2l0eSBmYWlsZWQgdG8gc2V0IGNvcnJlY3QgY2FwYWNpdHkiLCAyMCwgdgorICAgICAgICAgICAgICAgIC5jYXBhY2l0eSgpKTsKKyAgICAgICAgdiA9IG5ldyBWZWN0b3IoMTAwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbnN1cmVDYXBhY2l0eSByZWR1Y2VkIGNhcGFjaXR5IiwgMTAwLCB2LmNhcGFjaXR5KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5WZWN0b3IjZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9lcXVhbHNMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4gamF2YS51dGlsLlZlY3Rvci5lcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgVmVjdG9yIHYgPSBuZXcgVmVjdG9yKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspCisgICAgICAgICAgICB2LmFkZEVsZW1lbnQoIlRlc3QgIiArIGkpOworICAgICAgICBhc3NlcnRUcnVlKCJhKSBFcXVhbCB2ZWN0b3JzIHJldHVybmVkIGZhbHNlIiwgdFZlY3Rvci5lcXVhbHModikpOworICAgICAgICB2LmFkZEVsZW1lbnQobnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoImIpIFVuRXF1YWwgdmVjdG9ycyByZXR1cm5lZCB0cnVlIiwgIXRWZWN0b3IuZXF1YWxzKHYpKTsKKyAgICAgICAgdFZlY3Rvci5hZGRFbGVtZW50KG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJjKSBFcXVhbCB2ZWN0b3JzIHJldHVybmVkIGZhbHNlIiwgdFZlY3Rvci5lcXVhbHModikpOworICAgICAgICB0VmVjdG9yLnJlbW92ZUVsZW1lbnRBdCgyMik7CisgICAgICAgIGFzc2VydFRydWUoImQpIFVuRXF1YWwgdmVjdG9ycyByZXR1cm5lZCB0cnVlIiwgIXRWZWN0b3IuZXF1YWxzKHYpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2ZpcnN0RWxlbWVudCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9maXJzdEVsZW1lbnQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IGphdmEudXRpbC5WZWN0b3IuZmlyc3RFbGVtZW50KCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3QgZmlyc3RFbGVtZW50IiwgIlRlc3QgMCIsIHRWZWN0b3IuZmlyc3RFbGVtZW50KCkKKyAgICAgICAgICAgICAgICApOworICAgICAgICB0VmVjdG9yLmluc2VydEVsZW1lbnRBdChudWxsLCAwKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiUmV0dXJuZWQgaW5jb3JyZWN0IGZpcnN0RWxlbWVudC0td2FudGVkIG51bGwiLCB0VmVjdG9yCisgICAgICAgICAgICAgICAgLmZpcnN0RWxlbWVudCgpKTsKKworICAgICAgICB0VmVjdG9yID0gbmV3IFZlY3RvcigxMCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3IuZmlyc3RFbGVtZW50KCk7CisgICAgICAgICAgICBmYWlsKCJOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlZlY3RvciNnZXQoaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QgamF2YS51dGlsLlZlY3Rvci5nZXQoaW50KQorICAgICAgICBhc3NlcnRFcXVhbHMoIkdldCByZXR1cm5lZCBpbmNvcnJlY3Qgb2JqZWN0IiwKKyAgICAgICAgICAgICAgICAiVGVzdCA4MCIsIHRWZWN0b3IuZ2V0KDgwKSk7CisgICAgICAgIHRWZWN0b3IuYWRkKDI1LCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiUmV0dXJuZWQgaW5jb3JyZWN0IGVsZW1lbnQtLXdhbnRlZCBudWxsIiwKKyAgICAgICAgICAgICAgICB0VmVjdG9yLmdldCgyNSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0VmVjdG9yLmdldCgtNSk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3IuZ2V0KHRWZWN0b3Iuc2l6ZSgpICsgMSk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlZlY3RvciNoYXNoQ29kZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuVmVjdG9yLmhhc2hDb2RlKCkKKyAgICAgICAgaW50IGhhc2hDb2RlID0gMTsgLy8gb25lCisgICAgICAgIHRWZWN0b3IuaW5zZXJ0RWxlbWVudEF0KG51bGwsIDIwKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0VmVjdG9yLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICBPYmplY3Qgb2JqID0gdFZlY3Rvci5lbGVtZW50QXQoaSk7CisgICAgICAgICAgICBoYXNoQ29kZSA9IDMxICogaGFzaENvZGUgKyAob2JqID09IG51bGwgPyAwIDogb2JqLmhhc2hDb2RlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBoYXNoQ29kZSByZXR1cm5lZC4gIFdhbnRlZDogIiArIGhhc2hDb2RlCisgICAgICAgICAgICAgICAgKyAiIGdvdDogIiArIHRWZWN0b3IuaGFzaENvZGUoKSwgdFZlY3Rvci5oYXNoQ29kZSgpID09IGhhc2hDb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2luZGV4T2YoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luZGV4T2ZMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuVmVjdG9yLmluZGV4T2YoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgaW5kZXggcmV0dXJuZWQiLCAxMCwgdFZlY3Rvci5pbmRleE9mKCJUZXN0IDEwIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluZGV4IHJldHVybmVkIGZvciBpbnZhbGlkIE9iamVjdCIsIC0xLCB0VmVjdG9yCisgICAgICAgICAgICAgICAgLmluZGV4T2YoIlhYWFhYWFhYWFhYIikpOworICAgICAgICB0VmVjdG9yLnNldEVsZW1lbnRBdChudWxsLCAyMCk7CisgICAgICAgIHRWZWN0b3Iuc2V0RWxlbWVudEF0KG51bGwsIDQwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGluZGV4T2YgcmV0dXJuZWQgZm9yIG51bGw6ICIKKyAgICAgICAgICAgICAgICArIHRWZWN0b3IuaW5kZXhPZihudWxsKSwgdFZlY3Rvci5pbmRleE9mKG51bGwpID09IDIwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2luZGV4T2YoamF2YS5sYW5nLk9iamVjdCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5kZXhPZkxqYXZhX2xhbmdfT2JqZWN0SSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGludCBqYXZhLnV0aWwuVmVjdG9yLmluZGV4T2YoamF2YS5sYW5nLk9iamVjdCwgaW50KQorICAgICAgICBhc3NlcnRUcnVlKCJGYWlsZWQgdG8gZmluZCBjb3JyZWN0IGluZGV4IiwgKHRWZWN0b3IuaW5kZXhPZigiVGVzdCA5OCIsCisgICAgICAgICAgICAgICAgNTApID09IDk4KSk7CisgICAgICAgIGFzc2VydFRydWUoIkZvdW5kIGluZGV4IG9mIGJvZ3VzIGVsZW1lbnQiLCAodFZlY3Rvci5pbmRleE9mKAorICAgICAgICAgICAgICAgICJUZXN0IDEwMDEiLCA1MCkgPT0gLTEpKTsKKyAgICAgICAgdFZlY3Rvci5zZXRFbGVtZW50QXQobnVsbCwgMjApOworICAgICAgICB0VmVjdG9yLnNldEVsZW1lbnRBdChudWxsLCA0MCk7CisgICAgICAgIHRWZWN0b3Iuc2V0RWxlbWVudEF0KG51bGwsIDYwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiYSkgSW5jb3JyZWN0IGluZGV4T2YgcmV0dXJuZWQgZm9yIG51bGw6ICIKKyAgICAgICAgICAgICAgICArIHRWZWN0b3IuaW5kZXhPZihudWxsLCAyNSksIHRWZWN0b3IuaW5kZXhPZihudWxsLCAyNSkgPT0gNDApOworICAgICAgICBhc3NlcnRUcnVlKCJiKSBJbmNvcnJlY3QgaW5kZXhPZiByZXR1cm5lZCBmb3IgbnVsbDogIgorICAgICAgICAgICAgICAgICsgdFZlY3Rvci5pbmRleE9mKG51bGwsIDIwKSwgdFZlY3Rvci5pbmRleE9mKG51bGwsIDIwKSA9PSAyMCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3IuaW5kZXhPZihudWxsLCAtMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlZlY3RvciNpbnNlcnRFbGVtZW50QXQoamF2YS5sYW5nLk9iamVjdCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5zZXJ0RWxlbWVudEF0TGphdmFfbGFuZ19PYmplY3RJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZAorICAgICAgICAvLyBqYXZhLnV0aWwuVmVjdG9yLmluc2VydEVsZW1lbnRBdChqYXZhLmxhbmcuT2JqZWN0LCBpbnQpCisgICAgICAgIFZlY3RvciB2ID0gdmVjdG9yQ2xvbmUodFZlY3Rvcik7CisgICAgICAgIFN0cmluZyBwcmV2RWxlbWVudCA9IChTdHJpbmcpIHYuZWxlbWVudEF0KDk5KTsKKyAgICAgICAgdi5pbnNlcnRFbGVtZW50QXQoIkluc2VydGVkIEVsZW1lbnQiLCA5OSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRWxlbWVudCBub3QgaW5zZXJ0ZWQiLCAiSW5zZXJ0ZWQgRWxlbWVudCIsICgoU3RyaW5nKSB2LmVsZW1lbnRBdCg5OSkpCisgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRWxlbWVudHMgc2hpZnRlZCBpbmNvcnJlY3RseSIsICgoU3RyaW5nKSB2LmVsZW1lbnRBdCgxMDApKQorICAgICAgICAgICAgICAgIC5lcXVhbHMocHJldkVsZW1lbnQpKTsKKyAgICAgICAgdi5pbnNlcnRFbGVtZW50QXQobnVsbCwgMjApOworICAgICAgICBhc3NlcnROdWxsKCJudWxsIG5vdCBpbnNlcnRlZCIsIHYuZWxlbWVudEF0KDIwKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3IuaW5zZXJ0RWxlbWVudEF0KG51bGwsIC01KTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdFZlY3Rvci5pbnNlcnRFbGVtZW50QXQobnVsbCwgdFZlY3Rvci5zaXplKCkgKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2lzRW1wdHkoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNFbXB0eSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4gamF2YS51dGlsLlZlY3Rvci5pc0VtcHR5KClWZWN0b3IKKyAgICAgICAgVmVjdG9yIHYgPSBuZXcgamF2YS51dGlsLlZlY3RvcigpOworICAgICAgICBhc3NlcnRUcnVlKCJFbXB0eSB2ZWN0b3IgcmV0dXJuZWQgZmFsc2UiLCB2LmlzRW1wdHkoKSk7CisgICAgICAgIHYuYWRkRWxlbWVudChuZXcgT2JqZWN0KCkpOworICAgICAgICBhc3NlcnRUcnVlKCJub24tRW1wdHkgdmVjdG9yIHJldHVybmVkIHRydWUiLCAhdi5pc0VtcHR5KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5WZWN0b3IjaXNFbXB0eSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0VtcHR5X3N1YnRlc3QwKCkgeworICAgICAgICBmaW5hbCBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoKTsKKyAgICAgICAgdi5hZGRFbGVtZW50KCJpbml0aWFsIik7CisgICAgICAgIFRocmVhZCB0MSA9IG5ldyBUaHJlYWQoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgd2hpbGUgKCF2LmlzRW1wdHkoKSkKKyAgICAgICAgICAgICAgICAgICAgOworICAgICAgICAgICAgICAgIHYuYWRkRWxlbWVudCgiZmluYWwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgdDEuc3RhcnQoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDAwMDsgaSsrKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHYpIHsKKyAgICAgICAgICAgICAgICB2LnJlbW92ZUVsZW1lbnRBdCgwKTsKKyAgICAgICAgICAgICAgICB2LmFkZEVsZW1lbnQoU3RyaW5nLnZhbHVlT2YoaSkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHNpemU7CisgICAgICAgICAgICBpZiAoKHNpemUgPSB2LnNpemUoKSkgIT0gMSkgeworICAgICAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSAiU2l6ZSBpcyBub3QgMTogIiArIHNpemUgKyAiICIgKyB2OworICAgICAgICAgICAgICAgIC8vIHRlcm1pbmF0ZSB0aGUgdGhyZWFkCisgICAgICAgICAgICAgICAgdi5yZW1vdmVBbGxFbGVtZW50cygpOworICAgICAgICAgICAgICAgIGZhaWwocmVzdWx0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyB0ZXJtaW5hdGUgdGhlIHRocmVhZAorICAgICAgICB2LnJlbW92ZUVsZW1lbnRBdCgwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2xhc3RFbGVtZW50KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xhc3RFbGVtZW50KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdCBqYXZhLnV0aWwuVmVjdG9yLmxhc3RFbGVtZW50KCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbGFzdCBlbGVtZW50IHJldHVybmVkIiwgIlRlc3QgOTkiLCB0VmVjdG9yLmxhc3RFbGVtZW50KCkKKyAgICAgICAgICAgICAgICApOworICAgICAgICB0VmVjdG9yLmFkZEVsZW1lbnQobnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCBsYXN0IGVsZW1lbnQgcmV0dXJuZWQtLXdhbnRlZCBudWxsIiwgdFZlY3RvcgorICAgICAgICAgICAgICAgIC5sYXN0RWxlbWVudCgpKTsKKworICAgICAgICB0VmVjdG9yID0gbmV3IFZlY3RvcigxMCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3IubGFzdEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2xhc3RJbmRleE9mKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9sYXN0SW5kZXhPZkxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudXRpbC5WZWN0b3IubGFzdEluZGV4T2YoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgVmVjdG9yIHYgPSBuZXcgVmVjdG9yKDkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDk7IGkrKykKKyAgICAgICAgICAgIHYuYWRkRWxlbWVudCgiVGVzdCIpOworICAgICAgICB2LmFkZEVsZW1lbnQoInoiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gcmV0dXJuIGNvcnJlY3QgaW5kZXgiLCA4LCB2Lmxhc3RJbmRleE9mKCJUZXN0IikpOworICAgICAgICB0VmVjdG9yLnNldEVsZW1lbnRBdChudWxsLCAyMCk7CisgICAgICAgIHRWZWN0b3Iuc2V0RWxlbWVudEF0KG51bGwsIDQwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGxhc3RJbmRleE9mIHJldHVybmVkIGZvciBudWxsOiAiCisgICAgICAgICAgICAgICAgKyB0VmVjdG9yLmxhc3RJbmRleE9mKG51bGwpLCB0VmVjdG9yLmxhc3RJbmRleE9mKG51bGwpID09IDQwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI2xhc3RJbmRleE9mKGphdmEubGFuZy5PYmplY3QsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xhc3RJbmRleE9mTGphdmFfbGFuZ19PYmplY3RJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgaW50IGphdmEudXRpbC5WZWN0b3IubGFzdEluZGV4T2YoamF2YS5sYW5nLk9iamVjdCwKKyAgICAgICAgLy8gaW50KQorICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCB0byBmaW5kIG9iamVjdCIsCisgICAgICAgICAgICAgICAgMCwgdFZlY3Rvci5sYXN0SW5kZXhPZigiVGVzdCAwIiwgMCkpOworICAgICAgICBhc3NlcnRUcnVlKCJGb3VuZCBPYmplY3Qgb3V0c2lkZSBvZiBpbmRleCIsICh0VmVjdG9yLmxhc3RJbmRleE9mKAorICAgICAgICAgICAgICAgICJUZXN0IDAiLCAxMCkgPiAtMSkpOworICAgICAgICB0VmVjdG9yLnNldEVsZW1lbnRBdChudWxsLCAyMCk7CisgICAgICAgIHRWZWN0b3Iuc2V0RWxlbWVudEF0KG51bGwsIDQwKTsKKyAgICAgICAgdFZlY3Rvci5zZXRFbGVtZW50QXQobnVsbCwgNjApOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgbGFzdEluZGV4T2YgcmV0dXJuZWQgZm9yIG51bGw6ICIKKyAgICAgICAgICAgICAgICArIHRWZWN0b3IubGFzdEluZGV4T2YobnVsbCwgMTUpLAorICAgICAgICAgICAgICAgIHRWZWN0b3IubGFzdEluZGV4T2YobnVsbCwgMTUpID09IC0xKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGxhc3RJbmRleE9mIHJldHVybmVkIGZvciBudWxsOiAiCisgICAgICAgICAgICAgICAgKyB0VmVjdG9yLmxhc3RJbmRleE9mKG51bGwsIDQ1KSwKKyAgICAgICAgICAgICAgICB0VmVjdG9yLmxhc3RJbmRleE9mKG51bGwsIDQ1KSA9PSA0MCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3IubGFzdEluZGV4T2YobnVsbCwgdFZlY3Rvci5zaXplKCkpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5WZWN0b3IjcmVtb3ZlKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlbW92ZUkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IGphdmEudXRpbC5WZWN0b3IucmVtb3ZlKGludCkKKyAgICAgICAgdFZlY3Rvci5yZW1vdmUoMzYpOworICAgICAgICBhc3NlcnRUcnVlKCJDb250YWluZWQgZWxlbWVudCBhZnRlciByZW1vdmUiLCAhdFZlY3RvcgorICAgICAgICAgICAgICAgIC5jb250YWlucygiVGVzdCAzNiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gZGVjcmVtZW50IHNpemUgYWZ0ZXIgcmVtb3ZlIiwKKyAgICAgICAgICAgICAgICA5OSwgdFZlY3Rvci5zaXplKCkpOworICAgICAgICB0VmVjdG9yLmFkZCgyMCwgbnVsbCk7CisgICAgICAgIHRWZWN0b3IucmVtb3ZlKDE5KTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiRGlkbid0IG1vdmUgbnVsbCBlbGVtZW50IG92ZXIiLCB0VmVjdG9yLmdldCgxOSkpOworICAgICAgICB0VmVjdG9yLnJlbW92ZSgxOSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkRpZG4ndCByZW1vdmUgbnVsbCBlbGVtZW50IiwgdFZlY3Rvci5nZXQoMTkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gZGVjcmVtZW50IHNpemUgYWZ0ZXIgcmVtb3ZpbmcgbnVsbCIsIDk4LCB0VmVjdG9yCisgICAgICAgICAgICAgICAgLnNpemUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3IucmVtb3ZlKC01KTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdFZlY3Rvci5yZW1vdmUodFZlY3Rvci5zaXplKCkgKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI3JlbW92ZShqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEudXRpbC5WZWN0b3IucmVtb3ZlKGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIHRWZWN0b3IucmVtb3ZlKCJUZXN0IDAiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29udGFpbmVkIGVsZW1lbnQgYWZ0ZXIgcmVtb3ZlIiwgIXRWZWN0b3IKKyAgICAgICAgICAgICAgICAuY29udGFpbnMoIlRlc3QgMCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gZGVjcmVtZW50IHNpemUgYWZ0ZXIgcmVtb3ZlIiwKKyAgICAgICAgICAgICAgICA5OSwgdFZlY3Rvci5zaXplKCkpOworICAgICAgICB0VmVjdG9yLmFkZChudWxsKTsKKyAgICAgICAgdFZlY3Rvci5yZW1vdmUobnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoIkNvbnRhaW5lZCBudWxsIGFmdGVyIHJlbW92ZSIsICF0VmVjdG9yLmNvbnRhaW5zKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gZGVjcmVtZW50IHNpemUgYWZ0ZXIgcmVtb3ZpbmcgbnVsbCIsIDk5LCB0VmVjdG9yCisgICAgICAgICAgICAgICAgLnNpemUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlZlY3RvciNyZW1vdmVBbGwoamF2YS51dGlsLkNvbGxlY3Rpb24pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZW1vdmVBbGxMamF2YV91dGlsX0NvbGxlY3Rpb24oKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuCisgICAgICAgIC8vIGphdmEudXRpbC5WZWN0b3IucmVtb3ZlQWxsKGphdmEudXRpbC5Db2xsZWN0aW9uKQorICAgICAgICBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoKTsKKyAgICAgICAgQ29sbGVjdGlvbiBsID0gbmV3IExpbmtlZExpc3QoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA1OyBpKyspCisgICAgICAgICAgICBsLmFkZCgiVGVzdCAiICsgaSk7CisgICAgICAgIHYuYWRkRWxlbWVudChsKTsKKworICAgICAgICBDb2xsZWN0aW9uIHMgPSBuZXcgSGFzaFNldCgpOworICAgICAgICBPYmplY3QgbzsKKyAgICAgICAgcy5hZGQobyA9IHYuZmlyc3RFbGVtZW50KCkpOworICAgICAgICB2LnJlbW92ZUFsbChzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIHJlbW92ZSBpdGVtcyBpbiBjb2xsZWN0aW9uIiwgIXYuY29udGFpbnMobykpOworICAgICAgICB2LnJlbW92ZUFsbChsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIHJlbW92ZSBhbGwgZWxlbWVudHMiLCB2LmlzRW1wdHkoKSk7CisKKyAgICAgICAgdi5hZGQobnVsbCk7CisgICAgICAgIHYuYWRkKG51bGwpOworICAgICAgICB2LmFkZCgiQm9vbSIpOworICAgICAgICB2LnJlbW92ZUFsbChzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgbm90IGhhdmUgcmVtb3ZlZCBhbnkgZWxlbWVudHMiLCAzLCB2LnNpemUoKSk7CisgICAgICAgIGwgPSBuZXcgTGlua2VkTGlzdCgpOworICAgICAgICBsLmFkZChudWxsKTsKKyAgICAgICAgdi5yZW1vdmVBbGwobCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIG9ubHkgaGF2ZSBvbmUgZWxlbWVudCIsIDEsIHYuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJFbGVtZW50IHNob3VsZCBiZSAnQm9vbSciLCAiQm9vbSIsIHYuZmlyc3RFbGVtZW50KCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB2LnJlbW92ZUFsbChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5WZWN0b3IjcmVtb3ZlQWxsRWxlbWVudHMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlQWxsRWxlbWVudHMoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCB2b2lkIGphdmEudXRpbC5WZWN0b3IucmVtb3ZlQWxsRWxlbWVudHMoKQorICAgICAgICBWZWN0b3IgdiA9IHZlY3RvckNsb25lKHRWZWN0b3IpOworICAgICAgICB2LnJlbW92ZUFsbEVsZW1lbnRzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHRvIHJlbW92ZSBhbGwgZWxlbWVudHMiLCAwLCB2LnNpemUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlZlY3RvciNyZW1vdmVFbGVtZW50KGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZW1vdmVFbGVtZW50TGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuCisgICAgICAgIC8vIGphdmEudXRpbC5WZWN0b3IucmVtb3ZlRWxlbWVudChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBWZWN0b3IgdiA9IHZlY3RvckNsb25lKHRWZWN0b3IpOworICAgICAgICB2LnJlbW92ZUVsZW1lbnQoIlRlc3QgOTgiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJFbGVtZW50IG5vdCByZW1vdmVkIiwgIlRlc3QgOTkiLCAoKFN0cmluZykgdi5lbGVtZW50QXQoOTgpKQorICAgICAgICAgICAgICAgICk7CisgICAgICAgIGFzc2VydFRydWUoIlZlY3RvciBpcyB3cm9uZyBzaXplIGFmdGVyIHJlbW92YWw6ICIgKyB2LnNpemUoKSwKKyAgICAgICAgICAgICAgICB2LnNpemUoKSA9PSA5OSk7CisgICAgICAgIHRWZWN0b3IuYWRkRWxlbWVudChudWxsKTsKKyAgICAgICAgdi5yZW1vdmVFbGVtZW50KG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJWZWN0b3IgaXMgd3Jvbmcgc2l6ZSBhZnRlciByZW1vdmluZyBudWxsOiAiICsgdi5zaXplKCksIHYKKyAgICAgICAgICAgICAgICAuc2l6ZSgpID09IDk5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI3JlbW92ZUVsZW1lbnRBdChpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZW1vdmVFbGVtZW50QXRJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuVmVjdG9yLnJlbW92ZUVsZW1lbnRBdChpbnQpCisgICAgICAgIFZlY3RvciB2ID0gdmVjdG9yQ2xvbmUodFZlY3Rvcik7CisgICAgICAgIHYucmVtb3ZlRWxlbWVudEF0KDUwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGYWlsZWQgdG8gcmVtb3ZlIGVsZW1lbnQiLCAtMSwgdi5pbmRleE9mKCJUZXN0IDUwIiwgMCkpOworICAgICAgICB0VmVjdG9yLmluc2VydEVsZW1lbnRBdChudWxsLCA2MCk7CisgICAgICAgIHRWZWN0b3IucmVtb3ZlRWxlbWVudEF0KDYwKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiRWxlbWVudCBhdCA2MCBzaG91bGQgbm90IGJlIG51bGwgYWZ0ZXIgcmVtb3ZhbCIsIHRWZWN0b3IKKyAgICAgICAgICAgICAgICAuZWxlbWVudEF0KDYwKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3IuZWxlbWVudEF0KC01KTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdFZlY3Rvci5lbGVtZW50QXQodFZlY3Rvci5zaXplKCkgKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuVmVjdG9yI3JldGFpbkFsbChqYXZhLnV0aWwuQ29sbGVjdGlvbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JldGFpbkFsbExqYXZhX3V0aWxfQ29sbGVjdGlvbigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4KKyAgICAgICAgLy8gamF2YS51dGlsLlZlY3Rvci5yZXRhaW5BbGwoamF2YS51dGlsLkNvbGxlY3Rpb24pCisgICAgICAgIE9iamVjdCBvID0gdFZlY3Rvci5maXJzdEVsZW1lbnQoKTsKKyAgICAgICAgdFZlY3Rvci5hZGQobnVsbCk7CisgICAgICAgIENvbGxlY3Rpb24gcyA9IG5ldyBIYXNoU2V0KCk7CisgICAgICAgIHMuYWRkKG8pOworICAgICAgICBzLmFkZChudWxsKTsKKyAgICAgICAgdFZlY3Rvci5yZXRhaW5BbGwocyk7CisgICAgICAgIGFzc2VydFRydWUoIlJldGFpbmVkIGl0ZW1zIG90aGVyIHRoYW4gc3BlY2lmaWVkIiwgdFZlY3Rvci5zaXplKCkgPT0gMgorICAgICAgICAgICAgICAgICYmIHRWZWN0b3IuY29udGFpbnMobykgJiYgdFZlY3Rvci5jb250YWlucyhudWxsKSk7CisKKyAgICAgICAgSXRlcmF0b3IgaSA9IHMuaXRlcmF0b3IoKTsKKworICAgICAgICB3aGlsZSAoaS5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUodFZlY3Rvci5jb250YWlucyhpLm5leHQoKSkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3IucmV0YWluQWxsKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlZlY3RvciNzZXQoaW50LCBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0SUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5sYW5nLk9iamVjdCBqYXZhLnV0aWwuVmVjdG9yLnNldChpbnQsCisgICAgICAgIC8vIGphdmEubGFuZy5PYmplY3QpCisgICAgICAgIE9iamVjdCBvID0gbmV3IE9iamVjdCgpOworICAgICAgICB0VmVjdG9yLnNldCgyMywgbyk7CisgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBzZXQgT2JqZWN0IiwgdFZlY3Rvci5nZXQoMjMpID09IG8pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0VmVjdG9yLnNldCgtNSwgIldyb25nIHBvc2l0aW9uIik7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3Iuc2V0KHRWZWN0b3Iuc2l6ZSgpICsgMSwgIldyb25nIHBvc2l0aW9uIik7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlZlY3RvciNzZXRFbGVtZW50QXQoamF2YS5sYW5nLk9iamVjdCwgaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0RWxlbWVudEF0TGphdmFfbGFuZ19PYmplY3RJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuVmVjdG9yLnNldEVsZW1lbnRBdChqYXZhLmxhbmcuT2JqZWN0LAorICAgICAgICAvLyBpbnQpCisgICAgICAgIFZlY3RvciB2ID0gdmVjdG9yQ2xvbmUodFZlY3Rvcik7CisgICAgICAgIHYuc2V0RWxlbWVudEF0KCJJbnNlcnRlZCBFbGVtZW50IiwgOTkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkVsZW1lbnQgbm90IHNldCIsICJJbnNlcnRlZCBFbGVtZW50IiwgKChTdHJpbmcpIHYuZWxlbWVudEF0KDk5KSkKKyAgICAgICAgICAgICAgICApOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0VmVjdG9yLnNldEVsZW1lbnRBdCgiV3JvbmcgcG9zaXRpb24iLCAtNSk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3Iuc2V0RWxlbWVudEF0KCJXcm9uZyBwb3NpdGlvbiIsIHRWZWN0b3Iuc2l6ZSgpICsgMSk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlZlY3RvciNzZXRTaXplKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFNpemVJKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuVmVjdG9yLnNldFNpemUoaW50KQorICAgICAgICBWZWN0b3IgdiA9IHZlY3RvckNsb25lKHRWZWN0b3IpOworICAgICAgICB2LnNldFNpemUoMTApOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZhaWxlZCB0byBzZXQgc2l6ZSIsIDEwLCB2LnNpemUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3Iuc2V0U2l6ZSgtNSk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlZlY3RvciNzaXplKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NpemUoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBpbnQgamF2YS51dGlsLlZlY3Rvci5zaXplKCkKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSZXR1cm5lZCBpbmNvcnJlY3Qgc2l6ZSIsIDEwMCwgdFZlY3Rvci5zaXplKCkpOworCisgICAgICAgIGZpbmFsIFZlY3RvciB2ID0gbmV3IFZlY3RvcigpOworICAgICAgICB2LmFkZEVsZW1lbnQoImluaXRpYWwiKTsKKyAgICAgICAgVGhyZWFkIHQxID0gbmV3IFRocmVhZCgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB3aGlsZSAodi5zaXplKCkgPiAwKQorICAgICAgICAgICAgICAgICAgICA7CisgICAgICAgICAgICAgICAgdi5hZGRFbGVtZW50KCJmaW5hbCIpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICB0MS5zdGFydCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDAwOyBpKyspIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAodikgeworICAgICAgICAgICAgICAgIHYucmVtb3ZlRWxlbWVudEF0KDApOworICAgICAgICAgICAgICAgIHYuYWRkRWxlbWVudChTdHJpbmcudmFsdWVPZihpKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgc2l6ZTsKKyAgICAgICAgICAgIGlmICgoc2l6ZSA9IHYuc2l6ZSgpKSAhPSAxKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHJlc3VsdCA9ICJTaXplIGlzIG5vdCAxOiAiICsgc2l6ZSArICIgIiArIHY7CisgICAgICAgICAgICAgICAgLy8gdGVybWluYXRlIHRoZSB0aHJlYWQKKyAgICAgICAgICAgICAgICB2LnJlbW92ZUFsbEVsZW1lbnRzKCk7CisgICAgICAgICAgICAgICAgZmFpbChyZXN1bHQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIHRlcm1pbmF0ZSB0aGUgdGhyZWFkCisgICAgICAgIHYucmVtb3ZlRWxlbWVudEF0KDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5WZWN0b3Ijc3ViTGlzdChpbnQsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1Ykxpc3RJSSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5MaXN0IGphdmEudXRpbC5WZWN0b3Iuc3ViTGlzdChpbnQsIGludCkKKyAgICAgICAgTGlzdCBzbCA9IHRWZWN0b3Iuc3ViTGlzdCgxMCwgMjUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlJldHVybmVkIHN1Ymxpc3Qgb2YgaW5jb3JyZWN0IHNpemUiLCAxNSwgc2wuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDEwOyBpIDwgMjU7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBzdWJsaXN0Iiwgc2wKKyAgICAgICAgICAgICAgICAgICAgLmNvbnRhaW5zKHRWZWN0b3IuZ2V0KGkpKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJOb3Qgc3luY2hyb25pemVkIHJhbmRvbSBhY2Nlc3MiLCAiamF2YS51dGlsLkNvbGxlY3Rpb25zJFN5bmNocm9uaXplZFJhbmRvbUFjY2Vzc0xpc3QiLCBzbC5nZXRDbGFzcygpLmdldE5hbWUoKQorICAgICAgICAgICAgICAgICk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3Iuc3ViTGlzdCgtMTAsIDI1KTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0VmVjdG9yLnN1Ykxpc3QoMTAsIHRWZWN0b3Iuc2l6ZSgpICsgMSk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2goSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdFZlY3Rvci5zdWJMaXN0KDI1LCAxMCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlZlY3RvciN0b0FycmF5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvQXJyYXkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IFtdIGphdmEudXRpbC5WZWN0b3IudG9BcnJheSgpCisgICAgICAgIGFzc2VydFRydWUoIlJldHVybmVkIGluY29ycmVjdCBhcnJheSIsIEFycmF5cy5lcXVhbHMob2JqQXJyYXksIHRWZWN0b3IKKyAgICAgICAgICAgICAgICAudG9BcnJheSgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlZlY3RvciN0b0FycmF5KGphdmEubGFuZy5PYmplY3RbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvQXJyYXkkTGphdmFfbGFuZ19PYmplY3QoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLmxhbmcuT2JqZWN0IFtdCisgICAgICAgIC8vIGphdmEudXRpbC5WZWN0b3IudG9BcnJheShqYXZhLmxhbmcuT2JqZWN0IFtdKQorICAgICAgICBPYmplY3RbXSBvID0gbmV3IE9iamVjdFsxMDAwXTsKKyAgICAgICAgT2JqZWN0IGYgPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgby5sZW5ndGg7IGkrKykKKyAgICAgICAgICAgIG9baV0gPSBmOworICAgICAgICB0VmVjdG9yLnRvQXJyYXkobyk7CisgICAgICAgIGFzc2VydE51bGwoIkZhaWxlZCB0byBzZXQgc2xvdCB0byBudWxsIiwgb1sxMDBdKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0VmVjdG9yLnNpemUoKTsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmV0dXJuZWQgaW5jb3JyZWN0IGFycmF5IiwgdFZlY3Rvci5lbGVtZW50QXQoaSkgPT0gb1tpXSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRWZWN0b3IudG9BcnJheShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRWZWN0b3IgPSBuZXcgVmVjdG9yPEludGVnZXI+KCk7CisgICAgICAgIHRWZWN0b3IuYWRkKG5ldyBJbnRlZ2VyKDEpKTsKKyAgICAgICAgdFZlY3Rvci5hZGQobmV3IEludGVnZXIoMikpOworICAgICAgICB0VmVjdG9yLmFkZChuZXcgSW50ZWdlcigzKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0VmVjdG9yLnRvQXJyYXkobmV3IFN0cmluZ1t0VmVjdG9yLnNpemUoKV0pOworICAgICAgICAgICAgZmFpbCgiQXJyYXlTdG9yZUV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKEFycmF5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLlZlY3RvciN0b1N0cmluZygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF90b1N0cmluZygpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5TdHJpbmcgamF2YS51dGlsLlZlY3Rvci50b1N0cmluZygpCisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBTdHJpbmcgcmV0dXJuZWQiLCB0VmVjdG9yLnRvU3RyaW5nKCkuZXF1YWxzKAorICAgICAgICAgICAgICAgIHZTdHJpbmcpKTsKKworICAgICAgICBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoKTsKKyAgICAgICAgdi5hZGRFbGVtZW50KCJvbmUiKTsKKyAgICAgICAgdi5hZGRFbGVtZW50KHYpOworICAgICAgICB2LmFkZEVsZW1lbnQoIjMiKTsKKyAgICAgICAgLy8gdGVzdCBsYXN0IGVsZW1lbnQKKyAgICAgICAgdi5hZGRFbGVtZW50KHYpOworICAgICAgICBTdHJpbmcgcmVzdWx0ID0gdi50b1N0cmluZygpOworICAgICAgICBhc3NlcnRUcnVlKCJzaG91bGQgY29udGFpbiBzZWxmIHJlZiIsIHJlc3VsdC5pbmRleE9mKCIodGhpcyIpID4gLTEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5WZWN0b3IjdHJpbVRvU2l6ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF90cmltVG9TaXplKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2Qgdm9pZCBqYXZhLnV0aWwuVmVjdG9yLnRyaW1Ub1NpemUoKQorICAgICAgICBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoMTApOworICAgICAgICB2LmFkZEVsZW1lbnQobmV3IE9iamVjdCgpKTsKKyAgICAgICAgdi50cmltVG9TaXplKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiRmFpbGVkIHRvIHRyaW0gY2FwYWNpdHkiLCAxLCB2LmNhcGFjaXR5KCkpOworICAgIH0KKworICAgIGNsYXNzIE1vY2tfVmVjdG9yIGV4dGVuZHMgVmVjdG9yIHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIHJlbW92ZVJhbmdlKGludCBmcm9tLCBpbnQgdG8pIHsKKyAgICAgICAgICAgIHN1cGVyLnJlbW92ZVJhbmdlKGZyb20sIHRvKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfcmVtb3ZlUmFuZ2VJSSgpIHsKKyAgICAgICAgTW9ja19WZWN0b3IgbXYgPSBuZXcgTW9ja19WZWN0b3IoKTsKKyAgICAgICAgbXYuYWRkKCJGaXJzdCIpOworICAgICAgICBtdi5hZGQoIlNlY29uZCIpOworICAgICAgICBtdi5hZGQoIk9uZSBtb3JlIik7CisgICAgICAgIG12LmFkZCgiTGFzdCIpOworICAgICAgICBtdi5yZW1vdmVSYW5nZSgxLCAzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtdi5jb250YWlucygiRmlyc3QiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG12LmNvbnRhaW5zKCJTZWNvbmQiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKG12LmNvbnRhaW5zKCJPbmUgbW9yZSIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtdi5jb250YWlucygiTGFzdCIpKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgVmVjdG9yIHZlY3RvckNsb25lKFZlY3RvciBzKSB7CisgICAgICAgIHJldHVybiAoVmVjdG9yKSBzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMgbWV0aG9kCisgICAgICogaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspIHsKKyAgICAgICAgICAgIHRWZWN0b3IuYWRkRWxlbWVudCgiVGVzdCAiICsgaSk7CisgICAgICAgIH0KKyAgICAgICAgb2JqQXJyYXkgPSBuZXcgT2JqZWN0WzEwMF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspIHsKKyAgICAgICAgICAgIG9iakFycmF5W2ldID0gIlRlc3QgIiArIGk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWFycyBkb3duIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgY2xvc2UgYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMKKyAgICAgKiBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9XZWFrSGFzaE1hcFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL1dlYWtIYXNoTWFwVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBlNDNiZjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9XZWFrSGFzaE1hcFRlc3QuamF2YQpAQCAtMCwwICsxLDM4MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLkFic3RyYWN0TWFwOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuV2Vha0hhc2hNYXA7CisKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfTWFwVGVzdDI7CisKK3B1YmxpYyBjbGFzcyBXZWFrSGFzaE1hcFRlc3QgZXh0ZW5kcyBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UgeworICAgIGNsYXNzIE1vY2tNYXAgZXh0ZW5kcyBBYnN0cmFjdE1hcCB7CisgICAgICAgIHB1YmxpYyBTZXQgZW50cnlTZXQoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgaW50IHNpemUoKXsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfQorCisgICAgT2JqZWN0W10ga2V5QXJyYXkgPSBuZXcgT2JqZWN0WzEwMF07CisKKyAgICBPYmplY3RbXSB2YWx1ZUFycmF5ID0gbmV3IE9iamVjdFsxMDBdOworCisgICAgV2Vha0hhc2hNYXAgd2htOworCisgICAgLyoqCisgICAgICogamF2YS51dGlsLldlYWtIYXNoTWFwI1dlYWtIYXNoTWFwKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLldlYWtIYXNoTWFwKCkKKyAgICAgICAgbmV3IFN1cHBvcnRfTWFwVGVzdDIobmV3IFdlYWtIYXNoTWFwKCkpLnJ1blRlc3QoKTsKKworICAgICAgICB3aG0gPSBuZXcgV2Vha0hhc2hNYXAoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykKKyAgICAgICAgICAgIHdobS5wdXQoa2V5QXJyYXlbaV0sIHZhbHVlQXJyYXlbaV0pOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHZhbHVlIHJldHJpZXZlZCIsCisgICAgICAgICAgICAgICAgICAgIHdobS5nZXQoa2V5QXJyYXlbaV0pID09IHZhbHVlQXJyYXlbaV0pOworCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLldlYWtIYXNoTWFwI1dlYWtIYXNoTWFwKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9ySSgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5XZWFrSGFzaE1hcChpbnQpCisgICAgICAgIHdobSA9IG5ldyBXZWFrSGFzaE1hcCg1MCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspCisgICAgICAgICAgICB3aG0ucHV0KGtleUFycmF5W2ldLCB2YWx1ZUFycmF5W2ldKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCB2YWx1ZSByZXRyaWV2ZWQiLAorICAgICAgICAgICAgICAgICAgICB3aG0uZ2V0KGtleUFycmF5W2ldKSA9PSB2YWx1ZUFycmF5W2ldKTsKKworICAgICAgICBXZWFrSGFzaE1hcCBlbXB0eSA9IG5ldyBXZWFrSGFzaE1hcCgwKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiRW1wdHkgd2Vha2hhc2htYXAgYWNjZXNzIiwgZW1wdHkuZ2V0KCJub3RoaW5nIikpOworICAgICAgICBlbXB0eS5wdXQoInNvbWV0aGluZyIsICJoZXJlIik7CisgICAgICAgIGFzc2VydFRydWUoImNhbm5vdCBnZXQgZWxlbWVudCIsIGVtcHR5LmdldCgic29tZXRoaW5nIikgPT0gImhlcmUiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFdlYWtIYXNoTWFwKC01MCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5XZWFrSGFzaE1hcCNXZWFrSGFzaE1hcChpbnQsIGZsb2F0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JJRigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEudXRpbC5XZWFrSGFzaE1hcChpbnQsIGZsb2F0KQorICAgICAgICB3aG0gPSBuZXcgV2Vha0hhc2hNYXAoNTAsIDAuNWYpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKQorICAgICAgICAgICAgd2htLnB1dChrZXlBcnJheVtpXSwgdmFsdWVBcnJheVtpXSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspCisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgdmFsdWUgcmV0cmlldmVkIiwKKyAgICAgICAgICAgICAgICAgICAgd2htLmdldChrZXlBcnJheVtpXSkgPT0gdmFsdWVBcnJheVtpXSk7CisKKyAgICAgICAgV2Vha0hhc2hNYXAgZW1wdHkgPSBuZXcgV2Vha0hhc2hNYXAoMCwgMC43NWYpOworICAgICAgICBhc3NlcnROdWxsKCJFbXB0eSBoYXNodGFibGUgYWNjZXNzIiwgZW1wdHkuZ2V0KCJub3RoaW5nIikpOworICAgICAgICBlbXB0eS5wdXQoInNvbWV0aGluZyIsICJoZXJlIik7CisgICAgICAgIGFzc2VydFRydWUoImNhbm5vdCBnZXQgZWxlbWVudCIsIGVtcHR5LmdldCgic29tZXRoaW5nIikgPT0gImhlcmUiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFdlYWtIYXNoTWFwKDUwLCAtMC41Zik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgV2Vha0hhc2hNYXAoLTUwLCAwLjVmKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLldlYWtIYXNoTWFwI1dlYWtIYXNoTWFwKGphdmEudXRpbC5NYXApCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX3V0aWxfTWFwKCkgeworICAgICAgICBNYXAgbW9ja01hcCA9IG5ldyBNb2NrTWFwKCk7CisgICAgICAgIFdlYWtIYXNoTWFwIG1hcCA9IG5ldyBXZWFrSGFzaE1hcChtb2NrTWFwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaXplIHNob3VsZCBiZSAwIiwgMCwgbWFwLnNpemUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBXZWFrSGFzaE1hcChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5XZWFrSGFzaE1hcCNjbGVhcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jbGVhcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4gamF2YS51dGlsLldlYWtIYXNoTWFwLmNsZWFyKCkKKyAgICAgICAgd2htID0gbmV3IFdlYWtIYXNoTWFwKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspCisgICAgICAgICAgICB3aG0ucHV0KGtleUFycmF5W2ldLCB2YWx1ZUFycmF5W2ldKTsKKyAgICAgICAgd2htLmNsZWFyKCk7CisgICAgICAgIGFzc2VydFRydWUoIkNsZWFyZWQgbWFwIHNob3VsZCBiZSBlbXB0eSIsIHdobS5pc0VtcHR5KCkpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0TnVsbCgiQ2xlYXJlZCBtYXAgc2hvdWxkIG9ubHkgcmV0dXJuIG51bGwiLCB3aG0KKyAgICAgICAgICAgICAgICAgICAgLmdldChrZXlBcnJheVtpXSkpOworCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLldlYWtIYXNoTWFwI2NvbnRhaW5zS2V5KGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jb250YWluc0tleUxqYXZhX2xhbmdfT2JqZWN0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgYm9vbGVhbiBqYXZhLnV0aWwuV2Vha0hhc2hNYXAuY29udGFpbnNLZXkoKQorICAgICAgICB3aG0gPSBuZXcgV2Vha0hhc2hNYXAoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykKKyAgICAgICAgICAgIHdobS5wdXQoa2V5QXJyYXlbaV0sIHZhbHVlQXJyYXlbaV0pOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGNvbnRhaW4gcmVmZXJlbmNlZCBrZXkiLCB3aG0KKyAgICAgICAgICAgICAgICAgICAgLmNvbnRhaW5zS2V5KGtleUFycmF5W2ldKSk7CisgICAgICAgIGtleUFycmF5WzI1XSA9IG51bGw7CisgICAgICAgIGtleUFycmF5WzUwXSA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLldlYWtIYXNoTWFwI2NvbnRhaW5zVmFsdWUoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbnRhaW5zVmFsdWVMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGJvb2xlYW4gamF2YS51dGlsLldlYWtIYXNoTWFwLmNvbnRhaW5zVmFsdWUoKQorICAgICAgICB3aG0gPSBuZXcgV2Vha0hhc2hNYXAoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykKKyAgICAgICAgICAgIHdobS5wdXQoa2V5QXJyYXlbaV0sIHZhbHVlQXJyYXlbaV0pOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIGNvbnRhaW4gcmVmZXJlbmNlZCB2YWx1ZSIsIHdobQorICAgICAgICAgICAgICAgICAgICAuY29udGFpbnNWYWx1ZSh2YWx1ZUFycmF5W2ldKSk7CisgICAgICAgIGtleUFycmF5WzI1XSA9IG51bGw7CisgICAgICAgIGtleUFycmF5WzUwXSA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLldlYWtIYXNoTWFwI2VudHJ5U2V0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VudHJ5U2V0KCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlNldCBqYXZhLnV0aWwuV2Vha0hhc2hNYXAuZW50cnlTZXQoKQorICAgICAgICB3aG0gPSBuZXcgV2Vha0hhc2hNYXAoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykKKyAgICAgICAgICAgIHdobS5wdXQoa2V5QXJyYXlbaV0sIHZhbHVlQXJyYXlbaV0pOworICAgICAgICBMaXN0IGtleXMgPSBBcnJheXMuYXNMaXN0KGtleUFycmF5KTsKKyAgICAgICAgTGlzdCB2YWx1ZXMgPSBBcnJheXMuYXNMaXN0KHZhbHVlQXJyYXkpOworICAgICAgICBTZXQgZW50cnlTZXQgPSB3aG0uZW50cnlTZXQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG51bWJlciBvZiBlbnRyaWVzIHJldHVybmVkLS13YW50ZWQgMTAwLCBnb3Q6ICIKKyAgICAgICAgICAgICAgICArIGVudHJ5U2V0LnNpemUoKSwgZW50cnlTZXQuc2l6ZSgpID09IDEwMCk7CisgICAgICAgIEl0ZXJhdG9yIGl0ID0gZW50cnlTZXQuaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgTWFwLkVudHJ5IGVudHJ5ID0gKE1hcC5FbnRyeSkgaXQubmV4dCgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW52YWxpZCBtYXAgZW50cnkgcmV0dXJuZWQtLWJhZCBrZXkiLCBrZXlzCisgICAgICAgICAgICAgICAgICAgIC5jb250YWlucyhlbnRyeS5nZXRLZXkoKSkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW52YWxpZCBtYXAgZW50cnkgcmV0dXJuZWQtLWJhZCBrZXkiLCB2YWx1ZXMKKyAgICAgICAgICAgICAgICAgICAgLmNvbnRhaW5zKGVudHJ5LmdldFZhbHVlKCkpKTsKKyAgICAgICAgfQorICAgICAgICBrZXlzID0gbnVsbDsKKyAgICAgICAgdmFsdWVzID0gbnVsbDsKKyAgICAgICAga2V5QXJyYXlbNTBdID0gbnVsbDsKKworICAgICAgICBpbnQgY291bnQgPSAwOworICAgICAgICBkbyB7CisgICAgICAgICAgICBTeXN0ZW0uZ2MoKTsKKyAgICAgICAgICAgIFN5c3RlbS5nYygpOworICAgICAgICAgICAgUnVudGltZS5nZXRSdW50aW1lKCkucnVuRmluYWxpemF0aW9uKCk7CisgICAgICAgICAgICBjb3VudCsrOworICAgICAgICB9IHdoaWxlIChjb3VudCA8PSA1ICYmIGVudHJ5U2V0LnNpemUoKSA9PSAxMDApOworCisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIkluY29ycmVjdCBudW1iZXIgb2YgZW50cmllcyByZXR1cm5lZCBhZnRlciBnYy0td2FudGVkIDk5LCBnb3Q6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgZW50cnlTZXQuc2l6ZSgpLCBlbnRyeVNldC5zaXplKCkgPT0gOTkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5XZWFrSGFzaE1hcCNpc0VtcHR5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzRW1wdHkoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBib29sZWFuIGphdmEudXRpbC5XZWFrSGFzaE1hcC5pc0VtcHR5KCkKKyAgICAgICAgd2htID0gbmV3IFdlYWtIYXNoTWFwKCk7CisgICAgICAgIGFzc2VydFRydWUoIk5ldyBtYXAgc2hvdWxkIGJlIGVtcHR5Iiwgd2htLmlzRW1wdHkoKSk7CisgICAgICAgIE9iamVjdCBteU9iamVjdCA9IG5ldyBPYmplY3QoKTsKKyAgICAgICAgd2htLnB1dChteU9iamVjdCwgbXlPYmplY3QpOworICAgICAgICBhc3NlcnRUcnVlKCJNYXAgc2hvdWxkIG5vdCBiZSBlbXB0eSIsICF3aG0uaXNFbXB0eSgpKTsKKyAgICAgICAgd2htLnJlbW92ZShteU9iamVjdCk7CisgICAgICAgIGFzc2VydFRydWUoIk1hcCB3aXRoIGVsZW1lbnRzIHJlbW92ZWQgc2hvdWxkIGJlIGVtcHR5Iiwgd2htLmlzRW1wdHkoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLldlYWtIYXNoTWFwI3B1dChqYXZhLmxhbmcuT2JqZWN0LCBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcHV0TGphdmFfbGFuZ19PYmplY3RMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QKKyAgICAgICAgLy8gamF2YS51dGlsLldlYWtIYXNoTWFwLnB1dChqYXZhLmxhbmcuT2JqZWN0LCBqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICBXZWFrSGFzaE1hcCBtYXAgPSBuZXcgV2Vha0hhc2hNYXAoKTsKKyAgICAgICAgbWFwLnB1dChudWxsLCAidmFsdWUiKTsgLy8gYWRkIG51bGwga2V5CisgICAgICAgIFN5c3RlbS5nYygpOworICAgICAgICBTeXN0ZW0ucnVuRmluYWxpemF0aW9uKCk7CisgICAgICAgIG1hcC5yZW1vdmUoIm5vdGhpbmciKTsgLy8gQ2F1c2Ugb2JqZWN0cyBpbiBxdWV1ZSB0byBiZSByZW1vdmVkCisgICAgICAgIGFzc2VydEVxdWFscygibnVsbCBrZXkgd2FzIHJlbW92ZWQiLCAxLCBtYXAuc2l6ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuV2Vha0hhc2hNYXAjcHV0QWxsKGphdmEudXRpbC5NYXApCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wdXRBbGxMamF2YV91dGlsX01hcCgpIHsKKyAgICAgICAgTWFwIG1vY2tNYXA9bmV3IE1vY2tNYXAoKTsKKyAgICAgICAgV2Vha0hhc2hNYXAgbWFwID0gbmV3IFdlYWtIYXNoTWFwKCk7CisgICAgICAgIG1hcC5wdXRBbGwobW9ja01hcCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBzaG91bGQgYmUgMCIsIDAsIG1hcC5zaXplKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtYXAucHV0QWxsKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnV0aWwuV2Vha0hhc2hNYXAjcmVtb3ZlKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9yZW1vdmVMamF2YV9sYW5nX09iamVjdCgpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEubGFuZy5PYmplY3QKKyAgICAgICAgLy8gamF2YS51dGlsLldlYWtIYXNoTWFwLnJlbW92ZShqYXZhLmxhbmcuT2JqZWN0KQorICAgICAgICB3aG0gPSBuZXcgV2Vha0hhc2hNYXAoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykKKyAgICAgICAgICAgIHdobS5wdXQoa2V5QXJyYXlbaV0sIHZhbHVlQXJyYXlbaV0pOworCisgICAgICAgIGFzc2VydFRydWUoIlJlbW92ZSByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLAorICAgICAgICAgICAgICAgIHdobS5yZW1vdmUoa2V5QXJyYXlbMjVdKSA9PSB2YWx1ZUFycmF5WzI1XSk7CisgICAgICAgIGFzc2VydE51bGwoIlJlbW92ZSByZXR1cm5lZCBpbmNvcnJlY3QgdmFsdWUiLAorICAgICAgICAgICAgICAgIHdobS5yZW1vdmUoa2V5QXJyYXlbMjVdKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2l6ZSBzaG91bGQgYmUgOTkgYWZ0ZXIgcmVtb3ZlIiwgOTksIHdobS5zaXplKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5XZWFrSGFzaE1hcCNzaXplKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NpemUoKSB7CisgICAgICAgIHdobSA9IG5ldyBXZWFrSGFzaE1hcCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgd2htLnNpemUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS51dGlsLldlYWtIYXNoTWFwI2tleVNldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9rZXlTZXQoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnV0aWwuU2V0IGphdmEudXRpbC5XZWFrSGFzaE1hcC5rZXlTZXQoKQorICAgICAgICB3aG0gPSBuZXcgV2Vha0hhc2hNYXAoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykKKyAgICAgICAgICAgIHdobS5wdXQoa2V5QXJyYXlbaV0sIHZhbHVlQXJyYXlbaV0pOworCisgICAgICAgIExpc3Qga2V5cyA9IEFycmF5cy5hc0xpc3Qoa2V5QXJyYXkpOworICAgICAgICBMaXN0IHZhbHVlcyA9IEFycmF5cy5hc0xpc3QodmFsdWVBcnJheSk7CisKKyAgICAgICAgU2V0IGtleVNldCA9IHdobS5rZXlTZXQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbnVtYmVyIG9mIGtleXMgcmV0dXJuZWQsIiwgMTAwLCBrZXlTZXQuc2l6ZSgpKTsKKyAgICAgICAgSXRlcmF0b3IgaXQgPSBrZXlTZXQuaXRlcmF0b3IoKTsKKyAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgT2JqZWN0IGtleSA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkludmFsaWQgbWFwIGVudHJ5IHJldHVybmVkLS1iYWQga2V5Iiwga2V5cworICAgICAgICAgICAgICAgICAgICAuY29udGFpbnMoa2V5KSk7CisgICAgICAgIH0KKyAgICAgICAga2V5cyA9IG51bGw7CisgICAgICAgIHZhbHVlcyA9IG51bGw7CisgICAgICAgIGtleUFycmF5WzUwXSA9IG51bGw7CisKKyAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgZG8geworICAgICAgICAgICAgU3lzdGVtLmdjKCk7CisgICAgICAgICAgICBTeXN0ZW0uZ2MoKTsKKyAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLnJ1bkZpbmFsaXphdGlvbigpOworICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgfSB3aGlsZSAoY291bnQgPD0gNSAmJiBrZXlTZXQuc2l6ZSgpID09IDEwMCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbnVtYmVyIG9mIGtleXMgcmV0dXJuZWQgYWZ0ZXIgZ2MsIiwgOTksIGtleVNldAorICAgICAgICAgICAgICAgIC5zaXplKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEudXRpbC5XZWFrSGFzaE1hcCN2YWx1ZXMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdmFsdWVzKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS51dGlsLlNldCBqYXZhLnV0aWwuV2Vha0hhc2hNYXAudmFsdWVzKCkKKyAgICAgICAgd2htID0gbmV3IFdlYWtIYXNoTWFwKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspCisgICAgICAgICAgICB3aG0ucHV0KGtleUFycmF5W2ldLCB2YWx1ZUFycmF5W2ldKTsKKworICAgICAgICBMaXN0IGtleXMgPSBBcnJheXMuYXNMaXN0KGtleUFycmF5KTsKKyAgICAgICAgTGlzdCB2YWx1ZXMgPSBBcnJheXMuYXNMaXN0KHZhbHVlQXJyYXkpOworCisgICAgICAgIENvbGxlY3Rpb24gdmFsdWVzQ29sbGVjdGlvbiA9IHdobS52YWx1ZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbnVtYmVyIG9mIGtleXMgcmV0dXJuZWQsIiwgMTAwLAorICAgICAgICAgICAgICAgIHZhbHVlc0NvbGxlY3Rpb24uc2l6ZSgpKTsKKyAgICAgICAgSXRlcmF0b3IgaXQgPSB2YWx1ZXNDb2xsZWN0aW9uLml0ZXJhdG9yKCk7CisgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IGl0Lm5leHQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkludmFsaWQgbWFwIGVudHJ5IHJldHVybmVkLS1iYWQgdmFsdWUiLCB2YWx1ZXMKKyAgICAgICAgICAgICAgICAgICAgLmNvbnRhaW5zKHZhbHVlKSk7CisgICAgICAgIH0KKyAgICAgICAga2V5cyA9IG51bGw7CisgICAgICAgIHZhbHVlcyA9IG51bGw7CisgICAgICAgIGtleUFycmF5WzUwXSA9IG51bGw7CisKKyAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgZG8geworICAgICAgICAgICAgU3lzdGVtLmdjKCk7CisgICAgICAgICAgICBTeXN0ZW0uZ2MoKTsKKyAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLnJ1bkZpbmFsaXphdGlvbigpOworICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgfSB3aGlsZSAoY291bnQgPD0gNSAmJiB2YWx1ZXNDb2xsZWN0aW9uLnNpemUoKSA9PSAxMDApOworCisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IG51bWJlciBvZiBrZXlzIHJldHVybmVkIGFmdGVyIGdjLCIsIDk5LAorICAgICAgICAgICAgICAgIHZhbHVlc0NvbGxlY3Rpb24uc2l6ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHVwIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgb3BlbiBhIG5ldHdvcmsgY29ubmVjdGlvbi4gVGhpcyBtZXRob2QKKyAgICAgKiBpcyBjYWxsZWQgYmVmb3JlIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykgeworICAgICAgICAgICAga2V5QXJyYXlbaV0gPSBuZXcgT2JqZWN0KCk7CisgICAgICAgICAgICB2YWx1ZUFycmF5W2ldID0gbmV3IE9iamVjdCgpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZWFycyBkb3duIHRoZSBmaXh0dXJlLCBmb3IgZXhhbXBsZSwgY2xvc2UgYSBuZXR3b3JrIGNvbm5lY3Rpb24uIFRoaXMKKyAgICAgKiBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIGEgdGVzdCBpcyBleGVjdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9zdXBwb3J0L0EuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL3N1cHBvcnQvQS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyYjQzYjUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9zdXBwb3J0L0EuamF2YQpAQCAtMCwwICsxLDEzIEBACitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLnV0aWwuc3VwcG9ydDsKKworcHVibGljIGNsYXNzIEEgaW1wbGVtZW50cyBJIHsKKyAgICBwcml2YXRlIHN0YXRpYyBQIHBwID0gbmV3IFAoKTsKKworICAgIHB1YmxpYyBBKCkgeworICAgICAgICBwcC5zZXRDbGF6eihnZXRDbGFzcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGZpbmQoU3RyaW5nIGtleSkgeworICAgICAgICByZXR1cm4gcHAuZmluZFByb3Aoa2V5KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9zdXBwb3J0L0IuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL3N1cHBvcnQvQi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJhYWZkYmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9zdXBwb3J0L0IuamF2YQpAQCAtMCwwICsxLDQgQEAKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbC5zdXBwb3J0OworCitwdWJsaWMgY2xhc3MgQiBleHRlbmRzIEEgeworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvc3VwcG9ydC9JLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmEvdXRpbC9zdXBwb3J0L0kuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMWNkNzNhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvc3VwcG9ydC9JLmphdmEKQEAgLTAsMCArMSw1IEBACitwYWNrYWdlIHRlc3RzLmFwaS5qYXZhLnV0aWwuc3VwcG9ydDsKKworcHVibGljIGludGVyZmFjZSBJIHsKKyAgICBTdHJpbmcgZmluZChTdHJpbmcga2V5KTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL3N1cHBvcnQvUC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZhL3V0aWwvc3VwcG9ydC9QLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjg4MzkzNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YS91dGlsL3N1cHBvcnQvUC5qYXZhCkBAIC0wLDAgKzEsMjggQEAKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmEudXRpbC5zdXBwb3J0OworCitpbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOworCitwdWJsaWMgY2xhc3MgUCB7CisgICAgcHJpdmF0ZSBDbGFzcyBjOworCisgICAgcHVibGljIHZvaWQgc2V0Q2xhenooQ2xhc3MgYykgeworICAgICAgICB0aGlzLmMgPSBjOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZmluZFByb3AoU3RyaW5nIGtleSkgeworICAgICAgICByZXR1cm4gZmluZFByb3AodGhpcy5jLCBrZXkpOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGZpbmRQcm9wKENsYXNzIGNscywgU3RyaW5nIGtleSkgeworICAgICAgICBTdHJpbmcgcmV0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJlc291cmNlQnVuZGxlIGIgPSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUoY2xzLmdldE5hbWUoKSk7CisgICAgICAgICAgICByZXQgPSAoU3RyaW5nKWIuZ2V0T2JqZWN0KGtleSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJldCA9PSBudWxsICYmICFjbHMuZXF1YWxzKE9iamVjdC5jbGFzcykgJiYgIWNscy5pc1ByaW1pdGl2ZSgpKSB7CisgICAgICAgICAgICByZXQgPSBmaW5kUHJvcChjbHMuZ2V0U3VwZXJjbGFzcygpLCBrZXkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvU2VydmVyU29ja2V0RmFjdG9yeVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L1NlcnZlclNvY2tldEZhY3RvcnlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDUzMjAwZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L1NlcnZlclNvY2tldEZhY3RvcnlUZXN0LmphdmEKQEAgLTAsMCArMSwyMTAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEJvcmlzIFYuIEt1em5ldHNvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LlNlcnZlclNvY2tldEZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfUG9ydE1hbmFnZXI7CisKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+U2VydmVyU29ja2V0RmFjdG9yeTwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICovCitwdWJsaWMgY2xhc3MgU2VydmVyU29ja2V0RmFjdG9yeVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuU29ja2V0RmFjdG9yeSNTb2NrZXRGYWN0b3J5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2VydmVyU29ja2V0RmFjdG9yeSBzZiA9IG5ldyBNeVNlcnZlclNvY2tldEZhY3RvcnkoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LlNlcnZlclNvY2tldEZhY3RvcnkjY3JlYXRlU2VydmVyU29ja2V0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X2NyZWF0ZVNlcnZlclNvY2tldF8wMSgpIHsKKyAgICAgICAgU2VydmVyU29ja2V0RmFjdG9yeSBzZiA9IFNlcnZlclNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2VydmVyU29ja2V0IHNzID0gc2YuY3JlYXRlU2VydmVyU29ja2V0KCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHNzKTsKKyAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5TZXJ2ZXJTb2NrZXRGYWN0b3J5I2NyZWF0ZVNlcnZlclNvY2tldChpbnQgcG9ydCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X2NyZWF0ZVNlcnZlclNvY2tldF8wMigpIHsKKyAgICAgICAgU2VydmVyU29ja2V0RmFjdG9yeSBzZiA9IFNlcnZlclNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2VydmVyU29ja2V0IHNzID0gc2YuY3JlYXRlU2VydmVyU29ja2V0KHBvcnROdW1iZXIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChzcyk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBleCk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2YuY3JlYXRlU2VydmVyU29ja2V0KHBvcnROdW1iZXIpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKGV4ICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZi5jcmVhdGVTZXJ2ZXJTb2NrZXQoLTEpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoZXggKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5TZXJ2ZXJTb2NrZXRGYWN0b3J5I2NyZWF0ZVNlcnZlclNvY2tldChpbnQgcG9ydCwgaW50IGJhY2tsb2cpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF9jcmVhdGVTZXJ2ZXJTb2NrZXRfMDMoKSB7CisgICAgICAgIFNlcnZlclNvY2tldEZhY3Rvcnkgc2YgPSBTZXJ2ZXJTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNlcnZlclNvY2tldCBzcyA9IHNmLmNyZWF0ZVNlcnZlclNvY2tldChwb3J0TnVtYmVyLCAwKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc3MpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZXgpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNmLmNyZWF0ZVNlcnZlclNvY2tldChwb3J0TnVtYmVyLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbChleCArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElPRXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2YuY3JlYXRlU2VydmVyU29ja2V0KDY1NTM2LCAwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKGV4ICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuU2VydmVyU29ja2V0RmFjdG9yeSNjcmVhdGVTZXJ2ZXJTb2NrZXQoaW50IHBvcnQsIGludCBiYWNrbG9nLCBJbmV0QWRkcmVzcyBpZkFkZHJlc3MpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF9jcmVhdGVTZXJ2ZXJTb2NrZXRfMDQoKSB7CisgICAgICAgIFNlcnZlclNvY2tldEZhY3Rvcnkgc2YgPSBTZXJ2ZXJTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNlcnZlclNvY2tldCBzcyA9IHNmLmNyZWF0ZVNlcnZlclNvY2tldChwb3J0TnVtYmVyLCAwLCBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHNzKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGV4KTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZi5jcmVhdGVTZXJ2ZXJTb2NrZXQocG9ydE51bWJlciwgMCwgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCkpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKGV4ICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSU9FeGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZi5jcmVhdGVTZXJ2ZXJTb2NrZXQoSW50ZWdlci5NQVhfVkFMVUUsIDAsIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKGV4ICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuU2VydmVyU29ja2V0RmFjdG9yeSNnZXREZWZhdWx0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X2dldERlZmF1bHQoKSB7CisgICAgICAgIFNlcnZlclNvY2tldEZhY3Rvcnkgc2YgPSBTZXJ2ZXJTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKyAgICAgICAgU2VydmVyU29ja2V0IHM7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzID0gc2YuY3JlYXRlU2VydmVyU29ja2V0KDApOworICAgICAgICAgICAgcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMgPSBzZi5jcmVhdGVTZXJ2ZXJTb2NrZXQoMCwgNTApOworICAgICAgICAgICAgcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMgPSBzZi5jcmVhdGVTZXJ2ZXJTb2NrZXQoMCwgNTAsIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpKTsKKyAgICAgICAgICAgIHMuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorfQorY2xhc3MgTXlTZXJ2ZXJTb2NrZXRGYWN0b3J5IGV4dGVuZHMgU2VydmVyU29ja2V0RmFjdG9yeSB7CisKKyAgICBwdWJsaWMgTXlTZXJ2ZXJTb2NrZXRGYWN0b3J5KCkgeworICAgICAgICBzdXBlcigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTZXJ2ZXJTb2NrZXQgY3JlYXRlU2VydmVyU29ja2V0KGludCBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2VydmVyU29ja2V0IGNyZWF0ZVNlcnZlclNvY2tldChpbnQgcG9ydCwgaW50IGJhY2tsb2cpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU2VydmVyU29ja2V0IGNyZWF0ZVNlcnZlclNvY2tldChpbnQgcG9ydCwgaW50IGJhY2tsb2csCisgICAgICAgICAgICBJbmV0QWRkcmVzcyBhZGRyZXNzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9Tb2NrZXRGYWN0b3J5VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvU29ja2V0RmFjdG9yeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMjUwNjAyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvU29ja2V0RmFjdG9yeVRlc3QuamF2YQpAQCAtMCwwICsxLDM2MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQm9yaXMgVi4gS3V6bmV0c292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU2VydmVyU29ja2V0OworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVW5rbm93bkhvc3RFeGNlcHRpb247CisKK2ltcG9ydCBqYXZheC5uZXQuU29ja2V0RmFjdG9yeTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Qb3J0TWFuYWdlcjsKKworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5Tb2NrZXRGYWN0b3J5PC9jb2RlPiBjbGFzcyBtZXRob2RzLgorICovCitwdWJsaWMgY2xhc3MgU29ja2V0RmFjdG9yeVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuU29ja2V0RmFjdG9yeSNTb2NrZXRGYWN0b3J5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgTXlTb2NrZXRGYWN0b3J5IHNmID0gbmV3IE15U29ja2V0RmFjdG9yeSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuU29ja2V0RmFjdG9yeSNjcmVhdGVTb2NrZXQoKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfY3JlYXRlU29ja2V0XzAxKCkgeworICAgICAgICBTb2NrZXRGYWN0b3J5IHNmID0gU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldCBzID0gc2YuY3JlYXRlU29ja2V0KCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHMpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBzLmdldExvY2FsUG9ydCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBzLmdldFBvcnQoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgTXlTb2NrZXRGYWN0b3J5IG1zZiA9IG5ldyBNeVNvY2tldEZhY3RvcnkoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1zZi5jcmVhdGVTb2NrZXQoKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIFNvY2tldEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuU29ja2V0RmFjdG9yeSNjcmVhdGVTb2NrZXQoU3RyaW5nIGhvc3QsIGludCBwb3J0KQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfY3JlYXRlU29ja2V0XzAyKCkgeworICAgICAgICBTb2NrZXRGYWN0b3J5IHNmID0gU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCk7CisgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICBpbnQgc3BvcnQgPSBzdGFydFNlcnZlcigiQ29ucyBTdHJpbmcsSSIpOworICAgICAgICBpbnRbXSBpbnZhbGlkUG9ydHMgPSB7SW50ZWdlci5NSU5fVkFMVUUsIC0xLCA2NTUzNiwgSW50ZWdlci5NQVhfVkFMVUV9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTb2NrZXQgcyA9IHNmLmNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKS5nZXRIb3N0TmFtZSgpLCBzcG9ydCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHMpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHRvIGNyZWF0ZSBzb2NrZXQiLCBzLmdldFBvcnQoKSA9PSBzcG9ydCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldCBzID0gc2YuY3JlYXRlU29ja2V0KCJibGEtYmxhIiwgc3BvcnQpOworICAgICAgICAgICAgZmFpbCgiVW5rbm93bkhvc3RFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChVbmtub3duSG9zdEV4Y2VwdGlvbiB1aGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIFVua25vd25Ib3N0RXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRQb3J0cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTb2NrZXQgcyA9IHNmLmNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKS5nZXRIb3N0TmFtZSgpLCBpbnZhbGlkUG9ydHNbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIGZvciAiICsgaW52YWxpZFBvcnRzW2ldKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBmb3IgIiArIGludmFsaWRQb3J0c1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU29ja2V0IHMgPSBzZi5jcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCkuZ2V0SG9zdE5hbWUoKSwgcG9ydE51bWJlcik7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgU29ja2V0RmFjdG9yeSBmID0gU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTb2NrZXQgcyA9IGYuY3JlYXRlU29ja2V0KCJsb2NhbGhvc3QiLCA4MDgyKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHdhc24ndCB0aHJvd24gLi4uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5I2NyZWF0ZVNvY2tldChJbmV0QWRkcmVzcyBob3N0LCBpbnQgcG9ydCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X2NyZWF0ZVNvY2tldF8wMygpIHsKKyAgICAgICAgU29ja2V0RmFjdG9yeSBzZiA9IFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICAgICAgaW50IHNwb3J0ID0gc3RhcnRTZXJ2ZXIoIkNvbnMgSW5ldEFkZHJlc3MsSSIpOworICAgICAgICBpbnRbXSBpbnZhbGlkUG9ydHMgPSB7SW50ZWdlci5NSU5fVkFMVUUsIC0xLCA2NTUzNiwgSW50ZWdlci5NQVhfVkFMVUV9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTb2NrZXQgcyA9IHNmLmNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgc3BvcnQpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChzKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhaWxlZCB0byBjcmVhdGUgc29ja2V0Iiwgcy5nZXRQb3J0KCkgPT0gc3BvcnQpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFBvcnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFNvY2tldCBzID0gc2YuY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBpbnZhbGlkUG9ydHNbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIGZvciAiICsgaW52YWxpZFBvcnRzW2ldKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBmb3IgIiArIGludmFsaWRQb3J0c1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU29ja2V0IHMgPSBzZi5jcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHBvcnROdW1iZXIpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIFNvY2tldEZhY3RvcnkgZiA9IFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU29ja2V0IHMgPSBmLmNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgODA4MSk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIC4uLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuU29ja2V0RmFjdG9yeSNjcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MgYWRkcmVzcywgaW50IHBvcnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbEFkZHJlc3MsIGludCBsb2NhbFBvcnQpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF9jcmVhdGVTb2NrZXRfMDQoKSB7CisgICAgICAgIFNvY2tldEZhY3Rvcnkgc2YgPSBTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgIGludCBzcG9ydCA9IHN0YXJ0U2VydmVyKCJDb25zIEluZXRBZGRyZXNzLEksSW5ldEFkZHJlc3MsSSIpOworICAgICAgICBpbnRbXSBpbnZhbGlkUG9ydHMgPSB7SW50ZWdlci5NSU5fVkFMVUUsIC0xLCA2NTUzNiwgSW50ZWdlci5NQVhfVkFMVUV9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTb2NrZXQgcyA9IHNmLmNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgc3BvcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgcG9ydE51bWJlcik7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHMpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiMTogRmFpbGVkIHRvIGNyZWF0ZSBzb2NrZXQiLCBzLmdldFBvcnQoKSA9PSBzcG9ydCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCIyOiBGYWlsZWQgdG8gY3JlYXRlIHNvY2tldCIsIHMuZ2V0TG9jYWxQb3J0KCkgPT0gcG9ydE51bWJlcik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkUG9ydHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgU29ja2V0IHMgPSBzZi5jcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIGludmFsaWRQb3J0c1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgcG9ydE51bWJlcik7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24gZm9yICIgKyBpbnZhbGlkUG9ydHNbaV0pOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGZvciAiICsgaW52YWxpZFBvcnRzW2ldKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTb2NrZXQgcyA9IHNmLmNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgc3BvcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIGludmFsaWRQb3J0c1tpXSk7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24gZm9yICIgKyBpbnZhbGlkUG9ydHNbaV0pOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGZvciAiICsgaW52YWxpZFBvcnRzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTb2NrZXQgcyA9IHNmLmNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgc3BvcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgcG9ydE51bWJlcik7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgU29ja2V0RmFjdG9yeSBmID0gU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTb2NrZXQgcyA9IGYuY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCA4MDgxLCBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgODA4Mik7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIC4uLiIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuU29ja2V0RmFjdG9yeSNjcmVhdGVTb2NrZXQoU3RyaW5nIGhvc3QsIGludCBwb3J0LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MgbG9jYWxIb3N0LCBpbnQgbG9jYWxQb3J0KQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfY3JlYXRlU29ja2V0XzA1KCkgeworICAgICAgICBTb2NrZXRGYWN0b3J5IHNmID0gU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCk7CisgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICBpbnQgc3BvcnQgPSBzdGFydFNlcnZlcigiQ29ucyBTdHJpbmcsSSxJbmV0QWRkcmVzcyxJIik7CisgICAgICAgIGludFtdIGludmFsaWRQb3J0cyA9IHtJbnRlZ2VyLk1JTl9WQUxVRSwgLTEsIDY1NTM2LCBJbnRlZ2VyLk1BWF9WQUxVRX07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldCBzID0gc2YuY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLmdldEhvc3ROYW1lKCksIHNwb3J0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHBvcnROdW1iZXIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChzKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIjE6IEZhaWxlZCB0byBjcmVhdGUgc29ja2V0Iiwgcy5nZXRQb3J0KCkgPT0gc3BvcnQpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiMjogRmFpbGVkIHRvIGNyZWF0ZSBzb2NrZXQiLCBzLmdldExvY2FsUG9ydCgpID09IHBvcnROdW1iZXIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTb2NrZXQgcyA9IHNmLmNyZWF0ZVNvY2tldCgiYmxhLWJsYSIsIHNwb3J0LCBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgcG9ydE51bWJlcik7CisgICAgICAgICAgICBmYWlsKCJVbmtub3duSG9zdEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFVua25vd25Ib3N0RXhjZXB0aW9uIHVoZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgVW5rbm93bkhvc3RFeGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFBvcnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTb2NrZXQgcyA9IHNmLmNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKS5nZXRIb3N0TmFtZSgpLCBpbnZhbGlkUG9ydHNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHBvcnROdW1iZXIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIGZvciAiICsgaW52YWxpZFBvcnRzW2ldKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBmb3IgIiArIGludmFsaWRQb3J0c1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFNvY2tldCBzID0gc2YuY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLmdldEhvc3ROYW1lKCksIHNwb3J0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBpbnZhbGlkUG9ydHNbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIGZvciAiICsgaW52YWxpZFBvcnRzW2ldKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBmb3IgIiArIGludmFsaWRQb3J0c1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBTb2NrZXRGYWN0b3J5IGYgPSBTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldCBzID0gZi5jcmVhdGVTb2NrZXQoImxvY2FsaG9zdCIsIDgwODEsIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCA4MDgyKTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHdhc24ndCB0aHJvd24gLi4uIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5I2dldERlZmF1bHQoKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfZ2V0RGVmYXVsdCgpIHsKKyAgICAgICAgU29ja2V0RmFjdG9yeSBzZiA9IFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworICAgICAgICBTb2NrZXQgczsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMgPSBzZi5jcmVhdGVTb2NrZXQoImxvY2FsaG9zdCIsIDgwODIpOworICAgICAgICAgICAgcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMgPSBzZi5jcmVhdGVTb2NrZXQoImxvY2FsaG9zdCIsIDgwODEsIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCA4MDgyKTsKKyAgICAgICAgICAgIHMuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzID0gc2YuY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCA4MDgxKTsKKyAgICAgICAgICAgIHMuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzID0gc2YuY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCA4MDgxLCBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgODA4Mik7CisgICAgICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCBpbnQgc3RhcnRTZXJ2ZXIoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgIFNlcnZlclNvY2tldCBzcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzcyA9IG5ldyBTZXJ2ZXJTb2NrZXQocG9ydE51bWJlcik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwobmFtZSArICI6ICIgKyBlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3MuZ2V0TG9jYWxQb3J0KCk7CisgICAgfQorfQorCitjbGFzcyBNeVNvY2tldEZhY3RvcnkgZXh0ZW5kcyBTb2NrZXRGYWN0b3J5IHsKKworICAgIHB1YmxpYyBNeVNvY2tldEZhY3RvcnkoKSB7CisgICAgICAgIHN1cGVyKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoU3RyaW5nIGhvc3QsIGludCBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24sIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoU3RyaW5nIGhvc3QsIGludCBwb3J0LCBJbmV0QWRkcmVzcyBsb2NhbEhvc3QsIGludCBsb2NhbFBvcnQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MgaG9zdCwgaW50IHBvcnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcyBhZGRyZXNzLCBpbnQgcG9ydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbEFkZHJlc3MsIGludCBsb2NhbFBvcnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9DZXJ0UGF0aFRydXN0TWFuYWdlclBhcmFtZXRlcnNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvQ2VydFBhdGhUcnVzdE1hbmFnZXJQYXJhbWV0ZXJzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQxNDA3ZTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvQ2VydFBhdGhUcnVzdE1hbmFnZXJQYXJhbWV0ZXJzVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhQYXJhbWV0ZXJzOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuQ2VydFBhdGhUcnVzdE1hbmFnZXJQYXJhbWV0ZXJzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5DZXJ0UGF0aFRydXN0TWFuYWdlclBhcmFtZXRlcnM8L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycworICogYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgQ2VydFBhdGhUcnVzdE1hbmFnZXJQYXJhbWV0ZXJzVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuQ2VydFBhdGhUcnVzdE1hbmFnZXJQYXJhbWV0ZXJzIworICAgICAqICAgICBDZXJ0UGF0aFRydXN0TWFuYWdlclBhcmFtZXRlcnMoamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoUGFyYW1ldGVycykKKyAgICAgKiBDYXNlIDE6IFRyeSB0byBjb25zdHJ1Y3Qgb2JqZWN0LgorICAgICAqIENhc2UgMjogQ2hlY2sgTnVsbFBvaW50ZXJFeGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZhX3NlY3VyaXR5X2NlcnRfQ2VydFBhdGhQYXJhbWV0ZXJzKCkgeworICAgICAgICAvLyBjYXNlIDE6IFRyeSB0byBjb25zdHJ1Y3Qgb2JqZWN0LgorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydFBhdGhQYXJhbWV0ZXJzIHBhcmFtZXRlcnMgPSBuZXcgTXlDZXJ0UGF0aFBhcmFtZXRlcnMoKTsKKyAgICAgICAgICAgIENlcnRQYXRoVHJ1c3RNYW5hZ2VyUGFyYW1ldGVycyBwID0KKyAgICAgICAgICAgICAgICBuZXcgQ2VydFBhdGhUcnVzdE1hbmFnZXJQYXJhbWV0ZXJzKHBhcmFtZXRlcnMpOworICAgICAgICAgICAgYXNzZXJ0Tm90U2FtZSgiUGFyYW1ldGVycyB3ZXJlIGNsb25lZCBpbmNvcnJlY3RseSIsCisgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMsIHAuZ2V0UGFyYW1ldGVycygpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gY2FzZSAyOiBDaGVjayBOdWxsUG9pbnRlckV4Y2VwdGlvbi4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBDZXJ0UGF0aFRydXN0TWFuYWdlclBhcmFtZXRlcnMobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBDZXJ0UGF0aFRydXN0TWFuYWdlclBhcmFtZXRlcnMgd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5DZXJ0UGF0aFRydXN0TWFuYWdlclBhcmFtZXRlcnMjZ2V0UGFyYW1ldGVycygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQYXJhbWV0ZXJzKCkgeworICAgICAgICBDZXJ0UGF0aFBhcmFtZXRlcnMgcGFyYW1ldGVycyA9IG5ldyBNeUNlcnRQYXRoUGFyYW1ldGVycygpOworICAgICAgICBDZXJ0UGF0aFRydXN0TWFuYWdlclBhcmFtZXRlcnMgcCA9IG5ldyBDZXJ0UGF0aFRydXN0TWFuYWdlclBhcmFtZXRlcnMoCisgICAgICAgICAgICAgICAgcGFyYW1ldGVycyk7CisgICAgICAgIGlmICghKHAuZ2V0UGFyYW1ldGVycygpIGluc3RhbmNlb2YgTXlDZXJ0UGF0aFBhcmFtZXRlcnMpKSB7CisgICAgICAgICAgICBmYWlsKCJpbmNvcnJlY3QgcGFyYW1ldGVycyIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdFNhbWUoIlBhcmFtZXRlcnMgd2VyZSBjbG9uZWQgaW5jb3JyZWN0bHkiLAorICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMsIHAuZ2V0UGFyYW1ldGVycygpKTsKKyAgICB9Cit9CisKK2NsYXNzIE15Q2VydFBhdGhQYXJhbWV0ZXJzIGltcGxlbWVudHMgQ2VydFBhdGhQYXJhbWV0ZXJzIHsKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworICAgICAgICByZXR1cm4gbmV3IE15Q2VydFBhdGhQYXJhbWV0ZXJzKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL0NlcnRpZmljYXRlc1RvUGxheVdpdGguamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9DZXJ0aWZpY2F0ZXNUb1BsYXlXaXRoLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjBhZjNjMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9DZXJ0aWZpY2F0ZXNUb1BsYXlXaXRoLmphdmEKQEAgLTAsMCArMSw0NzggQEAKKy8qCisgKiAkSGVhZFVSTCQKKyAqICRSZXZpc2lvbiQKKyAqICREYXRlJAorICoKKyAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAqCisgKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQorICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCisgKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKKyAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KKyAqCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXgubmV0LnNzbDsKKworLyoqCisgKiBTb21lIFg1MDkgY2VydGlmaWNhdGVzIHRvIHRlc3QgYWdhaW5zdC4KKyAqIDxwLz4KKyAqIE5vdGU6ICBzb21lIG9mIHRoZXNlIGNlcnRpZmljYXRlcyBoYXZlIEphcGFuZXNlIEthbmppIGluIHRoZSAic3ViamVjdEFsdCIKKyAqIGZpZWxkIChVVEY4KS4gIE5vdCBzdXJlIGhvdyByZWFsaXN0aWMgdGhhdCBpcyBzaW5jZSBpbnRlcm5hdGlvbmFsIGNoYXJhY3RlcnMKKyAqIGluIEROUyBuYW1lcyB1c3VhbGx5IGdldCB0cmFuc2xhdGVkIGludG8gQVNDSUkgdXNpbmcgInhuLS0iIHN0eWxlIEROUworICogZW50cmllcy4gICJ4bi0taThzNTkyZy5jby5qcCIgaXMgd2hhdCBGaXJlRm94IGFjdHVhbGx5IHVzZXMgd2hlbiB0cnlpbmcgdG8KKyAqIGZpbmQgJiN4ODJiMTsmI3g1YjUwOy5jby5qcC4gIFNvIHdvdWxkIHRoZSBDTiBpbiB0aGUgY2VydGlmaWNhdGUgY29udGFpbgorICogInhuLS1pOHM1OTJnLmNvLmpwIiBpbiBBU0NJSSwgb3IgIiYjeDgyYjE7JiN4NWI1MDsuY28uanAiIGluIFVURjg/ICAoQm90aD8pCisgKgorICogQHNpbmNlIDExLURlYy0yMDA2CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQ2VydGlmaWNhdGVzVG9QbGF5V2l0aCB7CisKKyAgICAvKioKKyAgICAgKiBDTj1mb28uY29tCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBieXRlW10gWDUwOV9GT08gPSAoCisgICAgICAgICAgIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIiArCisgICAgICAgICAgIk1JSUVSakNDQXk2Z0F3SUJBZ0lKQUl6K0VZTUJVNmFRTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUdpTVFzd0NRWURcbiIgKworICAgICAgICAgICJWUVFHRXdKRFFURUxNQWtHQTFVRUNCTUNRa014RWpBUUJnTlZCQWNUQ1ZaaGJtTnZkWFpsY2pFV01CUUdBMVVFXG4iICsKKyAgICAgICAgICAiQ2hNTmQzZDNMbU4xWTJKakxtTnZiVEVVTUJJR0ExVUVDeFFMWTI5dGJXOXVjMTl6YzJ3eEhUQWJCZ05WQkFNVVxuIiArCisgICAgICAgICAgIkZHUmxiVzlmYVc1MFpYSnRaV1JwWVhSbFgyTmhNU1V3SXdZSktvWklodmNOQVFrQkZoWnFkV3hwZFhOa1lYWnBcbiIgKworICAgICAgICAgICJaWE5BWjIxaGFXd3VZMjl0TUI0WERUQTJNVEl4TVRFMU16RTBNVm9YRFRJNE1URXdOVEUxTXpFME1Wb3dnYVF4XG4iICsKKyAgICAgICAgICAiQ3pBSkJnTlZCQVlUQWxWVE1SRXdEd1lEVlFRSUV3aE5ZWEo1YkdGdVpERVVNQklHQTFVRUJ4TUxSbTl5WlhOMFxuIiArCisgICAgICAgICAgIklFaHBiR3d4RnpBVkJnTlZCQW9URG1oMGRIQmpiMjF3YjI1bGJuUnpNUm93R0FZRFZRUUxFeEYwWlhOMElHTmxcbiIgKworICAgICAgICAgICJjblJwWm1sallYUmxjekVRTUE0R0ExVUVBeE1IWm05dkxtTnZiVEVsTUNNR0NTcUdTSWIzRFFFSkFSWVdhblZzXG4iICsKKyAgICAgICAgICAiYVhWelpHRjJhV1Z6UUdkdFlXbHNMbU52YlRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ1xuIiArCisgICAgICAgICAgImdnRUJBTWhqcjVhQ1BveXAwUjFpcm9XQWZuRXlCTUdZV29DaWRIOTZ5R1BGallMb3dlejVhWUtZMUlPS1RZMkJcbiIgKworICAgICAgICAgICJsWWhvNE84NFgyNDRRclpUUmw4a1FiWXR4bkdoNGdTQ0QrWjhnalovZ012TFVsaHFPYitXWFBBVUhNQjM5R1J5XG4iICsKKyAgICAgICAgICAiemVyQS9adHJsVXFmK2xLbzB1V2NvY3hlUmM3NzFLTjhjUEgzbkhaMHJWMEh4NFpBWnk2VTR4eE9iZTRydFNWWVxuIiArCisgICAgICAgICAgIjA3aE5LWEFiMm9kblZxZ3pjWWlEa0xWOGlsdkVtb05XTVdycDhVQnFrVGNwRWhZaENZcDNjVGtnSndNU3VxdjhcbiIgKworICAgICAgICAgICJCcW5HZDg3eFFVM0ZWWkk0dGJ0a0IrS3pqRDl6ejhRQ0RKQWZEalpIUjAzS05RNW14T2dYd3h3S3c2bEdNYWlWXG4iICsKKyAgICAgICAgICAiSlR4cFRLcXltOTN3aFlrOTNsM29jRWU1NWMwQ0F3RUFBYU43TUhrd0NRWURWUjBUQkFJd0FEQXNCZ2xnaGtnQlxuIiArCisgICAgICAgICAgImh2aENBUTBFSHhZZFQzQmxibE5UVENCSFpXNWxjbUYwWldRZ1EyVnlkR2xtYVdOaGRHVXdIUVlEVlIwT0JCWUVcbiIgKworICAgICAgICAgICJGSjhVZDc4L09yYktPSUpDU0JZczJ0RExYb2ZZTUI4R0ExVWRJd1FZTUJhQUZIdWEybytRbVU1UzBxemJzd05TXG4iICsKKyAgICAgICAgICAieW9lbURUNE5NQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUJBUUMzalJtRXlhNnNRQ2ttaWVVTGN2eDh6ejFldUNrOVxuIiArCisgICAgICAgICAgImZTZXo3QkV0a2k4K2RtZk1YZTNLN3NIMGxJOGY0akpSMHJiU0NqcG1DUUxZbXpDM054QktlSk9XMFJjak5CcE9cbiIgKworICAgICAgICAgICJjMkpsR085YXVYdjJHRFA0SVlpWEVsTEo2VlNxYzhXdkRpa3YwSm1DQ1dtMFpnYStiWmJSL0VXTjVEZUV0RmRGXG4iICsKKyAgICAgICAgICAiODE1Q0xwSlpOY1l3aVl3R3kvQ1ZRN3cyVG5YbEcrbXJhWk96K293citjTDZKL1plc2JkRVdmam9TMStjVUVoRVxuIiArCisgICAgICAgICAgIkh3bE5yQXU4amxaMlVxU2dza1NXbGhZZE1UQVA5Q1BIaVV2OU43RmNUNThJdHYvSTRmS1JFSU5RWWpEcHZRY3hcbiIgKworICAgICAgICAgICJTYVRZYjlkcjVzQjRXTE5nbGs3enhEdE04MEg1MThWdmloVGNQN0ZITCtHbjZnNGo1ZmtJOTgrU1xuIiArCisgICAgICAgICAgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cbiIpLmdldEJ5dGVzKCk7CisKKyAgICAvKioKKyAgICAgKiBDTj0mI3g4MmIxOyYjeDViNTA7LmNvLmpwCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBieXRlW10gWDUwOV9IQU5BS08gPSAoCisgICAgICAgICAgIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIiArCisgICAgICAgICAgIk1JSUVTekNDQXpPZ0F3SUJBZ0lKQUl6K0VZTUJVNmFUTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUdpTVFzd0NRWURcbiIgKworICAgICAgICAgICJWUVFHRXdKRFFURUxNQWtHQTFVRUNCTUNRa014RWpBUUJnTlZCQWNUQ1ZaaGJtTnZkWFpsY2pFV01CUUdBMVVFXG4iICsKKyAgICAgICAgICAiQ2hNTmQzZDNMbU4xWTJKakxtTnZiVEVVTUJJR0ExVUVDeFFMWTI5dGJXOXVjMTl6YzJ3eEhUQWJCZ05WQkFNVVxuIiArCisgICAgICAgICAgIkZHUmxiVzlmYVc1MFpYSnRaV1JwWVhSbFgyTmhNU1V3SXdZSktvWklodmNOQVFrQkZoWnFkV3hwZFhOa1lYWnBcbiIgKworICAgICAgICAgICJaWE5BWjIxaGFXd3VZMjl0TUI0WERUQTJNVEl4TVRFMU5ESXhOVm9YRFRJNE1URXdOVEUxTkRJeE5Wb3dnYWt4XG4iICsKKyAgICAgICAgICAiQ3pBSkJnTlZCQVlUQWxWVE1SRXdEd1lEVlFRSURBaE5ZWEo1YkdGdVpERVVNQklHQTFVRUJ3d0xSbTl5WlhOMFxuIiArCisgICAgICAgICAgIklFaHBiR3d4RnpBVkJnTlZCQW9NRG1oMGRIQmpiMjF3YjI1bGJuUnpNUm93R0FZRFZRUUxEQkYwWlhOMElHTmxcbiIgKworICAgICAgICAgICJjblJwWm1sallYUmxjekVWTUJNR0ExVUVBd3dNNklxeDVhMlFMbU52TG1wd01TVXdJd1lKS29aSWh2Y05BUWtCXG4iICsKKyAgICAgICAgICAiRmhacWRXeHBkWE5rWVhacFpYTkFaMjFoYVd3dVkyOXRNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QVxuIiArCisgICAgICAgICAgIk1JSUJDZ0tDQVFFQXlHT3Zsb0kraktuUkhXS3VoWUIrY1RJRXdaaGFnS0owZjNySVk4V05ndWpCN1BscGdwalVcbiIgKworICAgICAgICAgICJnNHBOallHVmlHamc3emhmYmpoQ3RsTkdYeVJCdGkzR2NhSGlCSUlQNW55Q05uK0F5OHRTV0dvNXY1WmM4QlFjXG4iICsKKyAgICAgICAgICAid0hmMFpITE42c0Q5bTJ1VlNwLzZVcWpTNVp5aHpGNUZ6dnZVbzN4dzhmZWNkblN0WFFmSGhrQm5McFRqSEU1dFxuIiArCisgICAgICAgICAgIjdpdTFKVmpUdUUwcGNCdmFoMmRXcUROeGlJT1F0WHlLVzhTYWcxWXhhdW54UUdxUk55a1NGaUVKaW5keE9TQW5cbiIgKworICAgICAgICAgICJBeEs2cS93R3FjWjN6dkZCVGNWVmtqaTF1MlFINHJPTVAzUFB4QUlNa0I4T05rZEhUY28xRG1iRTZCZkRIQXJEXG4iICsKKyAgICAgICAgICAicVVZeHFKVWxQR2xNcXJLYjNmQ0ZpVDNlWGVod1I3bmx6UUlEQVFBQm8zc3dlVEFKQmdOVkhSTUVBakFBTUN3R1xuIiArCisgICAgICAgICAgIkNXQ0dTQUdHK0VJQkRRUWZGaDFQY0dWdVUxTk1JRWRsYm1WeVlYUmxaQ0JEWlhKMGFXWnBZMkYwWlRBZEJnTlZcbiIgKworICAgICAgICAgICJIUTRFRmdRVW54UjN2ejg2dHNvNGdrSklGaXphME10ZWg5Z3dId1lEVlIwakJCZ3dGb0FVZTVyYWo1Q1pUbExTXG4iICsKKyAgICAgICAgICAick51ekExTEtoNllOUGcwd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFMSjI3aTNva1YvS3ZsRHA2S01JRDNnZFxuIiArCisgICAgICAgICAgIklUbDY4UHlJdHp6eCtTcXVGOGdhaE1oMDE2Tlg3M3ovb1Zab1ZVTmRmdGxhOHdQVUIxR3dJa0FuR2toUTlMSEtcbiIgKworICAgICAgICAgICJzcEJkYlJpQ2owZ01tTENzWDhTcmpGdnI3Y1liMmNLNkovZkplOTJsMXRnLzdZNG83Vi9zNEpCZS9jeTlVOXc4XG4iICsKKyAgICAgICAgICAiYTBjdHVEbUVCQ2dDNzg0Sk1EdFQ2N2tsUmZyLzJMbHFXaGxPRXE3cFVGeFJMYmhwcXVhQUhTT2ptSWNXblZwd1xuIiArCisgICAgICAgICAgIjlCc083cWU0NmhpZGduMzloS2gxV2pLSzJWY0wvM1lSc0M0d1VpMFBCdEZXNlNjTUN1TWhnSVJYU1BVNTVSYWVcbiIgKworICAgICAgICAgICJVSWxPZFBqanIxU1VOV0dJZDFyRDdXMTZTY3B3bmtubjMxMEZOeEZNSFZJMEdUR0ZrTmRraWxOQ0ZKY0lvUkE9XG4iICsKKyAgICAgICAgICAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLVxuIikuZ2V0Qnl0ZXMoKTsKKworICAgIC8qKgorICAgICAqIENOPWZvby5jb20sIHN1YmplY3RBbHQ9YmFyLmNvbQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgYnl0ZVtdIFg1MDlfRk9PX0JBUiA9ICgKKyAgICAgICAgICAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iICsKKyAgICAgICAgICAiTUlJRVhEQ0NBMFNnQXdJQkFnSUpBSXorRVlNQlU2YVJNQTBHQ1NxR1NJYjNEUUVCQlFVQU1JR2lNUXN3Q1FZRFxuIiArCisgICAgICAgICAgIlZRUUdFd0pEUVRFTE1Ba0dBMVVFQ0JNQ1FrTXhFakFRQmdOVkJBY1RDVlpoYm1OdmRYWmxjakVXTUJRR0ExVUVcbiIgKworICAgICAgICAgICJDaE1OZDNkM0xtTjFZMkpqTG1OdmJURVVNQklHQTFVRUN4UUxZMjl0Ylc5dWMxOXpjMnd4SFRBYkJnTlZCQU1VXG4iICsKKyAgICAgICAgICAiRkdSbGJXOWZhVzUwWlhKdFpXUnBZWFJsWDJOaE1TVXdJd1lKS29aSWh2Y05BUWtCRmhacWRXeHBkWE5rWVhacFxuIiArCisgICAgICAgICAgIlpYTkFaMjFoYVd3dVkyOXRNQjRYRFRBMk1USXhNVEUxTXpZeU9Wb1hEVEk0TVRFd05URTFNell5T1Zvd2dhUXhcbiIgKworICAgICAgICAgICJDekFKQmdOVkJBWVRBbFZUTVJFd0R3WURWUVFJRXdoTllYSjViR0Z1WkRFVU1CSUdBMVVFQnhNTFJtOXlaWE4wXG4iICsKKyAgICAgICAgICAiSUVocGJHd3hGekFWQmdOVkJBb1REbWgwZEhCamIyMXdiMjVsYm5Sek1Sb3dHQVlEVlFRTEV4RjBaWE4wSUdObFxuIiArCisgICAgICAgICAgImNuUnBabWxqWVhSbGN6RVFNQTRHQTFVRUF4TUhabTl2TG1OdmJURWxNQ01HQ1NxR1NJYjNEUUVKQVJZV2FuVnNcbiIgKworICAgICAgICAgICJhWFZ6WkdGMmFXVnpRR2R0WVdsc0xtTnZiVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DXG4iICsKKyAgICAgICAgICAiZ2dFQkFNaGpyNWFDUG95cDBSMWlyb1dBZm5FeUJNR1lXb0NpZEg5NnlHUEZqWUxvd2V6NWFZS1kxSU9LVFkyQlxuIiArCisgICAgICAgICAgImxZaG80Tzg0WDI0NFFyWlRSbDhrUWJZdHhuR2g0Z1NDRCtaOGdqWi9nTXZMVWxocU9iK1dYUEFVSE1CMzlHUnlcbiIgKworICAgICAgICAgICJ6ZXJBL1p0cmxVcWYrbEtvMHVXY29jeGVSYzc3MUtOOGNQSDNuSFowclYwSHg0WkFaeTZVNHh4T2JlNHJ0U1ZZXG4iICsKKyAgICAgICAgICAiMDdoTktYQWIyb2RuVnFnemNZaURrTFY4aWx2RW1vTldNV3JwOFVCcWtUY3BFaFloQ1lwM2NUa2dKd01TdXF2OFxuIiArCisgICAgICAgICAgIkJxbkdkODd4UVUzRlZaSTR0YnRrQitLempEOXp6OFFDREpBZkRqWkhSMDNLTlE1bXhPZ1h3eHdLdzZsR01haVZcbiIgKworICAgICAgICAgICJKVHhwVEtxeW05M3doWWs5M2wzb2NFZTU1YzBDQXdFQUFhT0JrRENCalRBSkJnTlZIUk1FQWpBQU1Dd0dDV0NHXG4iICsKKyAgICAgICAgICAiU0FHRytFSUJEUVFmRmgxUGNHVnVVMU5NSUVkbGJtVnlZWFJsWkNCRFpYSjBhV1pwWTJGMFpUQWRCZ05WSFE0RVxuIiArCisgICAgICAgICAgIkZnUVVueFIzdno4NnRzbzRna0pJRml6YTBNdGVoOWd3SHdZRFZSMGpCQmd3Rm9BVWU1cmFqNUNaVGxMU3JOdXpcbiIgKworICAgICAgICAgICJBMUxLaDZZTlBnMHdFZ1lEVlIwUkJBc3dDWUlIWW1GeUxtTnZiVEFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBXG4iICsKKyAgICAgICAgICAiZFF5cHJOWkJtVm52dVZXalY0MnNleS9QVGZrWVNoSnd5MWowL2pjRlpSL3lwWlVvdnBpSEdETzFEZ0wzWTNJUFxuIiArCisgICAgICAgICAgInpWUTI2dWhVc1N3NkcwZ0dSaWFCRGUvMExVY2xYWm9KelhYMXFwUzU1T2FkeFc3M2JyemlTMHN4UmdHclpFL2RcbiIgKworICAgICAgICAgICIzZzVra2lvNklFRDQ3T1A2d1lubG1aN0VLUDljcWpXd2xudkhublVjWjJTc2NvTE5ZczlyTjljY3A4dHVxMmJ5XG4iICsKKyAgICAgICAgICAiODhPeWhLd0dqSmZoT3VkcWZUTlpjRHpSSHg0RnptN1VzVmF5Y1Z3NHVEbWhFSEpyQXNtTVBwai8rWFJLOS80MlxuIiArCisgICAgICAgICAgIjJ4cSs4YmM2SG9qZHRiQ3l1Zy9mdkJadlpxUVhTbVU4bThJVmNNbVdNejBaUU84ZWUzUWtCSE1aZkN5N1Ava3JcbiIgKworICAgICAgICAgICJWYld4L3VFVEltVXUrTlpnMjJld0V3PT1cbiIgKworICAgICAgICAgICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iKS5nZXRCeXRlcygpOworCisgICAgLyoqCisgICAgICogQ049Zm9vLmNvbSwgc3ViamVjdEFsdD1iYXIuY29tLCBzdWJqZWN0QWx0PSYjeDgyYjE7JiN4NWI1MDsuY28uanAKKyAgICAgKiAoaGFuYWtvLmNvLmpwIGluIGthbmppKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgYnl0ZVtdIFg1MDlfRk9PX0JBUl9IQU5BS08gPSAoCisgICAgICAgICAgIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIiArCisgICAgICAgICAgIk1JSUVhakNDQTFLZ0F3SUJBZ0lKQUl6K0VZTUJVNmFTTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUdpTVFzd0NRWURcbiIgKworICAgICAgICAgICJWUVFHRXdKRFFURUxNQWtHQTFVRUNCTUNRa014RWpBUUJnTlZCQWNUQ1ZaaGJtTnZkWFpsY2pFV01CUUdBMVVFXG4iICsKKyAgICAgICAgICAiQ2hNTmQzZDNMbU4xWTJKakxtTnZiVEVVTUJJR0ExVUVDeFFMWTI5dGJXOXVjMTl6YzJ3eEhUQWJCZ05WQkFNVVxuIiArCisgICAgICAgICAgIkZHUmxiVzlmYVc1MFpYSnRaV1JwWVhSbFgyTmhNU1V3SXdZSktvWklodmNOQVFrQkZoWnFkV3hwZFhOa1lYWnBcbiIgKworICAgICAgICAgICJaWE5BWjIxaGFXd3VZMjl0TUI0WERUQTJNVEl4TVRFMU16Z3hNMW9YRFRJNE1URXdOVEUxTXpneE0xb3dnYVF4XG4iICsKKyAgICAgICAgICAiQ3pBSkJnTlZCQVlUQWxWVE1SRXdEd1lEVlFRSUV3aE5ZWEo1YkdGdVpERVVNQklHQTFVRUJ4TUxSbTl5WlhOMFxuIiArCisgICAgICAgICAgIklFaHBiR3d4RnpBVkJnTlZCQW9URG1oMGRIQmpiMjF3YjI1bGJuUnpNUm93R0FZRFZRUUxFeEYwWlhOMElHTmxcbiIgKworICAgICAgICAgICJjblJwWm1sallYUmxjekVRTUE0R0ExVUVBeE1IWm05dkxtTnZiVEVsTUNNR0NTcUdTSWIzRFFFSkFSWVdhblZzXG4iICsKKyAgICAgICAgICAiYVhWelpHRjJhV1Z6UUdkdFlXbHNMbU52YlRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ1xuIiArCisgICAgICAgICAgImdnRUJBTWhqcjVhQ1BveXAwUjFpcm9XQWZuRXlCTUdZV29DaWRIOTZ5R1BGallMb3dlejVhWUtZMUlPS1RZMkJcbiIgKworICAgICAgICAgICJsWWhvNE84NFgyNDRRclpUUmw4a1FiWXR4bkdoNGdTQ0QrWjhnalovZ012TFVsaHFPYitXWFBBVUhNQjM5R1J5XG4iICsKKyAgICAgICAgICAiemVyQS9adHJsVXFmK2xLbzB1V2NvY3hlUmM3NzFLTjhjUEgzbkhaMHJWMEh4NFpBWnk2VTR4eE9iZTRydFNWWVxuIiArCisgICAgICAgICAgIjA3aE5LWEFiMm9kblZxZ3pjWWlEa0xWOGlsdkVtb05XTVdycDhVQnFrVGNwRWhZaENZcDNjVGtnSndNU3VxdjhcbiIgKworICAgICAgICAgICJCcW5HZDg3eFFVM0ZWWkk0dGJ0a0IrS3pqRDl6ejhRQ0RKQWZEalpIUjAzS05RNW14T2dYd3h3S3c2bEdNYWlWXG4iICsKKyAgICAgICAgICAiSlR4cFRLcXltOTN3aFlrOTNsM29jRWU1NWMwQ0F3RUFBYU9CbmpDQm16QUpCZ05WSFJNRUFqQUFNQ3dHQ1dDR1xuIiArCisgICAgICAgICAgIlNBR0crRUlCRFFRZkZoMVBjR1Z1VTFOTUlFZGxibVZ5WVhSbFpDQkRaWEowYVdacFkyRjBaVEFkQmdOVkhRNEVcbiIgKworICAgICAgICAgICJGZ1FVbnhSM3Z6ODZ0c280Z2tKSUZpemEwTXRlaDlnd0h3WURWUjBqQkJnd0ZvQVVlNXJhajVDWlRsTFNyTnV6XG4iICsKKyAgICAgICAgICAiQTFMS2g2WU5QZzB3SUFZRFZSMFJCQmt3RjRJSFltRnlMbU52YllJTTZJcXg1YTJRTG1OdkxtcHdNQTBHQ1NxR1xuIiArCisgICAgICAgICAgIlNJYjNEUUVCQlFVQUE0SUJBUUJlWnM3WklZeUt0ZG5WeFZ2ZExnd3lTRVBPRTRwQlNYaWk3WFl2MFE5UVV2Ry9cbiIgKworICAgICAgICAgICIrK2dGR1FoODlIaEFCekExbVZVakg1ZEpUUXFTTEZ2UmZxVEhxTHB4U3hTV3FNSG52Uk00Y1BCa0lScC9YbE1LXG4iICsKKyAgICAgICAgICAiUGxYYWRZdEpMUFRncGJndnVsQTFpY2tDOUV3bE5ZV25vd1o0dXhuZnNNZ2hXNEhza0JxYVYrUG5ROFp2eTNMMFxuIiArCisgICAgICAgICAgIjEyYzdDZzRtS0tTNXBiMUhkUnVpRDJvcForSGM3N2dSUUx2dFdOUzhqUXZkL2lUYmg2ZnV2VEtmQU9Gb1h3MjJcbiIgKworICAgICAgICAgICJzV0lLSFlybWhDSVJzaFVOb2hHWHY1MG0ybysxdzlvV21RNkRrcTdsQ2pmWGZVQjR3SWJnZ0pqcHlFdGJOcUJ0XG4iICsKKyAgICAgICAgICAiajRNQzJ4NXJmc0xLS3FUb0ttTkU3cEZFZ3F3ZTgvL0FhcjFiK1FqK1xuIiArCisgICAgICAgICAgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cbiIpLmdldEJ5dGVzKCk7CisKKyAgICAvKioKKyAgICAgKiBDTj0qLmZvby5jb20KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGJ5dGVbXSBYNTA5X1dJTERfRk9PID0gKAorICAgICAgICAgICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIgKworICAgICAgICAgICJNSUlFU0RDQ0F6Q2dBd0lCQWdJSkFJeitFWU1CVTZhVU1BMEdDU3FHU0liM0RRRUJCUVVBTUlHaU1Rc3dDUVlEXG4iICsKKyAgICAgICAgICAiVlFRR0V3SkRRVEVMTUFrR0ExVUVDQk1DUWtNeEVqQVFCZ05WQkFjVENWWmhibU52ZFhabGNqRVdNQlFHQTFVRVxuIiArCisgICAgICAgICAgIkNoTU5kM2QzTG1OMVkySmpMbU52YlRFVU1CSUdBMVVFQ3hRTFkyOXRiVzl1YzE5emMyd3hIVEFiQmdOVkJBTVVcbiIgKworICAgICAgICAgICJGR1JsYlc5ZmFXNTBaWEp0WldScFlYUmxYMk5oTVNVd0l3WUpLb1pJaHZjTkFRa0JGaFpxZFd4cGRYTmtZWFpwXG4iICsKKyAgICAgICAgICAiWlhOQVoyMWhhV3d1WTI5dE1CNFhEVEEyTVRJeE1URTJNVFUxTlZvWERUSTRNVEV3TlRFMk1UVTFOVm93Z2FZeFxuIiArCisgICAgICAgICAgIkN6QUpCZ05WQkFZVEFsVlRNUkV3RHdZRFZRUUlFd2hOWVhKNWJHRnVaREVVTUJJR0ExVUVCeE1MUm05eVpYTjBcbiIgKworICAgICAgICAgICJJRWhwYkd3eEZ6QVZCZ05WQkFvVERtaDBkSEJqYjIxd2IyNWxiblJ6TVJvd0dBWURWUVFMRXhGMFpYTjBJR05sXG4iICsKKyAgICAgICAgICAiY25ScFptbGpZWFJsY3pFU01CQUdBMVVFQXhRSktpNW1iMjh1WTI5dE1TVXdJd1lKS29aSWh2Y05BUWtCRmhacVxuIiArCisgICAgICAgICAgImRXeHBkWE5rWVhacFpYTkFaMjFoYVd3dVkyOXRNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJcbiIgKworICAgICAgICAgICJDZ0tDQVFFQXlHT3Zsb0kraktuUkhXS3VoWUIrY1RJRXdaaGFnS0owZjNySVk4V05ndWpCN1BscGdwalVnNHBOXG4iICsKKyAgICAgICAgICAiallHVmlHamc3emhmYmpoQ3RsTkdYeVJCdGkzR2NhSGlCSUlQNW55Q05uK0F5OHRTV0dvNXY1WmM4QlFjd0hmMFxuIiArCisgICAgICAgICAgIlpITE42c0Q5bTJ1VlNwLzZVcWpTNVp5aHpGNUZ6dnZVbzN4dzhmZWNkblN0WFFmSGhrQm5McFRqSEU1dDdpdTFcbiIgKworICAgICAgICAgICJKVmpUdUUwcGNCdmFoMmRXcUROeGlJT1F0WHlLVzhTYWcxWXhhdW54UUdxUk55a1NGaUVKaW5keE9TQW5BeEs2XG4iICsKKyAgICAgICAgICAicS93R3FjWjN6dkZCVGNWVmtqaTF1MlFINHJPTVAzUFB4QUlNa0I4T05rZEhUY28xRG1iRTZCZkRIQXJEcVVZeFxuIiArCisgICAgICAgICAgInFKVWxQR2xNcXJLYjNmQ0ZpVDNlWGVod1I3bmx6UUlEQVFBQm8zc3dlVEFKQmdOVkhSTUVBakFBTUN3R0NXQ0dcbiIgKworICAgICAgICAgICJTQUdHK0VJQkRRUWZGaDFQY0dWdVUxTk1JRWRsYm1WeVlYUmxaQ0JEWlhKMGFXWnBZMkYwWlRBZEJnTlZIUTRFXG4iICsKKyAgICAgICAgICAiRmdRVW54UjN2ejg2dHNvNGdrSklGaXphME10ZWg5Z3dId1lEVlIwakJCZ3dGb0FVZTVyYWo1Q1pUbExTck51elxuIiArCisgICAgICAgICAgIkExTEtoNllOUGcwd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFIMGlwRzZKNTYxVUtVZmdrZVc3R3ZZd1c5OEJcbiIgKworICAgICAgICAgICJOMVpvb1dYK0pFRVpLNytQZi85NmQzSWowcnc5QUNmTjRicGZuQ3EwVlVOWlZTWUIrR3RoUTJ6WXV6N3RmL1VZXG4iICsKKyAgICAgICAgICAiQTZueFZnUi9Jakc2OUJtc0JsOTJ1Rk83SlROdEh6dHVpUHFCbjU5cHQrdk54NHlQdm5vN3pteHNmSTdqdjB3d1xuIiArCisgICAgICAgICAgInlmcyswRk5tN0Z3ZHNDMWs0N0dCU09hR3czOGt1SVZXcVhTQWJMNEVYOUdrcnlHR09LR05oMHF2QUVOQ2RSU0JcbiIgKworICAgICAgICAgICJHOVo2dHlNYm1mUlkrZExTaDNhOUp3b0VjQlVzbzZFV1lCYWtMYnE0bkcvbnZZZFl2RzllaHJuTFZ3WkZMODJlXG4iICsKKyAgICAgICAgICAibDNRL1JLOTVibkE2Y3VSQ2xHdXNMYWQwZTZiamtCengvVlEzVmFyREVwQWtUTFVHVkFhMENMWHRueWM9XG4iICsKKyAgICAgICAgICAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLVxuIikuZ2V0Qnl0ZXMoKTsKKworICAgIC8qKgorICAgICAqIENOPSouY28uanAKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGJ5dGVbXSBYNTA5X1dJTERfQ09fSlAgPSAoCisgICAgICAgICAgIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIiArCisgICAgICAgICAgIk1JSUVSakNDQXk2Z0F3SUJBZ0lKQUl6K0VZTUJVNmFWTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUdpTVFzd0NRWURcbiIgKworICAgICAgICAgICJWUVFHRXdKRFFURUxNQWtHQTFVRUNCTUNRa014RWpBUUJnTlZCQWNUQ1ZaaGJtTnZkWFpsY2pFV01CUUdBMVVFXG4iICsKKyAgICAgICAgICAiQ2hNTmQzZDNMbU4xWTJKakxtTnZiVEVVTUJJR0ExVUVDeFFMWTI5dGJXOXVjMTl6YzJ3eEhUQWJCZ05WQkFNVVxuIiArCisgICAgICAgICAgIkZHUmxiVzlmYVc1MFpYSnRaV1JwWVhSbFgyTmhNU1V3SXdZSktvWklodmNOQVFrQkZoWnFkV3hwZFhOa1lYWnBcbiIgKworICAgICAgICAgICJaWE5BWjIxaGFXd3VZMjl0TUI0WERUQTJNVEl4TVRFMk1UWXpNRm9YRFRJNE1URXdOVEUyTVRZek1Gb3dnYVF4XG4iICsKKyAgICAgICAgICAiQ3pBSkJnTlZCQVlUQWxWVE1SRXdEd1lEVlFRSUV3aE5ZWEo1YkdGdVpERVVNQklHQTFVRUJ4TUxSbTl5WlhOMFxuIiArCisgICAgICAgICAgIklFaHBiR3d4RnpBVkJnTlZCQW9URG1oMGRIQmpiMjF3YjI1bGJuUnpNUm93R0FZRFZRUUxFeEYwWlhOMElHTmxcbiIgKworICAgICAgICAgICJjblJwWm1sallYUmxjekVRTUE0R0ExVUVBeFFIS2k1amJ5NXFjREVsTUNNR0NTcUdTSWIzRFFFSkFSWVdhblZzXG4iICsKKyAgICAgICAgICAiYVhWelpHRjJhV1Z6UUdkdFlXbHNMbU52YlRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ1xuIiArCisgICAgICAgICAgImdnRUJBTWhqcjVhQ1BveXAwUjFpcm9XQWZuRXlCTUdZV29DaWRIOTZ5R1BGallMb3dlejVhWUtZMUlPS1RZMkJcbiIgKworICAgICAgICAgICJsWWhvNE84NFgyNDRRclpUUmw4a1FiWXR4bkdoNGdTQ0QrWjhnalovZ012TFVsaHFPYitXWFBBVUhNQjM5R1J5XG4iICsKKyAgICAgICAgICAiemVyQS9adHJsVXFmK2xLbzB1V2NvY3hlUmM3NzFLTjhjUEgzbkhaMHJWMEh4NFpBWnk2VTR4eE9iZTRydFNWWVxuIiArCisgICAgICAgICAgIjA3aE5LWEFiMm9kblZxZ3pjWWlEa0xWOGlsdkVtb05XTVdycDhVQnFrVGNwRWhZaENZcDNjVGtnSndNU3VxdjhcbiIgKworICAgICAgICAgICJCcW5HZDg3eFFVM0ZWWkk0dGJ0a0IrS3pqRDl6ejhRQ0RKQWZEalpIUjAzS05RNW14T2dYd3h3S3c2bEdNYWlWXG4iICsKKyAgICAgICAgICAiSlR4cFRLcXltOTN3aFlrOTNsM29jRWU1NWMwQ0F3RUFBYU43TUhrd0NRWURWUjBUQkFJd0FEQXNCZ2xnaGtnQlxuIiArCisgICAgICAgICAgImh2aENBUTBFSHhZZFQzQmxibE5UVENCSFpXNWxjbUYwWldRZ1EyVnlkR2xtYVdOaGRHVXdIUVlEVlIwT0JCWUVcbiIgKworICAgICAgICAgICJGSjhVZDc4L09yYktPSUpDU0JZczJ0RExYb2ZZTUI4R0ExVWRJd1FZTUJhQUZIdWEybytRbVU1UzBxemJzd05TXG4iICsKKyAgICAgICAgICAieW9lbURUNE5NQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUJBUUEwc1dnbFZsTXgyek5HdlVxRkM3M1h0UkV3aWk1M1xuIiArCisgICAgICAgICAgIkNmTU02bXRmMitmM2svZDhLWGhMTnlTcmc4UlJsTjExemdtcFBhTHRiZFRMcm1HNFVkQUhIWXI4TzR5MkJCbUVcbiIgKworICAgICAgICAgICIxY3hOZkd4eGVjaGdGOEhYMTBRVjRka3l6cDZaMWNmd3ZDZU1yVDVHL1YxcGVqYWdvMGF5WHgrR1BMYldsTmVaXG4iICsKKyAgICAgICAgICAiUytLbDBtM3ArUXBsWHVqdHdHNWZZY0lwYUdwaVlyYUJMeDNUYWRpaDM5UU42NUNuQWgvelJEaExDVXpLeXQ5bFxuIiArCisgICAgICAgICAgIlVHUExFVUR6UkhNUEhMblNxVDFuNVVVNVVEUnl0YmpKUFh6RitsLytXWklzYW5lZldMc3hua2dBdVplL29NTUZcbiIgKworICAgICAgICAgICJFSk1yeUV6T2pnNFRmdWM1cU0wRVhvUGNRL0psaGVheFo0MHAySXlIcWJzV1Y0TVJZdUZINGJrTVxuIiArCisgICAgICAgICAgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cbiIpLmdldEJ5dGVzKCk7CisKKyAgICAvKioKKyAgICAgKiBDTj0qLmZvby5jb20sIHN1YmplY3RBbHQ9Ki5iYXIuY29tLCBzdWJqZWN0QWx0PSouJiN4ODJiMTsmI3g1YjUwOy5jby5qcAorICAgICAqICgqLmhhbmFrby5jby5qcCBpbiBrYW5qaSkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGJ5dGVbXSBYNTA5X1dJTERfRk9PX0JBUl9IQU5BS08gPSAoCisgICAgICAgICAgIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIiArCisgICAgICAgICAgIk1JSUVjRENDQTFpZ0F3SUJBZ0lKQUl6K0VZTUJVNmFXTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUdpTVFzd0NRWURcbiIgKworICAgICAgICAgICJWUVFHRXdKRFFURUxNQWtHQTFVRUNCTUNRa014RWpBUUJnTlZCQWNUQ1ZaaGJtTnZkWFpsY2pFV01CUUdBMVVFXG4iICsKKyAgICAgICAgICAiQ2hNTmQzZDNMbU4xWTJKakxtTnZiVEVVTUJJR0ExVUVDeFFMWTI5dGJXOXVjMTl6YzJ3eEhUQWJCZ05WQkFNVVxuIiArCisgICAgICAgICAgIkZHUmxiVzlmYVc1MFpYSnRaV1JwWVhSbFgyTmhNU1V3SXdZSktvWklodmNOQVFrQkZoWnFkV3hwZFhOa1lYWnBcbiIgKworICAgICAgICAgICJaWE5BWjIxaGFXd3VZMjl0TUI0WERUQTJNVEl4TVRFMk1UY3pNVm9YRFRJNE1URXdOVEUyTVRjek1Wb3dnYVl4XG4iICsKKyAgICAgICAgICAiQ3pBSkJnTlZCQVlUQWxWVE1SRXdEd1lEVlFRSUV3aE5ZWEo1YkdGdVpERVVNQklHQTFVRUJ4TUxSbTl5WlhOMFxuIiArCisgICAgICAgICAgIklFaHBiR3d4RnpBVkJnTlZCQW9URG1oMGRIQmpiMjF3YjI1bGJuUnpNUm93R0FZRFZRUUxFeEYwWlhOMElHTmxcbiIgKworICAgICAgICAgICJjblJwWm1sallYUmxjekVTTUJBR0ExVUVBeFFKS2k1bWIyOHVZMjl0TVNVd0l3WUpLb1pJaHZjTkFRa0JGaFpxXG4iICsKKyAgICAgICAgICAiZFd4cGRYTmtZWFpwWlhOQVoyMWhhV3d1WTI5dE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQlxuIiArCisgICAgICAgICAgIkNnS0NBUUVBeUdPdmxvSStqS25SSFdLdWhZQitjVElFd1poYWdLSjBmM3JJWThXTmd1akI3UGxwZ3BqVWc0cE5cbiIgKworICAgICAgICAgICJqWUdWaUdqZzd6aGZiamhDdGxOR1h5UkJ0aTNHY2FIaUJJSVA1bnlDTm4rQXk4dFNXR281djVaYzhCUWN3SGYwXG4iICsKKyAgICAgICAgICAiWkhMTjZzRDltMnVWU3AvNlVxalM1WnloekY1Rnp2dlVvM3h3OGZlY2RuU3RYUWZIaGtCbkxwVGpIRTV0N2l1MVxuIiArCisgICAgICAgICAgIkpWalR1RTBwY0J2YWgyZFdxRE54aUlPUXRYeUtXOFNhZzFZeGF1bnhRR3FSTnlrU0ZpRUppbmR4T1NBbkF4SzZcbiIgKworICAgICAgICAgICJxL3dHcWNaM3p2RkJUY1ZWa2ppMXUyUUg0ck9NUDNQUHhBSU1rQjhPTmtkSFRjbzFEbWJFNkJmREhBckRxVVl4XG4iICsKKyAgICAgICAgICAicUpVbFBHbE1xcktiM2ZDRmlUM2VYZWh3UjdubHpRSURBUUFCbzRHaU1JR2ZNQWtHQTFVZEV3UUNNQUF3TEFZSlxuIiArCisgICAgICAgICAgIllJWklBWWI0UWdFTkJCOFdIVTl3Wlc1VFUwd2dSMlZ1WlhKaGRHVmtJRU5sY25ScFptbGpZWFJsTUIwR0ExVWRcbiIgKworICAgICAgICAgICJEZ1FXQkJTZkZIZS9QenEyeWppQ1FrZ1dMTnJReTE2SDJEQWZCZ05WSFNNRUdEQVdnQlI3bXRxUGtKbE9VdEtzXG4iICsKKyAgICAgICAgICAiMjdNRFVzcUhwZzArRFRBa0JnTlZIUkVFSFRBYmdna3FMbUpoY2k1amIyMkNEaW91NklxeDVhMlFMbU52TG1wd1xuIiArCisgICAgICAgICAgIk1BMEdDU3FHU0liM0RRRUJCUVVBQTRJQkFRQm9iV0MrRDUvbHg2WWhYNjRDd1oyNlhManhhRTBTNDE1YWpiQnFcbiIgKworICAgICAgICAgICJESzdseitSZzd6T0UzR3NUQU1pK2xkVVluaHl6MHdEaVhCOFV3S1hsMFNEVG9CMlo0R09ncVFqQXFvTW1yUDB1XG4iICsKKyAgICAgICAgICAiV0I2WTZkcGtmZDFxRFJVekkxMjB6UFlnU2RzWGpIVzlxMkg3N2lWMjM4aHFJVTdxQ3ZFeitsZnFxV0VZNTA0elxuIiArCisgICAgICAgICAgImhZTmxrbmJVblI1MjVJdG9zRVZ3WEZCSlRrWjNZdzhnZzAyYzE5eWk4VEFoNUxpM0FkOFhRbW1TSk1XQlY0WEtcbiIgKworICAgICAgICAgICJxRnIwQUlaS0JsZzZOWlpGZi8wZFA5emNLaHpTcmlXMjdiWTBYZnpBNkdTaVJEWHJEamdYcTZiYVJUNll3Z0lnXG4iICsKKyAgICAgICAgICAicGdKc0RiSnRaZkhuVjFuZDNNNnpPdFFQbTFUSVFwTm1NTU1kL0RQckdjVVFlckQzXG4iICsKKyAgICAgICAgICAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLVxuIikuZ2V0Qnl0ZXMoKTsKKworICAgIC8qKgorICAgICAqIENOPWZvby5jb20sIENOPWJhci5jb20sIENOPSYjeDgyYjE7JiN4NWI1MDsuY28uanAKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGJ5dGVbXSBYNTA5X1RIUkVFX0NOU19GT09fQkFSX0hBTkFLTyA9ICgKKyAgICAgICAgICAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iICsKKyAgICAgICAgICAiTUlJRWJ6Q0NBMWVnQXdJQkFnSUpBSXorRVlNQlU2YVhNQTBHQ1NxR1NJYjNEUUVCQlFVQU1JR2lNUXN3Q1FZRFxuIiArCisgICAgICAgICAgIlZRUUdFd0pEUVRFTE1Ba0dBMVVFQ0JNQ1FrTXhFakFRQmdOVkJBY1RDVlpoYm1OdmRYWmxjakVXTUJRR0ExVUVcbiIgKworICAgICAgICAgICJDaE1OZDNkM0xtTjFZMkpqTG1OdmJURVVNQklHQTFVRUN4UUxZMjl0Ylc5dWMxOXpjMnd4SFRBYkJnTlZCQU1VXG4iICsKKyAgICAgICAgICAiRkdSbGJXOWZhVzUwWlhKdFpXUnBZWFJsWDJOaE1TVXdJd1lKS29aSWh2Y05BUWtCRmhacWRXeHBkWE5rWVhacFxuIiArCisgICAgICAgICAgIlpYTkFaMjFoYVd3dVkyOXRNQjRYRFRBMk1USXhNVEUyTVRrME5Wb1hEVEk0TVRFd05URTJNVGswTlZvd2djMHhcbiIgKworICAgICAgICAgICJDekFKQmdOVkJBWVRBbFZUTVJFd0R3WURWUVFJREFoTllYSjViR0Z1WkRFVU1CSUdBMVVFQnd3TFJtOXlaWE4wXG4iICsKKyAgICAgICAgICAiSUVocGJHd3hGekFWQmdOVkJBb01EbWgwZEhCamIyMXdiMjVsYm5Sek1Sb3dHQVlEVlFRTERCRjBaWE4wSUdObFxuIiArCisgICAgICAgICAgImNuUnBabWxqWVhSbGN6RVFNQTRHQTFVRUF3d0habTl2TG1OdmJURVFNQTRHQTFVRUF3d0hZbUZ5TG1OdmJURVZcbiIgKworICAgICAgICAgICJNQk1HQTFVRUF3d002SXF4NWEyUUxtTnZMbXB3TVNVd0l3WUpLb1pJaHZjTkFRa0JGaFpxZFd4cGRYTmtZWFpwXG4iICsKKyAgICAgICAgICAiWlhOQVoyMWhhV3d1WTI5dE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBeUdPdlxuIiArCisgICAgICAgICAgImxvSStqS25SSFdLdWhZQitjVElFd1poYWdLSjBmM3JJWThXTmd1akI3UGxwZ3BqVWc0cE5qWUdWaUdqZzd6aGZcbiIgKworICAgICAgICAgICJiamhDdGxOR1h5UkJ0aTNHY2FIaUJJSVA1bnlDTm4rQXk4dFNXR281djVaYzhCUWN3SGYwWkhMTjZzRDltMnVWXG4iICsKKyAgICAgICAgICAiU3AvNlVxalM1WnloekY1Rnp2dlVvM3h3OGZlY2RuU3RYUWZIaGtCbkxwVGpIRTV0N2l1MUpWalR1RTBwY0J2YVxuIiArCisgICAgICAgICAgImgyZFdxRE54aUlPUXRYeUtXOFNhZzFZeGF1bnhRR3FSTnlrU0ZpRUppbmR4T1NBbkF4SzZxL3dHcWNaM3p2RkJcbiIgKworICAgICAgICAgICJUY1ZWa2ppMXUyUUg0ck9NUDNQUHhBSU1rQjhPTmtkSFRjbzFEbWJFNkJmREhBckRxVVl4cUpVbFBHbE1xcktiXG4iICsKKyAgICAgICAgICAiM2ZDRmlUM2VYZWh3UjdubHpRSURBUUFCbzNzd2VUQUpCZ05WSFJNRUFqQUFNQ3dHQ1dDR1NBR0crRUlCRFFRZlxuIiArCisgICAgICAgICAgIkZoMVBjR1Z1VTFOTUlFZGxibVZ5WVhSbFpDQkRaWEowYVdacFkyRjBaVEFkQmdOVkhRNEVGZ1FVbnhSM3Z6ODZcbiIgKworICAgICAgICAgICJ0c280Z2tKSUZpemEwTXRlaDlnd0h3WURWUjBqQkJnd0ZvQVVlNXJhajVDWlRsTFNyTnV6QTFMS2g2WU5QZzB3XG4iICsKKyAgICAgICAgICAiRFFZSktvWklodmNOQVFFRkJRQURnZ0VCQUd1WmI4YWkxTk8yajR2M3k5VExadmQ1czB2aDUvVEU3bjdSWCs4VVxuIiArCisgICAgICAgICAgInkzN09MNWs3eDludDBtTTFUeUFLeGxDY1krOWg2ZnJ1ZThNZW1aSUlMU0l2TXJ0emNjcU56MFYxV0tnQStPcmZcbiIgKworICAgICAgICAgICJ1VXJhYm1uK0N4SEY1Z3B5NmcxUXMySWpWWVdBNWY3RlJPbi9KK0FkOGdKWWMxYXpPV0NMUXFTeWZwTlJMU3ZZXG4iICsKKyAgICAgICAgICAiRXJpUUZFVjYzWHZrSjhKckc2MmIrMk9UMmxxVDRPTzA3Z1NQZXRwcGRsU2E4TkJTS1A2QXJvOVJJWDFaalVaUVxuIiArCisgICAgICAgICAgIlNwUUZDZm8wMk5PMHVOUkRQVWRKeDJodXljZE5iK0FYSGFPN2VYZXZETEorUW5xSW1JenhXaVk2ekxPZHpqaklcbiIgKworICAgICAgICAgICJWQk1rTEhtblA3U2pHU1EzWEE0QnlyUU94Zk9VVHlMeUU3TnVlbWhIcHB1UVB4RT1cbiIgKworICAgICAgICAgICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iKS5nZXRCeXRlcygpOworCisgICAgLyoqCisgICAgICogc3ViamVjdEFsdD1mb28uY29tCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBieXRlW10gWDUwOV9OT19DTlNfRk9PID0gKAorICAgICAgICAgICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIgKworICAgICAgICAgICJNSUlFU2pDQ0F6S2dBd0lCQWdJSkFJeitFWU1CVTZhWU1BMEdDU3FHU0liM0RRRUJCUVVBTUlHaU1Rc3dDUVlEXG4iICsKKyAgICAgICAgICAiVlFRR0V3SkRRVEVMTUFrR0ExVUVDQk1DUWtNeEVqQVFCZ05WQkFjVENWWmhibU52ZFhabGNqRVdNQlFHQTFVRVxuIiArCisgICAgICAgICAgIkNoTU5kM2QzTG1OMVkySmpMbU52YlRFVU1CSUdBMVVFQ3hRTFkyOXRiVzl1YzE5emMyd3hIVEFiQmdOVkJBTVVcbiIgKworICAgICAgICAgICJGR1JsYlc5ZmFXNTBaWEp0WldScFlYUmxYMk5oTVNVd0l3WUpLb1pJaHZjTkFRa0JGaFpxZFd4cGRYTmtZWFpwXG4iICsKKyAgICAgICAgICAiWlhOQVoyMWhhV3d1WTI5dE1CNFhEVEEyTVRJeE1URTJNall4TUZvWERUSTRNVEV3TlRFMk1qWXhNRm93Z1pJeFxuIiArCisgICAgICAgICAgIkN6QUpCZ05WQkFZVEFsVlRNUkV3RHdZRFZRUUlEQWhOWVhKNWJHRnVaREVVTUJJR0ExVUVCd3dMUm05eVpYTjBcbiIgKworICAgICAgICAgICJJRWhwYkd3eEZ6QVZCZ05WQkFvTURtaDBkSEJqYjIxd2IyNWxiblJ6TVJvd0dBWURWUVFMREJGMFpYTjBJR05sXG4iICsKKyAgICAgICAgICAiY25ScFptbGpZWFJsY3pFbE1DTUdDU3FHU0liM0RRRUpBUllXYW5Wc2FYVnpaR0YyYVdWelFHZHRZV2xzTG1OdlxuIiArCisgICAgICAgICAgImJUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU1oanI1YUNQb3lwMFIxaXJvV0FcbiIgKworICAgICAgICAgICJmbkV5Qk1HWVdvQ2lkSDk2eUdQRmpZTG93ZXo1YVlLWTFJT0tUWTJCbFlobzRPODRYMjQ0UXJaVFJsOGtRYll0XG4iICsKKyAgICAgICAgICAieG5HaDRnU0NEK1o4Z2paL2dNdkxVbGhxT2IrV1hQQVVITUIzOUdSeXplckEvWnRybFVxZitsS28wdVdjb2N4ZVxuIiArCisgICAgICAgICAgIlJjNzcxS044Y1BIM25IWjByVjBIeDRaQVp5NlU0eHhPYmU0cnRTVlkwN2hOS1hBYjJvZG5WcWd6Y1lpRGtMVjhcbiIgKworICAgICAgICAgICJpbHZFbW9OV01XcnA4VUJxa1RjcEVoWWhDWXAzY1RrZ0p3TVN1cXY4QnFuR2Q4N3hRVTNGVlpJNHRidGtCK0t6XG4iICsKKyAgICAgICAgICAiakQ5eno4UUNESkFmRGpaSFIwM0tOUTVteE9nWHd4d0t3NmxHTWFpVkpUeHBUS3F5bTkzd2hZazkzbDNvY0VlNVxuIiArCisgICAgICAgICAgIjVjMENBd0VBQWFPQmtEQ0JqVEFKQmdOVkhSTUVBakFBTUN3R0NXQ0dTQUdHK0VJQkRRUWZGaDFQY0dWdVUxTk1cbiIgKworICAgICAgICAgICJJRWRsYm1WeVlYUmxaQ0JEWlhKMGFXWnBZMkYwWlRBZEJnTlZIUTRFRmdRVW54UjN2ejg2dHNvNGdrSklGaXphXG4iICsKKyAgICAgICAgICAiME10ZWg5Z3dId1lEVlIwakJCZ3dGb0FVZTVyYWo1Q1pUbExTck51ekExTEtoNllOUGcwd0VnWURWUjBSQkFzd1xuIiArCisgICAgICAgICAgIkNZSUhabTl2TG1OdmJUQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFqbDc4b01qekZkc015NkYxc0dnL0lrTzhcbiIgKworICAgICAgICAgICJ0RjV5VWdQZ0ZZcnM0MXl6QWNhN0lRdTZHOXF0RkRKei83ZWhoLzlIb0crb3FDQ0lIUHVJT21TN1NkMHdua3lKXG4iICsKKyAgICAgICAgICAiWTdZMDRqVlhJYjNhNmY2QWdCa0VGUDFuT1QwejZralQ3dmtBNUxKMnkzTWlEY1h1Uk5NU3RhNVBZVm5yWDhhWlxuIiArCisgICAgICAgICAgInlpcVZVTmk0MHBldVoyUjhtQVVTQnZXZ0Q3ejJxV2hGOFlnRGI3d1dhRmpnNTNJMzZ2V0tuOTBaRXRpM3dOQ3dcbiIgKworICAgICAgICAgICJxQVZxaXhNK0owcUptUVN0Z0FjNTNpMmFUTXZBUXUzQTNzbnZIL1BIVEJvKzVVTDcybjlTMWtaeU5Dc1ZmMVFvXG4iICsKKyAgICAgICAgICAibjhqS1RpUnJpRU0rZk1GbGNnUVAyODRFQkZ6WUh5Q1hGYjlPL2hNaksyKzZtWTlldU1CMVUxYUZGek0vQmc9PVxuIiArCisgICAgICAgICAgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cbiIpLmdldEJ5dGVzKCk7CisKKyAgICAvKioKKyAgICAgKiBJbnRlcm1lZGlhdGUgQ0EgZm9yIGFsbCBvZiB0aGVzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGJ5dGVbXSBYNTA5X0lOVEVSTUVESUFURV9DQSA9ICgKKyAgICAgICAgICAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iICsKKyAgICAgICAgICAiTUlJRW5EQ0NBNFNnQXdJQkFnSUpBSlROd1o2eU5hNWNNQTBHQ1NxR1NJYjNEUUVCQlFVQU1JR0dNUXN3Q1FZRFxuIiArCisgICAgICAgICAgIlZRUUdFd0pEUVRFTE1Ba0dBMVVFQ0JNQ1FrTXhGakFVQmdOVkJBb1REWGQzZHk1amRXTmlZeTVqYjIweEZEQVNcbiIgKworICAgICAgICAgICJCZ05WQkFzVUMyTnZiVzF2Ym5OZmMzTnNNUlV3RXdZRFZRUURGQXhrWlcxdlgzSnZiM1JmWTJFeEpUQWpCZ2txXG4iICsKKyAgICAgICAgICAiaGtpRzl3MEJDUUVXRm1wMWJHbDFjMlJoZG1sbGMwQm5iV0ZwYkM1amIyMHdIaGNOTURZeE1UQTFNakUwT1RNeFxuIiArCisgICAgICAgICAgIldoY05NRGN4TVRBMU1qRTBPVE14V2pDQm9qRUxNQWtHQTFVRUJoTUNRMEV4Q3pBSkJnTlZCQWdUQWtKRE1SSXdcbiIgKworICAgICAgICAgICJFQVlEVlFRSEV3bFdZVzVqYjNWMlpYSXhGakFVQmdOVkJBb1REWGQzZHk1amRXTmlZeTVqYjIweEZEQVNCZ05WXG4iICsKKyAgICAgICAgICAiQkFzVUMyTnZiVzF2Ym5OZmMzTnNNUjB3R3dZRFZRUURGQlJrWlcxdlgybHVkR1Z5YldWa2FXRjBaVjlqWVRFbFxuIiArCisgICAgICAgICAgIk1DTUdDU3FHU0liM0RRRUpBUllXYW5Wc2FYVnpaR0YyYVdWelFHZHRZV2xzTG1OdmJUQ0NBU0l3RFFZSktvWklcbiIgKworICAgICAgICAgICJodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUwwUzR5M3ZVTzBFTTZsd3FPRWZLOGZ2clVwcklic2lrWGFHXG4iICsKKyAgICAgICAgICAiWHplamNaK1QzbDJEYzd0OFd0QmZSZjc4aTRKeXBNcUpRU2lqclVpY2ozSDZtT01JUmVLYVhtNmxzNGhBNWQ4d1xuIiArCisgICAgICAgICAgIkxobWdpcXN6L2tXK2dBOFNlV0dXUk42ODNCRC9SYlFtek9sczZ5bkJ2YXA5alpsdGhYV0JyU0lsUENRb0JMWFlcbiIgKworICAgICAgICAgICJLVmF4R3piTDRlemFxK1hGTUtNUVNtMnVLd1ZtSEhRTmJmbVpsUHN1ZW5kQlZvbWIva2VkNTNBYjlJSDZkd3dOXG4iICsKKyAgICAgICAgICAicUpIOVdJcnZJeklWRVhXbHB2UTVNQ3Fvek03dTFha1UrRzhjYXpyOHRoZUdQQ2FZa3pvWG5pZ1d1YTRPamRwVlxuIiArCisgICAgICAgICAgIjl6NVpEa25oZkJ6RzFBamFwZEcwN0ZJaXJ3V1dnSXlaWHFaU0Q5NmlrbUx0d1QyOXFuc0NBd0VBQWFPQjdqQ0JcbiIgKworICAgICAgICAgICI2ekFkQmdOVkhRNEVGZ1FVZTVyYWo1Q1pUbExTck51ekExTEtoNllOUGcwd2dic0dBMVVkSXdTQnN6Q0JzSUFVXG4iICsKKyAgICAgICAgICAick44ZUZJdk1pUkZYWGdEcUt1bVMwL1cyQWhPaGdZeWtnWWt3Z1lZeEN6QUpCZ05WQkFZVEFrTkJNUXN3Q1FZRFxuIiArCisgICAgICAgICAgIlZRUUlFd0pDUXpFV01CUUdBMVVFQ2hNTmQzZDNMbU4xWTJKakxtTnZiVEVVTUJJR0ExVUVDeFFMWTI5dGJXOXVcbiIgKworICAgICAgICAgICJjMTl6YzJ3eEZUQVRCZ05WQkFNVURHUmxiVzlmY205dmRGOWpZVEVsTUNNR0NTcUdTSWIzRFFFSkFSWVdhblZzXG4iICsKKyAgICAgICAgICAiYVhWelpHRjJhV1Z6UUdkdFlXbHNMbU52YllJSkFKVE53WjZ5TmE1Yk1Bd0dBMVVkRXdRRk1BTUJBZjh3RFFZSlxuIiArCisgICAgICAgICAgIktvWklodmNOQVFFRkJRQURnZ0VCQUlCNEtNWnZIRDIwcGRLYWpGdE1CcEw3WDRXNHNvcTZFZVR0am1sM05ZYTlcbiIgKworICAgICAgICAgICJRYzUyYnNRRUdOY2NLWTlhZllTQkluZGFRdkZkdG16Nkhkb04rQjhUallTaHcyS2h5anRLaW1HTHBXWW9pMVlGXG4iICsKKyAgICAgICAgICAiZTRhSGRtQS9HcDV4azhwWnpSMThGbW9veEM5UnFCdXgrTkFNMmlURlNMZ0R0R0lJajRzZzJyYm42QmI2WmxRVFxuIiArCisgICAgICAgICAgIjFyZzZWdWNYQ0ExNjI5bE5mTWVOY3U3Q0JObVVLSWRheEhSL1lKUWFsbEUwS2ZHUmlPSVdQclBqL1ZOazBZQTZcbiIgKworICAgICAgICAgICJYRmcwb2NqcVhKMi9OME45cldWc2hNVWFYZ09oN200RC81emdhNS9udXhEVStQb1RvQTZtUTRiVjZlQ1lxWmJoXG4iICsKKyAgICAgICAgICAiYWExa1FZdFI5QjRaaUc2cEI4MnFWYzJkQ3FTdE9IMkZBRVdvczJnQVZrUT1cbiIgKworICAgICAgICAgICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iKS5nZXRCeXRlcygpOworCisgICAgLyoqCisgICAgICogUm9vdCBDQSBmb3IgYWxsIG9mIHRoZXNlLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgYnl0ZVtdIFg1MDlfUk9PVF9DQSA9ICgKKyAgICAgICAgICAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iICsKKyAgICAgICAgICAiTUlJRWdEQ0NBMmlnQXdJQkFnSUpBSlROd1o2eU5hNWJNQTBHQ1NxR1NJYjNEUUVCQlFVQU1JR0dNUXN3Q1FZRFxuIiArCisgICAgICAgICAgIlZRUUdFd0pEUVRFTE1Ba0dBMVVFQ0JNQ1FrTXhGakFVQmdOVkJBb1REWGQzZHk1amRXTmlZeTVqYjIweEZEQVNcbiIgKworICAgICAgICAgICJCZ05WQkFzVUMyTnZiVzF2Ym5OZmMzTnNNUlV3RXdZRFZRUURGQXhrWlcxdlgzSnZiM1JmWTJFeEpUQWpCZ2txXG4iICsKKyAgICAgICAgICAiaGtpRzl3MEJDUUVXRm1wMWJHbDFjMlJoZG1sbGMwQm5iV0ZwYkM1amIyMHdIaGNOTURZeE1UQTFNakV6TmpRelxuIiArCisgICAgICAgICAgIldoY05Nall4TVRBMU1qRXpOalF6V2pDQmhqRUxNQWtHQTFVRUJoTUNRMEV4Q3pBSkJnTlZCQWdUQWtKRE1SWXdcbiIgKworICAgICAgICAgICJGQVlEVlFRS0V3MTNkM2N1WTNWalltTXVZMjl0TVJRd0VnWURWUVFMRkF0amIyMXRiMjV6WDNOemJERVZNQk1HXG4iICsKKyAgICAgICAgICAiQTFVRUF4UU1aR1Z0YjE5eWIyOTBYMk5oTVNVd0l3WUpLb1pJaHZjTkFRa0JGaFpxZFd4cGRYTmtZWFpwWlhOQVxuIiArCisgICAgICAgICAgIloyMWhhV3d1WTI5dE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBditPbm9jbUpcbiIgKworICAgICAgICAgICI3OVVlTzJobEN3SytDbGU1dVpXblU2dXdKbCswOHo1Y3ZlYmI1dFQ2NFdMOStwc0RiZmdVSC9HbTlKc3V4S1RnXG4iICsKKyAgICAgICAgICAidzF0Wk8vNGR1SWduYUxOU3g0SG9xYVRqd2lnZC9oUjNUc29HRVBYVENrejFpa2dUQ09FRHZsK2lNaWQ2YU9yZFxuIiArCisgICAgICAgICAgIm1WaUU4SGhzY3hLWitoNUZFN29IWnl1VDZnRm9pYUlYaEZxK3hLMnc0WndEejlMK3BhaXdxeXd5VUpKTW5oOVVcbiIgKworICAgICAgICAgICJqS29yWStudWE4MU4wb3hwSWhIUHNwQ2FuRFU0bmVNekN6WU9aeUxSL0xxVjV4T1J2SGNGWTg0R1dNejVoSTI1XG4iICsKKyAgICAgICAgICAiSmJnYVdKc1lLdUNBdk5zblF3Vm9xS1BHYTd4MWZuN3g2b0dzWEphQ1Z0OHdlVXdJajJ4d2cxbHhNaHJOYWlzSFxuIiArCisgICAgICAgICAgIkV2S3BFQUVuR0d3V0tRSURBUUFCbzRIdU1JSHJNQjBHQTFVZERnUVdCQlNzM3g0VWk4eUpFVmRlQU9vcTZaTFRcbiIgKworICAgICAgICAgICI5YllDRXpDQnV3WURWUjBqQklHek1JR3dnQlNzM3g0VWk4eUpFVmRlQU9vcTZaTFQ5YllDRTZHQmpLU0JpVENCXG4iICsKKyAgICAgICAgICAiaGpFTE1Ba0dBMVVFQmhNQ1EwRXhDekFKQmdOVkJBZ1RBa0pETVJZd0ZBWURWUVFLRXcxM2QzY3VZM1ZqWW1NdVxuIiArCisgICAgICAgICAgIlkyOXRNUlF3RWdZRFZRUUxGQXRqYjIxdGIyNXpYM056YkRFVk1CTUdBMVVFQXhRTVpHVnRiMTl5YjI5MFgyTmhcbiIgKworICAgICAgICAgICJNU1V3SXdZSktvWklodmNOQVFrQkZoWnFkV3hwZFhOa1lYWnBaWE5BWjIxaGFXd3VZMjl0Z2drQWxNM0JuckkxXG4iICsKKyAgICAgICAgICAicmxzd0RBWURWUjBUQkFVd0F3RUIvekFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBbFBsMy84aDFMdHRSMXN2Q1xuIiArCisgICAgICAgICAgIlM4UlhiSHBBV0lUMkJFRGhHSFVOalNtZ0RRTmtFL2l0Zi9GQ0VYaDB0bFU0YllkdEJTT0h6ZmxibnpPeUlQSWRcbiIgKworICAgICAgICAgICJWWmVTV3MzM1YzOHhERnk2S29WZzFnVDhKeGtMbUU1UzF2V2twc0hJbHB3L1U2cjdLRDBLeDlGWXg1QWlYancwXG4iICsKKyAgICAgICAgICAibHp6L3psVk51TzJVMDlLSUR3RFBWRzFtQnpRaU1pU1dqMVUxcE00S3hJTmtXUXdEeS9mdnUvSTk4M3M4bFc1elxuIiArCisgICAgICAgICAgImhmMld1Rk56UU4zZmNNSzVkcEJFOU5WSXUyN29ZdUdZaDJzYWszNHYrN1Q3MDBXMm9vQkI3MXFGWHRtOVA1cmxcbiIgKworICAgICAgICAgICJZcDlSQ0VzZzNLRUVQTlR0Q0JzOGZST2VYdkxEclAwY21CSXF3R1lEdVJOQ3hGRFRPZGp2NllHZEE4bkxPamFIXG4iICsKKyAgICAgICAgICAiMmREazBnPT1cbiIgKworICAgICAgICAgICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iKS5nZXRCeXRlcygpOworCisgICAgLyoqCisgICAgICogQmVsb3cgaXMgdGhlIHByaXZhdGUga2V5IGZvciBhbGwgdGhlIHNlcnZlciBjZXJ0aWZpY2F0ZXMgYWJvdmUgKGJ1dAorICAgICAqIG5vdCB0aGUgaW50ZXJtZWRpYXRlIENBIG9yIHRoZSByb290IENBKS4gIEFsbCBvZiB0aG9zZSBzZXJ2ZXIgY2VydHMKKyAgICAgKiBjYW1lIGZyb20gdGhlIHNhbWUgcHJpdmF0ZSBrZXkuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgUlNBX1BVQkxJQ19NT0RVTFVTID0KKyAgICAgICAgICAiMDBjODYzYWY5NjgyM2U4Y2E5ZDExZDYyYWU4NTgwN2U3MTMyMDRjMTk4NWE4MGEyNzQ3ZjdhYzg2M2M1IiArCisgICAgICAgICAgIjhkODJlOGMxZWNmOTY5ODI5OGQ0ODM4YTRkOGQ4MTk1ODg2OGUwZWYzODVmNmUzODQyYjY1MzQ2NWYyNCIgKworICAgICAgICAgICI0MWI2MmRjNjcxYTFlMjA0ODIwZmU2N2M4MjM2N2Y4MGNiY2I1MjU4NmEzOWJmOTY1Y2YwMTQxY2MwNzciICsKKyAgICAgICAgICAiZjQ2NDcyY2RlYWMwZmQ5YjZiOTU0YTlmZmE1MmE4ZDJlNTljYTFjYzVlNDVjZWZiZDRhMzdjNzBmMWY3IiArCisgICAgICAgICAgIjljNzY3NGFkNWQwN2M3ODY0MDY3MmU5NGUzMWM0ZTZkZWUyYmI1MjU1OGQzYjg0ZDI5NzAxYmRhODc2NyIgKworICAgICAgICAgICI1NmE4MzM3MTg4ODM5MGI1N2M4YTViYzQ5YTgzNTYzMTZhZTlmMTQwNmE5MTM3MjkxMjE2MjEwOThhNzciICsKKyAgICAgICAgICAiNzEzOTIwMjcwMzEyYmFhYmZjMDZhOWM2NzdjZWYxNDE0ZGM1NTU5MjM4YjViYjY0MDdlMmIzOGMzZjczIiArCisgICAgICAgICAgImNmYzQwMjBjOTAxZjBlMzY0NzQ3NGRjYTM1MGU2NmM0ZTgxN2MzMWMwYWMzYTk0NjMxYTg5NTI1M2M2OSIgKworICAgICAgICAgICI0Y2FhYjI5YmRkZjA4NTg5M2RkZTVkZTg3MDQ3YjllNWNkIjsKKworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFJTQV9QVUJMSUNfRVhQT05FTlQgPSAiNjU1MzciOworCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgUlNBX1BSSVZBVEVfRVhQT05FTlQgPQorICAgICAgICAgICI1NzdhYmQzMjk1NTUzZDBlZmQ0ZDM4YzEzYjYyYTZkMDNmYTdiN2U0MGNjZTRmMWQ1MDcxODc3ZDk2YzYiICsKKyAgICAgICAgICAiN2EzOWE2M2YwZjdhYjIxYTg5ZGI4YWNhZTQ1NTg3YjNlZjI1MTMwOWE3MGY3NGRjMWFjMDJiZGU2OGYzIiArCisgICAgICAgICAgIjhlZDY1OGU1NGU2ODVlZDM3MGExOGMwNTQ0NDk1MTJlYTY2YTIyNTJlZDM2ZTgyYjU2NWI1MTU5ZWM4MyIgKworICAgICAgICAgICJmMjNkZjQwYWUxODk1NTBhMTgzODY1YjI1ZmQ3Nzc4OWU5NjBmMGQ4Y2VkY2Q3MmYzMmQ3YTY2ZWRiNGIiICsKKyAgICAgICAgICAiYTBhMmJhZjNmYmViNmM3ZDc1ZjU2ZWYwYWY5YTdjZmYxYzhjN2YyOTdkNzJlYWU3OTgyMTY0ZTUwYTg5IiArCisgICAgICAgICAgImQ0NTA2OThjZjU5OGQzOTM0MzIwMTA5NDI0MWQyZDE4MGE5NTg4MmE3MTExZTU4ZjRhNWJkYmM1YzEyNSIgKworICAgICAgICAgICJhOTY3ZGQ2ZWQ5ZWM2MTRjNTg1M2U4OGU0YzcxZThiNjgyYTdjZjg5Y2IxZDgyYjZmZTc4Y2M4NjUwODQiICsKKyAgICAgICAgICAiYzhjNWRmYmI1MGM5MzlkZjJiODM5Yzk3N2IwMjQ1YmZhMzYxNWUwNTkyYjUyN2IxMDEzZDViNjc1ZWNiIiArCisgICAgICAgICAgIjQ0ZTZiMzU1YzFkZjU4MWY1MDk5NzE3NTE2NmVlZjM5IjsKKworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFJTQV9QUklNRTEgPQorICAgICAgICAgICIwMGZlNzU5YzRmMGNlOGI3NjM4ODAyMTVlODI3NjdlN2E5MzcyOTc2NjhmNGU0YjFlMTE5YzZiMjJhM2MiICsKKyAgICAgICAgICAiYTJjN2IwNmM1NDdkODhkMGFhNDVmNjQ1ZDdkM2FlYWRhZjdmOGJjNTk0ZGVhZTA5Nzg1Mjk1OTI5NzdjIiArCisgICAgICAgICAgImIxZmY4OTBmMDUwMzNhOWU5ZTE1NTUxY2FkOWZiZjljNDFkMTIxMzljY2Q5OWMxYzNhYzdiMjE5N2VmZiIgKworICAgICAgICAgICIzNTBkMjM2YmI5MDBjMTQ0MDk1M2I2NDk1NmUwYTA1OGVmODI0YTJlMTY4OTRhZjE3NTE3N2M3N2RiZTEiICsKKyAgICAgICAgICAiZmVmN2Q4YjUzMjYwOGQyNTEzIjsKKworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFJTQV9QUklNRTIgPQorICAgICAgICAgICIwMGM5OWE0NTg3ODczN2E0Y2Y3M2Y5ODk2NjgwYjc1NDg3ZjFiNjY5Yjc2ODZhNmJhMDcxMDM4NTZmMzEiICsKKyAgICAgICAgICAiZGI2NjhjMmM0NDBjNDRjZGQxMTZmNzA4ZjYzMWMzN2E5YWRmMTE5ZjViNWNiNThmZmUzZGM2MmUyMGFmIiArCisgICAgICAgICAgImFmNzI2OTNkOTM2ZGM2YmIzYzUxOTQ5OTY0NjgzODljMWYwOTQwNzliODE1MjJlOTQ1NzJiNGFkN2QzOSIgKworICAgICAgICAgICI1MjkxNzhlOWI4ZWJhZWIxZjBmZGQ4M2I4NzMxYzUyMjNmMWRlYTEyNTM0MWQxZDY0OTE3ZjZiMWE2YWUiICsKKyAgICAgICAgICAiYzE4ZDMyMDUxMGQ3OWY4NTlmIjsKKworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFJTQV9FWFBPTkVOVDEgPQorICAgICAgICAgICIwMjlmZWJmMGQ0Y2Q0MWI3MDExYzI0NjViNGEyNTliZDYxMTg0ODY0NjRjMjQ3MjM2ZjQ0YTE2OWQ2MWUiICsKKyAgICAgICAgICAiNDdiOTA2MjUwOGY2NzQ1MDhkNTAzMTAwM2NlYWJjNTdlNzE0ZTYwMGQ3MWIyYzc1ZDU0NDNkYjJkYTUyIiArCisgICAgICAgICAgIjZiYjQ1YTM3NGYwNTM3YzVhMWFhYjMxNTA3NjRjZTkzY2YzODZjODQzNDZhNmJkMDFmNjczMmU0MjA3NSIgKworICAgICAgICAgICJjN2EwZTllNzhhOWU3M2I5MzRlN2Q4NzFkMGY3NTY3MzgyMDA4OWUxMjlhMTYwNDQzOGVkY2JiZWI0ZTIiICsKKyAgICAgICAgICAiMTA2NDY3ZGExMTJjZTM4OSI7CisKKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBSU0FfRVhQT05FTlQyID0KKyAgICAgICAgICAiMDA4MjdlNzY2NTBjOTQ2YWZjZDE3MDAzOGQzMmUxZjgzODZhYjAwZDZiZTc4ZDgzMGVmZTM4MmU0NWQ0IiArCisgICAgICAgICAgIjdhZDRiZDA0ZTYyMzFlZTIyZTY2NzQwZWZiZjUyODM4MTM0OTMyYzlmOGM0NjBjZGNjZGVjNThhMTQyNCIgKworICAgICAgICAgICI0NDI3ODU5MTkyZmQ2YWI2YzU4Yjc0ZTk3OTQxYjBlYWY1NzdmMmExMTcxM2FmNWU1OTUyYWYzYWUxMjQiICsKKyAgICAgICAgICAiOWE5YTg5MmU5ODQxMGRmYTI2MjhkOWFmNjY4YTQzYjUzMDJmYjdkNDk2YzliMmZlYzY5ZjU5NTI5MmI2IiArCisgICAgICAgICAgImU5OTdmMDc5YjBmNjMxNGViNyI7CisKKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBSU0FfQ09FRkZJQ0lFTlQgPQorICAgICAgICAgICIwMGU2YjYyYWRkMzUwZjFhMmE4OTY4OTAzZmY3NmMzMWNmNzAzYjBkNzMyNmM0YTYyMGFlZjAxMjI1YjciICsKKyAgICAgICAgICAiMTY0MGIzZjJlYzM3NTIwOGM1ZjcyOTk4NjNmNjAwNWI3Nzk5YjZlNTI5YmIxMTMzYzg0MzViZjVmZGI1IiArCisgICAgICAgICAgImE3ODZmNmNkOGExOWVlNzA5NGEzODRlNjU1N2M2MDBhMzg4NDVhMDk2MGRkYmZkMWRmMThkMGFmNTc0MCIgKworICAgICAgICAgICIwMDE4NTM3ODhmMWI1Y2NiZjlhZmZiNGM1MmM5ZDJlZmRiOGFhYjAxODNkODY3MzViMzI3MzdmYjRlNzkiICsKKyAgICAgICAgICAiMmI4YTljN2Q5MWM3ZDE3NWFlIjsKKworICAgIC8qKgorICAgICAqIHN1YmplY3RBbHQ9SVAgQWRkcmVzczoxMjcuMC4wLjEsIGVtYWlsOm9sZWdAdXJhbC5ydSwgRE5TOmxvY2FsaG9zdC5sb2NhbGRvbWFpbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgYnl0ZVtdIFg1MDlfTVVMVElQTEVfU1VCSkVDVF9BTFQgPSAoCisgICAgICAgICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIgKworICAgICAgICAiTUlJRGNUQ0NBdHFnQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFVRkFEQkFNUXN3Q1FZRFZRUUdFd0pEU0RFTFxuIiArCisgICAgICAgICJNQWtHQTFVRUNCTUNXa2d4RHpBTkJnTlZCQWNUQmxwMWNtbGphREVUTUJFR0ExVUVBeE1LVFhrZ1ZHVnpkQ0JEXG4iICsKKyAgICAgICAgIlFUQWVGdzB3T0RFd016RXhNVFUzTkRWYUZ3MHdPVEV3TXpFeE1UVTNORFZhTUdreEN6QUpCZ05WQkFZVEFrTklcbiIgKworICAgICAgICAiTVJBd0RnWURWUVFJRXdkVmJtdHViM2R1TVJBd0RnWURWUVFIRXdkVmJtdHViM2R1TVJBd0RnWURWUVFLRXdkVlxuIiArCisgICAgICAgICJibXR1YjNkdU1SQXdEZ1lEVlFRTEV3ZFZibXR1YjNkdU1SSXdFQVlEVlFRREV3bHNiMk5oYkdodmMzUXdnZ0c0XG4iICsKKyAgICAgICAgIk1JSUJMQVlIS29aSXpqZ0VBVENDQVI4Q2dZRUEvWDlUZ1IxMUVpbFMzMHFjTHV6azUvWVJ0MUk4NzBRQXd4NC9cbiIgKworICAgICAgICAiZ0xaUkptbEZYVUFpVWZ0WlBZMVkrci9GOWJvdzlzdWJWV3pYZ1R1QUhUUnY4bVpndDJ1WlVLV2tuNS9vQkhzUVxuIiArCisgICAgICAgICJJc0pQdTZuWC9yZkdHL2c3VitmR3FLWVZEd1Q3Zy9iVHhSN0RBalZVRTFvV2tUTDJkZk91SzJIWEt1L3lJZ01aXG4iICsKKyAgICAgICAgIm5kRklBY2NDRlFDWFlGQ1BGU01MekxLU3VZS2k2NFFMOEZnYzlRS0JnUUQzNGFDRjFwczkzc3U4cTF3MnVGZTVcbiIgKworICAgICAgICAiZVpTdnUvbzY2b0w1VjB3TFBRZUNaMUZaVjQ2NjFGbFA1bkVIRUlHQXRFa1djU1BvVENnV0U3ZlBDVEtNeUtiaFxuIiArCisgICAgICAgICJQQlo2aTFSOGpTamdvNjRlSzdPbWRaRnVvMzhMK2lFMVl2SDdZbm9CSkR2TXBQRytxRkdRaWFpRDMrRmE1WjhHXG4iICsKKyAgICAgICAgImtvdG1Yb0I3VlNWa0FVdzcvczlKS2dPQmhRQUNnWUVBNm9nQWIvWUxNMVJ6OUFvWEtXNExBNzBWdEZmN01xcXBcbiIgKworICAgICAgICAiZGl2ZHU5ZjcyV1FjMXZNS28xWU1mM2RRYWRrTWZCWVJ2QUFhMUlYRG5vaUZDSGhYblZSa1drb1VCSnlOZWJMQlxuIiArCisgICAgICAgICJOOTJDWmMwUlZGWmlNRmdRTUVoOFVsZG52QUlpNGNCazAvWXVOM0JHbDRNem1xdVZJR3JGb3ZkV0dxZWF2ZU91XG4iICsKKyAgICAgICAgIlhjdTRsS0dKTmlxak9EQTJNRFFHQTFVZEVRUXRNQ3VIQkg4QUFBR0JERzlzWldkQWRYSmhiQzV5ZFlJVmJHOWpcbiIgKworICAgICAgICAiWVd4b2IzTjBMbXh2WTJGc1pHOXRZV2x1TUEwR0NTcUdTSWIzRFFFQkJRVUFBNEdCQUlnRXdJb0NTUmtVM083S1xuIiArCisgICAgICAgICJVU1lhT1l5ZkpCOWhzdnM2WXBDbHZZWGlRLzVrUEdBUlA2MHBNNjJ2NHdDN3dJOXNoRWl6b2tJQXhZMitPM2NDXG4iICsKKyAgICAgICAgInZ3dUpoTllhYTJGSk1FTEl3Uk4zWEVTOFg4UjZKSFdiUGFSamFBQVBoY3p1RWQ4U1pZeTh5aVZMbUpUZ3cwZ0hcbiIgKworICAgICAgICAiQlNXNzc1Tkhsa2pzc2NGVmdYa05mMFBvYnFKOVxuIiArCisgICAgICAgICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tIikuZ2V0Qnl0ZXMoKTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL0hhbmRzaGFrZUNvbXBsZXRlZEV2ZW50VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL0hhbmRzaGFrZUNvbXBsZXRlZEV2ZW50VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhMDJmOWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvSGFuZHNoYWtlQ29tcGxldGVkRXZlbnRUZXN0LmphdmEKQEAgLTAsMCArMSw2MTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5BbmRyb2lkT25seTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0U29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5IYW5kc2hha2VDb21wbGV0ZWRFdmVudDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLkhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleU1hbmFnZXJGYWN0b3J5OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMQ29udGV4dDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5YNTA5VHJ1c3RNYW5hZ2VyOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBsaWJjb3JlLmlvLkJhc2U2NDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC50ZXN0cy5zdXBwb3J0Lm15U1NMU2Vzc2lvbjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfUG9ydE1hbmFnZXI7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkhhbmRzaGFrZUNvbXBsZXRlZEV2ZW50PC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgSGFuZHNoYWtlQ29tcGxldGVkRXZlbnRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgU3RyaW5nIGNlcnRpZmljYXRlID0gIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICAgICArICJNSUlDWlRDQ0FkSUNCUUwzQUFDMk1BMEdDU3FHU0liM0RRRUJBZ1VBTUY4eEN6QUpCZ05WQkFZVEFsVlRNU0F3XG4iCisgICAgICAgICsgIkhnWURWUVFLRXhkU1UwRWdSR0YwWVNCVFpXTjFjbWwwZVN3Z1NXNWpMakV1TUN3R0ExVUVDeE1sVTJWamRYSmxcbiIKKyAgICAgICAgKyAiSUZObGNuWmxjaUJEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVUQWVGdzA1TnpBeU1qQXdNREF3TURCYVxuIgorICAgICAgICArICJGdzA1T0RBeU1qQXlNelU1TlRsYU1JR1dNUXN3Q1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2XG4iCisgICAgICAgICsgImNtNXBZVEVTTUJBR0ExVUVCeE1KVUdGc2J5QkJiSFJ2TVI4d0hRWURWUVFLRXhaVGRXNGdUV2xqY205emVYTjBcbiIKKyAgICAgICAgKyAiWlcxekxDQkpibU11TVNFd0h3WURWUVFMRXhoVVpYTjBJR0Z1WkNCRmRtRnNkV0YwYVc5dUlFOXViSGt4R2pBWVxuIgorICAgICAgICArICJCZ05WQkFNVEVXRnlaMjl1TG1WdVp5NXpkVzR1WTI5dE1JR2ZNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCXG4iCisgICAgICAgICsgImlRS0JnUUNvZm1kWStQaVVXTjAxRk96RWV3ZitHYUcrbEZmMTMyVXB6QVRtWUprQTRBRUEvanVXN2pTaStMSmtcbiIKKyAgICAgICAgKyAid0pLaTVHTzRSeVpveWltQUwvNXlJV0RWNmwxS2x2eHlLc2xyMFJFaE1CYUQvM1ozRXNMVFRFZjVnVnJRUzZzVFxuIgorICAgICAgICArICJXTW9TWkF5ekIzOWtGZnNCNm9VWE50VjgrVUtLeFN4S2J4dmhRbjI2N1BlQ3o1VlgyUUlEQVFBQk1BMEdDU3FHXG4iCisgICAgICAgICsgIlNJYjNEUUVCQWdVQUEzNEFYbDNhdDZsdWlWLzdJOU1ONUNYWW9QSllJOEJjZGMxaEJhZ0p2VE1jbWxxTDJ1T1pcbiIKKyAgICAgICAgKyAiSDlUNWhOTUVMOVRrNmFJN3laUFhjdy94STJLNnBPUi9Gck1wMFV3Sm1keFg3bGpWNlp0VVpmN3BZNDkyVXF3Q1xuIgorICAgICAgICArICIxNzc3WFE5VUVaeXJLSnZGNW50bGVlTzBheUJxTEdWS0NXeldaWDlZc1hDcHY0N0ZOTFpidXBFPVxuIgorICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iOworCisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5IYW5kc2hha2VDb21wbGV0ZWRFdmVudCNIYW5kc2hha2VDb21wbGV0ZWRFdmVudChTU0xTb2NrZXQgc29jaywgU1NMU2Vzc2lvbiBzKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbXlTU0xTZXNzaW9uIHNlc3Npb24gPSBuZXcgbXlTU0xTZXNzaW9uKCk7CisgICAgICAgIFNTTFNvY2tldCBzb2NrZXQgPSAoU1NMU29ja2V0KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKS5jcmVhdGVTb2NrZXQoKTsKKyAgICAgICAgSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQgZXZlbnQgPSBuZXcgSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQoc29ja2V0LCBzZXNzaW9uKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBIYW5kc2hha2VDb21wbGV0ZWRFdmVudChudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkFueSBleGNlcHRpb24gd2Fzbid0IHRocm93biBmb3IgbnVsbCBwYXJhbWV0ZXJzIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIGphdmF4Lm5ldC5zc2wuSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQjZ2V0Q2lwaGVyU3VpdGUoKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfZ2V0Q2lwaGVyU3VpdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbXlTU0xTZXNzaW9uIHNlc3Npb24gPSBuZXcgbXlTU0xTZXNzaW9uKCJsb2NhbGhvc3QiLCAxMDgwLCBudWxsKTsKKyAgICAgICAgU1NMU29ja2V0IHNvY2tldCA9IChTU0xTb2NrZXQpIFNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpLmNyZWF0ZVNvY2tldCgpOworICAgICAgICBIYW5kc2hha2VDb21wbGV0ZWRFdmVudCBldmVudCA9IG5ldyBIYW5kc2hha2VDb21wbGV0ZWRFdmVudChzb2NrZXQsIHNlc3Npb24pOworICAgICAgICBhc3NlcnRFcXVhbHMoIlN1aXRlTmFtZSIsIGV2ZW50LmdldENpcGhlclN1aXRlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBqYXZheC5uZXQuc3NsLkhhbmRzaGFrZUNvbXBsZXRlZEV2ZW50I2dldExvY2FsQ2VydGlmaWNhdGVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X2dldExvY2FsQ2VydGlmaWNhdGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG15U1NMU2Vzc2lvbiBzZXNzaW9uID0gbmV3IG15U1NMU2Vzc2lvbigibG9jYWxob3N0IiwgMTA4MCwgbnVsbCk7CisgICAgICAgIFNTTFNvY2tldCBzb2NrZXQgPSAoU1NMU29ja2V0KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKS5jcmVhdGVTb2NrZXQoKTsKKyAgICAgICAgSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQgZXZlbnQgPSBuZXcgSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQoc29ja2V0LCBzZXNzaW9uKTsKKyAgICAgICAgYXNzZXJ0TnVsbChldmVudC5nZXRMb2NhbENlcnRpZmljYXRlcygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5IYW5kc2hha2VDb21wbGV0ZWRFdmVudCNnZXRMb2NhbFByaW5jaXBhbCgpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF9nZXRMb2NhbFByaW5jaXBhbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBteVNTTFNlc3Npb24gc2Vzc2lvbiA9IG5ldyBteVNTTFNlc3Npb24oImxvY2FsaG9zdCIsIDEwODAsIG51bGwpOworICAgICAgICBTU0xTb2NrZXQgc29ja2V0ID0gKFNTTFNvY2tldCkgU1NMU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCkuY3JlYXRlU29ja2V0KCk7CisgICAgICAgIEhhbmRzaGFrZUNvbXBsZXRlZEV2ZW50IGV2ZW50ID0gbmV3IEhhbmRzaGFrZUNvbXBsZXRlZEV2ZW50KHNvY2tldCwgc2Vzc2lvbik7CisgICAgICAgIGFzc2VydE51bGwoZXZlbnQuZ2V0TG9jYWxQcmluY2lwYWwoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIGphdmF4Lm5ldC5zc2wuSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQjZ2V0UGVlckNlcnRpZmljYXRlQ2hhaW4oKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfZ2V0UGVlckNlcnRpZmljYXRlQ2hhaW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNlcnRpZmljYXRlLmdldEJ5dGVzKCkpOworICAgICAgICBteVNTTFNlc3Npb24gc2Vzc2lvbiA9IG5ldyBteVNTTFNlc3Npb24oKFg1MDlDZXJ0aWZpY2F0ZVtdKSBudWxsKTsKKyAgICAgICAgU1NMU29ja2V0IHNvY2tldCA9IChTU0xTb2NrZXQpIFNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpLmNyZWF0ZVNvY2tldCgpOworICAgICAgICBIYW5kc2hha2VDb21wbGV0ZWRFdmVudCBldmVudCA9IG5ldyBIYW5kc2hha2VDb21wbGV0ZWRFdmVudChzb2NrZXQsIHNlc3Npb24pOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZXZlbnQuZ2V0UGVlckNlcnRpZmljYXRlQ2hhaW4oKTsKKyAgICAgICAgICAgIGZhaWwoIlNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSB4YyA9IFg1MDlDZXJ0aWZpY2F0ZS5nZXRJbnN0YW5jZShiaXMpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGVbXSB4Y3MgPSB7eGN9OworICAgICAgICBzZXNzaW9uID0gbmV3IG15U1NMU2Vzc2lvbih4Y3MpOworICAgICAgICBldmVudCA9IG5ldyBIYW5kc2hha2VDb21wbGV0ZWRFdmVudChzb2NrZXQsIHNlc3Npb24pOworCisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIHJlcyA9IGV2ZW50LmdldFBlZXJDZXJ0aWZpY2F0ZUNoYWluKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCByZXMubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5IYW5kc2hha2VDb21wbGV0ZWRFdmVudCNnZXRQZWVyQ2VydGlmaWNhdGVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X2dldFBlZXJDZXJ0aWZpY2F0ZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBteVNTTFNlc3Npb24gc2Vzc2lvbiA9IG5ldyBteVNTTFNlc3Npb24oImxvY2FsaG9zdCIsIDEwODAsIG51bGwpOworICAgICAgICBTU0xTb2NrZXQgc29ja2V0ID0gKFNTTFNvY2tldCkgU1NMU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCkuY3JlYXRlU29ja2V0KCk7CisgICAgICAgIEhhbmRzaGFrZUNvbXBsZXRlZEV2ZW50IGV2ZW50ID0gbmV3IEhhbmRzaGFrZUNvbXBsZXRlZEV2ZW50KHNvY2tldCwgc2Vzc2lvbik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBldmVudC5nZXRQZWVyQ2VydGlmaWNhdGVzKCk7CisgICAgICAgICAgICBmYWlsKCJTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBzZXNzaW9uID0gbmV3IG15U1NMU2Vzc2lvbigoWDUwOUNlcnRpZmljYXRlW10pIG51bGwpOworICAgICAgICBldmVudCA9IG5ldyBIYW5kc2hha2VDb21wbGV0ZWRFdmVudChzb2NrZXQsIHNlc3Npb24pOworICAgICAgICBDZXJ0aWZpY2F0ZVtdIHJlcyA9IGV2ZW50LmdldFBlZXJDZXJ0aWZpY2F0ZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHJlcy5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBqYXZheC5uZXQuc3NsLkhhbmRzaGFrZUNvbXBsZXRlZEV2ZW50I2dldFBlZXJQcmluY2lwYWwoKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfZ2V0UGVlclByaW5jaXBhbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG15U1NMU2Vzc2lvbiBzZXNzaW9uID0gbmV3IG15U1NMU2Vzc2lvbigibG9jYWxob3N0IiwgMTA4MCwgbnVsbCk7CisgICAgICAgIFNTTFNvY2tldCBzb2NrZXQgPSAoU1NMU29ja2V0KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKS5jcmVhdGVTb2NrZXQoKTsKKyAgICAgICAgSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQgZXZlbnQgPSBuZXcgSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQoc29ja2V0LCBzZXNzaW9uKTsKKyAgICAgICAgYXNzZXJ0TnVsbChldmVudC5nZXRQZWVyUHJpbmNpcGFsKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBqYXZheC5uZXQuc3NsLkhhbmRzaGFrZUNvbXBsZXRlZEV2ZW50I2dldFNlc3Npb24oKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfZ2V0U2Vzc2lvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG15U1NMU2Vzc2lvbiBzZXNzaW9uID0gbmV3IG15U1NMU2Vzc2lvbigibG9jYWxob3N0IiwgMTA4MCwgbnVsbCk7CisgICAgICAgIFNTTFNvY2tldCBzb2NrZXQgPSAoU1NMU29ja2V0KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKS5jcmVhdGVTb2NrZXQoKTsKKyAgICAgICAgSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQgZXZlbnQgPSBuZXcgSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQoc29ja2V0LCBzZXNzaW9uKTsKKyAgICAgICAgU1NMU2Vzc2lvbiBzcyA9IGV2ZW50LmdldFNlc3Npb24oKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzcyk7CisgICAgICAgIGFzc2VydEVxdWFscyhzZXNzaW9uLCBzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIGphdmF4Lm5ldC5zc2wuSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQjZ2V0U29ja2V0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X2dldFNvY2tldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFNTTFNvY2tldCBzb2NrZXQgPSAoU1NMU29ja2V0KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKS5jcmVhdGVTb2NrZXQoKTsKKyAgICAgICAgSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQgZXZlbnQgPSBuZXcgSGFuZHNoYWtlQ29tcGxldGVkRXZlbnQoc29ja2V0LCBudWxsKTsKKyAgICAgICAgU1NMU29ja2V0IHNzID0gZXZlbnQuZ2V0U29ja2V0KCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoc29ja2V0LCBzcyk7CisgICAgfQorCisKKyAgICAvLyBSZWdyZXNzaW9uIHRlc3QgZm9yIENvbXBsZXRlZEhhbmRzaGFrZUV2ZW50IG5vdCBmaXJpbmcgd2l0aCBhIGN1c3RvbQorICAgIC8vIFRydXN0TWFuYWdlcgorCisKKyAgICBTU0xTb2NrZXQgc29ja2V0OworICAgIFNTTFNvY2tldCBzZXJ2ZXJTb2NrZXQ7CisgICAgTXlIYW5kc2hha2VMaXN0ZW5lciBsaXN0ZW5lcjsKKyAgICBpbnQgcG9ydCA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICBTdHJpbmcgaG9zdCA9ICJsb2NhbGhvc3QiOworCisgICAgcHJpdmF0ZSBTdHJpbmcgUEFTU1dPUkQgPSAiYW5kcm9pZCI7CisKKyAgICAvKioKKyAgICAgKiBEZWZpbmVzIHRoZSBrZXlzdG9yZSBjb250ZW50cyBmb3IgdGhlIHNlcnZlciwgQktTIHZlcnNpb24uIEhvbGRzIGp1c3QgYQorICAgICAqIHNpbmdsZSBzZWxmLWdlbmVyYXRlZCBrZXkuIFRoZSBzdWJqZWN0IG5hbWUgaXMgIlRlc3QgU2VydmVyIi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VSVkVSX0tFWVNfQktTID0KKyAgICAgICAgICAgICJBQUFBQVFBQUFCUURrZWJ6b1AxWHdxeVdLUkNKRXBuL3Q4ZHFJUUFBQkRrRUFBVnRlV3RsZVFBQUFScFlsMjBuQUFBQUFRQUZXQzQxIgorICAgICAgICAgICAgKyAiTURrQUFBSk5NSUlDU1RDQ0FiS2dBd0lCQWdJRVNFZlUxakFOQmdrcWhraUc5dzBCQVFVRkFEQnBNUXN3Q1FZRFZRUUdFd0pWVXpFVCIKKyAgICAgICAgICAgICsgIk1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURU1NQW9HQTFVRUJ4TURUVlJXTVE4d0RRWURWUVFLRXdaSGIyOW5iR1V4RURBT0JnTlYiCisgICAgICAgICAgICArICJCQXNUQjBGdVpISnZhV1F4RkRBU0JnTlZCQU1UQzFSbGMzUWdVMlZ5ZG1WeU1CNFhEVEE0TURZd05URXhOVGd4TkZvWERUQTRNRGt3IgorICAgICAgICAgICAgKyAiTXpFeE5UZ3hORm93YVRFTE1Ba0dBMVVFQmhNQ1ZWTXhFekFSQmdOVkJBZ1RDa05oYkdsbWIzSnVhV0V4RERBS0JnTlZCQWNUQTAxVSIKKyAgICAgICAgICAgICsgIlZqRVBNQTBHQTFVRUNoTUdSMjl2WjJ4bE1SQXdEZ1lEVlFRTEV3ZEJibVJ5YjJsa01SUXdFZ1lEVlFRREV3dFVaWE4wSUZObGNuWmwiCisgICAgICAgICAgICArICJjakNCbnpBTkJna3Foa2lHOXcwQkFRRUZBQU9CalFBd2dZa0NnWUVBMExJZEthSXI5L3ZzVHE4QlpsQTNSK05GV1JhSDRsR3NUQVF5IgorICAgICAgICAgICAgKyAiRFBNRjlacUVET2FMNkRKdXUwY29sU0JCQlE4NWhRVFBhOW05bnlKb04zcEVpMWhnYW1xT3ZRSVdjWEJrK1NPcFVHUlpaRlh3bmlKViIKKyAgICAgICAgICAgICsgInpES1U1bkU5TVlnbjJCOUFvaUgzQ1N1TXo2SFJxZ1ZhcXRwcEllMWpodWtNYy9rSFZKdmxLUk55OVhNQ0F3RUFBVEFOQmdrcWhraUciCisgICAgICAgICAgICArICI5dzBCQVFVRkFBT0JnUUM3eUJtSjlPL2VXREd0U0g5QkgwUjNkaDJOZFNUM1c5aE5aOGhJYThVOGtsaE5IYlVDU1NrdFptWmt2YlBVIgorICAgICAgICAgICAgKyAiaHNlNUxJM2RoNlJ5TkR1cURyYll3Y3F6S2JGSmFxL2pYOWtDb2ViM3ZnYlFFbE1SWDhEMklEMXZSanh3bEFMRklTcnRhTjRWcFd6ViIKKyAgICAgICAgICAgICsgInllb0hQVzR4bGRlWm1vVnRqbjh6WE56UWhMdUJxWDJNbUFBQUFxd0FBQUFVdmtVU2Nmdzl5Q1NtQUxydVVSTm10QmFpN2tRQUFBWngiCisgICAgICAgICAgICArICI0Sm1panhzL2w4RUJhbGVhVXJ1NkVPUGlvV2tVQUVWV0N4ak0vVHhiR0hPaTJWTXNRV3FSci9EWjN3c0RtdFFndzNRVHJVSzY2NnNSIgorICAgICAgICAgICAgKyAiTUJuYnFkbnlDeXZNMUoyVjF4eExYUFVlUkJtUjJDWG9yWUdGOUR5ZTdOa2dWZGZBKzlnOUwvMEF1NlVnbisyQ2o1bGVvSWdrZ0FwTiIKKyAgICAgICAgICAgICsgInZ1RWNaZWdGbE5PVVBWRXMzU2xCZ1VGMUJZNk9CTTBVQkhUUHdHR3hGQkJjZXRjdU1SYlVudTY1dnlERzBwc2xUNTlxcGFSMFRNVnMiCisgICAgICAgICAgICArICJQK3RjaGVFemh5amJmTTMyL3Z3aG5MOWRCRWdNOHFNdDBzcUY2aXROT1FVL0Y0V0drSzJDbTJ2NENZRXlLWXczMjVmRWh6VFhvc2NrIgorICAgICAgICAgICAgKyAiTWhicW1jeUxhYjhFUGNlV0YzZHdlb1VUNzYrakVaeDhsVjJkYXBSK0NtY3pRSTQzdFY5YnRzZDF4aUJiQkhBS3Z5bW05RXA5YlB6TSIKKyAgICAgICAgICAgICsgIkowTVFpK090VVJMOUx4a2UvNzAvTVJ1ZXFiUGVVbE9hR3ZBTlRtWFFEMk9uVzdQSVN3SjlscGVMZlRHMExjcWtvcWtidExLUUxZSEkiCisgICAgICAgICAgICArICJyUWZWNWowait3bXZtcE14empOM3V2TmFqTGE0elE4bDBFb2s5U0ZhUnIyUkwwZ044UTJKZWdmT0w0cFVpSFBzaDY0V1d5YTJOQjdmIgorICAgICAgICAgICAgKyAiVisxczY1ZUE1b3NwWFlzU2hSam8wNDZRaEdUbXltd1hYemR6dXh1OElsblRFb250NlA0K0orR3NXazZjbGRHYmwyMGhjdHVVS3p5eCIKKyAgICAgICAgICAgICsgIk9wdGpFUE9LZWpWNjBpRENZR21IYkNXQXpROGg1TUlMVjgySWNsek5WaVptekFhcGVlQ25leGhwWGhXVHMreERFWVNLRWlHL2NhbXQiCisgICAgICAgICAgICArICJiaG1aYzNCY3lWSnJXMjNQa3RTZnBCUTZEOFp4b01mRjBMN1YyR1FNYVVnKzNyN3Vjcng4MmtwcW90anYweEhnaE5JbTk1YUJyMVF3IgorICAgICAgICAgICAgKyAiMWdhRWpzQy8wd0dtbUJEZzFkVERIK0YxcDlUSW56cjNFRnVZRDBZaVE3WWxBSHEzY1B1eUdvTFhKNWRYWXVTQmZoRFhKU2VkZFVrbCIKKyAgICAgICAgICAgICsgImsxdWZaeU9PY3NrZUluUWdlN2p6YVJmbUtnM1U5NHIrc3BNRXZiMEF6RFFWT0t2ampvMWl2eE1TZ0ZSWmFEYi80cXc9IjsKKworICAgIC8qKgorICAgICAqIERlZmluZXMgdGhlIGtleXN0b3JlIGNvbnRlbnRzIGZvciB0aGUgc2VydmVyLCBKS1MgdmVyc2lvbi4gSG9sZHMganVzdCBhCisgICAgICogc2luZ2xlIHNlbGYtZ2VuZXJhdGVkIGtleS4gVGhlIHN1YmplY3QgbmFtZSBpcyAiVGVzdCBTZXJ2ZXIiLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRVJWRVJfS0VZU19KS1MgPQorICAgICAgICAgICAgIi91Mys3UUFBQUFJQUFBQUJBQUFBQVFBRmJYbHJaWGtBQUFFYVdGZkJlQUFBQXJvd2dnSzJNQTRHQ2lzR0FRUUJLZ0lSQVFFRkFBU0MiCisgICAgICAgICAgICArICJBcUkya3A1WGpuRjhZWmtoY0Y5MllzSk5Ra3ZzbUg3enFNTTg3ajIzelNvVjREd3lFM1hlQy9nWldxMVRvU2NJaG9xWmt6bGJXY3U0IgorICAgICAgICAgICAgKyAiVC9aZmMvRHJmR2svcktiQkwxdVdLR1o4Zk10bFprOEtvQWh4WmsxSlN5SnZka3lLeHFtelVieGsxT0ZNbE4yVkpOdTk3RlBWSCtkdSIKKyAgICAgICAgICAgICsgImR2alR2bXBkb004MUlOV0JXLzFmWkplUWVEdm40bU1iYmUwSXhncGlMbkk5V1NldmxhRFAvc20xWDNpTzl5RXl6SExMK001RXJzcG8iCisgICAgICAgICAgICArICJDd2E1NThmT3U1RGRzSUNNWGh2RFF4aldGS0ZoUEhuS3RHZStWdndrRzkvYkFhRGd4M2tmaGswdzV6dmRua0tiKzhFZDl5bE5SemRrIgorICAgICAgICAgICAgKyAib2NBYS9teGxNVE9zVHZES1hqanNCdXBOUElJajdPUDRHTm5aYXhrSmpTczk4cEVPNjdvcDFHWDJxaHk2RlNPUE51cThrLzY1SHpVYyIKKyAgICAgICAgICAgICsgIlBZbjZ2b0VlaDZ2bTAyVS9zakVuelJldlEyKzJ3WG9BZHAwRXd0US9EbE1lK052Y3dQR1dLdU1nWDRBNEw5M0RaR2IwNE4yVm1BVTMiCisgICAgICAgICAgICArICJZTE90WndUTzBMYnVXcmNDTS9xOTlHLzdMY2N6a3hJVnJPMkkvcmg4UlhWY3psZjlRemNyRk9iRnY0QVR1c3BXSjh4RzdEaHNNYm5rIgorICAgICAgICAgICAgKyAiclQ5NFBxNlRvZ1llb3o4bzhaTXlrZXNBcU42bXQvOStUb0llbW1YditlK0tVMWhJNW9Md1dNblVHNmRYTTZoSXZyVUxZNm8rUUNQSCIKKyAgICAgICAgICAgICsgIjE3MllRSk1hKzY4SEFlUytpdEJUQUY0Q2xtL2JMbjZyZUhDR0dVNnZOZHdVMGxZbGRwaU9qOWNCM3QrdTJVdUxvNnRpRldqTGY1WnMiCisgICAgICAgICAgICArICJFUUpFVGQ0Zy9FSzluSHhKbjBHQUtyV25UdzdwRUhRSjA4ZWx6VXV5MDRDL2pFRUcrNFFYVTFJbnpTNG8va1IwU3F6MldUR0RvU29xIgorICAgICAgICAgICAgKyAiZXd1UFJVNWJ6UXMvYjlkYXEzbVhyblB0UkJMNkhmU0RBZHBUSzc2aUhxTENHZHF4M2F2SGpWU0JtNHpGdkV1WUJDZXYrM2lLT0JtZyIKKyAgICAgICAgICAgICsgInloN2VRUlRqejRVT1dmeTg1b21NQnI3bEs4UHRmVkJEek9YcGFzeFMwdUJnZFV5QkRYNHRPNms5alo4YTFrbVFSUUFBQUFFQUJWZ3UiCisgICAgICAgICAgICArICJOVEE1QUFBQ1NEQ0NBa1F3Z2dHdEFnUklSOFNLTUEwR0NTcUdTSWIzRFFFQkJBVUFNR2t4Q3pBSkJnTlZCQVlUQWxWVE1STXdFUVlEIgorICAgICAgICAgICAgKyAiVlFRSUV3cERZV3hwWm05eWJtbGhNUXd3Q2dZRFZRUUhFd05OVkZZeER6QU5CZ05WQkFvVEJrZHZiMmRzWlRFUU1BNEdBMVVFQ3hNSCIKKyAgICAgICAgICAgICsgIlFXNWtjbTlwWkRFVU1CSUdBMVVFQXhNTFZHVnpkQ0JUWlhKMlpYSXdIaGNOTURnd05qQTFNVEEwT0RReVdoY05NRGd3T1RBek1UQTAiCisgICAgICAgICAgICArICJPRFF5V2pCcE1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFTU1Bb0dBMVVFQnhNRFRWUldNUTh3IgorICAgICAgICAgICAgKyAiRFFZRFZRUUtFd1pIYjI5bmJHVXhFREFPQmdOVkJBc1RCMEZ1WkhKdmFXUXhGREFTQmdOVkJBTVRDMVJsYzNRZ1UyVnlkbVZ5TUlHZiIKKyAgICAgICAgICAgICsgIk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FDd29DNmNocUNJODRyajFQclh1SmdiaWl0NEVWOTA5elI2TjBqTmxZZmciCisgICAgICAgICAgICArICJpdHdCMzliUDM5d0gwM3JGbThUNTliM21iU3B0bkdtQ0lwTFpuMjVLUFBGc1lEM0pKK3dGbG1pVWRFUDlIMDVmbGZ3dEZRSm53OXVUIgorICAgICAgICAgICAgKyAiM3JSSWRZVk1QY1EzUm9aendBTWxpR3I4ODJJMnRoSURiQTZ4akdVLzFuUklkdmswTHR4SDNRSURBUUFCTUEwR0NTcUdTSWIzRFFFQiIKKyAgICAgICAgICAgICsgIkJBVUFBNEdCQUpuKzZZZ1VsWTE4SWUrMCtWdDhvRWk4MUROaS9iZlByQVVBaDYzZmhoQmlreC8zUjlkbDN3aDA5WjZwN2NJZE54alciCisgICAgICAgICAgICArICJuMmxsK2NSVzllcUY3ejc1RjBPbW0wQzcvS0FFUGp1a1Zic3ptemVVNVZxemtwU3Qwajg0WVdpK1RmY0hScmZ2aExicmxtR0lUVnBZIgorICAgICAgICAgICAgKyAib2w1cEhMRHlxR21EczUzcGd3aXBXcXNuL25FWEVCZ2ozRW9xUGVxSGJEZjdZYVA4aC81QlN0MD0iOworCisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUga2V5c3RvcmUgY29udGVudHMgZm9yIHRoZSBjbGllbnQsIEpLUyB2ZXJzaW9uLiBIb2xkcyBqdXN0IGEKKyAgICAgKiBzaW5nbGUgc2VsZi1nZW5lcmF0ZWQga2V5LiBUaGUgc3ViamVjdCBuYW1lIGlzICJUZXN0IENsaWVudCIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENMSUVOVF9LRVlTX0pLUyA9CisgICAgICAgICAgICAiL3UzKzdRQUFBQUlBQUFBQkFBQUFBUUFGYlhsclpYa0FBQUVhV0ZoeU1BQUFBcmt3Z2dLMU1BNEdDaXNHQVFRQktnSVJBUUVGQUFTQyIKKyAgICAgICAgICAgICsgIkFxR1ZTZlhvbEJTdFp5NG5uUk5uNGZBcitTN2tmVTJCUzIzd3dXOHVCMlJ1M0d2dEx6bEs5cTA4R3ZxL0xOcUJhZmp5RlRWTDVGVjUiCisgICAgICAgICAgICArICJTRUQvOFlvbU81YTk4R3Bza1NlUnZ5dENpVEJMSmRnR2h3czVUT0dla2dJQWNCUk9QR0l5T3RKUFEwSGZPUXMrQnFnekdESHpIUWh3IgorICAgICAgICAgICAgKyAidS84VG02eVF3aVArVy8xSTlCMVFuYUV6dFpBM21oVHlNTUpzbXNGVFlyb0dnQW9nODg1RDVDbXpkOHNZR2Z4ZWMzUjZJK3hjbUJBWSIKKyAgICAgICAgICAgICsgImVpYlI1a0dwV3d0MVIrcU12UnJ0QnFoNXI2V1NLaENCTmF4K1NKVmJ0VU5SaUt5aktjY2RKZzZmR3FJV1dlaXZ3WVR5ME9oakE2YjQiCisgICAgICAgICAgICArICJOaVovWlpzNXB4RkdXVWovUmxwMFJZeThmQ0Y2YXc1LzVzNEJmNE1JNmRQU3FNRzhIZjdzSlI5MUdiY0VMeXpQZE0waDVsTmF2Z2l0IgorICAgICAgICAgICAgKyAiUVBFektldURyR3hoWTFmckpUaEJzTnNTMGd4ZXUrT2dmSlBFYi9INGxwWVg1SXZ1SUdiV0tjeG9POXpxNC9maW1JWmtkQThBKzNlWSIKKyAgICAgICAgICAgICsgIm1mRGFvd3Z5NjVOQlZRUEpTeGFPeUZoTEhmZUxxT2VDc1ZFTkFlYTAydkE3YW5kWkhUWmVodmNycXlLdG0rejhuY0hHUkMySDlIOE8iCisgICAgICAgICAgICArICJqS3dLSGZ4eHJZWS9qTUFLTGwwMCtQQmIza3NwTytCSEkyRWNRblF1TXcvenI4M09SOU1lcTRUSjBUTXVOa0FwWkVMQWVGY2tJQmJTIgorICAgICAgICAgICAgKyAickJyOE5OakFJZmp1Q1R1S0hoc1RGV2lIZms5Wkl6aWd4WGFnZmVEUml5VmM2a2hPdUYvYkdvcmoyM04ybzdSZjN1TG9VNlB5WFdpNCIKKyAgICAgICAgICAgICsgInVoY3RSMWFMNk56eERvSzJQYllDZUE5aHhiRHY4ZW1hVlBJemxWd3BQSzNSdXZ2OW1ramNPaFo3NEo4YlBLMmZRbWJwbGJPbGpjWmkiCisgICAgICAgICAgICArICJ0WmlqT2Z6Y08vMTFKcndodUpaUkE2d2FuVHFIb3VqZ0NoVjlFdWtWcm1iV0dHQWNld0ZuQXNTYkZYSWlrNy8rUXpuWGFESXQ1TmdMIgorICAgICAgICAgICAgKyAiSC9CY3o0Wi9mZFY3QWUxZVVheEtYZFBiSS8vNEorOGxpVlQvZDhhd2pXMnRsZElhRGxtR01SM2FvYzgzMCszbUFBQUFBUUFGV0M0MSIKKyAgICAgICAgICAgICsgIk1Ea0FBQUpJTUlJQ1JEQ0NBYTBDQkVoSHhMZ3dEUVlKS29aSWh2Y05BUUVFQlFBd2FURUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlYiCisgICAgICAgICAgICArICJCQWdUQ2tOaGJHbG1iM0p1YVdFeEREQUtCZ05WQkFjVEEwMVVWakVQTUEwR0ExVUVDaE1HUjI5dloyeGxNUkF3RGdZRFZRUUxFd2RCIgorICAgICAgICAgICAgKyAiYm1SeWIybGtNUlF3RWdZRFZRUURFd3RVWlhOMElFTnNhV1Z1ZERBZUZ3MHdPREEyTURVeE1EUTVNamhhRncwd09EQTVNRE14TURRNSIKKyAgICAgICAgICAgICsgIk1qaGFNR2t4Q3pBSkJnTlZCQVlUQWxWVE1STXdFUVlEVlFRSUV3cERZV3hwWm05eWJtbGhNUXd3Q2dZRFZRUUhFd05OVkZZeER6QU4iCisgICAgICAgICAgICArICJCZ05WQkFvVEJrZHZiMmRzWlRFUU1BNEdBMVVFQ3hNSFFXNWtjbTlwWkRFVU1CSUdBMVVFQXhNTFZHVnpkQ0JEYkdsbGJuUXdnWjh3IgorICAgICAgICAgICAgKyAiRFFZSktvWklodmNOQVFFQkJRQURnWTBBTUlHSkFvR0JBSUszUStLaUZibUNHZzQyMlRBbzRnZ2dkaE1INkZKaGl1ejhEeFJ5ZU1LUiIKKyAgICAgICAgICAgICsgIlVBZlA0TUswd3RjOE40MndhWjZPS3Z4cEJGVXkwQlJmQnNYMEdENEt1OTl5dTkvdGF2U2lnVHJhZUp0d1YzV1dSUmpJcWs3TDN3WDUiCisgICAgICAgICAgICArICJjbWdTMktTRDQzWTByTlVLcmtvMjZsbnQ5TjRxaVlSQlNqK3RjQU4zTHg5K3B0cWsxTEFwQWdNQkFBRXdEUVlKS29aSWh2Y05BUUVFIgorICAgICAgICAgICAgKyAiQlFBRGdZRUFOYjdRMUdWU3V5MVJQSjBGbWlYb01ZQ0N0dmxSTGttSnBod3hvdkswY0FRSzEyVmxsK3lBekJoSGlRSHkvUkExMW1uZyIKKyAgICAgICAgICAgICsgIndZdWRDN3UzUDhYL3RCVDhHUjFZazdRVzNLZ0Z5UGFmcDNsUUJCQ3JhU3NmcmpLaitkQ0xpZzF1QkxVcjRmNjhXOFZGV1pXV1RIcXAiCisgICAgICAgICAgICArICJOTUdwQ1g2cW1qYmtKUUxWSy9ZZm8xZVBhVWV4UFNPWDBHOW04K0RvVjNpeU53NmF0MDFOUnc9PSI7CisKKyAgICAvKioKKyAgICAgKiBEZWZpbmVzIHRoZSBrZXlzdG9yZSBjb250ZW50cyBmb3IgdGhlIGNsaWVudCwgQktTIHZlcnNpb24uIEhvbGRzIGp1c3QgYQorICAgICAqIHNpbmdsZSBzZWxmLWdlbmVyYXRlZCBrZXkuIFRoZSBzdWJqZWN0IG5hbWUgaXMgIlRlc3QgQ2xpZW50Ii4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0xJRU5UX0tFWVNfQktTID0KKyAgICAgICAgICAgICJBQUFBQVFBQUFCVDRSa2E2ZnhiRnBzOThZNWsyVmlsbWJpYk5rUUFBQmZRRUFBVnRlV3RsZVFBQUFScFlsK1BPQUFBQUFRQUZXQzQxIgorICAgICAgICAgICAgKyAiTURrQUFBSk5NSUlDU1RDQ0FiS2dBd0lCQWdJRVNFZlU5VEFOQmdrcWhraUc5dzBCQVFVRkFEQnBNUXN3Q1FZRFZRUUdFd0pWVXpFVCIKKyAgICAgICAgICAgICsgIk1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURU1NQW9HQTFVRUJ4TURUVlJXTVE4d0RRWURWUVFLRXdaSGIyOW5iR1V4RURBT0JnTlYiCisgICAgICAgICAgICArICJCQXNUQjBGdVpISnZhV1F4RkRBU0JnTlZCQU1UQzFSbGMzUWdRMnhwWlc1ME1CNFhEVEE0TURZd05URXhOVGcwTlZvWERUQTRNRGt3IgorICAgICAgICAgICAgKyAiTXpFeE5UZzBOVm93YVRFTE1Ba0dBMVVFQmhNQ1ZWTXhFekFSQmdOVkJBZ1RDa05oYkdsbWIzSnVhV0V4RERBS0JnTlZCQWNUQTAxVSIKKyAgICAgICAgICAgICsgIlZqRVBNQTBHQTFVRUNoTUdSMjl2WjJ4bE1SQXdEZ1lEVlFRTEV3ZEJibVJ5YjJsa01SUXdFZ1lEVlFRREV3dFVaWE4wSUVOc2FXVnUiCisgICAgICAgICAgICArICJkRENCbnpBTkJna3Foa2lHOXcwQkFRRUZBQU9CalFBd2dZa0NnWUVBcFV2bVdzUURIUHBiREtLMTNZZXoyL3E1NHRUT21SbWwvcXZhIgorICAgICAgICAgICAgKyAiMks2ZFpqa2pTVFcwaVJ1azd6dGFWRXZkSnBmVklEdjFvQnNDSTUxdHR5TEhST3kxZXBqRitHb0w3NG1KYjdma2NkMFZPb1NPVGp0RCIKKyAgICAgICAgICAgICsgIiszR2daa0hQQW01WW1VWXhpSlhxeEtLSkpxTUNUSVc0NmVKYUEybkFlcDlRSXdaMTQvTkZBczRPYlY4Q0F3RUFBVEFOQmdrcWhraUciCisgICAgICAgICAgICArICI5dzBCQVFVRkFBT0JnUUNKckNyM2haUUZEbExJZnNTS0kxL3crQkx2eWY0ZnViT2lkMHBCeGZrbFI4S0JOUFRpcWpTbXU3cGQvQy9GIgorICAgICAgICAgICAgKyAiMUZSOENkWlVEb1BmbFpIQ09VK2ZqNXI1S1VDMUh5aWdZL3RFVXZsZm9yQnBmQjB1Q0YrdFhXNERiVWZPV2hmTXRMVjRuQ09KT09aZyIKKyAgICAgICAgICAgICsgImF3ZlpMSldCSm91TEtPcDQyN3ZEZnR4VFNCK0tzOFlqbGdBQUFxd0FBQUFVK05INlR0cnpqeURkQ1htNUI2Vm83eFg1RzRZQUFBWngiCisgICAgICAgICAgICArICJFQVVrY1p0bXlrbjdZZGFZeEMxalJGSitHRUpwQzhuWlZnODNRQ2xWdUNTSVM4YTVmOEhsNDRCazRvZXBPWnNQemh0ejNSZFZ6RFZpIgorICAgICAgICAgICAgKyAiUkZmb3laRnNyazlGNWJEVFZKNnNRYmIvMW5mSmtMaFpGWG9ra2Ewdk5ENUFYTVNvRDVCajFGcWVtM2NLN2ZTVXlxS3ZGb1JLQzNYRCIKKyAgICAgICAgICAgICsgIkZRdmhxb2FtMjlGMXJibDhGYVlkUHZoaFpvOFRmWlFZVXlVS3dXK1JiUjQ0TTVpSFB4K3lraWVNZS9DLzRiY00zejhjd0liWUkxYU8iCisgICAgICAgICAgICArICJnalFLUzJNSzliczE3eGFEemVBaDRzQktyc2tGR3JEZSsyZGd2clNLZG9ha0poTFROVEJTRzZtK3J6cU1TQ2VRcGFmTEtNU2pUU1N6IgorICAgICAgICAgICAgKyAiK0tvUTliTHlheDhjYnZWaUdHanUwU2xWaHF1bG9abUtPZkhyOFR1a0lvVjY0aDN1Q0dGT1ZGdFFqQ1lET3E2TmJmUnZNaDE0VVZGNSIKKyAgICAgICAgICAgICsgInpnRElHY3pvRDlkTW9VTFd4Qm1uaUdTbnRvTmdaTStRUDZJZDdEQmFzWkdLZnJISUF3M2xIQnFjdkI1c21lbVN1N0Y0aXRSb2EzRDgiCisgICAgICAgICAgICArICJON2hoVUVLQWMreEErOE5LbVhmaUNCb0hmUEhUd0R2dDRJUjdnV2plUDNYdjV2aXRjS1EvTUFmTzVSd2Z6a1lDWFEzRmZqZnptc0UxIgorICAgICAgICAgICAgKyAiMUlmTFJEaUJqK2xoUVN1bGhSVlN0S0k4OENoZTNNNEpVTkdLbGxyYzBudDFwV2Exdmd6bVVoaEM0TFNkbTZ0clRIZ3lKbkI2T2NTOSIKKyAgICAgICAgICAgICsgInQyZnVyWWpLODhqMUF1QjQ5MjFveE14Um04YzRDcnE4UHl1ZituM1lLaThQbDJCekJ0dysrMGdqME9EbGd3dXQ4U3JWajY2L252SUIiCisgICAgICAgICAgICArICJqTjNrTFZhaFI4blpyRUZGNnZUVG15WGk3NjFwenE5eU9WcUk1N3dKR3g4bzNZZ294MXArcFdVUGwxaFFSN3JyaFViZ0svUTV3bm85IgorICAgICAgICAgICAgKyAidUprMDdoM0labk54RSsvSUtnZU1UUC9INCtqbXlUNG1oc2V4SjJCRkhlaUtGMUtUL0ZNY0pkU2krWks1eW9OVmNZdVk4YVpieDBFZiIKKyAgICAgICAgICAgICsgImxIb3JDWEFtTEZCMFc2Q3o0S1BQMDFuRDlZQkI0b2x4aUsxdDdtMEFVOXpzY2Rpdk5pdVVhQjVPSUVyK0p1WjZkTnc9IjsKKworCisgICAgLyoqCisgICAgICogSW1wbGVtZW50cyB0aGUgYWN0dWFsIHRlc3QgY2FzZS4gTGF1bmNoZXMgYSBzZXJ2ZXIgYW5kIGEgY2xpZW50LCByZXF1aXJlcworICAgICAqIGNsaWVudCBhdXRoZW50aWNhdGlvbiBhbmQgY2hlY2tzIHRoZSBjZXJ0aWZpY2F0ZXMgYWZ0ZXJ3YXJkcyAobm90IGluIHRoZQorICAgICAqIHVzdWFsIHNlbnNlLCB3ZSBqdXN0IG1ha2Ugc3VyZSB0aGF0IHdlIGdvdCB0aGUgZXhwZWN0ZWQgY2VydGlmaWNhdGVzLAorICAgICAqIGJlY2F1c2Ugb3VyIHNlbGYtc2lnbmVkIHRlc3QgY2VydGlmaWNhdGVzIGFyZSBub3QgdmFsaWQuKQorICAgICAqLworCisgICAgQEFuZHJvaWRPbmx5KCJVc2VzIGJrcyBrZXkgc3RvcmUuIENoYW5nZSB1c2VCS1MgdG8gZmFsc2UgdG8gcnVuIG9uIHRoZSBSSSIpCisgICAgcHVibGljIHZvaWQgdGVzdENsaWVudEF1dGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBib29sZWFuIHVzZUJLUyA9IHRydWU7CisKKyAgICAgICAgbGlzdGVuZXIgPSBuZXcgTXlIYW5kc2hha2VMaXN0ZW5lcigpOworICAgICAgICBTdHJpbmcgc2VydmVyS2V5cyA9ICh1c2VCS1MgPyBTRVJWRVJfS0VZU19CS1MgOiBTRVJWRVJfS0VZU19KS1MpOworICAgICAgICBTdHJpbmcgY2xpZW50S2V5cyA9ICh1c2VCS1MgPyBDTElFTlRfS0VZU19CS1MgOiBDTElFTlRfS0VZU19KS1MpOworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKHRydWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGVzdFNlcnZlci5DTElFTlRfQVVUSF9XQU5URUQsIHNlcnZlcktleXMpOworICAgICAgICBUZXN0Q2xpZW50IGNsaWVudCA9IG5ldyBUZXN0Q2xpZW50KHRydWUsIGNsaWVudEtleXMpOworCisgICAgICAgIFRocmVhZCBzZXJ2ZXJUaHJlYWQgPSBuZXcgVGhyZWFkKHNlcnZlcik7CisgICAgICAgIFRocmVhZCBjbGllbnRUaHJlYWQgPSBuZXcgVGhyZWFkKGNsaWVudCk7CisKKyAgICAgICAgc2VydmVyVGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuc2xlZXAoMzAwMCk7CisgICAgICAgIGNsaWVudFRocmVhZC5zdGFydCgpOworCisgICAgICAgIHNlcnZlclRocmVhZC5qb2luKCk7CisgICAgICAgIGNsaWVudFRocmVhZC5qb2luKCk7CisKKyAgICAgICAgLy8gVGhlIHNlcnZlciBtdXN0IGhhdmUgY29tcGxldGVkIHdpdGhvdXQgYW4gZXhjZXB0aW9uLgorICAgICAgICBFeGNlcHRpb24gZSA9IHNlcnZlci5nZXRFeGNlcHRpb24oKTsKKyAgICAgICAgaWYgKGUgIT0gbnVsbCkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRoZSBjbGllbnQgbXVzdCBoYXZlIGNvbXBsZXRlZCB3aXRob3V0IGFuIGV4Y2VwdGlvbi4KKyAgICAgICAgZSA9IGNsaWVudC5nZXRFeGNlcHRpb24oKTsKKyAgICAgICAgaWYgKGUgIT0gbnVsbCkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydE51bGwoZSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShsaXN0ZW5lci5jb21wbGV0ZURvbmUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEltcGxlbWVudHMgYSB0ZXN0IFNTTCBzb2NrZXQgc2VydmVyLiBJdCB3YWl0IGZvciBhIGNvbm5lY3Rpb24gb24gYSBnaXZlbgorICAgICAqIHBvcnQsIHJlcXVlc3RzIGNsaWVudCBhdXRoZW50aWNhdGlvbiAoaWYgc3BlY2lmaWVkKSwgcmVhZHMgMjU2IGJ5dGVzCisgICAgICogZnJvbSB0aGUgc29ja2V0LCBhbmQgd3JpdGVzIDI1NiBieXRlcyB0byB0aGUgc29ja2V0LgorICAgICAqLworICAgIGNsYXNzIFRlc3RTZXJ2ZXIgaW1wbGVtZW50cyBSdW5uYWJsZSB7CisKKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xJRU5UX0FVVEhfTk9ORSA9IDA7CisKKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xJRU5UX0FVVEhfV0FOVEVEID0gMTsKKworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTElFTlRfQVVUSF9ORUVERUQgPSAyOworCisgICAgICAgIHByaXZhdGUgVGVzdFRydXN0TWFuYWdlciB0cnVzdE1hbmFnZXI7CisKKyAgICAgICAgcHJpdmF0ZSBFeGNlcHRpb24gZXhjZXB0aW9uOworCisgICAgICAgIFN0cmluZyBrZXlzOworCisgICAgICAgIHByaXZhdGUgaW50IGNsaWVudEF1dGg7CisKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIHByb3ZpZGVLZXlzOworCisgICAgICAgIHB1YmxpYyBUZXN0U2VydmVyKGJvb2xlYW4gcHJvdmlkZUtleXMsIGludCBjbGllbnRBdXRoLCBTdHJpbmcga2V5cykgeworICAgICAgICAgICAgdGhpcy5rZXlzID0ga2V5czsKKyAgICAgICAgICAgIHRoaXMuY2xpZW50QXV0aCA9IGNsaWVudEF1dGg7CisgICAgICAgICAgICB0aGlzLnByb3ZpZGVLZXlzID0gcHJvdmlkZUtleXM7CisKKyAgICAgICAgICAgIHRydXN0TWFuYWdlciA9IG5ldyBUZXN0VHJ1c3RNYW5hZ2VyKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEtleU1hbmFnZXJbXSBrZXlNYW5hZ2VycyA9IHByb3ZpZGVLZXlzID8gZ2V0S2V5TWFuYWdlcnMoa2V5cykgOiBudWxsOworICAgICAgICAgICAgICAgIFRydXN0TWFuYWdlcltdIHRydXN0TWFuYWdlcnMgPSBuZXcgVHJ1c3RNYW5hZ2VyW10geyB0cnVzdE1hbmFnZXIgfTsKKworICAgICAgICAgICAgICAgIFNTTENvbnRleHQgc3NsQ29udGV4dCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UoIlRMUyIpOworICAgICAgICAgICAgICAgIHNzbENvbnRleHQuaW5pdChrZXlNYW5hZ2VycywgdHJ1c3RNYW5hZ2VycywgbnVsbCk7CisKKyAgICAgICAgICAgICAgICBTU0xTZXJ2ZXJTb2NrZXQgc2VydmVyU29ja2V0ID0gKFNTTFNlcnZlclNvY2tldCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHNzbENvbnRleHQuZ2V0U2VydmVyU29ja2V0RmFjdG9yeSgpLmNyZWF0ZVNlcnZlclNvY2tldCgpOworCisgICAgICAgICAgICAgICAgaWYgKGNsaWVudEF1dGggPT0gQ0xJRU5UX0FVVEhfV0FOVEVEKSB7CisgICAgICAgICAgICAgICAgICAgIHNlcnZlclNvY2tldC5zZXRXYW50Q2xpZW50QXV0aCh0cnVlKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNsaWVudEF1dGggPT0gQ0xJRU5UX0FVVEhfTkVFREVEKSB7CisgICAgICAgICAgICAgICAgICAgIHNlcnZlclNvY2tldC5zZXROZWVkQ2xpZW50QXV0aCh0cnVlKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQuc2V0V2FudENsaWVudEF1dGgoZmFsc2UpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHNlcnZlclNvY2tldC5iaW5kKG5ldyBJbmV0U29ja2V0QWRkcmVzcyhwb3J0KSk7CisKKyAgICAgICAgICAgICAgICBTU0xTb2NrZXQgY2xpZW50U29ja2V0ID0gKFNTTFNvY2tldClzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisKKyAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBpc3RyZWFtID0gY2xpZW50U29ja2V0LmdldElucHV0U3RyZWFtKCk7CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDI1NjsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGludCBqID0gaXN0cmVhbS5yZWFkKCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhpLCBqKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpc3RyZWFtLmNsb3NlKCk7CisKKyAgICAgICAgICAgICAgICBPdXRwdXRTdHJlYW0gb3N0cmVhbSA9IGNsaWVudFNvY2tldC5nZXRPdXRwdXRTdHJlYW0oKTsKKworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgb3N0cmVhbS53cml0ZShpKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBvc3RyZWFtLmZsdXNoKCk7CisgICAgICAgICAgICAgICAgb3N0cmVhbS5jbG9zZSgpOworCisgICAgICAgICAgICAgICAgY2xpZW50U29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0LmNsb3NlKCk7CisKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGV4OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEV4Y2VwdGlvbiBnZXRFeGNlcHRpb24oKSB7CisgICAgICAgICAgICByZXR1cm4gZXhjZXB0aW9uOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFg1MDlDZXJ0aWZpY2F0ZVtdIGdldENoYWluKCkgeworICAgICAgICAgICAgcmV0dXJuIHRydXN0TWFuYWdlci5nZXRDaGFpbigpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbXBsZW1lbnRzIGEgdGVzdCBTU0wgc29ja2V0IGNsaWVudC4gSXQgb3BlbiBhIGNvbm5lY3Rpb24gdG8gbG9jYWxob3N0IG9uCisgICAgICogYSBnaXZlbiBwb3J0LCB3cml0ZXMgMjU2IGJ5dGVzIHRvIHRoZSBzb2NrZXQsIGFuZCByZWFkcyAyNTYgYnl0ZXMgZnJvbSB0aGUKKyAgICAgKiBzb2NrZXQuCisgICAgICovCisgICAgY2xhc3MgVGVzdENsaWVudCBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKworICAgICAgICBwcml2YXRlIFRlc3RUcnVzdE1hbmFnZXIgdHJ1c3RNYW5hZ2VyOworCisgICAgICAgIHByaXZhdGUgRXhjZXB0aW9uIGV4Y2VwdGlvbjsKKworICAgICAgICBwcml2YXRlIFN0cmluZyBrZXlzOworCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBwcm92aWRlS2V5czsKKworICAgICAgICBwdWJsaWMgVGVzdENsaWVudChib29sZWFuIHByb3ZpZGVLZXlzLCBTdHJpbmcga2V5cykgeworICAgICAgICAgICAgdGhpcy5rZXlzID0ga2V5czsKKyAgICAgICAgICAgIHRoaXMucHJvdmlkZUtleXMgPSBwcm92aWRlS2V5czsKKworICAgICAgICAgICAgdHJ1c3RNYW5hZ2VyID0gbmV3IFRlc3RUcnVzdE1hbmFnZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5TWFuYWdlcltdIGtleU1hbmFnZXJzID0gcHJvdmlkZUtleXMgPyBnZXRLZXlNYW5hZ2VycyhrZXlzKSA6IG51bGw7CisgICAgICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyW10gdHJ1c3RNYW5hZ2VycyA9IG5ldyBUcnVzdE1hbmFnZXJbXSB7IHRydXN0TWFuYWdlciB9OworCisgICAgICAgICAgICAgICAgU1NMQ29udGV4dCBzc2xDb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZSgiVExTIik7CisgICAgICAgICAgICAgICAgc3NsQ29udGV4dC5pbml0KGtleU1hbmFnZXJzLCB0cnVzdE1hbmFnZXJzLCBudWxsKTsKKworICAgICAgICAgICAgICAgIFNTTFNvY2tldCBzb2NrZXQgPSAoU1NMU29ja2V0KXNzbENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLmNyZWF0ZVNvY2tldCgpOworCisgICAgICAgICAgICAgICAgc29ja2V0LmNvbm5lY3QobmV3IEluZXRTb2NrZXRBZGRyZXNzKHBvcnQpKTsKKyAgICAgICAgICAgICAgICBzb2NrZXQuYWRkSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXIobGlzdGVuZXIpOworICAgICAgICAgICAgICAgIHNvY2tldC5zdGFydEhhbmRzaGFrZSgpOworCisgICAgICAgICAgICAgICAgT3V0cHV0U3RyZWFtIG9zdHJlYW0gPSBzb2NrZXQuZ2V0T3V0cHV0U3RyZWFtKCk7CisKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDI1NjsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIG9zdHJlYW0ud3JpdGUoaSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgb3N0cmVhbS5mbHVzaCgpOworICAgICAgICAgICAgICAgIG9zdHJlYW0uY2xvc2UoKTsKKworICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGlzdHJlYW0gPSBzb2NrZXQuZ2V0SW5wdXRTdHJlYW0oKTsKKworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGogPSBpc3RyZWFtLnJlYWQoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGksIGopOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlzdHJlYW0uY2xvc2UoKTsKKworICAgICAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpOworCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBleDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFeGNlcHRpb24gZ2V0RXhjZXB0aW9uKCkgeworICAgICAgICAgICAgcmV0dXJuIGV4Y2VwdGlvbjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBYNTA5Q2VydGlmaWNhdGVbXSBnZXRDaGFpbigpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVzdE1hbmFnZXIuZ2V0Q2hhaW4oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIExvYWRzIGEga2V5c3RvcmUgZnJvbSBhIGJhc2U2NC1lbmNvZGVkIFN0cmluZy4gUmV0dXJucyB0aGUgS2V5TWFuYWdlcltdCisgICAgICogZm9yIHRoZSByZXN1bHQuCisgICAgICovCisgICAgcHJpdmF0ZSBLZXlNYW5hZ2VyW10gZ2V0S2V5TWFuYWdlcnMoU3RyaW5nIGtleXMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gYnl0ZXMgPSBCYXNlNjQuZGVjb2RlKGtleXMuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIElucHV0U3RyZWFtIGlucHV0U3RyZWFtID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzKTsKKworICAgICAgICBLZXlTdG9yZSBrZXlTdG9yZSA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICBrZXlTdG9yZS5sb2FkKGlucHV0U3RyZWFtLCBQQVNTV09SRC50b0NoYXJBcnJheSgpKTsKKyAgICAgICAgaW5wdXRTdHJlYW0uY2xvc2UoKTsKKworICAgICAgICBTdHJpbmcgYWxnb3JpdGhtID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0RGVmYXVsdEFsZ29yaXRobSgpOworICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeSBrZXlNYW5hZ2VyRmFjdG9yeSA9IEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgIGtleU1hbmFnZXJGYWN0b3J5LmluaXQoa2V5U3RvcmUsIFBBU1NXT1JELnRvQ2hhckFycmF5KCkpOworCisgICAgICAgIHJldHVybiBrZXlNYW5hZ2VyRmFjdG9yeS5nZXRLZXlNYW5hZ2VycygpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogSW1wbGVtZW50cyBiYXNpY2FsbHkgYSBkdW1teSBUcnVzdE1hbmFnZXIuIEl0IHN0b3JlcyB0aGUgY2VydGlmaWNhdGUKKyAgICAgKiBjaGFpbiBpdCBzZWVzLCBzbyBpdCBjYW4gbGF0ZXIgYmUgcXVlcmllZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFRlc3RUcnVzdE1hbmFnZXIgaW1wbGVtZW50cyBYNTA5VHJ1c3RNYW5hZ2VyIHsKKworICAgICAgICBwcml2YXRlIFg1MDlDZXJ0aWZpY2F0ZVtdIGNoYWluOworCisgICAgICAgIHByaXZhdGUgU3RyaW5nIGF1dGhUeXBlOworCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrQ2xpZW50VHJ1c3RlZChYNTA5Q2VydGlmaWNhdGVbXSBjaGFpbiwgU3RyaW5nIGF1dGhUeXBlKSB7CisgICAgICAgICAgICB0aGlzLmNoYWluID0gY2hhaW47CisgICAgICAgICAgICB0aGlzLmF1dGhUeXBlID0gYXV0aFR5cGU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBjaGVja1NlcnZlclRydXN0ZWQoWDUwOUNlcnRpZmljYXRlW10gY2hhaW4sIFN0cmluZyBhdXRoVHlwZSkgeworICAgICAgICAgICAgdGhpcy5jaGFpbiA9IGNoYWluOworICAgICAgICAgICAgdGhpcy5hdXRoVHlwZSA9IGF1dGhUeXBlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGVbXSBnZXRBY2NlcHRlZElzc3VlcnMoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGVbMF07CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgWDUwOUNlcnRpZmljYXRlW10gZ2V0Q2hhaW4oKSB7CisgICAgICAgICAgICByZXR1cm4gY2hhaW47CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEF1dGhUeXBlKCkgeworICAgICAgICAgICAgcmV0dXJuIGF1dGhUeXBlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgY2hlY2tDbGllbnRUcnVzdGVkKAorICAgICAgICAgICAgICAgIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGVbXSBjaGFpbiwgU3RyaW5nIGF1dGhUeXBlKQorICAgICAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrU2VydmVyVHJ1c3RlZCgKKyAgICAgICAgICAgICAgICBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlW10gY2hhaW4sIFN0cmluZyBhdXRoVHlwZSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworCisgICAgICAgIH0KKworICAgIH0KKworICAgIGNsYXNzIE15SGFuZHNoYWtlTGlzdGVuZXIgaW1wbGVtZW50cyBIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lciB7CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gY29tcGxldGVEb25lOworCisgICAgICAgIE15SGFuZHNoYWtlTGlzdGVuZXIoKSB7CisgICAgICAgICAgICBjb21wbGV0ZURvbmUgPSBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGhhbmRzaGFrZUNvbXBsZXRlZChIYW5kc2hha2VDb21wbGV0ZWRFdmVudCBldmVudCkgeworICAgICAgICAgICAgaWYgKGV2ZW50ICE9IG51bGwpIGNvbXBsZXRlRG9uZSA9IHRydWU7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvSG9zdG5hbWVWZXJpZmllclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9Ib3N0bmFtZVZlcmlmaWVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI1M2ZlZDIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvSG9zdG5hbWVWZXJpZmllclRlc3QuamF2YQpAQCAtMCwwICsxLDI5MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGggdGhpcworICogd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gVGhlIEFTRgorICogbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQKKyAqIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZQorICogTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKKyAqIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLkhvc3RuYW1lVmVyaWZpZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5IdHRwc1VSTENvbm5lY3Rpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC50ZXN0cy5zdXBwb3J0Lm15U1NMU2Vzc2lvbjsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+SG9zdG5hbWVWZXJpZmllcjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIEhvc3RuYW1lVmVyaWZpZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgaW1wbGVtZW50cworICAgICAgICBDZXJ0aWZpY2F0ZXNUb1BsYXlXaXRoIHsKKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuSG9zdG5hbWVWZXJpZmllciN2ZXJpZnkoU3RyaW5nIGhvc3RuYW1lLCBTU0xTZXNzaW9uCisgICAgICogICAgICAgIHNlc3Npb24pCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF92ZXJpZnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbXlTU0xTZXNzaW9uIHNlc3Npb24gPSBuZXcgbXlTU0xTZXNzaW9uKCJsb2NhbGhvc3QiLCAxMDgwLCBudWxsKTsKKyAgICAgICAgSG9zdG5hbWVWZXJpZmllciBodiA9IEh0dHBzVVJMQ29ubmVjdGlvbi5nZXREZWZhdWx0SG9zdG5hbWVWZXJpZmllcigpOworICAgICAgICBhc3NlcnRGYWxzZShodi52ZXJpZnkoImxvY2FsaG9zdCIsIHNlc3Npb24pKTsKKyAgICB9CisKKyAgICAvLyBjb3BpZWQgYW5kIG1vZGlmaWVkIGZyb20gYXBhY2hlIGh0dHAgY2xpZW50IHRlc3Qgc3VpdGUuCisgICAgcHVibGljIHZvaWQgdGVzdFZlcmlmeSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIElucHV0U3RyZWFtIGluOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgeDUwOTsKKyAgICAgICAgaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oWDUwOV9GT08pOworICAgICAgICB4NTA5ID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShpbik7CisgICAgICAgIG15U1NMU2Vzc2lvbiBzZXNzaW9uID0gbmV3IG15U1NMU2Vzc2lvbihuZXcgWDUwOUNlcnRpZmljYXRlW10ge3g1MDl9KTsKKworICAgICAgICBIb3N0bmFtZVZlcmlmaWVyIHZlcmlmaWVyID0gSHR0cHNVUkxDb25uZWN0aW9uLmdldERlZmF1bHRIb3N0bmFtZVZlcmlmaWVyKCk7CisgICAgICAgIGFzc2VydFRydWUodmVyaWZpZXIudmVyaWZ5KCJmb28uY29tIiwgc2Vzc2lvbikpOworICAgICAgICBhc3NlcnRGYWxzZSh2ZXJpZmllci52ZXJpZnkoImEuZm9vLmNvbSIsIHNlc3Npb24pKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UodmVyaWZpZXIudmVyaWZ5KCJiYXIuY29tIiwgc2Vzc2lvbikpOworCisgICAgICAgIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKFg1MDlfSEFOQUtPKTsKKyAgICAgICAgeDUwOSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoaW4pOworICAgICAgICBzZXNzaW9uID0gbmV3IG15U1NMU2Vzc2lvbihuZXcgWDUwOUNlcnRpZmljYXRlW10ge3g1MDl9KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh2ZXJpZmllci52ZXJpZnkoIlx1ODJiMVx1NWI1MC5jby5qcCIsIHNlc3Npb24pKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UodmVyaWZpZXIudmVyaWZ5KCJhLlx1ODJiMVx1NWI1MC5jby5qcCIsIHNlc3Npb24pKTsKKworICAgICAgICBpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShYNTA5X0ZPT19CQVIpOworICAgICAgICB4NTA5ID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShpbik7CisgICAgICAgIHNlc3Npb24gPSBuZXcgbXlTU0xTZXNzaW9uKG5ldyBYNTA5Q2VydGlmaWNhdGVbXSB7eDUwOX0pOworICAgICAgICBhc3NlcnRUcnVlKHZlcmlmaWVyLnZlcmlmeSgiZm9vLmNvbSIsIHNlc3Npb24pKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UodmVyaWZpZXIudmVyaWZ5KCJhLmZvby5jb20iLCBzZXNzaW9uKSk7CisgICAgICAgIGFzc2VydFRydWUodmVyaWZpZXIudmVyaWZ5KCJiYXIuY29tIiwgc2Vzc2lvbikpOworICAgICAgICBhc3NlcnRGYWxzZSh2ZXJpZmllci52ZXJpZnkoImEuYmFyLmNvbSIsIHNlc3Npb24pKTsKKworICAgICAgICBpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShYNTA5X0ZPT19CQVJfSEFOQUtPKTsKKyAgICAgICAgeDUwOSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoaW4pOworICAgICAgICBzZXNzaW9uID0gbmV3IG15U1NMU2Vzc2lvbihuZXcgWDUwOUNlcnRpZmljYXRlW10ge3g1MDl9KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh2ZXJpZmllci52ZXJpZnkoImZvby5jb20iLCBzZXNzaW9uKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHZlcmlmaWVyLnZlcmlmeSgiYS5mb28uY29tIiwgc2Vzc2lvbikpOworICAgICAgICAvLyB0aGVzZSBjaGVja3MgdGVzdCBhbHRlcm5hdGl2ZSBzdWJqZWN0cy4gVGhlIHRlc3QgZGF0YSBjb250YWlucyBhbgorICAgICAgICAvLyBhbHRlcm5hdGl2ZSBzdWJqZWN0IHN0YXJ0aW5nIHdpdGggYSBqYXBhbmVzZSBrYW5qaSBjaGFyYWN0ZXIuIFRoaXMgaXMKKyAgICAgICAgLy8gbm90IHN1cHBvcnRlZCBieSBBbmRyb2lkIGJlY2F1c2UgdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24gZnJvbQorICAgICAgICAvLyBoYXJtb255IGZvbGxvd3MgdGhlIGRlZmluaXRpb24gZnJvbSByZmMgMTAzNCBwYWdlIDEwIGZvciBhbHRlcm5hdGl2ZQorICAgICAgICAvLyBzdWJqZWN0IG5hbWVzLiBUaGlzIGNhdXNlcyB0aGUgY29kZSB0byBkcm9wIGFsbCBhbHRlcm5hdGl2ZSBzdWJqZWN0cy4KKyAgICAgICAgLy8gYXNzZXJ0VHJ1ZSh2ZXJpZmllci52ZXJpZnkoImJhci5jb20iLCBzZXNzaW9uKSk7CisgICAgICAgIC8vIGFzc2VydEZhbHNlKHZlcmlmaWVyLnZlcmlmeSgiYS5iYXIuY29tIiwgc2Vzc2lvbikpOworICAgICAgICAvLyBhc3NlcnRGYWxzZSh2ZXJpZmllci52ZXJpZnkoImEuXHU4MmIxXHU1YjUwLmNvLmpwIiwgc2Vzc2lvbikpOworCisgICAgICAgIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKFg1MDlfTk9fQ05TX0ZPTyk7CisgICAgICAgIHg1MDkgPSAoWDUwOUNlcnRpZmljYXRlKSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKGluKTsKKyAgICAgICAgc2Vzc2lvbiA9IG5ldyBteVNTTFNlc3Npb24obmV3IFg1MDlDZXJ0aWZpY2F0ZVtdIHt4NTA5fSk7CisgICAgICAgIGFzc2VydFRydWUodmVyaWZpZXIudmVyaWZ5KCJmb28uY29tIiwgc2Vzc2lvbikpOworICAgICAgICBhc3NlcnRGYWxzZSh2ZXJpZmllci52ZXJpZnkoImEuZm9vLmNvbSIsIHNlc3Npb24pKTsKKworICAgICAgICBpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShYNTA5X05PX0NOU19GT08pOworICAgICAgICB4NTA5ID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShpbik7CisgICAgICAgIHNlc3Npb24gPSBuZXcgbXlTU0xTZXNzaW9uKG5ldyBYNTA5Q2VydGlmaWNhdGVbXSB7eDUwOX0pOworICAgICAgICBhc3NlcnRUcnVlKHZlcmlmaWVyLnZlcmlmeSgiZm9vLmNvbSIsIHNlc3Npb24pKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UodmVyaWZpZXIudmVyaWZ5KCJhLmZvby5jb20iLCBzZXNzaW9uKSk7CisKKyAgICAgICAgaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oWDUwOV9USFJFRV9DTlNfRk9PX0JBUl9IQU5BS08pOworICAgICAgICB4NTA5ID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShpbik7CisgICAgICAgIHNlc3Npb24gPSBuZXcgbXlTU0xTZXNzaW9uKG5ldyBYNTA5Q2VydGlmaWNhdGVbXSB7eDUwOX0pOworICAgICAgICBhc3NlcnRGYWxzZSh2ZXJpZmllci52ZXJpZnkoImZvby5jb20iLCBzZXNzaW9uKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHZlcmlmaWVyLnZlcmlmeSgiYS5mb28uY29tIiwgc2Vzc2lvbikpOworICAgICAgICBhc3NlcnRGYWxzZSh2ZXJpZmllci52ZXJpZnkoImJhci5jb20iLCBzZXNzaW9uKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHZlcmlmaWVyLnZlcmlmeSgiYS5iYXIuY29tIiwgc2Vzc2lvbikpOworICAgICAgICBhc3NlcnRUcnVlKHZlcmlmaWVyLnZlcmlmeSgiXHU4MmIxXHU1YjUwLmNvLmpwIiwgc2Vzc2lvbikpOworICAgICAgICBhc3NlcnRGYWxzZSh2ZXJpZmllci52ZXJpZnkoImEuXHU4MmIxXHU1YjUwLmNvLmpwIiwgc2Vzc2lvbikpOworCisgICAgICAgIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKFg1MDlfV0lMRF9GT08pOworICAgICAgICB4NTA5ID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShpbik7CisgICAgICAgIHNlc3Npb24gPSBuZXcgbXlTU0xTZXNzaW9uKG5ldyBYNTA5Q2VydGlmaWNhdGVbXSB7eDUwOX0pOworICAgICAgICBhc3NlcnRGYWxzZSh2ZXJpZmllci52ZXJpZnkoImZvby5jb20iLCBzZXNzaW9uKSk7CisgICAgICAgIGFzc2VydFRydWUodmVyaWZpZXIudmVyaWZ5KCJ3d3cuZm9vLmNvbSIsIHNlc3Npb24pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh2ZXJpZmllci52ZXJpZnkoIlx1ODJiMVx1NWI1MC5mb28uY29tIiwgc2Vzc2lvbikpOworICAgICAgICBhc3NlcnRUcnVlKHZlcmlmaWVyLnZlcmlmeSgiYS5iLmZvby5jb20iLCBzZXNzaW9uKSk7CisKKyAgICAgICAgaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oWDUwOV9XSUxEX0NPX0pQKTsKKyAgICAgICAgeDUwOSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoaW4pOworICAgICAgICBzZXNzaW9uID0gbmV3IG15U1NMU2Vzc2lvbihuZXcgWDUwOUNlcnRpZmljYXRlW10ge3g1MDl9KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UodmVyaWZpZXIudmVyaWZ5KCJmb28uY28uanAiLCBzZXNzaW9uKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHZlcmlmaWVyLnZlcmlmeSgiXHU4MmIxXHU1YjUwLmNvLmpwIiwgc2Vzc2lvbikpOworCisgICAgICAgIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKFg1MDlfV0lMRF9GT09fQkFSX0hBTkFLTyk7CisgICAgICAgIHg1MDkgPSAoWDUwOUNlcnRpZmljYXRlKSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKGluKTsKKyAgICAgICAgc2Vzc2lvbiA9IG5ldyBteVNTTFNlc3Npb24obmV3IFg1MDlDZXJ0aWZpY2F0ZVtdIHt4NTA5fSk7CisgICAgICAgIC8vIHRyeSB0aGUgZm9vLmNvbSB2YXJpYXRpb25zCisgICAgICAgIGFzc2VydEZhbHNlKHZlcmlmaWVyLnZlcmlmeSgiZm9vLmNvbSIsIHNlc3Npb24pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh2ZXJpZmllci52ZXJpZnkoInd3dy5mb28uY29tIiwgc2Vzc2lvbikpOworICAgICAgICBhc3NlcnRUcnVlKHZlcmlmaWVyLnZlcmlmeSgiXHU4MmIxXHU1YjUwLmZvby5jb20iLCBzZXNzaW9uKSk7CisgICAgICAgIGFzc2VydFRydWUodmVyaWZpZXIudmVyaWZ5KCJhLmIuZm9vLmNvbSIsIHNlc3Npb24pKTsKKyAgICAgICAgLy8gdGhlc2UgY2hlY2tzIHRlc3QgYWx0ZXJuYXRpdmUgc3ViamVjdHMuIFRoZSB0ZXN0IGRhdGEgY29udGFpbnMgYW4KKyAgICAgICAgLy8gYWx0ZXJuYXRpdmUgc3ViamVjdCBzdGFydGluZyB3aXRoIGEgamFwYW5lc2Uga2FuamkgY2hhcmFjdGVyLiBUaGlzIGlzCisgICAgICAgIC8vIG5vdCBzdXBwb3J0ZWQgYnkgQW5kcm9pZCBiZWNhdXNlIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uIGZyb20KKyAgICAgICAgLy8gaGFybW9ueSBmb2xsb3dzIHRoZSBkZWZpbml0aW9uIGZyb20gcmZjIDEwMzQgcGFnZSAxMCBmb3IgYWx0ZXJuYXRpdmUKKyAgICAgICAgLy8gc3ViamVjdCBuYW1lcy4gVGhpcyBjYXVzZXMgdGhlIGNvZGUgdG8gZHJvcCBhbGwgYWx0ZXJuYXRpdmUgc3ViamVjdHMuCisgICAgICAgIC8vIGFzc2VydEZhbHNlKHZlcmlmaWVyLnZlcmlmeSgiYmFyLmNvbSIsIHNlc3Npb24pKTsKKyAgICAgICAgLy8gYXNzZXJ0VHJ1ZSh2ZXJpZmllci52ZXJpZnkoInd3dy5iYXIuY29tIiwgc2Vzc2lvbikpOworICAgICAgICAvLyBhc3NlcnRUcnVlKHZlcmlmaWVyLnZlcmlmeSgiXHU4MmIxXHU1YjUwLmJhci5jb20iLCBzZXNzaW9uKSk7CisgICAgICAgIC8vIGFzc2VydFRydWUodmVyaWZpZXIudmVyaWZ5KCJhLmIuYmFyLmNvbSIsIHNlc3Npb24pKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3ViamVjdEFsdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKFg1MDlfTVVMVElQTEVfU1VCSkVDVF9BTFQpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgeDUwOSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoaW4pOworICAgICAgICBteVNTTFNlc3Npb24gc2Vzc2lvbiA9IG5ldyBteVNTTFNlc3Npb24obmV3IFg1MDlDZXJ0aWZpY2F0ZVtdIHt4NTA5fSk7CisKKyAgICAgICAgSG9zdG5hbWVWZXJpZmllciB2ZXJpZmllciA9IEh0dHBzVVJMQ29ubmVjdGlvbi5nZXREZWZhdWx0SG9zdG5hbWVWZXJpZmllcigpOworICAgICAgICBTdHJpbmcgZXhwZWN0ZWQgPSAiQ049bG9jYWxob3N0LE9VPVVua25vd24sTz1Vbmtub3duLEw9VW5rbm93bixTVD1Vbmtub3duLEM9Q0giOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IFg1MDBQcmluY2lwYWwoZXhwZWN0ZWQpLAorICAgICAgICAgICAgICAgICAgICAgeDUwOS5nZXRTdWJqZWN0WDUwMFByaW5jaXBhbCgpKTsKKworICAgICAgICBhc3NlcnRUcnVlKHZlcmlmaWVyLnZlcmlmeSgibG9jYWxob3N0Iiwgc2Vzc2lvbikpOworICAgICAgICBhc3NlcnRUcnVlKHZlcmlmaWVyLnZlcmlmeSgibG9jYWxob3N0LmxvY2FsZG9tYWluIiwgc2Vzc2lvbikpOworICAgICAgICBhc3NlcnRGYWxzZSh2ZXJpZmllci52ZXJpZnkoImxvY2FsLmhvc3QiLCBzZXNzaW9uKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFZlcmlmeUlwQWRkcmVzcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKFg1MDlfTVVMVElQTEVfU1VCSkVDVF9BTFQpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgeDUwOSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoaW4pOworICAgICAgICBteVNTTFNlc3Npb24gc2Vzc2lvbiA9IG5ldyBteVNTTFNlc3Npb24obmV3IFg1MDlDZXJ0aWZpY2F0ZVtdIHsgeDUwOSB9KTsKKyAgICAgICAgSG9zdG5hbWVWZXJpZmllciB2ZXJpZmllciA9IEh0dHBzVVJMQ29ubmVjdGlvbi5nZXREZWZhdWx0SG9zdG5hbWVWZXJpZmllcigpOworCisgICAgICAgIGFzc2VydFRydWUodmVyaWZpZXIudmVyaWZ5KCIxMjcuMC4wLjEiLCBzZXNzaW9uKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHZlcmlmaWVyLnZlcmlmeSgiMTI3LjAuMC4yIiwgc2Vzc2lvbikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RXaWxkY2FyZHNDYW5ub3RNYXRjaElwQWRkcmVzc2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIG9wZW5zc2wgcmVxIC14NTA5IC1ub2RlcyAtZGF5cyAzNjUwMCAtc3ViaiAnL0NOPSouMC4wLjEnIC1uZXdrZXkgcnNhOjUxMiAtb3V0IGNlcnQucGVtCisgICAgICAgIFN0cmluZyBjZXJ0ID0gIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICAgICAgICAgICAgICsgIk1JSUJrakNDQVR5Z0F3SUJBZ0lKQU1kZW1xT3dkL0JFTUEwR0NTcUdTSWIzRFFFQkJRVUFNQkl4RURBT0JnTlZcbiIKKyAgICAgICAgICAgICAgICArICJCQU1VQnlvdU1DNHdMakV3SUJjTk1UQXhNakl3TVRZME5ESTFXaGdQTWpFeE1ERXhNall4TmpRME1qVmFNQkl4XG4iCisgICAgICAgICAgICAgICAgKyAiRURBT0JnTlZCQU1VQnlvdU1DNHdMakV3WERBTkJna3Foa2lHOXcwQkFRRUZBQU5MQURCSUFrRUFxWThjOVFydFxuIgorICAgICAgICAgICAgICAgICsgIllQV0N2YjdsY2xJK2FESE02ZmdiSmNIc1M5Wmc4blVPaDVkV3JTN0FnZUEyNXd5YW9rRmw0cGxCYmJIUWUyaitcbiIKKyAgICAgICAgICAgICAgICArICJjQ2pzUmlKSWNRbzlId0lEQVFBQm8zTXdjVEFkQmdOVkhRNEVGZ1FVSjQzNlRaUEp2d0NCS2tsWlpxSXZ0MVl0XG4iCisgICAgICAgICAgICAgICAgKyAiSmpFd1FnWURWUjBqQkRzd09ZQVVKNDM2VFpQSnZ3Q0JLa2xaWnFJdnQxWXRKakdoRnFRVU1CSXhFREFPQmdOVlxuIgorICAgICAgICAgICAgICAgICsgIkJBTVVCeW91TUM0d0xqR0NDUURIWHBxanNIZndSREFNQmdOVkhSTUVCVEFEQVFIL01BMEdDU3FHU0liM0RRRUJcbiIKKyAgICAgICAgICAgICAgICArICJCUVVBQTBFQWs5aTg4eGRqV29ld3F2RStpTUM5dEQyb2JNY2hnRkRhSEgwb2d4eGlSYUlLZUVseTNnMHVHeEl0XG4iCisgICAgICAgICAgICAgICAgKyAiZmwyV1JZOGhiNHgrelJyd3NGYUxFcGRFdnFjak9RPT1cbiIKKyAgICAgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tIjsKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShjZXJ0LmdldEJ5dGVzKCJVVEYtOCIpKTsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIHg1MDkgPSAoWDUwOUNlcnRpZmljYXRlKSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKGluKTsKKyAgICAgICAgbXlTU0xTZXNzaW9uIHNlc3Npb24gPSBuZXcgbXlTU0xTZXNzaW9uKG5ldyBYNTA5Q2VydGlmaWNhdGVbXSB7IHg1MDkgfSk7CisgICAgICAgIEhvc3RuYW1lVmVyaWZpZXIgdmVyaWZpZXIgPSBIdHRwc1VSTENvbm5lY3Rpb24uZ2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoKTsKKworICAgICAgICBhc3NlcnRGYWxzZSh2ZXJpZmllci52ZXJpZnkoIjEyNy4wLjAuMSIsIHNlc3Npb24pKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V2lsZGNhcmRzTXVzdEhhdmVUd29Eb3RzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIG9wZW5zc2wgcmVxIC14NTA5IC1ub2RlcyAtZGF5cyAzNjUwMCAtc3ViaiAnL0NOPSouY29tJyAtbmV3a2V5IHJzYTo1MTIgLW91dCBjZXJ0LnBlbQorICAgICAgICBTdHJpbmcgY2VydCA9ICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICAgICArICJNSUlCakRDQ0FUYWdBd0lCQWdJSkFPVnVsWENTdTZIdU1BMEdDU3FHU0liM0RRRUJCUVVBTUJBeERqQU1CZ05WXG4iCisgICAgICAgICAgICAgICAgKyAiQkFNVUJTb3VZMjl0TUNBWERURXdNVEl5TURFMk5Ea3pPRm9ZRHpJeE1UQXhNVEkyTVRZME9UTTRXakFRTVE0d1xuIgorICAgICAgICAgICAgICAgICsgIkRBWURWUVFERkFVcUxtTnZiVEJjTUEwR0NTcUdTSWIzRFFFQkFRVUFBMHNBTUVnQ1FRREpkOHhxbmkraDdJYXpcbiIKKyAgICAgICAgICAgICAgICArICJ5cEl0aXZzOWtQdWlKVXFWeitTdUoxQzA1U0ZjM1BtbFJDdndTSWZoeUQ2N2ZIY2JNZGwrQS9McklqaGhLWkplXG4iCisgICAgICAgICAgICAgICAgKyAiMWpvTzArcEZBZ01CQUFHamNUQnZNQjBHQTFVZERnUVdCQlM0SXV6ZjV3OEpkQ3ArRXRCZmRGTnVkZjYrWXpCQVxuIgorICAgICAgICAgICAgICAgICsgIkJnTlZIU01FT1RBM2dCUzRJdXpmNXc4SmRDcCtFdEJmZEZOdWRmNitZNkVVcEJJd0VERU9NQXdHQTFVRUF4UUZcbiIKKyAgICAgICAgICAgICAgICArICJLaTVqYjIyQ0NRRGxicFZ3a3J1aDdqQU1CZ05WSFJNRUJUQURBUUgvTUEwR0NTcUdTSWIzRFFFQkJRVUFBMEVBXG4iCisgICAgICAgICAgICAgICAgKyAiVTZMRnhtWnIzMWxGeWlzMi9UNjhQcGpBcHBjMERwTlF1QTJtL1k3b1RIQkRpNTVGdzZIVkhDdzNsdWN1V1o1ZFxuIgorICAgICAgICAgICAgICAgICsgInFVWW80RVM1NDhKZHBRdGNMclcyc0E9PVxuIgorICAgICAgICAgICAgICAgICsgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0iOworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIElucHV0U3RyZWFtIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNlcnQuZ2V0Qnl0ZXMoIlVURi04IikpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgeDUwOSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoaW4pOworICAgICAgICBteVNTTFNlc3Npb24gc2Vzc2lvbiA9IG5ldyBteVNTTFNlc3Npb24obmV3IFg1MDlDZXJ0aWZpY2F0ZVtdIHsgeDUwOSB9KTsKKyAgICAgICAgSG9zdG5hbWVWZXJpZmllciB2ZXJpZmllciA9IEh0dHBzVVJMQ29ubmVjdGlvbi5nZXREZWZhdWx0SG9zdG5hbWVWZXJpZmllcigpOworCisgICAgICAgIGFzc2VydEZhbHNlKHZlcmlmaWVyLnZlcmlmeSgiZ29vZ2xlLmNvbSIsIHNlc3Npb24pKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3ViamVjdEFsdE5hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogJCBjYXQgLi9jZXJ0LmNuZgorICAgICAgICAgKiBbcmVxXQorICAgICAgICAgKiBkaXN0aW5ndWlzaGVkX25hbWU9ZGlzdGluZ3Vpc2hlZF9uYW1lCisgICAgICAgICAqIHJlcV9leHRlbnNpb25zPXJlcV9leHRlbnNpb25zCisgICAgICAgICAqIHg1MDlfZXh0ZW5zaW9ucz14NTA5X2V4dGVuc2lvbnMKKyAgICAgICAgICogW2Rpc3Rpbmd1aXNoZWRfbmFtZV0KKyAgICAgICAgICogW3JlcV9leHRlbnNpb25zXQorICAgICAgICAgKiBbeDUwOV9leHRlbnNpb25zXQorICAgICAgICAgKiBzdWJqZWN0QWx0TmFtZT1ETlM6YmFyLmNvbSxETlM6YmF6LmNvbQorICAgICAgICAgKgorICAgICAgICAgKiAkIG9wZW5zc2wgcmVxIC14NTA5IC1ub2RlcyAtZGF5cyAzNjUwMCAtc3ViaiAnL0NOPWZvby5jb20nIC1jb25maWcgLi9jZXJ0LmNuZiBcCisgICAgICAgICAqICAgICAtbmV3a2V5IHJzYTo1MTIgLW91dCBjZXJ0LnBlbQorICAgICAgICAgKi8KKyAgICAgICAgU3RyaW5nIGNlcnQgPSAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICAgICAgICAgKyAiTUlJQlBUQ0I2S0FEQWdFQ0Fna0E3em9IYWFxTkdIUXdEUVlKS29aSWh2Y05BUUVGQlFBd0VqRVFNQTRHQTFVRVxuIgorICAgICAgICAgICAgICAgICsgIkF4TUhabTl2TG1OdmJUQWdGdzB4TURFeU1qQXhPRE01TXpaYUdBOHlNVEV3TVRFeU5qRTRNemt6Tmxvd0VqRVFcbiIKKyAgICAgICAgICAgICAgICArICJNQTRHQTFVRUF4TUhabTl2TG1OdmJUQmNNQTBHQ1NxR1NJYjNEUUVCQVFVQUEwc0FNRWdDUVFDK2dtb1N4Ris4XG4iCisgICAgICAgICAgICAgICAgKyAiaGJWK3JnUlFxSElKZDUwMjE2T1dRSmJVM0J2ZGxQYmNhNzc5TllPNCtVWldURmRCTThCZFFxczNINEI1QWd2cFxuIgorICAgICAgICAgICAgICAgICsgInk3SGVTZmYxRjdYUkFnTUJBQUdqSHpBZE1Cc0dBMVVkRVFRVU1CS0NCMkpoY2k1amIyMkNCMkpoZWk1amIyMHdcbiIKKyAgICAgICAgICAgICAgICArICJEUVlKS29aSWh2Y05BUUVGQlFBRFFRQlhwWlpQT1kyRHkxbEdHODFKVHI4TDRvcjlqcEthY0Q3bjUxZVM4aXFJXG4iCisgICAgICAgICAgICAgICAgKyAib1R6blBOdVhIVTViRk4wQUFHWDJpajQ3Zi9FYWhxVHBvNVJkUzk1UDRzVm1cbiIKKyAgICAgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tIjsKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShjZXJ0LmdldEJ5dGVzKCJVVEYtOCIpKTsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIHg1MDkgPSAoWDUwOUNlcnRpZmljYXRlKSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKGluKTsKKyAgICAgICAgbXlTU0xTZXNzaW9uIHNlc3Npb24gPSBuZXcgbXlTU0xTZXNzaW9uKG5ldyBYNTA5Q2VydGlmaWNhdGVbXSB7IHg1MDkgfSk7CisgICAgICAgIEhvc3RuYW1lVmVyaWZpZXIgdmVyaWZpZXIgPSBIdHRwc1VSTENvbm5lY3Rpb24uZ2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoKTsKKworICAgICAgICBhc3NlcnRUcnVlKHZlcmlmaWVyLnZlcmlmeSgiZm9vLmNvbSIsIHNlc3Npb24pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh2ZXJpZmllci52ZXJpZnkoImJhci5jb20iLCBzZXNzaW9uKSk7CisgICAgICAgIGFzc2VydFRydWUodmVyaWZpZXIudmVyaWZ5KCJiYXouY29tIiwgc2Vzc2lvbikpOworICAgICAgICBhc3NlcnRGYWxzZSh2ZXJpZmllci52ZXJpZnkoImEuZm9vLmNvbSIsIHNlc3Npb24pKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UodmVyaWZpZXIudmVyaWZ5KCJxdXV4LmNvbSIsIHNlc3Npb24pKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3ViamVjdEFsdE5hbWVXaXRoV2lsZGNhcmQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogJCBjYXQgLi9jZXJ0LmNuZgorICAgICAgICAgKiBbcmVxXQorICAgICAgICAgKiBkaXN0aW5ndWlzaGVkX25hbWU9ZGlzdGluZ3Vpc2hlZF9uYW1lCisgICAgICAgICAqIHJlcV9leHRlbnNpb25zPXJlcV9leHRlbnNpb25zCisgICAgICAgICAqIHg1MDlfZXh0ZW5zaW9ucz14NTA5X2V4dGVuc2lvbnMKKyAgICAgICAgICogW2Rpc3Rpbmd1aXNoZWRfbmFtZV0KKyAgICAgICAgICogW3JlcV9leHRlbnNpb25zXQorICAgICAgICAgKiBbeDUwOV9leHRlbnNpb25zXQorICAgICAgICAgKiBzdWJqZWN0QWx0TmFtZT1ETlM6YmFyLmNvbSxETlM6Ki5iYXouY29tCisgICAgICAgICAqCisgICAgICAgICAqICQgb3BlbnNzbCByZXEgLXg1MDkgLW5vZGVzIC1kYXlzIDM2NTAwIC1zdWJqICcvQ049Zm9vLmNvbScgLWNvbmZpZyAuL2NlcnQuY25mIFwKKyAgICAgICAgICogICAgIC1uZXdrZXkgcnNhOjUxMiAtb3V0IGNlcnQucGVtCisgICAgICAgICAqLworICAgICAgICBTdHJpbmcgY2VydCA9ICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICAgICArICJNSUlCUHpDQjZxQURBZ0VDQWdrQW52LzdKdjVyN3BNd0RRWUpLb1pJaHZjTkFRRUZCUUF3RWpFUU1BNEdBMVVFXG4iCisgICAgICAgICAgICAgICAgKyAiQXhNSFptOXZMbU52YlRBZ0Z3MHhNREV5TWpBeE9EUTJNREZhR0E4eU1URXdNVEV5TmpFNE5EWXdNVm93RWpFUVxuIgorICAgICAgICAgICAgICAgICsgIk1BNEdBMVVFQXhNSFptOXZMbU52YlRCY01BMEdDU3FHU0liM0RRRUJBUVVBQTBzQU1FZ0NRUURBejJZWG55b2dcbiIKKyAgICAgICAgICAgICAgICArICJZZFlMU0ZyL09FZ1N1bXR3cXRaS0pUQjR3cVRXL2VLYkJDRXp4bnlVTXhXWklxVUd1MzUzUHp3Zk91V3AycmUzXG4iCisgICAgICAgICAgICAgICAgKyAibnZWVitRRFlRbGg5QWdNQkFBR2pJVEFmTUIwR0ExVWRFUVFXTUJTQ0IySmhjaTVqYjIyQ0NTb3VZbUY2TG1OdlxuIgorICAgICAgICAgICAgICAgICsgImJUQU5CZ2txaGtpRzl3MEJBUVVGQUFOQkFCOHlyU2w4enF5MDdpMFNOWXgyQi9GbnZRWTczNHB4aW9hcUZXZk9cbiIKKyAgICAgICAgICAgICAgICArICJCcW8xWlpsLzlhUEhFV0l3QnJ4WU5WQjBTR3Uva2tidC92eHFPanp6cmtYdWttST1cbiIKKyAgICAgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tIjsKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShjZXJ0LmdldEJ5dGVzKCJVVEYtOCIpKTsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIHg1MDkgPSAoWDUwOUNlcnRpZmljYXRlKSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKGluKTsKKyAgICAgICAgbXlTU0xTZXNzaW9uIHNlc3Npb24gPSBuZXcgbXlTU0xTZXNzaW9uKG5ldyBYNTA5Q2VydGlmaWNhdGVbXSB7IHg1MDkgfSk7CisgICAgICAgIEhvc3RuYW1lVmVyaWZpZXIgdmVyaWZpZXIgPSBIdHRwc1VSTENvbm5lY3Rpb24uZ2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoKTsKKworICAgICAgICBhc3NlcnRUcnVlKHZlcmlmaWVyLnZlcmlmeSgiZm9vLmNvbSIsIHNlc3Npb24pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh2ZXJpZmllci52ZXJpZnkoImJhci5jb20iLCBzZXNzaW9uKSk7CisgICAgICAgIGFzc2VydFRydWUodmVyaWZpZXIudmVyaWZ5KCJhLmJhei5jb20iLCBzZXNzaW9uKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHZlcmlmaWVyLnZlcmlmeSgiYmF6LmNvbSIsIHNlc3Npb24pKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UodmVyaWZpZXIudmVyaWZ5KCJhLmZvby5jb20iLCBzZXNzaW9uKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHZlcmlmaWVyLnZlcmlmeSgiYS5iYXIuY29tIiwgc2Vzc2lvbikpOworICAgICAgICBhc3NlcnRGYWxzZSh2ZXJpZmllci52ZXJpZnkoInF1dXguY29tIiwgc2Vzc2lvbikpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9IdHRwc1VSTENvbm5lY3Rpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvSHR0cHNVUkxDb25uZWN0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUyZWJkYmQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvSHR0cHNVUkxDb25uZWN0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzQxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CisKK2ltcG9ydCBqYXZheC5uZXQuc3NsLkhvc3RuYW1lVmVyaWZpZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5IdHRwc1VSTENvbm5lY3Rpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTb2NrZXRGYWN0b3J5OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5UZXN0VXRpbHM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5IdHRwc1VSTENvbm5lY3Rpb248L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBIdHRwc1VSTENvbm5lY3Rpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5IdHRwc1VSTENvbm5lY3Rpb24jSHR0cHNVUkxDb25uZWN0aW9uKGphdmFfbmV0X1VSTCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG5ldyBNeUh0dHBzVVJMQ29ubmVjdGlvbihuZXcgVVJMKCJodHRwczovL3d3dy5mb3J0aWZ5Lm5ldC8iKSk7CisgICAgICAgIG5ldyBNeUh0dHBzVVJMQ29ubmVjdGlvbihudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLkh0dHBzVVJMQ29ubmVjdGlvbiNnZXRDaXBoZXJTdWl0ZSgpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF9nZXRDaXBoZXJTdWl0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cHM6Ly9sb2NhbGhvc3Q6NTU1NTUiKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uZ2V0Q2lwaGVyU3VpdGUoKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbiA9IG5ldyBNeUh0dHBzVVJMQ29ubmVjdGlvbihuZXcgVVJMKCJodHRwczovL3d3dy5mb3J0aWZ5Lm5ldC8iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQ2lwaGVyU3VpdGUiLCBjb24uZ2V0Q2lwaGVyU3VpdGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5IdHRwc1VSTENvbm5lY3Rpb24jZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHBzOi8vbG9jYWxob3N0OjU1NTU1Iik7CisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gKEh0dHBzVVJMQ29ubmVjdGlvbikgdXJsLm9wZW5Db25uZWN0aW9uKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uZWN0aW9uLmdldExvY2FsQ2VydGlmaWNhdGVzKCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb24gPSBuZXcgTXlIdHRwc1VSTENvbm5lY3Rpb24obmV3IFVSTCgiaHR0cHM6Ly93d3cuZm9ydGlmeS5uZXQvIiksICJYLjUwOCIpOworICAgICAgICBhc3NlcnROdWxsKGNvbi5nZXRMb2NhbENlcnRpZmljYXRlcygpKTsKKyAgICAgICAgY29uID0gbmV3IE15SHR0cHNVUkxDb25uZWN0aW9uKG5ldyBVUkwoImh0dHBzOi8vd3d3LmZvcnRpZnkubmV0LyIpLCAiWC41MDkiKTsKKyAgICAgICAgQ2VydGlmaWNhdGVbXSBjZXJ0ID0gY29uLmdldExvY2FsQ2VydGlmaWNhdGVzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoY2VydCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBjZXJ0Lmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5IdHRwc1VSTENvbm5lY3Rpb24jZ2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfZ2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoKSB7CisgICAgICAgIEhvc3RuYW1lVmVyaWZpZXIgdmVyaWZ5ZXIgPQorICAgICAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uLmdldERlZmF1bHRIb3N0bmFtZVZlcmlmaWVyKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkRlZmF1bHQgaG9zdG5hbWUgdmVyaWZ5ZXIgaXMgbnVsbCIsIHZlcmlmeWVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLkh0dHBzVVJMQ29ubmVjdGlvbiNnZXREZWZhdWx0U1NMU29ja2V0RmFjdG9yeSgpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF9nZXREZWZhdWx0U1NMU29ja2V0RmFjdG9yeSgpIHsKKyAgICAgICAgU1NMU29ja2V0RmFjdG9yeSBzZiA9IEh0dHBzVVJMQ29ubmVjdGlvbi5nZXREZWZhdWx0U1NMU29ja2V0RmFjdG9yeSgpOworICAgICAgICBpZiAoIXNmLmVxdWFscyhTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKSkpIHsKKyAgICAgICAgICAgIGZhaWwoImluY29ycmVjdCBEZWZhdWx0U1NMU29ja2V0RmFjdG9yeSIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5IdHRwc1VSTENvbm5lY3Rpb24jZ2V0SG9zdG5hbWVWZXJpZmllcigpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF9nZXRIb3N0bmFtZVZlcmlmaWVyKCkKKyAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb24gPSBuZXcgTXlIdHRwc1VSTENvbm5lY3Rpb24oCisgICAgICAgICAgICAgICAgbmV3IFVSTCgiaHR0cHM6Ly93d3cuZm9ydGlmeS5uZXQvIikpOworICAgICAgICBIb3N0bmFtZVZlcmlmaWVyIHZlcmlmeWVyID0gY29uLmdldEhvc3RuYW1lVmVyaWZpZXIoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiSG9zdG5hbWUgdmVyaWZ5ZXIgaXMgbnVsbCIsIHZlcmlmeWVyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdmFsdWUgb2YgaG9zdG5hbWUgdmVyaXJmeWVyIiwKKyAgICAgICAgICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24uZ2V0RGVmYXVsdEhvc3RuYW1lVmVyaWZpZXIoKSwgdmVyaWZ5ZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuSHR0cHNVUkxDb25uZWN0aW9uI2dldExvY2FsUHJpbmNpcGFsKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X2dldExvY2FsUHJpbmNpcGFsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwczovL2xvY2FsaG9zdDo1NTU1NSIpOworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IChIdHRwc1VSTENvbm5lY3Rpb24pIHVybC5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubmVjdGlvbi5nZXRMb2NhbFByaW5jaXBhbCgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24gY29uID0gbmV3IE15SHR0cHNVUkxDb25uZWN0aW9uKG5ldyBVUkwoImh0dHBzOi8vd3d3LmZvcnRpZnkubmV0LyIpLCAiWC41MDgiKTsKKyAgICAgICAgYXNzZXJ0TnVsbChjb24uZ2V0TG9jYWxQcmluY2lwYWwoKSk7CisgICAgICAgIGNvbiA9IG5ldyBNeUh0dHBzVVJMQ29ubmVjdGlvbihuZXcgVVJMKCJodHRwczovL3d3dy5mb3J0aWZ5Lm5ldC8iKSwgIlguNTA5Iik7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkxvY2FsIHByaW5jaXBhbCBpcyBudWxsIiwgY29uLmdldExvY2FsUHJpbmNpcGFsKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuSHR0cHNVUkxDb25uZWN0aW9uI2dldFBlZXJQcmluY2lwYWwoKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfZ2V0UGVlclByaW5jaXBhbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cHM6Ly9sb2NhbGhvc3Q6NTU1NTUiKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uZ2V0UGVlclByaW5jaXBhbCgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbiA9IG5ldyBNeUh0dHBzVVJMQ29ubmVjdGlvbihuZXcgVVJMKCJodHRwczovL3d3dy5mb3J0aWZ5Lm5ldC8iKSwgIlguNTA4Iik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQcmluY2lwYWwgcCA9IGNvbi5nZXRQZWVyUHJpbmNpcGFsKCk7CisgICAgICAgICAgICBmYWlsKCJTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBjb24gPSBuZXcgTXlIdHRwc1VSTENvbm5lY3Rpb24obmV3IFVSTCgiaHR0cHM6Ly93d3cuZm9ydGlmeS5uZXQvIiksICJYLjUwOSIpOworICAgICAgICBQcmluY2lwYWwgcCA9IGNvbi5nZXRQZWVyUHJpbmNpcGFsKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwocCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5IdHRwc1VSTENvbm5lY3Rpb24jZ2V0U2VydmVyQ2VydGlmaWNhdGVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X2dldFNlcnZlckNlcnRpZmljYXRlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCgiaHR0cHM6Ly9sb2NhbGhvc3Q6NTU1NTUiKTsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoSHR0cHNVUkxDb25uZWN0aW9uKSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm5lY3Rpb24uZ2V0U2VydmVyQ2VydGlmaWNhdGVzKCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb24gPSBuZXcgTXlIdHRwc1VSTENvbm5lY3Rpb24obmV3IFVSTCgiaHR0cHM6Ly93d3cuZm9ydGlmeS5uZXQvIiksICJYLjUwOCIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29uLmdldFNlcnZlckNlcnRpZmljYXRlcygpOworICAgICAgICAgICAgZmFpbCgiU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgY29uID0gbmV3IE15SHR0cHNVUkxDb25uZWN0aW9uKG5ldyBVUkwoImh0dHBzOi8vd3d3LmZvcnRpZnkubmV0LyIpLCAiWC41MDkiKTsKKyAgICAgICAgQ2VydGlmaWNhdGVbXSBjZXJ0ID0gY29uLmdldFNlcnZlckNlcnRpZmljYXRlcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKGNlcnQpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY2VydC5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuSHR0cHNVUkxDb25uZWN0aW9uI2dldFNTTFNvY2tldEZhY3RvcnkoKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfZ2V0U1NMU29ja2V0RmFjdG9yeSgpIHsKKyAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uIGNvbiA9IG5ldyBNeUh0dHBzVVJMQ29ubmVjdGlvbihudWxsKTsKKyAgICAgICAgU1NMU29ja2V0RmFjdG9yeSBzZiA9IGNvbi5nZXRTU0xTb2NrZXRGYWN0b3J5KCk7CisgICAgICAgIGlmICghc2YuZXF1YWxzKFNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpKSkgeworICAgICAgICAgICAgZmFpbCgiaW5jb3JyZWN0IERlZmF1bHRTU0xTb2NrZXRGYWN0b3J5Iik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLkh0dHBzVVJMQ29ubmVjdGlvbiNzZXREZWZhdWx0SG9zdG5hbWVWZXJpZmllcigpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF9zZXREZWZhdWx0SG9zdG5hbWVWZXJpZmllcigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbi5zZXREZWZhdWx0SG9zdG5hbWVWZXJpZmllcihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBIb3N0bmFtZVZlcmlmaWVyIGRlZiA9IEh0dHBzVVJMQ29ubmVjdGlvbi5nZXREZWZhdWx0SG9zdG5hbWVWZXJpZmllcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXlIb3N0bmFtZVZlcmlmaWVyIGhudiA9IG5ldyBteUhvc3RuYW1lVmVyaWZpZXIoKTsKKyAgICAgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbi5zZXREZWZhdWx0SG9zdG5hbWVWZXJpZmllcihobnYpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGhudiwgSHR0cHNVUkxDb25uZWN0aW9uLmdldERlZmF1bHRIb3N0bmFtZVZlcmlmaWVyKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uLnNldERlZmF1bHRIb3N0bmFtZVZlcmlmaWVyKGRlZik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLkh0dHBzVVJMQ29ubmVjdGlvbiNzZXRIb3N0bmFtZVZlcmlmaWVyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X3NldEhvc3RuYW1lVmVyaWZpZXIoKSB7CisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb24gPSBuZXcgTXlIdHRwc1VSTENvbm5lY3Rpb24obnVsbCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb24uc2V0SG9zdG5hbWVWZXJpZmllcihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBteUhvc3RuYW1lVmVyaWZpZXIgaG52ID0gbmV3IG15SG9zdG5hbWVWZXJpZmllcigpOworICAgICAgICBjb24uc2V0SG9zdG5hbWVWZXJpZmllcihobnYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuSHR0cHNVUkxDb25uZWN0aW9uI3NldERlZmF1bHRTU0xTb2NrZXRGYWN0b3J5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X3NldERlZmF1bHRTU0xTb2NrZXRGYWN0b3J5KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgSHR0cHNVUkxDb25uZWN0aW9uLnNldERlZmF1bHRTU0xTb2NrZXRGYWN0b3J5KG51bGwpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIFNTTFNvY2tldEZhY3Rvcnkgc3NmID0gKFNTTFNvY2tldEZhY3RvcnkpIFNTTFNvY2tldEZhY3RvcnkKKyAgICAgICAgICAgICAgICAuZ2V0RGVmYXVsdCgpOworICAgICAgICBIdHRwc1VSTENvbm5lY3Rpb24uc2V0RGVmYXVsdFNTTFNvY2tldEZhY3Rvcnkoc3NmKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLkh0dHBzVVJMQ29ubmVjdGlvbiNzZXRTU0xTb2NrZXRGYWN0b3J5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X3NldFNTTFNvY2tldEZhY3RvcnkoKSB7CisgICAgICAgIEh0dHBzVVJMQ29ubmVjdGlvbiBjb24gPSBuZXcgTXlIdHRwc1VSTENvbm5lY3Rpb24obnVsbCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb24uc2V0U1NMU29ja2V0RmFjdG9yeShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBTU0xTb2NrZXRGYWN0b3J5IHNzZiA9IChTU0xTb2NrZXRGYWN0b3J5KSBTU0xTb2NrZXRGYWN0b3J5CisgICAgICAgICAgICAgICAgLmdldERlZmF1bHQoKTsKKyAgICAgICAgY29uLnNldFNTTFNvY2tldEZhY3Rvcnkoc3NmKTsKKyAgICB9Cit9CisKK2NsYXNzIE15SHR0cHNVUkxDb25uZWN0aW9uIGV4dGVuZHMgamF2YXgubmV0LnNzbC5IdHRwc1VSTENvbm5lY3Rpb24geworCisgICAgcHJpdmF0ZSBTdHJpbmcgdHlwZURvbmU7CisKKyAgICBwdWJsaWMgTXlIdHRwc1VSTENvbm5lY3Rpb24oVVJMIHVybCkgeworICAgICAgICBzdXBlcih1cmwpOworICAgIH0KKworICAgIHB1YmxpYyBNeUh0dHBzVVJMQ29ubmVjdGlvbihVUkwgdXJsLCBTdHJpbmcgdHlwZSkgeworICAgICAgICBzdXBlcih1cmwpOworICAgICAgICB0eXBlRG9uZSA9IHR5cGU7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuSHR0cHNVUkxDb25uZWN0aW9uI2dldENpcGhlclN1aXRlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENpcGhlclN1aXRlKCkgeworICAgICAgICByZXR1cm4gIkNpcGhlclN1aXRlIjsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5IdHRwc1VSTENvbm5lY3Rpb24jZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKQorICAgICAqLworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZVtdIGdldExvY2FsQ2VydGlmaWNhdGVzKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKHR5cGVEb25lKTsKKyAgICAgICAgICAgIGJ5dGVbXSBiYXJyID0gVGVzdFV0aWxzLmdldFg1MDlDZXJ0aWZpY2F0ZV92MSgpOworICAgICAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhcnIpOworICAgICAgICAgICAgQ2VydGlmaWNhdGUgY2VydCA9IGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoYmlzKTsKKyAgICAgICAgICAgIHJldHVybiBuZXcgQ2VydGlmaWNhdGVbXSB7IGNlcnQgfTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gc2UpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuSHR0cHNVUkxDb25uZWN0aW9uI2dldFNlcnZlckNlcnRpZmljYXRlcygpCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlW10gZ2V0U2VydmVyQ2VydGlmaWNhdGVzKCkgdGhyb3dzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSh0eXBlRG9uZSk7CisgICAgICAgICAgICBieXRlW10gYmFyciA9IFRlc3RVdGlscy5nZXRYNTA5Q2VydGlmaWNhdGVfdjMoKTsKKyAgICAgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYXJyKTsKKyAgICAgICAgICAgIENlcnRpZmljYXRlIGNlcnQgPSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKGJpcyk7CisgICAgICAgICAgICByZXR1cm4gbmV3IENlcnRpZmljYXRlW10geyBjZXJ0IH07CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24oIk5vIHNlcnZlcidzIGVuZC1lbnRpdHkgY2VydGlmaWNhdGUiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQHNlZSBqYXZhLm5ldC5IdHRwVVJMQ29ubmVjdGlvbiNkaXNjb25uZWN0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkaXNjb25uZWN0KCkgeworICAgIH0KKworICAgIC8qCisgICAgICogQHNlZSBqYXZhLm5ldC5IdHRwVVJMQ29ubmVjdGlvbiN1c2luZ1Byb3h5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB1c2luZ1Byb3h5KCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY29ubmVjdCgpIHsKKyAgICB9CisKK30KKworY2xhc3MgbXlIb3N0bmFtZVZlcmlmaWVyIGltcGxlbWVudHMgSG9zdG5hbWVWZXJpZmllciB7CisKKyAgICBteUhvc3RuYW1lVmVyaWZpZXIoKSB7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gdmVyaWZ5KFN0cmluZyBob3N0bmFtZSwgU1NMU2Vzc2lvbiBzZXNzaW9uKSB7CisgICAgICAgIGlmIChob3N0bmFtZSA9PSBzZXNzaW9uLmdldFBlZXJIb3N0KCkpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9IGVsc2UgcmV0dXJuIGZhbHNlOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL0tleU1hbmFnZXJGYWN0b3J5MVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9LZXlNYW5hZ2VyRmFjdG9yeTFUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjM2OWVkOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9LZXlNYW5hZ2VyRmFjdG9yeTFUZXN0LmphdmEKQEAgLTAsMCArMSw1MzIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5VbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKKworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5U3RvcmVCdWlsZGVyUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLk1hbmFnZXJGYWN0b3J5UGFyYW1ldGVyczsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleU1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyRmFjdG9yeTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleU1hbmFnZXJGYWN0b3J5U3BpOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuU3BpRW5nVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnhuZXQudGVzdHMuc3VwcG9ydC5NeUtleU1hbmFnZXJGYWN0b3J5U3BpOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5LZXlNYW5hZ2VyRmFjdG9yeTwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIEtleU1hbmFnZXJGYWN0b3J5MVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgc3J2S2V5TWFuYWdlckZhY3RvcnkgPSAiS2V5TWFuYWdlckZhY3RvcnkiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGRlZmF1bHRBbGdvcml0aG0gPSBudWxsOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGRlZmF1bHRQcm92aWRlck5hbWUgPSBudWxsOworCisgICAgcHJpdmF0ZSBzdGF0aWMgUHJvdmlkZXIgZGVmYXVsdFByb3ZpZGVyID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gREVGU3VwcG9ydGVkID0gZmFsc2U7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTm90U3VwcG9ydGVkTXNnID0gIlRoZXJlIGlzIG5vIHN1aXRhYmxlIHByb3ZpZGVyIGZvciBLZXlNYW5hZ2VyRmFjdG9yeSI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBpbnZhbGlkVmFsdWVzID0gU3BpRW5nVXRpbHMuaW52YWxpZFZhbHVlczsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIHZhbGlkVmFsdWVzID0gbmV3IFN0cmluZ1szXTsKKyAgICBzdGF0aWMgeworICAgICAgICBkZWZhdWx0QWxnb3JpdGhtID0gU2VjdXJpdHkKKyAgICAgICAgICAgICAgICAuZ2V0UHJvcGVydHkoInNzbC5LZXlNYW5hZ2VyRmFjdG9yeS5hbGdvcml0aG0iKTsKKyAgICAgICAgaWYgKGRlZmF1bHRBbGdvcml0aG0gIT0gbnVsbCkgeworICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyID0gU3BpRW5nVXRpbHMuaXNTdXBwb3J0KGRlZmF1bHRBbGdvcml0aG0sCisgICAgICAgICAgICAgICAgICAgIHNydktleU1hbmFnZXJGYWN0b3J5KTsKKyAgICAgICAgICAgIERFRlN1cHBvcnRlZCA9IChkZWZhdWx0UHJvdmlkZXIgIT0gbnVsbCk7CisgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lID0gKERFRlN1cHBvcnRlZCA/IGRlZmF1bHRQcm92aWRlci5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgOiBudWxsKTsKKyAgICAgICAgICAgIHZhbGlkVmFsdWVzWzBdID0gZGVmYXVsdEFsZ29yaXRobTsKKyAgICAgICAgICAgIHZhbGlkVmFsdWVzWzFdID0gZGVmYXVsdEFsZ29yaXRobS50b1VwcGVyQ2FzZSgpOworICAgICAgICAgICAgdmFsaWRWYWx1ZXNbMl0gPSBkZWZhdWx0QWxnb3JpdGhtLnRvTG93ZXJDYXNlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgS2V5TWFuYWdlckZhY3RvcnlbXSBjcmVhdGVLTUZhYygpIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoZGVmYXVsdEFsZ29yaXRobSArICIgYWxnb3JpdGhtIGlzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIEtleU1hbmFnZXJGYWN0b3J5W10ga01GID0gbmV3IEtleU1hbmFnZXJGYWN0b3J5WzNdOworICAgICAgICB0cnkgeworICAgICAgICAgICAga01GWzBdID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoZGVmYXVsdEFsZ29yaXRobSk7CisgICAgICAgICAgICBrTUZbMV0gPSBLZXlNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShkZWZhdWx0QWxnb3JpdGhtLAorICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICAgICAga01GWzJdID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoZGVmYXVsdEFsZ29yaXRobSwKKyAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICByZXR1cm4ga01GOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogYXZheC5uZXQuc3NsLktleU1hbmFnZXJGYWN0b3J5I2dldEFsZ29yaXRobSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBbGdvcml0aG0oKQorICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsCisgICAgICAgICAgICAgICAgZGVmYXVsdEFsZ29yaXRobSwKKyAgICAgICAgICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeQorICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZShkZWZhdWx0QWxnb3JpdGhtKS5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsCisgICAgICAgICAgICAgICAgZGVmYXVsdEFsZ29yaXRobSwKKyAgICAgICAgICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeQorICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZShkZWZhdWx0QWxnb3JpdGhtLCBkZWZhdWx0UHJvdmlkZXJOYW1lKQorICAgICAgICAgICAgICAgIC5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsCisgICAgICAgICAgICAgICAgZGVmYXVsdEFsZ29yaXRobSwKKyAgICAgICAgICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShkZWZhdWx0QWxnb3JpdGhtLCBkZWZhdWx0UHJvdmlkZXIpCisgICAgICAgICAgICAgICAgLmdldEFsZ29yaXRobSgpKTsKKyAgICB9CisKKyAgICAgICAvKioKKyAgICAgKiAgVGVzdCBmb3IgPGNvZGU+Z2V0RGVmYXVsdEFsZ29yaXRobSgpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgdmFsdWUgd2hpY2ggaXMgc3BlY2lmb2VkIGluIHNlY3VyaXR5IHByb3BlcnR5CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREZWZhdWx0QWxnb3JpdGhtKCkgeworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0ZWRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBkZWYgPSBLZXlNYW5hZ2VyRmFjdG9yeS5nZXREZWZhdWx0QWxnb3JpdGhtKCk7CisgICAgICAgIGlmIChkZWZhdWx0QWxnb3JpdGhtID09IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydE51bGwoIkRlZmF1bHRBbGdvcml0aG0gbXVzdCBiZSBudWxsIiwgZGVmKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW52YWxpZCBkZWZhdWx0IGFsZ29yaXRobSIsIGRlZiwgZGVmYXVsdEFsZ29yaXRobSk7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIGRlZkEgPSAiUHJvYmEua2V5bWFuYWdlcmZhY3RvcnkuZGVmYXVsLnR5cGUiOworICAgICAgICBTZWN1cml0eS5zZXRQcm9wZXJ0eSgic3NsLktleU1hbmFnZXJGYWN0b3J5LmFsZ29yaXRobSIsIGRlZkEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBkZWZhdWx0QWxnb3JpdGhtIiwKKyAgICAgICAgICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeS5nZXREZWZhdWx0QWxnb3JpdGhtKCksIGRlZkEpOworICAgICAgICBpZiAoZGVmID09IG51bGwpIHsKKyAgICAgICAgICAgIGRlZiA9ICIiOworICAgICAgICB9CisgICAgICAgIFNlY3VyaXR5LnNldFByb3BlcnR5KCJzc2wuS2V5TWFuYWdlckZhY3RvcnkuYWxnb3JpdGhtIiwgZGVmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgZGVmYXVsdEFsZ29yaXRobSIsCisgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnkuZ2V0RGVmYXVsdEFsZ29yaXRobSgpLCBkZWYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb25zOgorICAgICAqIHJldHVybnMgc2VjdXJpdHkgcHJvcGVydHkgInNzbC5LZXlNYW5hZ2VyRmFjdG9yeS5hbGdvcml0aG0iOworICAgICAqIHJldHVybnMgaW5zdGFuY2Ugb2YgS2V5TWFuYWdlckZhY3RvcnkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmcwMSgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0ZWRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIEtleU1hbmFnZXJGYWN0b3J5IGtleU1GOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBrZXlNRiA9IEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIk5vIEtleU1hbmFnZXJGYWN0b3J5IGNyZWF0ZWQiLCBrZXlNRik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkludmFsaWQgYWxnb3JpdGhtIiwga2V5TUYuZ2V0QWxnb3JpdGhtKCksCisgICAgICAgICAgICAgICAgICAgIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG51bGw7CisgICAgICogdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBub3QgY29ycmVjdDsKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmcwMigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG9yIE51bGxQb2ludGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gKGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIGFzIGV4cGVjdGVkIGZvciBhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbCBvciBlbXB0eQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nMDEoKSB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0ZWRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBwcm92aWRlciA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIHByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24gZm9yIG51bGwgcHJvdmlkZXIiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCAiIik7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIGZvciBlbXB0eSBwcm92aWRlciIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOgorICAgICAqIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBudWxsOworICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbm90IGNvcnJlY3Q7CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcwMigpIHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKG51bGwsIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG9yIE51bGxQb2ludGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gKGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaGFzCisgICAgICogaW52YWxpZCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nMDMoKQorICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydGVkTXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMTsgaiA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnZhbGlkVmFsdWVzW2pdKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiTnVTdWNoUHJvdmlkZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gKGFsZ29yaXRobTogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdmFsaWRWYWx1ZXNbaV0gKyAiIHByb3ZpZGVyOiAiICsgaW52YWxpZFZhbHVlc1tqXQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIikiKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QgQXNzZXJ0aW9uOiByZXR1cm5zIGluc3RhbmNlIG9mIEtleU1hbmFnZXJGYWN0b3J5CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcwNCgpCisgICAgICAgIHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgS2V5TWFuYWdlckZhY3Rvcnkga01GOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBrTUYgPSBLZXlNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJObyBLZXlNYW5hZ2VyRmFjdG9yeSBjcmVhdGVkIiwga01GKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGtNRi5nZXRBbGdvcml0aG0oKSwKKyAgICAgICAgICAgICAgICAgICAgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBrTUYuZ2V0UHJvdmlkZXIoKS5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgUHJvdmlkZXIgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aGVuIHByb3ZpZGVyIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmdMamF2YV9zZWN1cml0eV9Qcm92aWRlcjAxKCkKKyAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIgPSBudWxsOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBwcm92aWRlcik7CisgICAgICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIHdoZW4gcHJvdmlkZXIgaXMgbnVsbCIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG51bGw7CisgICAgICogdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBub3QgY29ycmVjdDsKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmdMamF2YV9zZWN1cml0eV9Qcm92aWRlcjAyKCkgeworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0ZWRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShudWxsLCBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG9yIE51bGxQb2ludGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gKGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldLCBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE51U3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgaW5zdGFuY2Ugb2YgS2V5TWFuYWdlckZhY3RvcnkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmdMamF2YV9zZWN1cml0eV9Qcm92aWRlcjAzKCkKKyAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgS2V5TWFuYWdlckZhY3Rvcnkga01GOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBrTUYgPSBLZXlNYW5hZ2VyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJObyBLZXlNYW5hZ2VyRmFjdG9yeSBjcmVhdGVkIiwga01GKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhrTUYuZ2V0QWxnb3JpdGhtKCksIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhrTUYuZ2V0UHJvdmlkZXIoKSwgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPktleU1hbmFnZXJGYWN0b3J5PC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBLZXlNYW5hZ2VyRmFjdG9yeSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgS2V5TWFuYWdlckZhY3RvcnlTcGkgc3BpID0gbmV3IE15S2V5TWFuYWdlckZhY3RvcnlTcGkoKTsKKyAgICAgICAgS2V5TWFuYWdlckZhY3Rvcnkga2V5TUYgPSBuZXcgbXlLZXlNYW5hZ2VyRmFjdG9yeShzcGksIGRlZmF1bHRQcm92aWRlciwKKyAgICAgICAgICAgICAgICBkZWZhdWx0QWxnb3JpdGhtKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwga2V5TUYuZ2V0QWxnb3JpdGhtKCksCisgICAgICAgICAgICAgICAgZGVmYXVsdEFsZ29yaXRobSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwga2V5TUYuZ2V0UHJvdmlkZXIoKSwgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleU1GLmluaXQobnVsbCwgbmV3IGNoYXJbMV0pOworICAgICAgICAgICAgZmFpbCgiVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQ6ICIrZS50b1N0cmluZygpKyIgd2FzIHRocm93biIpOworICAgICAgICB9CisgICAgICAgIGtleU1GID0gbmV3IG15S2V5TWFuYWdlckZhY3RvcnkobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoIkFhbGdvcml0aG0gbXVzdCBiZSBudWxsIiwga2V5TUYuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICBhc3NlcnROdWxsKCJQcm92aWRlciBtdXN0IGJlIG51bGwiLCBrZXlNRi5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleU1GLmdldEtleU1hbmFnZXJzKCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyRmFjdG9yeSNnZXRLZXlNYW5hZ2VycygpCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEtleU1hbmFnZXJzKCkKKyAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgIEtleU1hbmFnZXJGYWN0b3J5IGttZiA9IEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGRlZmF1bHRBbGdvcml0aG0pOworICAgICAgICBjaGFyW10gcGFzcyA9ICJwYXNzd29yZCIudG9DaGFyQXJyYXkoKTsKKyAgICAgICAga21mLmluaXQobnVsbCwgcGFzcyk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIktleSBtYW5hZ2VyIGFycmF5IGlzIG51bGwiLCBrbWYuZ2V0S2V5TWFuYWdlcnMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHNpemUgb2YgYXJyYXkiLAorICAgICAgICAgICAgICAgIDEsIGttZi5nZXRLZXlNYW5hZ2VycygpLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogYXZheC5uZXQuc3NsLktleU1hbmFnZXJGYWN0b3J5I2dldFByb3ZpZGVyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFByb3ZpZGVyKCkKKyAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwKKyAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXIsCisgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2UoZGVmYXVsdEFsZ29yaXRobSkuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwKKyAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXIsCisgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2UoZGVmYXVsdEFsZ29yaXRobSwgZGVmYXVsdFByb3ZpZGVyTmFtZSkKKyAgICAgICAgICAgICAgICAuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwKKyAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXIsCisgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoZGVmYXVsdEFsZ29yaXRobSwgZGVmYXVsdFByb3ZpZGVyKQorICAgICAgICAgICAgICAgIC5nZXRQcm92aWRlcigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5pbml0KEtleVN0b3JlIGtleVN0b3JlLCBjaGFyW10gcGFzc3dvcmQpPC9jb2RlPiBhbmQKKyAgICAgKiA8Y29kZT5nZXRLZXlNYW5hZ2VycygpPC9jb2RlPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBub3QgZW1wdHkgS2V5TWFuYWdlciBhcnJheQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5pdExqYXZhX3NlY3VyaXR5X0tleVN0b3JlJEMoKQorICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICBLZXlTdG9yZUV4Y2VwdGlvbiwgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRlZE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgS2V5TWFuYWdlckZhY3RvcnlbXSBrZXlNRiA9IGNyZWF0ZUtNRmFjKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIktleU1hbmFnZXJGYWN0b3J5IG9iamVjdCB3ZXJlIG5vdCBjcmVhdGVkIiwga2V5TUYpOworICAgICAgICBLZXlTdG9yZSBrc051bGwgPSBudWxsOworICAgICAgICBLZXlNYW5hZ2VyW10ga207CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga2V5TUYubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGtleU1GW2ldLmluaXQoa3NOdWxsLCBuZXcgY2hhclsxMF0pOworICAgICAgICAgICAga20gPSBrZXlNRltpXS5nZXRLZXlNYW5hZ2VycygpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiUmVzdWx0IHNob3VsZCBub3QgYmUgbnVsbCIsIGttKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkxlbmd0aCBvZiByZXN1bHQgS2V5TWFuYWdlciBhcnJheSBzaG91bGQgbm90IGJlIDAiLAorICAgICAgICAgICAgICAgICAgICAoa20ubGVuZ3RoID4gMCkpOworICAgICAgICB9CisgICAgICAgIEtleVN0b3JlIGtzOworICAgICAgICB0cnkgeworICAgICAgICAgICAga3MgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAgICAgIGtzLmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZS50b1N0cmluZygpICsgImRlZmF1bHQgS2V5U3RvcmUgdHlwZSBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkOiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGtleU1GLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGtleU1GW2ldLmluaXQoa3MsIG5ldyBjaGFyWzEwXSk7CisgICAgICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBrbSA9IGtleU1GW2ldLmdldEtleU1hbmFnZXJzKCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJSZXN1bHQgaGFzIG5vdCBiZSBudWxsIiwga20pOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTGVuZ3RoIG9mIHJlc3VsdCBLZXlNYW5hZ2VyIGFycmF5IHNob3VsZCBub3QgYmUgMCIsCisgICAgICAgICAgICAgICAgICAgIChrbS5sZW5ndGggPiAwKSk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmluaXQoTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzIHBhcmFtcyk8L2NvZGU+CisgICAgICogQXNzZXJ0aW9uOgorICAgICAqIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHdoZW4gcGFyYW1zIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luaXRMamF2YXhfbmV0X3NzbF9NYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMoKQorICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0ZWRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyBwYXIgPSBudWxsOworICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeVtdIGtleU1GID0gY3JlYXRlS01GYWMoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiS2V5TWFuYWdlckZhY3Rvcnkgb2JqZWN0IHdlcmUgbm90IGNyZWF0ZWQiLCBrZXlNRik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga2V5TUYubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAga2V5TUZbaV0uaW5pdChwYXIpOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgS2V5U3RvcmUuUHJvdGVjdGlvblBhcmFtZXRlciBwcCA9IG5ldyBQcm90ZWN0aW9uUGFyYW1ldGVySW1wbCgpOworICAgICAgICBLZXlTdG9yZS5CdWlsZGVyIGJsZCA9IEtleVN0b3JlLkJ1aWxkZXIubmV3SW5zdGFuY2UoInRlc3RUeXBlIiwgbnVsbCwgcHApOworICAgICAgICBhc3NlcnROb3ROdWxsKCJOdWxsIG9iamVjdCBLZXlTdG9yZS5CdWlsZGVyIiwgYmxkKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5TWFuYWdlckZhY3Rvcnkga21mID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoZGVmYXVsdEFsZ29yaXRobSk7CisgICAgICAgICAgICBLZXlTdG9yZUJ1aWxkZXJQYXJhbWV0ZXJzIGtzcCA9IG5ldyBLZXlTdG9yZUJ1aWxkZXJQYXJhbWV0ZXJzKGJsZCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGtzcC5nZXRQYXJhbWV0ZXJzKCkpOworICAgICAgICAgICAga21mLmluaXQoa3NwKTsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKK30KKworLyoqCisgKiBBZGRpdGlvbmFsIGNsYXNzIGZvciBLZXlNYW5hZ2VyRmFjdG9yeSBjb25zdHJ1Y3RvciB2ZXJpZmljYXRpb24KKyAqLworY2xhc3MgbXlLZXlNYW5hZ2VyRmFjdG9yeSBleHRlbmRzIEtleU1hbmFnZXJGYWN0b3J5IHsKKyAgICBwdWJsaWMgbXlLZXlNYW5hZ2VyRmFjdG9yeShLZXlNYW5hZ2VyRmFjdG9yeVNwaSBzcGksIFByb3ZpZGVyIHByb3YsCisgICAgICAgICAgICBTdHJpbmcgYWxnKSB7CisgICAgICAgIHN1cGVyKHNwaSwgcHJvdiwgYWxnKTsKKyAgICB9Cit9CisKK2NsYXNzIFByb3RlY3Rpb25QYXJhbWV0ZXJJbXBsIGltcGxlbWVudHMgS2V5U3RvcmUuUHJvdGVjdGlvblBhcmFtZXRlciB7CisgICAgUHJvdGVjdGlvblBhcmFtZXRlckltcGwoKXt9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvS2V5TWFuYWdlckZhY3RvcnkyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL0tleU1hbmFnZXJGYWN0b3J5MlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZDQ0Mzk2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL0tleU1hbmFnZXJGYWN0b3J5MlRlc3QuamF2YQpAQCAtMCwwICsxLDI2MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5VbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uOworCitpbXBvcnQgamF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyRmFjdG9yeTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLk1hbmFnZXJGYWN0b3J5UGFyYW1ldGVyczsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlNwaUVuZ1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnRlc3RzLnN1cHBvcnQuTXlLZXlNYW5hZ2VyRmFjdG9yeVNwaTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIEtleU1hbmFnZXJGYWN0b3J5IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcworICoKKyAqLworcHVibGljIGNsYXNzIEtleU1hbmFnZXJGYWN0b3J5MlRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHNydktleU1hbmFnZXJGYWN0b3J5ID0gIktleU1hbmFnZXJGYWN0b3J5IjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBkZWZhdWx0QWxnID0gIktleU1GIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBLZXlNYW5hZ2VyRmFjdG9yeVByb3ZpZGVyQ2xhc3MgPSAib3JnLmFwYWNoZS5oYXJtb255LnhuZXQudGVzdHMuc3VwcG9ydC5NeUtleU1hbmFnZXJGYWN0b3J5U3BpIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGludmFsaWRWYWx1ZXMgPSBTcGlFbmdVdGlscy5pbnZhbGlkVmFsdWVzOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gdmFsaWRWYWx1ZXM7CisKKyAgICBzdGF0aWMgeworICAgICAgICB2YWxpZFZhbHVlcyA9IG5ldyBTdHJpbmdbNF07CisgICAgICAgIHZhbGlkVmFsdWVzWzBdID0gZGVmYXVsdEFsZzsKKyAgICAgICAgdmFsaWRWYWx1ZXNbMV0gPSBkZWZhdWx0QWxnLnRvTG93ZXJDYXNlKCk7CisgICAgICAgIHZhbGlkVmFsdWVzWzJdID0gIktleW1mIjsKKyAgICAgICAgdmFsaWRWYWx1ZXNbM10gPSAia0VZTUYiOworICAgIH0KKworICAgIFByb3ZpZGVyIG1Qcm92OworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgbVByb3YgPSAobmV3IFNwaUVuZ1V0aWxzKCkpLm5ldyBNeVByb3ZpZGVyKCJNeUtNRlByb3ZpZGVyIiwKKyAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yIHRlc3RpbmciLCBzcnZLZXlNYW5hZ2VyRmFjdG9yeS5jb25jYXQoIi4iKQorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChkZWZhdWx0QWxnKSwgS2V5TWFuYWdlckZhY3RvcnlQcm92aWRlckNsYXNzKTsKKyAgICAgICAgU2VjdXJpdHkuaW5zZXJ0UHJvdmlkZXJBdChtUHJvdiwgMik7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIFRlc3RDYXNlI3RlYXJEb3duKCkKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcihtUHJvdi5nZXROYW1lKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja1Jlc3VsdChLZXlNYW5hZ2VyRmFjdG9yeSBrZXlNRikKKyAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEtleVN0b3JlIGtTdG9yZSA9IG51bGw7CisgICAgICAgIE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyBtZnAgPSBudWxsOworCisgICAgICAgIGNoYXJbXSBwYXNzID0geyAnYScsICdiJywgJ2MnIH07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleU1GLmluaXQoa1N0b3JlLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIktleVN0b3JlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5TUYuaW5pdChrU3RvcmUsIHBhc3MpOworICAgICAgICAgICAgZmFpbCgiVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5TUYuaW5pdChtZnApOworICAgICAgICAgICAgZmFpbCgiSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROdWxsKCJnZXRLZXlNYW5hZ2VycygpIHNob3VsZCByZXR1cm4gbnVsbCBvYmplY3QiLCBrZXlNRgorICAgICAgICAgICAgICAgIC5nZXRLZXlNYW5hZ2VycygpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga1N0b3JlID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSk7CisgICAgICAgICAgICBrU3RvcmUubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiZGVmYXVsdCBrZXlzdG9yZSBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAga2V5TUYuaW5pdChrU3RvcmUsIHBhc3MpOworCisgICAgICAgIG1mcCA9IG5ldyBNeUtleU1hbmFnZXJGYWN0b3J5U3BpLlBhcmFtZXRlcnMoa1N0b3JlLCBudWxsKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleU1GLmluaXQobWZwKTsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgbWZwID0gbmV3IE15S2V5TWFuYWdlckZhY3RvcnlTcGkuUGFyYW1ldGVycyhrU3RvcmUsIHBhc3MpOworICAgICAgICBrZXlNRi5pbml0KG1mcCk7CisgICAgfQorICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb25zOgorICAgICAqIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBudWxsOworICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbm90IGNvcnJlY3Q7CisgICAgICogcmV0dXJucyBLZXlNYW5hZ2VyRmFjdG9yeSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG9yIE51bGxQb2ludGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gKGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIChhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeSBrZXlNRjsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAga2V5TUYgPSBLZXlNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBrZXlNRi5nZXRBbGdvcml0aG0oKSwKKyAgICAgICAgICAgICAgICAgICAgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBrZXlNRi5nZXRQcm92aWRlcigpLCBtUHJvdik7CisgICAgICAgICAgICBjaGVja1Jlc3VsdChrZXlNRik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbnM6CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG51bGw7CisgICAgICogdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBub3QgY29ycmVjdDsKKyAgICAgKiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbCBvciBlbXB0eTsKKyAgICAgKiB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBhdmFpbGFibGU7CisgICAgICogcmV0dXJucyBLZXlNYW5hZ2VyRmFjdG9yeSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZygpCisgICAgICAgIHRocm93cyBFeGNlcHRpb24KKyAgICB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShudWxsLCBtUHJvdi5nZXROYW1lKCkpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG9yIE51bGxQb2ludGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gKGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldLCBtUHJvdi5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHByb3YgPSBudWxsOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBwcm92KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBudWxsIChhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sICIiKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBlbXB0eSAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDE7IGogPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW52YWxpZFZhbHVlc1tqXSk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIChhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiIHByb3ZpZGVyOiAiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tqXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgS2V5TWFuYWdlckZhY3Rvcnkga2V5TUY7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGtleU1GID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIG1Qcm92CisgICAgICAgICAgICAgICAgICAgIC5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwga2V5TUYuZ2V0QWxnb3JpdGhtKCksCisgICAgICAgICAgICAgICAgICAgIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwga2V5TUYuZ2V0UHJvdmlkZXIoKS5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgIG1Qcm92LmdldE5hbWUoKSk7CisgICAgICAgICAgICBjaGVja1Jlc3VsdChrZXlNRik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBQcm92aWRlciBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kCisgICAgICogQXNzZXJ0aW9uczoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbnVsbDsKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG5vdCBjb3JyZWN0OworICAgICAqIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBudWxsOworICAgICAqIHJldHVybnMgS2V5TWFuYWdlckZhY3Rvcnkgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfc2VjdXJpdHlfUHJvdmlkZXIoKQorICAgICAgICB0aHJvd3MgRXhjZXB0aW9uCisgICAgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UobnVsbCwgbVByb3YpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG9yIE51bGxQb2ludGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gKGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwgbVByb3YpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgUHJvdmlkZXIgcHJvdiA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIHByb3YpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHByb3ZpZGVyIGlzIG51bGwgKGFsZ29yaXRobTogIgorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChpbnZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIEtleU1hbmFnZXJGYWN0b3J5IGtleU1GOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBrZXlNRiA9IEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBtUHJvdik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBrZXlNRi5nZXRBbGdvcml0aG0oKSwKKyAgICAgICAgICAgICAgICAgICAgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBrZXlNRi5nZXRQcm92aWRlcigpLCBtUHJvdik7CisgICAgICAgICAgICBjaGVja1Jlc3VsdChrZXlNRik7CisgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9LZXlNYW5hZ2VyRmFjdG9yeVNwaVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9LZXlNYW5hZ2VyRmFjdG9yeVNwaVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZDQ0ZmRhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL0tleU1hbmFnZXJGYWN0b3J5U3BpVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTUxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5VbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleU1hbmFnZXJGYWN0b3J5U3BpOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnhuZXQudGVzdHMuc3VwcG9ydC5LZXlNYW5hZ2VyRmFjdG9yeVNwaUltcGw7CisKK3B1YmxpYyBjbGFzcyBLZXlNYW5hZ2VyRmFjdG9yeVNwaVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLktleU1hbmFnZXJGYWN0b3J5U3BpI0tleU1hbmFnZXJGYWN0b3J5U3BpKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5TWFuYWdlckZhY3RvcnlTcGlJbXBsIGttZiA9IG5ldyBLZXlNYW5hZ2VyRmFjdG9yeVNwaUltcGwoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoa21mIGluc3RhbmNlb2YgS2V5TWFuYWdlckZhY3RvcnlTcGkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBFeGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLktleU1hbmFnZXJGYWN0b3J5U3BpI0tlbmdpbmVJbml0KEtleVN0b3JlIGtzLCBjaGFyW10gcGFzc3dvcmQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9lbmdpbmVJbml0XzAxKCkgeworICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeVNwaUltcGwga21mID0gbmV3IEtleU1hbmFnZXJGYWN0b3J5U3BpSW1wbCgpOworICAgICAgICBLZXlTdG9yZSBrczsKKyAgICAgICAgY2hhcltdIHBzdyA9ICJwYXNzd29yZCIudG9DaGFyQXJyYXkoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga21mLmVuZ2luZUluaXQobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24ga3NlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrbWYuZW5naW5lSW5pdChudWxsLCBwc3cpOworICAgICAgICAgICAgZmFpbCgiS2V5U3RvcmVFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiB1a2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIEtleVN0b3JlRXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAga3MgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAgICAgIGttZi5lbmdpbmVJbml0KGtzLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIlVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uIHVrZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVN0b3JlIGtzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICAgICAga3N0LmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBrbWYuZW5naW5lSW5pdChrc3QsIHBzdyk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLktleU1hbmFnZXJGYWN0b3J5U3BpI0tlbmdpbmVJbml0KE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyBzcGVjKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZW5naW5lSW5pdF8wMigpIHsKKyAgICAgICAgS2V5TWFuYWdlckZhY3RvcnlTcGlJbXBsIGttZiA9IG5ldyBLZXlNYW5hZ2VyRmFjdG9yeVNwaUltcGwoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga21mLmVuZ2luZUluaXQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBpYXBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2hhcltdIHBzdyA9ICJwYXNzd29yZCIudG9DaGFyQXJyYXkoKTsKKyAgICAgICAgICAgIFBhcmFtZXRlcnMgcHIgPSBuZXcgUGFyYW1ldGVycyhwc3cpOworICAgICAgICAgICAga21mLmVuZ2luZUluaXQocHIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB1bmV4cGVjdGVkIGV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLktleU1hbmFnZXJGYWN0b3J5U3BpI2VuZ2luZUdldEtleU1hbmFnZXJzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VuZ2luZUdldEtleU1hbmFnZXJzKCkgeworICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeVNwaUltcGwga21mID0gbmV3IEtleU1hbmFnZXJGYWN0b3J5U3BpSW1wbCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlNYW5hZ2VyW10ga20gPSBrbWYuZW5naW5lR2V0S2V5TWFuYWdlcnMoKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpc2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNoYXJbXSBwc3cgPSAicGFzc3dvcmQiLnRvQ2hhckFycmF5KCk7CisgICAgICAgICAgICBQYXJhbWV0ZXJzIHByID0gbmV3IFBhcmFtZXRlcnMocHN3KTsKKyAgICAgICAgICAgIGttZi5lbmdpbmVJbml0KHByKTsKKyAgICAgICAgICAgIEtleU1hbmFnZXJbXSBrbSA9IGttZi5lbmdpbmVHZXRLZXlNYW5hZ2VycygpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiT2JqZWN0IGlzIG5vdCBOVUxMIiwga20pOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB1bmV4cGVjdGVkIGV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgUGFyYW1ldGVycyBpbXBsZW1lbnRzIE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyB7CisgICAgICAgIHByaXZhdGUgY2hhcltdIHBhc3NXRDsKKworICAgICAgICBwdWJsaWMgUGFyYW1ldGVycyAoY2hhcltdIHBhc3MpIHsKKyAgICAgICAgICAgIHRoaXMucGFzc1dEID0gcGFzczsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgY2hhcltdIGdldFBhc3N3b3JkKCkgeworICAgICAgICAgICAgcmV0dXJuIHBhc3NXRDsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL0tleVN0b3JlQnVpbGRlclBhcmFtZXRlcnNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvS2V5U3RvcmVCdWlsZGVyUGFyYW1ldGVyc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMmZlNDljCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL0tleVN0b3JlQnVpbGRlclBhcmFtZXRlcnNUZXN0LmphdmEKQEAgLTAsMCArMSwxMDEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyRmFjdG9yeVNwaTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleVN0b3JlQnVpbGRlclBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgS2V5U3RvcmVCdWlsZGVyUGFyYW1ldGVyc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLktleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMjS2V5U3RvcmVCdWlsZGVyUGFyYW1ldGVycyhLZXlTdG9yZS5CdWlsZGVyIGJ1aWxkZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcjAxKCkgeworICAgICAgICAvLyBOdWxsIHBhcmFtZXRlcgorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEtleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMoKEtleVN0b3JlLkJ1aWxkZXIpIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gTm90IG51bGwgcGFyYW1ldGVyCisgICAgICAgIEtleVN0b3JlLlByb3RlY3Rpb25QYXJhbWV0ZXIgcHAgPSBuZXcgUHJvdGVjdGlvblBhcmFtZXRlckltcGwoKTsKKyAgICAgICAgS2V5U3RvcmUuQnVpbGRlciBibGQgPSBLZXlTdG9yZS5CdWlsZGVyLm5ld0luc3RhbmNlKCJ0ZXN0VHlwZSIsIG51bGwsIHBwKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTnVsbCBvYmplY3QgS2V5U3RvcmUuQnVpbGRlciIsIGJsZCk7CisgICAgICAgIEtleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMga3NwID0gbmV3IEtleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMoYmxkKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChrc3AuZ2V0UGFyYW1ldGVycygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLktleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMjS2V5U3RvcmVCdWlsZGVyUGFyYW1ldGVycyhMaXN0IHBhcmFtZXRlcnMpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcjAyKCkgeworCisgICAgICAgIC8vIE51bGwgcGFyYW1ldGVyCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZUJ1aWxkZXJQYXJhbWV0ZXJzIGtzcCA9IG5ldyBLZXlTdG9yZUJ1aWxkZXJQYXJhbWV0ZXJzKChMaXN0KSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEVtcHR5IHBhcmFtZXRlcgorICAgICAgICBMaXN0IGxzRW1wdHkgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMga3NwID0gbmV3IEtleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMobHNFbXB0eSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gTm90IG51bGwgcGFyYW1ldGVyCisgICAgICAgIExpc3QgbHNGaWxlZCA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBsc0ZpbGVkLmFkZCgiUGFyYW1ldGVyMSIpOworICAgICAgICBsc0ZpbGVkLmFkZCgiUGFyYW1ldGVyMiIpOworICAgICAgICBuZXcgS2V5U3RvcmVCdWlsZGVyUGFyYW1ldGVycyhsc0ZpbGVkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLktleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMjZ2V0UGFyYW1ldGVycygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQYXJhbWV0ZXJzKCkgeworICAgICAgICBTdHJpbmdbXSBwYXJhbSA9IHsiUGFyYW1ldGVyMSIsICJQYXJhbWV0ZXIyIiwgIlBhcmFtZXRlcjMifTsKKyAgICAgICAgTGlzdCBscyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcmFtLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBscy5hZGQocGFyYW1baV0pOworICAgICAgICB9CisgICAgICAgIEtleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMga3NwID0gbmV3IEtleVN0b3JlQnVpbGRlclBhcmFtZXRlcnMobHMpOworICAgICAgICBMaXN0IHJlc19saXN0ID0ga3NwLmdldFBhcmFtZXRlcnMoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlc19saXN0LmFkZCgidGVzdCIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIE9iamVjdFtdIHJlcyA9IHJlc19saXN0LnRvQXJyYXkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlcy5sZW5ndGgsIHBhcmFtLmxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMocGFyYW1baV0sIHJlc1tpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBQcm90ZWN0aW9uUGFyYW1ldGVySW1wbCBpbXBsZW1lbnRzIEtleVN0b3JlLlByb3RlY3Rpb25QYXJhbWV0ZXIgeworICAgICAgICBwcml2YXRlIFByb3RlY3Rpb25QYXJhbWV0ZXJJbXBsKCkge30KKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xDb250ZXh0MVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xDb250ZXh0MVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZTUxY2MwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1NTTENvbnRleHQxVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTk5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlNYW5hZ2VtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5VbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uOworCitpbXBvcnQgamF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlckZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xDb250ZXh0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMQ29udGV4dFNwaTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldEZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uQ29udGV4dDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXJGYWN0b3J5OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuU3BpRW5nVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnhuZXQudGVzdHMuc3VwcG9ydC5NeVNTTENvbnRleHRTcGk7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlNTTENvbnRleHQ8L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBTU0xDb250ZXh0MVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgc3J2U1NMQ29udGV4dCA9ICJTU0xDb250ZXh0IjsKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBkZWZhdWx0UHJvdG9jb2wgPSAiVExTIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTm90U3VwcG9ydE1zZyA9ICJEZWZhdWx0IHByb3RvY29sIGlzIG5vdCBzdXBwb3J0ZWQiOworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZWZhdWx0UHJvdmlkZXJOYW1lID0gbnVsbDsKKyAgICBwcml2YXRlIHN0YXRpYyBQcm92aWRlciBkZWZhdWx0UHJvdmlkZXIgPSBudWxsOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGludmFsaWRWYWx1ZXMgPSBTcGlFbmdVdGlscy5pbnZhbGlkVmFsdWVzOworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gREVGU3VwcG9ydGVkID0gZmFsc2U7CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gdmFsaWRWYWx1ZXMgPSBuZXcgU3RyaW5nWzNdOworICAgIHN0YXRpYyB7CisgICAgICAgIGRlZmF1bHRQcm92aWRlciA9IFNwaUVuZ1V0aWxzLmlzU3VwcG9ydChkZWZhdWx0UHJvdG9jb2wsIHNydlNTTENvbnRleHQpOworICAgICAgICBERUZTdXBwb3J0ZWQgPSAoZGVmYXVsdFByb3ZpZGVyICE9IG51bGwpOworICAgICAgICBpZiAoREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lID0gKERFRlN1cHBvcnRlZCA/IGRlZmF1bHRQcm92aWRlci5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgOiBudWxsKTsKKyAgICAgICAgICAgIHZhbGlkVmFsdWVzWzBdID0gZGVmYXVsdFByb3RvY29sOworICAgICAgICAgICAgdmFsaWRWYWx1ZXNbMV0gPSBkZWZhdWx0UHJvdG9jb2wudG9VcHBlckNhc2UoKTsKKyAgICAgICAgICAgIHZhbGlkVmFsdWVzWzJdID0gZGVmYXVsdFByb3RvY29sLnRvTG93ZXJDYXNlKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBkZWZhdWx0UHJvdG9jb2wgPSBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIFNTTENvbnRleHRbXSBjcmVhdGVTU0xDb24oKSB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKGRlZmF1bHRQcm90b2NvbCArICIgcHJvdG9jb2wgaXMgbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgU1NMQ29udGV4dFtdIHNzbEMgPSBuZXcgU1NMQ29udGV4dFszXTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzbENbMF0gPSBTU0xDb250ZXh0LmdldEluc3RhbmNlKGRlZmF1bHRQcm90b2NvbCk7CisgICAgICAgICAgICBzc2xDWzFdID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZShkZWZhdWx0UHJvdG9jb2wsIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgICAgICBzc2xDWzJdID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZShkZWZhdWx0UHJvdG9jb2wsCisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgcmV0dXJuIHNzbEM7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5TU0xDb250ZXh0PC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IHJldHVybnMKKyAgICAgKiBTU0xDb250ZXh0IG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YXhfbmV0X3NzbF9TU0xDb250ZXh0U3BpTGphdmFfc2VjdXJpdHlfUHJvdmlkZXJMamF2YV9sYW5nX1N0cmluZygpCisgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgU1NMQ29udGV4dFNwaSBzcGkgPSBuZXcgTXlTU0xDb250ZXh0U3BpKCk7CisgICAgICAgIFNTTENvbnRleHQgc3NsQ29udGV4dCA9IG5ldyBNeVNzbENvbnRleHQoc3BpLCBkZWZhdWx0UHJvdmlkZXIsCisgICAgICAgICAgICAgICAgZGVmYXVsdFByb3RvY29sKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdG9jb2wiLCBkZWZhdWx0UHJvdG9jb2wsCisgICAgICAgICAgICAgICAgc3NsQ29udGV4dC5nZXRQcm90b2NvbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBkZWZhdWx0UHJvdmlkZXIsCisgICAgICAgICAgICAgICAgc3NsQ29udGV4dC5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgVHJ1c3RNYW5hZ2VyW10gdG0gPSBudWxsOworICAgICAgICBLZXlNYW5hZ2VyW10ga20gPSBudWxsOworICAgICAgICBzc2xDb250ZXh0LmluaXQoa20sIHRtLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJObyBTU0xFbmdpbmUgY3JlYXRlZCIsCisgICAgICAgICAgICAgICAgc3NsQ29udGV4dC5jcmVhdGVTU0xFbmdpbmUoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIk5vIFNTTEVuZ2luZSBjcmVhdGVkIiwKKyAgICAgICAgICAgICAgICBzc2xDb250ZXh0LmNyZWF0ZVNTTEVuZ2luZSgiaG9zdCIsIDg4ODgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzbENvbnRleHQuaW5pdChrbSwgdG0sIG51bGwpOworICAgICAgICAgICAgZmFpbCgiS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIGZvciBudWxsICIKKyAgICAgICAgICAgICAgICAgICAgKyAiU2VjdXJlUmFuZG9tIik7CisgICAgICAgIH0gY2F0Y2ggKEtleU1hbmFnZW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgc3NsQ29udGV4dCA9IG5ldyBNeVNzbENvbnRleHQobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCBwcm90b2NvbCIsIHNzbENvbnRleHQuZ2V0UHJvdG9jb2woKSk7CisgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCBwcm92aWRlciIsIHNzbENvbnRleHQuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2xDb250ZXh0LmNyZWF0ZVNTTEVuZ2luZSgpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzbENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24KKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTENvbnRleHQjY3JlYXRlU1NMRW5naW5lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NyZWF0ZVNTTEVuZ2luZSgpIHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgIFNTTENvbnRleHRTcGkgc3BpID0gbmV3IE15U1NMQ29udGV4dFNwaSgpOworICAgICAgICBTU0xDb250ZXh0IHNzbENvbnRleHQgPSBuZXcgTXlTc2xDb250ZXh0KHNwaSwgZGVmYXVsdFByb3ZpZGVyLAorICAgICAgICAgICAgICAgIGRlZmF1bHRQcm90b2NvbCk7CisgICAgICAgIHNzbENvbnRleHQuaW5pdChudWxsLCBudWxsLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICBTU0xFbmdpbmUgc3NsRW5naW5lID0gc3NsQ29udGV4dC5jcmVhdGVTU0xFbmdpbmUoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiU1NMIGVuZ2luZSBpcyBudWxsIiwgc3NsRW5naW5lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24KKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTENvbnRleHQjY3JlYXRlU1NMRW5naW5lKGphdmEubGFuZy5TdHJpbmcsIGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NyZWF0ZVNTTEVuZ2luZUxqYXZhX2xhbmdfU3RyaW5nSSgpCisgICAgICAgIHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgIFNTTENvbnRleHRTcGkgc3BpID0gbmV3IE15U1NMQ29udGV4dFNwaSgpOworICAgICAgICBTU0xDb250ZXh0IHNzbENvbnRleHQgPSBuZXcgTXlTc2xDb250ZXh0KHNwaSwgZGVmYXVsdFByb3ZpZGVyLAorICAgICAgICAgICAgICAgIGRlZmF1bHRQcm90b2NvbCk7CisgICAgICAgIHNzbENvbnRleHQuaW5pdChudWxsLCBudWxsLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICBTU0xFbmdpbmUgc3NsRW5naW5lID0gc3NsQ29udGV4dC5jcmVhdGVTU0xFbmdpbmUoInd3dy5mb3J0aWZ5Lm5ldCIsIDgwKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiU1NMIGVuZ2luZSBpcyBudWxsIiwgc3NsRW5naW5lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRDbGllbnRTZXNzaW9uQ29udGV4dCgpPC9jb2RlPgorICAgICAqIDxjb2RlPmdldFNlcnZpY2VTZXNzaW9uQ29udGV4dCgpPC9jb2RlPgorICAgICAqIG1ldGhvZHMgQXNzZXJ0aW9uOiByZXR1cm5zIGNvcnJlc3BvbmRlbnQgb2JqZWN0CisgICAgICogQHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDbGllbnRTZXNzaW9uQ29udGV4dCgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIEtleU1hbmFnZW1lbnRFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBTU0xDb250ZXh0W10gc3NsQyA9IGNyZWF0ZVNTTENvbigpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJTU0xDb250ZXh0IG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIHNzbEMpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNzbEMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHNzbENbaV0uaW5pdChudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIkNsaWVudCBzZXNzaW9uIGlzIGluY29ycmVjdGx5IGluc3RhbnRpYXRlZDogIiArIGksCisgICAgICAgICAgICAgICAgICAgIHNzbENbaV0uZ2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJTZXJ2ZXIgc2Vzc2lvbiBpcyBpbmNvcnJlY3RseSBpbnN0YW50aWF0ZWQ6ICIgKyBpLAorICAgICAgICAgICAgICAgICAgICBzc2xDW2ldLmdldFNlcnZlclNlc3Npb25Db250ZXh0KCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIHByb3RvY29sKTwvY29kZT4gbWV0aG9kIEFzc2VydGlvbjoKKyAgICAgKiByZXR1cm5zIFNTTENvbnRleHQgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nMDEoKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFNTTENvbnRleHQgc3NsQ29udGV4dDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc3NsQ29udGV4dCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTm8gU1NMQ29udGV4dCBjcmVhdGVkIiwgc3NsQ29udGV4dCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkludmFsaWQgcHJvdG9jb2wiLCB2YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgc3NsQ29udGV4dC5nZXRQcm90b2NvbCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBwcm90b2NvbCk8L2NvZGU+IG1ldGhvZCBBc3NlcnRpb246CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gcHJvdG9jb2wgaXMgbnVsbDsgdGhyb3dzCisgICAgICogTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gcHJvdG9jb2wgaXMgbm90IGNvcnJlY3Q7CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nMDIoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTU0xDb250ZXh0LmdldEluc3RhbmNlKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG9yIE51bGxQb2ludGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gKHByb3RvY29sIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTU0xDb250ZXh0LmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3YXMgbm90IHRocm93biBhcyBleHBlY3RlZCBmb3IgcHJvdmlkZXI6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBwcm90b2NvbCwgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QgQXNzZXJ0aW9uOiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbAorICAgICAqIG9yIGVtcHR5CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcwMSgpIHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBwcm92aWRlciA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgU1NMQ29udGV4dC5nZXRJbnN0YW5jZShkZWZhdWx0UHJvdG9jb2wsIHByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBudWxsIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTU0xDb250ZXh0LmdldEluc3RhbmNlKGRlZmF1bHRQcm90b2NvbCwgIiIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHByb3ZpZGVyIGlzIGVtcHR5Iik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIHByb3RvY29sLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZCBBc3NlcnRpb246IHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIHByb3RvY29sIGlzIG51bGw7CisgICAgICogdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIHByb3RvY29sIGlzIG5vdCBjb3JyZWN0OworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nMDIoKSB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMQ29udGV4dC5nZXRJbnN0YW5jZShudWxsLCBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBvciBOdWxsUG9pbnRlckV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIChwcm90b2NvbCBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgU1NMQ29udGV4dC5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldLCBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2FzIG5vdCB0aHJvd24gYXMgZXhwZWN0ZWQgKHByb3RvY29sOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgcHJvdG9jb2wsIFN0cmluZyBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kIEFzc2VydGlvbjogdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaGFzCisgICAgICogaW52YWxpZCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nMDMoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU1NMQ29udGV4dC5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tqXSwgaW52YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIk51U3VjaFByb3ZpZGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIChwcm90b2NvbDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQodmFsaWRWYWx1ZXNbal0pLmNvbmNhdCgiIHByb3ZpZGVyOiAiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgcHJvdG9jb2wsIFN0cmluZyBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kIEFzc2VydGlvbjogcmV0dXJucyBpbnN0YW5jZSBvZiBTU0xDb250ZXh0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcwNCgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFNTTENvbnRleHQgc3NsQ29udGV4dDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc3NsQ29udGV4dCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sCisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTm90IFNTTENvbnRleHQgY3JlYXRlZCIsIHNzbENvbnRleHQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbnZhbGlkIHByb3RvY29sIiwKKyAgICAgICAgICAgICAgICAgICAgdmFsaWRWYWx1ZXNbaV0sIHNzbENvbnRleHQuZ2V0UHJvdG9jb2woKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkludmFsaWQgcHJvdmlkZXIiLAorICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXIsIHNzbENvbnRleHQuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgcHJvdG9jb2wsIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QgQXNzZXJ0aW9uOiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZ0xqYXZhX3NlY3VyaXR5X1Byb3ZpZGVyMDEoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIgPSBudWxsOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFNTTENvbnRleHQuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIHByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBudWxsIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIHByb3RvY29sLCBQcm92aWRlciBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kIEFzc2VydGlvbjogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gcHJvdG9jb2wgaXMgbnVsbDsKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gcHJvdG9jb2wgaXMgbm90IGNvcnJlY3Q7CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfc2VjdXJpdHlfUHJvdmlkZXIwMigpIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNTTENvbnRleHQuZ2V0SW5zdGFuY2UobnVsbCwgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBvciBOdWxsUG9pbnRlckV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIChwcm90b2NvbCBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgU1NMQ29udGV4dC5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldLCBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3YXMgbm90IHRocm93biBhcyBleHBlY3RlZCIpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBwcm90b2NvbCwgUHJvdmlkZXIgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZCBBc3NlcnRpb246IHJldHVybnMgaW5zdGFuY2Ugb2YgU1NMQ29udGV4dAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZ0xqYXZhX3NlY3VyaXR5X1Byb3ZpZGVyMDMoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgU1NMQ29udGV4dCBzc2xDb250ZXh0OworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBzc2xDb250ZXh0ID0gU1NMQ29udGV4dAorICAgICAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJOb3QgU1NMQ29udGV4dCBjcmVhdGVkIiwgc3NsQ29udGV4dCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkludmFsaWQgcHJvdG9jb2wiLCB2YWxpZFZhbHVlc1tpXSwgc3NsQ29udGV4dC5nZXRQcm90b2NvbCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW52YWxpZCBwcm92aWRlciIsIGRlZmF1bHRQcm92aWRlciwgc3NsQ29udGV4dC5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogQHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMQ29udGV4dCNnZXRQcm90b2NvbCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQcm90b2NvbCgpCisgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFERUZTdXBwb3J0ZWQpIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgIFNTTENvbnRleHRTcGkgc3BpID0gbmV3IE15U1NMQ29udGV4dFNwaSgpOworICAgICAgICBTU0xDb250ZXh0IHNzbENvbnRleHQgPSBuZXcgTXlTc2xDb250ZXh0KHNwaSwgZGVmYXVsdFByb3ZpZGVyLAorICAgICAgICAgICAgICAgIGRlZmF1bHRQcm90b2NvbCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3RvY29sIiwKKyAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdG9jb2wsIHNzbENvbnRleHQuZ2V0UHJvdG9jb2woKSk7CisgICAgICAgIHNzbENvbnRleHQgPSBuZXcgTXlTc2xDb250ZXh0KHNwaSwgZGVmYXVsdFByb3ZpZGVyLAorICAgICAgICAgICAgICAgIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJJbmNvcnJlY3QgcHJvdG9jb2wiLCBzc2xDb250ZXh0LmdldFByb3RvY29sKCkpOworICAgICAgICBzc2xDb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZShkZWZhdWx0UHJvdG9jb2wpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm90b2NvbCIsCisgICAgICAgICAgICAgICAgZGVmYXVsdFByb3RvY29sLCBzc2xDb250ZXh0LmdldFByb3RvY29sKCkpOworICAgICAgICBzc2xDb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZShkZWZhdWx0UHJvdG9jb2wsIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3RvY29sIiwKKyAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdG9jb2wsIHNzbENvbnRleHQuZ2V0UHJvdG9jb2woKSk7CisgICAgICAgIHNzbENvbnRleHQgPSBTU0xDb250ZXh0LmdldEluc3RhbmNlKGRlZmF1bHRQcm90b2NvbCwgZGVmYXVsdFByb3ZpZGVyTmFtZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3RvY29sIiwKKyAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdG9jb2wsIHNzbENvbnRleHQuZ2V0UHJvdG9jb2woKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xDb250ZXh0I2dldFByb3ZpZGVyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFByb3ZpZGVyKCkKKyAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgU1NMQ29udGV4dFNwaSBzcGkgPSBuZXcgTXlTU0xDb250ZXh0U3BpKCk7CisgICAgICAgIFNTTENvbnRleHQgc3NsQ29udGV4dCA9IG5ldyBNeVNzbENvbnRleHQoc3BpLCBkZWZhdWx0UHJvdmlkZXIsCisgICAgICAgICAgICAgICAgZGVmYXVsdFByb3RvY29sKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLAorICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlciwgc3NsQ29udGV4dC5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgc3NsQ29udGV4dCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UoZGVmYXVsdFByb3RvY29sLCBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsCisgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyLCBzc2xDb250ZXh0LmdldFByb3ZpZGVyKCkpOworICAgICAgICBzc2xDb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZShkZWZhdWx0UHJvdG9jb2wsIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsCisgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyLCBzc2xDb250ZXh0LmdldFByb3ZpZGVyKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMQ29udGV4dCNnZXRTZXJ2bGV0U2Vzc2lvbkNvbnRleHQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uLCBLZXlTdG9yZUV4Y2VwdGlvbiwKKyAgICAgICAgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICBTU0xDb250ZXh0W10gc3NsQyA9IGNyZWF0ZVNTTENvbigpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJTU0xDb250ZXh0IG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIHNzbEMpOworICAgICAgICBTdHJpbmcgdEFsZyA9IFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0RGVmYXVsdEFsZ29yaXRobSgpOworICAgICAgICBTdHJpbmcga0FsZyA9IEtleU1hbmFnZXJGYWN0b3J5LmdldERlZmF1bHRBbGdvcml0aG0oKTsKKyAgICAgICAgaWYgKHRBbGcgPT0gbnVsbCkKKyAgICAgICAgICAgIGZhaWwoIlRydXN0TWFuYWdlckZhY3RvcnkgZGVmYXVsdCBhbGdvcml0aG0gaXMgbm90IGRlZmluZWQiKTsKKyAgICAgICAgaWYgKGtBbGcgPT0gbnVsbCkKKyAgICAgICAgICAgIGZhaWwoIktleU1hbmFnZXJGYWN0b3J5IGRlZmF1bHQgYWxnb3JpdGhtIGlzIG5vdCBkZWZpbmVkIik7CisgICAgICAgIEtleU1hbmFnZXJGYWN0b3J5IGttZiA9IEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGtBbGcpOworICAgICAgICBrbWYuaW5pdChudWxsLCBuZXcgY2hhclsxMV0pOworICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5IHRtZiA9IFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UodEFsZyk7CisgICAgICAgIEtleVN0b3JlIGtzID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSk7CisgICAgICAgIHRtZi5pbml0KGtzKTsKKyAgICAgICAgVHJ1c3RNYW5hZ2VyW10gdG1zID0gdG1mLmdldFRydXN0TWFuYWdlcnMoKTsKKyAgICAgICAgZm9yIChTU0xDb250ZXh0IHNzbENpIDogc3NsQykgeworICAgICAgICAgICAgc3NsQ2kuaW5pdChrbWYuZ2V0S2V5TWFuYWdlcnMoKSwgdG1zLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiU2VydmVyIGNvbnRleHQgaXMgaW5jb3JyZWN0bHkgaW5zdGFudGlhdGVkIiwgc3NsQ2kKKyAgICAgICAgICAgICAgICAgICAgLmdldFNlcnZlclNlc3Npb25Db250ZXh0KCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0U2VydmVyU29ja2V0RmFjdG9yeSgpPC9jb2RlPgorICAgICAqIDxjb2RlPmdldFNvY2tldEZhY3RvcnkoKTwvY29kZT4KKyAgICAgKiA8Y29kZT5pbml0KEtleU1hbmFnZXJbXSBrbSwgVHJ1c3RNYW5hZ2VyW10gdG0sIFNlY3VyZVJhbmRvbSByYW5kb20pPC9jb2RlPgorICAgICAqIG1ldGhvZHMgQXNzZXJ0aW9uOiByZXR1cm5zIGNvcnJlc3BvbmRlbnQgb2JqZWN0CisgICAgICoKKyAgICAgKi8KKyAgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTZXJ2ZXJTb2NrZXRGYWN0b3J5KCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEtleU1hbmFnZW1lbnRFeGNlcHRpb24sIEtleVN0b3JlRXhjZXB0aW9uLAorICAgICAgICAgICAgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghREVGU3VwcG9ydGVkKSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFNTTENvbnRleHRbXSBzc2xDID0gY3JlYXRlU1NMQ29uKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIlNTTENvbnRleHQgb2JqZWN0cyB3ZXJlIG5vdCBjcmVhdGVkIiwgc3NsQyk7CisgICAgICAgIFN0cmluZyB0QWxnID0gVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXREZWZhdWx0QWxnb3JpdGhtKCk7CisgICAgICAgIFN0cmluZyBrQWxnID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0RGVmYXVsdEFsZ29yaXRobSgpOworICAgICAgICBpZiAodEFsZyA9PSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKCJUcnVzdE1hbmFnZXJGYWN0b3J5IGRlZmF1bHQgYWxnb3JpdGhtIGlzIG5vdCBkZWZpbmVkIik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKGtBbGcgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbCgiS2V5TWFuYWdlckZhY3RvcnkgZGVmYXVsdCBhbGdvcml0aG0gaXMgbm90IGRlZmluZWQiKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeSBrbWYgPSBLZXlNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShrQWxnKTsKKyAgICAgICAgS2V5U3RvcmUga3MgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtzLmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gZm9yIG1ldGhvZCBsb2FkKG51bGwsIG51bGwpIik7CisgICAgICAgIH0KKyAgICAgICAga21mLmluaXQoa3MsIG5ldyBjaGFyWzEwXSk7CisgICAgICAgIEtleU1hbmFnZXJbXSBrbXMgPSBrbWYuZ2V0S2V5TWFuYWdlcnMoKTsKKyAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeSB0bWYgPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKHRBbGcpOworICAgICAgICB0bWYuaW5pdChrcyk7CisgICAgICAgIFRydXN0TWFuYWdlcltdIHRtcyA9IHRtZi5nZXRUcnVzdE1hbmFnZXJzKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3NsQy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc3NsQ1tpXS5pbml0KGttcywgdG1zLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTm8gU1NMU2VydmVyU29ja2V0RmFjdG9yeSBhdmFpbGFibGUiLAorICAgICAgICAgICAgICAgICAgICBzc2xDW2ldLmdldFNlcnZlclNvY2tldEZhY3RvcnkoKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJObyBTU0xTb2NrZXRGYWN0b3J5IGF2YWlsYWJsZSIsCisgICAgICAgICAgICAgICAgICAgIHNzbENbaV0uZ2V0U29ja2V0RmFjdG9yeSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgICAvKioKKyAgICAgICogamF2YXgubmV0LnNzbC5TU0xDb250ZXh0I2dldFNvY2tldEZhY3RvcnkoKQorICAgICAgKi8KKyAgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTb2NrZXRGYWN0b3J5KCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgIEtleU1hbmFnZW1lbnRFeGNlcHRpb24sIEtleVN0b3JlRXhjZXB0aW9uLAorICAgICAgICAgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiB7CisgICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgIFNTTENvbnRleHRbXSBzc2xDID0gY3JlYXRlU1NMQ29uKCk7CisgICAgICAgICBhc3NlcnROb3ROdWxsKCJTU0xDb250ZXh0IG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIHNzbEMpOworICAgICAgICAgU3RyaW5nIHRBbGcgPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldERlZmF1bHRBbGdvcml0aG0oKTsKKyAgICAgICAgIFN0cmluZyBrQWxnID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0RGVmYXVsdEFsZ29yaXRobSgpOworICAgICAgICAgaWYgKHRBbGcgPT0gbnVsbCkKKyAgICAgICAgICAgICBmYWlsKCJUcnVzdE1hbmFnZXJGYWN0b3J5IGRlZmF1bHQgYWxnb3JpdGhtIGlzIG5vdCBkZWZpbmVkIik7CisgICAgICAgICBpZiAoa0FsZyA9PSBudWxsKQorICAgICAgICAgICAgIGZhaWwoIktleU1hbmFnZXJGYWN0b3J5IGRlZmF1bHQgYWxnb3JpdGhtIGlzIG5vdCBkZWZpbmVkIik7CisgICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeSBrbWYgPSBLZXlNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShrQWxnKTsKKyAgICAgICAgIGttZi5pbml0KG51bGwsIG5ldyBjaGFyWzExXSk7CisgICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5IHRtZiA9IFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UodEFsZyk7CisgICAgICAgICBLZXlTdG9yZSBrcyA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICAgdG1mLmluaXQoa3MpOworICAgICAgICAgVHJ1c3RNYW5hZ2VyW10gdG1zID0gdG1mLmdldFRydXN0TWFuYWdlcnMoKTsKKyAgICAgICAgIGZvciAoU1NMQ29udGV4dCBzc2xDaSA6IHNzbEMpIHsKKyAgICAgICAgICAgICBzc2xDaS5pbml0KGttZi5nZXRLZXlNYW5hZ2VycygpLCB0bXMsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiU29ja2V0IGZhY3RvcnkgaXMgaW5jb3JyZWN0bHkgaW5zdGFudGlhdGVkIiwKKyAgICAgICAgICAgICAgICAgICAgIHNzbENpLmdldFNvY2tldEZhY3RvcnkoKSk7CisgICAgICAgICB9CisgICAgIH0KKworICAgICAvKioKKyAgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uCisgICAgICogQHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24KKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTENvbnRleHQjCisgICAgICAqICAgICBpbml0KGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlcltdLCBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlcltdLAorICAgICAgKiAgICAgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb20pCisgICAgICAqLworICAgICBwdWJsaWMgdm9pZCB0ZXN0X2luaXQkTGphdmF4X25ldF9zc2xfS2V5TWFuYWdlciRMamF2YXhfbmV0X3NzbF9UcnVzdE1hbmFnZXJMamF2YV9zZWN1cml0eV9TZWN1cmVSYW5kb20oKQorICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICBpZiAoIURFRlN1cHBvcnRlZCkgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgIFNTTENvbnRleHRTcGkgc3BpID0gbmV3IE15U1NMQ29udGV4dFNwaSgpOworICAgICAgICAgU1NMQ29udGV4dCBzc2xDb250ZXh0ID0gbmV3IE15U3NsQ29udGV4dChzcGksIGRlZmF1bHRQcm92aWRlciwKKyAgICAgICAgICAgICAgICAgZGVmYXVsdFByb3RvY29sKTsKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgc3NsQ29udGV4dC5jcmVhdGVTU0xFbmdpbmUoKTsKKyAgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBSdW50aW1lRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJ0ZSkgeworICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICB9CisKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgc3NsQ29udGV4dC5pbml0KG51bGwsIG51bGwsIG51bGwpOworICAgICAgICAgICAgIGZhaWwoIktleU1hbmFnZW1lbnRFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICAgfSBjYXRjaCAoS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiBrbWUpIHsKKyAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICB9CisKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgU3RyaW5nIHRBbGcgPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldERlZmF1bHRBbGdvcml0aG0oKTsKKyAgICAgICAgICAgICBTdHJpbmcga0FsZyA9IEtleU1hbmFnZXJGYWN0b3J5LmdldERlZmF1bHRBbGdvcml0aG0oKTsKKyAgICAgICAgICAgICBpZiAodEFsZyA9PSBudWxsKQorICAgICAgICAgICAgICAgICBmYWlsKCJUcnVzdE1hbmFnZXJGYWN0b3J5IGRlZmF1bHQgYWxnb3JpdGhtIGlzIG5vdCBkZWZpbmVkIik7CisgICAgICAgICAgICAgaWYgKGtBbGcgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgZmFpbCgiS2V5TWFuYWdlckZhY3RvcnkgZGVmYXVsdCBhbGdvcml0aG0gaXMgbm90IGRlZmluZWQiKTsKKyAgICAgICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeSBrbWYgPSBLZXlNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShrQWxnKTsKKyAgICAgICAgICAgICBrbWYuaW5pdChudWxsLCBuZXcgY2hhclsxMV0pOworICAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkgdG1mID0gVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZSh0QWxnKTsKKyAgICAgICAgICAgICBLZXlTdG9yZSBrcyA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICAgICAgIHRtZi5pbml0KGtzKTsKKyAgICAgICAgICAgICBUcnVzdE1hbmFnZXJbXSB0bXMgPSB0bWYuZ2V0VHJ1c3RNYW5hZ2VycygpOworICAgICAgICAgICAgIHNzbENvbnRleHQuaW5pdChrbWYuZ2V0S2V5TWFuYWdlcnMoKSwgdG1zLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVFID0gIiArIGUpOworICAgICAgICAgfQorICAgICB9Cit9CisKKy8qKgorICogQWRkaWZpb25hbCBjbGFzcyB0byB2ZXJpZnkgU1NMQ29udGV4dCBjb25zdHJ1Y3RvcgorICovCisKK2NsYXNzIE15U3NsQ29udGV4dCBleHRlbmRzIFNTTENvbnRleHQgeworICAgIHB1YmxpYyBNeVNzbENvbnRleHQoU1NMQ29udGV4dFNwaSBzcGksIFByb3ZpZGVyIHByb3YsIFN0cmluZyBhbGcpIHsKKyAgICAgICAgc3VwZXIoc3BpLCBwcm92LCBhbGcpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xDb250ZXh0MlRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xDb250ZXh0MlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wODgxNjE1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1NTTENvbnRleHQyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjkzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlNYW5hZ2VtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTENvbnRleHQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFbmdpbmU7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlNwaUVuZ1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnRlc3RzLnN1cHBvcnQuTXlTU0xDb250ZXh0U3BpOworCisvKioKKyAqIFRlc3RzIGZvciBTU0xDb250ZXh0IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcworICoKKyAqLworcHVibGljIGNsYXNzIFNTTENvbnRleHQyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBzcnZTU0xDb250ZXh0ID0gIlNTTENvbnRleHQiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGRlZmF1bHRQcm90b2NvbCA9ICJTK1MrTCI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTU0xDb250ZXh0UHJvdmlkZXJDbGFzcyA9IE15U1NMQ29udGV4dFNwaS5jbGFzcy5nZXROYW1lKCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBpbnZhbGlkVmFsdWVzID0gU3BpRW5nVXRpbHMuaW52YWxpZFZhbHVlczsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIHZhbGlkVmFsdWVzOworICAgIHN0YXRpYyB7CisgICAgICAgIHZhbGlkVmFsdWVzID0gbmV3IFN0cmluZ1s0XTsKKyAgICAgICAgdmFsaWRWYWx1ZXNbMF0gPSBkZWZhdWx0UHJvdG9jb2w7CisgICAgICAgIHZhbGlkVmFsdWVzWzFdID0gZGVmYXVsdFByb3RvY29sLnRvTG93ZXJDYXNlKCk7CisgICAgICAgIHZhbGlkVmFsdWVzWzJdID0gInMrUytMIjsKKyAgICAgICAgdmFsaWRWYWx1ZXNbM10gPSAiUytzK0wiOworICAgIH0KKworICAgIFByb3ZpZGVyIG1Qcm92OworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgbVByb3YgPSAobmV3IFNwaUVuZ1V0aWxzKCkpLm5ldyBNeVByb3ZpZGVyKCJNeVNTTENvbnRleHRQcm92aWRlciIsICJQcm92aWRlciBmb3IgdGVzdGluZyIsCisgICAgICAgICAgICAgICAgc3J2U1NMQ29udGV4dC5jb25jYXQoIi4iKS5jb25jYXQoZGVmYXVsdFByb3RvY29sKSwKKyAgICAgICAgICAgICAgICBTU0xDb250ZXh0UHJvdmlkZXJDbGFzcyk7CisgICAgICAgIFNlY3VyaXR5Lmluc2VydFByb3ZpZGVyQXQobVByb3YsIDEpOworICAgIH0KKworICAgIC8qCisgICAgICogQHNlZSBUZXN0Q2FzZSN0ZWFyRG93bigpCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICAgICAgU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIobVByb3YuZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tTU0xDb250ZXh0KFNTTENvbnRleHQgc3NsQykKKyAgICAgICAgICAgIHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NsQy5nZXRTb2NrZXRGYWN0b3J5KCk7CisgICAgICAgICAgICBmYWlsKCJSdW50aW1lRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbWVzc2FnZSIsICJOb3QgaW5pdGlhbGlhemVkIiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2xDLmdldFNlcnZlclNvY2tldEZhY3RvcnkoKTsKKyAgICAgICAgICAgIGZhaWwoIlJ1bnRpbWVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBtZXNzYWdlIiwgIk5vdCBpbml0aWFsaWF6ZWQiLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzbEMuZ2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKTsKKyAgICAgICAgICAgIGZhaWwoIlJ1bnRpbWVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBtZXNzYWdlIiwgIk5vdCBpbml0aWFsaWF6ZWQiLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzbEMuZ2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKTsKKyAgICAgICAgICAgIGZhaWwoIlJ1bnRpbWVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBtZXNzYWdlIiwgIk5vdCBpbml0aWFsaWF6ZWQiLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzbEMuY3JlYXRlU1NMRW5naW5lKCk7CisgICAgICAgICAgICBmYWlsKCJSdW50aW1lRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbWVzc2FnZSIsICJOb3QgaW5pdGlhbGlhemVkIiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2xDLmNyZWF0ZVNTTEVuZ2luZSgiaG9zdCIsMSk7CisgICAgICAgICAgICBmYWlsKCJSdW50aW1lRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbWVzc2FnZSIsICJOb3QgaW5pdGlhbGlhemVkIiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIFRydXN0TWFuYWdlciBbXSB0bSA9IG5ldyBUTWFuYWdlclsxMF07CisgICAgICAgIEtleU1hbmFnZXIgW10ga20gPSBuZXcgS01hbmFnZXJbNV07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2xDLmluaXQoa20sIHRtLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIktleU1hbmFnZW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgc3NsQy5pbml0KGttLCB0bSwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKworICAgICAgICBTU0xFbmdpbmUgc3NsRSA9IHNzbEMuY3JlYXRlU1NMRW5naW5lKCk7CisgICAgICAgIGFzc2VydFRydWUoIk5vdCBudWxsIHJlc3VsdCIsc3NsRSBpbnN0YW5jZW9mIFNTTEVuZ2luZSk7CisgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCBob3N0Iiwgc3NsRS5nZXRQZWVySG9zdCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcG9ydCIsIDAsIHNzbEUuZ2V0UGVlclBvcnQoKSk7CisgICAgICAgIFN0cmluZyBob3N0ID0gIlpaWiI7CisgICAgICAgIGludCBwb3J0ID0gODA4MDsKKyAgICAgICAgc3NsRSA9IHNzbEMuY3JlYXRlU1NMRW5naW5lKGhvc3QsIHBvcnQpOworICAgICAgICBhc3NlcnRUcnVlKCJOb3QgbnVsbCByZXN1bHQiLHNzbEUgaW5zdGFuY2VvZiBTU0xFbmdpbmUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBob3N0Iiwgc3NsRS5nZXRQZWVySG9zdCgpLCBob3N0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcG9ydCIsIHNzbEUuZ2V0UGVlclBvcnQoKSwgcG9ydCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJOb3QgbnVsbCByZXN1bHQiLCBzc2xDLmdldFNlcnZlclNlc3Npb25Db250ZXh0KCkpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydE51bGwoIk5vdCBudWxsIHJlc3VsdCIsIHNzbEMuZ2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKSk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBwcm90b2NvbCk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbnM6CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gcHJvdG9jb2wgaXMgbnVsbDsKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gcHJvdG9jb2wgaXMgbm90IGNvcnJlY3Q7CisgICAgICogcmV0dXJucyBTU0xDb250ZXh0IG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNTTENvbnRleHQuZ2V0SW5zdGFuY2UobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gb3IgTnVsbFBvaW50ZXJFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICsgIihwcm90b2NvbCBpcyBudWxsKSIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFNTTENvbnRleHQuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIChwcm90b2NvbDogIgorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChpbnZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFNTTENvbnRleHQgc3NsQzsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc3NsQyA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTm90IGluc3RhbmNlb2YgU1NMQ29udGV4dCBvYmplY3QiLCBzc2xDIGluc3RhbmNlb2YgU1NMQ29udGV4dCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm90b2NvbCIsIHNzbEMuZ2V0UHJvdG9jb2woKSwgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBzc2xDLmdldFByb3ZpZGVyKCksIG1Qcm92KTsKKyAgICAgICAgICAgIGNoZWNrU1NMQ29udGV4dChzc2xDKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBwcm90b2NvbCwgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb25zOgorICAgICAqIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIHByb3RvY29sIGlzIG51bGw7CisgICAgICogdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIHByb3RvY29sIGlzIG5vdCBjb3JyZWN0OworICAgICAqIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBudWxsIG9yIGVtcHR5OworICAgICAqIHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB3aGVuIHByb3ZpZGVyIGlzIGF2YWlsYWJsZTsKKyAgICAgKiByZXR1cm5zIFNTTENvbnRleHQgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcoKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIEtleU1hbmFnZW1lbnRFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMQ29udGV4dC5nZXRJbnN0YW5jZShudWxsLCBtUHJvdi5nZXROYW1lKCkpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG9yIE51bGxQb2ludGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gIgorICAgICAgICAgICAgICAgICArICIocHJvdG9jb2wgaXMgbnVsbCkiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTU0xDb250ZXh0LmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0sIG1Qcm92LmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIChwcm90b2NvbDogIgorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChpbnZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFN0cmluZyBwcm92ID0gbnVsbDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTU0xDb250ZXh0LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBwcm92KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBudWxsIChwcm90b2NvbDogIgorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChpbnZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTU0xDb250ZXh0LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCAiIik7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gcHJvdmlkZXIgaXMgZW1wdHkgKHByb3RvY29sOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDE7IGogPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU1NMQ29udGV4dC5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgaW52YWxpZFZhbHVlc1tqXSk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIChwcm90b2NvbDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIgcHJvdmlkZXI6ICIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChpbnZhbGlkVmFsdWVzW2pdKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBTU0xDb250ZXh0IHNzbEM7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHNzbEMgPSBTU0xDb250ZXh0LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBtUHJvdi5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTm90IGluc3RhbmNlb2YgU1NMQ29udGV4dCBvYmplY3QiLCBzc2xDIGluc3RhbmNlb2YgU1NMQ29udGV4dCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm90b2NvbCIsIHNzbEMuZ2V0UHJvdG9jb2woKSwgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBzc2xDLmdldFByb3ZpZGVyKCkuZ2V0TmFtZSgpLCBtUHJvdi5nZXROYW1lKCkpOworICAgICAgICAgICAgY2hlY2tTU0xDb250ZXh0KHNzbEMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIHByb3RvY29sLCBQcm92aWRlciBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kCisgICAgICogQXNzZXJ0aW9uczoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBwcm90b2NvbCBpcyBudWxsOworICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiBwcm90b2NvbCBpcyBub3QgY29ycmVjdDsKKyAgICAgKiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbDsKKyAgICAgKiByZXR1cm5zIFNTTENvbnRleHQgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfc2VjdXJpdHlfUHJvdmlkZXIoKQorICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIEtleU1hbmFnZW1lbnRFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMQ29udGV4dC5nZXRJbnN0YW5jZShudWxsLCBtUHJvdik7CisgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gb3IgTnVsbFBvaW50ZXJFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAiCisgICAgICAgICAgICAgICAgICsgIihwcm90b2NvbCBpcyBudWxsKSIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFNTTENvbnRleHQuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwgbVByb3YpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAocHJvdG9jb2w6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBwcm92ID0gbnVsbDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTU0xDb250ZXh0LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBwcm92KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBudWxsIChwcm90b2NvbDogIgorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChpbnZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFNTTENvbnRleHQgc3NsQzsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc3NsQyA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIG1Qcm92KTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIk5vdCBpbnN0YW5jZW9mIFNTTENvbnRleHQgb2JqZWN0Iiwgc3NsQyBpbnN0YW5jZW9mIFNTTENvbnRleHQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdG9jb2wiLCBzc2xDLmdldFByb3RvY29sKCksIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwgc3NsQy5nZXRQcm92aWRlcigpLCBtUHJvdik7CisgICAgICAgICAgICBjaGVja1NTTENvbnRleHQoc3NsQyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBUTWFuYWdlciBpbXBsZW1lbnRzIFRydXN0TWFuYWdlciB7CisKKyAgICB9CisgICAgY2xhc3MgS01hbmFnZXIgaW1wbGVtZW50cyBLZXlNYW5hZ2VyIHsKKworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xDb250ZXh0U3BpVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1NTTENvbnRleHRTcGlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDVhMWMxNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xDb250ZXh0U3BpVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjI5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlckZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xDb250ZXh0U3BpOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0RmFjdG9yeTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb25Db250ZXh0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0RmFjdG9yeTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleU1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXJGYWN0b3J5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5TWFuYWdlbWVudEV4Y2VwdGlvbjsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnRlc3RzLnN1cHBvcnQuU1NMQ29udGV4dFNwaUltcGw7CisKK3B1YmxpYyBjbGFzcyBTU0xDb250ZXh0U3BpVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMQ29udGV4dFNwaSNTU0xDb250ZXh0U3BpKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMQ29udGV4dFNwaUltcGwgc3NsID0gbmV3IFNTTENvbnRleHRTcGlJbXBsKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHNzbCBpbnN0YW5jZW9mIFNTTENvbnRleHRTcGkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTENvbnRleHRTcGkjZW5naW5lQ3JlYXRlU1NMRW5naW5lKCkKKyAgICAgKiBWZXJpZnkgZXhjZXB0aW9uIHdoZW4gU1NMQ29udGV4dFNwaSBvYmplY3Qgd2Fzbid0IGluaXRpYWxpYXplZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VuZ2luZUNyZWF0ZVNTTEVuZ2luZV8wMSgpIHsKKyAgICAgICAgU1NMQ29udGV4dFNwaUltcGwgc3NsID0gbmV3IFNTTENvbnRleHRTcGlJbXBsKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTU0xFbmdpbmUgc2xlbmcgPSBzc2wuZW5naW5lQ3JlYXRlU1NMRW5naW5lKCk7CisgICAgICAgICAgICBmYWlsKCJSdW50aW1lRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgU3RyaW5nIHN0ciA9IHJlLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGlmICghc3RyLmVxdWFscygiTm90IGluaXRpYWxpYXplZCIpKQorICAgICAgICAgICAgICAgIGZhaWwoIkluY29ycmVjdCBleGNlcHRpb24gbWVzc2FnZTogIiArIHN0cik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJbmNvcnJlY3QgZXhjZXB0aW9uICIgKyBlICsgIiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTENvbnRleHRTcGkjZW5naW5lQ3JlYXRlU1NMRW5naW5lKFN0cmluZyBob3N0LCBpbnQgcG9ydCkKKyAgICAgKiBWZXJpZnkgZXhjZXB0aW9uIHdoZW4gU1NMQ29udGV4dFNwaSBvYmplY3Qgd2Fzbid0IGluaXRpYWxpYXplZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VuZ2luZUNyZWF0ZVNTTEVuZ2luZV8wMigpIHsKKyAgICAgICAgaW50W10gaW52YWxpZF9wb3J0ID0ge0ludGVnZXIuTUlOX1ZBTFVFLCAtNjU1MzUsIC0xLCA2NTUzNiwgSW50ZWdlci5NQVhfVkFMVUV9OworICAgICAgICBTU0xDb250ZXh0U3BpSW1wbCBzc2wgPSBuZXcgU1NMQ29udGV4dFNwaUltcGwoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNTTEVuZ2luZSBzbGVuZyA9IHNzbC5lbmdpbmVDcmVhdGVTU0xFbmdpbmUoImxvY2FsaG9zdCIsIDEwODApOworICAgICAgICAgICAgZmFpbCgiUnVudGltZUV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gcmUpIHsKKyAgICAgICAgICAgIFN0cmluZyBzdHIgPSByZS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBpZiAoIXN0ci5lcXVhbHMoIk5vdCBpbml0aWFsaWF6ZWQiKSkKKyAgICAgICAgICAgICAgICBmYWlsKCJJbmNvcnJlY3QgZXhjZXB0aW9uIG1lc3NhZ2U6ICIgKyBzdHIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSW5jb3JyZWN0IGV4Y2VwdGlvbiAiICsgZSArICIgd2FzIHRocm93biIpOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkX3BvcnQubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgU1NMRW5naW5lIHNsZW5nID0gc3NsLmVuZ2luZUNyZWF0ZVNTTEVuZ2luZSgibG9jYWxob3N0IiwgaW52YWxpZF9wb3J0W2ldKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNTTENvbnRleHRTcGkjZW5naW5lR2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKQorICAgICAqIFNTTENvbnRleHRTcGkjZW5naW5lR2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKQorICAgICAqIFNTTENvbnRleHRTcGkjZW5naW5lR2V0U2VydmVyU29ja2V0RmFjdG9yeSgpCisgICAgICogU1NMQ29udGV4dFNwaSNlbmdpbmVHZXRTb2NrZXRGYWN0b3J5KCkKKyAgICAgKiBWZXJpZnkgZXhjZXB0aW9uIHdoZW4gU1NMQ29udGV4dFNwaSBvYmplY3Qgd2Fzbid0IGluaXRpYWxpYXplZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbW1vblRlc3RfMDEoKSB7CisgICAgICAgIFNTTENvbnRleHRTcGlJbXBsIHNzbCA9IG5ldyBTU0xDb250ZXh0U3BpSW1wbCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTU0xTZXNzaW9uQ29udGV4dCBzbHNjID0gc3NsLmVuZ2luZUdldENsaWVudFNlc3Npb25Db250ZXh0KCk7CisgICAgICAgICAgICBmYWlsKCJSdW50aW1lRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgU3RyaW5nIHN0ciA9IHJlLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGlmICghc3RyLmVxdWFscygiTm90IGluaXRpYWxpYXplZCIpKQorICAgICAgICAgICAgICAgIGZhaWwoIkluY29ycmVjdCBleGNlcHRpb24gbWVzc2FnZTogIiArIHN0cik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJbmNvcnJlY3QgZXhjZXB0aW9uICIgKyBlICsgIiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMU2Vzc2lvbkNvbnRleHQgc2xzYyA9IHNzbC5lbmdpbmVHZXRTZXJ2ZXJTZXNzaW9uQ29udGV4dCgpOworICAgICAgICAgICAgZmFpbCgiUnVudGltZUV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gcmUpIHsKKyAgICAgICAgICAgIFN0cmluZyBzdHIgPSByZS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBpZiAoIXN0ci5lcXVhbHMoIk5vdCBpbml0aWFsaWF6ZWQiKSkKKyAgICAgICAgICAgICAgICBmYWlsKCJJbmNvcnJlY3QgZXhjZXB0aW9uIG1lc3NhZ2U6ICIgKyBzdHIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSW5jb3JyZWN0IGV4Y2VwdGlvbiAiICsgZSArICIgd2FzIHRocm93biIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNTTFNlcnZlclNvY2tldEZhY3Rvcnkgc3NzZiA9IHNzbC5lbmdpbmVHZXRTZXJ2ZXJTb2NrZXRGYWN0b3J5KCk7CisgICAgICAgICAgICBmYWlsKCJSdW50aW1lRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgU3RyaW5nIHN0ciA9IHJlLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGlmICghc3RyLmVxdWFscygiTm90IGluaXRpYWxpYXplZCIpKQorICAgICAgICAgICAgICAgIGZhaWwoIkluY29ycmVjdCBleGNlcHRpb24gbWVzc2FnZTogIiArIHN0cik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJJbmNvcnJlY3QgZXhjZXB0aW9uICIgKyBlICsgIiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMU29ja2V0RmFjdG9yeSBzc2YgPSBzc2wuZW5naW5lR2V0U29ja2V0RmFjdG9yeSgpOworICAgICAgICAgICAgZmFpbCgiUnVudGltZUV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gcmUpIHsKKyAgICAgICAgICAgIFN0cmluZyBzdHIgPSByZS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBpZiAoIXN0ci5lcXVhbHMoIk5vdCBpbml0aWFsaWF6ZWQiKSkKKyAgICAgICAgICAgICAgICBmYWlsKCJJbmNvcnJlY3QgZXhjZXB0aW9uIG1lc3NhZ2U6ICIgKyBzdHIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiSW5jb3JyZWN0IGV4Y2VwdGlvbiAiICsgZSArICIgd2FzIHRocm93biIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU1NMQ29udGV4dFNwaSNlbmdpbmVJbml0KEtleU1hbmFnZXJbXSBrbSwgVHJ1c3RNYW5hZ2VyW10gdG0sIFNlY3VyZVJhbmRvbSBzcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VuZ2luZUluaXQoKSB7CisgICAgICAgIFNTTENvbnRleHRTcGlJbXBsIHNzbCA9IG5ldyBTU0xDb250ZXh0U3BpSW1wbCgpOworICAgICAgICBTdHJpbmcgZGVmYXVsdEFsZ29yaXRobSA9IFNlY3VyaXR5LmdldFByb3BlcnR5KCJzc2wuS2V5TWFuYWdlckZhY3RvcnkuYWxnb3JpdGhtIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeSBrbWYgPSBLZXlNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShkZWZhdWx0QWxnb3JpdGhtKTsKKyAgICAgICAgICAgIGNoYXJbXSBwYXNzID0gInBhc3N3b3JkIi50b0NoYXJBcnJheSgpOworICAgICAgICAgICAga21mLmluaXQobnVsbCwgcGFzcyk7CisgICAgICAgICAgICBLZXlNYW5hZ2VyW10ga20gPSBrbWYuZ2V0S2V5TWFuYWdlcnMoKTsKKyAgICAgICAgICAgIGRlZmF1bHRBbGdvcml0aG0gPSBTZWN1cml0eS5nZXRQcm9wZXJ0eSgic3NsLlRydXN0TWFuYWdlckZhY3RvcnkuYWxnb3JpdGhtIik7CisgICAgICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5IHRydXN0TUYgPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGRlZmF1bHRBbGdvcml0aG0pOworICAgICAgICAgICAgS2V5U3RvcmUga3MgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAgICAgIGtzLmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgICAgICB0cnVzdE1GLmluaXQoa3MpOworICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyW10gdG0gPSB0cnVzdE1GLmdldFRydXN0TWFuYWdlcnMoKTsKKyAgICAgICAgICAgIFNlY3VyZVJhbmRvbSBzciA9IFNlY3VyZVJhbmRvbS5nZXRJbnN0YW5jZSgiU0hBMVBSTkciKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3NsLmVuZ2luZUluaXQoa20sIHRtLCBzcik7CisgICAgICAgICAgICB9IGNhdGNoIChLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIGttZSkgeworICAgICAgICAgICAgICAgIGZhaWwoa21lICsgIiB3YXMgdGhyb3cgZm9yIGVuZ2luZUluaXQgbWV0aG9kIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHNzbC5lbmdpbmVJbml0KGttLCB0bSwgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIGttZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKGV4ICsgIiB1bmV4cGVjdGVkIGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU1NMQ29udGV4dFNwaSNlbmdpbmVDcmVhdGVTU0xFbmdpbmUoKQorICAgICAqIFNTTENvbnRleHRTcGkjZW5naW5lQ3JlYXRlU1NMRW5naW5lKFN0cmluZyBob3N0LCBpbnQgcG9ydCkKKyAgICAgKiBTU0xDb250ZXh0U3BpI2VuZ2luZUdldENsaWVudFNlc3Npb25Db250ZXh0KCkKKyAgICAgKiBTU0xDb250ZXh0U3BpI2VuZ2luZUdldFNlcnZlclNlc3Npb25Db250ZXh0KCkKKyAgICAgKiBTU0xDb250ZXh0U3BpI2VuZ2luZUdldFNlcnZlclNvY2tldEZhY3RvcnkoKQorICAgICAqIFNTTENvbnRleHRTcGkjZW5naW5lR2V0U29ja2V0RmFjdG9yeSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jb21tb25UZXN0XzAyKCkgeworICAgICAgICBTU0xDb250ZXh0U3BpSW1wbCBzc2wgPSBuZXcgU1NMQ29udGV4dFNwaUltcGwoKTsKKyAgICAgICAgU3RyaW5nIGRlZmF1bHRBbGdvcml0aG0gPSBTZWN1cml0eS5nZXRQcm9wZXJ0eSgic3NsLktleU1hbmFnZXJGYWN0b3J5LmFsZ29yaXRobSIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5TWFuYWdlckZhY3Rvcnkga21mID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoZGVmYXVsdEFsZ29yaXRobSk7CisgICAgICAgICAgICBjaGFyW10gcGFzcyA9ICJwYXNzd29yZCIudG9DaGFyQXJyYXkoKTsKKyAgICAgICAgICAgIGttZi5pbml0KG51bGwsIHBhc3MpOworICAgICAgICAgICAgS2V5TWFuYWdlcltdIGttID0ga21mLmdldEtleU1hbmFnZXJzKCk7CisgICAgICAgICAgICBkZWZhdWx0QWxnb3JpdGhtID0gU2VjdXJpdHkuZ2V0UHJvcGVydHkoInNzbC5UcnVzdE1hbmFnZXJGYWN0b3J5LmFsZ29yaXRobSIpOworICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeSB0cnVzdE1GID0gVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShkZWZhdWx0QWxnb3JpdGhtKTsKKyAgICAgICAgICAgIEtleVN0b3JlIGtzID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSk7CisgICAgICAgICAgICBrcy5sb2FkKG51bGwsIG51bGwpOworICAgICAgICAgICAgdHJ1c3RNRi5pbml0KGtzKTsKKyAgICAgICAgICAgIFRydXN0TWFuYWdlcltdIHRtID0gdHJ1c3RNRi5nZXRUcnVzdE1hbmFnZXJzKCk7CisgICAgICAgICAgICBTZWN1cmVSYW5kb20gc3IgPSBTZWN1cmVSYW5kb20uZ2V0SW5zdGFuY2UoIlNIQTFQUk5HIik7CisgICAgICAgICAgICBzc2wuZW5naW5lSW5pdChrbSwgdG0sIHNyKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKGV4ICsgIiB1bmV4cGVjdGVkIGV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIlN1YnRlc3RfMDE6IE9iamVjdCBpcyBOVUxMIiwgc3NsLmVuZ2luZUNyZWF0ZVNTTEVuZ2luZSgpKTsKKyAgICAgICAgICAgIFNTTEVuZ2luZSBzbGVuZyA9IHNzbC5lbmdpbmVDcmVhdGVTU0xFbmdpbmUoImxvY2FsaG9zdCIsIDEwODApOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiU3VidGVzdF8wMjogT2JqZWN0IGlzIE5VTEwiLCBzbGVuZyk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoc2xlbmcuZ2V0UGVlclBvcnQoKSwgMTA4MCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoc2xlbmcuZ2V0UGVlckhvc3QoKSwgImxvY2FsaG9zdCIpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiU3VidGVzdF8wMzogT2JqZWN0IG5vdCBOVUxMIiwgc3NsLmVuZ2luZUdldENsaWVudFNlc3Npb25Db250ZXh0KCkpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiU3VidGVzdF8wNDogT2JqZWN0IG5vdCBOVUxMIiwgc3NsLmVuZ2luZUdldFNlcnZlclNlc3Npb25Db250ZXh0KCkpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiU3VidGVzdF8wNTogT2JqZWN0IG5vdCBOVUxMIiwgc3NsLmVuZ2luZUdldFNlcnZlclNvY2tldEZhY3RvcnkoKSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJTdWJ0ZXN0XzA2OiBPYmplY3Qgbm90IE5VTEwiLCBzc2wuZW5naW5lR2V0U29ja2V0RmFjdG9yeSgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1NTTEVuZ2luZVJlc3VsdEhhbmRzaGFrZVN0YXR1c1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xFbmdpbmVSZXN1bHRIYW5kc2hha2VTdGF0dXNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2IxMzY3MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xFbmdpbmVSZXN1bHRIYW5kc2hha2VTdGF0dXNUZXN0LmphdmEKQEAgLTAsMCArMSw4MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZVJlc3VsdDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgU1NMRW5naW5lUmVzdWx0LlN0YXR1cyBjbGFzcworICoKKyAqLworcHVibGljIGNsYXNzIFNTTEVuZ2luZVJlc3VsdEhhbmRzaGFrZVN0YXR1c1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT4gU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cy52YWx1ZXMoKSA8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9TU0xFbmdpbmVSZXN1bHRIYW5kc2hha2VTdGF0dXNfdmFsdWVzKCkgeworICAgICAgICBTdHJpbmdbXSBzdHIgPSB7Ik5PVF9IQU5EU0hBS0lORyIsICJGSU5JU0hFRCIsICJORUVEX1RBU0siLCAiTkVFRF9XUkFQIiwgIk5FRURfVU5XUkFQIn07CisgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXNbXSBlblMgPSBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzLnZhbHVlcygpOworICAgICAgICBpZiAoZW5TLmxlbmd0aCA9PSBzdHIubGVuZ3RoKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVuUy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJlblNbIiArIGkgKyAiXSA9ICIgKyBlblNbaV0pOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IFN0YXR1cyIsIGVuU1tpXS50b1N0cmluZygpLCBzdHJbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmFpbCgiSW5jb3JyZWN0IG51bWJlciBvZiBlbnVtIGNvbnN0YW50IHdhcyByZXR1cm5lZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+IFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMudmFsdWVPZihTdHJpbmcgbmFtZSkgPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMRW5naW5lUmVzdWx0U3RhdHVzX3ZhbHVlT2YoKSB7CisgICAgICAgIFN0cmluZ1tdIHN0ciA9IHsiRklOSVNIRUQiLCAiTkVFRF9UQVNLIiwgIk5FRURfVU5XUkFQIiwgIk5FRURfV1JBUCIsICJOT1RfSEFORFNIQUtJTkcifTsKKyAgICAgICAgU3RyaW5nW10gc3RyX2ludmFsaWQgPSB7IiIsICJGSU5JU0hFRDEiLCAiTkVFRF90YXNrIiwgIk5FRURfVU4iLAorICAgICAgICAgICAgICAgICJORUVEX1dSQVBfV1JBUCIsICJub3RfSEFORFNIQUtJTkciLCAiQmFkIHN0cmluZyBmb3IgdmVyaWZpY2F0aW9uIHZhbHVlT2YgbWV0aG9kIn07CisgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMgZW5TOworCisgICAgICAgIC8vQ29ycmVjdCBwYXJhbWV0ZXIKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZW5TID0gU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cy52YWx1ZU9mKHN0cltpXSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgU3RhdHVzIiwgZW5TLnRvU3RyaW5nKCksIHN0cltpXSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlICsgIiB3YXMgdGhyb3duIGZvciAiICsgc3RyW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgLy9JbmNvcnJlY3QgcGFyYW1ldGVyCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3RyX2ludmFsaWQubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZW5TID0gU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cy52YWx1ZU9mKHN0cl9pbnZhbGlkW2ldKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biBmb3IgIiArIHN0cl9pbnZhbGlkW2ldKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvL051bGwgcGFyYW1ldGVyCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlblMgPSBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzLnZhbHVlT2YobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbi9JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biBmb3IgTlVMTCBwYXJhbWV0ZXIiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xFbmdpbmVSZXN1bHRTdGF0dXNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMRW5naW5lUmVzdWx0U3RhdHVzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA1YzhmMDMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMRW5naW5lUmVzdWx0U3RhdHVzVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFbmdpbmVSZXN1bHQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIFNTTEVuZ2luZVJlc3VsdC5TdGF0dXMgY2xhc3MKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBTU0xFbmdpbmVSZXN1bHRTdGF0dXNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+IFNTTEVuZ2luZVJlc3VsdC5TdGF0dXMudmFsdWVzKCkgPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMRW5naW5lUmVzdWx0U3RhdHVzX3ZhbHVlcygpIHsKKyAgICAgICAgYm9vbGVhbiBmbGFnID0gZmFsc2U7CisgICAgICAgIFN0cmluZ1tdIHN0ciA9IHsiQlVGRkVSX09WRVJGTE9XIiwgIkJVRkZFUl9VTkRFUkZMT1ciLCAiQ0xPU0VEIiwgIk9LIn07CisgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5TdGF0dXNbXSBlblMgPSBTU0xFbmdpbmVSZXN1bHQuU3RhdHVzLnZhbHVlcygpOworICAgICAgICBpZiAoZW5TLmxlbmd0aCA9PSBzdHIubGVuZ3RoKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVuUy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGZsYWcgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHN0ci5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgICAgICBpZiAoZW5TW2ldLnRvU3RyaW5nKCkgPT0gc3RyW2pdKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmbGFnID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IFN0YXR1cyIsIGZsYWcpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmFpbCgiSW5jb3JyZWN0IG51bWJlciBvZiBlbnVtIGNvbnN0YW50IHdhcyByZXR1cm5lZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+IFNTTEVuZ2luZVJlc3VsdC5TdGF0dXMudmFsdWVPZihTdHJpbmcgbmFtZSkgPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfU1NMRW5naW5lUmVzdWx0U3RhdHVzX3ZhbHVlT2YoKSB7CisgICAgICAgIFN0cmluZ1tdIHN0ciA9IHsiQlVGRkVSX09WRVJGTE9XIiwgIkJVRkZFUl9VTkRFUkZMT1ciLCAiQ0xPU0VEIiwgIk9LIn07CisgICAgICAgIFN0cmluZ1tdIHN0cl9pbnZhbGlkID0geyIiLCAiT0sxIiwgIkJVRkZFUl9vdmVyZmxvdyIsICJCVUZGRVJfVU5EIiwKKyAgICAgICAgICAgICAgICAiQ0xPU0VEX0NMT1NFRCIsICJCYWQgc3RyaW5nIGZvciB2ZXJpZmljYXRpb24gdmFsdWVPZiBtZXRob2QifTsKKyAgICAgICAgU1NMRW5naW5lUmVzdWx0LlN0YXR1cyBlblM7CisKKyAgICAgICAgLy9Db3JyZWN0IHBhcmFtZXRlcgorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBlblMgPSBTU0xFbmdpbmVSZXN1bHQuU3RhdHVzLnZhbHVlT2Yoc3RyW2ldKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBTdGF0dXMiLCBlblMudG9TdHJpbmcoKSwgc3RyW2ldKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUgKyAiIHdhcyB0aHJvd24gZm9yICIgKyBzdHJbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAvL0luY29ycmVjdCBwYXJhbWV0ZXIKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdHJfaW52YWxpZC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBlblMgPSBTU0xFbmdpbmVSZXN1bHQuU3RhdHVzLnZhbHVlT2Yoc3RyX2ludmFsaWRbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIGZvciAiICsgc3RyX2ludmFsaWRbaV0pOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vTnVsbCBwYXJhbWV0ZXIKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVuUyA9IFNTTEVuZ2luZVJlc3VsdC5TdGF0dXMudmFsdWVPZihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uL0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIGZvciBOVUxMIHBhcmFtZXRlciIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1NTTEVuZ2luZVJlc3VsdFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xFbmdpbmVSZXN1bHRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2EyYWM3OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xFbmdpbmVSZXN1bHRUZXN0LmphdmEKQEAgLTAsMCArMSwyMTcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZVJlc3VsdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKworLyoqCisgKiBUZXN0cyBmb3IgU1NMRW5naW5lUmVzdWx0IGNsYXNzCisgKgorICovCitwdWJsaWMgY2xhc3MgU1NMRW5naW5lUmVzdWx0VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPlNTTEVuZ2luZVJlc3VsdChTU0xFbmdpbmVSZXN1bHQuU3RhdHVzIHN0YXR1cywKKyAgICAgKiAgICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cyBoYW5kc2hha2VTdGF0dXMsCisgICAgICogICAgICAgICAgICAgIGludCBieXRlc0NvbnN1bWVkLAorICAgICAqICAgICAgICAgICAgICBpbnQgYnl0ZXNQcm9kdWNlZCkgPC9jb2RlPiBjb25zdHJ1Y3RvciBhbmQKKyAgICAgKiA8Y29kZT5nZXRIYW5kc2hha2VTdGF0dXMoKTwvY29kZT4KKyAgICAgKiA8Y29kZT5nZXRTdGF0dXMoKTwvY29kZT4KKyAgICAgKiA8Y29kZT5ieXRlc0NvbnN1bWVkKCk8L2NvZGU+CisgICAgICogPGNvZGU+Ynl0ZXNQcm9kdWNlZCgpPC9jb2RlPgorICAgICAqIDxjb2RlPnRvU3RyaW5nKCk8L2NvZGU+CisgICAgICogbWV0aG9kcworICAgICAqIEFzc2VydGlvbnM6CisgICAgICogY29uc3RydWN0b3IgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aGVuIGJ5dGVzQ29uc3VtZWQKKyAgICAgKiBvciBieXRlc1Byb2R1Y2VkIGlzIG5lZ2F0aXZlIG9yIHdoZW4gc3RhdHVzIG9yIGhhbmRzaGFrZVN0YXR1cworICAgICAqIGlzIG51bGwKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YXhfbmV0X3NzbF9TU0xFbmdpbmVSZXN1bHRfU3RhdHVzTGphdmF4X25ldF9zc2xfU1NMRW5naW5lUmVzdWx0X0hhbmRzaGFrZVN0YXR1c0lJKCkgeworCisgICAgICAgIGludFtdIG5lZyA9IHsgLTEsIC0xMCwgLTEwMDAsIEludGVnZXIuTUlOX1ZBTFVFLAorICAgICAgICAgICAgICAgIChJbnRlZ2VyLk1JTl9WQUxVRSArIDEpIH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgU1NMRW5naW5lUmVzdWx0KG51bGwsIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMuRklOSVNIRUQsCisgICAgICAgICAgICAgICAgICAgIDEsIDEpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBTU0xFbmdpbmVSZXN1bHQoU1NMRW5naW5lUmVzdWx0LlN0YXR1cy5CVUZGRVJfT1ZFUkZMT1csIG51bGwsCisgICAgICAgICAgICAgICAgICAgIDEsIDEpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuZWcubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbmV3IFNTTEVuZ2luZVJlc3VsdChTU0xFbmdpbmVSZXN1bHQuU3RhdHVzLkJVRkZFUl9PVkVSRkxPVywKKyAgICAgICAgICAgICAgICAgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMuRklOSVNIRUQsIG5lZ1tpXSwgMSk7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmVnLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG5ldyBTU0xFbmdpbmVSZXN1bHQoU1NMRW5naW5lUmVzdWx0LlN0YXR1cy5CVUZGRVJfT1ZFUkZMT1csCisgICAgICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzLkZJTklTSEVELCAxLCBuZWdbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQgcmVzID0gbmV3IFNTTEVuZ2luZVJlc3VsdChTU0xFbmdpbmVSZXN1bHQuU3RhdHVzLkJVRkZFUl9PVkVSRkxPVywKKyAgICAgICAgICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cy5GSU5JU0hFRCwgMSwgMik7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJOdWxsIG9iamVjdCIsIHJlcyk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgcmVzLmJ5dGVzQ29uc3VtZWQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMiwgcmVzLmJ5dGVzUHJvZHVjZWQoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Ynl0ZXNDb25zdW1lZCgpPC9jb2RlPiBtZXRob2QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2J5dGVzQ29uc3VtZWQoKSB7CisgICAgICAgIGludFtdIHBvcyA9IHsgMCwgMSwgMTAwMCwgSW50ZWdlci5NQVhfVkFMVUUsIChJbnRlZ2VyLk1BWF9WQUxVRSAtIDEpIH07CisgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5TdGF0dXMgW10gZW5TID0KKyAgICAgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5TdGF0dXMudmFsdWVzKCk7CisgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMgW10gZW5IUyA9CisgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzLnZhbHVlcygpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVuUy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBlbkhTLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgbiA9IDA7IG4gPCBwb3MubGVuZ3RoOyBuKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgbCA9IDA7IGwgPCBwb3MubGVuZ3RoOyBsKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFNTTEVuZ2luZVJlc3VsdCByZXMgPSBuZXcgU1NMRW5naW5lUmVzdWx0KGVuU1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5IU1tqXSwgcG9zW25dLCBwb3NbbF0pOworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYnl0ZXNDb25zdW1lZCIsIHBvc1tuXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzLmJ5dGVzQ29uc3VtZWQoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5ieXRlc1Byb2R1Y2VkKCk8L2NvZGU+IG1ldGhvZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYnl0ZXNQcm9kdWNlZCgpIHsKKyAgICAgICAgaW50W10gcG9zID0geyAwLCAxLCAxMDAwLCBJbnRlZ2VyLk1BWF9WQUxVRSwgKEludGVnZXIuTUFYX1ZBTFVFIC0gMSkgfTsKKyAgICAgICAgU1NMRW5naW5lUmVzdWx0LlN0YXR1cyBbXSBlblMgPQorICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LlN0YXR1cy52YWx1ZXMoKTsKKyAgICAgICAgU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cyBbXSBlbkhTID0KKyAgICAgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMudmFsdWVzKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZW5TLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGVuSFMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBuID0gMDsgbiA8IHBvcy5sZW5ndGg7IG4rKykgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBsID0gMDsgbCA8IHBvcy5sZW5ndGg7ICsrbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0IHJlcyA9IG5ldyBTU0xFbmdpbmVSZXN1bHQoZW5TW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbkhTW2pdLCBwb3Nbbl0sIHBvc1tsXSk7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBieXRlc1Byb2R1Y2VkIiwgcG9zW2xdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXMuYnl0ZXNQcm9kdWNlZCgpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEhhbmRzaGFrZVN0YXR1cygpPC9jb2RlPiBtZXRob2QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEhhbmRzaGFrZVN0YXR1cygpIHsKKyAgICAgICAgaW50W10gcG9zID0geyAwLCAxLCAxMDAwLCBJbnRlZ2VyLk1BWF9WQUxVRSwgKEludGVnZXIuTUFYX1ZBTFVFIC0gMSkgfTsKKyAgICAgICAgU1NMRW5naW5lUmVzdWx0LlN0YXR1cyBbXSBlblMgPQorICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LlN0YXR1cy52YWx1ZXMoKTsKKyAgICAgICAgU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cyBbXSBlbkhTID0KKyAgICAgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMudmFsdWVzKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZW5TLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGVuSFMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBuID0gMDsgbiA8IHBvcy5sZW5ndGg7IG4rKykgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBsID0gMDsgbCA8IHBvcy5sZW5ndGg7ICsrbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0IHJlcyA9IG5ldyBTU0xFbmdpbmVSZXN1bHQoZW5TW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbkhTW2pdLCBwb3Nbbl0sIHBvc1tsXSk7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBIYW5kc2hha2VTdGF0dXMiLCBlbkhTW2pdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXMuZ2V0SGFuZHNoYWtlU3RhdHVzKCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0U3RhdHVzKCk8L2NvZGU+IG1ldGhvZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0U3RhdHVzKCkgeworICAgICAgICBpbnRbXSBwb3MgPSB7IDAsIDEsIDEwMDAsIEludGVnZXIuTUFYX1ZBTFVFLCAoSW50ZWdlci5NQVhfVkFMVUUgLSAxKSB9OworICAgICAgICBTU0xFbmdpbmVSZXN1bHQuU3RhdHVzIFtdIGVuUyA9CisgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuU3RhdHVzLnZhbHVlcygpOworICAgICAgICBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzIFtdIGVuSFMgPQorICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cy52YWx1ZXMoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlblMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgZW5IUy5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgIGZvciAoaW50IG4gPSAwOyBuIDwgcG9zLmxlbmd0aDsgbisrKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGwgPSAwOyBsIDwgcG9zLmxlbmd0aDsgKytsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQgcmVzID0gbmV3IFNTTEVuZ2luZVJlc3VsdChlblNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuSFNbal0sIHBvc1tuXSwgcG9zW2xdKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IFN0YXR1cyIsIGVuU1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzLmdldFN0YXR1cygpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnRvU3RyaW5nKCk8L2NvZGU+IG1ldGhvZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9TdHJpbmcoKSB7CisgICAgICAgIGludFtdIHBvcyA9IHsgMCwgMSwgMTAwMCwgSW50ZWdlci5NQVhfVkFMVUUsIChJbnRlZ2VyLk1BWF9WQUxVRSAtIDEpIH07CisgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5TdGF0dXMgW10gZW5TID0KKyAgICAgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5TdGF0dXMudmFsdWVzKCk7CisgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMgW10gZW5IUyA9CisgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzLnZhbHVlcygpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVuUy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBlbkhTLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgbiA9IDA7IG4gPCBwb3MubGVuZ3RoOyBuKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgbCA9IDA7IGwgPCBwb3MubGVuZ3RoOyArK2wpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFNTTEVuZ2luZVJlc3VsdCByZXMgPSBuZXcgU1NMRW5naW5lUmVzdWx0KGVuU1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5IU1tqXSwgcG9zW25dLCBwb3NbbF0pOworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiUmVzdWx0IG9mIHRvU3JpbmcoKSBtZXRob2QgaXMgbnVsbCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcy50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBmaW5kRWwoT2JqZWN0W10gYXJyLCBPYmplY3QgZWwpIHsKKyAgICAgICAgYm9vbGVhbiBvayA9IGZhbHNlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKGFycltpXS5lcXVhbHMoZWwpKSB7CisgICAgICAgICAgICAgICAgb2sgPSB0cnVlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBvazsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xFbmdpbmVUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMRW5naW5lVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMxZDBhMTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMRW5naW5lVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTQ4MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5SZWFkT25seUJ1ZmZlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5QaXBlOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlBpcGUuU2lua0NoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuUGlwZS5Tb3VyY2VDaGFubmVsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5TWFuYWdlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTENvbnRleHQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFbmdpbmU7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFbmdpbmVSZXN1bHQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLkFuZHJvaWRPbmx5OworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLktub3duRmFpbHVyZTsKKworCisvKioKKyAqIFRlc3RzIGZvciBTU0xFbmdpbmUgY2xhc3MKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBTU0xFbmdpbmVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBIYW5kc2hha2VIYW5kbGVyIGNsaWVudEVuZ2luZTsKKyAgICBwcml2YXRlIEhhbmRzaGFrZUhhbmRsZXIgc2VydmVyRW5naW5lOworCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+U1NMRW5naW5lKCk8L2NvZGU+IGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY3JlYXRlcworICAgICAqIFNTTEVuZ2luZSBvYmplY3Qgd2l0aCBudWxsIGhvc3QgYW5kIC0xIHBvcnQKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMRW5naW5lIGUgPSBnZXRFbmdpbmUoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChlLmdldFBlZXJIb3N0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGUuZ2V0UGVlclBvcnQoKSk7CisgICAgICAgIFN0cmluZ1tdIHN1aXRlcyA9IGUuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgICAgIGUuc2V0RW5hYmxlZENpcGhlclN1aXRlcyhzdWl0ZXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoZS5nZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCkubGVuZ3RoLCBzdWl0ZXMubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5TU0xFbmdpbmUoU3RyaW5nIGhvc3QsIGludCBwb3J0KTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZ0kwMSgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpbnQgcG9ydCA9IDEwMTA7CisgICAgICAgIFNTTEVuZ2luZSBlID0gZ2V0RW5naW5lKG51bGwsIHBvcnQpOworICAgICAgICBhc3NlcnROdWxsKGUuZ2V0UGVlckhvc3QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhlLmdldFBlZXJQb3J0KCksIHBvcnQpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZS5iZWdpbkhhbmRzaGFrZSgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKFNTTEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBTU0xFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBlID0gZ2V0RW5naW5lKG51bGwsIHBvcnQpOworICAgICAgICBlLnNldFVzZUNsaWVudE1vZGUodHJ1ZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlLmJlZ2luSGFuZHNoYWtlKCk7CisgICAgICAgIH0gY2F0Y2ggKFNTTEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBlID0gZ2V0RW5naW5lKG51bGwsIHBvcnQpOworICAgICAgICBlLnNldFVzZUNsaWVudE1vZGUoZmFsc2UpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZS5iZWdpbkhhbmRzaGFrZSgpOworICAgICAgICB9IGNhdGNoIChTU0xFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5TU0xFbmdpbmUoU3RyaW5nIGhvc3QsIGludCBwb3J0KTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZ0kwMigpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgaG9zdCA9ICJuZXcgaG9zdCI7CisgICAgICAgIGludCBwb3J0ID0gODA4MDsKKyAgICAgICAgU1NMRW5naW5lIGUgPSBnZXRFbmdpbmUoaG9zdCwgcG9ydCk7CisgICAgICAgIGFzc2VydEVxdWFscyhlLmdldFBlZXJIb3N0KCksIGhvc3QpOworICAgICAgICBhc3NlcnRFcXVhbHMoZS5nZXRQZWVyUG9ydCgpLCBwb3J0KTsKKyAgICAgICAgU3RyaW5nW10gc3VpdGVzID0gZS5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKTsKKyAgICAgICAgZS5zZXRFbmFibGVkQ2lwaGVyU3VpdGVzKHN1aXRlcyk7CisgICAgICAgIGFzc2VydEVxdWFscyhlLmdldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKS5sZW5ndGgsIHN1aXRlcy5sZW5ndGgpOworICAgICAgICBlLnNldFVzZUNsaWVudE1vZGUodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoZS5nZXRVc2VDbGllbnRNb2RlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldFBlZXJIb3N0KCk8L2NvZGU+IG1ldGhvZAorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQZWVySG9zdCgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBTU0xFbmdpbmUgZSA9IGdldEVuZ2luZSgpOworICAgICAgICBhc3NlcnROdWxsKGUuZ2V0UGVlckhvc3QoKSk7CisgICAgICAgIGUgPSBnZXRFbmdpbmUoInd3dy5mb3J0aWZ5Lm5ldCIsIDgwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgaG9zdCBuYW1lIiwgInd3dy5mb3J0aWZ5Lm5ldCIsIGUuZ2V0UGVlckhvc3QoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UGVlclBvcnQoKTwvY29kZT4gbWV0aG9kCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFBlZXJQb3J0KCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIFNTTEVuZ2luZSBlID0gZ2V0RW5naW5lKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRlZmF1bHQgdmFsdWUgb2YgcGVlciBwb3J0IiwKKyAgICAgICAgICAgICAgICAtMSAsZS5nZXRQZWVyUG9ydCgpKTsKKyAgICAgICAgZSA9IGdldEVuZ2luZSgid3d3LmZvcnRpZnkubmV0IiwgODApOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwZWVyIHBvcnQiLCA4MCwgZS5nZXRQZWVyUG9ydCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI2dldFN1cHBvcnRlZFByb3RvY29scygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTdXBwb3J0ZWRQcm90b2NvbHMoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMRW5naW5lIHNzZSA9IGdldEVuZ2luZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nW10gcmVzID0gc3NlLmdldFN1cHBvcnRlZFByb3RvY29scygpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChyZXMpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShyZXMubGVuZ3RoID4gMCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjc2V0RW5hYmxlZFByb3RvY29scyhTdHJpbmdbXSBwcm90b2NvbHMpCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjZ2V0RW5hYmxlZFByb3RvY29scygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9FbmFibGVkUHJvdG9jb2xzKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIFNTTEVuZ2luZSBzc2UgPSBnZXRFbmdpbmUoKTsKKyAgICAgICAgU3RyaW5nW10gcHIgPSBzc2UuZ2V0U3VwcG9ydGVkUHJvdG9jb2xzKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2Uuc2V0RW5hYmxlZFByb3RvY29scyhwcik7CisgICAgICAgICAgICBTdHJpbmdbXSByZXMgPSBzc2UuZ2V0RW5hYmxlZFByb3RvY29scygpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTnVsbCBhcnJheSB3YXMgcmV0dXJuZWQiLCByZXMpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYXJyYXkgbGVuZ3RoIiwgcmVzLmxlbmd0aCwgcHIubGVuZ3RoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBhcnJheSB3YXMgcmV0dXJuZWQiLCBBcnJheXMuZXF1YWxzKHJlcywgcHIpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZXgpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2Uuc2V0RW5hYmxlZFByb3RvY29scyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFN1cHBvcnRlZENpcGhlclN1aXRlcygpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBTU0xFbmdpbmUgc3NlID0gZ2V0RW5naW5lKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmdbXSByZXMgPSBzc2UuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHJlcyk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHJlcy5sZW5ndGggPiAwKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSNzZXRFbmFibGVkQ2lwaGVyU3VpdGVzKFN0cmluZ1tdIHN1aXRlcykKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSNnZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0VuYWJsZWRDaXBoZXJTdWl0ZXMoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMRW5naW5lIHNzZSA9IGdldEVuZ2luZSgpOworICAgICAgICBTdHJpbmdbXSBzdCA9IHNzZS5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzZS5zZXRFbmFibGVkQ2lwaGVyU3VpdGVzKHN0KTsKKyAgICAgICAgICAgIFN0cmluZ1tdIHJlcyA9IHNzZS5nZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJOdWxsIGFycmF5IHdhcyByZXR1cm5lZCIsIHJlcyk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhcnJheSBsZW5ndGgiLCByZXMubGVuZ3RoLCBzdC5sZW5ndGgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGFycmF5IHdhcyByZXR1cm5lZCIsIEFycmF5cy5lcXVhbHMocmVzLCBzdCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBleCk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzZS5zZXRFbmFibGVkQ2lwaGVyU3VpdGVzKG51bGwpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSNzZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oYm9vbGVhbiBmbGFnKQorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI2dldEVuYWJsZVNlc3Npb25DcmVhdGlvbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9FbmFibGVTZXNzaW9uQ3JlYXRpb24oKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMRW5naW5lIHNzZSA9IGdldEVuZ2luZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShzc2UuZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCkpOworICAgICAgICAgICAgc3NlLnNldEVuYWJsZVNlc3Npb25DcmVhdGlvbihmYWxzZSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShzc2UuZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCkpOworICAgICAgICAgICAgc3NlLnNldEVuYWJsZVNlc3Npb25DcmVhdGlvbih0cnVlKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoc3NlLmdldEVuYWJsZVNlc3Npb25DcmVhdGlvbigpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSNzZXROZWVkQ2xpZW50QXV0aChib29sZWFuIG5lZWQpCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjZ2V0TmVlZENsaWVudEF1dGgoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfTmVlZENsaWVudEF1dGgoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMRW5naW5lIHNzZSA9IGdldEVuZ2luZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLnNldE5lZWRDbGllbnRBdXRoKGZhbHNlKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHNzZS5nZXROZWVkQ2xpZW50QXV0aCgpKTsKKyAgICAgICAgICAgIHNzZS5zZXROZWVkQ2xpZW50QXV0aCh0cnVlKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoc3NlLmdldE5lZWRDbGllbnRBdXRoKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3NldFdhbnRDbGllbnRBdXRoKGJvb2xlYW4gd2FudCkKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSNnZXRXYW50Q2xpZW50QXV0aCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9XYW50Q2xpZW50QXV0aCgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBTU0xFbmdpbmUgc3NlID0gZ2V0RW5naW5lKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2Uuc2V0V2FudENsaWVudEF1dGgoZmFsc2UpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc3NlLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICAgICAgc3NlLnNldFdhbnRDbGllbnRBdXRoKHRydWUpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShzc2UuZ2V0V2FudENsaWVudEF1dGgoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjYmVnaW5IYW5kc2hha2UoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYmVnaW5IYW5kc2hha2UoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMRW5naW5lIHNzZSA9IGdldEVuZ2luZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLmJlZ2luSGFuZHNoYWtlKCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gc2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgICAgIHNzZSA9IGdldEVuZ2luZSgibmV3IGhvc3QiLCAxMDgwKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzZS5iZWdpbkhhbmRzaGFrZSgpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlzZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICAgICAgc3NlID0gZ2V0RW5naW5lKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2Uuc2V0VXNlQ2xpZW50TW9kZSh0cnVlKTsKKyAgICAgICAgICAgIHNzZS5iZWdpbkhhbmRzaGFrZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3NldFVzZUNsaWVudE1vZGUoYm9vbGVhbiBtb2RlKQorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI2dldFVzZUNsaWVudE1vZGUoKQorICAgICAqLworICAgIEBBbmRyb2lkT25seSgiVGhlIFJJIGRvZXNuJ3QgdGhyb3cgdGhlIGV4cGVjdGVkIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbi4iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfVXNlQ2xpZW50TW9kZSgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBTU0xFbmdpbmUgc3NlID0gZ2V0RW5naW5lKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2Uuc2V0VXNlQ2xpZW50TW9kZShmYWxzZSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShzc2UuZ2V0VXNlQ2xpZW50TW9kZSgpKTsKKyAgICAgICAgICAgIHNzZS5zZXRVc2VDbGllbnRNb2RlKHRydWUpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShzc2UuZ2V0VXNlQ2xpZW50TW9kZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZXgpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzZSA9IGdldEVuZ2luZShudWxsLCAxMDgwKTsKKyAgICAgICAgICAgIHNzZS5zZXRVc2VDbGllbnRNb2RlKHRydWUpOworICAgICAgICAgICAgc3NlLmJlZ2luSGFuZHNoYWtlKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHNzZS5zZXRVc2VDbGllbnRNb2RlKGZhbHNlKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjZ2V0U2Vzc2lvbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTZXNzaW9uKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIFNTTEVuZ2luZSBzc2UgPSBnZXRFbmdpbmUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc3NlLmdldFNlc3Npb24oKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjZ2V0SGFuZHNoYWtlU3RhdHVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEhhbmRzaGFrZVN0YXR1cygpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBTU0xFbmdpbmUgc3NlID0gZ2V0RW5naW5lKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoc3NlLmdldEhhbmRzaGFrZVN0YXR1cygpLnRvU3RyaW5nKCksICJOT1RfSEFORFNIQUtJTkciKTsKKyAgICAgICAgICAgIHNzZS5zZXRVc2VDbGllbnRNb2RlKHRydWUpOworICAgICAgICAgICAgc3NlLmJlZ2luSGFuZHNoYWtlKCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoc3NlLmdldEhhbmRzaGFrZVN0YXR1cygpLnRvU3RyaW5nKCksICJORUVEX1dSQVAiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSNnZXREZWxlZ2F0ZWRUYXNrKCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC5wcm92aWRlci5qc3NlLlNTTEVuZ2luZUltcGwjZ2V0RGVsZWdhdGVkVGFzaygpIHRocm93cyBOUEUgaW5zdGVhZCBvZiByZXR1cm5pbmcgbnVsbCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREZWxlZ2F0ZWRUYXNrKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIFNTTEVuZ2luZSBzc2UgPSBnZXRFbmdpbmUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydE51bGwoc3NlLmdldERlbGVnYXRlZFRhc2soKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjdW53cmFwKEJ5dGVCdWZmZXIgc3JjLCBCeXRlQnVmZmVyW10gZHN0cywKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBvZmZzZXQsIGludCBsZW5ndGgpCisgICAgICogRXhjZXB0aW9uIGNhc2U6IFNTTEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdW53cmFwXzAxKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHByZXBhcmVFbmdpbmVzKCk7CisgICAgICAgIGRvSGFuZHNoYWtlKCk7CisKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYnMgPSBCeXRlQnVmZmVyLndyYXAobmV3IGJ5dGVbXSB7MSwyLDMsMSwyLDMsMSwyLDMsMSwyLDMsMSwyLDMsMSwyLDMsMSwyLDMsMSwyLDMsMSwyLDMsMSwyLDMsMSwyLDMsMSwyLDMxLDIsMywxLDIsMywxLDIsMywxLDIsM30pOworICAgICAgICBCeXRlQnVmZmVyIGJiZCA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTAwKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNsaWVudEVuZ2luZS5lbmdpbmUudW53cmFwKGJicywgbmV3IEJ5dGVCdWZmZXJbXSB7IGJiZCB9LCAwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIlNTTEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNTTEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjdW53cmFwKEJ5dGVCdWZmZXIgc3JjLCBCeXRlQnVmZmVyW10gZHN0cywKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBvZmZzZXQsIGludCBsZW5ndGgpCisgICAgICogRXhjZXB0aW9uIGNhc2U6IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4KKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJGaXhlZCBpbiBEb251dEJ1cmdlciwgYm91bmRhcnkgY2hlY2tzIG1pc3NpbmciKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfdW53cmFwXzAyKCkgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBob3N0ID0gIm5ldyBob3N0IjsKKyAgICAgICAgaW50IHBvcnQgPSA4MDgwOworICAgICAgICBCeXRlQnVmZmVyW10gYmJBID0geyBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwMCksIEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApLCBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwMCkgfTsKKworICAgICAgICBCeXRlQnVmZmVyIGJiID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCk7CisgICAgICAgIFNTTEVuZ2luZSBzc2UgPSBnZXRFbmdpbmUoaG9zdCwgcG9ydCk7CisgICAgICAgIHNzZS5zZXRVc2VDbGllbnRNb2RlKHRydWUpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2UudW53cmFwKGJiLCBiYkEsIC0xLCAzKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlvYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLnVud3JhcChiYiwgYmJBLCAwLCAtMyk7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzZS51bndyYXAoYmIsIGJiQSwgYmJBLmxlbmd0aCArIDEsIGJiQS5sZW5ndGgpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2UudW53cmFwKGJiLCBiYkEsIDAsIGJiQS5sZW5ndGggKyAxKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlvYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3Vud3JhcChCeXRlQnVmZmVyIHNyYywgQnl0ZUJ1ZmZlcltdIGRzdHMsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKQorICAgICAqIEV4Y2VwdGlvbiBjYXNlOiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLgorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIkZpeGVkIG9uIERvbnV0QnVyZ2VyLCBXcm9uZyBFeGNlcHRpb24gdGhyb3duIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Vud3JhcF8wMygpIHsKKyAgICAgICAgU3RyaW5nIGhvc3QgPSAibmV3IGhvc3QiOworICAgICAgICBpbnQgcG9ydCA9IDgwODA7CisgICAgICAgIEJ5dGVCdWZmZXIgYmJSID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMDApLmFzUmVhZE9ubHlCdWZmZXIoKTsKKyAgICAgICAgQnl0ZUJ1ZmZlcltdIGJiQSA9IHsgYmJSLCBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMDApIH07CisKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYiA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApOworICAgICAgICBTU0xFbmdpbmUgc3NlID0gZ2V0RW5naW5lKGhvc3QsIHBvcnQpOworICAgICAgICBzc2Uuc2V0VXNlQ2xpZW50TW9kZSh0cnVlKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLnVud3JhcChiYiwgYmJBLCAwLCBiYkEubGVuZ3RoKTsKKyAgICAgICAgICAgIGZhaWwoIlJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24gaW9iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3Vud3JhcChCeXRlQnVmZmVyIHNyYywgQnl0ZUJ1ZmZlcltdIGRzdHMsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKQorICAgICAqIEV4Y2VwdGlvbiBjYXNlOiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4KKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJGaXhlZCBvbiBEb251dEJ1cmdlciwgV3JvbmcgRXhjZXB0aW9uIHRocm93biIpCisgICAgcHVibGljIHZvaWQgdGVzdF91bndyYXBfMDQoKSB7CisgICAgICAgIFN0cmluZyBob3N0ID0gIm5ldyBob3N0IjsKKyAgICAgICAgaW50IHBvcnQgPSA4MDgwOworICAgICAgICBCeXRlQnVmZmVyW10gYmJBID0ge0J5dGVCdWZmZXIuYWxsb2NhdGUoMTAwKSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCksIEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTAwKX07CisgICAgICAgIEJ5dGVCdWZmZXJbXSBiYkFOID0ge0J5dGVCdWZmZXIuYWxsb2NhdGUoMTAwKSwgbnVsbCwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMDApfTsKKyAgICAgICAgQnl0ZUJ1ZmZlcltdIGJiTiA9IG51bGw7CisgICAgICAgIEJ5dGVCdWZmZXIgYmIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiTiA9IG51bGw7CisgICAgICAgIFNTTEVuZ2luZSBzc2UgPSBnZXRFbmdpbmUoaG9zdCwgcG9ydCk7CisgICAgICAgIHNzZS5zZXRVc2VDbGllbnRNb2RlKHRydWUpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2UudW53cmFwKGJOLCBiYkEsIDAsIDMpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlvYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLnVud3JhcChiYiwgYmJBTiwgMCwgMyk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaW9iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2UudW53cmFwKGJiLCBiYk4sIDAsIDApOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlvYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLnVud3JhcChiTiwgYmJOLCAwLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3Vud3JhcChCeXRlQnVmZmVyIHNyYywgQnl0ZUJ1ZmZlcltdIGRzdHMsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKQorICAgICAqIEV4Y2VwdGlvbiBjYXNlOiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4KKyAgICAgKi8KKyAgICBAQW5kcm9pZE9ubHkoIlRoZSBSSSBkb2Vzbid0IHRocm93IHRoZSBJbGxlZ2FsU3RhdGVFeGNlcHRpb24uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Vud3JhcF8wNSgpIHsKKyAgICAgICAgU3RyaW5nIGhvc3QgPSAibmV3IGhvc3QiOworICAgICAgICBpbnQgcG9ydCA9IDgwODA7CisgICAgICAgIEJ5dGVCdWZmZXJbXSBiYkEgPSB7IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTAwKSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCksIEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTAwKSB9OworCisgICAgICAgIEJ5dGVCdWZmZXIgYmIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKTsKKyAgICAgICAgU1NMRW5naW5lIHNzZSA9IGdldEVuZ2luZShob3N0LCBwb3J0KTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLnVud3JhcChiYiwgYmJBLCAwLCBiYkEubGVuZ3RoKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3Vud3JhcChCeXRlQnVmZmVyIHNyYywgQnl0ZUJ1ZmZlcltdIGRzdHMsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdW53cmFwXzA2KCkgeworICAgICAgICBTdHJpbmcgaG9zdCA9ICJuZXcgaG9zdCI7CisgICAgICAgIGludCBwb3J0ID0gODA4MDsKKyAgICAgICAgQnl0ZUJ1ZmZlcltdIGJiQSA9IHsgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMDApLCBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMDApIH07CisKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYiA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApOworICAgICAgICBTU0xFbmdpbmUgc3NlID0gZ2V0RW5naW5lKGhvc3QsIHBvcnQpOworICAgICAgICBzc2Uuc2V0VXNlQ2xpZW50TW9kZSh0cnVlKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0IHJlcyA9IHNzZS51bndyYXAoYmIsIGJiQSwgMCwgYmJBLmxlbmd0aCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgcmVzLmJ5dGVzQ29uc3VtZWQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgcmVzLmJ5dGVzUHJvZHVjZWQoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyYXBfMDEoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgcHJlcGFyZUVuZ2luZXMoKTsKKyAgICAgICAgZG9IYW5kc2hha2UoKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYnMgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwMCk7CisgICAgICAgIEJ5dGVCdWZmZXIgYmJkID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgyMDAwMCk7CisgICAgICAgIGNsaWVudEVuZ2luZS5lbmdpbmUud3JhcChuZXcgQnl0ZUJ1ZmZlcltdIHsgYmJzIH0sIDAsIDEsIGJiZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjd3JhcChCeXRlQnVmZmVyW10gc3JjcywgaW50IG9mZnNldCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoLCBCeXRlQnVmZmVyIGRzdCkKKyAgICAgKiBFeGNlcHRpb24gY2FzZTogSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLgorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIkZpeGVkIGluIERvbnV0QnVyZ2VyLCBib3VuZGFyeSBjaGVja3MgbWlzc2luZyIpCisgICAgcHVibGljIHZvaWQgdGVzdF93cmFwXzAyKCkgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBob3N0ID0gIm5ldyBob3N0IjsKKyAgICAgICAgaW50IHBvcnQgPSA4MDgwOworICAgICAgICBCeXRlQnVmZmVyIGJiID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCk7CisgICAgICAgIEJ5dGVCdWZmZXJbXSBiYkEgPSB7Qnl0ZUJ1ZmZlci5hbGxvY2F0ZSg1KSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCksIEJ5dGVCdWZmZXIuYWxsb2NhdGUoNSl9OworICAgICAgICBTU0xFbmdpbmUgc3NlID0gZ2V0RW5naW5lKGhvc3QsIHBvcnQpOworICAgICAgICBzc2Uuc2V0VXNlQ2xpZW50TW9kZSh0cnVlKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLndyYXAoYmJBLCAtMSwgMywgYmIpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2Uud3JhcChiYkEsIDAsIC0zLCBiYik7CisgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzZS53cmFwKGJiQSwgYmJBLmxlbmd0aCArIDEsIGJiQS5sZW5ndGgsIGJiKTsKKyAgICAgICAgICAgIGZhaWwoIkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlvYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLndyYXAoYmJBLCAwLCBiYkEubGVuZ3RoICsgMSwgYmIpOworICAgICAgICAgICAgZmFpbCgiSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW9iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjd3JhcChCeXRlQnVmZmVyW10gc3JjcywgaW50IG9mZnNldCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoLCBCeXRlQnVmZmVyIGRzdCkKKyAgICAgKiBFeGNlcHRpb24gY2FzZTogUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyYXBfMDMoKSB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGhvc3QgPSAibmV3IGhvc3QiOworICAgICAgICBpbnQgcG9ydCA9IDgwODA7CisgICAgICAgIEJ5dGVCdWZmZXIgYmIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKS5hc1JlYWRPbmx5QnVmZmVyKCk7CisgICAgICAgIEJ5dGVCdWZmZXJbXSBiYkEgPSB7Qnl0ZUJ1ZmZlci5hbGxvY2F0ZSg1KSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCksIEJ5dGVCdWZmZXIuYWxsb2NhdGUoNSl9OworICAgICAgICBTU0xFbmdpbmUgc3NlID0gZ2V0RW5naW5lKGhvc3QsIHBvcnQpOworICAgICAgICBzc2Uuc2V0VXNlQ2xpZW50TW9kZSh0cnVlKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLndyYXAoYmJBLCAwLCBiYkEubGVuZ3RoLCBiYik7CisgICAgICAgICAgICBmYWlsKCJSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uIGlvYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3dyYXAoQnl0ZUJ1ZmZlcltdIHNyY3MsIGludCBvZmZzZXQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxlbmd0aCwgQnl0ZUJ1ZmZlciBkc3QpCisgICAgICogRXhjZXB0aW9uIGNhc2U6IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLgorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIkZpeGVkIG9uIERvbnV0QnVyZ2VyLCBXcm9uZyBFeGNlcHRpb24gdGhyb3duIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyYXBfMDQoKSB7CisgICAgICAgIFN0cmluZyBob3N0ID0gIm5ldyBob3N0IjsKKyAgICAgICAgaW50IHBvcnQgPSA4MDgwOworICAgICAgICBCeXRlQnVmZmVyW10gYmJBID0ge0J5dGVCdWZmZXIuYWxsb2NhdGUoMTAwKSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCksIEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTAwKX07CisgICAgICAgIEJ5dGVCdWZmZXJbXSBiYk4gPSBudWxsOworICAgICAgICBCeXRlQnVmZmVyIGJOID0gbnVsbDsKKyAgICAgICAgU1NMRW5naW5lIGUgPSBnZXRFbmdpbmUoaG9zdCwgcG9ydCk7CisgICAgICAgIGUuc2V0VXNlQ2xpZW50TW9kZSh0cnVlKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZS53cmFwKGJiQSwgMCwgMywgYk4pOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIGZvciBudWxsIHNyY3MgYnl0ZSBidWZmZXIgYXJyYXkiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleCkgeworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoZXggKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlLndyYXAoYmJOLCAwLCAwLCBiTik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbChleCArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjd3JhcChCeXRlQnVmZmVyW10gc3JjcywgaW50IG9mZnNldCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoLCBCeXRlQnVmZmVyIGRzdCkKKyAgICAgKiBFeGNlcHRpb24gY2FzZTogSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uCisgICAgICovCisgICAgQEFuZHJvaWRPbmx5KCJUaGUgUkkgZG9lc24ndCB0aHJvdyB0aGUgSWxsZWdhbFN0YXRlRXhjZXB0aW9uLiIpCisgICAgcHVibGljIHZvaWQgdGVzdF93cmFwXzA1KCkgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBob3N0ID0gIm5ldyBob3N0IjsKKyAgICAgICAgaW50IHBvcnQgPSA4MDgwOworICAgICAgICBCeXRlQnVmZmVyIGJiID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCk7CisgICAgICAgIEJ5dGVCdWZmZXJbXSBiYkEgPSB7Qnl0ZUJ1ZmZlci5hbGxvY2F0ZSg1KSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCksIEJ5dGVCdWZmZXIuYWxsb2NhdGUoNSl9OworICAgICAgICBTU0xFbmdpbmUgc3NlID0gZ2V0RW5naW5lKGhvc3QsIHBvcnQpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2Uud3JhcChiYkEsIDAsIGJiQS5sZW5ndGgsIGJiKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSN3cmFwKEJ5dGVCdWZmZXJbXSBzcmNzLCBpbnQgb2Zmc2V0LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsZW5ndGgsIEJ5dGVCdWZmZXIgZHN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfd3JhcF8wNigpIHsKKyAgICAgICAgU3RyaW5nIGhvc3QgPSAibmV3IGhvc3QiOworICAgICAgICBpbnQgcG9ydCA9IDgwODA7CisgICAgICAgIEJ5dGVCdWZmZXIgYmIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKTsKKyAgICAgICAgQnl0ZUJ1ZmZlcltdIGJiQSA9IHtCeXRlQnVmZmVyLmFsbG9jYXRlKDUpLCBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSg1KX07CisgICAgICAgIFNTTEVuZ2luZSBzc2UgPSBnZXRFbmdpbmUoaG9zdCwgcG9ydCk7CisgICAgICAgIHNzZS5zZXRVc2VDbGllbnRNb2RlKHRydWUpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2Uud3JhcChiYkEsIDAsIGJiQS5sZW5ndGgsIGJiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjY2xvc2VPdXRib3VuZCgpCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjaXNPdXRib3VuZERvbmUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2xvc2VPdXRib3VuZCgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBTU0xFbmdpbmUgc3NlID0gZ2V0RW5naW5lKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHNzZS5pc091dGJvdW5kRG9uZSgpKTsKKyAgICAgICAgICAgIHNzZS5jbG9zZU91dGJvdW5kKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHNzZS5pc091dGJvdW5kRG9uZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjY2xvc2VJbmJvdW5kKCkKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSNpc0luYm91bmREb25lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb3NlSW5ib3VuZCgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBTU0xFbmdpbmUgc3NlID0gZ2V0RW5naW5lKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHNzZS5pc0luYm91bmREb25lKCkpOworICAgICAgICAgICAgc3NlLmNsb3NlSW5ib3VuZCgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShzc2UuaXNJbmJvdW5kRG9uZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3Vud3JhcChCeXRlQnVmZmVyIHNyYywgQnl0ZUJ1ZmZlciBkc3QpCisgICAgICogU1NMRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF91bndyYXBfQnl0ZUJ1ZmZlcl9CeXRlQnVmZmVyXzAxKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHByZXBhcmVFbmdpbmVzKCk7CisgICAgICAgIGRvSGFuZHNoYWtlKCk7CisgICAgICAgIEJ5dGVCdWZmZXIgYmJzID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMDApOworICAgICAgICBCeXRlQnVmZmVyIGJiZCA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTAwKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0IHVud3JhcCA9IGNsaWVudEVuZ2luZS5lbmdpbmUudW53cmFwKGJicywgYmJkKTsKKyAgICAgICAgICAgIGZhaWwoIlNTTEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNTTEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjdW53cmFwKEJ5dGVCdWZmZXIgc3JjLCBCeXRlQnVmZmVyIGRzdCkKKyAgICAgKiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLgorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIkZpeGVkIG9uIERvbnV0QnVyZ2VyLCBXcm9uZyBFeGNlcHRpb24gdGhyb3duIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Vud3JhcF9CeXRlQnVmZmVyX0J5dGVCdWZmZXJfMDIoKSB7CisgICAgICAgIFN0cmluZyBob3N0ID0gIm5ldyBob3N0IjsKKyAgICAgICAgaW50IHBvcnQgPSA4MDgwOworICAgICAgICBCeXRlQnVmZmVyIGJicyA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApOworICAgICAgICBCeXRlQnVmZmVyIGJiZCA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTAwKS5hc1JlYWRPbmx5QnVmZmVyKCk7CisgICAgICAgIFNTTEVuZ2luZSBzc2UgPSBnZXRFbmdpbmUoaG9zdCwgcG9ydCk7CisgICAgICAgIHNzZS5zZXRVc2VDbGllbnRNb2RlKHRydWUpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2UudW53cmFwKGJicywgYmJkKTsKKyAgICAgICAgICAgIGZhaWwoIlJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24gaW9iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3Vud3JhcChCeXRlQnVmZmVyIHNyYywgQnl0ZUJ1ZmZlciBkc3QpCisgICAgICogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgiRml4ZWQgb24gRG9udXRCdXJnZXIsIFdyb25nIEV4Y2VwdGlvbiB0aHJvd24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfdW53cmFwX0J5dGVCdWZmZXJfQnl0ZUJ1ZmZlcl8wMygpIHsKKyAgICAgICAgU3RyaW5nIGhvc3QgPSAibmV3IGhvc3QiOworICAgICAgICBpbnQgcG9ydCA9IDgwODA7CisgICAgICAgIEJ5dGVCdWZmZXIgYmJzTiA9IG51bGw7CisgICAgICAgIEJ5dGVCdWZmZXIgYmJkTiA9IG51bGw7CisgICAgICAgIEJ5dGVCdWZmZXIgYmJzID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCk7CisgICAgICAgIEJ5dGVCdWZmZXIgYmJkID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMDApOworICAgICAgICBTU0xFbmdpbmUgc3NlID0gZ2V0RW5naW5lKGhvc3QsIHBvcnQpOworICAgICAgICBzc2Uuc2V0VXNlQ2xpZW50TW9kZSh0cnVlKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLnVud3JhcChiYnNOLCBiYmQpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzZS51bndyYXAoYmJzLCBiYmROKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2UudW53cmFwKGJic04sIGJiZE4pOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjdW53cmFwKEJ5dGVCdWZmZXIgc3JjLCBCeXRlQnVmZmVyIGRzdCkKKyAgICAgKiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4KKyAgICAgKi8KKyAgICBAQW5kcm9pZE9ubHkoIlRoZSBSSSBkb2Vzbid0IHRocm93IHRoZSBJbGxlZ2FsU3RhdGVFeGNlcHRpb24uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Vud3JhcF9CeXRlQnVmZmVyX0J5dGVCdWZmZXJfMDQoKSB7CisgICAgICAgIFN0cmluZyBob3N0ID0gIm5ldyBob3N0IjsKKyAgICAgICAgaW50IHBvcnQgPSA4MDgwOworICAgICAgICBCeXRlQnVmZmVyIGJicyA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApOworICAgICAgICBCeXRlQnVmZmVyIGJiZCA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTAwKTsKKyAgICAgICAgU1NMRW5naW5lIHNzZSA9IGdldEVuZ2luZShob3N0LCBwb3J0KTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLnVud3JhcChiYnMsIGJiZCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaW9iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSN1bndyYXAoQnl0ZUJ1ZmZlciBzcmMsIEJ5dGVCdWZmZXIgZHN0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdW53cmFwX0J5dGVCdWZmZXJfQnl0ZUJ1ZmZlcl8wNSgpIHsKKyAgICAgICAgU3RyaW5nIGhvc3QgPSAibmV3IGhvc3QiOworICAgICAgICBpbnQgcG9ydCA9IDgwODA7CisgICAgICAgIEJ5dGVCdWZmZXIgYmJzID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCk7CisgICAgICAgIEJ5dGVCdWZmZXIgYmJkID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMDApOworICAgICAgICBTU0xFbmdpbmUgc3NlID0gZ2V0RW5naW5lKGhvc3QsIHBvcnQpOworICAgICAgICBzc2Uuc2V0VXNlQ2xpZW50TW9kZSh0cnVlKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0IHJlcyA9IHNzZS51bndyYXAoYmJzLCBiYmQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHJlcy5ieXRlc0NvbnN1bWVkKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHJlcy5ieXRlc1Byb2R1Y2VkKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3Vud3JhcChCeXRlQnVmZmVyIHNyYywgQnl0ZUJ1ZmZlcltdIGRzdHMpCisgICAgICogU1NMRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF91bndyYXBfQnl0ZUJ1ZmZlciRCeXRlQnVmZmVyXzAxKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHByZXBhcmVFbmdpbmVzKCk7CisgICAgICAgIGRvSGFuZHNoYWtlKCk7CisKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYnMgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwMCk7CisgICAgICAgIEJ5dGVCdWZmZXIgYmJkID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMDApOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjbGllbnRFbmdpbmUuZW5naW5lLnVud3JhcChiYnMsIG5ldyBCeXRlQnVmZmVyW10geyBiYmQgfSk7CisgICAgICAgICAgICBmYWlsKCJTU0xFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTU0xFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3Vud3JhcChCeXRlQnVmZmVyIHNyYywgQnl0ZUJ1ZmZlcltdIGRzdHMpCisgICAgICogUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4KKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJGaXhlZCBvbiBEb251dEJ1cmdlciwgV3JvbmcgRXhjZXB0aW9uIHRocm93biIpCisgICAgcHVibGljIHZvaWQgdGVzdF91bndyYXBfQnl0ZUJ1ZmZlciRCeXRlQnVmZmVyXzAyKCkgeworICAgICAgICBTdHJpbmcgaG9zdCA9ICJuZXcgaG9zdCI7CisgICAgICAgIGludCBwb3J0ID0gODA4MDsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYnMgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYlIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwMCkuYXNSZWFkT25seUJ1ZmZlcigpOworICAgICAgICBCeXRlQnVmZmVyW10gYmJBID0geyBiYlIsIEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApLCBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwMCkgfTsKKyAgICAgICAgU1NMRW5naW5lIHNzZSA9IGdldEVuZ2luZShob3N0LCBwb3J0KTsKKyAgICAgICAgc3NlLnNldFVzZUNsaWVudE1vZGUodHJ1ZSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzZS51bndyYXAoYmJzLCBiYkEpOworICAgICAgICAgICAgZmFpbCgiUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbiBpb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBSZWFkT25seUJ1ZmZlckV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjdW53cmFwKEJ5dGVCdWZmZXIgc3JjLCBCeXRlQnVmZmVyW10gZHN0cykKKyAgICAgKiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4KKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJGaXhlZCBvbiBEb251dEJ1cmdlciwgV3JvbmcgRXhjZXB0aW9uIHRocm93biIpCisgICAgcHVibGljIHZvaWQgdGVzdF91bndyYXBfQnl0ZUJ1ZmZlciRCeXRlQnVmZmVyXzAzKCkgeworICAgICAgICBTdHJpbmcgaG9zdCA9ICJuZXcgaG9zdCI7CisgICAgICAgIGludCBwb3J0ID0gODA4MDsKKyAgICAgICAgQnl0ZUJ1ZmZlcltdIGJiQSA9IHsgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMDApLCBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMDApIH07CisgICAgICAgIEJ5dGVCdWZmZXJbXSBiYk4gPSB7IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTAwKSwgbnVsbCwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMDApIH07CisgICAgICAgIEJ5dGVCdWZmZXJbXSBiYkFOID0gbnVsbDsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYiA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApOworICAgICAgICBCeXRlQnVmZmVyIGJOID0gbnVsbDsKKyAgICAgICAgU1NMRW5naW5lIHNzZSA9IGdldEVuZ2luZShob3N0LCBwb3J0KTsKKyAgICAgICAgc3NlLnNldFVzZUNsaWVudE1vZGUodHJ1ZSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzZS51bndyYXAoYk4sIGJiQSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaW9iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzZS51bndyYXAoYmIsIGJiQU4pOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlvYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2UudW53cmFwKGJiLCBiYk4pOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlvYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2UudW53cmFwKGJOLCBiYkFOKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSN1bndyYXAoQnl0ZUJ1ZmZlciBzcmMsIEJ5dGVCdWZmZXJbXSBkc3RzKQorICAgICAqIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLgorICAgICAqLworICAgIEBBbmRyb2lkT25seSgiVGhlIFJJIGRvZXNuJ3QgdGhyb3cgdGhlIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbi4iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfdW53cmFwX0J5dGVCdWZmZXIkQnl0ZUJ1ZmZlcl8wNCgpIHsKKyAgICAgICAgU3RyaW5nIGhvc3QgPSAibmV3IGhvc3QiOworICAgICAgICBpbnQgcG9ydCA9IDgwODA7CisgICAgICAgIEJ5dGVCdWZmZXIgYmJzID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCk7CisgICAgICAgIEJ5dGVCdWZmZXJbXSBiYmQgPSB7Qnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMDApLCBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMDApIH07CisgICAgICAgIFNTTEVuZ2luZSBzc2UgPSBnZXRFbmdpbmUoaG9zdCwgcG9ydCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzZS51bndyYXAoYmJzLCBiYmQpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlvYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjdW53cmFwKEJ5dGVCdWZmZXIgc3JjLCBCeXRlQnVmZmVyW10gZHN0cykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3Vud3JhcF9CeXRlQnVmZmVyJEJ5dGVCdWZmZXJfMDUoKSB7CisgICAgICAgIFN0cmluZyBob3N0ID0gIm5ldyBob3N0IjsKKyAgICAgICAgaW50IHBvcnQgPSA4MDgwOworICAgICAgICBCeXRlQnVmZmVyIGJicyA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApOworICAgICAgICBCeXRlQnVmZmVyW10gYmJkID0ge0J5dGVCdWZmZXIuYWxsb2NhdGUoMTAwKSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCksIEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTAwKSB9OworICAgICAgICBTU0xFbmdpbmUgc3NlID0gZ2V0RW5naW5lKGhvc3QsIHBvcnQpOworICAgICAgICBzc2Uuc2V0VXNlQ2xpZW50TW9kZSh0cnVlKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0IHJlcyA9IHNzZS51bndyYXAoYmJzLCBiYmQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHJlcy5ieXRlc0NvbnN1bWVkKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHJlcy5ieXRlc1Byb2R1Y2VkKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF93cmFwX0J5dGVCdWZmZXJfQnl0ZUJ1ZmZlcl8wMSgpIHRocm93cyBJT0V4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBwcmVwYXJlRW5naW5lcygpOworICAgICAgICBkb0hhbmRzaGFrZSgpOworICAgICAgICBCeXRlQnVmZmVyIGJicyA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMjApOworICAgICAgICBCeXRlQnVmZmVyIGJiZCA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMjAwMDApOworICAgICAgICBjbGllbnRFbmdpbmUuZW5naW5lLndyYXAoYmJzLCBiYmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3dyYXAoQnl0ZUJ1ZmZlciBzcmMsIEJ5dGVCdWZmZXIgZHN0KQorICAgICAqIFJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF93cmFwX0J5dGVCdWZmZXJfQnl0ZUJ1ZmZlcl8wMigpIHsKKyAgICAgICAgU3RyaW5nIGhvc3QgPSAibmV3IGhvc3QiOworICAgICAgICBpbnQgcG9ydCA9IDgwODA7CisgICAgICAgIEJ5dGVCdWZmZXIgYmJzID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCk7CisgICAgICAgIEJ5dGVCdWZmZXIgYmJkID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMDApLmFzUmVhZE9ubHlCdWZmZXIoKTsKKyAgICAgICAgU1NMRW5naW5lIHNzZSA9IGdldEVuZ2luZShob3N0LCBwb3J0KTsKKyAgICAgICAgc3NlLnNldFVzZUNsaWVudE1vZGUodHJ1ZSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzZS53cmFwKGJicywgYmJkKTsKKyAgICAgICAgICAgIGZhaWwoIlJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24gaW9iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3dyYXAoQnl0ZUJ1ZmZlciBzcmMsIEJ5dGVCdWZmZXIgZHN0KQorICAgICAqIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLgorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIkZpeGVkIG9uIERvbnV0QnVyZ2VyLCBXcm9uZyBFeGNlcHRpb24gdGhyb3duIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyYXBfQnl0ZUJ1ZmZlcl9CeXRlQnVmZmVyXzAzKCkgeworICAgICAgICBTdHJpbmcgaG9zdCA9ICJuZXcgaG9zdCI7CisgICAgICAgIGludCBwb3J0ID0gODA4MDsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYnNOID0gbnVsbDsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYmROID0gbnVsbDsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYnMgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYmQgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwMCk7CisgICAgICAgIFNTTEVuZ2luZSBzc2UgPSBnZXRFbmdpbmUoaG9zdCwgcG9ydCk7CisgICAgICAgIHNzZS5zZXRVc2VDbGllbnRNb2RlKHRydWUpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2Uud3JhcChiYnNOLCBiYmQpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzZS53cmFwKGJicywgYmJkTik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLndyYXAoYmJzTiwgYmJkTik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSN3cmFwKEJ5dGVCdWZmZXIgc3JjLCBCeXRlQnVmZmVyIGRzdCkKKyAgICAgKiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4KKyAgICAgKi8KKyAgICBAQW5kcm9pZE9ubHkoIlRoZSBSSSBkb2Vzbid0IHRocm93IHRoZSBJbGxlZ2FsU3RhdGVFeGNlcHRpb24uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyYXBfQnl0ZUJ1ZmZlcl9CeXRlQnVmZmVyXzA0KCkgeworICAgICAgICBTdHJpbmcgaG9zdCA9ICJuZXcgaG9zdCI7CisgICAgICAgIGludCBwb3J0ID0gODA4MDsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYnMgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYmQgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKTsKKyAgICAgICAgU1NMRW5naW5lIHNzZSA9IGdldEVuZ2luZShob3N0LCBwb3J0KTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLndyYXAoYmJzLCBiYmQpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlvYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjd3JhcChCeXRlQnVmZmVyIHNyYywgQnl0ZUJ1ZmZlciBkc3QpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF93cmFwX0J5dGVCdWZmZXJfQnl0ZUJ1ZmZlcl8wNSgpIHsKKyAgICAgICAgU3RyaW5nIGhvc3QgPSAibmV3IGhvc3QiOworICAgICAgICBpbnQgcG9ydCA9IDgwODA7CisgICAgICAgIEJ5dGVCdWZmZXIgYmIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKTsKKyAgICAgICAgU1NMRW5naW5lIHNzZSA9IGdldEVuZ2luZShob3N0LCBwb3J0KTsKKyAgICAgICAgc3NlLnNldFVzZUNsaWVudE1vZGUodHJ1ZSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNTTEVuZ2luZVJlc3VsdCByZXMgPSBzc2Uud3JhcChiYiwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHJlcy5ieXRlc0NvbnN1bWVkKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHJlcy5ieXRlc1Byb2R1Y2VkKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjd3JhcChCeXRlQnVmZmVyW10gc3JjcywgQnl0ZUJ1ZmZlciBkc3QpCisgICAgICogU1NMRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF93cmFwX0J5dGVCdWZmZXIkQnl0ZUJ1ZmZlcl8wMSgpIHRocm93cyBJT0V4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBwcmVwYXJlRW5naW5lcygpOworICAgICAgICBkb0hhbmRzaGFrZSgpOworICAgICAgICBCeXRlQnVmZmVyIGJicyA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTAwKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYmQgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDIwMDAwKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2xpZW50RW5naW5lLmVuZ2luZS53cmFwKG5ldyBCeXRlQnVmZmVyW10geyBiYnMgfSwgYmJkKTsKKyAgICAgICAgICAgIHNlcnZlckVuZ2luZS5lbmdpbmUud3JhcChuZXcgQnl0ZUJ1ZmZlcltdIHsgYmJzIH0sIGJiZCk7CisgICAgICAgICAgICAvL2ZhaWwoIlNTTEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNTTEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjd3JhcChCeXRlQnVmZmVyW10gc3JjcywgQnl0ZUJ1ZmZlciBkc3QpCisgICAgICogUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93bi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyYXBfQnl0ZUJ1ZmZlciRCeXRlQnVmZmVyXzAyKCkgeworICAgICAgICBTdHJpbmcgaG9zdCA9ICJuZXcgaG9zdCI7CisgICAgICAgIGludCBwb3J0ID0gODA4MDsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYiA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApLmFzUmVhZE9ubHlCdWZmZXIoKTsKKyAgICAgICAgQnl0ZUJ1ZmZlcltdIGJiQSA9IHtCeXRlQnVmZmVyLmFsbG9jYXRlKDUpLCBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSg1KX07CisgICAgICAgIFNTTEVuZ2luZSBzc2UgPSBnZXRFbmdpbmUoaG9zdCwgcG9ydCk7CisgICAgICAgIHNzZS5zZXRVc2VDbGllbnRNb2RlKHRydWUpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2Uud3JhcChiYkEsIGJiKTsKKyAgICAgICAgICAgIGZhaWwoIlJlYWRPbmx5QnVmZmVyRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24gaW9iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgUmVhZE9ubHlCdWZmZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lI3dyYXAoQnl0ZUJ1ZmZlcltdIHNyY3MsIEJ5dGVCdWZmZXIgZHN0KQorICAgICAqIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duLgorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIkZpeGVkIG9uIERvbnV0QnVyZ2VyLCBXcm9uZyBFeGNlcHRpb24gdGhyb3duIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyYXBfQnl0ZUJ1ZmZlciRCeXRlQnVmZmVyXzAzKCkgeworICAgICAgICBTdHJpbmcgaG9zdCA9ICJuZXcgaG9zdCI7CisgICAgICAgIGludCBwb3J0ID0gODA4MDsKKyAgICAgICAgQnl0ZUJ1ZmZlcltdIGJiQSA9IHtCeXRlQnVmZmVyLmFsbG9jYXRlKDEwMCksIEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApLCBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwMCl9OworICAgICAgICBCeXRlQnVmZmVyW10gYmJBTiA9IG51bGw7CisgICAgICAgIEJ5dGVCdWZmZXIgYmIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiTiA9IG51bGw7CisgICAgICAgIFNTTEVuZ2luZSBzc2UgPSBnZXRFbmdpbmUoaG9zdCwgcG9ydCk7CisgICAgICAgIHNzZS5zZXRVc2VDbGllbnRNb2RlKHRydWUpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2Uud3JhcChiYkEsIGJOKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpb2JlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLndyYXAoYmJBTiwgYmIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlvYmUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2Uud3JhcChiYkFOLCBiTik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaW9iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xFbmdpbmUjd3JhcChCeXRlQnVmZmVyW10gc3JjcywgQnl0ZUJ1ZmZlciBkc3QpCisgICAgICogSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24uCisgICAgICovCisgICAgQEFuZHJvaWRPbmx5KCJUaGUgUkkgZG9lc24ndCB0aHJvdyB0aGUgSWxsZWdhbFN0YXRlRXhjZXB0aW9uLiIpCisgICAgcHVibGljIHZvaWQgdGVzdF93cmFwX0J5dGVCdWZmZXIkQnl0ZUJ1ZmZlcl8wNCgpIHsKKyAgICAgICAgU3RyaW5nIGhvc3QgPSAibmV3IGhvc3QiOworICAgICAgICBpbnQgcG9ydCA9IDgwODA7CisgICAgICAgIEJ5dGVCdWZmZXIgYmIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKTsKKyAgICAgICAgQnl0ZUJ1ZmZlcltdIGJiQSA9IHsgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSg1KSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxMCksIEJ5dGVCdWZmZXIuYWxsb2NhdGUoNSkgfTsKKyAgICAgICAgU1NMRW5naW5lIHNzZSA9IGdldEVuZ2luZShob3N0LCBwb3J0KTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NlLndyYXAoYmJBLCBiYik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsU3RhdGVFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaW9iZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSN3cmFwKEJ5dGVCdWZmZXJbXSBzcmNzLCBCeXRlQnVmZmVyIGRzdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3dyYXBfQnl0ZUJ1ZmZlciRCeXRlQnVmZmVyXzA1KCkgeworICAgICAgICBTdHJpbmcgaG9zdCA9ICJuZXcgaG9zdCI7CisgICAgICAgIGludCBwb3J0ID0gODA4MDsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYiA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMTApOworICAgICAgICBCeXRlQnVmZmVyW10gYmJBID0geyBCeXRlQnVmZmVyLmFsbG9jYXRlKDUpLCBCeXRlQnVmZmVyLmFsbG9jYXRlKDEwKSwgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSg1KSB9OworICAgICAgICBTU0xFbmdpbmUgc3NlID0gZ2V0RW5naW5lKGhvc3QsIHBvcnQpOworICAgICAgICBzc2Uuc2V0VXNlQ2xpZW50TW9kZSh0cnVlKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0IHJlcyA9IHNzZS53cmFwKGJiQSwgYmIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHJlcy5ieXRlc0NvbnN1bWVkKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHJlcy5ieXRlc1Byb2R1Y2VkKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBTU0xFbmdpbmUgZ2V0RW5naW5lKCkgeworICAgICAgICBTU0xDb250ZXh0IGNvbnRleHQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29udGV4dCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UoIlRMUyIpOworICAgICAgICAgICAgY29udGV4dC5pbml0KG51bGwsIG51bGwsIG51bGwpOworICAgICAgICB9IGNhdGNoIChLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkNvdWxkIG5vdCBnZXQgU1NMRW5naW5lOiBrZXkgbWFuYWdlbWVudCBleGNlcHRpb24gIgorICAgICAgICAgICAgICAgICAgICArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIkNvdWxkIG5vdCBnZXQgU1NMRW5naW5lOiBubyBzdWNoIGFsZ29yaXRobSAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb250ZXh0LmNyZWF0ZVNTTEVuZ2luZSgpOworICAgIH0KKworICAgIHByaXZhdGUgU1NMRW5naW5lIGdldEVuZ2luZShTdHJpbmcgaG9zdCwgaW50IHBvcnQpIHsKKyAgICAgICAgU1NMQ29udGV4dCBjb250ZXh0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbnRleHQgPSBTU0xDb250ZXh0LmdldEluc3RhbmNlKCJUTFMiKTsKKyAgICAgICAgICAgIGNvbnRleHQuaW5pdChudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJDb3VsZCBub3QgZ2V0IFNTTEVuZ2luZToga2V5IG1hbmFnZW1lbnQgZXhjZXB0aW9uICIKKyAgICAgICAgICAgICAgICAgICAgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJDb3VsZCBub3QgZ2V0IFNTTEVuZ2luZTogbm8gc3VjaCBhbGdvcml0aG0gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29udGV4dC5jcmVhdGVTU0xFbmdpbmUoaG9zdCwgcG9ydCk7CisgICAgfQorCisgICAgY2xhc3MgSGFuZHNoYWtlSGFuZGxlciBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKworICAgICAgICBwcml2YXRlIGZpbmFsIFNTTEVuZ2luZSBlbmdpbmU7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTb3VyY2VDaGFubmVsIGluOworCisgICAgICAgIHByaXZhdGUgZmluYWwgU2lua0NoYW5uZWwgb3V0OworCisgICAgICAgIHByaXZhdGUgZmluYWwgQnl0ZUJ1ZmZlciBFTVBUWSA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMCk7CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIExPR1RBRzsKKworICAgICAgICBwcml2YXRlIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMgc3RhdHVzOworCisgICAgICAgIHByaXZhdGUgQnl0ZUJ1ZmZlciByZWFkQnVmZmVyOworCisgICAgICAgIHByaXZhdGUgQnl0ZUJ1ZmZlciB3cml0ZUJ1ZmZlcjsKKworICAgICAgICBIYW5kc2hha2VIYW5kbGVyKGJvb2xlYW4gY2xpZW50TW9kZSwgU291cmNlQ2hhbm5lbCBpbiwgU2lua0NoYW5uZWwgb3V0KQorICAgICAgICAgICAgICAgIHRocm93cyBTU0xFeGNlcHRpb24geworICAgICAgICAgICAgdGhpcy5pbiA9IGluOworICAgICAgICAgICAgdGhpcy5vdXQgPSBvdXQ7CisgICAgICAgICAgICBlbmdpbmUgPSBnZXRFbmdpbmUoKTsKKyAgICAgICAgICAgIGVuZ2luZS5zZXRVc2VDbGllbnRNb2RlKGNsaWVudE1vZGUpOworICAgICAgICAgICAgU3RyaW5nW10gY2lwaGVyU3VpdGVzID0gZW5naW5lLmdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpOworICAgICAgICAgICAgU2V0PFN0cmluZz4gZW5hYmxlZFN1aXRlcyA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIGNpcGhlclN1aXRlIDogY2lwaGVyU3VpdGVzKSB7CisgICAgICAgICAgICAgICAgaWYgKGNpcGhlclN1aXRlLmNvbnRhaW5zKCJhbm9uIikpIHsKKyAgICAgICAgICAgICAgICAgICAgZW5hYmxlZFN1aXRlcy5hZGQoY2lwaGVyU3VpdGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVuZ2luZS5zZXRFbmFibGVkQ2lwaGVyU3VpdGVzKChTdHJpbmdbXSkgZW5hYmxlZFN1aXRlcy50b0FycmF5KAorICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW2VuYWJsZWRTdWl0ZXMuc2l6ZSgpXSkpOworCisgICAgICAgICAgICBlbmdpbmUuYmVnaW5IYW5kc2hha2UoKTsKKyAgICAgICAgICAgIHN0YXR1cyA9IGVuZ2luZS5nZXRIYW5kc2hha2VTdGF0dXMoKTsKKworICAgICAgICAgICAgaWYgKGNsaWVudE1vZGUpIHsKKyAgICAgICAgICAgICAgICBMT0dUQUcgPSAiQ0xJRU5UOiAiOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBMT0dUQUcgPSAiU0VSVkVSOiAiOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBsb2coIkNpcGhlclN1aXRlczogIiArIEFycmF5cy50b1N0cmluZyhlbmdpbmUuZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpKSk7CisgICAgICAgICAgICBsb2coc3RhdHVzKTsKKworICAgICAgICAgICAgcmVhZEJ1ZmZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMjAwMDAwKTsKKyAgICAgICAgICAgIHdyaXRlQnVmZmVyID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgyMDAwMCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cyBnZXRTdGF0dXMoKSB7CisgICAgICAgICAgICByZXR1cm4gc3RhdHVzOworICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSB2b2lkIGxvZyhPYmplY3QgbykgeworICAgICAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50KExPR1RBRyk7CisgICAgICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbihvKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgQnl0ZUJ1ZmZlciByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChyZWFkQnVmZmVyID09IG51bGwgfHwgcmVhZEJ1ZmZlci5yZW1haW5pbmcoKSA9PSAwIHx8IHJlYWRCdWZmZXIucG9zaXRpb24oKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgcmVhZEJ1ZmZlci5jbGVhcigpOworICAgICAgICAgICAgICAgIGludCByZWFkID0gaW4ucmVhZChyZWFkQnVmZmVyKTsKKyAgICAgICAgICAgICAgICBsb2coInJlYWQ6ICIgKyByZWFkKTsKKyAgICAgICAgICAgICAgICByZWFkQnVmZmVyLnJld2luZCgpOworICAgICAgICAgICAgICAgIHJlYWRCdWZmZXIubGltaXQocmVhZCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVhZEJ1ZmZlcjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChzdGF0dXMpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRklOSVNIRUQ6IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2coc3RhdHVzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5FRURfVEFTSzogeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZyhzdGF0dXMpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJ1bm5hYmxlIHRhc2s7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCh0YXNrID0gZW5naW5lLmdldERlbGVnYXRlZFRhc2soKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXNrLnJ1bigpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBlbmdpbmUuZ2V0SGFuZHNoYWtlU3RhdHVzKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5FRURfVU5XUkFQOiB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nKHN0YXR1cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnl0ZUJ1ZmZlciBzb3VyY2UgPSByZWFkKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVCdWZmZXIuY2xlYXIoKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdGF0dXMgPT0gSGFuZHNoYWtlU3RhdHVzLk5FRURfVU5XUkFQKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTEVuZ2luZVJlc3VsdCByZXN1bHQgPSBlbmdpbmUudW53cmFwKHNvdXJjZSwgd3JpdGVCdWZmZXIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSByZXN1bHQuZ2V0SGFuZHNoYWtlU3RhdHVzKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZyhyZXN1bHQpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTkVFRF9XUkFQOiB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nKHN0YXR1cyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVCdWZmZXIuY2xlYXIoKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBwcm9kdWNlZCA9IDA7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0IHJlc3VsdCA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN0YXR1cyA9PSBIYW5kc2hha2VTdGF0dXMuTkVFRF9XUkFQKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGVuZ2luZS53cmFwKEVNUFRZLCB3cml0ZUJ1ZmZlcik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IHJlc3VsdC5nZXRIYW5kc2hha2VTdGF0dXMoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZHVjZWQgKz0gcmVzdWx0LmJ5dGVzUHJvZHVjZWQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nKHJlc3VsdCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlQnVmZmVyLnJld2luZCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlQnVmZmVyLmxpbWl0KHByb2R1Y2VkKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2coIndyaXRlOiAiICsgcHJvZHVjZWQpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dC53cml0ZSh3cml0ZUJ1ZmZlcik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5PVF9IQU5EU0hBS0lORzogeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZygiTm90IEhhbmRzaGFraW5nIik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGxvZyhlKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGlnbm9yZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBLbm93bkZhaWx1cmUoIkhhbmRzaGFrZSBTdGF0dXMgaXMgbmV2ZXIgZmluaXNoZWQuIE5QRSBpbiAiCisgICAgICAgICAgICArICJDbGllbnRTZXNzaW9uQ29udGV4dCRIb3N0QW5kUG9ydC5oYXNoQ29kZSgpIHdoZW4gaG9zdCBpcyBudWxsIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFuZHNoYWtlKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisKKyAgICAgICAgcHJlcGFyZUVuZ2luZXMoKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJoYW5kc2hha2UgZmFpbGVkIiwgZG9IYW5kc2hha2UoKSk7CisKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGNsaWVudEVuZ2luZS5lbmdpbmUuZ2V0U2Vzc2lvbigpLmdldENpcGhlclN1aXRlKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiSGFuZHNoYWtlIG5vdCBmaW5pc2hlZCIsCisgICAgICAgICAgICAgICAgU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cy5GSU5JU0hFRCwKKyAgICAgICAgICAgICAgICBjbGllbnRFbmdpbmUuZ2V0U3RhdHVzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkhhbmRzaGFrZSBub3QgZmluaXNoZWQiLAorICAgICAgICAgICAgICAgIFNTTEVuZ2luZVJlc3VsdC5IYW5kc2hha2VTdGF0dXMuRklOSVNIRUQsCisgICAgICAgICAgICAgICAgc2VydmVyRW5naW5lLmdldFN0YXR1cygpKTsKKyAgICB9CisKKyAgICB2b2lkIHByZXBhcmVFbmdpbmVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUGlwZSBjbGllbnRTZW5kUGlwZSA9IFBpcGUub3BlbigpOworICAgICAgICBQaXBlIHNlcnZlclNlbmRQaXBlID0gUGlwZS5vcGVuKCk7CisKKyAgICAgICAgU2lua0NoYW5uZWwgY2xpZW50U2luayA9IGNsaWVudFNlbmRQaXBlLnNpbmsoKTsKKyAgICAgICAgU291cmNlQ2hhbm5lbCBzZXJ2ZXJTb3VyY2UgPSBjbGllbnRTZW5kUGlwZS5zb3VyY2UoKTsKKyAgICAgICAgU2lua0NoYW5uZWwgc2VydmVyU2luayA9IHNlcnZlclNlbmRQaXBlLnNpbmsoKTsKKyAgICAgICAgU291cmNlQ2hhbm5lbCBjbGllbnRTb3VyY2UgPSBzZXJ2ZXJTZW5kUGlwZS5zb3VyY2UoKTsKKworICAgICAgICBjbGllbnRFbmdpbmUgPSBuZXcgSGFuZHNoYWtlSGFuZGxlcih0cnVlLCBjbGllbnRTb3VyY2UsIGNsaWVudFNpbmspOworICAgICAgICBzZXJ2ZXJFbmdpbmUgPSBuZXcgSGFuZHNoYWtlSGFuZGxlcihmYWxzZSwgc2VydmVyU291cmNlLCBzZXJ2ZXJTaW5rKTsKKyAgICB9CisKKyAgICBib29sZWFuIGRvSGFuZHNoYWtlKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgVGhyZWFkIGNsaWVudFRocmVhZCA9IG5ldyBUaHJlYWQoY2xpZW50RW5naW5lKTsKKyAgICAgICAgY2xpZW50VGhyZWFkLnN0YXJ0KCk7CisKKyAgICAgICAgVGhyZWFkIHNlcnZlclRocmVhZCA9IG5ldyBUaHJlYWQoc2VydmVyRW5naW5lKTsKKyAgICAgICAgc2VydmVyVGhyZWFkLnN0YXJ0KCk7CisKKyAgICAgICAgaW50IGkgPSAwOworICAgICAgICB3aGlsZSAoY2xpZW50VGhyZWFkLmlzQWxpdmUoKSAmJiBzZXJ2ZXJUaHJlYWQuaXNBbGl2ZSgpICYmIGkgPCAyMCkgeworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDUwMCk7CisgICAgICAgICAgICBpKys7CisgICAgICAgIH0KKworICAgICAgICBpZiAoY2xpZW50VGhyZWFkLmlzQWxpdmUoKSkgeworICAgICAgICAgICAgY2xpZW50VGhyZWFkLmludGVycnVwdCgpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHNlcnZlclRocmVhZC5pc0FsaXZlKCkpIHsKKyAgICAgICAgICAgIHNlcnZlclRocmVhZC5pbnRlcnJ1cHQoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjbGllbnRFbmdpbmUuZ2V0U3RhdHVzKCkgPT0gSGFuZHNoYWtlU3RhdHVzLkZJTklTSEVEICYmIHNlcnZlckVuZ2luZS5nZXRTdGF0dXMoKSA9PSBIYW5kc2hha2VTdGF0dXMuRklOSVNIRUQ7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1NTTEV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YjRhZTM1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1NTTEV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDE1OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMRXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5TU0xFeGNlcHRpb248L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBTU0xFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gbXNncyA9IHsKKyAgICAgICAgICAgICIiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSIgfTsKKworICAgIHByaXZhdGUgc3RhdGljIFRocm93YWJsZSB0Q2F1c2UgPSBuZXcgVGhyb3dhYmxlKCJUaHJvd2FibGUgZm9yIGV4Y2VwdGlvbiIpOworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+U1NMRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yIEFzc2VydGlvbjoKKyAgICAgKiBjb25zdHJ1Y3RzIFNTTEV4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4gUGFyYW1ldGVyCisgICAgICogPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U1NMRXhjZXB0aW9uMDEoKSB7CisgICAgICAgIFNTTEV4Y2VwdGlvbiBzRTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBzRSA9IG5ldyBTU0xFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHNFLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCBzRS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPlNTTEV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246CisgICAgICogY29uc3RydWN0cyBTU0xFeGNlcHRpb24gd2hlbiA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U1NMRXhjZXB0aW9uMDIoKSB7CisgICAgICAgIFN0cmluZyBtc2cgPSBudWxsOworICAgICAgICBTU0xFeGNlcHRpb24gc0UgPSBuZXcgU1NMRXhjZXB0aW9uKG1zZyk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHNFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHNFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPlNTTEV4Y2VwdGlvbihUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBTU0xFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTU0xFeGNlcHRpb24wMygpIHsKKyAgICAgICAgVGhyb3dhYmxlIGNhdXNlID0gbnVsbDsKKyAgICAgICAgU1NMRXhjZXB0aW9uIHNFID0gbmV3IFNTTEV4Y2VwdGlvbihjYXVzZSk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHNFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHNFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPlNTTEV4Y2VwdGlvbihUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBTU0xFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90CisgICAgICogbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTU0xFeGNlcHRpb24wNCgpIHsKKyAgICAgICAgU1NMRXhjZXB0aW9uIHNFID0gbmV3IFNTTEV4Y2VwdGlvbih0Q2F1c2UpOworICAgICAgICBpZiAoc0UuZ2V0TWVzc2FnZSgpICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIFN0cmluZyBnZXRNID0gc0UuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIHNob3VsZCBjb250YWluICIuY29uY2F0KHRvUyksIChnZXRNCisgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKHRvUykgIT0gLTEpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgc0UuZ2V0Q2F1c2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiAiLmNvbmNhdCh0Q2F1c2UudG9TdHJpbmcoKSksIHNFLmdldENhdXNlKCksIHRDYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+U1NMRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgU1NMRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwKKyAgICAgKiA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U1NMRXhjZXB0aW9uMDUoKSB7CisgICAgICAgIFNTTEV4Y2VwdGlvbiBzRSA9IG5ldyBTU0xFeGNlcHRpb24obnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsIiwgc0UuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgc0UuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+U1NMRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgU1NMRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwKKyAgICAgKiA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNTTEV4Y2VwdGlvbjA2KCkgeworICAgICAgICBTU0xFeGNlcHRpb24gc0U7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc0UgPSBuZXcgU1NMRXhjZXB0aW9uKG1zZ3NbaV0sIG51bGwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm46ICIuY29uY2F0KG1zZ3NbaV0pLCBzRQorICAgICAgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZSgpLCBtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHNFLmdldENhdXNlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+U1NMRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgU1NMRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdAorICAgICAqIG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNTTEV4Y2VwdGlvbjA3KCkgeworICAgICAgICBTU0xFeGNlcHRpb24gc0UgPSBuZXcgU1NMRXhjZXB0aW9uKG51bGwsIHRDYXVzZSk7CisgICAgICAgIGlmIChzRS5nZXRNZXNzYWdlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSBzRS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgbXVzdCBzaG91bGQgIi5jb25jYXQodG9TKSwgKGdldE0KKyAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCBzRS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwgc0UKKyAgICAgICAgICAgICAgICAuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5TU0xFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBTU0xFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90CisgICAgICogbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNTTEV4Y2VwdGlvbjA4KCkgeworICAgICAgICBTU0xFeGNlcHRpb24gc0U7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc0UgPSBuZXcgU1NMRXhjZXB0aW9uKG1zZ3NbaV0sIHRDYXVzZSk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHNFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGlmIChtc2dzW2ldLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IGNvbnRhaW4gIi5jb25jYXQobXNnc1tpXSksIGdldE0KKyAgICAgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKG1zZ3NbaV0pICE9IC0xKTsKKyAgICAgICAgICAgICAgICBpZiAoIWdldE0uZXF1YWxzKG1zZ3NbaV0pKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBzaG91bGQgY29udGFpbiAiLmNvbmNhdCh0b1MpLCBnZXRNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHNFLmdldENhdXNlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwKKyAgICAgICAgICAgICAgICAgICAgc0UuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xIYW5kc2hha2VFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMSGFuZHNoYWtlRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEyZDBlYzUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMSGFuZHNoYWtlRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xIYW5kc2hha2VFeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBTU0xIYW5kc2hha2VFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gbXNncyA9IHsKKyAgICAgICAgICAgICIiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSIgfTsKKworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+U1NMSGFuZHNoYWtlRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yIEFzc2VydGlvbjoKKyAgICAgKiBjb25zdHJ1Y3RzIFNTTEhhbmRzaGFrZUV4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4gUGFyYW1ldGVyCisgICAgICogPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yMDEoKSB7CisgICAgICAgIFNTTEhhbmRzaGFrZUV4Y2VwdGlvbiBzc2xFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHNzbEUgPSBuZXcgU1NMSGFuZHNoYWtlRXhjZXB0aW9uKG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm46ICIuY29uY2F0KG1zZ3NbaV0pLCBzc2xFLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCBzc2xFLmdldENhdXNlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+U1NMSGFuZHNoYWtlRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yIEFzc2VydGlvbjoKKyAgICAgKiBjb25zdHJ1Y3RzIFNTTEhhbmRzaGFrZUV4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4gUGFyYW1ldGVyCisgICAgICogPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IwMigpIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9IG51bGw7CisgICAgICAgIFNTTEhhbmRzaGFrZUV4Y2VwdGlvbiBzc2xFID0gbmV3IFNTTEhhbmRzaGFrZUV4Y2VwdGlvbihtc2cpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCBzc2xFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHNzbEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1NTTEtleUV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xLZXlFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDZiYTk5OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xLZXlFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw1NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEtleUV4Y2VwdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIFNTTEtleUV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5TU0xLZXlFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgU1NMS2V5RXhjZXB0aW9uIHdpdGggZGV0YWlsIG1lc3NhZ2UgbXNnLiBQYXJhbWV0ZXIKKyAgICAgKiA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IwMSgpIHsKKyAgICAgICAgU1NMS2V5RXhjZXB0aW9uIHNrRTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBza0UgPSBuZXcgU1NMS2V5RXhjZXB0aW9uKG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm46ICIuY29uY2F0KG1zZ3NbaV0pLCBza0UuZ2V0TWVzc2FnZSgpLCBtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHNrRS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPlNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yIEFzc2VydGlvbjoKKyAgICAgKiBjb25zdHJ1Y3RzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIHdpdGggZGV0YWlsIG1lc3NhZ2UgbXNnLiBQYXJhbWV0ZXIKKyAgICAgKiA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcjAyKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICAgICAgU1NMS2V5RXhjZXB0aW9uIHNrRSA9IG5ldyBTU0xLZXlFeGNlcHRpb24obXNnKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgc2tFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHNrRS5nZXRDYXVzZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYThiOWFjNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDU1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5TU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246CisgICAgICogY29uc3RydWN0cyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4gUGFyYW1ldGVyCisgICAgICogPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yMDEoKSB7CisgICAgICAgIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIHNzbEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc3NsRSA9IG5ldyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbihtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgc3NsRS5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgc3NsRS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPlNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yIEFzc2VydGlvbjoKKyAgICAgKiBjb25zdHJ1Y3RzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIHdpdGggZGV0YWlsIG1lc3NhZ2UgbXNnLiBQYXJhbWV0ZXIKKyAgICAgKiA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcjAyKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICAgICAgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24gc3NsRSA9IG5ldyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbihtc2cpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCBzc2xFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHNzbEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1NTTFByb3RvY29sRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1NTTFByb3RvY29sRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE0YjU2MmQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMUHJvdG9jb2xFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw1NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFByb3RvY29sRXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgU1NMUHJvdG9jb2xFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gbXNncyA9IHsKKyAgICAgICAgICAgICIiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSIgfTsKKworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+U1NMUHJvdG9jb2xFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgU1NMUHJvdG9jb2xFeGNlcHRpb24gd2l0aCBkZXRhaWwgbWVzc2FnZSBtc2cuIFBhcmFtZXRlcgorICAgICAqIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcjAxKCkgeworICAgICAgICBTU0xQcm90b2NvbEV4Y2VwdGlvbiBzc2xFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHNzbEUgPSBuZXcgU1NMUHJvdG9jb2xFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHNzbEUuZ2V0TWVzc2FnZSgpLCBtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHNzbEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5TU0xQcm90b2NvbEV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246CisgICAgICogY29uc3RydWN0cyBTU0xQcm90b2NvbEV4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4gUGFyYW1ldGVyCisgICAgICogPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IwMigpIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9IG51bGw7CisgICAgICAgIFNTTFByb3RvY29sRXhjZXB0aW9uIHNzbEUgPSBuZXcgU1NMUHJvdG9jb2xFeGNlcHRpb24obXNnKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgc3NsRS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCBzc2xFLmdldENhdXNlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1NTTFNlcnZlclNvY2tldEZhY3RvcnlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTk1OGVjYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5TZXJ2ZXJTb2NrZXQ7CisKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldEZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBTU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgY2xhc3MgTW9ja1NTTFNlcnZlclNvY2tldEZhY3RvcnkgZXh0ZW5kcyBTU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5IHsKKyAgICAgICAgcHVibGljIE1vY2tTU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5KCkgeworICAgICAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU2VydmVyU29ja2V0IGNyZWF0ZVNlcnZlclNvY2tldChpbnQgYXJnMCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTZXJ2ZXJTb2NrZXQgY3JlYXRlU2VydmVyU29ja2V0KGludCBhcmcwLCBpbnQgYXJnMSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFNlcnZlclNvY2tldCBjcmVhdGVTZXJ2ZXJTb2NrZXQoaW50IGFyZzAsIGludCBhcmcxLAorICAgICAgICAgICAgICAgIEluZXRBZGRyZXNzIGFyZzIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0RmFjdG9yeSNTU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgTW9ja1NTTFNlcnZlclNvY2tldEZhY3Rvcnkgc3NmID0gbmV3IE1vY2tTU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5KCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0RmFjdG9yeSNnZXREZWZhdWx0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERlZmF1bHQoKSB7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkluY29ycmVjdCBkZWZhdWx0IHNvY2tldCBmYWN0b3J5IiwKKyAgICAgICAgICAgICAgICBTU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5I2dldERlZmF1bHRDaXBoZXJTdWl0ZXMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgU1NMU2VydmVyU29ja2V0RmFjdG9yeSBzc2YgPSAoU1NMU2VydmVyU29ja2V0RmFjdG9yeSkgU1NMU2VydmVyU29ja2V0RmFjdG9yeQorICAgICAgICAgICAgICAgIC5nZXREZWZhdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHNzZi5nZXREZWZhdWx0Q2lwaGVyU3VpdGVzKCkubGVuZ3RoID4gMCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldEZhY3RvcnkjZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFN1cHBvcnRlZENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgU1NMU2VydmVyU29ja2V0RmFjdG9yeSBzc2YgPSAoU1NMU2VydmVyU29ja2V0RmFjdG9yeSkgU1NMU2VydmVyU29ja2V0RmFjdG9yeQorICAgICAgICAgICAgICAgIC5nZXREZWZhdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHNzZi5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKS5sZW5ndGggPiAwKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xTZXJ2ZXJTb2NrZXRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMU2VydmVyU29ja2V0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjOTY3ODIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMU2VydmVyU29ja2V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsNDgyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgbGliY29yZS5pby5CYXNlNjQ7CisKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfUG9ydE1hbmFnZXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleU1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyRmFjdG9yeTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTENvbnRleHQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXQ7CisKK3B1YmxpYyBjbGFzcyBTU0xTZXJ2ZXJTb2NrZXRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLy8gc2V0IHRvIHRydWUgaWYgb24gQW5kcm9pZCwgZmFsc2UgaWYgb24gUkkKKyAgICBib29sZWFuIHVzZUJLUyA9IHRydWU7CisKKyAgICAvKioKKyAgICAgKiBBZGRpdGlvbmFsIGNsYXNzIGZvciBTU0xTZXJ2ZXJTb2NrZXQgY29uc3RydWN0b3IgdmVyaWZpY2F0aW9uCisgICAgICovCisgICAgY2xhc3MgbXlTU0xTZXJ2ZXJTb2NrZXQgZXh0ZW5kcyBTU0xTZXJ2ZXJTb2NrZXQgeworCisgICAgICAgIHB1YmxpYyBteVNTTFNlcnZlclNvY2tldCgpIHRocm93cyBJT0V4Y2VwdGlvbnsKKyAgICAgICAgICAgIHN1cGVyKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgbXlTU0xTZXJ2ZXJTb2NrZXQoaW50IHBvcnQpIHRocm93cyBJT0V4Y2VwdGlvbnsKKyAgICAgICAgICAgIHN1cGVyKHBvcnQpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIG15U1NMU2VydmVyU29ja2V0KGludCBwb3J0LCBpbnQgYmFja2xvZykgdGhyb3dzIElPRXhjZXB0aW9ueworICAgICAgICAgICAgc3VwZXIocG9ydCwgYmFja2xvZyk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgbXlTU0xTZXJ2ZXJTb2NrZXQoaW50IHBvcnQsIGludCBiYWNrbG9nLCBJbmV0QWRkcmVzcyBhZGRyZXNzKSB0aHJvd3MgSU9FeGNlcHRpb257CisgICAgICAgICAgICBzdXBlcihwb3J0LCBiYWNrbG9nLCBhZGRyZXNzKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoU3RyaW5nW10gc3VpdGVzKSB7CisKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nW10gZ2V0U3VwcG9ydGVkUHJvdG9jb2xzKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RW5hYmxlZFByb3RvY29scygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0RW5hYmxlZFByb3RvY29scyhTdHJpbmdbXSBwcm90b2NvbHMpIHsKKworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKGJvb2xlYW4gZmxhZykgeworCisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBnZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXROZWVkQ2xpZW50QXV0aChib29sZWFuIG5lZWQpIHsKKworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZ2V0TmVlZENsaWVudEF1dGgoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBnZXRVc2VDbGllbnRNb2RlKCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0VXNlQ2xpZW50TW9kZShib29sZWFuIG1vZGUpIHsKKworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZ2V0V2FudENsaWVudEF1dGgoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIHZvaWQgc2V0V2FudENsaWVudEF1dGgoYm9vbGVhbiBtb2RlKSB7CisKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0I1NTTFNlcnZlclNvY2tldCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdG9yXzAxKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMU2VydmVyU29ja2V0IHNzbCA9IG5ldyBteVNTTFNlcnZlclNvY2tldCgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIHdhcyB0aHJvd24gIiArIGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0I1NTTFNlcnZlclNvY2tldChpbnQgcG9ydCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RydWN0b3JfMDIoKSB7CisgICAgICAgIFNTTFNlcnZlclNvY2tldCBzc2w7CisgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICBpbnRbXSBwb3J0X2ludmFsaWQgPSB7LTEsIDY1NTM2LCBJbnRlZ2VyLk1JTl9WQUxVRSwgSW50ZWdlci5NQVhfVkFMVUV9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2wgPSBuZXcgbXlTU0xTZXJ2ZXJTb2NrZXQocG9ydE51bWJlcik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMocG9ydE51bWJlciwgc3NsLmdldExvY2FsUG9ydCgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiB3YXMgdGhyb3duICIgKyBleCk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBvcnRfaW52YWxpZC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzc2wgPSBuZXcgbXlTU0xTZXJ2ZXJTb2NrZXQocG9ydF9pbnZhbGlkW2ldKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NsID0gbmV3IG15U1NMU2VydmVyU29ja2V0KHBvcnROdW1iZXIpOworICAgICAgICAgICAgbmV3IG15U1NMU2VydmVyU29ja2V0KHBvcnROdW1iZXIpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gRXhwZWN0ZWQgd2hlbiBvcGVuaW5nIGFuIGFscmVhZHkgb3BlbmVkIHBvcnQiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIHdhcyB0aHJvd24gIiArIGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0I1NTTFNlcnZlclNvY2tldChpbnQgcG9ydCwgaW50IGJhY2tsb2cpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdG9yXzAzKCkgeworICAgICAgICBteVNTTFNlcnZlclNvY2tldCBzc2w7CisgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICBpbnRbXSBwb3J0X2ludmFsaWQgPSB7LTEsIEludGVnZXIuTUlOX1ZBTFVFLCBJbnRlZ2VyLk1BWF9WQUxVRX07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzbCA9IG5ldyBteVNTTFNlcnZlclNvY2tldChwb3J0TnVtYmVyLCAxKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhwb3J0TnVtYmVyLCBzc2wuZ2V0TG9jYWxQb3J0KCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIHdhcyB0aHJvd24iKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcG9ydF9pbnZhbGlkLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHNzbCA9IG5ldyBteVNTTFNlcnZlclNvY2tldChwb3J0X2ludmFsaWRbaV0sIDEpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NsID0gbmV3IG15U1NMU2VydmVyU29ja2V0KHBvcnROdW1iZXIsIDEpOworICAgICAgICAgICAgbmV3IG15U1NMU2VydmVyU29ja2V0KHBvcnROdW1iZXIsIDEpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0I1NTTFNlcnZlclNvY2tldChpbnQgcG9ydCwgaW50IGJhY2tsb2csIEluZXRBZGRyZXNzIGFkZHJlc3MpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdG9yXzA0KCkgeworICAgICAgICBteVNTTFNlcnZlclNvY2tldCBzc2w7CisgICAgICAgIEluZXRBZGRyZXNzIGlhID0gbnVsbDsKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgIGludFtdIHBvcnRfaW52YWxpZCA9IHstMSwgNjU1MzYsIEludGVnZXIuTUlOX1ZBTFVFLCBJbnRlZ2VyLk1BWF9WQUxVRX07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzbCA9IG5ldyBteVNTTFNlcnZlclNvY2tldChwb3J0TnVtYmVyLCAwLCBpYSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMocG9ydE51bWJlciwgc3NsLmdldExvY2FsUG9ydCgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgIH0KKworICAgICAgICBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NsID0gbmV3IG15U1NMU2VydmVyU29ja2V0KHBvcnROdW1iZXIsIDAsIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhwb3J0TnVtYmVyLCBzc2wuZ2V0TG9jYWxQb3J0KCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIHdhcyB0aHJvd24iKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcG9ydF9pbnZhbGlkLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHNzbCA9IG5ldyBteVNTTFNlcnZlclNvY2tldChwb3J0X2ludmFsaWRbaV0sIDEsIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgc3NsID0gbmV3IG15U1NMU2VydmVyU29ja2V0KHBvcnROdW1iZXIsIDAsIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpKTsKKyAgICAgICAgICAgbmV3IG15U1NMU2VydmVyU29ja2V0KHBvcnROdW1iZXIsIDAsIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpKTsKKyAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biBmb3IiKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0I2dldFN1cHBvcnRlZENpcGhlclN1aXRlcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMU2VydmVyU29ja2V0IHNzcyA9IGdldFNTTFNlcnZlclNvY2tldCgpOworICAgICAgICBTdHJpbmdbXSByZXMgPSBzc3MuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIk5VTEwgcmVzdWx0IiwgcmVzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibm8gc3VwcG9ydGVkIGNpcGhlciBzdWl0ZXMgYXZhaWxhYmxlLiIsIHJlcy5sZW5ndGggPiAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXQjZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXQjc2V0RW5hYmxlZENpcGhlclN1aXRlcyhTdHJpbmdbXSBzdWl0ZXMpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9FbmFibGVkQ2lwaGVyU3VpdGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNTTFNlcnZlclNvY2tldCBzc3MgPSBnZXRTU0xTZXJ2ZXJTb2NrZXQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzcy5zZXRFbmFibGVkQ2lwaGVyU3VpdGVzKG51bGwpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nW10gdW5zdXBwb3J0ZWRDaXBoZXJTdWl0ZXMgPSB7InVuc3VwcG9ydGVkIn07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc3Muc2V0RW5hYmxlZENpcGhlclN1aXRlcyh1bnN1cHBvcnRlZENpcGhlclN1aXRlcyk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBpbnQgY291bnQgPSBzc3MuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkubGVuZ3RoOworICAgICAgICBhc3NlcnRUcnVlKCJObyBzdXBwb3J0ZWQgY2lwaGVyIHN1aXRlcyIsIGNvdW50ID4gMCk7CisgICAgICAgIHNzcy5zZXRFbmFibGVkQ2lwaGVyU3VpdGVzKHNzcy5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSk7CisgICAgICAgIFN0cmluZ1tdIHJlcyA9IHNzcy5nZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIk5VTEwgcmVzdWx0IiwgcmVzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub3QgYWxsIHN1cHBvcnRlZCBjaXBoZXIgc3VpdGVzIHdlcmUgZW5hYmxlZCIsCisgICAgICAgICAgICAgICAgICAgICBBcnJheXMuYXNMaXN0KHNzcy5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSksCisgICAgICAgICAgICAgICAgICAgICBBcnJheXMuYXNMaXN0KHJlcykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldCNnZXRTdXBwb3J0ZWRQcm90b2NvbHMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0U3VwcG9ydGVkUHJvdG9jb2xzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNTTFNlcnZlclNvY2tldCBzc3MgPSBnZXRTU0xTZXJ2ZXJTb2NrZXQoKTsKKyAgICAgICAgU3RyaW5nW10gcmVzID0gc3NzLmdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJOVUxMIHJlc3VsdCIsIHJlcyk7CisgICAgICAgIGFzc2VydFRydWUoIm5vIHN1cHBvcnRlZCBwcm90b2NvbHMgYXZhaWxhYmxlLiIsIHJlcy5sZW5ndGggPiAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXQjZ2V0RW5hYmxlZFByb3RvY29scygpCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXQjc2V0RW5hYmxlZFByb3RvY29scyhTdHJpbmdbXSBwcm90b2NvbHMpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9FbmFibGVkUHJvdG9jb2xzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNTTFNlcnZlclNvY2tldCBzc3MgPSBnZXRTU0xTZXJ2ZXJTb2NrZXQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzcy5zZXRFbmFibGVkUHJvdG9jb2xzKG51bGwpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nW10gdW5zdXBwb3J0ZWRQcm90b2NvbHMgPSB7InVuc3VwcG9ydGVkIn07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc3Muc2V0RW5hYmxlZFByb3RvY29scyh1bnN1cHBvcnRlZFByb3RvY29scyk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICBpbnQgY291bnQgPSBzc3MuZ2V0U3VwcG9ydGVkUHJvdG9jb2xzKCkubGVuZ3RoOworICAgICAgICBhc3NlcnRUcnVlKCJObyBzdXBwb3J0ZWQgcHJvdG9jb2xzIiwgY291bnQgPiAwKTsKKyAgICAgICAgc3NzLnNldEVuYWJsZWRQcm90b2NvbHMoc3NzLmdldFN1cHBvcnRlZFByb3RvY29scygpKTsKKyAgICAgICAgU3RyaW5nW10gcmVzID0gc3NzLmdldEVuYWJsZWRQcm90b2NvbHMoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTlVMTCByZXN1bHQiLCByZXMpOworICAgICAgICBhc3NlcnRUcnVlKCJubyBlbmFibGVkIHByb3RvY29scy4iLCByZXMubGVuZ3RoID09IGNvdW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXQjc2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKGJvb2xlYW4gZmxhZykKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldCNnZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfRW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNTTFNlcnZlclNvY2tldCBzc3MgPSBnZXRTU0xTZXJ2ZXJTb2NrZXQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzc3MuZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCkpOworICAgICAgICBzc3Muc2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc3NzLmdldEVuYWJsZVNlc3Npb25DcmVhdGlvbigpKTsKKyAgICAgICAgc3NzLnNldEVuYWJsZVNlc3Npb25DcmVhdGlvbih0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzc3MuZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldCNzZXROZWVkQ2xpZW50QXV0aChib29sZWFuIG5lZWQpCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXQjZ2V0TmVlZENsaWVudEF1dGhDcmVhdGlvbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9OZWVkQ2xpZW50QXV0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTU0xTZXJ2ZXJTb2NrZXQgc3NzID0gZ2V0U1NMU2VydmVyU29ja2V0KCk7CisgICAgICAgIHNzcy5zZXROZWVkQ2xpZW50QXV0aCh0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzc3MuZ2V0TmVlZENsaWVudEF1dGgoKSk7CisgICAgICAgIHNzcy5zZXROZWVkQ2xpZW50QXV0aChmYWxzZSk7CisgICAgICAgIGFzc2VydEZhbHNlKHNzcy5nZXROZWVkQ2xpZW50QXV0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXQjZ2V0VXNlQ2xpZW50TW9kZSgpCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXQjc2V0VXNlQ2xpZW50TW9kZShib29sZWFuIG1vZGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Vc2VDbGllbnRNb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNTTFNlcnZlclNvY2tldCBzc3MgPSBnZXRTU0xTZXJ2ZXJTb2NrZXQoKTsKKyAgICAgICAgc3NzLnNldFVzZUNsaWVudE1vZGUoZmFsc2UpOworICAgICAgICBhc3NlcnRGYWxzZShzc3MuZ2V0VXNlQ2xpZW50TW9kZSgpKTsKKyAgICAgICAgc3NzLnNldFVzZUNsaWVudE1vZGUodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoc3NzLmdldFVzZUNsaWVudE1vZGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0I3NldFdhbnRDbGllbnRBdXRoKGJvb2xlYW4gd2FudCkKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldCNnZXRXYW50Q2xpZW50QXV0aENyZWF0aW9uKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1dhbnRDbGllbnRBdXRoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFNTTFNlcnZlclNvY2tldCBzc3MgPSBnZXRTU0xTZXJ2ZXJTb2NrZXQoKTsKKyAgICAgICAgc3NzLnNldFdhbnRDbGllbnRBdXRoKHRydWUpOworICAgICAgICBhc3NlcnRUcnVlKHNzcy5nZXRXYW50Q2xpZW50QXV0aCgpKTsKKyAgICAgICAgc3NzLnNldFdhbnRDbGllbnRBdXRoKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc3NzLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUga2V5c3RvcmUgY29udGVudHMgZm9yIHRoZSBzZXJ2ZXIsIEJLUyB2ZXJzaW9uLiBIb2xkcyBqdXN0IGEKKyAgICAgKiBzaW5nbGUgc2VsZi1nZW5lcmF0ZWQga2V5LiBUaGUgc3ViamVjdCBuYW1lIGlzICJUZXN0IFNlcnZlciIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNFUlZFUl9LRVlTX0JLUyA9CisgICAgICAgICJBQUFBQVFBQUFCUURrZWJ6b1AxWHdxeVdLUkNKRXBuL3Q4ZHFJUUFBQkRrRUFBVnRlV3RsZVFBQUFScFlsMjBuQUFBQUFRQUZXQzQxIiArCisgICAgICAgICJNRGtBQUFKTk1JSUNTVENDQWJLZ0F3SUJBZ0lFU0VmVTFqQU5CZ2txaGtpRzl3MEJBUVVGQURCcE1Rc3dDUVlEVlFRR0V3SlZVekVUIiArCisgICAgICAgICJNQkVHQTFVRUNCTUtRMkZzYVdadmNtNXBZVEVNTUFvR0ExVUVCeE1EVFZSV01ROHdEUVlEVlFRS0V3WkhiMjluYkdVeEVEQU9CZ05WIiArCisgICAgICAgICJCQXNUQjBGdVpISnZhV1F4RkRBU0JnTlZCQU1UQzFSbGMzUWdVMlZ5ZG1WeU1CNFhEVEE0TURZd05URXhOVGd4TkZvWERUQTRNRGt3IiArCisgICAgICAgICJNekV4TlRneE5Gb3dhVEVMTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhEREFLQmdOVkJBY1RBMDFVIiArCisgICAgICAgICJWakVQTUEwR0ExVUVDaE1HUjI5dloyeGxNUkF3RGdZRFZRUUxFd2RCYm1SeWIybGtNUlF3RWdZRFZRUURFd3RVWlhOMElGTmxjblpsIiArCisgICAgICAgICJjakNCbnpBTkJna3Foa2lHOXcwQkFRRUZBQU9CalFBd2dZa0NnWUVBMExJZEthSXI5L3ZzVHE4QlpsQTNSK05GV1JhSDRsR3NUQVF5IiArCisgICAgICAgICJEUE1GOVpxRURPYUw2REp1dTBjb2xTQkJCUTg1aFFUUGE5bTlueUpvTjNwRWkxaGdhbXFPdlFJV2NYQmsrU09wVUdSWlpGWHduaUpWIiArCisgICAgICAgICJ6REtVNW5FOU1ZZ24yQjlBb2lIM0NTdU16NkhScWdWYXF0cHBJZTFqaHVrTWMva0hWSnZsS1JOeTlYTUNBd0VBQVRBTkJna3Foa2lHIiArCisgICAgICAgICI5dzBCQVFVRkFBT0JnUUM3eUJtSjlPL2VXREd0U0g5QkgwUjNkaDJOZFNUM1c5aE5aOGhJYThVOGtsaE5IYlVDU1NrdFptWmt2YlBVIiArCisgICAgICAgICJoc2U1TEkzZGg2UnlORHVxRHJiWXdjcXpLYkZKYXEvalg5a0NvZWIzdmdiUUVsTVJYOEQySUQxdlJqeHdsQUxGSVNydGFONFZwV3pWIiArCisgICAgICAgICJ5ZW9IUFc0eGxkZVptb1Z0am44elhOelFoTHVCcVgyTW1BQUFBcXdBQUFBVXZrVVNjZnc5eUNTbUFMcnVVUk5tdEJhaTdrUUFBQVp4IiArCisgICAgICAgICI0Sm1panhzL2w4RUJhbGVhVXJ1NkVPUGlvV2tVQUVWV0N4ak0vVHhiR0hPaTJWTXNRV3FSci9EWjN3c0RtdFFndzNRVHJVSzY2NnNSIiArCisgICAgICAgICJNQm5icWRueUN5dk0xSjJWMXh4TFhQVWVSQm1SMkNYb3JZR0Y5RHllN05rZ1ZkZkErOWc5TC8wQXU2VWduKzJDajVsZW9JZ2tnQXBOIiArCisgICAgICAgICJ2dUVjWmVnRmxOT1VQVkVzM1NsQmdVRjFCWTZPQk0wVUJIVFB3R0d4RkJCY2V0Y3VNUmJVbnU2NXZ5REcwcHNsVDU5cXBhUjBUTVZzIiArCisgICAgICAgICJQK3RjaGVFemh5amJmTTMyL3Z3aG5MOWRCRWdNOHFNdDBzcUY2aXROT1FVL0Y0V0drSzJDbTJ2NENZRXlLWXczMjVmRWh6VFhvc2NrIiArCisgICAgICAgICJNaGJxbWN5TGFiOEVQY2VXRjNkd2VvVVQ3NitqRVp4OGxWMmRhcFIrQ21jelFJNDN0VjlidHNkMXhpQmJCSEFLdnltbTlFcDliUHpNIiArCisgICAgICAgICJKME1RaStPdFVSTDlMeGtlLzcwL01SdWVxYlBlVWxPYUd2QU5UbVhRRDJPblc3UElTd0o5bHBlTGZURzBMY3Frb3FrYnRMS1FMWUhJIiArCisgICAgICAgICJyUWZWNWowait3bXZtcE14empOM3V2TmFqTGE0elE4bDBFb2s5U0ZhUnIyUkwwZ044UTJKZWdmT0w0cFVpSFBzaDY0V1d5YTJOQjdmIiArCisgICAgICAgICJWKzFzNjVlQTVvc3BYWXNTaFJqbzA0NlFoR1RteW13WFh6ZHp1eHU4SWxuVEVvbnQ2UDQrSitHc1drNmNsZEdibDIwaGN0dVVLenl4IiArCisgICAgICAgICJPcHRqRVBPS2VqVjYwaURDWUdtSGJDV0F6UThoNU1JTFY4MkljbHpOVmlabXpBYXBlZUNuZXhocFhoV1RzK3hERVlTS0VpRy9jYW10IiArCisgICAgICAgICJiaG1aYzNCY3lWSnJXMjNQa3RTZnBCUTZEOFp4b01mRjBMN1YyR1FNYVVnKzNyN3Vjcng4MmtwcW90anYweEhnaE5JbTk1YUJyMVF3IiArCisgICAgICAgICIxZ2FFanNDLzB3R21tQkRnMWRUREgrRjFwOVRJbnpyM0VGdVlEMFlpUTdZbEFIcTNjUHV5R29MWEo1ZFhZdVNCZmhEWEpTZWRkVWtsIiArCisgICAgICAgICJrMXVmWnlPT2Nza2VJblFnZTdqemFSZm1LZzNVOTRyK3NwTUV2YjBBekRRVk9LdmpqbzFpdnhNU2dGUlphRGIvNHF3PSI7CisKKyAgICAvKioKKyAgICAgKiBEZWZpbmVzIHRoZSBrZXlzdG9yZSBjb250ZW50cyBmb3IgdGhlIHNlcnZlciwgSktTIHZlcnNpb24uIEhvbGRzIGp1c3QgYQorICAgICAqIHNpbmdsZSBzZWxmLWdlbmVyYXRlZCBrZXkuIFRoZSBzdWJqZWN0IG5hbWUgaXMgIlRlc3QgU2VydmVyIi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VSVkVSX0tFWVNfSktTID0KKyAgICAgICAgIi91Mys3UUFBQUFJQUFBQUJBQUFBQVFBRmJYbHJaWGtBQUFFYVdGZkJlQUFBQXJvd2dnSzJNQTRHQ2lzR0FRUUJLZ0lSQVFFRkFBU0MiICsKKyAgICAgICAgIkFxSTJrcDVYam5GOFlaa2hjRjkyWXNKTlFrdnNtSDd6cU1NODdqMjN6U29WNER3eUUzWGVDL2daV3ExVG9TY0lob3Faa3psYldjdTQiICsKKyAgICAgICAgIlQvWmZjL0RyZkdrL3JLYkJMMXVXS0daOGZNdGxaazhLb0FoeFprMUpTeUp2ZGt5S3hxbXpVYnhrMU9GTWxOMlZKTnU5N0ZQVkgrZHUiICsKKyAgICAgICAgImR2alR2bXBkb004MUlOV0JXLzFmWkplUWVEdm40bU1iYmUwSXhncGlMbkk5V1NldmxhRFAvc20xWDNpTzl5RXl6SExMK001RXJzcG8iICsKKyAgICAgICAgIkN3YTU1OGZPdTVEZHNJQ01YaHZEUXhqV0ZLRmhQSG5LdEdlK1Z2d2tHOS9iQWFEZ3gza2ZoazB3NXp2ZG5rS2IrOEVkOXlsTlJ6ZGsiICsKKyAgICAgICAgIm9jQWEvbXhsTVRPc1R2REtYampzQnVwTlBJSWo3T1A0R05uWmF4a0pqU3M5OHBFTzY3b3AxR1gycWh5NkZTT1BOdXE4ay82NUh6VWMiICsKKyAgICAgICAgIlBZbjZ2b0VlaDZ2bTAyVS9zakVuelJldlEyKzJ3WG9BZHAwRXd0US9EbE1lK052Y3dQR1dLdU1nWDRBNEw5M0RaR2IwNE4yVm1BVTMiICsKKyAgICAgICAgIllMT3Rad1RPMExidVdyY0NNL3E5OUcvN0xjY3preElWck8ySS9yaDhSWFZjemxmOVF6Y3JGT2JGdjRBVHVzcFdKOHhHN0Roc01ibmsiICsKKyAgICAgICAgInJUOTRQcTZUb2dZZW96OG84Wk15a2VzQXFONm10LzkrVG9JZW1tWHYrZStLVTFoSTVvTHdXTW5VRzZkWE02aEl2clVMWTZvK1FDUEgiICsKKyAgICAgICAgIjE3MllRSk1hKzY4SEFlUytpdEJUQUY0Q2xtL2JMbjZyZUhDR0dVNnZOZHdVMGxZbGRwaU9qOWNCM3QrdTJVdUxvNnRpRldqTGY1WnMiICsKKyAgICAgICAgIkVRSkVUZDRnL0VLOW5IeEpuMEdBS3JXblR3N3BFSFFKMDhlbHpVdXkwNEMvakVFRys0UVhVMUluelM0by9rUjBTcXoyV1RHRG9Tb3EiICsKKyAgICAgICAgImV3dVBSVTVielFzL2I5ZGFxM21Ycm5QdFJCTDZIZlNEQWRwVEs3NmlIcUxDR2RxeDNhdkhqVlNCbTR6RnZFdVlCQ2V2KzNpS09CbWciICsKKyAgICAgICAgInloN2VRUlRqejRVT1dmeTg1b21NQnI3bEs4UHRmVkJEek9YcGFzeFMwdUJnZFV5QkRYNHRPNms5alo4YTFrbVFSUUFBQUFFQUJWZ3UiICsKKyAgICAgICAgIk5UQTVBQUFDU0RDQ0FrUXdnZ0d0QWdSSVI4U0tNQTBHQ1NxR1NJYjNEUUVCQkFVQU1Ha3hDekFKQmdOVkJBWVRBbFZUTVJNd0VRWUQiICsKKyAgICAgICAgIlZRUUlFd3BEWVd4cFptOXlibWxoTVF3d0NnWURWUVFIRXdOTlZGWXhEekFOQmdOVkJBb1RCa2R2YjJkc1pURVFNQTRHQTFVRUN4TUgiICsKKyAgICAgICAgIlFXNWtjbTlwWkRFVU1CSUdBMVVFQXhNTFZHVnpkQ0JUWlhKMlpYSXdIaGNOTURnd05qQTFNVEEwT0RReVdoY05NRGd3T1RBek1UQTAiICsKKyAgICAgICAgIk9EUXlXakJwTVFzd0NRWURWUVFHRXdKVlV6RVRNQkVHQTFVRUNCTUtRMkZzYVdadmNtNXBZVEVNTUFvR0ExVUVCeE1EVFZSV01ROHciICsKKyAgICAgICAgIkRRWURWUVFLRXdaSGIyOW5iR1V4RURBT0JnTlZCQXNUQjBGdVpISnZhV1F4RkRBU0JnTlZCQU1UQzFSbGMzUWdVMlZ5ZG1WeU1JR2YiICsKKyAgICAgICAgIk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FDd29DNmNocUNJODRyajFQclh1SmdiaWl0NEVWOTA5elI2TjBqTmxZZmciICsKKyAgICAgICAgIml0d0IzOWJQMzl3SDAzckZtOFQ1OWIzbWJTcHRuR21DSXBMWm4yNUtQUEZzWUQzSkord0ZsbWlVZEVQOUgwNWZsZnd0RlFKbnc5dVQiICsKKyAgICAgICAgIjNyUklkWVZNUGNRM1JvWnp3QU1saUdyODgySTJ0aElEYkE2eGpHVS8xblJJZHZrMEx0eEgzUUlEQVFBQk1BMEdDU3FHU0liM0RRRUIiICsKKyAgICAgICAgIkJBVUFBNEdCQUpuKzZZZ1VsWTE4SWUrMCtWdDhvRWk4MUROaS9iZlByQVVBaDYzZmhoQmlreC8zUjlkbDN3aDA5WjZwN2NJZE54alciICsKKyAgICAgICAgIm4ybGwrY1JXOWVxRjd6NzVGME9tbTBDNy9LQUVQanVrVmJzem16ZVU1VnF6a3BTdDBqODRZV2krVGZjSFJyZnZoTGJybG1HSVRWcFkiICsKKyAgICAgICAgIm9sNXBITER5cUdtRHM1M3Bnd2lwV3Fzbi9uRVhFQmdqM0VvcVBlcUhiRGY3WWFQOGgvNUJTdDA9IjsKKworICAgIHByaXZhdGUgU3RyaW5nIFBBU1NXT1JEID0gImFuZHJvaWQiOworCisgICAgLyoqCisgICAgICogTG9hZHMgYSBrZXlzdG9yZSBmcm9tIGEgYmFzZTY0LWVuY29kZWQgU3RyaW5nLiBSZXR1cm5zIHRoZSBLZXlNYW5hZ2VyW10KKyAgICAgKiBmb3IgdGhlIHJlc3VsdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIEtleU1hbmFnZXJbXSBnZXRLZXlNYW5hZ2VycygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcga2V5cyA9ICh1c2VCS1MgPyBTRVJWRVJfS0VZU19CS1MgOiBTRVJWRVJfS0VZU19KS1MpOworICAgICAgICBieXRlW10gYnl0ZXMgPSBCYXNlNjQuZGVjb2RlKGtleXMuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIElucHV0U3RyZWFtIGlucHV0U3RyZWFtID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzKTsKKworICAgICAgICBLZXlTdG9yZSBrZXlTdG9yZSA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICBrZXlTdG9yZS5sb2FkKGlucHV0U3RyZWFtLCBQQVNTV09SRC50b0NoYXJBcnJheSgpKTsKKyAgICAgICAgaW5wdXRTdHJlYW0uY2xvc2UoKTsKKworICAgICAgICBTdHJpbmcgYWxnb3JpdGhtID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0RGVmYXVsdEFsZ29yaXRobSgpOworICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeSBrZXlNYW5hZ2VyRmFjdG9yeSA9IEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgIGtleU1hbmFnZXJGYWN0b3J5LmluaXQoa2V5U3RvcmUsIFBBU1NXT1JELnRvQ2hhckFycmF5KCkpOworCisgICAgICAgIHJldHVybiBrZXlNYW5hZ2VyRmFjdG9yeS5nZXRLZXlNYW5hZ2VycygpOworICAgIH0KKworICAgIHByaXZhdGUgU1NMU2VydmVyU29ja2V0IGdldFNTTFNlcnZlclNvY2tldCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTU0xDb250ZXh0IGNvbnRleHQgPSBTU0xDb250ZXh0LmdldEluc3RhbmNlKCJUTFMiKTsKKyAgICAgICAgY29udGV4dC5pbml0KGdldEtleU1hbmFnZXJzKCksIG51bGwsIG51bGwpOworICAgICAgICBTU0xTZXJ2ZXJTb2NrZXQgc3NzID0gKFNTTFNlcnZlclNvY2tldCkgY29udGV4dC5nZXRTZXJ2ZXJTb2NrZXRGYWN0b3J5KCkKKyAgICAgICAgICAgICAgICAuY3JlYXRlU2VydmVyU29ja2V0KCk7CisgICAgICAgIHJldHVybiBzc3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jcmVhdGlvblN0cmVzc1Rlc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5TWFuYWdlcltdIGtleU1hbmFnZXJzID0gZ2V0S2V5TWFuYWdlcnMoKTsKKyAgICAgICAgLy8gVGVzdCB0aGUgZGVmYXVsdCBjb2RlcGF0aCwgd2hpY2ggdXNlcyAvZGV2L3VyYW5kb20uCisgICAgICAgIFNTTENvbnRleHQgc3NsQ29udGV4dCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UoIlRMUyIpOworICAgICAgICBzc2xDb250ZXh0LmluaXQoa2V5TWFuYWdlcnMsIG51bGwsIG51bGwpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDIwNDg7ICsraSkgeworICAgICAgICAgICAgc3NsQ29udGV4dC5nZXRTZXJ2ZXJTb2NrZXRGYWN0b3J5KCkuY3JlYXRlU2VydmVyU29ja2V0KCkuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRlc3QgdGhlIG90aGVyIGNvZGVwYXRoLCB3aGljaCBjb3BpZXMgYSBzZWVkIGZyb20gYSBieXRlW10uCisgICAgICAgIHNzbENvbnRleHQuaW5pdChrZXlNYW5hZ2VycywgbnVsbCwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDQ4OyArK2kpIHsKKyAgICAgICAgICAgIHNzbENvbnRleHQuZ2V0U2VydmVyU29ja2V0RmFjdG9yeSgpLmNyZWF0ZVNlcnZlclNvY2tldCgpLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMU2Vzc2lvbkJpbmRpbmdFdmVudFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xTZXNzaW9uQmluZGluZ0V2ZW50VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmY2NmNjgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMU2Vzc2lvbkJpbmRpbmdFdmVudFRlc3QuamF2YQpAQCAtMCwwICsxLDIzNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKKworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbkNvbnRleHQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uQmluZGluZ0V2ZW50OworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5TU0xTZXNzaW9uQmluZGluZ0V2ZW50PC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgU1NMU2Vzc2lvbkJpbmRpbmdFdmVudFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmF4X25ldF9zc2xfU1NMU2Vzc2lvbkxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICBTU0xTZXNzaW9uIHNlcyA9IG5ldyBNeVNTTFNlc3Npb24oKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMU2Vzc2lvbkJpbmRpbmdFdmVudCBldmVudCA9IG5ldyBTU0xTZXNzaW9uQmluZGluZ0V2ZW50KHNlcywgInRlc3QiKTsKKyAgICAgICAgICAgIGlmICghInRlc3QiLmVxdWFscyhldmVudC5nZXROYW1lKCkpKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiaW5jb3JyZWN0IG5hbWUiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghZXZlbnQuZ2V0U2Vzc2lvbigpLmVxdWFscyhzZXMpKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiaW5jb3JyZWN0IHNlc3Npb24iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTU0xTZXNzaW9uQmluZGluZ0V2ZW50IGV2ZW50ID0gbmV3IFNTTFNlc3Npb25CaW5kaW5nRXZlbnQobnVsbCwgInRlc3QiKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMU2Vzc2lvbkJpbmRpbmdFdmVudCBldmVudCA9IG5ldyBTU0xTZXNzaW9uQmluZGluZ0V2ZW50KHNlcywgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbkJpbmRpbmdFdmVudCNnZXROYW1lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE5hbWUoKSB7CisgICAgICAgIFNTTFNlc3Npb24gc2VzID0gbmV3IE15U1NMU2Vzc2lvbigpOworICAgICAgICBTU0xTZXNzaW9uQmluZGluZ0V2ZW50IGV2ZW50ID0gbmV3IFNTTFNlc3Npb25CaW5kaW5nRXZlbnQoc2VzLCAidGVzdCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBzZXNzaW9uIG5hbWUiLCAidGVzdCIsIGV2ZW50LmdldE5hbWUoKSk7CisgICAgICAgIGV2ZW50ID0gbmV3IFNTTFNlc3Npb25CaW5kaW5nRXZlbnQoc2VzLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3Qgc2Vzc2lvbiBuYW1lIiwgbnVsbCwgZXZlbnQuZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb25CaW5kaW5nRXZlbnQjZ2V0U2Vzc2lvbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTZXNzaW9uKCkgeworICAgICAgICBTU0xTZXNzaW9uIHNlcyA9IG5ldyBNeVNTTFNlc3Npb24oKTsKKyAgICAgICAgU1NMU2Vzc2lvbkJpbmRpbmdFdmVudCBldmVudCA9IG5ldyBTU0xTZXNzaW9uQmluZGluZ0V2ZW50KHNlcywgInRlc3QiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3Qgc2Vzc2lvbiIsIHNlcywgZXZlbnQuZ2V0U2Vzc2lvbigpKTsKKyAgICB9Cit9CisKK2NsYXNzIE15U1NMU2Vzc2lvbiBpbXBsZW1lbnRzIFNTTFNlc3Npb24geworICAgIC8qCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jZ2V0QXBwbGljYXRpb25CdWZmZXJTaXplKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEFwcGxpY2F0aW9uQnVmZmVyU2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNnZXRDaXBoZXJTdWl0ZSgpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDaXBoZXJTdWl0ZSgpIHsKKyAgICAgICAgcmV0dXJuICJNeVRlc3RDaXBoZXJTdWl0ZSI7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNnZXRDcmVhdGlvblRpbWUoKQorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldENyZWF0aW9uVGltZSgpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNnZXRJZCgpCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRJZCgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNnZXRMYXN0QWNjZXNzZWRUaW1lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRMYXN0QWNjZXNzZWRUaW1lKCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uI2dldExvY2FsQ2VydGlmaWNhdGVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVbXSBnZXRMb2NhbENlcnRpZmljYXRlcygpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNnZXRMb2NhbFByaW5jaXBhbCgpCisgICAgICovCisgICAgcHVibGljIFByaW5jaXBhbCBnZXRMb2NhbFByaW5jaXBhbCgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNnZXRQYWNrZXRCdWZmZXJTaXplKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFBhY2tldEJ1ZmZlclNpemUoKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jZ2V0UGVlckNlcnRpZmljYXRlQ2hhaW4oKQorICAgICAqLworICAgIHB1YmxpYyBYNTA5Q2VydGlmaWNhdGVbXSBnZXRQZWVyQ2VydGlmaWNhdGVDaGFpbigpCisgICAgdGhyb3dzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uKCJ0ZXN0IGV4Y2VwdGlvbiIpOworICAgIH0KKworICAgIC8qCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jZ2V0UGVlckNlcnRpZmljYXRlcygpCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlW10gZ2V0UGVlckNlcnRpZmljYXRlcygpCisgICAgdGhyb3dzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uKCJ0ZXN0IGV4Y2VwdGlvbiIpOworICAgIH0KKworICAgIC8qCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jZ2V0UGVlckhvc3QoKQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGVlckhvc3QoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jZ2V0UGVlclBvcnQoKQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UGVlclBvcnQoKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jZ2V0UGVlclByaW5jaXBhbCgpCisgICAgICovCisgICAgcHVibGljIFByaW5jaXBhbCBnZXRQZWVyUHJpbmNpcGFsKCkgdGhyb3dzIFNTTFBlZXJVbnZlcmlmaWVkRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNnZXRQcm90b2NvbCgpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRQcm90b2NvbCgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNnZXRTZXNzaW9uQ29udGV4dCgpCisgICAgICovCisgICAgcHVibGljIFNTTFNlc3Npb25Db250ZXh0IGdldFNlc3Npb25Db250ZXh0KCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uI2dldFZhbHVlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRWYWx1ZShTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uI2dldFZhbHVlTmFtZXMoKQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRWYWx1ZU5hbWVzKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uI2ludmFsaWRhdGUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGludmFsaWRhdGUoKSB7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNpc1ZhbGlkKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1ZhbGlkKCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNwdXRWYWx1ZShqYXZhLmxhbmcuU3RyaW5nLAorICAgICAqICAgICAgamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXRWYWx1ZShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKSB7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNyZW1vdmVWYWx1ZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZVZhbHVlKFN0cmluZyBuYW1lKSB7CisgICAgfQorCit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1NTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTAwNmE4MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsODUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldEZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbkJpbmRpbmdFdmVudDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTb2NrZXQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTb2NrZXRGYWN0b3J5OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgU1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lciBjbGFzcworICoKKyAqLworcHVibGljIGNsYXNzIFNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIGNsYXNzIG15U1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lciBpbXBsZW1lbnRzIFNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXIgeworCisgICAgICAgIHB1YmxpYyBib29sZWFuIGJvdW5kRG9uZSA9IGZhbHNlOworICAgICAgICBwdWJsaWMgYm9vbGVhbiB1bmJvdW5kRG9uZSA9IGZhbHNlOworCisgICAgICAgIG15U1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lcigpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHZhbHVlQm91bmQoU1NMU2Vzc2lvbkJpbmRpbmdFdmVudCBldmVudCkgeworICAgICAgICAgICAgaWYgKGV2ZW50ICE9IG51bGwpIGJvdW5kRG9uZSA9IHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIHZvaWQgdmFsdWVVbmJvdW5kKFNTTFNlc3Npb25CaW5kaW5nRXZlbnQgZXZlbnQpIHsKKyAgICAgICAgICAgIGlmIChldmVudCAhPSBudWxsKSB1bmJvdW5kRG9uZSA9IHRydWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogQHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24KKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXIjdmFsdWVCb3VuZChTU0xTZXNzaW9uQmluZGluZ0V2ZW50IGV2ZW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdmFsdWVCb3VuZCgpIHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24sCisgICAgICAgICAgICBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIFNTTFNvY2tldCBzb2NrID0gKFNTTFNvY2tldCkgU1NMU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCkKKyAgICAgICAgICAgICAgICAuY3JlYXRlU29ja2V0KCk7CisgICAgICAgIFNTTFNlc3Npb24gc3MgPSBzb2NrLmdldFNlc3Npb24oKTsKKyAgICAgICAgbXlTU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyIHNibCA9IG5ldyBteVNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXIoKTsKKyAgICAgICAgc3MucHV0VmFsdWUoInRlc3QiLCBzYmwpOworICAgICAgICBhc3NlcnRUcnVlKCJ2YWx1ZUJvdW5kIHdhcyBub3QgY2FsbGVkLiIsIHNibC5ib3VuZERvbmUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIFVua25vd25Ib3N0RXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyI3ZhbHVlVW5ib3VuZChTU0xTZXNzaW9uQmluZGluZ0V2ZW50IGV2ZW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdmFsdWVVbmJvdW5kKCkgdGhyb3dzIFVua25vd25Ib3N0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFNTTFNvY2tldCBzb2NrID0gKFNTTFNvY2tldCkgU1NMU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCkKKyAgICAgICAgICAgICAgICAuY3JlYXRlU29ja2V0KCk7CisgICAgICAgIFNTTFNlc3Npb24gc3MgPSBzb2NrLmdldFNlc3Npb24oKTsKKyAgICAgICAgbXlTU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyIHNibCA9IG5ldyBteVNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXIoKTsKKyAgICAgICAgc3MucHV0VmFsdWUoInRlc3QiLCBzYmwpOworICAgICAgICBzcy5yZW1vdmVWYWx1ZSgidGVzdCIpOworICAgICAgICBhc3NlcnRUcnVlKCJ2YWx1ZVVuYm91bmQgd2FzIG5vdCBjYWxsZWQuIiwgc2JsLnVuYm91bmREb25lKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMU2Vzc2lvbkNvbnRleHRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMU2Vzc2lvbkNvbnRleHRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWE5NWViOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xTZXNzaW9uQ29udGV4dFRlc3QuamF2YQpAQCAtMCwwICsxLDk1IEBACitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xDb250ZXh0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbkNvbnRleHQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleU1hbmFnZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlNTTFNlc3Npb25Db250ZXh0PC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKi8KK3B1YmxpYyBjbGFzcyBTU0xTZXNzaW9uQ29udGV4dFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbkNvbnRleCNnZXRTZXNzaW9uQ2FjaGVTaXplKCkKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb25Db250ZXgjc2V0U2Vzc2lvbkNhY2hlU2l6ZShpbnQgc2l6ZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X3Nlc3Npb25DYWNoZVNpemUoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgU1NMQ29udGV4dCBjb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZSgiVExTIik7CisgICAgICAgIGNvbnRleHQuaW5pdChudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgU1NMU2Vzc2lvbkNvbnRleHQgc2MgPSBjb250ZXh0CisgICAgICAgICAgICAgICAgLmdldENsaWVudFNlc3Npb25Db250ZXh0KCk7CisgICAgICAgIHNjLnNldFNlc3Npb25DYWNoZVNpemUoMTApOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEwIHdhc24ndCByZXR1cm5lZCIsIDEwLCBzYy5nZXRTZXNzaW9uQ2FjaGVTaXplKCkpOworICAgICAgICBzYy5zZXRTZXNzaW9uQ2FjaGVTaXplKDUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjUgd2Fzbid0IHJldHVybmVkIiwgNSwgc2MuZ2V0U2Vzc2lvbkNhY2hlU2l6ZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2Muc2V0U2Vzc2lvbkNhY2hlU2l6ZSgtMSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbkNvbnRleCNnZXRTZXNzaW9uVGltZW91dCgpCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uQ29udGV4I3NldFNlc3Npb25UaW1lb3V0KGludCBzZWNvbmRzKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3Rfc2Vzc2lvblRpbWVvdXQoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgU1NMQ29udGV4dCBjb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZSgiVExTIik7CisgICAgICAgIGNvbnRleHQuaW5pdChudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgU1NMU2Vzc2lvbkNvbnRleHQgc2MgPSBjb250ZXh0CisgICAgICAgICAgICAgICAgLmdldENsaWVudFNlc3Npb25Db250ZXh0KCk7CisgICAgICAgIHNjLnNldFNlc3Npb25UaW1lb3V0KDEwMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiMTAwIHdhc24ndCByZXR1cm5lZCIsIDEwMCwgc2MuZ2V0U2Vzc2lvblRpbWVvdXQoKSk7CisgICAgICAgIHNjLnNldFNlc3Npb25UaW1lb3V0KDUwMDApOworICAgICAgICBhc3NlcnRFcXVhbHMoIjUwMDAgd2Fzbid0IHJldHVybmVkIiwgNTAwMCwgc2MuZ2V0U2Vzc2lvblRpbWVvdXQoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNjLnNldFNlc3Npb25UaW1lb3V0KC0xKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogQHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uQ29udGV4I2dldFNlc3Npb24oYnl0ZVtdIHNlc3Npb25JZCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X2dldFNlc3Npb24oKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgU1NMQ29udGV4dCBjb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZSgiVExTIik7CisgICAgICAgIGNvbnRleHQuaW5pdChudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgU1NMU2Vzc2lvbkNvbnRleHQgc2MgPSBjb250ZXh0CisgICAgICAgICAgICAgICAgLmdldENsaWVudFNlc3Npb25Db250ZXh0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzYy5nZXRTZXNzaW9uKG51bGwpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIGFzc2VydE51bGwoc2MuZ2V0U2Vzc2lvbihuZXcgYnl0ZVs1XSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogQHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uQ29udGV4I2dldElkcygpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF9nZXRJZHMoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgU1NMQ29udGV4dCBjb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZSgiVExTIik7CisgICAgICAgIGNvbnRleHQuaW5pdChudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgU1NMU2Vzc2lvbkNvbnRleHQgc2MgPSBjb250ZXh0CisgICAgICAgICAgICAgICAgLmdldENsaWVudFNlc3Npb25Db250ZXh0KCk7CisgICAgICAgIGFzc2VydEZhbHNlKHNjLmdldElkcygpLmhhc01vcmVFbGVtZW50cygpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xTZXNzaW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1NTTFNlc3Npb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWMyM2NhZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xTZXNzaW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjUwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QcmluY2lwYWw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlckZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xDb250ZXh0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb25CaW5kaW5nRXZlbnQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuVHJ1c3RNYW5hZ2VyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBsaWJjb3JlLmlvLkJhc2U2NDsKK2ltcG9ydCB0ZXN0cy5hcGkuamF2YXgubmV0LnNzbC5IYW5kc2hha2VDb21wbGV0ZWRFdmVudFRlc3QuTXlIYW5kc2hha2VMaXN0ZW5lcjsKK2ltcG9ydCB0ZXN0cy5hcGkuamF2YXgubmV0LnNzbC5IYW5kc2hha2VDb21wbGV0ZWRFdmVudFRlc3QuVGVzdFRydXN0TWFuYWdlcjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfUG9ydE1hbmFnZXI7CisKKy8qKgorICogVGVzdHMgZm9yIFNTTFNlc3Npb24gY2xhc3MKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBTU0xTZXNzaW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8vIHNldCB0byB0cnVlIGlmIG9uIEFuZHJvaWQsIGZhbHNlIGlmIG9uIFJJCisgICAgYm9vbGVhbiB1c2VCS1MgPSB0cnVlOworCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uI2dldFBlZXJIb3N0KCkKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jZ2V0UGVlclBvcnQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UGVlckhvc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMU2Vzc2lvbiBzID0gY2xpZW50U2Vzc2lvbjsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLmdldEhvc3ROYW1lKCksIHMuZ2V0UGVlckhvc3QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhwb3J0LCBzLmdldFBlZXJQb3J0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNpbnZhbGlkYXRlKCkKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jaXNWYWxpZCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pbnZhbGlkYXRlKCkgeworICAgICAgICBTU0xTZXNzaW9uIHMgPSBjbGllbnRTZXNzaW9uOworICAgICAgICBhc3NlcnRUcnVlKHMuaXNWYWxpZCgpKTsKKyAgICAgICAgcy5pbnZhbGlkYXRlKCk7CisgICAgICAgIGFzc2VydEZhbHNlKHMuaXNWYWxpZCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jZ2V0UGVlclByaW5jaXBhbCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQZWVyUHJpbmNpcGFsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFByaW5jaXBhbCBwMSA9IGNsaWVudFNlc3Npb24uZ2V0UGVlclByaW5jaXBhbCgpOworICAgICAgICBLZXlTdG9yZSBzdG9yZSA9IHNlcnZlci5nZXRTdG9yZSgpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydCA9IChYNTA5Q2VydGlmaWNhdGUpc3RvcmUuZ2V0Q2VydGlmaWNhdGUoIm15a2V5Iik7CisgICAgICAgIFByaW5jaXBhbCBwMiA9IGNlcnQuZ2V0U3ViamVjdFg1MDBQcmluY2lwYWwoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHAxLCBwMik7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uI2dldEFwcGxpY2F0aW9uQnVmZmVyU2l6ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBcHBsaWNhdGlvbkJ1ZmZlclNpemUoKSB7CisgICAgICAgIGFzc2VydFRydWUoY2xpZW50U2Vzc2lvbi5nZXRBcHBsaWNhdGlvbkJ1ZmZlclNpemUoKSA+IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNnZXRDaXBoZXJTdWl0ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDaXBoZXJTdWl0ZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENJUEhFUl9TVUlURSwgY2xpZW50U2Vzc2lvbi5nZXRDaXBoZXJTdWl0ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jZ2V0Q3JlYXRpb25UaW1lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldENyZWF0aW9uVGltZSgpIHsKKyAgICAgICAgLy8gY2hlY2sgaWYgY3JlYXRpb24gdGltZSB3YXMgaW4gdGhlIGxhc3QgMTAgc2Vjb25kcworICAgICAgICBsb25nIGN1cnJlbnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgIGxvbmcgc2Vzc2lvblRpbWUgPSBjbGllbnRTZXNzaW9uLmdldENyZWF0aW9uVGltZSgpOworICAgICAgICBsb25nIGRpZmYgPSBjdXJyZW50VGltZSAtIHNlc3Npb25UaW1lOworICAgICAgICBhc3NlcnRUcnVlKCJkaWZmIGJldHdlZW4gIiArIGN1cnJlbnRUaW1lICsgIiBhbmQgIiArIHNlc3Npb25UaW1lICsgIiBzaG91bGQgYmUgPCAxMDAwMCIsCisgICAgICAgICAgICAgICAgICAgZGlmZiA8IDEwMDAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jZ2V0SWQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SWQoKSB7CisgICAgICAgIGJ5dGVbXSBpZCA9IGNsaWVudFNlc3Npb24uZ2V0SWQoKTsKKyAgICAgICAgU1NMU2Vzc2lvbiBzZXNzID0gY2xpZW50U3NsQ29udGV4dC5nZXRDbGllbnRTZXNzaW9uQ29udGV4dCgpLmdldFNlc3Npb24oaWQpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJDb3VsZCBub3QgZmluZCBzZXNzaW9uIGZvciBpZCAiICsgaWQsIHNlc3MpOworICAgICAgICBhc3NlcnRFcXVhbHMoY2xpZW50U2Vzc2lvbiwgc2Vzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uI2dldExhc3RBY2Nlc3NlZFRpbWUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TGFzdEFjY2Vzc2VkVGltZSgpIHsKKyAgICAgICAgLy8gY2hlY2sgaWYgbGFzdCBhY2Nlc3MgdGltZSB3YXMgaW4gdGhlIGxhc3QgMTAgc2Vjb25kcworICAgICAgICBsb25nIGN1cnJlbnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgIGxvbmcgc2Vzc2lvblRpbWUgPSBjbGllbnRTZXNzaW9uLmdldExhc3RBY2Nlc3NlZFRpbWUoKTsKKyAgICAgICAgbG9uZyBkaWZmID0gY3VycmVudFRpbWUgLSBzZXNzaW9uVGltZTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZGlmZiBiZXR3ZWVuICIgKyBjdXJyZW50VGltZSArICIgYW5kICIgKyBzZXNzaW9uVGltZSArICIgc2hvdWxkIGJlIDwgMTAwMDAiLAorICAgICAgICAgICAgICAgICAgIGRpZmYgPCAxMDAwMCk7CisgICAgICAgIGFzc2VydFRydWUgKCJkaWZmIHNob3VsZCBiZSA8IDEwMDAwIGJ1dCBpcyAiICsgZGlmZiwgZGlmZiA8IDEwMDAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5U3RvcmUgc3RvcmUgPSBjbGllbnQuZ2V0U3RvcmUoKTsKKyAgICAgICAgQ2VydGlmaWNhdGUgY2VydCA9IHN0b3JlLmdldENlcnRpZmljYXRlKCJteWtleSIpOworICAgICAgICBDZXJ0aWZpY2F0ZVtdIGNlcnRzID0gY2xpZW50U2Vzc2lvbi5nZXRMb2NhbENlcnRpZmljYXRlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoY2VydCwgY2VydHNbMF0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNnZXRMb2NhbFByaW5jaXBhbCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRMb2NhbFByaW5jaXBhbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQcmluY2lwYWwgcDEgPSBjbGllbnRTZXNzaW9uLmdldExvY2FsUHJpbmNpcGFsKCk7CisgICAgICAgIEtleVN0b3JlIHN0b3JlID0gY2xpZW50LmdldFN0b3JlKCk7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0ID0gKFg1MDlDZXJ0aWZpY2F0ZSlzdG9yZS5nZXRDZXJ0aWZpY2F0ZSgibXlrZXkiKTsKKyAgICAgICAgUHJpbmNpcGFsIHAyID0gY2VydC5nZXRTdWJqZWN0WDUwMFByaW5jaXBhbCgpOworICAgICAgICBhc3NlcnRFcXVhbHMocDEsIHAyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jZ2V0UGFja2V0QnVmZmVyU2l6ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQYWNrZXRCdWZmZXJTaXplKCkgeworICAgICAgICBhc3NlcnRUcnVlKGNsaWVudFNlc3Npb24uZ2V0UGFja2V0QnVmZmVyU2l6ZSgpID4gMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uI2dldFBlZXJDZXJ0aWZpY2F0ZXMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UGVlckNlcnRpZmljYXRlcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDZXJ0aWZpY2F0ZVtdIHJlcyA9IGNsaWVudFNlc3Npb24uZ2V0UGVlckNlcnRpZmljYXRlcygpOworICAgICAgICBhc3NlcnRUcnVlKHJlcy5sZW5ndGggPiAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jZ2V0UGVlckNlcnRpZmljYXRlQ2hhaW4oKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UGVlckNlcnRpZmljYXRlQ2hhaW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgamF2YXguc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGVbXSByZXMgPSBjbGllbnRTZXNzaW9uLmdldFBlZXJDZXJ0aWZpY2F0ZUNoYWluKCk7CisgICAgICAgIGFzc2VydFRydWUocmVzLmxlbmd0aCA+IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNnZXRQcm90b2NvbCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQcm90b2NvbCgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUTFN2MSIsIGNsaWVudFNlc3Npb24uZ2V0UHJvdG9jb2woKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uI2dldFNlc3Npb25Db250ZXh0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFNlc3Npb25Db250ZXh0KCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoY2xpZW50U2Vzc2lvbi5nZXRTZXNzaW9uQ29udGV4dCgpLAorICAgICAgICAgICAgICAgICAgICAgY2xpZW50U3NsQ29udGV4dC5nZXRDbGllbnRTZXNzaW9uQ29udGV4dCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jcHV0VmFsdWUoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb24jcmVtb3ZlVmFsdWUoU3RyaW5nIG5hbWUpCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uI2dldFZhbHVlTmFtZXMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcHV0VmFsdWUoKSB7CisgICAgICAgIFNTTFNlc3Npb24gcyA9IGNsaWVudFNlc3Npb247CisgICAgICAgIG15U1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lciBzYmwgPSBuZXcgbXlTU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwocy5nZXRWYWx1ZU5hbWVzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgcy5nZXRWYWx1ZU5hbWVzKCkubGVuZ3RoKTsKKyAgICAgICAgcy5wdXRWYWx1ZSgiTmFtZV8wMSIsIHNibCk7CisgICAgICAgIHMucHV0VmFsdWUoIk5hbWVfMDIiLCBzYmwpOworICAgICAgICBzLnB1dFZhbHVlKCJOYW1lXzAzIiwgc2JsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHMuZ2V0VmFsdWVOYW1lcygpLmxlbmd0aCk7CisgICAgICAgIHMucmVtb3ZlVmFsdWUoIk5hbWVfMDEiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHMuZ2V0VmFsdWVOYW1lcygpLmxlbmd0aCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMucHV0VmFsdWUobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMucHV0VmFsdWUoIkFCQyIsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLnB1dFZhbHVlKG51bGwsIHNibCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5yZW1vdmVWYWx1ZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiNnZXRWYWx1ZShTdHJpbmcgbmFtZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFZhbHVlKCkgeworICAgICAgICBTU0xTZXNzaW9uIHMgPSBjbGllbnRTZXNzaW9uOworICAgICAgICBteVNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXIgc2JsID0gbmV3IG15U1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lcigpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmdldFZhbHVlKG51bGwpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcy5wdXRWYWx1ZSgiTmFtZSIsIHNibCk7CisgICAgICAgIE9iamVjdCBvYmogPSBzLmdldFZhbHVlKCJOYW1lIik7CisgICAgICAgIGFzc2VydFRydWUob2JqIGluc3RhbmNlb2YgU1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lcik7CisgICAgfQorCisgICAgVGhyZWFkIHNlcnZlclRocmVhZCwgY2xpZW50VGhyZWFkOworICAgIFRlc3RTZXJ2ZXIgc2VydmVyOworICAgIFRlc3RDbGllbnQgY2xpZW50OworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIHBvcnQgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgIFN0cmluZyBzZXJ2ZXJLZXlzID0gKHVzZUJLUyA/IFNFUlZFUl9LRVlTX0JLUyA6IFNFUlZFUl9LRVlTX0pLUyk7CisgICAgICAgIFN0cmluZyBjbGllbnRLZXlzID0gKHVzZUJLUyA/IENMSUVOVF9LRVlTX0JLUyA6IENMSUVOVF9LRVlTX0pLUyk7CisgICAgICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKHRydWUsCisgICAgICAgICAgICAgICAgVGVzdFNlcnZlci5DTElFTlRfQVVUSF9XQU5URUQsIHNlcnZlcktleXMpOworICAgICAgICBjbGllbnQgPSBuZXcgVGVzdENsaWVudCh0cnVlLCBjbGllbnRLZXlzKTsKKworICAgICAgICBzZXJ2ZXJUaHJlYWQgPSBuZXcgVGhyZWFkKHNlcnZlcik7CisgICAgICAgIGNsaWVudFRocmVhZCA9IG5ldyBUaHJlYWQoY2xpZW50KTsKKworICAgICAgICBzZXJ2ZXJUaHJlYWQuc3RhcnQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuc2xlZXAoMTAwMCk7CisgICAgICAgICAgICBjbGllbnRUaHJlYWQuc3RhcnQoKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiQ291bGQgbm90IGNyZWF0ZSBzZXJ2ZXIgb3IgY2llbnQgIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICB3aGlsZSAoY2xpZW50U2Vzc2lvbiA9PSBudWxsCisgICAgICAgICAgICAgICAgJiYgc2VydmVyLmV4Y2VwdGlvbiA9PSBudWxsCisgICAgICAgICAgICAgICAgJiYgY2xpZW50LmV4Y2VwdGlvbiA9PSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuc2xlZXAoNTAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJjb3VsZG4ndCBjcmVhdGUgc2Vzc2lvbiIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChzZXJ2ZXIuZXhjZXB0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIHNlcnZlci5leGNlcHRpb24ucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0TnVsbCgic2VydmVyIHRocmVhZCBoYXMgYSBwZW5kaW5nIGV4Y2VwdGlvbjogIiArIHNlcnZlci5leGNlcHRpb24sCisgICAgICAgICAgICAgICAgc2VydmVyLmV4Y2VwdGlvbik7CisgICAgICAgIGlmIChjbGllbnQuZXhjZXB0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIGNsaWVudC5leGNlcHRpb24ucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0TnVsbCgiY2xpZW50IHRocmVhZCBoYXMgYSBwZW5kaW5nIGV4Y2VwdGlvbjogIiArIGNsaWVudC5leGNlcHRpb24sCisgICAgICAgICAgICAgICAgY2xpZW50LmV4Y2VwdGlvbik7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkNvdWxkIG5vdCBpbml0aWFsaXplIHNlc3Npb24iLCBjbGllbnRTZXNzaW9uKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgbm90RmluaXNoZWQgPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlcnZlclRocmVhZC5qb2luKCk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjbGllbnRUaHJlYWQuam9pbigpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRoZSBzZXJ2ZXIgbXVzdCBoYXZlIGNvbXBsZXRlZCB3aXRob3V0IGFuIGV4Y2VwdGlvbi4KKyAgICAgICAgaWYgKHNlcnZlci5nZXRFeGNlcHRpb24oKSAhPSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihzZXJ2ZXIuZ2V0RXhjZXB0aW9uKCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVGhlIGNsaWVudCBtdXN0IGhhdmUgY29tcGxldGVkIHdpdGhvdXQgYW4gZXhjZXB0aW9uLgorICAgICAgICBpZiAoY2xpZW50LmdldEV4Y2VwdGlvbigpICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGNsaWVudC5nZXRFeGNlcHRpb24oKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgbXlTU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyIGltcGxlbWVudHMKKyAgICAgICAgICAgIFNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXIgeworICAgICAgICBteVNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXIoKSB7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIHZvaWQgdmFsdWVCb3VuZChTU0xTZXNzaW9uQmluZGluZ0V2ZW50IGV2ZW50KSB7fQorICAgICAgICBwdWJsaWMgdm9pZCB2YWx1ZVVuYm91bmQoU1NMU2Vzc2lvbkJpbmRpbmdFdmVudCBldmVudCkge30KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWZpbmVzIHRoZSBrZXlzdG9yZSBjb250ZW50cyBmb3IgdGhlIHNlcnZlciwgQktTIHZlcnNpb24uIEhvbGRzIGp1c3QgYQorICAgICAqIHNpbmdsZSBzZWxmLWdlbmVyYXRlZCBrZXkuIFRoZSBzdWJqZWN0IG5hbWUgaXMgIlRlc3QgU2VydmVyIi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VSVkVSX0tFWVNfQktTID0KKyAgICAgICAgICAgICJBQUFBQVFBQUFCUURrZWJ6b1AxWHdxeVdLUkNKRXBuL3Q4ZHFJUUFBQkRrRUFBVnRlV3RsZVFBQUFScFlsMjBuQUFBQUFRQUZXQzQxIgorICAgICAgICAgICAgKyAiTURrQUFBSk5NSUlDU1RDQ0FiS2dBd0lCQWdJRVNFZlUxakFOQmdrcWhraUc5dzBCQVFVRkFEQnBNUXN3Q1FZRFZRUUdFd0pWVXpFVCIKKyAgICAgICAgICAgICsgIk1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURU1NQW9HQTFVRUJ4TURUVlJXTVE4d0RRWURWUVFLRXdaSGIyOW5iR1V4RURBT0JnTlYiCisgICAgICAgICAgICArICJCQXNUQjBGdVpISnZhV1F4RkRBU0JnTlZCQU1UQzFSbGMzUWdVMlZ5ZG1WeU1CNFhEVEE0TURZd05URXhOVGd4TkZvWERUQTRNRGt3IgorICAgICAgICAgICAgKyAiTXpFeE5UZ3hORm93YVRFTE1Ba0dBMVVFQmhNQ1ZWTXhFekFSQmdOVkJBZ1RDa05oYkdsbWIzSnVhV0V4RERBS0JnTlZCQWNUQTAxVSIKKyAgICAgICAgICAgICsgIlZqRVBNQTBHQTFVRUNoTUdSMjl2WjJ4bE1SQXdEZ1lEVlFRTEV3ZEJibVJ5YjJsa01SUXdFZ1lEVlFRREV3dFVaWE4wSUZObGNuWmwiCisgICAgICAgICAgICArICJjakNCbnpBTkJna3Foa2lHOXcwQkFRRUZBQU9CalFBd2dZa0NnWUVBMExJZEthSXI5L3ZzVHE4QlpsQTNSK05GV1JhSDRsR3NUQVF5IgorICAgICAgICAgICAgKyAiRFBNRjlacUVET2FMNkRKdXUwY29sU0JCQlE4NWhRVFBhOW05bnlKb04zcEVpMWhnYW1xT3ZRSVdjWEJrK1NPcFVHUlpaRlh3bmlKViIKKyAgICAgICAgICAgICsgInpES1U1bkU5TVlnbjJCOUFvaUgzQ1N1TXo2SFJxZ1ZhcXRwcEllMWpodWtNYy9rSFZKdmxLUk55OVhNQ0F3RUFBVEFOQmdrcWhraUciCisgICAgICAgICAgICArICI5dzBCQVFVRkFBT0JnUUM3eUJtSjlPL2VXREd0U0g5QkgwUjNkaDJOZFNUM1c5aE5aOGhJYThVOGtsaE5IYlVDU1NrdFptWmt2YlBVIgorICAgICAgICAgICAgKyAiaHNlNUxJM2RoNlJ5TkR1cURyYll3Y3F6S2JGSmFxL2pYOWtDb2ViM3ZnYlFFbE1SWDhEMklEMXZSanh3bEFMRklTcnRhTjRWcFd6ViIKKyAgICAgICAgICAgICsgInllb0hQVzR4bGRlWm1vVnRqbjh6WE56UWhMdUJxWDJNbUFBQUFxd0FBQUFVdmtVU2Nmdzl5Q1NtQUxydVVSTm10QmFpN2tRQUFBWngiCisgICAgICAgICAgICArICI0Sm1panhzL2w4RUJhbGVhVXJ1NkVPUGlvV2tVQUVWV0N4ak0vVHhiR0hPaTJWTXNRV3FSci9EWjN3c0RtdFFndzNRVHJVSzY2NnNSIgorICAgICAgICAgICAgKyAiTUJuYnFkbnlDeXZNMUoyVjF4eExYUFVlUkJtUjJDWG9yWUdGOUR5ZTdOa2dWZGZBKzlnOUwvMEF1NlVnbisyQ2o1bGVvSWdrZ0FwTiIKKyAgICAgICAgICAgICsgInZ1RWNaZWdGbE5PVVBWRXMzU2xCZ1VGMUJZNk9CTTBVQkhUUHdHR3hGQkJjZXRjdU1SYlVudTY1dnlERzBwc2xUNTlxcGFSMFRNVnMiCisgICAgICAgICAgICArICJQK3RjaGVFemh5amJmTTMyL3Z3aG5MOWRCRWdNOHFNdDBzcUY2aXROT1FVL0Y0V0drSzJDbTJ2NENZRXlLWXczMjVmRWh6VFhvc2NrIgorICAgICAgICAgICAgKyAiTWhicW1jeUxhYjhFUGNlV0YzZHdlb1VUNzYrakVaeDhsVjJkYXBSK0NtY3pRSTQzdFY5YnRzZDF4aUJiQkhBS3Z5bW05RXA5YlB6TSIKKyAgICAgICAgICAgICsgIkowTVFpK090VVJMOUx4a2UvNzAvTVJ1ZXFiUGVVbE9hR3ZBTlRtWFFEMk9uVzdQSVN3SjlscGVMZlRHMExjcWtvcWtidExLUUxZSEkiCisgICAgICAgICAgICArICJyUWZWNWowait3bXZtcE14empOM3V2TmFqTGE0elE4bDBFb2s5U0ZhUnIyUkwwZ044UTJKZWdmT0w0cFVpSFBzaDY0V1d5YTJOQjdmIgorICAgICAgICAgICAgKyAiVisxczY1ZUE1b3NwWFlzU2hSam8wNDZRaEdUbXltd1hYemR6dXh1OElsblRFb250NlA0K0orR3NXazZjbGRHYmwyMGhjdHVVS3p5eCIKKyAgICAgICAgICAgICsgIk9wdGpFUE9LZWpWNjBpRENZR21IYkNXQXpROGg1TUlMVjgySWNsek5WaVptekFhcGVlQ25leGhwWGhXVHMreERFWVNLRWlHL2NhbXQiCisgICAgICAgICAgICArICJiaG1aYzNCY3lWSnJXMjNQa3RTZnBCUTZEOFp4b01mRjBMN1YyR1FNYVVnKzNyN3Vjcng4MmtwcW90anYweEhnaE5JbTk1YUJyMVF3IgorICAgICAgICAgICAgKyAiMWdhRWpzQy8wd0dtbUJEZzFkVERIK0YxcDlUSW56cjNFRnVZRDBZaVE3WWxBSHEzY1B1eUdvTFhKNWRYWXVTQmZoRFhKU2VkZFVrbCIKKyAgICAgICAgICAgICsgImsxdWZaeU9PY3NrZUluUWdlN2p6YVJmbUtnM1U5NHIrc3BNRXZiMEF6RFFWT0t2ampvMWl2eE1TZ0ZSWmFEYi80cXc9IjsKKworICAgIC8qKgorICAgICAqIERlZmluZXMgdGhlIGtleXN0b3JlIGNvbnRlbnRzIGZvciB0aGUgY2xpZW50LCBCS1MgdmVyc2lvbi4gSG9sZHMganVzdCBhCisgICAgICogc2luZ2xlIHNlbGYtZ2VuZXJhdGVkIGtleS4gVGhlIHN1YmplY3QgbmFtZSBpcyAiVGVzdCBDbGllbnQiLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDTElFTlRfS0VZU19CS1MgPQorICAgICAgICAgICAgIkFBQUFBUUFBQUJUNFJrYTZmeGJGcHM5OFk1azJWaWxtYmliTmtRQUFCZlFFQUFWdGVXdGxlUUFBQVJwWWwrUE9BQUFBQVFBRldDNDEiCisgICAgICAgICAgICArICJNRGtBQUFKTk1JSUNTVENDQWJLZ0F3SUJBZ0lFU0VmVTlUQU5CZ2txaGtpRzl3MEJBUVVGQURCcE1Rc3dDUVlEVlFRR0V3SlZVekVUIgorICAgICAgICAgICAgKyAiTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFTU1Bb0dBMVVFQnhNRFRWUldNUTh3RFFZRFZRUUtFd1pIYjI5bmJHVXhFREFPQmdOViIKKyAgICAgICAgICAgICsgIkJBc1RCMEZ1WkhKdmFXUXhGREFTQmdOVkJBTVRDMVJsYzNRZ1EyeHBaVzUwTUI0WERUQTRNRFl3TlRFeE5UZzBOVm9YRFRBNE1Ea3ciCisgICAgICAgICAgICArICJNekV4TlRnME5Wb3dhVEVMTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhEREFLQmdOVkJBY1RBMDFVIgorICAgICAgICAgICAgKyAiVmpFUE1BMEdBMVVFQ2hNR1IyOXZaMnhsTVJBd0RnWURWUVFMRXdkQmJtUnliMmxrTVJRd0VnWURWUVFERXd0VVpYTjBJRU5zYVdWdSIKKyAgICAgICAgICAgICsgImREQ0JuekFOQmdrcWhraUc5dzBCQVFFRkFBT0JqUUF3Z1lrQ2dZRUFwVXZtV3NRREhQcGJES0sxM1llejIvcTU0dFRPbVJtbC9xdmEiCisgICAgICAgICAgICArICIySzZkWmpralNUVzBpUnVrN3p0YVZFdmRKcGZWSUR2MW9Cc0NJNTF0dHlMSFJPeTFlcGpGK0dvTDc0bUpiN2ZrY2QwVk9vU09UanREIgorICAgICAgICAgICAgKyAiKzNHZ1prSFBBbTVZbVVZeGlKWHF4S0tKSnFNQ1RJVzQ2ZUphQTJuQWVwOVFJd1oxNC9ORkFzNE9iVjhDQXdFQUFUQU5CZ2txaGtpRyIKKyAgICAgICAgICAgICsgIjl3MEJBUVVGQUFPQmdRQ0pyQ3IzaFpRRkRsTElmc1NLSTEvdytCTHZ5ZjRmdWJPaWQwcEJ4ZmtsUjhLQk5QVGlxalNtdTdwZC9DL0YiCisgICAgICAgICAgICArICIxRlI4Q2RaVURvUGZsWkhDT1UrZmo1cjVLVUMxSHlpZ1kvdEVVdmxmb3JCcGZCMHVDRit0WFc0RGJVZk9XaGZNdExWNG5DT0pPT1pnIgorICAgICAgICAgICAgKyAiYXdmWkxKV0JKb3VMS09wNDI3dkRmdHhUU0IrS3M4WWpsZ0FBQXF3QUFBQVUrTkg2VHRyemp5RGRDWG01QjZWbzd4WDVHNFlBQUFaeCIKKyAgICAgICAgICAgICsgIkVBVWtjWnRteWtuN1lkYVl4QzFqUkZKK0dFSnBDOG5aVmc4M1FDbFZ1Q1NJUzhhNWY4SGw0NEJrNG9lcE9ac1B6aHR6M1JkVnpEVmkiCisgICAgICAgICAgICArICJSRmZveVpGc3JrOUY1YkRUVko2c1FiYi8xbmZKa0xoWkZYb2trYTB2TkQ1QVhNU29ENUJqMUZxZW0zY0s3ZlNVeXFLdkZvUktDM1hEIgorICAgICAgICAgICAgKyAiRlF2aHFvYW0yOUYxcmJsOEZhWWRQdmhoWm84VGZaUVlVeVVLd1crUmJSNDRNNWlIUHgreWtpZU1lL0MvNGJjTTN6OGN3SWJZSTFhTyIKKyAgICAgICAgICAgICsgImdqUUtTMk1LOWJzMTd4YUR6ZUFoNHNCS3Jza0ZHckRlKzJkZ3ZyU0tkb2FrSmhMVE5UQlNHNm0rcnpxTVNDZVFwYWZMS01TalRTU3oiCisgICAgICAgICAgICArICIrS29ROWJMeWF4OGNidlZpR0dqdTBTbFZocXVsb1ptS09mSHI4VHVrSW9WNjRoM3VDR0ZPVkZ0UWpDWURPcTZOYmZSdk1oMTRVVkY1IgorICAgICAgICAgICAgKyAiemdESUdjem9EOWRNb1VMV3hCbW5pR1NudG9OZ1pNK1FQNklkN0RCYXNaR0tmckhJQXczbEhCcWN2QjVzbWVtU3U3RjRpdFJvYTNEOCIKKyAgICAgICAgICAgICsgIk43aGhVRUtBYyt4QSs4TkttWGZpQ0JvSGZQSFR3RHZ0NElSN2dXamVQM1h2NXZpdGNLUS9NQWZPNVJ3ZnprWUNYUTNGZmpmem1zRTEiCisgICAgICAgICAgICArICIxSWZMUkRpQmorbGhRU3VsaFJWU3RLSTg4Q2hlM000SlVOR0tsbHJjMG50MXBXYTF2Z3ptVWhoQzRMU2RtNnRyVEhneUpuQjZPY1M5IgorICAgICAgICAgICAgKyAidDJmdXJZaks4OGoxQXVCNDkyMW94TXhSbThjNENycThQeXVmK24zWUtpOFBsMkJ6QnR3KyswZ2owT0RsZ3d1dDhTclZqNjYvbnZJQiIKKyAgICAgICAgICAgICsgImpOM2tMVmFoUjhuWnJFRkY2dlRUbXlYaTc2MXB6cTl5T1ZxSTU3d0pHeDhvM1lnb3gxcCtwV1VQbDFoUVI3cnJoVWJnSy9RNXdubzkiCisgICAgICAgICAgICArICJ1SmswN2gzSVpuTnhFKy9JS2dlTVRQL0g0K2pteVQ0bWhzZXhKMkJGSGVpS0YxS1QvRk1jSmRTaStaSzV5b05WY1l1WThhWmJ4MEVmIgorICAgICAgICAgICAgKyAibEhvckNYQW1MRkIwVzZDejRLUFAwMW5EOVlCQjRvbHhpSzF0N20wQVU5enNjZGl2Tml1VWFCNU9JRXIrSnVaNmROdz0iOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENJUEhFUl9TVUlURSA9ICJTU0xfUlNBX1dJVEhfUkM0XzEyOF9NRDUiOworICAgIC8qKgorICAgICAqIERlZmluZXMgdGhlIGtleXN0b3JlIGNvbnRlbnRzIGZvciB0aGUgc2VydmVyLCBKS1MgdmVyc2lvbi4gSG9sZHMganVzdCBhCisgICAgICogc2luZ2xlIHNlbGYtZ2VuZXJhdGVkIGtleS4gVGhlIHN1YmplY3QgbmFtZSBpcyAiVGVzdCBTZXJ2ZXIiLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRVJWRVJfS0VZU19KS1MgPQorICAgICAgICAgICAgIi91Mys3UUFBQUFJQUFBQUJBQUFBQVFBRmJYbHJaWGtBQUFFYVdGZkJlQUFBQXJvd2dnSzJNQTRHQ2lzR0FRUUJLZ0lSQVFFRkFBU0MiCisgICAgICAgICAgICArICJBcUkya3A1WGpuRjhZWmtoY0Y5MllzSk5Ra3ZzbUg3enFNTTg3ajIzelNvVjREd3lFM1hlQy9nWldxMVRvU2NJaG9xWmt6bGJXY3U0IgorICAgICAgICAgICAgKyAiVC9aZmMvRHJmR2svcktiQkwxdVdLR1o4Zk10bFprOEtvQWh4WmsxSlN5SnZka3lLeHFtelVieGsxT0ZNbE4yVkpOdTk3RlBWSCtkdSIKKyAgICAgICAgICAgICsgImR2alR2bXBkb004MUlOV0JXLzFmWkplUWVEdm40bU1iYmUwSXhncGlMbkk5V1NldmxhRFAvc20xWDNpTzl5RXl6SExMK001RXJzcG8iCisgICAgICAgICAgICArICJDd2E1NThmT3U1RGRzSUNNWGh2RFF4aldGS0ZoUEhuS3RHZStWdndrRzkvYkFhRGd4M2tmaGswdzV6dmRua0tiKzhFZDl5bE5SemRrIgorICAgICAgICAgICAgKyAib2NBYS9teGxNVE9zVHZES1hqanNCdXBOUElJajdPUDRHTm5aYXhrSmpTczk4cEVPNjdvcDFHWDJxaHk2RlNPUE51cThrLzY1SHpVYyIKKyAgICAgICAgICAgICsgIlBZbjZ2b0VlaDZ2bTAyVS9zakVuelJldlEyKzJ3WG9BZHAwRXd0US9EbE1lK052Y3dQR1dLdU1nWDRBNEw5M0RaR2IwNE4yVm1BVTMiCisgICAgICAgICAgICArICJZTE90WndUTzBMYnVXcmNDTS9xOTlHLzdMY2N6a3hJVnJPMkkvcmg4UlhWY3psZjlRemNyRk9iRnY0QVR1c3BXSjh4RzdEaHNNYm5rIgorICAgICAgICAgICAgKyAiclQ5NFBxNlRvZ1llb3o4bzhaTXlrZXNBcU42bXQvOStUb0llbW1YditlK0tVMWhJNW9Md1dNblVHNmRYTTZoSXZyVUxZNm8rUUNQSCIKKyAgICAgICAgICAgICsgIjE3MllRSk1hKzY4SEFlUytpdEJUQUY0Q2xtL2JMbjZyZUhDR0dVNnZOZHdVMGxZbGRwaU9qOWNCM3QrdTJVdUxvNnRpRldqTGY1WnMiCisgICAgICAgICAgICArICJFUUpFVGQ0Zy9FSzluSHhKbjBHQUtyV25UdzdwRUhRSjA4ZWx6VXV5MDRDL2pFRUcrNFFYVTFJbnpTNG8va1IwU3F6MldUR0RvU29xIgorICAgICAgICAgICAgKyAiZXd1UFJVNWJ6UXMvYjlkYXEzbVhyblB0UkJMNkhmU0RBZHBUSzc2aUhxTENHZHF4M2F2SGpWU0JtNHpGdkV1WUJDZXYrM2lLT0JtZyIKKyAgICAgICAgICAgICsgInloN2VRUlRqejRVT1dmeTg1b21NQnI3bEs4UHRmVkJEek9YcGFzeFMwdUJnZFV5QkRYNHRPNms5alo4YTFrbVFSUUFBQUFFQUJWZ3UiCisgICAgICAgICAgICArICJOVEE1QUFBQ1NEQ0NBa1F3Z2dHdEFnUklSOFNLTUEwR0NTcUdTSWIzRFFFQkJBVUFNR2t4Q3pBSkJnTlZCQVlUQWxWVE1STXdFUVlEIgorICAgICAgICAgICAgKyAiVlFRSUV3cERZV3hwWm05eWJtbGhNUXd3Q2dZRFZRUUhFd05OVkZZeER6QU5CZ05WQkFvVEJrZHZiMmRzWlRFUU1BNEdBMVVFQ3hNSCIKKyAgICAgICAgICAgICsgIlFXNWtjbTlwWkRFVU1CSUdBMVVFQXhNTFZHVnpkQ0JUWlhKMlpYSXdIaGNOTURnd05qQTFNVEEwT0RReVdoY05NRGd3T1RBek1UQTAiCisgICAgICAgICAgICArICJPRFF5V2pCcE1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFTU1Bb0dBMVVFQnhNRFRWUldNUTh3IgorICAgICAgICAgICAgKyAiRFFZRFZRUUtFd1pIYjI5bmJHVXhFREFPQmdOVkJBc1RCMEZ1WkhKdmFXUXhGREFTQmdOVkJBTVRDMVJsYzNRZ1UyVnlkbVZ5TUlHZiIKKyAgICAgICAgICAgICsgIk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FDd29DNmNocUNJODRyajFQclh1SmdiaWl0NEVWOTA5elI2TjBqTmxZZmciCisgICAgICAgICAgICArICJpdHdCMzliUDM5d0gwM3JGbThUNTliM21iU3B0bkdtQ0lwTFpuMjVLUFBGc1lEM0pKK3dGbG1pVWRFUDlIMDVmbGZ3dEZRSm53OXVUIgorICAgICAgICAgICAgKyAiM3JSSWRZVk1QY1EzUm9aendBTWxpR3I4ODJJMnRoSURiQTZ4akdVLzFuUklkdmswTHR4SDNRSURBUUFCTUEwR0NTcUdTSWIzRFFFQiIKKyAgICAgICAgICAgICsgIkJBVUFBNEdCQUpuKzZZZ1VsWTE4SWUrMCtWdDhvRWk4MUROaS9iZlByQVVBaDYzZmhoQmlreC8zUjlkbDN3aDA5WjZwN2NJZE54alciCisgICAgICAgICAgICArICJuMmxsK2NSVzllcUY3ejc1RjBPbW0wQzcvS0FFUGp1a1Zic3ptemVVNVZxemtwU3Qwajg0WVdpK1RmY0hScmZ2aExicmxtR0lUVnBZIgorICAgICAgICAgICAgKyAib2w1cEhMRHlxR21EczUzcGd3aXBXcXNuL25FWEVCZ2ozRW9xUGVxSGJEZjdZYVA4aC81QlN0MD0iOworCisgICAgLyoqCisgICAgICogRGVmaW5lcyB0aGUga2V5c3RvcmUgY29udGVudHMgZm9yIHRoZSBjbGllbnQsIEpLUyB2ZXJzaW9uLiBIb2xkcyBqdXN0IGEKKyAgICAgKiBzaW5nbGUgc2VsZi1nZW5lcmF0ZWQga2V5LiBUaGUgc3ViamVjdCBuYW1lIGlzICJUZXN0IENsaWVudCIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENMSUVOVF9LRVlTX0pLUyA9CisgICAgICAgICAgICAiL3UzKzdRQUFBQUlBQUFBQkFBQUFBUUFGYlhsclpYa0FBQUVhV0ZoeU1BQUFBcmt3Z2dLMU1BNEdDaXNHQVFRQktnSVJBUUVGQUFTQyIKKyAgICAgICAgICAgICsgIkFxR1ZTZlhvbEJTdFp5NG5uUk5uNGZBcitTN2tmVTJCUzIzd3dXOHVCMlJ1M0d2dEx6bEs5cTA4R3ZxL0xOcUJhZmp5RlRWTDVGVjUiCisgICAgICAgICAgICArICJTRUQvOFlvbU81YTk4R3Bza1NlUnZ5dENpVEJMSmRnR2h3czVUT0dla2dJQWNCUk9QR0l5T3RKUFEwSGZPUXMrQnFnekdESHpIUWh3IgorICAgICAgICAgICAgKyAidS84VG02eVF3aVArVy8xSTlCMVFuYUV6dFpBM21oVHlNTUpzbXNGVFlyb0dnQW9nODg1RDVDbXpkOHNZR2Z4ZWMzUjZJK3hjbUJBWSIKKyAgICAgICAgICAgICsgImVpYlI1a0dwV3d0MVIrcU12UnJ0QnFoNXI2V1NLaENCTmF4K1NKVmJ0VU5SaUt5aktjY2RKZzZmR3FJV1dlaXZ3WVR5ME9oakE2YjQiCisgICAgICAgICAgICArICJOaVovWlpzNXB4RkdXVWovUmxwMFJZeThmQ0Y2YXc1LzVzNEJmNE1JNmRQU3FNRzhIZjdzSlI5MUdiY0VMeXpQZE0waDVsTmF2Z2l0IgorICAgICAgICAgICAgKyAiUVBFektldURyR3hoWTFmckpUaEJzTnNTMGd4ZXUrT2dmSlBFYi9INGxwWVg1SXZ1SUdiV0tjeG9POXpxNC9maW1JWmtkQThBKzNlWSIKKyAgICAgICAgICAgICsgIm1mRGFvd3Z5NjVOQlZRUEpTeGFPeUZoTEhmZUxxT2VDc1ZFTkFlYTAydkE3YW5kWkhUWmVodmNycXlLdG0rejhuY0hHUkMySDlIOE8iCisgICAgICAgICAgICArICJqS3dLSGZ4eHJZWS9qTUFLTGwwMCtQQmIza3NwTytCSEkyRWNRblF1TXcvenI4M09SOU1lcTRUSjBUTXVOa0FwWkVMQWVGY2tJQmJTIgorICAgICAgICAgICAgKyAickJyOE5OakFJZmp1Q1R1S0hoc1RGV2lIZms5Wkl6aWd4WGFnZmVEUml5VmM2a2hPdUYvYkdvcmoyM04ybzdSZjN1TG9VNlB5WFdpNCIKKyAgICAgICAgICAgICsgInVoY3RSMWFMNk56eERvSzJQYllDZUE5aHhiRHY4ZW1hVlBJemxWd3BQSzNSdXZ2OW1ramNPaFo3NEo4YlBLMmZRbWJwbGJPbGpjWmkiCisgICAgICAgICAgICArICJ0WmlqT2Z6Y08vMTFKcndodUpaUkE2d2FuVHFIb3VqZ0NoVjlFdWtWcm1iV0dHQWNld0ZuQXNTYkZYSWlrNy8rUXpuWGFESXQ1TmdMIgorICAgICAgICAgICAgKyAiSC9CY3o0Wi9mZFY3QWUxZVVheEtYZFBiSS8vNEorOGxpVlQvZDhhd2pXMnRsZElhRGxtR01SM2FvYzgzMCszbUFBQUFBUUFGV0M0MSIKKyAgICAgICAgICAgICsgIk1Ea0FBQUpJTUlJQ1JEQ0NBYTBDQkVoSHhMZ3dEUVlKS29aSWh2Y05BUUVFQlFBd2FURUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlYiCisgICAgICAgICAgICArICJCQWdUQ2tOaGJHbG1iM0p1YVdFeEREQUtCZ05WQkFjVEEwMVVWakVQTUEwR0ExVUVDaE1HUjI5dloyeGxNUkF3RGdZRFZRUUxFd2RCIgorICAgICAgICAgICAgKyAiYm1SeWIybGtNUlF3RWdZRFZRUURFd3RVWlhOMElFTnNhV1Z1ZERBZUZ3MHdPREEyTURVeE1EUTVNamhhRncwd09EQTVNRE14TURRNSIKKyAgICAgICAgICAgICsgIk1qaGFNR2t4Q3pBSkJnTlZCQVlUQWxWVE1STXdFUVlEVlFRSUV3cERZV3hwWm05eWJtbGhNUXd3Q2dZRFZRUUhFd05OVkZZeER6QU4iCisgICAgICAgICAgICArICJCZ05WQkFvVEJrZHZiMmRzWlRFUU1BNEdBMVVFQ3hNSFFXNWtjbTlwWkRFVU1CSUdBMVVFQXhNTFZHVnpkQ0JEYkdsbGJuUXdnWjh3IgorICAgICAgICAgICAgKyAiRFFZSktvWklodmNOQVFFQkJRQURnWTBBTUlHSkFvR0JBSUszUStLaUZibUNHZzQyMlRBbzRnZ2dkaE1INkZKaGl1ejhEeFJ5ZU1LUiIKKyAgICAgICAgICAgICsgIlVBZlA0TUswd3RjOE40MndhWjZPS3Z4cEJGVXkwQlJmQnNYMEdENEt1OTl5dTkvdGF2U2lnVHJhZUp0d1YzV1dSUmpJcWs3TDN3WDUiCisgICAgICAgICAgICArICJjbWdTMktTRDQzWTByTlVLcmtvMjZsbnQ5TjRxaVlSQlNqK3RjQU4zTHg5K3B0cWsxTEFwQWdNQkFBRXdEUVlKS29aSWh2Y05BUUVFIgorICAgICAgICAgICAgKyAiQlFBRGdZRUFOYjdRMUdWU3V5MVJQSjBGbWlYb01ZQ0N0dmxSTGttSnBod3hvdkswY0FRSzEyVmxsK3lBekJoSGlRSHkvUkExMW1uZyIKKyAgICAgICAgICAgICsgIndZdWRDN3UzUDhYL3RCVDhHUjFZazdRVzNLZ0Z5UGFmcDNsUUJCQ3JhU3NmcmpLaitkQ0xpZzF1QkxVcjRmNjhXOFZGV1pXV1RIcXAiCisgICAgICAgICAgICArICJOTUdwQ1g2cW1qYmtKUUxWSy9ZZm8xZVBhVWV4UFNPWDBHOW04K0RvVjNpeU53NmF0MDFOUnc9PSI7CisKKworICAgIGludCBwb3J0OworICAgIFNTTFNvY2tldCBzZXJ2ZXJTb2NrZXQ7CisgICAgTXlIYW5kc2hha2VMaXN0ZW5lciBsaXN0ZW5lcjsKKyAgICBTdHJpbmcgaG9zdCA9ICJsb2NhbGhvc3QiOworICAgIGJvb2xlYW4gbm90RmluaXNoZWQgPSB0cnVlOworICAgIFNTTFNlc3Npb24gY2xpZW50U2Vzc2lvbiA9IG51bGw7CisgICAgU1NMQ29udGV4dCBjbGllbnRTc2xDb250ZXh0ID0gbnVsbDsKKyAgICBTdHJpbmcgdGVzdERhdGEgPSAiUElORyI7CisKKyAgICBwcml2YXRlIFN0cmluZyBQQVNTV09SRCA9ICJhbmRyb2lkIjsKKworICAgIC8qKgorICAgICAqIEltcGxlbWVudHMgYSB0ZXN0IFNTTCBzb2NrZXQgc2VydmVyLiBJdCB3YWl0cyBmb3IgYSBjb25uZWN0aW9uIG9uIGEgZ2l2ZW4KKyAgICAgKiBwb3J0LCByZXF1ZXN0cyBjbGllbnQgYXV0aGVudGljYXRpb24gKGlmIHNwZWNpZmllZCksIHJlYWRzIGZyb20gdGhlIHNvY2tldCwKKyAgICAgKiBhbmQgd3JpdGVzIHRvIHRoZSBzb2NrZXQuCisgICAgICovCisgICAgY2xhc3MgVGVzdFNlcnZlciBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTElFTlRfQVVUSF9OT05FID0gMDsKKworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTElFTlRfQVVUSF9XQU5URUQgPSAxOworCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMSUVOVF9BVVRIX05FRURFRCA9IDI7CisKKyAgICAgICAgcHJpdmF0ZSBUZXN0VHJ1c3RNYW5hZ2VyIHRydXN0TWFuYWdlcjsKKworICAgICAgICBwcml2YXRlIEV4Y2VwdGlvbiBleGNlcHRpb247CisKKyAgICAgICAgU3RyaW5nIGtleXM7CisKKyAgICAgICAgcHJpdmF0ZSBpbnQgY2xpZW50QXV0aDsKKworICAgICAgICBwcml2YXRlIGJvb2xlYW4gcHJvdmlkZUtleXM7CisKKyAgICAgICAgcHJpdmF0ZSBLZXlTdG9yZSBzdG9yZTsKKworICAgICAgICBwdWJsaWMgVGVzdFNlcnZlcihib29sZWFuIHByb3ZpZGVLZXlzLCBpbnQgY2xpZW50QXV0aCwgU3RyaW5nIGtleXMpIHsKKyAgICAgICAgICAgIHRoaXMua2V5cyA9IGtleXM7CisgICAgICAgICAgICB0aGlzLmNsaWVudEF1dGggPSBjbGllbnRBdXRoOworICAgICAgICAgICAgdGhpcy5wcm92aWRlS2V5cyA9IHByb3ZpZGVLZXlzOworCisgICAgICAgICAgICB0cnVzdE1hbmFnZXIgPSBuZXcgVGVzdFRydXN0TWFuYWdlcigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdG9yZSA9IHByb3ZpZGVLZXlzID8gZ2V0S2V5U3RvcmUoa2V5cykgOiBudWxsOworICAgICAgICAgICAgICAgIEtleU1hbmFnZXJbXSBrZXlNYW5hZ2VycyA9IHN0b3JlICE9IG51bGwgPyBnZXRLZXlNYW5hZ2VycyhzdG9yZSkgOiBudWxsOworICAgICAgICAgICAgICAgIFRydXN0TWFuYWdlcltdIHRydXN0TWFuYWdlcnMgPSBuZXcgVHJ1c3RNYW5hZ2VyW10geyB0cnVzdE1hbmFnZXIgfTsKKworICAgICAgICAgICAgICAgIFNTTENvbnRleHQgc3NsQ29udGV4dCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UoIlRMUyIpOworICAgICAgICAgICAgICAgIHNzbENvbnRleHQuaW5pdChrZXlNYW5hZ2VycywgdHJ1c3RNYW5hZ2VycywgbnVsbCk7CisKKyAgICAgICAgICAgICAgICBTU0xTZXJ2ZXJTb2NrZXQgc2VydmVyU29ja2V0ID0gKFNTTFNlcnZlclNvY2tldClzc2xDb250ZXh0CisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0U2VydmVyU29ja2V0RmFjdG9yeSgpLmNyZWF0ZVNlcnZlclNvY2tldCgpOworCisgICAgICAgICAgICAgICAgaWYgKGNsaWVudEF1dGggPT0gQ0xJRU5UX0FVVEhfV0FOVEVEKSB7CisgICAgICAgICAgICAgICAgICAgIHNlcnZlclNvY2tldC5zZXRXYW50Q2xpZW50QXV0aCh0cnVlKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNsaWVudEF1dGggPT0gQ0xJRU5UX0FVVEhfTkVFREVEKSB7CisgICAgICAgICAgICAgICAgICAgIHNlcnZlclNvY2tldC5zZXROZWVkQ2xpZW50QXV0aCh0cnVlKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQuc2V0V2FudENsaWVudEF1dGgoZmFsc2UpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHNlcnZlclNvY2tldC5iaW5kKG5ldyBJbmV0U29ja2V0QWRkcmVzcyhwb3J0KSk7CisKKyAgICAgICAgICAgICAgICBTU0xTb2NrZXQgY2xpZW50U29ja2V0ID0gKFNTTFNvY2tldClzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisKKyAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBpc3RyZWFtID0gY2xpZW50U29ja2V0LmdldElucHV0U3RyZWFtKCk7CisgICAgICAgICAgICAgICAgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlWzEwMjRdOworICAgICAgICAgICAgICAgIGlzdHJlYW0ucmVhZChidWZmZXIpOworCisgICAgICAgICAgICAgICAgT3V0cHV0U3RyZWFtIG9zdHJlYW0gPSBjbGllbnRTb2NrZXQuZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICAgICAgb3N0cmVhbS53cml0ZSh0ZXN0RGF0YS5nZXRCeXRlcygpKTsKKyAgICAgICAgICAgICAgICBvc3RyZWFtLmZsdXNoKCk7CisKKyAgICAgICAgICAgICAgICB3aGlsZSAobm90RmluaXNoZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5zbGVlcCg1MDApOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGNsaWVudFNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgICAgIHNlcnZlclNvY2tldC5jbG9zZSgpOworCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBleDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFeGNlcHRpb24gZ2V0RXhjZXB0aW9uKCkgeworICAgICAgICAgICAgcmV0dXJuIGV4Y2VwdGlvbjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBqYXZheC5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZVtdIGdldENoYWluKCkgeworICAgICAgICAgICAgcmV0dXJuIHRydXN0TWFuYWdlci5nZXRDaGFpbigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEtleVN0b3JlIGdldFN0b3JlKCkgeworICAgICAgICAgICAgcmV0dXJuIHN0b3JlOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbXBsZW1lbnRzIGEgdGVzdCBTU0wgc29ja2V0IGNsaWVudC4gSXQgb3BlbnMgYSBjb25uZWN0aW9uIHRvIGxvY2FsaG9zdCBvbgorICAgICAqIGEgZ2l2ZW4gcG9ydCwgd3JpdGVzIHRvIHRoZSBzb2NrZXQsIGFuZCByZWFkcyBmcm9tIHRoZSBzb2NrZXQuCisgICAgICovCisgICAgY2xhc3MgVGVzdENsaWVudCBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKworICAgICAgICBwcml2YXRlIFRlc3RUcnVzdE1hbmFnZXIgdHJ1c3RNYW5hZ2VyOworCisgICAgICAgIHByaXZhdGUgRXhjZXB0aW9uIGV4Y2VwdGlvbjsKKworICAgICAgICBwcml2YXRlIFN0cmluZyBrZXlzOworCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBwcm92aWRlS2V5czsKKworICAgICAgICBwcml2YXRlIEtleVN0b3JlIHN0b3JlOworCisgICAgICAgIHB1YmxpYyBUZXN0Q2xpZW50KGJvb2xlYW4gcHJvdmlkZUtleXMsIFN0cmluZyBrZXlzKSB7CisgICAgICAgICAgICB0aGlzLmtleXMgPSBrZXlzOworICAgICAgICAgICAgdGhpcy5wcm92aWRlS2V5cyA9IHByb3ZpZGVLZXlzOworCisgICAgICAgICAgICB0cnVzdE1hbmFnZXIgPSBuZXcgVGVzdFRydXN0TWFuYWdlcigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdG9yZSA9IHByb3ZpZGVLZXlzID8gZ2V0S2V5U3RvcmUoa2V5cykgOiBudWxsOworICAgICAgICAgICAgICAgIEtleU1hbmFnZXJbXSBrZXlNYW5hZ2VycyA9IHN0b3JlICE9IG51bGwgPyBnZXRLZXlNYW5hZ2VycyhzdG9yZSkgOiBudWxsOworICAgICAgICAgICAgICAgIFRydXN0TWFuYWdlcltdIHRydXN0TWFuYWdlcnMgPSBuZXcgVHJ1c3RNYW5hZ2VyW10geyB0cnVzdE1hbmFnZXIgfTsKKworICAgICAgICAgICAgICAgIGNsaWVudFNzbENvbnRleHQgPSBTU0xDb250ZXh0LmdldEluc3RhbmNlKCJUTFMiKTsKKyAgICAgICAgICAgICAgICBjbGllbnRTc2xDb250ZXh0LmluaXQoa2V5TWFuYWdlcnMsIHRydXN0TWFuYWdlcnMsIG51bGwpOworCisgICAgICAgICAgICAgICAgU1NMU29ja2V0IHNvY2tldCA9IChTU0xTb2NrZXQpY2xpZW50U3NsQ29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCkuY3JlYXRlU29ja2V0KCk7CisKKyAgICAgICAgICAgICAgICBzb2NrZXQuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MocG9ydCkpOworICAgICAgICAgICAgICAgIE91dHB1dFN0cmVhbSBvc3RyZWFtID0gc29ja2V0LmdldE91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgIG9zdHJlYW0ud3JpdGUodGVzdERhdGEuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICAgICAgb3N0cmVhbS5mbHVzaCgpOworCisgICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXN0cmVhbSA9IHNvY2tldC5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVsxMDI0XTsKKyAgICAgICAgICAgICAgICBpc3RyZWFtLnJlYWQoYnVmZmVyKTsKKworICAgICAgICAgICAgICAgIGNsaWVudFNlc3Npb24gPSBzb2NrZXQuZ2V0U2Vzc2lvbigpOworICAgICAgICAgICAgICAgIHdoaWxlIChub3RGaW5pc2hlZCkgeworICAgICAgICAgICAgICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLnNsZWVwKDUwMCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpOworCisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBleDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBFeGNlcHRpb24gZ2V0RXhjZXB0aW9uKCkgeworICAgICAgICAgICAgcmV0dXJuIGV4Y2VwdGlvbjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBqYXZheC5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZVtdIGdldENoYWluKCkgeworICAgICAgICAgICAgcmV0dXJuIHRydXN0TWFuYWdlci5nZXRDaGFpbigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEtleVN0b3JlIGdldFN0b3JlKCkgeworICAgICAgICAgICAgcmV0dXJuIHN0b3JlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9hZHMgYSBrZXlzdG9yZSBmcm9tIGEgYmFzZTY0LWVuY29kZWQgU3RyaW5nLiBSZXR1cm5zIHRoZSBLZXlNYW5hZ2VyW10KKyAgICAgKiBmb3IgdGhlIHJlc3VsdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIEtleVN0b3JlIGdldEtleVN0b3JlKFN0cmluZyBrZXlzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIGJ5dGVzID0gQmFzZTY0LmRlY29kZShrZXlzLmdldEJ5dGVzKCkpOworICAgICAgICBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcyk7CisKKyAgICAgICAgS2V5U3RvcmUga2V5U3RvcmUgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAga2V5U3RvcmUubG9hZChpbnB1dFN0cmVhbSwgUEFTU1dPUkQudG9DaGFyQXJyYXkoKSk7CisgICAgICAgIGlucHV0U3RyZWFtLmNsb3NlKCk7CisgICAgICAgIHJldHVybiBrZXlTdG9yZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2FkcyBhIGtleXN0b3JlIGZyb20gYSBiYXNlNjQtZW5jb2RlZCBTdHJpbmcuIFJldHVybnMgdGhlIEtleU1hbmFnZXJbXQorICAgICAqIGZvciB0aGUgcmVzdWx0LgorICAgICAqLworICAgIHByaXZhdGUgS2V5TWFuYWdlcltdIGdldEtleU1hbmFnZXJzKEtleVN0b3JlIGtleVN0b3JlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGFsZ29yaXRobSA9IEtleU1hbmFnZXJGYWN0b3J5LmdldERlZmF1bHRBbGdvcml0aG0oKTsKKyAgICAgICAgS2V5TWFuYWdlckZhY3Rvcnkga2V5TWFuYWdlckZhY3RvcnkgPSBLZXlNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShhbGdvcml0aG0pOworICAgICAgICBrZXlNYW5hZ2VyRmFjdG9yeS5pbml0KGtleVN0b3JlLCBQQVNTV09SRC50b0NoYXJBcnJheSgpKTsKKworICAgICAgICByZXR1cm4ga2V5TWFuYWdlckZhY3RvcnkuZ2V0S2V5TWFuYWdlcnMoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMU29ja2V0RmFjdG9yeVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvbmV0L3NzbC9TU0xTb2NrZXRGYWN0b3J5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAyYWJjYzIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMU29ja2V0RmFjdG9yeVRlc3QuamF2YQpAQCAtMCwwICsxLDE0MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuVW5rbm93bkhvc3RFeGNlcHRpb247CisKK2ltcG9ydCBqYXZheC5uZXQuU29ja2V0RmFjdG9yeTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3Rvcnk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfUG9ydE1hbmFnZXI7CisKK3B1YmxpYyBjbGFzcyBTU0xTb2NrZXRGYWN0b3J5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgU2VydmVyU29ja2V0IHNzOworCisgICAgcHJvdGVjdGVkIGludCBzdGFydFNlcnZlcihTdHJpbmcgbmFtZSkgeworICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzID0gbmV3IFNlcnZlclNvY2tldChwb3J0TnVtYmVyKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChuYW1lICsgIjogIiArIGUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzcy5nZXRMb2NhbFBvcnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3RvcnkjU1NMU29ja2V0RmFjdG9yeSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldEZhY3Rvcnkgc2YgPSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoc2YgaW5zdGFuY2VvZiBTU0xTb2NrZXRGYWN0b3J5KTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTb2NrZXRGYWN0b3J5I2dldERlZmF1bHQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGVmYXVsdCgpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiSW5jb3JyZWN0IGRlZmF1bHQgc29ja2V0IGZhY3RvcnkiLAorICAgICAgICAgICAgICAgIFNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3RvcnkjY3JlYXRlU29ja2V0KFNvY2tldCBzLCBTdHJpbmcgaG9zdCwgaW50IHBvcnQsIGJvb2xlYW4gYXV0b0Nsb3NlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY3JlYXRlU29ja2V0KCkgeworICAgICAgICBTU0xTb2NrZXRGYWN0b3J5IHNmID0gKFNTTFNvY2tldEZhY3RvcnkpU1NMU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCk7CisgICAgICAgIGludCBzcG9ydCA9IHN0YXJ0U2VydmVyKCJ0ZXN0X2NyZWF0ZVNvY2tldCgpIik7CisgICAgICAgIGludFtdIGludmFsaWQgPSB7CisgICAgICAgICAgICAgICAgSW50ZWdlci5NSU5fVkFMVUUsIC0xLCA2NTUzNiwgSW50ZWdlci5NQVhfVkFMVUUKKyAgICAgICAgfTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldCBzdCA9IG5ldyBTb2NrZXQoImxvY2FsaG9zdCIsIHNwb3J0KTsKKyAgICAgICAgICAgIFNvY2tldCBzID0gc2YuY3JlYXRlU29ja2V0KHN0LCAibG9jYWxob3N0Iiwgc3BvcnQsIGZhbHNlKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHMuaXNDbG9zZWQoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGV4KTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgU29ja2V0IHN0ID0gbmV3IFNvY2tldCgibG9jYWxob3N0Iiwgc3BvcnQpOworICAgICAgICAgICAgU29ja2V0IHMgPSBzZi5jcmVhdGVTb2NrZXQoc3QsICJsb2NhbGhvc3QiLCBzcG9ydCwgdHJ1ZSk7CisgICAgICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHN0LmlzQ2xvc2VkKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBleCk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNmLmNyZWF0ZVNvY2tldChudWxsLCAibG9jYWxob3N0Iiwgc3BvcnQsIHRydWUpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFNvY2tldCBzID0gc2YuY3JlYXRlU29ja2V0KG5ldyBTb2NrZXQoKSwgImxvY2FsaG9zdCIsIDEwODAsIGZhbHNlKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNvY2tldCBzdCA9IG5ldyBTb2NrZXQoImJsYS1ibGEiLCBzcG9ydCk7CisgICAgICAgICAgICBTb2NrZXQgcyA9IHNmLmNyZWF0ZVNvY2tldChzdCwgImJsYS1ibGEiLCBzcG9ydCwgZmFsc2UpOworICAgICAgICAgICAgZmFpbCgiVW5rbm93bkhvc3RFeGNlcHRpb24gd2Fzbid0IHRocm93bjogIiArICJibGEtYmxhIik7CisgICAgICAgIH0gY2F0Y2ggKFVua25vd25Ib3N0RXhjZXB0aW9uIHVoZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIFVua25vd25Ib3N0RXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3RvcnkjZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREZWZhdWx0Q2lwaGVyU3VpdGVzKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMU29ja2V0RmFjdG9yeSBzZiA9IChTU0xTb2NrZXRGYWN0b3J5KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIm5vIGRlZmF1bHQgY2lwaGVyIHN1aXRlcyByZXR1cm5lZCIsCisgICAgICAgICAgICAgICAgICAgIHNmLmdldERlZmF1bHRDaXBoZXJTdWl0ZXMoKS5sZW5ndGggPiAwKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTb2NrZXRGYWN0b3J5I2dldFN1cHBvcnRlZENpcGhlclN1aXRlcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTU0xTb2NrZXRGYWN0b3J5IHNmID0gKFNTTFNvY2tldEZhY3RvcnkpIFNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgibm8gc3VwcG9ydGVkIGNpcGhlciBzdWl0ZXMgcmV0dXJuZWQiLAorICAgICAgICAgICAgICAgICAgICBzZi5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKS5sZW5ndGggPiAwKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvU1NMU29ja2V0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1NTTFNvY2tldFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYjYwZjcyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1NTTFNvY2tldFRlc3QuamF2YQpAQCAtMCwwICsxLDY0MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5BbmRyb2lkT25seTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0U29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YXgubmV0LnNzbC5IYW5kc2hha2VDb21wbGV0ZWRFdmVudDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLkhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleU1hbmFnZXJGYWN0b3J5OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMQ29udGV4dDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXI7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGxpYmNvcmUuaW8uQmFzZTY0OworaW1wb3J0IHRlc3RzLmFwaS5qYXZheC5uZXQuc3NsLkhhbmRzaGFrZUNvbXBsZXRlZEV2ZW50VGVzdC5UZXN0VHJ1c3RNYW5hZ2VyOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Qb3J0TWFuYWdlcjsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuU3RhbmRhcmROYW1lczsKKworcHVibGljIGNsYXNzIFNTTFNvY2tldFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgY2xhc3MgSGFuZHNoYWtlQ0wgaW1wbGVtZW50cyBIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lciB7CisgICAgICAgIHB1YmxpYyB2b2lkIGhhbmRzaGFrZUNvbXBsZXRlZChIYW5kc2hha2VDb21wbGV0ZWRFdmVudCBldmVudCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjU1NMU29ja2V0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RydWN0b3JfMDEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMU29ja2V0IHNzbCA9IGdldFNTTFNvY2tldCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKHNzbCk7CisgICAgICAgIHNzbC5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0I1NTTFNvY2tldChJbmV0QWRkcmVzcyBhZGRyZXNzLCBpbnQgcG9ydCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RydWN0b3JfMDIoKSB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHNwb3J0ID0gc3RhcnRTZXJ2ZXIoIkNvbnMgSW5ldEFkZHJlc3MsSSIpOworICAgICAgICBpbnRbXSBpbnZhbGlkUG9ydCA9IHstMSwgSW50ZWdlci5NSU5fVkFMVUUsIDY1NTM2LCBJbnRlZ2VyLk1BWF9WQUxVRX07CisKKyAgICAgICAgU1NMU29ja2V0IHNzbCA9IGdldFNTTFNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgc3BvcnQpOworICAgICAgICBhc3NlcnROb3ROdWxsKHNzbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhzcG9ydCwgc3NsLmdldFBvcnQoKSk7CisgICAgICAgIHNzbC5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBnZXRTU0xTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHNwb3J0ICsgMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRQb3J0Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGdldFNTTFNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgaW52YWxpZFBvcnRbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjU1NMU29ja2V0KEluZXRBZGRyZXNzIGFkZHJlc3MsIGludCBwb3J0LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MgY2xpZW50QWRkcmVzcywgaW50IGNsaWVudFBvcnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENvbnN0cnVjdG9yXzAzKCkgdGhyb3dzIFVua25vd25Ib3N0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBzcG9ydCA9IHN0YXJ0U2VydmVyKCJDb25zIEluZXRBZGRyZXNzLEksSW5ldEFkZHJlc3MsSSIpOworICAgICAgICBpbnQgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKworICAgICAgICBTU0xTb2NrZXQgc3NsID0gZ2V0U1NMU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBzcG9ydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgcG9ydE51bWJlcik7CisgICAgICAgIGFzc2VydE5vdE51bGwoc3NsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNwb3J0LCBzc2wuZ2V0UG9ydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHBvcnROdW1iZXIsIHNzbC5nZXRMb2NhbFBvcnQoKSk7CisgICAgICAgIHNzbC5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBnZXRTU0xTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIDgwODEsIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCA4MDgyKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBnZXRTU0xTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIC0xLCBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgc3BvcnQgKyAxKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGdldFNTTFNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgc3BvcnQsIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCAtMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGdldFNTTFNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgSW50ZWdlci5NSU5fVkFMVUUsCisgICAgICAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHNwb3J0ICsgMSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4cGVjdGVkT25SSSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShTdGFuZGFyZE5hbWVzLklTX1JJKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkT25BbmRyb2lkKSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShTdGFuZGFyZE5hbWVzLklTX1JJKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZ2V0U1NMU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLCBzcG9ydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgSW50ZWdlci5NQVhfVkFMVUUpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWRPbkFuZHJvaWQpIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKFN0YW5kYXJkTmFtZXMuSVNfUkkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjU1NMU29ja2V0KFN0cmluZyBob3N0LCBpbnQgcG9ydCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RydWN0b3JfMDQoKSB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHNwb3J0ID0gc3RhcnRTZXJ2ZXIoIkNvbnMgU3RyaW5nLEkiKTsKKyAgICAgICAgaW50W10gaW52YWxpZFBvcnQgPSB7LTEsIEludGVnZXIuTUlOX1ZBTFVFLCA2NTUzNiwgSW50ZWdlci5NQVhfVkFMVUV9OworCisgICAgICAgIFNTTFNvY2tldCBzc2wgPSBnZXRTU0xTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCkuZ2V0SG9zdE5hbWUoKSwgc3BvcnQpOworICAgICAgICBhc3NlcnROb3ROdWxsKHNzbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhzcG9ydCwgc3NsLmdldFBvcnQoKSk7CisgICAgICAgIHNzbC5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBnZXRTU0xTb2NrZXQoImxvY2FsaG9zdCIsIDgwODIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkUG9ydC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBnZXRTU0xTb2NrZXQoSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCkuZ2V0SG9zdE5hbWUoKSwgaW52YWxpZFBvcnRbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGdldFNTTFNvY2tldCgiYmxhLWJsYSIsIHNwb3J0KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0I1NTTFNvY2tldChTdHJpbmcgaG9zdCwgaW50IHBvcnQsIEluZXRBZGRyZXNzIGNsaWVudEFkZHJlc3MsCisgICAgICogICAgICAgICAgIGludCBjbGllbnRQb3J0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25zdHJ1Y3Rvcl8wNSgpIHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgc3BvcnQgPSBzdGFydFNlcnZlcigiQ29ucyBTdHJpbmcsSSxJbmV0QWRkcmVzcyxJIik7CisgICAgICAgIGludCBwb3J0TnVtYmVyID0gU3VwcG9ydF9Qb3J0TWFuYWdlci5nZXROZXh0UG9ydCgpOworICAgICAgICBpbnRbXSBpbnZhbGlkUG9ydCA9IHstMSwgSW50ZWdlci5NSU5fVkFMVUUsIDY1NTM2LCBJbnRlZ2VyLk1BWF9WQUxVRX07CisKKyAgICAgICAgU1NMU29ja2V0IHNzbCA9IGdldFNTTFNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKS5nZXRIb3N0TmFtZSgpLCBzcG9ydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgcG9ydE51bWJlcik7CisgICAgICAgIGFzc2VydE5vdE51bGwoc3NsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNwb3J0LCBzc2wuZ2V0UG9ydCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHBvcnROdW1iZXIsIHNzbC5nZXRMb2NhbFBvcnQoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGdldFNTTFNvY2tldCgibG9jYWxob3N0IiwgODA4MSwgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIDgwODIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkUG9ydC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgcG9ydE51bWJlciA9IFN1cHBvcnRfUG9ydE1hbmFnZXIuZ2V0TmV4dFBvcnQoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZ2V0U1NMU29ja2V0KEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLmdldEhvc3ROYW1lKCksIGludmFsaWRQb3J0W2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKSwgcG9ydE51bWJlcik7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGdldFNTTFNvY2tldChJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKS5nZXRIb3N0TmFtZSgpLCBzcG9ydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIGludmFsaWRQb3J0W2ldKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHBvcnROdW1iZXIgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBnZXRTU0xTb2NrZXQoImJsYS1ibGEiLCBzcG9ydCwgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCksIHBvcnROdW1iZXIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChVbmtub3duSG9zdEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9jcmVhdGlvblN0cmVzc1Rlc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gVGVzdCB0aGUgZGVmYXVsdCBjb2RlcGF0aCwgd2hpY2ggdXNlcyAvZGV2L3VyYW5kb20uCisgICAgICAgIFNTTENvbnRleHQgc3NsQ29udGV4dCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UoIlRMUyIpOworICAgICAgICBzc2xDb250ZXh0LmluaXQobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjA0ODsgKytpKSB7CisgICAgICAgICAgICBzc2xDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKS5jcmVhdGVTb2NrZXQoKS5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVGVzdCB0aGUgb3RoZXIgY29kZXBhdGgsIHdoaWNoIGNvcGllcyBhIHNlZWQgZnJvbSBhIGJ5dGVbXS4KKyAgICAgICAgc3NsQ29udGV4dC5pbml0KG51bGwsIG51bGwsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjA0ODsgKytpKSB7CisgICAgICAgICAgICBzc2xDb250ZXh0LmdldFNvY2tldEZhY3RvcnkoKS5jcmVhdGVTb2NrZXQoKS5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjYWRkSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXIoSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXIgbGlzdGVuZXIpCisgICAgICovCisgICAgQEFuZHJvaWRPbmx5KCJSSSBkb2Vzbid0IHRocm93IHRoZSBzcGVjaWZpZWQgSUFFIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZEhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMU29ja2V0IHNzbCA9IGdldFNTTFNvY2tldCgpOworICAgICAgICBIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lciBscyA9IG5ldyBIYW5kc2hha2VDTCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NsLmFkZEhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyKG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBzc2wuYWRkSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXIobHMpOworICAgICAgICBzc2wuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNyZW1vdmVIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lcihIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lciBsaXN0ZW5lcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3JlbW92ZUhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMU29ja2V0IHNzbCA9IGdldFNTTFNvY2tldCgpOworICAgICAgICBIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lciBscyA9IG5ldyBIYW5kc2hha2VDTCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NsLnJlbW92ZUhhbmRzaGFrZUNvbXBsZXRlZExpc3RlbmVyKG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2wucmVtb3ZlSGFuZHNoYWtlQ29tcGxldGVkTGlzdGVuZXIobHMpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHNzbC5hZGRIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lcihscyk7CisgICAgICAgIHNzbC5yZW1vdmVIYW5kc2hha2VDb21wbGV0ZWRMaXN0ZW5lcihscyk7CisgICAgICAgIHNzbC5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0I3NldEVuYWJsZVNlc3Npb25DcmVhdGlvbihib29sZWFuIGZsYWcpCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0VuYWJsZVNlc3Npb25DcmVhdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFNTTFNvY2tldCBzc2wgPSBnZXRTU0xTb2NrZXQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzc2wuZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCkpOworICAgICAgICBzc2wuc2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc3NsLmdldEVuYWJsZVNlc3Npb25DcmVhdGlvbigpKTsKKyAgICAgICAgc3NsLnNldEVuYWJsZVNlc3Npb25DcmVhdGlvbih0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzc2wuZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCkpOworICAgICAgICBzc2wuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNzZXROZWVkQ2xpZW50QXV0aChib29sZWFuIG5lZWQpCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjZ2V0TmVlZENsaWVudEF1dGhDcmVhdGlvbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9OZWVkQ2xpZW50QXV0aCgpIHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBTU0xTb2NrZXQgc3NsID0gZ2V0U1NMU29ja2V0KCk7CisgICAgICAgIHNzbC5zZXROZWVkQ2xpZW50QXV0aCh0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzc2wuZ2V0TmVlZENsaWVudEF1dGgoKSk7CisgICAgICAgIHNzbC5zZXROZWVkQ2xpZW50QXV0aChmYWxzZSk7CisgICAgICAgIGFzc2VydEZhbHNlKHNzbC5nZXROZWVkQ2xpZW50QXV0aCgpKTsKKyAgICAgICAgc3NsLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjc2V0V2FudENsaWVudEF1dGgoYm9vbGVhbiB3YW50KQorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0I2dldFdhbnRDbGllbnRBdXRoQ3JlYXRpb24oKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfV2FudENsaWVudEF1dGgoKSB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMU29ja2V0IHNzbCA9IGdldFNTTFNvY2tldCgpOworICAgICAgICBzc2wuc2V0V2FudENsaWVudEF1dGgodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoc3NsLmdldFdhbnRDbGllbnRBdXRoKCkpOworICAgICAgICBzc2wuc2V0V2FudENsaWVudEF1dGgoZmFsc2UpOworICAgICAgICBhc3NlcnRGYWxzZShzc2wuZ2V0V2FudENsaWVudEF1dGgoKSk7CisgICAgICAgIHNzbC5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0I2dldFN1cHBvcnRlZFByb3RvY29scygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTdXBwb3J0ZWRQcm90b2NvbHMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTU0xTb2NrZXQgc3NsID0gZ2V0U1NMU29ja2V0KCk7CisgICAgICAgIFN0cmluZ1tdIHJlcyA9IHNzbC5nZXRTdXBwb3J0ZWRQcm90b2NvbHMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTm8gc3VwcG9ydGVkIHByb3RvY29scyBmb3VuZCIsIHJlcy5sZW5ndGggPiAwKTsKKyAgICAgICAgc3NsLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjZ2V0RW5hYmxlZFByb3RvY29scygpCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjc2V0RW5hYmxlZFByb3RvY29scyhTdHJpbmdbXSBwcm90b2NvbHMpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9FbmFibGVkUHJvdG9jb2xzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMU29ja2V0IHNzbCA9IGdldFNTTFNvY2tldCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NsLnNldEVuYWJsZWRQcm90b2NvbHMobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHNzbC5zZXRFbmFibGVkUHJvdG9jb2xzKG5ldyBTdHJpbmdbXSB7fSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2wuc2V0RW5hYmxlZFByb3RvY29scyhuZXcgU3RyaW5nW10geyJibHViYiJ9KTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgc3NsLnNldEVuYWJsZWRQcm90b2NvbHMoc3NsLmdldEVuYWJsZWRQcm90b2NvbHMoKSk7CisgICAgICAgIFN0cmluZ1tdIHJlcyA9IHNzbC5nZXRFbmFibGVkUHJvdG9jb2xzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibm8gZW5hYmxlZCBwcm90b2NvbHMgc2V0IiwKKyAgICAgICAgICAgICAgICAgICAgIHNzbC5nZXRFbmFibGVkUHJvdG9jb2xzKCkubGVuZ3RoLCByZXMubGVuZ3RoKTsKKyAgICAgICAgc3NsLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjZ2V0U2Vzc2lvbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTZXNzaW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMU29ja2V0IHNzbCA9IGdldFNTTFNvY2tldCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKHNzbC5nZXRTZXNzaW9uKCkpOworICAgICAgICBzc2wuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMU29ja2V0IHNzbCA9IGdldFNTTFNvY2tldCgpOworICAgICAgICBTdHJpbmdbXSByZXMgPSBzc2wuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgICAgIGFzc2VydFRydWUoIm5vIHN1cHBvcnRlZCBjaXBoZXIgc3VpdGVzIiwgcmVzLmxlbmd0aCA+IDApOworICAgICAgICBzc2wuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNnZXRFbmFibGVkQ2lwaGVyU3VpdGVzKCkKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNzZXRFbmFibGVkQ2lwaGVyU3VpdGVzKFN0cmluZ1tdIHN1aXRlcykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0VuYWJsZWRDaXBoZXJTdWl0ZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTU0xTb2NrZXQgc3NsID0gZ2V0U1NMU29ja2V0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzc2wuc2V0RW5hYmxlZENpcGhlclN1aXRlcyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgc3NsLnNldEVuYWJsZWRDaXBoZXJTdWl0ZXMobmV3IFN0cmluZ1tdIHt9KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzbC5zZXRFbmFibGVkQ2lwaGVyU3VpdGVzKG5ldyBTdHJpbmdbXSB7ImJsdWJiIn0pOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBzc2wuc2V0RW5hYmxlZENpcGhlclN1aXRlcyhzc2wuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkpOworICAgICAgICBTdHJpbmdbXSByZXMgPSBzc2wuZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJOVUxMIHJlc3VsdCIsIHJlcyk7CisgICAgICAgIGFzc2VydEVxdWFscygibm90IGFsbCBzdXBwb3J0ZWQgY2lwaGVyIHN1aXRlcyB3ZXJlIGVuYWJsZWQiLAorICAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmFzTGlzdChzc2wuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkpLAorICAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmFzTGlzdChyZXMpKTsKKyAgICAgICAgc3NsLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjZ2V0VXNlQ2xpZW50TW9kZSgpCisgICAgICogamF2YXgubmV0LnNzbC5TU0xTb2NrZXQjc2V0VXNlQ2xpZW50TW9kZShib29sZWFuIG1vZGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Vc2VDbGllbnRNb2RlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU1NMU29ja2V0IHNzbCA9IGdldFNTTFNvY2tldCgpOworICAgICAgICBhc3NlcnRUcnVlKHNzbC5nZXRVc2VDbGllbnRNb2RlKCkpOworICAgICAgICBzc2wuc2V0VXNlQ2xpZW50TW9kZShmYWxzZSk7CisgICAgICAgIGFzc2VydEZhbHNlKHNzbC5nZXRVc2VDbGllbnRNb2RlKCkpOworICAgICAgICBzc2wuY2xvc2UoKTsKKworICAgICAgICBzc2wgPSBnZXRTU0xTb2NrZXQoImxvY2FsaG9zdCIsIHN0YXJ0U2VydmVyKCJVc2VDbGllbnRNb2RlIikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NsLnN0YXJ0SGFuZHNoYWtlKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgLy9mYWlsKGlvZSArICIgd2FzIHRocm93biBmb3IgbWV0aG9kIHN0YXJ0SGFuZHNoYWtlKCkiKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc3NsLnNldFVzZUNsaWVudE1vZGUoZmFsc2UpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorICAgICAgICBzc2wuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlNTTFNvY2tldCNzdGFydEhhbmRzaGFrZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zdGFydEhhbmRzaGFrZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFNTTFNvY2tldCBzc2wgPSBnZXRTU0xTb2NrZXQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNzbC5zdGFydEhhbmRzaGFrZSgpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHNzbC5jbG9zZSgpOworICAgIH0KKworICAgIGJvb2xlYW4gdXNlQktTID0gIVN0YW5kYXJkTmFtZXMuSVNfUkk7CisKKyAgICBwcml2YXRlIFN0cmluZyBQQVNTV09SRCA9ICJhbmRyb2lkIjsKKworICAgIHByaXZhdGUgaW50IHBvcnQgPSBTdXBwb3J0X1BvcnRNYW5hZ2VyLmdldE5leHRQb3J0KCk7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gc2VydmVyUmVhZHkgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIERlZmluZXMgdGhlIGtleXN0b3JlIGNvbnRlbnRzIGZvciB0aGUgc2VydmVyLCBCS1MgdmVyc2lvbi4gSG9sZHMganVzdCBhCisgICAgICogc2luZ2xlIHNlbGYtZ2VuZXJhdGVkIGtleS4gVGhlIHN1YmplY3QgbmFtZSBpcyAiVGVzdCBTZXJ2ZXIiLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRVJWRVJfS0VZU19CS1MgPSAiIgorICAgICAgICAgICAgKyAiQUFBQUFRQUFBQlFEa2Viem9QMVh3cXlXS1JDSkVwbi90OGRxSVFBQUJEa0VBQVZ0ZVd0bGVRQUFBUnBZbDIwbkFBQUFBUUFGV0M0MSIKKyAgICAgICAgICAgICsgIk1Ea0FBQUpOTUlJQ1NUQ0NBYktnQXdJQkFnSUVTRWZVMWpBTkJna3Foa2lHOXcwQkFRVUZBREJwTVFzd0NRWURWUVFHRXdKVlV6RVQiCisgICAgICAgICAgICArICJNQkVHQTFVRUNCTUtRMkZzYVdadmNtNXBZVEVNTUFvR0ExVUVCeE1EVFZSV01ROHdEUVlEVlFRS0V3WkhiMjluYkdVeEVEQU9CZ05WIgorICAgICAgICAgICAgKyAiQkFzVEIwRnVaSEp2YVdReEZEQVNCZ05WQkFNVEMxUmxjM1FnVTJWeWRtVnlNQjRYRFRBNE1EWXdOVEV4TlRneE5Gb1hEVEE0TURrdyIKKyAgICAgICAgICAgICsgIk16RXhOVGd4TkZvd2FURUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdUQ2tOaGJHbG1iM0p1YVdFeEREQUtCZ05WQkFjVEEwMVUiCisgICAgICAgICAgICArICJWakVQTUEwR0ExVUVDaE1HUjI5dloyeGxNUkF3RGdZRFZRUUxFd2RCYm1SeWIybGtNUlF3RWdZRFZRUURFd3RVWlhOMElGTmxjblpsIgorICAgICAgICAgICAgKyAiY2pDQm56QU5CZ2txaGtpRzl3MEJBUUVGQUFPQmpRQXdnWWtDZ1lFQTBMSWRLYUlyOS92c1RxOEJabEEzUitORldSYUg0bEdzVEFReSIKKyAgICAgICAgICAgICsgIkRQTUY5WnFFRE9hTDZESnV1MGNvbFNCQkJRODVoUVRQYTltOW55Sm9OM3BFaTFoZ2FtcU92UUlXY1hCaytTT3BVR1JaWkZYd25pSlYiCisgICAgICAgICAgICArICJ6REtVNW5FOU1ZZ24yQjlBb2lIM0NTdU16NkhScWdWYXF0cHBJZTFqaHVrTWMva0hWSnZsS1JOeTlYTUNBd0VBQVRBTkJna3Foa2lHIgorICAgICAgICAgICAgKyAiOXcwQkFRVUZBQU9CZ1FDN3lCbUo5Ty9lV0RHdFNIOUJIMFIzZGgyTmRTVDNXOWhOWjhoSWE4VThrbGhOSGJVQ1NTa3RabVprdmJQVSIKKyAgICAgICAgICAgICsgImhzZTVMSTNkaDZSeU5EdXFEcmJZd2NxektiRkphcS9qWDlrQ29lYjN2Z2JRRWxNUlg4RDJJRDF2Ump4d2xBTEZJU3J0YU40VnBXelYiCisgICAgICAgICAgICArICJ5ZW9IUFc0eGxkZVptb1Z0am44elhOelFoTHVCcVgyTW1BQUFBcXdBQUFBVXZrVVNjZnc5eUNTbUFMcnVVUk5tdEJhaTdrUUFBQVp4IgorICAgICAgICAgICAgKyAiNEptaWp4cy9sOEVCYWxlYVVydTZFT1Bpb1drVUFFVldDeGpNL1R4YkdIT2kyVk1zUVdxUnIvRFozd3NEbXRRZ3czUVRyVUs2NjZzUiIKKyAgICAgICAgICAgICsgIk1CbmJxZG55Q3l2TTFKMlYxeHhMWFBVZVJCbVIyQ1hvcllHRjlEeWU3TmtnVmRmQSs5ZzlMLzBBdTZVZ24rMkNqNWxlb0lna2dBcE4iCisgICAgICAgICAgICArICJ2dUVjWmVnRmxOT1VQVkVzM1NsQmdVRjFCWTZPQk0wVUJIVFB3R0d4RkJCY2V0Y3VNUmJVbnU2NXZ5REcwcHNsVDU5cXBhUjBUTVZzIgorICAgICAgICAgICAgKyAiUCt0Y2hlRXpoeWpiZk0zMi92d2huTDlkQkVnTThxTXQwc3FGNml0Tk9RVS9GNFdHa0syQ20ydjRDWUV5S1l3MzI1ZkVoelRYb3NjayIKKyAgICAgICAgICAgICsgIk1oYnFtY3lMYWI4RVBjZVdGM2R3ZW9VVDc2K2pFWng4bFYyZGFwUitDbWN6UUk0M3RWOWJ0c2QxeGlCYkJIQUt2eW1tOUVwOWJQek0iCisgICAgICAgICAgICArICJKME1RaStPdFVSTDlMeGtlLzcwL01SdWVxYlBlVWxPYUd2QU5UbVhRRDJPblc3UElTd0o5bHBlTGZURzBMY3Frb3FrYnRMS1FMWUhJIgorICAgICAgICAgICAgKyAiclFmVjVqMGord212bXBNeHpqTjN1dk5hakxhNHpROGwwRW9rOVNGYVJyMlJMMGdOOFEySmVnZk9MNHBVaUhQc2g2NFdXeWEyTkI3ZiIKKyAgICAgICAgICAgICsgIlYrMXM2NWVBNW9zcFhZc1NoUmpvMDQ2UWhHVG15bXdYWHpkenV4dThJbG5URW9udDZQNCtKK0dzV2s2Y2xkR2JsMjBoY3R1VUt6eXgiCisgICAgICAgICAgICArICJPcHRqRVBPS2VqVjYwaURDWUdtSGJDV0F6UThoNU1JTFY4MkljbHpOVmlabXpBYXBlZUNuZXhocFhoV1RzK3hERVlTS0VpRy9jYW10IgorICAgICAgICAgICAgKyAiYmhtWmMzQmN5VkpyVzIzUGt0U2ZwQlE2RDhaeG9NZkYwTDdWMkdRTWFVZyszcjd1Y3J4ODJrcHFvdGp2MHhIZ2hOSW05NWFCcjFRdyIKKyAgICAgICAgICAgICsgIjFnYUVqc0MvMHdHbW1CRGcxZFRESCtGMXA5VEluenIzRUZ1WUQwWWlRN1lsQUhxM2NQdXlHb0xYSjVkWFl1U0JmaERYSlNlZGRVa2wiCisgICAgICAgICAgICArICJrMXVmWnlPT2Nza2VJblFnZTdqemFSZm1LZzNVOTRyK3NwTUV2YjBBekRRVk9LdmpqbzFpdnhNU2dGUlphRGIvNHF3PSI7CisKKyAgICAvKioKKyAgICAgKiBEZWZpbmVzIHRoZSBrZXlzdG9yZSBjb250ZW50cyBmb3IgdGhlIHNlcnZlciwgSktTIHZlcnNpb24uIEhvbGRzIGp1c3QgYQorICAgICAqIHNpbmdsZSBzZWxmLWdlbmVyYXRlZCBrZXkuIFRoZSBzdWJqZWN0IG5hbWUgaXMgIlRlc3QgU2VydmVyIi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VSVkVSX0tFWVNfSktTID0gIiIKKyAgICAgICAgICAgICsgIi91Mys3UUFBQUFJQUFBQUJBQUFBQVFBRmJYbHJaWGtBQUFFYVdGZkJlQUFBQXJvd2dnSzJNQTRHQ2lzR0FRUUJLZ0lSQVFFRkFBU0MiCisgICAgICAgICAgICArICJBcUkya3A1WGpuRjhZWmtoY0Y5MllzSk5Ra3ZzbUg3enFNTTg3ajIzelNvVjREd3lFM1hlQy9nWldxMVRvU2NJaG9xWmt6bGJXY3U0IgorICAgICAgICAgICAgKyAiVC9aZmMvRHJmR2svcktiQkwxdVdLR1o4Zk10bFprOEtvQWh4WmsxSlN5SnZka3lLeHFtelVieGsxT0ZNbE4yVkpOdTk3RlBWSCtkdSIKKyAgICAgICAgICAgICsgImR2alR2bXBkb004MUlOV0JXLzFmWkplUWVEdm40bU1iYmUwSXhncGlMbkk5V1NldmxhRFAvc20xWDNpTzl5RXl6SExMK001RXJzcG8iCisgICAgICAgICAgICArICJDd2E1NThmT3U1RGRzSUNNWGh2RFF4aldGS0ZoUEhuS3RHZStWdndrRzkvYkFhRGd4M2tmaGswdzV6dmRua0tiKzhFZDl5bE5SemRrIgorICAgICAgICAgICAgKyAib2NBYS9teGxNVE9zVHZES1hqanNCdXBOUElJajdPUDRHTm5aYXhrSmpTczk4cEVPNjdvcDFHWDJxaHk2RlNPUE51cThrLzY1SHpVYyIKKyAgICAgICAgICAgICsgIlBZbjZ2b0VlaDZ2bTAyVS9zakVuelJldlEyKzJ3WG9BZHAwRXd0US9EbE1lK052Y3dQR1dLdU1nWDRBNEw5M0RaR2IwNE4yVm1BVTMiCisgICAgICAgICAgICArICJZTE90WndUTzBMYnVXcmNDTS9xOTlHLzdMY2N6a3hJVnJPMkkvcmg4UlhWY3psZjlRemNyRk9iRnY0QVR1c3BXSjh4RzdEaHNNYm5rIgorICAgICAgICAgICAgKyAiclQ5NFBxNlRvZ1llb3o4bzhaTXlrZXNBcU42bXQvOStUb0llbW1YditlK0tVMWhJNW9Md1dNblVHNmRYTTZoSXZyVUxZNm8rUUNQSCIKKyAgICAgICAgICAgICsgIjE3MllRSk1hKzY4SEFlUytpdEJUQUY0Q2xtL2JMbjZyZUhDR0dVNnZOZHdVMGxZbGRwaU9qOWNCM3QrdTJVdUxvNnRpRldqTGY1WnMiCisgICAgICAgICAgICArICJFUUpFVGQ0Zy9FSzluSHhKbjBHQUtyV25UdzdwRUhRSjA4ZWx6VXV5MDRDL2pFRUcrNFFYVTFJbnpTNG8va1IwU3F6MldUR0RvU29xIgorICAgICAgICAgICAgKyAiZXd1UFJVNWJ6UXMvYjlkYXEzbVhyblB0UkJMNkhmU0RBZHBUSzc2aUhxTENHZHF4M2F2SGpWU0JtNHpGdkV1WUJDZXYrM2lLT0JtZyIKKyAgICAgICAgICAgICsgInloN2VRUlRqejRVT1dmeTg1b21NQnI3bEs4UHRmVkJEek9YcGFzeFMwdUJnZFV5QkRYNHRPNms5alo4YTFrbVFSUUFBQUFFQUJWZ3UiCisgICAgICAgICAgICArICJOVEE1QUFBQ1NEQ0NBa1F3Z2dHdEFnUklSOFNLTUEwR0NTcUdTSWIzRFFFQkJBVUFNR2t4Q3pBSkJnTlZCQVlUQWxWVE1STXdFUVlEIgorICAgICAgICAgICAgKyAiVlFRSUV3cERZV3hwWm05eWJtbGhNUXd3Q2dZRFZRUUhFd05OVkZZeER6QU5CZ05WQkFvVEJrZHZiMmRzWlRFUU1BNEdBMVVFQ3hNSCIKKyAgICAgICAgICAgICsgIlFXNWtjbTlwWkRFVU1CSUdBMVVFQXhNTFZHVnpkQ0JUWlhKMlpYSXdIaGNOTURnd05qQTFNVEEwT0RReVdoY05NRGd3T1RBek1UQTAiCisgICAgICAgICAgICArICJPRFF5V2pCcE1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFTU1Bb0dBMVVFQnhNRFRWUldNUTh3IgorICAgICAgICAgICAgKyAiRFFZRFZRUUtFd1pIYjI5bmJHVXhFREFPQmdOVkJBc1RCMEZ1WkhKdmFXUXhGREFTQmdOVkJBTVRDMVJsYzNRZ1UyVnlkbVZ5TUlHZiIKKyAgICAgICAgICAgICsgIk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FDd29DNmNocUNJODRyajFQclh1SmdiaWl0NEVWOTA5elI2TjBqTmxZZmciCisgICAgICAgICAgICArICJpdHdCMzliUDM5d0gwM3JGbThUNTliM21iU3B0bkdtQ0lwTFpuMjVLUFBGc1lEM0pKK3dGbG1pVWRFUDlIMDVmbGZ3dEZRSm53OXVUIgorICAgICAgICAgICAgKyAiM3JSSWRZVk1QY1EzUm9aendBTWxpR3I4ODJJMnRoSURiQTZ4akdVLzFuUklkdmswTHR4SDNRSURBUUFCTUEwR0NTcUdTSWIzRFFFQiIKKyAgICAgICAgICAgICsgIkJBVUFBNEdCQUpuKzZZZ1VsWTE4SWUrMCtWdDhvRWk4MUROaS9iZlByQVVBaDYzZmhoQmlreC8zUjlkbDN3aDA5WjZwN2NJZE54alciCisgICAgICAgICAgICArICJuMmxsK2NSVzllcUY3ejc1RjBPbW0wQzcvS0FFUGp1a1Zic3ptemVVNVZxemtwU3Qwajg0WVdpK1RmY0hScmZ2aExicmxtR0lUVnBZIgorICAgICAgICAgICAgKyAib2w1cEhMRHlxR21EczUzcGd3aXBXcXNuL25FWEVCZ2ozRW9xUGVxSGJEZjdZYVA4aC81QlN0MD0iOworCisgICAgcHJvdGVjdGVkIGludCBzdGFydFNlcnZlcihTdHJpbmcgbmFtZSkgeworICAgICAgICBTdHJpbmcga2V5cyA9IHVzZUJLUyA/IFNFUlZFUl9LRVlTX0JLUyA6IFNFUlZFUl9LRVlTX0pLUzsKKyAgICAgICAgVGVzdFNlcnZlciBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcih0cnVlLCBrZXlzKTsKKyAgICAgICAgVGhyZWFkIHNlcnZlclRocmVhZCA9IG5ldyBUaHJlYWQoc2VydmVyKTsKKyAgICAgICAgc2VydmVyVGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3aGlsZSAoIXNlcnZlclJlYWR5KSB7CisgICAgICAgICAgICAgICAgRXhjZXB0aW9uIGUgPSBzZXJ2ZXIuZ2V0RXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgaWYgKGUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuc2xlZXAoNTApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gZ2l2ZSB0aGUgc2VydmVyIDEwMCBtaWxsaXMgdG8gYWNjZXB0CisgICAgICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLnNsZWVwKDEwMCk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICB9CisgICAgICAgIHJldHVybiBzZXJ2ZXIuc3BvcnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW1wbGVtZW50cyBhIHRlc3QgU1NMIHNvY2tldCBzZXJ2ZXIuIEl0IHdhaXQgZm9yIGEgY29ubmVjdGlvbiBvbiBhIGdpdmVuCisgICAgICogcG9ydCwgcmVxdWVzdHMgY2xpZW50IGF1dGhlbnRpY2F0aW9uIChpZiBzcGVjaWZpZWQpLCBhbmQgcmVhZCAyNTYgYnl0ZXMKKyAgICAgKiBmcm9tIHRoZSBzb2NrZXQuCisgICAgICovCisgICAgY2xhc3MgVGVzdFNlcnZlciBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTElFTlRfQVVUSF9OT05FID0gMDsKKworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTElFTlRfQVVUSF9XQU5URUQgPSAxOworCisgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMSUVOVF9BVVRIX05FRURFRCA9IDI7CisKKyAgICAgICAgcHJpdmF0ZSBUZXN0VHJ1c3RNYW5hZ2VyIHRydXN0TWFuYWdlcjsKKworICAgICAgICBwcml2YXRlIEV4Y2VwdGlvbiBleGNlcHRpb247CisKKyAgICAgICAgU3RyaW5nIGtleXM7CisKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIHByb3ZpZGVLZXlzOworCisgICAgICAgIGludCBzcG9ydDsKKworICAgICAgICBwdWJsaWMgVGVzdFNlcnZlcihib29sZWFuIHByb3ZpZGVLZXlzLCBTdHJpbmcga2V5cykgeworICAgICAgICAgICAgdGhpcy5rZXlzID0ga2V5czsKKyAgICAgICAgICAgIHRoaXMucHJvdmlkZUtleXMgPSBwcm92aWRlS2V5czsKKworICAgICAgICAgICAgdHJ1c3RNYW5hZ2VyID0gbmV3IFRlc3RUcnVzdE1hbmFnZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgS2V5TWFuYWdlcltdIGtleU1hbmFnZXJzID0gcHJvdmlkZUtleXMgPyBnZXRLZXlNYW5hZ2VycyhrZXlzKSA6IG51bGw7CisgICAgICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyW10gdHJ1c3RNYW5hZ2VycyA9IG5ldyBUcnVzdE1hbmFnZXJbXSB7IHRydXN0TWFuYWdlciB9OworCisgICAgICAgICAgICAgICAgU1NMQ29udGV4dCBzc2xDb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZSgiVExTIik7CisgICAgICAgICAgICAgICAgc3NsQ29udGV4dC5pbml0KGtleU1hbmFnZXJzLCB0cnVzdE1hbmFnZXJzLCBudWxsKTsKKworICAgICAgICAgICAgICAgIFNTTFNlcnZlclNvY2tldCBzZXJ2ZXJTb2NrZXQgPSAoU1NMU2VydmVyU29ja2V0KQorICAgICAgICAgICAgICAgICAgICAgICAgc3NsQ29udGV4dC5nZXRTZXJ2ZXJTb2NrZXRGYWN0b3J5KCkuY3JlYXRlU2VydmVyU29ja2V0KCk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0LmJpbmQobmV3IEluZXRTb2NrZXRBZGRyZXNzKHBvcnQpKTsKKyAgICAgICAgICAgICAgICAgICAgc3BvcnQgPSBzZXJ2ZXJTb2NrZXQuZ2V0TG9jYWxQb3J0KCk7CisgICAgICAgICAgICAgICAgICAgIHNlcnZlclJlYWR5ID0gdHJ1ZTsKKworICAgICAgICAgICAgICAgICAgICBTU0xTb2NrZXQgY2xpZW50U29ja2V0ID0gKFNTTFNvY2tldClzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIHN0cmVhbSA9IGNsaWVudFNvY2tldC5nZXRJbnB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDI1NjsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBqID0gc3RyZWFtLnJlYWQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgIT0gaikgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkVycm9yIHJlYWRpbmcgc29ja2V0LCBleHBlY3RlZCAiICsgaQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiLCBnb3QgIiArIGopOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudFNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gZXg7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgRXhjZXB0aW9uIGdldEV4Y2VwdGlvbigpIHsKKyAgICAgICAgICAgIHJldHVybiBleGNlcHRpb247CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgWDUwOUNlcnRpZmljYXRlW10gZ2V0Q2hhaW4oKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1c3RNYW5hZ2VyLmdldENoYWluKCk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIExvYWRzIGEga2V5c3RvcmUgZnJvbSBhIGJhc2U2NC1lbmNvZGVkIFN0cmluZy4gUmV0dXJucyB0aGUgS2V5TWFuYWdlcltdCisgICAgICogZm9yIHRoZSByZXN1bHQuCisgICAgICovCisgICAgcHJpdmF0ZSBLZXlNYW5hZ2VyW10gZ2V0S2V5TWFuYWdlcnMoU3RyaW5nIGtleXMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBieXRlW10gYnl0ZXMgPSBCYXNlNjQuZGVjb2RlKGtleXMuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIElucHV0U3RyZWFtIGlucHV0U3RyZWFtID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzKTsKKworICAgICAgICBLZXlTdG9yZSBrZXlTdG9yZSA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICBrZXlTdG9yZS5sb2FkKGlucHV0U3RyZWFtLCBQQVNTV09SRC50b0NoYXJBcnJheSgpKTsKKyAgICAgICAgaW5wdXRTdHJlYW0uY2xvc2UoKTsKKworICAgICAgICBTdHJpbmcgYWxnb3JpdGhtID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0RGVmYXVsdEFsZ29yaXRobSgpOworICAgICAgICBLZXlNYW5hZ2VyRmFjdG9yeSBrZXlNYW5hZ2VyRmFjdG9yeSA9IEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgICAgIGtleU1hbmFnZXJGYWN0b3J5LmluaXQoa2V5U3RvcmUsIFBBU1NXT1JELnRvQ2hhckFycmF5KCkpOworCisgICAgICAgIHJldHVybiBrZXlNYW5hZ2VyRmFjdG9yeS5nZXRLZXlNYW5hZ2VycygpOworICAgIH0KKworICAgIHByaXZhdGUgU1NMU29ja2V0IGdldFNTTFNvY2tldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiAoU1NMU29ja2V0KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKS5jcmVhdGVTb2NrZXQoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFNTTFNvY2tldCBnZXRTU0xTb2NrZXQoSW5ldEFkZHJlc3MgaG9zdCwgaW50IHBvcnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiAoU1NMU29ja2V0KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKS5jcmVhdGVTb2NrZXQoaG9zdCwgcG9ydCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBTU0xTb2NrZXQgZ2V0U1NMU29ja2V0KFN0cmluZyBob3N0LCBpbnQgcG9ydCkgdGhyb3dzIFVua25vd25Ib3N0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiAoU1NMU29ja2V0KSBTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKS5jcmVhdGVTb2NrZXQoaG9zdCwgcG9ydCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBTU0xTb2NrZXQgZ2V0U1NMU29ja2V0KEluZXRBZGRyZXNzIGhvc3QsIGludCBwb3J0LCBJbmV0QWRkcmVzcyBsb2NhbEhvc3QsIGludCBsb2NhbFBvcnQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gKFNTTFNvY2tldCkgU1NMU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCkuY3JlYXRlU29ja2V0KGhvc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9ydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbEhvc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxQb3J0KTsKKyAgICB9CisKKyAgICBwcml2YXRlIFNTTFNvY2tldCBnZXRTU0xTb2NrZXQoU3RyaW5nIGhvc3QsIGludCBwb3J0LCBJbmV0QWRkcmVzcyBsb2NhbEhvc3QsIGludCBsb2NhbFBvcnQpCisgICAgICAgICAgICB0aHJvd3MgVW5rbm93bkhvc3RFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIChTU0xTb2NrZXQpIFNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpLmNyZWF0ZVNvY2tldChob3N0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxIb3N0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsUG9ydCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1RydXN0TWFuYWdlckZhY3RvcnkxVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1RydXN0TWFuYWdlckZhY3RvcnkxVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzYjI0ZTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvVHJ1c3RNYW5hZ2VyRmFjdG9yeTFUZXN0LmphdmEKQEAgLTAsMCArMSw1MTkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5Lbm93bkZhaWx1cmU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5UcnVzdEFuY2hvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvcjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuQ2VydFBhdGhUcnVzdE1hbmFnZXJQYXJhbWV0ZXJzOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuVHJ1c3RNYW5hZ2VyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuVHJ1c3RNYW5hZ2VyRmFjdG9yeTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlckZhY3RvcnlTcGk7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlNwaUVuZ1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlRlc3RLZXlQYWlyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnRlc3RzLnN1cHBvcnQuTXlUcnVzdE1hbmFnZXJGYWN0b3J5U3BpOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5UcnVzdE1hbmFnZXJGYWN0b3J5PC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgVHJ1c3RNYW5hZ2VyRmFjdG9yeTFUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHNydlRydXN0TWFuYWdlckZhY3RvcnkgPSAiVHJ1c3RNYW5hZ2VyRmFjdG9yeSI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBpbnZhbGlkVmFsdWVzID0gU3BpRW5nVXRpbHMuaW52YWxpZFZhbHVlczsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBERUZBVUxUX0FMR09SSVRITTsKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgREVGQVVMVF9QUk9WSURFUl9OQU1FOworICAgIHByaXZhdGUgc3RhdGljIFByb3ZpZGVyIERFRkFVTFRfUFJPVklERVI7CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gVkFMSURfVkFMVUVTOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldERlZmF1bHRBbGdvcml0aG0oKSB7CisgICAgICAgIGluaXQoKTsKKyAgICAgICAgcmV0dXJuIERFRkFVTFRfQUxHT1JJVEhNOworICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0RGVmYXVsdFByb3ZpZGVyTmFtZSgpIHsKKyAgICAgICAgaW5pdCgpOworICAgICAgICByZXR1cm4gREVGQVVMVF9QUk9WSURFUl9OQU1FOworICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBQcm92aWRlciBnZXREZWZhdWx0UHJvdmlkZXIoKSB7CisgICAgICAgIGluaXQoKTsKKyAgICAgICAgcmV0dXJuIERFRkFVTFRfUFJPVklERVI7CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIGdldFZhbGlkVmFsdWVzKCkgeworICAgICAgICBpbml0KCk7CisgICAgICAgIHJldHVybiBWQUxJRF9WQUxVRVM7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgc3luY2hyb25pemVkIHZvaWQgaW5pdCgpIHsKKyAgICAgICAgaWYgKERFRkFVTFRfQUxHT1JJVEhNICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBERUZBVUxUX0FMR09SSVRITSA9IFNlY3VyaXR5LmdldFByb3BlcnR5KCJzc2wuVHJ1c3RNYW5hZ2VyRmFjdG9yeS5hbGdvcml0aG0iKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChERUZBVUxUX0FMR09SSVRITSk7CisgICAgICAgIERFRkFVTFRfUFJPVklERVIgPSBTcGlFbmdVdGlscy5pc1N1cHBvcnQoREVGQVVMVF9BTEdPUklUSE0sIHNydlRydXN0TWFuYWdlckZhY3RvcnkpOworICAgICAgICBERUZBVUxUX1BST1ZJREVSX05BTUUgPSBERUZBVUxUX1BST1ZJREVSLmdldE5hbWUoKTsKKyAgICAgICAgVkFMSURfVkFMVUVTID0gbmV3IFN0cmluZ1tdIHsgREVGQVVMVF9BTEdPUklUSE0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERFRkFVTFRfQUxHT1JJVEhNLnRvVXBwZXJDYXNlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERFRkFVTFRfQUxHT1JJVEhNLnRvTG93ZXJDYXNlKCkgfTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBUcnVzdE1hbmFnZXJGYWN0b3J5W10gY3JlYXRlVE1GYWMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ldyBUcnVzdE1hbmFnZXJGYWN0b3J5W10geworICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShnZXREZWZhdWx0QWxnb3JpdGhtKCkpLAorICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShnZXREZWZhdWx0QWxnb3JpdGhtKCksIGdldERlZmF1bHRQcm92aWRlcigpKSwKKyAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoZ2V0RGVmYXVsdEFsZ29yaXRobSgpLCBnZXREZWZhdWx0UHJvdmlkZXJOYW1lKCkpCisgICAgICAgIH07CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvckxqYXZheF9uZXRfc3NsX1RydXN0TWFuYWdlckZhY3RvcnlTcGlMamF2YV9zZWN1cml0eV9Qcm92aWRlckxqYXZhX2xhbmdfU3RyaW5nKCkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5U3BpIHNwaSA9IG5ldyBNeVRydXN0TWFuYWdlckZhY3RvcnlTcGkoKTsKKyAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeSB0bUYgPSBuZXcgbXlUcnVzdE1hbmFnZXJGYWN0b3J5KHNwaSwgZ2V0RGVmYXVsdFByb3ZpZGVyKCksCisgICAgICAgICAgICAgICAgZ2V0RGVmYXVsdEFsZ29yaXRobSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTm90IENlcnRTdG9yZSBvYmplY3QiLCB0bUYgaW5zdGFuY2VvZiBUcnVzdE1hbmFnZXJGYWN0b3J5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwgdG1GLmdldEFsZ29yaXRobSgpLAorICAgICAgICAgICAgICAgIGdldERlZmF1bHRBbGdvcml0aG0oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwgdG1GLmdldFByb3ZpZGVyKCksIGdldERlZmF1bHRQcm92aWRlcigpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiSW5jb3JyZWN0IHJlc3VsdCIsIHRtRi5nZXRUcnVzdE1hbmFnZXJzKCkpOworCisgICAgICAgIHRtRiA9IG5ldyBteVRydXN0TWFuYWdlckZhY3RvcnkobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoIk5vdCBDZXJ0U3RvcmUgb2JqZWN0IiwgdG1GIGluc3RhbmNlb2YgVHJ1c3RNYW5hZ2VyRmFjdG9yeSk7CisgICAgICAgIGFzc2VydE51bGwoIlByb3ZpZGVyIG11c3QgYmUgbnVsbCIsIHRtRi5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiQWxnb3JpdGhtIG11c3QgYmUgbnVsbCIsIHRtRi5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0bUYuZ2V0VHJ1c3RNYW5hZ2VycygpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogIFRlc3QgZm9yIDxjb2RlPmdldEFsZ29yaXRobSgpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgdGhlIGFsZ29yaXRobSBuYW1lIG9mIHRoaXMgb2JqZWN0CisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBbGdvcml0aG0oKQorICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsCisgICAgICAgICAgICAgICAgZ2V0RGVmYXVsdEFsZ29yaXRobSgpLAorICAgICAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2UoZ2V0RGVmYXVsdEFsZ29yaXRobSgpKS5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsCisgICAgICAgICAgICAgICAgZ2V0RGVmYXVsdEFsZ29yaXRobSgpLAorICAgICAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2UoZ2V0RGVmYXVsdEFsZ29yaXRobSgpLCBnZXREZWZhdWx0UHJvdmlkZXJOYW1lKCkpCisgICAgICAgICAgICAgICAgLmdldEFsZ29yaXRobSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwKKyAgICAgICAgICAgICAgICBnZXREZWZhdWx0QWxnb3JpdGhtKCksCisgICAgICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShnZXREZWZhdWx0QWxnb3JpdGhtKCksIGdldERlZmF1bHRQcm92aWRlcigpKQorICAgICAgICAgICAgICAgIC5nZXRBbGdvcml0aG0oKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogIFRlc3QgZm9yIDxjb2RlPmdldERlZmF1bHRBbGdvcml0aG0oKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHZhbHVlIHdoaWNoIGlzIHNwZWNpZm9lZCBpbiBzZWN1cml0eSBwcm9wZXJ0eQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGVmYXVsdEFsZ29yaXRobSgpIHsKKyAgICAgICAgU3RyaW5nIGRlZiA9IFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0RGVmYXVsdEFsZ29yaXRobSgpOworICAgICAgICBpZiAoZ2V0RGVmYXVsdEFsZ29yaXRobSgpID09IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydE51bGwoIkRlZmF1bHRBbGdvcml0aG0gbXVzdCBiZSBudWxsIiwgZGVmKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW52YWxpZCBkZWZhdWx0IGFsZ29yaXRobSIsIGRlZiwgZ2V0RGVmYXVsdEFsZ29yaXRobSgpKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgZGVmQSA9ICJQcm9iYS50cnVzdG1hbmFnZXJmYWN0b3J5LmRlZmF1bC50eXBlIjsKKyAgICAgICAgU2VjdXJpdHkuc2V0UHJvcGVydHkoInNzbC5UcnVzdE1hbmFnZXJGYWN0b3J5LmFsZ29yaXRobSIsIGRlZkEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBnZXREZWZhdWx0QWxnb3JpdGhtKCkiLAorICAgICAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0RGVmYXVsdEFsZ29yaXRobSgpLCBkZWZBKTsKKyAgICAgICAgaWYgKGRlZiA9PSBudWxsKSB7CisgICAgICAgICAgICBkZWYgPSAiIjsKKyAgICAgICAgfQorICAgICAgICBTZWN1cml0eS5zZXRQcm9wZXJ0eSgic3NsLlRydXN0TWFuYWdlckZhY3RvcnkuYWxnb3JpdGhtIiwgZGVmKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgZ2V0RGVmYXVsdEFsZ29yaXRobSgpIiwKKyAgICAgICAgICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldERlZmF1bHRBbGdvcml0aG0oKSwgZGVmKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uczogcmV0dXJucyBzZWN1cml0eSBwcm9wZXJ0eSAic3NsLlRydXN0TWFuYWdlckZhY3RvcnkuYWxnb3JpdGhtIjsKKyAgICAgKiByZXR1cm5zIGluc3RhbmNlIG9mIFRydXN0TWFuYWdlckZhY3RvcnkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmcwMSgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBmb3IgKFN0cmluZyB2YWxpZFZhbHVlIDogZ2V0VmFsaWRWYWx1ZXMoKSkgeworICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeSB0cnVzdE1GID0gVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIk5vdCBUcnVzdE1hbmFnZXJGYWN0b3J5IG9iamVjdCIsCisgICAgICAgICAgICAgICAgICAgICAgIHRydXN0TUYgaW5zdGFuY2VvZiBUcnVzdE1hbmFnZXJGYWN0b3J5KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW52YWxpZCBhbGdvcml0aG0iLCB0cnVzdE1GLmdldEFsZ29yaXRobSgpLCB2YWxpZFZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG51bGw7CisgICAgICogdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBub3QgY29ycmVjdDsKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmcwMigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UobnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3YXMgbm90IHRocm93biBhcyBleHBlY3RlZCBmb3IgYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aGVuIHByb3ZpZGVyIGlzIG51bGwKKyAgICAgKiBvciBlbXB0eQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nMDEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChTdHJpbmcgdmFsaWRWYWx1ZSA6IGdldFZhbGlkVmFsdWVzKCkpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlLCAoU3RyaW5nKSBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlLCAiIik7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbnVsbDsKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG5vdCBjb3JyZWN0OworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nMDIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UobnVsbCwgZ2V0RGVmYXVsdFByb3ZpZGVyTmFtZSgpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGdldERlZmF1bHRQcm92aWRlck5hbWUoKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIChhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gd2hlbiBwcm92aWRlciBoYXMKKyAgICAgKiBpbnZhbGlkIHZhbHVlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcwMygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKFN0cmluZyBpbnZhbGlkVmFsdWUgOiBpbnZhbGlkVmFsdWVzKSB7CisgICAgICAgICAgICBmb3IgKFN0cmluZyB2YWxpZFZhbHVlIDogZ2V0VmFsaWRWYWx1ZXMoKSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZSwgaW52YWxpZFZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gKGFsZ29yaXRobTogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQodmFsaWRWYWx1ZSkuY29uY2F0KCIgcHJvdmlkZXI6ICIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChpbnZhbGlkVmFsdWUpLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZSgiIi5lcXVhbHMoaW52YWxpZFZhbHVlKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiIiwgaW52YWxpZFZhbHVlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBpbnN0YW5jZSBvZiBUcnVzdE1hbmFnZXJGYWN0b3J5CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcwNCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IgKFN0cmluZyB2YWxpZFZhbHVlIDogZ2V0VmFsaWRWYWx1ZXMoKSkgeworICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeSB0cnVzdE1GID0gVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXREZWZhdWx0UHJvdmlkZXJOYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTm90IFRydXN0TWFuYWdlckZhY3Rvcnkgb2JqZWN0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgdHJ1c3RNRiBpbnN0YW5jZW9mIFRydXN0TWFuYWdlckZhY3RvcnkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbnZhbGlkIGFsZ29yaXRobSIsIHRydXN0TUYuZ2V0QWxnb3JpdGhtKCksIHZhbGlkVmFsdWUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbnZhbGlkIHByb3ZpZGVyIiwgdHJ1c3RNRi5nZXRQcm92aWRlcigpLCBnZXREZWZhdWx0UHJvdmlkZXIoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBQcm92aWRlciBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZ0xqYXZhX3NlY3VyaXR5X1Byb3ZpZGVyMDEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChTdHJpbmcgdmFsaWRWYWx1ZSA6IGdldFZhbGlkVmFsdWVzKCkpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlLCAoUHJvdmlkZXIpIG51bGwpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBQcm92aWRlciBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOgorICAgICAqIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBudWxsOworICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbm90IGNvcnJlY3Q7CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfc2VjdXJpdHlfUHJvdmlkZXIwMigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UobnVsbCwgZ2V0RGVmYXVsdFByb3ZpZGVyKCkpOworICAgICAgICAgICAgZmFpbCgiIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICBnZXREZWZhdWx0UHJvdmlkZXIoKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIChhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgaW5zdGFuY2Ugb2YgVHJ1c3RNYW5hZ2VyRmFjdG9yeQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZ0xqYXZhX3NlY3VyaXR5X1Byb3ZpZGVyMDMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChTdHJpbmcgdmFsaWRWYWx1ZSA6IGdldFZhbGlkVmFsdWVzKCkpIHsKKyAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkgdHJ1c3RNRiA9IFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0RGVmYXVsdFByb3ZpZGVyKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTm90IFRydXN0TWFuYWdlckZhY3Rvcnkgb2JqZWN0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgdHJ1c3RNRiBpbnN0YW5jZW9mIFRydXN0TWFuYWdlckZhY3RvcnkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbnZhbGlkIGFsZ29yaXRobSIsIHRydXN0TUYuZ2V0QWxnb3JpdGhtKCksIHZhbGlkVmFsdWUpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbnZhbGlkIHByb3ZpZGVyIiwgdHJ1c3RNRi5nZXRQcm92aWRlcigpLCBnZXREZWZhdWx0UHJvdmlkZXIoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRQcm92aWRlcigpPC9jb2RlPgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogQHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UHJvdmlkZXIoKQorICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwKKyAgICAgICAgICAgICAgICBnZXREZWZhdWx0UHJvdmlkZXIoKSwKKyAgICAgICAgICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKGdldERlZmF1bHRBbGdvcml0aG0oKSkuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwKKyAgICAgICAgICAgICAgICBnZXREZWZhdWx0UHJvdmlkZXIoKSwKKyAgICAgICAgICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgLmdldEluc3RhbmNlKGdldERlZmF1bHRBbGdvcml0aG0oKSwgZ2V0RGVmYXVsdFByb3ZpZGVyTmFtZSgpKQorICAgICAgICAgICAgICAgIC5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLAorICAgICAgICAgICAgICAgIGdldERlZmF1bHRQcm92aWRlcigpLAorICAgICAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoZ2V0RGVmYXVsdEFsZ29yaXRobSgpLCBnZXREZWZhdWx0UHJvdmlkZXIoKSkKKyAgICAgICAgICAgICAgICAuZ2V0UHJvdmlkZXIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2VUcnVzdE1hbmFnZXJzKCk8L2NvZGU+CisgICAgICogQHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFRydXN0TWFuYWdlcnMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5IHRydXN0TUYgPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGdldERlZmF1bHRBbGdvcml0aG0oKSk7CisgICAgICAgICAgICBLZXlTdG9yZSBrcyA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICAgICAga3MubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgICAgIHRydXN0TUYuaW5pdChrcyk7CisgICAgICAgICAgICBUcnVzdE1hbmFnZXJbXSB0bSA9IHRydXN0TUYuZ2V0VHJ1c3RNYW5hZ2VycygpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiUmVzdWx0IGhhcyBub3QgYmUgbnVsbCIsIHRtKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkxlbmd0aCBvZiByZXN1bHQgVHJ1c3RNYW5hZ2VyIGFycmF5IHNob3VsZCBub3QgYmUgMCIsCisgICAgICAgICAgICAgICAgICAgICh0bS5sZW5ndGggPiAwKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGV4LnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+aW5pdChLZXlTdG9yZSBrZXlTdG9yZSk8L2NvZGU+CisgICAgICogQXNzZXJ0aW9uOiBjYWxsIG1ldGhvZCB3aXRoIG51bGwgcGFyYW1ldGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pbml0TGphdmFfc2VjdXJpdHlfS2V5U3RvcmVfMDEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5U3RvcmUga3NOdWxsID0gbnVsbDsKKyAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeVtdIHRydXN0TUYgPSBjcmVhdGVUTUZhYygpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJUcnVzdE1hbmFnZXJGYWN0b3J5IG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIHRydXN0TUYpOworICAgICAgICAvLyBudWxsIHBhcmFtZXRlcgorICAgICAgICB0cnkgeworICAgICAgICAgICAgdHJ1c3RNRlswXS5pbml0KGtzTnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbChleCArICIgdW5leHBlY3RlZCBleGNlcHRpb24gd2FzIHRocm93biBmb3IgbnVsbCBwYXJhbWV0ZXIiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmluaXQoS2V5U3RvcmUga2V5U3RvcmUpPC9jb2RlPgorICAgICAqIEFzc2VydGlvbjogY2FsbCBtZXRob2Qgd2l0aCBub3QgbnVsbCBwYXJhbWV0ZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2luaXRMamF2YV9zZWN1cml0eV9LZXlTdG9yZV8wMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBLZXlTdG9yZSBrcyA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5W10gdHJ1c3RNRiA9IGNyZWF0ZVRNRmFjKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIlRydXN0TWFuYWdlckZhY3Rvcnkgb2JqZWN0cyB3ZXJlIG5vdCBjcmVhdGVkIiwgdHJ1c3RNRik7CisKKyAgICAgICAgLy8gbm90IG51bGwgcGFyYW1ldGVyCisgICAgICAgIHRydXN0TUZbMF0uaW5pdChrcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+aW5pdChNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMgcGFyYW1zKTwvY29kZT4KKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gd2hlbiBwYXJhbXMgaXMgbnVsbAorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIk1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyBvYmplY3QgaXMgbm90IHN1cHBvcnRlZCAiCisgICAgICAgICAgICAgICAgICArICJhbmQgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB3YXMgdGhyb3duLiIpCisgICAgcHVibGljIHZvaWQgdGVzdF9pbml0TGphdmF4X25ldF9zc2xfTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyBwYXIgPSBudWxsOworICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5W10gdHJ1c3RNRiA9IGNyZWF0ZVRNRmFjKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIlRydXN0TWFuYWdlckZhY3Rvcnkgb2JqZWN0cyB3ZXJlIG5vdCBjcmVhdGVkIiwgdHJ1c3RNRik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdHJ1c3RNRi5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0cnVzdE1GW2ldLmluaXQocGFyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBrZXlBbGcgPSAiRFNBIjsKKyAgICAgICAgU3RyaW5nIHZhbGlkQ2FOYW1lUmZjMjI1MyA9ICgiQ049VGVzdCBDQSwiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiT1U9VGVzdGluZyBEaXZpc2lvbiwiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiTz1UZXN0IEl0IEFsbCwiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiTD1UZXN0IFRvd24sIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIlNUPVRlc3RpZm9ybmlhLCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJDPVRlc3RsYW5kIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleVN0b3JlIGtTdG9yZSA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICAgICAga1N0b3JlLmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBQdWJsaWNLZXkgcGsgPSBuZXcgVGVzdEtleVBhaXIoa2V5QWxnKS5nZXRQdWJsaWMoKTsKKyAgICAgICAgICAgIFRydXN0QW5jaG9yIHRhID0gbmV3IFRydXN0QW5jaG9yKHZhbGlkQ2FOYW1lUmZjMjI1MywgcGssIGdldEZ1bGxFbmNvZGluZygpKTsKKyAgICAgICAgICAgIFNldDxUcnVzdEFuY2hvcj4gdHJ1c3RBbmNob3JzID0gbmV3IEhhc2hTZXQ8VHJ1c3RBbmNob3I+KCk7CisgICAgICAgICAgICB0cnVzdEFuY2hvcnMuYWRkKHRhKTsKKyAgICAgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3IgeGNzID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKyAgICAgICAgICAgIFBLSVhCdWlsZGVyUGFyYW1ldGVycyBwa2l4QlAgPSBuZXcgUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzKHRydXN0QW5jaG9ycywgeGNzKTsKKyAgICAgICAgICAgIENlcnRQYXRoVHJ1c3RNYW5hZ2VyUGFyYW1ldGVycyBjcHRtcCA9IG5ldyBDZXJ0UGF0aFRydXN0TWFuYWdlclBhcmFtZXRlcnMocGtpeEJQKTsKKyAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkgdG1mID0gVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShnZXREZWZhdWx0QWxnb3JpdGhtKCkpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0bWYuaW5pdChjcHRtcCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGV4ICsgIiB3YXMgdGhyb3duIGZvciBpbml0KE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyBzcGVjKSIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gZm9yIGNvbmZpZ3VyYXRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIGdldEZ1bGxFbmNvZGluZygpIHsKKyAgICAgICAgLy8gRE8gTk9UIE1PRElGWSEKKyAgICAgICAgcmV0dXJuIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgIChieXRlKTB4MzAsKGJ5dGUpMHg4MSwoYnl0ZSkweDhjLChieXRlKTB4YTAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg0NCwoYnl0ZSkweDMwLChieXRlKTB4MTYsKGJ5dGUpMHg4NiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDBlLChieXRlKTB4NjYsKGJ5dGUpMHg2OSwoYnl0ZSkweDZjLAorICAgICAgICAgICAgICAgIChieXRlKTB4NjUsKGJ5dGUpMHgzYSwoYnl0ZSkweDJmLChieXRlKTB4MmYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2NiwoYnl0ZSkweDZmLChieXRlKTB4NmYsKGJ5dGUpMHgyZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDYzLChieXRlKTB4NmYsKGJ5dGUpMHg2ZCwoYnl0ZSkweDgwLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDEsKGJ5dGUpMHgwMCwoYnl0ZSkweDgxLChieXRlKTB4MDEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwMSwoYnl0ZSkweDMwLChieXRlKTB4MTYsKGJ5dGUpMHg4NiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDBlLChieXRlKTB4NjYsKGJ5dGUpMHg2OSwoYnl0ZSkweDZjLAorICAgICAgICAgICAgICAgIChieXRlKTB4NjUsKGJ5dGUpMHgzYSwoYnl0ZSkweDJmLChieXRlKTB4MmYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2MiwoYnl0ZSkweDYxLChieXRlKTB4NzIsKGJ5dGUpMHgyZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDYzLChieXRlKTB4NmYsKGJ5dGUpMHg2ZCwoYnl0ZSkweDgwLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDEsKGJ5dGUpMHgwMCwoYnl0ZSkweDgxLChieXRlKTB4MDEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwMSwoYnl0ZSkweDMwLChieXRlKTB4MTIsKGJ5dGUpMHg4NiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDBhLChieXRlKTB4NjYsKGJ5dGUpMHg2OSwoYnl0ZSkweDZjLAorICAgICAgICAgICAgICAgIChieXRlKTB4NjUsKGJ5dGUpMHgzYSwoYnl0ZSkweDJmLChieXRlKTB4MmYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2ZCwoYnl0ZSkweDc1LChieXRlKTB4NzUsKGJ5dGUpMHg4MCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAxLChieXRlKTB4MDAsKGJ5dGUpMHg4MSwoYnl0ZSkweDAxLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDEsKGJ5dGUpMHhhMSwoYnl0ZSkweDQ0LChieXRlKTB4MzAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgxNiwoYnl0ZSkweDg2LChieXRlKTB4MGUsKGJ5dGUpMHg2OCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDc0LChieXRlKTB4NzQsKGJ5dGUpMHg3MCwoYnl0ZSkweDNhLAorICAgICAgICAgICAgICAgIChieXRlKTB4MmYsKGJ5dGUpMHgyZiwoYnl0ZSkweDY2LChieXRlKTB4NmYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2ZiwoYnl0ZSkweDJlLChieXRlKTB4NjMsKGJ5dGUpMHg2ZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDZkLChieXRlKTB4ODAsKGJ5dGUpMHgwMSwoYnl0ZSkweDAwLAorICAgICAgICAgICAgICAgIChieXRlKTB4ODEsKGJ5dGUpMHgwMSwoYnl0ZSkweDAxLChieXRlKTB4MzAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgxNiwoYnl0ZSkweDg2LChieXRlKTB4MGUsKGJ5dGUpMHg2OCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDc0LChieXRlKTB4NzQsKGJ5dGUpMHg3MCwoYnl0ZSkweDNhLAorICAgICAgICAgICAgICAgIChieXRlKTB4MmYsKGJ5dGUpMHgyZiwoYnl0ZSkweDYyLChieXRlKTB4NjEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg3MiwoYnl0ZSkweDJlLChieXRlKTB4NjMsKGJ5dGUpMHg2ZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDZkLChieXRlKTB4ODAsKGJ5dGUpMHgwMSwoYnl0ZSkweDAwLAorICAgICAgICAgICAgICAgIChieXRlKTB4ODEsKGJ5dGUpMHgwMSwoYnl0ZSkweDAxLChieXRlKTB4MzAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgxMiwoYnl0ZSkweDg2LChieXRlKTB4MGEsKGJ5dGUpMHg2OCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDc0LChieXRlKTB4NzQsKGJ5dGUpMHg3MCwoYnl0ZSkweDNhLAorICAgICAgICAgICAgICAgIChieXRlKTB4MmYsKGJ5dGUpMHgyZiwoYnl0ZSkweDZkLChieXRlKTB4NzUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg3NSwoYnl0ZSkweDgwLChieXRlKTB4MDEsKGJ5dGUpMHgwMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDgxLChieXRlKTB4MDEsKGJ5dGUpMHgwMQorICAgICAgICB9OworICAgIH0KK30KKworLyoqCisgKiBBZGRpZmlvbmFsIGNsYXNzIHRvIHZlcmlmeSBUcnVzdE1hbmFnZXJGYWN0b3J5IGNvbnN0cnVjdG9yCisgKi8KKworY2xhc3MgbXlUcnVzdE1hbmFnZXJGYWN0b3J5IGV4dGVuZHMgVHJ1c3RNYW5hZ2VyRmFjdG9yeSB7CisgICAgcHVibGljIG15VHJ1c3RNYW5hZ2VyRmFjdG9yeShUcnVzdE1hbmFnZXJGYWN0b3J5U3BpIHNwaSwgUHJvdmlkZXIgcHJvdiwKKyAgICAgICAgICAgIFN0cmluZyBhbGcpIHsKKyAgICAgICAgc3VwZXIoc3BpLCBwcm92LCBhbGcpOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1RydXN0TWFuYWdlckZhY3RvcnkyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1RydXN0TWFuYWdlckZhY3RvcnkyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjMDc2MGYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvVHJ1c3RNYW5hZ2VyRmFjdG9yeTJUZXN0LmphdmEKQEAgLTAsMCArMSwyNTUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworCitpbXBvcnQgamF2YXgubmV0LnNzbC5NYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXJGYWN0b3J5OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuU3BpRW5nVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnhuZXQudGVzdHMuc3VwcG9ydC5NeVRydXN0TWFuYWdlckZhY3RvcnlTcGk7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciBUcnVzdE1hbmFnZXJGYWN0b3J5IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcworICoKKyAqLworcHVibGljIGNsYXNzIFRydXN0TWFuYWdlckZhY3RvcnkyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgc3J2VHJ1c3RNYW5hZ2VyRmFjdG9yeSA9ICJUcnVzdE1hbmFnZXJGYWN0b3J5IjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZGVmYXVsdEFsZyA9ICJUTUYiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUcnVzdE1hbmFnZXJGYWN0b3J5UHJvdmlkZXJDbGFzcyA9ICJvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC50ZXN0cy5zdXBwb3J0Lk15VHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaSI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBpbnZhbGlkVmFsdWVzID0gU3BpRW5nVXRpbHMuaW52YWxpZFZhbHVlczsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIHZhbGlkVmFsdWVzOworCisgICAgc3RhdGljIHsKKyAgICAgICAgdmFsaWRWYWx1ZXMgPSBuZXcgU3RyaW5nWzRdOworICAgICAgICB2YWxpZFZhbHVlc1swXSA9IGRlZmF1bHRBbGc7CisgICAgICAgIHZhbGlkVmFsdWVzWzFdID0gZGVmYXVsdEFsZy50b0xvd2VyQ2FzZSgpOworICAgICAgICB2YWxpZFZhbHVlc1syXSA9ICJUbWYiOworICAgICAgICB2YWxpZFZhbHVlc1szXSA9ICJ0TUYiOworICAgIH0KKworICAgIFByb3ZpZGVyIG1Qcm92OworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgbVByb3YgPSAobmV3IFNwaUVuZ1V0aWxzKCkpLm5ldyBNeVByb3ZpZGVyKCJNeVRNRlByb3ZpZGVyIiwKKyAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yIHRlc3RpbmciLCBzcnZUcnVzdE1hbmFnZXJGYWN0b3J5LmNvbmNhdCgiLiIpCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGRlZmF1bHRBbGcpLCBUcnVzdE1hbmFnZXJGYWN0b3J5UHJvdmlkZXJDbGFzcyk7CisgICAgICAgIFNlY3VyaXR5Lmluc2VydFByb3ZpZGVyQXQobVByb3YsIDEpOworICAgIH0KKworICAgIC8qCisgICAgICogQHNlZSBUZXN0Q2FzZSN0ZWFyRG93bigpCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICAgICAgU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIobVByb3YuZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tSZXN1bHQoVHJ1c3RNYW5hZ2VyRmFjdG9yeSB0bWYpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBLZXlTdG9yZSBrU3RvcmUgPSBudWxsOworICAgICAgICBNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMgbWZwID0gbnVsbDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG1mLmluaXQoa1N0b3JlKTsKKyAgICAgICAgICAgIGZhaWwoIktleVN0b3JlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgdG1mLmluaXQobWZwKTsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0VHJ1c3RNYW5hZ2VycygpIHNob3VsZCByZXR1cm4gbnVsbCBvYmplY3QiLCB0bWYKKyAgICAgICAgICAgICAgICAuZ2V0VHJ1c3RNYW5hZ2VycygpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAga1N0b3JlID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSk7CisgICAgICAgICAgICBrU3RvcmUubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiZGVmYXVsdCBrZXlzdG9yZSBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdG1mLmluaXQoa1N0b3JlKTsKKyAgICAgICAgbWZwID0gKE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycykgbmV3IE15VHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaS5QYXJhbWV0ZXJzKG51bGwpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdG1mLmluaXQobWZwKTsKKyAgICAgICAgICAgIGZhaWwoIlJ1bnRpbWVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZXhjZXB0aW9uIiwgZS5nZXRDYXVzZSgpIGluc3RhbmNlb2YgS2V5U3RvcmVFeGNlcHRpb24pOworICAgICAgICB9CisgICAgICAgIG1mcCA9IChNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMpIG5ldyBNeVRydXN0TWFuYWdlckZhY3RvcnlTcGkuUGFyYW1ldGVycyhrU3RvcmUpOworICAgICAgICB0bWYuaW5pdChtZnApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb25zOgorICAgICAqIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBudWxsOworICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbm90IGNvcnJlY3Q7CisgICAgICogcmV0dXJucyBUcnVzdE1hbmFnZXJGYWN0b3J5IG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBvciBOdWxsUG9pbnRlckV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIChhbGdvcml0aG0gaXMgbnVsbCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIChhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5IHRtZjsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdG1mID0gVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJOb3QgaW5zdGFuY2VvZiBUcnVzdE1hbmFnZXJGYWN0b3J5IG9iamVjdCIsCisgICAgICAgICAgICAgICAgICAgIHRtZiBpbnN0YW5jZW9mIFRydXN0TWFuYWdlckZhY3RvcnkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwgdG1mLmdldEFsZ29yaXRobSgpLAorICAgICAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsIHRtZi5nZXRQcm92aWRlcigpLCBtUHJvdik7CisgICAgICAgICAgICBjaGVja1Jlc3VsdCh0bWYpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb25zOgorICAgICAqIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBudWxsOworICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbm90IGNvcnJlY3Q7CisgICAgICogdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aGVuIHByb3ZpZGVyIGlzIG51bGwgb3IgZW1wdHk7CisgICAgICogdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgYXZhaWxhYmxlOworICAgICAqIHJldHVybnMgVHJ1c3RNYW5hZ2VyRmFjdG9yeSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEluc3RhbmNlTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShudWxsLCBtUHJvdi5nZXROYW1lKCkpOworICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG9yIE51bGxQb2ludGVyRXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gKGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldLCBtUHJvdgorICAgICAgICAgICAgICAgICAgICAgICAgLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIChhbGdvcml0aG06ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcHJvdiA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgcHJvdik7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gcHJvdmlkZXIgaXMgbnVsbCAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sICIiKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBlbXB0eSAoYWxnb3JpdGhtOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDE7IGogPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnZhbGlkVmFsdWVzW2pdKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gKGFsZ29yaXRobTogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIgcHJvdmlkZXI6ICIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChpbnZhbGlkVmFsdWVzW2pdKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5IHRtZjsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdG1mID0gVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgbVByb3YKKyAgICAgICAgICAgICAgICAgICAgLmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJOb3QgaW5zdGFuY2VvZiBUcnVzdE1hbmFnZXJGYWN0b3J5IG9iamVjdCIsCisgICAgICAgICAgICAgICAgICAgIHRtZiBpbnN0YW5jZW9mIFRydXN0TWFuYWdlckZhY3RvcnkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwgdG1mLmdldEFsZ29yaXRobSgpLAorICAgICAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsIHRtZi5nZXRQcm92aWRlcigpLmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgbVByb3YuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGNoZWNrUmVzdWx0KHRtZik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBQcm92aWRlciBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kCisgICAgICogQXNzZXJ0aW9uczoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbnVsbDsKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG5vdCBjb3JyZWN0OworICAgICAqIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBudWxsOworICAgICAqIHJldHVybnMgVHJ1c3RNYW5hZ2VyRmFjdG9yeSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TGphdmFfbGFuZ19TdHJpbmdMamF2YV9zZWN1cml0eV9Qcm92aWRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZShudWxsLCBtUHJvdik7CisgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gb3IgTnVsbFBvaW50ZXJFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biAoYWxnb3JpdGhtIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0sIG1Qcm92KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gKGFsZ29yaXRobTogIgorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChpbnZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFByb3ZpZGVyIHByb3YgPSBudWxsOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIHByb3YpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHByb3ZpZGVyIGlzIG51bGwgKGFsZ29yaXRobTogIgorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChpbnZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkgdG1mOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0bWYgPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBtUHJvdik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJOb3QgaW5zdGFuY2VvZiBUcnVzdE1hbmFnZXJGYWN0b3J5IG9iamVjdCIsCisgICAgICAgICAgICAgICAgICAgIHRtZiBpbnN0YW5jZW9mIFRydXN0TWFuYWdlckZhY3RvcnkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwgdG1mLmdldEFsZ29yaXRobSgpLAorICAgICAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsIHRtZi5nZXRQcm92aWRlcigpLCBtUHJvdik7CisgICAgICAgICAgICBjaGVja1Jlc3VsdCh0bWYpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1RydXN0TWFuYWdlckZhY3RvcnlTcGlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YmRlYjQ1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1RydXN0TWFuYWdlckZhY3RvcnlTcGlUZXN0LmphdmEKQEAgLTAsMCArMSwxMzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKKworaW1wb3J0IGphdmF4Lm5ldC5zc2wuTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuVHJ1c3RNYW5hZ2VyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuVHJ1c3RNYW5hZ2VyRmFjdG9yeTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlckZhY3RvcnlTcGk7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnhuZXQudGVzdHMuc3VwcG9ydC5UcnVzdE1hbmFnZXJGYWN0b3J5U3BpSW1wbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC50ZXN0cy5zdXBwb3J0Lk15VHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaS5QYXJhbWV0ZXJzOworCitwdWJsaWMgY2xhc3MgVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIFRydXN0TWFuYWdlckZhY3RvcnlTcGlJbXBsIGZhY3RvcnkgPSBuZXcgVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaUltcGwoKTsKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlckZhY3RvcnlTcGkjVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnlTcGlJbXBsIHRtZiA9IG5ldyBUcnVzdE1hbmFnZXJGYWN0b3J5U3BpSW1wbCgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24KKyAgICAgKiBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlckZhY3RvcnlTcGkjZW5naW5lSW5pdChLZXlTdG9yZSBrcykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VuZ2luZUluaXRfMDEoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5LnJlc2V0KCk7CisgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyID0gbmV3IE15UHJvdmlkZXIoKTsKKyAgICAgICAgVHJ1c3RNYW5hZ2VyRmFjdG9yeSB0bWYgPSBUcnVzdE1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKCJNeVRNRiIsCisgICAgICAgICAgICAgICAgcHJvdmlkZXIpOworICAgICAgICBLZXlTdG9yZSBrcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrcyA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICAgICAga3MubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgICAgIHRtZi5pbml0KGtzKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoZmFjdG9yeS5pc0VuZ2luZUluaXRDYWxsZWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhrcywgZmFjdG9yeS5nZXRLcygpKTsKKyAgICAgICAgZmFjdG9yeS5yZXNldCgpOworICAgICAgICB0bWYuaW5pdCgoS2V5U3RvcmUpIG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKGZhY3RvcnkuaXNFbmdpbmVJbml0Q2FsbGVkKCkpOworICAgICAgICBhc3NlcnROdWxsKGZhY3RvcnkuZ2V0S3MoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlckZhY3RvcnlTcGkjZW5naW5lSW5pdChNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMgc3BlYykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VuZ2luZUluaXRfMDIoKSB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkucmVzZXQoKTsKKyAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIgPSBuZXcgTXlQcm92aWRlcigpOworICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5IHRtZiA9IFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoIk15VE1GIiwKKyAgICAgICAgICAgICAgICBwcm92aWRlcik7CisgICAgICAgIFBhcmFtZXRlcnMgcHIgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgS2V5U3RvcmUga3MgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAgICAgIGtzLmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBwciA9IG5ldyBQYXJhbWV0ZXJzKGtzKTsKKyAgICAgICAgICAgIHRtZi5pbml0KHByKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoZmFjdG9yeS5pc0VuZ2luZUluaXRDYWxsZWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhwciwgZmFjdG9yeS5nZXRTcGVjKCkpOworICAgICAgICBmYWN0b3J5LnJlc2V0KCk7CisgICAgICAgIHRtZi5pbml0KChNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMpIG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKGZhY3RvcnkuaXNFbmdpbmVJbml0Q2FsbGVkKCkpOworICAgICAgICBhc3NlcnROdWxsKGZhY3RvcnkuZ2V0U3BlYygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqIGphdmF4Lm5ldC5zc2wuVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaSNlbmdpbmVHZXRUcnVzdE1hbmFnZXJzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2VuZ2luZUdldFRydXN0TWFuYWdlcnMoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeS5yZXNldCgpOworICAgICAgICBQcm92aWRlciBwcm92aWRlciA9IG5ldyBNeVByb3ZpZGVyKCk7CisgICAgICAgIFRydXN0TWFuYWdlckZhY3RvcnkgdG1mID0gVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXRJbnN0YW5jZSgiTXlUTUYiLAorICAgICAgICAgICAgICAgIHByb3ZpZGVyKTsKKyAgICAgICAgVHJ1c3RNYW5hZ2VyW10gdG0gPSB0bWYuZ2V0VHJ1c3RNYW5hZ2VycygpOworICAgICAgICBhc3NlcnRUcnVlKGZhY3RvcnkuaXNFbmdpbmVHZXRUcnVzdE1hbmFnZXJzQ2FsbGVkKCkpOworICAgICAgICBmYWN0b3J5LnJlc2V0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZSBrcyA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICAgICAga3MubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgICAgIHRtZi5pbml0KGtzKTsKKyAgICAgICAgICAgIHRtID0gdG1mLmdldFRydXN0TWFuYWdlcnMoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZmFjdG9yeS5pc0VuZ2luZUdldFRydXN0TWFuYWdlcnNDYWxsZWQoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KK30KKworY2xhc3MgTXlQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyIHsKKworICAgIHB1YmxpYyBNeVByb3ZpZGVyKCkgeworICAgICAgICBzdXBlcigiTXlQcm92aWRlciIsIDEuMCwgIk15IFRlc3QgUHJvdmlkZXIiKTsKKyAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjxWb2lkPigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBWb2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICBwdXQoIlRydXN0TWFuYWdlckZhY3RvcnkuTXlUTUYiLAorICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnRlc3RzLnN1cHBvcnQuVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaUltcGwiKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1g1MDlFeHRlbmRlZEtleU1hbmFnZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvWDUwOUV4dGVuZGVkS2V5TWFuYWdlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MTRmZWQ4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1g1MDlFeHRlbmRlZEtleU1hbmFnZXJUZXN0LmphdmEKQEAgLTAsMCArMSwxNzYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QcmluY2lwYWw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CisKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlg1MDlFeHRlbmRlZEtleU1hbmFnZXI7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlg1MDlFeHRlbmRlZEtleU1hbmFnZXI8L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgY2xhc3MgTW9ja1g1MDlFeHRlbmRlZEtleU1hbmFnZXIgZXh0ZW5kcyBYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyIHsKKyAgICAgICAgcHVibGljIE1vY2tYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyKCkgeworICAgICAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuWDUwOUtleU1hbmFnZXIjY2hvb3NlQ2xpZW50QWxpYXMoamF2YS5sYW5nLlN0cmluZ1tdLCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbFtdLCBqYXZhLm5ldC5Tb2NrZXQpCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgU3RyaW5nIGNob29zZUNsaWVudEFsaWFzKFN0cmluZ1tdIGFyZzAsIFByaW5jaXBhbFtdIGFyZzEsIFNvY2tldCBhcmcyKSB7CisgICAgICAgICAgICAvLyBpdCBpcyBhIGZha2UKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5YNTA5S2V5TWFuYWdlciNjaG9vc2VTZXJ2ZXJBbGlhcyhqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbFtdLCBqYXZhLm5ldC5Tb2NrZXQpCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgU3RyaW5nIGNob29zZVNlcnZlckFsaWFzKFN0cmluZyBhcmcwLCBQcmluY2lwYWxbXSBhcmcxLCBTb2NrZXQgYXJnMikgeworICAgICAgICAgICAgLy8gaXQgaXMgYSBmYWtlCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuWDUwOUtleU1hbmFnZXIjZ2V0Q2VydGlmaWNhdGVDaGFpbihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFg1MDlDZXJ0aWZpY2F0ZVtdIGdldENlcnRpZmljYXRlQ2hhaW4oU3RyaW5nIGFyZzApIHsKKyAgICAgICAgICAgIC8vIGl0IGlzIGEgZmFrZQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlg1MDlLZXlNYW5hZ2VyI2dldENsaWVudEFsaWFzZXMoamF2YS5sYW5nLlN0cmluZywgamF2YS5zZWN1cml0eS5QcmluY2lwYWxbXSkKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRDbGllbnRBbGlhc2VzKFN0cmluZyBhcmcwLCBQcmluY2lwYWxbXSBhcmcxKSB7CisgICAgICAgICAgICAvLyBpdCBpcyBhIGZha2UKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5YNTA5S2V5TWFuYWdlciNnZXRQcml2YXRlS2V5KGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgUHJpdmF0ZUtleSBnZXRQcml2YXRlS2V5KFN0cmluZyBhcmcwKSB7CisgICAgICAgICAgICAvLyBpdCBpcyBhIGZha2UKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5YNTA5S2V5TWFuYWdlciNnZXRTZXJ2ZXJBbGlhc2VzKGphdmEubGFuZy5TdHJpbmcsIGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsW10pCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgU3RyaW5nW10gZ2V0U2VydmVyQWxpYXNlcyhTdHJpbmcgYXJnMCwgUHJpbmNpcGFsW10gYXJnMSkgeworICAgICAgICAgICAgLy8gaXQgaXMgYSBmYWtlCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuWDUwOUV4dGVuZGVkS2V5TWFuYWdlciNYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IE1vY2tYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuWDUwOUV4dGVuZGVkS2V5TWFuYWdlcgorICAgICAqICAgICAjY2hvb3NlRW5naW5lQ2xpZW50QWxpYXMoamF2YS5sYW5nLlN0cmluZ1tdLAorICAgICAqICAgICBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbFtdLCBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0X2Nob29zZUVuZ2luZUNsaWVudEFsaWFzKCkgeworICAgICAgICBYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyIGttID0gbmV3IE15WDUwOUV4dGVuZGVkS2V5TWFuYWdlcigpOworICAgICAgICBpZiAoa20uY2hvb3NlRW5naW5lQ2xpZW50QWxpYXMobnVsbCwgbnVsbCwgbnVsbCkgIT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbCgibm9uIG51bGwgcmVzdWx0Iik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlg1MDlFeHRlbmRlZEtleU1hbmFnZXIKKyAgICAgKiAgICAgI2Nob29zZUVuZ2luZVNlcnZlckFsaWFzKGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgIGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsW10sIGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfY2hvb3NlRW5naW5lU2VydmVyQWxpYXMoKSB7CisgICAgICAgIFg1MDlFeHRlbmRlZEtleU1hbmFnZXIga20gPSBuZXcgTXlYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyKCk7CisgICAgICAgIGlmIChrbS5jaG9vc2VFbmdpbmVTZXJ2ZXJBbGlhcyhudWxsLCBudWxsLCBudWxsKSAhPSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKCJub24gbnVsbCByZXN1bHQiKTsKKyAgICAgICAgfQorICAgIH0KKworfQorCitjbGFzcyBNeVg1MDlFeHRlbmRlZEtleU1hbmFnZXIgZXh0ZW5kcyBYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyIHsKKworICAgIC8qCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlg1MDlLZXlNYW5hZ2VyI2Nob29zZUNsaWVudEFsaWFzKGphdmEubGFuZy5TdHJpbmdbXSwKKyAgICAgKiAgICAgIGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsW10sIGphdmEubmV0LlNvY2tldCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGNob29zZUNsaWVudEFsaWFzKFN0cmluZ1tdIGtleVR5cGUsIFByaW5jaXBhbFtdIGlzc3VlcnMsCisgICAgICAgICAgICBTb2NrZXQgc29ja2V0KSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlg1MDlLZXlNYW5hZ2VyI2Nob29zZVNlcnZlckFsaWFzKGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgICBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbFtdLCBqYXZhLm5ldC5Tb2NrZXQpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBjaG9vc2VTZXJ2ZXJBbGlhcyhTdHJpbmcga2V5VHlwZSwgUHJpbmNpcGFsW10gaXNzdWVycywKKyAgICAgICAgICAgIFNvY2tldCBzb2NrZXQpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuWDUwOUtleU1hbmFnZXIjZ2V0Q2VydGlmaWNhdGVDaGFpbihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBYNTA5Q2VydGlmaWNhdGVbXSBnZXRDZXJ0aWZpY2F0ZUNoYWluKFN0cmluZyBhbGlhcykgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5YNTA5S2V5TWFuYWdlciNnZXRDbGllbnRBbGlhc2VzKGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgICBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbFtdKQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRDbGllbnRBbGlhc2VzKFN0cmluZyBrZXlUeXBlLCBQcmluY2lwYWxbXSBpc3N1ZXJzKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlg1MDlLZXlNYW5hZ2VyI2dldFNlcnZlckFsaWFzZXMoamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgIGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsW10pCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIGdldFNlcnZlckFsaWFzZXMoU3RyaW5nIGtleVR5cGUsIFByaW5jaXBhbFtdIGlzc3VlcnMpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuWDUwOUtleU1hbmFnZXIjZ2V0UHJpdmF0ZUtleShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBQcml2YXRlS2V5IGdldFByaXZhdGVLZXkoU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1g1MDlLZXlNYW5hZ2VyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1g1MDlLZXlNYW5hZ2VyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRkZGRiYzYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvWDUwOUtleU1hbmFnZXJUZXN0LmphdmEKQEAgLTAsMCArMSw3NTMgQEAKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5QS0NTOEVuY29kZWRLZXlTcGVjOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlckZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5YNTA5S2V5TWFuYWdlcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlg1MDlLZXlNYW5hZ2VyPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKi8KK3B1YmxpYyBjbGFzcyBYNTA5S2V5TWFuYWdlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIFg1MDlLZXlNYW5hZ2VyIG1hbmFnZXI7CisgICAgcHJpdmF0ZSBLZXlNYW5hZ2VyRmFjdG9yeSBmYWN0b3J5OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENMSUVOVCA9ICJDTElFTlQiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRVJWRVIgPSAiU0VSVkVSIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFlQRV9SU0EgPSAiUlNBIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gUEFTU1dPUkQgPSAiMTIzNCIudG9DaGFyQXJyYXkoKTsKKworICAgIHByaXZhdGUgU3RyaW5nIGtleVR5cGU7CisgICAgcHJpdmF0ZSBLZXlTdG9yZSBrZXlUZXN0OworICAgIHByaXZhdGUgWDUwOUNlcnRpZmljYXRlW10gY2VydDsKKyAgICBwcml2YXRlIFByaXZhdGVLZXlbXSBrZXlzOworCisKKyAgICAvKgorICAgICAgIENlcnRpZmljYXRlOgorICAgICAgICAgICBEYXRhOgorICAgICAgICAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICAgICAgICAgU2VyaWFsIE51bWJlcjogMCAoMHgwKQorICAgICAgICAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgICAgICAgICBJc3N1ZXI6IEM9QU4sIFNUPUFuZHJvaWQsIE89QW5kcm9pZCwgT1U9QW5kcm9pZCwgQ049QW5kcm9pZC9lbWFpbEFkZHJlc3M9YW5kcm9pZEBhbmRyb2lkLmNvbQorICAgICAgICAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgICAgICAgICBOb3QgQmVmb3JlOiBNYXIgMjAgMTc6MDA6MDYgMjAwOSBHTVQKKyAgICAgICAgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBNYXIgMTkgMTc6MDA6MDYgMjAxMiBHTVQKKyAgICAgICAgICAgICAgIFN1YmplY3Q6IEM9QU4sIFNUPUFuZHJvaWQsIE89QW5kcm9pZCwgT1U9QW5kcm9pZCwgQ049QW5kcm9pZC9lbWFpbEFkZHJlc3M9YW5kcm9pZEBhbmRyb2lkLmNvbQorICAgICAgICAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICAgICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgICAgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDEwMjQgYml0KQorICAgICAgICAgICAgICAgICAgICAgICBNb2R1bHVzICgxMDI0IGJpdCk6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAwMDphYTo0Mjo0MDplZDo5MjoyMToxNzo5OTo1ZjowZTplNDo0MjpiODpjYjoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIDY2OjNkOjYzOjJhOjE2OjM0OjNjOjdiOmQzOjNlOjFmOmE4OjNmOmJkOjlhOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgZWI6YjM6MjQ6NmI6OGM6ZTQ6ZGE6MmY6MzE6YmM6NjE6MDc6Mjc6MmU6Mjg6CisgICAgICAgICAgICAgICAgICAgICAgICAgICA3MTo3Nzo1ODphZTpiNDo4OTo3YzplYjpiMDowNjoyNDowNzo1NzozYzo1NDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIDcxOmRiOjcxOjQxOjA1OmFiOjNkOjlmOjA1OmQyOmNhOmNiOjFjOmJmOjlkOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgOGE6MjE6OTY6OGY6MTM6NjE6MjU6Njk6MTI6M2I6Nzc6YmQ6Zjc6MzQ6YjI6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAwOTphOTplMDo1Mjo5NDo0NDozMTpjZTpkYjozZDplYjo2NDpmMTpkNjpjYToKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGM1OjdkOjJmOmQ2OjZmOjhkOmU0OjI5OjhiOjA2Ojk4OjhhOjk1OjNkOjdhOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgOTc6NDE6OWE6ZjE6NjY6YzU6MDk6ODI6MGQKKyAgICAgICAgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAgICAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICAgICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6CisgICAgICAgICAgICAgICAgICAgICAgIEU3OjlCOjdEOjkwOjI5OkVBOjkwOjBCOjdGOjA4OjQxOjc2OjRFOjQxOjIzOkU4OjQzOjJDOkE5OjAzCisgICAgICAgICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjoKKyAgICAgICAgICAgICAgICAgICAgICAga2V5aWQ6RTc6OUI6N0Q6OTA6Mjk6RUE6OTA6MEI6N0Y6MDg6NDE6NzY6NEU6NDE6MjM6RTg6NDM6MkM6QTk6MDMKKyAgICAgICAgICAgICAgICAgICAgICAgRGlyTmFtZTovQz1BTi9TVD1BbmRyb2lkL089QW5kcm9pZC9PVT1BbmRyb2lkL0NOPUFuZHJvaWQvZW1haWxBZGRyZXNzPWFuZHJvaWRAYW5kcm9pZC5jb20KKyAgICAgICAgICAgICAgICAgICAgICAgc2VyaWFsOjAwCisKKyAgICAgICAgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6CisgICAgICAgICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgICAgICAgICAxNDo5ODozMDoyOTo0MjplZjphYjplNjpiODoyNTo0Yjo1NTo4NTowNDphNTpjNDpkZDoxZDoKKyAgICAgICAgICAgICAgIDhiOjZhOmMxOjZmOjZjOjFjOjFkOmMzOjYxOjM0OjMwOjA3OjM0OjRkOjZhOjhiOjU1OjZmOgorICAgICAgICAgICAgICAgNzU6NTU6NmU6MTU6NTg6YzU6Zjg6YWY6ZTA6YmU6NzM6YmE6ZDk6YTU6ODU6ZDc6YjU6MWE6CisgICAgICAgICAgICAgICA4NTo0NDoyYjo4ODpmZDpjYzpjYjpkMTplZDo0Njo2OTo0MzpmZjo1OTphZTo5Yjo1YzoxNzoKKyAgICAgICAgICAgICAgIDI2OmRhOmVlOmM4OmJmOjY3OjU1OjAxOmEwOjBlOjEwOmI5Ojg1OjQ5OjU0OmQ5Ojc5OjFlOgorICAgICAgICAgICAgICAgN2I6MmU6NmY6NjU6NGY6ZDk6MTA6MmU6OWQ6Yjg6OTI6NjM6Njc6NzQ6OGI6MjI6MGQ6NmQ6CisgICAgICAgICAgICAgICBkMzo1ZDo5ZToyOTo2MzpmOTozNjo5MzoxYjphNzo4MDplMjpiMTpmMTpiZjoyOToxOTo4MToKKyAgICAgICAgICAgICAgIDNkOjA3CisgICAgICovCisgICAgU3RyaW5nIGNlcnRpZmljYXRlID0gIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICAgICAgICAgKyAiTUlJRFB6Q0NBcWlnQXdJQkFnSUJBREFOQmdrcWhraUc5dzBCQVFVRkFEQjVNUXN3Q1FZRFZRUUdFd0pCVGpFUVxuIgorICAgICAgICAgICAgKyAiTUE0R0ExVUVDQk1IUVc1a2NtOXBaREVRTUE0R0ExVUVDaE1IUVc1a2NtOXBaREVRTUE0R0ExVUVDeE1IUVc1a1xuIgorICAgICAgICAgICAgKyAiY205cFpERVFNQTRHQTFVRUF4TUhRVzVrY205cFpERWlNQ0FHQ1NxR1NJYjNEUUVKQVJZVFlXNWtjbTlwWkVCaFxuIgorICAgICAgICAgICAgKyAiYm1SeWIybGtMbU52YlRBZUZ3MHdPVEF6TWpBeE56QXdNRFphRncweE1qQXpNVGt4TnpBd01EWmFNSGt4Q3pBSlxuIgorICAgICAgICAgICAgKyAiQmdOVkJBWVRBa0ZPTVJBd0RnWURWUVFJRXdkQmJtUnliMmxrTVJBd0RnWURWUVFLRXdkQmJtUnliMmxrTVJBd1xuIgorICAgICAgICAgICAgKyAiRGdZRFZRUUxFd2RCYm1SeWIybGtNUkF3RGdZRFZRUURFd2RCYm1SeWIybGtNU0l3SUFZSktvWklodmNOQVFrQlxuIgorICAgICAgICAgICAgKyAiRmhOaGJtUnliMmxrUUdGdVpISnZhV1F1WTI5dE1JR2ZNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCaVFLQlxuIgorICAgICAgICAgICAgKyAiZ1FDcVFrRHRraUVYbVY4TzVFSzR5Mlk5WXlvV05EeDcwejRmcUQrOW11dXpKR3VNNU5vdk1ieGhCeWN1S0hGM1xuIgorICAgICAgICAgICAgKyAiV0s2MGlYenJzQVlrQjFjOFZISGJjVUVGcXoyZkJkTEt5eHkvbllvaGxvOFRZU1ZwRWp0M3ZmYzBzZ21wNEZLVVxuIgorICAgICAgICAgICAgKyAiUkRITzJ6M3JaUEhXeXNWOUw5WnZqZVFwaXdhWWlwVTllcGRCbXZGbXhRbUNEUUlEQVFBQm80SFdNSUhUTUIwR1xuIgorICAgICAgICAgICAgKyAiQTFVZERnUVdCQlRubTMyUUtlcVFDMzhJUVhaT1FTUG9ReXlwQXpDQm93WURWUjBqQklHYk1JR1lnQlRubTMyUVxuIgorICAgICAgICAgICAgKyAiS2VxUUMzOElRWFpPUVNQb1F5eXBBNkY5cEhzd2VURUxNQWtHQTFVRUJoTUNRVTR4RURBT0JnTlZCQWdUQjBGdVxuIgorICAgICAgICAgICAgKyAiWkhKdmFXUXhFREFPQmdOVkJBb1RCMEZ1WkhKdmFXUXhFREFPQmdOVkJBc1RCMEZ1WkhKdmFXUXhFREFPQmdOVlxuIgorICAgICAgICAgICAgKyAiQkFNVEIwRnVaSEp2YVdReElqQWdCZ2txaGtpRzl3MEJDUUVXRTJGdVpISnZhV1JBWVc1a2NtOXBaQzVqYjIyQ1xuIgorICAgICAgICAgICAgKyAiQVFBd0RBWURWUjBUQkFVd0F3RUIvekFOQmdrcWhraUc5dzBCQVFVRkFBT0JnUUFVbURBcFF1K3I1cmdsUzFXRlxuIgorICAgICAgICAgICAgKyAiQktYRTNSMkxhc0Z2YkJ3ZHcyRTBNQWMwVFdxTFZXOTFWVzRWV01YNHIrQytjN3JacFlYWHRScUZSQ3VJL2N6TFxuIgorICAgICAgICAgICAgKyAiMGUxR2FVUC9XYTZiWEJjbTJ1N0l2MmRWQWFBT0VMbUZTVlRaZVI1N0xtOWxUOWtRTHAyNGttTm5kSXNpRFczVFxuIgorICAgICAgICAgICAgKyAiWFo0cFkvazJreHVuZ09LeDhiOHBHWUU5Qnc9PVxuIgorICAgICAgICAgICAgKyAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLSI7CisKKyAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBjZXJ0QXJyYXkgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oY2VydGlmaWNhdGUKKyAgICAgICAgICAgIC5nZXRCeXRlcygpKTsKKworICAgIC8qCisgICAgICogVGhlIGtleSBpbiBERVIgZm9ybWF0LgorICAgICAqIEJlbG93IGlzIHRoZSBzYW1lIGtleSBpbiBQRU0gZm9ybWF0IGFzIHJlZmVyZW5jZQorICAgICAqLworICAgIGJ5dGVbXSBrZXlCeXRlcyA9IG5ldyBieXRlW10geworICAgICAgICAgICAgKGJ5dGUpMHgzMCwgKGJ5dGUpMHg4MiwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg3NywgKGJ5dGUpMHgwMiwgKGJ5dGUpMHgwMSwgKGJ5dGUpMHgwMCwKKyAgICAgICAgICAgIChieXRlKTB4MzAsIChieXRlKTB4MGQsIChieXRlKTB4MDYsIChieXRlKTB4MDksIChieXRlKTB4MmEsIChieXRlKTB4ODYsIChieXRlKTB4NDgsCisgICAgICAgICAgICAoYnl0ZSkweDg2LCAoYnl0ZSkweGY3LCAoYnl0ZSkweDBkLCAoYnl0ZSkweDAxLCAoYnl0ZSkweDAxLCAoYnl0ZSkweDAxLCAoYnl0ZSkweDA1LAorICAgICAgICAgICAgKGJ5dGUpMHgwMCwgKGJ5dGUpMHgwNCwgKGJ5dGUpMHg4MiwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg2MSwgKGJ5dGUpMHgzMCwgKGJ5dGUpMHg4MiwKKyAgICAgICAgICAgIChieXRlKTB4MDIsIChieXRlKTB4NWQsIChieXRlKTB4MDIsIChieXRlKTB4MDEsIChieXRlKTB4MDAsIChieXRlKTB4MDIsIChieXRlKTB4ODEsCisgICAgICAgICAgICAoYnl0ZSkweDgxLCAoYnl0ZSkweDAwLCAoYnl0ZSkweGFhLCAoYnl0ZSkweDQyLCAoYnl0ZSkweDQwLCAoYnl0ZSkweGVkLCAoYnl0ZSkweDkyLAorICAgICAgICAgICAgKGJ5dGUpMHgyMSwgKGJ5dGUpMHgxNywgKGJ5dGUpMHg5OSwgKGJ5dGUpMHg1ZiwgKGJ5dGUpMHgwZSwgKGJ5dGUpMHhlNCwgKGJ5dGUpMHg0MiwKKyAgICAgICAgICAgIChieXRlKTB4YjgsIChieXRlKTB4Y2IsIChieXRlKTB4NjYsIChieXRlKTB4M2QsIChieXRlKTB4NjMsIChieXRlKTB4MmEsIChieXRlKTB4MTYsCisgICAgICAgICAgICAoYnl0ZSkweDM0LCAoYnl0ZSkweDNjLCAoYnl0ZSkweDdiLCAoYnl0ZSkweGQzLCAoYnl0ZSkweDNlLCAoYnl0ZSkweDFmLCAoYnl0ZSkweGE4LAorICAgICAgICAgICAgKGJ5dGUpMHgzZiwgKGJ5dGUpMHhiZCwgKGJ5dGUpMHg5YSwgKGJ5dGUpMHhlYiwgKGJ5dGUpMHhiMywgKGJ5dGUpMHgyNCwgKGJ5dGUpMHg2YiwKKyAgICAgICAgICAgIChieXRlKTB4OGMsIChieXRlKTB4ZTQsIChieXRlKTB4ZGEsIChieXRlKTB4MmYsIChieXRlKTB4MzEsIChieXRlKTB4YmMsIChieXRlKTB4NjEsCisgICAgICAgICAgICAoYnl0ZSkweDA3LCAoYnl0ZSkweDI3LCAoYnl0ZSkweDJlLCAoYnl0ZSkweDI4LCAoYnl0ZSkweDcxLCAoYnl0ZSkweDc3LCAoYnl0ZSkweDU4LAorICAgICAgICAgICAgKGJ5dGUpMHhhZSwgKGJ5dGUpMHhiNCwgKGJ5dGUpMHg4OSwgKGJ5dGUpMHg3YywgKGJ5dGUpMHhlYiwgKGJ5dGUpMHhiMCwgKGJ5dGUpMHgwNiwKKyAgICAgICAgICAgIChieXRlKTB4MjQsIChieXRlKTB4MDcsIChieXRlKTB4NTcsIChieXRlKTB4M2MsIChieXRlKTB4NTQsIChieXRlKTB4NzEsIChieXRlKTB4ZGIsCisgICAgICAgICAgICAoYnl0ZSkweDcxLCAoYnl0ZSkweDQxLCAoYnl0ZSkweDA1LCAoYnl0ZSkweGFiLCAoYnl0ZSkweDNkLCAoYnl0ZSkweDlmLCAoYnl0ZSkweDA1LAorICAgICAgICAgICAgKGJ5dGUpMHhkMiwgKGJ5dGUpMHhjYSwgKGJ5dGUpMHhjYiwgKGJ5dGUpMHgxYywgKGJ5dGUpMHhiZiwgKGJ5dGUpMHg5ZCwgKGJ5dGUpMHg4YSwKKyAgICAgICAgICAgIChieXRlKTB4MjEsIChieXRlKTB4OTYsIChieXRlKTB4OGYsIChieXRlKTB4MTMsIChieXRlKTB4NjEsIChieXRlKTB4MjUsIChieXRlKTB4NjksCisgICAgICAgICAgICAoYnl0ZSkweDEyLCAoYnl0ZSkweDNiLCAoYnl0ZSkweDc3LCAoYnl0ZSkweGJkLCAoYnl0ZSkweGY3LCAoYnl0ZSkweDM0LCAoYnl0ZSkweGIyLAorICAgICAgICAgICAgKGJ5dGUpMHgwOSwgKGJ5dGUpMHhhOSwgKGJ5dGUpMHhlMCwgKGJ5dGUpMHg1MiwgKGJ5dGUpMHg5NCwgKGJ5dGUpMHg0NCwgKGJ5dGUpMHgzMSwKKyAgICAgICAgICAgIChieXRlKTB4Y2UsIChieXRlKTB4ZGIsIChieXRlKTB4M2QsIChieXRlKTB4ZWIsIChieXRlKTB4NjQsIChieXRlKTB4ZjEsIChieXRlKTB4ZDYsCisgICAgICAgICAgICAoYnl0ZSkweGNhLCAoYnl0ZSkweGM1LCAoYnl0ZSkweDdkLCAoYnl0ZSkweDJmLCAoYnl0ZSkweGQ2LCAoYnl0ZSkweDZmLCAoYnl0ZSkweDhkLAorICAgICAgICAgICAgKGJ5dGUpMHhlNCwgKGJ5dGUpMHgyOSwgKGJ5dGUpMHg4YiwgKGJ5dGUpMHgwNiwgKGJ5dGUpMHg5OCwgKGJ5dGUpMHg4YSwgKGJ5dGUpMHg5NSwKKyAgICAgICAgICAgIChieXRlKTB4M2QsIChieXRlKTB4N2EsIChieXRlKTB4OTcsIChieXRlKTB4NDEsIChieXRlKTB4OWEsIChieXRlKTB4ZjEsIChieXRlKTB4NjYsCisgICAgICAgICAgICAoYnl0ZSkweGM1LCAoYnl0ZSkweDA5LCAoYnl0ZSkweDgyLCAoYnl0ZSkweDBkLCAoYnl0ZSkweDAyLCAoYnl0ZSkweDAzLCAoYnl0ZSkweDAxLAorICAgICAgICAgICAgKGJ5dGUpMHgwMCwgKGJ5dGUpMHgwMSwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg4MSwgKGJ5dGUpMHg4MCwgKGJ5dGUpMHgzNCwgKGJ5dGUpMHg5MSwKKyAgICAgICAgICAgIChieXRlKTB4OGUsIChieXRlKTB4NTAsIChieXRlKTB4OGIsIChieXRlKTB4ZmMsIChieXRlKTB4ZjEsIChieXRlKTB4YjcsIChieXRlKTB4NjYsCisgICAgICAgICAgICAoYnl0ZSkweDM1LCAoYnl0ZSkweDQ3LCAoYnl0ZSkweGRmLCAoYnl0ZSkweDFlLCAoYnl0ZSkweDA1LCAoYnl0ZSkweDk3LCAoYnl0ZSkweDQ0LAorICAgICAgICAgICAgKGJ5dGUpMHhiZSwgKGJ5dGUpMHhmOCwgKGJ5dGUpMHg4MCwgKGJ5dGUpMHhiMCwgKGJ5dGUpMHg5MiwgKGJ5dGUpMHgzOCwgKGJ5dGUpMHgzZCwKKyAgICAgICAgICAgIChieXRlKTB4NGEsIChieXRlKTB4MDIsIChieXRlKTB4MjYsIChieXRlKTB4NDUsIChieXRlKTB4YmYsIChieXRlKTB4ZmEsIChieXRlKTB4MzQsCisgICAgICAgICAgICAoYnl0ZSkweDZhLCAoYnl0ZSkweDM0LCAoYnl0ZSkweDg1LCAoYnl0ZSkweDhjLCAoYnl0ZSkweDk0LCAoYnl0ZSkweDIwLCAoYnl0ZSkweDk1LAorICAgICAgICAgICAgKGJ5dGUpMHhjZiwgKGJ5dGUpMHhjYSwgKGJ5dGUpMHg3NSwgKGJ5dGUpMHgzZSwgKGJ5dGUpMHhlYiwgKGJ5dGUpMHgyNywgKGJ5dGUpMHgwMiwKKyAgICAgICAgICAgIChieXRlKTB4NGYsIChieXRlKTB4YmUsIChieXRlKTB4NjQsIChieXRlKTB4YzAsIChieXRlKTB4NTQsIChieXRlKTB4NzcsIChieXRlKTB4ZGEsCisgICAgICAgICAgICAoYnl0ZSkweGZkLCAoYnl0ZSkweDNlLCAoYnl0ZSkweDc1LCAoYnl0ZSkweDM2LCAoYnl0ZSkweGVjLCAoYnl0ZSkweDk5LCAoYnl0ZSkweDRmLAorICAgICAgICAgICAgKGJ5dGUpMHhjNCwgKGJ5dGUpMHg1NiwgKGJ5dGUpMHhmZiwgKGJ5dGUpMHg0NSwgKGJ5dGUpMHg2MSwgKGJ5dGUpMHhhOCwgKGJ5dGUpMHhhOCwKKyAgICAgICAgICAgIChieXRlKTB4NDEsIChieXRlKTB4ZTQsIChieXRlKTB4NDIsIChieXRlKTB4NzEsIChieXRlKTB4N2EsIChieXRlKTB4OGMsIChieXRlKTB4ODQsCisgICAgICAgICAgICAoYnl0ZSkweGMyLCAoYnl0ZSkweDAyLCAoYnl0ZSkweDQwLCAoYnl0ZSkweDBiLCAoYnl0ZSkweDNkLCAoYnl0ZSkweDQyLCAoYnl0ZSkweGUwLAorICAgICAgICAgICAgKGJ5dGUpMHg4YiwgKGJ5dGUpMHgyMiwgKGJ5dGUpMHhmNywgKGJ5dGUpMHg0YywgKGJ5dGUpMHhhMywgKGJ5dGUpMHhiYiwgKGJ5dGUpMHhkOCwKKyAgICAgICAgICAgIChieXRlKTB4OGYsIChieXRlKTB4NDUsIChieXRlKTB4YTIsIChieXRlKTB4NTUsIChieXRlKTB4YzcsIChieXRlKTB4ZDAsIChieXRlKTB4NmEsCisgICAgICAgICAgICAoYnl0ZSkweDI1LCAoYnl0ZSkweGJmLCAoYnl0ZSkweGRhLCAoYnl0ZSkweDU0LCAoYnl0ZSkweDU3LCAoYnl0ZSkweDE0LCAoYnl0ZSkweDkxLAorICAgICAgICAgICAgKGJ5dGUpMHgwYywgKGJ5dGUpMHgwOSwgKGJ5dGUpMHgwYiwgKGJ5dGUpMHg5YSwgKGJ5dGUpMHg1MCwgKGJ5dGUpMHhjYSwgKGJ5dGUpMHhlNiwKKyAgICAgICAgICAgIChieXRlKTB4OWUsIChieXRlKTB4MjgsIChieXRlKTB4YzMsIChieXRlKTB4NzgsIChieXRlKTB4MzksIChieXRlKTB4MTAsIChieXRlKTB4MDYsCisgICAgICAgICAgICAoYnl0ZSkweDAyLCAoYnl0ZSkweDk2LCAoYnl0ZSkweDEwLCAoYnl0ZSkweDFhLCAoYnl0ZSkweGQyLCAoYnl0ZSkweDRiLCAoYnl0ZSkweDdiLAorICAgICAgICAgICAgKGJ5dGUpMHg2YywgKGJ5dGUpMHg3MiwgKGJ5dGUpMHg5ZSwgKGJ5dGUpMHgxZSwgKGJ5dGUpMHhhYywgKGJ5dGUpMHhkMiwgKGJ5dGUpMHhjMSwKKyAgICAgICAgICAgIChieXRlKTB4MDIsIChieXRlKTB4NDEsIChieXRlKTB4MDAsIChieXRlKTB4ZGUsIChieXRlKTB4MjcsIChieXRlKTB4YmQsIChieXRlKTB4NDMsCisgICAgICAgICAgICAoYnl0ZSkweGE0LCAoYnl0ZSkweGJkLCAoYnl0ZSkweDk1LCAoYnl0ZSkweDE0LCAoYnl0ZSkweDJlLCAoYnl0ZSkweDFjLCAoYnl0ZSkweGEwLAorICAgICAgICAgICAgKGJ5dGUpMHg3NCwgKGJ5dGUpMHhhNSwgKGJ5dGUpMHgzZSwgKGJ5dGUpMHhmYSwgKGJ5dGUpMHhmOSwgKGJ5dGUpMHgxNSwgKGJ5dGUpMHhiMiwKKyAgICAgICAgICAgIChieXRlKTB4MjksIChieXRlKTB4NmEsIChieXRlKTB4MmEsIChieXRlKTB4NDIsIChieXRlKTB4OTQsIChieXRlKTB4NWEsIChieXRlKTB4ZjIsCisgICAgICAgICAgICAoYnl0ZSkweDgxLCAoYnl0ZSkweGYzLCAoYnl0ZSkweGUxLCAoYnl0ZSkweDc2LCAoYnl0ZSkweDQ5LCAoYnl0ZSkweDExLCAoYnl0ZSkweDlkLAorICAgICAgICAgICAgKGJ5dGUpMHgxOCwgKGJ5dGUpMHhjNSwgKGJ5dGUpMHhlYiwgKGJ5dGUpMHhiNiwgKGJ5dGUpMHhiYywgKGJ5dGUpMHg4MSwgKGJ5dGUpMHgzYSwKKyAgICAgICAgICAgIChieXRlKTB4MTQsIChieXRlKTB4OWMsIChieXRlKTB4NDEsIChieXRlKTB4MDEsIChieXRlKTB4NTgsIChieXRlKTB4NTYsIChieXRlKTB4YTksCisgICAgICAgICAgICAoYnl0ZSkweDliLCAoYnl0ZSkweDczLCAoYnl0ZSkweDJmLCAoYnl0ZSkweGQ5LCAoYnl0ZSkweGE4LCAoYnl0ZSkweDhlLCAoYnl0ZSkweGM0LAorICAgICAgICAgICAgKGJ5dGUpMHg0OCwgKGJ5dGUpMHg2OSwgKGJ5dGUpMHgzNSwgKGJ5dGUpMHhlNiwgKGJ5dGUpMHhmNCwgKGJ5dGUpMHg3MywgKGJ5dGUpMHgyZiwKKyAgICAgICAgICAgIChieXRlKTB4ZjksIChieXRlKTB4MTIsIChieXRlKTB4MTIsIChieXRlKTB4NzEsIChieXRlKTB4MDIsIChieXRlKTB4NDEsIChieXRlKTB4MDAsCisgICAgICAgICAgICAoYnl0ZSkweGM0LCAoYnl0ZSkweDMyLCAoYnl0ZSkweDgxLCAoYnl0ZSkweDVkLCAoYnl0ZSkweDE5LCAoYnl0ZSkweDU0LCAoYnl0ZSkweDJjLAorICAgICAgICAgICAgKGJ5dGUpMHgyOSwgKGJ5dGUpMHg1YSwgKGJ5dGUpMHg5ZiwgKGJ5dGUpMHgzNiwgKGJ5dGUpMHg0YywgKGJ5dGUpMHg2ZiwgKGJ5dGUpMHgyZCwKKyAgICAgICAgICAgIChieXRlKTB4ZmQsIChieXRlKTB4NjIsIChieXRlKTB4MGUsIChieXRlKTB4ZTYsIChieXRlKTB4MzcsIChieXRlKTB4YzIsIChieXRlKTB4ZjYsCisgICAgICAgICAgICAoYnl0ZSkweDY5LCAoYnl0ZSkweDY0LCAoYnl0ZSkweGY5LCAoYnl0ZSkweDNhLCAoYnl0ZSkweGNjLCAoYnl0ZSkweGIyLCAoYnl0ZSkweDYzLAorICAgICAgICAgICAgKGJ5dGUpMHgyZiwgKGJ5dGUpMHhhOSwgKGJ5dGUpMHhmZSwgKGJ5dGUpMHg3ZSwgKGJ5dGUpMHg4YiwgKGJ5dGUpMHgyZCwgKGJ5dGUpMHg2OSwKKyAgICAgICAgICAgIChieXRlKTB4MTMsIChieXRlKTB4ZTUsIChieXRlKTB4NjEsIChieXRlKTB4NTgsIChieXRlKTB4YjcsIChieXRlKTB4ZmEsIChieXRlKTB4NTUsCisgICAgICAgICAgICAoYnl0ZSkweDc0LCAoYnl0ZSkweDJjLCAoYnl0ZSkweGU4LCAoYnl0ZSkweGExLCAoYnl0ZSkweGFjLCAoYnl0ZSkweGMzLCAoYnl0ZSkweGRkLAorICAgICAgICAgICAgKGJ5dGUpMHg1YiwgKGJ5dGUpMHg2MiwgKGJ5dGUpMHhhZSwgKGJ5dGUpMHgwYSwgKGJ5dGUpMHgyNywgKGJ5dGUpMHhjZSwgKGJ5dGUpMHhiMCwKKyAgICAgICAgICAgIChieXRlKTB4ZjIsIChieXRlKTB4ODEsIChieXRlKTB4NWYsIChieXRlKTB4OWEsIChieXRlKTB4NmYsIChieXRlKTB4NWYsIChieXRlKTB4M2YsCisgICAgICAgICAgICAoYnl0ZSkweDVkLCAoYnl0ZSkweDAyLCAoYnl0ZSkweDQxLCAoYnl0ZSkweDAwLCAoYnl0ZSkweDkyLCAoYnl0ZSkweDQyLCAoYnl0ZSkweGZmLAorICAgICAgICAgICAgKGJ5dGUpMHhhYywgKGJ5dGUpMHhlNSwgKGJ5dGUpMHg2ZCwgKGJ5dGUpMHg5YywgKGJ5dGUpMHgxNSwgKGJ5dGUpMHgyOSwgKGJ5dGUpMHgzNiwKKyAgICAgICAgICAgIChieXRlKTB4ZDcsIChieXRlKTB4YmQsIChieXRlKTB4NzQsIChieXRlKTB4N2UsIChieXRlKTB4M2UsIChieXRlKTB4YTYsIChieXRlKTB4NzcsCisgICAgICAgICAgICAoYnl0ZSkweGNlLCAoYnl0ZSkweDUwLCAoYnl0ZSkweGNlLCAoYnl0ZSkweDAwLCAoYnl0ZSkweGZjLCAoYnl0ZSkweGNjLCAoYnl0ZSkweGM4LAorICAgICAgICAgICAgKGJ5dGUpMHgwNCwgKGJ5dGUpMHgxOSwgKGJ5dGUpMHhlMywgKGJ5dGUpMHgwMywgKGJ5dGUpMHg3MSwgKGJ5dGUpMHhlOSwgKGJ5dGUpMHgzMSwKKyAgICAgICAgICAgIChieXRlKTB4OWIsIChieXRlKTB4ODgsIChieXRlKTB4OGYsIChieXRlKTB4ZTYsIChieXRlKTB4NWMsIChieXRlKTB4ZWQsIChieXRlKTB4NDYsCisgICAgICAgICAgICAoYnl0ZSkweGY3LCAoYnl0ZSkweDgyLCAoYnl0ZSkweDUyLCAoYnl0ZSkweDRkLCAoYnl0ZSkweGNhLCAoYnl0ZSkweDIwLCAoYnl0ZSkweGViLAorICAgICAgICAgICAgKGJ5dGUpMHgwZCwgKGJ5dGUpMHhjNywgKGJ5dGUpMHhiNiwgKGJ5dGUpMHhkMiwgKGJ5dGUpMHhhZSwgKGJ5dGUpMHgyZSwgKGJ5dGUpMHhmNywKKyAgICAgICAgICAgIChieXRlKTB4YWYsIChieXRlKTB4ZWIsIChieXRlKTB4MmMsIChieXRlKTB4YjksIChieXRlKTB4YmMsIChieXRlKTB4NTAsIChieXRlKTB4ZmMsCisgICAgICAgICAgICAoYnl0ZSkweGY1LCAoYnl0ZSkweDdjLCAoYnl0ZSkweGJhLCAoYnl0ZSkweDk1LCAoYnl0ZSkweDQxLCAoYnl0ZSkweDAyLCAoYnl0ZSkweDQwLAorICAgICAgICAgICAgKGJ5dGUpMHg1NCwgKGJ5dGUpMHhmOCwgKGJ5dGUpMHg0NiwgKGJ5dGUpMHg5YywgKGJ5dGUpMHg2YSwgKGJ5dGUpMHg1ZSwgKGJ5dGUpMHhkMCwKKyAgICAgICAgICAgIChieXRlKTB4ZWQsIChieXRlKTB4NmMsIChieXRlKTB4MDgsIChieXRlKTB4ZWQsIChieXRlKTB4ZmMsIChieXRlKTB4MzYsIChieXRlKTB4NWUsCisgICAgICAgICAgICAoYnl0ZSkweDY1LCAoYnl0ZSkweDkxLCAoYnl0ZSkweDc1LCAoYnl0ZSkweDQwLCAoYnl0ZSkweDcxLCAoYnl0ZSkweDNmLCAoYnl0ZSkweGU3LAorICAgICAgICAgICAgKGJ5dGUpMHg3NiwgKGJ5dGUpMHgwNywgKGJ5dGUpMHhiYywgKGJ5dGUpMHgwNCwgKGJ5dGUpMHhhMiwgKGJ5dGUpMHgyOCwgKGJ5dGUpMHg1MywKKyAgICAgICAgICAgIChieXRlKTB4ZGEsIChieXRlKTB4OGQsIChieXRlKTB4YjUsIChieXRlKTB4ZTEsIChieXRlKTB4NWEsIChieXRlKTB4MjcsIChieXRlKTB4NjUsCisgICAgICAgICAgICAoYnl0ZSkweDhkLCAoYnl0ZSkweGFmLCAoYnl0ZSkweDU2LCAoYnl0ZSkweGY0LCAoYnl0ZSkweDk0LCAoYnl0ZSkweDYxLCAoYnl0ZSkweDNmLAorICAgICAgICAgICAgKGJ5dGUpMHg2NywgKGJ5dGUpMHgxYywgKGJ5dGUpMHgxNywgKGJ5dGUpMHhmOCwgKGJ5dGUpMHgwNSwgKGJ5dGUpMHgxOSwgKGJ5dGUpMHhhMiwKKyAgICAgICAgICAgIChieXRlKTB4YTEsIChieXRlKTB4NzQsIChieXRlKTB4NjAsIChieXRlKTB4NDksIChieXRlKTB4OTcsIChieXRlKTB4YTksIChieXRlKTB4ZTUsCisgICAgICAgICAgICAoYnl0ZSkweDZhLCAoYnl0ZSkweDcxLCAoYnl0ZSkweDZiLCAoYnl0ZSkweDU1LCAoYnl0ZSkweDM4LCAoYnl0ZSkweDBjLCAoYnl0ZSkweGI5LAorICAgICAgICAgICAgKGJ5dGUpMHgyNSwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg0MSwgKGJ5dGUpMHgwMCwgKGJ5dGUpMHhhZSwgKGJ5dGUpMHhmMiwgKGJ5dGUpMHhhOCwKKyAgICAgICAgICAgIChieXRlKTB4NmQsIChieXRlKTB4MWQsIChieXRlKTB4MzUsIChieXRlKTB4MzgsIChieXRlKTB4NzMsIChieXRlKTB4OTgsIChieXRlKTB4MTUsCisgICAgICAgICAgICAoYnl0ZSkweGM3LCAoYnl0ZSkweDE1LCAoYnl0ZSkweDAyLCAoYnl0ZSkweDJmLCAoYnl0ZSkweDI5LCAoYnl0ZSkweDVkLCAoYnl0ZSkweDE4LAorICAgICAgICAgICAgKGJ5dGUpMHg0YiwgKGJ5dGUpMHg3ZCwgKGJ5dGUpMHhiMiwgKGJ5dGUpMHg1OSwgKGJ5dGUpMHhiZSwgKGJ5dGUpMHg1YSwgKGJ5dGUpMHhjNywKKyAgICAgICAgICAgIChieXRlKTB4NzIsIChieXRlKTB4ZDAsIChieXRlKTB4ODAsIChieXRlKTB4ZDgsIChieXRlKTB4NzcsIChieXRlKTB4YTEsIChieXRlKTB4N2YsCisgICAgICAgICAgICAoYnl0ZSkweGIyLCAoYnl0ZSkweDM1LCAoYnl0ZSkweDBkLCAoYnl0ZSkweDc4LCAoYnl0ZSkweDkyLCAoYnl0ZSkweDkxLCAoYnl0ZSkweDM1LAorICAgICAgICAgICAgKGJ5dGUpMHg0NywgKGJ5dGUpMHhlYiwgKGJ5dGUpMHg0YiwgKGJ5dGUpMHgwMCwgKGJ5dGUpMHg1OSwgKGJ5dGUpMHhiNCwgKGJ5dGUpMHhjNCwKKyAgICAgICAgICAgIChieXRlKTB4MmMsIChieXRlKTB4MjksIChieXRlKTB4ZTcsIChieXRlKTB4MzksIChieXRlKTB4OWQsIChieXRlKTB4NDgsIChieXRlKTB4OGIsCisgICAgICAgICAgICAoYnl0ZSkweDRmLCAoYnl0ZSkweDQ2LCAoYnl0ZSkweGU2LCAoYnl0ZSkweGNlLCAoYnl0ZSkweGQzLCAoYnl0ZSkweDZjLCAoYnl0ZSkweDg0LAorICAgICAgICAgICAgKGJ5dGUpMHg5YiwgKGJ5dGUpMHhkMiwgKGJ5dGUpMHgxMCwgKGJ5dGUpMHhiMCwgKGJ5dGUpMHhlMQorICAgIH07CisKKyAgICAvKgorICAgICAqIFRoZSBzYW1lIGtleSBpbiBQRU0gZm9ybWF0LgorICAgICAqIFRoZSBERVIgdmVyc2lvbiBvZiB0aGlzIGtleSB3YXMgY3JlYXRlZCB1c2luZworICAgICAqCisgICAgICogb3BlbnNzbCBwa2NzOCAtdG9wazggLW5vY3J5cHQgLWluIGtleTEucGVtCisgICAgICogICAgICAgICAtaW5mb3JtIFBFTSAtb3V0IGtleTEuZGVyIC1vdXRmb3JtIERFUgorICAgICAqCisgICAgICogLS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQorICAgICAqIFByb2MtVHlwZTogNCxFTkNSWVBURUQKKyAgICAgKiBERUstSW5mbzogREVTLUVERTMtQ0JDLDY5RTI2RkNDM0E3RjEzNkUKKyAgICAgKgorICAgICAqIFlLaUxYT3dmMnRlb2c0SW9PdmJiUk95OXZxcDBFTXQxS0Y5ZU5LZUtGQ1dHQ1M0UkZBVGFBR2pLcmRBMjZiT1YKKyAgICAgKiBNQmR5QjRWN3FheExDOC9Vd0xsekZMcHByb3VJZkdxckVvUi9OVDBlS1ErNFBsMjVHbE12bFBhUjBwQVRCTFoyCisgICAgICogT0VhQjN6Y055Z09RMDJKZHJtdzIrQ1M5cVZ0R0dYam42UXA2VFZGbTZlZE5Db09WWk9ETFA5a2t6UExuOE1rbQorICAgICAqIC9pc2dzcHJ3TUVMdXRoOFk1QkMwYnJJNVhZZE1xWkZJNWRMejR3elZIODF3QlliUm1KcVI3eU9FMXB6QUpTOUkKKyAgICAgKiBnSjVZdmNQN3BTbW9BMlNIVk40djRxb2xNK0dBTTlZSXAyYndFeVdGUmpicmlObEYxeU0rSGZsR01FWjFITnBaCisgICAgICogRlNGRkEzRzhFSUg5b2diWjNqKzdFdWpybmRKQzdHSWlid2l1NXJkM2VJSHRjd3JXcHJwK3dFb1BjL3ZNOE9wUgorICAgICAqIHNvOW1zN2lRWVY2ZmFZQ1dLNHllQ2ZFcll3N3QrQWhHcWZMaXFITzZiTzJYQVlKY0QyOFJZVjlnWG11Z1pPaFQKKyAgICAgKiA5NDcxTU93OTRIV0Y1dEJWamdJa3lOQmNiUnlNRjlpeVFLYWZia0hZcG14YUI0czJFcVFyMVNOWmwzU0xFd2hYCisgICAgICogTUVHeTMvdHl2ZXVNTEF2ZFRsU0RaYnQ2bWVtV29YWEVYNEVwL3E2cjBFckNUWTMxYXdkUC9YYUpjSkJHYjluaQorICAgICAqIElhaThESUNhRzF2NGJVdUJWZ2FpYWNabGd3MU80SGhqOEQyRFdmVlpzZ3B4NXk4dEJSTTJsR1d2eXpFaTVuMkYKKyAgICAgKiBQaVIyVWxUMERqQ0QxT2JqQ3BXSjVpbnNYL3c4ZFhTSEdaTExiOWNjR1JVcncvKzVCcHRuK0FvRWZkUCs4UzNqCisgICAgICogVWRNZHhsNnF0MmduZUNZdTFMcjNjUStxS1BxaWtRdHkyVVE2WXA4ZEpraGVMSjJUcitybmF5dE9DcDJkQVQ5SworICAgICAqIEtYVGltSWNYVitmdHZVTWJEUFhZdTRMSkJsZHIyVm9rRCtrM1FiSERnRm5mSElpTmt3aVB6QT09CisgICAgICogLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0KKyAgICAgKi8KKworICAgIC8qCisgICAgICAgQ2VydGlmaWNhdGU6CisgICAgICAgICAgIERhdGE6CisgICAgICAgICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICAgICAgICAgICBTZXJpYWwgTnVtYmVyOiAxICgweDEpCisgICAgICAgICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgICAgICAgICAgIElzc3VlcjogQz1BTiwgU1Q9QW5kcm9pZCwgTz1BbmRyb2lkLCBPVT1BbmRyb2lkLCBDTj1BbmRyb2lkL2VtYWlsQWRkcmVzcz1hbmRyb2lkQGFuZHJvaWQuY29tCisgICAgICAgICAgICAgICBWYWxpZGl0eQorICAgICAgICAgICAgICAgICAgIE5vdCBCZWZvcmU6IE1hciAyMCAxNzowMDo0MCAyMDA5IEdNVAorICAgICAgICAgICAgICAgICAgIE5vdCBBZnRlciA6IE1hciAyMCAxNzowMDo0MCAyMDEwIEdNVAorICAgICAgICAgICAgICAgU3ViamVjdDogQz1BTiwgU1Q9QW5kcm9pZCwgTD1BbmRyb2lkLCBPPUFuZHJvaWQsIE9VPUFuZHJvaWQsIENOPUFuZHJvaWQvZW1haWxBZGRyZXNzPWFuZHJvaWRAYW5kcm9pZC5jb20KKyAgICAgICAgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAgICAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICAgICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgxMDI0IGJpdCkKKyAgICAgICAgICAgICAgICAgICAgICAgTW9kdWx1cyAoMTAyNCBiaXQpOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgMDA6ZDA6NDQ6NWE6YzQ6NzY6ZWY6YWU6ZmY6OTk6NWI6YzM6Mzc6YzE6MDk6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAzMzpjMTo5NzplNTo2NDo3YTphOTo3ZTo5ODo0YjozYTphMzozMzpkMDo1YzoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGM3OjU2OmFjOmQ4OjQyOmU4OjRhOmFjOjljOmQ5OjhmOjg5Ojg0OmM4OjQ2OgorICAgICAgICAgICAgICAgICAgICAgICAgICAgOTU6Y2U6MjI6Zjc6NmE6MDk6ZGU6OTE6NDc6OWM6Mzg6MjM6YTU6NGE6ZmM6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAwODphZjo1YTpiNDo2ZTozOTo4ZTplOTpmNTowZTo0NjowMDo2OTplMTplNToKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNjOjRjOjgxOmI2OjgyOjdiOjU2OmZiOmY0OmRjOjA0OmZmOjYxOmUyOjdlOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgNWY6ZTI6Zjk6OTc6NTM6OTM6ZDQ6Njk6OWI6YmE6Nzk6MjA6Y2Q6MWU6M2U6CisgICAgICAgICAgICAgICAgICAgICAgICAgICBkNTo5YTo0NDo5NTo3YzpjZjpjMTo1MTpmMjoyMjpmYzplYzpjYzo2NjoxODoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIDc0OjYwOjJhOmEyOmJlOjA2OmMyOjllOjhkCisgICAgICAgICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgICAgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAgICAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czoKKyAgICAgICAgICAgICAgICAgICAgICAgQ0E6RkFMU0UKKyAgICAgICAgICAgICAgICAgICBOZXRzY2FwZSBDb21tZW50OgorICAgICAgICAgICAgICAgICAgICAgICBPcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZQorICAgICAgICAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOgorICAgICAgICAgICAgICAgICAgICAgICA5NTozRTpDMzo0Njo2OTo1Mjo3ODowODowNTo0NjpCOTowMDo2OTpFNTpFNzpBNzo5OTpFMzpDNDo2NworICAgICAgICAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6CisgICAgICAgICAgICAgICAgICAgICAgIGtleWlkOkU3OjlCOjdEOjkwOjI5OkVBOjkwOjBCOjdGOjA4OjQxOjc2OjRFOjQxOjIzOkU4OjQzOjJDOkE5OjAzCisKKyAgICAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgICAgICAgICBhMzo1YjozMDpmNToyODozZjo4NzpmNjoxYjozNjo2YToyMjo2ZDo2Njo0ODpmYTpjYjplZToKKyAgICAgICAgICAgICAgIDRjOjA0OmNmOjExOjE0OmUyOjFmOmI1OjY4OjBjOmU3OjYxOjBlOmJjOmQzOjY5OjE5OjAyOgorICAgICAgICAgICAgICAgOGI6ZDU6ZDM6MDU6NGE6Yzg6Mjk6ZTg6ZTM6ZDA6ZTk6MzI6YWQ6NmM6N2Q6OWM6YzQ6NDY6CisgICAgICAgICAgICAgICA2YzpmOTo2NjplNjo2NDo2MDo0Nzo2YjplZjo4ZTpjODoxYzo2Nzo1YTo1YTpjZjo3MzphMzoKKyAgICAgICAgICAgICAgIDdlOjlkOjZlOjg5OjBjOjY3Ojk5OjE3OjNkOmIyOmI4OjhlOjQxOjk1OjljOjg0Ojk1OmJmOgorICAgICAgICAgICAgICAgNTc6OTU6MjQ6MjI6OGY6MTk6MTI6YzE6ZmQ6MjM6NDU6NzU6N2Y6NGY6NjE6MDY6ZTM6OWY6CisgICAgICAgICAgICAgICAwNTpkYzplNzoyOTo5YTo2YjoxNzplMTplMTozNzpkNTo4YjpiYTpiNDpkMDo4YTozYzpkZDoKKyAgICAgICAgICAgICAgIDNmOjZhCisgICAgICovCisgICAgU3RyaW5nIGNlcnRpZmljYXRlMiA9ICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICsgIk1JSUM5akNDQWwrZ0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRVUZBREI1TVFzd0NRWURWUVFHRXdKQlRqRVFcbiIKKyAgICAgICAgICAgICsgIk1BNEdBMVVFQ0JNSFFXNWtjbTlwWkRFUU1BNEdBMVVFQ2hNSFFXNWtjbTlwWkRFUU1BNEdBMVVFQ3hNSFFXNWtcbiIKKyAgICAgICAgICAgICsgImNtOXBaREVRTUE0R0ExVUVBeE1IUVc1a2NtOXBaREVpTUNBR0NTcUdTSWIzRFFFSkFSWVRZVzVrY205cFpFQmhcbiIKKyAgICAgICAgICAgICsgImJtUnliMmxrTG1OdmJUQWVGdzB3T1RBek1qQXhOekF3TkRCYUZ3MHhNREF6TWpBeE56QXdOREJhTUlHTE1Rc3dcbiIKKyAgICAgICAgICAgICsgIkNRWURWUVFHRXdKQlRqRVFNQTRHQTFVRUNCTUhRVzVrY205cFpERVFNQTRHQTFVRUJ4TUhRVzVrY205cFpERVFcbiIKKyAgICAgICAgICAgICsgIk1BNEdBMVVFQ2hNSFFXNWtjbTlwWkRFUU1BNEdBMVVFQ3hNSFFXNWtjbTlwWkRFUU1BNEdBMVVFQXhNSFFXNWtcbiIKKyAgICAgICAgICAgICsgImNtOXBaREVpTUNBR0NTcUdTSWIzRFFFSkFSWVRZVzVrY205cFpFQmhibVJ5YjJsa0xtTnZiVENCbnpBTkJna3FcbiIKKyAgICAgICAgICAgICsgImhraUc5dzBCQVFFRkFBT0JqUUF3Z1lrQ2dZRUEwRVJheEhidnJ2K1pXOE0zd1FrendaZmxaSHFwZnBoTE9xTXpcbiIKKyAgICAgICAgICAgICsgIjBGekhWcXpZUXVoS3JKelpqNG1FeUVhVnppTDNhZ25la1VlY09DT2xTdndJcjFxMGJqbU82ZlVPUmdCcDRlWE1cbiIKKyAgICAgICAgICAgICsgIlRJRzJnbnRXKy9UY0JQOWg0bjVmNHZtWFU1UFVhWnU2ZVNETkhqN1Zta1NWZk0vQlVmSWkvT3pNWmhoMFlDcWlcbiIKKyAgICAgICAgICAgICsgInZnYkNubzBDQXdFQUFhTjdNSGt3Q1FZRFZSMFRCQUl3QURBc0JnbGdoa2dCaHZoQ0FRMEVIeFlkVDNCbGJsTlRcbiIKKyAgICAgICAgICAgICsgIlRDQkhaVzVsY21GMFpXUWdRMlZ5ZEdsbWFXTmhkR1V3SFFZRFZSME9CQllFRkpVK3cwWnBVbmdJQlVhNUFHbmxcbiIKKyAgICAgICAgICAgICsgIjU2ZVo0OFJuTUI4R0ExVWRJd1FZTUJhQUZPZWJmWkFwNnBBTGZ3aEJkazVCSStoRExLa0RNQTBHQ1NxR1NJYjNcbiIKKyAgICAgICAgICAgICsgIkRRRUJCUVVBQTRHQkFLTmJNUFVvUDRmMkd6WnFJbTFtU1ByTDdrd0V6eEVVNGgrMWFBem5ZUTY4MDJrWkFvdlZcbiIKKyAgICAgICAgICAgICsgIjB3Vkt5Q25vNDlEcE1xMXNmWnpFUm16NVp1WmtZRWRyNzQ3SUhHZGFXczl6bzM2ZGJva01aNWtYUGJLNGprR1ZcbiIKKyAgICAgICAgICAgICsgIm5JU1Z2MWVWSkNLUEdSTEIvU05GZFg5UFlRYmpud1hjNXltYWF4Zmg0VGZWaTdxMDBJbzgzVDlxXG5cbiIKKyAgICAgICAgICAgICsgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0iOworCisgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gY2VydEFycmF5MiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShjZXJ0aWZpY2F0ZTIKKyAgICAgICAgICAgIC5nZXRCeXRlcygpKTsKKworICAgICAgIC8qCisgICAgICAgICogVGhlIGtleSBpbiBERVIgZm9ybWF0LgorICAgICAgICAqIEJlbG93IGlzIHRoZSBzYW1lIGtleSBpbiBQRU0gZm9ybWF0IGFzIHJlZmVyZW5jZQorICAgICAgICAqLworICAgICAgIGJ5dGVbXSBrZXkyQnl0ZXMgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgIChieXRlKTB4MzAsIChieXRlKTB4ODIsIChieXRlKTB4MDIsIChieXRlKTB4NzUsIChieXRlKTB4MDIsIChieXRlKTB4MDEsIChieXRlKTB4MDAsCisgICAgICAgICAgICAoYnl0ZSkweDMwLCAoYnl0ZSkweDBkLCAoYnl0ZSkweDA2LCAoYnl0ZSkweDA5LCAoYnl0ZSkweDJhLCAoYnl0ZSkweDg2LCAoYnl0ZSkweDQ4LAorICAgICAgICAgICAgKGJ5dGUpMHg4NiwgKGJ5dGUpMHhmNywgKGJ5dGUpMHgwZCwgKGJ5dGUpMHgwMSwgKGJ5dGUpMHgwMSwgKGJ5dGUpMHgwMSwgKGJ5dGUpMHgwNSwKKyAgICAgICAgICAgIChieXRlKTB4MDAsIChieXRlKTB4MDQsIChieXRlKTB4ODIsIChieXRlKTB4MDIsIChieXRlKTB4NWYsIChieXRlKTB4MzAsIChieXRlKTB4ODIsCisgICAgICAgICAgICAoYnl0ZSkweDAyLCAoYnl0ZSkweDViLCAoYnl0ZSkweDAyLCAoYnl0ZSkweDAxLCAoYnl0ZSkweDAwLCAoYnl0ZSkweDAyLCAoYnl0ZSkweDgxLAorICAgICAgICAgICAgKGJ5dGUpMHg4MSwgKGJ5dGUpMHgwMCwgKGJ5dGUpMHhkMCwgKGJ5dGUpMHg0NCwgKGJ5dGUpMHg1YSwgKGJ5dGUpMHhjNCwgKGJ5dGUpMHg3NiwKKyAgICAgICAgICAgIChieXRlKTB4ZWYsIChieXRlKTB4YWUsIChieXRlKTB4ZmYsIChieXRlKTB4OTksIChieXRlKTB4NWIsIChieXRlKTB4YzMsIChieXRlKTB4MzcsCisgICAgICAgICAgICAoYnl0ZSkweGMxLCAoYnl0ZSkweDA5LCAoYnl0ZSkweDMzLCAoYnl0ZSkweGMxLCAoYnl0ZSkweDk3LCAoYnl0ZSkweGU1LCAoYnl0ZSkweDY0LAorICAgICAgICAgICAgKGJ5dGUpMHg3YSwgKGJ5dGUpMHhhOSwgKGJ5dGUpMHg3ZSwgKGJ5dGUpMHg5OCwgKGJ5dGUpMHg0YiwgKGJ5dGUpMHgzYSwgKGJ5dGUpMHhhMywKKyAgICAgICAgICAgIChieXRlKTB4MzMsIChieXRlKTB4ZDAsIChieXRlKTB4NWMsIChieXRlKTB4YzcsIChieXRlKTB4NTYsIChieXRlKTB4YWMsIChieXRlKTB4ZDgsCisgICAgICAgICAgICAoYnl0ZSkweDQyLCAoYnl0ZSkweGU4LCAoYnl0ZSkweDRhLCAoYnl0ZSkweGFjLCAoYnl0ZSkweDljLCAoYnl0ZSkweGQ5LCAoYnl0ZSkweDhmLAorICAgICAgICAgICAgKGJ5dGUpMHg4OSwgKGJ5dGUpMHg4NCwgKGJ5dGUpMHhjOCwgKGJ5dGUpMHg0NiwgKGJ5dGUpMHg5NSwgKGJ5dGUpMHhjZSwgKGJ5dGUpMHgyMiwKKyAgICAgICAgICAgIChieXRlKTB4ZjcsIChieXRlKTB4NmEsIChieXRlKTB4MDksIChieXRlKTB4ZGUsIChieXRlKTB4OTEsIChieXRlKTB4NDcsIChieXRlKTB4OWMsCisgICAgICAgICAgICAoYnl0ZSkweDM4LCAoYnl0ZSkweDIzLCAoYnl0ZSkweGE1LCAoYnl0ZSkweDRhLCAoYnl0ZSkweGZjLCAoYnl0ZSkweDA4LCAoYnl0ZSkweGFmLAorICAgICAgICAgICAgKGJ5dGUpMHg1YSwgKGJ5dGUpMHhiNCwgKGJ5dGUpMHg2ZSwgKGJ5dGUpMHgzOSwgKGJ5dGUpMHg4ZSwgKGJ5dGUpMHhlOSwgKGJ5dGUpMHhmNSwKKyAgICAgICAgICAgIChieXRlKTB4MGUsIChieXRlKTB4NDYsIChieXRlKTB4MDAsIChieXRlKTB4NjksIChieXRlKTB4ZTEsIChieXRlKTB4ZTUsIChieXRlKTB4Y2MsCisgICAgICAgICAgICAoYnl0ZSkweDRjLCAoYnl0ZSkweDgxLCAoYnl0ZSkweGI2LCAoYnl0ZSkweDgyLCAoYnl0ZSkweDdiLCAoYnl0ZSkweDU2LCAoYnl0ZSkweGZiLAorICAgICAgICAgICAgKGJ5dGUpMHhmNCwgKGJ5dGUpMHhkYywgKGJ5dGUpMHgwNCwgKGJ5dGUpMHhmZiwgKGJ5dGUpMHg2MSwgKGJ5dGUpMHhlMiwgKGJ5dGUpMHg3ZSwKKyAgICAgICAgICAgIChieXRlKTB4NWYsIChieXRlKTB4ZTIsIChieXRlKTB4ZjksIChieXRlKTB4OTcsIChieXRlKTB4NTMsIChieXRlKTB4OTMsIChieXRlKTB4ZDQsCisgICAgICAgICAgICAoYnl0ZSkweDY5LCAoYnl0ZSkweDliLCAoYnl0ZSkweGJhLCAoYnl0ZSkweDc5LCAoYnl0ZSkweDIwLCAoYnl0ZSkweGNkLCAoYnl0ZSkweDFlLAorICAgICAgICAgICAgKGJ5dGUpMHgzZSwgKGJ5dGUpMHhkNSwgKGJ5dGUpMHg5YSwgKGJ5dGUpMHg0NCwgKGJ5dGUpMHg5NSwgKGJ5dGUpMHg3YywgKGJ5dGUpMHhjZiwKKyAgICAgICAgICAgIChieXRlKTB4YzEsIChieXRlKTB4NTEsIChieXRlKTB4ZjIsIChieXRlKTB4MjIsIChieXRlKTB4ZmMsIChieXRlKTB4ZWMsIChieXRlKTB4Y2MsCisgICAgICAgICAgICAoYnl0ZSkweDY2LCAoYnl0ZSkweDE4LCAoYnl0ZSkweDc0LCAoYnl0ZSkweDYwLCAoYnl0ZSkweDJhLCAoYnl0ZSkweGEyLCAoYnl0ZSkweGJlLAorICAgICAgICAgICAgKGJ5dGUpMHgwNiwgKGJ5dGUpMHhjMiwgKGJ5dGUpMHg5ZSwgKGJ5dGUpMHg4ZCwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHgwMywgKGJ5dGUpMHgwMSwKKyAgICAgICAgICAgIChieXRlKTB4MDAsIChieXRlKTB4MDEsIChieXRlKTB4MDIsIChieXRlKTB4ODEsIChieXRlKTB4ODAsIChieXRlKTB4MDYsIChieXRlKTB4NDEsCisgICAgICAgICAgICAoYnl0ZSkweGQ3LCAoYnl0ZSkweDdjLCAoYnl0ZSkweDQ5LCAoYnl0ZSkweDlhLCAoYnl0ZSkweDdmLCAoYnl0ZSkweGU2LCAoYnl0ZSkweDdjLAorICAgICAgICAgICAgKGJ5dGUpMHgwNCwgKGJ5dGUpMHgwZSwgKGJ5dGUpMHhjNCwgKGJ5dGUpMHg3MSwgKGJ5dGUpMHgwZiwgKGJ5dGUpMHg0NiwgKGJ5dGUpMHhiNywKKyAgICAgICAgICAgIChieXRlKTB4Y2QsIChieXRlKTB4NDksIChieXRlKTB4N2UsIChieXRlKTB4MTAsIChieXRlKTB4NTUsIChieXRlKTB4NjEsIChieXRlKTB4NTEsCisgICAgICAgICAgICAoYnl0ZSkweDUwLCAoYnl0ZSkweDA5LCAoYnl0ZSkweDRkLCAoYnl0ZSkweGY3LCAoYnl0ZSkweGYzLCAoYnl0ZSkweDhkLCAoYnl0ZSkweGE2LAorICAgICAgICAgICAgKGJ5dGUpMHgwYiwgKGJ5dGUpMHg4YiwgKGJ5dGUpMHg5YiwgKGJ5dGUpMHhkZiwgKGJ5dGUpMHhiZSwgKGJ5dGUpMHhiYywgKGJ5dGUpMHhlNywKKyAgICAgICAgICAgIChieXRlKTB4OWMsIChieXRlKTB4YmEsIChieXRlKTB4YzgsIChieXRlKTB4OWUsIChieXRlKTB4MzgsIChieXRlKTB4MTgsIChieXRlKTB4MTAsCisgICAgICAgICAgICAoYnl0ZSkweDRlLCAoYnl0ZSkweGQ1LCAoYnl0ZSkweGU3LCAoYnl0ZSkweGE1LCAoYnl0ZSkweDA5LCAoYnl0ZSkweDUxLCAoYnl0ZSkweDhjLAorICAgICAgICAgICAgKGJ5dGUpMHg5NywgKGJ5dGUpMHg0ZSwgKGJ5dGUpMHhkMCwgKGJ5dGUpMHg3OSwgKGJ5dGUpMHhiYiwgKGJ5dGUpMHg1MCwgKGJ5dGUpMHg2ZiwKKyAgICAgICAgICAgIChieXRlKTB4MDUsIChieXRlKTB4NGQsIChieXRlKTB4NzksIChieXRlKTB4N2YsIChieXRlKTB4M2YsIChieXRlKTB4MjYsIChieXRlKTB4NzYsCisgICAgICAgICAgICAoYnl0ZSkweGMxLCAoYnl0ZSkweGNjLCAoYnl0ZSkweDQwLCAoYnl0ZSkweDBmLCAoYnl0ZSkweGRlLCAoYnl0ZSkweDQyLCAoYnl0ZSkweDVkLAorICAgICAgICAgICAgKGJ5dGUpMHhjMSwgKGJ5dGUpMHg1ZiwgKGJ5dGUpMHg3MCwgKGJ5dGUpMHg0NiwgKGJ5dGUpMHg3MCwgKGJ5dGUpMHg4ZCwgKGJ5dGUpMHhmZiwKKyAgICAgICAgICAgIChieXRlKTB4MjYsIChieXRlKTB4MzUsIChieXRlKTB4NzUsIChieXRlKTB4OWEsIChieXRlKTB4OTcsIChieXRlKTB4ZDIsIChieXRlKTB4NzQsCisgICAgICAgICAgICAoYnl0ZSkweDUzLCAoYnl0ZSkweDExLCAoYnl0ZSkweDJiLCAoYnl0ZSkweGMxLCAoYnl0ZSkweDc2LCAoYnl0ZSkweDljLCAoYnl0ZSkweDlmLAorICAgICAgICAgICAgKGJ5dGUpMHg5MywgKGJ5dGUpMHhhYSwgKGJ5dGUpMHhhOCwgKGJ5dGUpMHg0MSwgKGJ5dGUpMHgyMywgKGJ5dGUpMHg5YSwgKGJ5dGUpMHgwNCwKKyAgICAgICAgICAgIChieXRlKTB4MTEsIChieXRlKTB4NmUsIChieXRlKTB4NTYsIChieXRlKTB4ZWEsIChieXRlKTB4ZjUsIChieXRlKTB4ZDYsIChieXRlKTB4MWQsCisgICAgICAgICAgICAoYnl0ZSkweDQ5LCAoYnl0ZSkweDJhLCAoYnl0ZSkweDgzLCAoYnl0ZSkweDQ5LCAoYnl0ZSkweDdkLCAoYnl0ZSkweGI3LCAoYnl0ZSkweGQxLAorICAgICAgICAgICAgKGJ5dGUpMHhlNiwgKGJ5dGUpMHg4ZCwgKGJ5dGUpMHg5MywgKGJ5dGUpMHgxYSwgKGJ5dGUpMHg4MSwgKGJ5dGUpMHg4ZSwgKGJ5dGUpMHhjMiwKKyAgICAgICAgICAgIChieXRlKTB4YjksIChieXRlKTB4YmYsIChieXRlKTB4ZmQsIChieXRlKTB4MDAsIChieXRlKTB4ZTIsIChieXRlKTB4YjUsIChieXRlKTB4MDEsCisgICAgICAgICAgICAoYnl0ZSkweDAyLCAoYnl0ZSkweDQxLCAoYnl0ZSkweDAwLCAoYnl0ZSkweGVhLCAoYnl0ZSkweGNlLCAoYnl0ZSkweGM2LCAoYnl0ZSkweDExLAorICAgICAgICAgICAgKGJ5dGUpMHgxZSwgKGJ5dGUpMHhmNiwgKGJ5dGUpMHhjZiwgKGJ5dGUpMHgzYSwgKGJ5dGUpMHg4YywgKGJ5dGUpMHhlNywgKGJ5dGUpMHg4MCwKKyAgICAgICAgICAgIChieXRlKTB4MTYsIChieXRlKTB4OGYsIChieXRlKTB4MWQsIChieXRlKTB4ZWIsIChieXRlKTB4YTIsIChieXRlKTB4ZDIsIChieXRlKTB4MjMsCisgICAgICAgICAgICAoYnl0ZSkweDllLCAoYnl0ZSkweGY5LCAoYnl0ZSkweGYxLCAoYnl0ZSkweDE0LCAoYnl0ZSkweDE2LCAoYnl0ZSkweGM4LCAoYnl0ZSkweDg3LAorICAgICAgICAgICAgKGJ5dGUpMHhmMiwgKGJ5dGUpMHgxNywgKGJ5dGUpMHhkZiwgKGJ5dGUpMHhjNiwgKGJ5dGUpMHhlNCwgKGJ5dGUpMHgxYywgKGJ5dGUpMHg3NCwKKyAgICAgICAgICAgIChieXRlKTB4NzQsIChieXRlKTB4YjAsIChieXRlKTB4YmIsIChieXRlKTB4NDAsIChieXRlKTB4ZWIsIChieXRlKTB4YTYsIChieXRlKTB4YjIsCisgICAgICAgICAgICAoYnl0ZSkweDViLCAoYnl0ZSkweDZkLCAoYnl0ZSkweGY1LCAoYnl0ZSkweDlhLCAoYnl0ZSkweDg1LCAoYnl0ZSkweGYxLCAoYnl0ZSkweDczLAorICAgICAgICAgICAgKGJ5dGUpMHg4NCwgKGJ5dGUpMHhlYywgKGJ5dGUpMHhkYiwgKGJ5dGUpMHg5YiwgKGJ5dGUpMHhmOSwgKGJ5dGUpMHhmOCwgKGJ5dGUpMHgzZCwKKyAgICAgICAgICAgIChieXRlKTB4YmEsIChieXRlKTB4ZWIsIChieXRlKTB4ZDcsIChieXRlKTB4NmMsIChieXRlKTB4NDUsIChieXRlKTB4N2IsIChieXRlKTB4Y2EsCisgICAgICAgICAgICAoYnl0ZSkweDEyLCAoYnl0ZSkweDY3LCAoYnl0ZSkweDVmLCAoYnl0ZSkweGNkLCAoYnl0ZSkweDAyLCAoYnl0ZSkweDQxLCAoYnl0ZSkweDAwLAorICAgICAgICAgICAgKGJ5dGUpMHhlMywgKGJ5dGUpMHgxMCwgKGJ5dGUpMHg1YiwgKGJ5dGUpMHhkMCwgKGJ5dGUpMHhhZCwgKGJ5dGUpMHg1OSwgKGJ5dGUpMHg5MCwKKyAgICAgICAgICAgIChieXRlKTB4MTgsIChieXRlKTB4MTcsIChieXRlKTB4ZGMsIChieXRlKTB4NjgsIChieXRlKTB4ZDQsIChieXRlKTB4NzUsIChieXRlKTB4NTUsCisgICAgICAgICAgICAoYnl0ZSkweGFiLCAoYnl0ZSkweDdkLCAoYnl0ZSkweGQxLCAoYnl0ZSkweGI1LCAoYnl0ZSkweDVhLCAoYnl0ZSkweGM0LCAoYnl0ZSkweGIwLAorICAgICAgICAgICAgKGJ5dGUpMHgyZCwgKGJ5dGUpMHhhOSwgKGJ5dGUpMHhkMSwgKGJ5dGUpMHg2ZiwgKGJ5dGUpMHhlOSwgKGJ5dGUpMHgyMSwgKGJ5dGUpMHg0YSwKKyAgICAgICAgICAgIChieXRlKTB4MjcsIChieXRlKTB4YzQsIChieXRlKTB4OTgsIChieXRlKTB4ODksIChieXRlKTB4ZmEsIChieXRlKTB4NjUsIChieXRlKTB4YjYsCisgICAgICAgICAgICAoYnl0ZSkweDEwLCAoYnl0ZSkweDVkLCAoYnl0ZSkweDY2LCAoYnl0ZSkweGRkLCAoYnl0ZSkweDE3LCAoYnl0ZSkweGIzLCAoYnl0ZSkweGYzLAorICAgICAgICAgICAgKGJ5dGUpMHhkMywgKGJ5dGUpMHhlMywgKGJ5dGUpMHhhMCwgKGJ5dGUpMHgxYSwgKGJ5dGUpMHg5MywgKGJ5dGUpMHhlNCwgKGJ5dGUpMHhmYiwKKyAgICAgICAgICAgIChieXRlKTB4ODgsIChieXRlKTB4YTcsIChieXRlKTB4M2IsIChieXRlKTB4OTcsIChieXRlKTB4MWIsIChieXRlKTB4ZjEsIChieXRlKTB4MDgsCisgICAgICAgICAgICAoYnl0ZSkweDBjLCAoYnl0ZSkweDY2LCAoYnl0ZSkweGQwLCAoYnl0ZSkweDg2LCAoYnl0ZSkweDVlLCAoYnl0ZSkweDM5LCAoYnl0ZSkweGY5LAorICAgICAgICAgICAgKGJ5dGUpMHhjMSwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg0MCwgKGJ5dGUpMHgyNCwgKGJ5dGUpMHg3YywgKGJ5dGUpMHhjZCwgKGJ5dGUpMHgzYSwKKyAgICAgICAgICAgIChieXRlKTB4OGIsIChieXRlKTB4ZGQsIChieXRlKTB4M2UsIChieXRlKTB4ODYsIChieXRlKTB4OTIsIChieXRlKTB4YWUsIChieXRlKTB4YzYsCisgICAgICAgICAgICAoYnl0ZSkweGIwLCAoYnl0ZSkweGJhLCAoYnl0ZSkweGJjLCAoYnl0ZSkweGEzLCAoYnl0ZSkweDg5LCAoYnl0ZSkweDQxLCAoYnl0ZSkweGFlLAorICAgICAgICAgICAgKGJ5dGUpMHg1NywgKGJ5dGUpMHg1ZCwgKGJ5dGUpMHhlZiwgKGJ5dGUpMHhhMCwgKGJ5dGUpMHg3NywgKGJ5dGUpMHg4OSwgKGJ5dGUpMHhlMSwKKyAgICAgICAgICAgIChieXRlKTB4ZDYsIChieXRlKTB4MzQsIChieXRlKTB4ZWYsIChieXRlKTB4ODksIChieXRlKTB4MzAsIChieXRlKTB4OTksIChieXRlKTB4NWIsCisgICAgICAgICAgICAoYnl0ZSkweDVmLCAoYnl0ZSkweDY2LCAoYnl0ZSkweGI3LCAoYnl0ZSkweDMyLCAoYnl0ZSkweDc3LCAoYnl0ZSkweDZjLCAoYnl0ZSkweDA3LAorICAgICAgICAgICAgKGJ5dGUpMHhmYiwgKGJ5dGUpMHgzZCwgKGJ5dGUpMHgzMywgKGJ5dGUpMHgxNSwgKGJ5dGUpMHgzOCwgKGJ5dGUpMHgwYiwgKGJ5dGUpMHgzNSwKKyAgICAgICAgICAgIChieXRlKTB4MzAsIChieXRlKTB4NGEsIChieXRlKTB4YmUsIChieXRlKTB4MzUsIChieXRlKTB4OTYsIChieXRlKTB4YmEsIChieXRlKTB4ODQsCisgICAgICAgICAgICAoYnl0ZSkweDlkLCAoYnl0ZSkweDJmLCAoYnl0ZSkweDU4LCAoYnl0ZSkweGUyLCAoYnl0ZSkweDcyLCAoYnl0ZSkweDQ5LCAoYnl0ZSkweGIyLAorICAgICAgICAgICAgKGJ5dGUpMHgzNCwgKGJ5dGUpMHhmOSwgKGJ5dGUpMHhlYiwgKGJ5dGUpMHg2MSwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg0MCwgKGJ5dGUpMHgyYSwKKyAgICAgICAgICAgIChieXRlKTB4ZDQsIChieXRlKTB4ODksIChieXRlKTB4MWQsIChieXRlKTB4MjEsIChieXRlKTB4YjUsIChieXRlKTB4YzUsIChieXRlKTB4MzIsCisgICAgICAgICAgICAoYnl0ZSkweDY2LCAoYnl0ZSkweDNkLCAoYnl0ZSkweGQzLCAoYnl0ZSkweDIwLCAoYnl0ZSkweDUwLCAoYnl0ZSkweDQ5LCAoYnl0ZSkweGFhLAorICAgICAgICAgICAgKGJ5dGUpMHhhMSwgKGJ5dGUpMHg3ZiwgKGJ5dGUpMHgwZiwgKGJ5dGUpMHgyMCwgKGJ5dGUpMHg2MSwgKGJ5dGUpMHhmZCwgKGJ5dGUpMHg4MSwKKyAgICAgICAgICAgIChieXRlKTB4N2YsIChieXRlKTB4ODgsIChieXRlKTB4ZGIsIChieXRlKTB4ZmQsIChieXRlKTB4MzMsIChieXRlKTB4YTQsIChieXRlKTB4NTMsCisgICAgICAgICAgICAoYnl0ZSkweDQwLCAoYnl0ZSkweDA4LCAoYnl0ZSkweDJkLCAoYnl0ZSkweGVlLCAoYnl0ZSkweGE3LCAoYnl0ZSkweDg0LCAoYnl0ZSkweGUyLAorICAgICAgICAgICAgKGJ5dGUpMHgyZCwgKGJ5dGUpMHg1YywgKGJ5dGUpMHgxYiwgKGJ5dGUpMHhkNCwgKGJ5dGUpMHgzZSwgKGJ5dGUpMHhjMywgKGJ5dGUpMHg3ZCwKKyAgICAgICAgICAgIChieXRlKTB4NzIsIChieXRlKTB4NzAsIChieXRlKTB4NWUsIChieXRlKTB4ZDMsIChieXRlKTB4MGEsIChieXRlKTB4ZGMsIChieXRlKTB4NGYsCisgICAgICAgICAgICAoYnl0ZSkweDc4LCAoYnl0ZSkweDhjLCAoYnl0ZSkweDBiLCAoYnl0ZSkweDAyLCAoYnl0ZSkweGUwLCAoYnl0ZSkweDQyLCAoYnl0ZSkweDRlLAorICAgICAgICAgICAgKGJ5dGUpMHg2NCwgKGJ5dGUpMHg4ZSwgKGJ5dGUpMHg2YywgKGJ5dGUpMHhlYSwgKGJ5dGUpMHgxNSwgKGJ5dGUpMHgzMSwgKGJ5dGUpMHg4MSwKKyAgICAgICAgICAgIChieXRlKTB4MDIsIChieXRlKTB4NDAsIChieXRlKTB4NTcsIChieXRlKTB4NzIsIChieXRlKTB4YjksIChieXRlKTB4NzgsIChieXRlKTB4YzAsCisgICAgICAgICAgICAoYnl0ZSkweDFmLCAoYnl0ZSkweDViLCAoYnl0ZSkweDFkLCAoYnl0ZSkweGIyLCAoYnl0ZSkweGNmLCAoYnl0ZSkweDk0LCAoYnl0ZSkweDQyLAorICAgICAgICAgICAgKGJ5dGUpMHhlZCwgKGJ5dGUpMHhiZCwgKGJ5dGUpMHhlNywgKGJ5dGUpMHhhYSwgKGJ5dGUpMHgxNCwgKGJ5dGUpMHg1NiwgKGJ5dGUpMHhkMCwKKyAgICAgICAgICAgIChieXRlKTB4OTQsIChieXRlKTB4MjUsIChieXRlKTB4MzAsIChieXRlKTB4ODcsIChieXRlKTB4MzUsIChieXRlKTB4ODIsIChieXRlKTB4YTAsCisgICAgICAgICAgICAoYnl0ZSkweDQyLCAoYnl0ZSkweGI1LCAoYnl0ZSkweDdmLCAoYnl0ZSkweDY2LCAoYnl0ZSkweDc3LCAoYnl0ZSkweGIwLCAoYnl0ZSkweDEzLAorICAgICAgICAgICAgKGJ5dGUpMHhiZSwgKGJ5dGUpMHg1NywgKGJ5dGUpMHgwNiwgKGJ5dGUpMHg3ZSwgKGJ5dGUpMHg1MCwgKGJ5dGUpMHg2NywgKGJ5dGUpMHgxMywKKyAgICAgICAgICAgIChieXRlKTB4YTcsIChieXRlKTB4MDksIChieXRlKTB4YWMsIChieXRlKTB4ZDYsIChieXRlKTB4YmYsIChieXRlKTB4MjIsIChieXRlKTB4NzQsCisgICAgICAgICAgICAoYnl0ZSkweDZiLCAoYnl0ZSkweDM3LCAoYnl0ZSkweDkyLCAoYnl0ZSkweDJiLCAoYnl0ZSkweDkxLCAoYnl0ZSkweGJkLCAoYnl0ZSkweDBhLAorICAgICAgICAgICAgKGJ5dGUpMHhkOCwgKGJ5dGUpMHgwZiwgKGJ5dGUpMHg4ZCwgKGJ5dGUpMHg4NiwgKGJ5dGUpMHg0YiwgKGJ5dGUpMHgyMCwgKGJ5dGUpMHg1ZSwKKyAgICAgICAgICAgIChieXRlKTB4NTAsIChieXRlKTB4NjAsIChieXRlKTB4ODAKKyAgICB9OworCisgICAgLyoKKyAgICAgKiBUaGUgc2FtZSBrZXkgaW4gUEVNIGZvcm1hdC4KKyAgICAgKiBUaGUgREVSIHZlcnNpb24gb2YgdGhpcyBrZXkgd2FzIGNyZWF0ZWQgdXNpbmcKKyAgICAgKgorICAgICAqIG9wZW5zc2wgcGtjczggLXRvcGs4IC1ub2NyeXB0IC1pbiBrZXkxLnBlbQorICAgICAqICAgICAgICAgLWluZm9ybSBQRU0gLW91dCBrZXkxLmRlciAtb3V0Zm9ybSBERVIKKyAgICAgKgorICAgICAqIC0tLS0tQkVHSU4gUlNBIFBSSVZBVEUgS0VZLS0tLS0KKyAgICAgKiBQcm9jLVR5cGU6IDQsRU5DUllQVEVECisgICAgICogREVLLUluZm86IERFUy1FREUzLUNCQywzNzA3MjNGRkRDMUIxQ0ZBCisgICAgICoKKyAgICAgKiBLSjIwT0RCRVF1am9PcG56TmZITm9vNURGL3FFTmh3OUlhQXBDaEdNaitXaHFZdUZmS2ZQUUt1UmxpOHNKU0VrCisgICAgICogdW9QbUVxakpuZEh6NU01Ykk3d1Z4aWFmdi9VcDQrU2FOS2huL3Z1NnhqeC9zZW5KTVg4SE1VY2hxZnZuMGVDZAorICAgICAqIDMxTkhRZU5iUTY3TzczeEdJZGx0THp3VFJzYXZUdS9od2hubkp4aVh6WG5ZdEk1SFRaVWFSYlZKUU5wZGxrTlcKKyAgICAgKiBIOTF1NzBsd2xUOFcyTUFUQmhsM1Izd0liUkhRRzFJMFJRWDEyTzA0Z01mSzFQQmw5ZC90bkZPaTRFU2Z0aDFXCisgICAgICogZTA2WFYwVTEyZzA2VjUvVVV1aWNKQU52Z3lmMFBpeDB4eFByMnRxaWJXZUdwRndDdkpwTkhsNEwzdFVvY3lkRgorICAgICAqIEhZb1VLeC9yM1ZTbWVzbloxelVNc3VPMnpYT3VMTGN3Q1NGTis3M0dCTFdvY0N4QnZhZzZIRnZDZW15NVR1aHMKKyAgICAgKiA5TWhmRis1bEtFUi85QW1hL2U3QzYxdXNhb1VoUjFPdnBHV01mamV3ckZMQ3N5V2xJbnNjb1oxYWQ1WXRjV0d4CisgICAgICogTU03K0JzVG5LMDBmY1hadVBIVFBzaXdRMGZNVmVOTTJhL2U2NWFJaXZmenpIbWI2Z3FVaWdOcGZOWWNxUXNKSgorICAgICAqIFd3b2M1aFhWTzkydnVnZEhPSE9pQVVwZlpaZ05EWndnQ1RsdU11SStLSjBRQ2IwZGhGNXcvVERBOHordlJ3bVcKKyAgICAgKiBzejVXckE0RitUM0xmd3dMUWZ4SnlIVG5iQXUzOFZsTU1aUDk4aUlvYk9YM0FBa0J3NCtrVE9DRWVkdm1LdDBmCisgICAgICogczdpU0tybm5WNkF5elJQRUpVV2tuTUY4eE5GSDdIRHFrWmY0TXY4Y01NNmU0NUs0a0JHZDE3ZDN0Y0VGaTJBbgorICAgICAqIDVsNlM5aEh0b3lNaEhqbkFjeXVISmJEOXJHUmd5T2xiaFNZVGNiWC9nS2lFQ1pqMGtmOHhIaTIwcW50TzNjK3AKKyAgICAgKiBqZHBwOTdmSU1uUVRsNUlETnhPeTVoOU1ETHMvU1lBUjdpeUYxOVJrSUdjPQorICAgICAqIC0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCisgICAgICovCisKKyAgICAvKgorICAgICAgIENlcnRpZmljYXRlOgorICAgICAgICAgICBEYXRhOgorICAgICAgICAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAgICAgICAgICAgU2VyaWFsIE51bWJlcjogMiAoMHgyKQorICAgICAgICAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICAgICAgICAgICBJc3N1ZXI6IEM9QU4sIFNUPUFuZHJvaWQsIE89QW5kcm9pZCwgT1U9QW5kcm9pZCwgQ049QW5kcm9pZC9lbWFpbEFkZHJlc3M9YW5kcm9pZEBhbmRyb2lkLmNvbQorICAgICAgICAgICAgICAgVmFsaWRpdHkKKyAgICAgICAgICAgICAgICAgICBOb3QgQmVmb3JlOiBNYXIgMjAgMTc6MDI6MzIgMjAwOSBHTVQKKyAgICAgICAgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBNYXIgMjAgMTc6MDI6MzIgMjAxMCBHTVQKKyAgICAgICAgICAgICAgIFN1YmplY3Q6IEM9QU4sIFNUPUFuZHJvaWQsIEw9QW5kcm9pZCwgTz1BbmRyb2lkLCBPVT1BbmRyb2lkLCBDTj1BbmRyb2lkL2VtYWlsQWRkcmVzcz1hbmRyb2lkQGFuZHJvaWQuY29tCisgICAgICAgICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgICAgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAgICAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMTAyNCBiaXQpCisgICAgICAgICAgICAgICAgICAgICAgIE1vZHVsdXMgKDEwMjQgYml0KToKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIDAwOmI0OmM1OmVkOmRmOjMwOjQyOjZkOjhiOmFmOjRiOmU0OjljOjEzOjVlOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgODM6MjM6Y2Q6MmY6Y2U6MzQ6ZTI6NDM6ZDc6NmM6NzI6YmI6MDM6YjM6Yjk6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAyNDowMjplMDpjYzpiNTo4ZDpkNjo5Mjo0MTowNDoyYjo1Yzo5NDpiMjpjMzoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIDljOjlkOjU2OmYwOjk5OmJjOjBmOjgxOmFmOmViOjU0OmVkOjgwOmE2OmEwOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgYzc6YzI6NDM6MDU6MDQ6N2M6OWM6N2U6MDc6MDM6MTA6Yjk6YmQ6YzU6MTY6CisgICAgICAgICAgICAgICAgICAgICAgICAgICBjZjoxOTpkZDplMzo0Zjo3Mzo4Mzo3MjpjNTo2NjplNDo1YjoxNDpjNDo5NjoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGQxOmUzOjI0OjBiOmI2OmQ0OmY3Ojg0OjJlOmIxOmU3OjkzOjAyOjlkOmY1OgorICAgICAgICAgICAgICAgICAgICAgICAgICAgZGE6YWE6YzE6ZDk6Y2M6NWU6MzY6ZTk6OGY6YmY6OGI6ZGE6YTc6NDU6ODI6CisgICAgICAgICAgICAgICAgICAgICAgICAgICBmMjpiMDpmNTphNzplNDplMTo4MDphMzoxNworICAgICAgICAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICAgICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgICAgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6CisgICAgICAgICAgICAgICAgICAgICAgIENBOkZBTFNFCisgICAgICAgICAgICAgICAgICAgTmV0c2NhcGUgQ29tbWVudDoKKyAgICAgICAgICAgICAgICAgICAgICAgT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUKKyAgICAgICAgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjoKKyAgICAgICAgICAgICAgICAgICAgICAgM0I6NUI6M0Q6REI6NDU6RjU6OEY6NTg6NzA6MEI6RkM6NzA6M0U6MzE6MkI6NDM6NjM6QTk6RkU6MkIKKyAgICAgICAgICAgICAgICAgICBYNTA5djMgQXV0aG9yaXR5IEtleSBJZGVudGlmaWVyOgorICAgICAgICAgICAgICAgICAgICAgICBrZXlpZDpFNzo5Qjo3RDo5MDoyOTpFQTo5MDowQjo3RjowODo0MTo3Njo0RTo0MToyMzpFODo0MzoyQzpBOTowMworCisgICAgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAgICAgICAgICAgMWM6N2Y6OTM6MWM6NTk6MjE6ODg6MTU6NDU6NGI6ZTA6OWM6Nzg6M2E6ODg6M2U6NTU6MTk6CisgICAgICAgICAgICAgICA4NjozMTplODo1MzozZDo3NDplMjo0YTozNDo5Zjo5MjoxNzo0ZToxMzo0Njo5Mjo1NDpmODoKKyAgICAgICAgICAgICAgIDQzOmViOjVlOjAzOjRmOjE0OjUxOjYxOmQyOjA0OmI4OjA0OjVhOjMxOmViOjE0OjZhOjE4OgorICAgICAgICAgICAgICAgYjA6MjA6MDM6OTI6MGM6N2Y6MDc6YzQ6MWI6Zjk6OWU6N2Y6NWY6ZWM6MDM6N2E6Yzg6ZTM6CisgICAgICAgICAgICAgICBkZjpkMzo5NDo2ZTo2ODo4YTozYTozZDplNDo2MTpmMzplMDo4Nzo1ZDo0MDpkODpjYjo5OToKKyAgICAgICAgICAgICAgIDRkOjlhOjdiOmJjOjk1OjdjOmQyOjlkOmI3OjA0OjlhOjlhOjYzOjg5OmNkOjM5OmVjOjMyOgorICAgICAgICAgICAgICAgNjA6MGE6OTc6ZGE6ZTk6NTA6YTU6NzM6NGE6YTI6YWE6OWM6OWI6YTg6N2Y6NWE6MjA6ZDY6CisgICAgICAgICAgICAgICA0ODpiZAorICAgICAqLworICAgIFN0cmluZyBjZXJ0aWZpY2F0ZTMgPSAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICAgICArICJNSUlDOWpDQ0FsK2dBd0lCQWdJQkFqQU5CZ2txaGtpRzl3MEJBUVVGQURCNU1Rc3dDUVlEVlFRR0V3SkJUakVRXG4iCisgICAgICAgICAgICArICJNQTRHQTFVRUNCTUhRVzVrY205cFpERVFNQTRHQTFVRUNoTUhRVzVrY205cFpERVFNQTRHQTFVRUN4TUhRVzVrXG4iCisgICAgICAgICAgICArICJjbTlwWkRFUU1BNEdBMVVFQXhNSFFXNWtjbTlwWkRFaU1DQUdDU3FHU0liM0RRRUpBUllUWVc1a2NtOXBaRUJoXG4iCisgICAgICAgICAgICArICJibVJ5YjJsa0xtTnZiVEFlRncwd09UQXpNakF4TnpBeU16SmFGdzB4TURBek1qQXhOekF5TXpKYU1JR0xNUXN3XG4iCisgICAgICAgICAgICArICJDUVlEVlFRR0V3SkJUakVRTUE0R0ExVUVDQk1IUVc1a2NtOXBaREVRTUE0R0ExVUVCeE1IUVc1a2NtOXBaREVRXG4iCisgICAgICAgICAgICArICJNQTRHQTFVRUNoTUhRVzVrY205cFpERVFNQTRHQTFVRUN4TUhRVzVrY205cFpERVFNQTRHQTFVRUF4TUhRVzVrXG4iCisgICAgICAgICAgICArICJjbTlwWkRFaU1DQUdDU3FHU0liM0RRRUpBUllUWVc1a2NtOXBaRUJoYm1SeWIybGtMbU52YlRDQm56QU5CZ2txXG4iCisgICAgICAgICAgICArICJoa2lHOXcwQkFRRUZBQU9CalFBd2dZa0NnWUVBdE1YdDN6QkNiWXV2UytTY0UxNkRJODB2empUaVE5ZHNjcnNEXG4iCisgICAgICAgICAgICArICJzN2trQXVETXRZM1dra0VFSzF5VXNzT2NuVmJ3bWJ3UGdhL3JWTzJBcHFESHdrTUZCSHljZmdjREVMbTl4UmJQXG4iCisgICAgICAgICAgICArICJHZDNqVDNPRGNzVm01RnNVeEpiUjR5UUx0dFQzaEM2eDU1TUNuZlhhcXNIWnpGNDI2WSsvaTlxblJZTHlzUFduXG4iCisgICAgICAgICAgICArICI1T0dBb3hjQ0F3RUFBYU43TUhrd0NRWURWUjBUQkFJd0FEQXNCZ2xnaGtnQmh2aENBUTBFSHhZZFQzQmxibE5UXG4iCisgICAgICAgICAgICArICJUQ0JIWlc1bGNtRjBaV1FnUTJWeWRHbG1hV05oZEdVd0hRWURWUjBPQkJZRUZEdGJQZHRGOVk5WWNBdjhjRDR4XG4iCisgICAgICAgICAgICArICJLME5qcWY0ck1COEdBMVVkSXdRWU1CYUFGT2ViZlpBcDZwQUxmd2hCZGs1QkkraERMS2tETUEwR0NTcUdTSWIzXG4iCisgICAgICAgICAgICArICJEUUVCQlFVQUE0R0JBQngva3h4WklZZ1ZSVXZnbkhnNmlENVZHWVl4NkZNOWRPSktOSitTRjA0VFJwSlUrRVByXG4iCisgICAgICAgICAgICArICJYZ05QRkZGaDBnUzRCRm94NnhScUdMQWdBNUlNZndmRUcvbWVmMS9zQTNySTQ5L1RsRzVvaWpvOTVHSHo0SWRkXG4iCisgICAgICAgICAgICArICJRTmpMbVUyYWU3eVZmTktkdHdTYW1tT0p6VG5zTW1BS2w5cnBVS1Z6U3FLcW5KdW9mMW9nMWtpOVxuIgorICAgICAgICAgICAgKyAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLSI7CisKKyAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBjZXJ0QXJyYXkzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNlcnRpZmljYXRlMworICAgICAgICAgICAgLmdldEJ5dGVzKCkpOworCisgICAgLyoKKyAgICAgKiBUaGUga2V5IGluIERFUiBmb3JtYXQuCisgICAgICogQmVsb3cgaXMgdGhlIHNhbWUga2V5IGluIFBFTSBmb3JtYXQgYXMgcmVmZXJlbmNlCisgICAgICovCisgICAgYnl0ZVtdIGtleTNCeXRlcyA9IG5ldyBieXRlW10geworICAgICAgICAgICAgKGJ5dGUpMHgzMCwgKGJ5dGUpMHg4MiwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg3NiwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHgwMSwgKGJ5dGUpMHgwMCwKKyAgICAgICAgICAgIChieXRlKTB4MzAsIChieXRlKTB4MGQsIChieXRlKTB4MDYsIChieXRlKTB4MDksIChieXRlKTB4MmEsIChieXRlKTB4ODYsIChieXRlKTB4NDgsCisgICAgICAgICAgICAoYnl0ZSkweDg2LCAoYnl0ZSkweGY3LCAoYnl0ZSkweDBkLCAoYnl0ZSkweDAxLCAoYnl0ZSkweDAxLCAoYnl0ZSkweDAxLCAoYnl0ZSkweDA1LAorICAgICAgICAgICAgKGJ5dGUpMHgwMCwgKGJ5dGUpMHgwNCwgKGJ5dGUpMHg4MiwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg2MCwgKGJ5dGUpMHgzMCwgKGJ5dGUpMHg4MiwKKyAgICAgICAgICAgIChieXRlKTB4MDIsIChieXRlKTB4NWMsIChieXRlKTB4MDIsIChieXRlKTB4MDEsIChieXRlKTB4MDAsIChieXRlKTB4MDIsIChieXRlKTB4ODEsCisgICAgICAgICAgICAoYnl0ZSkweDgxLCAoYnl0ZSkweDAwLCAoYnl0ZSkweGI0LCAoYnl0ZSkweGM1LCAoYnl0ZSkweGVkLCAoYnl0ZSkweGRmLCAoYnl0ZSkweDMwLAorICAgICAgICAgICAgKGJ5dGUpMHg0MiwgKGJ5dGUpMHg2ZCwgKGJ5dGUpMHg4YiwgKGJ5dGUpMHhhZiwgKGJ5dGUpMHg0YiwgKGJ5dGUpMHhlNCwgKGJ5dGUpMHg5YywKKyAgICAgICAgICAgIChieXRlKTB4MTMsIChieXRlKTB4NWUsIChieXRlKTB4ODMsIChieXRlKTB4MjMsIChieXRlKTB4Y2QsIChieXRlKTB4MmYsIChieXRlKTB4Y2UsCisgICAgICAgICAgICAoYnl0ZSkweDM0LCAoYnl0ZSkweGUyLCAoYnl0ZSkweDQzLCAoYnl0ZSkweGQ3LCAoYnl0ZSkweDZjLCAoYnl0ZSkweDcyLCAoYnl0ZSkweGJiLAorICAgICAgICAgICAgKGJ5dGUpMHgwMywgKGJ5dGUpMHhiMywgKGJ5dGUpMHhiOSwgKGJ5dGUpMHgyNCwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHhlMCwgKGJ5dGUpMHhjYywKKyAgICAgICAgICAgIChieXRlKTB4YjUsIChieXRlKTB4OGQsIChieXRlKTB4ZDYsIChieXRlKTB4OTIsIChieXRlKTB4NDEsIChieXRlKTB4MDQsIChieXRlKTB4MmIsCisgICAgICAgICAgICAoYnl0ZSkweDVjLCAoYnl0ZSkweDk0LCAoYnl0ZSkweGIyLCAoYnl0ZSkweGMzLCAoYnl0ZSkweDljLCAoYnl0ZSkweDlkLCAoYnl0ZSkweDU2LAorICAgICAgICAgICAgKGJ5dGUpMHhmMCwgKGJ5dGUpMHg5OSwgKGJ5dGUpMHhiYywgKGJ5dGUpMHgwZiwgKGJ5dGUpMHg4MSwgKGJ5dGUpMHhhZiwgKGJ5dGUpMHhlYiwKKyAgICAgICAgICAgIChieXRlKTB4NTQsIChieXRlKTB4ZWQsIChieXRlKTB4ODAsIChieXRlKTB4YTYsIChieXRlKTB4YTAsIChieXRlKTB4YzcsIChieXRlKTB4YzIsCisgICAgICAgICAgICAoYnl0ZSkweDQzLCAoYnl0ZSkweDA1LCAoYnl0ZSkweDA0LCAoYnl0ZSkweDdjLCAoYnl0ZSkweDljLCAoYnl0ZSkweDdlLCAoYnl0ZSkweDA3LAorICAgICAgICAgICAgKGJ5dGUpMHgwMywgKGJ5dGUpMHgxMCwgKGJ5dGUpMHhiOSwgKGJ5dGUpMHhiZCwgKGJ5dGUpMHhjNSwgKGJ5dGUpMHgxNiwgKGJ5dGUpMHhjZiwKKyAgICAgICAgICAgIChieXRlKTB4MTksIChieXRlKTB4ZGQsIChieXRlKTB4ZTMsIChieXRlKTB4NGYsIChieXRlKTB4NzMsIChieXRlKTB4ODMsIChieXRlKTB4NzIsCisgICAgICAgICAgICAoYnl0ZSkweGM1LCAoYnl0ZSkweDY2LCAoYnl0ZSkweGU0LCAoYnl0ZSkweDViLCAoYnl0ZSkweDE0LCAoYnl0ZSkweGM0LCAoYnl0ZSkweDk2LAorICAgICAgICAgICAgKGJ5dGUpMHhkMSwgKGJ5dGUpMHhlMywgKGJ5dGUpMHgyNCwgKGJ5dGUpMHgwYiwgKGJ5dGUpMHhiNiwgKGJ5dGUpMHhkNCwgKGJ5dGUpMHhmNywKKyAgICAgICAgICAgIChieXRlKTB4ODQsIChieXRlKTB4MmUsIChieXRlKTB4YjEsIChieXRlKTB4ZTcsIChieXRlKTB4OTMsIChieXRlKTB4MDIsIChieXRlKTB4OWQsCisgICAgICAgICAgICAoYnl0ZSkweGY1LCAoYnl0ZSkweGRhLCAoYnl0ZSkweGFhLCAoYnl0ZSkweGMxLCAoYnl0ZSkweGQ5LCAoYnl0ZSkweGNjLCAoYnl0ZSkweDVlLAorICAgICAgICAgICAgKGJ5dGUpMHgzNiwgKGJ5dGUpMHhlOSwgKGJ5dGUpMHg4ZiwgKGJ5dGUpMHhiZiwgKGJ5dGUpMHg4YiwgKGJ5dGUpMHhkYSwgKGJ5dGUpMHhhNywKKyAgICAgICAgICAgIChieXRlKTB4NDUsIChieXRlKTB4ODIsIChieXRlKTB4ZjIsIChieXRlKTB4YjAsIChieXRlKTB4ZjUsIChieXRlKTB4YTcsIChieXRlKTB4ZTQsCisgICAgICAgICAgICAoYnl0ZSkweGUxLCAoYnl0ZSkweDgwLCAoYnl0ZSkweGEzLCAoYnl0ZSkweDE3LCAoYnl0ZSkweDAyLCAoYnl0ZSkweDAzLCAoYnl0ZSkweDAxLAorICAgICAgICAgICAgKGJ5dGUpMHgwMCwgKGJ5dGUpMHgwMSwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg4MSwgKGJ5dGUpMHg4MCwgKGJ5dGUpMHg1MywgKGJ5dGUpMHhiYywKKyAgICAgICAgICAgIChieXRlKTB4MWYsIChieXRlKTB4MWMsIChieXRlKTB4MzQsIChieXRlKTB4MDksIChieXRlKTB4ODEsIChieXRlKTB4MWUsIChieXRlKTB4YTMsCisgICAgICAgICAgICAoYnl0ZSkweGZiLCAoYnl0ZSkweDVlLCAoYnl0ZSkweDkwLCAoYnl0ZSkweGExLCAoYnl0ZSkweDM0LCAoYnl0ZSkweDM1LCAoYnl0ZSkweDQwLAorICAgICAgICAgICAgKGJ5dGUpMHg5ZiwgKGJ5dGUpMHgyOSwgKGJ5dGUpMHhkNiwgKGJ5dGUpMHhiNSwgKGJ5dGUpMHg4ZSwgKGJ5dGUpMHg1ZCwgKGJ5dGUpMHg2OCwKKyAgICAgICAgICAgIChieXRlKTB4NmEsIChieXRlKTB4ZjYsIChieXRlKTB4OTYsIChieXRlKTB4MDMsIChieXRlKTB4ZjcsIChieXRlKTB4ZmEsIChieXRlKTB4ZjksCisgICAgICAgICAgICAoYnl0ZSkweDYwLCAoYnl0ZSkweDRmLCAoYnl0ZSkweGVhLCAoYnl0ZSkweGUyLCAoYnl0ZSkweGVhLCAoYnl0ZSkweDI5LCAoYnl0ZSkweDhiLAorICAgICAgICAgICAgKGJ5dGUpMHgyMywgKGJ5dGUpMHg4YywgKGJ5dGUpMHg5ZiwgKGJ5dGUpMHhkZCwgKGJ5dGUpMHg0OSwgKGJ5dGUpMHg4ZiwgKGJ5dGUpMHhhOCwKKyAgICAgICAgICAgIChieXRlKTB4YTYsIChieXRlKTB4NjIsIChieXRlKTB4MDcsIChieXRlKTB4NDQsIChieXRlKTB4NzksIChieXRlKTB4YTEsIChieXRlKTB4YWYsCisgICAgICAgICAgICAoYnl0ZSkweGY5LCAoYnl0ZSkweDFkLCAoYnl0ZSkweDk4LCAoYnl0ZSkweGJmLCAoYnl0ZSkweDg1LCAoYnl0ZSkweDI4LCAoYnl0ZSkweDAzLAorICAgICAgICAgICAgKGJ5dGUpMHg4NywgKGJ5dGUpMHgxNCwgKGJ5dGUpMHgyMCwgKGJ5dGUpMHhiYSwgKGJ5dGUpMHhkNCwgKGJ5dGUpMHg5NiwgKGJ5dGUpMHg2MSwKKyAgICAgICAgICAgIChieXRlKTB4MmEsIChieXRlKTB4ZDAsIChieXRlKTB4YWEsIChieXRlKTB4MzAsIChieXRlKTB4MTksIChieXRlKTB4NGIsIChieXRlKTB4NDAsCisgICAgICAgICAgICAoYnl0ZSkweDM1LCAoYnl0ZSkweGIwLCAoYnl0ZSkweDc5LCAoYnl0ZSkweDBiLCAoYnl0ZSkweDdmLCAoYnl0ZSkweGQ3LCAoYnl0ZSkweGNkLAorICAgICAgICAgICAgKGJ5dGUpMHg2NCwgKGJ5dGUpMHhkOSwgKGJ5dGUpMHg5MywgKGJ5dGUpMHgzOCwgKGJ5dGUpMHhlMiwgKGJ5dGUpMHg1OSwgKGJ5dGUpMHhlMCwKKyAgICAgICAgICAgIChieXRlKTB4OWUsIChieXRlKTB4M2EsIChieXRlKTB4MjUsIChieXRlKTB4MjcsIChieXRlKTB4YTIsIChieXRlKTB4ZDksIChieXRlKTB4MjAsCisgICAgICAgICAgICAoYnl0ZSkweGIwLCAoYnl0ZSkweDQ1LCAoYnl0ZSkweDVmLCAoYnl0ZSkweDZjLCAoYnl0ZSkweDE1LCAoYnl0ZSkweDZmLCAoYnl0ZSkweDEwLAorICAgICAgICAgICAgKGJ5dGUpMHg1NSwgKGJ5dGUpMHhhNywgKGJ5dGUpMHhmOSwgKGJ5dGUpMHgzZCwgKGJ5dGUpMHg5MiwgKGJ5dGUpMHgzYywgKGJ5dGUpMHg3YywKKyAgICAgICAgICAgIChieXRlKTB4MjMsIChieXRlKTB4MWIsIChieXRlKTB4YzAsIChieXRlKTB4YjUsIChieXRlKTB4MTcsIChieXRlKTB4NDEsIChieXRlKTB4NWUsCisgICAgICAgICAgICAoYnl0ZSkweDhjLCAoYnl0ZSkweGRjLCAoYnl0ZSkweDI1LCAoYnl0ZSkweDFkLCAoYnl0ZSkweDM1LCAoYnl0ZSkweDJiLCAoYnl0ZSkweGQzLAorICAgICAgICAgICAgKGJ5dGUpMHg5NywgKGJ5dGUpMHgxYSwgKGJ5dGUpMHg2ZiwgKGJ5dGUpMHhhZSwgKGJ5dGUpMHhlYiwgKGJ5dGUpMHhmNSwgKGJ5dGUpMHhmOSwKKyAgICAgICAgICAgIChieXRlKTB4MDIsIChieXRlKTB4NDEsIChieXRlKTB4MDAsIChieXRlKTB4ZDcsIChieXRlKTB4M2UsIChieXRlKTB4ZWQsIChieXRlKTB4NzAsCisgICAgICAgICAgICAoYnl0ZSkweGZlLCAoYnl0ZSkweGVlLCAoYnl0ZSkweDBlLCAoYnl0ZSkweDMwLCAoYnl0ZSkweDI5LCAoYnl0ZSkweGZhLCAoYnl0ZSkweGQ3LAorICAgICAgICAgICAgKGJ5dGUpMHgzOCwgKGJ5dGUpMHhjZiwgKGJ5dGUpMHg4ZSwgKGJ5dGUpMHhjMSwgKGJ5dGUpMHg5YywgKGJ5dGUpMHg3OCwgKGJ5dGUpMHgwNiwKKyAgICAgICAgICAgIChieXRlKTB4MmQsIChieXRlKTB4ZGEsIChieXRlKTB4MzMsIChieXRlKTB4NTgsIChieXRlKTB4YTEsIChieXRlKTB4N2IsIChieXRlKTB4YmYsCisgICAgICAgICAgICAoYnl0ZSkweDAwLCAoYnl0ZSkweGI5LCAoYnl0ZSkweGRmLCAoYnl0ZSkweGVhLCAoYnl0ZSkweDY1LCAoYnl0ZSkweDg2LCAoYnl0ZSkweGJiLAorICAgICAgICAgICAgKGJ5dGUpMHhjYywgKGJ5dGUpMHg4MywgKGJ5dGUpMHhjZSwgKGJ5dGUpMHhkZSwgKGJ5dGUpMHhjMywgKGJ5dGUpMHhmOCwgKGJ5dGUpMHg4OSwKKyAgICAgICAgICAgIChieXRlKTB4ZjUsIChieXRlKTB4OWYsIChieXRlKTB4YTYsIChieXRlKTB4MWQsIChieXRlKTB4YzksIChieXRlKTB4ZmIsIChieXRlKTB4OTgsCisgICAgICAgICAgICAoYnl0ZSkweGExLCAoYnl0ZSkweDJlLCAoYnl0ZSkweGUwLCAoYnl0ZSkweDU3LCAoYnl0ZSkweDZlLCAoYnl0ZSkweGJkLCAoYnl0ZSkweDU3LAorICAgICAgICAgICAgKGJ5dGUpMHgyMCwgKGJ5dGUpMHhmOSwgKGJ5dGUpMHg2YiwgKGJ5dGUpMHgxMywgKGJ5dGUpMHg0MiwgKGJ5dGUpMHg5ZCwgKGJ5dGUpMHg4ZCwKKyAgICAgICAgICAgIChieXRlKTB4NjYsIChieXRlKTB4NGQsIChieXRlKTB4N2EsIChieXRlKTB4MmQsIChieXRlKTB4MDIsIChieXRlKTB4NDEsIChieXRlKTB4MDAsCisgICAgICAgICAgICAoYnl0ZSkweGQ3LCAoYnl0ZSkweDAwLCAoYnl0ZSkweDE4LCAoYnl0ZSkweDU0LCAoYnl0ZSkweGU4LCAoYnl0ZSkweDM3LCAoYnl0ZSkweGRiLAorICAgICAgICAgICAgKGJ5dGUpMHhmOCwgKGJ5dGUpMHg5OCwgKGJ5dGUpMHg3YiwgKGJ5dGUpMHgxOCwgKGJ5dGUpMHgzMywgKGJ5dGUpMHhmNiwgKGJ5dGUpMHgyOCwKKyAgICAgICAgICAgIChieXRlKTB4YTgsIChieXRlKTB4OGMsIChieXRlKTB4ZDksIChieXRlKTB4ZmQsIChieXRlKTB4NGMsIChieXRlKTB4NGUsIChieXRlKTB4NDEsCisgICAgICAgICAgICAoYnl0ZSkweDczLCAoYnl0ZSkweDJlLCAoYnl0ZSkweDc5LCAoYnl0ZSkweDMxLCAoYnl0ZSkweGNjLCAoYnl0ZSkweDdkLCAoYnl0ZSkweDQyLAorICAgICAgICAgICAgKGJ5dGUpMHhiNywgKGJ5dGUpMHhhMSwgKGJ5dGUpMHhkMiwgKGJ5dGUpMHhiYywgKGJ5dGUpMHgxZiwgKGJ5dGUpMHg2MiwgKGJ5dGUpMHhjZiwKKyAgICAgICAgICAgIChieXRlKTB4MTUsIChieXRlKTB4N2MsIChieXRlKTB4NjIsIChieXRlKTB4OTcsIChieXRlKTB4NzAsIChieXRlKTB4ZjEsIChieXRlKTB4MTUsCisgICAgICAgICAgICAoYnl0ZSkweGYxLCAoYnl0ZSkweDMzLCAoYnl0ZSkweGExLCAoYnl0ZSkweDlkLCAoYnl0ZSkweGJiLCAoYnl0ZSkweDVmLCAoYnl0ZSkweGQ3LAorICAgICAgICAgICAgKGJ5dGUpMHg1YSwgKGJ5dGUpMHhmOSwgKGJ5dGUpMHgyNCwgKGJ5dGUpMHg1OCwgKGJ5dGUpMHhhYywgKGJ5dGUpMHg4NiwgKGJ5dGUpMHg2YSwKKyAgICAgICAgICAgIChieXRlKTB4ZWQsIChieXRlKTB4ZDQsIChieXRlKTB4ODQsIChieXRlKTB4ZTQsIChieXRlKTB4M2YsIChieXRlKTB4ZmUsIChieXRlKTB4YjAsCisgICAgICAgICAgICAoYnl0ZSkweGQzLCAoYnl0ZSkweDAyLCAoYnl0ZSkweDQxLCAoYnl0ZSkweDAwLCAoYnl0ZSkweGQ0LCAoYnl0ZSkweGI3LCAoYnl0ZSkweDg0LAorICAgICAgICAgICAgKGJ5dGUpMHhiMiwgKGJ5dGUpMHgzOSwgKGJ5dGUpMHhjZSwgKGJ5dGUpMHgwYiwgKGJ5dGUpMHg0OSwgKGJ5dGUpMHg4MCwgKGJ5dGUpMHgwMywKKyAgICAgICAgICAgIChieXRlKTB4M2MsIChieXRlKTB4YjUsIChieXRlKTB4MTEsIChieXRlKTB4MzIsIChieXRlKTB4MzQsIChieXRlKTB4OTYsIChieXRlKTB4YWMsCisgICAgICAgICAgICAoYnl0ZSkweDZhLCAoYnl0ZSkweGY2LCAoYnl0ZSkweGRmLCAoYnl0ZSkweDgwLCAoYnl0ZSkweDA0LCAoYnl0ZSkweGU0LCAoYnl0ZSkweDM5LAorICAgICAgICAgICAgKGJ5dGUpMHhjNiwgKGJ5dGUpMHgwZSwgKGJ5dGUpMHgzMiwgKGJ5dGUpMHhhMywgKGJ5dGUpMHg1ZSwgKGJ5dGUpMHgyMywgKGJ5dGUpMHgwZCwKKyAgICAgICAgICAgIChieXRlKTB4OWYsIChieXRlKTB4MDQsIChieXRlKTB4YzMsIChieXRlKTB4NzIsIChieXRlKTB4MmEsIChieXRlKTB4ZTYsIChieXRlKTB4YTIsCisgICAgICAgICAgICAoYnl0ZSkweGY1LCAoYnl0ZSkweGJjLCAoYnl0ZSkweDNmLCAoYnl0ZSkweDE1LCAoYnl0ZSkweDRjLCAoYnl0ZSkweGI1LCAoYnl0ZSkweDMzLAorICAgICAgICAgICAgKGJ5dGUpMHgyNiwgKGJ5dGUpMHhhOCwgKGJ5dGUpMHg4YywgKGJ5dGUpMHgwOSwgKGJ5dGUpMHhmYiwgKGJ5dGUpMHg3ZSwgKGJ5dGUpMHgxZSwKKyAgICAgICAgICAgIChieXRlKTB4MzIsIChieXRlKTB4NDAsIChieXRlKTB4MGQsIChieXRlKTB4MWQsIChieXRlKTB4Y2IsIChieXRlKTB4N2YsIChieXRlKTB4ZjYsCisgICAgICAgICAgICAoYnl0ZSkweGYyLCAoYnl0ZSkweDI5LCAoYnl0ZSkweDliLCAoYnl0ZSkweDAxLCAoYnl0ZSkweGQ1LCAoYnl0ZSkweDAyLCAoYnl0ZSkweDQwLAorICAgICAgICAgICAgKGJ5dGUpMHgyNCwgKGJ5dGUpMHgyNiwgKGJ5dGUpMHgxYywgKGJ5dGUpMHhmMSwgKGJ5dGUpMHgzMSwgKGJ5dGUpMHhiNiwgKGJ5dGUpMHgyYSwKKyAgICAgICAgICAgIChieXRlKTB4YTMsIChieXRlKTB4MGEsIChieXRlKTB4YTgsIChieXRlKTB4MmYsIChieXRlKTB4YjIsIChieXRlKTB4OTQsIChieXRlKTB4ZTEsCisgICAgICAgICAgICAoYnl0ZSkweGQzLCAoYnl0ZSkweDJkLCAoYnl0ZSkweDEzLCAoYnl0ZSkweDdkLCAoYnl0ZSkweGQ2LCAoYnl0ZSkweDM1LCAoYnl0ZSkweDk2LAorICAgICAgICAgICAgKGJ5dGUpMHgyNSwgKGJ5dGUpMHg5MiwgKGJ5dGUpMHg5YiwgKGJ5dGUpMHhjNywgKGJ5dGUpMHhmNiwgKGJ5dGUpMHhiNCwgKGJ5dGUpMHhkYywKKyAgICAgICAgICAgIChieXRlKTB4ZTEsIChieXRlKTB4ZDksIChieXRlKTB4MzAsIChieXRlKTB4ODAsIChieXRlKTB4NzYsIChieXRlKTB4ZGEsIChieXRlKTB4N2IsCisgICAgICAgICAgICAoYnl0ZSkweDJkLCAoYnl0ZSkweDA2LCAoYnl0ZSkweGEzLCAoYnl0ZSkweGUxLCAoYnl0ZSkweDA4LCAoYnl0ZSkweDk5LCAoYnl0ZSkweDUwLAorICAgICAgICAgICAgKGJ5dGUpMHg3MiwgKGJ5dGUpMHgyNCwgKGJ5dGUpMHg5NywgKGJ5dGUpMHgzOCwgKGJ5dGUpMHhkOSwgKGJ5dGUpMHgwNywgKGJ5dGUpMHg0ZCwKKyAgICAgICAgICAgIChieXRlKTB4NDMsIChieXRlKTB4M2IsIChieXRlKTB4N2UsIChieXRlKTB4OTMsIChieXRlKTB4ZjYsIChieXRlKTB4MzYsIChieXRlKTB4MDcsCisgICAgICAgICAgICAoYnl0ZSkweDg2LCAoYnl0ZSkweDgzLCAoYnl0ZSkweDYzLCAoYnl0ZSkweGYwLCAoYnl0ZSkweGE4LCAoYnl0ZSkweDlkLCAoYnl0ZSkweGRmLAorICAgICAgICAgICAgKGJ5dGUpMHgwNywgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg0MCwgKGJ5dGUpMHgzZSwgKGJ5dGUpMHg1OCwgKGJ5dGUpMHgwMywgKGJ5dGUpMHhiZiwKKyAgICAgICAgICAgIChieXRlKTB4ZWEsIChieXRlKTB4M2UsIChieXRlKTB4MzQsIChieXRlKTB4MmMsIChieXRlKTB4YjcsIChieXRlKTB4YzMsIChieXRlKTB4MDksCisgICAgICAgICAgICAoYnl0ZSkweGU5LCAoYnl0ZSkweGY0LCAoYnl0ZSkweDQzLCAoYnl0ZSkweDQxLCAoYnl0ZSkweGM0LCAoYnl0ZSkweDdjLCAoYnl0ZSkweDZlLAorICAgICAgICAgICAgKGJ5dGUpMHg3NSwgKGJ5dGUpMHg3MiwgKGJ5dGUpMHg1ZCwgKGJ5dGUpMHhmYywgKGJ5dGUpMHhhMywgKGJ5dGUpMHg3NSwgKGJ5dGUpMHgxZCwKKyAgICAgICAgICAgIChieXRlKTB4YTAsIChieXRlKTB4ZWUsIChieXRlKTB4YzIsIChieXRlKTB4MWYsIChieXRlKTB4NzEsIChieXRlKTB4YjAsIChieXRlKTB4ZjMsCisgICAgICAgICAgICAoYnl0ZSkweDFkLCAoYnl0ZSkweGVjLCAoYnl0ZSkweDgxLCAoYnl0ZSkweGRiLCAoYnl0ZSkweDQ1LCAoYnl0ZSkweGU1LCAoYnl0ZSkweDZhLAorICAgICAgICAgICAgKGJ5dGUpMHhlOCwgKGJ5dGUpMHhlMCwgKGJ5dGUpMHg2NCwgKGJ5dGUpMHg5MCwgKGJ5dGUpMHhmZiwgKGJ5dGUpMHhiOSwgKGJ5dGUpMHhmOCwKKyAgICAgICAgICAgIChieXRlKTB4MTIsIChieXRlKTB4ZWQsIChieXRlKTB4NTUsIChieXRlKTB4NWMsIChieXRlKTB4OWIsIChieXRlKTB4ODEsIChieXRlKTB4Y2QsCisgICAgICAgICAgICAoYnl0ZSkweGJiLCAoYnl0ZSkweDA2LCAoYnl0ZSkweDkxLCAoYnl0ZSkweGZlLCAoYnl0ZSkweDI3LCAoYnl0ZSkweDJjLCAoYnl0ZSkweDNhLAorICAgICAgICAgICAgKGJ5dGUpMHhlZCwgKGJ5dGUpMHg5NiwgKGJ5dGUpMHgzYiwgKGJ5dGUpMHhmZQorICAgIH07CisKKyAgICAvKgorICAgICAqIFRoZSBzYW1lIGtleSBpbiBQRU0gZm9ybWF0LgorICAgICAqIFRoZSBERVIgdmVyc2lvbiBvZiB0aGlzIGtleSB3YXMgY3JlYXRlZCB1c2luZworICAgICAqCisgICAgICogb3BlbnNzbCBwa2NzOCAtdG9wazggLW5vY3J5cHQgLWluIGtleTEucGVtCisgICAgICogICAgICAgICAtaW5mb3JtIFBFTSAtb3V0IGtleTEuZGVyIC1vdXRmb3JtIERFUgorICAgICAqCisgICAgICogLS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQorICAgICAqIFByb2MtVHlwZTogNCxFTkNSWVBURUQKKyAgICAgKiBERUstSW5mbzogREVTLUVERTMtQ0JDLDBFRTZCMzNFQzJEOTIyOTcKKyAgICAgKgorICAgICAqIHI3bGJXd3RsbXViZ01HMDIwWGlPU3RxZ3J2UGtQMWhUcmJPVjdHaDJJVk5UeVhXeUE4VXJpUWxQeXFCUU56eTIKKyAgICAgKiA1K1orSlVxellvTENHWTBmUTk1Y2sreWEvd0hKUVg0T1NLRk9ad1FLcFU3cEVZOXdOMVlQYTdVOVpueUNQR3RCCisgICAgICogK2Vqdkh1SU1KaEU1d3E5WTFpRURJbE9OKytvbldUZjRUMzZTejNPUThnRUpibngzeCtVamNDSU5vb2o3a09lTQorICAgICAqIGdpQ2k1eUpFT0phZjRma1Jpb1VoNlM3Y20vbXNUSDNJRDMzcnJ2VGprN2NEOG1HenpUeTRoV3lLYUs0SzlHYkMKKyAgICAgKiBkT3ZTT1JNOW1Wd1RXTVVkdTF3SjV1eWFkd0JocFNJaEMvcXBQOEplNjBuRnk4WUpsekIyRmFNVXBBdUlPTTdCCisgICAgICogRVZOMnVBTUROT3BHemNPSlBiTGlnOHNtazJsQTQreTFUM2dGZDlwYXNrU2pEOUI4Ky8zS3VhZ1dFRVFRTDdUNAorICAgICAqIFlLM3h0anpYd0VwNk9kRzJRakQ0WmNLNUQwTUt1WVBGM1Bzend6bENuQkcvT242d0l2SWlUUFdCbi9HMnU1OUQKKyAgICAgKiBnSlBWN1YzSmlwbjBpWVlOK2k3VDVUTm9UN1ZrbzhzM0JScFZTcmxGVUZGaHRRUGFkNk5jeEdOTkg1TDFnM2ZGCisgICAgICogK2RwNFRuRzY0UENRWnR1dTZJNmdmdU1YenRPd1F0RXB4eEhvOVdrdGxDcHdMMHRUL3RweCt6T1ZiTHZndXNqQgorICAgICAqIFFLWUNJcGxiU0k3VnRwT2ZjSjNrVFRBV1NPR1psaTRGYXlCL0RwbGYvRlhONlp3d0FTdzA5aW9WUWMvQ0ZkTGsKKyAgICAgKiBYdzA1ZWx4VjgvQUZ2bSsvVmtVSEs1SkpTcDMyV01nQUpBK1hyVXNPYjVsdzFUbDNIbGo5S0hBTHArUHQvaTdOCisgICAgICogK0xQbnhycHVUcnkzMUFQdDhhUnVwL3BXT0xhK2Y5N0h6K2FycDR3SmE1TEsrR3RUVHRvSTQrUVpwNXF6Ui9qeQorICAgICAqIG9NK0RvS3RLKzFXc0NVN3RlSndFV1hWL2F5bzFURUZFaGNZMEY3SUFQQ3pEbEczWE9GbXVsUT09CisgICAgICogLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0KKyAgICAgKi8KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgeworICAgICAgICBTdHJpbmcgZGVmQWxnID0gS2V5TWFuYWdlckZhY3RvcnkuZ2V0RGVmYXVsdEFsZ29yaXRobSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGRlZkFsZyk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJjb3VsZCBub3QgZ2V0IGRlZmF1bHQgS2V5TWFuYWdlckZhY3RvcnkiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHZvaWQgaW5pdChTdHJpbmcgbmFtZSkgeworICAgICAga2V5VHlwZSA9IG5hbWU7CisgICAgICB0cnkgeworICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgICBLZXlGYWN0b3J5IGtmID0gS2V5RmFjdG9yeS5nZXRJbnN0YW5jZSgiUlNBIik7CisgICAgICAgICAga2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICAgIGtleVRlc3QubG9hZChudWxsLCAiMTIzNCIudG9DaGFyQXJyYXkoKSk7CisgICAgICAgICAgaWYgKGtleVR5cGUuZXF1YWxzKENMSUVOVCkpIHsKKyAgICAgICAgICAgICAga2V5cyA9IG5ldyBQcml2YXRlS2V5WzNdOworICAgICAgICAgICAgICBrZXlzWzBdID0ga2YuZ2VuZXJhdGVQcml2YXRlKG5ldyBQS0NTOEVuY29kZWRLZXlTcGVjKGtleUJ5dGVzKSk7CisgICAgICAgICAgICAgIGtleXNbMV0gPSBrZi5nZW5lcmF0ZVByaXZhdGUobmV3IFBLQ1M4RW5jb2RlZEtleVNwZWMoa2V5MkJ5dGVzKSk7CisgICAgICAgICAgICAgIGtleXNbMl0gPSBrZi5nZW5lcmF0ZVByaXZhdGUobmV3IFBLQ1M4RW5jb2RlZEtleVNwZWMoa2V5M0J5dGVzKSk7CisgICAgICAgICAgICAgIGNlcnQgPSBuZXcgWDUwOUNlcnRpZmljYXRlWzNdOworICAgICAgICAgICAgICBjZXJ0WzBdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkpOworICAgICAgICAgICAgICBjZXJ0WzFdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkyKTsKKyAgICAgICAgICAgICAgY2VydFsyXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5Myk7CisgICAgICAgICAgICAgIGtleVRlc3Quc2V0S2V5RW50cnkoImNsaWVudEtleV8wMSIsIGtleXNbMF0sIFBBU1NXT1JELCBuZXcgWDUwOUNlcnRpZmljYXRlW10ge2NlcnRbMF19KTsKKyAgICAgICAgICAgICAga2V5VGVzdC5zZXRLZXlFbnRyeSgiY2xpZW50S2V5XzAyIiwga2V5c1sxXSwgUEFTU1dPUkQsIG5ldyBYNTA5Q2VydGlmaWNhdGVbXSB7Y2VydFswXSwgY2VydFsxXX0pOworICAgICAgICAgICAgICBrZXlUZXN0LnNldEtleUVudHJ5KCJjbGllbnRLZXlfMDMiLCBrZXlzWzJdLCBQQVNTV09SRCwgbmV3IFg1MDlDZXJ0aWZpY2F0ZVtdIHtjZXJ0WzBdLCBjZXJ0WzJdfSk7CisgICAgICAgICAgICAgIGtleVRlc3Quc2V0Q2VydGlmaWNhdGVFbnRyeSgiY2xpZW50QWxpYXNfMDEiLCBjZXJ0WzBdKTsKKyAgICAgICAgICAgICAga2V5VGVzdC5zZXRDZXJ0aWZpY2F0ZUVudHJ5KCJjbGllbnRBbGlhc18wMiIsIGNlcnRbMF0pOworICAgICAgICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImNsaWVudEFsaWFzXzAzIiwgY2VydFsxXSk7CisgICAgICAgICAgfSBlbHNlIGlmIChrZXlUeXBlLmVxdWFscyhTRVJWRVIpKSB7CisgICAgICAgICAgICAgIGtleXMgPSBuZXcgUHJpdmF0ZUtleVsxXTsKKyAgICAgICAgICAgICAga2V5c1swXSA9IGtmLmdlbmVyYXRlUHJpdmF0ZShuZXcgUEtDUzhFbmNvZGVkS2V5U3BlYyhrZXlCeXRlcykpOworICAgICAgICAgICAgICBjZXJ0ID0gbmV3IFg1MDlDZXJ0aWZpY2F0ZVsxXTsKKyAgICAgICAgICAgICAgY2VydFswXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5Myk7CisgICAgICAgICAgICAgIGtleVRlc3Quc2V0S2V5RW50cnkoInNlcnZlcktleV8wMCIsIGtleXNbMF0sIFBBU1NXT1JELCBuZXcgWDUwOUNlcnRpZmljYXRlW10ge2NlcnRbMF19KTsKKyAgICAgICAgICAgICAga2V5VGVzdC5zZXRDZXJ0aWZpY2F0ZUVudHJ5KCJzZXJ2ZXJBbGlhc18wMCIsIGNlcnRbMF0pOworICAgICAgICAgIH0KKyAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgIH0KKyAgICAgIHRyeSB7CisgICAgICAgIGZhY3RvcnkuaW5pdChrZXlUZXN0LCAiMTIzNCIudG9DaGFyQXJyYXkoKSk7CisgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICBmYWlsKCJDb3VsZCd0IGluaXQgdGhlIEtleU1hbmFnZXJGYWN0b3J5Iik7CisgICAgICB9CisgICAgICBtYW5hZ2VyID0gKFg1MDlLZXlNYW5hZ2VyKSBmYWN0b3J5LmdldEtleU1hbmFnZXJzKClbMF07CisgICAgfQorCisgICAgLyoqCisgICAgICogWDUwOUtleU1hbmFnZXIjZ2V0Q2xpZW50QWxpYXNlcyhTdHJpbmcga2V5VHlwZSwgUHJpbmNpcGFsW10gaXNzdWVycykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldENsaWVudEFsaWFzZXMoKSB7CisgICAgICAgIGluaXQoQ0xJRU5UKTsKKyAgICAgICAgYXNzZXJ0TnVsbChtYW5hZ2VyLmdldENsaWVudEFsaWFzZXMobnVsbCwgbnVsbCkpOworICAgICAgICBhc3NlcnROdWxsKG1hbmFnZXIuZ2V0Q2xpZW50QWxpYXNlcygiIiwgbnVsbCkpOworICAgICAgICBTdHJpbmdbXSByZXNBcnJheSA9IG1hbmFnZXIuZ2V0Q2xpZW50QWxpYXNlcyhUWVBFX1JTQSwgbnVsbCk7CisgICAgICAgIGFzc2VydE5vdE51bGwocmVzQXJyYXkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgcmVzQXJyYXkubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0S25vd25BbGlhc2VzKHJlc0FycmF5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBYNTA5S2V5TWFuYWdlciNjaG9vc2VDbGllbnRBbGlhcyhTdHJpbmdbXSBrZXlUeXBlLCBQcmluY2lwYWxbXSBpc3N1ZXJzLCBTb2NrZXQgc29ja2V0KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2hvb3NlQ2xpZW50QWxpYXMoKSB7CisgICAgICAgIGluaXQoQ0xJRU5UKTsKKyAgICAgICAgYXNzZXJ0TnVsbChtYW5hZ2VyLmNob29zZUNsaWVudEFsaWFzKG51bGwsIG51bGwsIG5ldyBTb2NrZXQoKSkpOworICAgICAgICBhc3NlcnROdWxsKG1hbmFnZXIuY2hvb3NlQ2xpZW50QWxpYXMobmV3IFN0cmluZ1swXSwgbnVsbCwgbmV3IFNvY2tldCgpKSk7CisgICAgICAgIGFzc2VydE51bGwobWFuYWdlci5jaG9vc2VDbGllbnRBbGlhcyhuZXcgU3RyaW5nW117IkJPR1VTIn0sIG51bGwsIG5ldyBTb2NrZXQoKSkpOworICAgICAgICBTdHJpbmcgcmVzID0gbWFuYWdlci5jaG9vc2VDbGllbnRBbGlhcyhuZXcgU3RyaW5nW117VFlQRV9SU0F9LCBudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChyZXMpOworICAgICAgICBhc3NlcnRLbm93bkFsaWFzKHJlcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogWDUwOUtleU1hbmFnZXIjZ2V0U2VydmVyQWxpYXNlcyhTdHJpbmcga2V5VHlwZSwgUHJpbmNpcGFsW10gaXNzdWVycykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFNlcnZlckFsaWFzZXMoKSB7CisgICAgICAgIGluaXQoU0VSVkVSKTsKKyAgICAgICAgYXNzZXJ0TnVsbChtYW5hZ2VyLmdldFNlcnZlckFsaWFzZXMobnVsbCwgbnVsbCkpOworICAgICAgICBhc3NlcnROdWxsKG1hbmFnZXIuZ2V0U2VydmVyQWxpYXNlcygiIiwgbnVsbCkpOworICAgICAgICBTdHJpbmdbXSByZXNBcnJheSA9IG1hbmFnZXIuZ2V0U2VydmVyQWxpYXNlcyhUWVBFX1JTQSwgbnVsbCk7CisgICAgICAgIGFzc2VydE5vdE51bGwocmVzQXJyYXkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBsZW5ndGgiLCAxLCByZXNBcnJheS5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGlhc2UiLCAic2VydmVya2V5XzAwIiwgcmVzQXJyYXlbMF0udG9Mb3dlckNhc2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogWDUwOUtleU1hbmFnZXIjY2hvb3NlU2VydmVyQWxpYXMoU3RyaW5nIGtleVR5cGUsIFByaW5jaXBhbFtdIGlzc3VlcnMsIFNvY2tldCBzb2NrZXQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jaG9vc2VTZXJ2ZXJBbGlhcygpIHsKKyAgICAgICAgaW5pdChTRVJWRVIpOworICAgICAgICBhc3NlcnROdWxsKG1hbmFnZXIuY2hvb3NlU2VydmVyQWxpYXMobnVsbCwgbnVsbCwgbmV3IFNvY2tldCgpKSk7CisgICAgICAgIGFzc2VydE51bGwobWFuYWdlci5jaG9vc2VTZXJ2ZXJBbGlhcygiIiwgbnVsbCwgbmV3IFNvY2tldCgpKSk7CisgICAgICAgIFN0cmluZyByZXMgPSBtYW5hZ2VyLmNob29zZVNlcnZlckFsaWFzKFRZUEVfUlNBLCBudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChyZXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoInNlcnZlcmtleV8wMCIsIHJlcy50b0xvd2VyQ2FzZSgpKTsKKyAgICAgICAgcmVzID0gbWFuYWdlci5jaG9vc2VTZXJ2ZXJBbGlhcyhUWVBFX1JTQSwgbnVsbCwgbmV3IFNvY2tldCgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChyZXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoInNlcnZlcmtleV8wMCIsIHJlcy50b0xvd2VyQ2FzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBYNTA5S2V5TWFuYWdlciNnZXRDZXJ0aWZpY2F0ZUNoYWluKFN0cmluZyBhbGlhcykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldENlcnRpZmljYXRlQ2hhaW4oKSB7CisgICAgICAgIGluaXQoU0VSVkVSKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiTm90IE5VTEwgZm9yIE5VTEwgcGFyYW1ldGVyIiwgbWFuYWdlci5nZXRDZXJ0aWZpY2F0ZUNoYWluKG51bGwpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiTm90IE5VTEwgZm9yIGVtcHR5IHBhcmFtZXRlciIsbWFuYWdlci5nZXRDZXJ0aWZpY2F0ZUNoYWluKCIiKSk7CisgICAgICAgIGFzc2VydE51bGwoIk5vdCBOVUxMIGZvciBjbGllbnRBbGlhc18wMSBwYXJhbWV0ZXIiLCBtYW5hZ2VyLmdldENlcnRpZmljYXRlQ2hhaW4oImNsaWVudEFsaWFzXzAxIikpOworICAgICAgICBhc3NlcnROdWxsKCJOb3QgTlVMTCBmb3Igc2VydmVyQWxpYXNfMDAgcGFyYW1ldGVyIiwgbWFuYWdlci5nZXRDZXJ0aWZpY2F0ZUNoYWluKCJzZXJ2ZXJBbGlhc18wMCIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBYNTA5S2V5TWFuYWdlciNnZXRQcml2YXRlS2V5KFN0cmluZyBhbGlhcykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFByaXZhdGVLZXkoKSB7CisgICAgICAgIGluaXQoQ0xJRU5UKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiTm90IE5VTEwgZm9yIE5VTEwgcGFyYW1ldGVyIiwgbWFuYWdlci5nZXRQcml2YXRlS2V5KG51bGwpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiTm90IE5VTEwgZm9yIHNlcnZlckFsaWFzXzAwIHBhcmFtZXRlciIsIG1hbmFnZXIuZ2V0UHJpdmF0ZUtleSgic2VydmVyQWxpYXNfMDAiKSk7CisgICAgICAgIGFzc2VydE51bGwoIk5vdCBOVUxMIGZvciBjbGllbnRBbGlhc18wMiBwYXJhbWV0ZXIiLCBtYW5hZ2VyLmdldFByaXZhdGVLZXkoImNsaWVudEFsaWFzXzAyIikpOworICAgIH0KKworCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydEtub3duQWxpYXNlcyhTdHJpbmdbXSBhbGlhc2VzKSB7CisgICAgICAgIGZvciAoU3RyaW5nIGFsaWFzIDogYWxpYXNlcykgeworICAgICAgICAgICAgYXNzZXJ0S25vd25BbGlhcyhhbGlhcyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0S25vd25BbGlhcyhTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgU3RyaW5nIGEgPSBhbGlhcy50b0xvd2VyQ2FzZSgpOworICAgICAgICBib29sZWFuIG9rYXkgPSBhLmVxdWFscygiY2xpZW50a2V5XzAxIikgfHwgYS5lcXVhbHMoImNsaWVudGtleV8wMiIpIHx8IGEuZXF1YWxzKCJjbGllbnRrZXlfMDMiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRXhwZWN0ZWQgb25lIG9mIGNsaWVudGtleV8wMSwgY2xpZW50a2V5XzAyLCBjbGllbnRrZXlfMDMuIFJlY2VpdmVkOiAiICsgYWxpYXMsIG9rYXkpOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1g1MDlUcnVzdE1hbmFnZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L25ldC9zc2wvWDUwOVRydXN0TWFuYWdlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYmU1N2RlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9uZXQvc3NsL1g1MDlUcnVzdE1hbmFnZXJUZXN0LmphdmEKQEAgLTAsMCArMSwyMTAgQEAKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YXgubmV0LnNzbC5YNTA5VHJ1c3RNYW5hZ2VyOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5UZXN0VXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnhuZXQudGVzdHMuc3VwcG9ydC5YNTA5VHJ1c3RNYW5hZ2VySW1wbDsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+WDUwOVRydXN0TWFuYWdlcjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICovCitwdWJsaWMgY2xhc3MgWDUwOVRydXN0TWFuYWdlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIFg1MDlDZXJ0aWZpY2F0ZVtdIHNldFg1MDlDZXJ0aWZpY2F0ZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZXJ0RmFjdCA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBwZW1DZXJ0ID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2VydEZhY3QKKyAgICAgICAgICAgICAgICAuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oVGVzdFV0aWxzCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0WDUwOUNlcnRpZmljYXRlX3YzKCkpKTsKKyAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIHhjZXJ0ID0ge3BlbUNlcnR9OworICAgICAgICAgICAgcmV0dXJuIHhjZXJ0OworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBleCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBYNTA5Q2VydGlmaWNhdGVbXSBzZXRJbnZhbGlkKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNlcnRGYWN0ID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlIHBlbUNlcnQgPSAoWDUwOUNlcnRpZmljYXRlKSBjZXJ0RmFjdAorICAgICAgICAgICAgICAgIC5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShUZXN0VXRpbHMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRYNTA5Q2VydGlmaWNhdGVfdjEoKSkpOworICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlW10geGNlcnQgPSB7cGVtQ2VydH07CisgICAgICAgICAgICByZXR1cm4geGNlcnQ7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGV4KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlg1MDlUcnVzdE1hbmFnZXIjY2hlY2tDbGllbnRUcnVzdGVkKFg1MDlDZXJ0aWZpY2F0ZVtdIGNoYWluLCBTdHJpbmcgYXV0aFR5cGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jaGVja0NsaWVudFRydXN0ZWRfMDEoKSB7CisgICAgICAgIFg1MDlUcnVzdE1hbmFnZXJJbXBsIHh0bSA9IG5ldyBYNTA5VHJ1c3RNYW5hZ2VySW1wbCgpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGVbXSB4Y2VydCA9IG51bGw7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHh0bS5jaGVja0NsaWVudFRydXN0ZWQoeGNlcnQsICJTU0wiKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgeGNlcnQgPSBuZXcgWDUwOUNlcnRpZmljYXRlWzBdOworICAgICAgICB0cnkgeworICAgICAgICAgICAgeHRtLmNoZWNrQ2xpZW50VHJ1c3RlZCh4Y2VydCwgIlNTTCIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICB4Y2VydCA9IHNldFg1MDlDZXJ0aWZpY2F0ZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgeHRtLmNoZWNrQ2xpZW50VHJ1c3RlZCh4Y2VydCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB4dG0uY2hlY2tDbGllbnRUcnVzdGVkKHhjZXJ0LCAiIik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuWDUwOVRydXN0TWFuYWdlciNjaGVja0NsaWVudFRydXN0ZWQoWDUwOUNlcnRpZmljYXRlW10gY2hhaW4sIFN0cmluZyBhdXRoVHlwZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NoZWNrQ2xpZW50VHJ1c3RlZF8wMigpIHsKKyAgICAgICAgWDUwOVRydXN0TWFuYWdlckltcGwgeHRtID0gbmV3IFg1MDlUcnVzdE1hbmFnZXJJbXBsKCk7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIHhjZXJ0ID0gc2V0SW52YWxpZCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB4dG0uY2hlY2tDbGllbnRUcnVzdGVkKHhjZXJ0LCAiU1NMIik7CisgICAgICAgICAgICBmYWlsKCJDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGNlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5uZXQuc3NsLlg1MDlUcnVzdE1hbmFnZXIjY2hlY2tDbGllbnRUcnVzdGVkKFg1MDlDZXJ0aWZpY2F0ZVtdIGNoYWluLCBTdHJpbmcgYXV0aFR5cGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9jaGVja0NsaWVudFRydXN0ZWRfMDMoKSB7CisgICAgICAgIFg1MDlUcnVzdE1hbmFnZXJJbXBsIHh0bSA9IG5ldyBYNTA5VHJ1c3RNYW5hZ2VySW1wbCgpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGVbXSB4Y2VydCA9IHNldFg1MDlDZXJ0aWZpY2F0ZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB4dG0uY2hlY2tDbGllbnRUcnVzdGVkKHhjZXJ0LCAiU1NMIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuWDUwOVRydXN0TWFuYWdlciNjaGVja1NlcnZlclRydXN0ZWQoWDUwOUNlcnRpZmljYXRlW10gY2hhaW4sIFN0cmluZyBhdXRoVHlwZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NoZWNrU2VydmVyVHJ1c3RlZF8wMSgpIHsKKyAgICAgICAgWDUwOVRydXN0TWFuYWdlckltcGwgeHRtID0gbmV3IFg1MDlUcnVzdE1hbmFnZXJJbXBsKCk7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIHhjZXJ0ID0gbnVsbDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgeHRtLmNoZWNrU2VydmVyVHJ1c3RlZCh4Y2VydCwgIlNTTCIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICB4Y2VydCA9IG5ldyBYNTA5Q2VydGlmaWNhdGVbMF07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB4dG0uY2hlY2tTZXJ2ZXJUcnVzdGVkKHhjZXJ0LCAiU1NMIik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHhjZXJ0ID0gc2V0WDUwOUNlcnRpZmljYXRlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB4dG0uY2hlY2tTZXJ2ZXJUcnVzdGVkKHhjZXJ0LCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHh0bS5jaGVja1NlcnZlclRydXN0ZWQoeGNlcnQsICIiKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5YNTA5VHJ1c3RNYW5hZ2VyI2NoZWNrU2VydmVyVHJ1c3RlZChYNTA5Q2VydGlmaWNhdGVbXSBjaGFpbiwgU3RyaW5nIGF1dGhUeXBlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY2hlY2tTZXJ2ZXJUcnVzdGVkXzAyKCkgeworICAgICAgICBYNTA5VHJ1c3RNYW5hZ2VySW1wbCB4dG0gPSBuZXcgWDUwOVRydXN0TWFuYWdlckltcGwoKTsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlW10geGNlcnQgPSBzZXRJbnZhbGlkKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHh0bS5jaGVja1NlcnZlclRydXN0ZWQoeGNlcnQsICJTU0wiKTsKKyAgICAgICAgICAgIGZhaWwoIkNlcnRpZmljYXRlRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gY2UpIHsKKyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4Lm5ldC5zc2wuWDUwOVRydXN0TWFuYWdlciNjaGVja1NlcnZlclRydXN0ZWQoWDUwOUNlcnRpZmljYXRlW10gY2hhaW4sIFN0cmluZyBhdXRoVHlwZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NoZWNrU2VydmVyVHJ1c3RlZF8wMygpIHsKKyAgICAgICAgWDUwOVRydXN0TWFuYWdlckltcGwgeHRtID0gbmV3IFg1MDlUcnVzdE1hbmFnZXJJbXBsKCk7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIHhjZXJ0ID0gc2V0WDUwOUNlcnRpZmljYXRlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHh0bS5jaGVja1NlcnZlclRydXN0ZWQoeGNlcnQsICJTU0wiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgubmV0LnNzbC5YNTA5VHJ1c3RNYW5hZ2VyI2dldEFjY2VwdGVkSXNzdWVycygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBY2NlcHRlZElzc3VlcnMoKSB7CisgICAgICAgIFg1MDlUcnVzdE1hbmFnZXJJbXBsIHh0bSA9IG5ldyBYNTA5VHJ1c3RNYW5hZ2VySW1wbCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHh0bS5nZXRBY2NlcHRlZElzc3VlcnMoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGV4KTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9zZWN1cml0eS9hdXRoL0NhbGxiYWNrSGFuZGxlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvYXV0aC9DYWxsYmFja0hhbmRsZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzZjODYwYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvYXV0aC9DYWxsYmFja0hhbmRsZXJUZXN0LmphdmEKQEAgLTAsMCArMSw0NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXguc2VjdXJpdHkuYXV0aDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suQ2FsbGJhY2s7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC5jYWxsYmFjay5DYWxsYmFja0hhbmRsZXI7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkNhbGxiYWNrSGFuZGxlcjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIENhbGxiYWNrSGFuZGxlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5zZWN1cml0eS5hdXRoLmNhbGxiYWNrLkNhbGxiYWNrSGFuZGxlciNoYW5kbGUoQ2FsbGJhY2tbXSBjYWxsYmFja3MpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9DYWxsYmFja0hhbmRsZXIoKSB7CisgICAgICAgIENhbGxiYWNrSGFuZGxlckltcGwgY2ggPSBuZXcgQ2FsbGJhY2tIYW5kbGVySW1wbCgpOworICAgICAgICBhc3NlcnRGYWxzZShjaC5jYWxsZWQpOworICAgICAgICBjaC5oYW5kbGUobnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoY2guY2FsbGVkKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIENhbGxiYWNrSGFuZGxlckltcGwgaW1wbGVtZW50cyBDYWxsYmFja0hhbmRsZXIgeworICAgICAgICBib29sZWFuIGNhbGxlZCA9IGZhbHNlOworICAgICAgICBwdWJsaWMgdm9pZCBoYW5kbGUoQ2FsbGJhY2tbXSBjYWxsYmFja3MpIHsKKyAgICAgICAgICAgIGNhbGxlZCA9IHRydWU7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2F1dGgvRGVzdHJveUZhaWxlZEV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvYXV0aC9EZXN0cm95RmFpbGVkRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNmYjNkOTcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2F1dGgvRGVzdHJveUZhaWxlZEV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDgxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5zZWN1cml0eS5hdXRoOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC5EZXN0cm95RmFpbGVkRXhjZXB0aW9uOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5EZXN0cm95RmFpbGVkRXhjZXB0aW9uPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgRGVzdHJveUZhaWxlZEV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgZm9yIERlc3Ryb3lGYWlsZWRFeGNlcHRpb25UZXN0LgorICAgICAqCisgICAgICogQHBhcmFtIGFyZzAKKyAgICAgKi8KKyAgICBwdWJsaWMgRGVzdHJveUZhaWxlZEV4Y2VwdGlvblRlc3QoU3RyaW5nIGFyZzApIHsKKyAgICAgICAgc3VwZXIoYXJnMCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gbXNncyA9IHsKKyAgICAgICAgICAgICIiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSIgfTsKKworCisgICAgLyoqCisgICAgICogamF2YXguc2VjdXJpdHkuYXV0aC5EZXN0cm95RmFpbGVkRXhjZXB0aW9uI0Rlc3Ryb3lGYWlsZWRFeGNlcHRpb24oKQorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBEZXN0cm95RmFpbGVkRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVzdHJveUZhaWxlZEV4Y2VwdGlvbjAxKCkgeworICAgICAgICBEZXN0cm95RmFpbGVkRXhjZXB0aW9uIGRmRSA9IG5ldyBEZXN0cm95RmFpbGVkRXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIGRmRS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCBkZkUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXguc2VjdXJpdHkuYXV0aC5EZXN0cm95RmFpbGVkRXhjZXB0aW9uI0Rlc3Ryb3lGYWlsZWRFeGNlcHRpb24oU3RyaW5nIG1zZykKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgd2l0aCBub3QgbnVsbCBwYXJhbWV0ZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdERlc3Ryb3lGYWlsZWRFeGNlcHRpb24wMigpIHsKKyAgICAgICAgRGVzdHJveUZhaWxlZEV4Y2VwdGlvbiBkZkU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZGZFID0gbmV3IERlc3Ryb3lGYWlsZWRFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIGRmRS5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgZGZFLmdldENhdXNlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXguc2VjdXJpdHkuYXV0aC5EZXN0cm95RmFpbGVkRXhjZXB0aW9uI0Rlc3Ryb3lGYWlsZWRFeGNlcHRpb24oU3RyaW5nIG1zZykKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgd2l0aCBudWxsIHBhcmFtZXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVzdHJveUZhaWxlZEV4Y2VwdGlvbjAzKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICAgICAgRGVzdHJveUZhaWxlZEV4Y2VwdGlvbiBkZkUgPSBuZXcgRGVzdHJveUZhaWxlZEV4Y2VwdGlvbihtc2cpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCBkZkUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgZGZFLmdldENhdXNlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvYXV0aC9EZXN0cm95YWJsZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvYXV0aC9EZXN0cm95YWJsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YWU0N2NlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9zZWN1cml0eS9hdXRoL0Rlc3Ryb3lhYmxlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4LnNlY3VyaXR5LmF1dGg7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLkRlc3Ryb3lhYmxlOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGguRGVzdHJveUZhaWxlZEV4Y2VwdGlvbjsKKworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5EZXN0cm95YWJsZTwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIERlc3Ryb3lhYmxlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmF4LnNlY3VyaXR5LmF1dGguRGVzdHJveWFibGUjZGVzdHJveSgpCisgICAgICogamF2YXguc2VjdXJpdHkuYXV0aC5EZXN0cm95YWJsZSNpc0Rlc3Ryb3llZCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9kZXN0cm95KCkgeworICAgICAgICBteURlc3Ryb3lhYmxlIG1kID0gbmV3IG15RGVzdHJveWFibGUoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKG1kLmlzRGVzdHJveWVkKCkpOworICAgICAgICAgICAgbWQuZGVzdHJveSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShtZC5pc0Rlc3Ryb3llZCgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgbXlEZXN0cm95YWJsZSBpbXBsZW1lbnRzIERlc3Ryb3lhYmxlIHsKKworICAgICAgICBib29sZWFuIGRlc3Ryb3lEb25lID0gZmFsc2U7CisKKyAgICAgICAgbXlEZXN0cm95YWJsZSgpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGRlc3Ryb3koKSB0aHJvd3MgRGVzdHJveUZhaWxlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBkZXN0cm95RG9uZSA9IHRydWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0Rlc3Ryb3llZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBkZXN0cm95RG9uZTsKKyAgICAgICAgfQorICAgIH0KK30KKworCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2F1dGgvTG9naW5FeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2F1dGgvTG9naW5FeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWY1M2E5OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvYXV0aC9Mb2dpbkV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDgxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5zZWN1cml0eS5hdXRoOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC5sb2dpbi5Mb2dpbkV4Y2VwdGlvbjsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+TG9naW5FeGNlcHRpb248L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBMb2dpbkV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgZm9yIExvZ2luRXhjZXB0aW9uVGVzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhcmcwCisgICAgICovCisgICAgcHVibGljIExvZ2luRXhjZXB0aW9uVGVzdChTdHJpbmcgYXJnMCkgeworICAgICAgICBzdXBlcihhcmcwKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisKKyAgICAvKioKKyAgICAgKiBqYXZheC5zZWN1cml0eS5hdXRoLmxvZ2luLkxvZ2luRXhjZXB0aW9uI0xvZ2luRXhjZXB0aW9uKCkKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgTG9naW5FeGNlcHRpb24gd2l0aCBubyBkZXRhaWwgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RMb2dpbkV4Y2VwdGlvbjAxKCkgeworICAgICAgICBMb2dpbkV4Y2VwdGlvbiBsRSA9IG5ldyBMb2dpbkV4Y2VwdGlvbigpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCBsRS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCBsRS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5zZWN1cml0eS5hdXRoLmxvZ2luLkxvZ2luRXhjZXB0aW9uI0xvZ2luRXhjZXB0aW9uKFN0cmluZyBtc2cpCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIHdpdGggbm90IG51bGwgcGFyYW1ldGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RMb2dpbkV4Y2VwdGlvbjAyKCkgeworICAgICAgICBMb2dpbkV4Y2VwdGlvbiBsRTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBsRSA9IG5ldyBMb2dpbkV4Y2VwdGlvbihtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgbEUuZ2V0TWVzc2FnZSgpLCBtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIGxFLmdldENhdXNlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXguc2VjdXJpdHkuYXV0aC5sb2dpbi5Mb2dpbkV4Y2VwdGlvbiNMb2dpbkV4Y2VwdGlvbihTdHJpbmcgbXNnKQorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyB3aXRoIG51bGwgcGFyYW1ldGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RMb2dpbkV4Y2VwdGlvbjAzKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICAgICAgTG9naW5FeGNlcHRpb24gbEUgPSBuZXcgTG9naW5FeGNlcHRpb24obXNnKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgbEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgbEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9zZWN1cml0eS9hdXRoL1Bhc3N3b3JkQ2FsbGJhY2tUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2F1dGgvUGFzc3dvcmRDYWxsYmFja1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZGQ5OTJiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9zZWN1cml0eS9hdXRoL1Bhc3N3b3JkQ2FsbGJhY2tUZXN0LmphdmEKQEAgLTAsMCArMSwxMDcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4LnNlY3VyaXR5LmF1dGg7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLmNhbGxiYWNrLlBhc3N3b3JkQ2FsbGJhY2s7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlBhc3N3b3JkQ2FsbGJhY2s8L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBQYXNzd29yZENhbGxiYWNrVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suUGFzc3dvcmRDYWxsYmFjayNQYXNzd29yZENhbGxiYWNrKFN0cmluZyBwcm9tcHQsIGJvb2xlYW4gZWNob09uKQorICAgICAqIGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suUGFzc3dvcmRDYWxsYmFjayNnZXRQcm9tcHQoKQorICAgICAqIGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suUGFzc3dvcmRDYWxsYmFjayNpc0VjaG9PbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9QYXNzd29yZENhbGxiYWNrKCkgeworICAgICAgICBTdHJpbmcgcHJvbXB0ID0gInByb21wdFRlc3QiOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQYXNzd29yZENhbGxiYWNrIHBjID0gbmV3IFBhc3N3b3JkQ2FsbGJhY2socHJvbXB0LCB0cnVlKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIk51bGwgb2JqZWN0IHJldHVybmVkIiwgcGMpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHByb21wdCwgcGMuZ2V0UHJvbXB0KCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIHBjLmlzRWNob09uKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQYXNzd29yZENhbGxiYWNrIHBjID0gbmV3IFBhc3N3b3JkQ2FsbGJhY2socHJvbXB0LCBmYWxzZSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJOdWxsIG9iamVjdCByZXR1cm5lZCIsIHBjKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhwcm9tcHQsIHBjLmdldFByb21wdCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgcGMuaXNFY2hvT24oKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFBhc3N3b3JkQ2FsbGJhY2sgcGMgPSBuZXcgUGFzc3dvcmRDYWxsYmFjayhudWxsLCB0cnVlKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQYXNzd29yZENhbGxiYWNrIHBjID0gbmV3IFBhc3N3b3JkQ2FsbGJhY2soIiIsIHRydWUpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG5wZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXguc2VjdXJpdHkuYXV0aC5jYWxsYmFjay5QYXNzd29yZENhbGxiYWNrI2dldFBhc3N3b3JkKCkKKyAgICAgKiBqYXZheC5zZWN1cml0eS5hdXRoLmNhbGxiYWNrLlBhc3N3b3JkQ2FsbGJhY2sjc2V0UGFzc3dvcmQoY2hhcltdIHBhc3N3b3JkKQorICAgICAqIGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suUGFzc3dvcmRDYWxsYmFjayNjbGVhclBhc3N3b3JkKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1Bhc3N3b3JkKCkgeworICAgICAgICBTdHJpbmcgcHJvbXB0ID0gInByb21wdFRlc3QiOworICAgICAgICBjaGFyW10gcHN3MSA9ICJ0ZXN0UGFzc3dvcmQiLnRvQ2hhckFycmF5KCk7CisgICAgICAgIGNoYXJbXSBwc3cyID0gIm5ld1Bhc3N3b3JkIi50b0NoYXJBcnJheSgpOworICAgICAgICBQYXNzd29yZENhbGxiYWNrIHBjID0gbmV3IFBhc3N3b3JkQ2FsbGJhY2socHJvbXB0LCB0cnVlKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbChwYy5nZXRQYXNzd29yZCgpKTsKKyAgICAgICAgICAgIHBjLnNldFBhc3N3b3JkKHBzdzEpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHBzdzEubGVuZ3RoLCBwYy5nZXRQYXNzd29yZCgpLmxlbmd0aCk7CisgICAgICAgICAgICBwYy5zZXRQYXNzd29yZChudWxsKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwocGMuZ2V0UGFzc3dvcmQoKSk7CisgICAgICAgICAgICBwYy5zZXRQYXNzd29yZChwc3cyKTsKKyAgICAgICAgICAgIGNoYXJbXSByZXMgPSBwYy5nZXRQYXNzd29yZCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHBzdzIubGVuZ3RoLCByZXMubGVuZ3RoKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcGFzc3dvcmQgd2FzIHJldHVybmVkIiwgcHN3MltpXSwgcmVzW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBjLmNsZWFyUGFzc3dvcmQoKTsKKyAgICAgICAgICAgIHJlcyA9IHBjLmdldFBhc3N3b3JkKCk7CisgICAgICAgICAgICBpZiAocmVzLmVxdWFscyhwc3cyKSkgeworICAgICAgICAgICAgICAgIGZhaWwoIkluY29ycmVjdCBwYXNzd29yZCB3YXMgcmV0dXJuZWQgYWZ0ZXIgY2xlYXIiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBjLnNldFBhc3N3b3JkKHBzdzEpOworICAgICAgICAgICAgcmVzID0gcGMuZ2V0UGFzc3dvcmQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhwc3cxLmxlbmd0aCwgcmVzLmxlbmd0aCk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHJlc3VsdCIsIHBzdzFbaV0sIHJlc1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9zZWN1cml0eS9hdXRoL1N1YmplY3RUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2F1dGgvU3ViamVjdFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNTc0MWE5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9zZWN1cml0eS9hdXRoL1N1YmplY3RUZXN0LmphdmEKQEAgLTAsMCArMSwyNTAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4LnNlY3VyaXR5LmF1dGg7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLkF1dGhQZXJtaXNzaW9uOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGguUHJpdmF0ZUNyZWRlbnRpYWxQZXJtaXNzaW9uOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGguU3ViamVjdDsKKworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbENvbnRleHQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdGVjdGlvbkRvbWFpbjsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+U3ViamVjdDwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIFN1YmplY3RUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YXguc2VjdXJpdHkuYXV0aC5TdWJqZWN0I1N1YmplY3QoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JfMDEoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdWJqZWN0IHMgPSBuZXcgU3ViamVjdCgpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTnVsbCBvYmplY3QgcmV0dXJuZWQiLCBzKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlNldCBvZiBwcmluY2lwYWwgaXMgbm90IGVtcHR5Iiwgcy5nZXRQcmluY2lwYWxzKCkuaXNFbXB0eSgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlNldCBvZiBwcml2YXRlIGNyZWRlbnRpYWxzIGlzIG5vdCBlbXB0eSIsIHMuZ2V0UHJpdmF0ZUNyZWRlbnRpYWxzKCkuaXNFbXB0eSgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlNldCBvZiBwdWJsaWMgY3JlZGVudGlhbHMgaXMgbm90IGVtcHR5Iiwgcy5nZXRQdWJsaWNDcmVkZW50aWFscygpLmlzRW1wdHkoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXguc2VjdXJpdHkuYXV0aC5TdWJqZWN0I2RvQXMoU3ViamVjdCBzdWJqZWN0LCBQcml2aWxlZ2VkQWN0aW9uIGFjdGlvbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RvQXNfMDEoKSB7CisgICAgICAgIFN1YmplY3Qgc3ViaiA9IG5ldyBTdWJqZWN0KCk7CisgICAgICAgIFByaXZpbGVnZWRBY3Rpb248T2JqZWN0PiBwYSA9IG5ldyBteVByaXZpbGVnZWRBY3Rpb24oKTsKKyAgICAgICAgUHJpdmlsZWdlZEFjdGlvbjxPYmplY3Q+IHBhTnVsbCA9IG51bGw7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE9iamVjdCBvYmogPSBTdWJqZWN0LmRvQXMobnVsbCwgcGEpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBPYmplY3Qgb2JqID0gU3ViamVjdC5kb0FzKHN1YmosIHBhKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgT2JqZWN0IG9iaiA9IFN1YmplY3QuZG9BcyhzdWJqLCBwYU51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LnNlY3VyaXR5LmF1dGguU3ViamVjdCNkb0FzKFN1YmplY3Qgc3ViamVjdCwgUHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbiBhY3Rpb24pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9kb0FzXzAyKCkgeworICAgICAgICBTdWJqZWN0IHN1YmogPSBuZXcgU3ViamVjdCgpOworICAgICAgICBQcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uPE9iamVjdD4gcGVhID0gbmV3IG15UHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbigpOworICAgICAgICBQcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uPE9iamVjdD4gcGVhTnVsbCA9IG51bGw7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE9iamVjdCBvYmogPSBTdWJqZWN0LmRvQXMobnVsbCwgcGVhKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgT2JqZWN0IG9iaiA9IFN1YmplY3QuZG9BcyhzdWJqLCBwZWEpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBPYmplY3Qgb2JqID0gU3ViamVjdC5kb0FzKHN1YmosIHBlYU51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBpbnN0ZWFkIG9mIE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3ViamVjdC5kb0FzKHN1YmosIG5ldyBQcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uPE9iamVjdD4oKXsKKyAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHRocm93cyBQcml2aWxlZ2VkQWN0aW9uRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24obnVsbCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSk7CisgICAgICAgICAgICBmYWlsKCJQcml2aWxlZ2VkQWN0aW9uRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5zZWN1cml0eS5hdXRoLlN1YmplY3QjZG9Bc1ByaXZpbGVnZWQoU3ViamVjdCBzdWJqZWN0LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpdmlsZWdlZEFjdGlvbiBhY3Rpb24sCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBY2Nlc3NDb250cm9sQ29udGV4dCBhY2MpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9kb0FzUHJpdmlsZWdlZF8wMSgpIHsKKyAgICAgICAgU3ViamVjdCBzdWJqID0gbmV3IFN1YmplY3QoKTsKKyAgICAgICAgUHJpdmlsZWdlZEFjdGlvbjxPYmplY3Q+IHBhID0gbmV3IG15UHJpdmlsZWdlZEFjdGlvbigpOworICAgICAgICBQcml2aWxlZ2VkQWN0aW9uPE9iamVjdD4gcGFOdWxsID0gbnVsbDsKKyAgICAgICAgQWNjZXNzQ29udHJvbENvbnRleHQgYWNjID0gQWNjZXNzQ29udHJvbGxlci5nZXRDb250ZXh0KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE9iamVjdCBvYmogPSBTdWJqZWN0LmRvQXNQcml2aWxlZ2VkKG51bGwsIHBhLCBhY2MpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBPYmplY3Qgb2JqID0gU3ViamVjdC5kb0FzUHJpdmlsZWdlZChzdWJqLCBwYSwgYWNjKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgT2JqZWN0IG9iaiA9IFN1YmplY3QuZG9Bc1ByaXZpbGVnZWQoc3ViaiwgcGFOdWxsLCBhY2MpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LnNlY3VyaXR5LmF1dGguU3ViamVjdCNkb0FzUHJpdmlsZWdlZChTdWJqZWN0IHN1YmplY3QsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uIGFjdGlvbiwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xDb250ZXh0IGFjYykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RvQXNQcml2aWxlZ2VkXzAyKCkgeworICAgICAgICBTdWJqZWN0IHN1YmogPSBuZXcgU3ViamVjdCgpOworICAgICAgICBQcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uPE9iamVjdD4gcGVhID0gbmV3IG15UHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbigpOworICAgICAgICBQcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uPE9iamVjdD4gcGVhTnVsbCA9IG51bGw7CisgICAgICAgIEFjY2Vzc0NvbnRyb2xDb250ZXh0IGFjYyA9IEFjY2Vzc0NvbnRyb2xsZXIuZ2V0Q29udGV4dCgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBPYmplY3Qgb2JqID0gU3ViamVjdC5kb0FzUHJpdmlsZWdlZChudWxsLCBwZWEsIGFjYyk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE9iamVjdCBvYmogPSBTdWJqZWN0LmRvQXNQcml2aWxlZ2VkKHN1YmosIHBlYSwgYWNjKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgT2JqZWN0IG9iaiA9IFN1YmplY3QuZG9Bc1ByaXZpbGVnZWQoc3ViaiwgcGVhTnVsbCwgYWNjKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN1YmplY3QuZG9Bc1ByaXZpbGVnZWQoc3ViaiwgbmV3IFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb248T2JqZWN0PigpeworICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgdGhyb3dzIFByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbihudWxsKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9LCBhY2MpOworICAgICAgICAgICAgZmFpbCgiUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXguc2VjdXJpdHkuYXV0aC5TdWJqZWN0I2dldFN1YmplY3QoQWNjZXNzQ29udHJvbENvbnRleHQgYWNjKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0U3ViamVjdCgpIHsKKyAgICAgICAgU3ViamVjdCBzdWJqID0gbmV3IFN1YmplY3QoKTsKKyAgICAgICAgQWNjZXNzQ29udHJvbENvbnRleHQgYWNjID0gbmV3IEFjY2Vzc0NvbnRyb2xDb250ZXh0KG5ldyBQcm90ZWN0aW9uRG9tYWluWzBdKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbChTdWJqZWN0LmdldFN1YmplY3QoYWNjKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5zZWN1cml0eS5hdXRoLlN1YmplY3QjdG9TdHJpbmcoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdG9TdHJpbmcoKSB7CisgICAgICAgIFN1YmplY3Qgc3ViaiA9IG5ldyBTdWJqZWN0KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIk51bGwgcmV0dXJuZWQiLCBzdWJqLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LnNlY3VyaXR5LmF1dGguU3ViamVjdCNoYXNoQ29kZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9oYXNoQ29kZSgpIHsKKyAgICAgICAgU3ViamVjdCBzdWJqID0gbmV3IFN1YmplY3QoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTnVsbCByZXR1cm5lZCIsIHN1YmouaGFzaENvZGUoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisgICAgfQorfQorCisKK2NsYXNzIG15UHJpdmlsZWdlZEFjdGlvbiBpbXBsZW1lbnRzIFByaXZpbGVnZWRBY3Rpb24gPE9iamVjdD4geworICAgIG15UHJpdmlsZWdlZEFjdGlvbigpe30KKyAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBPYmplY3QoKTsKKyAgICB9Cit9CisKK2NsYXNzIG15UHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbiBpbXBsZW1lbnRzIFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb24gPE9iamVjdD4geworICAgIG15UHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbigpe30KKyAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBPYmplY3QoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2F1dGgvVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvYXV0aC9VbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFjNDFkNjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2F1dGgvVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDEyOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXguc2VjdXJpdHkuYXV0aDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLmNhbGxiYWNrLkNhbGxiYWNrOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5VbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgZm9yIFVuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb25UZXN0LgorICAgICAqCisgICAgICogQHBhcmFtIGFyZzAKKyAgICAgKi8KKyAgICBwdWJsaWMgVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvblRlc3QoU3RyaW5nIGFyZzApIHsKKyAgICAgICAgc3VwZXIoYXJnMCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gbXNncyA9IHsKKyAgICAgICAgICAgICIiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSIgfTsKKworCisgICAgLyoqCisgICAgICogamF2YXguc2VjdXJpdHkuYXV0aC5jYWxsYmFjay5VbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uVGVzdCNVbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uKENhbGxiYWNrIGNhbGxiYWNrKQorICAgICAqIGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvblRlc3QjZ2V0Q2FsbGJhY2soKQorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyB3aXRoIG51bGwgcGFyYW1ldGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uMDEoKSB7CisgICAgICAgIENhbGxiYWNrIGMgPSBudWxsOworICAgICAgICBVbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uIHVjRSA9IG5ldyBVbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uKGMpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB1Y0UuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2FsbGJhY2soKSBtdXN0IHJldHVybiBudWxsIiwgdWNFLmdldENhbGxiYWNrKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvblRlc3QjVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbihDYWxsYmFjayBjYWxsYmFjaykKKyAgICAgKiBqYXZheC5zZWN1cml0eS5hdXRoLmNhbGxiYWNrLlVuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb25UZXN0I2dldENhbGxiYWNrKCkKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgd2l0aCBub3QgbnVsbCBwYXJhbWV0ZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb24wMigpIHsKKyAgICAgICAgbXlDYWxsYmFjayBjID0gbmV3IG15Q2FsbGJhY2soKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ2FsbGJhY2sgb2JqZWN0IGlzIG51bGwiLCBjKTsKKyAgICAgICAgVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbiB1Y0UgPSBuZXcgVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbihjKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdWNFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGNhbGxiYWNrIG9iamVjdCB3YXMgcmV0dXJuZWQiLCBjLCB1Y0UuZ2V0Q2FsbGJhY2soKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXguc2VjdXJpdHkuYXV0aC5jYWxsYmFjay5VbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uVGVzdCNVbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uKENhbGxiYWNrIGNhbGxiYWNrLCBTdHJpbmcgbXNnKQorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyB3aXRoIG51bGwgY2FsbGJhY2sgcGFyYW1ldGVyIGFuZCBudWxsIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb24wMygpIHsKKyAgICAgICAgVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbiB1Y0UgPSBuZXcgVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbihudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdWNFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhbGxiYWNrKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB1Y0UuZ2V0Q2FsbGJhY2soKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXguc2VjdXJpdHkuYXV0aC5jYWxsYmFjay5VbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uVGVzdCNVbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uKENhbGxiYWNrIGNhbGxiYWNrLCBTdHJpbmcgbXNnKQorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyB3aXRoIG51bGwgY2FsbGJhY2sgcGFyYW1ldGVyIGFuZCBub3QgbnVsbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uMDQoKSB7CisgICAgICAgIFVuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb24gdWNFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHVjRSA9IG5ldyBVbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uKG51bGwsIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm46ICIuY29uY2F0KG1zZ3NbaV0pLCB1Y0UuZ2V0TWVzc2FnZSgpLCBtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldENhbGxiYWNrKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB1Y0UuZ2V0Q2FsbGJhY2soKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5zZWN1cml0eS5hdXRoLmNhbGxiYWNrLlVuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb25UZXN0I1Vuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb24oQ2FsbGJhY2sgY2FsbGJhY2ssIFN0cmluZyBtc2cpCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIHdpdGggbm90IG51bGwgY2FsbGJhY2sgcGFyYW1ldGVyIGFuZCBudWxsIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb24wNSgpIHsKKyAgICAgICAgbXlDYWxsYmFjayBjID0gbmV3IG15Q2FsbGJhY2soKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ2FsbGJhY2sgb2JqZWN0IGlzIG51bGwiLCBjKTsKKyAgICAgICAgVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbiB1Y0UgPSBuZXcgVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbihjLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdWNFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGNhbGxiYWNrIG9iamVjdCB3YXMgcmV0dXJuZWQiLCBjLCB1Y0UuZ2V0Q2FsbGJhY2soKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXguc2VjdXJpdHkuYXV0aC5jYWxsYmFjay5VbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uVGVzdCNVbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uKENhbGxiYWNrIGNhbGxiYWNrLCBTdHJpbmcgbXNnKQorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyB3aXRoIG5vdCBudWxsIHBhcmFtZXRlcnMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb24wNigpIHsKKyAgICAgICAgbXlDYWxsYmFjayBjID0gbmV3IG15Q2FsbGJhY2soKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ2FsbGJhY2sgb2JqZWN0IGlzIG51bGwiLCBjKTsKKyAgICAgICAgVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbiB1Y0U7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdWNFID0gbmV3IFVuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb24oYywgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHVjRS5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgY2FsbGJhY2sgb2JqZWN0IHdhcyByZXR1cm5lZCIsIGMsIHVjRS5nZXRDYWxsYmFjaygpKTsKKyAgICAgICAgfQorICAgIH0KK30KKworY2xhc3MgbXlDYWxsYmFjayBpbXBsZW1lbnRzIENhbGxiYWNrIHsKKyAgICBteUNhbGxiYWNrKCl7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2F1dGgvWDUwMFByaW5jaXBhbFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvYXV0aC9YNTAwUHJpbmNpcGFsVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdjYjgxYmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2F1dGgvWDUwMFByaW5jaXBhbFRlc3QuamF2YQpAQCAtMCwwICsxLDI3MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXguc2VjdXJpdHkuYXV0aDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0LlRlc3RVdGlsczsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+WDUwMFByaW5jaXBhbDwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIFg1MDBQcmluY2lwYWxUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWwjWDUwMFByaW5jaXBhbChTdHJpbmcgbmFtZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1g1MDBQcmluY2lwYWxfMDEoKSB7CisgICAgICAgIFN0cmluZyBuYW1lID0gIkNOPUR1a2UsT1U9SmF2YVNvZnQsTz1TdW4gTWljcm9zeXN0ZW1zLEM9VVMiOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBYNTAwUHJpbmNpcGFsIHhwciA9IG5ldyBYNTAwUHJpbmNpcGFsKG5hbWUpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTnVsbCBvYmplY3QgcmV0dXJuZWQiLCB4cHIpOworICAgICAgICAgICAgU3RyaW5nIHJlc05hbWUgPSB4cHIuZ2V0TmFtZSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG5hbWUsIHJlc05hbWUpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBYNTAwUHJpbmNpcGFsIHhwciA9IG5ldyBYNTAwUHJpbmNpcGFsKChTdHJpbmcpbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBYNTAwUHJpbmNpcGFsIHhwciA9IG5ldyBYNTAwUHJpbmNpcGFsKCJYNTAwUHJpbmNpcGFsTmFtZSIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG5wZSkgeworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbCNYNTAwUHJpbmNpcGFsKElucHV0U3RyZWFtIGlzKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfWDUwMFByaW5jaXBhbF8wMigpIHsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSAiQ049RHVrZSxPVT1KYXZhU29mdCxPPVN1biBNaWNyb3N5c3RlbXMsQz1VUyI7CisgICAgICAgIGJ5dGVbXSBiYSA9IGdldEJ5dGVBcnJheShUZXN0VXRpbHMuZ2V0WDUwOUNlcnRpZmljYXRlX3YxKCkpOworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYSk7CisgICAgICAgIElucHV0U3RyZWFtIGlzTnVsbCA9IG51bGw7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFg1MDBQcmluY2lwYWwgeHByID0gbmV3IFg1MDBQcmluY2lwYWwoaXMpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiTnVsbCBvYmplY3QgcmV0dXJuZWQiLCB4cHIpOworICAgICAgICAgICAgYnl0ZVtdIHJlc0FycmF5ID0geHByLmdldEVuY29kZWQoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhiYS5sZW5ndGgsIHJlc0FycmF5Lmxlbmd0aCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFg1MDBQcmluY2lwYWwgeHByID0gbmV3IFg1MDBQcmluY2lwYWwoaXNOdWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKSB7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICAgICAgaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmFtZS5nZXRCeXRlcygpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFg1MDBQcmluY2lwYWwgeHByID0gbmV3IFg1MDBQcmluY2lwYWwoaXMpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG5wZSkgeworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbCNYNTAwUHJpbmNpcGFsKGJ5dGVbXSBuYW1lKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfWDUwMFByaW5jaXBhbF8wMygpIHsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSAiQ049RHVrZSxPVT1KYXZhU29mdCxPPVN1biBNaWNyb3N5c3RlbXMsQz1VUyI7CisgICAgICAgIGJ5dGVbXSBiYSA9IGdldEJ5dGVBcnJheShUZXN0VXRpbHMuZ2V0WDUwOUNlcnRpZmljYXRlX3YxKCkpOworICAgICAgICBieXRlW10gYmFOdWxsID0gbnVsbDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgWDUwMFByaW5jaXBhbCB4cHIgPSBuZXcgWDUwMFByaW5jaXBhbChiYSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJOdWxsIG9iamVjdCByZXR1cm5lZCIsIHhwcik7CisgICAgICAgICAgICBieXRlW10gcmVzQXJyYXkgPSB4cHIuZ2V0RW5jb2RlZCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGJhLmxlbmd0aCwgcmVzQXJyYXkubGVuZ3RoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgWDUwMFByaW5jaXBhbCB4cHIgPSBuZXcgWDUwMFByaW5jaXBhbChiYU51bGwpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG5wZSkgeworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICBiYSA9IG5hbWUuZ2V0Qnl0ZXMoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFg1MDBQcmluY2lwYWwgeHByID0gbmV3IFg1MDBQcmluY2lwYWwoYmEpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG5wZSkgeworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbCNnZXROYW1lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE5hbWUoKSB7CisgICAgICAgIFN0cmluZyBuYW1lID0gIkNOPUR1a2UsT1U9SmF2YVNvZnQsTz1TdW4gTWljcm9zeXN0ZW1zLEM9VVMiOworICAgICAgICBYNTAwUHJpbmNpcGFsIHhwciA9IG5ldyBYNTAwUHJpbmNpcGFsKG5hbWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHJlc05hbWUgPSB4cHIuZ2V0TmFtZSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG5hbWUsIHJlc05hbWUpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsI2dldE5hbWUoU3RyaW5nIGZvcm1hdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE5hbWVfRm9ybWF0KCkgeworICAgICAgICBTdHJpbmcgbmFtZSA9ICJDTj1EdWtlLE9VPUphdmFTb2Z0LE89U3VuIE1pY3Jvc3lzdGVtcyxDPVVTIjsKKyAgICAgICAgU3RyaW5nIGV4cGVjdGVkTmFtZSA9ICJjbj1kdWtlLG91PWphdmFzb2Z0LG89c3VuIG1pY3Jvc3lzdGVtcyxjPXVzIjsKKyAgICAgICAgWDUwMFByaW5jaXBhbCB4cHIgPSBuZXcgWDUwMFByaW5jaXBhbChuYW1lKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyByZXNOYW1lID0geHByLmdldE5hbWUoWDUwMFByaW5jaXBhbC5DQU5PTklDQUwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkTmFtZSwgcmVzTmFtZSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgZXhwZWN0ZWROYW1lID0gIkNOPUR1a2UsIE9VPUphdmFTb2Z0LCBPPVN1biBNaWNyb3N5c3RlbXMsIEM9VVMiOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHJlc05hbWUgPSB4cHIuZ2V0TmFtZShYNTAwUHJpbmNpcGFsLlJGQzE3NzkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkTmFtZSwgcmVzTmFtZSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyByZXNOYW1lID0geHByLmdldE5hbWUoWDUwMFByaW5jaXBhbC5SRkMyMjUzKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhuYW1lLCByZXNOYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHJlc05hbWUgPSB4cHIuZ2V0TmFtZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAgd2Fzbid0IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gIGlhZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgcmVzTmFtZSA9IHhwci5nZXROYW1lKCJSRkMyMjU0Iik7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gIHdhc24ndCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICBpYWUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsI2hhc2hDb2RlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2hhc2hDb2RlKCkgeworICAgICAgICBTdHJpbmcgbmFtZSA9ICJDTj1EdWtlLE9VPUphdmFTb2Z0LE89U3VuIE1pY3Jvc3lzdGVtcyxDPVVTIjsKKyAgICAgICAgWDUwMFByaW5jaXBhbCB4cHIgPSBuZXcgWDUwMFByaW5jaXBhbChuYW1lKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCByZXMgPSB4cHIuaGFzaENvZGUoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocmVzKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbCN0b1N0cmluZygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF90b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSAiQ049RHVrZSwgT1U9SmF2YVNvZnQsIE89U3VuIE1pY3Jvc3lzdGVtcywgQz1VUyI7CisgICAgICAgIFg1MDBQcmluY2lwYWwgeHByID0gbmV3IFg1MDBQcmluY2lwYWwobmFtZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgcmVzID0geHByLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHJlcyk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobmFtZSwgcmVzKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbCNnZXRFbmNvZGVkKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEVuY29kZWQoKSB7CisgICAgICAgIGJ5dGVbXSBiYSA9IGdldEJ5dGVBcnJheShUZXN0VXRpbHMuZ2V0WDUwOUNlcnRpZmljYXRlX3YxKCkpOworICAgICAgICBYNTAwUHJpbmNpcGFsIHhwciA9IG5ldyBYNTAwUHJpbmNpcGFsKGJhKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ5dGVbXSByZXMgPSB4cHIuZ2V0RW5jb2RlZCgpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChyZXMpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGJhLmxlbmd0aCwgcmVzLmxlbmd0aCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWwjZXF1YWxzKE9iamVjdCBvKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZXF1YWxzKCkgeworICAgICAgICBTdHJpbmcgbmFtZTEgPSAiQ049RHVrZSwgT1U9SmF2YVNvZnQsIE89U3VuIE1pY3Jvc3lzdGVtcywgQz1VUyI7CisgICAgICAgIFN0cmluZyBuYW1lMiA9ICJjbj1kdWtlLG91PWphdmFzb2Z0LG89c3VuIG1pY3Jvc3lzdGVtcyxjPXVzIjsKKyAgICAgICAgU3RyaW5nIG5hbWUzID0gIkNOPUFsZXggQXN0YXBjaHVrLCBPVT1TU0csIE89SW50ZWwgWkFPLCBDPVJVIjsKKyAgICAgICAgWDUwMFByaW5jaXBhbCB4cHIxID0gbmV3IFg1MDBQcmluY2lwYWwobmFtZTEpOworICAgICAgICBYNTAwUHJpbmNpcGFsIHhwcjIgPSBuZXcgWDUwMFByaW5jaXBhbChuYW1lMik7CisgICAgICAgIFg1MDBQcmluY2lwYWwgeHByMyA9IG5ldyBYNTAwUHJpbmNpcGFsKG5hbWUzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkZhbHNlIHJldHVybmVkIiwgeHByMS5lcXVhbHMoeHByMikpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIlRydWUgcmV0dXJuZWQiLCB4cHIxLmVxdWFscyh4cHIzKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBieXRlW10gZ2V0Qnl0ZUFycmF5KGJ5dGVbXSBhcnJheSkgeworICAgICAgICBieXRlW10geCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShhcnJheSk7CisgICAgICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydCA9IChYNTA5Q2VydGlmaWNhdGUpY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShpcyk7CisgICAgICAgICAgICBYNTAwUHJpbmNpcGFsIHh4ID0gY2VydC5nZXRJc3N1ZXJYNTAwUHJpbmNpcGFsKCk7CisgICAgICAgICAgICB4ID0geHguZ2V0RW5jb2RlZCgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHg7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUzZmJkOWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDc4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4LnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb247CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkRpZ2VzdEV4Y2VwdGlvbjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgc3RhdGljIFN0cmluZ1tdIG1zZ3MgPSB7CisgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UiIH07CisKKyAgICBzdGF0aWMgVGhyb3dhYmxlIHRDYXVzZSA9IG5ldyBUaHJvd2FibGUoIlRocm93YWJsZSBmb3IgZXhjZXB0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uKCk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uMDEoKSB7CisgICAgICAgIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gdEUgPSBuZXcgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbigpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gd2l0aCBkZXRhaWwgbWVzc2FnZQorICAgICAqIG1zZy4gUGFyYW1ldGVyIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24wMigpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uKG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm46ICIuY29uY2F0KG1zZ3NbaV0pLCB0RQorICAgICAgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZSgpLCBtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHdoZW4gPGNvZGU+bXNnPC9jb2RlPgorICAgICAqIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjAzKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICAgICAgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uKG1zZyk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jY2MzYTJjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXguc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CisKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+RGlnZXN0RXhjZXB0aW9uPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgQ2VydGlmaWNhdGVFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgc3RhdGljIFN0cmluZ1tdIG1zZ3MgPSB7CisgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UiIH07CisKKyAgICBzdGF0aWMgVGhyb3dhYmxlIHRDYXVzZSA9IG5ldyBUaHJvd2FibGUoIlRocm93YWJsZSBmb3IgZXhjZXB0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbigpPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246CisgICAgICogY29uc3RydWN0cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRXhjZXB0aW9uMDEoKSB7CisgICAgICAgIENlcnRpZmljYXRlRXhjZXB0aW9uIHRFID0gbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlRXhjZXB0aW9uIHdpdGggZGV0YWlsIG1lc3NhZ2UgbXNnLgorICAgICAqIFBhcmFtZXRlciA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUV4Y2VwdGlvbjAyKCkgeworICAgICAgICBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbihtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlRXhjZXB0aW9uIHdoZW4gPGNvZGU+bXNnPC9jb2RlPiBpcworICAgICAqIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVFeGNlcHRpb24wMygpIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9IG51bGw7CisgICAgICAgIENlcnRpZmljYXRlRXhjZXB0aW9uIHRFID0gbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKG1zZyk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQwZTk0ZTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXguc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uOworCisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkRpZ2VzdEV4Y2VwdGlvbjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBzdGF0aWMgU3RyaW5nW10gbXNncyA9IHsKKyAgICAgICAgICAgICIiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSIgfTsKKworICAgIHN0YXRpYyBUaHJvd2FibGUgdENhdXNlID0gbmV3IFRocm93YWJsZSgiVGhyb3dhYmxlIGZvciBleGNlcHRpb24iKTsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbigpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24wMSgpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uIHRFID0gbmV3IENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbigpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uIHdpdGggZGV0YWlsIG1lc3NhZ2UKKyAgICAgKiBtc2cuIFBhcmFtZXRlciA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24wMigpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbihtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24gd2hlbiA8Y29kZT5tc2c8L2NvZGU+CisgICAgICogaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24wMygpIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9IG51bGw7CisgICAgICAgIENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24obXNnKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNzQ2NjQ4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw4MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YXguc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uOworCisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkRpZ2VzdEV4Y2VwdGlvbjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgc3RhdGljIFN0cmluZ1tdIG1zZ3MgPSB7CisgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UiIH07CisKKyAgICBzdGF0aWMgVGhyb3dhYmxlIHRDYXVzZSA9IG5ldyBUaHJvd2FibGUoIlRocm93YWJsZSBmb3IgZXhjZXB0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uKCk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwKKyAgICAgKiBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24wMSgpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbiB3aXRoCisgICAgICogZGV0YWlsIG1lc3NhZ2UgbXNnLiBQYXJhbWV0ZXIgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbjAyKCkgeworICAgICAgICBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uMDMoKSB7CisgICAgICAgIFN0cmluZyBtc2cgPSBudWxsOworICAgICAgICBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uIHRFID0gbmV3IENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgbXNnKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmMwN2ZmNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw4MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YXguc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb247CisKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+RGlnZXN0RXhjZXB0aW9uPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworCisgICAgc3RhdGljIFN0cmluZ1tdIG1zZ3MgPSB7CisgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UiIH07CisKKyAgICBzdGF0aWMgVGhyb3dhYmxlIHRDYXVzZSA9IG5ldyBUaHJvd2FibGUoIlRocm93YWJsZSBmb3IgZXhjZXB0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24oKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uMDEoKSB7CisgICAgICAgIENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24oKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlCisgICAgICogbXNnLiBQYXJhbWV0ZXIgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uMDIoKSB7CisgICAgICAgIENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIHdoZW4gPGNvZGU+bXNnPC9jb2RlPgorICAgICAqIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uMDMoKSB7CisgICAgICAgIFN0cmluZyBtc2cgPSBudWxsOworICAgICAgICBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24gdEUgPSBuZXcgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uKG1zZyk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYTFjN2EwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTU5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyAqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4LnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlRXhjZXB0aW9uOworCitpbXBvcnQgamF2YXguc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXguc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKKworcHVibGljIGNsYXNzIENlcnRpZmljYXRlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBzdHViIGNsYXNzIHVzZWQgZm9yIHRlc3Rpbmcgb2Ygbm9uIGFic3RyYWN0IG1ldGhvZHMuCisgICAgICovCisgICAgcHJpdmF0ZSBjbGFzcyBUQlRDZXJ0IGV4dGVuZHMgQ2VydGlmaWNhdGUgeworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5KSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBJbnZhbGlkS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLCBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgdmVyaWZ5KFB1YmxpY0tleSBrZXksIFN0cmluZyBzaWdQcm92aWRlcikKKyAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBJbnZhbGlkS2V5RXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiAiVEJUQ2VydCI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUHVibGljS2V5IGdldFB1YmxpY0tleSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGUoKTwvY29kZT4gY29uc3RydWN0b3I8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdENlcnRpZmljYXRlKCkgeworICAgICAgICBUQlRDZXJ0IHRidF9jZXJ0ID0gbmV3IFRCVENlcnQoKTsKKworICAgICAgICBhc3NlcnROdWxsKCJQdWJsaWMga2V5IHNob3VsZCBiZSBudWxsIiwgdGJ0X2NlcnQuZ2V0UHVibGljS2V5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHN0cmluZyByZXByZXNlbnRhdGlvbiBmb3IgQ2VydGlmaWNhdGUiLCAiVEJUQ2VydCIsIHRidF9jZXJ0LnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGVxdWFscyhPYmplY3Qgb2JqKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhlIGNvcnJlY3RuZXNzIG9mIGVxdWFsCisgICAgICogb3BlcmF0aW9uOiBpdCBzaG91bGQgYmUgcmVmbGV4aXZlLCBzeW1tZXRyaWMsIHRyYW5zaXRpdmUsIGNvbnNpc3RlbnQgYW5kCisgICAgICogc2hvdWxkIGJlIGZhbHNlIG9uIG51bGwgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHMoKSB7CisgICAgICAgIFRCVENlcnQgdGJ0X2NlcnQgPSBuZXcgVEJUQ2VydCgpIHsKKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7IDEsIDIsIDMgfTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBUQlRDZXJ0IHRidF9jZXJ0XzEgPSBuZXcgVEJUQ2VydCgpIHsKKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7IDEsIDIsIDMgfTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBUQlRDZXJ0IHRidF9jZXJ0XzIgPSBuZXcgVEJUQ2VydCgpIHsKKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7IDEsIDIsIDMgfTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBUQlRDZXJ0IHRidF9jZXJ0XzMgPSBuZXcgVEJUQ2VydCgpIHsKKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7IDMsIDIsIDEgfTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICAvLyBjaGVja2luZyBmb3IgcmVmbGV4aXZlIGxhdzoKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGVxdWl2YWxlbmNlIHJlbGF0aW9uIHNob3VsZCBiZSByZWZsZXhpdmUuIiwgdGJ0X2NlcnQKKyAgICAgICAgICAgICAgICAuZXF1YWxzKHRidF9jZXJ0KSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICJUaGUgQ2VydGlmaWNhdGVzIHdpdGggZXF1YWwgZW5jb2RlZCBmb3JtIHNob3VsZCBiZSBlcXVhbCIsCisgICAgICAgICAgICAgICAgdGJ0X2NlcnQsIHRidF9jZXJ0XzEpOworICAgICAgICAvLyBjaGVja2luZyBmb3Igc3ltbWV0cmljIGxhdzoKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGVxdWl2YWxlbmNlIHJlbGF0aW9uIHNob3VsZCBiZSBzeW1tZXRyaWMuIiwgdGJ0X2NlcnRfMQorICAgICAgICAgICAgICAgIC5lcXVhbHModGJ0X2NlcnQpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgIlRoZSBDZXJ0aWZpY2F0ZXMgd2l0aCBlcXVhbCBlbmNvZGVkIGZvcm0gc2hvdWxkIGJlIGVxdWFsIiwKKyAgICAgICAgICAgICAgICB0YnRfY2VydF8xLCB0YnRfY2VydF8yKTsKKyAgICAgICAgLy8gY2hlY2tpbmcgZm9yIHRyYW5zaXRpdmUgbGF3OgorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgZXF1aXZhbGVuY2UgcmVsYXRpb24gc2hvdWxkIGJlIHRyYW5zaXRpdmUuIiwgdGJ0X2NlcnQKKyAgICAgICAgICAgICAgICAuZXF1YWxzKHRidF9jZXJ0XzIpKTsKKworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIG5vdCBiZSBlcXVhbCB0byBudWxsIG9iamVjdC4iLCB0YnRfY2VydAorICAgICAgICAgICAgICAgIC5lcXVhbHMobnVsbCkpOworCisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgQ2VydGlmaWNhdGVzIHdpdGggZGlmZmVyaW5nIGVuY29kZWQgZm9ybSAiCisgICAgICAgICAgICAgICAgKyAic2hvdWxkIG5vdCBiZSBlcXVhbCIsIHRidF9jZXJ0LmVxdWFscyh0YnRfY2VydF8zKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgQ2VydGlmaWNhdGVzIHNob3VsZCBub3QgYmUgZXF1YWxzIHRvIHRoZSBvYmplY3QgIgorICAgICAgICAgICAgICAgICsgIndoaWNoIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBDZXJ0aWZpY2F0ZSIsIHRidF9jZXJ0CisgICAgICAgICAgICAgICAgLmVxdWFscyhuZXcgT2JqZWN0KCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBoYXNoQ29kZSgpIG1ldGhvZCB0ZXN0aW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RIYXNoQ29kZSgpIHsKKyAgICAgICAgVEJUQ2VydCB0YnRfY2VydCA9IG5ldyBUQlRDZXJ0KCkgeworICAgICAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVtdIHsgMSwgMiwgMyB9OworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBUQlRDZXJ0IHRidF9jZXJ0XzEgPSBuZXcgVEJUQ2VydCgpIHsKKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7IDEsIDIsIDMgfTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBhc3NlcnRUcnVlKCJFcXVhbCBvYmplY3RzIHNob3VsZCBoYXZlIHRoZSBzYW1lIGhhc2ggY29kZXMuIiwgdGJ0X2NlcnQKKyAgICAgICAgICAgICAgICAuaGFzaENvZGUoKSA9PSB0YnRfY2VydF8xLmhhc2hDb2RlKCkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgVGVzdCBzdWl0ZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBUZXN0U3VpdGUoQ2VydGlmaWNhdGVUZXN0LmNsYXNzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3NlY3VyaXR5L2NlcnQvWDUwOUNlcnRpZmljYXRlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9zZWN1cml0eS9jZXJ0L1g1MDlDZXJ0aWZpY2F0ZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45OTZjOTRkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC9zZWN1cml0eS9jZXJ0L1g1MDlDZXJ0aWZpY2F0ZVRlc3QuamF2YQpAQCAtMCwwICsxLDc4OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisgKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyAqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uQnJva2VuVGVzdDsKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5TaWRlRWZmZWN0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCB0ZXN0cy50YXJnZXRzLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5VGVzdFg1MDk7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlci5TZXJ2aWNlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nZ2VyOworCitpbXBvcnQgamF2YXguc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXguc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb247CitpbXBvcnQgamF2YXguc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKK2ltcG9ydCB0ZXN0cy50YXJnZXRzLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5VGVzdFg1MDk7CisKKy8qKgorICovCitwdWJsaWMgY2xhc3MgWDUwOUNlcnRpZmljYXRlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8vIFRlc3RpbmcgZGF0YSB3YXMgZ2VuZXJhdGVkIGJ5IHVzaW5nIG9mIGNsYXNzZXMKKyAgICAvLyBmcm9tIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xIHBhY2thZ2UgZW5jb2RlZAorICAgIC8vIGJ5IG9yZy5hcGFjaGUuaGFybW9ueS5taXNjLkJhc2U2NCBjbGFzcy4KKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBiYXNlNjRjZXJ0ID0gIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICAgICAgICAgKyAiTUlJQytqQ0NBcmFnQXdJQkFnSUNBaXN3REFZSEtvWkl6amdFQXdFQkFEQWRNUnN3R1FZRFZRUUtFeEpEWlhKMGEiCisgICAgICAgICAgICArICJXWnBZMkYwWlNCSmMzTjFaWEl3SWhnUE1UazNNREF4TVRJeE16UTJOREJhR0E4eE9UY3dNREV5TkRBek16TXlNRiIKKyAgICAgICAgICAgICsgIm93SHpFZE1Cc0dBMVVFQ2hNVVUzVmlhbVZqZENCUGNtZGhibWw2WVhScGIyNHdHVEFNQmdjcWhrak9PQVFEQVFFIgorICAgICAgICAgICAgKyAiQUF3a0FBUUlEQkFVR0J3aUJBZ0NxZ2dJQVZhT0NBaFF3Z2dJUU1BOEdBMVVkRHdFQi93UUZBd01CcW9Bd0VnWUQiCisgICAgICAgICAgICArICJWUjBUQVFIL0JBZ3dCZ0VCL3dJQkJUQVVCZ05WSFNBQkFmOEVDakFJTUFZR0JGVWRJQUF3WndZRFZSMFJBUUgvQiIKKyAgICAgICAgICAgICsgIkYwd1c0RU1jbVpqUURneU1pNU9ZVzFsZ2dka1RsTk9ZVzFscEJjeEZUQVRCZ05WQkFvVERFOXlaMkZ1YVhwaGRHIgorICAgICAgICAgICAgKyAibHZib1lhYUhSMGNEb3ZMM1Z1YVdadmNtMHVVbVZ6YjNWeVkyVXVTV1NIQlAvLy93Q0lCeW9Eb2x5RHNnTXdEQVkiCisgICAgICAgICAgICArICJEVlIwZUFRSC9CQUl3QURBTUJnTlZIU1FCQWY4RUFqQUFNSUdaQmdOVkhTVUJBZjhFZ1k0d2dZc0dCRlVkSlFBRyIKKyAgICAgICAgICAgICsgIkNDc0dBUVVGQndNQkJnZ3JCZ0VGQlFjREFRWUlLd1lCQlFVSEF3SUdDQ3NHQVFVRkJ3TURCZ2dyQmdFRkJRY0RCIgorICAgICAgICAgICAgKyAiQVlJS3dZQkJRVUhBd1VHQ0NzR0FRVUZCd01HQmdnckJnRUZCUWNEQndZSUt3WUJCUVVIQXdnR0NDc0dBUVVGQnciCisgICAgICAgICAgICArICJNSkJnZ3JCZ0VGQlFnQ0FnWUtLd1lCQkFHQ053b0RBd1lKWUlaSUFZYjRRZ1FCTUEwR0ExVWROZ0VCL3dRREFnRSIKKyAgICAgICAgICAgICsgIkJNQTRHQkNwTmhna0JBZjhFQXdFQkFUQmtCZ05WSFJJRVhUQmJnUXh5Wm1OQU9ESXlMazVoYldXQ0IyUk9VMDVoIgorICAgICAgICAgICAgKyAiYldXa0Z6RVZNQk1HQTFVRUNoTU1UM0puWVc1cGVtRjBhVzl1aGhwb2RIUndPaTh2ZFc1cFptOXliUzVTWlhOdmQiCisgICAgICAgICAgICArICJYSmpaUzVKWkljRS8vLy9BSWdIS2dPaVhJT3lBekFKQmdOVkhSOEVBakFBTUFvR0ExVWRJd1FEQVFFQk1Bb0dBMSIKKyAgICAgICAgICAgICsgIlVkRGdRREFRRUJNQW9HQTFVZElRUURBUUVCTUF3R0J5cUdTTTQ0QkFNQkFRQURNQUF3TFFJVUFMNFF2b2F6TldQIgorICAgICAgICAgICAgKyAiN2pyajg0L0dabGhtMDlEc0NGUUNCS0dLQ0diclA2NFZ0VXQ0SlBtTGpXMVZ4UUE9PVxuIgorICAgICAgICAgICAgKyAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLSI7CisKKyAgIC8qCisgICAgKiBhIHNlbGYtc2lnbmVkIGNlcnRpZmljYXRlCisgICAgKi8KKyAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBzZWxmU2lnbmVkQ2VydCA9ICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIgKworICAgIk1JSURQekNDQXFpZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRVUZBREI1TVFzd0NRWURWUVFHRXdKQlRqRVEiICsKKyAgICJNQTRHQTFVRUNCTUhRVzVrY205cFpERVFNQTRHQTFVRUNoTUhRVzVrY205cFpERVFNQTRHQTFVRUN4TUhRVzVrIiArCisgICAiY205cFpERVFNQTRHQTFVRUF4TUhRVzVrY205cFpERWlNQ0FHQ1NxR1NJYjNEUUVKQVJZVFlXNWtjbTlwWkVCaCIgKworICAgImJtUnliMmxrTG1OdmJUQWVGdzB3T1RBek1qQXhOekF3TURaYUZ3MHhNakF6TVRreE56QXdNRFphTUhreEN6QUoiICsKKyAgICJCZ05WQkFZVEFrRk9NUkF3RGdZRFZRUUlFd2RCYm1SeWIybGtNUkF3RGdZRFZRUUtFd2RCYm1SeWIybGtNUkF3IiArCisgICAiRGdZRFZRUUxFd2RCYm1SeWIybGtNUkF3RGdZRFZRUURFd2RCYm1SeWIybGtNU0l3SUFZSktvWklodmNOQVFrQiIgKworICAgIkZoTmhibVJ5YjJsa1FHRnVaSEp2YVdRdVkyOXRNSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdOQURDQmlRS0IiICsKKyAgICJnUUNxUWtEdGtpRVhtVjhPNUVLNHkyWTlZeW9XTkR4NzB6NGZxRCs5bXV1ekpHdU01Tm92TWJ4aEJ5Y3VLSEYzIiArCisgICAiV0s2MGlYenJzQVlrQjFjOFZISGJjVUVGcXoyZkJkTEt5eHkvbllvaGxvOFRZU1ZwRWp0M3ZmYzBzZ21wNEZLVSIgKworICAgIlJESE8yejNyWlBIV3lzVjlMOVp2amVRcGl3YVlpcFU5ZXBkQm12Rm14UW1DRFFJREFRQUJvNEhXTUlIVE1CMEciICsKKyAgICJBMVVkRGdRV0JCVG5tMzJRS2VxUUMzOElRWFpPUVNQb1F5eXBBekNCb3dZRFZSMGpCSUdiTUlHWWdCVG5tMzJRIiArCisgICAiS2VxUUMzOElRWFpPUVNQb1F5eXBBNkY5cEhzd2VURUxNQWtHQTFVRUJoTUNRVTR4RURBT0JnTlZCQWdUQjBGdSIgKworICAgIlpISnZhV1F4RURBT0JnTlZCQW9UQjBGdVpISnZhV1F4RURBT0JnTlZCQXNUQjBGdVpISnZhV1F4RURBT0JnTlYiICsKKyAgICJCQU1UQjBGdVpISnZhV1F4SWpBZ0Jna3Foa2lHOXcwQkNRRVdFMkZ1WkhKdmFXUkFZVzVrY205cFpDNWpiMjJDIiArCisgICAiQVFBd0RBWURWUjBUQkFVd0F3RUIvekFOQmdrcWhraUc5dzBCQVFVRkFBT0JnUUFVbURBcFF1K3I1cmdsUzFXRiIgKworICAgIkJLWEUzUjJMYXNGdmJCd2R3MkUwTUFjMFRXcUxWVzkxVlc0VldNWDRyK0MrYzdyWnBZWFh0UnFGUkN1SS9jekwiICsKKyAgICIwZTFHYVVQL1dhNmJYQmNtMnU3SXYyZFZBYUFPRUxtRlNWVFplUjU3TG05bFQ5a1FMcDI0a21ObmRJc2lEVzNUIiArCisgICAiWFo0cFkvazJreHVuZ09LeDhiOHBHWUU5Qnc9PVxuIiArCisgICAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLSI7CisKKyAgICBwcml2YXRlIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGUgY2VydDsKKworICAgIHByaXZhdGUgamF2YXguc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGUgdGJ0X2NlcnQ7CisKKyAgICBwcml2YXRlIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGUgamF2YUNlcnQ7CisKKyAgICBwcml2YXRlIFByb3ZpZGVyIG15UHJvdmlkZXI7CisKKyAgICBwcml2YXRlIGphdmF4LnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlIGphdmF4Q2VydDsKKworICAgIHByaXZhdGUgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlIGphdmFTU0NlcnQ7CisKKyAgICBwcml2YXRlIFByb3ZpZGVyIG15U1NQcm92aWRlcjsKKworICAgIHByaXZhdGUgQ2VydGlmaWNhdGUgamF2YXhTU0NlcnQ7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYXNlNjRjZXJ0CisgICAgICAgICAgICAgICAgICAgIC5nZXRCeXRlcygpKTsKKyAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgICAgIHRoaXMuY2VydCA9IChqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlKSBjZgorICAgICAgICAgICAgICAgICAgICAuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShiYWlzKTsKKyAgICAgICAgICAgIHRoaXMudGJ0X2NlcnQgPSBYNTA5Q2VydGlmaWNhdGUuZ2V0SW5zdGFuY2UoY2VydC5nZXRFbmNvZGVkKCkpOworCisgICAgICAgICAgICAvLyBub24gc2VsZiBzaWduZWQgY2VydAorICAgICAgICAgICAgdGhpcy5qYXZhQ2VydCA9IChqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlKWNmCisgICAgICAgICAgICAgICAgICAgIC5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShzZWxmU2lnbmVkQ2VydC5nZXRCeXRlcygpKSk7CisgICAgICAgICAgICB0aGlzLmphdmF4Q2VydCA9IFg1MDlDZXJ0aWZpY2F0ZS5nZXRJbnN0YW5jZShqYXZhQ2VydC5nZXRFbmNvZGVkKCkpOworICAgICAgICAgICAgbXlQcm92aWRlciA9IGNmLmdldFByb3ZpZGVyKCk7CisgICAgICAgICAgICBTZWN1cml0eS5hZGRQcm92aWRlcihteVByb3ZpZGVyKTsKKworICAgICAgICAgICAgLy8gc2VsZiBzaWduZWQgY2VydAorICAgICAgICAgICAgdGhpcy5qYXZhU1NDZXJ0ID0gY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgIHNlbGZTaWduZWRDZXJ0LmdldEJ5dGVzKCkpKTsKKyAgICAgICAgICAgIHRoaXMuamF2YXhTU0NlcnQgPSBYNTA5Q2VydGlmaWNhdGUuZ2V0SW5zdGFuY2UoamF2YUNlcnQKKyAgICAgICAgICAgICAgICAgICAgLmdldEVuY29kZWQoKSk7CisgICAgICAgICAgICBteVNTUHJvdmlkZXIgPSBjZi5nZXRQcm92aWRlcigpOworICAgICAgICAgICAgU2VjdXJpdHkuYWRkUHJvdmlkZXIobXlTU1Byb3ZpZGVyKTsKKworICAgICAgICB9IGNhdGNoIChqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gVGhlIHJlcXVlc3RlZCBjZXJ0aWZpY2F0ZSB0eXBlIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICAgICAgICAvLyBUZXN0IHBhc3MuLgorICAgICAgICAgICAgdGhpcy5jZXJ0ID0gbnVsbDsKKyAgICAgICAgICAgIExvZ2dlci5nbG9iYWwud2FybmluZygiRXJyb3IgaW4gdGVzdCBzZXR1cDogQ2VydGlmaWNhdGUgdHlwZSBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgIH0gY2F0Y2ggKGphdmF4LnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gVGhlIHJlcXVlc3RlZCBjZXJ0aWZpY2F0ZSB0eXBlIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICAgICAgICAvLyBUZXN0IHBhc3MuLgorICAgICAgICAgICAgdGhpcy5jZXJ0ID0gbnVsbDsKKyAgICAgICAgICAgIExvZ2dlci5nbG9iYWwud2FybmluZygiRXJyb3IgaW4gdGVzdCBzZXR1cDogQ2VydGlmaWNhdGUgdHlwZSBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBYNTA5Q2VydGlmaWNhdGUoKSBjb25zdHJ1Y3RvciB0ZXN0aW5nLgorICAgICAqIHtAbGluayBYNTA5Q2VydGlmaWNhdGUjWDUwOUNlcnRpZmljYXRlKCkgfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDb25zdHJ1Y3RvcigpIHsKKyAgICAgICAgLy9EaXJlY3QgY29uc3RydWN0b3IsIGNoZWNrIGlmIGl0IHRocm93cyBhbiBleGNlcHRpb24KKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIGNlcnQgPSBuZXcgTXlDZXJ0aWZpY2F0ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGdldEluc3RhbmNlKElucHV0U3RyZWFtIGluU3RyZWFtKSBtZXRob2QgdGVzdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2UxKCkgeworICAgICAgICBpZiAodGhpcy5jZXJ0ID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIFRoZSByZXF1ZXN0ZWQgY2VydGlmaWNhdGUgdHlwZSBpcyBub3QgYXZhaWxhYmxlLgorICAgICAgICAgICAgLy8gVGVzdCBjYW4gbm90IGJlIGFwcGxpZWQuCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJhaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oY2VydAorICAgICAgICAgICAgICAgICAgICAuZ2V0RW5jb2RlZCgpKTsKKworICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlLmdldEluc3RhbmNlKGJhaXMpOworICAgICAgICB9IGNhdGNoIChqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gVGhlIHJlcXVlc3RlZCBjZXJ0aWZpY2F0ZSB0eXBlIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICAgICAgICAvLyBUZXN0IHBhc3MuLgorICAgICAgICB9CisKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS03NTYKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZS5nZXRJbnN0YW5jZSgoSW5wdXRTdHJlYW0pIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgQ2VydGlmaWNhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRJbnN0YW5jZShieXRlW10gY2VydERhdGEpIG1ldGhvZCB0ZXN0aW5nLgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2UyKCkgdGhyb3dzIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgYm9vbGVhbiBjZXJ0aWZpY2F0ZUV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgYyA9IG51bGw7CisgICAgICAgIGlmICh0aGlzLmNlcnQgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gVGhlIHJlcXVlc3RlZCBjZXJ0aWZpY2F0ZSB0eXBlIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICAgICAgICAvLyBUZXN0IGNhbiBub3QgYmUgYXBwbGllZC4KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYyA9IFg1MDlDZXJ0aWZpY2F0ZS5nZXRJbnN0YW5jZShjZXJ0LmdldEVuY29kZWQoKSk7CisgICAgICAgIH0gY2F0Y2ggKGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBUaGUgcmVxdWVzdGVkIGNlcnRpZmljYXRlIHR5cGUgaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgICAgICAgIC8vIFRlc3QgcGFzcy4uCisgICAgICAgICAgICBjZXJ0aWZpY2F0ZUV4Y2VwdGlvbiA9IHRydWU7CisKKyAgICAgICAgfQorCisgICAgICAgIGlmICghIGNlcnRpZmljYXRlRXhjZXB0aW9uKSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGMpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGMuZ2V0RW5jb2RlZCgpLGNlcnQuZ2V0RW5jb2RlZCgpICkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZS5nZXRJbnN0YW5jZShuZXcgYnl0ZVtdeyhieXRlKSAxIH0pOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTc1NgorICAgICAgICB0cnkgeworICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlLmdldEluc3RhbmNlKChieXRlW10pIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgQ2VydGlmaWNhdGVFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQ7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGNoZWNrVmFsaWRpdHkoKSBtZXRob2QgdGVzdGluZy4KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2hlY2tWYWxpZGl0eTEoKSB0aHJvd3MgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uLCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uLCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0aGlzLmNlcnQgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gVGhlIHJlcXVlc3RlZCBjZXJ0aWZpY2F0ZSB0eXBlIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICAgICAgICAvLyBUZXN0IGNhbiBub3QgYmUgYXBwbGllZC4KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBEYXRlIGRhdGUgPSBuZXcgRGF0ZSgpOworICAgICAgICBEYXRlIG5iX2RhdGUgPSB0YnRfY2VydC5nZXROb3RCZWZvcmUoKTsKKyAgICAgICAgRGF0ZSBuYV9kYXRlID0gdGJ0X2NlcnQuZ2V0Tm90QWZ0ZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRidF9jZXJ0LmNoZWNrVmFsaWRpdHkoKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24gZXhwZWN0ZWQiLCBkYXRlCisgICAgICAgICAgICAgICAgICAgIC5jb21wYXJlVG8obmFfZGF0ZSkgPiAwKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uIGV4cGVjdGVkIiwgZGF0ZQorICAgICAgICAgICAgICAgICAgICAuY29tcGFyZVRvKG5iX2RhdGUpIDwgMCk7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJVbmV4cGVjdGVkIENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbiB3YXMgdGhyb3duIiwKKyAgICAgICAgICAgICAgICAgICAgZGF0ZS5jb21wYXJlVG8obmFfZGF0ZSkgPiAwKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJVbmV4cGVjdGVkIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24gd2FzIHRocm93biIsCisgICAgICAgICAgICAgICAgICAgIGRhdGUuY29tcGFyZVRvKG5iX2RhdGUpIDwgMCk7CisgICAgICAgIH0KKworICAgICAgIHRyeSB7CisgICAgICAgdGJ0X2NlcnQuY2hlY2tWYWxpZGl0eSgpOworICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIG9rCisgICAgICAgfQorCisgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnQuY2hlY2tWYWxpZGl0eSgpOworICAgICAgICB9IGNhdGNoIChqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGNoZWNrVmFsaWRpdHkoRGF0ZSBkYXRlKSBtZXRob2QgdGVzdGluZy4KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDaGVja1ZhbGlkaXR5MigpIHRocm93cyBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24geworICAgICAgICBpZiAodGhpcy5jZXJ0ID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIFRoZSByZXF1ZXN0ZWQgY2VydGlmaWNhdGUgdHlwZSBpcyBub3QgYXZhaWxhYmxlLgorICAgICAgICAgICAgLy8gVGVzdCBjYW4gbm90IGJlIGFwcGxpZWQuCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgRGF0ZVtdIGRhdGUgPSBuZXcgRGF0ZVs0XTsKKyAgICAgICAgQ2FsZW5kYXIgY2FsZW5kYXIgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNhbGVuZGFyLnNldChpICogNTAsIENhbGVuZGFyLkpBTlVBUlksIDEpOworICAgICAgICAgICAgZGF0ZVtpXSA9IGNhbGVuZGFyLmdldFRpbWUoKTsKKyAgICAgICAgfQorICAgICAgICBEYXRlIG5iX2RhdGUgPSB0YnRfY2VydC5nZXROb3RCZWZvcmUoKTsKKyAgICAgICAgRGF0ZSBuYV9kYXRlID0gdGJ0X2NlcnQuZ2V0Tm90QWZ0ZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkYXRlLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRidF9jZXJ0LmNoZWNrVmFsaWRpdHkoZGF0ZVtpXSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIkNlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbiBleHBlY3RlZCIsIGRhdGVbaV0KKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb21wYXJlVG8obmFfZGF0ZSkgPiAwKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZSgiQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbiBleHBlY3RlZCIsIGRhdGVbaV0KKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb21wYXJlVG8obmJfZGF0ZSkgPCAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVW5leHBlY3RlZCBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24gd2FzIHRocm93biIsCisgICAgICAgICAgICAgICAgICAgICAgICBkYXRlW2ldLmNvbXBhcmVUbyhuYV9kYXRlKSA+IDApOworICAgICAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVW5leHBlY3RlZCBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIndhcyB0aHJvd24iLCBkYXRlW2ldLmNvbXBhcmVUbyhuYl9kYXRlKSA8IDApOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQ2FsZW5kYXIgY2FsZW5kYXJOb3cgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0YnRfY2VydC5jaGVja1ZhbGlkaXR5KGNhbGVuZGFyTm93LmdldFRpbWUoKSk7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKworICAgICAgICBDYWxlbmRhciBjYWxlbmRhclBhc3QgPSBHcmVnb3JpYW5DYWxlbmRhci5nZXRJbnN0YW5jZSgpOworICAgICAgICBjYWxlbmRhclBhc3QuY2xlYXIoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGJ0X2NlcnQuY2hlY2tWYWxpZGl0eShjYWxlbmRhclBhc3QuZ2V0VGltZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvL29rCisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGdldFZlcnNpb24oKSBtZXRob2QgdGVzdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VmVyc2lvbigpIHsKKyAgICAgICAgaWYgKHRoaXMuY2VydCA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBUaGUgcmVxdWVzdGVkIGNlcnRpZmljYXRlIHR5cGUgaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgICAgICAgIC8vIFRlc3QgY2FuIG5vdCBiZSBhcHBsaWVkLgorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiVGhlIHZlcnNpb24gaXMgbm90IGNvcnJlY3QuIiwgdGJ0X2NlcnQuZ2V0VmVyc2lvbigpLCAyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRTZXJpYWxOdW1iZXIoKSBtZXRob2QgdGVzdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2VyaWFsTnVtYmVyKCkgeworICAgICAgICBpZiAodGhpcy5jZXJ0ID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIFRoZSByZXF1ZXN0ZWQgY2VydGlmaWNhdGUgdHlwZSBpcyBub3QgYXZhaWxhYmxlLgorICAgICAgICAgICAgLy8gVGVzdCBjYW4gbm90IGJlIGFwcGxpZWQuCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgc2VyaWFsIG51bWJlciBpcyBub3QgY29ycmVjdC4iLCB0YnRfY2VydAorICAgICAgICAgICAgICAgIC5nZXRTZXJpYWxOdW1iZXIoKSwgY2VydC5nZXRTZXJpYWxOdW1iZXIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0SXNzdWVyRE4oKSBtZXRob2QgdGVzdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SXNzdWVyRE4oKSB7CisgICAgICAgIGlmICh0aGlzLmNlcnQgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gVGhlIHJlcXVlc3RlZCBjZXJ0aWZpY2F0ZSB0eXBlIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICAgICAgICAvLyBUZXN0IGNhbiBub3QgYmUgYXBwbGllZC4KKyAgICAgICAgICAgIExvZ2dlci5nbG9iYWwud2FybmluZygidGVzdEdldElzc3VlckROOiBlcnJvciBpbiB0ZXN0IHNldHVwLiIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiVGhlIGlzc3VlciBETiBpcyBub3QgY29ycmVjdC4iLCB0YnRfY2VydC5nZXRJc3N1ZXJETigpLAorICAgICAgICAgICAgICAgIGNlcnQuZ2V0SXNzdWVyRE4oKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0U3ViamVjdEROKCkgbWV0aG9kIHRlc3RpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldFN1YmplY3RETigpIHsKKyAgICAgICAgaWYgKHRoaXMuY2VydCA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBUaGUgcmVxdWVzdGVkIGNlcnRpZmljYXRlIHR5cGUgaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgICAgICAgIC8vIFRlc3QgY2FuIG5vdCBiZSBhcHBsaWVkLgorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiVGhlIHN1YmplY3QgRE4gaXMgbm90IGNvcnJlY3QuIiwgdGJ0X2NlcnQuZ2V0U3ViamVjdEROKCksCisgICAgICAgICAgICAgICAgY2VydC5nZXRTdWJqZWN0RE4oKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0Tm90QmVmb3JlKCkgbWV0aG9kIHRlc3RpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldE5vdEJlZm9yZSgpIHsKKyAgICAgICAgaWYgKHRoaXMuY2VydCA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBUaGUgcmVxdWVzdGVkIGNlcnRpZmljYXRlIHR5cGUgaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgICAgICAgIC8vIFRlc3QgY2FuIG5vdCBiZSBhcHBsaWVkLgorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiVGhlIE5vdEJlZm9yZSBkYXRlIGlzIG5vdCBjb3JyZWN0LiIsIHRidF9jZXJ0CisgICAgICAgICAgICAgICAgLmdldE5vdEJlZm9yZSgpLCBjZXJ0LmdldE5vdEJlZm9yZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXROb3RBZnRlcigpIG1ldGhvZCB0ZXN0aW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXROb3RBZnRlcigpIHsKKyAgICAgICAgaWYgKHRoaXMuY2VydCA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBUaGUgcmVxdWVzdGVkIGNlcnRpZmljYXRlIHR5cGUgaXMgbm90IGF2YWlsYWJsZS4KKyAgICAgICAgICAgIC8vIFRlc3QgY2FuIG5vdCBiZSBhcHBsaWVkLgorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiVGhlIE5vdEFmdGVyIGRhdGUgaXMgbm90IGNvcnJlY3QuIiwgdGJ0X2NlcnQKKyAgICAgICAgICAgICAgICAuZ2V0Tm90QWZ0ZXIoKSwgY2VydC5nZXROb3RBZnRlcigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRTaWdBbGdOYW1lKCkgbWV0aG9kIHRlc3RpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldFNpZ0FsZ05hbWUoKSB7CisgICAgICAgIGlmICh0aGlzLmNlcnQgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gVGhlIHJlcXVlc3RlZCBjZXJ0aWZpY2F0ZSB0eXBlIGlzIG5vdCBhdmFpbGFibGUuCisgICAgICAgICAgICAvLyBUZXN0IGNhbiBub3QgYmUgYXBwbGllZC4KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSBuYW1lIG9mIHNpZ25hdHVyZSBhbGdvcml0aG0gaXMgbm90IGNvcnJlY3QuIiwKKyAgICAgICAgICAgICAgICB0YnRfY2VydC5nZXRTaWdBbGdOYW1lKCksIGNlcnQuZ2V0U2lnQWxnTmFtZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRTaWdBbGdPSUQoKSBtZXRob2QgdGVzdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2lnQWxnT0lEKCkgeworICAgICAgICBpZiAodGhpcy5jZXJ0ID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIFRoZSByZXF1ZXN0ZWQgY2VydGlmaWNhdGUgdHlwZSBpcyBub3QgYXZhaWxhYmxlLgorICAgICAgICAgICAgLy8gVGVzdCBjYW4gbm90IGJlIGFwcGxpZWQuCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgbmFtZSBvZiBPSUQgb2Ygc2lnbmF0dXJlIGFsZ29yaXRobSBpcyBub3QgY29ycmVjdC4iLAorICAgICAgICAgICAgICAgIHRidF9jZXJ0LmdldFNpZ0FsZ09JRCgpLCBjZXJ0LmdldFNpZ0FsZ09JRCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRTaWdBbGdQYXJhbXMoKSBtZXRob2QgdGVzdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2lnQWxnUGFyYW1zKCkgeworICAgICAgICBpZiAodGhpcy5jZXJ0ID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vIFRoZSByZXF1ZXN0ZWQgY2VydGlmaWNhdGUgdHlwZSBpcyBub3QgYXZhaWxhYmxlLgorICAgICAgICAgICAgLy8gVGVzdCBjYW4gbm90IGJlIGFwcGxpZWQuCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGJ5dGUgYXJyYXkgd2l0aCBlbmNvZGVkIGFsZ29yaXRobSBwYXJhbWV0ZXJzICIKKyAgICAgICAgICAgICAgICArICJpcyBub3QgY29ycmVjdC4iLCBBcnJheXMuZXF1YWxzKHRidF9jZXJ0LmdldFNpZ0FsZ1BhcmFtcygpLAorICAgICAgICAgICAgICAgIGNlcnQuZ2V0U2lnQWxnUGFyYW1zKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3R1YiBjbGFzcyB1c2VkIGZvciB0ZXN0aW5nIG9mIG5vbiBhYnN0cmFjdCBtZXRob2RzLgorICAgICAqLworICAgIHByaXZhdGUgY2xhc3MgTXlDZXJ0aWZpY2F0ZSBleHRlbmRzIFg1MDlDZXJ0aWZpY2F0ZSB7CisKKyAgICAgICAgcHVibGljIE15Q2VydGlmaWNhdGUoKSB7CisgICAgICAgICAgICBzdXBlcigpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrVmFsaWRpdHkoKSB0aHJvd3MgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrVmFsaWRpdHkoRGF0ZSBhcmcwKQorICAgICAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFByaW5jaXBhbCBnZXRJc3N1ZXJETigpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBEYXRlIGdldE5vdEFmdGVyKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIERhdGUgZ2V0Tm90QmVmb3JlKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0U2VyaWFsTnVtYmVyKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRTaWdBbGdOYW1lKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRTaWdBbGdPSUQoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldFNpZ0FsZ1BhcmFtcygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0U3ViamVjdEROKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBnZXRWZXJzaW9uKCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgdGhyb3dzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFB1YmxpY0tleSBnZXRQdWJsaWNLZXkoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgdmVyaWZ5KFB1YmxpY0tleSBrZXkpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIEludmFsaWRLZXlFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgdmVyaWZ5KFB1YmxpY0tleSBrZXksIFN0cmluZyBzaWdQcm92aWRlcikKKyAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBJbnZhbGlkS2V5RXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGNsYXNzIE15TW9kaWZpYWJsZVB1YmxpY0tleSBpbXBsZW1lbnRzIFB1YmxpY0tleSB7CisKKyAgICAgICAgcHJpdmF0ZSBQdWJsaWNLZXkga2V5OworICAgICAgICBwcml2YXRlIGJvb2xlYW4gbW9kaWZpZWRBbGdvOworICAgICAgICBwcml2YXRlIFN0cmluZyBhbGdvOworICAgICAgICBwcml2YXRlIFN0cmluZyBmb3JtYXQ7CisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBtb2RpZmllZEZvcm1hdDsKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIG1vZGlmaWVkRW5jb2Rpbmc7CisgICAgICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kaW5nOworCisgICAgICAgIHB1YmxpYyBNeU1vZGlmaWFibGVQdWJsaWNLZXkoUHVibGljS2V5IGspIHsKKyAgICAgICAgICAgIHN1cGVyKCk7CisgICAgICAgICAgICB0aGlzLmtleSA9IGs7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgIGlmIChtb2RpZmllZEFsZ28pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gYWxnbzsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGtleS5nZXRBbGdvcml0aG0oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgaWYgKG1vZGlmaWVkRm9ybWF0KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0OworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4ga2V5LmdldEZvcm1hdCgpOworICAgICAgICAgICAgfQorCisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICBpZiAobW9kaWZpZWRFbmNvZGluZykgeworICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY29kaW5nOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4ga2V5LmdldEVuY29kZWQoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGxvbmcgZ2V0U2VyVmVyVUlEKCkgeworICAgICAgICAgICAgcmV0dXJuIGtleS5zZXJpYWxWZXJzaW9uVUlEOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0QWxnb3JpdGhtKFN0cmluZyBteUFsZ28pIHsKKyAgICAgICAgICAgIG1vZGlmaWVkQWxnbyA9IHRydWU7CisgICAgICAgICAgICB0aGlzLmFsZ28gPSBteUFsZ287CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXRGb3JtYXQoU3RyaW5nIG15Rm9ybWF0KSB7CisgICAgICAgICAgICBtb2RpZmllZEZvcm1hdCA9IHRydWU7CisgICAgICAgICAgICBmb3JtYXQgPSBteUZvcm1hdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nKGJ5dGVbXSBteUVuY29kZWQpIHsKKyAgICAgICAgICAgIG1vZGlmaWVkRW5jb2RpbmcgPSB0cnVlOworICAgICAgICAgICAgZW5jb2RpbmcgPSBteUVuY29kZWQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24KKyAgICAgKiB7QGxpbmsgQ2VydGlmaWNhdGUjZ2V0RW5jb2RlZCgpfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRFbmNvZGVkKCkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uLCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICAvLyBjZXJ0ID0gREVSIGVuY29kaW5nIG9mIHRoZSBBU04xLjAgc3RydWN0dXJlCisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhjZXJ0LmdldEVuY29kZWQoKSwgdGJ0X2NlcnQuZ2V0RW5jb2RlZCgpKSk7CisgICAgICAgIGFzc2VydEZhbHNlKEFycmF5cy5lcXVhbHMoamF2YXhDZXJ0LmdldEVuY29kZWQoKSwgdGJ0X2NlcnQuZ2V0RW5jb2RlZCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0BsaW5rIENlcnRpZmljYXRlI2dldFB1YmxpY0tleSgpfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQdWJsaWNLZXkoKSB7CisgICAgICAgUHVibGljS2V5IGtleSA9IGphdmF4Q2VydC5nZXRQdWJsaWNLZXkoKTsKKyAgICAgICBhc3NlcnROb3ROdWxsKGtleSk7CisgICAgICAgYXNzZXJ0RXF1YWxzKGphdmF4Q2VydC5nZXRQdWJsaWNLZXkoKSwgamF2YUNlcnQuZ2V0UHVibGljS2V5KCkpOworICAgICAgIGFzc2VydEVxdWFscyhrZXkuZ2V0QWxnb3JpdGhtKCksIlJTQSIpOworCisgICAgICAga2V5ID0gamF2YXhTU0NlcnQuZ2V0UHVibGljS2V5KCk7CisgICAgICAgYXNzZXJ0Tm90TnVsbChrZXkpOworICAgICAgIGFzc2VydEVxdWFscyhrZXkuZ2V0QWxnb3JpdGhtKCksIlJTQSIpOworCisgICAgICAgLy9hc3NlcnRUcnVlKG15U1NQcm92aWRlci5jb250YWluc0tleShrZXkpKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uCisgICAgICogQHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbgorICAgICAqIHtAbGluayBDZXJ0aWZpY2F0ZSN2ZXJpZnkoUHVibGljS2V5KX0KKyAgICAgKi8KKyAgICBAU2lkZUVmZmVjdCgiRGVzdHJveXMgTUQ1IHByb3ZpZGVyLCBodXJ0cyBzdWNjZWVkaW5nIHRlc3RzIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmVyaWZ5UHVibGljS2V5KCkgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgU2lnbmF0dXJlRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisKKyAgICAgICAgLy8gUHJlY29uZGl0aW9ucworICAgICAgICBhc3NlcnROb3ROdWxsKGphdmF4Q2VydC5nZXRQdWJsaWNLZXkoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoamF2YXhTU0NlcnQuZ2V0UHVibGljS2V5KCkpOworICAgICAgICAvL3ByZWNvbmRpdGlvbiBmb3Igc2VsZiBzaWduZWQgY2VydGlmaWNhdGVzCisgICAgICAgIC8qYXNzZXJ0RXF1YWxzKCgoWDUwOUNlcnRpZmljYXRlKSBqYXZheFNTQ2VydCkuZ2V0SXNzdWVyRE4oKS5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgKChYNTA5Q2VydGlmaWNhdGUpIGphdmF4U1NDZXJ0KS5nZXRTdWJqZWN0RE4oKSk7Ki8KKworICAgICAgICAvLyBtdXN0IGFsd2F5cyBldmFsdWF0ZSB0cnVlIGZvciBzZWxmIHNpZ25lZAorICAgICAgICAvLyBoZXJlIG5vdCBzZWxmIHNpZ25lZDoKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGphdmF4Q2VydC52ZXJpZnkoamF2YXhDZXJ0LmdldFB1YmxpY0tleSgpKTsKKyAgICAgICAgfSBjYXRjaCAoU2lnbmF0dXJlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICBQdWJsaWNLZXkgayA9IGphdmF4Q2VydC5nZXRQdWJsaWNLZXkoKTsKKworICAgICAgICBNeU1vZGlmaWFibGVQdWJsaWNLZXkgY2hhbmdlZEVuY29kaW5nID0gbmV3IE15TW9kaWZpYWJsZVB1YmxpY0tleShrKTsKKyAgICAgICAgY2hhbmdlZEVuY29kaW5nCisgICAgICAgICAgICAgICAgLnNldEVuY29kaW5nKG5ldyBieXRlW2phdmF4Q2VydC5nZXRFbmNvZGVkKCkubGVuZ3RoIC0gMV0pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBqYXZheENlcnQudmVyaWZ5KHRidF9jZXJ0LmdldFB1YmxpY0tleSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgamF2YXhDZXJ0LnZlcmlmeShudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgamF2YXhDZXJ0LnZlcmlmeShjaGFuZ2VkRW5jb2RpbmcpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgLy8gZm9sbG93aW5nIHRlc3QgZG9lc24ndCB3b3JrIGJlY2F1c2UgdGhlIGFsZ29yaXRobSBpcyBkZXJpdmVkIGZyb20KKyAgICAgICAgLy8gc29tZXdoZXJlIGVsc2UuCisKKyAgICAgICAgLy8gTXlNb2RpZmlhYmxlUHVibGljS2V5IGNoYW5nZWRBbGdvID0gbmV3IE15TW9kaWZpYWJsZVB1YmxpY0tleShrKTsKKyAgICAgICAgLy8gY2hhbmdlZEFsZ28uc2V0QWxnb3JpdGhtKCJNRDV3aXRoQmxhIik7CisKKyAgICAgICAgLy8gdHJ5IHsKKyAgICAgICAgLy8gICAgIGphdmF4Q2VydC52ZXJpZnkoY2hhbmdlZEFsZ28pOworICAgICAgICAvLyAgICAgZmFpbCgiRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIC8vIH0gY2F0Y2ggKFNpZ25hdHVyZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vICAgICAvLyBvaworICAgICAgICAvLyB9CisKKyAgICAgICAgLy8gU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIobXlTU1Byb3ZpZGVyLmdldE5hbWUoKSk7CisKKyAgICAgICAgLy8gdHJ5IHsKKyAgICAgICAgLy8gICAgIGphdmF4U1NDZXJ0LnZlcmlmeShqYXZheFNTQ2VydC5nZXRQdWJsaWNLZXkoKSk7CisgICAgICAgIC8vIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gICAgIC8vIG9rCisgICAgICAgIC8vIH0KKworICAgICAgICAvLyBTZWN1cml0eS5hZGRQcm92aWRlcihteVNTUHJvdmlkZXIpOworCisgICAgICAgIC8vIG11c3QgYWx3YXlzIGV2YWx1YXRlIHRydWUgZm9yIHNlbGYgc2lnbmVkCisgICAgICAgIC8vIGphdmF4U1NDZXJ0LnZlcmlmeShqYXZheFNTQ2VydC5nZXRQdWJsaWNLZXkoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uCisgICAgICoge0BsaW5rIENlcnRpZmljYXRlI3ZlcmlmeShQdWJsaWNLZXksIFN0cmluZyl9CisgICAgICovCisgICAgQFNpZGVFZmZlY3QoIkRlc3Ryb3lzIE1ENSBwcm92aWRlciwgaHVydHMgc3VjY2VlZGluZyB0ZXN0cyIpCisgICAgcHVibGljIHZvaWQgdGVzdFZlcmlmeVB1YmxpY0tleVN0cmluZygpIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwgU2lnbmF0dXJlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgamF2YXhDZXJ0LnZlcmlmeShqYXZheENlcnQuZ2V0UHVibGljS2V5KCksIG15UHJvdmlkZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICAvLyBteVByb3ZpZGVyLmdldFNlcnZpY2UodHlwZSwgYWxnb3JpdGhtKQorCisgICAgICAgIFNlY3VyaXR5LnJlbW92ZVByb3ZpZGVyKG15UHJvdmlkZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGphdmF4Q2VydC52ZXJpZnkoamF2YXhDZXJ0LmdldFB1YmxpY0tleSgpLCBteVByb3ZpZGVyLmdldE5hbWUoKSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKyAgICAgICAgU2VjdXJpdHkuYWRkUHJvdmlkZXIobXlQcm92aWRlcik7CisKKyAgICAgICAgUHJvdmlkZXJbXSBwcm92aWRlcnMgPSBTZWN1cml0eS5nZXRQcm92aWRlcnMoIlNpZ25hdHVyZS5NRDV3aXRoUlNBIik7CisgICAgICAgIGlmIChwcm92aWRlcnMgPT0gbnVsbCB8fCBwcm92aWRlcnMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIGZhaWwoIm5vIFByb3ZpZGVyIGZvciBTaWduYXR1cmUuTUQ1d2l0aFJTQSIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLy8gc2VsZiBzaWduZWQgY2VydDogc2hvdWxkIHZlcmlmeSB3aXRoIHByb3ZpZGVyCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBqYXZheFNTQ2VydC52ZXJpZnkoamF2YXhTU0NlcnQuZ2V0UHVibGljS2V5KCksCisgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyc1swXS5nZXROYW1lKCkpOworICAgICAgICB9IGNhdGNoIChTaWduYXR1cmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiYmx1Iik7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgVGVzdCBzdWl0ZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBUZXN0U3VpdGUoWDUwOUNlcnRpZmljYXRlVGVzdC5jbGFzcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC94bWwvcGFyc2Vycy9Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC94bWwvcGFyc2Vycy9Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdkNzk1NjAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3htbC9wYXJzZXJzL0RvY3VtZW50QnVpbGRlckZhY3RvcnlUZXN0LmphdmEKQEAgLTAsMCArMSw5NzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLmFwaS5qYXZheC54bWwucGFyc2VyczsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CitpbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbjsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGRiZjsKKworICAgIExpc3Q8U3RyaW5nPiBjZGF0YUVsZW1lbnRzOworCisgICAgTGlzdDxTdHJpbmc+IHRleHRFbGVtZW50czsKKworICAgIExpc3Q8U3RyaW5nPiBjb21tZW50RWxlbWVudHM7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBkYmYgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisKKyAgICAgICAgY2RhdGFFbGVtZW50cyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICB0ZXh0RWxlbWVudHMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgY29tbWVudEVsZW1lbnRzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZGJmID0gbnVsbDsKKyAgICAgICAgY2RhdGFFbGVtZW50cyA9IG51bGw7CisgICAgICAgIHRleHRFbGVtZW50cyA9IG51bGw7CisgICAgICAgIGNvbW1lbnRFbGVtZW50cyA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSNEb2N1bWVudEJ1aWxkZXJGYWN0b3J5KCkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Q2hpbGQoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSNnZXRBdHRyaWJ1dGUoU3RyaW5nKS4KKyAgICAgKi8KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0QXR0cmlidXRlTGphdmFfbGFuZ19TdHJpbmcoKSB7CisvLyAgICAgICAgU3RyaW5nW10gYXR0cmlidXRlcyA9IHsKKy8vICAgICAgICAgICAgICAgICJodHRwOi8vamF2YS5zdW4uY29tL3htbC9qYXhwL3Byb3BlcnRpZXMvc2NoZW1hTGFuZ3VhZ2UiLAorLy8gICAgICAgICAgICAgICAgImh0dHA6Ly9qYXZhLnN1bi5jb20veG1sL2pheHAvcHJvcGVydGllcy9zY2hlbWFTb3VyY2UiIH07CisvLyAgICAgICAgT2JqZWN0W10gdmFsdWVzID0geyAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiLCAic291cmNlIiB9OworLy8KKy8vICAgICAgICB0cnkgeworLy8gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGF0dHJpYnV0ZXMubGVuZ3RoOyBpKyspIHsKKy8vICAgICAgICAgICAgICAgIGRiZi5zZXRBdHRyaWJ1dGUoYXR0cmlidXRlc1tpXSwgdmFsdWVzW2ldKTsKKy8vICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyh2YWx1ZXNbaV0sIGRiZi5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlc1tpXSkpOworLy8gICAgICAgICAgICB9CisvLyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKy8vICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworLy8gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisvLyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKy8vICAgICAgICB9CisvLworLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXR0cmlidXRlcy5sZW5ndGg7IGkrKykgeworLy8gICAgICAgICAgICAgICAgZGJmLnNldEF0dHJpYnV0ZShudWxsLCBudWxsKTsKKy8vICAgICAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisvLyAgICAgICAgICAgIH0KKy8vICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisvLyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisvLyAgICAgICAgfQorLy8KKy8vICAgICAgICBTdHJpbmdbXSBiYWRBdHRyaWJ1dGVzID0geyJiYWQxIiwgImJhZDIiLCAiIn07CisvLyAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBiYWRBdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7CisvLyAgICAgICAgICAgICAgICBkYmYuZ2V0QXR0cmlidXRlKGJhZEF0dHJpYnV0ZXNbaV0pOworLy8gICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisvLyAgICAgICAgICAgIH0KKy8vICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworLy8gICAgICAgICAgICAvLyBleHBlY3RlZAorLy8gICAgICAgIH0KKy8vICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3RvcnkjZ2V0RmVhdHVyZShTdHJpbmcpLgorICAgICAqLworLy8gVE9ETyBGYWlscyBvbiBKREsuIFdoeT8KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RmVhdHVyZUxqYXZhX2xhbmdfU3RyaW5nKCkgeworLy8gICAgICAgIFN0cmluZ1tdIGZlYXR1cmVzID0geyAiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXMiLAorLy8gICAgICAgICAgICAgICAgImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy92YWxpZGF0aW9uIiwKKy8vICAgICAgICAgICAgICAgICJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvZXh0ZXJuYWwtZ2VuZXJhbC1lbnRpdGllcyIgfTsKKy8vICAgICAgICB0cnkgeworLy8gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZlYXR1cmVzLmxlbmd0aDsgaSsrKSB7CisvLyAgICAgICAgICAgICAgICBkYmYuc2V0RmVhdHVyZShmZWF0dXJlc1tpXSwgdHJ1ZSk7CisvLyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGRiZi5nZXRGZWF0dXJlKGZlYXR1cmVzW2ldKSk7CisvLyAgICAgICAgICAgIH0KKy8vICAgICAgICB9IGNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKKy8vICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisvLyAgICAgICAgfQorLy8KKy8vICAgICAgICB0cnkgeworLy8gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZlYXR1cmVzLmxlbmd0aDsgaSsrKSB7CisvLyAgICAgICAgICAgICAgICBkYmYuc2V0RmVhdHVyZShmZWF0dXJlc1tpXSwgZmFsc2UpOworLy8gICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZGJmLmdldEZlYXR1cmUoZmVhdHVyZXNbaV0pKTsKKy8vICAgICAgICAgICAgfQorLy8gICAgICAgIH0gY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgeworLy8gICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKy8vICAgICAgICB9CisvLworLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmVhdHVyZXMubGVuZ3RoOyBpKyspIHsKKy8vICAgICAgICAgICAgICAgIGRiZi5zZXRGZWF0dXJlKG51bGwsIGZhbHNlKTsKKy8vICAgICAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisvLyAgICAgICAgICAgIH0KKy8vICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisvLyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisvLyAgICAgICAgfSBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisvLyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisvLyAgICAgICAgfQorLy8KKy8vICAgICAgICBTdHJpbmdbXSBiYWRGZWF0dXJlcyA9IHsiYmFkMSIsICJiYWQyIiwgIiJ9OworLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYmFkRmVhdHVyZXMubGVuZ3RoOyBpKyspIHsKKy8vICAgICAgICAgICAgICAgIGRiZi5nZXRGZWF0dXJlKGJhZEZlYXR1cmVzW2ldKTsKKy8vICAgICAgICAgICAgICAgIGZhaWwoIlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKy8vICAgICAgICAgICAgfQorLy8gICAgICAgIH0gY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgeworLy8gICAgICAgICAgICAvLyBleHBlY3RlZAorLy8gICAgICAgIH0KKy8vCisvLyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5I2dldFNjaGVtYSgpLgorICAgICAqICBUQkQgZ2V0U2NoZW1hcygpIElTIE5PVCBTVVBQT1JURUQKKyAgICAgKi8KKy8qICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0U2NoZW1hKCkgeworICAgICAgICBhc3NlcnROdWxsKGRiZi5nZXRTY2hlbWEoKSk7CisgICAgICAgIFNjaGVtYUZhY3Rvcnkgc2YgPQorICAgICAgICAgICAgU2NoZW1hRmFjdG9yeS5uZXdJbnN0YW5jZShYTUxDb25zdGFudHMuVzNDX1hNTF9TQ0hFTUFfTlNfVVJJKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNjaGVtYSBzY2hlbWEgPSBzZi5uZXdTY2hlbWEoKTsKKyAgICAgICAgICAgIGRiZi5zZXRTY2hlbWEoc2NoZW1hKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZGJmLmdldFNjaGVtYSgpKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIHNheCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIHNheC50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAqLworCisgICAgLyoqCisgICAgICogamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSNpc0NvYWxlc2NpbmcoKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzQ29hbGVzY2luZygpIHsKKyAgICAgICAgZGJmLnNldENvYWxlc2NpbmcodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoZGJmLmlzQ29hbGVzY2luZygpKTsKKworICAgICAgICBkYmYuc2V0Q29hbGVzY2luZyhmYWxzZSk7CisgICAgICAgIGFzc2VydEZhbHNlKGRiZi5pc0NvYWxlc2NpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSNpc0V4cGFuZEVudGl0eVJlZmVyZW5jZXMoKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzRXhwYW5kRW50aXR5UmVmZXJlbmNlcygpIHsKKyAgICAgICAgZGJmLnNldEV4cGFuZEVudGl0eVJlZmVyZW5jZXModHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoZGJmLmlzRXhwYW5kRW50aXR5UmVmZXJlbmNlcygpKTsKKworICAgICAgICBkYmYuc2V0RXhwYW5kRW50aXR5UmVmZXJlbmNlcyhmYWxzZSk7CisgICAgICAgIGFzc2VydEZhbHNlKGRiZi5pc0V4cGFuZEVudGl0eVJlZmVyZW5jZXMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSNpc0lnbm9yaW5nQ29tbWVudHMoKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzSWdub3JpbmdDb21tZW50cygpIHsKKyAgICAgICAgZGJmLnNldElnbm9yaW5nQ29tbWVudHModHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoZGJmLmlzSWdub3JpbmdDb21tZW50cygpKTsKKworICAgICAgICBkYmYuc2V0SWdub3JpbmdDb21tZW50cyhmYWxzZSk7CisgICAgICAgIGFzc2VydEZhbHNlKGRiZi5pc0lnbm9yaW5nQ29tbWVudHMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSNpc0lnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKCkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pc0lnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKCkgeworICAgICAgICBkYmYuc2V0SWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoZGJmLmlzSWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoKSk7CisKKyAgICAgICAgZGJmLnNldElnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZGJmLmlzSWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSNpc05hbWVzcGFjZUF3YXJlKCkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9pc05hbWVzcGFjZUF3YXJlKCkgeworICAgICAgICBkYmYuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoZGJmLmlzTmFtZXNwYWNlQXdhcmUoKSk7CisKKyAgICAgICAgZGJmLnNldE5hbWVzcGFjZUF3YXJlKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZGJmLmlzTmFtZXNwYWNlQXdhcmUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRJc1ZhbGlkYXRpbmcoKSB7CisgICAgICAgIGRiZi5zZXRWYWxpZGF0aW5nKHRydWUpOworICAgICAgICBhc3NlcnRUcnVlKGRiZi5pc1ZhbGlkYXRpbmcoKSk7CisKKyAgICAgICAgZGJmLnNldFZhbGlkYXRpbmcoZmFsc2UpOworICAgICAgICBhc3NlcnRGYWxzZShkYmYuaXNWYWxpZGF0aW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfaXNTZXRYSW5jbHVkZUF3YXJlKCkgeworICAgICAgICBkYmYuc2V0WEluY2x1ZGVBd2FyZSh0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShkYmYuaXNYSW5jbHVkZUF3YXJlKCkpOworCisgICAgICAgIGRiZi5zZXRYSW5jbHVkZUF3YXJlKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZGJmLmlzWEluY2x1ZGVBd2FyZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5I25ld0luc3RhbmNlKCkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9uZXdJbnN0YW5jZSgpIHsKKyAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBjYXNlIDE6IFRyeSB0byBvYnRhaW4gYSBuZXcgaW5zdGFuY2Ugb2YgZmFjdG9yeSBieSBkZWZhdWx0LgorICAgICAgICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBkYmYgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGRiZik7CisKKyAgICAgICAgICAgIC8vIGNhc2UgMjogVHJ5IHRvIGNyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiBmYWN0b3J5IHVzaW5nCisgICAgICAgICAgICAvLyBwcm9wZXJ0eSBEQVRBVFlQRUZBQ1RPUllfUFJPUEVSVFkKKyAgICAgICAgICAgIGNsYXNzTmFtZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSIpOworICAgICAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IiwKKyAgICAgICAgICAgICAgICAgICAgIm9yZy5hcGFjaGUuaGFybW9ueS54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbCIpOworCisgICAgICAgICAgICBkYmYgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGRiZik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGRiZiBpbnN0YW5jZW9mIG9yZy5hcGFjaGUuaGFybW9ueS54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbCk7CisKKyAgICAgICAgICAgIC8vIGNhc2UgMzogVHJ5IHRvIGNyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiBmYWN0b3J5IHVzaW5nIFByb3BlcnR5CisgICAgICAgICAgICBTdHJpbmcga2V5VmFsdWVQYWlyID0gImphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3RvcnkiCisgICAgICAgICAgICAgICAgICAgICsgIj0iICsgIm9yZy5hcGFjaGUuaGFybW9ueS54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbCI7CisgICAgICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oa2V5VmFsdWVQYWlyCisgICAgICAgICAgICAgICAgICAgIC5nZXRCeXRlcygpKTsKKyAgICAgICAgICAgIFByb3BlcnRpZXMgcHJvcCA9IFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwcm9wLmxvYWQoYmlzKTsKKyAgICAgICAgICAgIGRiZiA9IERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZGJmKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZGJmIGluc3RhbmNlb2Ygb3JnLmFwYWNoZS5oYXJtb255LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3RvcnlJbXBsKTsKKworICAgICAgICAgICAgLy8gY2FzZSA0OiBDaGVjayBGYWN0b3J5Q29uZmlndXJhdGlvbiBlcnJvcgorICAgICAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IiwgIiIpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGZjZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgLy8gU2V0IGRlZmF1bHQgdmFsdWUgb2YgRGF0YXR5cGUgZmFjdG9yeSwKKyAgICAgICAgICAgIC8vIGJlY2F1c2Ugb2YgdGhpcyB0ZXN0IG1vZGlmaWVzIGl0LgorICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmNsZWFyUHJvcGVydHkoImphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3RvcnkiKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IiwKKyAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbmV3RG9jdW1lbnRCdWlsZGVyKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXIgZGIgPSBkYmYubmV3RG9jdW1lbnRCdWlsZGVyKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGRiIGluc3RhbmNlb2YgRG9jdW1lbnRCdWlsZGVyKTsKKyAgICAgICAgICAgIGRiLnBhcnNlKGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbSgiL3NpbXBsZS54bWwiKSk7CisgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgLy8gRXhjZXB0aW9uIGNhc2UKKyAgICAgICAgZGJmLnNldFZhbGlkYXRpbmcodHJ1ZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXIgZGIgPSBkYmYubmV3RG9jdW1lbnRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2goUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZCwgc2luY2UgQW5kcm9pZCBkb2Vzbid0IGhhdmUgYSB2YWxpZGF0aW5nIHBhcnNlci4KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnkjc2V0QXR0cmlidXRlKGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgIGphdmEubGFuZy5PYmplY3QpLgorICAgICAqLworLy8gICAgcHVibGljIHZvaWQgdGVzdF9zZXRBdHRyaWJ1dGVMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfT2JqZWN0KCkgeworLy8gICAgICAgIFN0cmluZ1tdIGF0dHJpYnV0ZXMgPSB7CisvLyAgICAgICAgICAgICAgICAiaHR0cDovL2phdmEuc3VuLmNvbS94bWwvamF4cC9wcm9wZXJ0aWVzL3NjaGVtYUxhbmd1YWdlIiwKKy8vICAgICAgICAgICAgICAgICJodHRwOi8vamF2YS5zdW4uY29tL3htbC9qYXhwL3Byb3BlcnRpZXMvc2NoZW1hU291cmNlIiB9OworLy8gICAgICAgIE9iamVjdFtdIHZhbHVlcyA9IHsgImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiwgInNvdXJjZSIgfTsKKy8vCisvLyAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7CisvLyAgICAgICAgICAgICAgICBkYmYuc2V0QXR0cmlidXRlKGF0dHJpYnV0ZXNbaV0sIHZhbHVlc1tpXSk7CisvLyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHModmFsdWVzW2ldLCBkYmYuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZXNbaV0pKTsKKy8vICAgICAgICAgICAgfQorLy8gICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisvLyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKy8vICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworLy8gICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisvLyAgICAgICAgfQorLy8KKy8vICAgICAgICBTdHJpbmdbXSBiYWRBdHRyaWJ1dGVzID0geyJiYWQxIiwgImJhZDIiLCAiIn07CisvLyAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBiYWRBdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7CisvLyAgICAgICAgICAgICAgICBkYmYuc2V0QXR0cmlidXRlKGJhZEF0dHJpYnV0ZXNbaV0sICIiKTsKKy8vICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworLy8gICAgICAgICAgICB9CisvLyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworLy8gICAgICAgICAgICAvLyBleHBlY3RlZAorLy8gICAgICAgIH0KKy8vCisvLyAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7CisvLyAgICAgICAgICAgICAgICBkYmYuc2V0QXR0cmlidXRlKG51bGwsIG51bGwpOworLy8gICAgICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKy8vICAgICAgICAgICAgfQorLy8gICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKy8vICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKy8vICAgICAgICB9CisvLyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5I3NldENvYWxlc2NpbmcoYm9vbGVhbikuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRDb2FsZXNjaW5nWigpIHsKKyAgICAgICAgZGJmLnNldENvYWxlc2NpbmcodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoZGJmLmlzQ29hbGVzY2luZygpKTsKKworICAgICAgICB0ZXh0RWxlbWVudHMuY2xlYXIoKTsKKyAgICAgICAgY2RhdGFFbGVtZW50cy5jbGVhcigpOworICAgICAgICBFeGNlcHRpb24gcGFyc2VFeGNlcHRpb24gPSBudWxsOworICAgICAgICBEb2N1bWVudEJ1aWxkZXIgcGFyc2VyID0gbnVsbDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFyc2VyID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOworICAgICAgICAgICAgVmFsaWRhdGlvbkVycm9ySGFuZGxlciBlcnJvckhhbmRsZXIgPSBuZXcgVmFsaWRhdGlvbkVycm9ySGFuZGxlcigpOworICAgICAgICAgICAgcGFyc2VyLnNldEVycm9ySGFuZGxlcihlcnJvckhhbmRsZXIpOworCisgICAgICAgICAgICBEb2N1bWVudCBkb2N1bWVudCA9IHBhcnNlci5wYXJzZShnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgICIvcmVjaXB0LnhtbCIpKTsKKworICAgICAgICAgICAgcGFyc2VFeGNlcHRpb24gPSBlcnJvckhhbmRsZXIuZ2V0Rmlyc3RFeGNlcHRpb24oKTsKKworICAgICAgICAgICAgZ29UaHJvdWdoRG9jdW1lbnQoKE5vZGUpIGRvY3VtZW50LCAiIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHRleHRFbGVtZW50cworICAgICAgICAgICAgICAgICAgICAuY29udGFpbnMoIkJlZWZQYXJtZXNhbjx0aXRsZT53aXRoR2FybGljQW5nZWxIYWlyUGFzdGE8L3RpdGxlPiIpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBwYXJzZUV4Y2VwdGlvbiA9IGV4OworICAgICAgICB9CisgICAgICAgIHBhcnNlci5zZXRFcnJvckhhbmRsZXIobnVsbCk7CisKKyAgICAgICAgaWYgKHBhcnNlRXhjZXB0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBwYXJzZUV4Y2VwdGlvbi5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgZGJmLnNldENvYWxlc2NpbmcoZmFsc2UpOworICAgICAgICBhc3NlcnRGYWxzZShkYmYuaXNDb2FsZXNjaW5nKCkpOworCisgICAgICAgIHRleHRFbGVtZW50cy5jbGVhcigpOworICAgICAgICBjZGF0YUVsZW1lbnRzLmNsZWFyKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcnNlciA9IGRiZi5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKKyAgICAgICAgICAgIFZhbGlkYXRpb25FcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyID0gbmV3IFZhbGlkYXRpb25FcnJvckhhbmRsZXIoKTsKKyAgICAgICAgICAgIHBhcnNlci5zZXRFcnJvckhhbmRsZXIoZXJyb3JIYW5kbGVyKTsKKworICAgICAgICAgICAgRG9jdW1lbnQgZG9jdW1lbnQgPSBwYXJzZXIucGFyc2UoZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKAorICAgICAgICAgICAgICAgICAgICAiL3JlY2lwdC54bWwiKSk7CisKKyAgICAgICAgICAgIHBhcnNlRXhjZXB0aW9uID0gZXJyb3JIYW5kbGVyLmdldEZpcnN0RXhjZXB0aW9uKCk7CisKKyAgICAgICAgICAgIGdvVGhyb3VnaERvY3VtZW50KChOb2RlKSBkb2N1bWVudCwgIiIpOworCisgICAgICAgICAgICBhc3NlcnRGYWxzZSh0ZXh0RWxlbWVudHMKKyAgICAgICAgICAgICAgICAgICAgLmNvbnRhaW5zKCJCZWVmUGFybWVzYW48dGl0bGU+d2l0aEdhcmxpY0FuZ2VsSGFpclBhc3RhPC90aXRsZT4iKSk7CisKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBwYXJzZUV4Y2VwdGlvbiA9IGV4OworICAgICAgICB9CisgICAgICAgIHBhcnNlci5zZXRFcnJvckhhbmRsZXIobnVsbCk7CisKKyAgICAgICAgaWYgKHBhcnNlRXhjZXB0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBwYXJzZUV4Y2VwdGlvbi5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSNzZXRFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKGJvb2xlYW4pLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0RXhwYW5kRW50aXR5UmVmZXJlbmNlc1ooKSB7CisgICAgICAgIGRiZi5zZXRFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKHRydWUpOworICAgICAgICBhc3NlcnRUcnVlKGRiZi5pc0V4cGFuZEVudGl0eVJlZmVyZW5jZXMoKSk7CisKKyAgICAgICAgRXhjZXB0aW9uIHBhcnNlRXhjZXB0aW9uID0gbnVsbDsKKyAgICAgICAgRG9jdW1lbnRCdWlsZGVyIHBhcnNlciA9IG51bGw7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcnNlciA9IGRiZi5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKKyAgICAgICAgICAgIFZhbGlkYXRpb25FcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyID0gbmV3IFZhbGlkYXRpb25FcnJvckhhbmRsZXIoKTsKKyAgICAgICAgICAgIHBhcnNlci5zZXRFcnJvckhhbmRsZXIoZXJyb3JIYW5kbGVyKTsKKworICAgICAgICAgICAgRG9jdW1lbnQgZG9jdW1lbnQgPSBwYXJzZXIucGFyc2UoZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKAorICAgICAgICAgICAgICAgICAgICAiL3JlY2lwdC54bWwiKSk7CisKKyAgICAgICAgICAgIHBhcnNlRXhjZXB0aW9uID0gZXJyb3JIYW5kbGVyLmdldEZpcnN0RXhjZXB0aW9uKCk7CisKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZG9jdW1lbnQpOworCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgcGFyc2VFeGNlcHRpb24gPSBleDsKKyAgICAgICAgfQorICAgICAgICBwYXJzZXIuc2V0RXJyb3JIYW5kbGVyKG51bGwpOworCisgICAgICAgIGlmIChwYXJzZUV4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgcGFyc2VFeGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGRiZi5zZXRFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZGJmLmlzRXhwYW5kRW50aXR5UmVmZXJlbmNlcygpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcnNlciA9IGRiZi5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKKyAgICAgICAgICAgIFZhbGlkYXRpb25FcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyID0gbmV3IFZhbGlkYXRpb25FcnJvckhhbmRsZXIoKTsKKyAgICAgICAgICAgIHBhcnNlci5zZXRFcnJvckhhbmRsZXIoZXJyb3JIYW5kbGVyKTsKKworICAgICAgICAgICAgRG9jdW1lbnQgZG9jdW1lbnQgPSBwYXJzZXIucGFyc2UoZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKAorICAgICAgICAgICAgICAgICAgICAiL3JlY2lwdC54bWwiKSk7CisKKyAgICAgICAgICAgIHBhcnNlRXhjZXB0aW9uID0gZXJyb3JIYW5kbGVyLmdldEZpcnN0RXhjZXB0aW9uKCk7CisKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZG9jdW1lbnQpOworCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgcGFyc2VFeGNlcHRpb24gPSBleDsKKyAgICAgICAgfQorICAgICAgICBwYXJzZXIuc2V0RXJyb3JIYW5kbGVyKG51bGwpOworCisgICAgICAgIGlmIChwYXJzZUV4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgcGFyc2VFeGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnkjc2V0RmVhdHVyZShqYXZhLmxhbmcuU3RyaW5nKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFNldEZlYXR1cmVMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nW10gZmVhdHVyZXMgPSB7ICJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlcyIsCisgICAgICAgICAgICAgICAgImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy92YWxpZGF0aW9uIiB9OworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmZWF0dXJlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGRiZi5zZXRGZWF0dXJlKGZlYXR1cmVzW2ldLCB0cnVlKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGRiZi5nZXRGZWF0dXJlKGZlYXR1cmVzW2ldKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZlYXR1cmVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgZGJmLnNldEZlYXR1cmUoZmVhdHVyZXNbaV0sIGZhbHNlKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShkYmYuZ2V0RmVhdHVyZShmZWF0dXJlc1tpXSkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmZWF0dXJlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGRiZi5zZXRGZWF0dXJlKG51bGwsIGZhbHNlKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdbXSBiYWRGZWF0dXJlcyA9IHsgImJhZDEiLCAiYmFkMiIsICIiIH07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJhZEZlYXR1cmVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgZGJmLnNldEZlYXR1cmUoYmFkRmVhdHVyZXNbaV0sIGZhbHNlKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnkjc2V0SWdub3JpbmdDb21tZW50cyhib29sZWFuKS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldElnbm9yaW5nQ29tbWVudHNaKCkgeworICAgICAgICBjb21tZW50RWxlbWVudHMuY2xlYXIoKTsKKworICAgICAgICBkYmYuc2V0SWdub3JpbmdDb21tZW50cyh0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShkYmYuaXNJZ25vcmluZ0NvbW1lbnRzKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXIgcGFyc2VyID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOworCisgICAgICAgICAgICBEb2N1bWVudCBkb2N1bWVudCA9IHBhcnNlci5wYXJzZShnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgICIvcmVjaXB0LnhtbCIpKTsKKworICAgICAgICAgICAgZ29UaHJvdWdoRG9jdW1lbnQoKE5vZGUpIGRvY3VtZW50LCAiIik7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShjb21tZW50RWxlbWVudHMuY29udGFpbnMoImNvbW1lbnQxIikpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoY29tbWVudEVsZW1lbnRzLmNvbnRhaW5zKCJjb21tZW50MiIpKTsKKworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNBWEV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgY29tbWVudEVsZW1lbnRzLmNsZWFyKCk7CisKKyAgICAgICAgZGJmLnNldElnbm9yaW5nQ29tbWVudHMoZmFsc2UpOworICAgICAgICBhc3NlcnRGYWxzZShkYmYuaXNJZ25vcmluZ0NvbW1lbnRzKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXIgcGFyc2VyID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOworCisgICAgICAgICAgICBEb2N1bWVudCBkb2N1bWVudCA9IHBhcnNlci5wYXJzZShnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgICIvcmVjaXB0LnhtbCIpKTsKKworICAgICAgICAgICAgZ29UaHJvdWdoRG9jdW1lbnQoKE5vZGUpIGRvY3VtZW50LCAiIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGNvbW1lbnRFbGVtZW50cy5jb250YWlucygiY29tbWVudDEiKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGNvbW1lbnRFbGVtZW50cy5jb250YWlucygiY29tbWVudDIiKSk7CisKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTQVhFeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnkjc2V0SWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoYm9vbGVhbikuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRJZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZVooKSB7CisgICAgICAgIGRiZi5zZXRJZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSh0cnVlKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShkYmYuaXNJZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgRG9jdW1lbnRCdWlsZGVyIHBhcnNlciA9IGRiZi5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKKworICAgICAgICAgICAgRG9jdW1lbnQgZG9jdW1lbnQgPSBwYXJzZXIucGFyc2UoZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKAorICAgICAgICAgICAgICAgICAgICAiL3JlY2lwdC54bWwiKSk7CisKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZG9jdW1lbnQpOworCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU0FYRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBkYmYuc2V0SWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoZmFsc2UpOworICAgICAgICBhc3NlcnRGYWxzZShkYmYuaXNJZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgRG9jdW1lbnRCdWlsZGVyIHBhcnNlciA9IGRiZi5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKKworICAgICAgICAgICAgRG9jdW1lbnQgZG9jdW1lbnQgPSBwYXJzZXIucGFyc2UoZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKAorICAgICAgICAgICAgICAgICAgICAiL3JlY2lwdC54bWwiKSk7CisKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZG9jdW1lbnQpOworCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU0FYRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5I3NldE5hbWVzcGFjZUF3YXJlKGJvb2xlYW4pLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0TmFtZXNwYWNlQXdhcmVaKCkgeworICAgICAgICBkYmYuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoZGJmLmlzTmFtZXNwYWNlQXdhcmUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIERvY3VtZW50QnVpbGRlciBwYXJzZXIgPSBkYmYubmV3RG9jdW1lbnRCdWlsZGVyKCk7CisKKyAgICAgICAgICAgIERvY3VtZW50IGRvY3VtZW50ID0gcGFyc2VyLnBhcnNlKGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbSgKKyAgICAgICAgICAgICAgICAgICAgIi9yZWNpcHQueG1sIikpOworCisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGRvY3VtZW50KTsKKworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNBWEV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgZGJmLnNldE5hbWVzcGFjZUF3YXJlKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoZGJmLmlzTmFtZXNwYWNlQXdhcmUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIERvY3VtZW50QnVpbGRlciBwYXJzZXIgPSBkYmYubmV3RG9jdW1lbnRCdWlsZGVyKCk7CisKKyAgICAgICAgICAgIERvY3VtZW50IGRvY3VtZW50ID0gcGFyc2VyLnBhcnNlKGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbSgKKyAgICAgICAgICAgICAgICAgICAgIi9yZWNpcHQueG1sIikpOworCisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGRvY3VtZW50KTsKKworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNBWEV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTZXRBdHRyaWJ1dGUoKSB7CisgICAgICAgIC8vIEFuZHJvaWQgU0FYIGltcGxlbWVudGF0aW9uIGRvZXNuJ3Qgc3VwcG9ydCBhdHRyaWJ1dGVzLCBzbworICAgICAgICAvLyB3ZSBjYW4gb25seSBtYWtlIHN1cmUgdGhlIGV4cGVjdGVkIGV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkYmYuc2V0QXR0cmlidXRlKCJmb28iLCBuZXcgT2JqZWN0KCkpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRiZi5nZXRBdHRyaWJ1dGUoImZvbyIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSNzZXRTY2hlbWEoamF2YXgueG1sLnZhbGlkYXRpb24uU2NoZW1hKS4KKyAgICAgKi8KKyAvKiAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0U2NoZW1hTGphdmF4X3htbF92YWxpZGF0aW9uX1NjaGVtYSgpIHsKKyAgICAgICAgU2NoZW1hRmFjdG9yeSBzZiA9CisgICAgICAgICAgICBTY2hlbWFGYWN0b3J5Lm5ld0luc3RhbmNlKFhNTENvbnN0YW50cy5XM0NfWE1MX1NDSEVNQV9OU19VUkkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2NoZW1hIHNjaGVtYSA9IHNmLm5ld1NjaGVtYSgpOworICAgICAgICAgICAgZGJmLnNldFNjaGVtYShzY2hlbWEpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChkYmYuZ2V0U2NoZW1hKCkpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gc2F4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgc2F4LnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorKi8KKyAgICAvKioKKyAgICAgKiBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5I3NldFZhbGlkYXRpbmcoYm9vbGVhbikuCisgICAgICovCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFZhbGlkYXRpbmdaKCkgeworLy8gICAgICAgIEV4Y2VwdGlvbiBwYXJzZUV4Y2VwdGlvbiA9IG51bGw7CisvLyAgICAgICAgRG9jdW1lbnRCdWlsZGVyIHBhcnNlciA9IG51bGw7CisvLyAgICAgICAgRG9jdW1lbnQgZG9jdW1lbnQgPSBudWxsOworLy8KKy8vICAgICAgICBWYWxpZGF0aW9uRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlciA9IG5ldyBWYWxpZGF0aW9uRXJyb3JIYW5kbGVyKCk7CisvLworLy8gICAgICAgIGRiZi5zZXRWYWxpZGF0aW5nKGZhbHNlKTsKKy8vICAgICAgICBhc3NlcnRGYWxzZShkYmYuaXNWYWxpZGF0aW5nKCkpOworLy8KKy8vICAgICAgICAvLyBjYXNlIDE6IFZhbGlkYXRpb24gaXMgbm90IHNldC4gQ29ycmVjdCB4bWwtZmlsZQorLy8gICAgICAgIHRyeSB7CisvLworLy8gICAgICAgICAgICBwYXJzZXIgPSBkYmYubmV3RG9jdW1lbnRCdWlsZGVyKCk7CisvLyAgICAgICAgICAgIHBhcnNlci5zZXRFcnJvckhhbmRsZXIoZXJyb3JIYW5kbGVyKTsKKy8vCisvLyAgICAgICAgICAgIGRvY3VtZW50ID0gcGFyc2VyLnBhcnNlKGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbSgKKy8vICAgICAgICAgICAgICAgICAgICAiL3JlY2lwdC54bWwiKSk7CisvLworLy8gICAgICAgICAgICBwYXJzZUV4Y2VwdGlvbiA9IGVycm9ySGFuZGxlci5nZXRGaXJzdEV4Y2VwdGlvbigpOworLy8KKy8vICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChkb2N1bWVudCk7CisvLworLy8gICAgICAgICAgICBkb2N1bWVudCA9IHBhcnNlci5wYXJzZShnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oCisvLyAgICAgICAgICAgICAgICAgICAgIi9yZWNpcHRXcm9uZy54bWwiKSk7CisvLworLy8gICAgICAgICAgICBwYXJzZUV4Y2VwdGlvbiA9IGVycm9ySGFuZGxlci5nZXRGaXJzdEV4Y2VwdGlvbigpOworLy8KKy8vICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChkb2N1bWVudCk7CisvLworLy8gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworLy8gICAgICAgICAgICBwYXJzZUV4Y2VwdGlvbiA9IGV4OworLy8gICAgICAgIH0KKy8vICAgICAgICBwYXJzZXIuc2V0RXJyb3JIYW5kbGVyKG51bGwpOworLy8KKy8vICAgICAgICBpZiAocGFyc2VFeGNlcHRpb24gIT0gbnVsbCkgeworLy8gICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgcGFyc2VFeGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKKy8vICAgICAgICB9CisvLworLy8gICAgICAgIC8vIGNhc2UgMjogVmFsaWRhdGlvbiBpcyBub3Qgc2V0LiBXcm9uZyB4bWwtZmlsZQorLy8gICAgICAgIHRyeSB7CisvLworLy8gICAgICAgICAgICBwYXJzZXIgPSBkYmYubmV3RG9jdW1lbnRCdWlsZGVyKCk7CisvLyAgICAgICAgICAgIHBhcnNlci5zZXRFcnJvckhhbmRsZXIoZXJyb3JIYW5kbGVyKTsKKy8vCisvLyAgICAgICAgICAgIGRvY3VtZW50ID0gcGFyc2VyLnBhcnNlKGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbSgKKy8vICAgICAgICAgICAgICAgICAgICAiL3JlY2lwdFdyb25nLnhtbCIpKTsKKy8vICAgICAgICAgICAgcGFyc2VFeGNlcHRpb24gPSBlcnJvckhhbmRsZXIuZ2V0Rmlyc3RFeGNlcHRpb24oKTsKKy8vCisvLyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZG9jdW1lbnQpOworLy8KKy8vICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKy8vICAgICAgICAgICAgcGFyc2VFeGNlcHRpb24gPSBleDsKKy8vICAgICAgICB9CisvLyAgICAgICAgcGFyc2VyLnNldEVycm9ySGFuZGxlcihudWxsKTsKKy8vCisvLyAgICAgICAgaWYgKHBhcnNlRXhjZXB0aW9uICE9IG51bGwpIHsKKy8vICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIHBhcnNlRXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7CisvLyAgICAgICAgfQorLy8KKy8vICAgICAgICAvLyBjYXNlIDM6IFZhbGlkYXRpb24gaXMgc2V0LiBDb3JyZWN0IHhtbC1maWxlCisvLyAgICAgICAgZGJmLnNldFZhbGlkYXRpbmcodHJ1ZSk7CisvLyAgICAgICAgYXNzZXJ0VHJ1ZShkYmYuaXNWYWxpZGF0aW5nKCkpOworLy8KKy8vICAgICAgICB0cnkgeworLy8KKy8vICAgICAgICAgICAgcGFyc2VyID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOworLy8gICAgICAgICAgICBwYXJzZXIuc2V0RXJyb3JIYW5kbGVyKGVycm9ySGFuZGxlcik7CisvLworLy8gICAgICAgICAgICBkb2N1bWVudCA9IHBhcnNlci5wYXJzZShnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oCisvLyAgICAgICAgICAgICAgICAgICAgIi9yZWNpcHQueG1sIikpOworLy8gICAgICAgICAgICBwYXJzZUV4Y2VwdGlvbiA9IGVycm9ySGFuZGxlci5nZXRGaXJzdEV4Y2VwdGlvbigpOworLy8KKy8vICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChkb2N1bWVudCk7CisvLworLy8gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworLy8gICAgICAgICAgICBwYXJzZUV4Y2VwdGlvbiA9IGV4OworLy8gICAgICAgIH0KKy8vICAgICAgICBwYXJzZXIuc2V0RXJyb3JIYW5kbGVyKG51bGwpOworLy8KKy8vICAgICAgICBpZiAocGFyc2VFeGNlcHRpb24gIT0gbnVsbCkgeworLy8gICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgcGFyc2VFeGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKKy8vICAgICAgICB9CisvLworLy8gICAgICAgIC8vIGNhc2UgNDogVmFsaWRhdGlvbiBpcyBzZXQuIFdyb25nIHhtbC1maWxlCisvLyAgICAgICAgdHJ5IHsKKy8vCisvLyAgICAgICAgICAgIHBhcnNlciA9IGRiZi5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKKy8vICAgICAgICAgICAgcGFyc2VyLnNldEVycm9ySGFuZGxlcihlcnJvckhhbmRsZXIpOworLy8KKy8vICAgICAgICAgICAgZG9jdW1lbnQgPSBwYXJzZXIucGFyc2UoZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKAorLy8gICAgICAgICAgICAgICAgICAgICIvcmVjaXB0V3JvbmcueG1sIikpOworLy8gICAgICAgICAgICBwYXJzZUV4Y2VwdGlvbiA9IGVycm9ySGFuZGxlci5nZXRGaXJzdEV4Y2VwdGlvbigpOworLy8KKy8vICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChkb2N1bWVudCk7CisvLworLy8gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworLy8gICAgICAgICAgICBwYXJzZUV4Y2VwdGlvbiA9IGV4OworLy8gICAgICAgIH0KKy8vICAgICAgICBwYXJzZXIuc2V0RXJyb3JIYW5kbGVyKG51bGwpOworLy8KKy8vICAgICAgICBpZiAocGFyc2VFeGNlcHRpb24gPT0gbnVsbCkgeworLy8gICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgcGFyc2VFeGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKKy8vICAgICAgICB9IGVsc2UgeworLy8gICAgICAgICAgICBhc3NlcnRUcnVlKHBhcnNlRXhjZXB0aW9uCisvLyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKQorLy8gICAgICAgICAgICAgICAgICAgIC5jb250YWlucygKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUaGUgY29udGVudCBvZiBlbGVtZW50IHR5cGUgXCJjb2xsZWN0aW9uXCIgbXVzdCBtYXRjaCBcIihkZXNjcmlwdGlvbixyZWNpcGUrKVwiIikpOworLy8gICAgICAgIH0KKy8vCisvLyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5I3NldFhJbmNsdWRlQXdhcmUoKS4KKyAgICAgKi8KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0WEluY2x1ZGVBd2FyZSgpIHsKKy8vICAgICAgICBkYmYuc2V0WEluY2x1ZGVBd2FyZSh0cnVlKTsKKy8vICAgICAgICBhc3NlcnRUcnVlKGRiZi5pc1hJbmNsdWRlQXdhcmUoKSk7CisvLworLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIERvY3VtZW50QnVpbGRlciBwYXJzZXIgPSBkYmYubmV3RG9jdW1lbnRCdWlsZGVyKCk7CisvLworLy8gICAgICAgICAgICBEb2N1bWVudCBkb2N1bWVudCA9IHBhcnNlci5wYXJzZShnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oCisvLyAgICAgICAgICAgICAgICAgICAgIi9yZWNpcHQueG1sIikpOworLy8KKy8vICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChkb2N1bWVudCk7CisvLworLy8gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKy8vICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworLy8gICAgICAgIH0gY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgeworLy8gICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKy8vICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworLy8gICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNBWEV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworLy8gICAgICAgIH0KKy8vCisvLyAgICAgICAgZGJmLnNldFhJbmNsdWRlQXdhcmUoZmFsc2UpOworLy8gICAgICAgIGFzc2VydEZhbHNlKGRiZi5pc1hJbmNsdWRlQXdhcmUoKSk7CisvLworLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIERvY3VtZW50QnVpbGRlciBwYXJzZXIgPSBkYmYubmV3RG9jdW1lbnRCdWlsZGVyKCk7CisvLworLy8gICAgICAgICAgICBEb2N1bWVudCBkb2N1bWVudCA9IHBhcnNlci5wYXJzZShnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oCisvLyAgICAgICAgICAgICAgICAgICAgIi9yZWNpcHQueG1sIikpOworLy8KKy8vICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChkb2N1bWVudCk7CisvLworLy8gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKy8vICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworLy8gICAgICAgIH0gY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgeworLy8gICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKy8vICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworLy8gICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNBWEV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworLy8gICAgICAgIH0KKy8vICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBnb1Rocm91Z2hEb2N1bWVudChOb2RlIG5vZGUsIFN0cmluZyBpbmRlbnQpIHsKKyAgICAgICAgU3RyaW5nIHZhbHVlID0gbm9kZS5nZXROb2RlVmFsdWUoKTsKKworICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlQWxsKCIgIiwgIiIpOworICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlQWxsKCJcbiIsICIiKTsKKyAgICAgICAgfQorCisgICAgICAgIHN3aXRjaCAobm9kZS5nZXROb2RlVHlwZSgpKSB7CisgICAgICAgIGNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREU6CisgICAgICAgICAgICBjZGF0YUVsZW1lbnRzLmFkZCh2YWx1ZSk7CisgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oaW5kZW50ICsgIkNEQVRBX1NFQ1RJT05fTk9ERSAiICsgdmFsdWUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgTm9kZS5DT01NRU5UX05PREU6CisgICAgICAgICAgICBjb21tZW50RWxlbWVudHMuYWRkKHZhbHVlKTsKKyAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihpbmRlbnQgKyAiQ09NTUVOVF9OT0RFICIgKyB2YWx1ZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREU6CisgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oaW5kZW50ICsgIkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUgIiArIHZhbHVlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfTk9ERToKKyAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihpbmRlbnQgKyAiRE9DVU1FTlRfTk9ERSAiICsgdmFsdWUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9UWVBFX05PREU6CisgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oaW5kZW50ICsgIkRPQ1VNRU5UX1RZUEVfTk9ERSAiICsgdmFsdWUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6CisgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oaW5kZW50ICsgIkVMRU1FTlRfTk9ERSAiICsgdmFsdWUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfTk9ERToKKyAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihpbmRlbnQgKyAiRU5USVRZX05PREUgIiArIHZhbHVlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFOgorICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKGluZGVudCArICJFTlRJVFlfUkVGRVJFTkNFX05PREUgIiArIHZhbHVlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIE5vZGUuTk9UQVRJT05fTk9ERToKKyAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihpbmRlbnQgKyAiTk9UQVRJT05fTk9ERSAiICsgdmFsdWUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU6CisgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oaW5kZW50ICsgIlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSAiICsKKyAgICAgICAgICAgIC8vIHZhbHVlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIE5vZGUuVEVYVF9OT0RFOgorICAgICAgICAgICAgdGV4dEVsZW1lbnRzLmFkZCh2YWx1ZSk7CisgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oaW5kZW50ICsgIlRFWFRfTk9ERSAiICsgdmFsdWUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oaW5kZW50ICsgIlVua25vd24gbm9kZSAiICsgdmFsdWUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgTm9kZUxpc3QgbGlzdCA9IG5vZGUuZ2V0Q2hpbGROb2RlcygpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxpc3QuZ2V0TGVuZ3RoKCk7IGkrKykKKyAgICAgICAgICAgIGdvVGhyb3VnaERvY3VtZW50KGxpc3QuaXRlbShpKSwgaW5kZW50ICsgIiAgICIpOworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgVmFsaWRhdGlvbkVycm9ySGFuZGxlciBpbXBsZW1lbnRzIEVycm9ySGFuZGxlciB7CisgICAgICAgIHByaXZhdGUgU0FYRXhjZXB0aW9uIHBhcnNlRXhjZXB0aW9uOworCisgICAgICAgIHByaXZhdGUgaW50IGVycm9yQ291bnQ7CisKKyAgICAgICAgcHJpdmF0ZSBpbnQgd2FybmluZ0NvdW50OworCisgICAgICAgIHB1YmxpYyBWYWxpZGF0aW9uRXJyb3JIYW5kbGVyKCkgeworICAgICAgICAgICAgcGFyc2VFeGNlcHRpb24gPSBudWxsOworICAgICAgICAgICAgZXJyb3JDb3VudCA9IDA7CisgICAgICAgICAgICB3YXJuaW5nQ291bnQgPSAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgZXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGVycm9yQ291bnQrKzsKKyAgICAgICAgICAgIGlmIChwYXJzZUV4Y2VwdGlvbiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcGFyc2VFeGNlcHRpb24gPSBleDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoU0FYUGFyc2VFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHdhcm5pbmdDb3VudCsrOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgZmF0YWxFcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgaWYgKHBhcnNlRXhjZXB0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBwYXJzZUV4Y2VwdGlvbiA9IGV4OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFNBWEV4Y2VwdGlvbiBnZXRGaXJzdEV4Y2VwdGlvbigpIHsKKyAgICAgICAgICAgIHJldHVybiBwYXJzZUV4Y2VwdGlvbjsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeUNoaWxkIGV4dGVuZHMgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB7CisgICAgICAgIHB1YmxpYyBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Q2hpbGQoKSB7CisgICAgICAgICAgICBzdXBlcigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBnZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIERvY3VtZW50QnVpbGRlciBuZXdEb2N1bWVudEJ1aWxkZXIoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKSB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKSB7CisgICAgICAgIH0KKworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgveG1sL3BhcnNlcnMvRG9jdW1lbnRCdWlsZGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC94bWwvcGFyc2Vycy9Eb2N1bWVudEJ1aWxkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjZjZTYyMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgveG1sL3BhcnNlcnMvRG9jdW1lbnRCdWlsZGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjM3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXgueG1sLnBhcnNlcnM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbnRpdHlSZWZlcmVuY2U7CitpbXBvcnQgb3JnLnczYy5kb20uVGV4dDsKK2ltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOworaW1wb3J0IHRlc3RzLmFwaS5vcmcueG1sLnNheC5zdXBwb3J0Lk1ldGhvZExvZ2dlcjsKK2ltcG9ydCB0ZXN0cy5hcGkub3JnLnhtbC5zYXguc3VwcG9ydC5Nb2NrSGFuZGxlcjsKK2ltcG9ydCB0ZXN0cy5hcGkub3JnLnhtbC5zYXguc3VwcG9ydC5Nb2NrUmVzb2x2ZXI7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5yZXNvdXJjZS5TdXBwb3J0X1Jlc291cmNlczsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CisKK3B1YmxpYyBjbGFzcyBEb2N1bWVudEJ1aWxkZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBjbGFzcyBNb2NrRG9jdW1lbnRCdWlsZGVyIGV4dGVuZHMgRG9jdW1lbnRCdWlsZGVyIHsKKworICAgICAgICBwdWJsaWMgTW9ja0RvY3VtZW50QnVpbGRlcigpIHsKKyAgICAgICAgICAgIHN1cGVyKCk7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBAc2VlIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlciNnZXRET01JbXBsZW1lbnRhdGlvbigpCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIERPTUltcGxlbWVudGF0aW9uIGdldERPTUltcGxlbWVudGF0aW9uKCkgeworICAgICAgICAgICAgLy8gaXQgaXMgYSBmYWtlCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIEBzZWUgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyI2lzTmFtZXNwYWNlQXdhcmUoKQorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzTmFtZXNwYWNlQXdhcmUoKSB7CisgICAgICAgICAgICAvLyBpdCBpcyBhIGZha2UKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIEBzZWUgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyI2lzVmFsaWRhdGluZygpCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNWYWxpZGF0aW5nKCkgeworICAgICAgICAgICAgLy8gaXQgaXMgYSBmYWtlCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBAc2VlIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlciNuZXdEb2N1bWVudCgpCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIERvY3VtZW50IG5ld0RvY3VtZW50KCkgeworICAgICAgICAgICAgLy8gaXQgaXMgYSBmYWtlCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIEBzZWUgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyI3BhcnNlKG9yZy54bWwuc2F4LklucHV0U291cmNlKQorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBEb2N1bWVudCBwYXJzZShJbnB1dFNvdXJjZSBpcykgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICAgICAgLy8gaXQgaXMgYSBmYWtlCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIEBzZWUgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyI3NldEVudGl0eVJlc29sdmVyKAorICAgICAgICAgKiAgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXIpCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoRW50aXR5UmVzb2x2ZXIgZXIpIHsKKyAgICAgICAgICAgIC8vIGl0IGlzIGEgZmFrZQorICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogQHNlZSBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXIjc2V0RXJyb3JIYW5kbGVyKAorICAgICAgICAgKiAgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyKQorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgZWgpIHsKKyAgICAgICAgICAgIC8vIGl0IGlzIGEgZmFrZQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZGJmOworCisgICAgRG9jdW1lbnRCdWlsZGVyIGRiOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBkYmYgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisKKyAgICAgICAgZGJmLnNldElnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKHRydWUpOworCisgICAgICAgIGRiID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdERvY3VtZW50QnVpbGRlcigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBNb2NrRG9jdW1lbnRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqICBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXIjZ2V0U2NoZW1hKCkKKyAgICAgKiAgVEJEIGdldFNjaGVtYSgpIGlzIG5vdCBzdXBwb3J0ZWQKKyAgICAgKi8KKyAvKiAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0U2NoZW1hKCkgeworICAgICAgICBhc3NlcnROdWxsKGRiLmdldFNjaGVtYSgpKTsKKyAgICAgICAgU2NoZW1hRmFjdG9yeSBzZiA9CisgICAgICAgICAgICBTY2hlbWFGYWN0b3J5Lm5ld0luc3RhbmNlKFhNTENvbnN0YW50cy5XM0NfWE1MX1NDSEVNQV9OU19VUkkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2NoZW1hIHNjaGVtYSA9IHNmLm5ld1NjaGVtYSgpOworICAgICAgICAgICAgZGJmLnNldFNjaGVtYShzY2hlbWEpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChkYmYubmV3RG9jdW1lbnRCdWlsZGVyKCkuZ2V0U2NoZW1hKCkpOworICAgICAgICB9IGNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHBjZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uICIgKyBwY2UudG9TdHJpbmcoKSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzYXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU0FYRXhjZXB0aW9uICIgKyBzYXgudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisqLworICAgIHB1YmxpYyB2b2lkIHRlc3ROZXdEb2N1bWVudCgpIHsKKyAgICAgICAgRG9jdW1lbnQgZDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZCA9IGRiZi5uZXdEb2N1bWVudEJ1aWxkZXIoKS5uZXdEb2N1bWVudCgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnROb3ROdWxsKGQpOworICAgICAgICBhc3NlcnROdWxsKGQuZ2V0RG9jdHlwZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChkLmdldERvY3VtZW50RWxlbWVudCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChkLmdldE5hbWVzcGFjZVVSSSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW1wbGVtZW50YXRpb24oKSB7CisgICAgICAgIERPTUltcGxlbWVudGF0aW9uIGQ7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGQgPSBkYmYubmV3RG9jdW1lbnRCdWlsZGVyKCkuZ2V0RE9NSW1wbGVtZW50YXRpb24oKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNOYW1lc3BhY2VBd2FyZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRiZi5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpLmlzTmFtZXNwYWNlQXdhcmUoKSk7CisgICAgICAgICAgICBkYmYuc2V0TmFtZXNwYWNlQXdhcmUoZmFsc2UpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpLmlzTmFtZXNwYWNlQXdhcmUoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJc1ZhbGlkYXRpbmcoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkYmYuc2V0VmFsaWRhdGluZyhmYWxzZSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShkYmYubmV3RG9jdW1lbnRCdWlsZGVyKCkuaXNWYWxpZGF0aW5nKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNYSW5jbHVkZUF3YXJlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGJmLnNldFhJbmNsdWRlQXdhcmUoZmFsc2UpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpLmlzWEluY2x1ZGVBd2FyZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgdGhhdCB0aGUgQmFzZSBVUkkgZm9yIHRoZSBkb2N1bWVudCBpcyBwb3B1bGF0ZWQgd2l0aCB0aGUgZmlsZSBVUkkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEJhc2VVUkkoKSB0aHJvd3MgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgZiA9IFN1cHBvcnRfUmVzb3VyY2VzLnJlc291cmNlVG9UZW1wRmlsZSgiL3NpbXBsZS54bWwiKTsKKyAgICAgICAgRG9jdW1lbnQgZCA9IGRiLnBhcnNlKGYpOworICAgICAgICBhc3NlcnRUcnVlKGQuZ2V0RG9jdW1lbnRFbGVtZW50KCkuZ2V0QmFzZVVSSSgpLnN0YXJ0c1dpdGgoImZpbGU6Ly8iKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyI3BhcnNlKGphdmEuaW8uRmlsZSkKKyAgICAgKiBDYXNlIDE6IFRyeSB0byBwYXJzZSBjb3JyZWN0IHhtbCBkb2N1bWVudC4KKyAgICAgKiBDYXNlIDI6IFRyeSB0byBjYWxsIHBhcnNlKCkgd2l0aCBudWxsIGFyZ3VtZW50LgorICAgICAqIENhc2UgMzogVHJ5IHRvIHBhcnNlIGEgbm9uLWV4aXN0ZW50IGZpbGUuCisgICAgICogQ2FzZSA0OiBUcnkgdG8gcGFyc2UgaW5jb3JyZWN0IHhtbCBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcGFyc2VMamF2YV9pb19GaWxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZSBmID0gU3VwcG9ydF9SZXNvdXJjZXMucmVzb3VyY2VUb1RlbXBGaWxlKCIvc2ltcGxlLnhtbCIpOworCisgICAgICAgIC8vIGNhc2UgMTogVHJpdmlhbCB1c2UuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEb2N1bWVudCBkID0gZGIucGFyc2UoZik7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGQpOworICAgICAgIC8vICAgICAgVEJEIGdldFhtbEVuY29kaW5nKCkgSVMgTk9UIFNVUFBPUlRFRAorICAgICAgIC8vICAgICBhc3NlcnRFcXVhbHMoIklTTy04ODU5LTEiLCBkLmdldFhtbEVuY29kaW5nKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGQuZ2V0Q2hpbGROb2RlcygpLmdldExlbmd0aCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiI2NvbW1lbnQiLAorICAgICAgICAgICAgICAgICAgICBkLmdldENoaWxkTm9kZXMoKS5pdGVtKDApLmdldE5vZGVOYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJicmVha2Zhc3RfbWVudSIsCisgICAgICAgICAgICAgICAgICAgIGQuZ2V0Q2hpbGROb2RlcygpLml0ZW0oMSkuZ2V0Tm9kZU5hbWUoKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgaW9lLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gc2F4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNBWEV4Y2VwdGlvbiAiICsgc2F4LnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gY2FzZSAyOiBUcnkgdG8gY2FsbCBwYXJzZSB3aXRoIG51bGwgYXJndW1lbnQKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRiLnBhcnNlKChGaWxlKW51bGwpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgaW9lLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gc2F4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNBWEV4Y2VwdGlvbiAiICsgc2F4LnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gY2FzZSAzOiBUcnkgdG8gcGFyc2UgYSBub24tZXhpc3RlbnQgZmlsZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIucGFyc2UobmV3IEZpbGUoIl8iKSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJT0V4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzYXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU0FYRXhjZXB0aW9uICIgKyBzYXgudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBjYXNlIDQ6IFRyeSB0byBwYXJzZSBpbmNvcnJlY3QgeG1sIGZpbGUKKyAgICAgICAgZiA9IFN1cHBvcnRfUmVzb3VyY2VzLnJlc291cmNlVG9UZW1wRmlsZSgiL3dyb25nLnhtbCIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIucGFyc2UoZik7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBTQVhFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uICIgKyBpb2UudG9TdHJpbmcoKSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzYXgpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXIjcGFyc2UoamF2YS5pby5JbnB1dFN0cmVhbSkKKyAgICAgKiBDYXNlIDE6IFRyeSB0byBwYXJzZSBjb3JyZWN0IHhtbCBkb2N1bWVudC4KKyAgICAgKiBDYXNlIDI6IFRyeSB0byBjYWxsIHBhcnNlKCkgd2l0aCBudWxsIGFyZ3VtZW50LgorICAgICAqIENhc2UgMzogVHJ5IHRvIHBhcnNlIGEgbm9uLWV4aXN0ZW50IGZpbGUuCisgICAgICogQ2FzZSA0OiBUcnkgdG8gcGFyc2UgaW5jb3JyZWN0IHhtbCBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcGFyc2VMamF2YV9pb19JbnB1dFN0cmVhbSgpIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oIi9zaW1wbGUueG1sIik7CisgICAgICAgIC8vIGNhc2UgMTogVHJpdmlhbCB1c2UuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEb2N1bWVudCBkID0gZGIucGFyc2UoaXMpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChkKTsKKyAgICAgICAgICAgIC8vIFRCRCBnZXRYbWxFbmNvZGluZygpIElTIE5PVCBTVVBQT1JURUQKKyAgICAgICAgICAgIC8vIGFzc2VydEVxdWFscygiSVNPLTg4NTktMSIsIGQuZ2V0WG1sRW5jb2RpbmcoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMiwgZC5nZXRDaGlsZE5vZGVzKCkuZ2V0TGVuZ3RoKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCIjY29tbWVudCIsCisgICAgICAgICAgICAgICAgICAgIGQuZ2V0Q2hpbGROb2RlcygpLml0ZW0oMCkuZ2V0Tm9kZU5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImJyZWFrZmFzdF9tZW51IiwKKyAgICAgICAgICAgICAgICAgICAgZC5nZXRDaGlsZE5vZGVzKCkuaXRlbSgxKS5nZXROb2RlTmFtZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uICIgKyBpb2UudG9TdHJpbmcoKSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzYXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU0FYRXhjZXB0aW9uICIgKyBzYXgudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBjYXNlIDI6IFRyeSB0byBjYWxsIHBhcnNlIHdpdGggbnVsbCBhcmd1bWVudAorICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIucGFyc2UoKElucHV0U3RyZWFtKW51bGwpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgaW9lLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gc2F4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNBWEV4Y2VwdGlvbiAiICsgc2F4LnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gY2FzZSAzOiBUcnkgdG8gcGFyc2UgYSBub24tZXhpc3RlbnQgZmlsZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIucGFyc2UobmV3IEZpbGVJbnB1dFN0cmVhbSgiXyIpKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElPRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIHNheCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTQVhFeGNlcHRpb24gIiArIHNheC50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNhc2UgNDogVHJ5IHRvIHBhcnNlIGluY29ycmVjdCB4bWwgZmlsZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMgPSBnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oIi93cm9uZy54bWwiKTsKKyAgICAgICAgICAgIGRiLnBhcnNlKGlzKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIFNBWEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gIiArIGlvZS50b1N0cmluZygpKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIHNheCkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlciNwYXJzZShqYXZhLmlvLklucHV0U3RyZWFtKQorICAgICAqIENhc2UgMTogVHJ5IHRvIHBhcnNlIGNvcnJlY3QgeG1sIGRvY3VtZW50LgorICAgICAqIENhc2UgMjogVHJ5IHRvIGNhbGwgcGFyc2UoKSB3aXRoIG51bGwgYXJndW1lbnQuCisgICAgICogQ2FzZSAzOiBUcnkgdG8gcGFyc2UgYSBub24tZXhpc3RlbnQgZmlsZS4KKyAgICAgKiBDYXNlIDQ6IFRyeSB0byBwYXJzZSBpbmNvcnJlY3QgeG1sIGZpbGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlSW5wdXRTb3VyY2UoKSB7CisgICAgICAgIElucHV0U3RyZWFtIHN0cmVhbSA9IGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbSgiL3NpbXBsZS54bWwiKTsKKyAgICAgICAgSW5wdXRTb3VyY2UgaXMgPSBuZXcgSW5wdXRTb3VyY2Uoc3RyZWFtKTsKKworICAgICAgICAvLyBjYXNlIDE6IFRyaXZpYWwgdXNlLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgRG9jdW1lbnQgZCA9IGRiLnBhcnNlKGlzKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoZCk7CisgICAgICAgICAgICAvLyBUQkQgZ2V0WG1sRW5jb2RpbmcoKSBJUyBOT1QgU1VQUE9SVEVECisgICAgICAgICAgICAvLyBhc3NlcnRFcXVhbHMoIklTTy04ODU5LTEiLCBkLmdldFhtbEVuY29kaW5nKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGQuZ2V0Q2hpbGROb2RlcygpLmdldExlbmd0aCgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiI2NvbW1lbnQiLAorICAgICAgICAgICAgICAgICAgICBkLmdldENoaWxkTm9kZXMoKS5pdGVtKDApLmdldE5vZGVOYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJicmVha2Zhc3RfbWVudSIsCisgICAgICAgICAgICAgICAgICAgIGQuZ2V0Q2hpbGROb2RlcygpLml0ZW0oMSkuZ2V0Tm9kZU5hbWUoKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgaW9lLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gc2F4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNBWEV4Y2VwdGlvbiAiICsgc2F4LnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gY2FzZSAyOiBUcnkgdG8gY2FsbCBwYXJzZSB3aXRoIG51bGwgYXJndW1lbnQKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRiLnBhcnNlKChJbnB1dFNvdXJjZSludWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gIiArIGlvZS50b1N0cmluZygpKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIHNheCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTQVhFeGNlcHRpb24gIiArIHNheC50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNhc2UgMzogVHJ5IHRvIHBhcnNlIGEgbm9uLWV4aXN0ZW50IGZpbGUKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRiLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShuZXcgRmlsZUlucHV0U3RyZWFtKCJfIikpKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElPRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIHNheCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTQVhFeGNlcHRpb24gIiArIHNheC50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNhc2UgNDogVHJ5IHRvIHBhcnNlIGluY29ycmVjdCB4bWwgZmlsZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMgPSBuZXcgSW5wdXRTb3VyY2UoZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvd3JvbmcueG1sIikpOworICAgICAgICAgICAgZGIucGFyc2UoaXMpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgU0FYRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgaW9lLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gc2F4KSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyI3BhcnNlKGphdmEuaW8uSW5wdXRTdHJlYW0sCisgICAgICogICAgIGphdmEubGFuZy5TdHJpbmcpCisgICAgICogQ2FzZSAxOiBUcnkgdG8gcGFyc2UgY29ycmVjdCB4bWwgZG9jdW1lbnQuCisgICAgICogQ2FzZSAyOiBUcnkgdG8gY2FsbCBwYXJzZSgpIHdpdGggbnVsbCBhcmd1bWVudC4KKyAgICAgKiBDYXNlIDM6IFRyeSB0byBwYXJzZSBhIG5vbi1leGlzdGVudCBmaWxlLgorICAgICAqIENhc2UgNDogVHJ5IHRvIHBhcnNlIGluY29ycmVjdCB4bWwgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BhcnNlTGphdmFfaW9fSW5wdXRTdHJlYW1MamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oIi9zeXN0ZW1pZC54bWwiKTsKKyAgICAgICAgLy8gY2FzZSAxOiBUcml2aWFsIHVzZS4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIERvY3VtZW50IGQgPSBkYi5wYXJzZShpcywgU0FYUGFyc2VyVGVzdFN1cHBvcnQuWE1MX1NZU1RFTV9JRCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGQpOworLy8gICAgICAgICAgIFRCRCBnZXRYbWxFbmNvZGluZygpIGlzIG5vdCBzdXBwb3J0ZWQKKy8vICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlVURi04IiwgZC5nZXRYbWxFbmNvZGluZygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyg0LCBkLmdldENoaWxkTm9kZXMoKS5nZXRMZW5ndGgoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImNvbGxlY3Rpb24iLAorICAgICAgICAgICAgICAgICAgICBkLmdldENoaWxkTm9kZXMoKS5pdGVtKDApLmdldE5vZGVOYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCIjY29tbWVudCIsCisgICAgICAgICAgICAgICAgICAgIGQuZ2V0Q2hpbGROb2RlcygpLml0ZW0oMSkuZ2V0Tm9kZU5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImNvbGxlY3Rpb24iLAorICAgICAgICAgICAgICAgICAgICBkLmdldENoaWxkTm9kZXMoKS5pdGVtKDIpLmdldE5vZGVOYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCIjY29tbWVudCIsCisgICAgICAgICAgICAgICAgICAgIGQuZ2V0Q2hpbGROb2RlcygpLml0ZW0oMykuZ2V0Tm9kZU5hbWUoKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgaW9lLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gc2F4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNBWEV4Y2VwdGlvbiAiICsgc2F4LnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gY2FzZSAyOiBUcnkgdG8gY2FsbCBwYXJzZSB3aXRoIG51bGwgYXJndW1lbnQKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRiLnBhcnNlKChJbnB1dFN0cmVhbSludWxsLCBTQVhQYXJzZXJUZXN0U3VwcG9ydC5YTUxfU1lTVEVNX0lEKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gIiArIGlvZS50b1N0cmluZygpKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIHNheCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTQVhFeGNlcHRpb24gIiArIHNheC50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNhc2UgMzogVHJ5IHRvIHBhcnNlIGEgbm9uLWV4aXN0ZW50IGZpbGUKKy8vIERvZXNuJ3QgbWFrZSBzZW5zZSB0aGlzIHdheS4uLgorLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIGRiLnBhcnNlKGlzLCAiLyIpOworLy8gICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBJT0V4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworLy8gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworLy8gICAgICAgICAgICAvLyBleHBlY3RlZAorLy8gICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzYXgpIHsKKy8vICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTQVhFeGNlcHRpb24gIiArIHNheC50b1N0cmluZygpKTsKKy8vICAgICAgICB9CisKKyAgICAgICAgLy8gY2FzZSA0OiBUcnkgdG8gcGFyc2UgaW5jb3JyZWN0IHhtbCBmaWxlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcyA9IGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbSgiL3dyb25nLnhtbCIpOworICAgICAgICAgICAgZGIucGFyc2UoaXMsIFNBWFBhcnNlclRlc3RTdXBwb3J0LlhNTF9TWVNURU1fSUQpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgU0FYRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgaW9lLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gc2F4KSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyI3BhcnNlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICogQ2FzZSAxOiBUcnkgdG8gcGFyc2UgY29ycmVjdCB4bWwgZG9jdW1lbnQuCisgICAgICogQ2FzZSAyOiBUcnkgdG8gY2FsbCBwYXJzZSgpIHdpdGggbnVsbCBhcmd1bWVudC4KKyAgICAgKiBDYXNlIDM6IFRyeSB0byBwYXJzZSBhIG5vbi1leGlzdGVudCB1cmkuCisgICAgICogQ2FzZSA0OiBUcnkgdG8gcGFyc2UgaW5jb3JyZWN0IHhtbCBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcGFyc2VMamF2YV9sYW5nX1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBjYXNlIDE6IFRyaXZpYWwgdXNlLgorICAgICAgICBVUkwgcmVzb3VyY2UgPSBnZXRDbGFzcygpLmdldFJlc291cmNlKCIvc2ltcGxlLnhtbCIpOworICAgICAgICBEb2N1bWVudCBkID0gZGIucGFyc2UocmVzb3VyY2UudG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoZCk7CisvLyAgICAgICAgICBUQkQgIGdldFhtbEVuY29kaW5nKCkgaXMgbm90IHN1cHBvcnRlZAorLy8gICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJU08tODg1OS0xIiwgZC5nZXRYbWxFbmNvZGluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGQuZ2V0Q2hpbGROb2RlcygpLmdldExlbmd0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIjY29tbWVudCIsCisgICAgICAgICAgICAgICAgZC5nZXRDaGlsZE5vZGVzKCkuaXRlbSgwKS5nZXROb2RlTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJicmVha2Zhc3RfbWVudSIsCisgICAgICAgICAgICAgICAgZC5nZXRDaGlsZE5vZGVzKCkuaXRlbSgxKS5nZXROb2RlTmFtZSgpKTsKKworICAgICAgICAvLyBjYXNlIDI6IFRyeSB0byBjYWxsIHBhcnNlIHdpdGggbnVsbCBhcmd1bWVudAorICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIucGFyc2UoKFN0cmluZyludWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gY2FzZSAzOiBUcnkgdG8gcGFyc2UgYSBub24tZXhpc3RlbnQgdXJpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkYi5wYXJzZSgiXyIpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gY2FzZSA0OiBUcnkgdG8gcGFyc2UgaW5jb3JyZWN0IHhtbCBmaWxlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXNvdXJjZSA9IGdldENsYXNzKCkuZ2V0UmVzb3VyY2UoIi93cm9uZy54bWwiKTsKKyAgICAgICAgICAgIGRiLnBhcnNlKHJlc291cmNlLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgU0FYRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzYXgpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVzZXQoKSB7CisgICAgICAgIC8vIE1ha2Ugc3VyZSBFbnRpdHlSZXNvbHZlciBnZXRzIHJlc2V0CisgICAgICAgIElucHV0U3RyZWFtIHNvdXJjZSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgiPGE+JmZvbzs8L2E+Ii5nZXRCeXRlcygpKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gZW50aXR5ID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKCJiYXIiLmdldEJ5dGVzKCkpOworCisgICAgICAgIE1vY2tSZXNvbHZlciByZXNvbHZlciA9IG5ldyBNb2NrUmVzb2x2ZXIoKTsKKyAgICAgICAgcmVzb2x2ZXIuYWRkRW50aXR5KCJmb28iLCAiZm9vIiwgbmV3IElucHV0U291cmNlKGVudGl0eSkpOworCisgICAgICAgIERvY3VtZW50IGQ7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRiID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOworICAgICAgICAgICAgZGIuc2V0RW50aXR5UmVzb2x2ZXIocmVzb2x2ZXIpOworICAgICAgICAgICAgZGIucmVzZXQoKTsKKyAgICAgICAgICAgIGQgPSBkYi5wYXJzZShzb3VyY2UpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICBFbGVtZW50IHJvb3QgPSAoRWxlbWVudClkLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhIikuaXRlbSgwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCAoKEVudGl0eVJlZmVyZW5jZSlyb290LmdldEZpcnN0Q2hpbGQoKSkuZ2V0Tm9kZU5hbWUoKSk7CisKKyAgICAgICAgLy8gTWFrZSBzdXJlIEVycm9ySGFuZGxlciBnZXRzIHJlc2V0CisgICAgICAgIHNvdXJjZSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgiPC9hPiIuZ2V0Qnl0ZXMoKSk7CisKKyAgICAgICAgTWV0aG9kTG9nZ2VyIGxvZ2dlciA9IG5ldyBNZXRob2RMb2dnZXIoKTsKKyAgICAgICAgRXJyb3JIYW5kbGVyIGhhbmRsZXIgPSBuZXcgTW9ja0hhbmRsZXIobG9nZ2VyKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIgPSBkYmYubmV3RG9jdW1lbnRCdWlsZGVyKCk7CisgICAgICAgICAgICBkYi5zZXRFcnJvckhhbmRsZXIoaGFuZGxlcik7CisgICAgICAgICAgICBkYi5yZXNldCgpOworICAgICAgICAgICAgZCA9IGRiLnBhcnNlKHNvdXJjZSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygwLCBsb2dnZXIuc2l6ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0RXJyb3JIYW5kbGVyKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIElucHV0U3RyZWFtIHNvdXJjZSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgiPC9hPiIuZ2V0Qnl0ZXMoKSk7CisKKyAgICAgICAgTWV0aG9kTG9nZ2VyIGxvZ2dlciA9IG5ldyBNZXRob2RMb2dnZXIoKTsKKyAgICAgICAgRXJyb3JIYW5kbGVyIGhhbmRsZXIgPSBuZXcgTW9ja0hhbmRsZXIobG9nZ2VyKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgZGIgPSBkYmYubmV3RG9jdW1lbnRCdWlsZGVyKCk7CisgICAgICAgICAgICBkYi5zZXRFcnJvckhhbmRsZXIoaGFuZGxlcik7CisgICAgICAgICAgICBkYi5wYXJzZShzb3VyY2UpOworICAgICAgICB9IGNhdGNoIChTQVhQYXJzZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZCwgRXJyb3JIYW5kbGVyIGRvZXMgbm90IG1hc2sgZXhjZXB0aW9uCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygiZXJyb3IiLCBsb2dnZXIuZ2V0TWV0aG9kKCkpOworICAgICAgICBhc3NlcnRUcnVlKGxvZ2dlci5nZXRBcmdzKClbMF0gaW5zdGFuY2VvZiBTQVhQYXJzZUV4Y2VwdGlvbik7CisKKyAgICAgICAgLy8gbnVsbCBjYXNlCisgICAgICAgIHNvdXJjZSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgiPC9hPiIuZ2V0Qnl0ZXMoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRiID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOworICAgICAgICAgICAgZGIuc2V0RXJyb3JIYW5kbGVyKG51bGwpOworICAgICAgICAgICAgZGIucGFyc2Uoc291cmNlKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYUGFyc2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldEVudGl0eVJlc29sdmVyKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIElucHV0U3RyZWFtIHNvdXJjZSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgiPGE+JmZvbzs8L2E+Ii5nZXRCeXRlcygpKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gZW50aXR5ID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKCJiYXIiLmdldEJ5dGVzKCkpOworCisgICAgICAgIE1vY2tSZXNvbHZlciByZXNvbHZlciA9IG5ldyBNb2NrUmVzb2x2ZXIoKTsKKyAgICAgICAgcmVzb2x2ZXIuYWRkRW50aXR5KCJmb28iLCAiZm9vIiwgbmV3IElucHV0U291cmNlKGVudGl0eSkpOworCisgICAgICAgIERvY3VtZW50IGQ7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRiID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOworICAgICAgICAgICAgZGIuc2V0RW50aXR5UmVzb2x2ZXIocmVzb2x2ZXIpOworICAgICAgICAgICAgZCA9IGRiLnBhcnNlKHNvdXJjZSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIEVsZW1lbnQgcm9vdCA9IChFbGVtZW50KWQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImEiKS5pdGVtKDApOworICAgICAgICBhc3NlcnRFcXVhbHMoImJhciIsICgoVGV4dClyb290LmdldEZpcnN0Q2hpbGQoKSkuZ2V0RGF0YSgpKTsKKworICAgICAgICAvLyBudWxsIGNhc2UKKyAgICAgICAgc291cmNlID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKCI8YT4mZm9vOzwvYT4iLmdldEJ5dGVzKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkYiA9IGRiZi5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKKyAgICAgICAgICAgIGRiLnNldEVudGl0eVJlc29sdmVyKG51bGwpOworICAgICAgICAgICAgZCA9IGRiLnBhcnNlKHNvdXJjZSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHJvb3QgPSAoRWxlbWVudClkLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhIikuaXRlbSgwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCAoKEVudGl0eVJlZmVyZW5jZSlyb290LmdldEZpcnN0Q2hpbGQoKSkuZ2V0Tm9kZU5hbWUoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3htbC9wYXJzZXJzL0ZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3JUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3htbC9wYXJzZXJzL0ZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2RlZjRlMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgveG1sL3BhcnNlcnMvRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvclRlc3QuamF2YQpAQCAtMCwwICsxLDk5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXgueG1sLnBhcnNlcnM7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGZjZSA9IG5ldyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKCk7CisgICAgICAgIGFzc2VydE51bGwoZmNlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoZmNlLmdldExvY2FsaXplZE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoZmNlLmdldENhdXNlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX0V4Y2VwdGlvbigpIHsKKyAgICAgICAgRXhjZXB0aW9uIGUgPSBuZXcgRXhjZXB0aW9uKCk7CisgICAgICAgIC8vIGNhc2UgMTogVHJ5IHRvIGNyZWF0ZSBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yCisgICAgICAgIC8vIHdoaWNoIGlzIGJhc2VkIG9uIEV4Y2VwdGlvbiB3aXRob3V0IHBhcmFtZXRlcnMuCisgICAgICAgIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgZmNlID0gbmV3IEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoZSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoZmNlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoZmNlLmdldExvY2FsaXplZE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhlLmdldENhdXNlKCksIGZjZS5nZXRDYXVzZSgpKTsKKworICAgICAgICAvLyBjYXNlIDI6IFRyeSB0byBjcmVhdGUgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcgorICAgICAgICAvLyB3aGljaCBpcyBiYXNlZCBvbiBFeGNlcHRpb24gd2l0aCBTdHJpbmcgcGFyYW1ldGVyLgorICAgICAgICBlID0gbmV3IEV4Y2VwdGlvbigidGVzdCBtZXNzYWdlIik7CisgICAgICAgIGZjZSA9IG5ldyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKGUpOworICAgICAgICBhc3NlcnRFcXVhbHMoZS50b1N0cmluZygpLCBmY2UuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGUudG9TdHJpbmcoKSwgZmNlLmdldExvY2FsaXplZE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhlLmdldENhdXNlKCksIGZjZS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19FeGNlcHRpb25MamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgRXhjZXB0aW9uIGUgPSBuZXcgRXhjZXB0aW9uKCk7CisgICAgICAgIC8vIGNhc2UgMTogVHJ5IHRvIGNyZWF0ZSBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yCisgICAgICAgIC8vIHdoaWNoIGlzIGJhc2VkIG9uIEV4Y2VwdGlvbiB3aXRob3V0IHBhcmFtZXRlcnMuCisgICAgICAgIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgZmNlID0gbmV3IEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoZSwgIm1zZyIpOworICAgICAgICBhc3NlcnROb3ROdWxsKGZjZS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKGZjZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZS5nZXRDYXVzZSgpLCBmY2UuZ2V0Q2F1c2UoKSk7CisKKyAgICAgICAgLy8gY2FzZSAyOiBUcnkgdG8gY3JlYXRlIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IKKyAgICAgICAgLy8gd2hpY2ggaXMgYmFzZWQgb24gRXhjZXB0aW9uIHdpdGggU3RyaW5nIHBhcmFtZXRlci4KKyAgICAgICAgZSA9IG5ldyBFeGNlcHRpb24oInRlc3QgbWVzc2FnZSIpOworICAgICAgICBmY2UgPSBuZXcgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcihlLCAibXNnIik7CisgICAgICAgIGFzc2VydEVxdWFscygibXNnIiwgZmNlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibXNnIiwgZmNlLmdldExvY2FsaXplZE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhlLmdldENhdXNlKCksIGZjZS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgZmNlID0gbmV3IEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoIk9vcHMhIik7CisgICAgICAgIGFzc2VydEVxdWFscygiT29wcyEiLCBmY2UuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJPb3BzISIsIGZjZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKGZjZS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEV4Y2VwdGlvbigpIHsKKyAgICAgICAgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBmY2UgPSBuZXcgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcigpOworICAgICAgICBhc3NlcnROdWxsKGZjZS5nZXRFeGNlcHRpb24oKSk7CisgICAgICAgIGZjZSA9IG5ldyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKCJ0ZXN0Iik7CisgICAgICAgIGFzc2VydE51bGwoZmNlLmdldEV4Y2VwdGlvbigpKTsKKyAgICAgICAgRXhjZXB0aW9uIGUgPSBuZXcgRXhjZXB0aW9uKCJtc2ciKTsKKyAgICAgICAgZmNlID0gbmV3IEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhlLCBmY2UuZ2V0RXhjZXB0aW9uKCkpOworICAgICAgICBOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUgPSBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgZmNlID0gbmV3IEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IobnBlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5wZSwgZmNlLmdldEV4Y2VwdGlvbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1lc3NhZ2UoKSB7CisgICAgICAgIGFzc2VydE51bGwobmV3IEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoKS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm1zZzEiLAorICAgICAgICAgICAgICAgIG5ldyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKCJtc2cxIikuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBFeGNlcHRpb24oIm1zZzIiKS50b1N0cmluZygpLAorICAgICAgICAgICAgICAgIG5ldyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEV4Y2VwdGlvbigibXNnMiIpKS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCkudG9TdHJpbmcoKSwKKyAgICAgICAgICAgICAgICBuZXcgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcigKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpKS5nZXRNZXNzYWdlKCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC94bWwvcGFyc2Vycy9QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC94bWwvcGFyc2Vycy9QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQxZmViOWYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3htbC9wYXJzZXJzL1BhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSwzOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4LnhtbC5wYXJzZXJzOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2V7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHBjZSA9IG5ldyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwocGNlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwocGNlLmdldExvY2FsaXplZE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwocGNlLmdldENhdXNlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3JMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBwY2UgPQorICAgICAgICAgICAgbmV3IFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oIk9vcHMhIik7CisgICAgICAgIGFzc2VydEVxdWFscygiT29wcyEiLCBwY2UuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJPb3BzISIsIHBjZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKHBjZS5nZXRDYXVzZSgpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgveG1sL3BhcnNlcnMvU0FYUGFyc2VyRmFjdG9yeVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgveG1sL3BhcnNlcnMvU0FYUGFyc2VyRmFjdG9yeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MTRiOWQ4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC94bWwvcGFyc2Vycy9TQVhQYXJzZXJGYWN0b3J5VGVzdC5qYXZhCkBAIC0wLDAgKzEsNDE1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSB0ZXN0cy5hcGkuamF2YXgueG1sLnBhcnNlcnM7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlcjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcjsKKworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLkFuZHJvaWRPbmx5OworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLktub3duRmFpbHVyZTsKKworcHVibGljIGNsYXNzIFNBWFBhcnNlckZhY3RvcnlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgU0FYUGFyc2VyRmFjdG9yeSBzcGY7CisKKyAgICBJbnB1dFN0cmVhbSBpczE7CisKKyAgICBzdGF0aWMgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4gbnM7CisKKyAgICBzdGF0aWMgVmVjdG9yPFN0cmluZz4gZWw7CisKKyAgICBzdGF0aWMgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4gYXR0cjsKKworICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHNwZiA9IFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKKworICAgICAgICBpczEgPSBnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oIi9zaW1wbGUueG1sIik7CisKKyAgICAgICAgbnMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgYXR0ciA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOworICAgICAgICBlbCA9IG5ldyBWZWN0b3I8U3RyaW5nPigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGlzMS5jbG9zZSgpOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIEBBbmRyb2lkT25seSgiQW5kcm9pZCBTQVggaW1wbGVtZW50YXRpb24gaXMgbm9uLXZhbGlkYXRpbmciKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB7CisgICAgICAgIE15U0FYUGFyc2VyRmFjdG9yeSBtcGYgPSBuZXcgTXlTQVhQYXJzZXJGYWN0b3J5KCk7CisgICAgICAgIGFzc2VydFRydWUobXBmIGluc3RhbmNlb2YgU0FYUGFyc2VyRmFjdG9yeSk7CisgICAgICAgIGFzc2VydEZhbHNlKG1wZi5pc1ZhbGlkYXRpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeSNnZXRTY2hlbWEoKS4KKyAgICAgKiBUQkQgZ2V0U2NoZW1hKCkgSVMgTk9UIFNVUFBPUlRFRAorICAgICAqLworICAgIC8qICAgcHVibGljIHZvaWQgdGVzdF9nZXRTY2hlbWEoKSB7CisgICAgICAgIGFzc2VydE51bGwoc3BmLmdldFNjaGVtYSgpKTsKKyAgICAgICAgU2NoZW1hRmFjdG9yeSBzZiA9CisgICAgICAgICAgICBTY2hlbWFGYWN0b3J5Lm5ld0luc3RhbmNlKFhNTENvbnN0YW50cy5XM0NfWE1MX1NDSEVNQV9OU19VUkkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2NoZW1hIHNjaGVtYSA9IHNmLm5ld1NjaGVtYSgpOworICAgICAgICAgICAgc3BmLnNldFNjaGVtYShzY2hlbWEpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChzcGYuZ2V0U2NoZW1hKCkpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gc2F4KSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgc2F4LnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorICAgICAqLworCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRJc05hbWVzcGFjZUF3YXJlKCkgeworICAgICAgICBzcGYuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoc3BmLmlzTmFtZXNwYWNlQXdhcmUoKSk7CisgICAgICAgIHNwZi5zZXROYW1lc3BhY2VBd2FyZShmYWxzZSk7CisgICAgICAgIGFzc2VydEZhbHNlKHNwZi5pc05hbWVzcGFjZUF3YXJlKCkpOworICAgICAgICBzcGYuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoc3BmLmlzTmFtZXNwYWNlQXdhcmUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRJc1ZhbGlkYXRpbmcoKSB7CisgICAgICAgIHNwZi5zZXRWYWxpZGF0aW5nKHRydWUpOworICAgICAgICBhc3NlcnRUcnVlKHNwZi5pc1ZhbGlkYXRpbmcoKSk7CisgICAgICAgIHNwZi5zZXRWYWxpZGF0aW5nKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc3BmLmlzVmFsaWRhdGluZygpKTsKKyAgICAgICAgc3BmLnNldFZhbGlkYXRpbmcodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoc3BmLmlzVmFsaWRhdGluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldElzWEluY2x1ZGVBd2FyZSgpIHsKKyAgICAgICAgc3BmLnNldFhJbmNsdWRlQXdhcmUodHJ1ZSk7CisgICAgICAgIGFzc2VydFRydWUoc3BmLmlzWEluY2x1ZGVBd2FyZSgpKTsKKyAgICAgICAgc3BmLnNldFhJbmNsdWRlQXdhcmUoZmFsc2UpOworICAgICAgICBhc3NlcnRGYWxzZShzcGYuaXNYSW5jbHVkZUF3YXJlKCkpOworICAgIH0KKworICAgIEBLbm93bkZhaWx1cmUoIkRhbHZpayBkb2Vzbid0IGhvbm9yIHN5c3RlbSBwcm9wZXJ0aWVzIHdoZW4gY2hvb3NpbmcgYSBTQVggaW1wbGVtZW50YXRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfbmV3SW5zdGFuY2UoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTQVhQYXJzZXJGYWN0b3J5IGR0ZiA9IFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIk5ldyBJbnN0YW5jZSBvZiBEYXRhdHlwZUZhY3RvcnkgaXMgbnVsbCIsIGR0Zik7CisKKyAgICAgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgiamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeSIsCisgICAgICAgICAgICAib3JnLmFwYWNoZS5oYXJtb255LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnlJbXBsIik7CisKKyAgICAgICAgICAgIFNBWFBhcnNlckZhY3Rvcnkgc3BmMSA9IFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoc3BmMSBpbnN0YW5jZW9mIG9yZy5hcGFjaGUuaGFybW9ueS54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5SW1wbCk7CisKKyAgICAgICAgICAgIFN0cmluZyBrZXkgPSAiamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeSA9IG9yZy5hcGFjaGUuaGFybW9ueS54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5SW1wbCI7CisKKyAgICAgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShrZXkuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICBQcm9wZXJ0aWVzIHByb3AgPSBTeXN0ZW0uZ2V0UHJvcGVydGllcygpOworICAgICAgICAgICAgcHJvcC5sb2FkKGJpcyk7CisgICAgICAgICAgICBTQVhQYXJzZXJGYWN0b3J5IHNwZjIgPSBTQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHNwZjIgaW5zdGFuY2VvZiBvcmcuYXBhY2hlLmhhcm1vbnkueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeUltcGwpOworCisgICAgICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoImphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnkiLCAiIik7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBpb2UudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X25ld1NBWFBhcnNlcigpIHsKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgU0FYUGFyc2VyIHNwID0gc3BmLm5ld1NBWFBhcnNlcigpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShzcCBpbnN0YW5jZW9mIFNBWFBhcnNlcik7CisgICAgICAgICAgICBzcC5wYXJzZShpczEsIG5ldyBNeUhhbmRsZXIoKSk7CisgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgLy8gRXhjZXB0aW9uIGNhc2UKKyAgICAgICAgc3BmLnNldFZhbGlkYXRpbmcodHJ1ZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTQVhQYXJzZXIgc3AgPSBzcGYubmV3U0FYUGFyc2VyKCk7CisgICAgICAgIH0gY2F0Y2goUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZCwgc2luY2UgQW5kcm9pZCBkb2Vzbid0IGhhdmUgYSB2YWxpZGF0aW5nIHBhcnNlci4KKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRGZWF0dXJlTGphdmFfbGFuZ19TdHJpbmdaKCkgeworICAgICAgICAvLyBXZSBjYW4ndCB2ZXJpZnkgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBhbmQKKyAgICAgICAgLy8gU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHNpbmNlIHRoZXNlIGFyZSBuZXZlcgorICAgICAgICAvLyB0aHJvd24gYnkgQW5kcm9pZC4KKworICAgICAgICBTdHJpbmdbXSBmZWF0dXJlcyA9IHsKKyAgICAgICAgICAgICAgICAiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXMiLAorICAgICAgICAgICAgICAgICJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvdmFsaWRhdGlvbiIgfTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmZWF0dXJlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzcGYuc2V0RmVhdHVyZShmZWF0dXJlc1tpXSwgdHJ1ZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShzcGYuZ2V0RmVhdHVyZShmZWF0dXJlc1tpXSkpOworICAgICAgICAgICAgICAgIHNwZi5zZXRGZWF0dXJlKGZlYXR1cmVzW2ldLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc3BmLmdldEZlYXR1cmUoZmVhdHVyZXNbaV0pKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gcGNlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBpcyB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gc25yZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gaXMgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gc25zZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBpcyB0aHJvd24iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzcGYuc2V0RmVhdHVyZSgiIiwgdHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBwY2UpIHsKKyAgICAgICAgICAgIGZhaWwoIlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gaXMgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gc25yZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9IGNhdGNoIChTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gc25zZSkgeworICAgICAgICAgICAgZmFpbCgiU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIGlzIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGlzIHRocm93biIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNwZi5zZXRGZWF0dXJlKCJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvdW5rbm93bi1mZWF0dXJlIiwgdHJ1ZSk7CisgICAgICAgIH0gY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gcGNlKSB7CisgICAgICAgICAgICBmYWlsKCJQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGlzIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIHNucmUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gaXMgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBzbnNlKSB7CisgICAgICAgICAgICAvLyBBY2NlcHRhYmxlLCBhbHRob3VnaCB0aGlzIGRvZXNuJ3QgaGFwcGVuIGFuIEFuZHJvaWQuCisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gaXMgdGhyb3duIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3BmLnNldEZlYXR1cmUobnVsbCwgdHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gcGNlKSB7CisgICAgICAgICAgICBmYWlsKCJQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGlzIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIHNucmUpIHsKKyAgICAgICAgICAgIGZhaWwoIlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gaXMgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBzbnNlKSB7CisgICAgICAgICAgICBmYWlsKCJTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gaXMgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0TmFtZXNwYWNlQXdhcmVaKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE15SGFuZGxlciBtaCA9IG5ldyBNeUhhbmRsZXIoKTsKKworICAgICAgICBzcGYuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7CisgICAgICAgIElucHV0U3RyZWFtIGlzID0gZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvc2ltcGxlX25zLnhtbCIpOworICAgICAgICBzcGYubmV3U0FYUGFyc2VyKCkucGFyc2UoaXMsIG1oKTsKKyAgICAgICAgaXMuY2xvc2UoKTsKKworICAgICAgICBzcGYuc2V0TmFtZXNwYWNlQXdhcmUoZmFsc2UpOworICAgICAgICBpcyA9IGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbSgiL3NpbXBsZV9ucy54bWwiKTsKKyAgICAgICAgc3BmLm5ld1NBWFBhcnNlcigpLnBhcnNlKGlzLCBtaCk7CisgICAgICAgIGlzLmNsb3NlKCk7CisgICAgfQorCisgICAgLyogICBwdWJsaWMgdm9pZCB0ZXN0X3NldFNjaGVtYUxqYXZheF94bWxfdmFsaWRhdGlvbl9TY2hlbWEoKSB7CisgICAgICAgIFNjaGVtYUZhY3Rvcnkgc2YgPQorICAgICAgICAgICAgU2NoZW1hRmFjdG9yeS5uZXdJbnN0YW5jZShYTUxDb25zdGFudHMuVzNDX1hNTF9TQ0hFTUFfTlNfVVJJKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNjaGVtYSBzY2hlbWEgPSBzZi5uZXdTY2hlbWEoKTsKKyAgICAgICAgICAgIHNwZi5zZXRTY2hlbWEoc2NoZW1hKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc3BmLmdldFNjaGVtYSgpKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIHNheCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIHNheC50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAgKi8KKworLy8gICAgcHVibGljIHZvaWQgdGVzdF9zZXRWYWxpZGF0aW5nWigpIHsKKy8vICAgICAgICBNeUhhbmRsZXIgbWggPSBuZXcgTXlIYW5kbGVyKCk7CisvLyAgICAgICAgSW5wdXRTdHJlYW0gaXMyID0gZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvcmVjaXBlLnhtbCIpOworLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIHNwZi5zZXRWYWxpZGF0aW5nKHRydWUpOworLy8gICAgICAgICAgICBhc3NlcnRUcnVlKHNwZi5pc1ZhbGlkYXRpbmcoKSk7CisvLyAgICAgICAgICAgIHNwZi5uZXdTQVhQYXJzZXIoKS5wYXJzZShpczIsIG1oKTsKKy8vICAgICAgICB9IGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpIHsKKy8vICAgICAgICAgICAgZmFpbCgiU0FYRXhjZXB0aW9uIHdhcyB0aHJvd24gZHVyaW5nIHBhcnNpbmciKTsKKy8vICAgICAgICB9IGNhdGNoIChqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHBjZSkgeworLy8gICAgICAgICAgICBmYWlsKCJQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHdhcyB0aHJvd24gZHVyaW5nIHBhcnNpbmciKTsKKy8vICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKy8vICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gd2FzIHRocm93biBkdXJpbmcgcGFyc2luZyIpOworLy8gICAgICAgIH0gZmluYWxseSB7CisvLyAgICAgICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgICAgICBpczIuY2xvc2UoKTsKKy8vICAgICAgICAgICAgfSBjYXRjaChFeGNlcHRpb24gaW9lZSkge30KKy8vICAgICAgICB9CisvLyAgICAgICAgSW5wdXRTdHJlYW0gaXMzID0gZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvcmVjaXBlMS54bWwiKTsKKy8vICAgICAgICB0cnkgeworLy8gICAgICAgICAgICBhc3NlcnRUcnVlKHNwZi5pc1ZhbGlkYXRpbmcoKSk7CisvLyAgICAgICAgICAgIHNwZi5uZXdTQVhQYXJzZXIoKS5wYXJzZShpczMsIG1oKTsKKy8vICAgICAgICB9IGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpIHsKKy8vICAgICAgICAgICAgZmFpbCgiU0FYRXhjZXB0aW9uIHdhcyB0aHJvd24gZHVyaW5nIHBhcnNpbmciKTsKKy8vICAgICAgICB9IGNhdGNoIChqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHBjZSkgeworLy8gICAgICAgICAgICBmYWlsKCJQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHdhcyB0aHJvd24gZHVyaW5nIHBhcnNpbmciKTsKKy8vICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKy8vICAgICAgICAgICAgZmFpbCgiSU9FWGNlcHRpb24gd2FzIHRocm93biBkdXJpbmcgcGFyc2luZzogIiArIGlvZS5nZXRNZXNzYWdlKCkpOworLy8gICAgICAgIH0gZmluYWxseSB7CisvLyAgICAgICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgICAgICBpczMuY2xvc2UoKTsKKy8vICAgICAgICAgICAgfSBjYXRjaChFeGNlcHRpb24gaW9lZSkge30KKy8vICAgICAgICB9CisvLyAgICAgICAgaXMyID0gZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvcmVjaXBlLnhtbCIpOworLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIHNwZi5zZXRWYWxpZGF0aW5nKGZhbHNlKTsKKy8vICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoc3BmLmlzVmFsaWRhdGluZygpKTsKKy8vICAgICAgICAgICAgc3BmLm5ld1NBWFBhcnNlcigpLnBhcnNlKGlzMiwgbWgpOworLy8gICAgICAgIH0gY2F0Y2ggKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkgeworLy8gICAgICAgICAgICBmYWlsKCJTQVhFeGNlcHRpb24gd2FzIHRocm93biBkdXJpbmcgcGFyc2luZyIpOworLy8gICAgICAgIH0gY2F0Y2ggKGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gcGNlKSB7CisvLyAgICAgICAgICAgIGZhaWwoIlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gd2FzIHRocm93biBkdXJpbmcgcGFyc2luZyIpOworLy8gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworLy8gICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duIGR1cmluZyBwYXJzaW5nIik7CisvLyAgICAgICAgfSBmaW5hbGx5IHsKKy8vICAgICAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgICAgIGlzMi5jbG9zZSgpOworLy8gICAgICAgICAgICB9IGNhdGNoKEV4Y2VwdGlvbiBpb2VlKSB7fQorLy8gICAgICAgIH0KKy8vICAgICAgICBpczMgPSBnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oIi9yZWNpcGUxLnhtbCIpOworLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIGFzc2VydEZhbHNlKHNwZi5pc1ZhbGlkYXRpbmcoKSk7CisvLyAgICAgICAgICAgIHNwZi5uZXdTQVhQYXJzZXIoKS5wYXJzZShpczMsIG1oKTsKKy8vICAgICAgICB9IGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpIHsKKy8vICAgICAgICAgICAgZmFpbCgiU0FYRXhjZXB0aW9uIHdhcyB0aHJvd24gZHVyaW5nIHBhcnNpbmciKTsKKy8vICAgICAgICB9IGNhdGNoIChqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHBjZSkgeworLy8gICAgICAgICAgICBmYWlsKCJQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHdhcyB0aHJvd24gZHVyaW5nIHBhcnNpbmciKTsKKy8vICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKy8vICAgICAgICAgICAgZmFpbCgiSU9FWGNlcHRpb24gd2FzIHRocm93biBkdXJpbmcgcGFyc2luZzogIiArIGlvZS5nZXRNZXNzYWdlKCkpOworLy8gICAgICAgIH0gZmluYWxseSB7CisvLyAgICAgICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgICAgICBpczMuY2xvc2UoKTsKKy8vICAgICAgICAgICAgfSBjYXRjaChFeGNlcHRpb24gaW9lZSkge30KKy8vICAgICAgICB9CisvLyAgICB9CisKKy8vICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0WEluY2x1ZGVBd2FyZVooKSB7CisvLyAgICAgICAgc3BmLnNldFhJbmNsdWRlQXdhcmUodHJ1ZSk7CisvLyAgICAgICAgTXlIYW5kbGVyIG1oID0gbmV3IE15SGFuZGxlcigpOworLy8gICAgICAgIElucHV0U3RyZWFtIGlzID0gZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvc2ltcGxlX25zLnhtbCIpOworLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIHNwZi5uZXdTQVhQYXJzZXIoKS5wYXJzZShpcywgbWgpOworLy8gICAgICAgIH0gY2F0Y2goamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBwY2UpIHsKKy8vICAgICAgICAgICAgZmFpbCgiUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB3YXMgdGhyb3duIGR1cmluZyBwYXJzaW5nIik7CisvLyAgICAgICAgfSBjYXRjaChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpIHsKKy8vICAgICAgICAgICAgZmFpbCgiU0FYRXhjZXB0aW9uIHdhcyB0aHJvd24gZHVyaW5nIHBhcnNpbmciKTsKKy8vICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGlvZSkgeworLy8gICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duIGR1cmluZyBwYXJzaW5nIik7CisvLyAgICAgICAgfSBmaW5hbGx5IHsKKy8vICAgICAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgICAgIGlzLmNsb3NlKCk7CisvLyAgICAgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGlvZWUpIHt9CisvLyAgICAgICAgfQorLy8gICAgICAgIHNwZi5zZXRYSW5jbHVkZUF3YXJlKGZhbHNlKTsKKy8vICAgICAgICBpcyA9IGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbSgiL3NpbXBsZV9ucy54bWwiKTsKKy8vICAgICAgICB0cnkgeworLy8gICAgICAgICAgICBpcyA9IGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbSgiL3NpbXBsZV9ucy54bWwiKTsKKy8vICAgICAgICAgICAgc3BmLm5ld1NBWFBhcnNlcigpLnBhcnNlKGlzLCBtaCk7CisvLyAgICAgICAgfSBjYXRjaChqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHBjZSkgeworLy8gICAgICAgICAgICBmYWlsKCJQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHdhcyB0aHJvd24gZHVyaW5nIHBhcnNpbmciKTsKKy8vICAgICAgICB9IGNhdGNoKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkgeworLy8gICAgICAgICAgICBmYWlsKCJTQVhFeGNlcHRpb24gd2FzIHRocm93biBkdXJpbmcgcGFyc2luZyIpOworLy8gICAgICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gaW9lKSB7CisvLyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIHdhcyB0aHJvd24gZHVyaW5nIHBhcnNpbmciKTsKKy8vICAgICAgICB9IGZpbmFsbHkgeworLy8gICAgICAgICAgICB0cnkgeworLy8gICAgICAgICAgICAgICAgaXMuY2xvc2UoKTsKKy8vICAgICAgICAgICAgfSBjYXRjaChFeGNlcHRpb24gaW9lZSkge30KKy8vICAgICAgICB9CisvLyAgICAgICAgaXMgPSBnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oIi9zaW1wbGVfbnMueG1sIik7CisvLyAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgc3BmLnNldFhJbmNsdWRlQXdhcmUodHJ1ZSk7CisvLyAgICAgICAgICAgIHNwZi5uZXdTQVhQYXJzZXIoKS5wYXJzZShpcywgbWgpOworLy8gICAgICAgIH0gY2F0Y2goamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBwY2UpIHsKKy8vICAgICAgICAgICAgZmFpbCgiUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB3YXMgdGhyb3duIGR1cmluZyBwYXJzaW5nIik7CisvLyAgICAgICAgfSBjYXRjaChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpIHsKKy8vICAgICAgICAgICAgZmFpbCgiU0FYRXhjZXB0aW9uIHdhcyB0aHJvd24gZHVyaW5nIHBhcnNpbmciKTsKKy8vICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGlvZSkgeworLy8gICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXMgdGhyb3duIGR1cmluZyBwYXJzaW5nIik7CisvLyAgICAgICAgfSBmaW5hbGx5IHsKKy8vICAgICAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgICAgIGlzLmNsb3NlKCk7CisvLyAgICAgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGlvZWUpIHt9CisvLyAgICAgICAgfQorLy8gICAgfQorCisgICAgc3RhdGljIGNsYXNzIE15SGFuZGxlciBleHRlbmRzIERlZmF1bHRIYW5kbGVyIHsKKworICAgICAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lLAorICAgICAgICAgICAgICAgIEF0dHJpYnV0ZXMgYXR0cykgeworCisgICAgICAgICAgICBlbC5hZGQocU5hbWUpOworICAgICAgICAgICAgaWYgKCF1cmkuZXF1YWxzKCIiKSkKKyAgICAgICAgICAgICAgICBucy5wdXQocU5hbWUsIHVyaSk7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGF0dHMuZ2V0TGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgICAgIGF0dHIucHV0KGF0dHMuZ2V0UU5hbWUoaSksIGF0dHMuZ2V0VmFsdWUoaSkpOworICAgICAgICAgICAgfQorCisgICAgICAgIH0KKyAgICB9CisKKyAgICBjbGFzcyBNeVNBWFBhcnNlckZhY3RvcnkgZXh0ZW5kcyBTQVhQYXJzZXJGYWN0b3J5IHsKKworICAgICAgICBwdWJsaWMgTXlTQVhQYXJzZXJGYWN0b3J5KCkgeworICAgICAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTQVhQYXJzZXIgbmV3U0FYUGFyc2VyKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKSB0aHJvd3MKKyAgICAgICAgICAgICAgICBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLCBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7CisKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpIHRocm93cworICAgICAgICAgICAgICAgIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24sIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgveG1sL3BhcnNlcnMvU0FYUGFyc2VyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC94bWwvcGFyc2Vycy9TQVhQYXJzZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzU4NjE2MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvamF2YXgveG1sL3BhcnNlcnMvU0FYUGFyc2VyVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTIyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4LnhtbC5wYXJzZXJzOworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uS25vd25GYWlsdXJlOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlcjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBvcmcueG1sLnNheC5IYW5kbGVyQmFzZTsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKK2ltcG9ydCBvcmcueG1sLnNheC5QYXJzZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcjsKK2ltcG9ydCB0ZXN0cy5hcGkuamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyVGVzdFN1cHBvcnQuTXlEZWZhdWx0SGFuZGxlcjsKK2ltcG9ydCB0ZXN0cy5hcGkuamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyVGVzdFN1cHBvcnQuTXlIYW5kbGVyOworaW1wb3J0IHRlc3RzLmFwaS5vcmcueG1sLnNheC5zdXBwb3J0LkJyb2tlbklucHV0U3RyZWFtOworaW1wb3J0IHRlc3RzLmFwaS5vcmcueG1sLnNheC5zdXBwb3J0Lk1ldGhvZExvZ2dlcjsKK2ltcG9ydCB0ZXN0cy5hcGkub3JnLnhtbC5zYXguc3VwcG9ydC5Nb2NrSGFuZGxlcjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LnJlc291cmNlLlN1cHBvcnRfUmVzb3VyY2VzOworCitAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorcHVibGljIGNsYXNzIFNBWFBhcnNlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIGNsYXNzIE1vY2tTQVhQYXJzZXIgZXh0ZW5kcyBTQVhQYXJzZXIgeworICAgICAgICBwdWJsaWMgTW9ja1NBWFBhcnNlcigpIHsKKyAgICAgICAgICAgIHN1cGVyKCk7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBAc2VlIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlciNnZXRQYXJzZXIoKQorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBQYXJzZXIgZ2V0UGFyc2VyKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBpdCBpcyBhIGZha2UKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogQHNlZSBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXIjZ2V0UHJvcGVydHkoamF2YS5sYW5nLlN0cmluZykKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICAgICAgLy8gaXQgaXMgYSBmYWtlCisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIEBzZWUgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyI2dldFhNTFJlYWRlcigpCisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFhNTFJlYWRlciBnZXRYTUxSZWFkZXIoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIC8vIGl0IGlzIGEgZmFrZQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBAc2VlIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlciNpc05hbWVzcGFjZUF3YXJlKCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc05hbWVzcGFjZUF3YXJlKCkgeworICAgICAgICAgICAgLy8gaXQgaXMgYSBmYWtlCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBAc2VlIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlciNpc1ZhbGlkYXRpbmcoKQorICAgICAgICAgKi8KKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzVmFsaWRhdGluZygpIHsKKyAgICAgICAgICAgIC8vIGl0IGlzIGEgZmFrZQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogQHNlZSBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXIjc2V0UHJvcGVydHkoamF2YS5sYW5nLlN0cmluZywKKyAgICAgICAgICogamF2YS5sYW5nLk9iamVjdCkKKyAgICAgICAgICovCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKSB0aHJvd3MKKyAgICAgICAgICAgICAgICBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICAgICAgLy8gaXQgaXMgYSBmYWtlCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTEVYSUNBTF9IQU5ETEVSX1BST1BFUlRZCisgICAgICAgICAgICA9ICJodHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy9sZXhpY2FsLWhhbmRsZXIiOworCisgICAgU0FYUGFyc2VyRmFjdG9yeSBzcGY7CisKKyAgICBTQVhQYXJzZXIgcGFyc2VyOworCisgICAgc3RhdGljIEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IG5zOworCisgICAgc3RhdGljIFZlY3RvcjxTdHJpbmc+IGVsOworCisgICAgc3RhdGljIEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IGF0dHI7CisKKyAgICBTQVhQYXJzZXJUZXN0U3VwcG9ydCBzcCA9IG5ldyBTQVhQYXJzZXJUZXN0U3VwcG9ydCgpOworCisgICAgRmlsZSBbXSBsaXN0X3dmOworICAgIEZpbGUgW10gbGlzdF9ud2Y7CisgICAgRmlsZSBbXSBsaXN0X291dF9kaDsKKyAgICBGaWxlIFtdIGxpc3Rfb3V0X2hiOworCisgICAgYm9vbGVhbiB2YWxpZGF0aW5nID0gZmFsc2U7CisKKyAgICBwcml2YXRlIElucHV0U3RyZWFtIGdldFJlc291cmNlKFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiB0aGlzLmdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbShuYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBpbml0RmlsZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gd2UgZGlmZmVybnRpYXRlIGJldHdlZW4gYSB2YWxpZGF0aW5nIGFuZCBhIG5vbiB2YWxpZGF0aW5nIHBhcnNlcgorICAgICAgICB0cnkgeworICAgICAgICAgICAgU0FYUGFyc2VyIHBhcnNlciA9IFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKS5uZXdTQVhQYXJzZXIoKTsKKyAgICAgICAgICAgIHZhbGlkYXRpbmcgPSBwYXJzZXIuaXNWYWxpZGF0aW5nKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJjb3VsZCBub3Qgb2J0YWluIGEgU0FYUGFyc2VyIik7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgdG1wUGF0aCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5pby50bXBkaXIiKTsKKworICAgICAgICAvLyBud2YgPSBub3Qgd2VsbCBmb3JtZWQsIHdmID0gd2VsbCBmb3JtZWQKKyAgICAgICAgbGlzdF93ZiA9IG5ldyBGaWxlW10ge25ldyBGaWxlKHRtcFBhdGggKyAiLyIgKworICAgICAgICAgICAgICAgIFNBWFBhcnNlclRlc3RTdXBwb3J0LlhNTF9XRiArICJzdGFmZi54bWwiKX07CisgICAgICAgIGxpc3RfbndmID0gbmV3IEZpbGVbXSB7bmV3IEZpbGUodG1wUGF0aCArICIvIiArCisgICAgICAgICAgICAgICAgU0FYUGFyc2VyVGVzdFN1cHBvcnQuWE1MX05XRiArICJzdGFmZi54bWwiKX07CisgICAgICAgIGxpc3Rfb3V0X2RoID0gbmV3IEZpbGVbXSB7bmV3IEZpbGUodG1wUGF0aCArICIvIiArCisgICAgICAgICAgICAgICAgU0FYUGFyc2VyVGVzdFN1cHBvcnQuWE1MX1dGX09VVF9ESCArICJzdGFmZi5vdXQiKX07CisgICAgICAgIGxpc3Rfb3V0X2hiID0gbmV3IEZpbGVbXSB7bmV3IEZpbGUodG1wUGF0aCArICIvIiArCisgICAgICAgICAgICAgICAgU0FYUGFyc2VyVGVzdFN1cHBvcnQuWE1MX1dGX09VVF9IQiArICJzdGFmZi5vdXQiKX07CisKKyAgICAgICAgbGlzdF93ZlswXS5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgbGlzdF9ud2ZbMF0uZGVsZXRlT25FeGl0KCk7CisgICAgICAgIGxpc3Rfb3V0X2hiWzBdLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICBsaXN0X291dF9kaFswXS5kZWxldGVPbkV4aXQoKTsKKworCisgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlMb2NhbEZpbGV0byhsaXN0X3dmWzBdLAorICAgICAgICAgICAgICAgIGdldFJlc291cmNlKFNBWFBhcnNlclRlc3RTdXBwb3J0LlhNTF9XRiArICJzdGFmZi54bWwiKSk7CisgICAgICAgIFN1cHBvcnRfUmVzb3VyY2VzLmNvcHlMb2NhbEZpbGV0byhuZXcgRmlsZSgKKyAgICAgICAgICAgICAgICB0bXBQYXRoICsgIi8iICsgU0FYUGFyc2VyVGVzdFN1cHBvcnQuWE1MX1dGICsgInN0YWZmLmR0ZCIpLAorICAgICAgICAgICAgICAgIGdldFJlc291cmNlKFNBWFBhcnNlclRlc3RTdXBwb3J0LlhNTF9XRiArICJzdGFmZi5kdGQiKSk7CisKKyAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUxvY2FsRmlsZXRvKGxpc3RfbndmWzBdLAorICAgICAgICAgICAgICAgIGdldFJlc291cmNlKFNBWFBhcnNlclRlc3RTdXBwb3J0LlhNTF9OV0YgKyAic3RhZmYueG1sIikpOworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5TG9jYWxGaWxldG8obmV3IEZpbGUoCisgICAgICAgICAgICAgICAgdG1wUGF0aCArICIvIiArIFNBWFBhcnNlclRlc3RTdXBwb3J0LlhNTF9OV0YgKyAic3RhZmYuZHRkIiksCisgICAgICAgICAgICAgICAgZ2V0UmVzb3VyY2UoU0FYUGFyc2VyVGVzdFN1cHBvcnQuWE1MX05XRiArICJzdGFmZi5kdGQiKSk7CisKKyAgICAgICAgU3VwcG9ydF9SZXNvdXJjZXMuY29weUxvY2FsRmlsZXRvKGxpc3Rfb3V0X2RoWzBdLAorICAgICAgICAgICAgICAgIGdldFJlc291cmNlKFNBWFBhcnNlclRlc3RTdXBwb3J0LlhNTF9XRl9PVVRfREggKyAic3RhZmYub3V0IikpOworICAgICAgICBTdXBwb3J0X1Jlc291cmNlcy5jb3B5TG9jYWxGaWxldG8obGlzdF9vdXRfaGJbMF0sCisgICAgICAgICAgICAgICAgZ2V0UmVzb3VyY2UoU0FYUGFyc2VyVGVzdFN1cHBvcnQuWE1MX1dGX09VVF9IQiArICJzdGFmZi5vdXQiKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3BmID0gU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICAgICAgICBwYXJzZXIgPSBzcGYubmV3U0FYUGFyc2VyKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwocGFyc2VyKTsKKworICAgICAgICBucyA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOworICAgICAgICBhdHRyID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgICAgIGVsID0gbmV3IFZlY3RvcjxTdHJpbmc+KCk7CisgICAgICAgIGluaXRGaWxlcygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgfQorCisvLyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKy8vICAgICAgICBTQVhQYXJzZXJUZXN0IHN0ID0gbmV3IFNBWFBhcnNlclRlc3QoKTsKKy8vICAgICAgICBzdC5zZXRVcCgpOworLy8gICAgICAgIHN0LmdlbmVyYXRlRGF0YUZyb21SZWZlcmVuY2VJbXBsKCk7CisvLworLy8gICAgfQorLy8KKy8vICAgIHByaXZhdGUgdm9pZCBnZW5lcmF0ZURhdGFGcm9tUmVmZXJlbmNlSW1wbCgpIHsKKy8vICAgICAgICB0cnkgeworLy8gICAgICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbGlzdF93Zi5sZW5ndGg7IGkrKykgeworLy8gICAgICAgICAgICAgICAgTXlEZWZhdWx0SGFuZGxlciBkaCA9IG5ldyBNeURlZmF1bHRIYW5kbGVyKCk7CisvLyAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0obGlzdF93ZltpXSk7CisvLyAgICAgICAgICAgICAgICBwYXJzZXIucGFyc2UoaXMsIGRoLCBQYXJzaW5nU3VwcG9ydC5YTUxfU1lTVEVNX0lEKTsKKy8vICAgICAgICAgICAgICAgIEhhc2hNYXAgcmVmSG0gPSBkaC5jcmVhdGVEYXRhKCk7CisvLworLy8gICAgICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisvLyAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IFBhcnNpbmdTdXBwb3J0LktFWVMubGVuZ3RoOyBqKyspIHsKKy8vICAgICAgICAgICAgICAgICAgICBTdHJpbmcga2V5ID0gUGFyc2luZ1N1cHBvcnQuS0VZU1tqXTsKKy8vICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQocmVmSG0uZ2V0KGtleSkpLmFwcGVuZCgKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcnNpbmdTdXBwb3J0LlNFUEFSQVRPUl9EQVRBKTsKKy8vICAgICAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgICAgIEZpbGVXcml0ZXIgZncgPSBuZXcgRmlsZVdyaXRlcigiL3RtcC9idWlsZF9kaCIraSsiLm91dCIpOworLy8gICAgICAgICAgICAgICAgZncuYXBwZW5kKHNiLnRvU3RyaW5nKCkpOworLy8gICAgICAgICAgICAgICAgZncuY2xvc2UoKTsKKy8vICAgICAgICAgICAgfQorLy8KKy8vICAgICAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGxpc3RfbndmLmxlbmd0aDsgaSsrKSB7CisvLyAgICAgICAgICAgICAgICBNeUhhbmRsZXIgaGIgPSBuZXcgTXlIYW5kbGVyKCk7CisvLyAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0obGlzdF93ZltpXSk7CisvLyAgICAgICAgICAgICAgICBwYXJzZXIucGFyc2UoaXMsIGhiLCBQYXJzaW5nU3VwcG9ydC5YTUxfU1lTVEVNX0lEKTsKKy8vICAgICAgICAgICAgICAgIEhhc2hNYXAgcmVmSG0gPSBoYi5jcmVhdGVEYXRhKCk7CisvLworLy8gICAgICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisvLyAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IFBhcnNpbmdTdXBwb3J0LktFWVMubGVuZ3RoOyBqKyspIHsKKy8vICAgICAgICAgICAgICAgICAgICBTdHJpbmcga2V5ID0gUGFyc2luZ1N1cHBvcnQuS0VZU1tqXTsKKy8vICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQocmVmSG0uZ2V0KGtleSkpLmFwcGVuZCgKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcnNpbmdTdXBwb3J0LlNFUEFSQVRPUl9EQVRBKTsKKy8vICAgICAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgICAgIEZpbGVXcml0ZXIgZncgPSBuZXcgRmlsZVdyaXRlcigiL3RtcC9idWlsZF9oYiIraSsiLm91dCIpOworLy8gICAgICAgICAgICAgICAgZncuYXBwZW5kKHNiLnRvU3RyaW5nKCkpOworLy8gICAgICAgICAgICAgICAgZncuY2xvc2UoKTsKKy8vICAgICAgICAgICAgfQorLy8KKy8vCisvLyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKy8vICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKy8vICAgICAgICB9CisvLyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U0FYUGFyc2VyKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IE1vY2tTQVhQYXJzZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YXgueG1sLnBhcnNlci5TQVhQYXJzZXIjZ2V0U2NoZW1hKCkuCisgICAgICogVE9ETyBnZXRTY2hlbWEoKSBJUyBOT1QgU1VQUE9SVEVECisgICAgICovCisgICAgLyogICBwdWJsaWMgdm9pZCB0ZXN0X2dldFNjaGVtYSgpIHsKKyAgICAgICAgYXNzZXJ0TnVsbChwYXJzZXIuZ2V0U2NoZW1hKCkpOworICAgICAgICBTY2hlbWFGYWN0b3J5IHNmID0KKyAgICAgICAgICAgIFNjaGVtYUZhY3RvcnkubmV3SW5zdGFuY2UoWE1MQ29uc3RhbnRzLlczQ19YTUxfU0NIRU1BX05TX1VSSSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTY2hlbWEgc2NoZW1hID0gc2YubmV3U2NoZW1hKCk7CisgICAgICAgICAgICBzcGYuc2V0U2NoZW1hKHNjaGVtYSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHNwZi5uZXdTQVhQYXJzZXIoKS5nZXRTY2hlbWEoKSk7CisgICAgICAgIH0gY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gcGNlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gIiArIHBjZS50b1N0cmluZygpKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIHNheCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTQVhFeGNlcHRpb24gIiArIHNheC50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAgKi8KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJc05hbWVzcGFjZUF3YXJlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3BmLnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShzcGYubmV3U0FYUGFyc2VyKCkuaXNOYW1lc3BhY2VBd2FyZSgpKTsKKyAgICAgICAgICAgIHNwZi5zZXROYW1lc3BhY2VBd2FyZShmYWxzZSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShzcGYubmV3U0FYUGFyc2VyKCkuaXNOYW1lc3BhY2VBd2FyZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdElzVmFsaWRhdGluZygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNwZi5zZXRWYWxpZGF0aW5nKGZhbHNlKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHNwZi5uZXdTQVhQYXJzZXIoKS5pc1ZhbGlkYXRpbmcoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJc1hJbmNsdWRlQXdhcmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzcGYuc2V0WEluY2x1ZGVBd2FyZShmYWxzZSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShzcGYubmV3U0FYUGFyc2VyKCkuaXNYSW5jbHVkZUF3YXJlKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGVzdCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXIjcGFyc2UoamF2YS5pby5GaWxlLAorICAgICAqICAgICBvcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfcGFyc2VMamF2YV9pb19GaWxlTG9yZ194bWxfc2F4X2hlbHBlcnNfRGVmYXVsdEhhbmRsZXIoKQorICAgIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBsaXN0X3dmLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBIYXNoTWFwPFN0cmluZywgU3RyaW5nPiBobSA9CisgICAgICAgICAgICAgICAgbmV3IFNBWFBhcnNlclRlc3RTdXBwb3J0KCkucmVhZEZpbGUobGlzdF9vdXRfZGhbaV0uZ2V0UGF0aCgpKTsKKyAgICAgICAgICAgIE15RGVmYXVsdEhhbmRsZXIgZGggPSBuZXcgTXlEZWZhdWx0SGFuZGxlcigpOworICAgICAgICAgICAgcGFyc2VyLnBhcnNlKGxpc3Rfd2ZbaV0sIGRoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoU0FYUGFyc2VyVGVzdFN1cHBvcnQuZXF1YWxzTWFwcyhobSwgZGguY3JlYXRlRGF0YSgpKSk7CisgICAgICAgIH0KKworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbGlzdF9ud2YubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTXlEZWZhdWx0SGFuZGxlciBkaCA9IG5ldyBNeURlZmF1bHRIYW5kbGVyKCk7CisgICAgICAgICAgICAgICAgcGFyc2VyLnBhcnNlKGxpc3RfbndmW2ldLCBkaCk7CisgICAgICAgICAgICAgICAgZmFpbCgiU0FYRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2gob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE15RGVmYXVsdEhhbmRsZXIgZGggPSBuZXcgTXlEZWZhdWx0SGFuZGxlcigpOworICAgICAgICAgICAgcGFyc2VyLnBhcnNlKChGaWxlKSBudWxsLCBkaCk7CisgICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaChqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcnNlci5wYXJzZShsaXN0X3dmWzBdLCAoRGVmYXVsdEhhbmRsZXIpIG51bGwpOworICAgICAgICB9IGNhdGNoKGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93biIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlRmlsZUhhbmRsZXJCYXNlKCkgeworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbGlzdF93Zi5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBIYXNoTWFwPFN0cmluZywgU3RyaW5nPiBobSA9IHNwLnJlYWRGaWxlKAorICAgICAgICAgICAgICAgICAgICAgICAgbGlzdF9vdXRfaGJbaV0uZ2V0UGF0aCgpKTsKKyAgICAgICAgICAgICAgICBNeUhhbmRsZXIgZGggPSBuZXcgTXlIYW5kbGVyKCk7CisgICAgICAgICAgICAgICAgcGFyc2VyLnBhcnNlKGxpc3Rfd2ZbaV0sIGRoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKFNBWFBhcnNlclRlc3RTdXBwb3J0LmVxdWFsc01hcHMoaG0sCisgICAgICAgICAgICAgICAgICAgICAgICBkaC5jcmVhdGVEYXRhKCkpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gIiArIGlvZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzYXgpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNBWEV4Y2VwdGlvbiAiICsgc2F4LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGxpc3RfbndmLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIE15SGFuZGxlciBkaCA9IG5ldyBNeUhhbmRsZXIoKTsKKyAgICAgICAgICAgICAgICBwYXJzZXIucGFyc2UobGlzdF9ud2ZbaV0sIGRoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTQVhFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZm5lKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBGaWxlTm90Rm91bmRFeGNlcHRpb24gIiArIGZuZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gIiArIGlvZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNeUhhbmRsZXIgZGggPSBuZXcgTXlIYW5kbGVyKCk7CisgICAgICAgICAgICBwYXJzZXIucGFyc2UoKEZpbGUpIG51bGwsIGRoKTsKKyAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoKGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgaW9lLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoKFNBWEV4Y2VwdGlvbiBzYXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU0FYRXhjZXB0aW9uICIgKyBzYXgudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFyc2VyLnBhcnNlKGxpc3Rfd2ZbMF0sIChIYW5kbGVyQmFzZSkgbnVsbCk7CisgICAgICAgIH0gY2F0Y2goamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBmbmUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgRmlsZU5vdEZvdW5kRXhjZXB0aW9uICIgKyBmbmUudG9TdHJpbmcoKSk7CisgICAgICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uICIgKyBpb2UudG9TdHJpbmcoKSk7CisgICAgICAgIH0gY2F0Y2goU0FYRXhjZXB0aW9uIHNheCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTQVhFeGNlcHRpb24gIiArIHNheC50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEB0ZXN0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlciNwYXJzZShvcmcueG1sLnNheC5JbnB1dFNvdXJjZSwKKyAgICAgKiAgICAgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BhcnNlTG9yZ194bWxfc2F4X0lucHV0U291cmNlTG9yZ194bWxfc2F4X2hlbHBlcnNfRGVmYXVsdEhhbmRsZXIoKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBsaXN0X3dmLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBIYXNoTWFwPFN0cmluZywgU3RyaW5nPiBobSA9IG5ldyBTQVhQYXJzZXJUZXN0U3VwcG9ydCgpLnJlYWRGaWxlKAorICAgICAgICAgICAgICAgICAgICBsaXN0X291dF9kaFtpXS5nZXRQYXRoKCkpOworICAgICAgICAgICAgTXlEZWZhdWx0SGFuZGxlciBkaCA9IG5ldyBNeURlZmF1bHRIYW5kbGVyKCk7CisgICAgICAgICAgICBJbnB1dFNvdXJjZSBpcyA9IG5ldyBJbnB1dFNvdXJjZShuZXcgRmlsZUlucHV0U3RyZWFtKGxpc3Rfd2ZbaV0pKTsKKyAgICAgICAgICAgIHBhcnNlci5wYXJzZShpcywgZGgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShTQVhQYXJzZXJUZXN0U3VwcG9ydC5lcXVhbHNNYXBzKGhtLCBkaC5jcmVhdGVEYXRhKCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoRmlsZSBmaWxlIDogbGlzdF9ud2YpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTXlEZWZhdWx0SGFuZGxlciBkaCA9IG5ldyBNeURlZmF1bHRIYW5kbGVyKCk7CisgICAgICAgICAgICAgICAgSW5wdXRTb3VyY2UgaXMgPSBuZXcgSW5wdXRTb3VyY2UobmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKSk7CisgICAgICAgICAgICAgICAgcGFyc2VyLnBhcnNlKGlzLCBkaCk7CisgICAgICAgICAgICAgICAgZmFpbCgiU0FYRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE15RGVmYXVsdEhhbmRsZXIgZGggPSBuZXcgTXlEZWZhdWx0SGFuZGxlcigpOworICAgICAgICAgICAgcGFyc2VyLnBhcnNlKChJbnB1dFNvdXJjZSkgbnVsbCwgZGgpOworICAgICAgICAgICAgZmFpbCgiamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgSW5wdXRTb3VyY2UgaXMgPSBuZXcgSW5wdXRTb3VyY2UobmV3IEZpbGVJbnB1dFN0cmVhbShsaXN0X3dmWzBdKSk7CisgICAgICAgIHBhcnNlci5wYXJzZShpcywgKERlZmF1bHRIYW5kbGVyKSBudWxsKTsKKworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbiA9IG5ldyBCcm9rZW5JbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGxpc3Rfd2ZbMF0pLCAxMCk7CisgICAgICAgICAgICBpcyA9IG5ldyBJbnB1dFNvdXJjZShpbik7CisgICAgICAgICAgICBwYXJzZXIucGFyc2UoaXMsIChEZWZhdWx0SGFuZGxlcikgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlSW5wdXRTb3VyY2VIYW5kbGVyQmFzZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbGlzdF93Zi5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4gaG0gPSBzcC5yZWFkRmlsZShsaXN0X291dF9oYltpXS5nZXRQYXRoKCkpOworICAgICAgICAgICAgTXlIYW5kbGVyIGRoID0gbmV3IE15SGFuZGxlcigpOworICAgICAgICAgICAgSW5wdXRTb3VyY2UgaXMgPSBuZXcgSW5wdXRTb3VyY2UobmV3IEZpbGVJbnB1dFN0cmVhbShsaXN0X3dmW2ldKSk7CisgICAgICAgICAgICBwYXJzZXIucGFyc2UoaXMsIGRoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoU0FYUGFyc2VyVGVzdFN1cHBvcnQuZXF1YWxzTWFwcyhobSwgZGguY3JlYXRlRGF0YSgpKSk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEZpbGUgZmlsZSA6IGxpc3RfbndmKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIE15SGFuZGxlciBkaCA9IG5ldyBNeUhhbmRsZXIoKTsKKyAgICAgICAgICAgICAgICBJbnB1dFNvdXJjZSBpcyA9IG5ldyBJbnB1dFNvdXJjZShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpKTsKKyAgICAgICAgICAgICAgICBwYXJzZXIucGFyc2UoaXMsIGRoKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTQVhFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTXlIYW5kbGVyIGRoID0gbmV3IE15SGFuZGxlcigpOworICAgICAgICAgICAgcGFyc2VyLnBhcnNlKChJbnB1dFNvdXJjZSkgbnVsbCwgZGgpOworICAgICAgICAgICAgZmFpbCgiamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKworICAgICAgICBJbnB1dFNvdXJjZSBpcyA9IG5ldyBJbnB1dFNvdXJjZShuZXcgRmlsZUlucHV0U3RyZWFtKGxpc3Rfd2ZbMF0pKTsKKyAgICAgICAgcGFyc2VyLnBhcnNlKGlzLCAoSGFuZGxlckJhc2UpIG51bGwpOworCisgICAgICAgIC8vIFJlYWRlciBjYXNlCisgICAgICAgIGlzID0gbmV3IElucHV0U291cmNlKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihuZXcgRmlsZUlucHV0U3RyZWFtKGxpc3Rfd2ZbMF0pKSk7CisgICAgICAgIHBhcnNlci5wYXJzZShpcywgKEhhbmRsZXJCYXNlKSBudWxsKTsKKworICAgICAgICAvLyBTeXN0ZW1JRCBjYXNlCisgICAgICAgIGlzID0gbmV3IElucHV0U291cmNlKGxpc3Rfd2ZbMF0udG9VUkkoKS50b1N0cmluZygpKTsKKyAgICAgICAgcGFyc2VyLnBhcnNlKGlzLCAoSGFuZGxlckJhc2UpIG51bGwpOworCisgICAgICAgIC8vIEluamVjdCBJT0V4Y2VwdGlvbgorICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbiA9IG5ldyBCcm9rZW5JbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGxpc3Rfd2ZbMF0pLCAxMCk7CisgICAgICAgICAgICBwYXJzZXIucGFyc2UoaW4sIChIYW5kbGVyQmFzZSkgbnVsbCwgU0FYUGFyc2VyVGVzdFN1cHBvcnQuWE1MX1NZU1RFTV9JRCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRlc3QgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyI3BhcnNlKGphdmEuaW8uSW5wdXRTdHJlYW0sCisgICAgICogICAgIG9yZy54bWwuc2F4LmhlbHBlcnMuRGVmYXVsdEhhbmRsZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wYXJzZUxqYXZhX2lvX0lucHV0U3RyZWFtTG9yZ194bWxfc2F4X2hlbHBlcnNfRGVmYXVsdEhhbmRsZXIoKQorICAgIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBsaXN0X3dmLmxlbmd0aDsgaSsrKSB7CisKKyAgICAgICAgICAgIEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IGhtID0gbmV3IFNBWFBhcnNlclRlc3RTdXBwb3J0KCkucmVhZEZpbGUoCisgICAgICAgICAgICAgICAgICAgIGxpc3Rfb3V0X2RoW2ldLmdldFBhdGgoKSk7CisgICAgICAgICAgICBNeURlZmF1bHRIYW5kbGVyIGRoID0gbmV3IE15RGVmYXVsdEhhbmRsZXIoKTsKKyAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShsaXN0X3dmW2ldKTsKKyAgICAgICAgICAgIHBhcnNlci5wYXJzZShpcywgZGgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShTQVhQYXJzZXJUZXN0U3VwcG9ydC5lcXVhbHNNYXBzKGhtLCBkaC5jcmVhdGVEYXRhKCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBsaXN0X253Zi5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBNeURlZmF1bHRIYW5kbGVyIGRoID0gbmV3IE15RGVmYXVsdEhhbmRsZXIoKTsKKyAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0obGlzdF9ud2ZbaV0pOworICAgICAgICAgICAgICAgIHBhcnNlci5wYXJzZShpcywgZGgpOworICAgICAgICAgICAgICAgIGZhaWwoIlNBWEV4Y2VwdGlvbiBpcyBub3QgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkgeworICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNeURlZmF1bHRIYW5kbGVyIGRoID0gbmV3IE15RGVmYXVsdEhhbmRsZXIoKTsKKyAgICAgICAgICAgIHBhcnNlci5wYXJzZSgoSW5wdXRTdHJlYW0pIG51bGwsIGRoKTsKKyAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoKGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGxpc3Rfd2ZbMF0pOworICAgICAgICAgICAgcGFyc2VyLnBhcnNlKGlzLCAoRGVmYXVsdEhhbmRsZXIpIG51bGwpOworICAgICAgICB9IGNhdGNoKGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93biIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRlc3QgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyI3BhcnNlKGphdmEuaW8uSW5wdXRTdHJlYW0sCisgICAgICogICAgIG9yZy54bWwuc2F4LmhlbHBlcnMuRGVmYXVsdEhhbmRsZXIsIGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgiV2Ugc3VwcGx5IG9wdGlvbmFsIHFuYW1lcywgYnV0IHRoaXMgdGVzdCBkb2Vzbid0IGV4cGVjdCB0aGVtIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BhcnNlTGphdmFfaW9fSW5wdXRTdHJlYW1Mb3JnX3htbF9zYXhfaGVscGVyc19EZWZhdWx0SGFuZGxlckxqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbGlzdF93Zi5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBIYXNoTWFwPFN0cmluZywgU3RyaW5nPiBobSA9IHNwLnJlYWRGaWxlKAorICAgICAgICAgICAgICAgICAgICAgICAgbGlzdF9vdXRfaGJbaV0uZ2V0UGF0aCgpKTsKKyAgICAgICAgICAgICAgICBNeURlZmF1bHRIYW5kbGVyIGRoID0gbmV3IE15RGVmYXVsdEhhbmRsZXIoKTsKKyAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0obGlzdF93ZltpXSk7CisgICAgICAgICAgICAgICAgcGFyc2VyLnBhcnNlKGlzLCBkaCwgU0FYUGFyc2VyVGVzdFN1cHBvcnQuWE1MX1NZU1RFTV9JRCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGhtLCBkaC5jcmVhdGVEYXRhKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgaW9lLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIHNheCkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU0FYRXhjZXB0aW9uICIgKyBzYXgudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbGlzdF9ud2YubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTXlEZWZhdWx0SGFuZGxlciBkaCA9IG5ldyBNeURlZmF1bHRIYW5kbGVyKCk7CisgICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGxpc3RfbndmW2ldKTsKKyAgICAgICAgICAgICAgICBwYXJzZXIucGFyc2UoaXMsIGRoLCBTQVhQYXJzZXJUZXN0U3VwcG9ydC5YTUxfU1lTVEVNX0lEKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTQVhFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpIHsKKyAgICAgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZm5lKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBGaWxlTm90Rm91bmRFeGNlcHRpb24gIiArIGZuZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gIiArIGlvZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNeURlZmF1bHRIYW5kbGVyIGRoID0gbmV3IE15RGVmYXVsdEhhbmRsZXIoKTsKKyAgICAgICAgICAgIHBhcnNlci5wYXJzZSgoSW5wdXRTdHJlYW0pIG51bGwsIGRoLAorICAgICAgICAgICAgICAgICAgICBTQVhQYXJzZXJUZXN0U3VwcG9ydC5YTUxfU1lTVEVNX0lEKTsKKyAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoKGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgaW9lLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoKFNBWEV4Y2VwdGlvbiBzYXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU0FYRXhjZXB0aW9uICIgKyBzYXgudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGxpc3Rfd2ZbMF0pOworICAgICAgICAgICAgcGFyc2VyLnBhcnNlKGlzLCAoRGVmYXVsdEhhbmRsZXIpIG51bGwsCisgICAgICAgICAgICAgICAgICAgIFNBWFBhcnNlclRlc3RTdXBwb3J0LlhNTF9TWVNURU1fSUQpOworICAgICAgICB9IGNhdGNoKGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZm5lKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiAiICsgZm5lLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgaW9lLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoKFNBWEV4Y2VwdGlvbiBzYXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU0FYRXhjZXB0aW9uICIgKyBzYXgudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKy8vCisvLyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGxpc3Rfd2YubGVuZ3RoOyBpKyspIHsKKy8vCisvLyAgICAgICAgICAgIEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IGhtID0gbmV3IFNBWFBhcnNlclRlc3RTdXBwb3J0KCkucmVhZEZpbGUoCisvLyAgICAgICAgICAgICAgICAgICAgbGlzdF9vdXRfZGhbaV0uZ2V0UGF0aCgpKTsKKy8vICAgICAgICAgICAgTXlEZWZhdWx0SGFuZGxlciBkaCA9IG5ldyBNeURlZmF1bHRIYW5kbGVyKCk7CisvLyAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShsaXN0X3dmW2ldKTsKKy8vICAgICAgICAgICAgcGFyc2VyLnBhcnNlKGlzLCBkaCwgU0FYUGFyc2VyVGVzdFN1cHBvcnQuWE1MX1NZU1RFTV9JRCk7CisvLyAgICAgICAgICAgIGFzc2VydFRydWUoU0FYUGFyc2VyVGVzdFN1cHBvcnQuZXF1YWxzTWFwcyhobSwgZGguY3JlYXRlRGF0YSgpKSk7CisvLyAgICAgICAgfQorLy8KKy8vICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbGlzdF9ud2YubGVuZ3RoOyBpKyspIHsKKy8vICAgICAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgICAgIE15RGVmYXVsdEhhbmRsZXIgZGggPSBuZXcgTXlEZWZhdWx0SGFuZGxlcigpOworLy8gICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGxpc3RfbndmW2ldKTsKKy8vICAgICAgICAgICAgICAgIHBhcnNlci5wYXJzZShpcywgZGgsIFNBWFBhcnNlclRlc3RTdXBwb3J0LlhNTF9TWVNURU1fSUQpOworLy8gICAgICAgICAgICAgICAgZmFpbCgiU0FYRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKy8vICAgICAgICAgICAgfSBjYXRjaChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpIHsKKy8vICAgICAgICAgICAgICAgIC8vZXhwZWN0ZWQKKy8vICAgICAgICAgICAgfQorLy8gICAgICAgIH0KKy8vCisvLyAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgTXlEZWZhdWx0SGFuZGxlciBkaCA9IG5ldyBNeURlZmF1bHRIYW5kbGVyKCk7CisvLyAgICAgICAgICAgIHBhcnNlci5wYXJzZSgoSW5wdXRTdHJlYW0pIG51bGwsIGRoLAorLy8gICAgICAgICAgICAgICAgICAgIFNBWFBhcnNlclRlc3RTdXBwb3J0LlhNTF9TWVNURU1fSUQpOworLy8gICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKy8vICAgICAgICB9IGNhdGNoKGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisvLyAgICAgICAgICAgIC8vZXhwZWN0ZWQKKy8vICAgICAgICB9CisvLworLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShsaXN0X3dmWzBdKTsKKy8vICAgICAgICAgICAgcGFyc2VyLnBhcnNlKGlzLCAoRGVmYXVsdEhhbmRsZXIpIG51bGwsCisvLyAgICAgICAgICAgICAgICAgICAgU0FYUGFyc2VyVGVzdFN1cHBvcnQuWE1MX1NZU1RFTV9JRCk7CisvLyAgICAgICAgfSBjYXRjaChqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworLy8gICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93biIpOworLy8gICAgICAgIH0KKy8vCisvLyAgICAgICAgLy8gVE9ETyBjb21tZW50ZWQgb3V0IHNpbmNlIG91ciBwYXJzZXIgaXMgbm9udmFsaWRhdGluZyBhbmQgdGh1cyBuZXZlcgorLy8gICAgICAgIC8vIHRyaWVzIHRvIGxvYWQgc3RhZmYuZHRkIGluICIvIiAuLi4gYW5kIHRoZXJlZm9yZSBuZXZlciBjYW4gZmFpbCB3aXRoCisvLyAgICAgICAgLy8gYW4gSU9FeGNlcHRpb24KKy8vICAgICAgICAvKnRyeSB7CisvLyAgICAgICAgICAgIE15RGVmYXVsdEhhbmRsZXIgZGggPSBuZXcgTXlEZWZhdWx0SGFuZGxlcigpOworLy8gICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0obGlzdF93ZlswXSk7CisvLyAgICAgICAgICAgIHBhcnNlci5wYXJzZShpcywgZGgsICIvIik7CisvLyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElPRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisvLyAgICAgICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpIHsKKy8vICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKy8vICAgICAgICB9Ki8KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VJbnB1dFN0cmVhbUhhbmRsZXJCYXNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBsaXN0X3dmLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBIYXNoTWFwPFN0cmluZywgU3RyaW5nPiBobSA9IHNwLnJlYWRGaWxlKGxpc3Rfb3V0X2hiW2ldLmdldFBhdGgoKSk7CisgICAgICAgICAgICBNeUhhbmRsZXIgZGggPSBuZXcgTXlIYW5kbGVyKCk7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0obGlzdF93ZltpXSk7CisgICAgICAgICAgICBwYXJzZXIucGFyc2UoaXMsIGRoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoU0FYUGFyc2VyVGVzdFN1cHBvcnQuZXF1YWxzTWFwcyhobSwgZGguY3JlYXRlRGF0YSgpKSk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKEZpbGUgZmlsZSA6IGxpc3RfbndmKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIE15SGFuZGxlciBkaCA9IG5ldyBNeUhhbmRsZXIoKTsKKyAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSk7CisgICAgICAgICAgICAgICAgcGFyc2VyLnBhcnNlKGlzLCBkaCk7CisgICAgICAgICAgICAgICAgZmFpbCgiU0FYRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE15SGFuZGxlciBkaCA9IG5ldyBNeUhhbmRsZXIoKTsKKyAgICAgICAgICAgIHBhcnNlci5wYXJzZSgoSW5wdXRTdHJlYW0pIG51bGwsIGRoKTsKKyAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShsaXN0X3dmWzBdKTsKKyAgICAgICAgcGFyc2VyLnBhcnNlKGlzLCAoSGFuZGxlckJhc2UpIG51bGwpOworCisgICAgICAgIC8vIEluamVjdCBJT0V4Y2VwdGlvbgorICAgICAgICB0cnkgeworICAgICAgICAgICAgaXMgPSBuZXcgQnJva2VuSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShsaXN0X3dmWzBdKSwgMTApOworICAgICAgICAgICAgcGFyc2VyLnBhcnNlKGlzLCAoSGFuZGxlckJhc2UpIG51bGwpOworICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaXMuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZUlucHV0U3RyZWFtSGFuZGxlckJhc2VTdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGxpc3Rfd2YubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IGhtID0gc3AucmVhZEZpbGUobGlzdF9vdXRfaGJbaV0uZ2V0UGF0aCgpKTsKKyAgICAgICAgICAgIE15SGFuZGxlciBkaCA9IG5ldyBNeUhhbmRsZXIoKTsKKyAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShsaXN0X3dmW2ldKTsKKyAgICAgICAgICAgIHBhcnNlci5wYXJzZShpcywgZGgsIFNBWFBhcnNlclRlc3RTdXBwb3J0LlhNTF9TWVNURU1fSUQpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShTQVhQYXJzZXJUZXN0U3VwcG9ydC5lcXVhbHNNYXBzKGhtLCBkaC5jcmVhdGVEYXRhKCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoRmlsZSBmaWxlIDogbGlzdF9ud2YpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgTXlIYW5kbGVyIGRoID0gbmV3IE15SGFuZGxlcigpOworICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKTsKKyAgICAgICAgICAgICAgICBwYXJzZXIucGFyc2UoaXMsIGRoLCBTQVhQYXJzZXJUZXN0U3VwcG9ydC5YTUxfU1lTVEVNX0lEKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJTQVhFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTXlIYW5kbGVyIGRoID0gbmV3IE15SGFuZGxlcigpOworICAgICAgICAgICAgcGFyc2VyLnBhcnNlKG51bGwsIGRoLCBTQVhQYXJzZXJUZXN0U3VwcG9ydC5YTUxfU1lTVEVNX0lEKTsKKyAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGxpc3Rfd2ZbMF0pOworICAgICAgICBwYXJzZXIucGFyc2UoaXMsIChIYW5kbGVyQmFzZSkgbnVsbCwgU0FYUGFyc2VyVGVzdFN1cHBvcnQuWE1MX1NZU1RFTV9JRCk7CisKKyAgICAgICAgLy8gSW5qZWN0IElPRXhjZXB0aW9uCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpcyA9IG5ldyBCcm9rZW5JbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKGxpc3Rfd2ZbMF0pLCAxMCk7CisgICAgICAgICAgICBwYXJzZXIucGFyc2UoaXMsIChIYW5kbGVyQmFzZSkgbnVsbCwgU0FYUGFyc2VyVGVzdFN1cHBvcnQuWE1MX1NZU1RFTV9JRCk7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHRlc3QgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyI3BhcnNlKGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgIG9yZy54bWwuc2F4LmhlbHBlcnMuRGVmYXVsdEhhbmRsZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wYXJzZUxqYXZhX2xhbmdfU3RyaW5nTG9yZ194bWxfc2F4X2hlbHBlcnNfRGVmYXVsdEhhbmRsZXIoKQorICAgIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBsaXN0X3dmLmxlbmd0aDsgaSsrKSB7CisKKyAgICAgICAgICAgIEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IGhtID0gbmV3IFNBWFBhcnNlclRlc3RTdXBwb3J0KCkucmVhZEZpbGUoCisgICAgICAgICAgICAgICAgICAgIGxpc3Rfb3V0X2RoW2ldLmdldFBhdGgoKSk7CisgICAgICAgICAgICBNeURlZmF1bHRIYW5kbGVyIGRoID0gbmV3IE15RGVmYXVsdEhhbmRsZXIoKTsKKyAgICAgICAgICAgIHBhcnNlci5wYXJzZShsaXN0X3dmW2ldLnRvVVJJKCkudG9TdHJpbmcoKSwgZGgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShTQVhQYXJzZXJUZXN0U3VwcG9ydC5lcXVhbHNNYXBzKGhtLCBkaC5jcmVhdGVEYXRhKCkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBsaXN0X253Zi5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBNeURlZmF1bHRIYW5kbGVyIGRoID0gbmV3IE15RGVmYXVsdEhhbmRsZXIoKTsKKyAgICAgICAgICAgICAgICBwYXJzZXIucGFyc2UobGlzdF9ud2ZbaV0udG9VUkkoKS50b1N0cmluZygpLCBkaCk7CisgICAgICAgICAgICAgICAgZmFpbCgiU0FYRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2gob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE15RGVmYXVsdEhhbmRsZXIgZGggPSBuZXcgTXlEZWZhdWx0SGFuZGxlcigpOworICAgICAgICAgICAgcGFyc2VyLnBhcnNlKChTdHJpbmcpIG51bGwsIGRoKTsKKyAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoKGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFyc2VyLnBhcnNlKGxpc3Rfd2ZbMF0udG9VUkkoKS50b1N0cmluZygpLCAoRGVmYXVsdEhhbmRsZXIpIG51bGwpOworICAgICAgICB9IGNhdGNoKGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93biIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlU3RyaW5nSGFuZGxlckJhc2UoKSB7CisgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBsaXN0X3dmLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IGhtID0gc3AucmVhZEZpbGUoCisgICAgICAgICAgICAgICAgICAgICAgICBsaXN0X291dF9oYltpXS5nZXRQYXRoKCkpOworICAgICAgICAgICAgICAgIE15SGFuZGxlciBkaCA9IG5ldyBNeUhhbmRsZXIoKTsKKyAgICAgICAgICAgICAgICBwYXJzZXIucGFyc2UobGlzdF93ZltpXS50b1VSSSgpLnRvU3RyaW5nKCksIGRoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKFNBWFBhcnNlclRlc3RTdXBwb3J0LmVxdWFsc01hcHMoaG0sCisgICAgICAgICAgICAgICAgICAgICAgICBkaC5jcmVhdGVEYXRhKCkpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gIiArIGlvZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzYXgpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNBWEV4Y2VwdGlvbiAiICsgc2F4LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGxpc3RfbndmLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIE15SGFuZGxlciBkaCA9IG5ldyBNeUhhbmRsZXIoKTsKKyAgICAgICAgICAgICAgICBwYXJzZXIucGFyc2UobGlzdF9ud2ZbaV0udG9VUkkoKS50b1N0cmluZygpLCBkaCk7CisgICAgICAgICAgICAgICAgZmFpbCgiU0FYRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2gob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICAgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGZuZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgRmlsZU5vdEZvdW5kRXhjZXB0aW9uICIgKyBmbmUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uICIgKyBpb2UudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTXlIYW5kbGVyIGRoID0gbmV3IE15SGFuZGxlcigpOworICAgICAgICAgICAgcGFyc2VyLnBhcnNlKChTdHJpbmcpIG51bGwsIGRoKTsKKyAgICAgICAgICAgIGZhaWwoImphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoKGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgaW9lLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoKFNBWEV4Y2VwdGlvbiBzYXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU0FYRXhjZXB0aW9uICIgKyBzYXgudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFyc2VyLnBhcnNlKGxpc3Rfd2ZbMF0udG9VUkkoKS50b1N0cmluZygpLCAoSGFuZGxlckJhc2UpIG51bGwpOworICAgICAgICB9IGNhdGNoKGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICBmYWlsKCJqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZm5lKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiAiICsgZm5lLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiAiICsgaW9lLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoKFNBWEV4Y2VwdGlvbiBzYXgpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU0FYRXhjZXB0aW9uICIgKyBzYXgudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVzZXQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzcGYgPSBTQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisgICAgICAgICAgICBwYXJzZXIgPSBzcGYubmV3U0FYUGFyc2VyKCk7CisKKyAgICAgICAgICAgIHBhcnNlci5zZXRQcm9wZXJ0eShMRVhJQ0FMX0hBTkRMRVJfUFJPUEVSVFksIG5ldyBNb2NrSGFuZGxlcihuZXcgTWV0aG9kTG9nZ2VyKCkpKTsKKyAgICAgICAgICAgIHBhcnNlci5yZXNldCgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHBhcnNlci5nZXRQcm9wZXJ0eShMRVhJQ0FMX0hBTkRMRVJfUFJPUEVSVFkpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFBhcnNlcigpIHsKKyAgICAgICAgc3BmID0gU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgUGFyc2VyIHBhcnNlciA9IHNwZi5uZXdTQVhQYXJzZXIoKS5nZXRQYXJzZXIoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocGFyc2VyKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFJlYWRlcigpIHsKKyAgICAgICAgc3BmID0gU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgWE1MUmVhZGVyIHJlYWRlciA9IHNwZi5uZXdTQVhQYXJzZXIoKS5nZXRYTUxSZWFkZXIoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocmVhZGVyKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldEdldFByb3BlcnR5KCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIFN0cmluZyB2YWxpZE5hbWUgPSAiaHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvbGV4aWNhbC1oYW5kbGVyIjsKKyAgICAgICAgTGV4aWNhbEhhbmRsZXIgdmFsaWRWYWx1ZSA9IG5ldyBNb2NrSGFuZGxlcihuZXcgTWV0aG9kTG9nZ2VyKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTQVhQYXJzZXIgcGFyc2VyID0gc3BmLm5ld1NBWFBhcnNlcigpOworICAgICAgICAgICAgcGFyc2VyLnNldFByb3BlcnR5KHZhbGlkTmFtZSwgdmFsaWRWYWx1ZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModmFsaWRWYWx1ZSwgcGFyc2VyLmdldFByb3BlcnR5KHZhbGlkTmFtZSkpOworCisgICAgICAgICAgICBwYXJzZXIuc2V0UHJvcGVydHkodmFsaWROYW1lLCBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBwYXJzZXIuZ2V0UHJvcGVydHkodmFsaWROYW1lKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFVuc3VwcG9ydGVkIHByb3BlcnR5CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTQVhQYXJzZXIgcGFyc2VyID0gc3BmLm5ld1NBWFBhcnNlcigpOworICAgICAgICAgICAgcGFyc2VyLnNldFByb3BlcnR5KCJmb28iLCAiYmFyIik7CisgICAgICAgICAgICBmYWlsKCJTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNBWFBhcnNlciBwYXJzZXIgPSBzcGYubmV3U0FYUGFyc2VyKCk7CisgICAgICAgICAgICBwYXJzZXIuZ2V0UHJvcGVydHkoImZvbyIpOworICAgICAgICAgICAgZmFpbCgiU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIE5vIG5hbWUgY2FzZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgU0FYUGFyc2VyIHBhcnNlciA9IHNwZi5uZXdTQVhQYXJzZXIoKTsKKyAgICAgICAgICAgIHBhcnNlci5zZXRQcm9wZXJ0eShudWxsLCAiYmFyIik7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU0FYUGFyc2VyIHBhcnNlciA9IHNwZi5uZXdTQVhQYXJzZXIoKTsKKyAgICAgICAgICAgIHBhcnNlci5nZXRQcm9wZXJ0eShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC94bWwvcGFyc2Vycy9TQVhQYXJzZXJUZXN0U3VwcG9ydC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9qYXZheC94bWwvcGFyc2Vycy9TQVhQYXJzZXJUZXN0U3VwcG9ydC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiN2UxZGEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL2phdmF4L3htbC9wYXJzZXJzL1NBWFBhcnNlclRlc3RTdXBwb3J0LmphdmEKQEAgLTAsMCArMSw0OTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLmphdmF4LnhtbC5wYXJzZXJzOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKKworaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7CitpbXBvcnQgb3JnLnhtbC5zYXguSGFuZGxlckJhc2U7CitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CitpbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyOworCisvKioKKyAqIFN1cHBvcnQgZm9yIFNBWFBhcnNlclRlc3QuIFNoYXJlcyB0aGUgZWxlbWVudCBrZXlzIHVzZWQgaW4gdGhlIGdvbGRlbiBmaWxlcy4KKyAqIENvbXBhcmVzIHRoZSByZXN1bHQgb2YgdGhlIHBhcnNlciB3aXRoIGdvbGRlbiBkYXRhLgorICogQ29udGFpbnMgdGhlIGhhbmRsZXIgY2xhc3NlcyB1c2VkIHRvIHRyYWNrIHRoZSBvdXRwdXQgb2YgdGhlIHBhcnNlci4KKyAqLworY2xhc3MgU0FYUGFyc2VyVGVzdFN1cHBvcnQgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjaGFyIFNFUEFSQVRPUl9FTEVNRU5UID0gJ14nOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBTRVBBUkFUT1JfU1RSSU5HID0gJyQnOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBTRVBBUkFUT1JfREFUQSA9ICcjJzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9XRiA9ICIvd2YvIjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfTldGID0gIi9ud2YvIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9XRl9PVVRfREggPSAiL291dF9kaC8iOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9XRl9PVVRfSEIgPSAiL291dF9oYi8iOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX1NZU1RFTV9JRCA9ICIuIiArICIvc3lzdGVtaWQvIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEtFWV9JU19TVEFSVF9ET0MgPSAiaXNFbmREb2N1bWVudCI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgS0VZX0lTX0VORF9ET0MgPSAiaXNTdGFydERvY3VtZW50IjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBLRVlfVEVYVCA9ICJ0ZXh0IjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBLRVlfRVJST1IgPSAiZXJyb3IiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEtFWV9GQVRBTF9FUlJPUiA9ICJmYXRhbEVycm9yIjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBLRVlfV0FSTklORyA9ICJ3YXJuaW5nIjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBLRVlfRU5EX0VMRU1FTlQgPSAiZW5kRWxlbWVudCI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgS0VZX0VORF9QUkVGSVhfTUFQUElORyA9ICJlbmRQcmVmaXhNYXBwaW5nIjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBLRVlfSUdOT1JBQkxFX1dISVRFX1NQQUNFID0KKyAgICAgICAgImlnbm9yYWJsZVdoaXRlc3BhY2UiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEtFWV9OT1RBVElPTl9ERUNMID0gIm5vdGF0aW9uRGVjbCI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgS0VZX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04gPQorICAgICAgICAicHJvY2Vzc2luZ0luc3RydWN0aW9uIjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBLRVlfUkVTT0xWRV9FTlRJVFkgPSAicmVzb2x2ZUVudGl0eSI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgS0VZX0RPQ1VNRU5UX0xPQ0FUT1JTID0gImRvY3VtZW50TG9jYXRvcnMiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEtFWV9TS0lQUEVEX0VOVElUWSA9ICJza2lwcGVkRW50aXR5IjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBLRVlfU1RBUlRfRUxFTUVOVCA9ICJzdGFydEVsZW1lbnQiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEtFWV9TVEFSVF9QUkVGSVhfTUFQUElORyA9ICJzdGFydFByZWZpeE1hcHBpbmciOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEtFWV9VTlBBUlNFRF9FTlRJVFlfREVDTCA9ICJ1bnBhcnNlZEVudGl0eURlY2wiOworCisgICAgc3RhdGljIFN0cmluZyBbXSBLRVlTID0ge0tFWV9JU19TVEFSVF9ET0MsIEtFWV9JU19FTkRfRE9DLCBLRVlfVEVYVCwKKyAgICAgICAgICAgIEtFWV9FUlJPUiwgS0VZX0ZBVEFMX0VSUk9SLCBLRVlfV0FSTklORywgS0VZX0VORF9FTEVNRU5ULAorICAgICAgICAgICAgS0VZX0VORF9QUkVGSVhfTUFQUElORywgS0VZX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04sCisgICAgICAgICAgICBLRVlfU0tJUFBFRF9FTlRJVFksIEtFWV9TVEFSVF9FTEVNRU5ULAorICAgICAgICAgICAgS0VZX1NUQVJUX1BSRUZJWF9NQVBQSU5HfTsKKworICAgIHN0YXRpYyB7CisgICAgICAgIFN0cmluZyB0bXAgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaW8udG1wZGlyIiwgIi4iKTsKKworICAgICAgICBuZXcgRmlsZSh0bXApLm1rZGlycygpOworICAgICAgICBuZXcgRmlsZSh0bXAsIFhNTF9XRikubWtkaXJzKCk7CisgICAgICAgIG5ldyBGaWxlKHRtcCwgWE1MX05XRikubWtkaXJzKCk7CisgICAgICAgIG5ldyBGaWxlKHRtcCwgWE1MX1dGX09VVF9ESCkubWtkaXJzKCk7CisgICAgICAgIG5ldyBGaWxlKHRtcCwgWE1MX1dGX09VVF9IQikubWtkaXJzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZSB0aGUgU0FYUGFyc2VyVGVzdCByZWZlcmVuY2UgYnkgZmlsbGluZyBpbiB0aGUgZGF0YSBmcm9tIHRoZQorICAgICAqIGZpbGUgcGFzc2VkIHRvIHRoZSBtZXRob2QuIFRoaXMgd2lsbCBiZSB0aGUgcmVmZXJlbmNlIHRvIGNvbXBhcmUKKyAgICAgKiBhZ2FpbnN0IHdpdGggdGhlIG91dHB1dCBvZiB0aGUgcGFyc2VyLgorICAgICAqLworICAgIHB1YmxpYyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPiByZWFkRmlsZShTdHJpbmcgZmlsZU5hbWUpIHsKKyAgICAgICAgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4gc3RvcmFnZSA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZU5hbWUpOworCisgICAgICAgICAgICBpbnQgYyA9IGlzLnJlYWQoKTsKKworICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgICAgIHdoaWxlKGMgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICBpZigoY2hhciljID09IFNFUEFSQVRPUl9EQVRBKSB7CisgICAgICAgICAgICAgICAgICAvLyAgaWYoc3RyLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYoaSA8IEtFWVMubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmFnZS5wdXQoS0VZU1tpXSwgc3RyLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgU3lzdGVtLm91dC5wcmludGxuKHN0ci50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIuc2V0TGVuZ3RoKDApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgIC8vICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgoY2hhciljKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgYyA9IGlzLnJlYWQoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBjID0gLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorCisgICAgICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIklPRXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nIHRoZSBmaWxlOiAiCisgICAgICAgICAgICAgICAgICAgICsgZmlsZU5hbWUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzdG9yYWdlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSBjb250ZW50IG9mIHR3byBIYXNoTWFwcy4gT25lIG1hcCBzaG91bGQgYmUgdGhlIHJlZmVyZW5jZQorICAgICAqIGNvbnRhaW5pbmcgdGhlIGNvcnJlY3Qgc3RyaW5nIGZvciBlYWNoIHhtbCBkb2N1bWVudCBlbGVtZW50IGFuZCB0aGUgb3RoZXIKKyAgICAgKiBzaG91bGQgY29udGFpbiB0aGUgZWxlbWVudHMgZmlsbGVkIHdpdGggb3V0cHV0IGZyb20gdGhlIHBhcnNlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcmlnaW5hbCB0aGUgcmVmZXJlbmNlCisgICAgICogQHBhcmFtIHJlc3VsdCB0aGUgcmVzdWx0IG9mIHRoZSBwYXJzZXIKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhleSdyZSBlcXVhbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZXF1YWxzTWFwcyhIYXNoTWFwPFN0cmluZywgU3RyaW5nPiBvcmlnaW5hbCwKKyAgICAgICAgICAgIEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IHJlc3VsdCkgeworCisgICAgICAgIGlmKG9yaWdpbmFsID09IG51bGwgJiYgcmVzdWx0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYob3JpZ2luYWwuc2l6ZSgpICE9IHJlc3VsdC5zaXplKCkpIHJldHVybiBmYWxzZTsKKworICAgICAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IEtFWVMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZighb3JpZ2luYWwuZ2V0KEtFWVNbaV0pLmVxdWFscyhyZXN1bHQuZ2V0KEtFWVNbaV0pKSkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZvciAiK0tFWVNbaV0rIjogb3JpZ2luYWw6IiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWwuZ2V0KEtFWVNbaV0pKTsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiICByZXN1bHQ6IiArIHJlc3VsdC5nZXQoS0VZU1tpXSkpOworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIE15RGVmYXVsdEhhbmRsZXIgZXh0ZW5kcyBEZWZhdWx0SGFuZGxlciB7CisKKyAgICAgICAgcHVibGljIFN0cmluZ0J1ZmZlciBkYXRhX2lzRW5kRG9jdW1lbnQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgZGF0YV9pc1N0YXJ0RG9jdW1lbnQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgZGF0YV90ZXh0ID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGRhdGFfZXJyb3IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgZGF0YV9mYXRhbEVycm9yID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGRhdGFfd2FybmluZyA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgcHVibGljIFN0cmluZ0J1ZmZlciBkYXRhX2VuZEVsZW1lbnQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgZGF0YV9lbmRQcmVmaXhNYXBwaW5nID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGRhdGFfcHJvY2Vzc2luZ0luc3RydWN0aW9uID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGRhdGFfc2tpcHBlZEVudGl0eSA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgcHVibGljIFN0cmluZ0J1ZmZlciBkYXRhX3N0YXJ0RWxlbWVudCA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgcHVibGljIFN0cmluZ0J1ZmZlciBkYXRhX3N0YXJ0UHJlZml4TWFwcGluZyA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKworICAgICAgICBwdWJsaWMgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4gY3JlYXRlRGF0YSgpIHsKKyAgICAgICAgICAgIEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IGhtID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgICAgICAgICBobS5wdXQoS0VZX0lTX0VORF9ET0MsIGRhdGFfaXNFbmREb2N1bWVudC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGhtLnB1dChLRVlfSVNfU1RBUlRfRE9DLCBkYXRhX2lzU3RhcnREb2N1bWVudC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGhtLnB1dChLRVlfVEVYVCwgZGF0YV90ZXh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgaG0ucHV0KEtFWV9FUlJPUiwgZGF0YV9lcnJvci50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGhtLnB1dChLRVlfRkFUQUxfRVJST1IsIGRhdGFfZmF0YWxFcnJvci50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGhtLnB1dChLRVlfV0FSTklORywgZGF0YV93YXJuaW5nLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgaG0ucHV0KEtFWV9FTkRfRUxFTUVOVCwgZGF0YV9lbmRFbGVtZW50LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgaG0ucHV0KEtFWV9FTkRfUFJFRklYX01BUFBJTkcsIGRhdGFfZW5kUHJlZml4TWFwcGluZy50b1N0cmluZygpKTsKKworICAgICAgICAgICAgaG0ucHV0KEtFWV9QUk9DRVNTSU5HX0lOU1RSVUNUSU9OLAorICAgICAgICAgICAgICAgICAgICBkYXRhX3Byb2Nlc3NpbmdJbnN0cnVjdGlvbi50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGhtLnB1dChLRVlfU0tJUFBFRF9FTlRJVFksIGRhdGFfc2tpcHBlZEVudGl0eS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGhtLnB1dChLRVlfU1RBUlRfRUxFTUVOVCwgZGF0YV9zdGFydEVsZW1lbnQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBobS5wdXQoS0VZX1NUQVJUX1BSRUZJWF9NQVBQSU5HLAorICAgICAgICAgICAgICAgICAgICBkYXRhX3N0YXJ0UHJlZml4TWFwcGluZy50b1N0cmluZygpKTsKKyAgICAgICAgICAgIHJldHVybiBobTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHByaW50TWFwKCkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChkYXRhX2lzU3RhcnREb2N1bWVudC50b1N0cmluZygpICsgU0VQQVJBVE9SX0RBVEEgKworICAgICAgICAgICAgICAgICAgICBkYXRhX2lzRW5kRG9jdW1lbnQudG9TdHJpbmcoKSArIFNFUEFSQVRPUl9EQVRBICsKKyAgICAgICAgICAgICAgICAgICAgZGF0YV90ZXh0LnRvU3RyaW5nKCkgKyBTRVBBUkFUT1JfREFUQSArCisgICAgICAgICAgICAgICAgICAgIGRhdGFfZXJyb3IudG9TdHJpbmcoKSsgU0VQQVJBVE9SX0RBVEEgKworICAgICAgICAgICAgICAgICAgICBkYXRhX2ZhdGFsRXJyb3IudG9TdHJpbmcoKSsgU0VQQVJBVE9SX0RBVEEgKworICAgICAgICAgICAgICAgICAgICBkYXRhX3dhcm5pbmcudG9TdHJpbmcoKSsgU0VQQVJBVE9SX0RBVEEgKworICAgICAgICAgICAgICAgICAgICBkYXRhX2VuZEVsZW1lbnQudG9TdHJpbmcoKSArIFNFUEFSQVRPUl9EQVRBKworICAgICAgICAgICAgICAgICAgICBkYXRhX2VuZFByZWZpeE1hcHBpbmcudG9TdHJpbmcoKSsgU0VQQVJBVE9SX0RBVEEgKworICAgICAgICAgICAgICAgICAgICBkYXRhX3Byb2Nlc3NpbmdJbnN0cnVjdGlvbi50b1N0cmluZygpICsgU0VQQVJBVE9SX0RBVEEgKworICAgICAgICAgICAgICAgICAgICBkYXRhX3NraXBwZWRFbnRpdHkudG9TdHJpbmcoKSArICBTRVBBUkFUT1JfREFUQSArCisgICAgICAgICAgICAgICAgICAgIGRhdGFfc3RhcnRFbGVtZW50LnRvU3RyaW5nKCkgKyBTRVBBUkFUT1JfREFUQSArCisgICAgICAgICAgICAgICAgICAgIGRhdGFfc3RhcnRQcmVmaXhNYXBwaW5nLnRvU3RyaW5nKCkrIFNFUEFSQVRPUl9EQVRBKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB7CisgICAgICAgICAgICBTdHJpbmcgc3RyID0gbmV3IFN0cmluZyhjaCwgc3RhcnQsIGxlbmd0aCk7CisgICAgICAgICAgICBkYXRhX3RleHQuYXBwZW5kKHN0cik7CisgICAgICAgICAgICAvLyBkaWZmZXJlbnQgc2F4IHBhcnNlcnMgYXJlIGFsbG93ZWQgdG8gaGFuZGxlIGNodW5raW5nIGRpZmZlcmVudGx5LAorICAgICAgICAgICAgLy8gdGhlcmVmb3JlIHdlIGNhbm5vdCByZWx5IG9uIGlkZW50aWNhbCBjaHVua3MgYmVpbmcgZGVsaXZlcmVkLgorICAgICAgICAgICAgLy9kYXRhX3RleHQuYXBwZW5kKFBhcnNpbmdTdXBwb3J0LlNFUEFSQVRPUl9FTEVNRU5UKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHsKKyAgICAgICAgICAgIGRhdGFfaXNFbmREb2N1bWVudC5hcHBlbmQodHJ1ZSk7CisgICAgICAgICAgICBkYXRhX2lzRW5kRG9jdW1lbnQuYXBwZW5kKFNFUEFSQVRPUl9FTEVNRU5UKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkgeworICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICAgICAgc2IuYXBwZW5kKHVyaSk7CisgICAgICAgICAgICBzYi5hcHBlbmQoU0VQQVJBVE9SX1NUUklORyk7CisgICAgICAgICAgICBzYi5hcHBlbmQobG9jYWxOYW1lKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZChTRVBBUkFUT1JfU1RSSU5HKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZChxTmFtZSk7CisgICAgICAgICAgICBkYXRhX2VuZEVsZW1lbnQuYXBwZW5kKHNiKTsKKyAgICAgICAgICAgIGRhdGFfZW5kRWxlbWVudC5hcHBlbmQoU0VQQVJBVE9SX0VMRU1FTlQpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCkgeworICAgICAgICAgICAgZGF0YV9lbmRQcmVmaXhNYXBwaW5nLmFwcGVuZChwcmVmaXgpOworICAgICAgICAgICAgZGF0YV9lbmRQcmVmaXhNYXBwaW5nLmFwcGVuZChTRVBBUkFUT1JfRUxFTUVOVCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgZXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZGF0YV9lcnJvci5hcHBlbmQoZSk7CisgICAgICAgICAgICBkYXRhX2Vycm9yLmFwcGVuZChTRVBBUkFUT1JfRUxFTUVOVCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgZmF0YWxFcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBkYXRhX2ZhdGFsRXJyb3IuYXBwZW5kKGUpOworICAgICAgICAgICAgZGF0YV9mYXRhbEVycm9yLmFwcGVuZChTRVBBUkFUT1JfRUxFTUVOVCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkgeworICAgICAgICAgICAgLyogICAgU3RyaW5nIHMgPSBuZXcgU3RyaW5nKGNoLCBzdGFydCwgbGVuZ3RoKTsKKyAgICAgICAgICAgIGlnbm9yYWJsZVdoaXRlc3BhY2UuYXBwZW5kKHMpOworICAgICAgICAgICAgaWdub3JhYmxlV2hpdGVzcGFjZS5hcHBlbmQoUGFyc2luZ1N1cHBvcnQuU0VQQVJBVE9SX0VMRU1FTlQpOyovCisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgbm90YXRpb25EZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsCisgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkKSB7CisgICAgICAgICAgICAvKiBkYXRhX25vdGF0aW9uRGVjbC5hcHBlbmQobmFtZSArIFBhcnNpbmdTdXBwb3J0LlNFUEFSQVRPUl9TVFJJTkcgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljSWQgKyBQYXJzaW5nU3VwcG9ydC5TRVBBUkFUT1JfU1RSSU5HICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbUlkICsgUGFyc2luZ1N1cHBvcnQuU0VQQVJBVE9SX1NUUklORyk7CisgICAgICAgICAgICBkYXRhX25vdGF0aW9uRGVjbC5hcHBlbmQoUGFyc2luZ1N1cHBvcnQuU0VQQVJBVE9SX0VMRU1FTlQpOyovCisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKSB7CisgICAgICAgICAgICBkYXRhX3Byb2Nlc3NpbmdJbnN0cnVjdGlvbi5hcHBlbmQodGFyZ2V0ICsgU0VQQVJBVE9SX1NUUklORyArIGRhdGEpOworICAgICAgICAgICAgZGF0YV9wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24uYXBwZW5kKFNFUEFSQVRPUl9FTEVNRU5UKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgSW5wdXRTb3VyY2UgICAgcmVzb2x2ZUVudGl0eShTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkgeworICAgICAgICAgICAgLy8gZGF0YV9yZXNvbHZlRW50aXR5LmFwcGVuZChwdWJsaWNJZCArCisgICAgICAgICAgICAvLyAgICAgICAgICAgIFBhcnNpbmdTdXBwb3J0LlNFUEFSQVRPUl9TVFJJTkcgKyBzeXN0ZW1JZCk7CisgICAgICAgICAgICAvLyBkYXRhX3Jlc29sdmVFbnRpdHkuYXBwZW5kKFBhcnNpbmdTdXBwb3J0LlNFUEFSQVRPUl9FTEVNRU5UKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvcihMb2NhdG9yIGxvY2F0b3IpIHsKKyAgICAgICAgICAgIC8vICAgICAgIGRhdGFfZG9jdW1lbnRMb2NhdG9ycy5hcHBlbmQobG9jYXRvcik7CisgICAgICAgICAgICAvLyBkYXRhX2RvY3VtZW50TG9jYXRvcnMuYXBwZW5kKFBhcnNpbmdTdXBwb3J0LlNFUEFSQVRPUl9FTEVNRU5UKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBza2lwcGVkRW50aXR5KFN0cmluZyBuYW1lKSB7CisgICAgICAgICAgICBkYXRhX3NraXBwZWRFbnRpdHkuYXBwZW5kKG5hbWUpOworICAgICAgICAgICAgZGF0YV9za2lwcGVkRW50aXR5LmFwcGVuZChTRVBBUkFUT1JfRUxFTUVOVCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHsKKyAgICAgICAgICAgIGRhdGFfaXNTdGFydERvY3VtZW50LmFwcGVuZCh0cnVlKTsKKyAgICAgICAgICAgIGRhdGFfaXNTdGFydERvY3VtZW50LmFwcGVuZChTRVBBUkFUT1JfRUxFTUVOVCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSwKKyAgICAgICAgICAgICAgICBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHsKKyAgICAgICAgICAgIGRhdGFfc3RhcnRFbGVtZW50LmFwcGVuZCh1cmkpOworICAgICAgICAgICAgZGF0YV9zdGFydEVsZW1lbnQuYXBwZW5kKFNFUEFSQVRPUl9TVFJJTkcpOworICAgICAgICAgICAgZGF0YV9zdGFydEVsZW1lbnQuYXBwZW5kKGxvY2FsTmFtZSk7CisgICAgICAgICAgICBkYXRhX3N0YXJ0RWxlbWVudC5hcHBlbmQoU0VQQVJBVE9SX1NUUklORyk7CisgICAgICAgICAgICBkYXRhX3N0YXJ0RWxlbWVudC5hcHBlbmQocU5hbWUpOworCisgICAgICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsgaSArKykKKyAgICAgICAgICAgICAgICBkYXRhX3N0YXJ0RWxlbWVudC5hcHBlbmQoCisgICAgICAgICAgICAgICAgICAgICAgICBTRVBBUkFUT1JfU1RSSU5HICthdHRyaWJ1dGVzLmdldFFOYW1lKGkpICsKKyAgICAgICAgICAgICAgICAgICAgICAgIFNFUEFSQVRPUl9TVFJJTkcgKyBhdHRyaWJ1dGVzLmdldFZhbHVlKGkpKTsKKworICAgICAgICAgICAgZGF0YV9pc1N0YXJ0RG9jdW1lbnQuYXBwZW5kKFNFUEFSQVRPUl9FTEVNRU5UKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkgeworICAgICAgICAgICAgZGF0YV9zdGFydFByZWZpeE1hcHBpbmcuYXBwZW5kKHByZWZpeCArIFNFUEFSQVRPUl9TVFJJTkcgKyB1cmkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLAorICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIG5vdGF0aW9uTmFtZSkgeworICAgICAgICAgICAgLy8gZGF0YV91bnBhcnNlZEVudGl0eURlY2wuYXBwZW5kKG5hbWUKKyAgICAgICAgICAgIC8vICAgICArIFBhcnNpbmdTdXBwb3J0LlNFUEFSQVRPUl9TVFJJTkcgKyBwdWJsaWNJZAorICAgICAgICAgICAgLy8gICAgICsgUGFyc2luZ1N1cHBvcnQuU0VQQVJBVE9SX1NUUklORworICAgICAgICAgICAgLy8gICAgICsgc3lzdGVtSWQgKyBQYXJzaW5nU3VwcG9ydC5TRVBBUkFUT1JfU1RSSU5HICsgbm90YXRpb25OYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGRhdGFfd2FybmluZy5hcHBlbmQoZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHN0YXRpYyBjbGFzcyBNeUhhbmRsZXIgZXh0ZW5kcyBIYW5kbGVyQmFzZSB7CisKKyAgICAgICAgcHVibGljIFN0cmluZ0J1ZmZlciBkYXRhX2lzRW5kRG9jdW1lbnQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgZGF0YV9pc1N0YXJ0RG9jdW1lbnQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgZGF0YV90ZXh0ID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGRhdGFfZXJyb3IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgZGF0YV9mYXRhbEVycm9yID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGRhdGFfd2FybmluZyA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgcHVibGljIFN0cmluZ0J1ZmZlciBkYXRhX2VuZEVsZW1lbnQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgZGF0YV9lbmRQcmVmaXhNYXBwaW5nID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGRhdGFfcHJvY2Vzc2luZ0luc3RydWN0aW9uID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGRhdGFfc2tpcHBlZEVudGl0eSA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgcHVibGljIFN0cmluZ0J1ZmZlciBkYXRhX3N0YXJ0RWxlbWVudCA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgcHVibGljIFN0cmluZ0J1ZmZlciBkYXRhX3N0YXJ0UHJlZml4TWFwcGluZyA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKworICAgICAgICBwdWJsaWMgdm9pZCBwcmludE1hcCgpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoZGF0YV9pc1N0YXJ0RG9jdW1lbnQudG9TdHJpbmcoKSArIFNFUEFSQVRPUl9EQVRBICsKKyAgICAgICAgICAgICAgICAgICAgZGF0YV9pc0VuZERvY3VtZW50LnRvU3RyaW5nKCkgKyBTRVBBUkFUT1JfREFUQSArCisgICAgICAgICAgICAgICAgICAgIGRhdGFfdGV4dC50b1N0cmluZygpICsgU0VQQVJBVE9SX0RBVEEgKworICAgICAgICAgICAgICAgICAgICBkYXRhX2Vycm9yLnRvU3RyaW5nKCkrIFNFUEFSQVRPUl9EQVRBICsKKyAgICAgICAgICAgICAgICAgICAgZGF0YV9mYXRhbEVycm9yLnRvU3RyaW5nKCkrIFNFUEFSQVRPUl9EQVRBICsKKyAgICAgICAgICAgICAgICAgICAgZGF0YV93YXJuaW5nLnRvU3RyaW5nKCkrIFNFUEFSQVRPUl9EQVRBICsKKyAgICAgICAgICAgICAgICAgICAgZGF0YV9lbmRFbGVtZW50LnRvU3RyaW5nKCkgKyBTRVBBUkFUT1JfREFUQSsKKyAgICAgICAgICAgICAgICAgICAgZGF0YV9lbmRQcmVmaXhNYXBwaW5nLnRvU3RyaW5nKCkrIFNFUEFSQVRPUl9EQVRBICsKKyAgICAgICAgICAgICAgICAgICAgZGF0YV9wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24udG9TdHJpbmcoKSArIFNFUEFSQVRPUl9EQVRBICsKKyAgICAgICAgICAgICAgICAgICAgZGF0YV9za2lwcGVkRW50aXR5LnRvU3RyaW5nKCkgKyAgU0VQQVJBVE9SX0RBVEEgKworICAgICAgICAgICAgICAgICAgICBkYXRhX3N0YXJ0RWxlbWVudC50b1N0cmluZygpICsgU0VQQVJBVE9SX0RBVEEgKworICAgICAgICAgICAgICAgICAgICBkYXRhX3N0YXJ0UHJlZml4TWFwcGluZy50b1N0cmluZygpKyBTRVBBUkFUT1JfREFUQSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4gY3JlYXRlRGF0YSgpIHsKKyAgICAgICAgICAgIEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IGhtID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgICAgICAgICBobS5wdXQoS0VZX0lTX0VORF9ET0MsIGRhdGFfaXNFbmREb2N1bWVudC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGhtLnB1dChLRVlfSVNfU1RBUlRfRE9DLCBkYXRhX2lzU3RhcnREb2N1bWVudC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGhtLnB1dChLRVlfVEVYVCwgZGF0YV90ZXh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgaG0ucHV0KEtFWV9FUlJPUiwgZGF0YV9lcnJvci50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGhtLnB1dChLRVlfRkFUQUxfRVJST1IsIGRhdGFfZmF0YWxFcnJvci50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGhtLnB1dChLRVlfV0FSTklORywgZGF0YV93YXJuaW5nLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgaG0ucHV0KEtFWV9FTkRfRUxFTUVOVCwgZGF0YV9lbmRFbGVtZW50LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgaG0ucHV0KEtFWV9FTkRfUFJFRklYX01BUFBJTkcsIGRhdGFfZW5kUHJlZml4TWFwcGluZy50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGhtLnB1dChLRVlfUFJPQ0VTU0lOR19JTlNUUlVDVElPTiwKKyAgICAgICAgICAgICAgICAgICAgZGF0YV9wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24udG9TdHJpbmcoKSk7CisgICAgICAgICAgICBobS5wdXQoS0VZX1NLSVBQRURfRU5USVRZLCBkYXRhX3NraXBwZWRFbnRpdHkudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBobS5wdXQoS0VZX1NUQVJUX0VMRU1FTlQsIGRhdGFfc3RhcnRFbGVtZW50LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgaG0ucHV0KEtFWV9TVEFSVF9QUkVGSVhfTUFQUElORywKKyAgICAgICAgICAgICAgICAgICAgZGF0YV9zdGFydFByZWZpeE1hcHBpbmcudG9TdHJpbmcoKSk7CisgICAgICAgICAgICByZXR1cm4gaG07CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkgeworICAgICAgICAgICAgU3RyaW5nIHN0ciA9IG5ldyBTdHJpbmcoY2gsIHN0YXJ0LCBsZW5ndGgpOworICAgICAgICAgICAgZGF0YV90ZXh0LmFwcGVuZChzdHIpOworICAgICAgICAgICAgLy8gZGlmZmVyZW50IHNheCBwYXJzZXJzIGFyZSBhbGxvd2VkIHRvIGhhbmRsZSBjaHVua2luZyBkaWZmZXJlbnRseSwKKyAgICAgICAgICAgIC8vIHRoZXJlZm9yZSB3ZSBjYW5ub3QgcmVseSBvbiBpZGVudGljYWwgY2h1bmtzIGJlaW5nIGRlbGl2ZXJlZC4KKyAgICAgICAgICAgIC8vZGF0YV90ZXh0LmFwcGVuZChQYXJzaW5nU3VwcG9ydC5TRVBBUkFUT1JfRUxFTUVOVCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgICAgZW5kRG9jdW1lbnQoKSB7CisgICAgICAgICAgICBkYXRhX2lzRW5kRG9jdW1lbnQuYXBwZW5kKHRydWUpOworICAgICAgICAgICAgZGF0YV9pc0VuZERvY3VtZW50LmFwcGVuZChTRVBBUkFUT1JfRUxFTUVOVCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkgeworICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICAgICAgc2IuYXBwZW5kKHVyaSk7CisgICAgICAgICAgICBzYi5hcHBlbmQoU0VQQVJBVE9SX1NUUklORyk7CisgICAgICAgICAgICBzYi5hcHBlbmQobG9jYWxOYW1lKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZChTRVBBUkFUT1JfU1RSSU5HKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZChxTmFtZSk7CisgICAgICAgICAgICBkYXRhX2VuZEVsZW1lbnQuYXBwZW5kKHNiKTsKKyAgICAgICAgICAgIGRhdGFfZW5kRWxlbWVudC5hcHBlbmQoU0VQQVJBVE9SX0VMRU1FTlQpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGRhdGFfZXJyb3IuYXBwZW5kKGUpOworICAgICAgICAgICAgZGF0YV9lcnJvci5hcHBlbmQoU0VQQVJBVE9SX0VMRU1FTlQpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZGF0YV9mYXRhbEVycm9yLmFwcGVuZChlKTsKKyAgICAgICAgICAgIGRhdGFfZmF0YWxFcnJvci5hcHBlbmQoU0VQQVJBVE9SX0VMRU1FTlQpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHsKKworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLAorICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCkgeworCisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKSB7CisgICAgICAgICAgICBkYXRhX3Byb2Nlc3NpbmdJbnN0cnVjdGlvbi5hcHBlbmQodGFyZ2V0ICsgU0VQQVJBVE9SX1NUUklORyArIGRhdGEpOworICAgICAgICAgICAgZGF0YV9wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24uYXBwZW5kKFNFUEFSQVRPUl9FTEVNRU5UKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgSW5wdXRTb3VyY2UgICAgcmVzb2x2ZUVudGl0eShTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikgeworCisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHsKKyAgICAgICAgICAgIGRhdGFfaXNTdGFydERvY3VtZW50LmFwcGVuZCh0cnVlKTsKKyAgICAgICAgICAgIGRhdGFfaXNTdGFydERvY3VtZW50LmFwcGVuZChTRVBBUkFUT1JfRUxFTUVOVCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lLAorICAgICAgICAgICAgICAgIEF0dHJpYnV0ZXMgYXR0cmlidXRlcykgeworICAgICAgICAgICAgZGF0YV9zdGFydEVsZW1lbnQuYXBwZW5kKHVyaSk7CisgICAgICAgICAgICBkYXRhX3N0YXJ0RWxlbWVudC5hcHBlbmQoU0VQQVJBVE9SX1NUUklORyk7CisgICAgICAgICAgICBkYXRhX3N0YXJ0RWxlbWVudC5hcHBlbmQobG9jYWxOYW1lKTsKKyAgICAgICAgICAgIGRhdGFfc3RhcnRFbGVtZW50LmFwcGVuZChTRVBBUkFUT1JfU1RSSU5HKTsKKyAgICAgICAgICAgIGRhdGFfc3RhcnRFbGVtZW50LmFwcGVuZChxTmFtZSk7CisKKyAgICAgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOyBpICsrKQorICAgICAgICAgICAgICAgIGRhdGFfc3RhcnRFbGVtZW50LmFwcGVuZChTRVBBUkFUT1JfU1RSSU5HCisgICAgICAgICAgICAgICAgICAgICAgICArIGF0dHJpYnV0ZXMuZ2V0UU5hbWUoaSkgKworICAgICAgICAgICAgICAgICAgICAgICAgU0VQQVJBVE9SX1NUUklORyArIGF0dHJpYnV0ZXMuZ2V0VmFsdWUoaSkpOworCisgICAgICAgICAgICBkYXRhX2lzU3RhcnREb2N1bWVudC5hcHBlbmQoU0VQQVJBVE9SX0VMRU1FTlQpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLAorICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIG5vdGF0aW9uTmFtZSkgeworCisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgd2FybmluZyhTQVhQYXJzZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBkYXRhX3dhcm5pbmcuYXBwZW5kKGUpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcvYXBhY2hlL2hhcm1vbnkva2VybmVsL2RhbHZpay9UaHJlYWRzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcvYXBhY2hlL2hhcm1vbnkva2VybmVsL2RhbHZpay9UaHJlYWRzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI4NmQ0YWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy9hcGFjaGUvaGFybW9ueS9rZXJuZWwvZGFsdmlrL1RocmVhZHNUZXN0LmphdmEKQEAgLTAsMCArMSwyNTkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5vcmcuYXBhY2hlLmhhcm1vbnkua2VybmVsLmRhbHZpazsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkZpZWxkOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgc3VuLm1pc2MuVW5zYWZlOworCisvKioKKyAqIFRlc3RzIGZvciB0aGUgPGNvZGU+cGFyaygpPC9jb2RlPiBmdW5jdGlvbmFsaXR5IG9mIHtAbGluayBVbnNhZmV9LgorICovCitwdWJsaWMgY2xhc3MgVGhyZWFkc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgVW5zYWZlIFVOU0FGRSA9IG51bGw7CisgICAgcHJpdmF0ZSBzdGF0aWMgUnVudGltZUV4Y2VwdGlvbiBJTklUSUFMSVpFRkFJTEVEID0gbnVsbDsKKworICAgIHN0YXRpYyB7CisgICAgICAgIC8qCisgICAgICAgICAqIFNldCB1cCB7QGxpbmsgI1VOU0FGRX0uIFRoaXMgc3VidmVydHMgdGhlIGFjY2VzcyBjaGVjayB0bworICAgICAgICAgKiBnZXQgdGhlIHVuaXF1ZSBVbnNhZmUgaW5zdGFuY2UuIFdlIGNhbiBkbyB0aGlzIGJlY2F1c2UKKyAgICAgICAgICogdGhlcmUncyBubyBzZWN1cml0eSBtYW5hZ2VyIGluc3RhbGxlZCB3aGVuIHJ1bm5pbmcgdGhlCisgICAgICAgICAqIHRlc3QuCisgICAgICAgICAqLworICAgICAgICB0cnkgeworICAgICAgICAgICAgRmllbGQgZmllbGQgPSBVbnNhZmUuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgiVEhFX09ORSIpOworICAgICAgICAgICAgZmllbGQuc2V0QWNjZXNzaWJsZSh0cnVlKTsKKworICAgICAgICAgICAgVU5TQUZFID0gKFVuc2FmZSkgZmllbGQuZ2V0KG51bGwpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hGaWVsZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgSU5JVElBTElaRUZBSUxFRCA9IG5ldyBSdW50aW1lRXhjZXB0aW9uKGV4KTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgSU5JVElBTElaRUZBSUxFRCA9IG5ldyBSdW50aW1lRXhjZXB0aW9uKGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKiBUZXN0IHRoZSBjYXNlIHdoZXJlIHRoZSBwYXJrIHRpbWVzIG91dC4gKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BhcmtGb3JfMSgpIHsKKyAgICAgICAgUGFya2VyIHBhcmtlciA9IG5ldyBQYXJrZXIoZmFsc2UsIDUwMCk7CisgICAgICAgIFRocmVhZCBwYXJrZXJUaHJlYWQgPSBuZXcgVGhyZWFkKHBhcmtlcik7CisgICAgICAgIFRocmVhZCB3YWl0ZXJUaHJlYWQgPQorICAgICAgICAgICAgbmV3IFRocmVhZChuZXcgV2FpdEFuZFVucGFyaygxMDAwLCBwYXJrZXJUaHJlYWQpKTsKKworICAgICAgICBwYXJrZXJUaHJlYWQuc3RhcnQoKTsKKyAgICAgICAgd2FpdGVyVGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIHBhcmtlci5hc3NlcnREdXJhdGlvbklzSW5SYW5nZSg1MDApOworICAgIH0KKworICAgIC8qKiBUZXN0IHRoZSBjYXNlIHdoZXJlIHRoZSB1bnBhcmsgaGFwcGVucyBiZWZvcmUgdGhlIHRpbWVvdXQuICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wYXJrRm9yXzIoKSB7CisgICAgICAgIFBhcmtlciBwYXJrZXIgPSBuZXcgUGFya2VyKGZhbHNlLCAxMDAwKTsKKyAgICAgICAgVGhyZWFkIHBhcmtlclRocmVhZCA9IG5ldyBUaHJlYWQocGFya2VyKTsKKyAgICAgICAgVGhyZWFkIHdhaXRlclRocmVhZCA9CisgICAgICAgICAgICBuZXcgVGhyZWFkKG5ldyBXYWl0QW5kVW5wYXJrKDMwMCwgcGFya2VyVGhyZWFkKSk7CisKKyAgICAgICAgcGFya2VyVGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIHdhaXRlclRocmVhZC5zdGFydCgpOworICAgICAgICBwYXJrZXIuYXNzZXJ0RHVyYXRpb25Jc0luUmFuZ2UoMzAwKTsKKyAgICB9CisKKyAgICAvKiogVGVzdCB0aGUgY2FzZSB3aGVyZSB0aGUgdGhyZWFkIGlzIHByZWVtcHRpdmVseSB1bnBhcmtlZC4gKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BhcmtGb3JfMygpIHsKKyAgICAgICAgUGFya2VyIHBhcmtlciA9IG5ldyBQYXJrZXIoZmFsc2UsIDEwMDApOworICAgICAgICBUaHJlYWQgcGFya2VyVGhyZWFkID0gbmV3IFRocmVhZChwYXJrZXIpOworCisgICAgICAgIFVOU0FGRS51bnBhcmsocGFya2VyVGhyZWFkKTsKKyAgICAgICAgcGFya2VyVGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIHBhcmtlci5hc3NlcnREdXJhdGlvbklzSW5SYW5nZSgwKTsKKyAgICB9CisKKyAgICAvKiogVGVzdCB0aGUgY2FzZSB3aGVyZSB0aGUgcGFyayB0aW1lcyBvdXQuICovCisgICAgcHVibGljIHZvaWQgdGVzdF9wYXJrVW50aWxfMSgpIHsKKyAgICAgICAgUGFya2VyIHBhcmtlciA9IG5ldyBQYXJrZXIodHJ1ZSwgNTAwKTsKKyAgICAgICAgVGhyZWFkIHBhcmtlclRocmVhZCA9IG5ldyBUaHJlYWQocGFya2VyKTsKKyAgICAgICAgVGhyZWFkIHdhaXRlclRocmVhZCA9CisgICAgICAgICAgICBuZXcgVGhyZWFkKG5ldyBXYWl0QW5kVW5wYXJrKDEwMDAsIHBhcmtlclRocmVhZCkpOworCisgICAgICAgIHBhcmtlclRocmVhZC5zdGFydCgpOworICAgICAgICB3YWl0ZXJUaHJlYWQuc3RhcnQoKTsKKyAgICAgICAgcGFya2VyLmFzc2VydER1cmF0aW9uSXNJblJhbmdlKDUwMCk7CisgICAgfQorCisgICAgLyoqIFRlc3QgdGhlIGNhc2Ugd2hlcmUgdGhlIHVucGFyayBoYXBwZW5zIGJlZm9yZSB0aGUgdGltZW91dC4gKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BhcmtVbnRpbF8yKCkgeworICAgICAgICBQYXJrZXIgcGFya2VyID0gbmV3IFBhcmtlcih0cnVlLCAxMDAwKTsKKyAgICAgICAgVGhyZWFkIHBhcmtlclRocmVhZCA9IG5ldyBUaHJlYWQocGFya2VyKTsKKyAgICAgICAgVGhyZWFkIHdhaXRlclRocmVhZCA9CisgICAgICAgICAgICBuZXcgVGhyZWFkKG5ldyBXYWl0QW5kVW5wYXJrKDMwMCwgcGFya2VyVGhyZWFkKSk7CisKKyAgICAgICAgcGFya2VyVGhyZWFkLnN0YXJ0KCk7CisgICAgICAgIHdhaXRlclRocmVhZC5zdGFydCgpOworICAgICAgICBwYXJrZXIuYXNzZXJ0RHVyYXRpb25Jc0luUmFuZ2UoMzAwKTsKKyAgICB9CisKKyAgICAvKiogVGVzdCB0aGUgY2FzZSB3aGVyZSB0aGUgdGhyZWFkIGlzIHByZWVtcHRpdmVseSB1bnBhcmtlZC4gKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3BhcmtVbnRpbF8zKCkgeworICAgICAgICBQYXJrZXIgcGFya2VyID0gbmV3IFBhcmtlcih0cnVlLCAxMDAwKTsKKyAgICAgICAgVGhyZWFkIHBhcmtlclRocmVhZCA9IG5ldyBUaHJlYWQocGFya2VyKTsKKworICAgICAgICBVTlNBRkUudW5wYXJrKHBhcmtlclRocmVhZCk7CisgICAgICAgIHBhcmtlclRocmVhZC5zdGFydCgpOworICAgICAgICBwYXJrZXIuYXNzZXJ0RHVyYXRpb25Jc0luUmFuZ2UoMCk7CisgICAgfQorCisgICAgLy8gVE9ETzogQWRkIG1vcmUgdGVzdHMuCisKKyAgICAvKioKKyAgICAgKiBIZWxwZXIgPGNvZGU+UnVubmFibGU8L2NvZGU+IGZvciB0ZXN0cywgd2hpY2ggcGFya3MgZm9yIG9yIHVudGlsCisgICAgICogdGhlIGluZGljYXRlZCB2YWx1ZSwgbm90aW5nIHRoZSBkdXJhdGlvbiBvZiB0aW1lIGFjdHVhbGx5IHBhcmtlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBQYXJrZXIgaW1wbGVtZW50cyBSdW5uYWJsZSB7CisgICAgICAgIC8qKiB3aGV0aGVyIHtAbGluayAjYW1vdW50fSBpcyBtaWxsaXNlY29uZHMgdG8gd2FpdCBpbiBhbgorICAgICAgICAgKiBhYnNvbHV0ZSBmYXNoaW9uICg8Y29kZT50cnVlPC9jb2RlPikgb3IgbmFub3NlY29uZHMgdG8gd2FpdAorICAgICAgICAgKiBpbiBhIHJlbGF0aXZlIGZhc2hpb24gKDxjb2RlPmZhbHNlPC9jb2RlPikgKi8KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGFic29sdXRlOworCisgICAgICAgIC8qKiBhbW91bnQgdG8gd2FpdCAoc2VlIGFib3ZlKSAqLworICAgICAgICBwcml2YXRlIGZpbmFsIGxvbmcgYW1vdW50OworCisgICAgICAgIC8qKiB3aGV0aGVyIHRoZSBydW4gaGFzIGNvbXBsZXRlZCAqLworICAgICAgICBwcml2YXRlIGJvb2xlYW4gY29tcGxldGVkOworCisgICAgICAgIC8qKiByZWNvcmRlZCBzdGFydCB0aW1lICovCisgICAgICAgIHByaXZhdGUgbG9uZyBzdGFydE1pbGxpczsKKworICAgICAgICAvKiogcmVjb3JkZWQgZW5kIHRpbWUgKi8KKyAgICAgICAgcHJpdmF0ZSBsb25nIGVuZE1pbGxpczsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0IGFuIGluc3RhbmNlLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gYWJzb2x1dGUgd2hldGhlciB0byB1c2UgYW4gYWJzb2x1dGUgdGltZSBvciBub3Q7IGluCisgICAgICAgICAqIGVpdGhlciBjYXNlLCB0aGlzIGNvbnN0cnVjdG9yIHRha2VzIGEgZHVyYXRpb24gdG8gcGFyayBmb3IKKyAgICAgICAgICogQHBhcmFtIHBhcmtNaWxsaXMgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gYmUgcGFya2VkCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgUGFya2VyKGJvb2xlYW4gYWJzb2x1dGUsIGxvbmcgcGFya01pbGxpcykgeworICAgICAgICAgICAgdGhpcy5hYnNvbHV0ZSA9IGFic29sdXRlOworCisgICAgICAgICAgICAvLyBNdWx0aXBseSBieSAxMDAwMDAwIGJlY2F1c2UgcGFya0ZvcigpIHRha2VzIG5hbm9zZWNvbmRzLgorICAgICAgICAgICAgdGhpcy5hbW91bnQgPSBhYnNvbHV0ZSA/IHBhcmtNaWxsaXMgOiBwYXJrTWlsbGlzICogMTAwMDAwMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIGJvb2xlYW4gYWJzb2x1dGUgPSB0aGlzLmFic29sdXRlOworICAgICAgICAgICAgbG9uZyBhbW91bnQgPSB0aGlzLmFtb3VudDsKKyAgICAgICAgICAgIGxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKworICAgICAgICAgICAgaWYgKGFic29sdXRlKSB7CisgICAgICAgICAgICAgICAgVU5TQUZFLnBhcmsodHJ1ZSwgc3RhcnQgKyBhbW91bnQpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBVTlNBRkUucGFyayhmYWxzZSwgYW1vdW50KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgbG9uZyBlbmQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKworICAgICAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICAgICAgc3RhcnRNaWxsaXMgPSBzdGFydDsKKyAgICAgICAgICAgICAgICBlbmRNaWxsaXMgPSBlbmQ7CisgICAgICAgICAgICAgICAgY29tcGxldGVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBub3RpZnlBbGwoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBXYWl0IGZvciB0aGUgdGVzdCB0byBjb21wbGV0ZSBhbmQgcmV0dXJuIHRoZSBkdXJhdGlvbi4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG1heFdhaXRNaWxsaXMgdGhlIG1heGltdW0gYW1vdW50IG9mIHRpbWUgdG8KKyAgICAgICAgICogd2FpdCBmb3IgdGhlIHRlc3QgdG8gY29tcGxldGUKKyAgICAgICAgICogQHJldHVybiB0aGUgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgbG9uZyBnZXREdXJhdGlvbk1pbGxpcyhsb25nIG1heFdhaXRNaWxsaXMpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgICAgIGlmICghIGNvbXBsZXRlZCkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgd2FpdChtYXhXYWl0TWlsbGlzKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIElnbm9yZSBpdC4KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoISBjb21wbGV0ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIEFzc2VydC5mYWlsKCJwYXJrZXIgaGFuZ2luZyIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcmV0dXJuIGVuZE1pbGxpcyAtIHN0YXJ0TWlsbGlzOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEFzc2VydHMgdGhhdCB0aGUgYWN0dWFsIGR1cmF0aW9uIGlzIHdpdGhpbiA1JSBvZiB0aGUKKyAgICAgICAgICogZ2l2ZW4gZXhwZWN0ZWQgdGltZS4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIGV4cGVjdGVkTWlsbGlzIHRoZSBleHBlY3RlZCBkdXJhdGlvbiwgaW4gbWlsbGlzZWNvbmRzCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgdm9pZCBhc3NlcnREdXJhdGlvbklzSW5SYW5nZShsb25nIGV4cGVjdGVkTWlsbGlzKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogQWxsb3cgYSBiaXQgbW9yZSBzbG9wIGZvciB0aGUgbWF4aW11bSBvbiAiZXhwZWN0ZWQKKyAgICAgICAgICAgICAqIGluc3RhbnRhbmVvdXMiIHJlc3VsdHMuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGxvbmcgbWluaW11bSA9IChsb25nKSAoKGRvdWJsZSkgZXhwZWN0ZWRNaWxsaXMgKiAwLjk1KTsKKyAgICAgICAgICAgIGxvbmcgbWF4aW11bSA9CisgICAgICAgICAgICAgICAgTWF0aC5tYXgoKGxvbmcpICgoZG91YmxlKSBleHBlY3RlZE1pbGxpcyAqIDEuMDUpLCAxMCk7CisgICAgICAgICAgICBsb25nIHdhaXRNaWxsaXMgPSBNYXRoLm1heChleHBlY3RlZE1pbGxpcyAqIDEwLCAxMCk7CisgICAgICAgICAgICBsb25nIGR1cmF0aW9uID0gZ2V0RHVyYXRpb25NaWxsaXMod2FpdE1pbGxpcyk7CisKKyAgICAgICAgICAgIGlmIChkdXJhdGlvbiA8IG1pbmltdW0pIHsKKyAgICAgICAgICAgICAgICBBc3NlcnQuZmFpbCgiZXhwZWN0ZWQgZHVyYXRpb246ICIgKyBleHBlY3RlZE1pbGxpcyArCisgICAgICAgICAgICAgICAgICAgICAgICAiOyBhY3R1YWwgdG9vIHNob3J0OiAiICsgZHVyYXRpb24pOworICAgICAgICAgICAgfSBlbHNlIGlmIChkdXJhdGlvbiA+IG1heGltdW0pIHsKKyAgICAgICAgICAgICAgICBBc3NlcnQuZmFpbCgiZXhwZWN0ZWQgZHVyYXRpb246ICIgKyBleHBlY3RlZE1pbGxpcyArCisgICAgICAgICAgICAgICAgICAgICAgICAiOyBhY3R1YWwgdG9vIGxvbmc6ICIgKyBkdXJhdGlvbik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBIZWxwZXIgPGNvZGU+UnVubmFibGU8L2NvZGU+IGZvciB0ZXN0cywgd2hpY2ggd2FpdHMgZm9yIHRoZQorICAgICAqIHNwZWNpZmllZCBhbW91bnQgb2YgdGltZSBhbmQgdGhlbiB1bnBhcmtzIGFuIGluZGljYXRlZCB0aHJlYWQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgV2FpdEFuZFVucGFyayBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBsb25nIHdhaXRNaWxsaXM7CisgICAgICAgIHByaXZhdGUgZmluYWwgVGhyZWFkIHRocmVhZDsKKworICAgICAgICBwdWJsaWMgV2FpdEFuZFVucGFyayhsb25nIHdhaXRNaWxsaXMsIFRocmVhZCB0aHJlYWQpIHsKKyAgICAgICAgICAgIHRoaXMud2FpdE1pbGxpcyA9IHdhaXRNaWxsaXM7CisgICAgICAgICAgICB0aGlzLnRocmVhZCA9IHRocmVhZDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKHdhaXRNaWxsaXMpOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigic2hvdWxkbid0IGhhcHBlbiIsIGV4KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgVU5TQUZFLnVucGFyayh0aHJlYWQpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKElOSVRJQUxJWkVGQUlMRUQgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgSU5JVElBTElaRUZBSUxFRDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvSGFuZGxlckJhc2VUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L0hhbmRsZXJCYXNlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhkZmUzOGIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L0hhbmRsZXJCYXNlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTUxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5vcmcueG1sLnNheDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3Q7CitpbXBvcnQgb3JnLnhtbC5zYXguSGFuZGxlckJhc2U7CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlTGlzdEltcGw7CitpbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5Mb2NhdG9ySW1wbDsKKworQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKK3B1YmxpYyBjbGFzcyBIYW5kbGVyQmFzZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKgorICAgICAqIE5vdGU6IG1vc3Qgb2YgdGhlIHRlc3RzIGhhdmUgdG8gY2hlY2sgZm9yIGFuIGVtcHR5IGltcGxlbWVudGF0aW9uIG9mIHRoZQorICAgICAqIHJlc3BlY3RpdmUgbWV0aG9kcyBhbmQsIGFzIGEgcmVzdWx0LCBhcmUgc29tZXdoYXQgdHJpdmlhbC4KKyAgICAgKi8KKworICAgIHByaXZhdGUgSGFuZGxlckJhc2UgaCA9IG5ldyBIYW5kbGVyQmFzZSgpOworCisgICAgcHVibGljIHZvaWQgdGVzdFJlc29sdmVFbnRpdHkoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBoLnJlc29sdmVFbnRpdHkoInB1YmxpY0lEIiwgInN5c3RlbUlEIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROb3RhdGlvbkRlY2woKSB7CisgICAgICAgIGgubm90YXRpb25EZWNsKCJuYW1lIiwgInB1YmxpY0lEIiwgInN5c3RlbUlEIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFVucGFyc2VkRW50aXR5RGVjbCgpIHsKKyAgICAgICAgaC51bnBhcnNlZEVudGl0eURlY2woIm5hbWUiLCAicHVibGljSUQiLCAic3lzdGVtSUQiLCAibm90YXRpb25OYW1lIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldERvY3VtZW50TG9jYXRvcigpIHsKKyAgICAgICAgaC5zZXREb2N1bWVudExvY2F0b3IobmV3IExvY2F0b3JJbXBsKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdGFydERvY3VtZW50KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaC5zdGFydERvY3VtZW50KCk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbmREb2N1bWVudCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguZW5kRG9jdW1lbnQoKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0YXJ0RWxlbWVudCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguc3RhcnRFbGVtZW50KCJuYW1lIiwgbmV3IEF0dHJpYnV0ZUxpc3RJbXBsKCkpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5kRWxlbWVudCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguZW5kRWxlbWVudCgibmFtZSIpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2hhcmFjdGVycygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguY2hhcmFjdGVycygiVGhlIHF1aWNrIGJyb3duIGZveCIudG9DaGFyQXJyYXkoKSwgNCwgMTEpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWdub3JhYmxlV2hpdGVzcGFjZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguaWdub3JhYmxlV2hpdGVzcGFjZSgiICAgICAgICAgICAgICAgICAgICIudG9DaGFyQXJyYXkoKSwgNCwgMTEpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJvY2Vzc2luZ0luc3RydWN0aW9uKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaC5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oInRhcmdldCIsICJkYXRhIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RXYXJuaW5nKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaC53YXJuaW5nKG5ldyBTQVhQYXJzZUV4Y2VwdGlvbigiRm9vIiwgbmV3IExvY2F0b3JJbXBsKCkpKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVycm9yKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaC5lcnJvcihuZXcgU0FYUGFyc2VFeGNlcHRpb24oIkZvbyIsIG5ldyBMb2NhdG9ySW1wbCgpKSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGYXRhbEVycm9yKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBoLmZhdGFsRXJyb3IobmV3IFNBWFBhcnNlRXhjZXB0aW9uKCJGb28iLCBuZXcgTG9jYXRvckltcGwoKSkpOworICAgICAgICAgICAgZmFpbCgiU0FYRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gTm8gZXhjZXB0aW9uCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBoLmZhdGFsRXJyb3IobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L0lucHV0U291cmNlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9JbnB1dFNvdXJjZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOTA0MGYwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9JbnB1dFNvdXJjZVRlc3QuamF2YQpAQCAtMCwwICsxLDE2OCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkub3JnLnhtbC5zYXg7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CitpbXBvcnQgamF2YS5pby5TdHJpbmdSZWFkZXI7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKKworcHVibGljIGNsYXNzIElucHV0U291cmNlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnB1dFNvdXJjZSgpIHsKKyAgICAgICAgSW5wdXRTb3VyY2UgaSA9IG5ldyBJbnB1dFNvdXJjZSgpOworCisgICAgICAgIGFzc2VydE51bGwoaS5nZXRCeXRlU3RyZWFtKCkpOworICAgICAgICBhc3NlcnROdWxsKGkuZ2V0Q2hhcmFjdGVyU3RyZWFtKCkpOworICAgICAgICBhc3NlcnROdWxsKGkuZ2V0RW5jb2RpbmcoKSk7CisgICAgICAgIGFzc2VydE51bGwoaS5nZXRQdWJsaWNJZCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChpLmdldFN5c3RlbUlkKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnB1dFNvdXJjZVN0cmluZygpIHsKKyAgICAgICAgSW5wdXRTb3VyY2UgaSA9IG5ldyBJbnB1dFNvdXJjZSgiRm9vIik7CisKKyAgICAgICAgYXNzZXJ0TnVsbChpLmdldEJ5dGVTdHJlYW0oKSk7CisgICAgICAgIGFzc2VydE51bGwoaS5nZXRDaGFyYWN0ZXJTdHJlYW0oKSk7CisgICAgICAgIGFzc2VydE51bGwoaS5nZXRFbmNvZGluZygpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChpLmdldFB1YmxpY0lkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZvbyIsIGkuZ2V0U3lzdGVtSWQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdElucHV0U291cmNlSW5wdXRTdHJlYW0oKSB7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJhaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbMF0pOworCisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2UKKyAgICAgICAgSW5wdXRTb3VyY2UgaSA9IG5ldyBJbnB1dFNvdXJjZShiYWlzKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoYmFpcywgaS5nZXRCeXRlU3RyZWFtKCkpOworICAgICAgICBhc3NlcnROdWxsKGkuZ2V0Q2hhcmFjdGVyU3RyZWFtKCkpOworICAgICAgICBhc3NlcnROdWxsKGkuZ2V0RW5jb2RpbmcoKSk7CisgICAgICAgIGFzc2VydE51bGwoaS5nZXRQdWJsaWNJZCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChpLmdldFN5c3RlbUlkKCkpOworCisgICAgICAgIC8vIE5vIGlucHV0IHN0cmVhbQorICAgICAgICBpID0gbmV3IElucHV0U291cmNlKChJbnB1dFN0cmVhbSludWxsKTsKKworICAgICAgICBhc3NlcnROdWxsKGkuZ2V0Qnl0ZVN0cmVhbSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChpLmdldENoYXJhY3RlclN0cmVhbSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChpLmdldEVuY29kaW5nKCkpOworICAgICAgICBhc3NlcnROdWxsKGkuZ2V0UHVibGljSWQoKSk7CisgICAgICAgIGFzc2VydE51bGwoaS5nZXRTeXN0ZW1JZCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5wdXRTb3VyY2VSZWFkZXIoKSB7CisgICAgICAgIFN0cmluZ1JlYWRlciBzciA9IG5ldyBTdHJpbmdSZWFkZXIoIkhlbGxvLCB3b3JsZC4iKTsKKworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIElucHV0U291cmNlIGkgPSBuZXcgSW5wdXRTb3VyY2Uoc3IpOworCisgICAgICAgIGFzc2VydE51bGwoaS5nZXRCeXRlU3RyZWFtKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoc3IsIGkuZ2V0Q2hhcmFjdGVyU3RyZWFtKCkpOworICAgICAgICBhc3NlcnROdWxsKGkuZ2V0RW5jb2RpbmcoKSk7CisgICAgICAgIGFzc2VydE51bGwoaS5nZXRQdWJsaWNJZCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChpLmdldFN5c3RlbUlkKCkpOworCisgICAgICAgIC8vIE5vIHJlYWRlcgorICAgICAgICBpID0gbmV3IElucHV0U291cmNlKChSZWFkZXIpbnVsbCk7CisKKyAgICAgICAgYXNzZXJ0TnVsbChpLmdldEJ5dGVTdHJlYW0oKSk7CisgICAgICAgIGFzc2VydE51bGwoaS5nZXRDaGFyYWN0ZXJTdHJlYW0oKSk7CisgICAgICAgIGFzc2VydE51bGwoaS5nZXRFbmNvZGluZygpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChpLmdldFB1YmxpY0lkKCkpOworICAgICAgICBhc3NlcnROdWxsKGkuZ2V0U3lzdGVtSWQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldFB1YmxpY0lkR2V0UHVibGljSWQoKSB7CisgICAgICAgIElucHV0U291cmNlIGkgPSBuZXcgSW5wdXRTb3VyY2UoKTsKKworICAgICAgICBpLnNldFB1YmxpY0lkKCJGb28iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJGb28iLCBpLmdldFB1YmxpY0lkKCkpOworCisgICAgICAgIGkuc2V0UHVibGljSWQobnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoaS5nZXRQdWJsaWNJZCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0U3lzdGVtSWRHZXRTeXN0ZW1JZCgpIHsKKyAgICAgICAgSW5wdXRTb3VyY2UgaSA9IG5ldyBJbnB1dFNvdXJjZSgpOworCisgICAgICAgIGkuc2V0U3lzdGVtSWQoIkZvbyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkZvbyIsIGkuZ2V0U3lzdGVtSWQoKSk7CisKKyAgICAgICAgaS5zZXRTeXN0ZW1JZChudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChpLmdldFN5c3RlbUlkKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRCeXRlU3RyZWFtR2V0Qnl0ZVN0cmVhbSgpIHsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSk7CisKKyAgICAgICAgSW5wdXRTb3VyY2UgaSA9IG5ldyBJbnB1dFNvdXJjZSgpOworCisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2UKKyAgICAgICAgaS5zZXRCeXRlU3RyZWFtKGJhaXMpOworCisgICAgICAgIGFzc2VydEVxdWFscyhiYWlzLCBpLmdldEJ5dGVTdHJlYW0oKSk7CisKKyAgICAgICAgLy8gTm8gaW5wdXQgc3RyZWFtCisgICAgICAgIGkuc2V0Qnl0ZVN0cmVhbShudWxsKTsKKworICAgICAgICBhc3NlcnROdWxsKGkuZ2V0Qnl0ZVN0cmVhbSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0RW5jb2RpbmdHZXRFbmNvZGluZygpIHsKKyAgICAgICAgSW5wdXRTb3VyY2UgaSA9IG5ldyBJbnB1dFNvdXJjZSgpOworCisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2UKKyAgICAgICAgaS5zZXRFbmNvZGluZygiS2xpbmdvbiIpOworCisgICAgICAgIGFzc2VydEVxdWFscygiS2xpbmdvbiIsIGkuZ2V0RW5jb2RpbmcoKSk7CisKKyAgICAgICAgLy8gTm8gZW5jb2RpbmcKKyAgICAgICAgaS5zZXRFbmNvZGluZyhudWxsKTsKKworICAgICAgICBhc3NlcnROdWxsKGkuZ2V0RW5jb2RpbmcoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldENoYXJhY3RlclN0cmVhbUdldENoYXJhY3RlclN0cmVhbSgpIHsKKyAgICAgICAgU3RyaW5nUmVhZGVyIHNyID0gbmV3IFN0cmluZ1JlYWRlcigiSGVsbG8sIHdvcmxkLiIpOworCisgICAgICAgIElucHV0U291cmNlIGkgPSBuZXcgSW5wdXRTb3VyY2UoKTsKKworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIGkuc2V0Q2hhcmFjdGVyU3RyZWFtKHNyKTsKKworICAgICAgICBhc3NlcnROdWxsKGkuZ2V0Qnl0ZVN0cmVhbSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNyLCBpLmdldENoYXJhY3RlclN0cmVhbSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChpLmdldEVuY29kaW5nKCkpOworICAgICAgICBhc3NlcnROdWxsKGkuZ2V0UHVibGljSWQoKSk7CisgICAgICAgIGFzc2VydE51bGwoaS5nZXRTeXN0ZW1JZCgpKTsKKworICAgICAgICAvLyBObyByZWFkZXIKKyAgICAgICAgaS5zZXRDaGFyYWN0ZXJTdHJlYW0obnVsbCk7CisKKyAgICAgICAgYXNzZXJ0TnVsbChpLmdldEJ5dGVTdHJlYW0oKSk7CisgICAgICAgIGFzc2VydE51bGwoaS5nZXRDaGFyYWN0ZXJTdHJlYW0oKSk7CisgICAgICAgIGFzc2VydE51bGwoaS5nZXRFbmNvZGluZygpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChpLmdldFB1YmxpY0lkKCkpOworICAgICAgICBhc3NlcnROdWxsKGkuZ2V0U3lzdGVtSWQoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L1NBWEV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvU0FYRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExZDAwZTcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L1NBWEV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDEwMSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkub3JnLnhtbC5zYXg7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247CisKK3B1YmxpYyBjbGFzcyBTQVhFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSID0gIkhvdXN0b24sIHdlIGhhdmUgYSBwcm9ibGVtIjsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RTQVhQYXJzZUV4Y2VwdGlvbigpIHsKKyAgICAgICAgU0FYRXhjZXB0aW9uIGUgPSBuZXcgU0FYRXhjZXB0aW9uKCk7CisKKyAgICAgICAgYXNzZXJ0TnVsbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoZS5nZXRFeGNlcHRpb24oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNBWEV4Y2VwdGlvbl9TdHJpbmdfRXhjZXB0aW9uKCkgeworICAgICAgICBFeGNlcHRpb24gYyA9IG5ldyBFeGNlcHRpb24oKTsKKworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIFNBWEV4Y2VwdGlvbiBlID0gbmV3IFNBWEV4Y2VwdGlvbihFUlIsIGMpOworCisgICAgICAgIGFzc2VydEVxdWFscyhFUlIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGMsIGUuZ2V0RXhjZXB0aW9uKCkpOworCisgICAgICAgIC8vIE5vIG1lc3NhZ2UKKyAgICAgICAgZSA9IG5ldyBTQVhFeGNlcHRpb24obnVsbCwgYyk7CisKKyAgICAgICAgYXNzZXJ0TnVsbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjLCBlLmdldEV4Y2VwdGlvbigpKTsKKworICAgICAgICAvLyBObyBjYXVzZQorICAgICAgICBlID0gbmV3IFNBWFBhcnNlRXhjZXB0aW9uKEVSUiwgbnVsbCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEVSUiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKGUuZ2V0RXhjZXB0aW9uKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTQVhFeGNlcHRpb25fU3RyaW5nKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIFNBWEV4Y2VwdGlvbiBlID0gbmV3IFNBWEV4Y2VwdGlvbihFUlIpOworCisgICAgICAgIGFzc2VydEVxdWFscyhFUlIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChlLmdldEV4Y2VwdGlvbigpKTsKKworICAgICAgICAvLyBObyBtZXNzYWdlCisgICAgICAgIGUgPSBuZXcgU0FYRXhjZXB0aW9uKChTdHJpbmcpbnVsbCk7CisKKyAgICAgICAgYXNzZXJ0TnVsbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoZS5nZXRFeGNlcHRpb24oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNBWEV4Y2VwdGlvbl9FeGNlcHRpb24oKSB7CisgICAgICAgIEV4Y2VwdGlvbiBjID0gbmV3IEV4Y2VwdGlvbigpOworCisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2UKKyAgICAgICAgU0FYRXhjZXB0aW9uIGUgPSBuZXcgU0FYRXhjZXB0aW9uKGMpOworCisgICAgICAgIGFzc2VydE51bGwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYywgZS5nZXRFeGNlcHRpb24oKSk7CisKKyAgICAgICAgLy8gTm8gY2F1c2UKKyAgICAgICAgZSA9IG5ldyBTQVhFeGNlcHRpb24oKEV4Y2VwdGlvbiludWxsKTsKKworICAgICAgICBhc3NlcnROdWxsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChlLmdldEV4Y2VwdGlvbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VG9TdHJpbmcoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2UKKyAgICAgICAgU0FYRXhjZXB0aW9uIGUgPSBuZXcgU0FYRXhjZXB0aW9uKEVSUik7CisgICAgICAgIFN0cmluZyBzID0gZS50b1N0cmluZygpOworCisgICAgICAgIGFzc2VydFRydWUocy5jb250YWlucyhFUlIpKTsKKworICAgICAgICAvLyBObyBtZXNzYWdlCisgICAgICAgIGUgPSBuZXcgU0FYRXhjZXB0aW9uKCk7CisgICAgICAgIHMgPSBlLnRvU3RyaW5nKCk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2Uocy5jb250YWlucyhFUlIpKTsKKyAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNjNzNiNTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L1NBWE5vdFJlY29nbml6ZWRFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw0MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkub3JnLnhtbC5zYXg7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlIgPSAiSG91c3Rvbiwgd2UgaGF2ZSBhIHByb2JsZW0iOworCisgICAgcHVibGljIHZvaWQgdGVzdFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oKSB7CisgICAgICAgIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZSA9IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoZS5nZXRNZXNzYWdlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uX1N0cmluZygpIHsKKyAgICAgICAgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBlID0gbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oRVJSKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEVSUiwgZS5nZXRNZXNzYWdlKCkpOworCisgICAgICAgIGUgPSBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChlLmdldE1lc3NhZ2UoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L1NBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcxZWE0NTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L1NBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5vcmcueG1sLnNheDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKKworcHVibGljIGNsYXNzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlIgPSAiSG91c3Rvbiwgd2UgaGF2ZSBhIHByb2JsZW0iOworCisgICAgcHVibGljIHZvaWQgdGVzdFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigpIHsKKyAgICAgICAgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUgPSBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoZS5nZXRNZXNzYWdlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb25fU3RyaW5nKCkgeworICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSA9IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oRVJSKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEVSUiwgZS5nZXRNZXNzYWdlKCkpOworCisgICAgICAgIGUgPSBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKG51bGwpOworICAgICAgICBhc3NlcnROdWxsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvU0FYUGFyc2VFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L1NBWFBhcnNlRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJmYzQ4ZDQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L1NBWFBhcnNlRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjE2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5vcmcueG1sLnNheDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5Mb2NhdG9ySW1wbDsKKworcHVibGljIGNsYXNzIFNBWFBhcnNlRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUiA9ICJIb3VzdG9uLCB3ZSBoYXZlIGEgcHJvYmxlbSI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTWVMgPSAibXlTeXN0ZW1JRCI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQVUIgPSAibXlQdWJsaWNJRCI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST1cgPSAxOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09MID0gMjsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RTQVhQYXJzZUV4Y2VwdGlvbl9TdHJpbmdfTG9jYXRvcl9FeGNlcHRpb24oKSB7CisgICAgICAgIExvY2F0b3JJbXBsIGwgPSBuZXcgTG9jYXRvckltcGwoKTsKKyAgICAgICAgbC5zZXRQdWJsaWNJZChQVUIpOworICAgICAgICBsLnNldFN5c3RlbUlkKFNZUyk7CisgICAgICAgIGwuc2V0TGluZU51bWJlcihST1cpOworICAgICAgICBsLnNldENvbHVtbk51bWJlcihDT0wpOworCisgICAgICAgIEV4Y2VwdGlvbiBjID0gbmV3IEV4Y2VwdGlvbigpOworCisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2UKKyAgICAgICAgU0FYUGFyc2VFeGNlcHRpb24gZSA9IG5ldyBTQVhQYXJzZUV4Y2VwdGlvbihFUlIsIGwsIGMpOworCisgICAgICAgIGFzc2VydEVxdWFscyhFUlIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGMsIGUuZ2V0RXhjZXB0aW9uKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscyhQVUIsIGUuZ2V0UHVibGljSWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhTWVMsIGUuZ2V0U3lzdGVtSWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhST1csIGUuZ2V0TGluZU51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENPTCwgZS5nZXRDb2x1bW5OdW1iZXIoKSk7CisKKyAgICAgICAgLy8gTm8gbWVzc2FnZQorICAgICAgICBlID0gbmV3IFNBWFBhcnNlRXhjZXB0aW9uKG51bGwsIGwsIGMpOworCisgICAgICAgIGFzc2VydE51bGwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYywgZS5nZXRFeGNlcHRpb24oKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFBVQiwgZS5nZXRQdWJsaWNJZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFNZUywgZS5nZXRTeXN0ZW1JZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFJPVywgZS5nZXRMaW5lTnVtYmVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ09MLCBlLmdldENvbHVtbk51bWJlcigpKTsKKworICAgICAgICAvLyBObyBsb2NhdG9yCisgICAgICAgIGUgPSBuZXcgU0FYUGFyc2VFeGNlcHRpb24oRVJSLCBudWxsLCBjKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoRVJSLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjLCBlLmdldEV4Y2VwdGlvbigpKTsKKworICAgICAgICBhc3NlcnROdWxsKGUuZ2V0UHVibGljSWQoKSk7CisgICAgICAgIGFzc2VydE51bGwoZS5nZXRTeXN0ZW1JZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBlLmdldExpbmVOdW1iZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgZS5nZXRDb2x1bW5OdW1iZXIoKSk7CisKKyAgICAgICAgLy8gTm8gY2F1c2UKKyAgICAgICAgZSA9IG5ldyBTQVhQYXJzZUV4Y2VwdGlvbihFUlIsIGwsIG51bGwpOworCisgICAgICAgIGFzc2VydEVxdWFscyhFUlIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChlLmdldEV4Y2VwdGlvbigpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoUFVCLCBlLmdldFB1YmxpY0lkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoU1lTLCBlLmdldFN5c3RlbUlkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoUk9XLCBlLmdldExpbmVOdW1iZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDT0wsIGUuZ2V0Q29sdW1uTnVtYmVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTQVhQYXJzZUV4Y2VwdGlvbl9TdHJpbmdfTG9jYXRvcigpIHsKKyAgICAgICAgTG9jYXRvckltcGwgbCA9IG5ldyBMb2NhdG9ySW1wbCgpOworICAgICAgICBsLnNldFB1YmxpY0lkKFBVQik7CisgICAgICAgIGwuc2V0U3lzdGVtSWQoU1lTKTsKKyAgICAgICAgbC5zZXRMaW5lTnVtYmVyKFJPVyk7CisgICAgICAgIGwuc2V0Q29sdW1uTnVtYmVyKENPTCk7CisKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZQorICAgICAgICBTQVhQYXJzZUV4Y2VwdGlvbiBlID0gbmV3IFNBWFBhcnNlRXhjZXB0aW9uKEVSUiwgbCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEVSUiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKGUuZ2V0RXhjZXB0aW9uKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscyhQVUIsIGUuZ2V0UHVibGljSWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhTWVMsIGUuZ2V0U3lzdGVtSWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhST1csIGUuZ2V0TGluZU51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENPTCwgZS5nZXRDb2x1bW5OdW1iZXIoKSk7CisKKyAgICAgICAgLy8gTm8gbWVzc2FnZQorICAgICAgICBlID0gbmV3IFNBWFBhcnNlRXhjZXB0aW9uKG51bGwsIGwpOworCisgICAgICAgIGFzc2VydE51bGwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKGUuZ2V0RXhjZXB0aW9uKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscyhQVUIsIGUuZ2V0UHVibGljSWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhTWVMsIGUuZ2V0U3lzdGVtSWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhST1csIGUuZ2V0TGluZU51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENPTCwgZS5nZXRDb2x1bW5OdW1iZXIoKSk7CisKKyAgICAgICAgLy8gTm8gbG9jYXRvcgorICAgICAgICBlID0gbmV3IFNBWFBhcnNlRXhjZXB0aW9uKEVSUiwgbnVsbCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEVSUiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKGUuZ2V0RXhjZXB0aW9uKCkpOworCisgICAgICAgIGFzc2VydE51bGwoZS5nZXRQdWJsaWNJZCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChlLmdldFN5c3RlbUlkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGUuZ2V0TGluZU51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBlLmdldENvbHVtbk51bWJlcigpKTsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTQVhQYXJzZUV4Y2VwdGlvbl9TdHJpbmdfU3RyaW5nX1N0cmluZ19pbnRfaW50X0V4Y2VwdGlvbigpIHsKKyAgICAgICAgRXhjZXB0aW9uIGMgPSBuZXcgRXhjZXB0aW9uKCk7CisKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZQorICAgICAgICBTQVhQYXJzZUV4Y2VwdGlvbiBlID0gbmV3IFNBWFBhcnNlRXhjZXB0aW9uKEVSUiwgUFVCLCBTWVMsIFJPVywgQ09MLCBjKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoRVJSLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjLCBlLmdldEV4Y2VwdGlvbigpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoUFVCLCBlLmdldFB1YmxpY0lkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoU1lTLCBlLmdldFN5c3RlbUlkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoUk9XLCBlLmdldExpbmVOdW1iZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDT0wsIGUuZ2V0Q29sdW1uTnVtYmVyKCkpOworCisgICAgICAgIC8vIE5vIG1lc3NhZ2UKKyAgICAgICAgZSA9IG5ldyBTQVhQYXJzZUV4Y2VwdGlvbihudWxsLCBQVUIsIFNZUywgUk9XLCBDT0wsIGMpOworCisgICAgICAgIGFzc2VydE51bGwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoYywgZS5nZXRFeGNlcHRpb24oKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFBVQiwgZS5nZXRQdWJsaWNJZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFNZUywgZS5nZXRTeXN0ZW1JZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFJPVywgZS5nZXRMaW5lTnVtYmVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ09MLCBlLmdldENvbHVtbk51bWJlcigpKTsKKworICAgICAgICAvLyBObyBsb2NhdG9yCisgICAgICAgIGUgPSBuZXcgU0FYUGFyc2VFeGNlcHRpb24oRVJSLCBudWxsLCBudWxsLCAtMSwgLTEsIGMpOworCisgICAgICAgIGFzc2VydEVxdWFscyhFUlIsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGMsIGUuZ2V0RXhjZXB0aW9uKCkpOworCisgICAgICAgIGFzc2VydE51bGwoZS5nZXRQdWJsaWNJZCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChlLmdldFN5c3RlbUlkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGUuZ2V0TGluZU51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBlLmdldENvbHVtbk51bWJlcigpKTsKKworICAgICAgICAvLyBObyBjYXVzZQorICAgICAgICBlID0gbmV3IFNBWFBhcnNlRXhjZXB0aW9uKEVSUiwgUFVCLCBTWVMsIFJPVywgQ09MLCBudWxsKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoRVJSLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoZS5nZXRFeGNlcHRpb24oKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFBVQiwgZS5nZXRQdWJsaWNJZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFNZUywgZS5nZXRTeXN0ZW1JZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFJPVywgZS5nZXRMaW5lTnVtYmVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ09MLCBlLmdldENvbHVtbk51bWJlcigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U0FYUGFyc2VFeGNlcHRpb25fU3RyaW5nX1N0cmluZ19TdHJpbmdfaW50X2ludCgpIHsKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZQorICAgICAgICBTQVhQYXJzZUV4Y2VwdGlvbiBlID0gbmV3IFNBWFBhcnNlRXhjZXB0aW9uKEVSUiwgUFVCLCBTWVMsIFJPVywgQ09MKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoRVJSLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoZS5nZXRFeGNlcHRpb24oKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFBVQiwgZS5nZXRQdWJsaWNJZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFNZUywgZS5nZXRTeXN0ZW1JZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFJPVywgZS5nZXRMaW5lTnVtYmVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ09MLCBlLmdldENvbHVtbk51bWJlcigpKTsKKworICAgICAgICAvLyBObyBtZXNzYWdlCisgICAgICAgIGUgPSBuZXcgU0FYUGFyc2VFeGNlcHRpb24obnVsbCwgUFVCLCBTWVMsIFJPVywgQ09MKTsKKworICAgICAgICBhc3NlcnROdWxsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChlLmdldEV4Y2VwdGlvbigpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoUFVCLCBlLmdldFB1YmxpY0lkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoU1lTLCBlLmdldFN5c3RlbUlkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoUk9XLCBlLmdldExpbmVOdW1iZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhDT0wsIGUuZ2V0Q29sdW1uTnVtYmVyKCkpOworCisgICAgICAgIC8vIE5vIGxvY2F0b3IKKyAgICAgICAgZSA9IG5ldyBTQVhQYXJzZUV4Y2VwdGlvbihFUlIsIG51bGwsIG51bGwsIC0xLCAtMSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEVSUiwgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKGUuZ2V0RXhjZXB0aW9uKCkpOworCisgICAgICAgIGFzc2VydE51bGwoZS5nZXRQdWJsaWNJZCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChlLmdldFN5c3RlbUlkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIGUuZ2V0TGluZU51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBlLmdldENvbHVtbk51bWJlcigpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvZXh0L0F0dHJpYnV0ZXMySW1wbFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvZXh0L0F0dHJpYnV0ZXMySW1wbFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNDhiZWY1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9leHQvQXR0cmlidXRlczJJbXBsVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzkyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5vcmcueG1sLnNheC5leHQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOworaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5BdHRyaWJ1dGVzMkltcGw7CitpbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVzSW1wbDsKKworcHVibGljIGNsYXNzIEF0dHJpYnV0ZXMySW1wbFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvLyBOb3RlOiBUaGUgb3JpZ2luYWwgU0FYMiBpbXBsZW1lbnRhdGlvbiBvZiBBdHRyaWJ1dGVzMkltcGwgaXMKKyAgICAvLyBzZXZlcmVseSBicm9rZW4uIFRodXMgYWxsIG9mIHRoZXNlIHRlc3RzIHdpbGwgcHJvYmFibHkgZmFpbAorICAgIC8vIHVubGVzcyB0aGUgQW5kcm9pZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgY2xhc3MgZ2V0cyBmaXhlZC4KKworICAgIHByaXZhdGUgQXR0cmlidXRlczJJbXBsIGVtcHR5ID0gbmV3IEF0dHJpYnV0ZXMySW1wbCgpOworCisgICAgcHJpdmF0ZSBBdHRyaWJ1dGVzMkltcGwgbXVsdGkgPSBuZXcgQXR0cmlidXRlczJJbXBsKCk7CisKKyAgICBwcml2YXRlIEF0dHJpYnV0ZXMySW1wbCBjZGF0YSA9IG5ldyBBdHRyaWJ1dGVzMkltcGwoKTsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgeworICAgICAgICBtdWx0aS5hZGRBdHRyaWJ1dGUoImh0dHA6Ly9zb21lLnVyaSIsICJmb28iLCAibnMxOmZvbyIsCisgICAgICAgICAgICAgICAgInN0cmluZyIsICJhYmMiKTsKKyAgICAgICAgbXVsdGkuYWRkQXR0cmlidXRlKCJodHRwOi8vc29tZS51cmkiLCAiYmFyIiwgIm5zMTpiYXIiLAorICAgICAgICAgICAgICAgICJzdHJpbmciLCAieHl6Iik7CisgICAgICAgIG11bHRpLmFkZEF0dHJpYnV0ZSgiaHR0cDovL3NvbWUub3RoZXIudXJpIiwgImFuc3dlciIsICJuczI6YW5zd2VyIiwKKyAgICAgICAgICAgICAgICAiaW50IiwgIjQyIik7CisgICAgICAgIG11bHRpLmFkZEF0dHJpYnV0ZSgiaHR0cDovL3lldC5hbm90aGVyLnVyaSIsICJnYWJiYSIsICJuczM6Z2FiYmEiLAorICAgICAgICAgICAgICAgICJzdHJpbmciLCAiZ2FiYmEiKTsKKworICAgICAgICBtdWx0aS5zZXREZWNsYXJlZCgwLCBmYWxzZSk7CisgICAgICAgIG11bHRpLnNldFNwZWNpZmllZCgwLCBmYWxzZSk7CisKKyAgICAgICAgbXVsdGkuc2V0RGVjbGFyZWQoMSwgdHJ1ZSk7CisgICAgICAgIG11bHRpLnNldFNwZWNpZmllZCgxLCBmYWxzZSk7CisKKyAgICAgICAgbXVsdGkuc2V0RGVjbGFyZWQoMiwgZmFsc2UpOworICAgICAgICBtdWx0aS5zZXRTcGVjaWZpZWQoMiwgdHJ1ZSk7CisKKyAgICAgICAgbXVsdGkuc2V0RGVjbGFyZWQoMywgdHJ1ZSk7CisgICAgICAgIG11bHRpLnNldFNwZWNpZmllZCgzLCB0cnVlKTsKKworICAgICAgICBjZGF0YS5hZGRBdHRyaWJ1dGUoImh0dHA6Ly95ZXQuYW5vdGhlci51cmkiLCAiaGV5IiwgIm5zMzpoZXkiLAorICAgICAgICAgICAgICAgICJDREFUQSIsICJoZXkiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0QXR0cmlidXRlcygpIHsKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZSB3aXRoIEF0dHJpYnV0ZXMySW1wbAorICAgICAgICBBdHRyaWJ1dGVzMkltcGwgYXR0cnMgPSBuZXcgQXR0cmlidXRlczJJbXBsKCk7CisgICAgICAgIGF0dHJzLmFkZEF0dHJpYnV0ZSgiIiwgIiIsICJqb2huIiwgInN0cmluZyIsICJkb2UiKTsKKworICAgICAgICBhdHRycy5zZXRBdHRyaWJ1dGVzKGVtcHR5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGF0dHJzLmdldExlbmd0aCgpKTsKKworICAgICAgICBhdHRycy5zZXRBdHRyaWJ1dGVzKG11bHRpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtdWx0aS5nZXRMZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0VVJJKGkpLCBhdHRycy5nZXRVUkkoaSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG11bHRpLmdldExvY2FsTmFtZShpKSwgYXR0cnMuZ2V0TG9jYWxOYW1lKGkpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRRTmFtZShpKSwgYXR0cnMuZ2V0UU5hbWUoaSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG11bHRpLmdldFR5cGUoaSksIGF0dHJzLmdldFR5cGUoaSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG11bHRpLmdldFZhbHVlKGkpLCBhdHRycy5nZXRWYWx1ZShpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuaXNEZWNsYXJlZChpKSwgYXR0cnMuaXNEZWNsYXJlZChpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuaXNTcGVjaWZpZWQoaSksIGF0dHJzLmlzU3BlY2lmaWVkKGkpKTsKKyAgICAgICAgfQorCisgICAgICAgIGF0dHJzLnNldEF0dHJpYnV0ZXMoZW1wdHkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYXR0cnMuZ2V0TGVuZ3RoKCkpOworCisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2Ugd2l0aCBBdHRyaWJ1dGVzSW1wbAorICAgICAgICBhdHRycy5zZXRBdHRyaWJ1dGVzKG5ldyBBdHRyaWJ1dGVzSW1wbChtdWx0aSkpOworICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0TGVuZ3RoKCksIGF0dHJzLmdldExlbmd0aCgpKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG11bHRpLmdldExlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRVUkkoaSksIGF0dHJzLmdldFVSSShpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0TG9jYWxOYW1lKGkpLCBhdHRycy5nZXRMb2NhbE5hbWUoaSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG11bHRpLmdldFFOYW1lKGkpLCBhdHRycy5nZXRRTmFtZShpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0VHlwZShpKSwgYXR0cnMuZ2V0VHlwZShpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0VmFsdWUoaSksIGF0dHJzLmdldFZhbHVlKGkpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBhdHRycy5pc0RlY2xhcmVkKGkpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBhdHRycy5pc1NwZWNpZmllZChpKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBTcGVjaWFsIGNhc2Ugd2l0aCBDREFUQQorICAgICAgICBhdHRycy5zZXRBdHRyaWJ1dGVzKG5ldyBBdHRyaWJ1dGVzSW1wbChjZGF0YSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgYXR0cnMuZ2V0TGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIGF0dHJzLmlzRGVjbGFyZWQoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgYXR0cnMuaXNTcGVjaWZpZWQoMCkpOworCisgICAgICAgIC8vIG51bGwgY2FzZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYXR0cnMuc2V0QXR0cmlidXRlcyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWRkQXR0cmlidXRlKCkgeworICAgICAgICBBdHRyaWJ1dGVzMkltcGwgYXR0cnMgPSBuZXcgQXR0cmlidXRlczJJbXBsKCk7CisKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZQorICAgICAgICBhdHRycy5hZGRBdHRyaWJ1dGUoImh0dHA6Ly95ZXQuYW5vdGhlci51cmkiLCAiZG9lIiwgImpvaG46ZG9lIiwKKyAgICAgICAgICAgICAgICAic3RyaW5nIiwgImFiYyIpOworCisgICAgICAgIGFzc2VydEVxdWFscygxLCBhdHRycy5nZXRMZW5ndGgoKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8veWV0LmFub3RoZXIudXJpIiwgYXR0cnMuZ2V0VVJJKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2UiLCBhdHRycy5nZXRMb2NhbE5hbWUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImpvaG46ZG9lIiwgYXR0cnMuZ2V0UU5hbWUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInN0cmluZyIsIGF0dHJzLmdldFR5cGUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFiYyIsIGF0dHJzLmdldFZhbHVlKDApKTsKKworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgYXR0cnMuaXNEZWNsYXJlZCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBhdHRycy5pc1NwZWNpZmllZCgwKSk7CisKKyAgICAgICAgLy8gQ0RBVEEgY2FzZQorICAgICAgICBhdHRycy5hZGRBdHRyaWJ1dGUoImh0dHA6Ly95ZXQuYW5vdGhlci51cmkiLCAiZG9lIiwgImphbmU6ZG9lIiwKKyAgICAgICAgICAgICAgICAiQ0RBVEEiLCAiYWJjIik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGF0dHJzLmdldExlbmd0aCgpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly95ZXQuYW5vdGhlci51cmkiLCBhdHRycy5nZXRVUkkoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvZSIsIGF0dHJzLmdldExvY2FsTmFtZSgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiamFuZTpkb2UiLCBhdHRycy5nZXRRTmFtZSgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiQ0RBVEEiLCBhdHRycy5nZXRUeXBlKDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhYmMiLCBhdHRycy5nZXRWYWx1ZSgxKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBhdHRycy5pc0RlY2xhcmVkKDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGF0dHJzLmlzU3BlY2lmaWVkKDEpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlQXR0cmlidXRlKCkgeworICAgICAgICBBdHRyaWJ1dGVzMkltcGwgYXR0cnMgPSBuZXcgQXR0cmlidXRlczJJbXBsKG11bHRpKTsKKworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIGF0dHJzLnJlbW92ZUF0dHJpYnV0ZSgxKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMywgYXR0cnMuZ2V0TGVuZ3RoKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRVUkkoMCksIGF0dHJzLmdldFVSSSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRMb2NhbE5hbWUoMCksIGF0dHJzLmdldExvY2FsTmFtZSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRRTmFtZSgwKSwgYXR0cnMuZ2V0UU5hbWUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0VHlwZSgwKSwgYXR0cnMuZ2V0VHlwZSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRWYWx1ZSgwKSwgYXR0cnMuZ2V0VmFsdWUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuaXNEZWNsYXJlZCgwKSwgYXR0cnMuaXNEZWNsYXJlZCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5pc1NwZWNpZmllZCgwKSwgYXR0cnMuaXNTcGVjaWZpZWQoMCkpOworCisgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRVUkkoMiksIGF0dHJzLmdldFVSSSgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRMb2NhbE5hbWUoMiksIGF0dHJzLmdldExvY2FsTmFtZSgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRRTmFtZSgyKSwgYXR0cnMuZ2V0UU5hbWUoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0VHlwZSgyKSwgYXR0cnMuZ2V0VHlwZSgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRWYWx1ZSgyKSwgYXR0cnMuZ2V0VmFsdWUoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuaXNEZWNsYXJlZCgyKSwgYXR0cnMuaXNEZWNsYXJlZCgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5pc1NwZWNpZmllZCgyKSwgYXR0cnMuaXNTcGVjaWZpZWQoMSkpOworCisgICAgICAgIC8vIE91dCBvZiByYW5nZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYXR0cnMucmVtb3ZlQXR0cmlidXRlKC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhdHRycy5yZW1vdmVBdHRyaWJ1dGUoMyk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXR0cmlidXRlczJJbXBsKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZW1wdHkuZ2V0TGVuZ3RoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdHRyaWJ1dGVzMkltcGxBdHRyaWJ1dGVzKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlIHdpdGggQXR0cmlidXRlczJJbXBsCisgICAgICAgIEF0dHJpYnV0ZXMySW1wbCBhdHRycyA9IG5ldyBBdHRyaWJ1dGVzMkltcGwobXVsdGkpOworICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0TGVuZ3RoKCksIGF0dHJzLmdldExlbmd0aCgpKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG11bHRpLmdldExlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRVUkkoaSksIGF0dHJzLmdldFVSSShpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0TG9jYWxOYW1lKGkpLCBhdHRycy5nZXRMb2NhbE5hbWUoaSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG11bHRpLmdldFFOYW1lKGkpLCBhdHRycy5nZXRRTmFtZShpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0VHlwZShpKSwgYXR0cnMuZ2V0VHlwZShpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0VmFsdWUoaSksIGF0dHJzLmdldFZhbHVlKGkpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5pc0RlY2xhcmVkKGkpLCBhdHRycy5pc0RlY2xhcmVkKGkpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5pc1NwZWNpZmllZChpKSwgYXR0cnMuaXNTcGVjaWZpZWQoaSkpOworICAgICAgICB9CisKKyAgICAgICAgYXR0cnMgPSBuZXcgQXR0cmlidXRlczJJbXBsKGVtcHR5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGF0dHJzLmdldExlbmd0aCgpKTsKKworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlIHdpdGggQXR0cmlidXRlc0ltcGwKKyAgICAgICAgYXR0cnMgPSBuZXcgQXR0cmlidXRlczJJbXBsKG5ldyBBdHRyaWJ1dGVzSW1wbChtdWx0aSkpOworICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0TGVuZ3RoKCksIGF0dHJzLmdldExlbmd0aCgpKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG11bHRpLmdldExlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRVUkkoaSksIGF0dHJzLmdldFVSSShpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0TG9jYWxOYW1lKGkpLCBhdHRycy5nZXRMb2NhbE5hbWUoaSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG11bHRpLmdldFFOYW1lKGkpLCBhdHRycy5nZXRRTmFtZShpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0VHlwZShpKSwgYXR0cnMuZ2V0VHlwZShpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0VmFsdWUoaSksIGF0dHJzLmdldFZhbHVlKGkpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBhdHRycy5pc0RlY2xhcmVkKGkpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBhdHRycy5pc1NwZWNpZmllZChpKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBTcGVjaWFsIGNhc2Ugd2l0aCBDREFUQQorICAgICAgICBhdHRycyA9IG5ldyBBdHRyaWJ1dGVzMkltcGwobmV3IEF0dHJpYnV0ZXNJbXBsKGNkYXRhKSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBhdHRycy5nZXRMZW5ndGgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgYXR0cnMuaXNEZWNsYXJlZCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBhdHRycy5pc1NwZWNpZmllZCgwKSk7CisKKyAgICAgICAgLy8gbnVsbCBjYXNlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhdHRycyA9IG5ldyBBdHRyaWJ1dGVzMkltcGwobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdElzRGVjbGFyZWRJbnQoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2VzCisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgbXVsdGkuaXNEZWNsYXJlZCgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBtdWx0aS5pc0RlY2xhcmVkKDEpKTsKKworICAgICAgICAvLyBPdXQgb2YgcmFuZ2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG11bHRpLmlzRGVjbGFyZWQoLTEpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG11bHRpLmlzRGVjbGFyZWQoNCk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNEZWNsYXJlZFN0cmluZ1N0cmluZygpIHsKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZXMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBtdWx0aS5pc0RlY2xhcmVkKCJodHRwOi8vc29tZS51cmkiLCAiZm9vIikpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgbXVsdGkuaXNEZWNsYXJlZCgiaHR0cDovL3NvbWUudXJpIiwgImJhciIpKTsKKworICAgICAgICAvLyBOb3QgZm91bmQKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKG11bHRpLmlzRGVjbGFyZWQoIm5vdCIsICJmb3VuZCIpKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJc0RlY2xhcmVkU3RyaW5nKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlcworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIG11bHRpLmlzRGVjbGFyZWQoIm5zMTpmb28iKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBtdWx0aS5pc0RlY2xhcmVkKCJuczE6YmFyIikpOworCisgICAgICAgIC8vIE5vdCBmb3VuZAorICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UobXVsdGkuaXNEZWNsYXJlZCgibm90Zm91bmQiKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNTcGVjaWZpZWRJbnQoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2VzCisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgbXVsdGkuaXNTcGVjaWZpZWQoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgbXVsdGkuaXNTcGVjaWZpZWQoMikpOworCisgICAgICAgIC8vIE91dCBvZiByYW5nZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbXVsdGkuaXNTcGVjaWZpZWQoLTEpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG11bHRpLmlzU3BlY2lmaWVkKDQpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdElzU3BlY2lmaWVkU3RyaW5nU3RyaW5nKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlcworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIG11bHRpLmlzU3BlY2lmaWVkKCJodHRwOi8vc29tZS51cmkiLCAiYmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgbXVsdGkuaXNTcGVjaWZpZWQoImh0dHA6Ly9zb21lLm90aGVyLnVyaSIsICJhbnN3ZXIiKSk7CisKKyAgICAgICAgLy8gTm90IGZvdW5kCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShtdWx0aS5pc1NwZWNpZmllZCgibm90IiwgImZvdW5kIikpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdElzU3BlY2lmaWVkU3RyaW5nKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlcworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIG11bHRpLmlzU3BlY2lmaWVkKCJuczE6YmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgbXVsdGkuaXNTcGVjaWZpZWQoIm5zMjphbnN3ZXIiKSk7CisKKyAgICAgICAgLy8gTm90IGZvdW5kCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShtdWx0aS5pc1NwZWNpZmllZCgibm90Zm91bmQiKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0RGVjbGFyZWQoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2VzCisgICAgICAgIG11bHRpLnNldFNwZWNpZmllZCgwLCBmYWxzZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgbXVsdGkuaXNTcGVjaWZpZWQoMCkpOworCisgICAgICAgIG11bHRpLnNldFNwZWNpZmllZCgwLCB0cnVlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIG11bHRpLmlzU3BlY2lmaWVkKDApKTsKKworICAgICAgICBtdWx0aS5zZXRTcGVjaWZpZWQoMCwgZmFsc2UpOworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIG11bHRpLmlzU3BlY2lmaWVkKDApKTsKKworICAgICAgICAvLyBPdXQgb2YgcmFuZ2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG11bHRpLnNldFNwZWNpZmllZCgtMSwgdHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXVsdGkuc2V0U3BlY2lmaWVkKDUsIHRydWUpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldFNwZWNpZmllZCgpIHsKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZXMKKyAgICAgICAgbXVsdGkuc2V0U3BlY2lmaWVkKDAsIGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBtdWx0aS5pc1NwZWNpZmllZCgwKSk7CisKKyAgICAgICAgbXVsdGkuc2V0U3BlY2lmaWVkKDAsIHRydWUpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgbXVsdGkuaXNTcGVjaWZpZWQoMCkpOworCisgICAgICAgIG11bHRpLnNldFNwZWNpZmllZCgwLCBmYWxzZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgbXVsdGkuaXNTcGVjaWZpZWQoMCkpOworCisgICAgICAgIC8vIE91dCBvZiByYW5nZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbXVsdGkuc2V0U3BlY2lmaWVkKC0xLCB0cnVlKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtdWx0aS5zZXRTcGVjaWZpZWQoNSwgdHJ1ZSk7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvZXh0L0RlZmF1bHRIYW5kbGVyMlRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvZXh0L0RlZmF1bHRIYW5kbGVyMlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZTZjMjQ1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9leHQvRGVmYXVsdEhhbmRsZXIyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTUzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5vcmcueG1sLnNheC5leHQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguZXh0LkRlZmF1bHRIYW5kbGVyMjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK3B1YmxpYyBjbGFzcyBEZWZhdWx0SGFuZGxlcjJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBEZWZhdWx0SGFuZGxlcjIgaCA9IG5ldyBEZWZhdWx0SGFuZGxlcjIoKTsKKworICAgIHB1YmxpYyB2b2lkIHRlc3REZWZhdWx0SGFuZGxlcjIoKSB7CisgICAgICAgIG5ldyBEZWZhdWx0SGFuZGxlcjIoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RhcnRDREFUQSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguc3RhcnRDREFUQSgpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5kQ0RBVEEoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBoLmVuZENEQVRBKCk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdGFydERURCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguc3RhcnREVEQoIm5hbWUiLCAicHVibGljSWQiLCAic3lzdGVtSWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVuZERURCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguZW5kRFREKCk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdGFydEVudGl0eSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguc3RhcnRFbnRpdHkoIm5hbWUiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVuZEVudGl0eSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguZW5kRW50aXR5KCJuYW1lIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDb21tZW50KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaC5jb21tZW50KCI8IS0tIENvbW1lbnQgLS0+Ii50b0NoYXJBcnJheSgpLCAwLCAxNSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdHRyaWJ1dGVEZWNsKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaC5hdHRyaWJ1dGVEZWNsKCJlTmFtZSIsICJhTmFtZSIsICJ0eXBlIiwgIm1vZGUiLCAidmFsdWUiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVsZW1lbnREZWNsKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaC5lbGVtZW50RGVjbCgibmFtZSIsICJtb2RlbCIpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXh0ZXJuYWxFbnRpdHlEZWNsKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaC5leHRlcm5hbEVudGl0eURlY2woIm5hbWUiLCAicHVibGljSWQiLCAic3lzdGVtSWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEludGVybmFsRW50aXR5RGVjbCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguaW50ZXJuYWxFbnRpdHlEZWNsKCJuYW1lIiwgInZhbHVlIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRFeHRlcm5hbFN1YnNldCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydE51bGwoaC5nZXRFeHRlcm5hbFN1YnNldCgibmFtZSIsICJodHRwOi8vc29tZS51cmkiKSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVzb2x2ZUVudGl0eVN0cmluZ1N0cmluZygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydE51bGwoaC5yZXNvbHZlRW50aXR5KCJwdWJsaWNJZCIsICJzeXN0ZW1JZCIpKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXNvbHZlRW50aXR5U3RyaW5nU3RyaW5nU3RyaW5nU3RyaW5nKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbChoLnJlc29sdmVFbnRpdHkoIm5hbWUiLCAicHVibGljSWQiLCAiaHR0cDovL3NvbWUudXJpIiwKKyAgICAgICAgICAgICAgICAgICAgInN5c3RlbUlkIikpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L2V4dC9Mb2NhdG9yMkltcGxUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L2V4dC9Mb2NhdG9yMkltcGxUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGJlZDFkZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvZXh0L0xvY2F0b3IySW1wbFRlc3QuamF2YQpAQCAtMCwwICsxLDExMyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkub3JnLnhtbC5zYXguZXh0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKK2ltcG9ydCBvcmcueG1sLnNheC5leHQuTG9jYXRvcjJJbXBsOworaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuTG9jYXRvckltcGw7CisKK3B1YmxpYyBjbGFzcyBMb2NhdG9yMkltcGxUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1lTID0gIm15U3lzdGVtSUQiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFVCID0gIm15UHVibGljSUQiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUk9XID0gMTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTCA9IDI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTkMgPSAiS2xpbmdvbiI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUwgPSAiMS4wIjsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RMb2NhdG9ySW1wbCgpIHsKKyAgICAgICAgTG9jYXRvcjJJbXBsIGwgPSBuZXcgTG9jYXRvcjJJbXBsKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGwuZ2V0UHVibGljSWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBsLmdldFN5c3RlbUlkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbC5nZXRMaW5lTnVtYmVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbC5nZXRDb2x1bW5OdW1iZXIoKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGwuZ2V0RW5jb2RpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBsLmdldFhNTFZlcnNpb24oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdExvY2F0b3JJbXBsTG9jYXRvcigpIHsKKyAgICAgICAgTG9jYXRvcjJJbXBsIGlubmVyID0gbmV3IExvY2F0b3IySW1wbCgpOworCisgICAgICAgIGlubmVyLnNldFB1YmxpY0lkKFBVQik7CisgICAgICAgIGlubmVyLnNldFN5c3RlbUlkKFNZUyk7CisgICAgICAgIGlubmVyLnNldExpbmVOdW1iZXIoUk9XKTsKKyAgICAgICAgaW5uZXIuc2V0Q29sdW1uTnVtYmVyKENPTCk7CisKKyAgICAgICAgaW5uZXIuc2V0RW5jb2RpbmcoRU5DKTsKKyAgICAgICAgaW5uZXIuc2V0WE1MVmVyc2lvbihYTUwpOworCisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2UKKyAgICAgICAgTG9jYXRvcjJJbXBsIG91dGVyID0gbmV3IExvY2F0b3IySW1wbChpbm5lcik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFBVQiwgb3V0ZXIuZ2V0UHVibGljSWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhTWVMsIG91dGVyLmdldFN5c3RlbUlkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoUk9XLCBvdXRlci5nZXRMaW5lTnVtYmVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ09MLCBvdXRlci5nZXRDb2x1bW5OdW1iZXIoKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEVOQywgb3V0ZXIuZ2V0RW5jb2RpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYTUwsIG91dGVyLmdldFhNTFZlcnNpb24oKSk7CisKKyAgICAgICAgLy8gSW5zdGFuY2Ugb2Ygb2xkIGxvY2F0b3IKKyAgICAgICAgb3V0ZXIgPSBuZXcgTG9jYXRvcjJJbXBsKG5ldyBMb2NhdG9ySW1wbChpbm5lcikpOworCisgICAgICAgIGFzc2VydEVxdWFscyhQVUIsIG91dGVyLmdldFB1YmxpY0lkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoU1lTLCBvdXRlci5nZXRTeXN0ZW1JZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFJPVywgb3V0ZXIuZ2V0TGluZU51bWJlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKENPTCwgb3V0ZXIuZ2V0Q29sdW1uTnVtYmVyKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBvdXRlci5nZXRFbmNvZGluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG91dGVyLmdldFhNTFZlcnNpb24oKSk7CisKKyAgICAgICAgLy8gTm8gbG9jYXRvcgorICAgICAgICB0cnkgeworICAgICAgICAgICAgb3V0ZXIgPSBuZXcgTG9jYXRvcjJJbXBsKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRYTUxWZXJzaW9uR2V0WE1MVmVyc2lvbigpIHsKKyAgICAgICAgTG9jYXRvcjJJbXBsIGwgPSBuZXcgTG9jYXRvcjJJbXBsKCk7CisKKyAgICAgICAgbC5zZXRYTUxWZXJzaW9uKFhNTCk7CisgICAgICAgIGFzc2VydEVxdWFscyhYTUwsIGwuZ2V0WE1MVmVyc2lvbigpKTsKKworICAgICAgICBsLnNldFhNTFZlcnNpb24obnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBsLmdldFhNTFZlcnNpb24oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldEVuY29kaW5nR2V0RW5jb2RpbmcoKSB7CisgICAgICAgIExvY2F0b3IySW1wbCBsID0gbmV3IExvY2F0b3IySW1wbCgpOworCisgICAgICAgIGwuc2V0RW5jb2RpbmcoRU5DKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEVOQywgbC5nZXRFbmNvZGluZygpKTsKKworICAgICAgICBsLnNldEVuY29kaW5nKG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbC5nZXRFbmNvZGluZygpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvaGVscGVycy9BdHRyaWJ1dGVMaXN0SW1wbFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvaGVscGVycy9BdHRyaWJ1dGVMaXN0SW1wbFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yN2YzNmFlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9oZWxwZXJzL0F0dHJpYnV0ZUxpc3RJbXBsVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjA1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5vcmcueG1sLnNheC5oZWxwZXJzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdDsKK2ltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZUxpc3RJbXBsOworCitAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorcHVibGljIGNsYXNzIEF0dHJpYnV0ZUxpc3RJbXBsVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgQXR0cmlidXRlTGlzdEltcGwgZW1wdHkgPSBuZXcgQXR0cmlidXRlTGlzdEltcGwoKTsKKworICAgIHByaXZhdGUgQXR0cmlidXRlTGlzdEltcGwgbXVsdGkgPSBuZXcgQXR0cmlidXRlTGlzdEltcGwoKTsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgeworICAgICAgICBtdWx0aS5hZGRBdHRyaWJ1dGUoImZvbyIsICJzdHJpbmciLCAiYWJjIik7CisgICAgICAgIG11bHRpLmFkZEF0dHJpYnV0ZSgiYmFyIiwgInN0cmluZyIsICJ4eXoiKTsKKyAgICAgICAgbXVsdGkuYWRkQXR0cmlidXRlKCJhbnN3ZXIiLCAiaW50IiwgIjQyIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEF0dHJpYnV0ZUxpc3RJbXBsKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZW1wdHkuZ2V0TGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgbXVsdGkuZ2V0TGVuZ3RoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdHRyaWJ1dGVMaXN0SW1wbEF0dHJpYnV0ZUxpc3QoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2UKKyAgICAgICAgQXR0cmlidXRlTGlzdEltcGwgYWkgPSBuZXcgQXR0cmlidXRlTGlzdEltcGwoZW1wdHkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYWkuZ2V0TGVuZ3RoKCkpOworCisgICAgICAgIC8vIEFub3RoZXIgb3JkaW5hcnkgY2FzZQorICAgICAgICBhaSA9IG5ldyBBdHRyaWJ1dGVMaXN0SW1wbChtdWx0aSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBhaS5nZXRMZW5ndGgoKSk7CisKKyAgICAgICAgLy8gTm8gQXR0cmlidXRlcworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWkgPSBuZXcgQXR0cmlidXRlTGlzdEltcGwobnVsbCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYWkuZ2V0TGVuZ3RoKCkpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRBdHRyaWJ1dGVMaXN0KCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlcworICAgICAgICBBdHRyaWJ1dGVMaXN0SW1wbCBhdHRycyA9IG5ldyBBdHRyaWJ1dGVMaXN0SW1wbCgpOworICAgICAgICBhdHRycy5hZGRBdHRyaWJ1dGUoImRvZSIsICJib29sZWFuIiwgImZhbHNlIik7CisKKyAgICAgICAgYXR0cnMuc2V0QXR0cmlidXRlTGlzdChlbXB0eSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBhdHRycy5nZXRMZW5ndGgoKSk7CisKKyAgICAgICAgYXR0cnMuc2V0QXR0cmlidXRlTGlzdChtdWx0aSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRMZW5ndGgoKSwgYXR0cnMuZ2V0TGVuZ3RoKCkpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXVsdGkuZ2V0TGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG11bHRpLmdldE5hbWUoaSksIGF0dHJzLmdldE5hbWUoaSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG11bHRpLmdldFR5cGUoaSksIGF0dHJzLmdldFR5cGUoaSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG11bHRpLmdldFZhbHVlKGkpLCBhdHRycy5nZXRWYWx1ZShpKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBudWxsIGNhc2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGF0dHJzLnNldEF0dHJpYnV0ZUxpc3QobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZCwgbXVzdCBzdGlsbCBoYXZlIG9sZCBlbGVtZW50cworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGF0dHJzLmdldExlbmd0aCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRBdHRyaWJ1dGUoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2UKKyAgICAgICAgbXVsdGkuYWRkQXR0cmlidXRlKCJkb2UiLCAiYm9vbGVhbiIsICJmYWxzZSIpOworCisgICAgICAgIGFzc2VydEVxdWFscygiZG9lIiwgbXVsdGkuZ2V0TmFtZSgzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYm9vbGVhbiIsIG11bHRpLmdldFR5cGUoMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZhbHNlIiwgbXVsdGkuZ2V0VmFsdWUoMykpOworCisgICAgICAgIC8vIER1cGxpY2F0ZSBjYXNlCisgICAgICAgIG11bHRpLmFkZEF0dHJpYnV0ZSgiZG9lIiwgImJvb2xlYW4iLCAiZmFsc2UiKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoImRvZSIsIG11bHRpLmdldE5hbWUoNCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJvb2xlYW4iLCBtdWx0aS5nZXRUeXBlKDQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmYWxzZSIsIG11bHRpLmdldFZhbHVlKDQpKTsKKworICAgICAgICAvLyBudWxsIGNhc2UKKyAgICAgICAgbXVsdGkuYWRkQXR0cmlidXRlKG51bGwsIG51bGwsIG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbXVsdGkuZ2V0TmFtZSg1KSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRUeXBlKDUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFZhbHVlKDUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlQXR0cmlidXRlKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIG11bHRpLnJlbW92ZUF0dHJpYnV0ZSgiZm9vIik7CisgICAgICAgIGFzc2VydEVxdWFscygiYmFyIiwgbXVsdGkuZ2V0TmFtZSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygic3RyaW5nIiwgbXVsdGkuZ2V0VHlwZSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieHl6IiwgbXVsdGkuZ2V0VmFsdWUoMCkpOworCisgICAgICAgIC8vIFVua25vd24gYXR0cmlidXRlCisgICAgICAgIG11bHRpLnJlbW92ZUF0dHJpYnV0ZSgiam9obiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgbXVsdGkuZ2V0TGVuZ3RoKCkpOworCisgICAgICAgIC8vIG51bGwgY2FzZQorICAgICAgICBtdWx0aS5yZW1vdmVBdHRyaWJ1dGUobnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBtdWx0aS5nZXRMZW5ndGgoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENsZWFyKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoMywgbXVsdGkuZ2V0TGVuZ3RoKCkpOworICAgICAgICBtdWx0aS5jbGVhcigpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbXVsdGkuZ2V0TGVuZ3RoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRMZW5ndGgoKSB7CisgICAgICAgIEF0dHJpYnV0ZUxpc3RJbXBsIGFpID0gbmV3IEF0dHJpYnV0ZUxpc3RJbXBsKGVtcHR5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGFpLmdldExlbmd0aCgpKTsKKworICAgICAgICBhaSA9IG5ldyBBdHRyaWJ1dGVMaXN0SW1wbChtdWx0aSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBhaS5nZXRMZW5ndGgoKSk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDI7IGkgPj0gMDsgaS0tKSB7CisgICAgICAgICAgICBhaS5yZW1vdmVBdHRyaWJ1dGUoYWkuZ2V0TmFtZShpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaSwgYWkuZ2V0TGVuZ3RoKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldE5hbWUoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2VzCisgICAgICAgIGFzc2VydEVxdWFscygiZm9vIiwgbXVsdGkuZ2V0TmFtZSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYmFyIiwgbXVsdGkuZ2V0TmFtZSgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYW5zd2VyIiwgbXVsdGkuZ2V0TmFtZSgyKSk7CisKKyAgICAgICAgLy8gT3V0IG9mIHJhbmdlCisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXROYW1lKC0xKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXROYW1lKDMpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VHlwZUludCgpIHsKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZXMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdHJpbmciLCBtdWx0aS5nZXRUeXBlKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdHJpbmciLCBtdWx0aS5nZXRUeXBlKDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbnQiLCBtdWx0aS5nZXRUeXBlKDIpKTsKKworICAgICAgICAvLyBPdXQgb2YgcmFuZ2UKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFR5cGUoLTEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFR5cGUoMykpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRWYWx1ZUludCgpIHsKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZXMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhYmMiLCBtdWx0aS5nZXRWYWx1ZSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieHl6IiwgbXVsdGkuZ2V0VmFsdWUoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjQyIiwgbXVsdGkuZ2V0VmFsdWUoMikpOworCisgICAgICAgIC8vIE91dCBvZiByYW5nZQorICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbXVsdGkuZ2V0VmFsdWUoLTEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFZhbHVlKDUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VHlwZVN0cmluZygpIHsKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZXMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdHJpbmciLCBtdWx0aS5nZXRUeXBlKCJmb28iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygic3RyaW5nIiwgbXVsdGkuZ2V0VHlwZSgiYmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImludCIsIG11bHRpLmdldFR5cGUoImFuc3dlciIpKTsKKworICAgICAgICAvLyBOb3QgZm91bmQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFR5cGUoImpvaG4iKSk7CisKKyAgICAgICAgLy8gbnVsbCBjYXNlCisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRUeXBlKG51bGwpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VmFsdWVTdHJpbmcoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2VzCisgICAgICAgIGFzc2VydEVxdWFscygiYWJjIiwgbXVsdGkuZ2V0VmFsdWUoImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4eXoiLCBtdWx0aS5nZXRWYWx1ZSgiYmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjQyIiwgbXVsdGkuZ2V0VmFsdWUoImFuc3dlciIpKTsKKworICAgICAgICAvLyBOb3QgZm91bmQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFZhbHVlKCJqb2huIikpOworCisgICAgICAgIC8vIG51bGwgY2FzZQorICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbXVsdGkuZ2V0VmFsdWUobnVsbCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9oZWxwZXJzL0F0dHJpYnV0ZXNJbXBsVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9oZWxwZXJzL0F0dHJpYnV0ZXNJbXBsVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjYzc3ZWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L2hlbHBlcnMvQXR0cmlidXRlc0ltcGxUZXN0LmphdmEKQEAgLTAsMCArMSw0ODEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLm9yZy54bWwuc2F4LmhlbHBlcnM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOworaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlc0ltcGw7CisKK3B1YmxpYyBjbGFzcyBBdHRyaWJ1dGVzSW1wbFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIEF0dHJpYnV0ZXNJbXBsIGVtcHR5ID0gbmV3IEF0dHJpYnV0ZXNJbXBsKCk7CisKKyAgICBwcml2YXRlIEF0dHJpYnV0ZXNJbXBsIG11bHRpID0gbmV3IEF0dHJpYnV0ZXNJbXBsKCk7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgbXVsdGkuYWRkQXR0cmlidXRlKCJodHRwOi8vc29tZS51cmkiLCAiZm9vIiwgIm5zMTpmb28iLAorICAgICAgICAgICAgICAgICJzdHJpbmciLCAiYWJjIik7CisgICAgICAgIG11bHRpLmFkZEF0dHJpYnV0ZSgiaHR0cDovL3NvbWUudXJpIiwgImJhciIsICJuczE6YmFyIiwKKyAgICAgICAgICAgICAgICAic3RyaW5nIiwgInh5eiIpOworICAgICAgICBtdWx0aS5hZGRBdHRyaWJ1dGUoImh0dHA6Ly9zb21lLm90aGVyLnVyaSIsICJhbnN3ZXIiLCAibnMyOmFuc3dlciIsCisgICAgICAgICAgICAgICAgImludCIsICI0MiIpOworCisgICAgICAgIG11bHRpLmFkZEF0dHJpYnV0ZSgiIiwgImdhYmJhSGV5IiwgIiIsICJzdHJpbmciLCAiMS0yLTMtNCIpOworICAgICAgICBtdWx0aS5hZGRBdHRyaWJ1dGUoIiIsICIiLCAiZ2FiYmE6aGV5IiwgInN0cmluZyIsICIxLTItMy00Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEF0dHJpYnV0ZXNJbXBsKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgZW1wdHkuZ2V0TGVuZ3RoKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgbXVsdGkuZ2V0TGVuZ3RoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBdHRyaWJ1dGVzSW1wbEF0dHJpYnV0ZXMoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2UKKyAgICAgICAgQXR0cmlidXRlc0ltcGwgYWkgPSBuZXcgQXR0cmlidXRlc0ltcGwoZW1wdHkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYWkuZ2V0TGVuZ3RoKCkpOworCisgICAgICAgIC8vIEFub3RoZXIgb3JkaW5hcnkgY2FzZQorICAgICAgICBhaSA9IG5ldyBBdHRyaWJ1dGVzSW1wbChtdWx0aSk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBhaS5nZXRMZW5ndGgoKSk7CisKKyAgICAgICAgLy8gTm8gQXR0cmlidXRlcworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWkgPSBuZXcgQXR0cmlidXRlc0ltcGwobnVsbCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYWkuZ2V0TGVuZ3RoKCkpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRMZW5ndGgoKSB7CisgICAgICAgIEF0dHJpYnV0ZXNJbXBsIGFpID0gbmV3IEF0dHJpYnV0ZXNJbXBsKGVtcHR5KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGFpLmdldExlbmd0aCgpKTsKKworICAgICAgICBhaSA9IG5ldyBBdHRyaWJ1dGVzSW1wbChtdWx0aSk7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBhaS5nZXRMZW5ndGgoKSk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDQ7IGkgPj0gMDsgaS0tKSB7CisgICAgICAgICAgICBhaS5yZW1vdmVBdHRyaWJ1dGUoaSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaSwgYWkuZ2V0TGVuZ3RoKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFVSSSgpIHsKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZXMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vc29tZS51cmkiLCBtdWx0aS5nZXRVUkkoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly9zb21lLnVyaSIsIG11bHRpLmdldFVSSSgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL3NvbWUub3RoZXIudXJpIiwgbXVsdGkuZ2V0VVJJKDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBtdWx0aS5nZXRVUkkoMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIG11bHRpLmdldFVSSSg0KSk7CisKKyAgICAgICAgLy8gT3V0IG9mIHJhbmdlCisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRVUkkoLTEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFVSSSg1KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldExvY2FsTmFtZSgpIHsKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZXMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28iLCBtdWx0aS5nZXRMb2NhbE5hbWUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJhciIsIG11bHRpLmdldExvY2FsTmFtZSgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYW5zd2VyIiwgbXVsdGkuZ2V0TG9jYWxOYW1lKDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnYWJiYUhleSIsIG11bHRpLmdldExvY2FsTmFtZSgzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgbXVsdGkuZ2V0TG9jYWxOYW1lKDQpKTsKKworICAgICAgICAvLyBPdXQgb2YgcmFuZ2UKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldExvY2FsTmFtZSgtMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbXVsdGkuZ2V0TG9jYWxOYW1lKDUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UU5hbWUoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2VzCisgICAgICAgIGFzc2VydEVxdWFscygibnMxOmZvbyIsIG11bHRpLmdldFFOYW1lKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuczE6YmFyIiwgbXVsdGkuZ2V0UU5hbWUoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5zMjphbnN3ZXIiLCBtdWx0aS5nZXRRTmFtZSgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgbXVsdGkuZ2V0UU5hbWUoMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdhYmJhOmhleSIsIG11bHRpLmdldFFOYW1lKDQpKTsKKworICAgICAgICAvLyBPdXQgb2YgcmFuZ2UKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFFOYW1lKC0xKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRRTmFtZSg1KSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFR5cGVJbnQoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2VzCisgICAgICAgIGFzc2VydEVxdWFscygic3RyaW5nIiwgbXVsdGkuZ2V0VHlwZSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygic3RyaW5nIiwgbXVsdGkuZ2V0VHlwZSgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW50IiwgbXVsdGkuZ2V0VHlwZSgyKSk7CisgICAgICAgIGFzc2VydEVxdWFscygic3RyaW5nIiwgbXVsdGkuZ2V0VHlwZSgzKSk7CisgICAgICAgIGFzc2VydEVxdWFscygic3RyaW5nIiwgbXVsdGkuZ2V0VHlwZSg0KSk7CisKKyAgICAgICAgLy8gT3V0IG9mIHJhbmdlCisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRUeXBlKC0xKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRUeXBlKDUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VmFsdWVJbnQoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2VzCisgICAgICAgIGFzc2VydEVxdWFscygiYWJjIiwgbXVsdGkuZ2V0VmFsdWUoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInh5eiIsIG11bHRpLmdldFZhbHVlKDEpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI0MiIsIG11bHRpLmdldFZhbHVlKDIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxLTItMy00IiwgbXVsdGkuZ2V0VmFsdWUoMykpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjEtMi0zLTQiLCBtdWx0aS5nZXRWYWx1ZSg0KSk7CisKKyAgICAgICAgLy8gT3V0IG9mIHJhbmdlCisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRWYWx1ZSgtMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbXVsdGkuZ2V0VmFsdWUoNSkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbmRleFN0cmluZ1N0cmluZygpIHsKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZXMKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIG11bHRpLmdldEluZGV4KCJodHRwOi8vc29tZS51cmkiLCAiZm9vIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgbXVsdGkuZ2V0SW5kZXgoImh0dHA6Ly9zb21lLnVyaSIsICJiYXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBtdWx0aS5nZXRJbmRleCgiaHR0cDovL3NvbWUub3RoZXIudXJpIiwgImFuc3dlciIpKTsKKworICAgICAgICAvLyBOb3QgZm91bmQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBtdWx0aS5nZXRJbmRleCgiam9obiIsICJkb2UiKSk7CisKKyAgICAgICAgLy8gbnVsbCBjYXNlcworICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIG11bHRpLmdldEluZGV4KCJodHRwOi8vc29tZS51cmkiLCBudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgbXVsdGkuZ2V0SW5kZXgobnVsbCwgImZvbyIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5kZXhTdHJpbmcoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2VzCisgICAgICAgIGFzc2VydEVxdWFscygwLCBtdWx0aS5nZXRJbmRleCgibnMxOmZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG11bHRpLmdldEluZGV4KCJuczE6YmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgbXVsdGkuZ2V0SW5kZXgoIm5zMjphbnN3ZXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyg0LCBtdWx0aS5nZXRJbmRleCgiZ2FiYmE6aGV5IikpOworCisgICAgICAgIC8vIE5vdCBmb3VuZAorICAgICAgICBhc3NlcnRFcXVhbHMoLTEsIG11bHRpLmdldEluZGV4KCJqb2huOmRvZSIpKTsKKworICAgICAgICAvLyBudWxsIGNhc2UKKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBtdWx0aS5nZXRJbmRleChudWxsKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFR5cGVTdHJpbmdTdHJpbmcoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2VzCisgICAgICAgIGFzc2VydEVxdWFscygic3RyaW5nIiwgbXVsdGkuZ2V0VHlwZSgiaHR0cDovL3NvbWUudXJpIiwgImZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdHJpbmciLCBtdWx0aS5nZXRUeXBlKCJodHRwOi8vc29tZS51cmkiLCAiYmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImludCIsIG11bHRpLmdldFR5cGUoImh0dHA6Ly9zb21lLm90aGVyLnVyaSIsICJhbnN3ZXIiKSk7CisKKyAgICAgICAgLy8gTm90IGZvdW5kCisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRUeXBlKCJqb2huIiwgImRvZSIpKTsKKworICAgICAgICAvLyBudWxsIGNhc2VzCisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRUeXBlKCJodHRwOi8vc29tZS51cmkiLCBudWxsKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRUeXBlKG51bGwsICJmb28iKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFR5cGVTdHJpbmcoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2VzCisgICAgICAgIGFzc2VydEVxdWFscygic3RyaW5nIiwgbXVsdGkuZ2V0VHlwZSgibnMxOmZvbyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdHJpbmciLCBtdWx0aS5nZXRUeXBlKCJuczE6YmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImludCIsIG11bHRpLmdldFR5cGUoIm5zMjphbnN3ZXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygic3RyaW5nIiwgbXVsdGkuZ2V0VHlwZSgiZ2FiYmE6aGV5IikpOworCisgICAgICAgIC8vIE5vdCBmb3VuZAorICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbXVsdGkuZ2V0VHlwZSgiam9objpkb2UiKSk7CisKKyAgICAgICAgLy8gbnVsbCBjYXNlCisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRUeXBlKG51bGwpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VmFsdWVTdHJpbmdTdHJpbmcoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2VzCisgICAgICAgIGFzc2VydEVxdWFscygiYWJjIiwgbXVsdGkuZ2V0VmFsdWUoImh0dHA6Ly9zb21lLnVyaSIsICJmb28iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieHl6IiwgbXVsdGkuZ2V0VmFsdWUoImh0dHA6Ly9zb21lLnVyaSIsICJiYXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiNDIiLCBtdWx0aS5nZXRWYWx1ZSgiaHR0cDovL3NvbWUub3RoZXIudXJpIiwgImFuc3dlciIpKTsKKworICAgICAgICAvLyBOb3QgZm91bmQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFZhbHVlKCJqb2huIiwgImRvZSIpKTsKKworICAgICAgICAvLyBudWxsIGNhc2VzCisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRWYWx1ZSgiaHR0cDovL3NvbWUudXJpIiwgbnVsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbXVsdGkuZ2V0VmFsdWUobnVsbCwgImZvbyIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VmFsdWVTdHJpbmcoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2VzCisgICAgICAgIGFzc2VydEVxdWFscygiYWJjIiwgbXVsdGkuZ2V0VmFsdWUoIm5zMTpmb28iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygieHl6IiwgbXVsdGkuZ2V0VmFsdWUoIm5zMTpiYXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiNDIiLCBtdWx0aS5nZXRWYWx1ZSgibnMyOmFuc3dlciIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxLTItMy00IiwgbXVsdGkuZ2V0VmFsdWUoImdhYmJhOmhleSIpKTsKKworICAgICAgICAvLyBOb3QgZm91bmQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFZhbHVlKCJqb2huOmRvZSIpKTsKKworICAgICAgICAvLyBudWxsIGNhc2UKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFZhbHVlKG51bGwpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xlYXIoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyg1LCBtdWx0aS5nZXRMZW5ndGgoKSk7CisgICAgICAgIG11bHRpLmNsZWFyKCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBtdWx0aS5nZXRMZW5ndGgoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldEF0dHJpYnV0ZXMoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2VzCisgICAgICAgIEF0dHJpYnV0ZXNJbXBsIGF0dHJzID0gbmV3IEF0dHJpYnV0ZXNJbXBsKCk7CisgICAgICAgIGF0dHJzLmFkZEF0dHJpYnV0ZSgiaHR0cDovL3lldC5hbm90aGVyLnVyaSIsICJkb2UiLCAiam9objpkb2UiLAorICAgICAgICAgICAgICAgICJib29sZWFuIiwgImZhbHNlIik7CisKKyAgICAgICAgYXR0cnMuc2V0QXR0cmlidXRlcyhlbXB0eSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBhdHRycy5nZXRMZW5ndGgoKSk7CisKKyAgICAgICAgYXR0cnMuc2V0QXR0cmlidXRlcyhtdWx0aSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRMZW5ndGgoKSwgYXR0cnMuZ2V0TGVuZ3RoKCkpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXVsdGkuZ2V0TGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG11bHRpLmdldFVSSShpKSwgYXR0cnMuZ2V0VVJJKGkpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRMb2NhbE5hbWUoaSksIGF0dHJzLmdldExvY2FsTmFtZShpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobXVsdGkuZ2V0UU5hbWUoaSksIGF0dHJzLmdldFFOYW1lKGkpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRUeXBlKGkpLCBhdHRycy5nZXRUeXBlKGkpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhtdWx0aS5nZXRWYWx1ZShpKSwgYXR0cnMuZ2V0VmFsdWUoaSkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gbnVsbCBjYXNlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhdHRycy5zZXRBdHRyaWJ1dGVzKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQsIGJ1dCBtdXN0IGJlIGVtcHR5IG5vdworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGF0dHJzLmdldExlbmd0aCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRBdHRyaWJ1dGUoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2UKKyAgICAgICAgbXVsdGkuYWRkQXR0cmlidXRlKCJodHRwOi8veWV0LmFub3RoZXIudXJpIiwgImRvZSIsICJqb2huOmRvZSIsCisgICAgICAgICAgICAgICAgImJvb2xlYW4iLCAiZmFsc2UiKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoImh0dHA6Ly95ZXQuYW5vdGhlci51cmkiLCBtdWx0aS5nZXRVUkkoNSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvZSIsIG11bHRpLmdldExvY2FsTmFtZSg1KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiam9objpkb2UiLCBtdWx0aS5nZXRRTmFtZSg1KSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYm9vbGVhbiIsIG11bHRpLmdldFR5cGUoNSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZhbHNlIiwgbXVsdGkuZ2V0VmFsdWUoNSkpOworCisgICAgICAgIC8vIER1cGxpY2F0ZSBjYXNlCisgICAgICAgIG11bHRpLmFkZEF0dHJpYnV0ZSgiaHR0cDovL3lldC5hbm90aGVyLnVyaSIsICJkb2UiLCAiam9objpkb2UiLAorICAgICAgICAgICAgICAgICJib29sZWFuIiwgImZhbHNlIik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8veWV0LmFub3RoZXIudXJpIiwgbXVsdGkuZ2V0VVJJKDYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2UiLCBtdWx0aS5nZXRMb2NhbE5hbWUoNikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImpvaG46ZG9lIiwgbXVsdGkuZ2V0UU5hbWUoNikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJvb2xlYW4iLCBtdWx0aS5nZXRUeXBlKDYpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmYWxzZSIsIG11bHRpLmdldFZhbHVlKDYpKTsKKworICAgICAgICAvLyBudWxsIGNhc2UKKyAgICAgICAgbXVsdGkuYWRkQXR0cmlidXRlKG51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbXVsdGkuZ2V0VVJJKDcpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldExvY2FsTmFtZSg3KSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRRTmFtZSg3KSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRUeXBlKDcpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFZhbHVlKDcpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0QXR0cmlidXRlKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIG11bHRpLnNldEF0dHJpYnV0ZSgwLCAiaHR0cDovL3lldC5hbm90aGVyLnVyaSIsICJkb2UiLCAiam9objpkb2UiLAorICAgICAgICAgICAgICAgICJib29sZWFuIiwgImZhbHNlIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL3lldC5hbm90aGVyLnVyaSIsIG11bHRpLmdldFVSSSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZG9lIiwgbXVsdGkuZ2V0TG9jYWxOYW1lKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJqb2huOmRvZSIsIG11bHRpLmdldFFOYW1lKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJib29sZWFuIiwgbXVsdGkuZ2V0VHlwZSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZmFsc2UiLCBtdWx0aS5nZXRWYWx1ZSgwKSk7CisKKyAgICAgICAgLy8gbnVsbCBjYXNlCisgICAgICAgIG11bHRpLnNldEF0dHJpYnV0ZSgxLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFVSSSgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRMb2NhbE5hbWUoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbXVsdGkuZ2V0UU5hbWUoMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbXVsdGkuZ2V0VHlwZSgxKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRWYWx1ZSgxKSk7CisKKyAgICAgICAgLy8gT3V0IG9mIHJhbmdlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtdWx0aS5zZXRBdHRyaWJ1dGUoLTEsICJodHRwOi8veWV0LmFub3RoZXIudXJpIiwgImRvZSIsICJqb2huOmRvZSIsCisgICAgICAgICAgICAgICAgICAgICJib29sZWFuIiwgImZhbHNlIik7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXVsdGkuc2V0QXR0cmlidXRlKDUsICJodHRwOi8veWV0LmFub3RoZXIudXJpIiwgImRvZSIsICJqb2huOmRvZSIsCisgICAgICAgICAgICAgICAgICAgICJib29sZWFuIiwgImZhbHNlIik7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlQXR0cmlidXRlKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIG11bHRpLnJlbW92ZUF0dHJpYnV0ZSgwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJodHRwOi8vc29tZS51cmkiLCBtdWx0aS5nZXRVUkkoMCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImJhciIsIG11bHRpLmdldExvY2FsTmFtZSgwKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibnMxOmJhciIsIG11bHRpLmdldFFOYW1lKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdHJpbmciLCBtdWx0aS5nZXRUeXBlKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ4eXoiLCBtdWx0aS5nZXRWYWx1ZSgwKSk7CisKKyAgICAgICAgLy8gT3V0IG9mIHJhbmdlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtdWx0aS5yZW1vdmVBdHRyaWJ1dGUoLTEpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG11bHRpLnJlbW92ZUF0dHJpYnV0ZSg0KTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRVUkkoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2UKKyAgICAgICAgbXVsdGkuc2V0VVJJKDAsICJodHRwOi8veWV0LmFub3RoZXIudXJpIik7CisgICAgICAgIGFzc2VydEVxdWFscygiaHR0cDovL3lldC5hbm90aGVyLnVyaSIsIG11bHRpLmdldFVSSSgwKSk7CisKKyAgICAgICAgLy8gbnVsbCBjYXNlCisgICAgICAgIG11bHRpLnNldFVSSSgxLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFVSSSgxKSk7CisKKyAgICAgICAgLy8gT3V0IG9mIHJhbmdlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtdWx0aS5zZXRVUkkoLTEsICJodHRwOi8veWV0LmFub3RoZXIudXJpIik7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXVsdGkuc2V0VVJJKDUsICJodHRwOi8veWV0LmFub3RoZXIudXJpIik7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0TG9jYWxOYW1lKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIG11bHRpLnNldExvY2FsTmFtZSgwLCAiam9obiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImpvaG4iLCBtdWx0aS5nZXRMb2NhbE5hbWUoMCkpOworCisgICAgICAgIC8vIG51bGwgY2FzZQorICAgICAgICBtdWx0aS5zZXRMb2NhbE5hbWUoMSwgbnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRMb2NhbE5hbWUoMSkpOworCisgICAgICAgIC8vIE91dCBvZiByYW5nZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbXVsdGkuc2V0TG9jYWxOYW1lKC0xLCAiam9obiIpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG11bHRpLnNldExvY2FsTmFtZSg1LCAiam9obiIpOworICAgICAgICAgICAgZmFpbCgiQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldFFOYW1lKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIG11bHRpLnNldFFOYW1lKDAsICJqb2huOmRvZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImpvaG46ZG9lIiwgbXVsdGkuZ2V0UU5hbWUoMCkpOworCisgICAgICAgIC8vIG51bGwgY2FzZQorICAgICAgICBtdWx0aS5zZXRRTmFtZSgxLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFFOYW1lKDEpKTsKKworICAgICAgICAvLyBPdXQgb2YgcmFuZ2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG11bHRpLnNldFFOYW1lKC0xLCAiam9objpkb2UiKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtdWx0aS5zZXRRTmFtZSg1LCAiam9objpkb2UiKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRUeXBlKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIG11bHRpLnNldFR5cGUoMCwgImZsb2F0Iik7CisgICAgICAgIGFzc2VydEVxdWFscygiZmxvYXQiLCBtdWx0aS5nZXRUeXBlKDApKTsKKworICAgICAgICAvLyBudWxsIGNhc2UKKyAgICAgICAgbXVsdGkuc2V0VHlwZSgxLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIG11bHRpLmdldFR5cGUoMSkpOworCisgICAgICAgIC8vIE91dCBvZiByYW5nZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbXVsdGkuc2V0VHlwZSgtMSwgImZsb2F0Iik7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXVsdGkuc2V0VHlwZSg1LCAiZmxvYXQiKTsKKyAgICAgICAgICAgIGZhaWwoIkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRWYWx1ZSgpIHsKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZQorICAgICAgICBtdWx0aS5zZXRWYWx1ZSgwLCAidG9vIG11Y2giKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0b28gbXVjaCIsIG11bHRpLmdldFZhbHVlKDApKTsKKworICAgICAgICAvLyBudWxsIGNhc2UKKyAgICAgICAgbXVsdGkuc2V0VmFsdWUoMSwgbnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBtdWx0aS5nZXRWYWx1ZSgxKSk7CisKKyAgICAgICAgLy8gT3V0IG9mIHJhbmdlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtdWx0aS5zZXRWYWx1ZSgtMSwgInRvbyBtdWNoIik7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXVsdGkuc2V0VmFsdWUoNSwgInRvbyBtdWNoIik7CisgICAgICAgICAgICBmYWlsKCJBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvaGVscGVycy9EZWZhdWx0SGFuZGxlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvaGVscGVycy9EZWZhdWx0SGFuZGxlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOTUzMGYyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9oZWxwZXJzL0RlZmF1bHRIYW5kbGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTg3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5vcmcueG1sLnNheC5oZWxwZXJzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVzSW1wbDsKK2ltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuTG9jYXRvckltcGw7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgRGVmYXVsdEhhbmRsZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoKKyAgICAgKiBOb3RlOiBtb3N0IG9mIHRoZSB0ZXN0cyBoYXZlIHRvIGNoZWNrIGZvciBhbiBlbXB0eSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUKKyAgICAgKiByZXNwZWN0aXZlIG1ldGhvZHMgYW5kLCBhcyBhIHJlc3VsdCwgYXJlIHNvbWV3aGF0IHRyaXZpYWwuCisgICAgICovCisKKyAgICBwcml2YXRlIERlZmF1bHRIYW5kbGVyIGggPSBuZXcgRGVmYXVsdEhhbmRsZXIoKTsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXNvbHZlRW50aXR5KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaC5yZXNvbHZlRW50aXR5KCJwdWJsaWNJRCIsICJzeXN0ZW1JRCIpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE5vdGF0aW9uRGVjbCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGgubm90YXRpb25EZWNsKCJuYW1lIiwgInB1YmxpY0lEIiwgInN5c3RlbUlEIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RVbnBhcnNlZEVudGl0eURlY2woKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBoLnVucGFyc2VkRW50aXR5RGVjbCgibmFtZSIsICJwdWJsaWNJRCIsICJzeXN0ZW1JRCIsCisgICAgICAgICAgICAgICAgICAgICJub3RhdGlvbk5hbWUiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldERvY3VtZW50TG9jYXRvcigpIHsKKyAgICAgICAgaC5zZXREb2N1bWVudExvY2F0b3IobmV3IExvY2F0b3JJbXBsKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdGFydERvY3VtZW50KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaC5zdGFydERvY3VtZW50KCk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbmREb2N1bWVudCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguZW5kRG9jdW1lbnQoKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0YXJ0UHJlZml4TWFwcGluZygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguc3RhcnRQcmVmaXhNYXBwaW5nKCJwcmVmaXgiLCAidXJpIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbmRQcmVmaXhNYXBwaW5nKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaC5lbmRQcmVmaXhNYXBwaW5nKCJwcmVmaXgiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0YXJ0RWxlbWVudCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguc3RhcnRFbGVtZW50KCJ1cmkiLCAibmFtZSIsICJxbmFtZSIsIG5ldyBBdHRyaWJ1dGVzSW1wbCgpKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVuZEVsZW1lbnQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBoLmVuZEVsZW1lbnQoInVyaSIsICJuYW1lIiwgInFuYW1lIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDaGFyYWN0ZXJzKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaC5jaGFyYWN0ZXJzKCJUaGUgcXVpY2sgYnJvd24gZm94Ii50b0NoYXJBcnJheSgpLCA0LCAxMSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJZ25vcmFibGVXaGl0ZXNwYWNlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaC5pZ25vcmFibGVXaGl0ZXNwYWNlKCIgICAgICAgICAgICAgICAgICAgIi50b0NoYXJBcnJheSgpLCA0LCAxMSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBoLnByb2Nlc3NpbmdJbnN0cnVjdGlvbigidGFyZ2V0IiwgImRhdGEiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNraXBwZWRFbnRpdHkoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBoLnNraXBwZWRFbnRpdHkoIm5hbWUiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFdhcm5pbmcoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBoLndhcm5pbmcobmV3IFNBWFBhcnNlRXhjZXB0aW9uKCJGb28iLCBuZXcgTG9jYXRvckltcGwoKSkpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXJyb3IoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBoLmVycm9yKG5ldyBTQVhQYXJzZUV4Y2VwdGlvbigiRm9vIiwgbmV3IExvY2F0b3JJbXBsKCkpKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEZhdGFsRXJyb3IoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguZmF0YWxFcnJvcihuZXcgU0FYUGFyc2VFeGNlcHRpb24oIkZvbyIsIG5ldyBMb2NhdG9ySW1wbCgpKSk7CisgICAgICAgICAgICBmYWlsKCJTQVhFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBObyBleGNlcHRpb24KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguZmF0YWxFcnJvcihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvaGVscGVycy9Mb2NhdG9ySW1wbFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvaGVscGVycy9Mb2NhdG9ySW1wbFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YWE5YzExCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9oZWxwZXJzL0xvY2F0b3JJbXBsVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5vcmcueG1sLnNheC5oZWxwZXJzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKK2ltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkxvY2F0b3JJbXBsOworCitwdWJsaWMgY2xhc3MgTG9jYXRvckltcGxUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1lTID0gIm15U3lzdGVtSUQiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFVCID0gIm15UHVibGljSUQiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUk9XID0gMTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTCA9IDI7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9jYXRvckltcGwoKSB7CisgICAgICAgIExvY2F0b3JJbXBsIGwgPSBuZXcgTG9jYXRvckltcGwoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgbC5nZXRQdWJsaWNJZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGwuZ2V0U3lzdGVtSWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBsLmdldExpbmVOdW1iZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBsLmdldENvbHVtbk51bWJlcigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9jYXRvckltcGxMb2NhdG9yKCkgeworICAgICAgICBMb2NhdG9ySW1wbCBpbm5lciA9IG5ldyBMb2NhdG9ySW1wbCgpOworCisgICAgICAgIGlubmVyLnNldFB1YmxpY0lkKFBVQik7CisgICAgICAgIGlubmVyLnNldFN5c3RlbUlkKFNZUyk7CisgICAgICAgIGlubmVyLnNldExpbmVOdW1iZXIoUk9XKTsKKyAgICAgICAgaW5uZXIuc2V0Q29sdW1uTnVtYmVyKENPTCk7CisKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZQorICAgICAgICBMb2NhdG9ySW1wbCBvdXRlciA9IG5ldyBMb2NhdG9ySW1wbChpbm5lcik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFBVQiwgb3V0ZXIuZ2V0UHVibGljSWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhTWVMsIG91dGVyLmdldFN5c3RlbUlkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoUk9XLCBvdXRlci5nZXRMaW5lTnVtYmVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ09MLCBvdXRlci5nZXRDb2x1bW5OdW1iZXIoKSk7CisKKyAgICAgICAgLy8gTm8gbG9jYXRvcgorICAgICAgICB0cnkgeworICAgICAgICAgICAgb3V0ZXIgPSBuZXcgTG9jYXRvckltcGwobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldFB1YmxpY0lkR2V0UHVibGljSWQoKSB7CisgICAgICAgIExvY2F0b3JJbXBsIGwgPSBuZXcgTG9jYXRvckltcGwoKTsKKworICAgICAgICBsLnNldFB1YmxpY0lkKFBVQik7CisgICAgICAgIGFzc2VydEVxdWFscyhQVUIsIGwuZ2V0UHVibGljSWQoKSk7CisKKyAgICAgICAgbC5zZXRQdWJsaWNJZChudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGwuZ2V0UHVibGljSWQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldFN5c3RlbUlkR2V0U3lzdGVtSWQoKSB7CisgICAgICAgIExvY2F0b3JJbXBsIGwgPSBuZXcgTG9jYXRvckltcGwoKTsKKworICAgICAgICBsLnNldFN5c3RlbUlkKFNZUyk7CisgICAgICAgIGFzc2VydEVxdWFscyhTWVMsIGwuZ2V0U3lzdGVtSWQoKSk7CisKKyAgICAgICAgbC5zZXRTeXN0ZW1JZChudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGwuZ2V0U3lzdGVtSWQoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldExpbmVOdW1iZXJHZXRMaW5lTnVtYmVyKCkgeworICAgICAgICBMb2NhdG9ySW1wbCBsID0gbmV3IExvY2F0b3JJbXBsKCk7CisKKyAgICAgICAgbC5zZXRMaW5lTnVtYmVyKFJPVyk7CisgICAgICAgIGFzc2VydEVxdWFscyhST1csIGwuZ2V0TGluZU51bWJlcigpKTsKKworICAgICAgICBsLnNldExpbmVOdW1iZXIoMCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBsLmdldExpbmVOdW1iZXIoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldENvbHVtbk51bWJlckdldENvbHVtbk51bWJlcigpIHsKKyAgICAgICAgTG9jYXRvckltcGwgbCA9IG5ldyBMb2NhdG9ySW1wbCgpOworCisgICAgICAgIGwuc2V0Q29sdW1uTnVtYmVyKENPTCk7CisgICAgICAgIGFzc2VydEVxdWFscyhDT0wsIGwuZ2V0Q29sdW1uTnVtYmVyKCkpOworCisgICAgICAgIGwuc2V0Q29sdW1uTnVtYmVyKDApOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgbC5nZXRDb2x1bW5OdW1iZXIoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L2hlbHBlcnMvTmFtZXNwYWNlU3VwcG9ydFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvaGVscGVycy9OYW1lc3BhY2VTdXBwb3J0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJmMWZmOGQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L2hlbHBlcnMvTmFtZXNwYWNlU3VwcG9ydFRlc3QuamF2YQpAQCAtMCwwICsxLDMxOCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkub3JnLnhtbC5zYXguaGVscGVyczsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5FbXB0eVN0YWNrRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuTmFtZXNwYWNlU3VwcG9ydDsKKworcHVibGljIGNsYXNzIE5hbWVzcGFjZVN1cHBvcnRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgZmluYWwgc3RhdGljIFN0cmluZyBkZWZhdWx0VXJpID0gImh0dHA6Ly93d3cuYW5kcm9pZC5jb20iOworICAgIGZpbmFsIHN0YXRpYyBTdHJpbmcgbWFya2V0VXJpID0gImh0dHA6Ly93d3cuYW5kcm9pZC5jb20vbWFya2V0IjsKKworICAgIE5hbWVzcGFjZVN1cHBvcnQgbnM7CisgICAgQXJyYXlMaXN0PFN0cmluZz4gZXhwZWN0ZWQ7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgZXhwZWN0ZWQgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgZXhwZWN0ZWQuYWRkKCJhayIpOworICAgICAgICBleHBlY3RlZC5hZGQoImJrIik7CisKKyAgICAgICAgbnMgPSBuZXcgTmFtZXNwYWNlU3VwcG9ydCgpOworICAgICAgICBucy5wdXNoQ29udGV4dCgpOworCisgICAgICAgIG5zLmRlY2xhcmVQcmVmaXgoImFrIiwgbWFya2V0VXJpKTsKKyAgICAgICAgbnMuZGVjbGFyZVByZWZpeCgiYmsiLCBtYXJrZXRVcmkpOworICAgICAgICBucy5kZWNsYXJlUHJlZml4KCIiLCBkZWZhdWx0VXJpKTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29uc3RydWN0b3IoKSB7CisgICAgICAgIFN0cmluZyBwcmVmaXg7CisgICAgICAgIGJvb2xlYW4geG1sUHJlZml4RXhpc3RzID0gZmFsc2U7CisKKyAgICAgICAgbnMgPSBuZXcgTmFtZXNwYWNlU3VwcG9ydCgpOworICAgICAgICBFbnVtZXJhdGlvbjxTdHJpbmc+IHByZWZpeGVzID0gbnMuZ2V0RGVjbGFyZWRQcmVmaXhlcygpOworCisgICAgICAgIHdoaWxlIChwcmVmaXhlcy5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgcHJlZml4ID0gcHJlZml4ZXMubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGlmIChwcmVmaXguZXF1YWxzKCJ4bWwiKSkgeG1sUHJlZml4RXhpc3RzID0gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMTogeG1sIHByZWZpeCBkb2VzIG5vdCBleGlzdC4iLCB4bWxQcmVmaXhFeGlzdHMpOworCisgICAgICAgIC8vIENoZWNrIHRoYXQgb25seSBvbmUgY29udGV4dCBoYXMgYmVlbiBjcmVhdGVkIGJ5IHRoZSBjb25zdHJ1Y3Rvci4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5zLnBvcENvbnRleHQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogRW1wdHlTdGFja0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRW1wdHlTdGFja0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQdXNoX1BvcENvbnRleHQoKSB7CisgICAgICAgIGludCBjb3VudDsKKworICAgICAgICBucyA9IG5ldyBOYW1lc3BhY2VTdXBwb3J0KCk7CisgICAgICAgIGNvdW50ID0gY291bnRQcmVmaXhlcygpOworCisgICAgICAgIG5zLnB1c2hDb250ZXh0KCk7CisgICAgICAgIG5zLmRlY2xhcmVQcmVmaXgoImRjIiwgImh0dHA6Ly93d3cucHVybC5vcmcvZGMjIik7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgcHJlZml4IGNvdW50OyIsCisgICAgICAgICAgICAgICAgY291bnQgKyAxLCBjb3VudFByZWZpeGVzKCkpOworCisgICAgICAgIG5zLnBvcENvbnRleHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDI6IEluY29ycmVjdCBwcmVmaXggY291bnQ7IiwKKyAgICAgICAgICAgICAgICBjb3VudCwgY291bnRQcmVmaXhlcygpKTsKKworICAgICAgICAvLyBDaGVjayB0aGF0IG9ubHkgb25lIGNvbnRleHQgaGFzIGJlZW4gY3JlYXRlZCBieSBwdXNoQ29udGV4dCgpLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgbnMucG9wQ29udGV4dCgpOworICAgICAgICAgICAgZmFpbCgiVGVzdCAzOiBFbXB0eVN0YWNrRXhjZXB0aW9uIGV4cGVjdGVkLiIpOworICAgICAgICB9IGNhdGNoIChFbXB0eVN0YWNrRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFJlc2V0KCkgeworICAgICAgICBpbnQgY291bnQ7CisKKyAgICAgICAgbnMgPSBuZXcgTmFtZXNwYWNlU3VwcG9ydCgpOworICAgICAgICBjb3VudCA9IGNvdW50UHJlZml4ZXMoKTsKKworICAgICAgICBucy5wdXNoQ29udGV4dCgpOworICAgICAgICBucy5kZWNsYXJlUHJlZml4KCJkYyIsICJodHRwOi8vd3d3LnB1cmwub3JnL2RjIyIpOworCisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxOiBJbmNvcnJlY3QgcHJlZml4IGNvdW50OyIsCisgICAgICAgICAgICAgICAgY291bnQgKyAxLCBjb3VudFByZWZpeGVzKCkpOworCisgICAgICAgIG5zLnJlc2V0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBJbmNvcnJlY3QgcHJlZml4IGNvdW50OyIsCisgICAgICAgICAgICAgICAgY291bnQsIGNvdW50UHJlZml4ZXMoKSk7CisKKyAgICAgICAgLy8gQ2hlY2sgdGhhdCBvbmx5IG9uZSBjb250ZXh0IGhhcyBiZWVuIGNyZWF0ZWQgYnkgcmVzZXQoKS4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5zLnBvcENvbnRleHQoKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMzogRW1wdHlTdGFja0V4Y2VwdGlvbiBleHBlY3RlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRW1wdHlTdGFja0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZC4KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3REZWNsYXJlX0dldFByZWZpeCgpIHsKKyAgICAgICAgbnMucHVzaENvbnRleHQoKTsKKworICAgICAgICAvLyBQYXJ0IDE6IENoZWNrIHRoYXQgeG1sIGFuZCB4bWxucyBhcmUgbm90IGFjY2VwdGVkIGFzIHByZWZpeGVzLgorICAgICAgICBhc3NlcnRGYWxzZSgiVGVzdCAxOiBJbnZhbGlkIHByZWZpeCBhY2NlcHRlZC4iLAorICAgICAgICAgICAgICAgIG5zLmRlY2xhcmVQcmVmaXgoInhtbCIsIG1hcmtldFVyaSkpOworCisgICAgICAgIGFzc2VydEZhbHNlKCJUZXN0IDI6IEludmFsaWQgcHJlZml4IGFjY2VwdGVkLiIsCisgICAgICAgICAgICAgICAgbnMuZGVjbGFyZVByZWZpeCgieG1sbnMiLCBtYXJrZXRVcmkpKTsKKworICAgICAgICAvLyBQYXJ0IDI6IENoZWNrIHRoYXQgZGVjbGFyZVByZWZpeCBhbmQgZ2V0UHJlZml4IHdvcmsgZm9yIHZhbGlkCisgICAgICAgIC8vIHByZWZpeGVzLgorICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDM6IFZhbGlkIHByZWZpeCBub3QgYWNjZXB0ZWQuIiwKKyAgICAgICAgICAgICAgICBucy5kZWNsYXJlUHJlZml4KCJhayIsIG1hcmtldFVyaSkpOworCisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgNDogSW5jb3JyZWN0IHByZWZpeCByZXR1cm5lZC4iLAorICAgICAgICAgICAgICAgIG5zLmdldFByZWZpeChtYXJrZXRVcmkpLmVxdWFscygiYWsiKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCA1OiBWYWxpZCBwcmVmaXggbm90IGFjY2VwdGVkLiIsCisgICAgICAgICAgICAgICAgbnMuZGVjbGFyZVByZWZpeCgiYmsiLCBtYXJrZXRVcmkpKTsKKworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDY6IEluY29ycmVjdCBwcmVmaXggcmV0dXJuZWQuIiwKKyAgICAgICAgICAgICAgICBleHBlY3RlZC5jb250YWlucyhucy5nZXRQcmVmaXgobWFya2V0VXJpKSkpOworCisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgNzogVmFsaWQgcHJlZml4IG5vdCBhY2NlcHRlZC4iLAorICAgICAgICAgICAgICAgIG5zLmRlY2xhcmVQcmVmaXgoIiIsIGRlZmF1bHRVcmkpKTsKKworICAgICAgICAvLyBQYXJ0IDM6IE5lZ2F0aXZlIFRlc3RzIGZvciBnZXRQcmVmaXguCisgICAgICAgIGFzc2VydE51bGwoIlRlc3QgODogTm9uLW51bGwgdmFsdWUgcmV0dXJuZWQgZm9yIHRoZSBVUkkgdGhhdCBpcyAiICsKKyAgICAgICAgICAgICAgICAiYXNzaWduZWQgdG8gdGhlIGRlZmF1bHQgbmFtZXNwYWNlLiIsCisgICAgICAgICAgICAgICAgbnMuZ2V0UHJlZml4KGRlZmF1bHRVcmkpKTsKKworICAgICAgICBhc3NlcnROdWxsKCJUZXN0IDk6IE5vbi1udWxsIHZhbHVlIHJldHVybmVkIGZvciBhbiB1bmFzc2lnbmVkIFVSSS4iLAorICAgICAgICAgICAgICAgIG5zLmdldFByZWZpeChkZWZhdWx0VXJpICsgIi80MiIpKTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UHJlZml4ZXNMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgQXJyYXlMaXN0PFN0cmluZz4gcHJlZml4ZXM7CisKKyAgICAgICAgcHJlZml4ZXMgPSBDb2xsZWN0aW9ucy5saXN0KG5zLmdldFByZWZpeGVzKG1hcmtldFVyaSkpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IEluY29ycmVjdCBzZXQgb2YgcHJlZml4ZXMgcmV0dXJuZWQuIiwKKyAgICAgICAgICAgICAgICBleHBlY3RlZC5jb250YWluc0FsbChwcmVmaXhlcykgJiYgcHJlZml4ZXMuY29udGFpbnNBbGwoZXhwZWN0ZWQpKTsKKworICAgICAgICBwcmVmaXhlcyA9IENvbGxlY3Rpb25zLmxpc3QobnMuZ2V0UHJlZml4ZXMoZGVmYXVsdFVyaSkpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDI6IERlZmF1bHQgbmFtZXNwYWNlIHByZWZpeCBzaG91bGQgbm90IGJlIHJldHVybmVkLiIsCisgICAgICAgICAgICAgICAgcHJlZml4ZXMuc2l6ZSgpID09IDApOworCisgICAgICAgIHByZWZpeGVzID0gQ29sbGVjdGlvbnMubGlzdChucy5nZXRQcmVmaXhlcyhOYW1lc3BhY2VTdXBwb3J0LlhNTE5TKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgMzogeG1sIHByZWZpeCBpcyBtaXNzaW5nLiIsCisgICAgICAgICAgICAgICAgcHJlZml4ZXMuY29udGFpbnMoInhtbCIpICYmIHByZWZpeGVzLnNpemUoKSA9PSAxKTsKKworICAgICAgICBwcmVmaXhlcyA9IENvbGxlY3Rpb25zLmxpc3QobnMuZ2V0UHJlZml4ZXMoZGVmYXVsdFVyaSArICIvNDIiKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRlc3QgNDogTm9uLWVtcHR5IGVudW1lcmF0aW9uIHJldHVybmVkIGZvciBhbiB1bmFzc2lnbmVkIFVSSS4iLAorICAgICAgICAgICAgICAgIHByZWZpeGVzLnNpemUoKSA9PSAwKTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UHJlZml4ZXMoKSB7CisgICAgICAgIEFycmF5TGlzdDxTdHJpbmc+IHByZWZpeGVzOworCisgICAgICAgIGV4cGVjdGVkLmFkZCgieG1sIik7CisKKyAgICAgICAgcHJlZml4ZXMgPSBDb2xsZWN0aW9ucy5saXN0KG5zLmdldFByZWZpeGVzKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDE6IEluY29ycmVjdCBzZXQgb2YgcHJlZml4ZXMgcmV0dXJuZWQuIiwKKyAgICAgICAgICAgICAgICBleHBlY3RlZC5jb250YWluc0FsbChwcmVmaXhlcykgJiYgcHJlZml4ZXMuY29udGFpbnNBbGwoZXhwZWN0ZWQpKTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RGVjbGFyZWRQcmVmaXhlcygpIHsKKyAgICAgICAgQXJyYXlMaXN0PFN0cmluZz4gcHJlZml4ZXM7CisKKyAgICAgICAgZXhwZWN0ZWQuYWRkKCIiKTsKKworICAgICAgICBwcmVmaXhlcyA9IENvbGxlY3Rpb25zLmxpc3QobnMuZ2V0RGVjbGFyZWRQcmVmaXhlcygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAxOiBJbmNvcnJlY3Qgc2V0IG9mIHByZWZpeGVzIHJldHVybmVkLiIsCisgICAgICAgICAgICAgICAgZXhwZWN0ZWQuY29udGFpbnNBbGwocHJlZml4ZXMpICYmIHByZWZpeGVzLmNvbnRhaW5zQWxsKGV4cGVjdGVkKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFVyaSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE6IEluY29ycmVjdCBVUkkgcmV0dXJuZWQ7IiwKKyAgICAgICAgICAgICAgICBtYXJrZXRVcmksIG5zLmdldFVSSSgiYmsiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBJbmNvcnJlY3QgVVJJIHJldHVybmVkOyIsCisgICAgICAgICAgICAgICAgZGVmYXVsdFVyaSwgbnMuZ2V0VVJJKCIiKSk7CisgICAgICAgIGFzc2VydE51bGwoIlRlc3QgMzogTnVsbCBleHBlY3RlZCBmb3Igbm90LWV4aXN0aW5nIHByZWZpeC4iLAorICAgICAgICAgICAgICAgIG5zLmdldFVSSSgiY2siKSk7CisKKyAgICAgICAgbnMucG9wQ29udGV4dCgpOworICAgICAgICBhc3NlcnROdWxsKCJUZXN0IDQ6IE51bGwgZXhwZWN0ZWQgZm9yIG5vdC1leGlzdGluZyBwcmVmaXguIiwKKyAgICAgICAgICAgICAgICBucy5nZXRVUkkoImJrIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNTogSW5jb3JyZWN0IFVSSSByZXR1cm5lZDsiLAorICAgICAgICAgICAgICAgIE5hbWVzcGFjZVN1cHBvcnQuWE1MTlMsIG5zLmdldFVSSSgieG1sIikpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROYW1lc3BhY2VEZWNsVXJpcygpIHsKKworICAgICAgICBhc3NlcnRGYWxzZSgiVGVzdCAxOiBJbmNvcnJlY3QgZGVmYXVsdCB2YWx1ZSByZXR1cm5lZCBieSBpc05hbWVzcGFjZURlY2xVcmlzKCkuIiwKKyAgICAgICAgICAgICAgICBucy5pc05hbWVzcGFjZURlY2xVcmlzKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBucy5zZXROYW1lc3BhY2VEZWNsVXJpcyh0cnVlKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QgMjogSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4cGVjdGVkIHNpbmNlIGEgY29udGV4dCBoYXMgYWxyZWFkeSBiZWVuIHB1c2hlZCBpbiBzZXRVcCgpLiIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQuCisgICAgICAgIH0KKworICAgICAgICBucyA9IG5ldyBOYW1lc3BhY2VTdXBwb3J0KCk7CisgICAgICAgIG5zLnNldE5hbWVzcGFjZURlY2xVcmlzKHRydWUpOworICAgICAgICBhc3NlcnRUcnVlKCJUZXN0IDM6IEluY29ycmVjdCB2YWx1ZSByZXR1cm5lZCBieSBpc05hbWVzcGFjZURlY2xVcmlzKCkuIiwKKyAgICAgICAgICAgICAgICBucy5pc05hbWVzcGFjZURlY2xVcmlzKCkpOworCisgICAgICAgIG5zLnNldE5hbWVzcGFjZURlY2xVcmlzKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRlc3QgNDogSW5jb3JyZWN0IHZhbHVlIHJldHVybmVkIGJ5IGlzTmFtZXNwYWNlRGVjbFVyaXMoKS4iLAorICAgICAgICAgICAgICAgIG5zLmlzTmFtZXNwYWNlRGVjbFVyaXMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFByb2Nlc3NOYW1lX0VsZW1lbnQoKSB7CisgICAgICAgIFN0cmluZ1tdIHBhcnRzID0gbmV3IFN0cmluZ1szXTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKCJUZXN0IDE6IE5vbi1udWxsIHZhbHVlIGV4cGVjdGVkLiIsCisgICAgICAgICAgICAgICAgbnMucHJvY2Vzc05hbWUoImFrOmhlbGxvIiwgcGFydHMsIGZhbHNlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBJbmNvcnJlY3QgbmFtZXNwYWNlIFVSSTsiLCBtYXJrZXRVcmksIHBhcnRzWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDM6IEluY29ycmVjdCBsb2NhbCBuYW1lOyIsICJoZWxsbyIsIHBhcnRzWzFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDQ6IEluY29ycmVjdCByYXcgbmFtZTsiLCAiYWs6aGVsbG8iLCBwYXJ0c1syXSk7CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiVGVzdCA1OiBOb24tbnVsbCB2YWx1ZSBleHBlY3RlZC4iLAorICAgICAgICAgICAgICAgIG5zLnByb2Nlc3NOYW1lKCJiazoiLCBwYXJ0cywgZmFsc2UpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDY6IEluY29ycmVjdCBuYW1lc3BhY2UgVVJJOyIsIG1hcmtldFVyaSwgcGFydHNbMF0pOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNzogSW5jb3JyZWN0IGxvY2FsIG5hbWU7IiwgIiIsIHBhcnRzWzFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDg6IEluY29ycmVjdCByYXcgbmFtZTsiLCAiYms6IiwgcGFydHNbMl0pOworCisgICAgICAgIGFzc2VydE5vdE51bGwoIlRlc3QgOTogTm9uLW51bGwgdmFsdWUgZXhwZWN0ZWQuIiwKKyAgICAgICAgICAgICAgICBucy5wcm9jZXNzTmFtZSgid29ybGQiLCBwYXJ0cywgZmFsc2UpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDEwOiBJbmNvcnJlY3QgbmFtZXNwYWNlIFVSSTsiLCBkZWZhdWx0VXJpLCBwYXJ0c1swXSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxMTogSW5jb3JyZWN0IGxvY2FsIG5hbWU7IiwgIndvcmxkIiwgcGFydHNbMV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgMTI6IEluY29ycmVjdCByYXcgbmFtZTsiLCAid29ybGQiLCBwYXJ0c1syXSk7CisKKyAgICAgICAgYXNzZXJ0TnVsbCgiVGVzdCAxMzogTnVsbCBleHBlY3RlZCBmb3IgdW5kZWNsYXJlZCBwcmVmaXguIiwKKyAgICAgICAgICAgICAgICBucy5wcm9jZXNzTmFtZSgiY2s6bG9yZW0iLCBwYXJ0cywgZmFsc2UpKTsKKworICAgICAgICBhc3NlcnROdWxsKCJUZXN0IDE0OiBOdWxsIGV4cGVjdGVkIGZvciB4bWxucyBwcmVmaXguIiwKKyAgICAgICAgICAgICAgICBucy5wcm9jZXNzTmFtZSgieG1sbnM6aXBzdW0iLCBwYXJ0cywgZmFsc2UpKTsKKworICAgICAgICBucyA9IG5ldyBOYW1lc3BhY2VTdXBwb3J0KCk7CisgICAgICAgIG5zLnB1c2hDb250ZXh0KCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIlRlc3QgMTU6IE5vbi1udWxsIHZhbHVlIGV4cGVjdGVkLiIsCisgICAgICAgICAgICAgICAgbnMucHJvY2Vzc05hbWUoIndvcmxkIiwgcGFydHMsIGZhbHNlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxNjogSW5jb3JyZWN0IG5hbWVzcGFjZSBVUkk7IiwgIiIsIHBhcnRzWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE3OiBJbmNvcnJlY3QgbG9jYWwgbmFtZTsiLCAid29ybGQiLCBwYXJ0c1sxXSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxODogSW5jb3JyZWN0IHJhdyBuYW1lOyIsICJ3b3JsZCIsIHBhcnRzWzJdKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJvY2Vzc05hbWVfQXR0cmlidXRlKCkgeworICAgICAgICBTdHJpbmdbXSBwYXJ0cyA9IG5ldyBTdHJpbmdbM107CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiVGVzdCAxOiBOb24tbnVsbCB2YWx1ZSBleHBlY3RlZC4iLAorICAgICAgICAgICAgICAgIG5zLnByb2Nlc3NOYW1lKCJhazpoZWxsbyIsIHBhcnRzLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAyOiBJbmNvcnJlY3QgbmFtZXNwYWNlIFVSSTsiLCBtYXJrZXRVcmksIHBhcnRzWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDM6IEluY29ycmVjdCBsb2NhbCBuYW1lOyIsICJoZWxsbyIsIHBhcnRzWzFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDQ6IEluY29ycmVjdCByYXcgbmFtZTsiLCAiYWs6aGVsbG8iLCBwYXJ0c1syXSk7CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiVGVzdCA1OiBOb24tbnVsbCB2YWx1ZSBleHBlY3RlZC4iLAorICAgICAgICAgICAgICAgIG5zLnByb2Nlc3NOYW1lKCJiazoiLCBwYXJ0cywgdHJ1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgNjogSW5jb3JyZWN0IG5hbWVzcGFjZSBVUkk7IiwgbWFya2V0VXJpLCBwYXJ0c1swXSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCA3OiBJbmNvcnJlY3QgbG9jYWwgbmFtZTsiLCAiIiwgcGFydHNbMV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRlc3QgODogSW5jb3JyZWN0IHJhdyBuYW1lOyIsICJiazoiLCBwYXJ0c1syXSk7CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiVGVzdCA5OiBOb24tbnVsbCB2YWx1ZSBleHBlY3RlZC4iLAorICAgICAgICAgICAgICAgIG5zLnByb2Nlc3NOYW1lKCJ3b3JsZCIsIHBhcnRzLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxMDogSW5jb3JyZWN0IG5hbWVzcGFjZSBVUkk7IiwgIiIsIHBhcnRzWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDExOiBJbmNvcnJlY3QgbG9jYWwgbmFtZTsiLCAid29ybGQiLCBwYXJ0c1sxXSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxMjogSW5jb3JyZWN0IHJhdyBuYW1lOyIsICJ3b3JsZCIsIHBhcnRzWzJdKTsKKworICAgICAgICBhc3NlcnROdWxsKCJUZXN0IDEzOiBOdWxsIGV4cGVjdGVkIGZvciB1bmRlY2xhcmVkIHByZWZpeC4iLAorICAgICAgICAgICAgICAgIG5zLnByb2Nlc3NOYW1lKCJjazpsb3JlbSIsIHBhcnRzLCB0cnVlKSk7CisKKyAgICAgICAgYXNzZXJ0TnVsbCgiVGVzdCAxNDogTnVsbCBleHBlY3RlZCBmb3IgeG1sbnMgcHJlZml4LiIsCisgICAgICAgICAgICAgICAgbnMucHJvY2Vzc05hbWUoInhtbG5zOmlwc3VtIiwgcGFydHMsIHRydWUpKTsKKworICAgICAgICBucyA9IG5ldyBOYW1lc3BhY2VTdXBwb3J0KCk7CisgICAgICAgIG5zLnNldE5hbWVzcGFjZURlY2xVcmlzKHRydWUpOworICAgICAgICBucy5wdXNoQ29udGV4dCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJUZXN0IDE1OiBOb24tbnVsbCB2YWx1ZSBleHBlY3RlZC4iLAorICAgICAgICAgICAgICAgIG5zLnByb2Nlc3NOYW1lKCJ4bWxucyIsIHBhcnRzLCB0cnVlKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxNjogSW5jb3JyZWN0IG5hbWVzcGFjZSBVUkk7IiwgTmFtZXNwYWNlU3VwcG9ydC5OU0RFQ0wsIHBhcnRzWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0IDE3OiBJbmNvcnJlY3QgbG9jYWwgbmFtZTsiLCAieG1sbnMiLCBwYXJ0c1sxXSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAxODogSW5jb3JyZWN0IHJhdyBuYW1lOyIsICJ4bWxucyIsIHBhcnRzWzJdKTsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwcml2YXRlIGludCBjb3VudFByZWZpeGVzKCkKKyAgICB7CisgICAgICAgIEFycmF5TGlzdDxTdHJpbmc+IHByZWZpeGVzID0gQ29sbGVjdGlvbnMubGlzdChucy5nZXRQcmVmaXhlcygpKTsKKyAgICAgICAgcmV0dXJuIHByZWZpeGVzLnNpemUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L2hlbHBlcnMvUGFyc2VyQWRhcHRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvaGVscGVycy9QYXJzZXJBZGFwdGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzNDQ3MzYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L2hlbHBlcnMvUGFyc2VyQWRhcHRlclRlc3QuamF2YQpAQCAtMCwwICsxLDMzNSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkub3JnLnhtbC5zYXguaGVscGVyczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0OworaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7CitpbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRFRESGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CitpbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKK2ltcG9ydCBvcmcueG1sLnNheC5QYXJzZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlTGlzdEltcGw7CitpbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5Mb2NhdG9ySW1wbDsKK2ltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLlBhcnNlckFkYXB0ZXI7CisKK2ltcG9ydCB0ZXN0cy5hcGkub3JnLnhtbC5zYXguc3VwcG9ydC5NZXRob2RMb2dnZXI7CitpbXBvcnQgdGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQuTW9ja0hhbmRsZXI7CitpbXBvcnQgdGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQuTW9ja1BhcnNlcjsKK2ltcG9ydCB0ZXN0cy5hcGkub3JnLnhtbC5zYXguc3VwcG9ydC5Nb2NrUmVzb2x2ZXI7CisKK0BTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCitwdWJsaWMgY2xhc3MgUGFyc2VyQWRhcHRlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvLyBOb3RlOiBJbiBtYW55IGNhc2VzIHdlIGNhbiBvbmx5IHRlc3QgdGhhdCBkZWxlZ2F0aW9uIHdvcmtzCisgICAgLy8gcHJvcGVybHkuIFRoZSByZXN0IGlzIG91dHNpZGUgdGhlIHNjb3BlIG9mIHRoZSBzcGVjaWZpY2F0aW9uLgorCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIEZFQVRVUkVTID0gImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy8iOworCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIE5BTUVTUEFDRVMgPSBGRUFUVVJFUyArICJuYW1lc3BhY2VzIjsKKworICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBOQU1FU1BBQ0VfUFJFRklYRVMgPSBGRUFUVVJFUworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJuYW1lc3BhY2UtcHJlZml4ZXMiOworCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTE5TX1VSSXMgPSBGRUFUVVJFUyArICJ4bWxucy11cmlzIjsKKworICAgIHByaXZhdGUgTWV0aG9kTG9nZ2VyIGxvZ2dlciA9IG5ldyBNZXRob2RMb2dnZXIoKTsKKworICAgIHByaXZhdGUgTW9ja0hhbmRsZXIgaGFuZGxlciA9IG5ldyBNb2NrSGFuZGxlcihsb2dnZXIpOworCisgICAgcHJpdmF0ZSBQYXJzZXIgcGFyc2VyID0gbmV3IE1vY2tQYXJzZXIobG9nZ2VyKTsKKworICAgIHByaXZhdGUgUGFyc2VyQWRhcHRlciBhZGFwdGVyID0gbmV3IFBhcnNlckFkYXB0ZXIocGFyc2VyKTsKKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRFcXVhbHMoT2JqZWN0W10gYSwgT2JqZWN0W10gYikgeworICAgICAgICBhc3NlcnRFcXVhbHMoYS5sZW5ndGgsIGIubGVuZ3RoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiRWxlbWVudCAjIiArIGkgKyAiIG11c3QgYmUgZXF1YWwiLCBhW2ldLCBiW2ldKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgeworICAgICAgICBhZGFwdGVyLnNldENvbnRlbnRIYW5kbGVyKGhhbmRsZXIpOworICAgICAgICBhZGFwdGVyLnNldERUREhhbmRsZXIoaGFuZGxlcik7CisgICAgICAgIGFkYXB0ZXIuc2V0RXJyb3JIYW5kbGVyKGhhbmRsZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZXJBZGFwdGVyKCkgeworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoIm9yZy54bWwuc2F4LnBhcnNlciIsCisgICAgICAgICAgICAgICAgInRlc3RzLmFwaS5vcmcueG1sLnNheC5zdXBwb3J0LkRvTm90aGluZ1BhcnNlciIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUGFyc2VyQWRhcHRlcigpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VyQWRhcHRlclBhcnNlcigpIHsKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZQorICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICAgICAgUGFyc2VyQWRhcHRlciBhZGFwdGVyID0gbmV3IFBhcnNlckFkYXB0ZXIocGFyc2VyKTsKKworICAgICAgICAvLyBOdWxsIGNhc2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFkYXB0ZXIgPSBuZXcgUGFyc2VyQWRhcHRlcihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2V0RmVhdHVyZSgpIHsKKyAgICAgICAgU3RyaW5nW10gZmVhdHVyZXMgPSBuZXcgU3RyaW5nW10geyBOQU1FU1BBQ0VTLCBOQU1FU1BBQ0VfUFJFRklYRVMsCisgICAgICAgICAgICAgICAgWE1MTlNfVVJJcyB9OworCisgICAgICAgIGZvciAoU3RyaW5nIHM6IGZlYXR1cmVzKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGFkYXB0ZXIuc2V0RmVhdHVyZShzLCB0cnVlKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgYWRhcHRlci5nZXRGZWF0dXJlKHMpKTsKKworICAgICAgICAgICAgICAgIGFkYXB0ZXIuc2V0RmVhdHVyZShzLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBhZGFwdGVyLmdldEZlYXR1cmUocykpOworICAgICAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGFwdGVyLnNldEZlYXR1cmUoImh0dHA6Ly9hcmdsZS5iYXJnbGUiLCB0cnVlKTsKKyAgICAgICAgICAgIGZhaWwoIlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9IGNhdGNoIChTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2V0UHJvcGVydHkoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGFwdGVyLnNldFByb3BlcnR5KCJodHRwOi8vYXJnbGUuYmFyZ2xlIiwgIjopIik7CisgICAgICAgICAgICBmYWlsKCJTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFkYXB0ZXIuZ2V0UHJvcGVydHkoImh0dHA6Ly9hcmdsZS5iYXJnbGUiKTsKKyAgICAgICAgICAgIGZhaWwoIlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9IGNhdGNoIChTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2V0RW50aXR5UmVzb2x2ZXIoKSB7CisgICAgICAgIEVudGl0eVJlc29sdmVyIHJlc29sdmVyID0gbmV3IE1vY2tSZXNvbHZlcigpOworCisgICAgICAgIGFkYXB0ZXIuc2V0RW50aXR5UmVzb2x2ZXIocmVzb2x2ZXIpOworICAgICAgICBhc3NlcnRFcXVhbHMocmVzb2x2ZXIsIGFkYXB0ZXIuZ2V0RW50aXR5UmVzb2x2ZXIoKSk7CisKKyAgICAgICAgYWRhcHRlci5zZXRFbnRpdHlSZXNvbHZlcihudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGFkYXB0ZXIuZ2V0RW50aXR5UmVzb2x2ZXIoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFNldERUREhhbmRsZXIoKSB7CisgICAgICAgIGFkYXB0ZXIuc2V0RFRESGFuZGxlcihudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGFkYXB0ZXIuZ2V0RFRESGFuZGxlcigpKTsKKworICAgICAgICBhZGFwdGVyLnNldERUREhhbmRsZXIoaGFuZGxlcik7CisgICAgICAgIGFzc2VydEVxdWFscyhoYW5kbGVyLCBhZGFwdGVyLmdldERUREhhbmRsZXIoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFNldENvbnRlbnRIYW5kbGVyKCkgeworICAgICAgICBhZGFwdGVyLnNldENvbnRlbnRIYW5kbGVyKG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgYWRhcHRlci5nZXRDb250ZW50SGFuZGxlcigpKTsKKworICAgICAgICBhZGFwdGVyLnNldENvbnRlbnRIYW5kbGVyKGhhbmRsZXIpOworICAgICAgICBhc3NlcnRFcXVhbHMoaGFuZGxlciwgYWRhcHRlci5nZXRDb250ZW50SGFuZGxlcigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2V0RXJyb3JIYW5kbGVyKCkgeworICAgICAgICBhZGFwdGVyLnNldEVycm9ySGFuZGxlcihudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGFkYXB0ZXIuZ2V0RXJyb3JIYW5kbGVyKCkpOworCisgICAgICAgIGFkYXB0ZXIuc2V0RXJyb3JIYW5kbGVyKGhhbmRsZXIpOworICAgICAgICBhc3NlcnRFcXVhbHMoaGFuZGxlciwgYWRhcHRlci5nZXRFcnJvckhhbmRsZXIoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlU3RyaW5nKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWRhcHRlci5wYXJzZSgiZm9vIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBUaGUgU0FYIFJJIGNyZWF0ZXMgYW4gSW5wdXRTb3VyY2UgaXRzZWxmIGFuZCB0aGVuIGRlbGVnYXRlcyB0byB0aGUKKyAgICAgICAgLy8gIm90aGVyIiBwYXJzZSBtZXRob2QuCisgICAgICAgIGFzc2VydEVxdWFscygicGFyc2UiLCBsb2dnZXIuZ2V0TWV0aG9kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoSW5wdXRTb3VyY2UuY2xhc3MsIGxvZ2dlci5nZXRBcmdzKClbMF0uZ2V0Q2xhc3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlSW5wdXRTb3VyY2UoKSB7CisgICAgICAgIElucHV0U291cmNlIHNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZSgiZm9vIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFkYXB0ZXIucGFyc2Uoc291cmNlKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygicGFyc2UiLCBsb2dnZXIuZ2V0TWV0aG9kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IE9iamVjdFtdIHsgc291cmNlIH0sIGxvZ2dlci5nZXRBcmdzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXREb2N1bWVudExvY2F0b3IoKSB7CisgICAgICAgIExvY2F0b3IgbCA9IG5ldyBMb2NhdG9ySW1wbCgpOworCisgICAgICAgIGFkYXB0ZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGwpOworCisgICAgICAgIGFzc2VydEVxdWFscyhsb2dnZXIuc2l6ZSgpLCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzZXREb2N1bWVudExvY2F0b3IiLCBsb2dnZXIuZ2V0TWV0aG9kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IE9iamVjdFtdIHsgbCB9LCBsb2dnZXIuZ2V0QXJncygpKTsKKworICAgICAgICBhZGFwdGVyLnNldERvY3VtZW50TG9jYXRvcihudWxsKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMobG9nZ2VyLnNpemUoKSwgMik7CisgICAgICAgIGFzc2VydEVxdWFscygic2V0RG9jdW1lbnRMb2NhdG9yIiwgbG9nZ2VyLmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBPYmplY3RbXSB7IG51bGwgfSwgbG9nZ2VyLmdldEFyZ3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0YXJ0RG9jdW1lbnQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGFwdGVyLnN0YXJ0RG9jdW1lbnQoKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxvZ2dlci5zaXplKCksIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoInN0YXJ0RG9jdW1lbnQiLCBsb2dnZXIuZ2V0TWV0aG9kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IE9iamVjdFtdIHt9LCBsb2dnZXIuZ2V0QXJncygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5kRG9jdW1lbnQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGFwdGVyLmVuZERvY3VtZW50KCk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscyhsb2dnZXIuc2l6ZSgpLCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbmREb2N1bWVudCIsIGxvZ2dlci5nZXRNZXRob2QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgT2JqZWN0W10ge30sIGxvZ2dlci5nZXRBcmdzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdGFydEVsZW1lbnQoKSB7CisgICAgICAgIEF0dHJpYnV0ZUxpc3RJbXBsIGF0dHMgPSBuZXcgQXR0cmlidXRlTGlzdEltcGwoKTsKKyAgICAgICAgYXR0cy5hZGRBdHRyaWJ1dGUoImpvaG46ZG9lIiwgImludCIsICI0MiIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGFwdGVyLnN0YXJ0RG9jdW1lbnQoKTsKKyAgICAgICAgICAgIGFkYXB0ZXIuc3RhcnRFbGVtZW50KCJmb286YmFyIiwgYXR0cyk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygic3RhcnRFbGVtZW50IiwgbG9nZ2VyLmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBsb2dnZXIuZ2V0QXJncygpWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBsb2dnZXIuZ2V0QXJncygpWzFdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb286YmFyIiwgbG9nZ2VyLmdldEFyZ3MoKVsyXSk7CisgICAgICAgIGFzc2VydEVxdWFscygiam9objpkb2UiLCAoKEF0dHJpYnV0ZXMpbG9nZ2VyLmdldEFyZ3MoKVszXSkuZ2V0UU5hbWUoMCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RFbmRFbGVtZW50KCkgeworICAgICAgICBBdHRyaWJ1dGVMaXN0SW1wbCBhdHRzID0gbmV3IEF0dHJpYnV0ZUxpc3RJbXBsKCk7CisgICAgICAgIGF0dHMuYWRkQXR0cmlidXRlKCJqb2huOmRvZSIsICJpbnQiLCAiNDIiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWRhcHRlci5zdGFydERvY3VtZW50KCk7CisgICAgICAgICAgICBhZGFwdGVyLnN0YXJ0RWxlbWVudCgiZm9vOmJhciIsIGF0dHMpOworICAgICAgICAgICAgYWRhcHRlci5lbmRFbGVtZW50KCJmb286YmFyIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygiZW5kRWxlbWVudCIsIGxvZ2dlci5nZXRNZXRob2QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgU3RyaW5nW10geyAiIiwgIiIsICJmb286YmFyIiB9LCBsb2dnZXIuZ2V0QXJncygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2hhcmFjdGVycygpIHsKKyAgICAgICAgY2hhcltdIGNoID0gIkFuZHJvaWQiLnRvQ2hhckFycmF5KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFkYXB0ZXIuY2hhcmFjdGVycyhjaCwgMiwgNSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscyhsb2dnZXIuc2l6ZSgpLCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjaGFyYWN0ZXJzIiwgbG9nZ2VyLmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBPYmplY3RbXSB7IGNoLCAyLCA1IH0sIGxvZ2dlci5nZXRBcmdzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJZ25vcmFibGVXaGl0ZXNwYWNlKCkgeworICAgICAgICBjaGFyW10gY2ggPSAiICAgICAiLnRvQ2hhckFycmF5KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFkYXB0ZXIuaWdub3JhYmxlV2hpdGVzcGFjZShjaCwgMCwgNSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscyhsb2dnZXIuc2l6ZSgpLCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpZ25vcmFibGVXaGl0ZXNwYWNlIiwgbG9nZ2VyLmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBPYmplY3RbXSB7IGNoLCAwLCA1IH0sIGxvZ2dlci5nZXRBcmdzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGFwdGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbigiZm9vIiwgImJhciIpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMobG9nZ2VyLnNpemUoKSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygicHJvY2Vzc2luZ0luc3RydWN0aW9uIiwgbG9nZ2VyLmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBPYmplY3RbXSB7ICJmb28iICwgImJhciIgfSwgbG9nZ2VyLmdldEFyZ3MoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L2hlbHBlcnMvUGFyc2VyRmFjdG9yeVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvaGVscGVycy9QYXJzZXJGYWN0b3J5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI1OWNlNTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L2hlbHBlcnMvUGFyc2VyRmFjdG9yeVRlc3QuamF2YQpAQCAtMCwwICsxLDE0NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkub3JnLnhtbC5zYXguaGVscGVyczsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuUGFyc2VyRmFjdG9yeTsKKworQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKK3B1YmxpYyBjbGFzcyBQYXJzZXJGYWN0b3J5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNYWtlUGFyc2VyKCkgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24sCisgICAgICAgICAgICBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLCBJbnN0YW50aWF0aW9uRXhjZXB0aW9uIHsKKworICAgICAgICBTeXN0ZW0uY2xlYXJQcm9wZXJ0eSgib3JnLnhtbC5zYXgucGFyc2VyIik7CisKKyAgICAgICAgLy8gUHJvcGVydHkgbm90IHNldCBhdCBhbGwKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFBhcnNlckZhY3RvcnkubWFrZVBhcnNlcigpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIFVua25vd24gY2xhc3MKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJvcmcueG1sLnNheC5wYXJzZXIiLCAiZm9vLmJhci5TQVhQYXJzZXIiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUGFyc2VyRmFjdG9yeS5tYWtlUGFyc2VyKCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIE5vbi1hY2Nlc3NpYmxlIGNsYXNzCisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgib3JnLnhtbC5zYXgucGFyc2VyIiwKKyAgICAgICAgICAgICAgICAidGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQuTm9BY2Nlc3NQYXJzZXIiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUGFyc2VyRmFjdG9yeS5tYWtlUGFyc2VyKCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIE5vbi1pbnN0YW50aWFibGUgY2xhc3MKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJvcmcueG1sLnNheC5wYXJzZXIiLAorICAgICAgICAgICAgICAgICJ0ZXN0cy5hcGkub3JnLnhtbC5zYXguc3VwcG9ydC5Ob0luc3RhbmNlUGFyc2VyIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFBhcnNlckZhY3RvcnkubWFrZVBhcnNlcigpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBOb24tUGFyc2VyIGNsYXNzCisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgib3JnLnhtbC5zYXgucGFyc2VyIiwKKyAgICAgICAgICAgICAgICAidGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQuTm9TdWJjbGFzc1BhcnNlciIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQYXJzZXJGYWN0b3J5Lm1ha2VQYXJzZXIoKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIENsYXNzQ2FzdEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIEdvb2Qgb25lLCBmaW5hbGx5CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgib3JnLnhtbC5zYXgucGFyc2VyIiwKKyAgICAgICAgICAgICAgICAidGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQuRG9Ob3RoaW5nUGFyc2VyIik7CisKKyAgICAgICAgUGFyc2VyRmFjdG9yeS5tYWtlUGFyc2VyKCk7CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFrZVBhcnNlclN0cmluZygpIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwgSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiB7CisgICAgICAgIC8vIE5vIGNsYXNzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQYXJzZXJGYWN0b3J5Lm1ha2VQYXJzZXIobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gVW5rbm93biBjbGFzcworICAgICAgICB0cnkgeworICAgICAgICAgICAgUGFyc2VyRmFjdG9yeS5tYWtlUGFyc2VyKCJmb28uYmFyLlNBWFBhcnNlciIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBOb24tYWNjZXNzaWJsZSBjbGFzcworICAgICAgICB0cnkgeworICAgICAgICAgICAgUGFyc2VyRmFjdG9yeS5tYWtlUGFyc2VyKAorICAgICAgICAgICAgICAgICAgICAidGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQuTm9BY2Nlc3NQYXJzZXIiKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gTm9uLWluc3RhbnRpYWJsZSBjbGFzcworICAgICAgICB0cnkgeworICAgICAgICAgICAgUGFyc2VyRmFjdG9yeS5tYWtlUGFyc2VyKAorICAgICAgICAgICAgICAgICAgICAidGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQuTm9JbnN0YW5jZVBhcnNlciIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBOb24tUGFyc2VyIGNsYXNzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQYXJzZXJGYWN0b3J5Lm1ha2VQYXJzZXIoCisgICAgICAgICAgICAgICAgICAgICJ0ZXN0cy5hcGkub3JnLnhtbC5zYXguc3VwcG9ydC5Ob1N1YmNsYXNzUGFyc2VyIik7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBDbGFzc0Nhc3RFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBHb29kIG9uZSwgZmluYWxseQorICAgICAgICBQYXJzZXJGYWN0b3J5Lm1ha2VQYXJzZXIoCisgICAgICAgICAgICAgICAgInRlc3RzLmFwaS5vcmcueG1sLnNheC5zdXBwb3J0LkRvTm90aGluZ1BhcnNlciIpOworCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L2hlbHBlcnMvWE1MRmlsdGVySW1wbFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvaGVscGVycy9YTUxGaWx0ZXJJbXBsVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQwMDg3OWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L2hlbHBlcnMvWE1MRmlsdGVySW1wbFRlc3QuamF2YQpAQCAtMCwwICsxLDQ4NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkub3JnLnhtbC5zYXguaGVscGVyczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOworaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkRUREhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOworaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZXNJbXBsOworaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuTG9jYXRvckltcGw7CitpbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5YTUxGaWx0ZXJJbXBsOworCitpbXBvcnQgdGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQuTWV0aG9kTG9nZ2VyOworaW1wb3J0IHRlc3RzLmFwaS5vcmcueG1sLnNheC5zdXBwb3J0Lk1vY2tGaWx0ZXI7CitpbXBvcnQgdGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQuTW9ja0hhbmRsZXI7CitpbXBvcnQgdGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQuTW9ja1Jlc29sdmVyOworCitwdWJsaWMgY2xhc3MgWE1MRmlsdGVySW1wbFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvLyBOb3RlOiBJbiBtYW55IGNhc2VzIHdlIGNhbiBvbmx5IHRlc3QgdGhhdCBkZWxlZ2F0aW9uIHdvcmtzCisgICAgLy8gcHJvcGVybHkuIFRoZSByZXN0IGlzIG91dHNpZGUgdGhlIHNjb3BlIG9mIHRoZSBzcGVjaWZpY2F0aW9uLgorCisgICAgcHJpdmF0ZSBNZXRob2RMb2dnZXIgbG9nZ2VyID0gbmV3IE1ldGhvZExvZ2dlcigpOworCisgICAgcHJpdmF0ZSBNb2NrSGFuZGxlciBoYW5kbGVyID0gbmV3IE1vY2tIYW5kbGVyKGxvZ2dlcik7CisKKyAgICBwcml2YXRlIFhNTEZpbHRlckltcGwgcGFyZW50ID0gbmV3IE1vY2tGaWx0ZXIobG9nZ2VyKTsKKworICAgIHByaXZhdGUgWE1MRmlsdGVySW1wbCBjaGlsZCA9IG5ldyBYTUxGaWx0ZXJJbXBsKHBhcmVudCk7CisKKyAgICBwcml2YXRlIFhNTEZpbHRlckltcGwgb3JwaGFuID0gbmV3IFhNTEZpbHRlckltcGwoKTsKKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRFcXVhbHMoT2JqZWN0W10gYSwgT2JqZWN0W10gYikgeworICAgICAgICBhc3NlcnRFcXVhbHMoYS5sZW5ndGgsIGIubGVuZ3RoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiRWxlbWVudCAjIiArIGkgKyAiIG11c3QgYmUgZXF1YWwiLCBhW2ldLCBiW2ldKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgeworICAgICAgICBwYXJlbnQuc2V0Q29udGVudEhhbmRsZXIoaGFuZGxlcik7CisgICAgICAgIHBhcmVudC5zZXREVERIYW5kbGVyKGhhbmRsZXIpOworICAgICAgICBwYXJlbnQuc2V0RXJyb3JIYW5kbGVyKGhhbmRsZXIpOworCisgICAgICAgIGNoaWxkLnNldENvbnRlbnRIYW5kbGVyKGhhbmRsZXIpOworICAgICAgICBjaGlsZC5zZXREVERIYW5kbGVyKGhhbmRsZXIpOworICAgICAgICBjaGlsZC5zZXRFcnJvckhhbmRsZXIoaGFuZGxlcik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFhNTEZpbHRlckltcGwoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBwYXJlbnQuZ2V0UGFyZW50KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RYTUxGaWx0ZXJJbXBsWE1MUmVhZGVyKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBwYXJlbnQuZ2V0UGFyZW50KCkpOworCisgICAgICAgIC8vIG51bGwgY2FzZQorICAgICAgICBYTUxGaWx0ZXJJbXBsIGZpbHRlciA9IG5ldyBYTUxGaWx0ZXJJbXBsKG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgZmlsdGVyLmdldFBhcmVudCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2V0UGFyZW50KCkgeworICAgICAgICBjaGlsZC5zZXRQYXJlbnQobnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBjaGlsZC5nZXRQYXJlbnQoKSk7CisKKyAgICAgICAgY2hpbGQuc2V0UGFyZW50KHBhcmVudCk7CisgICAgICAgIGFzc2VydEVxdWFscyhwYXJlbnQsIGNoaWxkLmdldFBhcmVudCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2V0RmVhdHVyZSgpIHsKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY2hpbGQuc2V0RmVhdHVyZSgiZm9vIiwgdHJ1ZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgY2hpbGQuZ2V0RmVhdHVyZSgiZm9vIikpOworCisgICAgICAgICAgICBjaGlsZC5zZXRGZWF0dXJlKCJmb28iLCBmYWxzZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIGNoaWxkLmdldEZlYXR1cmUoImZvbyIpKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgLy8gTm8gcGFyZW50IGNhc2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9ycGhhbi5zZXRGZWF0dXJlKCJmb28iLCBmYWxzZSk7CisgICAgICAgICAgICBmYWlsKCJTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFNldFByb3BlcnR5KCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGlsZC5zZXRQcm9wZXJ0eSgiZm9vIiwgImJhciIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJiYXIiLCBjaGlsZC5nZXRQcm9wZXJ0eSgiZm9vIikpOworCisgICAgICAgICAgICBjaGlsZC5zZXRQcm9wZXJ0eSgiZm9vIiwgbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgY2hpbGQuZ2V0UHJvcGVydHkoImZvbyIpKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgLy8gTm8gcGFyZW50IGNhc2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9ycGhhbi5zZXRQcm9wZXJ0eSgiZm9vIiwgImJhciIpOworICAgICAgICAgICAgZmFpbCgiU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRTZXRFbnRpdHlSZXNvbHZlcigpIHsKKyAgICAgICAgRW50aXR5UmVzb2x2ZXIgcmVzb2x2ZXIgPSBuZXcgTW9ja1Jlc29sdmVyKCk7CisKKyAgICAgICAgcGFyZW50LnNldEVudGl0eVJlc29sdmVyKHJlc29sdmVyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc29sdmVyLCBwYXJlbnQuZ2V0RW50aXR5UmVzb2x2ZXIoKSk7CisKKyAgICAgICAgcGFyZW50LnNldEVudGl0eVJlc29sdmVyKG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgcGFyZW50LmdldEVudGl0eVJlc29sdmVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRTZXREVERIYW5kbGVyKCkgeworICAgICAgICBwYXJlbnQuc2V0RFRESGFuZGxlcihudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHBhcmVudC5nZXREVERIYW5kbGVyKCkpOworCisgICAgICAgIHBhcmVudC5zZXREVERIYW5kbGVyKGhhbmRsZXIpOworICAgICAgICBhc3NlcnRFcXVhbHMoaGFuZGxlciwgcGFyZW50LmdldERUREhhbmRsZXIoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldFNldENvbnRlbnRIYW5kbGVyKCkgeworICAgICAgICBwYXJlbnQuc2V0Q29udGVudEhhbmRsZXIobnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBwYXJlbnQuZ2V0Q29udGVudEhhbmRsZXIoKSk7CisKKyAgICAgICAgcGFyZW50LnNldENvbnRlbnRIYW5kbGVyKGhhbmRsZXIpOworICAgICAgICBhc3NlcnRFcXVhbHMoaGFuZGxlciwgcGFyZW50LmdldENvbnRlbnRIYW5kbGVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRTZXRFcnJvckhhbmRsZXIoKSB7CisgICAgICAgIHBhcmVudC5zZXRFcnJvckhhbmRsZXIobnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBwYXJlbnQuZ2V0RXJyb3JIYW5kbGVyKCkpOworCisgICAgICAgIHBhcmVudC5zZXRFcnJvckhhbmRsZXIoaGFuZGxlcik7CisgICAgICAgIGFzc2VydEVxdWFscyhoYW5kbGVyLCBwYXJlbnQuZ2V0RXJyb3JIYW5kbGVyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZUlucHV0U291cmNlKCkgeworICAgICAgICBJbnB1dFNvdXJjZSBpcyA9IG5ldyBJbnB1dFNvdXJjZSgpOworCisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNoaWxkLnBhcnNlKGlzKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygxLCBsb2dnZXIuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwYXJzZSIsIGxvZ2dlci5nZXRNZXRob2QoKSk7CisKKyAgICAgICAgLy8gTm8gcGFyZW50IGNhc2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9ycGhhbi5wYXJzZShpcyk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlU3RyaW5nKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGlsZC5wYXJzZSgiZm9vIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgbG9nZ2VyLnNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygicGFyc2UiLCBsb2dnZXIuZ2V0TWV0aG9kKCkpOworCisgICAgICAgIC8vIE5vIHBhcmVudCBjYXNlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvcnBoYW4ucGFyc2UoImZvbyIpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RSZXNvbHZlRW50aXR5KCkgeworICAgICAgICBJbnB1dFNvdXJjZSBleHBlY3RlZCA9IG5ldyBJbnB1dFNvdXJjZSgpOworCisgICAgICAgIE1vY2tSZXNvbHZlciByZXNvbHZlciA9IG5ldyBNb2NrUmVzb2x2ZXIoKTsKKyAgICAgICAgcmVzb2x2ZXIuYWRkRW50aXR5KCJmb28iLCAiYmFyIiwgZXhwZWN0ZWQpOworCisgICAgICAgIElucHV0U291cmNlIHJlc3VsdCA9IG51bGw7CisKKyAgICAgICAgcGFyZW50LnNldEVudGl0eVJlc29sdmVyKHJlc29sdmVyKTsKKworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXN1bHQgPSBwYXJlbnQucmVzb2x2ZUVudGl0eSgiZm9vIiwgImJhciIpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCByZXN1bHQpOworCisgICAgICAgIC8vIE5vIGVudGl0eSByZXNvbHZlciBjYXNlCisgICAgICAgIHBhcmVudC5zZXRFbnRpdHlSZXNvbHZlcihudWxsKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzdWx0ID0gcGFyZW50LnJlc29sdmVFbnRpdHkoImZvbyIsICJiYXIiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCByZXN1bHQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3ROb3RhdGlvbkRlY2woKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJlbnQubm90YXRpb25EZWNsKCJmb28iLCAiYmFyIiwgImZvb2JhciIpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMobG9nZ2VyLnNpemUoKSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygibm90YXRpb25EZWNsIiwgbG9nZ2VyLmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBPYmplY3RbXSB7ICJmb28iLCAiYmFyIiwgImZvb2JhciIgfSwKKyAgICAgICAgICAgICAgICBsb2dnZXIuZ2V0QXJncygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VW5wYXJzZWRFbnRpdHlEZWNsKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFyZW50LnVucGFyc2VkRW50aXR5RGVjbCgiZm9vIiwgImJhciIsICJnYWJiYSIsICJoZXkiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxvZ2dlci5zaXplKCksIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoInVucGFyc2VkRW50aXR5RGVjbCIsIGxvZ2dlci5nZXRNZXRob2QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgT2JqZWN0W10geyAiZm9vIiwgImJhciIsICJnYWJiYSIsICJoZXkiIH0sCisgICAgICAgICAgICAgICAgbG9nZ2VyLmdldEFyZ3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldERvY3VtZW50TG9jYXRvcigpIHsKKyAgICAgICAgTG9jYXRvciBsID0gbmV3IExvY2F0b3JJbXBsKCk7CisKKyAgICAgICAgY2hpbGQuc2V0RG9jdW1lbnRMb2NhdG9yKGwpOworCisgICAgICAgIGFzc2VydEVxdWFscyhsb2dnZXIuc2l6ZSgpLCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzZXREb2N1bWVudExvY2F0b3IiLCBsb2dnZXIuZ2V0TWV0aG9kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IE9iamVjdFtdIHsgbCB9LCBsb2dnZXIuZ2V0QXJncygpKTsKKworICAgICAgICBjaGlsZC5zZXREb2N1bWVudExvY2F0b3IobnVsbCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxvZ2dlci5zaXplKCksIDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInNldERvY3VtZW50TG9jYXRvciIsIGxvZ2dlci5nZXRNZXRob2QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgT2JqZWN0W10geyBudWxsIH0sIGxvZ2dlci5nZXRBcmdzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdGFydERvY3VtZW50KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFyZW50LnN0YXJ0RG9jdW1lbnQoKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxvZ2dlci5zaXplKCksIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoInN0YXJ0RG9jdW1lbnQiLCBsb2dnZXIuZ2V0TWV0aG9kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IE9iamVjdFtdIHt9LCBsb2dnZXIuZ2V0QXJncygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5kRG9jdW1lbnQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJlbnQuZW5kRG9jdW1lbnQoKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxvZ2dlci5zaXplKCksIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVuZERvY3VtZW50IiwgbG9nZ2VyLmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBPYmplY3RbXSB7fSwgbG9nZ2VyLmdldEFyZ3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0YXJ0UHJlZml4TWFwcGluZygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmVudC5zdGFydFByZWZpeE1hcHBpbmcoImZvbyIsICJodHRwOi8vc29tZS51cmkiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxvZ2dlci5zaXplKCksIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoInN0YXJ0UHJlZml4TWFwcGluZyIsIGxvZ2dlci5nZXRNZXRob2QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgT2JqZWN0W10geyAiZm9vIiwgImh0dHA6Ly9zb21lLnVyaSIgfSwKKyAgICAgICAgICAgICAgICBsb2dnZXIuZ2V0QXJncygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5kUHJlZml4TWFwcGluZygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmVudC5lbmRQcmVmaXhNYXBwaW5nKCJmb28iKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxvZ2dlci5zaXplKCksIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVuZFByZWZpeE1hcHBpbmciLCBsb2dnZXIuZ2V0TWV0aG9kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IE9iamVjdFtdIHsgImZvbyIgfSwgbG9nZ2VyLmdldEFyZ3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0YXJ0RWxlbWVudCgpIHsKKyAgICAgICAgQXR0cmlidXRlcyBhdHRzID0gbmV3IEF0dHJpYnV0ZXNJbXBsKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmVudC5zdGFydEVsZW1lbnQoImh0dHA6Ly9zb21lLnVyaSIsICJiYXIiLCAiZm9vOmJhciIsIGF0dHMpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMobG9nZ2VyLnNpemUoKSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygic3RhcnRFbGVtZW50IiwgbG9nZ2VyLmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBPYmplY3RbXSB7ICJodHRwOi8vc29tZS51cmkiLCAiYmFyIiwgImZvbzpiYXIiLCBhdHRzIH0sCisgICAgICAgICAgICAgICAgbG9nZ2VyLmdldEFyZ3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVuZEVsZW1lbnQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJlbnQuZW5kRWxlbWVudCgiaHR0cDovL3NvbWUudXJpIiwgImJhciIsICJmb286YmFyIik7CisgICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICAgfQorCisgICAgICAgICBhc3NlcnRFcXVhbHMobG9nZ2VyLnNpemUoKSwgMSk7CisgICAgICAgICBhc3NlcnRFcXVhbHMoImVuZEVsZW1lbnQiLCBsb2dnZXIuZ2V0TWV0aG9kKCkpOworICAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBPYmplY3RbXSB7ICJodHRwOi8vc29tZS51cmkiLCAiYmFyIiwgImZvbzpiYXIiIH0sCisgICAgICAgICAgICAgICAgIGxvZ2dlci5nZXRBcmdzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDaGFyYWN0ZXJzKCkgeworICAgICAgICBjaGFyW10gY2ggPSAiQW5kcm9pZCIudG9DaGFyQXJyYXkoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFyZW50LmNoYXJhY3RlcnMoY2gsIDIsIDUpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMobG9nZ2VyLnNpemUoKSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiY2hhcmFjdGVycyIsIGxvZ2dlci5nZXRNZXRob2QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgT2JqZWN0W10geyBjaCwgMiwgNSB9LCBsb2dnZXIuZ2V0QXJncygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWdub3JhYmxlV2hpdGVzcGFjZSgpIHsKKyAgICAgICAgY2hhcltdIGNoID0gIiAgICAgIi50b0NoYXJBcnJheSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJlbnQuaWdub3JhYmxlV2hpdGVzcGFjZShjaCwgMCwgNSk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscyhsb2dnZXIuc2l6ZSgpLCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpZ25vcmFibGVXaGl0ZXNwYWNlIiwgbG9nZ2VyLmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBPYmplY3RbXSB7IGNoLCAwLCA1IH0sIGxvZ2dlci5nZXRBcmdzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJlbnQucHJvY2Vzc2luZ0luc3RydWN0aW9uKCJmb28iLCAiYmFyIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscyhsb2dnZXIuc2l6ZSgpLCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24iLCBsb2dnZXIuZ2V0TWV0aG9kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IE9iamVjdFtdIHsgImZvbyIsICJiYXIiIH0sIGxvZ2dlci5nZXRBcmdzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTa2lwcGVkRW50aXR5KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGFyZW50LnNraXBwZWRFbnRpdHkoImZvbyIpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMobG9nZ2VyLnNpemUoKSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygic2tpcHBlZEVudGl0eSIsIGxvZ2dlci5nZXRNZXRob2QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgT2JqZWN0W10geyAiZm9vIiB9LCBsb2dnZXIuZ2V0QXJncygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V2FybmluZygpIHsKKyAgICAgICAgU0FYUGFyc2VFeGNlcHRpb24gZXhjZXB0aW9uID0gbmV3IFNBWFBhcnNlRXhjZXB0aW9uKCJPb3BzISIsIG51bGwpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBwYXJlbnQud2FybmluZyhleGNlcHRpb24pOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMobG9nZ2VyLnNpemUoKSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygid2FybmluZyIsIGxvZ2dlci5nZXRNZXRob2QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgT2JqZWN0W10geyBleGNlcHRpb24gfSwgbG9nZ2VyLmdldEFyZ3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVycm9yKCkgeworICAgICAgICBTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24gPSBuZXcgU0FYUGFyc2VFeGNlcHRpb24oIk9vcHMhIiwgbnVsbCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmVudC5lcnJvcihleGNlcHRpb24pOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMobG9nZ2VyLnNpemUoKSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZXJyb3IiLCBsb2dnZXIuZ2V0TWV0aG9kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IE9iamVjdFtdIHsgZXhjZXB0aW9uIH0sIGxvZ2dlci5nZXRBcmdzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RGYXRhbEVycm9yKCkgeworICAgICAgICBTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24gPSBuZXcgU0FYUGFyc2VFeGNlcHRpb24oIk9vcHMhIiwgbnVsbCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmVudC5mYXRhbEVycm9yKGV4Y2VwdGlvbik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscyhsb2dnZXIuc2l6ZSgpLCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmYXRhbEVycm9yIiwgbG9nZ2VyLmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBPYmplY3RbXSB7IGV4Y2VwdGlvbiB9LCBsb2dnZXIuZ2V0QXJncygpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvaGVscGVycy9YTUxSZWFkZXJBZGFwdGVyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9oZWxwZXJzL1hNTFJlYWRlckFkYXB0ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTYxMDRiMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvaGVscGVycy9YTUxSZWFkZXJBZGFwdGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzE0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5vcmcueG1sLnNheC5oZWxwZXJzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdDsKK2ltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOworaW1wb3J0IG9yZy54bWwuc2F4LkRUREhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKK2ltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVzSW1wbDsKK2ltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkxvY2F0b3JJbXBsOworaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuWE1MUmVhZGVyQWRhcHRlcjsKKworaW1wb3J0IHRlc3RzLmFwaS5vcmcueG1sLnNheC5zdXBwb3J0Lk1ldGhvZExvZ2dlcjsKK2ltcG9ydCB0ZXN0cy5hcGkub3JnLnhtbC5zYXguc3VwcG9ydC5Nb2NrSGFuZGxlcjsKK2ltcG9ydCB0ZXN0cy5hcGkub3JnLnhtbC5zYXguc3VwcG9ydC5Nb2NrUmVhZGVyOworaW1wb3J0IHRlc3RzLmFwaS5vcmcueG1sLnNheC5zdXBwb3J0Lk1vY2tSZXNvbHZlcjsKKworQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKK3B1YmxpYyBjbGFzcyBYTUxSZWFkZXJBZGFwdGVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8vIE5vdGU6IEluIG1hbnkgY2FzZXMgd2UgY2FuIG9ubHkgdGVzdCB0aGF0IGRlbGVnYXRpb24gd29ya3MKKyAgICAvLyBwcm9wZXJseS4gVGhlIHJlc3QgaXMgb3V0c2lkZSB0aGUgc2NvcGUgb2YgdGhlIHNwZWNpZmljYXRpb24uCisKKyAgICBwcml2YXRlIE1ldGhvZExvZ2dlciBsb2dnZXIgPSBuZXcgTWV0aG9kTG9nZ2VyKCk7CisKKyAgICBwcml2YXRlIE1vY2tIYW5kbGVyIGhhbmRsZXIgPSBuZXcgTW9ja0hhbmRsZXIobG9nZ2VyKTsKKworICAgIHByaXZhdGUgWE1MUmVhZGVyIHJlYWRlciA9IG5ldyBNb2NrUmVhZGVyKGxvZ2dlcik7CisKKyAgICBwcml2YXRlIFhNTFJlYWRlckFkYXB0ZXIgYWRhcHRlciA9IG5ldyBYTUxSZWFkZXJBZGFwdGVyKHJlYWRlcik7CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0RXF1YWxzKE9iamVjdFtdIGEsIE9iamVjdFtdIGIpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGEubGVuZ3RoLCBiLmxlbmd0aCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkVsZW1lbnQgIyIgKyBpICsgIiBtdXN0IGJlIGVxdWFsIiwgYVtpXSwgYltpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRVcCgpIHsKKyAgICAgICAgYWRhcHRlci5zZXREb2N1bWVudEhhbmRsZXIoaGFuZGxlcik7CisgICAgICAgIGFkYXB0ZXIuc2V0RFRESGFuZGxlcihoYW5kbGVyKTsKKyAgICAgICAgYWRhcHRlci5zZXRFcnJvckhhbmRsZXIoaGFuZGxlcik7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFhNTFJlYWRlckFkYXB0ZXIoKSB7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgib3JnLnhtbC5zYXguZHJpdmVyIiwKKyAgICAgICAgICAgICAgICAidGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQuRG9Ob3RoaW5nWE1MUmVhZGVyIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBYTUxSZWFkZXJBZGFwdGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RYTUxSZWFkZXJBZGFwdGVyWE1MUmVhZGVyKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgICAgICBYTUxSZWFkZXJBZGFwdGVyIGFkYXB0ZXIgPSBuZXcgWE1MUmVhZGVyQWRhcHRlcihyZWFkZXIpOworCisgICAgICAgIC8vIE51bGwgY2FzZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgYWRhcHRlciA9IG5ldyBYTUxSZWFkZXJBZGFwdGVyKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRMb2NhbGUoKSB7CisgICAgICAgIC8vIFNBWCBSSSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMsIGhlbmNlIGFsd2F5cyBleHBlY3QgZXhjZXB0aW9uCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGFwdGVyLnNldExvY2FsZShMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKKyAgICAgICAgICAgIGZhaWwoIlNBWEV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRFbnRpdHlSZXNvbHZlcigpIHsKKyAgICAgICAgRW50aXR5UmVzb2x2ZXIgcmVzb2x2ZXIgPSBuZXcgTW9ja1Jlc29sdmVyKCk7CisKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZQorICAgICAgICBhZGFwdGVyLnNldEVudGl0eVJlc29sdmVyKHJlc29sdmVyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc29sdmVyLCByZWFkZXIuZ2V0RW50aXR5UmVzb2x2ZXIoKSk7CisKKyAgICAgICAgLy8gbnVsbCBjYXNlCisgICAgICAgIGFkYXB0ZXIuc2V0RW50aXR5UmVzb2x2ZXIobnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCByZWFkZXIuZ2V0RW50aXR5UmVzb2x2ZXIoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldERUREhhbmRsZXIoKSB7CisgICAgICAgIC8vIE9yZGluYXJ5IGNhc2UKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGhhbmRsZXIsIHJlYWRlci5nZXREVERIYW5kbGVyKCkpOworCisgICAgICAgIC8vIG51bGwgY2FzZQorICAgICAgICBhZGFwdGVyLnNldERUREhhbmRsZXIobnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCByZWFkZXIuZ2V0RFRESGFuZGxlcigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0RG9jdW1lbnRIYW5kbGVyKCkgeworICAgICAgICAvLyBUaGVyZSBpcyBubyBnZXR0ZXIgZm9yIHRoZSBEb2N1bWVudEhhbmRsZXIsIHNvIHdlIGNhbiBvbmx5IHRlc3QKKyAgICAgICAgLy8gaW5kaXJlY3RseSB3aGV0aGVyIGlzIGhhcyBiZWVuIHNldCBjb3JyZWN0bHkuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGFwdGVyLnN0YXJ0RG9jdW1lbnQoKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzdGFydERvY3VtZW50IiwgbG9nZ2VyLmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBPYmplY3RbXSB7IH0sIGxvZ2dlci5nZXRBcmdzKCkpOworCisgICAgICAgIC8vIG51bGwgY2FzZQorICAgICAgICBhZGFwdGVyLnNldERvY3VtZW50SGFuZGxlcihudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0RXJyb3JIYW5kbGVyKCkgeworICAgICAgICAvLyBPcmRpbmFyeSBjYXNlCisgICAgICAgIGFzc2VydEVxdWFscyhoYW5kbGVyLCByZWFkZXIuZ2V0RXJyb3JIYW5kbGVyKCkpOworCisgICAgICAgIC8vIG51bGwgY2FzZQorICAgICAgICBhZGFwdGVyLnNldEVycm9ySGFuZGxlcihudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIHJlYWRlci5nZXRFcnJvckhhbmRsZXIoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlU3RyaW5nKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWRhcHRlci5wYXJzZSgiZm9vIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBUaGUgU0FYIFJJIGNyZWF0ZXMgYW4gSW5wdXRTb3VyY2UgaXRzZWxmIGFuZCB0aGVuIGRlbGVnYXRlcyB0byB0aGUKKyAgICAgICAgLy8gIm90aGVyIiBwYXJzZSBtZXRob2QuCisgICAgICAgIGFzc2VydEVxdWFscygicGFyc2UiLCBsb2dnZXIuZ2V0TWV0aG9kKDApKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKElucHV0U291cmNlLmNsYXNzLCBsb2dnZXIuZ2V0QXJncygwKVswXS5nZXRDbGFzcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VJbnB1dFNvdXJjZSgpIHsKKyAgICAgICAgSW5wdXRTb3VyY2Ugc291cmNlID0gbmV3IElucHV0U291cmNlKCJmb28iKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWRhcHRlci5wYXJzZShzb3VyY2UpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwYXJzZSIsIGxvZ2dlci5nZXRNZXRob2QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgT2JqZWN0W10geyBzb3VyY2UgfSwgbG9nZ2VyLmdldEFyZ3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldERvY3VtZW50TG9jYXRvcigpIHsKKyAgICAgICAgLy8gT3JkaW5hcnkgY2FzZQorICAgICAgICBMb2NhdG9ySW1wbCBsb2NhdG9yID0gbmV3IExvY2F0b3JJbXBsKCk7CisgICAgICAgIGFkYXB0ZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGxvY2F0b3IpOworCisgICAgICAgIGFzc2VydEVxdWFscygic2V0RG9jdW1lbnRMb2NhdG9yIiwgbG9nZ2VyLmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBPYmplY3RbXSB7IGxvY2F0b3IgfSwgbG9nZ2VyLmdldEFyZ3MoKSk7CisKKyAgICAgICAgLy8gbnVsbCBjYXNlIChmb3IgdGhlIERvY3VtZW50SGFuZGxlciBpdHNlbGYhKQorICAgICAgICBhZGFwdGVyLnNldERvY3VtZW50SGFuZGxlcihudWxsKTsKKyAgICAgICAgYWRhcHRlci5zZXREb2N1bWVudExvY2F0b3IobG9jYXRvcik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFN0YXJ0RG9jdW1lbnQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGFwdGVyLnN0YXJ0RG9jdW1lbnQoKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxvZ2dlci5zaXplKCksIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoInN0YXJ0RG9jdW1lbnQiLCBsb2dnZXIuZ2V0TWV0aG9kKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IE9iamVjdFtdIHt9LCBsb2dnZXIuZ2V0QXJncygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5kRG9jdW1lbnQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGFwdGVyLmVuZERvY3VtZW50KCk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscyhsb2dnZXIuc2l6ZSgpLCAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbmREb2N1bWVudCIsIGxvZ2dlci5nZXRNZXRob2QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgT2JqZWN0W10ge30sIGxvZ2dlci5nZXRBcmdzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdGFydFByZWZpeE1hcHBpbmcoKSB7CisgICAgICAgIGFkYXB0ZXIuc3RhcnRQcmVmaXhNYXBwaW5nKCJmb28iLCAiaHR0cDovL3NvbWUudXJpIik7CisgICAgICAgIGFzc2VydEVxdWFscyhsb2dnZXIuc2l6ZSgpLCAwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5kUHJlZml4TWFwcGluZygpIHsKKyAgICAgICAgYWRhcHRlci5lbmRQcmVmaXhNYXBwaW5nKCJmb28iKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxvZ2dlci5zaXplKCksIDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTdGFydEVsZW1lbnQoKSB7CisgICAgICAgIEF0dHJpYnV0ZXNJbXBsIGF0dHMgPSBuZXcgQXR0cmlidXRlc0ltcGwoKTsKKyAgICAgICAgYXR0cy5hZGRBdHRyaWJ1dGUoImh0dHA6Ly9zb21lLm90aGVyLnVyaSIsICJnYWJiYSIsICJnYWJiYTpoZXkiLAorICAgICAgICAgICAgICAgICJpbnQiLCAiNDIiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWRhcHRlci5zdGFydEVsZW1lbnQoImh0dHA6Ly9zb21lLnVyaSIsICJiYXIiLCAiZm9vOmJhciIsIGF0dHMpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMobG9nZ2VyLnNpemUoKSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygic3RhcnRFbGVtZW50IiwgbG9nZ2VyLmdldE1ldGhvZCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb286YmFyIiwgbG9nZ2VyLmdldEFyZ3MoKVswXSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ2FiYmE6aGV5IiwKKyAgICAgICAgICAgICAgICAoKEF0dHJpYnV0ZUxpc3QpbG9nZ2VyLmdldEFyZ3MoKVsxXSkuZ2V0TmFtZSgwKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEVuZEVsZW1lbnQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGFwdGVyLmVuZEVsZW1lbnQoImh0dHA6Ly9zb21lLnVyaSIsICJiYXIiLCAiZm9vOmJhciIpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMobG9nZ2VyLnNpemUoKSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZW5kRWxlbWVudCIsIGxvZ2dlci5nZXRNZXRob2QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgT2JqZWN0W10geyAiZm9vOmJhciIgfSwgbG9nZ2VyLmdldEFyZ3MoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENoYXJhY3RlcnMoKSB7CisgICAgICAgIGNoYXJbXSBjaCA9ICJBbmRyb2lkIi50b0NoYXJBcnJheSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGFwdGVyLmNoYXJhY3RlcnMoY2gsIDIsIDUpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMobG9nZ2VyLnNpemUoKSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiY2hhcmFjdGVycyIsIGxvZ2dlci5nZXRNZXRob2QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgT2JqZWN0W10geyBjaCwgMiwgNSB9LCBsb2dnZXIuZ2V0QXJncygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWdub3JhYmxlV2hpdGVzcGFjZSgpIHsKKyAgICAgICAgY2hhcltdIGNoID0gIiAgICAgIi50b0NoYXJBcnJheSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZGFwdGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UoY2gsIDAsIDUpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMobG9nZ2VyLnNpemUoKSwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaWdub3JhYmxlV2hpdGVzcGFjZSIsIGxvZ2dlci5nZXRNZXRob2QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgT2JqZWN0W10geyBjaCwgMCwgNSB9LCBsb2dnZXIuZ2V0QXJncygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJvY2Vzc2luZ0luc3RydWN0aW9uKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWRhcHRlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oImZvbyIsICJiYXIiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxvZ2dlci5zaXplKCksIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoInByb2Nlc3NpbmdJbnN0cnVjdGlvbiIsIGxvZ2dlci5nZXRNZXRob2QoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgT2JqZWN0W10geyAiZm9vIiAsICJiYXIiIH0sIGxvZ2dlci5nZXRBcmdzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTa2lwcGVkRW50aXR5KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWRhcHRlci5za2lwcGVkRW50aXR5KCJmb28iKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGxvZ2dlci5zaXplKCksIDApOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9oZWxwZXJzL1hNTFJlYWRlckZhY3RvcnlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L2hlbHBlcnMvWE1MUmVhZGVyRmFjdG9yeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MjA1ZGZkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9oZWxwZXJzL1hNTFJlYWRlckZhY3RvcnlUZXN0LmphdmEKQEAgLTAsMCArMSwxNDYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLm9yZy54bWwuc2F4LmhlbHBlcnM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5YTUxSZWFkZXJGYWN0b3J5OworCitwdWJsaWMgY2xhc3MgWE1MUmVhZGVyRmFjdG9yeVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q3JlYXRlWE1MUmVhZGVyKCkgeworICAgICAgICAvLyBQcm9wZXJ0eSBub3Qgc2V0IGF0IGFsbAorICAgICAgICB0cnkgeworICAgICAgICAgICAgWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBVbmtub3duIGNsYXNzCisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgib3JnLnhtbC5zYXguZHJpdmVyIiwgImZvby5iYXIuWE1MUmVhZGVyIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFhNTFJlYWRlckZhY3RvcnkuY3JlYXRlWE1MUmVhZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gTm9uLWFjY2Vzc2libGUgY2xhc3MKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJvcmcueG1sLnNheC5kcml2ZXIiLAorICAgICAgICAgICAgICAgICJ0ZXN0cy5hcGkub3JnLnhtbC5zYXguc3VwcG9ydC5Ob0FjY2Vzc1hNTFJlYWRlciIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBYTUxSZWFkZXJGYWN0b3J5LmNyZWF0ZVhNTFJlYWRlcigpOworICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIE5vbi1pbnN0YW50aWFibGUgY2xhc3MKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJvcmcueG1sLnNheC5kcml2ZXIiLAorICAgICAgICAgICAgICAgICJ0ZXN0cy5hcGkub3JnLnhtbC5zYXguc3VwcG9ydC5Ob0luc3RhbmNlWE1MUmVhZGVyIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFhNTFJlYWRlckZhY3RvcnkuY3JlYXRlWE1MUmVhZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gTm9uLVhNTFJlYWRlciBjbGFzcworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoIm9yZy54bWwuc2F4LmRyaXZlciIsCisgICAgICAgICAgICAgICAgInRlc3RzLmFwaS5vcmcueG1sLnNheC5zdXBwb3J0Lk5vU3ViY2xhc3NYTUxSZWFkZXIiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEdvb2Qgb25lLCBmaW5hbGx5CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgib3JnLnhtbC5zYXguZHJpdmVyIiwKKyAgICAgICAgICAgICAgICAidGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQuRG9Ob3RoaW5nWE1MUmVhZGVyIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFhNTFJlYWRlckZhY3RvcnkuY3JlYXRlWE1MUmVhZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE1ha2VQYXJzZXJTdHJpbmcoKSB7CisgICAgICAgIC8vIE5vIGNsYXNzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBYTUxSZWFkZXJGYWN0b3J5LmNyZWF0ZVhNTFJlYWRlcihudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVW5rbm93biBjbGFzcworICAgICAgICB0cnkgeworICAgICAgICAgICAgWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoImZvby5iYXIuWE1MUmVhZGVyIik7CisgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBFeHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gTm9uLWFjY2Vzc2libGUgY2xhc3MKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFhNTFJlYWRlckZhY3RvcnkuY3JlYXRlWE1MUmVhZGVyKAorICAgICAgICAgICAgICAgICAgICAidGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQuTm9BY2Nlc3NYTUxSZWFkZXIiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBOb24taW5zdGFudGlhYmxlIGNsYXNzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBYTUxSZWFkZXJGYWN0b3J5LmNyZWF0ZVhNTFJlYWRlcigKKyAgICAgICAgICAgICAgICAgICAgInRlc3RzLmFwaS5vcmcueG1sLnNheC5zdXBwb3J0Lk5vSW5zdGFuY2VYTUxSZWFkZXIiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBOb24tUGFyc2VyIGNsYXNzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBYTUxSZWFkZXJGYWN0b3J5LmNyZWF0ZVhNTFJlYWRlcigKKyAgICAgICAgICAgICAgICAgICAgInRlc3RzLmFwaS5vcmcueG1sLnNheC5zdXBwb3J0Lk5vU3ViY2xhc3NYTUxSZWFkZXIiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBHb29kIG9uZSwgZmluYWxseQorICAgICAgICB0cnkgeworICAgICAgICAgICAgWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoCisgICAgICAgICAgICAgICAgICAgICJ0ZXN0cy5hcGkub3JnLnhtbC5zYXguc3VwcG9ydC5Eb05vdGhpbmdYTUxSZWFkZXIiKTsKKyAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgICAgICB9CisKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Ccm9rZW5JbnB1dFN0cmVhbS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9zdXBwb3J0L0Jyb2tlbklucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODEzNmI4NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Ccm9rZW5JbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKKy8qKgorICogSW1wbGVtZW50cyBhbiBJbnB1dFN0cmVhbSB3aGF0IHdyYXBzIGFub3RoZXIgSW5wdXRTdHJlYW0gYW5kIHRocm93cyBhbgorICogSU9FeGNlcHRpb24gYWZ0ZXIgaGF2aW5nIHJlYWQgYSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJ5dGVzLiBVc2VkIGZvcgorICogaW5qZWN0aW5nIElPRXhjZXB0aW9ucyBvbiBsb3dlciBsZXZlbHMuCisgKi8KK3B1YmxpYyBjbGFzcyBCcm9rZW5JbnB1dFN0cmVhbSBleHRlbmRzIElucHV0U3RyZWFtIHsKKworICAgIHByaXZhdGUgSW5wdXRTdHJlYW0gc3RyZWFtOworCisgICAgcHJpdmF0ZSBpbnQgb2Zmc2V0OworCisgICAgcHVibGljIEJyb2tlbklucHV0U3RyZWFtKElucHV0U3RyZWFtIHN0cmVhbSwgaW50IG9mZnNldCkgeworICAgICAgICBzdXBlcigpOworCisgICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtOworICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAob2Zmc2V0ID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW5qZWN0ZWQgZXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICBvZmZzZXQtLTsKKyAgICAgICAgcmV0dXJuIHN0cmVhbS5yZWFkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzdHJlYW0uY2xvc2UoKTsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9zdXBwb3J0L0RvTm90aGluZ1BhcnNlci5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9zdXBwb3J0L0RvTm90aGluZ1BhcnNlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxOGI2ZWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L3N1cHBvcnQvRG9Ob3RoaW5nUGFyc2VyLmphdmEKQEAgLTAsMCArMSw1NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkub3JnLnhtbC5zYXguc3VwcG9ydDsKKworaW1wb3J0IG9yZy54bWwuc2F4LkRUREhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKK2ltcG9ydCBvcmcueG1sLnNheC5QYXJzZXI7CisKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCisvKioKKyAqIEEgU0FYIFBhcnNlciB0aGF0IGRvZXMgbm90aGluZywgYnV0IGNhbiBiZSBpbnN0YW50aWF0ZWQgcHJvcGVybHkuCisgKi8KK0BTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCitwdWJsaWMgY2xhc3MgRG9Ob3RoaW5nUGFyc2VyIGltcGxlbWVudHMgUGFyc2VyIHsKKworICAgIHB1YmxpYyB2b2lkIHBhcnNlKElucHV0U291cmNlIHNvdXJjZSkgIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBwYXJzZShTdHJpbmcgc3lzdGVtSWQpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEhhbmRsZXIoRG9jdW1lbnRIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyKERUREhhbmRsZXIgaGFuZGxlcikgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyKEVudGl0eVJlc29sdmVyIHJlc29sdmVyKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlciBoYW5kbGVyKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpIHsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Eb05vdGhpbmdYTUxSZWFkZXIuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Eb05vdGhpbmdYTUxSZWFkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44Njg3YmZmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9zdXBwb3J0L0RvTm90aGluZ1hNTFJlYWRlci5qYXZhCkBAIC0wLDAgKzEsNzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQ7CisKK2ltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKK2ltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7CisKKy8qKgorICogQW4gWE1MUmVhZGVyIHRoYXQgZG9lcyBub3RoaW5nLCBidXQgY2FuIGJlIGluc3RhbnRpYXRlZCBwcm9wZXJseS4KKyAqLworcHVibGljIGNsYXNzIERvTm90aGluZ1hNTFJlYWRlciBpbXBsZW1lbnRzIFhNTFJlYWRlciB7CisKKyAgICBwdWJsaWMgQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBEVERIYW5kbGVyIGdldERUREhhbmRsZXIoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBFbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlcigpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTb3VyY2UgaW5wdXQpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBwYXJzZShTdHJpbmcgc3lzdGVtSWQpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlciBoYW5kbGVyKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlcihEVERIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRFbnRpdHlSZXNvbHZlcihFbnRpdHlSZXNvbHZlciByZXNvbHZlcikgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgaGFuZGxlcikgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKSB7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L3N1cHBvcnQvTWV0aG9kTG9nZ2VyLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L3N1cHBvcnQvTWV0aG9kTG9nZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWQ4ZWY1ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9NZXRob2RMb2dnZXIuamF2YQpAQCAtMCwwICsxLDk1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5vcmcueG1sLnNheC5zdXBwb3J0OworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBBIHNpbXBsZSBoZWxwZXIgY2xhc3MgdGhhdCBsb2dzIG1ldGhvZCBjYWxscyBieSBzdG9yaW5nIG1ldGhvZCBuYW1lcyBhbmQKKyAqIHBhcmFtZXRlciBsaXN0cy4gVXNlZCBhcyBhIGZvdW5kYXRpb24gZm9yIHZhcmlvdXMgc2ltcGxlIFNBWCBoYW5kbGVycy4KKyAqLworcHVibGljIGNsYXNzIE1ldGhvZExvZ2dlciB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbmFtZXMgb2YgdGhlIGludm9rZWQgbWV0aG9kcywgaW4gb3JkZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBMaXN0PFN0cmluZz4gbWV0aG9kcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworCisgICAgLyoqCisgICAgICogVGhlIHBhcmFtZXRlciBsaXN0cyBvZiB0aGUgaW52b2tlZCBtZXRob2RzLCBpbiBvcmRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIExpc3Q8T2JqZWN0W10+IGFyZ0xpc3RzID0gbmV3IEFycmF5TGlzdDxPYmplY3RbXT4oKTsKKworICAgIC8qKgorICAgICAqIEFkZHMgYSBtZXRob2QgY2FsbCB3aXRoIGEgdmFyaWFibGUgbGlzdCBvZiBhcmd1bWVudHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkKFN0cmluZyBtZXRob2QsIE9iamVjdCAuLi4gYXJncykgeworICAgICAgICBPYmplY3RbXSBhcmdzQ29weSA9IG5ldyBPYmplY3RbYXJncy5sZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFyZ3MsIDAsIGFyZ3NDb3B5LCAwLCBhcmdzLmxlbmd0aCk7CisKKyAgICAgICAgbWV0aG9kcy5hZGQobWV0aG9kKTsKKyAgICAgICAgYXJnTGlzdHMuYWRkKGFyZ3NDb3B5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgbWV0aG9kIGludm9rZWQgc28gZmFyLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIG1ldGhvZHMuc2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1ldGhvZCBuYW1lIHN0b3JlZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRNZXRob2QoaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiBtZXRob2RzLmdldChpbmRleCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgbGFzdCBtZXRob2QgdGhhdCB3YXMgaW52b2tlZC4gUmV0dXJucyBudWxsIGlmIG5vCisgICAgICogbWV0aG9kIGNhbGxzIGhhdmUgYmVlbiBsb2dnZWQgc28gZmFyLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWV0aG9kKCkgeworICAgICAgICByZXR1cm4gKHNpemUoKSA9PSAwID8gbnVsbCA6IGdldE1ldGhvZChzaXplKCkgLSAxKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXJndW1lbnQgYXJyYXkgc3RvcmVkIGF0IHRoZSBnaXZlbiBpbmRleC4gTWF5IGJlIGVtcHR5LCBidXQKKyAgICAgKiBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0W10gZ2V0QXJncyhpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIGFyZ0xpc3RzLmdldChpbmRleCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXJndW1lbnQgYXJyYXkgb2YgdGhlIGxhc3QgbWV0aG9kIHRoYXQgd2FzIGludm9rZWQuIFJldHVybnMKKyAgICAgKiBudWxsIGlmIG5vIG1ldGhvZCBoYXMgYmVlbiBpbnZva2VkIHNvIGZhci4KKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0W10gZ2V0QXJncygpIHsKKyAgICAgICAgcmV0dXJuIChzaXplKCkgPT0gMCA/IG51bGwgOiBnZXRBcmdzKHNpemUoKSAtIDEpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbGVhcnMgdGhlIGxvZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgbWV0aG9kcy5jbGVhcigpOworICAgICAgICBhcmdMaXN0cy5jbGVhcigpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9zdXBwb3J0L01vY2tGaWx0ZXIuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Nb2NrRmlsdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTE4OWViZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Nb2NrRmlsdGVyLmphdmEKQEAgLTAsMCArMSw4OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkub3JnLnhtbC5zYXguc3VwcG9ydDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuWE1MRmlsdGVySW1wbDsKKworLyoqCisgKiBBIGhlbHBlciBjbGFzcyB0aGF0IGV4dGVuZHMgWE1MRmlsdGVySW1wbCwgcHJvdmlkZXMgZHVtbXkgZmVhdHVyZS9wcm9wZXJ0eQorICogbWFuYWdlbWVudCwgYW5kIGxvZ3Mgc29tZSBtZXRob2QgY2FsbHMuCisgKi8KK3B1YmxpYyBjbGFzcyBNb2NrRmlsdGVyIGV4dGVuZHMgWE1MRmlsdGVySW1wbCB7CisKKyAgICBwcml2YXRlIE1ldGhvZExvZ2dlciBsb2dnZXI7CisKKyAgICBwcml2YXRlIFNldDxTdHJpbmc+IGZlYXR1cmVzID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworCisgICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBPYmplY3Q+IHByb3BlcnRpZXMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIE9iamVjdD4oKTsKKworICAgIHB1YmxpYyBNb2NrRmlsdGVyKE1ldGhvZExvZ2dlciBsb2dnZXIpIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgdGhpcy5sb2dnZXIgPSBsb2dnZXI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sCisgICAgICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZmVhdHVyZXMuY29udGFpbnMobmFtZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sCisgICAgICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gcHJvcGVydGllcy5nZXQobmFtZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICBpZiAodmFsdWUpIHsKKyAgICAgICAgICAgIGZlYXR1cmVzLmFkZChuYW1lKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGZlYXR1cmVzLnJlbW92ZShuYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLAorICAgICAgICAgICAgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgIHByb3BlcnRpZXMucmVtb3ZlKG5hbWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcHJvcGVydGllcy5wdXQobmFtZSwgdmFsdWUpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTb3VyY2UgaW5wdXQpIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgicGFyc2UiLCBpbnB1dCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcGFyc2UoU3RyaW5nIHN5c3RlbUlkKSB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxvZ2dlci5hZGQoInBhcnNlIiwgc3lzdGVtSWQpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9zdXBwb3J0L01vY2tIYW5kbGVyLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L3N1cHBvcnQvTW9ja0hhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NTc1N2M5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9zdXBwb3J0L01vY2tIYW5kbGVyLmphdmEKQEAgLTAsMCArMSwxNDcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQ7CisKK2ltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0OworaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7CitpbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRFRESGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKKworLyoqCisgKiBBIGhlbHBlciBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhlIHZhcmlvdXMgU0FYIGNhbGxiYWNrIGludGVyZmFjZXMgYW5kIGxvZ3MKKyAqIG1ldGhvZCBjYWxscy4KKyAqLworQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKK3B1YmxpYyBjbGFzcyBNb2NrSGFuZGxlciBpbXBsZW1lbnRzIENvbnRlbnRIYW5kbGVyLCBEVERIYW5kbGVyLCBEb2N1bWVudEhhbmRsZXIsCisgICAgICAgIEVycm9ySGFuZGxlciwgTGV4aWNhbEhhbmRsZXIgeworCisgICAgcHJpdmF0ZSBNZXRob2RMb2dnZXIgbG9nZ2VyOworCisgICAgcHVibGljIE1vY2tIYW5kbGVyKE1ldGhvZExvZ2dlciBsb2dnZXIpIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgdGhpcy5sb2dnZXIgPSBsb2dnZXI7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIGxvZ2dlci5hZGQoImNoYXJhY3RlcnMiLCBjaCwgc3RhcnQsIGxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgiZW5kRG9jdW1lbnQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgiZW5kRWxlbWVudCIsIG5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIG5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICBsb2dnZXIuYWRkKCJlbmRFbGVtZW50IiwgdXJpLCBsb2NhbE5hbWUsIG5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIGxvZ2dlci5hZGQoImVuZFByZWZpeE1hcHBpbmciLCBwcmVmaXgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIGxvZ2dlci5hZGQoImVycm9yIiwgZXhjZXB0aW9uKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBmYXRhbEVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIGxvZ2dlci5hZGQoImZhdGFsRXJyb3IiLCBleGNlcHRpb24pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICBsb2dnZXIuYWRkKCJpZ25vcmFibGVXaGl0ZXNwYWNlIiwgY2gsIHN0YXJ0LCBsZW5ndGgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICBsb2dnZXIuYWRkKCJub3RhdGlvbkRlY2wiLCBuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIGxvZ2dlci5hZGQoInByb2Nlc3NpbmdJbnN0cnVjdGlvbiIsIHRhcmdldCwgZGF0YSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikgeworICAgICAgICBsb2dnZXIuYWRkKCJzZXREb2N1bWVudExvY2F0b3IiLCBsb2NhdG9yKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBza2lwcGVkRW50aXR5KFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgic2tpcHBlZEVudGl0eSIsIG5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgic3RhcnREb2N1bWVudCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgbmFtZSwgQXR0cmlidXRlTGlzdCBhdHRzKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgic3RhcnRFbGVtZW50IiwgbmFtZSwgYXR0cyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBuYW1lLCBBdHRyaWJ1dGVzIGF0dHMpCisgICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgic3RhcnRFbGVtZW50IiwgdXJpLCBsb2NhbE5hbWUsIG5hbWUsIGF0dHMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHN0YXJ0UHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgic3RhcnRQcmVmaXhNYXBwaW5nIiwgcHJlZml4LCB1cmkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQsCisgICAgICAgICAgICBTdHJpbmcgbm90YXRpb25OYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgidW5wYXJzZWRFbnRpdHlEZWNsIiwgbmFtZSwgcHVibGljSWQsIHN5c3RlbUlkLCBub3RhdGlvbk5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoU0FYUGFyc2VFeGNlcHRpb24gZXhjZXB0aW9uKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgid2FybmluZyIsIGV4Y2VwdGlvbik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY29tbWVudChjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIGxvZ2dlci5hZGQoImNvbW1lbnQiLCBjaCwgc3RhcnQsIGxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5kQ0RBVEEoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgiZW5kQ0RBVEEiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmREVEQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgiZW5kRFREIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5kRW50aXR5KFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgiZW5kRW50aXR5IiwgbmFtZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc3RhcnRDREFUQSgpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICBsb2dnZXIuYWRkKCJzdGFydENEQVRBIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc3RhcnREVEQoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgic3RhcnREVEQiLCBuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgic3RhcnRFbnRpdHkiLCBuYW1lKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Nb2NrUGFyc2VyLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L3N1cHBvcnQvTW9ja1BhcnNlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUxOWUxNGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L3N1cHBvcnQvTW9ja1BhcnNlci5qYXZhCkBAIC0wLDAgKzEsNjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CisKK2ltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CitpbXBvcnQgb3JnLnhtbC5zYXguUGFyc2VyOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKKworQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKK3B1YmxpYyBjbGFzcyBNb2NrUGFyc2VyIGltcGxlbWVudHMgUGFyc2VyIHsKKworICAgIHByaXZhdGUgTWV0aG9kTG9nZ2VyIGxvZ2dlcjsKKworICAgIHB1YmxpYyBNb2NrUGFyc2VyKE1ldGhvZExvZ2dlciBsb2dnZXIpIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgdGhpcy5sb2dnZXIgPSBsb2dnZXI7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTb3VyY2Ugc291cmNlKSB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGxvZ2dlci5hZGQoInBhcnNlIiwgc291cmNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBwYXJzZShTdHJpbmcgc3lzdGVtSWQpIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgicGFyc2UiLCBzeXN0ZW1JZCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlcihEVERIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgic2V0RFRESGFuZGxlciIsIGhhbmRsZXIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50SGFuZGxlcihEb2N1bWVudEhhbmRsZXIgaGFuZGxlcikgeworICAgICAgICBsb2dnZXIuYWRkKCJzZXREb2N1bWVudEhhbmRsZXIiLCBoYW5kbGVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRFbnRpdHlSZXNvbHZlcihFbnRpdHlSZXNvbHZlciByZXNvbHZlcikgeworICAgICAgICBsb2dnZXIuYWRkKCJzZXRFbnRpdHlSZXNvbHZlciIsIHJlc29sdmVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgic2V0RXJyb3JIYW5kbGVyIiwgaGFuZGxlcik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpIHRocm93cyBTQVhFeGNlcHRpb24geworICAgICAgICBsb2dnZXIuYWRkKCJzZXRMb2NhbGUiLCBsb2NhbGUpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9zdXBwb3J0L01vY2tSZWFkZXIuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Nb2NrUmVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmYwMDgxYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Nb2NrUmVhZGVyLmphdmEKQEAgLTAsMCArMSwxMjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkRUREhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7CisKKy8qKgorICogQSBoZWxwZXIgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoZSBTQVggWE1MUmVhZGVyIGludGVyZmFjZSBhbmQgbG9ncyBtZXRob2QKKyAqIGNhbGxzLgorICovCitwdWJsaWMgY2xhc3MgTW9ja1JlYWRlciBpbXBsZW1lbnRzIFhNTFJlYWRlciB7CisKKyAgICBwcml2YXRlIE1ldGhvZExvZ2dlciBsb2dnZXI7CisKKyAgICBwcml2YXRlIENvbnRlbnRIYW5kbGVyIGNvbnRlbnRIYW5kbGVyOworCisgICAgcHJpdmF0ZSBEVERIYW5kbGVyIGR0ZEhhbmRsZXI7CisKKyAgICBwcml2YXRlIEVudGl0eVJlc29sdmVyIHJlc29sdmVyOworCisgICAgcHJpdmF0ZSBFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyOworCisgICAgcHJpdmF0ZSBTZXQ8U3RyaW5nPiBmZWF0dXJlcyA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKworICAgIHByaXZhdGUgTWFwPFN0cmluZywgT2JqZWN0PiBwcm9wZXJ0aWVzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBPYmplY3Q+KCk7CisKKyAgICBwdWJsaWMgTW9ja1JlYWRlcihNZXRob2RMb2dnZXIgbG9nZ2VyKSB7CisgICAgICAgIHN1cGVyKCk7CisgICAgICAgIHRoaXMubG9nZ2VyID0gbG9nZ2VyOworICAgIH0KKworCisgICAgcHVibGljIENvbnRlbnRIYW5kbGVyIGdldENvbnRlbnRIYW5kbGVyKCkgeworICAgICAgICByZXR1cm4gY29udGVudEhhbmRsZXI7CisgICAgfQorCisgICAgcHVibGljIERUREhhbmRsZXIgZ2V0RFRESGFuZGxlcigpIHsKKyAgICAgICAgcmV0dXJuIGR0ZEhhbmRsZXI7CisgICAgfQorCisgICAgcHVibGljIEVudGl0eVJlc29sdmVyIGdldEVudGl0eVJlc29sdmVyKCkgeworICAgICAgICByZXR1cm4gcmVzb2x2ZXI7CisgICAgfQorCisgICAgcHVibGljIEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7CisgICAgICAgIHJldHVybiBlcnJvckhhbmRsZXI7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sCisgICAgICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZmVhdHVyZXMuY29udGFpbnMobmFtZSk7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sCisgICAgICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gcHJvcGVydGllcy5nZXQobmFtZSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTb3VyY2UgaW5wdXQpIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgbG9nZ2VyLmFkZCgicGFyc2UiLCBpbnB1dCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcGFyc2UoU3RyaW5nIHN5c3RlbUlkKSB0aHJvd3MgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiB7CisgICAgICAgIGxvZ2dlci5hZGQoInBhcnNlIiwgc3lzdGVtSWQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyKENvbnRlbnRIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICAgICAgdGhpcy5jb250ZW50SGFuZGxlciA9IGhhbmRsZXI7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlcihEVERIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICAgICAgdGhpcy5kdGRIYW5kbGVyID0gaGFuZGxlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRFbnRpdHlSZXNvbHZlcihFbnRpdHlSZXNvbHZlciByZXNvbHZlcikgeworICAgICAgICB0aGlzLnJlc29sdmVyID0gcmVzb2x2ZXI7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlciBoYW5kbGVyKSB7CisgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gaGFuZGxlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKSB7CisgICAgICAgIGlmICh2YWx1ZSkgeworICAgICAgICAgICAgZmVhdHVyZXMuYWRkKG5hbWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmVhdHVyZXMucmVtb3ZlKG5hbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sCisgICAgICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgcHJvcGVydGllcy5yZW1vdmUobmFtZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnB1dChuYW1lLCB2YWx1ZSk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Nb2NrUmVzb2x2ZXIuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Nb2NrUmVzb2x2ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZjRkZGJmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9zdXBwb3J0L01vY2tSZXNvbHZlci5qYXZhCkBAIC0wLDAgKzEsNDcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247CisKKy8qKgorICogQSBoZWxwZXIgY2xhc3MgZm9yIHJlc29sdmluZyBlbnRpdGllcy4KKyAqLworcHVibGljIGNsYXNzIE1vY2tSZXNvbHZlciBpbXBsZW1lbnRzIEVudGl0eVJlc29sdmVyIHsKKworICAgIHByaXZhdGUgTWFwPFN0cmluZywgSW5wdXRTb3VyY2U+IGVudGl0aWVzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBJbnB1dFNvdXJjZT4oKTsKKworICAgIHB1YmxpYyB2b2lkIGFkZEVudGl0eShTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwgSW5wdXRTb3VyY2Ugc291cmNlKSB7CisgICAgICAgIGVudGl0aWVzLnB1dCgiWyIgKyBwdWJsaWNJZCArICI6IiArIHN5c3RlbUlkICsgIl0iLCBzb3VyY2UpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlbW92ZUVudGl0eShTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkgeworICAgICAgICBlbnRpdGllcy5yZW1vdmUoIlsiICsgcHVibGljSWQgKyAiOiIgKyBzeXN0ZW1JZCArICJdIik7CisgICAgfQorCisgICAgcHVibGljIElucHV0U291cmNlIHJlc29sdmVFbnRpdHkoU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCisgICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBlbnRpdGllcy5nZXQoIlsiICsgcHVibGljSWQgKyAiOiIgKyBzeXN0ZW1JZCArICJdIik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L3N1cHBvcnQvTm9BY2Nlc3NQYXJzZXIuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Ob0FjY2Vzc1BhcnNlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmY2E1MTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L3N1cHBvcnQvTm9BY2Nlc3NQYXJzZXIuamF2YQpAQCAtMCwwICsxLDU1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5vcmcueG1sLnNheC5zdXBwb3J0OworCitpbXBvcnQgb3JnLnhtbC5zYXguRFRESGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOworaW1wb3J0IG9yZy54bWwuc2F4LlBhcnNlcjsKKworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CisKKy8qKgorICogQSBTQVggUGFyc2VyIHRoYXQgY2FuJ3QgYmUgYWNjZXNzZWQuCisgKi8KK0BTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCitjbGFzcyBOb0FjY2Vzc1BhcnNlciBpbXBsZW1lbnRzIFBhcnNlciB7CisKKyAgICBwdWJsaWMgdm9pZCBwYXJzZShJbnB1dFNvdXJjZSBzb3VyY2UpICB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcGFyc2UoU3RyaW5nIHN5c3RlbUlkKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRIYW5kbGVyKERvY3VtZW50SGFuZGxlciBoYW5kbGVyKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlcihEVERIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRFbnRpdHlSZXNvbHZlcihFbnRpdHlSZXNvbHZlciByZXNvbHZlcikgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgaGFuZGxlcikgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldExvY2FsZShMb2NhbGUgbG9jYWxlKSB7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L3N1cHBvcnQvTm9BY2Nlc3NYTUxSZWFkZXIuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Ob0FjY2Vzc1hNTFJlYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2YTBhNjgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L3N1cHBvcnQvTm9BY2Nlc3NYTUxSZWFkZXIuamF2YQpAQCAtMCwwICsxLDc5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5vcmcueG1sLnNheC5zdXBwb3J0OworCitpbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRFRESGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CitpbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOworCisvKioKKyAqIEFuIFhNTFJlYWRlciB0aGF0IGlzIG5vdCBhY2Nlc3NpYmxlLgorICovCitjbGFzcyBOb0FjY2Vzc1hNTFJlYWRlciBpbXBsZW1lbnRzIFhNTFJlYWRlciB7CisKKyAgICBwdWJsaWMgQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBEVERIYW5kbGVyIGdldERUREhhbmRsZXIoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBFbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlcigpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTb3VyY2UgaW5wdXQpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBwYXJzZShTdHJpbmcgc3lzdGVtSWQpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlciBoYW5kbGVyKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlcihEVERIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRFbnRpdHlSZXNvbHZlcihFbnRpdHlSZXNvbHZlciByZXNvbHZlcikgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgaGFuZGxlcikgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKSB7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L3N1cHBvcnQvTm9JbnN0YW5jZVBhcnNlci5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9zdXBwb3J0L05vSW5zdGFuY2VQYXJzZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40OGNmYmE3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9zdXBwb3J0L05vSW5zdGFuY2VQYXJzZXIuamF2YQpAQCAtMCwwICsxLDU4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmFwaS5vcmcueG1sLnNheC5zdXBwb3J0OworCitpbXBvcnQgb3JnLnhtbC5zYXguRFRESGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOworaW1wb3J0IG9yZy54bWwuc2F4LlBhcnNlcjsKKworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CisKKy8qKgorICogQSBTQVggUGFyc2VyIHRoYXQgY2FuIGJlIGFjY2Vzc2VkLCBidXQgbm90IGluc3RhbnRpYXRlZC4KKyAqLworQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKK3B1YmxpYyBjbGFzcyBOb0luc3RhbmNlUGFyc2VyIGltcGxlbWVudHMgUGFyc2VyIHsKKworICAgIHB1YmxpYyBOb0luc3RhbmNlUGFyc2VyKGludCBpKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTb3VyY2Ugc291cmNlKSAgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHBhcnNlKFN0cmluZyBzeXN0ZW1JZCkgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50SGFuZGxlcihEb2N1bWVudEhhbmRsZXIgaGFuZGxlcikgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldERUREhhbmRsZXIoRFRESGFuZGxlciBoYW5kbGVyKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoRW50aXR5UmVzb2x2ZXIgcmVzb2x2ZXIpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRMb2NhbGUoTG9jYWxlIGxvY2FsZSkgeworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2FwaS9vcmcveG1sL3NheC9zdXBwb3J0L05vSW5zdGFuY2VYTUxSZWFkZXIuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Ob0luc3RhbmNlWE1MUmVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2IzODZiYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Ob0luc3RhbmNlWE1MUmVhZGVyLmphdmEKQEAgLTAsMCArMSw4MiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5hcGkub3JnLnhtbC5zYXguc3VwcG9ydDsKKworaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkRUREhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOworaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKKworLyoqCisgKiBBbiBYTUxSZWFkZXIgdGhhdCBpcyBhY2Nlc3NpYmxlLCBidXQgY2FuJ3QgYmUgaW5zdGFudGlhdGVkLgorICovCitwdWJsaWMgY2xhc3MgTm9JbnN0YW5jZVhNTFJlYWRlciBpbXBsZW1lbnRzIFhNTFJlYWRlciB7CisKKyAgICBwdWJsaWMgTm9JbnN0YW5jZVhNTFJlYWRlcihpbnQgaSkgeworICAgIH0KKworICAgIHB1YmxpYyBDb250ZW50SGFuZGxlciBnZXRDb250ZW50SGFuZGxlcigpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIERUREhhbmRsZXIgZ2V0RFRESGFuZGxlcigpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIEVudGl0eVJlc29sdmVyIGdldEVudGl0eVJlc29sdmVyKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBwYXJzZShJbnB1dFNvdXJjZSBpbnB1dCkgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHBhcnNlKFN0cmluZyBzeXN0ZW1JZCkgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyKENvbnRlbnRIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyKERUREhhbmRsZXIgaGFuZGxlcikgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyKEVudGl0eVJlc29sdmVyIHJlc29sdmVyKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlciBoYW5kbGVyKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Ob1N1YmNsYXNzUGFyc2VyLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L3N1cHBvcnQvTm9TdWJjbGFzc1BhcnNlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgwMTZjMTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L3N1cHBvcnQvTm9TdWJjbGFzc1BhcnNlci5qYXZhCkBAIC0wLDAgKzEsNTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQ7CisKK2ltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CisKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCisvKioKKyAqIEEgU0FYIFBhcnNlciB0aGF0IGRvZXMgbm90IGltcGxlbWVudCB0aGUgUGFyc2VyIGludGVyZmFjZS4KKyAqLworQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKK3B1YmxpYyBjbGFzcyBOb1N1YmNsYXNzUGFyc2VyIHsKKworICAgIHB1YmxpYyB2b2lkIHBhcnNlKElucHV0U291cmNlIHNvdXJjZSkgIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBwYXJzZShTdHJpbmcgc3lzdGVtSWQpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEhhbmRsZXIoRG9jdW1lbnRIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyKERUREhhbmRsZXIgaGFuZGxlcikgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyKEVudGl0eVJlc29sdmVyIHJlc29sdmVyKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlciBoYW5kbGVyKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpIHsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9hcGkvb3JnL3htbC9zYXgvc3VwcG9ydC9Ob1N1YmNsYXNzWE1MUmVhZGVyLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L3N1cHBvcnQvTm9TdWJjbGFzc1hNTFJlYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFjZGJkODgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvYXBpL29yZy94bWwvc2F4L3N1cHBvcnQvTm9TdWJjbGFzc1hNTFJlYWRlci5qYXZhCkBAIC0wLDAgKzEsNzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuYXBpLm9yZy54bWwuc2F4LnN1cHBvcnQ7CisKK2ltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOworaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKK2ltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7CisKKy8qKgorICogQW4gWE1MUmVhZGVyIHRoYXQgZG9lcyBub3QgaW1wbGVtZW50IHRoZSBYTUxSZWFkZXIgaW50ZXJmYWNlLgorICovCitwdWJsaWMgY2xhc3MgTm9TdWJjbGFzc1hNTFJlYWRlciBpbXBsZW1lbnRzIFhNTFJlYWRlciB7CisKKyAgICBwdWJsaWMgQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBEVERIYW5kbGVyIGdldERUREhhbmRsZXIoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBFbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlcigpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTb3VyY2UgaW5wdXQpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBwYXJzZShTdHJpbmcgc3lzdGVtSWQpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlciBoYW5kbGVyKSB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlcihEVERIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRFbnRpdHlSZXNvbHZlcihFbnRpdHlSZXNvbHZlciByZXNvbHZlcikgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgaGFuZGxlcikgeworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKSB7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvamF2YS9sYW5nL1N0cmluZy9UZXN0cy5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2phdmEvbGFuZy9TdHJpbmcvVGVzdHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNWFiMjY5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2phdmEvbGFuZy9TdHJpbmcvVGVzdHMuamF2YQpAQCAtMCwwICsxLDQ4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5qYXZhLmxhbmcuU3RyaW5nOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZvciB0aGUgY2xhc3Mge0BsaW5rIFN0cmluZ30uCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0cyBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbnRhaW5zKCkgeworICAgICAgICBhc3NlcnRUcnVlKCJhYWJjIi5jb250YWlucygiYWJjIikpOworICAgICAgICBhc3NlcnRUcnVlKCJhYmNkIi5jb250YWlucygiYWJjIikpOworICAgICAgICBhc3NlcnRGYWxzZSgiYWJjZCIuY29udGFpbnMoImNiYSIpKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdF9jaGFyQXQoKSB7CisgICAgICAgIGFzc2VydFRydWUoImFiY2QiLmNoYXJBdCgwKSA9PSAnYScpOworICAgICAgICBhc3NlcnRUcnVlKCJhYmNkIi5jaGFyQXQoMykgPT0gJ2QnKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdF9TdGFydHNXaXRoKCkgeworICAgICAgICBhc3NlcnRUcnVlKCJhYmNkIi5zdGFydHNXaXRoKCJhYmMiKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJhYmNkIi5zdGFydHNXaXRoKCJhYWJjIikpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0VuZHNXaXRoKCkgeworICAgICAgICBhc3NlcnRUcnVlKCJhYmNkIi5lbmRzV2l0aCgiYmNkIikpOworICAgICAgICBhc3NlcnRGYWxzZSgiYWJjZCIuZW5kc1dpdGgoImJjZGUiKSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RfQ0FTRV9JTlNFTlNJVElWRV9PUkRFUigpIHsKKyAgICAgICAgU3RyaW5nICBzMSA9ICJBQkNERUZHIjsKKyAgICAgICAgU3RyaW5nICBzMiA9ICJhYmNkZWZnIjsKKworICAgICAgICBhc3NlcnRUcnVlKFN0cmluZy5DQVNFX0lOU0VOU0lUSVZFX09SREVSLmNvbXBhcmUoczEsIHMyKSA9PSAwKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvamF2YS9zZWN1cml0eS9BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JTcGlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvamF2YS9zZWN1cml0eS9BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JTcGlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDdiOWVkNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9qYXZhL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaVRlc3QuamF2YQpAQCAtMCwwICsxLDczIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyAqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2UgdGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5NeUFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+QWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yU3BpPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMKKyAqIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JTcGk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JTcGkwMSgpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIE15QWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yU3BpIGFsZ1BhckdlbiA9IG5ldyBNeUFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaSgpOworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtID0gYWxnUGFyR2VuLmVuZ2luZUdlbmVyYXRlUGFyYW1ldGVycygpOworICAgICAgICBhc3NlcnROdWxsKCJOb3QgbnVsbCBwYXJhbWV0ZXJzIiwgcGFyYW0pOworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBwID0gbnVsbDsKKyAgICAgICAgYWxnUGFyR2VuLmVuZ2luZUluaXQocHAsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhbGdQYXJHZW4uZW5naW5lSW5pdChwcCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBhbGdQYXJHZW4uZW5naW5lSW5pdCgwLCBudWxsKTsKKyAgICAgICAgYWxnUGFyR2VuLmVuZ2luZUluaXQoMCwgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYWxnUGFyR2VuLmVuZ2luZUluaXQoLTEwLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhbGdQYXJHZW4uZW5naW5lSW5pdCgtMTAsIG5ldyBTZWN1cmVSYW5kb20oKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvamF2YS9zZWN1cml0eS9JZGVudGl0eVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9qYXZhL3NlY3VyaXR5L0lkZW50aXR5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQwNWIxMDAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvamF2YS9zZWN1cml0eS9JZGVudGl0eVRlc3QuamF2YQpAQCAtMCwwICsxLDMzNCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxla3NlaSBZLiBTZW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSWRlbnRpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JZGVudGl0eVNjb3BlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5TWFuYWdlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5UGVybWlzc2lvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LkNlcnRpZmljYXRlU3R1YjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5JZGVudGl0eVN0dWI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuUHVibGljS2V5U3R1YjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgY2xhc3MgSWRlbnRpdHkKKyAqCisgKi8KK0BTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCitwdWJsaWMgY2xhc3MgSWRlbnRpdHlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBNeVNlY3VyaXR5TWFuYWdlciBleHRlbmRzIFNlY3VyaXR5TWFuYWdlciB7CisgICAgICAgIHB1YmxpYyBQZXJtaXNzaW9ucyBkZW5pZWQgPSBuZXcgUGVybWlzc2lvbnMoKTsKKyAgICAgICAgcHVibGljIHZvaWQgY2hlY2tQZXJtaXNzaW9uKFBlcm1pc3Npb24gcGVybWlzc2lvbil7CisgICAgICAgICAgICBpZiAoZGVuaWVkIT1udWxsICYmIGRlbmllZC5pbXBsaWVzKHBlcm1pc3Npb24pKSB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RIYXNoQ29kZSgpIHsKKyAgICAgICAgbmV3IElkZW50aXR5U3R1YigidGVzdEhhc2hDb2RlIikuaGFzaENvZGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXF1YWxzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElkZW50aXR5U3R1YiBpMSA9IG5ldyBJZGVudGl0eVN0dWIoInRlc3RFcXVhbHMiKTsKKyAgICAgICAgT2JqZWN0IHZhbHVlW10gPSAgeworICAgICAgICAgICAgICAgIG51bGwsIEJvb2xlYW4uRkFMU0UsCisgICAgICAgICAgICAgICAgbmV3IE9iamVjdCgpLCBCb29sZWFuLkZBTFNFLAorICAgICAgICAgICAgICAgIGkxLCBCb29sZWFuLlRSVUUsCisgICAgICAgICAgICAgICAgbmV3IElkZW50aXR5U3R1YihpMS5nZXROYW1lKCkpLCBCb29sZWFuLlRSVUUKKyAgICAgICAgfTsKKworICAgICAgICBmb3IgKGludCBrPTA7IGs8dmFsdWUubGVuZ3RoOyBrKz0yKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModmFsdWVbaysxXSwgbmV3IEJvb2xlYW4oaTEuZXF1YWxzKHZhbHVlW2tdKSkpOworICAgICAgICAgICAgaWYgKEJvb2xlYW4uVFJVRS5lcXVhbHModmFsdWVbaysxXSkpIGFzc2VydEVxdWFscyhpMS5oYXNoQ29kZSgpLCB2YWx1ZVtrXS5oYXNoQ29kZSgpKTsKKyAgICAgICAgfQorICAgICAgICAvLyBjaGVjayBvdGhlciBjYXNlcworICAgICAgICBJZGVudGl0eSBpMiA9IG5ldyBJZGVudGl0eVN0dWIoInRlc3RFcXVhbHMiLCBJZGVudGl0eVNjb3BlLmdldFN5c3RlbVNjb3BlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoaTEuaWRlbnRpdHlFcXVhbHMoaTIpLCBpMS5lcXVhbHMoaTIpKTsKKyAgICAgICAgSWRlbnRpdHkgaTMgPSBuZXcgSWRlbnRpdHlTdHViKCJ0ZXN0RXF1YWxzMyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoaTEuaWRlbnRpdHlFcXVhbHMoaTMpLCBpMS5lcXVhbHMoaTMpKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIHZlcmlmeSBJZGVudGl0eS50b1N0cmluZygpCisgICAgICovCisgICAgIHB1YmxpYyB2b2lkIHRlc3RUb1N0cmluZzIoKSB7CisgICAgICAgIGFzc2VydE5vdE51bGwobmV3IElkZW50aXR5U3R1YigidGVzdFRvU3RyaW5nMiIpLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHZlcmlmeSBJZGVudGl0eSgpIGNyZWF0ZXMgaW5zdGFuY2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWRlbnRpdHkoKSB7CisgICAgICAgIGFzc2VydE5vdE51bGwobmV3IElkZW50aXR5U3R1YigpKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIHZlcmlmeSBJZGVudGl0eShTdHJpbmcpIGNyZWF0ZXMgaW5zdGFuY2Ugd2l0aCBnaXZlbiBuYW1lCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdElkZW50aXR5U3RyaW5nKCkgeworICAgICAgICBJZGVudGl0eSBpID0gbmV3IElkZW50aXR5U3R1YigiaWlpIik7CisgICAgICAgIGFzc2VydE5vdE51bGwoaSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaWlpIiwgaS5nZXROYW1lKCkpOworICAgICAgICBpPW5ldyBJZGVudGl0eVN0dWIobnVsbCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoaSk7CisgICAgICAgIGFzc2VydE51bGwoaS5nZXROYW1lKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHZlcmlmeSBJZGVudGl0eShTdHJpbmcsIElkZW50aXR5U2NvcGUpIGNyZWF0ZXMgaW5zdGFuY2Ugd2l0aCBnaXZlbiBuYW1lIGFuZCBpbiBnaXZlIHNjb3BlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdElkZW50aXR5U3RyaW5nSWRlbnRpdHlTY29wZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBJZGVudGl0eVNjb3BlIHMgPSBJZGVudGl0eVNjb3BlLmdldFN5c3RlbVNjb3BlKCk7CisgICAgICAgIElkZW50aXR5IGkgPSBuZXcgSWRlbnRpdHlTdHViKCJpaWkyIiwgcyk7CisgICAgICAgIGFzc2VydE5vdE51bGwoaSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaWlpMiIsIGkuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShzLCBpLmdldFNjb3BlKCkpOworICAgICAgICBhc3NlcnRTYW1lKGksIHMuZ2V0SWRlbnRpdHkoaS5nZXROYW1lKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB2ZXJpZnkgYWRkQ2VydGlmaWNhdGUoQ2VydGlmaWNhdGUgY2VydGlmaWNhdGUpIGFkZHMgYSBjZXJ0aWZpY2F0ZSBmb3IgdGhpcyBpZGVudGl0eS4KKyAgICAgKiBJZiB0aGUgaWRlbnRpdHkgaGFzIGEgcHVibGljIGtleSwgdGhlIHB1YmxpYyBrZXkgaW4gdGhlIGNlcnRpZmljYXRlIG11c3QgYmUgdGhlIHNhbWUKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRDZXJ0aWZpY2F0ZTEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSWRlbnRpdHkgaSA9IG5ldyBJZGVudGl0eVN0dWIoImlpaSIpOworICAgICAgICBQdWJsaWNLZXlTdHViIHBrMSA9IG5ldyBQdWJsaWNLZXlTdHViKCJra2siLCAiZmZmIiwgbmV3IGJ5dGVbXXsxLDIsMyw0LDV9KTsKKyAgICAgICAgaS5zZXRQdWJsaWNLZXkocGsxKTsKKyAgICAgICAgLy8gdHJ5IHdpdGggdGhlIHNhbWUga2V5CisgICAgICAgIENlcnRpZmljYXRlU3R1YiBjMSA9IG5ldyBDZXJ0aWZpY2F0ZVN0dWIoImZmZiIsIG51bGwsIG51bGwsIHBrMSk7CisgICAgICAgIGkuYWRkQ2VydGlmaWNhdGUoYzEpOworICAgICAgICBhc3NlcnRTYW1lKGMxLCBpLmNlcnRpZmljYXRlcygpWzBdKTsKKyAgICAgICAgLy8gdHJ5IENlcnRpZmljYXRlIHdpdGggZGlmZmVyZW50IGtleQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaS5hZGRDZXJ0aWZpY2F0ZShuZXcgQ2VydGlmaWNhdGVTdHViKCJjY2MiLCBudWxsLCBudWxsLCBuZXcgUHVibGljS2V5U3R1YigiazIiLCAiZmZmIiwgbmV3IGJ5dGVbXXs2LDcsOCw5LDB9KSkpOworICAgICAgICAgICAgZmFpbCgiS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEtleU1hbmFnZW1lbnRFeGNlcHRpb24gb2spIHt9CisgICAgfQorCisgICAgLyoqCisgICAgICogdmVyaWZ5IGFkZENlcnRpZmljYXRlKENlcnRpZmljYXRlIGNlcnRpZmljYXRlKSBhZGRzIGEgY2VydGlmaWNhdGUgZm9yIHRoaXMgaWRlbnRpdHkuCisgICAgICogaWYgdGhlIGlkZW50aXR5IGRvZXMgbm90IGhhdmUgYSBwdWJsaWMga2V5LCB0aGUgaWRlbnRpdHkncyBwdWJsaWMga2V5IGlzIHNldCB0byBiZSB0aGF0IHNwZWNpZmllZCBpbiB0aGUgY2VydGlmaWNhdGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEFkZENlcnRpZmljYXRlMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBJZGVudGl0eSBpID0gbmV3IElkZW50aXR5U3R1YigiaWlpIik7CisgICAgICAgIFB1YmxpY0tleVN0dWIgcGsxID0gbmV3IFB1YmxpY0tleVN0dWIoImtrayIsICJmZmYiLCBudWxsKTsKKyAgICAgICAgQ2VydGlmaWNhdGVTdHViIGMxID0gbmV3IENlcnRpZmljYXRlU3R1YigiZmZmIiwgbnVsbCwgbnVsbCwgcGsxKTsKKyAgICAgICAgaS5hZGRDZXJ0aWZpY2F0ZShjMSk7CisgICAgICAgIGFzc2VydFNhbWUoYzEsIGkuY2VydGlmaWNhdGVzKClbMF0pOworICAgICAgICBhc3NlcnRTYW1lKHBrMSwgaS5nZXRQdWJsaWNLZXkoKSk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB2ZXJpZnkgYWRkQ2VydGlmaWNhdGUoQ2VydGlmaWNhdGUgY2VydGlmaWNhdGUpIHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIGlmIGNlcnRpZmljYXRlIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWRkQ2VydGlmaWNhdGU0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgSWRlbnRpdHlTdHViKCJhYWEiKS5hZGRDZXJ0aWZpY2F0ZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIktleU1hbmFnZW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIG9rKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG9rKSB7fQorCisgICAgfQorLy8KKy8vICBDb21tZW50ZWQgb3V0IHNpbmNlIHRoZXJlIHdpbGwgbm8gYmUgZml4IGZvciB0aGUgdGVzdCBmYWlsdXJlCisvLyAgICAvKioKKy8vICAgICAqIHZlcmlmeSByZW1vdmVDZXJ0aWZpY2F0ZShDZXJ0aWZpY2F0ZSBjZXJ0aWZpY2F0ZSkgcmVtb3ZlcyBjZXJ0aWZpY2F0ZQorLy8gICAgICovCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlQ2VydGlmaWNhdGUxKCkgdGhyb3dzIEV4Y2VwdGlvbnsKKy8vICAgICAgICBJZGVudGl0eSBpID0gbmV3IElkZW50aXR5U3R1YigiaWlpIik7CisvLyAgICAgICAgUHVibGljS2V5U3R1YiBwazEgPSBuZXcgUHVibGljS2V5U3R1Yigia2trIiwgImZmZiIsIG51bGwpOworLy8gICAgICAgIENlcnRpZmljYXRlU3R1YiBjMSA9IG5ldyBDZXJ0aWZpY2F0ZVN0dWIoImZmZiIsIG51bGwsIG51bGwsIHBrMSk7CisvLyAgICAgICAgaS5hZGRDZXJ0aWZpY2F0ZShjMSk7CisvLyAgICAgICAgYXNzZXJ0U2FtZShjMSwgaS5jZXJ0aWZpY2F0ZXMoKVswXSk7CisvLyAgICAgICAgaS5yZW1vdmVDZXJ0aWZpY2F0ZShjMSk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGkuY2VydGlmaWNhdGVzKCkubGVuZ3RoKTsKKy8vICAgICAgICAvLyB0aHJvdyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIGlmIGNlcnRpZmljYXRlIG5vdCBmb3VuZAorLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIGkucmVtb3ZlQ2VydGlmaWNhdGUoYzEpOworLy8gICAgICAgICAgICBmYWlsKCJLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24iKTsKKy8vICAgICAgICB9IGNhdGNoIChLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIG9rKSB7CisvLyAgICAgICAgfQorLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIGkucmVtb3ZlQ2VydGlmaWNhdGUobnVsbCk7CisvLyAgICAgICAgICAgIGZhaWwoIktleU1hbmFnZW1lbnRFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biIpOworLy8gICAgICAgIH0gY2F0Y2ggKEtleU1hbmFnZW1lbnRFeGNlcHRpb24gb2spIHsKKy8vCisvLyAgICAgICAgfQorLy8gICAgfQorCisgICAgLyoqCisgICAgICogdmVyaWZ5IGNlcnRpZmljYXRlcygpIHJldHVybnMgYSBjb3B5IG9mIGFsbCBjZXJ0aWZpY2F0ZXMgZm9yIHRoaXMgaWRlbnRpdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElkZW50aXR5IGkgPSBuZXcgSWRlbnRpdHlTdHViKCJpaWkiKTsKKyAgICAgICAgUHVibGljS2V5U3R1YiBwazEgPSBuZXcgUHVibGljS2V5U3R1Yigia2trIiwgImZmZiIsIG51bGwpOworICAgICAgICBDZXJ0aWZpY2F0ZVN0dWIgYzEgPSBuZXcgQ2VydGlmaWNhdGVTdHViKCJmZmYiLCBudWxsLCBudWxsLCBwazEpOworICAgICAgICBDZXJ0aWZpY2F0ZVN0dWIgYzIgPSBuZXcgQ2VydGlmaWNhdGVTdHViKCJ6enoiLCBudWxsLCBudWxsLCBwazEpOworICAgICAgICBpLmFkZENlcnRpZmljYXRlKGMxKTsKKyAgICAgICAgaS5hZGRDZXJ0aWZpY2F0ZShjMik7CisgICAgICAgIGphdmEuc2VjdXJpdHkuQ2VydGlmaWNhdGVbXSBzID0gaS5jZXJ0aWZpY2F0ZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjMS5lcXVhbHMoc1swXSkgfHwgYzIuZXF1YWxzKHNbMF0pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjMS5lcXVhbHMoc1sxXSkgfHwgYzIuZXF1YWxzKHNbMV0pKTsKKyAgICAgICAgc1swXSA9IG51bGw7CisgICAgICAgIHNbMV0gPSBudWxsOworICAgICAgICAvLyBjaGVjayB0aGF0IHRoZSBjb3B5IHdhcyBtb2RpZmllZAorICAgICAgICBzID0gaS5jZXJ0aWZpY2F0ZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIHMubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjMS5lcXVhbHMoc1swXSkgfHwgYzIuZXF1YWxzKHNbMF0pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjMS5lcXVhbHMoc1sxXSkgfHwgYzIuZXF1YWxzKHNbMV0pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB2ZXJpZnkgSWRlbnRpdHkuaWRlbnRpdHlFcXVhbHMoSWRlbnRpdHkpIHJldHVybiB0cnVlLCBvbmx5IGlmIG5hbWVzIGFuZCBwdWJsaWMga2V5cyBhcmUgZXF1YWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWRlbnRpdHlFcXVhbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSAibm5uIjsKKyAgICAgICAgUHVibGljS2V5IHBrID0gbmV3IFB1YmxpY0tleVN0dWIoImFhYSIsICJmZmYiLCBuZXcgYnl0ZVtdezEsMiwzLDQsNX0pOworICAgICAgICBJZGVudGl0eVN0dWIgaSA9IG5ldyBJZGVudGl0eVN0dWIobmFtZSk7CisgICAgICAgIGkuc2V0UHVibGljS2V5KHBrKTsKKyAgICAgICAgT2JqZWN0W10gdmFsdWUgPSB7CisgICAgICAgICAgICAgICAgLy9udWxsLCBCb29sZWFuLkZBTFNFLAorICAgICAgICAgICAgICAgIC8vbmV3IE9iamVjdCgpLCBCb29sZWFuLkZBTFNFLAorICAgICAgICAgICAgICAgIG5ldyBJZGVudGl0eVN0dWIoIjExMSIpLCBCb29sZWFuLkZBTFNFLAorICAgICAgICAgICAgICAgIG5ldyBJZGVudGl0eVN0dWIobmFtZSksIEJvb2xlYW4uRkFMU0UsCisgICAgICAgICAgICAgICAgbmV3IElkZW50aXR5U3R1YihuYW1lLCBJZGVudGl0eVNjb3BlLmdldFN5c3RlbVNjb3BlKCkpLCBCb29sZWFuLkZBTFNFLAorICAgICAgICAgICAgICAgIGksIEJvb2xlYW4uVFJVRSwKKyAgICAgICAgICAgICAgICBuZXcgSWRlbnRpdHlTdHViKG5hbWUsIHBrKSwgQm9vbGVhbi5UUlVFCisgICAgICAgIH07CisgICAgICAgIGZvciAoaW50IGs9MDsgazx2YWx1ZS5sZW5ndGg7IGsrPTIpeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHZhbHVlW2srMV0sIG5ldyBCb29sZWFuKGkuaWRlbnRpdHlFcXVhbHMoKElkZW50aXR5KXZhbHVlW2tdKSkpOworICAgICAgICAgICAgaWYgKEJvb2xlYW4uVFJVRS5lcXVhbHModmFsdWVbaysxXSkpIGFzc2VydEVxdWFscyhpLmhhc2hDb2RlKCksIHZhbHVlW2tdLmhhc2hDb2RlKCkpOworICAgICAgICB9CisgICAgICAgIElkZW50aXR5IGkyID0gSWRlbnRpdHlTY29wZS5nZXRTeXN0ZW1TY29wZSgpLmdldElkZW50aXR5KG5hbWUpOworICAgICAgICBpMi5zZXRQdWJsaWNLZXkocGspOworICAgICAgICBhc3NlcnRUcnVlKGkuaWRlbnRpdHlFcXVhbHMoaTIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB2ZXJpZnkgSWRlbnRpdHkudG9TdHJpbmcoYm9vbGVhbikgcmV0dXJuIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBpZGVudGl0eQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RUb1N0cmluZ2Jvb2xlYW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgbmV3IElkZW50aXR5U3R1YigiYWFhIikudG9TdHJpbmcoZmFsc2UpOworICAgICAgICBuZXcgSWRlbnRpdHlTdHViKCJhYWEyIiwgSWRlbnRpdHlTY29wZS5nZXRTeXN0ZW1TY29wZSgpKS50b1N0cmluZyhmYWxzZSk7CisgICAgICAgIG5ldyBJZGVudGl0eVN0dWIoImJiYiIpLnRvU3RyaW5nKHRydWUpOworICAgICAgICBuZXcgSWRlbnRpdHlTdHViKCJiYmIyIiwgSWRlbnRpdHlTY29wZS5nZXRTeXN0ZW1TY29wZSgpKS50b1N0cmluZyh0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB2ZXJpZnkgSWRlbnRpdHkuZ2V0U2NvcGUoKSByZXR1cm5zIGlkZW50aXR5J3Mgc2NvcGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2NvcGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICBJZGVudGl0eSBpID0gbmV3IElkZW50aXR5U3R1YigidGVzdEdldFNjb3BlIik7CisgICAgICAgYXNzZXJ0TnVsbChpLmdldFNjb3BlKCkpOworICAgICAgIElkZW50aXR5U2NvcGUgcyA9IElkZW50aXR5U2NvcGUuZ2V0U3lzdGVtU2NvcGUoKTsKKworICAgICAgIElkZW50aXR5IGkyID0gbmV3IElkZW50aXR5U3R1YigidGVzdEdldFNjb3BlMiIsIHMpOworICAgICAgIGFzc2VydFNhbWUocywgaTIuZ2V0U2NvcGUoKSk7CisKKyAgICB9CisgICAgLyoqCisgICAgICoKKyAgICAgKiB2ZXJpZnkgSWRlbnRpdHkuc2V0UHVibGljS2V5KCkgdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24gaWYga2V5IGlzIGludmFsaWQKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRQdWJsaWNLZXkyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElkZW50aXR5IGkyID0gbmV3IElkZW50aXR5U3R1YigidGVzdFNldFB1YmxpY0tleTJfMiIsIElkZW50aXR5U2NvcGUuZ2V0U3lzdGVtU2NvcGUoKSk7CisgICAgICAgIG5ldyBQdWJsaWNLZXlTdHViKCJra2siLCAidGVzdFNldFB1YmxpY0tleTIiLCBuZXcgYnl0ZVtdezEsMiwzLDQsNX0pOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaTIuc2V0UHVibGljS2V5KG51bGwpOworICAgICAgICAgICAgLy9mYWlsKCJLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHNob3VsZCBiZSB0aHJvd24gLSBrZXkgaXMgbnVsbCIpOworICAgICAgICB9IGNhdGNoIChLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIG9rKSB7fQorICAgIH0KKworLy8KKy8vICBDb21tZW50ZWQgb3V0IHNpbmNlIHRoZXJlIHdpbGwgbm8gYmUgZml4IGZvciB0aGUgdGVzdCBmYWlsdXJlCisvLyAgICAvKioKKy8vICAgICAqCisvLyAgICAgKiB2ZXJpZnkgSWRlbnRpdHkuc2V0UHVibGljS2V5KCkgdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24gaWYga2V5IGlzIGFscmVhZHkgdXNlZAorLy8gICAgICoKKy8vICAgICAqLworLy8gICAgcHVibGljIHZvaWQgdGVzdFNldFB1YmxpY0tleTMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKy8vICAgICAgICBJZGVudGl0eSBpMSA9IG5ldyBJZGVudGl0eVN0dWIoInRlc3RTZXRQdWJsaWNLZXkzXzEiLCBJZGVudGl0eVNjb3BlLmdldFN5c3RlbVNjb3BlKCkpOworLy8gICAgICAgIElkZW50aXR5IGkyID0gbmV3IElkZW50aXR5U3R1YigidGVzdFNldFB1YmxpY0tleTNfMiIsIElkZW50aXR5U2NvcGUuZ2V0U3lzdGVtU2NvcGUoKSk7CisvLyAgICAgICAgUHVibGljS2V5IHBrID0gbmV3IFB1YmxpY0tleVN0dWIoImtrayIsICJmZmYiLCBuZXcgYnl0ZVtdezEsMiwzLDQsNX0pOworLy8gICAgICAgIGkxLnNldFB1YmxpY0tleShwayk7CisvLyAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgaTIuc2V0UHVibGljS2V5KHBrKTsKKy8vICAgICAgICAgICAgZmFpbCgiS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duIC0ga2V5IGFscmVhZHkgdXNlZCIpOworLy8gICAgICAgIH0gY2F0Y2ggKEtleU1hbmFnZW1lbnRFeGNlcHRpb24gb2spIHt9OworLy8gICAgfQorICAgIC8qKgorICAgICAqCisgICAgICogdmVyaWZ5IElkZW50aXR5LnNldFB1YmxpY0tleSgpICByZW1vdmVzIG9sZCBrZXkgYW5kIGFsbCBpZGVudGl0eSdzIGNlcnRpZmljYXRlcworICAgICAqCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNldFB1YmxpY0tleTQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSWRlbnRpdHkgaSA9IG5ldyBJZGVudGl0eVN0dWIoInRlc3RTZXRQdWJsaWNLZXk0Iik7CisgICAgICAgIFB1YmxpY0tleVN0dWIgcGsxID0gbmV3IFB1YmxpY0tleVN0dWIoImtrayIsICJJZGVudGl0eS50ZXN0U2V0UHVibGljS2V5NCIsIG51bGwpOworICAgICAgICBDZXJ0aWZpY2F0ZVN0dWIgYzEgPSBuZXcgQ2VydGlmaWNhdGVTdHViKCJmZmYiLCBudWxsLCBudWxsLCBwazEpOworICAgICAgICBDZXJ0aWZpY2F0ZVN0dWIgYzIgPSBuZXcgQ2VydGlmaWNhdGVTdHViKCJ6enoiLCBudWxsLCBudWxsLCBwazEpOworICAgICAgICBpLmFkZENlcnRpZmljYXRlKGMxKTsKKyAgICAgICAgaS5hZGRDZXJ0aWZpY2F0ZShjMik7CisgICAgICAgIGFzc2VydEVxdWFscygyLCBpLmNlcnRpZmljYXRlcygpLmxlbmd0aCk7CisgICAgICAgIGFzc2VydFNhbWUocGsxLCBpLmdldFB1YmxpY0tleSgpKTsKKworICAgICAgICBQdWJsaWNLZXlTdHViIHBrMiA9IG5ldyBQdWJsaWNLZXlTdHViKCJ6enoiLCAiSWRlbnRpdHkudGVzdFNldFB1YmxpY0tleTQiLCBudWxsKTsKKyAgICAgICAgaS5zZXRQdWJsaWNLZXkocGsyKTsKKyAgICAgICAgYXNzZXJ0U2FtZShwazIsIGkuZ2V0UHVibGljS2V5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaS5jZXJ0aWZpY2F0ZXMoKS5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHZlcmlmeSBJZGVudGl0eS5nZXRQdWJsaWNLZXkoKSByZXR1cm5zIHB1YmxpYyBrZXkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UHVibGljS2V5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIElkZW50aXR5IGkgPSBuZXcgSWRlbnRpdHlTdHViKCJ0ZXN0R2V0UHVibGljS2V5Iik7CisgICAgICAgIGFzc2VydE51bGwoaS5nZXRQdWJsaWNLZXkoKSk7CisgICAgICAgIFB1YmxpY0tleSBwayA9IG5ldyBQdWJsaWNLZXlTdHViKCJra2siLCAiSWRlbnRpdHkudGVzdEdldFB1YmxpY0tleSIsIG51bGwpOworICAgICAgICBpLnNldFB1YmxpY0tleShwayk7CisgICAgICAgIGFzc2VydFNhbWUocGssIGkuZ2V0UHVibGljS2V5KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbmZvKCkgeworCisgICAgICAgIElkZW50aXR5IGkgPSBuZXcgSWRlbnRpdHlTdHViKCJ0ZXN0R2V0SW5mbyIpOworICAgICAgICBpLnNldEluZm8oInNvbWUgaW5mbyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInNvbWUgaW5mbyIsIGkuZ2V0SW5mbygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TmFtZSgpIHsKKyAgICAgICAgSWRlbnRpdHkgaSA9IG5ldyBJZGVudGl0eVN0dWIoInRlc3RHZXROYW1lIik7CisgICAgICAgIGFzc2VydEVxdWFscyAoInRlc3RHZXROYW1lIiwgaS5nZXROYW1lKCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2phdmEvc2VjdXJpdHkvU2VjdXJlQ2xhc3NMb2FkZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvamF2YS9zZWN1cml0eS9TZWN1cmVDbGFzc0xvYWRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YTA3NjFiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2phdmEvc2VjdXJpdHkvU2VjdXJlQ2xhc3NMb2FkZXJUZXN0LmphdmEKQEAgLTAsMCArMSwyMzcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorICogQGF1dGhvciBBbGV4YW5kZXIgVi4gQXN0YXBjaHVrCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSB0ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uS25vd25GYWlsdXJlOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEubmV0LlVSTENsYXNzTG9hZGVyOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Db2RlU291cmNlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb25Db2xsZWN0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdGVjdGlvbkRvbWFpbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZUNsYXNzTG9hZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKKworLyoqCisgKiBVbml0IHRlc3QgZm9yIFNlY3VyZUNsYXNzTG9hZGVyLgorICoKKyAqLworCitwdWJsaWMgY2xhc3MgU2VjdXJlQ2xhc3NMb2FkZXJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIC8qKgorICAgICAqIEEgY2xhc3MgbmFtZSBmb3IgdGhlIGNsYXNzIHByZXNlbnRlZCBhcyB7QGxpbmsgI2tsYXNzRGF0YSBieXRlY29kZSBiZWxvd30KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcga2xhc3NOYW1lID0gIkhpV29ybGQiOworCisgICAgLyoqCisgICAgICogU29tZSBjbGFzcyBwcmVzZW50ZWQgYXMgYnl0ZWNvZGU8YnI+CisgICAgICogQ2xhc3Mgc3JjOjxicj4KKyAgICAgKiA8cD4KKyAgICAgKiA8Y29kZT5wdWJsaWMgY2xhc3MgSGlXb3JsZCB7CisgICAgICogICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpCisgICAgICogICAgICAgICB7U3lzdGVtLm91dC5wcmludGxuKCJIaSwgd29ybGQhIik7IH0KKyAgICAgKiAgICB9CisgICAgICogPC9jb2RlPgorICAgICAqLworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIGtsYXNzRGF0YSA9IHsgKGJ5dGUpIDB4Q0EsIChieXRlKSAweEZFLAorICAgICAgICAgICAgKGJ5dGUpIDB4QkEsIChieXRlKSAweEJFLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MkUsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgyMiwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDcsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4NTcsIChieXRlKSAweDZGLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzIsIChieXRlKSAweDZDLCAoYnl0ZSkgMHg2NCwgKGJ5dGUpIDB4MDcsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MTAsIChieXRlKSAweDZBLAorICAgICAgICAgICAgKGJ5dGUpIDB4NjEsIChieXRlKSAweDc2LCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4MkYsIChieXRlKSAweDZDLAorICAgICAgICAgICAgKGJ5dGUpIDB4NjEsIChieXRlKSAweDZFLCAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4MkYsIChieXRlKSAweDRGLAorICAgICAgICAgICAgKGJ5dGUpIDB4NjIsIChieXRlKSAweDZBLCAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4NjMsIChieXRlKSAweDc0LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDcsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDYsIChieXRlKSAweDNDLCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4NkUsIChieXRlKSAweDY5LAorICAgICAgICAgICAgKGJ5dGUpIDB4NzQsIChieXRlKSAweDNFLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAzLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjgsIChieXRlKSAweDI5LCAoYnl0ZSkgMHg1NiwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDQsIChieXRlKSAweDQzLCAoYnl0ZSkgMHg2RiwgKGJ5dGUpIDB4NjQsIChieXRlKSAweDY1LAorICAgICAgICAgICAgKGJ5dGUpIDB4MEMsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDA2LAorICAgICAgICAgICAgKGJ5dGUpIDB4MEEsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDA4LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwRiwgKGJ5dGUpIDB4NEMsIChieXRlKSAweDY5LAorICAgICAgICAgICAgKGJ5dGUpIDB4NkUsIChieXRlKSAweDY1LCAoYnl0ZSkgMHg0RSwgKGJ5dGUpIDB4NzUsIChieXRlKSAweDZELAorICAgICAgICAgICAgKGJ5dGUpIDB4NjIsIChieXRlKSAweDY1LCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4NTQsIChieXRlKSAweDYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4NjIsIChieXRlKSAweDZDLCAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTIsIChieXRlKSAweDRDLCAoYnl0ZSkgMHg2RiwgKGJ5dGUpIDB4NjMsIChieXRlKSAweDYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4NkMsIChieXRlKSAweDU2LCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4NzIsIChieXRlKSAweDY5LAorICAgICAgICAgICAgKGJ5dGUpIDB4NjEsIChieXRlKSAweDYyLCAoYnl0ZSkgMHg2QywgKGJ5dGUpIDB4NjUsIChieXRlKSAweDU0LAorICAgICAgICAgICAgKGJ5dGUpIDB4NjEsIChieXRlKSAweDYyLCAoYnl0ZSkgMHg2QywgKGJ5dGUpIDB4NjUsIChieXRlKSAweDAxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDA0LCAoYnl0ZSkgMHg3NCwgKGJ5dGUpIDB4NjgsIChieXRlKSAweDY5LAorICAgICAgICAgICAgKGJ5dGUpIDB4NzMsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDksIChieXRlKSAweDRDLAorICAgICAgICAgICAgKGJ5dGUpIDB4NDgsIChieXRlKSAweDY5LCAoYnl0ZSkgMHg1NywgKGJ5dGUpIDB4NkYsIChieXRlKSAweDcyLAorICAgICAgICAgICAgKGJ5dGUpIDB4NkMsIChieXRlKSAweDY0LCAoYnl0ZSkgMHgzQiwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDQsIChieXRlKSAweDZELCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4NjksIChieXRlKSAweDZFLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4MjgsIChieXRlKSAweDVCLAorICAgICAgICAgICAgKGJ5dGUpIDB4NEMsIChieXRlKSAweDZBLCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4NzYsIChieXRlKSAweDYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MkYsIChieXRlKSAweDZDLCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4NkUsIChieXRlKSAweDY3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MkYsIChieXRlKSAweDUzLCAoYnl0ZSkgMHg3NCwgKGJ5dGUpIDB4NzIsIChieXRlKSAweDY5LAorICAgICAgICAgICAgKGJ5dGUpIDB4NkUsIChieXRlKSAweDY3LCAoYnl0ZSkgMHgzQiwgKGJ5dGUpIDB4MjksIChieXRlKSAweDU2LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4NkEsIChieXRlKSAweDYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzYsIChieXRlKSAweDYxLCAoYnl0ZSkgMHgyRiwgKGJ5dGUpIDB4NkMsIChieXRlKSAweDYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4NkUsIChieXRlKSAweDY3LCAoYnl0ZSkgMHgyRiwgKGJ5dGUpIDB4NTMsIChieXRlKSAweDc5LAorICAgICAgICAgICAgKGJ5dGUpIDB4NzMsIChieXRlKSAweDc0LCAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4NkQsIChieXRlKSAweDA3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDEwLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAzLAorICAgICAgICAgICAgKGJ5dGUpIDB4NkYsIChieXRlKSAweDc1LCAoYnl0ZSkgMHg3NCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTUsIChieXRlKSAweDRDLCAoYnl0ZSkgMHg2QSwgKGJ5dGUpIDB4NjEsIChieXRlKSAweDc2LAorICAgICAgICAgICAgKGJ5dGUpIDB4NjEsIChieXRlKSAweDJGLCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4NkYsIChieXRlKSAweDJGLAorICAgICAgICAgICAgKGJ5dGUpIDB4NTAsIChieXRlKSAweDcyLCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4NkUsIChieXRlKSAweDc0LAorICAgICAgICAgICAgKGJ5dGUpIDB4NTMsIChieXRlKSAweDc0LCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4NjUsIChieXRlKSAweDYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4NkQsIChieXRlKSAweDNCLCAoYnl0ZSkgMHgwQywgKGJ5dGUpIDB4MDAsIChieXRlKSAweDEyLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDEzLCAoYnl0ZSkgMHgwOSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDExLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDE0LCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDBBLAorICAgICAgICAgICAgKGJ5dGUpIDB4NDgsIChieXRlKSAweDY5LCAoYnl0ZSkgMHgyQywgKGJ5dGUpIDB4MjAsIChieXRlKSAweDc3LAorICAgICAgICAgICAgKGJ5dGUpIDB4NkYsIChieXRlKSAweDcyLCAoYnl0ZSkgMHg2QywgKGJ5dGUpIDB4NjQsIChieXRlKSAweDIxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDgsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTMsIChieXRlKSAweDZBLCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4NzYsIChieXRlKSAweDYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MkYsIChieXRlKSAweDY5LCAoYnl0ZSkgMHg2RiwgKGJ5dGUpIDB4MkYsIChieXRlKSAweDUwLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzIsIChieXRlKSAweDY5LCAoYnl0ZSkgMHg2RSwgKGJ5dGUpIDB4NzQsIChieXRlKSAweDUzLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzQsIChieXRlKSAweDcyLCAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4NjEsIChieXRlKSAweDZELAorICAgICAgICAgICAgKGJ5dGUpIDB4MDcsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDcsIChieXRlKSAweDcwLCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4NjksIChieXRlKSAweDZFLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzQsIChieXRlKSAweDZDLCAoYnl0ZSkgMHg2RSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTUsIChieXRlKSAweDI4LCAoYnl0ZSkgMHg0QywgKGJ5dGUpIDB4NkEsIChieXRlKSAweDYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzYsIChieXRlKSAweDYxLCAoYnl0ZSkgMHgyRiwgKGJ5dGUpIDB4NkMsIChieXRlKSAweDYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4NkUsIChieXRlKSAweDY3LCAoYnl0ZSkgMHgyRiwgKGJ5dGUpIDB4NTMsIChieXRlKSAweDc0LAorICAgICAgICAgICAgKGJ5dGUpIDB4NzIsIChieXRlKSAweDY5LCAoYnl0ZSkgMHg2RSwgKGJ5dGUpIDB4NjcsIChieXRlKSAweDNCLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjksIChieXRlKSAweDU2LCAoYnl0ZSkgMHgwQywgKGJ5dGUpIDB4MDAsIChieXRlKSAweDFBLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDFCLCAoYnl0ZSkgMHgwQSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDE5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDFDLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDA0LAorICAgICAgICAgICAgKGJ5dGUpIDB4NjEsIChieXRlKSAweDcyLCAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4NzMsIChieXRlKSAweDAxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDEzLCAoYnl0ZSkgMHg1QiwgKGJ5dGUpIDB4NEMsIChieXRlKSAweDZBLAorICAgICAgICAgICAgKGJ5dGUpIDB4NjEsIChieXRlKSAweDc2LCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4MkYsIChieXRlKSAweDZDLAorICAgICAgICAgICAgKGJ5dGUpIDB4NjEsIChieXRlKSAweDZFLCAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4MkYsIChieXRlKSAweDUzLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzQsIChieXRlKSAweDcyLCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4NkUsIChieXRlKSAweDY3LAorICAgICAgICAgICAgKGJ5dGUpIDB4M0IsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MEEsIChieXRlKSAweDUzLAorICAgICAgICAgICAgKGJ5dGUpIDB4NkYsIChieXRlKSAweDc1LCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4NjMsIChieXRlKSAweDY1LAorICAgICAgICAgICAgKGJ5dGUpIDB4NDYsIChieXRlKSAweDY5LCAoYnl0ZSkgMHg2QywgKGJ5dGUpIDB4NjUsIChieXRlKSAweDAxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDBDLCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4NjksIChieXRlKSAweDU3LAorICAgICAgICAgICAgKGJ5dGUpIDB4NkYsIChieXRlKSAweDcyLCAoYnl0ZSkgMHg2QywgKGJ5dGUpIDB4NjQsIChieXRlKSAweDJFLAorICAgICAgICAgICAgKGJ5dGUpIDB4NkEsIChieXRlKSAweDYxLCAoYnl0ZSkgMHg3NiwgKGJ5dGUpIDB4NjEsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjEsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDA0LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDIsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDA1LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDA2LCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDcsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDJGLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4MkEsIChieXRlKSAweEI3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDA5LCAoYnl0ZSkgMHhCMSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MEEsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MTQsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MEIsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDBDLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDUsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwQywgKGJ5dGUpIDB4MDAsIChieXRlKSAweDBELAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDksIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MEUsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwRiwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDA3LCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MzcsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDksIChieXRlKSAweEIyLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDE1LCAoYnl0ZSkgMHgxMiwgKGJ5dGUpIDB4MTcsIChieXRlKSAweEI2LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDFELCAoYnl0ZSkgMHhCMSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MEEsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwQSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAyLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MTcsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDgsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDBCLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MEMsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDA5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDFFLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MUYsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDIwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjEsIH07CisKKyAgICBAS25vd25GYWlsdXJlKCJBbmRyb2lkIGRvZXNuJ3QgYWxsb3cgbnVsbCBwYXJlbnQuIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VjdXJlQ2xhc3NMb2FkZXJDbGFzc0xvYWRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBVUkxbXSB1cmxzID0gbmV3IFVSTFtdIHsgbmV3IFVSTCgiaHR0cDovL2xvY2FsaG9zdCIpIH07CisgICAgICAgIFVSTENsYXNzTG9hZGVyIHVjbCA9IFVSTENsYXNzTG9hZGVyLm5ld0luc3RhbmNlKHVybHMpOworICAgICAgICBuZXcgTXlDbGFzc0xvYWRlcih1Y2wpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgTXlDbGFzc0xvYWRlcihudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UGVybWlzc2lvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoImh0dHA6Ly9sb2NhbGhvc3QiKTsKKyAgICAgICAgQ29kZVNvdXJjZSBjcyA9IG5ldyBDb2RlU291cmNlKHVybCwgKENlcnRpZmljYXRlW10pIG51bGwpOworICAgICAgICBNeUNsYXNzTG9hZGVyIGxkciA9IG5ldyBNeUNsYXNzTG9hZGVyKCk7CisgICAgICAgIGxkci5nZXRQZXJtcyhudWxsKTsKKyAgICAgICAgbGRyLmdldFBlcm1zKGNzKTsKKyAgICB9CisKKy8vICAgIC8qKgorLy8gICAgICogVGVzdHMgZGVmaW5lQ2xhc3MoU3RyaW5nLCBieXRlW10sIGludCwgaW50LCBDb2RlU291cmNlKQorLy8gICAgICovCisvLyAgICBwdWJsaWMgdm9pZCBfdGVzdERlZmluZUNsYXNzU3RyaW5nYnl0ZUFycmF5aW50aW50Q29kZVNvdXJjZSgpIHsKKy8vICAgICAgICBNeUNsYXNzTG9hZGVyIGxkciA9IG5ldyBNeUNsYXNzTG9hZGVyKCk7CisvLyAgICAgICAgQ2xhc3Mga2xhc3MgPSBsZHIuZGVmaW5lKG51bGwsIGtsYXNzRGF0YSwgMCwga2xhc3NEYXRhLmxlbmd0aCwgbnVsbCk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKGtsYXNzLmdldE5hbWUoKSwga2xhc3NOYW1lKTsKKy8vICAgIH0KKy8vCisvLyAgICAvKioKKy8vICAgICAqIFRlc3RzIGRlZmluZUNsYXNzKFN0cmluZywgQnl0ZUJ1ZmZlciwgQ29kZVNvdXJjZSkKKy8vICAgICAqLworLy8gICAgcHVibGljIHZvaWQgX3Rlc3REZWZpbmVDbGFzc1N0cmluZ0J5dGVCdWZmZXJDb2RlU291cmNlKCkgeworLy8gICAgICAgIE15Q2xhc3NMb2FkZXIgbGRyID0gbmV3IE15Q2xhc3NMb2FkZXIoKTsKKy8vICAgICAgICBCeXRlQnVmZmVyIGJidWYgPSBCeXRlQnVmZmVyLndyYXAoa2xhc3NEYXRhKTsKKy8vICAgICAgICBDbGFzcyBrbGFzcyA9IGxkci5kZWZpbmUobnVsbCwgYmJ1ZiwgbnVsbCk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKGtsYXNzLmdldE5hbWUoKSwga2xhc3NOYW1lKTsKKy8vICAgIH0KKworICAgIGNsYXNzIE15Q2xhc3NMb2FkZXIgZXh0ZW5kcyBTZWN1cmVDbGFzc0xvYWRlciB7CisKKyAgICAgICAgcHVibGljIE15Q2xhc3NMb2FkZXIoKSB7CisgICAgICAgICAgICBzdXBlcigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE15Q2xhc3NMb2FkZXIoQ2xhc3NMb2FkZXIgcGFyZW50KSB7CisgICAgICAgICAgICBzdXBlcihwYXJlbnQpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFBlcm1pc3Npb25Db2xsZWN0aW9uIGdldFBlcm1zKENvZGVTb3VyY2UgY29kZXNvdXJjZSkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldFBlcm1pc3Npb25zKGNvZGVzb3VyY2UpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIENsYXNzIGRlZmluZShTdHJpbmcgbmFtZSwgYnl0ZVtdIGJ5dGVzKSB7CisgICAgICAgICAgICByZXR1cm4gZGVmaW5lQ2xhc3MobmFtZSwgYnl0ZXMsIDAsIGJ5dGVzLmxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgKFByb3RlY3Rpb25Eb21haW4pIG51bGwpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIENsYXNzIGRlZmluZShTdHJpbmcgbmFtZSwgQnl0ZUJ1ZmZlciBiLCBDb2RlU291cmNlIGNzKSB7CisgICAgICAgICAgICByZXR1cm4gZGVmaW5lQ2xhc3MobmFtZSwgYiwgY3MpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIENsYXNzIGRlZmluZShTdHJpbmcgbmFtZSwgYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4sCisgICAgICAgICAgICAgICAgQ29kZVNvdXJjZSBjcykgeworICAgICAgICAgICAgcmV0dXJuIGRlZmluZUNsYXNzKG5hbWUsIGIsIG9mZiwgbGVuLCBjcyk7CisgICAgICAgIH0KKworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9qYXZhL3NlY3VyaXR5L1NlY3VyZVJhbmRvbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9qYXZhL3NlY3VyaXR5L1NlY3VyZVJhbmRvbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNDQyODBmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2phdmEvc2VjdXJpdHkvU2VjdXJlUmFuZG9tVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjk1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBCb3JpcyBWLiBLdXpuZXRzb3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5qYXZhLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlJhbmRvbUltcGw7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlNlY3VyZVJhbmRvbTwvY29kZT4gY29uc3RydWN0b3IgYW5kIG1ldGhvZHMKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBTZWN1cmVSYW5kb21UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogU1JQcm92aWRlcgorICAgICAqLworICAgIFByb3ZpZGVyIHA7CisKKyAgICAvKgorICAgICAqIEBzZWUgVGVzdENhc2Ujc2V0VXAoKQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHAgPSBuZXcgU1JQcm92aWRlcigpOworICAgICAgICBTZWN1cml0eS5pbnNlcnRQcm92aWRlckF0KHAsIDEpOworICAgIH0KKworICAgIC8qCisgICAgICogQHNlZSBUZXN0Q2FzZSN0ZWFyRG93bigpCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICAgICAgU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIocC5nZXROYW1lKCkpOworICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3ROZXh0KCkgeworICAgICAgICBNeVNlY3VyZVJhbmRvbSBzciA9IG5ldyBNeVNlY3VyZVJhbmRvbSgpOworICAgICAgICBpZiAoc3IubmV4dEVsZW1lbnQoMSkgIT0gMSB8fCBzci5uZXh0RWxlbWVudCgyKSAhPSAzIHx8IHNyLm5leHRFbGVtZW50KDMpICE9IDcpIHsKKyAgICAgICAgICAgIGZhaWwoIm5leHQgZmFpbGVkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIHZvaWQgc2V0U2VlZChsb25nKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RTZXRTZWVkbG9uZygpIHsKKyAgICAgICAgU2VjdXJlUmFuZG9tIHNyID0gbmV3IFNlY3VyZVJhbmRvbSgpOworICAgICAgICBzci5zZXRTZWVkKDEyMzQ1KTsKKyAgICAgICAgaWYgKCFSYW5kb21JbXBsLnJ1bkVuZ2luZVNldFNlZWQpIHsKKyAgICAgICAgICAgIGZhaWwoInNldFNlZWQgZmFpbGVkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0TmV4dEJ5dGVzKCkgeworICAgICAgICBieXRlW10gYiA9IG5ldyBieXRlWzVdOworICAgICAgICBTZWN1cmVSYW5kb20gc3IgPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIHNyLm5leHRCeXRlcyhiKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBiLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYltpXSAhPSAoYnl0ZSkoaSArIDB4RjEpKSB7CisgICAgICAgICAgICAgICAgZmFpbCgibmV4dEJ5dGVzIGZhaWxlZCIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNyLm5leHRCeXRlcyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIGV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3Igdm9pZCBTZWN1cmVSYW5kb20oKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RTZWN1cmVSYW5kb20oKSB7CisgICAgICAgIFNlY3VyZVJhbmRvbSBzciA9IG5ldyBTZWN1cmVSYW5kb20oKTsKKyAgICAgICAgaWYgKCFzci5nZXRBbGdvcml0aG0oKS5lcXVhbHMoInNvbWVSYW5kb20iKSAgfHwKKyAgICAgICAgICAgICAgICBzci5nZXRQcm92aWRlcigpIT0gcCkgeworICAgICAgICAgICAgZmFpbCgiaW5jb3JyZWN0IFNlY3VyZVJhbmRvbSBpbXBsZW1lbnRhdGlvbiIgKyBwLmdldE5hbWUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIHZvaWQgU2VjdXJlUmFuZG9tKGJ5dGVbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0U2VjdXJlUmFuZG9tYnl0ZUFycmF5KCkgeworICAgICAgICBieXRlW10gYiA9IHsxLDIsM307CisgICAgICAgIG5ldyBTZWN1cmVSYW5kb20oYik7CisKKyAgICAgICAgaWYgKCFSYW5kb21JbXBsLnJ1bkVuZ2luZVNldFNlZWQpIHsKKyAgICAgICAgICAgIGZhaWwoIk5vIHNldFNlZWQiKTsKKyAgICAgICAgfQorCisKKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIFNlY3VyZVJhbmRvbSBnZXRJbnN0YW5jZShTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEluc3RhbmNlU3RyaW5nKCkgeworICAgICAgICBTZWN1cmVSYW5kb20gc3IgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3IgPSBTZWN1cmVSYW5kb20uZ2V0SW5zdGFuY2UoInNvbWVSYW5kb20iKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3IuZ2V0UHJvdmlkZXIoKSAhPSBwIHx8ICEic29tZVJhbmRvbSIuZXF1YWxzKHNyLmdldEFsZ29yaXRobSgpKSkgeworICAgICAgICAgICAgZmFpbCgiZ2V0SW5zdGFuY2UgZmFpbGVkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIENsYXNzIHVuZGVyIHRlc3QgZm9yIFNlY3VyZVJhbmRvbSBnZXRJbnN0YW5jZShTdHJpbmcsIFN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0SW5zdGFuY2VTdHJpbmdTdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2VjdXJlUmFuZG9tIHNyID0gU2VjdXJlUmFuZG9tLmdldEluc3RhbmNlKCJzb21lUmFuZG9tIiwgIlNSUHJvdmlkZXIiKTsKKyAgICAgICAgaWYgKHNyLmdldFByb3ZpZGVyKCkgIT0gcCB8fCAhInNvbWVSYW5kb20iLmVxdWFscyhzci5nZXRBbGdvcml0aG0oKSkpIHsKKyAgICAgICAgICAgIGZhaWwoImdldEluc3RhbmNlIGZhaWxlZCIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNlY3VyZVJhbmRvbSByID0gU2VjdXJlUmFuZG9tLmdldEluc3RhbmNlKCJhbm90aGVyUmFuZG9tIiwgIlNSUHJvdmlkZXIiKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZDogIiArIGUpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZDogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2VjdXJlUmFuZG9tIHIgPSBTZWN1cmVSYW5kb20uZ2V0SW5zdGFuY2UoInNvbWVSYW5kb20iLCAiVW5rbm93blByb3ZpZGVyIik7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZDogIiArIGUpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZDogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2VjdXJlUmFuZG9tIHIgPSBTZWN1cmVSYW5kb20uZ2V0SW5zdGFuY2UoInNvbWVSYW5kb20iLCAoU3RyaW5nKW51bGwpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQ6ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQ6ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQ6ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTZWN1cmVSYW5kb20gciA9IFNlY3VyZVJhbmRvbS5nZXRJbnN0YW5jZShudWxsLCAiU1JQcm92aWRlciIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZDogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZDogIiArIGUpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZDogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDbGFzcyB1bmRlciB0ZXN0IGZvciBTZWN1cmVSYW5kb20gZ2V0SW5zdGFuY2UoU3RyaW5nLCBQcm92aWRlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0SW5zdGFuY2VTdHJpbmdQcm92aWRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQcm92aWRlciBwID0gbmV3IFNSUHJvdmlkZXIoKTsKKyAgICAgICAgU2VjdXJlUmFuZG9tIHNyID0gU2VjdXJlUmFuZG9tLmdldEluc3RhbmNlKCJzb21lUmFuZG9tIiwgcCk7CisgICAgICAgIGlmIChzci5nZXRQcm92aWRlcigpICE9IHAgfHwgISJzb21lUmFuZG9tIi5lcXVhbHMoc3IuZ2V0QWxnb3JpdGhtKCkpKSB7CisgICAgICAgICAgICBmYWlsKCJnZXRJbnN0YW5jZSBmYWlsZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTZWN1cmVSYW5kb20gciA9IFNlY3VyZVJhbmRvbS5nZXRJbnN0YW5jZSgidW5rbm93blJhbmRvbSIsIHApOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZDogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkOiAiICsgZSk7CisgICAgICAgIH0KKworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTZWN1cmVSYW5kb20gciA9IFNlY3VyZVJhbmRvbS5nZXRJbnN0YW5jZShudWxsLCBwKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2VjdXJlUmFuZG9tIHIgPSBTZWN1cmVSYW5kb20uZ2V0SW5zdGFuY2UoImFueVJhbmRvbSIsIChQcm92aWRlciludWxsKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZDogIiArIGUpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZDogIiArIGUpOworICAgICAgICB9CisKKworICAgIH0KKworICAgIC8qCisgICAgICogQ2xhc3MgdW5kZXIgdGVzdCBmb3Igdm9pZCBzZXRTZWVkKGJ5dGVbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0U2V0U2VlZGJ5dGVBcnJheSgpIHsKKyAgICAgICAgYnl0ZVtdIGIgPSB7MSwyLDN9OworICAgICAgICBTZWN1cmVSYW5kb20gc3IgPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIHNyLnNldFNlZWQoYik7CisgICAgICAgIGlmICghUmFuZG9tSW1wbC5ydW5FbmdpbmVTZXRTZWVkKSB7CisgICAgICAgICAgICBmYWlsKCJzZXRTZWVkIGZhaWxlZCIpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0U2VlZCgpIHsKKyAgICAgICAgYnl0ZVtdIGIgPSBTZWN1cmVSYW5kb20uZ2V0U2VlZCg0KTsKKyAgICAgICAgaWYoIGIubGVuZ3RoICE9IDQpIHsKKyAgICAgICAgICAgIGZhaWwoImdldFNlZWQgZmFpbGVkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2VuZXJhdGVTZWVkKCkgeworICAgICAgICBTZWN1cmVSYW5kb20gc3IgPSBuZXcgU2VjdXJlUmFuZG9tKCk7CisgICAgICAgIGJ5dGVbXSBiID0gc3IuZ2VuZXJhdGVTZWVkKDQpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGIubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChiW2ldICE9IChieXRlKWkpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJnZW5lcmF0ZVNlZWQgZmFpbGVkIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKworCisgICAgcHVibGljIGNsYXNzIFNSUHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlciB7CisgICAgICAgIHB1YmxpYyBTUlByb3ZpZGVyKCkgeworICAgICAgICAgICAgc3VwZXIoIlNSUHJvdmlkZXIiLCAxLjAsICJTUlByb3ZpZGVyIGZvciB0ZXN0aW5nIik7CisgICAgICAgICAgICBwdXQoIlNlY3VyZVJhbmRvbS5zb21lUmFuZG9tIiwKKyAgICAgICAgICAgICAgICAgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlJhbmRvbUltcGwiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIE15U2VjdXJlUmFuZG9tIGV4dGVuZHMgU2VjdXJlUmFuZG9tIHsKKyAgICAgICAgcHVibGljIE15U2VjdXJlUmFuZG9tKCl7CisgICAgICAgICAgICBzdXBlcigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBuZXh0RWxlbWVudChpbnQgbnVtQml0cykgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLm5leHQobnVtQml0cyk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvamF2YS9zcWwvRGF0YWJhc2VNZXRhRGF0YU5vdFN1cHBvcnRlZFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9qYXZhL3NxbC9EYXRhYmFzZU1ldGFEYXRhTm90U3VwcG9ydGVkVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNmMTZhNjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvamF2YS9zcWwvRGF0YWJhc2VNZXRhRGF0YU5vdFN1cHBvcnRlZFRlc3QuamF2YQpAQCAtMCwwICsxLDExMTkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuamF2YS5zcWw7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5Lbm93bkZhaWx1cmU7CisKK2ltcG9ydCBqdW5pdC5leHRlbnNpb25zLlRlc3RTZXR1cDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IHRlc3RzLnN1cHBvcnQuRGF0YWJhc2VDcmVhdG9yOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9TUUw7CisKK2ltcG9ydCBqYXZhLnNxbC5Db25uZWN0aW9uOworaW1wb3J0IGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGE7CitpbXBvcnQgamF2YS5zcWwuUmVzdWx0U2V0OworaW1wb3J0IGphdmEuc3FsLlJlc3VsdFNldE1ldGFEYXRhOworaW1wb3J0IGphdmEuc3FsLlNRTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5TdGF0ZW1lbnQ7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CisKK3B1YmxpYyBjbGFzcyBEYXRhYmFzZU1ldGFEYXRhTm90U3VwcG9ydGVkVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBWSUVXX05BTUUgPSAibXlWaWV3IjsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBDUkVBVEVfVklFV19RVUVSWSA9ICJDUkVBVEUgVklFVyAiICsgVklFV19OQU1FCisgICAgICAgICAgICArICIgQVMgU0VMRUNUICogRlJPTSAiICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIERST1BfVklFV19RVUVSWSA9ICJEUk9QIFZJRVcgIiArIFZJRVdfTkFNRTsKKworICAgIHByb3RlY3RlZCBzdGF0aWMgQ29ubmVjdGlvbiBjb25uOworCisgICAgcHJvdGVjdGVkIHN0YXRpYyBEYXRhYmFzZU1ldGFEYXRhIG1ldGE7CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIFN0YXRlbWVudCBzdGF0ZW1lbnQ7CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIFN0YXRlbWVudCBzdGF0ZW1lbnRGb3J3YXJkOworCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGlkID0gMTsKKworICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIFN1cHBvcnRfU1FMLmxvYWREcml2ZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4gPSBTdXBwb3J0X1NRTC5nZXRDb25uZWN0aW9uKCk7CisgICAgICAgICAgICBtZXRhID0gY29ubi5nZXRNZXRhRGF0YSgpOworICAgICAgICAgICAgc3RhdGVtZW50ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIGNyZWF0ZVRlc3RUYWJsZXMoKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXJyb3IgaW4gdGVzdCBzZXR1cDogIitlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29ubiA9IFN1cHBvcnRfU1FMLmdldENvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgIG1ldGEgPSBjb25uLmdldE1ldGFEYXRhKCk7CisgICAgICAgICAgICBzdGF0ZW1lbnQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgZGVsZXRlVGVzdFRhYmxlcygpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFcnJvciBpbiB0ZWFyZG93bjogIitlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNvbm4uY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY3JlYXRlVGVzdFRhYmxlcygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFJlc3VsdFNldCB1c2VyVGFiID0gbWV0YS5nZXRUYWJsZXMobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICB3aGlsZSAodXNlclRhYi5uZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgdGFibGVOYW1lID0gdXNlclRhYi5nZXRTdHJpbmcoIlRBQkxFX05BTUUiKTsKKyAgICAgICAgICAgICAgICBpZiAodGFibGVOYW1lLmVxdWFscyhEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEpKSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFMSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0YWJsZU5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUzKSkgeworICAgICAgICAgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRTMpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGFibGVOYW1lLmVxdWFscyhWSUVXX05BTUUpKSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERST1BfVklFV19RVUVSWSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgdXNlclRhYi5jbG9zZSgpOworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkNSRUFURV9UQUJMRTMpOworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkNSRUFURV9UQUJMRTEpOworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoQ1JFQVRFX1ZJRVdfUVVFUlkpOworICAgICAgICAgICAgbWV0YSA9IGNvbm4uZ2V0TWV0YURhdGEoKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU1FMRXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGRlbGV0ZVRlc3RUYWJsZXMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRTEpOworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEUzKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERST1BfVklFV19RVUVSWSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNRTEV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoISBjb25uLmlzQ2xvc2VkKCkpIHsKKyAgICAgICAgICAgICAgICBjb25uLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2FsbFByb2NlZHVyZXNBcmVDYWxsYWJsZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hbGxQcm9jZWR1cmVzQXJlQ2FsbGFibGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5hbGxQcm9jZWR1cmVzQXJlQ2FsbGFibGUoKSk7CisgICAgfQorCisgICAgQEtub3duRmFpbHVyZSgiTm90IHN1cHBvcnRlZCBvcHMgYXBwbGllZCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9hbGxUYWJsZXNBcmVTZWxlY3RhYmxlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIGdyYW50IFNFTEVDVCBwcml2aWxlZ2VzCisKKyAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gIkdSQU5UIENSRUFURSwgU0VMRUNUIE9OICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgVE8gIiArIFN1cHBvcnRfU1FMLnNxbFVzZXI7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKHF1ZXJ5KTsKKyAgICAgICAgQ29ubmVjdGlvbiB1c2VyQ29ubiA9IFN1cHBvcnRfU1FMLmdldENvbm5lY3Rpb24oU3VwcG9ydF9TUUwuc3FsVXJsLAorICAgICAgICAgICAgICAgIFN1cHBvcnRfU1FMLnNxbFVzZXIsIFN1cHBvcnRfU1FMLnNxbFVzZXIpOworICAgICAgICBEYXRhYmFzZU1ldGFEYXRhIHVzZXJNZXRhID0gdXNlckNvbm4uZ2V0TWV0YURhdGEoKTsKKyAgICAgICAgUmVzdWx0U2V0IHVzZXJUYWIgPSB1c2VyTWV0YS5nZXRUYWJsZXMobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGFibGVzIGFyZSBub3Qgb2J0YWluZWQiLCB1c2VyVGFiLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IG5hbWUgb2Ygb2J0YWluZWQgdGFibGUiLAorICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMS50b0xvd2VyQ2FzZSgpLCB1c2VyVGFiLmdldFN0cmluZygKKyAgICAgICAgICAgICAgICAgICAgICAgICJUQUJMRV9OQU1FIikudG9Mb3dlckNhc2UoKSk7CisgICAgICAgIGFzc2VydFRydWUoIk5vdCBhbGwgb2Ygb2J0YWluZWQgdGFibGVzIGFyZSBzZWxlY3RhYmxlIiwgdXNlck1ldGEKKyAgICAgICAgICAgICAgICAuYWxsVGFibGVzQXJlU2VsZWN0YWJsZSgpKTsKKworICAgICAgICB1c2VyVGFiLmNsb3NlKCk7CisgICAgICAgIC8vIHJldm9rZSBTRUxFQ1QgcHJpdmlsZWdlcworICAgICAgICBxdWVyeSA9ICJSRVZPS0UgU0VMRUNUIE9OICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEgKyAiIEZST00gIgorICAgICAgICAgICAgICAgICsgU3VwcG9ydF9TUUwuc3FsVXNlcjsKKyAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUocXVlcnkpOworCisgICAgICAgIHVzZXJUYWIgPSB1c2VyTWV0YS5nZXRUYWJsZXMobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGFibGVzIGFyZSBub3Qgb2J0YWluZWQiLCB1c2VyVGFiLm5leHQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IG5hbWUgb2Ygb2J0YWluZWQgdGFibGUiLAorICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMS50b0xvd2VyQ2FzZSgpLCB1c2VyVGFiLmdldFN0cmluZygKKyAgICAgICAgICAgICAgICAgICAgICAgICJUQUJMRV9OQU1FIikudG9Mb3dlckNhc2UoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJObyBTRUxFQ1QgcHJpdmlsZWdlcyIsIHVzZXJNZXRhLmFsbFRhYmxlc0FyZVNlbGVjdGFibGUoKSk7CisKKyAgICAgICAgdXNlclRhYi5jbG9zZSgpOworICAgICAgICAvLyByZXZva2UgQ1JFQVRFIHByaXZpbGVnZXMKKyAgICAgICAgcXVlcnkgPSAiUkVWT0tFIENSRUFURSBPTiAiICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxICsgIiBGUk9NICIKKyAgICAgICAgICAgICAgICArIFN1cHBvcnRfU1FMLnNxbFVzZXI7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKHF1ZXJ5KTsKKyAgICAgICAgdXNlckNvbm4uY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2RhdGFEZWZpbml0aW9uQ2F1c2VzVHJhbnNhY3Rpb25Db21taXQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZGF0YURlZmluaXRpb25DYXVzZXNUcmFuc2FjdGlvbkNvbW1pdCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAvLyBOT1RfRkVBU0lCTEU6IFNRTElURSBkb2VzIG5vdCBpbXBsZW1lbnQgdGhpcyBmdW5jdGlvbmFsaXR5CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNkYXRhRGVmaW5pdGlvbklnbm9yZWRJblRyYW5zYWN0aW9ucygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9kYXRhRGVmaW5pdGlvbklnbm9yZWRJblRyYW5zYWN0aW9ucygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLmRhdGFEZWZpbml0aW9uSWdub3JlZEluVHJhbnNhY3Rpb25zKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZGVsZXRlc0FyZURldGVjdGVkKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2RlbGV0ZXNBcmVEZXRlY3RlZEkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5kZWxldGVzQXJlRGV0ZWN0ZWQoMCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZG9lc01heFJvd1NpemVJbmNsdWRlQmxvYnMoKQorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIm5vdCBzdXBwb3J0ZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZG9lc01heFJvd1NpemVJbmNsdWRlQmxvYnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5kb2VzTWF4Um93U2l6ZUluY2x1ZGVCbG9icygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhICNnZXRBdHRyaWJ1dGVzKGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRBdHRyaWJ1dGVzTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcoKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDYXRhbG9ncygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBSZXN1bHRTZXQgcnMgPSBtZXRhLmdldENhdGFsb2dzKCk7CisgICAgICAgIC8vIE5PVF9GRUFTSUJMRSBnZXRDYXRhbG9nIGlzIG5vdCBzdXBwb3J0ZWQKKy8vICAgICAgICB3aGlsZSAocnMubmV4dCgpKSB7CisgICAgICAgICAgICAvL2lmIChycy5nZXRTdHJpbmcoIlRBQkxFX0NBVCIpLmVxdWFsc0lnbm9yZUNhc2UoY29ubi5nZXRDYXRhbG9nKCkpKSB7CisgICAgICAgICAgICAvLyAgICBycy5jbG9zZSgpOworICAgICAgICAgICAgLy8gICAgcmV0dXJuOworICAgICAgICAgICAgLy99CisvLyAgICAgICAgfQorICAgICAgICBycy5jbG9zZSgpOworLy8gICAgICAgIGZhaWwoIkluY29ycmVjdCBhIHNldCBvZiBjYXRhbG9ncyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0Q2F0YWxvZ1NlcGFyYXRvcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDYXRhbG9nU2VwYXJhdG9yKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBjYXRhbG9nIHNlcGFyYXRvciIsICIiLmVxdWFscyhtZXRhCisgICAgICAgICAgICAgICAgLmdldENhdGFsb2dTZXBhcmF0b3IoKS50cmltKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2dldENhdGFsb2dUZXJtKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldENhdGFsb2dUZXJtKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBjYXRhbG9nIHRlcm0iLCAiIi5lcXVhbHMobWV0YQorICAgICAgICAgICAgICAgIC5nZXRDYXRhbG9nU2VwYXJhdG9yKCkudHJpbSgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXRFeHRyYU5hbWVDaGFyYWN0ZXJzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEV4dHJhTmFtZUNoYXJhY3RlcnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiSW5jb3JyZWN0IGV4dHJhIG5hbWUgY2hhcmFjdGVycyIsIG1ldGEKKyAgICAgICAgICAgICAgICAuZ2V0RXh0cmFOYW1lQ2hhcmFjdGVycygpKTsKKworICAgIH0KKworICAgIEBLbm93bkZhaWx1cmUoIm5vdCBzdXBwb3J0ZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5kZXhJbmZvTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nWlooKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gdW5pcXVlID0gZmFsc2U7CisgICAgICAgIFJlc3VsdFNldCBycyA9IG1ldGEuZ2V0SW5kZXhJbmZvKGNvbm4uZ2V0Q2F0YWxvZygpLCBudWxsLAorICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSwgdW5pcXVlLCB0cnVlKTsKKyAgICAgICAgUmVzdWx0U2V0TWV0YURhdGEgcnNtZCA9IHJzLmdldE1ldGFEYXRhKCk7CisgICAgICAgIGFzc2VydFRydWUoIlJvd3MgZG8gbm90IG9idGFpbmVkIiwgcnMubmV4dCgpKTsKKyAgICAgICAgaW50IGNvbCA9IHJzbWQuZ2V0Q29sdW1uQ291bnQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbnVtYmVyIG9mIGNvbHVtbnMiLCAxMywgY29sKTsKKyAgICAgICAgU3RyaW5nW10gY29sdW1uTmFtZXMgPSB7ICJUQUJMRV9DQVQiLCAiVEFCTEVfU0NIRU0iLCAiVEFCTEVfTkFNRSIsCisgICAgICAgICAgICAgICAgIk5PTl9VTklRVUUiLCAiSU5ERVhfUVVBTElGSUVSIiwgIklOREVYX05BTUUiLCAiVFlQRSIsCisgICAgICAgICAgICAgICAgIk9SRElOQUxfUE9TSVRJT04iLCAiQ09MVU1OX05BTUUiLCAiQVNDX09SX0RFU0MiLAorICAgICAgICAgICAgICAgICJDQVJESU5BTElUWSIsICJQQUdFUyIsICJGSUxURVJfQ09ORElUSU9OIiB9OworICAgICAgICBmb3IgKGludCBjID0gMTsgYyA8PSBjb2w7ICsrYykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgY29sdW1uIG5hbWUiLCBjb2x1bW5OYW1lc1tjIC0gMV0sIHJzbWQKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbHVtbk5hbWUoYykpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdGFibGUgY2F0YWxvZyIsIGNvbm4uZ2V0Q2F0YWxvZygpLCBycworICAgICAgICAgICAgICAgIC5nZXRTdHJpbmcoIlRBQkxFX0NBVCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdGFibGUgc2NoZW1hIiwgbnVsbCwgcnMKKyAgICAgICAgICAgICAgICAuZ2V0U3RyaW5nKCJUQUJMRV9TQ0hFTSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdGFibGUgbmFtZSIsIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSwgcnMKKyAgICAgICAgICAgICAgICAuZ2V0U3RyaW5nKCJUQUJMRV9OQU1FIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBzdGF0ZSBvZiB1bmlxdWVzcyIsIHVuaXF1ZSwgcnMKKyAgICAgICAgICAgICAgICAuZ2V0Qm9vbGVhbigiTk9OX1VOSVFVRSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgaW5kZXggY2F0YWxvZyIsICIiLCBycworICAgICAgICAgICAgICAgIC5nZXRTdHJpbmcoIklOREVYX1FVQUxJRklFUiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgaW5kZXggbmFtZSIsICJwcmltYXJ5IiwgcnMuZ2V0U3RyaW5nKAorICAgICAgICAgICAgICAgICJJTkRFWF9OQU1FIikudG9Mb3dlckNhc2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGluZGV4IHR5cGUiLCBEYXRhYmFzZU1ldGFEYXRhLnRhYmxlSW5kZXhPdGhlciwKKyAgICAgICAgICAgICAgICBycy5nZXRTaG9ydCgiVFlQRSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgY29sdW1uIHNlcXVlbmNlIG51bWJlciB3aXRoaW4gaW5kZXgiLCAxLCBycworICAgICAgICAgICAgICAgIC5nZXRTaG9ydCgiT1JESU5BTF9QT1NJVElPTiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgY29sdW1uIG5hbWUiLCAiaWQiLCBycy5nZXRTdHJpbmcoIkNPTFVNTl9OQU1FIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBjb2x1bW4gc29ydCBzZXF1ZW5jZSIsICJhIiwgcnMuZ2V0U3RyaW5nKAorICAgICAgICAgICAgICAgICJBU0NfT1JfREVTQyIpLnRvTG93ZXJDYXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBjYXJkaW5hbGl0eSIsIDEsIHJzLmdldEludCgiQ0FSRElOQUxJVFkiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHZhbHVlIG9mIHBhZ2VzIiwgMCwgcnMuZ2V0SW50KCJQQUdFUyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgZmlsdGVyIGNvbmRpdGlvbiIsIG51bGwsIHJzCisgICAgICAgICAgICAgICAgLmdldFN0cmluZygiRklMVEVSX0NPTkRJVElPTiIpKTsKKyAgICAgICAgcnMuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAS25vd25GYWlsdXJlKCJub3Qgc3VwcG9ydGVkLiBQcml2aWxlZ2VzIGFyZSBub3Qgc3VwcG9ydGVkLiIpCisgICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Q29sdW1uUHJpdmlsZWdlc0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nKCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBSZXN1bHRTZXQgcnMgPSBtZXRhLmdldENvbHVtblByaXZpbGVnZXMoY29ubi5nZXRDYXRhbG9nKCksIG51bGwsCisgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxLCAiaWQiKTsKKyAgICAgICAgUmVzdWx0U2V0TWV0YURhdGEgcnNtZCA9IHJzLmdldE1ldGFEYXRhKCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJSb3dzIGFyZSBvYnRhaW5lZCIsIHJzLm5leHQoKSk7CisgICAgICAgIHJzLmNsb3NlKCk7CisKKyAgICAgICAgU3RyaW5nIHF1ZXJ5ID0gIkdSQU5UIFJFRkVSRU5DRVMoaWQpIE9OICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgVE8gIiArIFN1cHBvcnRfU1FMLnNxbExvZ2luOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShxdWVyeSk7CisKKyAgICAgICAgcnMgPSBtZXRhLmdldENvbHVtblByaXZpbGVnZXMoY29ubi5nZXRDYXRhbG9nKCksIG51bGwsCisgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxLCAiaWQiKTsKKyAgICAgICAgcnNtZCA9IHJzLmdldE1ldGFEYXRhKCk7CisgICAgICAgIGFzc2VydFRydWUoIlJvd3MgZG8gbm90IG9idGFpbmVkIiwgcnMubmV4dCgpKTsKKyAgICAgICAgaW50IGNvbCA9IHJzbWQuZ2V0Q29sdW1uQ291bnQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbnVtYmVyIG9mIGNvbHVtbnMiLCA4LCBjb2wpOworICAgICAgICBTdHJpbmdbXSBjb2x1bW5OYW1lcyA9IHsgIlRBQkxFX0NBVCIsICJUQUJMRV9TQ0hFTSIsICJUQUJMRV9OQU1FIiwKKyAgICAgICAgICAgICAgICAiQ09MVU1OX05BTUUiLCAiR1JBTlRPUiIsICJHUkFOVEVFIiwgIlBSSVZJTEVHRSIsCisgICAgICAgICAgICAgICAgIklTX0dSQU5UQUJMRSIgfTsKKyAgICAgICAgZm9yIChpbnQgYyA9IDE7IGMgPD0gY29sOyArK2MpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGNvbHVtbiBuYW1lIiwgY29sdW1uTmFtZXNbYyAtIDFdLCByc21kCisgICAgICAgICAgICAgICAgICAgIC5nZXRDb2x1bW5OYW1lKGMpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB0YWJsZSBjYXRhbG9ndWUiLCBjb25uLmdldENhdGFsb2coKSwgcnMKKyAgICAgICAgICAgICAgICAuZ2V0U3RyaW5nKCJUQUJMRV9DQVQiKS50b0xvd2VyQ2FzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdGFibGUgc2NoZW1hIiwgbnVsbCwgcnMKKyAgICAgICAgICAgICAgICAuZ2V0U3RyaW5nKCJUQUJMRV9TQ0hFTSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdGFibGUgbmFtZSIsIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSwgcnMKKyAgICAgICAgICAgICAgICAuZ2V0U3RyaW5nKCJUQUJMRV9OQU1FIikudG9Mb3dlckNhc2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGNvbHVtbiBuYW1lIiwgImlkIiwgcnMuZ2V0U3RyaW5nKCJDT0xVTU5fTkFNRSIpCisgICAgICAgICAgICAgICAgLnRvTG93ZXJDYXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBncmFudG9yIiwgU3VwcG9ydF9TUUwuc3FsTG9naW4gKyAiQCIKKyAgICAgICAgICAgICAgICArIFN1cHBvcnRfU1FMLnNxbEhvc3QsIHJzLmdldFN0cmluZygiR1JBTlRPUiIpLnRvTG93ZXJDYXNlKCkpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZ3JhbnRlZSIsCisgICAgICAgICAgICAgICAgcnMuZ2V0U3RyaW5nKCJHUkFOVEVFIikuaW5kZXhPZigicm9vdCIpICE9IC0xKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJpdmlsZWdlIiwgInJlZmVyZW5jZXMiLCBycy5nZXRTdHJpbmcoCisgICAgICAgICAgICAgICAgIlBSSVZJTEVHRSIpLnRvTG93ZXJDYXNlKCkpOworCisgICAgICAgIHF1ZXJ5ID0gIlJFVk9LRSBSRUZFUkVOQ0VTKGlkKSBPTiAiICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxCisgICAgICAgICAgICAgICAgKyAiIEZST00gIiArIFN1cHBvcnRfU1FMLnNxbExvZ2luOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShxdWVyeSk7CisgICAgICAgIHJzLmNsb3NlKCk7CisgICAgfQorCisKKyAgICBAS25vd25GYWlsdXJlKCJub3Qgc3VwcG9ydGVkIikKKyAgICAgcHVibGljIHZvaWQgdGVzdF9nZXRFeHBvcnRlZEtleXNMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcoKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFJlc3VsdFNldCBycyA9IG1ldGEuZ2V0RXhwb3J0ZWRLZXlzKGNvbm4uZ2V0Q2F0YWxvZygpLCBudWxsLAorICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMyk7CisgICAgICAgIFJlc3VsdFNldE1ldGFEYXRhIHJzbWQgPSBycy5nZXRNZXRhRGF0YSgpOworICAgICAgICBhc3NlcnRUcnVlKCJSb3dzIGRvIG5vdCBvYnRhaW5lZCIsIHJzLm5leHQoKSk7CisgICAgICAgIGludCBjb2wgPSByc21kLmdldENvbHVtbkNvdW50KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IG51bWJlciBvZiBjb2x1bW5zIiwgMTQsIGNvbCk7CisgICAgICAgIFN0cmluZ1tdIGNvbHVtbk5hbWVzID0geyAiUEtUQUJMRV9DQVQiLCAiUEtUQUJMRV9TQ0hFTSIsCisgICAgICAgICAgICAgICAgIlBLVEFCTEVfTkFNRSIsICJQS0NPTFVNTl9OQU1FIiwgIkZLVEFCTEVfQ0FUIiwKKyAgICAgICAgICAgICAgICAiRktUQUJMRV9TQ0hFTSIsICJGS1RBQkxFX05BTUUiLCAiRktDT0xVTU5fTkFNRSIsICJLRVlfU0VRIiwKKyAgICAgICAgICAgICAgICAiVVBEQVRFX1JVTEUiLCAiREVMRVRFX1JVTEUiLCAiRktfTkFNRSIsICJQS19OQU1FIiwKKyAgICAgICAgICAgICAgICAiREVGRVJSQUJJTElUWSIgfTsKKyAgICAgICAgZm9yIChpbnQgYyA9IDE7IGMgPD0gY29sOyArK2MpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGNvbHVtbiBuYW1lIiwgY29sdW1uTmFtZXNbYyAtIDFdLCByc21kCisgICAgICAgICAgICAgICAgICAgIC5nZXRDb2x1bW5OYW1lKGMpKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByaW1hcnkga2V5IHRhYmxlIGNhdGFsb2ciLCBjb25uLmdldENhdGFsb2coKSwKKyAgICAgICAgICAgICAgICBycy5nZXRTdHJpbmcoIlBLVEFCTEVfQ0FUIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcmltYXJ5IGtleSB0YWJsZSBzY2hlbWEiLCBudWxsLCBycworICAgICAgICAgICAgICAgIC5nZXRTdHJpbmcoIlBLVEFCTEVfU0NIRU0iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByaW1hcnkga2V5IHRhYmxlIG5hbWUiLAorICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMywgcnMuZ2V0U3RyaW5nKCJQS1RBQkxFX05BTUUiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByaW1hcnkga2V5IGNvbHVtbiBuYW1lIiwgImZrIiwgcnMKKyAgICAgICAgICAgICAgICAuZ2V0U3RyaW5nKCJQS0NPTFVNTl9OQU1FIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBmb3JlaWduIGtleSB0YWJsZSBjYXRhbG9nIiwgY29ubi5nZXRDYXRhbG9nKCksCisgICAgICAgICAgICAgICAgcnMuZ2V0U3RyaW5nKCJGS1RBQkxFX0NBVCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgZm9yZWlnbiBrZXkgdGFibGUgc2NoZW1hIiwgbnVsbCwgcnMKKyAgICAgICAgICAgICAgICAuZ2V0U3RyaW5nKCJGS1RBQkxFX1NDSEVNIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBmb3JlaWduIGtleSB0YWJsZSBuYW1lIiwKKyAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEsIHJzLmdldFN0cmluZygiRktUQUJMRV9OQU1FIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBmb3JlaWduIGtleSBjb2x1bW4gbmFtZSIsICJma2V5IiwgcnMKKyAgICAgICAgICAgICAgICAuZ2V0U3RyaW5nKCJGS0NPTFVNTl9OQU1FIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBzZXF1ZW5jZSBudW1iZXIgd2l0aGluIGZvcmVpZ24ga2V5IiwgMSwgcnMKKyAgICAgICAgICAgICAgICAuZ2V0U2hvcnQoIktFWV9TRVEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHVwZGF0ZSBydWxlIHZhbHVlIiwKKyAgICAgICAgICAgICAgICBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5Tm9BY3Rpb24sIHJzCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0U2hvcnQoIlVQREFURV9SVUxFIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBkZWxldGUgcnVsZSB2YWx1ZSIsCisgICAgICAgICAgICAgICAgRGF0YWJhc2VNZXRhRGF0YS5pbXBvcnRlZEtleU5vQWN0aW9uLCBycworICAgICAgICAgICAgICAgICAgICAgICAgLmdldFNob3J0KCJERUxFVEVfUlVMRSIpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiSW5jb3JyZWN0IGZvcmVpZ24ga2V5IG5hbWUiLCBycy5nZXRTdHJpbmcoIkZLX05BTUUiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByaW1hcnkga2V5IG5hbWUiLCBudWxsLCBycworICAgICAgICAgICAgICAgIC5nZXRTdHJpbmcoIlBLX05BTUUiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRlZmVycmFiaWxpdHkiLAorICAgICAgICAgICAgICAgIERhdGFiYXNlTWV0YURhdGEuaW1wb3J0ZWRLZXlOb3REZWZlcnJhYmxlLCBycworICAgICAgICAgICAgICAgICAgICAgICAgLmdldFNob3J0KCJERUZFUlJBQklMSVRZIikpOworICAgICAgICBycy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UHJvY2VkdXJlQ29sdW1uc0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nKCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBtZXRhLmdldFByb2NlZHVyZUNvbHVtbnMoIiIsICIiLCAiIiwgIiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UHJvY2VkdXJlc0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZygpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gTk9UX0ZFQVNJQkxFOiBTUUxJVEUgZG9lcyBub3QgaW1wbGVtZW50IHRoaXMgZnVuY3Rpb25hbGl0eQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0UHJvY2VkdXJlVGVybSgpCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgiRXhjZXB0aW9uIHRlc3QgZmFpbHMiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UHJvY2VkdXJlVGVybSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgcHJvY2VkdXJlIHRlcm0iLCAiIi5lcXVhbHMobWV0YQorICAgICAgICAgICAgICAgIC5nZXRQcm9jZWR1cmVUZXJtKCkudHJpbSgpKSk7CisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBtZXRhLmdldFByb2NlZHVyZVRlcm0oKTsKKyAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAvL29rCisgICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXRTY2hlbWFUZXJtKCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJFeGNlcHRpb24gdGVzdCBmYWlscyIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTY2hlbWFUZXJtKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyB0ZXJtID0gbWV0YS5nZXRTY2hlbWFUZXJtKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkluY29ycmVjdCBzY2hlbWEgdGVybSIsIHRlcm0gKTsKKworICAgICAgICBhc3NlcnRUcnVlKCIiLmVxdWFscyh0ZXJtKSk7CisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBtZXRhLmdldFNjaGVtYVRlcm0oKTsKKyAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAvL29rCisgICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTdXBlclRhYmxlc0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZygpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gTk9UX0ZFQVNJQkxFOiBTUUxJVEUgZG9lcyBub3QgaW1wbGVtZW50IHRoaXMgZnVuY3Rpb25hbGl0eQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0U3VwZXJUeXBlc0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZygpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gTk9UX0ZFQVNJQkxFOiBTUUxJVEUgZG9lcyBub3QgaW1wbGVtZW50IHRoaXMgZnVuY3Rpb25hbGl0eQorICAgIH0KKworICAgIEBLbm93bkZhaWx1cmUoIm5vdCBzdXBwb3J0ZWQuIFByaXZpbGVnZXMgYXJlIG5vdCBzdXBwb3J0ZWQuIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFRhYmxlUHJpdmlsZWdlc0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZygpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gY2FzZSAxLiBHZXQgcHJpdmlsZWdlcyB3aGVuIG5vIHByaXZpbGVnaWVzIGV4aXN0IGZvciBvbmUgdGFibGUKKyAgICAgICAgUmVzdWx0U2V0IHByaXZpbGVnZXMgPSBtZXRhLmdldFRhYmxlUHJpdmlsZWdlcyhjb25uLmdldENhdGFsb2coKSwgIiUiLAorICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMyk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTb21lIHByaXZpbGVnaWVzIGV4aXN0IiwgcHJpdmlsZWdlcy5uZXh0KCkpOworICAgICAgICBwcml2aWxlZ2VzLmNsb3NlKCk7CisKKyAgICAgICAgLy8gY2FzZSAyLiBHZXQgcHJpdmlsZWdlcyB3aGVuIG5vIHByaXZpbGVnaWVzIGV4aXN0IGZvciBhbGwgdGFibGVzCisgICAgICAgIHByaXZpbGVnZXMgPSBtZXRhLmdldFRhYmxlUHJpdmlsZWdlcyhudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNvbWUgcHJpdmlsZWdpZXMgZXhpc3QiLCBwcml2aWxlZ2VzLm5leHQoKSk7CisgICAgICAgIHByaXZpbGVnZXMuY2xvc2UoKTsKKworICAgICAgICAvLyBjYXNlIDMuIGdyYW50IENSRUFURSBhbmQgU0VMRUNUIHByaXZpbGVnZXMgYW5nIGdldCB0aGVtCisgICAgICAgIEhhc2hTZXQ8U3RyaW5nPiBleHBlY3RlZFByaXZzID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgICBleHBlY3RlZFByaXZzLmFkZCgiQ1JFQVRFIik7CisgICAgICAgIGV4cGVjdGVkUHJpdnMuYWRkKCJTRUxFQ1QiKTsKKworICAgICAgICBTdHJpbmcgcXVlcnkgPSAiR1JBTlQgQ1JFQVRFLCBTRUxFQ1QgT04gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMworICAgICAgICAgICAgICAgICsgIiBUTyAiICsgU3VwcG9ydF9TUUwuc3FsVXNlcjsKKyAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUocXVlcnkpOworCisgICAgICAgIHByaXZpbGVnZXMgPSBtZXRhLmdldFRhYmxlUHJpdmlsZWdlcyhjb25uLmdldENhdGFsb2coKSwgbnVsbCwKKyAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTMpOworCisgICAgICAgIHdoaWxlIChwcml2aWxlZ2VzLm5leHQoKSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBjYXRhbG9nIG5hbWUiLCBTdXBwb3J0X1NRTC5zcWxDYXRhbG9nLAorICAgICAgICAgICAgICAgICAgICBwcml2aWxlZ2VzLmdldFN0cmluZygiVEFCTEVfQ0FUIikpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiV3Jvbmcgc2NoZW1hIiwgcHJpdmlsZWdlcy5nZXRTdHJpbmcoIlRBQkxFX1NDSEVNIikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB0YWJsZSBuYW1lIiwgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUzLAorICAgICAgICAgICAgICAgICAgICBwcml2aWxlZ2VzLmdldFN0cmluZygiVEFCTEVfTkFNRSIpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIldyb25nIHByaXZpbGVnZSAiICsgcHJpdmlsZWdlcy5nZXRTdHJpbmcoIlBSSVZJTEVHRSIpLAorICAgICAgICAgICAgICAgICAgICBleHBlY3RlZFByaXZzLnJlbW92ZShwcml2aWxlZ2VzLmdldFN0cmluZygiUFJJVklMRUdFIikpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgZ3JhbnRvciIsIFN1cHBvcnRfU1FMLnNxbExvZ2luICsgIkAiCisgICAgICAgICAgICAgICAgICAgICsgU3VwcG9ydF9TUUwuc3FsSG9zdCwgcHJpdmlsZWdlcy5nZXRTdHJpbmcoIkdSQU5UT1IiKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGdyYW50ZWUiLCBTdXBwb3J0X1NRTC5zcWxVc2VyICsgIkAlIiwKKyAgICAgICAgICAgICAgICAgICAgcHJpdmlsZWdlcy5nZXRTdHJpbmcoIkdSQU5URUUiKSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJXcm9uZyB2YWx1ZSBvZiBJU19HUkFOVEFCTEUiLCBwcml2aWxlZ2VzCisgICAgICAgICAgICAgICAgICAgIC5nZXRTdHJpbmcoIklTX0dSQU5UQUJMRSIpKTsKKyAgICAgICAgfQorICAgICAgICBwcml2aWxlZ2VzLmNsb3NlKCk7CisgICAgICAgIGFzc2VydFRydWUoIldyb25nIHByaXZpbGVnZXMgd2VyZSByZXR1cm5lZCIsIGV4cGVjdGVkUHJpdnMuaXNFbXB0eSgpKTsKKworICAgICAgICBxdWVyeSA9ICJSRVZPS0UgQ1JFQVRFLCBTRUxFQ1QgT04gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMworICAgICAgICAgICAgICAgICsgIiBGUk9NICIgKyBTdXBwb3J0X1NRTC5zcWxVc2VyOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShxdWVyeSk7CisKKyAgICAgICAgLy8gY2FzZSA0LiBncmFudCBhbGwgcHJpdmlsZWdlcyBhbmcgZ2V0IHRoZW0KKyAgICAgICAgU3RyaW5nW10gcHJpdnMgPSBuZXcgU3RyaW5nW10geyAiQUxURVIiLCAiQ1JFQVRFIiwgIkNSRUFURSBWSUVXIiwKKyAgICAgICAgICAgICAgICAiREVMRVRFIiwgIkRST1AiLCAiSU5ERVgiLCAiSU5TRVJUIiwgIlJFRkVSRU5DRVMiLCAiU0VMRUNUIiwKKyAgICAgICAgICAgICAgICAiU0hPVyBWSUVXIiwgIlVQREFURSIgfTsKKyAgICAgICAgZXhwZWN0ZWRQcml2cyA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcml2cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZXhwZWN0ZWRQcml2cy5hZGQocHJpdnNbaV0pOworICAgICAgICB9CisgICAgICAgIHF1ZXJ5ID0gIkdSQU5UIEFMTCBPTiAiICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUzICsgIiBUTyAiCisgICAgICAgICAgICAgICAgKyBTdXBwb3J0X1NRTC5zcWxVc2VyOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShxdWVyeSk7CisKKyAgICAgICAgcHJpdmlsZWdlcyA9IG1ldGEuZ2V0VGFibGVQcml2aWxlZ2VzKGNvbm4uZ2V0Q2F0YWxvZygpLCBudWxsLAorICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMyk7CisKKyAgICAgICAgd2hpbGUgKHByaXZpbGVnZXMubmV4dCgpKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGNhdGFsb2cgbmFtZSIsIFN1cHBvcnRfU1FMLnNxbENhdGFsb2csCisgICAgICAgICAgICAgICAgICAgIHByaXZpbGVnZXMuZ2V0U3RyaW5nKCJUQUJMRV9DQVQiKSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJXcm9uZyBzY2hlbWEiLCBwcml2aWxlZ2VzLmdldFN0cmluZygiVEFCTEVfU0NIRU0iKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHRhYmxlIG5hbWUiLCBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTMsCisgICAgICAgICAgICAgICAgICAgIHByaXZpbGVnZXMuZ2V0U3RyaW5nKCJUQUJMRV9OQU1FIikpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcHJpdmlsZWdlICIgKyBwcml2aWxlZ2VzLmdldFN0cmluZygiUFJJVklMRUdFIiksCisgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkUHJpdnMucmVtb3ZlKHByaXZpbGVnZXMuZ2V0U3RyaW5nKCJQUklWSUxFR0UiKSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBncmFudG9yIiwgU3VwcG9ydF9TUUwuc3FsTG9naW4gKyAiQCIKKyAgICAgICAgICAgICAgICAgICAgKyBTdXBwb3J0X1NRTC5zcWxIb3N0LCBwcml2aWxlZ2VzLmdldFN0cmluZygiR1JBTlRPUiIpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgZ3JhbnRlZSIsIFN1cHBvcnRfU1FMLnNxbFVzZXIgKyAiQCUiLAorICAgICAgICAgICAgICAgICAgICBwcml2aWxlZ2VzLmdldFN0cmluZygiR1JBTlRFRSIpKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoIldyb25nIHZhbHVlIG9mIElTX0dSQU5UQUJMRSIsIHByaXZpbGVnZXMKKyAgICAgICAgICAgICAgICAgICAgLmdldFN0cmluZygiSVNfR1JBTlRBQkxFIikpOworICAgICAgICB9CisgICAgICAgIHByaXZpbGVnZXMuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgcHJpdmlsZWdlcyB3ZXJlIHJldHVybmVkIiwgZXhwZWN0ZWRQcml2cy5pc0VtcHR5KCkpOworCisgICAgICAgIHF1ZXJ5ID0gIlJFVk9LRSBBTEwgT04gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMyArICIgRlJPTSAiCisgICAgICAgICAgICAgICAgKyBTdXBwb3J0X1NRTC5zcWxVc2VyOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShxdWVyeSk7CisKKyAgICAgICAgLy8gY2FzZSA1LiBjaGVjayBubyBwcml2ZWxlZ2llcyBhZnRlciByZXZva2UKKyAgICAgICAgcHJpdmlsZWdlcyA9IG1ldGEuZ2V0VGFibGVQcml2aWxlZ2VzKGNvbm4uZ2V0Q2F0YWxvZygpLCAiJSIsCisgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNvbWUgcHJpdmlsZWdpZXMgZXhpc3QiLCBwcml2aWxlZ2VzLm5leHQoKSk7CisgICAgICAgIHByaXZpbGVnZXMuY2xvc2UoKTsKKworICAgICAgICBwcml2aWxlZ2VzID0gbWV0YS5nZXRUYWJsZVByaXZpbGVnZXMobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJTb21lIHByaXZpbGVnaWVzIGV4aXN0IiwgcHJpdmlsZWdlcy5uZXh0KCkpOworICAgICAgICBwcml2aWxlZ2VzLmNsb3NlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRVRFRzTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nJEkoKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIE5PVF9GRUFTSUJMRTogSkRCQyBkb2VzIG5vdCBpbXBsZW1lbnQgdGhpcyBmdW5jdGlvbmFsaXR5CisgICAgfQorCisgICAgQEtub3duRmFpbHVyZSgiTm90IHN1cHBvcnRlZCBvcHMgYXBwbGllZCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRWZXJzaW9uQ29sdW1uc0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZygpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgRGF0YWJhc2VNZXRhRGF0YVRlc3QuaW5zZXJ0TmV3UmVjb3JkKCk7CisKKyAgICAgICAgU3RyaW5nIHRyaWdnZXJOYW1lID0gInVwZGF0ZVRyaWdnZXIiOworICAgICAgICBTdHJpbmcgdHJpZ2dlclF1ZXJ5ID0gIkNSRUFURSBUUklHR0VSICIgKyB0cmlnZ2VyTmFtZQorICAgICAgICAgICAgICAgICsgIiBBRlRFUiBVUERBVEUgT04gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMQorICAgICAgICAgICAgICAgICsgIiBGT1IgRUFDSCBST1cgQkVHSU4gSU5TRVJUIElOVE8gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUzICsgIiBTRVQgZmsgPSAxMDsgRU5EOyI7CisgICAgICAgIHN0YXRlbWVudEZvcndhcmQuZXhlY3V0ZSh0cmlnZ2VyUXVlcnkpOworCisgICAgICAgIFN0cmluZyB1cGRhdGVRdWVyeSA9ICJVUERBVEUgIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMQorICAgICAgICAgICAgICAgICsgIiBTRVQgZmllbGQxPSdmZmZmZicgV0hFUkUgaWQ9MSI7CisgICAgICAgIHN0YXRlbWVudEZvcndhcmQuZXhlY3V0ZSh1cGRhdGVRdWVyeSk7CisKKyAgICAgICAgUmVzdWx0U2V0IHJzID0gbWV0YS5nZXRWZXJzaW9uQ29sdW1ucyhjb25uLmdldENhdGFsb2coKSwgbnVsbCwKKyAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEpOworICAgICAgICBhc3NlcnRUcnVlKCJSZXN1bHQgc2V0IGlzIGVtcHR5IiwgcnMubmV4dCgpKTsKKyAgICAgICAgcnMuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2lzQ2F0YWxvZ0F0U3RhcnQoKQorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIkV4Y2VwdGlvbiB0ZXN0IGZhaWxzIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzQ2F0YWxvZ0F0U3RhcnQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgICAgICAgImNhdGFsb2cgZG9lc24ndCBhcHBlYXIgYXQgdGhlIHN0YXJ0IG9mIGEgZnVsbHkgcXVhbGlmaWVkIHRhYmxlIG5hbWUiLAorICAgICAgICAgICAgICAgIG1ldGEuaXNDYXRhbG9nQXRTdGFydCgpKTsKKworICAgICAgLy9FeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgICB0cnkgeworICAgICAgICAgICAgIG1ldGEuaXNDYXRhbG9nQXRTdGFydCgpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKyAgICB9CisKKyAgICBAS25vd25GYWlsdXJlKCJub3Qgc3VwcG9ydGVkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2xvY2F0b3JzVXBkYXRlQ29weSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLmxvY2F0b3JzVXBkYXRlQ29weSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X251bGxQbHVzTm9uTnVsbElzTnVsbCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLm51bGxQbHVzTm9uTnVsbElzTnVsbCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X251bGxzQXJlU29ydGVkQXRFbmQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5udWxsc0FyZVNvcnRlZEF0RW5kKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbnVsbHNBcmVTb3J0ZWRBdFN0YXJ0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEubnVsbHNBcmVTb3J0ZWRBdFN0YXJ0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbnVsbHNBcmVTb3J0ZWRIaWdoKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEubnVsbHNBcmVTb3J0ZWRIaWdoKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RfbnVsbHNBcmVTb3J0ZWRMb3coKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5udWxsc0FyZVNvcnRlZExvdygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI293bkRlbGV0ZXNBcmVWaXNpYmxlKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X293bkRlbGV0ZXNBcmVWaXNpYmxlSSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICAvLyBOT1RfRkVBU0lCTEUgbm90IHN1cHBvcnRlZAorLy8gICAgICAgIGFzc2VydEZhbHNlKAorLy8gICAgICAgICAgICAgICAgInJlc3VsdCBzZXQncyBvd24gZGVsZXRlcyBhcmUgdmlzaWJsZSBmb3IgVFlQRV9GT1JXQVJEX09OTFkgdHlwZSIsCisvLyAgICAgICAgICAgICAgICBtZXRhLm93bkRlbGV0ZXNBcmVWaXNpYmxlKFJlc3VsdFNldC5UWVBFX0ZPUldBUkRfT05MWSkpOworLy8gICAgICAgIGFzc2VydEZhbHNlKAorLy8gICAgICAgICAgICAgICAgInJlc3VsdCBzZXQncyBvd24gZGVsZXRlcyBhcmUgdmlzaWJsZSBmb3IgVFlQRV9TQ1JPTExfSU5TRU5TSVRJVkUgdHlwZSIsCisvLyAgICAgICAgICAgICAgIG1ldGEub3duRGVsZXRlc0FyZVZpc2libGUoUmVzdWx0U2V0LlRZUEVfU0NST0xMX0lOU0VOU0lUSVZFKSk7CisvLyAgICAgICAgYXNzZXJ0RmFsc2UoCisvLyAgICAgICAgICAgICAgICAicmVzdWx0IHNldCdzIG93biBkZWxldGVzIGFyZSB2aXNpYmxlIGZvciBUWVBFX1NDUk9MTF9TRU5TSVRJVkUgdHlwZSIsCisvLyAgICAgICAgICAgICAgICBtZXRhLm93bkRlbGV0ZXNBcmVWaXNpYmxlKFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkUpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoInJlc3VsdCBzZXQncyBvd24gZGVsZXRlcyBhcmUgdmlzaWJsZSBmb3IgdW5rbm93biB0eXBlIiwKKyAgICAgICAgICAgICAgICBtZXRhLm93bkRlbGV0ZXNBcmVWaXNpYmxlKDEwMCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjb3duSW5zZXJ0c0FyZVZpc2libGUoaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfb3duSW5zZXJ0c0FyZVZpc2libGVJKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisvLyAgICAgICAgYXNzZXJ0RmFsc2UoCisvLyAgICAgICAgICAgICAgICAicmVzdWx0IHNldCdzIG93biBpbnNlcnRzIGFyZSB2aXNpYmxlIGZvciBUWVBFX0ZPUldBUkRfT05MWSB0eXBlIiwKKy8vICAgICAgICAgICAgICAgIG1ldGEub3duSW5zZXJ0c0FyZVZpc2libGUoUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZKSk7CisvLyAgICAgICAgYXNzZXJ0RmFsc2UoCisvLyAgICAgICAgICAgICAgICAicmVzdWx0IHNldCdzIG93biBpbnNlcnRzIGFyZSB2aXNpYmxlIGZvciBUWVBFX1NDUk9MTF9JTlNFTlNJVElWRSB0eXBlIiwKKy8vICAgICAgICAgICAgICAgIG1ldGEub3duSW5zZXJ0c0FyZVZpc2libGUoUmVzdWx0U2V0LlRZUEVfU0NST0xMX0lOU0VOU0lUSVZFKSk7CisvLyAgICAgICAgYXNzZXJ0RmFsc2UoCisvLyAgICAgICAgICAgICAgICAicmVzdWx0IHNldCdzIG93biBpbnNlcnRzIGFyZSB2aXNpYmxlIGZvciBUWVBFX1NDUk9MTF9TRU5TSVRJVkUgdHlwZSIsCisvLyAgICAgICAgICAgICAgICBtZXRhLm93bkluc2VydHNBcmVWaXNpYmxlKFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkUpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoInJlc3VsdCBzZXQncyBvd24gaW5zZXJ0cyBhcmUgdmlzaWJsZSBmb3IgdW5rbm93biB0eXBlIiwKKyAgICAgICAgICAgICAgICBtZXRhLm93bkluc2VydHNBcmVWaXNpYmxlKDEwMCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfb3duVXBkYXRlc0FyZVZpc2libGVJKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgInJlc3VsdCBzZXQncyBvd24gdXBkYXRlcyBhcmUgdmlzaWJsZSBmb3IgVFlQRV9GT1JXQVJEX09OTFkgdHlwZSIsCisgICAgICAgICAgICAgICAgbWV0YS5vd25VcGRhdGVzQXJlVmlzaWJsZShSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAicmVzdWx0IHNldCdzIG93biB1cGRhdGVzIGFyZSB2aXNpYmxlIGZvciBUWVBFX1NDUk9MTF9JTlNFTlNJVElWRSB0eXBlIiwKKyAgICAgICAgICAgICAgICBtZXRhLm93blVwZGF0ZXNBcmVWaXNpYmxlKFJlc3VsdFNldC5UWVBFX1NDUk9MTF9JTlNFTlNJVElWRSkpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJyZXN1bHQgc2V0J3Mgb3duIHVwZGF0ZXMgYXJlIHZpc2libGUgZm9yIFRZUEVfU0NST0xMX1NFTlNJVElWRSB0eXBlIiwKKyAgICAgICAgICAgICAgICBtZXRhLm93blVwZGF0ZXNBcmVWaXNpYmxlKFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkUpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoInJlc3VsdCBzZXQncyBvd24gdXBkYXRlcyBhcmUgdmlzaWJsZSBmb3IgdW5rbm93biB0eXBlIiwKKyAgICAgICAgICAgICAgICBtZXRhLm93blVwZGF0ZXNBcmVWaXNpYmxlKDEwMCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3RvcmVzTG93ZXJDYXNlSWRlbnRpZmllcnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5zdG9yZXNMb3dlckNhc2VJZGVudGlmaWVycygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N0b3Jlc0xvd2VyQ2FzZVF1b3RlZElkZW50aWZpZXJzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3RvcmVzTG93ZXJDYXNlUXVvdGVkSWRlbnRpZmllcnMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdG9yZXNVcHBlckNhc2VJZGVudGlmaWVycygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLnN0b3Jlc1VwcGVyQ2FzZUlkZW50aWZpZXJzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3RvcmVzVXBwZXJDYXNlUXVvdGVkSWRlbnRpZmllcnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5zdG9yZXNVcHBlckNhc2VRdW90ZWRJZGVudGlmaWVycygpKTsKKyAgICB9CisKKyAgICBAS25vd25GYWlsdXJlKCJub3Qgc3VwcG9ydGVkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzQU5TSTkyRW50cnlMZXZlbFNRTCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLnN1cHBvcnRzQU5TSTkyRW50cnlMZXZlbFNRTCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzQU5TSTkyRnVsbFNRTCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLnN1cHBvcnRzQU5TSTkyRnVsbFNRTCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzQU5TSTkySW50ZXJtZWRpYXRlU1FMKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNBTlNJOTJJbnRlcm1lZGlhdGVTUUwoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c0FsdGVyVGFibGVXaXRoQWRkQ29sdW1uKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNBbHRlclRhYmxlV2l0aEFkZENvbHVtbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzQWx0ZXJUYWJsZVdpdGhEcm9wQ29sdW1uKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNBbHRlclRhYmxlV2l0aERyb3BDb2x1bW4oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c0JhdGNoVXBkYXRlcygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKG1ldGEuc3VwcG9ydHNCYXRjaFVwZGF0ZXMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c0NhdGFsb2dzSW5EYXRhTWFuaXB1bGF0aW9uKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNDYXRhbG9nc0luRGF0YU1hbmlwdWxhdGlvbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzQ2F0YWxvZ3NJbkluZGV4RGVmaW5pdGlvbnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5zdXBwb3J0c0NhdGFsb2dzSW5JbmRleERlZmluaXRpb25zKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNDYXRhbG9nc0luUHJpdmlsZWdlRGVmaW5pdGlvbnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5zdXBwb3J0c0NhdGFsb2dzSW5Qcml2aWxlZ2VEZWZpbml0aW9ucygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzQ2F0YWxvZ3NJblByb2NlZHVyZUNhbGxzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNDYXRhbG9nc0luUHJvY2VkdXJlQ2FsbHMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c0NhdGFsb2dzSW5UYWJsZURlZmluaXRpb25zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNDYXRhbG9nc0luVGFibGVEZWZpbml0aW9ucygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzQ29udmVydCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLnN1cHBvcnRzQ29udmVydCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzQ29udmVydElJKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNDb252ZXJ0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNDb3JlU1FMR3JhbW1hcigpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLnN1cHBvcnRzQ29yZVNRTEdyYW1tYXIoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c0NvcnJlbGF0ZWRTdWJxdWVyaWVzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNDb3JyZWxhdGVkU3VicXVlcmllcygpKTsKKyAgICB9CisKKyAgICBAS25vd25GYWlsdXJlKCJub3Qgc3VwcG9ydGVkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzRGF0YURlZmluaXRpb25BbmREYXRhTWFuaXB1bGF0aW9uVHJhbnNhY3Rpb25zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNEYXRhRGVmaW5pdGlvbkFuZERhdGFNYW5pcHVsYXRpb25UcmFuc2FjdGlvbnMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c0RhdGFNYW5pcHVsYXRpb25UcmFuc2FjdGlvbnNPbmx5KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNEYXRhTWFuaXB1bGF0aW9uVHJhbnNhY3Rpb25zT25seSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzRGlmZmVyZW50VGFibGVDb3JyZWxhdGlvbk5hbWVzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNEaWZmZXJlbnRUYWJsZUNvcnJlbGF0aW9uTmFtZXMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c0V4dGVuZGVkU1FMR3JhbW1hcigpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLnN1cHBvcnRzRXh0ZW5kZWRTUUxHcmFtbWFyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNGdWxsT3V0ZXJKb2lucygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLnN1cHBvcnRzRnVsbE91dGVySm9pbnMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c0dldEdlbmVyYXRlZEtleXMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5zdXBwb3J0c0dldEdlbmVyYXRlZEtleXMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c0dyb3VwQnlCZXlvbmRTZWxlY3QoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5zdXBwb3J0c0dyb3VwQnlCZXlvbmRTZWxlY3QoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c0ludGVncml0eUVuaGFuY2VtZW50RmFjaWxpdHkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5zdXBwb3J0c0ludGVncml0eUVuaGFuY2VtZW50RmFjaWxpdHkoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c0xpa2VFc2NhcGVDbGF1c2UoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5zdXBwb3J0c0xpa2VFc2NhcGVDbGF1c2UoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c0xpbWl0ZWRPdXRlckpvaW5zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNMaW1pdGVkT3V0ZXJKb2lucygpKTsKKyAgICB9CisKKyAgICBAS25vd25GYWlsdXJlKCJub3Qgc3VwcG9ydGVkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzTWluaW11bVNRTEdyYW1tYXIoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5zdXBwb3J0c01pbmltdW1TUUxHcmFtbWFyKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNNaXhlZENhc2VJZGVudGlmaWVycygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLnN1cHBvcnRzTWl4ZWRDYXNlSWRlbnRpZmllcnMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c01peGVkQ2FzZVF1b3RlZElkZW50aWZpZXJzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNNaXhlZENhc2VRdW90ZWRJZGVudGlmaWVycygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzTXVsdGlwbGVPcGVuUmVzdWx0cygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLnN1cHBvcnRzTXVsdGlwbGVPcGVuUmVzdWx0cygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzTXVsdGlwbGVSZXN1bHRTZXRzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNNdWx0aXBsZVJlc3VsdFNldHMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c011bHRpcGxlVHJhbnNhY3Rpb25zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNNdWx0aXBsZVRyYW5zYWN0aW9ucygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzTmFtZWRQYXJhbWV0ZXJzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNOYW1lZFBhcmFtZXRlcnMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c09wZW5DdXJzb3JzQWNyb3NzQ29tbWl0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNPcGVuQ3Vyc29yc0Fjcm9zc0NvbW1pdCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzT3BlbkN1cnNvcnNBY3Jvc3NSb2xsYmFjaygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLnN1cHBvcnRzT3BlbkN1cnNvcnNBY3Jvc3NSb2xsYmFjaygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzT3BlblN0YXRlbWVudHNBY3Jvc3NDb21taXQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5zdXBwb3J0c09wZW5TdGF0ZW1lbnRzQWNyb3NzQ29tbWl0KCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNPcGVuU3RhdGVtZW50c0Fjcm9zc1JvbGxiYWNrKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNPcGVuU3RhdGVtZW50c0Fjcm9zc1JvbGxiYWNrKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNPdXRlckpvaW5zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNPdXRlckpvaW5zKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNQb3NpdGlvbmVkRGVsZXRlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNQb3NpdGlvbmVkRGVsZXRlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNQb3NpdGlvbmVkVXBkYXRlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNQb3NpdGlvbmVkVXBkYXRlKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNSZXN1bHRTZXRDb25jdXJyZW5jeUlJKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNSZXN1bHRTZXRDb25jdXJyZW5jeSgwLDApKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzUmVzdWx0U2V0SG9sZGFiaWxpdHlJKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNSZXN1bHRTZXRIb2xkYWJpbGl0eSgwKSk7CisgICAgfQorCisgICAgQEtub3duRmFpbHVyZSgibm90IHN1cHBvcnRlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c1Jlc3VsdFNldFR5cGVJKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoImRhdGFiYXNlIHN1cHBvcnRzIFRZUEVfRk9SV0FSRF9PTkxZIHR5cGUiLCBtZXRhCisgICAgICAgICAgICAgICAgLnN1cHBvcnRzUmVzdWx0U2V0VHlwZShSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoImRhdGFiYXNlIGRvZXNuJ3Qgc3VwcG9ydCBUWVBFX1NDUk9MTF9JTlNFTlNJVElWRSB0eXBlIiwKKyAgICAgICAgICAgICAgICBtZXRhLnN1cHBvcnRzUmVzdWx0U2V0VHlwZShSZXN1bHRTZXQuVFlQRV9TQ1JPTExfSU5TRU5TSVRJVkUpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoImRhdGFiYXNlIHN1cHBvcnRzIFRZUEVfU0NST0xMX1NFTlNJVElWRSB0eXBlIiwgbWV0YQorICAgICAgICAgICAgICAgIC5zdXBwb3J0c1Jlc3VsdFNldFR5cGUoUmVzdWx0U2V0LlRZUEVfU0NST0xMX1NFTlNJVElWRSkpOworICAgICAgICBhc3NlcnRGYWxzZSgiZGF0YWJhc2Ugc3VwcG9ydHMgdW5rbm93biB0eXBlIiwgbWV0YQorICAgICAgICAgICAgICAgIC5zdXBwb3J0c1Jlc3VsdFNldFR5cGUoMTAwKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c1NhdmVwb2ludHMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5zdXBwb3J0c1NhdmVwb2ludHMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c1NjaGVtYXNJbkRhdGFNYW5pcHVsYXRpb24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5zdXBwb3J0c1NjaGVtYXNJbkRhdGFNYW5pcHVsYXRpb24oKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c1NjaGVtYXNJbkluZGV4RGVmaW5pdGlvbnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5zdXBwb3J0c1NjaGVtYXNJbkluZGV4RGVmaW5pdGlvbnMoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c1NjaGVtYXNJblByaXZpbGVnZURlZmluaXRpb25zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIE5PVF9GRUFTSUJMRTogU1FMSVRFIGRvZXMgbm90IGltcGxlbWVudCB0aGlzIGZ1bmN0aW9uYWxpdHkKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzU2NoZW1hc0luUHJvY2VkdXJlQ2FsbHMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS5zdXBwb3J0c1NjaGVtYXNJblByb2NlZHVyZUNhbGxzKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNTY2hlbWFzSW5UYWJsZURlZmluaXRpb25zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNTY2hlbWFzSW5UYWJsZURlZmluaXRpb25zKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNTdGF0ZW1lbnRQb29saW5nKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNTdGF0ZW1lbnRQb29saW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNTdG9yZWRQcm9jZWR1cmVzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKG1ldGEuc3VwcG9ydHNTdG9yZWRQcm9jZWR1cmVzKCkpOworICAgIH0KKworICAgIEBLbm93bkZhaWx1cmUoIm5vdCBzdXBwb3J0ZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNTdWJxdWVyaWVzSW5Db21wYXJpc29ucygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLnN1cHBvcnRzU3VicXVlcmllc0luQ29tcGFyaXNvbnMoKSk7CisgICAgfQorCisgICAgQEtub3duRmFpbHVyZSgibm90IHN1cHBvcnRlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c1N1YnF1ZXJpZXNJbklucygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLnN1cHBvcnRzU3VicXVlcmllc0luSW5zKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNTdWJxdWVyaWVzSW5RdWFudGlmaWVkcygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLnN1cHBvcnRzU3VicXVlcmllc0luUXVhbnRpZmllZHMoKSk7CisgICAgfQorCisgICAgQEtub3duRmFpbHVyZSgibm90IHN1cHBvcnRlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c1RyYW5zYWN0aW9ucygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLnN1cHBvcnRzVHJhbnNhY3Rpb25zKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNVbmlvbigpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKG1ldGEuc3VwcG9ydHNVbmlvbigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzVW5pb25BbGwoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShtZXRhLnN1cHBvcnRzVW5pb25BbGwoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdF91c2VzTG9jYWxGaWxlUGVyVGFibGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobWV0YS51c2VzTG9jYWxGaWxlUGVyVGFibGUoKSk7CisgICAgfQorCisgICAgQEtub3duRmFpbHVyZSgibm90IHN1cHBvcnRlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdF91c2VzTG9jYWxGaWxlcygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShtZXRhLnVzZXNMb2NhbEZpbGVzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0TWF4QmluYXJ5TGl0ZXJhbExlbmd0aCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRNYXhCaW5hcnlMaXRlcmFsTGVuZ3RoKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBiaW5hcnkgbGl0ZXJhbCBsZW5ndGgiLCBtZXRhCisgICAgICAgICAgICAgICAgLmdldE1heEJpbmFyeUxpdGVyYWxMZW5ndGgoKSA9PSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2dldE1heENhdGFsb2dOYW1lTGVuZ3RoKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1heENhdGFsb2dOYW1lTGVuZ3RoKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBuYW1lIGxlbmd0aCIsIG1ldGEuZ2V0TWF4Q2F0YWxvZ05hbWVMZW5ndGgoKSA9PSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2dldE1heENoYXJMaXRlcmFsTGVuZ3RoKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1heENoYXJMaXRlcmFsTGVuZ3RoKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBjaGFyIGxpdGVyYWwgbGVuZ3RoIiwgbWV0YQorICAgICAgICAgICAgICAgIC5nZXRNYXhDaGFyTGl0ZXJhbExlbmd0aCgpID09IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0TWF4Q29sdW1uTmFtZUxlbmd0aCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRNYXhDb2x1bW5OYW1lTGVuZ3RoKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBjb2x1bW4gbmFtZSBsZW5ndGgiLCBtZXRhCisgICAgICAgICAgICAgICAgLmdldE1heENvbHVtbk5hbWVMZW5ndGgoKSA9PSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2dldE1heENvbHVtbnNJbkdyb3VwQnkoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TWF4Q29sdW1uc0luR3JvdXBCeSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgbnVtYmVyIG9mIGNvbHVtbnMiLAorICAgICAgICAgICAgICAgIG1ldGEuZ2V0TWF4Q29sdW1uc0luR3JvdXBCeSgpID09IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0TWF4Q29sdW1uc0luSW5kZXgoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TWF4Q29sdW1uc0luSW5kZXgoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG51bWJlciBvZiBjb2x1bW5zIiwKKyAgICAgICAgICAgICAgICBtZXRhLmdldE1heENvbHVtbnNJbkluZGV4KCkgPT0gMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXRNYXhDb2x1bW5zSW5PcmRlckJ5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1heENvbHVtbnNJbk9yZGVyQnkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG51bWJlciBvZiBjb2x1bW5zIiwKKyAgICAgICAgICAgICAgICBtZXRhLmdldE1heENvbHVtbnNJbk9yZGVyQnkoKSA9PSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2dldE1heENvbHVtbnNJblNlbGVjdCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRNYXhDb2x1bW5zSW5TZWxlY3QoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG51bWJlciBvZiBjb2x1bW5zIiwKKyAgICAgICAgICAgICAgICBtZXRhLmdldE1heENvbHVtbnNJblNlbGVjdCgpID09IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0TWF4Q29sdW1uc0luVGFibGUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TWF4Q29sdW1uc0luVGFibGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IG51bWJlciBvZiBjb2x1bW5zIiwKKyAgICAgICAgICAgICAgICBtZXRhLmdldE1heENvbHVtbnNJblRhYmxlKCkgPT0gMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXRNYXhDb25uZWN0aW9ucygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRNYXhDb25uZWN0aW9ucygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgbnVtYmVyIG9mIGNvbm5lY3Rpb25zIiwKKyAgICAgICAgICAgICAgICBtZXRhLmdldE1heENvbm5lY3Rpb25zKCkgPT0gMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXRNYXhJbmRleExlbmd0aCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRNYXhJbmRleExlbmd0aCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgbGVuZ3RoIG9mIGluZGV4IiwgbWV0YS5nZXRNYXhJbmRleExlbmd0aCgpID09IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0TWF4UHJvY2VkdXJlTmFtZUxlbmd0aCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRNYXhQcm9jZWR1cmVOYW1lTGVuZ3RoKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBsZW5ndGggb2YgcHJvY2VkdXJlIG5hbWUiLCBtZXRhCisgICAgICAgICAgICAgICAgLmdldE1heFByb2NlZHVyZU5hbWVMZW5ndGgoKSA9PSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2dldE1heFJvd1NpemUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TWF4Um93U2l6ZSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3Qgc2l6ZSBvZiByb3ciLCBtZXRhLmdldE1heFJvd1NpemUoKSA9PSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2dldE1heFNjaGVtYU5hbWVMZW5ndGgoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TWF4U2NoZW1hTmFtZUxlbmd0aCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgbGVuZ3RoIG9mIHNjaGVtYSBuYW1lIiwgbWV0YQorICAgICAgICAgICAgICAgIC5nZXRNYXhTY2hlbWFOYW1lTGVuZ3RoKCkgPT0gMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXRNYXhTdGF0ZW1lbnRMZW5ndGgoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TWF4U3RhdGVtZW50TGVuZ3RoKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBsZW5ndGggb2Ygc3RhdGVtZW50IiwgbWV0YQorICAgICAgICAgICAgICAgIC5nZXRNYXhTdGF0ZW1lbnRMZW5ndGgoKSA9PSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2dldE1heFN0YXRlbWVudHMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TWF4U3RhdGVtZW50cygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgbnVtYmVyIG9mIHN0YXRlbWVudHMiLAorICAgICAgICAgICAgICAgIG1ldGEuZ2V0TWF4U3RhdGVtZW50cygpID09IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0TWF4VGFibGVOYW1lTGVuZ3RoKCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJFeGNlcHRpb24gdGVzdCBmYWlscyIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRNYXhUYWJsZU5hbWVMZW5ndGgoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTm93IHN1cHBvcnRlZCIsIG1ldGEKKyAgICAgICAgICAgICAgICAuZ2V0TWF4VGFibGVOYW1lTGVuZ3RoKCkgPT0gMCk7CisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBtZXRhLmdldE1heFRhYmxlTmFtZUxlbmd0aCgpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2dldE1heFRhYmxlc0luU2VsZWN0KCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJFeGNlcHRpb24gdGVzdCBmYWlscyIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRNYXhUYWJsZXNJblNlbGVjdCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKCJUYWJsZXMgaW4gc2VsZWN0IGlzIG5vdyBzdXBwb3J0ZWQ6IGNoYW5nZSB0ZXN0IGltcGxlbWVudGF0aW9uXCIiLAorICAgICAgICAgICAgICAgIG1ldGEuZ2V0TWF4VGFibGVzSW5TZWxlY3QoKSA9PSAwKTsKKworICAgICAgLy9FeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgICB0cnkgeworICAgICAgICAgICAgIG1ldGEuZ2V0TWF4VGFibGVzSW5TZWxlY3QoKTsKKyAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAvL29rCisgICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXRNYXhVc2VyTmFtZUxlbmd0aCgpCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgiRXhjZXB0aW9uIHRlc3QgZmFpbHMiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TWF4VXNlck5hbWVMZW5ndGgoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVXNlcm5hbWVzIGFyZSBub3cgc3VwcG9ydGVkOiBjaGFuZ2UgdGVzdCBpbXBsZW1lbnRhdGlvbiIsCisgICAgICAgICAgICAgICAgbWV0YS5nZXRNYXhVc2VyTmFtZUxlbmd0aCgpID09IDApOworCisgICAgICAvL0V4Y3BldGlvbiBjaGVja2luZworICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgbWV0YS5nZXRNYXhVc2VyTmFtZUxlbmd0aCgpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKyAgICB9CisKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2phdmEvc3FsL0RhdGFiYXNlTWV0YURhdGFUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvamF2YS9zcWwvRGF0YWJhc2VNZXRhRGF0YVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi42NzgxOGM1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2phdmEvc3FsL0RhdGFiYXNlTWV0YURhdGFUZXN0LmphdmEKQEAgLTAsMCArMSwyNDczIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSB0ZXN0cy5qYXZhLnNxbDsKKworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLktub3duRmFpbHVyZTsKKworaW1wb3J0IGp1bml0LmV4dGVuc2lvbnMuVGVzdFNldHVwOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgdGVzdHMuc3VwcG9ydC5EYXRhYmFzZUNyZWF0b3I7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1NRTDsKKworaW1wb3J0IGphdmEuc3FsLkNvbm5lY3Rpb247CitpbXBvcnQgamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YTsKK2ltcG9ydCBqYXZhLnNxbC5Ecml2ZXJNYW5hZ2VyOworaW1wb3J0IGphdmEuc3FsLlByZXBhcmVkU3RhdGVtZW50OworaW1wb3J0IGphdmEuc3FsLlJlc3VsdFNldDsKK2ltcG9ydCBqYXZhLnNxbC5SZXN1bHRTZXRNZXRhRGF0YTsKK2ltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247CitpbXBvcnQgamF2YS5zcWwuU3RhdGVtZW50OworaW1wb3J0IGphdmEuc3FsLlR5cGVzOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CisKK3B1YmxpYyBjbGFzcyBEYXRhYmFzZU1ldGFEYXRhVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgVklFV19OQU1FID0gIm15VmlldyI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgQ1JFQVRFX1ZJRVdfUVVFUlkgPSAiQ1JFQVRFIFZJRVcgIiArIFZJRVdfTkFNRQorICAgICAgICAgICAgKyAiIEFTIFNFTEVDVCAqIEZST00gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMTsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBEUk9QX1ZJRVdfUVVFUlkgPSAiRFJPUCBWSUVXICIgKyBWSUVXX05BTUU7CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIENvbm5lY3Rpb24gY29ubjsKKworICAgIHByb3RlY3RlZCBzdGF0aWMgRGF0YWJhc2VNZXRhRGF0YSBtZXRhOworCisgICAgcHJvdGVjdGVkIHN0YXRpYyBTdGF0ZW1lbnQgc3RhdGVtZW50OworCisgICAgcHJvdGVjdGVkIHN0YXRpYyBTdGF0ZW1lbnQgc3RhdGVtZW50Rm9yd2FyZDsKKworICAgIHByaXZhdGUgc3RhdGljIGludCBpZCA9IDE7CisKKyAgICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBTdXBwb3J0X1NRTC5sb2FkRHJpdmVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uID0gU3VwcG9ydF9TUUwuZ2V0Q29ubmVjdGlvbigpOworICAgICAgICAgICAgbWV0YSA9IGNvbm4uZ2V0TWV0YURhdGEoKTsKKyAgICAgICAgICAgIHN0YXRlbWVudCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBzdGF0ZW1lbnRGb3J3YXJkID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoCisgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5UWVBFX0ZPUldBUkRfT05MWSwKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0LkNPTkNVUl9SRUFEX09OTFkpOworICAgICAgICAgICAgY3JlYXRlVGVzdFRhYmxlcygpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFcnJvciBpbiB0ZXN0IHNldHVwOiAiK2UuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uID0gU3VwcG9ydF9TUUwuZ2V0Q29ubmVjdGlvbigpOworICAgICAgICAgICAgbWV0YSA9IGNvbm4uZ2V0TWV0YURhdGEoKTsKKyAgICAgICAgICAgIHN0YXRlbWVudCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICBkZWxldGVUZXN0VGFibGVzKCk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVycm9yIGluIHRlYXJkb3duOiAiK2UuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY29ubi5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZVRlc3RUYWJsZXMoKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHVzZXJUYWIgPSBtZXRhLmdldFRhYmxlcyhudWxsLCBudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHVzZXJUYWIubmV4dCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdGFibGVOYW1lID0gdXNlclRhYi5nZXRTdHJpbmcoIlRBQkxFX05BTUUiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YWJsZU5hbWUuZXF1YWxzKERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRTEpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0YWJsZU5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTMpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEUzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGFibGVOYW1lLmVxdWFscyhWSUVXX05BTUUpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRFJPUF9WSUVXX1FVRVJZKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB1c2VyVGFiLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEUzKTsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkNSRUFURV9UQUJMRTEpOworICAgICAgICAgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShDUkVBVEVfVklFV19RVUVSWSk7CisgICAgICAgICAgICAgICAgICAgIG1ldGEgPSBjb25uLmdldE1ldGFEYXRhKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTUUxFeGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwcml2YXRlIHZvaWQgZGVsZXRlVGVzdFRhYmxlcygpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRTEpOworICAgICAgICAgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRTMpOworICAgICAgICAgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEUk9QX1ZJRVdfUVVFUlkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU1FMRXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGlmICghIGNvbm4uaXNDbG9zZWQoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgY29ubi5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAvKgorICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY29ubiA9IFN1cHBvcnRfU1FMLmdldENvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgICAgICBzdGF0ZW1lbnQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgIHN0YXRlbWVudEZvcndhcmQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgKKyAgICAgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5UWVBFX0ZPUldBUkRfT05MWSwKKyAgICAgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldC5DT05DVVJfUkVBRF9PTkxZKTsKKyAgICAgICAgICAgICAgICBtZXRhID0gY29ubi5nZXRNZXRhRGF0YSgpOworCisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoY29ubi5pc0Nsb3NlZCgpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTUUxFeGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgY2F0Y2ggYmxvY2sKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKworICAgIH0KKyAgICAqLworCisgICAgLyoqCisgICAgICoge0BsaW5rIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEgI2dldEJlc3RSb3dJZGVudGlmaWVyKGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGludCwgYm9vbGVhbikgfQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0QmVzdFJvd0lkZW50aWZpZXJMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdJWigpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgUmVzdWx0U2V0IHJlc3VsdCA9IHN0YXRlbWVudEZvcndhcmQuZXhlY3V0ZVF1ZXJ5KCJTRUxFQ1QgKiBGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSk7CisKKyAgICAgICAgLy9VcGRhdGFibGUgUmVzdWx0U2V0IG5vdCBzdXBwb3J0ZWQsIGNvbnZlcnRlZCB0byBub3JtYWwgaW5zZXJ0IHN0YXRlbWVudAorICAgICAgICBzdGF0ZW1lbnRGb3J3YXJkLmV4ZWN1dGVVcGRhdGUoIklOU0VSVCBJTlRPICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgKGlkLCBmaWVsZDEpIFZBTFVFUyggMTIzNDU2NywgJ3Rlc3QxJyk7Iik7CisgICAgICAgIC8qIG5vdCBzdXBwb3J0ZWQKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgIHJlc3VsdC5tb3ZlVG9JbnNlcnRSb3coKTsKKyAgICAgICAgIHJlc3VsdC51cGRhdGVJbnQoImlkIiwgMTIzNDU2Nyk7CisgICAgICAgICByZXN1bHQudXBkYXRlU3RyaW5nKCJmaWVsZDEiLCAidGVzdDEiKTsKKyAgICAgICAgIHJlc3VsdC5pbnNlcnRSb3coKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNRTEV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgIH0KKyAgICAgICAgICovCisKKworICAgICAgICByZXN1bHQuY2xvc2UoKTsKKworICAgICAgICBSZXN1bHRTZXQgcnMgPSBtZXRhLmdldEJlc3RSb3dJZGVudGlmaWVyKG51bGwsIG51bGwsCisgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxLCBEYXRhYmFzZU1ldGFEYXRhLmJlc3RSb3dTZXNzaW9uLAorICAgICAgICAgICAgICAgIHRydWUpOworICAgICAgICBSZXN1bHRTZXRNZXRhRGF0YSByc21kID0gcnMuZ2V0TWV0YURhdGEoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUm93cyBub3Qgb2J0YWluZWQiLCBycy5uZXh0KCkpOworICAgICAgICBpbnQgY29sID0gcnNtZC5nZXRDb2x1bW5Db3VudCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBudW1iZXIgb2YgY29sdW1ucyIsIDgsIGNvbCk7CisgICAgICAgIFN0cmluZ1tdIGNvbHVtbk5hbWVzID0geworICAgICAgICAgICAgICAgICJTQ09QRSIsICJDT0xVTU5fTkFNRSIsICJEQVRBX1RZUEUiLCAiVFlQRV9OQU1FIiwKKyAgICAgICAgICAgICAgICAiQ09MVU1OX1NJWkUiLCAiQlVGRkVSX0xFTkdUSCIsICJERUNJTUFMX0RJR0lUUyIsCisgICAgICAgICAgICAgICAgIlBTRVVET19DT0xVTU4ifTsKKyAgICAgICAgZm9yIChpbnQgYyA9IDE7IGMgPD0gY29sOyArK2MpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGNvbHVtbiBuYW1lIiwgY29sdW1uTmFtZXNbYyAtIDFdLCByc21kCisgICAgICAgICAgICAgICAgICAgIC5nZXRDb2x1bW5OYW1lKGMpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBzY29wZSIsIERhdGFiYXNlTWV0YURhdGEuYmVzdFJvd1Nlc3Npb24sIHJzCisgICAgICAgICAgICAgICAgLmdldFNob3J0KCJTQ09QRSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgY29sdW1uIG5hbWUiLCAiX1JPV0lEXyIsIHJzLmdldFN0cmluZygiQ09MVU1OX05BTUUiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRhdGEgdHlwZSIsIGphdmEuc3FsLlR5cGVzLklOVEVHRVIsIHJzLmdldEludCgiREFUQV9UWVBFIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB0eXBlIG5hbWUiLCAiSU5URUdFUiIsIHJzLmdldFN0cmluZygiVFlQRV9OQU1FIikpOworICAgICAgICBycy5jbG9zZSgpOworCisgICAgIC8vIEV4Y2VwdGlvbiB0ZXN0aW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWV0YS5nZXRDb2x1bW5zKG51bGwsIG51bGwsCisgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEsICIlIik7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEgI2dldENvbHVtbnMoamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKgorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIk5vdCBzdXBwb3J0ZWQgOiBwYXR0ZXJuIHdpdGggJSIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDb2x1bW5zQXJiaXRyYXJ5KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFJlc3VsdFNldCBzZXRBbGxOdWxsID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IHNldE1peGVkID0gbnVsbDsKKyAgICAgICAgUmVzdWx0U2V0IGFsbEFyYml0cmFyeSA9IG51bGw7CisgICAgICAgIFN0cmluZ1tdIHRhYmxlc05hbWUgPSB7RGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxLAorICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFM307CisgICAgICAgIEFycmF5cy5zb3J0KHRhYmxlc05hbWUpOworICAgICAgICBpbnQgc2V0U2l6ZSA9IDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhbGxBcmJpdHJhcnkgPSBtZXRhLmdldENvbHVtbnMoIiUiLCIlIiwiJSIsIiUiKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoYWxsQXJiaXRyYXJ5KTsKKyAgICAgICAgICAgIGNoZWNrQ29sdW1uc1NoYXBlKGFsbEFyYml0cmFyeSk7CisgICAgICAgICAgICBzZXRTaXplID0gY3Jvc3NDaGVja0dldENvbHVtbnNBbmRSZXN1bHRTZXRNZXRhRGF0YShhbGxBcmJpdHJhcnksIGZhbHNlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyg2LCBzZXRTaXplKTsKKworICAgICAgICAgICAgc2V0TWl4ZWQgPSBtZXRhLmdldENvbHVtbnMobnVsbCwgbnVsbCwiJSIsIiUiKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoc2V0TWl4ZWQpOworICAgICAgICAgICAgY2hlY2tDb2x1bW5zU2hhcGUoc2V0TWl4ZWQpOworICAgICAgICAgICAgc2V0U2l6ZSA9IGNyb3NzQ2hlY2tHZXRDb2x1bW5zQW5kUmVzdWx0U2V0TWV0YURhdGEoc2V0TWl4ZWQsIGZhbHNlKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyg2LCBzZXRTaXplKTsKKworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBFeGNlcHRpb24gdGVzdGluZworICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1ldGEuZ2V0Q29sdW1ucyhudWxsLCBudWxsLAorICAgICAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEsICIlIik7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEgI2dldENvbHVtbnMoamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKgorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIk5vdCBzdXBwb3J0ZWQgb3BzIGFwcGxpZWQ6IHRlc3QgZmFpbHMgb24gYXJndW1lbnRzOiAnJywgJycsICclJywgJyUnICIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDb2x1bW5zVGFibGVXaXRoTm9DYXRhbG9nU2NoZW1hKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbnsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUmVzdWx0U2V0IG5vU2NoZW1hVGFibGUgPSBtZXRhLmdldENvbHVtbnMoIiIsICIiLAorICAgICAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEsICJma2V5Iik7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG5vU2NoZW1hVGFibGUpOworICAgICAgICAgICAgbm9TY2hlbWFUYWJsZS5sYXN0KCk7CisgICAgICAgICAgICBpbnQgc2l6ZSA9IG5vU2NoZW1hVGFibGUuZ2V0Um93KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICJEb2VzIG5vdCBzdXBwb3J0IGVtcHR5IHN0cmluZyBhcyBpbnB1dCBwYXJhbWV0ZXIgb3IgV2lsZGNhcmQgJSIsCisgICAgICAgICAgICAgICAgICAgIDEsIHNpemUpOworCisKKworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUmVzdWx0U2V0IG5vU2NoZW1hVGFibGUgPSBtZXRhLmdldENvbHVtbnMoIiIsICIiLAorICAgICAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEsICIlIik7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG5vU2NoZW1hVGFibGUpOworICAgICAgICAgICAgbm9TY2hlbWFUYWJsZS5sYXN0KCk7CisgICAgICAgICAgICBpbnQgc2l6ZSA9IG5vU2NoZW1hVGFibGUuZ2V0Um93KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICJEb2VzIG5vdCBzdXBwb3J0IGVtcHR5IHN0cmluZyBhcyBpbnB1dCBwYXJhbWV0ZXIgb3IgV2lsZGNhcmQgJSIsCisgICAgICAgICAgICAgICAgICAgIDUsIHNpemUpOworCisKKworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUmVzdWx0U2V0IG5vU2NoZW1hVGFibGUgPSBtZXRhLmdldENvbHVtbnMoIiIsICIiLCAiJSIsICIlIik7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG5vU2NoZW1hVGFibGUpOworICAgICAgICAgICAgbm9TY2hlbWFUYWJsZS5sYXN0KCk7CisgICAgICAgICAgICBpbnQgc2l6ZSA9IG5vU2NoZW1hVGFibGUuZ2V0Um93KCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICJEb2VzIG5vdCBzdXBwb3J0IGRvdWJsZSBXaWxkY2FyZCAnJScgYXMgaW5wdXQiLAorICAgICAgICAgICAgICAgICAgICA2LCBzaXplKTsKKworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBFeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtZXRhLmdldENvbHVtbnMobnVsbCwgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxLCAiJSIpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKyAgICB9CisKKworCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSAjZ2V0Q29sdW1ucyhqYXZhLmxhbmcuU3RyaW5nLAorICAgICAqICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgiV2lsZGNhcmQgb3BlcmF0b3IgZG9lcyBub3Qgc2VlbSB3byB3b3JrIGNvcnJlY3RseS4iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0Q29sdW1uc1NwZWNpZmljKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIHRhYmxlc05hbWUgPSB7CisgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxLCBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTN9OworICAgICAgICBTdHJpbmdbXSBmaWVsZHMgPSB7ImlkIiwgImZpZWxkMSIsICJmaWVsZDIiLCAiZmllbGQzIiwgImZrZXkifTsKKyAgICAgICAgU3RyaW5nW10gbnVsbGFibGUgPSB7IllFUyIsICJOTyIsIiJ9OworICAgICAgICBpbnRbXSBudWxsYWJsZUludCA9IHsKKyAgICAgICAgICAgICAgICBEYXRhYmFzZU1ldGFEYXRhLmNvbHVtbk5vTnVsbHMsCisgICAgICAgICAgICAgICAgRGF0YWJhc2VNZXRhRGF0YS5jb2x1bW5OdWxsYWJsZSwKKyAgICAgICAgICAgICAgICBEYXRhYmFzZU1ldGFEYXRhLmNvbHVtbk51bGxhYmxlVW5rbm93bn07CisgICAgICAgIEFycmF5cy5zb3J0KHRhYmxlc05hbWUpOworICAgICAgICBBcnJheXMuc29ydChmaWVsZHMpOworICAgICAgICBBcnJheXMuc29ydChudWxsYWJsZUludCk7CisgICAgICAgIEFycmF5cy5zb3J0KG51bGxhYmxlKTsKKyAgICAgICAgaW50IGNvdW50U2luZ2xlID0gMDsKKyAgICAgICAgaW50IGNvdW50QWxsMSA9IDA7CisgICAgICAgIGludCBjb3VudEFsbDIgPSAwOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBtZXRhLmdldENvbHVtbnMobnVsbCwgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxLCAiJSIpOworCisgICAgICAgICAgICB3aGlsZSAocnMubmV4dCgpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW52YWxpZCB0YWJsZSBuYW1lIiwgQXJyYXlzLmJpbmFyeVNlYXJjaCgKKyAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlc05hbWUsIHJzLmdldFN0cmluZygiVEFCTEVfTkFNRSIpKSA+IC0xKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJJbnZhbGlkIGZpZWxkIG5hbWUiLCBBcnJheXMuYmluYXJ5U2VhcmNoKGZpZWxkcywgcnMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRTdHJpbmcoIkNPTFVNTl9OQU1FIikpID4gLTEpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIkludmFsaWQgbnVsbGFibGUgdmFsdWUiLCBBcnJheXMuYmluYXJ5U2VhcmNoKAorICAgICAgICAgICAgICAgICAgICAgICAgbnVsbGFibGUsIHJzLmdldFN0cmluZygiSVNfTlVMTEFCTEUiKSkgPiAtMSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiSW52YWxpZCBudWxsYWJsZSBjb2RlIiwgQXJyYXlzLmJpbmFyeVNlYXJjaCgKKyAgICAgICAgICAgICAgICAgICAgICAgIG51bGxhYmxlSW50LCBycy5nZXRJbnQoIk5VTExBQkxFIikpID4gLTEpOworICAgICAgICAgICAgICAgIGNvdW50U2luZ2xlKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIk5vdCBhbGwgcmVzdWx0cyBhcmUgZm91bmQiLCA1LCBjb3VudFNpbmdsZSk7CisgICAgICAgICAgICBycy5jbG9zZSgpOworCisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBtZXRhLmdldENvbHVtbnMobnVsbCwgbnVsbCwgIiUiK0RhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEUxLnN1YnN0cmluZygwLCAzKSsiJSIsIiUiICk7CisgICAgICAgICAgICB3aGlsZSAocnMubmV4dCgpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgdGFibGUgbmFtZSIsIEFycmF5cy5iaW5hcnlTZWFyY2godGFibGVzTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHJzLmdldFN0cmluZygiVEFCTEVfTkFNRSIpKSA+IC0xKTsKKyAgICAgICAgICAgICAgICBjb3VudEFsbDErKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiTm90IGFsbCByZXN1bHRzIGFyZSBmb3VuZCIsIDYsIGNvdW50QWxsMSk7CisgICAgICAgICAgICBycy5jbG9zZSgpOworCisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSZXN1bHRTZXQgcnMgPSBtZXRhLmdldENvbHVtbnMobnVsbCwgbnVsbCwgIiVURVNUXyUiLCAiJSIpOworCisgICAgICAgICAgICB3aGlsZSAocnMubmV4dCgpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgdGFibGUgbmFtZSIsIEFycmF5cy5iaW5hcnlTZWFyY2godGFibGVzTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHJzLmdldFN0cmluZygiVEFCTEVfTkFNRSIpKSA+IC0xKTsKKyAgICAgICAgICAgICAgICBjb3VudEFsbDIrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiTm90IGFsbCByZXN1bHRzIGFyZSBmb3VuZCIsIDYsIGNvdW50QWxsMik7CisgICAgICAgICAgICBycy5jbG9zZSgpOworCisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgIC8vIEV4Y2VwdGlvbiBjaGVja2luZworICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1ldGEuZ2V0Q29sdW1ucyhudWxsLCBudWxsLAorICAgICAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEsICIlIik7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisKKyAgICB9CisKKworCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXRDb25uZWN0aW9uKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldENvbm5lY3Rpb24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgY29ubmVjdGlvbiB2YWx1ZSIsIGNvbm4sIG1ldGEuZ2V0Q29ubmVjdGlvbigpKTsKKworICAgICAgICAvLyBFeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb25uZWN0aW9uIGNvbiA9IG1ldGEuZ2V0Q29ubmVjdGlvbigpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShjb24uaXNDbG9zZWQoKSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSAjZ2V0Q3Jvc3NSZWZlcmVuY2UoamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywKKyAgICAgKiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCIoVGlja2V0IDkxKSBUYWJsZXMgYXBwbHkgZm9yZWlnbiBrZXkgY29uc3RyYWludC4gQ2F0YWxvZ3Mgbm90IHN1cHBvcnRlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDcm9zc1JlZmVyZW5jZUxqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZygpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgUmVzdWx0U2V0IHJzID0gbWV0YS5nZXRDcm9zc1JlZmVyZW5jZShjb25uLmdldENhdGFsb2coKSwgbnVsbCwKKyAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTMsIGNvbm4uZ2V0Q2F0YWxvZygpLCBudWxsLAorICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSk7CisgICAgICAgIFJlc3VsdFNldE1ldGFEYXRhIHJzbWQgPSBycy5nZXRNZXRhRGF0YSgpOworICAgICAgICBhc3NlcnRUcnVlKCJSb3dzIGRvIG5vdCBvYnRhaW5lZCIsIHJzLm5leHQoKSk7CisgICAgICAgIGludCBjb2wgPSByc21kLmdldENvbHVtbkNvdW50KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IG51bWJlciBvZiBjb2x1bW5zIiwgMTQsIGNvbCk7CisgICAgICAgIFN0cmluZ1tdIGNvbHVtbk5hbWVzID0geyAiUEtUQUJMRV9DQVQiLCAiUEtUQUJMRV9TQ0hFTSIsCisgICAgICAgICAgICAgICAgIlBLVEFCTEVfTkFNRSIsICJQS0NPTFVNTl9OQU1FIiwgIkZLVEFCTEVfQ0FUIiwKKyAgICAgICAgICAgICAgICAiRktUQUJMRV9TQ0hFTSIsICJGS1RBQkxFX05BTUUiLCAiRktDT0xVTU5fTkFNRSIsICJLRVlfU0VRIiwKKyAgICAgICAgICAgICAgICAiVVBEQVRFX1JVTEUiLCAiREVMRVRFX1JVTEUiLCAiRktfTkFNRSIsICJQS19OQU1FIiwKKyAgICAgICAgICAgICAgICAiREVGRVJSQUJJTElUWSIgfTsKKyAgICAgICAgZm9yIChpbnQgYyA9IDE7IGMgPD0gY29sOyArK2MpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGNvbHVtbiBuYW1lIiwgY29sdW1uTmFtZXNbYyAtIDFdLCByc21kCisgICAgICAgICAgICAgICAgICAgIC5nZXRDb2x1bW5OYW1lKGMpKTsKKyAgICAgICAgfQorLy8gICAgICBUT0RPIGdldENhdGFsb2cgaXMgbm90IHN1cHBvcnRlZAorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcmltYXJ5IGtleSB0YWJsZSBjYXRhbG9nIiwgY29ubi5nZXRDYXRhbG9nKCksCisgICAgICAgICAgICAgICAgcnMuZ2V0U3RyaW5nKCJQS1RBQkxFX0NBVCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJpbWFyeSBrZXkgdGFibGUgc2NoZW1hIiwgIiIsIHJzCisgICAgICAgICAgICAgICAgLmdldFN0cmluZygiUEtUQUJMRV9TQ0hFTSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJpbWFyeSBrZXkgdGFibGUgbmFtZSIsCisgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUzLCBycy5nZXRTdHJpbmcoIlBLVEFCTEVfTkFNRSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJpbWFyeSBrZXkgY29sdW1uIG5hbWUiLCAiZmtleSIsIHJzCisgICAgICAgICAgICAgICAgLmdldFN0cmluZygiUEtDT0xVTU5fTkFNRSIpKTsKKyAgICAgICAgLy8gVE9ETyBnZXRDYXRhbG9nIGlzIG5vdCBzdXBwb3J0ZWQKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgZm9yZWlnbiBrZXkgdGFibGUgY2F0YWxvZyIsIGNvbm4uZ2V0Q2F0YWxvZygpLAorICAgICAgICAgICAgICAgIHJzLmdldFN0cmluZygiRktUQUJMRV9DQVQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGZvcmVpZ24ga2V5IHRhYmxlIHNjaGVtYSIsICIiLCBycworICAgICAgICAgICAgICAgIC5nZXRTdHJpbmcoIkZLVEFCTEVfU0NIRU0iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGZvcmVpZ24ga2V5IHRhYmxlIG5hbWUiLAorICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSwgcnMuZ2V0U3RyaW5nKCJGS1RBQkxFX05BTUUiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGZvcmVpZ24ga2V5IGNvbHVtbiBuYW1lIiwgImZrIiwgcnMKKyAgICAgICAgICAgICAgICAuZ2V0U3RyaW5nKCJGS0NPTFVNTl9OQU1FIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBzZXF1ZW5jZSBudW1iZXIgd2l0aGluIGZvcmVpZ24ga2V5IiwgMSwgcnMKKyAgICAgICAgICAgICAgICAuZ2V0U2hvcnQoIktFWV9TRVEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHVwZGF0ZSBydWxlIHZhbHVlIiwKKyAgICAgICAgICAgICAgICBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5Tm9BY3Rpb24sIHJzCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0U2hvcnQoIlVQREFURV9SVUxFIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBkZWxldGUgcnVsZSB2YWx1ZSIsCisgICAgICAgICAgICAgICAgRGF0YWJhc2VNZXRhRGF0YS5pbXBvcnRlZEtleU5vQWN0aW9uLCBycworICAgICAgICAgICAgICAgICAgICAgICAgLmdldFNob3J0KCJERUxFVEVfUlVMRSIpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiSW5jb3JyZWN0IGZvcmVpZ24ga2V5IG5hbWUiLCBycy5nZXRTdHJpbmcoIkZLX05BTUUiKSk7CisgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCBwcmltYXJ5IGtleSBuYW1lIiwgcnMuZ2V0U3RyaW5nKCJQS19OQU1FIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBkZWZlcnJhYmlsaXR5IiwKKyAgICAgICAgICAgICAgICBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5Tm90RGVmZXJyYWJsZSwgcnMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRTaG9ydCgiREVGRVJSQUJJTElUWSIpKTsKKyAgICAgICAgcnMuY2xvc2UoKTsKKworICAgICAvLyBFeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtZXRhLmdldENyb3NzUmVmZXJlbmNlKGNvbm4uZ2V0Q2F0YWxvZygpLCBudWxsLAorICAgICAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTMsIGNvbm4uZ2V0Q2F0YWxvZygpLCBudWxsLAorICAgICAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICAvLyBFeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtZXRhLmdldENyb3NzUmVmZXJlbmNlKGNvbm4uZ2V0Q2F0YWxvZygpLCBudWxsLAorICAgICAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTMsIGNvbm4uZ2V0Q2F0YWxvZygpLCBudWxsLAorICAgICAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2dldERhdGFiYXNlTWFqb3JWZXJzaW9uKCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJUaWNrZXQgOTgiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGF0YWJhc2VNYWpvclZlcnNpb24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZGN0IGRhdGFiYXNlIG1ham9yIHZlcnNpb24iLCBtZXRhCisgICAgICAgICAgICAgICAgLmdldERhdGFiYXNlTWFqb3JWZXJzaW9uKCkgPj0gMCk7CisKKyAgICAgICAgLy8gRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWV0YS5nZXREYXRhYmFzZU1ham9yVmVyc2lvbigpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0RGF0YWJhc2VNaW5vclZlcnNpb24oKQorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIlRpY2tldCA5OCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREYXRhYmFzZU1pbm9yVmVyc2lvbigpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZGF0YWJhc2UgbWlub3IgdmVyc2lvbiIsIG1ldGEKKyAgICAgICAgICAgICAgICAuZ2V0RGF0YWJhc2VNaW5vclZlcnNpb24oKSA+PSAwKTsKKworICAgICAvLyBFeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtZXRhLmdldERhdGFiYXNlTWlub3JWZXJzaW9uKCk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0RGF0YWJhc2VQcm9kdWN0TmFtZSgpCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgiVGlja2V0IDk4IikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERhdGFiYXNlUHJvZHVjdE5hbWUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGRhdGFiYXNlIHByb2R1Y3QgbmFtZSIsICEiIi5lcXVhbHMobWV0YQorICAgICAgICAgICAgICAgIC5nZXREYXRhYmFzZVByb2R1Y3ROYW1lKCkudHJpbSgpKSk7CisKKyAgICAgICAgLy8gRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWV0YS5nZXREYXRhYmFzZVByb2R1Y3ROYW1lKCk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXREYXRhYmFzZVByb2R1Y3RWZXJzaW9uKCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJUaWNrZXQgOTgiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGF0YWJhc2VQcm9kdWN0VmVyc2lvbigpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZGF0YWJhc2UgcHJvZHVjdCB2ZXJzaW9uIiwgISIiLmVxdWFscyhtZXRhCisgICAgICAgICAgICAgICAgLmdldERhdGFiYXNlUHJvZHVjdFZlcnNpb24oKS50cmltKCkpKTsKKyAgICAgICAgLy8gRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWV0YS5nZXREYXRhYmFzZVByb2R1Y3RWZXJzaW9uKCk7CisgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0RGVmYXVsdFRyYW5zYWN0aW9uSXNvbGF0aW9uKCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJUaWNrZXQgOTgiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RGVmYXVsdFRyYW5zYWN0aW9uSXNvbGF0aW9uKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBkZWZhdWx0TGV2ZWwgPSBtZXRhLmdldERlZmF1bHRUcmFuc2FjdGlvbklzb2xhdGlvbigpOworICAgICAgICBzd2l0Y2ggKGRlZmF1bHRMZXZlbCkgeworICAgICAgICBjYXNlIENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fTk9ORToKKyAgICAgICAgY2FzZSBDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1JFQURfQ09NTUlUVEVEOgorICAgICAgICBjYXNlIENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fUkVBRF9VTkNPTU1JVFRFRDoKKyAgICAgICAgY2FzZSBDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1JFUEVBVEFCTEVfUkVBRDoKKyAgICAgICAgY2FzZSBDb25uZWN0aW9uLlRSQU5TQUNUSU9OX1NFUklBTElaQUJMRToKKyAgICAgICAgICAgIC8vIHRoZXNlIGxldmVscyBhcmUgT0sKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgZmFpbCgiSW5jb3JyZWN0IHZhbHVlIG9mIGRlZmF1bHQgdHJhbnNhY3Rpb24gaXNvbGF0aW9uIGxldmVsIik7CisgICAgICAgIH0KKworICAgICAgICAvLyBFeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtZXRhLmdldERlZmF1bHRUcmFuc2FjdGlvbklzb2xhdGlvbigpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2dldERyaXZlck1ham9yVmVyc2lvbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREcml2ZXJNYWpvclZlcnNpb24oKSAgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBkcml2ZXIgbWFqb3IgdmVyc2lvbiIsIG1ldGEKKyAgICAgICAgICAgICAgICAuZ2V0RHJpdmVyTWFqb3JWZXJzaW9uKCkgPj0gMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXREcml2ZXJNaW5vclZlcnNpb24oKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RHJpdmVyTWlub3JWZXJzaW9uKCkgeworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgZHJpdmVyIG1pbm9yIHZlcnNpb24iLCBtZXRhCisgICAgICAgICAgICAgICAgLmdldERyaXZlck1pbm9yVmVyc2lvbigpID49IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0RHJpdmVyTmFtZSgpCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgiVGlja2V0IDk4IikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldERyaXZlck5hbWUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGRyaXZlck5hbWUgPSBtZXRhLmdldERyaXZlck5hbWUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IGRyaXZlciBuYW1lIiwgZHJpdmVyTmFtZS50cmltKCkuc3RhcnRzV2l0aCgKKyAgICAgICAgICAgICAgICAiU1FMaXRlIikpOworCisgICAgICAgIC8vIEV4Y2VwdGlvbiBjaGVja2luZworICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1ldGEuZ2V0RHJpdmVyTmFtZSgpOworICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2dldERyaXZlclZlcnNpb24oKQorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIlRpY2tldCA5OCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREcml2ZXJWZXJzaW9uKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBkcml2ZXIgdmVyc2lvbiIsICEiIi5lcXVhbHMobWV0YQorICAgICAgICAgICAgICAgIC5nZXREcml2ZXJWZXJzaW9uKCkudHJpbSgpKSk7CisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBtZXRhLmdldERyaXZlclZlcnNpb24oKTsKKyAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAvL29rCisgICAgICAgICB9CisKKyAgICB9CisKKworICAgIEBLbm93bkZhaWx1cmUoIktleXMgYXJlIG5vdCBzdXBwb3J0ZWQ6IFRpY2tldCA5MSIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbXBvcnRlZEtleXNMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmcoKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFJlc3VsdFNldCBycyA9IG1ldGEuZ2V0SW1wb3J0ZWRLZXlzKGNvbm4uZ2V0Q2F0YWxvZygpLCBudWxsLAorICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSk7CisgICAgICAgIFJlc3VsdFNldE1ldGFEYXRhIHJzbWQgPSBycy5nZXRNZXRhRGF0YSgpOworICAgICAgICBhc3NlcnRUcnVlKCJSb3dzIGRvIG5vdCBvYnRhaW5lZCIsIHJzLm5leHQoKSk7CisgICAgICAgIGludCBjb2wgPSByc21kLmdldENvbHVtbkNvdW50KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IG51bWJlciBvZiBjb2x1bW5zIiwgMTQsIGNvbCk7CisgICAgICAgIFN0cmluZ1tdIGNvbHVtbk5hbWVzID0geyAiUEtUQUJMRV9DQVQiLCAiUEtUQUJMRV9TQ0hFTSIsCisgICAgICAgICAgICAgICAgIlBLVEFCTEVfTkFNRSIsICJQS0NPTFVNTl9OQU1FIiwgIkZLVEFCTEVfQ0FUIiwKKyAgICAgICAgICAgICAgICAiRktUQUJMRV9TQ0hFTSIsICJGS1RBQkxFX05BTUUiLCAiRktDT0xVTU5fTkFNRSIsICJLRVlfU0VRIiwKKyAgICAgICAgICAgICAgICAiVVBEQVRFX1JVTEUiLCAiREVMRVRFX1JVTEUiLCAiRktfTkFNRSIsICJQS19OQU1FIiwKKyAgICAgICAgICAgICAgICAiREVGRVJSQUJJTElUWSIgfTsKKyAgICAgICAgZm9yIChpbnQgYyA9IDE7IGMgPD0gY29sOyArK2MpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGNvbHVtbiBuYW1lIiwgY29sdW1uTmFtZXNbYyAtIDFdLCByc21kCisgICAgICAgICAgICAgICAgICAgIC5nZXRDb2x1bW5OYW1lKGMpKTsKKyAgICAgICAgfQorLy8gICAgICBUT0RPIGdldENhdGFsb2cgaXMgbm90IHN1cHBvcnRlZAorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcmltYXJ5IGtleSB0YWJsZSBjYXRhbG9nIiwgY29ubi5nZXRDYXRhbG9nKCksCisgICAgICAgICAgICAgICAgcnMuZ2V0U3RyaW5nKCJQS1RBQkxFX0NBVCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJpbWFyeSBrZXkgdGFibGUgc2NoZW1hIiwgIiIsIHJzCisgICAgICAgICAgICAgICAgLmdldFN0cmluZygiUEtUQUJMRV9TQ0hFTSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJpbWFyeSBrZXkgdGFibGUgbmFtZSIsCisgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUzLCBycy5nZXRTdHJpbmcoIlBLVEFCTEVfTkFNRSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJpbWFyeSBrZXkgY29sdW1uIG5hbWUiLCAiZmtleSIsIHJzCisgICAgICAgICAgICAgICAgLmdldFN0cmluZygiUEtDT0xVTU5fTkFNRSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgZm9yZWlnbiBrZXkgdGFibGUgY2F0YWxvZyIsIGNvbm4uZ2V0Q2F0YWxvZygpLAorICAgICAgICAgICAgICAgIHJzLmdldFN0cmluZygiRktUQUJMRV9DQVQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGZvcmVpZ24ga2V5IHRhYmxlIHNjaGVtYSIsICIiLCBycworICAgICAgICAgICAgICAgIC5nZXRTdHJpbmcoIkZLVEFCTEVfU0NIRU0iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGZvcmVpZ24ga2V5IHRhYmxlIG5hbWUiLAorICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSwgcnMuZ2V0U3RyaW5nKCJGS1RBQkxFX05BTUUiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGZvcmVpZ24ga2V5IGNvbHVtbiBuYW1lIiwgImZrIiwgcnMKKyAgICAgICAgICAgICAgICAuZ2V0U3RyaW5nKCJGS0NPTFVNTl9OQU1FIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBzZXF1ZW5jZSBudW1iZXIgd2l0aGluIGZvcmVpZ24ga2V5IiwgMSwgcnMKKyAgICAgICAgICAgICAgICAuZ2V0U2hvcnQoIktFWV9TRVEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHVwZGF0ZSBydWxlIHZhbHVlIiwKKyAgICAgICAgICAgICAgICBEYXRhYmFzZU1ldGFEYXRhLmltcG9ydGVkS2V5Tm9BY3Rpb24sIHJzCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0U2hvcnQoIlVQREFURV9SVUxFIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBkZWxldGUgcnVsZSB2YWx1ZSIsCisgICAgICAgICAgICAgICAgRGF0YWJhc2VNZXRhRGF0YS5pbXBvcnRlZEtleU5vQWN0aW9uLCBycworICAgICAgICAgICAgICAgICAgICAgICAgLmdldFNob3J0KCJERUxFVEVfUlVMRSIpKTsKKyAvLyAgICAgICBhc3NlcnROb3ROdWxsKCJJbmNvcnJlY3QgZm9yZWlnbiBrZXkgbmFtZSIsIHJzLmdldFN0cmluZygiRktfTkFNRSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJpbWFyeSBrZXkgbmFtZSIsIG51bGwsIHJzCisgICAgICAgICAgICAgICAgLmdldFN0cmluZygiUEtfTkFNRSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgZGVmZXJyYWJpbGl0eSIsCisgICAgICAgICAgICAgICAgRGF0YWJhc2VNZXRhRGF0YS5pbXBvcnRlZEtleU5vdERlZmVycmFibGUsIHJzCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0U2hvcnQoIkRFRkVSUkFCSUxJVFkiKSk7CisgICAgICAgIHJzLmNsb3NlKCk7CisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBtZXRhLmdldEltcG9ydGVkS2V5cyhjb25uLmdldENhdGFsb2coKSwgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSk7CisgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgLy9vaworICAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0TWF4Q3Vyc29yTmFtZUxlbmd0aCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRNYXhDdXJzb3JOYW1lTGVuZ3RoKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBuYW1lTGVuZ3RoID0gbWV0YS5nZXRNYXhDdXJzb3JOYW1lTGVuZ3RoKCk7CisgICAgICAgIGlmIChuYW1lTGVuZ3RoID4gMCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdGF0ZW1lbnQuc2V0Q3Vyc29yTmFtZShuZXcgU3RyaW5nKG5ldyBieXRlW25hbWVMZW5ndGggKyAxXSkpOworICAgICAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIFNRTEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKG5hbWVMZW5ndGggPCAwKSB7CisgICAgICAgICAgICBmYWlsKCJJbmNvcnJlY3QgbGVuZ3RoIG9mIGN1cnNvciBuYW1lIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI2dldEpEQkNNaW5vclZlcnNpb24oKQorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIlRpY2tldCA5OCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRKREJDTWlub3JWZXJzaW9uKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBKREJDIG1pbm9yIHZlcnNpb24iLAorICAgICAgICAgICAgICAgIG1ldGEuZ2V0SkRCQ01pbm9yVmVyc2lvbigpID49IDApOworCisgICAgICAvL0V4Y2VwdGlvbiBjaGVja2luZworICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgbWV0YS5nZXRKREJDTWlub3JWZXJzaW9uKCk7CisgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgLy9vaworICAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXRKREJDTWFqb3JWZXJzaW9uKCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJUaWNrZXQgOTgiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SkRCQ01ham9yVmVyc2lvbigpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgSkRCQyBtYWpvciB2ZXJzaW9uIiwKKyAgICAgICAgICAgICAgICBtZXRhLmdldEpEQkNNYWpvclZlcnNpb24oKSA+PSAwKTsKKworICAgICAgLy9FeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgICB0cnkgeworICAgICAgICAgICAgIG1ldGEuZ2V0SkRCQ01ham9yVmVyc2lvbigpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKworICAgIH0KKworCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXROdW1lcmljRnVuY3Rpb25zKCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJOb3Qgc3VwcG9ydGVkIGZlYXR1cmUsIFRpY2tldCA5OC4gQnJva2VuIGJlY2F1c2UgIisKKyAgICAgICAgICAgICJOVU1FUklDX0ZVTkNUSU9OUyBub3QgY29tcGxldGUuIFdoZW4gZml4ZWQgY2hhbmdlIHRvIEBLbm93bkZhaWx1cmUiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TnVtZXJpY0Z1bmN0aW9ucygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBlc2NhcGVkRnVuY3Rpb25zKE5VTUVSSUNfRlVOQ1RJT05TLCBtZXRhLmdldE51bWVyaWNGdW5jdGlvbnMoKSk7CisKKworICAgICAgLy9FeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgICB0cnkgeworICAgICAgICAgICAgIG1ldGEuZ2V0TnVtZXJpY0Z1bmN0aW9ucygpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEgI2dldFByaW1hcnlLZXlzKGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgiIFRpY2tldCA5MSA6IHJlbGllcyBvbiBub3Qgc3VwcG9ydGVkIGZlYXR1cmVzOiBnZXRDYXRhbG9nLCBrZXlzIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFByaW1hcnlLZXlzTGphdmFfbGFuZ19TdHJpbmdMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nKCkKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBSZXN1bHRTZXQgcnMgPSBtZXRhLmdldFByaW1hcnlLZXlzKGNvbm4uZ2V0Q2F0YWxvZygpLCBudWxsLAorICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSk7CisgICAgICAgIFJlc3VsdFNldE1ldGFEYXRhIHJzbWQgPSBycy5nZXRNZXRhRGF0YSgpOworICAgICAgICBhc3NlcnRUcnVlKCJSb3dzIG5vdCBvYnRhaW5lZCIsIHJzLm5leHQoKSk7CisgICAgICAgIGludCBjb2wgPSByc21kLmdldENvbHVtbkNvdW50KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IG51bWJlciBvZiBjb2x1bW5zIiwgNiwgY29sKTsKKyAgICAgICAgU3RyaW5nW10gY29sdW1uTmFtZXMgPSB7ICJUQUJMRV9DQVQiLCAiVEFCTEVfU0NIRU0iLCAiVEFCTEVfTkFNRSIsCisgICAgICAgICAgICAgICAgIkNPTFVNTl9OQU1FIiwgIktFWV9TRVEiLCAiUEtfTkFNRSIgfTsKKyAgICAgICAgZm9yIChpbnQgYyA9IDE7IGMgPD0gY29sOyArK2MpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGNvbHVtbiBuYW1lIiwgY29sdW1uTmFtZXNbYyAtIDFdLCByc21kCisgICAgICAgICAgICAgICAgICAgIC5nZXRDb2x1bW5OYW1lKGMpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB0YWJsZSBjYXRhbG9ndWUiLCBjb25uLmdldENhdGFsb2coKSwgcnMKKyAgICAgICAgICAgICAgICAuZ2V0U3RyaW5nKCJUQUJMRV9DQVQiKS50b0xvd2VyQ2FzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdGFibGUgc2NoZW1hIiwgIiIsIHJzCisgICAgICAgICAgICAgICAgLmdldFN0cmluZygiVEFCTEVfU0NIRU0iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHRhYmxlIG5hbWUiLCBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEsIHJzCisgICAgICAgICAgICAgICAgLmdldFN0cmluZygiVEFCTEVfTkFNRSIpLnRvTG93ZXJDYXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBjb2x1bW4gbmFtZSIsICJpZCIsIHJzLmdldFN0cmluZygiQ09MVU1OX05BTUUiKQorICAgICAgICAgICAgICAgIC50b0xvd2VyQ2FzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3Qgc2VxdWVuY2UgbnVtYmVyIiwgMSwgcnMuZ2V0U2hvcnQoIktFWV9TRVEiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByaW1hcnkga2V5IG5hbWUiLCAicHJpbWFyeSIsIHJzLmdldFN0cmluZygKKyAgICAgICAgICAgICAgICAiUEtfTkFNRSIpLnRvTG93ZXJDYXNlKCkpOworICAgICAgICBycy5jbG9zZSgpOworCisgICAgICAvL0V4Y2VwdGlvbiBjaGVja2luZworICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgbWV0YS5nZXRQcmltYXJ5S2V5cyhjb25uLmdldENhdGFsb2coKSwgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSk7CisgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgLy9vaworICAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0UmVzdWx0U2V0SG9sZGFiaWxpdHkoKQorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIlRpY2tldCA5OCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRSZXN1bHRTZXRIb2xkYWJpbGl0eSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBpbnQgaGRiID0gbWV0YS5nZXRSZXN1bHRTZXRIb2xkYWJpbGl0eSgpOworICAgICAgICBzd2l0Y2ggKGhkYikgeworICAgICAgICBjYXNlIFJlc3VsdFNldC5IT0xEX0NVUlNPUlNfT1ZFUl9DT01NSVQ6CisgICAgICAgIGNhc2UgUmVzdWx0U2V0LkNMT1NFX0NVUlNPUlNfQVRfQ09NTUlUOgorICAgICAgICAgICAgLy8gdGhlc2UgaG9sZGFiaWxpdGllcyBhcmUgT0sKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgZmFpbCgiSW5jb3JyZWN0IHZhbHVlIG9mIGhvbGRhYmlsaXR5Iik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoIkluY29ycmVjdCByZXN1bHQgc2V0IGhvbGRhYmlsaXR5IiwgbWV0YQorICAgICAgICAgICAgICAgIC5zdXBwb3J0c1Jlc3VsdFNldEhvbGRhYmlsaXR5KGhkYikpOworCisgICAgICAvL0V4Y2VwdGlvbiBjaGVja2luZworICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgbWV0YS5nZXRSZXN1bHRTZXRIb2xkYWJpbGl0eSgpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0U1FMS2V5d29yZHMoKQorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIlRpY2tldCA5OCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTUUxLZXl3b3JkcygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgU1FMIGtleXdvcmRzIiwgISIiLmVxdWFscyhtZXRhLmdldFNRTEtleXdvcmRzKCkKKyAgICAgICAgICAgICAgICAudHJpbSgpKSk7CisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBtZXRhLmdldFNRTEtleXdvcmRzKCk7CisgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgLy9vaworICAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXRTUUxTdGF0ZVR5cGUoKQorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIlRpY2tldCA5OCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTUUxTdGF0ZVR5cGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHR5cGUgPSBtZXRhLmdldFNRTFN0YXRlVHlwZSgpOworICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgICAgY2FzZSBEYXRhYmFzZU1ldGFEYXRhLnNxbFN0YXRlU1FMOTk6CisgICAgICAgIGNhc2UgRGF0YWJhc2VNZXRhRGF0YS5zcWxTdGF0ZVhPcGVuOgorICAgICAgICAgICAgLy8gdGhlc2UgdHlwZXMgYXJlIE9LCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIGZhaWwoIkluY29ycmVjdCBTUUwgc3RhdGUgdHlwZXMiKTsKKyAgICAgICAgfQorCisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBtZXRhLmdldFNRTFN0YXRlVHlwZSgpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0U2NoZW1hcygpCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgiVGlja2V0IDk4IikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFNjaGVtYXMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgUmVzdWx0U2V0IHJzID0gbWV0YS5nZXRTY2hlbWFzKCk7CisgICAgICAgIFJlc3VsdFNldE1ldGFEYXRhIHJzbWQgPSBycy5nZXRNZXRhRGF0YSgpOworICAgICAgICBhc3NlcnRUcnVlKCJSb3dzIGRvIG5vdCBvYnRhaW5lZCIsIHJzLm5leHQoKSk7CisgICAgICAgIGludCBjb2wgPSByc21kLmdldENvbHVtbkNvdW50KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IG51bWJlciBvZiBjb2x1bW5zIiwgMSwgY29sKTsKKyAgICAgICAgU3RyaW5nW10gY29sdW1uTmFtZXMgPSB7ICJUQUJMRV9TQ0hFTSIsICJUQUJMRV9DQVRBTE9HIiB9OworICAgICAgICBmb3IgKGludCBjID0gMTsgYyA8PSBjb2w7ICsrYykgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgY29sdW1uIG5hbWUiLCBjb2x1bW5OYW1lc1tjIC0gMV0sIHJzbWQKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbHVtbk5hbWUoYykpOworICAgICAgICB9CisgICAgICAgIHJzLmNsb3NlKCk7CisKKworICAgICAgLy9FeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgICB0cnkgeworICAgICAgICAgICAgIG1ldGEuZ2V0U2NoZW1hcygpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0U2VhcmNoU3RyaW5nRXNjYXBlKCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJUaWNrZXQgOTgiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0U2VhcmNoU3RyaW5nRXNjYXBlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBzZWFyY2ggc3RyaW5nIGVzY2FwZSIsICEiIi5lcXVhbHMobWV0YQorICAgICAgICAgICAgICAgIC5nZXRTZWFyY2hTdHJpbmdFc2NhcGUoKS50cmltKCkpKTsKKworICAgICAgLy9FeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgICB0cnkgeworICAgICAgICAgICAgIG1ldGEuZ2V0U2VhcmNoU3RyaW5nRXNjYXBlKCk7CisgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgLy9vaworICAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXRTdHJpbmdGdW5jdGlvbnMoKQorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIm5vdCBzdXBwb3J0ZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0U3RyaW5nRnVuY3Rpb25zKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGVzY2FwZWRGdW5jdGlvbnMoU1RSSU5HX0ZVTkNUSU9OUywgbWV0YS5nZXRTdHJpbmdGdW5jdGlvbnMoKSk7CisKKworICAgICAgLy9FeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgICB0cnkgeworICAgICAgICAgICAgIG1ldGEuZ2V0U3RyaW5nRnVuY3Rpb25zKCk7CisgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgLy9vaworICAgICAgICAgfQorCisKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0U3lzdGVtRnVuY3Rpb25zKCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJub3Qgc3VwcG9ydGVkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFN5c3RlbUZ1bmN0aW9ucygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBlc2NhcGVkRnVuY3Rpb25zKFNZU1RFTV9GVU5DVElPTlMsIG1ldGEuZ2V0U3lzdGVtRnVuY3Rpb25zKCkpOworCisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBtZXRhLmdldFN5c3RlbUZ1bmN0aW9ucygpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKworICAgIH0KKworCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXRUYWJsZVR5cGVzKCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJUaWNrZXQgOTgiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0VGFibGVUeXBlcygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdHJpbmdbXSB0YWJsZVR5cGVzID0geyAiTE9DQUwgVEVNUE9SQVJZIiwgIlRBQkxFIiwgIlZJRVciIH07CisgICAgICAgIFJlc3VsdFNldCBycyA9IG1ldGEuZ2V0VGFibGVUeXBlcygpOworCisgICAgICAgIHdoaWxlIChycy5uZXh0KCkpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIldyb25nIHRhYmxlIHR5cGUiLCBBcnJheXMuYmluYXJ5U2VhcmNoKHRhYmxlVHlwZXMsIHJzCisgICAgICAgICAgICAgICAgICAgIC5nZXRTdHJpbmcoIlRBQkxFX1RZUEUiKSkgPiAtMSk7CisgICAgICAgIH0KKyAgICAgICAgcnMuY2xvc2UoKTsKKworCisgICAgICAvL0V4Y2VwdGlvbiBjaGVja2luZworICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgbWV0YS5nZXRUYWJsZVR5cGVzKCk7CisgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgLy9vaworICAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSAjZ2V0VGFibGVzKGphdmEubGFuZy5TdHJpbmcsCisgICAgICogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmdbXSkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJJZiBubyBzY2hlbWEgaXMgYXNzb2NpYXRlZDogcmV0dXJucyBlbXB0eSBzdHJpbmcgd2hlcmUgYWN0dWFsbHkgbnVsbCBiZSByZXR1cm5lZD8uIFRpY2tldCA5OCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRUYWJsZXNMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nTGphdmFfbGFuZ19TdHJpbmckTGphdmFfbGFuZ19TdHJpbmcoKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIHRhYmxlc05hbWUgPSB7CisgICAgICAgICAgICAgICAgVklFV19OQU1FLCBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEsCisgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUzfTsKKyAgICAgICAgU3RyaW5nW10gdGFibGVzVHlwZSA9IHsiVEFCTEUiLCAiVklFVyJ9OworICAgICAgICBBcnJheXMuc29ydCh0YWJsZXNOYW1lKTsKKyAgICAgICAgQXJyYXlzLnNvcnQodGFibGVzVHlwZSk7CisKKyAgICAgICAgLy8gY2FzZSAxLiBnZXQgYWxsIHRhYmxlcy4gVGhlcmUgYXJlIHR3byB0YWJsZXMgYW5kIG9uZSB2aWV3IGluIHRoZQorICAgICAgICAvLyBkYXRhYmFzZQorICAgICAgICBSZXN1bHRTZXQgcnMgPSBtZXRhLmdldFRhYmxlcyhudWxsLCBudWxsLCBudWxsLCBudWxsKTsKKyAgICAgICAgd2hpbGUgKHJzLm5leHQoKSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgdGFibGUgbmFtZSIsIEFycmF5cy5iaW5hcnlTZWFyY2godGFibGVzTmFtZSwgcnMKKyAgICAgICAgICAgICAgICAgICAgLmdldFN0cmluZygiVEFCTEVfTkFNRSIpKSA+IC0xKTsKKyAgICAgICAgLy9ObyBTY2hlbWEgYXNzb2NpYXRlZAorICAgICAgICAgICAgYXNzZXJ0TnVsbCgiV3JvbmcgdGFibGUgc2NoZW1hOiAiK3JzLmdldFN0cmluZygiVEFCTEVfU0NIRU0iKSwgcnMuZ2V0U3RyaW5nKCJUQUJMRV9TQ0hFTSIpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIldyb25nIHRhYmxlIHR5cGUiLCBBcnJheXMuYmluYXJ5U2VhcmNoKHRhYmxlc1R5cGUsIHJzCisgICAgICAgICAgICAgICAgICAgIC5nZXRTdHJpbmcoIlRBQkxFX1RZUEUiKSkgPiAtMSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHBhcmFtZXRlciBSRU1BUktTIiwgIiIsIHJzLmdldFN0cmluZygiUkVNQVJLUyIpKTsKKyAgICAgICAgfQorICAgICAgICBycy5jbG9zZSgpOworCisgICAgICAgIC8vIGNhc2UgMi4gZ2V0IHRhYmxlcyB3aXRoIHNwZWNpZmllZCB0eXBlcy4gVGhlcmUgYXJlIG5vIHRhYmxlcyBvZiBzdWNoCisgICAgICAgIC8vIHR5cGVzCisgICAgICAgIHJzID0gbWV0YS5nZXRUYWJsZXMoY29ubi5nZXRDYXRhbG9nKCksIG51bGwsIG51bGwsIG5ldyBTdHJpbmdbXSB7CisgICAgICAgICAgICAgICAgIlNZU1RFTSBUQUJMRSIsICJMT0NBTCBURU1QT1JBUlkiIH0pOworICAgICAgICBhc3NlcnRGYWxzZSgiU29tZSB0YWJsZXMgZXhpc3QiLCBycy5uZXh0KCkpOworICAgICAgICBycy5jbG9zZSgpOworCisgICAgICAgIC8vIGNhc2UgMy4gZ2V0IHRhYmxlcyB3aXRoIHNwZWNpZmllZCB0eXBlcy4gVGhlcmUgaXMgYSB0YWJsZSBvZiBzdWNoCisgICAgICAgIC8vIHR5cGVzCisgICAgICAgIHJzID0gbWV0YS5nZXRUYWJsZXMoY29ubi5nZXRDYXRhbG9nKCksIG51bGwsIG51bGwsIG5ldyBTdHJpbmdbXSB7CisgICAgICAgICAgICAgICAgIlZJRVciLCAiTE9DQUwgVEVNUE9SQVJZIiB9KTsKKworICAgICAgICBhc3NlcnRUcnVlKCJObyB0YWJsZXMgZXhpc3QiLCBycy5uZXh0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHRhYmxlIG5hbWUiLCBWSUVXX05BTUUsIHJzLmdldFN0cmluZygiVEFCTEVfTkFNRSIpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiV3JvbmcgdGFibGUgc2NoZW1hOiAiK3JzLmdldFN0cmluZygiVEFCTEVfU0NIRU0iKSwgcnMuZ2V0U3RyaW5nKCJUQUJMRV9TQ0hFTSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB0YWJsZSB0eXBlIiwgIlZJRVciLCBycy5nZXRTdHJpbmcoIlRBQkxFX1RZUEUiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcGFyYW1ldGVyIFJFTUFSS1MiLCAiIiwgcnMuZ2V0U3RyaW5nKCJSRU1BUktTIikpOworICAgICAgICBhc3NlcnRGYWxzZSgiV3Jvbmcgc2l6ZSBvZiByZXN1bHQgc2V0IiwgcnMubmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNvbWUgdGFibGVzIGV4aXN0IiwgcnMubmV4dCgpKTsKKyAgICAgICAgcnMuY2xvc2UoKTsKKworICAgICAgICAvLyBjYXNlIDQuIGdldCBhbGwgdGFibGVzIHVzaW5nIHRhYmxlcyBwYXR0ZXJuLgorICAgICAgICAvLyBUaGVyZSBhcmUgdHdvIHRhYmxlcyBhbmQgb25lIHZpZXcgaW4gdGhlIGRhdGFiYXNlCisgICAgICAgIHJzID0gbWV0YS5nZXRUYWJsZXMobnVsbCwgbnVsbCwgIiUiLCBudWxsKTsKKworICAgICAgICB3aGlsZSAocnMubmV4dCgpKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyB0YWJsZSBuYW1lIiwgQXJyYXlzLmJpbmFyeVNlYXJjaCh0YWJsZXNOYW1lLCBycworICAgICAgICAgICAgICAgICAgICAuZ2V0U3RyaW5nKCJUQUJMRV9OQU1FIikpID4gLTEpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiV3JvbmcgdGFibGUgc2NoZW1hICIsIHJzLmdldFN0cmluZygiVEFCTEVfU0NIRU0iKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyB0YWJsZSB0eXBlIiwgQXJyYXlzLmJpbmFyeVNlYXJjaCh0YWJsZXNUeXBlLCBycworICAgICAgICAgICAgICAgICAgICAuZ2V0U3RyaW5nKCJUQUJMRV9UWVBFIikpID4gLTEpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYXJhbWV0ZXIgUkVNQVJLUyIsICIiLCBycy5nZXRTdHJpbmcoIlJFTUFSS1MiKSk7CisgICAgICAgIH0KKyAgICAgICAgcnMuY2xvc2UoKTsKKworCisgICAgICAvL0V4Y2VwdGlvbiBjaGVja2luZworICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgbWV0YS5nZXRUYWJsZXMobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgLy9vaworICAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXRUaW1lRGF0ZUZ1bmN0aW9ucygpCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgibm90IHN1cHBvcnRlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRUaW1lRGF0ZUZ1bmN0aW9ucygpIHRocm93cyBTUUxFeGNlcHRpb24geworCisgICAgICAgIGVzY2FwZWRGdW5jdGlvbnMoVElNRURBVEVfRlVOQ1RJT05TLCBtZXRhLmdldFRpbWVEYXRlRnVuY3Rpb25zKCkpOworCisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBtZXRhLmdldFRpbWVEYXRlRnVuY3Rpb25zKCk7CisgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgLy9vaworICAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjZ2V0VHlwZUluZm8oKQorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIm5vdCBzdXBwb3J0ZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0VHlwZUluZm8oKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgaW5zZXJ0TmV3UmVjb3JkKCk7CisKKyAgICAgICAgUmVzdWx0U2V0IHJzID0gbWV0YS5nZXRUeXBlSW5mbygpOworCisgICAgICAgIGZpbmFsIFN0cmluZ1tdIG5hbWVzID0geyAiVFlQRV9OQU1FIiwgIkRBVEFfVFlQRSIsICJQUkVDSVNJT04iLAorICAgICAgICAgICAgICAgICJMSVRFUkFMX1BSRUZJWCIsICJMSVRFUkFMX1NVRkZJWCIsICJDUkVBVEVfUEFSQU1TIiwKKyAgICAgICAgICAgICAgICAiTlVMTEFCTEUiLCAiQ0FTRV9TRU5TSVRJVkUiLCAiU0VBUkNIQUJMRSIsCisgICAgICAgICAgICAgICAgIlVOU0lHTkVEX0FUVFJJQlVURSIsICJGSVhFRF9QUkVDX1NDQUxFIiwgIkFVVE9fSU5DUkVNRU5UIiwKKyAgICAgICAgICAgICAgICAiTE9DQUxfVFlQRV9OQU1FIiwgIk1JTklNVU1fU0NBTEUiLCAiTUFYSU1VTV9TQ0FMRSIsCisgICAgICAgICAgICAgICAgIlNRTF9EQVRBX1RZUEUiLCAiU1FMX0RBVEVUSU1FX1NVQiIsICJOVU1fUFJFQ19SQURJWCIgfTsKKyAgICAgICAgQXJyYXlzLnNvcnQobmFtZXMpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcnMuZ2V0TWV0YURhdGEoKS5nZXRDb2x1bW5Db3VudCgpOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIndyb25nIGNvbHVtbiB3YXMgcmV0dXJuIiwgQXJyYXlzLmJpbmFyeVNlYXJjaChuYW1lcywgcnMKKyAgICAgICAgICAgICAgICAgICAgLmdldE1ldGFEYXRhKCkuZ2V0Q29sdW1uTmFtZShpICsgMSkpID4gLTEpOworICAgICAgICB9CisKKyAgICAgICAgaW50W10gdHlwZXMgPSB7IFR5cGVzLkFSUkFZLCBUeXBlcy5CSUdJTlQsIFR5cGVzLkJJTkFSWSwgVHlwZXMuQklULAorICAgICAgICAgICAgICAgIFR5cGVzLkJMT0IsIFR5cGVzLkJPT0xFQU4sIFR5cGVzLkNIQVIsIFR5cGVzLkNMT0IsCisgICAgICAgICAgICAgICAgVHlwZXMuREFUQUxJTkssIFR5cGVzLkRBVEUsIFR5cGVzLkRFQ0lNQUwsIFR5cGVzLkRJU1RJTkNULAorICAgICAgICAgICAgICAgIFR5cGVzLkRPVUJMRSwgVHlwZXMuRkxPQVQsIFR5cGVzLklOVEVHRVIsIFR5cGVzLkpBVkFfT0JKRUNULAorICAgICAgICAgICAgICAgIFR5cGVzLkxPTkdWQVJCSU5BUlksIFR5cGVzLkxPTkdWQVJDSEFSLCBUeXBlcy5OVUxMLAorICAgICAgICAgICAgICAgIFR5cGVzLk5VTUVSSUMsIFR5cGVzLk9USEVSLCBUeXBlcy5SRUFMLCBUeXBlcy5SRUYsCisgICAgICAgICAgICAgICAgVHlwZXMuU01BTExJTlQsIFR5cGVzLlNUUlVDVCwgVHlwZXMuVElNRSwgVHlwZXMuVElNRVNUQU1QLAorICAgICAgICAgICAgICAgIFR5cGVzLlRJTllJTlQsIFR5cGVzLlZBUkJJTkFSWSwgVHlwZXMuVkFSQ0hBUiB9OworICAgICAgICBBcnJheXMuc29ydCh0eXBlcyk7CisKKyAgICAgICAgd2hpbGUgKHJzLm5leHQoKSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgid3JvbmcgdHlwZSB3YXMgcmV0dXJuICIsIEFycmF5cy5iaW5hcnlTZWFyY2godHlwZXMsIHJzCisgICAgICAgICAgICAgICAgICAgIC5nZXRJbnQoIkRBVEFfVFlQRSIpKSA+IC0xKTsKKyAgICAgICAgfQorICAgICAgICBycy5jbG9zZSgpOworCisgICAgICAvL0V4Y2VwdGlvbiBjaGVja2luZworICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgbWV0YS5nZXRUeXBlSW5mbygpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKworICAgIH0KKworCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNnZXRVUkwoKQorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIlRpY2tldCA5OCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRVUkwoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB1cmwiLCBTdXBwb3J0X1NRTC5zcWxVcmwsIG1ldGEuZ2V0VVJMKCkpOworCisgICAgICAvL0V4Y2VwdGlvbiBjaGVja2luZworICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgbWV0YS5nZXRVUkwoKTsKKyAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAvL29rCisgICAgICAgICB9CisKKyAgICB9CisKKyAgICBAS25vd25GYWlsdXJlKCJUaWNrZXQgOTgiKQorICAgIHB1YmxpYyB2b2lkIHMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdXNlciBuYW1lIiwgU3VwcG9ydF9TUUwuc3FsVXNlciwgbWV0YS5nZXRVc2VyTmFtZSgpKTsKKworICAgICAgLy9FeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgICB0cnkgeworICAgICAgICAgICAgIG1ldGEuZ2V0VXNlck5hbWUoKTsKKyAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAvL29rCisgICAgICAgICB9CisKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjaW5zZXJ0c0FyZURldGVjdGVkKGludCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJUaWNrZXQgOTgiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RfaW5zZXJ0c0FyZURldGVjdGVkSSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZSgKKyAgICAgICAgICAgICAgICAidmlzaWJsZSByb3cgaW5zZXJ0IGNhbiBiZSBkZXRlY3RlZCBmb3IgVFlQRV9GT1JXQVJEX09OTFkgdHlwZSIsCisgICAgICAgICAgICAgICAgbWV0YS5pbnNlcnRzQXJlRGV0ZWN0ZWQoUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZKSk7CisgICAgICAgIGFzc2VydEZhbHNlKAorICAgICAgICAgICAgICAgICJ2aXNpYmxlIHJvdyBpbnNlcnQgY2FuIGJlIGRldGVjdGVkIGZvciBUWVBFX1NDUk9MTF9JTlNFTlNJVElWRSB0eXBlIiwKKyAgICAgICAgICAgICAgICBtZXRhLmluc2VydHNBcmVEZXRlY3RlZChSZXN1bHRTZXQuVFlQRV9TQ1JPTExfSU5TRU5TSVRJVkUpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgICAgICAgInZpc2libGUgcm93IGluc2VydCBjYW4gYmUgZGV0ZWN0ZWQgZm9yIFRZUEVfU0NST0xMX1NFTlNJVElWRSB0eXBlIiwKKyAgICAgICAgICAgICAgICBtZXRhLmluc2VydHNBcmVEZXRlY3RlZChSZXN1bHRTZXQuVFlQRV9TQ1JPTExfU0VOU0lUSVZFKSk7CisKKworICAgICAgLy9FeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgICB0cnkgeworICAgICAgICAgICAgIG1ldGEuaW5zZXJ0c0FyZURldGVjdGVkKFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkUpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjaXNSZWFkT25seSgpCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgiVGlja2V0IDk4IikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2lzUmVhZE9ubHkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoImRhdGFiYXNlIGlzIG5vdCByZWFkLW9ubHkiLCBtZXRhLmlzUmVhZE9ubHkoKSk7CisKKworICAgICAgLy9FeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgICB0cnkgeworICAgICAgICAgICAgIG1ldGEuaXNSZWFkT25seSgpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI290aGVyc0RlbGV0ZXNBcmVWaXNpYmxlKGludCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJUaWNrZXQgOTgiKQorICAgIHB1YmxpYyB2b2lkIHRlc3Rfb3RoZXJzRGVsZXRlc0FyZVZpc2libGVJKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKAorICAgICAgICAgICAgICAgICJkZWxldGVzIG1hZGUgYnkgb3RoZXJzIGFyZSB2aXNpYmxlIGZvciBUWVBFX0ZPUldBUkRfT05MWSB0eXBlIiwKKyAgICAgICAgICAgICAgICBtZXRhLm90aGVyc0RlbGV0ZXNBcmVWaXNpYmxlKFJlc3VsdFNldC5UWVBFX0ZPUldBUkRfT05MWSkpOworICAgICAgICBhc3NlcnRGYWxzZSgKKyAgICAgICAgICAgICAgICAiZGVsZXRlcyBtYWRlIGJ5IG90aGVycyBhcmUgdmlzaWJsZSBmb3IgVFlQRV9TQ1JPTExfSU5TRU5TSVRJVkUgdHlwZSIsCisgICAgICAgICAgICAgICAgbWV0YS5vdGhlcnNEZWxldGVzQXJlVmlzaWJsZShSZXN1bHRTZXQuVFlQRV9TQ1JPTExfSU5TRU5TSVRJVkUpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgICAgICAgImRlbGV0ZXMgbWFkZSBieSBvdGhlcnMgYXJlIHZpc2libGUgZm9yIFRZUEVfU0NST0xMX1NFTlNJVElWRSB0eXBlIiwKKyAgICAgICAgICAgICAgICBtZXRhLm90aGVyc0RlbGV0ZXNBcmVWaXNpYmxlKFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkUpKTsKKworCisgICAgICAvL0V4Y2VwdGlvbiBjaGVja2luZworICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoImluc2VydHMgbWFkZSBieSBvdGhlcnMgYXJlIHZpc2libGUgZm9yIHVua25vd24gdHlwZSIsIG1ldGEKKyAgICAgICAgICAgICAgICAgICAgIC5vdGhlcnNEZWxldGVzQXJlVmlzaWJsZShSZXN1bHRTZXQuQ09OQ1VSX1JFQURfT05MWSkpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjb3RoZXJzSW5zZXJ0c0FyZVZpc2libGUoaW50KQorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIlRpY2tldCA5OCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9vdGhlcnNJbnNlcnRzQXJlVmlzaWJsZUkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgICAgICAgImluc2VydHMgbWFkZSBieSBvdGhlcnMgYXJlIHZpc2libGUgZm9yIFRZUEVfRk9SV0FSRF9PTkxZIHR5cGUiLAorICAgICAgICAgICAgICAgIG1ldGEub3RoZXJzSW5zZXJ0c0FyZVZpc2libGUoUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZKSk7CisgICAgICAgIGFzc2VydEZhbHNlKAorICAgICAgICAgICAgICAgICJpbnNlcnRzIG1hZGUgYnkgb3RoZXJzIGFyZSB2aXNpYmxlIGZvciBUWVBFX1NDUk9MTF9JTlNFTlNJVElWRSB0eXBlIiwKKyAgICAgICAgICAgICAgICBtZXRhLm90aGVyc0luc2VydHNBcmVWaXNpYmxlKFJlc3VsdFNldC5UWVBFX1NDUk9MTF9JTlNFTlNJVElWRSkpOworICAgICAgICBhc3NlcnRGYWxzZSgKKyAgICAgICAgICAgICAgICAiaW5zZXJ0cyBtYWRlIGJ5IG90aGVycyBhcmUgdmlzaWJsZSBmb3IgVFlQRV9TQ1JPTExfU0VOU0lUSVZFIHR5cGUiLAorICAgICAgICAgICAgICAgIG1ldGEub3RoZXJzSW5zZXJ0c0FyZVZpc2libGUoUmVzdWx0U2V0LlRZUEVfU0NST0xMX1NFTlNJVElWRSkpOworCisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBhc3NlcnRGYWxzZSgiaW5zZXJ0cyBtYWRlIGJ5IG90aGVycyBhcmUgdmlzaWJsZSBmb3IgdW5rbm93biB0eXBlIiwgbWV0YQorICAgICAgICAgICAgICAgICAgICAgLm90aGVyc0luc2VydHNBcmVWaXNpYmxlKFJlc3VsdFNldC5DT05DVVJfUkVBRF9PTkxZKSk7CisgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgLy9vaworICAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNvdGhlcnNVcGRhdGVzQXJlVmlzaWJsZShpbnQpCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgiVGlja2V0IDk4IikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X290aGVyc1VwZGF0ZXNBcmVWaXNpYmxlSSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZSgKKyAgICAgICAgICAgICAgICAidXBkYXRlcyBtYWRlIGJ5IG90aGVycyBhcmUgdmlzaWJsZSBmb3IgVFlQRV9GT1JXQVJEX09OTFkgdHlwZSIsCisgICAgICAgICAgICAgICAgbWV0YS5vdGhlcnNVcGRhdGVzQXJlVmlzaWJsZShSZXN1bHRTZXQuVFlQRV9GT1JXQVJEX09OTFkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgICAgICAgInVwZGF0ZXMgbWFkZSBieSBvdGhlcnMgYXJlIHZpc2libGUgZm9yIFRZUEVfU0NST0xMX0lOU0VOU0lUSVZFIHR5cGUiLAorICAgICAgICAgICAgICAgIG1ldGEub3RoZXJzVXBkYXRlc0FyZVZpc2libGUoUmVzdWx0U2V0LlRZUEVfU0NST0xMX0lOU0VOU0lUSVZFKSk7CisgICAgICAgIGFzc2VydEZhbHNlKAorICAgICAgICAgICAgICAgICJ1cGRhdGVzIG1hZGUgYnkgb3RoZXJzIGFyZSB2aXNpYmxlIGZvciBUWVBFX1NDUk9MTF9TRU5TSVRJVkUgdHlwZSIsCisgICAgICAgICAgICAgICAgbWV0YS5vdGhlcnNVcGRhdGVzQXJlVmlzaWJsZShSZXN1bHRTZXQuVFlQRV9TQ1JPTExfU0VOU0lUSVZFKSk7CisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoInVwZGF0ZXMgbWFkZSBieSBvdGhlcnMgYXJlIHZpc2libGUgZm9yIHVua25vd24gdHlwZSIsIG1ldGEKKyAgICAgICAgICAgICAgICAgICAgIC5vdGhlcnNVcGRhdGVzQXJlVmlzaWJsZShSZXN1bHRTZXQuQ09OQ1VSX1JFQURfT05MWSkpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI3N0b3Jlc01peGVkQ2FzZVF1b3RlZElkZW50aWZpZXJzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N0b3Jlc01peGVkQ2FzZVF1b3RlZElkZW50aWZpZXJzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBxdW90ZSA9IG1ldGEuZ2V0SWRlbnRpZmllclF1b3RlU3RyaW5nKCk7CisKKworCisgICAgICAgIGluc2VydE5ld1JlY29yZCgpOworCisgICAgICAgIFN0cmluZyBzZWxlY3RRdWVyeSA9ICJTRUxFQ1QgIiArIHF1b3RlICsgImZpZUxEMSIgKyBxdW90ZSArICIgRlJPTSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTE7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlUXVlcnkoc2VsZWN0UXVlcnkpOworICAgICAgICAgICAgaWYgKCFtZXRhLnN0b3Jlc01peGVkQ2FzZUlkZW50aWZpZXJzKCkpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJtaXhlZCBjYXNlIGlzIHN1cHBvcnRlZCIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaWYgKG1ldGEuc3RvcmVzTWl4ZWRDYXNlUXVvdGVkSWRlbnRpZmllcnMoKSkgeworICAgICAgICAgICAgICAgIGZhaWwoInF1b3RlZCBjYXNlIGlzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIC8qCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBtZXRhLnN0b3Jlc01peGVkQ2FzZUlkZW50aWZpZXJzKCk7CisgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgLy9vaworICAgICAgICAgfQorCisgICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgbWV0YS5zdG9yZXNNaXhlZENhc2VRdW90ZWRJZGVudGlmaWVycygpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKworICAgIH0KKworICAgIEBLbm93bkZhaWx1cmUoIlRpY2tldCA5OCIpCisgICAgcHVibGljIHZvaWQgdGVzdEdldElkZW50aWZpZXJRdW90ZVN0cmluZygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgIGFzc2VydE5vdE51bGwoCisgICAgICAgICAgICAgICBtZXRhLmdldElkZW50aWZpZXJRdW90ZVN0cmluZygpCisgICAgICAgICAgICAgICApOworCisgICAgICAgLy9FeGNlcHRpb24gdGVzdAorICAgICAgIC8qCisgICAgICAgY29ubi5jbG9zZSgpOworICAgICAgIHRyeSB7CisgICAgICAgICAgIG1ldGEuZ2V0SWRlbnRpZmllclF1b3RlU3RyaW5nKCk7CisgICAgICAgICAgIGZhaWwoIlNob3VsZCB0aHJvdyBleGNlcHRpb24iKTsKKyAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAvL29rCisgICAgICAgfQorICAgICAgICovCisKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjc3VwcG9ydHNDb2x1bW5BbGlhc2luZygpCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgibm90IHN1cHBvcnRlZC4gU1FMRXhjZXB0aW9uIGNoZWNraW5nIHRlc3QgZmFpbHMiKQorICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNDb2x1bW5BbGlhc2luZygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBpbnNlcnROZXdSZWNvcmQoKTsKKworICAgICAgICBTdHJpbmcgYWxpYXMgPSAiRklFTEQzIjsKKyAgICAgICAgU3RyaW5nIHNlbGVjdFF1ZXJ5ID0gIlNFTEVDVCBmaWVsZDEgQVMgIiArIGFsaWFzICsgIiBGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMTsKKyAgICAgICAgUmVzdWx0U2V0IHJzID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeShzZWxlY3RRdWVyeSk7CisgICAgICAgIFJlc3VsdFNldE1ldGFEYXRhIHJzbWQgPSBycy5nZXRNZXRhRGF0YSgpOworCisgICAgICAgIGlmIChtZXRhLnN1cHBvcnRzQ29sdW1uQWxpYXNpbmcoKSkgeworICAgICAgICAgICAgLy8gc3VwcG9ydHMgYWxpYXNpbmcKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgY291bnQgb2YgY29sdW1ucyIsIDEsIHJzbWQuZ2V0Q29sdW1uQ291bnQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkFsaWFzaW5nIGlzIG5vdCBzdXBwb3J0ZWQiLCBhbGlhcywgcnNtZAorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29sdW1uTGFiZWwoMSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gZG9lc24ndCBzdXBwb3J0IGFsaWFzaW5nCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkFsaWFzaW5nIGlzIHN1cHBvcnRlZCIsIDAsIHJzbWQuZ2V0Q29sdW1uQ291bnQoKSk7CisgICAgICAgIH0KKyAgICAgICAgcnMuY2xvc2UoKTsKKworICAgICAgLy9FeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgICB0cnkgeworICAgICAgICAgICAgIG1ldGEuc3VwcG9ydHNDb2x1bW5BbGlhc2luZygpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKworICAgIH0KKworCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNzdXBwb3J0c0V4cHJlc3Npb25zSW5PcmRlckJ5KCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJleGNlcHRpb24gdGVzdCBmYWlscyIpCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c0V4cHJlc3Npb25zSW5PcmRlckJ5KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGluc2VydE5ld1JlY29yZCgpOworCisgICAgICAgIFN0cmluZyBzZWxlY3RRdWVyeSA9ICJTRUxFQ1QgKiBGUk9NICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgT1JERVIgQlkgaWQgKyBmaWVsZDMiOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KHNlbGVjdFF1ZXJ5KTsKKyAgICAgICAgICAgIGlmICghbWV0YS5zdXBwb3J0c0V4cHJlc3Npb25zSW5PcmRlckJ5KCkpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJFeHByZXNzaW9ucyBpbiBvcmRlciBieSBhcmUgc3VwcG9ydGVkIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAobWV0YS5zdXBwb3J0c0V4cHJlc3Npb25zSW5PcmRlckJ5KCkpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJFeHByZXNzaW9ucyBpbiBvcmRlciBieSBhcmUgbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBtZXRhLnN1cHBvcnRzRXhwcmVzc2lvbnNJbk9yZGVyQnkoKTsKKyAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAvL29rCisgICAgICAgICB9CisKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjc3VwcG9ydHNHcm91cEJ5KCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJleGNlcHRpb24gdGVzdCBmYWlscyIpCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c0dyb3VwQnkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgaW5zZXJ0TmV3UmVjb3JkKCk7CisKKyAgICAgICAgU3RyaW5nIHNlbGVjdFF1ZXJ5ID0gIlNFTEVDVCAqIEZST00gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMQorICAgICAgICAgICAgICAgICsgIiBHUk9VUCBCWSBmaWVsZDMiOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KHNlbGVjdFF1ZXJ5KTsKKyAgICAgICAgICAgIGlmICghbWV0YS5zdXBwb3J0c0dyb3VwQnkoKSkgeworICAgICAgICAgICAgICAgIGZhaWwoImdyb3VwIGJ5IGFyZSBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGlmIChtZXRhLnN1cHBvcnRzR3JvdXBCeSgpKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiZ3JvdXAgYnkgYXJlIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAvL0V4Y2VwdGlvbiBjaGVja2luZworICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgbWV0YS5zdXBwb3J0c0dyb3VwQnkoKTsKKyAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAvL29rCisgICAgICAgICB9CisKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjc3VwcG9ydHNHcm91cEJ5VW5yZWxhdGVkKCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJleGNlcHRpb24gdGVzdCBmYWlscyIpCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c0dyb3VwQnlVbnJlbGF0ZWQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgaW5zZXJ0TmV3UmVjb3JkKCk7CisKKyAgICAgICAgU3RyaW5nIHNlbGVjdFF1ZXJ5ID0gIlNFTEVDVCBmaWVsZDEsIGZpZWxkMiBGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSArICIgR1JPVVAgQlkgZmllbGQzIjsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGVRdWVyeShzZWxlY3RRdWVyeSk7CisgICAgICAgICAgICBpZiAoIW1ldGEuc3VwcG9ydHNHcm91cEJ5VW5yZWxhdGVkKCkpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJ1bnJlbGF0ZWQgY29sdW1ucyBpbiBncm91cCBieSBhcmUgc3VwcG9ydGVkIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAobWV0YS5zdXBwb3J0c0dyb3VwQnlVbnJlbGF0ZWQoKSkgeworICAgICAgICAgICAgICAgIGZhaWwoInVucmVsYXRlZCBjb2x1bW5zIGluIGdyb3VwIGJ5IGFyZSBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvL0V4Y2VwdGlvbiBjaGVja2luZworICAgICAgICBjb25uLmNsb3NlKCk7CisKKyAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgbWV0YS5zdXBwb3J0c0dyb3VwQnlVbnJlbGF0ZWQoKTsKKyAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAvL29rCisgICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI3N1cHBvcnRzTm9uTnVsbGFibGVDb2x1bW5zKCkKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJUaWNrZXQgOTgiKQorICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNOb25OdWxsYWJsZUNvbHVtbnMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiY29sdW1ucyBpbiB0aGlzIGRhdGFiYXNlIG1heSBub3QgYmUgZGVmaW5lZCBhcyBub24tbnVsbGFibGUiLAorICAgICAgICAgICAgICAgIG1ldGEuc3VwcG9ydHNOb25OdWxsYWJsZUNvbHVtbnMoKSk7CisgICAgICAgIHN0YXRlbWVudEZvcndhcmQuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGNvbXBhbmllcyhpZCBpbnRlZ2VyIG5vdCBudWxsKTsiKTsKKyAgICAgICAgc3RhdGVtZW50Rm9yd2FyZC5leGVjdXRlKCJkcm9wIHRhYmxlIGNvbXBhbmllcyIpOworCisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBtZXRhLnN1cHBvcnRzTm9uTnVsbGFibGVDb2x1bW5zKCk7CisgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgLy9vaworICAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNzdXBwb3J0c09yZGVyQnlVbnJlbGF0ZWQoKQorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoImV4Y2VwdGlvbiB0ZXN0IGZhaWxzIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzT3JkZXJCeVVucmVsYXRlZCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBpbnNlcnROZXdSZWNvcmQoKTsKKworICAgICAgICBTdHJpbmcgc2VsZWN0UXVlcnkgPSAiU0VMRUNUIGZpZWxkMSwgZmllbGQyIEZST00gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxICsgIiBPUkRFUiBCWSBpZCArIGZpZWxkMyI7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlUXVlcnkoc2VsZWN0UXVlcnkpOworICAgICAgICAgICAgaWYgKCFtZXRhLnN1cHBvcnRzT3JkZXJCeVVucmVsYXRlZCgpKSB7CisgICAgICAgICAgICAgICAgZmFpbCgidW5yZWxhdGVkIGNvbHVtbnMgaW4gb3JkZXIgYnkgYXJlIHN1cHBvcnRlZCIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaWYgKG1ldGEuc3VwcG9ydHNPcmRlckJ5VW5yZWxhdGVkKCkpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJ1bnJlbGF0ZWQgY29sdW1ucyBpbiBvcmRlciBieSBhcmUgbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBtZXRhLnN1cHBvcnRzT3JkZXJCeVVucmVsYXRlZCgpOworICAgICAgICAgICAgIGZhaWwoIlNRTEV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgIC8vb2sKKyAgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc3FsLkRhdGFiYXNlTWV0YURhdGEjc3VwcG9ydHNTZWxlY3RGb3JVcGRhdGUoKQorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoImV4Y2VwdGlvbiB0ZXN0IGZhaWxzIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3N1cHBvcnRzU2VsZWN0Rm9yVXBkYXRlKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGluc2VydE5ld1JlY29yZCgpOworCisgICAgICAgIFN0cmluZyBzZWxlY3RRdWVyeSA9ICJTRUxFQ1QgZmllbGQxIEZST00gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxICsgIiBGT1IgVVBEQVRFIjsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGVRdWVyeShzZWxlY3RRdWVyeSk7CisgICAgICAgICAgICBpZiAoIW1ldGEuc3VwcG9ydHNTZWxlY3RGb3JVcGRhdGUoKSkgeworICAgICAgICAgICAgICAgIGZhaWwoInNlbGVjdCBmb3IgdXBkYXRlIGFyZSBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGlmICghbWV0YS5zdXBwb3J0c1NlbGVjdEZvclVwZGF0ZSgpKSB7CisgICAgICAgICAgICAgICAgZmFpbCgic2VsZWN0IGZvciB1cGRhdGUgYXJlIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBtZXRhLnN1cHBvcnRzU2VsZWN0Rm9yVXBkYXRlKCk7CisgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgLy9vaworICAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNzdXBwb3J0c1N1YnF1ZXJpZXNJbkV4aXN0cygpCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgiZXhjZXB0aW9uIHRlc3QgZmFpbHMiKQorICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNTdWJxdWVyaWVzSW5FeGlzdHMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgaW5zZXJ0TmV3UmVjb3JkKCk7CisKKyAgICAgICAgU3RyaW5nIHNlbGVjdFF1ZXJ5ID0gIlNFTEVDVCBmaWVsZDEgRlJPTSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgV0hFUkUgRVhJU1RTKFNFTEVDVCBmaWVsZDIgRlJPTSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEgKyAiKSI7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlUXVlcnkoc2VsZWN0UXVlcnkpOworICAgICAgICAgICAgaWYgKCFtZXRhLnN1cHBvcnRzU3VicXVlcmllc0luRXhpc3RzKCkpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJTdWJxdWVyaWVzIGluIGV4aXN0cyBhcmUgc3VwcG9ydGVkIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAobWV0YS5zdXBwb3J0c1N1YnF1ZXJpZXNJbkV4aXN0cygpKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiU3VicXVlcmllcyBpbiBleGlzdHMgYXJlIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisKKyAgICAgIC8vRXhjZXB0aW9uIGNoZWNraW5nCisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBtZXRhLnN1cHBvcnRzU3VicXVlcmllc0luRXhpc3RzKCk7CisgICAgICAgICAgICAgZmFpbCgiU1FMRXhjZXB0aW9uIG5vdCB0aHJvd24iKTsKKyAgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgLy9vaworICAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSNzdXBwb3J0c1RhYmxlQ29ycmVsYXRpb25OYW1lcygpCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgiZXhjZXB0aW9uIHRlc3QgZmFpbHMiKQorICAgIHB1YmxpYyB2b2lkIHRlc3Rfc3VwcG9ydHNUYWJsZUNvcnJlbGF0aW9uTmFtZXMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKworICAgICAgICBpbnNlcnROZXdSZWNvcmQoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoY29ubi5pc0Nsb3NlZCgpKTsKKworICAgICAgICBTdHJpbmcgY29yZWxhdGlvbk5hbWUgPSAiVEFCTEVfTkFNRSI7CisgICAgICAgIFN0cmluZyBzZWxlY3RRdWVyeSA9ICJTRUxFQ1QgKiBGUk9NICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgQVMgIiArIGNvcmVsYXRpb25OYW1lOworICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdGF0ZW1lbnRGb3J3YXJkLmV4ZWN1dGVRdWVyeShzZWxlY3RRdWVyeSk7CisgICAgICAgIFJlc3VsdFNldE1ldGFEYXRhIHJzbWQgPSBycy5nZXRNZXRhRGF0YSgpOworICAgICAgICBpbnQgbnVtT2ZDb2x1bW4gPSByc21kLmdldENvbHVtbkNvdW50KCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1PZkNvbHVtbjsgaSsrKSB7CisgICAgICAgICAgICBpZiAobWV0YS5zdXBwb3J0c1RhYmxlQ29ycmVsYXRpb25OYW1lcygpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJDb3JlbGF0aW9uIG5hbWVzIGlzIG5vdyBzdXBwb3J0ZWQiLAorICAgICAgICAgICAgICAgICAgICAgICAgY29yZWxhdGlvbk5hbWUsIHJzbWQuZ2V0VGFibGVOYW1lKGkgKyAxKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiQ29yZWxhdGlvbiBuYW1lcyBpcyBzdXBwb3J0ZWQiLAorICAgICAgICAgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxLCByc21kLmdldFRhYmxlTmFtZShpICsgMSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKworICAgICAgLy9FeGNlcHRpb24gY2hlY2tpbmcKKyAgICAgICAgY29ubi5jbG9zZSgpOworCisgICAgICAgICB0cnkgeworICAgICAgICAgICAgIG1ldGEuc3VwcG9ydHNUYWJsZUNvcnJlbGF0aW9uTmFtZXMoKTsKKyAgICAgICAgICAgICBmYWlsKCJTUUxFeGNlcHRpb24gbm90IHRocm93biIpOworICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAvL29rCisgICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhI3N1cHBvcnRzVHJhbnNhY3Rpb25Jc29sYXRpb25MZXZlbChpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zdXBwb3J0c1RyYW5zYWN0aW9uSXNvbGF0aW9uTGV2ZWxJKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKCJkYXRhYmFzZSBzdXBwb3J0cyBUUkFOU0FDVElPTl9OT05FIGlzb2xhdGlvbiBsZXZlbCIsIG1ldGEKKyAgICAgICAgICAgICAgICAuc3VwcG9ydHNUcmFuc2FjdGlvbklzb2xhdGlvbkxldmVsKENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fTk9ORSkpOworICAgICAgICAvLyBUT0RPIG9ubHkgQ29ubmVjdGlvbi5UUkFOU0FDVElPTl9TRVJJQUxJWkFCTEUgaXMgc3VwcG9ydGVkCisvLyAgICAgICAgYXNzZXJ0VHJ1ZSgKKy8vICAgICAgICAgICAgICAgICJkYXRhYmFzZSBkb2Vzbid0IHN1cHBvcnRzIFRSQU5TQUNUSU9OX1JFQURfQ09NTUlUVEVEIGlzb2xhdGlvbiBsZXZlbCIsCisvLyAgICAgICAgICAgICAgICBtZXRhCisvLyAgICAgICAgICAgICAgICAgICAgICAgIC5zdXBwb3J0c1RyYW5zYWN0aW9uSXNvbGF0aW9uTGV2ZWwoQ29ubmVjdGlvbi5UUkFOU0FDVElPTl9SRUFEX0NPTU1JVFRFRCkpOworLy8gICAgICAgIGFzc2VydFRydWUoCisvLyAgICAgICAgICAgICAgICAiZGF0YWJhc2UgZG9lc24ndCBzdXBwb3J0cyBUUkFOU0FDVElPTl9SRUFEX1VOQ09NTUlUVEVEIGlzb2xhdGlvbiBsZXZlbCIsCisvLyAgICAgICAgICAgICAgICBtZXRhCisvLyAgICAgICAgICAgICAgICAgICAgICAgIC5zdXBwb3J0c1RyYW5zYWN0aW9uSXNvbGF0aW9uTGV2ZWwoQ29ubmVjdGlvbi5UUkFOU0FDVElPTl9SRUFEX1VOQ09NTUlUVEVEKSk7CisvLyAgICAgICAgYXNzZXJ0VHJ1ZSgKKy8vICAgICAgICAgICAgICAgImRhdGFiYXNlIGRvZXNuJ3Qgc3VwcG9ydHMgVFJBTlNBQ1RJT05fUkVQRUFUQUJMRV9SRUFEIGlzb2xhdGlvbiBsZXZlbCIsCisvLyAgICAgICAgICAgICAgICBtZXRhCisvLyAgICAgICAgICAgICAgICAgICAgICAgIC5zdXBwb3J0c1RyYW5zYWN0aW9uSXNvbGF0aW9uTGV2ZWwoQ29ubmVjdGlvbi5UUkFOU0FDVElPTl9SRVBFQVRBQkxFX1JFQUQpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiZGF0YWJhc2UgZG9lc24ndCBzdXBwb3J0cyBUUkFOU0FDVElPTl9TRVJJQUxJWkFCTEUgaXNvbGF0aW9uIGxldmVsIiwKKyAgICAgICAgICAgICAgICBtZXRhCisgICAgICAgICAgICAgICAgICAgICAgICAuc3VwcG9ydHNUcmFuc2FjdGlvbklzb2xhdGlvbkxldmVsKENvbm5lY3Rpb24uVFJBTlNBQ1RJT05fU0VSSUFMSVpBQkxFKSk7CisKKworICAgICAgLy9FeGNlcHRpb24gY2hlY2tpbmcKKworICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICBhc3NlcnRGYWxzZSgiZGF0YWJhc2Ugc3VwcG9ydHMgdW5rbm93biBpc29sYXRpb24gbGV2ZWwiLCBtZXRhCisgICAgICAgICAgICAgICAgICAgICAuc3VwcG9ydHNUcmFuc2FjdGlvbklzb2xhdGlvbkxldmVsKEludGVnZXIuTUFYX1ZBTFVFKSk7OworICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAvL29rCisgICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YSN1cGRhdGVzQXJlRGV0ZWN0ZWQoaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfdXBkYXRlc0FyZURldGVjdGVkSSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZSgKKyAgICAgICAgICAgICAgICAidmlzaWJsZSByb3cgdXBkYXRlIGNhbiBiZSBkZXRlY3RlZCBmb3IgVFlQRV9GT1JXQVJEX09OTFkgdHlwZSIsCisgICAgICAgICAgICAgICAgbWV0YS51cGRhdGVzQXJlRGV0ZWN0ZWQoUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZKSk7CisgICAgICAgIGFzc2VydEZhbHNlKAorICAgICAgICAgICAgICAgICJ2aXNpYmxlIHJvdyB1cGRhdGUgY2FuIGJlIGRldGVjdGVkIGZvciBUWVBFX1NDUk9MTF9JTlNFTlNJVElWRSB0eXBlIiwKKyAgICAgICAgICAgICAgICBtZXRhLnVwZGF0ZXNBcmVEZXRlY3RlZChSZXN1bHRTZXQuVFlQRV9TQ1JPTExfSU5TRU5TSVRJVkUpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoCisgICAgICAgICAgICAgICAgInZpc2libGUgcm93IHVwZGF0ZSBjYW4gYmUgZGV0ZWN0ZWQgZm9yIFRZUEVfU0NST0xMX1NFTlNJVElWRSB0eXBlIiwKKyAgICAgICAgICAgICAgICBtZXRhLnVwZGF0ZXNBcmVEZXRlY3RlZChSZXN1bHRTZXQuVFlQRV9TQ1JPTExfU0VOU0lUSVZFKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJ2aXNpYmxlIHJvdyB1cGRhdGUgY2FuIGJlIGRldGVjdGVkIGZvciB1bmtub3duIHR5cGUiLCBtZXRhCisgICAgICAgICAgICAgICAgLnVwZGF0ZXNBcmVEZXRlY3RlZCgxMDApKTsKKworICAgICAgICAvL0V4Y2VwdGlvbiBjaGVja2luZworICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWV0YS51cGRhdGVzQXJlRGV0ZWN0ZWQoUmVzdWx0U2V0LkNMT1NFX0NVUlNPUlNfQVRfQ09NTUlUKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJ2aXNpYmxlIHJvdyB1cGRhdGUgY2FuIGJlIGRldGVjdGVkIGZvciB1bmtub3duIHR5cGUiLCBtZXRhCisgICAgICAgICAgICAgICAgICAgIC51cGRhdGVzQXJlRGV0ZWN0ZWQoUmVzdWx0U2V0LkNMT1NFX0NVUlNPUlNfQVRfQ09NTUlUKSk7CisKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vb2sKKyAgICAgICAgfQorICAgIH0KKworCisgICAgcHJvdGVjdGVkIHN0YXRpYyB2b2lkIGluc2VydE5ld1JlY29yZCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBpZiAoY29ubi5pc0Nsb3NlZCgpKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRhdGFiYXNlTWV0YURhdGFUZXN0Lmluc2VydE5ld1JlY29yZCgpIDogY2xvc2VkIik7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgaW5zZXJ0UXVlcnkgPSAiSU5TRVJUIElOVE8gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMQorICAgICAgICAgICAgICAgICsgIiAoaWQsIGZpZWxkMSwgZmllbGQyLCBmaWVsZDMpIFZBTFVFUygiICsgaWQgKyAiLCAnIgorICAgICAgICAgICAgICAgICsgInZhbHVlIiArIGlkICsgIicsICIgKyBpZCArICIsICIgKyBpZCArICIpIjsKKyAgICAgICAgaWQrKzsKKyAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoaW5zZXJ0UXVlcnkpOworICAgIH0KKworICAgIC8vQkVHSU4gQVBBQ0hFLURFUkJZCisKKyAgICAvKioKKyAgICAgKiBUZXN0IE1ldGhvZCBmcm9tIEFwYWNoZSBEZXJieSBQcm9qZWN0CisgICAgICogQ2xhc3MKKyAgICAgKiBvcmcuYXBhY2hlLmRlcmJ5VGVzdGluZy5mdW5jdGlvblRlc3RzLnRlc3RzLmpkYmNhcGkuRGF0YWJhc2VNZXRhRGF0YVRlc3QKKyAgICAgKgorICAgICAqIENvbXBhcmUgYSBSZXN1bHRTZXQgZnJvbSBnZXRDb2x1bW5zKCkgd2l0aCBSZXN1bHRTZXRNZXRhRGF0YSByZXR1cm5lZAorICAgICAqIGZyb20gYSBTRUxFQ1QgKiBhZ2FpbnN0IHRoZSB0YWJsZS4gVGhpcyBtZXRob2QgaGFuZGxlcyBzaXR1YXRpb25zIHdoZXJlIGEKKyAgICAgKiBmdWxsIHNldCBvZiB0aGUgY29sdW1ucyBhcmUgaW4gdGhlIFJlc3VsdFNldC4gVGhlIGZpcnN0IGFjdGlvbiBpcyB0byBjYWxsCisgICAgICogcnMubmV4dCgpLiBUaGUgUmVzdWx0U2V0IHdpbGwgYmUgY2xvc2VkIGJ5IHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIHJzCisgICAgICogICAgICAgICAgICByZXN1bHRzZXQgdG8gY3Jvc3NDaGVjaworICAgICAqIEBwYXJhbSBwYXJ0aWFsCisgICAgICogICAgICAgICAgICB1c2VkIHRvIGluZGljYXRlIGlmIG9yZGluYWwgcG9zaXRpb24gc2hvdWxkIGdldCBjaGVja2VkCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHJvd3MgaW4gdGhlIHJlc3VsdFNldAorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgY3Jvc3NDaGVja0dldENvbHVtbnNBbmRSZXN1bHRTZXRNZXRhRGF0YShSZXN1bHRTZXQgcnMsCisgICAgICAgICAgICBib29sZWFuIHBhcnRpYWwpCisgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgU3RhdGVtZW50IHMgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICB3aGlsZSAocnMubmV4dCgpKQorICAgICAgICB7CisgICAgICAgICAgICBTdHJpbmcgc2NoZW1hID0gcnMuZ2V0U3RyaW5nKCJUQUJMRV9TQ0hFTSIpOworICAgICAgICAgICAgU3RyaW5nIHRhYmxlID0gcnMuZ2V0U3RyaW5nKCJUQUJMRV9OQU1FIik7CisKKyAgICAgICAgICAgIFJlc3VsdFNldCByc3QgPSBzLmV4ZWN1dGVRdWVyeSgKKyAgICAgICAgICAgICAgICAiU0VMRUNUICogRlJPTSAiICsgc2NoZW1hKyIuIit0YWJsZSk7CisgICAgICAgICAgICBSZXN1bHRTZXRNZXRhRGF0YSByc21kdCA9IHJzdC5nZXRNZXRhRGF0YSgpOworCisKKyAgICAgICAgICAgIGZvciAoaW50IGNvbCA9IDE7IGNvbCA8PSByc21kdC5nZXRDb2x1bW5Db3VudCgpIDsgY29sKyspCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgaWYgKCFwYXJ0aWFsKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChjb2wgIT0gMSkKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUocnMubmV4dCgpKTsKKworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIk9SRElOQUxfUE9TSVRJT04iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbCwgcnMuZ2V0SW50KCJPUkRJTkFMX1BPU0lUSU9OIikpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiVEFCTEVfQ0FUIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICIiLCBycy5nZXRTdHJpbmcoIlRBQkxFX0NBVCIpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRBQkxFX1NDSEVNIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtYSwgcnMuZ2V0U3RyaW5nKCJUQUJMRV9TQ0hFTSIpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRBQkxFX05BTUUiLAorICAgICAgICAgICAgICAgICAgICAgICAgdGFibGUsIHJzLmdldFN0cmluZygiVEFCTEVfTkFNRSIpKTsKKworICAgICAgICAgICAgICAgIGNyb3NzQ2hlY2tHZXRDb2x1bW5Sb3dBbmRSZXN1bHRTZXRNZXRhRGF0YShycywgcnNtZHQpOworICAgICAgICAgICAgICAgIGlmIChwYXJ0aWFsKQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgfQorICAgICAgICAgICAgcnN0LmNsb3NlKCk7CisKKworICAgICAgICB9CisgICAgICAgIGludCBjb3VudCA9IHJzLmdldFJvdygpOworICAgICAgICBycy5jbG9zZSgpOworICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgIHJldHVybiBjb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiAqIFRlc3QgTWV0aG9kIGZyb20gQXBhY2hlIERlcmJ5IFByb2plY3QKKyAgICAgKiBDbGFzcworICAgICAqIG9yZy5hcGFjaGUuZGVyYnlUZXN0aW5nLmZ1bmN0aW9uVGVzdHMudGVzdHMuamRiY2FwaS5EYXRhYmFzZU1ldGFEYXRhVGVzdAorICAgICAqCisgICAgICogQ3Jvc3MgY2hlY2sgYSBzaW5nbGUgcm93IGZyb20gZ2V0Q29sdW1ucygpIHdpdGggUmVzdWx0U2V0TWV0YURhdGEKKyAgICAgKiBmb3IgYSBTRUxFQ1QgKiBmcm9tIHRoZSBzYW1lIHRhYmxlLgorICAgICAqIEBwYXJhbSBycyBSZXN1bHRTZXQgZnJvbSBnZXRDb2x1bW5zIGFscmVhZHkgcG9zaXRpb25lZCBvbiB0aGUgcm93LgorICAgICAqIEBwYXJhbSByc21kdCBSZXN1bHRTZXRNZXRhRGF0YSBmb3IgdGhlIFNFTEVDVCAqCisgICAgICogQHBhcmFtIG9kYmMgMCBmb3IgSkRCQyBjYWxsLCAxIGZvciBPREJDLiBOZWVkZWQgdG8gYWxsb3cgZm9yIGRpZmZlcmVuY2UKKyAgICAgKiAgICBpbiB1c2luZyBCVUZGRVJfTEVOR1RIIChPREJDKSBvciBubyhKREJDKS4KKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjcm9zc0NoZWNrR2V0Q29sdW1uUm93QW5kUmVzdWx0U2V0TWV0YURhdGEoCisgICAgICAgICAgICBSZXN1bHRTZXQgcnMsIFJlc3VsdFNldE1ldGFEYXRhIHJzbWR0KQorICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgeworICAgICAgICBpbnQgY29sID0gcnMuZ2V0SW50KCJPUkRJTkFMX1BPU0lUSU9OIik7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSU01ELmdldENhdGFsb2dOYW1lIiwKKyAgICAgICAgICAgICAgICByc21kdC5nZXRDYXRhbG9nTmFtZShjb2wpLCBycy5nZXRTdHJpbmcoIlRBQkxFX0NBVCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSU01ELmdldFNjaGVtYU5hbWUiLAorICAgICAgICAgICAgICAgIHJzbWR0LmdldFNjaGVtYU5hbWUoY29sKSwgcnMuZ2V0U3RyaW5nKCJUQUJMRV9TQ0hFTSIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJSU01ELmdldFRhYmxlTmFtZSIsCisgICAgICAgICAgICAgICAgcnNtZHQuZ2V0VGFibGVOYW1lKGNvbCksIHJzLmdldFN0cmluZygiVEFCTEVfTkFNRSIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIkNPTFVNTl9OQU1FIiwKKyAgICAgICAgICAgICAgICByc21kdC5nZXRDb2x1bW5OYW1lKGNvbCksIHJzLmdldFN0cmluZygiQ09MVU1OX05BTUUiKSk7CisKKyAgICAgICAgLy8gREVSQlktMjI4NSBCT09MRUFOIGNvbHVtbnMgYXBwZWFyIGRpZmZlcmVudCBvbgorICAgICAgICAvLyBuZXR3b3JrIGNsaWVudC4KKyAgICAgICAgLy8gbWV0YSByZXR1cm5zIEJPT0xFQU4KKyAgICAgICAgLy8gUlNNRCByZXR1cm5zIFNNQUxMSU5UCisgICAgICAgIGludCBtZXRhQ29sdW1uVHlwZSA9IHJzLmdldEludCgiREFUQV9UWVBFIik7CisgICAgICAgIGlmIChtZXRhQ29sdW1uVHlwZSA9PSBUeXBlcy5CT09MRUFOICkKKyAgICAgICAgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUWVBFX05BTUUiLAorICAgICAgICAgICAgICAgICAgICAiQk9PTEVBTiIsIHJzLmdldFN0cmluZygiVFlQRV9OQU1FIikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUWVBFX05BTUUiLAorICAgICAgICAgICAgICAgICAgICAiU01BTExJTlQiLCByc21kdC5nZXRDb2x1bW5UeXBlTmFtZShjb2wpKTsKKworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJEQVRBX1RZUEUiLAorICAgICAgICAgICAgICAgICAgICBUeXBlcy5TTUFMTElOVCwgcnNtZHQuZ2V0Q29sdW1uVHlwZShjb2wpKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChtZXRhQ29sdW1uVHlwZSA9PSBUeXBlcy5KQVZBX09CSkVDVCkKKyAgICAgICAgeworICAgICAgICAgICAgLy8gbWV0YSByZXR1cm5zIEpBVkFfT0JKRUNUCisgICAgICAgICAgICAvLyBSU01EIHJldHVybnMgTE9OR1ZBUkJJTkFSWSEKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiREFUQV9UWVBFIiwKKyAgICAgICAgICAgICAgICAgICAgVHlwZXMuTE9OR1ZBUkJJTkFSWSwgcnNtZHQuZ2V0Q29sdW1uVHlwZShjb2wpKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChtZXRhQ29sdW1uVHlwZSA9PSBUeXBlcy5WQVJCSU5BUlkgKQorICAgICAgICB7CisgICAgICAgICAgICAvLyBtZXRhIHJldHVybnMgZGlmZmVyZW50IHR5cGUgbmFtZSB0byBSU01ECisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkRBVEFfVFlQRSIsCisgICAgICAgICAgICAgICAgICAgIFR5cGVzLlZBUkJJTkFSWSwgcnNtZHQuZ2V0Q29sdW1uVHlwZShjb2wpKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChtZXRhQ29sdW1uVHlwZSA9PSBUeXBlcy5CSU5BUlkgKQorICAgICAgICB7CisgICAgICAgICAgICAvLyBtZXRhIHJldHVybnMgZGlmZmVyZW50IHR5cGUgbmFtZSB0byBSU01ECisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkRBVEFfVFlQRSIsCisgICAgICAgICAgICAgICAgICAgIFR5cGVzLkJJTkFSWSwgcnNtZHQuZ2V0Q29sdW1uVHlwZShjb2wpKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChtZXRhQ29sdW1uVHlwZSA9PSBUeXBlcy5OVU1FUklDICkKKyAgICAgICAgeworICAgICAgICAgICAgLy8gREVSQlktNTg0IGluY29uc2lzdGVuY3kgaW4gbnVtZXJpYyAmIGRlY2ltYWwKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiREFUQV9UWVBFIiwKKyAgICAgICAgICAgICAgICAgICAgVHlwZXMuREVDSU1BTCwgcnNtZHQuZ2V0Q29sdW1uVHlwZShjb2wpKTsKKworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUWVBFX05BTUUiLAorICAgICAgICAgICAgICAgICAgICAiREVDSU1BTCIsIHJzbWR0LmdldENvbHVtblR5cGVOYW1lKGNvbCkpOworCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRZUEVfTkFNRSIsCisgICAgICAgICAgICAgICAgICAgICJOVU1FUklDIiwgcnMuZ2V0U3RyaW5nKCJUWVBFX05BTUUiKSk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZQorICAgICAgICB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkRBVEFfVFlQRSIsCisgICAgICAgICAgICAgICAgcnNtZHQuZ2V0Q29sdW1uVHlwZShjb2wpLCBycy5nZXRJbnQoIkRBVEFfVFlQRSIpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiVFlQRV9OQU1FIiwKKyAgICAgICAgICAgICAgICByc21kdC5nZXRDb2x1bW5UeXBlTmFtZShjb2wpLCBycy5nZXRTdHJpbmcoIlRZUEVfTkFNRSIpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgIGlmIChtZXRhQ29sdW1uVHlwZSAhPSBUeXBlcy5KQVZBX09CSkVDVCkgeworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRZUEUgIiArIHJzLmdldEludCgiREFUQV9UWVBFIikpOworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oSkRCQy5lc2NhcGUoc2NoZW1hLCB0YWJsZSkgKyAiICIgKyBycy5nZXRTdHJpbmcoIkNPTFVNTl9OQU1FIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkNPTFVNTl9TSVpFIiwKKyAgICAgICAgICAgICAgICByc21kdC5nZXRQcmVjaXNpb24oY29sKSwgcnMuZ2V0SW50KCJDT0xVTU5fU0laRSIpKTsKKyAgICAgICAgfQorICAgICAgICAqLworCisgICAgICAgIC8qCisgICAgICAgIGFzc2VydEVxdWFscygiREVDSU1BTF9ESUdJVFMiLAorICAgICAgICAgICAgICAgIHJzbWR0LmdldFNjYWxlKGNvbCksIHJzLmdldEludCgiREVDSU1BTF9ESUdJVFMiKSk7CisgICAgICAgICovCisKKyAgICAgICAgLy8gVGhpcyBhc3N1bWVzIHRoZSBjb25zdGFudHMgZGVmaW5lZCBieSBtZXRhIGFuZCBSZXN1bHRTZXQKKyAgICAgICAgLy8gZm9yIG51bGxhYmlsaXR5IGFyZSBlcXVhbC4gVGhleSBhcmUgYnkgaW5zcGVjdGlvbgorICAgICAgICAvLyBhbmQgc2luY2UgdGhleSBhcmUgc3RhdGljIGZpbmFsIGFuZCBwYXJ0IG9mIGEgZGVmaW5lZAorICAgICAgICAvLyBhcGkgYnkgZGVmaW5pdGlvbiB0aGV5IGNhbm5vdCBjaGFuZ2UuIFdlIGFsc28KKyAgICAgICAgLy8gY2hlY2sgc3RhdGljYWxseSB0aGlzIGlzIHRydWUgaW4gdGhlIHRlc3RDb25zdGFudHMgZml4dHVyZS4KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJOVUxMQUJMRSIsCisgICAgICAgICAgICAgICAgcnNtZHQuaXNOdWxsYWJsZShjb2wpLCBycy5nZXRJbnQoIk5VTExBQkxFIikpOworCisgICAgICAgIC8vIFJFTUFSS1Mgc2V0IHRvIGVtcHR5IHN0cmluZyBieSBEZXJieQorICAgICAgICBhc3NlcnRFcXVhbHMoIlJFTUFSS1MiLCAiIiwgcnMuZ2V0U3RyaW5nKCJSRU1BUktTIikpOworCisKKyAgICAgICAgLy8gSVNfTlVMTEFCTEUKKyAgICAgICAgc3dpdGNoIChyc21kdC5pc051bGxhYmxlKGNvbCkpCisgICAgICAgIHsKKyAgICAgICAgY2FzZSBSZXN1bHRTZXRNZXRhRGF0YS5jb2x1bW5Ob051bGxzOgorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJU19OVUxMQUJMRSIsICJOTyIsIHJzLmdldFN0cmluZygiSVNfTlVMTEFCTEUiKSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBSZXN1bHRTZXRNZXRhRGF0YS5jb2x1bW5OdWxsYWJsZToKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSVNfTlVMTEFCTEUiLCAiWUVTIiwgcnMuZ2V0U3RyaW5nKCJJU19OVUxMQUJMRSIpKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFJlc3VsdFNldE1ldGFEYXRhLmNvbHVtbk51bGxhYmxlVW5rbm93bjoKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSVNfTlVMTEFCTEUiLCAiIiwgcnMuZ2V0U3RyaW5nKCJJU19OVUxMQUJMRSIpKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgZmFpbCgiaW52YWxpZCByZXR1cm4gZnJvbSByc21kdC5pc051bGxhYmxlKGNvbCkiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFNDT1BFIG5vdCBzdXBwb3J0ZWQKKyAgICAgICAgYXNzZXJ0TnVsbCgiU0NPUEVfQ0FUTE9HIiwgcnMuZ2V0U3RyaW5nKCJTQ09QRV9DQVRMT0ciKSk7CisgICAgICAgIGFzc2VydE51bGwoIlNDT1BFX1NDSEVNQSIsIHJzLmdldFN0cmluZygiU0NPUEVfU0NIRU1BIikpOworICAgICAgICBhc3NlcnROdWxsKCJTQ09QRV9UQUJMRSIsIHJzLmdldFN0cmluZygiU0NPUEVfVEFCTEUiKSk7CisKKyAgICAgICAgLy8gRElTVElOQ1Qgbm90IHN1cHBvcnRlZAorICAgICAgICBhc3NlcnRFcXVhbHMoIlNPVVJDRV9EQVRBX1RZUEUiLCAwLCBycy5nZXRTaG9ydCgiU09VUkNFX0RBVEFfVFlQRSIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShycy53YXNOdWxsKCkpOworCisgICAgICAgIC8vIElTX0FVVE9JTkNSRU1FTlQgYWRkZWQgaW4gSkRCQyA0LjAKKyAgICAgICBhc3NlcnRFcXVhbHMoIklTX0FVVE9JTkNSRU1FTlQiLAorICAgICAgICAgICAgICAgcnNtZHQuaXNBdXRvSW5jcmVtZW50KGNvbCkgPyAiWUVTIiA6ICJOTyIsCisgICAgICAgICAgICAgICBycy5nZXRTdHJpbmcoIklTX0FVVE9JTkNSRU1FTlQiKSk7CisgICAgICAgYXNzZXJ0RmFsc2UocnMud2FzTnVsbCgpKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENoZWNrIHRoZSBzaGFwZSBvZiB0aGUgUmVzdWx0U2V0IGZyb20gYW55IGdldENvbHVtbnMgY2FsbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY2hlY2tDb2x1bW5zU2hhcGUoUmVzdWx0U2V0IHJzKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgaW50W10gY29sdW1uVHlwZXMgPSBuZXcgaW50W10geworICAgICAgICAgICAgICAgIFR5cGVzLlZBUkNIQVIsIFR5cGVzLlZBUkNIQVIsIFR5cGVzLlZBUkNIQVIsIFR5cGVzLlZBUkNIQVIsCisgICAgICAgICAgICAgICAgVHlwZXMuU01BTExJTlQsIFR5cGVzLlZBUkNIQVIsIFR5cGVzLklOVEVHRVIsIFR5cGVzLklOVEVHRVIsCisgICAgICAgICAgICAgICAgVHlwZXMuSU5URUdFUiwgVHlwZXMuSU5URUdFUiwgVHlwZXMuSU5URUdFUiwgVHlwZXMuVkFSQ0hBUiwKKyAgICAgICAgICAgICAgICBUeXBlcy5WQVJDSEFSLCBUeXBlcy5JTlRFR0VSLCBUeXBlcy5JTlRFR0VSLCBUeXBlcy5JTlRFR0VSLAorICAgICAgICAgICAgICAgIFR5cGVzLklOVEVHRVIsIFR5cGVzLlZBUkNIQVIsIFR5cGVzLlZBUkNIQVIsIFR5cGVzLlZBUkNIQVIsCisgICAgICAgICAgICAgICAgVHlwZXMuVkFSQ0hBUiwgVHlwZXMuU01BTExJTlQsIFR5cGVzLlZBUkNIQVJ9OworCisgICAgICAgIGFzc2VydE1ldGFEYXRhUmVzdWx0U2V0KHJzLCBuZXcgU3RyaW5nW10geworICAgICAgICAgICAgICAgICJUQUJMRV9DQVQiLCAiVEFCTEVfU0NIRU0iLCAiVEFCTEVfTkFNRSIsICJDT0xVTU5fTkFNRSIsCisgICAgICAgICAgICAgICAgIkRBVEFfVFlQRSIsICJUWVBFX05BTUUiLCAiQ09MVU1OX1NJWkUiLCAiQlVGRkVSX0xFTkdUSCIsCisgICAgICAgICAgICAgICAgIkRFQ0lNQUxfRElHSVRTIiwgIk5VTV9QUkVDX1JBRElYIiwgIk5VTExBQkxFIiwgIlJFTUFSS1MiLAorICAgICAgICAgICAgICAgICJDT0xVTU5fREVGIiwgIlNRTF9EQVRBX1RZUEUiLCAiU1FMX0RBVEVUSU1FX1NVQiIsCisgICAgICAgICAgICAgICAgIkNIQVJfT0NURVRfTEVOR1RIIiwgIk9SRElOQUxfUE9TSVRJT04iLCAiSVNfTlVMTEFCTEUiLAorICAgICAgICAgICAgICAgICJTQ09QRV9DQVRMT0ciLCAiU0NPUEVfU0NIRU1BIiwgIlNDT1BFX1RBQkxFIiwKKyAgICAgICAgICAgICAgICAiU09VUkNFX0RBVEFfVFlQRSIsICJJU19BVVRPSU5DUkVNRU5UIn0sIGNvbHVtblR5cGVzLCBudWxsKTsKKworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRNZXRhRGF0YVJlc3VsdFNldChSZXN1bHRTZXQgcnMsCisgICAgICAgICAgICBTdHJpbmdbXSBjb2x1bW5OYW1lcywgaW50W10gY29sdW1uVHlwZXMsCisgICAgICAgICAgICBib29sZWFuW10gbnVsbGFiaWxpdHkpIHRocm93cyBTUUxFeGNlcHRpb24KKyAgICB7CisgICAgIC8vIHNlZSBSZXN1bHRTZXRHZXR0ZXJUZXN0LCBnZXRUeXBlKCkgLT4gdGhpcyB0ZXN0IGZhaWxzIGN1cnJlbnRseQorICAgICAgICBhc3NlcnRFcXVhbHMoUmVzdWx0U2V0LlRZUEVfRk9SV0FSRF9PTkxZLCBycy5nZXRUeXBlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoUmVzdWx0U2V0LkNPTkNVUl9SRUFEX09OTFksIHJzLmdldENvbmN1cnJlbmN5KCkpOworCisgICAgICAgIGlmIChjb2x1bW5OYW1lcyAhPSBudWxsKQorICAgICAgICAgICAgYXNzZXJ0Q29sdW1uTmFtZXMocnMsIGNvbHVtbk5hbWVzKTsKKyAgICAgICAgaWYgKGNvbHVtblR5cGVzICE9IG51bGwpCisgICAgICAgICAgICBhc3NlcnRDb2x1bW5UeXBlcyhycywgY29sdW1uVHlwZXMpOworICAgICAgICBpZiAobnVsbGFiaWxpdHkgIT0gbnVsbCkKKyAgICAgICAgICAgIGFzc2VydE51bGxhYmlsaXR5KHJzLCBudWxsYWJpbGl0eSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogKiBUZXN0IE1ldGhvZCBmcm9tIEFwYWNoZSBEZXJieSBQcm9qZWN0CisgICAgICogICBDbGFzcworICAgICAqIG9yZy5hcGFjaGUuZGVyYnlUZXN0aW5nLmZ1bmN0aW9uVGVzdHMudGVzdHMuamRiY2FwaS5EYXRhYmFzZU1ldGFEYXRhVGVzdAorICAgICAqCisgICAgICogVGFrZXMgYSByZXN1bHQgc2V0IGFuZCBhbiBhcnJheSBvZiBleHBlY3RlZCBjb2x1bSBuYW1lcyAoYXMKKyAgICAgKiBTdHJpbmdzKSAgYW5kIGFzc2VydHMgdGhhdCB0aGUgY29sdW1uIG5hbWVzIGluIHRoZSByZXN1bHQKKyAgICAgKiBzZXQgbWV0YWRhdGEgbWF0Y2ggdGhlIG51bWJlciwgb3JkZXIsIGFuZCBuYW1lcyBvZiB0aG9zZQorICAgICAqIGluIHRoZSBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBycyBSZXN1bHRTZXQgZm9yIHdoaWNoIHdlJ3JlIGNoZWNraW5nIGNvbHVtbiBuYW1lcy4KKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWRDb2xOYW1lcyBBcnJheSBvZiBleHBlY3RlZCBjb2x1bW4gbmFtZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydENvbHVtbk5hbWVzKFJlc3VsdFNldCBycywKKyAgICAgICAgU3RyaW5nIFtdIGV4cGVjdGVkQ29sTmFtZXMpIHRocm93cyBTUUxFeGNlcHRpb24KKyAgICB7CisgICAgICAgIFJlc3VsdFNldE1ldGFEYXRhIHJzbWQgPSBycy5nZXRNZXRhRGF0YSgpOworICAgICAgICBpbnQgYWN0dWFsQ29scyA9IHJzbWQuZ2V0Q29sdW1uQ291bnQoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFjdHVhbENvbHM7IGkrKykKKyAgICAgICAgeworICAgICAgICBhc3NlcnRFcXVhbHMoIkNvbHVtbiBuYW1lcyBkbyBub3QgbWF0Y2g6IiwKKyAgICAgICAgICAgICAgICBleHBlY3RlZENvbE5hbWVzW2ldLCByc21kLmdldENvbHVtbk5hbWUoaSsxKSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoIlVuZXhwZWN0ZWQgY29sdW1uIGNvdW50OiIsCisgICAgICAgIGV4cGVjdGVkQ29sTmFtZXMubGVuZ3RoLCByc21kLmdldENvbHVtbkNvdW50KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgTWV0aG9kIGZyb20gQXBhY2hlIERlcmJ5IFByb2plY3QKKyAgICAgKiBDbGFzcworICAgICAqIG9yZy5hcGFjaGUuZGVyYnlUZXN0aW5nLmZ1bmN0aW9uVGVzdHMudGVzdHMuamRiY2FwaS5EYXRhYmFzZU1ldGFEYXRhVGVzdAorICAgICAqCisgICAgICogVGFrZXMgYSByZXN1bHQgc2V0IGFuZCBhbiBhcnJheSBvZiBleHBlY3RlZCBjb2x1bW4gdHlwZXMKKyAgICAgKiBmcm9tIGphdmEuc3FsLlR5cGVzCisgICAgICogYW5kIGFzc2VydHMgdGhhdCB0aGUgY29sdW1uIHR5cGVzIGluIHRoZSByZXN1bHQKKyAgICAgKiBzZXQgbWV0YWRhdGEgbWF0Y2ggdGhlIG51bWJlciwgb3JkZXIsIGFuZCBuYW1lcyBvZiB0aG9zZQorICAgICAqIGluIHRoZSBhcnJheS4KKyAgICAgKgorICAgICAqIE5vIGxlbmd0aCBpbmZvcm1hdGlvbiBmb3IgdmFyaWFibGUgbGVuZ3RoIHR5cGVzCisgICAgICogY2FuIGJlIHBhc3NlZC4gRm9yIFJlc3VsdFNldHMgZnJvbSBKREJDIERhdGFiYXNlTWV0YURhdGEKKyAgICAgKiB0aGUgc3BlY2lmaWNhdGlvbiBvbmx5IGluZGljYXRlcyB0aGUgdHlwZXMgb2YgdGhlCisgICAgICogY29sdW1ucywgbm90IHRoZSBsZW5ndGguCisgICAgICoKKyAgICAgKiBAcGFyYW0gcnMgUmVzdWx0U2V0IGZvciB3aGljaCB3ZSdyZSBjaGVja2luZyBjb2x1bW4gbmFtZXMuCisgICAgICogQHBhcmFtIGV4cGVjdGVkVHlwZXMgQXJyYXkgb2YgZXhwZWN0ZWQgY29sdW1uIHR5cGVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRDb2x1bW5UeXBlcyhSZXN1bHRTZXQgcnMsCisgICAgICAgIGludFtdIGV4cGVjdGVkVHlwZXMpIHRocm93cyBTUUxFeGNlcHRpb24KKyAgICB7CisgICAgICAgIFJlc3VsdFNldE1ldGFEYXRhIHJzbWQgPSBycy5nZXRNZXRhRGF0YSgpOworICAgICAgICBpbnQgYWN0dWFsQ29scyA9IHJzbWQuZ2V0Q29sdW1uQ291bnQoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlVuZXhwZWN0ZWQgY29sdW1uIGNvdW50OiIsCisgICAgICAgICAgICAgICAgZXhwZWN0ZWRUeXBlcy5sZW5ndGgsIHJzbWQuZ2V0Q29sdW1uQ291bnQoKSk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhY3R1YWxDb2xzOyBpKyspCisgICAgICAgIHsKKyAgICAgICBhc3NlcnRFcXVhbHMoIkNvbHVtbiB0eXBlcyBkbyBub3QgbWF0Y2ggZm9yIGNvbHVtbiAiICsgKGkrMSksCisgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkVHlwZXNbaV0sIHJzbWQuZ2V0Q29sdW1uVHlwZShpKzEpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIHRoZSBudWxsYWJpbGl0eSBvZiB0aGUgY29sdW1uIGRlZmluaXRpb25zIGZvcgorICAgICAqIHRoZSBSZXN1bHRTZXQgbWF0Y2hlcyB0aGUgZXhwZWN0ZWQgdmFsdWVzLgorICAgICAqIEBwYXJhbSBycworICAgICAqIEBwYXJhbSBudWxsYWJpbGl0eQorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydE51bGxhYmlsaXR5KFJlc3VsdFNldCBycywKKyAgICAgICAgICAgIGJvb2xlYW5bXSBudWxsYWJpbGl0eSkgdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgUmVzdWx0U2V0TWV0YURhdGEgcnNtZCA9IHJzLmdldE1ldGFEYXRhKCk7CisgICAgICAgIGludCBhY3R1YWxDb2xzID0gcnNtZC5nZXRDb2x1bW5Db3VudCgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiVW5leHBlY3RlZCBjb2x1bW4gY291bnQ6IiwKKyAgICAgICAgICAgICAgICBudWxsYWJpbGl0eS5sZW5ndGgsIHJzbWQuZ2V0Q29sdW1uQ291bnQoKSk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhY3R1YWxDb2xzOyBpKyspCisgICAgICAgIHsKKyAgICAgICAgICAgIGludCBleHBlY3RlZCA9IG51bGxhYmlsaXR5W2ldID8KKyAgICAgICAgICAgICAgIFJlc3VsdFNldE1ldGFEYXRhLmNvbHVtbk51bGxhYmxlIDogUmVzdWx0U2V0TWV0YURhdGEuY29sdW1uTm9OdWxsczsKKyAgICAgICBhc3NlcnRFcXVhbHMoIkNvbHVtbiBudWxsYWJpbGl0eSBkbyBub3QgbWF0Y2ggZm9yIGNvbHVtbiAiICsgKGkrMSksCisgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkLCByc21kLmlzTnVsbGFibGUoaSsxKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvL0JFR0lOIEFwYWNoZSBEZXJieSBEYXRhYmFzZU1ldGFEYXRhVGVzdAorCisgICAgIC8qCisgICAgICAqIEVzY2FwZWQgZnVuY3Rpb24gdGVzdGluZyBUT0RPIGNvbXBsZXRlIHRoaXMgbGlzdAorICAgICAgKi8KKyAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW11bXSBOVU1FUklDX0ZVTkNUSU9OUyA9IHsKKyAgICAgICAgICAgICAvLyBTZWN0aW9uIEMuMSBKREJDIDMuMCBzcGVjLgorICAgICAgICAgICAgIHsiQUJTIiwgIi0yNS42NyJ9LAorCisvLyAgICAgICAgICAgICB7IkFDT1MiLCAiMC4wNzA3In0sIHsiQVNJTiIsICIwLjk5NyJ9LAorLy8gICAgICAgICAgICAgeyJBVEFOIiwgIjE0LjEwIn0sIHsiQVRBTjIiLCAiMC41NiIsICIxLjIifSwgeyJDRUlMSU5HIiwgIjMuNDUifSwKKy8vICAgICAgICAgICAgIHsiQ09TIiwgIjEuMiJ9LCB7IkNPVCIsICIzLjQifSwgeyJERUdSRUVTIiwgIjIuMSJ9LCB7IkVYUCIsICIyLjMifSwKKy8vICAgICAgICAgICAgIHsiRkxPT1IiLCAiMy4yMiJ9LCB7IkxPRyIsICIzNC4xIn0sIHsiTE9HMTAiLCAiMTguNyJ9LAorLy8gICAgICAgICAgICAgeyJNT0QiLCAiMTI0IiwgIjcifSwgeyJQSSJ9LCB7IlBPV0VSIiwgIjIiLCAiMyJ9LAorLy8gICAgICAgICAgICAgeyJSQURJQU5TIiwgIjU0In0sIHsiUkFORCIsICIxNyJ9LAorCisgICAgICAgICAgICAgeyJST1VORCIsICIzNDUuMzQ1IiwgIjEifQorCisvLyAgICAgICAgICAgICB7IlNJR04iLCAiLTM0In0sIHsiU0lOIiwgIjAuMzIifSwgeyJTUVJUIiwgIjYuMjIifSwKKy8vICAgICAgICAgICAgIHsiVEFOIiwgIjAuNTciLH0sIHsiVFJVTkNBVEUiLCAiMzQ1LjM5NSIsICIxIn0KKworICAgICAgICAgICAgIH07CisKKyAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW11bXSBUSU1FREFURV9GVU5DVElPTlMgPSB7CisgICAgICAgICAgICAgLy8gU2VjdGlvbiBDLjMgSkRCQyAzLjAgc3BlYy4KKworICAgICAgICAgICAgIHsiZGF0ZSIsIidub3cnIn0KKworICAgICAgICAgICAgIC8vVE9ETyBDb21wbGV0ZSBsaXN0CisKKyAgICAgfTsKKworICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXVtdIFNZU1RFTV9GVU5DVElPTlMgPSB7CisgICAgIC8vIFNlY3Rpb24gQy40IEpEQkMgMy4wIHNwZWMuCisgICAgICAgICAgICAgeyJJRk5VTEwiLCAiJ3RoaXMnIiwgIid0aGF0JyJ9LCB7IlVTRVIifQorICAgICAgICAgICAgIH07CisKKyAgICAgLyoKKyAgICAgICogVE9ETyBjb21wbGV0ZSBvciBjaGVjayB0aGlzIGxpc3QKKyAgICAgICovCisgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdW10gU1RSSU5HX0ZVTkNUSU9OUyA9IHsKKyAgICAgICAgICAgICAvLyBTZWN0aW9uIEMuMiBKREJDIDMuMCBzcGVjLgorLy8gICAgICAgICAgICAgeyJBU0NJSSIsICInWWVsbG93JyJ9LCB7IkNIQVIiLCAiNjUifSwKKy8vICAgICAgICAgICAgIHsiQ09OQ0FUIiwgIidoZWxsbyciLCAiJ3RoZXJlJyJ9LAorLy8gICAgICAgICAgICAgeyJESUZGRVJFTkNFIiwgIidQaXJlcyciLCAiJ1BpZXJzJyJ9LAorLy8gICAgICAgICAgICAgeyJJTlNFUlQiLCAiJ0JpbGwgQ2xpbnRvbiciLCAiNCIsICInV2lsbGlhbScifSwKKy8vICAgICAgICAgICAgIHsiTENBU0UiLCAiJ0Zlcm5hbmRvIEFsb25zbycifSwgeyJMRUZUIiwgIidCb25qb3VyJyIsICIzIn0sCisvLyAgICAgICAgICAgICB7IkxFTkdUSCIsICInZm91ciAgICAnIn0sIHsiTE9DQVRFIiwgIidqb3VyJyIsICInQm9uam91cicifSwKKyAgICAgICAgICAgICB7IkxUUklNIiwgIicgICBsZWZ0IHRyaW0gICAnIn0sCisvLyAgICAgICAgICAgICAgIHsiUkVQRUFUIiwgIidlY2hvJyIsICIzIn0sCisvLyAgICAgICAgICAgICB7IlJFUExBQ0UiLCAiJ3RvIGJlIG9yIG5vdCB0byBiZSciLCAiJ2JlJyIsICInRW5nbGFuZCcifSwKKy8vICAgICAgICAgICAgIHsiUlRSSU0iLCAiJyAgcmlnaHQgdHJpbSAgICcifSwgeyJTT1VOREVYIiwgIidEZXJieScifSwKKy8vICAgICAgICAgICAgIHsiU1BBQ0UiLCAiMTIifSwKKy8vICAgICAgICAgICAgIHsiU1VCU1RSSU5HIiwgIidSdWJ5IHRoZSBSdWJpY29uIEplZXAnIiwgIjEwIiwgIjciLH0sCisvLyAgICAgICAgICAgICB7IlVDQVNFIiwgIidGZXJuYW5kbyBBbG9uc28nIn0KKyAgICAgfTsKKworICAgICAvKioKKyAgICAgICogU2l4IGNvbWJpbmF0aW9ucyBvZiB2YWxpZCBpZGVudGlmaWVycyB3aXRoIG1peGVkIGNhc2UsIHRvIHNlZSBob3cgdGhlCisgICAgICAqIHZhcmlvdXMgcGF0dGVybiBtYXRjaGluZyBhbmQgcmV0dXJuZWQgdmFsdWVzIGhhbmRsZSB0aGVtLiBUaGlzIHRlc3Qgb25seQorICAgICAgKiBjcmVhdGVzIG9iamVjdHMgaW4gdGhlc2Ugc2NoZW1hcy4KKyAgICAgICovCisgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIElEUyA9IHsKKyAgICAgICAgICAgICAib25lX21ldGFfdGVzdCIsICJUV09fbWV0YV90ZXN0IiwgIlRoUmVFX21ldGFfdGVzdCIsCisgICAgICAgICAgICAgIlwiZm91cl9tZXRhX3Rlc3RcIiIsICJcIkZJVkVfbWV0YV90ZXN0XCIiLCAiXCJzSXhfbWV0YV90ZXN0XCIifTsKKworICAgICAvKioKKyAgICAgICogQWxsIHRoZSBidWlsdGluIHNjaGVtYXMuCisgICAgICAqLworICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBCVUlMVElOX1NDSEVNQVMgPSB7CisgICAgICAgICAgICAgLy9UT0RPOiBBcmUgdGhlcmUgYW55IG90aGVyIGJ1aWx0IGluIHNjaGVtYXM/CisKKyAgICAgfTsKKworICAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRTdG9yZWRJZGVudGlmaWVyKFN0cmluZyBzcWxJZGVudGlmaWVyKSB7CisgICAgICAgICBpZiAoc3FsSWRlbnRpZmllci5jaGFyQXQoMCkgPT0gJyInKQorICAgICAgICAgICAgIHJldHVybiBzcWxJZGVudGlmaWVyLnN1YnN0cmluZygxLCBzcWxJZGVudGlmaWVyLmxlbmd0aCgpIC0gMSk7CisgICAgICAgICBlbHNlCisgICAgICAgICAgICAgcmV0dXJuIHNxbElkZW50aWZpZXIudG9VcHBlckNhc2UoKTsKKyAgICAgfQorCisgICAgIC8qKgorICAgICAgKiBUZXN0IGdldFNjaGVtYXMoKSB3aXRob3V0IG1vZGlmeWluZyB0aGUgZGF0YWJhc2UuCisgICAgICAqCisgICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICAqLworICAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2NoZW1hc1JlYWRPbmx5KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisKKyAgICAgICAgIFJlc3VsdFNldCBycyA9IG1ldGEuZ2V0U2NoZW1hcygpOworICAgICAgICAgY2hlY2tTY2hlbWFzKHJzLCBuZXcgU3RyaW5nWzBdKTsKKyAgICAgfQorCisKKyAgICAgLyoqCisgICAgICAqIENoZWNrIHRoZSByZXR1cm5lZCBpbmZvcm1hdGlvbiBmcm9tIGEgZ2V0U2NoZW1hcygpLiBUaGUgcGFzc2VkIGluCisgICAgICAqIFN0cmluZ1tdIGV4cGVjdGVkIGlzIGEgbGlzdCBvZiB0aGUgc2NoZW1hcyBleHBlY3RlZCB0byBiZSBwcmVzZW50IGluIHRoZQorICAgICAgKiByZXR1cm5lZCBzZXQuIFRoZSByZXR1cm5lZCBzZXQgbWF5IGNvbnRhaW4gYWRkaXRpb25hbCBzY2hlbWFzIHdoaWNoIHdpbGwKKyAgICAgICogYmUgaWdub3JlZCwgdGh1cyB0aGlzIHRlc3QgY2FuIGJlIHVzZWQgcmVnYXJkbGVzcyBvZiB0aGUgZGF0YWJhc2Ugc3RhdGUuCisgICAgICAqIFRoZSBidWlsdGluIHNjaGVtYXMgYXJlIGF1dG9tYXRpY2FsbHkgY2hlY2tlZCBhbmQgbXVzdCBub3QgYmUgcGFydCBvZiB0aGUKKyAgICAgICogcGFzc2VkIGluIGxpc3QuCisgICAgICAqLworICAgICBwdWJsaWMgc3RhdGljIHZvaWQgY2hlY2tTY2hlbWFzKFJlc3VsdFNldCBycywgU3RyaW5nW10gdXNlckV4cGVjdGVkKQorICAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb24geworCisgICAgICAgICAvLyBBZGQgaW4gdGhlIHN5c3RlbSBzY2hlbWFzCisgICAgICAgICBTdHJpbmdbXSBleHBlY3RlZCA9IG5ldyBTdHJpbmdbQlVJTFRJTl9TQ0hFTUFTLmxlbmd0aAorICAgICAgICAgICAgICAgICArIHVzZXJFeHBlY3RlZC5sZW5ndGhdOworCisgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KEJVSUxUSU5fU0NIRU1BUywgMCwgZXhwZWN0ZWQsIDAsCisgICAgICAgICAgICAgICAgIEJVSUxUSU5fU0NIRU1BUy5sZW5ndGgpOworICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh1c2VyRXhwZWN0ZWQsIDAsIGV4cGVjdGVkLCBCVUlMVElOX1NDSEVNQVMubGVuZ3RoLAorICAgICAgICAgICAgICAgICB1c2VyRXhwZWN0ZWQubGVuZ3RoKTsKKworICAgICAgICAgLy8gUmVtb3ZlIGFueSBxdW90ZXMgZnJvbSB1c2VyIHNjaGVtYXMgYW5kIHVwcGVyIGNhc2UKKyAgICAgICAgIC8vIHRob3NlIHdpdGhvdXQgcXVvdGVzLgorICAgICAgICAgZm9yIChpbnQgaSA9IEJVSUxUSU5fU0NIRU1BUy5sZW5ndGg7IGkgPCBleHBlY3RlZC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgIGV4cGVjdGVkW2ldID0gZ2V0U3RvcmVkSWRlbnRpZmllcihleHBlY3RlZFtpXSk7CisgICAgICAgICB9CisKKyAgICAgICAgIC8vIG91dHB1dCBpcyBvcmRlcmVkIGJ5IFRBQkxFX1NDSEVNCisgICAgICAgICBBcnJheXMuc29ydChleHBlY3RlZCk7CisKKyAgICAgICAgIGludCBuZXh0TWF0Y2ggPSAwOworCisgICAgICAgICB3aGlsZSAocnMubmV4dCgpKSB7CisgICAgICAgICAgICAgU3RyaW5nIHNjaGVtYSA9IHJzLmdldFN0cmluZygiVEFCTEVfU0NIRU0iKTsKKyAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHNjaGVtYSk7CisKKyAgICAgICAgICAgICAvLyBDYXRhbG9ncyBub3Qgc3VwcG9ydGVkCisvLyAgICAgICAgICAgICBhc3NlcnROdWxsKHJzLmdldFN0cmluZygiVEFCTEVfQ0FUQUxPRyIpKTsKKworICAgICAgICAgICAgIGlmIChuZXh0TWF0Y2ggPCBleHBlY3RlZC5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICAgaWYgKGV4cGVjdGVkW25leHRNYXRjaF0uZXF1YWxzKHNjaGVtYSkpIG5leHRNYXRjaCsrOworICAgICAgICAgICAgIH0KKyAgICAgICAgIH0KKyAgICAgICAgIHJzLmNsb3NlKCk7CisgICAgICAgICBhc3NlcnRFcXVhbHMoIlNjaGVtYXMgbWlzc2luZyAiLCBleHBlY3RlZC5sZW5ndGgsIG5leHRNYXRjaCk7CisgICAgIH0KKworICAgICBwcml2YXRlIHZvaWQgYXNzZXJ0TWF0Y2hlc1BhdHRlcm4oU3RyaW5nIHBhdHRlcm4sIFN0cmluZyByZXN1bHQpIHsKKyAgICAgICAgIGlmICghZG9lc01hdGNoKHBhdHRlcm4sIDAsIHJlc3VsdCwgMCkpIHsKKyAgICAgICAgICAgICBmYWlsKCJCYWQgcGF0dGVybiBtYXRjaGluZzoiICsgcGF0dGVybiArICIgcmVzdWx0OiIgKyByZXN1bHQpOworICAgICAgICAgfQorCisgICAgIH0KKworICAgICAvKioKKyAgICAgICogU2VlIGlmIGEgc3RyaW5nIG1hdGNoZXMgdGhlIHBhdHRlcm4gYXMgZGVmaW5lZCBieSBEYXRhYmFzZU1ldGFEYXRhLiBCeQorICAgICAgKiBwYXNzaW5nIGluIG5vbi16ZXJvIHZhbHVlcyBjYW4gY2hlY2sgc3ViLXNldHMgb2YgdGhlIHBhdHRlcm4gYWdhaW5zdCB0aGUKKyAgICAgICogc3ViIHN0cmluZ3Mgb2YgdGhlIHJlc3VsdC4gPEJSPgorICAgICAgKiBfIG1hdGNoZXMgYSBzaW5nbGUgY2hhcmFjdGVyIDxCUj4KKyAgICAgICogJSBtYXRjaGVzIHplcm8gb3IgbW9yZSBjaGFyYWN0ZXJzIDxCUj4KKyAgICAgICogT3RoZXIgY2hhcmFjdGVycyBtYXRjaCB0aGVtc2VsdmVzLgorICAgICAgKgorICAgICAgKiBAcGFyYW0gcGF0dGVybgorICAgICAgKiAgICAgICAgICAgIFBhdHRlcm4KKyAgICAgICogQHBhcmFtIHBwCisgICAgICAqICAgICAgICAgICAgUG9zaXRpb24gaW4gcGF0dGVybiB0byBzdGFydCB0aGUgYWN0dWFsIHBhdHRlcm4gZnJvbQorICAgICAgKiBAcGFyYW0gcmVzdWx0CisgICAgICAqICAgICAgICAgICAgcmVzdWx0IHN0cmluZworICAgICAgKiBAcGFyYW0gcnAKKyAgICAgICogICAgICAgICAgICBwb3NpdGlvbiBpbiByZXN1bHQgdG8gc3RhcnRpbmcgY2hlY2tpbmcKKyAgICAgICogQHJldHVybiB0cnVlIGlmIGEgbWF0Y2ggaXMgZm91bmQKKyAgICAgICovCisgICAgIHByaXZhdGUgYm9vbGVhbiBkb2VzTWF0Y2goU3RyaW5nIHBhdHRlcm4sIGludCBwcCwgU3RyaW5nIHJlc3VsdCwgaW50IHJwKSB7CisgICAgICAgICAvLyBGaW5kIGEgbWF0Y2gKKyAgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgICBpZiAocHAgPT0gcGF0dGVybi5sZW5ndGgoKSAmJiBycCA9PSByZXN1bHQubGVuZ3RoKCkpIHJldHVybiB0cnVlOworCisgICAgICAgICAgICAgLy8gbW9yZSBjaGFyYWN0ZXJzIHRvIG1hdGNoIGluIHRoZSByZXN1bHQgYnV0CisgICAgICAgICAgICAgLy8gbm8gbW9yZSBwYXR0ZXJuLgorICAgICAgICAgICAgIGlmIChwcCA9PSBwYXR0ZXJuLmxlbmd0aCgpKSByZXR1cm4gZmFsc2U7CisKKyAgICAgICAgICAgICBjaGFyIHBjID0gcGF0dGVybi5jaGFyQXQocHApOworICAgICAgICAgICAgIGlmIChwYyA9PSAnXycpIHsKKyAgICAgICAgICAgICAgICAgLy8gbmVlZCB0byBtYXRjaCBhIHNpbmdsZSBjaGFyYWN0ZXIgYnV0CisgICAgICAgICAgICAgICAgIC8vIGV4aGF1c3RlZCByZXN1bHQsIHNvIG5vIG1hdGNoLgorICAgICAgICAgICAgICAgICBpZiAocnAgPT0gcmVzdWx0Lmxlbmd0aCgpKSByZXR1cm4gZmFsc2U7CisKKyAgICAgICAgICAgICAgICAgcHArKzsKKyAgICAgICAgICAgICAgICAgcnArKzsKKyAgICAgICAgICAgICB9IGVsc2UgaWYgKHBjID09ICclJykgeworICAgICAgICAgICAgICAgICAvLyAlIGF0IGVuZCwgY29tcGxldGUgbWF0Y2ggcmVnYXJkbGVzcyBvZgorICAgICAgICAgICAgICAgICAvLyBwb3NpdGlvbiBvZiByZXN1bHQgc2luY2UgJSBtYXRjaGVzIHplcm8gb3IgbW9yZS4KKyAgICAgICAgICAgICAgICAgaWYgKHBwID09IHBhdHRlcm4ubGVuZ3RoKCkgLSAxKSB7CisgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgIC8vIEJydXQgZm9yY2UsIHdlIGhhdmUgYSBwYXR0ZXJuIGxpa2UgJVgKKyAgICAgICAgICAgICAgICAgLy8gYW5kIHdlIGFyZSBzYXkgaW4gdGhlIHRoaXJkIGNoYXJhY3RlciBvZgorICAgICAgICAgICAgICAgICAvLyBhYkNkZWZnWAorICAgICAgICAgICAgICAgICAvLyB0aGVuIHN0YXJ0IGEgJ0NkZWZnWCcgYW5kIGxvb2sgZm9yIGEgbWF0Y2gsCisgICAgICAgICAgICAgICAgIC8vIHRoZW4gJ2RlZmdYJyBldGMuCisgICAgICAgICAgICAgICAgIGZvciAoaW50IHNwID0gcnA7IHNwIDwgcmVzdWx0Lmxlbmd0aCgpOyBzcCsrKSB7CisgICAgICAgICAgICAgICAgICAgICBpZiAoZG9lc01hdGNoKHBhdHRlcm4sIHBwICsgMSwgcmVzdWx0LCBzcCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIYXZlIGEgbWF0Y2ggZm9yIHRoZSBwYXR0ZXJuIGFmdGVyIHRoZSAlCisgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2hpY2ggbWVhbnMgd2UgaGF2ZSBhIG1hdGNoIGZvciB0aGUgcGF0dGVybgorICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdpdGggdGhlICUgc2luY2Ugd2UgY2FuIG1hdGNoIDAgb3IgbW9yIGNoYXJhY3RlcnMKKyAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3aXRoICUuCisgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAvLyBDb3VsZCBub3QgbWF0Y2ggdGhlIHBhdHRlcm4gYWZ0ZXIgdGhlICUKKyAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgIC8vIG5lZWQgdG8gbWF0Y2ggYSBzaW5nbGUgY2hhcmFjdGVyIGJ1dAorICAgICAgICAgICAgICAgICAvLyBleGhhdXN0ZWQgcmVzdWx0LCBzbyBubyBtYXRjaC4KKyAgICAgICAgICAgICAgICAgaWYgKHJwID09IHJlc3VsdC5sZW5ndGgoKSkgcmV0dXJuIGZhbHNlOworCisgICAgICAgICAgICAgICAgIC8vIFNpbmdsZSBjaGFyYWN0ZXIsIG11c3QgbWF0Y2ggZXhhY3RseS4KKyAgICAgICAgICAgICAgICAgaWYgKHBjICE9IHJlc3VsdC5jaGFyQXQocnApKSB7CisgICAgICAgICAgICAgICAgICAgICAvLyBDb21wdXRlciBzYXlzIG5vLgorICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgIHBwKys7CisgICAgICAgICAgICAgICAgIHJwKys7CisgICAgICAgICAgICAgfQorCisgICAgICAgICB9CisKKyAgICAgfQorCisKKyAgICAgLyoqCisgICAgICAqIENoZWNrIHRoYXQgdGhlIGxpc3Qgb2YgZXNjYXBlZCBmdW5jdGlvbnMgcHJvdmlkZWQgYnkgdGhlIGRyaXZlciBpcyBhCisgICAgICAqIHN0cmljdCBzdWJldCBvZiB0aGUgc3BlY2lmaWVkIHNldCwgdGhlIGxpc3QgZG9lcyBub3QgY29udGFpbiBkdXBsaWNhdGVzLAorICAgICAgKiBhbGwgdGhlIGZ1bmN0aW9ucyBsaXN0ZWQgY2FuIGJlIGV4ZWN1dGVkIGFuZCB0aGF0IGlmIGEgZnVuY3Rpb24gaXMgbm90IGluCisgICAgICAqIHRoZSBsaXN0IGJ1dCBpcyBzcGVjaWZpZWQgaXQgY2Fubm90IGJlIGV4ZWN1dGVkLgorICAgICAgKi8KKyAgICAgcHJpdmF0ZSB2b2lkIGVzY2FwZWRGdW5jdGlvbnMoU3RyaW5nW11bXSBzcGVjTGlzdCwgU3RyaW5nIG1ldGFEYXRhTGlzdCkKKyAgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKworICAgICAgICAgYm9vbGVhbltdIHNlZW5GdW5jdGlvbiA9IG5ldyBib29sZWFuW3NwZWNMaXN0Lmxlbmd0aF07CisKKyAgICAgICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIobWV0YURhdGFMaXN0LCAiLCIpOworICAgICAgICAgaW50IGNvdW50ZXIgPSAwOworICAgICAgICAgd2hpbGUgKHN0Lmhhc01vcmVUb2tlbnMoKSkgeworICAgICAgICAgICAgIGNvdW50ZXIrKzsKKyAgICAgICAgICAgICBTdHJpbmcgZnVuY3Rpb24gPSBzdC5uZXh0VG9rZW4oKTsKKworICAgICAgICAgICAgIC8vIGZpbmQgdGhpcyBmdW5jdGlvbiBpbiB0aGUgbGlzdAorICAgICAgICAgICAgIGJvb2xlYW4gaXNTcGVjRnVuY3Rpb24gPSBmYWxzZTsKKyAgICAgICAgICAgICBmb3IgKGludCBmID0gMDsgZiA8IHNwZWNMaXN0Lmxlbmd0aDsgZisrKSB7CisgICAgICAgICAgICAgICAgIFN0cmluZ1tdIHNwZWNEZXRhaWxzID0gc3BlY0xpc3RbZl07CisgICAgICAgICAgICAgICAgIGlmIChmdW5jdGlvbi5lcXVhbHMoc3BlY0RldGFpbHNbMF0pKSB7CisgICAgICAgICAgICAgICAgICAgICAvLyBNYXRjaGVkIHNwZWMuCisgICAgICAgICAgICAgICAgICAgICBpZiAoc2VlbkZ1bmN0aW9uW2ZdKQorICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoIkZ1bmN0aW9uIGluIGxpc3QgdHdpY2U6ICIgKyBmdW5jdGlvbik7CisgICAgICAgICAgICAgICAgICAgICBzZWVuRnVuY3Rpb25bZl0gPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgaXNTcGVjRnVuY3Rpb24gPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgZXhlY3V0ZUVzY2FwZWQoc3BlY0RldGFpbHMpOworICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICBpZiAoIWlzU3BlY0Z1bmN0aW9uKSB7CisgICAgICAgICAgICAgICAgIGZhaWwoIk5vbi1KREJDIHNwZWMgZnVuY3Rpb24gaW4gbGlzdDogIiArIGZ1bmN0aW9uKTsKKyAgICAgICAgICAgICB9CisgICAgICAgICB9CisKKyAgICAgICAgIC8vIE5vdyBzZWUgaWYgYW55IHNwZWNlZCBmdW5jdGlvbnMgYXJlIG5vdCBpbiB0aGUgbWV0YWRhdGEgbGlzdAorICAgICAgICAgYXNzZXJ0U2FtZSgiRnVuY3Rpb24gbWlzc2luZyBpbiBtZXRhZGF0YSBpbXBsIixzcGVjTGlzdC5sZW5ndGgsIGNvdW50ZXIpOworICAgICAgICAgZm9yIChpbnQgZiA9IDA7IGYgPCBzcGVjTGlzdC5sZW5ndGg7IGYrKykgeworICAgICAgICAgICAgIGlmIChzZWVuRnVuY3Rpb25bZl0pIGNvbnRpbnVlOworICAgICAgICAgICAgIFN0cmluZ1tdIHNwZWNEZXRhaWxzID0gc3BlY0xpc3RbZl07CisKKyAgICAgICAgICAgICAvLyBidWcgREVSQlktNzIzIENIQVIgbWFwcyB0byB3cm9uZyBmdW5jdGlvbgorICAgICAgICAgICAgIGlmICgiQ0hBUiIuZXF1YWxzKHNwZWNEZXRhaWxzWzBdKSkgY29udGludWU7CisgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgZXhlY3V0ZUVzY2FwZWQoc3BlY0RldGFpbHMpOworICAgICAgICAgICAgICAgICBmYWlsKCJmdW5jdGlvbiB3b3JrcyBidXQgbm90IGRlY2xhcmVkIGluIGxpc3Q6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICArIHNwZWNEZXRhaWxzWzBdKTsKKyAgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAvL29rCisgICAgICAgICAgICAgfQorICAgICAgICAgfQorICAgICB9CisKKyAgICAgLyoqCisgICAgICAqIFRlc3Qgd2UgY2FuIGV4ZWN1dGUgYSBmdW5jdGlvbiBsaXN0ZWQgYXMgYSBzdXBwb3J0ZWQKKyAgICAgICogSkRCQyBlc2NhcGVkIGZ1bmN0aW9uLiBXZSBkb24ndCBjYXJlIGFib3V0IHRoZSBhY3R1YWwKKyAgICAgICogcmV0dXJuIHZhbHVlLCB0aGF0IHNob3VsZCBiZSB0ZXN0ZWQgZWxzZXdoZXJlIGluCisgICAgICAqIHRoZSBzcGVjaWZpYyB0ZXN0IG9mIGEgZnVuY3Rpb24uCisgICAgICAqLworICAgICBwcml2YXRlIHZvaWQgZXhlY3V0ZUVzY2FwZWQoU3RyaW5nW10gc3BlY0RldGFpbHMpCisgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgIHsKKworICAgICAgICAgU3RyaW5nIHNxbCA9ICJTRUxFQ1QgIiArIHNwZWNEZXRhaWxzWzBdICsgIigiOworCisgICAgICAgICBmb3IgKGludCBwID0gMDsgcCA8IHNwZWNEZXRhaWxzLmxlbmd0aCAtIDE7IHArKykKKyAgICAgICAgIHsKKyAgICAgICAgICAgICBpZiAocCAhPSAwKQorICAgICAgICAgICAgICAgICBzcWwgPSBzcWwgKyAiLCAiOworCisgICAgICAgICAgICAgc3FsID0gc3FsICsgc3BlY0RldGFpbHNbcCArIDFdOworICAgICAgICAgfQorCisgICAgICAgICBzcWwgPSBzcWwgKyAiKSA7IjsKKworICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJEYXRhYmFzZU1ldGFEYXRhVGVzdC5leGVjdXRlRXNjYXBlZCgpICIrc3FsKTsKKyAgICAgICAgIFN0YXRlbWVudCBzdCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICBSZXN1bHRTZXQgcnMgPSBzdC5leGVjdXRlUXVlcnkoc3FsKTsKKworICAgICAgICAgYXNzZXJ0Tm90TnVsbCgibm90IHN1cHBvcnRlZCBmdW5jdGlvbjogIitzcWwscnMpOworCisgICAgICAgICBycy5jbG9zZSgpOworICAgICAgICAgc3QuY2xvc2UoKTsKKyAgICAgfQorCisgIC8vRU5EIEFQQUNIRS1ERVJCWQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2phdmEvc3FsL0RlbGV0ZUZ1bmN0aW9uYWxpdHlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvamF2YS9zcWwvRGVsZXRlRnVuY3Rpb25hbGl0eVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi41M2UzZWIzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2phdmEvc3FsL0RlbGV0ZUZ1bmN0aW9uYWxpdHlUZXN0LmphdmEKQEAgLTAsMCArMSwyMDEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLmphdmEuc3FsOworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uS25vd25GYWlsdXJlOworCitpbXBvcnQgamF2YS5zcWwuQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhOworaW1wb3J0IGphdmEuc3FsLlByZXBhcmVkU3RhdGVtZW50OworaW1wb3J0IGphdmEuc3FsLlJlc3VsdFNldDsKK2ltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247CitpbXBvcnQgamF2YS5zcWwuU3RhdGVtZW50OworCitpbXBvcnQgdGVzdHMuc3VwcG9ydC5EYXRhYmFzZUNyZWF0b3I7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1NRTDsKKworaW1wb3J0IGp1bml0LmV4dGVuc2lvbnMuVGVzdFNldHVwOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitwdWJsaWMgY2xhc3MgRGVsZXRlRnVuY3Rpb25hbGl0eVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBDb25uZWN0aW9uIGNvbm4gPSBudWxsOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RhdGVtZW50IHN0YXRlbWVudCA9IG51bGw7CisKKyAgICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBTdXBwb3J0X1NRTC5sb2FkRHJpdmVyKCk7CisgICAgICAgIGNvbm4gPSBTdXBwb3J0X1NRTC5nZXRDb25uZWN0aW9uKCk7CisgICAgICAgIHN0YXRlbWVudCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgIGNyZWF0ZVRlc3RUYWJsZXMoKTsKKyAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmZpbGxQYXJlbnRUYWJsZShjb25uKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkZWxldGVUZXN0VGFibGVzKCk7CisgICAgICAgIHN0YXRlbWVudC5jbG9zZSgpOworICAgICAgICBjb25uLmNsb3NlKCk7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCBjcmVhdGVUZXN0VGFibGVzKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgRGF0YWJhc2VNZXRhRGF0YSBtZXRhID0gY29ubi5nZXRNZXRhRGF0YSgpOworICAgICAgICAgICAgUmVzdWx0U2V0IHVzZXJUYWIgPSBtZXRhLmdldFRhYmxlcyhudWxsLCBudWxsLCBudWxsLCBudWxsKTsKKworICAgICAgICAgICAgd2hpbGUgKHVzZXJUYWIubmV4dCgpKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHRhYmxlTmFtZSA9IHVzZXJUYWIuZ2V0U3RyaW5nKCJUQUJMRV9OQU1FIik7CisgICAgICAgICAgICAgICAgaWYgKHRhYmxlTmFtZS5lcXVhbHMoRGF0YWJhc2VDcmVhdG9yLlBBUkVOVF9UQUJMRSkpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEVfUEFSRU5UKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRhYmxlTmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhEYXRhYmFzZUNyZWF0b3IuRktDQVNDQURFX1RBQkxFKSkgeworICAgICAgICAgICAgICAgICAgICBzdGF0ZW1lbnQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRV9GS0NBU0NBREUpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGFibGVOYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKERhdGFiYXNlQ3JlYXRvci5GS1NUUklDVF9UQUJMRSkpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEVfRktTVFJJQ1QpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGFibGVOYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFNSkpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEU1KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICB1c2VyVGFiLmNsb3NlKCk7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuQ1JFQVRFX1RBQkxFX1BBUkVOVCk7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuQ1JFQVRFX1RBQkxFX0ZLU1RSSUNUKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEVfRktDQVNDQURFKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEU1KTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU1FMRXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZGVsZXRlVGVzdFRhYmxlcygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFX0ZLQ0FTQ0FERSk7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRV9GS1NUUklDVCk7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRV9QQVJFTlQpOworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEU1KTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU1FMRXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVsZXRlRnVuY3Rpb25hbGl0eVRlc3QjdGVzdERlbGV0ZTEoKS4gRGVsZXRlcyByb3cgd2l0aCBubworICAgICAqICAgICAgICByZWZlcmVuY2luZyBvbmVzIGFuZCBSRVNUUklDVCBhY3Rpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVsZXRlMSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBEYXRhYmFzZUNyZWF0b3IuZmlsbEZLU3RyaWN0VGFibGUoY29ubik7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKCJERUxFVEUgRlJPTSAiICsgRGF0YWJhc2VDcmVhdG9yLlBBUkVOVF9UQUJMRQorICAgICAgICAgICAgICAgICsgIiBXSEVSRSBpZCA9IDM7Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVsZXRlRnVuY3Rpb25hbGl0eVRlc3QjdGVzdERlbGV0ZTIoKS4gQXR0ZW1wdHMgdG8gZGVsZXRlIHJvdyB3aXRoCisgICAgICogICAgICAgIHJlZmVyZW5jaW5nIG9uZXMgYW5kIFJFU1RSSUNUIGFjdGlvbiAtIGV4cGVjdGluZyBTUUxFeGNlcHRpb24KKyAgICAgKiAgVE9ETyBmb3JlaWduIGtleSBmdW5jdGlvbmFsaXR5IGlzIG5vdCBzdXBwb3J0ZWQKKyAgICAgKi8KKy8qICAgIHB1YmxpYyB2b2lkIHRlc3REZWxldGUyKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIERhdGFiYXNlQ3JlYXRvci5maWxsRktTdHJpY3RUYWJsZShjb25uKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKCJERUxFVEUgRlJPTSAiICsgRGF0YWJhc2VDcmVhdG9yLlBBUkVOVF9UQUJMRQorICAgICAgICAgICAgICAgICAgICArICIgV0hFUkUgaWQgPSAxOyIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0aW5nIFNRTEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisqLworICAgIC8qKgorICAgICAqIERlbGV0ZUZ1bmN0aW9uYWxpdHlUZXN0I3Rlc3REZWxldGUzKCkuIERlbGV0ZXMgYWxsIHJlZmVyZW5jaW5nCisgICAgICogICAgICAgIHJvd3MgYW5kIHRoZW4gZGVsZXRlcyByZWZlcmVuY2VkIG9uZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REZWxldGUzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKCJERUxFVEUgRlJPTSAiICsgRGF0YWJhc2VDcmVhdG9yLkZLU1RSSUNUX1RBQkxFCisgICAgICAgICAgICAgICAgKyAiIFdIRVJFIG5hbWVfaWQgPSAxOyIpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZSgiREVMRVRFIEZST00gIiArIERhdGFiYXNlQ3JlYXRvci5GS1NUUklDVF9UQUJMRQorICAgICAgICAgICAgICAgICsgIiBXSEVSRSBpZCA9IDE7Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVsZXRlRnVuY3Rpb25hbGl0eVRlc3QjdGVzdERlbGV0ZTQoKS4gRGVsZXRlcyByb3cgd2l0aCBubworICAgICAqICAgICAgICByZWZlcmVuY2luZyBvbmVzIGFuZCBDQVNDQURFIGFjdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REZWxldGU0KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIERhdGFiYXNlQ3JlYXRvci5maWxsRktDYXNjYWRlVGFibGUoY29ubik7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKCJERUxFVEUgRlJPTSAiICsgRGF0YWJhc2VDcmVhdG9yLlBBUkVOVF9UQUJMRQorICAgICAgICAgICAgICAgICsgIiBXSEVSRSBpZCA9IDM7Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVsZXRlRnVuY3Rpb25hbGl0eVRlc3QjdGVzdERlbGV0ZTUoKS4gQXR0ZW1wdHMgdG8gZGVsZXRlIHJvdyB3aXRoCisgICAgICogICAgICAgIHJlZmVyZW5jaW5nIG9uZXMgYW5kIENBU0NBREUgYWN0aW9uIC0gZXhwZWN0aW5nIGFsbCByZWZlcmVuY2luZworICAgICAqICAgICAgICByb3dzIHdpbGwgYWxzbyBiZSBkZWxldGVkCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdERlbGV0ZTUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoIkRFTEVURSBGUk9NICIgKyBEYXRhYmFzZUNyZWF0b3IuUEFSRU5UX1RBQkxFCisgICAgICAgICAgICAgICAgKyAiIFdIRVJFIGlkID0gMTsiKTsKKworICAgICAgICBSZXN1bHRTZXQgciA9IHN0YXRlbWVudC5leGVjdXRlUXVlcnkoIlNFTEVDVCBDT1VOVCgqKSBGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5GS0NBU0NBREVfVEFCTEUgKyAiIFdIRVJFIG5hbWVfaWQgPSAxOyIpOworICAgICAgICByLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgYmUgbm8gcm93cyIsIDAsIHIuZ2V0SW50KDEpKTsKKyAgICAgICAgci5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlbGV0ZUZ1bmN0aW9uYWxpdHlUZXN0I3Rlc3REZWxldGU2KCkuCisgICAgICogIFRPRE8gRm9yZWlnbiBrZXkgZnVuY3Rpb25hbGl0eSBpcyBub3Qgc3VwcG9ydGVkCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgibm90IHN1cHBvcnRlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdERlbGV0ZTYoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmZpbGxGS1N0cmljdFRhYmxlKGNvbm4pOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZSgiREVMRVRFIEZST00gIiArIERhdGFiYXNlQ3JlYXRvci5GS1NUUklDVF9UQUJMRQorICAgICAgICAgICAgICAgICsgIiBXSEVSRSBuYW1lX2lkID0gQU5ZIChTRUxFQ1QgaWQgRlJPTSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuUEFSRU5UX1RBQkxFICsgIiBXSEVSRSBpZCA+IDEpIik7CisgICAgICAgIFJlc3VsdFNldCByID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeSgiU0VMRUNUIENPVU5UKCopIEZST00gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLkZLU1RSSUNUX1RBQkxFICsgIiBXSEVSRSBuYW1lX2lkID0gMTsiKTsKKyAgICAgICAgci5uZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIGJlIDIgcm93cyIsIDIsIHIuZ2V0SW50KDEpKTsKKyAgICAgICAgci5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlbGV0ZUZ1bmN0aW9uYWxpdHlUZXN0I3Rlc3REZWxldGU3KCkuIERlbGV0ZXMgcm93cyB1c2luZworICAgICAqICAgICAgICBQcmVwYXJlZFN0YXRlbWVudAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3REZWxldGU3KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIERhdGFiYXNlQ3JlYXRvci5maWxsVGVzdFRhYmxlNShjb25uKTsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgc3RhdCA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudCgiREVMRVRFIEZST00gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEU1ICsgIiBXSEVSRSB0ZXN0SUQgPSA/Iik7CisgICAgICAgIHN0YXQuc2V0SW50KDEsIDEpOworICAgICAgICBzdGF0LmV4ZWN1dGUoKTsKKyAgICAgICAgc3RhdC5zZXRJbnQoMSwgMik7CisgICAgICAgIHN0YXQuZXhlY3V0ZSgpOworICAgICAgICBSZXN1bHRTZXQgciA9IHN0YXRlbWVudC5leGVjdXRlUXVlcnkoIlNFTEVDVCBDT1VOVCgqKSBGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFNSArICIgV0hFUkUgdGVzdElEIDwgMyAiKTsKKyAgICAgICAgci5uZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCByLmdldEludCgxKSk7CisgICAgICAgIHIuY2xvc2UoKTsKKyAgICAgICAgc3RhdC5jbG9zZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9qYXZhL3NxbC9JbnNlcnRGdW5jdGlvbmFsaXR5VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2phdmEvc3FsL0luc2VydEZ1bmN0aW9uYWxpdHlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uM2M2YzI4ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9qYXZhL3NxbC9JbnNlcnRGdW5jdGlvbmFsaXR5VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjI1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSB0ZXN0cy5qYXZhLnNxbDsKKworaW1wb3J0IGphdmEuc3FsLkNvbm5lY3Rpb247CitpbXBvcnQgamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YTsKK2ltcG9ydCBqYXZhLnNxbC5QcmVwYXJlZFN0YXRlbWVudDsKK2ltcG9ydCBqYXZhLnNxbC5SZXN1bHRTZXQ7CitpbXBvcnQgamF2YS5zcWwuU1FMRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc3FsLlN0YXRlbWVudDsKKworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9TUUw7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5EYXRhYmFzZUNyZWF0b3I7CisKK2ltcG9ydCBqdW5pdC5leHRlbnNpb25zLlRlc3RTZXR1cDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworcHVibGljIGNsYXNzIEluc2VydEZ1bmN0aW9uYWxpdHlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgQ29ubmVjdGlvbiBjb25uID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIFN0YXRlbWVudCBzdGF0ZW1lbnQgPSBudWxsOworCisgICAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgU3VwcG9ydF9TUUwubG9hZERyaXZlcigpOworICAgICAgICBjb25uID0gU3VwcG9ydF9TUUwuZ2V0Q29ubmVjdGlvbigpOworICAgICAgICBzdGF0ZW1lbnQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICBjcmVhdGVUZXN0VGFibGVzKCk7CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkZWxldGVUZXN0VGFibGVzKCk7CisgICAgICAgIHN0YXRlbWVudC5jbG9zZSgpOworICAgICAgICBjb25uLmNsb3NlKCk7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY3JlYXRlVGVzdFRhYmxlcygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIERhdGFiYXNlTWV0YURhdGEgbWV0YSA9IGNvbm4uZ2V0TWV0YURhdGEoKTsKKyAgICAgICAgICAgIFJlc3VsdFNldCB1c2VyVGFiID0gbWV0YS5nZXRUYWJsZXMobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7CisKKyAgICAgICAgICAgIHdoaWxlICh1c2VyVGFiLm5leHQoKSkgeworICAgICAgICAgICAgICAgIFN0cmluZyB0YWJsZU5hbWUgPSB1c2VyVGFiLmdldFN0cmluZygiVEFCTEVfTkFNRSIpOworICAgICAgICAgICAgICAgIGlmICh0YWJsZU5hbWUuZXF1YWxzKERhdGFiYXNlQ3JlYXRvci5QQVJFTlRfVEFCTEUpKSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFX1BBUkVOVCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0YWJsZU5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoRGF0YWJhc2VDcmVhdG9yLkZLQ0FTQ0FERV9UQUJMRSkpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEVfRktDQVNDQURFKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRhYmxlTmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhEYXRhYmFzZUNyZWF0b3IuRktTVFJJQ1RfVEFCTEUpKSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFX0ZLU1RSSUNUKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRhYmxlTmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMSkpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEVfU0lNUExFMSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0YWJsZU5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTIpKSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFX1NJTVBMRTIpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGFibGVOYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFNSkpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEU1KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICB1c2VyVGFiLmNsb3NlKCk7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuQ1JFQVRFX1RBQkxFX1BBUkVOVCk7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuQ1JFQVRFX1RBQkxFX0ZLU1RSSUNUKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEVfRktDQVNDQURFKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEVfU0lNUExFMik7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuQ1JFQVRFX1RBQkxFX1NJTVBMRTEpOworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkNSRUFURV9UQUJMRTUpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTUUxFeGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBkZWxldGVUZXN0VGFibGVzKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEVfRktDQVNDQURFKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFX0ZLU1RSSUNUKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFX1BBUkVOVCk7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRV9TSU1QTEUyKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFX1NJTVBMRTEpOworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEU1KTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU1FMRXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0RnVuY3Rpb25hbGl0eVRlc3QjdGVzdEluc2VydDEoKS4gQXR0ZW1wdHMgdG8gaW5zZXJ0IHJvdyBpbnRvCisgICAgICogICAgICAgIHRhYmxlIHdpdGggaW50ZWdyaXR5IGNoZWNraW5nCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEluc2VydDEoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmZpbGxQYXJlbnRUYWJsZShjb25uKTsKKyAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmZpbGxGS1N0cmljdFRhYmxlKGNvbm4pOworICAgICAgICBEYXRhYmFzZUNyZWF0b3IuZmlsbEZLQ2FzY2FkZVRhYmxlKGNvbm4pOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZSgiSU5TRVJUIElOVE8gIiArIERhdGFiYXNlQ3JlYXRvci5GS1NUUklDVF9UQUJMRQorICAgICAgICAgICAgICAgICsgIiBWQUxVRVMoNCwgMSwgJ3Rlc3RJbnNlcnQnKSIpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZSgiSU5TRVJUIElOVE8gIiArIERhdGFiYXNlQ3JlYXRvci5GS0NBU0NBREVfVEFCTEUKKyAgICAgICAgICAgICAgICArICIgVkFMVUVTKDQsIDEsICd0ZXN0SW5zZXJ0JykiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnNlcnRGdW5jdGlvbmFsaXR5VGVzdCN0ZXN0SW5zZXJ0MigpLiBBdHRlbXB0cyB0byBpbnNlcnQgcm93IGludG8KKyAgICAgKiAgICAgICAgdGFibGUgd2l0aCBpbnRlZ3JpdHkgY2hlY2tpbmcgd2hlbiByb3cgaGFzIGluY29ycmVjdCBmb3JlaWduIGtleQorICAgICAqICAgICAgICB2YWx1ZSAtIGV4cGVjdGluZyBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5zZXJ0MigpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBEYXRhYmFzZUNyZWF0b3IuZmlsbFBhcmVudFRhYmxlKGNvbm4pOworICAgICAgICBEYXRhYmFzZUNyZWF0b3IuZmlsbEZLU3RyaWN0VGFibGUoY29ubik7CisgICAgICAgIERhdGFiYXNlQ3JlYXRvci5maWxsRktDYXNjYWRlVGFibGUoY29ubik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZSgiSU5TRVJUIElOVE8gIiArIERhdGFiYXNlQ3JlYXRvci5GS1NUUklDVF9UQUJMRQorICAgICAgICAgICAgICAgICAgICArICIgVkFMVUVTKDQsIDQsICd0ZXN0SW5zZXJ0JykiKTsKKyAgICAgICAgICAgLy8gVE9ETyBGb3JlaWduIGtleSBmdW5jdGlvbmFsaXR5IGlzbid0IHN1cHBvcnRlZAorICAgICAgICAgICAvLyBmYWlsKCJleHBlY3RpbmcgU1FMRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoIklOU0VSVCBJTlRPICIgKyBEYXRhYmFzZUNyZWF0b3IuRktDQVNDQURFX1RBQkxFCisgICAgICAgICAgICAgICAgICAgICsgIiBWQUxVRVMoNCwgNCwgJ3Rlc3RJbnNlcnQnKSIpOworICAgICAgICAgICAvLyBUT0RPIEZvcmVpZ24ga2V5IGZ1bmN0aW9uYWxpdHkgaXNuJ3Qgc3VwcG9ydGVkCisgICAgICAgICAgIC8vIGZhaWwoImV4cGVjdGluZyBTUUxFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0RnVuY3Rpb25hbGl0eVRlc3QjdGVzdEluc2VydDMoKS4gVGVzdHMgSU5TRVJUIC4uLiBTRUxFQ1QKKyAgICAgKiAgICAgICAgZnVuY3Rpb25hbGl0eQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnNlcnQzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIERhdGFiYXNlQ3JlYXRvci5maWxsUGFyZW50VGFibGUoY29ubik7CisgICAgICAgIERhdGFiYXNlQ3JlYXRvci5maWxsRktTdHJpY3RUYWJsZShjb25uKTsKKyAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoIklOU0VSVCBJTlRPICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTUKKyAgICAgICAgICAgICAgICArICIgU0VMRUNUIGlkIEFTIHRlc3RJZCwgdmFsdWUgQVMgdGVzdFZhbHVlICIgKyAiRlJPTSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuRktTVFJJQ1RfVEFCTEUgKyAiIFdIRVJFIG5hbWVfaWQgPSAxIik7CisgICAgICAgIFJlc3VsdFNldCByID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeSgiU0VMRUNUIENPVU5UKCopIEZST00gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEU1KTsKKyAgICAgICAgci5uZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIGJlIDIgcm93cyIsIDIsIHIuZ2V0SW50KDEpKTsKKyAgICAgICAgci5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluc2VydEZ1bmN0aW9uYWxpdHlUZXN0I3Rlc3RJbnNlcnQ0KCkuIFRlc3RzIElOU0VSVCAuLi4gU0VMRUNUCisgICAgICogICAgICAgIHdpdGggZXhwcmVzc2lvbnMgaW4gU0VMRUNUIHF1ZXJ5CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEluc2VydDQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmZpbGxTaW1wbGVUYWJsZTEoY29ubik7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKCJJTlNFUlQgSU5UTyAiICsgRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTIKKyAgICAgICAgICAgICAgICArICIgU0VMRUNUIGlkLCBzcGVlZCoxMCBBUyBzcGVlZCwgc2l6ZS0xIEFTIHNpemUgRlJPTSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMSk7CisgICAgICAgIFJlc3VsdFNldCByID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeSgiU0VMRUNUIENPVU5UKCopIEZST00gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTIgKyAiIEFTIGEgSk9JTiAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMQorICAgICAgICAgICAgICAgICsgIiBBUyBiIE9OIGEuc3BlZWQgPSAxMCpiLnNwZWVkIEFORCBhLnNpemUgPSBiLnNpemUtMSIpOworICAgICAgICByLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgYmUgMiByb3dzIiwgMiwgci5nZXRJbnQoMSkpOworICAgICAgICByLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0RnVuY3Rpb25hbGl0eVRlc3QjdGVzdEluc2VydDUoKS4gSW5zZXJ0cyBtdWx0aXBsZSByb3dzIHVzaW5nCisgICAgICogICAgICAgIFVOSU9OIEFMTAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnNlcnQ1KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKCJJTlNFUlQgSU5UTyAiICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEU1CisgICAgICAgICAgICAgICAgKyAiIFNFTEVDVCAxIGFzIHRlc3RJZCwgMiBhcyB0ZXN0VmFsdWUgIgorICAgICAgICAgICAgICAgICsgIlVOSU9OIFNFTEVDVCAyIGFzIHRlc3RJZCwgMyBhcyB0ZXN0VmFsdWUgIgorICAgICAgICAgICAgICAgICsgIlVOSU9OIFNFTEVDVCAzIGFzIHRlc3RJZCwgNCBhcyB0ZXN0VmFsdWUiKTsKKyAgICAgICAgUmVzdWx0U2V0IHIgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KCJTRUxFQ1QgQ09VTlQoKikgRlJPTSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTUpOworICAgICAgICByLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgYmUgMyByb3dzIiwgMywgci5nZXRJbnQoMSkpOworICAgICAgICByLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5zZXJ0RnVuY3Rpb25hbGl0eVRlc3QjdGVzdEluc2VydDYoKS4gVGVzdHMgSU5TRVJUIHdpdGgKKyAgICAgKiAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5zZXJ0UHJlcGFyZWQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgc3RhdCA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudCgiSU5TRVJUIElOVE8gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEU1ICsgIiBWQUxVRVMoPywgPykiKTsKKyAgICAgICAgc3RhdC5zZXRJbnQoMSwgMSk7CisgICAgICAgIHN0YXQuc2V0U3RyaW5nKDIsICIxIik7CisgICAgICAgIHN0YXQuZXhlY3V0ZSgpOworICAgICAgICBzdGF0LnNldEludCgxLCAyKTsKKyAgICAgICAgc3RhdC5zZXRTdHJpbmcoMiwgIjMiKTsKKyAgICAgICAgc3RhdC5leGVjdXRlKCk7CisgICAgICAgIFJlc3VsdFNldCByID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeSgiU0VMRUNUIENPVU5UKCopIEZST00gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEU1CisgICAgICAgICAgICAgICAgKyAiIFdIRVJFICh0ZXN0SWQgPSAxIEFORCB0ZXN0VmFsdWUgPSAnMScpICIKKyAgICAgICAgICAgICAgICArICJPUiAodGVzdElkID0gMiBBTkQgdGVzdFZhbHVlID0gJzMnKSIpOworICAgICAgICByLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbnVtYmVyIG9mIHJlY29yZHMiLCAyLCByLmdldEludCgxKSk7CisgICAgICAgIHIuY2xvc2UoKTsKKyAgICAgICAgc3RhdC5jbG9zZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9qYXZhL3NxbC9NdWx0aVRocmVhZEFjY2Vzc1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9qYXZhL3NxbC9NdWx0aVRocmVhZEFjY2Vzc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi45NDc3NzdiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2phdmEvc3FsL011bHRpVGhyZWFkQWNjZXNzVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDMzIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmphdmEuc3FsOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7CitpbXBvcnQgamF2YS5zcWwuQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5SZXN1bHRTZXQ7CitpbXBvcnQgamF2YS5zcWwuU1FMRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc3FsLlN0YXRlbWVudDsKKworaW1wb3J0IHRlc3RzLnN1cHBvcnQuRGF0YWJhc2VDcmVhdG9yOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9TUUw7CisKK2ltcG9ydCBqdW5pdC5leHRlbnNpb25zLlRlc3RTZXR1cDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworaW1wb3J0IHRlc3RzLnN1cHBvcnQuVGhyZWFkUG9vbDsKKworcHVibGljIGNsYXNzIE11bHRpVGhyZWFkQWNjZXNzVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIENvbm5lY3Rpb24gY29ubjsKKworICAgIHByaXZhdGUgc3RhdGljIFN0YXRlbWVudCBzdGF0ZW1lbnQ7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgbnVtVGhyZWFkcyA9IDEwOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IG51bU9mUmVjb3JkcyA9IDIwOworCisgICAgcHJpdmF0ZSBUaHJlYWRQb29sIHRocmVhZFBvb2w7CisKKyAgICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBTdXBwb3J0X1NRTC5sb2FkRHJpdmVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb25uID0gU3VwcG9ydF9TUUwuZ2V0Q29ubmVjdGlvbigpOworICAgICAgICAgICAgc3RhdGVtZW50ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgIGNyZWF0ZVRlc3RUYWJsZXMoKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU1FMRXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIHRocmVhZFBvb2wgPSBuZXcgVGhyZWFkUG9vbChudW1UaHJlYWRzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0aHJlYWRQb29sLmpvaW4oKTsKKyAgICAgICAgZGVsZXRlVGVzdFRhYmxlcygpOworICAgICAgICBjb25uLmNsb3NlKCk7CisgICAgICAgIHN0YXRlbWVudC5jbG9zZSgpOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGNyZWF0ZVRlc3RUYWJsZXMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSZXN1bHRTZXQgdXNlclRhYiA9IGNvbm4uZ2V0TWV0YURhdGEoKS5nZXRUYWJsZXMobnVsbCwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwgbnVsbCk7CisKKyAgICAgICAgICAgIHdoaWxlICh1c2VyVGFiLm5leHQoKSkgeworICAgICAgICAgICAgICAgIFN0cmluZyB0YWJsZU5hbWUgPSB1c2VyVGFiLmdldFN0cmluZygiVEFCTEVfTkFNRSIpOworICAgICAgICAgICAgICAgIGlmICh0YWJsZU5hbWUuZXF1YWxzKERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSkpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEUxKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRhYmxlTmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTIpKSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFMik7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0YWJsZU5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEU0KSkgeworICAgICAgICAgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRTQpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGFibGVOYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMykpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEUzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHVzZXJUYWIuY2xvc2UoKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEUzKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEU0KTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEUxKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEUyKTsKKworICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmZpbGxUZXN0VGFibGUxKGNvbm4sIG51bU9mUmVjb3Jkcyk7CisgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuZmlsbFRlc3RUYWJsZTIoY29ubiwgbnVtT2ZSZWNvcmRzKTsKKyAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5maWxsVGVzdFRhYmxlNChjb25uLCBudW1PZlJlY29yZHMpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTUUxFeGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBkZWxldGVUZXN0VGFibGVzKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEUxKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFMik7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRTMpOworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEU0KTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU1FMRXhjZXB0aW9uICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBmZXcgdGhyZWFkcyBleGVjdXRlIHNlbGVjdCBvcGVyYXRpb24gaW4gdGhlIHNhbWUgdGltZSBmb3Igb25lIHRhYmxlIGluCisgICAgICogdGhlIGRhdGFiYXNlLiBOdW1iZXIgb2YgdGhyZWFkcyBpcyBkZWZpbmVkIGJ5IG51bVRocmVhZHMgdmFyaWFibGUKKyAgICAgKgorICAgICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9NdWx0aXBsZUFjY2Vzc1RvT25lVGFibGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1UaHJlYWRzOyBpKyspIHsKKyAgICAgICAgICAgIHRocmVhZFBvb2wucnVuVGFzayhjcmVhdGVUYXNrMShpKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBIGZldyB0aHJlYWRzIGV4ZWN1dGUgc2VsZWN0IG9wZXJhdGlvbiBpbiB0aGUgc2FtZSB0aW1lIGZvciBkaWZmZXJlbnQKKyAgICAgKiB0YWJsZXMgaW4gdGhlIGRhdGFiYXNlLiBOdW1iZXIgb2YgdGhyZWFkcyBpcyBkZWZpbmVkIGJ5IG51bVRocmVhZHMKKyAgICAgKiB2YXJpYWJsZQorICAgICAqCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X011bHRpcGxlQWNjZXNzVG9TZXZlcmFsVGFibGVzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIHRocmVhZFBvb2wucnVuVGFzayhjcmVhdGVUYXNrMSgxKSk7CisgICAgICAgIHRocmVhZFBvb2wucnVuVGFzayhjcmVhdGVUYXNrMigyKSk7CisgICAgICAgIHRocmVhZFBvb2wucnVuVGFzayhjcmVhdGVUYXNrMygzKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBmZXcgdGhyZWFkcyBleGVjdXRlIHVwZGF0ZSwgaW5zZXJ0IGFuZCBkZWxldGUgb3BlcmF0aW9ucyBpbiB0aGUgc2FtZQorICAgICAqIHRpbWUgZm9yIG9uZSB0YWJsZSBpbiB0aGUgZGF0YWJhc2UuIE51bWJlciBvZiB0aHJlYWRzIGlzIGRlZmluZWQgYnkKKyAgICAgKiBudW1UaHJlYWRzIHZhcmlhYmxlCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfTXVsdGlwbGVPcGVyYXRpb25zSW5TZXZlcmFsVGFibGVzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBpZDEgPSBudW1PZlJlY29yZHMgLSAxOworICAgICAgICB0aHJlYWRQb29sLnJ1blRhc2soY3JlYXRlVGFzazQoaWQxKSk7CisKKyAgICAgICAgaW50IGlkMiA9IG51bU9mUmVjb3JkcyArIDE7CisgICAgICAgIHRocmVhZFBvb2wucnVuVGFzayhjcmVhdGVUYXNrNShpZDIpKTsKKworICAgICAgICBpbnQgb2xkSUQgPSA1OworICAgICAgICBpbnQgbmV3SUQgPSAxMDA7CisgICAgICAgIHRocmVhZFBvb2wucnVuVGFzayhjcmVhdGVUYXNrNihvbGRJRCwgbmV3SUQpKTsKKworICAgICAgICB0aHJlYWRQb29sLmpvaW4oKTsKKworICAgICAgICBTdGF0ZW1lbnQgc3RhdGVtZW50ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgU3RyaW5nIHNlbGVjdFF1ZXJ5ID0gIlNFTEVDVCAqIEZST00gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMQorICAgICAgICAgICAgICAgICsgIiBXSEVSRSBpZD0iOworCisgICAgICAgIFJlc3VsdFNldCByZXN1bHQgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KHNlbGVjdFF1ZXJ5ICsgaWQxKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSByZWNvcmQgd2FzIG5vdCBkZWxldGVkIiwgcmVzdWx0Lm5leHQoKSk7CisKKyAgICAgICAgcmVzdWx0ID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeShzZWxlY3RRdWVyeSArIGlkMik7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSByZWNvcmQgd2FzIG5vdCBpbnNlcnRlZCIsIHJlc3VsdC5uZXh0KCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgb2YgZmllbGQxIiwgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRTdHJpbmcKKyAgICAgICAgICAgICAgICArIGlkMiwgcmVzdWx0LmdldFN0cmluZygiZmllbGQxIikpOworLy8gICAgICAgICBUT0RPIGdldEJpZ0RlY2ltYWwgaXMgbm90IHN1cHBvcnRlZAorICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIG9mIGZpZWxkMiIsIEludGVnZXIudmFsdWVPZihpZDIpLmludFZhbHVlKCksIHJlc3VsdAorICAgICAgICAgICAgICAgIC5nZXRJbnQoImZpZWxkMiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSBvZiBmaWVsZDMiLCBJbnRlZ2VyLnZhbHVlT2YoaWQyKS5pbnRWYWx1ZSgpLCByZXN1bHQKKyAgICAgICAgICAgICAgICAuZ2V0SW50KCJmaWVsZDMiKSk7CisgICAgICAgIHJlc3VsdC5jbG9zZSgpOworCisgICAgICAgIHJlc3VsdCA9IHN0YXRlbWVudC5leGVjdXRlUXVlcnkoc2VsZWN0UXVlcnkgKyBvbGRJRCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgcmVjb3JkIHdhcyBub3QgZGVsZXRlZCIsIHJlc3VsdC5uZXh0KCkpOworICAgICAgICByZXN1bHQuY2xvc2UoKTsKKworICAgICAgICByZXN1bHQgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KHNlbGVjdFF1ZXJ5ICsgbmV3SUQpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgcmVjb3JkIHdhcyBub3QgdXBkYXRlZCIsIHJlc3VsdC5uZXh0KCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgb2YgZmllbGQxIiwgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRTdHJpbmcKKyAgICAgICAgICAgICAgICArIG5ld0lELCByZXN1bHQuZ2V0U3RyaW5nKCJmaWVsZDEiKSk7CisgICAgICAgIC8vIFRPRE8gZ2V0QmlnRGVjaW1hbCBpcyBub3Qgc3VwcG9ydGVkCisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgb2YgZmllbGQyIiwgSW50ZWdlci52YWx1ZU9mKG5ld0lEKS5pbnRWYWx1ZSgpLCByZXN1bHQKKyAgICAgICAgICAgICAgICAuZ2V0SW50KCJmaWVsZDIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgb2YgZmllbGQzIiwgSW50ZWdlci52YWx1ZU9mKG5ld0lEKS5pbnRWYWx1ZSgpLCByZXN1bHQKKyAgICAgICAgICAgICAgICAuZ2V0SW50KCJmaWVsZDMiKSk7CisgICAgICAgIHJlc3VsdC5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgZmV3IHRocmVhZHMgZXhlY3V0ZSB1cGRhdGUgb3BlcmF0aW9uIGluIHRoZSBzYW1lIHRpbWUgZm9yIG9uZSB0YWJsZXMgaW4KKyAgICAgKiB0aGUgZGF0YWJhc2UuIE51bWJlciBvZiB0aHJlYWRzIGlzIGRlZmluZWQgYnkgbnVtVGhyZWFkcyB2YXJpYWJsZQorICAgICAqCisgICAgICogQHRocm93cyBTUUxFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X011bHRpcGxlVXBkYXRlc0luT25lVGFibGVzKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIGludCBpZCA9IDE7CisgICAgICAgIFN0cmluZyBmaWVsZCA9ICJmaWVsZDMiOworCisgICAgICAgIFN0cmluZyBzZWxlY3RRdWVyeSA9ICJTRUxFQ1QgKiBGUk9NICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgV0hFUkUgaWQ9IiArIGlkOworICAgICAgICBTdGF0ZW1lbnQgc3RhdGVtZW50ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKworICAgICAgICBSZXN1bHRTZXQgcmVzdWx0ID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeShzZWxlY3RRdWVyeSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZXJlIGlzIG5vIHJlY29yZHMgd2l0aCBpZCA9ICIgKyBpZCwgcmVzdWx0Lm5leHQoKSk7CisgICAgICAgIC8vIFRPRE8gZ2V0QmlnRGVjaW1hbCBpcyBub3Qgc3VwcG9ydGVkCisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSBvZiBmaWVsZCAiICsgZmllbGQsIEJpZ0RlY2ltYWwudmFsdWVPZihpZCksCisvLyAgICAgICAgICAgICAgICByZXN1bHQuZ2V0QmlnRGVjaW1hbChmaWVsZCkpOworICAgICAgICByZXN1bHQuY2xvc2UoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bVRocmVhZHM7IGkrKykgeworICAgICAgICAgICAgdGhyZWFkUG9vbC5ydW5UYXNrKGNyZWF0ZVRhc2s3KGlkLCBmaWVsZCkpOworICAgICAgICB9CisKKyAgICAgICAgdGhyZWFkUG9vbC5qb2luKCk7CisKKyAgICAgICAgZG91YmxlIGV4cGVjdGVkVmFsID0gaWQgKyBudW1UaHJlYWRzOworICAgICAgICByZXN1bHQgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KHNlbGVjdFF1ZXJ5KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlcmUgaXMgbm8gcmVjb3JkcyB3aXRoIGlkID0gIiArIGlkLCByZXN1bHQubmV4dCgpKTsKKyAgICAgICAgLy8gVE9ETyBnZXRCaWdEZWNpbWFsIGlzIG5vdCBzdXBwb3J0ZWQgLT4KKy8vICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIG9mIGZpZWxkICIgKyBmaWVsZCwgZXhwZWN0ZWRWYWwsIHJlc3VsdAorLy8gICAgICAgICAgICAgICAgLmdldEJpZ0RlY2ltYWwoZmllbGQpLmRvdWJsZVZhbHVlKCkpOworICAgICAgICByZXN1bHQuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBjcmVhdGVzIGEgUnVubmFibGUgdGhhdCBleGVjdXRlcyBzZWxlY3Qgb3BlcmF0aW9uIGZvciB0aGUKKyAgICAgKiBmaXJzdCB0YWJsZQorICAgICAqCisgICAgICogQHBhcmFtIHRhc2tJRAorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBSdW5uYWJsZSBjcmVhdGVUYXNrMShmaW5hbCBpbnQgdGFza0lEKSB7CisgICAgICAgIHJldHVybiBuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU3RhdGVtZW50IHN0YXRlbWVudCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgICAgIFJlc3VsdFNldCByZXN1bHQgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KCJTRUxFQ1QgKiBGUk9NICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMSk7CisKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHJlc3VsdC5uZXh0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgb2YgaWQgIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRTdHJpbmcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHJlc3VsdC5nZXRJbnQoImlkIiksIHJlc3VsdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRTdHJpbmcoImZpZWxkMSIpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgb2YgZmllbGQyICIsIHJlc3VsdC5nZXRJbnQoImlkIiksIHJlc3VsdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0SW50KCJmaWVsZDIiKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIG9mIGZpZWxkMyAiLHJlc3VsdC5nZXRJbnQoImlkIiksIHJlc3VsdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0SW50KCJmaWVsZDMiKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJUYXNrIDEgIitlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBSdW5uYWJsZSB0aGF0IGV4ZWN1dGUgc2VsZWN0IG9wZXJhdGlvbiBmb3IgdGhlCisgICAgICogc2Vjb25kIHRhYmxlCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGFza0lECisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgUnVubmFibGUgY3JlYXRlVGFzazIoZmluYWwgaW50IHRhc2tJRCkgeworICAgICAgICByZXR1cm4gbmV3IFJ1bm5hYmxlKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFN0YXRlbWVudCBzdGF0ZW1lbnQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgICAgICBSZXN1bHRTZXQgcmVzdWx0ID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeSgiU0VMRUNUICogRlJPTSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTIpOworCisgICAgICAgICAgICAgICAgICAgIHdoaWxlIChyZXN1bHQubmV4dCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAocmVzdWx0Lm5leHQoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpZCA9IHJlc3VsdC5nZXRJbnQoImZpbnRlZ2VyIik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSBvZiBmdGV4dCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuZGVmYXVsdFN0cmluZyArIGlkLCByZXN1bHQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldFN0cmluZygiZnRleHQiKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSBvZiBmY2hhcmFjdGVyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5kZWZhdWx0Q2hhcmFjdGVyICsgaWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuZ2V0U3RyaW5nKCJmY2hhcmFjdGVyIikpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgb2YgZmRlY2ltYWwiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHREb3VibGUgKyBpZCwgcmVzdWx0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXREb3VibGUoImZkZWNpbWFsIikpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgb2YgZm51bWVyaWMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHREb3VibGUgKyBpZCwgcmVzdWx0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXREb3VibGUoImZudW1lcmljIikpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgb2YgZnNtYWxsaW50IiwgcmVzdWx0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0SW50KCJmaW50ZWdlciIpLCByZXN1bHQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRTaG9ydCgiZnNtYWxsaW50IikpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgb2YgZmZsb2F0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmbG9hdCkgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHREb3VibGUgKyBpZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5nZXRGbG9hdCgiZmZsb2F0IikpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgdmFsdWUgb2YgZnJlYWwiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZsb2F0KSBEYXRhYmFzZUNyZWF0b3IuZGVmYXVsdERvdWJsZSArIGlkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmdldEZsb2F0KCJmcmVhbCIpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIG9mIGZkb3VibGUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHREb3VibGUgKyBpZCwgcmVzdWx0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXREb3VibGUoImZkb3VibGUiKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJUYXNrMiAiK2UuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgY3JlYXRlcyBhIFJ1bm5hYmxlIHRoYXQgZXhlY3V0ZSBzZWxlY3Qgb3BlcmF0aW9uIGZvciB0aGUKKyAgICAgKiB0aGlyZCB0YWJsZQorICAgICAqCisgICAgICogQHBhcmFtIHRhc2tJRAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFJ1bm5hYmxlIGNyZWF0ZVRhc2szKGZpbmFsIGludCB0YXNrSUQpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBTdGF0ZW1lbnQgc3RhdGVtZW50ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgICAgICAgICAgICAgUmVzdWx0U2V0IHJlc3VsdCA9IHN0YXRlbWVudC5leGVjdXRlUXVlcnkoIlNFTEVDVCAqIEZST00gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEU0KTsKKworICAgICAgICAgICAgICAgICAgICB3aGlsZSAocmVzdWx0Lm5leHQoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyB2YWx1ZSBvZiBmaWVsZDEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuZGVmYXVsdFN0cmluZworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgcmVzdWx0LmdldEludCgiZmsiKSwgcmVzdWx0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldFN0cmluZygiZmllbGQxIikpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVGFzayAzICIrZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBjcmVhdGVzIGEgUnVubmFibGUgdGhhdCBleGVjdXRlcyBkZWxldGUgb3BlcmF0aW9uIGZvciB0aGUKKyAgICAgKiBmaXJzdCB0YWJsZQorICAgICAqCisgICAgICogQHBhcmFtIHRhc2tJRAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFJ1bm5hYmxlIGNyZWF0ZVRhc2s0KGZpbmFsIGludCBpZCkgeworICAgICAgICByZXR1cm4gbmV3IFJ1bm5hYmxlKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFN0YXRlbWVudCBzdGF0ZW1lbnQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZSgiREVMRVRFIEZST00gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxICsgIiBXSEVSRSBpZD0iICsgaWQpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVGFzayA0ICIrZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBjcmVhdGVzIGEgUnVubmFibGUgdGhhdCBleGVjdXRlcyBpbnNlcnQgb3BlcmF0aW9uIGZvciB0aGUKKyAgICAgKiBmaXJzdCB0YWJsZQorICAgICAqCisgICAgICogQHBhcmFtIHRhc2tJRAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFJ1bm5hYmxlIGNyZWF0ZVRhc2s1KGZpbmFsIGludCBpZCkgeworICAgICAgICByZXR1cm4gbmV3IFJ1bm5hYmxlKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFN0YXRlbWVudCBzdGF0ZW1lbnQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBEYXRhYmFzZUNyZWF0b3IuZGVmYXVsdFN0cmluZyArIGlkOworCisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBpbnNlcnRRdWVyeSA9ICJJTlNFUlQgSU5UTyAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgKGlkLCBmaWVsZDEsIGZpZWxkMiwgZmllbGQzKSBWQUxVRVMoIiArIGlkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiLCAnIiArIHZhbHVlICsgIicsICIgKyBpZCArICIsICIgKyBpZCArICIpIjsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoaW5zZXJ0UXVlcnkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVGFzayA1ICIrZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBjcmVhdGVzIGEgUnVubmFibGUgdGhhdCBleGVjdXRlcyB1cGRhdGUgb3BlcmF0aW9uIGZvciB0aGUgb25lCisgICAgICogcmVjb3JkIG9mIHRoZSBmaXJzdCB0YWJsZQorICAgICAqCisgICAgICogQHBhcmFtIHRhc2tJRAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFJ1bm5hYmxlIGNyZWF0ZVRhc2s2KGZpbmFsIGludCBvbGRJRCwgZmluYWwgaW50IG5ld0lEKSB7CisgICAgICAgIHJldHVybiBuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU3RhdGVtZW50IHN0YXRlbWVudCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IERhdGFiYXNlQ3JlYXRvci5kZWZhdWx0U3RyaW5nICsgbmV3SUQ7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyB1cGRhdGVRdWVyeSA9ICJVUERBVEUgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxICsgIiBTRVQgaWQ9IiArIG5ld0lECisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiLCBmaWVsZDE9JyIgKyB2YWx1ZSArICInLCBmaWVsZDI9IiArIG5ld0lECisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiLCBmaWVsZDM9IiArIG5ld0lEICsgIiBXSEVSRSBpZD0iICsgb2xkSUQ7CisgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKHVwZGF0ZVF1ZXJ5KTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlRhc2sgNiAiK2UuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgY3JlYXRlcyBhIFJ1bm5hYmxlIHRoYXQgZXhlY3V0ZXMgdXBkYXRlIG9wZXJhdGlvbiBmb3IgdGhlIG9uZQorICAgICAqIGZpZWxkIG9mIG9uZSByZWNvcmQgd2l0aCBpZGVudGlmaWVyIGlkIGluIHRoZSBmaXJzdCB0YWJsZQorICAgICAqCisgICAgICogQHBhcmFtIHRhc2tJRAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFJ1bm5hYmxlIGNyZWF0ZVRhc2s3KGZpbmFsIGludCBpZCwgZmluYWwgU3RyaW5nIGZpZWxkKSB7CisgICAgICAgIHJldHVybiBuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU3RhdGVtZW50IHN0YXRlbWVudCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyB1cGRhdGVRdWVyeSA9ICJVUERBVEUgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxICsgIiBTRVQgIiArIGZpZWxkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiPSAiICsgZmllbGQgKyAiKyAxIFdIRVJFIGlkPSIgKyBpZDsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUodXBkYXRlUXVlcnkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVGFzayA3ICIrZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvamF2YS9zcWwvU2VsZWN0RnVuY3Rpb25hbGl0eVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9qYXZhL3NxbC9TZWxlY3RGdW5jdGlvbmFsaXR5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjRjMDI4NTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvamF2YS9zcWwvU2VsZWN0RnVuY3Rpb25hbGl0eVRlc3QuamF2YQpAQCAtMCwwICsxLDU0MyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5qYXZhLnNxbDsKKworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLktub3duRmFpbHVyZTsKKworaW1wb3J0IGphdmEuaW8uQ2hhckFycmF5UmVhZGVyOworaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOworaW1wb3J0IGphdmEuc3FsLkNvbm5lY3Rpb247CitpbXBvcnQgamF2YS5zcWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnNxbC5QcmVwYXJlZFN0YXRlbWVudDsKK2ltcG9ydCBqYXZhLnNxbC5SZXN1bHRTZXQ7CitpbXBvcnQgamF2YS5zcWwuU1FMRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc3FsLlN0YXRlbWVudDsKK2ltcG9ydCBqYXZhLnNxbC5UaW1lOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworCitpbXBvcnQgdGVzdHMuc3VwcG9ydC5EYXRhYmFzZUNyZWF0b3I7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1NRTDsKK2ltcG9ydCBqdW5pdC5leHRlbnNpb25zLlRlc3RTZXR1cDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworcHVibGljIGNsYXNzIFNlbGVjdEZ1bmN0aW9uYWxpdHlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgQ29ubmVjdGlvbiBjb25uOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RhdGVtZW50IHN0YXRlbWVudDsKKworICAgIHByaXZhdGUgc3RhdGljIERhdGUgZGF0ZTsKKworICAgIHByaXZhdGUgc3RhdGljIFRpbWUgdGltZTsKKworICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIFN1cHBvcnRfU1FMLmxvYWREcml2ZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4gPSBTdXBwb3J0X1NRTC5nZXRDb25uZWN0aW9uKCk7CisgICAgICAgICAgICBzdGF0ZW1lbnQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgY3JlYXRlVGVzdFRhYmxlcygpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTUUxFeGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkZWxldGVUZXN0VGFibGVzKCk7CisgICAgICAgIGNvbm4uY2xvc2UoKTsKKyAgICAgICAgc3RhdGVtZW50LmNsb3NlKCk7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZVRlc3RUYWJsZXMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSZXN1bHRTZXQgdXNlclRhYiA9IGNvbm4uZ2V0TWV0YURhdGEoKS5nZXRUYWJsZXMobnVsbCwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwgbnVsbCk7CisKKyAgICAgICAgICAgIHdoaWxlICh1c2VyVGFiLm5leHQoKSkgeworICAgICAgICAgICAgICAgIFN0cmluZyB0YWJsZU5hbWUgPSB1c2VyVGFiLmdldFN0cmluZygiVEFCTEVfTkFNRSIpOworICAgICAgICAgICAgICAgIGlmICh0YWJsZU5hbWUuZXF1YWxzKERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMikpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEUyKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRhYmxlTmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhEYXRhYmFzZUNyZWF0b3IuU0FMRVNQRU9QTEVfVEFCTEUpKSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFX1NBTEVTUEVPUExFKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRhYmxlTmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhEYXRhYmFzZUNyZWF0b3IuQ1VTVE9NRVJTX1RBQkxFKSkgeworICAgICAgICAgICAgICAgICAgICBzdGF0ZW1lbnQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRV9DVVNUT01FUlMpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGFibGVOYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKERhdGFiYXNlQ3JlYXRvci5PUkRFUlNfVEFCTEUpKSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFX09SREVSUyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgdXNlclRhYi5jbG9zZSgpOworCisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuQ1JFQVRFX1RBQkxFMik7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuQ1JFQVRFX1RBQkxFX1NBTEVTUEVPUExFKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEVfQ1VTVE9NRVJTKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEVfT1JERVJTKTsKKworICAgICAgICAgICAgbG9uZyBjdXJyZW50VGltZSA9IENhbGVuZGFyLmdldEluc3RhbmNlKCkuZ2V0VGltZUluTWlsbGlzKCk7CisgICAgICAgICAgICBkYXRlID0gbmV3IERhdGUoY3VycmVudFRpbWUpOworICAgICAgICAgICAgdGltZSA9IG5ldyBUaW1lKGN1cnJlbnRUaW1lKTsKKworICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmZpbGxUZXN0VGFibGUyKGNvbm4sIDEsIDUsIGN1cnJlbnRUaW1lKTsKKyAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5maWxsQ3VzdG9tZXJzVGFibGUoY29ubik7CisgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuZmlsbE9yZGVyc1RhYmxlKGNvbm4pOworICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmZpbGxTYWxlc1Blb3BsZVRhYmxlKGNvbm4pOworCisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNRTEV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBkZWxldGVUZXN0VGFibGVzKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEUyKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFX1NBTEVTUEVPUExFKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFX0NVU1RPTUVSUyk7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRV9PUkRFUlMpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTUUxFeGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWxlY3RGdW5jdGlvbmFsaXR5VGVzdCN0ZXN0X1NlbGVjdFNpbXBsZSgpLiBTZWxlY3RzIGFsbCByZWNvcmRzCisgICAgICogICAgICAgIGZyb20gdGhlIHRhYmxlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9TZWxlY3RTaW1wbGUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHNxbCA9ICJTRUxFQ1QgKiBGUk9NICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTI7CisgICAgICAgIFJlc3VsdFNldCByZXN1bHQgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KHNxbCk7CisgICAgICAgIGludCBjb3VudGVyID0gMDsKKworICAgICAgICB3aGlsZSAocmVzdWx0Lm5leHQoKSkgeworICAgICAgICAgICAgaW50IGlkID0gcmVzdWx0LmdldEludCgiZmludGVnZXIiKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZXhwZWN0ZWQgdmFsdWUgZG9lc24ndCBlcXVhbCBhY3R1YWwiLAorICAgICAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuZGVmYXVsdFN0cmluZyArIGlkLCByZXN1bHQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0U3RyaW5nKCJmdGV4dCIpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZXhwZWN0ZWQgdmFsdWUgZG9lc24ndCBlcXVhbCBhY3R1YWwiLAorICAgICAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuZGVmYXVsdENoYXJhY3RlciArIGlkLCByZXN1bHQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0U3RyaW5nKCJmY2hhcmFjdGVyIikpOworCisgICAgICAgICAgICAvLyBUT0RPIGdldEJpZ0RlY2ltYWwgaXMgbm90IHN1cHBvcnRlZAorLy8gICAgICAgICAgICBhc3NlcnRFcXVhbHMoImV4cGVjdGVkIHZhbHVlIGRvZXNuJ3QgZXF1YWwgYWN0dWFsIiwgQmlnRGVjaW1hbAorLy8gICAgICAgICAgICAgICAgICAgIC52YWx1ZU9mKGlkICsgMC4xKSwgcmVzdWx0LmdldEJpZ0RlY2ltYWwoImZkZWNpbWFsIikpOworLy8gICAgICAgICAgICBhc3NlcnRFcXVhbHMoImV4cGVjdGVkIHZhbHVlIGRvZXNuJ3QgZXF1YWwgYWN0dWFsIiwgQmlnRGVjaW1hbAorLy8gICAgICAgICAgICAgICAgICAgIC52YWx1ZU9mKGlkICsgMC4xKSwgcmVzdWx0LmdldEJpZ0RlY2ltYWwoImZudW1lcmljIikpOworLy8gICAgICAgICAgICBhc3NlcnRFcXVhbHMoImV4cGVjdGVkIHZhbHVlIGRvZXNuJ3QgZXF1YWwgYWN0dWFsIiwgaWQsIHJlc3VsdAorLy8gICAgICAgICAgICAgICAgICAgIC5nZXRJbnQoImZzbWFsbGludCIpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZXhwZWN0ZWQgdmFsdWUgZG9lc24ndCBlcXVhbCBhY3R1YWwiLCBCaWdEZWNpbWFsCisgICAgICAgICAgICAgICAgICAgIC52YWx1ZU9mKGlkICsgMC4xKS5mbG9hdFZhbHVlKCksIHJlc3VsdC5nZXRGbG9hdCgiZmZsb2F0IikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJleHBlY3RlZCB2YWx1ZSBkb2Vzbid0IGVxdWFsIGFjdHVhbCIsIEJpZ0RlY2ltYWwKKyAgICAgICAgICAgICAgICAgICAgLnZhbHVlT2YoaWQgKyAwLjEpLmRvdWJsZVZhbHVlKCksIHJlc3VsdC5nZXREb3VibGUoImZyZWFsIikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJleHBlY3RlZCB2YWx1ZSBkb2Vzbid0IGVxdWFsIGFjdHVhbCIsIEJpZ0RlY2ltYWwKKyAgICAgICAgICAgICAgICAgICAgLnZhbHVlT2YoaWQgKyAwLjEpLmRvdWJsZVZhbHVlKCksIHJlc3VsdAorICAgICAgICAgICAgICAgICAgICAuZ2V0RG91YmxlKCJmZG91YmxlIikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJleHBlY3RlZCB2YWx1ZSBkb2Vzbid0IGVxdWFsIGFjdHVhbCIsCisgICAgICAgICAgICAgICAgICAgIGRhdGUudG9TdHJpbmcoKSwgcmVzdWx0LmdldERhdGUoImZkYXRlIikudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImV4cGVjdGVkIHZhbHVlIGRvZXNuJ3QgZXF1YWwgYWN0dWFsIiwKKyAgICAgICAgICAgICAgICAgICAgdGltZS50b1N0cmluZygpLCByZXN1bHQuZ2V0VGltZSgiZnRpbWUiKS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGNvdW50ZXIrKzsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygibnVtYmVyIG9mIHJvd3MgaW4gUmVzdWx0U2V0IGlzIHdyb25nIiwgNSwgY291bnRlcik7CisgICAgICAgIHJlc3VsdC5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbGVjdEZ1bmN0aW9uYWxpdHlUZXN0I3Rlc3RfU2VsZWN0UHJlcGFyZWQoKS4gU2VsZWN0cyBhbGwgcmVjb3JkcworICAgICAqICAgICAgICBmcm9tIHRoZSB0YWJsZSB1c2luZyBwYXJhbWV0cmljIHF1ZXJ5CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9TZWxlY3RQcmVwYXJlZCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc3FsID0gIlNFTEVDVCBmaW50ZWdlciwgZnRleHQsIGZjaGFyYWN0ZXIsIGZkZWNpbWFsLCBmbnVtZXJpYywiCisgICAgICAgICAgICAgICAgKyAiIGZzbWFsbGludCwgZmZsb2F0LCBmcmVhbCwgZmRvdWJsZSwgZmRhdGUsIGZ0aW1lIiArICIgRlJPTSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTIKKyAgICAgICAgICAgICAgICArICIgV0hFUkUgZmludGVnZXIgPSA/IEFORCBmdGV4dCA9ID8gQU5EIGZjaGFyYWN0ZXIgPSA/IEFORCIKKyAgICAgICAgICAgICAgICArICIgZmRlY2ltYWwgPSA/IEFORCBmbnVtZXJpYyA9ID8gQU5EIGZzbWFsbGludCA9ID8gQU5EIgorICAgICAgICAgICAgICAgICsgIiBmcmVhbCA9ID8gQU5EIGZkb3VibGUgPSA/IEFORCBmZGF0ZSA9ID8iICsgIiBBTkQgZnRpbWUgPSA/IjsKKyAgICAgICAgUHJlcGFyZWRTdGF0ZW1lbnQgcHJlcFN0YXRlbWVudCA9IGNvbm4ucHJlcGFyZVN0YXRlbWVudChzcWwpOworCisgICAgICAgIENoYXJBcnJheVJlYWRlciByZWFkZXIgPSBuZXcgQ2hhckFycmF5UmVhZGVyKG5ldyBTdHJpbmcoCisgICAgICAgICAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRDaGFyYWN0ZXIgKyAiMSIpLnRvQ2hhckFycmF5KCkpOworICAgICAgICBwcmVwU3RhdGVtZW50LnNldEludCgxLCAxKTsKKyAgICAgICAgcHJlcFN0YXRlbWVudC5zZXRTdHJpbmcoMiwgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRTdHJpbmcgKyAiMSIpOworLy8gICAgICBUT0RPIHNldENoYXJhY3RlclN0cmVhbSBhbmQgc2V0QmlnRGVjaW1hbCBhcmUgbm90IHN1cHBvcnRlZAorLy8gICAgICAgIHByZXBTdGF0ZW1lbnQuc2V0Q2hhcmFjdGVyU3RyZWFtKDMsIHJlYWRlciwgNCk7CisvLyAgICAgICAgcHJlcFN0YXRlbWVudC5zZXRCaWdEZWNpbWFsKDQsIEJpZ0RlY2ltYWwudmFsdWVPZigxLjEpKTsKKy8vICAgICAgICBwcmVwU3RhdGVtZW50LnNldEJpZ0RlY2ltYWwoNSwgQmlnRGVjaW1hbC52YWx1ZU9mKDEuMSkpOworICAgICAgICBwcmVwU3RhdGVtZW50LnNldEludCg2LCAxKTsKKyAgICAgICAgcHJlcFN0YXRlbWVudC5zZXREb3VibGUoNywgMS4xKTsKKyAgICAgICAgcHJlcFN0YXRlbWVudC5zZXREb3VibGUoOCwgMS4xKTsKKyAgICAgICAgcHJlcFN0YXRlbWVudC5zZXREYXRlKDksIGRhdGUpOworICAgICAgICBwcmVwU3RhdGVtZW50LnNldFRpbWUoMTAsIHRpbWUpOworCisgICAgICAgIGludCBjb3VudGVyID0gMDsKKyAgICAgICAgUmVzdWx0U2V0IHJlc3VsdCA9IHByZXBTdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KCk7CisgICAgICAgIHdoaWxlIChyZXN1bHQubmV4dCgpKSB7CisgICAgICAgICAgICBpbnQgaWQgPSByZXN1bHQuZ2V0SW50KCJmaW50ZWdlciIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJleHBlY3RlZCB2YWx1ZSBkb2Vzbid0IGVxdWFsIGFjdHVhbCIsCisgICAgICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5kZWZhdWx0U3RyaW5nICsgaWQsIHJlc3VsdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRTdHJpbmcoImZ0ZXh0IikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJleHBlY3RlZCB2YWx1ZSBkb2Vzbid0IGVxdWFsIGFjdHVhbCIsCisgICAgICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5kZWZhdWx0Q2hhcmFjdGVyICsgaWQsIHJlc3VsdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRTdHJpbmcoImZjaGFyYWN0ZXIiKSk7CisvLyAgICAgICAgICAgIFRPRE8gZ2V0QmlnRGVjaW1hbCBpcyBub3Qgc3VwcG9ydGVkCisvLyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZXhwZWN0ZWQgdmFsdWUgZG9lc24ndCBlcXVhbCBhY3R1YWwiLCBCaWdEZWNpbWFsCisvLyAgICAgICAgICAgICAgICAgICAgLnZhbHVlT2YoMS4xKSwgcmVzdWx0LmdldEJpZ0RlY2ltYWwoImZkZWNpbWFsIikpOworLy8gICAgICAgICAgICBhc3NlcnRFcXVhbHMoImV4cGVjdGVkIHZhbHVlIGRvZXNuJ3QgZXF1YWwgYWN0dWFsIiwgQmlnRGVjaW1hbAorLy8gICAgICAgICAgICAgICAgICAgIC52YWx1ZU9mKDEuMSksIHJlc3VsdC5nZXRCaWdEZWNpbWFsKCJmbnVtZXJpYyIpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZXhwZWN0ZWQgdmFsdWUgZG9lc24ndCBlcXVhbCBhY3R1YWwiLCBpZCwgcmVzdWx0CisgICAgICAgICAgICAgICAgICAgIC5nZXRJbnQoImZzbWFsbGludCIpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZXhwZWN0ZWQgdmFsdWUgZG9lc24ndCBlcXVhbCBhY3R1YWwiLAorICAgICAgICAgICAgICAgICAgICAoZmxvYXQpIChpZCArIDAuMSksIHJlc3VsdC5nZXRGbG9hdCgiZmZsb2F0IikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJleHBlY3RlZCB2YWx1ZSBkb2Vzbid0IGVxdWFsIGFjdHVhbCIsCisgICAgICAgICAgICAgICAgICAgIChkb3VibGUpIChpZCArIDAuMSksIHJlc3VsdC5nZXREb3VibGUoImZyZWFsIikpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJleHBlY3RlZCB2YWx1ZSBkb2Vzbid0IGVxdWFsIGFjdHVhbCIsCisgICAgICAgICAgICAgICAgICAgIChkb3VibGUpIChpZCArIDAuMSksIHJlc3VsdC5nZXREb3VibGUoImZkb3VibGUiKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImV4cGVjdGVkIHZhbHVlIGRvZXNuJ3QgZXF1YWwgYWN0dWFsIiwKKyAgICAgICAgICAgICAgICAgICAgZGF0ZS50b1N0cmluZygpLCByZXN1bHQuZ2V0RGF0ZSgiZmRhdGUiKS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZXhwZWN0ZWQgdmFsdWUgZG9lc24ndCBlcXVhbCBhY3R1YWwiLAorICAgICAgICAgICAgICAgICAgICB0aW1lLnRvU3RyaW5nKCksIHJlc3VsdC5nZXRUaW1lKCJmdGltZSIpLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgY291bnRlcisrOworICAgICAgICB9CisvLyAgICAgICBUT0RPIHF1ZXJ5IHdhc24ndCBleGVjdXRlZCBkdWUgdG8gIm5vdCBzdXBwb3J0ZWQiIG1ldGhvZHMKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoIm51bWJlciBvZiByb3dzIGluIFJlc3VsdFNldCBpcyB3cm9uZyIsIDEsIGNvdW50ZXIpOworICAgICAgICBwcmVwU3RhdGVtZW50LmNsb3NlKCk7CisgICAgICAgIHJlc3VsdC5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbGVjdEZ1bmN0aW9uYWxpdHlUZXN0I3Rlc3RfU3ViU2VsZWN0KCkuIFNlbGVjdHMgcmVjb3JkcyBmcm9tIHRoZQorICAgICAqICAgICAgICB0YWJsZSB1c2luZyBzdWJzZWxlY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1N1YlNlbGVjdCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc3FsID0gIlNFTEVDVCBmaW50ZWdlciwiICsgIiAoU0VMRUNUIGZ0ZXh0IEZST00gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUyICsgIiBXSEVSRSBmaW50ZWdlciA9IDEpIGFzIGZ0ZXh0IgorICAgICAgICAgICAgICAgICsgIiBGUk9NICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTI7CisgICAgICAgIFJlc3VsdFNldCByZXN1bHQgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KHNxbCk7CisKKyAgICAgICAgSGFzaE1hcDxJbnRlZ2VyLCBTdHJpbmc+IHZhbHVlID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgU3RyaW5nPigpOworICAgICAgICB2YWx1ZS5wdXQoMSwgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRTdHJpbmcgKyAiMSIpOworICAgICAgICB2YWx1ZS5wdXQoMiwgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRTdHJpbmcgKyAiMSIpOworICAgICAgICB2YWx1ZS5wdXQoMywgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRTdHJpbmcgKyAiMSIpOworICAgICAgICB2YWx1ZS5wdXQoNCwgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRTdHJpbmcgKyAiMSIpOworICAgICAgICB2YWx1ZS5wdXQoNSwgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRTdHJpbmcgKyAiMSIpOworCisgICAgICAgIHdoaWxlIChyZXN1bHQubmV4dCgpKSB7CisgICAgICAgICAgICBpbnQga2V5ID0gcmVzdWx0LmdldEludCgiZmludGVnZXIiKTsKKyAgICAgICAgICAgIFN0cmluZyB2YWwgPSByZXN1bHQuZ2V0U3RyaW5nKCJmdGV4dCIpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgid3JvbmcgdmFsdWUgb2YgZmludGVnZXIgZmllbGQiLCB2YWx1ZS5jb250YWluc0tleShrZXkpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygid3JvbmcgdmFsdWUgb2YgZnRleHQgZmllbGQiLCB2YWx1ZS5nZXQoa2V5KSwgdmFsKTsKKyAgICAgICAgICAgIHZhbHVlLnJlbW92ZShrZXkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoImV4cGVjdGVkIHJvd3MgbnVtYmVyIGRvZXNuJ3QgZXF1YWwgYWN0dWFsIHJvd3MgbnVtYmVyIiwKKyAgICAgICAgICAgICAgICB2YWx1ZS5pc0VtcHR5KCkpOworICAgICAgICByZXN1bHQuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWxlY3RGdW5jdGlvbmFsaXR5VGVzdCN0ZXN0X1NlbGVjdFRocmVlVGFibGVzKCkuIFNlbGVjdHMgcmVjb3JkcworICAgICAqICAgICAgICBmcm9tIGEgZmV3IHRhYmxlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfU2VsZWN0VGhyZWVUYWJsZXMoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHNxbCA9ICJTRUxFQ1Qgb251bSwgIiArIERhdGFiYXNlQ3JlYXRvci5PUkRFUlNfVEFCTEUgKyAiLmNudW0iCisgICAgICAgICAgICAgICAgKyAiIEZST00gIiArIERhdGFiYXNlQ3JlYXRvci5TQUxFU1BFT1BMRV9UQUJMRSArICIsICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5DVVNUT01FUlNfVEFCTEUgKyAiLCAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuT1JERVJTX1RBQkxFICsgIiBXSEVSRSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuQ1VTVE9NRVJTX1RBQkxFICsgIi5jaXR5IDw+ICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5TQUxFU1BFT1BMRV9UQUJMRSArICIuY2l0eSIgKyAiIEFORCAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuT1JERVJTX1RBQkxFICsgIi5jbnVtID0gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLkNVU1RPTUVSU19UQUJMRSArICIuY251bSIgKyAiIEFORCAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuT1JERVJTX1RBQkxFICsgIi5zbnVtID0gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlNBTEVTUEVPUExFX1RBQkxFICsgIi5zbnVtIjsKKyAgICAgICAgUmVzdWx0U2V0IHJlc3VsdCA9IHN0YXRlbWVudC5leGVjdXRlUXVlcnkoc3FsKTsKKworICAgICAgICBIYXNoTWFwPEludGVnZXIsIEludGVnZXI+IHZhbHVlID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgSW50ZWdlcj4oKTsKKyAgICAgICAgdmFsdWUucHV0KDMwMDEsIDIwMDgpOworICAgICAgICB2YWx1ZS5wdXQoMzAwMiwgMjAwNyk7CisgICAgICAgIHZhbHVlLnB1dCgzMDA2LCAyMDA4KTsKKyAgICAgICAgdmFsdWUucHV0KDMwMDksIDIwMDIpOworICAgICAgICB2YWx1ZS5wdXQoMzAwNywgMjAwNCk7CisgICAgICAgIHZhbHVlLnB1dCgzMDEwLCAyMDA0KTsKKworICAgICAgICB3aGlsZSAocmVzdWx0Lm5leHQoKSkgeworICAgICAgICAgICAgaW50IGtleSA9IHJlc3VsdC5nZXRJbnQoIm9udW0iKTsKKyAgICAgICAgICAgIGludCB2YWwgPSByZXN1bHQuZ2V0SW50KCJjbnVtIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ3cm9uZyB2YWx1ZSBvZiBvbnVtIGZpZWxkIiwgdmFsdWUuY29udGFpbnNLZXkoa2V5KSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIHZhbHVlIG9mIGNudW0gZmllbGQiLCB2YWx1ZS5nZXQoa2V5KSwKKyAgICAgICAgICAgICAgICAgICAgKEludGVnZXIpIHZhbCk7CisgICAgICAgICAgICB2YWx1ZS5yZW1vdmUoa2V5KTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJleHBlY3RlZCByb3dzIG51bWJlciBkb2Vzbid0IGVxdWFsIGFjdHVhbCByb3dzIG51bWJlciIsCisgICAgICAgICAgICAgICAgdmFsdWUuaXNFbXB0eSgpKTsKKyAgICAgICAgcmVzdWx0LmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VsZWN0RnVuY3Rpb25hbGl0eVRlc3QjdGVzdF9TZWxlY3RUaHJlZVRhYmxlcygpLiBTZWxlY3RzIHJlY29yZHMKKyAgICAgKiAgICAgICAgZnJvbSBhIHRhYmxlIHVzaW5nIHVuaW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9TZWxlY3RVbmlvbkl0c2VsZigpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc3FsID0gIlNFTEVDVCBiLmNudW0sIGIuY25hbWUiICsgIiBGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5DVVNUT01FUlNfVEFCTEUgKyAiIGEsICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5DVVNUT01FUlNfVEFCTEUgKyAiIGIiCisgICAgICAgICAgICAgICAgKyAiIFdIRVJFIGEuc251bSA9IDEwMDIiICsgIiBBTkQgYi5jaXR5ID0gYS5jaXR5IjsKKyAgICAgICAgUmVzdWx0U2V0IHJlc3VsdCA9IHN0YXRlbWVudC5leGVjdXRlUXVlcnkoc3FsKTsKKworICAgICAgICBIYXNoTWFwPEludGVnZXIsIFN0cmluZz4gdmFsdWUgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBTdHJpbmc+KCk7CisgICAgICAgIHZhbHVlLnB1dCgyMDAzLCAiTGl1Iik7CisgICAgICAgIHZhbHVlLnB1dCgyMDA0LCAiR3Jhc3MiKTsKKyAgICAgICAgdmFsdWUucHV0KDIwMDgsICJDaXNuZXJvcyIpOworCisgICAgICAgIHdoaWxlIChyZXN1bHQubmV4dCgpKSB7CisgICAgICAgICAgICBpbnQga2V5ID0gcmVzdWx0LmdldEludCgiY251bSIpOworICAgICAgICAgICAgU3RyaW5nIHZhbCA9IHJlc3VsdC5nZXRTdHJpbmcoImNuYW1lIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ3cm9uZyB2YWx1ZSBvZiBjbnVtIGZpZWxkIiwgdmFsdWUuY29udGFpbnNLZXkoa2V5KSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIHZhbHVlIG9mIGNuYW1lIGZpZWxkIiwgdmFsdWUuZ2V0KGtleSksIHZhbCk7CisgICAgICAgICAgICB2YWx1ZS5yZW1vdmUoa2V5KTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJleHBlY3RlZCByb3dzIG51bWJlciBkb2Vzbid0IGVxdWFsIGFjdHVhbCByb3dzIG51bWJlciIsCisgICAgICAgICAgICAgICAgdmFsdWUuaXNFbXB0eSgpKTsKKyAgICAgICAgcmVzdWx0LmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VsZWN0RnVuY3Rpb25hbGl0eVRlc3QjdGVzdF9TZWxlY3RMZWZ0T3V0ZXJKb2luKCkuIFNlbGVjdHMKKyAgICAgKiAgICAgICAgcmVjb3JkcyBmcm9tIGEgdGFibGUgdXNpbmcgbGVmdCBqb2luCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9TZWxlY3RMZWZ0T3V0ZXJKb2luKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzcWwgPSAiU0VMRUNUIGRpc3RpbmN0IHMuc251bSBhcyBzc251bSwgYy5zbnVtIGFzIGNjbnVtIEZST00gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLkNVU1RPTUVSU19UQUJMRSArICIgYyBsZWZ0IG91dGVyIGpvaW4gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlNBTEVTUEVPUExFX1RBQkxFICsgIiBzIG9uIHMuc251bT1jLnNudW0iOworICAgICAgICBSZXN1bHRTZXQgcmVzdWx0ID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeShzcWwpOworCisgICAgICAgIEhhc2hNYXA8SW50ZWdlciwgSW50ZWdlcj4gdmFsdWUgPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPigpOworICAgICAgICB2YWx1ZS5wdXQoMTAwMSwgMTAwMSk7CisgICAgICAgIHZhbHVlLnB1dCgxMDAyLCAxMDAyKTsKKyAgICAgICAgdmFsdWUucHV0KDEwMDMsIDEwMDMpOworICAgICAgICB2YWx1ZS5wdXQoMTAwNCwgMTAwNCk7CisgICAgICAgIHZhbHVlLnB1dCgxMDA3LCAxMDA3KTsKKworICAgICAgICB3aGlsZSAocmVzdWx0Lm5leHQoKSkgeworICAgICAgICAgICAgaW50IGtleSA9IHJlc3VsdC5nZXRJbnQoInNzbnVtIik7CisgICAgICAgICAgICBPYmplY3QgdmFsID0gcmVzdWx0LmdldE9iamVjdCgiY2NudW0iKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIndyb25nIHZhbHVlIG9mIHNzbnVtIGZpZWxkIiwgdmFsdWUuY29udGFpbnNLZXkoa2V5KSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIHZhbHVlIG9mIGNjbnVtIGZpZWxkIiwgdmFsdWUuZ2V0KGtleSksCisgICAgICAgICAgICAgICAgICAgIChJbnRlZ2VyKSB2YWwpOworICAgICAgICAgICAgdmFsdWUucmVtb3ZlKGtleSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiZXhwZWN0ZWQgcm93cyBudW1iZXIgZG9lc24ndCBlcXVhbCBhY3R1YWwgcm93cyBudW1iZXIiLAorICAgICAgICAgICAgICAgIHZhbHVlLmlzRW1wdHkoKSk7CisgICAgICAgIHJlc3VsdC5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbGVjdEZ1bmN0aW9uYWxpdHlUZXN0I3Rlc3RfU2VsZWN0UmlnaHRPdXRlckpvaW4oKS4gU2VsZWN0cworICAgICAqICAgICAgICByZWNvcmRzIGZyb20gYSB0YWJsZSB1c2luZyByaWdodCBqb2luCisgICAgICoKKyAgICAgKiBUT0RPIFJJR0hUIGFuZCBGVUxMIE9VVEVSIEpPSU5zIGFyZSBub3Qgc3VwcG9ydGVkCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgibm90IHN1cHBvcnRlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdF9TZWxlY3RSaWdodE91dGVySm9pbigpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc3FsID0gIlNFTEVDVCBkaXN0aW5jdCBzLnNudW0gYXMgc3NudW0sIGMuc251bSBhcyBjY251bSBGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5DVVNUT01FUlNfVEFCTEUgKyAiIGMgcmlnaHQgb3V0ZXIgam9pbiAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuU0FMRVNQRU9QTEVfVEFCTEUgKyAiIHMgb24gcy5zbnVtPWMuc251bSI7CisgICAgICAgIFJlc3VsdFNldCByZXN1bHQgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KHNxbCk7CisKKyAgICAgICAgSGFzaE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiB2YWx1ZSA9IG5ldyBIYXNoTWFwPEludGVnZXIsIEludGVnZXI+KCk7CisgICAgICAgIHZhbHVlLnB1dCgxMDAxLCAxMDAxKTsKKyAgICAgICAgdmFsdWUucHV0KDEwMDIsIDEwMDIpOworICAgICAgICB2YWx1ZS5wdXQoMTAwMywgMTAwMyk7CisgICAgICAgIHZhbHVlLnB1dCgxMDA0LCAxMDA0KTsKKyAgICAgICAgdmFsdWUucHV0KDEwMDcsIDEwMDcpOworICAgICAgICB2YWx1ZS5wdXQoMTAxMywgbnVsbCk7CisKKyAgICAgICAgd2hpbGUgKHJlc3VsdC5uZXh0KCkpIHsKKyAgICAgICAgICAgIGludCBrZXkgPSByZXN1bHQuZ2V0SW50KCJzc251bSIpOworICAgICAgICAgICAgT2JqZWN0IHZhbCA9IHJlc3VsdC5nZXRPYmplY3QoImNjbnVtIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ3cm9uZyB2YWx1ZSBvZiBzc251bSBmaWVsZCIsIHZhbHVlLmNvbnRhaW5zS2V5KGtleSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ3cm9uZyB2YWx1ZSBvZiBjY251bSBmaWVsZCIsIHZhbHVlLmdldChrZXkpLAorICAgICAgICAgICAgICAgICAgICAoSW50ZWdlcikgdmFsKTsKKyAgICAgICAgICAgIHZhbHVlLnJlbW92ZShrZXkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoImV4cGVjdGVkIHJvd3MgbnVtYmVyIGRvZXNuJ3QgZXF1YWwgYWN0dWFsIHJvd3MgbnVtYmVyIiwKKyAgICAgICAgICAgICAgICB2YWx1ZS5pc0VtcHR5KCkpOworICAgICAgICByZXN1bHQuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWxlY3RGdW5jdGlvbmFsaXR5VGVzdCN0ZXN0X1NlbGVjdEdyb3VwQnkoKS4gU2VsZWN0cyByZWNvcmRzIGZyb20KKyAgICAgKiAgICAgICAgYSB0YWJsZSB1c2luZyBncm91cCBieQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfU2VsZWN0R3JvdXBCeSgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc2VsZWN0UXVlcnkgPSAiU0VMRUNUIHJhdGluZywgU1VNKHNudW0pIEFTIHN1bSBGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5DVVNUT01FUlNfVEFCTEUgKyAiIEdST1VQIEJZIHJhdGluZyI7CisgICAgICAgIFJlc3VsdFNldCByZXN1bHQgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KHNlbGVjdFF1ZXJ5KTsKKworICAgICAgICBIYXNoTWFwPEludGVnZXIsIEludGVnZXI+IHZhbHVlcyA9IG5ldyBIYXNoTWFwPEludGVnZXIsIEludGVnZXI+KCk7CisgICAgICAgIHZhbHVlcy5wdXQoMTAwLCAzMDA2KTsKKyAgICAgICAgdmFsdWVzLnB1dCgyMDAsIDIwMDUpOworICAgICAgICB2YWx1ZXMucHV0KDMwMCwgMjAwOSk7CisKKyAgICAgICAgd2hpbGUgKHJlc3VsdC5uZXh0KCkpIHsKKyAgICAgICAgICAgIGludCByYXRpbmcgPSByZXN1bHQuZ2V0SW50KCJyYXRpbmciKTsKKyAgICAgICAgICAgIGludCBzdW0gPSByZXN1bHQuZ2V0SW50KCJzdW0iKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIldyb25nIHZhbHVlIG9mIHJhdGluZyBmaWVsZCIsIHZhbHVlcworICAgICAgICAgICAgICAgICAgICAuY29udGFpbnNLZXkocmF0aW5nKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHZhbHVlIG9mIHN1bSBmaWVsZCIsIHZhbHVlcy5nZXQocmF0aW5nKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoc3VtKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobmV3IEludGVnZXIoc3VtKSwgdmFsdWVzLnJlbW92ZShyYXRpbmcpKTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHQuY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUmVzdWx0IHNldCBoYXMgd3Jvbmcgc2l6ZSIsIHZhbHVlcy5pc0VtcHR5KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbGVjdEZ1bmN0aW9uYWxpdHlUZXN0I3Rlc3RfU2VsZWN0T3JkZXJCeSgpLiBTZWxlY3RzIHJlY29yZHMgZnJvbQorICAgICAqICAgICAgICBhIHRhYmxlIHVzaW5nIG9yZGVyIGJ5CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9TZWxlY3RPcmRlckJ5KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzZWxlY3RRdWVyeSA9ICJTRUxFQ1Qgb251bSBGUk9NICIgKyBEYXRhYmFzZUNyZWF0b3IuT1JERVJTX1RBQkxFCisgICAgICAgICAgICAgICAgKyAiIE9SREVSIEJZIG9udW0iOworICAgICAgICBSZXN1bHRTZXQgcmVzdWx0ID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeShzZWxlY3RRdWVyeSk7CisKKyAgICAgICAgQXJyYXlMaXN0PEludGVnZXI+IHZhbHVlcyA9IG5ldyBBcnJheUxpc3Q8SW50ZWdlcj4oKTsKKyAgICAgICAgdmFsdWVzLmFkZChJbnRlZ2VyLnZhbHVlT2YoMzAwMSkpOworICAgICAgICB2YWx1ZXMuYWRkKEludGVnZXIudmFsdWVPZigzMDAyKSk7CisgICAgICAgIHZhbHVlcy5hZGQoSW50ZWdlci52YWx1ZU9mKDMwMDMpKTsKKyAgICAgICAgdmFsdWVzLmFkZChJbnRlZ2VyLnZhbHVlT2YoMzAwNSkpOworICAgICAgICB2YWx1ZXMuYWRkKEludGVnZXIudmFsdWVPZigzMDA2KSk7CisgICAgICAgIHZhbHVlcy5hZGQoSW50ZWdlci52YWx1ZU9mKDMwMDcpKTsKKyAgICAgICAgdmFsdWVzLmFkZChJbnRlZ2VyLnZhbHVlT2YoMzAwOCkpOworICAgICAgICB2YWx1ZXMuYWRkKEludGVnZXIudmFsdWVPZigzMDA5KSk7CisgICAgICAgIHZhbHVlcy5hZGQoSW50ZWdlci52YWx1ZU9mKDMwMTApKTsKKyAgICAgICAgdmFsdWVzLmFkZChJbnRlZ2VyLnZhbHVlT2YoMzAxMSkpOworCisgICAgICAgIGludCBpbmRleCA9IDA7CisgICAgICAgIHdoaWxlIChyZXN1bHQubmV4dCgpKSB7CisgICAgICAgICAgICBJbnRlZ2VyIG9udW0gPSByZXN1bHQuZ2V0SW50KCJvbnVtIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJyZXN1bHQgc2V0IGRvZXNuJ3QgY29udGFpbiB2YWx1ZSIsIHZhbHVlcworICAgICAgICAgICAgICAgICAgICAuY29udGFpbnMob251bSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJyZXN1bHQgc2V0IGlzIG5vdCBzb3J0ZWQiLCBpbmRleCwgdmFsdWVzCisgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKG9udW0pKTsKKyAgICAgICAgICAgIGluZGV4Kys7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0LmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VsZWN0RnVuY3Rpb25hbGl0eVRlc3QjdGVzdF9TZWxlY3REaXN0aW5jdCgpLiBTZWxlY3RzIHJlY29yZHMKKyAgICAgKiAgICAgICAgZnJvbSBhIHRhYmxlIHVzaW5nIGRpc3RpbmN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9TZWxlY3REaXN0aW5jdCgpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc2VsZWN0UXVlcnkgPSAiU0VMRUNUIERJU1RJTkNUIHJhdGluZyBGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5DVVNUT01FUlNfVEFCTEU7CisgICAgICAgIFJlc3VsdFNldCByZXN1bHQgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KHNlbGVjdFF1ZXJ5KTsKKworICAgICAgICBIYXNoU2V0PEludGVnZXI+IHZhbHVlcyA9IG5ldyBIYXNoU2V0PEludGVnZXI+KCk7CisgICAgICAgIHZhbHVlcy5hZGQoSW50ZWdlci52YWx1ZU9mKDEwMCkpOworICAgICAgICB2YWx1ZXMuYWRkKEludGVnZXIudmFsdWVPZigyMDApKTsKKyAgICAgICAgdmFsdWVzLmFkZChJbnRlZ2VyLnZhbHVlT2YoMzAwKSk7CisKKyAgICAgICAgd2hpbGUgKHJlc3VsdC5uZXh0KCkpIHsKKyAgICAgICAgICAgIEludGVnZXIgcmF0aW5nID0gcmVzdWx0LmdldEludCgicmF0aW5nIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJyZXN1bHQgc2V0IGRvZXNuJ3QgY29udGFpbiB2YWx1ZSIsIHZhbHVlcworICAgICAgICAgICAgICAgICAgICAuY29udGFpbnMocmF0aW5nKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ3cm9uZyB2YWx1ZSBpbiB0aGUgcmVzdWx0IHNldCIsIHZhbHVlcy5yZW1vdmUocmF0aW5nKSk7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0LmNsb3NlKCk7CisgICAgICAgIGFzc2VydFRydWUoIlJlc3VsdCBzZXQgaGFzIHdyb25nIHNpemUiLCB2YWx1ZXMuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWxlY3RGdW5jdGlvbmFsaXR5VGVzdCN0ZXN0X1NlbGVjdEFncmVnYXRlRnVuY3Rpb25zKCkuIFNlbGVjdHMKKyAgICAgKiAgICAgICAgcmVjb3JkcyBmcm9tIGEgdGFibGUgdXNpbmcgYWdyZWdhdGUgZnVuY3Rpb25zCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9TZWxlY3RBZ3JlZ2F0ZUZ1bmN0aW9ucygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc2VsZWN0Q291bnQgPSAiU0VMRUNUIGNvdW50KG9udW0pIGFzIGNvdW50IEZST00gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLk9SREVSU19UQUJMRTsKKyAgICAgICAgU3RyaW5nIHNlbGVjdFN1bSA9ICJTRUxFQ1Qgc3VtKG9udW0pIGFzIHN1bSBGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5PUkRFUlNfVEFCTEU7CisgICAgICAgIFN0cmluZyBzZWxlY3RBdmcgPSAiU0VMRUNUIGF2ZyhvbnVtKSBhcyBhdmcgRlJPTSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuT1JERVJTX1RBQkxFOworICAgICAgICBTdHJpbmcgc2VsZWN0TWF4ID0gIlNFTEVDVCBtYXgob251bSkgYXMgbWF4IEZST00gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLk9SREVSU19UQUJMRTsKKyAgICAgICAgU3RyaW5nIHNlbGVjdE1pbiA9ICJTRUxFQ1QgbWluKG9udW0pIGFzIG1pbiBGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5PUkRFUlNfVEFCTEU7CisKKyAgICAgICAgZnVuYygiY291bnQiLCBzZWxlY3RDb3VudCwgMTApOworICAgICAgICBmdW5jKCJzdW0iLCBzZWxlY3RTdW0sIDMwMDYyKTsKKyAgICAgICAgZnVuYygiYXZnIiwgc2VsZWN0QXZnLCAzMDA2KTsKKyAgICAgICAgZnVuYygibWF4Iiwgc2VsZWN0TWF4LCAzMDExKTsKKyAgICAgICAgZnVuYygibWluIiwgc2VsZWN0TWluLCAzMDAxKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZnVuYyhTdHJpbmcgbmFtZSwgU3RyaW5nIHF1ZXJ5LCBpbnQgZXhwZWN0ZWQpIHsKKyAgICAgICAgaW50IHJlcyA9IDA7CisgICAgICAgIGRvdWJsZSByZXNEb3VibGUgPSAwLjA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBSZXN1bHRTZXQgcmVzdWx0ID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeShxdWVyeSk7CisgICAgICAgICAgICB3aGlsZSAocmVzdWx0Lm5leHQoKSkgeworICAgICAgICAgICAgICAgIHJlcyA9IHJlc3VsdC5nZXRJbnQobmFtZSk7CisgICAgICAgICAgICAgICAgaWYgKHJlcyAhPSAwICkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCxyZXMpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBmb3IgRG91YmxlOiBnZXRJbnQgbm90IHN1cHBvcnRlZCB5ZXQKKyAgICAgICAgICAgICAgICByZXNEb3VibGUgID0gRG91YmxlLnBhcnNlRG91YmxlKHJlc3VsdC5nZXRTdHJpbmcobmFtZSkpOworICAgICAgICAgICAgICAgIHJlcyA9IChpbnQpIE1hdGgucmludChyZXNEb3VibGUpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCxyZXMpOworCisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRGYWxzZSgid3Jvbmcgc2l6ZSBvZiByZXN1bHQgc2V0IiwgcmVzdWx0Lm5leHQoKSk7CisgICAgICAgICAgICByZXN1bHQuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VsZWN0RnVuY3Rpb25hbGl0eVRlc3QjdGVzdF9TZWxlY3RIYXZpbmcoKS4gU2VsZWN0cyByZWNvcmRzIGZyb20KKyAgICAgKiAgICAgICAgYSB0YWJsZSB1c2luZyBoYXZpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1NlbGVjdEhhdmluZygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgc2VsZWN0UXVlcnkgPSAiU0VMRUNUIHNudW0sIG1heChhbXQpIEFTIG1heCBGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5PUkRFUlNfVEFCTEUKKyAgICAgICAgICAgICAgICArICIgR1JPVVAgQlkgc251bSBIQVZJTkcgbWF4KGFtdCkgPiAzMDAwIjsKKyAgICAgICAgUmVzdWx0U2V0IHJlc3VsdCA9IHN0YXRlbWVudC5leGVjdXRlUXVlcnkoc2VsZWN0UXVlcnkpOworCisgICAgICAgIEhhc2hTZXQ8RG91YmxlPiB2YWx1ZXMgPSBuZXcgSGFzaFNldDxEb3VibGU+KCk7CisgICAgICAgIHZhbHVlcy5hZGQoRG91YmxlLnZhbHVlT2YoOTg5MS44OCkpOworICAgICAgICB2YWx1ZXMuYWRkKERvdWJsZS52YWx1ZU9mKDUxNjAuNDUpKTsKKworICAgICAgICB3aGlsZSAocmVzdWx0Lm5leHQoKSkgeworICAgICAgICAgICAgRG91YmxlIG1heCA9IHJlc3VsdC5nZXREb3VibGUoIm1heCIpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgicmVzdWx0IHNldCBkb2Vzbid0IGNvbnRhaW4gdmFsdWUiLCB2YWx1ZXMuY29udGFpbnMobWF4KSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ3cm9uZyB2YWx1ZSBpbiB0aGUgcmVzdWx0IHNldCIsIHZhbHVlcy5yZW1vdmUobWF4KSk7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0LmNsb3NlKCk7CisgICAgICAgIGFzc2VydFRydWUoIlJlc3VsdCBzZXQgaGFzIHdyb25nIHNpemUiLCB2YWx1ZXMuaXNFbXB0eSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvamF2YS9zcWwvU3RyZXNzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2phdmEvc3FsL1N0cmVzc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi5iOTgxZDVlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2phdmEvc3FsL1N0cmVzc1Rlc3QuamF2YQpAQCAtMCwwICsxLDMzOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5qYXZhLnNxbDsKKworaW1wb3J0IGphdmEuc3FsLkNvbm5lY3Rpb247CitpbXBvcnQgamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YTsKK2ltcG9ydCBqYXZhLnNxbC5Ecml2ZXI7CitpbXBvcnQgamF2YS5zcWwuUHJlcGFyZWRTdGF0ZW1lbnQ7CitpbXBvcnQgamF2YS5zcWwuUmVzdWx0U2V0OworaW1wb3J0IGphdmEuc3FsLlNRTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5TdGF0ZW1lbnQ7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5Mb2dnZXI7CisKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LkRhdGFiYXNlQ3JlYXRvcjsKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfU1FMOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuVGhyZWFkUG9vbDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBTdHJlc3NUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIFZlY3RvcjxDb25uZWN0aW9uPiB2YyA9IG5ldyBWZWN0b3I8Q29ubmVjdGlvbj4oKTsKKworICAgIHByaXZhdGUgc3RhdGljIENvbm5lY3Rpb24gY29ubjsKKworICAgIHByaXZhdGUgc3RhdGljIFN0YXRlbWVudCBzdGF0ZW1lbnQ7CisKKyAgICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBTdXBwb3J0X1NRTC5sb2FkRHJpdmVyKCk7CisgICAgICAgIGNvbm4gPSBTdXBwb3J0X1NRTC5nZXRDb25uZWN0aW9uKCk7CisgICAgICAgIHN0YXRlbWVudCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgIGNyZWF0ZVRlc3RUYWJsZXMoKTsKKyAgICAgICAgdmMuY2xlYXIoKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjbG9zZUNvbm5lY3Rpb25zKCk7CisgICAgICAgIHN0YXRlbWVudC5jbG9zZSgpOworICAgICAgICBjb25uLmNsb3NlKCk7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZVRlc3RUYWJsZXMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEYXRhYmFzZU1ldGFEYXRhIG1ldGEgPSBjb25uLmdldE1ldGFEYXRhKCk7CisgICAgICAgICAgICBSZXN1bHRTZXQgdXNlclRhYiA9IG1ldGEuZ2V0VGFibGVzKG51bGwsIG51bGwsIG51bGwsIG51bGwpOworCisgICAgICAgICAgICB3aGlsZSAodXNlclRhYi5uZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgdGFibGVOYW1lID0gdXNlclRhYi5nZXRTdHJpbmcoIlRBQkxFX05BTUUiKTsKKyAgICAgICAgICAgICAgICBpZiAodGFibGVOYW1lLmVxdWFscyhEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTIpKSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFMik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkNSRUFURV9UQUJMRTIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNRTEV4Y2VwdGlvbiAiICsgc3FsLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZHJvcFRlc3RUYWJsZXMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRTIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNRTEV4Y2VwdGlvbiAiICsgc3FsLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKy8vICAgIC8qKgorLy8gICAgICogQHNlZSBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2Ujc2V0VXAoKQorLy8gICAgICovCisvLyAgICBAT3ZlcnJpZGUKKy8vICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisvLyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKy8vICAgICAgICB2Yy5jbGVhcigpOworLy8gICAgfQorLy8KKy8vICAgIC8qKgorLy8gICAgICogQHNlZSBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UjdGVhckRvd24oKQorLy8gICAgICovCisvLyAgICBAT3ZlcnJpZGUKKy8vICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisvLyAgICAgICAgY2xvc2VDb25uZWN0aW9ucygpOworLy8gICAgICAgIHN0YXRlbWVudC5leGVjdXRlKCJERUxFVEUgRlJPTSAiICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUyKTsKKy8vICAgICAgICBzdXBlci50ZWFyRG93bigpOworLy8gICAgfQorCisgICAgLyoqCisgICAgICogU3RyZXNzVGVzdCN0ZXN0TWFueUNvbm5lY3Rpb25zVXNpbmdPbmVUaHJlYWQoKS4gQ3JlYXRlIG1hbnkKKyAgICAgKiAgICAgICAgY29ubmVjdGlvbnMgdG8gdGhlIERhdGFCYXNlIHVzaW5nIG9uZSB0aHJlYWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE1hbnlDb25uZWN0aW9uc1VzaW5nT25lVGhyZWFkKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IG1heENvbm5lY3Rpb25zID0gZ2V0Q29ubmVjdGlvbk51bSgpOworICAgICAgICAgICAgb3BlbkNvbm5lY3Rpb25zKG1heENvbm5lY3Rpb25zKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IG51bWJlciBvZiBjcmVhdGVkIGNvbm5lY3Rpb25zIiwKKyAgICAgICAgICAgICAgICAgICAgbWF4Q29ubmVjdGlvbnMsIHZjLnNpemUoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIEV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFN0cmVzc1Rlc3QjdGVzdE1hbnlDb25uZWN0aW9uc1VzaW5nTWFueVRocmVhZHMoKS4gQ3JlYXRlIG1hbnkKKyAgICAgKiAgICAgICAgY29ubmVjdGlvbnMgdG8gdGhlIERhdGFCYXNlIHVzaW5nIHNvbWUgdGhyZWFkcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFueUNvbm5lY3Rpb25zVXNpbmdNYW55VGhyZWFkcygpIHsKKyAgICAgICAgaW50IG51bVRhc2tzID0gZ2V0Q29ubmVjdGlvbk51bSgpOworCisgICAgICAgIFRocmVhZFBvb2wgdGhyZWFkUG9vbCA9IG5ldyBUaHJlYWRQb29sKG51bVRhc2tzKTsKKworICAgICAgICAvLyBydW4gZXhhbXBsZSB0YXNrcworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bVRhc2tzOyBpKyspIHsKKyAgICAgICAgICAgIHRocmVhZFBvb2wucnVuVGFzayhjcmVhdGVUYXNrKGkpKTsKKyAgICAgICAgfQorICAgICAgICAvLyBjbG9zZSB0aGUgcG9vbCBhbmQgd2FpdCBmb3IgYWxsIHRhc2tzIHRvIGZpbmlzaC4KKyAgICAgICAgdGhyZWFkUG9vbC5qb2luKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVW5hYmxlIHRvIGNyZWF0ZSBhIGNvbm5lY3Rpb24iLCBudW1UYXNrcywgdmMuc2l6ZSgpKTsKKyAgICAgICAgaWYgKG51bVRhc2tzICE9IFN1cHBvcnRfU1FMLnNxbE1heENvbm5lY3Rpb25zKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIHRyeSB0byBjcmVhdGUgY29ubmVjdGlvbiBuICsgMQorICAgICAgICAgICAgICAgIENvbm5lY3Rpb24gYyA9IFN1cHBvcnRfU1FMLmdldENvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgICAgICBjLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgZmFpbCgiSXQgaXMgcG9zc2libGUgdG8gY3JlYXRlIG1vcmUgdGhhbiAiICsgbnVtVGFza3MKKyAgICAgICAgICAgICAgICAgICAgICAgICsgImNvbm5lY3Rpb25zIik7CisgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFN0cmVzc1Rlc3QjdGVzdEluc2VydE9mTWFueVJvd3NVc2luZ09uZVRocmVhZCgpLiBJbnNlcnQgYSBsb3Qgb2YKKyAgICAgKiAgICAgICAgcmVjb3JkcyB0byB0aGUgRGF0YWJhc2UgdXNpbmcgYSBtYXhpbXVtIG51bWJlciBvZiBjb25uZWN0aW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5zZXJ0T2ZNYW55Um93c1VzaW5nT25lVGhyZWFkKCkgeworCisgICAgICAgIExvZ2dlci5nbG9iYWwKKyAgICAgICAgICAgICAgICAuaW5mbygiamF2YS5zcWwgc3RyZXNzIHRlc3Q6IHNpbmdsZSB0aHJlYWQgYW5kIG1hbnkgb3BlcmF0aW9ucy4iKTsKKyAgICAgICAgaW50IG1heENvbm5lY3Rpb25zID0gZ2V0Q29ubmVjdGlvbk51bSgpOworICAgICAgICBMb2dnZXIuZ2xvYmFsLmluZm8oIk9wZW5pbmcgIiArIG1heENvbm5lY3Rpb25zICsgIiB0byBkYXRhYmFzZSAiCisgICAgICAgICAgICAgICAgKyBTdXBwb3J0X1NRTC5nZXRGaWxlbmFtZSgpKTsKKyAgICAgICAgb3BlbkNvbm5lY3Rpb25zKG1heENvbm5lY3Rpb25zKTsKKworICAgICAgICBpbnQgdGFza3NQZXJDb25uZWN0aW9uID0gU3VwcG9ydF9TUUwuc3FsTWF4VGFza3MgLyBtYXhDb25uZWN0aW9uczsKKyAgICAgICAgTG9nZ2VyLmdsb2JhbC5pbmZvKCJUYXNrc1BlckNvbm5lY3Rpb24gPSAgIiArIFN1cHBvcnRfU1FMLnNxbE1heFRhc2tzCisgICAgICAgICAgICAgICAgKyAiIGJ5IChtYXhDb25uZWN0aW9ucykgIiArIG1heENvbm5lY3Rpb25zICsgIiA9ICIKKyAgICAgICAgICAgICAgICArIHRhc2tzUGVyQ29ubmVjdGlvbik7CisgICAgICAgIGludCBwayA9IDE7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmMuc2l6ZSgpOyArK2kpIHsKKyAgICAgICAgICAgIExvZ2dlci5nbG9iYWwuaW5mbygiIGNyZWF0aW5nICIgKyB0YXNrc1BlckNvbm5lY3Rpb24KKyAgICAgICAgICAgICAgICAgICAgKyAidGFza3MgZm9yIENvbm5lY3Rpb24gIiArIGkpOworICAgICAgICAgICAgQ29ubmVjdGlvbiBjID0gdmMuZWxlbWVudEF0KGkpOworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCB0YXNrc1BlckNvbm5lY3Rpb247ICsraikgeworICAgICAgICAgICAgICAgIGluc2VydE5ld1JlY29yZChjLCBwaysrKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3RhdGVtZW50CisgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlUXVlcnkoIlNFTEVDVCBDT1VOVCgqKSBhcyBjb3VudGVyIEZST00gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUyKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJlY29yZFNldCBpcyBlbXB0eSIsIHJzLm5leHQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBudW1iZXIgb2YgcmVjb3JkcyIsIHRhc2tzUGVyQ29ubmVjdGlvbgorICAgICAgICAgICAgICAgICAgICAqIG1heENvbm5lY3Rpb25zLCBycy5nZXRJbnQoImNvdW50ZXIiKSk7CisgICAgICAgICAgICBycy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNRTEV4Y2VwdGlvbiAiICsgc3FsLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAdGVzdHMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5zZXJ0T2ZNYW55Um93c1VzaW5nTWFueVRocmVhZHMoKSB7CisgICAgICAgIExvZ2dlci5nbG9iYWwuaW5mbygiamF2YS5zcWwgc3RyZXNzIHRlc3Q6IG11bHRpcGxlIHRocmVhZHMgYW5kIG1hbnkgb3BlcmF0aW9ucy4iKTsKKworICAgICAgICBpbnQgbnVtQ29ubmVjdGlvbnMgPSBnZXRDb25uZWN0aW9uTnVtKCk7CisgICAgICAgIGludCB0YXNrc1BlckNvbm5lY3Rpb24gPSBTdXBwb3J0X1NRTC5zcWxNYXhUYXNrcyAvIG51bUNvbm5lY3Rpb25zOworCisgICAgICAgIExvZ2dlci5nbG9iYWwuaW5mbygiT3BlbmluZyAiK251bUNvbm5lY3Rpb25zKyIgdG8gZGF0YWJhc2UgIitTdXBwb3J0X1NRTC5nZXRGaWxlbmFtZSgpKTsKKworICAgICAgICBUaHJlYWRQb29sIHRocmVhZFBvb2wgPSBuZXcgVGhyZWFkUG9vbChudW1Db25uZWN0aW9ucyk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1Db25uZWN0aW9uczsgKytpKSB7CisgICAgICAgICAgICBMb2dnZXIuZ2xvYmFsLmluZm8oIiBjcmVhdGluZyAiK3Rhc2tzUGVyQ29ubmVjdGlvbisgIiB0YXNrcyBmb3IgQ29ubmVjdGlvbiAiK2kpOworICAgICAgICAgICAgdGhyZWFkUG9vbC5ydW5UYXNrKGluc2VydFRhc2sobnVtQ29ubmVjdGlvbnMsIGkpKTsKKyAgICAgICAgfQorICAgICAgICAvLyBjbG9zZSB0aGUgcG9vbCBhbmQgd2FpdCBmb3IgYWxsIHRhc2tzIHRvIGZpbmlzaC4KKyAgICAgICAgdGhyZWFkUG9vbC5qb2luKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiVW5hYmxlIHRvIGNyZWF0ZSBhIGNvbm5lY3Rpb24iLCBudW1Db25uZWN0aW9ucywgdmMuc2l6ZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUmVzdWx0U2V0IHJzID0gc3RhdGVtZW50CisgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlUXVlcnkoIlNFTEVDVCBDT1VOVCgqKSBhcyBjb3VudGVyIEZST00gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUyKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlJlY29yZFNldCBpcyBlbXB0eSIsIHJzLm5leHQoKSk7CisKKworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgbnVtYmVyIG9mIHJlY29yZHMiLCB0YXNrc1BlckNvbm5lY3Rpb24KKyAgICAgICAgICAgICAgICAgICAgKiBudW1Db25uZWN0aW9ucywgcnMuZ2V0SW50KCJjb3VudGVyIikpOworICAgICAgICAgICAgcnMuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTUUxFeGNlcHRpb24gIiArIHNxbC50b1N0cmluZygpKTsKKworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBnZXRDb25uZWN0aW9uTnVtKCkgeworICAgICAgICBpbnQgbnVtID0gU3VwcG9ydF9TUUwuc3FsTWF4Q29ubmVjdGlvbnM7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgbWMgPSBjb25uLmdldE1ldGFEYXRhKCkuZ2V0TWF4Q29ubmVjdGlvbnMoKTsKKyAgICAgICAgICAgIGlmIChtYyAhPSAwKSB7CisgICAgICAgICAgICAgICAgaWYgKG51bSAhPSBtYykgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIldpbGwgYmUgdXNlZCBubyBtb3JlIHRoYW4gIiArIG1jCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGNvbm5lY3Rpb25zIHRvIHRoZSBEYXRhQmFzZSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBudW0gPSBtYzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbCkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTUUxFeGNlcHRpb24gIiArIHNxbC50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVtOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBvcGVuQ29ubmVjdGlvbnMoaW50IG1heENvbm5lY3Rpb25zKSB7CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvciAoOyBpIDwgbWF4Q29ubmVjdGlvbnM7ICsraSkgeworICAgICAgICAgICAgICAgIENvbm5lY3Rpb24gYyA9IFN1cHBvcnRfU1FMLmdldENvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgICAgICBpZiAoYyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiVW5hYmxlIHRvIGNyZWF0ZSBhIGNvbm5lY3Rpb24iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heENvbm5lY3Rpb25zLCBpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdmMuYWRkKGMpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlVuYWJsZSB0byBjcmVhdGUgYSBjb25uZWN0aW9uIiwgbWF4Q29ubmVjdGlvbnMsIGkpOworICAgICAgICB9CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2xvc2VDb25uZWN0aW9ucygpIHsKKyAgICAgICAgaW50IGkgPSAwOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9yICg7IGkgPCB2Yy5zaXplKCk7ICsraSkgeworICAgICAgICAgICAgICAgIHZjLmVsZW1lbnRBdChpKS5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlVuYWJsZSB0byBjbG9zZSBhIGNvbm5lY3Rpb24iLCB2Yy5zaXplKCksIGkpOworICAgICAgICB9CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBwcml2YXRlIFJ1bm5hYmxlIGNyZWF0ZVRhc2soZmluYWwgaW50IHRhc2tJRCkgeworICAgICAgICByZXR1cm4gbmV3IFJ1bm5hYmxlKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIENvbm5lY3Rpb24gYyA9IFN1cHBvcnRfU1FMLmdldENvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgICAgICAgICAgICAgdmMuYWRkKGMpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbCkgeworICAgICAgICAgICAgICAgICAgICAvLyBub3RoaW5nIHRvIGRvCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIHByaXZhdGUgUnVubmFibGUgaW5zZXJ0VGFzayhmaW5hbCBpbnQgbnVtQ29ubmVjdGlvbnMsIGZpbmFsIGludCB0YXNrSUQpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBDb25uZWN0aW9uIGMgPSBTdXBwb3J0X1NRTC5nZXRDb25uZWN0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChjID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHZjLmFkZChjKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpbnQgdGFza3NQZXJDb25uZWN0aW9uID0gU3VwcG9ydF9TUUwuc3FsTWF4VGFza3MKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvIG51bUNvbm5lY3Rpb25zOworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRhc2tzUGVyQ29ubmVjdGlvbjsgKytpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnNlcnROZXdSZWNvcmQoYywgKGkgKyAxKSArIHRhc2tzUGVyQ29ubmVjdGlvbgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHRhc2tJRCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gc3FsKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGluc2VydE5ld1JlY29yZChDb25uZWN0aW9uIGMsIGludCBwaykgeworICAgICAgICBTdHJpbmcgcXVlcnkgPSAiSU5TRVJUIElOVE8gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMgorICAgICAgICAgICAgICAgICsgIihmaW50ZWdlciwgZnRleHQsIGZjaGFyYWN0ZXIsIGZkZWNpbWFsLCBmbnVtZXJpYywiCisgICAgICAgICAgICAgICAgKyAiIGZzbWFsbGludCwgZmZsb2F0LCBmcmVhbCwgZmRvdWJsZSwgZmRhdGUsIGZ0aW1lKSIKKyAgICAgICAgICAgICAgICArICIgVkFMVUVTICg/LCA/LCA/LCA/LCA/LCA/LCA/LCA/LCA/LCA/LCA/KSI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBwcyA9IGMucHJlcGFyZVN0YXRlbWVudChxdWVyeSk7CisgICAgICAgICAgICBwcy5zZXRJbnQoMSwgcGspOworICAgICAgICAgICAgcHMuc2V0U3RyaW5nKDIsICJ0ZXh0Iik7CisgICAgICAgICAgICBwcy5zZXRTdHJpbmcoMywgImNociIpOworICAgICAgICAgICAgcHMuc2V0RmxvYXQoNCwgMC4xZik7CisgICAgICAgICAgICBwcy5zZXRGbG9hdCg1LCAwLjJmKTsKKyAgICAgICAgICAgIHBzLnNldFNob3J0KDYsIChzaG9ydCkgMyk7CisgICAgICAgICAgICBwcy5zZXRGbG9hdCg3LCAwLjRmKTsKKyAgICAgICAgICAgIHBzLnNldERvdWJsZSg4LCAwLjUpOworICAgICAgICAgICAgcHMuc2V0RG91YmxlKDksIDAuNik7CisgICAgICAgICAgICBwcy5zZXREYXRlKDEwLCBuZXcgamF2YS5zcWwuRGF0ZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSkpOworICAgICAgICAgICAgcHMuc2V0VGltZSgxMSwgbmV3IGphdmEuc3FsLlRpbWUoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpKTsKKyAgICAgICAgICAgIHBzLmV4ZWN1dGUoKTsKKyAgICAgICAgICAgIHBzLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBzcWwpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgU1FMRXhjZXB0aW9uICIgKyBzcWwudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9qYXZhL3NxbC9VcGRhdGVGdW5jdGlvbmFsaXR5VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL2phdmEvc3FsL1VwZGF0ZUZ1bmN0aW9uYWxpdHlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uYzVjZjE0MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9qYXZhL3NxbC9VcGRhdGVGdW5jdGlvbmFsaXR5VGVzdC5qYXZhCkBAIC0wLDAgKzEsMzQ5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmphdmEuc3FsOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7CitpbXBvcnQgamF2YS5zcWwuQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhOworaW1wb3J0IGphdmEuc3FsLlJlc3VsdFNldDsKK2ltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247CitpbXBvcnQgamF2YS5zcWwuU3RhdGVtZW50OworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworCitpbXBvcnQgdGVzdHMuc3VwcG9ydC5EYXRhYmFzZUNyZWF0b3I7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X1NRTDsKK2ltcG9ydCBqdW5pdC5leHRlbnNpb25zLlRlc3RTZXR1cDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworcHVibGljIGNsYXNzIFVwZGF0ZUZ1bmN0aW9uYWxpdHlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IG51bWJlck9mUmVjb3JkcyA9IDIwOworCisgICAgcHJpdmF0ZSBzdGF0aWMgQ29ubmVjdGlvbiBjb25uOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RhdGVtZW50IHN0YXRlbWVudDsKKworICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIFN1cHBvcnRfU1FMLmxvYWREcml2ZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4gPSBTdXBwb3J0X1NRTC5nZXRDb25uZWN0aW9uKCk7CisgICAgICAgICAgICBzdGF0ZW1lbnQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgY3JlYXRlVGVzdFRhYmxlcygpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTUUxFeGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmZpbGxUZXN0VGFibGUxKGNvbm4sIG51bWJlck9mUmVjb3Jkcyk7CisgICAgICAgIERhdGFiYXNlQ3JlYXRvci5maWxsVGVzdFRhYmxlMihjb25uLCBudW1iZXJPZlJlY29yZHMpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRlbGV0ZVRlc3RUYWJsZXMoKTsKKyAgICAgICAgc3RhdGVtZW50LmNsb3NlKCk7CisgICAgICAgIGNvbm4uY2xvc2UoKTsKKworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGNyZWF0ZVRlc3RUYWJsZXMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEYXRhYmFzZU1ldGFEYXRhIG1ldGEgPSBjb25uLmdldE1ldGFEYXRhKCk7CisgICAgICAgICAgICBSZXN1bHRTZXQgdXNlclRhYiA9IG1ldGEuZ2V0VGFibGVzKG51bGwsIG51bGwsIG51bGwsIG51bGwpOworCisgICAgICAgICAgICB3aGlsZSAodXNlclRhYi5uZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgdGFibGVOYW1lID0gdXNlclRhYi5nZXRTdHJpbmcoIlRBQkxFX05BTUUiKTsKKyAgICAgICAgICAgICAgICBpZiAodGFibGVOYW1lLmVxdWFscyhEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEpKSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFMSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0YWJsZU5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUyKSkgeworICAgICAgICAgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRTIpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGFibGVOYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMykpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEUzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICB1c2VyVGFiLmNsb3NlKCk7CisKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEUzKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEUyKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEUxKTsKKworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTUUxFeGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBkZWxldGVUZXN0VGFibGVzKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEUxKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFMik7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRTMpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTUUxFeGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVGdW5jdGlvbmFsaXR5VGVzdCN0ZXN0VXBkYXRlMSgpLiBVcGRhdGVzIGFsbCB2YWx1ZXMgaW4gb25lCisgICAgICogICAgICAgIGNvbHVtbiBpbiB0aGUgdGFibGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXBkYXRlMSgpIHsKKyAgICAgICAgU3RyaW5nIG5ld1ZhbHVlID0gIm5ld1ZhbHVlIjsKKyAgICAgICAgU3RyaW5nIHVwZGF0ZVF1ZXJ5ID0gIlVQREFURSAiICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxCisgICAgICAgICAgICAgICAgKyAiIFNFVCBmaWVsZDE9JyIgKyBuZXdWYWx1ZSArICInIjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGludCBudW0gPSBzdGF0ZW1lbnQuZXhlY3V0ZVVwZGF0ZSh1cGRhdGVRdWVyeSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIk5vdCBhbGwgcmVjb3JkcyBpbiB0aGUgZGF0YWJhc2Ugd2VyZSB1cGRhdGVkIiwKKyAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZSZWNvcmRzLCBudW0pOworICAgICAgICAgICAgU3RyaW5nIHNlbGVjdFF1ZXJ5ID0gIlNFTEVDVCBmaWVsZDEgRlJPTSAiCisgICAgICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxOworICAgICAgICAgICAgUmVzdWx0U2V0IHJlc3VsdCA9IHN0YXRlbWVudC5leGVjdXRlUXVlcnkoc2VsZWN0UXVlcnkpOworICAgICAgICAgICAgd2hpbGUgKHJlc3VsdC5uZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSBmaWVsZCBmaWVsZDEgd2FzIG5vdCB1cGRhdGVkIiwgbmV3VmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuZ2V0U3RyaW5nKCJmaWVsZDEiKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHQuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoU1FMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZUZ1bmN0aW9uYWxpdHlUZXN0I3Rlc3RVcGRhdGUyKCkuIFVwZGF0ZXMgdmFsdWVzIGluIG9uZQorICAgICAqICAgICAgICBjb2x1bW4gaW4gdGhlIHRhYmxlIHVzaW5nIHdoZXJlIGNvbmRpdGlvbiBpbiB1cGRhdGUgY29tbWFuZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVcGRhdGUyKCkgeworICAgICAgICBTdHJpbmcgbmV3VmFsdWUgPSAibmV3VmFsdWUiOworICAgICAgICBTdHJpbmcgdXBkYXRlUXVlcnkgPSAiVVBEQVRFICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgU0VUIGZpZWxkMT0nIiArIG5ld1ZhbHVlICsgIicgV0hFUkUgKGlkID4gMikgYW5kIChpZCA8IDEwKSI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgbnVtID0gc3RhdGVtZW50LmV4ZWN1dGVVcGRhdGUodXBkYXRlUXVlcnkpOworICAgICAgICAgICAgaW50IGV4cGVjdGVkVXBkYXRlZCA9IDc7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIk5vdCBhbGwgcmVjb3JkcyBpbiB0aGUgZGF0YWJhc2Ugd2VyZSB1cGRhdGVkIiwKKyAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWRVcGRhdGVkLCBudW0pOworICAgICAgICAgICAgU3RyaW5nIHNlbGVjdFF1ZXJ5ID0gIlNFTEVDVCAqIEZST00gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMTsKKyAgICAgICAgICAgIFJlc3VsdFNldCByZXN1bHQgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KHNlbGVjdFF1ZXJ5KTsKKyAgICAgICAgICAgIHdoaWxlIChyZXN1bHQubmV4dCgpKSB7CisgICAgICAgICAgICAgICAgaW50IGlkID0gcmVzdWx0LmdldEludCgiaWQiKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcgZmllbGQxID0gcmVzdWx0LmdldFN0cmluZygiZmllbGQxIik7CisgICAgICAgICAgICAgICAgaWYgKChpZCA+IDIpICYmIChpZCA8IDEwKSkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSBmaWVsZCBmaWVsZDEgd2FzIG5vdCB1cGRhdGVkIiwgbmV3VmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQxKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSBmaWVsZCBmaWVsZDEgd2FzIG5vdCB1cGRhdGVkIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhYmFzZUNyZWF0b3IuZGVmYXVsdFN0cmluZyArIGlkLCBmaWVsZDEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdC5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlRnVuY3Rpb25hbGl0eVRlc3QjdGVzdFVwZGF0ZTMoKS4gVXBkYXRlcyB2YWx1ZXMgaW4gYSBzZXZlcmFsCisgICAgICogICAgICAgIGNvbHVtbnMgaW4gdGhlIHRhYmxlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVwZGF0ZTMoKSB7CisgICAgICAgIGludCBuZXdWYWx1ZTEgPSAtMTsKKyAgICAgICAgaW50IG5ld1ZhbHVlMiA9IC0yOworICAgICAgICBTdHJpbmcgdXBkYXRlUXVlcnkgPSAiVVBEQVRFICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgU0VUIGZpZWxkMj0iICsgbmV3VmFsdWUxICsgIiwgZmllbGQzPSIgKyBuZXdWYWx1ZTI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnQgbnVtID0gc3RhdGVtZW50LmV4ZWN1dGVVcGRhdGUodXBkYXRlUXVlcnkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJOb3QgYWxsIHJlY29yZHMgaW4gdGhlIGRhdGFiYXNlIHdlcmUgdXBkYXRlZCIsCisgICAgICAgICAgICAgICAgICAgIG51bWJlck9mUmVjb3JkcywgbnVtKTsKKyAgICAgICAgICAgIFN0cmluZyBzZWxlY3RRdWVyeSA9ICJTRUxFQ1QgZmllbGQyLCBmaWVsZDMgRlJPTSAiCisgICAgICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxOworICAgICAgICAgICAgUmVzdWx0U2V0IHJlc3VsdCA9IHN0YXRlbWVudC5leGVjdXRlUXVlcnkoc2VsZWN0UXVlcnkpOworICAgICAgICAgICAgd2hpbGUgKHJlc3VsdC5uZXh0KCkpIHsKKyAgICAgICAgICAgLy8gVE9ETyBnZXRCaWdEZWNpbWFsIGlzIG5vdCBzdXBwb3J0ZWQKKy8vICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGhlIGZpZWxkIGZpZWxkMiB3YXMgbm90IHVwZGF0ZWQiLCBuZXdWYWx1ZTEsCisvLyAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5nZXRCaWdEZWNpbWFsKCJmaWVsZDIiKS5pbnRWYWx1ZSgpKTsKKy8vICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGhlIGZpZWxkIGZpZWxkMyB3YXMgbm90IHVwZGF0ZWQiLCBuZXdWYWx1ZTIsCisvLyAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5nZXRCaWdEZWNpbWFsKCJmaWVsZDMiKS5pbnRWYWx1ZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdC5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlRnVuY3Rpb25hbGl0eVRlc3QjdGVzdFVwZGF0ZTQoKS4gVXBkYXRlcyB2YWx1ZXMgaW4gYSBzZXZlcmFsCisgICAgICogICAgICAgIGNvbHVtbnMgaW4gdGhlIHRhYmxlIHVzaW5nIHdoZXJlIGNvbmRpdGlvbiBpbiB1cGRhdGUgY29tbWFuZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVcGRhdGU0KCkgeworICAgICAgICBpbnQgbmV3VmFsdWUxID0gLTE7CisgICAgICAgIGludCBuZXdWYWx1ZTIgPSAtMjsKKyAgICAgICAgU3RyaW5nIHVwZGF0ZVF1ZXJ5ID0gIlVQREFURSAiICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxCisgICAgICAgICAgICAgICAgKyAiIFNFVCBmaWVsZDI9IiArIG5ld1ZhbHVlMSArICIsIGZpZWxkMz0iICsgbmV3VmFsdWUyCisgICAgICAgICAgICAgICAgKyAiIFdIRVJFIGlkID4gMTAiOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IG51bSA9IHN0YXRlbWVudC5leGVjdXRlVXBkYXRlKHVwZGF0ZVF1ZXJ5KTsKKyAgICAgICAgICAgIGludCBleHBlY3RlZFVwZGF0ZWQgPSA5OworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJOb3QgYWxsIHJlY29yZHMgaW4gdGhlIGRhdGFiYXNlIHdlcmUgdXBkYXRlZCIsCisgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkVXBkYXRlZCwgbnVtKTsKKyAgICAgICAgICAgIFN0cmluZyBzZWxlY3RRdWVyeSA9ICJTRUxFQ1QgaWQsIGZpZWxkMiwgZmllbGQzIEZST00gIgorICAgICAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMTsKKyAgICAgICAgICAgIFJlc3VsdFNldCByZXN1bHQgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KHNlbGVjdFF1ZXJ5KTsKKyAgICAgICAgICAgIHdoaWxlIChyZXN1bHQubmV4dCgpKSB7CisgICAgICAgICAgICAgICAgaW50IGlkID0gcmVzdWx0LmdldEludCgiaWQiKTsKKyAgICAgICAgICAgICAgICAvLyBUT0RPIGdldEJpZ0RlY2ltYWwgaXMgbm90IHN1cHBvcnRlZAorLy8gICAgICAgICAgICAgICAgaW50IHZhbHVlMiA9IHJlc3VsdC5nZXRCaWdEZWNpbWFsKCJmaWVsZDIiKS5pbnRWYWx1ZSgpOworLy8gICAgICAgICAgICAgICAgaW50IHZhbHVlMyA9IHJlc3VsdC5nZXRCaWdEZWNpbWFsKCJmaWVsZDMiKS5pbnRWYWx1ZSgpOworLy8gICAgICAgICAgICAgICAgaWYgKGlkID4gZXhwZWN0ZWRVcGRhdGVkICsgMSkgeworLy8gICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGhlIGZpZWxkIGZpZWxkMiB3YXMgbm90IHVwZGF0ZWQiLCBuZXdWYWx1ZTEsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTIpOworLy8gICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiVGhlIGZpZWxkIGZpZWxkMyB3YXMgbm90IHVwZGF0ZWQiLCBuZXdWYWx1ZTIsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTMpOworLy8gICAgICAgICAgICAgICAgfSBlbHNlIHsKKy8vICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSBmaWVsZCBmaWVsZDIgd2FzIG5vdCB1cGRhdGVkIiwgaWQsIHZhbHVlMik7CisvLyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgZmllbGQgZmllbGQzIHdhcyBub3QgdXBkYXRlZCIsIGlkLCB2YWx1ZTMpOworLy8gICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0LmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVGdW5jdGlvbmFsaXR5VGVzdCN0ZXN0VXBkYXRlNSgpLiBVcGRhdGVzIHZhbHVlcyBpbiBvbmUKKyAgICAgKiAgICAgICAgY29sdW1ucyBpbiB0aGUgdGFibGUgdXNpbmcgY29uZGl0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVwZGF0ZTUoKSB7CisgICAgICAgIGludCBmYWN0b3IgPSAzOworICAgICAgICBTdHJpbmcgdXBkYXRlUXVlcnkgPSAiVVBEQVRFICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgU0VUIGZpZWxkMj1maWVsZDIgKiIgKyBmYWN0b3I7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgc2VsZWN0UXVlcnkgPSAiU0VMRUNUIGZpZWxkMiBGUk9NICIKKyAgICAgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTE7CisgICAgICAgICAgICBSZXN1bHRTZXQgcmVzdWx0ID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeShzZWxlY3RRdWVyeSk7CisgICAgICAgICAgICBIYXNoU2V0PEJpZ0RlY2ltYWw+IHZhbHVlcyA9IG5ldyBIYXNoU2V0PEJpZ0RlY2ltYWw+KCk7CisgICAgICAgICAgICAvLyBUT0RPIGdldEJpZ0RlY2ltYWwgaXMgbm90IHN1cHBvcnRlZAorLy8gICAgICAgICAgICB3aGlsZSAocmVzdWx0Lm5leHQoKSkgeworLy8gICAgICAgICAgICAgICAgdmFsdWVzLmFkZChCaWdEZWNpbWFsLnZhbHVlT2YocmVzdWx0LmdldEJpZ0RlY2ltYWwoImZpZWxkMiIpCisvLyAgICAgICAgICAgICAgICAgICAgICAgIC5pbnRWYWx1ZSgpCisvLyAgICAgICAgICAgICAgICAgICAgICAgICogZmFjdG9yKSk7CisvLyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IG51bSA9IHN0YXRlbWVudC5leGVjdXRlVXBkYXRlKHVwZGF0ZVF1ZXJ5KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiTm90IGFsbCByZWNvcmRzIGluIHRoZSBkYXRhYmFzZSB3ZXJlIHVwZGF0ZWQiLAorICAgICAgICAgICAgICAgICAgICBudW1iZXJPZlJlY29yZHMsIG51bSk7CisgICAgICAgICAgICByZXN1bHQgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KHNlbGVjdFF1ZXJ5KTsKKyAgICAgICAgICAgIC8vIFRPRE8gZ2V0QmlnRGVjaW1hbCBpcyBub3Qgc3VwcG9ydGVkCisvLyAgICAgICAgICAgIHdoaWxlIChyZXN1bHQubmV4dCgpKSB7CisvLyAgICAgICAgICAgICAgICBCaWdEZWNpbWFsIHZhbHVlID0gcmVzdWx0LmdldEJpZ0RlY2ltYWwoImZpZWxkMiIpOworLy8gICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgdmFsdWUgb2YgZmllbGQyIGFmdGVyIHVwZGF0ZSIKKy8vICAgICAgICAgICAgICAgICAgICAgICAgKyB2YWx1ZS5pbnRWYWx1ZSgpLCB2YWx1ZXMucmVtb3ZlKHZhbHVlKSk7CisvLyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoIk5vdCBhbGwgcmVjb3JkcyB3ZXJlIHVwZGF0ZWQiLCB2YWx1ZXMuaXNFbXB0eSgpKTsKKworICAgICAgICAgICAgcmVzdWx0LmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVGdW5jdGlvbmFsaXR5VGVzdCN0ZXN0VXBkYXRlNigpLiBTZXRzIHZhbHVlIG9mIGZpZWxkMiB0bworICAgICAqICAgICAgICBkZWZhdWx0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVwZGF0ZTYoKSB7CisgICAgICAgIFN0cmluZyB1cGRhdGVRdWVyeSA9ICJVUERBVEUgIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMQorICAgICAgICAgICAgICAgICsgIiBTRVQgZmllbGQyPScxJyI7CisgICAgICAgIHRyeSB7CisKKyAgICAgICAgICAgIGludCBudW0gPSBzdGF0ZW1lbnQuZXhlY3V0ZVVwZGF0ZSh1cGRhdGVRdWVyeSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIk5vdCBhbGwgcmVjb3JkcyBpbiB0aGUgZGF0YWJhc2Ugd2VyZSB1cGRhdGVkIiwKKyAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZSZWNvcmRzLCBudW0pOworICAgICAgICAgICAgU3RyaW5nIHNlbGVjdFF1ZXJ5ID0gIlNFTEVDVCBmaWVsZDIgRlJPTSAiCisgICAgICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEUxOworICAgICAgICAgICAgUmVzdWx0U2V0IHJlc3VsdCA9IHN0YXRlbWVudC5leGVjdXRlUXVlcnkoc2VsZWN0UXVlcnkpOworICAgICAgICAgICAgLy8gVE9ETyBnZXRCaWdEZWNpbWFsIGlzIG5vdCBzdXBwb3J0ZWQKKy8vICAgICAgICAgICAgd2hpbGUgKHJlc3VsdC5uZXh0KCkpIHsKKy8vICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygidmFsdWUgb2YgZmllbGQyIHNob3VsZCBiZSBkZWZhdWx0ICIsCisvLyAgICAgICAgICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5kZWZhdWx0SW50LCByZXN1bHQuZ2V0QmlnRGVjaW1hbCgKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmllbGQyIikuaW50VmFsdWUoKSk7CisvLyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdC5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlRnVuY3Rpb25hbGl0eVRlc3QjdGVzdFVwZGF0ZTcoKS4gVXBkYXRlcyByZWNvcmRzIGluIHRoZQorICAgICAqICAgICAgICB0YWJsZSB1c2luZyBzdWJxdWVyeSBpbiB1cGRhdGUgY29tbWFuZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVcGRhdGU3KCkgeworICAgICAgICBTdHJpbmcgdXBkYXRlUXVlcnkgPSAiVVBEQVRFICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgU0VUIGZpZWxkMj0nMScgV0hFUkUgaWQgPCAoIFNFTEVDVCBDT1VOVCgqKSBGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMiArICIgV0hFUkUgZmludGVnZXIgPiAxNSkiOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IG51bSA9IHN0YXRlbWVudC5leGVjdXRlVXBkYXRlKHVwZGF0ZVF1ZXJ5KTsKKyAgICAgICAgICAgIGludCBleHBlY3RlZFVwZGF0ZWQgPSA0OworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJOb3QgYWxsIHJlY29yZHMgaW4gdGhlIGRhdGFiYXNlIHdlcmUgdXBkYXRlZCIsCisgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkVXBkYXRlZCwgbnVtKTsKKyAgICAgICAgICAgIFN0cmluZyBzZWxlY3RRdWVyeSA9ICJTRUxFQ1QgaWQsIGZpZWxkMiBGUk9NICIKKyAgICAgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTE7CisgICAgICAgICAgICBSZXN1bHRTZXQgcmVzdWx0ID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeShzZWxlY3RRdWVyeSk7CisgICAgICAgICAgICB3aGlsZSAocmVzdWx0Lm5leHQoKSkgeworICAgICAgICAgICAvLyBUT0RPIGdldEJpZ0RlY2ltYWwgaXMgbm90IHN1cHBvcnRlZAorLy8gICAgICAgICAgICAgICAgaW50IHZhbHVlID0gcmVzdWx0LmdldEJpZ0RlY2ltYWwoImZpZWxkMiIpLmludFZhbHVlKCk7CisvLyAgICAgICAgICAgICAgICBpbnQgaWQgPSByZXN1bHQuZ2V0SW50KCJpZCIpOworLy8gICAgICAgICAgICAgICAgaWYgKGlkIDwgZXhwZWN0ZWRVcGRhdGVkKSB7CisvLyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZSBvZiBmaWVsZDIgc2hvdWxkIGJlIGRlZmF1bHQgIiwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIERhdGFiYXNlQ3JlYXRvci5kZWZhdWx0SW50LCB2YWx1ZSk7CisvLyAgICAgICAgICAgICAgICB9IGVsc2UgeworLy8gICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygid3JvbmcgdmFsdWUgb2YgZmllbGQyIiwgaWQsIHZhbHVlKTsKKy8vICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdC5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlRnVuY3Rpb25hbGl0eVRlc3QjdGVzdFVwZGF0ZTgoKS4gU2V0cyB2YWx1ZSBvZiBmaWVsZDIgdG8KKyAgICAgKiAgICAgICAgTlVMTAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVcGRhdGU4KCkgeworICAgICAgICBTdHJpbmcgdXBkYXRlUXVlcnkgPSAiVVBEQVRFICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICArICIgU0VUIGZpZWxkMj1OVUxMIjsKKyAgICAgICAgdHJ5IHsKKworICAgICAgICAgICAgaW50IG51bSA9IHN0YXRlbWVudC5leGVjdXRlVXBkYXRlKHVwZGF0ZVF1ZXJ5KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiTm90IGFsbCByZWNvcmRzIGluIHRoZSBkYXRhYmFzZSB3ZXJlIHVwZGF0ZWQiLAorICAgICAgICAgICAgICAgICAgICBudW1iZXJPZlJlY29yZHMsIG51bSk7CisgICAgICAgICAgICBTdHJpbmcgc2VsZWN0UXVlcnkgPSAiU0VMRUNUIGZpZWxkMiBGUk9NICIKKyAgICAgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTE7CisgICAgICAgICAgICBSZXN1bHRTZXQgcmVzdWx0ID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeShzZWxlY3RRdWVyeSk7CisgICAgICAgICAgICB3aGlsZSAocmVzdWx0Lm5leHQoKSkgeworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoInZhbHVlIG9mIGZpZWxkMiBzaG91bGQgYmUgTlVMTCIsIHJlc3VsdAorICAgICAgICAgICAgICAgICAgICAgICAgLmdldE9iamVjdCgiZmllbGQyIikpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0LmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvamF2YS9zcWwvVXBkYXRlRnVuY3Rpb25hbGl0eVRlc3QyLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvamF2YS9zcWwvVXBkYXRlRnVuY3Rpb25hbGl0eVRlc3QyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uMDFkNjE0MAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9qYXZhL3NxbC9VcGRhdGVGdW5jdGlvbmFsaXR5VGVzdDIuamF2YQpAQCAtMCwwICsxLDI4NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5qYXZhLnNxbDsKKworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLktub3duRmFpbHVyZTsKKworaW1wb3J0IGphdmEuc3FsLkNvbm5lY3Rpb247CitpbXBvcnQgamF2YS5zcWwuRGF0YWJhc2VNZXRhRGF0YTsKK2ltcG9ydCBqYXZhLnNxbC5QcmVwYXJlZFN0YXRlbWVudDsKK2ltcG9ydCBqYXZhLnNxbC5SZXN1bHRTZXQ7CitpbXBvcnQgamF2YS5zcWwuU1FMRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc3FsLlN0YXRlbWVudDsKKworaW1wb3J0IHRlc3RzLnN1cHBvcnQuRGF0YWJhc2VDcmVhdG9yOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9TUUw7CisKK2ltcG9ydCBqdW5pdC5leHRlbnNpb25zLlRlc3RTZXR1cDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKKworcHVibGljIGNsYXNzIFVwZGF0ZUZ1bmN0aW9uYWxpdHlUZXN0MiBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIENvbm5lY3Rpb24gY29ubiA9IG51bGw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdGF0ZW1lbnQgc3RhdGVtZW50ID0gbnVsbDsKKworICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIFN1cHBvcnRfU1FMLmxvYWREcml2ZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbm4gPSBTdXBwb3J0X1NRTC5nZXRDb25uZWN0aW9uKCk7CisgICAgICAgICAgICBzdGF0ZW1lbnQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICAgICAgY3JlYXRlVGVzdFRhYmxlcygpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTUUxFeGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmZpbGxQYXJlbnRUYWJsZShjb25uKTsKKyAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmZpbGxTaW1wbGVUYWJsZTMoY29ubik7CisgICAgICAgIERhdGFiYXNlQ3JlYXRvci5maWxsU2ltcGxlVGFibGUxKGNvbm4pOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRlbGV0ZVRlc3RUYWJsZXMoKTsKKyAgICAgICAgc3RhdGVtZW50LmNsb3NlKCk7CisgICAgICAgIGNvbm4uY2xvc2UoKTsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY3JlYXRlVGVzdFRhYmxlcygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIERhdGFiYXNlTWV0YURhdGEgbWV0YSA9IGNvbm4uZ2V0TWV0YURhdGEoKTsKKyAgICAgICAgICAgIFJlc3VsdFNldCB1c2VyVGFiID0gbWV0YS5nZXRUYWJsZXMobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7CisKKyAgICAgICAgICAgIHdoaWxlICh1c2VyVGFiLm5leHQoKSkgeworICAgICAgICAgICAgICAgIFN0cmluZyB0YWJsZU5hbWUgPSB1c2VyVGFiLmdldFN0cmluZygiVEFCTEVfTkFNRSIpOworICAgICAgICAgICAgICAgIGlmICh0YWJsZU5hbWUuZXF1YWxzKERhdGFiYXNlQ3JlYXRvci5QQVJFTlRfVEFCTEUpKSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFX1BBUkVOVCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0YWJsZU5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoRGF0YWJhc2VDcmVhdG9yLkZLQ0FTQ0FERV9UQUJMRSkpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEVfRktDQVNDQURFKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRhYmxlTmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhEYXRhYmFzZUNyZWF0b3IuRktTVFJJQ1RfVEFCTEUpKSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFX0ZLU1RSSUNUKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRhYmxlTmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMSkpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEVfU0lNUExFMSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0YWJsZU5hbWUKKyAgICAgICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTMpKSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFX1NJTVBMRTMpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGFibGVOYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFNSkpIHsKKyAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEU1KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICB1c2VyVGFiLmNsb3NlKCk7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuQ1JFQVRFX1RBQkxFX1BBUkVOVCk7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuQ1JFQVRFX1RBQkxFX0ZLU1RSSUNUKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEVfRktDQVNDQURFKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5DUkVBVEVfVEFCTEVfU0lNUExFMyk7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuQ1JFQVRFX1RBQkxFX1NJTVBMRTEpOworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkNSRUFURV9UQUJMRTUpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBTUUxFeGNlcHRpb24gIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZGVsZXRlVGVzdFRhYmxlcygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFX0ZLQ0FTQ0FERSk7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRV9GS1NUUklDVCk7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRV9QQVJFTlQpOworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLkRST1BfVEFCTEVfU0lNUExFMyk7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuRFJPUF9UQUJMRV9TSU1QTEUxKTsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5EUk9QX1RBQkxFNSk7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIFNRTEV4Y2VwdGlvbiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZUZ1bmN0aW9uYWxpdHlUZXN0MiN0ZXN0VXBkYXRlMSgpLiBVcGRhdGVzIHJvdyB3aXRoIG5vCisgICAgICogICAgICAgIHJlZmVyZW5jaW5nIG9uZXMgYW5kIFJFU1RSSUNUIGFjdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVcGRhdGUxKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIERhdGFiYXNlQ3JlYXRvci5maWxsRktTdHJpY3RUYWJsZShjb25uKTsKKyAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoIlVQREFURSAiICsgRGF0YWJhc2VDcmVhdG9yLlBBUkVOVF9UQUJMRQorICAgICAgICAgICAgICAgICsgIiBTRVQgaWQgPSA0IFdIRVJFIGlkID0gMyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZUZ1bmN0aW9uYWxpdHlUZXN0MiN0ZXN0VXBkYXRlMigpLiBBdHRlbXB0cyB0byB1cGRhdGUgcm93CisgICAgICogICAgICAgIHdpdGggcmVmZXJlbmNpbmcgb25lcyBhbmQgUkVTVFJJQ1QgYWN0aW9uIC0gZXhwZWN0aW5nIFNRTEV4Y2VwdGlvbgorICAgICAqCisgICAgICogIFRPRE8gbm90IHN1cHBvcnRlZAorICAgICAqLworICAgIEBLbm93bkZhaWx1cmUoIm5vdCBzdXBwb3J0ZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RVcGRhdGUyKCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIERhdGFiYXNlQ3JlYXRvci5maWxsRktTdHJpY3RUYWJsZShjb25uKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlVXBkYXRlKCJVUERBVEUgIiArIERhdGFiYXNlQ3JlYXRvci5QQVJFTlRfVEFCTEUKKyAgICAgICAgICAgICAgICAgICAgKyAiIFNFVCBpZCA9IDUgV0hFUkUgaWQgPSAxOyIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0aW5nIFNRTEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZUZ1bmN0aW9uYWxpdHlUZXN0MiN0ZXN0VXBkYXRlMygpLiBEZWxldGVzIGFsbCByZWZlcmVuY2luZworICAgICAqICAgICAgICByb3dzIGFuZCB0aGVuIHVwZGF0ZXMgcmVmZXJlbmNlZCBvbmUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXBkYXRlMygpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBEYXRhYmFzZUNyZWF0b3IuZmlsbEZLU3RyaWN0VGFibGUoY29ubik7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKCJERUxFVEUgRlJPTSAiICsgRGF0YWJhc2VDcmVhdG9yLkZLU1RSSUNUX1RBQkxFCisgICAgICAgICAgICAgICAgKyAiIFdIRVJFIG5hbWVfaWQgPSAxOyIpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZSgiVVBEQVRFICIgKyBEYXRhYmFzZUNyZWF0b3IuUEFSRU5UX1RBQkxFCisgICAgICAgICAgICAgICAgKyAiIFNFVCBpZCA9IDUgV0hFUkUgaWQgPSAxOyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZUZ1bmN0aW9uYWxpdHlUZXN0MiN0ZXN0VXBkYXRlNCgpLiBBdHRlbXB0cyB0byBzZXQgaW5jb3JyZWN0CisgICAgICogICAgICAgIGZvcmVpZ24ga2V5IHZhbHVlIC0gZXhwZWN0aW5nIFNRTEV4Y2VwdGlvbgorICAgICAqCisgICAgICogIFRPRE8gZm9yZWlnbiBrZXkgZnVuY3Rpb25hbGl0eSBpcyBub3Qgc3VwcG9ydGVkCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgibm90IHN1cHBvcnRlZCIpCisgICAgcHVibGljIHZvaWQgdGVzdFVwZGF0ZTQoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICBEYXRhYmFzZUNyZWF0b3IuZmlsbEZLU3RyaWN0VGFibGUoY29ubik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZVVwZGF0ZSgiVVBEQVRFICIgKyBEYXRhYmFzZUNyZWF0b3IuRktTVFJJQ1RfVEFCTEUKKyAgICAgICAgICAgICAgICAgICAgKyAiIFNFVCBuYW1lX2lkID0gNiBXSEVSRSBuYW1lX2lkID0gMiIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0aW5nIFNRTEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVGdW5jdGlvbmFsaXR5VGVzdDIjdGVzdFVwZGF0ZTUoKS4gVXBkYXRlcyByb3cgd2l0aAorICAgICAqICAgICAgICByZWZlcmVuY2luZyBvbmVzIGFuZCBDQVNDQURFIGFjdGlvbiAtIGV4cGVjdGluZyB0aGF0IGFsbAorICAgICAqICAgICAgICByZWZlcmVuY2luZyByb3dzIHdpbGwgYWxzbyBiZSB1cGRhdGVkCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVwZGF0ZTUoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmZpbGxGS0Nhc2NhZGVUYWJsZShjb25uKTsKKyAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGVVcGRhdGUoIlVQREFURSAiICsgRGF0YWJhc2VDcmVhdG9yLlBBUkVOVF9UQUJMRQorICAgICAgICAgICAgICAgICsgIiBTRVQgaWQgPSA1IFdIRVJFIGlkID0gMTsiKTsKKworICAgICAgICBSZXN1bHRTZXQgciA9IHN0YXRlbWVudC5leGVjdXRlUXVlcnkoIlNFTEVDVCBDT1VOVCgqKSAiICsgIkZST00gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLkZLQ0FTQ0FERV9UQUJMRSArICIgV0hFUkUgbmFtZV9pZCA9IDE7Iik7CisgICAgICAgIHIubmV4dCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCBiZSAyIHJvd3MiLCAyLCByLmdldEludCgxKSk7CisgICAgICAgIHIgPSBzdGF0ZW1lbnQuZXhlY3V0ZVF1ZXJ5KCJTRUxFQ1QgQ09VTlQoKikgIiArICJGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5GS0NBU0NBREVfVEFCTEUgKyAiIFdIRVJFIG5hbWVfaWQgPSA1OyIpOworICAgICAgICByLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTaG91bGQgYmUgMCByb3dzIiwgMCwgci5nZXRJbnQoMSkpOworICAgICAgICByLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlRnVuY3Rpb25hbGl0eVRlc3QyI3Rlc3RVcGRhdGU2KCkuIEF0dGVtcHRzIHRvIHNldCBpbmNvcnJlY3QKKyAgICAgKiAgICAgICAgZm9yZWlnbiBrZXkgdmFsdWUgdG8gcm93IHdpdGggQ0FTQ0FERSBhY3Rpb24gLSBleHBlY3RpbmcKKyAgICAgKiAgICAgICAgU1FMRXhjZXB0aW9uCisgICAgICoKKyAgICAgKiAgVE9ETyBGb3JlaWduIGtleSBmdW5jdGlvbmFsaXR5IGlzIG5vdCBzdXBwb3J0ZWQKKyAgICAgKi8KKyAgICBAS25vd25GYWlsdXJlKCJub3Qgc3VwcG9ydGVkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXBkYXRlNigpIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBEYXRhYmFzZUNyZWF0b3IuZmlsbEZLQ2FzY2FkZVRhYmxlKGNvbm4pOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGVVcGRhdGUoIlVQREFURSAiICsgRGF0YWJhc2VDcmVhdG9yLkZLQ0FTQ0FERV9UQUJMRQorICAgICAgICAgICAgICAgICAgICArICIgU0VUIG5hbWVfaWQgPSA2IFdIRVJFIG5hbWVfaWQgPSAyIik7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RpbmcgU1FMRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKFNRTEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZUZ1bmN0aW9uYWxpdHlUZXN0MiN0ZXN0VXBkYXRlNygpLiBVcGRhdGVzIHRhYmxlIHVzaW5nCisgICAgICogICAgICAgIHN1YnF1ZXJ5IGluIFdIRVJFIGNsYXVzZQorICAgICAqCisgICAgICogIFRPRE8gRm9yZWlnbiBrZXkgZnVuY3Rpb25hbGl0eSBpcyBub3Qgc3VwcG9ydGVkCisgICAgICovCisgICAgQEtub3duRmFpbHVyZSgibm90IHN1cHBvcnRlZCIpCisgICBwdWJsaWMgdm9pZCB0ZXN0VXBkYXRlNygpIHRocm93cyBTUUxFeGNlcHRpb24geworCisgICAgICAgIERhdGFiYXNlQ3JlYXRvci5maWxsRktTdHJpY3RUYWJsZShjb25uKTsKKyAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGVVcGRhdGUoIlVQREFURSAiICsgRGF0YWJhc2VDcmVhdG9yLkZLU1RSSUNUX1RBQkxFCisgICAgICAgICAgICAgICAgKyAiIFNFVCB2YWx1ZSA9ICd1cGRhdGVkJyBXSEVSRSBuYW1lX2lkID0gQU5ZIChTRUxFQ1QgaWQgRlJPTSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuUEFSRU5UX1RBQkxFICsgIiBXSEVSRSBpZCA+IDEpIik7CisgICAgICAgIFJlc3VsdFNldCByID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeSgiU0VMRUNUIENPVU5UKCopIEZST00gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLkZLU1RSSUNUX1RBQkxFICsgIiBXSEVSRSB2YWx1ZSA9ICd1cGRhdGVkJzsiKTsKKyAgICAgICAgci5uZXh0KCk7CisgICAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIGJlIDEgcm93IiwgMSwgci5nZXRJbnQoMSkpOworICAgICAgICByLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlRnVuY3Rpb25hbGl0eVRlc3QyI3Rlc3RVcGRhdGU4KCkuIFVwZGF0ZXMgdGFibGUgdXNpbmcgc2NhbGFyCisgICAgICogICAgICAgIHN1YnF1ZXJ5IGFzIG5ldyBmaWVsZCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RVcGRhdGU4KCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlVXBkYXRlKCJVUERBVEUgIiArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUzCisgICAgICAgICAgICAgICAgKyAiIFNFVCBzcGVlZCA9IChTRUxFQ1QgTUFYKHNwZWVkKSBGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxCisgICAgICAgICAgICAgICAgKyAiKSBXSEVSRSBpZCA9IChTRUxFQ1QgaWQgRlJPTSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMQorICAgICAgICAgICAgICAgICsgIiBXSEVSRSBzcGVlZCA9IChTRUxFQ1QgTUFYKHNwZWVkKSBGUk9NICIKKyAgICAgICAgICAgICAgICArIERhdGFiYXNlQ3JlYXRvci5TSU1QTEVfVEFCTEUxICsgIikpIik7CisgICAgICAgIFJlc3VsdFNldCByID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeSgiU0VMRUNUIGlkIEZST00gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlNJTVBMRV9UQUJMRTMKKyAgICAgICAgICAgICAgICArICIgV0hFUkUgc3BlZWQgPSAoU0VMRUNUIE1BWChzcGVlZCkgRlJPTSAiCisgICAgICAgICAgICAgICAgKyBEYXRhYmFzZUNyZWF0b3IuU0lNUExFX1RBQkxFMSArICIpOyIpOworICAgICAgICByLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgaWQgdXBkYXRlZCIsIDEsIHIuZ2V0SW50KDEpKTsKKyAgICAgICAgci5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZUZ1bmN0aW9uYWxpdHlUZXN0MiN0ZXN0VXBkYXRlOSgpLiBVcGRhdGVzIHRhYmxlIHVzaW5nCisgICAgICogICAgICAgIFByZXBhcmVkU3RhdGVtZW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFVwZGF0ZTkoKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgRGF0YWJhc2VDcmVhdG9yLmZpbGxUZXN0VGFibGU1KGNvbm4pOworICAgICAgICBQcmVwYXJlZFN0YXRlbWVudCBzdGF0ID0gY29ubi5wcmVwYXJlU3RhdGVtZW50KCJVUERBVEUgIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEU1CisgICAgICAgICAgICAgICAgKyAiIFNFVCB0ZXN0VmFsdWUgPSA/IFdIRVJFIHRlc3RJRCA9ID8iKTsKKyAgICAgICAgc3RhdC5zZXRTdHJpbmcoMSwgIjEiKTsKKyAgICAgICAgc3RhdC5zZXRJbnQoMiwgMSk7CisgICAgICAgIHN0YXQuZXhlY3V0ZSgpOworICAgICAgICBzdGF0LnNldFN0cmluZygxLCAiMiIpOworICAgICAgICBzdGF0LnNldEludCgyLCAyKTsKKyAgICAgICAgc3RhdC5leGVjdXRlKCk7CisgICAgICAgIFJlc3VsdFNldCByID0gc3RhdGVtZW50LmV4ZWN1dGVRdWVyeSgiU0VMRUNUIHRlc3RJZCwgdGVzdFZhbHVlIEZST00gIgorICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLlRFU1RfVEFCTEU1CisgICAgICAgICAgICAgICAgKyAiIFdIRVJFIHRlc3RJRCA8IDMgT1JERVIgQlkgdGVzdElEIik7CisgICAgICAgIHdoaWxlIChyLm5leHQoKSkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdmFsdWUgd2FzIHJldHVybmVkIiwgbmV3IEludGVnZXIocgorICAgICAgICAgICAgICAgICAgICAuZ2V0SW50KDEpKS50b1N0cmluZygpLCByLmdldFN0cmluZygyKSk7CisgICAgICAgIH0KKyAgICAgICAgci5jbG9zZSgpOworICAgICAgICBzdGF0LmNsb3NlKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0F0dHJHZXRPd25lckVsZW1lbnQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9BdHRyR2V0T3duZXJFbGVtZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjZjZmQ1OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9BdHRyR2V0T3duZXJFbGVtZW50LmphdmEKQEAgLTAsMCArMSwxMjYgQEAKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5BdHRyOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKK2ltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBBdHRyR2V0T3duZXJFbGVtZW50IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24yKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKy8vIEFzc3VtZXMgdmFsaWRhdGlvbi4KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRPd25lckVsZW1lbnQxKCkgdGhyb3dzIFRocm93YWJsZSB7CisvLyAgICAgICAgRG9jdW1lbnQgZG9jOworLy8gICAgICAgIEF0dHIgYXR0cjsKKy8vICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisvLyAgICAgICAgRWxlbWVudCBvd25lckVsZW1lbnQ7CisvLyAgICAgICAgU3RyaW5nIG93bmVyRWxlbWVudE5hbWU7CisvLyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisvLyAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisvLyAgICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisvLworLy8gICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworLy8KKy8vICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwKKy8vICAgICAgICAgICAgICAgICJlbXBsb3llZSIpOworLy8gICAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgxKTsKKy8vICAgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisvLyAgICAgICAgYXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKG51bGxOUywgImRlZmF1bHRBdHRyIik7CisvLyAgICAgICAgb3duZXJFbGVtZW50ID0gYXR0ci5nZXRPd25lckVsZW1lbnQoKTsKKy8vICAgICAgICBvd25lckVsZW1lbnROYW1lID0gb3duZXJFbGVtZW50LmdldE5vZGVOYW1lKCk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyZ2V0b3duZXJlbGVtZW50MDEiLCAiZW1wOmVtcGxveWVlIiwgb3duZXJFbGVtZW50TmFtZSk7CisvLworLy8gICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRPd25lckVsZW1lbnQyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBFbGVtZW50IG93bmVyRWxlbWVudDsKKyAgICAgICAgU3RyaW5nIG93bmVyRWxlbWVudE5hbWU7CisgICAgICAgIEF0dHIgYXR0cjsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCJyb290Iik7CisgICAgICAgIGF0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9MMSIsICJMMTphdHQiKTsKKyAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMoYXR0cik7CisgICAgICAgIG93bmVyRWxlbWVudCA9IGF0dHIuZ2V0T3duZXJFbGVtZW50KCk7CisgICAgICAgIG93bmVyRWxlbWVudE5hbWUgPSBvd25lckVsZW1lbnQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyZ2V0b3duZXJlbGVtZW50MDIiLCAicm9vdCIsIG93bmVyRWxlbWVudE5hbWUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0T3duZXJFbGVtZW50MygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGUgb3duZXJFbGVtZW50OworICAgICAgICBBdHRyIGF0dHI7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBhdHRyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00iLCAiZG9tOmF0dHIiKTsKKyAgICAgICAgb3duZXJFbGVtZW50ID0gYXR0ci5nZXRPd25lckVsZW1lbnQoKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiYXR0cmdldG93bmVyZWxlbWVudDAzIiwgb3duZXJFbGVtZW50KTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldE93bmVyRWxlbWVudDQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBEb2N1bWVudCBkb2NJbXA7CisgICAgICAgIE5vZGUgb3duZXJFbGVtZW50OworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIEF0dHIgYXR0cjsKKyAgICAgICAgQXR0ciBhdHRySW1wOworICAgICAgICBOb2RlTGlzdCBhZGRyZXNzZXM7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvY0ltcCA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBidWlsZGVyKTsKKworICAgICAgICBhZGRyZXNzZXMgPSBkb2MKKyAgICAgICAgICAgICAgICAuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJhZGRyZXNzIik7CisgICAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgYWRkcmVzc2VzLml0ZW0oMSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoImVtcEFkZHJlc3NOb3ROdWxsIiwgZWxlbWVudCk7CisgICAgICAgIGF0dHIgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5vZGVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJ6b25lIik7CisgICAgICAgIGF0dHJJbXAgPSAoQXR0cikgZG9jSW1wLmltcG9ydE5vZGUoYXR0ciwgdHJ1ZSk7CisgICAgICAgIG93bmVyRWxlbWVudCA9IGF0dHJJbXAuZ2V0T3duZXJFbGVtZW50KCk7CisgICAgICAgIGFzc2VydE51bGwoImF0dHJnZXRvd25lcmVsZW1lbnQwNCIsIG93bmVyRWxlbWVudCk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRPd25lckVsZW1lbnQ1KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZSBlbGVtZW50OworICAgICAgICBFbGVtZW50IG93bmVyRWxlbWVudDsKKyAgICAgICAgRWxlbWVudCBwYXJlbnRFbGVtZW50OworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgU3RyaW5nIG93bmVyRWxlbWVudE5hbWU7CisgICAgICAgIEF0dHIgYXR0cjsKKworICAgICAgICBOYW1lZE5vZGVNYXAgbm9kZU1hcDsKKyAgICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiYWRkcmVzcyIpOworICAgICAgICBlbGVtZW50ID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgICAgcGFyZW50RWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50LmdldFBhcmVudE5vZGUoKTsKKyAgICAgICAgbm9kZU1hcCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgICBwYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKGVsZW1lbnQpOworICAgICAgICBhdHRyID0gKEF0dHIpIG5vZGVNYXAuZ2V0TmFtZWRJdGVtTlMobnVsbE5TLCAic3RyZWV0Iik7CisgICAgICAgIG93bmVyRWxlbWVudCA9IGF0dHIuZ2V0T3duZXJFbGVtZW50KCk7CisgICAgICAgIG93bmVyRWxlbWVudE5hbWUgPSBvd25lckVsZW1lbnQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyZ2V0b3duZXJlbGVtZW50MDUiLCAiYWRkcmVzcyIsIG93bmVyRWxlbWVudE5hbWUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9DcmVhdGVBdHRyaWJ1dGVOUy5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0NyZWF0ZUF0dHJpYnV0ZU5TLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGU1MzgxMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9DcmVhdGVBdHRyaWJ1dGVOUy5qYXZhCkBAIC0wLDAgKzEsMTg4IEBACisvKgorIFRoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKKyBhbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorIFRoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworIENvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwKKyBSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyBQVVJQT1NFLgorCisgU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworICovCisKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkF0dHI7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBDcmVhdGVBdHRyaWJ1dGVOUyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMigpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVBdHRyaWJ1dGVOUzEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LmVjb21tZXJjZS5vcmcvIjsKKyAgICAgICAgU3RyaW5nIG1hbGZvcm1lZE5hbWUgPSAicHJlZml4Ojpsb2NhbCI7CisgICAgICAgIERvY3VtZW50IGRvYzsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgbWFsZm9ybWVkTmFtZSk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVBdHRyaWJ1dGVOUzIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9IG51bGw7CisKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAicHJlZml4OmxvY2FsIjsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBkb2MuY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZUF0dHJpYnV0ZU5TMygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cud2VkZGluZy5jb20vIjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWU7CisgICAgICAgIERvY3VtZW50IGRvYzsKKworICAgICAgICBMaXN0PFN0cmluZz4gaWxsZWdhbFFOYW1lcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOnsiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjp9Iik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246fiIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOiciKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjohIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246QCIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOiMiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjokIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246JSIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOl4iKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjomIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246KiIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOigiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjopIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246KyIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOj0iKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjpbIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246XSIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOlxcIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246LyIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOjsiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjpgIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246PCIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOj4iKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjosIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246YSAiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjpcIiIpOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBmb3IgKGludCBpbmRleE4xMDA5MCA9IDA7IGluZGV4TjEwMDkwIDwgaWxsZWdhbFFOYW1lcy5zaXplKCk7IGluZGV4TjEwMDkwKyspIHsKKyAgICAgICAgICAgIHF1YWxpZmllZE5hbWUgPSAoU3RyaW5nKSBpbGxlZ2FsUU5hbWVzLmdldChpbmRleE4xMDA5MCk7CisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSU5WQUxJRF9DSEFSQUNURVJfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZUF0dHJpYnV0ZU5TNCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZXMiOworICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJ4bWw6YXR0cjEiOworICAgICAgICBEb2N1bWVudCBkb2M7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisKKyAgICAgICAgeworICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGRvYy5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X05BTUVTUEFDRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q3JlYXRlQXR0cmlidXRlTlM1KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5lY29tbWVyY2Uub3JnLyI7CisgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gImVjb25tOmxvY2FsIjsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBBdHRyIG5ld0F0dHI7CisgICAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIG5ld0F0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgYXR0ck5hbWUgPSBuZXdBdHRyLmdldE5hbWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0aHJvd19FcXVhbHMiLCBxdWFsaWZpZWROYW1lLCBhdHRyTmFtZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVBdHRyaWJ1dGVOUzYoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LmV4YW1wbGUuY29tLyI7CisgICAgICAgIERvY3VtZW50IGRvYzsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgYnVpbGRlcik7CisKKyAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIC8vICAgICBPdXIgZXhjZXB0aW9uIHByaW9yaXRpZXMgZGlmZmVyIGZyb20gdGhlIHNwZWMKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRvYy5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksICIiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgIH0KKyAgICAgICAgLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9DcmVhdGVEb2N1bWVudC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0NyZWF0ZURvY3VtZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTk3Mzg0MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9DcmVhdGVEb2N1bWVudC5qYXZhCkBAIC0wLDAgKzEsMjc1IEBACisvKgorIFRoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKKyBhbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorIFRoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworIENvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwKKyBSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyBQVVJQT1NFLgorCisgU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworICovCisKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCitpbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRUeXBlOworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBUaGUgImNyZWF0ZURvY3VtZW50KG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lLGRvY3R5cGUpIiBtZXRob2QgZm9yIGEKKyAqIERPTUltcGxlbWVudGF0aW9uIHNob3VsZCByYWlzZSBOQU1FU1BBQ0VfRVJSIERPTUV4Y2VwdGlvbiBpZiBwYXJhbWV0ZXIKKyAqIHF1YWxpZmllZE5hbWUgaXMgbWFsZm9ybWVkLgorICoKKyAqIFJldHJpZXZlIHRoZSBET01JbXBsZW1lbnRhdGlvbiBvbiB0aGUgWE1MTlMgRG9jdW1lbnQuIEludm9rZSBtZXRob2QKKyAqIGNyZWF0ZURvY3VtZW50KG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lLGRvY3R5cGUpIG9uIHRoZSByZXRyaWV2ZWQKKyAqIERPTUltcGxlbWVudGF0aW9uIHdpdGggbmFtZXNwYWNlVVJJIGJlaW5nIHRoZSBsaXRlcmFsIHN0cmluZworICogImh0dHA6Ly93d3cuZWNvbW1lcmNlLm9yZy8iLCBxdWFsaWZpZWROYW1lIGFzICJwcmVmaXg6OmxvY2FsIiwgYW5kIGRvY3R5cGUgYXMKKyAqIG51bGwuIE1ldGhvZCBzaG91bGQgcmFpc2UgTkFNRVNQQUNFX0VSUiBET01FeGNlcHRpb24uCisgKgorICogQGF1dGhvciBOSVNUCisgKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOQU1FU1BBQ0VfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05BTUVTUEFDRV9FUlInXSk8L2E+CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2N1bWVudDwvYT4KKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50JykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIENyZWF0ZURvY3VtZW50IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24xKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZURvY3VtZW50MSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cuZWNvbW1lcmNlLm9yZy8iOworICAgICAgICBTdHJpbmcgbWFsZm9ybWVkTmFtZSA9ICJwcmVmaXg6OmxvY2FsIjsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZSA9IG51bGw7CisKKyAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworCisgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZG9tSW1wbC5jcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkksIG1hbGZvcm1lZE5hbWUsIGRvY1R5cGUpOworICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworCisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVEb2N1bWVudDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9IG51bGw7CisKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiazpsb2NhbCI7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGUgPSBudWxsOworCisgICAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKworICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRvbUltcGwuY3JlYXRlRG9jdW1lbnQobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lLCBkb2NUeXBlKTsKKyAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoInRocm93X05BTUVTUEFDRV9FUlIiLCBzdWNjZXNzKTsKKworICAgIH0KKworLy8gICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZURvY3VtZW50MygpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5lY29tbWVyY2Uub3JnL3NjaGVtYSI7CisvLyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAibmFtZXNwYWNlVVJJOngiOworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKy8vICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworLy8KKy8vICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKy8vICAgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKy8vICAgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisvLworLy8gICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIGRvbUltcGwuY3JlYXRlRG9jdW1lbnQobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lLCBkb2NUeXBlKTsKKy8vICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKy8vICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIpOworLy8gICAgICAgIH0KKy8vICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19XUk9OR19ET0NVTUVOVF9FUlIiLCBzdWNjZXNzKTsKKy8vCisvLyAgICB9CisKKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVEb2N1bWVudDQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKy8vICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cuZWNvbW1lcmNlLm9yZy9zY2hlbWEiOworLy8gICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gIm5hbWVzcGFjZVVSSTp4IjsKKy8vICAgICAgICBEb2N1bWVudCBkb2M7CisvLyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisvLyAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKy8vICAgICAgICBEb2N1bWVudCBhTmV3RG9jOworLy8gICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworLy8gICAgICAgIGFOZXdEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKy8vICAgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKy8vICAgICAgICBkb21JbXBsID0gYU5ld0RvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworLy8KKy8vICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKy8vICAgICAgICB0cnkgeworLy8gICAgICAgICAgICBhTmV3RG9jID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsCisvLyAgICAgICAgICAgICAgICAgICAgZG9jVHlwZSk7CisvLyAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisvLyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSKTsKKy8vICAgICAgICB9CisvLyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfV1JPTkdfRE9DVU1FTlRfRVJSIiwgc3VjY2Vzcyk7CisvLworLy8gICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVEb2N1bWVudDUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LmVjb21tZXJjZS5vcmcvc2NoZW1hIjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWU7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGUgPSBudWxsOworCisgICAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisKKyAgICAgICAgTGlzdDxTdHJpbmc+IGlsbGVnYWxRTmFtZXMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTp7Iik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6fSIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOn4iKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTonIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6ISIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOkAiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTojIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6JCIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOiUiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTpeIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6JiIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOioiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTooIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6KSIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOisiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTo9Iik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6WyIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOl0iKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTpcXCIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOi8iKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTo7Iik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6YCIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOjwiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoIm5hbWVzcGFjZVVSSTo+Iik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6LCIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgibmFtZXNwYWNlVVJJOmEgIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJuYW1lc3BhY2VVUkk6XCIiKTsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZm9yIChpbnQgaW5kZXhOMTAwOUEgPSAwOyBpbmRleE4xMDA5QSA8IGlsbGVnYWxRTmFtZXMuc2l6ZSgpOyBpbmRleE4xMDA5QSsrKSB7CisgICAgICAgICAgICBxdWFsaWZpZWROYW1lID0gKFN0cmluZykgaWxsZWdhbFFOYW1lcy5nZXQoaW5kZXhOMTAwOUEpOworICAgICAgICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworCisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZG9tSW1wbC5jcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsIGRvY1R5cGUpOworICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTlZBTElEX0NIQVJBQ1RFUl9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSU5WQUxJRF9DSEFSQUNURVJfRVJSIiwgc3VjY2Vzcyk7CisKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q3JlYXRlRG9jdW1lbnQ2KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL2Vjb21tZXJjZS5vcmcvc2NoZW1hIjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAieG1sOmxvY2FsIjsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZSA9IG51bGw7CisKKyAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworCisgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZG9tSW1wbC5jcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsIGRvY1R5cGUpOworICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworCisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVEb2N1bWVudDcoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LmVjb21tZXJjZS5vcmcvc2NoZW1hIjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAieTp4IjsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZSA9IG51bGw7CisKKyAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgICAgRG9jdW1lbnQgYU5ld0RvYzsKKyAgICAgICAgU3RyaW5nIG5vZGVOYW1lOworICAgICAgICBTdHJpbmcgbm9kZVZhbHVlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgICBhTmV3RG9jID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsIGRvY1R5cGUpOworICAgICAgICBub2RlTmFtZSA9IGFOZXdEb2MuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgICAgbm9kZVZhbHVlID0gYU5ld0RvYy5nZXROb2RlVmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTmFtZSIsICIjZG9jdW1lbnQiLCBub2RlTmFtZSk7CisgICAgICAgIGFzc2VydE51bGwoIm5vZGVWYWx1ZSIsIG5vZGVWYWx1ZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVEb2N1bWVudDgoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LmV4YW1wbGUub3JnL3NjaGVtYSI7CisgICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlID0gbnVsbDsKKworICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworCisgICAgICAgIGRvbUltcGwgPSBidWlsZGVyLmdldERPTUltcGxlbWVudGF0aW9uKCk7CisKKyAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIC8vICAgICBPdXIgZXhjZXB0aW9uIHByaW9yaXRpZXMgZGlmZmVyIGZyb20gdGhlIHNwZWMKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRvbUltcGwuY3JlYXRlRG9jdW1lbnQobmFtZXNwYWNlVVJJLCAiIiwgZG9jVHlwZSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICB9CisgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vQ3JlYXRlRG9jdW1lbnRUeXBlLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vQ3JlYXRlRG9jdW1lbnRUeXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjdkYTQzNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9DcmVhdGVEb2N1bWVudFR5cGUuamF2YQpAQCAtMCwwICsxLDE5MiBAQAorLyoKKyBUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCisgYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KKyBUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKyBDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCisgUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgUFVSUE9TRS4KKworIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyAqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogVGhlICJjcmVhdGVEb2N1bWVudFR5cGUocXVhbGlmaWVkTmFtZSxwdWJsaWNJZCxzeXN0ZW1JZCkiIG1ldGhvZCBmb3IgYQorICogRE9NSW1wbGVtZW50YXRpb24gc2hvdWxkIHJhaXNlIE5BTUVTUEFDRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHF1YWxpZmllZE5hbWUgaXMKKyAqIG1hbGZvcm1lZC4KKyAqCisgKiBSZXRyaWV2ZSB0aGUgRE9NSW1wbGVtZW50YXRpb24gb24gdGhlIFhNTE5TIERvY3VtZW50LiBJbnZva2UgbWV0aG9kCisgKiBjcmVhdGVEb2N1bWVudFR5cGUocXVhbGlmaWVkTmFtZSxwdWJsaWNJZCxzeXN0ZW1JZCkgb24gdGhlIHJldHJpZXZlZAorICogRE9NSW1wbGVtZW50YXRpb24gd2l0aCBxdWFsaWZpZWROYW1lIGJlaW5nIHRoZSBsaXRlcmFsIHN0cmluZworICogInByZWZpeDo6bG9jYWwiLCBwdWJsaWNJZCBhcyAiU1RBRkYiLCBhbmQgc3lzdGVtSWQgYXMgInN0YWZmIi4gTWV0aG9kIHNob3VsZAorICogcmFpc2UgTkFNRVNQQUNFX0VSUiBET01FeGNlcHRpb24uCisgKgorICogQGF1dGhvciBOSVNUCisgKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOQU1FU1BBQ0VfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05BTUVTUEFDRV9FUlInXSk8L2E+CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY1R5cGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY1R5cGU8L2E+CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2NUeXBlJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY1R5cGUnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdOQU1FU1BBQ0VfRVJSJ10pPC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQ3JlYXRlRG9jdW1lbnRUeXBlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24xKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZURvY3VtZW50VHlwZTEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIHB1YmxpY0lkID0gIlNUQUZGIjsKKyAgICAgICAgU3RyaW5nIHN5c3RlbUlkID0gInN0YWZmLnhtbCI7CisgICAgICAgIFN0cmluZyBtYWxmb3JtZWROYW1lID0gInByZWZpeDo6bG9jYWwiOworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZG9tSW1wbC5jcmVhdGVEb2N1bWVudFR5cGUobWFsZm9ybWVkTmFtZSwgcHVibGljSWQsIHN5c3RlbUlkKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZURvY3VtZW50VHlwZTIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIHB1YmxpY0lkID0gImh0dHA6Ly93d3cubG9jYWxob3N0LmNvbS8iOworICAgICAgICBTdHJpbmcgc3lzdGVtSWQgPSAibXlEb2MuZHRkIjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWU7CisgICAgICAgIERvY3VtZW50IGRvYzsKKworICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgICBMaXN0PFN0cmluZz4gaWxsZWdhbFFOYW1lcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOnsiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTp9Iik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6fiIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOiciKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTohIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6QCIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOiMiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTokIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6JSIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOl4iKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTomIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6KiIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOigiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTopIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6KyIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOj0iKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTpbIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6XSIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOlxcIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6LyIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOjsiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTpgIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6PCIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgiZWRpOj4iKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTosIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJlZGk6YSAiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoImVkaTpcIiIpOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBmb3IgKGludCBpbmRleE4xMDA5QSA9IDA7IGluZGV4TjEwMDlBIDwgaWxsZWdhbFFOYW1lcy5zaXplKCk7IGluZGV4TjEwMDlBKyspIHsKKyAgICAgICAgICAgIHF1YWxpZmllZE5hbWUgPSAoU3RyaW5nKSBpbGxlZ2FsUU5hbWVzLmdldChpbmRleE4xMDA5QSk7CisgICAgICAgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBkb21JbXBsLmNyZWF0ZURvY3VtZW50VHlwZShxdWFsaWZpZWROYW1lLCBwdWJsaWNJZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1JZCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSU5WQUxJRF9DSEFSQUNURVJfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZURvY3VtZW50VHlwZTMoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKworICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJwcmVmaXg6bXlEb2MiOworICAgICAgICBTdHJpbmcgcHVibGljSWQgPSAiaHR0cDovL3d3dy5sb2NhbGhvc3QuY29tIjsKKyAgICAgICAgU3RyaW5nIHN5c3RlbUlkID0gIm15RG9jLmR0ZCI7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgICAgRG9jdW1lbnRUeXBlIG5ld1R5cGUgPSBudWxsOworCisgICAgICAgIFN0cmluZyBub2RlTmFtZTsKKyAgICAgICAgU3RyaW5nIG5vZGVWYWx1ZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgICAgbmV3VHlwZSA9IGRvbUltcGwuY3JlYXRlRG9jdW1lbnRUeXBlKHF1YWxpZmllZE5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCk7CisgICAgICAgIG5vZGVOYW1lID0gbmV3VHlwZS5nZXROb2RlTmFtZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lIiwgInByZWZpeDpteURvYyIsIG5vZGVOYW1lKTsKKyAgICAgICAgbm9kZVZhbHVlID0gbmV3VHlwZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgibm9kZVZhbHVlIiwgbm9kZVZhbHVlKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZURvY3VtZW50VHlwZTQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIHB1YmxpY0lkID0gImh0dHA6Ly93d3cuZXhhbXBsZS5jb20vIjsKKyAgICAgICAgU3RyaW5nIHN5c3RlbUlkID0gIm15RG9jLmR0ZCI7CisKKyAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgICAgZG9tSW1wbCA9IGJ1aWxkZXIuZ2V0RE9NSW1wbGVtZW50YXRpb24oKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZG9tSW1wbC5jcmVhdGVEb2N1bWVudFR5cGUoIiIsIHB1YmxpY0lkLCBzeXN0ZW1JZCk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0NyZWF0ZUVsZW1lbnROUy5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0NyZWF0ZUVsZW1lbnROUy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUwYmZiZjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vQ3JlYXRlRWxlbWVudE5TLmphdmEKQEAgLTAsMCArMSwyMTAgQEAKKy8qCisgVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorIGFuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCisgVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisgQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbAorIFJpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorIFBVUlBPU0UuCisKKyBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisgKi8KKworcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBUaGUgImNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkkscXVhbGlmaWVkTmFtZSkiIG1ldGhvZCBmb3IgYSBEb2N1bWVudAorICogc2hvdWxkIHJhaXNlIE5BTUVTUEFDRV9FUlIgRE9NRXhjZXB0aW9uIGlmIHF1YWxpZmllZE5hbWUgaXMgbWFsZm9ybWVkLgorICoKKyAqIEludm9rZSBtZXRob2QgY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZVVSSSxxdWFsaWZpZWROYW1lKSBvbiB0aGUgWE1MTlMKKyAqIERvY3VtZW50IHdpdGggbmFtZXNwYWNlVVJJIGJlaW5nIHRoZSBsaXRlcmFsIHN0cmluZworICogImh0dHA6Ly93d3cuZWNvbW1lcmNlLm9yZy8iLCBhbmQgcXVhbGlmaWVkTmFtZSBhcyAicHJlZml4Ojpsb2NhbCIuIE1ldGhvZAorICogc2hvdWxkIHJhaXNlIE5BTUVTUEFDRV9FUlIgRE9NRXhjZXB0aW9uLgorICoKKyAqIEBhdXRob3IgTklTVAorICogQGF1dGhvciBNYXJ5IEJyYWR5CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nTkFNRVNQQUNFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOQU1FU1BBQ0VfRVJSJ10pPC9hPgorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRG9jQ3JFbE5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRG9jQ3JFbE5TPC9hPgorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELURvY0NyRWxOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05BTUVTUEFDRV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRG9jQ3JFbE5TJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTkFNRVNQQUNFX0VSUiddKTwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIENyZWF0ZUVsZW1lbnROUyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVFbGVtZW50TlMxKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5lY29tbWVyY2Uub3JnLyI7CisgICAgICAgIFN0cmluZyBtYWxmb3JtZWROYW1lID0gInByZWZpeDo6bG9jYWwiOworICAgICAgICBEb2N1bWVudCBkb2M7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisKKyAgICAgICAgeworICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGRvYy5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCBtYWxmb3JtZWROYW1lKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZUVsZW1lbnROUzIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9IG51bGw7CisKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAicHJlZml4OmxvY2FsIjsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBkb2MuY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVFbGVtZW50TlMzKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy53ZWRkaW5nLmNvbS8iOworICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZTsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworCisgICAgICAgIExpc3Q8U3RyaW5nPiBpbGxlZ2FsUU5hbWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246eyIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOn0iKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjp+Iik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246JyIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOiEiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjpAIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246IyIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOiQiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjolIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246XiIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOiYiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjoqIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246KCIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOikiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjorIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246PSIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOlsiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjpdIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246XFwiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjovIik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246OyIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOmAiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjo8Iik7CisgICAgICAgIGlsbGVnYWxRTmFtZXMuYWRkKCJwZXJzb246PiIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOiwiKTsKKyAgICAgICAgaWxsZWdhbFFOYW1lcy5hZGQoInBlcnNvbjphICIpOworICAgICAgICBpbGxlZ2FsUU5hbWVzLmFkZCgicGVyc29uOlwiIik7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGZvciAoaW50IGluZGV4TjEwMDk4ID0gMDsgaW5kZXhOMTAwOTggPCBpbGxlZ2FsUU5hbWVzLnNpemUoKTsgaW5kZXhOMTAwOTgrKykgeworICAgICAgICAgICAgcXVhbGlmaWVkTmFtZSA9IChTdHJpbmcpIGlsbGVnYWxRTmFtZXMuZ2V0KGluZGV4TjEwMDk4KTsKKworICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGRvYy5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTlZBTElEX0NIQVJBQ1RFUl9FUlIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTlZBTElEX0NIQVJBQ1RFUl9FUlIiLCBzdWNjZXNzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q3JlYXRlRWxlbWVudE5TNCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZXMiOworICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJ4bWw6ZWxlbWVudDEiOworICAgICAgICBEb2N1bWVudCBkb2M7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisKKyAgICAgICAgeworICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGRvYy5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZUVsZW1lbnROUzUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5pc3QuZ292IjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiZ292OmZhY3VsdHkiOworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEVsZW1lbnQgbmV3RWxlbWVudDsKKyAgICAgICAgU3RyaW5nIGVsZW1lbnROYW1lOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgbmV3RWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgZWxlbWVudE5hbWUgPSBuZXdFbGVtZW50LmdldFRhZ05hbWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0aHJvd19FcXVhbHMiLCBxdWFsaWZpZWROYW1lLCBlbGVtZW50TmFtZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVFbGVtZW50TlM2KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5leGFtcGxlLmNvbS8iOworCisgICAgICAgIERvY3VtZW50IGRvYzsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgYnVpbGRlcik7CisKKyAgICAgICAgeworICAgICAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgICAgICAvLyAgICAgT3VyIGV4Y2VwdGlvbiBwcmlvcml0aWVzIGRpZmZlciBmcm9tIHRoZSBzcGVjCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGRvYy5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCAiIik7CisgICAgICAgICAgICAgICAgZmFpbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBFTkQgYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0RPTURvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZWI5OWM4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0RPTURvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDk0IEBACitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKKworcHVibGljIGNsYXNzIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgeworICAgIC8qKgorICAgICAqIFBhcnNlciBjb25maWd1cmF0aW9uCisgICAgICovCisgICAgcHJpdmF0ZSBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MgPSBudWxsOworCisgICAgcHJpdmF0ZSBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlciA9IG51bGw7CisKKyAgICBwcml2YXRlIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9IG51bGw7CisKKyAgICBwdWJsaWMgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gc2V0dGluZ3MpIHsKKyAgICAgICAgaWYgKHNldHRpbmdzID09IG51bGwpIHsKKyAgICAgICAgICAgIHNldHRpbmdzID0gbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmdbMF07CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzZXR0aW5ncyA9IChEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10pIHNldHRpbmdzLmNsb25lKCk7CisgICAgICAgIH0KKworICAgICAgICBmYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworCisgICAgICAgIGlmIChmYWN0b3J5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IG11c3Qgbm90IGJlIG51bGwiKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzZXR0aW5ncyAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNldHRpbmdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgc2V0dGluZ3NbaV0uYXBwbHlTZXR0aW5nKGZhY3RvcnkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGJ1aWxkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkRvY3VtZW50QnVpbGRlciBtdXN0IG5vdCBiZSBudWxsIik7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHB1YmxpYyBEb2N1bWVudEJ1aWxkZXIgZ2V0QnVpbGRlcigpIHsKKyAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaGFzRmVhdHVyZShTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pIHsKKyAgICAgICAgcmV0dXJuIGJ1aWxkZXIuZ2V0RE9NSW1wbGVtZW50YXRpb24oKS5oYXNGZWF0dXJlKGZlYXR1cmUsIHZlcnNpb24pOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzQ29hbGVzY2luZygpIHsKKyAgICAgICAgcmV0dXJuIGZhY3RvcnkuaXNDb2FsZXNjaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKCkgeworICAgICAgICByZXR1cm4gZmFjdG9yeS5pc0V4cGFuZEVudGl0eVJlZmVyZW5jZXMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0lnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKCkgeworICAgICAgICByZXR1cm4gZmFjdG9yeS5pc0lnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNOYW1lc3BhY2VBd2FyZSgpIHsKKyAgICAgICAgcmV0dXJuIGZhY3RvcnkuaXNOYW1lc3BhY2VBd2FyZSgpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzVmFsaWRhdGluZygpIHsKKyAgICAgICAgcmV0dXJuIGZhY3RvcnkuaXNWYWxpZGF0aW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10gZ2V0Q29uZmlndXJhdGlvbjEoKSB7CisgICAgICAgIHJldHVybiBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1tdIHsKKyAgICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5vdENvYWxlc2NpbmcsCisgICAgICAgICAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RFeHBhbmRFbnRpdHlSZWZlcmVuY2VzLAorICAgICAgICAgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcubm90SWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UsCisgICAgICAgICAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3ROYW1lc3BhY2VBd2FyZSwKKyAgICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5vdFZhbGlkYXRpbmcgfTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIERvY3VtZW50QnVpbGRlclNldHRpbmdbXSBnZXRDb25maWd1cmF0aW9uMigpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nW10geworICAgICAgICAgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcubm90Q29hbGVzY2luZywKKyAgICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5vdEV4cGFuZEVudGl0eVJlZmVyZW5jZXMsCisgICAgICAgICAgICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5ub3RJZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSwKKyAgICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nLm5hbWVzcGFjZUF3YXJlLAorICAgICAgICAgICAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmcubm90VmFsaWRhdGluZyB9OworCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRE9NSW1wbGVtZW50YXRpb25DcmVhdGVEb2N1bWVudC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0RPTUltcGxlbWVudGF0aW9uQ3JlYXRlRG9jdW1lbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YzFlMDdkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0RPTUltcGxlbWVudGF0aW9uQ3JlYXRlRG9jdW1lbnQuamF2YQpAQCAtMCwwICsxLDE0NyBAQAorcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSBjcmVhdGVEb2N1bWVudCBtZXRob2Qgd2l0aCB2YWxpZCBhcmd1bWVudHMsIHNob3VsZCBjcmVhdGUgYSBET00gRG9jdW1lbnQKKyAqIG9mIHRoZSBzcGVjaWZpZWQgdHlwZS4KKyAqCisgKiBDYWxsIHRoZSBjcmVhdGVEb2N1bWVudCBvbiB0aGlzIERPTUltcGxlbWVudGF0aW9uIHdpdGggY3JlYXRlRG9jdW1lbnQKKyAqICgiaHR0cDovL3d3dy53My5vcmcvRE9NVGVzdC9MMiIsc2VlIHRoZSBhcnJheSBiZWxvdyBmb3IgdmFsaWQgUU5hbWVzLG51bGwpLgorICogQ2hlY2sgaWYgdGhlIHJldHVybmVkIERvY3VtZW50IG9iamVjdCBpcyBpcyBlbXB0eSB3aXRoIG5vIERvY3VtZW50IEVsZW1lbnQuCisgKgorICogQGF1dGhvciBJQk0KKyAqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1ET00tY3JlYXRlRG9jdW1lbnQiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtRE9NLWNyZWF0ZURvY3VtZW50PC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRE9NSW1wbGVtZW50YXRpb25DcmVhdGVEb2N1bWVudCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVEb2N1bWVudDMoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgICBEb2N1bWVudCBuZXdEb2M7CisgICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlID0gbnVsbDsKKworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cudzMub3JnL0RPTVRlc3QvTDIiOworICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZTsKKyAgICAgICAgTGlzdDxTdHJpbmc+IHF1YWxpZmllZE5hbWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiXzpfIik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiXzpoMCIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIl86dGVzdCIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoImxfOl8iKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJuczpfMCIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIm5zOmEwIik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgibnMwOnRlc3QiKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJhLmI6YyIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoImEtYjpjIik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiYS1iOmMiKTsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgICBmb3IgKGludCBpbmRleE4xMDA2QiA9IDA7IGluZGV4TjEwMDZCIDwgcXVhbGlmaWVkTmFtZXMuc2l6ZSgpOyBpbmRleE4xMDA2QisrKSB7CisgICAgICAgICAgICBxdWFsaWZpZWROYW1lID0gKFN0cmluZykgcXVhbGlmaWVkTmFtZXMuZ2V0KGluZGV4TjEwMDZCKTsKKyAgICAgICAgICAgIG5ld0RvYyA9IGRvbUltcGwuY3JlYXRlRG9jdW1lbnQobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lLAorICAgICAgICAgICAgICAgICAgICBkb2NUeXBlKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoImRvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwMyIsIG5ld0RvYyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZURvY3VtZW50NCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9IG51bGw7CisKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiZG9tOnJvb3QiOworICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZSA9IG51bGw7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZG9tSW1wbC5jcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsIGRvY1R5cGUpOworICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoImRvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwNCIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVEb2N1bWVudDUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworCisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy53My5vcmcveG1sLzE5OTgvbmFtZXNwYWNlIjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAieG1sOnJvb3QiOworICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZSA9IG51bGw7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZG9tSW1wbC5jcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsIGRvY1R5cGUpOworICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoImRvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnQwNSIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVEb2N1bWVudDcoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworCisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy53My5vcmcvRE9NVGVzdC9sZXZlbDIiOworICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZSA9IG51bGw7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZG9tSW1wbC5jcmVhdGVEb2N1bWVudChuYW1lc3BhY2VVUkksICI6IiwgZG9jVHlwZSk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudDA3Iiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRE9NSW1wbGVtZW50YXRpb25DcmVhdGVEb2N1bWVudFR5cGUuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9ET01JbXBsZW1lbnRhdGlvbkNyZWF0ZURvY3VtZW50VHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmZDU3YjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRE9NSW1wbGVtZW50YXRpb25DcmVhdGVEb2N1bWVudFR5cGUuamF2YQpAQCAtMCwwICsxLDE4NCBAQAorLyoKKyBUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCisgYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KKyBUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKyBDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCisgUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgUFVSUE9TRS4KKworIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyAqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBUaGUgbWV0aG9kIGNyZWF0ZURvY3VtZW50VHlwZSB3aXRoIHZhbGlkIHZhbHVlcyBmb3IgcXVhbGlmaWVkTmFtZSwgcHVibGljSWQKKyAqIGFuZCBzeXN0ZW1JZCBzaG91bGQgY3JlYXRlIGFuIGVtcHR5IERvY3VtZW50VHlwZSBub2RlLgorICoKKyAqIEludm9rZSBjcmVhdGVEb2N1bWVudCBvbiB0aGlzIERPTUltcGxlbWVudGF0aW9uIHdpdGggYSB2YWxpZCBxdWFsaWZpZWROYW1lCisgKiBhbmQgZGlmZmVyZW50IHB1YmxpY0lkcyBhbmQgc3lzdGVtSWRzLiBDaGVjayBpZiB0aGUgdGhlIERvY3VtZW50VHlwZSBub2RlIHdhcworICogY3JlYXRlZCB3aXRoIGl0cyBvd25lckRvY3VtZW50IGF0dHJpYnV0ZSBzZXQgdG8gbnVsbC4KKyAqCisgKiBAYXV0aG9yIElCTQorICogQGF1dGhvciBOZWlsIERlbGltYQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLURPTS1jcmVhdGVEb2N1bWVudCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0xldmVsLTItQ29yZS1ET00tY3JlYXRlRG9jdW1lbnQ8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBET01JbXBsZW1lbnRhdGlvbkNyZWF0ZURvY3VtZW50VHlwZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVEb2N1bWVudFR5cGUxKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgICAgRG9jdW1lbnRUeXBlIG5ld0RvY1R5cGU7CisgICAgICAgIERvY3VtZW50IG93bmVyRG9jdW1lbnQ7CisgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gInRlc3Q6cm9vdCI7CisgICAgICAgIFN0cmluZyBwdWJsaWNJZDsKKyAgICAgICAgU3RyaW5nIHN5c3RlbUlkOworICAgICAgICBMaXN0PFN0cmluZz4gcHVibGljSWRzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIHB1YmxpY0lkcy5hZGQoIjEyMzQiKTsKKyAgICAgICAgcHVibGljSWRzLmFkZCgidGVzdCIpOworCisgICAgICAgIExpc3Q8U3RyaW5nPiBzeXN0ZW1JZHMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgc3lzdGVtSWRzLmFkZCgiIik7CisgICAgICAgIHN5c3RlbUlkcy5hZGQoInRlc3QiKTsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgICBmb3IgKGludCBpbmRleE4xMDA1RCA9IDA7IGluZGV4TjEwMDVEIDwgcHVibGljSWRzLnNpemUoKTsgaW5kZXhOMTAwNUQrKykgeworICAgICAgICAgICAgcHVibGljSWQgPSAoU3RyaW5nKSBwdWJsaWNJZHMuZ2V0KGluZGV4TjEwMDVEKTsKKyAgICAgICAgICAgIGZvciAoaW50IGluZGV4TjEwMDYxID0gMDsgaW5kZXhOMTAwNjEgPCBzeXN0ZW1JZHMuc2l6ZSgpOyBpbmRleE4xMDA2MSsrKSB7CisgICAgICAgICAgICAgICAgc3lzdGVtSWQgPSAoU3RyaW5nKSBzeXN0ZW1JZHMuZ2V0KGluZGV4TjEwMDYxKTsKKyAgICAgICAgICAgICAgICBuZXdEb2NUeXBlID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudFR5cGUocXVhbGlmaWVkTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpY0lkLCBzeXN0ZW1JZCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgKKyAgICAgICAgICAgICAgICAgICAgICAgICJkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50dHlwZTAxX25ld0RvY1R5cGUiLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3RG9jVHlwZSk7CisgICAgICAgICAgICAgICAgb3duZXJEb2N1bWVudCA9IG5ld0RvY1R5cGUuZ2V0T3duZXJEb2N1bWVudCgpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoCisgICAgICAgICAgICAgICAgICAgICAgICAiZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwMV9vd25lckRvY3VtZW50IiwKKyAgICAgICAgICAgICAgICAgICAgICAgIG93bmVyRG9jdW1lbnQpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVEb2N1bWVudFR5cGUyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgICAgRG9jdW1lbnRUeXBlIG5ld0RvY1R5cGU7CisgICAgICAgIERvY3VtZW50IG93bmVyRG9jdW1lbnQ7CisgICAgICAgIFN0cmluZyBwdWJsaWNJZCA9ICJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9kb20yLmR0ZCI7CisgICAgICAgIFN0cmluZyBzeXN0ZW1JZCA9ICJkb20yLmR0ZCI7CisgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lOworICAgICAgICBMaXN0PFN0cmluZz4gcXVhbGlmaWVkTmFtZXMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJfOl8iKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJfOmgwIik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiXzp0ZXN0Iik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiXzpfLiIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIl86YS0iKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJsXzpfIik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgibnM6XzAiKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJuczphMCIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIm5zMDp0ZXN0Iik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgibnM6RUVFLiIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIm5zOl8tIik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiYS5iOmMiKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJhLWI6Yy5qIik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiYS1iOmMiKTsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgICBmb3IgKGludCBpbmRleE4xMDA3NyA9IDA7IGluZGV4TjEwMDc3IDwgcXVhbGlmaWVkTmFtZXMuc2l6ZSgpOyBpbmRleE4xMDA3NysrKSB7CisgICAgICAgICAgICBxdWFsaWZpZWROYW1lID0gKFN0cmluZykgcXVhbGlmaWVkTmFtZXMuZ2V0KGluZGV4TjEwMDc3KTsKKyAgICAgICAgICAgIG5ld0RvY1R5cGUgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50VHlwZShxdWFsaWZpZWROYW1lLCBwdWJsaWNJZCwKKyAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwMl9uZXdEb2NUeXBlIiwKKyAgICAgICAgICAgICAgICAgICAgbmV3RG9jVHlwZSk7CisgICAgICAgICAgICBvd25lckRvY3VtZW50ID0gbmV3RG9jVHlwZS5nZXRPd25lckRvY3VtZW50KCk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJkb21pbXBsZW1lbnRhdGlvbmNyZWF0ZWRvY3VtZW50dHlwZTAyX293bmVyRG9jdW1lbnQiLAorICAgICAgICAgICAgICAgICAgICBvd25lckRvY3VtZW50KTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q3JlYXRlRG9jdW1lbnRUeXBlNCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICAgIERvY3VtZW50VHlwZSBuZXdEb2NUeXBlOworICAgICAgICBEb2N1bWVudCBvd25lckRvY3VtZW50OworICAgICAgICBTdHJpbmcgcHVibGljSWQgPSAiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvZG9tMi5kdGQiOworICAgICAgICBTdHJpbmcgc3lzdGVtSWQgPSAiZG9tMi5kdGQiOworICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZTsKKyAgICAgICAgTGlzdDxTdHJpbmc+IHF1YWxpZmllZE5hbWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiXzpfIik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiXzpoMCIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIl86dGVzdCIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIl86Xy4iKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJfOmEtIik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgibF86XyIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIm5zOl8wIik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgibnM6YTAiKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJuczA6dGVzdCIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIm5zOkVFRS4iKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJuczpfLSIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoImEuYjpjIik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiYS1iOmMuaiIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoImEtYjpjIik7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgICAgZm9yIChpbnQgaW5kZXhOMTAwNzcgPSAwOyBpbmRleE4xMDA3NyA8IHF1YWxpZmllZE5hbWVzLnNpemUoKTsgaW5kZXhOMTAwNzcrKykgeworICAgICAgICAgICAgcXVhbGlmaWVkTmFtZSA9IChTdHJpbmcpIHF1YWxpZmllZE5hbWVzLmdldChpbmRleE4xMDA3Nyk7CisgICAgICAgICAgICBuZXdEb2NUeXBlID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudFR5cGUocXVhbGlmaWVkTmFtZSwgcHVibGljSWQsCisgICAgICAgICAgICAgICAgICAgIHN5c3RlbUlkKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoImRvbWltcGxlbWVudGF0aW9uY3JlYXRlZG9jdW1lbnR0eXBlMDJfbmV3RG9jVHlwZSIsCisgICAgICAgICAgICAgICAgICAgIG5ld0RvY1R5cGUpOworICAgICAgICAgICAgb3duZXJEb2N1bWVudCA9IG5ld0RvY1R5cGUuZ2V0T3duZXJEb2N1bWVudCgpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZG9taW1wbGVtZW50YXRpb25jcmVhdGVkb2N1bWVudHR5cGUwMl9vd25lckRvY3VtZW50IiwKKyAgICAgICAgICAgICAgICAgICAgb3duZXJEb2N1bWVudCk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9ET01JbXBsZW1lbnRhdGlvbkhhc0ZlYXR1cmUuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9ET01JbXBsZW1lbnRhdGlvbkhhc0ZlYXR1cmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MDM3MzBiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0RPTUltcGxlbWVudGF0aW9uSGFzRmVhdHVyZS5qYXZhCkBAIC0wLDAgKzEsMTE3IEBACitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSAiZmVhdHVyZSIgcGFyYW1ldGVyIGluIHRoZSAiaGFzRmVhdHVyZShmZWF0dXJlLHZlcnNpb24pIiBtZXRob2QgaXMgdGhlCisgKiBwYWNrYWdlIG5hbWUgb2YgdGhlIGZlYXR1cmUuIExlZ2FsIHZhbHVlcyBhcmUgWE1MIGFuZCBIVE1MIGFuZCBDT1JFLiAoVGVzdAorICogZm9yIGZlYXR1cmUgY29yZSwgbG93ZXIgY2FzZSkKKyAqCisgKiBSZXRyaWV2ZSB0aGUgZW50aXJlIERPTSBkb2N1bWVudCBhbmQgaW52b2tlIGl0cyAiZ2V0SW1wbGVtZW50YXRpb24oKSIgbWV0aG9kLgorICogVGhpcyBzaG91bGQgY3JlYXRlIGEgRE9NSW1wbGVtZW50YXRpb24gb2JqZWN0IHdob3NlICJoYXNGZWF0dXJlKGZlYXR1cmUsCisgKiB2ZXJzaW9uKSIgbWV0aG9kIGlzIGludm9rZWQgd2l0aCBmZWF0dXJlIGVxdWFsIHRvICJjb3JlIi4gVGhlIG1ldGhvZCBzaG91bGQKKyAqIHJldHVybiBhIGJvb2xlYW4gInRydWUiLgorICoKKyAqIEBhdXRob3IgTklTVAorICogQGF1dGhvciBNYXJ5IEJyYWR5CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC01Q0VEOTRENyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELTVDRUQ5NEQ3PC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRE9NSW1wbGVtZW50YXRpb25IYXNGZWF0dXJlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24xKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEhhc0ZlYXR1cmVDb3JlKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGJ1aWxkZXIpOworICAgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICAgIHN0YXRlID0gZG9tSW1wbC5oYXNGZWF0dXJlKCJjb3JlIiwgIjIuMCIpOworICAgICAgICBhc3NlcnRUcnVlKCJkb21pbXBsZW1lbnRhdGlvbkZlYXR1cmVjb3JlQXNzZXJ0Iiwgc3RhdGUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzRmVhdHVyZVhtbCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBidWlsZGVyKTsKKyAgICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgICBzdGF0ZSA9IGRvbUltcGwuaGFzRmVhdHVyZSgieG1sIiwgIjIuMCIpOworICAgICAgICBhc3NlcnRUcnVlKCJkb21pbXBsZW1lbnRhdGlvbkZlYXR1cmV4bWxWZXJzaW9uMkFzc2VydCIsIHN0YXRlKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEhhc0ZlYXR1cmUxKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgICAgU3RyaW5nIHZlcnNpb24gPSAiIjsKKyAgICAgICAgU3RyaW5nIHZlcnNpb24xID0gIjEuMCI7CisgICAgICAgIFN0cmluZyB2ZXJzaW9uMiA9ICIyLjAiOworICAgICAgICBTdHJpbmcgZmVhdHVyZUNvcmU7CisgICAgICAgIFN0cmluZyBmZWF0dXJlWE1MOworICAgICAgICBib29sZWFuIHN1Y2Nlc3M7CisgICAgICAgIExpc3Q8U3RyaW5nPiBmZWF0dXJlc1hNTCA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBmZWF0dXJlc1hNTC5hZGQoIlhNTCIpOworICAgICAgICBmZWF0dXJlc1hNTC5hZGQoInhtTCIpOworCisgICAgICAgIExpc3Q8U3RyaW5nPiBmZWF0dXJlc0NvcmUgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgZmVhdHVyZXNDb3JlLmFkZCgiQ29yZSIpOworICAgICAgICBmZWF0dXJlc0NvcmUuYWRkKCJDT1JFIik7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgICAgZm9yIChpbnQgaW5kZXhOMTAwNjMgPSAwOyBpbmRleE4xMDA2MyA8IGZlYXR1cmVzWE1MLnNpemUoKTsgaW5kZXhOMTAwNjMrKykgeworICAgICAgICAgICAgZmVhdHVyZVhNTCA9IChTdHJpbmcpIGZlYXR1cmVzWE1MLmdldChpbmRleE4xMDA2Myk7CisgICAgICAgICAgICBzdWNjZXNzID0gZG9tSW1wbC5oYXNGZWF0dXJlKGZlYXR1cmVYTUwsIHZlcnNpb24pOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZG9taW1wbGVtZW50YXRpb25oYXNmZWF0dXJlMDFfWE1MXzEiLCBzdWNjZXNzKTsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSBkb21JbXBsLmhhc0ZlYXR1cmUoZmVhdHVyZVhNTCwgdmVyc2lvbjEpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZG9taW1wbGVtZW50YXRpb25oYXNmZWF0dXJlMDFfWE1MXzIiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpbmRleE4xMDA3QyA9IDA7IGluZGV4TjEwMDdDIDwgZmVhdHVyZXNDb3JlLnNpemUoKTsgaW5kZXhOMTAwN0MrKykgeworICAgICAgICAgICAgZmVhdHVyZUNvcmUgPSAoU3RyaW5nKSBmZWF0dXJlc0NvcmUuZ2V0KGluZGV4TjEwMDdDKTsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSBkb21JbXBsLmhhc0ZlYXR1cmUoZmVhdHVyZUNvcmUsIHZlcnNpb24pOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZG9taW1wbGVtZW50YXRpb25oYXNmZWF0dXJlMDFfQ29yZV8xIiwgc3VjY2Vzcyk7CisgICAgICAgICAgICBzdWNjZXNzID0gZG9tSW1wbC5oYXNGZWF0dXJlKGZlYXR1cmVDb3JlLCB2ZXJzaW9uMSk7CisgICAgICAgICAgICBzdWNjZXNzID0gZG9tSW1wbC5oYXNGZWF0dXJlKGZlYXR1cmVDb3JlLCB2ZXJzaW9uMik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJkb21pbXBsZW1lbnRhdGlvbmhhc2ZlYXR1cmUwMV9Db3JlXzMiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzRmVhdHVyZTIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgICBib29sZWFuIHN1Y2Nlc3M7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICAgIHN1Y2Nlc3MgPSBkb21JbXBsLmhhc0ZlYXR1cmUoIkJsYWggQmxhaCIsICIiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoImRvbWltcGxlbWVudGF0aW9uaGFzZmVhdHVyZTAyIiwgc3VjY2Vzcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0RPTVRlc3RDYXNlLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRE9NVGVzdENhc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNTUwODk4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0RPTVRlc3RDYXNlLmphdmEKQEAgLTAsMCArMSwyMjcgQEAKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJMOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOworaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgRE9NVGVzdENhc2UgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgRG9jdW1lbnQgbG9hZChTdHJpbmcgZG9jVVJJLCBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcikgeworICAgICAgICBEb2N1bWVudCBkb2MgPSBsb2FkKHJlc29sdmVVUkkoZG9jVVJJKSwgYnVpbGRlcik7CisgICAgICAgIHJldHVybiBkb2M7CisgICAgfQorCisgICAgcHVibGljIERvY3VtZW50IGxvYWQoVVJMIHVybCwgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jID0gbnVsbDsKKyAgICAgICAgRXhjZXB0aW9uIHBhcnNlRXhjZXB0aW9uID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIExvYWRFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyID0gbmV3IExvYWRFcnJvckhhbmRsZXIoKTsKKyAgICAgICAgICAgIGJ1aWxkZXIuc2V0RXJyb3JIYW5kbGVyKGVycm9ySGFuZGxlcik7CisgICAgICAgICAgICBkb2MgPSBidWlsZGVyLnBhcnNlKHVybC5vcGVuU3RyZWFtKCkpOworICAgICAgICAgICAgcGFyc2VFeGNlcHRpb24gPSBlcnJvckhhbmRsZXIuZ2V0Rmlyc3RFeGNlcHRpb24oKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBwYXJzZUV4Y2VwdGlvbiA9IGV4OworICAgICAgICB9CisgICAgICAgIGJ1aWxkZXIuc2V0RXJyb3JIYW5kbGVyKG51bGwpOworICAgICAgICBpZiAocGFyc2VFeGNlcHRpb24gIT0gbnVsbCkgeworICAgICAgICAgICAgLy8gZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIHBhcnNlRXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIHBhcnNlRXhjZXB0aW9uLmdldE1lc3NhZ2UoKSwgcGFyc2VFeGNlcHRpb24pOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkb2M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcHJlbG9hZChTdHJpbmcgY29udGVudFR5cGUsIFN0cmluZyBkb2NVUkksCisgICAgICAgICAgICBib29sZWFuIHdpbGxCZU1vZGlmaWVkKSB7CisgICAgICAgIGlmICgidGV4dC9odG1sIi5lcXVhbHMoY29udGVudFR5cGUpCisgICAgICAgICAgICAgICAgfHwgImFwcGxpY2F0aW9uL3hodG1sK3htbCIuZXF1YWxzKGNvbnRlbnRUeXBlKSkgeworICAgICAgICAgICAgaWYgKGRvY1VSSS5zdGFydHNXaXRoKCJzdGFmZiIpCisgICAgICAgICAgICAgICAgICAgIHx8IGRvY1VSSS5lcXVhbHMoImRhdGF0eXBlX25vcm1hbGl6YXRpb24iKSkgeworCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIFVSTCByZXNvbHZlVVJJKFN0cmluZyBiYXNlVVJJKSB7CisgICAgICAgIFN0cmluZyBkb2NVUkkgPSBiYXNlVVJJICsgIi54bWwiOworCisgICAgICAgIFVSTCByZXNvbHZlZFVSSSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXNvbHZlZFVSSSA9IG5ldyBVUkwoZG9jVVJJKTsKKyAgICAgICAgICAgIGlmIChyZXNvbHZlZFVSSS5nZXRQcm90b2NvbCgpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZWRVUkk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgLy8gZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgLy8KKyAgICAgICAgLy8gYnVpbGQgYSBVUkwgZm9yIGEgdGVzdCBmaWxlIGluIHRoZSBKQVIKKyAgICAgICAgLy8KKyAgICAgICAgcmVzb2x2ZWRVUkkgPSBnZXRDbGFzcygpLmdldFJlc291cmNlKCIvIiArIGRvY1VSSSk7CisgICAgICAgIGlmIChyZXNvbHZlZFVSSSA9PSBudWxsKSB7CisgICAgICAgICAgICAvLworICAgICAgICAgICAgLy8gc2VlIGlmIGl0IGlzIGFuIGFic29sdXRlIFVSSQorICAgICAgICAgICAgLy8KKyAgICAgICAgICAgIGludCBmaXJzdFNsYXNoID0gZG9jVVJJLmluZGV4T2YoJy8nKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKGZpcnN0U2xhc2ggPT0gMAorICAgICAgICAgICAgICAgICAgICAgICAgfHwgKGZpcnN0U2xhc2ggPj0gMSAmJiBkb2NVUkkuY2hhckF0KGZpcnN0U2xhc2ggLSAxKSA9PSAnOicpKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc29sdmVkVVJJID0gbmV3IFVSTChkb2NVUkkpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIC8vCisgICAgICAgICAgICAgICAgICAgIC8vIHRyeSB0aGUgZmlsZXMvbGV2ZWw/L3NwZWMgZGlyZWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC8vCisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBmaWxlbmFtZSA9IGdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUgPSAidGVzdHMvIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZmlsZW5hbWUuc3Vic3RyaW5nKDE0KS5yZXBsYWNlKCcuJywgJy8nKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIi9maWxlcy8iICsgZG9jVVJJOworICAgICAgICAgICAgICAgICAgICByZXNvbHZlZFVSSSA9IG5ldyBqYXZhLmlvLkZpbGUoZmlsZW5hbWUpLnRvVVJMKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAocmVzb2x2ZWRVUkkgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbCgicmVzb2x2ZWRVUkkgaXMgbnVsbCAiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzb2x2ZWRVUkk7CisgICAgfQorCisKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgeworICAgICAgICByZXR1cm4gInhtbCI7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYXNzZXJ0VVJJRXF1YWxzKFN0cmluZyBhc3NlcnRJRCwgU3RyaW5nIHNjaGVtZSwgU3RyaW5nIHBhdGgsCisgICAgICAgICAgICBTdHJpbmcgaG9zdCwgU3RyaW5nIGZpbGUsIFN0cmluZyBuYW1lLCBTdHJpbmcgcXVlcnksCisgICAgICAgICAgICBTdHJpbmcgZnJhZ21lbnQsIEJvb2xlYW4gaXNBYnNvbHV0ZSwgU3RyaW5nIGFjdHVhbCkgeworICAgICAgICAvLworICAgICAgICAvLyBVUkkgbXVzdCBiZSBub24tbnVsbAorICAgICAgICBhc3NlcnROb3ROdWxsKGFzc2VydElELCBhY3R1YWwpOworCisgICAgICAgIFN0cmluZyB1cmkgPSBhY3R1YWw7CisKKyAgICAgICAgaW50IGxhc3RQb3VuZCA9IGFjdHVhbC5sYXN0SW5kZXhPZigiIyIpOworICAgICAgICBTdHJpbmcgYWN0dWFsRnJhZ21lbnQgPSAiIjsKKyAgICAgICAgaWYgKGxhc3RQb3VuZCAhPSAtMSkgeworICAgICAgICAgICAgLy8KKyAgICAgICAgICAgIC8vIHN1YnN0cmluZyBiZWZvcmUgcG91bmQKKyAgICAgICAgICAgIC8vCisgICAgICAgICAgICB1cmkgPSBhY3R1YWwuc3Vic3RyaW5nKDAsIGxhc3RQb3VuZCk7CisgICAgICAgICAgICBhY3R1YWxGcmFnbWVudCA9IGFjdHVhbC5zdWJzdHJpbmcobGFzdFBvdW5kICsgMSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGZyYWdtZW50ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhhc3NlcnRJRCwgZnJhZ21lbnQsIGFjdHVhbEZyYWdtZW50KTsKKworICAgICAgICB9CisgICAgICAgIGludCBsYXN0UXVlc3Rpb24gPSB1cmkubGFzdEluZGV4T2YoIj8iKTsKKyAgICAgICAgU3RyaW5nIGFjdHVhbFF1ZXJ5ID0gIiI7CisgICAgICAgIGlmIChsYXN0UXVlc3Rpb24gIT0gLTEpIHsKKyAgICAgICAgICAgIC8vCisgICAgICAgICAgICAvLyBzdWJzdHJpbmcgYmVmb3JlIHBvdW5kCisgICAgICAgICAgICAvLworICAgICAgICAgICAgdXJpID0gYWN0dWFsLnN1YnN0cmluZygwLCBsYXN0UXVlc3Rpb24pOworICAgICAgICAgICAgYWN0dWFsUXVlcnkgPSBhY3R1YWwuc3Vic3RyaW5nKGxhc3RRdWVzdGlvbiArIDEpOworICAgICAgICB9CisgICAgICAgIGlmIChxdWVyeSAhPSBudWxsKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYXNzZXJ0SUQsIHF1ZXJ5LCBhY3R1YWxRdWVyeSk7CisKKyAgICAgICAgfQorICAgICAgICBpbnQgZmlyc3RDb2xvbiA9IHVyaS5pbmRleE9mKCI6Iik7CisgICAgICAgIGludCBmaXJzdFNsYXNoID0gdXJpLmluZGV4T2YoIi8iKTsKKyAgICAgICAgU3RyaW5nIGFjdHVhbFBhdGggPSB1cmk7CisgICAgICAgIFN0cmluZyBhY3R1YWxTY2hlbWUgPSAiIjsKKyAgICAgICAgaWYgKGZpcnN0Q29sb24gIT0gLTEgJiYgZmlyc3RDb2xvbiA8IGZpcnN0U2xhc2gpIHsKKyAgICAgICAgICAgIGFjdHVhbFNjaGVtZSA9IHVyaS5zdWJzdHJpbmcoMCwgZmlyc3RDb2xvbik7CisgICAgICAgICAgICBhY3R1YWxQYXRoID0gdXJpLnN1YnN0cmluZyhmaXJzdENvbG9uICsgMSk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc2NoZW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhhc3NlcnRJRCwgc2NoZW1lLCBhY3R1YWxTY2hlbWUpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHBhdGggIT0gbnVsbCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFzc2VydElELCBwYXRoLCBhY3R1YWxQYXRoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChob3N0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN0cmluZyBhY3R1YWxIb3N0ID0gIiI7CisgICAgICAgICAgICBpZiAoYWN0dWFsUGF0aC5zdGFydHNXaXRoKCIvLyIpKSB7CisgICAgICAgICAgICAgICAgaW50IHRlcm1TbGFzaCA9IGFjdHVhbFBhdGguaW5kZXhPZigiLyIsIDIpOworICAgICAgICAgICAgICAgIGFjdHVhbEhvc3QgPSBhY3R1YWxQYXRoLnN1YnN0cmluZygwLCB0ZXJtU2xhc2gpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFzc2VydElELCBob3N0LCBhY3R1YWxIb3N0KTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBhY3R1YWxGaWxlID0gYWN0dWFsUGF0aDsKKyAgICAgICAgaWYgKGZpbGUgIT0gbnVsbCB8fCBuYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIGludCBmaW5hbFNsYXNoID0gYWN0dWFsUGF0aC5sYXN0SW5kZXhPZigiLyIpOworICAgICAgICAgICAgaWYgKGZpbmFsU2xhc2ggIT0gLTEpIHsKKyAgICAgICAgICAgICAgICBhY3R1YWxGaWxlID0gYWN0dWFsUGF0aC5zdWJzdHJpbmcoZmluYWxTbGFzaCArIDEpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGZpbGUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhhc3NlcnRJRCwgZmlsZSwgYWN0dWFsRmlsZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAobmFtZSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgYWN0dWFsTmFtZSA9IGFjdHVhbEZpbGU7CisgICAgICAgICAgICBpbnQgZmluYWxQZXJpb2QgPSBhY3R1YWxGaWxlLmxhc3RJbmRleE9mKCIuIik7CisgICAgICAgICAgICBpZiAoZmluYWxQZXJpb2QgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICBhY3R1YWxOYW1lID0gYWN0dWFsRmlsZS5zdWJzdHJpbmcoMCwgZmluYWxQZXJpb2QpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFzc2VydElELCBuYW1lLCBhY3R1YWxOYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChpc0Fic29sdXRlICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vCisgICAgICAgICAgICAvLyBKYXIgVVJMJ3Mgd2lsbCBoYXZlIGFueSBhY3R1YWwgcGF0aCBsaWtlIGZpbGU6L2M6L3NvbWVkcml2ZS4uLgorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGFzc2VydElELCBpc0Fic29sdXRlLmJvb2xlYW5WYWx1ZSgpLCBhY3R1YWxQYXRoCisgICAgICAgICAgICAgICAgICAgIC5zdGFydHNXaXRoKCIvIikKKyAgICAgICAgICAgICAgICAgICAgfHwgYWN0dWFsUGF0aC5zdGFydHNXaXRoKCJmaWxlOi8iKSk7CisgICAgICAgIH0KKyAgICB9CisKKworICAgIHByaXZhdGUgY2xhc3MgTG9hZEVycm9ySGFuZGxlciBpbXBsZW1lbnRzIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciB7CisgICAgICAgIHByaXZhdGUgU0FYRXhjZXB0aW9uIHBhcnNlRXhjZXB0aW9uOworCisgICAgICAgIHByaXZhdGUgaW50IGVycm9yQ291bnQ7CisKKyAgICAgICAgcHJpdmF0ZSBpbnQgd2FybmluZ0NvdW50OworCisgICAgICAgIHB1YmxpYyBMb2FkRXJyb3JIYW5kbGVyKCkgeworICAgICAgICAgICAgcGFyc2VFeGNlcHRpb24gPSBudWxsOworICAgICAgICAgICAgZXJyb3JDb3VudCA9IDA7CisgICAgICAgICAgICB3YXJuaW5nQ291bnQgPSAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgZXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGVycm9yQ291bnQrKzsKKyAgICAgICAgICAgIGlmIChwYXJzZUV4Y2VwdGlvbiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcGFyc2VFeGNlcHRpb24gPSBleDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoU0FYUGFyc2VFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHdhcm5pbmdDb3VudCsrOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgZmF0YWxFcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgaWYgKHBhcnNlRXhjZXB0aW9uID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBwYXJzZUV4Y2VwdGlvbiA9IGV4OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFNBWEV4Y2VwdGlvbiBnZXRGaXJzdEV4Y2VwdGlvbigpIHsKKyAgICAgICAgICAgIHJldHVybiBwYXJzZUV4Y2VwdGlvbjsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Eb2N1bWVudEJ1aWxkZXJTZXR0aW5nLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJiYjcxOTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRG9jdW1lbnRCdWlsZGVyU2V0dGluZy5qYXZhCkBAIC0wLDAgKzEsMjgxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlCisgKiBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuCisgKiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMKKyAqIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZCisgKiBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTCisgKiBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZQorICogaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKyAqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIGFuIHBhcnNlciBzZXR0aW5nLCBzdWNoIGFzIG5vbi12YWxpZGF0aW5nIG9yIGVudGl0eS1leHBhbmRpbmcuCisgKgorICogQGF1dGhvciBDdXJ0IEFybm9sZCBAZGF0ZSAyIEZlYiAyMDAyCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIHsKKyAgLyoqCisgICAqIHByb3BlcnR5IG5hbWUuCisgICAqLworICBwcml2YXRlIGZpbmFsIFN0cmluZyBwcm9wZXJ0eTsKKworICAvKioKKyAgICogICBwcm9wZXJ0eSB2YWx1ZS4KKyAgICovCisgIHByaXZhdGUgZmluYWwgYm9vbGVhbiB2YWx1ZTsKKworICAvKioKKyAgICogc3RyYXRlZ3kgdXNlZCB0byBzZXQgb3IgZ2V0IHByb3BlcnR5IHZhbHVlLgorICAgKi8KKyAgcHJpdmF0ZSBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kgc3RyYXRlZ3k7CisKKyAgLyoqCisgICAqIGNvYWxlc2NpbmcgPSB0cnVlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIGNvYWxlc2NpbmcgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICAiY29hbGVzY2luZyIsCisgICAgICB0cnVlLAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5LmNvYWxlc2NpbmcpOworCisgIC8qKgorICAgKiBjb2FsZXNjaW5nID0gZmFsc2UuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmcgbm90Q29hbGVzY2luZyA9CisgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZygKKyAgICAgICJjb2FsZXNjaW5nIiwKKyAgICAgIGZhbHNlLAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5LmNvYWxlc2NpbmcpOworCisgIC8qKgorICAgKiBleHBhbmRFbnRpdHlSZWZlcmVuY2VzID0gZmFsc2UuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmcgZXhwYW5kRW50aXR5UmVmZXJlbmNlcyA9CisgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZygKKyAgICAgICJleHBhbmRFbnRpdHlSZWZlcmVuY2VzIiwKKyAgICAgIHRydWUsCisgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kuZXhwYW5kRW50aXR5UmVmZXJlbmNlcyk7CisKKyAgLyoqCisgICAqIGV4cGFuZEVudGl0eVJlZmVyZW5jZXMgPSB0cnVlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIG5vdEV4cGFuZEVudGl0eVJlZmVyZW5jZXMgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICAiZXhwYW5kRW50aXR5UmVmZXJlbmNlcyIsCisgICAgICBmYWxzZSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneS5leHBhbmRFbnRpdHlSZWZlcmVuY2VzKTsKKworICAvKioKKyAgICogaWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UgPSB0cnVlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIGlnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlID0KKyAgICAgIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nKAorICAgICAgImlnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlIiwKKyAgICAgIHRydWUsCisgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kuaWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UpOworCisgIC8qKgorICAgKiBpZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSA9IGZhbHNlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nCisgICAgICBub3RJZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSA9CisgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZygKKyAgICAgICJpZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSIsCisgICAgICBmYWxzZSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneS5pZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSk7CisKKyAgLyoqCisgICAqIG5hbWVzcGFjZUF3YXJlID0gdHJ1ZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZyBuYW1lc3BhY2VBd2FyZSA9CisgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZygKKyAgICAgICJuYW1lc3BhY2VBd2FyZSIsCisgICAgICB0cnVlLAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5Lm5hbWVzcGFjZUF3YXJlKTsKKworICAvKioKKyAgICogbmFtZXNwYWNlQXdhcmUgPSBmYWxzZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZyBub3ROYW1lc3BhY2VBd2FyZSA9CisgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZygKKyAgICAgICJuYW1lc3BhY2VBd2FyZSIsCisgICAgICBmYWxzZSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneS5uYW1lc3BhY2VBd2FyZSk7CisKKyAgLyoqCisgICAqIHZhbGlkYXRpbmcgPSB0cnVlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIHZhbGlkYXRpbmcgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICAidmFsaWRhdGluZyIsCisgICAgICB0cnVlLAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5LnZhbGlkYXRpbmcpOworCisgIC8qKgorICAgKiB2YWxpZGF0aW5nID0gZmFsc2UuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmcgbm90VmFsaWRhdGluZyA9CisgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZygKKyAgICAgICJ2YWxpZGF0aW5nIiwKKyAgICAgIGZhbHNlLAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5LnZhbGlkYXRpbmcpOworCisgIC8qKgorICAgKiBzaWduZWQgPSB0cnVlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIHNpZ25lZCA9CisgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZygKKyAgICAgICJzaWduZWQiLAorICAgICAgdHJ1ZSwKKyAgICAgIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneS5zaWduZWQpOworCisgIC8qKgorICAgKiBzaWduZWQgPSBmYWxzZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZyBub3RTaWduZWQgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICAic2lnbmVkIiwKKyAgICAgIGZhbHNlLAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5LnNpZ25lZCk7CisKKyAgLyoqCisgICAqIGhhc051bGxTdHJpbmcgPSB0cnVlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIGhhc051bGxTdHJpbmcgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICAiaGFzTnVsbFN0cmluZyIsCisgICAgICB0cnVlLAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5Lmhhc051bGxTdHJpbmcpOworCisgIC8qKgorICAgKiBoYXNOdWxsU3RyaW5nID0gZmFsc2UuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmcgbm90SGFzTnVsbFN0cmluZyA9CisgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZygKKyAgICAgICJoYXNOdWxsU3RyaW5nIiwKKyAgICAgIGZhbHNlLAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5Lmhhc051bGxTdHJpbmcpOworCisgIC8qKgorICAgKiBTY2hlbWEgdmFsaWRhdGluZyBlbmFibGVkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nIHNjaGVtYVZhbGlkYXRpbmcgPQorICAgICAgbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICAic2NoZW1hVmFsaWRhdGluZyIsCisgICAgICB0cnVlLAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5LnNjaGVtYVZhbGlkYXRpbmcpOworCisgIC8qKgorICAgKiBTY2hlbWEgdmFsaWRhdGluZyBkaXNhYmxlZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZyBub3RTY2hlbWFWYWxpZGF0aW5nID0KKyAgICAgIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nKAorICAgICAgInNjaGVtYVZhbGlkYXRpbmciLAorICAgICAgZmFsc2UsCisgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kuc2NoZW1hVmFsaWRhdGluZyk7CisKKyAgLyoqCisgICAqIENvbW1lbnRzIGlnbm9yZWQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmcgaWdub3JpbmdDb21tZW50cyA9CisgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZygKKyAgICAgICJpZ25vcmluZ0NvbW1lbnRzIiwKKyAgICAgIHRydWUsCisgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kuaWdub3JpbmdDb21tZW50cyk7CisKKyAgLyoqCisgICAqIENvbW1lbnRzIHByZXNlcnZlZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZyBub3RJZ25vcmluZ0NvbW1lbnRzID0KKyAgICAgIG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nKAorICAgICAgImlnbm9yaW5nQ29tbWVudHMiLAorICAgICAgZmFsc2UsCisgICAgICBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kuaWdub3JpbmdDb21tZW50cyk7CisKKyAgLyoqCisgICAqIFByb3RlY3RlZCBjb25zdHJ1Y3RvciwgdXNlIHN0YXRpYyBtZW1iZXJzIGZvciBzdXBwb3J0ZWQgc2V0dGluZ3MuCisgICAqIEBwYXJhbSBwcm9wZXJ0eSBwcm9wZXJ0eSBuYW1lLCBmb2xsb3dzIEpBWFAuCisgICAqIEBwYXJhbSB2YWx1ZSBwcm9wZXJ0eSB2YWx1ZQorICAgKiBAcGFyYW0gc3RyYXRlZ3kgc3RyYXRlZ3ksIG1heSBub3QgYmUgbnVsbAorICAgKi8KKyAgcHJvdGVjdGVkIERvY3VtZW50QnVpbGRlclNldHRpbmcoCisgICAgICBTdHJpbmcgcHJvcGVydHksCisgICAgICBib29sZWFuIHZhbHVlLAorICAgICAgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5IHN0cmF0ZWd5KSB7CisgICAgaWYgKHByb3BlcnR5ID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicHJvcGVydHkiKTsKKyAgICB9CisgICAgdGhpcy5wcm9wZXJ0eSA9IHByb3BlcnR5OworICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICB0aGlzLnN0cmF0ZWd5ID0gc3RyYXRlZ3k7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzZXR0aW5ncyBoYXZlIGEgY29uZmxpY3Qgb3IgYXJlIGlkZW50aWNhbC4KKyAgICoKKyAgICogQHBhcmFtIG90aGVyCisgICAqICAgICAgICAgICAgb3RoZXIgc2V0dGluZywgbWF5IG5vdCBiZSBudWxsLgorICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBzZXR0aW5nIGFuZCB0aGUgc3BlY2lmaWVkIHNldHRpbmcgY29uZmxpY3QKKyAgICovCisgIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc0NvbmZsaWN0KERvY3VtZW50QnVpbGRlclNldHRpbmcgb3RoZXIpIHsKKyAgICBpZiAob3RoZXIgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJvdGhlciIpOworICAgIH0KKyAgICBpZiAob3RoZXIgPT0gdGhpcykgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIHJldHVybiBzdHJhdGVneS5oYXNDb25mbGljdChvdGhlci5zdHJhdGVneSk7CisgIH0KKworICAvKioKKyAgICogRGV0ZXJtaW5lcyBjdXJyZW50IHZhbHVlIG9mIHNldHRpbmcuCisgICAqIEBwYXJhbSBmYWN0b3J5IERPTVRlc3REb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkKKyAgICogQHJldHVybiBib29sZWFuIHRydWUgaWYgcHJvcGVydHkgZW5hYmxlZC4KKyAgICovCisgIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc1NldHRpbmcoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSB7CisgICAgcmV0dXJuIHN0cmF0ZWd5Lmhhc1NldHRpbmcoZmFjdG9yeSkgPT0gdmFsdWU7CisgfQorCisgIC8qKgorICAgKiBBdHRlbXB0cyB0byBjaGFuZ2UgYnVpbGRlciB0byBoYXZlIHRoaXMgc2V0dGluZy4KKyAgICogQHBhcmFtIGZhY3RvcnkgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBGYWN0b3J5IGZvciBET00gYnVpbGRlcnMKKyAgICogQHRocm93cyBET01UZXN0SW5jb21wYXRpYmxlRXhjZXB0aW9uCisgICAqICAgICAgaWYgZmFjdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHRoZSBzZXR0aW5nCisgICAqLworICBwdWJsaWMgZmluYWwgdm9pZCBhcHBseVNldHRpbmcoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSAgeworICAgIHN0cmF0ZWd5LmFwcGx5U2V0dGluZyhmYWN0b3J5LCB2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogR2V0cyB0aGUgcHJvcGVydHkgbmFtZS4KKyAgICogQHJldHVybiBwcm9wZXJ0eSBuYW1lCisgICAqLworICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldFByb3BlcnR5KCkgeworICAgIHJldHVybiBwcm9wZXJ0eTsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIHRoZSBwcm9wZXJ0eSB2YWx1ZS4KKyAgICogQHJldHVybiBwcm9wZXJ0eSB2YWx1ZQorICAgKi8KKyAgcHVibGljIGZpbmFsIGJvb2xlYW4gZ2V0VmFsdWUoKSB7CisgICAgcmV0dXJuIHZhbHVlOworICB9CisKKyAgLyoqCisgICAqIEdldHMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNldHRpbmcuCisgICAqIEByZXR1cm4gc3RyaW5nIHJlcHJlc2VudGF0aW9uCisgICAqLworICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIFN0cmluZ0J1ZmZlciBidWlsZGVyID0gbmV3IFN0cmluZ0J1ZmZlcihwcm9wZXJ0eSk7CisgICAgYnVpbGRlci5hcHBlbmQoJz0nKTsKKyAgICBidWlsZGVyLmFwcGVuZChTdHJpbmcudmFsdWVPZih2YWx1ZSkpOworICAgIHJldHVybiBidWlsZGVyLnRvU3RyaW5nKCk7CisgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0RvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0RvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc3YmJjZTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5LmphdmEKQEAgLTAsMCArMSwxNTggQEAKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5IHsKKyAgICBwcm90ZWN0ZWQgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5KCkgeworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBKQVhQX1NDSEVNQV9MQU5HVUFHRSA9ICJodHRwOi8vamF2YS5zdW4uY29tL3htbC9qYXhwL3Byb3BlcnRpZXMvc2NoZW1hTGFuZ3VhZ2UiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFczQ19YTUxfU0NIRU1BID0gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIjsKKworICAgIHB1YmxpYyBib29sZWFuIGhhc0NvbmZsaWN0KERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneSBvdGhlcikgeworICAgICAgICByZXR1cm4gKG90aGVyID09IHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGFwcGx5U2V0dGluZyhEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnksCisgICAgICAgICAgICBib29sZWFuIHZhbHVlKTsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGhhc1NldHRpbmcoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5IGNvYWxlc2NpbmcgPSBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5KCkgeworICAgICAgICBwdWJsaWMgdm9pZCBhcHBseVNldHRpbmcoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5LAorICAgICAgICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgICAgICAgIGZhY3Rvcnkuc2V0Q29hbGVzY2luZyh2YWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTZXR0aW5nKERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgeworICAgICAgICAgICAgcmV0dXJuIGZhY3RvcnkuaXNDb2FsZXNjaW5nKCk7CisgICAgICAgIH0KKworICAgIH07CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneSBleHBhbmRFbnRpdHlSZWZlcmVuY2VzID0gbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneSgpIHsKKyAgICAgICAgcHVibGljIHZvaWQgYXBwbHlTZXR0aW5nKERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSwgYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICAgICAgZmFjdG9yeS5zZXRFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKHZhbHVlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc1NldHRpbmcoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSB7CisgICAgICAgICAgICByZXR1cm4gZmFjdG9yeS5pc0V4cGFuZEVudGl0eVJlZmVyZW5jZXMoKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneSBpZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSA9IG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3koKSB7CisgICAgICAgIHB1YmxpYyB2b2lkIGFwcGx5U2V0dGluZyhEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnksIGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgICAgICAgIGZhY3Rvcnkuc2V0SWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UodmFsdWUpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzU2V0dGluZyhET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWN0b3J5LmlzSWdub3JpbmdFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneSBpZ25vcmluZ0NvbW1lbnRzID0gbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneSgpIHsKKyAgICAgICAgcHVibGljIHZvaWQgYXBwbHlTZXR0aW5nKERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSwgYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICAgICAgaWYgKHZhbHVlKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJpZ25vcmVDb21tZW50cz10cnVlIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc1NldHRpbmcoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5KSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kgbmFtZXNwYWNlQXdhcmUgPSBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5KCkgeworICAgICAgICBwdWJsaWMgdm9pZCBhcHBseVNldHRpbmcoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5LCBib29sZWFuIHZhbHVlKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgIGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodmFsdWUpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzU2V0dGluZyhET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWN0b3J5LmlzTmFtZXNwYWNlQXdhcmUoKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneSB2YWxpZGF0aW5nID0gbmV3IERvY3VtZW50QnVpbGRlclNldHRpbmdTdHJhdGVneSgpIHsKKyAgICAgICAgcHVibGljIHZvaWQgYXBwbHlTZXR0aW5nKERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSwgYm9vbGVhbiB2YWx1ZSkKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICBmYWN0b3J5LnNldFZhbGlkYXRpbmcodmFsdWUpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzU2V0dGluZyhET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWN0b3J5LmlzVmFsaWRhdGluZygpOworICAgICAgICB9CisgICAgfTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5IHNpZ25lZCA9IG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3koKSB7CisgICAgICAgIHB1YmxpYyB2b2lkIGFwcGx5U2V0dGluZyhEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnksIGJvb2xlYW4gdmFsdWUpCisgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRvY3VtZW50QnVpbGRlclNldHRpbmcubm90U2lnbmVkIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTZXR0aW5nKERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICB9OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kgaGFzTnVsbFN0cmluZyA9IG5ldyBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3koKSB7CisgICAgICAgIHB1YmxpYyB2b2lkIGFwcGx5U2V0dGluZyhEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnksIGJvb2xlYW4gdmFsdWUpCisgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRvY3VtZW50QnVpbGRlclNldHRpbmcubm90SGFzTnVsbFN0cmluZyIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzU2V0dGluZyhET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgfTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5IHNjaGVtYVZhbGlkYXRpbmcgPSBuZXcgRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5KCkgeworICAgICAgICBwdWJsaWMgdm9pZCBhcHBseVNldHRpbmcoRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5LCBib29sZWFuIHZhbHVlKQorICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICBpZiAodmFsdWUpIHsKKyAgICAgICAgICAgICAgICBmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOworICAgICAgICAgICAgICAgIGZhY3Rvcnkuc2V0VmFsaWRhdGluZyh0cnVlKTsKKyAgICAgICAgICAgICAgICBmYWN0b3J5LnNldEF0dHJpYnV0ZShKQVhQX1NDSEVNQV9MQU5HVUFHRSwgVzNDX1hNTF9TQ0hFTUEpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmYWN0b3J5LnNldEF0dHJpYnV0ZShKQVhQX1NDSEVNQV9MQU5HVUFHRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTZXR0aW5nKERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAoZmFjdG9yeS5pc1ZhbGlkYXRpbmcoKSkgeworICAgICAgICAgICAgICAgICAgICBNZXRob2QgZ2V0QXR0ck1ldGhvZCA9IGZhY3RvcnkuZ2V0Q2xhc3MoKS5nZXRNZXRob2QoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdldEF0dHJpYnV0ZSIsIG5ldyBDbGFzc1tdIHsgU3RyaW5nLmNsYXNzIH0pOworICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsID0gKFN0cmluZykgZ2V0QXR0ck1ldGhvZC5pbnZva2UoZmFjdG9yeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBKQVhQX1NDSEVNQV9MQU5HVUFHRSB9KTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFczQ19YTUxfU0NIRU1BLmVxdWFscyh2YWwpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLy8KKyAgICAgICAgLy8gc2NoZW1hIHZhbGlkYXRpbmcgY29uZmxpY3RzIHdpdGggbmFtZXNwYWNlQXdhcmUKKyAgICAgICAgLy8gYW5kIHZhbGlkYXRpbmcKKyAgICAgICAgLy8KKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzQ29uZmxpY3QoRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5IG90aGVyKSB7CisgICAgICAgICAgICBpZiAob3RoZXIgPT0gdGhpcworICAgICAgICAgICAgICAgICAgICB8fCBvdGhlciA9PSBEb2N1bWVudEJ1aWxkZXJTZXR0aW5nU3RyYXRlZ3kubmFtZXNwYWNlQXdhcmUKKyAgICAgICAgICAgICAgICAgICAgfHwgb3RoZXIgPT0gRG9jdW1lbnRCdWlsZGVyU2V0dGluZ1N0cmF0ZWd5LnZhbGlkYXRpbmcpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgfTsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0RvY3VtZW50Q3JlYXRlQXR0cmlidXRlTlMuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Eb2N1bWVudENyZWF0ZUF0dHJpYnV0ZU5TLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDBkNTI4NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Eb2N1bWVudENyZWF0ZUF0dHJpYnV0ZU5TLmphdmEKQEAgLTAsMCArMSwyNjcgQEAKKy8qCisgVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorIGFuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCisgVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisgQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbAorIFJpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorIFBVUlBPU0UuCisKKyBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisgKi8KKworcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5BdHRyOworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogVGhlIG1ldGhvZCBjcmVhdGVBdHRyaWJ1dGVOUyBjcmVhdGVzIGFuIGF0dHJpYnV0ZSBvZiB0aGUgZ2l2ZW4gcXVhbGlmaWVkIG5hbWUKKyAqIGFuZCBuYW1lc3BhY2UgVVJJCisgKgorICogSW52b2tlIHRoZSBjcmVhdGVBdHRyaWJ1dGVOUyBtZXRob2Qgb24gdGhpcyBEb2N1bWVudCBvYmplY3Qgd2l0aCBhIG51bGwKKyAqIG5hbWVzcGFjZVVSSSwgYW5kIGEgcXVhbGlmaWVkTmFtZSB3aXRob3V0IGEgcHJlZml4LiBUaGlzIHNob3VsZCByZXR1cm4gYQorICogdmFsaWQgQXR0ciBub2RlIG9iamVjdC4KKyAqCisgKiBAYXV0aG9yIElCTQorICogQGF1dGhvciBOZWlsIERlbGltYQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZTwvYT4KKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyQXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRG9jQ3JBdHRyTlM8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBEb2N1bWVudENyZWF0ZUF0dHJpYnV0ZU5TIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24xKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZUF0dHJpYnV0ZU5TMSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gbnVsbDsKKworICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJ0ZXN0IjsKKworICAgICAgICBTdHJpbmcgbm9kZU5hbWU7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGF0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgICBub2RlTmFtZSA9IGF0dHJpYnV0ZS5nZXROb2RlTmFtZSgpOworCisgICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzAxIiwgInRlc3QiLCBub2RlTmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q3JlYXRlQXR0cmlidXRlTlMyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgQXR0ciBhdHRyaWJ1dGUxOworICAgICAgICBBdHRyIGF0dHJpYnV0ZTI7CisgICAgICAgIFN0cmluZyBuYW1lOworICAgICAgICBTdHJpbmcgbm9kZU5hbWU7CisgICAgICAgIFN0cmluZyBub2RlVmFsdWU7CisgICAgICAgIFN0cmluZyBwcmVmaXg7CisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkk7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBhdHRyaWJ1dGUxID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKAorICAgICAgICAgICAgICAgICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiLCAieG1sOnhtbCIpOworICAgICAgICBuYW1lID0gYXR0cmlidXRlMS5nZXROYW1lKCk7CisgICAgICAgIG5vZGVOYW1lID0gYXR0cmlidXRlMS5nZXROb2RlTmFtZSgpOworICAgICAgICBub2RlVmFsdWUgPSBhdHRyaWJ1dGUxLmdldE5vZGVWYWx1ZSgpOworICAgICAgICBwcmVmaXggPSBhdHRyaWJ1dGUxLmdldFByZWZpeCgpOworICAgICAgICBuYW1lc3BhY2VVUkkgPSBhdHRyaWJ1dGUxLmdldE5hbWVzcGFjZVVSSSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMl9hdHQxX25hbWUiLCAieG1sOnhtbCIsIG5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMl9hdHQxX25vZGVOYW1lIiwgInhtbDp4bWwiLAorICAgICAgICAgICAgICAgIG5vZGVOYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDJfYXR0MV9ub2RlVmFsdWUiLCAiIiwKKyAgICAgICAgICAgICAgICBub2RlVmFsdWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMl9hdHQxX3ByZWZpeCIsICJ4bWwiLCBwcmVmaXgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMl9hdHQxX25hbWVzcGFjZVVSSSIsCisgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIsIG5hbWVzcGFjZVVSSSk7CisgICAgICAgIGF0dHJpYnV0ZTIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIiwKKyAgICAgICAgICAgICAgICAieG1sbnMiKTsKKyAgICAgICAgbmFtZSA9IGF0dHJpYnV0ZTIuZ2V0TmFtZSgpOworICAgICAgICBub2RlTmFtZSA9IGF0dHJpYnV0ZTIuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgICAgbm9kZVZhbHVlID0gYXR0cmlidXRlMi5nZXROb2RlVmFsdWUoKTsKKyAgICAgICAgcHJlZml4ID0gYXR0cmlidXRlMi5nZXRQcmVmaXgoKTsKKyAgICAgICAgbmFtZXNwYWNlVVJJID0gYXR0cmlidXRlMi5nZXROYW1lc3BhY2VVUkkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDJfYXR0Ml9uYW1lIiwgInhtbG5zIiwgbmFtZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzAyX2F0dDJfbm9kZU5hbWUiLCAieG1sbnMiLAorICAgICAgICAgICAgICAgIG5vZGVOYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGNyZWF0ZWF0dHJpYnV0ZU5TMDJfYXR0Ml9ub2RlVmFsdWUiLCAiIiwKKyAgICAgICAgICAgICAgICBub2RlVmFsdWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Y3JlYXRlYXR0cmlidXRlTlMwMl9hdHQyX25hbWVzcGFjZVVSSSIsCisgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIiwgbmFtZXNwYWNlVVJJKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZUF0dHJpYnV0ZU5TMygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9MZXZlbDIiOworICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZTsKKyAgICAgICAgTGlzdDxTdHJpbmc+IHF1YWxpZmllZE5hbWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiLyIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIi8vIik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiXFwiKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCI7Iik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiJiIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIioiKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJdXSIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIj4iKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCI8Iik7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGZvciAoaW50IGluZGV4TjEwMDVBID0gMDsgaW5kZXhOMTAwNUEgPCBxdWFsaWZpZWROYW1lcy5zaXplKCk7IGluZGV4TjEwMDVBKyspIHsKKyAgICAgICAgICAgIHF1YWxpZmllZE5hbWUgPSAoU3RyaW5nKSBxdWFsaWZpZWROYW1lcy5nZXQoaW5kZXhOMTAwNUEpOworCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzAzIiwgc3VjY2Vzcyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZUF0dHJpYnV0ZU5TNCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9MZXZlbDIiOworICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZTsKKyAgICAgICAgTGlzdDxTdHJpbmc+IHF1YWxpZmllZE5hbWVzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiXzoiKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCI6MGEiKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCI6Iik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiYTpiOmMiKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJfOjphIik7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGZvciAoaW50IGluZGV4TjEwMDRFID0gMDsgaW5kZXhOMTAwNEUgPCBxdWFsaWZpZWROYW1lcy5zaXplKCk7IGluZGV4TjEwMDRFKyspIHsKKyAgICAgICAgICAgIHF1YWxpZmllZE5hbWUgPSAoU3RyaW5nKSBxdWFsaWZpZWROYW1lcy5nZXQoaW5kZXhOMTAwNEUpOworCisgICAgICAgICAgICB7CisKKyAgICAgICAgICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgICAgICAgICAvLyAgICAgT3VyIGV4Y2VwdGlvbiBwcmlvcml0aWVzIGRpZmZlciBmcm9tIHRoZSBzcGVjCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVBdHRyaWJ1dGVOUzUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBEb2N1bWVudCBuZXdEb2M7CisgICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlID0gbnVsbDsKKworICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworCisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSBudWxsOworCisgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gImFiYzpkZWYiOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgICBuZXdEb2MgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsCisgICAgICAgICAgICAgICAgImRvbTpkb2MiLCBkb2NUeXBlKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbmV3RG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA1Iiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZUF0dHJpYnV0ZU5TNigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIERvY3VtZW50IG5ld0RvYzsKKyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGUgPSBudWxsOworCisgICAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OCAvbmFtZXNwYWNlIjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAieG1sOnJvb3QiOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgICBuZXdEb2MgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsCisgICAgICAgICAgICAgICAgImRvbTpkb2MiLCBkb2NUeXBlKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbmV3RG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA2Iiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZUF0dHJpYnV0ZU5TNygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LlczLm9yZy8yMDAwL3htbG5zIjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAieG1sbnMiOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZG9jdW1lbnRjcmVhdGVhdHRyaWJ1dGVOUzA3Iiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRG9jdW1lbnRDcmVhdGVFbGVtZW50TlMuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Eb2N1bWVudENyZWF0ZUVsZW1lbnROUy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZjNjgzZjkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRG9jdW1lbnRDcmVhdGVFbGVtZW50TlMuamF2YQpAQCAtMCwwICsxLDEzOSBAQAorcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBUaGUgbWV0aG9kIGNyZWF0ZUVsZW1lbnROUyBjcmVhdGVzIGFuIGVsZW1lbnQgb2YgdGhlIGdpdmVuIHZhbGlkCisgKiBxdWFsaWZpZWROYW1lIGFuZCBOYW1lc3BhY2VVUkkuCisgKgorICogSW52b2tlIHRoZSBjcmVhdGVFbGVtZW50TlMgbWV0aG9kIG9uIHRoaXMgRG9jdW1lbnQgb2JqZWN0IHdpdGggYSB2YWxpZAorICogbmFtZXNwYWNlVVJJIGFuZCBxdWFsaWZpZWROYW1lLiBDaGVjayBpZiBhIHZhbGlkIEVsZW1lbnQgb2JqZWN0IGlzIHJldHVybmVkCisgKiB3aXRoIHRoZSBzYW1lIG5vZGUgYXR0cmlidXRlcy4KKyAqCisgKiBAYXV0aG9yIElCTQorICogQGF1dGhvciBOZWlsIERlbGltYQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZTwvYT4KKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyRWxOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELURvY0NyRWxOUzwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIERvY3VtZW50Q3JlYXRlRWxlbWVudE5TIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24xKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZUVsZW1lbnROUzEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvbGV2ZWwyIjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiWE1MOlhNTCI7CisgICAgICAgIFN0cmluZyBub2RlTmFtZTsKKyAgICAgICAgU3RyaW5nIG5zVVJJOworICAgICAgICBTdHJpbmcgbG9jYWxOYW1lOworICAgICAgICBTdHJpbmcgcHJlZml4OworICAgICAgICBTdHJpbmcgdGFnTmFtZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICAgIG5vZGVOYW1lID0gZWxlbWVudC5nZXROb2RlTmFtZSgpOworICAgICAgICBuc1VSSSA9IGVsZW1lbnQuZ2V0TmFtZXNwYWNlVVJJKCk7CisgICAgICAgIGxvY2FsTmFtZSA9IGVsZW1lbnQuZ2V0TG9jYWxOYW1lKCk7CisgICAgICAgIHByZWZpeCA9IGVsZW1lbnQuZ2V0UHJlZml4KCk7CisgICAgICAgIHRhZ05hbWUgPSBlbGVtZW50LmdldFRhZ05hbWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGNyZWF0ZWVsZW1lbnROUzAxX25vZGVOYW1lIiwgIlhNTDpYTUwiLCBub2RlTmFtZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwMV9uYW1lc3BhY2VVUkkiLAorICAgICAgICAgICAgICAgICJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9sZXZlbDIiLCBuc1VSSSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRjcmVhdGVlbGVtZW50TlMwMV9sb2NhbE5hbWUiLCAiWE1MIiwgbG9jYWxOYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGNyZWF0ZWVsZW1lbnROUzAxX3ByZWZpeCIsICJYTUwiLCBwcmVmaXgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Y3JlYXRlZWxlbWVudE5TMDFfdGFnTmFtZSIsICJYTUw6WE1MIiwgdGFnTmFtZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVFbGVtZW50TlMyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gbnVsbDsKKworICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJeXiI7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBkb2MuY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJkb2N1bWVudGNyZWF0ZWVsZW1lbnROUzAyIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZUVsZW1lbnROUzUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworCisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSBudWxsOworCisgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gIm51bGw6eG1sIjsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisKKyAgICAgICAgeworICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGRvYy5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJkb2N1bWVudGNyZWF0ZWVsZW1lbnROUzA1Iiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdENyZWF0ZUVsZW1lbnROUzYoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBEb2N1bWVudCBuZXdEb2M7CisgICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlID0gbnVsbDsKKworICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworCisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy53My5vcmcveG1sLzE5OTgvbmFtZXNwYWNlICI7CisgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gInhtbDpyb290IjsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgICAgbmV3RG9jID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudCgiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLAorICAgICAgICAgICAgICAgICJkb206ZG9jIiwgZG9jVHlwZSk7CisKKyAgICAgICAgeworICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG5ld0RvYy5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJkb2N1bWVudGNyZWF0ZWVsZW1lbnROUzA2Iiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRG9jdW1lbnRHZXRFbGVtZW50c0J5VGFnbmFtZU5TLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRG9jdW1lbnRHZXRFbGVtZW50c0J5VGFnbmFtZU5TLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDg4YzNlOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Eb2N1bWVudEdldEVsZW1lbnRzQnlUYWduYW1lTlMuamF2YQpAQCAtMCwwICsxLDExNCBAQAorcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSBtZXRob2QgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyByZXR1cm5zIGEgTm9kZUxpc3Qgb2YgYWxsIHRoZSBFbGVtZW50cyB3aXRoCisgKiBhIGdpdmVuIGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkgaW4gdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlCisgKiBlbmNvdW50ZXJlZCBpbiBhIHByZW9yZGVyIHRyYXZlcnNhbCBvZiB0aGUgRG9jdW1lbnQgdHJlZS4KKyAqCisgKiBJbnZva2UgdGhlIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMgbWV0aG9kIG9uIGEgbmV3IERvY3VtZW50IG9iamVjdCB3aXRoIHRoZQorICogdmFsdWVzIG9mIG5hbWVzcGFjZVVSST0qIGFuZCBsb2NhbE5hbWU9Ki4gVGhpcyBzaG91bGQgcmV0dXJuIGEgbm9kZUxpc3Qgb2YgMQorICogaXRlbS4KKyAqCisgKiBAYXV0aG9yIElCTQorICogQGF1dGhvciBOZWlsIERlbGltYQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZTwvYT4KKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQlROTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXRFbEJUTk5TPC9hPgorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5PC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRG9jdW1lbnRHZXRFbGVtZW50c0J5VGFnbmFtZU5TIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24yKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEVsZW1lbnRzQnlUYWdOYW1lTlMxKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRG9jdW1lbnQgbmV3RG9jOworICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZSA9IG51bGw7CisKKyAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgICBTdHJpbmcgbnVsbE5TID0gbnVsbDsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgICBuZXdEb2MgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KG51bGxOUywgInJvb3QiLCBkb2NUeXBlKTsKKyAgICAgICAgY2hpbGRMaXN0ID0gbmV3RG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiKiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzAxIiwgMSwgY2hpbGRMaXN0CisgICAgICAgICAgICAgICAgLmdldExlbmd0aCgpKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldEVsZW1lbnRzQnlUYWdOYW1lTlMyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRWxlbWVudCBkb2NFbGVtOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZG9jRWxlbSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoInRlc3QiLCAiZW1wbG95ZWVJZCIpOworICAgICAgICBkb2NFbGVtLmFwcGVuZENoaWxkKGVsZW1lbnQpOworICAgICAgICBjaGlsZExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJlbXBsb3llZUlkIik7CisgICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDIiLCA2LCBjaGlsZExpc3QKKyAgICAgICAgICAgICAgICAuZ2V0TGVuZ3RoKCkpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RWxlbWVudHNCeVRhZ05hbWVOUzMoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBjaGlsZExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKioiLCAiKiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzAzIiwgMCwgY2hpbGRMaXN0CisgICAgICAgICAgICAgICAgLmdldExlbmd0aCgpKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldEVsZW1lbnRzQnlUYWdOYW1lTlM0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgICBTdHJpbmcgbnVsbE5TID0gbnVsbDsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgY2hpbGRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMobnVsbE5TLCAiMCIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVOUzA0IiwgMCwgY2hpbGRMaXN0CisgICAgICAgICAgICAgICAgLmdldExlbmd0aCgpKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldEVsZW1lbnRzQnlUYWdOYW1lTlM1KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgY2hpbGRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIm51bGwiLCAiZWxlbWVudElkIik7CisgICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRnZXRlbGVtZW50c2J5dGFnbmFtZU5TMDUiLCAwLCBjaGlsZExpc3QKKyAgICAgICAgICAgICAgICAuZ2V0TGVuZ3RoKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Eb2N1bWVudEdldGVFZW1lbnRCeUlkLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRG9jdW1lbnRHZXRlRWVtZW50QnlJZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI0YjNmMGYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRG9jdW1lbnRHZXRlRWVtZW50QnlJZC5qYXZhCkBAIC0wLDAgKzEsNjAgQEAKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSBtZXRob2QgZ2V0RWxlbWVudEJ5SWQgcmV0dXJucyB0aGUgZWxlbWVudCB3aG9zZSBJRCBpcyBnaXZlbiBieSBlbGVtZW50SWQuCisgKiBJZiBub3Qgc3VjaCBlbGVtZW50IGV4aXN0cywgcmV0dXJucyBudWxsLgorICoKKyAqIEludm9rZSB0aGUgZ2V0RWxlbWVudEJ5SWQgbWV0aG9kIG9uIHRoaXMgRG9jdW1lbnQgb2JqZWN0IHdpdGggYW4gaW52YWxpZAorICogZWxlbWVudElkLiBUaGlzIHNob3VsZCByZXR1cm4gYSBudWxsIGVsZW1lbnQuCisgKgorICogQGF1dGhvciBJQk0KKyAqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXRFbEJJZCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQklkPC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRG9jdW1lbnRHZXRlRWVtZW50QnlJZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRFbGVtZW50QnlJZCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgU3RyaW5nIGVsZW1lbnRJZCA9ICItLS0iOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudCA9IGRvYy5nZXRFbGVtZW50QnlJZChlbGVtZW50SWQpOworICAgICAgICBhc3NlcnROdWxsKCJkb2N1bWVudGdldGVsZW1lbnRieWlkMDEiLCBlbGVtZW50KTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Eb2N1bWVudEltcG9ydE5vZGUuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Eb2N1bWVudEltcG9ydE5vZGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lODY0Zjk5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0RvY3VtZW50SW1wb3J0Tm9kZS5qYXZhCkBAIC0wLDAgKzEsNjE1IEBACitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLkF0dHI7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLlByb2Nlc3NpbmdJbnN0cnVjdGlvbjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBUaGUgaW1wb3J0Tm9kZSBtZXRob2QgaW1wb3J0cyBhIG5vZGUgZnJvbSBhbm90aGVyIGRvY3VtZW50IHRvIHRoaXMgZG9jdW1lbnQuCisgKiBUaGUgcmV0dXJuZWQgbm9kZSBoYXMgbm8gcGFyZW50OyAocGFyZW50Tm9kZSBpcyBudWxsKS4gVGhlIHNvdXJjZSBub2RlIGlzIG5vdAorICogYWx0ZXJlZCBvciByZW1vdmVkIGZyb20gdGhlIG9yaWdpbmFsIGRvY3VtZW50IGJ1dCBhIG5ldyBjb3B5IG9mIHRoZSBzb3VyY2UKKyAqIG5vZGUgaXMgY3JlYXRlZC4KKyAqCisgKiBVc2luZyB0aGUgbWV0aG9kIGltcG9ydE5vZGUgd2l0aCBkZWVwPXRydWUsIGltcG9ydCB0aGUgYXR0cmlidXRlLCAic3RyZWV0IiBvZgorICogdGhlIHNlY29uZCBlbGVtZW50IG5vZGUsIGZyb20gYSBsaXN0IG9mIG5vZGVzIHdob3NlIGxvY2FsIG5hbWVzIGFyZSAiYWRkcmVzcyIKKyAqIGFuZCBuYW1lc3BhY2VVUkkgImh0dHA6Ly93d3cubmlzdC5nb3YiIGludG8gdGhlIHNhbWUgZG9jdW1lbnQuIENoZWNrIHRoZQorICogcGFyZW50Tm9kZSwgbm9kZU5hbWUsIG5vZGVUeXBlIGFuZCBub2RlVmFsdWUgb2YgdGhlIGltcG9ydGVkIG5vZGUgdG8gdmVyaWZ5CisgKiBpZiBpdCBoYXMgYmVlbiBpbXBvcnRlZCBjb3JyZWN0bHkuCisgKgorICogQGF1dGhvciBJQk0KKyAqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmU8L2E+CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNDb3JlLURvY3VtZW50LWltcG9ydE5vZGU8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBEb2N1bWVudEltcG9ydE5vZGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKy8vIEFzc3VtZXMgdmFsaWRhdGlvbi4KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnROb2RlMSgpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisvLyAgICAgICAgQXR0ciBhdHRyOworLy8gICAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKy8vICAgICAgICBOb2RlIGltcG9ydGVkQXR0cjsKKy8vICAgICAgICBTdHJpbmcgbm9kZU5hbWU7CisvLyAgICAgICAgaW50IG5vZGVUeXBlOworLy8gICAgICAgIFN0cmluZyBub2RlVmFsdWU7CisvLyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisvLyAgICAgICAgY2hpbGRMaXN0ID0gZG9jCisvLyAgICAgICAgICAgICAgICAuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJhZGRyZXNzIik7CisvLyAgICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBjaGlsZExpc3QuaXRlbSgxKTsKKy8vICAgICAgICBhdHRyID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlKCJzdHJlZXQiKTsKKy8vICAgICAgICBpbXBvcnRlZEF0dHIgPSBkb2MuaW1wb3J0Tm9kZShhdHRyLCBmYWxzZSk7CisvLyAgICAgICAgbm9kZU5hbWUgPSBpbXBvcnRlZEF0dHIuZ2V0Tm9kZU5hbWUoKTsKKy8vICAgICAgICBub2RlVmFsdWUgPSBpbXBvcnRlZEF0dHIuZ2V0Tm9kZVZhbHVlKCk7CisvLyAgICAgICAgbm9kZVR5cGUgPSAoaW50KSBpbXBvcnRlZEF0dHIuZ2V0Tm9kZVR5cGUoKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTAxX25vZGVOYW1lIiwgInN0cmVldCIsIG5vZGVOYW1lKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTAxX25vZGVUeXBlIiwgMiwgbm9kZVR5cGUpOworLy8gICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMDFfbm9kZVZhbHVlIiwgIlllcyIsIG5vZGVWYWx1ZSk7CisvLyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGUyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRG9jdW1lbnQgZG9jSW1wb3J0ZWQ7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgQXR0ciBhdHRyOworICAgICAgICBOb2RlIGltcG9ydGVkQXR0cjsKKyAgICAgICAgU3RyaW5nIG5vZGVOYW1lOworICAgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICAgIFN0cmluZyBub2RlVmFsdWU7CisgICAgICAgIE5vZGVMaXN0IGFkZHJlc3NlczsKKyAgICAgICAgTm9kZSBhdHRyc1BhcmVudDsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvY0ltcG9ydGVkID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGJ1aWxkZXIpOworICAgICAgICBhZGRyZXNzZXMgPSBkb2MKKyAgICAgICAgICAgICAgICAuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJhZGRyZXNzIik7CisgICAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgYWRkcmVzc2VzLml0ZW0oMSk7CisgICAgICAgIGF0dHIgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5vZGVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJ6b25lIik7CisgICAgICAgIGltcG9ydGVkQXR0ciA9IGRvY0ltcG9ydGVkLmltcG9ydE5vZGUoYXR0ciwgZmFsc2UpOworICAgICAgICBub2RlTmFtZSA9IGltcG9ydGVkQXR0ci5nZXROb2RlTmFtZSgpOworICAgICAgICBub2RlVHlwZSA9IChpbnQpIGltcG9ydGVkQXR0ci5nZXROb2RlVHlwZSgpOworICAgICAgICBub2RlVmFsdWUgPSBpbXBvcnRlZEF0dHIuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICAgIGF0dHJzUGFyZW50ID0gaW1wb3J0ZWRBdHRyLmdldFBhcmVudE5vZGUoKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZG9jdW1lbnRpbXBvcnRub2RlMDJfcGFyZW50TnVsbCIsIGF0dHJzUGFyZW50KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUwMl9ub2RlTmFtZSIsICJlbXA6em9uZSIsIG5vZGVOYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUwMl9ub2RlVHlwZSIsIDIsIG5vZGVUeXBlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUwMl9ub2RlVmFsdWUiLCAiQ0FOQURBIiwgbm9kZVZhbHVlKTsKKyAgICB9CisKKy8vIEFzc3VtZXMgdmFsaWRhdGlvbi4KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnROb2RlMygpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisvLyAgICAgICAgQXR0ciBhdHRyOworLy8gICAgICAgIE5vZGVMaXN0IGNoaWxkTGlzdDsKKy8vICAgICAgICBOb2RlIGltcG9ydGVkQXR0cjsKKy8vICAgICAgICBTdHJpbmcgbm9kZU5hbWU7CisvLyAgICAgICAgaW50IG5vZGVUeXBlOworLy8gICAgICAgIFN0cmluZyBub2RlVmFsdWU7CisvLyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisvLyAgICAgICAgY2hpbGRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLAorLy8gICAgICAgICAgICAgICAgImVtcGxveWVlIik7CisvLyAgICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBjaGlsZExpc3QuaXRlbSgxKTsKKy8vICAgICAgICBhdHRyID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlKCJkZWZhdWx0QXR0ciIpOworLy8gICAgICAgIGltcG9ydGVkQXR0ciA9IGRvYy5pbXBvcnROb2RlKGF0dHIsIGZhbHNlKTsKKy8vICAgICAgICBub2RlTmFtZSA9IGltcG9ydGVkQXR0ci5nZXROb2RlTmFtZSgpOworLy8gICAgICAgIG5vZGVWYWx1ZSA9IGltcG9ydGVkQXR0ci5nZXROb2RlVmFsdWUoKTsKKy8vICAgICAgICBub2RlVHlwZSA9IChpbnQpIGltcG9ydGVkQXR0ci5nZXROb2RlVHlwZSgpOworLy8gICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMDNfbm9kZU5hbWUiLCAiZGVmYXVsdEF0dHIiLCBub2RlTmFtZSk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUwM19ub2RlVHlwZSIsIDIsIG5vZGVUeXBlKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTAzX25vZGVWYWx1ZSIsICJkZWZhdWx0VmFsIiwgbm9kZVZhbHVlKTsKKy8vICAgIH0KKworLy8gQXNzdW1lcyB2YWxpZGF0aW9uLgorLy8gICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGU0KCkgdGhyb3dzIFRocm93YWJsZSB7CisvLyAgICAgICAgRG9jdW1lbnQgZG9jOworLy8gICAgICAgIERvY3VtZW50IG5ld0RvYzsKKy8vICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZSA9IG51bGw7CisvLworLy8gICAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisvLyAgICAgICAgRWxlbWVudCBlbGVtZW50OworLy8gICAgICAgIEF0dHIgYXR0cjsKKy8vICAgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisvLyAgICAgICAgTm9kZSBpbXBvcnRlZEF0dHI7CisvLyAgICAgICAgU3RyaW5nIG5vZGVOYW1lOworLy8gICAgICAgIGludCBub2RlVHlwZTsKKy8vICAgICAgICBTdHJpbmcgbm9kZVZhbHVlOworLy8gICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworLy8gICAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKy8vICAgICAgICBuZXdEb2MgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsCisvLyAgICAgICAgICAgICAgICAibDI6cm9vdCIsIGRvY1R5cGUpOworLy8gICAgICAgIGNoaWxkTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwKKy8vICAgICAgICAgICAgICAgICJlbXBsb3llZSIpOworLy8gICAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgY2hpbGRMaXN0Lml0ZW0oMSk7CisvLyAgICAgICAgYXR0ciA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlTm9kZSgiZGVmYXVsdEF0dHIiKTsKKy8vICAgICAgICBpbXBvcnRlZEF0dHIgPSBuZXdEb2MuaW1wb3J0Tm9kZShhdHRyLCB0cnVlKTsKKy8vICAgICAgICBub2RlTmFtZSA9IGltcG9ydGVkQXR0ci5nZXROb2RlTmFtZSgpOworLy8gICAgICAgIG5vZGVWYWx1ZSA9IGltcG9ydGVkQXR0ci5nZXROb2RlVmFsdWUoKTsKKy8vICAgICAgICBub2RlVHlwZSA9IChpbnQpIGltcG9ydGVkQXR0ci5nZXROb2RlVHlwZSgpOworLy8gICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMDRfbm9kZU5hbWUiLCAiZGVmYXVsdEF0dHIiLCBub2RlTmFtZSk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUwNF9ub2RlVHlwZSIsIDIsIG5vZGVUeXBlKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTA0X25vZGVWYWx1ZSIsICJkZWZhdWx0VmFsIiwgbm9kZVZhbHVlKTsKKy8vICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0Tm9kZTUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBEb2N1bWVudCBkb2NJbXBvcnRlZDsKKyAgICAgICAgQXR0ciBhdHRyOworICAgICAgICBOb2RlIGltcG9ydGVkQXR0cjsKKyAgICAgICAgU3RyaW5nIG5vZGVOYW1lOworICAgICAgICBpbnQgbm9kZVR5cGU7CisgICAgICAgIFN0cmluZyBub2RlVmFsdWU7CisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkk7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBkb2NJbXBvcnRlZCA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBidWlsZGVyKTsKKyAgICAgICAgYXR0ciA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLCAiYV86YjAiKTsKKyAgICAgICAgaW1wb3J0ZWRBdHRyID0gZG9jSW1wb3J0ZWQuaW1wb3J0Tm9kZShhdHRyLCBmYWxzZSk7CisgICAgICAgIG5vZGVOYW1lID0gaW1wb3J0ZWRBdHRyLmdldE5vZGVOYW1lKCk7CisgICAgICAgIG5vZGVWYWx1ZSA9IGltcG9ydGVkQXR0ci5nZXROb2RlVmFsdWUoKTsKKyAgICAgICAgbm9kZVR5cGUgPSAoaW50KSBpbXBvcnRlZEF0dHIuZ2V0Tm9kZVR5cGUoKTsKKyAgICAgICAgbmFtZXNwYWNlVVJJID0gaW1wb3J0ZWRBdHRyLmdldE5hbWVzcGFjZVVSSSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTA1X25vZGVOYW1lIiwgImFfOmIwIiwgbm9kZU5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTA1X25vZGVUeXBlIiwgMiwgbm9kZVR5cGUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTA1X25vZGVWYWx1ZSIsICIiLCBub2RlVmFsdWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTA1X25hbWVzcGFjZVVSSSIsCisgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgbmFtZXNwYWNlVVJJKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGU2KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZG9jLmltcG9ydE5vZGUoZG9jLCBmYWxzZSk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9TVVBQT1JURURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGU3KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKworICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBkb2MuaW1wb3J0Tm9kZShkb2NUeXBlLCB0cnVlKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9UX1NVUFBPUlRFRF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0Tm9kZTgoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworCisgICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgICBTdHJpbmcgbnVsbE5TID0gbnVsbDsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgICBkb2NUeXBlID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudFR5cGUoInRlc3Q6cm9vdCIsIG51bGxOUywgbnVsbE5TKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZG9jLmltcG9ydE5vZGUoZG9jVHlwZSwgdHJ1ZSk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9TVVBQT1JURURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGU5KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRG9jdW1lbnRGcmFnbWVudCBkb2NGcmFnbWVudDsKKyAgICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgICBib29sZWFuIHN1Y2Nlc3M7CisgICAgICAgIE5vZGUgYWRkcmVzc05vZGU7CisKKyAgICAgICAgTm9kZSBpbXBvcnRlZERvY0ZyYWc7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBkb2NGcmFnbWVudCA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CisgICAgICAgIGNoaWxkTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCIqIiwgImFkZHJlc3MiKTsKKyAgICAgICAgYWRkcmVzc05vZGUgPSBjaGlsZExpc3QuaXRlbSgwKTsKKyAgICAgICAgZG9jRnJhZ21lbnQuYXBwZW5kQ2hpbGQoYWRkcmVzc05vZGUpOworICAgICAgICBpbXBvcnRlZERvY0ZyYWcgPSBkb2MuaW1wb3J0Tm9kZShkb2NGcmFnbWVudCwgZmFsc2UpOworICAgICAgICBzdWNjZXNzID0gaW1wb3J0ZWREb2NGcmFnLmhhc0NoaWxkTm9kZXMoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoImRvY3VtZW50aW1wb3J0bm9kZTA5Iiwgc3VjY2Vzcyk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnROb2RlMTAoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBEb2N1bWVudEZyYWdtZW50IGRvY0ZyYWdtZW50OworICAgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICAgIGJvb2xlYW4gc3VjY2VzczsKKyAgICAgICAgTm9kZSBhZGRyZXNzTm9kZTsKKworICAgICAgICBOb2RlIGltcG9ydGVkRG9jRnJhZzsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvY0ZyYWdtZW50ID0gZG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKKyAgICAgICAgY2hpbGRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiYWRkcmVzcyIpOworICAgICAgICBhZGRyZXNzTm9kZSA9IGNoaWxkTGlzdC5pdGVtKDApOworICAgICAgICBkb2NGcmFnbWVudC5hcHBlbmRDaGlsZChhZGRyZXNzTm9kZSk7CisgICAgICAgIGltcG9ydGVkRG9jRnJhZyA9IGRvYy5pbXBvcnROb2RlKGRvY0ZyYWdtZW50LCB0cnVlKTsKKyAgICAgICAgc3VjY2VzcyA9IGltcG9ydGVkRG9jRnJhZy5oYXNDaGlsZE5vZGVzKCk7CisgICAgICAgIGFzc2VydFRydWUoImRvY3VtZW50aW1wb3J0bm9kZTEwIiwgc3VjY2Vzcyk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnROb2RlMTEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGRvY0VsZW1lbnQ7CisgICAgICAgIE5vZGUgaW1wb3J0ZWQ7CisgICAgICAgIGJvb2xlYW4gc3VjY2VzczsKKyAgICAgICAgU3RyaW5nIG5vZGVOYW1lT3JpZzsKKyAgICAgICAgU3RyaW5nIG5vZGVOYW1lSW1wb3J0ZWQ7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBkb2NFbGVtZW50ID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgICBpbXBvcnRlZCA9IGRvYy5pbXBvcnROb2RlKGRvY0VsZW1lbnQsIGZhbHNlKTsKKyAgICAgICAgc3VjY2VzcyA9IGltcG9ydGVkLmhhc0NoaWxkTm9kZXMoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoImRvY3VtZW50aW1wb3J0bm9kZTExIiwgc3VjY2Vzcyk7CisgICAgICAgIG5vZGVOYW1lSW1wb3J0ZWQgPSBpbXBvcnRlZC5nZXROb2RlTmFtZSgpOworICAgICAgICBub2RlTmFtZU9yaWcgPSBkb2NFbGVtZW50LmdldE5vZGVOYW1lKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMTFfTm9kZU5hbWUiLCBub2RlTmFtZUltcG9ydGVkLAorICAgICAgICAgICAgICAgIG5vZGVOYW1lT3JpZyk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnROb2RlMTIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICAgIE5vZGUgaW1wb3J0ZWQ7CisgICAgICAgIE5vZGUgYWRkcmVzc0VsZW07CisgICAgICAgIE5vZGVMaXN0IGFkZHJlc3NFbGVtQ2hpbGRyZW47CisgICAgICAgIE5vZGVMaXN0IGltcG9ydGVkQ2hpbGRyZW47CisgICAgICAgIGludCBhZGRyZXNzRWxlbUxlbjsKKyAgICAgICAgaW50IGltcG9ydGVkTGVuOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgY2hpbGRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiYWRkcmVzcyIpOworICAgICAgICBhZGRyZXNzRWxlbSA9IGNoaWxkTGlzdC5pdGVtKDApOworICAgICAgICBpbXBvcnRlZCA9IGRvYy5pbXBvcnROb2RlKGFkZHJlc3NFbGVtLCB0cnVlKTsKKyAgICAgICAgYWRkcmVzc0VsZW1DaGlsZHJlbiA9IGFkZHJlc3NFbGVtLmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgaW1wb3J0ZWRDaGlsZHJlbiA9IGltcG9ydGVkLmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgYWRkcmVzc0VsZW1MZW4gPSAoaW50KSBhZGRyZXNzRWxlbUNoaWxkcmVuLmdldExlbmd0aCgpOworICAgICAgICBpbXBvcnRlZExlbiA9IChpbnQpIGltcG9ydGVkQ2hpbGRyZW4uZ2V0TGVuZ3RoKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMTIiLCBpbXBvcnRlZExlbiwgYWRkcmVzc0VsZW1MZW4pOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0Tm9kZTEzKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworICAgICAgICBOb2RlIGltcG9ydGVkOworICAgICAgICBOb2RlTGlzdCBpbXBvcnRlZExpc3Q7CisgICAgICAgIE5vZGUgZW1wbG95ZWVFbGVtOworICAgICAgICBpbnQgaW1wb3J0ZWRMZW47CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBjaGlsZExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJlbXBsb3llZSIpOworICAgICAgICBlbXBsb3llZUVsZW0gPSBjaGlsZExpc3QuaXRlbSgwKTsKKyAgICAgICAgaW1wb3J0ZWQgPSBkb2MuaW1wb3J0Tm9kZShlbXBsb3llZUVsZW0sIGZhbHNlKTsKKyAgICAgICAgaW1wb3J0ZWRMaXN0ID0gaW1wb3J0ZWQuZ2V0Q2hpbGROb2RlcygpOworICAgICAgICBpbXBvcnRlZExlbiA9IChpbnQpIGltcG9ydGVkTGlzdC5nZXRMZW5ndGgoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUxMyIsIDAsIGltcG9ydGVkTGVuKTsKKyAgICB9CisKKy8vIEFzc3VtZXMgdmFsaWRhdGlvbi4KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnROb2RlMTQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKy8vICAgICAgICBEb2N1bWVudCBkb2M7CisvLyAgICAgICAgRG9jdW1lbnQgbmV3RG9jOworLy8gICAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisvLyAgICAgICAgRG9jdW1lbnRUeXBlIG51bGxEb2NUeXBlID0gbnVsbDsKKy8vCisvLyAgICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworLy8gICAgICAgIE5vZGUgaW1wb3J0ZWQ7CisvLyAgICAgICAgTm9kZSBlbXBsb3llZUVsZW07CisvLyAgICAgICAgQXR0ciBhdHRyTm9kZTsKKy8vICAgICAgICBTdHJpbmcgYXR0clZhbHVlOworLy8gICAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworLy8KKy8vICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKy8vICAgICAgICBjaGlsZExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJlbXBsb3llZSIpOworLy8gICAgICAgIGVtcGxveWVlRWxlbSA9IGNoaWxkTGlzdC5pdGVtKDMpOworLy8gICAgICAgIGRvbUltcGwgPSBidWlsZGVyLmdldERPTUltcGxlbWVudGF0aW9uKCk7CisvLyAgICAgICAgbmV3RG9jID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudChudWxsTlMsICJzdGFmZiIsIG51bGxEb2NUeXBlKTsKKy8vICAgICAgICBpbXBvcnRlZCA9IG5ld0RvYy5pbXBvcnROb2RlKGVtcGxveWVlRWxlbSwgdHJ1ZSk7CisvLyAgICAgICAgYXR0ck5vZGUgPSAoKEVsZW1lbnQpIC8qIE5vZGUgKi9pbXBvcnRlZCkuZ2V0QXR0cmlidXRlTm9kZU5TKG51bGxOUywKKy8vICAgICAgICAgICAgICAgICJkZWZhdWx0QXR0ciIpOworLy8gICAgICAgIGFzc2VydE51bGwoImRlZmF1bHRBdHRyTm90SW1wb3J0ZWQiLCBhdHRyTm9kZSk7CisvLyAgICAgICAgYXR0clZhbHVlID0gKChFbGVtZW50KSAvKiBOb2RlICovaW1wb3J0ZWQpLmdldEF0dHJpYnV0ZU5TKAorLy8gICAgICAgICAgICAgICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIiwgImVtcCIpOworLy8gICAgICAgIGFzc2VydEVxdWFscygiZXhwbGljaXRBdHRySW1wb3J0ZWQiLCAiaHR0cDovL3d3dy5uaXN0LmdvdiIsIGF0dHJWYWx1ZSk7CisvLyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGUxNSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisKKyAgICAgICAgTm9kZSB0ZXh0SW1wb3J0OworICAgICAgICBOb2RlIHRleHRUb0ltcG9ydDsKKyAgICAgICAgU3RyaW5nIG5vZGVWYWx1ZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisKKyAgICAgICAgdGV4dFRvSW1wb3J0ID0gZG9jCisgICAgICAgICAgICAgICAgLmNyZWF0ZVRleHROb2RlKCJEb2N1bWVudC5pbXBvcnROb2RlIHRlc3QgZm9yIGEgVEVYVF9OT0RFIik7CisgICAgICAgIHRleHRJbXBvcnQgPSBkb2MuaW1wb3J0Tm9kZSh0ZXh0VG9JbXBvcnQsIHRydWUpOworICAgICAgICBub2RlVmFsdWUgPSB0ZXh0SW1wb3J0LmdldE5vZGVWYWx1ZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTE1IiwKKyAgICAgICAgICAgICAgICAiRG9jdW1lbnQuaW1wb3J0Tm9kZSB0ZXN0IGZvciBhIFRFWFRfTk9ERSIsIG5vZGVWYWx1ZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnROb2RlMTcoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworCisgICAgICAgIE5vZGUgY29tbWVudEltcG9ydDsKKyAgICAgICAgTm9kZSBjb21tZW50VG9JbXBvcnQ7CisgICAgICAgIFN0cmluZyBub2RlVmFsdWU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworCisgICAgICAgIGNvbW1lbnRUb0ltcG9ydCA9IGRvYworICAgICAgICAgICAgICAgIC5jcmVhdGVDb21tZW50KCJEb2N1bWVudC5pbXBvcnROb2RlIHRlc3QgZm9yIGEgQ09NTUVOVF9OT0RFIik7CisgICAgICAgIGNvbW1lbnRJbXBvcnQgPSBkb2MuaW1wb3J0Tm9kZShjb21tZW50VG9JbXBvcnQsIHRydWUpOworICAgICAgICBub2RlVmFsdWUgPSBjb21tZW50SW1wb3J0LmdldE5vZGVWYWx1ZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTE3IiwKKyAgICAgICAgICAgICAgICAiRG9jdW1lbnQuaW1wb3J0Tm9kZSB0ZXN0IGZvciBhIENPTU1FTlRfTk9ERSIsIG5vZGVWYWx1ZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnROb2RlMTgoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworCisgICAgICAgIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBwaUltcG9ydDsKKyAgICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uIHBpVG9JbXBvcnQ7CisgICAgICAgIFN0cmluZyBwaURhdGE7CisgICAgICAgIFN0cmluZyBwaVRhcmdldDsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisKKyAgICAgICAgcGlUb0ltcG9ydCA9IGRvYy5jcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oIlRhcmdldCIsICJEYXRhIik7CisgICAgICAgIHBpSW1wb3J0ID0gKFByb2Nlc3NpbmdJbnN0cnVjdGlvbikgZG9jLmltcG9ydE5vZGUocGlUb0ltcG9ydCwgZmFsc2UpOworICAgICAgICBwaVRhcmdldCA9IHBpSW1wb3J0LmdldFRhcmdldCgpOworICAgICAgICBwaURhdGEgPSBwaUltcG9ydC5nZXREYXRhKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMThfVGFyZ2V0IiwgIlRhcmdldCIsIHBpVGFyZ2V0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUxOF9EYXRhIiwgIkRhdGEiLCBwaURhdGEpOworICAgIH0KKworLy8gQXNzdW1lcyB2YWxpZGF0aW9uLgorLy8gICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGUxOSgpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZU51bGwgPSBudWxsOworLy8KKy8vICAgICAgICBEb2N1bWVudCBkb2NJbXA7CisvLyAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKy8vICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKy8vICAgICAgICBOYW1lZE5vZGVNYXAgbm9kZU1hcDsKKy8vICAgICAgICBFbnRpdHkgZW50aXR5MjsKKy8vICAgICAgICBFbnRpdHkgZW50aXR5NjsKKy8vICAgICAgICBFbnRpdHkgZW50aXR5SW1wMjsKKy8vICAgICAgICBFbnRpdHkgZW50aXR5SW1wNjsKKy8vICAgICAgICBTdHJpbmcgbm9kZU5hbWU7CisvLyAgICAgICAgU3RyaW5nIHN5c3RlbUlkOworLy8gICAgICAgIFN0cmluZyBub3RhdGlvbk5hbWU7CisvLyAgICAgICAgU3RyaW5nIG5vZGVOYW1lSW1wOworLy8gICAgICAgIFN0cmluZyBzeXN0ZW1JZEltcDsKKy8vICAgICAgICBTdHJpbmcgbm90YXRpb25OYW1lSW1wOworLy8gICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworLy8gICAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKy8vICAgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKy8vICAgICAgICBkb2NJbXAgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJhOmIiLAorLy8gICAgICAgICAgICAgICAgZG9jVHlwZU51bGwpOworLy8gICAgICAgIG5vZGVNYXAgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisvLyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50aXRpZXNOb3ROdWxsIiwgbm9kZU1hcCk7CisvLyAgICAgICAgZW50aXR5MiA9IChFbnRpdHkpIG5vZGVNYXAuZ2V0TmFtZWRJdGVtKCJlbnQyIik7CisvLyAgICAgICAgZW50aXR5NiA9IChFbnRpdHkpIG5vZGVNYXAuZ2V0TmFtZWRJdGVtKCJlbnQ2Iik7CisvLyAgICAgICAgZW50aXR5SW1wMiA9IChFbnRpdHkpIGRvY0ltcC5pbXBvcnROb2RlKGVudGl0eTIsIGZhbHNlKTsKKy8vICAgICAgICBlbnRpdHlJbXA2ID0gKEVudGl0eSkgZG9jSW1wLmltcG9ydE5vZGUoZW50aXR5NiwgdHJ1ZSk7CisvLyAgICAgICAgbm9kZU5hbWUgPSBlbnRpdHkyLmdldE5vZGVOYW1lKCk7CisvLyAgICAgICAgbm9kZU5hbWVJbXAgPSBlbnRpdHlJbXAyLmdldE5vZGVOYW1lKCk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUxOV9FbnQyTm9kZU5hbWUiLCBub2RlTmFtZSwgbm9kZU5hbWVJbXApOworLy8gICAgICAgIG5vZGVOYW1lID0gZW50aXR5Ni5nZXROb2RlTmFtZSgpOworLy8gICAgICAgIG5vZGVOYW1lSW1wID0gZW50aXR5SW1wNi5nZXROb2RlTmFtZSgpOworLy8gICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMTlfRW50Nk5vZGVOYW1lIiwgbm9kZU5hbWUsIG5vZGVOYW1lSW1wKTsKKy8vICAgICAgICBzeXN0ZW1JZCA9IGVudGl0eTIuZ2V0U3lzdGVtSWQoKTsKKy8vICAgICAgICBzeXN0ZW1JZEltcCA9IGVudGl0eUltcDIuZ2V0U3lzdGVtSWQoKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTE5X0VudDJTeXN0ZW1JZCIsIHN5c3RlbUlkLCBzeXN0ZW1JZEltcCk7CisvLyAgICAgICAgc3lzdGVtSWQgPSBlbnRpdHk2LmdldFN5c3RlbUlkKCk7CisvLyAgICAgICAgc3lzdGVtSWRJbXAgPSBlbnRpdHlJbXA2LmdldFN5c3RlbUlkKCk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUxOV9FbnQ2U3lzdGVtSWQiLCBzeXN0ZW1JZCwgc3lzdGVtSWRJbXApOworLy8gICAgICAgIG5vdGF0aW9uTmFtZSA9IGVudGl0eTIuZ2V0Tm90YXRpb25OYW1lKCk7CisvLyAgICAgICAgbm90YXRpb25OYW1lSW1wID0gZW50aXR5SW1wMi5nZXROb3RhdGlvbk5hbWUoKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTE5X0VudDJOb3RhdGlvbk5hbWUiLCBub3RhdGlvbk5hbWUsCisvLyAgICAgICAgICAgICAgICBub3RhdGlvbk5hbWVJbXApOworLy8gICAgICAgIG5vdGF0aW9uTmFtZSA9IGVudGl0eTYuZ2V0Tm90YXRpb25OYW1lKCk7CisvLyAgICAgICAgbm90YXRpb25OYW1lSW1wID0gZW50aXR5SW1wNi5nZXROb3RhdGlvbk5hbWUoKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTE5X0VudDZOb3RhdGlvbk5hbWUiLCBub3RhdGlvbk5hbWUsCisvLyAgICAgICAgICAgICAgICBub3RhdGlvbk5hbWVJbXApOworLy8gICAgfQorCisvLyBBc3N1bWVzIHZhbGlkYXRpb24uCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0Tm9kZTIwKCkgdGhyb3dzIFRocm93YWJsZSB7CisvLyAgICAgICAgRG9jdW1lbnQgZG9jOworLy8gICAgICAgIERvY3VtZW50IGRvY0ltcDsKKy8vICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworLy8gICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworLy8gICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlTnVsbCA9IG51bGw7CisvLworLy8gICAgICAgIE5hbWVkTm9kZU1hcCBub2RlTWFwOworLy8gICAgICAgIEVudGl0eSBlbnRpdHk0OworLy8gICAgICAgIEVudGl0eSBlbnRpdHlJbXA0OworLy8gICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKy8vICAgICAgICBDaGFyYWN0ZXJEYXRhIGNkYXRhOworLy8gICAgICAgIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBwaTsKKy8vICAgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisvLyAgICAgICAgTm9kZUxpc3QgZWxlbWNoaWxkTGlzdDsKKy8vICAgICAgICBTdHJpbmcgZW50NE5hbWU7CisvLyAgICAgICAgU3RyaW5nIGVudDRJbXBOYW1lOworLy8gICAgICAgIFN0cmluZyBjZGF0YVZhbDsKKy8vICAgICAgICBTdHJpbmcgcGlUYXJnZXRWYWw7CisvLyAgICAgICAgU3RyaW5nIHBpRGF0YVZhbDsKKy8vICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKy8vICAgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisvLyAgICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisvLyAgICAgICAgZG9jSW1wID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudCgiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLCAiYTpiIiwKKy8vICAgICAgICAgICAgICAgIGRvY1R5cGVOdWxsKTsKKy8vICAgICAgICBub2RlTWFwID0gZG9jVHlwZS5nZXRFbnRpdGllcygpOworLy8gICAgICAgIGVudGl0eTQgPSAoRW50aXR5KSBub2RlTWFwLmdldE5hbWVkSXRlbSgiZW50NCIpOworLy8gICAgICAgIGVudGl0eUltcDQgPSAoRW50aXR5KSBkb2NJbXAuaW1wb3J0Tm9kZShlbnRpdHk0LCB0cnVlKTsKKy8vICAgICAgICBjaGlsZExpc3QgPSBlbnRpdHlJbXA0LmdldENoaWxkTm9kZXMoKTsKKy8vICAgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGNoaWxkTGlzdC5pdGVtKDApOworLy8gICAgICAgIGVsZW1jaGlsZExpc3QgPSBlbGVtZW50LmdldENoaWxkTm9kZXMoKTsKKy8vICAgICAgICBjZGF0YSA9IChDaGFyYWN0ZXJEYXRhKSBlbGVtY2hpbGRMaXN0Lml0ZW0oMCk7CisvLyAgICAgICAgcGkgPSAoUHJvY2Vzc2luZ0luc3RydWN0aW9uKSBjaGlsZExpc3QuaXRlbSgxKTsKKy8vICAgICAgICBlbnQ0TmFtZSA9IGVudGl0eTQuZ2V0Tm9kZU5hbWUoKTsKKy8vICAgICAgICBlbnQ0SW1wTmFtZSA9IGVudGl0eUltcDQuZ2V0Tm9kZU5hbWUoKTsKKy8vICAgICAgICBjZGF0YVZhbCA9IGNkYXRhLmdldERhdGEoKTsKKy8vICAgICAgICBwaVRhcmdldFZhbCA9IHBpLmdldFRhcmdldCgpOworLy8gICAgICAgIHBpRGF0YVZhbCA9IHBpLmdldERhdGEoKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTIwX0VudDROb2RlTmFtZSIsIGVudDROYW1lLCBlbnQ0SW1wTmFtZSk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUyMF9DZGF0YSIsICJFbGVtZW50IGRhdGEiLCBjZGF0YVZhbCk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUyMF9QSVRhcmdldCIsICJQSXRhcmdldCIsIHBpVGFyZ2V0VmFsKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTIwX1BJRGF0YSIsICJQSWRhdGEiLCBwaURhdGFWYWwpOworLy8gICAgfQorCisvLyBUT0RPIEZhaWxzIG9uIEpESy4gV2h5PworLy8gICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGUyMSgpIHRocm93cyBUaHJvd2FibGUgeworLy8KKy8vCisvLyAgICAgICAgRG9jdW1lbnQgZG9jOworLy8gICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlTnVsbCA9IG51bGw7CisvLworLy8gICAgICAgIERvY3VtZW50IGRvY0ltcDsKKy8vICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworLy8gICAgICAgIE5vZGVMaXN0IGFkZHJlc3NMaXN0OworLy8gICAgICAgIE5vZGVMaXN0IGFkZHJlc3NDaGlsZExpc3Q7CisvLyAgICAgICAgRWxlbWVudCBlbGVtZW50OworLy8gICAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWYyOworLy8gICAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWZJbXAyOworLy8gICAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWYzOworLy8gICAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWZJbXAzOworLy8gICAgICAgIFN0cmluZyBub2RlTmFtZTI7CisvLyAgICAgICAgU3RyaW5nIG5vZGVOYW1lMzsKKy8vICAgICAgICBTdHJpbmcgbm9kZU5hbWVJbXAyOworLy8gICAgICAgIFN0cmluZyBub2RlTmFtZUltcDM7CisvLyAgICAgICAgTm9kZUxpc3Qgbm9kZXM7CisvLyAgICAgICAgTm9kZSBub2RlSW1wMzsKKy8vICAgICAgICBOb2RlIG5vZGVJbXAyOworLy8gICAgICAgIFN0cmluZyBub2RlVmFsdWVJbXAyOworLy8gICAgICAgIFN0cmluZyBub2RlVmFsdWVJbXAzOworLy8gICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworLy8gICAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKy8vICAgICAgICBkb2NJbXAgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJhOmIiLAorLy8gICAgICAgICAgICAgICAgZG9jVHlwZU51bGwpOworLy8gICAgICAgIGFkZHJlc3NMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisvLyAgICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBhZGRyZXNzTGlzdC5pdGVtKDEpOworLy8gICAgICAgIGFkZHJlc3NDaGlsZExpc3QgPSBlbGVtZW50LmdldENoaWxkTm9kZXMoKTsKKy8vICAgICAgICBlbnRSZWYyID0gKEVudGl0eVJlZmVyZW5jZSkgYWRkcmVzc0NoaWxkTGlzdC5pdGVtKDApOworLy8gICAgICAgIGVudFJlZjMgPSAoRW50aXR5UmVmZXJlbmNlKSBhZGRyZXNzQ2hpbGRMaXN0Lml0ZW0oMik7CisvLyAgICAgICAgZW50UmVmSW1wMiA9IChFbnRpdHlSZWZlcmVuY2UpIGRvY0ltcC5pbXBvcnROb2RlKGVudFJlZjIsIHRydWUpOworLy8gICAgICAgIGVudFJlZkltcDMgPSAoRW50aXR5UmVmZXJlbmNlKSBkb2NJbXAuaW1wb3J0Tm9kZShlbnRSZWYzLCBmYWxzZSk7CisvLyAgICAgICAgbm9kZU5hbWUyID0gZW50UmVmMi5nZXROb2RlTmFtZSgpOworLy8gICAgICAgIG5vZGVOYW1lMyA9IGVudFJlZjMuZ2V0Tm9kZU5hbWUoKTsKKy8vICAgICAgICBub2RlTmFtZUltcDIgPSBlbnRSZWZJbXAyLmdldE5vZGVOYW1lKCk7CisvLyAgICAgICAgbm9kZU5hbWVJbXAzID0gZW50UmVmSW1wMy5nZXROb2RlTmFtZSgpOworLy8gICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMjFfRW50Mk5vZGVOYW1lIiwgbm9kZU5hbWUyLAorLy8gICAgICAgICAgICAgICAgbm9kZU5hbWVJbXAyKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTIxX0VudDNOb2RlTmFtZSIsIG5vZGVOYW1lMywKKy8vICAgICAgICAgICAgICAgIG5vZGVOYW1lSW1wMyk7CisvLyAgICAgICAgZW50UmVmSW1wMiA9IChFbnRpdHlSZWZlcmVuY2UpIGRvYy5pbXBvcnROb2RlKGVudFJlZjIsIHRydWUpOworLy8gICAgICAgIGVudFJlZkltcDMgPSAoRW50aXR5UmVmZXJlbmNlKSBkb2MuaW1wb3J0Tm9kZShlbnRSZWYzLCBmYWxzZSk7CisvLyAgICAgICAgbm9kZXMgPSBlbnRSZWZJbXAyLmdldENoaWxkTm9kZXMoKTsKKy8vICAgICAgICBub2RlSW1wMiA9IG5vZGVzLml0ZW0oMCk7CisvLyAgICAgICAgbm9kZVZhbHVlSW1wMiA9IG5vZGVJbXAyLmdldE5vZGVWYWx1ZSgpOworLy8gICAgICAgIG5vZGVzID0gZW50UmVmSW1wMy5nZXRDaGlsZE5vZGVzKCk7CisvLyAgICAgICAgbm9kZUltcDMgPSBub2Rlcy5pdGVtKDApOworLy8gICAgICAgIG5vZGVWYWx1ZUltcDMgPSBub2RlSW1wMy5nZXROb2RlVmFsdWUoKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTIxX0VudDJOb2RlVmFsdWUiLCAiMTkwMCBEYWxsYXMgUm9hZCIsCisvLyAgICAgICAgICAgICAgICBub2RlVmFsdWVJbXAyKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTIxX0VudDNOb2RldmFsdWUiLCAiVGV4YXMiLAorLy8gICAgICAgICAgICAgICAgbm9kZVZhbHVlSW1wMyk7CisvLworLy8gICAgfQorCisvLyBBc3N1bWVzIHZhbGlkYXRpb24uCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0Tm9kZTIyKCkgdGhyb3dzIFRocm93YWJsZSB7CisvLyAgICAgICAgRG9jdW1lbnQgZG9jOworLy8gICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlTnVsbCA9IG51bGw7CisvLworLy8gICAgICAgIERvY3VtZW50IGRvY0ltcDsKKy8vICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworLy8gICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworLy8gICAgICAgIE5hbWVkTm9kZU1hcCBub2RlTWFwOworLy8gICAgICAgIE5vdGF0aW9uIG5vdGF0aW9uMTsKKy8vICAgICAgICBOb3RhdGlvbiBub3RhdGlvbjI7CisvLworLy8gICAgICAgIFN0cmluZyBwdWJsaWNJZDE7CisvLyAgICAgICAgU3RyaW5nIHB1YmxpY0lkMUltcDsKKy8vICAgICAgICBTdHJpbmcgcHVibGljSWQxTmV3SW1wOworLy8gICAgICAgIFN0cmluZyBwdWJsaWNJZDJJbXA7CisvLworLy8gICAgICAgIFN0cmluZyBzeXN0ZW1JZDFJbXA7CisvLyAgICAgICAgU3RyaW5nIHN5c3RlbUlkMU5ld0ltcDsKKy8vICAgICAgICBTdHJpbmcgc3lzdGVtSWQyOworLy8gICAgICAgIFN0cmluZyBzeXN0ZW1JZDJJbXA7CisvLyAgICAgICAgU3RyaW5nIHN5c3RlbUlkMk5ld0ltcDsKKy8vICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKy8vICAgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisvLyAgICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisvLyAgICAgICAgZG9jSW1wID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudCgiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLCAiYTpiIiwKKy8vICAgICAgICAgICAgICAgIGRvY1R5cGVOdWxsKTsKKy8vICAgICAgICBub2RlTWFwID0gZG9jVHlwZS5nZXROb3RhdGlvbnMoKTsKKy8vICAgICAgICBhc3NlcnROb3ROdWxsKCJub3RhdGlvbnNOb3ROdWxsIiwgbm9kZU1hcCk7CisvLyAgICAgICAgbm90YXRpb24xID0gKE5vdGF0aW9uKSBub2RlTWFwLmdldE5hbWVkSXRlbSgibm90YXRpb24xIik7CisvLyAgICAgICAgbm90YXRpb24yID0gKE5vdGF0aW9uKSBub2RlTWFwLmdldE5hbWVkSXRlbSgibm90YXRpb24yIik7CisvLyAgICAgICAgZG9jLmltcG9ydE5vZGUobm90YXRpb24xLCB0cnVlKTsKKy8vICAgICAgICBkb2MuaW1wb3J0Tm9kZShub3RhdGlvbjIsIGZhbHNlKTsKKy8vICAgICAgICBkb2NJbXAuaW1wb3J0Tm9kZShub3RhdGlvbjEsIGZhbHNlKTsKKy8vICAgICAgICBkb2NJbXAuaW1wb3J0Tm9kZShub3RhdGlvbjIsIHRydWUpOworLy8gICAgICAgIHB1YmxpY0lkMSA9IG5vdGF0aW9uMS5nZXRQdWJsaWNJZCgpOworLy8gICAgICAgIHB1YmxpY0lkMUltcCA9IG5vdGF0aW9uMS5nZXRQdWJsaWNJZCgpOworLy8gICAgICAgIHB1YmxpY0lkMU5ld0ltcCA9IG5vdGF0aW9uMS5nZXRQdWJsaWNJZCgpOworLy8gICAgICAgIHN5c3RlbUlkMUltcCA9IG5vdGF0aW9uMS5nZXRTeXN0ZW1JZCgpOworLy8gICAgICAgIHN5c3RlbUlkMU5ld0ltcCA9IG5vdGF0aW9uMS5nZXRTeXN0ZW1JZCgpOworLy8gICAgICAgIHB1YmxpY0lkMkltcCA9IG5vdGF0aW9uMi5nZXRQdWJsaWNJZCgpOworLy8gICAgICAgIG5vdGF0aW9uMi5nZXRQdWJsaWNJZCgpOworLy8gICAgICAgIHN5c3RlbUlkMiA9IG5vdGF0aW9uMi5nZXRTeXN0ZW1JZCgpOworLy8gICAgICAgIHN5c3RlbUlkMkltcCA9IG5vdGF0aW9uMi5nZXRTeXN0ZW1JZCgpOworLy8gICAgICAgIHN5c3RlbUlkMk5ld0ltcCA9IG5vdGF0aW9uMi5nZXRTeXN0ZW1JZCgpOworLy8gICAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnRpbXBvcnRub2RlMjJfTjFQSUQiLCBwdWJsaWNJZDEsIHB1YmxpY0lkMUltcCk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUyMl9OMU5QSUQiLCBwdWJsaWNJZDEsIHB1YmxpY0lkMU5ld0ltcCk7CisvLyAgICAgICAgYXNzZXJ0TnVsbCgiZG9jdW1lbnRpbXBvcnRub2RlMjJfTjFTSUQiLCBzeXN0ZW1JZDFJbXApOworLy8gICAgICAgIGFzc2VydE51bGwoImRvY3VtZW50aW1wb3J0bm9kZTIyX04xTlNJRCIsIHN5c3RlbUlkMU5ld0ltcCk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkb2N1bWVudGltcG9ydG5vZGUyMl9OMlNJRCIsIHN5c3RlbUlkMiwgc3lzdGVtSWQySW1wKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50aW1wb3J0bm9kZTIyX04yTlNJRCIsIHN5c3RlbUlkMiwgc3lzdGVtSWQyTmV3SW1wKTsKKy8vICAgICAgICBhc3NlcnROdWxsKCJkb2N1bWVudGltcG9ydG5vZGUyMl9OMlBJRCIsIHB1YmxpY0lkMkltcCk7CisvLyAgICAgICAgYXNzZXJ0TnVsbCgiZG9jdW1lbnRpbXBvcnRub2RlMjJfTjJOUElEIiwgcHVibGljSWQySW1wKTsKKy8vICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Eb2N1bWVudFR5cGVJbnRlcm5hbFN1YnNldC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0RvY3VtZW50VHlwZUludGVybmFsU3Vic2V0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjg0ZTY2YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Eb2N1bWVudFR5cGVJbnRlcm5hbFN1YnNldC5qYXZhCkBAIC0wLDAgKzEsNjQgQEAKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogVGhlIG1ldGhvZCBnZXRJbnRlcm5hbFN1YnNldCgpIHJldHVybnMgdGhlIGludGVybmFsIHN1YnNldCBhcyBhIHN0cmluZy4KKyAqCisgKiBDcmVhdGUgYSBuZXcgRG9jdW1lbnRUeXBlIG5vZGUgd2l0aCBudWxsIHZhbHVlcyBmb3IgcHVibGljSWQgYW5kIHN5c3RlbUlkLgorICogVmVyaWZ5IHRoYXQgaXRzIGludGVybmFsIHN1YnNldCBpcyBudWxsLgorICoKKyAqIEBhdXRob3IgSUJNCisgKiBAYXV0aG9yIE5laWwgRGVsaW1hCisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Db3JlLURvY1R5cGUtaW50ZXJuYWxTdWJzZXQiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Db3JlLURvY1R5cGUtaW50ZXJuYWxTdWJzZXQ8L2E+CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTk8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBEb2N1bWVudFR5cGVJbnRlcm5hbFN1YnNldCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnRlcm5hbFN1YnNldCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgICBTdHJpbmcgaW50ZXJuYWw7CisgICAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICAgIGRvY1R5cGUgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50VHlwZSgibDI6cm9vdCIsIG51bGxOUywgbnVsbE5TKTsKKyAgICAgICAgaW50ZXJuYWwgPSBkb2NUeXBlLmdldEludGVybmFsU3Vic2V0KCk7CisgICAgICAgIGFzc2VydE51bGwoImludGVybmFsU3Vic2V0TnVsbCIsIGludGVybmFsKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRG9jdW1lbnRUeXBlUHVibGljSWQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Eb2N1bWVudFR5cGVQdWJsaWNJZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYyNTQ0ZjAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRG9jdW1lbnRUeXBlUHVibGljSWQuamF2YQpAQCAtMCwwICsxLDg1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKworCisvKioKKyAqICAgICBUaGUgbWV0aG9kIGdldEludGVybmFsU3Vic2V0KCkgcmV0dXJucyB0aGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIHN1YnNldC4KKyAqCisgKiAgICAgQ3JlYXRlIGEgbmV3IERvY3VtZW50VHlwZSBub2RlIHdpdGggdGhlIHZhbHVlICJQVUIiIGZvciBpdHMgcHVibGljSWQuCisgKiAgICAgQ2hlY2sgdGhlIHZhbHVlIG9mIHRoZSBwdWJsaWNJZCBhdHRyaWJ1dGUgdXNpbmcgZ2V0UHVibGljSWQoKS4KKyogQGF1dGhvciBJQk0KKyogQGF1dGhvciBOZWlsIERlbGltYQorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Db3JlLURvY1R5cGUtcHVibGljSWQiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Db3JlLURvY1R5cGUtcHVibGljSWQ8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OSI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTI1OTwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgRG9jdW1lbnRUeXBlUHVibGljSWQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UHVibGljSWQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgIFN0cmluZyBwdWJsaWNJZDsKKyAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworCisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgIGRvY1R5cGUgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50VHlwZSgibDI6cm9vdCIsICJQVUIiLCBudWxsTlMpOworICAgICAgcHVibGljSWQgPSBkb2NUeXBlLmdldFB1YmxpY0lkKCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50dHlwZXB1YmxpY2lkMDEiLCAiUFVCIiwgcHVibGljSWQpOworICAgICAgfQorCit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Eb2N1bWVudFR5cGVTeXN0ZW1JZC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0RvY3VtZW50VHlwZVN5c3RlbUlkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDkwOGUxZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Eb2N1bWVudFR5cGVTeXN0ZW1JZC5qYXZhCkBAIC0wLDAgKzEsODMgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogICAgIFRoZSBtZXRob2QgZ2V0SW50ZXJuYWxTdWJzZXQoKSByZXR1cm5zIHRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgc3Vic2V0LgorICoKKyAqICAgICBDcmVhdGUgYSBuZXcgRG9jdW1lbnRUeXBlIG5vZGUgd2l0aCB0aGUgdmFsdWUgIlNZUyIgZm9yIGl0cyBzeXN0ZW1JZCBhbmQgUFVCIGZvcgorICogICAgIGl0cyBwdWJsaWNJZC4gIENoZWNrIHRoZSB2YWx1ZSBvZiB0aGUgc3lzdGVtSWQgYW5kIHBidWxpY0lkIGF0dHJpYnV0ZXMuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtQ29yZS1Eb2NUeXBlLXN5c3RlbUlkIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtQ29yZS1Eb2NUeXBlLXN5c3RlbUlkPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBEb2N1bWVudFR5cGVTeXN0ZW1JZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHRlc3RHZXRTeXN0ZW1JZCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgU3RyaW5nIHB1YmxpY0lkOworICAgICAgU3RyaW5nIHN5c3RlbUlkOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICBkb2NUeXBlID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudFR5cGUoImwyOnJvb3QiLCAiUFVCIiwgIlNZUyIpOworICAgICAgcHVibGljSWQgPSBkb2NUeXBlLmdldFB1YmxpY0lkKCk7CisgICAgICBzeXN0ZW1JZCA9IGRvY1R5cGUuZ2V0U3lzdGVtSWQoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZG9jdW1lbnR0eXBlcHVibGljaWQwMSIsICJQVUIiLCBwdWJsaWNJZCk7CisgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50dHlwZXN5c3RlbWlkMDEiLCAiU1lTIiwgc3lzdGVtSWQpOworICAgICAgfQorCit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9FbGVtZW50R2V0QXR0cmlidXRlTlMuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9FbGVtZW50R2V0QXR0cmlidXRlTlMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YjM5MGY4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0VsZW1lbnRHZXRBdHRyaWJ1dGVOUy5qYXZhCkBAIC0wLDAgKzEsODYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CisKKworLyoqCisgKiAgICAgICBUaGUgbWV0aG9kIGdldEF0dHJpYnV0ZU5TIHJldHJpZXZlcyBhbiBhdHRyaWJ1dGUgdmFsdWUgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4KKyAqICAgICAgIFVzaW5nIHRoZSBnZXRBdHRyaWJ1dGVOb2RlTlMsIHJldHJlaXZlIGFuZCB2ZXJpZnkgdGhlIHZhbHVlIG9mIHRoZSBkZWZhdWx0CisgKiAgICAgICBhdHRyaWJ1dGUgbm9kZS4KKyAqCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxHZXRBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEdldEF0dHJOUzwvYT4KKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBFbGVtZW50R2V0QXR0cmlidXRlTlMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisvLyBBc3N1bWVzIHZhbGlkYXRpb24uCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0QXR0cmlidXRlTlMoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKy8vICAgICAgICBEb2N1bWVudCBkb2M7CisvLyAgICAgICAgRWxlbWVudCBlbGVtZW50OworLy8gICAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisvLyAgICAgICAgTm9kZUxpc3QgY2hpbGRMaXN0OworLy8gICAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworLy8KKy8vICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKy8vICAgICAgICBjaGlsZExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsCisvLyAgICAgICAgICAgICAgICAiZW1wbG95ZWUiKTsKKy8vICAgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGNoaWxkTGlzdC5pdGVtKDEpOworLy8gICAgICAgIGF0dHJWYWx1ZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlTlMobnVsbE5TLCAiZGVmYXVsdEF0dHIiKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRnZXRhdHRyaWJ1dGVuczAyIiwgImRlZmF1bHRWYWwiLCBhdHRyVmFsdWUpOworLy8gICAgfQorCit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9FbGVtZW50R2V0QXR0cmlidXRlTm9kZU5TLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRWxlbWVudEdldEF0dHJpYnV0ZU5vZGVOUy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYxNzkxYTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRWxlbWVudEdldEF0dHJpYnV0ZU5vZGVOUy5qYXZhCkBAIC0wLDAgKzEsMTIxIEBACitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5BdHRyOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSBtZXRob2QgZ2V0QXR0cmlidXRlTm9kZU5TIHJldHJpZXZlcyBhbiBBdHRyIG5vZGUgYnkgbG9jYWwgbmFtZSBhbmQKKyAqIG5hbWVzcGFjZSBVUkkuIENyZWF0ZSBhIG5ldyBlbGVtZW50IG5vZGUgYW5kIGFkZCAyIG5ldyBhdHRyaWJ1dGUgbm9kZXMgdG8gaXQKKyAqIHRoYXQgaGF2ZSB0aGUgc2FtZSBsb2NhbCBuYW1lIGJ1dCBkaWZmZXJlbnQgbmFtZXNwYWNlVVJJcyBhbmQgcHJlZml4ZXMuCisgKiBSZXRyaWV2ZSBhbiBhdHRyaWJ1dGUgdXNpbmcgbmFtZXNwYWNlIGFuZCBsb2NhbG5hbWUgYW5kIGNoZWNrIGl0cyB2YWx1ZSwgbmFtZQorICogYW5kIG5hbWVzcGFjZVVSSS4KKyAqCisgKiBAYXV0aG9yIElCTQorICogQGF1dGhvciBOZWlsIERlbGltYQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxHZXRBdE5vZGVOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsR2V0QXROb2RlTlM8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBFbGVtZW50R2V0QXR0cmlidXRlTm9kZU5TIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24yKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEF0dHJpYnV0ZU5vZGVOUzEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIEF0dHIgYXR0cmlidXRlMTsKKyAgICAgICAgQXR0ciBhdHRyaWJ1dGUyOworCisKKyAgICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgICAgU3RyaW5nIGF0dE5vZGVOYW1lOworICAgICAgICBTdHJpbmcgYXR0ckxvY2FsTmFtZTsKKyAgICAgICAgU3RyaW5nIGF0dHJOUzsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJuYW1lc3BhY2VVUkkiLCAicm9vdCIpOworICAgICAgICBhdHRyaWJ1dGUxID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vTGV2ZWwyIiwKKyAgICAgICAgICAgICAgICAibDI6YXR0Iik7CisgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZU5TKGF0dHJpYnV0ZTEpOworICAgICAgICBhdHRyaWJ1dGUyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vTGV2ZWwxIiwKKyAgICAgICAgICAgICAgICAiYXR0Iik7CisgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZU5TKGF0dHJpYnV0ZTIpOworICAgICAgICBhdHRyaWJ1dGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5vZGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL0xldmVsMiIsCisgICAgICAgICAgICAgICAgImF0dCIpOworICAgICAgICBhdHRyVmFsdWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICAgIGF0dHJOYW1lID0gYXR0cmlidXRlLmdldE5hbWUoKTsKKyAgICAgICAgYXR0Tm9kZU5hbWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgICAgYXR0ckxvY2FsTmFtZSA9IGF0dHJpYnV0ZS5nZXRMb2NhbE5hbWUoKTsKKyAgICAgICAgYXR0ck5TID0gYXR0cmlidXRlLmdldE5hbWVzcGFjZVVSSSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnMwMV9hdHRyVmFsdWUiLCAiIiwgYXR0clZhbHVlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50Z2V0YXR0cmlidXRlbm9kZW5zMDFfYXR0ck5hbWUiLCAibDI6YXR0IiwgYXR0ck5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRnZXRhdHRyaWJ1dGVub2RlbnMwMV9hdHRyTm9kZU5hbWUiLCAibDI6YXR0IiwKKyAgICAgICAgICAgICAgICBhdHROb2RlTmFtZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAxX2F0dHJMb2NhbE5hbWUiLCAiYXR0IiwKKyAgICAgICAgICAgICAgICBhdHRyTG9jYWxOYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50Z2V0YXR0cmlidXRlbm9kZW5zMDFfYXR0ck5zIiwKKyAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvRE9NL0xldmVsMiIsIGF0dHJOUyk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRBdHRyaWJ1dGVOb2RlTlMyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKworICAgICAgICBTdHJpbmcgYXR0clZhbHVlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoIm5hbWVzcGFjZVVSSSIsICJyb290Iik7CisgICAgICAgIGF0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL0xldmVsMiIsCisgICAgICAgICAgICAgICAgImwyOmF0dCIpOworICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5vZGVOUyhhdHRyaWJ1dGUpOworICAgICAgICBhdHRyaWJ1dGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5vZGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL0xldmVsMiIsCisgICAgICAgICAgICAgICAgImF0dCIpOworICAgICAgICBhdHRyVmFsdWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZWxlbWVudGdldGF0dHJpYnV0ZW5vZGVuczAyIiwgIiIsIGF0dHJWYWx1ZSk7CisgICAgfQorCisvLyBBc3N1bWVzIHZhbGlkYXRpb24uCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0QXR0cmlidXRlTm9kZU5TMygpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisvLyAgICAgICAgQXR0ciBhdHRyaWJ1dGU7CisvLyAgICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKy8vICAgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisvLyAgICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisvLworLy8gICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworLy8gICAgICAgIGNoaWxkTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwKKy8vICAgICAgICAgICAgICAgICJlbXBsb3llZSIpOworLy8gICAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgY2hpbGRMaXN0Lml0ZW0oMSk7CisvLyAgICAgICAgYXR0cmlidXRlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlTlMobnVsbE5TLCAiZGVmYXVsdEF0dHIiKTsKKy8vICAgICAgICBhdHRyVmFsdWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZVZhbHVlKCk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50Z2V0YXR0cmlidXRlbm9kZW5zMDMiLCAiZGVmYXVsdFZhbCIsIGF0dHJWYWx1ZSk7CisvLyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRWxlbWVudEdldEVsZW1lbnRzQnlUYWdOYW1lTlMuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9FbGVtZW50R2V0RWxlbWVudHNCeVRhZ05hbWVOUy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI1NjU3YTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRWxlbWVudEdldEVsZW1lbnRzQnlUYWdOYW1lTlMuamF2YQpAQCAtMCwwICsxLDk4IEBACitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBUaGUgbWV0aG9kIGdldEVsZW1lbnRzQnlUYWdOYW1lTlMgcmV0dXJucyBhIE5vZGVMaXN0IG9mIGFsbCB0aGUgRWxlbWVudHMgd2l0aAorICogYSBnaXZlbiBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJIGluIHRoZSBvcmRlciBpbiB3aGljaCB0aGV5IGFyZQorICogZW5jb3VudGVyZWQgaW4gYSBwcmVvcmRlciB0cmF2ZXJzYWwgb2YgdGhlIERvY3VtZW50IHRyZWUuIEludm9rZQorICogZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyBvbiB0aGUgZG9jdW1lbnRFbGVtZW50IHdpdGggdmFsdWVzIGZvciBuYW1lc3BhY2VVUkkKKyAqICcqJyBhbmQgbG9jYWxOYW1lICcqJy4gVmVyaWZ5IGlmIHRoaXMgcmV0dXJucyBhIG5vZGVMaXN0IG9mIDAgZWxlbWVudHMuCisgKgorICogQGF1dGhvciBJQk0KKyAqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQlROTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXRFbEJUTk5TPC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRWxlbWVudEdldEVsZW1lbnRzQnlUYWdOYW1lTlMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RWxlbWVudHNCeVRhZ05hbWVOUzEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudCA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBlbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioqIiwgIioiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVuczAyIiwgMCwgZWxlbWVudExpc3QKKyAgICAgICAgICAgICAgICAuZ2V0TGVuZ3RoKCkpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RWxlbWVudHNCeVRhZ05hbWVOUzQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIEVsZW1lbnQgY2hpbGQxOworICAgICAgICBFbGVtZW50IGNoaWxkMjsKKyAgICAgICAgRWxlbWVudCBjaGlsZDM7CisKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NIiwgInJvb3QiKTsKKyAgICAgICAgY2hpbGQxID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NL0xldmVsMSIsCisgICAgICAgICAgICAgICAgImRvbTpjaGlsZCIpOworICAgICAgICBjaGlsZDIgPSBkb2MuY3JlYXRlRWxlbWVudE5TKG51bGxOUywgImNoaWxkIik7CisgICAgICAgIGNoaWxkMyA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9MZXZlbDIiLAorICAgICAgICAgICAgICAgICJkb206Y2hpbGQiKTsKKyAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChjaGlsZDEpOworICAgICAgICBlbGVtZW50LmFwcGVuZENoaWxkKGNoaWxkMik7CisgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoY2hpbGQzKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBlbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lTlMobnVsbE5TLCAiY2hpbGQiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50Z2V0ZWxlbWVudHNieXRhZ25hbWVuczA0XzEiLCAxLCBlbGVtZW50TGlzdAorICAgICAgICAgICAgICAgIC5nZXRMZW5ndGgoKSk7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCIqIiwgImNoaWxkIik7CisgICAgICAgIGFzc2VydEVxdWFscygiZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwNF8yIiwgMywgZWxlbWVudExpc3QKKyAgICAgICAgICAgICAgICAuZ2V0TGVuZ3RoKCkpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RWxlbWVudHNCeVRhZ05hbWVOUzUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudCA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBlbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoCisgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cuYWx0YXZpc3RhLmNvbSIsICIqIik7CisgICAgICAgIGFzc2VydEVxdWFscygiZWxlbWVudGdldGVsZW1lbnRzYnl0YWduYW1lbnMwNSIsIDEsIGVsZW1lbnRMaXN0CisgICAgICAgICAgICAgICAgLmdldExlbmd0aCgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRWxlbWVudEhhc0F0dHJpYnV0ZS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0VsZW1lbnRIYXNBdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMTMyZmVmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0VsZW1lbnRIYXNBdHRyaWJ1dGUuamF2YQpAQCAtMCwwICsxLDk5IEBACitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5BdHRyOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSBtZXRob2QgaGFzQXR0cmlidXRlIHJldHVybnMgdHJ1ZSB3aGVuIGFuIGF0dHJpYnV0ZSB3aXRoIGEgZ2l2ZW4gbmFtZSBpcworICogc3BlY2lmaWVkIG9uIHRoaXMgZWxlbWVudCBvciBoYXMgYSBkZWZhdWx0IHZhbHVlLCBmYWxzZSBvdGhlcndpc2UgSW52b2tlIHRoZQorICogaGFzQXR0cmlidXRlIG1ldGhvZCB0byBjaGVjayBpZiB0aGUgZG9jdW1lbnRFbGVtZW50IGhhcyBhdHRyaWJ1dHJlcy4KKyAqCisgKiBAYXV0aG9yIElCTQorICogQGF1dGhvciBOZWlsIERlbGltYQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZUhhc0F0dHJzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZUhhc0F0dHJzPC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgRWxlbWVudEhhc0F0dHJpYnV0ZSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RIYXNBdHRyaWJ1dGUxKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBib29sZWFuIHN0YXRlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnQgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIHN0YXRlID0gZWxlbWVudC5oYXNBdHRyaWJ1dGUoIiIpOworICAgICAgICBhc3NlcnRGYWxzZSgiZWxlbWVudGhhc2F0dHJpYnV0ZTAxIiwgc3RhdGUpOworICAgIH0KKworLy8gQXNzdW1lcyB2YWxpZGF0aW9uLgorLy8gICAgcHVibGljIHZvaWQgdGVzdEhhc0F0dHJpYnV0ZTIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKy8vICAgICAgICBEb2N1bWVudCBkb2M7CisvLyAgICAgICAgRWxlbWVudCBlbGVtZW50OworLy8gICAgICAgIGJvb2xlYW4gc3RhdGU7CisvLyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisvLyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisvLyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDplbXBsb3llZSIpOworLy8gICAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKy8vICAgICAgICBhc3NlcnROb3ROdWxsKCJlbXBFbXBsb3llZU5vdE51bGwiLCBlbGVtZW50KTsKKy8vICAgICAgICBzdGF0ZSA9IGVsZW1lbnQuaGFzQXR0cmlidXRlKCJkZWZhdWx0QXR0ciIpOworLy8gICAgICAgIGFzc2VydFRydWUoImVsZW1lbnRoYXNhdHRyaWJ1dGUwMiIsIHN0YXRlKTsKKy8vICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzQXR0cmlidXRlMygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgICAgQXR0ciBhdHRyaWJ1dGU7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnQoImFkZHJlc3MiKTsKKyAgICAgICAgYXR0cmlidXRlID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZSgiZG9tZXN0aWMiKTsKKyAgICAgICAgc3RhdGUgPSBlbGVtZW50Lmhhc0F0dHJpYnV0ZSgiZG9tZXN0aWMiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoImVsZW1lbnRoYXNhdHRyaWJ1dGUwM19GYWxzZSIsIHN0YXRlKTsKKyAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlKGF0dHJpYnV0ZSk7CisgICAgICAgIHN0YXRlID0gZWxlbWVudC5oYXNBdHRyaWJ1dGUoImRvbWVzdGljIik7CisgICAgICAgIGFzc2VydFRydWUoImVsZW1lbnRoYXNhdHRyaWJ1dGUwM19UcnVlIiwgc3RhdGUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzQXR0cmlidXRlNCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgICAgQXR0ciBhdHRyaWJ1dGU7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnQoImFkZHJlc3MiKTsKKyAgICAgICAgYXR0cmlidXRlID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZSgiZG9tZXN0aWMiKTsKKyAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlKGF0dHJpYnV0ZSk7CisgICAgICAgIHN0YXRlID0gZWxlbWVudC5oYXNBdHRyaWJ1dGUoImRvbWVzdGljIik7CisgICAgICAgIGFzc2VydFRydWUoImVsZW1lbnRoYXNhdHRyaWJ1dGUwNCIsIHN0YXRlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRWxlbWVudEhhc0F0dHJpYnV0ZU5TLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRWxlbWVudEhhc0F0dHJpYnV0ZU5TLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWY4NGNiYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9FbGVtZW50SGFzQXR0cmlidXRlTlMuamF2YQpAQCAtMCwwICsxLDExNSBAQAorLyoKKyBUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCisgYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KKyBUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKyBDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCisgUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgUFVSUE9TRS4KKworIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyAqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKK2ltcG9ydCBvcmcudzNjLmRvbS5BdHRyOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSBtZXRob2QgaGFzQXR0cmlidXRlTlMgcmV0dXJucyB0cnVlIHdoZW4gYW4gYXR0cmlidXRlIHdpdGggYSBnaXZlbiBsb2NhbAorICogbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSBpcyBzcGVjaWZpZWQgb24gdGhpcyBlbGVtZW50IG9yIGhhcyBhIGRlZmF1bHQgdmFsdWUsCisgKiBmYWxzZSBvdGhlcndpc2UuCisgKgorICogUmV0cmVpdmUgdGhlIGZpcnN0IGVtcGxveWVlIGVsZW1lbnQgbm9kZS4gSW52b2tlIHRoZSBoYXNBdHRyaWJ1dGVOUyBtZXRob2QgdG8KKyAqIGNoZWNrIGlmIGl0IGhhcyB0aGUgeG1sbnMgYXR0cmlidXRlIHRoYXQgYmVsb25ncyB0byB0aGUgbmFtZXNwYWNlCisgKiBodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLy4KKyAqCisgKiBAYXV0aG9yIElCTQorICogQGF1dGhvciBOZWlsIERlbGltYQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxIYXNBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEhhc0F0dHJOUzwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEVsZW1lbnRIYXNBdHRyaWJ1dGVOUyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMigpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIF90ZXN0SGFzQXR0cmlidXRlTlMxKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBib29sZWFuIHN0YXRlOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiZW1wbG95ZWUiKTsKKyAgICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgICBzdGF0ZSA9IGVsZW1lbnQKKyAgICAgICAgICAgICAgICAuaGFzQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIiwgInhtbG5zIik7CisgICAgICAgIGFzc2VydFRydWUoImVsZW1lbnRoYXNhdHRyaWJ1dGVuczAxIiwgc3RhdGUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzQXR0cmlidXRlTlMyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBib29sZWFuIHN0YXRlOworICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00iLCAiYWRkcmVzcyIpOworICAgICAgICBhdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTSIsICJkb21lc3RpYyIpOworICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5vZGUoYXR0cmlidXRlKTsKKyAgICAgICAgc3RhdGUgPSBlbGVtZW50Lmhhc0F0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00iLCAiZG9tZXN0aWMiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaGFzRG9tZXN0aWNBdHRyIiwgc3RhdGUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzQXR0cmlidXRlTlMzKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBib29sZWFuIHN0YXRlOworICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKworICAgICAgICBTdHJpbmcgbnVsbE5TID0gbnVsbDsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00iLCAiYWRkcmVzcyIpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJjcmVhdGVFbGVtZW50Tm90TnVsbCIsIGVsZW1lbnQpOworICAgICAgICBhdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMobnVsbE5TLCAiZG9tZXN0aWMiKTsKKyAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlKGF0dHJpYnV0ZSk7CisgICAgICAgIHN0YXRlID0gZWxlbWVudC5oYXNBdHRyaWJ1dGVOUyhudWxsTlMsICJkb21lc3RpYyIpOworICAgICAgICBhc3NlcnRUcnVlKCJlbGVtZW50aGFzYXR0cmlidXRlbnMwMyIsIHN0YXRlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRWxlbWVudFJlbW92ZUF0dHJpYnV0ZU5TLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRWxlbWVudFJlbW92ZUF0dHJpYnV0ZU5TLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTUzNTA3MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9FbGVtZW50UmVtb3ZlQXR0cmlidXRlTlMuamF2YQpAQCAtMCwwICsxLDY4IEBACitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5BdHRyOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSBtZXRob2QgcmVtb3ZlQXR0cmlidXRlTlMgcmVtb3ZlcyBhbiBhdHRyaWJ1dGUgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlCisgKiBVUkkuIENyZWF0ZSBhIG5ldyBlbGVtZW50IGFuZCBhZGQgYSBuZXcgYXR0cmlidXRlIG5vZGUgdG8gaXQuIFJlbW92ZSB0aGUKKyAqIGF0dHJpYnV0ZSBub2RlIHVzaW5nIHRoZSByZW1vdmVBdHRyaWJ1dGVOb2RlTlMgbWV0aG9kLiBDaGVjayBpZiB0aGUgYXR0cmlidXRlCisgKiB3YXMgcmVtb3ZlIGJ5IGludm9raW5nIHRoZSBoYXNBdHRyaWJ1dGVOUyBtZXRob2Qgb24gdGhlIGVsZW1lbnQgYW5kIGNoZWNrIGlmCisgKiBpdCByZXR1cm5zIGZhbHNlLgorICoKKyAqIEBhdXRob3IgSUJNCisgKiBAYXV0aG9yIE5laWwgRGVsaW1hCisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFJlbUF0TlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFJlbUF0TlM8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBFbGVtZW50UmVtb3ZlQXR0cmlidXRlTlMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlQXR0cmlidXRlTlMoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICAgIEF0dHIgYXR0cmlidXRlOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTSIsICJlbGVtIik7CisgICAgICAgIGF0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygKKyAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvY3JlYXRlQXR0cmlidXRlTlMiLCAiYXR0ciIpOworICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5vZGVOUyhhdHRyaWJ1dGUpOworICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZU5TKAorICAgICAgICAgICAgICAgICJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9jcmVhdGVBdHRyaWJ1dGVOUyIsICJhdHRyIik7CisgICAgICAgIHN0YXRlID0gZWxlbWVudC5oYXNBdHRyaWJ1dGVOUygKKyAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvY3JlYXRlQXR0cmlidXRlTlMiLCAiYXR0ciIpOworICAgICAgICBhc3NlcnRGYWxzZSgiZWxlbWVudHJlbW92ZWF0dHJpYnV0ZW5zMDEiLCBzdGF0ZSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRWxlbWVudFNldEF0dHJpYnV0ZU5TLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRWxlbWVudFNldEF0dHJpYnV0ZU5TLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDUwZmQ0YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9FbGVtZW50U2V0QXR0cmlidXRlTlMuamF2YQpAQCAtMCwwICsxLDIxOCBAQAorcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkF0dHI7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogVGhlIG1ldGhvZCBzZXRBdHRyaWJ1dGVOUyBhZGRzIGEgbmV3IGF0dHJpYnV0ZS4gQ3JlYXRlIGEgbmV3IGVsZW1lbnQgYW5kIGFkZAorICogYSBuZXcgYXR0cmlidXRlIG5vZGUgdG8gaXQgdXNpbmcgdGhlIHNldEF0dHJpYnV0ZU5TIG1ldGhvZC4gQ2hlY2sgaWYgdGhlCisgKiBhdHRyaWJ1dGUgd2FzIGNvcnJlY3RseSBzZXQgYnkgaW52b2tpbmcgdGhlIGdldEF0dHJpYnV0ZU5vZGVOUyBtZXRob2QgYW5kCisgKiBjaGVja2luZyB0aGUgbm9kZU5hbWUgYW5kIG5vZGVWYWx1ZSBvZiB0aGUgcmV0dXJuZWQgbm9kZXMuCisgKgorICogQGF1dGhvciBJQk0KKyAqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdHRyTlM8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBFbGVtZW50U2V0QXR0cmlidXRlTlMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0QXR0cmlidXRlTlMxKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgICAgU3RyaW5nIGF0dHJOYW1lOworICAgICAgICBTdHJpbmcgYXR0clZhbHVlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00iLCAiZG9tOmVsZW0iKTsKKyAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3Qvc2V0QXR0cmlidXRlTlMiLAorICAgICAgICAgICAgICAgICJhdHRyIiwgInZhbHVlIik7CisgICAgICAgIGF0dHJpYnV0ZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlTm9kZU5TKAorICAgICAgICAgICAgICAgICJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9zZXRBdHRyaWJ1dGVOUyIsICJhdHRyIik7CisgICAgICAgIGF0dHJOYW1lID0gYXR0cmlidXRlLmdldE5vZGVOYW1lKCk7CisgICAgICAgIGF0dHJWYWx1ZSA9IGF0dHJpYnV0ZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50c2V0YXR0cmlidXRlbnMwMV9hdHRyTmFtZSIsICJhdHRyIiwgYXR0ck5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRzZXRhdHRyaWJ1dGVuczAxX2F0dHJWYWx1ZSIsICJ2YWx1ZSIsIGF0dHJWYWx1ZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRBdHRyaWJ1dGVOUzIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgU3RyaW5nIGF0dHJOYW1lOworICAgICAgICBTdHJpbmcgYXR0clZhbHVlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiYWRkcmVzcyIpOworICAgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L3NldEF0dHJpYnV0ZU5TIiwKKyAgICAgICAgICAgICAgICAidGhpczpzdHJlZXQiLCAiU2lsdmVyIFN0cmVldCIpOworICAgICAgICBhdHRyaWJ1dGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5vZGVOUygKKyAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3Qvc2V0QXR0cmlidXRlTlMiLCAic3RyZWV0Iik7CisgICAgICAgIGF0dHJOYW1lID0gYXR0cmlidXRlLmdldE5vZGVOYW1lKCk7CisgICAgICAgIGF0dHJWYWx1ZSA9IGF0dHJpYnV0ZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50c2V0YXR0cmlidXRlbnMwMl9hdHRyTmFtZSIsICJ0aGlzOnN0cmVldCIsCisgICAgICAgICAgICAgICAgYXR0ck5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRzZXRhdHRyaWJ1dGVuczAyX2F0dHJWYWx1ZSIsICJTaWx2ZXIgU3RyZWV0IiwKKyAgICAgICAgICAgICAgICBhdHRyVmFsdWUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0QXR0cmlidXRlTlMzKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6ZW1wbG95ZWUiKTsKKyAgICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgICBhc3NlcnROb3ROdWxsKCJlbXBFbXBsb3llZU5vdE51bGwiLCBlbGVtZW50KTsKKyAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvMSIsICJkZWZhdWx0QXR0ciIsCisgICAgICAgICAgICAgICAgImRlZmF1bHQxIik7CisgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0LzIiLCAiZGVmYXVsdEF0dHIiLAorICAgICAgICAgICAgICAgICJkZWZhdWx0MiIpOworICAgICAgICBhdHRyaWJ1dGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5vZGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvMSIsCisgICAgICAgICAgICAgICAgImRlZmF1bHRBdHRyIik7CisgICAgICAgIGF0dHJOYW1lID0gYXR0cmlidXRlLmdldE5vZGVOYW1lKCk7CisgICAgICAgIGF0dHJWYWx1ZSA9IGF0dHJpYnV0ZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50c2V0YXR0cmlidXRlbnMwM19hdHRyTmFtZSIsICJkZWZhdWx0QXR0ciIsCisgICAgICAgICAgICAgICAgYXR0ck5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRzZXRhdHRyaWJ1dGVuczAzX2F0dHJWYWx1ZSIsICJkZWZhdWx0MSIsIGF0dHJWYWx1ZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRBdHRyaWJ1dGVOUzQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lOworICAgICAgICBMaXN0PFN0cmluZz4gcXVhbGlmaWVkTmFtZXMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCIvIik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiLy8iKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCJcXCIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIjsiKTsKKyAgICAgICAgcXVhbGlmaWVkTmFtZXMuYWRkKCImIik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiKiIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIl1dIik7CisgICAgICAgIHF1YWxpZmllZE5hbWVzLmFkZCgiPiIpOworICAgICAgICBxdWFsaWZpZWROYW1lcy5hZGQoIjwiKTsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L0wyIiwKKyAgICAgICAgICAgICAgICAiZG9tOmVsZW0iKTsKKyAgICAgICAgZm9yIChpbnQgaW5kZXhOMTAwNTggPSAwOyBpbmRleE4xMDA1OCA8IHF1YWxpZmllZE5hbWVzLnNpemUoKTsgaW5kZXhOMTAwNTgrKykgeworICAgICAgICAgICAgcXVhbGlmaWVkTmFtZSA9IChTdHJpbmcpIHF1YWxpZmllZE5hbWVzLmdldChpbmRleE4xMDA1OCk7CisKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9MMiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVhbGlmaWVkTmFtZSwgInRlc3QiKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTlZBTElEX0NIQVJBQ1RFUl9FUlIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJlbGVtZW50c2V0YXR0cmlidXRlbnMwNCIsIHN1Y2Nlc3MpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRBdHRyaWJ1dGVOUzUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvTDIiLAorICAgICAgICAgICAgICAgICJkb206ZWxlbSIpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGxOUywgImRvbTpyb290IiwgInRlc3QiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJlbGVtZW50c2V0YXR0cmlidXRlbnMwNSIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRBdHRyaWJ1dGVOUzgoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NVGVzdC9sZXZlbDIiLAorICAgICAgICAgICAgICAgICJkb206ZWxlbSIpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET01UZXN0L2xldmVsMiIsCisgICAgICAgICAgICAgICAgICAgICAgICAieG1sbnMiLCAidGVzdCIpOworICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoImVsZW1lbnRzZXRhdHRyaWJ1dGVuczA4X0VycjEiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET01UZXN0L2xldmVsMiIsCisgICAgICAgICAgICAgICAgICAgICAgICAieG1sbnM6cm9vdCIsICJ0ZXN0Iik7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZWxlbWVudHNldGF0dHJpYnV0ZW5zMDhfRXJyMiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRBdHRyaWJ1dGVOU1VSSU51bGwoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gbnVsbDsKKworICAgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gImVtcDpxdWFsaWZpZWROYW1lIjsKKyAgICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgICAgTm9kZSB0ZXN0QWRkcjsKKyAgICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICAgICAgdGVzdEFkZHIgPSBlbGVtZW50TGlzdC5pdGVtKDApOworCisgICAgICAgICAgeworICAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgKChFbGVtZW50KSAvKk5vZGUgKi90ZXN0QWRkcikuc2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lLCAibmV3VmFsdWUiKTsKKyAgICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgICAgICB9CisgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vRWxlbWVudFNldEF0dHJpYnV0ZU5vZGVOUy5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0VsZW1lbnRTZXRBdHRyaWJ1dGVOb2RlTlMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOTJkYjk3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0VsZW1lbnRTZXRBdHRyaWJ1dGVOb2RlTlMuamF2YQpAQCAtMCwwICsxLDIzNCBAQAorLyoKKyBUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCisgYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KKyBUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKyBDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCisgUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgUFVSUE9TRS4KKworIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyAqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5BdHRyOworaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRW50aXR5UmVmZXJlbmNlOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRlc3RpbmcgRWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlM6IElmIGFuIGF0dHJpYnV0ZSB3aXRoIHRoYXQgbG9jYWwgbmFtZSBhbmQKKyAqIHRoYXQgbmFtZXNwYWNlIFVSSSBpcyBhbHJlYWR5IHByZXNlbnQgaW4gdGhlIGVsZW1lbnQsIGl0IGlzIHJlcGxhY2VkIGJ5IHRoZQorICogbmV3IG9uZS4gQ3JlYXRlIGEgbmV3IGVsZW1lbnQgYW5kIHR3byBuZXcgYXR0cmlidXRlIG5vZGVzIChpbiB0aGUgc2FtZQorICogbmFtZXNwYWNlIGFuZCBzYW1lIGxvY2FsTmFtZXMpLiBBZGQgdGhlIHR3byBuZXcgYXR0cmlidXRlIG5vZGVzIHRvIHRoZQorICogZWxlbWVudCBub2RlIHVzaW5nIHRoZSBzZXRBdHRyaWJ1dGVOb2RlTlMgbWV0aG9kLiBDaGVjayB0aGF0IG9ubHkgb25lCisgKiBhdHRyaWJ1dGUgaXMgYWRkZWQsIGNoZWNrIHRoZSB2YWx1ZSBvZiB0aGlzIGF0dHJpYnV0ZS4KKyAqCisgKiBAYXV0aG9yIElCTQorICogQGF1dGhvciBOZWlsIERlbGltYQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdE5vZGVOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXROb2RlTlM8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBFbGVtZW50U2V0QXR0cmlidXRlTm9kZU5TIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24yKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNldEF0dHJpYnV0ZU5vZGVOUzEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIEF0dHIgYXR0cmlidXRlMTsKKyAgICAgICAgQXR0ciBhdHRyaWJ1dGUyOworICAgICAgICBBdHRyIGF0dHJOb2RlOworICAgICAgICBTdHJpbmcgYXR0ck5hbWU7CisgICAgICAgIFN0cmluZyBhdHRyTlM7CisKKyAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisKKyAgICAgICAgaW50IGxlbmd0aDsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvTGV2ZWwyIiwKKyAgICAgICAgICAgICAgICAibmV3OmVsZW1lbnQiKTsKKyAgICAgICAgYXR0cmlidXRlMSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvYXR0MSIsCisgICAgICAgICAgICAgICAgInAxOmF0dCIpOworICAgICAgICBhdHRyaWJ1dGUyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9hdHQxIiwKKyAgICAgICAgICAgICAgICAicDI6YXR0Iik7CisgICAgICAgIGF0dHJpYnV0ZTIuc2V0VmFsdWUoInZhbHVlMiIpOworICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5vZGVOUyhhdHRyaWJ1dGUxKTsKKyAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMoYXR0cmlidXRlMik7CisgICAgICAgIGF0dHJOb2RlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlTlMoCisgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L2F0dDEiLCAiYXR0Iik7CisgICAgICAgIGF0dHJOYW1lID0gYXR0ck5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgICAgYXR0ck5TID0gYXR0ck5vZGUuZ2V0TmFtZXNwYWNlVVJJKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczAxX2F0dHJOYW1lIiwgInAyOmF0dCIsIGF0dHJOYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDFfYXR0ck5TIiwKKyAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvYXR0MSIsIGF0dHJOUyk7CisgICAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgbGVuZ3RoID0gKGludCkgYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJsZW5ndGgiLCAxLCBsZW5ndGgpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0QXR0cmlidXRlTm9kZU5TMigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50MjsKKyAgICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICAgIEF0dHIgYXR0cmlidXRlQ2xvbmVkOworICAgICAgICBBdHRyIG5ld0F0dHI7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBTdHJpbmcgYXR0ck5hbWU7CisgICAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwKKyAgICAgICAgICAgICAgICAiYWRkcmVzcyIpOworICAgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICAgIGF0dHJpYnV0ZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlTm9kZU5TKG51bGxOUywgInN0cmVldCIpOworICAgICAgICBhdHRyaWJ1dGVDbG9uZWQgPSAoQXR0cikgYXR0cmlidXRlLmNsb25lTm9kZSh0cnVlKTsKKyAgICAgICAgZWxlbWVudDIgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgICAgbmV3QXR0ciA9IGVsZW1lbnQyLnNldEF0dHJpYnV0ZU5vZGVOUyhhdHRyaWJ1dGVDbG9uZWQpOworICAgICAgICBhdHRyTmFtZSA9IG5ld0F0dHIuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgICAgYXR0clZhbHVlID0gbmV3QXR0ci5nZXROb2RlVmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDJfYXR0ck5hbWUiLCAic3RyZWV0IiwgYXR0ck5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVsZW1lbnRzZXRhdHRyaWJ1dGVub2RlbnMwMl9hdHRyVmFsdWUiLCAiWWVzIiwgYXR0clZhbHVlKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFNldEF0dHJpYnV0ZU5vZGVOUzMoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGVsZW1lbnQxOworICAgICAgICBFbGVtZW50IGVsZW1lbnQyOworICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLAorICAgICAgICAgICAgICAgICJhZGRyZXNzIik7CisgICAgICAgIGVsZW1lbnQxID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICAgIGF0dHJpYnV0ZSA9IGVsZW1lbnQxLmdldEF0dHJpYnV0ZU5vZGVOUyhudWxsTlMsICJzdHJlZXQiKTsKKyAgICAgICAgZWxlbWVudDIgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgyKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZWxlbWVudDIuc2V0QXR0cmlidXRlTm9kZU5TKGF0dHJpYnV0ZSk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVVNFX0FUVFJJQlVURV9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczAzIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFNldEF0dHJpYnV0ZU5vZGVOUzQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGVsZW1lbnQxOworICAgICAgICBFbGVtZW50IGVsZW1lbnQyOworICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudDEgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJlbGVtMSIpOworICAgICAgICBlbGVtZW50MiA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgImVsZW0yIik7CisgICAgICAgIGF0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLCAiYXR0ciIpOworICAgICAgICBlbGVtZW50MS5zZXRBdHRyaWJ1dGVOb2RlTlMoYXR0cmlidXRlKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZWxlbWVudDIuc2V0QXR0cmlidXRlTm9kZU5TKGF0dHJpYnV0ZSk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVVNFX0FUVFJJQlVURV9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZWxlbWVudHNldGF0dHJpYnV0ZW5vZGVuczA0Iiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFNldEF0dHJpYnV0ZU5vZGVOUzUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBEb2N1bWVudCBkb2NBbHQ7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgQXR0ciBhdHRyaWJ1dGU7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvY0FsdCA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLCAiZWxlbTEiKTsKKyAgICAgICAgYXR0cmlidXRlID0gZG9jQWx0LmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsCisgICAgICAgICAgICAgICAgImF0dHIiKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMoYXR0cmlidXRlKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X1dST05HX0RPQ1VNRU5UX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIF90ZXN0U2V0QXR0cmlidXRlTm9kZU5TNigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICAgIEF0dHIgYXR0cmlidXRlMjsKKyAgICAgICAgRW50aXR5UmVmZXJlbmNlIGVudFJlZjsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJlbGVtMSIpOworICAgICAgICBhdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgImF0dHIiKTsKKyAgICAgICAgZW50UmVmID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworICAgICAgICBhdHRyaWJ1dGUuYXBwZW5kQ2hpbGQoZW50UmVmKTsKKyAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMoYXR0cmlidXRlKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBlbnRSZWYuZ2V0Q2hpbGROb2RlcygpOworICAgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIGF0dHJpYnV0ZTIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwKKyAgICAgICAgICAgICAgICAiYXR0cjIiKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMoYXR0cmlidXRlMik7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJlbGVtZW50c2V0YXR0cmlidXRlbm9kZW5zMDYiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0dldEF0dHJpYnV0ZU5TLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vR2V0QXR0cmlidXRlTlMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNTViNzVjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0dldEF0dHJpYnV0ZU5TLmphdmEKQEAgLTAsMCArMSwxNTcgQEAKKy8qCisgVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorIGFuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCisgVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisgQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCisgUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgUFVSUE9TRS4KKworIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyAqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5BdHRyOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSAiZ2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSkiIG1ldGhvZCByZXRyaWV2ZXMgYW4gYXR0cmlidXRlCisgKiB2YWx1ZSBieSBsb2NhbCBuYW1lIGFuZCBOYW1lc3BhY2VVUkkuCisgKgorICogUmV0cmlldmUgdGhlIGZpcnN0ICJlbXA6YWRkcmVzcyIgZWxlbWVudC4gVGhlIHZhbHVlIHJldHVybmVkIGJ5IHRoZQorICogImdldEF0dHJpYnV0ZU5TKCkiIG1ldGhvZCBzaG91bGQgYmUgdGhlIHZhbHVlICJESVNUUklDVCIgc2luY2UgdGhlIGF0dHJpYnV0ZQorICogaGFzIGEgZGVmYXVsdCB2YWx1ZS4KKyAqCisgKiBAYXV0aG9yIE5JU1QKKyAqIEBhdXRob3IgTWFyeSBCcmFkeQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxHZXRBdHRyTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEdldEF0dHJOUzwvYT4KKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzOCI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzODwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEdldEF0dHJpYnV0ZU5TIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24yKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgICovCisvLyBBc3N1bWVzIHZhbGlkYXRpb24uCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0QXR0cmlidXRlTlMxKCkgdGhyb3dzIFRocm93YWJsZSB7CisvLyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5pc3QuZ292IjsKKy8vICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gImRpc3RyaWN0IjsKKy8vCisvLyAgICAgICAgRG9jdW1lbnQgZG9jOworLy8gICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworLy8gICAgICAgIEVsZW1lbnQgdGVzdEFkZHI7CisvLyAgICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKy8vICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKy8vICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmFkZHJlc3MiKTsKKy8vICAgICAgICB0ZXN0QWRkciA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworLy8gICAgICAgIGF0dHJWYWx1ZSA9IHRlc3RBZGRyLmdldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImF0dHJWYWx1ZSIsICJESVNUUklDVCIsIGF0dHJWYWx1ZSk7CisvLyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldEF0dHJpYnV0ZU5TMigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cubmlzdC5nb3YiOworICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gImRpc3RyaWN0IjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiZW1wOmRpc3RyaWN0IjsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBBdHRyIG5ld0F0dHJpYnV0ZTsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIEVsZW1lbnQgdGVzdEFkZHI7CisKKyAgICAgICAgU3RyaW5nIGF0dHJWYWx1ZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIG5ld0F0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmFkZHJlc3MiKTsKKyAgICAgICAgdGVzdEFkZHIgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkck5vdE51bGwiLCB0ZXN0QWRkcik7CisgICAgICAgIHRlc3RBZGRyLnNldEF0dHJpYnV0ZU5vZGVOUyhuZXdBdHRyaWJ1dGUpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmFkZHJlc3MiKTsKKyAgICAgICAgdGVzdEFkZHIgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgICAgYXR0clZhbHVlID0gdGVzdEFkZHIuZ2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRocm93X0VxdWFscyIsICIiLCBhdHRyVmFsdWUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0QXR0cmlidXRlTlMzKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5uaXN0LmdvdiI7CisgICAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSAiZG9tZXN0aWMiOworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBFbGVtZW50IHRlc3RBZGRyOworICAgICAgICBTdHJpbmcgYXR0clZhbHVlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICAgIHRlc3RBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoImVtcEFkZHJOb3ROdWxsIiwgdGVzdEFkZHIpOworICAgICAgICB0ZXN0QWRkci5yZW1vdmVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7CisgICAgICAgIGF0dHJWYWx1ZSA9IHRlc3RBZGRyLmdldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0aHJvd19FcXVhbHMiLCAiIiwgYXR0clZhbHVlKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldEF0dHJpYnV0ZU5TNCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cubmlzdC5nb3YiOworICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gImJsYW5rIjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiZW1wOmJsYW5rIjsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworCisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBFbGVtZW50IHRlc3RBZGRyOworCisgICAgICAgIFN0cmluZyBhdHRyVmFsdWU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBkb2MuY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICAgIHRlc3RBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoImVtcEFkZHJOb3ROdWxsIiwgdGVzdEFkZHIpOworICAgICAgICB0ZXN0QWRkci5zZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsICJOZXdWYWx1ZSIpOworICAgICAgICBhdHRyVmFsdWUgPSB0ZXN0QWRkci5nZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7CisgICAgICAgIGFzc2VydEVxdWFscygidGhyb3dfRXF1YWxzIiwgIk5ld1ZhbHVlIiwgYXR0clZhbHVlKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldEF0dHJpYnV0ZU5TNSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBFbGVtZW50IHRlc3RBZGRyOworICAgICAgICBTdHJpbmcgYXR0clZhbHVlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICAgIHRlc3RBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoImVtcEFkZHJOb3ROdWxsIiwgdGVzdEFkZHIpOworICAgICAgICBhdHRyVmFsdWUgPSB0ZXN0QWRkci5nZXRBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJkb21lc3RpYyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImF0dHJWYWx1ZSIsICJZZXMiLCBhdHRyVmFsdWUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9HZXRBdHRyaWJ1dGVOb2RlTlMuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9HZXRBdHRyaWJ1dGVOb2RlTlMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YjVjNDRjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0dldEF0dHJpYnV0ZU5vZGVOUy5qYXZhCkBAIC0wLDAgKzEsMTAzIEBACisvKgorIFRoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKKyBhbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorIFRoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworIENvcHlyaWdodCAoYykgMjAwMS0yMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbAorIFJpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorIFBVUlBPU0UuCisKKyBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisgKi8KKworcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CitpbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBUaGUgImdldEF0dHJpYnV0ZU5vZGVOUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKSIgbWV0aG9kIHJldHJpZXZlcyBhbgorICogYXR0cmlidXRlIG5vZGUgYnkgbG9jYWwgbmFtZSBhbmQgTmFtZXNwYWNlVVJJLgorICoKKyAqIFJldHJpZXZlIHRoZSBmaXJzdCBlbXA6YWRkcmVzcyBlbGVtZW50IG5vZGUuIFRoZSBnZXRBdHRyaWJ1dGVOb2RlTlMgbWV0aG9kCisgKiByZXR1cm5zIGFuIEF0dHIgbm9kZSwgdGhlICJ2YWx1ZSIgY2FuIGJlIGV4YW1pbmVkIHRvIGVuc3VyZSB0aGUgcHJvcGVyCisgKiBhdHRyaWJ1dGUgbm9kZSB3YXMgcmV0cmlldmVkLiBUaGlzIGF0dHJpYnV0ZSB2YWx1ZSBzaG91bGQgYmUgbnVsbCBzaW5jZSB0aGVyZQorICogaXMgbm8gc3VjaCBhdHRyaWJ1dGUuCisgKgorICogQGF1dGhvciBOSVNUCisgKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsR2V0QXROb2RlTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEdldEF0Tm9kZU5TPC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgR2V0QXR0cmlidXRlTm9kZU5TIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24yKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEF0dHJpYnV0ZU5vZGVOUzEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5pc3QuZ292IjsKKyAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9ICJpbnZhbGlkbG9jYWxuYW1lIjsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgRWxlbWVudCB0ZXN0QWRkcjsKKyAgICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmFkZHJlc3MiKTsKKyAgICAgICAgdGVzdEFkZHIgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkck5vdE51bGwiLCB0ZXN0QWRkcik7CisgICAgICAgIGF0dHJpYnV0ZSA9IHRlc3RBZGRyLmdldEF0dHJpYnV0ZU5vZGVOUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7CisgICAgICAgIGFzc2VydE51bGwoInRocm93X051bGwiLCBhdHRyaWJ1dGUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0QXR0cmlidXRlTm9kZU5TMigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBFbGVtZW50IHRlc3RBZGRyOworICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgICAgU3RyaW5nIGF0dHJOYW1lOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICAgIHRlc3RBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoImVtcEFkZHJOb3ROdWxsIiwgdGVzdEFkZHIpOworICAgICAgICBhdHRyaWJ1dGUgPSB0ZXN0QWRkci5nZXRBdHRyaWJ1dGVOb2RlTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLAorICAgICAgICAgICAgICAgICJkb21lc3RpYyIpOworICAgICAgICBhdHRyTmFtZSA9IGF0dHJpYnV0ZS5nZXROb2RlTmFtZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImF0dHJOYW1lIiwgImVtcDpkb21lc3RpYyIsIGF0dHJOYW1lKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vR2V0RWxlbWVudEJ5SWQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9HZXRFbGVtZW50QnlJZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI0OWRmNjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vR2V0RWxlbWVudEJ5SWQuamF2YQpAQCAtMCwwICsxLDkwIEBACisvKgorIFRoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKKyBhbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorIFRoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworIENvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbAorIFJpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorIFBVUlBPU0UuCisKKyBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisgKi8KKworcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogVGhlICJnZXRFbGVtZW50QnlJZChlbGVtZW50SWQpIiBtZXRob2QgZm9yIGEgRG9jdW1lbnQgc2hvdWxkIHJldHVybiBhbgorICogZWxlbWVudCB3aG9zZSBJRCBtYXRjaGVzIGVsZW1lbnRJZC4KKyAqCisgKiBJbnZva2UgbWV0aG9kIGdldEVsZW1lbnRCeUlkKGVsZW1lbnRJZCkgb24gdGhpcyBkb2N1bWVudCB3aXRoIGVsZW1lbnRJZAorICogZXF1YWxzICJDQU5BREEiLiBNZXRob2Qgc2hvdWxkIHJldHVybiBhbiBlbGVtZW50IHdob3NlIHRhZyBuYW1lIGlzCisgKiAiZW1wOmFkZHJlc3MiLgorICoKKyAqIEBhdXRob3IgTklTVAorICogQGF1dGhvciBNYXJ5IEJyYWR5CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC0xMDQ2ODI4MTUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC0xMDQ2ODI4MTU8L2E+CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0zODMiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0zODM8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBHZXRFbGVtZW50QnlJZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworLy8gQXNzdW1lcyB2YWxpZGF0aW9uLgorLy8gICAgcHVibGljIHZvaWQgdGVzdEdldEVsZW1lbnRCeUlkMSgpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisvLyAgICAgICAgU3RyaW5nIHRhZ25hbWU7CisvLyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisvLyAgICAgICAgZWxlbWVudCA9IGRvYy5nZXRFbGVtZW50QnlJZCgiQ0FOQURBIik7CisvLyAgICAgICAgdGFnbmFtZSA9IGVsZW1lbnQuZ2V0VGFnTmFtZSgpOworLy8gICAgICAgIGFzc2VydEVxdWFscygidGhyb3dfRXF1YWxzIiwgImVtcDphZGRyZXNzIiwgdGFnbmFtZSk7CisvLyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldEVsZW1lbnRCeUlkMigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnQgPSBkb2MuZ2V0RWxlbWVudEJ5SWQoIkNhbmN1biIpOworICAgICAgICBhc3NlcnROdWxsKCJ0aHJvd19OdWxsIiwgZWxlbWVudCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0dldEVsZW1lbnRzQnlUYWdOYW1lTlMuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9HZXRFbGVtZW50c0J5VGFnTmFtZU5TLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTlkYzgyNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9HZXRFbGVtZW50c0J5VGFnTmFtZU5TLmphdmEKQEAgLTAsMCArMSwyOTEgQEAKKy8qCisgVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorIGFuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCisgVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisgQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbAorIFJpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorIFBVUlBPU0UuCisKKyBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisgKi8KKworcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogVGhlICJnZXRFbGVtZW50c0J5VGFnTmFtZU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpIiBtZXRob2QgZm9yIGEgRG9jdW1lbnQKKyAqIHNob3VsZCByZXR1cm4gYSBuZXcgTm9kZUxpc3Qgb2YgYWxsIEVsZW1lbnRzIHRoYXQgaGF2ZSBhIG5hbWVzcGFjZSB3aGVuIGxvY2FsCisgKiBuYW1lIGlzIHNwZWNpZmllZCBhcyAnICcuCisgKgorICogSW52b2tlIG1ldGhvZCBnZXRFbGVtZW50c0J5VGFnTmFtZU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpIG9uIHRoaXMgZG9jdW1lbnQKKyAqIHdpdGggbmFtZXNwYWNlVVJJIGFuZCBsb2NhbE5hbWUgYXMgIiAiLiBNZXRob2Qgc2hvdWxkIHJldHVybiBhIG5ldyBOb2RlTGlzdAorICogb2YgMzcgZWxlbWVudHMuCisgKgorICogQGF1dGhvciBOSVNUCisgKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldEVsQlROTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXRFbEJUTk5TPC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgR2V0RWxlbWVudHNCeVRhZ05hbWVOUyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRFbGVtZW50c0J5VGFnTmFtZU5TMSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gIioiOworICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gIioiOworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IG5ld0xpc3Q7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBuZXdMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQ6IFdhcyAzNywgYnV0IHRoYXQgYXNzdW1lZCB2YWxpZGF0aW9uLgorICAgICAgICBhc3NlcnRFcXVhbHMoInRocm93X1NpemUiLCAzNiwgbmV3TGlzdC5nZXRMZW5ndGgoKSk7CisgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldEVsZW1lbnRzQnlUYWdOYW1lTlMyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgbmV3TGlzdDsKKyAgICAgICAgRWxlbWVudCBuZXdFbGVtZW50OworICAgICAgICBTdHJpbmcgcHJlZml4OworICAgICAgICBTdHJpbmcgbG5hbWU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBuZXdMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiZW1wbG95ZWUiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbXBsb3llZUNvdW50IiwgNSwgbmV3TGlzdC5nZXRMZW5ndGgoKSk7CisgICAgICAgIG5ld0VsZW1lbnQgPSAoRWxlbWVudCkgbmV3TGlzdC5pdGVtKDMpOworICAgICAgICBwcmVmaXggPSBuZXdFbGVtZW50LmdldFByZWZpeCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoInByZWZpeCIsICJlbXAiLCBwcmVmaXgpOworICAgICAgICBsbmFtZSA9IG5ld0VsZW1lbnQuZ2V0TG9jYWxOYW1lKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibG5hbWUiLCAiZW1wbG95ZWUiLCBsbmFtZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRFbGVtZW50c0J5VGFnTmFtZU5TMygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBOb2RlIGNoaWxkOworICAgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgICBMaXN0PFN0cmluZz4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisKKyAgICAgICAgTGlzdDxTdHJpbmc+IGV4cGVjdGVkUmVzdWx0ID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZW1wbG95ZWUiKTsKKyAgICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJlbXBsb3llZUlkIik7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgibmFtZSIpOworICAgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoInBvc2l0aW9uIik7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgic2FsYXJ5Iik7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZ2VuZGVyIik7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiYWRkcmVzcyIpOworICAgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcDplbXBsb3llZSIpOworICAgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcDplbXBsb3llZUlkIik7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZW1wOnBvc2l0aW9uIik7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZW1wOnNhbGFyeSIpOworICAgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcDpnZW5kZXIiKTsKKyAgICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJlbXA6YWRkcmVzcyIpOworICAgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImFkZHJlc3MiKTsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICIqIik7CisgICAgICAgIGZvciAoaW50IGluZGV4TjEwMDc2ID0gMDsgaW5kZXhOMTAwNzYgPCBlbGVtZW50TGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwNzYrKykgeworICAgICAgICAgICAgY2hpbGQgPSAoTm9kZSkgZWxlbWVudExpc3QuaXRlbShpbmRleE4xMDA3Nik7CisgICAgICAgICAgICBjaGlsZE5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgICAgICAgcmVzdWx0LmFkZChjaGlsZE5hbWUpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygibm9kZU5hbWVzIiwgZXhwZWN0ZWRSZXN1bHQsIHJlc3VsdCk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRFbGVtZW50c0J5VGFnTmFtZU5TNCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBOb2RlIGNoaWxkOworICAgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgICBMaXN0PFN0cmluZz4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisKKyAgICAgICAgTGlzdDxTdHJpbmc+IGV4cGVjdGVkUmVzdWx0ID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiYWRkcmVzcyIpOworICAgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImFkZHJlc3MiKTsKKyAgICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJhZGRyZXNzIik7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZW1wOmFkZHJlc3MiKTsKKyAgICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJhZGRyZXNzIik7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiYWRkcmVzcyIpOworICAgICAgICBmb3IgKGludCBpbmRleE4xMDA1OSA9IDA7IGluZGV4TjEwMDU5IDwgZWxlbWVudExpc3QuZ2V0TGVuZ3RoKCk7IGluZGV4TjEwMDU5KyspIHsKKyAgICAgICAgICAgIGNoaWxkID0gKE5vZGUpIGVsZW1lbnRMaXN0Lml0ZW0oaW5kZXhOMTAwNTkpOworICAgICAgICAgICAgY2hpbGROYW1lID0gY2hpbGQuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgICAgICAgIHJlc3VsdC5hZGQoY2hpbGROYW1lKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lcyIsIGV4cGVjdGVkUmVzdWx0LCByZXN1bHQpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RWxlbWVudHNCeVRhZ05hbWVOUzUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5pc3QuZ292IjsKKyAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9ICJub21hdGNoIjsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRocm93X1NpemUiLCAwLCBlbGVtZW50TGlzdC5nZXRMZW5ndGgoKSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRFbGVtZW50c0J5VGFnTmFtZU5TNigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5ub21hdGNoLmNvbSIsCisgICAgICAgICAgICAgICAgImFkZHJlc3MiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJtYXRjaFNpemUiLCAwLCBlbGVtZW50TGlzdC5nZXRMZW5ndGgoKSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRFbGVtZW50c0J5VGFnTmFtZU5TNygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsCisgICAgICAgICAgICAgICAgImFkZHJlc3MiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhZGRyZXNzZXMiLCAzLCBlbGVtZW50TGlzdC5nZXRMZW5ndGgoKSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRFbGVtZW50c0J5VGFnTmFtZU5TOCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEVsZW1lbnQgZG9jRWxlbTsKKyAgICAgICAgTm9kZUxpc3QgbmV3TGlzdDsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvY0VsZW0gPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIG5ld0xpc3QgPSBkb2NFbGVtLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiKiIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImxpc3RTaXplIiwgMzUsIG5ld0xpc3QuZ2V0TGVuZ3RoKCkpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RWxlbWVudHNCeVRhZ05hbWVOUzkoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBuZXdMaXN0OworICAgICAgICBFbGVtZW50IG5ld0VsZW1lbnQ7CisgICAgICAgIFN0cmluZyBwcmVmaXg7CisgICAgICAgIFN0cmluZyBsbmFtZTsKKyAgICAgICAgRWxlbWVudCBkb2NFbGVtOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZG9jRWxlbSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgbmV3TGlzdCA9IGRvY0VsZW0uZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJlbXBsb3llZSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVtcGxveWVlQ291bnQiLCA1LCBuZXdMaXN0LmdldExlbmd0aCgpKTsKKyAgICAgICAgbmV3RWxlbWVudCA9IChFbGVtZW50KSBuZXdMaXN0Lml0ZW0oMyk7CisgICAgICAgIHByZWZpeCA9IG5ld0VsZW1lbnQuZ2V0UHJlZml4KCk7CisgICAgICAgIGFzc2VydEVxdWFscygicHJlZml4IiwgImVtcCIsIHByZWZpeCk7CisgICAgICAgIGxuYW1lID0gbmV3RWxlbWVudC5nZXRMb2NhbE5hbWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJsbmFtZSIsICJlbXBsb3llZSIsIGxuYW1lKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldEVsZW1lbnRzQnlUYWdOYW1lTlMxMCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEVsZW1lbnQgZG9jRWxlbTsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIE5vZGUgY2hpbGQ7CisgICAgICAgIFN0cmluZyBjaGlsZE5hbWU7CisgICAgICAgIExpc3Q8U3RyaW5nPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKworICAgICAgICBMaXN0PFN0cmluZz4gZXhwZWN0ZWRSZXN1bHQgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJlbXBsb3llZSIpOworICAgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcGxveWVlSWQiKTsKKyAgICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJuYW1lIik7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgicG9zaXRpb24iKTsKKyAgICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJzYWxhcnkiKTsKKyAgICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJnZW5kZXIiKTsKKyAgICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJhZGRyZXNzIik7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZW1wOmVtcGxveWVlIik7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZW1wOmVtcGxveWVlSWQiKTsKKyAgICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJlbXA6cG9zaXRpb24iKTsKKyAgICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJlbXA6c2FsYXJ5Iik7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZW1wOmdlbmRlciIpOworICAgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVtcDphZGRyZXNzIik7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiYWRkcmVzcyIpOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBkb2NFbGVtID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvY0VsZW0KKyAgICAgICAgICAgICAgICAuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICIqIik7CisgICAgICAgIGZvciAoaW50IGluZGV4TjEwMDdFID0gMDsgaW5kZXhOMTAwN0UgPCBlbGVtZW50TGlzdC5nZXRMZW5ndGgoKTsgaW5kZXhOMTAwN0UrKykgeworICAgICAgICAgICAgY2hpbGQgPSAoTm9kZSkgZWxlbWVudExpc3QuaXRlbShpbmRleE4xMDA3RSk7CisgICAgICAgICAgICBjaGlsZE5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworICAgICAgICAgICAgcmVzdWx0LmFkZChjaGlsZE5hbWUpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygibm9kZU5hbWVzIiwgZXhwZWN0ZWRSZXN1bHQsIHJlc3VsdCk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRFbGVtZW50c0J5VGFnTmFtZU5TMTEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGRvY0VsZW07CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBOb2RlIGNoaWxkOworICAgICAgICBTdHJpbmcgY2hpbGROYW1lOworICAgICAgICBMaXN0PFN0cmluZz4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisKKyAgICAgICAgTGlzdDxTdHJpbmc+IGV4cGVjdGVkUmVzdWx0ID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiYWRkcmVzcyIpOworICAgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImFkZHJlc3MiKTsKKyAgICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJhZGRyZXNzIik7CisgICAgICAgIGV4cGVjdGVkUmVzdWx0LmFkZCgiZW1wOmFkZHJlc3MiKTsKKyAgICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJhZGRyZXNzIik7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvY0VsZW0gPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jRWxlbS5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCIqIiwgImFkZHJlc3MiKTsKKyAgICAgICAgZm9yIChpbnQgaW5kZXhOMTAwNUUgPSAwOyBpbmRleE4xMDA1RSA8IGVsZW1lbnRMaXN0LmdldExlbmd0aCgpOyBpbmRleE4xMDA1RSsrKSB7CisgICAgICAgICAgICBjaGlsZCA9IChOb2RlKSBlbGVtZW50TGlzdC5pdGVtKGluZGV4TjEwMDVFKTsKKyAgICAgICAgICAgIGNoaWxkTmFtZSA9IGNoaWxkLmdldE5vZGVOYW1lKCk7CisgICAgICAgICAgICByZXN1bHQuYWRkKGNoaWxkTmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTmFtZXMiLCBleHBlY3RlZFJlc3VsdCwgcmVzdWx0KTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldEVsZW1lbnRzQnlUYWdOYW1lTlMxMigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEVsZW1lbnQgZG9jRWxlbTsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBkb2NFbGVtID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvY0VsZW0uZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsCisgICAgICAgICAgICAgICAgIm5vbWF0Y2giKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJzaXplIiwgMCwgZWxlbWVudExpc3QuZ2V0TGVuZ3RoKCkpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0RWxlbWVudHNCeVRhZ05hbWVOUzEzKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRWxlbWVudCBkb2NFbGVtOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvY0VsZW0gPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jRWxlbS5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5vbWF0Y2guY29tIiwKKyAgICAgICAgICAgICAgICAiYWRkcmVzcyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm1hdGNoU2l6ZSIsIDAsIGVsZW1lbnRMaXN0LmdldExlbmd0aCgpKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldEVsZW1lbnRzQnlUYWdOYW1lTlMxNCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEVsZW1lbnQgZG9jRWxlbTsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBkb2NFbGVtID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvY0VsZW0uZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsCisgICAgICAgICAgICAgICAgImFkZHJlc3MiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhZGRyZXNzZXMiLCAzLCBlbGVtZW50TGlzdC5nZXRMZW5ndGgoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0dldE5hbWVkSXRlbU5TLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vR2V0TmFtZWRJdGVtTlMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MGMzYjUzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0dldE5hbWVkSXRlbU5TLmphdmEKQEAgLTAsMCArMSwxMTcgQEAKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSAiZ2V0TmFtZWRJdGVtTlMobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSkiIG1ldGhvZCBmb3IgYSBOYW1lZE5vZGVNYXAgc2hvdWxkCisgKiByZXR1cm4gYSBub2RlIHNwZWNpZmllZCBieSBsb2NhbE5hbWUgYW5kIG5hbWVzcGFjZVVSSQorICoKKyAqIFJldHJpZXZlIGEgbGlzdCBvZiBlbGVtZW50cyB3aXRoIHRhZyBuYW1lICJhZGRyZXNzIi4gQWNjZXNzIHRoZSBzZWNvbmQKKyAqIGVsZW1lbnQgZnJvbSB0aGUgbGlzdCBhbmQgZ2V0IGl0cyBhdHRyaWJ1dGVzLiBUcnkgdG8gcmV0cmlldmUgdGhlIGF0dHJpYnV0ZQorICogbm9kZSB3aXRoIGxvY2FsIG5hbWUgImRvbWVzdGljIiBhbmQgbmFtZXNwYWNlIHVyaSAiaHR0cDovL3d3dy51c2EuY29tIiB3aXRoCisgKiBtZXRob2QgZ2V0TmFtZWRJdGVtTlMobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSkuCisgKgorICogQGF1dGhvciBOSVNUCisgKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1GNjhEMDk1PC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgR2V0TmFtZWRJdGVtTlMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TmFtZWRJdGVtTlMxKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgICAgQXR0ciBkb21lc3RpY0F0dHI7CisgICAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICAgIHRlc3RFbXBsb3llZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0RW1wbG95ZWUuZ2V0QXR0cmlidXRlcygpOworICAgICAgICBkb21lc3RpY0F0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW1OUygiaHR0cDovL3d3dy51c2EuY29tIiwKKyAgICAgICAgICAgICAgICAiZG9tZXN0aWMiKTsKKyAgICAgICAgYXR0ck5hbWUgPSBkb21lc3RpY0F0dHIuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyTmFtZSIsICJkbXN0Yzpkb21lc3RpYyIsIGF0dHJOYW1lKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldE5hbWVkSXRlbU5TMigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cudXNhLmNvbSI7CisgICAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSAiZG9tZXN0IjsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgTm9kZSB0ZXN0RW1wbG95ZWU7CisgICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgICBBdHRyIG5ld0F0dHI7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgICB0ZXN0RW1wbG95ZWUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgICBhdHRyaWJ1dGVzID0gdGVzdEVtcGxveWVlLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgbmV3QXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgidGhyb3dfTnVsbCIsIG5ld0F0dHIpOworICAgIH0KKworLy8gQXNzdW1lcyB2YWxpZGF0aW9uLgorLy8gICAgcHVibGljIHZvaWQgdGVzdEdldE5hbWVkSXRlbU5TMygpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKy8vICAgICAgICBOYW1lZE5vZGVNYXAgZW50aXRpZXM7CisvLyAgICAgICAgRW50aXR5IGVudGl0eTsKKy8vICAgICAgICBTdHJpbmcgbnVsbE5TID0gbnVsbDsKKy8vCisvLyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisvLyAgICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisvLyAgICAgICAgZW50aXRpZXMgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisvLyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50aXRpZXNOb3ROdWxsIiwgZW50aXRpZXMpOworLy8gICAgICAgIGVudGl0eSA9IChFbnRpdHkpIGVudGl0aWVzLmdldE5hbWVkSXRlbU5TKG51bGxOUywgImVudDEiKTsKKy8vICAgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdHlOdWxsIiwgZW50aXR5KTsKKy8vICAgIH0KKworLy8gQXNzdW1lcyB2YWxpZGF0aW9uLgorLy8gICAgcHVibGljIHZvaWQgdGVzdEdldE5hbWVkSXRlbU5TNCgpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKy8vICAgICAgICBOYW1lZE5vZGVNYXAgbm90YXRpb25zOworLy8gICAgICAgIE5vdGF0aW9uIG5vdGF0aW9uOworLy8gICAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworLy8KKy8vICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKy8vICAgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKy8vICAgICAgICBub3RhdGlvbnMgPSBkb2NUeXBlLmdldE5vdGF0aW9ucygpOworLy8gICAgICAgIGFzc2VydE5vdE51bGwoIm5vdGF0aW9uc05vdE51bGwiLCBub3RhdGlvbnMpOworLy8gICAgICAgIG5vdGF0aW9uID0gKE5vdGF0aW9uKSBub3RhdGlvbnMuZ2V0TmFtZWRJdGVtTlMobnVsbE5TLCAibm90YXRpb24xIik7CisvLyAgICAgICAgYXNzZXJ0Tm90TnVsbCgibm90YXRpb25OdWxsIiwgbm90YXRpb24pOworLy8gICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0hDRW50aXRpZXNSZW1vdmVOYW1lZEl0ZW1OUy5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0hDRW50aXRpZXNSZW1vdmVOYW1lZEl0ZW1OUy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjOWQ2NWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vSENFbnRpdGllc1JlbW92ZU5hbWVkSXRlbU5TLmphdmEKQEAgLTAsMCArMSw5OSBAQAorLyoKKyBUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCisgYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KKyBUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisgQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorIFBVUlBPU0UuCisgU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyAqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7CisKKy8qKgorICogQW4gYXR0ZW1wdCB0byBhZGQgcmVtb3ZlIGFuIGVudGl0eSB1c2luZyByZW1vdmVOYW1lZEl0ZW1OUyBzaG91bGQgcmVzdWx0IGluIGEKKyAqIE5PX01PRElGSUNBVElPTl9FUlIgb3IgYSBOT1RfRk9VTkRfRVJSLgorICoKKyAqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELTE3ODg3OTQ2MzAiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC0xNzg4Nzk0NjMwPC9hPgorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtcmVtb3ZlTmFtZWRJdGVtTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1yZW1vdmVOYW1lZEl0ZW1OUzwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEhDRW50aXRpZXNSZW1vdmVOYW1lZEl0ZW1OUyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworLy8gQXNzdW1lcyB2YWxpZGF0aW9uLgorLy8gICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZU5hbWVkSXRlbU5TKCkgdGhyb3dzIFRocm93YWJsZSB7CisvLyAgICAgICAgRG9jdW1lbnQgZG9jOworLy8gICAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdGllczsKKy8vICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKy8vCisvLyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGJ1aWxkZXIpOworLy8gICAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworLy8KKy8vICAgICAgICBpZiAoISgoInRleHQvaHRtbCIuZXF1YWxzKGdldENvbnRlbnRUeXBlKCkpKSkpIHsKKy8vICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZG9jVHlwZU5vdE51bGwiLCBkb2NUeXBlKTsKKy8vICAgICAgICAgICAgZW50aXRpZXMgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisvLyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoImVudGl0aWVzTm90TnVsbCIsIGVudGl0aWVzKTsKKy8vCisvLyAgICAgICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgICAgICBlbnRpdGllcy5yZW1vdmVOYW1lZEl0ZW1OUygKKy8vICAgICAgICAgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiLCAiYWxwaGEiKTsKKy8vICAgICAgICAgICAgICAgIGZhaWwoInRocm93X05PX01PRF9PUl9OT1RfRk9VTkRfRVJSIik7CisvLworLy8gICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKy8vICAgICAgICAgICAgICAgIHN3aXRjaCAoZXguY29kZSkgeworLy8gICAgICAgICAgICAgICAgY2FzZSA3OgorLy8gICAgICAgICAgICAgICAgICAgIGJyZWFrOworLy8gICAgICAgICAgICAgICAgY2FzZSA4OgorLy8gICAgICAgICAgICAgICAgICAgIGJyZWFrOworLy8gICAgICAgICAgICAgICAgZGVmYXVsdDoKKy8vICAgICAgICAgICAgICAgICAgICB0aHJvdyBleDsKKy8vICAgICAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgfQorLy8gICAgICAgIH0KKy8vICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0hDRW50aXRpZXNTZXROYW1lZEl0ZW1OUy5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0hDRW50aXRpZXNTZXROYW1lZEl0ZW1OUy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5MmIzM2UKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vSENFbnRpdGllc1NldE5hbWVkSXRlbU5TLmphdmEKQEAgLTAsMCArMSw4MyBAQAorcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7CitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7CisKKy8qKgorICogQW4gYXR0ZW1wdCB0byBhZGQgYW4gZWxlbWVudCB0byB0aGUgbmFtZWQgbm9kZSBtYXAgcmV0dXJuZWQgYnkgZW50aXRpZXMKKyAqIHNob3VsZCByZXN1bHQgaW4gYSBOT19NT0RJRklDQVRJT05fRVJSIG9yIEhJRVJBUkNIWV9SRVFVRVNUX0VSUi4KKyAqCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC0xNzg4Nzk0NjMwIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtMTc4ODc5NDYzMDwvYT4KKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXNldE5hbWVkSXRlbU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtc2V0TmFtZWRJdGVtTlM8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBIQ0VudGl0aWVzU2V0TmFtZWRJdGVtTlMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKy8vIEFzc3VtZXMgdmFsaWRhdGlvbi4KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RTZXROYW1lZEl0ZW1OUygpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBOYW1lZE5vZGVNYXAgZW50aXRpZXM7CisvLyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisvLworLy8gICAgICAgIEVsZW1lbnQgZWxlbTsKKy8vICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgYnVpbGRlcik7CisvLyAgICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisvLworLy8gICAgICAgIGlmICghKCgidGV4dC9odG1sIi5lcXVhbHMoZ2V0Q29udGVudFR5cGUoKSkpKSkgeworLy8gICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworLy8gICAgICAgICAgICBlbnRpdGllcyA9IGRvY1R5cGUuZ2V0RW50aXRpZXMoKTsKKy8vICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50aXRpZXNOb3ROdWxsIiwgZW50aXRpZXMpOworLy8gICAgICAgICAgICBlbGVtID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIsICJiciIpOworLy8KKy8vICAgICAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgICAgIGVudGl0aWVzLnNldE5hbWVkSXRlbU5TKGVsZW0pOworLy8gICAgICAgICAgICAgICAgZmFpbCgidGhyb3dfSElFUl9PUl9OT19NT0RfRVJSIik7CisvLworLy8gICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKy8vICAgICAgICAgICAgICAgIHN3aXRjaCAoZXguY29kZSkgeworLy8gICAgICAgICAgICAgICAgY2FzZSAzOgorLy8gICAgICAgICAgICAgICAgICAgIGJyZWFrOworLy8gICAgICAgICAgICAgICAgY2FzZSA3OgorLy8gICAgICAgICAgICAgICAgICAgIGJyZWFrOworLy8gICAgICAgICAgICAgICAgZGVmYXVsdDoKKy8vICAgICAgICAgICAgICAgICAgICB0aHJvdyBleDsKKy8vICAgICAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgfQorLy8gICAgICAgIH0KKy8vICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0hDTmFtZWROb2RlTWFwSW52YWxpZFR5cGUuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9IQ05hbWVkTm9kZU1hcEludmFsaWRUeXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTFkMjU5MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9IQ05hbWVkTm9kZU1hcEludmFsaWRUeXBlLmphdmEKQEAgLTAsMCArMSw5MSBAQAorLyoKKyBUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCisgYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KKyBUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisgQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKKyBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgUFVSUE9TRS4KKyBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworICovCisKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogQXR0ZW1wdCB0byBpbnNlcnQgYW4gZWxlbWVudCBpbnRvIGFuIGF0dHJpYnV0ZSBsaXN0LCBzaG91bGQgcmFpc2UgYQorICogSElFUkFSQ0hZX1JFUVVFU1RfRVJSLgorICoKKyAqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0hJRVJBUkNIWV9SRVFVRVNUX0VSUiddKTwvYT4KKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTAyNTE2Mzc4OCI+aHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEvbGV2ZWwtb25lLWNvcmUjSUQtMTAyNTE2Mzc4ODwvYT4KKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8xMS9ET00tTGV2ZWwtMi1lcnJhdGEjY29yZS00Ij5odHRwOi8vd3d3LnczLm9yZy8yMDAwLzExL0RPTS1MZXZlbC0yLWVycmF0YSNjb3JlLTQ8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBIQ05hbWVkTm9kZU1hcEludmFsaWRUeXBlIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24xKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE5hbWVkTm9kZU1hcEludmFsaWRUeXBlKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICAgIEVsZW1lbnQgZG9jRWxlbTsKKyAgICAgICAgRWxlbWVudCBuZXdFbGVtOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBidWlsZGVyKTsKKyAgICAgICAgZG9jRWxlbSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgYXR0cmlidXRlcyA9IGRvY0VsZW0uZ2V0QXR0cmlidXRlcygpOworICAgICAgICBuZXdFbGVtID0gZG9jLmNyZWF0ZUVsZW1lbnQoImh0bWwiKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5zZXROYW1lZEl0ZW0obmV3RWxlbSk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19ISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0hDTm9kZURvY3VtZW50RnJhZ21lbnROb3JtYWxpemUuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9IQ05vZGVEb2N1bWVudEZyYWdtZW50Tm9ybWFsaXplLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDNhYzYxZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9IQ05vZGVEb2N1bWVudEZyYWdtZW50Tm9ybWFsaXplLmphdmEKQEAgLTAsMCArMSw4MiBAQAorcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRGcmFnbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5UZXh0OworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIENyZWF0ZSBhIGRvY3VtZW50IGZyYWdtZW50IHdpdGggdHdvIGFkamFjZW50IHRleHQgbm9kZXMsIG5vcm1hbGl6ZSBhbmQgc2VlIGlmCisgKiB0aGUgdGV4dCBub2RlcyB3ZXJlIGNvbWJpbmVkLgorICoKKyAqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1GNjhEMDk1PC9hPgorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtQjYzRUQxQTMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1CNjNFRDFBMzwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEhDTm9kZURvY3VtZW50RnJhZ21lbnROb3JtYWxpemUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9kZURvY3VtZW50RnJhZ21lbnROb3JtYWxpemUxKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRG9jdW1lbnRGcmFnbWVudCBkb2NGcmFnbWVudDsKKyAgICAgICAgU3RyaW5nIG5vZGVWYWx1ZTsKKyAgICAgICAgVGV4dCB0eHROb2RlOworICAgICAgICBOb2RlIHJldHZhbDsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoImhjX3N0YWZmIiwgYnVpbGRlcik7CisgICAgICAgIGRvY0ZyYWdtZW50ID0gZG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKKyAgICAgICAgdHh0Tm9kZSA9IGRvYy5jcmVhdGVUZXh0Tm9kZSgiZm9vIik7CisgICAgICAgIHJldHZhbCA9IGRvY0ZyYWdtZW50LmFwcGVuZENoaWxkKHR4dE5vZGUpOworICAgICAgICB0eHROb2RlID0gZG9jLmNyZWF0ZVRleHROb2RlKCJiYXIiKTsKKyAgICAgICAgcmV0dmFsID0gZG9jRnJhZ21lbnQuYXBwZW5kQ2hpbGQodHh0Tm9kZSk7CisgICAgICAgIGRvY0ZyYWdtZW50Lm5vcm1hbGl6ZSgpOworICAgICAgICB0eHROb2RlID0gKFRleHQpIGRvY0ZyYWdtZW50LmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgICAgbm9kZVZhbHVlID0gdHh0Tm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub3JtYWxpemVkTm9kZVZhbHVlIiwgImZvb2JhciIsIG5vZGVWYWx1ZSk7CisgICAgICAgIHJldHZhbCA9IHR4dE5vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgic2luZ2xlQ2hpbGQiLCByZXR2YWwpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9kZURvY3VtZW50RnJhZ21lbnROb3JtYWxpemUyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRG9jdW1lbnRGcmFnbWVudCBkb2NGcmFnbWVudDsKKyAgICAgICAgVGV4dCB0eHROb2RlOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBidWlsZGVyKTsKKyAgICAgICAgZG9jRnJhZ21lbnQgPSBkb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOworICAgICAgICB0eHROb2RlID0gZG9jLmNyZWF0ZVRleHROb2RlKCIiKTsKKyAgICAgICAgZG9jRnJhZ21lbnQuYXBwZW5kQ2hpbGQodHh0Tm9kZSk7CisgICAgICAgIGRvY0ZyYWdtZW50Lm5vcm1hbGl6ZSgpOworICAgICAgICB0eHROb2RlID0gKFRleHQpIGRvY0ZyYWdtZW50LmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgibm9DaGlsZCIsIHR4dE5vZGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9IQ05vdGF0aW9uc1JlbW92ZU5hbWVkSXRlbU5TLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vSENOb3RhdGlvbnNSZW1vdmVOYW1lZEl0ZW1OUy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2NTgzODcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vSENOb3RhdGlvbnNSZW1vdmVOYW1lZEl0ZW1OUy5qYXZhCkBAIC0wLDAgKzEsOTggQEAKKy8qCisgVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorIGFuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCisgVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAorIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyBQVVJQT1NFLgorIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisgKi8KKworcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIEFuIGF0dGVtcHQgdG8gYWRkIHJlbW92ZSBhbiBub3RhdGlvbiB1c2luZyByZW1vdmVOYW1lZEl0ZW1OUyBzaG91bGQgcmVzdWx0IGluCisgKiBhIE5PX01PRElGSUNBVElPTl9FUlIgb3IgYSBOT1RfRk9VTkRfRVJSLgorICoKKyAqIEBhdXRob3IgQ3VydCBBcm5vbGQKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUQ0NjgyOUVGIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRDQ2ODI5RUY8L2E+CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1yZW1vdmVOYW1lZEl0ZW1OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXJlbW92ZU5hbWVkSXRlbU5TPC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSENOb3RhdGlvbnNSZW1vdmVOYW1lZEl0ZW1OUyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVOYW1lZEl0ZW1OUygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5hbWVkTm9kZU1hcCBub3RhdGlvbnM7CisgICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBidWlsZGVyKTsKKyAgICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisKKyAgICAgICAgaWYgKCEoKCJ0ZXh0L2h0bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpKSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgICAgICAgbm90YXRpb25zID0gZG9jVHlwZS5nZXROb3RhdGlvbnMoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIm5vdGF0aW9uc05vdE51bGwiLCBub3RhdGlvbnMpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG5vdGF0aW9ucy5yZW1vdmVOYW1lZEl0ZW1OUygiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIsCisgICAgICAgICAgICAgICAgICAgICAgICAiYWxwaGEiKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJ0aHJvd19OT19NT0RfT1JfTk9UX0ZPVU5EX0VSUiIpOworCisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzd2l0Y2ggKGV4LmNvZGUpIHsKKyAgICAgICAgICAgICAgICBjYXNlIDc6CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgODoKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXg7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vSENOb3RhdGlvbnNTZXROYW1lZEl0ZW1OUy5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0hDTm90YXRpb25zU2V0TmFtZWRJdGVtTlMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNjdiMmYzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0hDTm90YXRpb25zU2V0TmFtZWRJdGVtTlMuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorLyoKKyBUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCisgYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KKyBUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisgQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCisgUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorIFBVUlBPU0UuCisgU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKyAqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBBbiBhdHRlbXB0IHRvIGFkZCBhbiBlbGVtZW50IHRvIHRoZSBuYW1lZCBub2RlIG1hcCByZXR1cm5lZCBieSBub3RhdGlvbnMKKyAqIHNob3VsZCByZXN1bHQgaW4gYSBOT19NT0RJRklDQVRJT05fRVJSIG9yIEhJRVJBUkNIWV9SRVFVRVNUX0VSUi4KKyAqCisgKiBAYXV0aG9yIEN1cnQgQXJub2xkCisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1ENDY4MjlFRiI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUQ0NjgyOUVGPC9hPgorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtc2V0TmFtZWRJdGVtTlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1zZXROYW1lZEl0ZW1OUzwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEhDTm90YXRpb25zU2V0TmFtZWRJdGVtTlMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm90YXRpb25zU2V0TmFtZWRJdGVtTlMoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOYW1lZE5vZGVNYXAgbm90YXRpb25zOworICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKworICAgICAgICBFbGVtZW50IGVsZW07CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgiaGNfc3RhZmYiLCBidWlsZGVyKTsKKyAgICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisKKyAgICAgICAgaWYgKCEoKCJ0ZXh0L2h0bWwiLmVxdWFscyhnZXRDb250ZW50VHlwZSgpKSkpKSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJkb2NUeXBlTm90TnVsbCIsIGRvY1R5cGUpOworICAgICAgICAgICAgbm90YXRpb25zID0gZG9jVHlwZS5nZXROb3RhdGlvbnMoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIm5vdGF0aW9uc05vdE51bGwiLCBub3RhdGlvbnMpOworICAgICAgICAgICAgZWxlbSA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiLCAiYnIiKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBub3RhdGlvbnMuc2V0TmFtZWRJdGVtTlMoZWxlbSk7CisgICAgICAgICAgICAgICAgZmFpbCgidGhyb3dfSElFUl9PUl9OT19NT0RfRVJSIik7CisKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN3aXRjaCAoZXguY29kZSkgeworICAgICAgICAgICAgICAgIGNhc2UgMzoKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSA3OgorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICB0aHJvdyBleDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9IYXNBdHRyaWJ1dGUuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9IYXNBdHRyaWJ1dGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNTA5ZTY5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0hhc0F0dHJpYnV0ZS5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSAiaGFzQXR0cmlidXRlKCkiIG1ldGhvZCBmb3IgYW4gRWxlbWVudCBzaG91bGQgcmV0dXJuIHRydWUgaWYgdGhlIGVsZW1lbnQKKyAqIGhhcyBhbiBhdHRyaWJ1dGUgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4gUmV0cmlldmUgdGhlIGZpcnN0ICJhZGRyZXNzIiBlbGVtZW50CisgKiBhbmQgdGhlICJoYXNBdHRyaWJ1dGUoKSIgbWV0aG9kIHNob3VsZCByZXR1cm4gZmFsc2Ugc2luY2UgdGhlIGVsZW1lbnQgZG9lcworICogbm90IGhhdmUgYSBkZWZhdWx0IHZhbHVlLgorICoKKyAqIEBhdXRob3IgTklTVAorICogQGF1dGhvciBNYXJ5IEJyYWR5CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEhhc0F0dHIiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEhhc0F0dHI8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBIYXNBdHRyaWJ1dGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzQXR0cmlidXRlMSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBFbGVtZW50IHRlc3ROb2RlOworICAgICAgICBib29sZWFuIHN0YXRlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICAgIHRlc3ROb2RlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oNCk7CisgICAgICAgIHN0YXRlID0gdGVzdE5vZGUuaGFzQXR0cmlidXRlKCJkb21lc3RpYyIpOworICAgICAgICBhc3NlcnRGYWxzZSgidGhyb3dfRmFsc2UiLCBzdGF0ZSk7CisgICAgfQorCisvLyBBc3N1bWVzIHZhbGlkYXRpb24uCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzQXR0cmlidXRlMigpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKy8vICAgICAgICBFbGVtZW50IHRlc3ROb2RlOworLy8gICAgICAgIGJvb2xlYW4gc3RhdGU7CisvLyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGJ1aWxkZXIpOworLy8gICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisvLyAgICAgICAgdGVzdE5vZGUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKy8vICAgICAgICBzdGF0ZSA9IHRlc3ROb2RlLmhhc0F0dHJpYnV0ZSgic3RyZWV0Iik7CisvLyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfVHJ1ZSIsIHN0YXRlKTsKKy8vICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzQXR0cmlidXRlMygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBFbGVtZW50IHRlc3ROb2RlOworICAgICAgICBib29sZWFuIHN0YXRlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICAgIHRlc3ROb2RlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIHN0YXRlID0gdGVzdE5vZGUuaGFzQXR0cmlidXRlKCJub21hdGNoIik7CisgICAgICAgIGFzc2VydEZhbHNlKCJ0aHJvd19GYWxzZSIsIHN0YXRlKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEhhc0F0dHJpYnV0ZTQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgRWxlbWVudCB0ZXN0Tm9kZTsKKyAgICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICAgIHRlc3ROb2RlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIHN0YXRlID0gdGVzdE5vZGUuaGFzQXR0cmlidXRlKCJkbXN0Yzpkb21lc3RpYyIpOworICAgICAgICBhc3NlcnRUcnVlKCJoYXNEb21lc3RpY0F0dHIiLCBzdGF0ZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0hhc0F0dHJpYnV0ZU5TLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vSGFzQXR0cmlidXRlTlMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iODFiMDA3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL0hhc0F0dHJpYnV0ZU5TLmphdmEKQEAgLTAsMCArMSwxNDIgQEAKKy8qCisgVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorIGFuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCisgVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisgQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbAorIFJpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorIFBVUlBPU0UuCisKKyBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisgKi8KKworcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICoKKyAqIFRoZSAiaGFzQXR0cmlidXRlTlMoKSIgbWV0aG9kIGZvciBhbiBFbGVtZW50IHNob3VsZCByZXR1cm4gZmFsc2UgaWYgdGhlCisgKiBlbGVtZW50IGRvZXMgbm90IGhhdmUgYW4gYXR0cmlidXRlIHdpdGggdGhlIGdpdmVuIGxvY2FsIG5hbWUgYW5kL29yIGEKKyAqIG5hbWVzcGFjZSBVUkkgc3BlY2lmaWVkIG9uIHRoaXMgZWxlbWVudCBvciBkb2VzIG5vdCBoYXZlIGEgZGVmYXVsdCB2YWx1ZS4KKyAqIFJldHJpZXZlIHRoZSBmaXJzdCAiYWRkcmVzcyIgZWxlbWVudCBhbmQgdGhlICJoYXNBdHRyaWJ1dGVOUygpIiBtZXRob2Qgc2hvdWxkCisgKiByZXR1cm4gZmFsc2Ugc2luY2UgdGhlIGVsZW1lbnQgaGFzICJub21hdGNoIiBhcyB0aGUgbG9jYWwgbmFtZSBhbmQKKyAqICJodHRwOi8vd3d3LnVzYS5jb20iIGFzIHRoZSBuYW1lc3BhY2UgVVJJLgorICoKKyAqIEBhdXRob3IgTklTVAorICogQGF1dGhvciBNYXJ5IEJyYWR5CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbEhhc0F0dHJOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsSGFzQXR0ck5TPC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSGFzQXR0cmlidXRlTlMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzQXR0cmlidXRlTlMxKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSAibm9tYXRjaCI7CisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy51c2EuY29tIjsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgRWxlbWVudCB0ZXN0Tm9kZTsKKyAgICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICAgIHRlc3ROb2RlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIHN0YXRlID0gdGVzdE5vZGUuaGFzQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgICBhc3NlcnRGYWxzZSgidGhyb3dfRmFsc2UiLCBzdGF0ZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RIYXNBdHRyaWJ1dGVOUzIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9ICJkb21lc3RpYyI7CisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5ub21hdGNoLmNvbSI7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIEVsZW1lbnQgdGVzdE5vZGU7CisgICAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgICB0ZXN0Tm9kZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgICBzdGF0ZSA9IHRlc3ROb2RlLmhhc0F0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoInRocm93X0ZhbHNlIiwgc3RhdGUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzQXR0cmlidXRlTlMzKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSAiYmxhbmsiOworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cubmlzdC5nb3YiOworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBFbGVtZW50IHRlc3ROb2RlOworICAgICAgICBib29sZWFuIHN0YXRlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICAgIHRlc3ROb2RlID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoImVtcEFkZHJOb3ROdWxsIiwgdGVzdE5vZGUpOworICAgICAgICBzdGF0ZSA9IHRlc3ROb2RlLmhhc0F0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoInRocm93X0ZhbHNlIiwgc3RhdGUpOworICAgIH0KKworLy8gQXNzdW1lcyB2YWxpZGF0aW9uLgorLy8gICAgcHVibGljIHZvaWQgdGVzdEhhc0F0dHJpYnV0ZU5TNCgpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSAiZGlzdHJpY3QiOworLy8gICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5uaXN0LmdvdiI7CisvLyAgICAgICAgRG9jdW1lbnQgZG9jOworLy8gICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworLy8gICAgICAgIEVsZW1lbnQgdGVzdE5vZGU7CisvLyAgICAgICAgYm9vbGVhbiBzdGF0ZTsKKy8vICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKy8vICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmFkZHJlc3MiKTsKKy8vICAgICAgICB0ZXN0Tm9kZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworLy8gICAgICAgIGFzc2VydE5vdE51bGwoImVtcEFkZHJlc3NOb3ROdWxsIiwgdGVzdE5vZGUpOworLy8gICAgICAgIHN0YXRlID0gdGVzdE5vZGUuaGFzQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworLy8gICAgICAgIGFzc2VydFRydWUoImhhc0F0dHJpYnV0ZSIsIHN0YXRlKTsKKy8vICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzQXR0cmlidXRlTlM1KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSAiZG9tZXN0aWMiOworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cudXNhLmNvbSI7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIEVsZW1lbnQgdGVzdE5vZGU7CisgICAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgICB0ZXN0Tm9kZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgICBzdGF0ZSA9IHRlc3ROb2RlLmhhc0F0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaGFzQXR0cmlidXRlIiwgc3RhdGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9IYXNBdHRyaWJ1dGVzLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vSGFzQXR0cmlidXRlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExYzZkNWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vSGFzQXR0cmlidXRlcy5qYXZhCkBAIC0wLDAgKzEsOTMgQEAKKy8qCisgVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorIGFuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCisgVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisgQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbAorIFJpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorIFBVUlBPU0UuCisKKyBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisgKi8KKworcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogVGhlICJoYXNBdHRyaWJ1dGVzKCkiIG1ldGhvZCBmb3IgYSBub2RlIHNob3VsZCByZXR1cm4gZmFsc2UgaWYgdGhlIG5vZGUgZG9lcworICogbm90IGhhdmUgYW4gYXR0cmlidXRlLiBSZXRyaWV2ZSB0aGUgZmlyc3QgIm5hbWUiIG5vZGUgYW5kIGludm9rZSB0aGUKKyAqICJoYXNBdHRyaWJ1dGVzKCkiIG1ldGhvZC4gVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGZhbHNlIHNpbmNlIHRoZSBub2RlIGRvZXMKKyAqIG5vdCBoYXZlIGFuIGF0dHJpYnV0ZS4KKyAqCisgKiBAYXV0aG9yIE5JU1QKKyAqIEBhdXRob3IgTWFyeSBCcmFkeQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZUhhc0F0dHJzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZUhhc0F0dHJzPC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSGFzQXR0cmlidXRlcyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RIYXNBdHRyaWJ1dGVzMSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGFkZHJMaXN0OworICAgICAgICBOb2RlIGFkZHJOb2RlOworICAgICAgICBib29sZWFuIHN0YXRlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICAgIGFkZHJMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJuYW1lIik7CisgICAgICAgIGFkZHJOb2RlID0gYWRkckxpc3QuaXRlbSgwKTsKKyAgICAgICAgc3RhdGUgPSBhZGRyTm9kZS5oYXNBdHRyaWJ1dGVzKCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJ0aHJvd19GYWxzZSIsIHN0YXRlKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEhhc0F0dHJpYnV0ZXMyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgYWRkckxpc3Q7CisgICAgICAgIE5vZGUgYWRkck5vZGU7CisgICAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBidWlsZGVyKTsKKyAgICAgICAgYWRkckxpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgICAgYWRkck5vZGUgPSBhZGRyTGlzdC5pdGVtKDApOworICAgICAgICBzdGF0ZSA9IGFkZHJOb2RlLmhhc0F0dHJpYnV0ZXMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfVHJ1ZSIsIHN0YXRlKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9JbXBvcnROb2RlLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vSW1wb3J0Tm9kZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ0MmJhYzcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vSW1wb3J0Tm9kZS5qYXZhCkBAIC0wLDAgKzEsNTI2IEBACisvKgorIFRoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKKyBhbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorIFRoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworIENvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwKKyBSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyBQVVJQT1NFLgorCisgU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworICovCisKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKK2ltcG9ydCBvcmcudzNjLmRvbS5UZXh0OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CitpbXBvcnQgb3JnLnczYy5kb20uQ0RBVEFTZWN0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkNvbW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRGcmFnbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbnRpdHlSZWZlcmVuY2U7CitpbXBvcnQgb3JnLnczYy5kb20uUHJvY2Vzc2luZ0luc3RydWN0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBUaGUgImltcG9ydE5vZGUoaW1wb3J0ZWROb2RlLGRlZXApIiBtZXRob2QgZm9yIGEgRG9jdW1lbnQgc2hvdWxkIGltcG9ydCB0aGUKKyAqIGdpdmVuIGltcG9ydGVkTm9kZSBpbnRvIHRoYXQgRG9jdW1lbnQuIFRoZSBpbXBvcnRlZE5vZGUgaXMgb2YgdHlwZSBBdHRyLiBUaGUKKyAqIG93bmVyRWxlbWVudCBpcyBzZXQgdG8gbnVsbC4gU3BlY2lmaWVkIGZsYWcgaXMgc2V0IHRvIHRydWUuIENoaWxkcmVuIGlzCisgKiBpbXBvcnRlZC4KKyAqCisgKiBDcmVhdGUgYSBuZXcgYXR0cmlidXRlIHdob3NlIG5hbWUgaXMgImVsZW06YXR0cjEiIGluIGEgZGlmZmVyZW50IGRvY3VtZW50LgorICogQ3JlYXRlIGEgY2hpbGQgVGV4dCBub2RlIHdpdGggdmFsdWUgImltcG9ydGVkVGV4dCIgZm9yIHRoZSBhdHRyaWJ1dGUgbm9kZQorICogYWJvdmUuIEludm9rZSBtZXRob2QgaW1wb3J0Tm9kZShpbXBvcnRlZE5vZGUsZGVlcCkgb24gdGhpcyBkb2N1bWVudCB3aXRoCisgKiBpbXBvcnRlZE5vZGUgYmVpbmcgdGhlIG5ld2x5IGNyZWF0ZWQgYXR0cmlidXRlLiBNZXRob2Qgc2hvdWxkIHJldHVybiBhIG5vZGUKKyAqIHdob3NlIG5hbWUgbWF0Y2hlcyAiZWxlbTphdHRyMSIgYW5kIGEgY2hpbGQgbm9kZSB3aG9zZSB2YWx1ZSBlcXVhbHMKKyAqICJpbXBvcnRlZFRleHQiLiBUaGUgcmV0dXJuZWQgbm9kZSBzaG91bGQgYmVsb25nIHRvIHRoaXMgZG9jdW1lbnQgd2hvc2UKKyAqIHN5c3RlbUlkIGlzICJzdGFmZi5kdGQiCisgKgorICogQGF1dGhvciBOSVNUCisgKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0NvcmUtRG9jdW1lbnQtaW1wb3J0Tm9kZTwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEltcG9ydE5vZGUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBfdGVzdEltcG9ydE5vZGUxKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRG9jdW1lbnQgYU5ld0RvYzsKKyAgICAgICAgQXR0ciBuZXdBdHRyOworICAgICAgICBUZXh0IGltcG9ydGVkQ2hpbGQ7CisgICAgICAgIE5vZGUgYU5vZGU7CisgICAgICAgIERvY3VtZW50IG93bmVyRG9jdW1lbnQ7CisgICAgICAgIEVsZW1lbnQgYXR0ck93bmVyRWxlbWVudDsKKyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICAgIFN0cmluZyBzeXN0ZW07CisgICAgICAgIGJvb2xlYW4gc3BlY2lmaWVkOworICAgICAgICBOb2RlTGlzdCBjaGlsZExpc3Q7CisgICAgICAgIFN0cmluZyBub2RlTmFtZTsKKyAgICAgICAgTm9kZSBjaGlsZDsKKyAgICAgICAgU3RyaW5nIGNoaWxkVmFsdWU7CisgICAgICAgIExpc3Q8U3RyaW5nPiBleHBlY3RlZFJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBleHBlY3RlZFJlc3VsdC5hZGQoImVsZW06YXR0cjEiKTsKKyAgICAgICAgZXhwZWN0ZWRSZXN1bHQuYWRkKCJpbXBvcnRlZFRleHQiKTsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgYU5ld0RvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBuZXdBdHRyID0gYU5ld0RvYy5jcmVhdGVBdHRyaWJ1dGUoImVsZW06YXR0cjEiKTsKKyAgICAgICAgaW1wb3J0ZWRDaGlsZCA9IGFOZXdEb2MuY3JlYXRlVGV4dE5vZGUoImltcG9ydGVkVGV4dCIpOworICAgICAgICBhTm9kZSA9IG5ld0F0dHIuYXBwZW5kQ2hpbGQoaW1wb3J0ZWRDaGlsZCk7CisgICAgICAgIGFOb2RlID0gZG9jLmltcG9ydE5vZGUobmV3QXR0ciwgZmFsc2UpOworICAgICAgICBvd25lckRvY3VtZW50ID0gYU5vZGUuZ2V0T3duZXJEb2N1bWVudCgpOworICAgICAgICBkb2NUeXBlID0gb3duZXJEb2N1bWVudC5nZXREb2N0eXBlKCk7CisgICAgICAgIHN5c3RlbSA9IGRvY1R5cGUuZ2V0U3lzdGVtSWQoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiYU5vZGUiLCBhTm9kZSk7CisgICAgICAgIGFzc2VydFVSSUVxdWFscygic3lzdGVtSWQiLCBudWxsLCBudWxsLCBudWxsLCAic3RhZmZOUy5kdGQiLCBudWxsLAorICAgICAgICAgICAgICAgIG51bGwsIG51bGwsIG51bGwsIHN5c3RlbSk7CisgICAgICAgIGF0dHJPd25lckVsZW1lbnQgPSAoKEF0dHIpIC8qIE5vZGUgKi9hTm9kZSkuZ2V0T3duZXJFbGVtZW50KCk7CisgICAgICAgIGFzc2VydE51bGwoIm93bmVyRWxlbWVudCIsIGF0dHJPd25lckVsZW1lbnQpOworICAgICAgICBzcGVjaWZpZWQgPSAoKEF0dHIpIC8qIE5vZGUgKi9hTm9kZSkuZ2V0U3BlY2lmaWVkKCk7CisgICAgICAgIGFzc2VydFRydWUoInNwZWNpZmllZCIsIHNwZWNpZmllZCk7CisgICAgICAgIGNoaWxkTGlzdCA9IGFOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjaGlsZExpc3QiLCAxLCBjaGlsZExpc3QuZ2V0TGVuZ3RoKCkpOworICAgICAgICBub2RlTmFtZSA9IGFOb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibm9kZU5hbWUiLCAiZWxlbTphdHRyMSIsIG5vZGVOYW1lKTsKKyAgICAgICAgY2hpbGQgPSBhTm9kZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICAgIGNoaWxkVmFsdWUgPSBjaGlsZC5nZXROb2RlVmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJjaGlsZFZhbHVlIiwgImltcG9ydGVkVGV4dCIsIGNoaWxkVmFsdWUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0Tm9kZTIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBEb2N1bWVudCBhTmV3RG9jOworICAgICAgICBDREFUQVNlY3Rpb24gY0RhdGFTZWM7CisgICAgICAgIE5vZGUgYU5vZGU7CisgICAgICAgIERvY3VtZW50IG93bmVyRG9jdW1lbnQ7CisgICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgICBTdHJpbmcgc3lzdGVtOworICAgICAgICBTdHJpbmcgdmFsdWU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBhTmV3RG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGNEYXRhU2VjID0gYU5ld0RvYy5jcmVhdGVDREFUQVNlY3Rpb24oInRoaXMgaXMgQ0RBVEFTZWN0aW9uIGRhdGEiKTsKKyAgICAgICAgYU5vZGUgPSBkb2MuaW1wb3J0Tm9kZShjRGF0YVNlYywgZmFsc2UpOworICAgICAgICBvd25lckRvY3VtZW50ID0gYU5vZGUuZ2V0T3duZXJEb2N1bWVudCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJvd25lckRvY3VtZW50Tm90TnVsbCIsIG93bmVyRG9jdW1lbnQpOworICAgICAgICBkb2NUeXBlID0gb3duZXJEb2N1bWVudC5nZXREb2N0eXBlKCk7CisgICAgICAgIHN5c3RlbSA9IGRvY1R5cGUuZ2V0U3lzdGVtSWQoKTsKKyAgICAgICAgYXNzZXJ0VVJJRXF1YWxzKCJkdGRTeXN0ZW1JZCIsIG51bGwsIG51bGwsIG51bGwsICJzdGFmZk5TLmR0ZCIsIG51bGwsCisgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwgbnVsbCwgc3lzdGVtKTsKKyAgICAgICAgdmFsdWUgPSBhTm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlVmFsdWUiLCAidGhpcyBpcyBDREFUQVNlY3Rpb24gZGF0YSIsIHZhbHVlKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGUzKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRG9jdW1lbnQgYU5ld0RvYzsKKyAgICAgICAgQ29tbWVudCBjb21tZW50OworICAgICAgICBOb2RlIGFOb2RlOworICAgICAgICBEb2N1bWVudCBvd25lckRvY3VtZW50OworICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgICAgU3RyaW5nIHN5c3RlbTsKKyAgICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgYU5ld0RvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBjb21tZW50ID0gYU5ld0RvYy5jcmVhdGVDb21tZW50KCJ0aGlzIGlzIGEgY29tbWVudCIpOworICAgICAgICBhTm9kZSA9IGRvYy5pbXBvcnROb2RlKGNvbW1lbnQsIGZhbHNlKTsKKyAgICAgICAgb3duZXJEb2N1bWVudCA9IGFOb2RlLmdldE93bmVyRG9jdW1lbnQoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgib3duZXJEb2N1bWVudE5vdE51bGwiLCBvd25lckRvY3VtZW50KTsKKyAgICAgICAgZG9jVHlwZSA9IG93bmVyRG9jdW1lbnQuZ2V0RG9jdHlwZSgpOworICAgICAgICBzeXN0ZW0gPSBkb2NUeXBlLmdldFN5c3RlbUlkKCk7CisgICAgICAgIGFzc2VydFVSSUVxdWFscygic3lzdGVtSWQiLCBudWxsLCBudWxsLCBudWxsLCAic3RhZmZOUy5kdGQiLCBudWxsLAorICAgICAgICAgICAgICAgIG51bGwsIG51bGwsIG51bGwsIHN5c3RlbSk7CisgICAgICAgIHZhbHVlID0gYU5vZGUuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibm9kZVZhbHVlIiwgInRoaXMgaXMgYSBjb21tZW50IiwgdmFsdWUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0Tm9kZTQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBEb2N1bWVudCBhTmV3RG9jOworICAgICAgICBEb2N1bWVudEZyYWdtZW50IGRvY0ZyYWc7CisgICAgICAgIENvbW1lbnQgY29tbWVudDsKKyAgICAgICAgTm9kZSBhTm9kZTsKKyAgICAgICAgTm9kZUxpc3QgY2hpbGRyZW47CisgICAgICAgIE5vZGUgY2hpbGQ7CisgICAgICAgIFN0cmluZyBjaGlsZFZhbHVlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICAgIGFOZXdEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICAgIGRvY0ZyYWcgPSBhTmV3RG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKKyAgICAgICAgY29tbWVudCA9IGFOZXdEb2MuY3JlYXRlQ29tbWVudCgiZGVzY2VuZGFudDEiKTsKKyAgICAgICAgYU5vZGUgPSBkb2NGcmFnLmFwcGVuZENoaWxkKGNvbW1lbnQpOworICAgICAgICBhTm9kZSA9IGRvYy5pbXBvcnROb2RlKGRvY0ZyYWcsIHRydWUpOworICAgICAgICBjaGlsZHJlbiA9IGFOb2RlLmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0aHJvd19TaXplIiwgMSwgY2hpbGRyZW4uZ2V0TGVuZ3RoKCkpOworICAgICAgICBjaGlsZCA9IGFOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgICAgY2hpbGRWYWx1ZSA9IGNoaWxkLmdldE5vZGVWYWx1ZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRlc2NlbmRhbnQxIiwgImRlc2NlbmRhbnQxIiwgY2hpbGRWYWx1ZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnROb2RlNSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIERvY3VtZW50IGFOZXdEb2M7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgTm9kZSBhTm9kZTsKKyAgICAgICAgYm9vbGVhbiBoYXNDaGlsZDsKKyAgICAgICAgRG9jdW1lbnQgb3duZXJEb2N1bWVudDsKKyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICAgIFN0cmluZyBzeXN0ZW07CisgICAgICAgIFN0cmluZyBuYW1lOworICAgICAgICBOb2RlTGlzdCBhZGRyZXNzZXM7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBhTmV3RG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGFkZHJlc3NlcyA9IGFOZXdEb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgYWRkcmVzc2VzLml0ZW0oMCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoImVtcEFkZHJlc3NOb3ROdWxsIiwgZWxlbWVudCk7CisgICAgICAgIGFOb2RlID0gZG9jLmltcG9ydE5vZGUoZWxlbWVudCwgZmFsc2UpOworICAgICAgICBoYXNDaGlsZCA9IGFOb2RlLmhhc0NoaWxkTm9kZXMoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoImhhc0NoaWxkIiwgaGFzQ2hpbGQpOworICAgICAgICBvd25lckRvY3VtZW50ID0gYU5vZGUuZ2V0T3duZXJEb2N1bWVudCgpOworICAgICAgICBkb2NUeXBlID0gb3duZXJEb2N1bWVudC5nZXREb2N0eXBlKCk7CisgICAgICAgIHN5c3RlbSA9IGRvY1R5cGUuZ2V0U3lzdGVtSWQoKTsKKyAgICAgICAgYXNzZXJ0VVJJRXF1YWxzKCJkdGRTeXN0ZW1JZCIsIG51bGwsIG51bGwsIG51bGwsICJzdGFmZk5TLmR0ZCIsIG51bGwsCisgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwgbnVsbCwgc3lzdGVtKTsKKyAgICAgICAgbmFtZSA9IGFOb2RlLmdldE5vZGVOYW1lKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibm9kZU5hbWUiLCAiZW1wOmFkZHJlc3MiLCBuYW1lKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGU2KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRG9jdW1lbnQgYU5ld0RvYzsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBOb2RlIGFOb2RlOworICAgICAgICBib29sZWFuIGhhc0NoaWxkOworICAgICAgICBTdHJpbmcgbmFtZTsKKyAgICAgICAgTm9kZSBjaGlsZDsKKyAgICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgICBOb2RlTGlzdCBhZGRyZXNzZXM7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBhTmV3RG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGFkZHJlc3NlcyA9IGFOZXdEb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgYWRkcmVzc2VzLml0ZW0oMCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoImVtcEFkZHJlc3NOb3ROdWxsIiwgZWxlbWVudCk7CisgICAgICAgIGFOb2RlID0gZG9jLmltcG9ydE5vZGUoZWxlbWVudCwgdHJ1ZSk7CisgICAgICAgIGhhc0NoaWxkID0gYU5vZGUuaGFzQ2hpbGROb2RlcygpOworICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19UcnVlIiwgaGFzQ2hpbGQpOworICAgICAgICBuYW1lID0gYU5vZGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTmFtZSIsICJlbXA6YWRkcmVzcyIsIG5hbWUpOworICAgICAgICBjaGlsZCA9IGFOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKyAgICAgICAgdmFsdWUgPSBjaGlsZC5nZXROb2RlVmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlVmFsdWUiLCAiMjcgU291dGggUm9hZC4gRGFsbGFzLCB0ZXhhcyA5ODU1NiIsIHZhbHVlKTsKKyAgICB9CisKKy8vIEFzc3VtZXMgdmFsaWRhdGlvbi4KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnROb2RlNygpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBEb2N1bWVudCBhTmV3RG9jOworLy8gICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKy8vICAgICAgICBOb2RlIGFOb2RlOworLy8gICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworLy8gICAgICAgIFN0cmluZyBuYW1lOworLy8gICAgICAgIE5vZGUgYXR0cjsKKy8vICAgICAgICBTdHJpbmcgbG5hbWU7CisvLyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5pc3QuZ292IjsKKy8vICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJlbXA6ZW1wbG95ZWUiOworLy8gICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworLy8gICAgICAgIGFOZXdEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisvLyAgICAgICAgZWxlbWVudCA9IGFOZXdEb2MuY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisvLyAgICAgICAgYU5vZGUgPSBkb2MuaW1wb3J0Tm9kZShlbGVtZW50LCBmYWxzZSk7CisvLyAgICAgICAgYXR0cmlidXRlcyA9IGFOb2RlLmdldEF0dHJpYnV0ZXMoKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoInRocm93X1NpemUiLCAxLCBhdHRyaWJ1dGVzLmdldExlbmd0aCgpKTsKKy8vICAgICAgICBuYW1lID0gYU5vZGUuZ2V0Tm9kZU5hbWUoKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lIiwgImVtcDplbXBsb3llZSIsIG5hbWUpOworLy8gICAgICAgIGF0dHIgPSBhdHRyaWJ1dGVzLml0ZW0oMCk7CisvLyAgICAgICAgbG5hbWUgPSBhdHRyLmdldExvY2FsTmFtZSgpOworLy8gICAgICAgIGFzc2VydEVxdWFscygibG5hbWUiLCAiZGVmYXVsdEF0dHIiLCBsbmFtZSk7CisvLyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGU4KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRG9jdW1lbnQgYU5ld0RvYzsKKyAgICAgICAgRG9jdW1lbnRGcmFnbWVudCBkb2NGcmFnOworICAgICAgICBOb2RlIGFOb2RlOworICAgICAgICBib29sZWFuIGhhc0NoaWxkOworICAgICAgICBEb2N1bWVudCBvd25lckRvY3VtZW50OworICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgICAgU3RyaW5nIHN5c3RlbTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGFOZXdEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZG9jRnJhZyA9IGFOZXdEb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOworICAgICAgICBhTm9kZSA9IGRvYy5pbXBvcnROb2RlKGRvY0ZyYWcsIGZhbHNlKTsKKyAgICAgICAgaGFzQ2hpbGQgPSBhTm9kZS5oYXNDaGlsZE5vZGVzKCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJoYXNDaGlsZCIsIGhhc0NoaWxkKTsKKyAgICAgICAgb3duZXJEb2N1bWVudCA9IGFOb2RlLmdldE93bmVyRG9jdW1lbnQoKTsKKyAgICAgICAgZG9jVHlwZSA9IG93bmVyRG9jdW1lbnQuZ2V0RG9jdHlwZSgpOworICAgICAgICBzeXN0ZW0gPSBkb2NUeXBlLmdldFN5c3RlbUlkKCk7CisgICAgICAgIGFzc2VydFVSSUVxdWFscygic3lzdGVtIiwgbnVsbCwgbnVsbCwgbnVsbCwgInN0YWZmTlMuZHRkIiwgbnVsbCwgbnVsbCwKKyAgICAgICAgICAgICAgICBudWxsLCBudWxsLCBzeXN0ZW0pOworICAgIH0KKworLy8gQXNzdW1lcyB2YWxpZGF0aW9uLgorLy8gICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGU5KCkgdGhyb3dzIFRocm93YWJsZSB7CisvLyAgICAgICAgRG9jdW1lbnQgZG9jOworLy8gICAgICAgIERvY3VtZW50IGFOZXdEb2M7CisvLworLy8gICAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdHlMaXN0OworLy8gICAgICAgIEVudGl0eSBlbnRpdHkyOworLy8gICAgICAgIEVudGl0eSBlbnRpdHkxOworLy8gICAgICAgIERvY3VtZW50IG93bmVyRG9jdW1lbnQ7CisvLyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisvLyAgICAgICAgU3RyaW5nIHN5c3RlbTsKKy8vICAgICAgICBTdHJpbmcgZW50aXR5TmFtZTsKKy8vICAgICAgICBTdHJpbmcgcHVibGljVmFsOworLy8gICAgICAgIFN0cmluZyBub3RhdGlvbk5hbWU7CisvLyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisvLyAgICAgICAgYU5ld0RvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworLy8gICAgICAgIGRvY1R5cGUgPSBhTmV3RG9jLmdldERvY3R5cGUoKTsKKy8vICAgICAgICBlbnRpdHlMaXN0ID0gZG9jVHlwZS5nZXRFbnRpdGllcygpOworLy8gICAgICAgIGFzc2VydE5vdE51bGwoImVudGl0aWVzTm90TnVsbCIsIGVudGl0eUxpc3QpOworLy8gICAgICAgIGVudGl0eTIgPSAoRW50aXR5KSBlbnRpdHlMaXN0LmdldE5hbWVkSXRlbSgiZW50NiIpOworLy8gICAgICAgIGVudGl0eTEgPSAoRW50aXR5KSBkb2MuaW1wb3J0Tm9kZShlbnRpdHkyLCBmYWxzZSk7CisvLyAgICAgICAgb3duZXJEb2N1bWVudCA9IGVudGl0eTEuZ2V0T3duZXJEb2N1bWVudCgpOworLy8gICAgICAgIGRvY1R5cGUgPSBvd25lckRvY3VtZW50LmdldERvY3R5cGUoKTsKKy8vICAgICAgICBzeXN0ZW0gPSBkb2NUeXBlLmdldFN5c3RlbUlkKCk7CisvLyAgICAgICAgYXNzZXJ0VVJJRXF1YWxzKCJkdGRTeXN0ZW1JZCIsIG51bGwsIG51bGwsIG51bGwsICJzdGFmZk5TLmR0ZCIsIG51bGwsCisvLyAgICAgICAgICAgICAgICBudWxsLCBudWxsLCBudWxsLCBzeXN0ZW0pOworLy8gICAgICAgIGVudGl0eU5hbWUgPSBlbnRpdHkxLmdldE5vZGVOYW1lKCk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbnRpdHlOYW1lIiwgImVudDYiLCBlbnRpdHlOYW1lKTsKKy8vICAgICAgICBwdWJsaWNWYWwgPSBlbnRpdHkxLmdldFB1YmxpY0lkKCk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbnRpdHlQdWJsaWNJZCIsICJ1cmkiLCBwdWJsaWNWYWwpOworLy8gICAgICAgIHN5c3RlbSA9IGVudGl0eTEuZ2V0U3lzdGVtSWQoKTsKKy8vICAgICAgICBhc3NlcnRVUklFcXVhbHMoImVudGl0eVN5c3RlbUlkIiwgbnVsbCwgbnVsbCwgbnVsbCwgImZpbGUiLCBudWxsLCBudWxsLAorLy8gICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwgc3lzdGVtKTsKKy8vICAgICAgICBub3RhdGlvbk5hbWUgPSBlbnRpdHkxLmdldE5vdGF0aW9uTmFtZSgpOworLy8gICAgICAgIGFzc2VydEVxdWFscygibm90YXRpb25OYW1lIiwgIm5vdGF0aW9uMiIsIG5vdGF0aW9uTmFtZSk7CisvLyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGUxMCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIERvY3VtZW50IGFOZXdEb2M7CisgICAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWY7CisgICAgICAgIE5vZGUgYU5vZGU7CisgICAgICAgIERvY3VtZW50IG93bmVyRG9jdW1lbnQ7CisgICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgICBTdHJpbmcgc3lzdGVtOworICAgICAgICBTdHJpbmcgbmFtZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGFOZXdEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZW50UmVmID0gYU5ld0RvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudFJlZjEiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworICAgICAgICBlbnRSZWYuc2V0Tm9kZVZhbHVlKCJlbnRSZWYxVmFsdWUiKTsKKyAgICAgICAgYU5vZGUgPSBkb2MuaW1wb3J0Tm9kZShlbnRSZWYsIGZhbHNlKTsKKyAgICAgICAgb3duZXJEb2N1bWVudCA9IGFOb2RlLmdldE93bmVyRG9jdW1lbnQoKTsKKyAgICAgICAgZG9jVHlwZSA9IG93bmVyRG9jdW1lbnQuZ2V0RG9jdHlwZSgpOworICAgICAgICBzeXN0ZW0gPSBkb2NUeXBlLmdldFN5c3RlbUlkKCk7CisgICAgICAgIGFzc2VydFVSSUVxdWFscygic3lzdGVtSWQiLCBudWxsLCBudWxsLCBudWxsLCAic3RhZmZOUy5kdGQiLCBudWxsLAorICAgICAgICAgICAgICAgIG51bGwsIG51bGwsIG51bGwsIHN5c3RlbSk7CisgICAgICAgIG5hbWUgPSBhTm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lIiwgImVudFJlZjEiLCBuYW1lKTsKKyAgICB9CisKKy8vIEFzc3VtZXMgdmFsaWRhdGlvbgorLy8gICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGUxMSgpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBEb2N1bWVudCBhTmV3RG9jOworLy8gICAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRSZWY7CisvLyAgICAgICAgTm9kZSBhTm9kZTsKKy8vICAgICAgICBTdHJpbmcgbmFtZTsKKy8vICAgICAgICBOb2RlIGNoaWxkOworLy8gICAgICAgIFN0cmluZyBjaGlsZFZhbHVlOworLy8gICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBidWlsZGVyKTsKKy8vICAgICAgICBhTmV3RG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGJ1aWxkZXIpOworLy8gICAgICAgIGVudFJlZiA9IGFOZXdEb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQzIik7CisvLyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworLy8gICAgICAgIGFOb2RlID0gZG9jLmltcG9ydE5vZGUoZW50UmVmLCB0cnVlKTsKKy8vICAgICAgICBuYW1lID0gYU5vZGUuZ2V0Tm9kZU5hbWUoKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImVudGl0eU5hbWUiLCAiZW50MyIsIG5hbWUpOworLy8gICAgICAgIGNoaWxkID0gYU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOworLy8gICAgICAgIGFzc2VydE5vdE51bGwoImNoaWxkIiwgY2hpbGQpOworLy8gICAgICAgIGNoaWxkVmFsdWUgPSBjaGlsZC5nZXROb2RlVmFsdWUoKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImNoaWxkVmFsdWUiLCAiVGV4YXMiLCBjaGlsZFZhbHVlKTsKKy8vICAgIH0KKworLy8gQXNzdW1lcyB2YWxpZGF0aW9uLgorLy8gICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGUxMigpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBEb2N1bWVudCBhTmV3RG9jOworLy8gICAgICAgIERvY3VtZW50VHlwZSBkb2MxVHlwZTsKKy8vICAgICAgICBOYW1lZE5vZGVNYXAgZW50aXR5TGlzdDsKKy8vICAgICAgICBFbnRpdHkgZW50aXR5MjsKKy8vICAgICAgICBFbnRpdHkgZW50aXR5MTsKKy8vICAgICAgICBEb2N1bWVudCBvd25lckRvY3VtZW50OworLy8gICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworLy8gICAgICAgIFN0cmluZyBzeXN0ZW07CisvLyAgICAgICAgU3RyaW5nIGVudGl0eU5hbWU7CisvLyAgICAgICAgTm9kZSBjaGlsZDsKKy8vICAgICAgICBTdHJpbmcgY2hpbGROYW1lOworLy8gICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworLy8gICAgICAgIGFOZXdEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKy8vICAgICAgICBkb2MxVHlwZSA9IGFOZXdEb2MuZ2V0RG9jdHlwZSgpOworLy8gICAgICAgIGVudGl0eUxpc3QgPSBkb2MxVHlwZS5nZXRFbnRpdGllcygpOworLy8gICAgICAgIGFzc2VydE5vdE51bGwoImVudGl0aWVzTm90TnVsbCIsIGVudGl0eUxpc3QpOworLy8gICAgICAgIGVudGl0eTIgPSAoRW50aXR5KSBlbnRpdHlMaXN0LmdldE5hbWVkSXRlbSgiZW50NCIpOworLy8gICAgICAgIGVudGl0eTEgPSAoRW50aXR5KSBkb2MuaW1wb3J0Tm9kZShlbnRpdHkyLCB0cnVlKTsKKy8vICAgICAgICBvd25lckRvY3VtZW50ID0gZW50aXR5MS5nZXRPd25lckRvY3VtZW50KCk7CisvLyAgICAgICAgZG9jVHlwZSA9IG93bmVyRG9jdW1lbnQuZ2V0RG9jdHlwZSgpOworLy8gICAgICAgIHN5c3RlbSA9IGRvY1R5cGUuZ2V0U3lzdGVtSWQoKTsKKy8vICAgICAgICBhc3NlcnRVUklFcXVhbHMoInN5c3RlbUlkIiwgbnVsbCwgbnVsbCwgbnVsbCwgInN0YWZmTlMuZHRkIiwgbnVsbCwKKy8vICAgICAgICAgICAgICAgIG51bGwsIG51bGwsIG51bGwsIHN5c3RlbSk7CisvLyAgICAgICAgZW50aXR5TmFtZSA9IGVudGl0eTEuZ2V0Tm9kZU5hbWUoKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoImVudGl0eU5hbWUiLCAiZW50NCIsIGVudGl0eU5hbWUpOworLy8gICAgICAgIGNoaWxkID0gZW50aXR5MS5nZXRGaXJzdENoaWxkKCk7CisvLyAgICAgICAgYXNzZXJ0Tm90TnVsbCgibm90bnVsbCIsIGNoaWxkKTsKKy8vICAgICAgICBjaGlsZE5hbWUgPSBjaGlsZC5nZXROb2RlTmFtZSgpOworLy8gICAgICAgIGFzc2VydEVxdWFscygiY2hpbGROYW1lIiwgImVudEVsZW1lbnQxIiwgY2hpbGROYW1lKTsKKy8vICAgIH0KKworLy8gQXNzdW1lcyB2YWxpZGF0aW9uCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0Tm9kZTEzKCkgdGhyb3dzIFRocm93YWJsZSB7CisvLyAgICAgICAgRG9jdW1lbnQgZG9jOworLy8gICAgICAgIERvY3VtZW50IGFOZXdEb2M7CisvLyAgICAgICAgRG9jdW1lbnRUeXBlIGRvYzFUeXBlOworLy8gICAgICAgIE5hbWVkTm9kZU1hcCBub3RhdGlvbkxpc3Q7CisvLyAgICAgICAgTm90YXRpb24gbm90YXRpb247CisvLyAgICAgICAgTm90YXRpb24gYU5vZGU7CisvLyAgICAgICAgRG9jdW1lbnQgb3duZXJEb2N1bWVudDsKKy8vICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKy8vICAgICAgICBTdHJpbmcgc3lzdGVtOworLy8gICAgICAgIFN0cmluZyBwdWJsaWNWYWw7CisvLyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisvLyAgICAgICAgYU5ld0RvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworLy8gICAgICAgIGRvYzFUeXBlID0gYU5ld0RvYy5nZXREb2N0eXBlKCk7CisvLyAgICAgICAgbm90YXRpb25MaXN0ID0gZG9jMVR5cGUuZ2V0Tm90YXRpb25zKCk7CisvLyAgICAgICAgYXNzZXJ0Tm90TnVsbCgibm90YXRpb25zTm90TnVsbCIsIG5vdGF0aW9uTGlzdCk7CisvLyAgICAgICAgbm90YXRpb24gPSAoTm90YXRpb24pIG5vdGF0aW9uTGlzdC5nZXROYW1lZEl0ZW0oIm5vdGF0aW9uMSIpOworLy8gICAgICAgIGFOb2RlID0gKE5vdGF0aW9uKSBkb2MuaW1wb3J0Tm9kZShub3RhdGlvbiwgZmFsc2UpOworLy8gICAgICAgIG93bmVyRG9jdW1lbnQgPSBhTm9kZS5nZXRPd25lckRvY3VtZW50KCk7CisvLyAgICAgICAgZG9jVHlwZSA9IG93bmVyRG9jdW1lbnQuZ2V0RG9jdHlwZSgpOworLy8gICAgICAgIHN5c3RlbSA9IGRvY1R5cGUuZ2V0U3lzdGVtSWQoKTsKKy8vICAgICAgICBhc3NlcnRVUklFcXVhbHMoInN5c3RlbUlkIiwgbnVsbCwgbnVsbCwgbnVsbCwgInN0YWZmTlMuZHRkIiwgbnVsbCwKKy8vICAgICAgICAgICAgICAgIG51bGwsIG51bGwsIG51bGwsIHN5c3RlbSk7CisvLyAgICAgICAgcHVibGljVmFsID0gYU5vZGUuZ2V0UHVibGljSWQoKTsKKy8vICAgICAgICBhc3NlcnRFcXVhbHMoInB1YmxpY0lkIiwgIm5vdGF0aW9uMUZpbGUiLCBwdWJsaWNWYWwpOworLy8gICAgICAgIHN5c3RlbSA9IGFOb2RlLmdldFN5c3RlbUlkKCk7CisvLyAgICAgICAgYXNzZXJ0TnVsbCgibm90YXRpb25TeXN0ZW1JZCIsIHN5c3RlbSk7CisvLyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGUxNCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIERvY3VtZW50IGFOZXdEb2M7CisgICAgICAgIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBwaTsKKyAgICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uIGFOb2RlOworICAgICAgICBEb2N1bWVudCBvd25lckRvY3VtZW50OworICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKyAgICAgICAgU3RyaW5nIHN5c3RlbTsKKyAgICAgICAgU3RyaW5nIHRhcmdldDsKKyAgICAgICAgU3RyaW5nIGRhdGE7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGFOZXdEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgcGkgPSBhTmV3RG9jLmNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbigidGFyZ2V0MSIsICJkYXRhMSIpOworICAgICAgICBhTm9kZSA9IChQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24pIGRvYy5pbXBvcnROb2RlKHBpLCBmYWxzZSk7CisgICAgICAgIG93bmVyRG9jdW1lbnQgPSBhTm9kZS5nZXRPd25lckRvY3VtZW50KCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIm93bmVyRG9jdW1lbnROb3ROdWxsIiwgb3duZXJEb2N1bWVudCk7CisgICAgICAgIGRvY1R5cGUgPSBvd25lckRvY3VtZW50LmdldERvY3R5cGUoKTsKKyAgICAgICAgc3lzdGVtID0gZG9jVHlwZS5nZXRTeXN0ZW1JZCgpOworICAgICAgICBhc3NlcnRVUklFcXVhbHMoInN5c3RlbUlkIiwgbnVsbCwgbnVsbCwgbnVsbCwgInN0YWZmTlMuZHRkIiwgbnVsbCwKKyAgICAgICAgICAgICAgICBudWxsLCBudWxsLCBudWxsLCBzeXN0ZW0pOworICAgICAgICB0YXJnZXQgPSBhTm9kZS5nZXRUYXJnZXQoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwaVRhcmdldCIsICJ0YXJnZXQxIiwgdGFyZ2V0KTsKKyAgICAgICAgZGF0YSA9IGFOb2RlLmdldERhdGEoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwaURhdGEiLCAiZGF0YTEiLCBkYXRhKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEltcG9ydE5vZGUxNSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIERvY3VtZW50IGFOZXdEb2M7CisgICAgICAgIFRleHQgdGV4dDsKKyAgICAgICAgTm9kZSBhTm9kZTsKKyAgICAgICAgRG9jdW1lbnQgb3duZXJEb2N1bWVudDsKKyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICAgIFN0cmluZyBzeXN0ZW07CisgICAgICAgIFN0cmluZyB2YWx1ZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGFOZXdEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgdGV4dCA9IGFOZXdEb2MuY3JlYXRlVGV4dE5vZGUoInRoaXMgaXMgdGV4dCBkYXRhIik7CisgICAgICAgIGFOb2RlID0gZG9jLmltcG9ydE5vZGUodGV4dCwgZmFsc2UpOworICAgICAgICBvd25lckRvY3VtZW50ID0gYU5vZGUuZ2V0T3duZXJEb2N1bWVudCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJvd25lckRvY3VtZW50Tm90TnVsbCIsIG93bmVyRG9jdW1lbnQpOworICAgICAgICBkb2NUeXBlID0gb3duZXJEb2N1bWVudC5nZXREb2N0eXBlKCk7CisgICAgICAgIHN5c3RlbSA9IGRvY1R5cGUuZ2V0U3lzdGVtSWQoKTsKKyAgICAgICAgYXNzZXJ0VVJJRXF1YWxzKCJzeXN0ZW1JZCIsIG51bGwsIG51bGwsIG51bGwsICJzdGFmZk5TLmR0ZCIsIG51bGwsCisgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwgbnVsbCwgc3lzdGVtKTsKKyAgICAgICAgdmFsdWUgPSBhTm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlVmFsdWUiLCAidGhpcyBpcyB0ZXh0IGRhdGEiLCB2YWx1ZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnROb2RlMTYoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBEb2N1bWVudCBhbm90aGVyRG9jOworICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgYW5vdGhlckRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBkb2NUeXBlID0gYW5vdGhlckRvYy5nZXREb2N0eXBlKCk7CisKKyAgICAgICAgeworICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGRvYy5pbXBvcnROb2RlKGRvY1R5cGUsIGZhbHNlKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9UX1NVUFBPUlRFRF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0Tm9kZTE3KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRG9jdW1lbnQgYW5vdGhlckRvYzsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgYW5vdGhlckRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBkb2MuaW1wb3J0Tm9kZShhbm90aGVyRG9jLCBmYWxzZSk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9TVVBQT1JURURfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vSW50ZXJuYWxTdWJzZXQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9JbnRlcm5hbFN1YnNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzOWI3OTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vSW50ZXJuYWxTdWJzZXQuamF2YQpAQCAtMCwwICsxLDgwIEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogICAgIFRoZSAiZ2V0SW50ZXJuYWxTdWJzZXQoKSIgbWV0aG9kIHJldHVybnMKKyAqICAgIHRoZSBpbnRlcm5hbCBzdWJzZXQgYXMgYSBzdHJpbmcgb3IgbnVsbCBpZiB0aGVyZSBpcyBub25lLgorICogICAgVGhpcyBkb2VzIG5vdCBjb250YWluIHRoZSBkZWxpbWl0aW5nIGJyYWNrZXRzLgorICoKKyAqICAgIFJldHJpZXZlIHRoZSBkb2N1bWVudHR5cGUuCisgKiAgICBBcHBseSB0aGUgImdldEludGVybmFsU3Vic2V0KCkiIG1ldGhvZC4gIE51bGwgaXMgcmV0dXJuZWQgc2luY2UgdGhlcmUKKyAqICAgIGlzIG5vdCBhbiBpbnRlcm5hbCBzdWJzZXQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtQ29yZS1Eb2NUeXBlLWludGVybmFsU3Vic2V0Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtQ29yZS1Eb2NUeXBlLWludGVybmFsU3Vic2V0PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBJbnRlcm5hbFN1YnNldCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnRlcm5hbFN1YnNldCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBTdHJpbmcgaW50ZXJuYWw7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmMiIsIGJ1aWxkZXIpOworICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisgICAgICBpbnRlcm5hbCA9IGRvY1R5cGUuZ2V0SW50ZXJuYWxTdWJzZXQoKTsKKyAgICAgIGFzc2VydE51bGwoImludGVybmFsU3Vic2V0TnVsbCIsIGludGVybmFsKTsKKyAgICAgIH0KKworfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vSXNTdXBwb3J0ZWQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Jc1N1cHBvcnRlZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIyN2Q5YzgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vSXNTdXBwb3J0ZWQuamF2YQpAQCAtMCwwICsxLDE5NCBAQAorcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSAiZmVhdHVyZSIgcGFyYW1ldGVyIGluIHRoZSBpc1N1cHBvcnRlZChmZWF0dXJlLHZlcnNpb24pIiBtZXRob2QgaXMgdGhlCisgKiBuYW1lIG9mIHRoZSBmZWF0dXJlIGFuZCB0aGUgdmVyc2lvbiBpcyB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGZlYXR1cmUgdG8KKyAqIHRlc3QuIFhYWCBpcyBOT1QgYSBsZWdhbCB2YWx1ZSBmb3IgdGhlIGZlYXR1cmUgcGFyYW1ldGVyLiBUaGUgbWV0aG9kIHNob3VsZAorICogcmV0dXJuICJmYWxzZSIgc2luY2UgWFhYIGlzIG5vdCBhIHZhbGlkIGZlYXR1cmUuCisgKgorICogUmV0cmlldmUgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgRE9NIGRvY3VtZW50IGJ5IGludm9raW5nIHRoZQorICogImdldERvY3VtZW50RWxlbWVudCgpIiBtZXRob2QuIFRoaXMgc2hvdWxkIGNyZWF0ZSBhIG5vZGUgb2JqZWN0IG9uIHdoaWNoIHRoZQorICogImlzU3VwcG9ydGVkKGZlYXR1cmUsdmVyc2lvbikiIG1ldGhvZCBpcyBpbnZva2VkIHdpdGggImZlYXR1cmUiIGVxdWFsIHRvCisgKiAiWFhYIiBhbmQgdmVyc2lvbiB0byAiMS4wIi4gVGhlIG1ldGhvZCBzaG91bGQgcmV0dXJuIGEgYm9vbGVhbiAiZmFsc2UiIHNpbmNlCisgKiBYWFggaXMgbm90IGEgdmFsaWQgZmVhdHVyZS4KKyAqCisgKiBAYXV0aG9yIE5JU1QKKyAqIEBhdXRob3IgTWFyeSBCcmFkeQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtTm9kZS1zdXBwb3J0czwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIElzU3VwcG9ydGVkIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24xKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdElzU3VwcG9ydGVkMSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGUgcm9vdE5vZGU7CisgICAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBidWlsZGVyKTsKKyAgICAgICAgcm9vdE5vZGUgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIHN0YXRlID0gcm9vdE5vZGUuaXNTdXBwb3J0ZWQoIlhYWCIsICIxLjAiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoInRocm93X0ZhbHNlIiwgc3RhdGUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNTdXBwb3J0ZWQyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZSByb290Tm9kZTsKKyAgICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGJ1aWxkZXIpOworICAgICAgICByb290Tm9kZSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgc3RhdGUgPSByb290Tm9kZS5pc1N1cHBvcnRlZCgiWE1MIiwgIjkuMCIpOworICAgICAgICBhc3NlcnRGYWxzZSgidGhyb3dfRmFsc2UiLCBzdGF0ZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RJc1N1cHBvcnRlZDQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlIHJvb3ROb2RlOworICAgICAgICBib29sZWFuIHN0YXRlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICAgIHJvb3ROb2RlID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgICBzdGF0ZSA9IHJvb3ROb2RlLmlzU3VwcG9ydGVkKCJ4bWwiLCAiMS4wIik7CisgICAgICAgIGFzc2VydFRydWUoInRocm93X1RydWUiLCBzdGF0ZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RJc1N1cHBvcnRlZDUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlIHJvb3ROb2RlOworICAgICAgICBib29sZWFuIHN0YXRlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICAgIHJvb3ROb2RlID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgICBzdGF0ZSA9IHJvb3ROb2RlLmlzU3VwcG9ydGVkKCJjb3JlIiwgIjIuMCIpOworICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19UcnVlIiwgc3RhdGUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNTdXBwb3J0ZWQ2KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZSByb290Tm9kZTsKKyAgICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGJ1aWxkZXIpOworICAgICAgICByb290Tm9kZSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgc3RhdGUgPSByb290Tm9kZS5pc1N1cHBvcnRlZCgieG1sIiwgIjIuMCIpOworICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19UcnVlIiwgc3RhdGUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNTdXBwb3J0ZWQ3KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZSByb290Tm9kZTsKKyAgICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGJ1aWxkZXIpOworICAgICAgICByb290Tm9kZSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgc3RhdGUgPSByb290Tm9kZS5pc1N1cHBvcnRlZCgiWE1MIiwgIiIpOworICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19UcnVlIiwgc3RhdGUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNTdXBwb3J0ZWQ5KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZSByb290Tm9kZTsKKyAgICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGJ1aWxkZXIpOworICAgICAgICByb290Tm9kZSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgc3RhdGUgPSByb290Tm9kZS5pc1N1cHBvcnRlZCgiWE1MIiwgIjEuMCIpOworICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19UcnVlIiwgc3RhdGUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNTdXBwb3J0ZWQxMCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGUgcm9vdE5vZGU7CisgICAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBidWlsZGVyKTsKKyAgICAgICAgcm9vdE5vZGUgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIHN0YXRlID0gcm9vdE5vZGUuaXNTdXBwb3J0ZWQoIkNPUkUiLCAiMi4wIik7CisgICAgICAgIGFzc2VydFRydWUoInRocm93X1RydWUiLCBzdGF0ZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RJc1N1cHBvcnRlZDExKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZSByb290Tm9kZTsKKyAgICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGJ1aWxkZXIpOworICAgICAgICByb290Tm9kZSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKKyAgICAgICAgc3RhdGUgPSByb290Tm9kZS5pc1N1cHBvcnRlZCgiWE1MIiwgIjIuMCIpOworICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19UcnVlIiwgc3RhdGUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJc1N1cHBvcnRlZDEyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIExpc3Q8U3RyaW5nPiBmZWF0dXJlcyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgICAgICBmZWF0dXJlcy5hZGQoIkNvcmUiKTsKKyAgICAgICAgZmVhdHVyZXMuYWRkKCJYTUwiKTsKKyAgICAgICAgZmVhdHVyZXMuYWRkKCJIVE1MIik7CisgICAgICAgIGZlYXR1cmVzLmFkZCgiVmlld3MiKTsKKyAgICAgICAgZmVhdHVyZXMuYWRkKCJTdHlsZVNoZWV0cyIpOworICAgICAgICBmZWF0dXJlcy5hZGQoIkNTUyIpOworICAgICAgICBmZWF0dXJlcy5hZGQoIkNTUzIiKTsKKyAgICAgICAgZmVhdHVyZXMuYWRkKCJFdmVudHMiKTsKKyAgICAgICAgZmVhdHVyZXMuYWRkKCJVSUV2ZW50cyIpOworICAgICAgICBmZWF0dXJlcy5hZGQoIk1vdXNlRXZlbnRzIik7CisgICAgICAgIGZlYXR1cmVzLmFkZCgiTXV0YXRpb25FdmVudHMiKTsKKyAgICAgICAgZmVhdHVyZXMuYWRkKCJIVE1MRXZlbnRzIik7CisgICAgICAgIGZlYXR1cmVzLmFkZCgiUmFuZ2UiKTsKKyAgICAgICAgZmVhdHVyZXMuYWRkKCJUcmF2ZXJzYWwiKTsKKyAgICAgICAgZmVhdHVyZXMuYWRkKCJib2d1cy5ib2d1cy5ib2d1cyIpOworCisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZSByb290Tm9kZTsKKyAgICAgICAgU3RyaW5nIGZlYXR1cmVFbGVtZW50OworICAgICAgICBib29sZWFuIHN0YXRlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICAgIHJvb3ROb2RlID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgICBzdGF0ZSA9IHJvb3ROb2RlLmlzU3VwcG9ydGVkKCJDb3JlIiwgIjIuMCIpOworICAgICAgICBhc3NlcnRUcnVlKCJDb3JlMiIsIHN0YXRlKTsKKyAgICAgICAgZm9yIChpbnQgaW5kZXhOMTAwNzggPSAwOyBpbmRleE4xMDA3OCA8IGZlYXR1cmVzLnNpemUoKTsgaW5kZXhOMTAwNzgrKykgeworICAgICAgICAgICAgZmVhdHVyZUVsZW1lbnQgPSAoU3RyaW5nKSBmZWF0dXJlcy5nZXQoaW5kZXhOMTAwNzgpOworICAgICAgICAgICAgc3RhdGUgPSByb290Tm9kZS5pc1N1cHBvcnRlZChmZWF0dXJlRWxlbWVudCwgIjEuMCIpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGluZGV4TjEwMDgzID0gMDsgaW5kZXhOMTAwODMgPCBmZWF0dXJlcy5zaXplKCk7IGluZGV4TjEwMDgzKyspIHsKKyAgICAgICAgICAgIGZlYXR1cmVFbGVtZW50ID0gKFN0cmluZykgZmVhdHVyZXMuZ2V0KGluZGV4TjEwMDgzKTsKKyAgICAgICAgICAgIHN0YXRlID0gcm9vdE5vZGUuaXNTdXBwb3J0ZWQoZmVhdHVyZUVsZW1lbnQsICIyLjAiKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNTdXBwb3J0ZWQxMygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGUgcm9vdE5vZGU7CisgICAgICAgIGJvb2xlYW4gc3RhdGU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBidWlsZGVyKTsKKyAgICAgICAgcm9vdE5vZGUgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIHN0YXRlID0gcm9vdE5vZGUuaXNTdXBwb3J0ZWQoIkNvcmUiLCAiIik7CisgICAgICAgIGFzc2VydFRydWUoIkNvcmUiLCBzdGF0ZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RJc1N1cHBvcnRlZDE0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZSByb290Tm9kZTsKKyAgICAgICAgYm9vbGVhbiBzdGF0ZTsKKyAgICAgICAgU3RyaW5nIG51bGxTdHJpbmcgPSBudWxsOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBidWlsZGVyKTsKKyAgICAgICAgcm9vdE5vZGUgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIHN0YXRlID0gcm9vdE5vZGUuaXNTdXBwb3J0ZWQoIkNvcmUiLCBudWxsU3RyaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29yZSIsIHN0YXRlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTG9jYWxOYW1lLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTG9jYWxOYW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTc5NmVmMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Mb2NhbE5hbWUuamF2YQpAQCAtMCwwICsxLDEwMiBAQAorcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5BdHRyOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSAiZ2V0TG9jYWxOYW1lKCkiIG1ldGhvZCBmb3IgYSBOb2RlIHJldHVybnMgdGhlIGxvY2FsIHBhcnQgb2YgdGhlCisgKiBxdWFsaWZpZWQgbmFtZSBvZiB0aGlzIG5vZGUsIGFuZCBmb3Igbm9kZXMgb2YgYW55IHR5cGUgb3RoZXIgdGhhbgorICogRUxFTUVOVF9OT0RFIGFuZCBBVFRSSUJVVEVfTk9ERSBhbmQgbm9kZXMgY3JlYXRlZCB3aXRoIGEgRE9NIExldmVsIDEgbWV0aG9kLAorICogdGhpcyBpcyBudWxsLgorICoKKyAqIFJldHJpZXZlIHRoZSBmaXJzdCBlbXA6YWRkcmVzcyBub2RlIGFuZCBnZXQgdGhlIGF0dHJpYnV0ZXMgb2YgdGhpcyBub2RlLiIKKyAqIFRoZW4gYXBwbHkgdGhlIGdldExvY2FsTmFtZSgpIG1ldGhvZCB0byB0aGUgZW1wOmRvbWVzdGljIGF0dHJpYnV0ZS4gVGhlCisgKiBtZXRob2Qgc2hvdWxkIHJldHVybiAiZG9tZXN0aWMiLgorICoKKyAqIEBhdXRob3IgTklTVAorICogQGF1dGhvciBNYXJ5IEJyYWR5CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNMb2NhbE4iPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNMb2NhbE48L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBMb2NhbE5hbWUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TG9jYWxOYW1lMSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBFbGVtZW50IHRlc3RBZGRyOworICAgICAgICBBdHRyIGFkZHJBdHRyOworICAgICAgICBTdHJpbmcgbG9jYWxOYW1lOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICAgIHRlc3RBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoImVtcEFkZHJOb3ROdWxsIiwgdGVzdEFkZHIpOworICAgICAgICBhZGRyQXR0ciA9IHRlc3RBZGRyLmdldEF0dHJpYnV0ZU5vZGUoImVtcDpkb21lc3RpYyIpOworICAgICAgICBsb2NhbE5hbWUgPSBhZGRyQXR0ci5nZXRMb2NhbE5hbWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJsb2NhbE5hbWUiLCAiZG9tZXN0aWMiLCBsb2NhbE5hbWUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TG9jYWxOYW1lMigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGUgY3JlYXRlZE5vZGU7CisgICAgICAgIFN0cmluZyBsb2NhbE5hbWU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBjcmVhdGVkTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50KCJ0ZXN0OmVtcGxveWVlIik7CisgICAgICAgIGxvY2FsTmFtZSA9IGNyZWF0ZWROb2RlLmdldExvY2FsTmFtZSgpOworICAgICAgICBhc3NlcnROdWxsKCJsb2NhbE5hbWVOdWxsIiwgbG9jYWxOYW1lKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldExvY2FsTmFtZTMoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgTm9kZSB0ZXN0RW1wbG95ZWU7CisgICAgICAgIE5vZGUgdGV4dE5vZGU7CisgICAgICAgIFN0cmluZyBsb2NhbE5hbWU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWVJZCIpOworICAgICAgICB0ZXN0RW1wbG95ZWUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgICB0ZXh0Tm9kZSA9IHRlc3RFbXBsb3llZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICAgIGxvY2FsTmFtZSA9IHRleHROb2RlLmdldExvY2FsTmFtZSgpOworICAgICAgICBhc3NlcnROdWxsKCJ0ZXh0Tm9kZUxvY2FsTmFtZSIsIGxvY2FsTmFtZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRMb2NhbE5hbWU0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgICBTdHJpbmcgZW1wbG95ZWVMb2NhbE5hbWU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgICAgdGVzdEVtcGxveWVlID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgICAgZW1wbG95ZWVMb2NhbE5hbWUgPSB0ZXN0RW1wbG95ZWUuZ2V0TG9jYWxOYW1lKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibG5hbWUiLCAiZW1wbG95ZWUiLCBlbXBsb3llZUxvY2FsTmFtZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL05hbWVkTm9kZU1hcEdldE5hbWVkSXRlbU5TLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTmFtZWROb2RlTWFwR2V0TmFtZWRJdGVtTlMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYmRhYzE4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL05hbWVkTm9kZU1hcEdldE5hbWVkSXRlbU5TLmphdmEKQEAgLTAsMCArMSwxOTkgQEAKKy8qCisgVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorIGFuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCisgVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisgQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCisgUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgUFVSUE9TRS4KKworIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyAqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CitpbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFVzaW5nIHRoZSBtZXRob2QgZ2V0TmFtZWRJdGVtTlMsIHJldHJlaXZlIHRoZSBlbnRpdHkgImVudDEiIGFuZCBub3RhdGlvbgorICogIm5vdGF0aW9uMSIgZnJvbSBhIE5hbWVkTm9kZU1hcCBvZiB0aGlzIERvY3VtZW50VHlwZXMgZW50aXRpZXMgYW5kIG5vdGF0aW9ucy4KKyAqIEJvdGggc2hvdWxkIGJlIG51bGwgc2luY2UgZW50aXRpZXMgYW5kIG5vdGF0aW9ucyBhcmUgbm90IG5hbWVzcGFjZWQuCisgKgorICogQGF1dGhvciBJQk0KKyAqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldE5hbWVkSXRlbU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtZ2V0TmFtZWRJdGVtTlM8L2E+CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTk8L2E+CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD00MDciPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD00MDc8L2E+CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly9saXN0cy53My5vcmcvQXJjaGl2ZXMvTWVtYmVyL3czYy1kb20taWcvMjAwM05vdi8wMDE2Lmh0bWwiPmh0dHA6Ly9saXN0cy53My5vcmcvQXJjaGl2ZXMvTWVtYmVyL3czYy1kb20taWcvMjAwM05vdi8wMDE2Lmh0bWw8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBOYW1lZE5vZGVNYXBHZXROYW1lZEl0ZW1OUyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMigpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworLy8gQXNzdW1lcyB2YWxpZGF0aW9uLgorLy8gICAgcHVibGljIHZvaWQgdGVzdEdldE5hbWVkSXRlbU5TMSgpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZTsKKy8vICAgICAgICBOYW1lZE5vZGVNYXAgZW50aXRpZXM7CisvLyAgICAgICAgTmFtZWROb2RlTWFwIG5vdGF0aW9uczsKKy8vICAgICAgICBFbnRpdHkgZW50aXR5OworLy8gICAgICAgIE5vdGF0aW9uIG5vdGF0aW9uOworLy8KKy8vICAgICAgICBTdHJpbmcgbnVsbE5TID0gbnVsbDsKKy8vCisvLyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisvLyAgICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisvLyAgICAgICAgZW50aXRpZXMgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisvLyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50aXRpZXNOb3ROdWxsIiwgZW50aXRpZXMpOworLy8gICAgICAgIG5vdGF0aW9ucyA9IGRvY1R5cGUuZ2V0Tm90YXRpb25zKCk7CisvLyAgICAgICAgYXNzZXJ0Tm90TnVsbCgibm90YXRpb25zTm90TnVsbCIsIG5vdGF0aW9ucyk7CisvLyAgICAgICAgZW50aXR5ID0gKEVudGl0eSkgZW50aXRpZXMuZ2V0TmFtZWRJdGVtTlMobnVsbE5TLCAiZW50MSIpOworLy8gICAgICAgIGFzc2VydE5vdE51bGwoImVudGl0eU51bGwiLCBlbnRpdHkpOworLy8gICAgICAgIG5vdGF0aW9uID0gKE5vdGF0aW9uKSBub3RhdGlvbnMuZ2V0TmFtZWRJdGVtTlMobnVsbE5TLCAibm90YXRpb24xIik7CisvLyAgICAgICAgYXNzZXJ0Tm90TnVsbCgibm90YXRpb25OdWxsIiwgbm90YXRpb24pOworLy8gICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXROYW1lZEl0ZW1OUzIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgICAgTm9kZSBlbGVtZW50OworICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLAorICAgICAgICAgICAgICAgICJhZGRyZXNzIik7CisgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwKKyAgICAgICAgICAgICAgICAiZG9tZXN0aWMiKTsKKyAgICAgICAgYXR0ck5hbWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczAyIiwgImVtcDpkb21lc3RpYyIsIGF0dHJOYW1lKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldE5hbWVkSXRlbU5TMygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgICBOb2RlIGVsZW1lbnQ7CisgICAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgICBBdHRyIG5ld0F0dHIxOworICAgICAgICBBdHRyIG5ld0F0dHIyOworCisgICAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJyb290Iik7CisgICAgICAgIG5ld0F0dHIxID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vTDEiLCAiTDE6YXR0Iik7CisgICAgICAgICgoRWxlbWVudCkgLyogTm9kZSAqL2VsZW1lbnQpLnNldEF0dHJpYnV0ZU5vZGVOUyhuZXdBdHRyMSk7CisgICAgICAgIG5ld0F0dHIyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vTDIiLCAiTDI6YXR0Iik7CisgICAgICAgICgoRWxlbWVudCkgLyogTm9kZSAqL2VsZW1lbnQpLnNldEF0dHJpYnV0ZU5vZGVOUyhuZXdBdHRyMik7CisgICAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgYXR0cmlidXRlID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtTlMoCisgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cudzMub3JnL0RPTS9MMiIsICJhdHQiKTsKKyAgICAgICAgYXR0ck5hbWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uczAzIiwgIkwyOmF0dCIsIGF0dHJOYW1lKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldE5hbWVkSXRlbU5TNCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgICBBdHRyIG5ld0F0dHIxOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgU3RyaW5nIGF0dHJOYW1lOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJhZGRyZXNzIik7CisgICAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgICAgbmV3QXR0cjEgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9MMSIsICJzdHJlZXQiKTsKKyAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMobmV3QXR0cjEpOworICAgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKAorICAgICAgICAgICAgICAgICJodHRwOi8vd3d3LnczLm9yZy9ET00vTDEiLCAic3RyZWV0Iik7CisgICAgICAgIGF0dHJOYW1lID0gYXR0cmlidXRlLmdldE5vZGVOYW1lKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnMwNCIsICJzdHJlZXQiLCBhdHRyTmFtZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXROYW1lZEl0ZW1OUzUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgICAgTm9kZSBlbGVtZW50OworICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCIqIiwgImFkZHJlc3MiKTsKKyAgICAgICAgZWxlbWVudCA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgYXR0cmlidXRlID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtTlMoIioiLCAic3RyZWV0Iik7CisgICAgICAgIGFzc2VydE51bGwoIm5hbWVkbm9kZW1hcGdldG5hbWVkaXRlbW5zMDUiLCBhdHRyaWJ1dGUpOworICAgIH0KKworLy8gQXNzdW1lcyB2YWxpZGF0aW9uLgorLy8gICAgcHVibGljIHZvaWQgdGVzdEdldE5hbWVkSXRlbU5TNigpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlc01hcDE7CisvLyAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXNNYXAyOworLy8gICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKy8vICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKy8vICAgICAgICBBdHRyIG5ld0F0dHIxOworLy8KKy8vICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKy8vICAgICAgICBTdHJpbmcgYXR0ck5hbWU7CisvLyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisvLyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiKiIsICJhZGRyZXNzIik7CisvLyAgICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDEpOworLy8gICAgICAgIGF0dHJpYnV0ZXNNYXAxID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisvLyAgICAgICAgYXR0cmlidXRlc01hcDIgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKy8vICAgICAgICBuZXdBdHRyMSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL0wxIiwgInN0cmVldCIpOworLy8gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZU5TKG5ld0F0dHIxKTsKKy8vICAgICAgICBhdHRyaWJ1dGUgPSAoQXR0cikgYXR0cmlidXRlc01hcDEuZ2V0TmFtZWRJdGVtTlMoCisvLyAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvRE9NL0wxIiwgInN0cmVldCIpOworLy8gICAgICAgIGF0dHJOYW1lID0gYXR0cmlidXRlLmdldE5vZGVOYW1lKCk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lZG5vZGVtYXBnZXRuYW1lZGl0ZW1uc01hcDEwNiIsICJzdHJlZXQiLCBhdHRyTmFtZSk7CisvLyAgICAgICAgYXR0cmlidXRlID0gKEF0dHIpIGF0dHJpYnV0ZXNNYXAyLmdldE5hbWVkSXRlbU5TKAorLy8gICAgICAgICAgICAgICAgImh0dHA6Ly93d3cudzMub3JnL0RPTS9MMSIsICJzdHJlZXQiKTsKKy8vICAgICAgICBhdHRyTmFtZSA9IGF0dHJpYnV0ZS5nZXROb2RlTmFtZSgpOworLy8gICAgICAgIGFzc2VydEVxdWFscygibmFtZWRub2RlbWFwZ2V0bmFtZWRpdGVtbnNNYXAyMDYiLCAic3RyZWV0IiwgYXR0ck5hbWUpOworLy8gICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTmFtZWROb2RlTWFwUmVtb3ZlTmFtZWRJdGVtTlMuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9OYW1lZE5vZGVNYXBSZW1vdmVOYW1lZEl0ZW1OUy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE5Nzk1ZTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTmFtZWROb2RlTWFwUmVtb3ZlTmFtZWRJdGVtTlMuamF2YQpAQCAtMCwwICsxLDI5NCBAQAorLyoKKyBUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCisgYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KKyBUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKyBDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCisgUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgUFVSUE9TRS4KKworIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyAqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CitpbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBUaGUgbWV0aG9kIHJlbW92ZU5hbWVkSXRlbU5TIHJlbW92ZXMgYSBub2RlIHNwZWNpZmllZCBieSBsb2NhbCBuYW1lIGFuZAorICogbmFtZXNwYWNlCisgKgorICogUmV0cmVpdmUgYW4gYXR0cmlidXRlIG5vZGUgYW5kIHRoZW4gcmVtb3ZlIGZyb20gdGhlIE5hbWVkTm9kZU1hcC4gVmVyaWZ5IGlmCisgKiB0aGUgYXR0cmlidXRlIG5vZGUgd2FzIGFjdHVhbGx5IHJlbW92ZSBmcm9tIHRoZSBub2RlIG1hcC4KKyAqCisgKiBAYXV0aG9yIElCTQorICogQGF1dGhvciBOZWlsIERlbGltYQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRDU4QjE5MyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUQ1OEIxOTM8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBOYW1lZE5vZGVNYXBSZW1vdmVOYW1lZEl0ZW1OUyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMigpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVOYW1lZEl0ZW1OUzEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgICAgTm9kZSBlbGVtZW50OworICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwKKyAgICAgICAgICAgICAgICAiYWRkcmVzcyIpOworICAgICAgICBlbGVtZW50ID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgICAgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgICBhdHRyaWJ1dGUgPSAoQXR0cikgYXR0cmlidXRlcy5yZW1vdmVOYW1lZEl0ZW1OUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsCisgICAgICAgICAgICAgICAgImRvbWVzdGljIik7CisgICAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwKKyAgICAgICAgICAgICAgICAiZG9tZXN0aWMiKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgibmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMSIsIGF0dHJpYnV0ZSk7CisgICAgfQorCisvLyBBc3N1bWVzIHZhbGlkYXRpb24uCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlTmFtZWRJdGVtTlMyKCkgdGhyb3dzIFRocm93YWJsZSB7CisvLyAgICAgICAgRG9jdW1lbnQgZG9jOworLy8gICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworLy8gICAgICAgIE5vZGUgZWxlbWVudDsKKy8vICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKy8vICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKy8vICAgICAgICBTdHJpbmcgYXR0clZhbHVlOworLy8gICAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworLy8KKy8vICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKy8vICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwKKy8vICAgICAgICAgICAgICAgICJlbXBsb3llZSIpOworLy8gICAgICAgIGVsZW1lbnQgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworLy8gICAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKy8vICAgICAgICBhdHRyaWJ1dGUgPSAoQXR0cikgYXR0cmlidXRlcy5yZW1vdmVOYW1lZEl0ZW1OUyhudWxsTlMsICJkZWZhdWx0QXR0ciIpOworLy8gICAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKG51bGxOUywgImRlZmF1bHRBdHRyIik7CisvLyAgICAgICAgYXR0clZhbHVlID0gYXR0cmlidXRlLmdldE5vZGVWYWx1ZSgpOworLy8gICAgICAgIGFzc2VydE5vdE51bGwoIm5hbWVkbm9kZW1hcHJlbW92ZW5hbWVkaXRlbW5zMDIiLCBhdHRyaWJ1dGUpOworLy8gICAgICAgIGFzc2VydEVxdWFscygibmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMl9hdHRyVmFsdWUiLCAiZGVmYXVsdFZhbCIsCisvLyAgICAgICAgICAgICAgICBhdHRyVmFsdWUpOworLy8gICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVOYW1lZEl0ZW1OUzMoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgICAgTm9kZSBlbGVtZW50OworICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKworICAgICAgICBBdHRyIGF0dHJpYnV0ZTE7CisgICAgICAgIEF0dHIgYXR0cmlidXRlMjsKKyAgICAgICAgU3RyaW5nIG5vZGVOYW1lOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgInJvb3QiKTsKKyAgICAgICAgYXR0cmlidXRlMSA9IGRvYworICAgICAgICAgICAgICAgIC5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL0wxIiwgIkwxOmF0dCIpOworICAgICAgICAoKEVsZW1lbnQpIC8qIE5vZGUgKi9lbGVtZW50KS5zZXRBdHRyaWJ1dGVOb2RlTlMoYXR0cmlidXRlMSk7CisgICAgICAgIGF0dHJpYnV0ZTIgPSBkb2MKKyAgICAgICAgICAgICAgICAuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9MMiIsICJMMjphdHQiKTsKKyAgICAgICAgKChFbGVtZW50KSAvKiBOb2RlICovZWxlbWVudCkuc2V0QXR0cmlidXRlTm9kZU5TKGF0dHJpYnV0ZTIpOworICAgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLnJlbW92ZU5hbWVkSXRlbU5TKAorICAgICAgICAgICAgICAgICJodHRwOi8vd3d3LnczLm9yZy9ET00vTDEiLCAiYXR0Iik7CisgICAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKAorICAgICAgICAgICAgICAgICJodHRwOi8vd3d3LnczLm9yZy9ET00vTDIiLCAiYXR0Iik7CisgICAgICAgIG5vZGVOYW1lID0gYXR0cmlidXRlLmdldE5vZGVOYW1lKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwMiIsICJMMjphdHQiLCBub2RlTmFtZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIF90ZXN0UmVtb3ZlTmFtZWRJdGVtTlM0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICAgIE5vZGUgZWxlbWVudDsKKyAgICAgICAgQXR0ciBhdHRyaWJ1dGU7CisKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCIqIiwgImVtcGxveWVlIik7CisgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAgIGF0dHJpYnV0ZXMucmVtb3ZlTmFtZWRJdGVtTlMoImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIiwgInhtbG5zIik7CisgICAgICAgIGF0dHJpYnV0ZSA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKAorICAgICAgICAgICAgICAgICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIsICJ4bWxucyIpOworICAgICAgICBhc3NlcnROdWxsKCJuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA0XzEiLCBhdHRyaWJ1dGUpOworICAgICAgICBhdHRyaWJ1dGVzLnJlbW92ZU5hbWVkSXRlbU5TKCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIsICJkbXN0YyIpOworICAgICAgICBhdHRyaWJ1dGUgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW1OUygKKyAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iLCAiZG1zdGMiKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgibmFtZWRub2RlbWFwcmVtb3ZlbmFtZWRpdGVtbnMwNF8yIiwgYXR0cmlidXRlKTsKKyAgICB9CisKKy8vIEFzc3VtZXMgdmFsaWRhdGlvbi4KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVOYW1lZEl0ZW1OUzUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKy8vICAgICAgICBEb2N1bWVudCBkb2M7CisvLyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisvLyAgICAgICAgTmFtZWROb2RlTWFwIGVudGl0aWVzOworLy8gICAgICAgIE5hbWVkTm9kZU1hcCBub3RhdGlvbnM7CisvLworLy8gICAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworLy8KKy8vICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKy8vICAgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKy8vICAgICAgICBlbnRpdGllcyA9IGRvY1R5cGUuZ2V0RW50aXRpZXMoKTsKKy8vICAgICAgICBhc3NlcnROb3ROdWxsKCJlbnRpdGllc05vdE51bGwiLCBlbnRpdGllcyk7CisvLyAgICAgICAgbm90YXRpb25zID0gZG9jVHlwZS5nZXROb3RhdGlvbnMoKTsKKy8vICAgICAgICBhc3NlcnROb3ROdWxsKCJub3RhdGlvbnNOb3ROdWxsIiwgbm90YXRpb25zKTsKKy8vCisvLyAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgZW50aXRpZXMucmVtb3ZlTmFtZWRJdGVtTlMobnVsbE5TLCAiZW50MSIpOworLy8gICAgICAgICAgICBmYWlsKCJlbnRpdHlfdGhyb3dfRE9NRXhjZXB0aW9uIik7CisvLworLy8gICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworLy8gICAgICAgICAgICBzd2l0Y2ggKGV4LmNvZGUpIHsKKy8vICAgICAgICAgICAgY2FzZSA4OgorLy8gICAgICAgICAgICAgICAgYnJlYWs7CisvLyAgICAgICAgICAgIGNhc2UgNzoKKy8vICAgICAgICAgICAgICAgIGJyZWFrOworLy8gICAgICAgICAgICBkZWZhdWx0OgorLy8gICAgICAgICAgICAgICAgdGhyb3cgZXg7CisvLyAgICAgICAgICAgIH0KKy8vICAgICAgICB9CisvLworLy8gICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgIG5vdGF0aW9ucy5yZW1vdmVOYW1lZEl0ZW1OUyhudWxsTlMsICJub3RhdGlvbjEiKTsKKy8vICAgICAgICAgICAgZmFpbCgibm90YXRpb25fdGhyb3dfRE9NRXhjZXB0aW9uIik7CisvLworLy8gICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworLy8gICAgICAgICAgICBzd2l0Y2ggKGV4LmNvZGUpIHsKKy8vICAgICAgICAgICAgY2FzZSA4OgorLy8gICAgICAgICAgICAgICAgYnJlYWs7CisvLyAgICAgICAgICAgIGNhc2UgNzoKKy8vICAgICAgICAgICAgICAgIGJyZWFrOworLy8gICAgICAgICAgICBkZWZhdWx0OgorLy8gICAgICAgICAgICAgICAgdGhyb3cgZXg7CisvLyAgICAgICAgICAgIH0KKy8vICAgICAgICB9CisvLyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZU5hbWVkSXRlbU5TNigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgICBOb2RlIGVsZW1lbnQ7CisKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwKKyAgICAgICAgICAgICAgICAiZW1wbG95ZWUiKTsKKyAgICAgICAgZWxlbWVudCA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5yZW1vdmVOYW1lZEl0ZW1OUygiaHR0cDovL3d3dy5OaXN0LmdvdiIsICJkb21lc3RpYyIpOworICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT1RfRk9VTkRfRVJSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9GT1VORF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlTmFtZWRJdGVtTlM3KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICAgIE5vZGUgZWxlbWVudDsKKworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLAorICAgICAgICAgICAgICAgICJlbXBsb3llZSIpOworICAgICAgICBlbGVtZW50ID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgICAgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLnJlbW92ZU5hbWVkSXRlbU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgImRvbWVzdGljIik7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9UX0ZPVU5EX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVOYW1lZEl0ZW1OUzgoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworCisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsCisgICAgICAgICAgICAgICAgImFkZHJlc3MiKTsKKyAgICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLCAiZG9tZXN0aWMiKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5yZW1vdmVOYW1lZEl0ZW1OUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJkb21lc3RpYyIpOworICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT1RfRk9VTkRfRVJSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PVF9GT1VORF9FUlIiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlTmFtZWRJdGVtTlM5KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICAgIE5hbWVkTm9kZU1hcCBuZXdBdHRyaWJ1dGVzOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLAorICAgICAgICAgICAgICAgICJhZGRyZXNzIik7CisgICAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgICAgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgICBhdHRyaWJ1dGUgPSAoQXR0cikgYXR0cmlidXRlcy5yZW1vdmVOYW1lZEl0ZW1OUygiaHR0cDovL3d3dy5uaXN0LmdvdiIsCisgICAgICAgICAgICAgICAgImRvbWVzdGljIik7CisgICAgICAgIG5ld0F0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgYXR0cmlidXRlID0gKEF0dHIpIG5ld0F0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLAorICAgICAgICAgICAgICAgICJkb21lc3RpYyIpOworICAgICAgICBhc3NlcnROdWxsKCJuYW1lZG5vZGVtYXByZW1vdmVuYW1lZGl0ZW1uczA5IiwgYXR0cmlidXRlKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9OYW1lZE5vZGVNYXBTZXROYW1lZEl0ZW1OUy5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL05hbWVkTm9kZU1hcFNldE5hbWVkSXRlbU5TLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzAyNDNlNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9OYW1lZE5vZGVNYXBTZXROYW1lZEl0ZW1OUy5qYXZhCkBAIC0wLDAgKzEsNDAzIEBACisvKgorIFRoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKKyBhbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorIFRoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworIENvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwKKyBSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyBQVVJQT1NFLgorCisgU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworICovCisKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBUaGUgbWV0aG9kIHNldE5hbWVkSXRlbU5TIGFkZHMgYSBub2RlIHVzaW5nIGl0cyBuYW1lc3BhY2VVUkkgYW5kIGxvY2FsTmFtZS4KKyAqIElmIGEgbm9kZSB3aXRoIHRoYXQgbmFtZXNwYWNlIFVSSSBhbmQgdGhhdCBsb2NhbCBuYW1lIGlzIGFscmVhZHkgcHJlc2VudCBpbgorICogdGhpcyBtYXAsIGl0IGlzIHJlcGxhY2VkIGJ5IHRoZSBuZXcgb25lLgorICoKKyAqIFJldHJlaXZlIHRoZSBmaXJzdCBlbGVtZW50IHdob3NlIGxvY2FsTmFtZSBpcyBhZGRyZXNzIGFuZCBuYW1lc3BhY2VVUkkKKyAqIGh0dHA6Ly93d3cubmlzdC5nb3YiLCBhbmQgcHV0IGl0cyBhdHRyaWJ1dGVzIGludG8gYSBuYW1lZCBub2RlIG1hcC4gQ3JlYXRlIGEKKyAqIG5ldyBhdHRyaWJ1dGUgbm9kZSBhbmQgYWRkIGl0IHRvIHRoaXMgbWFwLiBWZXJpZnkgaWYgdGhlIGF0dHIgbm9kZSB3YXMKKyAqIHN1Y2Nlc3NmdWxseSBhZGRlZCBieSBjaGVja2luZyB0aGUgbm9kZU5hbWUgb2YgdGhlIHJldHJlaXZlZCBhdHR0cmlidXRlLgorICoKKyAqIEBhdXRob3IgSUJNCisgKiBAYXV0aG9yIE5laWwgRGVsaW1hCisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1nZXROYW1lZEl0ZW1OUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELWdldE5hbWVkSXRlbU5TPC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTmFtZWROb2RlTWFwU2V0TmFtZWRJdGVtTlMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBDaGFuZ2VkIHRvIGNvbmZpZ3VyYXRpb24gIzIuIFRoaXMgdGVzdCBjYXNlIGp1c3QgZG9lc24ndCBtYWtlCisgICAgICAgICAgICAvLyBzZW5zZSB3aXRob3V0IGEgbmFtZXNwYWNlLWF3YXJlIHBhcnNlci4gSXQgYWN0dWFsbHkgZmFpbHMgZXZlbgorICAgICAgICAgICAgLy8gb24gdGhlIEpESyBpbiB0aGF0IGNhc2UuCisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0TmFtZWRJdGVtTlMxKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICAgIE5vZGUgZWxlbWVudDsKKyAgICAgICAgQXR0ciBhdHRyaWJ1dGU7CisKKyAgICAgICAgQXR0ciBuZXdBdHRyMTsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLAorICAgICAgICAgICAgICAgICJhZGRyZXNzIik7CisgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAgIG5ld0F0dHIxID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vTDEiLCAic3RyZWV0cyIpOworICAgICAgICAoKEVsZW1lbnQpIC8qIE5vZGUgKi9lbGVtZW50KS5zZXRBdHRyaWJ1dGVOb2RlTlMobmV3QXR0cjEpOworICAgICAgICBhdHRyaWJ1dGUgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW1OUygKKyAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvRE9NL0wxIiwgInN0cmVldHMiKTsKKyAgICAgICAgYXR0ck5hbWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZU5hbWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczAxIiwgInN0cmVldHMiLCBhdHRyTmFtZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXROYW1lZEl0ZW1OUzIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgICAgQXR0ciBhdHRyaWJ1dGUxOworCisgICAgICAgIFN0cmluZyBhdHRyTmFtZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJyb290Iik7CisgICAgICAgIGF0dHJpYnV0ZTEgPSBkb2MKKyAgICAgICAgICAgICAgICAuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9MMSIsICJMMTphdHQiKTsKKyAgICAgICAgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworICAgICAgICBhdHRyaWJ1dGVzLnNldE5hbWVkSXRlbU5TKGF0dHJpYnV0ZTEpOworICAgICAgICBhdHRyaWJ1dGUgPSAoQXR0cikgYXR0cmlidXRlcy5nZXROYW1lZEl0ZW1OUygKKyAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvRE9NL0wxIiwgImF0dCIpOworICAgICAgICBhdHRyTmFtZSA9IGF0dHJpYnV0ZS5nZXROb2RlTmFtZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5hbWVkbm9kZW1hcHNldG5hbWVkaXRlbW5zMDIiLCAiTDE6YXR0IiwgYXR0ck5hbWUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0TmFtZWRJdGVtTlMzKCkgdGhyb3dzIFRocm93YWJsZSB7CisKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBEb2N1bWVudCBkb2NBbHQ7CisgICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlc0FsdDsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0QWx0OworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudEFsdDsKKyAgICAgICAgQXR0ciBhdHRyOworCisgICAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCIqIiwgImFkZHJlc3MiKTsKKyAgICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAgIGRvY0FsdCA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdEFsdCA9IGRvY0FsdC5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCIqIiwgImFkZHJlc3MiKTsKKyAgICAgICAgZWxlbWVudEFsdCA9IChFbGVtZW50KSBlbGVtZW50TGlzdEFsdC5pdGVtKDEpOworICAgICAgICBhdHRyaWJ1dGVzQWx0ID0gZWxlbWVudEFsdC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAgIGF0dHIgPSAoQXR0cikgYXR0cmlidXRlc0FsdC5nZXROYW1lZEl0ZW1OUyhudWxsTlMsICJzdHJlZXQiKTsKKyAgICAgICAgYXR0cmlidXRlc0FsdC5yZW1vdmVOYW1lZEl0ZW1OUyhudWxsTlMsICJzdHJlZXQiKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5zZXROYW1lZEl0ZW1OUyhhdHRyKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X1dST05HX0RPQ1VNRU5UX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXROYW1lZEl0ZW1OUzQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBkb21JbXBsOworICAgICAgICBEb2N1bWVudCBkb2NBbHQ7CisgICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlID0gbnVsbDsKKworICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgQXR0ciBhdHRyQWx0OworCisgICAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCIqIiwgImFkZHJlc3MiKTsKKyAgICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgICBhdHRyaWJ1dGVzID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAgIGRvbUltcGwgPSBkb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKKyAgICAgICAgZG9jQWx0ID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudChudWxsTlMsICJuZXdEb2MiLCBkb2NUeXBlKTsKKyAgICAgICAgYXR0ckFsdCA9IGRvY0FsdC5jcmVhdGVBdHRyaWJ1dGVOUyhudWxsTlMsICJzdHJlZXQiKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5zZXROYW1lZEl0ZW1OUyhhdHRyQWx0KTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X1dST05HX0RPQ1VNRU5UX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorCisvLyBBc3N1bWVzIHZhbGlkYXRpb24uCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0TmFtZWRJdGVtTlM1KCkgdGhyb3dzIFRocm93YWJsZSB7CisvLyAgICAgICAgRG9jdW1lbnQgZG9jOworLy8gICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworLy8gICAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdGllczsKKy8vICAgICAgICBOYW1lZE5vZGVNYXAgbm90YXRpb25zOworLy8gICAgICAgIEVudGl0eSBlbnRpdHk7CisvLyAgICAgICAgTm90YXRpb24gbm90YXRpb247CisvLworLy8gICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworLy8gICAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworLy8gICAgICAgIGVudGl0aWVzID0gZG9jVHlwZS5nZXRFbnRpdGllcygpOworLy8gICAgICAgIGFzc2VydE5vdE51bGwoImVudGl0aWVzTm90TnVsbCIsIGVudGl0aWVzKTsKKy8vICAgICAgICBub3RhdGlvbnMgPSBkb2NUeXBlLmdldE5vdGF0aW9ucygpOworLy8gICAgICAgIGFzc2VydE5vdE51bGwoIm5vdGF0aW9uc05vdE51bGwiLCBub3RhdGlvbnMpOworLy8gICAgICAgIGVudGl0eSA9IChFbnRpdHkpIGVudGl0aWVzLmdldE5hbWVkSXRlbSgiZW50MSIpOworLy8gICAgICAgIG5vdGF0aW9uID0gKE5vdGF0aW9uKSBub3RhdGlvbnMuZ2V0TmFtZWRJdGVtKCJub3RhdGlvbjEiKTsKKy8vCisvLyAgICAgICAgeworLy8gICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKy8vICAgICAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgICAgIGVudGl0aWVzLnNldE5hbWVkSXRlbU5TKGVudGl0eSk7CisvLyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworLy8gICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworLy8gICAgICAgICAgICB9CisvLyAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUl9lbnRpdGllcyIsIHN1Y2Nlc3MpOworLy8gICAgICAgIH0KKy8vCisvLyAgICAgICAgeworLy8gICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKy8vICAgICAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgICAgIG5vdGF0aW9ucy5zZXROYW1lZEl0ZW1OUyhub3RhdGlvbik7CisvLyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworLy8gICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworLy8gICAgICAgICAgICB9CisvLyAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUl9ub3RhdGlvbnMiLCBzdWNjZXNzKTsKKy8vICAgICAgICB9CisvLyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFNldE5hbWVkSXRlbU5TNigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBBdHRyIGF0dHI7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiYWRkcmVzcyIpOworICAgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgYXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKCJodHRwOi8vd3d3LnVzYS5jb20iLAorICAgICAgICAgICAgICAgICJkb21lc3RpYyIpOworICAgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5zZXROYW1lZEl0ZW1OUyhhdHRyKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5VU0VfQVRUUklCVVRFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA2Iiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFNldE5hbWVkSXRlbU5TNygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBBdHRyIGF0dHI7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiYWRkcmVzcyIpOworICAgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgYXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKCJodHRwOi8vd3d3LnVzYS5jb20iLAorICAgICAgICAgICAgICAgICJkb21lc3RpYyIpOworICAgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5zZXROYW1lZEl0ZW1OUyhhdHRyKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5VU0VfQVRUUklCVVRFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA3Iiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFNldE5hbWVkSXRlbU5TOCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBBdHRyIGF0dHI7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiYWRkcmVzcyIpOworICAgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgYXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKCJodHRwOi8vd3d3LnVzYS5jb20iLAorICAgICAgICAgICAgICAgICJkb21lc3RpYyIpOworICAgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5zZXROYW1lZEl0ZW1OUyhhdHRyKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5VU0VfQVRUUklCVVRFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJuYW1lZG5vZGVtYXBzZXRuYW1lZGl0ZW1uczA4Iiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisKKy8vIEFzc3VtZXMgdmFsaWRhdGlvbi4KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RTZXROYW1lZEl0ZW1OUzkoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKy8vICAgICAgICBEb2N1bWVudCBkb2M7CisvLyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisvLyAgICAgICAgTmFtZWROb2RlTWFwIGVudGl0aWVzOworLy8gICAgICAgIE5hbWVkTm9kZU1hcCBub3RhdGlvbnM7CisvLyAgICAgICAgQXR0ciBhdHRyOworLy8gICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworLy8gICAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworLy8gICAgICAgIGVudGl0aWVzID0gZG9jVHlwZS5nZXRFbnRpdGllcygpOworLy8gICAgICAgIG5vdGF0aW9ucyA9IGRvY1R5cGUuZ2V0Tm90YXRpb25zKCk7CisvLyAgICAgICAgYXR0ciA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLCAidGVzdCIpOworLy8KKy8vICAgICAgICB7CisvLyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworLy8gICAgICAgICAgICB0cnkgeworLy8gICAgICAgICAgICAgICAgZW50aXRpZXMuc2V0TmFtZWRJdGVtTlMoYXR0cik7CisvLyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworLy8gICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworLy8gICAgICAgICAgICB9CisvLyAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUl9lbnRpdGllcyIsIHN1Y2Nlc3MpOworLy8gICAgICAgIH0KKy8vCisvLyAgICAgICAgeworLy8gICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKy8vICAgICAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgICAgIG5vdGF0aW9ucy5zZXROYW1lZEl0ZW1OUyhhdHRyKTsKKy8vICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisvLyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisvLyAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSX25vdGF0aW9ucyIsIHN1Y2Nlc3MpOworLy8gICAgICAgIH0KKy8vICAgIH0KKworLy8gQXNzdW1lcyB2YWxpZGF0aW9uLgorLy8gICAgcHVibGljIHZvaWQgdGVzdFNldE5hbWVkSXRlbU5TMTAoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKy8vICAgICAgICBEb2N1bWVudCBkb2M7CisvLyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisvLyAgICAgICAgTmFtZWROb2RlTWFwIGVudGl0aWVzOworLy8gICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworLy8gICAgICAgIEVudGl0eSBlbnRpdHk7CisvLworLy8gICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKy8vICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKy8vCisvLyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisvLyAgICAgICAgZG9jVHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7CisvLyAgICAgICAgZW50aXRpZXMgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7CisvLyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50aXRpZXNOb3ROdWxsIiwgZW50aXRpZXMpOworLy8gICAgICAgIGVudGl0eSA9IChFbnRpdHkpIGVudGl0aWVzLmdldE5hbWVkSXRlbSgiZW50MSIpOworLy8gICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLAorLy8gICAgICAgICAgICAgICAgImFkZHJlc3MiKTsKKy8vICAgICAgICBlbGVtZW50ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisvLyAgICAgICAgYXR0cmlidXRlcyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOworLy8KKy8vICAgICAgICB7CisvLyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworLy8gICAgICAgICAgICB0cnkgeworLy8gICAgICAgICAgICAgICAgYXR0cmlidXRlcy5zZXROYW1lZEl0ZW1OUyhlbnRpdHkpOworLy8gICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKy8vICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSKTsKKy8vICAgICAgICAgICAgfQorLy8gICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19ISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBzdWNjZXNzKTsKKy8vICAgICAgICB9CisvLyAgICB9CisKKy8vIEFzc3VtZXMgdmFsaWRhdGlvbi4KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RTZXROYW1lZEl0ZW1OUzExKCkgdGhyb3dzIFRocm93YWJsZSB7CisvLyAgICAgICAgRG9jdW1lbnQgZG9jOworLy8gICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworLy8gICAgICAgIE5hbWVkTm9kZU1hcCBub3RhdGlvbnM7CisvLyAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisvLyAgICAgICAgTm90YXRpb24gbm90YXRpb247CisvLyAgICAgICAgRWxlbWVudCBlbGVtZW50OworLy8gICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworLy8KKy8vICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKy8vICAgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKy8vICAgICAgICBub3RhdGlvbnMgPSBkb2NUeXBlLmdldE5vdGF0aW9ucygpOworLy8gICAgICAgIGFzc2VydE5vdE51bGwoIm5vdGF0aW9uc05vdE51bGwiLCBub3RhdGlvbnMpOworLy8gICAgICAgIG5vdGF0aW9uID0gKE5vdGF0aW9uKSBub3RhdGlvbnMuZ2V0TmFtZWRJdGVtKCJub3RhdGlvbjEiKTsKKy8vICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwKKy8vICAgICAgICAgICAgICAgICJhZGRyZXNzIik7CisvLyAgICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworLy8gICAgICAgIGF0dHJpYnV0ZXMgPSBlbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKy8vCisvLyAgICAgICAgeworLy8gICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKy8vICAgICAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuc2V0TmFtZWRJdGVtTlMobm90YXRpb24pOworLy8gICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKy8vICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSKTsKKy8vICAgICAgICAgICAgfQorLy8gICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19ISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBzdWNjZXNzKTsKKy8vICAgICAgICB9CisvLyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTmFtZXNwYWNlVVJJLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTmFtZXNwYWNlVVJJLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWVhYjlkYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9OYW1lc3BhY2VVUkkuamF2YQpAQCAtMCwwICsxLDEyOSBAQAorLyoKKyBUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCisgYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KKyBUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKyBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwKKyBSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyBQVVJQT1NFLgorCisgU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworICovCisKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5BdHRyOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBUaGUgImdldE5hbWVzcGFjZVVSSSgpIiBtZXRob2QgZm9yIGFuIEF0dHJpYnV0ZSByZXR1cm5zIHRoZSBuYW1lc3BhY2UgVVJJIG9mCisgKiB0aGlzIG5vZGUsIG9yIG51bGwgaWYgdW5zcGVjaWZpZWQuCisgKgorICogUmV0cmlldmUgdGhlIGZpcnN0ICJlbXA6YWRkcmVzcyIgbm9kZSB3aGljaCBoYXMgYW4gYXR0cmlidXRlIG9mCisgKiAiZW1wOmRpc3RyaWN0IiB0aGF0IGlzIHNwZWNpZmllZCBpbiB0aGUgRFRELiBJbnZva2UgdGhlICJnZXROYW1lc3BhY2VVUkkoKSIKKyAqIG1ldGhvZCBvbiB0aGUgYXR0cmlidXRlLiBUaGUgbWV0aG9kIHNob3VsZCByZXR1cm4gImh0dHA6Ly93d3cubmlzdC5nb3YiLgorICoKKyAqIEBhdXRob3IgTklTVAorICogQGF1dGhvciBNYXJ5IEJyYWR5CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNuYW1lIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TbmFtZTwvYT4KKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzOCI+aHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIzODwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE5hbWVzcGFjZVVSSSBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMigpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworLy8gQXNzdW1lcyB2YWxpZGF0aW9uLgorLy8gICAgcHVibGljIHZvaWQgdGVzdEdldE5hbWVzcGFjZVVSSTEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKy8vICAgICAgICBEb2N1bWVudCBkb2M7CisvLyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisvLyAgICAgICAgRWxlbWVudCB0ZXN0QWRkcjsKKy8vICAgICAgICBBdHRyIGFkZHJBdHRyOworLy8gICAgICAgIFN0cmluZyBhdHRyTmFtZXNwYWNlVVJJOworLy8gICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworLy8gICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6YWRkcmVzcyIpOworLy8gICAgICAgIHRlc3RBZGRyID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisvLyAgICAgICAgYWRkckF0dHIgPSB0ZXN0QWRkci5nZXRBdHRyaWJ1dGVOb2RlTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLAorLy8gICAgICAgICAgICAgICAgImRpc3RyaWN0Iik7CisvLyAgICAgICAgYXR0ck5hbWVzcGFjZVVSSSA9IGFkZHJBdHRyLmdldE5hbWVzcGFjZVVSSSgpOworLy8gICAgICAgIGFzc2VydEVxdWFscygibmFtZXNwYWNlVVJJIiwgImh0dHA6Ly93d3cubmlzdC5nb3YiLCBhdHRyTmFtZXNwYWNlVVJJKTsKKy8vICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TmFtZXNwYWNlVVJJMigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBFbGVtZW50IHRlc3RBZGRyOworICAgICAgICBBdHRyIGFkZHJBdHRyOworICAgICAgICBTdHJpbmcgYXR0ck5hbWVzcGFjZVVSSTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6YWRkcmVzcyIpOworICAgICAgICB0ZXN0QWRkciA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgICBhc3NlcnROb3ROdWxsKCJlbXBBZGRyZXNzTm90TnVsbCIsIHRlc3RBZGRyKTsKKyAgICAgICAgYWRkckF0dHIgPSB0ZXN0QWRkci5nZXRBdHRyaWJ1dGVOb2RlTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLAorICAgICAgICAgICAgICAgICJkb21lc3RpYyIpOworICAgICAgICBhdHRyTmFtZXNwYWNlVVJJID0gYWRkckF0dHIuZ2V0TmFtZXNwYWNlVVJJKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibmFtZXNwYWNlVVJJIiwgImh0dHA6Ly93d3cubmlzdC5nb3YiLCBhdHRyTmFtZXNwYWNlVVJJKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldE5hbWVzcGFjZVVSSTMoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgTm9kZSB0ZXN0RW1wbG95ZWU7CisgICAgICAgIFN0cmluZyBlbXBsb3llZU5hbWVzcGFjZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgICB0ZXN0RW1wbG95ZWUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgICBhc3NlcnROb3ROdWxsKCJlbXBsb3llZU5vdE51bGwiLCB0ZXN0RW1wbG95ZWUpOworICAgICAgICBlbXBsb3llZU5hbWVzcGFjZSA9IHRlc3RFbXBsb3llZS5nZXROYW1lc3BhY2VVUkkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJuYW1lc3BhY2VVUkkiLCAiaHR0cDovL3d3dy5uaXN0LmdvdiIsIGVtcGxveWVlTmFtZXNwYWNlKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldE5hbWVzcGFjZVVSSTQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgTm9kZSB0ZXN0RW1wbG95ZWU7CisgICAgICAgIFN0cmluZyBlbXBsb3llZU5hbWVzcGFjZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgICB0ZXN0RW1wbG95ZWUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgICBlbXBsb3llZU5hbWVzcGFjZSA9IHRlc3RFbXBsb3llZS5nZXROYW1lc3BhY2VVUkkoKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgidGhyb3dfTnVsbCIsIGVtcGxveWVlTmFtZXNwYWNlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTm9kZUdldExvY2FsTmFtZS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL05vZGVHZXRMb2NhbE5hbWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZWFhMjVkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL05vZGVHZXRMb2NhbE5hbWUuamF2YQpAQCAtMCwwICsxLDk1IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkF0dHI7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogIFRoZSBtZXRob2QgZ2V0TG9jYWxOYW1lIHJldHVybnMgdGhlIGxvY2FsIHBhcnQgb2YgdGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoaXMgbm9kZS4KKyAqCisgKiAgQ2VhdGUgdHdvIG5ldyBlbGVtZW50IG5vZGVzIGFuZCBhdHJpYnV0ZSBub2Rlcywgd2l0aCBhbmQgd2l0aG91dCBuYW1lc3BhY2UgcHJlZml4ZXMuCisgKiAgUmV0cmVpdmUgdGhlIGxvY2FsIHBhcnQgb2YgdGhlaXIgcXVhbGlmaWVkIG5hbWVzIHVzaW5nIGdldExvY2FsTmFtZSBhbmQgdmVycmlmeQorICogIGlmIGl0IGlzIGNvcnJlY3QuCisqIEBhdXRob3IgSUJNCisqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TTG9jYWxOIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TTG9jYWxOPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBOb2RlR2V0TG9jYWxOYW1lIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24xKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgdGVzdEdldExvY2FsTmFtZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgRWxlbWVudCBxZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cjsKKyAgICAgIEF0dHIgcWF0dHI7CisgICAgICBTdHJpbmcgbG9jYWxFbGVtTmFtZTsKKyAgICAgIFN0cmluZyBsb2NhbFFFbGVtTmFtZTsKKyAgICAgIFN0cmluZyBsb2NhbEF0dHJOYW1lOworICAgICAgU3RyaW5nIGxvY2FsUUF0dHJOYW1lOworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGJ1aWxkZXIpOworICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L2VsZW0iLCAiZWxlbSIpOworICAgICAgcWVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9lbGVtIiwgInF1YWw6cWVsZW0iKTsKKyAgICAgIGF0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L2F0dHIiLCAiYXR0ciIpOworICAgICAgcWF0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L2F0dHIiLCAicXVhbDpxYXR0ciIpOworICAgICAgbG9jYWxFbGVtTmFtZSA9IGVsZW1lbnQuZ2V0TG9jYWxOYW1lKCk7CisgICAgICBsb2NhbFFFbGVtTmFtZSA9IHFlbGVtZW50LmdldExvY2FsTmFtZSgpOworICAgICAgbG9jYWxBdHRyTmFtZSA9IGF0dHIuZ2V0TG9jYWxOYW1lKCk7CisgICAgICBsb2NhbFFBdHRyTmFtZSA9IHFhdHRyLmdldExvY2FsTmFtZSgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlZ2V0bG9jYWxuYW1lMDNfbG9jYWxFbGVtTmFtZSIsICJlbGVtIiwgbG9jYWxFbGVtTmFtZSk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVnZXRsb2NhbG5hbWUwM19sb2NhbFFFbGVtTmFtZSIsICJxZWxlbSIsIGxvY2FsUUVsZW1OYW1lKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZWdldGxvY2FsbmFtZTAzX2xvY2FsQXR0ck5hbWUiLCAiYXR0ciIsIGxvY2FsQXR0ck5hbWUpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlZ2V0bG9jYWxuYW1lMDNfbG9jYWxRQXR0ck5hbWUiLCAicWF0dHIiLCBsb2NhbFFBdHRyTmFtZSk7CisgICAgICB9CisKK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL05vZGVHZXROYW1lc3BhY2VVUkkuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Ob2RlR2V0TmFtZXNwYWNlVVJJLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjI3NzA5YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Ob2RlR2V0TmFtZXNwYWNlVVJJLmphdmEKQEAgLTAsMCArMSw5OSBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxLTIwMDMgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkF0dHI7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogIFRoZSBtZXRob2QgZ2V0TmFtZXNwYWNlVVJJIHJldHVybnMgdGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhpcyBub2RlLCBvciBudWxsIGlmIGl0IGlzIHVuc3BlY2lmaWVkCisgKiAgRm9yIG5vZGVzIG9mIGFueSB0eXBlIG90aGVyIHRoYW4gRUxFTUVOVF9OT0RFIGFuZCBBVFRSSUJVVEVfTk9ERSBhbmQgbm9kZXMgY3JlYXRlZCB3aXRoCisgKiAgYSBET00gTGV2ZWwgMSBtZXRob2QsIHN1Y2ggYXMgY3JlYXRlRWxlbWVudCBmcm9tIHRoZSBEb2N1bWVudCBpbnRlcmZhY2UsIHRoaXMgaXMgYWx3YXlzIG51bGwuCisgKgorICogIENlYXRlIHR3byBuZXcgZWxlbWVudCBub2RlcyBhbmQgYXRyaWJ1dGUgbm9kZXMsIHdpdGggYW5kIHdpdGhvdXQgbmFtZXNwYWNlIHByZWZpeGVzLgorICogIFJldHJlaXZlIHRoZWlyIG5hbWVzcGFjZVVSSSdzIHVzaW5nIGdldE5hbWVzcGFjZVVSSSBhbmQgdmVycmlmeSBpZiBpdCBpcyBjb3JyZWN0LgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU25hbWUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Ob2RlTlNuYW1lPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTkiPmh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yNTk8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIE5vZGVHZXROYW1lc3BhY2VVUkkgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TmFtZXNwYWNlVVJJKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBEb2N1bWVudCBkb2M7CisgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICBFbGVtZW50IGVsZW1lbnROUzsKKyAgICAgIEF0dHIgYXR0cjsKKyAgICAgIEF0dHIgYXR0ck5TOworICAgICAgU3RyaW5nIGVsZW1OU1VSSTsKKyAgICAgIFN0cmluZyBlbGVtTlNVUklOdWxsOworICAgICAgU3RyaW5nIGF0dHJOU1VSSTsKKyAgICAgIFN0cmluZyBhdHRyTlNVUklOdWxsOworICAgICAgU3RyaW5nIG51bGxOUyA9IG51bGw7CisKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBidWlsZGVyKTsKKyAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKG51bGxOUywgImVsZW0iKTsKKyAgICAgIGVsZW1lbnROUyA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L2VsZW0iLCAicXVhbDpxZWxlbSIpOworICAgICAgYXR0ciA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUyhudWxsTlMsICJhdHRyIik7CisgICAgICBhdHRyTlMgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L2F0dHIiLCAicXVhbDpxYXR0ciIpOworICAgICAgZWxlbU5TVVJJID0gZWxlbWVudE5TLmdldE5hbWVzcGFjZVVSSSgpOworICAgICAgZWxlbU5TVVJJTnVsbCA9IGVsZW1lbnQuZ2V0TmFtZXNwYWNlVVJJKCk7CisgICAgICBhdHRyTlNVUkkgPSBhdHRyTlMuZ2V0TmFtZXNwYWNlVVJJKCk7CisgICAgICBhdHRyTlNVUklOdWxsID0gYXR0ci5nZXROYW1lc3BhY2VVUkkoKTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZWdldG5hbWVzcGFjZXVyaTAzX2VsZW1OU1VSSSIsICJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9lbGVtIiwgZWxlbU5TVVJJKTsKKyAgICAgIGFzc2VydE51bGwoIm5vZGVnZXRuYW1lc3BhY2V1cmkwM18xIiwgZWxlbU5TVVJJTnVsbCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVnZXRuYW1lc3BhY2V1cmkwM19hdHRyTlNVUkkiLCAiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvYXR0ciIsIGF0dHJOU1VSSSk7CisgICAgICBhc3NlcnROdWxsKCJub2RlZ2V0bmFtZXNwYWNldXJpMDNfMiIsIGF0dHJOU1VSSU51bGwpOworICAgICAgfQorCit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Ob2RlR2V0T3duZXJEb2N1bWVudC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL05vZGVHZXRPd25lckRvY3VtZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTUwNWVhYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Ob2RlR2V0T3duZXJEb2N1bWVudC5qYXZhCkBAIC0wLDAgKzEsMTEwIEBACisvKgorIFRoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKKyBhbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorIFRoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworIENvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbAorIFJpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorIFBVUlBPU0UuCisKKyBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisgKi8KKworcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRUeXBlOworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogVGhlIG1ldGhvZCBnZXRPd25lckRvY3VtZW50IHJldHVybnMgdGhlIERvY3VtZW50IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcworICogbm9kZQorICoKKyAqIENyZWF0ZSBhIG5ldyBEb2N1bWVudFR5cGUgbm9kZS4gU2luY2UgdGhpcyBub2RlIGlzIG5vdCB1c2VkIHdpdGggYW55IERvY3VtZW50CisgKiB5ZXQgdmVyaWZ5IGlmIHRoZSBvd25lckRvY3VtZW50IGlzIG51bGwuCisgKgorICogQGF1dGhvciBJQk0KKyAqIEBhdXRob3IgTmVpbCBEZWxpbWEKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI25vZGUtb3duZXJEb2MiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNub2RlLW93bmVyRG9jPC9hPgorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5Ij5odHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjU5PC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTm9kZUdldE93bmVyRG9jdW1lbnQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0T3duZXJEb2N1bWVudDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBEb2N1bWVudCBvd25lckRvYzsKKyAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICAgIFN0cmluZyBudWxsSUQgPSBudWxsOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBidWlsZGVyKTsKKyAgICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgICBkb2NUeXBlID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudFR5cGUoIm15ZG9jIiwgbnVsbElELCBudWxsSUQpOworICAgICAgICBvd25lckRvYyA9IGRvY1R5cGUuZ2V0T3duZXJEb2N1bWVudCgpOworICAgICAgICBhc3NlcnROdWxsKCJub2RlZ2V0b3duZXJkb2N1bWVudDAxIiwgb3duZXJEb2MpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0T3duZXJEb2N1bWVudDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBEb2N1bWVudCBuZXdEb2M7CisgICAgICAgIEVsZW1lbnQgbmV3RWxlbTsKKyAgICAgICAgRG9jdW1lbnQgb3duZXJEb2NEb2M7CisgICAgICAgIERvY3VtZW50IG93bmVyRG9jRWxlbTsKKyAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICAgIFN0cmluZyBudWxsTlMgPSBudWxsOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBidWlsZGVyKTsKKyAgICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgICBkb2NUeXBlID0gZG9tSW1wbC5jcmVhdGVEb2N1bWVudFR5cGUoIm15ZG9jIiwgbnVsbE5TLCBudWxsTlMpOworICAgICAgICBuZXdEb2MgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJteWRvYyIsCisgICAgICAgICAgICAgICAgZG9jVHlwZSk7CisgICAgICAgIG93bmVyRG9jRG9jID0gbmV3RG9jLmdldE93bmVyRG9jdW1lbnQoKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgibm9kZWdldG93bmVyZG9jdW1lbnQwMl8xIiwgb3duZXJEb2NEb2MpOworICAgICAgICBuZXdFbGVtID0gbmV3RG9jCisgICAgICAgICAgICAgICAgLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLCAibXllbGVtIik7CisgICAgICAgIG93bmVyRG9jRWxlbSA9IG5ld0VsZW0uZ2V0T3duZXJEb2N1bWVudCgpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJub2RlZ2V0b3duZXJkb2N1bWVudDAyXzIiLCBvd25lckRvY0VsZW0pOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Ob2RlR2V0UHJlZml4LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTm9kZUdldFByZWZpeC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEzMTk3ZTgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTm9kZUdldFByZWZpeC5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiAgICAgVGhlIG1ldGhvZCBnZXRQcmVmaXggcmV0dXJucyB0aGUgbmFtZXNwYWNlIHByZWZpeCBvZiB0aGlzIG5vZGUsIG9yIG51bGwgaWYgaXQgaXMgdW5zcGVjaWZpZWQuCisgKgorICogICBDZWF0ZSB0d28gbmV3IGVsZW1lbnQgbm9kZXMgYW5kIGF0cmlidXRlIG5vZGVzLCB3aXRoIGFuZCB3aXRob3V0IG5hbWVzcGFjZSBwcmVmaXhlcy4KKyAqICAgUmV0cmVpdmUgdGhlIHByZWZpeCBwYXJ0IG9mIHRoZWlyIHF1YWxpZmllZCBuYW1lcyB1c2luZyBnZXRQcmVmaXggYW5kIHZlcmlmeQorICogICBpZiBpdCBpcyBjb3JyZWN0LgorKiBAYXV0aG9yIElCTQorKiBAYXV0aG9yIE5laWwgRGVsaW1hCisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeDwvYT4KKyovCitwdWJsaWMgZmluYWwgY2xhc3MgTm9kZUdldFByZWZpeCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKworICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgdGVzdEdldFByZWZpeCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgRWxlbWVudCBxZWxlbWVudDsKKyAgICAgIEF0dHIgYXR0cjsKKyAgICAgIEF0dHIgcWF0dHI7CisgICAgICBTdHJpbmcgZWxlbU5vUHJlZml4OworICAgICAgU3RyaW5nIGVsZW1QcmVmaXg7CisgICAgICBTdHJpbmcgYXR0ck5vUHJlZml4OworICAgICAgU3RyaW5nIGF0dHJQcmVmaXg7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICBlbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvZWxlbSIsICJlbGVtIik7CisgICAgICBxZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L2VsZW0iLCAicXVhbDpxZWxlbSIpOworICAgICAgYXR0ciA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvYXR0ciIsICJhdHRyIik7CisgICAgICBxYXR0ciA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvYXR0ciIsICJxdWFsOnFhdHRyIik7CisgICAgICBlbGVtTm9QcmVmaXggPSBlbGVtZW50LmdldFByZWZpeCgpOworICAgICAgZWxlbVByZWZpeCA9IHFlbGVtZW50LmdldFByZWZpeCgpOworICAgICAgYXR0ck5vUHJlZml4ID0gYXR0ci5nZXRQcmVmaXgoKTsKKyAgICAgIGF0dHJQcmVmaXggPSBxYXR0ci5nZXRQcmVmaXgoKTsKKyAgICAgIGFzc2VydE51bGwoIm5vZGVnZXRwcmVmaXgwM18xIiwgZWxlbU5vUHJlZml4KTsKKyAgICAgIGFzc2VydEVxdWFscygibm9kZWdldHByZWZpeDAzXzIiLCAicXVhbCIsIGVsZW1QcmVmaXgpOworICAgICAgYXNzZXJ0TnVsbCgibm9kZWdldHByZWZpeDAzXzMiLCBhdHRyTm9QcmVmaXgpOworICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlZ2V0cHJlZml4MDNfNCIsICJxdWFsIiwgYXR0clByZWZpeCk7CisgICAgICB9CisKK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL05vZGVIYXNBdHRyaWJ1dGVzLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTm9kZUhhc0F0dHJpYnV0ZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMDU4NDg1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL05vZGVIYXNBdHRyaWJ1dGVzLmphdmEKQEAgLTAsMCArMSwxNDEgQEAKKy8qCisgVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorIGFuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCisgVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisgQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbAorIFJpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorIFBVUlBPU0UuCisKKyBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisgKi8KKworcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7CitpbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBUaGUgbWV0aG9kIGhhc0F0dHJpYnV0ZXMgcmV0dXJucyB3aGV0aGVyIHRoaXMgbm9kZSAoaWYgaXQgaXMgYW4gZWxlbWVudCkgaGFzCisgKiBhbnkgYXR0cmlidXRlcy4gUmV0cmVpdmUgYW4gZWxlbWVudCBub2RlIHdpdGhvdXQgYXR0cmlidXRlcy4gVmVyaWZ5IGlmCisgKiBoYXNBdHRyaWJ1dGVzIHJldHVybnMgZmFsc2UuIFJldHJlaXZlIGFub3RoZXIgZWxlbWVudCBub2RlIHdpdGggYXR0cmlidXRlcy4KKyAqIFZlcmlmeSBpZiBoYXNBdHRyaWJ1dGVzIHJldHVybnMgdHJ1ZS4KKyAqCisgKiBAYXV0aG9yIElCTQorICogQGF1dGhvciBOZWlsIERlbGltYQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZUhhc0F0dHJzIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZUhhc0F0dHJzPC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTm9kZUhhc0F0dHJpYnV0ZXMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzQXR0cmlidXRlczEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBib29sZWFuIGhhc0F0dHJpYnV0ZXM7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgICAgaGFzQXR0cmlidXRlcyA9IGVsZW1lbnQuaGFzQXR0cmlidXRlcygpOworICAgICAgICBhc3NlcnRGYWxzZSgibm9kZWhhc2F0dHJpYnV0ZXMwMV8xIiwgaGFzQXR0cmlidXRlcyk7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisgICAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgICAgaGFzQXR0cmlidXRlcyA9IGVsZW1lbnQuaGFzQXR0cmlidXRlcygpOworICAgICAgICBhc3NlcnRUcnVlKCJub2RlaGFzYXR0cmlidXRlczAxXzIiLCBoYXNBdHRyaWJ1dGVzKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEhhc0F0dHJpYnV0ZXMyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICAgIGJvb2xlYW4gaGFzQXR0cmlidXRlczsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgICBoYXNBdHRyaWJ1dGVzID0gZG9jVHlwZS5oYXNBdHRyaWJ1dGVzKCk7CisgICAgICAgIGFzc2VydEZhbHNlKCJub2RlaGFzYXR0cmlidXRlczAyIiwgaGFzQXR0cmlidXRlcyk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RIYXNBdHRyaWJ1dGVzMygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIGJvb2xlYW4gaGFzQXR0cmlidXRlczsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6ZW1wbG95ZWUiKTsKKyAgICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgICBhc3NlcnROb3ROdWxsKCJlbXBFbXBsb3llZU5vdE51bGwiLCBlbGVtZW50KTsKKyAgICAgICAgaGFzQXR0cmlidXRlcyA9IGVsZW1lbnQuaGFzQXR0cmlidXRlcygpOworICAgICAgICBhc3NlcnRUcnVlKCJoYXNBdHRyaWJ1dGVzIiwgaGFzQXR0cmlidXRlcyk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RIYXNBdHRyaWJ1dGVzNCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIERvY3VtZW50IG5ld0RvYzsKKyAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGUgPSBudWxsOworCisgICAgICAgIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGw7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50VGVzdDsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50RG9jOworICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKworCisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBib29sZWFuIGhhc0F0dHJpYnV0ZXM7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBkb21JbXBsID0gZG9jLmdldEltcGxlbWVudGF0aW9uKCk7CisgICAgICAgIG5ld0RvYyA9IGRvbUltcGwuY3JlYXRlRG9jdW1lbnQoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0IiwgInRlc3QiLAorICAgICAgICAgICAgICAgIGRvY1R5cGUpOworICAgICAgICBlbGVtZW50ID0gbmV3RG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLAorICAgICAgICAgICAgICAgICJkb206ZWxlbSIpOworICAgICAgICBhdHRyaWJ1dGUgPSBuZXdEb2MuY3JlYXRlQXR0cmlidXRlKCJhdHRyIik7CisgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZShhdHRyaWJ1dGUpOworICAgICAgICBlbGVtZW50RG9jID0gbmV3RG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgICBlbGVtZW50RG9jLmFwcGVuZENoaWxkKGVsZW1lbnQpOworICAgICAgICBlbGVtZW50TGlzdCA9IG5ld0RvYy5nZXRFbGVtZW50c0J5VGFnTmFtZU5TKAorICAgICAgICAgICAgICAgICJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsICJlbGVtIik7CisgICAgICAgIGVsZW1lbnRUZXN0ID0gKEVsZW1lbnQpIGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIGhhc0F0dHJpYnV0ZXMgPSBlbGVtZW50VGVzdC5oYXNBdHRyaWJ1dGVzKCk7CisgICAgICAgIGFzc2VydFRydWUoIm5vZGVoYXNhdHRyaWJ1dGVzMDQiLCBoYXNBdHRyaWJ1dGVzKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Ob2RlSXNTdXBwb3J0ZWQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Ob2RlSXNTdXBwb3J0ZWQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OTg3ZmIzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL05vZGVJc1N1cHBvcnRlZC5qYXZhCkBAIC0wLDAgKzEsMTgwIEBACisvKgorIFRoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKKyBhbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorIFRoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworIENvcHlyaWdodCAoYykgMjAwMS0yMDAzIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbAorIFJpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorIFBVUlBPU0UuCisKKyBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisgKi8KKworcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7CitpbXBvcnQgb3JnLnczYy5kb20uRW50aXR5UmVmZXJlbmNlOworaW1wb3J0IG9yZy53M2MuZG9tLlByb2Nlc3NpbmdJbnN0cnVjdGlvbjsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBUaGUgbWV0aG9kICJpc1N1cHBvcnRlZChmZWF0dXJlLHZlcnNpb24pIiBUZXN0cyB3aGV0aGVyIHRoZSBET00KKyAqIGltcGxlbWVudGF0aW9uIGltcGxlbWVudHMgYSBzcGVjaWZpYyBmZWF0dXJlIGFuZCB0aGF0IGZlYXR1cmUgaXMgc3VwcG9ydGVkIGJ5CisgKiB0aGlzIG5vZGUuCisgKgorICogQ2FsbCB0aGUgaXNTdXBwb3J0ZWQgbWV0aG9kIG9uIHRoZSBkb2N1bWVudCBlbGVtZW50IG5vZGUgd2l0aCBhIGNvbWJpbmF0aW9uCisgKiBvZiBmZWF0dXJlcyB2ZXJzaW9ucyBhbmQgdmVyc2lvbnMgYXMgYmVsb3cuIFZhbGlkIGZlYXR1cmUgbmFtZXMgYXJlIGNhc2UKKyAqIGluc2Vuc2l0aXZlIGFuZCB2ZXJzaW9ucyAiMi4wIiwgIjEuMCIgYW5kIGlmIHRoZSB2ZXJzaW9uIGlzIG5vdCBzcGVjaWZpZWQsCisgKiBzdXBwb3J0aW5nIGFueSB2ZXJzaW9uIG9mIHRoZSBmZWF0dXJlIHNob3VsZCByZXR1cm4gdHJ1ZS4gQ2hlY2sgaWYgdGhlIHZhbHVlCisgKiByZXR1cm5lZCB2YWx1ZSB3YXMgdHJ1ZS4KKyAqCisgKiBAYXV0aG9yIElCTQorICogQGF1dGhvciBOZWlsIERlbGltYQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjTGV2ZWwtMi1Db3JlLU5vZGUtc3VwcG9ydHMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNMZXZlbC0yLUNvcmUtTm9kZS1zdXBwb3J0czwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE5vZGVJc1N1cHBvcnRlZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJc1N1cHBvcnRlZDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ7CisgICAgICAgIFN0cmluZyB2ZXJzaW9uID0gIiI7CisgICAgICAgIFN0cmluZyB2ZXJzaW9uMSA9ICIxLjAiOworICAgICAgICBTdHJpbmcgdmVyc2lvbjIgPSAiMi4wIjsKKyAgICAgICAgU3RyaW5nIGZlYXR1cmVDb3JlOworICAgICAgICBTdHJpbmcgZmVhdHVyZVhNTDsKKyAgICAgICAgYm9vbGVhbiBzdWNjZXNzOworICAgICAgICBMaXN0PFN0cmluZz4gZmVhdHVyZXNYTUwgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgZmVhdHVyZXNYTUwuYWRkKCJYTUwiKTsKKyAgICAgICAgZmVhdHVyZXNYTUwuYWRkKCJ4bUwiKTsKKworICAgICAgICBMaXN0PFN0cmluZz4gZmVhdHVyZXNDb3JlID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGZlYXR1cmVzQ29yZS5hZGQoIkNvcmUiKTsKKyAgICAgICAgZmVhdHVyZXNDb3JlLmFkZCgiQ09SRSIpOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50ID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgICBmb3IgKGludCBpbmRleE4xMDA2MyA9IDA7IGluZGV4TjEwMDYzIDwgZmVhdHVyZXNYTUwuc2l6ZSgpOyBpbmRleE4xMDA2MysrKSB7CisgICAgICAgICAgICBmZWF0dXJlWE1MID0gKFN0cmluZykgZmVhdHVyZXNYTUwuZ2V0KGluZGV4TjEwMDYzKTsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSBlbGVtZW50LmlzU3VwcG9ydGVkKGZlYXR1cmVYTUwsIHZlcnNpb24pOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgibm9kZWlzc3VwcG9ydGVkMDFfWE1MMSIsIHN1Y2Nlc3MpOworICAgICAgICAgICAgc3VjY2VzcyA9IGVsZW1lbnQuaXNTdXBwb3J0ZWQoZmVhdHVyZVhNTCwgdmVyc2lvbjEpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgibm9kZWlzc3VwcG9ydGVkMDFfWE1MMiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGluZGV4TjEwMDdDID0gMDsgaW5kZXhOMTAwN0MgPCBmZWF0dXJlc0NvcmUuc2l6ZSgpOyBpbmRleE4xMDA3QysrKSB7CisgICAgICAgICAgICBmZWF0dXJlQ29yZSA9IChTdHJpbmcpIGZlYXR1cmVzQ29yZS5nZXQoaW5kZXhOMTAwN0MpOworICAgICAgICAgICAgc3VjY2VzcyA9IGVsZW1lbnQuaXNTdXBwb3J0ZWQoZmVhdHVyZUNvcmUsIHZlcnNpb24pOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgibm9kZWlzc3VwcG9ydGVkMDFfQ29yZTEiLCBzdWNjZXNzKTsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSBlbGVtZW50LmlzU3VwcG9ydGVkKGZlYXR1cmVDb3JlLCB2ZXJzaW9uMSk7CisgICAgICAgICAgICBzdWNjZXNzID0gZWxlbWVudC5pc1N1cHBvcnRlZChmZWF0dXJlQ29yZSwgdmVyc2lvbjIpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgibm9kZWlzc3VwcG9ydGVkMDFfQ29yZTMiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNTdXBwb3J0ZWQyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgQXR0ciBhdHRyaWJ1dGU7CisgICAgICAgIFN0cmluZyB2ZXJzaW9uID0gIiI7CisgICAgICAgIFN0cmluZyB2ZXJzaW9uMSA9ICIxLjAiOworICAgICAgICBTdHJpbmcgdmVyc2lvbjIgPSAiMi4wIjsKKyAgICAgICAgU3RyaW5nIGZlYXR1cmVDb3JlOworICAgICAgICBTdHJpbmcgZmVhdHVyZVhNTDsKKyAgICAgICAgYm9vbGVhbiBzdWNjZXNzOworICAgICAgICBMaXN0PFN0cmluZz4gZmVhdHVyZXNYTUwgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgZmVhdHVyZXNYTUwuYWRkKCJYTUwiKTsKKyAgICAgICAgZmVhdHVyZXNYTUwuYWRkKCJ4bUwiKTsKKworICAgICAgICBMaXN0PFN0cmluZz4gZmVhdHVyZXNDb3JlID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGZlYXR1cmVzQ29yZS5hZGQoIkNvcmUiKTsKKyAgICAgICAgZmVhdHVyZXNDb3JlLmFkZCgiQ09SRSIpOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBhdHRyaWJ1dGUgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJUZXN0QXR0ciIpOworICAgICAgICBmb3IgKGludCBpbmRleE4xMDA2NCA9IDA7IGluZGV4TjEwMDY0IDwgZmVhdHVyZXNYTUwuc2l6ZSgpOyBpbmRleE4xMDA2NCsrKSB7CisgICAgICAgICAgICBmZWF0dXJlWE1MID0gKFN0cmluZykgZmVhdHVyZXNYTUwuZ2V0KGluZGV4TjEwMDY0KTsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSBhdHRyaWJ1dGUuaXNTdXBwb3J0ZWQoZmVhdHVyZVhNTCwgdmVyc2lvbik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJub2RlaXNzdXBwb3J0ZWQwMl9YTUwxIiwgc3VjY2Vzcyk7CisgICAgICAgICAgICBzdWNjZXNzID0gYXR0cmlidXRlLmlzU3VwcG9ydGVkKGZlYXR1cmVYTUwsIHZlcnNpb24xKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIm5vZGVpc3N1cHBvcnRlZDAyX1hNTDIiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpbmRleE4xMDA3RCA9IDA7IGluZGV4TjEwMDdEIDwgZmVhdHVyZXNDb3JlLnNpemUoKTsgaW5kZXhOMTAwN0QrKykgeworICAgICAgICAgICAgZmVhdHVyZUNvcmUgPSAoU3RyaW5nKSBmZWF0dXJlc0NvcmUuZ2V0KGluZGV4TjEwMDdEKTsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSBhdHRyaWJ1dGUuaXNTdXBwb3J0ZWQoZmVhdHVyZUNvcmUsIHZlcnNpb24pOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgibm9kZWlzc3VwcG9ydGVkMDJfQ29yZTEiLCBzdWNjZXNzKTsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSBhdHRyaWJ1dGUuaXNTdXBwb3J0ZWQoZmVhdHVyZUNvcmUsIHZlcnNpb24xKTsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSBhdHRyaWJ1dGUuaXNTdXBwb3J0ZWQoZmVhdHVyZUNvcmUsIHZlcnNpb24yKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIm5vZGVpc3N1cHBvcnRlZDAyX0NvcmUzIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdElzU3VwcG9ydGVkMygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgICBib29sZWFuIHN1Y2Nlc3M7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBkb2NUeXBlID0gZG9jLmdldERvY3R5cGUoKTsKKyAgICAgICAgc3VjY2VzcyA9IGRvY1R5cGUuaXNTdXBwb3J0ZWQoIiIsICIiKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIm5vZGVpc3N1cHBvcnRlZDAzIiwgc3VjY2Vzcyk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RJc1N1cHBvcnRlZDQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBFbnRpdHlSZWZlcmVuY2UgZW50UmVmOworICAgICAgICBib29sZWFuIHN1Y2Nlc3M7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbnRSZWYgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQxIik7CisgICAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZW50UmVmKTsKKyAgICAgICAgc3VjY2VzcyA9IGVudFJlZi5pc1N1cHBvcnRlZCgiWE1MIENPUkUiLCAiIik7CisgICAgICAgIGFzc2VydEZhbHNlKCJub2RlaXNzdXBwb3J0ZWQwNCIsIHN1Y2Nlc3MpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNTdXBwb3J0ZWQ1KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uIHBpOworICAgICAgICBib29sZWFuIHN1Y2Nlc3M7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBwaSA9IGRvYy5jcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oIlBJVGFyZ2V0IiwgIlBJRGF0YSIpOworICAgICAgICBzdWNjZXNzID0gcGkuaXNTdXBwb3J0ZWQoIi0iLCAiKyIpOworICAgICAgICBhc3NlcnRGYWxzZSgibm9kZWlzc3VwcG9ydGVkMDUiLCBzdWNjZXNzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTm9kZU5vcm1hbGl6ZS5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL05vZGVOb3JtYWxpemUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZmU5Yzg3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL05vZGVOb3JtYWxpemUuamF2YQpAQCAtMCwwICsxLDE5NyBAQAorLyoKKyBUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCisgYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KKyBUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKyBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwKKyBSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyBQVVJQT1NFLgorCisgU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworICovCisKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRUeXBlOworaW1wb3J0IG9yZy53M2MuZG9tLlRleHQ7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247CitpbXBvcnQgb3JnLnczYy5kb20uRW50aXR5UmVmZXJlbmNlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworaW1wb3J0IG9yZy53M2MuZG9tLkNEQVRBU2VjdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb247CitpbXBvcnQgb3JnLnczYy5kb20uQ29tbWVudDsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBUaGUgbWV0aG9kICJub3JtYWxpemUiIHB1dHMgYWxsIFRleHQgbm9kZXMgaW4gdGhlIGZ1bGwgZGVwdGggb2YgdGhlIHN1Yi10cmVlCisgKiB1bmRlcm5lYXRoIHRoaXMgTm9kZSwgaW5jbHVkaW5nIGF0dHJpYnV0ZSBub2RlcywgaW50byBhICJub3JtYWwiIGZvcm0gd2hlcmUKKyAqIG9ubHkgc3RydWN0dXJlIChlLmcuLCBlbGVtZW50cywgY29tbWVudHMsIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zLCBDREFUQQorICogc2VjdGlvbnMsIGFuZCBlbnRpdHkgcmVmZXJlbmNlcykgc2VwYXJhdGVzIFRleHQgbm9kZXMsIGkuZS4sIHRoZXJlIGFyZQorICogbmVpdGhlciBhZGphY2VudCBUZXh0IG5vZGVzIG5vciBlbXB0eSBUZXh0IG5vZGVzLgorICoKKyAqIENyZWF0ZSBhIGRvbSB0cmVlIGNvbnNpc3Rpbmcgb2YgZWxlbWVudHMsIGNvbW1lbnRzLCBwcm9jZXNzaW5nIGluc3RydWN0aW9ucywKKyAqIENEQVRBIHNlY3Rpb25zLCBhbmQgZW50aXR5IHJlZmVyZW5jZXMgbm9kZXMgc2VwZXJhdGVkIGJ5IHRleHQgbm9kZXMuIENoZWNrCisgKiB0aGUgbGVuZ3RoIG9mIHRoZSBub2RlIGxpc3Qgb2YgZWFjaCBiZWZvcmUgYW5kIGFmdGVyIG5vcm1hbGl6ZSBoYXMgYmVlbgorICogY2FsbGVkLgorICoKKyAqIEBhdXRob3IgSUJNCisgKiBAYXV0aG9yIE5laWwgRGVsaW1hCisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1ub3JtYWxpemUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1ub3JtYWxpemU8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBOb2RlTm9ybWFsaXplIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24xKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdE5vcm1hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIERvY3VtZW50IG5ld0RvYzsKKyAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKKworICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZU51bGwgPSBudWxsOworCisgICAgICAgIEVsZW1lbnQgZG9jdW1lbnRFbGVtZW50OworICAgICAgICBFbGVtZW50IGVsZW1lbnQxOworICAgICAgICBFbGVtZW50IGVsZW1lbnQyOworICAgICAgICBFbGVtZW50IGVsZW1lbnQzOworICAgICAgICBFbGVtZW50IGVsZW1lbnQ0OworICAgICAgICBFbGVtZW50IGVsZW1lbnQ1OworICAgICAgICBFbGVtZW50IGVsZW1lbnQ2OworICAgICAgICBFbGVtZW50IGVsZW1lbnQ3OworICAgICAgICBUZXh0IHRleHQxOworICAgICAgICBUZXh0IHRleHQyOworICAgICAgICBUZXh0IHRleHQzOworICAgICAgICBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gcGk7CisgICAgICAgIENEQVRBU2VjdGlvbiBjRGF0YTsKKyAgICAgICAgQ29tbWVudCBjb21tZW50OworICAgICAgICBFbnRpdHlSZWZlcmVuY2UgZW50UmVmOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZG9tSW1wbCA9IGRvYy5nZXRJbXBsZW1lbnRhdGlvbigpOworICAgICAgICBuZXdEb2MgPSBkb21JbXBsLmNyZWF0ZURvY3VtZW50KCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsCisgICAgICAgICAgICAgICAgImRvbTpyb290IiwgZG9jVHlwZU51bGwpOworICAgICAgICBlbGVtZW50MSA9IG5ld0RvYy5jcmVhdGVFbGVtZW50KCJlbGVtZW50MSIpOworICAgICAgICBlbGVtZW50MiA9IG5ld0RvYy5jcmVhdGVFbGVtZW50KCJlbGVtZW50MiIpOworICAgICAgICBlbGVtZW50MyA9IG5ld0RvYy5jcmVhdGVFbGVtZW50KCJlbGVtZW50MyIpOworICAgICAgICBlbGVtZW50NCA9IG5ld0RvYy5jcmVhdGVFbGVtZW50KCJlbGVtZW50NCIpOworICAgICAgICBlbGVtZW50NSA9IG5ld0RvYy5jcmVhdGVFbGVtZW50KCJlbGVtZW50NSIpOworICAgICAgICBlbGVtZW50NiA9IG5ld0RvYy5jcmVhdGVFbGVtZW50KCJlbGVtZW50NiIpOworICAgICAgICBlbGVtZW50NyA9IG5ld0RvYy5jcmVhdGVFbGVtZW50KCJlbGVtZW50NyIpOworICAgICAgICB0ZXh0MSA9IG5ld0RvYy5jcmVhdGVUZXh0Tm9kZSgidGV4dDEiKTsKKyAgICAgICAgdGV4dDIgPSBuZXdEb2MuY3JlYXRlVGV4dE5vZGUoInRleHQyIik7CisgICAgICAgIHRleHQzID0gbmV3RG9jLmNyZWF0ZVRleHROb2RlKCJ0ZXh0MyIpOworICAgICAgICBjRGF0YSA9IG5ld0RvYy5jcmVhdGVDREFUQVNlY3Rpb24oIkNkYXRhIik7CisgICAgICAgIGNvbW1lbnQgPSBuZXdEb2MuY3JlYXRlQ29tbWVudCgiY29tbWVudCIpOworICAgICAgICBwaSA9IG5ld0RvYy5jcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oIlBJVGFyZ2V0IiwgIlBJRGF0YSIpOworICAgICAgICBlbnRSZWYgPSBuZXdEb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJFbnRSZWYiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBlbnRSZWYpOworICAgICAgICBkb2N1bWVudEVsZW1lbnQgPSBuZXdEb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICAgIGRvY3VtZW50RWxlbWVudC5hcHBlbmRDaGlsZChlbGVtZW50MSk7CisgICAgICAgIGVsZW1lbnQyLmFwcGVuZENoaWxkKHRleHQxKTsKKyAgICAgICAgZWxlbWVudDIuYXBwZW5kQ2hpbGQodGV4dDIpOworICAgICAgICBlbGVtZW50Mi5hcHBlbmRDaGlsZCh0ZXh0Myk7CisgICAgICAgIGVsZW1lbnQxLmFwcGVuZENoaWxkKGVsZW1lbnQyKTsKKyAgICAgICAgdGV4dDEgPSAoVGV4dCkgdGV4dDEuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgICAgdGV4dDIgPSAoVGV4dCkgdGV4dDIuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgICAgZWxlbWVudDMuYXBwZW5kQ2hpbGQoZW50UmVmKTsKKyAgICAgICAgZWxlbWVudDMuYXBwZW5kQ2hpbGQodGV4dDEpOworICAgICAgICBlbGVtZW50My5hcHBlbmRDaGlsZCh0ZXh0Mik7CisgICAgICAgIGVsZW1lbnQxLmFwcGVuZENoaWxkKGVsZW1lbnQzKTsKKyAgICAgICAgdGV4dDEgPSAoVGV4dCkgdGV4dDEuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgICAgdGV4dDIgPSAoVGV4dCkgdGV4dDIuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgICAgZWxlbWVudDQuYXBwZW5kQ2hpbGQoY0RhdGEpOworICAgICAgICBlbGVtZW50NC5hcHBlbmRDaGlsZCh0ZXh0MSk7CisgICAgICAgIGVsZW1lbnQ0LmFwcGVuZENoaWxkKHRleHQyKTsKKyAgICAgICAgZWxlbWVudDEuYXBwZW5kQ2hpbGQoZWxlbWVudDQpOworICAgICAgICB0ZXh0MiA9IChUZXh0KSB0ZXh0Mi5jbG9uZU5vZGUoZmFsc2UpOworICAgICAgICB0ZXh0MyA9IChUZXh0KSB0ZXh0My5jbG9uZU5vZGUoZmFsc2UpOworICAgICAgICBlbGVtZW50NS5hcHBlbmRDaGlsZChjb21tZW50KTsKKyAgICAgICAgZWxlbWVudDUuYXBwZW5kQ2hpbGQodGV4dDIpOworICAgICAgICBlbGVtZW50NS5hcHBlbmRDaGlsZCh0ZXh0Myk7CisgICAgICAgIGVsZW1lbnQxLmFwcGVuZENoaWxkKGVsZW1lbnQ1KTsKKyAgICAgICAgdGV4dDIgPSAoVGV4dCkgdGV4dDIuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgICAgdGV4dDMgPSAoVGV4dCkgdGV4dDMuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgICAgZWxlbWVudDYuYXBwZW5kQ2hpbGQocGkpOworICAgICAgICBlbGVtZW50Ni5hcHBlbmRDaGlsZCh0ZXh0Mik7CisgICAgICAgIGVsZW1lbnQ2LmFwcGVuZENoaWxkKHRleHQzKTsKKyAgICAgICAgZWxlbWVudDEuYXBwZW5kQ2hpbGQoZWxlbWVudDYpOworICAgICAgICBlbnRSZWYgPSAoRW50aXR5UmVmZXJlbmNlKSBlbnRSZWYuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgICAgdGV4dDEgPSAoVGV4dCkgdGV4dDEuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgICAgdGV4dDIgPSAoVGV4dCkgdGV4dDIuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgICAgdGV4dDMgPSAoVGV4dCkgdGV4dDMuY2xvbmVOb2RlKGZhbHNlKTsKKyAgICAgICAgZWxlbWVudDcuYXBwZW5kQ2hpbGQoZW50UmVmKTsKKyAgICAgICAgZWxlbWVudDcuYXBwZW5kQ2hpbGQodGV4dDEpOworICAgICAgICBlbGVtZW50Ny5hcHBlbmRDaGlsZCh0ZXh0Mik7CisgICAgICAgIGVsZW1lbnQ3LmFwcGVuZENoaWxkKHRleHQzKTsKKyAgICAgICAgZWxlbWVudDEuYXBwZW5kQ2hpbGQoZWxlbWVudDcpOworICAgICAgICBlbGVtZW50TGlzdCA9IGVsZW1lbnQxLmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTm9ybWFsaXplMDFfMUJlZiIsIDYsIGVsZW1lbnRMaXN0LmdldExlbmd0aCgpKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBlbGVtZW50Mi5nZXRDaGlsZE5vZGVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibm9kZU5vcm1hbGl6ZTAxXzJCZWYiLCAzLCBlbGVtZW50TGlzdC5nZXRMZW5ndGgoKSk7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZWxlbWVudDMuZ2V0Q2hpbGROb2RlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOb3JtYWxpemUwMV8zQmVmIiwgMywgZWxlbWVudExpc3QuZ2V0TGVuZ3RoKCkpOworICAgICAgICBlbGVtZW50TGlzdCA9IGVsZW1lbnQ0LmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTm9ybWFsaXplMDFfNEJlZiIsIDMsIGVsZW1lbnRMaXN0LmdldExlbmd0aCgpKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBlbGVtZW50NS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibm9kZU5vcm1hbGl6ZTAxXzVCZWYiLCAzLCBlbGVtZW50TGlzdC5nZXRMZW5ndGgoKSk7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZWxlbWVudDYuZ2V0Q2hpbGROb2RlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOb3JtYWxpemUwMV82QmVmIiwgMywgZWxlbWVudExpc3QuZ2V0TGVuZ3RoKCkpOworICAgICAgICBlbGVtZW50TGlzdCA9IGVsZW1lbnQ3LmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTm9ybWFsaXplMDFfN0JlZiIsIDQsIGVsZW1lbnRMaXN0LmdldExlbmd0aCgpKTsKKyAgICAgICAgbmV3RG9jLm5vcm1hbGl6ZSgpOworICAgICAgICBlbGVtZW50TGlzdCA9IGVsZW1lbnQxLmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTm9ybWFsaXplMDFfMUFmdCIsIDYsIGVsZW1lbnRMaXN0LmdldExlbmd0aCgpKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBlbGVtZW50Mi5nZXRDaGlsZE5vZGVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibm9kZU5vcm1hbGl6ZTAxXzJBZnQiLCAxLCBlbGVtZW50TGlzdC5nZXRMZW5ndGgoKSk7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZWxlbWVudDMuZ2V0Q2hpbGROb2RlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOb3JtYWxpemUwMV8zQWZ0IiwgMiwgZWxlbWVudExpc3QuZ2V0TGVuZ3RoKCkpOworICAgICAgICBlbGVtZW50TGlzdCA9IGVsZW1lbnQ0LmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTm9ybWFsaXplMDFfNEFmdCIsIDIsIGVsZW1lbnRMaXN0LmdldExlbmd0aCgpKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBlbGVtZW50NS5nZXRDaGlsZE5vZGVzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibm9kZU5vcm1hbGl6ZTAxXzVBZnQiLCAyLCBlbGVtZW50TGlzdC5nZXRMZW5ndGgoKSk7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZWxlbWVudDYuZ2V0Q2hpbGROb2RlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOb3JtYWxpemUwMV82QWZ0IiwgMiwgZWxlbWVudExpc3QuZ2V0TGVuZ3RoKCkpOworICAgICAgICBlbGVtZW50TGlzdCA9IGVsZW1lbnQ3LmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJub2RlTm9ybWFsaXplMDFfN0FmdCIsIDIsIGVsZW1lbnRMaXN0LmdldExlbmd0aCgpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Ob2RlU2V0UHJlZml4LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTm9kZVNldFByZWZpeC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMxMTQ3NmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTm9kZVNldFByZWZpeC5qYXZhCkBAIC0wLDAgKzEsMjY2IEBACisvKgorIFRoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKKyBhbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorIFRoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworIENvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwKKyBSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyBQVVJQT1NFLgorCisgU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworICovCisKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworaW1wb3J0IG9yZy53M2MuZG9tLkF0dHI7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogVGhlIG1ldGhvZCBzZXRQcmVmaXggc2V0cyB0aGUgbmFtZXNwYWNlIHByZWZpeCBvZiB0aGlzIG5vZGUuIE5vdGUgdGhhdAorICogc2V0dGluZyB0aGlzIGF0dHJpYnV0ZSwgd2hlbiBwZXJtaXR0ZWQsIGNoYW5nZXMgdGhlIG5vZGVOYW1lIGF0dHJpYnV0ZSwgd2hpY2gKKyAqIGhvbGRzIHRoZSBxdWFsaWZpZWQgbmFtZSwgYXMgd2VsbCBhcyB0aGUgdGFnTmFtZSBhbmQgbmFtZSBhdHRyaWJ1dGVzIG9mIHRoZQorICogRWxlbWVudCBhbmQgQXR0ciBpbnRlcmZhY2VzLCB3aGVuIGFwcGxpY2FibGUuCisgKgorICogQ3JlYXRlIGEgbmV3IGVsZW1lbnQgbm9kZSB3aXRoIGEgbmFtZXNwYWNlIHByZWZpeC4gQWRkIGl0IHRvIGEgbmV3CisgKiBEb2N1bWVudEZyYWdtZW50IE5vZGUgd2l0aG91dCBhIHByZWZpeC4gQ2FsbCBzZXRQcmVmaXggb24gdGhlIGVsZW1lbiBub2RlLgorICogQ2hlY2sgaWYgdGhlIHByZWZpeCB3YXMgc2V0IGNvcnJlY3RseSBvbiB0aGUgZWxlbWVudC4KKyAqCisgKiBAYXV0aG9yIElCTQorICogQGF1dGhvciBOZWlsIERlbGltYQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4Ij5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtTm9kZU5TUHJlZml4PC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTm9kZVNldFByZWZpeCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRQcmVmaXgxKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRG9jdW1lbnRGcmFnbWVudCBkb2NGcmFnbWVudDsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBTdHJpbmcgZWxlbWVudFRhZ05hbWU7CisgICAgICAgIFN0cmluZyBlbGVtZW50Tm9kZU5hbWU7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGJ1aWxkZXIpOworICAgICAgICBkb2NGcmFnbWVudCA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CisgICAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdCIsCisgICAgICAgICAgICAgICAgImVtcDphZGRyZXNzIik7CisgICAgICAgIGRvY0ZyYWdtZW50LmFwcGVuZENoaWxkKGVsZW1lbnQpOworICAgICAgICBlbGVtZW50LnNldFByZWZpeCgiZG1zdGMiKTsKKyAgICAgICAgZWxlbWVudFRhZ05hbWUgPSBlbGVtZW50LmdldFRhZ05hbWUoKTsKKyAgICAgICAgZWxlbWVudE5vZGVOYW1lID0gZWxlbWVudC5nZXROb2RlTmFtZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVzZXRwcmVmaXgwMV90YWduYW1lIiwgImRtc3RjOmFkZHJlc3MiLCBlbGVtZW50VGFnTmFtZSk7CisgICAgICAgIGFzc2VydEVxdWFscygibm9kZXNldHByZWZpeDAxX25vZGVOYW1lIiwgImRtc3RjOmFkZHJlc3MiLAorICAgICAgICAgICAgICAgIGVsZW1lbnROb2RlTmFtZSk7CisgICAgfQorCisvLyBUT0RPIEZhaWxzIG9uIEpESy4gV2h5PworLy8gICAgcHVibGljIHZvaWQgdGVzdFNldFByZWZpeDIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKy8vICAgICAgICBEb2N1bWVudCBkb2M7CisvLyAgICAgICAgRWxlbWVudCBlbGVtZW50OworLy8gICAgICAgIEF0dHIgYXR0cmlidXRlOworLy8gICAgICAgIEF0dHIgbmV3QXR0cmlidXRlOworLy8KKy8vICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKy8vICAgICAgICBTdHJpbmcgYXR0ck5hbWU7CisvLyAgICAgICAgU3RyaW5nIG5ld0F0dHJOYW1lOworLy8gICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworLy8gICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhZGRyZXNzIik7CisvLyAgICAgICAgZWxlbWVudCA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDEpOworLy8gICAgICAgIG5ld0F0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QiLAorLy8gICAgICAgICAgICAgICAgInRlc3Q6YWRkcmVzcyIpOworLy8gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZU5TKG5ld0F0dHJpYnV0ZSk7CisvLyAgICAgICAgbmV3QXR0cmlidXRlLnNldFByZWZpeCgiZG9tIik7CisvLyAgICAgICAgYXR0cmlidXRlID0gZWxlbWVudAorLy8gICAgICAgICAgICAgICAgLmdldEF0dHJpYnV0ZU5vZGVOUygiaHR0cDovL3d3dy51c2EuY29tIiwgImRvbWVzdGljIik7CisvLyAgICAgICAgYXR0ck5hbWUgPSBhdHRyaWJ1dGUuZ2V0Tm9kZU5hbWUoKTsKKy8vICAgICAgICBuZXdBdHRyTmFtZSA9IG5ld0F0dHJpYnV0ZS5nZXROb2RlTmFtZSgpOworLy8gICAgICAgIGFzc2VydEVxdWFscygibm9kZXNldHByZWZpeDAyX2F0dHJOYW1lIiwgImRtc3RjOmRvbWVzdGljIiwgYXR0ck5hbWUpOworLy8gICAgICAgIGFzc2VydEVxdWFscygibm9kZXNldHByZWZpeDAyX25ld0F0dHJOYW1lIiwgImRvbTphZGRyZXNzIiwgbmV3QXR0ck5hbWUpOworLy8gICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRQcmVmaXgzKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCJhZGRyZXNzIik7CisKKyAgICAgICAgeworICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0UHJlZml4KCJ0ZXN0Iik7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorCisvLyBSZWxpZXMgb24gdmFsaWRhdGlvbiwgd2hpY2ggd2UgZG9uJ3Qgc3VwcG9ydC4KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRQcmVmaXg0KCkgdGhyb3dzIFRocm93YWJsZSB7CisvLyAgICAgICAgRG9jdW1lbnQgZG9jOworLy8gICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKy8vICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKy8vICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKy8vICAgICAgICBTdHJpbmcgbnVsbE5TID0gbnVsbDsKKy8vCisvLyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisvLyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDplbXBsb3llZSIpOworLy8gICAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKy8vICAgICAgICBhc3NlcnROb3ROdWxsKCJlbXBFbXBsb3llZU5vdE51bGwiLCBlbGVtZW50KTsKKy8vICAgICAgICBhdHRyaWJ1dGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5vZGVOUyhudWxsTlMsICJkZWZhdWx0QXR0ciIpOworLy8KKy8vICAgICAgICB7CisvLyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworLy8gICAgICAgICAgICB0cnkgeworLy8gICAgICAgICAgICAgICAgYXR0cmlidXRlLnNldFByZWZpeCgidGVzdCIpOworLy8gICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKy8vICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisvLyAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgibm9kZXNldHByZWZpeDA0Iiwgc3VjY2Vzcyk7CisvLyAgICAgICAgfQorLy8gICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRQcmVmaXg1KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBTdHJpbmcgcHJlZml4VmFsdWU7CisgICAgICAgIExpc3Q8U3RyaW5nPiBwcmVmaXhWYWx1ZXMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgcHJlZml4VmFsdWVzLmFkZCgiXzoiKTsKKyAgICAgICAgcHJlZml4VmFsdWVzLmFkZCgiOjAiKTsKKyAgICAgICAgcHJlZml4VmFsdWVzLmFkZCgiOiIpOworICAgICAgICBwcmVmaXhWYWx1ZXMuYWRkKCJfOjoiKTsKKyAgICAgICAgcHJlZml4VmFsdWVzLmFkZCgiYTowOmMiKTsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L0wyIiwKKyAgICAgICAgICAgICAgICAiZG9tOmVsZW0iKTsKKyAgICAgICAgZm9yIChpbnQgaW5kZXhOMTAwNTAgPSAwOyBpbmRleE4xMDA1MCA8IHByZWZpeFZhbHVlcy5zaXplKCk7IGluZGV4TjEwMDUwKyspIHsKKyAgICAgICAgICAgIHByZWZpeFZhbHVlID0gKFN0cmluZykgcHJlZml4VmFsdWVzLmdldChpbmRleE4xMDA1MCk7CisKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnNldFByZWZpeChwcmVmaXhWYWx1ZSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X05BTUVTUEFDRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0UHJlZml4NigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy9ET00vVGVzdC9MMiIsCisgICAgICAgICAgICAgICAgImRvbTplbGVtIik7CisKKyAgICAgICAgeworICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0UHJlZml4KCJ4bWwiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFNldFByZWZpeDcoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBBdHRyIGF0dHJpYnV0ZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGF0dHJpYnV0ZSA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvRE9NL1Rlc3QvTDIiLAorICAgICAgICAgICAgICAgICJhYmM6ZWxlbSIpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhdHRyaWJ1dGUuc2V0UHJlZml4KCJ4bWxucyIpOworICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X05BTUVTUEFDRV9FUlIiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0UHJlZml4OCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEVsZW1lbnQgZWxlbWVudDsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIEF0dHIgYXR0cmlidXRlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICAgIGVsZW1lbnQgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgICAgYXR0cmlidXRlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlKCJ4bWxucyIpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhdHRyaWJ1dGUuc2V0UHJlZml4KCJ4bWwiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgX3Rlc3RTZXRQcmVmaXg5KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgU3RyaW5nIHZhbHVlID0gIiMkJSYnKClAIjsKKyAgICAgICAgRWxlbWVudCBlbGVtZW50OworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnL0RPTS9UZXN0L0wyIiwKKyAgICAgICAgICAgICAgICAiZG9tOmVsZW0iKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRQcmVmaXgodmFsdWUpOworICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5JTlZBTElEX0NIQVJBQ1RFUl9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSU5WQUxJRF9DSEFSQUNURVJfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTm9ybWFsaXplLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vTm9ybWFsaXplLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDNkNjAxNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Ob3JtYWxpemUuamF2YQpAQCAtMCwwICsxLDk0IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworaW1wb3J0IG9yZy53M2MuZG9tLkNoYXJhY3RlckRhdGE7CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogICAgIFRoZSAibm9ybWFsaXplKCkiIG1ldGhvZCBwdXRzIGFsbCB0aGUgbm9kZXMgaW4gdGhlIGZ1bGwKKyAqICAgICBkZXB0aCBvZiB0aGUgc3ViLXRyZWUgdW5kZXJuZWF0aCB0aGlzIGVsZW1lbnQgaW50byBhCisgKiAgICAgIm5vcm1hbCIgZm9ybS4KKyAqCisgKiAgICAgUmV0cmlldmUgdGhlIHRoaXJkIGVtcGxveWVlIGFuZCBhY2Nlc3MgaXRzIHNlY29uZCBjaGlsZC4KKyAqICAgICBUaGlzIGNoaWxkIGNvbnRhaW5zIGEgYmxvY2sgb2YgdGV4dCB0aGF0IGlzIHNwcmVhZAorICogICAgIGFjcm9zcyBtdWx0aXBsZSBsaW5lcy4gICBUaGUgY29udGVudCBvZiB0aGUgIm5hbWUiIGNoaWxkCisgKiAgICAgc2hvdWxkIGJlIHBhcnNlZCBhbmQgdHJlYXRlZCBhcyBhIHNpbmdsZSBUZXh0IG5vZGUuCisgKiAgICAgVGhpcyBhcHBlYXJzIHRvIGJlIGEgZHVwbGljYXRlIG9mIGVsZW1lbnRub3JtYWxpemUueG1sIGluIERPTSBMMSBUZXN0IFN1aXRlCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtbm9ybWFsaXplIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtbm9ybWFsaXplPC9hPgorKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC03MkFCODM1OSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELTcyQUI4MzU5PC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBOb3JtYWxpemUgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorICAgLyoqCisgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgKiBAdGhyb3dzIFRocm93YWJsZSBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAqLworICAgcHVibGljIHZvaWQgdGVzdE5vcm1hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRWxlbWVudCByb290OworICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICBOb2RlIGZpcnN0Q2hpbGQ7CisgICAgICBOb2RlTGlzdCB0ZXh0TGlzdDsKKyAgICAgIENoYXJhY3RlckRhdGEgdGV4dE5vZGU7CisgICAgICBTdHJpbmcgZGF0YTsKKyAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmYiLCBidWlsZGVyKTsKKyAgICAgIHJvb3QgPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7CisgICAgICByb290Lm5vcm1hbGl6ZSgpOworICAgICAgZWxlbWVudExpc3QgPSByb290LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJuYW1lIik7CisgICAgICBmaXJzdENoaWxkID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKyAgICAgIHRleHRMaXN0ID0gZmlyc3RDaGlsZC5nZXRDaGlsZE5vZGVzKCk7CisgICAgICB0ZXh0Tm9kZSA9IChDaGFyYWN0ZXJEYXRhKSB0ZXh0TGlzdC5pdGVtKDApOworICAgICAgZGF0YSA9IHRleHROb2RlLmdldERhdGEoKTsKKyAgICAgIGFzc2VydEVxdWFscygiZGF0YSIsICJSb2dlclxuIEpvbmVzIiwgZGF0YSk7CisgICAgICB9CisKK30KKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL093bmVyRG9jdW1lbnQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Pd25lckRvY3VtZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWIxYThkZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Pd25lckRvY3VtZW50LmphdmEKQEAgLTAsMCArMSw3NiBAQAorCisvKgorVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KK1RoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKK1JlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwKK1JpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKK0ludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQoraG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgordGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorUFVSUE9TRS4KKworU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworKi8KKworcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiAgICAgVGhlICJnZXRPd25lckRvY3VtZW50KCkiIG1ldGhvZCByZXR1cm5zIG51bGwgaWYgdGhlIHRhcmdldAorICogICAgIG5vZGUgaXRzZWxmIGlzIGEgRG9jdW1lbnRUeXBlIHdoaWNoIGlzIG5vdCB1c2VkIHdpdGggYW55IGRvY3VtZW50IHlldC4KKyAqCisgKiAgICAgSW52b2tlIHRoZSAiZ2V0T3duZXJEb2N1bWVudCgpIiBtZXRob2Qgb24gdGhlIG1hc3RlcgorICogICAgIGRvY3VtZW50LiAgIFRoZSBEb2N1bWVudFR5cGUgcmV0dXJuZWQgc2hvdWxkIGJlIG51bGwuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjbm9kZS1vd25lckRvYyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI25vZGUtb3duZXJEb2M8L2E+CisqLworcHVibGljIGZpbmFsIGNsYXNzIE93bmVyRG9jdW1lbnQgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjEoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAvKioKKyAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAqIEB0aHJvd3MgVGhyb3dhYmxlIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICovCisgICBwdWJsaWMgdm9pZCB0ZXN0R2V0T3duZXJEb2N1bWVudCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIG93bmVyRG9jdW1lbnQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICBvd25lckRvY3VtZW50ID0gKERvY3VtZW50VHlwZSkgZG9jLmdldE93bmVyRG9jdW1lbnQoKTsKKyAgICAgIGFzc2VydE51bGwoInRocm93X051bGwiLCBvd25lckRvY3VtZW50KTsKKyAgICAgIH0KKworfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vT3duZXJFbGVtZW50LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vT3duZXJFbGVtZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDc3N2Y0MgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9Pd25lckVsZW1lbnQuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorLyoKKyBUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCisgYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KKyBUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKyBDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCisgUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgUFVSUE9TRS4KKworIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyAqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5BdHRyOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSAiZ2V0T3duZXJFbGVtZW50KCkiIHdpbGwgcmV0dXJuIHRoZSBFbGVtZW50IG5vZGUgdGhpcyBhdHRyaWJ1dGUgaXMKKyAqIGF0dGFjaGVkIHRvIG9yIG51bGwgaWYgdGhpcyBhdHRyaWJ1dGUgaXMgbm90IGluIHVzZS4gR2V0IHRoZSAiZG9tZXN0aWMiCisgKiBhdHRyaWJ1dGUgZnJvbSB0aGUgZmlyc3QgImFkZHJlc3MiIG5vZGUuIEFwcGx5IHRoZSAiZ2V0T3duZXJFbGVtZW50KCkiIG1ldGhvZAorICogdG8gZ2V0IHRoZSBFbGVtZW50IGFzc29jaWF0ZWQgd2l0aCB0aGUgYXR0cmlidXRlLiBUaGUgdmFsdWUgcmV0dXJuZWQgc2hvdWxkCisgKiBiZSAiYWRkcmVzcyIuCisgKgorICogQGF1dGhvciBOSVNUCisgKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUY2OEQwOTUiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1GNjhEMDk1PC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgT3duZXJFbGVtZW50IGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24xKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldE93bmVyRWxlbWVudDEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBhZGRyZXNzTGlzdDsKKyAgICAgICAgTm9kZSB0ZXN0Tm9kZTsKKyAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICAgIEF0dHIgZG9tZXN0aWNBdHRyOworICAgICAgICBFbGVtZW50IGVsZW1lbnROb2RlOworICAgICAgICBTdHJpbmcgbmFtZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZiIsIGJ1aWxkZXIpOworICAgICAgICBhZGRyZXNzTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgICB0ZXN0Tm9kZSA9IGFkZHJlc3NMaXN0Lml0ZW0oMCk7CisgICAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAgIGRvbWVzdGljQXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgiZG9tZXN0aWMiKTsKKyAgICAgICAgZWxlbWVudE5vZGUgPSBkb21lc3RpY0F0dHIuZ2V0T3duZXJFbGVtZW50KCk7CisgICAgICAgIG5hbWUgPSBlbGVtZW50Tm9kZS5nZXROb2RlTmFtZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRocm93X0VxdWFscyIsICJhZGRyZXNzIiwgbmFtZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRPd25lckVsZW1lbnQyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgQXR0ciBuZXdBdHRyOworICAgICAgICBFbGVtZW50IGVsZW1lbnROb2RlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisgICAgICAgIG5ld0F0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlKCJuZXdBdHRyaWJ1dGUiKTsKKyAgICAgICAgZWxlbWVudE5vZGUgPSBuZXdBdHRyLmdldE93bmVyRWxlbWVudCgpOworICAgICAgICBhc3NlcnROdWxsKCJ0aHJvd19OdWxsIiwgZWxlbWVudE5vZGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9QcmVmaXguamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9QcmVmaXguamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOGNmNmE0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL1ByZWZpeC5qYXZhCkBAIC0wLDAgKzEsMjcxIEBACisvKgorIFRoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKKyBhbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorIFRoZSBzb3VyY2UgZG9jdW1lbnQgY29udGFpbmVkIHRoZSBmb2xsb3dpbmcgbm90aWNlOgorCisKKworIENvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwKKyBSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyBQVVJQT1NFLgorCisgU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworICovCisKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogVGhlICJnZXRQcmVmaXgoKSIgbWV0aG9kIGZvciBhIE5vZGUgcmV0dXJucyB0aGUgbmFtZXNwYWNlIHByZWZpeCBvZiB0aGUgbm9kZSwKKyAqIGFuZCBmb3Igbm9kZXMgb2YgYW55IHR5cGUgb3RoZXIgdGhhbiBFTEVNRU5UX05PREUgYW5kIEFUVFJJQlVURV9OT0RFIGFuZAorICogbm9kZXMgY3JlYXRlZCB3aXRoIGEgRE9NIExldmVsIDEgbWV0aG9kLCB0aGlzIGlzIG51bGwuCisgKgorICogQ3JlYXRlIGFuIG5ldyBFbGVtZW50IHdpdGggdGhlIGNyZWF0ZUVsZW1lbnQoKSBtZXRob2QuIEludm9rZSB0aGUKKyAqICJnZXRQcmVmaXgoKSIgbWV0aG9kIG9uIHRoZSBuZXdseSBjcmVhdGVkIGVsZW1lbnQgbm9kZSB3aWxsIGNhdXNlICJudWxsIiB0bworICogYmUgcmV0dXJuZWQuCisgKgorICogQGF1dGhvciBOSVNUCisgKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeCI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELU5vZGVOU1ByZWZpeDwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFByZWZpeCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMigpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQcmVmaXgxKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZSBjcmVhdGVkTm9kZTsKKyAgICAgICAgU3RyaW5nIHByZWZpeDsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGNyZWF0ZWROb2RlID0gZG9jLmNyZWF0ZUVsZW1lbnQoInRlc3Q6ZW1wbG95ZWUiKTsKKyAgICAgICAgcHJlZml4ID0gY3JlYXRlZE5vZGUuZ2V0UHJlZml4KCk7CisgICAgICAgIGFzc2VydE51bGwoInRocm93X051bGwiLCBwcmVmaXgpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UHJlZml4MigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBOb2RlIHRlc3RFbXBsb3llZTsKKyAgICAgICAgTm9kZSB0ZXh0Tm9kZTsKKyAgICAgICAgU3RyaW5nIHByZWZpeDsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6ZW1wbG95ZWVJZCIpOworICAgICAgICB0ZXN0RW1wbG95ZWUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgICBhc3NlcnROb3ROdWxsKCJlbXBFbXBsb3llZU5vdE51bGwiLCB0ZXN0RW1wbG95ZWUpOworICAgICAgICB0ZXh0Tm9kZSA9IHRlc3RFbXBsb3llZS5nZXRGaXJzdENoaWxkKCk7CisgICAgICAgIHByZWZpeCA9IHRleHROb2RlLmdldFByZWZpeCgpOworICAgICAgICBhc3NlcnROdWxsKCJ0ZXh0Tm9kZVByZWZpeCIsIHByZWZpeCk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQcmVmaXgzKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgICBTdHJpbmcgcHJlZml4OworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDplbXBsb3llZSIpOworICAgICAgICB0ZXN0RW1wbG95ZWUgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgICBhc3NlcnROb3ROdWxsKCJlbXBFbXBsb3llZU5vdE51bGwiLCB0ZXN0RW1wbG95ZWUpOworICAgICAgICBwcmVmaXggPSB0ZXN0RW1wbG95ZWUuZ2V0UHJlZml4KCk7CisgICAgICAgIGFzc2VydEVxdWFscygicHJlZml4IiwgImVtcCIsIHByZWZpeCk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQcmVmaXg0KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIE5vZGUgdGVzdEVtcGxveWVlOworICAgICAgICBTdHJpbmcgcHJlZml4OworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICAgIHRlc3RFbXBsb3llZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIHByZWZpeCA9IHRlc3RFbXBsb3llZS5nZXRQcmVmaXgoKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgidGhyb3dfTnVsbCIsIHByZWZpeCk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQcmVmaXg1KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIEVsZW1lbnQgYWRkck5vZGU7CisgICAgICAgIEF0dHIgYWRkckF0dHI7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmFkZHJlc3MiKTsKKyAgICAgICAgYWRkck5vZGUgPSAoRWxlbWVudCkgZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkck5vdE51bGwiLCBhZGRyTm9kZSk7CisgICAgICAgIGFkZHJBdHRyID0gYWRkck5vZGUuZ2V0QXR0cmlidXRlTm9kZSgiZW1wOmRvbWVzdGljIik7CisKKyAgICAgICAgeworICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGFkZHJBdHRyLnNldFByZWZpeCgieG1sbnMiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgX3Rlc3RHZXRQcmVmaXg2KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisKKyAgICAgICAgeworICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGVtcGxveWVlTm9kZS5zZXRQcmVmaXgoInByZV5maXggeG1sbnM9J2h0dHAvL3d3dy5uaXN0LmdvdiciKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X0lOVkFMSURfQ0hBUkFDVEVSX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQcmVmaXg3KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcGxveWVlIik7CisgICAgICAgIGVtcGxveWVlTm9kZSA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisKKyAgICAgICAgeworICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGVtcGxveWVlTm9kZS5zZXRQcmVmaXgoImVtcDo6Iik7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorCisvLyBBc3N1bWVzIHZhbGlkYXRpb24uCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UHJlZml4OCgpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBOb2RlTGlzdCBnZW5kZXJMaXN0OworLy8gICAgICAgIE5vZGUgZ2VuZGVyTm9kZTsKKy8vICAgICAgICBOb2RlIGVudFJlZjsKKy8vICAgICAgICBOb2RlIGVudEVsZW1lbnQ7CisvLworLy8gICAgICAgIGludCBub2RlVHlwZTsKKy8vICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmIiwgYnVpbGRlcik7CisvLyAgICAgICAgZ2VuZGVyTGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZ2VuZGVyIik7CisvLyAgICAgICAgZ2VuZGVyTm9kZSA9IGdlbmRlckxpc3QuaXRlbSgyKTsKKy8vICAgICAgICBlbnRSZWYgPSBnZW5kZXJOb2RlLmdldEZpcnN0Q2hpbGQoKTsKKy8vICAgICAgICBub2RlVHlwZSA9IChpbnQpIGVudFJlZi5nZXROb2RlVHlwZSgpOworLy8KKy8vICAgICAgICBpZiAoMSA9PSBub2RlVHlwZSkgeworLy8gICAgICAgICAgICBlbnRSZWYgPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQ0Iik7CisvLyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZW50UmVmKTsKKy8vICAgICAgICB9CisvLyAgICAgICAgZW50RWxlbWVudCA9IGVudFJlZi5nZXRGaXJzdENoaWxkKCk7CisvLyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZW50RWxlbWVudCIsIGVudEVsZW1lbnQpOworLy8gICAgICAgIGRvYy5jcmVhdGVFbGVtZW50KCJ0ZXh0MyIpOworLy8KKy8vICAgICAgICB7CisvLyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworLy8gICAgICAgICAgICB0cnkgeworLy8gICAgICAgICAgICAgICAgZW50RWxlbWVudC5zZXRQcmVmaXgoIm5ld1ByZWZpeCIpOworLy8gICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKy8vICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKy8vICAgICAgICAgICAgfQorLy8gICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBzdWNjZXNzKTsKKy8vICAgICAgICB9CisvLyAgICB9CisgICAgcHVibGljIHZvaWQgX3Rlc3RHZXRQcmVmaXg5KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIEVsZW1lbnQgYWRkck5vZGU7CisgICAgICAgIEF0dHIgYWRkckF0dHI7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgICBhZGRyTm9kZSA9IChFbGVtZW50KSBlbGVtZW50TGlzdC5pdGVtKDMpOworICAgICAgICBhZGRyQXR0ciA9IGFkZHJOb2RlLmdldEF0dHJpYnV0ZU5vZGUoInhtbG5zIik7CisKKyAgICAgICAgeworICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGFkZHJBdHRyLnNldFByZWZpeCgieHh4Iik7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQcmVmaXgxMCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBOb2RlIGVtcGxveWVlTm9kZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgICBlbXBsb3llZU5vZGUgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBlbXBsb3llZU5vZGUuc2V0UHJlZml4KCJ4bWwiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldFByZWZpeDExKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIE5vZGUgZW1wbG95ZWVOb2RlOworCisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgICAgZW1wbG95ZWVOb2RlID0gZWxlbWVudExpc3QuaXRlbSgxKTsKKyAgICAgICAgZW1wbG95ZWVOb2RlLmdldE5hbWVzcGFjZVVSSSgpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBlbXBsb3llZU5vZGUuc2V0UHJlZml4KCJlbXBsb3llZTEiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vUHVibGljSWQuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9QdWJsaWNJZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ0N2EyNTAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vUHVibGljSWQuamF2YQpAQCAtMCwwICsxLDc5IEBACisKKy8qCitUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCithbmQgaXMgYSBkZXJpdmVkIHdvcmsgZnJvbSB0aGUgc291cmNlIGRvY3VtZW50LgorVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCitDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyhNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbAorUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCitob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCit0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCitQVVJQT1NFLgorCitTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRUeXBlOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqICAgICBUaGUgImdldFB1YmxpY0lkKCkiIG1ldGhvZCBvZiBhIGRvY3VtZW50dHlwZSBub2RlIGNvbnRhaW5zCisgKiAgICB0aGUgcHVibGljIGlkZW50aWZpZXIgYXNzb2NpYXRlZCB3aXRoIHRoZSBleHRlcm5hbCBzdWJzZXQuCisgKgorICogICAgUmV0cmlldmUgdGhlIGRvY3VtZW50dHlwZS4KKyAqICAgIEFwcGx5IHRoZSAiZ2V0UHVibGljSWQoKSIgbWV0aG9kLiAgVGhlIHN0cmluZyAiU1RBRkYiIHNob3VsZCBiZQorICogICAgcmV0dXJuZWQuCisqIEBhdXRob3IgTklTVAorKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtQ29yZS1Eb2NUeXBlLXB1YmxpY0lkIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtQ29yZS1Eb2NUeXBlLXB1YmxpY0lkPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBQdWJsaWNJZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQdWJsaWNJZCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGU7CisgICAgICBTdHJpbmcgcHVibGljSWQ7CisgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgcHVibGljSWQgPSBkb2NUeXBlLmdldFB1YmxpY0lkKCk7CisgICAgICBhc3NlcnRFcXVhbHMoInRocm93X0VxdWFscyIsICJTVEFGRiIsIHB1YmxpY0lkKTsKKyAgICAgIH0KKworfQorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vUmVtb3ZlQXR0cmlidXRlTlMuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9SZW1vdmVBdHRyaWJ1dGVOUy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAyOTM1NzgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vUmVtb3ZlQXR0cmlidXRlTlMuamF2YQpAQCAtMCwwICsxLDE0NCBAQAorLyoKKyBUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCisgYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KKyBUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKyBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQorIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuICBBbGwKKyBSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCisgSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCisgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgorIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyBQVVJQT1NFLgorCisgU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCisKKworICovCisKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKK2ltcG9ydCBvcmcudzNjLmRvbS5BdHRyOworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CisKKy8qKgorICogVGhlICJyZW1vdmVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKSIgbWV0aG9kIGZvciBhbiBhdHRyaWJ1dGUKKyAqIGNhdXNlcyB0aGUgRE9NRXhjZXB0aW9uIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiB0byBiZSByYWlzZWQgaWYgdGhlIG5vZGUKKyAqIGlzIHJlYWRvbmx5LgorICoKKyAqIE9idGFpbiB0aGUgY2hpbGRyZW4gb2YgdGhlIFRISVJEICJnZW5kZXIiIGVsZW1lbnQuIFRoZSBlbGVtZW50cyBjb250ZW50IGlzIGFuCisgKiBlbnRpdHkgcmVmZXJlbmNlLiBUcnkgdG8gcmVtb3ZlIGFuIGF0dHJpYnV0ZSBmcm9tIHRoZSBlbnRpdHkgcmVmZXJlbmNlIGJ5CisgKiBleGVjdXRpbmcgdGhlICJyZW1vdmVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKSIgbWV0aG9kLiBUaGlzIGNhdXNlcworICogYSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgRE9NRXhjZXB0aW9uIHRvIGJlIHRocm93bi4KKyAqCisgKiBAYXV0aG9yIE5JU1QKKyAqIEBhdXRob3IgTWFyeSBCcmFkeQorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlInXSk8L2E+CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFJlbUF0TlMiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1FbFJlbUF0TlM8L2E+CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRWxSZW1BdE5TJykvcmFpc2VzL2V4Y2VwdGlvbltAbmFtZT0nRE9NRXhjZXB0aW9uJ10vZGVzY3IvcFtzdWJzdHJpbmctYmVmb3JlKC4sJzonKT0nTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELUVsUmVtQXROUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J05PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiddKTwvYT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFJlbW92ZUF0dHJpYnV0ZU5TIGV4dGVuZHMgRE9NVGVzdENhc2UgeworCisgICAgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBmYWN0b3J5OworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5KERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbmZpZ3VyYXRpb24yKCkpOworICAgICAgICAgICAgYnVpbGRlciA9IGZhY3RvcnkuZ2V0QnVpbGRlcigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmFjdG9yeSA9IG51bGw7CisgICAgICAgIGJ1aWxkZXIgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIHRlc3QgY2FzZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVGhyb3dhYmxlCisgICAgICogICAgICAgICAgICAgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgICovCisvLyBBc3N1bWVzIHZhbGlkYXRpb24uCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlQXR0cmlidXRlTlMxKCkgdGhyb3dzIFRocm93YWJsZSB7CisvLyAgICAgICAgRG9jdW1lbnQgZG9jOworLy8gICAgICAgIE5vZGVMaXN0IGdlbmRlckxpc3Q7CisvLyAgICAgICAgTm9kZSBnZW5kZXI7CisvLyAgICAgICAgTm9kZSBnZW47CisvLyAgICAgICAgTm9kZUxpc3QgZ0xpc3Q7CisvLyAgICAgICAgRWxlbWVudCBnZW5FbGVtZW50OworLy8gICAgICAgIGludCBub2RlVHlwZTsKKy8vICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKy8vICAgICAgICBnZW5kZXJMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJnZW5kZXIiKTsKKy8vICAgICAgICBnZW5kZXIgPSBnZW5kZXJMaXN0Lml0ZW0oMik7CisvLyAgICAgICAgZ2VuID0gZ2VuZGVyLmdldEZpcnN0Q2hpbGQoKTsKKy8vICAgICAgICBub2RlVHlwZSA9IChpbnQpIGdlbi5nZXROb2RlVHlwZSgpOworLy8KKy8vICAgICAgICBpZiAoMSA9PSBub2RlVHlwZSkgeworLy8gICAgICAgICAgICBnZW4gPSBkb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKCJlbnQ0Iik7CisvLyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoImNyZWF0ZWRFbnRSZWZOb3ROdWxsIiwgZ2VuKTsKKy8vICAgICAgICB9CisvLyAgICAgICAgZ0xpc3QgPSBnZW4uZ2V0Q2hpbGROb2RlcygpOworLy8gICAgICAgIGdlbkVsZW1lbnQgPSAoRWxlbWVudCkgZ0xpc3QuaXRlbSgwKTsKKy8vICAgICAgICBhc3NlcnROb3ROdWxsKCJub3RudWxsIiwgZ2VuRWxlbWVudCk7CisvLworLy8gICAgICAgIHsKKy8vICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisvLyAgICAgICAgICAgIHRyeSB7CisvLyAgICAgICAgICAgICAgICBnZW5FbGVtZW50LnJlbW92ZUF0dHJpYnV0ZU5TKCJ3d3cueHl6LmNvbSIsICJsb2NhbDEiKTsKKy8vICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisvLyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisvLyAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisvLyAgICAgICAgfQorLy8gICAgfQorCisvLyBBc3N1bWVzIHZhbGlkYXRpb24KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVBdHRyaWJ1dGVOUzIoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKy8vICAgICAgICBEb2N1bWVudCBkb2M7CisvLyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisvLyAgICAgICAgTm9kZSB0ZXN0QWRkcjsKKy8vICAgICAgICBBdHRyIGFkZHJBdHRyOworLy8gICAgICAgIFN0cmluZyBhdHRyOworLy8gICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkk7CisvLyAgICAgICAgU3RyaW5nIGxvY2FsTmFtZTsKKy8vICAgICAgICBTdHJpbmcgcHJlZml4OworLy8gICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworLy8gICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6YWRkcmVzcyIpOworLy8gICAgICAgIHRlc3RBZGRyID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKy8vICAgICAgICAoKEVsZW1lbnQpIC8qIE5vZGUgKi90ZXN0QWRkcikucmVtb3ZlQXR0cmlidXRlTlMoImh0dHA6Ly93d3cubmlzdC5nb3YiLAorLy8gICAgICAgICAgICAgICAgImxvY2FsMSIpOworLy8gICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6YWRkcmVzcyIpOworLy8gICAgICAgIHRlc3RBZGRyID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKy8vICAgICAgICBhZGRyQXR0ciA9ICgoRWxlbWVudCkgLyogTm9kZSAqL3Rlc3RBZGRyKS5nZXRBdHRyaWJ1dGVOb2RlTlMoCisvLyAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJsb2NhbDEiKTsKKy8vICAgICAgICBhdHRyID0gKChFbGVtZW50KSAvKiBOb2RlICovdGVzdEFkZHIpLmdldEF0dHJpYnV0ZU5TKAorLy8gICAgICAgICAgICAgICAgImh0dHA6Ly93d3cubmlzdC5nb3YiLCAibG9jYWwxIik7CisvLyAgICAgICAgbmFtZXNwYWNlVVJJID0gYWRkckF0dHIuZ2V0TmFtZXNwYWNlVVJJKCk7CisvLyAgICAgICAgbG9jYWxOYW1lID0gYWRkckF0dHIuZ2V0TG9jYWxOYW1lKCk7CisvLyAgICAgICAgcHJlZml4ID0gdGVzdEFkZHIuZ2V0UHJlZml4KCk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyIiwgIkZBTFNFIiwgYXR0cik7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1cmkiLCAiaHR0cDovL3d3dy5uaXN0LmdvdiIsIG5hbWVzcGFjZVVSSSk7CisvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCJsbmFtZSIsICJsb2NhbDEiLCBsb2NhbE5hbWUpOworLy8gICAgICAgIGFzc2VydEVxdWFscygicHJlZml4IiwgImVtcCIsIHByZWZpeCk7CisvLyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vUmVtb3ZlTmFtZWRJdGVtTlMuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9SZW1vdmVOYW1lZEl0ZW1OUy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQwMWQ1YzEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vUmVtb3ZlTmFtZWRJdGVtTlMuamF2YQpAQCAtMCwwICsxLDE2MCBAQAorLyoKKyBUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCisgYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KKyBUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKyBDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCisgUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgUFVSUE9TRS4KKworIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyAqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CitpbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogVGhlICJyZW1vdmVOYW1lZEl0ZW1OUyhuYW1lc3BhY2VVUkksbG9jYWxOYW1lKSIgbWV0aG9kIGZvciBhIE5hbWVkTm9kZU1hcAorICogc2hvdWxkIHJlbW92ZSBhIG5vZGUgc3BlY2lmaWVkIGJ5IGxvY2FsTmFtZSBhbmQgbmFtZXNwYWNlVVJJLgorICoKKyAqIFJldHJpZXZlIGEgbGlzdCBvZiBlbGVtZW50cyB3aXRoIHRhZyBuYW1lICJhZGRyZXNzIi4gQWNjZXNzIHRoZSBzZWNvbmQKKyAqIGVsZW1lbnQgZnJvbSB0aGUgbGlzdCBhbmQgZ2V0IGl0cyBhdHRyaWJ1dGVzLiBUcnkgdG8gcmVtb3ZlIHRoZSBhdHRyaWJ1dGUKKyAqIG5vZGUgd2l0aCBsb2NhbCBuYW1lICJkb21lc3RpYyIgYW5kIG5hbWVzcGFjZSB1cmkgImh0dHA6Ly93d3cudXNhLmNvbSIgd2l0aAorICogbWV0aG9kIHJlbW92ZU5hbWVkSXRlbU5TKG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpLiBDaGVjayB0byBzZWUgaWYgdGhlIG5vZGUKKyAqIGhhcyBiZWVuIHJlbW92ZWQuCisgKgorICogQGF1dGhvciBOSVNUCisgKiBAYXV0aG9yIE1hcnkgQnJhZHkKKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELTEwNzQ1Nzc1NDkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC0xMDc0NTc3NTQ5PC9hPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUmVtb3ZlTmFtZWRJdGVtTlMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlTmFtZWRJdGVtTlMxKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIE5vZGUgdGVzdEFkZHJlc3M7CisgICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworICAgICAgICBBdHRyIG5ld0F0dHI7CisgICAgICAgIE5vZGUgcmVtb3ZlZE5vZGU7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgICB0ZXN0QWRkcmVzcyA9IGVsZW1lbnRMaXN0Lml0ZW0oMSk7CisgICAgICAgIGF0dHJpYnV0ZXMgPSB0ZXN0QWRkcmVzcy5nZXRBdHRyaWJ1dGVzKCk7CisgICAgICAgIHJlbW92ZWROb2RlID0gYXR0cmlidXRlcy5yZW1vdmVOYW1lZEl0ZW1OUygiaHR0cDovL3d3dy51c2EuY29tIiwKKyAgICAgICAgICAgICAgICAiZG9tZXN0aWMiKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgicmV0dmFsIiwgcmVtb3ZlZE5vZGUpOworICAgICAgICBuZXdBdHRyID0gKEF0dHIpIGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJkbXN0Yzpkb21lc3RpYyIpOworICAgICAgICBhc3NlcnROdWxsKCJub2RlUmVtb3ZlZCIsIG5ld0F0dHIpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlTmFtZWRJdGVtTlMyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy51c2EuY29tIjsKKyAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9ICJkb21lc3QiOworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBOb2RlIHRlc3RBZGRyZXNzOworICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgICAgdGVzdEFkZHJlc3MgPSBlbGVtZW50TGlzdC5pdGVtKDEpOworICAgICAgICBhdHRyaWJ1dGVzID0gdGVzdEFkZHJlc3MuZ2V0QXR0cmlidXRlcygpOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLnJlbW92ZU5hbWVkSXRlbU5TKG5hbWVzcGFjZVVSSSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsTmFtZSk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9UX0ZPVU5EX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorCisvLyBBc3N1bWVzIHZhbGlkYXRpb24uCisvLyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlTmFtZWRJdGVtTlMzKCkgdGhyb3dzIFRocm93YWJsZSB7CisvLyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyI7CisvLyAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9ICJsb2NhbDEiOworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKy8vICAgICAgICBOb2RlIHRlc3RBZGRyZXNzOworLy8gICAgICAgIE5vZGVMaXN0IG5MaXN0OworLy8gICAgICAgIE5vZGUgY2hpbGQ7CisvLyAgICAgICAgTm9kZUxpc3QgbjJMaXN0OworLy8gICAgICAgIE5vZGUgY2hpbGQyOworLy8gICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworLy8KKy8vICAgICAgICBpbnQgbm9kZVR5cGU7CisvLyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisvLyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImdlbmRlciIpOworLy8gICAgICAgIHRlc3RBZGRyZXNzID0gZWxlbWVudExpc3QuaXRlbSgyKTsKKy8vICAgICAgICBuTGlzdCA9IHRlc3RBZGRyZXNzLmdldENoaWxkTm9kZXMoKTsKKy8vICAgICAgICBjaGlsZCA9IG5MaXN0Lml0ZW0oMCk7CisvLyAgICAgICAgbm9kZVR5cGUgPSAoaW50KSBjaGlsZC5nZXROb2RlVHlwZSgpOworLy8KKy8vICAgICAgICBpZiAoMSA9PSBub2RlVHlwZSkgeworLy8gICAgICAgICAgICBjaGlsZCA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDQiKTsKKy8vICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBjaGlsZCk7CisvLyAgICAgICAgfQorLy8gICAgICAgIG4yTGlzdCA9IGNoaWxkLmdldENoaWxkTm9kZXMoKTsKKy8vICAgICAgICBjaGlsZDIgPSBuMkxpc3QuaXRlbSgwKTsKKy8vICAgICAgICBhc3NlcnROb3ROdWxsKCJub3RudWxsIiwgY2hpbGQyKTsKKy8vICAgICAgICBhdHRyaWJ1dGVzID0gY2hpbGQyLmdldEF0dHJpYnV0ZXMoKTsKKy8vCisvLyAgICAgICAgeworLy8gICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKy8vICAgICAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMucmVtb3ZlTmFtZWRJdGVtTlMobmFtZXNwYWNlVVJJLAorLy8gICAgICAgICAgICAgICAgICAgICAgICBsb2NhbE5hbWUpOworLy8gICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKy8vICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKy8vICAgICAgICAgICAgfQorLy8gICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBzdWNjZXNzKTsKKy8vICAgICAgICB9CisvLyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vU2V0QXR0cmlidXRlTlMuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9TZXRBdHRyaWJ1dGVOUy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY3MWVmYmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vU2V0QXR0cmlidXRlTlMuamF2YQpAQCAtMCwwICsxLDMwMSBAQAorLyoKKyBUaGlzIEphdmEgc291cmNlIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB0ZXN0LXRvLWphdmEueHNsCisgYW5kIGlzIGEgZGVyaXZlZCB3b3JrIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4KKyBUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKKyBDb3B5cmlnaHQgKGMpIDIwMDEgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCisgUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgUFVSUE9TRS4KKworIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyAqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5BdHRyOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSAic2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLHF1YWxpZmllZE5hbWUsVmFsdWUpIiBtZXRob2QgcmFpc2VzIGEKKyAqIElOVkFMSURfQ0hBUkFDVEVSX0VSUiBET01FeGNlcHRpb24gaWYgdGhlIHNwZWNpZmllZCBwcmVmaXggY29udGFpbnMgYW4KKyAqIGlsbGVnYWwgY2hhcmFjdGVyLgorICoKKyAqIEF0dGVtcHQgdG8gYWRkIGEgbmV3IGF0dHJpYnV0ZSBvbiB0aGUgZmlyc3QgZW1wbG95ZWUgbm9kZS4gQW4gZXhjZXB0aW9uCisgKiBzaG91bGQgYmUgcmFpc2VkIHNpbmNlIHRoZSAicXVhbGlmaWVkTmFtZSIgaGFzIGFuIGludmFsaWQgY2hhcmFjdGVyLgorICoKKyAqIEBhdXRob3IgTklTVAorICogQGF1dGhvciBNYXJ5IEJyYWR5CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5WQUxJRF9DSEFSQUNURVJfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVkFMSURfQ0hBUkFDVEVSX0VSUiddKTwvYT4KKyAqIEBzZWUgPGEKKyAqICAgICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXR0ck5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdHRyTlM8L2E+CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRWxTZXRBdHRyTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRWxTZXRBdHRyTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlZBTElEX0NIQVJBQ1RFUl9FUlInXSk8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTZXRBdHRyaWJ1dGVOUyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRBdHRyaWJ1dGVOUzEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5pc3QuZ292IjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiZW1wOnF1YWw/bmFtZSI7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIE5vZGUgdGVzdEFkZHI7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgICAgdGVzdEFkZHIgPSBlbGVtZW50TGlzdC5pdGVtKDApOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAoKEVsZW1lbnQpIC8qIE5vZGUgKi90ZXN0QWRkcikuc2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLAorICAgICAgICAgICAgICAgICAgICAgICAgcXVhbGlmaWVkTmFtZSwgIm5ld1ZhbHVlIik7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTlZBTElEX0NIQVJBQ1RFUl9FUlIiLCBzdWNjZXNzKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0QXR0cmlidXRlTlMyKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5uaXN0LmdvdiI7CisgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gImVtcDoiOworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBOb2RlIHRlc3RBZGRyOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDplbXBsb3llZSIpOworICAgICAgICB0ZXN0QWRkciA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisKKyAgICAgICAgeworICAgICAgICAgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisgICAgICAgICAgICAvLyAgICAgT3VyIGV4Y2VwdGlvbiBwcmlvcml0aWVzIGRpZmZlciBmcm9tIHRoZSBzcGVjCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICgoRWxlbWVudCkgLyogTm9kZSAqL3Rlc3RBZGRyKS5zZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksCisgICAgICAgICAgICAgICAgICAgICAgICBxdWFsaWZpZWROYW1lLCAibmV3VmFsdWUiKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgfQorICAgIH0KKworLy8gQXNzdW1lcyB2YWxpZGF0aW9uLgorLy8gICAgcHVibGljIHZvaWQgdGVzdFNldEF0dHJpYnV0ZU5TMygpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAid3d3Lnh5ei5jb20iOworLy8gICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gImVtcDpsb2NhbDEiOworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBOb2RlTGlzdCBnZW5kZXJMaXN0OworLy8gICAgICAgIE5vZGUgZ2VuZGVyOworLy8gICAgICAgIE5vZGVMaXN0IGdlbkxpc3Q7CisvLyAgICAgICAgTm9kZSBnZW47CisvLyAgICAgICAgTm9kZUxpc3QgZ0xpc3Q7CisvLyAgICAgICAgRWxlbWVudCBnZW5FbGVtZW50OworLy8gICAgICAgIGludCBub2RlVHlwZTsKKy8vICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKy8vICAgICAgICBnZW5kZXJMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJnZW5kZXIiKTsKKy8vICAgICAgICBnZW5kZXIgPSBnZW5kZXJMaXN0Lml0ZW0oMik7CisvLyAgICAgICAgZ2VuTGlzdCA9IGdlbmRlci5nZXRDaGlsZE5vZGVzKCk7CisvLyAgICAgICAgZ2VuID0gZ2VuTGlzdC5pdGVtKDApOworLy8gICAgICAgIG5vZGVUeXBlID0gKGludCkgZ2VuLmdldE5vZGVUeXBlKCk7CisvLworLy8gICAgICAgIGlmICgxID09IG5vZGVUeXBlKSB7CisvLyAgICAgICAgICAgIGdlbiA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDQiKTsKKy8vICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBnZW4pOworLy8gICAgICAgIH0KKy8vICAgICAgICBnTGlzdCA9IGdlbi5nZXRDaGlsZE5vZGVzKCk7CisvLyAgICAgICAgZ2VuRWxlbWVudCA9IChFbGVtZW50KSBnTGlzdC5pdGVtKDApOworLy8gICAgICAgIGFzc2VydE5vdE51bGwoIm5vdG51bGwiLCBnZW5FbGVtZW50KTsKKy8vCisvLyAgICAgICAgeworLy8gICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKy8vICAgICAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgICAgIGdlbkVsZW1lbnQuc2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lLAorLy8gICAgICAgICAgICAgICAgICAgICAgICAibmV3VmFsdWUiKTsKKy8vICAgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisvLyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7CisvLyAgICAgICAgICAgIH0KKy8vICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisvLyAgICAgICAgfQorLy8gICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRBdHRyaWJ1dGVOUzQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgTm9kZSB0ZXN0QWRkcjsKKyAgICAgICAgQXR0ciBhZGRyQXR0cjsKKyAgICAgICAgU3RyaW5nIHJlc3VsdEF0dHI7CisgICAgICAgIFN0cmluZyByZXN1bHROYW1lc3BhY2VVUkk7CisgICAgICAgIFN0cmluZyByZXN1bHRMb2NhbE5hbWU7CisgICAgICAgIFN0cmluZyByZXN1bHRQcmVmaXg7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmFkZHJlc3MiKTsKKyAgICAgICAgdGVzdEFkZHIgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgICBhc3NlcnROb3ROdWxsKCJlbXBBZGRyTm90TnVsbCIsIHRlc3RBZGRyKTsKKyAgICAgICAgKChFbGVtZW50KSAvKiBOb2RlICovdGVzdEFkZHIpLnNldEF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwKKyAgICAgICAgICAgICAgICAibmV3cHJlZml4OnpvbmUiLCAibmV3VmFsdWUiKTsKKyAgICAgICAgYWRkckF0dHIgPSAoKEVsZW1lbnQpIC8qIE5vZGUgKi90ZXN0QWRkcikuZ2V0QXR0cmlidXRlTm9kZU5TKAorICAgICAgICAgICAgICAgICJodHRwOi8vd3d3Lm5pc3QuZ292IiwgInpvbmUiKTsKKyAgICAgICAgcmVzdWx0QXR0ciA9ICgoRWxlbWVudCkgLyogTm9kZSAqL3Rlc3RBZGRyKS5nZXRBdHRyaWJ1dGVOUygKKyAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy5uaXN0LmdvdiIsICJ6b25lIik7CisgICAgICAgIGFzc2VydEVxdWFscygiYXR0clZhbHVlIiwgIm5ld1ZhbHVlIiwgcmVzdWx0QXR0cik7CisgICAgICAgIHJlc3VsdE5hbWVzcGFjZVVSSSA9IGFkZHJBdHRyLmdldE5hbWVzcGFjZVVSSSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5zdXJpIiwgImh0dHA6Ly93d3cubmlzdC5nb3YiLCByZXN1bHROYW1lc3BhY2VVUkkpOworICAgICAgICByZXN1bHRMb2NhbE5hbWUgPSBhZGRyQXR0ci5nZXRMb2NhbE5hbWUoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJsbmFtZSIsICJ6b25lIiwgcmVzdWx0TG9jYWxOYW1lKTsKKyAgICAgICAgcmVzdWx0UHJlZml4ID0gYWRkckF0dHIuZ2V0UHJlZml4KCk7CisgICAgICAgIGFzc2VydEVxdWFscygicHJlZml4IiwgIm5ld3ByZWZpeCIsIHJlc3VsdFByZWZpeCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFNldEF0dHJpYnV0ZU5TNSgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gIm5ld0F0dHIiOworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cubmV3YXR0ci5jb20iOworICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJlbXA6bmV3QXR0ciI7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIE5vZGUgdGVzdEFkZHI7CisKKyAgICAgICAgU3RyaW5nIHJlc3VsdEF0dHI7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wOmFkZHJlc3MiKTsKKyAgICAgICAgdGVzdEFkZHIgPSBlbGVtZW50TGlzdC5pdGVtKDApOworICAgICAgICBhc3NlcnROb3ROdWxsKCJlbXBBZGRyTm90TnVsbCIsIHRlc3RBZGRyKTsKKyAgICAgICAgKChFbGVtZW50KSAvKiBOb2RlICovdGVzdEFkZHIpLnNldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwKKyAgICAgICAgICAgICAgICBxdWFsaWZpZWROYW1lLCAiPG5ld1ZhbHVlPiIpOworICAgICAgICByZXN1bHRBdHRyID0gKChFbGVtZW50KSAvKiBOb2RlICovdGVzdEFkZHIpLmdldEF0dHJpYnV0ZU5TKAorICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0aHJvd19FcXVhbHMiLCAiPG5ld1ZhbHVlPiIsIHJlc3VsdEF0dHIpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0QXR0cmlidXRlTlM2KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5uaXN0LmdvdiI7CisgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gInhtbDpxdWFsaWZpZWROYW1lIjsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgTm9kZSB0ZXN0QWRkcjsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXBsb3llZSIpOworICAgICAgICB0ZXN0QWRkciA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisKKyAgICAgICAgeworICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICgoRWxlbWVudCkgLyogTm9kZSAqL3Rlc3RBZGRyKS5zZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksCisgICAgICAgICAgICAgICAgICAgICAgICBxdWFsaWZpZWROYW1lLCAibmV3VmFsdWUiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OQU1FU1BBQ0VfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFNldEF0dHJpYnV0ZU5TNygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gImh0dHA6Ly93d3cubmlzdC5nb3YiOworICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJ4bWxucyI7CisgICAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgIE5vZGUgdGVzdEFkZHI7CisgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW1wbG95ZWUiKTsKKyAgICAgICAgdGVzdEFkZHIgPSBlbGVtZW50TGlzdC5pdGVtKDApOworCisgICAgICAgIHsKKyAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAoKEVsZW1lbnQpIC8qIE5vZGUgKi90ZXN0QWRkcikuc2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLAorICAgICAgICAgICAgICAgICAgICAgICAgcXVhbGlmaWVkTmFtZSwgIm5ld1ZhbHVlIik7CisgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTkFNRVNQQUNFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRBdHRyaWJ1dGVOUzkoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9ICJuZXdBdHRyIjsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5ld2F0dHIuY29tIjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiZW1wOm5ld0F0dHIiOworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBOb2RlIHRlc3RBZGRyOworICAgICAgICBBdHRyIGFkZHJBdHRyOworICAgICAgICBTdHJpbmcgcmVzdWx0QXR0cjsKKyAgICAgICAgU3RyaW5nIHJlc3VsdE5hbWVzcGFjZVVSSTsKKyAgICAgICAgU3RyaW5nIHJlc3VsdExvY2FsTmFtZTsKKyAgICAgICAgU3RyaW5nIHJlc3VsdFByZWZpeDsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6YWRkcmVzcyIpOworICAgICAgICB0ZXN0QWRkciA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoImVtcEFkZHJOb3ROdWxsIiwgdGVzdEFkZHIpOworICAgICAgICAoKEVsZW1lbnQpIC8qIE5vZGUgKi90ZXN0QWRkcikuc2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLAorICAgICAgICAgICAgICAgIHF1YWxpZmllZE5hbWUsICJuZXdWYWx1ZSIpOworICAgICAgICBhZGRyQXR0ciA9ICgoRWxlbWVudCkgLyogTm9kZSAqL3Rlc3RBZGRyKS5nZXRBdHRyaWJ1dGVOb2RlTlMoCisgICAgICAgICAgICAgICAgbmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOworICAgICAgICByZXN1bHRBdHRyID0gKChFbGVtZW50KSAvKiBOb2RlICovdGVzdEFkZHIpLmdldEF0dHJpYnV0ZU5TKAorICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhdHRyVmFsdWUiLCAibmV3VmFsdWUiLCByZXN1bHRBdHRyKTsKKyAgICAgICAgcmVzdWx0TmFtZXNwYWNlVVJJID0gYWRkckF0dHIuZ2V0TmFtZXNwYWNlVVJJKCk7CisgICAgICAgIGFzc2VydEVxdWFscygibnN1cmkiLCAiaHR0cDovL3d3dy5uZXdhdHRyLmNvbSIsIHJlc3VsdE5hbWVzcGFjZVVSSSk7CisgICAgICAgIHJlc3VsdExvY2FsTmFtZSA9IGFkZHJBdHRyLmdldExvY2FsTmFtZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImxuYW1lIiwgIm5ld0F0dHIiLCByZXN1bHRMb2NhbE5hbWUpOworICAgICAgICByZXN1bHRQcmVmaXggPSBhZGRyQXR0ci5nZXRQcmVmaXgoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwcmVmaXgiLCAiZW1wIiwgcmVzdWx0UHJlZml4KTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFNldEF0dHJpYnV0ZU5TMTAoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LmV4YW1wbGUuZ292IjsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgTm9kZSB0ZXN0QWRkcjsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJoY19zdGFmZiIsIGJ1aWxkZXIpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZW0iKTsKKyAgICAgICAgdGVzdEFkZHIgPSBlbGVtZW50TGlzdC5pdGVtKDApOworCisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICAgICAgLy8gICAgIE91ciBleGNlcHRpb24gcHJpb3JpdGllcyBkaWZmZXIgZnJvbSB0aGUgc3BlYworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAoKEVsZW1lbnQpIC8qIE5vZGUgKi90ZXN0QWRkcikuc2V0QXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCAiIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJuZXdWYWx1ZSIpOworICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL1NldEF0dHJpYnV0ZU5vZGVOUy5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL1NldEF0dHJpYnV0ZU5vZGVOUy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVlMjE4ZjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vU2V0QXR0cmlidXRlTm9kZU5TLmphdmEKQEAgLTAsMCArMSwyMDcgQEAKKy8qCisgVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorIGFuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCisgVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisgQ29weXJpZ2h0IChjKSAyMDAxLTIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKKyAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKKyBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCisgUmlnaHRzIFJlc2VydmVkLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQorIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQorIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KKyB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCisgUFVSUE9TRS4KKworIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyAqLworCitwYWNrYWdlIHRlc3RzLm9yZy53M2MuZG9tOworCitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworaW1wb3J0IG9yZy53M2MuZG9tLkF0dHI7CitpbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOworCitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOworCisvKioKKyAqIFRoZSAic2V0QXR0cmlidXRlTm9kZShuZXdBdHRyKSIgbWV0aG9kIHJhaXNlcyBhbiAiSU5VU0VfQVRUUklCVVRFX0VSUgorICogRE9NRXhjZXB0aW9uIGlmIHRoZSAibmV3QXR0ciIgaXMgYWxyZWFkeSBhbiBhdHRyaWJ1dGUgb2YgYW5vdGhlciBlbGVtZW50LgorICoKKyAqIFJldHJpZXZlIHRoZSBmaXJzdCBlbXA6YWRkcmVzcyBhbmQgYXBwZW5kIGEgbmV3bHkgY3JlYXRlZCBlbGVtZW50LiBUaGUKKyAqICJjcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkkscXVhbGlmaWVkTmFtZSkiIGFuZAorICogInNldEF0dHJpYnV0ZU5vZGVOUyhuZXdBdHRyKSIgbWV0aG9kcyBhcmUgaW52b2tlZCB0byBjcmVhdGUgYW5kIGFkZCBhIG5ldworICogYXR0cmlidXRlIHRvIHRoZSBuZXdseSBjcmVhdGVkIEVsZW1lbnQuIFRoZSAic2V0QXR0cmlidXRlTm9kZU5TKG5ld0F0dHIpIgorICogbWV0aG9kIGlzIG9uY2UgYWdhaW4gY2FsbGVkIHRvIGFkZCB0aGUgbmV3IGF0dHJpYnV0ZSBjYXVzaW5nIGFuIGV4Y2VwdGlvbiB0bworICogYmUgcmFpc2VkIHNpbmNlIHRoZSBhdHRyaWJ1dGUgaXMgYWxyZWFkeSBhbiBhdHRyaWJ1dGUgb2YgYW5vdGhlciBlbGVtZW50LgorICoKKyAqIEBhdXRob3IgTklTVAorICogQGF1dGhvciBNYXJ5IEJyYWR5CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtMjU4QTAwQUYnKS9jb25zdGFudFtAbmFtZT0nSU5VU0VfQVRUUklCVVRFX0VSUiddKSI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlVTRV9BVFRSSUJVVEVfRVJSJ10pPC9hPgorICogQHNlZSA8YQorICogICAgICBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtRWxTZXRBdE5vZGVOUyI+aHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELUVsU2V0QXROb2RlTlM8L2E+CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRWxTZXRBdE5vZGVOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVVNFX0FUVFJJQlVURV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtRWxTZXRBdE5vZGVOUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVVNFX0FUVFJJQlVURV9FUlInXSk8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTZXRBdHRyaWJ1dGVOb2RlTlMgZXh0ZW5kcyBET01UZXN0Q2FzZSB7CisKKyAgICBET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlcjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWN0b3J5ID0gbmV3IERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkoRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbjIoKSk7CisgICAgICAgICAgICBidWlsZGVyID0gZmFjdG9yeS5nZXRCdWlsZGVyKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgYnVpbGRlciA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICAqCisgICAgICogQHRocm93cyBUaHJvd2FibGUKKyAgICAgKiAgICAgICAgICAgICBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGNhdXNlcyB0ZXN0IHRvIGZhaWwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0QXR0cmlidXRlTm9kZTEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5ld2F0dHIuY29tIjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiZW1wOm5ld0F0dHIiOworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIEVsZW1lbnQgbmV3RWxlbWVudDsKKyAgICAgICAgQXR0ciBuZXdBdHRyOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgTm9kZSB0ZXN0QWRkcjsKKworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICAgIHRlc3RBZGRyID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkck5vdE51bGwiLCB0ZXN0QWRkcik7CisgICAgICAgIG5ld0VsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudCgibmV3RWxlbWVudCIpOworICAgICAgICB0ZXN0QWRkci5hcHBlbmRDaGlsZChuZXdFbGVtZW50KTsKKyAgICAgICAgbmV3QXR0ciA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgICBuZXdFbGVtZW50LnNldEF0dHJpYnV0ZU5vZGVOUyhuZXdBdHRyKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgKChFbGVtZW50KSAvKiBOb2RlICovdGVzdEFkZHIpLnNldEF0dHJpYnV0ZU5vZGVOUyhuZXdBdHRyKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uSU5VU0VfQVRUUklCVVRFX0VSUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19JTlVTRV9BVFRSSUJVVEVfRVJSIiwgc3VjY2Vzcyk7CisgICAgICAgIH0KKyAgICB9CisKKy8vIEFzc3VtZXMgdmFsaWRhdGlvbi4KKy8vICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRBdHRyaWJ1dGVOb2RlMigpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgIERvY3VtZW50IGRvYzsKKy8vICAgICAgICBOb2RlTGlzdCBnZW5kZXJMaXN0OworLy8gICAgICAgIE5vZGUgZ2VuZGVyOworLy8gICAgICAgIE5vZGVMaXN0IGdlbkxpc3Q7CisvLyAgICAgICAgTm9kZSBnZW47CisvLyAgICAgICAgTm9kZUxpc3QgZ0xpc3Q7CisvLyAgICAgICAgRWxlbWVudCBnZW5FbGVtZW50OworLy8gICAgICAgIEF0dHIgbmV3QXR0cjsKKy8vCisvLyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisvLworLy8gICAgICAgIGlmICghZmFjdG9yeS5pc0V4cGFuZEVudGl0eVJlZmVyZW5jZXMoKSkgeworLy8gICAgICAgICAgICBnZW5kZXJMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJnZW5kZXIiKTsKKy8vICAgICAgICAgICAgZ2VuZGVyID0gZ2VuZGVyTGlzdC5pdGVtKDIpOworLy8gICAgICAgICAgICBnZW5MaXN0ID0gZ2VuZGVyLmdldENoaWxkTm9kZXMoKTsKKy8vICAgICAgICAgICAgZ2VuID0gZ2VuTGlzdC5pdGVtKDApOworLy8gICAgICAgIH0gZWxzZSB7CisvLyAgICAgICAgICAgIGdlbiA9IGRvYy5jcmVhdGVFbnRpdHlSZWZlcmVuY2UoImVudDQiKTsKKy8vICAgICAgICB9CisvLworLy8gICAgICAgIGdMaXN0ID0gZ2VuLmdldENoaWxkTm9kZXMoKTsKKy8vICAgICAgICBnZW5FbGVtZW50ID0gKEVsZW1lbnQpIGdMaXN0Lml0ZW0oMCk7CisvLyAgICAgICAgYXNzZXJ0Tm90TnVsbCgibm90bnVsbCIsIGdlbkVsZW1lbnQpOworLy8gICAgICAgIG5ld0F0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMoInd3dy54eXouY29tIiwgImVtcDpsb2NhbDEiKTsKKy8vCisvLyAgICAgICAgeworLy8gICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKy8vICAgICAgICAgICAgdHJ5IHsKKy8vICAgICAgICAgICAgICAgIGdlbkVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZU5TKG5ld0F0dHIpOworLy8gICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKy8vICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKKy8vICAgICAgICAgICAgfQorLy8gICAgICAgICAgICBhc3NlcnRUcnVlKCJ0aHJvd19OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBzdWNjZXNzKTsKKy8vICAgICAgICB9CisvLyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFNldEF0dHJpYnV0ZU5vZGUzKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy5uZXdhdHRyLmNvbSI7CisgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gImVtcDpuZXdBdHRyIjsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgTm9kZSB0ZXN0QWRkcjsKKyAgICAgICAgQXR0ciBuZXdBdHRyOworICAgICAgICBBdHRyIG5ld0FkZHJBdHRyOworICAgICAgICBkb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICAgIHRlc3RBZGRyID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZW1wQWRkck5vdE51bGwiLCB0ZXN0QWRkcik7CisgICAgICAgIG5ld0F0dHIgPSBkb2MuY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKKyAgICAgICAgbmV3QWRkckF0dHIgPSAoKEVsZW1lbnQpIC8qIE5vZGUgKi90ZXN0QWRkcikKKyAgICAgICAgICAgICAgICAuc2V0QXR0cmlidXRlTm9kZU5TKG5ld0F0dHIpOworICAgICAgICBhc3NlcnROdWxsKCJ0aHJvd19OdWxsIiwgbmV3QWRkckF0dHIpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0QXR0cmlidXRlTm9kZTQoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKyAgICAgICAgTm9kZSB0ZXN0QWRkcjsKKyAgICAgICAgQXR0ciBuZXdBdHRyOworICAgICAgICBBdHRyIG5ld0FkZHJBdHRyOworICAgICAgICBTdHJpbmcgbmV3TmFtZTsKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGVsZW1lbnRMaXN0ID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJlbXA6YWRkcmVzcyIpOworICAgICAgICB0ZXN0QWRkciA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoImVtcEFkZHJOb3ROdWxsIiwgdGVzdEFkZHIpOworICAgICAgICBuZXdBdHRyID0gZG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3Lm5pc3QuZ292IiwgInh4eDpkb21lc3RpYyIpOworICAgICAgICBuZXdBZGRyQXR0ciA9ICgoRWxlbWVudCkgLyogTm9kZSAqL3Rlc3RBZGRyKQorICAgICAgICAgICAgICAgIC5zZXRBdHRyaWJ1dGVOb2RlTlMobmV3QXR0cik7CisgICAgICAgIG5ld05hbWUgPSBuZXdBZGRyQXR0ci5nZXROb2RlTmFtZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIm5vZGVOYW1lIiwgImVtcDpkb21lc3RpYyIsIG5ld05hbWUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0QXR0cmlidXRlTm9kZTUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5ld2F0dHIuY29tIjsKKyAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSAiZW1wOm5ld0F0dHIiOworICAgICAgICBEb2N1bWVudCBkb2MxOworICAgICAgICBEb2N1bWVudCBkb2MyOworICAgICAgICBBdHRyIG5ld0F0dHI7CisgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICBOb2RlIHRlc3RBZGRyOworCisgICAgICAgIGRvYzEgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgZG9jMiA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICBuZXdBdHRyID0gZG9jMi5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgICBlbGVtZW50TGlzdCA9IGRvYzEuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImVtcDphZGRyZXNzIik7CisgICAgICAgIHRlc3RBZGRyID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKworICAgICAgICB7CisgICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgKChFbGVtZW50KSAvKiBOb2RlICovdGVzdEFkZHIpLnNldEF0dHJpYnV0ZU5vZGVOUyhuZXdBdHRyKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSAoZXguY29kZSA9PSBET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X1dST05HX0RPQ1VNRU5UX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL1NldE5hbWVkSXRlbU5TLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvb3JnL3czYy9kb20vU2V0TmFtZWRJdGVtTlMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xODA4ODg1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL1NldE5hbWVkSXRlbU5TLmphdmEKQEAgLTAsMCArMSwyMTggQEAKKworLyoKK1RoaXMgSmF2YSBzb3VyY2UgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IHRlc3QtdG8tamF2YS54c2wKK2FuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCitUaGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5lZCB0aGUgZm9sbG93aW5nIG5vdGljZToKKworCisKK0NvcHlyaWdodCAoYykgMjAwMSBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAorKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCitSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiAgQWxsCitSaWdodHMgUmVzZXJ2ZWQuICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCitJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKK2hvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KK3RoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKK1BVUlBPU0UuCisKK1NlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgorCisKKyovCisKK3BhY2thZ2UgdGVzdHMub3JnLnczYy5kb207CisKK2ltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKK2ltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247CisKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CisKKy8qKgorICogICAgIFRoZSAic2V0TmFtZWRJdGVtTlMoYXJnKSIgbWV0aG9kIGZvciBhCisgKiAgICBOYW1lZE5vZGVNYXAgc2hvdWxkIHJhaXNlIElOVVNFX0FUVFJJQlVURV9FUlIgRE9NRXhjZXB0aW9uIGlmCisgKiAgICBhcmcgaXMgYW4gQXR0ciB0aGF0IGlzIGFscmVhZHkgYW4gYXR0cmlidXRlIG9mIGFub3RoZXIgRWxlbWVudCBvYmplY3QuCisgKgorICogICAgUmV0cmlldmUgYW4gYXR0ciBub2RlIGZyb20gdGhlIHRoaXJkICJhZGRyZXNzIiBlbGVtZW50IHdob3NlIGxvY2FsIG5hbWUKKyAqICAgIGlzICJkb21lc3RpYyIgYW5kIG5hbWVzcGFjZVVSSSBpcyAiaHR0cDovL3d3dy5uZXR6ZXJvLmNvbSIuCisgKiAgICBJbnZva2UgbWV0aG9kIHNldE5hbWVkSXRlbU5TKGFyZykgb24gdGhlIG1hcCBvZiB0aGUgZmlyc3QgImFkZHJlc3MiIGVsZW1lbnQgd2l0aAorICogICAgYXJnIGJlaW5nIHRoZSBhdHRyIG5vZGUgZnJvbSBhYm92ZS4gIE1ldGhvZCBzaG91bGQgcmFpc2UKKyAqICAgIElOVVNFX0FUVFJJQlVURV9FUlIgRE9NRXhjZXB0aW9uLgorKiBAYXV0aG9yIE5JU1QKKyogQGF1dGhvciBNYXJ5IEJyYWR5CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC0yNThBMDBBRicpL2NvbnN0YW50W0BuYW1lPSdJTlVTRV9BVFRSSUJVVEVfRVJSJ10pIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjeHBvaW50ZXIoaWQoJ0lELTI1OEEwMEFGJykvY29uc3RhbnRbQG5hbWU9J0lOVVNFX0FUVFJJQlVURV9FUlInXSk8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI0lELXNldE5hbWVkSXRlbU5TIj5odHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1Db3JlL2NvcmUjSUQtc2V0TmFtZWRJdGVtTlM8L2E+CisqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItQ29yZS9jb3JlI3hwb2ludGVyKGlkKCdJRC1zZXROYW1lZEl0ZW1OUycpL3JhaXNlcy9leGNlcHRpb25bQG5hbWU9J0RPTUV4Y2VwdGlvbiddL2Rlc2NyL3Bbc3Vic3RyaW5nLWJlZm9yZSguLCc6Jyk9J0lOVVNFX0FUVFJJQlVURV9FUlInXSkiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSN4cG9pbnRlcihpZCgnSUQtc2V0TmFtZWRJdGVtTlMnKS9yYWlzZXMvZXhjZXB0aW9uW0BuYW1lPSdET01FeGNlcHRpb24nXS9kZXNjci9wW3N1YnN0cmluZy1iZWZvcmUoLiwnOicpPSdJTlVTRV9BVFRSSUJVVEVfRVJSJ10pPC9hPgorKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTZXROYW1lZEl0ZW1OUyBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMigpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgIC8qKgorICAgICogUnVucyB0aGUgdGVzdCBjYXNlLgorICAgICogQHRocm93cyBUaHJvd2FibGUgQW55IHVuY2F1Z2h0IGV4Y2VwdGlvbiBjYXVzZXMgdGVzdCB0byBmYWlsCisgICAgKi8KKyAgIHB1YmxpYyB2b2lkIHRlc3RTZXROYW1lZEl0ZW1OUzEoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgIERvY3VtZW50IGRvYzsKKyAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgTm9kZSBhbm90aGVyRWxlbWVudDsKKyAgICAgIE5hbWVkTm9kZU1hcCBhbm90aGVyTWFwOworICAgICAgTm9kZSBhcmc7CisgICAgICBOb2RlIHRlc3RBZGRyZXNzOworICAgICAgTmFtZWROb2RlTWFwIG1hcDsKKworICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgYW5vdGhlckVsZW1lbnQgPSBlbGVtZW50TGlzdC5pdGVtKDIpOworICAgICAgYW5vdGhlck1hcCA9IGFub3RoZXJFbGVtZW50LmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgIGFyZyA9IGFub3RoZXJNYXAuZ2V0TmFtZWRJdGVtTlMoImh0dHA6Ly93d3cubmV0emVyby5jb20iLCAiZG9tZXN0aWMiKTsKKyAgICAgIHRlc3RBZGRyZXNzID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgIG1hcCA9IHRlc3RBZGRyZXNzLmdldEF0dHJpYnV0ZXMoKTsKKworICAgICAgeworICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgICB0cnkgeworICAgICAgICAgICAgbWFwLnNldE5hbWVkSXRlbU5TKGFyZyk7CisgICAgICAgICAgfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLklOVVNFX0FUVFJJQlVURV9FUlIpOworICAgICAgICAgfQorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfSU5VU0VfQVRUUklCVVRFX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgfQorfQorICAgcHVibGljIHZvaWQgdGVzdFNldE5hbWVkSXRlbU5TMigpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSAiaHR0cDovL3d3dy51c2EuY29tIjsKKyAgICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJkbXN0Yzpkb21lc3RpYyI7CisgICAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICAgIERvY3VtZW50IGFub3RoZXJEb2M7CisgICAgICAgICAgTm9kZSBhcmc7CisgICAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgICAgTm9kZSB0ZXN0QWRkcmVzczsKKyAgICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKworICAgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICAgIGFub3RoZXJEb2MgPSAoRG9jdW1lbnQpIGxvYWQoInN0YWZmTlMiLCBidWlsZGVyKTsKKyAgICAgICAgICBhcmcgPSBhbm90aGVyRG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7CisgICAgICAgICAgYXJnLnNldE5vZGVWYWx1ZSgiTWF5YmUiKTsKKyAgICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYWRkcmVzcyIpOworICAgICAgICAgIHRlc3RBZGRyZXNzID0gZWxlbWVudExpc3QuaXRlbSgwKTsKKyAgICAgICAgICBhdHRyaWJ1dGVzID0gdGVzdEFkZHJlc3MuZ2V0QXR0cmlidXRlcygpOworCisgICAgICAgICAgeworICAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5zZXROYW1lZEl0ZW1OUyhhcmcpOworICAgICAgICAgICAgICB9IGNhdGNoIChET01FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBzdWNjZXNzID0gKGV4LmNvZGUgPT0gRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUik7CisgICAgICAgICAgICAgfQorICAgICAgICAgICAgIGFzc2VydFRydWUoInRocm93X1dST05HX0RPQ1VNRU5UX0VSUiIsIHN1Y2Nlc3MpOworICAgICAgICAgIH0KKyAgICB9CisgICBwdWJsaWMgdm9pZCB0ZXN0U2V0TmFtZWRJdGVtTlMzKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3Lm5pc3QuZ292IjsKKyAgICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9ICJwcmVmaXg6bmV3QXR0ciI7CisgICAgICAgICAgRG9jdW1lbnQgZG9jOworICAgICAgICAgIE5vZGUgYXJnOworICAgICAgICAgIE5vZGVMaXN0IGVsZW1lbnRMaXN0OworICAgICAgICAgIE5vZGUgdGVzdEFkZHJlc3M7CisgICAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXM7CisgICAgICAgICAgTm9kZSByZXRub2RlOworICAgICAgICAgIFN0cmluZyB2YWx1ZTsKKworICAgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICAgIGFyZyA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgICAgIGFyZy5zZXROb2RlVmFsdWUoIm5ld1ZhbHVlIik7CisgICAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgICAgICB0ZXN0QWRkcmVzcyA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgICAgYXR0cmlidXRlcyA9IHRlc3RBZGRyZXNzLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgICBhdHRyaWJ1dGVzLnNldE5hbWVkSXRlbU5TKGFyZyk7CisgICAgICAgICAgcmV0bm9kZSA9IGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtTlMobmFtZXNwYWNlVVJJLCAibmV3QXR0ciIpOworICAgICAgICAgIHZhbHVlID0gcmV0bm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoInRocm93X0VxdWFscyIsICJuZXdWYWx1ZSIsIHZhbHVlKTsKKyAgICAgICAgICB9CisKKy8vIEFzc3VtZXMgdmFsaWRhdGlvbi4KKy8vICAgcHVibGljIHZvaWQgdGVzdFNldE5hbWVkSXRlbU5TNCgpIHRocm93cyBUaHJvd2FibGUgeworLy8gICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyI7CisvLyAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gImxvY2FsMSI7CisvLyAgICAgICAgICBEb2N1bWVudCBkb2M7CisvLyAgICAgICAgICBOb2RlTGlzdCBlbGVtZW50TGlzdDsKKy8vICAgICAgICAgIE5vZGUgdGVzdEFkZHJlc3M7CisvLyAgICAgICAgICBOb2RlTGlzdCBuTGlzdDsKKy8vICAgICAgICAgIE5vZGUgY2hpbGQ7CisvLyAgICAgICAgICBOb2RlTGlzdCBuMkxpc3Q7CisvLyAgICAgICAgICBOb2RlIGNoaWxkMjsKKy8vICAgICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzOworLy8gICAgICAgICAgTm9kZSBhcmc7CisvLworLy8gICAgICAgICAgaW50IG5vZGVUeXBlOworLy8gICAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisvLyAgICAgICAgICBlbGVtZW50TGlzdCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZ2VuZGVyIik7CisvLyAgICAgICAgICB0ZXN0QWRkcmVzcyA9IGVsZW1lbnRMaXN0Lml0ZW0oMik7CisvLyAgICAgICAgICBuTGlzdCA9IHRlc3RBZGRyZXNzLmdldENoaWxkTm9kZXMoKTsKKy8vICAgICAgICAgIGNoaWxkID0gbkxpc3QuaXRlbSgwKTsKKy8vICAgICAgICAgIG5vZGVUeXBlID0gKGludCkgY2hpbGQuZ2V0Tm9kZVR5cGUoKTsKKy8vCisvLyAgICAgICAgICBpZiAoMSA9PSBub2RlVHlwZSkgeworLy8gICAgICAgICAgICAgIGNoaWxkID0gZG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZSgiZW50NCIpOworLy8gICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiY3JlYXRlZEVudFJlZk5vdE51bGwiLCBjaGlsZCk7CisvLyAgICAgICAgICB9CisvLyAgICAgICAgbjJMaXN0ID0gY2hpbGQuZ2V0Q2hpbGROb2RlcygpOworLy8gICAgICAgICAgY2hpbGQyID0gbjJMaXN0Lml0ZW0oMCk7CisvLyAgICAgICAgICBhc3NlcnROb3ROdWxsKCJub3RudWxsIiwgY2hpbGQyKTsKKy8vICAgICAgICAgIGF0dHJpYnV0ZXMgPSBjaGlsZDIuZ2V0QXR0cmlidXRlcygpOworLy8gICAgICAgICAgYXJnID0gYXR0cmlidXRlcy5nZXROYW1lZEl0ZW1OUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7CisvLworLy8gICAgICAgICAgeworLy8gICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisvLyAgICAgICAgICAgICB0cnkgeworLy8gICAgICAgICAgICAgICAgYXR0cmlidXRlcy5zZXROYW1lZEl0ZW1OUyhhcmcpOworLy8gICAgICAgICAgICAgIH0gY2F0Y2ggKERPTUV4Y2VwdGlvbiBleCkgeworLy8gICAgICAgICAgICAgICAgc3VjY2VzcyA9IChleC5jb2RlID09IERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOworLy8gICAgICAgICAgICAgfQorLy8gICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgidGhyb3dfTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgc3VjY2Vzcyk7CisvLyAgICAgICAgICB9CisvLyAgICB9CisgICBwdWJsaWMgdm9pZCB0ZXN0U2V0TmFtZWRJdGVtTlM1KCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9ICJodHRwOi8vd3d3LnVzYS5jb20iOworICAgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gImRtc3RjOmRvbWVzdGljIjsKKyAgICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgICAgTm9kZSBhcmc7CisgICAgICAgICAgTm9kZUxpc3QgZWxlbWVudExpc3Q7CisgICAgICAgICAgTm9kZSB0ZXN0QWRkcmVzczsKKyAgICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cmlidXRlczsKKyAgICAgICAgICBOb2RlIHJldG5vZGU7CisgICAgICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgICAgIGRvYyA9IChEb2N1bWVudCkgbG9hZCgic3RhZmZOUyIsIGJ1aWxkZXIpOworICAgICAgICAgIGFyZyA9IGRvYy5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOworICAgICAgICAgIGFyZy5zZXROb2RlVmFsdWUoIm5ld1ZhbHVlIik7CisgICAgICAgICAgZWxlbWVudExpc3QgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImFkZHJlc3MiKTsKKyAgICAgICAgICB0ZXN0QWRkcmVzcyA9IGVsZW1lbnRMaXN0Lml0ZW0oMCk7CisgICAgICAgICAgYXR0cmlidXRlcyA9IHRlc3RBZGRyZXNzLmdldEF0dHJpYnV0ZXMoKTsKKyAgICAgICAgICByZXRub2RlID0gYXR0cmlidXRlcy5zZXROYW1lZEl0ZW1OUyhhcmcpOworICAgICAgICAgIHZhbHVlID0gcmV0bm9kZS5nZXROb2RlVmFsdWUoKTsKKyAgICAgICAgICBhc3NlcnRFcXVhbHMoInRocm93X0VxdWFscyIsICJZZXMiLCB2YWx1ZSk7CisgICAgICAgICAgfQorCit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9TeXN0ZW1JZC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL29yZy93M2MvZG9tL1N5c3RlbUlkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjQxZWEwYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9vcmcvdzNjL2RvbS9TeXN0ZW1JZC5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qCisgVGhpcyBKYXZhIHNvdXJjZSBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgdGVzdC10by1qYXZhLnhzbAorIGFuZCBpcyBhIGRlcml2ZWQgd29yayBmcm9tIHRoZSBzb3VyY2UgZG9jdW1lbnQuCisgVGhlIHNvdXJjZSBkb2N1bWVudCBjb250YWluZWQgdGhlIGZvbGxvd2luZyBub3RpY2U6CisKKworCisgQ29weXJpZ2h0IChjKSAyMDAxIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCisgKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCisgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gIEFsbAorIFJpZ2h0cyBSZXNlcnZlZC4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKKyBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKKyBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCisgdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorIFBVUlBPU0UuCisKKyBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KKworCisgKi8KKworcGFja2FnZSB0ZXN0cy5vcmcudzNjLmRvbTsKKworaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKKworLyoqCisgKiBUaGUgImdldFN5c3RlbUlkKCkiIG1ldGhvZCBvZiBhIGRvY3VtZW50dHlwZSBub2RlIGNvbnRhaW5zIHRoZSBzeXN0ZW0KKyAqIGlkZW50aWZpZXIgYXNzb2NpYXRlZCB3aXRoIHRoZSBleHRlcm5hbCBzdWJzZXQuCisgKgorICogUmV0cmlldmUgdGhlIGRvY3VtZW50dHlwZS4gQXBwbHkgdGhlICJnZXRTeXN0ZW1JZCgpIiBtZXRob2QuIFRoZSBzdHJpbmcKKyAqICJzdGFmZk5TLmR0ZCIgc2hvdWxkIGJlIHJldHVybmVkLgorICoKKyAqIEBhdXRob3IgTklTVAorICogQGF1dGhvciBNYXJ5IEJyYWR5CisgKiBAc2VlIDxhCisgKiAgICAgIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Db3JlLURvY1R5cGUtc3lzdGVtSWQiPmh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvY29yZSNJRC1Db3JlLURvY1R5cGUtc3lzdGVtSWQ8L2E+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTeXN0ZW1JZCBleHRlbmRzIERPTVRlc3RDYXNlIHsKKworICAgIERPTURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZhY3RvcnkgPSBuZXcgRE9NRG9jdW1lbnRCdWlsZGVyRmFjdG9yeShET01Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZXRDb25maWd1cmF0aW9uMSgpKTsKKyAgICAgICAgICAgIGJ1aWxkZXIgPSBmYWN0b3J5LmdldEJ1aWxkZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZhY3RvcnkgPSBudWxsOworICAgICAgICBidWlsZGVyID0gbnVsbDsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSdW5zIHRoZSB0ZXN0IGNhc2UuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFRocm93YWJsZQorICAgICAqICAgICAgICAgICAgIEFueSB1bmNhdWdodCBleGNlcHRpb24gY2F1c2VzIHRlc3QgdG8gZmFpbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRTeXN0ZW1JZCgpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICBEb2N1bWVudCBkb2M7CisgICAgICAgIERvY3VtZW50VHlwZSBkb2NUeXBlOworICAgICAgICBTdHJpbmcgc3lzdGVtSWQ7CisKKyAgICAgICAgZG9jID0gKERvY3VtZW50KSBsb2FkKCJzdGFmZk5TIiwgYnVpbGRlcik7CisgICAgICAgIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOworICAgICAgICBzeXN0ZW1JZCA9IGRvY1R5cGUuZ2V0U3lzdGVtSWQoKTsKKyAgICAgICAgYXNzZXJ0VVJJRXF1YWxzKCJzeXN0ZW1JZCIsIG51bGwsIG51bGwsIG51bGwsICJzdGFmZk5TLmR0ZCIsIG51bGwsCisgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwgbnVsbCwgc3lzdGVtSWQpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0NlcnRQYXRoQnVpbGRlclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9DZXJ0UGF0aEJ1aWxkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjY2MDM5MAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9DZXJ0UGF0aEJ1aWxkZXJUZXN0LmphdmEKQEAgLTAsMCArMSw1NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGg7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoQnVpbGRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhCdWlsZGVyUmVzdWx0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aFBhcmFtZXRlcnM7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworcHVibGljIGFic3RyYWN0IGNsYXNzIENlcnRQYXRoQnVpbGRlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBhbGdvcml0aG1OYW1lOworICAgIHByaXZhdGUgQ2VydFBhdGhQYXJhbWV0ZXJzIHBhcmFtczsKKworICAgIHB1YmxpYyBDZXJ0UGF0aEJ1aWxkZXJUZXN0KFN0cmluZyBhbGdvcml0aG1OYW1lKSB7CisgICAgICAgIHRoaXMuYWxnb3JpdGhtTmFtZSA9IGFsZ29yaXRobU5hbWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKworICAgICAgICBwYXJhbXMgPSBnZXRDZXJ0UGF0aFBhcmFtZXRlcnMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYWJzdHJhY3QgQ2VydFBhdGhQYXJhbWV0ZXJzIGdldENlcnRQYXRoUGFyYW1ldGVycygpIHRocm93cyBFeGNlcHRpb247CisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgdmFsaWRhdGVDZXJ0UGF0aChDZXJ0UGF0aCBwYXRoKTsKKworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aEJ1aWxkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2VydFBhdGhCdWlsZGVyIHBhdGhCdWlsZGVyID0gQ2VydFBhdGhCdWlsZGVyLmdldEluc3RhbmNlKAorICAgICAgICAgICAgICAgIGFsZ29yaXRobU5hbWUpOworCisgICAgICAgIENlcnRQYXRoQnVpbGRlclJlc3VsdCBidWlsZGVyUmVzdWx0ID0gcGF0aEJ1aWxkZXIuYnVpbGQocGFyYW1zKTsKKworICAgICAgICBDZXJ0UGF0aCBwYXRoID0gYnVpbGRlclJlc3VsdC5nZXRDZXJ0UGF0aCgpOworCisgICAgICAgIGFzc2VydE5vdE51bGwoImJ1aWx0IHBhdGggaXMgbnVsbCIsIHBhdGgpOworCisgICAgICAgIHZhbGlkYXRlQ2VydFBhdGgocGF0aCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0NlcnRQYXRoVmFsaWRhdG9yVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0NlcnRQYXRoVmFsaWRhdG9yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmViMmUxOTYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvQ2VydFBhdGhWYWxpZGF0b3JUZXN0LmphdmEKQEAgLTAsMCArMSw0OCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGg7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhWYWxpZGF0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoVmFsaWRhdG9yUmVzdWx0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGFic3RyYWN0IGNsYXNzIENlcnRQYXRoVmFsaWRhdG9yVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGFsZ29yaXRobU5hbWU7CisKKworICAgIHB1YmxpYyBDZXJ0UGF0aFZhbGlkYXRvclRlc3QoU3RyaW5nIGFsZ29yaXRobU5hbWUpIHsKKyAgICAgICAgdGhpcy5hbGdvcml0aG1OYW1lID0gYWxnb3JpdGhtTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYWJzdHJhY3QgQ2VydFBhdGhQYXJhbWV0ZXJzIGdldFBhcmFtcygpOworICAgIHB1YmxpYyBhYnN0cmFjdCBDZXJ0UGF0aCBnZXRDZXJ0UGF0aCgpOworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHZhbGlkYXRlUmVzdWx0KENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0IHZhbGlkYXRvclJlc3VsdCk7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhWYWxpZGF0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3IgY2VydFBhdGhWYWxpZGF0b3IgPSBDZXJ0UGF0aFZhbGlkYXRvci5nZXRJbnN0YW5jZSgKKyAgICAgICAgICAgICAgICBhbGdvcml0aG1OYW1lKTsKKworICAgICAgICBDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCB2YWxpZGF0b3JSZXN1bHQgPSBjZXJ0UGF0aFZhbGlkYXRvci52YWxpZGF0ZSgKKyAgICAgICAgICAgICAgICBnZXRDZXJ0UGF0aCgpLCBnZXRQYXJhbXMoKSk7CisKKyAgICAgICAgdmFsaWRhdGVSZXN1bHQodmFsaWRhdG9yUmVzdWx0KTsKKyAgICB9CisKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0NlcnRpZmljYXRlRmFjdG9yeVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9DZXJ0aWZpY2F0ZUZhY3RvcnlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2EyNjdhOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9DZXJ0aWZpY2F0ZUZhY3RvcnlUZXN0LmphdmEKQEAgLTAsMCArMSw0NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ2VydGlmaWNhdGVGYWN0b3J5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGFsZ29yaXRobU5hbWU7CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gY2VydGlmaWNhdGVEYXRhOworCisKKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVGYWN0b3J5VGVzdChTdHJpbmcgYWxnb3JpdGhtTmFtZSwgYnl0ZVtdIGNlcnRpZmljYXRlRGF0YSkgeworICAgICAgICB0aGlzLmFsZ29yaXRobU5hbWUgPSBhbGdvcml0aG1OYW1lOworICAgICAgICB0aGlzLmNlcnRpZmljYXRlRGF0YSA9IGNlcnRpZmljYXRlRGF0YTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUZhY3RvcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNlcnRpZmljYXRlRmFjdG9yeSA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgKKyAgICAgICAgICAgICAgICBhbGdvcml0aG1OYW1lKTsKKworICAgICAgICBDZXJ0aWZpY2F0ZSBjZXJ0aWZpY2F0ZSA9IGNlcnRpZmljYXRlRmFjdG9yeS5nZW5lcmF0ZUNlcnRpZmljYXRlKAorICAgICAgICAgICAgICAgIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShjZXJ0aWZpY2F0ZURhdGEpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjZXJ0aWZpY2F0ZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L1NlY3VyZVJhbmRvbVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9TZWN1cmVSYW5kb21UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmIwMzhlMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9TZWN1cmVSYW5kb21UZXN0LmphdmEKQEAgLTAsMCArMSw5NiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNhbGxhYmxlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yQ29tcGxldGlvblNlcnZpY2U7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JTZXJ2aWNlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yczsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTZWN1cmVSYW5kb21UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgYWxnb3JpdGhtTmFtZTsKKworICAgIHByaXZhdGUgaW50IGNvdW50ZXIgPSAwOworCisgICAgcHJvdGVjdGVkIFNlY3VyZVJhbmRvbVRlc3QoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgdGhpcy5hbGdvcml0aG1OYW1lID0gbmFtZTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZWN1cmVSYW5kb20oKSB7CisgICAgICAgIFNlY3VyZVJhbmRvbSBzZWN1cmVSYW5kb20xID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlY3VyZVJhbmRvbTEgPSBTZWN1cmVSYW5kb20uZ2V0SW5zdGFuY2UoYWxnb3JpdGhtTmFtZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIFNlY3VyZVJhbmRvbSBzZWN1cmVSYW5kb20yID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlY3VyZVJhbmRvbTIgPSBTZWN1cmVSYW5kb20uZ2V0SW5zdGFuY2UoYWxnb3JpdGhtTmFtZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGVbXSB0ZXN0UmFuZG9tMSA9IGdldFJhbmRvbUJ5dGVzKHNlY3VyZVJhbmRvbTEpOworICAgICAgICBieXRlW10gdGVzdFJhbmRvbTIgPSBnZXRSYW5kb21CeXRlcyhzZWN1cmVSYW5kb20yKTsKKworICAgICAgICBhc3NlcnRGYWxzZShBcnJheXMuZXF1YWxzKHRlc3RSYW5kb20xLCB0ZXN0UmFuZG9tMikpOworCisKKyAgICB9CisKKyAgICBwcml2YXRlIGJ5dGVbXSBnZXRSYW5kb21CeXRlcyhTZWN1cmVSYW5kb20gcmFuZG9tKSB7CisgICAgICAgIGJ5dGVbXSByYW5kb21EYXRhID0gbmV3IGJ5dGVbNjRdOworCisgICAgICAgIHJhbmRvbS5zZXRTZWVkKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpK2NvdW50ZXIpOworICAgICAgICBjb3VudGVyKys7CisKKyAgICAgICAgcmFuZG9tLm5leHRCeXRlcyhyYW5kb21EYXRhKTsKKworICAgICAgICByZXR1cm4gcmFuZG9tRGF0YTsKKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3RTZWN1cmVSYW5kb21UaHJlYWRTYWZldHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU2VjdXJlUmFuZG9tIHNlY3VyZVJhbmRvbSA9IFNlY3VyZVJhbmRvbS5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lKTsKKyAgICAgICAgaW50IHRocmVhZHMgPSAyOworICAgICAgICBFeGVjdXRvclNlcnZpY2UgZXhlY3V0b3IgPSBFeGVjdXRvcnMubmV3Rml4ZWRUaHJlYWRQb29sKHRocmVhZHMpOworICAgICAgICBFeGVjdXRvckNvbXBsZXRpb25TZXJ2aWNlIGVjcyA9IG5ldyBFeGVjdXRvckNvbXBsZXRpb25TZXJ2aWNlKGV4ZWN1dG9yKTsKKyAgICAgICAgZm9yIChpbnQgdCA9IDA7IHQgPCB0aHJlYWRzOyB0KyspIHsKKyAgICAgICAgICAgIGVjcy5zdWJtaXQobmV3IENhbGxhYmxlPFZvaWQ+KCkgeworICAgICAgICAgICAgICAgIHB1YmxpYyBWb2lkIGNhbGwgKCkgeworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDA7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgc2VjdXJlUmFuZG9tLmdlbmVyYXRlU2VlZCgxMDI0KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKyAgICAgICAgfQorICAgICAgICBleGVjdXRvci5zaHV0ZG93bigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRocmVhZHM7IGkrKykgeworICAgICAgICAgICAgZWNzLnRha2UoKS5nZXQoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9hY2wvQWNsTm90Rm91bmRFeGNlcHRpb24yVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2FjbC9BY2xOb3RGb3VuZEV4Y2VwdGlvbjJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDNiNzczNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9hY2wvQWNsTm90Rm91bmRFeGNlcHRpb24yVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDQgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmFjbDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuYWNsLkFjbE5vdEZvdW5kRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgQWNsTm90Rm91bmRFeGNlcHRpb24yVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuYWNsLkFjbE5vdEZvdW5kRXhjZXB0aW9uI0FjbE5vdEZvdW5kRXhjZXB0aW9uKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yKCkgeworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5zZWN1cml0eS5hY2wuQWNsTm90Rm91bmRFeGNlcHRpb24oKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKHRydWUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWNsTm90Rm91bmRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBBY2xOb3RGb3VuZEV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChBY2xOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkFjbE5vdEZvdW5kRXhjZXB0aW9uLnRvU3RyaW5nKCkgc2hvdWxkIGhhdmUgYmVlbiAiCisgICAgICAgICAgICAgICAgICAgICsgIidqYXZhLnNlY3VyaXR5LmFjbC5BY2xOb3RGb3VuZEV4Y2VwdGlvbicgYnV0IHdhcyAiCisgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpLAorICAgICAgICAgICAgICAgICAgICAiamF2YS5zZWN1cml0eS5hY2wuQWNsTm90Rm91bmRFeGNlcHRpb24iLAorICAgICAgICAgICAgICAgICAgICBlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2FjbC9BY2xOb3RGb3VuZEV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9hY2wvQWNsTm90Rm91bmRFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTRjMzg5ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9hY2wvQWNsTm90Rm91bmRFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxla3NlaSBZLiBTZW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuYWNsOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5hY2wuQWNsTm90Rm91bmRFeGNlcHRpb247CisKKy8qKgorICogVW5pdCB0ZXN0IGZvciBBY2xOb3RGb3VuZEV4Y2VwdGlvbi4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBBY2xOb3RGb3VuZEV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgLyoqCisgICAgICogY2hlY2sgZGVmYXVsdCBjb25zdHJ1Y3RvcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RBY2xOb3RGb3VuZEV4Y2VwdGlvbigpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXcgQWNsTm90Rm91bmRFeGNlcHRpb24oKSk7CisgICAgICAgIGFzc2VydE51bGwobmV3IEFjbE5vdEZvdW5kRXhjZXB0aW9uKCkuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChuZXcgQWNsTm90Rm91bmRFeGNlcHRpb24oKS5nZXRDYXVzZSgpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9hY2wvTGFzdE93bmVyRXhjZXB0aW9uMlRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9hY2wvTGFzdE93bmVyRXhjZXB0aW9uMlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YjdkOWExCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2FjbC9MYXN0T3duZXJFeGNlcHRpb24yVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmFjbDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuYWNsLkxhc3RPd25lckV4Y2VwdGlvbjsKKworcHVibGljIGNsYXNzIExhc3RPd25lckV4Y2VwdGlvbjJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5hY2wuTGFzdE93bmVyRXhjZXB0aW9uI0xhc3RPd25lckV4Y2VwdGlvbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEuc2VjdXJpdHkuYWNsLkxhc3RPd25lckV4Y2VwdGlvbigpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTGFzdE93bmVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0gY2F0Y2ggKExhc3RPd25lckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkxhc3RPd25lckV4Y2VwdGlvbi50b1N0cmluZygpIHNob3VsZCBoYXZlIGJlZW4gIgorICAgICAgICAgICAgICAgICAgICArICInamF2YS5zZWN1cml0eS5hY2wuTGFzdE93bmVyRXhjZXB0aW9uJyBidXQgd2FzICIKKyAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCksICJqYXZhLnNlY3VyaXR5LmFjbC5MYXN0T3duZXJFeGNlcHRpb24iLCBlCisgICAgICAgICAgICAgICAgICAgIC50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9hY2wvTGFzdE93bmVyRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2FjbC9MYXN0T3duZXJFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmNhY2EyMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9hY2wvTGFzdE93bmVyRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZWtzZWkgWS4gU2VtZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmFjbDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuYWNsLkxhc3RPd25lckV4Y2VwdGlvbjsKKworLyoqCisgKiBVbml0IHRlc3QgZm9yIExhc3RPd25lckV4Y2VwdGlvbi4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBMYXN0T3duZXJFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3RMYXN0T3duZXJFeGNlcHRpb24oKSB7CisgICAgICAgIGFzc2VydE5vdE51bGwobmV3IExhc3RPd25lckV4Y2VwdGlvbigpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChuZXcgTGFzdE93bmVyRXhjZXB0aW9uKCkuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChuZXcgTGFzdE93bmVyRXhjZXB0aW9uKCkuZ2V0Q2F1c2UoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvYWNsL05vdE93bmVyRXhjZXB0aW9uMlRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9hY2wvTm90T3duZXJFeGNlcHRpb24yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2MzJlYzcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvYWNsL05vdE93bmVyRXhjZXB0aW9uMlRlc3QuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5hY2w7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmFjbC5Ob3RPd25lckV4Y2VwdGlvbjsKKworcHVibGljIGNsYXNzIE5vdE93bmVyRXhjZXB0aW9uMlRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmFjbC5Ob3RPd25lckV4Y2VwdGlvbiNOb3RPd25lckV4Y2VwdGlvbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9Db25zdHJ1Y3RvcigpIHsKKyAgICAgICAgLy8gVGVzdCBmb3IgbWV0aG9kIGphdmEuc2VjdXJpdHkuYWNsLk5vdE93bmVyRXhjZXB0aW9uKCkKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb3RPd25lckV4Y2VwdGlvbigpOworICAgICAgICB9IGNhdGNoIChOb3RPd25lckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIk5vdE93bmVyRXhjZXB0aW9uLnRvU3RyaW5nKCkgc2hvdWxkIGhhdmUgYmVlbiAiCisgICAgICAgICAgICAgICAgICAgICsgIidqYXZhLnNlY3VyaXR5LmFjbC5Ob3RPd25lckV4Y2VwdGlvbicgYnV0IHdhcyAiCisgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpLCAiamF2YS5zZWN1cml0eS5hY2wuTm90T3duZXJFeGNlcHRpb24iLCBlCisgICAgICAgICAgICAgICAgICAgIC50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9hY2wvTm90T3duZXJFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvYWNsL05vdE93bmVyRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgwYjc4MjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvYWNsL05vdE93bmVyRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZWtzZWkgWS4gU2VtZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmFjbDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuYWNsLk5vdE93bmVyRXhjZXB0aW9uOworCisvKioKKyAqIFVuaXQgdGVzdCBmb3IgTm90T3duZXJFeGNlcHRpb24uCisgKgorICovCitwdWJsaWMgY2xhc3MgTm90T3duZXJFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIHB1YmxpYyB2b2lkIHRlc3ROb3RPd25lckV4Y2VwdGlvbigpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXcgTm90T3duZXJFeGNlcHRpb24oKSk7CisgICAgICAgIGFzc2VydE51bGwobmV3IE5vdE93bmVyRXhjZXB0aW9uKCkuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChuZXcgTm90T3duZXJFeGNlcHRpb24oKS5nZXRDYXVzZSgpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NSTEV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NSTEV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNTQyYTJhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ1JMRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTc0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DUkxFeGNlcHRpb247CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkNSTEV4Y2VwdGlvbjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIENSTEV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgVGhyb3dhYmxlIHRDYXVzZSA9IG5ldyBUaHJvd2FibGUoIlRocm93YWJsZSBmb3IgZXhjZXB0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DUkxFeGNlcHRpb24oKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzCisgICAgICogQ1JMRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q1JMRXhjZXB0aW9uMDEoKSB7CisgICAgICAgIENSTEV4Y2VwdGlvbiB0RSA9IG5ldyBDUkxFeGNlcHRpb24oKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q1JMRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yIEFzc2VydGlvbjoKKyAgICAgKiBjb25zdHJ1Y3RzIENSTEV4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4gUGFyYW1ldGVyCisgICAgICogPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q1JMRXhjZXB0aW9uMDIoKSB7CisgICAgICAgIENSTEV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBDUkxFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DUkxFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgQ1JMRXhjZXB0aW9uIHdoZW4gPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENSTEV4Y2VwdGlvbjAzKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICAgICAgQ1JMRXhjZXB0aW9uIHRFID0gbmV3IENSTEV4Y2VwdGlvbihtc2cpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DUkxFeGNlcHRpb24oVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgQ1JMRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q1JMRXhjZXB0aW9uMDQoKSB7CisgICAgICAgIFRocm93YWJsZSBjYXVzZSA9IG51bGw7CisgICAgICAgIENSTEV4Y2VwdGlvbiB0RSA9IG5ldyBDUkxFeGNlcHRpb24oY2F1c2UpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DUkxFeGNlcHRpb24oVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgQ1JMRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENSTEV4Y2VwdGlvbjA1KCkgeworICAgICAgICBDUkxFeGNlcHRpb24gdEUgPSBuZXcgQ1JMRXhjZXB0aW9uKHRDYXVzZSk7CisgICAgICAgIGlmICh0RS5nZXRNZXNzYWdlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgc2hvdWxkIGNvbnRhaW4gIi5jb25jYXQodG9TKSwgKGdldE0KKyAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwgdEUKKyAgICAgICAgICAgICAgICAuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DUkxFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDUkxFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbAorICAgICAqIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDUkxFeGNlcHRpb24wNigpIHsKKyAgICAgICAgQ1JMRXhjZXB0aW9uIHRFID0gbmV3IENSTEV4Y2VwdGlvbihudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DUkxFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDUkxFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbAorICAgICAqIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q1JMRXhjZXB0aW9uMDcoKSB7CisgICAgICAgIENSTEV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBDUkxFeGNlcHRpb24obXNnc1tpXSwgbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DUkxFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDUkxFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKiA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q1JMRXhjZXB0aW9uMDgoKSB7CisgICAgICAgIENSTEV4Y2VwdGlvbiB0RSA9IG5ldyBDUkxFeGNlcHRpb24obnVsbCwgdENhdXNlKTsKKyAgICAgICAgaWYgKHRFLmdldE1lc3NhZ2UoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IHNob3VsZCAiLmNvbmNhdCh0b1MpLCAoZ2V0TQorICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgIC5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNSTEV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENSTEV4Y2VwdGlvbiB3aGVuIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QgbnVsbAorICAgICAqIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q1JMRXhjZXB0aW9uMDkoKSB7CisgICAgICAgIENSTEV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBDUkxFeGNlcHRpb24obXNnc1tpXSwgdENhdXNlKTsKKyAgICAgICAgICAgIFN0cmluZyBnZXRNID0gdEUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgaWYgKG1zZ3NbaV0ubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIG11c3QgY29udGFpbiAiLmNvbmNhdChtc2dzW2ldKSwgZ2V0TQorICAgICAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YobXNnc1tpXSkgIT0gLTEpOworICAgICAgICAgICAgICAgIGlmICghZ2V0TS5lcXVhbHMobXNnc1tpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIHNob3VsZCBjb250YWluICIuY29uY2F0KHRvUyksIGdldE0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLAorICAgICAgICAgICAgICAgICAgICB0RS5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ1JMVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ1JMVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJlOGRkY2QKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DUkxUZXN0LmphdmEKQEAgLTAsMCArMSwxMjUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DUkw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuU3BpRW5nVXRpbHM7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPmphdmEuc2VjdXJpdHkuY2VydC5DUkw8L2NvZGU+IGZpZWxkcyBhbmQgbWV0aG9kcworICoKKyAqLworcHVibGljIGNsYXNzIENSTFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZ1tdIHZhbGlkVmFsdWVzID0geyAiWC41MDkiLCAieC41MDkiIH07CisKKyAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmdbXSBpbnZhbGlkVmFsdWVzID0gU3BpRW5nVXRpbHMuaW52YWxpZFZhbHVlczsKKworICAgIC8vCisgICAgLy8gVGVzdHMKKyAgICAvLworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q1JMKFN0cmluZyB0eXBlKTwvY29kZT4gY29uc3RydWN0b3I8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdENvbnN0cnVjdG9yKCkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaTwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIENSTCBjcmwgPSBuZXcgTXlDUkwodmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHZhbGlkVmFsdWVzW2ldLCBjcmwuZ2V0VHlwZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBDUkwgY3JsID0gbmV3IE15Q1JMKGludmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGludmFsaWRWYWx1ZXNbaV0sIGNybC5nZXRUeXBlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENSTCBjcmwgPSBuZXcgTXlDUkwobnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiBmb3IgTlVMTCBwYXJhbWV0ZXIiKTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+Z2V0VHlwZSgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIDxjb2RlPkNSTDwvY29kZT4gdHlwZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRUeXBlMDEoKSB7CisgICAgICAgIENSTCBjcmwgPSBuZXcgTXlDUkwoIlRFU1RfVFlQRSIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRFU1RfVFlQRSIsIGNybC5nZXRUeXBlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPmdldFR5cGUoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyA8Y29kZT5DUkw8L2NvZGU+IHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0VHlwZTAyKCkgeworICAgICAgICBDUkwgY3JsID0gbmV3IE15Q1JMKG51bGwpOworICAgICAgICBhc3NlcnROdWxsKGNybC5nZXRUeXBlKCkpOworICAgIH0KKworICAgIC8vCisgICAgLy8gdGhlIGZvbGxvd2luZyB0ZXN0cyBqdXN0IGNhbGwgbWV0aG9kcworICAgIC8vIHRoYXQgYXJlIGFic3RyYWN0IGluIDxjb2RlPkNlcnRpZmljYXRlPC9jb2RlPgorICAgIC8vIChTbyB0aGV5IGp1c3QgbGlrZSBzaWduYXR1cmUgdGVzdHMpCisgICAgLy8KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnRvU3RyaW5nKCk8L2NvZGU+IG1ldGhvZAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RUb1N0cmluZygpIHsKKyAgICAgICAgQ1JMIGNybCA9IG5ldyBNeUNSTCgiVEVTVF9UWVBFIik7CisgICAgICAgIGNybC50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmlzUmV2b2tlZCgpPC9jb2RlPiBtZXRob2QKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0SXNSZXZva2VkKCkgeworICAgICAgICBDUkwgY3JsID0gbmV3IE15Q1JMKCJURVNUX1RZUEUiKTsKKyAgICAgICAgY3JsLmlzUmV2b2tlZChudWxsKTsKKyAgICB9CisKKyAgICBjbGFzcyBNeUNSTCBleHRlbmRzIENSTCB7CisKKyAgICAgICAgcHJvdGVjdGVkIE15Q1JMKFN0cmluZyB0eXBlKSB7CisgICAgICAgICAgICBzdXBlcih0eXBlKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1Jldm9rZWQoQ2VydGlmaWNhdGUgY2VydCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhCdWlsZGVyMVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoQnVpbGRlcjFUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWFlMDIxYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoQnVpbGRlcjFUZXN0LmphdmEKQEAgLTAsMCArMSw0NzUgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uS25vd25GYWlsdXJlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuU3BpRW5nVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5NeUNlcnRQYXRoQnVpbGRlclNwaTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0LlRlc3RVdGlsczsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGg7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoQnVpbGRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aEJ1aWxkZXJSZXN1bHQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoQnVpbGRlclNwaTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhQYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+Q2VydFBhdGhCdWlsZGVyPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kCisgKiBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIENlcnRQYXRoQnVpbGRlcjFUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgc3J2Q2VydFBhdGhCdWlsZGVyID0gIkNlcnRQYXRoQnVpbGRlciI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBkZWZhdWx0VHlwZSA9ICJQS0lYIjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBbXSB2YWxpZFZhbHVlcyA9IHsKKyAgICAgICAgICAgICJQS0lYIiwgInBraXgiLCAiUGtpWCIsICJwS2lYIiB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIFtdIGludmFsaWRWYWx1ZXMgPSBTcGlFbmdVdGlscy5pbnZhbGlkVmFsdWVzOworCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBQS0lYU3VwcG9ydCA9IGZhbHNlOworCisgICAgcHJpdmF0ZSBzdGF0aWMgUHJvdmlkZXIgZGVmYXVsdFByb3ZpZGVyOworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZWZhdWx0UHJvdmlkZXJOYW1lOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIE5vdFN1cHBvcnRNc2cgPSAiIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfVFlQRV9QUk9QRVJUWSA9ICJjZXJ0cGF0aGJ1aWxkZXIudHlwZSI7CisKKyAgICBzdGF0aWMgeworICAgICAgICBkZWZhdWx0UHJvdmlkZXIgPSBTcGlFbmdVdGlscy5pc1N1cHBvcnQoZGVmYXVsdFR5cGUsCisgICAgICAgICAgICAgICAgc3J2Q2VydFBhdGhCdWlsZGVyKTsKKyAgICAgICAgUEtJWFN1cHBvcnQgPSAoZGVmYXVsdFByb3ZpZGVyICE9IG51bGwpOworICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lID0gKFBLSVhTdXBwb3J0ID8gZGVmYXVsdFByb3ZpZGVyLmdldE5hbWUoKSA6IG51bGwpOworICAgICAgICBOb3RTdXBwb3J0TXNnID0gZGVmYXVsdFR5cGUuY29uY2F0KCIgaXMgbm90IHN1cHBvcnRlZCIpOworICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBDZXJ0UGF0aEJ1aWxkZXJbXSBjcmVhdGVDUEJzKCkgeworICAgICAgICBpZiAoIVBLSVhTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRQYXRoQnVpbGRlcltdIGNlcnRQQnMgPSBuZXcgQ2VydFBhdGhCdWlsZGVyWzNdOworICAgICAgICAgICAgY2VydFBCc1swXSA9IENlcnRQYXRoQnVpbGRlci5nZXRJbnN0YW5jZShkZWZhdWx0VHlwZSk7CisgICAgICAgICAgICBjZXJ0UEJzWzFdID0gQ2VydFBhdGhCdWlsZGVyLmdldEluc3RhbmNlKGRlZmF1bHRUeXBlLAorICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgIGNlcnRQQnNbMl0gPSBDZXJ0UGF0aEJ1aWxkZXIuZ2V0SW5zdGFuY2UoZGVmYXVsdFR5cGUsCisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgICAgICByZXR1cm4gY2VydFBCczsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoQnVpbGRlciNnZXREZWZhdWx0VHlwZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXREZWZhdWx0VHlwZSgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMjc4NQorCisgICAgICAgIC8vIHRlc3Q6IGRlZmF1bHQgdmFsdWUKKyAgICAgICAgYXNzZXJ0TnVsbChTZWN1cml0eS5nZXRQcm9wZXJ0eShERUZBVUxUX1RZUEVfUFJPUEVSVFkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJQS0lYIiwgQ2VydFBhdGhCdWlsZGVyLmdldERlZmF1bHRUeXBlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtICBpcyBub3QgY29ycmVjdAorICAgICAqIG9yIGl0IGlzIG5vdCBhdmFpbGFibGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhCdWlsZGVyMDIoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRQYXRoQnVpbGRlci5nZXRJbnN0YW5jZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydFBhdGhCdWlsZGVyLmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0pPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgQ2VydFBhdGhCdWlsZGVyIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aEJ1aWxkZXIwMygpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gIHsKKyAgICAgICAgaWYgKCFQS0lYU3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBDZXJ0UGF0aEJ1aWxkZXIgY3BiID0gQ2VydFBhdGhCdWlsZGVyLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGNwYi5nZXRBbGdvcml0aG0oKSwgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICB9CisgICAgfQorICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcik8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aGVuIHByb3ZpZGVyIGlzIG51bGwgb3IgZW1wdHkKKyAgICAgKgorICAgICAqIEZJWE1FOiB2ZXJpZnkgd2hhdCBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24gaWYgcHJvdmlkZXIgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhCdWlsZGVyMDQoKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gIHsKKyAgICAgICAgaWYgKCFQS0lYU3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcHJvdmlkZXIgPSBudWxsOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRQYXRoQnVpbGRlci5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgcHJvdmlkZXIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRQYXRoQnVpbGRlci5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgIiIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaGFzIGludmFsaWQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhCdWlsZGVyMDUoKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiAgeworICAgICAgICBpZiAoIVBLSVhTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKysgKSB7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMTsgaiA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBDZXJ0UGF0aEJ1aWxkZXIuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIGludmFsaWRWYWx1ZXNbal0pOworICAgICAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBtdXN0IGJlIGhyb3duIik7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZTEpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOgorICAgICAqIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBudWxsCisgICAgICogdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSAgaXMgbm90IGNvcnJlY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhCdWlsZGVyMDYoKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gIHsKKyAgICAgICAgaWYgKCFQS0lYU3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydFBhdGhCdWlsZGVyLmdldEluc3RhbmNlKG51bGwsIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDZXJ0UGF0aEJ1aWxkZXIuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwgZGVmYXVsdFByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZTEpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcik8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBDZXJ0UGF0aEJ1aWxkZXIgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoQnVpbGRlcjA3KCkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uICB7CisgICAgICAgIGlmICghUEtJWFN1cHBvcnQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgQ2VydFBhdGhCdWlsZGVyIGNlcnRQQjsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgY2VydFBCID0gQ2VydFBhdGhCdWlsZGVyLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGNlcnRQQi5nZXRBbGdvcml0aG0oKSwgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIgbmFtZSIsIGNlcnRQQi5nZXRQcm92aWRlcigpLmdldE5hbWUoKSwgZGVmYXVsdFByb3ZpZGVyTmFtZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBQcm92aWRlciBwcm92aWRlcik8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aGVuIHByb3ZpZGVyIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhCdWlsZGVyMDgoKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiAgeworICAgICAgICBpZiAoIVBLSVhTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFByb3ZpZGVyIHByb3YgPSBudWxsOworICAgICAgICBmb3IgKGludCB0ID0gMDsgdCA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgdCsrICkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDZXJ0UGF0aEJ1aWxkZXIuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbdF0sIHByb3YpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUxKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtICBpcyBub3QgY29ycmVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aEJ1aWxkZXIwOSgpCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiAgeworICAgICAgICBpZiAoIVBLSVhTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0UGF0aEJ1aWxkZXIuZ2V0SW5zdGFuY2UobnVsbCwgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgIGZhaWwoIk5vIGV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydFBhdGhCdWlsZGVyLmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0sIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZTEpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgQ2VydFBhdGhCdWlsZGVyIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aEJ1aWxkZXIxMCgpCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiAgeworICAgICAgICBpZiAoIVBLSVhTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIENlcnRQYXRoQnVpbGRlciBjZXJ0UEI7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgY2VydFBCID0gQ2VydFBhdGhCdWlsZGVyLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwgY2VydFBCLmdldEFsZ29yaXRobSgpLCB2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciBuYW1lIiwgY2VydFBCLmdldFByb3ZpZGVyKCksIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgIH0KKyAgICB9CisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+YnVpbGQoQ2VydFBhdGhQYXJhbWV0ZXJzIHBhcmFtcyk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gcGFyYW1zIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhCdWlsZGVyMTEoKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICBDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24geworICAgICAgICBpZiAoIVBLSVhTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIENlcnRQYXRoQnVpbGRlciBbXSBjZXJ0UEIgPSBjcmVhdGVDUEJzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkNlcnRQYXRoQnVpbGRlciBvYmplY3RzIHdlcmUgbm90IGNyZWF0ZWQiLCBjZXJ0UEIpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNlcnRQQi5sZW5ndGg7IGkrKyApeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjZXJ0UEJbaV0uYnVpbGQobnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIFRlc3QgcGFzc2VkIG9uIFJJCisgICAgQEtub3duRmFpbHVyZSh2YWx1ZT0iZXhwaXJlZCBjZXJ0aWZpY2F0ZSBidWcgMjMyMjY2MiIpCisgICAgcHVibGljIHZvaWQgdGVzdEJ1aWxkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RVdGlscy5pbml0Q2VydFBhdGhTU0NlcnRDaGFpbigpOworICAgICAgICBDZXJ0UGF0aFBhcmFtZXRlcnMgcGFyYW1zID0gVGVzdFV0aWxzLmdldENlcnRQYXRoUGFyYW1ldGVycygpOworICAgICAgICBDZXJ0UGF0aEJ1aWxkZXIgYnVpbGRlciA9IFRlc3RVdGlscy5nZXRDZXJ0UGF0aEJ1aWxkZXIoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydFBhdGhCdWlsZGVyUmVzdWx0IHJlc3VsdCA9IGJ1aWxkZXIuYnVpbGQocGFyYW1zKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoImJ1aWxkZXIgcmVzdWx0IGlzIG51bGwiLCByZXN1bHQpOworICAgICAgICAgICAgQ2VydFBhdGggY2VydFBhdGggPSByZXN1bHQuZ2V0Q2VydFBhdGgoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoImNlcnRwYXRoIG9mIGJ1aWxkZXIgcmVzdWx0IGlzIG51bGwiLCBjZXJ0UGF0aCk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBFeGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgfQorICAgIC8qKgorICAgICAqIFRlc3QgZm9yCisgICAgICogPGNvZGU+Q2VydFBhdGhCdWlsZGVyPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBDZXJ0UGF0aEJ1aWxkZXIgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoQnVpbGRlcjEyKCkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24sCisgICAgICAgICAgICBDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24geworICAgICAgICBpZiAoIVBLSVhTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIENlcnRQYXRoQnVpbGRlclNwaSBzcGkgPSBuZXcgTXlDZXJ0UGF0aEJ1aWxkZXJTcGkoKTsKKyAgICAgICAgQ2VydFBhdGhCdWlsZGVyIGNlcnRQQiA9IG5ldyBteUNlcnRQYXRoQnVpbGRlcihzcGksCisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlciwgZGVmYXVsdFR5cGUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBjZXJ0UEIuZ2V0QWxnb3JpdGhtKCksIGRlZmF1bHRUeXBlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBjZXJ0UEIuZ2V0UHJvdmlkZXIoKSwgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRQQi5idWlsZChudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkNlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBjZXJ0UEIgPSBuZXcgbXlDZXJ0UGF0aEJ1aWxkZXIobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCBhbGdvcml0aG0iLCBjZXJ0UEIuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICBhc3NlcnROdWxsKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBjZXJ0UEIuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0UEIuYnVpbGQobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0QWxnb3JpdGhtKCk8L2NvZGU+IG1ldGhvZCBBc3NlcnRpb246IHJldHVybnMKKyAgICAgKiBDZXJ0UGF0aEJ1aWxkZXIgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoQnVpbGRlcjEzKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghUEtJWFN1cHBvcnQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBDZXJ0UGF0aEJ1aWxkZXIgY3BiID0gQ2VydFBhdGhCdWlsZGVyLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGNwYi5nZXRBbGdvcml0aG0oKSwKKyAgICAgICAgICAgICAgICAgICAgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjcGIgPSBDZXJ0UGF0aEJ1aWxkZXIuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBjcGIuZ2V0QWxnb3JpdGhtKCksCisgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBleGVwdGlvbiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjcGIgPSBDZXJ0UGF0aEJ1aWxkZXIuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBjcGIuZ2V0QWxnb3JpdGhtKCksCisgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UHJvdmlkZXIoKTwvY29kZT4gbWV0aG9kIEFzc2VydGlvbjogcmV0dXJucworICAgICAqIENlcnRQYXRoQnVpbGRlciBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhCdWlsZGVyMTQoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFQS0lYU3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIENlcnRQYXRoQnVpbGRlciBjcGIyID0gQ2VydFBhdGhCdWlsZGVyLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLAorICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBjcGIyLmdldFByb3ZpZGVyKCksCisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlcik7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydFBhdGhCdWlsZGVyIGNwYjMgPSBDZXJ0UGF0aEJ1aWxkZXIuZ2V0SW5zdGFuY2UoCisgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1tpXSwgZGVmYXVsdFByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBjcGIzLmdldFByb3ZpZGVyKCksCisgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgfQorfQorLyoqCisgKiBBZGRpdGlvbmFsIGNsYXNzIHRvIHZlcmlmeSBDZXJ0UGF0aEJ1aWxkZXIgY29uc3RydWN0b3IKKyAqLworY2xhc3MgbXlDZXJ0UGF0aEJ1aWxkZXIgZXh0ZW5kcyBDZXJ0UGF0aEJ1aWxkZXIgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgUHJvdmlkZXIgcHJvdmlkZXI7CisKKyAgICBwdWJsaWMgbXlDZXJ0UGF0aEJ1aWxkZXIoQ2VydFBhdGhCdWlsZGVyU3BpIHNwaSwgUHJvdmlkZXIgcHJvdiwgU3RyaW5nIHR5cGUpIHsKKyAgICAgICAgc3VwZXIoc3BpLCBwcm92LCB0eXBlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIENlcnRQYXRoQnVpbGRlciBnZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIG15Q2VydFBhdGhCdWlsZGVyIG1jcGIgPSBuZXcgbXlDZXJ0UGF0aEJ1aWxkZXIobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgIHByb3ZpZGVyID0gbWNwYi5uZXcgTXlQcm92aWRlcigpOworICAgICAgICByZXR1cm4gQ2VydFBhdGhCdWlsZGVyLmdldEluc3RhbmNlKGFsZ29yaXRobSk7CisgICAgfQorCisgICAgcHVibGljIFByb3ZpZGVyIGdldE15UHJvdmlkZXIoKSB7CisgICAgICAgIHJldHVybiBwcm92aWRlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgTXlQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjUzNzQ0NzkwNTY1ODE5MTE4NEw7CisKKyAgICAgICAgTXlQcm92aWRlcigpIHsKKyAgICAgICAgICAgIHN1cGVyKCJNeVByb3ZpZGVyIiwgMS4wLCAiUHJvdmlkZXIgZm9yIHRlc3RpbmciKTsKKyAgICAgICAgfQorCisgICAgICAgIE15UHJvdmlkZXIoU3RyaW5nIG5hbWUsIGRvdWJsZSB2ZXJzaW9uLCBTdHJpbmcgaW5mbykgeworICAgICAgICAgICAgc3VwZXIobmFtZSwgdmVyc2lvbiwgaW5mbyk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBwdXRTZXJ2aWNlKFByb3ZpZGVyLlNlcnZpY2UgcykgeworICAgICAgICAgICAgc3VwZXIucHV0U2VydmljZShzKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZVNlcnZpY2UoUHJvdmlkZXIuU2VydmljZSBzKSB7CisgICAgICAgICAgICBzdXBlci5yZW1vdmVTZXJ2aWNlKHMpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aEJ1aWxkZXIyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhCdWlsZGVyMlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZmM1ZDA4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhCdWlsZGVyMlRlc3QuamF2YQpAQCAtMCwwICsxLDI0NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCB0ZXN0cy5zZWN1cml0eS5jZXJ0Lm15Q2VydFBhdGhCdWlsZGVyLk15UHJvdmlkZXI7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoQnVpbGRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aEJ1aWxkZXJSZXN1bHQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5TcGlFbmdVdGlsczsKKy8qKgorICogVGVzdHMgZm9yIENlcnRQYXRoQnVpbGRlciBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBDZXJ0UGF0aEJ1aWxkZXIyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZGVmYXVsdEFsZyA9ICJDZXJ0UEIiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDZXJ0UGF0aEJ1aWxkZXJQcm92aWRlckNsYXNzID0gIm9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuTXlDZXJ0UGF0aEJ1aWxkZXJTcGkiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gaW52YWxpZFZhbHVlcyA9IFNwaUVuZ1V0aWxzLmludmFsaWRWYWx1ZXM7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSB2YWxpZFZhbHVlczsKKworICAgIHN0YXRpYyB7CisgICAgICAgIHZhbGlkVmFsdWVzID0gbmV3IFN0cmluZ1s0XTsKKyAgICAgICAgdmFsaWRWYWx1ZXNbMF0gPSBkZWZhdWx0QWxnOworICAgICAgICB2YWxpZFZhbHVlc1sxXSA9IGRlZmF1bHRBbGcudG9Mb3dlckNhc2UoKTsKKyAgICAgICAgdmFsaWRWYWx1ZXNbMl0gPSAiQ2VSdFBiIjsKKyAgICAgICAgdmFsaWRWYWx1ZXNbM10gPSAiY0VSVHBiIjsKKyAgICB9CisKKyAgICBQcm92aWRlciBtUHJvdjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIG1Qcm92ID0gKG5ldyBTcGlFbmdVdGlscygpKS5uZXcgTXlQcm92aWRlcigiTXlDZXJ0UGF0aEJ1aWxkZXJQcm92aWRlciIsCisgICAgICAgICAgICAgICAgIlByb3ZpZGVyIGZvciB0ZXN0aW5nIiwgQ2VydFBhdGhCdWlsZGVyMVRlc3Quc3J2Q2VydFBhdGhCdWlsZGVyCisgICAgICAgICAgICAgICAgICAgICAgICArICIuIiArIGRlZmF1bHRBbGcsCisKKyAgICAgICAgICAgICAgICBDZXJ0UGF0aEJ1aWxkZXJQcm92aWRlckNsYXNzKTsKKyAgICAgICAgU2VjdXJpdHkuaW5zZXJ0UHJvdmlkZXJBdChtUHJvdiwgMSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAc2VlIFRlc3RDYXNlI3RlYXJEb3duKCkKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcihtUHJvdi5nZXROYW1lKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja1Jlc3VsdChDZXJ0UGF0aEJ1aWxkZXIgY2VydEJ1aWxkKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24sCisgICAgICAgICAgICBDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgZHQgPSBDZXJ0UGF0aEJ1aWxkZXIuZ2V0RGVmYXVsdFR5cGUoKTsKKyAgICAgICAgU3RyaW5nIHByb3BOYW1lID0gQ2VydFBhdGhCdWlsZGVyMVRlc3QuREVGQVVMVF9UWVBFX1BST1BFUlRZOworICAgICAgICBTdHJpbmcgZHROOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8aW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU2VjdXJpdHkuc2V0UHJvcGVydHkocHJvcE5hbWUsIGludmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgZHROID0gQ2VydFBhdGhCdWlsZGVyLmdldERlZmF1bHRUeXBlKCk7CisgICAgICAgICAgICBpZiAoIWR0Ti5lcXVhbHMoaW52YWxpZFZhbHVlc1tpXSkgJiYgIWR0Ti5lcXVhbHMoZHQpKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiSW5jb3JyZWN0IGRlZmF1bHQgdHlwZTogIi5jb25jYXQoZHROKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgU2VjdXJpdHkuc2V0UHJvcGVydHkocHJvcE5hbWUsIGR0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgZGVmYXVsdCB0eXBlIiwgQ2VydFBhdGhCdWlsZGVyLmdldERlZmF1bHRUeXBlKCksCisgICAgICAgICAgICAgICAgZHQpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEJ1aWxkLmJ1aWxkKG51bGwpOworICAgICAgICAgICAgZmFpbCgiQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgQ2VydFBhdGhCdWlsZGVyUmVzdWx0IGNwYlJlc3VsdCA9IGNlcnRCdWlsZC5idWlsZChudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiTm90IG51bGwgQ2VydFBhdGhCdWlsZGVyUmVzdWx0IiwgY3BiUmVzdWx0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uczoKKyAgICAgKiB0aHJvd3MKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gaXMgbnVsbAorICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiBhbGdvcml0aG0gIGlzIG5vdCBjb3JyZWN0CisgICAgICogcmV0dXJucyBDZXJ0UGF0aEJ1aWxkZXIgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlMDEoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiwgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRQYXRoQnVpbGRlci5nZXRJbnN0YW5jZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydFBhdGhCdWlsZGVyLmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAodHlwZTogIi5jb25jYXQoCisgICAgICAgICAgICAgICAgICAgICAgICBpbnZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIENlcnRQYXRoQnVpbGRlciBjZXJQQjsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgY2VyUEIgPSBDZXJ0UGF0aEJ1aWxkZXIuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdHlwZSIsIGNlclBCLmdldEFsZ29yaXRobSgpLCB2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsIGNlclBCLmdldFByb3ZpZGVyKCksIG1Qcm92KTsKKyAgICAgICAgICAgIGNoZWNrUmVzdWx0KGNlclBCKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcik8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbnM6CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtICBpcyBub3QgY29ycmVjdAorICAgICAqIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBudWxsIG9yIGVtcHR5OworICAgICAqIHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB3aGVuIHByb3ZpZGVyIGlzIGF2YWlsYWJsZTsKKyAgICAgKiByZXR1cm5zIENlcnRQYXRoQnVpbGRlciBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2UwMigpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiwgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRQYXRoQnVpbGRlci5nZXRJbnN0YW5jZShudWxsLCBtUHJvdi5nZXROYW1lKCkpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDZXJ0UGF0aEJ1aWxkZXIuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwgbVByb3YKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAodHlwZTogIi5jb25jYXQoCisgICAgICAgICAgICAgICAgICAgICAgICBpbnZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFN0cmluZyBwcm92ID0gbnVsbDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDZXJ0UGF0aEJ1aWxkZXIuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIHByb3YpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHByb3ZpZGVyIGlzIG51bGwgKHR5cGU6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQodmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRQYXRoQnVpbGRlci5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgIiIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHByb3ZpZGVyIGlzIGVtcHR5ICh0eXBlOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KHZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSAxOyBqIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIENlcnRQYXRoQnVpbGRlci5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnZhbGlkVmFsdWVzW2pdKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gKHR5cGU6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KHZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIiBwcm92aWRlcjogIikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbal0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIENlcnRQYXRoQnVpbGRlciBjZXJQQjsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgY2VyUEIgPSBDZXJ0UGF0aEJ1aWxkZXIuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIG1Qcm92CisgICAgICAgICAgICAgICAgICAgIC5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdHlwZSIsIGNlclBCLmdldEFsZ29yaXRobSgpLCB2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsIGNlclBCLmdldFByb3ZpZGVyKCkuZ2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICBtUHJvdi5nZXROYW1lKCkpOworICAgICAgICAgICAgY2hlY2tSZXN1bHQoY2VyUEIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgUHJvdmlkZXIgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbnM6CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtICBpcyBub3QgY29ycmVjdAorICAgICAqIHJldHVybnMgQ2VydFBhdGhCdWlsZGVyIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZTAzKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24sIENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0UGF0aEJ1aWxkZXIuZ2V0SW5zdGFuY2UobnVsbCwgbVByb3YpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDZXJ0UGF0aEJ1aWxkZXIuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwgbVByb3YpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAodHlwZTogIi5jb25jYXQoCisgICAgICAgICAgICAgICAgICAgICAgICBpbnZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFByb3ZpZGVyIHByb3YgPSBudWxsOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRQYXRoQnVpbGRlci5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgcHJvdik7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gcHJvdmlkZXIgaXMgbnVsbCAodHlwZTogIgorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdCh2YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBDZXJ0UGF0aEJ1aWxkZXIgY2VyUEI7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNlclBCID0gQ2VydFBhdGhCdWlsZGVyLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBtUHJvdik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB0eXBlIiwgY2VyUEIuZ2V0QWxnb3JpdGhtKCksIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwgY2VyUEIuZ2V0UHJvdmlkZXIoKSwgbVByb3YpOworICAgICAgICAgICAgY2hlY2tSZXN1bHQoY2VyUEIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYxNjk0ZGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSwxNzkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbjsKKworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5DZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb248L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQKKyAqIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIG1zZ3MgPSB7CisgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UiIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBUaHJvd2FibGUgdENhdXNlID0gbmV3IFRocm93YWJsZSgiVGhyb3dhYmxlIGZvciBleGNlcHRpb24iKTsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbigpPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246CisgICAgICogY29uc3RydWN0cyBDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24wMSgpIHsKKyAgICAgICAgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uIHRFID0gbmV3IENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbigpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uIHdpdGggZGV0YWlsIG1lc3NhZ2UgbXNnLgorICAgICAqIFBhcmFtZXRlciA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24wMigpIHsKKyAgICAgICAgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbihtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24gd2hlbiA8Y29kZT5tc2c8L2NvZGU+IGlzCisgICAgICogbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24wMygpIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9IG51bGw7CisgICAgICAgIENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24obXNnKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uKFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbiB3aGVuIDxjb2RlPmNhdXNlPC9jb2RlPgorICAgICAqIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uMDQoKSB7CisgICAgICAgIFRocm93YWJsZSBjYXVzZSA9IG51bGw7CisgICAgICAgIENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24oY2F1c2UpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24oVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+CisgICAgICogaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uMDUoKSB7CisgICAgICAgIENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24odENhdXNlKTsKKyAgICAgICAgaWYgKHRFLmdldE1lc3NhZ2UoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBzaG91bGQgY29udGFpbiAiLmNvbmNhdCh0b1MpLCAoZ2V0TQorICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgIC5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbjA2KCkgeworICAgICAgICBDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24gdEUgPSBuZXcgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uKG51bGwsIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24wNygpIHsKKyAgICAgICAgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbihtc2dzW2ldLCBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdCBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24wOCgpIHsKKyAgICAgICAgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uIHRFID0gbmV3IENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbihudWxsLCB0Q2F1c2UpOworICAgICAgICBpZiAodEUuZ2V0TWVzc2FnZSgpICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIFN0cmluZyBnZXRNID0gdEUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIG11c3Qgc2hvdWxkICIuY29uY2F0KHRvUyksIChnZXRNCisgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKHRvUykgIT0gLTEpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiAiLmNvbmNhdCh0Q2F1c2UudG9TdHJpbmcoKSksIHRFCisgICAgICAgICAgICAgICAgLmdldENhdXNlKCksIHRDYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uIHdoZW4KKyAgICAgKiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90IG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24wOSgpIHsKKyAgICAgICAgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbihtc2dzW2ldLCB0Q2F1c2UpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBpZiAobXNnc1tpXS5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgbXVzdCBjb250YWluICIuY29uY2F0KG1zZ3NbaV0pLCBnZXRNCisgICAgICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZihtc2dzW2ldKSAhPSAtMSk7CisgICAgICAgICAgICAgICAgaWYgKCFnZXRNLmVxdWFscyhtc2dzW2ldKSkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgc2hvdWxkIGNvbnRhaW4gIi5jb25jYXQodG9TKSwgZ2V0TQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKHRvUykgIT0gLTEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiAiLmNvbmNhdCh0Q2F1c2UudG9TdHJpbmcoKSksCisgICAgICAgICAgICAgICAgICAgIHRFLmdldENhdXNlKCksIHRDYXVzZSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aEJ1aWxkZXJTcGlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aEJ1aWxkZXJTcGlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjU2MTVjYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoQnVpbGRlclNwaVRlc3QuamF2YQpAQCAtMCwwICsxLDU3IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aEJ1aWxkZXJSZXN1bHQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoQnVpbGRlclNwaTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhQYXJhbWV0ZXJzOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5NeUNlcnRQYXRoQnVpbGRlclNwaTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+Q2VydFBhdGhCdWlsZGVyU3BpPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgQ2VydFBhdGhCdWlsZGVyU3BpVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRQYXRoQnVpbGRlclNwaTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgQ2VydFBhdGhCdWlsZGVyU3BpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoQnVpbGRlclNwaTAxKCkgdGhyb3dzIENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBDZXJ0UGF0aEJ1aWxkZXJTcGkgY2VydFBhdGhCdWlsZGVyID0gbmV3IE15Q2VydFBhdGhCdWlsZGVyU3BpKCk7CisgICAgICAgIENlcnRQYXRoUGFyYW1ldGVycyBjcHAgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydFBhdGhCdWlsZGVyLmVuZ2luZUJ1aWxkKGNwcCk7CisgICAgICAgICAgICBmYWlsKCJDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQgY3BiUmVzdWx0ID0gY2VydFBhdGhCdWlsZGVyLmVuZ2luZUJ1aWxkKGNwcCk7CisgICAgICAgIGFzc2VydE51bGwoIk5vdCBudWxsIENlcnRQYXRoQnVpbGRlclJlc3VsdCIsIGNwYlJlc3VsdCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhDZXJ0UGF0aFJlcFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoQ2VydFBhdGhSZXBUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGRhYzhjMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoQ2VydFBhdGhSZXBUZXN0LmphdmEKQEAgLTAsMCArMSw2MiBAQAorcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5NeUNlcnRQYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuTXlDZXJ0UGF0aC5NeUNlcnRQYXRoUmVwOworCitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoOworCitwdWJsaWMgY2xhc3MgQ2VydFBhdGhDZXJ0UGF0aFJlcFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gdGVzdEVuY29kaW5nID0gbmV3IGJ5dGVbXSB7IChieXRlKSAxLCAoYnl0ZSkgMiwKKyAgICAgICAgICAgIChieXRlKSAzLCAoYnl0ZSkgNCwgKGJ5dGUpIDUgfTsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0UGF0aC5DZXJ0UGF0aFJlcChTdHJpbmcgdHlwZSwgYnl0ZVtdIGRhdGEpPC9jb2RlPgorICAgICAqIG1ldGhvZDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0Q2VydFBhdGhDZXJ0UGF0aFJlcCgpIHsKKyAgICAgICAgTXlDZXJ0UGF0aCBjcCA9IG5ldyBNeUNlcnRQYXRoKHRlc3RFbmNvZGluZyk7CisgICAgICAgIE15Q2VydFBhdGhSZXAgcmVwID0gY3AubmV3IE15Q2VydFBhdGhSZXAoIk15RW5jb2RpbmciLCB0ZXN0RW5jb2RpbmcpOworICAgICAgICBhc3NlcnRFcXVhbHModGVzdEVuY29kaW5nLCByZXAuZ2V0RGF0YSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJNeUVuY29kaW5nIiwgcmVwLmdldFR5cGUoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNwLm5ldyBNeUNlcnRQYXRoUmVwKG51bGwsIG51bGwpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGVwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UmVhZFJlc29sdmUoKSB7CisgICAgICAgIE15Q2VydFBhdGggY3AgPSBuZXcgTXlDZXJ0UGF0aCh0ZXN0RW5jb2RpbmcpOworICAgICAgICBNeUNlcnRQYXRoUmVwIHJlcCA9IGNwLm5ldyBNeUNlcnRQYXRoUmVwKCJNeUVuY29kaW5nIiwgdGVzdEVuY29kaW5nKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgT2JqZWN0IG9iaiA9IHJlcC5yZWFkUmVzb2x2ZSgpOworICAgICAgICAgICAgZmFpbCgiT2JqZWN0U3RyZWFtRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChPYmplY3RTdHJlYW1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgcmVwID0gY3AubmV3IE15Q2VydFBhdGhSZXAoIk15RW5jb2RpbmciLCBuZXcgYnl0ZVtdIHsoYnl0ZSkgMSwgKGJ5dGUpIDIsIChieXRlKSAzIH0pOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVwLnJlYWRSZXNvbHZlKCk7CisgICAgICAgICAgICBmYWlsKCJPYmplY3RTdHJlYW1FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoT2JqZWN0U3RyZWFtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oZSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM0MWNhZDAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aFRlc3QuamF2YQpAQCAtMCwwICsxLDI0MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuTXlDZXJ0UGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0Lk15RmFpbGluZ0NlcnRQYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuVGVzdFV0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS50ZXN0ZnJhbWV3b3JrLnNlcmlhbGl6YXRpb24uU2VyaWFsaXphdGlvblRlc3Q7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkNlcnRQYXRoPC9jb2RlPiBmaWVsZHMgYW5kIG1ldGhvZHMKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBDZXJ0UGF0aFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgLyoqCisgICAgICogTWVhbmluZ2xlc3MgY2VydCBwYXRoIGVuY29kaW5nIGp1c3QgZm9yIHRlc3RpbmcgcHVycG9zZXMKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gdGVzdEVuY29kaW5nID0gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAoYnl0ZSkxLCAoYnl0ZSkyLCAoYnl0ZSkzLCAoYnl0ZSk0LCAoYnl0ZSk1CisgICAgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSB0ZXN0RW5jb2RpbmcxID0gbmV3IGJ5dGVbXSB7CisgICAgICAgIChieXRlKTEsIChieXRlKTIsIChieXRlKTMsIChieXRlKTQsIChieXRlKTUsIChieXRlKTYKKyAgICB9OworCisgICAgLy8KKyAgICAvLyBUZXN0cworICAgIC8vCisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0UGF0aChTdHJpbmcgdHlwZSk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgaGFzaCBvZiB0aGUgPGNvZGU+Q2VydGlmaWNhdGU8L2NvZGU+IGluc3RhbmNlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdENlcnRQYXRoKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydFBhdGggY3AxID0gbmV3IE15Q2VydFBhdGgodGVzdEVuY29kaW5nKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiTXlFbmNvZGluZyIsIGNwMS5nZXRUeXBlKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKHRlc3RFbmNvZGluZywgY3AxLmdldEVuY29kZWQoKSkpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRQYXRoIGNwMSA9IG5ldyBNeUNlcnRQYXRoKG51bGwpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmhhc2hDb2RlKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgaGFzaCBvZiB0aGUgPGNvZGU+Q2VydGlmaWNhdGU8L2NvZGU+IGluc3RhbmNlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEhhc2hDb2RlKCkgeworICAgICAgICBDZXJ0UGF0aCBjcDEgPSBuZXcgTXlDZXJ0UGF0aCh0ZXN0RW5jb2RpbmcpOworICAgICAgICBDZXJ0UGF0aCBjcDIgPSBuZXcgTXlDZXJ0UGF0aCh0ZXN0RW5jb2RpbmcpOworICAgICAgICBDZXJ0UGF0aCBjcDMgPSBuZXcgTXlDZXJ0UGF0aCh0ZXN0RW5jb2RpbmcxKTsKKworICAgICAgICBhc3NlcnRUcnVlKGNwMS5oYXNoQ29kZSgpID09IGNwMi5oYXNoQ29kZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjcDEuaGFzaENvZGUoKSAhPSBjcDMuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+aGFzaENvZGUoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogaGFzaCBjb2RlIG9mIGVxdWFsIG9iamVjdHMgc2hvdWxkIGJlIHRoZSBzYW1lCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEhhc2hDb2RlRXF1YWxzT2JqZWN0KCkgeworICAgICAgICBDZXJ0UGF0aCBjcDEgPSBuZXcgTXlDZXJ0UGF0aCh0ZXN0RW5jb2RpbmcpOworICAgICAgICBDZXJ0UGF0aCBjcDIgPSBuZXcgTXlDZXJ0UGF0aCh0ZXN0RW5jb2RpbmcpOworICAgICAgICBhc3NlcnRUcnVlKChjcDEuaGFzaENvZGUoKSA9PSBjcDIuaGFzaENvZGUoKSkgJiYgY3AxLmVxdWFscyhjcDIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRUeXBlKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgY2VydCBwYXRoIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0VHlwZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJNeUVuY29kaW5nIiwgbmV3IE15Q2VydFBhdGgodGVzdEVuY29kaW5nKS5nZXRUeXBlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPmVxdWFscyhPYmplY3QpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiBvYmplY3QgZXF1YWxzIHRvIGl0c2VsZgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFcXVhbHNPYmplY3QwMSgpIHsKKyAgICAgICAgQ2VydFBhdGggY3AxID0gbmV3IE15Q2VydFBhdGgodGVzdEVuY29kaW5nKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjcDEuZXF1YWxzKGNwMSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmVxdWFscyhPYmplY3QpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiBvYmplY3QgZXF1YWxzIHRvIG90aGVyIDxjb2RlPkNlcnRQYXRoPC9jb2RlPgorICAgICAqIGluc3RhbmNlIHdpdGggdGhlIHNhbWUgc3RhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RXF1YWxzT2JqZWN0MDIoKSB7CisgICAgICAgIENlcnRQYXRoIGNwMSA9IG5ldyBNeUNlcnRQYXRoKHRlc3RFbmNvZGluZyk7CisgICAgICAgIENlcnRQYXRoIGNwMiA9IG5ldyBNeUNlcnRQYXRoKHRlc3RFbmNvZGluZyk7CisgICAgICAgIGFzc2VydFRydWUoY3AxLmVxdWFscyhjcDIpICYmIGNwMi5lcXVhbHMoY3AxKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+ZXF1YWxzKE9iamVjdCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IG9iamVjdCBub3QgZXF1YWxzIHRvIDxjb2RlPm51bGw8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVxdWFsc09iamVjdDAzKCkgeworICAgICAgICBDZXJ0UGF0aCBjcDEgPSBuZXcgTXlDZXJ0UGF0aCh0ZXN0RW5jb2RpbmcpOworICAgICAgICBhc3NlcnRGYWxzZShjcDEuZXF1YWxzKG51bGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5lcXVhbHMoT2JqZWN0KTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogb2JqZWN0IG5vdCBlcXVhbHMgdG8gb3RoZXIgd2hpY2ggaXMgbm90CisgICAgICogaW5zdGFuY2Ugb2YgPGNvZGU+Q2VydFBhdGg8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVxdWFsc09iamVjdDA0KCkgeworICAgICAgICBDZXJ0UGF0aCBjcDEgPSBuZXcgTXlDZXJ0UGF0aCh0ZXN0RW5jb2RpbmcpOworICAgICAgICBhc3NlcnRGYWxzZShjcDEuZXF1YWxzKCJNeUVuY29kaW5nIikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnRvU3RyaW5nKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mCisgICAgICogPGNvZGU+Q2VydFBhdGg8L2NvZGU+IG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RUb1N0cmluZygpIHsKKyAgICAgICAgQ2VydFBhdGggY3AxID0gbmV3IE15Q2VydFBhdGgodGVzdEVuY29kaW5nKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjcDEudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLy8KKyAgICAvLyB0aGUgZm9sbG93aW5nIHRlc3RzIGp1c3QgY2FsbCBtZXRob2RzCisgICAgLy8gdGhhdCBhcmUgYWJzdHJhY3QgaW4gPGNvZGU+Q2VydFBhdGg8L2NvZGU+CisgICAgLy8gKFNvIHRoZXkganVzdCBsaWtlIHNpZ25hdHVyZSB0ZXN0cykKKyAgICAvLworCisgICAgLyoqCisgICAgICogVGhpcyB0ZXN0IGp1c3QgY2FsbHMgPGNvZGU+Z2V0Q2VydGlmaWNhdGVzKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0Q2VydGlmaWNhdGVzKCkgeworICAgICAgICBDZXJ0UGF0aCBjcDEgPSBuZXcgTXlDZXJ0UGF0aCh0ZXN0RW5jb2RpbmcpOworICAgICAgICBjcDEuZ2V0Q2VydGlmaWNhdGVzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyB0ZXN0IGp1c3QgY2FsbHMgPGNvZGU+Z2V0RW5jb2RlZCgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICoKKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0RW5jb2RlZCgpIHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgQ2VydFBhdGggY3AxID0gbmV3IE15Q2VydFBhdGgodGVzdEVuY29kaW5nKTsKKyAgICAgICAgY3AxLmdldEVuY29kZWQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIHRlc3QganVzdCBjYWxscyA8Y29kZT5nZXRFbmNvZGVkKFN0cmluZyk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRFbmNvZGVkU3RyaW5nKCkgdGhyb3dzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24geworICAgICAgICBDZXJ0UGF0aCBjcDEgPSBuZXcgTXlDZXJ0UGF0aCh0ZXN0RW5jb2RpbmcpOworICAgICAgICBjcDEuZ2V0RW5jb2RlZCgiTXlFbmNvZGluZyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgdGVzdCBqdXN0IGNhbGxzIDxjb2RlPmdldEVuY29kaW5ncygpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEVuY29kaW5ncygpIHsKKyAgICAgICAgQ2VydFBhdGggY3AxID0gbmV3IE15Q2VydFBhdGgodGVzdEVuY29kaW5nKTsKKyAgICAgICAgY3AxLmdldEVuY29kaW5ncygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgdGVzdCBqdXN0IGNhbGxzIDxjb2RlPndyaXRlUmVwbGFjZSgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFdyaXRlUmVwbGFjZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE15Q2VydFBhdGggY3AxID0gbmV3IE15Q2VydFBhdGgodGVzdEVuY29kaW5nKTsKKyAgICAgICAgICAgIE9iamVjdCBvYmogPSBjcDEud3JpdGVSZXBsYWNlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKG9iai50b1N0cmluZygpLmNvbnRhaW5zKAorICAgICAgICAgICAgICAgICAgICAiamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoJENlcnRQYXRoUmVwIikpOworICAgICAgICB9IGNhdGNoIChPYmplY3RTdHJlYW1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBPYmplY3RTdHJlYW1FeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RXcml0ZVJlcGxhY2VfT2JqZWN0U3RyZWFtRXhjZXB0aW9uKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgTXlGYWlsaW5nQ2VydFBhdGggY3AgPSBuZXcgTXlGYWlsaW5nQ2VydFBhdGgodGVzdEVuY29kaW5nKTsKKyAgICAgICAgICAgIE9iamVjdCBvYmogPSBjcC53cml0ZVJlcGxhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChPYmplY3RTdHJlYW1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIHNlcmlhbGl6YXRpb24vZGVzZXJpYWxpemF0aW9uIGNvbXBhdGliaWxpdHkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6YXRpb25TZWxmKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RVdGlscy5pbml0Q2VydFBhdGhTU0NlcnRDaGFpbigpOworICAgICAgICBDZXJ0UGF0aCBjZXJ0UGF0aCA9IFRlc3RVdGlscy5idWlsZENlcnRQYXRoU1NDZXJ0Q2hhaW4oKTsKKworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdC52ZXJpZnlTZWxmKGNlcnRQYXRoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBzZXJpYWxpemF0aW9uL2Rlc2VyaWFsaXphdGlvbiBjb21wYXRpYmlsaXR5IHdpdGggUkkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6YXRpb25Db21wYXRpYmlsaXR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RVdGlscy5pbml0Q2VydFBhdGhTU0NlcnRDaGFpbigpOworICAgICAgICBDZXJ0UGF0aCBjZXJ0UGF0aCA9IFRlc3RVdGlscy5idWlsZENlcnRQYXRoU1NDZXJ0Q2hhaW4oKTsKKworICAgICAgICBTZXJpYWxpemF0aW9uVGVzdC52ZXJpZnlHb2xkZW4odGhpcywgY2VydFBhdGgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoVmFsaWRhdG9yMVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoVmFsaWRhdG9yMVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMzU1NGQ2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhWYWxpZGF0b3IxVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDU2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhQYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aFZhbGlkYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoVmFsaWRhdG9yU3BpOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuTXlDZXJ0UGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0Lk15Q2VydFBhdGhWYWxpZGF0b3JTcGk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuU3BpRW5nVXRpbHM7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkNlcnRQYXRoVmFsaWRhdG9yPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kCisgKiBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIENlcnRQYXRoVmFsaWRhdG9yMVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBzcnZDZXJ0UGF0aFZhbGlkYXRvciA9ICJDZXJ0UGF0aFZhbGlkYXRvciI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZGVmYXVsdFR5cGUgPSAiUEtJWCI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgW10gdmFsaWRWYWx1ZXMgPSB7CisgICAgICAgICAgICAiUEtJWCIsICJwa2l4IiwgIlBraVgiLCAicEtpWCIgfTsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBbXSBpbnZhbGlkVmFsdWVzID0gU3BpRW5nVXRpbHMuaW52YWxpZFZhbHVlczsKKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gUEtJWFN1cHBvcnQgPSBmYWxzZTsKKworICAgIHByaXZhdGUgc3RhdGljIFByb3ZpZGVyIGRlZmF1bHRQcm92aWRlcjsKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZGVmYXVsdFByb3ZpZGVyTmFtZTsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBOb3RTdXBwb3J0TXNnID0gIiI7CisKKyAgICBzdGF0aWMgeworICAgICAgICBkZWZhdWx0UHJvdmlkZXIgPSBTcGlFbmdVdGlscy5pc1N1cHBvcnQoZGVmYXVsdFR5cGUsCisgICAgICAgICAgICAgICAgc3J2Q2VydFBhdGhWYWxpZGF0b3IpOworICAgICAgICBQS0lYU3VwcG9ydCA9IChkZWZhdWx0UHJvdmlkZXIgIT0gbnVsbCk7CisgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUgPSAoUEtJWFN1cHBvcnQgPyBkZWZhdWx0UHJvdmlkZXIuZ2V0TmFtZSgpIDogbnVsbCk7CisgICAgICAgIE5vdFN1cHBvcnRNc2cgPSBkZWZhdWx0VHlwZS5jb25jYXQoIiBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgfQorCisKKworICAgIHByaXZhdGUgc3RhdGljIENlcnRQYXRoVmFsaWRhdG9yW10gY3JlYXRlQ1BWcygpIHsKKyAgICAgICAgaWYgKCFQS0lYU3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0UGF0aFZhbGlkYXRvcltdIGNlcnRQVnMgPSBuZXcgQ2VydFBhdGhWYWxpZGF0b3JbM107CisgICAgICAgICAgICBjZXJ0UFZzWzBdID0gQ2VydFBhdGhWYWxpZGF0b3IuZ2V0SW5zdGFuY2UoZGVmYXVsdFR5cGUpOworICAgICAgICAgICAgY2VydFBWc1sxXSA9IENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKGRlZmF1bHRUeXBlLAorICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgIGNlcnRQVnNbMl0gPSBDZXJ0UGF0aFZhbGlkYXRvci5nZXRJbnN0YW5jZShkZWZhdWx0VHlwZSwKKyAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgIHJldHVybiBjZXJ0UFZzOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldERlZmF1bHRUeXBlKCk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBzZWN1cml0eSBwcm9wZXJ0eSAiY2VydHBhdGh2YWxpZGF0b3IudHlwZSIgb3IgIlBLSVgiCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoVmFsaWRhdG9yMDEoKSB7CisgICAgICAgIGlmICghUEtJWFN1cHBvcnQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHByb3BOYW1lID0gImNlcnRwYXRodmFsaWRhdG9yLnR5cGUiOworICAgICAgICBTdHJpbmcgZGVmQ1BWID0gU2VjdXJpdHkuZ2V0UHJvcGVydHkocHJvcE5hbWUpOworCisgICAgICAgIFN0cmluZyBkdCA9IENlcnRQYXRoVmFsaWRhdG9yLmdldERlZmF1bHRUeXBlKCk7CisgICAgICAgIFN0cmluZyByZXNUeXBlID0gZGVmQ1BWOworICAgICAgICBpZiAocmVzVHlwZSA9PSBudWxsKSB7CisgICAgICAgICAgICByZXNUeXBlID0gZGVmYXVsdFR5cGU7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiRGVmYXVsdCB0eXBlIGhhdmUgbm90IGJlIG51bGwiLCBkdCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRlZmF1bHQgdHlwZSIsIGR0LCByZXNUeXBlKTsKKworICAgICAgICBpZiAoZGVmQ1BWID09IG51bGwpIHsKKyAgICAgICAgICAgIFNlY3VyaXR5LnNldFByb3BlcnR5KHByb3BOYW1lLCBkZWZhdWx0VHlwZSk7CisgICAgICAgICAgICBkdCA9IENlcnRQYXRoVmFsaWRhdG9yLmdldERlZmF1bHRUeXBlKCk7CisgICAgICAgICAgICByZXNUeXBlID0gU2VjdXJpdHkuZ2V0UHJvcGVydHkocHJvcE5hbWUpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiSW5jb3JyZWN0IGRlZmF1bHQgdHlwZSIsIHJlc1R5cGUpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiRGVmYXVsdCB0eXBlIGhhdmUgbm90IGJlIG51bGwiLCBkdCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBkZWZhdWx0IHR5cGUiLCBkdCwgcmVzVHlwZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOgorICAgICAqIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBudWxsCisgICAgICogdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSAgaXMgbm90IGF2YWlsYWJsZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aFZhbGlkYXRvcjAyKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3IuZ2V0SW5zdGFuY2UobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBvciBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBhbGdvcml0aG0gaXMgbnVsbCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIENlcnRQYXRoVmFsaWRhdG9yIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aFZhbGlkYXRvcjAzKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiAgeworICAgICAgICBpZiAoIVBLSVhTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yIGNlcnRQVjsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgY2VydFBWID0gQ2VydFBhdGhWYWxpZGF0b3IuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwgY2VydFBWLmdldEFsZ29yaXRobSgpLCB2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgIH0KKyAgICB9CisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbCBvciBlbXB0eQorICAgICAqCisgICAgICogRklYTUU6IHZlcmlmeSB3aGF0IGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93biBpZiBwcm92aWRlciBpcyBlbXB0eQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aFZhbGlkYXRvcjA0KCkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uICB7CisgICAgICAgIGlmICghUEtJWFN1cHBvcnQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHByb3ZpZGVyID0gbnVsbDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDZXJ0UGF0aFZhbGlkYXRvci5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgcHJvdmlkZXIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCAiIik7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaGFzIGludmFsaWQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhWYWxpZGF0b3IwNSgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoIVBLSVhTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IHQgPSAwOyB0IDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyB0KyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW3RdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUxKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOgorICAgICAqIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBudWxsCisgICAgICogdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSAgaXMgbm90IGF2YWlsYWJsZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aFZhbGlkYXRvcjA2KCkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uICB7CisgICAgICAgIGlmICghUEtJWFN1cHBvcnQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKG51bGwsIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDZXJ0UGF0aFZhbGlkYXRvci5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldLCBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlMSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcik8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBDZXJ0UGF0aFZhbGlkYXRvciBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhWYWxpZGF0b3IwNygpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghUEtJWFN1cHBvcnQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3IgY2VydFBWOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjZXJ0UFYgPSBDZXJ0UGF0aFZhbGlkYXRvci5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBjZXJ0UFYuZ2V0QWxnb3JpdGhtKCksCisgICAgICAgICAgICAgICAgICAgIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIG5hbWUiLCBjZXJ0UFYuZ2V0UHJvdmlkZXIoKQorICAgICAgICAgICAgICAgICAgICAuZ2V0TmFtZSgpLCBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aFZhbGlkYXRvcjA4KCkKKyAgICAgICAgICAgIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gIHsKKyAgICAgICAgaWYgKCFQS0lYU3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBwcm92ID0gbnVsbDsKKyAgICAgICAgZm9yIChpbnQgdCA9IDA7IHQgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IHQrKyApIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3IuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbdF0sIHByb3YpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUxKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtICBpcyBub3QgYXZhaWxhYmxlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoVmFsaWRhdG9yMDkoKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gIHsKKyAgICAgICAgaWYgKCFQS0lYU3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3IuZ2V0SW5zdGFuY2UobnVsbCwgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3IuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG0gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlMSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBwcm92aWRlcik8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBDZXJ0UGF0aFZhbGlkYXRvciBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhWYWxpZGF0b3IxMCgpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghUEtJWFN1cHBvcnQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3IgY2VydFBWOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNlcnRQViA9IENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLAorICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgYWxnb3JpdGhtIiwgY2VydFBWLmdldEFsZ29yaXRobSgpLAorICAgICAgICAgICAgICAgICAgICB2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciBuYW1lIiwgY2VydFBWLmdldFByb3ZpZGVyKCksCisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT52YWxpZGF0ZShDZXJ0UGF0aCBjZXJ0cGF0aCwgQ2VydFBhdGhQYXJhbWV0ZXJzIHBhcmFtcyk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gcGFyYW1zIGlzIG5vdAorICAgICAqIGluc3RhbmNlIG9mIFBLSVhQYXJhbWV0ZXJzIG9yIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhWYWxpZGF0b3IxMSgpCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24geworICAgICAgICBpZiAoIVBLSVhTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yIFtdIGNlcnRQViA9IGNyZWF0ZUNQVnMoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ2VydFBhdGhWYWxpZGF0b3Igb2JqZWN0cyB3ZXJlIG5vdCBjcmVhdGVkIiwgY2VydFBWKTsKKyAgICAgICAgTXlDZXJ0UGF0aCBtQ1AgPSBuZXcgTXlDZXJ0UGF0aChuZXcgYnl0ZVswXSk7CisgICAgICAgIGludmFsaWRQYXJhbXMgbVBhciA9IG5ldyBpbnZhbGlkUGFyYW1zKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2VydFBWLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNlcnRQVltpXS52YWxpZGF0ZShtQ1AsIG1QYXIpOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2goSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNlcnRQVltpXS52YWxpZGF0ZShtQ1AsIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2goSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAgLyoqCisgICAgICogVGVzdCBmb3IKKyAgICAgKiA8Y29kZT5DZXJ0UGF0aFZhbGlkYXRvcjwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgQ2VydFBhdGhWYWxpZGF0b3Igb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoVmFsaWRhdG9yMTIoKQorICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24sIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBpZiAoIVBLSVhTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yU3BpIHNwaSA9IG5ldyBNeUNlcnRQYXRoVmFsaWRhdG9yU3BpKCk7CisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yIGNlcnRQViA9IG5ldyBteUNlcnRQYXRoVmFsaWRhdG9yKHNwaSwKKyAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyLCBkZWZhdWx0VHlwZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGNlcnRQVi5nZXRBbGdvcml0aG0oKSwgZGVmYXVsdFR5cGUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsIGNlcnRQVi5nZXRQcm92aWRlcigpLCBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICBjZXJ0UFYudmFsaWRhdGUobnVsbCwgbnVsbCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0UFYudmFsaWRhdGUobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgY2VydFBWID0gbmV3IG15Q2VydFBhdGhWYWxpZGF0b3IobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCBhbGdvcml0aG0iLCBjZXJ0UFYuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICBhc3NlcnROdWxsKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBjZXJ0UFYuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0UFYudmFsaWRhdGUobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRBbGdvcml0aG0oKTwvY29kZT4gbWV0aG9kCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoVmFsaWRhdG9yMTMoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFQS0lYU3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBDZXJ0UGF0aFZhbGlkYXRvciBjZXJ0UFY7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNlcnRQViA9IENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGNlcnRQVi5nZXRBbGdvcml0aG0oKSwKKyAgICAgICAgICAgICAgICAgICAgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjZXJ0UFYgPSBDZXJ0UGF0aFZhbGlkYXRvci5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGNlcnRQVi5nZXRBbGdvcml0aG0oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjZXJ0UFYgPSBDZXJ0UGF0aFZhbGlkYXRvci5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGFsZ29yaXRobSIsIGNlcnRQVi5nZXRBbGdvcml0aG0oKSwKKyAgICAgICAgICAgICAgICAgICAgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UHJvdmlkZXIoKTwvY29kZT4gbWV0aG9kCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoVmFsaWRhdG9yMTQoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFQS0lYU3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yIGNlcnRQVjsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNlcnRQViA9IENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBjZXJ0UFYuZ2V0UHJvdmlkZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjZXJ0UFYgPSBDZXJ0UGF0aFZhbGlkYXRvci5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwgY2VydFBWLmdldFByb3ZpZGVyKCksCisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgIH0KKyAgICB9Cit9CisvKioKKyAqIEFkZGl0aW9uYWwgY2xhc3MgdG8gdmVyaWZ5IENlcnRQYXRoVmFsaWRhdG9yIGNvbnN0cnVjdG9yCisgKi8KK2NsYXNzIG15Q2VydFBhdGhWYWxpZGF0b3IgZXh0ZW5kcyBDZXJ0UGF0aFZhbGlkYXRvciB7CisKKyAgICBwdWJsaWMgbXlDZXJ0UGF0aFZhbGlkYXRvcihDZXJ0UGF0aFZhbGlkYXRvclNwaSBzcGksIFByb3ZpZGVyIHByb3YsIFN0cmluZyB0eXBlKSB7CisgICAgICAgIHN1cGVyKHNwaSwgcHJvdiwgdHlwZSk7CisgICAgfQorfQorLyoqCisgKiBBZGRpdGlvbmFsIGNsYXNzIHRvIHZlcmlmeSB2YWxpZGF0ZSBtZXRob2QKKyAqLworY2xhc3MgaW52YWxpZFBhcmFtcyBpbXBsZW1lbnRzIENlcnRQYXRoUGFyYW1ldGVycyB7CisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBpbnZhbGlkUGFyYW1zKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhWYWxpZGF0b3IyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhWYWxpZGF0b3IyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhmNWI2ZDUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aFZhbGlkYXRvcjJUZXN0LmphdmEKQEAgLTAsMCArMSwyNjIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorICogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuU3BpRW5nVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5NeUNlcnRQYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuVGVzdFV0aWxzOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhQYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aFZhbGlkYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LlBLSVhQYXJhbWV0ZXJzOworCisvKioKKyAqIFRlc3RzIGZvciBDZXJ0UGF0aFZhbGlkYXRvciBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMKKyAqLworcHVibGljIGNsYXNzIENlcnRQYXRoVmFsaWRhdG9yMlRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGRlZmF1bHRBbGcgPSAiQ2VydFBCIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENlcnRQYXRoVmFsaWRhdG9yUHJvdmlkZXJDbGFzcyA9ICJvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0Lk15Q2VydFBhdGhWYWxpZGF0b3JTcGkiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gaW52YWxpZFZhbHVlcyA9IFNwaUVuZ1V0aWxzLmludmFsaWRWYWx1ZXM7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSB2YWxpZFZhbHVlczsKKworICAgIHN0YXRpYyB7CisgICAgICAgIHZhbGlkVmFsdWVzID0gbmV3IFN0cmluZ1s0XTsKKyAgICAgICAgdmFsaWRWYWx1ZXNbMF0gPSBkZWZhdWx0QWxnOworICAgICAgICB2YWxpZFZhbHVlc1sxXSA9IGRlZmF1bHRBbGcudG9Mb3dlckNhc2UoKTsKKyAgICAgICAgdmFsaWRWYWx1ZXNbMl0gPSAiQ2VSdFBiIjsKKyAgICAgICAgdmFsaWRWYWx1ZXNbM10gPSAiY0VSVHBiIjsKKyAgICB9CisKKyAgICBQcm92aWRlciBtUHJvdjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIG1Qcm92ID0gKG5ldyBTcGlFbmdVdGlscygpKS5uZXcgTXlQcm92aWRlcigiTXlDZXJ0UGF0aFZhbGlkYXRvclByb3ZpZGVyIiwKKyAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yIHRlc3RpbmciLCBDZXJ0UGF0aFZhbGlkYXRvcjFUZXN0LnNydkNlcnRQYXRoVmFsaWRhdG9yLmNvbmNhdCgiLiIpCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGRlZmF1bHRBbGcpLCBDZXJ0UGF0aFZhbGlkYXRvclByb3ZpZGVyQ2xhc3MpOworICAgICAgICBTZWN1cml0eS5pbnNlcnRQcm92aWRlckF0KG1Qcm92LCAxKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEBzZWUgVGVzdENhc2UjdGVhckRvd24oKQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgICAgIFNlY3VyaXR5LnJlbW92ZVByb3ZpZGVyKG1Qcm92LmdldE5hbWUoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrUmVzdWx0KENlcnRQYXRoVmFsaWRhdG9yIGNlcnRWKSB0aHJvd3MgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGR0ID0gQ2VydFBhdGhWYWxpZGF0b3IuZ2V0RGVmYXVsdFR5cGUoKTsKKyAgICAgICAgU3RyaW5nIHByb3BOYW1lID0gImNlcnRwYXRodmFsaWRhdG9yLnR5cGUiOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFNlY3VyaXR5LnNldFByb3BlcnR5KHByb3BOYW1lLCBpbnZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRlZmF1bHQgdHlwZSIsIENlcnRQYXRoVmFsaWRhdG9yLmdldERlZmF1bHRUeXBlKCksCisgICAgICAgICAgICAgICAgICAgIGludmFsaWRWYWx1ZXNbaV0pOworICAgICAgICB9CisgICAgICAgIFNlY3VyaXR5LnNldFByb3BlcnR5KHByb3BOYW1lLCBkdCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRlZmF1bHQgdHlwZSIsIENlcnRQYXRoVmFsaWRhdG9yLmdldERlZmF1bHRUeXBlKCksIGR0KTsKKyAgICAgICAgY2VydFYudmFsaWRhdGUobnVsbCwgbnVsbCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0Vi52YWxpZGF0ZShudWxsLCBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0Vi52YWxpZGF0ZShudWxsLCBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtKTwvY29kZT4gbWV0aG9kIEFzc2VydGlvbnM6CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwgdGhyb3dzCisgICAgICogTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUgcmV0dXJucworICAgICAqIENlcnRQYXRoVmFsaWRhdG9yIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZTAxKCkgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24sIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDZXJ0UGF0aFZhbGlkYXRvci5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gKHR5cGU6ICIuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBDZXJ0UGF0aFZhbGlkYXRvciBjZXJQVjsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgY2VyUFYgPSBDZXJ0UGF0aFZhbGlkYXRvci5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB0eXBlIiwgY2VyUFYuZ2V0QWxnb3JpdGhtKCksIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwgY2VyUFYuZ2V0UHJvdmlkZXIoKSwgbVByb3YpOworICAgICAgICAgICAgY2hlY2tSZXN1bHQoY2VyUFYpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QgQXNzZXJ0aW9uczogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHdoZW4gYWxnb3JpdGhtIGlzIG5vdCBhdmFpbGFibGUgdGhyb3dzCisgICAgICogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbCBvciBlbXB0eTsgdGhyb3dzCisgICAgICogTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBhdmFpbGFibGU7IHJldHVybnMKKyAgICAgKiBDZXJ0UGF0aFZhbGlkYXRvciBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2UwMigpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3IuZ2V0SW5zdGFuY2UobnVsbCwgbVByb3YuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3IuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwgbVByb3YuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gKHR5cGU6ICIuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcHJvdiA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3IuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIHByb3YpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHByb3ZpZGVyIGlzIG51bGwgKHR5cGU6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQodmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCAiIik7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gcHJvdmlkZXIgaXMgZW1wdHkgKHR5cGU6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQodmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDE7IGogPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3IuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIGludmFsaWRWYWx1ZXNbal0pOworICAgICAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAodHlwZTogIi5jb25jYXQodmFsaWRWYWx1ZXNbaV0pCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdCgiIHByb3ZpZGVyOiAiKS5jb25jYXQoaW52YWxpZFZhbHVlc1tqXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3IgY2VyUFY7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNlclBWID0gQ2VydFBhdGhWYWxpZGF0b3IuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sIG1Qcm92LmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB0eXBlIiwgY2VyUFYuZ2V0QWxnb3JpdGhtKCksIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwgY2VyUFYuZ2V0UHJvdmlkZXIoKS5nZXROYW1lKCksIG1Qcm92LmdldE5hbWUoKSk7CisgICAgICAgICAgICBjaGVja1Jlc3VsdChjZXJQVik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgYWxnb3JpdGhtLCBQcm92aWRlciBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kIEFzc2VydGlvbnM6IHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBudWxsCisgICAgICogdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIGFsZ29yaXRobSBpcyBub3QgYXZhaWxhYmxlIHRocm93cworICAgICAqIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aGVuIHByb3ZpZGVyIGlzIG51bGw7IHJldHVybnMgQ2VydFBhdGhWYWxpZGF0b3IKKyAgICAgKiBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2UwMygpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24sIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKG51bGwsIG1Qcm92KTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIGFsZ29yaXRobSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3IuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwgbVByb3YpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAodHlwZTogIi5jb25jYXQoaW52YWxpZFZhbHVlc1tpXSkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFByb3ZpZGVyIHByb3YgPSBudWxsOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBwcm92KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBudWxsICh0eXBlOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KHZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yIGNlclBWOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjZXJQViA9IENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBtUHJvdik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB0eXBlIiwgY2VyUFYuZ2V0QWxnb3JpdGhtKCksIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwgY2VyUFYuZ2V0UHJvdmlkZXIoKSwgbVByb3YpOworICAgICAgICAgICAgY2hlY2tSZXN1bHQoY2VyUFYpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFZhbGlkYXRlKCkgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIE15Q2VydFBhdGggbUNQID0gbmV3IE15Q2VydFBhdGgobmV3IGJ5dGVbMF0pOworICAgICAgICBDZXJ0UGF0aFBhcmFtZXRlcnMgcGFyYW1zID0gbmV3IFBLSVhQYXJhbWV0ZXJzKFRlc3RVdGlscy5nZXRUcnVzdEFuY2hvclNldCgpKTsKKyAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3IgY2VydFBWID0gQ2VydFBhdGhWYWxpZGF0b3IuZ2V0SW5zdGFuY2UoZGVmYXVsdEFsZyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0UFYudmFsaWRhdGUobUNQLCBwYXJhbXMpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRQVi52YWxpZGF0ZShudWxsLCBwYXJhbXMpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0UFYudmFsaWRhdGUobUNQLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9IGNhdGNoIChDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbiIpOworICAgICAgICB9CisKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aFZhbGlkYXRvcjNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aFZhbGlkYXRvcjNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzg0MTBjYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoVmFsaWRhdG9yM1Rlc3QuamF2YQpAQCAtMCwwICsxLDExMSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlNwaUVuZ1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuTXlDZXJ0UGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0LlRlc3RVdGlsczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhQYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aFZhbGlkYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5QS0lYUGFyYW1ldGVyczsKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkNlcnRQYXRoVmFsaWRhdG9yPC9jb2RlPiBjbGFzcyAgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBDZXJ0UGF0aFZhbGlkYXRvcjNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGRlZmF1bHRUeXBlID0gQ2VydFBhdGhCdWlsZGVyMVRlc3QuZGVmYXVsdFR5cGU7CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIFBLSVhTdXBwb3J0ID0gZmFsc2U7CisKKyAgICBwcml2YXRlIHN0YXRpYyBQcm92aWRlciBkZWZhdWx0UHJvdmlkZXI7CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGRlZmF1bHRQcm92aWRlck5hbWU7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgTm90U3VwcG9ydE1zZyA9ICIiOworCisgICAgc3RhdGljIHsKKyAgICAgICAgZGVmYXVsdFByb3ZpZGVyID0gU3BpRW5nVXRpbHMuaXNTdXBwb3J0KGRlZmF1bHRUeXBlLAorICAgICAgICAgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yMVRlc3Quc3J2Q2VydFBhdGhWYWxpZGF0b3IpOworICAgICAgICBQS0lYU3VwcG9ydCA9IChkZWZhdWx0UHJvdmlkZXIgIT0gbnVsbCk7CisgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUgPSAoUEtJWFN1cHBvcnQgPyBkZWZhdWx0UHJvdmlkZXIuZ2V0TmFtZSgpIDogbnVsbCk7CisgICAgICAgIE5vdFN1cHBvcnRNc2cgPSBkZWZhdWx0VHlwZS5jb25jYXQoIiBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgQ2VydFBhdGhWYWxpZGF0b3JbXSBjcmVhdGVDUFZzKCkgeworICAgICAgICBpZiAoIVBLSVhTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yW10gY2VydFBWcyA9IG5ldyBDZXJ0UGF0aFZhbGlkYXRvclszXTsKKyAgICAgICAgICAgIGNlcnRQVnNbMF0gPSBDZXJ0UGF0aFZhbGlkYXRvci5nZXRJbnN0YW5jZShkZWZhdWx0VHlwZSk7CisgICAgICAgICAgICBjZXJ0UFZzWzFdID0gQ2VydFBhdGhWYWxpZGF0b3IuZ2V0SW5zdGFuY2UoZGVmYXVsdFR5cGUsCisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgY2VydFBWc1syXSA9IENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKGRlZmF1bHRUeXBlLAorICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICAgICAgcmV0dXJuIGNlcnRQVnM7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT52YWxpZGF0ZShDZXJ0UGF0aCBjZXJ0cGF0aCwgQ2VydFBhdGhQYXJhbWV0ZXJzIHBhcmFtcyk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiB3aGVuIHBhcmFtcyBpcyBpbnN0YW5jZSBvZiBQS0lYUGFyYW1ldGVycyBhbmQKKyAgICAgKiBjZXJ0cGF0aCBpcyBub3QgWC41MDkgdHlwZQorICAgICAqCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdFZhbGlkYXRlMDEoKSB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiwgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24gIHsKKyAgICAgICAgaWYgKCFQS0lYU3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBNeUNlcnRQYXRoIG1DUCA9IG5ldyBNeUNlcnRQYXRoKG5ldyBieXRlWzBdKTsKKyAgICAgICAgQ2VydFBhdGhQYXJhbWV0ZXJzIHBhcmFtcyA9IG5ldyBQS0lYUGFyYW1ldGVycyhUZXN0VXRpbHMuZ2V0VHJ1c3RBbmNob3JTZXQoKSk7CisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yIFtdIGNlcnRQViA9IGNyZWF0ZUNQVnMoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ2VydFBhdGhWYWxpZGF0b3Igb2JqZWN0cyB3ZXJlIG5vdCBjcmVhdGVkIiwgY2VydFBWKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjZXJ0UFYubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2VydFBWW2ldLnZhbGlkYXRlKG1DUCwgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2VydFBWW2ldLnZhbGlkYXRlKG51bGwsIHBhcmFtcyk7CisgICAgICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2goTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZWFjMWY3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw0NjkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKKworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5DZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZAorICogbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgVGhyb3dhYmxlIHRDYXVzZSA9IG5ldyBUaHJvd2FibGUoIlRocm93YWJsZSBmb3IgZXhjZXB0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbigpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uMDEoKSB7CisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHRFID0gbmV3IENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHdpdGggZGV0YWlsIG1lc3NhZ2UgbXNnLgorICAgICAqIFBhcmFtZXRlciA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbjAyKCkgeworICAgICAgICBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbihtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHdoZW4gPGNvZGU+bXNnPC9jb2RlPgorICAgICAqIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24wMygpIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9IG51bGw7CisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHRFID0gbmV3IENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKG1zZyk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+CisgICAgICogaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbjA0KCkgeworICAgICAgICBUaHJvd2FibGUgY2F1c2UgPSBudWxsOworICAgICAgICBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbihjYXVzZSk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHdoZW4gPGNvZGU+Y2F1c2U8L2NvZGU+CisgICAgICogaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24wNSgpIHsKKyAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24gdEUgPSBuZXcgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24odENhdXNlKTsKKyAgICAgICAgaWYgKHRFLmdldE1lc3NhZ2UoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBzaG91bGQgY29udGFpbiAiLmNvbmNhdCh0b1MpLCAoZ2V0TQorICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgIC5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbjA2KCkgeworICAgICAgICBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbihudWxsLAorICAgICAgICAgICAgICAgIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24wNygpIHsKKyAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24obXNnc1tpXSwgbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHdoZW4KKyAgICAgKiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90IG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uMDgoKSB7CisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHRFID0gbmV3IENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKG51bGwsCisgICAgICAgICAgICAgICAgdENhdXNlKTsKKyAgICAgICAgaWYgKHRFLmdldE1lc3NhZ2UoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IHNob3VsZCAiLmNvbmNhdCh0b1MpLCAoZ2V0TQorICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgIC5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QgbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uMDkoKSB7CisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKG1zZ3NbaV0sIHRDYXVzZSk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGlmIChtc2dzW2ldLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IGNvbnRhaW4gIi5jb25jYXQobXNnc1tpXSksIGdldE0KKyAgICAgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKG1zZ3NbaV0pICE9IC0xKTsKKyAgICAgICAgICAgICAgICBpZiAoIWdldE0uZXF1YWxzKG1zZ3NbaV0pKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBzaG91bGQgY29udGFpbiAiLmNvbmNhdCh0b1MpLCBnZXRNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwKKyAgICAgICAgICAgICAgICAgICAgdEUuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yCisgICAgICogPGNvZGU+Q2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUsIENlcnRQYXRoLCBpbnQpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsCisgICAgICogPGNvZGU+Y2VydFBhdGg8L2NvZGU+IGlzIG51bGwgPGNvZGU+aW5kZXg8L2NvZGU+IGlzIC0xCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uMTAoKSB7CisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHRFID0gbmV3IENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKG51bGwsCisgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwgLTEpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDZXJ0UGF0aCgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDZXJ0UGF0aCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRJbmRleCgpIG11c3QgYmUgLTEiLCB0RS5nZXRJbmRleCgpLCAtMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IKKyAgICAgKiA8Y29kZT5DZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSwgQ2VydFBhdGgsIGludCk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHdoZW4KKyAgICAgKiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKiA8Y29kZT5jZXJ0UGF0aDwvY29kZT4gaXMgbnVsbCA8Y29kZT5pbmRleDwvY29kZT4gbm90IC0xIHRocm93czoKKyAgICAgKiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24xMSgpIHsKKyAgICAgICAgaW50W10gaW5keCA9IHsgMCwgMSwgMTAwLCBJbnRlZ2VyLk1BWF9WQUxVRSwgSW50ZWdlci5NSU5fVkFMVUUgfTsKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBpbmR4Lmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBuZXcgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24obXNnc1tpXSwgdENhdXNlLCBudWxsLCBpbmR4W2pdKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiRXJyb3IuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgbm90IHRocm93biBhcyBleHBlY3RlZC4gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBtc2c6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIG1zZ3NbaV0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIsIGNlcnRQYXRoIGlzIG51bGwgYW5kIGluZGV4IGlzICIgKyBpbmR4W2pdKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yCisgICAgICogPGNvZGU+Q2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUsIENlcnRQYXRoLCBpbnQpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IG5vdCBudWxsIDxjb2RlPm1zZzwvY29kZT4gbm90IG51bGwKKyAgICAgKiA8Y29kZT5jZXJ0UGF0aDwvY29kZT4gaXMgbnVsbCA8Y29kZT5pbmRleDwvY29kZT4gaXMgLTEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24xMigpIHsKKyAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24gdEU7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRFID0gbmV3IENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKG1zZ3NbaV0sIHRDYXVzZSwgbnVsbCwgLTEpOworICAgICAgICAgICAgICAgIFN0cmluZyBnZXRNID0gdEUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgICAgICBpZiAobXNnc1tpXS5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIG11c3QgY29udGFpbiAiLmNvbmNhdChtc2dzW2ldKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRNLmluZGV4T2YobXNnc1tpXSkgIT0gLTEpOworICAgICAgICAgICAgICAgICAgICBpZiAoIWdldE0uZXF1YWxzKG1zZ3NbaV0pKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgc2hvdWxkIGNvbnRhaW4gIi5jb25jYXQodG9TKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TS5pbmRleE9mKHRvUykgIT0gLTEpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIgorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdCh0Q2F1c2UudG9TdHJpbmcoKSksIHRFLmdldENhdXNlKCksIHRDYXVzZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2VydFBhdGgoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2VydFBhdGgoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRJbmRleCgpIG11c3QgcmV0dXJuIC0xIiwgdEUuZ2V0SW5kZXgoKSwgLTEpOworICAgICAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlLnRvU3RyaW5nKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiBQYXJhbWV0ZXJzOiBtc2c6ICIgKyBtc2dzW2ldCisgICAgICAgICAgICAgICAgICAgICAgICArICIsIGNlcnRQYXRoIGlzIG51bGwgYW5kIGluZGV4IGlzIC0xIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvcgorICAgICAqIDxjb2RlPkNlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlLCBDZXJ0UGF0aCwgaW50KTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBub3QgbnVsbCA8Y29kZT5tc2c8L2NvZGU+IG5vdCBudWxsCisgICAgICogPGNvZGU+Y2VydFBhdGg8L2NvZGU+IG5vdCBudWxsIDxjb2RlPmluZGV4PC9jb2RlPjwgLTEgfHwgPj0KKyAgICAgKiBjZXJ0UGF0aC5nZXRDZXJ0aWZpY2F0ZXMoKS5zaXplKCkgdGhyb3dzOiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uMTMoKSB7CisgICAgICAgIG15Q2VydFBhdGggbWNwID0gbmV3IG15Q2VydFBhdGgoIlguNTA5IiwgIiIpOworICAgICAgICBDZXJ0UGF0aCBjcCA9IG1jcC5nZXQoIlguNTA5Iik7CisgICAgICAgIGludFtdIGluZHggPSB7IC0yLCAtMTAwLCAwLCAxLCAxMDAsIEludGVnZXIuTUFYX1ZBTFVFLAorICAgICAgICAgICAgICAgIEludGVnZXIuTUlOX1ZBTFVFIH07CisgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgaW5keC5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgbmV3IENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKG1zZ3NbaV0sIHRDYXVzZSwgY3AsIGluZHhbal0pOworICAgICAgICAgICAgICAgICAgICBmYWlsKCJJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIGFzIGV4cGVjdGVkLiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIG1zZzogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgbXNnc1tpXQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiwgY2VydFBhdGggaXMgbnVsbCBhbmQgaW5kZXggaXMgIiArIGluZHhbal0pOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yCisgICAgICogPGNvZGU+Q2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUsIENlcnRQYXRoLCBpbnQpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IG5vdCBudWxsIDxjb2RlPm1zZzwvY29kZT4gbm90IG51bGwKKyAgICAgKiA8Y29kZT5jZXJ0UGF0aDwvY29kZT4gbm90IG51bGwgPGNvZGU+aW5kZXg8L2NvZGU+PAorICAgICAqIGNlcnRQYXRoLmdldENlcnRpZmljYXRlcygpLnNpemUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbjE0KCkgeworICAgICAgICBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbiB0RTsKKyAgICAgICAgbXlDZXJ0UGF0aCBtY3AgPSBuZXcgbXlDZXJ0UGF0aCgiWC41MDkiLCAiIik7CisgICAgICAgIENlcnRQYXRoIGNwID0gbWNwLmdldCgiWC41MDkiKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRFID0gbmV3IENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKG1zZ3NbaV0sIHRDYXVzZSwgY3AsIC0xKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICAgICAgaWYgKG1zZ3NbaV0ubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IGNvbnRhaW4gIi5jb25jYXQobXNnc1tpXSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TS5pbmRleE9mKG1zZ3NbaV0pICE9IC0xKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFnZXRNLmVxdWFscyhtc2dzW2ldKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIHNob3VsZCBjb250YWluICIuY29uY2F0KHRvUyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE0uaW5kZXhPZih0b1MpICE9IC0xKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RS5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoImdldENlcnRQYXRoKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RQorICAgICAgICAgICAgICAgICAgICAgICAgLmdldENlcnRQYXRoKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygKKyAgICAgICAgICAgICAgICAgICAgICAgICJnZXRDZXJ0UGF0aCgpIG11c3QgcmV0dXJuICIuY29uY2F0KGNwLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0Q2VydFBhdGgoKSwgY3ApOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0SW5kZXgoKSBtdXN0IHJldHVybiAtMSIsIHRFLmdldEluZGV4KCksIC0xKTsKKworICAgICAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHdhcyB0aHJvd24uICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldENlcnRQYXRoKCk8L2NvZGU+LiBSZXR1cm5zIHRoZSBjZXJ0aWZpY2F0aW9uIHBhdGgKKyAgICAgKiB0aGF0IHdhcyBiZWluZyB2YWxpZGF0ZWQgd2hlbiB0aGUgZXhjZXB0aW9uIHdhcyB0aHJvd24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uMTUoKSB7CisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHRFID0gbmV3IENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldENlcnRQYXRoKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRDZXJ0UGF0aCgpKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2VydFBhdGgoKSBtdXN0IHJldHVybiBudWxsICIsIHRFLmdldENlcnRQYXRoKCkpOworICAgICAgICB9CisKKyAgICAgICAgVGhyb3dhYmxlIGNhdXNlID0gbnVsbDsKKyAgICAgICAgdEUgPSBuZXcgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24oY2F1c2UpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDZXJ0UGF0aCgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0Q2VydFBhdGgoKSk7CisKKyAgICAgICAgdEUgPSBuZXcgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24odENhdXNlKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2VydFBhdGgoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldENlcnRQYXRoKCkpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24obXNnc1tpXSwgdENhdXNlKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldENlcnRQYXRoKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENlcnRQYXRoKCkpOworICAgICAgICB9CisKKyAgICAgICAgdEUgPSBuZXcgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24obnVsbCwgbnVsbCwgbnVsbCwgLTEpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDZXJ0UGF0aCgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDZXJ0UGF0aCgpKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdEUgPSBuZXcgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24obXNnc1tpXSwgdENhdXNlLCBudWxsLCAtMSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2VydFBhdGgoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2VydFBhdGgoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIG15Q2VydFBhdGggbWNwID0gbmV3IG15Q2VydFBhdGgoIlguNTA5IiwgIiIpOworICAgICAgICBDZXJ0UGF0aCBjcCA9IG1jcC5nZXQoIlguNTA5Iik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0RSA9IG5ldyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbihtc2dzW2ldLCB0Q2F1c2UsIGNwLCAtMSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2VydFBhdGgoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0Q2VydFBhdGgoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKAorICAgICAgICAgICAgICAgICAgICAgICAgImdldENlcnRQYXRoKCkgbXVzdCByZXR1cm4gIi5jb25jYXQoY3AudG9TdHJpbmcoKSksIHRFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRDZXJ0UGF0aCgpLCBjcCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gd2FzIHRocm93bi4gIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBlLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5kZXgoKTwvY29kZT4uIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBjZXJ0aWZpY2F0ZQorICAgICAqIGluIHRoZSBjZXJ0aWZpY2F0aW9uIHBhdGggdGhhdCBjYXVzZWQgdGhlIGV4Y2VwdGlvbiB0byBiZSB0aHJvd24uIE5vdGUKKyAgICAgKiB0aGF0IHRoZSBsaXN0IG9mIGNlcnRpZmljYXRlcyBpbiBhIENlcnRQYXRoIGlzIHplcm8gYmFzZWQuIElmIG5vIGluZGV4CisgICAgICogaGFzIGJlZW4gc2V0LCAtMSBpcyByZXR1cm5lZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24xNigpIHsKKyAgICAgICAgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24gdEUgPSBuZXcgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24oKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRJbmRleCgpIG11c3QgYmUgZXF1YWxzIC0xIiwgLTEsIHRFLmdldEluZGV4KCkpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldEluZGV4KCkgbXVzdCBiZSBlcXVhbHMgLTEiLCAtMSwgdEUuZ2V0SW5kZXgoKSk7CisgICAgICAgIH0KKworICAgICAgICBUaHJvd2FibGUgY2F1c2UgPSBudWxsOworICAgICAgICB0RSA9IG5ldyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbihjYXVzZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ2V0SW5kZXgoKSBtdXN0IGJlIGVxdWFscyAtMSIsIC0xLCB0RS5nZXRJbmRleCgpKTsKKworICAgICAgICB0RSA9IG5ldyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbih0Q2F1c2UpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldEluZGV4KCkgbXVzdCBiZSBlcXVhbHMgLTEiLCAtMSwgdEUuZ2V0SW5kZXgoKSk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbihtc2dzW2ldLCB0Q2F1c2UpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRJbmRleCgpIG11c3QgYmUgZXF1YWxzIC0xIiwgLTEsIHRFLmdldEluZGV4KCkpOworICAgICAgICB9CisKKyAgICAgICAgdEUgPSBuZXcgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24obnVsbCwgbnVsbCwgbnVsbCwgLTEpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldEluZGV4KCkgbXVzdCBiZSBlcXVhbHMgLTEiLCAtMSwgdEUuZ2V0SW5kZXgoKSk7CisKKyAgICAgICAgbXlDZXJ0UGF0aCBtY3AgPSBuZXcgbXlDZXJ0UGF0aCgiWC41MDkiLCAiIik7CisgICAgICAgIENlcnRQYXRoIGNwID0gbWNwLmdldCgiWC41MDkiKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRFID0gbmV3IENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uKG1zZ3NbaV0sIHRDYXVzZSwgY3AsIC0xKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRJbmRleCgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRDZXJ0UGF0aCgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoCisgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0SW5kZXgoKSBtdXN0IHJldHVybiAiLmNvbmNhdChjcC50b1N0cmluZygpKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldENlcnRQYXRoKCksIGNwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3YXMgdGhyb3duLiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIGNsYXNzIG15Q2VydFBhdGggZXh0ZW5kcyBDZXJ0UGF0aCB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTg3MTYwMzA0NzI0NDcyMjUxMUw7CisKKyAgICAgICAgcHVibGljIExpc3Q8Q2VydGlmaWNhdGU+IGdldENlcnRpZmljYXRlcygpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVmVjdG9yPENlcnRpZmljYXRlPigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBieXRlWzBdOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKFN0cmluZyBzKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbMF07CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSXRlcmF0b3I8U3RyaW5nPiBnZXRFbmNvZGluZ3MoKSB7CisgICAgICAgICAgICByZXR1cm4gKEl0ZXJhdG9yPFN0cmluZz4pIChuZXcgU3RyaW5nVG9rZW5pemVyKCJzcyBzcyBzcyBzcyIpKTsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCBteUNlcnRQYXRoKFN0cmluZyBzKSB7CisgICAgICAgICAgICBzdXBlcihzKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBDZXJ0UGF0aCBnZXQoU3RyaW5nIHMpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgbXlDZXJ0UGF0aChzKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBteUNlcnRQYXRoKFN0cmluZyBzLCBTdHJpbmcgczEpIHsKKyAgICAgICAgICAgIHN1cGVyKHMpOworICAgICAgICB9CisKKyAgICB9Cit9CisKKwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhWYWxpZGF0b3JTcGlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aFZhbGlkYXRvclNwaVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNjlhM2U1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhWYWxpZGF0b3JTcGlUZXN0LmphdmEKQEAgLTAsMCArMSw2NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aFBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aFZhbGlkYXRvclJlc3VsdDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhWYWxpZGF0b3JTcGk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0Lk15Q2VydFBhdGhWYWxpZGF0b3JTcGk7CisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5DZXJ0UGF0aFZhbGlkYXRvclNwaTwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIENlcnRQYXRoVmFsaWRhdG9yU3BpVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRQYXRoVmFsaWRhdG9yU3BpPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246CisgICAgICogY29uc3RydWN0cyBDZXJ0UGF0aFZhbGlkYXRvclNwaQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0UGF0aFZhbGlkYXRvclNwaTAxKCkgdGhyb3dzIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yU3BpIGNlcnRQYXRoVmFsaWQgPSBuZXcgTXlDZXJ0UGF0aFZhbGlkYXRvclNwaSgpOworICAgICAgICBDZXJ0UGF0aFBhcmFtZXRlcnMgcGFyYW1zID0gbnVsbDsKKyAgICAgICAgQ2VydFBhdGggY2VydFBhdGggPSBudWxsOworICAgICAgICBDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCBjcHZSZXN1bHQgPSBjZXJ0UGF0aFZhbGlkLmVuZ2luZVZhbGlkYXRlKAorICAgICAgICAgICAgICAgIGNlcnRQYXRoLCBwYXJhbXMpOworICAgICAgICBhc3NlcnROdWxsKCJOb3QgbnVsbCBDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCIsIGNwdlJlc3VsdCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0UGF0aFZhbGlkLmVuZ2luZVZhbGlkYXRlKGNlcnRQYXRoLCBwYXJhbXMpOworICAgICAgICAgICAgZmFpbCgiQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0UGF0aFZhbGlkLmVuZ2luZVZhbGlkYXRlKGNlcnRQYXRoLCBwYXJhbXMpOworICAgICAgICAgICAgZmFpbCgiSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRTdG9yZTFUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0U3RvcmUxVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjMjkwZTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0U3RvcmUxVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTA5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LlNwaUVuZ1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuTXlDZXJ0U3RvcmVQYXJhbWV0ZXJzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuTXlDZXJ0U3RvcmVTcGk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFN0b3JlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0U3RvcmVQYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0U3RvcmVTcGk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5MREFQQ2VydFN0b3JlUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+Q2VydFN0b3JlPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kCisgKiBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIENlcnRTdG9yZTFUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgc3J2Q2VydFN0b3JlID0gIkNlcnRTdG9yZSI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZGVmYXVsdFR5cGUgPSAiTERBUCI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgW10gdmFsaWRWYWx1ZXMgPSAgeworICAgICAgICAgICAgIkxEQVAiLCAibGRhcCIsICJMZGFwIiwgImxEQVAiLCAibERhUCIgfTsKKyAgICBwdWJsaWMgc3RhdGljICBTdHJpbmcgW10gdmFsaWRWYWx1ZXNDID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBbXSBpbnZhbGlkVmFsdWVzID0gU3BpRW5nVXRpbHMuaW52YWxpZFZhbHVlczsKKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gTERBUFN1cHBvcnQgPSBmYWxzZTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ29sbGVjdGlvblR5cGUgPSAiQ29sbGVjdGlvbiI7CisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBDb2xsZWN0aW9uU3VwcG9ydCA9IGZhbHNlOworCisgICAgcHJpdmF0ZSBzdGF0aWMgUHJvdmlkZXIgZGVmYXVsdFByb3ZpZGVyOworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZWZhdWx0UHJvdmlkZXJOYW1lOworICAgIHByaXZhdGUgc3RhdGljIFByb3ZpZGVyIGRlZmF1bHRQcm92aWRlckNvbDsKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZGVmYXVsdFByb3ZpZGVyQ29sTmFtZTsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBOb3RTdXBwb3J0TXNnID0gIiI7CisKKyAgICBzdGF0aWMgeworICAgICAgICBkZWZhdWx0UHJvdmlkZXIgPSBTcGlFbmdVdGlscy5pc1N1cHBvcnQoZGVmYXVsdFR5cGUsCisgICAgICAgICAgICAgICAgc3J2Q2VydFN0b3JlKTsKKyAgICAgICAgTERBUFN1cHBvcnQgPSAoZGVmYXVsdFByb3ZpZGVyICE9IG51bGwpOworICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lID0gKExEQVBTdXBwb3J0ID8gZGVmYXVsdFByb3ZpZGVyLmdldE5hbWUoKSA6IG51bGwpOworICAgICAgICBOb3RTdXBwb3J0TXNnID0gIkxEQVAgYW5kIENvbGxlY3Rpb24gYWxnb3JpdGhtIGFyZSBub3Qgc3VwcG9ydGVkIjsKKworICAgICAgICBkZWZhdWx0UHJvdmlkZXJDb2wgPSBTcGlFbmdVdGlscy5pc1N1cHBvcnQoQ29sbGVjdGlvblR5cGUsCisgICAgICAgICAgICAgICAgc3J2Q2VydFN0b3JlKTsKKyAgICAgICAgQ29sbGVjdGlvblN1cHBvcnQgPSAoZGVmYXVsdFByb3ZpZGVyQ29sICE9IG51bGwpOworICAgICAgICBkZWZhdWx0UHJvdmlkZXJDb2xOYW1lID0gKENvbGxlY3Rpb25TdXBwb3J0ID8gZGVmYXVsdFByb3ZpZGVyQ29sLmdldE5hbWUoKSA6IG51bGwpOworICAgICAgICBpZiAoQ29sbGVjdGlvblN1cHBvcnQpIHsKKyAgICAgICAgICAgIHZhbGlkVmFsdWVzQyA9IG5ldyBTdHJpbmdbM107CisgICAgICAgICAgICB2YWxpZFZhbHVlc0NbMF0gPSBDb2xsZWN0aW9uVHlwZTsKKyAgICAgICAgICAgIHZhbGlkVmFsdWVzQ1sxXSA9IENvbGxlY3Rpb25UeXBlLnRvVXBwZXJDYXNlKCk7CisgICAgICAgICAgICB2YWxpZFZhbHVlc0NbMl0gPSBDb2xsZWN0aW9uVHlwZS50b0xvd2VyQ2FzZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBQcm92aWRlciBkUHJvdiA9IG51bGw7CisgICAgcHJpdmF0ZSBTdHJpbmcgZE5hbWUgPSBudWxsOworICAgIHByaXZhdGUgU3RyaW5nIGRUeXBlID0gbnVsbDsKKyAgICBwcml2YXRlIENlcnRTdG9yZVBhcmFtZXRlcnMgZFBhcmFtcyA9IG51bGw7CisgICAgcHJpdmF0ZSBTdHJpbmdbXSBkVmFsaWQ7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaW5pdFBhcmFtcygpIHsKKyAgICAgICAgaWYgKCFMREFQU3VwcG9ydCAmJiAhQ29sbGVjdGlvblN1cHBvcnQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgZFBhcmFtcyA9IChDb2xsZWN0aW9uU3VwcG9ydCA/IChDZXJ0U3RvcmVQYXJhbWV0ZXJzKW5ldyBDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycygpIDoKKyAgICAgICAgICAgIChDZXJ0U3RvcmVQYXJhbWV0ZXJzKW5ldyBMREFQQ2VydFN0b3JlUGFyYW1ldGVycygpKTsKKyAgICAgICAgZFR5cGUgPSAoQ29sbGVjdGlvblN1cHBvcnQgPyBDb2xsZWN0aW9uVHlwZSA6IGRlZmF1bHRUeXBlICk7CisgICAgICAgIGRQcm92ID0gKENvbGxlY3Rpb25TdXBwb3J0ID8gZGVmYXVsdFByb3ZpZGVyQ29sIDogZGVmYXVsdFByb3ZpZGVyICk7CisgICAgICAgIGROYW1lID0gKENvbGxlY3Rpb25TdXBwb3J0ID8gZGVmYXVsdFByb3ZpZGVyQ29sTmFtZSA6IGRlZmF1bHRQcm92aWRlck5hbWUgKTsKKyAgICAgICAgZFZhbGlkID0gKENvbGxlY3Rpb25TdXBwb3J0ID8gdmFsaWRWYWx1ZXNDIDogdmFsaWRWYWx1ZXMgKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIHByaXZhdGUgQ2VydFN0b3JlIFtdIGNyZWF0ZUNTKCkgeworICAgICAgICBpZiAoIUxEQVBTdXBwb3J0ICYmICFDb2xsZWN0aW9uU3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0U3RvcmUgW10gc3MgPSBuZXcgQ2VydFN0b3JlWzNdOworICAgICAgICAgICAgc3NbMF0gPSBDZXJ0U3RvcmUuZ2V0SW5zdGFuY2UoZFR5cGUsIGRQYXJhbXMpOworICAgICAgICAgICAgc3NbMV0gPSBDZXJ0U3RvcmUuZ2V0SW5zdGFuY2UoZFR5cGUsIGRQYXJhbXMsIGRQcm92KTsKKyAgICAgICAgICAgIHNzWzJdID0gQ2VydFN0b3JlLmdldEluc3RhbmNlKGRUeXBlLCBkUGFyYW1zLCBkTmFtZSk7CisgICAgICAgICAgICByZXR1cm4gc3M7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0RGVmYXVsdFR5cGUoKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHNlY3VyaXR5IHByb3BlcnR5ICJjZXJ0c3RvcmUudHlwZSIgb3IgIkxEQVAiCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRTdG9yZTAxKCkgeworICAgICAgICBpZiAoIUxEQVBTdXBwb3J0KSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIGR0ID0gQ2VydFN0b3JlLmdldERlZmF1bHRUeXBlKCk7CisgICAgICAgIFN0cmluZyBzbiA9IFNlY3VyaXR5LmdldFByb3BlcnR5KCJjZXJ0c3RvcmUudHlwZSIpOworICAgICAgICBTdHJpbmcgZGVmID0gIlByb2JhLmNlcnQuc3RvcmUudHlwZSI7CisgICAgICAgIGlmIChzbiA9PSBudWxsKSB7CisgICAgICAgICAgICBzbiA9IGRlZmF1bHRUeXBlOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoIkRlZmF1bHQgdHlwZSBoYXZlIG5vdCBiZSBudWxsIiwgZHQpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBkZWZhdWx0IHR5cGUiLCBkdCwgc24pOworCisgICAgICAgIFNlY3VyaXR5LnNldFByb3BlcnR5KCJjZXJ0c3RvcmUudHlwZSIsIGRlZik7CisgICAgICAgIGR0ID0gQ2VydFN0b3JlLmdldERlZmF1bHRUeXBlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRlZmF1bHQgdHlwZSIsIGR0LCBkZWYpOworICAgICAgICBTZWN1cml0eS5zZXRQcm9wZXJ0eSgiY2VydHN0b3JlLnR5cGUiLCBzbik7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRlZmF1bHQgdHlwZSIsIFNlY3VyaXR5LmdldFByb3BlcnR5KCJjZXJ0c3RvcmUudHlwZSIpLCBzbiApOworICAgIH0KKyAgICAvKioKKyAgICAgKiBUZXN0IGZvcgorICAgICAqIDxjb2RlPkNlcnRTdG9yZTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgQ2VydFN0b3JlIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0U3RvcmUwMigpIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uLCBDZXJ0U3RvcmVFeGNlcHRpb24geworICAgICAgICBpZiAoIWluaXRQYXJhbXMoKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIE15Q2VydFN0b3JlUGFyYW1ldGVycyBwcCA9IG5ldyBNeUNlcnRTdG9yZVBhcmFtZXRlcnMoKTsKKyAgICAgICAgQ2VydFN0b3JlU3BpIHNwaSA9IG5ldyBNeUNlcnRTdG9yZVNwaShwcCk7CisgICAgICAgIENlcnRTdG9yZSBjZXJ0UyA9IG5ldyBteUNlcnRTdG9yZShzcGksIGRQcm92LCBkVHlwZSwgcHApOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBhbGdvcml0aG0iLCBjZXJ0Uy5nZXRUeXBlKCksIGRUeXBlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBjZXJ0Uy5nZXRQcm92aWRlcigpLCBkUHJvdik7CisgICAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCBwYXJhbWV0ZXJzIiwgY2VydFMuZ2V0Q2VydFN0b3JlUGFyYW1ldGVycygpCisgICAgICAgICAgICAgICAgaW5zdGFuY2VvZiBNeUNlcnRTdG9yZVBhcmFtZXRlcnMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydFMuZ2V0Q2VydGlmaWNhdGVzKG51bGwpOworICAgICAgICAgICAgZmFpbCgiQ2VydFN0b3JlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgY2VydFMgPSBuZXcgbXlDZXJ0U3RvcmUobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCBhbGdvcml0aG0iLCBjZXJ0Uy5nZXRUeXBlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBjZXJ0Uy5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiSW5jb3JyZWN0IHBhcmFtZXRlcnMiLCBjZXJ0Uy5nZXRDZXJ0U3RvcmVQYXJhbWV0ZXJzKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydFMuZ2V0Q2VydGlmaWNhdGVzKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIHR5cGUsIENlcnRTdG9yZVBhcmFtZXRlcnMgcGFyYW1zKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOgorICAgICAqIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIHR5cGUgaXMgbnVsbAorICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiB0eXBlIGlzIGluY29ycmVjdDsKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFN0b3JlMDMoKSB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaW5pdFBhcmFtcygpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRTdG9yZS5nZXRJbnN0YW5jZShudWxsLCBkUGFyYW1zKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHR5cGUgaXMgbnVsbCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrICkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDZXJ0U3RvcmUuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwgZFBhcmFtcyk7CisgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIHR5cGUsIENlcnRTdG9yZVBhcmFtZXRlcnMgcGFyYW1zKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm4gQ2VydFN0b3JlIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0U3RvcmUwNSgpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpbml0UGFyYW1zKCkpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBDZXJ0U3RvcmUgY2VydFM7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZFZhbGlkLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjZXJ0UyA9IENlcnRTdG9yZS5nZXRJbnN0YW5jZShkVmFsaWRbaV0sIGRQYXJhbXMpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdHlwZSIsIGNlcnRTLmdldFR5cGUoKSwgZFZhbGlkW2ldKTsKKyAgICAgICAgICAgIGNlcnRTLmdldENlcnRTdG9yZVBhcmFtZXRlcnMoKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciBtZXRob2QKKyAgICAgKiA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgdHlwZSwgQ2VydFN0b3JlUGFyYW1ldGVycyBwYXJhbXMsIFN0cmluZyBwcm92aWRlcik8L2NvZGU+CisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbCBvciBlbXB0eQorICAgICAqCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRTdG9yZTA2KCkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAoIWluaXRQYXJhbXMoKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFN0cmluZyBwcm92aWRlciA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZFZhbGlkLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRTdG9yZS5nZXRJbnN0YW5jZShkVmFsaWRbaV0sIGRQYXJhbXMsIHByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRTdG9yZS5nZXRJbnN0YW5jZShkVmFsaWRbaV0sIGRQYXJhbXMsICIiKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgLyoqCisgICAgICogVGVzdCBmb3IgbWV0aG9kCisgICAgICogPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIHR5cGUsIENlcnRTdG9yZVBhcmFtZXRlcnMgcGFyYW1zLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaGFzIGludmFsaWQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFN0b3JlMDcoKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaW5pdFBhcmFtcygpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkVmFsaWQubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGZvciAoaW50IGogPSAxOyBqIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGorKyApIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBDZXJ0U3RvcmUuZ2V0SW5zdGFuY2UoZFZhbGlkW2ldLCBkUGFyYW1zLCBpbnZhbGlkVmFsdWVzW2pdKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIC8qKgorICAgICAqIFRlc3QgZm9yIG1ldGhvZAorICAgICAqIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyB0eXBlLCBDZXJ0U3RvcmVQYXJhbWV0ZXJzIHBhcmFtcywgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gdHlwZSBpcyBudWxsCisgICAgICogdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB3aGVuIHR5cGUgaXMgaW5jb3JyZWN0OworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0U3RvcmUwOCgpIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworICAgICAgICBpZiAoIWluaXRQYXJhbXMoKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDZXJ0U3RvcmUuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwgZFBhcmFtcywgZE5hbWUpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0U3RvcmUuZ2V0SW5zdGFuY2UobnVsbCwgZFBhcmFtcywgZE5hbWUpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gdHlwZSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIG1ldGhvZAorICAgICAqIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyB0eXBlLCBDZXJ0U3RvcmVQYXJhbWV0ZXJzIHBhcmFtcywgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybiBDZXJ0U3RvcmUgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRTdG9yZTEwKCkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpbml0UGFyYW1zKCkpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBDZXJ0U3RvcmUgY2VydFM7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZFZhbGlkLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjZXJ0UyA9IENlcnRTdG9yZS5nZXRJbnN0YW5jZShkVmFsaWRbaV0sIGRQYXJhbXMsIGROYW1lKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHR5cGUiLCBjZXJ0Uy5nZXRUeXBlKCksIGRWYWxpZFtpXSk7CisgICAgICAgICAgICBjZXJ0Uy5nZXRDZXJ0U3RvcmVQYXJhbWV0ZXJzKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciBtZXRob2QKKyAgICAgKiA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgdHlwZSwgQ2VydFN0b3JlUGFyYW1ldGVycyBwYXJhbXMsIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBBc3NlcnRpb246IHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRTdG9yZTExKCkgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoIWluaXRQYXJhbXMoKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyID0gbnVsbDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkVmFsaWQubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydFN0b3JlLmdldEluc3RhbmNlKGRWYWxpZFtpXSwgZFBhcmFtcywgcHJvdmlkZXIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgdHlwZSwgQ2VydFN0b3JlUGFyYW1ldGVycyBwYXJhbXMsIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOgorICAgICAqIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIHR5cGUgaXMgbnVsbAorICAgICAqIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gd2hlbiB0eXBlIGlzIGluY29ycmVjdDsKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFN0b3JlMTIoKSB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaW5pdFBhcmFtcygpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRTdG9yZS5nZXRJbnN0YW5jZShudWxsLCBkUGFyYW1zLCBkUHJvdik7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBvciBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiB0eXBlIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKyApIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydFN0b3JlLmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0sIGRQYXJhbXMsIGRQcm92KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciBtZXRob2QKKyAgICAgKiA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgdHlwZSwgQ2VydFN0b3JlUGFyYW1ldGVycyBwYXJhbXMsIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybiBDZXJ0U3RvcmUgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRTdG9yZTE0KCkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBpZiAoIWluaXRQYXJhbXMoKSkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIENlcnRTdG9yZSBjZXJ0UzsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkVmFsaWQubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNlcnRTID0gQ2VydFN0b3JlLmdldEluc3RhbmNlKGRWYWxpZFtpXSwgZFBhcmFtcywgZFByb3YpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdHlwZSIsIGNlcnRTLmdldFR5cGUoKSwgZFZhbGlkW2ldKTsKKyAgICAgICAgICAgIGNlcnRTLmdldENlcnRTdG9yZVBhcmFtZXRlcnMoKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciBtZXRob2RzCisgICAgICogPGNvZGU+Z2V0Q2VydGlmaWNhdGVzKENlcnRTZWxlY3RvciBzZWxlY3Rvcik8L2NvZGU+CisgICAgICogPGNvZGU+Z2V0Q1JMcyhDUkxTZWxlY3RvciBzZWxlY3Rvcik8L2NvZGU+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIGVtcHR5IENvbGxlY3Rpb24gd2hlbiBzZWxlY3RvciBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRTdG9yZTE1KCkgdGhyb3dzIENlcnRTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaW5pdFBhcmFtcygpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgQ2VydFN0b3JlIFtdIGNlcnRTID0gY3JlYXRlQ1MoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ2VydFN0b3JlIG9iamVjdCB3ZXJlIG5vdCBjcmVhdGVkIiwgY2VydFMpOworICAgICAgICBDb2xsZWN0aW9uPD8+IGNvbGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2VydFMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNvbGwgPSBjZXJ0U1tpXS5nZXRDZXJ0aWZpY2F0ZXMobnVsbCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJSZXN1bHQgY29sbGVjdGlvbiBub3QgZW1wdHkiLGNvbGwuaXNFbXB0eSgpKTsKKyAgICAgICAgICAgIGNvbGwgPSBjZXJ0U1tpXS5nZXRDUkxzKG51bGwpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiUmVzdWx0IGNvbGxlY3Rpb24gbm90IGVtcHR5Iixjb2xsLmlzRW1wdHkoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRUeXBlKCk8L2NvZGU+IG1ldGhvZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0U3RvcmUxNigpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFpbml0UGFyYW1zKCkpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIENlcnRTdG9yZSBjZXJ0UzsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkVmFsaWQubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNlcnRTID0gQ2VydFN0b3JlLmdldEluc3RhbmNlKGRWYWxpZFtpXSwgZFBhcmFtcyk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB0eXBlIiwgY2VydFMuZ2V0VHlwZSgpLCBkVmFsaWRbaV0pOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNlcnRTID0gQ2VydFN0b3JlLmdldEluc3RhbmNlKGRWYWxpZFtpXSwgZFBhcmFtcywKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlckNvbCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdHlwZSIsIGNlcnRTLmdldFR5cGUoKSwgZFZhbGlkW2ldKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjZXJ0UyA9IENlcnRTdG9yZS5nZXRJbnN0YW5jZShkVmFsaWRbaV0sIGRQYXJhbXMsCisgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJDb2xOYW1lKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB0eXBlIiwgY2VydFMuZ2V0VHlwZSgpLCBkVmFsaWRbaV0pOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRQcm92aWRlcigpPC9jb2RlPiBtZXRob2QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFN0b3JlMTcoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaW5pdFBhcmFtcygpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBDZXJ0U3RvcmUgY2VydFM7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZFZhbGlkLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNlcnRTID0gQ2VydFN0b3JlLmdldEluc3RhbmNlKGRWYWxpZFtpXSwgZFBhcmFtcywKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlckNvbCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBjZXJ0Uy5nZXRQcm92aWRlcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyQ29sKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjZXJ0UyA9IENlcnRTdG9yZS5nZXRJbnN0YW5jZShkVmFsaWRbaV0sIGRQYXJhbXMsCisgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJDb2xOYW1lKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsIGNlcnRTLmdldFByb3ZpZGVyKCksCisgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJDb2wpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9Cit9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0Q2VydFN0b3JlUGFyYW1ldGVycygpPC9jb2RlPiBtZXRob2QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFN0b3JlMTgoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghaW5pdFBhcmFtcygpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBDZXJ0U3RvcmUgY2VydFM7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZFZhbGlkLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjZXJ0UyA9IENlcnRTdG9yZS5nZXRJbnN0YW5jZShkVmFsaWRbaV0sIGRQYXJhbXMpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcGFyYW1ldGVycyIsCisgICAgICAgICAgICAgICAgICAgICgoQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMpIGNlcnRTCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldENlcnRTdG9yZVBhcmFtZXRlcnMoKSkuZ2V0Q29sbGVjdGlvbigpLAorICAgICAgICAgICAgICAgICAgICAoKENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzKSBkUGFyYW1zKS5nZXRDb2xsZWN0aW9uKCkpOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNlcnRTID0gQ2VydFN0b3JlLmdldEluc3RhbmNlKGRWYWxpZFtpXSwgZFBhcmFtcywKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlckNvbCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcGFyYW1ldGVycyIsCisgICAgICAgICAgICAgICAgICAgICAgICAoKENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzKSBjZXJ0UworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0Q2VydFN0b3JlUGFyYW1ldGVycygpKS5nZXRDb2xsZWN0aW9uKCksCisgICAgICAgICAgICAgICAgICAgICAgICAoKENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzKSBkUGFyYW1zKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0Q29sbGVjdGlvbigpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjZXJ0UyA9IENlcnRTdG9yZS5nZXRJbnN0YW5jZShkVmFsaWRbaV0sIGRQYXJhbXMsCisgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJDb2xOYW1lKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwYXJhbWV0ZXJzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICgoQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMpIGNlcnRTCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRDZXJ0U3RvcmVQYXJhbWV0ZXJzKCkpLmdldENvbGxlY3Rpb24oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICgoQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMpIGRQYXJhbXMpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRDb2xsZWN0aW9uKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CisKKy8qKgorICogQWRkaXRpb25hbCBjbGFzcyB0byB2ZXJpZnkgQ2VydFN0b3JlIGNvbnN0cnVjdG9yCisgKi8KK2NsYXNzIG15Q2VydFN0b3JlIGV4dGVuZHMgQ2VydFN0b3JlIHsKKyAgICBwdWJsaWMgbXlDZXJ0U3RvcmUoQ2VydFN0b3JlU3BpIHNwaSwgUHJvdmlkZXIgcHJvdiwgU3RyaW5nIHR5cGUsIENlcnRTdG9yZVBhcmFtZXRlcnMgcGFyYW1zKSB7CisgICAgICAgIHN1cGVyKHNwaSwgcHJvdiwgdHlwZSwgcGFyYW1zKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0U3RvcmUyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFN0b3JlMlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Yjg1MmQ3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFN0b3JlMlRlc3QuamF2YQpAQCAtMCwwICsxLDM3OSBAQAorcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DUkw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNSTFNlbGVjdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0U2VsZWN0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFN0b3JlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0U3RvcmVQYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0U3RvcmVTcGk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CisKK3B1YmxpYyBjbGFzcyBDZXJ0U3RvcmUyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDRVJUX1NUT1JFX1BST1ZJREVSX05BTUUgPSAiVGVzdENlcnRTdG9yZVByb3ZpZGVyIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0VSVF9TVE9SRV9OQU1FID0gIlRlc3RDZXJ0U3RvcmUiOworCisgICAgUHJvdmlkZXIgcHJvdmlkZXI7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBwcm92aWRlciA9IG5ldyBNeUNlcnRTdG9yZVByb3ZpZGVyKCk7CisgICAgICAgIFNlY3VyaXR5LmFkZFByb3ZpZGVyKHByb3ZpZGVyKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcihDRVJUX1NUT1JFX1BST1ZJREVSX05BTUUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZVN0cmluZ0NlcnRTdG9yZVBhcmFtZXRlcnMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0U3RvcmVQYXJhbWV0ZXJzIHBhcmFtZXRlcnMgPSBuZXcgTXlDZXJ0U3RvcmVQYXJhbWV0ZXJzKCk7CisgICAgICAgICAgICBDZXJ0U3RvcmUgY2VydFN0b3JlID0gQ2VydFN0b3JlLmdldEluc3RhbmNlKENFUlRfU1RPUkVfTkFNRSwKKyAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycyk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGNlcnRTdG9yZSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGNlcnRTdG9yZS5nZXRDZXJ0U3RvcmVQYXJhbWV0ZXJzKCkpOworICAgICAgICAgICAgYXNzZXJ0Tm90U2FtZShwYXJhbWV0ZXJzLCBjZXJ0U3RvcmUuZ2V0Q2VydFN0b3JlUGFyYW1ldGVycygpKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0U3RvcmUgY2VydFN0b3JlID0gQ2VydFN0b3JlLmdldEluc3RhbmNlKENFUlRfU1RPUkVfTkFNRSwgbnVsbCk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGNlcnRTdG9yZSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKGNlcnRTdG9yZS5nZXRDZXJ0U3RvcmVQYXJhbWV0ZXJzKCkpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRTdG9yZS5nZXRJbnN0YW5jZSgiVW5rbm93bkNlcnRTdG9yZSIsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydFN0b3JlLmdldEluc3RhbmNlKENFUlRfU1RPUkVfTkFNRSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IE15T3RoZXJDZXJ0U3RvcmVQYXJhbWV0ZXJzKCkpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlU3RyaW5nQ2VydFN0b3JlUGFyYW1ldGVyc1N0cmluZygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRTdG9yZVBhcmFtZXRlcnMgcGFyYW1ldGVycyA9IG5ldyBNeUNlcnRTdG9yZVBhcmFtZXRlcnMoKTsKKyAgICAgICAgICAgIENlcnRTdG9yZSBjZXJ0U3RvcmUgPSBDZXJ0U3RvcmUuZ2V0SW5zdGFuY2UoQ0VSVF9TVE9SRV9OQU1FLAorICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLCBDRVJUX1NUT1JFX1BST1ZJREVSX05BTUUpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChjZXJ0U3RvcmUpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChjZXJ0U3RvcmUuZ2V0Q2VydFN0b3JlUGFyYW1ldGVycygpKTsKKyAgICAgICAgICAgIGFzc2VydE5vdFNhbWUocGFyYW1ldGVycywgY2VydFN0b3JlLmdldENlcnRTdG9yZVBhcmFtZXRlcnMoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoQ0VSVF9TVE9SRV9QUk9WSURFUl9OQU1FLCBjZXJ0U3RvcmUuZ2V0UHJvdmlkZXIoKQorICAgICAgICAgICAgICAgICAgICAuZ2V0TmFtZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0U3RvcmUgY2VydFN0b3JlID0gQ2VydFN0b3JlLmdldEluc3RhbmNlKENFUlRfU1RPUkVfTkFNRSwgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgQ0VSVF9TVE9SRV9QUk9WSURFUl9OQU1FKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoY2VydFN0b3JlKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoY2VydFN0b3JlLmdldENlcnRTdG9yZVBhcmFtZXRlcnMoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoQ0VSVF9TVE9SRV9QUk9WSURFUl9OQU1FLCBjZXJ0U3RvcmUuZ2V0UHJvdmlkZXIoKQorICAgICAgICAgICAgICAgICAgICAuZ2V0TmFtZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0U3RvcmUuZ2V0SW5zdGFuY2UoIlVua25vd25DZXJ0U3RvcmUiLAorICAgICAgICAgICAgICAgICAgICBuZXcgTXlDZXJ0U3RvcmVQYXJhbWV0ZXJzKCksIENFUlRfU1RPUkVfUFJPVklERVJfTkFNRSk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0U3RvcmUuZ2V0SW5zdGFuY2UoQ0VSVF9TVE9SRV9OQU1FLCBudWxsLAorICAgICAgICAgICAgICAgICAgICAiVW5rbm93bkNlcnRTdG9yZVByb3ZpZGVyIik7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRTdG9yZS5nZXRJbnN0YW5jZShDRVJUX1NUT1JFX05BTUUsCisgICAgICAgICAgICAgICAgICAgIG5ldyBNeU90aGVyQ2VydFN0b3JlUGFyYW1ldGVycygpLCBDRVJUX1NUT1JFX1BST1ZJREVSX05BTUUpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZVN0cmluZ0NlcnRTdG9yZVBhcmFtZXRlcnNQcm92aWRlcigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRTdG9yZVBhcmFtZXRlcnMgcGFyYW1ldGVycyA9IG5ldyBNeUNlcnRTdG9yZVBhcmFtZXRlcnMoKTsKKyAgICAgICAgICAgIENlcnRTdG9yZSBjZXJ0U3RvcmUgPSBDZXJ0U3RvcmUuZ2V0SW5zdGFuY2UoQ0VSVF9TVE9SRV9OQU1FLAorICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLCBwcm92aWRlcik7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGNlcnRTdG9yZSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGNlcnRTdG9yZS5nZXRDZXJ0U3RvcmVQYXJhbWV0ZXJzKCkpOworICAgICAgICAgICAgYXNzZXJ0Tm90U2FtZShwYXJhbWV0ZXJzLCBjZXJ0U3RvcmUuZ2V0Q2VydFN0b3JlUGFyYW1ldGVycygpKTsKKyAgICAgICAgICAgIGFzc2VydFNhbWUocHJvdmlkZXIsIGNlcnRTdG9yZS5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0U3RvcmUgY2VydFN0b3JlID0gQ2VydFN0b3JlLmdldEluc3RhbmNlKENFUlRfU1RPUkVfTkFNRSwgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXIpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChjZXJ0U3RvcmUpOworICAgICAgICAgICAgYXNzZXJ0TnVsbChjZXJ0U3RvcmUuZ2V0Q2VydFN0b3JlUGFyYW1ldGVycygpKTsKKyAgICAgICAgICAgIGFzc2VydFNhbWUocHJvdmlkZXIsIGNlcnRTdG9yZS5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0U3RvcmUuZ2V0SW5zdGFuY2UoIlVua25vd25DZXJ0U3RvcmUiLCBudWxsLCBwcm92aWRlcik7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0U3RvcmUuZ2V0SW5zdGFuY2UoQ0VSVF9TVE9SRV9OQU1FLAorICAgICAgICAgICAgICAgICAgICBuZXcgTXlPdGhlckNlcnRTdG9yZVBhcmFtZXRlcnMoKSwgcHJvdmlkZXIpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q2VydGlmaWNhdGVzKCkgeworICAgICAgICBDZXJ0U3RvcmUgY2VydFN0b3JlID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRTdG9yZSA9IENlcnRTdG9yZS5nZXRJbnN0YW5jZShDRVJUX1NUT1JFX05BTUUsIG51bGwpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjZXJ0U3RvcmUpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDZXJ0aWZpY2F0ZT4gY2VydGlmaWNhdGVzID0gY2VydFN0b3JlLmdldENlcnRpZmljYXRlcyhudWxsKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoY2VydGlmaWNhdGVzKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydFN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29sbGVjdGlvbjw/IGV4dGVuZHMgQ2VydGlmaWNhdGU+IGNlcnRpZmljYXRlcyA9IGNlcnRTdG9yZS5nZXRDZXJ0aWZpY2F0ZXMobmV3IE15Q2VydFNlbGVjdG9yKCkpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChjZXJ0aWZpY2F0ZXMpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShjZXJ0aWZpY2F0ZXMuaXNFbXB0eSgpKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydFN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydFN0b3JlLmdldENlcnRpZmljYXRlcyhuZXcgTXlPdGhlckNlcnRTZWxlY3RvcigpKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIENlcnRTdG9yZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChDZXJ0U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDUkxzKCkgeworICAgICAgICBDZXJ0U3RvcmUgY2VydFN0b3JlID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRTdG9yZSA9IENlcnRTdG9yZS5nZXRJbnN0YW5jZShDRVJUX1NUT1JFX05BTUUsIG5ldyBNeUNlcnRTdG9yZVBhcmFtZXRlcnMoKSk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnROb3ROdWxsKGNlcnRTdG9yZSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENvbGxlY3Rpb248PyBleHRlbmRzIENSTD4gbHMgPSBjZXJ0U3RvcmUuZ2V0Q1JMcyhudWxsKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwobHMpOworICAgICAgICB9IGNhdGNoIChDZXJ0U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgidW5leHBlY3RlZCBleGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDUkw+IGxzID0gY2VydFN0b3JlLmdldENSTHMobmV3IE15Q1JMU2VsZWN0b3IoKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGxzKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUobHMuaXNFbXB0eSgpKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydFN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydFN0b3JlLmdldENSTHMobmV3IE15T3RoZXJDUkxTZWxlY3RvcigpKTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIENlcnRTdG9yZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChDZXJ0U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBNeUNlcnRTdG9yZVByb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXIgeworCisgICAgICAgIHByb3RlY3RlZCBNeUNlcnRTdG9yZVByb3ZpZGVyKCkgeworICAgICAgICAgICAgc3VwZXIoQ0VSVF9TVE9SRV9QUk9WSURFUl9OQU1FLCAxLjAsICJUZXN0IENlcnRTdG9yZSBQcm92aWRlciAxLjAiKTsKKyAgICAgICAgICAgIHB1dCgiQ2VydFN0b3JlLiIgKyBDRVJUX1NUT1JFX05BTUUsIE15Q2VydFN0b3JlU3BpLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgTXlDZXJ0U3RvcmVQYXJhbWV0ZXJzIGltcGxlbWVudHMgQ2VydFN0b3JlUGFyYW1ldGVycyB7CisgICAgICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IE15Q2VydFN0b3JlUGFyYW1ldGVycygpOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIE15T3RoZXJDZXJ0U3RvcmVQYXJhbWV0ZXJzIGltcGxlbWVudHMgQ2VydFN0b3JlUGFyYW1ldGVycyB7CisgICAgICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IE15Q2VydFN0b3JlUGFyYW1ldGVycygpOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIE15Q1JMU2VsZWN0b3IgaW1wbGVtZW50cyBDUkxTZWxlY3RvciB7CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gbWF0Y2goQ1JMIGNybCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgTXlDUkxTZWxlY3RvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIE15T3RoZXJDUkxTZWxlY3RvciBpbXBsZW1lbnRzIENSTFNlbGVjdG9yIHsKKyAgICAgICAgcHVibGljIGJvb2xlYW4gbWF0Y2goQ1JMIGNybCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgTXlPdGhlckNSTFNlbGVjdG9yKCk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBNeUNlcnRTZWxlY3RvciBpbXBsZW1lbnRzIENlcnRTZWxlY3RvciB7CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gbWF0Y2goQ2VydGlmaWNhdGUgY2VydCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgTXlDZXJ0U2VsZWN0b3IoKTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIE15T3RoZXJDZXJ0U2VsZWN0b3IgaW1wbGVtZW50cyBDZXJ0U2VsZWN0b3IgeworICAgICAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChDZXJ0aWZpY2F0ZSBjcmwpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IE15T3RoZXJDUkxTZWxlY3RvcigpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE15Q2VydFN0b3JlU3BpIGV4dGVuZHMgQ2VydFN0b3JlU3BpIHsKKworICAgICAgICBwdWJsaWMgTXlDZXJ0U3RvcmVTcGkoKSB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcihudWxsKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBNeUNlcnRTdG9yZVNwaShDZXJ0U3RvcmVQYXJhbWV0ZXJzIHBhcmFtcykKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcihwYXJhbXMpOworICAgICAgICAgICAgaWYgKHBhcmFtcyAhPSBudWxsICYmICEocGFyYW1zIGluc3RhbmNlb2YgTXlDZXJ0U3RvcmVQYXJhbWV0ZXJzKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgImludmFsaWQgcGFyYW1ldGVycyIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDUkw+IGVuZ2luZUdldENSTHMoQ1JMU2VsZWN0b3Igc2VsZWN0b3IpCisgICAgICAgICAgICAgICAgdGhyb3dzIENlcnRTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoc2VsZWN0b3IgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmICghKHNlbGVjdG9yIGluc3RhbmNlb2YgTXlDUkxTZWxlY3RvcikpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRTdG9yZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5TGlzdDxDUkw+KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgQ29sbGVjdGlvbjw/IGV4dGVuZHMgQ2VydGlmaWNhdGU+IGVuZ2luZUdldENlcnRpZmljYXRlcygKKyAgICAgICAgICAgICAgICBDZXJ0U2VsZWN0b3Igc2VsZWN0b3IpIHRocm93cyBDZXJ0U3RvcmVFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKHNlbGVjdG9yICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZiAoIShzZWxlY3RvciBpbnN0YW5jZW9mIE15Q2VydFNlbGVjdG9yKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydFN0b3JlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQXJyYXlMaXN0PENlcnRpZmljYXRlPigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFN0b3JlRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFN0b3JlRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU3MzZhMDIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0U3RvcmVFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSwxNzYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRTdG9yZUV4Y2VwdGlvbjsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+Q2VydFN0b3JlRXhjZXB0aW9uPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgQ2VydFN0b3JlRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIG1zZ3MgPSB7CisgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UiIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBUaHJvd2FibGUgdENhdXNlID0gbmV3IFRocm93YWJsZSgiVGhyb3dhYmxlIGZvciBleGNlcHRpb24iKTsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRTdG9yZUV4Y2VwdGlvbigpPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246CisgICAgICogY29uc3RydWN0cyBDZXJ0U3RvcmVFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0U3RvcmVFeGNlcHRpb24wMSgpIHsKKyAgICAgICAgQ2VydFN0b3JlRXhjZXB0aW9uIHRFID0gbmV3IENlcnRTdG9yZUV4Y2VwdGlvbigpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0U3RvcmVFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgQ2VydFN0b3JlRXhjZXB0aW9uIHdpdGggZGV0YWlsIG1lc3NhZ2UgbXNnLiBQYXJhbWV0ZXIKKyAgICAgKiA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0U3RvcmVFeGNlcHRpb24wMigpIHsKKyAgICAgICAgQ2VydFN0b3JlRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IENlcnRTdG9yZUV4Y2VwdGlvbihtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRTdG9yZUV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvciBBc3NlcnRpb246CisgICAgICogY29uc3RydWN0cyBDZXJ0U3RvcmVFeGNlcHRpb24gd2hlbiA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFN0b3JlRXhjZXB0aW9uMDMoKSB7CisgICAgICAgIFN0cmluZyBtc2cgPSBudWxsOworICAgICAgICBDZXJ0U3RvcmVFeGNlcHRpb24gdEUgPSBuZXcgQ2VydFN0b3JlRXhjZXB0aW9uKG1zZyk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRTdG9yZUV4Y2VwdGlvbihUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0U3RvcmVFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMKKyAgICAgKiBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRTdG9yZUV4Y2VwdGlvbjA0KCkgeworICAgICAgICBUaHJvd2FibGUgY2F1c2UgPSBudWxsOworICAgICAgICBDZXJ0U3RvcmVFeGNlcHRpb24gdEUgPSBuZXcgQ2VydFN0b3JlRXhjZXB0aW9uKGNhdXNlKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydFN0b3JlRXhjZXB0aW9uKFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRTdG9yZUV4Y2VwdGlvbiB3aGVuIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QKKyAgICAgKiBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRTdG9yZUV4Y2VwdGlvbjA1KCkgeworICAgICAgICBDZXJ0U3RvcmVFeGNlcHRpb24gdEUgPSBuZXcgQ2VydFN0b3JlRXhjZXB0aW9uKHRDYXVzZSk7CisgICAgICAgIGlmICh0RS5nZXRNZXNzYWdlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgc2hvdWxkIGNvbnRhaW4gIi5jb25jYXQodG9TKSwgKGdldE0KKyAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwgdEUKKyAgICAgICAgICAgICAgICAuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0U3RvcmVFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0U3RvcmVFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMKKyAgICAgKiBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0U3RvcmVFeGNlcHRpb24wNigpIHsKKyAgICAgICAgQ2VydFN0b3JlRXhjZXB0aW9uIHRFID0gbmV3IENlcnRTdG9yZUV4Y2VwdGlvbihudWxsLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0U3RvcmVFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0U3RvcmVFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMKKyAgICAgKiBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFN0b3JlRXhjZXB0aW9uMDcoKSB7CisgICAgICAgIENlcnRTdG9yZUV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBDZXJ0U3RvcmVFeGNlcHRpb24obXNnc1tpXSwgbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0U3RvcmVFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0U3RvcmVFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90CisgICAgICogbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFN0b3JlRXhjZXB0aW9uMDgoKSB7CisgICAgICAgIENlcnRTdG9yZUV4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0U3RvcmVFeGNlcHRpb24obnVsbCwgdENhdXNlKTsKKyAgICAgICAgaWYgKHRFLmdldE1lc3NhZ2UoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IHNob3VsZCAiLmNvbmNhdCh0b1MpLCAoZ2V0TQorICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgIC5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRTdG9yZUV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRTdG9yZUV4Y2VwdGlvbiB3aGVuIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QKKyAgICAgKiBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydFN0b3JlRXhjZXB0aW9uMDkoKSB7CisgICAgICAgIENlcnRTdG9yZUV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBDZXJ0U3RvcmVFeGNlcHRpb24obXNnc1tpXSwgdENhdXNlKTsKKyAgICAgICAgICAgIFN0cmluZyBnZXRNID0gdEUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgaWYgKG1zZ3NbaV0ubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIG11c3QgY29udGFpbiAiLmNvbmNhdChtc2dzW2ldKSwgZ2V0TQorICAgICAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YobXNnc1tpXSkgIT0gLTEpOworICAgICAgICAgICAgICAgIGlmICghZ2V0TS5lcXVhbHMobXNnc1tpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIHNob3VsZCBjb250YWluICIuY29uY2F0KHRvUyksIGdldE0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLAorICAgICAgICAgICAgICAgICAgICB0RS5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFN0b3JlU3BpVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFN0b3JlU3BpVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5M2FiZWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0U3RvcmVTcGlUZXN0LmphdmEKQEAgLTAsMCArMSw5NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DUkw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNSTFNlbGVjdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0U2VsZWN0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRTdG9yZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFN0b3JlU3BpOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuTXlDZXJ0U3RvcmVQYXJhbWV0ZXJzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuTXlDZXJ0U3RvcmVTcGk7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkNlcnRTdG9yZVNwaTwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIENlcnRTdG9yZVNwaVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRTdG9yZVNwaTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzCisgICAgICogQ2VydFN0b3JlU3BpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRTdG9yZVNwaTAxKCkgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24sCisgICAgICAgICAgICBDZXJ0U3RvcmVFeGNlcHRpb24geworICAgICAgICBDZXJ0U3RvcmVTcGkgY2VydFN0b3JlU3BpID0gbnVsbDsKKyAgICAgICAgQ2VydFNlbGVjdG9yIGNlcnRTZWxlY3RvciA9IG5ldyB0bXBDZXJ0U2VsZWN0b3IoKTsvL25ldworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFg1MDlDZXJ0U2VsZWN0b3IoKTsKKyAgICAgICAgQ1JMU2VsZWN0b3IgY3JsU2VsZWN0b3IgPSBuZXcgdG1wQ1JMU2VsZWN0b3IoKTsvL25ldyBYNTA5Q1JMU2VsZWN0b3IoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRTdG9yZVNwaSA9IG5ldyBNeUNlcnRTdG9yZVNwaShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgY2VydFN0b3JlU3BpID0gbmV3IE15Q2VydFN0b3JlU3BpKG5ldyBNeUNlcnRTdG9yZVBhcmFtZXRlcnMoKSk7CisgICAgICAgIGFzc2VydE51bGwoIk5vdCBudWxsIGNvbGxlY3Rpb24iLCBjZXJ0U3RvcmVTcGkKKyAgICAgICAgICAgICAgICAuZW5naW5lR2V0Q2VydGlmaWNhdGVzKGNlcnRTZWxlY3RvcikpOworICAgICAgICBhc3NlcnROdWxsKCJOb3QgbnVsbCBjb2xsZWN0aW9uIiwgY2VydFN0b3JlU3BpCisgICAgICAgICAgICAgICAgLmVuZ2luZUdldENSTHMoY3JsU2VsZWN0b3IpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFRlc3Qgc3VpdGUoKSB7CisgICAgICAgIHJldHVybiBuZXcgVGVzdFN1aXRlKENlcnRTdG9yZVNwaVRlc3QuY2xhc3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZGl0aW9uYWwgY2xhc3NlcyBmb3IgdmVyaWZpY2F0aW9uIENlcnRTdG9yZVNwaSBjbGFzcworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgdG1wQ1JMU2VsZWN0b3IgaW1wbGVtZW50cyBDUkxTZWxlY3RvciB7CisgICAgICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaCAoQ1JMIGNybCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgdG1wQ2VydFNlbGVjdG9yIGltcGxlbWVudHMgQ2VydFNlbGVjdG9yIHsKKyAgICAgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIG1hdGNoIChDZXJ0aWZpY2F0ZSBjcmwpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUNlcnRpZmljYXRlUmVwVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVDZXJ0aWZpY2F0ZVJlcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZDk3M2U3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVDZXJ0aWZpY2F0ZVJlcFRlc3QuamF2YQpAQCAtMCwwICsxLDgyIEBACitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0Lk15Q2VydGlmaWNhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5UZXN0VXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5NeUNlcnRpZmljYXRlLk15Q2VydGlmaWNhdGVSZXA7CisKK2ltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworcHVibGljIGNsYXNzIENlcnRpZmljYXRlQ2VydGlmaWNhdGVSZXBUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIHRlc3RFbmNvZGluZyA9IG5ldyBieXRlW10geyAoYnl0ZSkgMSwgKGJ5dGUpIDIsCisgICAgICAgICAgICAoYnl0ZSkgMywgKGJ5dGUpIDQsIChieXRlKSA1IH07CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IKKyAgICAgKiA8Y29kZT5DZXJ0aWZpY2F0ZS5DZXJ0aWZpY2F0ZVJlcChTdHJpbmcgdHlwZSwgYnl0ZVtdIGRhdGEpPC9jb2RlPgorICAgICAqIG1ldGhvZDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0Q2VydGlmaWNhdGVDZXJ0aWZpY2F0ZVJlcCgpIHsKKyAgICAgICAgTXlDZXJ0aWZpY2F0ZSBjMSA9IG5ldyBNeUNlcnRpZmljYXRlKCJURVNUX1RZUEUiLCB0ZXN0RW5jb2RpbmcpOworICAgICAgICBNeUNlcnRpZmljYXRlUmVwIHJlcCA9IGMxLm5ldyBNeUNlcnRpZmljYXRlUmVwKCJURVNUX1RZUEUiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMSwgKGJ5dGUpIDIsIChieXRlKSAzIH0pOworCisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhuZXcgYnl0ZVtdIHsgKGJ5dGUpIDEsIChieXRlKSAyLCAoYnl0ZSkgMyB9LAorICAgICAgICAgICAgICAgIHJlcC5nZXREYXRhKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJURVNUX1RZUEUiLCByZXAuZ2V0VHlwZSgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYzEubmV3IE15Q2VydGlmaWNhdGVSZXAobnVsbCwgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4ZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTXlDZXJ0aWZpY2F0ZS5NeUNlcnRpZmljYXRlUmVwIHJlcDEgPSBjMS5uZXcgTXlDZXJ0aWZpY2F0ZVJlcCgKKyAgICAgICAgICAgICAgICAgICAgIlg1MDkiLCBUZXN0VXRpbHMuZ2V0WDUwOUNlcnRpZmljYXRlX3YzKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJYNTA5IiwgcmVwMS5nZXRUeXBlKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKFRlc3RVdGlscy5nZXRYNTA5Q2VydGlmaWNhdGVfdjMoKSwgcmVwMS5nZXREYXRhKCkpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnJlYWRSZXNvbHZlKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UmVhZFJlc29sdmUoKSB7CisgICAgICAgIE15Q2VydGlmaWNhdGUgYzEgPSBuZXcgTXlDZXJ0aWZpY2F0ZSgiVEVTVF9UWVBFIiwgdGVzdEVuY29kaW5nKTsKKyAgICAgICAgTXlDZXJ0aWZpY2F0ZVJlcCByZXAgPSBjMS5uZXcgTXlDZXJ0aWZpY2F0ZVJlcCgiVEVTVF9UWVBFIiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgKGJ5dGUpIDEsIChieXRlKSAyLCAoYnl0ZSkgMyB9KTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVwLnJlYWRSZXNvbHZlKCk7CisgICAgICAgICAgICBmYWlsKCJPYmplY3RTdHJlYW1FeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoT2JqZWN0U3RyZWFtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICBNeUNlcnRpZmljYXRlUmVwIHJlcDEgPSBjMS5uZXcgTXlDZXJ0aWZpY2F0ZVJlcCgiWDUwOSIsIFRlc3RVdGlscworICAgICAgICAgICAgICAgIC5nZXRYNTA5Q2VydGlmaWNhdGVfdjMoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBvYmogPSAoQ2VydGlmaWNhdGUpIHJlcDEucmVhZFJlc29sdmUoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiMC4zLjUiLCBvYmouZ2V0UHVibGljS2V5KCkuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJYLjUwOSIsIG9iai5nZXRQdWJsaWNLZXkoKS5nZXRGb3JtYXQoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIlguNTA5Iiwgb2JqLmdldFR5cGUoKSk7CisgICAgICAgIH0gY2F0Y2ggKE9iamVjdFN0cmVhbUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uMlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ODk2ZGM2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjJUZXN0LmphdmEKQEAgLTAsMCArMSw0MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uI0NlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24oKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbigpCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAodHJ1ZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmYWlsKCJTaG91bGQgaGF2ZSB0aHJvd24gQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5pdGlhbGl6ZXIgZmFpbGVkIDogIiArIGUudG9TdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgImphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIiwKKyAgICAgICAgICAgICAgICAgICAgZS50b1N0cmluZygpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIGR1cmluZyB0ZXN0IDogIiArIGUpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmE2NmNkYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSwxODMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb247CisKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+Q2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZAorICogbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIG1zZ3MgPSB7CisgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UiIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBUaHJvd2FibGUgdENhdXNlID0gbmV3IFRocm93YWJsZSgiVGhyb3dhYmxlIGZvciBleGNlcHRpb24iKTsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24oKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24wMSgpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlCisgICAgICogbXNnLiBQYXJhbWV0ZXIgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjAyKCkgeworICAgICAgICBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gd2hlbiA8Y29kZT5tc2c8L2NvZGU+CisgICAgICogaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uMDMoKSB7CisgICAgICAgIFN0cmluZyBtc2cgPSBudWxsOworICAgICAgICBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHRFID0gbmV3IENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24obXNnKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbihUaHJvd2FibGUpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHdoZW4KKyAgICAgKiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uMDQoKSB7CisgICAgICAgIFRocm93YWJsZSBjYXVzZSA9IG51bGw7CisgICAgICAgIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gdEUgPSBuZXcgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICBjYXVzZSk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24oVGhyb3dhYmxlKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24wNSgpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgIHRDYXVzZSk7CisgICAgICAgIGlmICh0RS5nZXRNZXNzYWdlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgc2hvdWxkIGNvbnRhaW4gIi5jb25jYXQodG9TKSwgKGdldE0KKyAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwgdEUKKyAgICAgICAgICAgICAgICAuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24wNigpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHdoZW4KKyAgICAgKiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24wNygpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uKG1zZ3NbaV0sIG51bGwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm46ICIuY29uY2F0KG1zZ3NbaV0pLCB0RQorICAgICAgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZSgpLCBtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QgbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjA4KCkgeworICAgICAgICBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHRFID0gbmV3IENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgbnVsbCwgdENhdXNlKTsKKyAgICAgICAgaWYgKHRFLmdldE1lc3NhZ2UoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IHNob3VsZCAiLmNvbmNhdCh0b1MpLCAoZ2V0TQorICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgIC5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHdoZW4KKyAgICAgKiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90IG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uMDkoKSB7CisgICAgICAgIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbihtc2dzW2ldLCB0Q2F1c2UpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBpZiAobXNnc1tpXS5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgbXVzdCBjb250YWluICIuY29uY2F0KG1zZ3NbaV0pLCBnZXRNCisgICAgICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZihtc2dzW2ldKSAhPSAtMSk7CisgICAgICAgICAgICAgICAgaWYgKCFnZXRNLmVxdWFscyhtc2dzW2ldKSkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgc2hvdWxkIGNvbnRhaW4gIi5jb25jYXQodG9TKSwgZ2V0TQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKHRvUykgIT0gLTEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiAiLmNvbmNhdCh0Q2F1c2UudG9TdHJpbmcoKSksCisgICAgICAgICAgICAgICAgICAgIHRFLmdldENhdXNlKCksIHRDYXVzZSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjdmOWQwZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRXhjZXB0aW9uMlRlc3QuamF2YQpAQCAtMCwwICsxLDYwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgQ2VydGlmaWNhdGVFeGNlcHRpb24yVGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb24jQ2VydGlmaWNhdGVFeGNlcHRpb24oKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfQ29uc3RydWN0b3IoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb24oKQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKHRydWUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluaXRpYWxpemVyIGZhaWxlZCA6ICIgKyBlLnRvU3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb24iLCBlLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gZHVyaW5nIHRlc3QgOiAiICsgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb24jQ2VydGlmaWNhdGVFeGNlcHRpb24oamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0NvbnN0cnVjdG9yTGphdmFfbGFuZ19TdHJpbmcoKSB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZAorICAgICAgICAvLyBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb24oamF2YS5sYW5nLlN0cmluZykKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICh0cnVlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKCJTb21lIGVycm9yIG1lc3NhZ2UiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluaXRpYWxpemVyIGZhaWxlZCIsCisgICAgICAgICAgICAgICAgICAgICJTb21lIGVycm9yIG1lc3NhZ2UiLCBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiBkdXJpbmcgdGVzdCA6ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTI4YTZkMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTc4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKKworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIENlcnRpZmljYXRlRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIG1zZ3MgPSB7CisgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UgQ2hlY2sgbmV3IG1lc3NhZ2UiIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBUaHJvd2FibGUgdENhdXNlID0gbmV3IFRocm93YWJsZSgiVGhyb3dhYmxlIGZvciBleGNlcHRpb24iKTsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlRXhjZXB0aW9uKCk8L2NvZGU+IGNvbnN0cnVjdG9yIEFzc2VydGlvbjoKKyAgICAgKiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVFeGNlcHRpb24wMSgpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVFeGNlcHRpb24gdEUgPSBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydGlmaWNhdGVFeGNlcHRpb24gd2l0aCBkZXRhaWwgbWVzc2FnZSBtc2cuCisgICAgICogUGFyYW1ldGVyIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRXhjZXB0aW9uMDIoKSB7CisgICAgICAgIENlcnRpZmljYXRlRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm46ICIuY29uY2F0KG1zZ3NbaV0pLCB0RQorICAgICAgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZSgpLCBtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydGlmaWNhdGVFeGNlcHRpb24gd2hlbiA8Y29kZT5tc2c8L2NvZGU+IGlzCisgICAgICogbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUV4Y2VwdGlvbjAzKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICAgICAgQ2VydGlmaWNhdGVFeGNlcHRpb24gdEUgPSBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24obXNnKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVFeGNlcHRpb24oVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydGlmaWNhdGVFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMKKyAgICAgKiBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRXhjZXB0aW9uMDQoKSB7CisgICAgICAgIFRocm93YWJsZSBjYXVzZSA9IG51bGw7CisgICAgICAgIENlcnRpZmljYXRlRXhjZXB0aW9uIHRFID0gbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKGNhdXNlKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVFeGNlcHRpb24oVGhyb3dhYmxlKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydGlmaWNhdGVFeGNlcHRpb24gd2hlbiA8Y29kZT5jYXVzZTwvY29kZT4gaXMKKyAgICAgKiBub3QgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUV4Y2VwdGlvbjA1KCkgeworICAgICAgICBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbih0Q2F1c2UpOworICAgICAgICBpZiAodEUuZ2V0TWVzc2FnZSgpICE9IG51bGwpIHsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIFN0cmluZyBnZXRNID0gdEUuZ2V0TWVzc2FnZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiZ2V0TWVzc2FnZSgpIHNob3VsZCBjb250YWluICIuY29uY2F0KHRvUyksIChnZXRNCisgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKHRvUykgIT0gLTEpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROb3ROdWxsKCJnZXRDYXVzZSgpIG11c3Qgbm90IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiAiLmNvbmNhdCh0Q2F1c2UudG9TdHJpbmcoKSksIHRFCisgICAgICAgICAgICAgICAgLmdldENhdXNlKCksIHRDYXVzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRXhjZXB0aW9uMDYoKSB7CisgICAgICAgIENlcnRpZmljYXRlRXhjZXB0aW9uIHRFID0gbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKG51bGwsIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydGlmaWNhdGVFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVFeGNlcHRpb24wNygpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24obXNnc1tpXSwgbnVsbCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlRXhjZXB0aW9uIHdoZW4KKyAgICAgKiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90IG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRXhjZXB0aW9uMDgoKSB7CisgICAgICAgIENlcnRpZmljYXRlRXhjZXB0aW9uIHRFID0gbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKG51bGwsIHRDYXVzZSk7CisgICAgICAgIGlmICh0RS5nZXRNZXNzYWdlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgbXVzdCBzaG91bGQgIi5jb25jYXQodG9TKSwgKGdldE0KKyAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwgdEUKKyAgICAgICAgICAgICAgICAuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlRXhjZXB0aW9uIHdoZW4KKyAgICAgKiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90IG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUV4Y2VwdGlvbjA5KCkgeworICAgICAgICBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbihtc2dzW2ldLCB0Q2F1c2UpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBpZiAobXNnc1tpXS5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgbXVzdCBjb250YWluICIuY29uY2F0KG1zZ3NbaV0pLCBnZXRNCisgICAgICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZihtc2dzW2ldKSAhPSAtMSk7CisgICAgICAgICAgICAgICAgaWYgKCFnZXRNLmVxdWFscyhtc2dzW2ldKSkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgc2hvdWxkIGNvbnRhaW4gIi5jb25jYXQodG9TKSwgZ2V0TQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKHRvUykgIT0gLTEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiAiLmNvbmNhdCh0Q2F1c2UudG9TdHJpbmcoKSksCisgICAgICAgICAgICAgICAgICAgIHRFLmdldENhdXNlKCksIHRDYXVzZSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb25UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmY2ZjFkZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDc5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb247CisKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+RGlnZXN0RXhjZXB0aW9uPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisgICAgc3RhdGljIFRocm93YWJsZSB0Q2F1c2UgPSBuZXcgVGhyb3dhYmxlKCJUaHJvd2FibGUgZm9yIGV4Y2VwdGlvbiIpOworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uKCk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbjAxKCkgeworICAgICAgICBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24gdEUgPSBuZXcgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uKCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24gd2l0aCBkZXRhaWwgbWVzc2FnZQorICAgICAqIG1zZy4gUGFyYW1ldGVyIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbjAyKCkgeworICAgICAgICBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uKG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm46ICIuY29uY2F0KG1zZ3NbaV0pLCB0RQorICAgICAgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZSgpLCBtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbiB3aGVuIDxjb2RlPm1zZzwvY29kZT4KKyAgICAgKiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbjAzKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICAgICAgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uIHRFID0gbmV3IENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbihtc2cpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUZhY3RvcnkxVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVGYWN0b3J5MVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kODA4ZjU5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVGYWN0b3J5MVRlc3QuamF2YQpAQCAtMCwwICsxLDcyNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuU3BpRW5nVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5NeUNlcnRQYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuTXlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0Lk15Q2VydGlmaWNhdGVGYWN0b3J5U3BpOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DUkw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNSTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGg7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3RvcnlTcGk7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkNlcnRpZmljYXRlRmFjdG9yeTwvY29kZT4gY2xhc3MgbWV0aG9kcyBhbmQgY29uc3RydWN0b3IKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBDZXJ0aWZpY2F0ZUZhY3RvcnkxVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIHNydkNlcnRpZmljYXRlRmFjdG9yeSA9ICJDZXJ0aWZpY2F0ZUZhY3RvcnkiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGRlZmF1bHRQcm92aWRlck5hbWUgPSBudWxsOworCisgICAgcHJpdmF0ZSBzdGF0aWMgUHJvdmlkZXIgZGVmYXVsdFByb3ZpZGVyID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gWDUwOVN1cHBvcnQgPSBmYWxzZTsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGRlZmF1bHRUeXBlID0gIlguNTA5IjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nW10gdmFsaWRWYWx1ZXMgPSB7CisgICAgICAgICAgICAiWC41MDkiLCAieC41MDkiIH07CisKKyAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmdbXSBpbnZhbGlkVmFsdWVzID0gU3BpRW5nVXRpbHMuaW52YWxpZFZhbHVlczsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBOb3RTdXBwb3J0TXNnID0gIiI7CisKKyAgICBzdGF0aWMgeworICAgICAgICBkZWZhdWx0UHJvdmlkZXIgPSBTcGlFbmdVdGlscy5pc1N1cHBvcnQoZGVmYXVsdFR5cGUsCisgICAgICAgICAgICAgICAgc3J2Q2VydGlmaWNhdGVGYWN0b3J5KTsKKyAgICAgICAgWDUwOVN1cHBvcnQgPSAoZGVmYXVsdFByb3ZpZGVyICE9IG51bGwpOworICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lID0gKFg1MDlTdXBwb3J0ID8gZGVmYXVsdFByb3ZpZGVyLmdldE5hbWUoKSA6IG51bGwpOworICAgICAgICBOb3RTdXBwb3J0TXNnID0gZGVmYXVsdFR5cGUuY29uY2F0KCIgaXMgbm90IHN1cHBvcnRlZCIpOyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBDZXJ0aWZpY2F0ZUZhY3RvcnlbXSBpbml0Q2VydEZzKCkgeworICAgICAgICBpZiAoIVg1MDlTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeVtdIGNlcnRGcyA9IG5ldyBDZXJ0aWZpY2F0ZUZhY3RvcnlbM107CisgICAgICAgICAgICBjZXJ0RnNbMF0gPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoZGVmYXVsdFR5cGUpOworICAgICAgICAgICAgY2VydEZzWzFdID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKGRlZmF1bHRUeXBlLAorICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgIGNlcnRGc1syXSA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZShkZWZhdWx0VHlwZSwKKyAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgIHJldHVybiBjZXJ0RnM7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIE15Q2VydGlmaWNhdGUgY3JlYXRlTUMoKSB7CisgICAgICAgIGJ5dGVbXSBlbmMgPSB7IChieXRlKSAwLCAoYnl0ZSkgMiwgKGJ5dGUpIDMsIChieXRlKSA0LCAoYnl0ZSkgNSB9OworICAgICAgICByZXR1cm4gbmV3IE15Q2VydGlmaWNhdGUoIlRlc3RfVGVzdCIsIGVuYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIHR5cGUpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgQ2VydGlmaWNhdGVGYWN0b3J5IGlmIHR5cGUgaXMgWC41MDkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVGYWN0b3J5MDEoKSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBpZiAoIVg1MDlTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZXJ0RiA9IENlcnRpZmljYXRlRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdHlwZTogIiwgdmFsaWRWYWx1ZXNbaV0sIGNlcnRGLmdldFR5cGUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgdHlwZSk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiB0eXBlIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24gd2hlbiB0eXBlIGlzIG5vdCBhdmFpbGFibGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVGYWN0b3J5MDIoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBvciBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHR5cGUgaXMgbnVsbCIpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIkNlcnRpZmljYXRlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gdHlwZTogIgorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChpbnZhbGlkVmFsdWVzW2ldKSk7CisgICAgICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgdHlwZSwgU3RyaW5nIHByb3ZpZGVyKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgbnVsbCBvciBlbXB0eQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUZhY3RvcnkwMygpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFYNTA5U3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcHJvdmlkZXIgPSBudWxsOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgcHJvdmlkZXIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHByb3ZpZGVyIGlzIG51bGwiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgIiIpOworICAgICAgICAgICAgICAgIGZhaWwoIklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAgbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBlbXB0eSIpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyB0eXBlLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gdHlwZSBpcyBudWxsCisgICAgICogdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHdoZW4gdHlwZSBpcyBub3QgYXZhaWxhYmxlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRmFjdG9yeTA0KCkgdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFYNTA5U3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKG51bGwsIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgQ2VydGlmaWNhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiB0eXBlIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyTmFtZSk7CisgICAgICAgICAgICAgICAgZmFpbCgiQ2VydGlmaWNhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gKHR5cGU6ICIuY29uY2F0KAorICAgICAgICAgICAgICAgICAgICAgICAgaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIgcHJvdmlkZXI6ICIpLmNvbmNhdCgKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUpLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyB0eXBlLCBTdHJpbmcgcHJvdmlkZXIpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgQ2VydGlmaWNhdGVGYWN0b3J5IHdoZW4gdHlwZSBhbmQgcHJvdmlkZXIgaGF2ZSB2YWxpZAorICAgICAqIHZhbHVlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUZhY3RvcnkwNSgpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFYNTA5U3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2VydEY7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGNlcnRGID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLAorICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHR5cGUiLCBjZXJ0Ri5nZXRUeXBlKCksIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIG5hbWUiLCBjZXJ0Ri5nZXRQcm92aWRlcigpCisgICAgICAgICAgICAgICAgICAgIC5nZXROYW1lKCksIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIHR5cGUsIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRmFjdG9yeTA2KCkgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFYNTA5U3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBQcm92aWRlciBwcm92aWRlciA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBwcm92aWRlcik7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duICB3aGVuIHByb3ZpZGVyIGlzIG51bGwiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgdHlwZSwgUHJvdmlkZXIgcHJvdmlkZXIpPC9jb2RlPgorICAgICAqIG1ldGhvZAorICAgICAqIEFzc2VydGlvbjoKKyAgICAgKiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiB0eXBlIGlzIG51bGwKKyAgICAgKiB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24gd2hlbiB0eXBlIGlzIG5vdCBhdmFpbGFibGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVGYWN0b3J5MDcoKSB7CisgICAgICAgIGlmICghWDUwOVN1cHBvcnQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZShudWxsLCBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gb3IgQ2VydGlmaWNhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiB0eXBlIGlzIG51bGwiKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZShpbnZhbGlkVmFsdWVzW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB3YXMgbm90IHRocm93biBhcyBleHBlY3RlZCAodHlwZToiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiIHByb3ZpZGVyOiAiKS5jb25jYXQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlci5nZXROYW1lKCkpLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEluc3RhbmNlKFN0cmluZyB0eXBlLCBQcm92aWRlciBwcm92aWRlcik8L2NvZGU+CisgICAgICogbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIENlcnRpZmljYXRlRmFjdG9yeXRocm93cyB3aGVuIHR5cGUgYW5kIHByb3ZpZGVyCisgICAgICogaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVGYWN0b3J5MDgoKSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBpZiAoIVg1MDlTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZXJ0RjsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgY2VydEYgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sCisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsIGNlcnRGLmdldFByb3ZpZGVyKCksCisgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB0eXBlIiwgY2VydEYuZ2V0VHlwZSgpLCB2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRDZXJ0UGF0aEVuY29kaW5ncygpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgZW5jb2RpbmdzCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRmFjdG9yeTA5KCkgeworICAgICAgICBpZiAoIVg1MDlTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeVtdIGNlcnRGcyA9IGluaXRDZXJ0RnMoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ2VydGlmaWNhdGVGYWN0b3J5IG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIGNlcnRGcyk7CisgICAgICAgIEl0ZXJhdG9yPFN0cmluZz4gaXQxID0gY2VydEZzWzBdLmdldENlcnRQYXRoRW5jb2RpbmdzKCk7CisgICAgICAgIEl0ZXJhdG9yPFN0cmluZz4gaXQyID0gY2VydEZzWzFdLmdldENlcnRQYXRoRW5jb2RpbmdzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGVuY29kaW5ncyIsIGl0MS5oYXNOZXh0KCksIGl0Mi5oYXNOZXh0KCkpOworICAgICAgICB3aGlsZSAoaXQxLmhhc05leHQoKSkgeworICAgICAgICAgICAgaXQyID0gY2VydEZzWzFdLmdldENlcnRQYXRoRW5jb2RpbmdzKCk7CisgICAgICAgICAgICBTdHJpbmcgczEgPSBpdDEubmV4dCgpOworICAgICAgICAgICAgYm9vbGVhbiB5ZXNObyA9IGZhbHNlOworICAgICAgICAgICAgd2hpbGUgKGl0Mi5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoczEuZXF1YWxzKGl0Mi5uZXh0KCkpKSB7CisgICAgICAgICAgICAgICAgICAgIHllc05vID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRW5jb2Rpbmc6ICIuY29uY2F0KHMxKS5jb25jYXQoCisgICAgICAgICAgICAgICAgICAgICIgZG9lcyBub3QgZGVmaW5lIGZvciBjZXJ0RjIgQ2VydGlmaWNhdGVGYWN0b3J5IiksIHllc05vKTsKKyAgICAgICAgfQorICAgICAgICBpdDEgPSBjZXJ0RnNbMF0uZ2V0Q2VydFBhdGhFbmNvZGluZ3MoKTsKKyAgICAgICAgaXQyID0gY2VydEZzWzJdLmdldENlcnRQYXRoRW5jb2RpbmdzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGVuY29kaW5ncyIsIGl0MS5oYXNOZXh0KCksIGl0Mi5oYXNOZXh0KCkpOworICAgICAgICB3aGlsZSAoaXQxLmhhc05leHQoKSkgeworICAgICAgICAgICAgaXQyID0gY2VydEZzWzJdLmdldENlcnRQYXRoRW5jb2RpbmdzKCk7CisgICAgICAgICAgICBTdHJpbmcgczEgPSBpdDEubmV4dCgpOworICAgICAgICAgICAgYm9vbGVhbiB5ZXNObyA9IGZhbHNlOworICAgICAgICAgICAgd2hpbGUgKGl0Mi5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoczEuZXF1YWxzKGl0Mi5uZXh0KCkpKSB7CisgICAgICAgICAgICAgICAgICAgIHllc05vID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRW5jb2Rpbmc6ICIuY29uY2F0KHMxKS5jb25jYXQoCisgICAgICAgICAgICAgICAgICAgICIgZG9lcyBub3QgZGVmaW5lIGZvciBjZXJ0RjMgQ2VydGlmaWNhdGVGYWN0b3J5IiksIHllc05vKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdlbmVyYXRlQ2VydGlmaWNhdGUoSW5wdXRTdHJlYW0gaW5TdHJlYW0pPC9jb2RlPgorICAgICAqIDxjb2RlPmdlbmVyYXRlQ2VydGlmaWNhdGVzKElucHV0U3RyZWFtIGluU3RyZWFtKTwvY29kZT4KKyAgICAgKiA8Y29kZT5nZW5lcmF0ZUNSTChJbnB1dFN0cmVhbSBpblN0cmVhbSk8L2NvZGU+CisgICAgICogPGNvZGU+Z2VuZXJhdGVDUkxzKElucHV0U3RyZWFtIGluU3RyZWFtKTwvY29kZT4KKyAgICAgKiBtZXRob2RzCisgICAgICogQXNzZXJ0aW9uOiB0aHJvdyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBhbmQgQ1JMRXhjZXB0aW9uIHdoZW4KKyAgICAgKiBpblN0cmVhbSBpcyBudWxsIG9yIGVtcHR5CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRmFjdG9yeTEwKCkgeworICAgICAgICBpZiAoIVg1MDlTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeVtdIGNlcnRGcyA9IGluaXRDZXJ0RnMoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ2VydGlmaWNhdGVGYWN0b3J5IG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIGNlcnRGcyk7CisgICAgICAgIGJ5dGUgW10gYmIgPSB7fTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmIpOworICAgICAgICBDb2xsZWN0aW9uPD8+IGNvbENlcjsKKyAgICAgICAgQ29sbGVjdGlvbjw/PiBjb2xDcmw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2VydEZzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNlcnRGc1tpXS5nZW5lcmF0ZUNlcnRpZmljYXRlKG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoImdlbmVyYXRlQ2VydGlmaWNhdGUgbXVzdCB0aHJvd24gQ2VydGlmaWNhdGVFeGNlcHRpb24gb3IgTnVsbFBvaW50ZXJFWGNlcHRpb24gd2hlbiBpbnB1dCBzdHJlYW0gaXMgbnVsbCIpOworICAgICAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmIpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjZXJ0RnNbaV0uZ2VuZXJhdGVDZXJ0aWZpY2F0ZXMobnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiZ2VuZXJhdGVDZXJ0aWZpY2F0ZXMgbXVzdCB0aHJvdyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBvciBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIGlucHV0IHN0cmVhbSBpcyBudWxsIik7CisgICAgICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYik7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNlcnRGc1tpXS5nZW5lcmF0ZUNlcnRpZmljYXRlKGlzKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJiKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY29sQ2VyID0gY2VydEZzW2ldLmdlbmVyYXRlQ2VydGlmaWNhdGVzKGlzKTsKKyAgICAgICAgICAgICAgICBpZiAoY29sQ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTm90IGVtcHR5IGNlcnRpZmljYXRlIGNvbGxlY3Rpb24iLCBjb2xDZXIuaXNFbXB0eSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjZXJ0RnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2VydEZzW2ldLmdlbmVyYXRlQ1JMKG51bGwpOworICAgICAgICAgICAgfSBjYXRjaCAoQ1JMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY29sQ3JsID0gY2VydEZzW2ldLmdlbmVyYXRlQ1JMcyhudWxsKTsKKyAgICAgICAgICAgICAgICBpZiAoY29sQ3JsICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTm90IGVtcHR5IENSTCBjb2xsZWN0aW9uIHdhcyByZXR1cm5lZCBmcm9tIG51bGwgc3RyZWFtIiwgY29sQ3JsLmlzRW1wdHkoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoQ1JMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJiKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgIGNlcnRGc1tpXS5nZW5lcmF0ZUNSTChpcyk7CisgICAgICAgICAgICB9IGNhdGNoIChDUkxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmIpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjZXJ0RnNbaV0uZ2VuZXJhdGVDUkxzKGlzKTsKKyAgICAgICAgICAgICAgICBjb2xDcmwgPSBjZXJ0RnNbaV0uZ2VuZXJhdGVDUkxzKG51bGwpOworICAgICAgICAgICAgICAgIGlmIChjb2xDcmwgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJOb3QgZW1wdHkgQ1JMIGNvbGxlY3Rpb24gd2FzIHJldHVybmVkIGZyb20gZW1wdHkgc3RyZWFtIiwgY29sQ3JsLmlzRW1wdHkoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoQ1JMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogVGVzdCBmb3IgPGNvZGU+IGdlbmVyYXRlQ2VydGlmaWNhdGUoSW5wdXRTdHJlYW0gaW5TdHJlYW0pIDwvY29kZT48Y29kZT4KKyAgICAgKiBnZW5lcmF0ZUNlcnRpZmljYXRlcyhJbnB1dFN0cmVhbSBpblN0cmVhbSkgPC9jb2RlPjxjb2RlPgorICAgICAqIGdlbmVyYXRlQ1JMKElucHV0U3RyZWFtIGluU3RyZWFtKSA8L2NvZGU+PGNvZGU+CisgICAgICogZ2VuZXJhdGVDUkxzKElucHV0U3RyZWFtIGluU3RyZWFtKSA8L2NvZGU+CisgICAgICogbWV0aG9kcworICAgICAqIEFzc2VydGlvbjogdGhyb3cgQ2VydGlmaWNhdGVFeGNlcHRpb24gYW5kIENSTEV4Y2VwdGlvbiB3aGVuIGluU3RyZWFtCisgICAgICogY29udGFpbnMgaW5jb21wYXRpYmxlIGRhdGFzCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRmFjdG9yeTExKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFYNTA5U3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnlbXSBjZXJ0RnMgPSBpbml0Q2VydEZzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkNlcnRpZmljYXRlRmFjdG9yeSBvYmplY3RzIHdlcmUgbm90IGNyZWF0ZWQiLCBjZXJ0RnMpOworICAgICAgICBNeUNlcnRpZmljYXRlIG1jID0gY3JlYXRlTUMoKTsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0gb29zID0gbmV3IE9iamVjdE91dHB1dFN0cmVhbShvcyk7CisgICAgICAgIG9vcy53cml0ZU9iamVjdChtYyk7CisgICAgICAgIG9vcy5mbHVzaCgpOworICAgICAgICBvb3MuY2xvc2UoKTsKKworICAgICAgICBDZXJ0aWZpY2F0ZSBjZXI7CisgICAgICAgIENvbGxlY3Rpb248Pz4gY29sQ2VyOworICAgICAgICBDUkwgY3JsOworICAgICAgICBDb2xsZWN0aW9uPD8+IGNvbENybDsKKworICAgICAgICBieXRlW10gYXJyID0gb3MudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gaXM7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2VydEZzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShhcnIpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjZXIgPSBjZXJ0RnNbaV0uZ2VuZXJhdGVDZXJ0aWZpY2F0ZShpcyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbCgiTm90IG51bGwgY2VydGlmaWNhdGUgd2FzIGNyZWF0ZWQiLCBjZXIpOworICAgICAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYXJyKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY29sQ2VyID0gY2VydEZzW2ldLmdlbmVyYXRlQ2VydGlmaWNhdGVzKGlzKTsKKyAgICAgICAgICAgICAgICBpZiAoY29sQ2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTm90IGVtcHR5IGNlcnRpZmljYXRlIENvbGxlY3Rpb24gd2FzIGNyZWF0ZWQiLCBjb2xDZXIuaXNFbXB0eSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShhcnIpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjcmwgPSBjZXJ0RnNbaV0uZ2VuZXJhdGVDUkwoaXMpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwoIk5vdCBudWxsIENSTCB3YXMgY3JlYXRlZCIsIGNybCk7CisgICAgICAgICAgICB9IGNhdGNoIChDUkxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYXJyKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY29sQ3JsID0gY2VydEZzW2ldLmdlbmVyYXRlQ1JMcyhpcyk7CisgICAgICAgICAgICAgICAgaWYgKGNvbENybCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIk5vdCBlbXB0eSBDUkwgQ29sbGVjdGlvbiB3YXMgY3JlYXRlZCIsIGNvbENybC5pc0VtcHR5KCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKENSTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZW5lcmF0ZUNlcnRQYXRoKElucHV0U3RyZWFtIGluU3RyZWFtKTwvY29kZT4KKyAgICAgKiA8Y29kZT5nZW5lcmF0ZUNlcnRQYXRoKElucHV0U3RyZWFtIGluU3RyZWFtLCBTdHJpbmcgZW5jb2RpbmcpPC9jb2RlPgorICAgICAqIG1ldGhvZHMKKyAgICAgKiBBc3NlcnRpb246IHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB3aGVuIGluU3RyZWFtIGlzIG51bGwgb3IKKyAgICAgKiB3aGVuIGlzU3RyZWFtIGNvbnRhaW5zIGludmFsaWQgZGF0YXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVGYWN0b3J5MTIoKSB7CisgICAgICAgIGlmICghWDUwOVN1cHBvcnQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5W10gY2VydEZzID0gaW5pdENlcnRGcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJDZXJ0aWZpY2F0ZUZhY3Rvcnkgb2JqZWN0cyB3ZXJlIG5vdCBjcmVhdGVkIiwgY2VydEZzKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMxID0gbnVsbDsKKyAgICAgICAgSW5wdXRTdHJlYW0gaXMyID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlWzEwXSk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjZXJ0RnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2VydEZzW2ldLmdlbmVyYXRlQ2VydFBhdGgoaXMxKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJnZW5lcmF0ZUNlcnRpZmljYXRlIG11c3QgdGhyb3duIENlcnRpZmljYXRlRXhjZXB0aW9uIG9yIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gaW5wdXQgc3RyZWFtIGlzIG51bGwiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2VydEZzW2ldLmdlbmVyYXRlQ2VydFBhdGgoaXMyKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJnZW5lcmF0ZUNlcnRpZmljYXRlIG11c3QgdGhyb3duIENlcnRpZmljYXRlRXhjZXB0aW9uIHdoZW4gaW5wdXQgc3RyZWFtIGNvbnRhaW5zIGludmFsaWQgZGF0YXMiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEl0ZXJhdG9yPFN0cmluZz4gaXQgPSBjZXJ0RnNbaV0uZ2V0Q2VydFBhdGhFbmNvZGluZ3MoKTsKKyAgICAgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgZW5jID0gaXQubmV4dCgpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGNlcnRGc1tpXS5nZW5lcmF0ZUNlcnRQYXRoKGlzMSwgZW5jKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiZ2VuZXJhdGVDZXJ0aWZpY2F0ZSBtdXN0IHRocm93biBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBvciBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIGlucHV0IHN0cmVhbSBpcyBudWxsIGFuZCBlbmNvZGluZ3MgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoZW5jKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgY2VydEZzW2ldLmdlbmVyYXRlQ2VydFBhdGgoaXMyLCBlbmMpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCJnZW5lcmF0ZUNlcnRpZmljYXRlIG11c3QgdGhyb3duIENlcnRpZmljYXRlRXhjZXB0aW9uIHdoZW4gaW5wdXQgc3RyZWFtIGNvbnRhaW5zIGludmFsaWQgZGF0YXMgIGFuZCBlbmNvZGluZ3MgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoZW5jKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdlbmVyYXRlQ2VydFBhdGgoSW5wdXRTdHJlYW0gaW5TdHJlYW0pPC9jb2RlPgorICAgICAqIDxjb2RlPmdlbmVyYXRlQ2VydFBhdGgoSW5wdXRTdHJlYW0gaW5TdHJlYW0sIFN0cmluZyBlbmNvZGluZyk8L2NvZGU+CisgICAgICogbWV0aG9kcworICAgICAqIEFzc2VydGlvbjogdGhyb3cgQ2VydGlmaWNhdGVFeGNlcHRpb24gd2hlbiBpc1N0cmVhbSBjb250YWlucyBpbnZhbGlkIGRhdGFzCisgICAgICovCisgICAgLy8gVGVzdCBwYXNzZWQgb24gUkkKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVGYWN0b3J5MTMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoIVg1MDlTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeVtdIGNlcnRGcyA9IGluaXRDZXJ0RnMoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ2VydGlmaWNhdGVGYWN0b3J5IG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIGNlcnRGcyk7CisgICAgICAgIGJ5dGVbXSBlbmMgPSB7IChieXRlKSAwLCAoYnl0ZSkgMiwgKGJ5dGUpIDMsIChieXRlKSA0LCAoYnl0ZSkgNSB9OworICAgICAgICBNeUNlcnRQYXRoIG1jID0gbmV3IE15Q2VydFBhdGgoZW5jKTsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCisgICAgICAgIE9iamVjdE91dHB1dFN0cmVhbSBvb3MgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKG9zKTsKKyAgICAgICAgb29zLndyaXRlT2JqZWN0KG1jKTsKKyAgICAgICAgb29zLmZsdXNoKCk7CisgICAgICAgIG9vcy5jbG9zZSgpOworCisgICAgICAgIGJ5dGVbXSBhcnIgPSBvcy50b0J5dGVBcnJheSgpOworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShhcnIpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2VydEZzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGNlcnRGc1tpXS5nZW5lcmF0ZUNlcnRQYXRoKGlzKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biBiZWNhdXNlIGlucHV0IHN0cmVhbSBjb250YWlucyBpbmNvcnJlY3QgZGF0YXMiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIEl0ZXJhdG9yPFN0cmluZz4gaXQgPSBjZXJ0RnNbaV0uZ2V0Q2VydFBhdGhFbmNvZGluZ3MoKTsKKyAgICAgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBjZXJ0RnNbaV0uZ2VuZXJhdGVDZXJ0UGF0aChpcywgaXQubmV4dCgpKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiQ2VydGlmaWNhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gYmVjYXVzZSBpbnB1dCBzdHJlYW0gY29udGFpbnMgaW5jb3JyZWN0IGRhdGFzIik7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdlbmVyYXRlQ2VydFBhdGgoTGlzdCBjZXJ0aWZpY2F0ZXMpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIGNlcnRpZmljYXRlcyBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRmFjdG9yeTE0KCkgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFYNTA5U3VwcG9ydCkgeworICAgICAgICAgICAgZmFpbChOb3RTdXBwb3J0TXNnKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnlbXSBjZXJ0RnMgPSBpbml0Q2VydEZzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkNlcnRpZmljYXRlRmFjdG9yeSBvYmplY3RzIHdlcmUgbm90IGNyZWF0ZWQiLCBjZXJ0RnMpOworICAgICAgICBMaXN0PENlcnRpZmljYXRlPiBsaXN0ID0gbnVsbDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjZXJ0RnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2VydEZzW2ldLmdlbmVyYXRlQ2VydFBhdGgobGlzdCk7CisgICAgICAgICAgICAgICAgZmFpbCgiZ2VuZXJhdGVDZXJ0aWZpY2F0ZSBtdXN0IHRocm93biBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB3aGVuIGxpc3QgaXMgbnVsbCIpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2VuZXJhdGVDZXJ0UGF0aChMaXN0IGNlcnRpZmljYXRlcyk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBlbXB0eSBDZXJ0UGF0aCBpZiBjZXJ0aWZpY2F0ZXMgaXMgZW1wdHkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVGYWN0b3J5MTUoKSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBpZiAoIVg1MDlTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeVtdIGNlcnRGcyA9IGluaXRDZXJ0RnMoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ2VydGlmaWNhdGVGYWN0b3J5IG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIGNlcnRGcyk7CisgICAgICAgIExpc3Q8Q2VydGlmaWNhdGU+IGxpc3QgPSBuZXcgVmVjdG9yPENlcnRpZmljYXRlPigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNlcnRGcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgQ2VydFBhdGggY3AgPSBjZXJ0RnNbaV0uZ2VuZXJhdGVDZXJ0UGF0aChsaXN0KTsKKyAgICAgICAgICAgIExpc3Q8PyBleHRlbmRzIENlcnRpZmljYXRlPiBsaXN0MSA9IGNwLmdldENlcnRpZmljYXRlcygpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTGlzdCBzaG91bGQgYmUgZW1wdHkiLCBsaXN0MS5pc0VtcHR5KCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2VuZXJhdGVDZXJ0UGF0aChMaXN0IGNlcnRpZmljYXRlcyk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHdoZW4gY2VydGlmaWNhdGVzIGNvbnRhaW5zCisgICAgICogaW5jb3JyZWN0IENlcnRpZmljYXRlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRmFjdG9yeTE2KCkgeworICAgICAgICBpZiAoIVg1MDlTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeVtdIGNlcnRGcyA9IGluaXRDZXJ0RnMoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ2VydGlmaWNhdGVGYWN0b3J5IG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIGNlcnRGcyk7CisgICAgICAgIE15Q2VydGlmaWNhdGUgbXMgPSBjcmVhdGVNQygpOworICAgICAgICBMaXN0PENlcnRpZmljYXRlPiBsaXN0ID0gbmV3IFZlY3RvcjxDZXJ0aWZpY2F0ZT4oKTsKKyAgICAgICAgbGlzdC5hZGQobXMpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNlcnRGcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjZXJ0RnNbaV0uZ2VuZXJhdGVDZXJ0UGF0aChsaXN0KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVGYWN0b3J5PC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBDZXJ0aWZpY2F0ZUZhY3Rvcnkgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlRmFjdG9yeTE3KCkgdGhyb3dzIENSTEV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghWDUwOVN1cHBvcnQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5U3BpIHNwaSA9IG5ldyBNeUNlcnRpZmljYXRlRmFjdG9yeVNwaSgpOworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBuZXcgbXlDZXJ0aWZpY2F0ZUZhY3Rvcnkoc3BpLCBkZWZhdWx0UHJvdmlkZXIsCisgICAgICAgICAgICAgICAgZGVmYXVsdFR5cGUpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB0eXBlIiwgY2YuZ2V0VHlwZSgpLCBkZWZhdWx0VHlwZSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwgY2YuZ2V0UHJvdmlkZXIoKSwgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNmLmdlbmVyYXRlQ1JMcyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkNSTEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChDUkxFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgY2YgPSBuZXcgbXlDZXJ0aWZpY2F0ZUZhY3RvcnkobnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoIkluY29ycmVjdCB0eXBlIiwgY2YuZ2V0VHlwZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiSW5jb3JyZWN0IHByb3ZpZGVyIiwgY2YuZ2V0UHJvdmlkZXIoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZi5nZW5lcmF0ZUNSTHMobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRUeXBlKCk8L2NvZGU+IG1ldGhvZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUZhY3RvcnkxOCgpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghWDUwOVN1cHBvcnQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2VydEYgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgdHlwZTogIiwgdmFsaWRWYWx1ZXNbaV0sIGNlcnRGCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0VHlwZSgpKTsKKyAgICAgICAgICAgICAgICBjZXJ0RiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHR5cGUiLCBjZXJ0Ri5nZXRUeXBlKCksIHZhbGlkVmFsdWVzW2ldKTsKKworICAgICAgICAgICAgICAgIGNlcnRGID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFByb3ZpZGVyKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsIGNlcnRGLmdldFByb3ZpZGVyKCksCisgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdmlkZXIpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHR5cGUiLCBjZXJ0Ri5nZXRUeXBlKCksIHZhbGlkVmFsdWVzW2ldKTsKKworICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJjYXN0IikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVGYWN0b3J5MTkoKSB7CisgICAgICAgIGlmICghWDUwOVN1cHBvcnQpIHsKKyAgICAgICAgICAgIGZhaWwoTm90U3VwcG9ydE1zZyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5U3BpIHNwaSA9IG5ldyBNeUNlcnRpZmljYXRlRmFjdG9yeVNwaSgpOworICAgICAgICBteUNlcnRpZmljYXRlRmFjdG9yeSBjZjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNmID0gbmV3IG15Q2VydGlmaWNhdGVGYWN0b3J5KHNwaSwgZGVmYXVsdFByb3ZpZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VHlwZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB0eXBlIiwgY2YuZ2V0VHlwZSgpLCBkZWZhdWx0VHlwZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBwcm92aWRlciIsIGNmLmdldFByb3ZpZGVyKCksIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGNmIGluc3RhbmNlb2YgQ2VydGlmaWNhdGVGYWN0b3J5KTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNmID0gbmV3IG15Q2VydGlmaWNhdGVGYWN0b3J5KG51bGwsIG51bGwsIG51bGwpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24iICsgZSk7CisgICAgICAgIH0KKyAgICB9Cit9CisvKioKKyAqIEFkZGl0aW9uYWwgY2xhc3MgdG8gdmVyaWZ5IENlcnRpZmljYXRlRmFjdG9yeSBjb25zdHJ1Y3RvcgorICovCisKK2NsYXNzIG15Q2VydGlmaWNhdGVGYWN0b3J5IGV4dGVuZHMgQ2VydGlmaWNhdGVGYWN0b3J5IHsKKworICAgIHB1YmxpYyBteUNlcnRpZmljYXRlRmFjdG9yeShDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkgc3BpLCBQcm92aWRlciBwcm92LAorICAgICAgICAgICAgU3RyaW5nIHR5cGUpIHsKKyAgICAgICAgc3VwZXIoc3BpLCBwcm92LCB0eXBlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUZhY3RvcnkyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVGYWN0b3J5MlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOGZjNzlmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVGYWN0b3J5MlRlc3QuamF2YQpAQCAtMCwwICsxLDMzNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5TcGlFbmdVdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0Lk15Q2VydGlmaWNhdGVGYWN0b3J5U3BpOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ1JMOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DUkxFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRmFjdG9yeTsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKgorICogVGVzdHMgZm9yIENlcnRpZmljYXRlRmFjdG9yeSBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kIG1ldGhvZHMKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBDZXJ0aWZpY2F0ZUZhY3RvcnkyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZGVmYXVsdEFsZyA9ICJDZXJ0RmFjIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ2VydGlmaWNhdGVGYWN0b3J5UHJvdmlkZXJDbGFzcyA9ICJvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0Lk15Q2VydGlmaWNhdGVGYWN0b3J5U3BpIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGludmFsaWRWYWx1ZXMgPSBTcGlFbmdVdGlscy5pbnZhbGlkVmFsdWVzOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gdmFsaWRWYWx1ZXM7CisKKyAgICBzdGF0aWMgeworICAgICAgICB2YWxpZFZhbHVlcyA9IG5ldyBTdHJpbmdbNF07CisgICAgICAgIHZhbGlkVmFsdWVzWzBdID0gZGVmYXVsdEFsZzsKKyAgICAgICAgdmFsaWRWYWx1ZXNbMV0gPSBkZWZhdWx0QWxnLnRvTG93ZXJDYXNlKCk7CisgICAgICAgIHZhbGlkVmFsdWVzWzJdID0gIkNlUnRGYUMiOworICAgICAgICB2YWxpZFZhbHVlc1szXSA9ICJjZXJURmFjIjsKKyAgICB9CisKKyAgICBQcm92aWRlciBtUHJvdjsKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIG1Qcm92ID0gKG5ldyBTcGlFbmdVdGlscygpKS5uZXcgTXlQcm92aWRlcigiTXlDRlByb3ZpZGVyIiwKKyAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yIHRlc3RpbmciLCBDZXJ0aWZpY2F0ZUZhY3RvcnkxVGVzdC5zcnZDZXJ0aWZpY2F0ZUZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoIi4iKS5jb25jYXQoZGVmYXVsdEFsZyksCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5UHJvdmlkZXJDbGFzcyk7CisgICAgICAgIFNlY3VyaXR5Lmluc2VydFByb3ZpZGVyQXQobVByb3YsIDEpOworICAgIH0KKworICAgIC8qCisgICAgICogQHNlZSBUZXN0Q2FzZSN0ZWFyRG93bigpCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICAgICAgU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIobVByb3YuZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tSZXN1bHQoQ2VydGlmaWNhdGVGYWN0b3J5IGNlcnRGYWN0b3J5LCBib29sZWFuIG1vZGUpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sIENSTEV4Y2VwdGlvbiB7CisgICAgICAgIE15Q2VydGlmaWNhdGVGYWN0b3J5U3BpLnB1dE1vZGUobW9kZSk7CisKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSk7CisgICAgICAgIERhdGFJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGF0YUlucHV0U3RyZWFtKGJhaXMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEZhY3RvcnkuZ2VuZXJhdGVDZXJ0UGF0aChiYWlzKTsKKyAgICAgICAgICAgIGZhaWwoIkNlcnRpZmljYXRlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEZhY3RvcnkuZ2VuZXJhdGVDZXJ0UGF0aChkaXMpOworICAgICAgICAgICAgaWYgKCFtb2RlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiQ2VydGlmaWNhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gYmVjYXVzZSBlbmNvZGluZ3MgbGlzdCBpcyBlbXB0eSIpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAobW9kZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgQ2VydGlmaWNhdGVGYWN0b3J5RXhjZXB0aW9uIHdhcyB0aHJvd24iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEZhY3RvcnkuZ2VuZXJhdGVDZXJ0UGF0aChiYWlzLCAiYWEiKTsKKyAgICAgICAgICAgIGZhaWwoIkNlcnRpZmljYXRlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEZhY3RvcnkuZ2VuZXJhdGVDZXJ0UGF0aChkaXMsICIiKTsKKyAgICAgICAgICAgIGlmIChtb2RlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAoIW1vZGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3YXMgdGhyb3duIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY2VydEZhY3RvcnkuZ2VuZXJhdGVDZXJ0UGF0aChkaXMsICJzcyIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0RmFjdG9yeS5nZW5lcmF0ZUNlcnRpZmljYXRlKGJhaXMpOworICAgICAgICAgICAgZmFpbCgiQ2VydGlmaWNhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0RmFjdG9yeS5nZW5lcmF0ZUNlcnRpZmljYXRlcyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkNlcnRpZmljYXRlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBDZXJ0aWZpY2F0ZSBjZXJ0ID0gY2VydEZhY3RvcnkuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShkaXMpOworICAgICAgICBhc3NlcnROdWxsKCJSZXN1bHQgbXVzdCBiZSBudWxsIiwgY2VydCk7CisgICAgICAgIENvbGxlY3Rpb248PyBleHRlbmRzIENlcnRpZmljYXRlPiBjb2wgPSBjZXJ0RmFjdG9yeS5nZW5lcmF0ZUNlcnRpZmljYXRlcyhkaXMpOworICAgICAgICBhc3NlcnROdWxsKCJSZXN1bHQgbXVzdCBiZSBudWxsIiwgY29sKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEZhY3RvcnkuZ2VuZXJhdGVDUkwoYmFpcyk7CisgICAgICAgICAgICBmYWlsKCJDUkxFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ1JMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEZhY3RvcnkuZ2VuZXJhdGVDUkxzKG51bGwpOworICAgICAgICAgICAgZmFpbCgiQ1JMRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENSTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgQ1JMIGNybCA9IGNlcnRGYWN0b3J5LmdlbmVyYXRlQ1JMKGRpcyk7CisgICAgICAgIGFzc2VydE51bGwoIlJlc3VsdCBtdXN0IGJlIG51bGwiLCBjcmwpOworICAgICAgICBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDUkw+IGNvbGMgPSBjZXJ0RmFjdG9yeS5nZW5lcmF0ZUNSTHMoZGlzKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiUmVzdWx0IG11c3QgYmUgbnVsbCIsIGNvbGMpOworCisgICAgICAgIExpc3Q8Q2VydGlmaWNhdGU+IGxpc3QgPSBudWxsOworICAgICAgICBDZXJ0UGF0aCBjcDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNwID0gY2VydEZhY3RvcnkuZ2VuZXJhdGVDZXJ0UGF0aChsaXN0KTsKKyAgICAgICAgICAgIGlmIChtb2RlKSB7CisgICAgICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbCgiTXVzdCBiZSBudWxsIiwgY3ApOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAoIW1vZGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIHdhcyB0aHJvd24iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBJdGVyYXRvcjxTdHJpbmc+IGl0ID0gY2VydEZhY3RvcnkuZ2V0Q2VydFBhdGhFbmNvZGluZ3MoKTsKKyAgICAgICAgaWYgKG1vZGUpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoaXQuaGFzTmV4dCgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGl0Lmhhc05leHQoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRJbnN0YW5jZShTdHJpbmcgdHlwZSk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbnM6CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gdHlwZSBpcyBudWxsCisgICAgICogdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHdoZW4gdHlwZSBpcyBub3QgYXZhaWxhYmxlCisgICAgICogcmV0dXJucyBDZXJ0aWZpY2F0ZUZhY3Rvcnkgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgR2V0SW5zdGFuY2UwMShib29sZWFuIG1vZGUpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwgQ1JMRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZShudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIENlcnRpZmljYXRlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gdHlwZSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICAgICAgZmFpbCgiQ2VydGlmaWNhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gKHR5cGU6ICIuY29uY2F0KAorICAgICAgICAgICAgICAgICAgICAgICAgaW52YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZXJGOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjZXJGID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHR5cGUiLCBjZXJGLmdldFR5cGUoKSwgdmFsaWRWYWx1ZXNbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgcHJvdmlkZXIiLCBjZXJGLmdldFByb3ZpZGVyKCksIG1Qcm92KTsKKyAgICAgICAgICAgIGNoZWNrUmVzdWx0KGNlckYsIG1vZGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIHR5cGUsIFN0cmluZyBwcm92aWRlcik8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbnM6CisgICAgICogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHdoZW4gdHlwZSBpcyBudWxsCisgICAgICogdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHdoZW4gdHlwZSBpcyBub3QgYXZhaWxhYmxlCisgICAgICogdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aGVuIHByb3ZpZGVyIGlzIG51bGwgb3IgZW1wdHk7CisgICAgICogdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHdoZW4gcHJvdmlkZXIgaXMgYXZhaWxhYmxlOworICAgICAqIHJldHVybnMgQ2VydGlmaWNhdGVGYWN0b3J5IG9iamVjdAorICAgICAqLworCisgICAgcHVibGljIHZvaWQgR2V0SW5zdGFuY2UwMihib29sZWFuIG1vZGUpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIENSTEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UobnVsbCwgbVByb3YuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIG9yIENlcnRpZmljYXRlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIHdoZW4gdHlwZSBpcyBudWxsIik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoaW52YWxpZFZhbHVlc1tpXSwgbVByb3YKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIGZhaWwoIkNlcnRpZmljYXRlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duICh0eXBlOiAiLmNvbmNhdCgKKyAgICAgICAgICAgICAgICAgICAgICAgIGludmFsaWRWYWx1ZXNbaV0pLmNvbmNhdCgiKSIpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgcHJvdiA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBwcm92KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBudWxsICh0eXBlOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KHZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sICIiKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBlbXB0eSAodHlwZTogIgorICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdCh2YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIpIikpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMTsgaiA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UodmFsaWRWYWx1ZXNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW52YWxpZFZhbHVlc1tqXSk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duICh0eXBlOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdCh2YWxpZFZhbHVlc1tpXSkuY29uY2F0KCIgcHJvdmlkZXI6ICIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChpbnZhbGlkVmFsdWVzW2pdKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2VyRjsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgY2VyRiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSh2YWxpZFZhbHVlc1tpXSwgbVByb3YKKyAgICAgICAgICAgICAgICAgICAgLmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB0eXBlIiwgY2VyRi5nZXRUeXBlKCksIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwgY2VyRi5nZXRQcm92aWRlcigpLmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgbVByb3YuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGNoZWNrUmVzdWx0KGNlckYsIG1vZGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0SW5zdGFuY2UoU3RyaW5nIHR5cGUsIFByb3ZpZGVyIHByb3ZpZGVyKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb25zOgorICAgICAqIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIHR5cGUgaXMgbnVsbAorICAgICAqIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB3aGVuIHR5cGUgaXMgbm90IGF2YWlsYWJsZQorICAgICAqIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2hlbiBwcm92aWRlciBpcyBudWxsOworICAgICAqIHJldHVybnMgQ2VydGlmaWNhdGVGYWN0b3J5IG9iamVjdAorICAgICAqLworCisgICAgcHVibGljIHZvaWQgR2V0SW5zdGFuY2UwMyhib29sZWFuIG1vZGUpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgQ1JMRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZShudWxsLCBtUHJvdik7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBvciBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biB3aGVuIHR5cGUgaXMgbnVsbCIpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKGludmFsaWRWYWx1ZXNbaV0sIG1Qcm92KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biAodHlwZTogIi5jb25jYXQoCisgICAgICAgICAgICAgICAgICAgICAgICBpbnZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgUHJvdmlkZXIgcHJvdiA9IG51bGw7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBwcm92KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24gd2hlbiBwcm92aWRlciBpcyBudWxsICh0eXBlOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KHZhbGlkVmFsdWVzW2ldKS5jb25jYXQoIikiKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZXJGOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjZXJGID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKHZhbGlkVmFsdWVzW2ldLCBtUHJvdik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCB0eXBlIiwgY2VyRi5nZXRUeXBlKCksIHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHByb3ZpZGVyIiwgY2VyRi5nZXRQcm92aWRlcigpLCBtUHJvdik7CisgICAgICAgICAgICBjaGVja1Jlc3VsdChjZXJGLCAgbW9kZSk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlMDEoKSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sIENSTEV4Y2VwdGlvbiB7CisgICAgICAgIEdldEluc3RhbmNlMDEodHJ1ZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZTAyKCkgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uLAorICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBDUkxFeGNlcHRpb24geworICAgICAgICBHZXRJbnN0YW5jZTAyKHRydWUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2UwMygpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwKKyAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBDUkxFeGNlcHRpb24geworICAgICAgICBHZXRJbnN0YW5jZTAzKHRydWUpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2UwNCgpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwgQ1JMRXhjZXB0aW9uIHsKKyAgICAgICAgR2V0SW5zdGFuY2UwMShmYWxzZSk7CisgICAgfQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZTA1KCkgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uLAorICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBDUkxFeGNlcHRpb24geworICAgICAgICBHZXRJbnN0YW5jZTAyKGZhbHNlKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlMDYoKSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sCisgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgQ1JMRXhjZXB0aW9uIHsKKyAgICAgICAgR2V0SW5zdGFuY2UwMyhmYWxzZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVGYWN0b3J5M1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRmFjdG9yeTNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjkwOGI2OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRmFjdG9yeTNUZXN0LmphdmEKQEAgLTAsMCArMSwxOTAgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuU3BpRW5nVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5UZXN0VXRpbHM7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5yZXNvdXJjZS5TdXBwb3J0X1Jlc291cmNlczsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRmFjdG9yeTsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+Q2VydGlmaWNhdGVGYWN0b3J5PC9jb2RlPiBjbGFzcyBtZXRob2RzCisgKi8KK3B1YmxpYyBjbGFzcyBDZXJ0aWZpY2F0ZUZhY3RvcnkzVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZWZhdWx0UHJvdmlkZXJOYW1lID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIFByb3ZpZGVyIGRlZmF1bHRQcm92aWRlciA9IG51bGw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZGVmYXVsdFR5cGUgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkxVGVzdC5kZWZhdWx0VHlwZTsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGZpbGVDZXJ0UGF0aFBraSA9ICJqYXZhL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGguUGtpUGF0aCI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIFg1MDlTdXBwb3J0ID0gZmFsc2U7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgTm90U3VwcG9ydE1zZyA9ICIiOworCisgICAgc3RhdGljIHsKKyAgICAgICAgZGVmYXVsdFByb3ZpZGVyID0gU3BpRW5nVXRpbHMuaXNTdXBwb3J0KGRlZmF1bHRUeXBlLAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeTFUZXN0LnNydkNlcnRpZmljYXRlRmFjdG9yeSk7CisgICAgICAgIFg1MDlTdXBwb3J0ID0gZGVmYXVsdFByb3ZpZGVyICE9IG51bGw7CisgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUgPSBYNTA5U3VwcG9ydCA/IGRlZmF1bHRQcm92aWRlci5nZXROYW1lKCkgOiBudWxsOworCisgICAgICAgIE5vdFN1cHBvcnRNc2cgPSBkZWZhdWx0VHlwZS5jb25jYXQoIiBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgQ2VydGlmaWNhdGVGYWN0b3J5W10gaW5pdENlcnRGcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBpZiAoIVg1MDlTdXBwb3J0KSB7CisgICAgICAgICAgICBmYWlsKE5vdFN1cHBvcnRNc2cpOworICAgICAgICB9CisKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5W10gY2VydEZzID0gbmV3IENlcnRpZmljYXRlRmFjdG9yeVszXTsKKyAgICAgICAgY2VydEZzWzBdID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKGRlZmF1bHRUeXBlKTsKKyAgICAgICAgY2VydEZzWzFdID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKGRlZmF1bHRUeXBlLAorICAgICAgICAgICAgICAgIGRlZmF1bHRQcm92aWRlck5hbWUpOworICAgICAgICBjZXJ0RnNbMl0gPSBDZXJ0aWZpY2F0ZUZhY3RvcnkKKyAgICAgICAgICAgICAgICAuZ2V0SW5zdGFuY2UoZGVmYXVsdFR5cGUsIGRlZmF1bHRQcm92aWRlcik7CisgICAgICAgIHJldHVybiBjZXJ0RnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2VuZXJhdGVDZXJ0aWZpY2F0ZShJbnB1dFN0cmVhbSBpblN0cmVhbSk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBDZXJ0aWZpY2F0ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmF0ZUNlcnRpZmljYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeVtdIGNlcnRGcyA9IGluaXRDZXJ0RnMoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ2VydGlmaWNhdGVGYWN0b3J5IG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIGNlcnRGcyk7CisgICAgICAgIENlcnRpZmljYXRlW10gY2VydHMgPSBuZXcgQ2VydGlmaWNhdGVbM107CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2VydEZzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBjZXJ0c1tpXSA9IGNlcnRGc1tpXS5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICAgICAgVGVzdFV0aWxzLmdldEVuY29kZWRYNTA5Q2VydGlmaWNhdGUoKSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscyhjZXJ0c1swXSwgY2VydHNbMV0pOworICAgICAgICBhc3NlcnRFcXVhbHMoY2VydHNbMF0sIGNlcnRzWzJdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZW5lcmF0ZUNlcnRpZmljYXRlcyhJbnB1dFN0cmVhbSBpblN0cmVhbSk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBDb2xsZWN0aW9uIHdoaWNoIGNvbnNpc3RzIG9mIDEgQ2VydGlmaWNhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2VuZXJhdGVDZXJ0aWZpY2F0ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5W10gY2VydEZzID0gaW5pdENlcnRGcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKCJDZXJ0aWZpY2F0ZUZhY3Rvcnkgb2JqZWN0cyB3ZXJlIG5vdCBjcmVhdGVkIiwgY2VydEZzKTsKKyAgICAgICAgQ2VydGlmaWNhdGUgY2VydCA9IGNlcnRGc1swXQorICAgICAgICAgICAgICAgIC5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShUZXN0VXRpbHMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRFbmNvZGVkWDUwOUNlcnRpZmljYXRlKCkpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjZXJ0RnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIENvbGxlY3Rpb248PyBleHRlbmRzIENlcnRpZmljYXRlPiBjb2wgPSBudWxsOworICAgICAgICAgICAgY29sID0gY2VydEZzW2ldLmdlbmVyYXRlQ2VydGlmaWNhdGVzKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICAgICAgVGVzdFV0aWxzLmdldEVuY29kZWRYNTA5Q2VydGlmaWNhdGUoKSkpOworICAgICAgICAgICAgSXRlcmF0b3I8PyBleHRlbmRzIENlcnRpZmljYXRlPiBpdCA9IGNvbC5pdGVyYXRvcigpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgQ29sbGVjdGlvbiBzaXplIiwgY29sLnNpemUoKSwgMSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkluY29ycmVjdCBDZXJ0aWZpY2F0ZSBpbiBDb2xsZWN0aW9uIiwgY2VydCwgaXQubmV4dCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdlbmVyYXRlQ2VydFBhdGgoTGlzdCBjZXJ0aWZpY2F0ZXMpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgQ2VydFBhdGggd2l0aCAxIENlcnRpZmljYXRlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdlbmVyYXRlQ2VydFBhdGgwMSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnlbXSBjZXJ0RnMgPSBpbml0Q2VydEZzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkNlcnRpZmljYXRlRmFjdG9yeSBvYmplY3RzIHdlcmUgbm90IGNyZWF0ZWQiLCBjZXJ0RnMpOworICAgICAgICAvLyBjcmVhdGUgbGlzdCBvZiBjZXJ0aWZpY2F0ZXMgd2l0aCBvbmUgY2VydGlmaWNhdGUKKyAgICAgICAgQ2VydGlmaWNhdGUgY2VydCA9IGNlcnRGc1swXQorICAgICAgICAgICAgICAgIC5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShUZXN0VXRpbHMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRFbmNvZGVkWDUwOUNlcnRpZmljYXRlKCkpKTsKKyAgICAgICAgTGlzdDxDZXJ0aWZpY2F0ZT4gbGlzdCA9IG5ldyBWZWN0b3I8Q2VydGlmaWNhdGU+KCk7CisgICAgICAgIGxpc3QuYWRkKGNlcnQpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNlcnRGcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgQ2VydFBhdGggY2VydFBhdGggPSBudWxsOworICAgICAgICAgICAgY2VydFBhdGggPSBjZXJ0RnNbaV0uZ2VuZXJhdGVDZXJ0UGF0aChsaXN0KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhjZXJ0LmdldFR5cGUoKSwgY2VydFBhdGguZ2V0VHlwZSgpKTsKKyAgICAgICAgICAgIExpc3Q8PyBleHRlbmRzIENlcnRpZmljYXRlPiBsaXN0MSA9IGNlcnRQYXRoLmdldENlcnRpZmljYXRlcygpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoIlJlc3VsdCBsaXN0IGlzIGVtcHR5IiwgbGlzdDEuaXNFbXB0eSgpKTsKKyAgICAgICAgICAgIEl0ZXJhdG9yPD8gZXh0ZW5kcyBDZXJ0aWZpY2F0ZT4gaXQgPSBsaXN0MS5pdGVyYXRvcigpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbmNvcnJlY3QgQ2VydGlmaWNhdGUgaW4gQ2VydFBhdGgiLCBjZXJ0LCBpdC5uZXh0KCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IKKyAgICAgKiA8Y29kZT5nZW5lcmF0ZUNlcnRQYXRoKElucHV0U3RyZWFtIGluU3RyZWFtLCBTdHJpbmcgZW5jb2RpbmcpPC9jb2RlPgorICAgICAqIG1ldGhvZCBBc3NlcnRpb246IHJldHVybnMgQ2VydFBhdGggd2l0aCAxIENlcnRpZmljYXRlCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdlbmVyYXRlQ2VydFBhdGgwMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnlbXSBjZXJ0RnMgPSBpbml0Q2VydEZzKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkNlcnRpZmljYXRlRmFjdG9yeSBvYmplY3RzIHdlcmUgbm90IGNyZWF0ZWQiLCBjZXJ0RnMpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNlcnRGcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgQ2VydFBhdGggY2VydFBhdGggPSBudWxsOworICAgICAgICAgICAgSW5wdXRTdHJlYW0gZmlzID0gU3VwcG9ydF9SZXNvdXJjZXMKKyAgICAgICAgICAgICAgICAgICAgLmdldFJlc291cmNlU3RyZWFtKGZpbGVDZXJ0UGF0aFBraSk7CisgICAgICAgICAgICBjZXJ0UGF0aCA9IGNlcnRGc1tpXS5nZW5lcmF0ZUNlcnRQYXRoKGZpcywgIlBraVBhdGgiKTsKKyAgICAgICAgICAgIGZpcy5jbG9zZSgpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGRlZmF1bHRUeXBlLCBjZXJ0UGF0aC5nZXRUeXBlKCkpOworCisgICAgICAgICAgICBMaXN0PD8gZXh0ZW5kcyBDZXJ0aWZpY2F0ZT4gbGlzdDEgPSBjZXJ0UGF0aC5nZXRDZXJ0aWZpY2F0ZXMoKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJSZXN1bHQgbGlzdCBpcyBlbXB0eSIsIGxpc3QxLmlzRW1wdHkoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZW5lcmF0ZUNlcnRQYXRoKElucHV0U3RyZWFtIGluU3RyZWFtKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIENlcnRQYXRoIHdpdGggMSBDZXJ0aWZpY2F0ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmF0ZUNlcnRQYXRoMDMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGNlcnRQYXRoRW5jb2RpbmcgPSAiUGtpUGF0aCI7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeVtdIGNlcnRGcyA9IGluaXRDZXJ0RnMoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiQ2VydGlmaWNhdGVGYWN0b3J5IG9iamVjdHMgd2VyZSBub3QgY3JlYXRlZCIsIGNlcnRGcyk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2VydEZzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBJdGVyYXRvcjxTdHJpbmc+IGl0ID0gY2VydEZzWzBdLmdldENlcnRQYXRoRW5jb2RpbmdzKCk7CisKKyAgICAgICAgICAgIGFzc2VydFRydWUoIm5vIENlcnRQYXRoIGVuY29kaW5ncyIsIGl0Lmhhc05leHQoKSk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IGRlZmF1bHQgZW5jb2RpbmciLCBjZXJ0UGF0aEVuY29kaW5nLCBpdAorICAgICAgICAgICAgICAgICAgICAubmV4dCgpKTsKKworICAgICAgICAgICAgQ2VydFBhdGggY2VydFBhdGggPSBudWxsOworICAgICAgICAgICAgSW5wdXRTdHJlYW0gZmlzID0gU3VwcG9ydF9SZXNvdXJjZXMKKyAgICAgICAgICAgICAgICAgICAgLmdldFJlc291cmNlU3RyZWFtKGZpbGVDZXJ0UGF0aFBraSk7CisgICAgICAgICAgICBjZXJ0UGF0aCA9IGNlcnRGc1tpXS5nZW5lcmF0ZUNlcnRQYXRoKGZpcyk7CisgICAgICAgICAgICBmaXMuY2xvc2UoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhkZWZhdWx0VHlwZSwgY2VydFBhdGguZ2V0VHlwZSgpKTsKKworICAgICAgICAgICAgTGlzdDw/IGV4dGVuZHMgQ2VydGlmaWNhdGU+IGxpc3QxID0gY2VydFBhdGguZ2V0Q2VydGlmaWNhdGVzKCk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSgiUmVzdWx0IGxpc3QgaXMgZW1wdHkiLCBsaXN0MS5pc0VtcHR5KCkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVGYWN0b3J5NFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRmFjdG9yeTRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDYwYTRhMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRmFjdG9yeTRUZXN0LmphdmEKQEAgLTAsMCArMSw2MDUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCB0ZXN0cy5zdXBwb3J0LnJlc291cmNlLlN1cHBvcnRfUmVzb3VyY2VzOworCitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0dldFJlc291cmNlOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DUkw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNSTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK3B1YmxpYyBjbGFzcyBDZXJ0aWZpY2F0ZUZhY3Rvcnk0VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBCQVNFX1VSTCA9IFN1cHBvcnRfR2V0UmVzb3VyY2UKKyAgICAgICAgICAgIC5nZXRSZXNvdXJjZVVSTCgiLy4uL2ludGVybmFscmVzLyIpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gQ0VSVElGSUNBVEVfVVJMUyA9IG5ldyBTdHJpbmdbXSB7CisgICAgICAgICAgICAiQnVnOTM4OTEtUEVNLmNlciIsICJCdWc5Mzg5MS1ERVIuY2VyIiwgIkJ1Zzk0NDA0LVBLQ1M3LmNlciIgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIENSTF9VUkxTID0gbmV3IFN0cmluZ1tdIHsgIkJ1ZzkzODkzLTEuY3JsIiwKKyAgICAgICAgICAgICJCdWc5Mzg5My0yLmNybCIsICJCdWc5NDQwNC1ERVIuY3JsIiB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gQ1JMQ09MTEVDVElPTl9VUkxTID0gbmV3IFN0cmluZ1tdIHsgIkJ1Zzk0NDA0LVBLQ1M3LmNybCIgfTsKKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3RvcnkjZ2VuZXJhdGVDZXJ0aWZpY2F0ZShqYXZhLmlvLklucHV0U3RyZWFtKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2VuZXJhdGVDZXJ0aWZpY2F0ZUxqYXZhX2lvX0lucHV0U3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgMQorICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlCisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3RvcnkuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShqYXZhLmlvLklucHV0U3RyZWFtKQorICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgZmFjdCA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBDRVJUSUZJQ0FURVNfRU5DT0RFRF9YNTA5Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiYWlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgICAgICBDRVJUSUZJQ0FURVNfRU5DT0RFRF9YNTA5W2ldLmdldEJ5dGVzKCkpOworICAgICAgICAgICAgZmFjdC5nZW5lcmF0ZUNlcnRpZmljYXRlKGJhaXMpOworCisgICAgICAgICAgICAvLyB0cnkgYWdhaW4gd2l0aCBnZW5lcmF0ZUNlcnRpZmljYXRlcygpCisgICAgICAgICAgICBiYWlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKENFUlRJRklDQVRFU19FTkNPREVEX1g1MDlbaV0KKyAgICAgICAgICAgICAgICAgICAgLmdldEJ5dGVzKCkpOworICAgICAgICAgICAgZmFjdC5nZW5lcmF0ZUNlcnRpZmljYXRlKGJhaXMpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVGVzdCAyCisgICAgICAgIElucHV0U3RyZWFtIGlzID0gU3VwcG9ydF9SZXNvdXJjZXMuZ2V0UmVzb3VyY2VTdHJlYW0oImh5dHNfYmFkcGVtLmNlciIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmFjdC5nZW5lcmF0ZUNlcnRpZmljYXRlKGlzKTsKKyAgICAgICAgICAgIGZhaWwoIlRlc3QyOiBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHt9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpcy5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlKSB7fQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRmFjdG9yeSNnZW5lcmF0ZUNlcnRpZmljYXRlcyhqYXZhLmlvLklucHV0U3RyZWFtKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2VuZXJhdGVDZXJ0aWZpY2F0ZXNMamF2YV9pb19JbnB1dFN0cmVhbSgpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGZhY3QgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQ0VSVElGSUNBVEVfVVJMUy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgVVJMIGNlcnRVcmwgPSBuZXcgVVJMKEJBU0VfVVJMICsgQ0VSVElGSUNBVEVfVVJMU1tpXSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gY2VydFVybC5vcGVuU3RyZWFtKCk7CisgICAgICAgICAgICAgICAgQ29sbGVjdGlvbjw/IGV4dGVuZHMgQ2VydGlmaWNhdGU+IGNlcnRzID0gZmFjdC5nZW5lcmF0ZUNlcnRpZmljYXRlcyhpcyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiVGhlIGNlcnRpZmljYXRlcyBpbiBcIiIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgY2VydFVybC50b0V4dGVybmFsRm9ybSgpCisgICAgICAgICAgICAgICAgICAgICAgICArICJcIiB3ZXJlIG5vdCBwYXJzZWQgY29ycmVjdGx5IiwgY2VydHMpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIHRoZSBjZXJ0aWZpY2F0ZSBjb3VsZCBub3QgYmUgZm91bmQsIHNraXAgaXQKKyAgICAgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJBbiBleGNlcHRpb24gd2FzIHRocm93biB3aGlsZSBwYXJzaW5nIFwiIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBjZXJ0VXJsLnRvRXh0ZXJuYWxGb3JtKCkgKyAiXCI6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5I2dlbmVyYXRlQ1JMKGphdmEuaW8uSW5wdXRTdHJlYW0pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZW5lcmF0ZUNSTExqYXZhX2lvX0lucHV0U3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBmYWN0ID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IENSTF9VUkxTLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBVUkwgY2VydFVybCA9IG5ldyBVUkwoQkFTRV9VUkwgKyBDUkxfVVJMU1tpXSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gY2VydFVybC5vcGVuU3RyZWFtKCk7CisgICAgICAgICAgICAgICAgQ1JMIGNybCA9IGZhY3QuZ2VuZXJhdGVDUkwoaXMpOworICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwoIlRoZSBDUkwgaW4gXCIiICsgY2VydFVybC50b0V4dGVybmFsRm9ybSgpCisgICAgICAgICAgICAgICAgICAgICAgICArICJcIiB3ZXJlIG5vdCBwYXJzZWQgY29ycmVjdGx5IiwgY3JsKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyB0aGUgY2VydGlmaWNhdGUgY291bGQgbm90IGJlIGZvdW5kLCBza2lwIGl0CisgICAgICAgICAgICB9IGNhdGNoIChDUkxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGZhaWwoIkFuIGV4Y2VwdGlvbiB3YXMgdGhyb3duIHdoaWxlIHBhcnNpbmcgXCIiCisgICAgICAgICAgICAgICAgICAgICAgICArIGNlcnRVcmwudG9FeHRlcm5hbEZvcm0oKSArICJcIjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3RvcnkjZ2VuZXJhdGVDUkxzKGphdmEuaW8uSW5wdXRTdHJlYW0pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZW5lcmF0ZUNSTHNMamF2YV9pb19JbnB1dFN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgZmFjdCA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBDUkxDT0xMRUNUSU9OX1VSTFMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFVSTCBjZXJ0VXJsID0gbmV3IFVSTChCQVNFX1VSTCArIENSTENPTExFQ1RJT05fVVJMU1tpXSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gY2VydFVybC5vcGVuU3RyZWFtKCk7CisgICAgICAgICAgICAgICAgQ29sbGVjdGlvbjw/IGV4dGVuZHMgQ1JMPiBjcmxzID0gZmFjdC5nZW5lcmF0ZUNSTHMoaXMpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoIlRoZSBDUkxzIGluIFwiIiArIGNlcnRVcmwudG9FeHRlcm5hbEZvcm0oKQorICAgICAgICAgICAgICAgICAgICAgICAgKyAiXCIgd2VyZSBub3QgcGFyc2VkIGNvcnJlY3RseSIsIGNybHMgIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgJiYgY3Jscy5zaXplKCkgPiAwKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyB0aGUgY2VydGlmaWNhdGUgY291bGQgbm90IGJlIGZvdW5kLCBza2lwIGl0CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5I2dldEluc3RhbmNlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJbnN0YW5jZUxqYXZhX2xhbmdfU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5CisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoamF2YS5sYW5nLlN0cmluZykKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGZhY3QgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIGFzc2VydFRydWUoImZhY3RvcnkgaXMgbnVsbCIsIGZhY3QgIT0gbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRmFjdG9yeSNnZXRJbnN0YW5jZShqYXZhLmxhbmcuU3RyaW5nLAorICAgICAqICAgICAgICBqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SW5zdGFuY2VMamF2YV9sYW5nX1N0cmluZ0xqYXZhX2xhbmdfU3RyaW5nKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBUZXN0IGZvciBtZXRob2QgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRmFjdG9yeQorICAgICAgICAvLyBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKGphdmEubGFuZy5TdHJpbmcsCisgICAgICAgIC8vIGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIFByb3ZpZGVyW10gcHJvdmlkZXJzID0gU2VjdXJpdHkKKyAgICAgICAgICAgICAgICAuZ2V0UHJvdmlkZXJzKCJDZXJ0aWZpY2F0ZUZhY3RvcnkuWC41MDkiKTsKKworICAgICAgICBpZiAocHJvdmlkZXJzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdmlkZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGZhY3QgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoCisgICAgICAgICAgICAgICAgICAgICAgICAiWC41MDkiLCBwcm92aWRlcnNbaV0uZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKCJmYWN0b3J5IGlzIG51bGwiLCBmYWN0KTsKKyAgICAgICAgICAgIH0vLyBlbmQgZm9yCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmYWlsKCJObyBwcm92aWRlcnMgc3VwcG9ydCBDZXJ0aWZpY2F0ZUZhY3RvcnkuWC41MDkiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGV4Y2VwdGlvbiBjYXNlCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5IiwgIklIYXZlbnRCZWVuQ29uZmlndXJlZCIpOworICAgICAgICAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIEV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5I2dldFByb3ZpZGVyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFByb3ZpZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIFRlc3QgZm9yIG1ldGhvZCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyCisgICAgICAgIC8vIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0UHJvdmlkZXIoKQorICAgICAgICBQcm92aWRlciBwID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpLmdldFByb3ZpZGVyKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoInByb3ZpZGVyIGlzIG51bGwiLCBwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5I2dlbmVyYXRlQ1JMcyhJbnB1dFN0cmVhbQorICAgICAqICAgICAgICBpblN0cmVhbSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2VuZXJhdGVDUkxzMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTgxNAorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpLmdlbmVyYXRlQ1JMKAorICAgICAgICAgICAgICAgICAgICAoSW5wdXRTdHJlYW0pIG51bGwpOworICAgICAgICAgICAgZmFpbCgiQ1JMRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENSTEV4Y2VwdGlvbiBlKSB7fQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3RvcnkjZ2VuZXJhdGVDZXJ0aWZpY2F0ZShJbnB1dFN0cmVhbQorICAgICAqICAgICAgICBpblN0cmVhbSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2VuZXJhdGVDZXJ0aWZpY2F0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTgxNAorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpLmdlbmVyYXRlQ2VydGlmaWNhdGUobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7fQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3RvcnkjZ2VuZXJhdGVDZXJ0aWZpY2F0ZXMoSW5wdXRTdHJlYW0KKyAgICAgKiAgICAgICAgaW5TdHJlYW0pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdlbmVyYXRlQ2VydGlmaWNhdGVzMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTgxNAorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpLmdlbmVyYXRlQ2VydGlmaWNhdGVzKG51bGwpOworICAgICAgICAgICAgZmFpbCgiQ2VydGlmaWNhdGVFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkge30KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5I2dlbmVyYXRlQ2VydFBhdGgoSW5wdXRTdHJlYW0KKyAgICAgKiAgICAgICAgaW5TdHJlYW0sIFN0cmluZyBlbmNvZGluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2VuZXJhdGVDZXJ0UGF0aDEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS04MTQKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKS5nZW5lcmF0ZUNlcnRQYXRoKAorICAgICAgICAgICAgICAgICAgICAoSW5wdXRTdHJlYW0pIG51bGwsICJQa2lQYXRoIik7CisgICAgICAgICAgICBmYWlsKCJDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7fQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3RvcnkjZ2VuZXJhdGVDZXJ0UGF0aChMaXN0PD8KKyAgICAgKiAgICAgICAgZXh0ZW5kcyBDZXJ0aWZpY2F0ZT4gY2VydGlmaWNhdGVzKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmF0ZUNlcnRQYXRoMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTgxNAorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpLmdlbmVyYXRlQ2VydFBhdGgoCisgICAgICAgICAgICAgICAgICAgIChMaXN0PENlcnRpZmljYXRlPikgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiB3YXMgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7fQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3RvcnkjZ2VuZXJhdGVDZXJ0UGF0aChJbnB1dFN0cmVhbQorICAgICAqICAgICAgICBpblN0cmVhbSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2VuZXJhdGVDZXJ0UGF0aDMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS04MTQKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKS5nZW5lcmF0ZUNlcnRQYXRoKAorICAgICAgICAgICAgICAgICAgICAoSW5wdXRTdHJlYW0pIG51bGwpOworICAgICAgICAgICAgZmFpbCgiQ2VydGlmaWNhdGVFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkge30KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5I2dlbmVyYXRlQ1JMKElucHV0U3RyZWFtCisgICAgICogICAgICAgIGluU3RyZWFtKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZW5lcmF0ZUNSTCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTgxNAorICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpLmdlbmVyYXRlQ1JMKAorICAgICAgICAgICAgICAgICAgICAoSW5wdXRTdHJlYW0pIG51bGwpOworICAgICAgICAgICAgZmFpbCgiQ1JMRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENSTEV4Y2VwdGlvbiBlKSB7fQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIENFUlRJRklDQVRFU19FTkNPREVEX1g1MDkgPSB7CisgICAgICAgICAgICAvLyBDRVJUSUZJQ0FURVNfRU5DT0RFRF9YNTA5WzBdCisgICAgICAgICAgICAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICAgICAgICAgICAgICsgIk1JSUNaVENDQWRJQ0JRTDNBQUMyTUEwR0NTcUdTSWIzRFFFQkFnVUFNRjh4Q3pBSkJnTlZCQVlUQWxWVE1TQXdcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiSGdZRFZRUUtFeGRTVTBFZ1JHRjBZU0JUWldOMWNtbDBlU3dnU1c1akxqRXVNQ3dHQTFVRUN4TWxVMlZqZFhKbFxuIgorICAgICAgICAgICAgICAgICAgICArICJJRk5sY25abGNpQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVRBZUZ3MDVOekF5TWpBd01EQXdNREJhXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkZ3MDVPREF5TWpBeU16VTVOVGxhTUlHV01Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiY201cFlURVNNQkFHQTFVRUJ4TUpVR0ZzYnlCQmJIUnZNUjh3SFFZRFZRUUtFeFpUZFc0Z1RXbGpjbTl6ZVhOMFxuIgorICAgICAgICAgICAgICAgICAgICArICJaVzF6TENCSmJtTXVNU0V3SHdZRFZRUUxFeGhVWlhOMElHRnVaQ0JGZG1Gc2RXRjBhVzl1SUU5dWJIa3hHakFZXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkJnTlZCQU1URVdGeVoyOXVMbVZ1Wnk1emRXNHVZMjl0TUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiaVFLQmdRQ29mbWRZK1BpVVdOMDFGT3pFZXdmK0dhRytsRmYxMzJVcHpBVG1ZSmtBNEFFQS9qdVc3alNpK0xKa1xuIgorICAgICAgICAgICAgICAgICAgICArICJ3SktpNUdPNFJ5Wm95aW1BTC81eUlXRFY2bDFLbHZ4eUtzbHIwUkVoTUJhRC8zWjNFc0xUVEVmNWdWclFTNnNUXG4iCisgICAgICAgICAgICAgICAgICAgICsgIldNb1NaQXl6QjM5a0Zmc0I2b1VYTnRWOCtVS0t4U3hLYnh2aFFuMjY3UGVDejVWWDJRSURBUUFCTUEwR0NTcUdcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiU0liM0RRRUJBZ1VBQTM0QVhsM2F0Nmx1aVYvN0k5TU41Q1hZb1BKWUk4QmNkYzFoQmFnSnZUTWNtbHFMMnVPWlxuIgorICAgICAgICAgICAgICAgICAgICArICJIOVQ1aE5NRUw5VGs2YUk3eVpQWGN3L3hJMks2cE9SL0ZyTXAwVXdKbWR4WDdsalY2WnRVWmY3cFk0OTJVcXdDXG4iCisgICAgICAgICAgICAgICAgICAgICsgIjE3NzdYUTlVRVp5cktKdkY1bnRsZWVPMGF5QnFMR1ZLQ1d6V1pYOVlzWENwdjQ3Rk5MWmJ1cEU9XG4iCisgICAgICAgICAgICAgICAgICAgICsgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cbiIsCisKKyAgICAgICAgICAgIC8vIENFUlRJRklDQVRFU19FTkNPREVEX1g1MDlbMV0KKyAgICAgICAgICAgICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTUlJQ1p6Q0NBZENnQXdJQkFnSUJHekFOQmdrcWhraUc5dzBCQVFVRkFEQmhNUXN3Q1FZRFZRUUdFd0pWVXpFWVxuIgorICAgICAgICAgICAgICAgICAgICArICJNQllHQTFVRUNoTVBWUzVUTGlCSGIzWmxjbTV0Wlc1ME1Rd3dDZ1lEVlFRTEV3TkViMFF4RERBS0JnTlZCQXNUXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkExQkxTVEVjTUJvR0ExVUVBeE1UUkc5RUlGQkxTU0JOWldRZ1VtOXZkQ0JEUVRBZUZ3MDVPREE0TURNeU1qQXlcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTWpsYUZ3MHdPREE0TURReU1qQXlNamxhTUdFeEN6QUpCZ05WQkFZVEFsVlRNUmd3RmdZRFZRUUtFdzlWTGxNdVxuIgorICAgICAgICAgICAgICAgICAgICArICJJRWR2ZG1WeWJtMWxiblF4RERBS0JnTlZCQXNUQTBSdlJERU1NQW9HQTFVRUN4TURVRXRKTVJ3d0dnWURWUVFEXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkV4TkViMFFnVUV0SklFMWxaQ0JTYjI5MElFTkJNSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdOQURDQmlRS0JcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiZ1FEYnJNL0o5RnJKU1grenhGVWJzSTlWdzVRYmd1VkJJYTk1cndXLzBNOCtzTTByNWdkK0RZNml1Ym02d25Ya1xuIgorICAgICAgICAgICAgICAgICAgICArICJDU3ZiZlFsRkVEU0tyNFdZZWVHcCtkOVdsRG5RZHRERkxkQTQ1dENpNVNIam5XK2hHQW1abmxkMHJ6NndRZWtGXG4iCisgICAgICAgICAgICAgICAgICAgICsgIjV4UWFhNUE2d2poTWxMT2piaDI3enlzY3Jvck1KMU81RkJPV25FSGNSdjZ4cVFJREFRQUJveTh3TFRBZEJnTlZcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiSFE0RUZnUVVWcm1ZUjZtOTcwMWNIUTNyNWtYeUc3enNDTjB3REFZRFZSMFRCQVV3QXdFQi96QU5CZ2txaGtpR1xuIgorICAgICAgICAgICAgICAgICAgICArICI5dzBCQVFVRkFBT0JnUURWWDFZMFlxQzd2ZWtlWmpWeHR5dUM4TW54YnJ6NkQxMDlBWDA3TEVJUnpOWXp3WjB3XG4iCisgICAgICAgICAgICAgICAgICAgICsgIk1USW1TcDlzRXpXVyszRnVlQklVN0F4R3lzMk83WDBxbU4zemdzelBmU2lvY0J1UXVYSVlRY3RKaEtqRjVLVmNcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiVkdRUllZbHQrbXlobDJ2eTZ5UHpFVkNqaUt3TUViMVNwdTBpckNmK2xGVzJoc2Rqdm1TUU10WnZPdz09XG4iCisgICAgICAgICAgICAgICAgICAgICsgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cbiIsCisKKyAgICAgICAgICAgIC8vIENFUlRJRklDQVRFU19FTkNPREVEX1g1MDlbMl0KKyAgICAgICAgICAgICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTUlJRDZUQ0NBMUtnQXdJQkFnSUJHakFOQmdrcWhraUc5dzBCQVFVRkFEQmhNUXN3Q1FZRFZRUUdFd0pWVXpFWVxuIgorICAgICAgICAgICAgICAgICAgICArICJNQllHQTFVRUNoTVBWUzVUTGlCSGIzWmxjbTV0Wlc1ME1Rd3dDZ1lEVlFRTEV3TkViMFF4RERBS0JnTlZCQXNUXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkExQkxTVEVjTUJvR0ExVUVBeE1UUkc5RUlGQkxTU0JOWldRZ1VtOXZkQ0JEUVRBZUZ3MDVPREE0TURJeE5qUTFcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTXpoYUZ3MHdNekE0TURJeE5qUTFNemhhTUZZeEN6QUpCZ05WQkFZVEFsVlRNUmd3RmdZRFZRUUtFdzlWTGxNdVxuIgorICAgICAgICAgICAgICAgICAgICArICJJRWR2ZG1WeWJtMWxiblF4RERBS0JnTlZCQXNUQTBSdlJERU1NQW9HQTFVRUN4TURVRXRKTVJFd0R3WURWUVFEXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkV3aE5aV1FnUTBFdE1UQ0JuekFOQmdrcWhraUc5dzBCQVFFRkFBT0JqUUF3Z1lrQ2dZRUF5VWNydzFrNlFLZEJcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiV2pndEdPazFBVmFxSk5JOGFjREdnbGhxUVE5NFFZZnFaS3VvMXd3ZG5ZZWhyZ281UWNHa3c5WGNqQlllZ0xGc1xuIgorICAgICAgICAgICAgICAgICAgICArICJ2NE5DQ3daMnBnc2ZZSmx2SGNTR1BoVC93Uk9VWUVwWEtlbGZYaUVlYUdoRmw4ekdjcXRlSTIrRUJiT1puRnBqXG4iCisgICAgICAgICAgICAgICAgICAgICsgIlk0eSsyNWRRY2pZbnJSR01BUTk4cUd3UXRvZ0RpRGNDQXdFQUFhT0NBYm93Z2dHMk1CWUdBMVVkSUFRUE1BMHdcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiQ3dZSllJWklBV1VDQVFzRE1COEdBMVVkSXdRWU1CYUFGRmE1bUVlcHZlOU5YQjBONitaRjhodTg3QWpkTUF3R1xuIgorICAgICAgICAgICAgICAgICAgICArICJBMVVkSkFRRk1BT0FBUUF3SFFZRFZSME9CQllFRkRNNkZPZ0paMkdJWlNRZzdIbHdRdGVta3g3Mk1BNEdBMVVkXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkR3RUIvd1FFQXdJQmhqQitCZ05WSFJJRWR6QjFobk5zWkdGd09pOHZaSE10TVM1amFHRnRZaTVrYVhOaExtMXBcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiYkM5amJpVXpaRVJ2UkNVeU1GQkxTU1V5TUUxbFpDVXlNRkp2YjNRbE1qQkRRU1V5WTI5MUpUTmtVRXRKSlRJZ1xuIgorICAgICAgICAgICAgICAgICAgICArICJZMjkxSlROa1JHOUVKVEpqYnlVelpGVXVVeTRsTWpCSGIzWmxjbTV0Wlc1MEpUSmpZeVV6WkZWVE1BOEdBMVVkXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkV3RUIvd1FGTUFNQkFmOHdnYXdHQTFVZEh3U0JwRENCb1RDQm5xQ0JtNkNCbUlhQmxXeGtZWEE2THk5a2N5MHhcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTG1Ob1lXMWlMbVJwYzJFdWJXbHNMMk51SlROa1JHOUVKVEl3VUV0SkpUSXdUV1ZrSlRJd1VtOXZkQ1V5TUVOQlxuIgorICAgICAgICAgICAgICAgICAgICArICJKVEpqYjNVbE0yUlFTMGtsTW1OdmRTVXpaRVJ2UkNVeVkyOGxNMlJWTGxNdUpUSXdSMjkyWlhKdWJXVnVkQ1V5XG4iCisgICAgICAgICAgICAgICAgICAgICsgIlkyTWxNMlJWVXo5alpYSjBhV1pwWTJGMFpWSmxkbTlqWVhScGIyNU1hWE4wSlROaVltbHVZWEo1TUEwR0NTcUdcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiU0liM0RRRUJCUVVBQTRHQkFGbzUvVHUwZHN5OHR5aEpWdnhhS0ZOTWZQM0xMYXNwbCtPcjhvQ3BuY0tkcEt5alxuIgorICAgICAgICAgICAgICAgICAgICArICI3Wk82dUowbjdvcXZFYVVUaG04amdYU05neXR0bFlQd29OQnhFc1RxL2xCRFYzK3kvYzYxcHN3M3FNMmJvQjFIXG4iCisgICAgICAgICAgICAgICAgICAgICsgIk9pM3hYblJZK2V0RzMzVE45eXlkenJaNTJYTTBobkpaZDR4SWZvQWdxczRUMnJncWc4aHgweWRVN280b1xuIgorICAgICAgICAgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iLAorCisgICAgICAgICAgICAvLyBDRVJUSUZJQ0FURVNfRU5DT0RFRF9YNTA5WzNdCisgICAgICAgICAgICAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICAgICAgICAgICAgICsgIk1JSURWakNDQXIrZ0F3SUJBZ0lCUlRBTkJna3Foa2lHOXcwQkFRVUZBREJXTVFzd0NRWURWUVFHRXdKVlV6RVlcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTUJZR0ExVUVDaE1QVlM1VExpQkhiM1psY201dFpXNTBNUXd3Q2dZRFZRUUxFd05FYjBReEREQUtCZ05WQkFzVFxuIgorICAgICAgICAgICAgICAgICAgICArICJBMUJMU1RFUk1BOEdBMVVFQXhNSVRXVmtJRU5CTFRFd0hoY05PVGd3T0RBeU1UY3hNekk1V2hjTk1ERXdPREF5XG4iCisgICAgICAgICAgICAgICAgICAgICsgIk1UY3hNekk1V2pCd01Rc3dDUVlEVlFRR0V3SlZVekVZTUJZR0ExVUVDaE1QVlM1VExpQkhiM1psY201dFpXNTBcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTVF3d0NnWURWUVFMRXdORWIwUXhEREFLQmdOVkJBc1RBMUJMU1RFTk1Bc0dBMVVFQ3hNRVZWTkJSakVjTUJvR1xuIgorICAgICAgICAgICAgICAgICAgICArICJBMVVFQXhNVFpITXRNUzVqYVhOMGR5NXpZV2xqTG1OdmJUQ0JuVEFOQmdrcWhraUc5dzBCQVFFRkFBT0Jpd0F3XG4iCisgICAgICAgICAgICAgICAgICAgICsgImdZY0NnWUVBMTlvSnNzcFNIbldEaTEvTlR0aGJMcm5pY0RvZ2czYzYzWkhQZWRVMVlEOTBMMW9na1l6eFNBMnRcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTWdzVlpwTmVqQmdsRTk3Mm1YS1BxRUdEb2puRGdsdFJnUkx0THFpc0lzMERTRlFySnJoQThlZ01IL3BIQW85SFxuIgorICAgICAgICAgICAgICAgICAgICArICJmSDBuOXJRVVlCSTNkc0x4UWtHVlVTYkI0UDgzVkhpMHNRTzBkV3NxNW1FWmQ5RytNZnNDQVFPamdnRWFNSUlCXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkZqQVdCZ05WSFNBRUR6QU5NQXNHQ1dDR1NBRmxBZ0VMQXpBZkJnTlZIU01FR0RBV2dCUXpPaFRvQ1dkaGlHVWtcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiSU94NWNFTFhwcE1lOWpBZEJnTlZIUTRFRmdRVWNRYVlPOEVFamplK1ZJM3ZmQklsREM2SE5qMHdEZ1lEVlIwUFxuIgorICAgICAgICAgICAgICAgICAgICArICJBUUgvQkFRREFnVWdNQXdHQTFVZEV3RUIvd1FDTUFBd2daMEdBMVVkSHdTQmxUQ0JrakNCajZDQmpLQ0JpWWFCXG4iCisgICAgICAgICAgICAgICAgICAgICsgImhteGtZWEE2THk5a2N5MHhMbU5vWVcxaUxtUnBjMkV1Yldsc0wyTnVKVE5rVFdWa0pUSXdRMEVsTW1ReEpUSmpcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiYjNVbE0yUlFTMGtsTW1OdmRTVXpaRVJ2UkNVeVkyOGxNMlJWTGxNdUpUSXdSMjkyWlhKdWJXVnVkQ1V5WTJNbFxuIgorICAgICAgICAgICAgICAgICAgICArICJNMlJWVXo5alpYSjBhV1pwWTJGMFpWSmxkbTlqWVhScGIyNU1hWE4wSlROaVltbHVZWEo1TUEwR0NTcUdTSWIzXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkRRRUJCUVVBQTRHQkFFZzdBQzliYWQyS1p6eVg0Y3FMVS9tdjJjYlZnNnRFUzJQSWVTVDduazhDUWN2OWE4SU9cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiM0s0dWhyS29Uc1FmcXM5cDYrNnMwVmJnSDNQS3ZPQUlGNERBcDVZcTF6ejNmQitoc2FGbGVIcXRETnVsZG0xK1xuIgorICAgICAgICAgICAgICAgICAgICArICIzWEEyT3FhNWFSRmtiNktydXQwRUVPVjRjL0dFQVBPclJHVVR6WW1PcDRTRWM4VEVhRC83NUE3UlxuIgorICAgICAgICAgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iLAorCisgICAgICAgICAgICAvLyBDRVJUSUZJQ0FURVNfRU5DT0RFRF9YNTA5WzRdCisgICAgICAgICAgICAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICAgICAgICAgICAgICsgIk1JSURYRENDQXNXZ0F3SUJBZ0lCU2pBTkJna3Foa2lHOXcwQkFRVUZBREJXTVFzd0NRWURWUVFHRXdKVlV6RVlcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTUJZR0ExVUVDaE1QVlM1VExpQkhiM1psY201dFpXNTBNUXd3Q2dZRFZRUUxFd05FYjBReEREQUtCZ05WQkFzVFxuIgorICAgICAgICAgICAgICAgICAgICArICJBMUJMU1RFUk1BOEdBMVVFQXhNSVRXVmtJRU5CTFRFd0hoY05PVGd3T0RBeU1UZ3dNalF3V2hjTk1ERXdPREF5XG4iCisgICAgICAgICAgICAgICAgICAgICsgIk1UZ3dNalF3V2pCME1Rc3dDUVlEVlFRR0V3SlZVekVZTUJZR0ExVUVDaE1QVlM1VExpQkhiM1psY201dFpXNTBcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTVF3d0NnWURWUVFMRXdORWIwUXhEREFLQmdOVkJBc1RBMUJMU1RFTk1Bc0dBMVVFQ3hNRVZWTkJSakVnTUI0R1xuIgorICAgICAgICAgICAgICAgICAgICArICJBMVVFQXhNWFIzVnRZbmt1U205elpYQm9MakF3TURBd01EVXdORFF3Z1o4d0RRWUpLb1pJaHZjTkFRRUJCUUFEXG4iCisgICAgICAgICAgICAgICAgICAgICsgImdZMEFNSUdKQW9HQkFMVC9SN2JQcXMxYzFZcVhBZzVITnBaTGdXMkh1QWM3UkNhUDA2Y0U0UjQ0R0JMdy9mUWNcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiVlJOTG41cGdiVFhzRG5qaVpWZDhxRWdZcWpLRlFrYTQvdE5oYUY3Tm8ydEJaQitvWUwvZVAwSVd0UCtoL1c2RFxuIgorICAgICAgICAgICAgICAgICAgICArICJLUjUrVXZJSWRnbXg3azN0OWpwMlE1MUpwSGhoS0ViOVdONTR0ckNPOVl1N1BZVStMSTg1akVJQkFnTUJBQUdqXG4iCisgICAgICAgICAgICAgICAgICAgICsgImdnRWFNSUlCRmpBV0JnTlZIU0FFRHpBTk1Bc0dDV0NHU0FGbEFnRUxBekFmQmdOVkhTTUVHREFXZ0JRek9oVG9cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiQ1dkaGlHVWtJT3g1Y0VMWHBwTWU5akFkQmdOVkhRNEVGZ1FVa0xCSmwrYXlLZ3pPcC93d0JYOU0xbFNrQ2c0d1xuIgorICAgICAgICAgICAgICAgICAgICArICJEZ1lEVlIwUEFRSC9CQVFEQWdiQU1Bd0dBMVVkRXdFQi93UUNNQUF3Z1owR0ExVWRId1NCbFRDQmtqQ0JqNkNCXG4iCisgICAgICAgICAgICAgICAgICAgICsgImpLQ0JpWWFCaG14a1lYQTZMeTlrY3kweExtTm9ZVzFpTG1ScGMyRXViV2xzTDJOdUpUTmtUV1ZrSlRJd1EwRWxcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTW1ReEpUSmpiM1VsTTJSUVMwa2xNbU52ZFNVelpFUnZSQ1V5WTI4bE0yUlZMbE11SlRJd1IyOTJaWEp1YldWdVxuIgorICAgICAgICAgICAgICAgICAgICArICJkQ1V5WTJNbE0yUlZVejlqWlhKMGFXWnBZMkYwWlZKbGRtOWpZWFJwYjI1TWFYTjBKVE5pWW1sdVlYSjVNQTBHXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkNTcUdTSWIzRFFFQkJRVUFBNEdCQUZqYXB1REhNdklkVWVZUnlFWWRTaEJSMUpaQzIwdEozTVFueUJRdmVkZHpcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTEdGREdwSWtSQVFVN1QvNS9uZThsTWV4eXhWaUMyMXhPbEs5TGRiSkNiVnl5d3ZiOXVFbS8xamU5d2llUVF0clxuIgorICAgICAgICAgICAgICAgICAgICArICJranlrdUIrV0I2cVRDSXNsQU8vZVVtZ3pmeklFTnZuSDhPK2ZIN1FUcjJQZGtGa2lQSXFCSllIdnc3RjNYRHF5XG4iCisgICAgICAgICAgICAgICAgICAgICsgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cbiIsCisKKyAgICAgICAgICAgIC8vIENFUlRJRklDQVRFU19FTkNPREVEX1g1MDlbNV0KKyAgICAgICAgICAgICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTUlJRGxEQ0NBdjJnQXdJQkFnSUJHVEFOQmdrcWhraUc5dzBCQVFVRkFEQmNNUXN3Q1FZRFZRUUdFd0pWVXpFWVxuIgorICAgICAgICAgICAgICAgICAgICArICJNQllHQTFVRUNoTVBWUzVUTGlCSGIzWmxjbTV0Wlc1ME1Rd3dDZ1lEVlFRTEV3TkViMFF4RERBS0JnTlZCQXNUXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkExQkxTVEVYTUJVR0ExVUVBeE1PVFdWa0lFVnRZV2xzSUVOQkxURXdIaGNOT1Rnd09EQXlNVGd3TmpNMFdoY05cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTURBd09EQXlNVGd3TmpNMFdqQ0JtVEVMTUFrR0ExVUVCaE1DVlZNeEdEQVdCZ05WQkFvVEQxVXVVeTRnUjI5MlxuIgorICAgICAgICAgICAgICAgICAgICArICJaWEp1YldWdWRERU1NQW9HQTFVRUN4TURSRzlFTVF3d0NnWURWUVFMRXdOUVMwa3hEVEFMQmdOVkJBc1RCRlZUXG4iCisgICAgICAgICAgICAgICAgICAgICsgIlFVWXhJREFlQmdOVkJBTVRGMGQxYldKNUxrcHZjMlZ3YUM0d01EQXdNREExTURRME1TTXdJUVlKS29aSWh2Y05cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiQVFrQkZoUm5kVzFpZVVCamFYTjBkeTV6WVdsakxtTnZiVENCbnpBTkJna3Foa2lHOXcwQkFRRUZBQU9CalFBd1xuIgorICAgICAgICAgICAgICAgICAgICArICJnWWtDZ1lFQXZVNExNb09uRjlibWhIdnhaejh3Q2M5ZVJKMGo0UkIwU21WWW9xOWlQclNKQndST2V1eHVVOFZTXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkpCTC91K1JCNXQ2VUpWTmpYRm1CMXdTMGZveHBPSEZRQkZXeXZXbXVPaVJVTmFSeFRWQ3JPNGVHK25tTS9VODlcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiREtBYzlGVjRiWjhkUEU5UGxLOW9xMEo4WTJESUt6MStnSWVNMXNUUE1uRHRGZ2ZHeUg4Q0F3RUFBYU9DQVNZd1xuIgorICAgICAgICAgICAgICAgICAgICArICJnZ0VpTUJZR0ExVWRJQVFQTUEwd0N3WUpZSVpJQVdVQ0FRc0RNQjhHQTFVZEl3UVlNQmFBRkpjclNITi9hK2FOXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkw1REsxTnBKVUl2WCtiVm5NQjBHQTFVZERnUVdCQlI1ME45N0F4SzBHNlUxN0VQMWl1MzhMaUxUQnpBT0JnTlZcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiSFE4QkFmOEVCQU1DQmFBd0RBWURWUjBUQVFIL0JBSXdBRENCcVFZRFZSMGZCSUdoTUlHZU1JR2JvSUdZb0lHVlxuIgorICAgICAgICAgICAgICAgICAgICArICJob0dTYkdSaGNEb3ZMMlJ6TFRFdVkyaGhiV0l1WkdsellTNXRhV3c2TXprd0wyTnVKVE5rVFdWa0pUSXdSVzFoXG4iCisgICAgICAgICAgICAgICAgICAgICsgImFXd2xNakJEUVNVeVpERWxNbU52ZFNVelpGQkxTU1V5WTI5MUpUTmtSRzlFSlRKamJ5VXpaRlV1VXk0bE1qQkhcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiYjNabGNtNXRaVzUwSlRKall5VXpaRlZUUDJObGNuUnBabWxqWVhSbFVtVjJiMk5oZEdsdmJreHBjM1FsTTJKaVxuIgorICAgICAgICAgICAgICAgICAgICArICJhVzVoY25rd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ1lFQUE5ejhoN0s0djBDdU95dm1BTE5sOFRRdDBpbmYwdzUyXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkpKVXZ3LzNGTEE2MjJJSGUvdkM5Vkh5SUYwaWJTRWxqV2VPQnVSam9NRUxBWkdYQ3dSdTQzbzJMRFJxSHI0UGNcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiV2xHMHVVdGdIVFB4YlpwYVV3dWVJWkNCWmc1N2Y3WmhsdWI3QWcrQWplT3liRmozRllxREI3VFlxV0pnQXMvN1xuIgorICAgICAgICAgICAgICAgICAgICArICJnNVdmTkVWQUV3Yz1cbiIgKyAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLVxuIiwKKworICAgICAgICAgICAgLy8gQ0VSVElGSUNBVEVTX0VOQ09ERURfWDUwOVs2XQorICAgICAgICAgICAgIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICAgICAgICAgICAgICAgICArICJNSUlFRWpDQ0E3eWdBd0lCQWdJSUV0NHI0Z0FBQWxJd0RRWUpLb1pJaHZjTkFRRUVCUUF3Z1pNeEN6QUpCZ05WXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkJBWVRBbFZUTVFzd0NRWURWUVFJRXdKWFFURVFNQTRHQTFVRUJ4TUhVbVZrYlc5dVpERVRNQkVHQTFVRUNoTUtcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiVjJsdVpHOTNjeUJPVkRFYk1Ca0dBMVVFQ3hNU1JHbHpkSEpwWW5WMFpXUWdVM2x6ZEdWdE1UTXdNUVlEVlFRRFxuIgorICAgICAgICAgICAgICAgICAgICArICJFeXBOYVdOeWIzTnZablFnUTJWeWRHbG1hV05oZEdVZ1UyVnlkbVZ5SUZSbGMzUWdSM0p2ZFhBZ1EwRXdIaGNOXG4iCisgICAgICAgICAgICAgICAgICAgICsgIk9UY3hNVEkxTVRrd05ESXlXaGNOT1RneE1ERTBNVGd4TVRJNFdqQnVNUXN3Q1FZRFZRUUdFd0pWVXpFTE1Ba0dcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiQTFVRUNCTUNWMEV4RURBT0JnTlZCQWNUQjFKbFpHMXZibVF4SGpBY0JnTlZCQW9URlUxcFkzSnZjMjltZENCRFxuIgorICAgICAgICAgICAgICAgICAgICArICJiM0p3YjNKaGRHbHZiakVOTUFzR0ExVUVDeE1FUkZOWlV6RVJNQThHQTFVRUF4TUlRMlZ5ZEZSbGMzUXdXekFOXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkJna3Foa2lHOXcwQkFRRUZBQU5LQURCSEFrQjZoS2diWW1lOGd0Q2YxVnk3NEtWTkxmMm8vUjFrUVZEU1ppTm1cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAibEJTRXNIQUpTTFh1dVZkWXNLby9oemFycjlnR21JL2dVem1hcmdZMXhKR1FZYmF6QWdNQkFBR2pnZ0lYTUlJQ1xuIgorICAgICAgICAgICAgICAgICAgICArICJFekNCendZRFZSMGpCSUhITUlIRWdCUzNoVElSdUJaYU9pYmh0MURaam5UVWcvSWlSYUdCbWFTQmxqQ0JrekVMXG4iCisgICAgICAgICAgICAgICAgICAgICsgIk1Ba0dBMVVFQmhNQ1ZWTXhDekFKQmdOVkJBZ1RBbGRCTVJBd0RnWURWUVFIRXdkU1pXUnRiMjVrTVJNd0VRWURcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiVlFRS0V3cFhhVzVrYjNkeklFNVVNUnN3R1FZRFZRUUxFeEpFYVhOMGNtbGlkWFJsWkNCVGVYTjBaVzB4TXpBeFxuIgorICAgICAgICAgICAgICAgICAgICArICJCZ05WQkFNVEtrMXBZM0p2YzI5bWRDQkRaWEowYVdacFkyRjBaU0JUWlhKMlpYSWdWR1Z6ZENCSGNtOTFjQ0JEXG4iCisgICAgICAgICAgICAgICAgICAgICsgIlFZSVFFUk5oQUtvQS9vVVIwVVM1NGlnVVl6Q0J2UVlEVlIwZkJJRzFNSUd5TUZhZ1ZLQlNobEJvZEhSd09pOHZcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiUTBWU1ZGTlNWaTlEWlhKMFUzSjJMME5sY25SRmJuSnZiR3d2VFdsamNtOXpiMlowSUVObGNuUnBabWxqWVhSbFxuIgorICAgICAgICAgICAgICAgICAgICArICJJRk5sY25abGNpQlVaWE4wSUVkeWIzVndJRU5CTG1OeWJEQllvRmFnVklaU1ptbHNaVG92TDF4Y1EwVlNWRk5TXG4iCisgICAgICAgICAgICAgICAgICAgICsgIlZseERaWEowVTNKMlhFTmxjblJGYm5KdmJHeGNUV2xqY205emIyWjBJRU5sY25ScFptbGpZWFJsSUZObGNuWmxcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiY2lCVVpYTjBJRWR5YjNWd0lFTkJMbU55YkRBSkJnTlZIUk1FQWpBQU1IUUdDQ3NHQVFVRkJ3RUJCR2d3WmpCa1xuIgorICAgICAgICAgICAgICAgICAgICArICJCZ2dyQmdFRkJRY3dBb1pZYUhSMGNEb3ZMME5GVWxSVFVsWXZRMlZ5ZEZOeWRpOURaWEowUlc1eWIyeHNMME5GXG4iCisgICAgICAgICAgICAgICAgICAgICsgIlVsUlRVbFpmVFdsamNtOXpiMlowSUVObGNuUnBabWxqWVhSbElGTmxjblpsY2lCVVpYTjBJRWR5YjNWd0lFTkJcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTG1OeWREQU5CZ2txaGtpRzl3MEJBUVFGQUFOQkFGYkVqNGovM052NldjQXZxMjRDN3l3OEwwRmN5RTRkdExMWFxuIgorICAgICAgICAgICAgICAgICAgICArICJVKzA0UDBQT2UvZG95VFQ2VW5nWE5YcDlSWHBxRFNpSUhCUlRzaHB2UitOMnZ3ZVI1cUE9XG4iCisgICAgICAgICAgICAgICAgICAgICsgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cbiIsCisKKyAgICAgICAgICAgIC8vIENFUlRJRklDQVRFU19FTkNPREVEX1g1MDlbN10KKyAgICAgICAgICAgICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTUlJRVlUQ0NCQXVnQXdJQkFnSUlGVmlXbXdBQUFsb3dEUVlKS29aSWh2Y05BUUVFQlFBd2daTXhDekFKQmdOVlxuIgorICAgICAgICAgICAgICAgICAgICArICJCQVlUQWxWVE1Rc3dDUVlEVlFRSUV3SlhRVEVRTUE0R0ExVUVCeE1IVW1Wa2JXOXVaREVUTUJFR0ExVUVDaE1LXG4iCisgICAgICAgICAgICAgICAgICAgICsgIlYybHVaRzkzY3lCT1ZERWJNQmtHQTFVRUN4TVNSR2x6ZEhKcFluVjBaV1FnVTNsemRHVnRNVE13TVFZRFZRUURcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiRXlwTmFXTnliM052Wm5RZ1EyVnlkR2xtYVdOaGRHVWdVMlZ5ZG1WeUlGUmxjM1FnUjNKdmRYQWdRMEV3SGhjTlxuIgorICAgICAgICAgICAgICAgICAgICArICJPVGN4TVRJMk1EWXpOekU0V2hjTk9UZ3hNREUwTVRneE1USTRXakNCbWpFak1DRUdDU3FHU0liM0RRRUpBUllVXG4iCisgICAgICAgICAgICAgICAgICAgICsgIllXeHNZVzVqUUcxcFkzSnZjMjltZEM1amIyMHhDekFKQmdOVkJBWVRBbFZUTVFzd0NRWURWUVFJRXdKWFFURVFcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTUE0R0ExVUVCeE1IVW1Wa2JXOXVaREVlTUJ3R0ExVUVDaE1WVFdsamNtOXpiMlowSUVOdmNuQnZjbUYwYVc5dVxuIgorICAgICAgICAgICAgICAgICAgICArICJNUTB3Q3dZRFZRUUxFd1JFVTFsVE1SZ3dGZ1lEVlFRREV3OUJiR3hoYmlCS0xpQkRiMjl3WlhJd1d6QU5CZ2txXG4iCisgICAgICAgICAgICAgICAgICAgICsgImhraUc5dzBCQVFFRkFBTktBREJIQWtCMTk1MXVaTHlKWGpTWlRjOFoxUW51WHZLQkFxbTJXVDRPRmFGeVNGL0ZcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiV25NYklsQUUwcHZzekRrS1orTjdoQnpjYzVwVklqZXpQZlo4Y1BoLy9qVlBBZ01CQUFHamdnSTVNSUlDTlRBTFxuIgorICAgICAgICAgICAgICAgICAgICArICJCZ05WSFE4RUJBTUNBRGd3RXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdRd2djOEdBMVVkSXdTQnh6Q0J4SUFVXG4iCisgICAgICAgICAgICAgICAgICAgICsgInQ0VXlFYmdXV2pvbTRiZFEyWTUwMUlQeUlrV2hnWm1rZ1pZd2daTXhDekFKQmdOVkJBWVRBbFZUTVFzd0NRWURcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiVlFRSUV3SlhRVEVRTUE0R0ExVUVCeE1IVW1Wa2JXOXVaREVUTUJFR0ExVUVDaE1LVjJsdVpHOTNjeUJPVkRFYlxuIgorICAgICAgICAgICAgICAgICAgICArICJNQmtHQTFVRUN4TVNSR2x6ZEhKcFluVjBaV1FnVTNsemRHVnRNVE13TVFZRFZRUURFeXBOYVdOeWIzTnZablFnXG4iCisgICAgICAgICAgICAgICAgICAgICsgIlEyVnlkR2xtYVdOaGRHVWdVMlZ5ZG1WeUlGUmxjM1FnUjNKdmRYQWdRMEdDRUJFVFlRQ3FBUDZGRWRGRXVlSW9cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiRkdNd2diMEdBMVVkSHdTQnRUQ0JzakJXb0ZTZ1VvWlFhSFIwY0RvdkwwTkZVbFJUVWxZdlEyVnlkRk55ZGk5RFxuIgorICAgICAgICAgICAgICAgICAgICArICJaWEowUlc1eWIyeHNMMDFwWTNKdmMyOW1kQ0JEWlhKMGFXWnBZMkYwWlNCVFpYSjJaWElnVkdWemRDQkhjbTkxXG4iCisgICAgICAgICAgICAgICAgICAgICsgImNDQkRRUzVqY213d1dLQldvRlNHVW1acGJHVTZMeTljWEVORlVsUlRVbFpjUTJWeWRGTnlkbHhEWlhKMFJXNXlcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiYjJ4c1hFMXBZM0p2YzI5bWRDQkRaWEowYVdacFkyRjBaU0JUWlhKMlpYSWdWR1Z6ZENCSGNtOTFjQ0JEUVM1alxuIgorICAgICAgICAgICAgICAgICAgICArICJjbXd3Q1FZRFZSMFRCQUl3QURCMEJnZ3JCZ0VGQlFjQkFRUm9NR1l3WkFZSUt3WUJCUVVITUFLR1dHaDBkSEE2XG4iCisgICAgICAgICAgICAgICAgICAgICsgIkx5OURSVkpVVTFKV0wwTmxjblJUY25ZdlEyVnlkRVZ1Y205c2JDOURSVkpVVTFKV1gwMXBZM0p2YzI5bWRDQkRcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiWlhKMGFXWnBZMkYwWlNCVFpYSjJaWElnVkdWemRDQkhjbTkxY0NCRFFTNWpjblF3RFFZSktvWklodmNOQVFFRVxuIgorICAgICAgICAgICAgICAgICAgICArICJCUUFEUVFBMVRZc2swN3RXMGRoVTZiSFBLN05YSFVGRmlaMmZBdEMwZXBMWTlHNnl1WWIxbG96UHY1c0RuQ2wxXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkEyZlpQZ2F3dkFxQ3ZLOXhrdjVMNGoyRit2NFVcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLVxuIiwKKworICAgICAgICAgICAgLy8gQ0VSVElGSUNBVEVTX0VOQ09ERURfWDUwOVs4XQorICAgICAgICAgICAgIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICAgICAgICAgICAgICAgICArICJNSUlFWWpDQ0JBeWdBd0lCQWdJSUZWc0hhUUFBQWx3d0RRWUpLb1pJaHZjTkFRRUVCUUF3Z1pNeEN6QUpCZ05WXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkJBWVRBbFZUTVFzd0NRWURWUVFJRXdKWFFURVFNQTRHQTFVRUJ4TUhVbVZrYlc5dVpERVRNQkVHQTFVRUNoTUtcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiVjJsdVpHOTNjeUJPVkRFYk1Ca0dBMVVFQ3hNU1JHbHpkSEpwWW5WMFpXUWdVM2x6ZEdWdE1UTXdNUVlEVlFRRFxuIgorICAgICAgICAgICAgICAgICAgICArICJFeXBOYVdOeWIzTnZablFnUTJWeWRHbG1hV05oZEdVZ1UyVnlkbVZ5SUZSbGMzUWdSM0p2ZFhBZ1EwRXdIaGNOXG4iCisgICAgICAgICAgICAgICAgICAgICsgIk9UY3hNVEkyTURZek9UVTRXaGNOT1RneE1ERTBNVGd4TVRJNFdqQ0JtakVqTUNFR0NTcUdTSWIzRFFFSkFSWVVcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiWVd4c1lXNWpRRzFwWTNKdmMyOW1kQzVqYjIweEN6QUpCZ05WQkFZVEFsVlRNUXN3Q1FZRFZRUUlFd0pYUVRFUVxuIgorICAgICAgICAgICAgICAgICAgICArICJNQTRHQTFVRUJ4TUhVbVZrYlc5dVpERWVNQndHQTFVRUNoTVZUV2xqY205emIyWjBJRU52Y25CdmNtRjBhVzl1XG4iCisgICAgICAgICAgICAgICAgICAgICsgIk1RMHdDd1lEVlFRTEV3UkVVMWxUTVJnd0ZnWURWUVFERXc5QmJHeGhiaUJLTGlCRGIyOXdaWEl3WERBTkJna3FcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiaGtpRzl3MEJBUUVGQUFOTEFEQklBa0VBMFQxdGQ4a2ZzSmd3bThRaitqdHJxMjl0cWMvRElrSWJBUGN5eWdLR1xuIgorICAgICAgICAgICAgICAgICAgICArICIxWEVVdnpRRVF1bVZReDVsQ0QyTE9PSnMwZU91djRoNm5ndkxXK2dvRGFpZE5RSURBUUFCbzRJQ09UQ0NBalV3XG4iCisgICAgICAgICAgICAgICAgICAgICsgIkN3WURWUjBQQkFRREFnREFNQk1HQTFVZEpRUU1NQW9HQ0NzR0FRVUZCd01JTUlIUEJnTlZIU01FZ2Njd2djU0FcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiRkxlRk1oRzRGbG82SnVHM1VObU9kTlNEOGlKRm9ZR1pwSUdXTUlHVE1Rc3dDUVlEVlFRR0V3SlZVekVMTUFrR1xuIgorICAgICAgICAgICAgICAgICAgICArICJBMVVFQ0JNQ1YwRXhFREFPQmdOVkJBY1RCMUpsWkcxdmJtUXhFekFSQmdOVkJBb1RDbGRwYm1SdmQzTWdUbFF4XG4iCisgICAgICAgICAgICAgICAgICAgICsgIkd6QVpCZ05WQkFzVEVrUnBjM1J5YVdKMWRHVmtJRk41YzNSbGJURXpNREVHQTFVRUF4TXFUV2xqY205emIyWjBcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiSUVObGNuUnBabWxqWVhSbElGTmxjblpsY2lCVVpYTjBJRWR5YjNWd0lFTkJnaEFSRTJFQXFnRCtoUkhSUkxuaVxuIgorICAgICAgICAgICAgICAgICAgICArICJLQlJqTUlHOUJnTlZIUjhFZ2JVd2diSXdWcUJVb0ZLR1VHaDBkSEE2THk5RFJWSlVVMUpXTDBObGNuUlRjbll2XG4iCisgICAgICAgICAgICAgICAgICAgICsgIlEyVnlkRVZ1Y205c2JDOU5hV055YjNOdlpuUWdRMlZ5ZEdsbWFXTmhkR1VnVTJWeWRtVnlJRlJsYzNRZ1IzSnZcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiZFhBZ1EwRXVZM0pzTUZpZ1ZxQlVobEptYVd4bE9pOHZYRnhEUlZKVVUxSldYRU5sY25SVGNuWmNRMlZ5ZEVWdVxuIgorICAgICAgICAgICAgICAgICAgICArICJjbTlzYkZ4TmFXTnliM052Wm5RZ1EyVnlkR2xtYVdOaGRHVWdVMlZ5ZG1WeUlGUmxjM1FnUjNKdmRYQWdRMEV1XG4iCisgICAgICAgICAgICAgICAgICAgICsgIlkzSnNNQWtHQTFVZEV3UUNNQUF3ZEFZSUt3WUJCUVVIQVFFRWFEQm1NR1FHQ0NzR0FRVUZCekFDaGxob2RIUndcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiT2k4dlEwVlNWRk5TVmk5RFpYSjBVM0oyTDBObGNuUkZibkp2Ykd3dlEwVlNWRk5TVmw5TmFXTnliM052Wm5RZ1xuIgorICAgICAgICAgICAgICAgICAgICArICJRMlZ5ZEdsbWFXTmhkR1VnVTJWeWRtVnlJRlJsYzNRZ1IzSnZkWEFnUTBFdVkzSjBNQTBHQ1NxR1NJYjNEUUVCXG4iCisgICAgICAgICAgICAgICAgICAgICsgIkJBVUFBMEVBVVBYdDJwT1kzWXdSVUh6RDdEdGd5eDVHN0t4S3RMYW4xd0ZCRmpodjQwNnYyVXRiKzIrd1RRbFNcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAidWxXZW1jbThlT2RHNjRuc3B2MG9xU0puQThmNHhnPT1cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLVxuIiwKKworICAgICAgICAgICAgLy8gQ0VSVElGSUNBVEVTX0VOQ09ERURfWDUwOVs5XQorICAgICAgICAgICAgIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICAgICAgICAgICAgICAgICArICJNSUlDaVRDQ0FmSUNBUUF3RFFZSktvWklodmNOQVFFRUJRQXdnWXd4Q3pBSkJnTlZCQVlUQWxWVE1SVXdFd1lEXG4iCisgICAgICAgICAgICAgICAgICAgICsgIlZRUUlFd3hPYjNKMGFDQkVZV3R2ZEdFeEZEQVNCZ05WQkFjVEMwZHlZVzVrSUVadmNtdHpNUll3RkFZRFZRUUtcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiRXcxVlRrUWdRV1Z5YjNOd1lXTmxNUmd3RmdZRFZRUURGQTl5YjI5MFFHTnpMblZ1WkM1bFpIVXhIakFjQmdrcVxuIgorICAgICAgICAgICAgICAgICAgICArICJoa2lHOXcwQkNRRVdEM0p2YjNSQVkzTXVkVzVrTG1Wa2RUQWVGdzA1T1RBek1ESXlNRFU0TkRSYUZ3MHdPVEF5XG4iCisgICAgICAgICAgICAgICAgICAgICsgIk1qY3lNRFU0TkRSYU1JR01NUXN3Q1FZRFZRUUdFd0pWVXpFVk1CTUdBMVVFQ0JNTVRtOXlkR2dnUkdGcmIzUmhcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTVJRd0VnWURWUVFIRXd0SGNtRnVaQ0JHYjNKcmN6RVdNQlFHQTFVRUNoTU5WVTVFSUVGbGNtOXpjR0ZqWlRFWVxuIgorICAgICAgICAgICAgICAgICAgICArICJNQllHQTFVRUF4UVBjbTl2ZEVCamN5NTFibVF1WldSMU1SNHdIQVlKS29aSWh2Y05BUWtCRmc5eWIyOTBRR056XG4iCisgICAgICAgICAgICAgICAgICAgICsgIkxuVnVaQzVsWkhVd2daOHdEUVlKS29aSWh2Y05BUUVCQlFBRGdZMEFNSUdKQW9HQkFMbWxRSmc1TmwyVnNRWjFcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiL0I4Zlc0WURkazA5U2xWYzd2eVdjYmNtYldSQkplZTBqY0g0NDhYZFJQL20vTVhJUnNWS3loTEE1ZjAxK1ZQeVxuIgorICAgICAgICAgICAgICAgICAgICArICJFMmFEa3gyV2lVNERwcWJNYkdHQXl0dVhCTnVkSlFtQlhqV0VGaUFHZTdkWWdETkdLSzdZbzFrNDlRNnFHZzlxXG4iCisgICAgICAgICAgICAgICAgICAgICsgIjVkaWQzK3Bwc3lmemJlYWlEQ0gwTE81Z2VnTnZBZ01CQUFFd0RRWUpLb1pJaHZjTkFRRUVCUUFEZ1lFQUpub2tcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiMWd2ajRLQzlIZVVYL1I0US9mNXRiSjJqTGVRQVRJSHRVeDlRU0tTcTdJc2RZMHp6OUVuS09zYzlwcjhKZkJUTFxuIgorICAgICAgICAgICAgICAgICAgICArICJjQXdyeHF2bDVRdW9DRlZSMnRRcThEdEJRWTh2cDdiRUYyQ1pWb3haSlhNSUtLaUQvSGpiMG95cGJxNXdGMFNZXG4iCisgICAgICAgICAgICAgICAgICAgICsgInhONURVZkc1c1NoaSt2UElBd0U2MnRaMVAxSTFOOERRcERZaVhrdz1cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLVxuIiwKKworICAgICAgICAgICAgLy8gQ0VSVElGSUNBVEVTX0VOQ09ERURfWDUwOVsxMF0KKyAgICAgICAgICAgICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTUlJQ1dEQ0NBZ0lDQVFBd0RRWUpLb1pJaHZjTkFRRUVCUUF3Z2JZeEN6QUpCZ05WQkFZVEFscEJNUlV3RXdZRFxuIgorICAgICAgICAgICAgICAgICAgICArICJWUVFJRXd4WFpYTjBaWEp1SUVOaGNHVXhFakFRQmdOVkJBY1RDVU5oY0dVZ1ZHOTNiakVkTUJzR0ExVUVDaE1VXG4iCisgICAgICAgICAgICAgICAgICAgICsgIlZHaGhkM1JsSUVOdmJuTjFiSFJwYm1jZ1kyTXhIekFkQmdOVkJBc1RGa05sY25ScFptbGpZWFJwYjI0Z1UyVnlcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiZG1salpYTXhGekFWQmdOVkJBTVREbmQzZHk1MGFHRjNkR1V1WTI5dE1TTXdJUVlKS29aSWh2Y05BUWtCRmhSM1xuIgorICAgICAgICAgICAgICAgICAgICArICJaV0p0WVhOMFpYSkFkR2hoZDNSbExtTnZiVEFlRncwNU5qRXhNVFF4TnpFMU1qVmFGdzA1TmpFeU1UUXhOekUxXG4iCisgICAgICAgICAgICAgICAgICAgICsgIk1qVmFNSUcyTVFzd0NRWURWUVFHRXdKYVFURVZNQk1HQTFVRUNCTU1WMlZ6ZEdWeWJpQkRZWEJsTVJJd0VBWURcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiVlFRSEV3bERZWEJsSUZSdmQyNHhIVEFiQmdOVkJBb1RGRlJvWVhkMFpTQkRiMjV6ZFd4MGFXNW5JR05qTVI4d1xuIgorICAgICAgICAgICAgICAgICAgICArICJIUVlEVlFRTEV4WkRaWEowYVdacFkyRjBhVzl1SUZObGNuWnBZMlZ6TVJjd0ZRWURWUVFERXc1M2QzY3VkR2hoXG4iCisgICAgICAgICAgICAgICAgICAgICsgImQzUmxMbU52YlRFak1DRUdDU3FHU0liM0RRRUpBUllVZDJWaWJXRnpkR1Z5UUhSb1lYZDBaUzVqYjIwd1hEQU5cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiQmdrcWhraUc5dzBCQVFFRkFBTkxBREJJQWtFQW1wSWw3YVIzYVNQVVV3VXJIenBWTXJzbTNncEkyUHpJd01oM1xuIgorICAgICAgICAgICAgICAgICAgICArICI5bDFoL1JzekkwLzBxQzJXUk1sZndtNUZhcG9ob3lqVEo2WnlHVVVlbklDbGxLeUtad0lEQVFBQk1BMEdDU3FHXG4iCisgICAgICAgICAgICAgICAgICAgICsgIlNJYjNEUUVCQkFVQUEwRUFmSTU3V0xrT0tFeVFxeUNEWVo2cmVDdWtWRG1BZTduWlNiT3lLdjZLVXZUQ2lRNWNcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiZTVMNHkzYy9WaUtkbG91NUJjUVlBYnhBN3J3Ty92ejRtNTF3NHc9PVxuIgorICAgICAgICAgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iLAorCisgICAgICAgICAgICAvLyBDRVJUSUZJQ0FURVNfRU5DT0RFRF9YNTA5WzExXQorICAgICAgICAgICAgIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICAgICAgICAgICAgICAgICArICJNSUlER2pDQ0F0Z0NCRGFSVzRzd0N3WUhLb1pJempnRUF3VUFNSE14Q3pBSkJnTlZCQVlUQWxWVE1SQXdEZ1lEVlFRSUV3ZEdiRzl5XG4iCisgICAgICAgICAgICAgICAgICAgICsgImFXUmhNUlF3RWdZRFZRUUhFd3RIWVdsdVpYTjJhV3hzWlRFUU1BNEdBMVVFQ2hNSFZXNXJibTkzYmpFUU1BNEdBMVVFQ3hNSFZXNXJcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiYm05M2JqRVlNQllHQTFVRUF4TVBVbTlpWlhKMElFeDVZbUZ5WjJWeU1CNFhEVGs1TURFd05UQXdNak16T1ZvWERUazVNRFF3TlRBd1xuIgorICAgICAgICAgICAgICAgICAgICArICJNak16T1Zvd2N6RUxNQWtHQTFVRUJoTUNWVk14RURBT0JnTlZCQWdUQjBac2IzSnBaR0V4RkRBU0JnTlZCQWNUQzBkaGFXNWxjM1pwXG4iCisgICAgICAgICAgICAgICAgICAgICsgImJHeGxNUkF3RGdZRFZRUUtFd2RWYm10dWIzZHVNUkF3RGdZRFZRUUxFd2RWYm10dWIzZHVNUmd3RmdZRFZRUURFdzlTYjJKbGNuUWdcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiVEhsaVlYSm5aWEl3Z2dHM01JSUJMQVlIS29aSXpqZ0VBVENDQVI4Q2dZRUEvWDlUZ1IxMUVpbFMzMHFjTHV6azUvWVJ0MUk4NzBRQVxuIgorICAgICAgICAgICAgICAgICAgICArICJ3eDQvZ0xaUkptbEZYVUFpVWZ0WlBZMVkrci9GOWJvdzlzdWJWV3pYZ1R1QUhUUnY4bVpndDJ1WlVLV2tuNS9vQkhzUUlzSlB1Nm5YXG4iCisgICAgICAgICAgICAgICAgICAgICsgIi9yZkdHL2c3VitmR3FLWVZEd1Q3Zy9iVHhSN0RBalZVRTFvV2tUTDJkZk91SzJIWEt1L3lJZ01abmRGSUFjY0NGUUNYWUZDUEZTTUxcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiekxLU3VZS2k2NFFMOEZnYzlRS0JnUUQzNGFDRjFwczkzc3U4cTF3MnVGZTVlWlN2dS9vNjZvTDVWMHdMUFFlQ1oxRlpWNDY2MUZsUFxuIgorICAgICAgICAgICAgICAgICAgICArICI1bkVIRUlHQXRFa1djU1BvVENnV0U3ZlBDVEtNeUtiaFBCWjZpMVI4alNqZ282NGVLN09tZFpGdW8zOEwraUUxWXZIN1lub0JKRHZNXG4iCisgICAgICAgICAgICAgICAgICAgICsgInBQRytxRkdRaWFpRDMrRmE1WjhHa290bVhvQjdWU1ZrQVV3Ny9zOUpLZ09CaEFBQ2dZQk1ocy9YY0YwTEFqYnVob0FZNEVPbXhkNFVcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiVTB3NG5TSlEydktjZ3B5SFUxU3YvdGJVcjN4RW02WXl4NDlqMWVOcDlqVndNMWE2TllYOEJPOGZDU0hJaVVWdkpWRmxDY29PN1FiOFxuIgorICAgICAgICAgICAgICAgICAgICArICJQeDdkcmZiRkFGdDhtRkUxbWpZQ3VqMjFlUEhoczFEbFpLSnd1MkVsQzZHYVJ3dEJrMytvQ01EQW5MdXlTZDArZkFvaGREQUxCZ2NxXG4iCisgICAgICAgICAgICAgICAgICAgICsgImhrak9PQVFEQlFBREx3QXdMQUlVZGRicUMzd29NY0FCZy9yMUdQVzllVk5TdEd3Q0ZDQkd5U3ZkWEswaTRhTFZDNFB0YmMzUFFGanBcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLVxuIiwKKworICAgICAgICAgICAgLy9DRVJUSUZJQ0FURVNfRU5DT0RFRF9YNTA5WzEyXQorICAgICAgICAgICAgIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICAgICAgICAgICAgICAgICArICJNSUlDeXpDQ0FqUUNBUUF3RFFZSktvWklodmNOQVFFRUJRQXdnYTB4Q3pBSkJnTlZCQVlUQWxWVE1SRXdEd1lEXG4iCisgICAgICAgICAgICAgICAgICAgICsgIlZRUUlFd2hPWlhjZ1dXOXlhekVXTUJRR0ExVUVCeE1OVG1WM0lGbHZjbXNnUTJsMGVURWNNQm9HQTFVRUNoTVRcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiUTI5c2RXMWlhV0VnVlc1cGRtVnljMmwwZVRFTk1Bc0dBMVVFQ3hNRVFXTkpVekVmTUIwR0ExVUVBeE1XUTI5c1xuIgorICAgICAgICAgICAgICAgICAgICArICJkVzFpYVdFZ1ZXNXBkbVZ5YzJsMGVTQkRRVEVsTUNNR0NTcUdTSWIzRFFFSkFSWVdZMlZ5ZEMxaGRYUm9RR052XG4iCisgICAgICAgICAgICAgICAgICAgICsgImJIVnRZbWxoTG1Wa2RUQWVGdzA1TnpBME1qZ3hORFF4TUROYUZ3MHdNREEwTWpneE5EUXhNRE5hTUlHdE1Rc3dcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiQ1FZRFZRUUdFd0pWVXpFUk1BOEdBMVVFQ0JNSVRtVjNJRmx2Y21zeEZqQVVCZ05WQkFjVERVNWxkeUJaYjNKclxuIgorICAgICAgICAgICAgICAgICAgICArICJJRU5wZEhreEhEQWFCZ05WQkFvVEUwTnZiSFZ0WW1saElGVnVhWFpsY25OcGRIa3hEVEFMQmdOVkJBc1RCRUZqXG4iCisgICAgICAgICAgICAgICAgICAgICsgIlNWTXhIekFkQmdOVkJBTVRGa052YkhWdFltbGhJRlZ1YVhabGNuTnBkSGtnUTBFeEpUQWpCZ2txaGtpRzl3MEJcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiQ1FFV0ZtTmxjblF0WVhWMGFFQmpiMngxYldKcFlTNWxaSFV3Z1o4d0RRWUpLb1pJaHZjTkFRRUJCUUFEZ1kwQVxuIgorICAgICAgICAgICAgICAgICAgICArICJNSUdKQW9HQkFOaW9kNmZsek03MkNic0svM2d6SHpjZGpwb296UkREL3dncTMxakVlRGRmS1krbGpBd3hhWlM5XG4iCisgICAgICAgICAgICAgICAgICAgICsgIm10N1MxZzdsTCs1NWZ4N0ZqZkp4dkpSWHZTOVViRFU0NlBERHlKbG9XWW9iZzg0Yks1WmNWNVVuSVBabUdIVy9cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiL3hWRFV0SUdoYzRUK1htNXA0Ris0QWNnZXdGMnM0VGJLV3hmQzk4RkpmZXBjMzFLamtHYkFnTUJBQUV3RFFZSlxuIgorICAgICAgICAgICAgICAgICAgICArICJLb1pJaHZjTkFRRUVCUUFEZ1lFQUkvZTZ4Qytvc1ZNNGVNa1NVVVdnaWh1b2NRbFJMOWl4VGxHcVc5ZnZObEkxXG4iCisgICAgICAgICAgICAgICAgICAgICsgInE1OGZFTFU1YmNGa283ZDAyUzlFZ2FjLzlja2t0L3NiSE12OXpRaGZudnBvbDhCTitMaXZHdSswOUlpT1c0eXFcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiYzl4VDU4UHY5Z3daL0VpNVZTK0ZYdnpISXI5MXlXSWx3THNuS2ZnWURybVFvd0c1RmtIU0cxWm90VWRsN09vPVxuIgorICAgICAgICAgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iLAorCisgICAgICAgICAgICAvL0NFUlRJRklDQVRFU19FTkNPREVEX1g1MDlbMTNdCisgICAgICAgICAgICAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICAgICAgICAgICAgICsgIk1JSUNuakNDQWdjQ0FRTXdEUVlKS29aSWh2Y05BUUVFQlFBd2dhQXhDekFKQmdOVkJBWVRBa2xVTVI0d0hBWURcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiVlFRS0V4VlFiMnhwZEdWamJtbGpieUJrYVNCVWIzSnBibTh4SXpBaEJnTlZCQXNUR2tsRFJTMVVSVXdnU1hSaFxuIgorICAgICAgICAgICAgICAgICAgICArICJiR2xoYmlCRFFTQm1iM0lnVjFkWE1TQXdIZ1lEVlFRREV4ZERaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwXG4iCisgICAgICAgICAgICAgICAgICAgICsgImVURXFNQ2dHQ1NxR1NJYjNEUUVKQVJZYmQzZDNMV05oTFdsMFFHbGpaUzEwWld3dWNHOXNhWFJ2TG1sME1CNFhcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiRFRrMk1UQXdNakV4TkRRME5Gb1hEVGszTVRJd01URXhORFEwTkZvd2dZMHhDekFKQmdOVkJBWVRBa2xVTVE4d1xuIgorICAgICAgICAgICAgICAgICAgICArICJEUVlEVlFRSEV3WlViM0pwYm04eEhqQWNCZ05WQkFvVEZWQnZiR2wwWldOdWFXTnZJR1JwSUZSdmNtbHViekVPXG4iCisgICAgICAgICAgICAgICAgICAgICsgIk1Bd0dBMVVFQ3hNRlEyVlRTVlF4R1RBWEJnTlZCQU1URUhWc2FYTnpaUzV3YjJ4cGRHOHVhWFF4SWpBZ0Jna3FcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiaGtpRzl3MEJDUUVXRTNkbFltMWhjM1JsY2tCd2IyeHBkRzh1YVhRd2daOHdEUVlKS29aSWh2Y05BUUVCQlFBRFxuIgorICAgICAgICAgICAgICAgICAgICArICJnWTBBTUlHSkFvR0JBTVVxL0ZkcnhiU2ZHdEdacS9GVFRnQzFKcXhPNGlpSGl5eHRnUlQxb0V2SklVamFqVlJOXG4iCisgICAgICAgICAgICAgICAgICAgICsgImR0QlZVaFc2Sm1oSGplL3FuTW9wMDlYY0Y3Yjg5YTlhaHRHOWpNNzBTMDNiaVhWbWc2NnBXT3B5NlA3em5BUWpcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiVkZQb0NSUjdCcVVpR3EwNDE5YTEwMUFjYXFreGkvNERkcWlUUGVlNEg3bWNEWll1K2ZEUE5RYUhBZ01CQUFFd1xuIgorICAgICAgICAgICAgICAgICAgICArICJEUVlKS29aSWh2Y05BUUVFQlFBRGdZRUF0MTViemswWE8rWk0rUTYyNzVWVFFJb242S1FRSG52OU5mbElGT29XXG4iCisgICAgICAgICAgICAgICAgICAgICsgImZnR1Jtb3lpSkZyalUxc0lTOGN0RjAzREgyeFIyMEN1S2Q5OGZCcEtub09MZDdlVEtBR3pHRlBtbDM2VFBWaitcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiWVlXZHJXcW5JelFuNkYwT0tSL1UzWStvdDVmVU51cU4zNlExd3NWdnBQSmxPTXg4RDhPUXk4YWluSGdHM1lZQVxuIgorICAgICAgICAgICAgICAgICAgICArICJUSms9XG4iICsgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cbiIsCisKKyAgICAgICAgICAgIC8vQ0VSVElGSUNBVEVTX0VOQ09ERURfWDUwOVsxNF0KKyAgICAgICAgICAgICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTUlJQzFUQ0NBajZnQXdJQkFnSUJCREFOQmdrcWhraUc5dzBCQVFRRkFEQlpNUXN3Q1FZRFZRUUdFd0pWVXpFZlxuIgorICAgICAgICAgICAgICAgICAgICArICJNQjBHQTFVRUNoTVdWVzVwZG1WeWMybDBlU0J2WmlCRGIyeHZjbUZrYnpFV01CUUdBMVVFQ3hNTlUzbHpkR1Z0XG4iCisgICAgICAgICAgICAgICAgICAgICsgIklFOW1abWxqWlRFUk1BOEdBMVVFQXhNSVZVMVRJRU5CTFRFd0hoY05PVGd3TlRFeE1qRXdNalUwV2hjTk1EZ3dcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTlRFd01qRXdNalUwV2pCWk1Rc3dDUVlEVlFRR0V3SlZVekVmTUIwR0ExVUVDaE1XVlc1cGRtVnljMmwwZVNCdlxuIgorICAgICAgICAgICAgICAgICAgICArICJaaUJEYjJ4dmNtRmtiekVXTUJRR0ExVUVDeE1OVTNsemRHVnRJRTltWm1salpURVJNQThHQTFVRUF4TUlWVTFUXG4iCisgICAgICAgICAgICAgICAgICAgICsgIklFTkJMVEV3Z1o4d0RRWUpLb1pJaHZjTkFRRUJCUUFEZ1kwQU1JR0pBb0dCQUxHZjhOeStrSGxYcUxUaTN1SWZcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAibWt4eHdESmQxNHNPZytodjg1cHhzcXpDUkpFZ094NVlEVXQwNWhKN04wczRySi9nTlVjSmFLUjZ1bCtxTEdiV1xuIgorICAgICAgICAgICAgICAgICAgICArICIrWmI0UzFZRmJuS2FPMTZ6Z2d2Z2Nrd3BMR1lSQmJtZWU5K0U0N1c4VkVPWldySlhVa3BKL1pWOEdBbmVzcnZuXG4iCisgICAgICAgICAgICAgICAgICAgICsgIlhURUtmbTdiWDlzNlI3RlFmRG9ITm5RZkFnTUJBQUdqZ2F3d2dha3dFUVlKWUlaSUFZYjRRZ0VCQkFRREFnRDJcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTUI4R0ExVWRJd1FZTUJhQUZPcWxJRDlFcjZkSTA5bjlMdm5ieStGSVNpN29NRlFHQ1dDR1NBR0crRUlCRFFSSFxuIgorICAgICAgICAgICAgICAgICAgICArICJGa1ZGZUhSbGJtUmxaQ0JEUVNCRFpYSjBhV1pwWTJGMFpTQm1jbTl0SURJMElFMXZiblJvY3lCMGJ5QXhNakFnXG4iCisgICAgICAgICAgICAgICAgICAgICsgIlRXOXVkR2h6TGlBZ1JGUkhJRDBnTURVeE1URTVPVGd3SFFZRFZSME9CQllFRk9xbElEOUVyNmRJMDluOUx2bmJcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAieStGSVNpN29NQTBHQ1NxR1NJYjNEUUVCQkFVQUE0R0JBRk5GbzI3SmVlSWdzTXFTN05hLy82Z0pRUmlseHdWU1xuIgorICAgICAgICAgICAgICAgICAgICArICJCZng2SjQzWVg0N0VnTkRMbjRKN0I5VHN0KzJiRFpEQWsxbFp5dTR5MldDTHJuZmcvZTZCMUtZQmhDdC9TcnNjXG4iCisgICAgICAgICAgICAgICAgICAgICsgInIrV29tRmN3MTlrMWpCdEJhWXhWd2gvOU40cHBaR2RLSUxBQ2NpWGJ4Zm9MYmJOZ1NEeDUrS2JFMmMybTlpczdcbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiTUlaZ1JleFR2bkphXG4iICsgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cbiIgfTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRmFjdG9yeVNwaVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlRmFjdG9yeVNwaVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZTNmMWFkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVGYWN0b3J5U3BpVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDMyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuY2VydDsKKworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5NeUNlcnRpZmljYXRlRmFjdG9yeVNwaTsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ1JMOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DUkxFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5U3BpOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5DZXJ0aWZpY2F0ZUZhY3RvcnlTcGk8L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcworICoKKyAqLworcHVibGljIGNsYXNzIENlcnRpZmljYXRlRmFjdG9yeVNwaVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZUZhY3RvcnlTcGk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlRmFjdG9yeVNwaQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkwMSgpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIENSTEV4Y2VwdGlvbiB7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeVNwaSBjZXJ0RmFjdG9yeVNwaSA9IG5ldyBleHRDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkoKTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKGJhaXMpOworICAgICAgICAgICAgZmFpbCgiVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKGJhaXMsICIiKTsKKyAgICAgICAgICAgIGZhaWwoIlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgTGlzdDxDZXJ0aWZpY2F0ZT4gbGlzdCA9IG51bGw7CisgICAgICAgICAgICBjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKGxpc3QpOworICAgICAgICAgICAgZmFpbCgiVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZXRDZXJ0UGF0aEVuY29kaW5ncygpOworICAgICAgICAgICAgZmFpbCgiVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIENlcnRpZmljYXRlIGNjID0gY2VydEZhY3RvcnlTcGkuZW5naW5lR2VuZXJhdGVDZXJ0aWZpY2F0ZShiYWlzKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiTm90IG51bGwgQ2VyaWZpY2F0ZSIsIGNjKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ2VydGlmaWNhdGUobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgQ29sbGVjdGlvbjw/IGV4dGVuZHMgQ2VydGlmaWNhdGU+IGNvbCA9IGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ2VydGlmaWNhdGVzKGJhaXMpOworICAgICAgICBhc3NlcnROdWxsKCJOb3QgbnVsbCBDb2xsZWN0aW9uIiwgY29sKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ2VydGlmaWNhdGVzKG51bGwpOworICAgICAgICAgICAgZmFpbCgiQ2VydGlmaWNhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgQ1JMIGNjQ1JMID0gY2VydEZhY3RvcnlTcGkuZW5naW5lR2VuZXJhdGVDUkwoYmFpcyk7CisgICAgICAgIGFzc2VydE51bGwoIk5vdCBudWxsIENSTCIsIGNjQ1JMKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ1JMKG51bGwpOworICAgICAgICAgICAgZmFpbCgiQ1JMRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENSTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDUkw+IGNvbENSTCA9IGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ1JMcyhiYWlzKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiTm90IG51bGwgQ1JMIiwgY29sQ1JMKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ1JMcyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkNSTEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChDUkxFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVGYWN0b3J5U3BpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVGYWN0b3J5U3BpMDIoKSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sCisgICAgICAgICAgICBDUkxFeGNlcHRpb24geworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkgY2VydEZhY3RvcnlTcGkgPSBuZXcgTXlDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkoKTsKKyAgICAgICAgTXlDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkucHV0TW9kZSh0cnVlKTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSk7CisgICAgICAgIERhdGFJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGF0YUlucHV0U3RyZWFtKGJhaXMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEZhY3RvcnlTcGkuZW5naW5lR2VuZXJhdGVDZXJ0UGF0aChiYWlzKTsKKyAgICAgICAgICAgIGZhaWwoIkNlcnRpZmljYXRlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKGRpcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKGJhaXMsICJhYSIpOworICAgICAgICAgICAgZmFpbCgiQ2VydGlmaWNhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKGRpcywgIiIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgY2VydEZhY3RvcnlTcGkuZW5naW5lR2VuZXJhdGVDZXJ0UGF0aChkaXMsICJzcyIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZW5lcmF0ZUNlcnRpZmljYXRlKGJhaXMpOworICAgICAgICAgICAgZmFpbCgiQ2VydGlmaWNhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZW5lcmF0ZUNlcnRpZmljYXRlcyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkNlcnRpZmljYXRlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBDZXJ0aWZpY2F0ZSBjZXJ0ID0gY2VydEZhY3RvcnlTcGkKKyAgICAgICAgICAgICAgICAuZW5naW5lR2VuZXJhdGVDZXJ0aWZpY2F0ZShkaXMpOworICAgICAgICBhc3NlcnROdWxsKCJSZXN1bHQgbXVzdCBiZSBudWxsIiwgY2VydCk7CisgICAgICAgIENvbGxlY3Rpb248PyBleHRlbmRzIENlcnRpZmljYXRlPiBjb2wgPSBjZXJ0RmFjdG9yeVNwaQorICAgICAgICAgICAgICAgIC5lbmdpbmVHZW5lcmF0ZUNlcnRpZmljYXRlcyhkaXMpOworICAgICAgICBhc3NlcnROdWxsKCJSZXN1bHQgbXVzdCBiZSBudWxsIiwgY29sKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEZhY3RvcnlTcGkuZW5naW5lR2VuZXJhdGVDUkwoYmFpcyk7CisgICAgICAgICAgICBmYWlsKCJDUkxFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ1JMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEZhY3RvcnlTcGkuZW5naW5lR2VuZXJhdGVDUkxzKG51bGwpOworICAgICAgICAgICAgZmFpbCgiQ1JMRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENSTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgQ1JMIGNybCA9IGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ1JMKGRpcyk7CisgICAgICAgIGFzc2VydE51bGwoIlJlc3VsdCBtdXN0IGJlIG51bGwiLCBjcmwpOworICAgICAgICBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDUkw+IGNvbGNybCA9IGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ1JMcyhkaXMpOworICAgICAgICBhc3NlcnROdWxsKCJSZXN1bHQgbXVzdCBiZSBudWxsIiwgY29sY3JsKTsKKworICAgICAgICBMaXN0PENlcnRpZmljYXRlPiBsaXN0ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ2VydFBhdGgobGlzdCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBlbmMgPSBjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZXRDZXJ0UGF0aEVuY29kaW5ncygpOworICAgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgSXRlcmF0b3IiLCBlbmMuaGFzTmV4dCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZUZhY3RvcnlTcGk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlRmFjdG9yeVNwaQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkwMygpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIENSTEV4Y2VwdGlvbiB7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeVNwaSBjZXJ0RmFjdG9yeVNwaSA9IG5ldyBNeUNlcnRpZmljYXRlRmFjdG9yeVNwaSgpOworICAgICAgICBNeUNlcnRpZmljYXRlRmFjdG9yeVNwaS5wdXRNb2RlKGZhbHNlKTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSk7CisgICAgICAgIERhdGFJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGF0YUlucHV0U3RyZWFtKGJhaXMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEZhY3RvcnlTcGkuZW5naW5lR2VuZXJhdGVDZXJ0UGF0aChiYWlzKTsKKyAgICAgICAgICAgIGZhaWwoIkNlcnRpZmljYXRlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEZhY3RvcnlTcGkuZW5naW5lR2VuZXJhdGVDZXJ0UGF0aChkaXMpOworICAgICAgICAgICAgZmFpbCgiQ2VydGlmaWNhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKGJhaXMsICJhYSIpOworICAgICAgICAgICAgZmFpbCgiQ2VydGlmaWNhdGVFeGNlcHRpb24gbXVzdCBiZSB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ2VydFBhdGgoZGlzLCAiIik7CisgICAgICAgIGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ2VydFBhdGgoZGlzLCAic3MiKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEZhY3RvcnlTcGkuZW5naW5lR2VuZXJhdGVDZXJ0aWZpY2F0ZShiYWlzKTsKKyAgICAgICAgICAgIGZhaWwoIkNlcnRpZmljYXRlRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEZhY3RvcnlTcGkuZW5naW5lR2VuZXJhdGVDZXJ0aWZpY2F0ZXMobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgQ2VydGlmaWNhdGUgY2VydCA9IGNlcnRGYWN0b3J5U3BpCisgICAgICAgICAgICAgICAgLmVuZ2luZUdlbmVyYXRlQ2VydGlmaWNhdGUoZGlzKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiUmVzdWx0IG11c3QgYmUgbnVsbCIsIGNlcnQpOworICAgICAgICBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBDZXJ0aWZpY2F0ZT4gY29sID0gY2VydEZhY3RvcnlTcGkKKyAgICAgICAgICAgICAgICAuZW5naW5lR2VuZXJhdGVDZXJ0aWZpY2F0ZXMoZGlzKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiUmVzdWx0IG11c3QgYmUgbnVsbCIsIGNvbCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ1JMKGJhaXMpOworICAgICAgICAgICAgZmFpbCgiQ1JMRXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKENSTEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ1JMcyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIkNSTEV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChDUkxFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIENSTCBjcmwgPSBjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZW5lcmF0ZUNSTChkaXMpOworICAgICAgICBhc3NlcnROdWxsKCJSZXN1bHQgbXVzdCBiZSBudWxsIiwgY3JsKTsKKyAgICAgICAgQ29sbGVjdGlvbjw/IGV4dGVuZHMgQ1JMPiBjb2xjcmwgPSBjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZW5lcmF0ZUNSTHMoZGlzKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiUmVzdWx0IG11c3QgYmUgbnVsbCIsIGNvbGNybCk7CisKKyAgICAgICAgTGlzdDxDZXJ0aWZpY2F0ZT4gbGlzdCA9IG51bGw7CisgICAgICAgIGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ2VydFBhdGgobGlzdCk7CisgICAgICAgIEl0ZXJhdG9yPFN0cmluZz4gZW5jID0gY2VydEZhY3RvcnlTcGkuZW5naW5lR2V0Q2VydFBhdGhFbmNvZGluZ3MoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkluY29ycmVjdCBJdGVyYXRvciIsIGVuYy5oYXNOZXh0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmVuZ2luZUdlbmVyYXRlQ2VydFBhdGgoSW5wdXRTdHJlYW0pPC9jb2RlPiBtZXRob2QuCisgICAgICogQXNzZXJ0aW9uOiBHZW5lcmF0ZXMgYSA8Y29kZT5DZXJ0UGF0aDwvY29kZT4gb2JqZWN0IGFuZCBpbml0aWFsaXplcyBpdAorICAgICAqIHdpdGggdGhlIGRhdGEgcmVhZCBmcm9tIHRoZSA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5naW5lR2VuZXJhdGVDZXJ0UGF0aExqYXZhX2lvX0lucHV0U3RyZWFtMDEoKSB7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeVNwaSBjZXJ0RmFjdG9yeVNwaSA9IG5ldyBNeUNlcnRpZmljYXRlRmFjdG9yeVNwaSgpOworCisgICAgICAgIE15Q2VydGlmaWNhdGVGYWN0b3J5U3BpLnB1dE1vZGUodHJ1ZSk7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJhaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbMF0pOworICAgICAgICBEYXRhSW5wdXRTdHJlYW0gZGlzID0gbmV3IERhdGFJbnB1dFN0cmVhbShiYWlzKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbChjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKGRpcykpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIENlcnRpZmljYXRlRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5lbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKElucHV0U3RyZWFtKTwvY29kZT4gbWV0aG9kLgorICAgICAqIEFzc2VydGlvbjogR2VuZXJhdGVzIGEgPGNvZGU+Q2VydFBhdGg8L2NvZGU+IG9iamVjdCBhbmQgaW5pdGlhbGl6ZXMgaXQKKyAgICAgKiB3aXRoIHRoZSBkYXRhIHJlYWQgZnJvbSB0aGUgPGNvZGU+SW5wdXRTdHJlYW08L2NvZGU+CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEVuZ2luZUdlbmVyYXRlQ2VydFBhdGhMamF2YV9pb19JbnB1dFN0cmVhbTAyKCkgeworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkgY2VydEZhY3RvcnlTcGkgPSBuZXcgZXh0Q2VydGlmaWNhdGVGYWN0b3J5U3BpKCk7CisKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSk7CisgICAgICAgIERhdGFJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGF0YUlucHV0U3RyZWFtKGJhaXMpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKGRpcyk7CisgICAgICAgICAgICBmYWlsKCJVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIENlcnRpZmljYXRlRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5lbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKElucHV0U3RyZWFtLCBTdHJpbmcpPC9jb2RlPgorICAgICAqIG1ldGhvZC4gQXNzZXJ0aW9uOiBnZW5lcmF0ZXMgYSA8Y29kZT5DZXJ0UGF0aDwvY29kZT4gb2JqZWN0IGFuZAorICAgICAqIGluaXRpYWxpemVzIGl0IHdpdGggdGhlIGRhdGEgcmVhZCBmcm9tIHRoZSA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5naW5lR2VuZXJhdGVDZXJ0UGF0aExqYXZhX2lvX0lucHV0U3RyZWFtX0xqYXZhX2xhbmdfU3RyaW5nMDEoKSB7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeVNwaSBjZXJ0RmFjdG9yeVNwaSA9IG5ldyBNeUNlcnRpZmljYXRlRmFjdG9yeVNwaSgpOworICAgICAgICBNeUNlcnRpZmljYXRlRmFjdG9yeVNwaS5wdXRNb2RlKHRydWUpOworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiYWlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlWzBdKTsKKyAgICAgICAgRGF0YUlucHV0U3RyZWFtIGRpcyA9IG5ldyBEYXRhSW5wdXRTdHJlYW0oYmFpcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKGRpcywgIiIpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIENlcnRpZmljYXRlRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbChjZXJ0RmFjdG9yeVNwaS5lbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKGRpcywgImVuY29kaW5nIikpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIENlcnRpZmljYXRlRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5lbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKElucHV0U3RyZWFtLCBTdHJpbmcpPC9jb2RlPgorICAgICAqIG1ldGhvZC4gQXNzZXJ0aW9uOiBnZW5lcmF0ZXMgYSA8Y29kZT5DZXJ0UGF0aDwvY29kZT4gb2JqZWN0IGFuZAorICAgICAqIGluaXRpYWxpemVzIGl0IHdpdGggdGhlIGRhdGEgcmVhZCBmcm9tIHRoZSA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5naW5lR2VuZXJhdGVDZXJ0UGF0aExqYXZhX2lvX0lucHV0U3RyZWFtX0xqYXZhX2xhbmdfU3RyaW5nMDIoKSB7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeVNwaSBjZXJ0RmFjdG9yeVNwaSA9IG5ldyBleHRDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkoKTsKKworICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiYWlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlWzBdKTsKKyAgICAgICAgRGF0YUlucHV0U3RyZWFtIGRpcyA9IG5ldyBEYXRhSW5wdXRTdHJlYW0oYmFpcyk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ2VydFBhdGgoZGlzLCAiZW5jb2RpbmciKTsKKyAgICAgICAgICAgIGZhaWwoIlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgQ2VydGlmaWNhdGVFeGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmVuZ2luZUdlbmVyYXRlQ2VydFBhdGgoTGlzdDw/IGV4dGVuZHMgQ2VydGlmaWNhdGU+KTwvY29kZT4KKyAgICAgKiBtZXRob2QgQXNzZXJ0aW9uOiBnZW5lcmF0ZXMgYSA8Y29kZT5DZXJ0UGF0aDwvY29kZT4gb2JqZWN0IGFuZAorICAgICAqIGluaXRpYWxpemVzIGl0IHdpdGggYSA8Y29kZT5MaXN0PC9jb2RlPiBvZiA8Y29kZT5DZXJ0aWZpY2F0ZXM8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEVuZ2luZUdlbmVyYXRlQ2VydFBhdGhMSmF2YV91dGlsX0xpc3QwMSgpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5U3BpIGNlcnRGYWN0b3J5U3BpID0gbmV3IE15Q2VydGlmaWNhdGVGYWN0b3J5U3BpKCk7CisgICAgICAgIE15Q2VydGlmaWNhdGVGYWN0b3J5U3BpLnB1dE1vZGUodHJ1ZSk7CisgICAgICAgIExpc3Q8Q2VydGlmaWNhdGU+IGxpc3QgPSBuZXcgQXJyYXlMaXN0PENlcnRpZmljYXRlPigpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnROdWxsKGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ2VydFBhdGgobGlzdCkpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIENlcnRpZmljYXRlRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEZhY3RvcnlTcGkuZW5naW5lR2VuZXJhdGVDZXJ0UGF0aCgoTGlzdDw/IGV4dGVuZHMgQ2VydGlmaWNhdGU+KW51bGwpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+ZW5naW5lR2VuZXJhdGVDZXJ0UGF0aChMaXN0PD8gZXh0ZW5kcyBDZXJ0aWZpY2F0ZT4pPC9jb2RlPgorICAgICAqIG1ldGhvZCBBc3NlcnRpb246IGdlbmVyYXRlcyBhIDxjb2RlPkNlcnRQYXRoPC9jb2RlPiBvYmplY3QgYW5kCisgICAgICogaW5pdGlhbGl6ZXMgaXQgd2l0aCBhIDxjb2RlPkxpc3Q8L2NvZGU+IG9mIDxjb2RlPkNlcnRpZmljYXRlczwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5naW5lR2VuZXJhdGVDZXJ0UGF0aExKYXZhX3V0aWxfTGlzdDAyKCkgeworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkgY2VydEZhY3RvcnlTcGkgPSBuZXcgZXh0Q2VydGlmaWNhdGVGYWN0b3J5U3BpKCk7CisKKyAgICAgICAgTGlzdDxDZXJ0aWZpY2F0ZT4gbGlzdCA9IG5ldyBBcnJheUxpc3Q8Q2VydGlmaWNhdGU+KCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ2VydFBhdGgobGlzdCk7CisgICAgICAgICAgICBmYWlsKCJVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIENlcnRpZmljYXRlRXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWJzdHJhY3RNZXRob2RzKCkgeworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkgY2VydEZhY3RvcnlTcGkgPSBuZXcgZXh0Q2VydGlmaWNhdGVGYWN0b3J5U3BpKCk7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJhaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbM10pOworICAgICAgICBEYXRhSW5wdXRTdHJlYW0gZGlzID0gbmV3IERhdGFJbnB1dFN0cmVhbShiYWlzKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydEZhY3RvcnlTcGkuZW5naW5lR2VuZXJhdGVDUkwoZGlzKTsKKyAgICAgICAgICAgIGNlcnRGYWN0b3J5U3BpLmVuZ2luZUdlbmVyYXRlQ1JMcyhkaXMpOworICAgICAgICAgICAgY2VydEZhY3RvcnlTcGkuZW5naW5lR2VuZXJhdGVDZXJ0aWZpY2F0ZShkaXMpOworICAgICAgICAgICAgY2VydEZhY3RvcnlTcGkuZW5naW5lR2VuZXJhdGVDZXJ0aWZpY2F0ZXMoZGlzKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBleHRDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkgZXh0ZW5kcyBDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkgeworICAgICAgICBwdWJsaWMgQ2VydGlmaWNhdGUgZW5naW5lR2VuZXJhdGVDZXJ0aWZpY2F0ZShJbnB1dFN0cmVhbSBpblN0cmVhbSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKGluU3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oIklucHV0U3RyZWFtIG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgICAgIHB1YmxpYyBDb2xsZWN0aW9uIGVuZ2luZUdlbmVyYXRlQ2VydGlmaWNhdGVzKElucHV0U3RyZWFtIGluU3RyZWFtKQorICAgICAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoaW5TdHJlYW0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigiSW5wdXRTdHJlYW0gbnVsbCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgQ1JMIGVuZ2luZUdlbmVyYXRlQ1JMKElucHV0U3RyZWFtIGluU3RyZWFtKSB0aHJvd3MgQ1JMRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmIChpblN0cmVhbSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENSTEV4Y2VwdGlvbigiSW5wdXRTdHJlYW0gbnVsbCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgcHVibGljIENvbGxlY3Rpb24gZW5naW5lR2VuZXJhdGVDUkxzKElucHV0U3RyZWFtIGluU3RyZWFtKQorICAgICAgICAgICAgICAgIHRocm93cyBDUkxFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKGluU3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ1JMRXhjZXB0aW9uKCJJbnB1dFN0cmVhbSBudWxsIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisKKworCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGVhNWU4ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw4MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbjsKKworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5EaWdlc3RFeGNlcHRpb248L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisgICAgc3RhdGljIFRocm93YWJsZSB0Q2F1c2UgPSBuZXcgVGhyb3dhYmxlKCJUaHJvd2FibGUgZm9yIGV4Y2VwdGlvbiIpOworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbigpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsCisgICAgICogbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uMDEoKSB7CisgICAgICAgIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24gdEUgPSBuZXcgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbigpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24gd2l0aAorICAgICAqIGRldGFpbCBtZXNzYWdlIG1zZy4gUGFyYW1ldGVyIDxjb2RlPm1zZzwvY29kZT4gaXMgbm90IG51bGwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24wMigpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uKG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm46ICIuY29uY2F0KG1zZ3NbaV0pLCB0RQorICAgICAgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZSgpLCBtc2dzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uIHdoZW4KKyAgICAgKiA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbjAzKCkgeworICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICAgICAgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgIG1zZyk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvblRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYzFmMjU0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTgxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb247CisKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+Q2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uPC9jb2RlPiBjbGFzcyBjb25zdHJ1Y3RvcnMgYW5kCisgKiBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBtc2dzID0geworICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAiQ2hlY2sgbmV3IG1lc3NhZ2UiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIENoZWNrIG5ldyBtZXNzYWdlIiB9OworCisgICAgcHJpdmF0ZSBzdGF0aWMgVGhyb3dhYmxlIHRDYXVzZSA9IG5ldyBUaHJvd2FibGUoIlRocm93YWJsZSBmb3IgZXhjZXB0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24oKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uMDEoKSB7CisgICAgICAgIENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbiB0RSA9IG5ldyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24oKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlCisgICAgICogbXNnLiBQYXJhbWV0ZXIgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uMDIoKSB7CisgICAgICAgIENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24oU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIHdoZW4gPGNvZGU+bXNnPC9jb2RlPgorICAgICAqIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uMDMoKSB7CisgICAgICAgIFN0cmluZyBtc2cgPSBudWxsOworICAgICAgICBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24gdEUgPSBuZXcgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uKG1zZyk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsLiIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbihUaHJvd2FibGUpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbjA0KCkgeworICAgICAgICBUaHJvd2FibGUgY2F1c2UgPSBudWxsOworICAgICAgICBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24gdEUgPSBuZXcgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uKGNhdXNlKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuIG51bGwuIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Q2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uKFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbjA1KCkgeworICAgICAgICBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24gdEUgPSBuZXcgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uKHRDYXVzZSk7CisgICAgICAgIGlmICh0RS5nZXRNZXNzYWdlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgc2hvdWxkIGNvbnRhaW4gIi5jb25jYXQodG9TKSwgKGdldE0KKyAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwgdEUKKyAgICAgICAgICAgICAgICAuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24wNigpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIHRFID0gbmV3IENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbihudWxsLAorICAgICAgICAgICAgICAgIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIGFzc2VydE51bGwoImdldENhdXNlKCkgbXVzdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24wNygpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbihtc2dzW2ldLCBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdCBudWxsIDxjb2RlPm1zZzwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24wOCgpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIHRFID0gbmV3IENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbihudWxsLAorICAgICAgICAgICAgICAgIHRDYXVzZSk7CisgICAgICAgIGlmICh0RS5nZXRNZXNzYWdlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgbXVzdCBzaG91bGQgIi5jb25jYXQodG9TKSwgKGdldE0KKyAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwgdEUKKyAgICAgICAgICAgICAgICAuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5DZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QgbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbjA5KCkgeworICAgICAgICBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uKG1zZ3NbaV0sIHRDYXVzZSk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGlmIChtc2dzW2ldLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IGNvbnRhaW4gIi5jb25jYXQobXNnc1tpXSksIGdldE0KKyAgICAgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKG1zZ3NbaV0pICE9IC0xKTsKKyAgICAgICAgICAgICAgICBpZiAoIWdldE0uZXF1YWxzKG1zZ3NbaV0pKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBzaG91bGQgY29udGFpbiAiLmNvbmNhdCh0b1MpLCBnZXRNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwKKyAgICAgICAgICAgICAgICAgICAgdEUuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDEzZTE2YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDQzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5NeUNlcnRpZmljYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuTXlGYWlsaW5nQ2VydGlmaWNhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5UZXN0VXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnRlc3RmcmFtZXdvcmsuc2VyaWFsaXphdGlvbi5TZXJpYWxpemF0aW9uVGVzdDsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+Q2VydGlmaWNhdGU8L2NvZGU+IGZpZWxkcyBhbmQgbWV0aG9kcworICoKKyAqLworcHVibGljIGNsYXNzIENlcnRpZmljYXRlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICAvKioKKyAgICAgKiBNZWFuaW5nbGVzcyBjZXJ0IGVuY29kaW5nIGp1c3QgZm9yIHRlc3RpbmcgcHVycG9zZXMKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gdGVzdEVuY29kaW5nID0gbmV3IGJ5dGVbXSB7IChieXRlKSAxLCAoYnl0ZSkgMiwKKyAgICAgICAgICAgIChieXRlKSAzLCAoYnl0ZSkgNCwgKGJ5dGUpIDUgfTsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkNlcnRpZmljYXRlKFN0cmluZyB0eXBlKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RDZXJ0aWZpY2F0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDZXJ0aWZpY2F0ZSBjMSA9IG5ldyBNeUNlcnRpZmljYXRlKCJURVNUX1RZUEUiLCB0ZXN0RW5jb2RpbmcpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHModGVzdEVuY29kaW5nLCBjMS5nZXRFbmNvZGVkKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJURVNUIiwgYzEuZ2V0UHVibGljS2V5KCkuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMobmV3IGJ5dGVbXSB7IChieXRlKSAxLCAoYnl0ZSkgMiwgKGJ5dGUpIDMgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMxLmdldFB1YmxpY0tleSgpLmdldEVuY29kZWQoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRFU1RfRk9STUFUIiwgYzEuZ2V0UHVibGljS2V5KCkuZ2V0Rm9ybWF0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRFU1RfVFlQRSIsIGMxLmdldFR5cGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+aGFzaENvZGUoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBoYXNoIG9mIHRoZSA8Y29kZT5DZXJ0aWZpY2F0ZTwvY29kZT4gaW5zdGFuY2UKKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0SGFzaENvZGUoKSB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIENlcnRpZmljYXRlIGMxID0gbmV3IE15Q2VydGlmaWNhdGUoIlRFU1RfVFlQRSIsIHRlc3RFbmNvZGluZyk7CisgICAgICAgIENlcnRpZmljYXRlIGMyID0gbmV3IE15Q2VydGlmaWNhdGUoIlRFU1RfVFlQRSIsIHRlc3RFbmNvZGluZyk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShjMS5oYXNoQ29kZSgpID09IGMyLmhhc2hDb2RlKCkpOworCisgICAgICAgIGFzc2VydEZhbHNlKGMxLmhhc2hDb2RlKCkgPT0gbmV3IE15Q2VydGlmaWNhdGUoIlRFU1RfVFlQRSIsIGNlcnQKKyAgICAgICAgICAgICAgICAuZ2V0RW5jb2RlZCgpKS5oYXNoQ29kZSgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoYzEuaGFzaENvZGUoKSA9PSBjZXJ0Lmhhc2hDb2RlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmhhc2hDb2RlKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IGhhc2ggY29kZSBvZiBlcXVhbCBvYmplY3RzIHNob3VsZCBiZSB0aGUgc2FtZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RIYXNoQ29kZUVxdWFsc09iamVjdCgpIHsKKyAgICAgICAgQ2VydGlmaWNhdGUgYzEgPSBuZXcgTXlDZXJ0aWZpY2F0ZSgiVEVTVF9UWVBFIiwgdGVzdEVuY29kaW5nKTsKKyAgICAgICAgQ2VydGlmaWNhdGUgYzIgPSBuZXcgTXlDZXJ0aWZpY2F0ZSgiVEVTVF9UWVBFIiwgdGVzdEVuY29kaW5nKTsKKworICAgICAgICBhc3NlcnRUcnVlKChjMS5oYXNoQ29kZSgpID09IGMyLmhhc2hDb2RlKCkpICYmIGMxLmVxdWFscyhjMikpOworICAgICAgICBhc3NlcnRGYWxzZShjZXJ0LmVxdWFscyhjMSkpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0VHlwZSgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHRoaXMgY2VydGlmaWNhdGUgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRUeXBlKCkgeworICAgICAgICBDZXJ0aWZpY2F0ZSBjMSA9IG5ldyBNeUNlcnRpZmljYXRlKCJURVNUX1RZUEUiLCB0ZXN0RW5jb2RpbmcpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRFU1RfVFlQRSIsIGMxLmdldFR5cGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+ZXF1YWxzKE9iamVjdCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IG9iamVjdCBlcXVhbHMgdG8gaXRzZWxmCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVxdWFsc09iamVjdDAxKCkgeworICAgICAgICBDZXJ0aWZpY2F0ZSBjMSA9IG5ldyBNeUNlcnRpZmljYXRlKCJURVNUX1RZUEUiLCB0ZXN0RW5jb2RpbmcpOworICAgICAgICBhc3NlcnRUcnVlKGMxLmVxdWFscyhjMSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmVxdWFscyhPYmplY3QpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiBvYmplY3QgZXF1YWxzIHRvIG90aGVyIDxjb2RlPkNlcnRpZmljYXRlPC9jb2RlPgorICAgICAqIGluc3RhbmNlIHdpdGggdGhlIHNhbWUgc3RhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RXF1YWxzT2JqZWN0MDIoKSB7CisgICAgICAgIENlcnRpZmljYXRlIGMxID0gbmV3IE15Q2VydGlmaWNhdGUoIlRFU1RfVFlQRSIsIHRlc3RFbmNvZGluZyk7CisgICAgICAgIENlcnRpZmljYXRlIGMyID0gbmV3IE15Q2VydGlmaWNhdGUoIlRFU1RfVFlQRSIsIHRlc3RFbmNvZGluZyk7CisgICAgICAgIGFzc2VydFRydWUoYzEuZXF1YWxzKGMyKSAmJiBjMi5lcXVhbHMoYzEpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5lcXVhbHMoT2JqZWN0KTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogb2JqZWN0IG5vdCBlcXVhbHMgdG8gPGNvZGU+bnVsbDwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RXF1YWxzT2JqZWN0MDMoKSB7CisgICAgICAgIENlcnRpZmljYXRlIGMxID0gbmV3IE15Q2VydGlmaWNhdGUoIlRFU1RfVFlQRSIsIHRlc3RFbmNvZGluZyk7CisgICAgICAgIGFzc2VydEZhbHNlKGMxLmVxdWFscyhudWxsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+ZXF1YWxzKE9iamVjdCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IG9iamVjdCBub3QgZXF1YWxzIHRvIG90aGVyIHdoaWNoIGlzIG5vdAorICAgICAqIGluc3RhbmNlIG9mIDxjb2RlPkNlcnRpZmljYXRlPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFcXVhbHNPYmplY3QwNCgpIHsKKyAgICAgICAgQ2VydGlmaWNhdGUgYzEgPSBuZXcgTXlDZXJ0aWZpY2F0ZSgiVEVTVF9UWVBFIiwgdGVzdEVuY29kaW5nKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoYzEuZXF1YWxzKCJURVNUX1RZUEUiKSk7CisgICAgfQorCisgICAgLy8gdGhlIGZvbGxvd2luZyB0ZXN0cyBqdXN0IGNhbGwgbWV0aG9kcworICAgIC8vIHRoYXQgYXJlIGFic3RyYWN0IGluIDxjb2RlPkNlcnRpZmljYXRlPC9jb2RlPgorICAgIC8vIChTbyB0aGV5IGp1c3QgbGlrZSBzaWduYXR1cmUgdGVzdHMpCisKKyAgICAvKioKKyAgICAgKiBUaGlzIHRlc3QganVzdCBjYWxscyA8Y29kZT5nZXRFbmNvZGVkKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEVuY29kZWQoKSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBDZXJ0aWZpY2F0ZSBjMSA9IG5ldyBNeUNlcnRpZmljYXRlKCJURVNUX1RZUEUiLCB0ZXN0RW5jb2RpbmcpOworICAgICAgICBhc3NlcnROb3ROdWxsKGMxLmdldEVuY29kZWQoKSk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyh0ZXN0RW5jb2RpbmcsYzEuZ2V0RW5jb2RlZCgpKSk7CisKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICBieXRlW10gZXhwZWN0ZWRFbmNvZGluZyA9IGNlcnQuZ2V0RW5jb2RlZCgpOworICAgICAgICBDZXJ0aWZpY2F0ZSBhY3R1YWwgPSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShleHBlY3RlZEVuY29kaW5nKSk7CisgICAgICAgIGJ5dGVbXSBhY3R1YWxFbmNvZGluZyA9IGFjdHVhbC5nZXRFbmNvZGVkKCk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhleHBlY3RlZEVuY29kaW5nLCBhY3R1YWxFbmNvZGluZykpOworCisgICAgICAgIGFzc2VydEZhbHNlKGV4cGVjdGVkRW5jb2RpbmdbNF0gPT0gMjAwKTsKKyAgICAgICAgZXhwZWN0ZWRFbmNvZGluZ1s0XSA9IChieXRlKSAyMDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShleHBlY3RlZEVuY29kaW5nKSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIHRlc3QganVzdCBjYWxscyA8Y29kZT52ZXJpZnkoUHVibGljS2V5KTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogQHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFZlcmlmeVB1YmxpY0tleSgpCisgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVFeGNlcHRpb24sCisgICAgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgIENlcnRpZmljYXRlIGMxID0gbmV3IE15Q2VydGlmaWNhdGUoIlRFU1RfVFlQRSIsIHRlc3RFbmNvZGluZyk7CisgICAgICAgIGMxLnZlcmlmeShudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIHRlc3QganVzdCBjYWxscyA8Y29kZT52ZXJpZnkoUHVibGljS2V5LFN0cmluZyk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RWZXJpZnlQdWJsaWNLZXlTdHJpbmcoKQorICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgIENlcnRpZmljYXRlRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICAgICBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICBDZXJ0aWZpY2F0ZSBjMSA9IG5ldyBNeUNlcnRpZmljYXRlKCJURVNUX1RZUEUiLCB0ZXN0RW5jb2RpbmcpOworICAgICAgICBjMS52ZXJpZnkobnVsbCwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyB0ZXN0IGp1c3QgY2FsbHMgPGNvZGU+dG9TdHJpbmcoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RUb1N0cmluZygpIHsKKyAgICAgICAgQ2VydGlmaWNhdGUgYzEgPSBuZXcgTXlDZXJ0aWZpY2F0ZSgiVEVTVF9UWVBFIiwgdGVzdEVuY29kaW5nKTsKKyAgICAgICAgYzEudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIHRlc3QganVzdCBjYWxscyA8Y29kZT50ZXN0R2V0UHVibGljS2V5KCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0UHVibGljS2V5KCkgeworICAgICAgICBDZXJ0aWZpY2F0ZSBjMSA9IG5ldyBNeUNlcnRpZmljYXRlKCJURVNUX1RZUEUiLCB0ZXN0RW5jb2RpbmcpOworICAgICAgICBjMS5nZXRQdWJsaWNLZXkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIHRlc3QganVzdCBjYWxscyA8Y29kZT53cml0ZVJlcGxhY2UoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RXcml0ZVJlcGxhY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTXlDZXJ0aWZpY2F0ZSBjMSA9IG5ldyBNeUNlcnRpZmljYXRlKCJURVNUX1RZUEUiLCB0ZXN0RW5jb2RpbmcpOworICAgICAgICBPYmplY3Qgb2JqID0gYzEud3JpdGVSZXBsYWNlKCk7CisgICAgICAgIGFzc2VydFRydWUob2JqLnRvU3RyaW5nKCkuY29udGFpbnMoImphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZSRDZXJ0aWZpY2F0ZVJlcCIpKTsKKyAgICB9CisKK3B1YmxpYyBjbGFzcyBNeU1vZGlmaWFibGVQdWJsaWNLZXkgaW1wbGVtZW50cyBQdWJsaWNLZXkgeworCisgICAgICAgIHByaXZhdGUgUHVibGljS2V5IGtleTsKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIG1vZGlmaWVkQWxnbzsKKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgYWxnbzsKKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgZm9ybWF0OworICAgICAgICBwcml2YXRlIGJvb2xlYW4gbW9kaWZpZWRGb3JtYXQ7CisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBtb2RpZmllZEVuY29kaW5nOworICAgICAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGluZzsKKworICAgICAgICBwdWJsaWMgTXlNb2RpZmlhYmxlUHVibGljS2V5KFB1YmxpY0tleSBrKSB7CisgICAgICAgICAgICBzdXBlcigpOworICAgICAgICAgICAgdGhpcy5rZXkgPSBrOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgICAgICBpZiAobW9kaWZpZWRBbGdvKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGFsZ287CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBrZXkuZ2V0QWxnb3JpdGhtKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgICAgIGlmIChtb2RpZmllZEZvcm1hdCkgeworICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1hdDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGtleS5nZXRGb3JtYXQoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgaWYgKG1vZGlmaWVkRW5jb2RpbmcpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGluZzsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGtleS5nZXRFbmNvZGVkKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBsb25nIGdldFNlclZlclVJRCgpIHsKKyAgICAgICAgICAgIHJldHVybiBrZXkuc2VyaWFsVmVyc2lvblVJRDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldEFsZ29yaXRobShTdHJpbmcgbXlBbGdvKSB7CisgICAgICAgICAgICBtb2RpZmllZEFsZ28gPSB0cnVlOworICAgICAgICAgICAgdGhpcy5hbGdvID0gbXlBbGdvOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0Rm9ybWF0KFN0cmluZyBteUZvcm1hdCkgeworICAgICAgICAgICAgbW9kaWZpZWRGb3JtYXQgPSB0cnVlOworICAgICAgICAgICAgZm9ybWF0ID0gbXlGb3JtYXQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyhieXRlW10gbXlFbmNvZGVkKSB7CisgICAgICAgICAgICBtb2RpZmllZEVuY29kaW5nID0gdHJ1ZTsKKyAgICAgICAgICAgIGVuY29kaW5nID0gbXlFbmNvZGVkOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBDZXJ0aWZpY2F0ZSBjZXJ0OworCisgICAgcHJpdmF0ZSBQcm92aWRlciB3cm9uZ1Byb3ZpZGVyOworCisgICAgcHJpdmF0ZSBQcm92aWRlciB1c2VmdWxQcm92aWRlcjsKKworICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIFRlc3RVdGlscy5pbml0Q2VydFBhdGhTU0NlcnRDaGFpbigpOworICAgICAgICBjZXJ0ID0gVGVzdFV0aWxzLnJvb3RDZXJ0aWZpY2F0ZVNTOworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIHdyb25nUHJvdmlkZXIgPSBjZi5nZXRQcm92aWRlcigpOworICAgICAgICB1c2VmdWxQcm92aWRlciA9IFNpZ25hdHVyZS5nZXRJbnN0YW5jZSgiU0hBMVdpdGhSU0EiKS5nZXRQcm92aWRlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgdGVzdCBqdXN0IGNhbGxzIDxjb2RlPnZlcmlmeShQdWJsaWNLZXksU3RyaW5nKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogQHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFZlcmlmeVB1YmxpY0tleVN0cmluZzIoKSB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIENlcnRpZmljYXRlRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKworICAgICAgICAvLyByZWFsIHRlc3QKKyAgICAgICAgY2VydC52ZXJpZnkoY2VydC5nZXRQdWJsaWNLZXkoKSwgdXNlZnVsUHJvdmlkZXIuZ2V0TmFtZSgpKTsKKworICAgICAgICAvLyBFeGNlcHRpb24gdGVzdHMKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydC52ZXJpZnkoY2VydC5nZXRQdWJsaWNLZXkoKSwgIlVua25vd25Qcm92aWRlciIpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgLy8gVGhpcyB0ZXN0IGhhcyBzaWRlIGVmZmVjdHMgYWZmZWN0aW5nIGFsbCBvdGhlciB0ZXN0cyBydW5uaW5nIGxhdGVyCisgICAgICAgIC8vIG9uIGluIHRoZSBzYW1lIHZtIGluc3RhbmNlLiBNYXliZSBhIGJldHRlciB3YXkgd291bGQgYmUgdG8gZmlyc3QgYWRkCisgICAgICAgIC8vIGEgbmV3IHByb3ZpZGVyLCB0ZXN0IGlmIGl0IHdvcmtzLCB0aGVuIHJlbW92ZSBpdCBhbmQgdGVzdCBpZiB0aGUKKyAgICAgICAgLy8gZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgICAgLy8KKyAgICAgICAgLy8gU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIod3JvbmdQcm92aWRlci5nZXROYW1lKCkpOworICAgICAgICAvLworICAgICAgICAvLyB0cnkgeworICAgICAgICAvLyAgICAgY2VydC52ZXJpZnkoY2VydC5nZXRQdWJsaWNLZXkoKSwgd3JvbmdQcm92aWRlci5nZXROYW1lKCkpOworICAgICAgICAvLyAgICAgZmFpbCgpOworICAgICAgICAvLyB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgLy8gfQorICAgICAgICAvLworICAgICAgICAvLyBTZWN1cml0eS5pbnNlcnRQcm92aWRlckF0KHdyb25nUHJvdmlkZXIsIG9sZFBvc2l0aW9uKTsKKworICAgICAgICAvKgorICAgICAgICBQdWJsaWNLZXkgayA9IGNlcnQuZ2V0UHVibGljS2V5KCk7CisgICAgICAgIE15TW9kaWZpYWJsZVB1YmxpY0tleSB0YW1wZXJlZEtleSA9IG5ldyBNeU1vZGlmaWFibGVQdWJsaWNLZXkoayk7CisgICAgICAgIHRhbXBlcmVkS2V5LnNldEFsZ29yaXRobSgid3JvbmdBbGdvIik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnQudmVyaWZ5KHRhbXBlcmVkS2V5LCBwcm92c1swXS5nZXROYW1lKCkpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChTaWduYXR1cmVFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0LnZlcmlmeShjMS5nZXRQdWJsaWNLZXkoKSwgcHJvdnNbMF0uZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgICovCisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyB0ZXN0IGp1c3QgY2FsbHMgPGNvZGU+dmVyaWZ5KFB1YmxpY0tleSk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0VmVyaWZ5UHVibGljS2V5MigpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiwgQ2VydGlmaWNhdGVFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sIFNpZ25hdHVyZUV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCisgICAgICAgIENlcnRpZmljYXRlIGMxID0gbmV3IE15Q2VydGlmaWNhdGUoIlRFU1RfVFlQRSIsIHRlc3RFbmNvZGluZyk7CisgICAgICAgIGMxLnZlcmlmeShudWxsKTsKKworICAgICAgICBjZXJ0LnZlcmlmeShjZXJ0LmdldFB1YmxpY0tleSgpKTsKKworICAgICAgICBQdWJsaWNLZXkgayA9IGNlcnQuZ2V0UHVibGljS2V5KCk7CisKKyAgICAgICAgTXlNb2RpZmlhYmxlUHVibGljS2V5IGNoYW5nZWRFbmNvZGluZyA9IG5ldyBNeU1vZGlmaWFibGVQdWJsaWNLZXkoayk7CisgICAgICAgIGNoYW5nZWRFbmNvZGluZy5zZXRFbmNvZGluZyhuZXcgYnl0ZVtjZXJ0LmdldEVuY29kZWQoKS5sZW5ndGggLSAxXSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnQudmVyaWZ5KGMxLmdldFB1YmxpY0tleSgpKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNlcnQudmVyaWZ5KGNoYW5nZWRFbmNvZGluZyk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyB0ZXN0IGp1c3QgY2FsbHMgPGNvZGU+d3JpdGVSZXBsYWNlKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0V3JpdGVSZXBsYWNlMigpIHsKKyAgICAgICAgTXlDZXJ0aWZpY2F0ZSBjMSA9IG5ldyBNeUZhaWxpbmdDZXJ0aWZpY2F0ZSgiVEVTVF9UWVBFIiwgdGVzdEVuY29kaW5nKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYzEud3JpdGVSZXBsYWNlKCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKE9iamVjdFN0cmVhbUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogc2VyaWFsaXphdGlvbi9kZXNlcmlhbGl6YXRpb24gY29tcGF0aWJpbGl0eS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXphdGlvblNlbGYoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVGVzdFV0aWxzLmluaXRDZXJ0UGF0aFNTQ2VydENoYWluKCk7CisKKyAgICAgICAgU2VyaWFsaXphdGlvblRlc3QudmVyaWZ5U2VsZihUZXN0VXRpbHMucm9vdENlcnRpZmljYXRlU1MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHNlcmlhbGl6YXRpb24vZGVzZXJpYWxpemF0aW9uIGNvbXBhdGliaWxpdHkgd2l0aCBSSS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXphdGlvbkNvbXBhdGliaWxpdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gY3JlYXRlIHRlc3QgZmlsZSAob25jZSkKKyAgICAgICAgLy8gU2VyaWFsaXphdGlvblRlc3QuY3JlYXRlR29sZGVuRmlsZSgiL3NkY2FyZCIsIHRoaXMsIFRlc3RVdGlscy5yb290Q2VydGlmaWNhdGVTUyk7CisgICAgICAgIFRlc3RVdGlscy5pbml0Q2VydFBhdGhTU0NlcnRDaGFpbigpOworCisgICAgICAgIFNlcmlhbGl6YXRpb25UZXN0LnZlcmlmeUdvbGRlbih0aGlzLCBUZXN0VXRpbHMucm9vdENlcnRpZmljYXRlU1MpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWU5OGMxNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0NvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjA5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFN0b3JlUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0Lk15Q2VydGlmaWNhdGU7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkNvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzPC9jb2RlPi4KKyAqLworcHVibGljIGNsYXNzIENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8vCisgICAgLy8gVGVzdHMKKyAgICAvLworCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+Q29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMoKTwvY29kZT4gY29uc3RydWN0b3I8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzMDEoKSB7CisgICAgICAgIENlcnRTdG9yZVBhcmFtZXRlcnMgY3AgPSBuZXcgQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaXNDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycyIsCisgICAgICAgICAgICAgICAgY3AgaW5zdGFuY2VvZiBDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+Q29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnM8L2NvZGU+IGNvbnN0cnVjdG9yPGJyPgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVyczAyKCkgeworICAgICAgICBDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycyBjcCA9IG5ldyBDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycygpOworICAgICAgICBDb2xsZWN0aW9uIGMgPSBjcC5nZXRDb2xsZWN0aW9uKCk7CisgICAgICAgIGFzc2VydFRydWUoImlzRW1wdHkiLCBjLmlzRW1wdHkoKSk7CisKKyAgICAgICAgLy8gY2hlY2sgdGhhdCBlbXB0eSBjb2xsZWN0aW9uIGlzIGltbXV0YWJsZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gdHJ5IHRvIG1vZGlmeSBpdAorICAgICAgICAgICAgYy5hZGQobmV3IE9iamVjdCgpKTsKKyAgICAgICAgICAgIGZhaWwoImVtcHR5IGNvbGxlY3Rpb24gbXVzdCBiZSBpbW11dGFibGUiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPkNvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzKENvbGxlY3Rpb24pPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yPGJyPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVyc0NvbGxlY3Rpb24wMSgpIHsKKyAgICAgICAgVmVjdG9yPENlcnRpZmljYXRlPiBjZXJ0aWZpY2F0ZXMgPSBuZXcgVmVjdG9yPENlcnRpZmljYXRlPigpOworICAgICAgICBjZXJ0aWZpY2F0ZXMuYWRkKG5ldyBNeUNlcnRpZmljYXRlKCJURVNUIiwgbmV3IGJ5dGVbXSB7fSkpOworICAgICAgICBuZXcgQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMoY2VydGlmaWNhdGVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5Db2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycyhDb2xsZWN0aW9uKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0Q29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnNDb2xsZWN0aW9uMDIoKSB7CisgICAgICAgIC8vIGp1c3QgY2hlY2sgdGhhdCB3ZSBhYmxlIHRvIGNyZWF0ZSBDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycworICAgICAgICAvLyBvYmplY3QgcGFzc2luZyBDb2xsZWN0aW9uIGNvbnRhaW5pbmcgT2JqZWN0IHdoaWNoIGlzIG5vdAorICAgICAgICAvLyBhIENlcnRpZmljYXRlIG9yIENSTAorICAgICAgICBWZWN0b3I8U3RyaW5nPiBjZXJ0aWZpY2F0ZXMgPSBuZXcgVmVjdG9yPFN0cmluZz4oKTsKKyAgICAgICAgY2VydGlmaWNhdGVzLmFkZChuZXcgU3RyaW5nKCJOb3QgYSBDZXJ0aWZpY2F0ZSIpKTsKKyAgICAgICAgbmV3IENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzKGNlcnRpZmljYXRlcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMyBmb3IgPGNvZGU+Q29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMoQ29sbGVjdGlvbik8L2NvZGU+CisgICAgICogY29uc3RydWN0b3I8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzQ29sbGVjdGlvbjAzKCkgeworICAgICAgICBWZWN0b3I8Q2VydGlmaWNhdGU+IGNlcnRpZmljYXRlcyA9IG5ldyBWZWN0b3I8Q2VydGlmaWNhdGU+KCk7CisgICAgICAgIC8vIGNyZWF0ZSB1c2luZyBlbXB0eSBjb2xsZWN0aW9uCisgICAgICAgIENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzIGNwID0KKyAgICAgICAgICAgIG5ldyBDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycyhjZXJ0aWZpY2F0ZXMpOworICAgICAgICAvLyBjaGVjayB0aGF0IHRoZSByZWZlcmVuY2UgaXMgdXNlZAorICAgICAgICBhc3NlcnRUcnVlKCJpc1JlZlVzZWRfMSIsIGNlcnRpZmljYXRlcyA9PSBjcC5nZXRDb2xsZWN0aW9uKCkpOworICAgICAgICAvLyBjaGVjayB0aGF0IGNvbGxlY3Rpb24gc3RpbGwgZW1wdHkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaXNFbXB0eSIsIGNwLmdldENvbGxlY3Rpb24oKS5pc0VtcHR5KCkpOworICAgICAgICAvLyBtb2RpZnkgb3VyIGNvbGxlY3Rpb24KKyAgICAgICAgY2VydGlmaWNhdGVzLmFkZChuZXcgTXlDZXJ0aWZpY2F0ZSgiVEVTVCIsIG5ldyBieXRlW10geyhieXRlKTF9KSk7CisgICAgICAgIGNlcnRpZmljYXRlcy5hZGQobmV3IE15Q2VydGlmaWNhdGUoIlRFU1QiLCBuZXcgYnl0ZVtdIHsoYnl0ZSkyfSkpOworICAgICAgICAvLyBjaGVjayB0aGF0IGludGVybmFsIHN0YXRlIGhhcyBiZWVuIGNoYW5nZWQgYWNjb3JkaW5nbHkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaXNSZWZVc2VkXzIiLCBjZXJ0aWZpY2F0ZXMuZXF1YWxzKGNwLmdldENvbGxlY3Rpb24oKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzQgZm9yIDxjb2RlPkNvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzKENvbGxlY3Rpb24pPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yPGJyPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVyc0NvbGxlY3Rpb24wNCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk5QRSBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5jbG9uZSgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdENsb25lMDEoKSB7CisgICAgICAgIFZlY3RvcjxDZXJ0aWZpY2F0ZT4gY2VydGlmaWNhdGVzID0gbmV3IFZlY3RvcjxDZXJ0aWZpY2F0ZT4oKTsKKyAgICAgICAgY2VydGlmaWNhdGVzLmFkZChuZXcgTXlDZXJ0aWZpY2F0ZSgiVEVTVCIsIG5ldyBieXRlW10geyhieXRlKTR9KSk7CisgICAgICAgIENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzIGNwMSA9CisgICAgICAgICAgICBuZXcgQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMoY2VydGlmaWNhdGVzKTsKKyAgICAgICAgQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMgY3AyID0KKyAgICAgICAgICAgIChDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycyljcDEuY2xvbmUoKTsKKyAgICAgICAgLy8gY2hlY2sgdGhhdCB0aGF0IHdlIGhhdmUgbmV3IG9iamVjdAorICAgICAgICBhc3NlcnRUcnVlKGNwMSAhPSBjcDIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPmNsb25lKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0Q2xvbmUwMigpIHsKKyAgICAgICAgVmVjdG9yPENlcnRpZmljYXRlPiBjZXJ0aWZpY2F0ZXMgPSBuZXcgVmVjdG9yPENlcnRpZmljYXRlPigpOworICAgICAgICBjZXJ0aWZpY2F0ZXMuYWRkKG5ldyBNeUNlcnRpZmljYXRlKCJURVNUIiwgbmV3IGJ5dGVbXSB7KGJ5dGUpNH0pKTsKKyAgICAgICAgQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMgY3AxID0KKyAgICAgICAgICAgIG5ldyBDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycyhjZXJ0aWZpY2F0ZXMpOworICAgICAgICBDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycyBjcDIgPQorICAgICAgICAgICAgKENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzKWNwMS5jbG9uZSgpOworICAgICAgICAvLyBjaGVjayB0aGF0IGJvdGggb2JqZWN0cyBob2xkIHRoZSBzYW1lIHJlZmVyZW5jZQorICAgICAgICBhc3NlcnRUcnVlKGNwMS5nZXRDb2xsZWN0aW9uKCkgPT0gY3AyLmdldENvbGxlY3Rpb24oKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMyBmb3IgPGNvZGU+Y2xvbmUoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RDbG9uZTAzKCkgeworICAgICAgICBDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycyBjcDEgPQorICAgICAgICAgICAgbmV3IENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzKCk7CisgICAgICAgIENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzIGNwMiA9CisgICAgICAgICAgICAoQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMpY3AxLmNsb25lKCk7CisgICAgICAgIENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzIGNwMyA9CisgICAgICAgICAgICAoQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMpY3AyLmNsb25lKCk7CisgICAgICAgIC8vIGNoZWNrIHRoYXQgYWxsIG9iamVjdHMgaG9sZCB0aGUgc2FtZSByZWZlcmVuY2UKKyAgICAgICAgYXNzZXJ0VHJ1ZShjcDEuZ2V0Q29sbGVjdGlvbigpID09IGNwMi5nZXRDb2xsZWN0aW9uKCkgJiYKKyAgICAgICAgICAgICAgICAgICBjcDMuZ2V0Q29sbGVjdGlvbigpID09IGNwMi5nZXRDb2xsZWN0aW9uKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPnRvU3RyaW5nKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0VG9TdHJpbmcwMSgpIHsKKyAgICAgICAgQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMgY3AgPQorICAgICAgICAgICAgbmV3IENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzKCk7CisgICAgICAgIFN0cmluZyBzID0gY3AudG9TdHJpbmcoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT50b1N0cmluZygpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFRvU3RyaW5nMDIoKSB7CisgICAgICAgIFZlY3RvcjxDZXJ0aWZpY2F0ZT4gY2VydGlmaWNhdGVzID0gbmV3IFZlY3RvcjxDZXJ0aWZpY2F0ZT4oKTsKKyAgICAgICAgY2VydGlmaWNhdGVzLmFkZChuZXcgTXlDZXJ0aWZpY2F0ZSgiVEVTVCIsIG5ldyBieXRlW10geyhieXRlKTR9KSk7CisgICAgICAgIENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzIGNwID0KKyAgICAgICAgICAgIG5ldyBDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycyhjZXJ0aWZpY2F0ZXMpOworCisgICAgICAgIGFzc2VydE5vdE51bGwoY3AudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+Z2V0Q29sbGVjdGlvbigpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldENvbGxlY3Rpb24wMSgpIHsKKyAgICAgICAgQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMgY3AgPSBuZXcgQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjcC5nZXRDb2xsZWN0aW9uKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPmdldENvbGxlY3Rpb24oKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRDb2xsZWN0aW9uMDIoKSB7CisgICAgICAgIFZlY3RvciBjZXJ0aWZpY2F0ZXMgPSBuZXcgVmVjdG9yKCk7CisgICAgICAgIENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzIGNwID0KKyAgICAgICAgICAgIG5ldyBDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycyhjZXJ0aWZpY2F0ZXMpOworICAgICAgICBhc3NlcnROb3ROdWxsKGNwLmdldENvbGxlY3Rpb24oKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9MREFQQ2VydFN0b3JlUGFyYW1ldGVyc1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L0xEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE5NjNmMzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9MREFQQ2VydFN0b3JlUGFyYW1ldGVyc1Rlc3QuamF2YQpAQCAtMCwwICsxLDE5NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRTdG9yZVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkxEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5qYXZhLnNlY3VyaXR5LmNlcnQuTERBUENlcnRTdG9yZVBhcmFtZXRlcnM8L2NvZGU+CisgKiBmaWVsZHMgYW5kIG1ldGhvZHMKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBMREFQQ2VydFN0b3JlUGFyYW1ldGVyc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvLworICAgIC8vIFRlc3RzCisgICAgLy8KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPkxEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzKCk8L2NvZGU+IGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiA8Y29kZT5MREFQQ2VydFN0b3JlUGFyYW1ldGVyczwvY29kZT4KKyAgICAgKiB3aXRoIHRoZSBkZWZhdWx0IHBhcmFtZXRlciB2YWx1ZXMgKHNlcnZlciBuYW1lICJsb2NhbGhvc3QiLCBwb3J0IDM4OSkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0TERBUENlcnRTdG9yZVBhcmFtZXRlcnMwMSgpIHsKKyAgICAgICAgQ2VydFN0b3JlUGFyYW1ldGVycyBjcCA9IG5ldyBMREFQQ2VydFN0b3JlUGFyYW1ldGVycygpOworICAgICAgICBhc3NlcnRUcnVlKCJpc0xEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzIiwKKyAgICAgICAgICAgICAgICBjcCBpbnN0YW5jZW9mIExEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5MREFQQ2VydFN0b3JlUGFyYW1ldGVycygpPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+TERBUENlcnRTdG9yZVBhcmFtZXRlcnM8L2NvZGU+CisgICAgICogd2l0aCB0aGUgZGVmYXVsdCBwYXJhbWV0ZXIgdmFsdWVzIChzZXJ2ZXIgbmFtZSAibG9jYWxob3N0IiwgcG9ydCAzODkpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdExEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzMDIoKSB7CisgICAgICAgIExEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzIGNwID0gbmV3IExEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygiaG9zdCIsICJsb2NhbGhvc3QiLCBjcC5nZXRTZXJ2ZXJOYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInBvcnQiLCAzODksIGNwLmdldFBvcnQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+TERBUENlcnRTdG9yZVBhcmFtZXRlcnMoU3RyaW5nKTwvY29kZT4gY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIDxjb2RlPkxEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzPC9jb2RlPgorICAgICAqIHdpdGggdGhlIHNwZWNpZmllZCBzZXJ2ZXIgbmFtZSBhbmQgYSBkZWZhdWx0IHBvcnQgb2YgMzg5CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdExEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzU3RyaW5nMDEoKSB7CisgICAgICAgIENlcnRTdG9yZVBhcmFtZXRlcnMgY3AgPSBuZXcgTERBUENlcnRTdG9yZVBhcmFtZXRlcnMoIm15aG9zdCIpOworICAgICAgICBhc3NlcnRUcnVlKCJpc0xEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzIiwKKyAgICAgICAgICAgICAgICBjcCBpbnN0YW5jZW9mIExEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5MREFQQ2VydFN0b3JlUGFyYW1ldGVycyhTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+TERBUENlcnRTdG9yZVBhcmFtZXRlcnM8L2NvZGU+CisgICAgICogd2l0aCB0aGUgc3BlY2lmaWVkIHNlcnZlciBuYW1lIGFuZCBhIGRlZmF1bHQgcG9ydCBvZiAzODkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0TERBUENlcnRTdG9yZVBhcmFtZXRlcnNTdHJpbmcwMigpIHsKKyAgICAgICAgU3RyaW5nIHNlcnZlck5hbWUgPSAibXlob3N0IjsKKyAgICAgICAgTERBUENlcnRTdG9yZVBhcmFtZXRlcnMgY3AgPSBuZXcgTERBUENlcnRTdG9yZVBhcmFtZXRlcnMoc2VydmVyTmFtZSk7CisgICAgICAgIGFzc2VydFRydWUoImhvc3QiLCBzZXJ2ZXJOYW1lLmVxdWFscyhjcC5nZXRTZXJ2ZXJOYW1lKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwb3J0IiwgMzg5LCBjcC5nZXRQb3J0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzMgZm9yIDxjb2RlPkxEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzKFN0cmluZyk8L2NvZGU+IGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiAtCisgICAgICogaWYgPGNvZGU+c2VydmVyTmFtZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0TERBUENlcnRTdG9yZVBhcmFtZXRlcnNTdHJpbmcwMygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBMREFQQ2VydFN0b3JlUGFyYW1ldGVycyhudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk5QRSBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5MREFQQ2VydFN0b3JlUGFyYW1ldGVycyhTdHJpbmcsIGludCk8L2NvZGU+IGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiA8Y29kZT5MREFQQ2VydFN0b3JlUGFyYW1ldGVyczwvY29kZT4KKyAgICAgKiB3aXRoIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIHZhbHVlcworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RMREFQQ2VydFN0b3JlUGFyYW1ldGVyc1N0cmluZ2ludDAxKCkgeworICAgICAgICBDZXJ0U3RvcmVQYXJhbWV0ZXJzIGNwID0gbmV3IExEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzKCJteWhvc3QiLCAxMDk4KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaXNMREFQQ2VydFN0b3JlUGFyYW1ldGVycyIsCisgICAgICAgICAgICAgICAgY3AgaW5zdGFuY2VvZiBMREFQQ2VydFN0b3JlUGFyYW1ldGVycyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+TERBUENlcnRTdG9yZVBhcmFtZXRlcnMoU3RyaW5nLCBpbnQpPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+TERBUENlcnRTdG9yZVBhcmFtZXRlcnM8L2NvZGU+CisgICAgICogd2l0aCB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciB2YWx1ZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0TERBUENlcnRTdG9yZVBhcmFtZXRlcnNTdHJpbmdpbnQwMigpIHsKKyAgICAgICAgU3RyaW5nIHNlcnZlck5hbWUgPSAibXlob3N0IjsKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSAxMDk5OworICAgICAgICBMREFQQ2VydFN0b3JlUGFyYW1ldGVycyBjcCA9CisgICAgICAgICAgICBuZXcgTERBUENlcnRTdG9yZVBhcmFtZXRlcnMoc2VydmVyTmFtZSwgcG9ydE51bWJlcik7CisgICAgICAgIGFzc2VydFRydWUoImhvc3QiLCBzZXJ2ZXJOYW1lLmVxdWFscyhjcC5nZXRTZXJ2ZXJOYW1lKCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgicG9ydCIsIGNwLmdldFBvcnQoKSA9PSBwb3J0TnVtYmVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMzIGZvciA8Y29kZT5MREFQQ2VydFN0b3JlUGFyYW1ldGVycyhTdHJpbmcsIGludCk8L2NvZGU+IGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiAtCisgICAgICogaWYgPGNvZGU+c2VydmVyTmFtZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0TERBUENlcnRTdG9yZVBhcmFtZXRlcnNTdHJpbmdpbnQwMygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBMREFQQ2VydFN0b3JlUGFyYW1ldGVycyhudWxsLCAwKTsKKyAgICAgICAgICAgIGZhaWwoIk5QRSBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgc2VydmVyTmFtZSA9ICJteWhvc3QiOworICAgICAgICBpbnRbXSBwb3J0TnVtYmVyID0gey0xLCAtMTAwLCBJbnRlZ2VyLk1JTl9WQUxVRSwgSW50ZWdlci5NQVhfVkFMVUV9OworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBvcnROdW1iZXIubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbmV3IExEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzKHNlcnZlck5hbWUsIHBvcnROdW1iZXJbaV0pOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiBmb3IgaW5jb3JyZWN0IGludGVnZXIgcGFyYW1ldHIiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmNsb25lKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IFJldHVybnMgYSBjb3B5IG9mIHRoaXMgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdENsb25lKCkgeworICAgICAgICBMREFQQ2VydFN0b3JlUGFyYW1ldGVycyBjcDEgPQorICAgICAgICAgICAgbmV3IExEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzKCJteWhvc3QiLCAxMTAwKTsKKyAgICAgICAgTERBUENlcnRTdG9yZVBhcmFtZXRlcnMgY3AyID0gKExEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzKWNwMS5jbG9uZSgpOworICAgICAgICAvLyBjaGVjayB0aGF0IHRoYXQgd2UgaGF2ZSBuZXcgb2JqZWN0CisgICAgICAgIGFzc2VydFRydWUoIm5ld09iamVjdCIsIGNwMSAhPSBjcDIpOworICAgICAgICBhc3NlcnRUcnVlKCJob3N0c1RoZVNhbWUiLAorICAgICAgICAgICAgICAgIGNwMS5nZXRTZXJ2ZXJOYW1lKCkuZXF1YWxzKGNwMi5nZXRTZXJ2ZXJOYW1lKCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgicG9ydHNUaGVTYW1lIiwgY3AxLmdldFBvcnQoKSA9PSBjcDIuZ2V0UG9ydCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT50b1N0cmluZygpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHRoZSBmb3JtYXR0ZWQgc3RyaW5nIGRlc2NyaWJpbmcgcGFyYW1ldGVycworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RUb1N0cmluZygpIHsKKyAgICAgICAgTERBUENlcnRTdG9yZVBhcmFtZXRlcnMgY3AxID0KKyAgICAgICAgICAgIG5ldyBMREFQQ2VydFN0b3JlUGFyYW1ldGVycygibXlob3N0IiwgMTEwMSk7CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjcDEudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+dG9TdHJpbmcoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyB0aGUgcG9ydCBudW1iZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0UG9ydCgpIHsKKyAgICAgICAgaW50IHBvcnROdW1iZXIgPSAtMTA5OTsKKyAgICAgICAgTERBUENlcnRTdG9yZVBhcmFtZXRlcnMgY3AgPQorICAgICAgICAgICAgbmV3IExEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzKCJzZXJ2ZXJOYW1lIiwgcG9ydE51bWJlcik7CisgICAgICAgIGFzc2VydFRydWUoY3AuZ2V0UG9ydCgpID09IHBvcnROdW1iZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnRvU3RyaW5nKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgdGhlIHNlcnZlciBuYW1lIChuZXZlciA8Y29kZT5udWxsPC9jb2RlPikKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0U2VydmVyTmFtZSgpIHsKKyAgICAgICAgTERBUENlcnRTdG9yZVBhcmFtZXRlcnMgY3AgPQorICAgICAgICAgICAgbmV3IExEQVBDZXJ0U3RvcmVQYXJhbWV0ZXJzKCJzZXJ2ZXJOYW1lIik7CisgICAgICAgIGFzc2VydE5vdE51bGwoY3AuZ2V0U2VydmVyTmFtZSgpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L1BLSVhCdWlsZGVyUGFyYW1ldGVyc1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L1BLSVhCdWlsZGVyUGFyYW1ldGVyc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNWUzNTM4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzYwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LlBLSVhCdWlsZGVyUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuUEtJWFBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LlRydXN0QW5jaG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuVGVzdFV0aWxzOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5QS0lYQnVpbGRlclBhcmFtZXRlcnM8L2NvZGU+IGZpZWxkcyBhbmQgbWV0aG9kcworICoKKyAqLworcHVibGljIGNsYXNzIFBLSVhCdWlsZGVyUGFyYW1ldGVyc1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgU3RyaW5nIGNlcnRpZmljYXRlID0gIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICAgICAgICAgKyAiTUlJQ1pUQ0NBZElDQlFMM0FBQzJNQTBHQ1NxR1NJYjNEUUVCQWdVQU1GOHhDekFKQmdOVkJBWVRBbFZUTVNBd1xuIgorICAgICAgICAgICAgKyAiSGdZRFZRUUtFeGRTVTBFZ1JHRjBZU0JUWldOMWNtbDBlU3dnU1c1akxqRXVNQ3dHQTFVRUN4TWxVMlZqZFhKbFxuIgorICAgICAgICAgICAgKyAiSUZObGNuWmxjaUJEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVUQWVGdzA1TnpBeU1qQXdNREF3TURCYVxuIgorICAgICAgICAgICAgKyAiRncwNU9EQXlNakF5TXpVNU5UbGFNSUdXTVFzd0NRWURWUVFHRXdKVlV6RVRNQkVHQTFVRUNCTUtRMkZzYVdadlxuIgorICAgICAgICAgICAgKyAiY201cFlURVNNQkFHQTFVRUJ4TUpVR0ZzYnlCQmJIUnZNUjh3SFFZRFZRUUtFeFpUZFc0Z1RXbGpjbTl6ZVhOMFxuIgorICAgICAgICAgICAgKyAiWlcxekxDQkpibU11TVNFd0h3WURWUVFMRXhoVVpYTjBJR0Z1WkNCRmRtRnNkV0YwYVc5dUlFOXViSGt4R2pBWVxuIgorICAgICAgICAgICAgKyAiQmdOVkJBTVRFV0Z5WjI5dUxtVnVaeTV6ZFc0dVkyOXRNSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdOQURDQlxuIgorICAgICAgICAgICAgKyAiaVFLQmdRQ29mbWRZK1BpVVdOMDFGT3pFZXdmK0dhRytsRmYxMzJVcHpBVG1ZSmtBNEFFQS9qdVc3alNpK0xKa1xuIgorICAgICAgICAgICAgKyAid0pLaTVHTzRSeVpveWltQUwvNXlJV0RWNmwxS2x2eHlLc2xyMFJFaE1CYUQvM1ozRXNMVFRFZjVnVnJRUzZzVFxuIgorICAgICAgICAgICAgKyAiV01vU1pBeXpCMzlrRmZzQjZvVVhOdFY4K1VLS3hTeEtieHZoUW4yNjdQZUN6NVZYMlFJREFRQUJNQTBHQ1NxR1xuIgorICAgICAgICAgICAgKyAiU0liM0RRRUJBZ1VBQTM0QVhsM2F0Nmx1aVYvN0k5TU41Q1hZb1BKWUk4QmNkYzFoQmFnSnZUTWNtbHFMMnVPWlxuIgorICAgICAgICAgICAgKyAiSDlUNWhOTUVMOVRrNmFJN3laUFhjdy94STJLNnBPUi9Gck1wMFV3Sm1keFg3bGpWNlp0VVpmN3BZNDkyVXF3Q1xuIgorICAgICAgICAgICAgKyAiMTc3N1hROVVFWnlyS0p2RjVudGxlZU8wYXlCcUxHVktDV3pXWlg5WXNYQ3B2NDdGTkxaYnVwRT1cbiIKKyAgICAgICAgICAgICsgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cbiI7CisKKyAgICBTdHJpbmcgY2VydGlmaWNhdGUyID0gIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICAgICAgICAgKyAiTUlJQ1p6Q0NBZENnQXdJQkFnSUJHekFOQmdrcWhraUc5dzBCQVFVRkFEQmhNUXN3Q1FZRFZRUUdFd0pWVXpFWVxuIgorICAgICAgICAgICAgKyAiTUJZR0ExVUVDaE1QVlM1VExpQkhiM1psY201dFpXNTBNUXd3Q2dZRFZRUUxFd05FYjBReEREQUtCZ05WQkFzVFxuIgorICAgICAgICAgICAgKyAiQTFCTFNURWNNQm9HQTFVRUF4TVRSRzlFSUZCTFNTQk5aV1FnVW05dmRDQkRRVEFlRncwNU9EQTRNRE15TWpBeVxuIgorICAgICAgICAgICAgKyAiTWpsYUZ3MHdPREE0TURReU1qQXlNamxhTUdFeEN6QUpCZ05WQkFZVEFsVlRNUmd3RmdZRFZRUUtFdzlWTGxNdVxuIgorICAgICAgICAgICAgKyAiSUVkdmRtVnlibTFsYm5ReEREQUtCZ05WQkFzVEEwUnZSREVNTUFvR0ExVUVDeE1EVUV0Sk1Sd3dHZ1lEVlFRRFxuIgorICAgICAgICAgICAgKyAiRXhORWIwUWdVRXRKSUUxbFpDQlNiMjkwSUVOQk1JR2ZNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCaVFLQlxuIgorICAgICAgICAgICAgKyAiZ1FEYnJNL0o5RnJKU1grenhGVWJzSTlWdzVRYmd1VkJJYTk1cndXLzBNOCtzTTByNWdkK0RZNml1Ym02d25Ya1xuIgorICAgICAgICAgICAgKyAiQ1N2YmZRbEZFRFNLcjRXWWVlR3ArZDlXbERuUWR0REZMZEE0NXRDaTVTSGpuVytoR0FtWm5sZDByejZ3UWVrRlxuIgorICAgICAgICAgICAgKyAiNXhRYWE1QTZ3amhNbExPamJoMjd6eXNjcm9yTUoxTzVGQk9XbkVIY1J2NnhxUUlEQVFBQm95OHdMVEFkQmdOVlxuIgorICAgICAgICAgICAgKyAiSFE0RUZnUVVWcm1ZUjZtOTcwMWNIUTNyNWtYeUc3enNDTjB3REFZRFZSMFRCQVV3QXdFQi96QU5CZ2txaGtpR1xuIgorICAgICAgICAgICAgKyAiOXcwQkFRVUZBQU9CZ1FEVlgxWTBZcUM3dmVrZVpqVnh0eXVDOE1ueGJyejZEMTA5QVgwN0xFSVJ6Tll6d1owd1xuIgorICAgICAgICAgICAgKyAiTVRJbVNwOXNFeldXKzNGdWVCSVU3QXhHeXMyTzdYMHFtTjN6Z3N6UGZTaW9jQnVRdVhJWVFjdEpoS2pGNUtWY1xuIgorICAgICAgICAgICAgKyAiVkdRUllZbHQrbXlobDJ2eTZ5UHpFVkNqaUt3TUViMVNwdTBpckNmK2xGVzJoc2Rqdm1TUU10WnZPdz09XG4iCisgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iOworCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+UEtJWEJ1aWxkZXJQYXJhbWV0ZXJzKFNldCwgQ2VydFNlbGVjdG9yKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IGNyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+UEtJWEJ1aWxkZXJQYXJhbWV0ZXJzPC9jb2RlPgorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RQS0lYQnVpbGRlclBhcmFtZXRlcnNTZXRDZXJ0U2VsZWN0b3IwMSgpCisgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgU2V0PFRydXN0QW5jaG9yPiB0YVNldCA9IFRlc3RVdGlscy5nZXRUcnVzdEFuY2hvclNldCgpOworICAgICAgICBpZiAodGFTZXQgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiOiBub3QgcGVyZm9ybWVkIChjb3VsZCBub3QgY3JlYXRlIHRlc3QgVHJ1c3RBbmNob3Igc2V0KSIpOworICAgICAgICB9CisgICAgICAgIC8vIGJvdGggcGFyYW1ldGVycyBhcmUgdmFsaWQgYW5kIG5vbi1udWxsCisgICAgICAgIFBLSVhQYXJhbWV0ZXJzIHAgPQorICAgICAgICAgICAgbmV3IFBLSVhCdWlsZGVyUGFyYW1ldGVycyh0YVNldCwgbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKSk7CisgICAgICAgIGFzc2VydFRydWUoImluc3RhbmNlT2YiLCBwIGluc3RhbmNlb2YgUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiY2VydFNlbGVjdG9yIiwgcC5nZXRUYXJnZXRDZXJ0Q29uc3RyYWludHMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+UEtJWEJ1aWxkZXJQYXJhbWV0ZXJzKFNldCwgQ2VydFNlbGVjdG9yKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IGNyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+UEtJWEJ1aWxkZXJQYXJhbWV0ZXJzPC9jb2RlPgorICAgICAqIEB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RQS0lYQnVpbGRlclBhcmFtZXRlcnNTZXRDZXJ0U2VsZWN0b3IwMigpCisgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgU2V0PFRydXN0QW5jaG9yPiB0YVNldCA9IFRlc3RVdGlscy5nZXRUcnVzdEFuY2hvclNldCgpOworICAgICAgICBpZiAodGFTZXQgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiOiBub3QgcGVyZm9ybWVkIChjb3VsZCBub3QgY3JlYXRlIHRlc3QgVHJ1c3RBbmNob3Igc2V0KSIpOworICAgICAgICB9CisgICAgICAgIC8vIGJvdGggcGFyYW1ldGVycyBhcmUgdmFsaWQgYnV0IENlcnRTZWxlY3RvciBpcyBudWxsCisgICAgICAgIFBLSVhQYXJhbWV0ZXJzIHAgPSBuZXcgUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzKHRhU2V0LCBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiaW5zdGFuY2VPZiIsIHAgaW5zdGFuY2VvZiBQS0lYQnVpbGRlclBhcmFtZXRlcnMpOworICAgICAgICBhc3NlcnROdWxsKCJjZXJ0U2VsZWN0b3IiLCBwLmdldFRhcmdldENlcnRDb25zdHJhaW50cygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMzIGZvciA8Y29kZT5QS0lYQnVpbGRlclBhcmFtZXRlcnMoU2V0LCBDZXJ0U2VsZWN0b3IpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogLi4uIHRoZSA8Y29kZT5TZXQ8L2NvZGU+IGlzIGNvcGllZCB0byBwcm90ZWN0IGFnYWluc3QKKyAgICAgKiBzdWJzZXF1ZW50IG1vZGlmaWNhdGlvbnMKKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UEtJWEJ1aWxkZXJQYXJhbWV0ZXJzU2V0Q2VydFNlbGVjdG9yMDMoKQorICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIFNldDxUcnVzdEFuY2hvcj4gdGFTZXQgPSBUZXN0VXRpbHMuZ2V0VHJ1c3RBbmNob3JTZXQoKTsKKyAgICAgICAgaWYgKHRhU2V0ID09IG51bGwpIHsKKyAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm90IHBlcmZvcm1lZCAoY291bGQgbm90IGNyZWF0ZSB0ZXN0IFRydXN0QW5jaG9yIHNldCkiKTsKKyAgICAgICAgfQorICAgICAgICBIYXNoU2V0PFRydXN0QW5jaG9yPiBvcmlnaW5hbFNldCA9IChIYXNoU2V0PFRydXN0QW5jaG9yPikgdGFTZXQ7CisgICAgICAgIEhhc2hTZXQ8VHJ1c3RBbmNob3I+IG9yaWdpbmFsU2V0Q29weSA9IChIYXNoU2V0PFRydXN0QW5jaG9yPikgb3JpZ2luYWxTZXQKKyAgICAgICAgICAgICAgICAuY2xvbmUoKTsKKyAgICAgICAgLy8gY3JlYXRlIHRlc3Qgb2JqZWN0IHVzaW5nIG9yaWdpbmFsU2V0CisgICAgICAgIFBLSVhCdWlsZGVyUGFyYW1ldGVycyBwcCA9CisgICAgICAgICAgICBuZXcgUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzKG9yaWdpbmFsU2V0Q29weSwgbnVsbCk7CisgICAgICAgIC8vIG1vZGlmeSBvcmlnaW5hbFNldAorICAgICAgICBvcmlnaW5hbFNldENvcHkuY2xlYXIoKTsKKyAgICAgICAgLy8gY2hlY2sgdGhhdCB0ZXN0IG9iamVjdCdzIGludGVybmFsIHN0YXRlCisgICAgICAgIC8vIGhhcyBub3QgYmVlbiBhZmZlY3RlZCBieSB0aGUgYWJvdmUgbW9kaWZpY2F0aW9uCisgICAgICAgIFNldCByZXR1cm5lZFNldCA9IHBwLmdldFRydXN0QW5jaG9ycygpOworICAgICAgICBhc3NlcnRFcXVhbHMob3JpZ2luYWxTZXQsIHJldHVybmVkU2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM0IGZvciA8Y29kZT5QS0lYQnVpbGRlclBhcmFtZXRlcnMoU2V0LCBDZXJ0U2VsZWN0b3IpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IC0KKyAgICAgKiBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPlNldDwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RQS0lYQnVpbGRlclBhcmFtZXRlcnNTZXRDZXJ0U2VsZWN0b3IwNCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gcGFzcyBudWxsCisgICAgICAgICAgICBuZXcgUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzKChTZXQ8VHJ1c3RBbmNob3I+KSBudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk5QRSBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM1IGZvciA8Y29kZT5QS0lYQnVpbGRlclBhcmFtZXRlcnMoU2V0LCBDZXJ0U2VsZWN0b3IpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogPGNvZGU+SW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjwvY29kZT4gLQorICAgICAqIGlmIHRoZSBzcGVjaWZpZWQgPGNvZGU+U2V0PC9jb2RlPiBpcyBlbXB0eQorICAgICAqICg8Y29kZT50cnVzdEFuY2hvcnMuaXNFbXB0eSgpID09IHRydWU8L2NvZGU+KQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RQS0lYQnVpbGRlclBhcmFtZXRlcnNTZXRDZXJ0U2VsZWN0b3IwNSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIHVzZSBlbXB0eSBzZXQKKyAgICAgICAgICAgIG5ldyBQS0lYQnVpbGRlclBhcmFtZXRlcnMobmV3IEhhc2hTZXQ8VHJ1c3RBbmNob3I+KCksIG51bGwpOworICAgICAgICAgICAgZmFpbCgiSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPlBLSVhCdWlsZGVyUGFyYW1ldGVycyhLZXlTdG9yZSwgQ2VydFNlbGVjdG9yKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiAtIGlmIHRoZQorICAgICAqIDxjb2RlPmtleXN0b3JlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RQS0lYQnVpbGRlclBhcmFtZXRlcnNLZXlTdG9yZUNlcnRTZWxlY3RvcjAxKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFBLSVhCdWlsZGVyUGFyYW1ldGVycygoS2V5U3RvcmUpIG51bGwsIG5ldyBYNTA5Q2VydFNlbGVjdG9yKCkpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPlBLSVhCdWlsZGVyUGFyYW1ldGVycyhLZXlTdG9yZSwgQ2VydFNlbGVjdG9yKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IDxjb2RlPktleVN0b3JlRXhjZXB0aW9uPC9jb2RlPiAtIGlmIHRoZQorICAgICAqIDxjb2RlPmtleXN0b3JlPC9jb2RlPiBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UEtJWEJ1aWxkZXJQYXJhbWV0ZXJzS2V5U3RvcmVDZXJ0U2VsZWN0b3IwMigpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5U3RvcmUga2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFBLSVhCdWlsZGVyUGFyYW1ldGVycyhrZXlUZXN0LCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIktleVN0b3JlRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKEtleVN0b3JlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMzIGZvciA8Y29kZT5QS0lYQnVpbGRlclBhcmFtZXRlcnMoS2V5U3RvcmUsIENlcnRTZWxlY3Rvcik8L2NvZGU+CisgICAgICogY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiA8Y29kZT5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uPC9jb2RlPiAtIGlmIHRoZQorICAgICAqIDxjb2RlPmtleXN0b3JlPC9jb2RlPiBkb2VzIG5vdCBjb250YWluIGF0IGxlYXN0IG9uZSB0cnVzdGVkIGNlcnRpZmljYXRlCisgICAgICogZW50cnkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UEtJWEJ1aWxkZXJQYXJhbWV0ZXJzS2V5U3RvcmVDZXJ0U2VsZWN0b3IwMygpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5U3RvcmUga2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICBrZXlUZXN0LmxvYWQobnVsbCwgbnVsbCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzKGtleVRlc3QsIG5ldyBYNTA5Q2VydFNlbGVjdG9yKCkpOworICAgICAgICAgICAgZmFpbCgiSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM0IGZvciA8Y29kZT5QS0lYQnVpbGRlclBhcmFtZXRlcnMoS2V5U3RvcmUsIENlcnRTZWxlY3Rvcik8L2NvZGU+CisgICAgICogY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gLQorICAgICAqIGlmIHRoZSA8Y29kZT5rZXlzdG9yZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UEtJWEJ1aWxkZXJQYXJhbWV0ZXJzS2V5U3RvcmVDZXJ0U2VsZWN0b3IwNCgpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5U3RvcmUga2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICBrZXlUZXN0LmxvYWQobnVsbCwgbnVsbCk7CisKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gY2VydEFycmF5ID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNlcnRpZmljYXRlCisgICAgICAgICAgICAgICAgLmdldEJ5dGVzKCkpOworCisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGNlcnRBcnJheTIgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oY2VydGlmaWNhdGUyCisgICAgICAgICAgICAgICAgLmdldEJ5dGVzKCkpOworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0W10gPSBuZXcgWDUwOUNlcnRpZmljYXRlWzJdOworICAgICAgICBjZXJ0WzBdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkpOworICAgICAgICBjZXJ0WzFdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkyKTsKKworICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMSIsIGNlcnRbMF0pOworICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMiIsIGNlcnRbMF0pOworICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMyIsIGNlcnRbMV0pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBQS0lYQnVpbGRlclBhcmFtZXRlcnMgcCA9IG5ldyBQS0lYQnVpbGRlclBhcmFtZXRlcnMoa2V5VGVzdCwKKyAgICAgICAgICAgICAgICAgICAgbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMywgcC5nZXRUcnVzdEFuY2hvcnMoKS5zaXplKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIHAuZ2V0TWF4UGF0aExlbmd0aCgpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRNYXhQYXRoTGVuZ3RoKCk8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldE1heFBhdGhMZW5ndGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5U3RvcmUga2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICBrZXlUZXN0LmxvYWQobnVsbCwgbnVsbCk7CisKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gY2VydEFycmF5ID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNlcnRpZmljYXRlCisgICAgICAgICAgICAgICAgLmdldEJ5dGVzKCkpOworCisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGNlcnRBcnJheTIgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oY2VydGlmaWNhdGUyCisgICAgICAgICAgICAgICAgLmdldEJ5dGVzKCkpOworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0W10gPSBuZXcgWDUwOUNlcnRpZmljYXRlWzJdOworICAgICAgICBjZXJ0WzBdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkpOworICAgICAgICBjZXJ0WzFdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkyKTsKKworICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMSIsIGNlcnRbMF0pOworICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMiIsIGNlcnRbMF0pOworICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMyIsIGNlcnRbMV0pOworCisgICAgICAgIFBLSVhCdWlsZGVyUGFyYW1ldGVycyBwID0gbmV3IFBLSVhCdWlsZGVyUGFyYW1ldGVycyhrZXlUZXN0LAorICAgICAgICAgICAgICAgIG5ldyBYNTA5Q2VydFNlbGVjdG9yKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoNSwgcC5nZXRNYXhQYXRoTGVuZ3RoKCkpOworICAgICAgICBwLnNldE1heFBhdGhMZW5ndGgoMTApOworICAgICAgICBhc3NlcnRFcXVhbHMoMTAsIHAuZ2V0TWF4UGF0aExlbmd0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5zZXRNYXhQYXRoTGVuZ3RoKCk8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFNldE1heFBhdGhMZW5ndGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5U3RvcmUga2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICBrZXlUZXN0LmxvYWQobnVsbCwgbnVsbCk7CisKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gY2VydEFycmF5ID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNlcnRpZmljYXRlCisgICAgICAgICAgICAgICAgLmdldEJ5dGVzKCkpOworCisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGNlcnRBcnJheTIgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oY2VydGlmaWNhdGUyCisgICAgICAgICAgICAgICAgLmdldEJ5dGVzKCkpOworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0W10gPSBuZXcgWDUwOUNlcnRpZmljYXRlWzJdOworICAgICAgICBjZXJ0WzBdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkpOworICAgICAgICBjZXJ0WzFdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkyKTsKKworICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMSIsIGNlcnRbMF0pOworICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMiIsIGNlcnRbMF0pOworICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMyIsIGNlcnRbMV0pOworCisgICAgICAgIFBLSVhCdWlsZGVyUGFyYW1ldGVycyBwID0gbmV3IFBLSVhCdWlsZGVyUGFyYW1ldGVycyhrZXlUZXN0LAorICAgICAgICAgICAgICAgIG5ldyBYNTA5Q2VydFNlbGVjdG9yKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscyg1LCBwLmdldE1heFBhdGhMZW5ndGgoKSk7CisgICAgICAgIHAuc2V0TWF4UGF0aExlbmd0aCgxMCk7CisgICAgICAgIGFzc2VydEVxdWFscygxMCwgcC5nZXRNYXhQYXRoTGVuZ3RoKCkpOworICAgICAgICBwLnNldE1heFBhdGhMZW5ndGgoMCk7CisgICAgICAgIGFzc2VydEVxdWFscygwLCBwLmdldE1heFBhdGhMZW5ndGgoKSk7CisgICAgICAgIHAuc2V0TWF4UGF0aExlbmd0aCgtMSk7CisgICAgICAgIGFzc2VydEVxdWFscygtMSwgcC5nZXRNYXhQYXRoTGVuZ3RoKCkpOworCisgICAgICAgIGludFtdIG1heFBhdGhMZW5ndGggPSB7LTIsIC0xMCwgSW50ZWdlci5NSU5fVkFMVUV9OworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1heFBhdGhMZW5ndGgubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcC5zZXRNYXhQYXRoTGVuZ3RoKG1heFBhdGhMZW5ndGhbaV0pOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gZXhwZWN0ZWQgIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+dG9TdHJpbmcoKTwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0VG9TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5U3RvcmUga2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICBrZXlUZXN0LmxvYWQobnVsbCwgbnVsbCk7CisKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gY2VydEFycmF5ID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNlcnRpZmljYXRlCisgICAgICAgICAgICAgICAgLmdldEJ5dGVzKCkpOworCisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGNlcnRBcnJheTIgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oY2VydGlmaWNhdGUyCisgICAgICAgICAgICAgICAgLmdldEJ5dGVzKCkpOworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0W10gPSBuZXcgWDUwOUNlcnRpZmljYXRlWzJdOworICAgICAgICBjZXJ0WzBdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkpOworICAgICAgICBjZXJ0WzFdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkyKTsKKworICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMSIsIGNlcnRbMF0pOworICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMiIsIGNlcnRbMF0pOworICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImFsaWFzMyIsIGNlcnRbMV0pOworCisgICAgICAgIFBLSVhCdWlsZGVyUGFyYW1ldGVycyBwID0gbmV3IFBLSVhCdWlsZGVyUGFyYW1ldGVycyhrZXlUZXN0LAorICAgICAgICAgICAgICAgIG5ldyBYNTA5Q2VydFNlbGVjdG9yKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHAudG9TdHJpbmcoKSk7CisKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9QS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvUEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOWIxNGIyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvUEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdFRlc3QuamF2YQpAQCAtMCwwICsxLDI1MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5NeUNlcnRQYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuVGVzdFV0aWxzOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aEJ1aWxkZXJSZXN1bHQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LlBLSVhDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LlRydXN0QW5jaG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5JbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbjsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+UEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdDwvY29kZT4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBQS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICAvKioKKyAgICAgKiBDZXJ0IHBhdGggZW5jb2Rpbmcgc3R1YgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSB0ZXN0RW5jb2RpbmcgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgIChieXRlKTEsIChieXRlKTIsIChieXRlKTMsIChieXRlKTQsIChieXRlKTUKKyAgICB9OworCisgICAgLyoqCisgICAgICogUHVibGljS2V5IHN0dWIKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBQdWJsaWNLZXkgdGVzdFB1YmxpY0tleSA9IG5ldyBQdWJsaWNLZXkoKSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTU1Mjk5NTA3MDMzOTQ3NTE2MzhMOworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgIHJldHVybiAiTmV2ZXJNaW5kIjsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgICAgIHJldHVybiAiTmV2ZXJNaW5kIjsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7fTsKKyAgICAgICAgfQorICAgIH07CisKKworICAgIC8vCisgICAgLy8gVGVzdHMKKyAgICAvLworCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+UEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdChDZXJ0UGF0aCwgVHJ1c3RBbmNob3IsCisgICAgICogICBQb2xpY3lOb2RlLCBQdWJsaWNLZXkpPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+UEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdDwvY29kZT4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdDAxKCkKKyAgICAgICAgdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgVHJ1c3RBbmNob3IgdGEgPSBUZXN0VXRpbHMuZ2V0VHJ1c3RBbmNob3IoKTsKKyAgICAgICAgaWYgKHRhID09IG51bGwpIHsKKyAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm90IHBlcmZvcm1lZCAoY291bGQgbm90IGNyZWF0ZSB0ZXN0IFRydXN0QW5jaG9yKSIpOworICAgICAgICB9CisgICAgICAgIENlcnRQYXRoQnVpbGRlclJlc3VsdCByID0KKyAgICAgICAgICAgIG5ldyBQS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0KAorICAgICAgICAgICAgICAgICAgICBuZXcgTXlDZXJ0UGF0aCh0ZXN0RW5jb2RpbmcpLAorICAgICAgICAgICAgICAgICAgICB0YSwKKyAgICAgICAgICAgICAgICAgICAgVGVzdFV0aWxzLmdldFBvbGljeVRyZWUoKSwKKyAgICAgICAgICAgICAgICAgICAgdGVzdFB1YmxpY0tleSk7CisgICAgICAgIGFzc2VydFRydWUociBpbnN0YW5jZW9mIFBLSVhDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPlBLSVhDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQoQ2VydFBhdGgsIFRydXN0QW5jaG9yLAorICAgICAqICAgUG9saWN5Tm9kZSwgUHVibGljS2V5KTwvY29kZT4gY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiBwb2xpY3kgdHJlZSBwYXJhbWV0ZXIgbWF5IGJlIDxjb2RlPm51bGw8L2NvZGU+CisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFBLSVhDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQwMigpCisgICAgICAgIHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIFRydXN0QW5jaG9yIHRhID0gVGVzdFV0aWxzLmdldFRydXN0QW5jaG9yKCk7CisgICAgICAgIGlmICh0YSA9PSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IG5vdCBwZXJmb3JtZWQgKGNvdWxkIG5vdCBjcmVhdGUgdGVzdCBUcnVzdEFuY2hvcikiKTsKKyAgICAgICAgfQorICAgICAgICBDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQgciA9CisgICAgICAgICAgICBuZXcgUEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdCgKKyAgICAgICAgICAgICAgICAgICAgbmV3IE15Q2VydFBhdGgodGVzdEVuY29kaW5nKSwKKyAgICAgICAgICAgICAgICAgICAgdGEsCisgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgICAgIHRlc3RQdWJsaWNLZXkpOworICAgICAgICBhc3NlcnRUcnVlKHIgaW5zdGFuY2VvZiBQS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMzIGZvciA8Y29kZT5QS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0KENlcnRQYXRoLCBUcnVzdEFuY2hvciwKKyAgICAgKiAgIFBvbGljeU5vZGUsIFB1YmxpY0tleSk8L2NvZGU+IGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+CisgICAgICogaWYgY2VydFBhdGggaXMgPGNvZGU+bnVsbDwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdDAzKCkgeworICAgICAgICBUcnVzdEFuY2hvciB0YSA9IFRlc3RVdGlscy5nZXRUcnVzdEFuY2hvcigpOworICAgICAgICBpZiAodGEgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiOiBub3QgcGVyZm9ybWVkIChjb3VsZCBub3QgY3JlYXRlIHRlc3QgVHJ1c3RBbmNob3IpIik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gcGFzcyBudWxsCisgICAgICAgICAgICBuZXcgUEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdCgKKyAgICAgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgdGEsCisgICAgICAgICAgICAgICAgICAgIFRlc3RVdGlscy5nZXRQb2xpY3lUcmVlKCksCisgICAgICAgICAgICAgICAgICAgIHRlc3RQdWJsaWNLZXkpOworICAgICAgICAgICAgZmFpbCgiTlBFIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzQgZm9yIDxjb2RlPlBLSVhDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQoQ2VydFBhdGgsIFRydXN0QW5jaG9yLAorICAgICAqICAgUG9saWN5Tm9kZSwgUHVibGljS2V5KTwvY29kZT4gY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4KKyAgICAgKiBpZiB0cnVzdEFuY2hvciBpcyA8Y29kZT5udWxsPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RQS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0MDQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBwYXNzIG51bGwKKyAgICAgICAgICAgIG5ldyBQS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0KAorICAgICAgICAgICAgICAgICAgICBuZXcgTXlDZXJ0UGF0aCh0ZXN0RW5jb2RpbmcpLAorICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICBUZXN0VXRpbHMuZ2V0UG9saWN5VHJlZSgpLAorICAgICAgICAgICAgICAgICAgICB0ZXN0UHVibGljS2V5KTsKKyAgICAgICAgICAgIGZhaWwoIk5QRSBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM1IGZvciA8Y29kZT5QS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0KENlcnRQYXRoLCBUcnVzdEFuY2hvciwKKyAgICAgKiAgIFBvbGljeU5vZGUsIFB1YmxpY0tleSk8L2NvZGU+IGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+CisgICAgICogaWYgcHVibGljS2V5IGlzIDxjb2RlPm51bGw8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFBLSVhDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQwNSgpIHsKKyAgICAgICAgVHJ1c3RBbmNob3IgdGEgPSBUZXN0VXRpbHMuZ2V0VHJ1c3RBbmNob3IoKTsKKyAgICAgICAgaWYgKHRhID09IG51bGwpIHsKKyAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm90IHBlcmZvcm1lZCAoY291bGQgbm90IGNyZWF0ZSB0ZXN0IFRydXN0QW5jaG9yKSIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIHBhc3MgbnVsbAorICAgICAgICAgICAgbmV3IFBLSVhDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQoCisgICAgICAgICAgICAgICAgICAgIG5ldyBNeUNlcnRQYXRoKHRlc3RFbmNvZGluZyksCisgICAgICAgICAgICAgICAgICAgIHRhLAorICAgICAgICAgICAgICAgICAgICBUZXN0VXRpbHMuZ2V0UG9saWN5VHJlZSgpLAorICAgICAgICAgICAgICAgICAgICBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk5QRSBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF9jbG9uZSgpIHsKKworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTI3ODYuCisgICAgICAgIFRydXN0QW5jaG9yIHRhID0gVGVzdFV0aWxzLmdldFRydXN0QW5jaG9yKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgKyAiOiBub3QgcGVyZm9ybWVkIChjb3VsZCBub3QgY3JlYXRlIHRlc3QgVHJ1c3RBbmNob3IpIiwgdGEpOworCisgICAgICAgIFBLSVhDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQgaW5pdCA9IG5ldyBQS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0KAorICAgICAgICAgICAgICAgIG5ldyBNeUNlcnRQYXRoKHRlc3RFbmNvZGluZyksIHRhLCBUZXN0VXRpbHMuZ2V0UG9saWN5VHJlZSgpLAorICAgICAgICAgICAgICAgIHRlc3RQdWJsaWNLZXkpOworCisgICAgICAgIFBLSVhDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQgY2xvbmUgPSAoUEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdCkgaW5pdAorICAgICAgICAgICAgICAgIC5jbG9uZSgpOworICAgICAgICBhc3NlcnRTYW1lKGluaXQuZ2V0Q2VydFBhdGgoKSwgY2xvbmUuZ2V0Q2VydFBhdGgoKSk7CisgICAgICAgIGFzc2VydFNhbWUoaW5pdC5nZXRQb2xpY3lUcmVlKCksIGNsb25lLmdldFBvbGljeVRyZWUoKSk7CisgICAgICAgIGFzc2VydFNhbWUoaW5pdC5nZXRQdWJsaWNLZXkoKSwgY2xvbmUuZ2V0UHVibGljS2V5KCkpOworICAgICAgICBhc3NlcnRTYW1lKGluaXQuZ2V0VHJ1c3RBbmNob3IoKSwgY2xvbmUuZ2V0VHJ1c3RBbmNob3IoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0Q2VydFBhdGgoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogdGhlIGJ1aWx0IGFuZCB2YWxpZGF0ZWQgPGNvZGU+Q2VydFBhdGg8L2NvZGU+CisgICAgICogKG5ldmVyIDxjb2RlPm51bGw8L2NvZGU+KQorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRDZXJ0UGF0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUcnVzdEFuY2hvciB0YSA9IFRlc3RVdGlscy5nZXRUcnVzdEFuY2hvcigpOworICAgICAgICBpZiAodGEgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiOiBub3QgcGVyZm9ybWVkIChjb3VsZCBub3QgY3JlYXRlIHRlc3QgVHJ1c3RBbmNob3IpIik7CisgICAgICAgIH0KKworICAgICAgICBDZXJ0UGF0aCBjcCA9IG5ldyBNeUNlcnRQYXRoKHRlc3RFbmNvZGluZyk7CisgICAgICAgIENlcnRQYXRoQnVpbGRlclJlc3VsdCByID0KKyAgICAgICAgICAgIG5ldyBQS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0KAorICAgICAgICAgICAgICAgICAgICBjcCwKKyAgICAgICAgICAgICAgICAgICAgdGEsCisgICAgICAgICAgICAgICAgICAgIFRlc3RVdGlscy5nZXRQb2xpY3lUcmVlKCksCisgICAgICAgICAgICAgICAgICAgIHRlc3RQdWJsaWNLZXkpOworCisgICAgICAgIC8vIG11c3QgcmV0dXJuIHRoZSBzYW1lIHJlZmVyZW5jZQorICAgICAgICAvLyBhcyBwYXNzZWQgdG8gdGhlIGNvbnN0cnVjdG9yCisgICAgICAgIGFzc2VydFNhbWUoY3AsIHIuZ2V0Q2VydFBhdGgoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+dG9TdHJpbmcoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogdGhlIHByaW50YWJsZSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG9iamVjdAorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RUb1N0cmluZygpCisgICAgICAgIHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiB7CisgICAgICAgIFRydXN0QW5jaG9yIHRhID0gVGVzdFV0aWxzLmdldFRydXN0QW5jaG9yKCk7CisgICAgICAgIGlmICh0YSA9PSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IG5vdCBwZXJmb3JtZWQgKGNvdWxkIG5vdCBjcmVhdGUgdGVzdCBUcnVzdEFuY2hvcikiKTsKKyAgICAgICAgfQorICAgICAgICBDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQgciA9CisgICAgICAgICAgICBuZXcgUEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdCgKKyAgICAgICAgICAgICAgICAgICAgbmV3IE15Q2VydFBhdGgodGVzdEVuY29kaW5nKSwKKyAgICAgICAgICAgICAgICAgICAgdGEsCisgICAgICAgICAgICAgICAgICAgIFRlc3RVdGlscy5nZXRQb2xpY3lUcmVlKCksCisgICAgICAgICAgICAgICAgICAgIHRlc3RQdWJsaWNLZXkpOworCisgICAgICAgIGFzc2VydE5vdE51bGwoci50b1N0cmluZygpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L1BLSVhDZXJ0UGF0aENoZWNrZXJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9QS0lYQ2VydFBhdGhDaGVja2VyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ0YTJmYTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9QS0lYQ2VydFBhdGhDaGVja2VyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTEwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5QS0lYQ2VydFBhdGhDaGVja2VyOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0Lk15Q2VydGlmaWNhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5UZXN0VXRpbHM7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlBLSVhDZXJ0UGF0aENoZWNrZXI8L2NvZGU+CisgKgorICovCitwdWJsaWMgY2xhc3MgUEtJWENlcnRQYXRoQ2hlY2tlclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvLworICAgIC8vIFRlc3RzCisgICAgLy8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0Q29uc3RydWN0b3IoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgTXlQS0lYQ2VydFBhdGhDaGVja2VyKCk7CisgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdENsb25lKCkgeworICAgICAgICBQS0lYQ2VydFBhdGhDaGVja2VyIHBjMSA9IFRlc3RVdGlscy5nZXRUZXN0Q2VydFBhdGhDaGVja2VyKCk7CisgICAgICAgIFBLSVhDZXJ0UGF0aENoZWNrZXIgcGMyID0gKFBLSVhDZXJ0UGF0aENoZWNrZXIpIHBjMS5jbG9uZSgpOworICAgICAgICBhc3NlcnROb3RTYW1lKCJub3RTYW1lIiwgcGMxLCBwYzIpOworICAgIH0KKworICAgIC8vCisgICAgLy8gdGhlIGZvbGxvd2luZyB0ZXN0cyBqdXN0IGNhbGwgbWV0aG9kcworICAgIC8vIHRoYXQgYXJlIGFic3RyYWN0IGluIDxjb2RlPlBLSVhDZXJ0UGF0aENoZWNrZXI8L2NvZGU+CisgICAgLy8gKFNvIHRoZXkganVzdCBsaWtlIHNpZ25hdHVyZSB0ZXN0cykKKyAgICAvLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RJc0ZvcndhcmRDaGVja2luZ1N1cHBvcnRlZCgpIHsKKyAgICAgICAgUEtJWENlcnRQYXRoQ2hlY2tlciBwYyA9IFRlc3RVdGlscy5nZXRUZXN0Q2VydFBhdGhDaGVja2VyKCk7CisgICAgICAgIHBjLmlzRm9yd2FyZENoZWNraW5nU3VwcG9ydGVkKCk7CisgICAgfQorICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RJbml0KCkKKyAgICAgICAgdGhyb3dzIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHsKKyAgICAgICAgUEtJWENlcnRQYXRoQ2hlY2tlciBwYyA9IFRlc3RVdGlscy5nZXRUZXN0Q2VydFBhdGhDaGVja2VyKCk7CisgICAgICAgIHBjLmluaXQodHJ1ZSk7CisgICAgfQorICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRTdXBwb3J0ZWRFeHRlbnNpb25zKCkgeworICAgICAgICBQS0lYQ2VydFBhdGhDaGVja2VyIHBjID0gVGVzdFV0aWxzLmdldFRlc3RDZXJ0UGF0aENoZWNrZXIoKTsKKyAgICAgICAgcGMuZ2V0U3VwcG9ydGVkRXh0ZW5zaW9ucygpOworICAgIH0KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0Q2hlY2soKSB0aHJvd3MgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24geworICAgICAgICBQS0lYQ2VydFBhdGhDaGVja2VyIHBjID0gVGVzdFV0aWxzLmdldFRlc3RDZXJ0UGF0aENoZWNrZXIoKTsKKyAgICAgICAgcGMuY2hlY2sobmV3IE15Q2VydGlmaWNhdGUoIiIsIG51bGwpLCBuZXcgSGFzaFNldDxTdHJpbmc+KCkpOworICAgIH0KKworICAgIGNsYXNzIE15UEtJWENlcnRQYXRoQ2hlY2tlciBleHRlbmRzIFBLSVhDZXJ0UGF0aENoZWNrZXIgeworCisgICAgICAgIHB1YmxpYyBNeVBLSVhDZXJ0UGF0aENoZWNrZXIoKSB7CisgICAgICAgICAgICBzdXBlcigpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrKENlcnRpZmljYXRlIGNlcnQsCisgICAgICAgICAgICAgICAgQ29sbGVjdGlvbjxTdHJpbmc+IHVucmVzb2x2ZWRDcml0RXh0cykKKyAgICAgICAgdGhyb3dzIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU2V0PFN0cmluZz4gZ2V0U3VwcG9ydGVkRXh0ZW5zaW9ucygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGluaXQoYm9vbGVhbiBmb3J3YXJkKSB0aHJvd3MgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRm9yd2FyZENoZWNraW5nU3VwcG9ydGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L1BLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L1BLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNTc4YjUzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMzMzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5Qb2xpY3lOb2RlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5UcnVzdEFuY2hvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuSW52YWxpZEtleVNwZWNFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0LlRlc3RVdGlsczsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+UEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0PC9jb2RlPgorICoKKyAqLworcHVibGljIGNsYXNzIFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgICAgLyoqCisgICAgICogUHVibGljS2V5IHN0dWIKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBQdWJsaWNLZXkgdGVzdFB1YmxpY0tleSA9IG5ldyBQdWJsaWNLZXkoKSB7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03Mzc0NTQ1MjM3Mzk0ODkxOTJMOworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgIHJldHVybiAiTmV2ZXJNaW5kIjsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgICAgIHJldHVybiAiTmV2ZXJNaW5kIjsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7fTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICAvLworICAgIC8vIFRlc3RzCisgICAgLy8KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPlBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdChUcnVzdEFuY2hvciwKKyAgICAgKiBQb2xpY3lOb2RlLCBQdWJsaWNLZXkpPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IGNyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YKKyAgICAgKiA8Y29kZT5QS0lYQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHQ8L2NvZGU+CisgICAgICoKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0MDEoKQorICAgICAgICB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24sCisgICAgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBUcnVzdEFuY2hvciB0YSA9IFRlc3RVdGlscy5nZXRUcnVzdEFuY2hvcigpOworICAgICAgICBpZiAodGEgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiOiBub3QgcGVyZm9ybWVkIChjb3VsZCBub3QgY3JlYXRlIHRlc3QgVHJ1c3RBbmNob3IpIik7CisgICAgICAgIH0KKyAgICAgICAgbmV3IFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCgKKyAgICAgICAgICAgICAgICB0YSwKKyAgICAgICAgICAgICAgICBUZXN0VXRpbHMuZ2V0UG9saWN5VHJlZSgpLAorICAgICAgICAgICAgICAgIHRlc3RQdWJsaWNLZXkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPlBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdChUcnVzdEFuY2hvciwKKyAgICAgKiBQb2xpY3lOb2RlLCBQdWJsaWNLZXkpPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpZgorICAgICAqIDxjb2RlPlRydXN0QW5jaG9yPC9jb2RlPiBwYXJhbWV0ZXIgaXMgPGNvZGU+bnVsbDwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0MDIoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBwYXNzIG51bGwKKyAgICAgICAgICAgIG5ldyBQS0lYQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHQoCisgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgICAgIFRlc3RVdGlscy5nZXRQb2xpY3lUcmVlKCksCisgICAgICAgICAgICAgICAgICAgIHRlc3RQdWJsaWNLZXkpOworICAgICAgICAgICAgZmFpbCgiTlBFIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzMgZm9yIDxjb2RlPlBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdChUcnVzdEFuY2hvciwKKyAgICAgKiBQb2xpY3lOb2RlLCBQdWJsaWNLZXkpPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpZgorICAgICAqIDxjb2RlPlB1YmxpY0tleTwvY29kZT4gcGFyYW1ldGVyIGlzIDxjb2RlPm51bGw8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdDAzKCkgeworICAgICAgICBUcnVzdEFuY2hvciB0YSA9IFRlc3RVdGlscy5nZXRUcnVzdEFuY2hvcigpOworICAgICAgICBpZiAodGEgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiOiBub3QgcGVyZm9ybWVkIChjb3VsZCBub3QgY3JlYXRlIHRlc3QgVHJ1c3RBbmNob3IpIik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIHBhc3MgbnVsbAorICAgICAgICAgICAgbmV3IFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCgKKyAgICAgICAgICAgICAgICAgICAgdGEsCisgICAgICAgICAgICAgICAgICAgIFRlc3RVdGlscy5nZXRQb2xpY3lUcmVlKCksCisgICAgICAgICAgICAgICAgICAgIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTlBFIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzQgZm9yIDxjb2RlPlBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdChUcnVzdEFuY2hvciwKKyAgICAgKiBQb2xpY3lOb2RlLCBQdWJsaWNLZXkpPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IDxjb2RlPlBvbGljeU5vZGU8L2NvZGU+Y2FuIGJlIDxjb2RlPm51bGw8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdDA0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRydXN0QW5jaG9yIHRhID0gVGVzdFV0aWxzLmdldFRydXN0QW5jaG9yKCk7CisgICAgICAgIGlmICh0YSA9PSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IG5vdCBwZXJmb3JtZWQgKGNvdWxkIG5vdCBjcmVhdGUgdGVzdCBUcnVzdEFuY2hvcikiKTsKKyAgICAgICAgfQorCisgICAgICAgIG5ldyBQS0lYQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHQoCisgICAgICAgICAgICAgICAgdGEsCisgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICB0ZXN0UHVibGljS2V5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRUcnVzdEFuY2hvcigpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIDxjb2RlPlRydXN0QW5jaG9yPC9jb2RlPiAobmV2ZXIgPGNvZGU+bnVsbDwvY29kZT4pCisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFRydXN0QW5jaG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRydXN0QW5jaG9yIHRhID0gVGVzdFV0aWxzLmdldFRydXN0QW5jaG9yKCk7CisgICAgICAgIGlmICh0YSA9PSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IG5vdCBwZXJmb3JtZWQgKGNvdWxkIG5vdCBjcmVhdGUgdGVzdCBUcnVzdEFuY2hvcikiKTsKKyAgICAgICAgfQorCisgICAgICAgIFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCB2ciA9CisgICAgICAgICAgICBuZXcgUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0KAorICAgICAgICAgICAgICAgICAgICB0YSwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgdGVzdFB1YmxpY0tleSk7CisKKyAgICAgICAgLy8gbXVzdCByZXR1cm4gdGhlIHNhbWUgcmVmZXJlbmNlIHBhc3NlZAorICAgICAgICAvLyBhcyBhIHBhcmFtZXRlciB0byB0aGUgY29uc3RydWN0b3IKKyAgICAgICAgYXNzZXJ0U2FtZSh0YSwgdnIuZ2V0VHJ1c3RBbmNob3IoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UHVibGljS2V5KCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgdGhlIHN1YmplY3QncyBwdWJsaWMga2V5IChuZXZlciA8Y29kZT5udWxsPC9jb2RlPikKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0UHVibGljS2V5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRydXN0QW5jaG9yIHRhID0gVGVzdFV0aWxzLmdldFRydXN0QW5jaG9yKCk7CisgICAgICAgIGlmICh0YSA9PSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IG5vdCBwZXJmb3JtZWQgKGNvdWxkIG5vdCBjcmVhdGUgdGVzdCBUcnVzdEFuY2hvcikiKTsKKyAgICAgICAgfQorCisgICAgICAgIFB1YmxpY0tleSBwayA9IHRlc3RQdWJsaWNLZXk7CisgICAgICAgIFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCB2ciA9CisgICAgICAgICAgICBuZXcgUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0KAorICAgICAgICAgICAgICAgICAgICB0YSwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgcGspOworCisgICAgICAgIC8vIG11c3QgcmV0dXJuIHRoZSBzYW1lIHJlZmVyZW5jZSBwYXNzZWQKKyAgICAgICAgLy8gYXMgYSBwYXJhbWV0ZXIgdG8gdGhlIGNvbnN0cnVjdG9yCisgICAgICAgIGFzc2VydFNhbWUocGssIHZyLmdldFB1YmxpY0tleSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRQb2xpY3lUcmVlKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgdmFsaWQKKyAgICAgKiBwb2xpY3kgdHJlZSBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBhcmUKKyAgICAgKiBubyB2YWxpZCBwb2xpY2llcworICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRQb2xpY3lUcmVlMDEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVHJ1c3RBbmNob3IgdGEgPSBUZXN0VXRpbHMuZ2V0VHJ1c3RBbmNob3IoKTsKKyAgICAgICAgaWYgKHRhID09IG51bGwpIHsKKyAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm90IHBlcmZvcm1lZCAoY291bGQgbm90IGNyZWF0ZSB0ZXN0IFRydXN0QW5jaG9yKSIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gdmFsaWQgcG9saWN5IHRyZWUgY2FzZTsKKyAgICAgICAgUG9saWN5Tm9kZSBwbiA9IFRlc3RVdGlscy5nZXRQb2xpY3lUcmVlKCk7CisgICAgICAgIFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCB2ciA9CisgICAgICAgICAgICBuZXcgUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0KAorICAgICAgICAgICAgICAgICAgICB0YSwKKyAgICAgICAgICAgICAgICAgICAgcG4sCisgICAgICAgICAgICAgICAgICAgIHRlc3RQdWJsaWNLZXkpOworCisgICAgICAgIC8vIG11c3QgcmV0dXJuIHRoZSBzYW1lIHJlZmVyZW5jZSBwYXNzZWQKKyAgICAgICAgLy8gYXMgYSBwYXJhbWV0ZXIgdG8gdGhlIGNvbnN0cnVjdG9yCisgICAgICAgIGFzc2VydFNhbWUocG4sIHZyLmdldFBvbGljeVRyZWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UG9saWN5VHJlZSgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHRoZSByb290IG5vZGUgb2YgdGhlIHZhbGlkCisgICAgICogcG9saWN5IHRyZWUgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgYXJlCisgICAgICogbm8gdmFsaWQgcG9saWNpZXMKKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0UG9saWN5VHJlZTAyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRydXN0QW5jaG9yIHRhID0gVGVzdFV0aWxzLmdldFRydXN0QW5jaG9yKCk7CisgICAgICAgIGlmICh0YSA9PSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IG5vdCBwZXJmb3JtZWQgKGNvdWxkIG5vdCBjcmVhdGUgdGVzdCBUcnVzdEFuY2hvcikiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIG5vIHZhbGlkIHBvbGljeSB0cmVlIGNhc2UgKG51bGwpCisgICAgICAgIFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCB2ciA9CisgICAgICAgICAgICBuZXcgUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0KAorICAgICAgICAgICAgICAgICAgICB0YSwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgdGVzdFB1YmxpY0tleSk7CisKKyAgICAgICAgLy8gbXVzdCByZXR1cm4gdGhlIHNhbWUgcmVmZXJlbmNlIHBhc3NlZAorICAgICAgICAvLyBhcyBhIHBhcmFtZXRlciB0byB0aGUgY29uc3RydWN0b3IKKyAgICAgICAgYXNzZXJ0TnVsbCh2ci5nZXRQb2xpY3lUcmVlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmNsb25lKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgYSBjb3B5IG9mIHRoaXMgb2JqZWN0CisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdENsb25lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRydXN0QW5jaG9yIHRhID0gVGVzdFV0aWxzLmdldFRydXN0QW5jaG9yKCk7CisgICAgICAgIGlmICh0YSA9PSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IG5vdCBwZXJmb3JtZWQgKGNvdWxkIG5vdCBjcmVhdGUgdGVzdCBUcnVzdEFuY2hvcikiKTsKKyAgICAgICAgfQorCisgICAgICAgIFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCB2cjEgPQorICAgICAgICAgICAgbmV3IFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCgKKyAgICAgICAgICAgICAgICAgICAgdGEsCisgICAgICAgICAgICAgICAgICAgIFRlc3RVdGlscy5nZXRQb2xpY3lUcmVlKCksCisgICAgICAgICAgICAgICAgICAgIHRlc3RQdWJsaWNLZXkpOworCisgICAgICAgIFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCB2cjIgPQorICAgICAgICAgICAgKFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCkgdnIxLmNsb25lKCk7CisKKyAgICAgICAgLy8gY2hlY2sgdGhhdCBtZXRob2QgbWFrZXMgc2hhbGxvdyBjb3B5CisgICAgICAgIGFzc2VydE5vdFNhbWUoIm5vdFNhbWUiLCB2cjEsIHZyMik7CisgICAgICAgIGFzc2VydFNhbWUoInRydXN0QW5jb3IiLCB2cjEuZ2V0VHJ1c3RBbmNob3IoKSwgdnIyLmdldFRydXN0QW5jaG9yKCkpOworICAgICAgICBhc3NlcnRTYW1lKCJwb2xpY3lUcmVlIiwgdnIxLmdldFBvbGljeVRyZWUoKSwgdnIyLmdldFBvbGljeVRyZWUoKSk7CisgICAgICAgIGFzc2VydFNhbWUoInB1YmxpY0tleSIsIHZyMS5nZXRQdWJsaWNLZXkoKSwgdnIyLmdldFB1YmxpY0tleSgpKTsKKworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTI3ODYuCisgICAgICAgIGJ5dGVbXSBlbmNvZGluZyA9IHsgMHgwMSB9OworICAgICAgICBNeVBLSVhDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQgbXkgPSBuZXcgTXlQS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0KHRhLAorICAgICAgICAgICAgICAgIFRlc3RVdGlscy5nZXRQb2xpY3lUcmVlKCksIHRlc3RQdWJsaWNLZXksIGVuY29kaW5nKTsKKyAgICAgICAgTXlQS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0IG15Q2xvbmUgPSAoTXlQS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0KSBteQorICAgICAgICAgICAgICAgIC5jbG9uZSgpOworICAgICAgICBhc3NlcnRTYW1lKG15LmdldFBvbGljeVRyZWUoKSwgbXlDbG9uZS5nZXRQb2xpY3lUcmVlKCkpOworICAgICAgICBhc3NlcnRTYW1lKG15LmdldFB1YmxpY0tleSgpLCBteUNsb25lLmdldFB1YmxpY0tleSgpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShteS5nZXRUcnVzdEFuY2hvcigpLCBteUNsb25lLmdldFRydXN0QW5jaG9yKCkpOworICAgICAgICBhc3NlcnRTYW1lKG15LmVuYywgbXlDbG9uZS5lbmMpOworICAgIH0KKworICAgIGNsYXNzIE15UEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdCBleHRlbmRzIFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCB7CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBlbmM7IC8vIGJ5dGUgYXJyYXkgaXMgY2xvbmVhYmxlCisKKyAgICAgICAgcHVibGljIE15UEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdChUcnVzdEFuY2hvciB0cnVzdEFuY2hvciwKKyAgICAgICAgICAgICAgICBQb2xpY3lOb2RlIHBvbGljeVRyZWUsIFB1YmxpY0tleSBzdWJqZWN0UHVibGljS2V5LCBieXRlW10gZW5jKSB7CisgICAgICAgICAgICBzdXBlcih0cnVzdEFuY2hvciwgcG9saWN5VHJlZSwgc3ViamVjdFB1YmxpY0tleSk7CisKKyAgICAgICAgICAgIHRoaXMuZW5jID0gZW5jOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+dG9TdHJpbmcoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogUmV0dXJucyBhIGZvcm1hdHRlZCBzdHJpbmcgZGVzY3JpYmluZyB0aGlzIG9iamVjdAorICAgICAqIEB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RUb1N0cmluZzAxKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRydXN0QW5jaG9yIHRhID0gVGVzdFV0aWxzLmdldFRydXN0QW5jaG9yKCk7CisgICAgICAgIGlmICh0YSA9PSBudWxsKSB7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICI6IG5vdCBwZXJmb3JtZWQgKGNvdWxkIG5vdCBjcmVhdGUgdGVzdCBUcnVzdEFuY2hvcikiKTsKKyAgICAgICAgfQorCisgICAgICAgIFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCB2ciA9CisgICAgICAgICAgICBuZXcgUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0KAorICAgICAgICAgICAgICAgICAgICB0YSwKKyAgICAgICAgICAgICAgICAgICAgVGVzdFV0aWxzLmdldFBvbGljeVRyZWUoKSwKKyAgICAgICAgICAgICAgICAgICAgdGVzdFB1YmxpY0tleSk7CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh2ci50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT50b1N0cmluZygpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiBSZXR1cm5zIGEgZm9ybWF0dGVkIHN0cmluZyBkZXNjcmliaW5nIHRoaXMgb2JqZWN0CisgICAgICogQHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFRvU3RyaW5nMDIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgVHJ1c3RBbmNob3IgdGEgPSBUZXN0VXRpbHMuZ2V0VHJ1c3RBbmNob3IoKTsKKyAgICAgICAgaWYgKHRhID09IG51bGwpIHsKKyAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIjogbm90IHBlcmZvcm1lZCAoY291bGQgbm90IGNyZWF0ZSB0ZXN0IFRydXN0QW5jaG9yKSIpOworICAgICAgICB9CisKKyAgICAgICAgUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0IHZyID0KKyAgICAgICAgICAgIG5ldyBQS0lYQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHQoCisgICAgICAgICAgICAgICAgICAgIHRhLAorICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICB0ZXN0UHVibGljS2V5KTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKHZyLnRvU3RyaW5nKCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvUG9saWN5UXVhbGlmaWVySW5mb1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L1BvbGljeVF1YWxpZmllckluZm9UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTg5YzA2MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L1BvbGljeVF1YWxpZmllckluZm9UZXN0LmphdmEKQEAgLTAsMCArMSwzMTYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5Qb2xpY3lRdWFsaWZpZXJJbmZvOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogUG9saWN5UXVhbGlmaWVySW5mbyB0ZXN0CisgKgorICovCitwdWJsaWMgY2xhc3MgUG9saWN5UXVhbGlmaWVySW5mb1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPlBvbGljeVF1YWxpZmllckluZm88L2NvZGU+IGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIDxjb2RlPklPRXhjZXB0aW9uPC9jb2RlPiBpZiBieXRlIGFycmF5CisgICAgICogcGFyYW1ldGVyIGRvZXMgbm90IHJlcHJlc2VudCBhIHZhbGlkIGFuZCBwYXJzYWJsZSBwb2xpY3kKKyAgICAgKiBxdWFsaWZpZXIgaW5mbworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RfQ3RvcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBwYXNzIG51bGwKKyAgICAgICAgICAgIG5ldyBQb2xpY3lRdWFsaWZpZXJJbmZvKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIHBhc3MgZW1wdHkgYXJyYXkKKyAgICAgICAgICAgIG5ldyBQb2xpY3lRdWFsaWZpZXJJbmZvKG5ldyBieXRlWzBdKTsKKyAgICAgICAgICAgIGZhaWwoIklPRSBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBwYXNzIGludmFsaWQgYXJyYXkKKyAgICAgICAgICAgIG5ldyBQb2xpY3lRdWFsaWZpZXJJbmZvKAorICAgICAgICAgICAgICAgICAgICBuZXcgYnl0ZVtdIHsoYnl0ZSkweDA2LCAoYnl0ZSkweDAzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKTB4ODEsIChieXRlKTB4MzQsIChieXRlKTB4MDN9KTsKKyAgICAgICAgICAgIGZhaWwoIklPRSBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5Qb2xpY3lRdWFsaWZpZXJJbmZvPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IHRocm93cyA8Y29kZT5JT0V4Y2VwdGlvbjwvY29kZT4gaWYgYnl0ZSBhcnJheQorICAgICAqIHBhcmFtZXRlciBkb2VzIG5vdCByZXByZXNlbnQgYSB2YWxpZCBhbmQgcGFyc2FibGUgcG9saWN5CisgICAgICogcXVhbGlmaWVyIGluZm8KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UG9saWN5UXVhbGlmaWVySW5mbzAyKCkgeworICAgICAgICAvLyBnZXQgdmFsaWQgZW5jb2RpbmcKKyAgICAgICAgYnl0ZVtdIGVuY29kaW5nID0gZ2V0RGVyRW5jb2RpbmcoKTsKKyAgICAgICAgLy8gY29ycnVwdCByb290IHNlcSBsZW5ndGgKKyAgICAgICAgZW5jb2RpbmdbMV0gPSAoYnl0ZSkweDI3OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBwYXNzIGludmFsaWQgYXJyYXkKKyAgICAgICAgICAgIG5ldyBQb2xpY3lRdWFsaWZpZXJJbmZvKGVuY29kaW5nKTsKKyAgICAgICAgICAgIGZhaWwoIklPRSBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKworCisgICAgICAgIC8vIGdldCB2YWxpZCBlbmNvZGluZworICAgICAgICBlbmNvZGluZyA9IGdldERlckVuY29kaW5nKCk7CisgICAgICAgIC8vIGNvcnJ1cHQgcG9saWN5IHF1YWxpZmllciBJRDoKKyAgICAgICAgLy8gIC0gY2hhbmdlIE9JRCB0byB0aGUgUmVsYXRpdmUgT0lECisgICAgICAgIGVuY29kaW5nWzJdID0gKGJ5dGUpMTM7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBwYXNzIGludmFsaWQgYXJyYXkKKyAgICAgICAgICAgIG5ldyBQb2xpY3lRdWFsaWZpZXJJbmZvKGVuY29kaW5nKTsKKyAgICAgICAgICAgIGZhaWwoIklPRSBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMzIGZvciA8Y29kZT5Qb2xpY3lRdWFsaWZpZXJJbmZvPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+UG9saWN5UXVhbGlmaWVySW5mbzwvY29kZT4KKyAgICAgKiBmcm9tIHRoZSBlbmNvZGVkIGJ5dGVzCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFBvbGljeVF1YWxpZmllckluZm8wMygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIGdldCB2YWxpZCBlbmNvZGluZworICAgICAgICBieXRlW10gZW5jb2RpbmcgPSBnZXREZXJFbmNvZGluZygpOworICAgICAgICAvLyBwYXNzIHZhbGlkIGFycmF5CisgICAgICAgIG5ldyBQb2xpY3lRdWFsaWZpZXJJbmZvKGVuY29kaW5nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM0IGZvciA8Y29kZT5Qb2xpY3lRdWFsaWZpZXJJbmZvPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IFRoZSBlbmNvZGVkIGJ5dGUgYXJyYXkgaXMgY29waWVkIG9uIGNvbnN0cnVjdGlvbgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RQb2xpY3lRdWFsaWZpZXJJbmZvMDQoKSB0aHJvd3MgSU9FeGNlcHRpb24gIHsKKyAgICAgICAgLy8gZ2V0IHZhbGlkIGVuY29kaW5nCisgICAgICAgIGJ5dGVbXSBlbmNvZGluZyA9IGdldERlckVuY29kaW5nKCk7CisgICAgICAgIGJ5dGVbXSBlbmNvZGluZ0NvcHkgPSBlbmNvZGluZy5jbG9uZSgpOworICAgICAgICAvLyBwYXNzIHZhbGlkIGFycmF5CisgICAgICAgIFBvbGljeVF1YWxpZmllckluZm8gaSA9IG5ldyBQb2xpY3lRdWFsaWZpZXJJbmZvKGVuY29kaW5nQ29weSk7CisgICAgICAgIC8vIGdldCBlbmNvZGluZworICAgICAgICBieXRlW10gZW5jb2RpbmdSZXQgPSBpLmdldEVuY29kZWQoKTsKKyAgICAgICAgLy8gY2hlY2sgcmV0dXJuZWQgYXJyYXkKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGVuY29kaW5nLCBlbmNvZGluZ1JldCkpOworICAgICAgICAvLyBtb2RpZnkgaW5wdXQKKyAgICAgICAgZW5jb2RpbmdDb3B5WzBdID0gKGJ5dGUpMDsKKyAgICAgICAgLy8gZ2V0IGVuY29kaW5nIGFnYWluCisgICAgICAgIGJ5dGVbXSBlbmNvZGluZ1JldDEgPSBpLmdldEVuY29kZWQoKTsKKyAgICAgICAgLy8gY2hlY2sgdGhhdCBhYm92ZSBtb2RpZmljYXRpb24gZGlkIG5vdCBjaGFuZ2UKKyAgICAgICAgLy8gaW50ZXJuYWwgc3RhdGUgb2YgdGhlIFBvbGljeVF1YWxpZmllckluZm8gaW5zdGFuY2UKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGVuY29kaW5nLCBlbmNvZGluZ1JldDEpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5nZXRFbmNvZGVkKCk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogUmV0dXJucyB0aGUgQVNOLjEgREVSIGVuY29kZWQgZm9ybSBvZgorICAgICAqIHRoaXMgPGNvZGU+UG9saWN5UXVhbGlmaWVySW5mbzwvY29kZT4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0RW5jb2RlZDAxKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gZ2V0IHZhbGlkIGVuY29kaW5nCisgICAgICAgIGJ5dGVbXSBlbmNvZGluZyA9IGdldERlckVuY29kaW5nKCk7CisgICAgICAgIC8vIHBhc3MgdmFsaWQgYXJyYXkKKyAgICAgICAgUG9saWN5UXVhbGlmaWVySW5mbyBpID0gbmV3IFBvbGljeVF1YWxpZmllckluZm8oZW5jb2RpbmcpOworICAgICAgICAvLyBnZXQgZW5jb2RpbmcKKyAgICAgICAgYnl0ZVtdIGVuY29kaW5nUmV0ID0gaS5nZXRFbmNvZGVkKCk7CisgICAgICAgIC8vIGNoZWNrIHJldHVybmVkIGFycmF5CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhlbmNvZGluZywgZW5jb2RpbmdSZXQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5nZXRFbmNvZGVkKCk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogYSBjb3B5IGlzIHJldHVybmVkIGVhY2ggdGltZQorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRFbmNvZGVkMDIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBnZXQgdmFsaWQgZW5jb2RpbmcKKyAgICAgICAgYnl0ZVtdIGVuY29kaW5nID0gZ2V0RGVyRW5jb2RpbmcoKTsKKyAgICAgICAgYnl0ZVtdIGVuY29kaW5nQ29weSA9IGVuY29kaW5nLmNsb25lKCk7CisgICAgICAgIC8vIHBhc3MgdmFsaWQgYXJyYXkKKyAgICAgICAgUG9saWN5UXVhbGlmaWVySW5mbyBpID0gbmV3IFBvbGljeVF1YWxpZmllckluZm8oZW5jb2RpbmdDb3B5KTsKKyAgICAgICAgLy8gZ2V0IGVuY29kaW5nCisgICAgICAgIGJ5dGVbXSBlbmNvZGluZ1JldCA9IGkuZ2V0RW5jb2RlZCgpOworICAgICAgICAvLyBtb2RpZnkgcmV0dXJuZWQgYXJyYXkKKyAgICAgICAgZW5jb2RpbmdSZXRbMF0gPSAoYnl0ZSkwOworICAgICAgICAvLyBnZXQgZW5jb2RpbmcgYWdhaW4KKyAgICAgICAgYnl0ZVtdIGVuY29kaW5nUmV0MSA9IGkuZ2V0RW5jb2RlZCgpOworICAgICAgICAvLyBjaGVjayB0aGF0IGFib3ZlIG1vZGlmaWNhdGlvbiBkaWQgbm90IGNoYW5nZQorICAgICAgICAvLyBpbnRlcm5hbCBzdGF0ZSBvZiB0aGUgUG9saWN5UXVhbGlmaWVySW5mbyBpbnN0YW5jZQorICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoZW5jb2RpbmcsIGVuY29kaW5nUmV0MSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPmdldFBvbGljeVF1YWxpZmllcigpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IFJldHVybnMgdGhlIEFTTi4xIERFUiBlbmNvZGVkIGZvcm0gb2YKKyAgICAgKiB0aGlzIDxjb2RlPlBvbGljeVF1YWxpZmllckluZm88L2NvZGU+CisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFBvbGljeVF1YWxpZmllcjAxKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gZ2V0IHZhbGlkIGVuY29kaW5nCisgICAgICAgIGJ5dGVbXSBlbmNvZGluZyA9IGdldERlckVuY29kaW5nKCk7CisgICAgICAgIC8vIGdldCBwb2xpY3kgcXVhbGlmaWVyIGVuY29kaW5nCisgICAgICAgIGJ5dGVbXSBwcUVuY29kaW5nID0gbmV3IGJ5dGVbMjhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVuY29kaW5nLCAxMiwgcHFFbmNvZGluZywgMCwgcHFFbmNvZGluZy5sZW5ndGgpOworICAgICAgICAvLyBwYXNzIHZhbGlkIGFycmF5CisgICAgICAgIFBvbGljeVF1YWxpZmllckluZm8gaSA9IG5ldyBQb2xpY3lRdWFsaWZpZXJJbmZvKGVuY29kaW5nKTsKKyAgICAgICAgLy8gZ2V0IGVuY29kaW5nCisgICAgICAgIGJ5dGVbXSBwcUVuY29kaW5nUmV0ID0gaS5nZXRQb2xpY3lRdWFsaWZpZXIoKTsKKyAgICAgICAgLy8gY2hlY2sgcmV0dXJuZWQgYXJyYXkKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKHBxRW5jb2RpbmcsIHBxRW5jb2RpbmdSZXQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5nZXRQb2xpY3lRdWFsaWZpZXIoKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiBhIGNvcHkgaXMgcmV0dXJuZWQgZWFjaCB0aW1lCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFBvbGljeVF1YWxpZmllcjAyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gZ2V0IHZhbGlkIGVuY29kaW5nCisgICAgICAgIGJ5dGVbXSBlbmNvZGluZyA9IGdldERlckVuY29kaW5nKCk7CisgICAgICAgIC8vIGdldCBwb2xpY3kgcXVhbGlmaWVyIGVuY29kaW5nCisgICAgICAgIGJ5dGVbXSBwcUVuY29kaW5nID0gbmV3IGJ5dGVbMjhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVuY29kaW5nLCAxMiwgcHFFbmNvZGluZywgMCwgcHFFbmNvZGluZy5sZW5ndGgpOworICAgICAgICAvLyBwYXNzIHZhbGlkIGFycmF5CisgICAgICAgIFBvbGljeVF1YWxpZmllckluZm8gaSA9IG5ldyBQb2xpY3lRdWFsaWZpZXJJbmZvKGVuY29kaW5nKTsKKyAgICAgICAgLy8gZ2V0IGVuY29kaW5nCisgICAgICAgIGJ5dGVbXSBwcUVuY29kaW5nUmV0ID0gaS5nZXRQb2xpY3lRdWFsaWZpZXIoKTsKKyAgICAgICAgLy8gbW9kaWZ5IHJldHVybmVkIGFycmF5CisgICAgICAgIHBxRW5jb2RpbmdSZXRbMF0gPSAoYnl0ZSkwOworICAgICAgICAvLyBnZXQgZW5jb2RpbmcgYWdhaW4KKyAgICAgICAgYnl0ZVtdIHBxRW5jb2RpbmdSZXQxID0gaS5nZXRQb2xpY3lRdWFsaWZpZXIoKTsKKyAgICAgICAgLy8KKyAgICAgICAgYXNzZXJ0Tm90U2FtZShwcUVuY29kaW5nUmV0LCBwcUVuY29kaW5nUmV0MSk7CisgICAgICAgIC8vIGNoZWNrIHRoYXQgYWJvdmUgbW9kaWZpY2F0aW9uIGRpZCBub3QgY2hhbmdlCisgICAgICAgIC8vIGludGVybmFsIHN0YXRlIG9mIHRoZSBQb2xpY3lRdWFsaWZpZXJJbmZvIGluc3RhbmNlCisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhwcUVuY29kaW5nLCBwcUVuY29kaW5nUmV0MSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldFBvbGljeVF1YWxpZmllcklkKCk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogUmV0dXJucyB0aGUgPGNvZGU+cG9saWN5UXVhbGlmaWVySWQ8L2NvZGU+CisgICAgICogZmllbGQgb2YgdGhpcyA8Y29kZT5Qb2xpY3lRdWFsaWZpZXJJbmZvPC9jb2RlPi4KKyAgICAgKiBUaGUgPGNvZGU+cG9saWN5UXVhbGlmaWVySWQ8L2NvZGU+IGlzIGFuIE9iamVjdCBJZGVudGlmaWVyIChPSUQpCisgICAgICogcmVwcmVzZW50ZWQgYnkgYSBzZXQgb2Ygbm9ubmVnYXRpdmUgaW50ZWdlcnMgc2VwYXJhdGVkIGJ5IHBlcmlvZHMKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0UG9saWN5UXVhbGlmaWVySWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBnZXQgdmFsaWQgZW5jb2RpbmcKKyAgICAgICAgYnl0ZVtdIGVuY29kaW5nID0gZ2V0RGVyRW5jb2RpbmcoKTsKKyAgICAgICAgLy8gcGFzcyB2YWxpZCBhcnJheQorICAgICAgICBQb2xpY3lRdWFsaWZpZXJJbmZvIGkgPSBuZXcgUG9saWN5UXVhbGlmaWVySW5mbyhlbmNvZGluZyk7CisgICAgICAgIC8vIGdldCBPSUQgYXMgU3RyaW5nIGFuZCBjaGVjayBpdAorICAgICAgICBhc3NlcnRFcXVhbHMoIjEuMy42LjEuNS41LjcuMi4xIiwgaS5nZXRQb2xpY3lRdWFsaWZpZXJJZCgpKTsKKworICAgICAgICAvLyBnZXQgdmFsaWQgZW5jb2RpbmcKKyAgICAgICAgZW5jb2RpbmcgPSBnZXREZXJFbmNvZGluZygpOworICAgICAgICAvLyBjaGFuZ2UgT0lEIHRvIDEuMy45ODQzNy44MjgxOC4xCisgICAgICAgIGVuY29kaW5nWzVdID0gKGJ5dGUpMHg4NjsKKyAgICAgICAgZW5jb2RpbmdbNl0gPSAoYnl0ZSkweDgxOworICAgICAgICBlbmNvZGluZ1s4XSA9IChieXRlKTB4ODU7CisgICAgICAgIGVuY29kaW5nWzldID0gKGJ5dGUpMHg4NzsKKyAgICAgICAgaSA9IG5ldyBQb2xpY3lRdWFsaWZpZXJJbmZvKGVuY29kaW5nKTsKKyAgICAgICAgLy8gZ2V0IE9JRCBhcyBTdHJpbmcgYW5kIGNoZWNrIGl0CisgICAgICAgIGFzc2VydEVxdWFscygiMS4zLjk4NDM3LjgyODE4LjEiLCBpLmdldFBvbGljeVF1YWxpZmllcklkKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPnRvU3RyaW5nKCk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBkZXNjcmlwdGlvbiBvZiB0aGUgY29udGVudHMgb2YgdGhpcworICAgICAqIDxjb2RlPlBvbGljeVF1YWxpZmllckluZm88L2NvZGU+IGFzIHByaW50YWJsZSA8Y29kZT5TdHJpbmc8L2NvZGU+CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RUb1N0cmluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIGdldCB2YWxpZCBlbmNvZGluZworICAgICAgICBieXRlW10gZW5jb2RpbmcgPSBnZXREZXJFbmNvZGluZygpOworICAgICAgICAvLyBwYXNzIHZhbGlkIGFycmF5CisgICAgICAgIFBvbGljeVF1YWxpZmllckluZm8gaSA9IG5ldyBQb2xpY3lRdWFsaWZpZXJJbmZvKGVuY29kaW5nKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKGkudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLy8KKyAgICAvLyBQcml2YXRlIHN0dWZmCisgICAgLy8KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdmFsaWQgREVSIGVuY29kaW5nIGZvciB0aGUgZm9sbG93aW5nIEFTTi4xIGRlZmluaXRpb24KKyAgICAgKiAoYXMgc3BlY2lmaWVkIGluIFJGQyAzMjgwIC0KKyAgICAgKiAgSW50ZXJuZXQgWC41MDkgUHVibGljIEtleSBJbmZyYXN0cnVjdHVyZS4KKyAgICAgKiAgQ2VydGlmaWNhdGUgYW5kIENlcnRpZmljYXRlIFJldm9jYXRpb24gTGlzdCAoQ1JMKSBQcm9maWxlLgorICAgICAqICBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCk6CisgICAgICoKKyAgICAgKiAgIFBvbGljeVF1YWxpZmllckluZm8gOjo9IFNFUVVFTkNFIHsKKyAgICAgKiAgICAgIHBvbGljeVF1YWxpZmllcklkICAgICAgIFBvbGljeVF1YWxpZmllcklkLAorICAgICAqICAgICAgcXVhbGlmaWVyICAgICAgICAgICAgICAgQU5ZIERFRklORUQgQlkgcG9saWN5UXVhbGlmaWVySWQKKyAgICAgKiAgIH0KKyAgICAgKgorICAgICAqIHdoZXJlIHBvbGljeVF1YWxpZmllcklkIChPSUQpIGlzCisgICAgICogICAgICAxLjMuNi4xLjUuNS43LjIuMQorICAgICAqIGFuZCBxdWFsaWZpZXIgKElBNVN0cmluZykgaXMKKyAgICAgKiAgICAgICJodHRwOi8vd3d3LnFxLmNvbS9zdG10LnR4dCIKKyAgICAgKgorICAgICAqIChkYXRhIGdlbmVyYXRlZCBieSBvd24gZW5jb2RlciBkdXJpbmcgdGVzdCBkZXZlbG9wbWVudCkKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gZ2V0RGVyRW5jb2RpbmcoKSB7CisgICAgICAgIC8vIERPIE5PVCBNT0RJRlkhCisgICAgICAgIHJldHVybiAgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAoYnl0ZSkweDMwLCAoYnl0ZSkweDI2LCAvLyB0YWcgU2VxLCBsZW5ndGgKKyAgICAgICAgICAgICAgKGJ5dGUpMHgwNiwgKGJ5dGUpMHgwOCwgLy8gdGFnIE9JRCwgbGVuZ3RoCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgyYiwgKGJ5dGUpMHgwNiwgKGJ5dGUpMHgwMSwgKGJ5dGUpMHgwNSwgLy8gb2lkIHZhbHVlCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwNSwgKGJ5dGUpMHgwNywgKGJ5dGUpMHgwMiwgKGJ5dGUpMHgwMSwgLy8gb2lkIHZhbHVlCisgICAgICAgICAgICAgIChieXRlKTB4MTYsIChieXRlKTB4MWEsIC8vIHRhZyBJQTVTdHJpbmcsIGxlbmd0aAorICAgICAgICAgICAgICAgIChieXRlKTB4NjgsIChieXRlKTB4NzQsIChieXRlKTB4NzQsIChieXRlKTB4NzAsICAvLyBJQTVTdHJpbmcgdmFsdWUKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDNhLCAoYnl0ZSkweDJmLCAoYnl0ZSkweDJmLCAoYnl0ZSkweDc3LCAgLy8gSUE1U3RyaW5nIHZhbHVlCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg3NywgKGJ5dGUpMHg3NywgKGJ5dGUpMHgyZSwgKGJ5dGUpMHg3MSwgIC8vIElBNVN0cmluZyB2YWx1ZQorICAgICAgICAgICAgICAgIChieXRlKTB4NzEsIChieXRlKTB4MmUsIChieXRlKTB4NjMsIChieXRlKTB4NmYsICAvLyBJQTVTdHJpbmcgdmFsdWUKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDZkLCAoYnl0ZSkweDJmLCAoYnl0ZSkweDczLCAoYnl0ZSkweDc0LCAgLy8gSUE1U3RyaW5nIHZhbHVlCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2ZCwgKGJ5dGUpMHg3NCwgKGJ5dGUpMHgyZSwgKGJ5dGUpMHg3NCwgIC8vIElBNVN0cmluZyB2YWx1ZQorICAgICAgICAgICAgICAgIChieXRlKTB4NzgsIChieXRlKTB4NzQgICAvLyBJQTVTdHJpbmcgdmFsdWUKKyAgICAgICAgfTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9UcnVzdEFuY2hvclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L1RydXN0QW5jaG9yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2MzI0ZjAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9UcnVzdEFuY2hvclRlc3QuamF2YQpAQCAtMCwwICsxLDc2MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuVGVzdENlcnRVdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5UZXN0S2V5UGFpcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0LlRlc3RVdGlsczsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LlRydXN0QW5jaG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkludmFsaWRLZXlTcGVjRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbDsKKworLyoqCisgKiBVbml0IHRlc3RzIGZvciA8Y29kZT5UcnVzdEFuY2hvcjwvY29kZT4KKyAqLworcHVibGljIGNsYXNzIFRydXN0QW5jaG9yVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcga2V5QWxnID0gIkRTQSI7CisgICAgLy8gU2FtcGxlIG9mIHNvbWUgdmFsaWQgQ0EgbmFtZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyB2YWxpZENhTmFtZVJmYzIyNTMgPQorICAgICAgICAiQ049VGVzdCBDQSwiKworICAgICAgICAiT1U9VGVzdGluZyBEaXZpc2lvbiwiKworICAgICAgICAiTz1UZXN0IEl0IEFsbCwiKworICAgICAgICAiTD1UZXN0IFRvd24sIisKKyAgICAgICAgIlNUPVRlc3RpZm9ybmlhLCIrCisgICAgICAgICJDPVRlc3RsYW5kIjsKKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPlRydXN0QW5jaG9yKFN0cmluZywgUHVibGljS2V5LCBieXRlW10pPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IGNyZWF0ZXMgPGNvZGU+VHJ1c3RBbmNob3I8L2NvZGU+IGluc3RhbmNlPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogdmFsaWQgcGFyYW1ldGVycyBwYXNzZWQ8YnI+CisgICAgICogRXhwZWN0ZWQ6IG11c3QgcGFzcyB3aXRob3V0IGFueSBleGNlcHRpb25zCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RUcnVzdEFuY2hvclN0cmluZ1B1YmxpY0tleWJ5dGVBcnJheTAxKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIFB1YmxpY0tleSBwayA9IG5ldyBUZXN0S2V5UGFpcihrZXlBbGcpLmdldFB1YmxpYygpOworCisgICAgICAgIC8vIHN1YiB0ZXN0Y2FzZSAxCisgICAgICAgIG5ldyBUcnVzdEFuY2hvcih2YWxpZENhTmFtZVJmYzIyNTMsIHBrLCBnZXRGdWxsRW5jb2RpbmcoKSk7CisgICAgICAgIC8vIHN1YiB0ZXN0Y2FzZSAyCisgICAgICAgIG5ldyBUcnVzdEFuY2hvcih2YWxpZENhTmFtZVJmYzIyNTMsIHBrLCBnZXRFbmNvZGluZ1BTT25seSgpKTsKKyAgICAgICAgLy8gc3ViIHRlc3RjYXNlIDMKKyAgICAgICAgbmV3IFRydXN0QW5jaG9yKHZhbGlkQ2FOYW1lUmZjMjI1MywgcGssIGdldEVuY29kaW5nRVNPbmx5KCkpOworICAgICAgICAvLyBzdWIgdGVzdGNhc2UgNAorICAgICAgICBuZXcgVHJ1c3RBbmNob3IodmFsaWRDYU5hbWVSZmMyMjUzLCBwaywgZ2V0RW5jb2RpbmdOb01pbk1heCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5UcnVzdEFuY2hvcihTdHJpbmcsIFB1YmxpY0tleSwgYnl0ZVtdKTwvY29kZT4gY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiBjcmVhdGVzIDxjb2RlPlRydXN0QW5jaG9yPC9jb2RlPiBpbnN0YW5jZTxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IDxjb2RlPm51bGw8L2NvZGU+IGFzIG5hbWVDb25zdHJhaW50cyBwYXNzZWQ8YnI+CisgICAgICogRXhwZWN0ZWQ6IG11c3QgcGFzcyB3aXRob3V0IGFueSBleGNlcHRpb25zCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RUcnVzdEFuY2hvclN0cmluZ1B1YmxpY0tleWJ5dGVBcnJheTAyKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIFB1YmxpY0tleSBwayA9IG5ldyBUZXN0S2V5UGFpcihrZXlBbGcpLmdldFB1YmxpYygpOworCisgICAgICAgIG5ldyBUcnVzdEFuY2hvcih2YWxpZENhTmFtZVJmYzIyNTMsIHBrLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMzIGZvciA8Y29kZT5UcnVzdEFuY2hvcihTdHJpbmcsIFB1YmxpY0tleSwgYnl0ZVtdKTwvY29kZT4gY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiBuYW1lQ29uc3RyYWludHMgY2xvbmVkIGJ5IHRoZSBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IG1vZGlmeSBwYXNzZWQgbmFtZUNvbnN0cmFpbnRzPGJyPgorICAgICAqIEV4cGVjdGVkOiBtb2RpZmljYXRpb24gbXVzdCBub3QgY2hhbmdlIG9iamVjdCBpbnRlcm5hbCBzdGF0ZQorICAgICAqIEB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0VHJ1c3RBbmNob3JTdHJpbmdQdWJsaWNLZXlieXRlQXJyYXkwMygpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBQdWJsaWNLZXkgcGsgPSBuZXcgVGVzdEtleVBhaXIoa2V5QWxnKS5nZXRQdWJsaWMoKTsKKworICAgICAgICBieXRlW10gbmMgPSBnZXRFbmNvZGluZ1BTT25seSgpOworICAgICAgICBieXRlW10gbmNDb3B5ID0gbmMuY2xvbmUoKTsKKyAgICAgICAgLy8gc3ViIHRlc3RjYXNlIDUgLSBuYW1lQ29uc3RyYWludHMgY2FuIGJlIG51bGwKKyAgICAgICAgVHJ1c3RBbmNob3IgdGEgPSBuZXcgVHJ1c3RBbmNob3IodmFsaWRDYU5hbWVSZmMyMjUzLCBwaywgbmNDb3B5KTsKKyAgICAgICAgLy8gbW9kaWZ5CisgICAgICAgIG5jQ29weVswXT0oYnl0ZSkwOworICAgICAgICAvLyBjaGVjayB0aGF0IGFib3ZlIG1vZGlmaWNhdGlvbiBkaWQgbm90IGNoYW5nZQorICAgICAgICAvLyBvYmplY3QgaW50ZXJuYWwgc3RhdGUKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKG5jLCB0YS5nZXROYW1lQ29uc3RyYWludHMoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzQgZm9yIDxjb2RlPlRydXN0QW5jaG9yKFN0cmluZywgUHVibGljS2V5LCBieXRlW10pPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpZiA8Y29kZT5jYU5hbWU8L2NvZGU+CisgICAgICogb3IgPGNvZGU+Y2FQdWJsaWNLZXk8L2NvZGU+IHBhcmFtZXRlciBpcyA8Y29kZT5udWxsPC9jb2RlPjxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHBhc3MgPGNvZGU+bnVsbDwvY29kZT4gYXMgbWVudGlvbmVkIHBhcmFtZXRlcjxicj4KKyAgICAgKiBFeHBlY3RlZDogTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0VHJ1c3RBbmNob3JTdHJpbmdQdWJsaWNLZXlieXRlQXJyYXkwNCgpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBQdWJsaWNLZXkgcGsgPSBuZXcgVGVzdEtleVBhaXIoa2V5QWxnKS5nZXRQdWJsaWMoKTsKKworICAgICAgICAvLyBzdWIgdGVzdGNhc2UgMTogJ2NhTmFtZScgcGFyYW0gaXMgbnVsbAorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFRydXN0QW5jaG9yKChTdHJpbmcpbnVsbCwgcGssIGdldEVuY29kaW5nUFNPbmx5KCkpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBvaykgeworICAgICAgICB9CisKKyAgICAgICAgLy8gc3ViIHRlc3RjYXNlIDI6ICdjYVB1YmxpY0tleScgcGFyYW0gaXMgbnVsbAorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFRydXN0QW5jaG9yKHZhbGlkQ2FOYW1lUmZjMjI1MywgbnVsbCwgZ2V0RW5jb2RpbmdQU09ubHkoKSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG9rKSB7CisgICAgICAgIH0KKworICAgICAgICAvLyBzdWIgdGVzdGNhc2UgMzogJ2NhTmFtZScgYW5kICdjYVB1YmxpY0tleScgcGFyYW1zIGFyZSBudWxsCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVHJ1c3RBbmNob3IoKFN0cmluZyludWxsLCBudWxsLCBnZXRFbmNvZGluZ1BTT25seSgpKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gb2spIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHN1YiB0ZXN0Y2FzZSA0OiAnY2FOYW1lJyBwYXJhbSBpcyBlbXB0eQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFRydXN0QW5jaG9yKCIiLCBwaywgZ2V0RW5jb2RpbmdQU09ubHkoKSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gb2spIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHN1YiB0ZXN0Y2FzZSA1OiAnY2FOYW1lJyBwYXJhbSBpcyBpbmNvcnJlY3QgZGlzdGluZ3Vpc2hlZCBuYW1lCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVHJ1c3RBbmNob3IoIkFJRC4xMS4xMj1BIiwgcGssIGdldEVuY29kaW5nUFNPbmx5KCkpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG9rKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5UcnVzdEFuY2hvcihYNTAwUHJpbmNpcGFsLCBQdWJsaWNLZXksIGJ5dGVbXSk8L2NvZGU+IGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogY3JlYXRlcyA8Y29kZT5UcnVzdEFuY2hvcjwvY29kZT4gaW5zdGFuY2U8YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiB2YWxpZCBwYXJhbWV0ZXJzIHBhc3NlZDxicj4KKyAgICAgKiBFeHBlY3RlZDogbXVzdCBwYXNzIHdpdGhvdXQgYW55IGV4Y2VwdGlvbnMKKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFRydXN0QW5jaG9yWDUwMFByaW5jaXBhbFB1YmxpY0tleWJ5dGVBcnJheTAxKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIFB1YmxpY0tleSBwayA9IG5ldyBUZXN0S2V5UGFpcihrZXlBbGcpLmdldFB1YmxpYygpOworCisgICAgICAgIFg1MDBQcmluY2lwYWwgeDUwMHAgPSBuZXcgWDUwMFByaW5jaXBhbCh2YWxpZENhTmFtZVJmYzIyNTMpOworICAgICAgICAvLyBzdWIgdGVzdGNhc2UgMQorICAgICAgICBuZXcgVHJ1c3RBbmNob3IoeDUwMHAsIHBrLCBnZXRGdWxsRW5jb2RpbmcoKSk7CisgICAgICAgIC8vIHN1YiB0ZXN0Y2FzZSAyCisgICAgICAgIG5ldyBUcnVzdEFuY2hvcih4NTAwcCwgcGssIGdldEVuY29kaW5nUFNPbmx5KCkpOworICAgICAgICAvLyBzdWIgdGVzdGNhc2UgMworICAgICAgICBuZXcgVHJ1c3RBbmNob3IoeDUwMHAsIHBrLCBnZXRFbmNvZGluZ0VTT25seSgpKTsKKyAgICAgICAgLy8gc3ViIHRlc3RjYXNlIDQKKyAgICAgICAgbmV3IFRydXN0QW5jaG9yKHg1MDBwLCBwaywgZ2V0RW5jb2RpbmdOb01pbk1heCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5UcnVzdEFuY2hvcihYNTAwUHJpbmNpcGFsLCBQdWJsaWNLZXksIGJ5dGVbXSk8L2NvZGU+IGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogY3JlYXRlcyA8Y29kZT5UcnVzdEFuY2hvcjwvY29kZT4gaW5zdGFuY2U8YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiA8Y29kZT5udWxsPC9jb2RlPiBhcyBuYW1lQ29uc3RyYWludHMgcGFzc2VkPGJyPgorICAgICAqIEV4cGVjdGVkOiBtdXN0IHBhc3Mgd2l0aG91dCBhbnkgZXhjZXB0aW9ucworICAgICAqIEB0aHJvd3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0VHJ1c3RBbmNob3JYNTAwUHJpbmNpcGFsUHVibGljS2V5Ynl0ZUFycmF5MDIoKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgUHVibGljS2V5IHBrID0gbmV3IFRlc3RLZXlQYWlyKGtleUFsZykuZ2V0UHVibGljKCk7CisKKyAgICAgICAgWDUwMFByaW5jaXBhbCB4NTAwcCA9IG5ldyBYNTAwUHJpbmNpcGFsKHZhbGlkQ2FOYW1lUmZjMjI1Myk7CisKKyAgICAgICAgbmV3IFRydXN0QW5jaG9yKHg1MDBwLCBwaywgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMyBmb3IgPGNvZGU+VHJ1c3RBbmNob3IoWDUwMFByaW5jaXBhbCwgUHVibGljS2V5LCBieXRlW10pPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IG5hbWVDb25zdHJhaW50cyBjbG9uZWQgYnkgdGhlIGNvbnN0cnVjdG9yPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogbW9kaWZ5IHBhc3NlZCBuYW1lQ29uc3RyYWludHM8YnI+CisgICAgICogRXhwZWN0ZWQ6IG1vZGlmaWNhdGlvbiBtdXN0IG5vdCBjaGFuZ2Ugb2JqZWN0IGludGVybmFsIHN0YXRlCisgICAgICogQHRocm93cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RUcnVzdEFuY2hvclg1MDBQcmluY2lwYWxQdWJsaWNLZXlieXRlQXJyYXkwMygpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBQdWJsaWNLZXkgcGsgPSBuZXcgVGVzdEtleVBhaXIoa2V5QWxnKS5nZXRQdWJsaWMoKTsKKworICAgICAgICBieXRlW10gbmMgPSBnZXRFbmNvZGluZ1BTT25seSgpOworICAgICAgICBieXRlW10gbmNDb3B5ID0gbmMuY2xvbmUoKTsKKyAgICAgICAgLy8gc3ViIHRlc3RjYXNlIDUgLSBuYW1lQ29uc3RyYWludHMgY2FuIGJlIG51bGwKKyAgICAgICAgVHJ1c3RBbmNob3IgdGEgPSBuZXcgVHJ1c3RBbmNob3IobmV3IFg1MDBQcmluY2lwYWwodmFsaWRDYU5hbWVSZmMyMjUzKSwKKyAgICAgICAgICAgICAgICBwaywgbmNDb3B5KTsKKyAgICAgICAgLy8gbW9kaWZ5CisgICAgICAgIG5jQ29weVswXT0oYnl0ZSkwOworICAgICAgICAvLyBjaGVjayB0aGF0IGFib3ZlIG1vZGlmaWNhdGlvbiBkaWQgbm90IGNoYW5nZQorICAgICAgICAvLyBvYmplY3QgaW50ZXJuYWwgc3RhdGUKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKG5jLCB0YS5nZXROYW1lQ29uc3RyYWludHMoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzQgZm9yIDxjb2RlPlRydXN0QW5jaG9yKFg1MDBQcmluY2lwYWwsIFB1YmxpY0tleSwgYnl0ZVtdKTwvY29kZT4gY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaWYgPGNvZGU+Y2FQcmluY2lwYWw8L2NvZGU+CisgICAgICogb3IgPGNvZGU+Y2FQdWJsaWNLZXk8L2NvZGU+IHBhcmFtZXRlciBpcyA8Y29kZT5udWxsPC9jb2RlPjxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHBhc3MgPGNvZGU+bnVsbDwvY29kZT4gYXMgbWVudGlvbmVkIHBhcmFtZXRlcjxicj4KKyAgICAgKiBFeHBlY3RlZDogTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFRydXN0QW5jaG9yWDUwMFByaW5jaXBhbFB1YmxpY0tleWJ5dGVBcnJheTA0KCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIFB1YmxpY0tleSBwayA9IG5ldyBUZXN0S2V5UGFpcihrZXlBbGcpLmdldFB1YmxpYygpOworCisgICAgICAgIFg1MDBQcmluY2lwYWwgeDUwMHAgPSBuZXcgWDUwMFByaW5jaXBhbCh2YWxpZENhTmFtZVJmYzIyNTMpOworICAgICAgICAvLyBzdWIgdGVzdGNhc2UgMQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFRydXN0QW5jaG9yKChYNTAwUHJpbmNpcGFsKW51bGwsCisgICAgICAgICAgICAgICAgICAgIHBrLCBnZXRFbmNvZGluZ1BTT25seSgpKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gb2spIHsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHN1YiB0ZXN0Y2FzZSAyCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVHJ1c3RBbmNob3IoeDUwMHAsIG51bGwsIGdldEVuY29kaW5nUFNPbmx5KCkpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBvaykgeworICAgICAgICB9CisKKyAgICAgICAgLy8gc3ViIHRlc3RjYXNlIDMKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBUcnVzdEFuY2hvcigoWDUwMFByaW5jaXBhbCludWxsLCBudWxsLAorICAgICAgICAgICAgICAgICAgICBnZXRFbmNvZGluZ1BTT25seSgpKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gb2spIHsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+VHJ1c3RBbmNob3IoWDUwOUNlcnRpZmljYXRlLCBieXRlW10pPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogY3JlYXRlcyA8Y29kZT5UcnVzdEFuY2hvcjwvY29kZT4gaW5zdGFuY2U8YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiB2YWxpZCBwYXJhbWV0ZXJzIHBhc3NlZDxicj4KKyAgICAgKiBFeHBlY3RlZDogbXVzdCBwYXNzIHdpdGhvdXQgYW55IGV4Y2VwdGlvbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0VHJ1c3RBbmNob3JYNTA5Q2VydGlmaWNhdGVieXRlQXJyYXkwMSgpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworCisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZXJ0RmFjdCA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWDUwOSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgcGVtQ2VydCA9IChYNTA5Q2VydGlmaWNhdGUpIGNlcnRGYWN0CisgICAgICAgICAgICAgICAgLmdlbmVyYXRlQ2VydGlmaWNhdGUobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKFRlc3RVdGlscworICAgICAgICAgICAgICAgICAgICAgICAgLmdldFg1MDlDZXJ0aWZpY2F0ZV92MygpKSk7CisKKyAgICAgICAgLy8gc3ViIHRlc3RjYXNlIDEKKyAgICAgICAgVHJ1c3RBbmNob3IgdGExID0gbmV3IFRydXN0QW5jaG9yKHBlbUNlcnQsIGdldEZ1bGxFbmNvZGluZygpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh0YTEuZ2V0Q0EoKSk7CisgICAgICAgIGFzc2VydE51bGwodGExLmdldENBTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh0YTEuZ2V0Q0FQdWJsaWNLZXkoKSk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhnZXRGdWxsRW5jb2RpbmcoKSwgdGExLmdldE5hbWVDb25zdHJhaW50cygpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhwZW1DZXJ0LCB0YTEuZ2V0VHJ1c3RlZENlcnQoKSk7CisKKyAgICAgICAgLy8gc3ViIHRlc3RjYXNlIDIKKyAgICAgICAgVHJ1c3RBbmNob3IgdGEyID0gbmV3IFRydXN0QW5jaG9yKHBlbUNlcnQsIGdldEVuY29kaW5nUFNPbmx5KCkpOworICAgICAgICBhc3NlcnROdWxsKHRhMi5nZXRDQSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh0YTIuZ2V0Q0FOYW1lKCkpOworICAgICAgICBhc3NlcnROdWxsKHRhMi5nZXRDQVB1YmxpY0tleSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGdldEVuY29kaW5nUFNPbmx5KCksIHRhMi5nZXROYW1lQ29uc3RyYWludHMoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMocGVtQ2VydCwgdGEyLmdldFRydXN0ZWRDZXJ0KCkpOworCisgICAgICAgIC8vIHN1YiB0ZXN0Y2FzZSAzCisgICAgICAgIFRydXN0QW5jaG9yIHRhMyA9IG5ldyBUcnVzdEFuY2hvcihwZW1DZXJ0LCBnZXRFbmNvZGluZ0VTT25seSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh0YTMuZ2V0Q0EoKSk7CisgICAgICAgIGFzc2VydE51bGwodGEzLmdldENBTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh0YTMuZ2V0Q0FQdWJsaWNLZXkoKSk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhnZXRFbmNvZGluZ0VTT25seSgpLCB0YTMuZ2V0TmFtZUNvbnN0cmFpbnRzKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHBlbUNlcnQsIHRhMy5nZXRUcnVzdGVkQ2VydCgpKTsKKworICAgICAgICAvLyBzdWIgdGVzdGNhc2UgNAorICAgICAgICBUcnVzdEFuY2hvciB0YTQgPSBuZXcgVHJ1c3RBbmNob3IocGVtQ2VydCwgZ2V0RW5jb2RpbmdOb01pbk1heCgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh0YTQuZ2V0Q0EoKSk7CisgICAgICAgIGFzc2VydE51bGwodGE0LmdldENBTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh0YTQuZ2V0Q0FQdWJsaWNLZXkoKSk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhnZXRFbmNvZGluZ05vTWluTWF4KCksIHRhNAorICAgICAgICAgICAgICAgIC5nZXROYW1lQ29uc3RyYWludHMoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMocGVtQ2VydCwgdGE0LmdldFRydXN0ZWRDZXJ0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPlRydXN0QW5jaG9yKFg1MDlDZXJ0aWZpY2F0ZSwgYnl0ZVtdKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IGNyZWF0ZXMgPGNvZGU+VHJ1c3RBbmNob3I8L2NvZGU+IGluc3RhbmNlPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogPGNvZGU+bnVsbDwvY29kZT4gYXMgWDUwOUNlcnRpZmljYXRlIHBhc3NlZDxicj4KKyAgICAgKiBFeHBlY3RlZDogPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFRydXN0QW5jaG9yWDUwOUNlcnRpZmljYXRlYnl0ZUFycmF5MDIoKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBUcnVzdEFuY2hvcihudWxsLCBnZXRGdWxsRW5jb2RpbmcoKSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMyBmb3IgPGNvZGU+VHJ1c3RBbmNob3IoWDUwOUNlcnRpZmljYXRlLCBieXRlW10pPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogY3JlYXRlcyA8Y29kZT5UcnVzdEFuY2hvcjwvY29kZT4gaW5zdGFuY2U8YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiA8Y29kZT5udWxsPC9jb2RlPiBhcyBuYW1lQ29uc3RyYWludHMgcGFzc2VkPGJyPgorICAgICAqIEV4cGVjdGVkOiBtdXN0IHBhc3Mgd2l0aG91dCBhbnkgZXhjZXB0aW9ucworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RUcnVzdEFuY2hvclg1MDlDZXJ0aWZpY2F0ZWJ5dGVBcnJheTAzKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2VydEZhY3QgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlg1MDkiKTsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIHBlbUNlcnQgPSAoWDUwOUNlcnRpZmljYXRlKSBjZXJ0RmFjdAorICAgICAgICAgICAgICAgIC5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShUZXN0VXRpbHMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRYNTA5Q2VydGlmaWNhdGVfdjMoKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVHJ1c3RBbmNob3IocGVtQ2VydCwgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4ZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM0IGZvciA8Y29kZT5UcnVzdEFuY2hvcihYNTA5Q2VydGlmaWNhdGUsIGJ5dGVbXSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiBjcmVhdGVzIDxjb2RlPlRydXN0QW5jaG9yPC9jb2RlPiBpbnN0YW5jZTxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHBhc3Mgbm90IHZhbGlkIG5hbWUgY29uc3RyYWludHMgYXJyYXkgRXhwZWN0ZWQ6CisgICAgICogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0VHJ1c3RBbmNob3JYNTA5Q2VydGlmaWNhdGVieXRlQXJyYXkwNCgpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2VydEZhY3QgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlg1MDkiKTsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIHBlbUNlcnQgPSAoWDUwOUNlcnRpZmljYXRlKSBjZXJ0RmFjdAorICAgICAgICAgICAgICAgIC5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShUZXN0VXRpbHMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRYNTA5Q2VydGlmaWNhdGVfdjMoKSkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVHJ1c3RBbmNob3IocGVtQ2VydCwKKyAgICAgICAgICAgICAgICAgICAgbmV3IGJ5dGVbXSB7IChieXRlKSAxLCAoYnl0ZSkgMiwgKGJ5dGUpIDMgfSk7CisgICAgICAgICAgICBmYWlsKCJJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM1IGZvciA8Y29kZT5UcnVzdEFuY2hvcihYNTA5Q2VydGlmaWNhdGUsIGJ5dGVbXSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiBjcmVhdGVzIDxjb2RlPlRydXN0QW5jaG9yPC9jb2RlPiBpbnN0YW5jZTxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IGJvdGggcGFyYW1ldGVycyBhcmUgcGFzc2VkIGFzIG51bGw8YnI+CisgICAgICogRXhwZWN0ZWQ6IDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RUcnVzdEFuY2hvclg1MDlDZXJ0aWZpY2F0ZWJ5dGVBcnJheTA1KCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgVHJ1c3RBbmNob3IobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+Z2V0Q0FQdWJsaWNLZXkoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIG1vc3QgdHJ1c3RlZCBDQSBwdWJsaWMga2V5PC9jb2RlPjxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHZhbGlkIG5hbWUgcGFzc2VkIHRvIHRoZSBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBFeHBlY3RlZDogdGhlIHNhbWUgbmFtZSBtdXN0IGJlIHJldHVybmVkIGJ5IHRoZSBtZXRob2Q8YnI+CisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0Q0FQdWJsaWNLZXkwMSgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIFB1YmxpY0tleSBwayA9IG5ldyBUZXN0S2V5UGFpcihrZXlBbGcpLmdldFB1YmxpYygpOworCisgICAgICAgIC8vIHN1YiB0ZXN0Y2FzZSAxCisgICAgICAgIFRydXN0QW5jaG9yIHRhID0KKyAgICAgICAgICAgIG5ldyBUcnVzdEFuY2hvcih2YWxpZENhTmFtZVJmYzIyNTMsIHBrLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlcXVhbHMxIiwgcGssIHRhLmdldENBUHVibGljS2V5KCkpOworICAgICAgICAvLyBzdWIgdGVzdGNhc2UgMgorICAgICAgICBYNTAwUHJpbmNpcGFsIHg1MDBwID0gbmV3IFg1MDBQcmluY2lwYWwodmFsaWRDYU5hbWVSZmMyMjUzKTsKKyAgICAgICAgdGEgPSBuZXcgVHJ1c3RBbmNob3IoeDUwMHAsIHBrLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJlcXVhbHMyIiwgcGssIHRhLmdldENBUHVibGljS2V5KCkpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+Z2V0Q0FOYW1lKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBtb3N0IHRydXN0ZWQgQ0EgbmFtZSBhcyA8Y29kZT5TdHJpbmc8L2NvZGU+PGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogdmFsaWQgbmFtZSBwYXNzZWQgdG8gdGhlIGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEV4cGVjdGVkOiB0aGUgc2FtZSBuYW1lIG11c3QgYmUgcmV0dXJuZWQgYnkgdGhlIG1ldGhvZDxicj4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldENBTmFtZTAxKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgUHVibGljS2V5IHBrID0gbmV3IFRlc3RLZXlQYWlyKGtleUFsZykuZ2V0UHVibGljKCk7CisKKyAgICAgICAgLy8gc3ViIHRlc3RjYXNlIDEKKyAgICAgICAgVHJ1c3RBbmNob3IgdGEgPQorICAgICAgICAgICAgbmV3IFRydXN0QW5jaG9yKHZhbGlkQ2FOYW1lUmZjMjI1MywgcGssIG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVxdWFsczEiLCB2YWxpZENhTmFtZVJmYzIyNTMsIHRhLmdldENBTmFtZSgpKTsKKyAgICAgICAgLy8gc3ViIHRlc3RjYXNlIDIKKyAgICAgICAgWDUwMFByaW5jaXBhbCB4NTAwcCA9IG5ldyBYNTAwUHJpbmNpcGFsKHZhbGlkQ2FOYW1lUmZjMjI1Myk7CisgICAgICAgIHRhID0gbmV3IFRydXN0QW5jaG9yKHg1MDBwLCBwaywgbnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscygiZXF1YWxzMiIsIHZhbGlkQ2FOYW1lUmZjMjI1MywgdGEuZ2V0Q0FOYW1lKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPmdldENBTmFtZSgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgLi4uIDxjb2RlPm51bGw8L2NvZGU+IGlmIDxjb2RlPlRydXN0QW5jaG9yPC9jb2RlPgorICAgICAqIHdhcyBub3Qgc3BlY2lmaWVkIGFzIHRydXN0ZWQgY2VydGlmaWNhdGU8YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiB0ZXN0IG9iamVjdCBpcyBub3Qgc3BlY2lmaWVkIGFzIHRydXN0ZWQgY2VydGlmaWNhdGU8YnI+CisgICAgICogRXhwZWN0ZWQ6IDxjb2RlPm51bGw8L2NvZGU+IGFzIHJldHVybiB2YWx1ZTxicj4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFRydXN0ZWRDZXIwMigpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIFB1YmxpY0tleSBwayA9IG5ldyBUZXN0S2V5UGFpcihrZXlBbGcpLmdldFB1YmxpYygpOworCisgICAgICAgIC8vIHN1YiB0ZXN0Y2FzZSAxCisgICAgICAgIFRydXN0QW5jaG9yIHRhID0KKyAgICAgICAgICAgIG5ldyBUcnVzdEFuY2hvcih2YWxpZENhTmFtZVJmYzIyNTMsIHBrLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgibnVsbDEiLCB0YS5nZXRUcnVzdGVkQ2VydCgpKTsKKyAgICAgICAgLy8gc3ViIHRlc3RjYXNlIDIKKyAgICAgICAgWDUwMFByaW5jaXBhbCB4NTAwcCA9IG5ldyBYNTAwUHJpbmNpcGFsKHZhbGlkQ2FOYW1lUmZjMjI1Myk7CisgICAgICAgIHRhID0gbmV3IFRydXN0QW5jaG9yKHg1MDBwLCBwaywgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoIm51bGwyIiwgdGEuZ2V0VHJ1c3RlZENlcnQoKSk7CisKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIGNlcnQgPSBuZXcgVGVzdENlcnRVdGlscy5UZXN0WDUwOUNlcnRpZmljYXRlKHg1MDBwLCB4NTAwcCk7CisgICAgICAgIFRydXN0QW5jaG9yIHRhMiA9IG5ldyBUcnVzdEFuY2hvcihjZXJ0LCBudWxsKTsKKyAgICAgICAgYXNzZXJ0U2FtZShjZXJ0LCB0YTIuZ2V0VHJ1c3RlZENlcnQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+Z2V0TmFtZUNvbnN0cmFpbnRzKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogUmV0dXJucyB0aGUgbmFtZSBjb25zdHJhaW50cyBwYXJhbWV0ZXIuPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogdmFsaWQgcGFyYW1ldGVycyBhcmUgcGFzc2VkIHRvIHRoZSBjb25zdHJ1Y3RvcnM8YnI+CisgICAgICogRXhwZWN0ZWQ6IHRoZSB2YWxpZCBwYXJhbWV0ZXJzIG11c3QgYmUgcmV0dXJuZWQgYnkgdGhlIG1ldGhvZDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0TmFtZUNvbnN0cmFpbnRzMDEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHVibGljS2V5IHBrID0gbmV3IFRlc3RLZXlQYWlyKGtleUFsZykuZ2V0UHVibGljKCk7CisgICAgICAgIFRydXN0QW5jaG9yIHRhMSA9IG5ldyBUcnVzdEFuY2hvcih2YWxpZENhTmFtZVJmYzIyNTMsIHBrLAorICAgICAgICAgICAgICAgIGdldEZ1bGxFbmNvZGluZygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGdldEZ1bGxFbmNvZGluZygpLCB0YTEuZ2V0TmFtZUNvbnN0cmFpbnRzKCkpKTsKKworICAgICAgICBYNTAwUHJpbmNpcGFsIHg1MDBwID0gbmV3IFg1MDBQcmluY2lwYWwodmFsaWRDYU5hbWVSZmMyMjUzKTsKKyAgICAgICAgVHJ1c3RBbmNob3IgdGEyID0gbmV3IFRydXN0QW5jaG9yKHg1MDBwLCBwaywgZ2V0RW5jb2RpbmdOb01pbk1heCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGdldEVuY29kaW5nTm9NaW5NYXgoKSwgdGEyCisgICAgICAgICAgICAgICAgLmdldE5hbWVDb25zdHJhaW50cygpKSk7CisKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNlcnRGYWN0ID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYNTA5Iik7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBwZW1DZXJ0ID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2VydEZhY3QKKyAgICAgICAgICAgICAgICAuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oVGVzdFV0aWxzCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0WDUwOUNlcnRpZmljYXRlX3YzKCkpKTsKKworICAgICAgICBUcnVzdEFuY2hvciB0YTMgPSBuZXcgVHJ1c3RBbmNob3IocGVtQ2VydCwgZ2V0RW5jb2RpbmdQU09ubHkoKSk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhnZXRFbmNvZGluZ1BTT25seSgpLCB0YTMuZ2V0TmFtZUNvbnN0cmFpbnRzKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5nZXROYW1lQ29uc3RyYWludHMoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBSZXR1cm5zIHRoZSBuYW1lIGNvbnN0cmFpbnRzIHBhcmFtZXRlci48YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiBudWxsIHBhcmFtZXRlcnMgYXJlIHBhc3NlZCB0byB0aGUgY29uc3RydWN0b3JzPGJyPgorICAgICAqIEV4cGVjdGVkOiB0aGUgbnVsbCBwYXJhbWV0ZXJzIG11c3QgYmUgcmV0dXJuZWQgYnkgdGhlIG1ldGhvZDxicj4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0TmFtZUNvbnN0cmFpbnRzMDIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHVibGljS2V5IHBrID0gbmV3IFRlc3RLZXlQYWlyKGtleUFsZykuZ2V0UHVibGljKCk7CisgICAgICAgIFRydXN0QW5jaG9yIHRhMSA9IG5ldyBUcnVzdEFuY2hvcih2YWxpZENhTmFtZVJmYzIyNTMsIHBrLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh0YTEuZ2V0TmFtZUNvbnN0cmFpbnRzKCkpOworCisgICAgICAgIFg1MDBQcmluY2lwYWwgeDUwMHAgPSBuZXcgWDUwMFByaW5jaXBhbCh2YWxpZENhTmFtZVJmYzIyNTMpOworICAgICAgICBUcnVzdEFuY2hvciB0YTIgPSBuZXcgVHJ1c3RBbmNob3IoeDUwMHAsIHBrLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh0YTIuZ2V0TmFtZUNvbnN0cmFpbnRzKCkpOworCisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZXJ0RmFjdCA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWDUwOSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgcGVtQ2VydCA9IChYNTA5Q2VydGlmaWNhdGUpIGNlcnRGYWN0CisgICAgICAgICAgICAgICAgLmdlbmVyYXRlQ2VydGlmaWNhdGUobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKFRlc3RVdGlscworICAgICAgICAgICAgICAgICAgICAgICAgLmdldFg1MDlDZXJ0aWZpY2F0ZV92MygpKSk7CisKKyAgICAgICAgVHJ1c3RBbmNob3IgdGEzID0gbmV3IFRydXN0QW5jaG9yKHBlbUNlcnQsIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKHRhMy5nZXROYW1lQ29uc3RyYWludHMoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+dG9TdHJpbmcoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIGEgZm9ybWF0dGVkIHN0cmluZyBkZXNjcmliaW5nIHRoZSBUcnVzdEFuY2hvcjxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHZhbGlkIHBhcmFtZXRlcnMgYXJlIHBhc3NlZCB0byB0aGUgY29uc3RydWN0b3JzPGJyPgorICAgICAqIEV4cGVjdGVkOiBub3QgbnVsbCBzdHJpbmc8YnI+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFRvU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFB1YmxpY0tleSBwayA9IG5ldyBUZXN0S2V5UGFpcihrZXlBbGcpLmdldFB1YmxpYygpOworICAgICAgICBUcnVzdEFuY2hvciB0YTEgPSBuZXcgVHJ1c3RBbmNob3IodmFsaWRDYU5hbWVSZmMyMjUzLCBwaywKKyAgICAgICAgICAgICAgICBnZXRGdWxsRW5jb2RpbmcoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwodGExLnRvU3RyaW5nKCkpOworCisgICAgICAgIFg1MDBQcmluY2lwYWwgeDUwMHAgPSBuZXcgWDUwMFByaW5jaXBhbCh2YWxpZENhTmFtZVJmYzIyNTMpOworICAgICAgICBUcnVzdEFuY2hvciB0YTIgPSBuZXcgVHJ1c3RBbmNob3IoeDUwMHAsIHBrLCBnZXRFbmNvZGluZ05vTWluTWF4KCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRhMi50b1N0cmluZygpKTsKKworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2VydEZhY3QgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlg1MDkiKTsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIHBlbUNlcnQgPSAoWDUwOUNlcnRpZmljYXRlKSBjZXJ0RmFjdAorICAgICAgICAgICAgICAgIC5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShUZXN0VXRpbHMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRYNTA5Q2VydGlmaWNhdGVfdjMoKSkpOworCisgICAgICAgIFRydXN0QW5jaG9yIHRhMyA9IG5ldyBUcnVzdEFuY2hvcihwZW1DZXJ0LCBnZXRFbmNvZGluZ1BTT25seSgpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0YTMudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+Z2V0Q0EoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIG1vc3QgdHJ1c3RlZCBDQTxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHZhbGlkIENBIG9yIENBIG5hbWUgcGFzc2VkIHRvIHRoZSBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBFeHBlY3RlZDogdGhlIHNhbWUgQ0Egb3QgdGhlIENBIHdpdGggdGhlIHNhbWUgbmFtZSBtdXN0IGJlIHJldHVybmVkCisgICAgICogYnkgdGhlIG1ldGhvZDxicj4KKyAgICAgKiBAdGhyb3dzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldENBMDEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBQdWJsaWNLZXkgcGsgPSBuZXcgVGVzdEtleVBhaXIoa2V5QWxnKS5nZXRQdWJsaWMoKTsKKworICAgICAgICAvLyBzdWIgdGVzdGNhc2UgMQorICAgICAgICBUcnVzdEFuY2hvciB0YSA9CisgICAgICAgICAgICBuZXcgVHJ1c3RBbmNob3IodmFsaWRDYU5hbWVSZmMyMjUzLCBwaywgbnVsbCk7CisgICAgICAgIFg1MDBQcmluY2lwYWwgY2EgPSB0YS5nZXRDQSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVxdWFsczEiLCB2YWxpZENhTmFtZVJmYzIyNTMsIGNhLmdldE5hbWUoKSk7CisgICAgICAgIC8vIHN1YiB0ZXN0Y2FzZSAyCisgICAgICAgIFg1MDBQcmluY2lwYWwgeDUwMHAgPSBuZXcgWDUwMFByaW5jaXBhbCh2YWxpZENhTmFtZVJmYzIyNTMpOworICAgICAgICB0YSA9IG5ldyBUcnVzdEFuY2hvcih4NTAwcCwgcGssIG51bGwpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVxdWFsczIiLCB4NTAwcCwgdGEuZ2V0Q0EoKSk7CisgICAgfQorCisgICAgLy8KKyAgICAvLyBQcml2YXRlIHN0dWZmCisgICAgLy8KKworICAgIC8qCisgICAgICogVGhlIGZvbGxvd2luZyBtZXRob2RzIHJldHVybiB2YWxpZCBERVIgZW5jb2RpbmcKKyAgICAgKiBmb3IgdGhlIGZvbGxvd2luZyBBU04uMSBkZWZpbml0aW9uIChhcyBzcGVjaWZpZWQgaW4gUkZDIDMyODAgLQorICAgICAqICBJbnRlcm5ldCBYLjUwOSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgorICAgICAqICBDZXJ0aWZpY2F0ZSBhbmQgQ2VydGlmaWNhdGUgUmV2b2NhdGlvbiBMaXN0IChDUkwpIFByb2ZpbGUuCisgICAgICogIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KToKKyAgICAgKgorICAgICAqICBOYW1lQ29uc3RyYWludHMgOjo9IFNFUVVFTkNFIHsKKyAgICAgKiAgICAgICAgICAgICBwZXJtaXR0ZWRTdWJ0cmVlcyAgICAgICBbMF0gICAgIEdlbmVyYWxTdWJ0cmVlcyBPUFRJT05BTCwKKyAgICAgKiAgICAgICAgICAgICBleGNsdWRlZFN1YnRyZWVzICAgICAgICBbMV0gICAgIEdlbmVyYWxTdWJ0cmVlcyBPUFRJT05BTCB9CisgICAgICoKKyAgICAgKiAgICAgICAgR2VuZXJhbFN1YnRyZWVzIDo6PSBTRVFVRU5DRSBTSVpFICgxLi5NQVgpIE9GIEdlbmVyYWxTdWJ0cmVlCisgICAgICoKKyAgICAgKiAgICAgICAgR2VuZXJhbFN1YnRyZWUgOjo9IFNFUVVFTkNFIHsKKyAgICAgKiAgICAgICAgICAgICBiYXNlICAgICAgICAgICAgICAgICAgICBHZW5lcmFsTmFtZSwKKyAgICAgKiAgICAgICAgICAgICBtaW5pbXVtICAgICAgICAgWzBdICAgICBCYXNlRGlzdGFuY2UgREVGQVVMVCAwLAorICAgICAqICAgICAgICAgICAgIG1heGltdW0gICAgICAgICBbMV0gICAgIEJhc2VEaXN0YW5jZSBPUFRJT05BTCB9CisgICAgICoKKyAgICAgKiAgICAgICAgQmFzZURpc3RhbmNlIDo6PSBJTlRFR0VSICgwLi5NQVgpCisgICAgICoKKyAgICAgKiAgICAgICAgR2VuZXJhbE5hbWUgOjo9IENIT0lDRSB7CisgICAgICogICAgICAgICAgICAgb3RoZXJOYW1lICAgICAgICAgICAgICAgICAgICAgICBbMF0gICAgIE90aGVyTmFtZSwKKyAgICAgKiAgICAgICAgICAgICByZmM4MjJOYW1lICAgICAgICAgICAgICAgICAgICAgIFsxXSAgICAgSUE1U3RyaW5nLAorICAgICAqICAgICAgICAgICAgIGROU05hbWUgICAgICAgICAgICAgICAgICAgICAgICAgWzJdICAgICBJQTVTdHJpbmcsCisgICAgICogICAgICAgICAgICAgeDQwMEFkZHJlc3MgICAgICAgICAgICAgICAgICAgICBbM10gICAgIE9SQWRkcmVzcywKKyAgICAgKiAgICAgICAgICAgICBkaXJlY3RvcnlOYW1lICAgICAgICAgICAgICAgICAgIFs0XSAgICAgTmFtZSwKKyAgICAgKiAgICAgICAgICAgICBlZGlQYXJ0eU5hbWUgICAgICAgICAgICAgICAgICAgIFs1XSAgICAgRURJUGFydHlOYW1lLAorICAgICAqICAgICAgICAgICAgIHVuaWZvcm1SZXNvdXJjZUlkZW50aWZpZXIgICAgICAgWzZdICAgICBJQTVTdHJpbmcsCisgICAgICogICAgICAgICAgICAgaVBBZGRyZXNzICAgICAgICAgICAgICAgICAgICAgICBbN10gICAgIE9DVEVUIFNUUklORywKKyAgICAgKiAgICAgICAgICAgICByZWdpc3RlcmVkSUQgICAgICAgICAgICAgICAgICAgIFs4XSAgICAgT0JKRUNUIElERU5USUZJRVJ9CisgICAgICovCisKKyAgICAvLworICAgIC8vIEZ1bGwgTmFtZUNvbnN0cmFpbnRzIGVuY29kaW5nCisgICAgLy8gKGdlbmVyYXRlZCBieSBvd24gZW5jb2RlciBjbGFzcyBjcmVhdGVkIGR1cmluZyB0ZXN0IGRldmVsb3BtZW50KQorICAgIC8vCisgICAgLy8gQHJldHVybiBGdWxsIE5hbWVDb25zdHJhaW50cyBlbmNvZGluZworICAgIC8vIHdpdGggYWxsIE9QVElPTkFMIHZhbHVlcyBwcmVzZW50ZWQuCisgICAgLy8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gZ2V0RnVsbEVuY29kaW5nKCkgeworICAgICAgICAvLyBETyBOT1QgTU9ESUZZIQorICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzMCwoYnl0ZSkweDgxLChieXRlKTB4OGMsKGJ5dGUpMHhhMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDQ0LChieXRlKTB4MzAsKGJ5dGUpMHgxNiwoYnl0ZSkweDg2LAorICAgICAgICAgICAgICAgIChieXRlKTB4MGUsKGJ5dGUpMHg2NiwoYnl0ZSkweDY5LChieXRlKTB4NmMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2NSwoYnl0ZSkweDNhLChieXRlKTB4MmYsKGJ5dGUpMHgyZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDY2LChieXRlKTB4NmYsKGJ5dGUpMHg2ZiwoYnl0ZSkweDJlLAorICAgICAgICAgICAgICAgIChieXRlKTB4NjMsKGJ5dGUpMHg2ZiwoYnl0ZSkweDZkLChieXRlKTB4ODAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwMSwoYnl0ZSkweDAwLChieXRlKTB4ODEsKGJ5dGUpMHgwMSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAxLChieXRlKTB4MzAsKGJ5dGUpMHgxNiwoYnl0ZSkweDg2LAorICAgICAgICAgICAgICAgIChieXRlKTB4MGUsKGJ5dGUpMHg2NiwoYnl0ZSkweDY5LChieXRlKTB4NmMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2NSwoYnl0ZSkweDNhLChieXRlKTB4MmYsKGJ5dGUpMHgyZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDYyLChieXRlKTB4NjEsKGJ5dGUpMHg3MiwoYnl0ZSkweDJlLAorICAgICAgICAgICAgICAgIChieXRlKTB4NjMsKGJ5dGUpMHg2ZiwoYnl0ZSkweDZkLChieXRlKTB4ODAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwMSwoYnl0ZSkweDAwLChieXRlKTB4ODEsKGJ5dGUpMHgwMSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAxLChieXRlKTB4MzAsKGJ5dGUpMHgxMiwoYnl0ZSkweDg2LAorICAgICAgICAgICAgICAgIChieXRlKTB4MGEsKGJ5dGUpMHg2NiwoYnl0ZSkweDY5LChieXRlKTB4NmMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2NSwoYnl0ZSkweDNhLChieXRlKTB4MmYsKGJ5dGUpMHgyZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDZkLChieXRlKTB4NzUsKGJ5dGUpMHg3NSwoYnl0ZSkweDgwLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDEsKGJ5dGUpMHgwMCwoYnl0ZSkweDgxLChieXRlKTB4MDEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwMSwoYnl0ZSkweGExLChieXRlKTB4NDQsKGJ5dGUpMHgzMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDE2LChieXRlKTB4ODYsKGJ5dGUpMHgwZSwoYnl0ZSkweDY4LAorICAgICAgICAgICAgICAgIChieXRlKTB4NzQsKGJ5dGUpMHg3NCwoYnl0ZSkweDcwLChieXRlKTB4M2EsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgyZiwoYnl0ZSkweDJmLChieXRlKTB4NjYsKGJ5dGUpMHg2ZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDZmLChieXRlKTB4MmUsKGJ5dGUpMHg2MywoYnl0ZSkweDZmLAorICAgICAgICAgICAgICAgIChieXRlKTB4NmQsKGJ5dGUpMHg4MCwoYnl0ZSkweDAxLChieXRlKTB4MDAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg4MSwoYnl0ZSkweDAxLChieXRlKTB4MDEsKGJ5dGUpMHgzMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDE2LChieXRlKTB4ODYsKGJ5dGUpMHgwZSwoYnl0ZSkweDY4LAorICAgICAgICAgICAgICAgIChieXRlKTB4NzQsKGJ5dGUpMHg3NCwoYnl0ZSkweDcwLChieXRlKTB4M2EsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgyZiwoYnl0ZSkweDJmLChieXRlKTB4NjIsKGJ5dGUpMHg2MSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDcyLChieXRlKTB4MmUsKGJ5dGUpMHg2MywoYnl0ZSkweDZmLAorICAgICAgICAgICAgICAgIChieXRlKTB4NmQsKGJ5dGUpMHg4MCwoYnl0ZSkweDAxLChieXRlKTB4MDAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg4MSwoYnl0ZSkweDAxLChieXRlKTB4MDEsKGJ5dGUpMHgzMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDEyLChieXRlKTB4ODYsKGJ5dGUpMHgwYSwoYnl0ZSkweDY4LAorICAgICAgICAgICAgICAgIChieXRlKTB4NzQsKGJ5dGUpMHg3NCwoYnl0ZSkweDcwLChieXRlKTB4M2EsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgyZiwoYnl0ZSkweDJmLChieXRlKTB4NmQsKGJ5dGUpMHg3NSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDc1LChieXRlKTB4ODAsKGJ5dGUpMHgwMSwoYnl0ZSkweDAwLAorICAgICAgICAgICAgICAgIChieXRlKTB4ODEsKGJ5dGUpMHgwMSwoYnl0ZSkweDAxCisgICAgICAgIH07CisgICAgfQorCisgICAgLy8KKyAgICAvLyBOYW1lQ29uc3RyYWludHMgZW5jb2Rpbmcgd2l0aG91dCBleGNsdWRlZFN1YnRyZWVzCisgICAgLy8gKGdlbmVyYXRlZCBieSBvd24gZW5jb2RlciBjbGFzcyBjcmVhdGVkIGR1cmluZyB0ZXN0IGRldmVsb3BtZW50KQorICAgIC8vCisgICAgLy8gQHJldHVybiBOYW1lQ29uc3RyYWludHMgZW5jb2Rpbmcgd2l0aAorICAgIC8vIHBlcm1pdHRlZFN1YnRyZWVzIG9ubHk7IGFsbCBPUFRJT05BTAorICAgIC8vIHZhbHVlcyBpbiBwZXJtaXR0ZWRTdWJ0cmVlcyBhcmUgcHJlc2VudGVkLgorICAgIC8vCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIGdldEVuY29kaW5nUFNPbmx5KCkgeworICAgICAgICAvLyBETyBOT1QgTU9ESUZZIQorICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzMCwoYnl0ZSkweDQ2LChieXRlKTB4YTAsKGJ5dGUpMHg0NCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDMwLChieXRlKTB4MTYsKGJ5dGUpMHg4NiwoYnl0ZSkweDBlLAorICAgICAgICAgICAgICAgIChieXRlKTB4NjYsKGJ5dGUpMHg2OSwoYnl0ZSkweDZjLChieXRlKTB4NjUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzYSwoYnl0ZSkweDJmLChieXRlKTB4MmYsKGJ5dGUpMHg2NiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDZmLChieXRlKTB4NmYsKGJ5dGUpMHgyZSwoYnl0ZSkweDYzLAorICAgICAgICAgICAgICAgIChieXRlKTB4NmYsKGJ5dGUpMHg2ZCwoYnl0ZSkweDgwLChieXRlKTB4MDEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwMCwoYnl0ZSkweDgxLChieXRlKTB4MDEsKGJ5dGUpMHgwMSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDMwLChieXRlKTB4MTYsKGJ5dGUpMHg4NiwoYnl0ZSkweDBlLAorICAgICAgICAgICAgICAgIChieXRlKTB4NjYsKGJ5dGUpMHg2OSwoYnl0ZSkweDZjLChieXRlKTB4NjUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzYSwoYnl0ZSkweDJmLChieXRlKTB4MmYsKGJ5dGUpMHg2MiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDYxLChieXRlKTB4NzIsKGJ5dGUpMHgyZSwoYnl0ZSkweDYzLAorICAgICAgICAgICAgICAgIChieXRlKTB4NmYsKGJ5dGUpMHg2ZCwoYnl0ZSkweDgwLChieXRlKTB4MDEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwMCwoYnl0ZSkweDgxLChieXRlKTB4MDEsKGJ5dGUpMHgwMSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDMwLChieXRlKTB4MTIsKGJ5dGUpMHg4NiwoYnl0ZSkweDBhLAorICAgICAgICAgICAgICAgIChieXRlKTB4NjYsKGJ5dGUpMHg2OSwoYnl0ZSkweDZjLChieXRlKTB4NjUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzYSwoYnl0ZSkweDJmLChieXRlKTB4MmYsKGJ5dGUpMHg2ZCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDc1LChieXRlKTB4NzUsKGJ5dGUpMHg4MCwoYnl0ZSkweDAxLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDAsKGJ5dGUpMHg4MSwoYnl0ZSkweDAxLChieXRlKTB4MDEsCisgICAgICAgIH07CisgICAgfQorCisgICAgLy8KKyAgICAvLyBOYW1lQ29uc3RyYWludHMgZW5jb2Rpbmcgd2l0aG91dCBwZXJtaXR0ZWRTdWJ0cmVlcworICAgIC8vIChnZW5lcmF0ZWQgYnkgb3duIGVuY29kZXIgY2xhc3MgY3JlYXRlZCBkdXJpbmcgdGVzdCBkZXZlbG9wbWVudCkKKyAgICAvLworICAgIC8vIEByZXR1cm4gTmFtZUNvbnN0cmFpbnRzIGVuY29kaW5nIHdpdGgKKyAgICAvLyBleGNsdWRlZFN1YnRyZWVzIG9ubHk7IGFsbCBPUFRJT05BTAorICAgIC8vIHZhbHVlcyBpbiBleGNsdWRlZFN1YnRyZWVzIGFyZSBwcmVzZW50ZWQuCisgICAgLy8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gZ2V0RW5jb2RpbmdFU09ubHkoKSB7CisgICAgICAgIC8vIERPIE5PVCBNT0RJRlkhCisgICAgICAgIHJldHVybiBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDMwLChieXRlKTB4NDYsKGJ5dGUpMHhhMSwoYnl0ZSkweDQ0LAorICAgICAgICAgICAgICAgIChieXRlKTB4MzAsKGJ5dGUpMHgxNiwoYnl0ZSkweDg2LChieXRlKTB4MGUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2OCwoYnl0ZSkweDc0LChieXRlKTB4NzQsKGJ5dGUpMHg3MCwgLy8gaHR0cAorICAgICAgICAgICAgICAgIChieXRlKTB4M2EsKGJ5dGUpMHgyZiwoYnl0ZSkweDJmLChieXRlKTB4NjYsIC8vIDovL2YKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDZmLChieXRlKTB4NmYsKGJ5dGUpMHgyZSwoYnl0ZSkweDYzLCAvLyBvby5jCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2ZiwoYnl0ZSkweDZkLChieXRlKTB4ODAsKGJ5dGUpMHgwMSwgLy8gb20KKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAwLChieXRlKTB4ODEsKGJ5dGUpMHgwMSwoYnl0ZSkweDAxLAorICAgICAgICAgICAgICAgIChieXRlKTB4MzAsKGJ5dGUpMHgxNiwoYnl0ZSkweDg2LChieXRlKTB4MGUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2OCwoYnl0ZSkweDc0LChieXRlKTB4NzQsKGJ5dGUpMHg3MCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDNhLChieXRlKTB4MmYsKGJ5dGUpMHgyZiwoYnl0ZSkweDYyLAorICAgICAgICAgICAgICAgIChieXRlKTB4NjEsKGJ5dGUpMHg3MiwoYnl0ZSkweDJlLChieXRlKTB4NjMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2ZiwoYnl0ZSkweDZkLChieXRlKTB4ODAsKGJ5dGUpMHgwMSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAwLChieXRlKTB4ODEsKGJ5dGUpMHgwMSwoYnl0ZSkweDAxLAorICAgICAgICAgICAgICAgIChieXRlKTB4MzAsKGJ5dGUpMHgxMiwoYnl0ZSkweDg2LChieXRlKTB4MGEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2OCwoYnl0ZSkweDc0LChieXRlKTB4NzQsKGJ5dGUpMHg3MCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDNhLChieXRlKTB4MmYsKGJ5dGUpMHgyZiwoYnl0ZSkweDZkLAorICAgICAgICAgICAgICAgIChieXRlKTB4NzUsKGJ5dGUpMHg3NSwoYnl0ZSkweDgwLChieXRlKTB4MDEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwMCwoYnl0ZSkweDgxLChieXRlKTB4MDEsKGJ5dGUpMHgwMSwKKyAgICAgICAgfTsKKyAgICB9CisKKyAgICAvLworICAgIC8vIE5hbWVDb25zdHJhaW50cyBmdWxsIGVuY29kaW5nIHdpdGggYWxsIChPUFRJT05BTCkKKyAgICAvLyBtaW5pbXVtL21heGltdW0gR2VuZXJhbFN1YnRyZWUgZmllbGRzIE9NSVRURUQKKyAgICAvLyAoZ2VuZXJhdGVkIGJ5IG93biBlbmNvZGVyIGNsYXNzIGNyZWF0ZWQgZHVyaW5nIHRlc3QgZGV2ZWxvcG1lbnQpCisgICAgLy8KKyAgICAvLyBAcmV0dXJuIEZ1bGwgTmFtZUNvbnN0cmFpbnRzIGVuY29kaW5nCisgICAgLy8gd2l0aCBhbGwgKE9QVElPTkFMKSBtaW5pbXVtL21heGltdW0KKyAgICAvLyBHZW5lcmFsU3VidHJlZSBmaWVsZHMgT01JVFRFRAorICAgIC8vCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIGdldEVuY29kaW5nTm9NaW5NYXgoKSB7CisgICAgICAgIC8vIERPIE5PVCBNT0RJRlkhCisgICAgICAgIHJldHVybiBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDMwLChieXRlKTB4NjgsKGJ5dGUpMHhhMCwoYnl0ZSkweDMyLAorICAgICAgICAgICAgICAgIChieXRlKTB4MzAsKGJ5dGUpMHgxMCwoYnl0ZSkweDg2LChieXRlKTB4MGUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2NiwoYnl0ZSkweDY5LChieXRlKTB4NmMsKGJ5dGUpMHg2NSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDNhLChieXRlKTB4MmYsKGJ5dGUpMHgyZiwoYnl0ZSkweDY2LAorICAgICAgICAgICAgICAgIChieXRlKTB4NmYsKGJ5dGUpMHg2ZiwoYnl0ZSkweDJlLChieXRlKTB4NjMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2ZiwoYnl0ZSkweDZkLChieXRlKTB4MzAsKGJ5dGUpMHgxMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDg2LChieXRlKTB4MGUsKGJ5dGUpMHg2NiwoYnl0ZSkweDY5LAorICAgICAgICAgICAgICAgIChieXRlKTB4NmMsKGJ5dGUpMHg2NSwoYnl0ZSkweDNhLChieXRlKTB4MmYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgyZiwoYnl0ZSkweDYyLChieXRlKTB4NjEsKGJ5dGUpMHg3MiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDJlLChieXRlKTB4NjMsKGJ5dGUpMHg2ZiwoYnl0ZSkweDZkLAorICAgICAgICAgICAgICAgIChieXRlKTB4MzAsKGJ5dGUpMHgwYywoYnl0ZSkweDg2LChieXRlKTB4MGEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2NiwoYnl0ZSkweDY5LChieXRlKTB4NmMsKGJ5dGUpMHg2NSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDNhLChieXRlKTB4MmYsKGJ5dGUpMHgyZiwoYnl0ZSkweDZkLAorICAgICAgICAgICAgICAgIChieXRlKTB4NzUsKGJ5dGUpMHg3NSwoYnl0ZSkweGExLChieXRlKTB4MzIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzMCwoYnl0ZSkweDEwLChieXRlKTB4ODYsKGJ5dGUpMHgwZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDY4LChieXRlKTB4NzQsKGJ5dGUpMHg3NCwoYnl0ZSkweDcwLAorICAgICAgICAgICAgICAgIChieXRlKTB4M2EsKGJ5dGUpMHgyZiwoYnl0ZSkweDJmLChieXRlKTB4NjYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2ZiwoYnl0ZSkweDZmLChieXRlKTB4MmUsKGJ5dGUpMHg2MywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDZmLChieXRlKTB4NmQsKGJ5dGUpMHgzMCwoYnl0ZSkweDEwLAorICAgICAgICAgICAgICAgIChieXRlKTB4ODYsKGJ5dGUpMHgwZSwoYnl0ZSkweDY4LChieXRlKTB4NzQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg3NCwoYnl0ZSkweDcwLChieXRlKTB4M2EsKGJ5dGUpMHgyZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDJmLChieXRlKTB4NjIsKGJ5dGUpMHg2MSwoYnl0ZSkweDcyLAorICAgICAgICAgICAgICAgIChieXRlKTB4MmUsKGJ5dGUpMHg2MywoYnl0ZSkweDZmLChieXRlKTB4NmQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzMCwoYnl0ZSkweDBjLChieXRlKTB4ODYsKGJ5dGUpMHgwYSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDY4LChieXRlKTB4NzQsKGJ5dGUpMHg3NCwoYnl0ZSkweDcwLAorICAgICAgICAgICAgICAgIChieXRlKTB4M2EsKGJ5dGUpMHgyZiwoYnl0ZSkweDJmLChieXRlKTB4NmQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg3NSwoYnl0ZSkweDc1LAorICAgICAgICB9OworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvWDUwOUNSTDJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9YNTA5Q1JMMlRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOTg2MDMyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvWDUwOUNSTDJUZXN0LmphdmEKQEAgLTAsMCArMSwyMjAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMRW50cnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUV4dGVuc2lvbjsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworCitwdWJsaWMgY2xhc3MgWDUwOUNSTDJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBYNTA5Q2VydGlmaWNhdGUgcGVtQ2VydCA9IG51bGw7CisKKyAgICBTdHJpbmcgY2VydGlmaWNhdGUgPSAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICsgIk1JSUQwakNDQXp1Z0F3SUJBZ0lCQWpBTkJna3Foa2lHOXcwQkFRUUZBRENCbWpFTE1Ba0dBMVVFQmhNQ1ZVc3hcbiIKKyAgICAgICAgKyAiRWpBUUJnTlZCQWdUQ1VoaGJYQnphR2x5WlRFVE1CRUdBMVVFQnhNS1YybHVZMmhsYzNSbGNqRVRNQkVHQTFVRVxuIgorICAgICAgICArICJDaE1LU1VKTklGVkxJRXgwWkRFTU1Bb0dBMVVFQ3hNRFNsUkRNUll3RkFZRFZRUURFdzFRWVhWc0lFZ2dRV0ppXG4iCisgICAgICAgICsgImIzUjBNU2N3SlFZSktvWklodmNOQVFrQkZoaFFZWFZzWDBoZlFXSmliM1IwUUhWckxtbGliUzVqYjIwd0hoY05cbiIKKyAgICAgICAgKyAiTURRd05qSXlNakExTURVMVdoY05NRFV3TmpJeU1qQTFNRFUxV2pDQm1ERUxNQWtHQTFVRUJoTUNWVXN4RWpBUVxuIgorICAgICAgICArICJCZ05WQkFnVENVaGhiWEJ6YUdseVpURVRNQkVHQTFVRUJ4TUtWMmx1WTJobGMzUmxjakVUTUJFR0ExVUVDaE1LXG4iCisgICAgICAgICsgIlNVSk5JRlZySUV4MFpERU1NQW9HQTFVRUN4TURTa1ZVTVJRd0VnWURWUVFERXd0UVlYVnNJRUZpWW05MGRERW5cbiIKKyAgICAgICAgKyAiTUNVR0NTcUdTSWIzRFFFSkFSWVlVR0YxYkY5SVgwRmlZbTkwZEVCMWF5NXBZbTB1WTI5dE1JR2ZNQTBHQ1NxR1xuIgorICAgICAgICArICJTSWIzRFFFQkFRVUFBNEdOQURDQmlRS0JnUURpdFpCUTVkMThlY05KcGNudUtUcmFIWXRxc0F1Z29jOTUvTDVRXG4iCisgICAgICAgICsgIjI4czN0MVFBdTI1MDVxUVIxTVphQWtZN3RETnlsMXZQblpveW0rWTA2VXN3VHJab1ZZby9nUE5leVdQTVRzTEFcbiIKKyAgICAgICAgKyAid3pRdms1LzZ5aHRFOWNpSDdCMFNxWXc2dVNpRFRiVVkvelE2cWVkK1RzUWhqbGJuM1BVSFJqbkkyUDhBMDRjZ1xuIgorICAgICAgICArICJMZ1lZR1FJREFRQUJvNElCSmpDQ0FTSXdDUVlEVlIwVEJBSXdBREFzQmdsZ2hrZ0JodmhDQVEwRUh4WWRUM0JsXG4iCisgICAgICAgICsgImJsTlRUQ0JIWlc1bGNtRjBaV1FnUTJWeWRHbG1hV05oZEdVd0hRWURWUjBPQkJZRUZQcGxSUHM2NWhVZnhVQnNcbiIKKyAgICAgICAgKyAiNi9UYXE3bk44aTFVTUlISEJnTlZIU01FZ2I4d2dieUFGSk9NdFBBd2xYZFpMcUU3REtVNnhwTDZGakZ0b1lHZ1xuIgorICAgICAgICArICJwSUdkTUlHYU1Rc3dDUVlEVlFRR0V3SlZTekVTTUJBR0ExVUVDQk1KU0dGdGNITm9hWEpsTVJNd0VRWURWUVFIXG4iCisgICAgICAgICsgIkV3cFhhVzVqYUdWemRHVnlNUk13RVFZRFZRUUtFd3BKUWswZ1ZVc2dUSFJrTVF3d0NnWURWUVFMRXdOS1ZFTXhcbiIKKyAgICAgICAgKyAiRmpBVUJnTlZCQU1URFZCaGRXd2dTQ0JCWW1KdmRIUXhKekFsQmdrcWhraUc5dzBCQ1FFV0dGQmhkV3hmU0Y5QlxuIgorICAgICAgICArICJZbUp2ZEhSQWRXc3VhV0p0TG1OdmJZSUJBREFOQmdrcWhraUc5dzBCQVFRRkFBT0JnUUFuUTIySncySFVyejdjXG4iCisgICAgICAgICsgIlZhT2FwMzFtVGlrdVEvQ1F4cHdQWWlTeVRKNHM5OWVFem4rMnlBazl0SURJSnBxb2F5L2ZqK09MZ1BVUUtJQW9cbiIKKyAgICAgICAgKyAiWHBSVnZtSGxHRTdVcU1LZWJadFNaSlF6czZWb2VlS0ZoZ0htcWc4ZVZDMkFzVGM0WnN3Sm1nNHdDdWk1QUgzYVxuIgorICAgICAgICArICJvcUc3UElNM0x4WnFYWVFsWmlQU1o2a0NwRE9XVmc9PVxuIgorICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iOworCisKKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGNlcnRBcnJheSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShjZXJ0aWZpY2F0ZQorICAgICAgICAgICAgICAgIC5nZXRCeXRlcygpKTsKKworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2VydEZhY3QgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlg1MDkiKTsKKyAgICAgICAgcGVtQ2VydCA9IChYNTA5Q2VydGlmaWNhdGUpIGNlcnRGYWN0LmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNSTCNnZXRFeHRlbnNpb25WYWx1ZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RXh0ZW5zaW9uVmFsdWVMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNldFVwKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gIiArIGUgKyAiIHdhcyB0aHJvd24gZHVyaW5nIGNvbmZpZ2FyYXRpb24iKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocGVtQ2VydCAhPSBudWxsKSB7CisgICAgICAgICAgICBWZWN0b3I8U3RyaW5nPiBleHRlbnNpb25PaWRzID0gbmV3IFZlY3RvcjxTdHJpbmc+KCk7CisgICAgICAgICAgICBleHRlbnNpb25PaWRzLmFkZEFsbChwZW1DZXJ0LmdldENyaXRpY2FsRXh0ZW5zaW9uT0lEcygpKTsKKyAgICAgICAgICAgIGV4dGVuc2lvbk9pZHMuYWRkQWxsKHBlbUNlcnQuZ2V0Tm9uQ3JpdGljYWxFeHRlbnNpb25PSURzKCkpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UocGVtQ2VydC5oYXNVbnN1cHBvcnRlZENyaXRpY2FsRXh0ZW5zaW9uKCkpOworICAgICAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBpID0gZXh0ZW5zaW9uT2lkcy5pdGVyYXRvcigpOworICAgICAgICAgICAgd2hpbGUgKGkuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIG9pZCA9IGkubmV4dCgpOworICAgICAgICAgICAgICAgIGJ5dGVbXSB2YWx1ZSA9IHBlbUNlcnQuZ2V0RXh0ZW5zaW9uVmFsdWUob2lkKTsKKyAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCAmJiB2YWx1ZS5sZW5ndGggPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgaXQgaXMgYW4gZW5jb2RlZCBhcyBhIE9DVEVUIFNUUklORworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJUaGUgZXh0ZW5zaW9uIHZhbHVlIGZvciB0aGUgb2lkICIgKyBvaWQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgd2FzIG5vdCBlbmNvZGVkIGFzIGFuIE9DVEVUIFNUUklORyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVbMF0gPT0gMHgwNCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfS8vIGVuZCB3aGlsZQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmFpbCgiVW5hYmxlIHRvIG9idGFpbiBYNTA5Q2VydGlmaWNhdGUiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMI1g1MDlDUkwoKQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJjYXN0IikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1g1MDlDUkwoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNeVg1MDlDUkwgY3JsID0gbmV3IE15WDUwOUNSTCgpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChjcmwpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShjcmwgaW5zdGFuY2VvZiBYNTA5Q1JMKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIGZvciBjb25zdHJ1Y3RvciIpOworICAgICAgICB9CisgICAgfQorCisgICAgY2xhc3MgTXlYNTA5Q1JMIGV4dGVuZHMgWDUwOUNSTCBpbXBsZW1lbnRzIFg1MDlFeHRlbnNpb24geworCisgICAgICAgIHB1YmxpYyBNeVg1MDlDUkwoKSB7CisgICAgICAgICAgICBzdXBlcigpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0SXNzdWVyRE4oKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgRGF0ZSBnZXROZXh0VXBkYXRlKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFg1MDlDUkxFbnRyeSBnZXRSZXZva2VkQ2VydGlmaWNhdGUoQmlnSW50ZWdlciBzZXJpYWxOdW1iZXIpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTZXQ8PyBleHRlbmRzIFg1MDlDUkxFbnRyeT4gZ2V0UmV2b2tlZENlcnRpZmljYXRlcygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2lnQWxnTmFtZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2lnQWxnT0lEKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRTaWdBbGdQYXJhbXMoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldFNpZ25hdHVyZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0VEJTQ2VydExpc3QoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgRGF0ZSBnZXRUaGlzVXBkYXRlKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBnZXRWZXJzaW9uKCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgdmVyaWZ5KFB1YmxpY0tleSBrZXkpIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCB2ZXJpZnkoUHVibGljS2V5IGtleSwgU3RyaW5nIHNpZ1Byb3ZpZGVyKSB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNSZXZva2VkKENlcnRpZmljYXRlIGNlcnQpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU2V0PFN0cmluZz4gZ2V0Q3JpdGljYWxFeHRlbnNpb25PSURzKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEV4dGVuc2lvblZhbHVlKFN0cmluZyBvaWQpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFNldDxTdHJpbmc+IGdldE5vbkNyaXRpY2FsRXh0ZW5zaW9uT0lEcygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzVW5zdXBwb3J0ZWRDcml0aWNhbEV4dGVuc2lvbigpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvWDUwOUNSTEVudHJ5VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2NlcnQvWDUwOUNSTEVudHJ5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYxNmNhZmYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9YNTA5Q1JMRW50cnlUZXN0LmphdmEKQEAgLTAsMCArMSwyMDggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhhbmRlciBZLiBLbGV5bWVub3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ1JMRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMRW50cnk7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworLyoqCisgKi8KK3B1YmxpYyBjbGFzcyBYNTA5Q1JMRW50cnlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgWDUwOUNSTEVudHJ5IHRidF9jcmxlbnRyeTsKKworICAgIC8qKgorICAgICAqIFRoZSBzdHViIGNsYXNzIHVzZWQgZm9yIHRlc3Rpbmcgb2Ygbm9uIGFic3RyYWN0IG1ldGhvZHMuCisgICAgICovCisgICAgcHJpdmF0ZSBjbGFzcyBUQlRDUkxFbnRyeSBleHRlbmRzIFg1MDlDUkxFbnRyeSB7CisgICAgICAgIHB1YmxpYyBUQlRDUkxFbnRyeSgpIHsKKyAgICAgICAgICAgIHN1cGVyKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU2V0PFN0cmluZz4gZ2V0Tm9uQ3JpdGljYWxFeHRlbnNpb25PSURzKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU2V0PFN0cmluZz4gZ2V0Q3JpdGljYWxFeHRlbnNpb25PSURzKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEV4dGVuc2lvblZhbHVlKFN0cmluZyBvaWQpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzVW5zdXBwb3J0ZWRDcml0aWNhbEV4dGVuc2lvbigpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHRocm93cyBDUkxFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRTZXJpYWxOdW1iZXIoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBEYXRlIGdldFJldm9jYXRpb25EYXRlKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNFeHRlbnNpb25zKCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFg1MDlDUkxFbnRyeVRlc3QoKSB7CisgICAgICAgIHRidF9jcmxlbnRyeSA9IG5ldyBUQlRDUkxFbnRyeSgpIHsKKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHRocm93cyBDUkxFeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVtdIHsxLCAyLCAzfTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBYNTA5Q1JMRW50cnkoKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgZm9yIGNyZWF0aW5nIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0WDUwOUNSTEVudHJ5KCkgeworICAgICAgICBUQlRDUkxFbnRyeSB0YnRfY3JsZW50cnkgPSBuZXcgVEJUQ1JMRW50cnkoKTsKKworICAgICAgICBhc3NlcnROdWxsKHRidF9jcmxlbnRyeS5nZXRDZXJ0aWZpY2F0ZUlzc3VlcigpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCh0YnRfY3JsZW50cnkuZ2V0Q3JpdGljYWxFeHRlbnNpb25PSURzKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbCh0YnRfY3JsZW50cnkuZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgfSBjYXRjaCAoQ1JMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0TnVsbCh0YnRfY3JsZW50cnkuZ2V0Tm9uQ3JpdGljYWxFeHRlbnNpb25PSURzKCkpOworICAgICAgICBhc3NlcnROdWxsKHRidF9jcmxlbnRyeS5nZXRSZXZvY2F0aW9uRGF0ZSgpKTsKKworICAgIH0KKworICAgIC8qKgorICAgICAqIGVxdWFscyhPYmplY3Qgb3RoZXIpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGUgY29ycmVjdG5lc3Mgb2YgZXF1YWwKKyAgICAgKiBvcGVyYXRpb246IGl0IHNob3VsZCBiZSByZWZsZXhpdmUsIHN5bW1ldHJpYywgdHJhbnNpdGl2ZSwgY29uc2lzdGVudAorICAgICAqIGFuZCBzaG91bGQgYmUgZmFsc2Ugb24gbnVsbCBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEVxdWFscygpIHsKKyAgICAgICAgVEJUQ1JMRW50cnkgdGJ0X2NybGVudHJ5XzEgPSBuZXcgVEJUQ1JMRW50cnkoKSB7CisgICAgICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBieXRlW10gezEsIDIsIDN9OworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIFRCVENSTEVudHJ5IHRidF9jcmxlbnRyeV8yID0gbmV3IFRCVENSTEVudHJ5KCkgeworICAgICAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVtdIHsxLCAyLCAzfTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBUQlRDUkxFbnRyeSB0YnRfY3JsZW50cnlfMyA9IG5ldyBUQlRDUkxFbnRyeSgpIHsKKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7MywgMiwgMX07CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgLy8gY2hlY2tpbmcgZm9yIHJlZmxleGl2ZSBsYXc6CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBlcXVpdmFsZW5jZSByZWxhdGlvbiBzaG91bGQgYmUgcmVmbGV4aXZlLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRidF9jcmxlbnRyeS5lcXVhbHModGJ0X2NybGVudHJ5KSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgQ1JMIEVudHJpZXMgd2l0aCBlcXVhbHMgZW5jb2RlZCBmb3JtIHNob3VsZCBiZSBlcXVhbCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRidF9jcmxlbnRyeSwgdGJ0X2NybGVudHJ5XzEpOworICAgICAgICAvLyBjaGVja2luZyBmb3Igc3ltbWV0cmljIGxhdzoKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGVxdWl2YWxlbmNlIHJlbGF0aW9uIHNob3VsZCBiZSBzeW1tZXRyaWMuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJ0X2NybGVudHJ5XzEuZXF1YWxzKHRidF9jcmxlbnRyeSkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiVGhlIENSTCBFbnRyaWVzIHdpdGggZXF1YWxzIGVuY29kZWQgZm9ybSBzaG91bGQgYmUgZXF1YWwiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YnRfY3JsZW50cnlfMSwgdGJ0X2NybGVudHJ5XzIpOworICAgICAgICAvLyBjaGVja2luZyBmb3IgdHJhbnNpdGl2ZSBsYXc6CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBlcXVpdmFsZW5jZSByZWxhdGlvbiBzaG91bGQgYmUgdHJhbnNpdGl2ZS4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YnRfY3JsZW50cnkuZXF1YWxzKHRidF9jcmxlbnRyeV8yKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlNob3VsZCBub3QgYmUgZXF1YWwgdG8gbnVsbCBvYmplY3QuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJ0X2NybGVudHJ5LmVxdWFscyhudWxsKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBDUkwgRW50cmllcyB3aXRoIGRpZmZlcmluZyBlbmNvZGVkIGZvcm0gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJzaG91bGQgbm90IGJlIGVxdWFsLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRidF9jcmxlbnRyeS5lcXVhbHModGJ0X2NybGVudHJ5XzMpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBDUkwgRW50cmllcyBzaG91bGQgbm90IGJlIGVxdWFscyB0byB0aGUgb2JqZWN0ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAid2hpY2ggaXMgbm90IGFuIGluc3RhbmNlIG9mIFg1MDlDUkxFbnRyeS4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YnRfY3JsZW50cnkuZXF1YWxzKG5ldyBPYmplY3QoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGhhc2hDb2RlKCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIHRoYXQgZm9yIGVxdWFsIG9iamVjdHMgaGFzaCBjb2RlcworICAgICAqIGFyZSBlcXVhbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzaENvZGUoKSB7CisgICAgICAgIFRCVENSTEVudHJ5IHRidF9jcmxlbnRyeV8xID0gbmV3IFRCVENSTEVudHJ5KCkgeworICAgICAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVtdIHsxLCAyLCAzfTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRXF1YWwgb2JqZWN0cyBzaG91bGQgaGF2ZSB0aGUgc2FtZSBoYXNoIGNvZGVzLiIsCisgICAgICAgICAgICAgICAgICAgICAgICB0YnRfY3JsZW50cnkuaGFzaENvZGUoKSA9PSB0YnRfY3JsZW50cnlfMS5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRDZXJ0aWZpY2F0ZUlzc3VlcigpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyBpZiB0aGUgbWV0aG9kIHRocm93cworICAgICAqIGFwcHJvcHJpYXRlIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q2VydGlmaWNhdGVJc3N1ZXIoKSB7CisgICAgICAgIGFzc2VydE51bGwoIlRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHNob3VsZCByZXR1cm4gbnVsbC4iLAorICAgICAgICAgICAgICAgIHRidF9jcmxlbnRyeS5nZXRDZXJ0aWZpY2F0ZUlzc3VlcigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWJzdHJhY3RNZXRob2RzKCkgeworICAgICAgICBUQlRDUkxFbnRyeSB0YnQgPSBuZXcgVEJUQ1JMRW50cnkoKSB7CisgICAgICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBieXRlW10gezEsIDIsIDN9OworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0YnQuZ2V0RW5jb2RlZCgpOworICAgICAgICAgICAgdGJ0LmdldFJldm9jYXRpb25EYXRlKCk7CisgICAgICAgICAgICB0YnQuZ2V0U2VyaWFsTnVtYmVyKCk7CisgICAgICAgICAgICB0YnQuaGFzRXh0ZW5zaW9ucygpOworICAgICAgICAgICAgdGJ0LnRvU3RyaW5nKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBUZXN0IHN1aXRlKCkgeworICAgICAgICByZXR1cm4gbmV3IFRlc3RTdWl0ZShYNTA5Q1JMRW50cnlUZXN0LmNsYXNzKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L1g1MDlDUkxTZWxlY3RvcjJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9YNTA5Q1JMU2VsZWN0b3IyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYyZTgxNGQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9YNTA5Q1JMU2VsZWN0b3IyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjQwIEBACitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5BbmRyb2lkT25seTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFJbnRlZ2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFPY3RldFN0cmluZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0LlRlc3RVdGlsczsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ1JMOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DUkxFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMRW50cnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDUkxTZWxlY3RvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsOworCitwdWJsaWMgY2xhc3MgWDUwOUNSTFNlbGVjdG9yMlRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogY29uc3RydWN0b3IgdGVzdGluZy4KKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RYNTA5Q1JMU2VsZWN0b3IoKSB7CisgICAgICAgIFg1MDlDUkxTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q1JMU2VsZWN0b3IoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChzZWxlY3Rvci5nZXREYXRlQW5kVGltZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChzZWxlY3Rvci5nZXRDZXJ0aWZpY2F0ZUNoZWNraW5nKCkpOworICAgICAgICBhc3NlcnROdWxsKHNlbGVjdG9yLmdldElzc3Vlck5hbWVzKCkpOworICAgICAgICBhc3NlcnROdWxsKHNlbGVjdG9yLmdldElzc3VlcnMoKSk7CisgICAgICAgIGFzc2VydE51bGwoc2VsZWN0b3IuZ2V0TWF4Q1JMKCkpOworICAgICAgICBhc3NlcnROdWxsKHNlbGVjdG9yLmdldE1pbkNSTCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBhZGRJc3N1ZXIoWDUwMFByaW5jaXBhbCBpc3N1ZXIpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyBpZiBDUkxzIHdpdGgKKyAgICAgKiBzcGVjaWZpZWQgaXNzdWVycyBtYXRjaCB0aGUgc2VsZWN0b3IsIGFuZCBpZiBub3Qgc3BlY2lmaWVkIGlzc3VlciBkb2VzCisgICAgICogbm90IG1hdGNoIHRoZSBzZWxlY3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWRkSXNzdWVyTGphdmF4X3NlY3VyaXR5X2F1dGhfeDUwMF9YNTAwUHJpbmNpcGFsMDIoKSB7CisgICAgICAgIFg1MDlDUkxTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q1JMU2VsZWN0b3IoKTsKKyAgICAgICAgWDUwMFByaW5jaXBhbCBpc3MxID0gbmV3IFg1MDBQcmluY2lwYWwoIk89Rmlyc3QgT3JnLiIpOworICAgICAgICBYNTAwUHJpbmNpcGFsIGlzczIgPSBuZXcgWDUwMFByaW5jaXBhbCgiTz1TZWNvbmQgT3JnLiIpOworICAgICAgICBDUkwgY3JsMSA9IG5ldyBUZXN0Q1JMKGlzczEpOworICAgICAgICBDUkwgY3JsMiA9IG5ldyBUZXN0Q1JMKGlzczIpOworCisgICAgICAgIHNlbGVjdG9yLmFkZElzc3Vlcihpc3MxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIENSTCBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLCBzZWxlY3RvcgorICAgICAgICAgICAgICAgIC5tYXRjaChjcmwxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgQ1JMIHNob3VsZCBub3QgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNybDIpKTsKKyAgICAgICAgc2VsZWN0b3IuYWRkSXNzdWVyKGlzczIpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgQ1JMIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsIHNlbGVjdG9yCisgICAgICAgICAgICAgICAgLm1hdGNoKGNybDIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBhZGRJc3N1ZXJOYW1lKFN0cmluZyBuYW1lKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgaWYgQ1JMcyB3aXRoIHNwZWNpZmllZAorICAgICAqIGlzc3VlcnMgbWF0Y2ggdGhlIHNlbGVjdG9yLCBhbmQgaWYgbm90IHNwZWNpZmllZCBpc3N1ZXIgZG9lcyBub3QgbWF0Y2gKKyAgICAgKiB0aGUgc2VsZWN0b3IuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEFkZElzc3Vlck5hbWVMamF2YV9sYW5nX1N0cmluZzAzKCkgeworICAgICAgICBYNTA5Q1JMU2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNSTFNlbGVjdG9yKCk7CisgICAgICAgIFN0cmluZyBpc3MxID0gIk89Rmlyc3QgT3JnLiI7CisgICAgICAgIFN0cmluZyBpc3MyID0gIk89U2Vjb25kIE9yZy4iOworICAgICAgICBUZXN0Q1JMIGNybDEgPSBuZXcgVGVzdENSTChuZXcgWDUwMFByaW5jaXBhbChpc3MxKSk7CisgICAgICAgIFRlc3RDUkwgY3JsMiA9IG5ldyBUZXN0Q1JMKG5ldyBYNTAwUHJpbmNpcGFsKGlzczIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VsZWN0b3IuYWRkSXNzdWVyTmFtZShpc3MxKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgQ1JMIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsIHNlbGVjdG9yCisgICAgICAgICAgICAgICAgLm1hdGNoKGNybDEpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBDUkwgc2hvdWxkIG5vdCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY3JsMikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VsZWN0b3IuYWRkSXNzdWVyTmFtZShpc3MyKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgQ1JMIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsIHNlbGVjdG9yCisgICAgICAgICAgICAgICAgLm1hdGNoKGNybDIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBzZXRJc3N1ZXJOYW1lcyhDb2xsZWN0aW9uIDw/PiBuYW1lcykgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIGlmIENSTHMgd2l0aAorICAgICAqIGFueSBpc3N1ZXJzIG1hdGNoIHRoZSBzZWxlY3RvciBpbiB0aGUgY2FzZSBvZiBudWxsIGlzc3Vlck5hbWVzIGNyaXRlcmlhLAorICAgICAqIGlmIHNwZWNpZmllZCBpc3N1ZXJzIG1hdGNoIHRoZSBzZWxlY3RvciwgaWYgbm90IHNwZWNpZmllZCBpc3N1ZXIgZG9lcyBub3QKKyAgICAgKiBtYXRjaCB0aGUgc2VsZWN0b3IsIGFuZCBpZiB0aGUgaW50ZXJuYWwgY29sbGVjdGlvbiBvZiBpc3N1ZXIgbmFtZXMgaXMKKyAgICAgKiBjb3BpZWQgZHVyaW5nIGluaXRpYWxpemF0aW9uLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRJc3N1ZXJOYW1lc0xqYXZhX3V0aWxfQ29sbGVjdGlvbjAyKCkgeworICAgICAgICBYNTA5Q1JMU2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNSTFNlbGVjdG9yKCk7CisgICAgICAgIFN0cmluZyBpc3MxID0gIk89Rmlyc3QgT3JnLiI7CisgICAgICAgIGJ5dGVbXSBpc3MyID0gbmV3IGJ5dGVbXQorICAgICAgICAvLyBtYW51YWxseSBvYnRhaW5lZCBERVIgZW5jb2Rpbmcgb2YgIk89U2Vjb25kIE9yZy4iIGlzc3VlciBuYW1lOworICAgICAgICB7IDQ4LCAyMiwgNDksIDIwLCA0OCwgMTgsIDYsIDMsIDg1LCA0LCAxMCwgMTksIDExLCA4MywgMTAxLCA5OSwgMTExLAorICAgICAgICAgICAgICAgIDExMCwgMTAwLCAzMiwgNzksIDExNCwgMTAzLCA0NiB9OworCisgICAgICAgIFN0cmluZyBpc3MzID0gIk89VGhpcmQgT3JnLiI7CisgICAgICAgIFRlc3RDUkwgY3JsMSA9IG5ldyBUZXN0Q1JMKG5ldyBYNTAwUHJpbmNpcGFsKGlzczEpKTsKKyAgICAgICAgVGVzdENSTCBjcmwyID0gbmV3IFRlc3RDUkwobmV3IFg1MDBQcmluY2lwYWwoaXNzMikpOworICAgICAgICBUZXN0Q1JMIGNybDMgPSBuZXcgVGVzdENSTChuZXcgWDUwMFByaW5jaXBhbChpc3MzKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlbGVjdG9yLnNldElzc3Vlck5hbWVzKG51bGwpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkFueSBDUkwgaXNzdWVycyBzaG91bGQgbWF0Y2ggaW4gdGhlIGNhc2Ugb2YgbnVsbCBpc3N1ZXJzLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY3JsMSkgJiYgc2VsZWN0b3IubWF0Y2goY3JsMikpOworCisgICAgICAgIEFycmF5TGlzdCBpc3N1ZXJzID0gbmV3IEFycmF5TGlzdCgyKTsKKyAgICAgICAgaXNzdWVycy5hZGQoaXNzMSk7CisgICAgICAgIGlzc3VlcnMuYWRkKGlzczIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0SXNzdWVyTmFtZXMoaXNzdWVycyk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIENSTCBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLCBzZWxlY3RvcgorICAgICAgICAgICAgICAgIC5tYXRjaChjcmwxKQorICAgICAgICAgICAgICAgICYmIHNlbGVjdG9yLm1hdGNoKGNybDIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBDUkwgc2hvdWxkIG5vdCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY3JsMykpOworICAgICAgICBpc3N1ZXJzLmFkZChpc3MzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBpbnRlcm5hbCBpc3N1ZXIgY29sbGVjdGlvbiBpcyBub3QgcHJvdGVjdGVkICIKKyAgICAgICAgICAgICAgICArICJhZ2FpbnN0IHRoZSBtb2RpZmljYXRpb25zLiIsIHNlbGVjdG9yLm1hdGNoKGNybDMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBzZXRJc3N1ZXJzKENvbGxlY3Rpb24gPFg1MDBQcmluY2lwYWw+IGlzc3VlcnMpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyBpZgorICAgICAqIENSTHMgd2l0aCBhbnkgaXNzdWVycyBtYXRjaCB0aGUgc2VsZWN0b3IgaW4gdGhlIGNhc2Ugb2YgbnVsbCBpc3N1ZXJOYW1lcworICAgICAqIGNyaXRlcmlhLCBpZiBzcGVjaWZpZWQgaXNzdWVycyBtYXRjaCB0aGUgc2VsZWN0b3IsIGFuZCBpZiBub3Qgc3BlY2lmaWVkCisgICAgICogaXNzdWVyIGRvZXMgbm90IG1hdGNoIHRoZSBzZWxlY3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0SXNzdWVyc0xqYXZhX3V0aWxfQ29sbGVjdGlvbigpIHsKKyAgICAgICAgWDUwOUNSTFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDUkxTZWxlY3RvcigpOworICAgICAgICBYNTAwUHJpbmNpcGFsIGlzczEgPSBuZXcgWDUwMFByaW5jaXBhbCgiTz1GaXJzdCBPcmcuIik7CisgICAgICAgIFg1MDBQcmluY2lwYWwgaXNzMiA9IG5ldyBYNTAwUHJpbmNpcGFsKCJPPVNlY29uZCBPcmcuIik7CisgICAgICAgIFg1MDBQcmluY2lwYWwgaXNzMyA9IG5ldyBYNTAwUHJpbmNpcGFsKCJPPVRoaXJkIE9yZy4iKTsKKyAgICAgICAgVGVzdENSTCBjcmwxID0gbmV3IFRlc3RDUkwoaXNzMSk7CisgICAgICAgIFRlc3RDUkwgY3JsMiA9IG5ldyBUZXN0Q1JMKGlzczIpOworICAgICAgICBUZXN0Q1JMIGNybDMgPSBuZXcgVGVzdENSTChpc3MzKTsKKworICAgICAgICBzZWxlY3Rvci5zZXRJc3N1ZXJzKG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJBbnkgQ1JMIGlzc3VlcnMgc2hvdWxkIG1hdGNoIGluIHRoZSBjYXNlIG9mIG51bGwgaXNzdWVycy4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNybDEpICYmIHNlbGVjdG9yLm1hdGNoKGNybDIpKTsKKworICAgICAgICBBcnJheUxpc3Q8WDUwMFByaW5jaXBhbD4gaXNzdWVycyA9IG5ldyBBcnJheUxpc3Q8WDUwMFByaW5jaXBhbD4oMik7CisgICAgICAgIGlzc3VlcnMuYWRkKGlzczEpOworICAgICAgICBpc3N1ZXJzLmFkZChpc3MyKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0SXNzdWVycyhpc3N1ZXJzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIENSTCBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLCBzZWxlY3RvcgorICAgICAgICAgICAgICAgIC5tYXRjaChjcmwxKQorICAgICAgICAgICAgICAgICYmIHNlbGVjdG9yLm1hdGNoKGNybDIpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBDUkwgc2hvdWxkIG5vdCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY3JsMykpOworICAgICAgICBpc3N1ZXJzLmFkZChpc3MzKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBpbnRlcm5hbCBpc3N1ZXIgY29sbGVjdGlvbiBpcyBub3QgcHJvdGVjdGVkICIKKyAgICAgICAgICAgICAgICArICJhZ2FpbnN0IHRoZSBtb2RpZmljYXRpb25zLiIsIHNlbGVjdG9yLm1hdGNoKGNybDMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBhZGRJc3N1ZXJOYW1lKGJ5dGVbXSBuYW1lKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgaWYgQ1JMcyB3aXRoIHNwZWNpZmllZAorICAgICAqIGlzc3VlcnMgbWF0Y2ggdGhlIHNlbGVjdG9yLCBhbmQgaWYgbm90IHNwZWNpZmllZCBpc3N1ZXIgZG9lcyBub3QgbWF0Y2gKKyAgICAgKiB0aGUgc2VsZWN0b3IuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEFkZElzc3Vlck5hbWUkQigpIHsKKyAgICAgICAgWDUwOUNSTFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDUkxTZWxlY3RvcigpOworICAgICAgICBieXRlW10gaXNzMSA9IG5ldyBieXRlW10KKyAgICAgICAgLy8gbWFudWFsbHkgb2J0YWluZWQgREVSIGVuY29kaW5nIG9mICJPPUZpcnN0IE9yZy4iIGlzc3VlciBuYW1lOworICAgICAgICB7IDQ4LCAyMSwgNDksIDE5LCA0OCwgMTcsIDYsIDMsIDg1LCA0LCAxMCwgMTksIDEwLCA3MCwgMTA1LCAxMTQsIDExNSwKKyAgICAgICAgICAgICAgICAxMTYsIDMyLCA3OSwgMTE0LCAxMDMsIDQ2IH07CisgICAgICAgIGJ5dGVbXSBpc3MyID0gbmV3IGJ5dGVbXQorICAgICAgICAvLyBtYW51YWxseSBvYnRhaW5lZCBERVIgZW5jb2Rpbmcgb2YgIk89U2Vjb25kIE9yZy4iIGlzc3VlciBuYW1lOworICAgICAgICB7IDQ4LCAyMiwgNDksIDIwLCA0OCwgMTgsIDYsIDMsIDg1LCA0LCAxMCwgMTksIDExLCA4MywgMTAxLCA5OSwgMTExLAorICAgICAgICAgICAgICAgIDExMCwgMTAwLCAzMiwgNzksIDExNCwgMTAzLCA0NiB9OworICAgICAgICBUZXN0Q1JMIGNybDEgPSBuZXcgVGVzdENSTChuZXcgWDUwMFByaW5jaXBhbChpc3MxKSk7CisgICAgICAgIFRlc3RDUkwgY3JsMiA9IG5ldyBUZXN0Q1JMKG5ldyBYNTAwUHJpbmNpcGFsKGlzczIpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VsZWN0b3IuYWRkSXNzdWVyTmFtZShpc3MxKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgQ1JMIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsIHNlbGVjdG9yCisgICAgICAgICAgICAgICAgLm1hdGNoKGNybDEpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBDUkwgc2hvdWxkIG5vdCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY3JsMikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VsZWN0b3IuYWRkSXNzdWVyTmFtZShpc3MyKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgQ1JMIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsIHNlbGVjdG9yCisgICAgICAgICAgICAgICAgLm1hdGNoKGNybDIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBzZXRNaW5DUkxOdW1iZXIoQmlnSW50ZWdlciBtaW5DUkwpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyBpZiBDUkxzIHdpdGggYW55CisgICAgICogY3JsIG51bWJlciB2YWx1ZSBtYXRjaCB0aGUgc2VsZWN0b3IgaW4gdGhlIGNhc2Ugb2YgbnVsbCBjcmxOdW1iZXIKKyAgICAgKiBjcml0ZXJpYSwgaWYgc3BlY2lmaWVkIG1pbkNSTCB2YWx1ZSBtYXRjaGVzIHRoZSBzZWxlY3RvciwgYW5kIGlmIENSTCB3aXRoCisgICAgICogaW5hcHByb3ByaWF0ZSBjcmxOdW1iZXIgdmFsdWUgZG9lcyBub3QgbWF0Y2ggdGhlIHNlbGVjdG9yLgorICAgICAqLworICAgIEBBbmRyb2lkT25seSgiVXNlcyBzcGVjaWZpYyBjbGFzczogIiArCisgICAgICAgICAgICAib3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMU9jdGV0U3RyaW5nLiIpCisgICAgcHVibGljIHZvaWQgdGVzdFNldE1pbkNSTE51bWJlckxqYXZhX21hdGhfQmlnSW50ZWdlcigpIHsKKyAgICAgICAgWDUwOUNSTFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDUkxTZWxlY3RvcigpOworICAgICAgICBCaWdJbnRlZ2VyIG1pbkNSTCA9IG5ldyBCaWdJbnRlZ2VyKCIxMDAwMCIpOworICAgICAgICBDUkwgY3JsID0gbmV3IFRlc3RDUkwobWluQ1JMKTsKKworICAgICAgICBzZWxlY3Rvci5zZXRNaW5DUkxOdW1iZXIobnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoIkFueSBDUkwgc2hvdWxkIG1hdGNoIGluIHRoZSBjYXNlIG9mIG51bGwgbWluQ1JMTnVtYmVyLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY3JsKSk7CisgICAgICAgIHNlbGVjdG9yLnNldE1pbkNSTE51bWJlcihtaW5DUkwpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgQ1JMIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsIHNlbGVjdG9yCisgICAgICAgICAgICAgICAgLm1hdGNoKGNybCkpOworICAgICAgICBzZWxlY3Rvci5zZXRNaW5DUkxOdW1iZXIobmV3IEJpZ0ludGVnZXIoIjEwMDAxIikpOworICAgICAgICBhc3NlcnRGYWxzZSgiVGhlIENSTCBzaG91bGQgbm90IG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjcmwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBzZXRNYXhDUkxOdW1iZXIoQmlnSW50ZWdlciBtYXhDUkwpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyBpZiBDUkxzIHdpdGggYW55CisgICAgICogY3JsIG51bWJlciB2YWx1ZSBtYXRjaCB0aGUgc2VsZWN0b3IgaW4gdGhlIGNhc2Ugb2YgbnVsbCBjcmxOdW1iZXIKKyAgICAgKiBjcml0ZXJpYSwgaWYgc3BlY2lmaWVkIG1heENSTCB2YWx1ZSBtYXRjaGVzIHRoZSBzZWxlY3RvciwgYW5kIGlmIENSTCB3aXRoCisgICAgICogaW5hcHByb3ByaWF0ZSBjcmxOdW1iZXIgdmFsdWUgZG9lcyBub3QgbWF0Y2ggdGhlIHNlbGVjdG9yLgorICAgICAqLworICAgIEBBbmRyb2lkT25seSgiVXNlcyBzcGVjaWZpYyBjbGFzczogIiArCisgICAgICAgICAgICAib3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMU9jdGV0U3RyaW5nLiIpCisgICAgcHVibGljIHZvaWQgdGVzdFNldE1heENSTE51bWJlckxqYXZhX21hdGhfQmlnSW50ZWdlcigpIHsKKyAgICAgICAgWDUwOUNSTFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDUkxTZWxlY3RvcigpOworICAgICAgICBCaWdJbnRlZ2VyIG1heENSTCA9IG5ldyBCaWdJbnRlZ2VyKCIxMDAwMCIpOworICAgICAgICBUZXN0Q1JMIGNybCA9IG5ldyBUZXN0Q1JMKG1heENSTCk7CisKKyAgICAgICAgc2VsZWN0b3Iuc2V0TWF4Q1JMTnVtYmVyKG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJBbnkgQ1JMIHNob3VsZCBtYXRjaCBpbiB0aGUgY2FzZSBvZiBudWxsIG1pbkNSTE51bWJlci4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNybCkpOworICAgICAgICBzZWxlY3Rvci5zZXRNYXhDUkxOdW1iZXIobWF4Q1JMKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIENSTCBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLCBzZWxlY3RvcgorICAgICAgICAgICAgICAgIC5tYXRjaChjcmwpKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0TWF4Q1JMTnVtYmVyKG5ldyBCaWdJbnRlZ2VyKCI5OTk5IikpOworICAgICAgICBhc3NlcnRGYWxzZSgiVGhlIENSTCBzaG91bGQgbm90IG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjcmwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBzZXREYXRlQW5kVGltZShEYXRlIGRhdGVBbmRUaW1lKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgaWYgQ1JMcyB3aXRoIGFueQorICAgICAqIHVwZGF0ZSBkYXRlcyBtYXRjaCB0aGUgc2VsZWN0b3IgaW4gdGhlIGNhc2Ugb2YgbnVsbCBkYXRlQW5kVGltZSBjcml0ZXJpYSwKKyAgICAgKiBpZiBjb3JyZWN0IGRhdGVzIG1hdGNoIGFuZCBpbmNvcnJlY3QgZG8gbm90IG1hdGNoIHRoZSBzZWxlY3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0RGF0ZUFuZFRpbWVMamF2YV91dGlsX0RhdGUoKSB7CisgICAgICAgIFg1MDlDUkxTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q1JMU2VsZWN0b3IoKTsKKyAgICAgICAgVGVzdENSTCBjcmwgPSBuZXcgVGVzdENSTChuZXcgRGF0ZSgyMDApLCBuZXcgRGF0ZSgzMDApKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0RGF0ZUFuZFRpbWUobnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoIkFueSBDUkwgc2hvdWxkIG1hdGNoIGluIHRoZSBjYXNlIG9mIG51bGwgZGF0ZUFuZFRpbWUuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjcmwpKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0RGF0ZUFuZFRpbWUobmV3IERhdGUoMjAwKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBDUkwgc2hvdWxkIG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwgc2VsZWN0b3IKKyAgICAgICAgICAgICAgICAubWF0Y2goY3JsKSk7CisgICAgICAgIHNlbGVjdG9yLnNldERhdGVBbmRUaW1lKG5ldyBEYXRlKDI1MCkpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgQ1JMIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsIHNlbGVjdG9yCisgICAgICAgICAgICAgICAgLm1hdGNoKGNybCkpOworICAgICAgICBzZWxlY3Rvci5zZXREYXRlQW5kVGltZShuZXcgRGF0ZSgzMDApKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIENSTCBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLCBzZWxlY3RvcgorICAgICAgICAgICAgICAgIC5tYXRjaChjcmwpKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0RGF0ZUFuZFRpbWUobmV3IERhdGUoMTUwKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgQ1JMIHNob3VsZCBub3QgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNybCkpOworICAgICAgICBzZWxlY3Rvci5zZXREYXRlQW5kVGltZShuZXcgRGF0ZSgzNTApKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBDUkwgc2hvdWxkIG5vdCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY3JsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogc2V0Q2VydGlmaWNhdGVDaGVja2luZyhYNTA5Q2VydGlmaWNhdGUpIG1ldGhvZCB0ZXN0aW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRDZXJ0aWZpY2F0ZUNoZWNraW5nTGphdmFfWDUwOUNlcnRpZmljYXRlKCkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIFg1MDlDUkxTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q1JMU2VsZWN0b3IoKTsKKworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2VydEZhY3QgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlg1MDkiKTsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIGNlcnQgPSAoWDUwOUNlcnRpZmljYXRlKSBjZXJ0RmFjdAorICAgICAgICAgICAgICAgIC5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShUZXN0VXRpbHMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRYNTA5Q2VydGlmaWNhdGVfdjMoKSkpOworCisgICAgICAgIFRlc3RDUkwgY3JsID0gbmV3IFRlc3RDUkwoKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0Q2VydGlmaWNhdGVDaGVja2luZyhjZXJ0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIENSTCBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLCBzZWxlY3RvcgorICAgICAgICAgICAgICAgIC5tYXRjaChjcmwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNlcnQsIHNlbGVjdG9yLmdldENlcnRpZmljYXRlQ2hlY2tpbmcoKSk7CisKKyAgICAgICAgc2VsZWN0b3Iuc2V0Q2VydGlmaWNhdGVDaGVja2luZyhudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIENSTCBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLCBzZWxlY3RvcgorICAgICAgICAgICAgICAgIC5tYXRjaChjcmwpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChzZWxlY3Rvci5nZXRDZXJ0aWZpY2F0ZUNoZWNraW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGdldElzc3VlcnMoKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgaWYgdGhlIG1ldGhvZCByZXR1cm4gbnVsbCBpbiB0aGUgY2FzZQorICAgICAqIG9mIG5vdCBzcGVjaWZpZWQgaXNzdWVycywgaWYgdGhlIHJldHVybmVkIGNvbGxlY3Rpb24gY29ycmVzcG9uZHMgdG8gdGhlCisgICAgICogc3BlY2lmaWVkIGlzc3VlcnMgYW5kIHRoaXMgY29sbGVjdGlvbiBpcyB1bm1vZGlmaWFibGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldElzc3VlcnMoKSB7CisgICAgICAgIFg1MDlDUkxTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q1JMU2VsZWN0b3IoKTsKKyAgICAgICAgWDUwMFByaW5jaXBhbCBpc3MxID0gbmV3IFg1MDBQcmluY2lwYWwoIk89Rmlyc3QgT3JnLiIpOworICAgICAgICBYNTAwUHJpbmNpcGFsIGlzczIgPSBuZXcgWDUwMFByaW5jaXBhbCgiTz1TZWNvbmQgT3JnLiIpOworICAgICAgICBYNTAwUHJpbmNpcGFsIGlzczMgPSBuZXcgWDUwMFByaW5jaXBhbCgiTz1UaGlyZCBPcmcuIik7CisgICAgICAgIGFzc2VydE51bGwoIlRoZSBjb2xsZWN0aW9uIHNob3VsZCBiZSBudWxsLiIsIHNlbGVjdG9yLmdldElzc3VlcnMoKSk7CisgICAgICAgIHNlbGVjdG9yLmFkZElzc3Vlcihpc3MxKTsKKyAgICAgICAgc2VsZWN0b3IuYWRkSXNzdWVyKGlzczIpOworICAgICAgICBDb2xsZWN0aW9uPFg1MDBQcmluY2lwYWw+IHJlc3VsdCA9IHNlbGVjdG9yLmdldElzc3VlcnMoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlc3VsdC5hZGQoaXNzMyk7CisgICAgICAgICAgICBmYWlsKCJUaGUgcmV0dXJuZWQgY29sbGVjdGlvbiBzaG91bGQgYmUgdW5tb2RpZmlhYmxlLiIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGNvbGxlY3Rpb24gc2hvdWxkIGNvbnRhaW4gdGhlIHNwZWNpZmllZCBETi4iLCByZXN1bHQKKyAgICAgICAgICAgICAgICAuY29udGFpbnMoaXNzMikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGdldElzc3Vlck5hbWVzKCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIGlmIHRoZSBtZXRob2QgcmV0dXJuIG51bGwgaW4gdGhlCisgICAgICogY2FzZSBvZiBub3Qgc3BlY2lmaWVkIGlzc3VlcnMsIGlmIHRoZSByZXR1cm5lZCBjb2xsZWN0aW9uIGNvcnJlc3BvbmRzIHRvCisgICAgICogdGhlIHNwZWNpZmllZCBpc3N1ZXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJc3N1ZXJOYW1lcygpIHsKKyAgICAgICAgWDUwOUNSTFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDUkxTZWxlY3RvcigpOworICAgICAgICBieXRlW10gaXNzMSA9IG5ldyBieXRlW10KKyAgICAgICAgLy8gbWFudWFsbHkgb2J0YWluZWQgREVSIGVuY29kaW5nIG9mICJPPUZpcnN0IE9yZy4iIGlzc3VlciBuYW1lOworICAgICAgICB7IDQ4LCAyMSwgNDksIDE5LCA0OCwgMTcsIDYsIDMsIDg1LCA0LCAxMCwgMTksIDEwLCA3MCwgMTA1LCAxMTQsIDExNSwKKyAgICAgICAgICAgICAgICAxMTYsIDMyLCA3OSwgMTE0LCAxMDMsIDQ2IH07CisgICAgICAgIGJ5dGVbXSBpc3MyID0gbmV3IGJ5dGVbXQorICAgICAgICAvLyBtYW51YWxseSBvYnRhaW5lZCBERVIgZW5jb2Rpbmcgb2YgIk89U2Vjb25kIE9yZy4iIGlzc3VlciBuYW1lOworICAgICAgICB7IDQ4LCAyMiwgNDksIDIwLCA0OCwgMTgsIDYsIDMsIDg1LCA0LCAxMCwgMTksIDExLCA4MywgMTAxLCA5OSwgMTExLAorICAgICAgICAgICAgICAgIDExMCwgMTAwLCAzMiwgNzksIDExNCwgMTAzLCA0NiB9OworICAgICAgICBhc3NlcnROdWxsKCJUaGUgY29sbGVjdGlvbiBzaG91bGQgYmUgbnVsbC4iLCBzZWxlY3Rvci5nZXRJc3N1ZXJOYW1lcygpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlbGVjdG9yLmFkZElzc3Vlck5hbWUoaXNzMSk7CisgICAgICAgICAgICBzZWxlY3Rvci5hZGRJc3N1ZXJOYW1lKGlzczIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgICAgIENvbGxlY3Rpb248T2JqZWN0PiByZXN1bHQgPSBzZWxlY3Rvci5nZXRJc3N1ZXJOYW1lcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSBjb2xsZWN0aW9uIHNob3VsZCBjb250YWluIGFsbCBvZiB0aGUgc3BlY2lmaWVkIEROcy4iLAorICAgICAgICAgICAgICAgIDIsIHJlc3VsdC5zaXplKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGdldE1pbkNSTCgpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyBpZiB0aGUgbWV0aG9kIHJldHVybiBudWxsIGluIHRoZSBjYXNlCisgICAgICogb2Ygbm90IHNwZWNpZmllZCBtaW5DUkwgY3JpdGVyaWEsIGFuZCBpZiB0aGUgcmV0dXJuZWQgdmFsdWUgY29ycmVzcG9uZHMKKyAgICAgKiB0byB0aGUgc3BlY2lmaWVkIG9uZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TWluQ1JMKCkgeworICAgICAgICBYNTA5Q1JMU2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNSTFNlbGVjdG9yKCk7CisgICAgICAgIGFzc2VydE51bGwoIkluaXRpYWxseSB0aGUgbWluQ1JMIHNob3VsZCBiZSBudWxsLiIsIHNlbGVjdG9yLmdldE1pbkNSTCgpKTsKKyAgICAgICAgQmlnSW50ZWdlciBtaW5DUkwgPSBuZXcgQmlnSW50ZWdlcigiMTAwMDAiKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0TWluQ1JMTnVtYmVyKG1pbkNSTCk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSByZXN1bHQgc2hvdWxkIGJlIGVxdWFsIHRvIHNwZWNpZmllZC4iLCBtaW5DUkwKKyAgICAgICAgICAgICAgICAuZXF1YWxzKHNlbGVjdG9yLmdldE1pbkNSTCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0TWF4Q1JMKCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIGlmIHRoZSBtZXRob2QgcmV0dXJuIG51bGwgaW4gdGhlIGNhc2UKKyAgICAgKiBvZiBub3Qgc3BlY2lmaWVkIG1heENSTCBjcml0ZXJpYSwgYW5kIGlmIHRoZSByZXR1cm5lZCB2YWx1ZSBjb3JyZXNwb25kcworICAgICAqIHRvIHRoZSBzcGVjaWZpZWQgb25lLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRNYXhDUkwoKSB7CisgICAgICAgIFg1MDlDUkxTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q1JMU2VsZWN0b3IoKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiSW5pdGlhbGx5IHRoZSBtYXhDUkwgc2hvdWxkIGJlIG51bGwuIiwgc2VsZWN0b3IuZ2V0TWF4Q1JMKCkpOworICAgICAgICBCaWdJbnRlZ2VyIG1heENSTCA9IG5ldyBCaWdJbnRlZ2VyKCIxMDAwMCIpOworICAgICAgICBzZWxlY3Rvci5zZXRNYXhDUkxOdW1iZXIobWF4Q1JMKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIHJlc3VsdCBzaG91bGQgYmUgZXF1YWwgdG8gc3BlY2lmaWVkLiIsIG1heENSTAorICAgICAgICAgICAgICAgIC5lcXVhbHMoc2VsZWN0b3IuZ2V0TWF4Q1JMKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXREYXRlQW5kVGltZSgpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyBpZiB0aGUgbWV0aG9kIHJldHVybiBudWxsIGluIHRoZQorICAgICAqIGNhc2Ugb2Ygbm90IHNwZWNpZmllZCBkYXRlQW5kVGltZSBjcml0ZXJpYSwgYW5kIGlmIHRoZSByZXR1cm5lZCB2YWx1ZQorICAgICAqIGNvcnJlc3BvbmRzIHRvIHRoZSBzcGVjaWZpZWQgb25lLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXREYXRlQW5kVGltZSgpIHsKKyAgICAgICAgWDUwOUNSTFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDUkxTZWxlY3RvcigpOworICAgICAgICBhc3NlcnROdWxsKCJJbml0aWFsbHkgdGhlIGRhdGVBbmRUaW1lIGNyaXRlcmlhIHNob3VsZCBiZSBudWxsLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IuZ2V0RGF0ZUFuZFRpbWUoKSk7CisgICAgICAgIERhdGUgZGF0ZSA9IG5ldyBEYXRlKDIwMCk7CisgICAgICAgIHNlbGVjdG9yLnNldERhdGVBbmRUaW1lKGRhdGUpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgcmVzdWx0IHNob3VsZCBiZSBlcXVhbCB0byBzcGVjaWZpZWQuIiwgZGF0ZQorICAgICAgICAgICAgICAgIC5lcXVhbHMoc2VsZWN0b3IuZ2V0RGF0ZUFuZFRpbWUoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGdldENlcnRpZmljYXRlQ2hlY2tpbmcoKSBtZXRob2QgdGVzdGluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q2VydGlmaWNhdGVDaGVja2luZ0xqYXZhX1g1MDlDZXJ0aWZpY2F0ZSgpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBYNTA5Q1JMU2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNSTFNlbGVjdG9yKCk7CisKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNlcnRGYWN0ID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYNTA5Iik7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0ID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2VydEZhY3QKKyAgICAgICAgICAgICAgICAuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oVGVzdFV0aWxzCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0WDUwOUNlcnRpZmljYXRlX3YzKCkpKTsKKworICAgICAgICBzZWxlY3Rvci5zZXRDZXJ0aWZpY2F0ZUNoZWNraW5nKGNlcnQpOworICAgICAgICBhc3NlcnRFcXVhbHMoY2VydCwgc2VsZWN0b3IuZ2V0Q2VydGlmaWNhdGVDaGVja2luZygpKTsKKworICAgICAgICBzZWxlY3Rvci5zZXRDZXJ0aWZpY2F0ZUNoZWNraW5nKG51bGwpOworICAgICAgICBhc3NlcnROdWxsKHNlbGVjdG9yLmdldENlcnRpZmljYXRlQ2hlY2tpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogbWF0Y2goQ1JMIGNybCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIGlmIHRoZSBudWxsIG9iamVjdCBtYXRjaGVzIHRvIHRoZQorICAgICAqIHNlbGVjdG9yIG9yIG5vdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWF0Y2hMamF2YV9zZWN1cml0eV9jZXJ0X1g1MDlDUkwoKSB7CisgICAgICAgIFg1MDlDUkxTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q1JMU2VsZWN0b3IoKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBudWxsIG9iamVjdCBzaG91bGQgbm90IG1hdGNoIiwgc2VsZWN0b3IKKyAgICAgICAgICAgICAgICAubWF0Y2goKFg1MDlDUkwpIG51bGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBjbG9uZSgpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyBpZiB0aGUgc2VsZWN0b3IgaXMgY2xvbmVkIGNvcnJlY3RseTogdGhlCisgICAgICogY3JsIHdoaWNoIG1hdGNoZSB0byB0aGUgaW5pdGlhbCBzZWxlY3RvciBzaG91bGQgbWF0Y2ggdG8gdGhlIGNsb25lIGFuZAorICAgICAqIHRoZSBjaGFuZ2Ugb2YgY2xvbmUgc2hvdWxkIG5vdCBjYXVzZSB0aGUgY2hhbmdlIG9mIGluaXRpYWwgc2VsZWN0b3IuCisgICAgICovCisgICAgQEFuZHJvaWRPbmx5KCJVc2VzIHNwZWNpZmljIGNsYXNzZXM6ICIgKworICAgICAgICAgICAgIm9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFPY3RldFN0cmluZywgIiArCisgICAgICAgICAgICAib3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUludGVnZXIuIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvbmUoKSB7CisgICAgICAgIFg1MDlDUkxTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q1JMU2VsZWN0b3IoKTsKKyAgICAgICAgWDUwMFByaW5jaXBhbCBpc3MxID0gbmV3IFg1MDBQcmluY2lwYWwoIk89Rmlyc3QgT3JnLiIpOworICAgICAgICBYNTAwUHJpbmNpcGFsIGlzczIgPSBuZXcgWDUwMFByaW5jaXBhbCgiTz1TZWNvbmQgT3JnLiIpOworICAgICAgICBYNTAwUHJpbmNpcGFsIGlzczMgPSBuZXcgWDUwMFByaW5jaXBhbCgiTz1UaGlyZCBPcmcuIik7CisgICAgICAgIEJpZ0ludGVnZXIgbWluQ1JMID0gbmV3IEJpZ0ludGVnZXIoIjEwMDAwIik7CisgICAgICAgIEJpZ0ludGVnZXIgbWF4Q1JMID0gbmV3IEJpZ0ludGVnZXIoIjEwMDAwIik7CisgICAgICAgIERhdGUgZGF0ZSA9IG5ldyBEYXRlKDIwMCk7CisKKyAgICAgICAgc2VsZWN0b3IuYWRkSXNzdWVyKGlzczEpOworICAgICAgICBzZWxlY3Rvci5hZGRJc3N1ZXIoaXNzMik7CisgICAgICAgIHNlbGVjdG9yLnNldE1pbkNSTE51bWJlcihtaW5DUkwpOworICAgICAgICBzZWxlY3Rvci5zZXRNYXhDUkxOdW1iZXIobWF4Q1JMKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0RGF0ZUFuZFRpbWUoZGF0ZSk7CisKKyAgICAgICAgWDUwOUNSTFNlbGVjdG9yIGNsb25lID0gKFg1MDlDUkxTZWxlY3Rvcikgc2VsZWN0b3IuY2xvbmUoKTsKKyAgICAgICAgVGVzdENSTCBjcmwgPSBuZXcgVGVzdENSTChpc3MxKTsKKyAgICAgICAgY3JsLnNldENybE51bWJlcihtaW5DUkwpOworICAgICAgICBjcmwuc2V0VXBkYXRlRGF0ZXMobmV3IERhdGUoMjAwKSwgbmV3IERhdGUoMjAwKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBzcGVjaWZpZWQgQ1JMIHNob3VsZCBtYXRjaCB0aGUgY2xvbmUgc2VsZWN0b3IuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjcmwpKTsKKworICAgICAgICBjbG9uZS5hZGRJc3N1ZXIoaXNzMyk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2hhbmdlcyBvZiB0aGUgY2xvbmUgc2VsZWN0b3Igc2hvdWxkIG5vdCBjYXVzZSAiCisgICAgICAgICAgICAgICAgKyAidGhlIGNoYW5nZXMgb2YgaW5pdGlhbCBvYmplY3QiLCBzZWxlY3Rvci5nZXRJc3N1ZXJOYW1lcygpCisgICAgICAgICAgICAgICAgLnNpemUoKSA9PSAzKTsKKyAgICB9CisgICAgcHVibGljIHZvaWQgdGVzdFRvU3RyaW5nKCkgeworICAgICAgICBYNTA5Q1JMU2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNSTFNlbGVjdG9yKCk7CisgICAgICAgIFg1MDBQcmluY2lwYWwgaXNzMSA9IG5ldyBYNTAwUHJpbmNpcGFsKCJPPUZpcnN0IE9yZy4iKTsKKyAgICAgICAgWDUwMFByaW5jaXBhbCBpc3MyID0gbmV3IFg1MDBQcmluY2lwYWwoIk89U2Vjb25kIE9yZy4iKTsKKyAgICAgICAgQmlnSW50ZWdlciBtaW5DUkwgPSBuZXcgQmlnSW50ZWdlcigiMTAwMDAiKTsKKyAgICAgICAgQmlnSW50ZWdlciBtYXhDUkwgPSBuZXcgQmlnSW50ZWdlcigiMTAwMDAiKTsKKyAgICAgICAgRGF0ZSBkYXRlID0gbmV3IERhdGUoMjAwKTsKKworICAgICAgICBzZWxlY3Rvci5hZGRJc3N1ZXIoaXNzMSk7CisgICAgICAgIHNlbGVjdG9yLmFkZElzc3Vlcihpc3MyKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0TWluQ1JMTnVtYmVyKG1pbkNSTCk7CisgICAgICAgIHNlbGVjdG9yLnNldE1heENSTE51bWJlcihtYXhDUkwpOworICAgICAgICBzZWxlY3Rvci5zZXREYXRlQW5kVGltZShkYXRlKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKCJUaGUgcmVzdWx0IHNob3VsZCBub3QgYmUgbnVsbC4iLCBzZWxlY3Rvci50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWJzdHJhY3QgY2xhc3Mgc3R1YiBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGNsYXNzIFRlc3RDUkwgZXh0ZW5kcyBYNTA5Q1JMIHsKKworICAgICAgICBwcml2YXRlIFg1MDBQcmluY2lwYWwgcHJpbmNpcGFsID0gbnVsbDsKKworICAgICAgICBwcml2YXRlIEJpZ0ludGVnZXIgY3JsTnVtYmVyID0gbnVsbDsKKworICAgICAgICBwcml2YXRlIERhdGUgdGhpc1VwZGF0ZSA9IG51bGw7CisKKyAgICAgICAgcHJpdmF0ZSBEYXRlIG5leHRVcGRhdGUgPSBudWxsOworCisgICAgICAgIHB1YmxpYyBUZXN0Q1JMKCkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFRlc3RDUkwoWDUwMFByaW5jaXBhbCBwcmluY2lwYWwpIHsKKyAgICAgICAgICAgIHRoaXMucHJpbmNpcGFsID0gcHJpbmNpcGFsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFRlc3RDUkwoRGF0ZSB0aGlzVXBkYXRlLCBEYXRlIG5leHRVcGRhdGUpIHsKKyAgICAgICAgICAgIHNldFVwZGF0ZURhdGVzKHRoaXNVcGRhdGUsIG5leHRVcGRhdGUpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFRlc3RDUkwoQmlnSW50ZWdlciBjcmxOdW1iZXIpIHsKKyAgICAgICAgICAgIHNldENybE51bWJlcihjcmxOdW1iZXIpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0VXBkYXRlRGF0ZXMoRGF0ZSB0aGlzVXBkYXRlLCBEYXRlIG5leHRVcGRhdGUpIHsKKyAgICAgICAgICAgIHRoaXMudGhpc1VwZGF0ZSA9IHRoaXNVcGRhdGU7CisgICAgICAgICAgICB0aGlzLm5leHRVcGRhdGUgPSBuZXh0VXBkYXRlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0Q3JsTnVtYmVyKEJpZ0ludGVnZXIgY3JsTnVtYmVyKSB7CisgICAgICAgICAgICB0aGlzLmNybE51bWJlciA9IGNybE51bWJlcjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBYNTAwUHJpbmNpcGFsIGdldElzc3Vlclg1MDBQcmluY2lwYWwoKSB7CisgICAgICAgICAgICByZXR1cm4gcHJpbmNpcGFsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNSZXZva2VkKENlcnRpZmljYXRlIGNlcnQpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFNldDxTdHJpbmc+IGdldE5vbkNyaXRpY2FsRXh0ZW5zaW9uT0lEcygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFNldDxTdHJpbmc+IGdldENyaXRpY2FsRXh0ZW5zaW9uT0lEcygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFeHRlbnNpb25WYWx1ZShTdHJpbmcgb2lkKSB7CisgICAgICAgICAgICBpZiAoIjIuNS4yOS4yMCIuZXF1YWxzKG9pZCkgJiYgKGNybE51bWJlciAhPSBudWxsKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBBU04xT2N0ZXRTdHJpbmcuZ2V0SW5zdGFuY2UoKS5lbmNvZGUoCisgICAgICAgICAgICAgICAgICAgICAgICBBU04xSW50ZWdlci5nZXRJbnN0YW5jZSgpLmVuY29kZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JsTnVtYmVyLnRvQnl0ZUFycmF5KCkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzVW5zdXBwb3J0ZWRDcml0aWNhbEV4dGVuc2lvbigpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgICAgICAgIHB1YmxpYyB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5KSB0aHJvd3MgQ1JMRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgICAgICBwdWJsaWMgdm9pZCB2ZXJpZnkoUHVibGljS2V5IGtleSwgU3RyaW5nIHNpZ1Byb3ZpZGVyKQorICAgICAgICAgICAgICAgIHRocm93cyBDUkxFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBJbnZhbGlkS2V5RXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXRWZXJzaW9uKCkgeworICAgICAgICAgICAgcmV0dXJuIDI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUHJpbmNpcGFsIGdldElzc3VlckROKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgRGF0ZSBnZXRUaGlzVXBkYXRlKCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXNVcGRhdGU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgRGF0ZSBnZXROZXh0VXBkYXRlKCkgeworICAgICAgICAgICAgcmV0dXJuIG5leHRVcGRhdGU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgWDUwOUNSTEVudHJ5IGdldFJldm9rZWRDZXJ0aWZpY2F0ZShCaWdJbnRlZ2VyIHNlcmlhbE51bWJlcikgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU2V0PFg1MDlDUkxFbnRyeT4gZ2V0UmV2b2tlZENlcnRpZmljYXRlcygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRUQlNDZXJ0TGlzdCgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRTaWduYXR1cmUoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2lnQWxnTmFtZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRTaWdBbGdPSUQoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0U2lnQWxnUGFyYW1zKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9YNTA5Q1JMU2VsZWN0b3JUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9YNTA5Q1JMU2VsZWN0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDk2YmZlZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L1g1MDlDUkxTZWxlY3RvclRlc3QuamF2YQpAQCAtMCwwICsxLDEyNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxleGFuZGVyIFkuIEtsZXltZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmNlcnQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMU2VsZWN0b3I7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5UcmVlU2V0OworCitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CisKK3B1YmxpYyBjbGFzcyBYNTA5Q1JMU2VsZWN0b3JUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDUkxTZWxlY3RvciNhZGRJc3N1ZXIoamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWwpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRJc3N1ZXJMamF2YXhfc2VjdXJpdHlfYXV0aF94NTAwX1g1MDBQcmluY2lwYWwwMSgpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy9SZWdyZXNzaW9uIGZvciBIQVJNT05ZLTQ2NQorICAgICAgICBYNTA5Q1JMU2VsZWN0b3Igb2JqID0gbmV3IFg1MDlDUkxTZWxlY3RvcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2JqLmFkZElzc3VlcigoWDUwMFByaW5jaXBhbCkgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDUkxTZWxlY3RvciNhZGRJc3N1ZXJOYW1lKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRJc3N1ZXJOYW1lTGphdmFfbGFuZ19TdHJpbmcwMSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvL1JlZ3Jlc3Npb24gZm9yIEhBUk1PTlktNDY1CisgICAgICAgIFg1MDlDUkxTZWxlY3RvciBvYmogPSBuZXcgWDUwOUNSTFNlbGVjdG9yKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmouYWRkSXNzdWVyTmFtZSgiMjM0Iik7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS0xMDc2CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgWDUwOUNSTFNlbGVjdG9yKCkuYWRkSXNzdWVyTmFtZSgidz15Iik7CisgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDUkxTZWxlY3RvciNhZGRJc3N1ZXJOYW1lKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRJc3N1ZXJOYW1lTGphdmFfbGFuZ19TdHJpbmcwMigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktNzM2CisgICAgICAgIFg1MDlDUkxTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q1JMU2VsZWN0b3IoKTsKKworICAgICAgICAvLyBubyBleGNlcHRpb24gZm9yIG51bGwKKyAgICAgICAgc2VsZWN0b3IuYWRkSXNzdWVyTmFtZSgoU3RyaW5nKSBudWxsKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q1JMU2VsZWN0b3IjYWRkSXNzdWVyTmFtZShieXRlW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRJc3N1ZXJOYW1lJEJfMygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvL1JlZ3Jlc3Npb24gZm9yIEhBUk1PTlktNDY1CisgICAgICAgIFg1MDlDUkxTZWxlY3RvciBvYmogPSBuZXcgWDUwOUNSTFNlbGVjdG9yKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvYmouYWRkSXNzdWVyTmFtZShuZXcgYnl0ZVtdIHsgKGJ5dGUpIDIsIChieXRlKSAzLCAoYnl0ZSkgNCB9KTsKKyAgICAgICAgICAgIGZhaWwoIklPRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNSTFNlbGVjdG9yI2FkZElzc3Vlck5hbWUoYnl0ZVtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkSXNzdWVyTmFtZSRCXzQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy9SZWdyZXNzaW9uIGZvciBIQVJNT05ZLTQ2NQorICAgICAgICBYNTA5Q1JMU2VsZWN0b3Igb2JqID0gbmV3IFg1MDlDUkxTZWxlY3RvcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2JqLmFkZElzc3Vlck5hbWUoKGJ5dGVbXSkgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3RlZCIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogc2V0SXNzdWVyTmFtZXMoQ29sbGVjdGlvbiA8Pz4gbmFtZXMpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRJc3N1ZXJOYW1lc0xqYXZhX3V0aWxfQ29sbGVjdGlvbjAxKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS03MzcKKyAgICAgICAgWDUwOUNSTFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDUkxTZWxlY3RvcigpOworICAgICAgICBzZWxlY3Rvci5zZXRJc3N1ZXJOYW1lcyhuZXcgVHJlZVNldDxDb21wYXJhYmxlPigpIHsKKyAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDYwMDk1NDU1MDUzMjEwOTI0OThMOworCisgICAgICAgICAgICBwdWJsaWMgSXRlcmF0b3I8Q29tcGFyYWJsZT4gaXRlcmF0b3IoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L1g1MDlDUkxUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9YNTA5Q1JMVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMwMTYzZjMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9YNTA5Q1JMVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzM0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgWS4gS2xleW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IGRhbHZpay5hbm5vdGF0aW9uLkFuZHJvaWRPbmx5OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3Q7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0U3VpdGU7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmF0dXJlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DUkxFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDUkw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDUkxFbnRyeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuVGVzdFV0aWxzOworCitpbXBvcnQgdGVzdHMuc2VjdXJpdHkuY2VydC5YNTA5Q1JMMlRlc3QuTXlYNTA5Q1JMOworLyoqCisgKi8KK3B1YmxpYyBjbGFzcyBYNTA5Q1JMVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgWDUwOUNSTCB0YnRfY3JsOworCisgICAgU3RyaW5nIGNlcnRpZmljYXRlID0gIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICAgICArICJNSUlDWlRDQ0FkSUNCUUwzQUFDMk1BMEdDU3FHU0liM0RRRUJBZ1VBTUY4eEN6QUpCZ05WQkFZVEFsVlRNU0F3XG4iCisgICAgICAgICsgIkhnWURWUVFLRXhkU1UwRWdSR0YwWVNCVFpXTjFjbWwwZVN3Z1NXNWpMakV1TUN3R0ExVUVDeE1sVTJWamRYSmxcbiIKKyAgICAgICAgKyAiSUZObGNuWmxjaUJEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVUQWVGdzA1TnpBeU1qQXdNREF3TURCYVxuIgorICAgICAgICArICJGdzA1T0RBeU1qQXlNelU1TlRsYU1JR1dNUXN3Q1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2XG4iCisgICAgICAgICsgImNtNXBZVEVTTUJBR0ExVUVCeE1KVUdGc2J5QkJiSFJ2TVI4d0hRWURWUVFLRXhaVGRXNGdUV2xqY205emVYTjBcbiIKKyAgICAgICAgKyAiWlcxekxDQkpibU11TVNFd0h3WURWUVFMRXhoVVpYTjBJR0Z1WkNCRmRtRnNkV0YwYVc5dUlFOXViSGt4R2pBWVxuIgorICAgICAgICArICJCZ05WQkFNVEVXRnlaMjl1TG1WdVp5NXpkVzR1WTI5dE1JR2ZNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCXG4iCisgICAgICAgICsgImlRS0JnUUNvZm1kWStQaVVXTjAxRk96RWV3ZitHYUcrbEZmMTMyVXB6QVRtWUprQTRBRUEvanVXN2pTaStMSmtcbiIKKyAgICAgICAgKyAid0pLaTVHTzRSeVpveWltQUwvNXlJV0RWNmwxS2x2eHlLc2xyMFJFaE1CYUQvM1ozRXNMVFRFZjVnVnJRUzZzVFxuIgorICAgICAgICArICJXTW9TWkF5ekIzOWtGZnNCNm9VWE50VjgrVUtLeFN4S2J4dmhRbjI2N1BlQ3o1VlgyUUlEQVFBQk1BMEdDU3FHXG4iCisgICAgICAgICsgIlNJYjNEUUVCQWdVQUEzNEFYbDNhdDZsdWlWLzdJOU1ONUNYWW9QSllJOEJjZGMxaEJhZ0p2VE1jbWxxTDJ1T1pcbiIKKyAgICAgICAgKyAiSDlUNWhOTUVMOVRrNmFJN3laUFhjdy94STJLNnBPUi9Gck1wMFV3Sm1keFg3bGpWNlp0VVpmN3BZNDkyVXF3Q1xuIgorICAgICAgICArICIxNzc3WFE5VUVaeXJLSnZGNW50bGVlTzBheUJxTEdWS0NXeldaWDlZc1hDcHY0N0ZOTFpidXBFPVxuIgorICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iOworCisgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gY2VydEFycmF5ID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNlcnRpZmljYXRlCisgICAgICAgIC5nZXRCeXRlcygpKTsKKworICAgIC8qKgorICAgICAqIFRoZSBzdHViIGNsYXNzIHVzZWQgZm9yIHRlc3Rpbmcgb2Ygbm9uIGFic3RyYWN0IG1ldGhvZHMuCisgICAgICovCisgICAgcHJpdmF0ZSBjbGFzcyBUQlRDUkwgZXh0ZW5kcyBYNTA5Q1JMIHsKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNSZXZva2VkKENlcnRpZmljYXRlIGNlcnQpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFNldDxTdHJpbmc+IGdldE5vbkNyaXRpY2FsRXh0ZW5zaW9uT0lEcygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFNldDxTdHJpbmc+IGdldENyaXRpY2FsRXh0ZW5zaW9uT0lEcygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFeHRlbnNpb25WYWx1ZShTdHJpbmcgb2lkKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc1Vuc3VwcG9ydGVkQ3JpdGljYWxFeHRlbnNpb24oKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5KQorICAgICAgICAgICAgICAgICB0aHJvd3MgQ1JMRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICBJbnZhbGlkS2V5RXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgIFNpZ25hdHVyZUV4Y2VwdGlvbgorICAgICAgICB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCB2ZXJpZnkoUHVibGljS2V5IGtleSwgU3RyaW5nIHNpZ1Byb3ZpZGVyKQorICAgICAgICAgICAgICAgICB0aHJvd3MgQ1JMRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICBJbnZhbGlkS2V5RXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgIFNpZ25hdHVyZUV4Y2VwdGlvbgorICAgICAgICB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldFZlcnNpb24oKSB7CisgICAgICAgICAgICByZXR1cm4gMjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0SXNzdWVyRE4oKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBEYXRlIGdldFRoaXNVcGRhdGUoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBEYXRlIGdldE5leHRVcGRhdGUoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBYNTA5Q1JMRW50cnkgZ2V0UmV2b2tlZENlcnRpZmljYXRlKEJpZ0ludGVnZXIgc2VyaWFsTnVtYmVyKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTZXQ8WDUwOUNSTEVudHJ5PiBnZXRSZXZva2VkQ2VydGlmaWNhdGVzKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldFRCU0NlcnRMaXN0KCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldFNpZ25hdHVyZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRTaWdBbGdOYW1lKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFNpZ0FsZ09JRCgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRTaWdBbGdQYXJhbXMoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgcHVibGljIFg1MDlDUkxUZXN0KCkgeworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VXAoKSB7CisgICAgICAgIHRidF9jcmwgPSBuZXcgVEJUQ1JMKCkgeworICAgICAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVtdIHsxLCAyLCAzfTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRUeXBlKCkgbWV0aG9kIHRlc3RpbmcuIFRlc3RzIHRoYXQgZ2V0VHlwZSgpIG1ldGhvZCByZXR1cm5zCisgICAgICogdGhlIHZhbHVlICJYLjUwOSIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VHlwZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgdHlwZSBvZiBYNTA5Q1JMIHNob3VsZCBiZSBYLjUwOSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRidF9jcmwuZ2V0VHlwZSgpLCAiWC41MDkiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBlcXVhbHMoT2JqZWN0IG90aGVyKSBtZXRob2QgdGVzdGluZy4gVGVzdHMgdGhlIGNvcnJlY3RuZXNzIG9mIGVxdWFsCisgICAgICogb3BlcmF0aW9uOiBpdCBzaG91bGQgYmUgcmVmbGV4aXZlLCBzeW1tZXRyaWMsIHRyYW5zaXRpdmUsIGNvbnNpc3RlbnQKKyAgICAgKiBhbmQgc2hvdWxkIGJlIGZhbHNlIG9uIG51bGwgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHMoKSB7CisgICAgICAgIFRCVENSTCB0YnRfY3JsXzEgPSBuZXcgVEJUQ1JMKCkgeworICAgICAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVtdIHsxLCAyLCAzfTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBUQlRDUkwgdGJ0X2NybF8yID0gbmV3IFRCVENSTCgpIHsKKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7MSwgMiwgM307CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgVEJUQ1JMIHRidF9jcmxfMyA9IG5ldyBUQlRDUkwoKSB7CisgICAgICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBieXRlW10gezMsIDIsIDF9OworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIC8vIGNoZWNraW5nIGZvciByZWZsZXhpdmUgbGF3OgorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgZXF1aXZhbGVuY2UgcmVsYXRpb24gc2hvdWxkIGJlIHJlZmxleGl2ZS4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRidF9jcmwuZXF1YWxzKHRidF9jcmwpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSBDUkxzIHdpdGggZXF1YWwgZW5jb2RlZCBmb3JtIHNob3VsZCBiZSBlcXVhbCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJ0X2NybCwgdGJ0X2NybF8xKTsKKyAgICAgICAgLy8gY2hlY2tpbmcgZm9yIHN5bW1ldHJpYyBsYXc6CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBlcXVpdmFsZW5jZSByZWxhdGlvbiBzaG91bGQgYmUgc3ltbWV0cmljLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJ0X2NybF8xLmVxdWFscyh0YnRfY3JsKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgQ1JMcyB3aXRoIGVxdWFsIGVuY29kZWQgZm9ybSBzaG91bGQgYmUgZXF1YWwiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRidF9jcmxfMSwgdGJ0X2NybF8yKTsKKyAgICAgICAgLy8gY2hlY2tpbmcgZm9yIHRyYW5zaXRpdmUgbGF3OgorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgZXF1aXZhbGVuY2UgcmVsYXRpb24gc2hvdWxkIGJlIHRyYW5zaXRpdmUuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YnRfY3JsLmVxdWFscyh0YnRfY3JsXzIpKTsKKworICAgICAgICBhc3NlcnRGYWxzZSgiU2hvdWxkIG5vdCBiZSBlcXVhbCB0byBudWxsIG9iamVjdC4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRidF9jcmwuZXF1YWxzKG51bGwpKTsKKworICAgICAgICBhc3NlcnRGYWxzZSgiVGhlIENSTHMgd2l0aCBkaWZmZXJpbmcgZW5jb2RlZCBmb3JtIHNob3VsZCBub3QgYmUgZXF1YWwiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRidF9jcmwuZXF1YWxzKHRidF9jcmxfMykpOworICAgICAgICBhc3NlcnRGYWxzZSgiVGhlIENSTCBzaG91bGQgbm90IGJlIGVxdWFscyB0byB0aGUgb2JqZWN0IHdoaWNoIGlzIG5vdCAiCisgICAgICAgICAgICAgICAgICAgICsgImFuIGluc3RhbmNlIG9mIFg1MDlDUkwiLCB0YnRfY3JsLmVxdWFscyhuZXcgT2JqZWN0KCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBoYXNoQ29kZSgpIG1ldGhvZCB0ZXN0aW5nLiBUZXN0cyB0aGF0IGZvciBlcXVhbCBvYmplY3RzIGhhc2ggY29kZXMKKyAgICAgKiBhcmUgZXF1YWwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEhhc2hDb2RlKCkgeworICAgICAgICBUQlRDUkwgdGJ0X2NybF8xID0gbmV3IFRCVENSTCgpIHsKKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7MSwgMiwgM307CisgICAgICAgICAgICB9CisgICAgICAgIH07CisgICAgICAgIGFzc2VydFRydWUoIkVxdWFsIG9iamVjdHMgc2hvdWxkIGhhdmUgdGhlIHNhbWUgaGFzaCBjb2Rlcy4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJ0X2NybC5oYXNoQ29kZSgpID09IHRidF9jcmxfMS5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNSTCNnZXRJc3N1ZXJYNTAwUHJpbmNpcGFsKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SXNzdWVyWDUwMFByaW5jaXBhbCgpIHsKKyAgICAgICAgLy8gcmV0dXJuIHZhbGlkIGVuY29kaW5nCisgICAgICAgIFRCVENSTCBjcmwgPSBuZXcgVEJUQ1JMKCkgeworICAgICAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBUZXN0VXRpbHMuZ2V0WDUwOUNSTF92MSgpOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgWDUwMFByaW5jaXBhbCgiQ049WiIpLCBjcmwuZ2V0SXNzdWVyWDUwMFByaW5jaXBhbCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRSZXZva2VkQ2VydGlmaWNhdGUoWDUwOUNlcnRpZmljYXRlIGNlcnRpZmljYXRlKSBtZXRob2QgdGVzdGluZy4KKyAgICAgKiBDaGVjayBpZiB0aGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KKyAgICAgKiBvbiBudWxsIGlucHV0IGRhdGEuCisgICAgICovCisgICAgQEFuZHJvaWRPbmx5KCJUZXN0IGZpbGVkIG9uIFJJOiBnZXRSZXZva2VkQ2VydGlmaWNhdGUgdGhyb3dzICIgKworICAgICAgICAgICAgIlJ1bnRpbWVFeGNlcHRpb24uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0UmV2b2tlZENlcnRpZmljYXRlKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGJ0X2NybC5nZXRSZXZva2VkQ2VydGlmaWNhdGUoKFg1MDlDZXJ0aWZpY2F0ZSkgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBzaG91bGQgYmUgdGhyb3duICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIG51bGwgaW5wdXQgZGF0YS4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlIGNlcnQgPSAoWDUwOUNlcnRpZmljYXRlKSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKGNlcnRBcnJheSk7CisgICAgICAgICAgICB0YnRfY3JsLmdldFJldm9rZWRDZXJ0aWZpY2F0ZShjZXJ0KTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWJzdHJhY3RNZXRob2RzKCkgeworICAgICAgICBUQlRDUkwgY3JsID0gbmV3IFRCVENSTCgpIHsKKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gVGVzdFV0aWxzLmdldFg1MDlDUkxfdjEoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY3JsLmdldEVuY29kZWQoKTsKKyAgICAgICAgICAgIGNybC5nZXRJc3N1ZXJETigpOworICAgICAgICAgICAgY3JsLmdldE5leHRVcGRhdGUoKTsKKyAgICAgICAgICAgIGNybC5nZXRSZXZva2VkQ2VydGlmaWNhdGUoQmlnSW50ZWdlci5PTkUpOworICAgICAgICAgICAgY3JsLmdldFJldm9rZWRDZXJ0aWZpY2F0ZXMoKTsKKyAgICAgICAgICAgIGNybC5nZXRTaWdBbGdOYW1lKCk7CisgICAgICAgICAgICBjcmwuZ2V0U2lnQWxnT0lEKCk7CisgICAgICAgICAgICBjcmwuZ2V0U2lnQWxnUGFyYW1zKCk7CisgICAgICAgICAgICBjcmwuZ2V0U2lnbmF0dXJlKCk7CisgICAgICAgICAgICBjcmwuZ2V0VEJTQ2VydExpc3QoKTsKKyAgICAgICAgICAgIGNybC5nZXRUaGlzVXBkYXRlKCk7CisgICAgICAgICAgICBjcmwuZ2V0VmVyc2lvbigpOworCisgICAgICAgICAgICBjcmwudmVyaWZ5KG51bGwpOworICAgICAgICAgICAgY3JsLnZlcmlmeShudWxsLCAidGVzdCIpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gZm9yIGNvbnN0cnVjdG9yIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0WDUwOUNSTCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRCVENSTCBjcmwgPSBuZXcgVEJUQ1JMKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGNybCBpbnN0YW5jZW9mIFg1MDlDUkwpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gZm9yIGNvbnN0cnVjdG9yIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFRlc3Qgc3VpdGUoKSB7CisgICAgICAgIHJldHVybiBuZXcgVGVzdFN1aXRlKFg1MDlDUkxUZXN0LmNsYXNzKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L1g1MDlDZXJ0U2VsZWN0b3JUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9YNTA5Q2VydFNlbGVjdG9yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFmYzY0MjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9YNTA5Q2VydFNlbGVjdG9yVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjI2NiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGg7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoQnVpbGRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5QS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5UcnVzdEFuY2hvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CisKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQuTXlDUkw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5UZXN0VXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuVGVzdEtleVBhaXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUJvb2xlYW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMUludGVnZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMU9jdGV0U3RyaW5nOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFPaWQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LmFzbjEuQVNOMVNlcXVlbmNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS5hc24xLkFTTjFUeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTAxLk5hbWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuQ2VydGlmaWNhdGVQb2xpY2llczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5HZW5lcmFsTmFtZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5HZW5lcmFsTmFtZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuTmFtZUNvbnN0cmFpbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5Lk9SQWRkcmVzczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkueDUwOS5PdGhlck5hbWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuUG9saWN5SW5mb3JtYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkuUHJpdmF0ZUtleVVzYWdlUGVyaW9kOworCisvKioKKyAqIFg1MDlDZXJ0U2VsZWN0b3JUZXN0CisgKi8KK3B1YmxpYyBjbGFzcyBYNTA5Q2VydFNlbGVjdG9yVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIGJ5dGVbXVtdIGNvbnN0cmFpbnRCeXRlcyA9IG5ldyBieXRlW11bXSB7CisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIDQ4LCAzNCwgLTk2LCAxNSwgNDgsIDEzLCAtMTI3LCA4LCA1NiwgNTAsIDUwLCA0NiwgNzgsCisgICAgICAgICAgICAgICAgICAgIDk3LCAxMDksIDEwMSwgLTEyOCwgMSwgMCwgLTk1LCAxNSwgNDgsIDEzLCAtMTI3LCA4LCA1NiwKKyAgICAgICAgICAgICAgICAgICAgNTAsIDUwLCA0NiwgNzgsIDk3LCAxMDksIDEwMSwgLTEyOCwgMSwgMH0sCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIDQ4LCA0MiwgLTk2LCAxOSwgNDgsIDE3LCAtMTI3LCAxMiwgMTE0LCAxMDIsIDk5LCA2NCwKKyAgICAgICAgICAgICAgICAgICAgNTYsIDUwLCA1MCwgNDYsIDc4LCA5NywgMTA5LCAxMDEsIC0xMjgsIDEsIDAsIC05NSwgMTksCisgICAgICAgICAgICAgICAgICAgIDQ4LCAxNywgLTEyNywgMTIsIDExNCwgMTAyLCA5OSwgNjQsIDU2LCA1MCwgNTAsIDQ2LCA3OCwKKyAgICAgICAgICAgICAgICAgICAgOTcsIDEwOSwgMTAxLCAtMTI4LCAxLCAwfSwKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgNDgsIDM0LCAtOTYsIDE1LCA0OCwgMTMsIC0xMjYsIDgsIDc4LCA5NywgMTA5LCAxMDEsIDQ2LAorICAgICAgICAgICAgICAgICAgICAxMTEsIDExNCwgMTAzLCAtMTI4LCAxLCAwLCAtOTUsIDE1LCA0OCwgMTMsIC0xMjYsIDgsCisgICAgICAgICAgICAgICAgICAgIDc4LCA5NywgMTA5LCAxMDEsIDQ2LCAxMTEsIDExNCwgMTAzLCAtMTI4LCAxLCAwfSwKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgNDgsIDQyLCAtOTYsIDE5LCA0OCwgMTcsIC0xMjYsIDEyLCAxMDAsIDc4LCA4MywgNDYsIDc4LAorICAgICAgICAgICAgICAgICAgICA5NywgMTA5LCAxMDEsIDQ2LCAxMTEsIDExNCwgMTAzLCAtMTI4LCAxLCAwLCAtOTUsIDE5LAorICAgICAgICAgICAgICAgICAgICA0OCwgMTcsIC0xMjYsIDEyLCAxMDAsIDc4LCA4MywgNDYsIDc4LCA5NywgMTA5LCAxMDEsCisgICAgICAgICAgICAgICAgICAgIDQ2LCAxMTEsIDExNCwgMTAzLCAtMTI4LCAxLCAwfSwKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgNDgsIDU0LCAtOTYsIDI1LCA0OCwgMjMsIC0xMjIsIDE4LCAxMDQsIDExNiwgMTE2LCAxMTIsCisgICAgICAgICAgICAgICAgICAgIDU4LCA0NywgNDcsIDgyLCAxMDEsIDExNSwgMTExLCAxMTcsIDExNCwgOTksIDEwMSwgNDYsCisgICAgICAgICAgICAgICAgICAgIDczLCAxMDAsIC0xMjgsIDEsIDAsIC05NSwgMjUsIDQ4LCAyMywgLTEyMiwgMTgsIDEwNCwKKyAgICAgICAgICAgICAgICAgICAgMTE2LCAxMTYsIDExMiwgNTgsIDQ3LCA0NywgODIsIDEwMSwgMTE1LCAxMTEsIDExNywgMTE0LAorICAgICAgICAgICAgICAgICAgICA5OSwgMTAxLCA0NiwgNzMsIDEwMCwgLTEyOCwgMSwgMH0sCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIDQ4LCA3MCwgLTk2LCAzMywgNDgsIDMxLCAtMTIyLCAyNiwgMTA0LCAxMTYsIDExNiwgMTEyLAorICAgICAgICAgICAgICAgICAgICA1OCwgNDcsIDQ3LCAxMTcsIDExMCwgMTA1LCAxMDIsIDExMSwgMTE0LCAxMDksIDQ2LCA4MiwKKyAgICAgICAgICAgICAgICAgICAgMTAxLCAxMTUsIDExMSwgMTE3LCAxMTQsIDk5LCAxMDEsIDQ2LCA3MywgMTAwLCAtMTI4LCAxLAorICAgICAgICAgICAgICAgICAgICAwLCAtOTUsIDMzLCA0OCwgMzEsIC0xMjIsIDI2LCAxMDQsIDExNiwgMTE2LCAxMTIsIDU4LAorICAgICAgICAgICAgICAgICAgICA0NywgNDcsIDExNywgMTEwLCAxMDUsIDEwMiwgMTExLCAxMTQsIDEwOSwgNDYsIDgyLCAxMDEsCisgICAgICAgICAgICAgICAgICAgIDExNSwgMTExLCAxMTcsIDExNCwgOTksIDEwMSwgNDYsIDczLCAxMDAsIC0xMjgsIDEsIDB9LAorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICA0OCwgMjYsIC05NiwgMTEsIDQ4LCA5LCAtMTIxLCA0LCAxLCAxLCAxLCAxLCAtMTI4LCAxLAorICAgICAgICAgICAgICAgICAgICAwLCAtOTUsIDExLCA0OCwgOSwgLTEyMSwgNCwgMSwgMSwgMSwgMSwgLTEyOCwgMSwgMH0sCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIDQ4LCA1MCwgLTk2LCAyMywgNDgsIDIxLCAtMTIxLCAxNiwgMSwgMSwgMSwgMSwgMSwgMSwgMSwKKyAgICAgICAgICAgICAgICAgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgLTEyOCwgMSwgMCwgLTk1LCAyMywgNDgsIDIxLAorICAgICAgICAgICAgICAgICAgICAtMTIxLCAxNiwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwKKyAgICAgICAgICAgICAgICAgICAgMSwgLTEyOCwgMSwgMH19OworCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3IjYWRkU3ViamVjdEFsdGVybmF0aXZlTmFtZShpbnQsIGJ5dGVbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZFN1YmplY3RBbHRlcm5hdGl2ZU5hbWVMaW50TGJ5dGVfYXJyYXkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTI0ODcKKyAgICAgICAgaW50W10gdHlwZXMgPSB7IEdlbmVyYWxOYW1lLk9USEVSX05BTUUsCisgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmFsTmFtZS5SRkM4MjJfTkFNRSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYWxOYW1lLkROU19OQU1FLAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhbE5hbWUuWDQwMF9BRERSLAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhbE5hbWUuRElSX05BTUUsCisgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmFsTmFtZS5FRElQX05BTUUsCisgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmFsTmFtZS5VUl9JRCwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYWxOYW1lLklQX0FERFIsCisgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmFsTmFtZS5SRUdfSUQgfTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBuZXcgWDUwOUNlcnRTZWxlY3RvcigpLmFkZFN1YmplY3RBbHRlcm5hdGl2ZU5hbWUodHlwZXNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZVtdKSBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJObyBleHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiBmb3IgdHlwZTogIiArIHR5cGVzW2ldKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2FkZFN1YmplY3RBbHRlcm5hdGl2ZU5hbWUoaW50LCBTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lTGludExqYXZhX2xhbmdfU3RyaW5nKCkgeworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIQVJNT05ZLTcyNworICAgICAgICBpbnRbXSB0eXBlcyA9IHsgR2VuZXJhbE5hbWUuT1RIRVJfTkFNRSwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdlbmVyYWxOYW1lLlJGQzgyMl9OQU1FLAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhbE5hbWUuRE5TX05BTUUsCisgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmFsTmFtZS5YNDAwX0FERFIsCisgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmFsTmFtZS5ESVJfTkFNRSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYWxOYW1lLkVESVBfTkFNRSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYWxOYW1lLlVSX0lELAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhbE5hbWUuSVBfQUREUiwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYWxOYW1lLlJFR19JRCB9OworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG5ldyBYNTA5Q2VydFNlbGVjdG9yKCkuYWRkU3ViamVjdEFsdGVybmF0aXZlTmFtZSh0eXBlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICItMHhERlJGIik7CisgICAgICAgICAgICAgICAgZmFpbCgiSU9FeGNlcHRpb24gZXhwZWN0ZWQgZm9yIHR5cGU6ICIgKyB0eXBlc1tpXSk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNhZGRQYXRoVG9OYW1lKGludCwgYnl0ZVtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkUGF0aFRvTmFtZUxpbnRMYnl0ZV9hcnJheSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMjQ4NworICAgICAgICBpbnRbXSB0eXBlcyA9IHsgR2VuZXJhbE5hbWUuT1RIRVJfTkFNRSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYWxOYW1lLlJGQzgyMl9OQU1FLAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhbE5hbWUuRE5TX05BTUUsCisgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmFsTmFtZS5YNDAwX0FERFIsCisgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmFsTmFtZS5ESVJfTkFNRSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYWxOYW1lLkVESVBfTkFNRSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYWxOYW1lLlVSX0lELAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhbE5hbWUuSVBfQUREUiwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYWxOYW1lLlJFR19JRCB9OworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG5ldyBYNTA5Q2VydFNlbGVjdG9yKCkuYWRkUGF0aFRvTmFtZSh0eXBlc1tpXSwgKGJ5dGVbXSkgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiTm8gZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24gZm9yIHR5cGU6ICIgKyB0eXBlc1tpXSk7CisgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNhZGRQYXRoVG9OYW1lKGludCwgU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfYWRkUGF0aFRvTmFtZUxpbnRMamF2YV9sYW5nX1N0cmluZygpIHsKKyAgICAgICAgLy8gUmVncmVzc2lvbiBmb3IgSEFSTU9OWS03MjQKKyAgICAgICAgZm9yIChpbnQgdHlwZSA9IDA7IHR5cGUgPD0gODsgdHlwZSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIG5ldyBYNTA5Q2VydFNlbGVjdG9yKCkuYWRkUGF0aFRvTmFtZSh0eXBlLCAoU3RyaW5nKSBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiBleHBlY3RlZCEiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKworCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3IjWDUwOUNlcnRTZWxlY3RvcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9YNTA5Q2VydFNlbGVjdG9yKCkgeworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKC0xLCBzZWxlY3Rvci5nZXRCYXNpY0NvbnN0cmFpbnRzKCkpOworICAgICAgICBhc3NlcnRUcnVlKHNlbGVjdG9yLmdldE1hdGNoQWxsU3ViamVjdEFsdE5hbWVzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2Nsb25lKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2Nsb25lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yMSA9IChYNTA5Q2VydFNlbGVjdG9yKSBzZWxlY3Rvci5jbG9uZSgpOworCisgICAgICAgIGFzc2VydEVxdWFscyhzZWxlY3Rvci5nZXRNYXRjaEFsbFN1YmplY3RBbHROYW1lcygpLCBzZWxlY3RvcjEKKyAgICAgICAgICAgICAgICAuZ2V0TWF0Y2hBbGxTdWJqZWN0QWx0TmFtZXMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzZWxlY3Rvci5nZXRBdXRob3JpdHlLZXlJZGVudGlmaWVyKCksIHNlbGVjdG9yMQorICAgICAgICAgICAgICAgIC5nZXRBdXRob3JpdHlLZXlJZGVudGlmaWVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoc2VsZWN0b3IuZ2V0QmFzaWNDb25zdHJhaW50cygpLCBzZWxlY3RvcjEKKyAgICAgICAgICAgICAgICAuZ2V0QmFzaWNDb25zdHJhaW50cygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNlbGVjdG9yLmdldENlcnRpZmljYXRlKCksIHNlbGVjdG9yMS5nZXRDZXJ0aWZpY2F0ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNlbGVjdG9yLmdldENlcnRpZmljYXRlVmFsaWQoKSwgc2VsZWN0b3IxCisgICAgICAgICAgICAgICAgLmdldENlcnRpZmljYXRlVmFsaWQoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzZWxlY3Rvci5nZXRFeHRlbmRlZEtleVVzYWdlKCksIHNlbGVjdG9yMQorICAgICAgICAgICAgICAgIC5nZXRFeHRlbmRlZEtleVVzYWdlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoc2VsZWN0b3IuZ2V0SXNzdWVyKCksIHNlbGVjdG9yMS5nZXRJc3N1ZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzZWxlY3Rvci5nZXRJc3N1ZXJBc0J5dGVzKCksIHNlbGVjdG9yMS5nZXRJc3N1ZXJBc0J5dGVzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoc2VsZWN0b3IuZ2V0SXNzdWVyQXNTdHJpbmcoKSwgc2VsZWN0b3IxCisgICAgICAgICAgICAgICAgLmdldElzc3VlckFzU3RyaW5nKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoc2VsZWN0b3IuZ2V0S2V5VXNhZ2UoKSwgc2VsZWN0b3IxLmdldEtleVVzYWdlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoc2VsZWN0b3IuZ2V0TmFtZUNvbnN0cmFpbnRzKCksIHNlbGVjdG9yMQorICAgICAgICAgICAgICAgIC5nZXROYW1lQ29uc3RyYWludHMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzZWxlY3Rvci5nZXRQYXRoVG9OYW1lcygpLCBzZWxlY3RvcjEuZ2V0UGF0aFRvTmFtZXMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzZWxlY3Rvci5nZXRQb2xpY3koKSwgc2VsZWN0b3IxLmdldFBvbGljeSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHNlbGVjdG9yLmdldFByaXZhdGVLZXlWYWxpZCgpLCBzZWxlY3RvcjEKKyAgICAgICAgICAgICAgICAuZ2V0UHJpdmF0ZUtleVZhbGlkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoc2VsZWN0b3IuZ2V0U2VyaWFsTnVtYmVyKCksIHNlbGVjdG9yMS5nZXRTZXJpYWxOdW1iZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzZWxlY3Rvci5nZXRTdWJqZWN0KCksIHNlbGVjdG9yMS5nZXRTdWJqZWN0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoc2VsZWN0b3IuZ2V0U3ViamVjdEFsdGVybmF0aXZlTmFtZXMoKSwgc2VsZWN0b3IxCisgICAgICAgICAgICAgICAgLmdldFN1YmplY3RBbHRlcm5hdGl2ZU5hbWVzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoc2VsZWN0b3IuZ2V0U3ViamVjdEFzQnl0ZXMoKSwgc2VsZWN0b3IxCisgICAgICAgICAgICAgICAgLmdldFN1YmplY3RBc0J5dGVzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoc2VsZWN0b3IuZ2V0U3ViamVjdEFzU3RyaW5nKCksIHNlbGVjdG9yMQorICAgICAgICAgICAgICAgIC5nZXRTdWJqZWN0QXNTdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzZWxlY3Rvci5nZXRTdWJqZWN0S2V5SWRlbnRpZmllcigpLCBzZWxlY3RvcjEKKyAgICAgICAgICAgICAgICAuZ2V0U3ViamVjdEtleUlkZW50aWZpZXIoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzZWxlY3Rvci5nZXRTdWJqZWN0UHVibGljS2V5KCksIHNlbGVjdG9yMQorICAgICAgICAgICAgICAgIC5nZXRTdWJqZWN0UHVibGljS2V5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoc2VsZWN0b3IuZ2V0U3ViamVjdFB1YmxpY0tleUFsZ0lEKCksIHNlbGVjdG9yMQorICAgICAgICAgICAgICAgIC5nZXRTdWJqZWN0UHVibGljS2V5QWxnSUQoKSk7CisKKyAgICAgICAgc2VsZWN0b3IgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VsZWN0b3IuY2xvbmUoKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNnZXRBdXRob3JpdHlLZXlJZGVudGlmaWVyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldEF1dGhvcml0eUtleUlkZW50aWZpZXIoKSB7CisgICAgICAgIGJ5dGVbXSBha2lkMSA9IG5ldyBieXRlW10geyA0LCA1LCAxLCAyLCAzLCA0LCA1IH07IC8vIHJhbmRvbSB2YWx1ZQorICAgICAgICBieXRlW10gYWtpZDIgPSBuZXcgYnl0ZVtdIHsgNCwgNSwgNSwgNCwgMywgMiwgMSB9OyAvLyByYW5kb20gdmFsdWUKKyAgICAgICAgWDUwOUNlcnRTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisKKyAgICAgICAgYXNzZXJ0TnVsbCgiU2VsZWN0b3Igc2hvdWxkIHJldHVybiBudWxsIiwgc2VsZWN0b3IKKyAgICAgICAgICAgICAgICAuZ2V0QXV0aG9yaXR5S2V5SWRlbnRpZmllcigpKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0QXV0aG9yaXR5S2V5SWRlbnRpZmllcihha2lkMSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSByZXR1cm5lZCBrZXlJRCBzaG91bGQgYmUgZXF1YWwgdG8gc3BlY2lmaWVkIiwgQXJyYXlzCisgICAgICAgICAgICAgICAgLmVxdWFscyhha2lkMSwgc2VsZWN0b3IuZ2V0QXV0aG9yaXR5S2V5SWRlbnRpZmllcigpKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSByZXR1cm5lZCBrZXlJRCBzaG91bGQgYmUgZXF1YWwgdG8gc3BlY2lmaWVkIiwgQXJyYXlzCisgICAgICAgICAgICAgICAgLmVxdWFscyhha2lkMSwgc2VsZWN0b3IuZ2V0QXV0aG9yaXR5S2V5SWRlbnRpZmllcigpKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgcmV0dXJuZWQga2V5SUQgc2hvdWxkIGRpZmZlciIsIEFycmF5cy5lcXVhbHMoYWtpZDIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IuZ2V0QXV0aG9yaXR5S2V5SWRlbnRpZmllcigpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3IjZ2V0QmFzaWNDb25zdHJhaW50cygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRCYXNpY0NvbnN0cmFpbnRzKCkgeworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKyAgICAgICAgaW50W10gdmFsaWRWYWx1ZXMgPSB7IDIsIDEsIDAsIDEsIDIsIDMsIDEwLCAyMCB9OworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBzZWxlY3Rvci5zZXRCYXNpY0NvbnN0cmFpbnRzKHZhbGlkVmFsdWVzW2ldKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh2YWxpZFZhbHVlc1tpXSwgc2VsZWN0b3IuZ2V0QmFzaWNDb25zdHJhaW50cygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2dldENlcnRpZmljYXRlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldENlcnRpZmljYXRlKCkgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgWDUwOUNlcnRTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZXJ0RmFjdCA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWDUwOSIpOworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydDEgPSAoWDUwOUNlcnRpZmljYXRlKSBjZXJ0RmFjdAorICAgICAgICAgICAgICAgIC5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShUZXN0VXRpbHMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRYNTA5Q2VydGlmaWNhdGVfdjMoKSkpOworCisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0MiA9IChYNTA5Q2VydGlmaWNhdGUpIGNlcnRGYWN0CisgICAgICAgICAgICAgICAgLmdlbmVyYXRlQ2VydGlmaWNhdGUobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKFRlc3RVdGlscworICAgICAgICAgICAgICAgICAgICAgICAgLmdldFg1MDlDZXJ0aWZpY2F0ZV92MSgpKSk7CisKKyAgICAgICAgc2VsZWN0b3Iuc2V0Q2VydGlmaWNhdGUoY2VydDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoY2VydDEsIHNlbGVjdG9yLmdldENlcnRpZmljYXRlKCkpOworCisgICAgICAgIHNlbGVjdG9yLnNldENlcnRpZmljYXRlKGNlcnQyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNlcnQyLCBzZWxlY3Rvci5nZXRDZXJ0aWZpY2F0ZSgpKTsKKworICAgICAgICBzZWxlY3Rvci5zZXRDZXJ0aWZpY2F0ZShudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChzZWxlY3Rvci5nZXRDZXJ0aWZpY2F0ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNnZXRDZXJ0aWZpY2F0ZVZhbGlkKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldENlcnRpZmljYXRlVmFsaWQoKSB7CisgICAgICAgIERhdGUgZGF0ZTEgPSBuZXcgRGF0ZSgxMDApOworICAgICAgICBEYXRlIGRhdGUyID0gbmV3IERhdGUoMjAwKTsKKyAgICAgICAgRGF0ZSBkYXRlMyA9IENhbGVuZGFyLmdldEluc3RhbmNlKCkuZ2V0VGltZSgpOworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKworICAgICAgICBhc3NlcnROdWxsKCJTZWxlY3RvciBzaG91bGQgcmV0dXJuIG51bGwiLCBzZWxlY3RvcgorICAgICAgICAgICAgICAgIC5nZXRDZXJ0aWZpY2F0ZVZhbGlkKCkpOworICAgICAgICBzZWxlY3Rvci5zZXRDZXJ0aWZpY2F0ZVZhbGlkKGRhdGUxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIHJldHVybmVkIGRhdGUgc2hvdWxkIGJlIGVxdWFsIHRvIHNwZWNpZmllZCIsIGRhdGUxCisgICAgICAgICAgICAgICAgLmVxdWFscyhzZWxlY3Rvci5nZXRDZXJ0aWZpY2F0ZVZhbGlkKCkpKTsKKyAgICAgICAgc2VsZWN0b3IuZ2V0Q2VydGlmaWNhdGVWYWxpZCgpLnNldFRpbWUoMjAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIHJldHVybmVkIGRhdGUgc2hvdWxkIGJlIGVxdWFsIHRvIHNwZWNpZmllZCIsIGRhdGUxCisgICAgICAgICAgICAgICAgLmVxdWFscyhzZWxlY3Rvci5nZXRDZXJ0aWZpY2F0ZVZhbGlkKCkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSByZXR1cm5lZCBkYXRlIHNob3VsZCBkaWZmZXIiLCBkYXRlMi5lcXVhbHMoc2VsZWN0b3IKKyAgICAgICAgICAgICAgICAuZ2V0Q2VydGlmaWNhdGVWYWxpZCgpKSk7CisgICAgICAgIHNlbGVjdG9yLnNldENlcnRpZmljYXRlVmFsaWQoZGF0ZTMpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgcmV0dXJuZWQgZGF0ZSBzaG91bGQgYmUgZXF1YWwgdG8gc3BlY2lmaWVkIiwgZGF0ZTMKKyAgICAgICAgICAgICAgICAuZXF1YWxzKHNlbGVjdG9yLmdldENlcnRpZmljYXRlVmFsaWQoKSkpOworICAgICAgICBzZWxlY3Rvci5zZXRDZXJ0aWZpY2F0ZVZhbGlkKG51bGwpOworICAgICAgICBhc3NlcnROdWxsKHNlbGVjdG9yLmdldENlcnRpZmljYXRlVmFsaWQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3IjZ2V0RXh0ZW5kZWRLZXlVc2FnZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRFeHRlbmRlZEtleVVzYWdlKCkgeworICAgICAgICBIYXNoU2V0PFN0cmluZz4ga3UgPSBuZXcgSGFzaFNldDxTdHJpbmc+KEFycmF5cworICAgICAgICAgICAgICAgIC5hc0xpc3QobmV3IFN0cmluZ1tdIHsgIjEuMy42LjEuNS41LjcuMy4xIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICIxLjMuNi4xLjUuNS43LjMuMiIsICIxLjMuNi4xLjUuNS43LjMuMyIsCisgICAgICAgICAgICAgICAgICAgICAgICAiMS4zLjYuMS41LjUuNy4zLjQiLCAiMS4zLjYuMS41LjUuNy4zLjgiLAorICAgICAgICAgICAgICAgICAgICAgICAgIjEuMy42LjEuNS41LjcuMy45IiwgIjEuMy42LjEuNS41LjcuMy41IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICIxLjMuNi4xLjUuNS43LjMuNiIsICIxLjMuNi4xLjUuNS43LjMuNyIgfSkpOworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKworICAgICAgICBhc3NlcnROdWxsKCJTZWxlY3RvciBzaG91bGQgcmV0dXJuIG51bGwiLCBzZWxlY3RvcgorICAgICAgICAgICAgICAgIC5nZXRFeHRlbmRlZEtleVVzYWdlKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0RXh0ZW5kZWRLZXlVc2FnZShrdSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJUaGUgcmV0dXJuZWQgZXh0ZW5kZWRLZXlVc2FnZSBzaG91bGQgYmUgZXF1YWwgdG8gc3BlY2lmaWVkIiwKKyAgICAgICAgICAgICAgICBrdS5lcXVhbHMoc2VsZWN0b3IuZ2V0RXh0ZW5kZWRLZXlVc2FnZSgpKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZWxlY3Rvci5nZXRFeHRlbmRlZEtleVVzYWdlKCkuYWRkKCJLUklCTEVHUkFCTEkiKTsKKyAgICAgICAgICAgIGZhaWwoIlRoZSByZXR1cm5lZCBTZXQgc2hvdWxkIGJlIGltbXV0YWJsZS4iKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2dldElzc3VlcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRJc3N1ZXIoKSB7CisgICAgICAgIFg1MDBQcmluY2lwYWwgaXNzMSA9IG5ldyBYNTAwUHJpbmNpcGFsKCJPPUZpcnN0IE9yZy4iKTsKKyAgICAgICAgWDUwMFByaW5jaXBhbCBpc3MyID0gbmV3IFg1MDBQcmluY2lwYWwoIk89U2Vjb25kIE9yZy4iKTsKKyAgICAgICAgWDUwOUNlcnRTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisKKyAgICAgICAgYXNzZXJ0TnVsbCgiU2VsZWN0b3Igc2hvdWxkIHJldHVybiBudWxsIiwgc2VsZWN0b3IuZ2V0SXNzdWVyKCkpOworICAgICAgICBzZWxlY3Rvci5zZXRJc3N1ZXIoaXNzMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhlIHJldHVybmVkIGlzc3VlciBzaG91bGQgYmUgZXF1YWwgdG8gc3BlY2lmaWVkIiwgaXNzMSwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5nZXRJc3N1ZXIoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgcmV0dXJuZWQgaXNzdWVyIHNob3VsZCBkaWZmZXIiLCBpc3MyLmVxdWFscyhzZWxlY3RvcgorICAgICAgICAgICAgICAgIC5nZXRJc3N1ZXIoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2dldElzc3VlckFzQnl0ZXMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0SXNzdWVyQXNCeXRlcygpIHsKKyAgICAgICAgYnl0ZVtdIG5hbWUxID0gbmV3IGJ5dGVbXQorICAgICAgICAvLyBtYW51YWxseSBvYnRhaW5lZCBERVIgZW5jb2Rpbmcgb2YgIk89Rmlyc3QgT3JnLiIgaXNzdWVyIG5hbWU7CisgICAgICAgIHsgNDgsIDIxLCA0OSwgMTksIDQ4LCAxNywgNiwgMywgODUsIDQsIDEwLCAxOSwgMTAsIDcwLCAxMDUsIDExNCwgMTE1LAorICAgICAgICAgICAgICAgIDExNiwgMzIsIDc5LCAxMTQsIDEwMywgNDYgfTsKKworICAgICAgICBieXRlW10gbmFtZTIgPSBuZXcgYnl0ZVtdCisgICAgICAgIC8vIG1hbnVhbGx5IG9idGFpbmVkIERFUiBlbmNvZGluZyBvZiAiTz1TZWNvbmQgT3JnLiIgaXNzdWVyIG5hbWU7CisgICAgICAgIHsgNDgsIDIyLCA0OSwgMjAsIDQ4LCAxOCwgNiwgMywgODUsIDQsIDEwLCAxOSwgMTEsIDgzLCAxMDEsIDk5LCAxMTEsCisgICAgICAgICAgICAgICAgMTEwLCAxMDAsIDMyLCA3OSwgMTE0LCAxMDMsIDQ2IH07CisgICAgICAgIFg1MDBQcmluY2lwYWwgaXNzMSA9IG5ldyBYNTAwUHJpbmNpcGFsKG5hbWUxKTsKKyAgICAgICAgWDUwMFByaW5jaXBhbCBpc3MyID0gbmV3IFg1MDBQcmluY2lwYWwobmFtZTIpOworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiU2VsZWN0b3Igc2hvdWxkIHJldHVybiBudWxsIiwgc2VsZWN0b3IKKyAgICAgICAgICAgICAgICAgICAgLmdldElzc3VlckFzQnl0ZXMoKSk7CisgICAgICAgICAgICBzZWxlY3Rvci5zZXRJc3N1ZXIoaXNzMSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJUaGUgcmV0dXJuZWQgaXNzdWVyIHNob3VsZCBiZSBlcXVhbCB0byBzcGVjaWZpZWQiLAorICAgICAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKG5hbWUxLCBzZWxlY3Rvci5nZXRJc3N1ZXJBc0J5dGVzKCkpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgcmV0dXJuZWQgaXNzdWVyIHNob3VsZCBkaWZmZXIiLCBuYW1lMgorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKHNlbGVjdG9yLmdldElzc3VlckFzQnl0ZXMoKSkpOworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0SXNzdWVyKGlzczIpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIHJldHVybmVkIGlzc3VlciBzaG91bGQgYmUgZXF1YWwgdG8gc3BlY2lmaWVkIiwKKyAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmVxdWFscyhuYW1lMiwgc2VsZWN0b3IuZ2V0SXNzdWVyQXNCeXRlcygpKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2dldElzc3VlckFzU3RyaW5nKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldElzc3VlckFzU3RyaW5nKCkgeworICAgICAgICBTdHJpbmcgbmFtZTEgPSAiTz1GaXJzdCBPcmcuIjsKKyAgICAgICAgU3RyaW5nIG5hbWUyID0gIk89U2Vjb25kIE9yZy4iOworICAgICAgICBYNTAwUHJpbmNpcGFsIGlzczEgPSBuZXcgWDUwMFByaW5jaXBhbChuYW1lMSk7CisgICAgICAgIFg1MDBQcmluY2lwYWwgaXNzMiA9IG5ldyBYNTAwUHJpbmNpcGFsKG5hbWUyKTsKKyAgICAgICAgWDUwOUNlcnRTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisKKyAgICAgICAgYXNzZXJ0TnVsbCgiU2VsZWN0b3Igc2hvdWxkIHJldHVybiBudWxsIiwgc2VsZWN0b3IuZ2V0SXNzdWVyQXNTdHJpbmcoKSk7CisgICAgICAgIHNlbGVjdG9yLnNldElzc3Vlcihpc3MxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgcmV0dXJuZWQgaXNzdWVyIHNob3VsZCBiZSBlcXVhbCB0byBzcGVjaWZpZWQiLCBuYW1lMSwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5nZXRJc3N1ZXJBc1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSByZXR1cm5lZCBpc3N1ZXIgc2hvdWxkIGRpZmZlciIsIG5hbWUyLmVxdWFscyhzZWxlY3RvcgorICAgICAgICAgICAgICAgIC5nZXRJc3N1ZXJBc1N0cmluZygpKSk7CisgICAgICAgIHNlbGVjdG9yLnNldElzc3Vlcihpc3MyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgcmV0dXJuZWQgaXNzdWVyIHNob3VsZCBiZSBlcXVhbCB0byBzcGVjaWZpZWQiLCBuYW1lMiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5nZXRJc3N1ZXJBc1N0cmluZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNnZXRLZXlVc2FnZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRLZXlVc2FnZSgpIHsKKyAgICAgICAgYm9vbGVhbltdIGt1ID0gbmV3IGJvb2xlYW5bXSB7IHRydWUsIGZhbHNlLCB0cnVlLCBmYWxzZSwgdHJ1ZSwgZmFsc2UsCisgICAgICAgICAgICAgICAgdHJ1ZSwgZmFsc2UsIHRydWUgfTsKKyAgICAgICAgWDUwOUNlcnRTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisKKyAgICAgICAgYXNzZXJ0TnVsbCgiU2VsZWN0b3Igc2hvdWxkIHJldHVybiBudWxsIiwgc2VsZWN0b3IuZ2V0S2V5VXNhZ2UoKSk7CisgICAgICAgIHNlbGVjdG9yLnNldEtleVVzYWdlKGt1KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIHJldHVybmVkIGRhdGUgc2hvdWxkIGJlIGVxdWFsIHRvIHNwZWNpZmllZCIsIEFycmF5cworICAgICAgICAgICAgICAgIC5lcXVhbHMoa3UsIHNlbGVjdG9yLmdldEtleVVzYWdlKCkpKTsKKyAgICAgICAgYm9vbGVhbltdIHJlc3VsdCA9IHNlbGVjdG9yLmdldEtleVVzYWdlKCk7CisgICAgICAgIHJlc3VsdFswXSA9ICFyZXN1bHRbMF07CisgICAgICAgIGFzc2VydFRydWUoIlRoZSByZXR1cm5lZCBrZXlVc2FnZSBzaG91bGQgYmUgZXF1YWwgdG8gc3BlY2lmaWVkIiwgQXJyYXlzCisgICAgICAgICAgICAgICAgLmVxdWFscyhrdSwgc2VsZWN0b3IuZ2V0S2V5VXNhZ2UoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2dldE1hdGNoQWxsU3ViamVjdEFsdE5hbWVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1hdGNoQWxsU3ViamVjdEFsdE5hbWVzKCkgeworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIG1hdGNoQWxsTmFtZXMgaW5pdGlhbGx5IHNob3VsZCBiZSB0cnVlIiwgc2VsZWN0b3IKKyAgICAgICAgICAgICAgICAuZ2V0TWF0Y2hBbGxTdWJqZWN0QWx0TmFtZXMoKSk7CisgICAgICAgIHNlbGVjdG9yLnNldE1hdGNoQWxsU3ViamVjdEFsdE5hbWVzKGZhbHNlKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSB2YWx1ZSBzaG91bGQgYmUgZmFsc2UiLCBzZWxlY3RvcgorICAgICAgICAgICAgICAgIC5nZXRNYXRjaEFsbFN1YmplY3RBbHROYW1lcygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNnZXROYW1lQ29uc3RyYWludHMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0TmFtZUNvbnN0cmFpbnRzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworLy8gVXNlZCB0byBnZW5lcmF0ZSBmb2xsb3dpbmcgYnl0ZSBhcnJheQorLy8gICAgICAgIEdlbmVyYWxOYW1lW10gbmFtZV9jb25zdHJhaW50cyA9IG5ldyBHZW5lcmFsTmFtZVtdIHsKKy8vICAgICAgICAgICAgICAgIG5ldyBHZW5lcmFsTmFtZSgxLCAiODIyLk5hbWUiKSwKKy8vICAgICAgICAgICAgICAgIG5ldyBHZW5lcmFsTmFtZSgxLCAicmZjQDgyMi5OYW1lIiksCisvLyAgICAgICAgICAgICAgICBuZXcgR2VuZXJhbE5hbWUoMiwgIk5hbWUub3JnIiksCisvLyAgICAgICAgICAgICAgICBuZXcgR2VuZXJhbE5hbWUoMiwgImROUy5OYW1lLm9yZyIpLAorLy8KKy8vICAgICAgICAgICAgICAgIG5ldyBHZW5lcmFsTmFtZSg2LCAiaHR0cDovL1Jlc291cmNlLklkIiksCisvLyAgICAgICAgICAgICAgICBuZXcgR2VuZXJhbE5hbWUoNiwgImh0dHA6Ly91bmlmb3JtLlJlc291cmNlLklkIiksCisvLyAgICAgICAgICAgICAgICBuZXcgR2VuZXJhbE5hbWUoNywgIjEuMS4xLjEiKSwKKy8vCisvLyAgICAgICAgICAgICAgICBuZXcgR2VuZXJhbE5hbWUobmV3IGJ5dGVbXSB7IDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsCisvLyAgICAgICAgICAgICAgICAgICAgICAgIDEsIDEsIDEsIDEsIDEgfSksIH07CisvLworLy8gICAgICAgIGNvbnN0cmFpbnRCeXRlcyA9IG5ldyBieXRlW25hbWVfY29uc3RyYWludHMubGVuZ3RoXVtdOworLy8KKy8vICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5hbWVfY29uc3RyYWludHMubGVuZ3RoOyBpKyspIHsKKy8vICAgICAgICAgICAgR2VuZXJhbFN1YnRyZWUgc3VidHJlZSA9IG5ldyBHZW5lcmFsU3VidHJlZShuYW1lX2NvbnN0cmFpbnRzW2ldKTsKKy8vICAgICAgICAgICAgR2VuZXJhbFN1YnRyZWVzIHN1YnRyZWVzID0gbmV3IEdlbmVyYWxTdWJ0cmVlcygpOworLy8gICAgICAgICAgICBzdWJ0cmVlcy5hZGRTdWJ0cmVlKHN1YnRyZWUpOworLy8gICAgICAgICAgICBOYW1lQ29uc3RyYWludHMgY29uc3RyYWludHMgPSBuZXcgTmFtZUNvbnN0cmFpbnRzKHN1YnRyZWVzLAorLy8gICAgICAgICAgICAgICAgICAgIHN1YnRyZWVzKTsKKy8vICAgICAgICAgICAgY29uc3RyYWludEJ5dGVzW2ldID0gY29uc3RyYWludHMuZ2V0RW5jb2RlZCgpOworLy8gICAgICAgIH0KKy8vICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlhYWCIrQXJyYXlzLmRlZXBUb1N0cmluZyhjb25zdHJhaW50Qnl0ZXMpKyJYWFgiKTsKKworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbnN0cmFpbnRCeXRlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0TmFtZUNvbnN0cmFpbnRzKGNvbnN0cmFpbnRCeXRlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoY29uc3RyYWludEJ5dGVzW2ldLCBzZWxlY3RvcgorICAgICAgICAgICAgICAgICAgICAuZ2V0TmFtZUNvbnN0cmFpbnRzKCkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2dldFBhdGhUb05hbWVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFBhdGhUb05hbWVzKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgR2VuZXJhbE5hbWUgc2FuMCA9IG5ldyBHZW5lcmFsTmFtZShuZXcgT3RoZXJOYW1lKCIxLjIuMy40LjUiLAorICAgICAgICAgICAgICAgICAgICBuZXcgYnl0ZVtdIHsgMSwgMiwgMCwgMSB9KSk7CisgICAgICAgICAgICBHZW5lcmFsTmFtZSBzYW4xID0gbmV3IEdlbmVyYWxOYW1lKDEsICJyZmNAODIyLk5hbWUiKTsKKyAgICAgICAgICAgIEdlbmVyYWxOYW1lIHNhbjIgPSBuZXcgR2VuZXJhbE5hbWUoMiwgImROU05hbWUiKTsKKyAgICAgICAgICAgIEdlbmVyYWxOYW1lIHNhbjMgPSBuZXcgR2VuZXJhbE5hbWUobmV3IE9SQWRkcmVzcygpKTsKKyAgICAgICAgICAgIEdlbmVyYWxOYW1lIHNhbjQgPSBuZXcgR2VuZXJhbE5hbWUobmV3IE5hbWUoIk89T3JnYW5pemF0aW9uIikpOworICAgICAgICAgICAgR2VuZXJhbE5hbWUgc2FuNiA9IG5ldyBHZW5lcmFsTmFtZSg2LCAiaHR0cDovL3VuaWZvcm0uUmVzb3VyY2UuSWQiKTsKKyAgICAgICAgICAgIEdlbmVyYWxOYW1lIHNhbjcgPSBuZXcgR2VuZXJhbE5hbWUoNywgIjEuMS4xLjEiKTsKKyAgICAgICAgICAgIEdlbmVyYWxOYW1lIHNhbjggPSBuZXcgR2VuZXJhbE5hbWUoOCwgIjEuMi4zLjQ0NDQuNTU1NTUiKTsKKworICAgICAgICAgICAgR2VuZXJhbE5hbWVzIHNhbnMxID0gbmV3IEdlbmVyYWxOYW1lcygpOworICAgICAgICAgICAgc2FuczEuYWRkTmFtZShzYW4wKTsKKyAgICAgICAgICAgIHNhbnMxLmFkZE5hbWUoc2FuMSk7CisgICAgICAgICAgICBzYW5zMS5hZGROYW1lKHNhbjIpOworICAgICAgICAgICAgc2FuczEuYWRkTmFtZShzYW4zKTsKKyAgICAgICAgICAgIHNhbnMxLmFkZE5hbWUoc2FuNCk7CisgICAgICAgICAgICBzYW5zMS5hZGROYW1lKHNhbjYpOworICAgICAgICAgICAgc2FuczEuYWRkTmFtZShzYW43KTsKKyAgICAgICAgICAgIHNhbnMxLmFkZE5hbWUoc2FuOCk7CisgICAgICAgICAgICBHZW5lcmFsTmFtZXMgc2FuczIgPSBuZXcgR2VuZXJhbE5hbWVzKCk7CisgICAgICAgICAgICBzYW5zMi5hZGROYW1lKHNhbjApOworCisgICAgICAgICAgICBUZXN0Q2VydCBjZXJ0MSA9IG5ldyBUZXN0Q2VydChzYW5zMSk7CisgICAgICAgICAgICBUZXN0Q2VydCBjZXJ0MiA9IG5ldyBUZXN0Q2VydChzYW5zMik7CisgICAgICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKyAgICAgICAgICAgIHNlbGVjdG9yLnNldE1hdGNoQWxsU3ViamVjdEFsdE5hbWVzKHRydWUpOworCisgICAgICAgICAgICBzZWxlY3Rvci5zZXRQYXRoVG9OYW1lcyhudWxsKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkFueSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggaW4gdGhlIGNhc2Ugb2YgbnVsbCAiCisgICAgICAgICAgICAgICAgICAgICsgInN1YmplY3RBbHRlcm5hdGl2ZU5hbWVzIGNyaXRlcmlhLiIsIHNlbGVjdG9yCisgICAgICAgICAgICAgICAgICAgIC5tYXRjaChjZXJ0MSkKKyAgICAgICAgICAgICAgICAgICAgJiYgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKworICAgICAgICAgICAgQ29sbGVjdGlvbjxMaXN0PD8+PiBzYW5zID0gc2FuczEuZ2V0UGFpcnNMaXN0KCk7CisKKyAgICAgICAgICAgIHNlbGVjdG9yLnNldFBhdGhUb05hbWVzKHNhbnMpOworICAgICAgICAgICAgc2VsZWN0b3IuZ2V0UGF0aFRvTmFtZXMoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2dldFBvbGljeSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQb2xpY3koKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmdbXSBwb2xpY2llczEgPSBuZXcgU3RyaW5nW10geyAiMS4zLjYuMS41LjUuNy4zLjEiLAorICAgICAgICAgICAgICAgICIxLjMuNi4xLjUuNS43LjMuMiIsICIxLjMuNi4xLjUuNS43LjMuMyIsICIxLjMuNi4xLjUuNS43LjMuNCIsCisgICAgICAgICAgICAgICAgIjEuMy42LjEuNS41LjcuMy44IiwgIjEuMy42LjEuNS41LjcuMy45IiwgIjEuMy42LjEuNS41LjcuMy41IiwKKyAgICAgICAgICAgICAgICAiMS4zLjYuMS41LjUuNy4zLjYiLCAiMS4zLjYuMS41LjUuNy4zLjciIH07CisKKyAgICAgICAgU3RyaW5nW10gcG9saWNpZXMyID0gbmV3IFN0cmluZ1tdIHsgIjEuMy42LjcuMy4xIiB9OworCisgICAgICAgIEhhc2hTZXQ8U3RyaW5nPiBwMSA9IG5ldyBIYXNoU2V0PFN0cmluZz4oQXJyYXlzLmFzTGlzdChwb2xpY2llczEpKTsKKyAgICAgICAgSGFzaFNldDxTdHJpbmc+IHAyID0gbmV3IEhhc2hTZXQ8U3RyaW5nPihBcnJheXMuYXNMaXN0KHBvbGljaWVzMikpOworCisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworCisgICAgICAgIHNlbGVjdG9yLnNldFBvbGljeShudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChzZWxlY3Rvci5nZXRQb2xpY3koKSk7CisKKyAgICAgICAgc2VsZWN0b3Iuc2V0UG9saWN5KHAxKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgcmV0dXJuZWQgZGF0ZSBzaG91bGQgYmUgZXF1YWwgdG8gc3BlY2lmaWVkIiwgcDEsIHNlbGVjdG9yLmdldFBvbGljeSgpKTsKKworICAgICAgICBzZWxlY3Rvci5zZXRQb2xpY3kocDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlRoZSByZXR1cm5lZCBkYXRlIHNob3VsZCBiZSBlcXVhbCB0byBzcGVjaWZpZWQiLCBwMiwgc2VsZWN0b3IuZ2V0UG9saWN5KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2dldFByaXZhdGVLZXlWYWxpZCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQcml2YXRlS2V5VmFsaWQoKSB7CisgICAgICAgIERhdGUgZGF0ZTEgPSBuZXcgRGF0ZSgxMDApOworICAgICAgICBEYXRlIGRhdGUyID0gbmV3IERhdGUoMjAwKTsKKyAgICAgICAgWDUwOUNlcnRTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisKKyAgICAgICAgYXNzZXJ0TnVsbCgiU2VsZWN0b3Igc2hvdWxkIHJldHVybiBudWxsIiwgc2VsZWN0b3IuZ2V0UHJpdmF0ZUtleVZhbGlkKCkpOworICAgICAgICBzZWxlY3Rvci5zZXRQcml2YXRlS2V5VmFsaWQoZGF0ZTEpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgcmV0dXJuZWQgZGF0ZSBzaG91bGQgYmUgZXF1YWwgdG8gc3BlY2lmaWVkIiwgZGF0ZTEKKyAgICAgICAgICAgICAgICAuZXF1YWxzKHNlbGVjdG9yLmdldFByaXZhdGVLZXlWYWxpZCgpKSk7CisgICAgICAgIHNlbGVjdG9yLmdldFByaXZhdGVLZXlWYWxpZCgpLnNldFRpbWUoMjAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIHJldHVybmVkIGRhdGUgc2hvdWxkIGJlIGVxdWFsIHRvIHNwZWNpZmllZCIsIGRhdGUxCisgICAgICAgICAgICAgICAgLmVxdWFscyhzZWxlY3Rvci5nZXRQcml2YXRlS2V5VmFsaWQoKSkpOworICAgICAgICBhc3NlcnRGYWxzZSgiVGhlIHJldHVybmVkIGRhdGUgc2hvdWxkIGRpZmZlciIsIGRhdGUyLmVxdWFscyhzZWxlY3RvcgorICAgICAgICAgICAgICAgIC5nZXRQcml2YXRlS2V5VmFsaWQoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2dldFNlcmlhbE51bWJlcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTZXJpYWxOdW1iZXIoKSB7CisgICAgICAgIEJpZ0ludGVnZXIgc2VyMSA9IG5ldyBCaWdJbnRlZ2VyKCIxMDAwMCIpOworICAgICAgICBCaWdJbnRlZ2VyIHNlcjIgPSBuZXcgQmlnSW50ZWdlcigiMTAwMDEiKTsKKyAgICAgICAgWDUwOUNlcnRTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisKKyAgICAgICAgYXNzZXJ0TnVsbCgiU2VsZWN0b3Igc2hvdWxkIHJldHVybiBudWxsIiwgc2VsZWN0b3IuZ2V0U2VyaWFsTnVtYmVyKCkpOworICAgICAgICBzZWxlY3Rvci5zZXRTZXJpYWxOdW1iZXIoc2VyMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhlIHJldHVybmVkIHNlcmlhbCBudW1iZXIgc2hvdWxkIGJlIGVxdWFsIHRvIHNwZWNpZmllZCIsCisgICAgICAgICAgICAgICAgc2VyMSwgc2VsZWN0b3IuZ2V0U2VyaWFsTnVtYmVyKCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiVGhlIHJldHVybmVkIHNlcmlhbCBudW1iZXIgc2hvdWxkIGRpZmZlciIsIHNlcjIKKyAgICAgICAgICAgICAgICAuZXF1YWxzKHNlbGVjdG9yLmdldFNlcmlhbE51bWJlcigpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3IjZ2V0U3ViamVjdCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTdWJqZWN0KCkgeworICAgICAgICBYNTAwUHJpbmNpcGFsIHN1YjEgPSBuZXcgWDUwMFByaW5jaXBhbCgiTz1GaXJzdCBPcmcuIik7CisgICAgICAgIFg1MDBQcmluY2lwYWwgc3ViMiA9IG5ldyBYNTAwUHJpbmNpcGFsKCJPPVNlY29uZCBPcmcuIik7CisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworCisgICAgICAgIGFzc2VydE51bGwoIlNlbGVjdG9yIHNob3VsZCByZXR1cm4gbnVsbCIsIHNlbGVjdG9yLmdldFN1YmplY3QoKSk7CisgICAgICAgIHNlbGVjdG9yLnNldFN1YmplY3Qoc3ViMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhlIHJldHVybmVkIHN1YmplY3Qgc2hvdWxkIGJlIGVxdWFsIHRvIHNwZWNpZmllZCIsIHN1YjEsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IuZ2V0U3ViamVjdCgpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSByZXR1cm5lZCBzdWJqZWN0IHNob3VsZCBkaWZmZXIiLCBzdWIyLmVxdWFscyhzZWxlY3RvcgorICAgICAgICAgICAgICAgIC5nZXRTdWJqZWN0KCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNnZXRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEdlbmVyYWxOYW1lIHNhbjEgPSBuZXcgR2VuZXJhbE5hbWUoMSwgInJmY0A4MjIuTmFtZSIpOworICAgICAgICAgICAgR2VuZXJhbE5hbWUgc2FuMiA9IG5ldyBHZW5lcmFsTmFtZSgyLCAiZE5TTmFtZSIpOworCisgICAgICAgICAgICBHZW5lcmFsTmFtZXMgc2FucyA9IG5ldyBHZW5lcmFsTmFtZXMoKTsKKyAgICAgICAgICAgIHNhbnMuYWRkTmFtZShzYW4xKTsKKyAgICAgICAgICAgIHNhbnMuYWRkTmFtZShzYW4yKTsKKworICAgICAgICAgICAgVGVzdENlcnQgY2VydF8xID0gbmV3IFRlc3RDZXJ0KHNhbnMpOworICAgICAgICAgICAgWDUwOUNlcnRTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisKKyAgICAgICAgICAgIGFzc2VydE51bGwoIlNlbGVjdG9yIHNob3VsZCByZXR1cm4gbnVsbCIsIHNlbGVjdG9yCisgICAgICAgICAgICAgICAgICAgIC5nZXRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcygpKTsKKworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0U3ViamVjdEFsdGVybmF0aXZlTmFtZXMoc2Fucy5nZXRQYWlyc0xpc3QoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydF8xKSk7CisgICAgICAgICAgICBzZWxlY3Rvci5nZXRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcygpLmNsZWFyKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJUaGUgbW9kaWZpY2F0aW9uIG9mIGluaXRpYWxpemF0aW9uIG9iamVjdCAiCisgICAgICAgICAgICAgICAgICAgICsgInNob3VsZCBub3QgYWZmZWN0IHRoZSBtb2RpZmljYXRpb24gIgorICAgICAgICAgICAgICAgICAgICArICJvZiBpbnRlcm5hbCBvYmplY3QuIiwgc2VsZWN0b3IubWF0Y2goY2VydF8xKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNnZXRTdWJqZWN0QXNCeXRlcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTdWJqZWN0QXNCeXRlcygpIHsKKyAgICAgICAgYnl0ZVtdIG5hbWUxID0gbmV3IGJ5dGVbXQorICAgICAgICAvLyBtYW51YWxseSBvYnRhaW5lZCBERVIgZW5jb2Rpbmcgb2YgIk89Rmlyc3QgT3JnLiIgaXNzdWVyIG5hbWU7CisgICAgICAgIHsgNDgsIDIxLCA0OSwgMTksIDQ4LCAxNywgNiwgMywgODUsIDQsIDEwLCAxOSwgMTAsIDcwLCAxMDUsIDExNCwgMTE1LAorICAgICAgICAgICAgICAgIDExNiwgMzIsIDc5LCAxMTQsIDEwMywgNDYgfTsKKyAgICAgICAgYnl0ZVtdIG5hbWUyID0gbmV3IGJ5dGVbXQorICAgICAgICAvLyBtYW51YWxseSBvYnRhaW5lZCBERVIgZW5jb2Rpbmcgb2YgIk89U2Vjb25kIE9yZy4iIGlzc3VlciBuYW1lOworICAgICAgICB7IDQ4LCAyMiwgNDksIDIwLCA0OCwgMTgsIDYsIDMsIDg1LCA0LCAxMCwgMTksIDExLCA4MywgMTAxLCA5OSwgMTExLAorICAgICAgICAgICAgICAgIDExMCwgMTAwLCAzMiwgNzksIDExNCwgMTAzLCA0NiB9OworCisgICAgICAgIFg1MDBQcmluY2lwYWwgc3ViMSA9IG5ldyBYNTAwUHJpbmNpcGFsKG5hbWUxKTsKKyAgICAgICAgWDUwMFByaW5jaXBhbCBzdWIyID0gbmV3IFg1MDBQcmluY2lwYWwobmFtZTIpOworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiU2VsZWN0b3Igc2hvdWxkIHJldHVybiBudWxsIiwgc2VsZWN0b3IKKyAgICAgICAgICAgICAgICAgICAgLmdldFN1YmplY3RBc0J5dGVzKCkpOworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0U3ViamVjdChzdWIxKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlRoZSByZXR1cm5lZCBpc3N1ZXIgc2hvdWxkIGJlIGVxdWFsIHRvIHNwZWNpZmllZCIsCisgICAgICAgICAgICAgICAgICAgIEFycmF5cy5lcXVhbHMobmFtZTEsIHNlbGVjdG9yLmdldFN1YmplY3RBc0J5dGVzKCkpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgcmV0dXJuZWQgaXNzdWVyIHNob3VsZCBkaWZmZXIiLCBuYW1lMgorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKHNlbGVjdG9yLmdldFN1YmplY3RBc0J5dGVzKCkpKTsKKyAgICAgICAgICAgIHNlbGVjdG9yLnNldFN1YmplY3Qoc3ViMik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJUaGUgcmV0dXJuZWQgaXNzdWVyIHNob3VsZCBiZSBlcXVhbCB0byBzcGVjaWZpZWQiLAorICAgICAgICAgICAgICAgICAgICBBcnJheXMuZXF1YWxzKG5hbWUyLCBzZWxlY3Rvci5nZXRTdWJqZWN0QXNCeXRlcygpKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2dldFN1YmplY3RBc1N0cmluZygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRTdWJqZWN0QXNTdHJpbmcoKSB7CisgICAgICAgIFN0cmluZyBuYW1lMSA9ICJPPUZpcnN0IE9yZy4iOworICAgICAgICBTdHJpbmcgbmFtZTIgPSAiTz1TZWNvbmQgT3JnLiI7CisgICAgICAgIFg1MDBQcmluY2lwYWwgc3ViMSA9IG5ldyBYNTAwUHJpbmNpcGFsKG5hbWUxKTsKKyAgICAgICAgWDUwMFByaW5jaXBhbCBzdWIyID0gbmV3IFg1MDBQcmluY2lwYWwobmFtZTIpOworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKworICAgICAgICBhc3NlcnROdWxsKCJTZWxlY3RvciBzaG91bGQgcmV0dXJuIG51bGwiLCBzZWxlY3Rvci5nZXRTdWJqZWN0QXNTdHJpbmcoKSk7CisgICAgICAgIHNlbGVjdG9yLnNldFN1YmplY3Qoc3ViMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGhlIHJldHVybmVkIHN1YmplY3Qgc2hvdWxkIGJlIGVxdWFsIHRvIHNwZWNpZmllZCIsCisgICAgICAgICAgICAgICAgbmFtZTEsIHNlbGVjdG9yLmdldFN1YmplY3RBc1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSByZXR1cm5lZCBzdWJqZWN0IHNob3VsZCBkaWZmZXIiLCBuYW1lMi5lcXVhbHMoc2VsZWN0b3IKKyAgICAgICAgICAgICAgICAuZ2V0U3ViamVjdEFzU3RyaW5nKCkpKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0U3ViamVjdChzdWIyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJUaGUgcmV0dXJuZWQgc3ViamVjdCBzaG91bGQgYmUgZXF1YWwgdG8gc3BlY2lmaWVkIiwKKyAgICAgICAgICAgICAgICBuYW1lMiwgc2VsZWN0b3IuZ2V0U3ViamVjdEFzU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2dldFN1YmplY3RLZXlJZGVudGlmaWVyKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFN1YmplY3RLZXlJZGVudGlmaWVyKCkgeworICAgICAgICBieXRlW10gc2tpZDEgPSBuZXcgYnl0ZVtdIHsgMSwgMiwgMywgNCwgNSB9OyAvLyByYW5kb20gdmFsdWUKKyAgICAgICAgYnl0ZVtdIHNraWQyID0gbmV3IGJ5dGVbXSB7IDQsIDUsIDUsIDQsIDMsIDIsIDEgfTsgLy8gcmFuZG9tIHZhbHVlCisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworCisgICAgICAgIGFzc2VydE51bGwoIlNlbGVjdG9yIHNob3VsZCByZXR1cm4gbnVsbCIsIHNlbGVjdG9yCisgICAgICAgICAgICAgICAgLmdldFN1YmplY3RLZXlJZGVudGlmaWVyKCkpOworICAgICAgICBzZWxlY3Rvci5zZXRTdWJqZWN0S2V5SWRlbnRpZmllcihza2lkMSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSByZXR1cm5lZCBrZXlJRCBzaG91bGQgYmUgZXF1YWwgdG8gc3BlY2lmaWVkIiwgQXJyYXlzCisgICAgICAgICAgICAgICAgLmVxdWFscyhza2lkMSwgc2VsZWN0b3IuZ2V0U3ViamVjdEtleUlkZW50aWZpZXIoKSkpOworICAgICAgICBzZWxlY3Rvci5nZXRTdWJqZWN0S2V5SWRlbnRpZmllcigpWzBdKys7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSByZXR1cm5lZCBrZXlJRCBzaG91bGQgYmUgZXF1YWwgdG8gc3BlY2lmaWVkIiwgQXJyYXlzCisgICAgICAgICAgICAgICAgLmVxdWFscyhza2lkMSwgc2VsZWN0b3IuZ2V0U3ViamVjdEtleUlkZW50aWZpZXIoKSkpOworICAgICAgICBhc3NlcnRGYWxzZSgiVGhlIHJldHVybmVkIGtleUlEIHNob3VsZCBkaWZmZXIiLCBBcnJheXMuZXF1YWxzKHNraWQyLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLmdldFN1YmplY3RLZXlJZGVudGlmaWVyKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNnZXRTdWJqZWN0UHVibGljS2V5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFN1YmplY3RQdWJsaWNLZXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICAvLyBTdWJqZWN0UHVibGljS2V5SW5mbyA6Oj0gU0VRVUVOQ0UgeworICAgICAgICAvLyBhbGdvcml0aG0gQWxnb3JpdGhtSWRlbnRpZmllciwKKyAgICAgICAgLy8gc3ViamVjdFB1YmxpY0tleSBCSVQgU1RSSU5HIH0KKyAgICAgICAgYnl0ZVtdIGVuYyA9IHsgMHgzMCwgMHgwRSwgLy8gU0VRVUVOQ0UKKyAgICAgICAgICAgICAgICAweDMwLCAweDA3LCAvLyBTRVFVRU5DRQorICAgICAgICAgICAgICAgIDB4MDYsIDB4MDIsIDB4MDMsIDB4MDUsLy8gT0lECisgICAgICAgICAgICAgICAgMHgwMSwgMHgwMSwgMHgwNywgLy8gQU5ZCisgICAgICAgICAgICAgICAgMHgwMywgMHgwMywgMHgwMSwgMHgwMSwgMHgwNiwgLy8gc3ViamVjdFB1YmxpY0tleQorICAgICAgICB9OworCisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworCisgICAgICAgIHNlbGVjdG9yLnNldFN1YmplY3RQdWJsaWNLZXkoZW5jKTsKKyAgICAgICAgUHVibGljS2V5IGtleSA9IHNlbGVjdG9yLmdldFN1YmplY3RQdWJsaWNLZXkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIwLjMuNSIsIGtleS5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWC41MDkiLCBrZXkuZ2V0Rm9ybWF0KCkpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoZW5jLCBrZXkuZ2V0RW5jb2RlZCgpKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoa2V5LnRvU3RyaW5nKCkpOworCisgICAgICAgIGtleSA9IG5ldyBNeVB1YmxpY0tleSgpOworCisgICAgICAgIHNlbGVjdG9yLnNldFN1YmplY3RQdWJsaWNLZXkoa2V5KTsKKyAgICAgICAgUHVibGljS2V5IGtleUFjdHVhbCA9IHNlbGVjdG9yLmdldFN1YmplY3RQdWJsaWNLZXkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGtleSwga2V5QWN0dWFsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGtleS5nZXRBbGdvcml0aG0oKSwga2V5QWN0dWFsLmdldEFsZ29yaXRobSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNnZXRTdWJqZWN0UHVibGljS2V5QWxnSUQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0U3ViamVjdFB1YmxpY0tleUFsZ0lEKCkgeworCisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworICAgICAgICBTdHJpbmdbXSB2YWxpZE9JRHMgPSB7ICIwLjAuMjAiLCAiMS4yNS4wIiwgIjIuMC4zOSIsICIwLjIuMTAiLCAiMS4zNS4xNSIsCisgICAgICAgICAgICAgICAgIjIuMTcuODkiIH07CisKKyAgICAgICAgYXNzZXJ0TnVsbCgiU2VsZWN0b3Igc2hvdWxkIHJldHVybiBudWxsIiwgc2VsZWN0b3IKKyAgICAgICAgICAgICAgICAuZ2V0U3ViamVjdFB1YmxpY0tleUFsZ0lEKCkpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRPSURzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHNlbGVjdG9yLnNldFN1YmplY3RQdWJsaWNLZXlBbGdJRCh2YWxpZE9JRHNbaV0pOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyh2YWxpZE9JRHNbaV0sIHNlbGVjdG9yLmdldFN1YmplY3RQdWJsaWNLZXlBbGdJRCgpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInQgPSAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgICAgIC8vZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBwa2FpZDEgPSAiMS4yLjg0MC4xMTM1NDkuMS4xLjEiOyAvLyBSU0EgZW5jcnlwdGlvbgorICAgICAgICBTdHJpbmcgcGthaWQyID0gIjEuMi44NDAuMTEzNTQ5LjEuMS40IjsgLy8gTUQ1IHdpdGggUlNBIGVuY3J5cHRpb24KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0U3ViamVjdFB1YmxpY0tleUFsZ0lEKHBrYWlkMSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgcmV0dXJuZWQgb2lkIHNob3VsZCBiZSBlcXVhbCB0byBzcGVjaWZpZWQiLCBwa2FpZDEKKyAgICAgICAgICAgICAgICAuZXF1YWxzKHNlbGVjdG9yLmdldFN1YmplY3RQdWJsaWNLZXlBbGdJRCgpKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgcmV0dXJuZWQgb2lkIHNob3VsZCBkaWZmZXIiLCBwa2FpZDIuZXF1YWxzKHNlbGVjdG9yCisgICAgICAgICAgICAgICAgLmdldFN1YmplY3RQdWJsaWNLZXlBbGdJRCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3IjbWF0Y2goamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfbWF0Y2hMamF2YV9zZWN1cml0eV9jZXJ0X0NlcnRpZmljYXRlKCkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworICAgICAgICBhc3NlcnRGYWxzZShzZWxlY3Rvci5tYXRjaChudWxsKSk7CisKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNlcnRGYWN0ID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYNTA5Iik7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0MSA9IChYNTA5Q2VydGlmaWNhdGUpIGNlcnRGYWN0CisgICAgICAgICAgICAgICAgLmdlbmVyYXRlQ2VydGlmaWNhdGUobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKFRlc3RVdGlscworICAgICAgICAgICAgICAgICAgICAgICAgLmdldFg1MDlDZXJ0aWZpY2F0ZV92MygpKSk7CisKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIGNlcnQyID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2VydEZhY3QKKyAgICAgICAgICAgICAgICAuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oVGVzdFV0aWxzCisgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0WDUwOUNlcnRpZmljYXRlX3YxKCkpKTsKKworICAgICAgICBzZWxlY3Rvci5zZXRDZXJ0aWZpY2F0ZShjZXJ0MSk7CisgICAgICAgIGFzc2VydFRydWUoc2VsZWN0b3IubWF0Y2goY2VydDEpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKworICAgICAgICBzZWxlY3Rvci5zZXRDZXJ0aWZpY2F0ZShjZXJ0Mik7CisgICAgICAgIGFzc2VydEZhbHNlKHNlbGVjdG9yLm1hdGNoKGNlcnQxKSk7CisgICAgICAgIGFzc2VydFRydWUoc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNzZXRBdXRob3JpdHlLZXlJZGVudGlmaWVyKGJ5dGVbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEF1dGhvcml0eUtleUlkZW50aWZpZXJMQiQoKSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKworICAgICAgICBieXRlW10gYWtpZDEgPSBuZXcgYnl0ZVtdIHsgMSwgMiwgMywgNCwgNSB9OyAvLyByYW5kb20gdmFsdWUKKyAgICAgICAgYnl0ZVtdIGFraWQyID0gbmV3IGJ5dGVbXSB7IDUsIDQsIDMsIDIsIDEgfTsgLy8gcmFuZG9tIHZhbHVlCisgICAgICAgIFRlc3RDZXJ0IGNlcnQxID0gbmV3IFRlc3RDZXJ0KGFraWQxKTsKKyAgICAgICAgVGVzdENlcnQgY2VydDIgPSBuZXcgVGVzdENlcnQoYWtpZDIpOworCisgICAgICAgIHNlbGVjdG9yLnNldEF1dGhvcml0eUtleUlkZW50aWZpZXIobnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQxKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisgICAgICAgIGFzc2VydE51bGwoc2VsZWN0b3IuZ2V0QXV0aG9yaXR5S2V5SWRlbnRpZmllcigpKTsKKworICAgICAgICBzZWxlY3Rvci5zZXRBdXRob3JpdHlLZXlJZGVudGlmaWVyKGFraWQxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGNlcnRpZmljYXRlIHNob3VsZCBub3QgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG5vdCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0QXV0aG9yaXR5S2V5SWRlbnRpZmllcihha2lkMik7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG5vdCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGNlcnRpZmljYXRlIHNob3VsZCBub3QgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisKKyAgICAgICAgYWtpZDJbMF0rKzsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGNlcnRpZmljYXRlIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNzZXRCYXNpY0NvbnN0cmFpbnRzKGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEJhc2ljQ29uc3RyYWludHNMaW50KCkgeworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKyAgICAgICAgaW50W10gaW52YWxpZFZhbHVlcyA9IHsgLTMsIC00LCAtNSwgMTAwMDAwMDAwMCB9OworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWRWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2VsZWN0b3Iuc2V0QmFzaWNDb25zdHJhaW50cygtMyk7CisgICAgICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkIik7CisgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpbnRbXSB2YWxpZFZhbHVlcyA9IHsgLTIsIC0xLCAwLCAxLCAyLCAzLCAxMCwgMjAgfTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0QmFzaWNDb25zdHJhaW50cyh2YWxpZFZhbHVlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModmFsaWRWYWx1ZXNbaV0sIHNlbGVjdG9yLmdldEJhc2ljQ29uc3RyYWludHMoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNzZXRDZXJ0aWZpY2F0ZShqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRDZXJ0aWZpY2F0ZUxqYXZhX3NlY3VyaXR5X2NlcnRfWDUwOUNlcnRpZmljYXRlKCkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisKKyAgICAgICAgVGVzdENlcnQgY2VydDEgPSBuZXcgVGVzdENlcnQoInNhbWUgY2VydGlmaWNhdGUiKTsKKyAgICAgICAgVGVzdENlcnQgY2VydDIgPSBuZXcgVGVzdENlcnQoIm90aGVyIGNlcnRpZmljYXRlIik7CisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworCisgICAgICAgIHNlbGVjdG9yLnNldENlcnRpZmljYXRlKG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJBbnkgY2VydGlmaWNhdGVzIHNob3VsZCBtYXRjaCBpbiB0aGUgY2FzZSBvZiBudWxsICIKKyAgICAgICAgICAgICAgICArICJjZXJ0aWZpY2F0ZUVxdWFscyBjcml0ZXJpYS4iLCBzZWxlY3Rvci5tYXRjaChjZXJ0MSkKKyAgICAgICAgICAgICAgICAmJiBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgICAgICBzZWxlY3Rvci5zZXRDZXJ0aWZpY2F0ZShjZXJ0MSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG5vdCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0Q2VydGlmaWNhdGUoY2VydDIpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgICAgICBzZWxlY3Rvci5zZXRDZXJ0aWZpY2F0ZShudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChzZWxlY3Rvci5nZXRDZXJ0aWZpY2F0ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNzZXRDZXJ0aWZpY2F0ZVZhbGlkKGphdmEudXRpbC5EYXRlKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0Q2VydGlmaWNhdGVWYWxpZExqYXZhX3V0aWxfRGF0ZSgpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKworICAgICAgICBEYXRlIGRhdGUxID0gbmV3IERhdGUoMTAwKTsKKyAgICAgICAgRGF0ZSBkYXRlMiA9IG5ldyBEYXRlKDIwMCk7CisgICAgICAgIFRlc3RDZXJ0IGNlcnQxID0gbmV3IFRlc3RDZXJ0KGRhdGUxKTsKKyAgICAgICAgVGVzdENlcnQgY2VydDIgPSBuZXcgVGVzdENlcnQoZGF0ZTIpOworCisgICAgICAgIHNlbGVjdG9yLnNldENlcnRpZmljYXRlVmFsaWQobnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoc2VsZWN0b3IuZ2V0Q2VydGlmaWNhdGVWYWxpZCgpKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0Q2VydGlmaWNhdGVWYWxpZChkYXRlMSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG5vdCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0Q2VydGlmaWNhdGVWYWxpZChkYXRlMik7CisgICAgICAgIGRhdGUyLnNldFRpbWUoMzAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGNlcnRpZmljYXRlIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNzZXRFeHRlbmRlZEtleVVzYWdlKFNldDxTdHJpbmc+KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0RXh0ZW5kZWRLZXlVc2FnZUxqYXZhX3V0aWxfU2V0KCkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIEhhc2hTZXQ8U3RyaW5nPiBrdTEgPSBuZXcgSGFzaFNldDxTdHJpbmc+KEFycmF5cworICAgICAgICAgICAgICAgIC5hc0xpc3QobmV3IFN0cmluZ1tdIHsgIjEuMy42LjEuNS41LjcuMy4xIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICIxLjMuNi4xLjUuNS43LjMuMiIsICIxLjMuNi4xLjUuNS43LjMuMyIsCisgICAgICAgICAgICAgICAgICAgICAgICAiMS4zLjYuMS41LjUuNy4zLjQiLCAiMS4zLjYuMS41LjUuNy4zLjgiLAorICAgICAgICAgICAgICAgICAgICAgICAgIjEuMy42LjEuNS41LjcuMy45IiwgIjEuMy42LjEuNS41LjcuMy41IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICIxLjMuNi4xLjUuNS43LjMuNiIsICIxLjMuNi4xLjUuNS43LjMuNyIgfSkpOworICAgICAgICBIYXNoU2V0PFN0cmluZz4ga3UyID0gbmV3IEhhc2hTZXQ8U3RyaW5nPihBcnJheXMuYXNMaXN0KG5ldyBTdHJpbmdbXSB7CisgICAgICAgICAgICAgICAgIjEuMy42LjEuNS41LjcuMy4xIiwgIjEuMy42LjEuNS41LjcuMy4yIiwgIjEuMy42LjEuNS41LjcuMy4zIiwKKyAgICAgICAgICAgICAgICAiMS4zLjYuMS41LjUuNy4zLjQiLCAiMS4zLjYuMS41LjUuNy4zLjgiLCAiMS4zLjYuMS41LjUuNy4zLjkiLAorICAgICAgICAgICAgICAgICIxLjMuNi4xLjUuNS43LjMuNSIsICIxLjMuNi4xLjUuNS43LjMuNiIgfSkpOworICAgICAgICBUZXN0Q2VydCBjZXJ0MSA9IG5ldyBUZXN0Q2VydChrdTEpOworICAgICAgICBUZXN0Q2VydCBjZXJ0MiA9IG5ldyBUZXN0Q2VydChrdTIpOworCisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZWxlY3Rvci5zZXRFeHRlbmRlZEtleVVzYWdlKG51bGwpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQW55IGNlcnRpZmljYXRlIHNob3VsZCBtYXRjaCBpbiB0aGUgY2FzZSBvZiBudWxsICIKKyAgICAgICAgICAgICAgICArICJleHRlbmRlZEtleVVzYWdlIGNyaXRlcmlhLiIsIHNlbGVjdG9yLm1hdGNoKGNlcnQxKQorICAgICAgICAgICAgICAgICYmIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZWxlY3Rvci5zZXRFeHRlbmRlZEtleVVzYWdlKGt1MSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoa3UxLCBzZWxlY3Rvci5nZXRFeHRlbmRlZEtleVVzYWdlKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZWxlY3Rvci5zZXRFeHRlbmRlZEtleVVzYWdlKGt1Mik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoa3UyLCBzZWxlY3Rvci5nZXRFeHRlbmRlZEtleVVzYWdlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI3NldElzc3VlcihieXRlW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRJc3N1ZXJMQiQoKSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBieXRlW10gbmFtZTEgPSBuZXcgYnl0ZVtdCisgICAgICAgIC8vIG1hbnVhbGx5IG9idGFpbmVkIERFUiBlbmNvZGluZyBvZiAiTz1GaXJzdCBPcmcuIiBpc3N1ZXIgbmFtZTsKKyAgICAgICAgeyA0OCwgMjEsIDQ5LCAxOSwgNDgsIDE3LCA2LCAzLCA4NSwgNCwgMTAsIDE5LCAxMCwgNzAsIDEwNSwgMTE0LCAxMTUsCisgICAgICAgICAgICAgICAgMTE2LCAzMiwgNzksIDExNCwgMTAzLCA0NiB9OworICAgICAgICBieXRlW10gbmFtZTIgPSBuZXcgYnl0ZVtdCisgICAgICAgIC8vIG1hbnVhbGx5IG9idGFpbmVkIERFUiBlbmNvZGluZyBvZiAiTz1TZWNvbmQgT3JnLiIgaXNzdWVyIG5hbWU7CisgICAgICAgIHsgNDgsIDIyLCA0OSwgMjAsIDQ4LCAxOCwgNiwgMywgODUsIDQsIDEwLCAxOSwgMTEsIDgzLCAxMDEsIDk5LCAxMTEsCisgICAgICAgICAgICAgICAgMTEwLCAxMDAsIDMyLCA3OSwgMTE0LCAxMDMsIDQ2IH07CisgICAgICAgIFg1MDBQcmluY2lwYWwgaXNzMSA9IG5ldyBYNTAwUHJpbmNpcGFsKG5hbWUxKTsKKyAgICAgICAgWDUwMFByaW5jaXBhbCBpc3MyID0gbmV3IFg1MDBQcmluY2lwYWwobmFtZTIpOworICAgICAgICBUZXN0Q2VydCBjZXJ0MSA9IG5ldyBUZXN0Q2VydChpc3MxKTsKKyAgICAgICAgVGVzdENlcnQgY2VydDIgPSBuZXcgVGVzdENlcnQoaXNzMik7CisKKyAgICAgICAgWDUwOUNlcnRTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlbGVjdG9yLnNldElzc3VlcigoYnl0ZVtdKSBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkFueSBjZXJ0aWZpY2F0ZXMgc2hvdWxkIG1hdGNoICIKKyAgICAgICAgICAgICAgICArICJpbiB0aGUgY2FzZSBvZiBudWxsIGlzc3VlciBjcml0ZXJpYS4iLCBzZWxlY3Rvci5tYXRjaChjZXJ0MSkKKyAgICAgICAgICAgICAgICAmJiBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0SXNzdWVyKG5hbWUxKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG5vdCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlbGVjdG9yLnNldElzc3VlcihuYW1lMik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI3NldElzc3VlcihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0SXNzdWVyTGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworCisgICAgICAgIFN0cmluZyBuYW1lMSA9ICJPPUZpcnN0IE9yZy4iOworICAgICAgICBTdHJpbmcgbmFtZTIgPSAiTz1TZWNvbmQgT3JnLiI7CisgICAgICAgIFg1MDBQcmluY2lwYWwgaXNzMSA9IG5ldyBYNTAwUHJpbmNpcGFsKG5hbWUxKTsKKyAgICAgICAgWDUwMFByaW5jaXBhbCBpc3MyID0gbmV3IFg1MDBQcmluY2lwYWwobmFtZTIpOworICAgICAgICBUZXN0Q2VydCBjZXJ0MSA9IG5ldyBUZXN0Q2VydChpc3MxKTsKKyAgICAgICAgVGVzdENlcnQgY2VydDIgPSBuZXcgVGVzdENlcnQoaXNzMik7CisKKyAgICAgICAgWDUwOUNlcnRTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlbGVjdG9yLnNldElzc3VlcigoU3RyaW5nKSBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkFueSBjZXJ0aWZpY2F0ZXMgc2hvdWxkIG1hdGNoICIKKyAgICAgICAgICAgICAgICArICJpbiB0aGUgY2FzZSBvZiBudWxsIGlzc3VlciBjcml0ZXJpYS4iLCBzZWxlY3Rvci5tYXRjaChjZXJ0MSkKKyAgICAgICAgICAgICAgICAmJiBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0SXNzdWVyKG5hbWUxKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG5vdCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlbGVjdG9yLnNldElzc3VlcihuYW1lMik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI3NldElzc3VlcihqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldElzc3VlckxqYXZheF9zZWN1cml0eV9hdXRoX3g1MDBfWDUwMFByaW5jaXBhbCgpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBYNTAwUHJpbmNpcGFsIGlzczEgPSBuZXcgWDUwMFByaW5jaXBhbCgiTz1GaXJzdCBPcmcuIik7CisgICAgICAgIFg1MDBQcmluY2lwYWwgaXNzMiA9IG5ldyBYNTAwUHJpbmNpcGFsKCJPPVNlY29uZCBPcmcuIik7CisgICAgICAgIFRlc3RDZXJ0IGNlcnQxID0gbmV3IFRlc3RDZXJ0KGlzczEpOworICAgICAgICBUZXN0Q2VydCBjZXJ0MiA9IG5ldyBUZXN0Q2VydChpc3MyKTsKKyAgICAgICAgWDUwOUNlcnRTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisKKyAgICAgICAgc2VsZWN0b3Iuc2V0SXNzdWVyKChYNTAwUHJpbmNpcGFsKSBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQW55IGNlcnRpZmljYXRlcyBzaG91bGQgbWF0Y2ggIgorICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIG51bGwgaXNzdWVyIGNyaXRlcmlhLiIsIHNlbGVjdG9yLm1hdGNoKGNlcnQxKQorICAgICAgICAgICAgICAgICYmIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisgICAgICAgIHNlbGVjdG9yLnNldElzc3Vlcihpc3MxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGNlcnRpZmljYXRlIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDEpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbm90IG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgICAgICBzZWxlY3Rvci5zZXRJc3N1ZXIoaXNzMik7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3Ijc2V0S2V5VXNhZ2UoYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldEtleVVzYWdlWigpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW5bXSBrdTEgPSBuZXcgYm9vbGVhbltdIHsgdHJ1ZSwgdHJ1ZSwgdHJ1ZSwgdHJ1ZSwgdHJ1ZSwgdHJ1ZSwKKyAgICAgICAgICAgICAgICB0cnVlLCB0cnVlLCB0cnVlIH07CisgICAgICAgIC8vIGRlY2lwaGVyT25seSBpcyBkaXNhbGxvd2VkCisgICAgICAgIGJvb2xlYW5bXSBrdTIgPSBuZXcgYm9vbGVhbltdIHsgdHJ1ZSwgdHJ1ZSwgdHJ1ZSwgdHJ1ZSwgdHJ1ZSwgdHJ1ZSwKKyAgICAgICAgICAgICAgICB0cnVlLCB0cnVlLCBmYWxzZSB9OworICAgICAgICBUZXN0Q2VydCBjZXJ0MSA9IG5ldyBUZXN0Q2VydChrdTEpOworICAgICAgICBUZXN0Q2VydCBjZXJ0MiA9IG5ldyBUZXN0Q2VydChrdTIpOworICAgICAgICBUZXN0Q2VydCBjZXJ0MyA9IG5ldyBUZXN0Q2VydCgoYm9vbGVhbltdKSBudWxsKTsKKworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKworICAgICAgICBzZWxlY3Rvci5zZXRLZXlVc2FnZShudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQW55IGNlcnRpZmljYXRlIHNob3VsZCBtYXRjaCBpbiB0aGUgY2FzZSBvZiBudWxsICIKKyAgICAgICAgICAgICAgICArICJrZXlVc2FnZSBjcml0ZXJpYS4iLCBzZWxlY3Rvci5tYXRjaChjZXJ0MSkKKyAgICAgICAgICAgICAgICAmJiBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgICAgICBzZWxlY3Rvci5zZXRLZXlVc2FnZShrdTEpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjZXJ0MSkpOworICAgICAgICBhc3NlcnRGYWxzZSgiVGhlIGNlcnRpZmljYXRlIHNob3VsZCBub3QgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSB3aGljaCBkb2VzIG5vdCBoYXZlIGEga2V5VXNhZ2UgZXh0ZW5zaW9uICIKKyAgICAgICAgICAgICAgICArICJpbXBsaWNpdGx5IGFsbG93cyBhbGwga2V5VXNhZ2UgdmFsdWVzLiIsIHNlbGVjdG9yCisgICAgICAgICAgICAgICAgLm1hdGNoKGNlcnQzKSk7CisgICAgICAgIHNlbGVjdG9yLnNldEtleVVzYWdlKGt1Mik7CisgICAgICAgIGt1MlswXSA9ICFrdTJbMF07CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3Ijc2V0TWF0Y2hBbGxTdWJqZWN0QWx0TmFtZXMoYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldE1hdGNoQWxsU3ViamVjdEFsdE5hbWVzWigpIHsKKyAgICAgICAgVGVzdENlcnQgY2VydCA9IG5ldyBUZXN0Q2VydCgpOworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKworICAgICAgICBhc3NlcnRUcnVlKHNlbGVjdG9yLm1hdGNoKGNlcnQpKTsKKworICAgICAgICBhc3NlcnRGYWxzZShzZWxlY3Rvci5tYXRjaChudWxsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3Ijc2V0TmFtZUNvbnN0cmFpbnRzKGJ5dGVbXQorICAgICAqICAgICAgICBieXRlcykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldE5hbWVDb25zdHJhaW50c0xCJCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisvLyAgICAgICAgR2VuZXJhbE5hbWVbXSBuYW1lX2NvbnN0cmFpbnRzID0gbmV3IEdlbmVyYWxOYW1lW10geworLy8gICAgICAgICAgICAgICAgbmV3IEdlbmVyYWxOYW1lKDEsICI4MjIuTmFtZSIpLAorLy8gICAgICAgICAgICAgICAgbmV3IEdlbmVyYWxOYW1lKDEsICJyZmNAODIyLk5hbWUiKSwKKy8vICAgICAgICAgICAgICAgIG5ldyBHZW5lcmFsTmFtZSgyLCAiTmFtZS5vcmciKSwKKy8vICAgICAgICAgICAgICAgIG5ldyBHZW5lcmFsTmFtZSgyLCAiZE5TLk5hbWUub3JnIiksCisvLworLy8gICAgICAgICAgICAgICAgbmV3IEdlbmVyYWxOYW1lKDYsICJodHRwOi8vUmVzb3VyY2UuSWQiKSwKKy8vICAgICAgICAgICAgICAgIG5ldyBHZW5lcmFsTmFtZSg2LCAiaHR0cDovL3VuaWZvcm0uUmVzb3VyY2UuSWQiKSwKKy8vICAgICAgICAgICAgICAgIG5ldyBHZW5lcmFsTmFtZSg3LCAiMS4xLjEuMSIpLAorLy8KKy8vICAgICAgICAgICAgICAgIG5ldyBHZW5lcmFsTmFtZShuZXcgYnl0ZVtdIHsgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgMSwgMSwgMSwgMSwgMSB9KSwgfTsKKy8vCisvLyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuYW1lX2NvbnN0cmFpbnRzLmxlbmd0aDsgaSsrKSB7CisvLyAgICAgICAgICAgIEdlbmVyYWxTdWJ0cmVlIHN1YnRyZWUgPSBuZXcgR2VuZXJhbFN1YnRyZWUobmFtZV9jb25zdHJhaW50c1tpXSk7CisvLyAgICAgICAgICAgIEdlbmVyYWxTdWJ0cmVlcyBzdWJ0cmVlcyA9IG5ldyBHZW5lcmFsU3VidHJlZXMoKTsKKy8vICAgICAgICAgICAgc3VidHJlZXMuYWRkU3VidHJlZShzdWJ0cmVlKTsKKy8vICAgICAgICAgICAgTmFtZUNvbnN0cmFpbnRzIGNvbnN0cmFpbnRzID0gbmV3IE5hbWVDb25zdHJhaW50cyhzdWJ0cmVlcywKKy8vICAgICAgICAgICAgICAgICAgICBzdWJ0cmVlcyk7CisvLyAgICAgICAgfQorICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbnN0cmFpbnRCeXRlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0TmFtZUNvbnN0cmFpbnRzKGNvbnN0cmFpbnRCeXRlc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoY29uc3RyYWludEJ5dGVzW2ldLCBzZWxlY3RvcgorICAgICAgICAgICAgICAgICAgICAuZ2V0TmFtZUNvbnN0cmFpbnRzKCkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI3NldFBhdGhUb05hbWVzKENvbGxlY3Rpb248TGlzdDw/Pj4pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRQYXRoVG9OYW1lc0xqYXZhX3V0aWxfQ29sbGVjdGlvbigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEdlbmVyYWxOYW1lIHNhbjAgPSBuZXcgR2VuZXJhbE5hbWUobmV3IE90aGVyTmFtZSgiMS4yLjMuNC41IiwKKyAgICAgICAgICAgICAgICAgICAgbmV3IGJ5dGVbXSB7IDEsIDIsIDAsIDEgfSkpOworICAgICAgICAgICAgR2VuZXJhbE5hbWUgc2FuMSA9IG5ldyBHZW5lcmFsTmFtZSgxLCAicmZjQDgyMi5OYW1lIik7CisgICAgICAgICAgICBHZW5lcmFsTmFtZSBzYW4yID0gbmV3IEdlbmVyYWxOYW1lKDIsICJkTlNOYW1lIik7CisgICAgICAgICAgICBHZW5lcmFsTmFtZSBzYW4zID0gbmV3IEdlbmVyYWxOYW1lKG5ldyBPUkFkZHJlc3MoKSk7CisgICAgICAgICAgICBHZW5lcmFsTmFtZSBzYW40ID0gbmV3IEdlbmVyYWxOYW1lKG5ldyBOYW1lKCJPPU9yZ2FuaXphdGlvbiIpKTsKKyAgICAgICAgICAgIEdlbmVyYWxOYW1lIHNhbjYgPSBuZXcgR2VuZXJhbE5hbWUoNiwgImh0dHA6Ly91bmlmb3JtLlJlc291cmNlLklkIik7CisgICAgICAgICAgICBHZW5lcmFsTmFtZSBzYW43ID0gbmV3IEdlbmVyYWxOYW1lKDcsICIxLjEuMS4xIik7CisgICAgICAgICAgICBHZW5lcmFsTmFtZSBzYW44ID0gbmV3IEdlbmVyYWxOYW1lKDgsICIxLjIuMy40NDQ0LjU1NTU1Iik7CisKKyAgICAgICAgICAgIEdlbmVyYWxOYW1lcyBzYW5zMSA9IG5ldyBHZW5lcmFsTmFtZXMoKTsKKyAgICAgICAgICAgIHNhbnMxLmFkZE5hbWUoc2FuMCk7CisgICAgICAgICAgICBzYW5zMS5hZGROYW1lKHNhbjEpOworICAgICAgICAgICAgc2FuczEuYWRkTmFtZShzYW4yKTsKKyAgICAgICAgICAgIHNhbnMxLmFkZE5hbWUoc2FuMyk7CisgICAgICAgICAgICBzYW5zMS5hZGROYW1lKHNhbjQpOworICAgICAgICAgICAgc2FuczEuYWRkTmFtZShzYW42KTsKKyAgICAgICAgICAgIHNhbnMxLmFkZE5hbWUoc2FuNyk7CisgICAgICAgICAgICBzYW5zMS5hZGROYW1lKHNhbjgpOworICAgICAgICAgICAgR2VuZXJhbE5hbWVzIHNhbnMyID0gbmV3IEdlbmVyYWxOYW1lcygpOworICAgICAgICAgICAgc2FuczIuYWRkTmFtZShzYW4wKTsKKworICAgICAgICAgICAgVGVzdENlcnQgY2VydDEgPSBuZXcgVGVzdENlcnQoc2FuczEpOworICAgICAgICAgICAgVGVzdENlcnQgY2VydDIgPSBuZXcgVGVzdENlcnQoc2FuczIpOworICAgICAgICAgICAgWDUwOUNlcnRTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisgICAgICAgICAgICBzZWxlY3Rvci5zZXRNYXRjaEFsbFN1YmplY3RBbHROYW1lcyh0cnVlKTsKKworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0UGF0aFRvTmFtZXMobnVsbCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJBbnkgY2VydGlmaWNhdGUgc2hvdWxkIG1hdGNoIGluIHRoZSBjYXNlIG9mIG51bGwgIgorICAgICAgICAgICAgICAgICAgICArICJzdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcyBjcml0ZXJpYS4iLCBzZWxlY3RvcgorICAgICAgICAgICAgICAgICAgICAubWF0Y2goY2VydDEpCisgICAgICAgICAgICAgICAgICAgICYmIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisKKyAgICAgICAgICAgIENvbGxlY3Rpb248TGlzdDw/Pj4gc2FucyA9IHNhbnMxLmdldFBhaXJzTGlzdCgpOworCisgICAgICAgICAgICBzZWxlY3Rvci5zZXRQYXRoVG9OYW1lcyhzYW5zKTsKKyAgICAgICAgICAgIHNlbGVjdG9yLmdldFBhdGhUb05hbWVzKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNzZXRQb2xpY3koU2V0PFN0cmluZz4pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRQb2xpY3lMamF2YV91dGlsX1NldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1tdIHBvbGljaWVzMSA9IG5ldyBTdHJpbmdbXSB7ICIxLjMuNi4xLjUuNS43LjMuMSIsCisgICAgICAgICAgICAgICAgIjEuMy42LjEuNS41LjcuMy4yIiwgIjEuMy42LjEuNS41LjcuMy4zIiwgIjEuMy42LjEuNS41LjcuMy40IiwKKyAgICAgICAgICAgICAgICAiMS4zLjYuMS41LjUuNy4zLjgiLCAiMS4zLjYuMS41LjUuNy4zLjkiLCAiMS4zLjYuMS41LjUuNy4zLjUiLAorICAgICAgICAgICAgICAgICIxLjMuNi4xLjUuNS43LjMuNiIsICIxLjMuNi4xLjUuNS43LjMuNyIgfTsKKworICAgICAgICBTdHJpbmdbXSBwb2xpY2llczIgPSBuZXcgU3RyaW5nW10geyAiMS4zLjYuNy4zLjEiIH07CisKKyAgICAgICAgSGFzaFNldDxTdHJpbmc+IHAxID0gbmV3IEhhc2hTZXQ8U3RyaW5nPihBcnJheXMuYXNMaXN0KHBvbGljaWVzMSkpOworICAgICAgICBIYXNoU2V0PFN0cmluZz4gcDIgPSBuZXcgSGFzaFNldDxTdHJpbmc+KEFycmF5cy5hc0xpc3QocG9saWNpZXMyKSk7CisKKyAgICAgICAgWDUwOUNlcnRTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisKKyAgICAgICAgVGVzdENlcnQgY2VydDEgPSBuZXcgVGVzdENlcnQocG9saWNpZXMxKTsKKyAgICAgICAgVGVzdENlcnQgY2VydDIgPSBuZXcgVGVzdENlcnQocG9saWNpZXMyKTsKKworICAgICAgICBzZWxlY3Rvci5zZXRQb2xpY3kobnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoIkFueSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggaW4gdGhlIGNhc2Ugb2YgbnVsbCAiCisgICAgICAgICAgICAgICAgKyAicHJpdmF0ZUtleVZhbGlkIGNyaXRlcmlhLiIsIHNlbGVjdG9yLm1hdGNoKGNlcnQxKQorICAgICAgICAgICAgICAgICYmIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisKKyAgICAgICAgc2VsZWN0b3Iuc2V0UG9saWN5KHAxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGNlcnRpZmljYXRlIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDEpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbm90IG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworCisgICAgICAgIHNlbGVjdG9yLnNldFBvbGljeShwMik7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG5vdCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGNlcnRpZmljYXRlIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNzZXRQcml2YXRlS2V5VmFsaWQoamF2YS51dGlsLkRhdGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRQcml2YXRlS2V5VmFsaWRMamF2YV91dGlsX0RhdGUoKQorICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgRGF0ZSBkYXRlMSA9IG5ldyBEYXRlKDEwMDAwMDAwMCk7CisgICAgICAgIERhdGUgZGF0ZTIgPSBuZXcgRGF0ZSgyMDAwMDAwMDApOworICAgICAgICBEYXRlIGRhdGUzID0gbmV3IERhdGUoMzAwMDAwMDAwKTsKKyAgICAgICAgRGF0ZSBkYXRlNCA9IG5ldyBEYXRlKDE1MDAwMDAwMCk7CisgICAgICAgIERhdGUgZGF0ZTUgPSBuZXcgRGF0ZSgyNTAwMDAwMDApOworICAgICAgICBUZXN0Q2VydCBjZXJ0MSA9IG5ldyBUZXN0Q2VydChkYXRlMSwgZGF0ZTIpOworICAgICAgICBUZXN0Q2VydCBjZXJ0MiA9IG5ldyBUZXN0Q2VydChkYXRlMiwgZGF0ZTMpOworCisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworCisgICAgICAgIHNlbGVjdG9yLnNldFByaXZhdGVLZXlWYWxpZChudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQW55IGNlcnRpZmljYXRlIHNob3VsZCBtYXRjaCBpbiB0aGUgY2FzZSBvZiBudWxsICIKKyAgICAgICAgICAgICAgICArICJwcml2YXRlS2V5VmFsaWQgY3JpdGVyaWEuIiwgc2VsZWN0b3IubWF0Y2goY2VydDEpCisgICAgICAgICAgICAgICAgJiYgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0UHJpdmF0ZUtleVZhbGlkKGRhdGU0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGNlcnRpZmljYXRlIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDEpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbm90IG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgICAgICBzZWxlY3Rvci5zZXRQcml2YXRlS2V5VmFsaWQoZGF0ZTUpOworICAgICAgICBkYXRlNS5zZXRUaW1lKGRhdGU0LmdldFRpbWUoKSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3Ijc2V0U2VyaWFsTnVtYmVyKGphdmEubWF0aC5CaWdJbnRlZ2VyKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0U2VyaWFsTnVtYmVyTGphdmFfbWF0aF9CaWdJbnRlZ2VyKCkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIEJpZ0ludGVnZXIgc2VyMSA9IG5ldyBCaWdJbnRlZ2VyKCIxMDAwMCIpOworICAgICAgICBCaWdJbnRlZ2VyIHNlcjIgPSBuZXcgQmlnSW50ZWdlcigiMTAwMDEiKTsKKyAgICAgICAgVGVzdENlcnQgY2VydDEgPSBuZXcgVGVzdENlcnQoc2VyMSk7CisgICAgICAgIFRlc3RDZXJ0IGNlcnQyID0gbmV3IFRlc3RDZXJ0KHNlcjIpOworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKworICAgICAgICBzZWxlY3Rvci5zZXRTZXJpYWxOdW1iZXIobnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoIkFueSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggaW4gdGhlIGNhc2Ugb2YgbnVsbCAiCisgICAgICAgICAgICAgICAgKyAic2VyaWFsTnVtYmVyIGNyaXRlcmlhLiIsIHNlbGVjdG9yLm1hdGNoKGNlcnQxKQorICAgICAgICAgICAgICAgICYmIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisgICAgICAgIHNlbGVjdG9yLnNldFNlcmlhbE51bWJlcihzZXIxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGNlcnRpZmljYXRlIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDEpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbm90IG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgICAgICBzZWxlY3Rvci5zZXRTZXJpYWxOdW1iZXIoc2VyMik7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3Ijc2V0U3ViamVjdChieXRlW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRTdWJqZWN0TEIkKCkgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIG5hbWUxID0gbmV3IGJ5dGVbXQorICAgICAgICAvLyBtYW51YWxseSBvYnRhaW5lZCBERVIgZW5jb2Rpbmcgb2YgIk89Rmlyc3QgT3JnLiIgaXNzdWVyIG5hbWU7CisgICAgICAgIHsgNDgsIDIxLCA0OSwgMTksIDQ4LCAxNywgNiwgMywgODUsIDQsIDEwLCAxOSwgMTAsIDcwLCAxMDUsIDExNCwgMTE1LAorICAgICAgICAgICAgICAgIDExNiwgMzIsIDc5LCAxMTQsIDEwMywgNDYgfTsKKyAgICAgICAgYnl0ZVtdIG5hbWUyID0gbmV3IGJ5dGVbXQorICAgICAgICAvLyBtYW51YWxseSBvYnRhaW5lZCBERVIgZW5jb2Rpbmcgb2YgIk89U2Vjb25kIE9yZy4iIGlzc3VlciBuYW1lOworICAgICAgICB7IDQ4LCAyMiwgNDksIDIwLCA0OCwgMTgsIDYsIDMsIDg1LCA0LCAxMCwgMTksIDExLCA4MywgMTAxLCA5OSwgMTExLAorICAgICAgICAgICAgICAgIDExMCwgMTAwLCAzMiwgNzksIDExNCwgMTAzLCA0NiB9OworICAgICAgICBYNTAwUHJpbmNpcGFsIHN1YjEgPSBuZXcgWDUwMFByaW5jaXBhbChuYW1lMSk7CisgICAgICAgIFg1MDBQcmluY2lwYWwgc3ViMiA9IG5ldyBYNTAwUHJpbmNpcGFsKG5hbWUyKTsKKyAgICAgICAgVGVzdENlcnQgY2VydDEgPSBuZXcgVGVzdENlcnQoc3ViMSk7CisgICAgICAgIFRlc3RDZXJ0IGNlcnQyID0gbmV3IFRlc3RDZXJ0KHN1YjIpOworCisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZWxlY3Rvci5zZXRTdWJqZWN0KChieXRlW10pIG51bGwpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQW55IGNlcnRpZmljYXRlcyBzaG91bGQgbWF0Y2ggIgorICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIG51bGwgaXNzdWVyIGNyaXRlcmlhLiIsIHNlbGVjdG9yLm1hdGNoKGNlcnQxKQorICAgICAgICAgICAgICAgICYmIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZWxlY3Rvci5zZXRTdWJqZWN0KG5hbWUxKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG5vdCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlbGVjdG9yLnNldFN1YmplY3QobmFtZTIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGNlcnRpZmljYXRlIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNzZXRTdWJqZWN0KGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRTdWJqZWN0TGphdmFfbGFuZ19TdHJpbmcoKSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgbmFtZTEgPSAiTz1GaXJzdCBPcmcuIjsKKyAgICAgICAgU3RyaW5nIG5hbWUyID0gIk89U2Vjb25kIE9yZy4iOworICAgICAgICBYNTAwUHJpbmNpcGFsIHN1YjEgPSBuZXcgWDUwMFByaW5jaXBhbChuYW1lMSk7CisgICAgICAgIFg1MDBQcmluY2lwYWwgc3ViMiA9IG5ldyBYNTAwUHJpbmNpcGFsKG5hbWUyKTsKKyAgICAgICAgVGVzdENlcnQgY2VydDEgPSBuZXcgVGVzdENlcnQoc3ViMSk7CisgICAgICAgIFRlc3RDZXJ0IGNlcnQyID0gbmV3IFRlc3RDZXJ0KHN1YjIpOworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0U3ViamVjdCgoU3RyaW5nKSBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBJT0V4Y2VwdGlvbiB3YXMgdGhyb3duLiIpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIkFueSBjZXJ0aWZpY2F0ZXMgc2hvdWxkIG1hdGNoICIKKyAgICAgICAgICAgICAgICArICJpbiB0aGUgY2FzZSBvZiBudWxsIHN1YmplY3QgY3JpdGVyaWEuIiwgc2VsZWN0b3IKKyAgICAgICAgICAgICAgICAubWF0Y2goY2VydDEpCisgICAgICAgICAgICAgICAgJiYgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlbGVjdG9yLnNldFN1YmplY3QobmFtZTEpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGNlcnRpZmljYXRlIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDEpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbm90IG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0U3ViamVjdChuYW1lMik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI3NldFN1YmplY3QoamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWwpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRTdWJqZWN0TGphdmF4X3NlY3VyaXR5X2F1dGhfeDUwMF9YNTAwUHJpbmNpcGFsKCkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIFg1MDBQcmluY2lwYWwgc3ViMSA9IG5ldyBYNTAwUHJpbmNpcGFsKCJPPUZpcnN0IE9yZy4iKTsKKyAgICAgICAgWDUwMFByaW5jaXBhbCBzdWIyID0gbmV3IFg1MDBQcmluY2lwYWwoIk89U2Vjb25kIE9yZy4iKTsKKyAgICAgICAgVGVzdENlcnQgY2VydDEgPSBuZXcgVGVzdENlcnQoc3ViMSk7CisgICAgICAgIFRlc3RDZXJ0IGNlcnQyID0gbmV3IFRlc3RDZXJ0KHN1YjIpOworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKworICAgICAgICBzZWxlY3Rvci5zZXRTdWJqZWN0KChYNTAwUHJpbmNpcGFsKSBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQW55IGNlcnRpZmljYXRlcyBzaG91bGQgbWF0Y2ggIgorICAgICAgICAgICAgICAgICsgImluIHRoZSBjYXNlIG9mIG51bGwgc3ViamNldCBjcml0ZXJpYS4iLCBzZWxlY3RvcgorICAgICAgICAgICAgICAgIC5tYXRjaChjZXJ0MSkKKyAgICAgICAgICAgICAgICAmJiBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgICAgICBzZWxlY3Rvci5zZXRTdWJqZWN0KHN1YjEpOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjZXJ0MSkpOworICAgICAgICBhc3NlcnRGYWxzZSgiVGhlIGNlcnRpZmljYXRlIHNob3VsZCBub3QgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisgICAgICAgIHNlbGVjdG9yLnNldFN1YmplY3Qoc3ViMik7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3Ijc2V0U3ViamVjdEFsdGVybmF0aXZlTmFtZXMoQ29sbGVjdGlvbjxMaXN0PD8+PikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3NldFN1YmplY3RBbHRlcm5hdGl2ZU5hbWVzTGphdmFfdXRpbF9Db2xsZWN0aW9uKCkgeworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBHZW5lcmFsTmFtZSBzYW4wID0gbmV3IEdlbmVyYWxOYW1lKG5ldyBPdGhlck5hbWUoIjEuMi4zLjQuNSIsCisgICAgICAgICAgICAgICAgICAgIG5ldyBieXRlW10geyAxLCAyLCAwLCAxIH0pKTsKKyAgICAgICAgICAgIEdlbmVyYWxOYW1lIHNhbjEgPSBuZXcgR2VuZXJhbE5hbWUoMSwgInJmY0A4MjIuTmFtZSIpOworICAgICAgICAgICAgR2VuZXJhbE5hbWUgc2FuMiA9IG5ldyBHZW5lcmFsTmFtZSgyLCAiZE5TTmFtZSIpOworICAgICAgICAgICAgR2VuZXJhbE5hbWUgc2FuMyA9IG5ldyBHZW5lcmFsTmFtZShuZXcgT1JBZGRyZXNzKCkpOworICAgICAgICAgICAgR2VuZXJhbE5hbWUgc2FuNCA9IG5ldyBHZW5lcmFsTmFtZShuZXcgTmFtZSgiTz1Pcmdhbml6YXRpb24iKSk7CisgICAgICAgICAgICBHZW5lcmFsTmFtZSBzYW42ID0gbmV3IEdlbmVyYWxOYW1lKDYsICJodHRwOi8vdW5pZm9ybS5SZXNvdXJjZS5JZCIpOworICAgICAgICAgICAgR2VuZXJhbE5hbWUgc2FuNyA9IG5ldyBHZW5lcmFsTmFtZSg3LCAiMS4xLjEuMSIpOworICAgICAgICAgICAgR2VuZXJhbE5hbWUgc2FuOCA9IG5ldyBHZW5lcmFsTmFtZSg4LCAiMS4yLjMuNDQ0NC41NTU1NSIpOworCisgICAgICAgICAgICBHZW5lcmFsTmFtZXMgc2FuczEgPSBuZXcgR2VuZXJhbE5hbWVzKCk7CisgICAgICAgICAgICBzYW5zMS5hZGROYW1lKHNhbjApOworICAgICAgICAgICAgc2FuczEuYWRkTmFtZShzYW4xKTsKKyAgICAgICAgICAgIHNhbnMxLmFkZE5hbWUoc2FuMik7CisgICAgICAgICAgICBzYW5zMS5hZGROYW1lKHNhbjMpOworICAgICAgICAgICAgc2FuczEuYWRkTmFtZShzYW40KTsKKyAgICAgICAgICAgIHNhbnMxLmFkZE5hbWUoc2FuNik7CisgICAgICAgICAgICBzYW5zMS5hZGROYW1lKHNhbjcpOworICAgICAgICAgICAgc2FuczEuYWRkTmFtZShzYW44KTsKKyAgICAgICAgICAgIEdlbmVyYWxOYW1lcyBzYW5zMiA9IG5ldyBHZW5lcmFsTmFtZXMoKTsKKyAgICAgICAgICAgIHNhbnMyLmFkZE5hbWUoc2FuMCk7CisKKyAgICAgICAgICAgIFRlc3RDZXJ0IGNlcnQxID0gbmV3IFRlc3RDZXJ0KHNhbnMxKTsKKyAgICAgICAgICAgIFRlc3RDZXJ0IGNlcnQyID0gbmV3IFRlc3RDZXJ0KHNhbnMyKTsKKyAgICAgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0TWF0Y2hBbGxTdWJqZWN0QWx0TmFtZXModHJ1ZSk7CisKKyAgICAgICAgICAgIHNlbGVjdG9yLnNldFN1YmplY3RBbHRlcm5hdGl2ZU5hbWVzKG51bGwpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiQW55IGNlcnRpZmljYXRlIHNob3VsZCBtYXRjaCBpbiB0aGUgY2FzZSBvZiBudWxsICIKKyAgICAgICAgICAgICAgICAgICAgKyAic3ViamVjdEFsdGVybmF0aXZlTmFtZXMgY3JpdGVyaWEuIiwgc2VsZWN0b3IKKyAgICAgICAgICAgICAgICAgICAgLm1hdGNoKGNlcnQxKQorICAgICAgICAgICAgICAgICAgICAmJiBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworCisgICAgICAgICAgICBDb2xsZWN0aW9uPExpc3Q8Pz4+IHNhbnMgPSBzYW5zMS5nZXRQYWlyc0xpc3QoKTsKKworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0U3ViamVjdEFsdGVybmF0aXZlTmFtZXMoc2Fucyk7CisKKyAgICAgICAgICAgIHNlbGVjdG9yLmdldFN1YmplY3RBbHRlcm5hdGl2ZU5hbWVzKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvciNzZXRTdWJqZWN0S2V5SWRlbnRpZmllcihieXRlW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRTdWJqZWN0S2V5SWRlbnRpZmllckxCJCgpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBza2lkMSA9IG5ldyBieXRlW10geyAxLCAyLCAzLCA0LCA1IH07IC8vIHJhbmRvbSB2YWx1ZQorICAgICAgICBieXRlW10gc2tpZDIgPSBuZXcgYnl0ZVtdIHsgNSwgNCwgMywgMiwgMSB9OyAvLyByYW5kb20gdmFsdWUKKyAgICAgICAgVGVzdENlcnQgY2VydDEgPSBuZXcgVGVzdENlcnQoc2tpZDEpOworICAgICAgICBUZXN0Q2VydCBjZXJ0MiA9IG5ldyBUZXN0Q2VydChza2lkMik7CisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworCisgICAgICAgIHNlbGVjdG9yLnNldFN1YmplY3RLZXlJZGVudGlmaWVyKG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJBbnkgY2VydGlmaWNhdGUgc2hvdWxkIG1hdGNoIGluIHRoZSBjYXNlIG9mIG51bGwgIgorICAgICAgICAgICAgICAgICsgInNlcmlhbE51bWJlciBjcml0ZXJpYS4iLCBzZWxlY3Rvci5tYXRjaChjZXJ0MSkKKyAgICAgICAgICAgICAgICAmJiBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgICAgICBzZWxlY3Rvci5zZXRTdWJqZWN0S2V5SWRlbnRpZmllcihza2lkMSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG5vdCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0U3ViamVjdEtleUlkZW50aWZpZXIoc2tpZDIpOworICAgICAgICBza2lkMlswXSsrOworICAgICAgICBhc3NlcnRUcnVlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI3NldFN1YmplY3RQdWJsaWNLZXkoYnl0ZVtdKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0U3ViamVjdFB1YmxpY0tleUxCJCgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIC8vU3ViamVjdFB1YmxpY0tleUluZm8gIDo6PSAgU0VRVUVOQ0UgIHsKKyAgICAgICAgLy8gICAgYWxnb3JpdGhtICAgICAgICAgICAgQWxnb3JpdGhtSWRlbnRpZmllciwKKyAgICAgICAgLy8gICAgc3ViamVjdFB1YmxpY0tleSAgICAgQklUIFNUUklORyAgfQorICAgICAgICBieXRlW10gZW5jID0geyAweDMwLCAweDBFLCAvLyBTRVFVRU5DRQorICAgICAgICAgICAgICAgIDB4MzAsIDB4MDcsIC8vIFNFUVVFTkNFCisgICAgICAgICAgICAgICAgMHgwNiwgMHgwMiwgMHgwMywgMHgwNSwvL09JRAorICAgICAgICAgICAgICAgIDB4MDEsIDB4MDEsIDB4MDcsIC8vQU5ZCisgICAgICAgICAgICAgICAgMHgwMywgMHgwMywgMHgwMSwgMHgwMSwgMHgwNiwgLy8gc3ViamVjdFB1YmxpY0tleQorICAgICAgICB9OworCisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworCisgICAgICAgIHNlbGVjdG9yLnNldFN1YmplY3RQdWJsaWNLZXkoZW5jKTsKKyAgICAgICAgUHVibGljS2V5IGtleSA9IHNlbGVjdG9yLmdldFN1YmplY3RQdWJsaWNLZXkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIwLjMuNSIsIGtleS5nZXRBbGdvcml0aG0oKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWC41MDkiLCBrZXkuZ2V0Rm9ybWF0KCkpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoZW5jLCBrZXkuZ2V0RW5jb2RlZCgpKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoa2V5LnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI3NldFN1YmplY3RQdWJsaWNLZXkoamF2YS5zZWN1cml0eS5QdWJsaWNLZXkga2V5KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3Rfc2V0U3ViamVjdFB1YmxpY0tleUxqYXZhX3NlY3VyaXR5X1B1YmxpY0tleSgpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBQdWJsaWNLZXkgcGtleTEgPSBudWxsOworICAgICAgICBQdWJsaWNLZXkgcGtleTIgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGtleTEgPSBuZXcgVGVzdEtleVBhaXIoIlJTQSIpLmdldFB1YmxpYygpOworICAgICAgICAgICAgcGtleTIgPSBuZXcgVGVzdEtleVBhaXIoIkRTQSIpLmdldFB1YmxpYygpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBFeGNlcHRpb24gd2FzIHRocm93bjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIFRlc3RDZXJ0IGNlcnQxID0gbmV3IFRlc3RDZXJ0KHBrZXkxKTsKKyAgICAgICAgVGVzdENlcnQgY2VydDIgPSBuZXcgVGVzdENlcnQocGtleTIpOworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKworICAgICAgICBzZWxlY3Rvci5zZXRTdWJqZWN0UHVibGljS2V5KChQdWJsaWNLZXkpIG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKCJBbnkgY2VydGlmaWNhdGUgc2hvdWxkIG1hdGNoIGluIHRoZSBjYXNlIG9mIG51bGwgIgorICAgICAgICAgICAgICAgICsgInN1YmplY3RQdWJsaWNLZXkgY3JpdGVyaWEuIiwgc2VsZWN0b3IubWF0Y2goY2VydDEpCisgICAgICAgICAgICAgICAgJiYgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0U3ViamVjdFB1YmxpY0tleShwa2V5MSk7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG5vdCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKyAgICAgICAgc2VsZWN0b3Iuc2V0U3ViamVjdFB1YmxpY0tleShwa2V5Mik7CisgICAgICAgIGFzc2VydFRydWUoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbWF0Y2ggdGhlIHNlbGVjdGlvbiBjcml0ZXJpYS4iLAorICAgICAgICAgICAgICAgIHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3Ijc2V0U3ViamVjdFB1YmxpY0tleUFsZ0lEKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9zZXRTdWJqZWN0UHVibGljS2V5QWxnSURMamF2YV9sYW5nX1N0cmluZygpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworCisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworICAgICAgICBTdHJpbmcgcGthaWQxID0gIjEuMi44NDAuMTEzNTQ5LjEuMS4xIjsgLy8gUlNBIChzb3VyY2U6CisgICAgICAgIC8vIGh0dHA6Ly9hc24xLmVsaWJlbC50bS5mcikKKyAgICAgICAgU3RyaW5nIHBrYWlkMiA9ICIxLjIuODQwLjEwMDQwLjQuMSI7IC8vIERTQSAoc291cmNlOgorICAgICAgICAvLyBodHRwOi8vYXNuMS5lbGliZWwudG0uZnIpCisgICAgICAgIFB1YmxpY0tleSBwa2V5MTsKKyAgICAgICAgUHVibGljS2V5IHBrZXkyOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcGtleTEgPSBuZXcgVGVzdEtleVBhaXIoIlJTQSIpLmdldFB1YmxpYygpOworICAgICAgICAgICAgcGtleTIgPSBuZXcgVGVzdEtleVBhaXIoIkRTQSIpLmdldFB1YmxpYygpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgRXhjZXB0aW9uIHdhcyB0aHJvd246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgVGVzdENlcnQgY2VydDEgPSBuZXcgVGVzdENlcnQocGtleTEpOworICAgICAgICBUZXN0Q2VydCBjZXJ0MiA9IG5ldyBUZXN0Q2VydChwa2V5Mik7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlbGVjdG9yLnNldFN1YmplY3RQdWJsaWNLZXlBbGdJRChudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworCisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQW55IGNlcnRpZmljYXRlIHNob3VsZCBtYXRjaCBpbiB0aGUgY2FzZSBvZiBudWxsICIKKyAgICAgICAgICAgICAgICArICJzdWJqZWN0UHVibGljS2V5QWxnSUQgY3JpdGVyaWEuIiwgc2VsZWN0b3IubWF0Y2goY2VydDEpCisgICAgICAgICAgICAgICAgJiYgc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKworICAgICAgICBTdHJpbmdbXSB2YWxpZE9JRHMgPSB7ICIwLjAuMjAiLCAiMS4yNS4wIiwgIjIuMC4zOSIsICIwLjIuMTAiLCAiMS4zNS4xNSIsCisgICAgICAgICAgICAgICAgIjIuMTcuODkiLCAiMi41LjI5LjE2IiwgIjIuNS4yOS4xNyIsICIyLjUuMjkuMzAiLCAiMi41LjI5LjMyIiwKKyAgICAgICAgICAgICAgICAiMi41LjI5LjM3IiB9OworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRPSURzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHNlbGVjdG9yLnNldFN1YmplY3RQdWJsaWNLZXlBbGdJRCh2YWxpZE9JRHNbaV0pOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyh2YWxpZE9JRHNbaV0sIHNlbGVjdG9yLmdldFN1YmplY3RQdWJsaWNLZXlBbGdJRCgpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nW10gaW52YWxpZE9JRHMgPSB7ICIwLjIwIiwgIjEuMjUiLCAiMi4zOSIsICIzLjEwIn07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZE9JRHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc2VsZWN0b3Iuc2V0U3ViamVjdFB1YmxpY0tleUFsZ0lEKGludmFsaWRPSURzW2ldKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJJT0V4Y2VwdGlvbiB3YXNuJ3QgdGhyb3duIGZvciAiICsgaW52YWxpZE9JRHNbaV0pOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlbGVjdG9yLnNldFN1YmplY3RQdWJsaWNLZXlBbGdJRChwa2FpZDEpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIElPRXhjZXB0aW9uIHdhcyB0aHJvd24uIik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGhlIGNlcnRpZmljYXRlIHNob3VsZCBtYXRjaCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLiIsCisgICAgICAgICAgICAgICAgc2VsZWN0b3IubWF0Y2goY2VydDEpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIlRoZSBjZXJ0aWZpY2F0ZSBzaG91bGQgbm90IG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VsZWN0b3Iuc2V0U3ViamVjdFB1YmxpY0tleUFsZ0lEKHBrYWlkMik7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgSU9FeGNlcHRpb24gd2FzIHRocm93bi4iKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJUaGUgY2VydGlmaWNhdGUgc2hvdWxkIG1hdGNoIHRoZSBzZWxlY3Rpb24gY3JpdGVyaWEuIiwKKyAgICAgICAgICAgICAgICBzZWxlY3Rvci5tYXRjaChjZXJ0MikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI3RvU3RyaW5nKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X3RvU3RyaW5nKCkgeworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzZWxlY3Rvci50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgTXlQdWJsaWNLZXkgaW1wbGVtZW50cyBQdWJsaWNLZXkgeworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAyODk5NTI4Mzc1MzU0NjQ1NzUyTDsKKworICAgICAgICBwdWJsaWMgTXlQdWJsaWNLZXkoKSB7CisgICAgICAgICAgICBzdXBlcigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgICAgICByZXR1cm4gIlB1YmxpY0tleSI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgICAgIHJldHVybiAiRm9ybWF0IjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVswXTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBsb25nIGdldFNlclZlclVJRCgpIHsKKyAgICAgICAgICAgIHJldHVybiBzZXJpYWxWZXJzaW9uVUlEOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBUZXN0Q2VydCBleHRlbmRzIFg1MDlDZXJ0aWZpY2F0ZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTc2Njc2MTE1MjU0MjYwNDA1TDsKKworICAgICAgICAvKiBTdHVmZiBmaWVsZHMgKi8KKyAgICAgICAgcHJvdGVjdGVkIFN0cmluZyBlcXVhbENyaXRlcmlhID0gbnVsbDsgLy8gdG8gc2ltcGxpZnkgbWV0aG9kIGVxdWFscygpCisKKyAgICAgICAgcHJvdGVjdGVkIEJpZ0ludGVnZXIgc2VyaWFsTnVtYmVyID0gbnVsbDsKKworICAgICAgICBwcm90ZWN0ZWQgWDUwMFByaW5jaXBhbCBpc3N1ZXIgPSBudWxsOworCisgICAgICAgIHByb3RlY3RlZCBYNTAwUHJpbmNpcGFsIHN1YmplY3QgPSBudWxsOworCisgICAgICAgIHByb3RlY3RlZCBieXRlW10ga2V5SWRlbnRpZmllciA9IG51bGw7CisKKyAgICAgICAgcHJvdGVjdGVkIERhdGUgZGF0ZSA9IG51bGw7CisKKyAgICAgICAgcHJvdGVjdGVkIERhdGUgbm90QmVmb3JlID0gbnVsbDsKKworICAgICAgICBwcm90ZWN0ZWQgRGF0ZSBub3RBZnRlciA9IG51bGw7CisKKyAgICAgICAgcHJvdGVjdGVkIFB1YmxpY0tleSBrZXkgPSBudWxsOworCisgICAgICAgIHByb3RlY3RlZCBib29sZWFuW10ga2V5VXNhZ2UgPSBudWxsOworCisgICAgICAgIHByb3RlY3RlZCBMaXN0PFN0cmluZz4gZXh0S2V5VXNhZ2UgPSBudWxsOworCisgICAgICAgIHByb3RlY3RlZCBpbnQgcGF0aExlbiA9IDE7CisKKyAgICAgICAgcHJvdGVjdGVkIEdlbmVyYWxOYW1lcyBzYW5zID0gbnVsbDsKKworICAgICAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuY29kaW5nID0gbnVsbDsKKworICAgICAgICBwcm90ZWN0ZWQgU3RyaW5nW10gcG9saWNpZXMgPSBudWxsOworCisgICAgICAgIHByb3RlY3RlZCBDb2xsZWN0aW9uPExpc3Q8Pz4+IGNvbGxlY3Rpb24gPSBudWxsOworCisgICAgICAgIHByb3RlY3RlZCBOYW1lQ29uc3RyYWludHMgbmFtZUNvbnN0cmFpbnRzID0gbnVsbDsKKworICAgICAgICAvKiBTdHVmZiBtZXRob2RzICovCisgICAgICAgIHB1YmxpYyBUZXN0Q2VydCgpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBUZXN0Q2VydChHZW5lcmFsTmFtZXMgc2FucykgeworICAgICAgICAgICAgc2V0U3ViamVjdEFsdGVybmF0aXZlTmFtZXMoc2Fucyk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgVGVzdENlcnQoTmFtZUNvbnN0cmFpbnRzIG5hbWVDb25zdHJhaW50cykgeworICAgICAgICAgICAgdGhpcy5uYW1lQ29uc3RyYWludHMgPSBuYW1lQ29uc3RyYWludHM7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgVGVzdENlcnQoQ29sbGVjdGlvbjxMaXN0PD8+PiBjb2xsZWN0aW9uKSB7CisgICAgICAgICAgICBzZXRDb2xsZWN0aW9uKGNvbGxlY3Rpb24pOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFRlc3RDZXJ0KFN0cmluZyBlcXVhbENyaXRlcmlhKSB7CisgICAgICAgICAgICBzZXRFcXVhbENyaXRlcmlhKGVxdWFsQ3JpdGVyaWEpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFRlc3RDZXJ0KFN0cmluZ1tdIHBvbGljaWVzKSB7CisgICAgICAgICAgICBzZXRQb2xpY2llcyhwb2xpY2llcyk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgVGVzdENlcnQoQmlnSW50ZWdlciBzZXJpYWwpIHsKKyAgICAgICAgICAgIHNldFNlcmlhbE51bWJlcihzZXJpYWwpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFRlc3RDZXJ0KFg1MDBQcmluY2lwYWwgcHJpbmNpcGFsKSB7CisgICAgICAgICAgICBzZXRJc3N1ZXIocHJpbmNpcGFsKTsKKyAgICAgICAgICAgIHNldFN1YmplY3QocHJpbmNpcGFsKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBUZXN0Q2VydChieXRlW10gYXJyYXkpIHsKKyAgICAgICAgICAgIHNldEtleUlkZW50aWZpZXIoYXJyYXkpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFRlc3RDZXJ0KERhdGUgZGF0ZSkgeworICAgICAgICAgICAgc2V0RGF0ZShkYXRlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBUZXN0Q2VydChEYXRlIG5vdEJlZm9yZSwgRGF0ZSBub3RBZnRlcikgeworICAgICAgICAgICAgc2V0UGVyaW9kKG5vdEJlZm9yZSwgbm90QWZ0ZXIpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFRlc3RDZXJ0KFB1YmxpY0tleSBrZXkpIHsKKyAgICAgICAgICAgIHNldFB1YmxpY0tleShrZXkpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFRlc3RDZXJ0KGJvb2xlYW5bXSBrZXlVc2FnZSkgeworICAgICAgICAgICAgc2V0S2V5VXNhZ2Uoa2V5VXNhZ2UpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFRlc3RDZXJ0KFNldDxTdHJpbmc+IGV4dEtleVVzYWdlKSB7CisgICAgICAgICAgICBzZXRFeHRlbmRlZEtleVVzYWdlKGV4dEtleVVzYWdlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBUZXN0Q2VydChpbnQgcGF0aExlbikgeworICAgICAgICAgICAgdGhpcy5wYXRoTGVuID0gcGF0aExlbjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldFN1YmplY3RBbHRlcm5hdGl2ZU5hbWVzKEdlbmVyYWxOYW1lcyBzYW5zKSB7CisgICAgICAgICAgICB0aGlzLnNhbnMgPSBzYW5zOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0Q29sbGVjdGlvbihDb2xsZWN0aW9uPExpc3Q8Pz4+IGNvbGxlY3Rpb24pIHsKKyAgICAgICAgICAgIHRoaXMuY29sbGVjdGlvbiA9IGNvbGxlY3Rpb247CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXRQb2xpY2llcyhTdHJpbmdbXSBwb2xpY2llcykgeworICAgICAgICAgICAgdGhpcy5wb2xpY2llcyA9IHBvbGljaWVzOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0RXh0ZW5kZWRLZXlVc2FnZShTZXQ8U3RyaW5nPiBleHRLZXlVc2FnZSkgeworICAgICAgICAgICAgdGhpcy5leHRLZXlVc2FnZSA9IChleHRLZXlVc2FnZSA9PSBudWxsKSA/IG51bGwgOiBuZXcgQXJyYXlMaXN0PFN0cmluZz4oCisgICAgICAgICAgICAgICAgICAgIGV4dEtleVVzYWdlKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldEtleVVzYWdlKGJvb2xlYW5bXSBrZXlVc2FnZSkgeworICAgICAgICAgICAgdGhpcy5rZXlVc2FnZSA9IChrZXlVc2FnZSA9PSBudWxsKSA/IG51bGwgOiAoYm9vbGVhbltdKSBrZXlVc2FnZQorICAgICAgICAgICAgICAgICAgICAuY2xvbmUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldFB1YmxpY0tleShQdWJsaWNLZXkga2V5KSB7CisgICAgICAgICAgICB0aGlzLmtleSA9IGtleTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldFBlcmlvZChEYXRlIG5vdEJlZm9yZSwgRGF0ZSBub3RBZnRlcikgeworICAgICAgICAgICAgdGhpcy5ub3RCZWZvcmUgPSBub3RCZWZvcmU7CisgICAgICAgICAgICB0aGlzLm5vdEFmdGVyID0gbm90QWZ0ZXI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXRTZXJpYWxOdW1iZXIoQmlnSW50ZWdlciBzZXJpYWwpIHsKKyAgICAgICAgICAgIHRoaXMuc2VyaWFsTnVtYmVyID0gc2VyaWFsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0RXF1YWxDcml0ZXJpYShTdHJpbmcgZXF1YWxDcml0ZXJpYSkgeworICAgICAgICAgICAgdGhpcy5lcXVhbENyaXRlcmlhID0gZXF1YWxDcml0ZXJpYTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldElzc3VlcihYNTAwUHJpbmNpcGFsIGlzc3VlcikgeworICAgICAgICAgICAgdGhpcy5pc3N1ZXIgPSBpc3N1ZXI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXRTdWJqZWN0KFg1MDBQcmluY2lwYWwgc3ViamVjdCkgeworICAgICAgICAgICAgdGhpcy5zdWJqZWN0ID0gc3ViamVjdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHNldEtleUlkZW50aWZpZXIoYnl0ZVtdIHN1YmplY3RLZXlJRCkgeworICAgICAgICAgICAgdGhpcy5rZXlJZGVudGlmaWVyID0gKGJ5dGVbXSkgc3ViamVjdEtleUlELmNsb25lKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBzZXREYXRlKERhdGUgZGF0ZSkgeworICAgICAgICAgICAgdGhpcy5kYXRlID0gbmV3IERhdGUoZGF0ZS5nZXRUaW1lKCkpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2V0RW5jb2RpbmcoYnl0ZVtdIGVuY29kaW5nKSB7CisgICAgICAgICAgICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7CisgICAgICAgIH0KKworICAgICAgICAvKiBNZXRob2QgaW1wbGVtZW50YXRpb25zICovCisgICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgY2VydCkgeworICAgICAgICAgICAgaWYgKGNlcnQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICgoZXF1YWxDcml0ZXJpYSA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICB8fCAoKChUZXN0Q2VydCkgY2VydCkuZXF1YWxDcml0ZXJpYSA9PSBudWxsKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGVxdWFsQ3JpdGVyaWEuZXF1YWxzKCgoVGVzdENlcnQpIGNlcnQpLmVxdWFsQ3JpdGVyaWEpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIGlmIChlcXVhbENyaXRlcmlhICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZXF1YWxDcml0ZXJpYTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrVmFsaWRpdHkoKSB0aHJvd3MgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIENlcnRpZmljYXRlTm90WWV0VmFsaWRFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgY2hlY2tWYWxpZGl0eShEYXRlIGRhdGUpCisgICAgICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmICh0aGlzLmRhdGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGludCByZXN1bHQgPSB0aGlzLmRhdGUuY29tcGFyZVRvKGRhdGUpOworICAgICAgICAgICAgaWYgKHJlc3VsdCA+IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeHBpcmVkRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocmVzdWx0IDwgMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldFZlcnNpb24oKSB7CisgICAgICAgICAgICByZXR1cm4gMzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFNlcmlhbE51bWJlcigpIHsKKyAgICAgICAgICAgIHJldHVybiAoc2VyaWFsTnVtYmVyID09IG51bGwpID8gbmV3IEJpZ0ludGVnZXIoIjExMTEiKQorICAgICAgICAgICAgICAgICAgICA6IHNlcmlhbE51bWJlcjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0SXNzdWVyRE4oKSB7CisgICAgICAgICAgICByZXR1cm4gaXNzdWVyOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFg1MDBQcmluY2lwYWwgZ2V0SXNzdWVyWDUwMFByaW5jaXBhbCgpIHsKKyAgICAgICAgICAgIHJldHVybiBpc3N1ZXI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUHJpbmNpcGFsIGdldFN1YmplY3RETigpIHsKKyAgICAgICAgICAgIHJldHVybiBzdWJqZWN0OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFg1MDBQcmluY2lwYWwgZ2V0U3ViamVjdFg1MDBQcmluY2lwYWwoKSB7CisgICAgICAgICAgICByZXR1cm4gc3ViamVjdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBEYXRlIGdldE5vdEJlZm9yZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIERhdGUgZ2V0Tm90QWZ0ZXIoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0VEJTQ2VydGlmaWNhdGUoKSB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0U2lnbmF0dXJlKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFNpZ0FsZ05hbWUoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2lnQWxnT0lEKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldFNpZ0FsZ1BhcmFtcygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW5bXSBnZXRJc3N1ZXJVbmlxdWVJRCgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW5bXSBnZXRTdWJqZWN0VW5pcXVlSUQoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuW10gZ2V0S2V5VXNhZ2UoKSB7CisgICAgICAgICAgICByZXR1cm4ga2V5VXNhZ2U7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTGlzdDxTdHJpbmc+IGdldEV4dGVuZGVkS2V5VXNhZ2UoKQorICAgICAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIGV4dEtleVVzYWdlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXRCYXNpY0NvbnN0cmFpbnRzKCkgeworICAgICAgICAgICAgcmV0dXJuIHBhdGhMZW47CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCB2ZXJpZnkoUHVibGljS2V5IGtleSkgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5LCBTdHJpbmcgc2lnUHJvdmlkZXIpCisgICAgICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICAgICAgSW52YWxpZEtleUV4Y2VwdGlvbiwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBQdWJsaWNLZXkgZ2V0UHVibGljS2V5KCkgeworICAgICAgICAgICAgcmV0dXJuIGtleTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBlbmNvZGluZzsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTZXQ8U3RyaW5nPiBnZXROb25Dcml0aWNhbEV4dGVuc2lvbk9JRHMoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTZXQ8U3RyaW5nPiBnZXRDcml0aWNhbEV4dGVuc2lvbk9JRHMoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RXh0ZW5zaW9uVmFsdWUoU3RyaW5nIG9pZCkgeworCisgICAgICAgICAgICBpZiAoKCIyLjUuMjkuMTQiLmVxdWFscyhvaWQpKSB8fCAoIjIuNS4yOS4zNSIuZXF1YWxzKG9pZCkpKSB7CisgICAgICAgICAgICAgICAgLy8gRXh0ZW5zaW9uIHZhbHVlIGlzIHJlcHJlc2VudGVkIGFzIGFuIE9jdGV0U3RyaW5nCisgICAgICAgICAgICAgICAgcmV0dXJuIEFTTjFPY3RldFN0cmluZy5nZXRJbnN0YW5jZSgpLmVuY29kZShrZXlJZGVudGlmaWVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICgiMi41LjI5LjE2Ii5lcXVhbHMob2lkKSkgeworICAgICAgICAgICAgICAgIFByaXZhdGVLZXlVc2FnZVBlcmlvZCBwa3VwID0gbmV3IFByaXZhdGVLZXlVc2FnZVBlcmlvZCgKKyAgICAgICAgICAgICAgICAgICAgICAgIG5vdEJlZm9yZSwgbm90QWZ0ZXIpOworICAgICAgICAgICAgICAgIGJ5dGVbXSBlbmNvZGVkID0gcGt1cC5nZXRFbmNvZGVkKCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIEFTTjFPY3RldFN0cmluZy5nZXRJbnN0YW5jZSgpLmVuY29kZShlbmNvZGVkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICgoIjIuNS4yOS4zNyIuZXF1YWxzKG9pZCkpICYmIChleHRLZXlVc2FnZSAhPSBudWxsKSkgeworICAgICAgICAgICAgICAgIEFTTjFPaWRbXSBvYSA9IG5ldyBBU04xT2lkW2V4dEtleVVzYWdlLnNpemUoKV07CisgICAgICAgICAgICAgICAgU3RyaW5nW10gdmFsID0gbmV3IFN0cmluZ1tleHRLZXlVc2FnZS5zaXplKCldOworICAgICAgICAgICAgICAgIEl0ZXJhdG9yIGl0ID0gZXh0S2V5VXNhZ2UuaXRlcmF0b3IoKTsKKyAgICAgICAgICAgICAgICBpbnQgaWQgPSAwOworICAgICAgICAgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgb2FbaWRdID0gQVNOMU9pZC5nZXRJbnN0YW5jZUZvclN0cmluZygpOworICAgICAgICAgICAgICAgICAgICB2YWxbaWQrK10gPSAoU3RyaW5nKSBpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBBU04xT2N0ZXRTdHJpbmcuZ2V0SW5zdGFuY2UoKS5lbmNvZGUoCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQVNOMVNlcXVlbmNlKG9hKS5lbmNvZGUodmFsKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIjIuNS4yOS4xOSIuZXF1YWxzKG9pZCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gQVNOMU9jdGV0U3RyaW5nLmdldEluc3RhbmNlKCkuZW5jb2RlKAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEFTTjFTZXF1ZW5jZShuZXcgQVNOMVR5cGVbXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTjFCb29sZWFuLmdldEluc3RhbmNlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTjFJbnRlZ2VyLmdldEluc3RhbmNlKCkgfSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmVuY29kZShuZXcgT2JqZWN0W10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBCb29sZWFuKHBhdGhMZW4gIT0gMSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci52YWx1ZU9mKHBhdGhMZW4pCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudG9CeXRlQXJyYXkoKSB9KSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIjIuNS4yOS4xNyIuZXF1YWxzKG9pZCkgJiYgKHNhbnMgIT0gbnVsbCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoc2Fucy5nZXROYW1lcygpID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBBU04xT2N0ZXRTdHJpbmcuZ2V0SW5zdGFuY2UoKS5lbmNvZGUoCisgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmFsTmFtZXMuQVNOMS5lbmNvZGUoc2FucykpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCIyLjUuMjkuMzIiLmVxdWFscyhvaWQpICYmIChwb2xpY2llcyAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICAmJiAocG9saWNpZXMubGVuZ3RoID4gMCkpIHsKKyAgICAgICAgICAgICAgICAvLyBDZXJ0aWZpY2F0ZSBQb2xpY2llcyBFeHRlbnNpb24gKGFzIHNwZWNpZmllZCBpbiByZmMgMzI4MCkKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZVBvbGljaWVzIGNlcnRpZmljYXRlUG9saWNpZXMgPSBuZXcgQ2VydGlmaWNhdGVQb2xpY2llcygpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcG9saWNpZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgUG9saWN5SW5mb3JtYXRpb24gcG9saWN5SW5mb3JtYXRpb24gPSBuZXcgUG9saWN5SW5mb3JtYXRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9saWNpZXNbaV0pOworICAgICAgICAgICAgICAgICAgICBjZXJ0aWZpY2F0ZVBvbGljaWVzLmFkZFBvbGljeUluZm9ybWF0aW9uKHBvbGljeUluZm9ybWF0aW9uKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIEFTTjFPY3RldFN0cmluZy5nZXRJbnN0YW5jZSgpLmVuY29kZSgKKyAgICAgICAgICAgICAgICAgICAgICAgIGNlcnRpZmljYXRlUG9saWNpZXMuZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICgiMi41LjI5LjMwIi5lcXVhbHMob2lkKSAmJiAobmFtZUNvbnN0cmFpbnRzICE9IG51bGwpKSB7IC8vCisgICAgICAgICAgICAgICAgLy8gTmFtZQorICAgICAgICAgICAgICAgIC8vIENvbnN0cmFpbnRzCisgICAgICAgICAgICAgICAgLy8gRXh0ZW5zaW9uCisgICAgICAgICAgICAgICAgLy8gKGFzCisgICAgICAgICAgICAgICAgLy8gc3BlY2lmaWVkCisgICAgICAgICAgICAgICAgLy8gaW4KKyAgICAgICAgICAgICAgICAvLyByZmMKKyAgICAgICAgICAgICAgICAvLyAzMjgwKQorICAgICAgICAgICAgICAgIHJldHVybiBBU04xT2N0ZXRTdHJpbmcuZ2V0SW5zdGFuY2UoKS5lbmNvZGUoCisgICAgICAgICAgICAgICAgICAgICAgICBuYW1lQ29uc3RyYWludHMuZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNVbnN1cHBvcnRlZENyaXRpY2FsRXh0ZW5zaW9uKCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgWDUwOUNlcnRpZmljYXRlIHJvb3RDZXJ0aWZpY2F0ZTsKKworICAgIHB1YmxpYyBYNTA5Q2VydGlmaWNhdGUgZW5kQ2VydGlmaWNhdGU7CisKKyAgICBwdWJsaWMgTXlDUkwgY3JsOworCisgICAgcHJpdmF0ZSBYNTA5Q2VydFNlbGVjdG9yIHRoZUNlcnRTZWxlY3RvcjsKKworICAgIHByaXZhdGUgQ2VydFBhdGhCdWlsZGVyIGJ1aWxkZXI7CisKKyAgICBwcml2YXRlIHZvaWQgc2V0dXBFbnZpcm9ubWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBjcmVhdGUgY2VydGlmaWNhdGVzIGFuZCBDUkxzCisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmkgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oVGVzdFV0aWxzLnJvb3RDZXJ0LmdldEJ5dGVzKCkpOworICAgICAgICByb290Q2VydGlmaWNhdGUgPSAoWDUwOUNlcnRpZmljYXRlKSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKGJpKTsKKyAgICAgICAgYmkgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oVGVzdFV0aWxzLmVuZENlcnQuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIGVuZENlcnRpZmljYXRlID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShiaSk7CisKKyAgICAgICAgQmlnSW50ZWdlciByZXZva2VkU2VyaWFsTnVtYmVyID0gQmlnSW50ZWdlci52YWx1ZU9mKDEpOworICAgICAgICBjcmwgPSBuZXcgTXlDUkwoIlguNTA5Iik7CisvLyAgICAgICAgWDUwOUNSTCByb290Q1JMID0gWDUwOUNSTDsKKy8vICAgICAgICBYNTA5Q1JMIGludGVyQ1JMID0gWDUwOUNSTEV4YW1wbGUuY3JlYXRlQ1JMKGludGVyQ2VydCwgaW50ZXJQYWlyCisvLyAgICAgICAgICAgICAgICAuZ2V0UHJpdmF0ZSgpLCByZXZva2VkU2VyaWFsTnVtYmVyKTsKKworICAgICAgICAvLyBjcmVhdGUgQ2VydFN0b3JlIHRvIHN1cHBvcnQgcGF0aCBidWlsZGluZworICAgICAgICBMaXN0PE9iamVjdD4gbGlzdCA9IG5ldyBBcnJheUxpc3Q8T2JqZWN0PigpOworCisgICAgICAgIGxpc3QuYWRkKHJvb3RDZXJ0aWZpY2F0ZSk7CisgICAgICAgIGxpc3QuYWRkKGVuZENlcnRpZmljYXRlKTsKKworLy8gICAgICAgIENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzIHBhcmFtcyA9IG5ldyBDb2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVycygKKy8vICAgICAgICAgICAgICAgIGxpc3QpOworLy8gICAgICAgIENlcnRTdG9yZSBzdG9yZSA9IENlcnRTdG9yZS5nZXRJbnN0YW5jZSgiQ29sbGVjdGlvbiIsIHBhcmFtcyk7CisvLworICAgICAgICB0aGVDZXJ0U2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworICAgICAgICB0aGVDZXJ0U2VsZWN0b3Iuc2V0Q2VydGlmaWNhdGUoZW5kQ2VydGlmaWNhdGUpOworICAgICAgICB0aGVDZXJ0U2VsZWN0b3Iuc2V0SXNzdWVyKGVuZENlcnRpZmljYXRlLmdldElzc3Vlclg1MDBQcmluY2lwYWwoKQorICAgICAgICAgICAgICAgIC5nZXRFbmNvZGVkKCkpOworCisgICAgIC8vIGJ1aWxkIHRoZSBwYXRoCisgICAgICAgIGJ1aWxkZXIgPSBDZXJ0UGF0aEJ1aWxkZXIuZ2V0SW5zdGFuY2UoIlBLSVgiKTsKKworICAgIH0KKworICAgIHByaXZhdGUgQ2VydFBhdGggYnVpbGRDZXJ0UGF0aCgpIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgUEtJWENlcnRQYXRoQnVpbGRlclJlc3VsdCByZXN1bHQgPSBudWxsOworICAgICAgICBQS0lYQnVpbGRlclBhcmFtZXRlcnMgYnVpbGRQYXJhbXMgPSBuZXcgUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzKAorICAgICAgICAgICAgICAgIENvbGxlY3Rpb25zLnNpbmdsZXRvbihuZXcgVHJ1c3RBbmNob3Iocm9vdENlcnRpZmljYXRlLCBudWxsKSksCisgICAgICAgICAgICAgICAgdGhlQ2VydFNlbGVjdG9yKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgcmVzdWx0ID0gKFBLSVhDZXJ0UGF0aEJ1aWxkZXJSZXN1bHQpIGJ1aWxkZXIKKyAgICAgICAgLmJ1aWxkKGJ1aWxkUGFyYW1zKTsKKyAgICAgICAgfSBjYXRjaChDZXJ0UGF0aEJ1aWxkZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdC5nZXRDZXJ0UGF0aCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2FkZFBhdGhUb05hbWUoaW50LCBieXRlW10pCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRQYXRoVG9OYW1lTGludExieXRlX2FycmF5MigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0VXRpbHMuaW5pdENlcnRQYXRoU1NDZXJ0Q2hhaW4oKTsKKyAgICAgICAgc2V0dXBFbnZpcm9ubWVudCgpOworICAgICAgICBieXRlW10gYnl0ZXMsIGJ5dGVzTmFtZTsKKyAgICAgICAgLy8gR2VuZXJhbE5hbWUgbmFtZSA9IG5ldyBHZW5lcmFsTmFtZSgxLCAiODIyLk5hbWUiKTsKKyAgICAgICAgLy8gYnl0ZXMgPSBuYW1lLmdldEVuY29kZWQoKTsKKyAgICAgICAgLy8gYnl0ZXNOYW1lID0gbmFtZS5nZXRFbmNvZGVkTmFtZSgpOworICAgICAgICBieXRlcyA9IG5ldyBieXRlW10gey0xMjcsIDgsIDU2LCA1MCwgNTAsIDQ2LCA3OCwgOTcsIDEwOSwgMTAxfTsKKyAgICAgICAgYnl0ZXNOYW1lID0gbmV3IGJ5dGVbXSB7MjIsIDgsIDU2LCA1MCwgNTAsIDQ2LCA3OCwgOTcsIDEwOSwgMTAxfTsKKyAgICAgICAgYnl0ZXNbYnl0ZXMubGVuZ3RoLTNdID0gKGJ5dGUpIDIwMDsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhlQ2VydFNlbGVjdG9yLmFkZFBhdGhUb05hbWUoMSwgYnl0ZXMpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgdGhlQ2VydFNlbGVjdG9yLnNldFBhdGhUb05hbWVzKG51bGwpOworCisgICAgICAgIHRoZUNlcnRTZWxlY3Rvci5hZGRQYXRoVG9OYW1lKDEsIGJ5dGVzTmFtZSk7CisgICAgICAgIGFzc2VydE5vdE51bGwodGhlQ2VydFNlbGVjdG9yLmdldFBhdGhUb05hbWVzKCkpOworICAgICAgICBDZXJ0UGF0aCBwID0gYnVpbGRDZXJ0UGF0aCgpOworICAgICAgICBhc3NlcnROdWxsKHApOworCisgICAgICAgIHRoZUNlcnRTZWxlY3Rvci5zZXRQYXRoVG9OYW1lcyhudWxsKTsKKworLy8gICAgICAgIG5hbWUgPSBuZXcgR2VuZXJhbE5hbWUobmV3IE5hbWUoIk89QW5kcm9pZCIpKTsKKy8vICAgICAgICB0aGVDZXJ0U2VsZWN0b3IuYWRkUGF0aFRvTmFtZSg0LCBlbmRDZXJ0aWZpY2F0ZS5nZXRTdWJqZWN0RE4oKS5nZXROYW1lKCkpOworICAgICAgICB0aGVDZXJ0U2VsZWN0b3IuYWRkUGF0aFRvTmFtZSg0LCBUZXN0VXRpbHMucm9vdENlcnRpZmljYXRlU1MuZ2V0SXNzdWVyWDUwMFByaW5jaXBhbCgpLmdldEVuY29kZWQoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwodGhlQ2VydFNlbGVjdG9yLmdldFBhdGhUb05hbWVzKCkpOworICAgICAgICBwID0gVGVzdFV0aWxzLmJ1aWxkQ2VydFBhdGhTU0NlcnRDaGFpbigpOworICAgICAgICBhc3NlcnROb3ROdWxsKHApOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2FkZFBhdGhUb05hbWUoaW50LCBTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRQYXRoVG9OYW1lTGludExqYXZhX2xhbmdfU3RyaW5nMigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzZXR1cEVudmlyb25tZW50KCk7CisgICAgICAgIGJ5dGVbXSBieXRlcywgYnl0ZXNOYW1lOworICAgICAgICAvLyBHZW5lcmFsTmFtZSBuYW1lID0gbmV3IEdlbmVyYWxOYW1lKDEsICI4MjIuTmFtZSIpOworICAgICAgICAvLyBieXRlcyA9IG5hbWUuZ2V0RW5jb2RlZCgpOworICAgICAgICAvLyBieXRlc05hbWUgPSBuYW1lLmdldEVuY29kZWROYW1lKCk7CisgICAgICAgIGJ5dGVzID0gbmV3IGJ5dGVbXSB7LTEyNywgOCwgNTYsIDUwLCA1MCwgNDYsIDc4LCA5NywgMTA5LCAxMDF9OworICAgICAgICBieXRlc05hbWUgPSBuZXcgYnl0ZVtdIHsyMiwgOCwgNTYsIDUwLCA1MCwgNDYsIDc4LCA5NywgMTA5LCAxMDF9OworICAgICAgICBhc3NlcnROb3ROdWxsKGJ5dGVzKTsKKyAgICAgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVtieXRlcy5sZW5ndGhdOworICAgICAgICBiID0gYnl0ZXM7CisgICAgICAgIGJbYnl0ZXMubGVuZ3RoLTNdID0gKGJ5dGUpIDIwMDsKKworICAgICAgICB0cnkgeworICAgICAgICB0aGVDZXJ0U2VsZWN0b3IuYWRkUGF0aFRvTmFtZSgxLCBuZXcgU3RyaW5nKGIpKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgICAgIHRoZUNlcnRTZWxlY3Rvci5zZXRQYXRoVG9OYW1lcyhudWxsKTsKKworICAgICAgICB0aGVDZXJ0U2VsZWN0b3IuYWRkUGF0aFRvTmFtZSgxLCBuZXcgU3RyaW5nKGJ5dGVzTmFtZSkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRoZUNlcnRTZWxlY3Rvci5nZXRQYXRoVG9OYW1lcygpKTsKKworICAgICAgICBDZXJ0UGF0aCBwID0gYnVpbGRDZXJ0UGF0aCgpOworICAgICAgICBhc3NlcnROdWxsKHApOworCisgICAgICAgIHRoZUNlcnRTZWxlY3Rvci5zZXRQYXRoVG9OYW1lcyhudWxsKTsKKyAgICAgICAgdGhlQ2VydFNlbGVjdG9yLmFkZFBhdGhUb05hbWUoMSwgcm9vdENlcnRpZmljYXRlLmdldElzc3Vlclg1MDBQcmluY2lwYWwoKS5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnROb3ROdWxsKHRoZUNlcnRTZWxlY3Rvci5nZXRQYXRoVG9OYW1lcygpKTsKKyAgICAgICAgLy9wID0gYnVpbGRDZXJ0UGF0aCgpOworICAgICAgICAvL2Fzc2VydE5vdE51bGwocCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3IjYWRkU3ViamVjdEFsdGVybmF0aXZlTmFtZShpbnQsIGJ5dGVbXSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2FkZFN1YmplY3RBbHRlcm5hdGl2ZU5hbWVMaW50TGJ5dGVfYXJyYXkyKCkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworCisKKyAgICAgICAgR2VuZXJhbE5hbWUgc2FuMCA9IG5ldyBHZW5lcmFsTmFtZShuZXcgT3RoZXJOYW1lKCIxLjIuMy40LjUiLAorICAgICAgICAgICAgICAgIG5ldyBieXRlW10gezEsIDIsIDAsIDF9KSk7CisgICAgICAgIEdlbmVyYWxOYW1lIHNhbjEgPSBuZXcgR2VuZXJhbE5hbWUoMSwgInJmY0A4MjIuTmFtZSIpOworICAgICAgICBHZW5lcmFsTmFtZSBzYW4yID0gbmV3IEdlbmVyYWxOYW1lKDIsICJkTlNOYW1lIik7CisKKyAgICAgICAgR2VuZXJhbE5hbWVzIHNhbnMxID0gbmV3IEdlbmVyYWxOYW1lcygpOworICAgICAgICBzYW5zMS5hZGROYW1lKHNhbjApOworICAgICAgICBzYW5zMS5hZGROYW1lKHNhbjEpOworICAgICAgICBzYW5zMS5hZGROYW1lKHNhbjIpOworCisgICAgICAgIFg1MDlDZXJ0U2VsZWN0b3Igc2VsZWN0b3IgPSBuZXcgWDUwOUNlcnRTZWxlY3RvcigpOworCisgICAgICAgIHNlbGVjdG9yLmFkZFN1YmplY3RBbHRlcm5hdGl2ZU5hbWUoMCwgc2FuMC5nZXRFbmNvZGVkTmFtZSgpKTsKKyAgICAgICAgc2VsZWN0b3IuYWRkU3ViamVjdEFsdGVybmF0aXZlTmFtZSgxLCBzYW4xLmdldEVuY29kZWROYW1lKCkpOworICAgICAgICBzZWxlY3Rvci5hZGRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lKDIsIHNhbjIuZ2V0RW5jb2RlZE5hbWUoKSk7CisKKyAgICAgICAgR2VuZXJhbE5hbWVzIHNhbnMyID0gbmV3IEdlbmVyYWxOYW1lcygpOworICAgICAgICBzYW5zMi5hZGROYW1lKHNhbjApOworCisgICAgICAgIFRlc3RDZXJ0IGNlcnQxID0gbmV3IFRlc3RDZXJ0KHNhbnMxKTsKKyAgICAgICAgVGVzdENlcnQgY2VydDIgPSBuZXcgVGVzdENlcnQoc2FuczIpOworCisgICAgICAgIGFzc2VydFRydWUoc2VsZWN0b3IubWF0Y2goY2VydDEpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2VsZWN0b3IubWF0Y2goY2VydDIpKTsKKworICAgICAgICBzZWxlY3Rvci5zZXRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcyhudWxsKTsKKworICAgICAgICBHZW5lcmFsTmFtZSBuYW1lID0gbmV3IEdlbmVyYWxOYW1lKG5ldyBOYW1lKCJPPUFuZHJvaWQiKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZWxlY3Rvci5hZGRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lKDAsIG5hbWUuZ2V0RW5jb2RlZE5hbWUoKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydFNlbGVjdG9yI2FkZFN1YmplY3RBbHRlcm5hdGl2ZU5hbWUoaW50LCBTdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9hZGRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lTGludExqYXZhX2xhbmdfU3RyaW5nMigpIHRocm93cyBFeGNlcHRpb257CisgICAgICAgIEdlbmVyYWxOYW1lIHNhbjYgPSBuZXcgR2VuZXJhbE5hbWUoNiwgImh0dHA6Ly91bmlmb3JtLlJlc291cmNlLklkIik7CisgICAgICAgIEdlbmVyYWxOYW1lIHNhbjIgPSBuZXcgR2VuZXJhbE5hbWUoMiwgImROU05hbWUiKTsKKworICAgICAgICBHZW5lcmFsTmFtZXMgc2FuczEgPSBuZXcgR2VuZXJhbE5hbWVzKCk7CisgICAgICAgIHNhbnMxLmFkZE5hbWUoc2FuNik7CisgICAgICAgIHNhbnMxLmFkZE5hbWUoc2FuMik7CisKKyAgICAgICAgWDUwOUNlcnRTZWxlY3RvciBzZWxlY3RvciA9IG5ldyBYNTA5Q2VydFNlbGVjdG9yKCk7CisKKyAgICAgICAgc2VsZWN0b3IuYWRkU3ViamVjdEFsdGVybmF0aXZlTmFtZSg2LCAiaHR0cDovL3VuaWZvcm0uUmVzb3VyY2UuSWQiKTsKKyAgICAgICAgc2VsZWN0b3IuYWRkU3ViamVjdEFsdGVybmF0aXZlTmFtZSgyLCAiZE5TTmFtZSIpOworCisgICAgICAgIEdlbmVyYWxOYW1lcyBzYW5zMiA9IG5ldyBHZW5lcmFsTmFtZXMoKTsKKyAgICAgICAgc2FuczIuYWRkTmFtZShzYW4yKTsKKworICAgICAgICBUZXN0Q2VydCBjZXJ0MSA9IG5ldyBUZXN0Q2VydChzYW5zMSk7CisgICAgICAgIFRlc3RDZXJ0IGNlcnQyID0gbmV3IFRlc3RDZXJ0KHNhbnMyKTsKKworICAgICAgICBhc3NlcnRUcnVlKHNlbGVjdG9yLm1hdGNoKGNlcnQxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHNlbGVjdG9yLm1hdGNoKGNlcnQyKSk7CisKKyAgICAgICAgc2VsZWN0b3Iuc2V0U3ViamVjdEFsdGVybmF0aXZlTmFtZXMobnVsbCk7CisKKyAgICAgICAgR2VuZXJhbE5hbWUgbmFtZSA9IG5ldyBHZW5lcmFsTmFtZShuZXcgTmFtZSgiTz1BbmRyb2lkIikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VsZWN0b3IuYWRkU3ViamVjdEFsdGVybmF0aXZlTmFtZSgwLCAobmFtZS50b1N0cmluZygpKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9jZXJ0L1g1MDlDZXJ0aWZpY2F0ZTJUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9YNTA5Q2VydGlmaWNhdGUyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU1NzgyMzQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvY2VydC9YNTA5Q2VydGlmaWNhdGUyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDMzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydC5UZXN0VXRpbHM7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUV4dGVuc2lvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLng1MDAuWDUwMFByaW5jaXBhbDsKKworcHVibGljIGNsYXNzIFg1MDlDZXJ0aWZpY2F0ZTJUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIFguNTA5IENlcnRpZmljYXRlIHByb3ZpZGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF90b1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIC8vIFJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMzM4NAorICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2VydEZhY3QgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlg1MDkiKTsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIHBlbUNlcnQgPSAoWDUwOUNlcnRpZmljYXRlKSBjZXJ0RmFjdAorICAgICAgICAgICAgICAgIC5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShUZXN0VXRpbHMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRYNTA5Q2VydGlmaWNhdGVfdjMoKSkpOworCisgICAgICAgIC8vIGV4dGVuc2lvbiB2YWx1ZSBpcyBlbXB0eSBzZXF1ZW5jZQorICAgICAgICBieXRlW10gZXh0blZhbHVlID0gcGVtQ2VydC5nZXRFeHRlbnNpb25WYWx1ZSgiMi41LjI5LjM1Iik7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzCisgICAgICAgICAgICAgICAgLmVxdWFscyhuZXcgYnl0ZVtdIHsweDA0LCAweDAyLCAweDMwLCAweDAwfSwgZXh0blZhbHVlKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwocGVtQ2VydC50b1N0cmluZygpKTsKKyAgICAgICAgLy8gRW5kIHJlZ3Jlc3Npb24gZm9yIEhBUk1PTlktMzM4NAorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGUjWDUwOUNlcnRpZmljYXRlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X1g1MDlDZXJ0aWZpY2F0ZSgpIHsKKyAgICAgICAgTXlYNTA5Q2VydGlmaWNhdGUgcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzID0gbmV3IE15WDUwOUNlcnRpZmljYXRlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiWC41MDkiLCBzLmdldFR5cGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEFic3RyYWN0TWV0aG9kcygpIHsKKyAgICAgICAgTXlYNTA5Q2VydGlmaWNhdGUgcyA9IG5ldyBNeVg1MDlDZXJ0aWZpY2F0ZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcy5jaGVja1ZhbGlkaXR5KCk7CisgICAgICAgICAgICBzLmNoZWNrVmFsaWRpdHkobmV3IERhdGUoKSk7CisgICAgICAgICAgICBzLmdldEJhc2ljQ29uc3RyYWludHMoKTsKKyAgICAgICAgICAgIHMuZ2V0SXNzdWVyRE4oKTsKKyAgICAgICAgICAgIHMuZ2V0SXNzdWVyVW5pcXVlSUQoKTsKKyAgICAgICAgICAgIHMuZ2V0S2V5VXNhZ2UoKTsKKyAgICAgICAgICAgIHMuZ2V0Tm90QWZ0ZXIoKTsKKyAgICAgICAgICAgIHMuZ2V0Tm90QmVmb3JlKCk7CisgICAgICAgICAgICBzLmdldFNlcmlhbE51bWJlcigpOworICAgICAgICAgICAgcy5nZXRTaWdBbGdOYW1lKCk7CisgICAgICAgICAgICBzLmdldFNpZ0FsZ09JRCgpOworICAgICAgICAgICAgcy5nZXRTaWdBbGdQYXJhbXMoKTsKKyAgICAgICAgICAgIHMuZ2V0U2lnbmF0dXJlKCk7CisgICAgICAgICAgICBzLmdldFN1YmplY3RETigpOworICAgICAgICAgICAgcy5nZXRTdWJqZWN0VW5pcXVlSUQoKTsKKyAgICAgICAgICAgIHMuZ2V0VEJTQ2VydGlmaWNhdGUoKTsKKyAgICAgICAgICAgIHMuZ2V0VmVyc2lvbigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIEJhc2U2NCBlbmNvZGVkIGZvcm0gb2YgQVNOLjEgREVSIGVuY29kZWQgWC41MDkgQ2VydGlmaWNhdGUKKyAgICAvLyAoc2VlIFJGQyAzMjgwIGF0IGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMyODAudHh0KQorICAgIC8vIChnZW5lcmF0ZWQgYnkgdXNpbmcgb2YgY2xhc3NlcyBmcm9tCisgICAgLy8gb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5Lng1MDkgcGFja2FnZSkKKyAgICBzdGF0aWMgU3RyaW5nIGJhc2U2NGNlcnQgPQorICAgICAgICAiTUlJQnl6Q0NBVGFnQXdJQkFnSUNBaXN3Q3dZSktvWklodmNOQVFFRk1CMHhHekFaQmdOVkJBb1QiCisgICAgICAgICAgICArICJFa05sY25ScFptbGpZWFJsSUVsemMzVmxjakFlRncwd05qQTBNall3TmpJNE1qSmFGdzB6TXpBeiIKKyAgICAgICAgICAgICsgIk1ERXhOalEwTURsYU1CMHhHekFaQmdOVkJBb1RFa05sY25ScFptbGpZWFJsSUVsemMzVmxjakNCIgorICAgICAgICAgICAgKyAibnpBTkJna3Foa2lHOXcwQkFRRUZBQU9CalFBd2dZa0NnWUVBa0xHTHNQZFNQRE15UDFPVU9LdSIKKyAgICAgICAgICAgICsgIlUzY3ZiTks1UkdhUTNiWGM1YURqdkFweDQzQmNhb1hndDZZRC81eVh6ME9zSW9vajV5QTM3YlkiCisgICAgICAgICAgICArICJKR2NWcnZGRDVGTVBkRGQzdmpOUFFPZXAwTXpHNENkYmthWmRlNVNpZ1BhYk9NUVlTNG9VeUxCeCIKKyAgICAgICAgICAgICsgIlczTEdHMG1VT0RlNUFHR3F0cVhVMEdsS2c0SzJqZTZjQ3Rvb2tDVUNBd0VBQWFNZU1Cd3dHZ1lEIgorICAgICAgICAgICAgKyAiVlIwUkFRSC9CQkF3RG9FTWNtWmpRRGd5TWk1T1lXMWxNQXNHQ1NxR1NJYjNEUUVCQlFPQmdRQloiCisgICAgICAgICAgICArICJwVlhqMDFkT3BxblpFclVRYjUwajhsSkQxZElhejFlSlR2SkNTYWRqN3ppVjFWdG5uYXBJMDdjIgorICAgICAgICAgICAgKyAiWEVhN09OemNIUVRZVEcxMHBvSGZPSy9hMEJhVUxGM0dsY3RERVNpbHdRWWJXNUJkZnBBbFpwYkgiCisgICAgICAgICAgICArICJBRkxjVURoNkVxNTBrYzBBL2FuaC9qM21nQk51dmJJTW83aEhOblpCNmsvcHJzd20yQnN6eUxEIgorICAgICAgICAgICAgKyAieXc9PSI7CisgICAgc3RhdGljIFN0cmluZyBiYXNlNjRjZXJ0Q29ycmVjdCA9CisgICAgICAgICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgKyAiTUlJQytqQ0NBcmFnQXdJQkFnSUNBaXN3REFZSEtvWkl6amdFQXdFQkFEQWRNUnN3R1FZRFZRUUtFeEpEWlhKMGEiCisgICAgICAgICsgIldacFkyRjBaU0JKYzNOMVpYSXdJaGdQTVRrM01EQXhNVEl4TXpRMk5EQmFHQTh4T1Rjd01ERXlOREF6TXpNeU1GIgorICAgICAgICArICJvd0h6RWRNQnNHQTFVRUNoTVVVM1ZpYW1WamRDQlBjbWRoYm1sNllYUnBiMjR3R1RBTUJnY3Foa2pPT0FRREFRRSIKKyAgICAgICAgKyAiQUF3a0FBUUlEQkFVR0J3aUJBZ0NxZ2dJQVZhT0NBaFF3Z2dJUU1BOEdBMVVkRHdFQi93UUZBd01CcW9Bd0VnWUQiCisgICAgICAgICsgIlZSMFRBUUgvQkFnd0JnRUIvd0lCQlRBVUJnTlZIU0FCQWY4RUNqQUlNQVlHQkZVZElBQXdad1lEVlIwUkFRSC9CIgorICAgICAgICArICJGMHdXNEVNY21aalFEZ3lNaTVPWVcxbGdnZGtUbE5PWVcxbHBCY3hGVEFUQmdOVkJBb1RERTl5WjJGdWFYcGhkRyIKKyAgICAgICAgKyAibHZib1lhYUhSMGNEb3ZMM1Z1YVdadmNtMHVVbVZ6YjNWeVkyVXVTV1NIQlAvLy93Q0lCeW9Eb2x5RHNnTXdEQVkiCisgICAgICAgICsgIkRWUjBlQVFIL0JBSXdBREFNQmdOVkhTUUJBZjhFQWpBQU1JR1pCZ05WSFNVQkFmOEVnWTR3Z1lzR0JGVWRKUUFHIgorICAgICAgICArICJDQ3NHQVFVRkJ3TUJCZ2dyQmdFRkJRY0RBUVlJS3dZQkJRVUhBd0lHQ0NzR0FRVUZCd01EQmdnckJnRUZCUWNEQiIKKyAgICAgICAgKyAiQVlJS3dZQkJRVUhBd1VHQ0NzR0FRVUZCd01HQmdnckJnRUZCUWNEQndZSUt3WUJCUVVIQXdnR0NDc0dBUVVGQnciCisgICAgICAgICsgIk1KQmdnckJnRUZCUWdDQWdZS0t3WUJCQUdDTndvREF3WUpZSVpJQVliNFFnUUJNQTBHQTFVZE5nRUIvd1FEQWdFIgorICAgICAgICArICJCTUE0R0JDcE5oZ2tCQWY4RUF3RUJBVEJrQmdOVkhSSUVYVEJiZ1F4eVptTkFPREl5TGs1aGJXV0NCMlJPVTA1aCIKKyAgICAgICAgKyAiYldXa0Z6RVZNQk1HQTFVRUNoTU1UM0puWVc1cGVtRjBhVzl1aGhwb2RIUndPaTh2ZFc1cFptOXliUzVTWlhOdmQiCisgICAgICAgICsgIlhKalpTNUpaSWNFLy8vL0FJZ0hLZ09pWElPeUF6QUpCZ05WSFI4RUFqQUFNQW9HQTFVZEl3UURBUUVCTUFvR0ExIgorICAgICAgICArICJVZERnUURBUUVCTUFvR0ExVWRJUVFEQVFFQk1Bd0dCeXFHU000NEJBTUJBUUFETUFBd0xRSVVBTDRRdm9hek5XUCIKKyAgICAgICAgKyAiN2pyajg0L0dabGhtMDlEc0NGUUNCS0dLQ0diclA2NFZ0VXQ0SlBtTGpXMVZ4UUE9PVxuIgorICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tIjsKKworICAgIHByaXZhdGUgWDUwOUNlcnRpZmljYXRlIGNlcnQ7CisKKyAgICBzdGF0aWMgU3RyaW5nIGJhc2U2NGNlcnRUYW1wZXJlZCA9ICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgKyAiTUlJQytqQ0NBcmFnQXdJQkFnSUNBaXN3REFZSEtvWkl6amdFQXdFQkFEQWRNUnN3R1FZRFZRUUtFeEpEWlhKMGEiCisgICAgICAgICsgIldacFkyRjBaU0JKYzNOMVpYSXdJaGdQTVRrM01EQXhNVEl4TXpRMk5EQmFHQTh4T1Rjd01ERXlOREF6TXpNeU1GIgorICAgICAgICArICJvd0h6RWRNQnNHQTFVRUNoTVVVM1ZpYW1WamRDQlBjbWRoYm1sNllYUnBiMjR3R1RBTUJnY3Foa2pPT0FRREFRRSIKKyAgICAgICAgKyAiQUF3a0FBUUlEQkFVR0J3aUJBZ0NxZ2dJQVZhT0NBaFF3Z2dJUU1BOEdBMVVkRHdFQi93UUZBd01CcW9Bd0VnWUQiCisgICAgICAgICsgIlZSMFRBUUgvQkFnd0JnRUIvd0lCQlRBVUJnTlZIU0FCQWY4RUNqQUlNQXlHQkZVZElBQXdad1lEVlIwUkFRSC9CIgorICAgICAgICArICJGMHdXNEVNY21aalFEZ3lNaTVPWVcxbGdnZGtUbE5PWVcxbHBCY3hGVEFUQmdOVkJBb1RERTl5WjJGdWFYcGhkRyIKKyAgICAgICAgKyAibHZib1lhYUhSMGNEb3ZMM1Z1YVdadmNtMHVVbVZ6YjNWeVkyVXVTV1NIQlAvLy93Q0lCeW9Eb2x5RHNnTXdEQVkiCisgICAgICAgICsgIkRWUjBlQVFIL0JBSXdBREFNQmdOVkhTUUJBZjhFQWpBQU1JR1pCZ05WSFNVQkFmOEVnWTR3Z1lzR0JGVWRKUUFHIgorICAgICAgICArICJDQ3NHQVFVRkJ3TUJCZ2dyQmdFRkJRY0RBUVlJS3hZQkJRVUhBd0lHQ0NzR0FRVUZCd01EQmdnckJnRUZCUWNEQiIKKyAgICAgICAgKyAiQVlJS3dZQkJRVUhBd1VHQ0NzR0FRVUZCd01HQmdnckJnRUZCUWNEQndZSUt3WUJCUVVIQXdnR0NDc0dBUVVGQnciCisgICAgICAgICsgIk1KQmdnckJnRUZCUWdDQWdZS0t3WUJCQUdDTndvREF3WUpZSVpJQVliNFFnUUJNQTBHQTFVZE5nRUIvd1FEQWdFIgorICAgICAgICArICJCTUE0R0JDcE5oZ2tCQWY4RUF3RUJBVEJrQmdOVkhSSUVYVEJiZ1F4eVptTkFPREl5TGs1aGJXV0NCMlJPVTA1aCIKKyAgICAgICAgKyAiYldXa0Z6RVZNQk1HQTFVRUNoTU1UM0puWVc1cGVtRjBhVzl1aGhwb2RIUndPaTh2ZFc1cFptOXliUzVTWlhOdmQiCisgICAgICAgICsgIlhKalpTNUpaSWNFLy8vL0FJZ0hLZ09pWElPeUF6QUpCZ05WSFI4RUFqQUFNQW9HQTFVZEl3UURBUUVCTUFvR0ExIgorICAgICAgICArICJVZERnUURBUUVCTUFvR0ExVWRJUVFEQVFFQk1Bd0hCeXFHU000NEJBTUJBUUFETUFBd0xRSVVBTDRRdm9hek5XUCIKKyAgICAgICAgKyAiN2pyajg0L0dabGhtMDlEc0NGUUNCS0dLQ0diclA2NFZ0VXQ0SlBtTGpXMVZ4UUE9PVxuIgorICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tIjsKKworICAgIC8vIEJhc2U2NCBlbmNvZGVkIGZvcm0gb2YgQVNOLjEgREVSIGVuY29kZWQgWC41MDkgQ1JMCisgICAgLy8gKHNlZSBSRkMgMzI4MCBhdCBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMjgwLnR4dCkKKyAgICAvLyAoZ2VuZXJhdGVkIGJ5IHVzaW5nIG9mIGNsYXNzZXMgZnJvbQorICAgIC8vIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS54NTA5IHBhY2thZ2UpCisgICAgc3RhdGljIFN0cmluZyBiYXNlNjRjcmwgPQorICAgICAgICAiTUlIWE1JR1hBZ0VCTUFrR0J5cUdTTTQ0QkFNd0ZURVRNQkVHQTFVRUNoTUtRMUpNSUVsemMzVmwiCisgICAgICAgICAgICArICJjaGNOTURZd05ESTNNRFl4TXpRMVdoY05NRFl3TkRJM01EWXhOVEkxV2pCQk1EOENBZ0lyRncwdyIKKyAgICAgICAgICAgICsgIk5qQTBNamN3TmpFek5EWmFNQ293Q2dZRFZSMFZCQU1LQVFFd0hBWURWUjBZQkJVWUV6SXdNRFl3IgorICAgICAgICAgICAgKyAiTkRJM01EWXhNelExTGpRMk9GcWdEekFOTUFzR0ExVWRGQVFFQkFRRUJEQUpCZ2NxaGtqT09BUUQiCisgICAgICAgICAgICArICJBekFBTUMwQ0ZRQ2swdDBEVHl1ODJRcGFqYkJseFg5dVh2VURTZ0lVU0JONGcreFRFZWV4cy8wayIKKyAgICAgICAgICAgICsgIjlBa2pCaGpGMEVzPSI7CisKKyAgICAvLyBoYXMgc3R1YiBpbXBsZW1lbnRhdGlvbiBmb3IgYWJzdHJhY3QgbWV0aG9kcworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIE15WDUwOUNlcnRpZmljYXRlIGV4dGVuZHMgWDUwOUNlcnRpZmljYXRlIGltcGxlbWVudHMKKyAgICAgICAgICAgIFg1MDlFeHRlbnNpb24geworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03MTk2Njk0MDcyMjk2NjA3MDA3TDsKKworICAgICAgICBwdWJsaWMgdm9pZCBjaGVja1ZhbGlkaXR5KCkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgY2hlY2tWYWxpZGl0eShEYXRlIGRhdGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0VmVyc2lvbigpIHsKKyAgICAgICAgICAgIHJldHVybiAzOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0U2VyaWFsTnVtYmVyKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUHJpbmNpcGFsIGdldElzc3VlckROKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUHJpbmNpcGFsIGdldFN1YmplY3RETigpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIERhdGUgZ2V0Tm90QmVmb3JlKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgRGF0ZSBnZXROb3RBZnRlcigpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRUQlNDZXJ0aWZpY2F0ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRTaWduYXR1cmUoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2lnQWxnTmFtZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRTaWdBbGdPSUQoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0U2lnQWxnUGFyYW1zKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbltdIGdldElzc3VlclVuaXF1ZUlEKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbltdIGdldFN1YmplY3RVbmlxdWVJRCgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW5bXSBnZXRLZXlVc2FnZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXRCYXNpY0NvbnN0cmFpbnRzKCkgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCB2ZXJpZnkoUHVibGljS2V5IGtleSkgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgdmVyaWZ5KFB1YmxpY0tleSBrZXksIFN0cmluZyBzaWdQcm92aWRlcikgeworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBQdWJsaWNLZXkgZ2V0UHVibGljS2V5KCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTZXQ8U3RyaW5nPiBnZXROb25Dcml0aWNhbEV4dGVuc2lvbk9JRHMoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTZXQ8U3RyaW5nPiBnZXRDcml0aWNhbEV4dGVuc2lvbk9JRHMoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RXh0ZW5zaW9uVmFsdWUoU3RyaW5nIG9pZCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNVbnN1cHBvcnRlZENyaXRpY2FsRXh0ZW5zaW9uKCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZSNnZXRUeXBlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VHlwZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJYLjUwOSIsIG5ldyBNeVg1MDlDZXJ0aWZpY2F0ZSgpLmdldFR5cGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZSNnZXRJc3N1ZXJYNTAwUHJpbmNpcGFsKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SXNzdWVyWDUwMFByaW5jaXBhbCgpIHsKKyAgICAgICAgLy8gcmV0dXJuIHZhbGlkIGVuY29kaW5nCisgICAgICAgIE15WDUwOUNlcnRpZmljYXRlIGNlcnQgPSBuZXcgTXlYNTA5Q2VydGlmaWNhdGUoKSB7CisgICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA2Mzg2NTk5MDgzMjM3NDExNjVMOworCisgICAgICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIFRlc3RVdGlscy5nZXRYNTA5Q2VydGlmaWNhdGVfdjEoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBhc3NlcnRFcXVhbHMobmV3IFg1MDBQcmluY2lwYWwoIkNOPVoiKSwgY2VydC5nZXRJc3N1ZXJYNTAwUHJpbmNpcGFsKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGUjZ2V0U3ViamVjdFg1MDBQcmluY2lwYWwoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRTdWJqZWN0WDUwMFByaW5jaXBhbCgpIHsKKyAgICAgICAgLy8gcmV0dXJuIHZhbGlkIGVuY29kaW5nCisgICAgICAgIE15WDUwOUNlcnRpZmljYXRlIGNlcnQgPSBuZXcgTXlYNTA5Q2VydGlmaWNhdGUoKSB7CisgICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzYyNTkxMzYzNzQxMzg0MDY5NEw7CisKKyAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gVGVzdFV0aWxzLmdldFg1MDlDZXJ0aWZpY2F0ZV92MSgpOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgWDUwMFByaW5jaXBhbCgiQ049WSIpLCBjZXJ0LmdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24KKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlI2dldEV4dGVuZGVkS2V5VXNhZ2UoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRFeHRlbmRlZEtleVVzYWdlKCkgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0TnVsbChuZXcgTXlYNTA5Q2VydGlmaWNhdGUoKS5nZXRFeHRlbmRlZEtleVVzYWdlKCkpOworCisgICAgICAgIExpc3Q8U3RyaW5nPiBsID0gY2VydC5nZXRFeHRlbmRlZEtleVVzYWdlKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwobCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGwuY2xlYXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbC5hZGQoIlRlc3QiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGwuc2l6ZSgpID4gMCkgeworICAgICAgICAgICAgICAgIGwucmVtb3ZlKDApOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZSNnZXRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEdldFN1YmplY3RBbHRlcm5hdGl2ZU5hbWVzKCkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24geworCisgICAgICAgIGFzc2VydE51bGwobmV3IE15WDUwOUNlcnRpZmljYXRlKCkuZ2V0U3ViamVjdEFsdGVybmF0aXZlTmFtZXMoKSk7CisKKyAgICAgICAgQ29sbGVjdGlvbjxMaXN0PD8+PiBjb2xsID0gY2VydC5nZXRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcygpOworICAgICAgICAvL2dldFN1YmplY3RBbHRlcm5hdGl2ZU5hbWVzIG1ldGhvZCBpcyBub3Qgc3VwcG9ydGVkCisgICAgICAgIGFzc2VydE5vdE51bGwoY29sbCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbGwuY2xlYXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGNvbGwuc2l6ZSgpID4gMCkgeworICAgICAgICAgICAgICAgIGNvbGwucmVtb3ZlKDApOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydFRydWUoY29sbC5zaXplKCkgPCAxMCk7CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlI2dldElzc3VlckFsdGVybmF0aXZlTmFtZXMoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJc3N1ZXJBbHRlcm5hdGl2ZU5hbWVzKCkKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24geworCisgICAgICAgIGFzc2VydE51bGwobmV3IE15WDUwOUNlcnRpZmljYXRlKCkuZ2V0SXNzdWVyQWx0ZXJuYXRpdmVOYW1lcygpKTsKKworICAgICAgICBDb2xsZWN0aW9uPExpc3Q8Pz4+IGNvbGwgPSBjZXJ0LmdldElzc3VlckFsdGVybmF0aXZlTmFtZXMoKTsKKyAgICAgICAgLy8gZ2V0SXNzdWVyQWx0ZXJuYXRpdmVOYW1lcyByZXR1cm5zIG51bGwuCisgICAgICAgIGFzc2VydE5vdE51bGwoY29sbCk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNvbGwuY2xlYXIoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIG9rCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGNvbGwuc2l6ZSgpID4gMCkgeworICAgICAgICAgICAgICAgIGNvbGwucmVtb3ZlKDApOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydFRydWUoY29sbC5zaXplKCkgPCAxMCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdENlcmZpY2F0ZUV4Y2VwdGlvbigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJhaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgIGJhc2U2NGNlcnRUYW1wZXJlZC5nZXRCeXRlcygpKTsKKyAgICAgICAgICAgIGNlcnQgPSAoWDUwOUNlcnRpZmljYXRlKSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKGJhaXMpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJhaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYmFzZTY0Y2VydAorICAgICAgICAgICAgICAgICAgICAuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgICBjZXJ0ID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShiYWlzKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmFpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiYXNlNjRjZXJ0Q29ycmVjdAorICAgICAgICAgICAgICAgIC5nZXRCeXRlcygpKTsKKyAgICAgICAgY2VydCA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoYmFpcyk7CisgICAgICAgIGFzc2VydE5vdE51bGwoY2VydCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2ludGVyZmFjZXMvRFNBS2V5UGFpckdlbmVyYXRvclRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL0RTQUtleVBhaXJHZW5lcmF0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGUyZmVmZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL0RTQUtleVBhaXJHZW5lcmF0b3JUZXN0LmphdmEKQEAgLTAsMCArMSwxMzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5pbnRlcmZhY2VzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLkRTQUtleVBhaXJHZW5lcmF0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLkRTQVBhcmFtczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRFNBUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5pbnRlcmZhY2VzLkRTQUtleVBhaXJHZW5lcmF0b3JJbXBsOworCitwdWJsaWMgY2xhc3MgRFNBS2V5UGFpckdlbmVyYXRvclRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgcCA9IG5ldyBCaWdJbnRlZ2VyKCI0Iik7CisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIHEgPSBCaWdJbnRlZ2VyLlRFTjsKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgZyA9IEJpZ0ludGVnZXIuWkVSTzsKKworCisgICAgY2xhc3MgTXlEU0EgZXh0ZW5kcyBEU0FLZXlQYWlyR2VuZXJhdG9ySW1wbCB7CisgICAgICAgIHB1YmxpYyBNeURTQShEU0FQYXJhbXMgZHNhUGFyYW1zKSB7CisgICAgICAgICAgICBzdXBlcihkc2FQYXJhbXMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLkRTQUtleVBhaXJHZW5lcmF0b3IKKyAgICAgKiAjaW5pdGlhbGl6ZShEU0FQYXJhbXMgcGFyYW1zLCBTZWN1cmVSYW5kb20gcmFuZG9tKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfRFNBS2V5UGFpckdlbmVyYXRvcjAxKCkgeworICAgICAgICBEU0FQYXJhbXMgZHNhUGFyYW1zID0gbmV3IERTQVBhcmFtZXRlclNwZWMocCwgcSwgZyk7CisgICAgICAgIFNlY3VyZVJhbmRvbSByYW5kb20gPSBudWxsOworICAgICAgICBNeURTQSBkc2EgPSBuZXcgTXlEU0EoZHNhUGFyYW1zKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhbmRvbSA9IFNlY3VyZVJhbmRvbS5nZXRJbnN0YW5jZSgiU0hBMVBSTkciKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIGZvciBTZWN1cmVSYW5kb206ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkc2EuaW5pdGlhbGl6ZShkc2FQYXJhbXMsIHJhbmRvbSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRzYS5pbml0aWFsaXplKGRzYVBhcmFtcywgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gaXBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRzYS5pbml0aWFsaXplKG51bGwsIHJhbmRvbSk7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gaXBlKSB7CisgICAgICAgICAgICAvL2V4cGVjdGVkCisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuRFNBS2V5UGFpckdlbmVyYXRvcgorICAgICAqICNpbml0aWFsaXplKGludCBtb2RsZW4sIGJvb2xlYW4gZ2VuUGFyYW1zLCBTZWN1cmVSYW5kb20gcmFuZG9tbSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0RTQUtleVBhaXJHZW5lcmF0b3IwMigpIHsKKyAgICAgICAgaW50W10gaW52YWxpZExlbiA9IHstMSwgMCwgNTExLCA1MTMsIDY1MCwgMTAyMywgMTAyNX07CisgICAgICAgIERTQVBhcmFtcyBkc2FQYXJhbXMgPSBuZXcgRFNBUGFyYW1ldGVyU3BlYyhwLCBxLCBnKTsKKyAgICAgICAgU2VjdXJlUmFuZG9tIHJhbmRvbSA9IG51bGw7CisgICAgICAgIE15RFNBIGRzYSA9IG5ldyBNeURTQShudWxsKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJhbmRvbSA9IFNlY3VyZVJhbmRvbS5nZXRJbnN0YW5jZSgiU0hBMVBSTkciKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIGZvciBTZWN1cmVSYW5kb206ICIgKyBlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vZXhjZXB0aW9uIGNhc2UKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRzYS5pbml0aWFsaXplKDUyMCwgZmFsc2UsIHJhbmRvbSk7CisgICAgICAgICAgICBmYWlsKCJJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gaXBlKSB7CisgICAgICAgICAgICBTdHJpbmcgc3RyID0gaXBlLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGlmICghc3RyLmVxdWFscygidGhlcmUgYXJlIG5vdCBwcmVjb21wdXRlZCBwYXJhbWV0ZXJzIikpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJJbmNvcnJlY3QgZXhjZXB0aW9uJ3MgbWVzc2FnZTogIiArIHN0cik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUgKyAiIHdhcyB0aHJvd24gaW5zdGVhZCBvZiBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICAvL2V4Y2VwdGlvbiBjYXNlCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW52YWxpZExlbi5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBkc2EuaW5pdGlhbGl6ZShpbnZhbGlkTGVuW2ldLCB0cnVlLCByYW5kb20pOworICAgICAgICAgICAgICAgIGZhaWwoIkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24gaXBlKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHN0ciA9IGlwZS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICAgICAgaWYgKCFzdHIuZXF1YWxzKCJJbmNvcnJlY3QgbW9kbGVuIikpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiSW5jb3JyZWN0IGV4Y2VwdGlvbidzIG1lc3NhZ2U6ICIgKyBzdHIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGluc3RlYWQgb2YgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy9wb3NpdGl2ZSBjYXNlCisgICAgICAgIGRzYSA9IG5ldyBNeURTQShkc2FQYXJhbXMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZHNhLmluaXRpYWxpemUoNTIwLCB0cnVlLCByYW5kb20pOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlICsgIiB3YXMgdGhyb3duIGZvciBzdWJjYXNlIDEiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vcG9zaXRpdmUgY2FzZQorICAgICAgICB0cnkgeworICAgICAgICAgICAgZHNhLmluaXRpYWxpemUoNTIwLCBmYWxzZSwgcmFuZG9tKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZSArICIgd2FzIHRocm93biBmb3Igc3ViY2FzZSAxIik7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvaW50ZXJmYWNlcy9EU0FLZXlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvaW50ZXJmYWNlcy9EU0FLZXlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTUzY2RkYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL0RTQUtleVRlc3QuamF2YQpAQCAtMCwwICsxLDU2IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuaW50ZXJmYWNlczsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuRFNBS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5EU0FQYXJhbXM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkRTQVBhcmFtZXRlclNwZWM7CisKK3B1YmxpYyBjbGFzcyBEU0FLZXlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLkRTQUtleQorICAgICAqICNnZXRQYXJhbXMoKQorICAgICAqIHRlc3QgY292ZXJzIGZvbGxvd2luZyB1c2UgY2FzZXMKKyAgICAgKiAgIENhc2UgMTogY2hlY2sgcHJpdmF0ZSBrZXkKKyAgICAgKiAgIENhc2UgMjogY2hlY2sgcHVibGljIGtleQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UGFyYW1zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIERTQVBhcmFtcyBwYXJhbSA9IG5ldyBEU0FQYXJhbWV0ZXJTcGVjKFV0aWwuUCwgVXRpbC5RLCBVdGlsLkcpOworCisgICAgICAgIEtleVBhaXJHZW5lcmF0b3IgZ2VuID0gS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZSgiRFNBIik7CisgICAgICAgIGdlbi5pbml0aWFsaXplKChEU0FQYXJhbWV0ZXJTcGVjKSBwYXJhbSk7CisgICAgICAgIERTQUtleSBrZXkgPSBudWxsOworCisgICAgICAgIC8vIENhc2UgMTogY2hlY2sgcHJpdmF0ZSBrZXkKKyAgICAgICAga2V5ID0gKERTQUtleSkgZ2VuLmdlbmVyYXRlS2V5UGFpcigpLmdldFByaXZhdGUoKTsKKyAgICAgICAgYXNzZXJ0RFNBUGFyYW1zRXF1YWxzKHBhcmFtLCBrZXkuZ2V0UGFyYW1zKCkpOworCisgICAgICAgIC8vIENhc2UgMjogY2hlY2sgcHVibGljIGtleQorICAgICAgICBrZXkgPSAoRFNBS2V5KSBnZW4uZ2VuZXJhdGVLZXlQYWlyKCkuZ2V0UHVibGljKCk7CisgICAgICAgIGFzc2VydERTQVBhcmFtc0VxdWFscyhwYXJhbSwga2V5LmdldFBhcmFtcygpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0RFNBUGFyYW1zRXF1YWxzKERTQVBhcmFtcyBleHBlY3RlZCwgRFNBUGFyYW1zIGFjdHVhbCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIlAgZGlmZmVyIiwgZXhwZWN0ZWQuZ2V0UCgpLCBhY3R1YWwuZ2V0UCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJRIGRpZmZlciIsIGV4cGVjdGVkLmdldFEoKSwgYWN0dWFsLmdldFEoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiRyBkaWZmZXIiLCBleHBlY3RlZC5nZXRHKCksIGFjdHVhbC5nZXRHKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL0RTQVBhcmFtc1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL0RTQVBhcmFtc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMDdkNWNkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2ludGVyZmFjZXMvRFNBUGFyYW1zVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuaW50ZXJmYWNlczsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5EU0FQYXJhbXM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkRTQVBhcmFtZXRlclNwZWM7CisKK3B1YmxpYyBjbGFzcyBEU0FQYXJhbXNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIHAgPSBuZXcgQmlnSW50ZWdlcigiNCIpOworICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBxID0gQmlnSW50ZWdlci5URU47CisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIGcgPSBCaWdJbnRlZ2VyLlpFUk87CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuRFNBUGFyYW1zCisgICAgICogI2dldEcoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RygpIHsKKyAgICAgICAgRFNBUGFyYW1zIHBhcmFtcyA9IG5ldyBEU0FQYXJhbWV0ZXJTcGVjKHAsIHEsIGcpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkludmFsaWQgRyIsIGcsIHBhcmFtcy5nZXRHKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5EU0FQYXJhbXMKKyAgICAgKiAjZ2V0UCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQKCkgeworICAgICAgICBEU0FQYXJhbXMgcGFyYW1zID0gbmV3IERTQVBhcmFtZXRlclNwZWMocCwgcSwgZyk7CisgICAgICAgIGFzc2VydEVxdWFscygiSW52YWxpZCBQIiwgcCwgcGFyYW1zLmdldFAoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLkRTQVBhcmFtcworICAgICAqICNnZXRRKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFEoKSB7CisgICAgICAgIERTQVBhcmFtcyBwYXJhbXMgPSBuZXcgRFNBUGFyYW1ldGVyU3BlYyhwLCBxLCBnKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJJbnZhbGlkIFEiLCBxLCBwYXJhbXMuZ2V0USgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvaW50ZXJmYWNlcy9EU0FQcml2YXRlS2V5VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2ludGVyZmFjZXMvRFNBUHJpdmF0ZUtleVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42Y2ViZGE1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2ludGVyZmFjZXMvRFNBUHJpdmF0ZUtleVRlc3QuamF2YQpAQCAtMCwwICsxLDQyIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmludGVyZmFjZXM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5EU0FQcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5EU0FQdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkRTQVBhcmFtZXRlclNwZWM7CisKK3B1YmxpYyBjbGFzcyBEU0FQcml2YXRlS2V5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5EU0FQcml2YXRlS2V5CisgICAgICogI2dldFgoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0WCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGtleUdlbiA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRTQSIpOworICAgICAgICBrZXlHZW4uaW5pdGlhbGl6ZShuZXcgRFNBUGFyYW1ldGVyU3BlYyhVdGlsLlAsIFV0aWwuUSwgVXRpbC5HKSwKKyAgICAgICAgICAgICAgICBuZXcgU2VjdXJlUmFuZG9tKG5ldyBNeVNlY3VyZVJhbmRvbVNwaSgpLCBudWxsKSB7CisgICAgICAgICAgICAgICAgfSk7CisgICAgICAgIEtleVBhaXIga2V5UGFpciA9IGtleUdlbi5nZW5lcmF0ZUtleVBhaXIoKTsKKyAgICAgICAgRFNBUHJpdmF0ZUtleSBrZXkgPSAoRFNBUHJpdmF0ZUtleSkga2V5UGFpci5nZXRQcml2YXRlKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkludmFsaWQgWCB2YWx1ZSIsIGtleS5nZXRYKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL0RTQVB1YmxpY0tleVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL0RTQVB1YmxpY0tleVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZmU0OTEwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2ludGVyZmFjZXMvRFNBUHVibGljS2V5VGVzdC5qYXZhCkBAIC0wLDAgKzEsNjEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuaW50ZXJmYWNlczsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXJHZW5lcmF0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLkRTQVByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLkRTQVB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRFNBUGFyYW1ldGVyU3BlYzsKKworcHVibGljIGNsYXNzIERTQVB1YmxpY0tleVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuRFNBUHVibGljS2V5CisgICAgICogI2dldFkoKQorICAgICAqIHRlc3QgY292ZXJzIGZvbGxvd2luZyB1c2UgY2FzZXMKKyAgICAgKiAgIENhc2UgMTogY2hlY2sgd2l0aCBwcmVkZWZpbmVkIHAsIHEsIGcsIHgKKyAgICAgKiAgIENhc2UgMjogY2hlY2sgd2l0aCByYW5kb20gcCwgcSwgZywgeC4gSXQgdGFrZXMgc29tZSB0aW1lICh1cCB0bworICAgICAqICAgICAgICAgICBtaW51dGUpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRZKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEtleVBhaXJHZW5lcmF0b3Iga2V5R2VuID0gbnVsbDsKKyAgICAgICAgS2V5UGFpciBrZXlzID0gbnVsbDsKKyAgICAgICAgRFNBUHJpdmF0ZUtleSBwcml2ID0gbnVsbDsKKyAgICAgICAgRFNBUHVibGljS2V5IHB1YmwgPSBudWxsOworCisgICAgICAgIC8vIENhc2UgMTogY2hlY2sgd2l0aCBwcmVkZWZpbmVkIHAsIHEsIGcsIHgKKyAgICAgICAga2V5R2VuID0gS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZSgiRFNBIik7CisgICAgICAgIGtleUdlbi5pbml0aWFsaXplKG5ldyBEU0FQYXJhbWV0ZXJTcGVjKFV0aWwuUCwgVXRpbC5RLCBVdGlsLkcpLAorICAgICAgICAgICAgICAgIG5ldyBTZWN1cmVSYW5kb20obmV3IE15U2VjdXJlUmFuZG9tU3BpKCksIG51bGwpIHsKKyAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAga2V5cyA9IGtleUdlbi5nZW5lcmF0ZUtleVBhaXIoKTsKKyAgICAgICAgcHJpdiA9IChEU0FQcml2YXRlS2V5KSBrZXlzLmdldFByaXZhdGUoKTsKKyAgICAgICAgcHVibCA9IChEU0FQdWJsaWNLZXkpIGtleXMuZ2V0UHVibGljKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkludmFsaWQgWSB2YWx1ZSIsIHB1YmwuZ2V0WSgpKTsKKworICAgICAgICAvLyBDYXNlIDI6IGNoZWNrIHdpdGggcmFuZG9tIHAsIHEsIGcsIHguIEl0IHRha2VzIHNvbWUgdGltZSAodXAgdG8KKyAgICAgICAgLy8gbWludXRlKQorICAgICAgICBrZXlHZW4gPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKCJEU0EiKTsKKyAgICAgICAga2V5cyA9IGtleUdlbi5nZW5lcmF0ZUtleVBhaXIoKTsKKyAgICAgICAgcHJpdiA9IChEU0FQcml2YXRlS2V5KSBrZXlzLmdldFByaXZhdGUoKTsKKyAgICAgICAgcHVibCA9IChEU0FQdWJsaWNLZXkpIGtleXMuZ2V0UHVibGljKCk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIkludmFsaWQgWSB2YWx1ZSIsIHB1YmwuZ2V0WSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvaW50ZXJmYWNlcy9SU0FLZXlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvaW50ZXJmYWNlcy9SU0FLZXlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWYyODMwZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL1JTQUtleVRlc3QuamF2YQpAQCAtMCwwICsxLDUwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LmludGVyZmFjZXM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLlJTQUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuUlNBUHJpdmF0ZUtleVNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLlJTQVB1YmxpY0tleVNwZWM7CisKK3B1YmxpYyBjbGFzcyBSU0FLZXlUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLlJTQUtleQorICAgICAqICNnZXRNb2R1bHVzKCkKKyAgICAgKiB0ZXN0IGNvdmVycyBmb2xsb3dpbmcgdXNlIGNhc2VzCisgICAgICogICBDYXNlIDE6IGNoZWNrIHByaXZhdGUga2V5CisgICAgICogICBDYXNlIDI6IGNoZWNrIHB1YmxpYyBrZXkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE1vZHVsdXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5RmFjdG9yeSBnZW4gPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKCJSU0EiKTsKKyAgICAgICAgZmluYWwgQmlnSW50ZWdlciBuID0gQmlnSW50ZWdlci52YWx1ZU9mKDMyMzMpOworICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIGQgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoMjc1Myk7CisgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgZSA9IEJpZ0ludGVnZXIudmFsdWVPZigxNyk7CisgICAgICAgIFJTQUtleSBrZXkgPSBudWxsOworCisgICAgICAgIC8vIENhc2UgMTogY2hlY2sgcHJpdmF0ZSBrZXkKKyAgICAgICAga2V5ID0gKFJTQUtleSkgZ2VuLmdlbmVyYXRlUHJpdmF0ZShuZXcgUlNBUHJpdmF0ZUtleVNwZWMobiwgZCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImludmFsaWQgbW9kdWx1cyIsIG4sIGtleS5nZXRNb2R1bHVzKCkpOworCisgICAgICAgIC8vIENhc2UgMjogY2hlY2sgcHVibGljIGtleQorICAgICAgICBrZXkgPSAoUlNBS2V5KSBnZW4uZ2VuZXJhdGVQdWJsaWMobmV3IFJTQVB1YmxpY0tleVNwZWMobiwgZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImludmFsaWQgbW9kdWx1cyIsIG4sIGtleS5nZXRNb2R1bHVzKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL1JTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5VGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2ludGVyZmFjZXMvUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGNhOGRlNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL1JTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuaW50ZXJmYWNlczsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5SU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuUlNBT3RoZXJQcmltZUluZm87CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5pbnRlcmZhY2VzLlJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5SW1wbDsKKworcHVibGljIGNsYXNzIFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFJlZmVyZW5jZSBhcnJheSBvZiBSU0FPdGhlclByaW1lSW5mby4gRE8gTk9UIE1PRElGWQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFJTQU90aGVyUHJpbWVJbmZvW10gb3BpID0gbmV3IFJTQU90aGVyUHJpbWVJbmZvW10geworICAgICAgICAgICAgbmV3IFJTQU90aGVyUHJpbWVJbmZvKEJpZ0ludGVnZXIuT05FLCBCaWdJbnRlZ2VyLk9ORSwgQmlnSW50ZWdlci5PTkUpLAorICAgICAgICAgICAgbmV3IFJTQU90aGVyUHJpbWVJbmZvKEJpZ0ludGVnZXIuT05FLCBCaWdJbnRlZ2VyLk9ORSwgQmlnSW50ZWdlci5PTkUpLAorICAgICAgICAgICAgbmV3IFJTQU90aGVyUHJpbWVJbmZvKEJpZ0ludGVnZXIuT05FLCBCaWdJbnRlZ2VyLk9ORSwgQmlnSW50ZWdlci5PTkUpCisgICAgfTsKKworICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBwdWJsaWNFeHBvbmVudCA9IEJpZ0ludGVnZXIuT05FOworICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBwcmltZUV4cG9uZW50UCA9IEJpZ0ludGVnZXIuT05FOworICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBwcmltZUV4cG9uZW50USA9IEJpZ0ludGVnZXIuT05FOworICAgIHByaXZhdGUgZmluYWwgQmlnSW50ZWdlciBwcmltZVAgPSBCaWdJbnRlZ2VyLk9ORTsKKyAgICBwcml2YXRlIGZpbmFsIEJpZ0ludGVnZXIgcHJpbWVRID0gQmlnSW50ZWdlci5PTkU7CisgICAgcHJpdmF0ZSBmaW5hbCBCaWdJbnRlZ2VyIGNydENvZWZmaWNpZW50ID0gQmlnSW50ZWdlci5PTkU7CisKKyAgICBjbGFzcyBSU0FNdWx0aSBleHRlbmRzIFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5SW1wbCB7CisgICAgICAgIHB1YmxpYyBSU0FNdWx0aShCaWdJbnRlZ2VyIHB1YmxpY0V4cCwKKyAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVFeHBQLAorICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZUV4cFEsCisgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByUCwKKyAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJRLAorICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBjcnRDZnQsCisgICAgICAgICAgICAgICAgICAgICAgICBSU0FPdGhlclByaW1lSW5mb1tdIG90aGVyUHJtSW5mbykgeworICAgICAgICAgICAgc3VwZXIocHVibGljRXhwLCBwcmltZUV4cFAsIHByaW1lRXhwUSwgcHJQLCBwclEsIGNydENmdCwgb3RoZXJQcm1JbmZvKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5SU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleSNnZXRDcnRDb2VmZmljaWVudCgpCisgICAgICogamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLlJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5I2dldFByaW1lRXhwb25lbnRQKCkKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXkjZ2V0UHJpbWVFeHBvbmVudFEoKQorICAgICAqIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5SU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleSNnZXRQcmltZVAoKQorICAgICAqIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5SU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleSNnZXRQcmltZVEoKQorICAgICAqIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5SU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleSNnZXRQdWJsaWNFeHBvbmVudCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9SU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleSgpIHsKKyAgICAgICAgUlNBTXVsdGkgcnNhbSA9IG5ldyBSU0FNdWx0aShwdWJsaWNFeHBvbmVudCwgcHJpbWVFeHBvbmVudFAsIHByaW1lRXhwb25lbnRRLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW1lUCwgcHJpbWVRLCBjcnRDb2VmZmljaWVudCwgb3BpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhyc2FtLmdldENydENvZWZmaWNpZW50KCksIGNydENvZWZmaWNpZW50KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhyc2FtLmdldFByaW1lRXhwb25lbnRQKCksIHByaW1lRXhwb25lbnRQKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhyc2FtLmdldFByaW1lRXhwb25lbnRRKCksIHByaW1lRXhwb25lbnRRKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhyc2FtLmdldFByaW1lUCgpLCBwcmltZVApOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHJzYW0uZ2V0UHJpbWVRKCksIHByaW1lUSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMocnNhbS5nZXRQdWJsaWNFeHBvbmVudCgpLCBwdWJsaWNFeHBvbmVudCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLlJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5I2dldE90aGVyUHJpbWVJbmZvKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldE90aGVyUHJpbWVJbmZvKCkgeworICAgICAgICBSU0FNdWx0aSByc2FtID0gbmV3IFJTQU11bHRpKHB1YmxpY0V4cG9uZW50LCBwcmltZUV4cG9uZW50UCwgcHJpbWVFeHBvbmVudFEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbWVQLCBwcmltZVEsIGNydENvZWZmaWNpZW50LCBudWxsKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydE51bGwoIk9iamVjdCBSU0FPdGhlclByaW1lSW5mbyBpcyBub3QgTlVMTCIsIHJzYW0uZ2V0T3RoZXJQcmltZUluZm8oKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisgICAgICAgIHJzYW0gPSBuZXcgUlNBTXVsdGkocHVibGljRXhwb25lbnQsIHByaW1lRXhwb25lbnRQLCBwcmltZUV4cG9uZW50USwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmltZVAsIHByaW1lUSwgY3J0Q29lZmZpY2llbnQsIG9waSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhyc2FtLmdldE90aGVyUHJpbWVJbmZvKCksIG9waSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2ludGVyZmFjZXMvUlNBUHJpdmF0ZUNydEtleVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL1JTQVByaXZhdGVDcnRLZXlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDBjNzk0YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL1JTQVByaXZhdGVDcnRLZXlUZXN0LmphdmEKQEAgLTAsMCArMSw5MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5pbnRlcmZhY2VzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlGYWN0b3J5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5SU0FQcml2YXRlQ3J0S2V5OworCitwdWJsaWMgY2xhc3MgUlNBUHJpdmF0ZUNydEtleVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBSU0FQcml2YXRlQ3J0S2V5IGtleSA9IG51bGw7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBLZXlGYWN0b3J5IGdlbiA9IEtleUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlJTQSIpOworICAgICAgICBrZXkgPSAoUlNBUHJpdmF0ZUNydEtleSkgZ2VuLmdlbmVyYXRlUHJpdmF0ZShVdGlsLnJzYUNydFBhcmFtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuUlNBUHJpdmF0ZUNydEtleQorICAgICAqICNnZXRDcnRDb2VmZmljaWVudCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRDcnRDb2VmZmljaWVudCgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbnZhbGlkIENSVCBjb2VmZmljaWVudCIsCisgICAgICAgICAgICAgICAgVXRpbC5yc2FDcnRQYXJhbS5nZXRDcnRDb2VmZmljaWVudCgpLCBrZXkuZ2V0Q3J0Q29lZmZpY2llbnQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLlJTQVByaXZhdGVDcnRLZXkKKyAgICAgKiAjZ2V0UHJpbWVFeHBvbmVudFAoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UHJpbWVFeHBvbmVudFAoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiaW52YWxpZCBwcmltZSBleHBvbmVudCBQIiwKKyAgICAgICAgICAgICAgICBVdGlsLnJzYUNydFBhcmFtLmdldFByaW1lRXhwb25lbnRQKCksIGtleS5nZXRQcmltZUV4cG9uZW50UCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuUlNBUHJpdmF0ZUNydEtleQorICAgICAqICNnZXRQcmltZUV4cG9uZW50USgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQcmltZUV4cG9uZW50USgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbnZhbGlkIHByaW1lIGV4cG9uZW50IFEiLAorICAgICAgICAgICAgICAgIFV0aWwucnNhQ3J0UGFyYW0uZ2V0UHJpbWVFeHBvbmVudFEoKSwga2V5LmdldFByaW1lRXhwb25lbnRRKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5SU0FQcml2YXRlQ3J0S2V5CisgICAgICogI2dldFByaW1lUCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQcmltZVAoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiaW52YWxpZCBwcmltZSBQIiwKKyAgICAgICAgICAgICAgICBVdGlsLnJzYUNydFBhcmFtLmdldFByaW1lUCgpLCBrZXkuZ2V0UHJpbWVQKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5SU0FQcml2YXRlQ3J0S2V5CisgICAgICogI2dldFByaW1lUSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQcmltZVEoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiaW52YWxpZCBwcmltZSBRIiwKKyAgICAgICAgICAgICAgICBVdGlsLnJzYUNydFBhcmFtLmdldFByaW1lUSgpLCBrZXkuZ2V0UHJpbWVRKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5SU0FQcml2YXRlQ3J0S2V5CisgICAgICogI2dldFB1YmxpY0V4cG9uZW50KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2dldFB1YmxpY0V4cG9uZW50KCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoImludmFsaWQgcHVibGljIGV4cG9uZW50IiwKKyAgICAgICAgICAgICAgICBVdGlsLnJzYUNydFBhcmFtLmdldFB1YmxpY0V4cG9uZW50KCksIGtleS5nZXRQdWJsaWNFeHBvbmVudCgpKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBrZXkgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL1JTQVByaXZhdGVLZXlUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvaW50ZXJmYWNlcy9SU0FQcml2YXRlS2V5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1MDM1YTkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvaW50ZXJmYWNlcy9SU0FQcml2YXRlS2V5VGVzdC5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuaW50ZXJmYWNlczsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5RmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuUlNBUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuUlNBUHJpdmF0ZUtleVNwZWM7CisKK3B1YmxpYyBjbGFzcyBSU0FQcml2YXRlS2V5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5SU0FQcml2YXRlS2V5CisgICAgICogI2dldFByaXZhdGVFeHBvbmVudCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9nZXRQcml2YXRlRXhwb25lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5RmFjdG9yeSBnZW4gPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKCJSU0EiKTsKKyAgICAgICAgZmluYWwgQmlnSW50ZWdlciBuID0gQmlnSW50ZWdlci52YWx1ZU9mKDMyMzMpOworICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIGQgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoMjc1Myk7CisgICAgICAgIFJTQVByaXZhdGVLZXkga2V5ID0gKFJTQVByaXZhdGVLZXkpIGdlbi5nZW5lcmF0ZVByaXZhdGUobmV3IFJTQVByaXZhdGVLZXlTcGVjKAorICAgICAgICAgICAgICAgIG4sIGQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbnZhbGlkIHByaXZhdGUgZXhwb25lbnQiLCBkLCBrZXkuZ2V0UHJpdmF0ZUV4cG9uZW50KCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL1JTQVB1YmxpY0tleVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL1JTQVB1YmxpY0tleVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wOTkxOWFmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L2ludGVyZmFjZXMvUlNBUHVibGljS2V5VGVzdC5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuaW50ZXJmYWNlczsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5RmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuUlNBUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5SU0FQdWJsaWNLZXlTcGVjOworCitwdWJsaWMgY2xhc3MgUlNBUHVibGljS2V5VGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5SU0FQdWJsaWNLZXkKKyAgICAgKiAjZ2V0UHVibGljRXhwb25lbnQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0UHVibGljRXhwb25lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5RmFjdG9yeSBnZW4gPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKCJSU0EiKTsKKyAgICAgICAgZmluYWwgQmlnSW50ZWdlciBuID0gQmlnSW50ZWdlci52YWx1ZU9mKDMyMzMpOworICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIGUgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoMTcpOworICAgICAgICBSU0FQdWJsaWNLZXkga2V5ID0gKFJTQVB1YmxpY0tleSkgZ2VuLmdlbmVyYXRlUHVibGljKG5ldyBSU0FQdWJsaWNLZXlTcGVjKAorICAgICAgICAgICAgICAgIG4sIGUpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbnZhbGlkIHB1YmxpYyBleHBvbmVudCIsIGUsIGtleS5nZXRQdWJsaWNFeHBvbmVudCgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvaW50ZXJmYWNlcy9VdGlsLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvaW50ZXJmYWNlcy9VdGlsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTZiYTM2ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9pbnRlcmZhY2VzL1V0aWwuamF2YQpAQCAtMCwwICsxLDEwOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5pbnRlcmZhY2VzOworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tU3BpOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FQ0ZpZWxkRnA7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkVDUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRUNQb2ludDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRWxsaXB0aWNDdXJ2ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuUlNBUHJpdmF0ZUNydEtleVNwZWM7CisKKy8qKgorICogVXRpbGl0eSBjbGFzcyB0byBwcm92aWRlIHNvbWUgY29uc3RhbnRzCisgKi8KK2NsYXNzIFV0aWwgeworCisgICAgLyoqCisgICAgICogVmFsaWQgUCBmb3IgRFNBIHRlc3RzCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIEJpZ0ludGVnZXIgUCA9IG5ldyBCaWdJbnRlZ2VyKAorICAgICAgICAgICAgIjE3ODQ3OTU3MjI4MTg5NjU1MTY0NjAwNDM2NDQ3OTE4NjI0MzI3NDU1NDI1MzQ0Mjk3MTY3NTIwMjcxMjAzNzE2OCIKKyAgICAgICAgICAgICAgICAgICAgKyAiODI4MDU0MzkxNzEyODY3NTcwMTI2MjI3NDIyNzM1NjY2Mjg5NTM5Mjk3ODQzODU2NTQ4NTk4OTgiCisgICAgICAgICAgICAgICAgICAgICsgIjI4MDE5OTQzMjY2NDk4OTcwNjk1ODc4MDE0Njk5NDIzNTY1Nzc1NTAwMjgxMDEzNjYxNjA0NTczIgorICAgICAgICAgICAgICAgICAgICArICIwOTM1MTM3MDk0MjQ0MTg3OTg4OTQ3NzY0NzY2OTY2NDg3NjgwNTk5OTE2MTM1ODY3NTEyMTkwOSIKKyAgICAgICAgICAgICAgICAgICAgKyAiMDI4NzU0NjE4NDA1NTA5MzI2MjQ2NTI0MDI3MzIzMDcxODQ4NjIwNTE4MTIxMTk4MDk1MTA0NjciCisgICAgICAgICAgICAgICAgICAgICsgIjY5OTcxNDk0OTk1MzM0NjYzNjEiKTsKKworICAgIC8qKgorICAgICAqIFZhbGlkIFEgZm9yIERTQSB0ZXN0cworICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBCaWdJbnRlZ2VyIFEgPSBuZXcgQmlnSW50ZWdlcigKKyAgICAgICAgICAgICI3NjQ5MDU0MDgxMDA1NDQ0MTc0NTI5NTcwNTc0MDQ4MTU4NTI4OTQ1MzQ3MDk0MjMiKTsKKworICAgIC8qKgorICAgICAqIFZhbGlkIEcgZm9yIERTQSB0ZXN0cworICAgICAqLworICAgIHN0YXRpYyBmaW5hbCBCaWdJbnRlZ2VyIEcgPSBuZXcgQmlnSW50ZWdlcigKKyAgICAgICAgICAgICIyNTAzNDYzMDM4NzA0ODI4Mjg1MzA4NDIxNzY5ODYzOTM0MTU1MTMwNzE5MTI5MzcwNDE0MjUzMjIwMTIzNjEwMTIiCisgICAgICAgICAgICAgICAgICAgICsgIjE2NTc1NzI1Njg5NzA2ODIxODU1OTI5MjY1MDc1MjY1NDIzODE3MDA5NDk3Nzk4OTQ4OTE0NzkzIgorICAgICAgICAgICAgICAgICAgICArICIzNjI3Mjc2OTcyMTU2Nzg3NjgyNjk0OTA3MDUzODY3MTQzODYzNjYyNjcxNTMwODIxNjA2NDYxMCIKKyAgICAgICAgICAgICAgICAgICAgKyAiOTExNjE1NzM4ODU5OTEwNzA5ODQ1ODA2MDc2NTI1NDE4NDUxMjczOTk4NjU2NjE1MjAxOTE3MjYiCisgICAgICAgICAgICAgICAgICAgICsgIjQ3ODE4OTEzMzg2NjE4OTY4MjI5ODM1MTc4NDQ2MTA0NTY2NTQzODE0NTc3NDM2MzEyNjg1MDIxIgorICAgICAgICAgICAgICAgICAgICArICI3MTM5Nzk0MTQxNTM1NTc1MzciKTsKKworICAgIC8qKgorICAgICAqIFZhbHVlIHJldHVybmVkIHVzaW5nIE15U2VjdXJlUmFuZG9tU3BpCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIEJpZ0ludGVnZXIgUk5EX1JFVCA9IG5ldyBCaWdJbnRlZ2VyKCIxMCIpOworCisgICAgLyoqCisgICAgICogVmFsaWQgUlNBIHBhcmFtZXRlcnMKKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgUlNBUHJpdmF0ZUNydEtleVNwZWMgcnNhQ3J0UGFyYW0gPSBuZXcgUlNBUHJpdmF0ZUNydEtleVNwZWMoCisgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoMzIzMyksIEJpZ0ludGVnZXIudmFsdWVPZigxNyksCisgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoMjc1MyksIEJpZ0ludGVnZXIudmFsdWVPZig2MSksCisgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoNTMpLCBCaWdJbnRlZ2VyLnZhbHVlT2YoNTMpLAorICAgICAgICAgICAgQmlnSW50ZWdlci52YWx1ZU9mKDQ5KSwgQmlnSW50ZWdlci52YWx1ZU9mKDUyKSk7CisKKyAgICAvKioKKyAgICAgKiBWYWxpZCBFQyBwYXJhbWV0ZXJzCisgICAgICovCisgICAgc3RhdGljIGZpbmFsIEVDUGFyYW1ldGVyU3BlYyBlY1BhcmFtID0gbmV3IEVDUGFyYW1ldGVyU3BlYygKKyAgICAgICAgICAgIG5ldyBFbGxpcHRpY0N1cnZlKAorICAgICAgICAgICAgICAgICAgICBuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigyMykpLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoNSksIEJpZ0ludGVnZXIudmFsdWVPZigzKSksCisgICAgICAgICAgICBuZXcgRUNQb2ludChCaWdJbnRlZ2VyLnZhbHVlT2YoMSksIEJpZ0ludGVnZXIudmFsdWVPZigzKSksCisgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoMjMpLCAxKTsKKworICAgIHByaXZhdGUgVXRpbCgpIHsKKyAgICB9Cit9CisKKy8qKgorICogVXRpbGl0eSBjbGFzcyB0byBwcm92aWRlICJyYW5kb20iIGRhdGEuCisgKiBSZXR1cm5lZCB2YWx1ZSBpcyBhbHdheXMgY29uc3RhbnQgMTAgaWYgY29udmVydGVkIHRvIEJpZ0ludGVnZXIKKyAqLworQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCitjbGFzcyBNeVNlY3VyZVJhbmRvbVNwaSBleHRlbmRzIFNlY3VyZVJhbmRvbVNwaSB7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuZ2luZUdlbmVyYXRlU2VlZChpbnQgYXJnMCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVOZXh0Qnl0ZXMoYnl0ZVtdIGJ5dGVzKSB7CisgICAgICAgIGphdmEudXRpbC5BcnJheXMuZmlsbChieXRlcywgKGJ5dGUpIDApOworICAgICAgICBieXRlc1tieXRlcy5sZW5ndGggLSAxXSA9IChieXRlKSAxMDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVTZXRTZWVkKGJ5dGVbXSBhcmcwKSB7CisgICAgICAgIHJldHVybjsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0RTQVBhcmFtZXRlclNwZWNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9EU0FQYXJhbWV0ZXJTcGVjVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyNzBhMGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9EU0FQYXJhbWV0ZXJTcGVjVGVzdC5qYXZhCkBAIC0wLDAgKzEsODQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5EU0FQYXJhbWV0ZXJTcGVjOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5EU0FQYXJhbWV0ZXJTcGVjPC9jb2RlPgorICoKKyAqLworcHVibGljIGNsYXNzIERTQVBhcmFtZXRlclNwZWNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogQ3RvciB0ZXN0CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdERTQVBhcmFtZXRlclNwZWMoKSB7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgYXBzID0gbmV3IERTQVBhcmFtZXRlclNwZWMoCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjEiKSwKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMiIpLAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIzIikpOworCisgICAgICAgIGFzc2VydFRydWUoYXBzIGluc3RhbmNlb2YgRFNBUGFyYW1ldGVyU3BlYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0RygpIHRlc3QKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0RygpIHsKKyAgICAgICAgRFNBUGFyYW1ldGVyU3BlYyBkcHMgPSBuZXcgRFNBUGFyYW1ldGVyU3BlYygKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMSIpLAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIyIiksCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjMiKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGRwcy5nZXRHKCkuaW50VmFsdWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0UCgpIHRlc3QKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0UCgpIHsKKyAgICAgICAgRFNBUGFyYW1ldGVyU3BlYyBkcHMgPSBuZXcgRFNBUGFyYW1ldGVyU3BlYygKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMSIpLAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIyIiksCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjMiKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGRwcy5nZXRQKCkuaW50VmFsdWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogZ2V0USgpIHRlc3QKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0USgpIHsKKyAgICAgICAgRFNBUGFyYW1ldGVyU3BlYyBkcHMgPSBuZXcgRFNBUGFyYW1ldGVyU3BlYygKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMSIpLAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIyIiksCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjMiKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIGRwcy5nZXRRKCkuaW50VmFsdWUoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvRFNBUHJpdmF0ZUtleVNwZWNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9EU0FQcml2YXRlS2V5U3BlY1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45OGJkOGYwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvRFNBUHJpdmF0ZUtleVNwZWNUZXN0LmphdmEKQEAgLTAsMCArMSwxMDIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5EU0FQcml2YXRlS2V5U3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuS2V5U3BlYzsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+RFNBUHJpdmF0ZUtleVNwZWM8L2NvZGU+CisgKgorICovCitwdWJsaWMgY2xhc3MgRFNBUHJpdmF0ZUtleVNwZWNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgY29uc3RydWN0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RFNBUHJpdmF0ZUtleVNwZWMoKSB7CisgICAgICAgIEtleVNwZWMga3MgPSBuZXcgRFNBUHJpdmF0ZUtleVNwZWMoCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjEiKSwKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMiIpLAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIzIiksCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjQiKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShrcyBpbnN0YW5jZW9mIERTQVByaXZhdGVLZXlTcGVjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRHKCkgdGVzdAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRHKCkgeworICAgICAgICBEU0FQcml2YXRlS2V5U3BlYyBkcGtzID0gbmV3IERTQVByaXZhdGVLZXlTcGVjKAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIxIiksCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjIiKSwKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMyIpLAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCI0IikpOworCisgICAgICAgIGFzc2VydEVxdWFscyg0LCBkcGtzLmdldEcoKS5pbnRWYWx1ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRQKCkgdGVzdAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRQKCkgeworICAgICAgICBEU0FQcml2YXRlS2V5U3BlYyBkcGtzID0gbmV3IERTQVByaXZhdGVLZXlTcGVjKAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIxIiksCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjIiKSwKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMyIpLAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCI0IikpOworCisgICAgICAgIGFzc2VydEVxdWFscygyLCBkcGtzLmdldFAoKS5pbnRWYWx1ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRRKCkgdGVzdAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRRKCkgeworICAgICAgICBEU0FQcml2YXRlS2V5U3BlYyBkcGtzID0gbmV3IERTQVByaXZhdGVLZXlTcGVjKAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIxIiksCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjIiKSwKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMyIpLAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCI0IikpOworCisgICAgICAgIGFzc2VydEVxdWFscygzLCBkcGtzLmdldFEoKS5pbnRWYWx1ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBnZXRYKCkgdGVzdAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRYKCkgeworICAgICAgICBEU0FQcml2YXRlS2V5U3BlYyBkcGtzID0gbmV3IERTQVByaXZhdGVLZXlTcGVjKAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIxIiksCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjIiKSwKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMyIpLAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCI0IikpOworCisgICAgICAgIGFzc2VydEVxdWFscygxLCBkcGtzLmdldFgoKS5pbnRWYWx1ZSgpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0RTQVB1YmxpY0tleVNwZWNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9EU0FQdWJsaWNLZXlTcGVjVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE5MjE1NjYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9EU0FQdWJsaWNLZXlTcGVjVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LnNwZWM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRFNBUHVibGljS2V5U3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuS2V5U3BlYzsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+RFNBUHVibGljS2V5U3BlYzwvY29kZT4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBEU0FQdWJsaWNLZXlTcGVjVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkRTQVB1YmxpY0tleVNwZWM8L2NvZGU+IGN0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RFNBUHVibGljS2V5U3BlYygpIHsKKyAgICAgICAgS2V5U3BlYyBrcyA9IG5ldyBEU0FQdWJsaWNLZXlTcGVjKAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIxIiksIC8vIHkKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMiIpLCAvLyBwCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjMiKSwgLy8gcQorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCI0IikpOy8vIGcKKworICAgICAgICBhc3NlcnRUcnVlKGtzIGluc3RhbmNlb2YgRFNBUHVibGljS2V5U3BlYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0RzwvY29kZT4gbWV0aG9kCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEcoKSB7CisgICAgICAgIERTQVB1YmxpY0tleVNwZWMgZHBrcyA9IG5ldyBEU0FQdWJsaWNLZXlTcGVjKAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIxIiksIC8vIHkKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMiIpLCAvLyBwCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjMiKSwgLy8gcQorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCI0IikpOy8vIGcKKworICAgICAgICBhc3NlcnRFcXVhbHMoNCwgZHBrcy5nZXRHKCkuaW50VmFsdWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UDwvY29kZT4gbWV0aG9kCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFAoKSB7CisgICAgICAgIERTQVB1YmxpY0tleVNwZWMgZHBrcyA9IG5ldyBEU0FQdWJsaWNLZXlTcGVjKAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIxIiksIC8vIHkKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMiIpLCAvLyBwCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjMiKSwgLy8gcQorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCI0IikpOy8vIGcKKworICAgICAgICBhc3NlcnRFcXVhbHMoMiwgZHBrcy5nZXRQKCkuaW50VmFsdWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UTwvY29kZT4gbWV0aG9kCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFEoKSB7CisgICAgICAgIERTQVB1YmxpY0tleVNwZWMgZHBrcyA9IG5ldyBEU0FQdWJsaWNLZXlTcGVjKAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIxIiksIC8vIHkKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMiIpLCAvLyBwCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjMiKSwgLy8gcQorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCI0IikpOy8vIGcKKworICAgICAgICBhc3NlcnRFcXVhbHMoMywgZHBrcy5nZXRRKCkuaW50VmFsdWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0WTwvY29kZT4gbWV0aG9kCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFkoKSB7CisgICAgICAgIERTQVB1YmxpY0tleVNwZWMgZHBrcyA9IG5ldyBEU0FQdWJsaWNLZXlTcGVjKAorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIxIiksIC8vIHkKKyAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMiIpLCAvLyBwCisgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjMiKSwgLy8gcQorICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCI0IikpOy8vIGcKKworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZHBrcy5nZXRZKCkuaW50VmFsdWUoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvRUNGaWVsZEYybVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0VDRmllbGRGMm1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmU1NDFjMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0VDRmllbGRGMm1UZXN0LmphdmEKQEAgLTAsMCArMSw1NzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FQ0ZpZWxkRjJtOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+RUNGaWVsZEYybTwvY29kZT4gY2xhc3MgZmllbGRzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIEVDRmllbGRGMm1UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogU3VwcG9ydCBjbGFzcyBmb3IgdGhpcyB0ZXN0LgorICAgICAqIEVuY2Fwc3VsYXRlcyA8Y29kZT5FQ0ZpZWxkRjJtPC9jb2RlPiB0ZXN0aW5nCisgICAgICogZG9tYWluIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogPGNvZGU+TlBFPC9jb2RlPiByZWZlcmVuY2Ugb2JqZWN0IG9mIGNsYXNzIE51bGxQb2ludGVyRXhjZXB0aW9uLgorICAgICAgICAgKiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBtdXN0IGJlIHRocm93biBieSA8Y29kZT5FQ0ZpZWxkRjJtPC9jb2RlPgorICAgICAgICAgKiBjdG9ycyBpbiBzb21lIGNpcmN1bXN0YW5jZXMKKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBmaW5hbCBOdWxsUG9pbnRlckV4Y2VwdGlvbiBOUEUgPSBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgLyoqCisgICAgICAgICAqIDxjb2RlPklBcmdFPC9jb2RlPiByZWZlcmVuY2Ugb2JqZWN0IG9mIGNsYXNzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi4KKyAgICAgICAgICogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG11c3QgYmUgdGhyb3duIGJ5IDxjb2RlPkVDRmllbGRGMm08L2NvZGU+CisgICAgICAgICAqIGN0b3JzIGluIHNvbWUgY2lyY3Vtc3RhbmNlcworICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIGZpbmFsIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJQXJnRSA9IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIDxjb2RlPm08L2NvZGU+IHBhcmFtZXRlciBmb3IgPGNvZGU+RUNGaWVsZEYybTwvY29kZT4KKyAgICAgICAgICogY3RvciBmb3IgdGhlIGN1cnJlbnQgdGVzdC4KKyAgICAgICAgICovCisgICAgICAgIGZpbmFsIGludCBtOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIDxjb2RlPnJwPC9jb2RlPiBwYXJhbWV0ZXIgZm9yIDxjb2RlPkVDRmllbGRGMm08L2NvZGU+CisgICAgICAgICAqIGN0b3IgZm9yIHRoZSBjdXJyZW50IHRlc3QuCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIHJwOworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIDxjb2RlPmtzPC9jb2RlPiBwYXJhbWV0ZXIgZm9yIDxjb2RlPkVDRmllbGRGMm08L2NvZGU+CisgICAgICAgICAqIGN0b3IgZm9yIHRoZSBjdXJyZW50IHRlc3QuCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBpbnRbXSBrczsKKworCisgICAgICAgIC8qKgorICAgICAgICAgKiBFeGNlcHRpb24gZXhwZWN0ZWQgd2l0aCB0aGlzIHBhcmFtZXRlcnMgc2V0IG9yIDxjb2RlPm51bGw8L2NvZGU+CisgICAgICAgICAqIGlmIG5vIGV4Y2VwdGlvbiBleHBlY3RlZC4KKyAgICAgICAgICovCisgICAgICAgIGZpbmFsIEV4Y2VwdGlvbiB4OworCisgICAgICAgIC8qKgorICAgICAgICAgKiBDb25zdHJ1Y3RzIEVDRmllbGRGMm1Eb21haW5QYXJhbXMKKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG0KKyAgICAgICAgICogQHBhcmFtIHJwCisgICAgICAgICAqIEBwYXJhbSBrcworICAgICAgICAgKiBAcGFyYW0gZXhwZWN0ZWRFeGNlcHRpb24KKyAgICAgICAgICovCisgICAgICAgIEVDRmllbGRGMm1Eb21haW5QYXJhbXMoZmluYWwgaW50IG0sCisgICAgICAgICAgICAgICAgZmluYWwgQmlnSW50ZWdlciBycCwKKyAgICAgICAgICAgICAgICBmaW5hbCBpbnRbXSBrcywKKyAgICAgICAgICAgICAgICBmaW5hbCBFeGNlcHRpb24gZXhwZWN0ZWRFeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRoaXMubSA9IG07CisgICAgICAgICAgICB0aGlzLnJwID0gcnA7CisgICAgICAgICAgICB0aGlzLmtzID0ga3M7CisgICAgICAgICAgICB0aGlzLnggPSBleHBlY3RlZEV4Y2VwdGlvbjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vCisgICAgLy8gVGVzdHMKKyAgICAvLworCisgICAgLyoqCisgICAgICogU2V0IG9mIHBhcmFtZXRlcnMgdXNlZCBmb3IgPGNvZGU+RUNGaWVsZEYybShpbnQpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIHRlc3RzLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgRUNGaWVsZEYybURvbWFpblBhcmFtc1tdIGludEN0b3JUZXN0UGFyYW1ldGVycyA9CisgICAgICAgIG5ldyBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zW10geworICAgICAgICAgICAgLy8gc2V0IDA6IHZhbGlkIG0KKyAgICAgICAgICAgIG5ldyBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zKDEsIG51bGwsIG51bGwsIG51bGwpLAorICAgICAgICAgICAgLy8gc2V0IDE6IHZhbGlkIG0KKyAgICAgICAgICAgIG5ldyBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zKEludGVnZXIuTUFYX1ZBTFVFLCBudWxsLCBudWxsLCBudWxsKSwKKyAgICAgICAgICAgIC8vIHNldCAyOiBpbnZhbGlkIG0KKyAgICAgICAgICAgIG5ldyBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zKDAsIG51bGwsIG51bGwsIEVDRmllbGRGMm1Eb21haW5QYXJhbXMuSUFyZ0UpLAorICAgICAgICAgICAgLy8gc2V0IDM6IGludmFsaWQgbQorICAgICAgICAgICAgbmV3IEVDRmllbGRGMm1Eb21haW5QYXJhbXMoLTEsIG51bGwsIG51bGwsIEVDRmllbGRGMm1Eb21haW5QYXJhbXMuSUFyZ0UpCisgICAgICAgIH07CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBmb3IgY29uc3RydWN0b3IgPGNvZGU+RUNGaWVsZEYybShpbnQpPC9jb2RlPjxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBuZXcgPGNvZGU+RUNGaWVsZEYybTwvY29kZT4gb2JqZWN0CisgICAgICogdXNpbmcgdmFsaWQgcGFyYW1ldGVyIG0uCisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBtIGlzIG5vdCBwb3NpdGl2ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RUNGaWVsZEYybWludCgpIHsKKyAgICAgICAgZm9yKGludCBpPTA7IGk8aW50Q3RvclRlc3RQYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zIHRwID0gaW50Q3RvclRlc3RQYXJhbWV0ZXJzW2ldOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAvLyBwZXJmb3JtIHRlc3QKKyAgICAgICAgICAgICAgICBuZXcgRUNGaWVsZEYybSh0cC5tKTsKKworICAgICAgICAgICAgICAgIGlmICh0cC54ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gZXhjZXB0aW9uIGhhcyBiZWVuIGV4cGVjdGVkCisgICAgICAgICAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIiwgc2V0ICIgKyBpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIEZBSUxFRDogZXhwZWN0ZWQgZXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSl7CisgICAgICAgICAgICAgICAgaWYgKHRwLnggPT0gbnVsbCB8fCAhZS5nZXRDbGFzcygpLmlzSW5zdGFuY2UodHAueCkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gZXhjZXB0aW9uOiBmYWlsdXJlCisgICAgICAgICAgICAgICAgICAgIC8vIGlmIGl0IGhhcyBub3QgYmVlbiBleHBlY3RlZAorICAgICAgICAgICAgICAgICAgICAvLyBvciB3cm9uZyBvbmUgaGFzIGJlZW4gdGhyb3duCisgICAgICAgICAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsgIiwgc2V0ICIgKyBpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIEZBSUxFRDogdW5leHBlY3RlZCAiICsgZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IG9mIHBhcmFtZXRlcnMgdXNlZCBmb3IgPGNvZGU+RUNGaWVsZEYybShpbnQsIGludFtdIGtzKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciB0ZXN0cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIEVDRmllbGRGMm1Eb21haW5QYXJhbXNbXSBjb25zdHJ1Y3RvclRlc3RQYXJhbWV0ZXJzID0KKyAgICAgICAgbmV3IEVDRmllbGRGMm1Eb21haW5QYXJhbXNbXSB7CisgICAgICAgICAgICAvLyBzZXQgMDogdmFsaWQgbSBhbmQga3MgLSB0cmlub21pYWwgYmFzaXMgcGFyYW1zCisgICAgICAgICAgICBuZXcgRUNGaWVsZEYybURvbWFpblBhcmFtcygKKyAgICAgICAgICAgICAgICAgICAgMTk5OSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjU3NDA2NTM0NzYzNzEyNzI2MjExNjQxNjYwMDU4ODg0MDk5MjAxMTE1ODg1MTA0NDM0NzYwMDIzODgyMTM2ODQxMjg4MzEzMDY5NjE4NTE1NjkyODMyOTc0MzE1ODI1MzEzNDk1OTIyMjk4MjMxOTQ5MzczMTM4NjcyMzU1OTQ4MDQzMTUyNzY2NTcxMjk2NTY3ODA4MzMyNjU5MjY5NTY0OTk0NTcyNjU2MTQwMDAwMzQ0Mzg5NTc0MTIwMDIyNDM1NzE0NDYzNDk1MDMxNzQzMTIyMzkwODA3NzMxODIzMTk0MTgxOTczNjU4NTEzMDIwMjMzMTc2OTg1NDUyNDk4Mjc5MDgxMTk5NDA0NDcyMzE0ODAyODExNjU1ODI0NzY4MDgyMTEwOTg1MTY2MzQwNjcyMDg0NDU0NDkyMjI5MjUyODAxMTg5NzQyNDAzOTU3MDI5NDUwNDY3Mzg4MjUwMjE0NTAxMzU4MzUzMzEyOTE1MjYxMDA0MDY2MTE4MTQwNjQ1ODgwNjMzOTQxNjU4NjAzMjk5NDk3Njk4MjA5MDYzNTEwODg5OTI5MjAyMDIxMDc5OTI2NTkxNjI1NzcwNDQ0NzE2OTUxMDQ1OTYwMjc3NDc4ODkxNzk0ODM2MDE5NTgwMDQwOTc4OTA4OTI4NzQxOTcyNzQwODY1OTYxNzE2NTI0MTUzMjA5NTMyNzEzODAzMzkzNTE0NzIyNTgxMzQyNDc0NTU2OTQzODQwNTE5NjE1MDgxMzAyMTQ4NzYyNDU0NTIwMTMxNDg2NDEzNjYyMTkxNjE3IiksCisgICAgICAgICAgICAgICAgICAgIG5ldyBpbnRbXSB7MzY3fSwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCksCisgICAgICAgICAgICAvLyBzZXQgMTogdmFsaWQgbSBhbmQga3MgLSBwZW50YW5vbWlhbCBiYXNpcyBwYXJhbXMKKyAgICAgICAgICAgIG5ldyBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zKAorICAgICAgICAgICAgICAgICAgICAyMDAwLAorICAgICAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiMTE0ODEzMDY5NTI3NDI1NDUyNDIzMjgzMzIwMTE3NzY4MTk4NDAyMjMxNzcwMjA4ODY5NTIwMDQ3NzY0MjczNjgyNTc2NjI2MTM5MjM3MDMxMzg1NjY1OTQ4NjMxNjUwNjI2OTkxODQ0NTk2NDYzODk4NzQ2Mjc3MzQ0NzExODk2MDg2MzA1NTMzMTQyNTkzMTM1NjE2NjY1MzE4NTM5MTI5OTg5MTQ1MzEyMjgwMDAwNjg4Nzc5MTQ4MjQwMDQ0ODcxNDI4OTI2OTkwMDYzNDg2MjQ0NzgxNjE1NDYzNjQ2Mzg4MzYzOTQ3MzE3MDI2MDQwNDY2MzUzOTcwOTA0OTk2NTU4MTYyMzk4ODA4OTQ0NjI5NjA1NjIzMzExNjQ5NTM2MTY0MjIxOTcwMzMyNjgxMzY0NjA2MzEzNzU0MDk0MDM2NDczNzQwNzQxMzg5NDExMjg1ODE3NDY1NDc3NDA3Mjg4MDg3OTQxNjkyNzA5NTkzMDc5MDU3OTA0OTc0NDczMzI1Mzk5MjM3NDQ5OTYxNzk2MTc4MTUwMjYzMDczODExNTUyOTMxMTU2NjgxODA3MTYxMDAzNTgyMzM3NTEwMDA4NjQ4MzM4NzY1NjY0NjMxODE1ODc0NjA4Nzg5MzY2Njk5NjY4MjI0ODA2OTA3NTcxNTA1NzUwNzk4NjQ3ODU1Nzk3MjIwMDU2Mjg1NDc5ODY5NzY3MjkxMTM3MTUzNzMyNzkwNTk3MzQ4MzA4NDQ2ODg3MjMwNTg0NjM3MjM1NzE2NDQ0OTIwOTA3NTEyODEwNTY5NzM1IiksCisgICAgICAgICAgICAgICAgICAgIG5ldyBpbnRbXSB7OTgxLDIsMX0sCisgICAgICAgICAgICAgICAgICAgIG51bGwpLAorICAgICAgICAgICAgLy8gc2V0IDI6IHZhbGlkIG0sIGludmFsaWQgKG51bGwpIHByLCBpbnZhbGlkIChudWxsKSBrcworICAgICAgICAgICAgbmV3IEVDRmllbGRGMm1Eb21haW5QYXJhbXMoCisgICAgICAgICAgICAgICAgICAgIDE5NjMsCisgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgICAgIEVDRmllbGRGMm1Eb21haW5QYXJhbXMuTlBFKSwKKyAgICAgICAgICAgIC8vIHNldCAzOiB2YWxpZCBtLCBpbnZhbGlkIHByLCBpbnZhbGlkIGtzIC0gd3JvbmcgbGVuZ3RoCisgICAgICAgICAgICBuZXcgRUNGaWVsZEYybURvbWFpblBhcmFtcygKKyAgICAgICAgICAgICAgICAgICAgMTk2MywKKyAgICAgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjExNDgxMzA2OTUyNzQyNTQ1MjQyMzI4MzMyMDExNzc2ODE5ODQwMjIzMTc3MDIwODg2OTUyMDA0Nzc2NDI3MzY4MjU3NjYyNjEzOTIzNzAzMTM4NTY2NTk0ODYzMTY1MDYyNjk5MTg0NDU5NjQ2Mzg5ODc0NjI3NzM0NDcxMTg5NjA4NjMwNTUzMzE0MjU5MzEzNTYxNjY2NTMxODUzOTEyOTk4OTE0NTMxMjI4MDAwMDY4ODc3OTE0ODI0MDA0NDg3MTQyODkyNjk5MDA2MzQ4NjI0NDc4MTYxNTQ2MzY0NjM4ODM2Mzk0NzMxNzAyNjA0MDQ2NjM1Mzk3MDkwNDk5NjU1ODE2MjM5ODgwODk0NDYyOTYwNTYyMzMxMTY0OTUzNjE2NDIyMTk3MDMzMjY4MTM2NDYwNjMxMzc1NDA5NDAzNjQ3Mzc0MDc0MTM4OTQxMTI4NTgxNzQ2NTQ3NzQwNzI4ODA4Nzk0MTY5MjcwOTU5MzA3OTA1NzkwNDk3NDQ3MzMyNTM5OTIzNzQ0OTk2MTc5NjE3ODE1MDI2MzA3MzgxMTU1MjkzMTE1NjY4MTgwNzE2MTAwMzU4MjMzNzUxMDAwODY0ODMzODc2NTY2NDYzMTgxNTg3NDYwODc4OTM2NjY5OTY2ODIyNDgwNjkwNzU3MTUwNTc1MDc5ODY0Nzg1NTc5NzIyMDA1NjI4NTQ3OTg2OTc2NzI5MTEzNzE1MzczMjc5MDU5NzM0ODMwODQ0Njg4NzIzMDU4NDYzNzIzNTcxNjQ0NDkyMDkwNzUxMjgxMDU2OTczNCIpLAorICAgICAgICAgICAgICAgICAgICBuZXcgaW50W10gezk4MSwyfSwKKyAgICAgICAgICAgICAgICAgICAgRUNGaWVsZEYybURvbWFpblBhcmFtcy5JQXJnRSksCisgICAgICAgICAgICAvLyBzZXQgNDogdmFsaWQgbSwgaW52YWxpZCBrcyAtIHdyb25nIGxlbmd0aAorICAgICAgICAgICAgbmV3IEVDRmllbGRGMm1Eb21haW5QYXJhbXMoCisgICAgICAgICAgICAgICAgICAgIDE5NjMsCisgICAgICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCI1IiksCisgICAgICAgICAgICAgICAgICAgIG5ldyBpbnRbXSB7OTgxLDEyNCwyLDF9LAorICAgICAgICAgICAgICAgICAgICBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zLklBcmdFKSwKKyAgICAgICAgICAgIC8vIHNldCA1OiB2YWxpZCBtLCBpbnZhbGlkIGtzIC0gd3JvbmcgdmFsdWUKKyAgICAgICAgICAgIG5ldyBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zKAorICAgICAgICAgICAgICAgICAgICAxOTk5LAorICAgICAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiNSIpLAorICAgICAgICAgICAgICAgICAgICBuZXcgaW50W10gezE5OTl9LAorICAgICAgICAgICAgICAgICAgICBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zLklBcmdFKSwKKyAgICAgICAgICAgIC8vIHNldCA2OiB2YWxpZCBtLCBpbnZhbGlkIGtzIC0gd3JvbmcgdmFsdWUKKyAgICAgICAgICAgIG5ldyBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zKAorICAgICAgICAgICAgICAgICAgICAxOTk5LAorICAgICAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiNSIpLAorICAgICAgICAgICAgICAgICAgICBuZXcgaW50W10gezB9LAorICAgICAgICAgICAgICAgICAgICBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zLklBcmdFKSwKKyAgICAgICAgICAgIC8vIHNldCA3OiB2YWxpZCBtLCBpbnZhbGlkIGtzIC0gd3JvbmcgdmFsdWVzCisgICAgICAgICAgICBuZXcgRUNGaWVsZEYybURvbWFpblBhcmFtcygKKyAgICAgICAgICAgICAgICAgICAgMjAwMCwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjUiKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IGludFtdIHsyMDAwLDIsMX0sCisgICAgICAgICAgICAgICAgICAgIEVDRmllbGRGMm1Eb21haW5QYXJhbXMuSUFyZ0UpLAorICAgICAgICAgICAgLy8gc2V0IDg6IHZhbGlkIG0sIGludmFsaWQga3MgLSB3cm9uZyB2YWx1ZXMKKyAgICAgICAgICAgIG5ldyBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zKAorICAgICAgICAgICAgICAgICAgICAyMDAwLAorICAgICAgICAgICAgICAgICAgICBuZXcgQmlnSW50ZWdlcigiNSIpLAorICAgICAgICAgICAgICAgICAgICBuZXcgaW50W10gezk4MSwyLDB9LAorICAgICAgICAgICAgICAgICAgICBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zLklBcmdFKSwKKyAgICAgICAgICAgIC8vIHNldCA5OiBpbnZhbGlkIG0KKyAgICAgICAgICAgIG5ldyBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zKAorICAgICAgICAgICAgICAgICAgICAtNSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjExNDgxMzA2OTUyNzQyNTQ1MjQyMzI4MzMyMDExNzc2ODE5ODQwMjIzMTc3MDIwODg2OTUyMDA0Nzc2NDI3MzY4MjU3NjYyNjEzOTIzNzAzMTM4NTY2NTk0ODYzMTY1MDYyNjk5MTg0NDU5NjQ2Mzg5ODc0NjI3NzM0NDcxMTg5NjA4NjMwNTUzMzE0MjU5MzEzNTYxNjY2NTMxODUzOTEyOTk4OTE0NTMxMjI4MDAwMDY4ODc3OTE0ODI0MDA0NDg3MTQyODkyNjk5MDA2MzQ4NjI0NDc4MTYxNTQ2MzY0NjM4ODM2Mzk0NzMxNzAyNjA0MDQ2NjM1Mzk3MDkwNDk5NjU1ODE2MjM5ODgwODk0NDYyOTYwNTYyMzMxMTY0OTUzNjE2NDIyMTk3MDMzMjY4MTM2NDYwNjMxMzc1NDA5NDAzNjQ3Mzc0MDc0MTM4OTQxMTI4NTgxNzQ2NTQ3NzQwNzI4ODA4Nzk0MTY5MjcwOTU5MzA3OTA1NzkwNDk3NDQ3MzMyNTM5OTIzNzQ0OTk2MTc5NjE3ODE1MDI2MzA3MzgxMTU1MjkzMTE1NjY4MTgwNzE2MTAwMzU4MjMzNzUxMDAwODY0ODMzODc2NTY2NDYzMTgxNTg3NDYwODc4OTM2NjY5OTY2ODIyNDgwNjkwNzU3MTUwNTc1MDc5ODY0Nzg1NTc5NzIyMDA1NjI4NTQ3OTg2OTc2NzI5MTEzNzE1MzczMjc5MDU5NzM0ODMwODQ0Njg4NzIzMDU4NDYzNzIzNTcxNjQ0NDkyMDkwNzUxMjgxMDU2OTczNSIpLAorICAgICAgICAgICAgICAgICAgICBuZXcgaW50W10gezk4MSwyLDF9LAorICAgICAgICAgICAgICAgICAgICBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zLklBcmdFKSwKKyAgICAgICAgICAgIC8vIHNldCAxMDogdmFsaWQgbSwgaW52YWxpZCBrcyAtIHdyb25nIG9yZGVyCisgICAgICAgICAgICBuZXcgRUNGaWVsZEYybURvbWFpblBhcmFtcygKKyAgICAgICAgICAgICAgICAgICAgMjAwMCwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjUiKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IGludFtdIHs5ODEsMSwyfSwKKyAgICAgICAgICAgICAgICAgICAgRUNGaWVsZEYybURvbWFpblBhcmFtcy5JQXJnRSksCisgICAgICAgICAgICAvLyBzZXQgMTE6IHZhbGlkIG0sIGludmFsaWQga3MgLSBubyBjb250ZW50CisgICAgICAgICAgICBuZXcgRUNGaWVsZEYybURvbWFpblBhcmFtcygKKyAgICAgICAgICAgICAgICAgICAgMjAwMCwKKyAgICAgICAgICAgICAgICAgICAgbmV3IEJpZ0ludGVnZXIoIjUiKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IGludFszXSwKKyAgICAgICAgICAgICAgICAgICAgRUNGaWVsZEYybURvbWFpblBhcmFtcy5JQXJnRSksCisgICAgICAgICAgICAvLyBzZXQgMTI6IHZhbGlkIG0sIGludmFsaWQga3MgLSBsZW5ndGggaXMgMAorICAgICAgICAgICAgbmV3IEVDRmllbGRGMm1Eb21haW5QYXJhbXMoCisgICAgICAgICAgICAgICAgICAgIDIwMDAsCisgICAgICAgICAgICAgICAgICAgIG5ldyBCaWdJbnRlZ2VyKCIwIiksCisgICAgICAgICAgICAgICAgICAgIG5ldyBpbnRbMF0sCisgICAgICAgICAgICAgICAgICAgIEVDRmllbGRGMm1Eb21haW5QYXJhbXMuSUFyZ0UpLAorICAgICAgICB9OworCisgICAgLyoqCisgICAgICogVGVzdHMgZm9yIGNvbnN0cnVjdG9yIDxjb2RlPkVDRmllbGRGMm0oaW50IG0sIGludFtdIGtzKTwvY29kZT48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgbmV3IDxjb2RlPkVDRmllbGRGMm08L2NvZGU+IG9iamVjdAorICAgICAqIHVzaW5nIHZhbGlkIHBhcmFtZXRlcnMgbSBhbmQgcnAuIGtzIHJlcHJlc2VudHMgdHJpbm9taWFsIGJhc2lzLgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIG5ldyA8Y29kZT5FQ0ZpZWxkRjJtPC9jb2RlPiBvYmplY3QKKyAgICAgKiB1c2luZyB2YWxpZCBwYXJhbWV0ZXJzIG0gYW5kIGtzLiBrcyByZXByZXNlbnRzIHBlbnRhbm9taWFsIGJhc2lzLgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgbSBpcyBub3QgcG9zaXRpdmUuCisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGtzIGlzIG51bGwuCisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBrcyBpcyBpbnZhbGlkLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFQ0ZpZWxkRjJtaW50aW50QXJyYXkoKSB7CisgICAgICAgIGZvcihpbnQgaT0wOyBpPGNvbnN0cnVjdG9yVGVzdFBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIEVDRmllbGRGMm1Eb21haW5QYXJhbXMgdHAgPSBjb25zdHJ1Y3RvclRlc3RQYXJhbWV0ZXJzW2ldOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAvLyBwZXJmb3JtIHRlc3QKKyAgICAgICAgICAgICAgICBFQ0ZpZWxkRjJtIHRlc3QgPSBuZXcgRUNGaWVsZEYybSh0cC5tLCB0cC5rcyk7CisKKyAgICAgICAgICAgICAgICBpZiAodHAueCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGV4Y2VwdGlvbiBoYXMgYmVlbiBleHBlY3RlZAorICAgICAgICAgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICIsIHNldCAiICsgaSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBGQUlMRUQ6IGV4cGVjdGVkIGV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpeworICAgICAgICAgICAgICAgIGlmICh0cC54ID09IG51bGwgfHwgIWUuZ2V0Q2xhc3MoKS5pc0luc3RhbmNlKHRwLngpKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGV4Y2VwdGlvbjogZmFpbHVyZQorICAgICAgICAgICAgICAgICAgICAvLyBpZiBpdCBoYXMgbm90IGJlZW4gZXhwZWN0ZWQKKyAgICAgICAgICAgICAgICAgICAgLy8gb3Igd3Jvbmcgb25lIGhhcyBiZWVuIHRocm93bgorICAgICAgICAgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArICIsIHNldCAiICsgaSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBGQUlMRUQ6IHVuZXhwZWN0ZWQgIiArIGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIGZvciBjb25zdHJ1Y3RvciA8Y29kZT5FQ0ZpZWxkRjJtKGludCBtLCBCaWdJbnRlZ2VyIHJwKTwvY29kZT48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgbmV3IDxjb2RlPkVDRmllbGRGMm08L2NvZGU+IG9iamVjdAorICAgICAqIHVzaW5nIHZhbGlkIHBhcmFtZXRlcnMgbSBhbmQgcnAuCisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgbmV3IDxjb2RlPkVDRmllbGRGMm08L2NvZGU+IG9iamVjdAorICAgICAqIHVzaW5nIHZhbGlkIHBhcmFtZXRlcnMgbSBhbmQgcnAuCisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBtIGlzIG5vdCBwb3NpdGl2ZS4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgcnAgaXMgbnVsbC4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHJwIGlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVDRmllbGRGMm1pbnRCaWdJbnRlZ2VyKCkgeworICAgICAgICBmb3IoaW50IGk9MDsgaTxjb25zdHJ1Y3RvclRlc3RQYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBFQ0ZpZWxkRjJtRG9tYWluUGFyYW1zIHRwID0gY29uc3RydWN0b3JUZXN0UGFyYW1ldGVyc1tpXTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgLy8gcGVyZm9ybSB0ZXN0CisgICAgICAgICAgICAgICAgbmV3IEVDRmllbGRGMm0odHAubSwgdHAucnApOworCisgICAgICAgICAgICAgICAgaWYgKHRwLnggIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAvLyBleGNlcHRpb24gaGFzIGJlZW4gZXhwZWN0ZWQKKyAgICAgICAgICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiLCBzZXQgIiArIGkgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgRkFJTEVEOiBleHBlY3RlZCBleGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKXsKKyAgICAgICAgICAgICAgICBpZiAodHAueCA9PSBudWxsIHx8ICFlLmdldENsYXNzKCkuaXNJbnN0YW5jZSh0cC54KSkgeworICAgICAgICAgICAgICAgICAgICAvLyBleGNlcHRpb246IGZhaWx1cmUKKyAgICAgICAgICAgICAgICAgICAgLy8gaWYgaXQgaGFzIG5vdCBiZWVuIGV4cGVjdGVkCisgICAgICAgICAgICAgICAgICAgIC8vIG9yIHdyb25nIG9uZSBoYXMgYmVlbiB0aHJvd24KKyAgICAgICAgICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKyAiLCBzZXQgIiArIGkgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgRkFJTEVEOiB1bmV4cGVjdGVkICIgKyBlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5oYXNoQ29kZSgpPC9jb2RlPiBtZXRob2QuPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBtdXN0IHJldHVybiB0aGUgc2FtZSB2YWx1ZSBpZiBpbnZva2VkCisgICAgICogcmVwZWF0ZWRseSBvbiB0aGUgc2FtZSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEhhc2hDb2RlMDEoKSB7CisgICAgICAgIEVDRmllbGRGMm0gZiA9IG5ldyBFQ0ZpZWxkRjJtKDIwMDApOworICAgICAgICBpbnQgaGMgPSBmLmhhc2hDb2RlKCk7CisgICAgICAgIGFzc2VydFRydWUoaGMgPT0gZi5oYXNoQ29kZSgpICYmCisgICAgICAgICAgICAgICAgICAgaGMgPT0gZi5oYXNoQ29kZSgpICYmCisgICAgICAgICAgICAgICAgICAgaGMgPT0gZi5oYXNoQ29kZSgpICYmCisgICAgICAgICAgICAgICAgICAgaGMgPT0gZi5oYXNoQ29kZSgpICYmCisgICAgICAgICAgICAgICAgICAgaGMgPT0gZi5oYXNoQ29kZSgpICYmCisgICAgICAgICAgICAgICAgICAgaGMgPT0gZi5oYXNoQ29kZSgpICYmCisgICAgICAgICAgICAgICAgICAgaGMgPT0gZi5oYXNoQ29kZSgpICYmCisgICAgICAgICAgICAgICAgICAgaGMgPT0gZi5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5oYXNoQ29kZSgpPC9jb2RlPiBtZXRob2QuPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBtdXN0IHJldHVybiB0aGUgc2FtZSB2YWx1ZSBpZiBpbnZva2VkCisgICAgICogcmVwZWF0ZWRseSBvbiB0aGUgc2FtZSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEhhc2hDb2RlMDIoKSB7CisgICAgICAgIEVDRmllbGRGMm0gZiA9IG5ldyBFQ0ZpZWxkRjJtKDIwMDAsIG5ldyBpbnRbXSB7OTgxLCAyLCAxfSk7CisgICAgICAgIGludCBoYyA9IGYuaGFzaENvZGUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShoYyA9PSBmLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBmLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBmLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBmLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBmLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBmLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBmLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBmLmhhc2hDb2RlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzMgZm9yIDxjb2RlPmhhc2hDb2RlKCk8L2NvZGU+IG1ldGhvZC48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IG11c3QgcmV0dXJuIHRoZSBzYW1lIHZhbHVlIGlmIGludm9rZWQKKyAgICAgKiBvbiBlcXVhbCAoYWNjb3JkaW5nIHRvIHRoZSA8Y29kZT5lcXVhbHMoT2JqZWN0KTwvY29kZT4gbWV0aG9kKSBvYmplY3RzLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RIYXNoQ29kZTAzKCkgeworICAgICAgICBhc3NlcnRUcnVlKG5ldyBFQ0ZpZWxkRjJtKDExMSkuaGFzaENvZGUoKSA9PQorICAgICAgICAgICAgICAgICAgIG5ldyBFQ0ZpZWxkRjJtKDExMSkuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjNCBmb3IgPGNvZGU+aGFzaENvZGUoKTwvY29kZT4gbWV0aG9kLjxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogbXVzdCByZXR1cm4gdGhlIHNhbWUgdmFsdWUgaWYgaW52b2tlZAorICAgICAqIG9uIGVxdWFsIChhY2NvcmRpbmcgdG8gdGhlIDxjb2RlPmVxdWFscyhPYmplY3QpPC9jb2RlPiBtZXRob2QpIG9iamVjdHMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEhhc2hDb2RlMDQoKSB7CisgICAgICAgIGFzc2VydFRydWUobmV3IEVDRmllbGRGMm0oMjAwMCwgbmV3IGludFtdIHs5ODEsIDIsIDF9KS5oYXNoQ29kZSgpID09CisgICAgICAgICAgICAgICAgICAgbmV3IEVDRmllbGRGMm0oMjAwMCwgbmV3IGludFtdIHs5ODEsIDIsIDF9KS5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM1IGZvciA8Y29kZT5oYXNoQ29kZSgpPC9jb2RlPiBtZXRob2QuPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBtdXN0IHJldHVybiB0aGUgc2FtZSB2YWx1ZSBpZiBpbnZva2VkCisgICAgICogb24gZXF1YWwgKGFjY29yZGluZyB0byB0aGUgPGNvZGU+ZXF1YWxzKE9iamVjdCk8L2NvZGU+IG1ldGhvZCkgb2JqZWN0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0SGFzaENvZGUwNSgpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuZXcgRUNGaWVsZEYybSgyMDAwLCBuZXcgaW50W10gezk4MSwgMiwgMX0pLmhhc2hDb2RlKCkgPT0KKyAgICAgICAgICAgICAgICAgICBuZXcgRUNGaWVsZEYybSgyMDAwLCBCaWdJbnRlZ2VyLnZhbHVlT2YoMEwpLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldEJpdCgwKS5zZXRCaXQoMSkuc2V0Qml0KDIpLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldEJpdCg5ODEpLnNldEJpdCgyMDAwKSkuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+ZXF1YWxzKCk8L2NvZGU+IG1ldGhvZC48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IG9iamVjdCBlcXVhbHMgdG8gaXRzZWxmLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFcXVhbHNPYmplY3QwMSgpIHsKKyAgICAgICAgRUNGaWVsZEYybSBvYmogPSBuZXcgRUNGaWVsZEYybSgxOTk5LCBuZXcgaW50W10gezM2N30pOworICAgICAgICBhc3NlcnRUcnVlKG9iai5lcXVhbHMob2JqKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+ZXF1YWxzKCk8L2NvZGU+IG1ldGhvZC48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IG5vcm1hbCBiYXNpcyAtIG9iamVjdHMgZXF1YWwgaWYgdGhlaXIgbSBhcmUgZXF1YWwuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVxdWFsc09iamVjdDAyKCkgeworICAgICAgICBhc3NlcnRUcnVlKG5ldyBFQ0ZpZWxkRjJtKDQzKS5lcXVhbHMobmV3IEVDRmllbGRGMm0oNDMpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMyBmb3IgPGNvZGU+ZXF1YWxzKCk8L2NvZGU+IG1ldGhvZC48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHRyaW5vbWlhbCBiYXNpcyAtIG9iamVjdHMgZXF1YWwgaWYgdGhlaXIgbSwgYW5kIHJwCisgICAgICogYXJlIG11dHVhbGx5IGVxdWFsLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFcXVhbHNPYmplY3QwMygpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuZXcgRUNGaWVsZEYybSgxOTk5LCBuZXcgaW50W10gezM2N30pLmVxdWFscygKKyAgICAgICAgICAgICAgICAgICBuZXcgRUNGaWVsZEYybSgxOTk5LCBCaWdJbnRlZ2VyLnZhbHVlT2YoMEwpLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldEJpdCgwKS5zZXRCaXQoMzY3KS5zZXRCaXQoMTk5OSkpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjNCBmb3IgPGNvZGU+ZXF1YWxzKCk8L2NvZGU+IG1ldGhvZC48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHBlbnRhbm9taWFsIGJhc2lzIC0gb2JqZWN0cyBlcXVhbCBpZiB0aGVpciBtLCBhbmQgcnAKKyAgICAgKiBhcmUgbXV0dWFsbHkgZXF1YWwuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVxdWFsc09iamVjdDA0KCkgeworICAgICAgICBFQ0ZpZWxkRjJtIGYxID0gbmV3IEVDRmllbGRGMm0oMjAwMCwgbmV3IGludFtdIHs5ODEsIDIsIDF9KTsKKyAgICAgICAgRUNGaWVsZEYybSBmMiA9IG5ldyBFQ0ZpZWxkRjJtKDIwMDAsIEJpZ0ludGVnZXIudmFsdWVPZigwTCkuCisgICAgICAgICAgICAgICAgc2V0Qml0KDApLnNldEJpdCgxKS5zZXRCaXQoMikuCisgICAgICAgICAgICAgICAgc2V0Qml0KDk4MSkuc2V0Qml0KDIwMDApKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShmMS5lcXVhbHMoZjIpICYmIGYyLmVxdWFscyhmMSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzUgZm9yIDxjb2RlPmVxdWFscygpPC9jb2RlPiBtZXRob2QuPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBvYmplY3RzIGVxdWFsIGlmIHRoZWlyIG0sIGFuZCBycCBhcmUgbXV0dWFsbHkgZXF1YWwuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVxdWFsc09iamVjdDA1KCkgeworICAgICAgICBFQ0ZpZWxkRjJtIGYxID0gbmV3IEVDRmllbGRGMm0oMjAwMCk7CisgICAgICAgIEVDRmllbGRGMm0gZjIgPSBuZXcgRUNGaWVsZEYybSgyMDAwLCBCaWdJbnRlZ2VyLnZhbHVlT2YoMEwpLgorICAgICAgICAgICAgICAgIHNldEJpdCgwKS5zZXRCaXQoMSkuc2V0Qml0KDIpLgorICAgICAgICAgICAgICAgIHNldEJpdCg5ODEpLnNldEJpdCgyMDAwKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGYxLmVxdWFscyhmMikgfHwgZjIuZXF1YWxzKGYxKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjNiBmb3IgPGNvZGU+ZXF1YWxzKE9iamVjdCBvYmopPC9jb2RlPiBtZXRob2QuPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIGZhbHNlIGlmIG9iaiBpcyA8Y29kZT5udWxsPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFcXVhbHNPYmplY3QwNigpIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobmV3IEVDRmllbGRGMm0oMjAwMCkuZXF1YWxzKG51bGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM3IGZvciA8Y29kZT5lcXVhbHMoT2JqZWN0IG9iaik8L2NvZGU+IG1ldGhvZC48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgZmFsc2UgaWYgb2JqIGlzIG5vdCBpbnN0YW5jZSBvZiA8Y29kZT5FQ0ZpZWxkRjJtPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFcXVhbHNPYmplY3QwNygpIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobmV3IEVDRmllbGRGMm0oMjAwMCkuZXF1YWxzKG5ldyBPYmplY3QoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEZpZWxkU2l6ZSgpPC9jb2RlPiBtZXRob2QuPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIG0gdmFsdWUgZm9yIDxjb2RlPkVDRmllbGRGMm08L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEZpZWxkU2l6ZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIwMDAsIG5ldyBFQ0ZpZWxkRjJtKDIwMDApLmdldEZpZWxkU2l6ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRNKCk8L2NvZGU+IG1ldGhvZC48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgbSB2YWx1ZSBmb3IgPGNvZGU+RUNGaWVsZEYybTwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0TSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIwMDAsIG5ldyBFQ0ZpZWxkRjJtKDIwMDApLmdldE0oKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+Z2V0TWlkVGVybXNPZlJlZHVjdGlvblBvbHlub21pYWwoKTwvY29kZT4gbWV0aG9kLjxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBtaWQgdGVybXMgb2YgcmVkdWN0aW9uIHBvbHlub21pYWwKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0TWlkVGVybXNPZlJlZHVjdGlvblBvbHlub21pYWwwMSgpIHsKKyAgICAgICAgaW50W10gYSA9IG5ldyBpbnRbXSB7OTgxLDIsMX07CisgICAgICAgIGludFtdIGIgPSBuZXcgRUNGaWVsZEYybSgyMDAwLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZigwTCkuc2V0Qml0KDApLnNldEJpdCgxKS4KKyAgICAgICAgICAgICAgICBzZXRCaXQoMikuc2V0Qml0KDk4MSkuc2V0Qml0KDIwMDApKS4KKyAgICAgICAgICAgICAgICBnZXRNaWRUZXJtc09mUmVkdWN0aW9uUG9seW5vbWlhbCgpOworICAgICAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoYSwgYikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPmdldE1pZFRlcm1zT2ZSZWR1Y3Rpb25Qb2x5bm9taWFsKCk8L2NvZGU+IG1ldGhvZC48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgbnVsbCBmb3Igbm9ybWFsIGJhc2lzCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldE1pZFRlcm1zT2ZSZWR1Y3Rpb25Qb2x5bm9taWFsMDIoKSB7CisgICAgICAgIGFzc2VydE51bGwobmV3IEVDRmllbGRGMm0oMjAwMCkuZ2V0TWlkVGVybXNPZlJlZHVjdGlvblBvbHlub21pYWwoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMyBmb3IgPGNvZGU+Z2V0TWlkVGVybXNPZlJlZHVjdGlvblBvbHlub21pYWwoKTwvY29kZT4gbWV0aG9kLjxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBtaWQgdGVybXMgb2YgcmVkdWN0aW9uIHBvbHlub21pYWwKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0TWlkVGVybXNPZlJlZHVjdGlvblBvbHlub21pYWwwMygpIHsKKyAgICAgICAgaW50W10gYSA9IG5ldyBpbnRbXSB7MzY3fTsKKyAgICAgICAgaW50W10gYiA9IG5ldyBFQ0ZpZWxkRjJtKDE5OTksIGEpLmdldE1pZFRlcm1zT2ZSZWR1Y3Rpb25Qb2x5bm9taWFsKCk7CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhhLCBiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+Z2V0UmVkdWN0aW9uUG9seW5vbWlhbCgpPC9jb2RlPiBtZXRob2QuPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHJlZHVjdGlvbiBwb2x5bm9taWFsCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFJlZHVjdGlvblBvbHlub21pYWwwMSgpIHsKKyAgICAgICAgQmlnSW50ZWdlciBycCA9IEJpZ0ludGVnZXIudmFsdWVPZigwTCkuc2V0Qml0KDApLnNldEJpdCgxKS5zZXRCaXQoMikuCisgICAgICAgIHNldEJpdCg5ODEpLnNldEJpdCgyMDAwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuZXcgRUNGaWVsZEYybSgyMDAwLCBycCkuZ2V0UmVkdWN0aW9uUG9seW5vbWlhbCgpLmVxdWFscyhycCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPmdldFJlZHVjdGlvblBvbHlub21pYWwoKTwvY29kZT4gbWV0aG9kLjxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBudWxsIGZvciBub3JtYWwgYmFzaXMKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0UmVkdWN0aW9uUG9seW5vbWlhbDAyKCkgeworICAgICAgICBhc3NlcnROdWxsKG5ldyBFQ0ZpZWxkRjJtKDIwMDApLmdldFJlZHVjdGlvblBvbHlub21pYWwoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgdGhhdCBvYmplY3Qgc3RhdGUgaXMgcHJlc2VydmVkIGFnYWluc3QgbW9kaWZpY2F0aW9ucworICAgICAqIHRocm91Z2ggYXJyYXkgcmVmZXJlbmNlIHBhc3NlZCB0byB0aGUgY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdElzU3RhdGVQcmVzZXJ2ZWQwMSgpIHsKKyAgICAgICAgLy8gcmVmZXJlbmNlIGFycmF5CisgICAgICAgIGludFtdIGEgPSBuZXcgaW50W10gezM2N307CisgICAgICAgIC8vIHJlZmVyZW5jZSBhcnJheSBjb3B5CisgICAgICAgIGludFtdIGFDb3B5ID0gYS5jbG9uZSgpOworICAgICAgICAvLyBjcmVhdGUgb2JqIHVzaW5nIGNvcHkKKyAgICAgICAgRUNGaWVsZEYybSBmID0gbmV3IEVDRmllbGRGMm0oMTk5OSwgYUNvcHkpOworICAgICAgICAvLyBtb2RpZnkgY29weQorICAgICAgICBhQ29weVswXSA9IDU7CisgICAgICAgIC8vIGNvbXBhcmUgcmVmZXJlbmNlIHdpdGggcmV0dXJuZWQgYXJyYXkKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGEsIGYuZ2V0TWlkVGVybXNPZlJlZHVjdGlvblBvbHlub21pYWwoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHRoYXQgb2JqZWN0IHN0YXRlIGlzIHByZXNlcnZlZCBhZ2FpbnN0CisgICAgICogbW9kaWZpY2F0aW9ucyB0aHJvdWdoIGFycmF5IHJlZmVyZW5jZSByZXR1cm5lZCBieQorICAgICAqIDxjb2RlPmdldE1pZFRlcm1zT2ZSZWR1Y3Rpb25Qb2x5bm9taWFsKCk8L2NvZGU+IG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0SXNTdGF0ZVByZXNlcnZlZDAyKCkgeworICAgICAgICAvLyByZWZlcmVuY2UgYXJyYXkKKyAgICAgICAgaW50W10gYSA9IG5ldyBpbnRbXSB7OTgxLDIsMX07CisgICAgICAgIC8vIHJlZmVyZW5jZSBhcnJheSBjb3B5CisgICAgICAgIGludFtdIGFDb3B5ID0gYS5jbG9uZSgpOworICAgICAgICAvLyBjcmVhdGUgb2JqIHVzaW5nIGNvcHkKKyAgICAgICAgRUNGaWVsZEYybSBmID0gbmV3IEVDRmllbGRGMm0oMjAwMCwgYUNvcHkpOworICAgICAgICAvLyBnZXQgYXJyYXkgcmVmZXJlbmNlIGFuZCBtb2RpZnkgcmV0dXJuZWQgYXJyYXkKKyAgICAgICAgZi5nZXRNaWRUZXJtc09mUmVkdWN0aW9uUG9seW5vbWlhbCgpWzBdID0gMTUzMjsKKyAgICAgICAgLy8gY29tcGFyZSByZWZlcmVuY2Ugd2l0aCByZXR1cm5lZCBmb3IgdGhlIHNlY29uZCB0aW1lIGFycmF5CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhhLCBmLmdldE1pZFRlcm1zT2ZSZWR1Y3Rpb25Qb2x5bm9taWFsKCkpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0VDRmllbGRGcFRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0VDRmllbGRGcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MzhlYWQwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvRUNGaWVsZEZwVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTkwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LnNwZWM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRUNGaWVsZEZwOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5FQ0ZpZWxkRnA8L2NvZGU+IGNsYXNzIGZpZWxkcyBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBFQ0ZpZWxkRnBUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLy8KKyAgICAvLyBUZXN0cworICAgIC8vCisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5FQ0ZpZWxkRnA8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IGNyZWF0ZXMgbmV3IG9iamVjdCBvZiA8Y29kZT5FQ0ZpZWxkRnA8L2NvZGU+IGNsYXNzCisgICAgICogdXNpbmcgdmFsaWQgPGNvZGU+cDwvY29kZT4gKG9kZCBwcmltZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RUNGaWVsZEZwMDEoKSB7CisgICAgICAgIG5ldyBFQ0ZpZWxkRnAoQmlnSW50ZWdlci52YWx1ZU9mKDIzTCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPkVDRmllbGRGcDwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogY3JlYXRlcyBuZXcgb2JqZWN0IG9mIDxjb2RlPkVDRmllbGRGcDwvY29kZT4gY2xhc3MKKyAgICAgKiB1c2luZyB2YWxpZCA8Y29kZT5wPC9jb2RlPiAob2RkIGJ1dCBub3QgcHJpbWUpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVDRmllbGRGcDAyKCkgeworICAgICAgICBuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigyMUwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMzIGZvciA8Y29kZT5FQ0ZpZWxkRnA8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiA8Y29kZT5wPC9jb2RlPiBpcyBub3QgcG9zaXRpdmUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RUNGaWVsZEZwMDMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigtMUwpKTsKKyAgICAgICAgICAgIGZhaWwoZ2V0TmFtZSgpICsKKyAgICAgICAgICAgICAgICAgICAgIiBGQUlMRUQ6IGV4cGVjdGVkIGV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM0IGZvciA8Y29kZT5FQ0ZpZWxkRnA8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiA8Y29kZT5wPC9jb2RlPiBpcyBub3QgcG9zaXRpdmUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RUNGaWVsZEZwMDQoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigwTCkpOworICAgICAgICAgICAgZmFpbChnZXROYW1lKCkgKworICAgICAgICAgICAgICAgICAgICAiIEZBSUxFRDogZXhwZWN0ZWQgZXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzQgZm9yIDxjb2RlPkVDRmllbGRGcDwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+cDwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFQ0ZpZWxkRnAwNSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFQ0ZpZWxkRnAobnVsbCk7CisgICAgICAgICAgICBmYWlsKGdldE5hbWUoKSArCisgICAgICAgICAgICAgICAgICAgICIgRkFJTEVEOiBleHBlY3RlZCBleGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5oYXNoQ29kZSgpPC9jb2RlPiBtZXRob2QuPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBtdXN0IHJldHVybiB0aGUgc2FtZSB2YWx1ZSBpZiBpbnZva2VkCisgICAgICogcmVwZWF0ZWRseSBvbiB0aGUgc2FtZSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEhhc2hDb2RlMDEoKSB7CisgICAgICAgIEVDRmllbGRGcCBmID0gbmV3IEVDRmllbGRGcChCaWdJbnRlZ2VyLnZhbHVlT2YoMjNMKSk7CisgICAgICAgIGludCBoYyA9IGYuaGFzaENvZGUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShoYyA9PSBmLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBmLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBmLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBmLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBmLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBmLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBmLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBmLmhhc2hDb2RlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPmhhc2hDb2RlKCk8L2NvZGU+IG1ldGhvZC48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IG11c3QgcmV0dXJuIHRoZSBzYW1lIHZhbHVlIGlmIGludm9rZWQKKyAgICAgKiBvbiBlcXVhbCAoYWNjb3JkaW5nIHRvIHRoZSA8Y29kZT5lcXVhbHMoT2JqZWN0KTwvY29kZT4gbWV0aG9kKSBvYmplY3RzLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RIYXNoQ29kZTAyKCkgeworICAgICAgICBhc3NlcnRUcnVlKG5ldyBFQ0ZpZWxkRnAoQmlnSW50ZWdlci52YWx1ZU9mKDIzTCkpLmhhc2hDb2RlKCkgPT0KKyAgICAgICAgICAgICAgICAgICBuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigyM0wpKS5oYXNoQ29kZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRGaWVsZFNpemUoKSgpPC9jb2RlPiBtZXRob2QuPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIGZpZWxkIHNpemUgaW4gYml0cyB3aGljaCBpcyBwcmltZSBzaXplCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEZpZWxkU2l6ZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUsIG5ldyBFQ0ZpZWxkRnAoQmlnSW50ZWdlci52YWx1ZU9mKDIzTCkpLmdldEZpZWxkU2l6ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRQKCk8L2NvZGU+IG1ldGhvZC48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgcHJpbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0UCgpIHsKKyAgICAgICAgQmlnSW50ZWdlciBwID0gQmlnSW50ZWdlci52YWx1ZU9mKDIzTCk7CisgICAgICAgIGFzc2VydFRydWUocC5lcXVhbHMobmV3IEVDRmllbGRGcChwKS5nZXRQKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5lcXVhbHMoKTwvY29kZT4gbWV0aG9kLjxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogb2JqZWN0IGVxdWFscyB0byBpdHNlbGYuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVxdWFsc09iamVjdDAxKCkgeworICAgICAgICBFQ0ZpZWxkRnAgb2JqID0gbmV3IEVDRmllbGRGcChCaWdJbnRlZ2VyLnZhbHVlT2YoMjNMKSk7CisgICAgICAgIGFzc2VydFRydWUob2JqLmVxdWFscyhvYmopKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5lcXVhbHMoT2JqZWN0IG9iaik8L2NvZGU+IG1ldGhvZC48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgZmFsc2UgaWYgPGNvZGU+b2JqPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFcXVhbHNPYmplY3QwMigpIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UobmV3IEVDRmllbGRGcChCaWdJbnRlZ2VyLnZhbHVlT2YoMjNMKSkuZXF1YWxzKG51bGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMzIGZvciA8Y29kZT5lcXVhbHMoT2JqZWN0IG9iaik8L2NvZGU+IG1ldGhvZC48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgZmFsc2UgaWYgPGNvZGU+b2JqPC9jb2RlPgorICAgICAqIGlzIG5vdCBpbnN0YW5jZSBvZiA8Y29kZT5FQ0ZpZWxkRnA8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVxdWFsc09iamVjdDAzKCkgeworICAgICAgICBhc3NlcnRGYWxzZShuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigyM0wpKS5lcXVhbHMobmV3IE9iamVjdCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjNCBmb3IgPGNvZGU+ZXF1YWxzKCk8L2NvZGU+IG1ldGhvZC48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IHRydWUgaWYgcHJpbWUgdmFsdWVzIG1hdGNoLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFcXVhbHNPYmplY3QwNCgpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigyM0wpKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgICAgbmV3IEVDRmllbGRGcChCaWdJbnRlZ2VyLnZhbHVlT2YoMjNMKSkpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0VDR2VuUGFyYW1ldGVyU3BlY1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0VDR2VuUGFyYW1ldGVyU3BlY1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mM2EzOTEzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvRUNHZW5QYXJhbWV0ZXJTcGVjVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FQ0dlblBhcmFtZXRlclNwZWM7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkVDR2VuUGFyYW1ldGVyU3BlYzwvY29kZT4gY2xhc3MgZmllbGRzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIEVDR2VuUGFyYW1ldGVyU3BlY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvLworICAgIC8vIFRlc3RzCisgICAgLy8KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPkVDR2VuUGFyYW1ldGVyU3BlYzwvY29kZT4gY29uc3RydWN0b3I8YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IGNyZWF0ZXMgbmV3IG9iamVjdCBvZiA8Y29kZT5FQ0dlblBhcmFtZXRlclNwZWM8L2NvZGU+IGNsYXNzCisgICAgICogdXNpbmcgdmFsaWQgPGNvZGU+bmFtZTwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RUNHZW5QYXJhbWV0ZXJTcGVjMDEoKSB7CisgICAgICAgIG5ldyBFQ0dlblBhcmFtZXRlclNwZWMoInNvbWVOYW1lIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+RUNHZW5QYXJhbWV0ZXJTcGVjPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCisgICAgICogaWYgPGNvZGU+bmFtZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RUNHZW5QYXJhbWV0ZXJTcGVjMDIoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRUNHZW5QYXJhbWV0ZXJTcGVjKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTlBFIGV4cGVjdGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG9rKSB7fQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldE5hbWUoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHRoZSA8Y29kZT5uYW1lPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXROYW1lKCkgeworICAgICAgICBTdHJpbmcgbmFtZSA9ICJzb21lTmFtZSI7CisgICAgICAgIEVDR2VuUGFyYW1ldGVyU3BlYyBwcyA9IG5ldyBFQ0dlblBhcmFtZXRlclNwZWMobmFtZSk7CisgICAgICAgIGFzc2VydEVxdWFscyhuYW1lLCBwcy5nZXROYW1lKCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvRUNQYXJhbWV0ZXJTcGVjVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvRUNQYXJhbWV0ZXJTcGVjVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNiMWM2NmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9FQ1BhcmFtZXRlclNwZWNUZXN0LmphdmEKQEAgLTAsMCArMSwxNDAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FQ0ZpZWxkRjJtOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FQ1BhcmFtZXRlclNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkVDUG9pbnQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkVsbGlwdGljQ3VydmU7CisKK3B1YmxpYyBjbGFzcyBFQ1BhcmFtZXRlclNwZWNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgRWxsaXB0aWNDdXJ2ZSBjdXJ2ZTsKKworICAgIEVDUG9pbnQgZWNwb2ludDsKKworICAgIEVDUGFyYW1ldGVyU3BlYyBlY3BzOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgY3VydmUgPSBuZXcgRWxsaXB0aWNDdXJ2ZShuZXcgRUNGaWVsZEYybSgyKSwgQmlnSW50ZWdlci52YWx1ZU9mKDEpLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZigxKSk7CisgICAgICAgIGVjcG9pbnQgPSBuZXcgRUNQb2ludChCaWdJbnRlZ2VyLnZhbHVlT2YoMSksIEJpZ0ludGVnZXIudmFsdWVPZigxKSk7CisgICAgICAgIGVjcHMgPSBuZXcgRUNQYXJhbWV0ZXJTcGVjKGN1cnZlLCBlY3BvaW50LCBCaWdJbnRlZ2VyLnZhbHVlT2YoMSksIDEpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGN1cnZlID0gbnVsbDsKKyAgICAgICAgZWNwb2ludCA9IG51bGw7CisgICAgICAgIGVjcHMgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHRlc3QgZm9yIEVDUGFyYW1ldGVyU3BlYyhFbGxpcHRpY0N1cnZlLCBFQ1BvaW50LCBCaWdJbnRlZ2VyLCBpbnQpIGNvbnN0cnVjdG9yCisgICAgICogdGVzdCBjb3ZlcnMgZm9sbG93aW5nIHVzZWNhc2VzOgorICAgICAqIGNhc2UgMTogY3JlYXRpbmcgb2JqZWN0IHdpdGggdmFsaWQgcGFyYW1ldGVycworICAgICAqIGNhc2UgMjogTnVsbFBvaW50ZXJFeGNlcHRpb24gLSBpZiBjdXJ2ZSBpcyBudWxsCisgICAgICogY2FzZSAzOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiAtIGlmIGcgaXMgbnVsbAorICAgICAqIGNhc2UgNDogTnVsbFBvaW50ZXJFeGNlcHRpb24gLSBpZiBuIGlzIG51bGwKKyAgICAgKiBjYXNlIDU6IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAtIGlmIG4gaXMgbm90IHBvc2l0aXZlCisgICAgICogY2FzZSA2OiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gLSBpZiBoIGlzIG5vdCBwb3NpdGl2ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfY29uc3RydWN0b3JMamF2YV9zZWN1cml0eV9zcGVjX0VsbGlwdGljQ3VydmVMamF2YV9zZWN1cml0eV9zcGVjX0VDUG9pbnRMamF2YV9tYXRoX0JpZ0ludGVnZXJJKCkgeworCisgICAgICAgIC8vIGNhc2UgMTogY3JlYXRpbmcgb2JqZWN0IHdpdGggdmFsaWQgcGFyYW1ldGVycworICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIGNvZmFjdG9yIHdhcyByZXR1cm5lZCIsIDEsIGVjcHMuZ2V0Q29mYWN0b3IoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygid3JvbmcgZWxsaXB0aWMgY3VydmUiLCBjdXJ2ZSwgZWNwcy5nZXRDdXJ2ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ3cm9uZyBnZW5lcmF0b3Igd2FzIHJldHVybmVkIiwgZWNwb2ludCwgZWNwcworICAgICAgICAgICAgICAgIC5nZXRHZW5lcmF0b3IoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygid3Jvbmcgb3JkZXIgd2FzIHJldGV1cm5lZCIsIEJpZ0ludGVnZXIudmFsdWVPZigxKSwgZWNwcworICAgICAgICAgICAgICAgIC5nZXRPcmRlcigpKTsKKworICAgICAgICAvLyBjYXNlIDI6IE51bGxQb2ludGVyRXhjZXB0aW9uIC0gaWYgY3VydmUgaXMgbnVsbC4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFQ1BhcmFtZXRlclNwZWMobnVsbCwgZWNwb2ludCwgQmlnSW50ZWdlci52YWx1ZU9mKDEpLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBjYXNlIDM6IE51bGxQb2ludGVyRXhjZXB0aW9uIC0gaWYgZyBpcyBudWxsLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEVDUGFyYW1ldGVyU3BlYyhjdXJ2ZSwgbnVsbCwgQmlnSW50ZWdlci52YWx1ZU9mKDEpLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBjYXNlIDQ6IE51bGxQb2ludGVyRXhjZXB0aW9uIC0gaWYgbiBpcyBudWxsLgorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEVDUGFyYW1ldGVyU3BlYyhjdXJ2ZSwgZWNwb2ludCwgbnVsbCwgMSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBleGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gY2FzZSA1OiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gLSBpZiBuIGlzIG5vdCBwb3NpdGl2ZS4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFQ1BhcmFtZXRlclNwZWMoY3VydmUsIGVjcG9pbnQsIEJpZ0ludGVnZXIudmFsdWVPZigtMSksIDEpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgLy8gY2FzZSA2OiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gLSBpZiBoIGlzIG5vdCBwb3NpdGl2ZS4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFQ1BhcmFtZXRlclNwZWMoY3VydmUsIGVjcG9pbnQsIEJpZ0ludGVnZXIudmFsdWVPZigxKSwgLTEpOworICAgICAgICAgICAgZmFpbCgiSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogdGVzdCBmb3IgZ2V0Q3VydmUoKSBtZXRob2QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0dldEN1cnZlKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIGVsbGlwdGljIGN1cnZlIiwgY3VydmUsIGVjcHMuZ2V0Q3VydmUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogdGVzdCBmb3IgZ2V0R2VuZXJhdG9yKCkgbWV0aG9kCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9HZXRHZW5lcmF0b3IoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygid3JvbmcgZ2VuZXJhdG9yIHdhcyByZXR1cm5lZCIsIGVjcG9pbnQsIGVjcHMKKyAgICAgICAgICAgICAgICAuZ2V0R2VuZXJhdG9yKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHRlc3QgZm9yIGdldE9yZGVyKCkgbWV0aG9kCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9HZXRPcmRlcigpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ3cm9uZyBvcmRlciB3YXMgcmV0ZXVybmVkIiwgQmlnSW50ZWdlci52YWx1ZU9mKDEpLCBlY3BzCisgICAgICAgICAgICAgICAgLmdldE9yZGVyKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHRlc3QgZm9yIGdldENvZmFjdG9yKCkgbWV0aG9kCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdF9HZXRDb2ZhY3RvcigpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ3cm9uZyBjb2ZhY3RvciB3YXMgcmV0dXJuZWQiLCAxLCBlY3BzLmdldENvZmFjdG9yKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0VDUG9pbnRUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9FQ1BvaW50VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUyNDBmM2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9FQ1BvaW50VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjM2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LnNwZWM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRUNQb2ludDsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+RUNQb2ludDwvY29kZT4gY2xhc3MgZmllbGRzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIEVDUG9pbnRUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLy8KKyAgICAvLyBUZXN0cworICAgIC8vCisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5FQ1BvaW50KEJpZ0ludGVnZXIsIEJpZ0ludGVnZXIpPC9jb2RlPiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IGNyZWF0ZXMgPGNvZGU+RUNQb2ludDwvY29kZT4gaW5zdGFuY2U8YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiB2YWxpZCBwYXJhbWV0ZXJzIHBhc3NlZDxicj4KKyAgICAgKiBFeHBlY3RlZDogbXVzdCBwYXNzIHdpdGhvdXQgYW55IGV4Y2VwdGlvbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RUNQb2ludDAxKCkgeworICAgICAgICBuZXcgRUNQb2ludChCaWdJbnRlZ2VyLlpFUk8sIEJpZ0ludGVnZXIuWkVSTyk7CisgICAgICAgIG5ldyBFQ1BvaW50KEJpZ0ludGVnZXIudmFsdWVPZigtMjM0NTZMKSwgQmlnSW50ZWdlci52YWx1ZU9mKC0yMzQ1NkwpKTsKKyAgICAgICAgbmV3IEVDUG9pbnQoQmlnSW50ZWdlci52YWx1ZU9mKDEyMzQ1NkwpLCBCaWdJbnRlZ2VyLnZhbHVlT2YoMTIzNDU2TCkpOworICAgICAgICBuZXcgRUNQb2ludChCaWdJbnRlZ2VyLnZhbHVlT2YoLTU2TCksIEJpZ0ludGVnZXIudmFsdWVPZigyMzRMKSk7CisgICAgICAgIG5ldyBFQ1BvaW50KEJpZ0ludGVnZXIudmFsdWVPZigzNDU2TCksIEJpZ0ludGVnZXIudmFsdWVPZigtMjM0NEwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5FQ1BvaW50KEJpZ0ludGVnZXIgeCwgQmlnSW50ZWdlciB5KTwvY29kZT4gY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlmIDxjb2RlPng8L2NvZGU+b3IKKyAgICAgKiA8Y29kZT55PC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPjxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHBhc3MgPGNvZGU+bnVsbDwvY29kZT4gYXMgbWVudGlvbmVkIHBhcmFtZXRlcnM8YnI+CisgICAgICogRXhwZWN0ZWQ6IG11c3QgdGhyb3cgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVDUG9pbnQwMigpIHsKKyAgICAgICAgLy8gdGVzdCBjYXNlIDE6IHggaXMgbnVsbAorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEVDUG9pbnQobnVsbCwgQmlnSW50ZWdlci5aRVJPKTsKKyAgICAgICAgICAgIGZhaWwoIiMxOiBFeHBlY3RlZCBOUEUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBvaykgeworICAgICAgICB9CisKKworICAgICAgICAvLyB0ZXN0IGNhc2UgMjogeSBpcyBudWxsCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRUNQb2ludChCaWdJbnRlZ2VyLlpFUk8sIG51bGwpOworICAgICAgICAgICAgZmFpbCgiIzI6IEV4cGVjdGVkIE5QRSBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG9rKSB7CisgICAgICAgIH0KKworCisgICAgICAgIC8vIHRlc3QgY2FzZSAzOiBib3RoIDogeCBhbmQgeSBhcmUgbnVsbAorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEVDUG9pbnQobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCIjMzogRXhwZWN0ZWQgTlBFIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gb2spIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPmdldEFmZmluZVgoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBhZmZpbmUgPGNvZGU+eDwvY29kZT4gY29vcmRpbmF0ZTxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IDxjb2RlPkVDUG9pbnQ8L2NvZGU+IGluc3RhbmNlCisgICAgICogY3JlYXRlZCB1c2luZyB2YWxpZCBwYXJhbWV0ZXJzPGJyPgorICAgICAqIEV4cGVjdGVkOiBtdXN0IHJldHVybiBhZmZpbmUgPGNvZGU+eDwvY29kZT4gY29vcmRpbmF0ZQorICAgICAqIHdoaWNoIGlzIGVxdWFsIHRvIHRoZSBvbmUgcGFzc2VkIHRvIHRoZSBjb25zdHJ1Y3RvcjsKKyAgICAgKiAoYm90aCBtdXN0IHJlZmVyIHRoZSBzYW1lIG9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0QWZmaW5lWDAxKCkgeworICAgICAgICBCaWdJbnRlZ2VyIHggPSBCaWdJbnRlZ2VyLnZhbHVlT2YoLTIzNDU2TCk7CisgICAgICAgIEVDUG9pbnQgcCA9IG5ldyBFQ1BvaW50KHgsIEJpZ0ludGVnZXIudmFsdWVPZigyMzQ1NkwpKTsKKyAgICAgICAgQmlnSW50ZWdlciB4UmV0ID0gcC5nZXRBZmZpbmVYKCk7CisgICAgICAgIGFzc2VydEVxdWFscyh4LCB4UmV0KTsKKyAgICAgICAgYXNzZXJ0U2FtZSh4LCB4UmV0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5nZXRBZmZpbmVYKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4gZm9yIDxjb2RlPkVDUG9pbnQuUE9JTlRfSU5GSU5JVFk8L2NvZGU+PGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogbm9uZTxicj4KKyAgICAgKiBFeHBlY3RlZDogbXVzdCByZXR1cm4gPGNvZGU+bnVsbDwvY29kZT4gZm9yCisgICAgICogPGNvZGU+RUNQb2ludC5QT0lOVF9JTkZJTklUWTwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0QWZmaW5lWDAyKCkgeworICAgICAgICBhc3NlcnROdWxsKEVDUG9pbnQuUE9JTlRfSU5GSU5JVFkuZ2V0QWZmaW5lWCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5nZXRBZmZpbmVZKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgYWZmaW5lIDxjb2RlPnk8L2NvZGU+IGNvb3JkaW5hdGU8YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiA8Y29kZT5FQ1BvaW50PC9jb2RlPiBpbnN0YW5jZQorICAgICAqIGNyZWF0ZWQgdXNpbmcgdmFsaWQgcGFyYW1ldGVyczxicj4KKyAgICAgKiBFeHBlY3RlZDogbXVzdCByZXR1cm4gYWZmaW5lIDxjb2RlPnk8L2NvZGU+IGNvb3JkaW5hdGUKKyAgICAgKiB3aGljaCBpcyBlcXVhbCB0byB0aGUgb25lIHBhc3NlZCB0byB0aGUgY29uc3RydWN0b3I7CisgICAgICogKGJvdGggbXVzdCByZWZlciB0aGUgc2FtZSBvYmplY3QpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEFmZmluZVkwMSgpIHsKKyAgICAgICAgQmlnSW50ZWdlciB5ID0gIEJpZ0ludGVnZXIudmFsdWVPZigyMzQ1NkwpOworICAgICAgICBFQ1BvaW50IHAgPSBuZXcgRUNQb2ludChCaWdJbnRlZ2VyLnZhbHVlT2YoLTIzNDU2TCksIHkpOworICAgICAgICBCaWdJbnRlZ2VyIHlSZXQgPSBwLmdldEFmZmluZVkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHksIHlSZXQpOworICAgICAgICBhc3NlcnRTYW1lKHksIHlSZXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPmdldEFmZmluZVgoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPiBmb3IgPGNvZGU+RUNQb2ludC5QT0lOVF9JTkZJTklUWTwvY29kZT48YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiBub25lPGJyPgorICAgICAqIEV4cGVjdGVkOiBtdXN0IHJldHVybiA8Y29kZT5udWxsPC9jb2RlPiBmb3IKKyAgICAgKiA8Y29kZT5FQ1BvaW50LlBPSU5UX0lORklOSVRZPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRBZmZpbmVZMDIoKSB7CisgICAgICAgIGFzc2VydE51bGwoRUNQb2ludC5QT0lOVF9JTkZJTklUWS5nZXRBZmZpbmVZKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPmVxdWFscyhPYmplY3Qgb3RoZXIpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm4gdHJ1ZSBpZiB0aGlzIGFuZCBvdGhlciBvYmplY3RzIGFyZSBlcXVhbDxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHNlZSB0ZXN0IGNvbW1lbnRzPGJyPgorICAgICAqIEV4cGVjdGVkOiBhbGwgb2JqZWN0cyBpbiB0aGlzIHRlc3QgbXVzdCBiZSBlcXVhbAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFcXVhbHNPYmplY3QwMSgpIHsKKyAgICAgICAgLy8gdGVzdCBjYXNlIDE6IG11c3QgYmUgZXF1YWwgdG8gaXRzZWxmCisgICAgICAgIEVDUG9pbnQgcDI9bnVsbCwgcDEgPQorICAgICAgICAgICAgbmV3IEVDUG9pbnQoQmlnSW50ZWdlci52YWx1ZU9mKC0yMzQ1NkwpLCBCaWdJbnRlZ2VyLk9ORSk7CisgICAgICAgIGFzc2VydFRydWUocDEuZXF1YWxzKHAxKSk7CisKKyAgICAgICAgLy8gdGVzdCBjYXNlIDI6IGVxdWFsIG9iamVjdHMKKyAgICAgICAgcDEgPSBuZXcgRUNQb2ludChCaWdJbnRlZ2VyLnZhbHVlT2YoLTIzNDU2TCksIEJpZ0ludGVnZXIuT05FKTsKKyAgICAgICAgcDIgPSBuZXcgRUNQb2ludChCaWdJbnRlZ2VyLnZhbHVlT2YoLTIzNDU2TCksIEJpZ0ludGVnZXIudmFsdWVPZigxTCkpOworICAgICAgICBhc3NlcnRUcnVlKHAxLmVxdWFscyhwMikgJiYgcDIuZXF1YWxzKHAxKSk7CisKKyAgICAgICAgLy8gdGVzdCBjYXNlIDM6IGVxdWFsIFBPSU5UX0lORklOSVRZIG9iamVjdChzKQorICAgICAgICBwMSA9IEVDUG9pbnQuUE9JTlRfSU5GSU5JVFk7CisgICAgICAgIHAyID0gRUNQb2ludC5QT0lOVF9JTkZJTklUWTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShwMS5lcXVhbHMocDIpICYmIHAyLmVxdWFscyhwMSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPmVxdWFscyhPYmplY3Qgb3RoZXIpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm4gZmFsc2UgaWYgdGhpcyBhbmQgb3RoZXIgb2JqZWN0cyBhcmUgbm90IGVxdWFsPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogc2VlIHRlc3QgY29tbWVudHM8YnI+CisgICAgICogRXhwZWN0ZWQ6IGFsbCBvYmplY3RzIGluIHRoaXMgdGVzdCBtdXN0IGJlIG5vdCBlcXVhbAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFcXVhbHNPYmplY3QwMigpIHsKKyAgICAgICAgLy8gdGVzdCBjYXNlIDE6IG11c3QgYmUgbm90IGVxdWFsIHRvIG51bGwKKyAgICAgICAgRUNQb2ludCBwMj1udWxsLCBwMSA9CisgICAgICAgICAgICBuZXcgRUNQb2ludChCaWdJbnRlZ2VyLnZhbHVlT2YoLTIzNDU2TCksIEJpZ0ludGVnZXIuT05FKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocDEuZXF1YWxzKHAyKSk7CisKKyAgICAgICAgLy8gdGVzdCBjYXNlIDI6IG5vdCBlcXVhbCBvYmplY3RzIC0geAorICAgICAgICBwMSA9IG5ldyBFQ1BvaW50KEJpZ0ludGVnZXIudmFsdWVPZigtMjM0NTdMKSwgQmlnSW50ZWdlci5PTkUpOworICAgICAgICBwMiA9IG5ldyBFQ1BvaW50KEJpZ0ludGVnZXIudmFsdWVPZigtMjM0NTZMKSwgQmlnSW50ZWdlci52YWx1ZU9mKDFMKSk7CisgICAgICAgIGFzc2VydEZhbHNlKHAxLmVxdWFscyhwMikgfHwgcDIuZXF1YWxzKHAxKSk7CisKKyAgICAgICAgLy8gdGVzdCBjYXNlIDM6IG5vdCBlcXVhbCBvYmplY3RzIC0geQorICAgICAgICBwMSA9IG5ldyBFQ1BvaW50KEJpZ0ludGVnZXIudmFsdWVPZigtMjM0NTdMKSwgQmlnSW50ZWdlci5PTkUpOworICAgICAgICBwMiA9IG5ldyBFQ1BvaW50KEJpZ0ludGVnZXIudmFsdWVPZigtMjM0NTZMKSwgQmlnSW50ZWdlci5aRVJPKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocDEuZXF1YWxzKHAyKSB8fCBwMi5lcXVhbHMocDEpKTsKKworICAgICAgICAvLyB0ZXN0IGNhc2UgNDogbm90IGVxdWFsIC0gc29tZSBwb2ludCBhbmQgUE9JTlRfSU5GSU5JVFkKKyAgICAgICAgcDEgPSBFQ1BvaW50LlBPSU5UX0lORklOSVRZOworICAgICAgICBwMiA9IG5ldyBFQ1BvaW50KEJpZ0ludGVnZXIudmFsdWVPZigtMjM0NTZMKSwgQmlnSW50ZWdlci5aRVJPKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocDEuZXF1YWxzKHAyKSB8fCBwMi5lcXVhbHMocDEpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5oYXNoQ29kZSgpPC9jb2RlPiBtZXRob2QuPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBtdXN0IHJldHVybiB0aGUgc2FtZSB2YWx1ZSBpZiBpbnZva2VkCisgICAgICogcmVwZWF0ZWRseSBvbiB0aGUgc2FtZSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEhhc2hDb2RlMDEoKSB7CisgICAgICAgIEVDUG9pbnQgZiA9IG5ldyBFQ1BvaW50KEJpZ0ludGVnZXIudmFsdWVPZigtMjM0NTdMKSwgQmlnSW50ZWdlci5PTkUpOworICAgICAgICBpbnQgaGMgPSBmLmhhc2hDb2RlKCk7CisgICAgICAgIGFzc2VydFRydWUoaGMgPT0gZi5oYXNoQ29kZSgpICYmCisgICAgICAgICAgICAgICAgICAgaGMgPT0gZi5oYXNoQ29kZSgpICYmCisgICAgICAgICAgICAgICAgICAgaGMgPT0gZi5oYXNoQ29kZSgpICYmCisgICAgICAgICAgICAgICAgICAgaGMgPT0gZi5oYXNoQ29kZSgpICYmCisgICAgICAgICAgICAgICAgICAgaGMgPT0gZi5oYXNoQ29kZSgpICYmCisgICAgICAgICAgICAgICAgICAgaGMgPT0gZi5oYXNoQ29kZSgpICYmCisgICAgICAgICAgICAgICAgICAgaGMgPT0gZi5oYXNoQ29kZSgpICYmCisgICAgICAgICAgICAgICAgICAgaGMgPT0gZi5oYXNoQ29kZSgpKTsKKworCisgICAgICAgIC8vIHRoZSBzYW1lIGZvciBQT0lOVF9JTkZJTklUWQorICAgICAgICBoYyA9IEVDUG9pbnQuUE9JTlRfSU5GSU5JVFkuaGFzaENvZGUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShoYyA9PSBFQ1BvaW50LlBPSU5UX0lORklOSVRZLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBFQ1BvaW50LlBPSU5UX0lORklOSVRZLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBFQ1BvaW50LlBPSU5UX0lORklOSVRZLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBFQ1BvaW50LlBPSU5UX0lORklOSVRZLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBFQ1BvaW50LlBPSU5UX0lORklOSVRZLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBFQ1BvaW50LlBPSU5UX0lORklOSVRZLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBFQ1BvaW50LlBPSU5UX0lORklOSVRZLmhhc2hDb2RlKCkgJiYKKyAgICAgICAgICAgICAgICAgICBoYyA9PSBFQ1BvaW50LlBPSU5UX0lORklOSVRZLmhhc2hDb2RlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPmhhc2hDb2RlKCk8L2NvZGU+IG1ldGhvZC48YnI+CisgICAgICoKKyAgICAgKiBBc3NlcnRpb246IG11c3QgcmV0dXJuIHRoZSBzYW1lIHZhbHVlIGlmIGludm9rZWQKKyAgICAgKiBvbiBlcXVhbCAoYWNjb3JkaW5nIHRvIHRoZSA8Y29kZT5lcXVhbHMoT2JqZWN0KTwvY29kZT4gbWV0aG9kKSBvYmplY3RzLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RIYXNoQ29kZTAyKCkgeworICAgICAgICBFQ1BvaW50IHAxID0gbmV3IEVDUG9pbnQoQmlnSW50ZWdlci52YWx1ZU9mKC0yMzQ1NkwpLCBCaWdJbnRlZ2VyLk9ORSk7CisgICAgICAgIEVDUG9pbnQgcDIgPSBuZXcgRUNQb2ludChCaWdJbnRlZ2VyLnZhbHVlT2YoLTIzNDU2TCksIEJpZ0ludGVnZXIudmFsdWVPZigxTCkpOworICAgICAgICBhc3NlcnRFcXVhbHMocDEuaGFzaENvZGUoKSwgcDIuaGFzaENvZGUoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9FQ1ByaXZhdGVLZXlTcGVjVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvRUNQcml2YXRlS2V5U3BlY1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hM2RiNWE3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvRUNQcml2YXRlS2V5U3BlY1Rlc3QuamF2YQpAQCAtMCwwICsxLDk5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LnNwZWM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRUNGaWVsZEYybTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRUNQYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FQ1BvaW50OworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FQ1ByaXZhdGVLZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FbGxpcHRpY0N1cnZlOworCitwdWJsaWMgY2xhc3MgRUNQcml2YXRlS2V5U3BlY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBCaWdJbnRlZ2VyIHM7CisKKyAgICBFQ1BhcmFtZXRlclNwZWMgZWNwYXJhbXM7CisKKyAgICBFQ1ByaXZhdGVLZXlTcGVjIGVjcGtzOworCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKworICAgICAgICBFQ1BvaW50IGVjcG9pbnQgPSBuZXcgRUNQb2ludChCaWdJbnRlZ2VyLnZhbHVlT2YoMSksIEJpZ0ludGVnZXIKKyAgICAgICAgICAgICAgICAudmFsdWVPZigxKSk7CisgICAgICAgIEVsbGlwdGljQ3VydmUgY3VydmUgPSBuZXcgRWxsaXB0aWNDdXJ2ZShuZXcgRUNGaWVsZEYybSgyKSwgQmlnSW50ZWdlcgorICAgICAgICAgICAgICAgIC52YWx1ZU9mKDEpLCBCaWdJbnRlZ2VyLnZhbHVlT2YoMSkpOworCisgICAgICAgIHMgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoMSk7CisgICAgICAgIGVjcGFyYW1zID0gbmV3IEVDUGFyYW1ldGVyU3BlYyhjdXJ2ZSwgZWNwb2ludCwgQmlnSW50ZWdlci52YWx1ZU9mKDEpLCAxKTsKKyAgICAgICAgZWNwa3MgPSBuZXcgRUNQcml2YXRlS2V5U3BlYyhzLCBlY3BhcmFtcyk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcyA9IG51bGw7CisgICAgICAgIGVjcGFyYW1zID0gbnVsbDsKKyAgICAgICAgZWNwa3MgPSBudWxsOworICAgICAgICBzdXBlci50ZWFyRG93bigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHRlc3QgZm9yIGNvbnN0cnVjdG9yIEVDUHJpdmF0ZUtleVNwZWMoQmlnSW50ZWdlciwgRUNQYXJhbWV0ZXJTcGVjKQorICAgICAqIHRlc3QgY292ZXJzIGZvbGxvd2luZyB1c2VjYXNlczoKKyAgICAgKiBjYXNlIDE6IGNyZWF0aW5nIG9iamVjdCB3aXRoIHZhbGlkIHBhcmFtZXRlcnMKKyAgICAgKiBjYXNlIDI6IGNhdGNoIE51bGxQb2ludGVyRXhjZXB0aW9uIC0gaWYgcyBpcyBudWxsLgorICAgICAqIGNhc2UgMzogY2F0Y2ggTnVsbFBvaW50ZXJFeGNlcHRpb24gLSBpZiBwYXJhbXMgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X2NvbnN0cnVjdG9yTGphdmFfbWF0aF9CaWdJbnRlZ2VyTGphdmFfc2VjdXJpdHlfc3BlY19FQ1BhcmFtZXRlclNwZWMoKSB7CisKKyAgICAgICAgLy8gY2FzZSAxOiBjcmVhdGluZyBvYmplY3Qgd2l0aCB2YWxpZCBwYXJhbWV0ZXJzCisgICAgICAgIGFzc2VydEVxdWFscygid3JvbmcgcHJpdmF0ZSB2YWx1ZSIsIHMsIGVjcGtzLmdldFMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygid3JvbmcgcGFyYW1ldGVycyIsIGVjcGFyYW1zLCBlY3Brcy5nZXRQYXJhbXMoKSk7CisKKyAgICAgICAgLy8gY2FzZSAyOiBjYXRjaCBOdWxsUG9pbnRlckV4Y2VwdGlvbiAtIGlmIHMgaXMgbnVsbC4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFQ1ByaXZhdGVLZXlTcGVjKG51bGwsIGVjcGFyYW1zKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGxQb2ludGVyRXhjZXB0aW9uIGhhcyBub3QgYmVlbiB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNhc2UgMzogY2F0Y2ggTnVsbFBvaW50ZXJFeGNlcHRpb24gLSBpZiBwYXJhbXMgaXMgbnVsbC4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFQ1ByaXZhdGVLZXlTcGVjKHMsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogdGVzdCBmb3IgZ2V0UygpIG1ldGhvZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfR2V0UygpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ3cm9uZyBwcml2YXRlIHZhbHVlIiwgcywgZWNwa3MuZ2V0UygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB0ZXN0IGZvciBnZXRQYXJhbXMoKSBtZXRob2QKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0X0dldFBhcmFtcygpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ3cm9uZyBwYXJhbWV0ZXJzIiwgZWNwYXJhbXMsIGVjcGtzLmdldFBhcmFtcygpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9FQ1B1YmxpY0tleVNwZWNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9FQ1B1YmxpY0tleVNwZWNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWJhYzdhMgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0VDUHVibGljS2V5U3BlY1Rlc3QuamF2YQpAQCAtMCwwICsxLDk3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA3IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LnNwZWM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRUNGaWVsZEYybTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRUNQYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FQ1BvaW50OworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FQ1B1YmxpY0tleVNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkVsbGlwdGljQ3VydmU7CisKK3B1YmxpYyBjbGFzcyBFQ1B1YmxpY0tleVNwZWNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworICAgIEVDUG9pbnQgdzsKKworICAgIEVDUGFyYW1ldGVyU3BlYyBwYXJhbXM7CisKKyAgICBFQ1B1YmxpY0tleVNwZWMgZWNwa3M7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBFQ1BvaW50IGVjcG9pbnQgPSBuZXcgRUNQb2ludChCaWdJbnRlZ2VyLnZhbHVlT2YoMSksIEJpZ0ludGVnZXIKKyAgICAgICAgICAgICAgICAudmFsdWVPZigxKSk7CisgICAgICAgIEVsbGlwdGljQ3VydmUgY3VydmUgPSBuZXcgRWxsaXB0aWNDdXJ2ZShuZXcgRUNGaWVsZEYybSgyKSwgQmlnSW50ZWdlcgorICAgICAgICAgICAgICAgIC52YWx1ZU9mKDEpLCBCaWdJbnRlZ2VyLnZhbHVlT2YoMSkpOworCisgICAgICAgIHcgPSBuZXcgRUNQb2ludChCaWdJbnRlZ2VyLnZhbHVlT2YoMSksIEJpZ0ludGVnZXIudmFsdWVPZigxKSk7CisgICAgICAgIHBhcmFtcyA9IG5ldyBFQ1BhcmFtZXRlclNwZWMoY3VydmUsIGVjcG9pbnQsIEJpZ0ludGVnZXIudmFsdWVPZigxKSwgMSk7CisgICAgICAgIGVjcGtzID0gbmV3IEVDUHVibGljS2V5U3BlYyh3LCBwYXJhbXMpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHcgPSBudWxsOworICAgICAgICBwYXJhbXMgPSBudWxsOworICAgICAgICBlY3BrcyA9IG51bGw7CisgICAgICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogdGVzdCBmb3IgY29uc3RydWN0b3IgRUNQdWJsaWNLZXlTcGVjKEVDUG9pbnQsIEVDUGFyYW1ldGVyU3BlYykKKyAgICAgKiB0ZXN0IGNvdmVycyBmb2xsb3dpbmcgdXNlY2FzZXM6CisgICAgICogY2FzZSAxOiBjcmVhdGluZyBvYmplY3Qgd2l0aCB2YWxpZCBwYXJhbWV0ZXJzCisgICAgICogY2FzZSAyOiBjYXRjaCBOdWxsUG9pbnRlckV4Y2VwdGlvbiAtIGlmIHcgaXMgbnVsbC4KKyAgICAgKiBjYXNlIDM6IGNhdGNoIE51bGxQb2ludGVyRXhjZXB0aW9uIC0gaWYgcGFyYW1zIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdF9jb25zdHJ1Y3RvckxqYXZhX3NlY3VyaXR5X3NwZWNfRUNQb2ludExqYXZhX3NlY3VyaXR5X3NwZWNfRUNQYXJhbWV0ZXJTcGVjKCkgeworCisgICAgICAgIC8vIGNhc2UgMTogY3JlYXRpbmcgb2JqZWN0IHdpdGggdmFsaWQgcGFyYW1ldGVycworICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIHBhcmFtcyB2YWx1ZSIsIHBhcmFtcywgZWNwa3MuZ2V0UGFyYW1zKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIHcgdmFsdWUiLCB3LCBlY3Brcy5nZXRXKCkpOworCisgICAgICAgIC8vIGNhc2UgMjogY2F0Y2ggTnVsbFBvaW50ZXJFeGNlcHRpb24gLSBpZiB3IGlzIG51bGwuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRUNQdWJsaWNLZXlTcGVjKG51bGwsIHBhcmFtcyk7CisgICAgICAgICAgICBmYWlsKCJOdWxsUG9pbnRlckV4Y2VwdGlvbiBoYXMgbm90IGJlZW4gdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICAvLyBjYXNlIDM6IGNhdGNoIE51bGxQb2ludGVyRXhjZXB0aW9uIC0gaWYgcGFyYW1zIGlzIG51bGwuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRUNQdWJsaWNLZXlTcGVjKHcsIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogdGVzdCBmb3IgZ2V0VygpIG1ldGhvZAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRXKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIndyb25nIHcgdmFsdWUiLCB3LCBlY3Brcy5nZXRXKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIHRlc3QgZm9yIGdldFBhcmFtcygpIG1leWhvZAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRQYXJhbXMoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygid3JvbmcgcGFyYW1zIHZhbHVlIiwgcGFyYW1zLCBlY3Brcy5nZXRQYXJhbXMoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvRWxsaXB0aWNDdXJ2ZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0VsbGlwdGljQ3VydmVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2QwOTBjNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0VsbGlwdGljQ3VydmVUZXN0LmphdmEKQEAgLTAsMCArMSw2NDggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FQ0ZpZWxkOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FQ0ZpZWxkRjJtOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FQ0ZpZWxkRnA7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkVsbGlwdGljQ3VydmU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+RWxsaXB0aWNDdXJ2ZTwvY29kZT4gY2xhc3MgZmllbGRzIGFuZCBtZXRob2RzLgorICoKKyAqLworcHVibGljIGNsYXNzIEVsbGlwdGljQ3VydmVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IgPGNvZGU+RWxsaXB0aWNDdXJ2ZShFQ0ZpZWxkLCBCaWdJbnRlZ2VyLCBCaWdJbnRlZ2VyLCBieXRlW10pPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogY3JlYXRlcyBpbnN0YW5jZSBvZiBFbGxpcHRpY0N1cnZlPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogdmFsaWQgcGFyYW1ldGVycyBwYXNzZWQ8YnI+CisgICAgICogRXhwZWN0ZWQ6IG11c3QgcGFzcyB3aXRob3V0IGFueSBleGNlcHRpb25zCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVsbGlwdGljQ3VydmVFQ0ZpZWxkQmlnSW50ZWdlckJpZ0ludGVnZXJieXRlQXJyYXkwMSgpIHsKKyAgICAgICAgLy8gdGVzdCBjYXNlIDEgcGFyYW1ldGVycyBzZXQKKyAgICAgICAgRUNGaWVsZEZwIGYgPSBuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigyM0wpKTsKKyAgICAgICAgQmlnSW50ZWdlciBhID0gQmlnSW50ZWdlci5PTkU7CisgICAgICAgIEJpZ0ludGVnZXIgYiA9IEJpZ0ludGVnZXIudmFsdWVPZigxOUwpOworICAgICAgICBieXRlW10gc2VlZCA9IG5ldyBieXRlWzI0XTsKKyAgICAgICAgLy8gcGVyZm9ybSB0ZXN0IGNhc2UgMQorICAgICAgICBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiLCBzZWVkKTsKKworICAgICAgICAvLyB0ZXN0IGNhc2UgMiBwYXJhbWV0ZXJzIHNldAorICAgICAgICBFQ0ZpZWxkRjJtIGYxID0gbmV3IEVDRmllbGRGMm0oNSk7CisgICAgICAgIGEgPSBCaWdJbnRlZ2VyLlpFUk87CisgICAgICAgIGIgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoMjNMKTsKKyAgICAgICAgLy8gcGVyZm9ybSB0ZXN0IGNhc2UgMgorICAgICAgICBuZXcgRWxsaXB0aWNDdXJ2ZShmMSwgYSwgYiwgc2VlZCk7CisKKyAgICAgICAgLy8gdGVzdCBjYXNlIDMgcGFyYW1ldGVycyBzZXQsCisgICAgICAgIC8vIHRoZSBzZWVkIHBhcmFtZXRlciBtYXkgYmUgbnVsbAorICAgICAgICBmID0gbmV3IEVDRmllbGRGcChCaWdJbnRlZ2VyLnZhbHVlT2YoMjNMKSk7CisgICAgICAgIGEgPSBCaWdJbnRlZ2VyLk9ORTsKKyAgICAgICAgYiA9IEJpZ0ludGVnZXIudmFsdWVPZigxOUwpOworICAgICAgICBzZWVkID0gbnVsbDsKKyAgICAgICAgLy8gcGVyZm9ybSB0ZXN0IGNhc2UgMworICAgICAgICBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiLCBzZWVkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5FbGxpcHRpY0N1cnZlKEVDRmllbGQsIEJpZ0ludGVnZXIsIEJpZ0ludGVnZXIsIGJ5dGVbXSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlmIDxjb2RlPmZpZWxkPC9jb2RlPiwKKyAgICAgKiA8Y29kZT5hPC9jb2RlPiBvciA8Y29kZT5iPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPjxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHBhc3MgPGNvZGU+bnVsbDwvY29kZT4gYXMgbWVudGlvbmVkIHBhcmFtZXRlcnM8YnI+CisgICAgICogRXhwZWN0ZWQ6IG11c3QgdGhyb3cgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVsbGlwdGljQ3VydmVFQ0ZpZWxkQmlnSW50ZWdlckJpZ0ludGVnZXJieXRlQXJyYXkwMigpIHsKKyAgICAgICAgLy8gdGVzdCBjYXNlIDEgcGFyYW1ldGVycyBzZXQKKyAgICAgICAgRUNGaWVsZEZwIGYgPSBudWxsOworICAgICAgICBCaWdJbnRlZ2VyIGEgPSBCaWdJbnRlZ2VyLk9ORTsKKyAgICAgICAgQmlnSW50ZWdlciBiID0gQmlnSW50ZWdlci52YWx1ZU9mKDE5TCk7CisgICAgICAgIGJ5dGVbXSBzZWVkID0gbmV3IGJ5dGVbMjRdOworCisgICAgICAgIC8vIHBlcmZvcm0gdGVzdCBjYXNlIDEKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFbGxpcHRpY0N1cnZlKGYsIGEsIGIsIHNlZWQpOworICAgICAgICAgICAgZmFpbCgiIzE6IEV4cGVjdGVkIE5QRSBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG9rKSB7fQorCisgICAgICAgIC8vIHRlc3QgY2FzZSAyIHBhcmFtZXRlcnMgc2V0LAorICAgICAgICBmID0gbmV3IEVDRmllbGRGcChCaWdJbnRlZ2VyLnZhbHVlT2YoMjNMKSk7CisgICAgICAgIGEgPSBudWxsOworICAgICAgICBiID0gQmlnSW50ZWdlci52YWx1ZU9mKDE5TCk7CisgICAgICAgIHNlZWQgPSBuZXcgYnl0ZVsyNF07CisgICAgICAgIC8vIHBlcmZvcm0gdGVzdCBjYXNlIDIKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFbGxpcHRpY0N1cnZlKGYsIGEsIGIsIHNlZWQpOworICAgICAgICAgICAgZmFpbCgiIzI6IEV4cGVjdGVkIE5QRSBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG9rKSB7fQorCisgICAgICAgIC8vIHRlc3QgY2FzZSAzIHBhcmFtZXRlcnMgc2V0LAorICAgICAgICBmID0gbmV3IEVDRmllbGRGcChCaWdJbnRlZ2VyLnZhbHVlT2YoMjNMKSk7CisgICAgICAgIGEgPSBCaWdJbnRlZ2VyLk9ORTsKKyAgICAgICAgYiA9IG51bGw7CisgICAgICAgIHNlZWQgPSBuZXcgYnl0ZVsyNF07CisgICAgICAgIC8vIHBlcmZvcm0gdGVzdCBjYXNlIDIKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFbGxpcHRpY0N1cnZlKGYsIGEsIGIsIHNlZWQpOworICAgICAgICAgICAgZmFpbCgiIzM6IEV4cGVjdGVkIE5QRSBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG9rKSB7fQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzMgZm9yIDxjb2RlPkVsbGlwdGljQ3VydmUoRUNGaWVsZCwgQmlnSW50ZWdlciwgQmlnSW50ZWdlciwgYnl0ZVtdKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IHRocm93cyA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlmCisgICAgICogPGNvZGU+YTwvY29kZT4gb3IgPGNvZGU+YjwvY29kZT4gaXMgbm90IDxjb2RlPm51bGw8L2NvZGU+IGFuZCBub3QgaW4KKyAgICAgKiB0aGUgPGNvZGU+ZmllbGQ8L2NvZGU+PGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogcGFzcyA8Y29kZT5hPC9jb2RlPiwgPGNvZGU+YjwvY29kZT4gd2hpY2ggYXJlCisgICAgICogbm90IGluIHRoZSA8Y29kZT5maWVsZDwvY29kZT4gb2YgdHlwZSA8Y29kZT5FQ0ZpZWxkRnA8L2NvZGU+PGJyPgorICAgICAqIEV4cGVjdGVkOiBtdXN0IHRocm93IDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RWxsaXB0aWNDdXJ2ZUVDRmllbGRCaWdJbnRlZ2VyQmlnSW50ZWdlcmJ5dGVBcnJheTAzKCkgeworICAgICAgICAvLyB0ZXN0IGNhc2UgMSBwYXJhbWV0ZXJzIHNldCwKKyAgICAgICAgLy8gYSBpcyBub3QgaW4gZmllbGQKKyAgICAgICAgRUNGaWVsZEZwIGYgPSBuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigyM0wpKTsKKyAgICAgICAgQmlnSW50ZWdlciBhID0gQmlnSW50ZWdlci52YWx1ZU9mKDI0TCk7CisgICAgICAgIEJpZ0ludGVnZXIgYiA9IEJpZ0ludGVnZXIudmFsdWVPZigxOUwpOworICAgICAgICBieXRlW10gc2VlZCA9IG5ldyBieXRlWzI0XTsKKworICAgICAgICAvLyBwZXJmb3JtIHRlc3QgY2FzZSAxCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiLCBzZWVkKTsKKyAgICAgICAgICAgIGZhaWwoIiMxOiBFeHBlY3RlZCBJQUUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gb2spIHt9CisKKyAgICAgICAgLy8gdGVzdCBjYXNlIDEuMSBwYXJhbWV0ZXJzIHNldCwKKyAgICAgICAgLy8gYiBpcyBub3QgaW4gZmllbGQKKyAgICAgICAgZiA9IG5ldyBFQ0ZpZWxkRnAoQmlnSW50ZWdlci52YWx1ZU9mKDIzTCkpOworICAgICAgICBhID0gQmlnSW50ZWdlci52YWx1ZU9mKDFMKTsKKyAgICAgICAgYiA9IEJpZ0ludGVnZXIudmFsdWVPZigyM0wpOworICAgICAgICBzZWVkID0gbmV3IGJ5dGVbMjRdOworICAgICAgICAvLyBwZXJmb3JtIHRlc3QgY2FzZSAxLjEKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFbGxpcHRpY0N1cnZlKGYsIGEsIGIsIHNlZWQpOworICAgICAgICAgICAgZmFpbCgiIzEuMTogRXhwZWN0ZWQgSUFFIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG9rKSB7fQorCisgICAgICAgIC8vIHRlc3QgY2FzZSAyIHBhcmFtZXRlcnMgc2V0LAorICAgICAgICAvLyBiIGlzIG5vdCBpbiBmaWVsZAorICAgICAgICBmID0gbmV3IEVDRmllbGRGcChCaWdJbnRlZ2VyLnZhbHVlT2YoMjNMKSk7CisgICAgICAgIGEgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoMTlMKTsKKyAgICAgICAgYiA9IEJpZ0ludGVnZXIudmFsdWVPZigyNEwpOworICAgICAgICBzZWVkID0gbmV3IGJ5dGVbMjRdOworICAgICAgICAvLyBwZXJmb3JtIHRlc3QgY2FzZSAyCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiLCBzZWVkKTsKKyAgICAgICAgICAgIGZhaWwoIiMyOiBFeHBlY3RlZCBJQUUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gb2spIHt9CisKKyAgICAgICAgLy8gdGVzdCBjYXNlIDMgcGFyYW1ldGVycyBzZXQsCisgICAgICAgIC8vIGJvdGggYSBhbmQgYiBhcmUgbm90IGluIGZpZWxkCisgICAgICAgIGYgPSBuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigyM0wpKTsKKyAgICAgICAgYSA9IEJpZ0ludGVnZXIudmFsdWVPZigyNUwpOworICAgICAgICBiID0gQmlnSW50ZWdlci52YWx1ZU9mKDI0MEwpOworICAgICAgICBzZWVkID0gbmV3IGJ5dGVbMjRdOworICAgICAgICAvLyBwZXJmb3JtIHRlc3QgY2FzZSAzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiLCBzZWVkKTsKKyAgICAgICAgICAgIGZhaWwoIiMzOiBFeHBlY3RlZCBJQUUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gb2spIHt9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjNCBmb3IgPGNvZGU+RWxsaXB0aWNDdXJ2ZShFQ0ZpZWxkLCBCaWdJbnRlZ2VyLCBCaWdJbnRlZ2VyLCBieXRlW10pPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaWYKKyAgICAgKiA8Y29kZT5hPC9jb2RlPiBvciA8Y29kZT5iPC9jb2RlPiBpcyBub3QgPGNvZGU+bnVsbDwvY29kZT4gYW5kIG5vdCBpbgorICAgICAqIHRoZSA8Y29kZT5maWVsZDwvY29kZT48YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiBwYXNzIDxjb2RlPmE8L2NvZGU+LCA8Y29kZT5iPC9jb2RlPiB3aGljaCBhcmUKKyAgICAgKiBub3QgaW4gdGhlIDxjb2RlPmZpZWxkPC9jb2RlPiBvZiB0eXBlIDxjb2RlPkVDRmllbGRGMm08L2NvZGU+PGJyPgorICAgICAqIEV4cGVjdGVkOiBtdXN0IHRocm93IDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RWxsaXB0aWNDdXJ2ZUVDRmllbGRCaWdJbnRlZ2VyQmlnSW50ZWdlcmJ5dGVBcnJheTA0KCkgeworICAgICAgICAvLyB0ZXN0IGNhc2UgMSBwYXJhbWV0ZXJzIHNldCwKKyAgICAgICAgLy8gYSBpcyBub3QgaW4gZmllbGQKKyAgICAgICAgRUNGaWVsZEYybSBmID0gbmV3IEVDRmllbGRGMm0oNSk7CisgICAgICAgIEJpZ0ludGVnZXIgYSA9IEJpZ0ludGVnZXIudmFsdWVPZigzMkwpOworICAgICAgICBCaWdJbnRlZ2VyIGIgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoMTlMKTsKKyAgICAgICAgYnl0ZVtdIHNlZWQgPSBuZXcgYnl0ZVsyNF07CisKKyAgICAgICAgLy8gcGVyZm9ybSB0ZXN0IGNhc2UgMQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEVsbGlwdGljQ3VydmUoZiwgYSwgYiwgc2VlZCk7CisgICAgICAgICAgICBmYWlsKCIjMTogRXhwZWN0ZWQgSUFFIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG9rKSB7fQorCisgICAgICAgIC8vIHRlc3QgY2FzZSAyIHBhcmFtZXRlcnMgc2V0LAorICAgICAgICAvLyBiIGlzIG5vdCBpbiBmaWVsZAorICAgICAgICBmID0gbmV3IEVDRmllbGRGMm0oNSk7CisgICAgICAgIGEgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoMTlMKTsKKyAgICAgICAgYiA9IEJpZ0ludGVnZXIudmFsdWVPZigzMkwpOworICAgICAgICBzZWVkID0gbmV3IGJ5dGVbMjRdOworICAgICAgICAvLyBwZXJmb3JtIHRlc3QgY2FzZSAyCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiLCBzZWVkKTsKKyAgICAgICAgICAgIGZhaWwoIiMyOiBFeHBlY3RlZCBJQUUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gb2spIHt9CisKKyAgICAgICAgLy8gdGVzdCBjYXNlIDMgcGFyYW1ldGVycyBzZXQsCisgICAgICAgIC8vIGJvdGggYSBhbmQgYiBhcmUgbm90IGluIGZpZWxkCisgICAgICAgIGYgPSBuZXcgRUNGaWVsZEYybSg1KTsKKyAgICAgICAgYSA9IEJpZ0ludGVnZXIudmFsdWVPZigzMkwpOworICAgICAgICBiID0gQmlnSW50ZWdlci52YWx1ZU9mKDQzTCk7CisgICAgICAgIHNlZWQgPSBuZXcgYnl0ZVsyNF07CisgICAgICAgIC8vIHBlcmZvcm0gdGVzdCBjYXNlIDMKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFbGxpcHRpY0N1cnZlKGYsIGEsIGIsIHNlZWQpOworICAgICAgICAgICAgZmFpbCgiIzM6IEV4cGVjdGVkIElBRSBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBvaykge30KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM1IGZvciA8Y29kZT5FbGxpcHRpY0N1cnZlKEVDRmllbGQsIEJpZ0ludGVnZXIsIEJpZ0ludGVnZXIsIGJ5dGVbXSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiBhcnJheSA8Y29kZT5zZWVkPC9jb2RlPiBpcyBjb3BpZWQgdG8gcHJldmVudCBzdWJzZXF1ZW50IG1vZGlmaWNhdGlvbjxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHBhc3MgPGNvZGU+c2VlZDwvY29kZT4gdG8gdGhlIGN0b3IgdGhlbiBtb2RpZnkgaXQ8YnI+CisgICAgICogRXhwZWN0ZWQ6IGdldFNlZWQoKSBtdXN0IHJldHVybiB1bm1vZGlmaWVkIGFycmF5CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVsbGlwdGljQ3VydmVFQ0ZpZWxkQmlnSW50ZWdlckJpZ0ludGVnZXJieXRlQXJyYXkwNSgpIHsKKyAgICAgICAgRUNGaWVsZEYybSBmID0gbmV3IEVDRmllbGRGMm0oNSk7CisgICAgICAgIEJpZ0ludGVnZXIgYSA9IEJpZ0ludGVnZXIudmFsdWVPZigwTCk7CisgICAgICAgIEJpZ0ludGVnZXIgYiA9IEJpZ0ludGVnZXIudmFsdWVPZigxOUwpOworICAgICAgICBieXRlW10gc2VlZCA9IG5ldyBieXRlWzI0XTsKKyAgICAgICAgYnl0ZVtdIHNlZWRDb3B5ID0gc2VlZC5jbG9uZSgpOworICAgICAgICBFbGxpcHRpY0N1cnZlIGMgPSBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiLCBzZWVkQ29weSk7CisgICAgICAgIC8vIG1vZGlmeSBhcnJheSBwYXNzZWQKKyAgICAgICAgc2VlZENvcHlbMF0gPSAoYnl0ZSkgMTsKKyAgICAgICAgLy8gY2hlY2sgdGhhdCBhYm92ZSBtb2RpZmljYXRpb24gZGlkIG5vdCBjaGFuZ2VkCisgICAgICAgIC8vIGludGVybmFsIHN0YXRlIG9mIHRlc3Qgb2JqZWN0CisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhzZWVkLCBjLmdldFNlZWQoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPkVsbGlwdGljQ3VydmUoRUNGaWVsZCwgQmlnSW50ZWdlciwgQmlnSW50ZWdlcik8L2NvZGU+CisgICAgICogY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiBjcmVhdGVzIGluc3RhbmNlIG9mIEVsbGlwdGljQ3VydmU8YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiB2YWxpZCBwYXJhbWV0ZXJzIHBhc3NlZCwgZmllbGQgdHlwZSBpcyBFQ0ZpZWxkRnA8YnI+CisgICAgICogRXhwZWN0ZWQ6IG11c3QgcGFzcyB3aXRob3V0IGFueSBleGNlcHRpb25zCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEVsbGlwdGljQ3VydmVFQ0ZpZWxkQmlnSW50ZWdlckJpZ0ludGVnZXIwMSgpIHsKKyAgICAgICAgLy8gdGVzdCBjYXNlIDEgcGFyYW1ldGVycyBzZXQKKyAgICAgICAgRUNGaWVsZEZwIGYgPSBuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigyM0wpKTsKKyAgICAgICAgQmlnSW50ZWdlciBhID0gQmlnSW50ZWdlci5PTkU7CisgICAgICAgIEJpZ0ludGVnZXIgYiA9IEJpZ0ludGVnZXIudmFsdWVPZigxOUwpOworICAgICAgICAvLyBwZXJmb3JtIHRlc3QgY2FzZSAxCisgICAgICAgIG5ldyBFbGxpcHRpY0N1cnZlKGYsIGEsIGIpOworCisgICAgICAgIC8vIHRlc3QgY2FzZSAyIHBhcmFtZXRlcnMgc2V0CisgICAgICAgIEVDRmllbGRGMm0gZjEgPSBuZXcgRUNGaWVsZEYybSg1KTsKKyAgICAgICAgYSA9IEJpZ0ludGVnZXIuWkVSTzsKKyAgICAgICAgYiA9IEJpZ0ludGVnZXIudmFsdWVPZigyM0wpOworICAgICAgICAvLyBwZXJmb3JtIHRlc3QgY2FzZSAyCisgICAgICAgIG5ldyBFbGxpcHRpY0N1cnZlKGYxLCBhLCBiKTsKKworICAgICAgICAvLyB0ZXN0IGNhc2UgMyBwYXJhbWV0ZXJzIHNldCwKKyAgICAgICAgLy8gdGhlIHNlZWQgcGFyYW1ldGVyIG1heSBiZSBudWxsCisgICAgICAgIGYgPSBuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigyM0wpKTsKKyAgICAgICAgYSA9IEJpZ0ludGVnZXIuT05FOworICAgICAgICBiID0gQmlnSW50ZWdlci52YWx1ZU9mKDE5TCk7CisgICAgICAgIC8vIHBlcmZvcm0gdGVzdCBjYXNlIDMKKyAgICAgICAgbmV3IEVsbGlwdGljQ3VydmUoZiwgYSwgYik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+RWxsaXB0aWNDdXJ2ZShFQ0ZpZWxkLCBCaWdJbnRlZ2VyLCBCaWdJbnRlZ2VyKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IHRocm93cyA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaWYgPGNvZGU+ZmllbGQ8L2NvZGU+LAorICAgICAqIDxjb2RlPmE8L2NvZGU+IG9yIDxjb2RlPmI8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+PGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogcGFzcyA8Y29kZT5udWxsPC9jb2RlPiBhcyBtZW50aW9uZWQgcGFyYW1ldGVyczxicj4KKyAgICAgKiBFeHBlY3RlZDogbXVzdCB0aHJvdyA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RWxsaXB0aWNDdXJ2ZUVDRmllbGRCaWdJbnRlZ2VyQmlnSW50ZWdlcjAyKCkgeworICAgICAgICAvLyB0ZXN0IGNhc2UgMSBwYXJhbWV0ZXJzIHNldAorICAgICAgICBFQ0ZpZWxkRnAgZiA9IG51bGw7CisgICAgICAgIEJpZ0ludGVnZXIgYSA9IEJpZ0ludGVnZXIuT05FOworICAgICAgICBCaWdJbnRlZ2VyIGIgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoMTlMKTsKKworICAgICAgICAvLyBwZXJmb3JtIHRlc3QgY2FzZSAxCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiKTsKKyAgICAgICAgICAgIGZhaWwoIiMxOiBFeHBlY3RlZCBOUEUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBvaykge30KKworICAgICAgICAvLyB0ZXN0IGNhc2UgMiBwYXJhbWV0ZXJzIHNldCwKKyAgICAgICAgZiA9IG5ldyBFQ0ZpZWxkRnAoQmlnSW50ZWdlci52YWx1ZU9mKDIzTCkpOworICAgICAgICBhID0gbnVsbDsKKyAgICAgICAgYiA9IEJpZ0ludGVnZXIudmFsdWVPZigxOUwpOworICAgICAgICAvLyBwZXJmb3JtIHRlc3QgY2FzZSAyCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiKTsKKyAgICAgICAgICAgIGZhaWwoIiMyOiBFeHBlY3RlZCBOUEUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBvaykge30KKworICAgICAgICAvLyB0ZXN0IGNhc2UgMyBwYXJhbWV0ZXJzIHNldCwKKyAgICAgICAgZiA9IG5ldyBFQ0ZpZWxkRnAoQmlnSW50ZWdlci52YWx1ZU9mKDIzTCkpOworICAgICAgICBhID0gQmlnSW50ZWdlci5PTkU7CisgICAgICAgIGIgPSBudWxsOworICAgICAgICAvLyBwZXJmb3JtIHRlc3QgY2FzZSAzCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiKTsKKyAgICAgICAgICAgIGZhaWwoIiMzOiBFeHBlY3RlZCBOUEUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBvaykge30KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMzIGZvciA8Y29kZT5FbGxpcHRpY0N1cnZlKEVDRmllbGQsIEJpZ0ludGVnZXIsIEJpZ0ludGVnZXIpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogdGhyb3dzIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaWYKKyAgICAgKiA8Y29kZT5hPC9jb2RlPiBvciA8Y29kZT5iPC9jb2RlPiBpcyBub3QgPGNvZGU+bnVsbDwvY29kZT4gYW5kIG5vdCBpbgorICAgICAqIHRoZSA8Y29kZT5maWVsZDwvY29kZT48YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiBwYXNzIDxjb2RlPmE8L2NvZGU+LCA8Y29kZT5iPC9jb2RlPiB3aGljaCBhcmUKKyAgICAgKiBub3QgaW4gdGhlIDxjb2RlPmZpZWxkPC9jb2RlPiBvZiB0eXBlIDxjb2RlPkVDRmllbGRGcDwvY29kZT48YnI+CisgICAgICogRXhwZWN0ZWQ6IG11c3QgdGhyb3cgPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFbGxpcHRpY0N1cnZlRUNGaWVsZEJpZ0ludGVnZXJCaWdJbnRlZ2VyMDMoKSB7CisgICAgICAgIC8vIHRlc3QgY2FzZSAxIHBhcmFtZXRlcnMgc2V0LAorICAgICAgICAvLyBhIGlzIG5vdCBpbiBmaWVsZAorICAgICAgICBFQ0ZpZWxkRnAgZiA9IG5ldyBFQ0ZpZWxkRnAoQmlnSW50ZWdlci52YWx1ZU9mKDIzTCkpOworICAgICAgICBCaWdJbnRlZ2VyIGEgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoMjRMKTsKKyAgICAgICAgQmlnSW50ZWdlciBiID0gQmlnSW50ZWdlci52YWx1ZU9mKDE5TCk7CisKKyAgICAgICAgLy8gcGVyZm9ybSB0ZXN0IGNhc2UgMQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEVsbGlwdGljQ3VydmUoZiwgYSwgYik7CisgICAgICAgICAgICBmYWlsKCIjMTogRXhwZWN0ZWQgSUFFIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG9rKSB7fQorCisgICAgICAgIC8vIHRlc3QgY2FzZSAxLjEgcGFyYW1ldGVycyBzZXQsCisgICAgICAgIC8vIGEgaXMgbm90IGluIGZpZWxkCisgICAgICAgIGYgPSBuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigyM0wpKTsKKyAgICAgICAgYSA9IEJpZ0ludGVnZXIudmFsdWVPZigyM0wpOworICAgICAgICBiID0gQmlnSW50ZWdlci52YWx1ZU9mKDE5TCk7CisgICAgICAgIC8vIHBlcmZvcm0gdGVzdCBjYXNlIDEuMQorICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEVsbGlwdGljQ3VydmUoZiwgYSwgYik7CisgICAgICAgICAgICBmYWlsKCIjMS4xOiBFeHBlY3RlZCBJQUUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gb2spIHt9CisKKyAgICAgICAgLy8gdGVzdCBjYXNlIDIgcGFyYW1ldGVycyBzZXQsCisgICAgICAgIC8vIGIgaXMgbm90IGluIGZpZWxkCisgICAgICAgIGYgPSBuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigyM0wpKTsKKyAgICAgICAgYSA9IEJpZ0ludGVnZXIudmFsdWVPZigxOUwpOworICAgICAgICBiID0gQmlnSW50ZWdlci52YWx1ZU9mKDI0TCk7CisgICAgICAgIC8vIHBlcmZvcm0gdGVzdCBjYXNlIDIKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFbGxpcHRpY0N1cnZlKGYsIGEsIGIpOworICAgICAgICAgICAgZmFpbCgiIzI6IEV4cGVjdGVkIElBRSBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBvaykge30KKworICAgICAgICAvLyB0ZXN0IGNhc2UgMyBwYXJhbWV0ZXJzIHNldCwKKyAgICAgICAgLy8gYm90aCBhIGFuZCBiIGFyZSBub3QgaW4gZmllbGQKKyAgICAgICAgZiA9IG5ldyBFQ0ZpZWxkRnAoQmlnSW50ZWdlci52YWx1ZU9mKDIzTCkpOworICAgICAgICBhID0gQmlnSW50ZWdlci52YWx1ZU9mKDI1TCk7CisgICAgICAgIGIgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoMjQwTCk7CisgICAgICAgIC8vIHBlcmZvcm0gdGVzdCBjYXNlIDMKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFbGxpcHRpY0N1cnZlKGYsIGEsIGIpOworICAgICAgICAgICAgZmFpbCgiIzM6IEV4cGVjdGVkIElBRSBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBvaykge30KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM0IGZvciA8Y29kZT5FbGxpcHRpY0N1cnZlKEVDRmllbGQsIEJpZ0ludGVnZXIsIEJpZ0ludGVnZXIsIGJ5dGVbXSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiB0aHJvd3MgPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpZgorICAgICAqIDxjb2RlPmE8L2NvZGU+IG9yIDxjb2RlPmI8L2NvZGU+IGlzIG5vdCA8Y29kZT5udWxsPC9jb2RlPiBhbmQgbm90IGluCisgICAgICogdGhlIDxjb2RlPmZpZWxkPC9jb2RlPjxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IHBhc3MgPGNvZGU+YTwvY29kZT4sIDxjb2RlPmI8L2NvZGU+IHdoaWNoIGFyZQorICAgICAqIG5vdCBpbiB0aGUgPGNvZGU+ZmllbGQ8L2NvZGU+IG9mIHR5cGUgPGNvZGU+RUNGaWVsZEYybTwvY29kZT48YnI+CisgICAgICogRXhwZWN0ZWQ6IG11c3QgdGhyb3cgPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFbGxpcHRpY0N1cnZlRUNGaWVsZEJpZ0ludGVnZXJCaWdJbnRlZ2VyMDQoKSB7CisgICAgICAgIC8vIHRlc3QgY2FzZSAxIHBhcmFtZXRlcnMgc2V0LAorICAgICAgICAvLyBhIGlzIG5vdCBpbiBmaWVsZAorICAgICAgICBFQ0ZpZWxkRjJtIGYgPSBuZXcgRUNGaWVsZEYybSg1KTsKKyAgICAgICAgQmlnSW50ZWdlciBhID0gQmlnSW50ZWdlci52YWx1ZU9mKDMyTCk7CisgICAgICAgIEJpZ0ludGVnZXIgYiA9IEJpZ0ludGVnZXIudmFsdWVPZigxOUwpOworICAgICAgICAvLyBwZXJmb3JtIHRlc3QgY2FzZSAxCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiKTsKKyAgICAgICAgICAgIGZhaWwoIiMxOiBFeHBlY3RlZCBJQUUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gb2spIHt9CisKKyAgICAgICAgLy8gdGVzdCBjYXNlIDIgcGFyYW1ldGVycyBzZXQsCisgICAgICAgIC8vIGIgaXMgbm90IGluIGZpZWxkCisgICAgICAgIGYgPSBuZXcgRUNGaWVsZEYybSg1KTsKKyAgICAgICAgYSA9IEJpZ0ludGVnZXIudmFsdWVPZigxOUwpOworICAgICAgICBiID0gQmlnSW50ZWdlci52YWx1ZU9mKDMyTCk7CisgICAgICAgIC8vIHBlcmZvcm0gdGVzdCBjYXNlIDIKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBFbGxpcHRpY0N1cnZlKGYsIGEsIGIpOworICAgICAgICAgICAgZmFpbCgiIzI6IEV4cGVjdGVkIElBRSBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBvaykge30KKworICAgICAgICAvLyB0ZXN0IGNhc2UgMyBwYXJhbWV0ZXJzIHNldCwKKyAgICAgICAgLy8gYm90aCBhIGFuZCBiIGFyZSBub3QgaW4gZmllbGQKKyAgICAgICAgZiA9IG5ldyBFQ0ZpZWxkRjJtKDUpOworICAgICAgICBhID0gQmlnSW50ZWdlci52YWx1ZU9mKDMyTCk7CisgICAgICAgIGIgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoNDNMKTsKKyAgICAgICAgLy8gcGVyZm9ybSB0ZXN0IGNhc2UgMworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IEVsbGlwdGljQ3VydmUoZiwgYSwgYik7CisgICAgICAgICAgICBmYWlsKCIjMzogRXhwZWN0ZWQgSUFFIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIG9rKSB7fQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEEoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBjb2VmZmljaWVudCA8Y29kZT5hPC9jb2RlPjxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IDxjb2RlPkVDRmllbGRGMm08L2NvZGU+IGluc3RhbmNlCisgICAgICogY3JlYXRlZCB1c2luZyB2YWxpZCBwYXJhbWV0ZXJzPGJyPgorICAgICAqIEV4cGVjdGVkOiBtdXN0IHJldHVybiBjb2VmZmljaWVudCA8Y29kZT5hPC9jb2RlPiB3aGljaCBpcyBlcXVhbAorICAgICAqIHRvIHRoZSBvbmUgcGFzc2VkIHRvIHRoZSBjb25zdHJ1Y3RvcjsgKGJvdGggbXVzdCByZWZlcgorICAgICAqIHRoZSBzYW1lIG9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0QSgpIHsKKyAgICAgICAgRUNGaWVsZEYybSBmID0gbmV3IEVDRmllbGRGMm0oNSk7CisgICAgICAgIEJpZ0ludGVnZXIgYSA9IEJpZ0ludGVnZXIudmFsdWVPZig1TCk7CisgICAgICAgIEJpZ0ludGVnZXIgYiA9IEJpZ0ludGVnZXIudmFsdWVPZigxOUwpOworICAgICAgICBFbGxpcHRpY0N1cnZlIGMgPSBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGEsIGMuZ2V0QSgpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShhLCBjLmdldEEoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogamF2YS9zZWN1cml0eS9zcGVjL0VsbGlwdGljQ3VydmUjRWxsaXB0aWNDdXJ2ZShFY0ZpZWxkLEJpZ0ludGVnZXIsQmlnSW50ZWdlcikKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RWxsaXB0aWNDdXJ2ZUVDRmllbGRCaWdJbnRlZ2VyQmlnSW50ZWdlcjA1KCkgeworICAgICAgICAvLyBSZWdyZXNzaW9uIGZvciBIYXJtb255LTczMQorICAgICAgICBFbGxpcHRpY0N1cnZlIGVjID0gbmV3IEVsbGlwdGljQ3VydmUobmV3IHRlc3RFQ0ZpZWxkKCksIEJpZ0ludGVnZXIKKyAgICAgICAgICAgICAgICAudmFsdWVPZig0TCksIEJpZ0ludGVnZXIuT05FKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3QgYSIsIGVjLmdldEEoKSwgQmlnSW50ZWdlci52YWx1ZU9mKDRMKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaW5jb3JyZWN0IGIiLCBlYy5nZXRCKCksIEJpZ0ludGVnZXIuT05FKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJpbmNvcnJlY3Qgc2l6ZSIsIGVjLmdldEZpZWxkKCkuZ2V0RmllbGRTaXplKCksIDIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEIoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBjb2VmZmljaWVudCA8Y29kZT5iPC9jb2RlPjxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IDxjb2RlPkVDRmllbGRGMm08L2NvZGU+IGluc3RhbmNlCisgICAgICogY3JlYXRlZCB1c2luZyB2YWxpZCBwYXJhbWV0ZXJzPGJyPgorICAgICAqIEV4cGVjdGVkOiBtdXN0IHJldHVybiBjb2VmZmljaWVudCA8Y29kZT5iPC9jb2RlPiB3aGljaCBpcyBlcXVhbAorICAgICAqIHRvIHRoZSBvbmUgcGFzc2VkIHRvIHRoZSBjb25zdHJ1Y3RvcjsgKGJvdGggbXVzdCByZWZlcgorICAgICAqIHRoZSBzYW1lIG9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0QigpIHsKKyAgICAgICAgRUNGaWVsZEYybSBmID0gbmV3IEVDRmllbGRGMm0oNSk7CisgICAgICAgIEJpZ0ludGVnZXIgYSA9IEJpZ0ludGVnZXIudmFsdWVPZig1TCk7CisgICAgICAgIEJpZ0ludGVnZXIgYiA9IEJpZ0ludGVnZXIudmFsdWVPZigxOUwpOworICAgICAgICBFbGxpcHRpY0N1cnZlIGMgPSBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGIsIGMuZ2V0QigpKTsKKyAgICAgICAgYXNzZXJ0U2FtZShiLCBjLmdldEIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0RmllbGQoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyA8Y29kZT5maWVsZDwvY29kZT48YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiA8Y29kZT5FQ0ZpZWxkRjJtPC9jb2RlPiBpbnN0YW5jZQorICAgICAqIGNyZWF0ZWQgdXNpbmcgdmFsaWQgcGFyYW1ldGVyczxicj4KKyAgICAgKiBFeHBlY3RlZDogbXVzdCByZXR1cm4gPGNvZGU+ZmllbGQ8L2NvZGU+IHdoaWNoIGlzIGVxdWFsCisgICAgICogdG8gdGhlIG9uZSBwYXNzZWQgdG8gdGhlIGNvbnN0cnVjdG9yOyAoYm90aCBtdXN0IHJlZmVyCisgICAgICogdGhlIHNhbWUgb2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRGaWVsZCgpIHsKKyAgICAgICAgRUNGaWVsZEYybSBmID0gbmV3IEVDRmllbGRGMm0oNSk7CisgICAgICAgIEJpZ0ludGVnZXIgYSA9IEJpZ0ludGVnZXIudmFsdWVPZig1TCk7CisgICAgICAgIEJpZ0ludGVnZXIgYiA9IEJpZ0ludGVnZXIudmFsdWVPZigxOUwpOworICAgICAgICBFbGxpcHRpY0N1cnZlIGMgPSBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGYsIGMuZ2V0RmllbGQoKSk7CisgICAgICAgIGFzc2VydFNhbWUoZiwgYy5nZXRGaWVsZCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5nZXRTZWVkKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgPGNvZGU+c2VlZDwvY29kZT48YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiA8Y29kZT5FQ0ZpZWxkRjJtPC9jb2RlPiBpbnN0YW5jZQorICAgICAqIGNyZWF0ZWQgdXNpbmcgdmFsaWQgcGFyYW1ldGVyczxicj4KKyAgICAgKiBFeHBlY3RlZDogbXVzdCByZXR1cm4gPGNvZGU+c2VlZDwvY29kZT4gd2hpY2ggaXMgZXF1YWwKKyAgICAgKiB0byB0aGUgb25lIHBhc3NlZCB0byB0aGUgY29uc3RydWN0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0U2VlZDAxKCkgeworICAgICAgICBFQ0ZpZWxkRnAgZiA9IG5ldyBFQ0ZpZWxkRnAoQmlnSW50ZWdlci52YWx1ZU9mKDIzTCkpOworICAgICAgICBCaWdJbnRlZ2VyIGEgPSBCaWdJbnRlZ2VyLk9ORTsKKyAgICAgICAgQmlnSW50ZWdlciBiID0gQmlnSW50ZWdlci52YWx1ZU9mKDE5TCk7CisgICAgICAgIGJ5dGVbXSBzZWVkID0gbmV3IGJ5dGVbMjRdOworICAgICAgICBFbGxpcHRpY0N1cnZlIGMgPSBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiLCBzZWVkKTsKKyAgICAgICAgYnl0ZVtdIHNlZWRSZXQgPSBjLmdldFNlZWQoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChzZWVkUmV0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKHNlZWQsIHNlZWRSZXQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvciA8Y29kZT5nZXRTZWVkKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybmVkIGFycmF5IGlzIGNvcGllZCB0byBwcmV2ZW50IHN1YnNlcXVlbnQgbW9kaWZpY2F0aW9uPGJyPgorICAgICAqIFRlc3QgcHJlY29uZGl0aW9uczogPGNvZGU+RUNGaWVsZEYybTwvY29kZT4gaW5zdGFuY2UKKyAgICAgKiBjcmVhdGVkIHVzaW5nIHZhbGlkIHBhcmFtZXRlcnM7IDxjb2RlPmdldFNlZWQoKTwvY29kZT4KKyAgICAgKiBjYWxsZWQgYW5kIHRoZW4gcmV0dXJuZWQgYXJyYXkgbW9kaWZpZWQ8YnI+CisgICAgICogRXhwZWN0ZWQ6IGludGVybmFsIHN0YXRlIG11c3Qgbm90IGJlIGFmZmVjdGVkIGJ5IHRoZSBtb2RpZmljYXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0U2VlZDAyKCkgeworICAgICAgICBFQ0ZpZWxkRnAgZiA9IG5ldyBFQ0ZpZWxkRnAoQmlnSW50ZWdlci52YWx1ZU9mKDIzTCkpOworICAgICAgICBCaWdJbnRlZ2VyIGEgPSBCaWdJbnRlZ2VyLk9ORTsKKyAgICAgICAgQmlnSW50ZWdlciBiID0gQmlnSW50ZWdlci52YWx1ZU9mKDE5TCk7CisgICAgICAgIGJ5dGVbXSBzZWVkID0gbmV3IGJ5dGVbMjRdOworICAgICAgICBFbGxpcHRpY0N1cnZlIGMgPSBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiLCBzZWVkLmNsb25lKCkpOworICAgICAgICBieXRlW10gc2VlZFJldCA9IGMuZ2V0U2VlZCgpOworICAgICAgICAvLyBtb2RpZnkgcmV0dXJuZWQgYXJyYXkKKyAgICAgICAgc2VlZFJldFswXSA9IChieXRlKSAxOworICAgICAgICAvLyBjaGVjayB0aGF0IGFib3ZlIG1vZGlmaWNhdGlvbiBkaWQgbm90IGNoYW5nZWQKKyAgICAgICAgLy8gaW50ZXJuYWwgc3RhdGUgb2YgdGVzdCBvYmplY3QKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKHNlZWQsIGMuZ2V0U2VlZCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMyBmb3IgPGNvZGU+Z2V0U2VlZCgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5lZCBhcnJheSBpcyBjb3BpZWQgdG8gcHJldmVudCBzdWJzZXF1ZW50IG1vZGlmaWNhdGlvbjxicj4KKyAgICAgKiBUZXN0IHByZWNvbmRpdGlvbnM6IDxjb2RlPkVDRmllbGRGMm08L2NvZGU+IGluc3RhbmNlCisgICAgICogY3JlYXRlZCB1c2luZyB2YWxpZCBwYXJhbWV0ZXJzPGJyPgorICAgICAqIEV4cGVjdGVkOiByZXBlYXRlZCBtZXRob2QgY2FsbHMgbXVzdCByZXR1cm4gZGlmZmVyZW50IHJlZnMKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0U2VlZDAzKCkgeworICAgICAgICBFQ0ZpZWxkRnAgZiA9IG5ldyBFQ0ZpZWxkRnAoQmlnSW50ZWdlci52YWx1ZU9mKDIzTCkpOworICAgICAgICBCaWdJbnRlZ2VyIGEgPSBCaWdJbnRlZ2VyLk9ORTsKKyAgICAgICAgQmlnSW50ZWdlciBiID0gQmlnSW50ZWdlci52YWx1ZU9mKDE5TCk7CisgICAgICAgIGJ5dGVbXSBzZWVkID0gbmV3IGJ5dGVbMjRdOworICAgICAgICBFbGxpcHRpY0N1cnZlIGMgPSBuZXcgRWxsaXB0aWNDdXJ2ZShmLCBhLCBiLCBzZWVkKTsKKyAgICAgICAgYy5nZXRTZWVkKCk7CisgICAgICAgIGFzc2VydE5vdFNhbWUoYy5nZXRTZWVkKCksIGMuZ2V0U2VlZCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBqYXZhLnNlY3VyaXR5LnNwZWMuRWxsaXB0aWNDdXJ2ZSNnZXRTZWVkKCkKKyAgICAgKiBBc3NlcnRpb246IG51bGwgaWYgbm90IHNwZWNpZmllZAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRTZWVkMDQoKSB7CisgICAgICAgIC8vUmVncmVzc2lvbiBmb3IgSEFSTU9OWS03MzIKKyAgICAgICAgRUNGaWVsZEZwIGYgPSBuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigyM0wpKTsKKyAgICAgICAgQmlnSW50ZWdlciBhID0gQmlnSW50ZWdlci5PTkU7CisgICAgICAgIGFzc2VydE51bGwobmV3IEVsbGlwdGljQ3VydmUoZiwgYSwgYSkuZ2V0U2VlZCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5lcXVhbHMoT2JqZWN0IG90aGVyKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJuIHRydWUgaWYgdGhpcyBhbmQgb3RoZXIgb2JqZWN0cyBhcmUgZXF1YWw8YnI+CisgICAgICogVGVzdCBwcmVjb25kaXRpb25zOiBzZWUgdGVzdCBjb21tZW50czxicj4KKyAgICAgKiBFeHBlY3RlZDogYWxsIG9iamVjdHMgaW4gdGhpcyB0ZXN0IG11c3QgYmUgZXF1YWwKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RXF1YWxzT2JqZWN0MDEoKSB7CisgICAgICAgIC8vIHRlc3QgY2FzZSAxOiBtdXN0IGJlIGVxdWFsIHRvIGl0c2VsZgorICAgICAgICBFbGxpcHRpY0N1cnZlIGMyID0gbnVsbCwgYzEgPSBuZXcgRWxsaXB0aWNDdXJ2ZShuZXcgRUNGaWVsZEZwKAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZigyM0wpKSwgQmlnSW50ZWdlci5PTkUsIEJpZ0ludGVnZXIKKyAgICAgICAgICAgICAgICAudmFsdWVPZigxOUwpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjMS5lcXVhbHMoYzEpKTsKKworICAgICAgICAvLyB0ZXN0IGNhc2UgMjogZXF1YWwgb2JqZWN0cworICAgICAgICBjMSA9IG5ldyBFbGxpcHRpY0N1cnZlKG5ldyBFQ0ZpZWxkRnAoQmlnSW50ZWdlci52YWx1ZU9mKDIzTCkpLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLCBCaWdJbnRlZ2VyLnZhbHVlT2YoMTlMKSk7CisgICAgICAgIGMyID0gbmV3IEVsbGlwdGljQ3VydmUobmV3IEVDRmllbGRGcChCaWdJbnRlZ2VyLnZhbHVlT2YoMjNMKSksCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci52YWx1ZU9mKDFMKSwgQmlnSW50ZWdlci52YWx1ZU9mKDE5TCkpOworICAgICAgICBhc3NlcnRUcnVlKGMxLmVxdWFscyhjMikgJiYgYzIuZXF1YWxzKGMxKSk7CisKKyAgICAgICAgLy8gdGVzdCBjYXNlIDM6IGVxdWFsIG9iamVjdHMgd2l0aCBzZWVkIG5vdCBudWxsCisgICAgICAgIGMxID0gbmV3IEVsbGlwdGljQ3VydmUobmV3IEVDRmllbGRGcChCaWdJbnRlZ2VyLnZhbHVlT2YoMjNMKSksCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsIEJpZ0ludGVnZXIudmFsdWVPZigxOUwpLCBuZXcgYnl0ZVsyNF0pOworICAgICAgICBjMiA9IG5ldyBFbGxpcHRpY0N1cnZlKG5ldyBFQ0ZpZWxkRnAoQmlnSW50ZWdlci52YWx1ZU9mKDIzTCkpLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZigxTCksIEJpZ0ludGVnZXIudmFsdWVPZigxOUwpLCBuZXcgYnl0ZVsyNF0pOworICAgICAgICBhc3NlcnRUcnVlKGMxLmVxdWFscyhjMikgJiYgYzIuZXF1YWxzKGMxKSk7CisKKyAgICAgICAgLy8gdGVzdCBjYXNlIDQ6IGVxdWFsIG9iamVjdCBhbmQgc3ViY2xhc3Mgb2JqZWN0CisgICAgICAgIGMxID0gbmV3IEVsbGlwdGljQ3VydmUobmV3IEVDRmllbGRGcChCaWdJbnRlZ2VyLnZhbHVlT2YoMjNMKSksCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsIEJpZ0ludGVnZXIudmFsdWVPZigxOUwpLCBuZXcgYnl0ZVsyNF0pOworICAgICAgICBNeUVsbGlwdGljQ3VydmUgYzMgPSBuZXcgTXlFbGxpcHRpY0N1cnZlKG5ldyBFQ0ZpZWxkRnAoQmlnSW50ZWdlcgorICAgICAgICAgICAgICAgIC52YWx1ZU9mKDIzTCkpLCBCaWdJbnRlZ2VyLk9ORSwgQmlnSW50ZWdlci52YWx1ZU9mKDE5TCksCisgICAgICAgICAgICAgICAgbmV3IGJ5dGVbMjRdKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjMS5lcXVhbHMoYzMpICYmIGMzLmVxdWFscyhjMSkpOworCisgICAgICAgIC8vIHRlc3QgY2FzZSA1OiBlcXVhbCBvYmplY3RzCisgICAgICAgIGMxID0gbmV3IEVsbGlwdGljQ3VydmUobmV3IEVDRmllbGRGcChCaWdJbnRlZ2VyLnZhbHVlT2YoMjNMKSksCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsIEJpZ0ludGVnZXIudmFsdWVPZigxOUwpKTsKKyAgICAgICAgYzIgPSBuZXcgRWxsaXB0aWNDdXJ2ZShuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigyM0wpKSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoMUwpLCBCaWdJbnRlZ2VyLnZhbHVlT2YoMTlMKSwgbnVsbCk7CisgICAgICAgIGFzc2VydFRydWUoYzEuZXF1YWxzKGMyKSAmJiBjMi5lcXVhbHMoYzEpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5oYXNoQ29kZSgpPC9jb2RlPiBtZXRob2QuPGJyPgorICAgICAqCisgICAgICogQXNzZXJ0aW9uOiBtdXN0IHJldHVybiB0aGUgc2FtZSB2YWx1ZSBpZiBpbnZva2VkCisgICAgICogcmVwZWF0ZWRseSBvbiB0aGUgc2FtZSBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEhhc2hDb2RlMDEoKSB7CisgICAgICAgIGludCBoYyA9IDA7CisgICAgICAgIEVsbGlwdGljQ3VydmUgZiA9IG5ldyBFbGxpcHRpY0N1cnZlKG5ldyBFQ0ZpZWxkRnAoQmlnSW50ZWdlcgorICAgICAgICAgICAgICAgIC52YWx1ZU9mKDIzTCkpLCBCaWdJbnRlZ2VyLk9ORSwgQmlnSW50ZWdlci52YWx1ZU9mKDE5TCksCisgICAgICAgICAgICAgICAgbmV3IGJ5dGVbMjRdKTsKKyAgICAgICAgaGMgPSBmLmhhc2hDb2RlKCk7CisgICAgICAgIGFzc2VydFRydWUoaGMgPT0gZi5oYXNoQ29kZSgpICYmIGhjID09IGYuaGFzaENvZGUoKQorICAgICAgICAgICAgICAgICYmIGhjID09IGYuaGFzaENvZGUoKSAmJiBoYyA9PSBmLmhhc2hDb2RlKCkKKyAgICAgICAgICAgICAgICAmJiBoYyA9PSBmLmhhc2hDb2RlKCkgJiYgaGMgPT0gZi5oYXNoQ29kZSgpCisgICAgICAgICAgICAgICAgJiYgaGMgPT0gZi5oYXNoQ29kZSgpICYmIGhjID09IGYuaGFzaENvZGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+aGFzaENvZGUoKTwvY29kZT4gbWV0aG9kLjxicj4KKyAgICAgKgorICAgICAqIEFzc2VydGlvbjogbXVzdCByZXR1cm4gdGhlIHNhbWUgdmFsdWUgaWYgaW52b2tlZAorICAgICAqIG9uIGVxdWFsIChhY2NvcmRpbmcgdG8gdGhlIDxjb2RlPmVxdWFscyhPYmplY3QpPC9jb2RlPiBtZXRob2QpIG9iamVjdHMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEhhc2hDb2RlMDIoKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhuZXcgRWxsaXB0aWNDdXJ2ZShuZXcgRUNGaWVsZEZwKEJpZ0ludGVnZXIudmFsdWVPZigyM0wpKSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwgQmlnSW50ZWdlci52YWx1ZU9mKDE5TCksIG5ldyBieXRlWzI0XSkKKyAgICAgICAgICAgICAgICAuaGFzaENvZGUoKSwgbmV3IEVsbGlwdGljQ3VydmUobmV3IEVDRmllbGRGcChCaWdJbnRlZ2VyCisgICAgICAgICAgICAgICAgLnZhbHVlT2YoMjNMKSksIEJpZ0ludGVnZXIuT05FLCBCaWdJbnRlZ2VyLnZhbHVlT2YoMTlMKSwKKyAgICAgICAgICAgICAgICBuZXcgYnl0ZVsyNF0pLmhhc2hDb2RlKCkpOworICAgIH0KKworICAgIC8vCisgICAgLy8gUHJpdmF0ZSBzdHVmZgorICAgIC8vCisKKyAgICBjbGFzcyB0ZXN0RUNGaWVsZCBpbXBsZW1lbnRzIEVDRmllbGQgeworCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaXplKCkgeworICAgICAgICAgICAgcmV0dXJuIDI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbGxpcHRpY0N1cnZlIHN1YmNsYXNzIGZvciB0ZXN0aW5nIHB1cnBvc2VzCisgICAgICoKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBNeUVsbGlwdGljQ3VydmUgZXh0ZW5kcyBFbGxpcHRpY0N1cnZlIHsKKworICAgICAgICBNeUVsbGlwdGljQ3VydmUoRUNGaWVsZCBmLCBCaWdJbnRlZ2VyIGEsIEJpZ0ludGVnZXIgYiwgYnl0ZVtdIHNlZWQpIHsKKyAgICAgICAgICAgIHN1cGVyKGYsIGEsIGIsIHNlZWQpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvRW5jb2RlZEtleVNwZWMyVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvRW5jb2RlZEtleVNwZWMyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVkYjgwMWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9FbmNvZGVkS2V5U3BlYzJUZXN0LmphdmEKQEAgLTAsMCArMSw4NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5RmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5EU0FQcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy5EU0FQdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkVuY29kZWRLZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5QS0NTOEVuY29kZWRLZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5YNTA5RW5jb2RlZEtleVNwZWM7CisKK3B1YmxpYyBjbGFzcyBFbmNvZGVkS2V5U3BlYzJUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogamF2YS5zZWN1cml0eS5zcGVjLkVuY29kZWRLZXlTcGVjI2dldEVuY29kZWQoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RfZ2V0RW5jb2RlZCgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGtleUdlbiA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoIkRTQSIpOworCisgICAgICAgICAgICAgICBrZXlHZW4uaW5pdGlhbGl6ZSgxMDI0KTsKKyAgICAgICAgICAgICAgIEtleVBhaXIga2V5cyA9IGtleUdlbi5nZW5lcmF0ZUtleVBhaXIoKTsKKworCisgICAgICAgICAgICAgICBLZXlGYWN0b3J5IGZhY3QgPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKCJEU0EiKTsKKworCisgICAgICAgICAgICAgICAvLyBjaGVjayBwdWJsaWMga2V5IGVuY29kaW5nCisgICAgICAgICAgICAgICBieXRlW10gZW5jb2RlZCA9IGtleXMuZ2V0UHVibGljKCkuZ2V0RW5jb2RlZCgpOworICAgICAgICAgICAgICAgS2V5IGtleSA9IGZhY3QuZ2VuZXJhdGVQdWJsaWMobmV3IFg1MDlFbmNvZGVkS2V5U3BlYyhlbmNvZGVkKSk7CisKKyAgICAgICAgICAgICAgIGFzc2VydFRydWUoInB1YmxpYyBrZXkgZW5jb2RpbmdzIHdlcmUgZGlmZmVyZW50IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzRXF1YWwoa2V5LCBrZXlzLmdldFB1YmxpYygpKSk7CisKKyAgICAgICAgICAgICAgIC8vIGNoZWNrIHByaXZhdGUga2V5IGVuY29kaW5nCisgICAgICAgICAgICAgICBlbmNvZGVkID0ga2V5cy5nZXRQcml2YXRlKCkuZ2V0RW5jb2RlZCgpOworICAgICAgICAgICAgICAga2V5ID0gZmFjdC5nZW5lcmF0ZVByaXZhdGUobmV3IFBLQ1M4RW5jb2RlZEtleVNwZWMoZW5jb2RlZCkpOworCisgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJwcml2YXRlIGtleSBlbmNvZGluZ3Mgd2VyZSBkaWZmZXJlbnQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNFcXVhbChrZXksIGtleXMuZ2V0UHJpdmF0ZSgpKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGlzRXF1YWwoS2V5IGtleTEsIEtleSBrZXkyKSB7CisgICAgICAgIGlmIChrZXkxIGluc3RhbmNlb2YgRFNBUHVibGljS2V5ICYmIGtleTIgaW5zdGFuY2VvZiBEU0FQdWJsaWNLZXkpIHsKKyAgICAgICAgICAgIERTQVB1YmxpY0tleSBkc2ExID0gKChEU0FQdWJsaWNLZXkpIGtleTEpOworICAgICAgICAgICAgRFNBUHVibGljS2V5IGRzYTIgPSAoKERTQVB1YmxpY0tleSkga2V5Mik7CisgICAgICAgICAgICByZXR1cm4gZHNhMS5nZXRZKCkuZXF1YWxzKGRzYTIuZ2V0WSgpKQorICAgICAgICAgICAgICAgICAgICAmJiBkc2ExLmdldFBhcmFtcygpLmdldEcoKS5lcXVhbHMoZHNhMi5nZXRQYXJhbXMoKS5nZXRHKCkpCisgICAgICAgICAgICAgICAgICAgICYmIGRzYTEuZ2V0UGFyYW1zKCkuZ2V0UCgpLmVxdWFscyhkc2EyLmdldFBhcmFtcygpLmdldFAoKSkKKyAgICAgICAgICAgICAgICAgICAgJiYgZHNhMS5nZXRQYXJhbXMoKS5nZXRRKCkuZXF1YWxzKGRzYTIuZ2V0UGFyYW1zKCkuZ2V0USgpKTsKKworICAgICAgICB9IGVsc2UgaWYgKGtleTEgaW5zdGFuY2VvZiBEU0FQcml2YXRlS2V5CisgICAgICAgICAgICAgICAgJiYga2V5MiBpbnN0YW5jZW9mIERTQVByaXZhdGVLZXkpIHsKKyAgICAgICAgICAgIERTQVByaXZhdGVLZXkgZHNhMSA9ICgoRFNBUHJpdmF0ZUtleSkga2V5MSk7CisgICAgICAgICAgICBEU0FQcml2YXRlS2V5IGRzYTIgPSAoKERTQVByaXZhdGVLZXkpIGtleTIpOworICAgICAgICAgICAgcmV0dXJuIGRzYTEuZ2V0WCgpLmVxdWFscyhkc2EyLmdldFgoKSkKKyAgICAgICAgICAgICAgICAgICAgJiYgZHNhMS5nZXRQYXJhbXMoKS5nZXRHKCkuZXF1YWxzKGRzYTIuZ2V0UGFyYW1zKCkuZ2V0RygpKQorICAgICAgICAgICAgICAgICAgICAmJiBkc2ExLmdldFBhcmFtcygpLmdldFAoKS5lcXVhbHMoZHNhMi5nZXRQYXJhbXMoKS5nZXRQKCkpCisgICAgICAgICAgICAgICAgICAgICYmIGRzYTEuZ2V0UGFyYW1zKCkuZ2V0USgpLmVxdWFscyhkc2EyLmdldFBhcmFtcygpLmdldFEoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9FbmNvZGVkS2V5U3BlY1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0VuY29kZWRLZXlTcGVjVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ5N2IzN2QKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9FbmNvZGVkS2V5U3BlY1Rlc3QuamF2YQpAQCAtMCwwICsxLDEyMSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisgKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisgKiBAdmVyc2lvbiAkUmV2aXNpb24kCisgKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5zcGVjOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuc3BlYy5NeUVuY29kZWRLZXlTcGVjOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkVuY29kZWRLZXlTcGVjOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPkVuY29kZWRLZXlTcGVjPC9jb2RlPiBjbGFzcyBmaWVsZHMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgRW5jb2RlZEtleVNwZWNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogVGVzdHMgZm9yIGNvbnN0cnVjdG9yIDxjb2RlPkVuY29kZWRLZXlTcGVjKGJ5dGVbXSk8L2NvZGU+PGJyPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RFbmNvZGVkS2V5U3BlYygpIHsKKyAgICAgICAgYnl0ZVtdIGVuY29kZWRLZXkgPSBuZXcgYnl0ZVtdIHsgKGJ5dGUpIDEsIChieXRlKSAyLCAoYnl0ZSkgMywgKGJ5dGUpIDQgfTsKKyAgICAgICAgRW5jb2RlZEtleVNwZWMgZWtzID0gbmV3IE15RW5jb2RlZEtleVNwZWMoZW5jb2RlZEtleSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZSgid3JvbmcgZW5jb2RlZCBrZXkgd2FzIHJldHVybmVkIiwgQXJyYXlzLmVxdWFscyhlbmNvZGVkS2V5LAorICAgICAgICAgICAgICAgIGVrcy5nZXRFbmNvZGVkKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ3cm9uZyBuYW1lIG9mIGVuY29kaW5nIGZvcm1hdCIsICJNeSIsIGVrcy5nZXRGb3JtYXQoKSk7CisKKyAgICAgICAgZW5jb2RlZEtleSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBla3MgPSBuZXcgTXlFbmNvZGVkS2V5U3BlYyhlbmNvZGVkS2V5KTsKKyAgICAgICAgICAgIGZhaWwoImV4cGVjdGVkIE51bGxQb2ludGVyRXhjZXB0aW9uIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB0aGF0IDxjb2RlPmdldEVuY29kZWQoKTwvY29kZT4gbWV0aG9kIHJldHVybnMgdmFsaWQgYnl0ZSBhcnJheQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRFbmNvZGVkKCkgeworCisgICAgICAgIGJ5dGVbXSBlbmNvZGVkS2V5ID0gbmV3IGJ5dGVbXSB7IChieXRlKSAxLCAoYnl0ZSkgMiwgKGJ5dGUpIDMsIChieXRlKSA0IH07CisgICAgICAgIEVuY29kZWRLZXlTcGVjIG1la3MgPSBuZXcgTXlFbmNvZGVkS2V5U3BlYyhlbmNvZGVkS2V5KTsKKworICAgICAgICAvKiBHZXQgZW5jb2RlZCBrZXkgKi8KKyAgICAgICAgYnl0ZVtdIGVrID0gbWVrcy5nZXRFbmNvZGVkKCk7CisKKyAgICAgICAgLyogQ2hlY2sgcmV0dXJuZWQgYXJyYXkgKi8KKyAgICAgICAgYm9vbGVhbiByZXN1bHQgPSB0cnVlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVuY29kZWRLZXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChlbmNvZGVkS2V5W2ldICE9IGVrW2ldKSB7CisgICAgICAgICAgICAgICAgLyogaW5kaWNhdGUgZmFpbHVyZSAqLworICAgICAgICAgICAgICAgIHJlc3VsdCA9IGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8qIHBhc3NlZCAqLworICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgdGhhdCBpbnRlcm5hbCBzdGF0ZSBvZiB0aGUgb2JqZWN0IGNhbiBub3QgYmUgbW9kaWZpZWQgYnkgbW9kaWZ5aW5nCisgICAgICogaW5pdGlhbCBhcnJheSB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RJc1N0YXRlUHJlc2VydmVkMSgpIHsKKyAgICAgICAgLyogQ3JlYXRlIGluaXRpYWwgYnl0ZSBhcnJheSAqLworICAgICAgICBieXRlW10gZW5jb2RlZEtleSA9IG5ldyBieXRlW10geyAoYnl0ZSkgMSwgKGJ5dGUpIDIsIChieXRlKSAzLCAoYnl0ZSkgNCB9OworCisgICAgICAgIEVuY29kZWRLZXlTcGVjIG1la3MgPSBuZXcgTXlFbmNvZGVkS2V5U3BlYyhlbmNvZGVkS2V5KTsKKworICAgICAgICAvKiBNb2RpZnkgaW5pdGlhbCBhcnJheSdzIHZhbHVlICovCisgICAgICAgIGVuY29kZWRLZXlbM10gPSAoYnl0ZSkgNTsKKworICAgICAgICAvKiBHZXQgZW5jb2RlZCBrZXkgKi8KKyAgICAgICAgYnl0ZVtdIGVrID0gbWVrcy5nZXRFbmNvZGVkKCk7CisKKyAgICAgICAgLyogQ2hlY2sgdGhhdCBieXRlIHZhbHVlIGhhcyBub3QgYmVlbiBjaGFuZ2VkICovCisgICAgICAgIGFzc2VydFRydWUoZWtbM10gPT0gKGJ5dGUpIDQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHRoYXQgaW50ZXJuYWwgc3RhdGUgb2YgdGhlIG9iamVjdCBjYW4gbm90IGJlIG1vZGlmaWVkIHVzaW5nCisgICAgICogcmV0dXJuZWQgdmFsdWUgb2YgPGNvZGU+Z2V0RW5jb2RlZCgpPC9jb2RlPiBtZXRob2QKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0SXNTdGF0ZVByZXNlcnZlZDIoKSB7CisKKyAgICAgICAgYnl0ZVtdIGVuY29kZWRLZXkgPSBuZXcgYnl0ZVtdIHsgKGJ5dGUpIDEsIChieXRlKSAyLCAoYnl0ZSkgMywgKGJ5dGUpIDQgfTsKKyAgICAgICAgRW5jb2RlZEtleVNwZWMgbWVrcyA9IG5ldyBNeUVuY29kZWRLZXlTcGVjKGVuY29kZWRLZXkpOworCisgICAgICAgIC8qIEdldCBlbmNvZGVkIGtleSAqLworICAgICAgICBieXRlW10gZWsgPSBtZWtzLmdldEVuY29kZWQoKTsKKyAgICAgICAgLyogTW9kaWZ5IHJldHVybmVkIHZhbHVlICovCisgICAgICAgIGVrWzNdID0gKGJ5dGUpIDU7CisgICAgICAgIC8qIEdldCBlbmNvZGVkIGtleSBhZ2FpbiAqLworICAgICAgICBieXRlW10gZWsxID0gbWVrcy5nZXRFbmNvZGVkKCk7CisKKyAgICAgICAgLyogQ2hlY2sgdGhhdCBieXRlIHZhbHVlIGhhcyBub3QgYmVlbiBjaGFuZ2VkICovCisgICAgICAgIGFzc2VydFRydWUoZWsxWzNdID09IChieXRlKSA0KTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0ludmFsaWRLZXlTcGVjRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvSW52YWxpZEtleVNwZWNFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjc2NmQ3ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0ludmFsaWRLZXlTcGVjRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTc4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5JbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbjsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+SW52YWxpZEtleVNwZWNFeGNlcHRpb248L2NvZGU+IGNsYXNzIGNvbnN0cnVjdG9ycyBhbmQKKyAqIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgSW52YWxpZEtleVNwZWNFeGNlcHRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gbXNncyA9IHsKKyAgICAgICAgICAgICIiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSIgfTsKKworICAgIHByaXZhdGUgc3RhdGljIFRocm93YWJsZSB0Q2F1c2UgPSBuZXcgVGhyb3dhYmxlKCJUaHJvd2FibGUgZm9yIGV4Y2VwdGlvbiIpOworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+SW52YWxpZEtleVNwZWNFeGNlcHRpb24oKTwvY29kZT4gY29uc3RydWN0b3IgQXNzZXJ0aW9uOgorICAgICAqIGNvbnN0cnVjdHMgSW52YWxpZEtleVNwZWNFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbjAxKCkgeworICAgICAgICBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiB0RSA9IG5ldyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbigpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5JbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlIG1zZy4KKyAgICAgKiBQYXJhbWV0ZXIgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZEtleVNwZWNFeGNlcHRpb24wMigpIHsKKyAgICAgICAgSW52YWxpZEtleVNwZWNFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgSW52YWxpZEtleVNwZWNFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5JbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiB3aGVuIDxjb2RlPm1zZzwvY29kZT4gaXMKKyAgICAgKiBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEludmFsaWRLZXlTcGVjRXhjZXB0aW9uMDMoKSB7CisgICAgICAgIFN0cmluZyBtc2cgPSBudWxsOworICAgICAgICBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiB0RSA9IG5ldyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbihtc2cpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5JbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbihUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiB3aGVuIDxjb2RlPmNhdXNlPC9jb2RlPgorICAgICAqIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZEtleVNwZWNFeGNlcHRpb24wNCgpIHsKKyAgICAgICAgVGhyb3dhYmxlIGNhdXNlID0gbnVsbDsKKyAgICAgICAgSW52YWxpZEtleVNwZWNFeGNlcHRpb24gdEUgPSBuZXcgSW52YWxpZEtleVNwZWNFeGNlcHRpb24oY2F1c2UpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5JbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbihUaHJvd2FibGUpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiB3aGVuIDxjb2RlPmNhdXNlPC9jb2RlPgorICAgICAqIGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEludmFsaWRLZXlTcGVjRXhjZXB0aW9uMDUoKSB7CisgICAgICAgIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIHRFID0gbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKHRDYXVzZSk7CisgICAgICAgIGlmICh0RS5nZXRNZXNzYWdlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHRvUyA9IHRDYXVzZS50b1N0cmluZygpOworICAgICAgICAgICAgU3RyaW5nIGdldE0gPSB0RS5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJnZXRNZXNzYWdlKCkgc2hvdWxkIGNvbnRhaW4gIi5jb25jYXQodG9TKSwgKGdldE0KKyAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoImdldENhdXNlKCkgbXVzdCBub3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwgdEUKKyAgICAgICAgICAgICAgICAuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5JbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbihTdHJpbmcsIFRocm93YWJsZSk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIHdoZW4KKyAgICAgKiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZEtleVNwZWNFeGNlcHRpb24wNigpIHsKKyAgICAgICAgSW52YWxpZEtleVNwZWNFeGNlcHRpb24gdEUgPSBuZXcgSW52YWxpZEtleVNwZWNFeGNlcHRpb24obnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydE51bGwoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+SW52YWxpZEtleVNwZWNFeGNlcHRpb24oU3RyaW5nLCBUaHJvd2FibGUpPC9jb2RlPgorICAgICAqIGNvbnN0cnVjdG9yIEFzc2VydGlvbjogY29uc3RydWN0cyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiB3aGVuCisgICAgICogPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG51bGwgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbjA3KCkgeworICAgICAgICBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbiB0RTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICB0RSA9IG5ldyBJbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbihtc2dzW2ldLCBudWxsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZ2V0TWVzc2FnZSgpIG11c3QgcmV0dXJuOiAiLmNvbmNhdChtc2dzW2ldKSwgdEUKKyAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2UoKSwgbXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkludmFsaWRLZXlTcGVjRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgSW52YWxpZEtleVNwZWNFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QgbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZEtleVNwZWNFeGNlcHRpb24wOCgpIHsKKyAgICAgICAgSW52YWxpZEtleVNwZWNFeGNlcHRpb24gdEUgPSBuZXcgSW52YWxpZEtleVNwZWNFeGNlcHRpb24obnVsbCwgdENhdXNlKTsKKyAgICAgICAgaWYgKHRFLmdldE1lc3NhZ2UoKSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgdG9TID0gdENhdXNlLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IHNob3VsZCAiLmNvbmNhdCh0b1MpLCAoZ2V0TQorICAgICAgICAgICAgICAgICAgICAuaW5kZXhPZih0b1MpICE9IC0xKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImdldENhdXNlKCkgbXVzdCByZXR1cm4gIi5jb25jYXQodENhdXNlLnRvU3RyaW5nKCkpLCB0RQorICAgICAgICAgICAgICAgIC5nZXRDYXVzZSgpLCB0Q2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkludmFsaWRLZXlTcGVjRXhjZXB0aW9uKFN0cmluZywgVGhyb3dhYmxlKTwvY29kZT4KKyAgICAgKiBjb25zdHJ1Y3RvciBBc3NlcnRpb246IGNvbnN0cnVjdHMgSW52YWxpZEtleVNwZWNFeGNlcHRpb24gd2hlbgorICAgICAqIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QgbnVsbCA8Y29kZT5tc2c8L2NvZGU+IGlzIG5vdCBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEludmFsaWRLZXlTcGVjRXhjZXB0aW9uMDkoKSB7CisgICAgICAgIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIHRFOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHRFID0gbmV3IEludmFsaWRLZXlTcGVjRXhjZXB0aW9uKG1zZ3NbaV0sIHRDYXVzZSk7CisgICAgICAgICAgICBTdHJpbmcgZ2V0TSA9IHRFLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIFN0cmluZyB0b1MgPSB0Q2F1c2UudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGlmIChtc2dzW2ldLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBtdXN0IGNvbnRhaW4gIi5jb25jYXQobXNnc1tpXSksIGdldE0KKyAgICAgICAgICAgICAgICAgICAgICAgIC5pbmRleE9mKG1zZ3NbaV0pICE9IC0xKTsKKyAgICAgICAgICAgICAgICBpZiAoIWdldE0uZXF1YWxzKG1zZ3NbaV0pKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImdldE1lc3NhZ2UoKSBzaG91bGQgY29udGFpbiAiLmNvbmNhdCh0b1MpLCBnZXRNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmluZGV4T2YodG9TKSAhPSAtMSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IG5vdCByZXR1cm4gbnVsbCIsIHRFLmdldENhdXNlKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuICIuY29uY2F0KHRDYXVzZS50b1N0cmluZygpKSwKKyAgICAgICAgICAgICAgICAgICAgdEUuZ2V0Q2F1c2UoKSwgdENhdXNlKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0ludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGFiYTQ5NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL0ludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsODEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5zcGVjOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5JbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbjwvY29kZT4gY2xhc3MgY29uc3RydWN0b3JzIGFuZAorICogbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBzdGF0aWMgU3RyaW5nW10gbXNncyA9IHsKKyAgICAgICAgICAgICIiLAorICAgICAgICAgICAgIkNoZWNrIG5ldyBtZXNzYWdlIiwKKyAgICAgICAgICAgICJDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSBDaGVjayBuZXcgbWVzc2FnZSIgfTsKKworICAgIHN0YXRpYyBUaHJvd2FibGUgdENhdXNlID0gbmV3IFRocm93YWJsZSgiVGhyb3dhYmxlIGZvciBleGNlcHRpb24iKTsKKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uKCk8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIEludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsCisgICAgICogbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbjAxKCkgeworICAgICAgICBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbiB0RSA9IG5ldyBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbigpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5JbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbiB3aXRoIGRldGFpbCBtZXNzYWdlCisgICAgICogbXNnLiBQYXJhbWV0ZXIgPGNvZGU+bXNnPC9jb2RlPiBpcyBub3QgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24wMigpIHsKKyAgICAgICAgSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24gdEU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgdEUgPSBuZXcgSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24obXNnc1tpXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImdldE1lc3NhZ2UoKSBtdXN0IHJldHVybjogIi5jb25jYXQobXNnc1tpXSksIHRFCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXNzYWdlKCksIG1zZ3NbaV0pOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiZ2V0Q2F1c2UoKSBtdXN0IHJldHVybiBudWxsIiwgdEUuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5JbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbihTdHJpbmcpPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbiB3aGVuIDxjb2RlPm1zZzwvY29kZT4KKyAgICAgKiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdEludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uMDMoKSB7CisgICAgICAgIFN0cmluZyBtc2cgPSBudWxsOworICAgICAgICBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbiB0RSA9IG5ldyBJbnZhbGlkUGFyYW1ldGVyU3BlY0V4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICBtc2cpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRNZXNzYWdlKCkgbXVzdCByZXR1cm4gbnVsbC4iLCB0RS5nZXRNZXNzYWdlKCkpOworICAgICAgICBhc3NlcnROdWxsKCJnZXRDYXVzZSgpIG11c3QgcmV0dXJuIG51bGwiLCB0RS5nZXRDYXVzZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9NR0YxUGFyYW1ldGVyU3BlY1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL01HRjFQYXJhbWV0ZXJTcGVjVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE3OGZjY2UKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9NR0YxUGFyYW1ldGVyU3BlY1Rlc3QuamF2YQpAQCAtMCwwICsxLDk0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LnNwZWM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuTUdGMVBhcmFtZXRlclNwZWM7CisKKy8qKgorICogVGVzdCBmb3IgTUdGMVBhcmFtZXRlclNwZWMgY2xhc3MKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBNR0YxUGFyYW1ldGVyU3BlY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBNZWFuaW5nbGVzcyBhbGdvcml0aG0gbmFtZSBqdXN0IGZvciB0ZXN0aW5nIHB1cnBvc2VzCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHRlc3RBbGdOYW1lID0gIlRFU1QiOworCisgICAgLy8KKyAgICAvLyBUZXN0cworICAgIC8vCisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5NR0YxUGFyYW1ldGVyU3BlYzwvY29kZT4gY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIG5ldyA8Y29kZT5NR0YxUGFyYW1ldGVyU3BlYzwvY29kZT4KKyAgICAgKiBvYmplY3QgdXNpbmcgdmFsaWQgcGFyYW1ldGVyCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdE1HRjFQYXJhbWV0ZXJTcGVjMDEoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNR0YxUGFyYW1ldGVyU3BlYyBwZ2YgPSBuZXcgTUdGMVBhcmFtZXRlclNwZWModGVzdEFsZ05hbWUpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwZ2YpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShwZ2YgaW5zdGFuY2VvZiBNR0YxUGFyYW1ldGVyU3BlYyk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbjogIiArIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+TUdGMVBhcmFtZXRlclNwZWM8L2NvZGU+IGNvbnN0cnVjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlmIHBhcmFtZXRlciBpcyA8Y29kZT5udWxsPC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RNR0YxUGFyYW1ldGVyU3BlYzAyKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IE1HRjFQYXJhbWV0ZXJTcGVjKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbFBvaW50ZXJFeGNlcHRpb24gaGFzIG5vdCBiZWVuIHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBvaykgeworICAgICAgICAgICAgLy9leHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0RGlnZXN0QWxnb3JpdGhtPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHRoZSBhbGdvcml0aG0gbmFtZSBvZiB0aGUgbWVzc2FnZQorICAgICAqIGRpZ2VzdCB1c2VkIGJ5IHRoZSBtYXNrIGdlbmVyYXRpb24gZnVuY3Rpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0RGlnZXN0QWxnb3JpdGhtKCkgeworICAgICAgICBNR0YxUGFyYW1ldGVyU3BlYyBhcHMgPSBuZXcgTUdGMVBhcmFtZXRlclNwZWModGVzdEFsZ05hbWUpOworICAgICAgICBhc3NlcnRUcnVlKHRlc3RBbGdOYW1lLmVxdWFscyhhcHMuZ2V0RGlnZXN0QWxnb3JpdGhtKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciBwdWJsaWMgc3RhdGljIGZpZWxkcyBhbmQgPGNvZGU+Z2V0RGlnZXN0QWxnb3JpdGhtPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHRoZSBhbGdvcml0aG0gbmFtZSBvZiB0aGUgbWVzc2FnZQorICAgICAqIGRpZ2VzdCB1c2VkIGJ5IHRoZSBtYXNrIGdlbmVyYXRpb24gZnVuY3Rpb24KKyAgICAgKi8KKworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RGaWVsZHNHZXREaWdlc3RBbGdvcml0aG0oKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiU0hBLTEiLCBNR0YxUGFyYW1ldGVyU3BlYy5TSEExLmdldERpZ2VzdEFsZ29yaXRobSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTSEEtMjU2IiwgTUdGMVBhcmFtZXRlclNwZWMuU0hBMjU2LmdldERpZ2VzdEFsZ29yaXRobSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTSEEtMzg0IiwgTUdGMVBhcmFtZXRlclNwZWMuU0hBMzg0LmdldERpZ2VzdEFsZ29yaXRobSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTSEEtNTEyIiwgTUdGMVBhcmFtZXRlclNwZWMuU0hBNTEyLmdldERpZ2VzdEFsZ29yaXRobSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9QS0NTOEVuY29kZWRLZXlTcGVjVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvUEtDUzhFbmNvZGVkS2V5U3BlY1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MWE1ZDMzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvUEtDUzhFbmNvZGVkS2V5U3BlY1Rlc3QuamF2YQpAQCAtMCwwICsxLDEzNiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5zcGVjOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkVuY29kZWRLZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5QS0NTOEVuY29kZWRLZXlTcGVjOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlBLQ1M4RW5jb2RlZEtleVNwZWM8L2NvZGU+IGNsYXNzIGZpZWxkcyBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBQS0NTOEVuY29kZWRLZXlTcGVjVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8vCisgICAgLy8gVGVzdHMKKyAgICAvLworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+UEtDUzhFbmNvZGVkS2V5U3BlYzwvY29kZT4gY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIG5ldyA8Y29kZT5QS0NTOEVuY29kZWRLZXlTcGVjPC9jb2RlPgorICAgICAqIG9iamVjdCB1c2luZyB2YWxpZCBwYXJhbWV0ZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UEtDUzhFbmNvZGVkS2V5U3BlYygpIHsKKyAgICAgICAgYnl0ZVtdIGVuY29kZWRLZXkgPSBuZXcgYnl0ZVtdIHsoYnl0ZSkxLChieXRlKTIsKGJ5dGUpMywoYnl0ZSk0fTsKKworICAgICAgICBFbmNvZGVkS2V5U3BlYyBla3MgPSBuZXcgUEtDUzhFbmNvZGVkS2V5U3BlYyhlbmNvZGVkS2V5KTsKKworICAgICAgICBhc3NlcnRUcnVlKGVrcyBpbnN0YW5jZW9mIFBLQ1M4RW5jb2RlZEtleVNwZWMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZWtzID0gbmV3IFBLQ1M4RW5jb2RlZEtleVNwZWMobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJleHBlY3RlZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBvaworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0RW5jb2RlZCgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIGVuY29kZWQga2V5CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEVuY29kZWQoKSB7CisgICAgICAgIGJ5dGVbXSBlbmNvZGVkS2V5ID0gbmV3IGJ5dGVbXSB7KGJ5dGUpMSwoYnl0ZSkyLChieXRlKTMsKGJ5dGUpNH07CisKKyAgICAgICAgUEtDUzhFbmNvZGVkS2V5U3BlYyBtZWtzID0gbmV3IFBLQ1M4RW5jb2RlZEtleVNwZWMoZW5jb2RlZEtleSk7CisKKyAgICAgICAgYnl0ZVtdIGVrID0gbWVrcy5nZXRFbmNvZGVkKCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGVuY29kZWRLZXksIGVrKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0Rm9ybWF0KCk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBmb3JtYXQgbmFtZSAoYWx3YXlzICJQS0NTIzgiKQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRGb3JtYXQoKSB7CisgICAgICAgIGJ5dGVbXSBlbmNvZGVkS2V5ID0gbmV3IGJ5dGVbXSB7KGJ5dGUpMSwoYnl0ZSkyLChieXRlKTMsKGJ5dGUpNH07CisKKyAgICAgICAgUEtDUzhFbmNvZGVkS2V5U3BlYyBtZWtzID0gbmV3IFBLQ1M4RW5jb2RlZEtleVNwZWMoZW5jb2RlZEtleSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJQS0NTIzgiLCBtZWtzLmdldEZvcm1hdCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB0aGF0IGludGVybmFsIHN0YXRlIG9mIHRoZSBvYmplY3QKKyAgICAgKiBjYW4gbm90IGJlIGNoYW5nZWQgYnkgbW9kaWZ5aW5nIGluaXRpYWwKKyAgICAgKiBhcnJheSB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RJc1N0YXRlUHJlc2VydmVkMSgpIHsKKyAgICAgICAgLy8gUmVmZXJlbmNlIGFycmF5CisgICAgICAgIGJ5dGVbXSBlbmNvZGVkS2V5ID0gbmV3IGJ5dGVbXSB7KGJ5dGUpMSwoYnl0ZSkyLChieXRlKTMsKGJ5dGUpNH07CisgICAgICAgIC8vIFJlZmVyZW5jZSBhcnJheSdzIGNvcHkgd2lsbCBiZSB1c2VkIGZvciB0ZXN0CisgICAgICAgIGJ5dGVbXSBlbmNvZGVkS2V5Q29weSA9IGVuY29kZWRLZXkuY2xvbmUoKTsKKworICAgICAgICBQS0NTOEVuY29kZWRLZXlTcGVjIG1la3MgPSBuZXcgUEtDUzhFbmNvZGVkS2V5U3BlYyhlbmNvZGVkS2V5Q29weSk7CisKKyAgICAgICAgLy8gTW9kaWZ5IGluaXRpYWwgYXJyYXkncyB2YWx1ZQorICAgICAgICBlbmNvZGVkS2V5Q29weVszXSA9IChieXRlKTU7CisKKyAgICAgICAgLy8gR2V0IGVuY29kZWQga2V5CisgICAgICAgIGJ5dGVbXSBlayA9IG1la3MuZ2V0RW5jb2RlZCgpOworCisgICAgICAgIC8vIENoZWNrICB1c2luZyByZWZlcmVuY2UgYXJyYXkgdGhhdAorICAgICAgICAvLyBieXRlIHZhbHVlIGhhcyBub3QgYmVlbiBjaGFuZ2VkCisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhlbmNvZGVkS2V5LCBlaykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHRoYXQgaW50ZXJuYWwgc3RhdGUgb2YgdGhlIG9iamVjdAorICAgICAqIGNhbiBub3QgYmUgbW9kaWZpZWQgdXNpbmcgcmV0dXJuZWQgdmFsdWUKKyAgICAgKiBvZiA8Y29kZT5nZXRFbmNvZGVkKCk8L2NvZGU+IG1ldGhvZAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RJc1N0YXRlUHJlc2VydmVkMigpIHsKKyAgICAgICAgLy8gUmVmZXJlbmNlIGFycmF5CisgICAgICAgIGJ5dGVbXSBlbmNvZGVkS2V5ID0gbmV3IGJ5dGVbXSB7KGJ5dGUpMSwoYnl0ZSkyLChieXRlKTMsKGJ5dGUpNH07CisgICAgICAgIC8vIFJlZmVyZW5jZSBhcnJheSdzIGNvcHkgd2lsbCBiZSB1c2VkIGZvciB0ZXN0CisgICAgICAgIGJ5dGVbXSBlbmNvZGVkS2V5Q29weSA9IGVuY29kZWRLZXkuY2xvbmUoKTsKKworICAgICAgICBQS0NTOEVuY29kZWRLZXlTcGVjIG1la3MgPSBuZXcgUEtDUzhFbmNvZGVkS2V5U3BlYyhlbmNvZGVkS2V5Q29weSk7CisKKyAgICAgICAgYnl0ZVtdIGVrID0gbWVrcy5nZXRFbmNvZGVkKCk7CisKKyAgICAgICAgLy8gTW9kaWZ5IHJldHVybmVkIGFycmF5CisgICAgICAgIGVrWzNdID0gKGJ5dGUpNTsKKworICAgICAgICAvLyBHZXQgZW5jb2RlZCBrZXkgYWdhaW4KKyAgICAgICAgYnl0ZVtdIGVrMSA9IG1la3MuZ2V0RW5jb2RlZCgpOworCisgICAgICAgIC8vIENoZWNrIHVzaW5nIHJlZmVyZW5jZSBhcnJheSB0aGF0CisgICAgICAgIC8vIGJ5dGUgdmFsdWUgaGFzIG5vdCBiZWVuIGNoYW5nZWQKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGVuY29kZWRLZXksIGVrMSkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvUFNTUGFyYW1ldGVyU3BlY1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL1BTU1BhcmFtZXRlclNwZWNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmU3MjBkMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL1BTU1BhcmFtZXRlclNwZWNUZXN0LmphdmEKQEAgLTAsMCArMSwyNTkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5NR0YxUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuUFNTUGFyYW1ldGVyU3BlYzsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+UFNTUGFyYW1ldGVyU3BlYzwvY29kZT4gY2xhc3MgKDEuNSkKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBQU1NQYXJhbWV0ZXJTcGVjVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qKgorICAgICAqIFRlc3QgIzEgZm9yIDxjb2RlPlBTU1BhcmFtZXRlclNwZWMoaW50KTwvY29kZT4gY3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgdXNpbmcgdmFsaWQgcGFyYW1ldGVyCisgICAgICogPGNvZGU+UFNTUGFyYW1ldGVyU3BlYzxjb2RlPiBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UFNTUGFyYW1ldGVyU3BlYzAxMDEoKSB7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgYXBzID0gbmV3IFBTU1BhcmFtZXRlclNwZWMoMjApOworICAgICAgICBhc3NlcnRUcnVlKGFwcyBpbnN0YW5jZW9mIFBTU1BhcmFtZXRlclNwZWMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPlBTU1BhcmFtZXRlclNwZWMoaW50KTwvY29kZT4gY3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246CisgICAgICogdGhyb3dzIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4KKyAgICAgKiBpZiA8Y29kZT5zYWx0TGVuPC9jb2RlPiBsZXNzIHRoYW4gMAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RQU1NQYXJhbWV0ZXJTcGVjMDEwMigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBQU1NQYXJhbWV0ZXJTcGVjKC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElBRSBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvcgorICAgICAqIDxjb2RlPgorICAgICAqIFBTU1BhcmFtZXRlclNwZWMoU3RyaW5nLFN0cmluZyxBbGdvcml0aG1QYXJhbWV0ZXJTcGVjLGludCxpbnQpCisgICAgICogPC9jb2RlPiBjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyB1c2luZyB2YWxpZCBwYXJhbWV0ZXJzCisgICAgICogPGNvZGU+UFNTUGFyYW1ldGVyU3BlYzxjb2RlPiBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UFNTUGFyYW1ldGVyU3BlYzAyMDEoKSB7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgYXBzID0gbmV3IFBTU1BhcmFtZXRlclNwZWMoIlNIQS0xIiwgIk1HRjEiLAorICAgICAgICAgICAgICAgIE1HRjFQYXJhbWV0ZXJTcGVjLlNIQTEsIDIwLCAxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhcHMgaW5zdGFuY2VvZiBQU1NQYXJhbWV0ZXJTcGVjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvcgorICAgICAqIDxjb2RlPgorICAgICAqIFBTU1BhcmFtZXRlclNwZWMoU3RyaW5nLFN0cmluZyxBbGdvcml0aG1QYXJhbWV0ZXJTcGVjLGludCxpbnQpCisgICAgICogPC9jb2RlPiBjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjoKKyAgICAgKiB0aHJvd3MgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+CisgICAgICogaWYgPGNvZGU+bWROYW1lPC9jb2RlPiBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFBTU1BhcmFtZXRlclNwZWMwMjAyKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFBTU1BhcmFtZXRlclNwZWMobnVsbCwgIk1HRjEiLCBNR0YxUGFyYW1ldGVyU3BlYy5TSEExLCAyMCwgMSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOUEUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMzIGZvcgorICAgICAqIDxjb2RlPgorICAgICAqIFBTU1BhcmFtZXRlclNwZWMoU3RyaW5nLFN0cmluZyxBbGdvcml0aG1QYXJhbWV0ZXJTcGVjLGludCxpbnQpCisgICAgICogPC9jb2RlPiBjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjoKKyAgICAgKiB0aHJvd3MgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+CisgICAgICogaWYgPGNvZGU+bWdmTmFtZTwvY29kZT4gaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RQU1NQYXJhbWV0ZXJTcGVjMDIwMygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBQU1NQYXJhbWV0ZXJTcGVjKCJTSEEtMSIsIG51bGwsIE1HRjFQYXJhbWV0ZXJTcGVjLlNIQTEsIDIwLCAxKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE5QRSBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzQgZm9yCisgICAgICogPGNvZGU+CisgICAgICogUFNTUGFyYW1ldGVyU3BlYyhTdHJpbmcsU3RyaW5nLEFsZ29yaXRobVBhcmFtZXRlclNwZWMsaW50LGludCkKKyAgICAgKiA8L2NvZGU+IGN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOgorICAgICAqIHRocm93cyA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248Y29kZT4KKyAgICAgKiBpZiA8Y29kZT5zYWx0TGVuPGNvZGU+IGxlc3MgdGhhbiAwCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFBTU1BhcmFtZXRlclNwZWMwMjA0KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFBTU1BhcmFtZXRlclNwZWMoIlNIQS0xIiwgIk1HRjEiLAorICAgICAgICAgICAgICAgICAgICBNR0YxUGFyYW1ldGVyU3BlYy5TSEExLCAtMjAsIDEpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSUFFIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzUgZm9yCisgICAgICogPGNvZGU+CisgICAgICogUFNTUGFyYW1ldGVyU3BlYyhTdHJpbmcsU3RyaW5nLEFsZ29yaXRobVBhcmFtZXRlclNwZWMsaW50LGludCkKKyAgICAgKiA8L2NvZGU+IGN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOgorICAgICAqIHRocm93cyA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+CisgICAgICogaWYgPGNvZGU+dHJhaWxlckZpZWxkPC9jb2RlPiBsZXNzIHRoYW4gMAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RQU1NQYXJhbWV0ZXJTcGVjMDIwNSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBQU1NQYXJhbWV0ZXJTcGVjKCJTSEEtMSIsICJNR0YxIiwKKyAgICAgICAgICAgICAgICAgICAgTUdGMVBhcmFtZXRlclNwZWMuU0hBMSwgMjAsIC0xKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIElBRSBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM2IGZvcgorICAgICAqIDxjb2RlPgorICAgICAqIFBTU1BhcmFtZXRlclNwZWMoU3RyaW5nLFN0cmluZyxBbGdvcml0aG1QYXJhbWV0ZXJTcGVjLGludCxpbnQpCisgICAgICogPC9jb2RlPiBjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogPGNvZGU+QWxnb3JpdGhtUGFyYW1ldGVyU3BlYzwvY29kZT4gY2FuIGJlIG51bGwKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RQU1NQYXJhbWV0ZXJTcGVjMDIwNigpIHsKKyAgICAgICAgbmV3IFBTU1BhcmFtZXRlclNwZWMoIlNIQS0xIiwgIk1HRjEiLCBudWxsLCAyMCwgMSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0RGlnZXN0QWxnb3JpdGhtKCk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBtZXNzYWdlIGRpZ2VzdCBhbGdvcml0aG0gbmFtZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXREaWdlc3RBbGdvcml0aG0oKSB7CisgICAgICAgIFBTU1BhcmFtZXRlclNwZWMgcHNzcHMgPSBuZXcgUFNTUGFyYW1ldGVyU3BlYygiU0hBLTEiLCAiTUdGMSIsCisgICAgICAgICAgICAgICAgTUdGMVBhcmFtZXRlclNwZWMuU0hBMSwgMjAsIDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlNIQS0xIiwgcHNzcHMuZ2V0RGlnZXN0QWxnb3JpdGhtKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldE1HRkFsZ29yaXRobSgpPC9jb2RlPiBtZXRob2QKKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgbWFzayBnZW5lcmF0aW9uIGZ1bmN0aW9uIGFsZ29yaXRobSBuYW1lCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldE1HRkFsZ29yaXRobSgpIHsKKyAgICAgICAgUFNTUGFyYW1ldGVyU3BlYyBwc3NwcyA9IG5ldyBQU1NQYXJhbWV0ZXJTcGVjKCJTSEEtMSIsICJNR0YxIiwKKyAgICAgICAgICAgICAgICBNR0YxUGFyYW1ldGVyU3BlYy5TSEExLCAyMCwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygiTUdGMSIsIHBzc3BzLmdldE1HRkFsZ29yaXRobSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5nZXRNR0ZQYXJhbWV0ZXJzKCk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBtYXNrIGdlbmVyYXRpb24gZnVuY3Rpb24gcGFyYW1ldGVycworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRNR0ZQYXJhbWV0ZXJzMDEoKSB7CisgICAgICAgIFBTU1BhcmFtZXRlclNwZWMgcHNzcHMgPSBuZXcgUFNTUGFyYW1ldGVyU3BlYygiU0hBLTEiLCAiTUdGMSIsCisgICAgICAgICAgICAgICAgTUdGMVBhcmFtZXRlclNwZWMuU0hBMSwgMjAsIDEpOworICAgICAgICBhc3NlcnRUcnVlKE1HRjFQYXJhbWV0ZXJTcGVjLlNIQTEuZXF1YWxzKHBzc3BzLmdldE1HRlBhcmFtZXRlcnMoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPmdldE1HRlBhcmFtZXRlcnMoKTwvY29kZT4gbWV0aG9kCisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+CisgICAgICogaWYgPGNvZGU+bnVsbDwvY29kZT4gaGFkIGJlZW4gcGFzc2VkIGFzCisgICAgICogQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbWV0ZXIgdG8gdGhlIGN0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0TUdGUGFyYW1ldGVyczAyKCkgeworICAgICAgICBQU1NQYXJhbWV0ZXJTcGVjIHBzc3BzID0gbmV3IFBTU1BhcmFtZXRlclNwZWMoIlNIQS0xIiwgIk1HRjEiLAorICAgICAgICAgICAgICAgIG51bGwsIDIwLCAxKTsKKyAgICAgICAgYXNzZXJ0TnVsbChwc3Nwcy5nZXRNR0ZQYXJhbWV0ZXJzKCkpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0U2FsdExlbmd0aCgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHNhbHQgbGVuZ3RoIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFNhbHRMZW5ndGgoKSB7CisgICAgICAgIFBTU1BhcmFtZXRlclNwZWMgcHNzcHMgPSBuZXcgUFNTUGFyYW1ldGVyU3BlYygyMCk7CisgICAgICAgIGFzc2VydEVxdWFscygyMCwgcHNzcHMuZ2V0U2FsdExlbmd0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRUcmFpbGVyRmllbGQoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyB0cmFpbGVyIGZpZWxkIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFRyYWlsZXJGaWVsZCgpIHsKKyAgICAgICAgUFNTUGFyYW1ldGVyU3BlYyBwc3NwcyA9IG5ldyBQU1NQYXJhbWV0ZXJTcGVjKCJTSEEtMSIsICJNR0YxIiwKKyAgICAgICAgICAgICAgICBNR0YxUGFyYW1ldGVyU3BlYy5TSEExLCAyMCwgMSk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBwc3Nwcy5nZXRUcmFpbGVyRmllbGQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+REVGQVVMVDwvY29kZT4gZmllbGQ8YnI+CisgICAgICogQXNzZXJ0aW9uOiBkZWZhdWx0IG1lc3NhZ2UgZGlnZXN0IGFsZ29yaXRobSBuYW1lIGlzICJTSEEtMSIKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0REVGQVVMVG1kTmFtZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJTSEEtMSIsIFBTU1BhcmFtZXRlclNwZWMuREVGQVVMVC5nZXREaWdlc3RBbGdvcml0aG0oKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+REVGQVVMVDwvY29kZT4gZmllbGQ8YnI+CisgICAgICogQXNzZXJ0aW9uOiBkZWZhdWx0IG1hc2sgZ2VuZXJhdGlvbiBmdW5jdGlvbiBhbGdvcml0aG0gbmFtZSBpcyAiTUdGMSIKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0REVGQVVMVG1nZk5hbWUoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiTUdGMSIsIFBTU1BhcmFtZXRlclNwZWMuREVGQVVMVC5nZXRNR0ZBbGdvcml0aG0oKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+REVGQVVMVDwvY29kZT4gZmllbGQ8YnI+CisgICAgICogQXNzZXJ0aW9uOiBkZWZhdWx0IGFsZ29yaXRobSBwYXJhbWV0ZXJzIGZvciBtYXNrCisgICAgICogZ2VuZXJhdGlvbiBmdW5jdGlvbiBhcmUgPGNvZGU+TUdGMVBhcmFtZXRlclNwZWMuU0hBMTwvY29kZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0REVGQVVMVG1nZlNwZWMoKSB7CisgICAgICAgIGFzc2VydFRydWUoTUdGMVBhcmFtZXRlclNwZWMuU0hBMS5lcXVhbHMoUFNTUGFyYW1ldGVyU3BlYy5ERUZBVUxULmdldE1HRlBhcmFtZXRlcnMoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPkRFRkFVTFQ8L2NvZGU+IGZpZWxkPGJyPgorICAgICAqIEFzc2VydGlvbjogZGVmYXVsdCBzYWx0IGxlbmd0aCB2YWx1ZSBpcyAyMAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RERUZBVUxUc2FsdExlbigpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDIwLCBQU1NQYXJhbWV0ZXJTcGVjLkRFRkFVTFQuZ2V0U2FsdExlbmd0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5ERUZBVUxUPC9jb2RlPiBmaWVsZDxicj4KKyAgICAgKiBBc3NlcnRpb246IGRlZmF1bHQgdHJhaWxlciBmaWVsZCB2YWx1ZSBpcyAxCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdERFRkFVTFR0cmFpbGVyRmllbGQoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBQU1NQYXJhbWV0ZXJTcGVjLkRFRkFVTFQuZ2V0VHJhaWxlckZpZWxkKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL1JTQUtleUdlblBhcmFtZXRlclNwZWNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9SU0FLZXlHZW5QYXJhbWV0ZXJTcGVjVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkyOTAzNGEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9SU0FLZXlHZW5QYXJhbWV0ZXJTcGVjVGVzdC5qYXZhCkBAIC0wLDAgKzEsODQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5SU0FLZXlHZW5QYXJhbWV0ZXJTcGVjOworCisvKioKKyAqIFRlc3RzIGZvciA8Y29kZT5SU0FLZXlHZW5QYXJhbWV0ZXJTcGVjPC9jb2RlPiBjbGFzcyBmaWVsZHMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgUlNBS2V5R2VuUGFyYW1ldGVyU3BlY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5SU0FLZXlHZW5QYXJhbWV0ZXJTcGVjKGludCxCaWdJbnRlZ2VyKTwvY29kZT4gY3RvcgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyA8Y29kZT5SU0FLZXlHZW5QYXJhbWV0ZXJTcGVjPC9jb2RlPgorICAgICAqIG9iamVjdCB1c2luZyB2YWxpZCBwYXJhbWV0ZXJzCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJTQUtleUdlblBhcmFtZXRlclNwZWMoKSB7CisgICAgICAgIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgYXBzID0KKyAgICAgICAgICAgIG5ldyBSU0FLZXlHZW5QYXJhbWV0ZXJTcGVjKDUxMiwgQmlnSW50ZWdlci52YWx1ZU9mKDBMKSk7CisgICAgICAgIGFzc2VydFRydWUoYXBzIGluc3RhbmNlb2YgUlNBS2V5R2VuUGFyYW1ldGVyU3BlYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0S2V5U2l6ZSgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIGtleSBzaXplIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEtleXNpemUoKSB7CisgICAgICAgIFJTQUtleUdlblBhcmFtZXRlclNwZWMgcmtncHMgPQorICAgICAgICAgICAgbmV3IFJTQUtleUdlblBhcmFtZXRlclNwZWMoNTEyLCBCaWdJbnRlZ2VyLnZhbHVlT2YoMEwpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDUxMiwgcmtncHMuZ2V0S2V5c2l6ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRQdWJsaWNFeHBvbmVudCgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHB1YmxpYyBleHBvbmVudCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRQdWJsaWNFeHBvbmVudCgpIHsKKyAgICAgICAgUlNBS2V5R2VuUGFyYW1ldGVyU3BlYyBya2dwcyA9CisgICAgICAgICAgICBuZXcgUlNBS2V5R2VuUGFyYW1ldGVyU3BlYyg1MTIsIEJpZ0ludGVnZXIudmFsdWVPZigwTCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgcmtncHMuZ2V0UHVibGljRXhwb25lbnQoKS5pbnRWYWx1ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5GMDwvY29kZT4gZmllbGQ8YnI+CisgICAgICogQXNzZXJ0aW9uOiB0aGUgcHVibGljIGV4cG9uZW50IHZhbHVlIEYwID0gMworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RGMFZhbHVlKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoMywgUlNBS2V5R2VuUGFyYW1ldGVyU3BlYy5GMC5pbnRWYWx1ZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5GNDwvY29kZT4gZmllbGQ8YnI+CisgICAgICogQXNzZXJ0aW9uOiB0aGUgcHVibGljIGV4cG9uZW50IHZhbHVlIEYwID0gNjU1MzcKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0RjRWYWx1ZSgpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDY1NTM3LCBSU0FLZXlHZW5QYXJhbWV0ZXJTcGVjLkY0LmludFZhbHVlKCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJiNmJjODcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9SU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWNUZXN0LmphdmEKQEAgLTAsMCArMSw3MDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5LZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5SU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLlJTQU90aGVyUHJpbWVJbmZvOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5SU0FQcml2YXRlS2V5U3BlYzsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+UlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjPC9jb2RlPiBjbGFzcyBmaWVsZHMgYW5kIG1ldGhvZHMuCisgKgorICovCitwdWJsaWMgY2xhc3MgUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICAvKioKKyAgICAgKiBSZWZlcmVuY2UgYXJyYXkgb2YgUlNBT3RoZXJQcmltZUluZm8uIERPIE5PVCBNT0RJRlkKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBSU0FPdGhlclByaW1lSW5mb1tdIG9waSA9IG5ldyBSU0FPdGhlclByaW1lSW5mb1tdIHsKKyAgICAgICAgICAgIG5ldyBSU0FPdGhlclByaW1lSW5mbyhCaWdJbnRlZ2VyLk9ORSwgQmlnSW50ZWdlci5PTkUsIEJpZ0ludGVnZXIuT05FKSwKKyAgICAgICAgICAgIG5ldyBSU0FPdGhlclByaW1lSW5mbyhCaWdJbnRlZ2VyLk9ORSwgQmlnSW50ZWdlci5PTkUsIEJpZ0ludGVnZXIuT05FKSwKKyAgICAgICAgICAgIG5ldyBSU0FPdGhlclByaW1lSW5mbyhCaWdJbnRlZ2VyLk9ORSwgQmlnSW50ZWdlci5PTkUsIEJpZ0ludGVnZXIuT05FKQorICAgIH07CisKKyAgICAvLyBUZXN0LWNhc2VzOgorCisgICAgLyoqCisgICAgICogVGVzdCAjMSBmb3IKKyAgICAgKiA8Y29kZT5SU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMoQmlnSW50ZWdlciBtb2R1bHVzLAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHB1YmxpY0V4cG9uZW50LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaXZhdGVFeHBvbmVudCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZVAsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVRLAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lRXhwb25lbnRQLAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lRXhwb25lbnRRLAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIGNydENvZWZmaWNpZW50LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSU0FPdGhlclByaW1lSW5mb1tdIG90aGVyUHJpbWVJbmZvKQorICAgICAqIDwvY29kZT4gY3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgPGNvZGU+UlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjPC9jb2RlPgorICAgICAqIG9iamVjdCB1c2luZyB2YWxpZCBwYXJhbWV0ZXJzCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYzAxKCkgeworICAgICAgICBLZXlTcGVjIGtzID0gbmV3IFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYygKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBvcGkpOworICAgICAgICBhc3NlcnRUcnVlKGtzIGluc3RhbmNlb2YgUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMyIGZvcgorICAgICAqIDxjb2RlPlJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYyhCaWdJbnRlZ2VyIG1vZHVsdXMsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHVibGljRXhwb25lbnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpdmF0ZUV4cG9uZW50LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lUCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZVEsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVFeHBvbmVudFAsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVFeHBvbmVudFEsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgY3J0Q29lZmZpY2llbnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJTQU90aGVyUHJpbWVJbmZvW10gb3RoZXJQcmltZUluZm8pCisgICAgICogPC9jb2RlPiBjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgbW9kdWx1cyBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYzAyKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYygKKyAgICAgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIG9waSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOUEUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMzIGZvcgorICAgICAqIDxjb2RlPlJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYyhCaWdJbnRlZ2VyIG1vZHVsdXMsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHVibGljRXhwb25lbnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpdmF0ZUV4cG9uZW50LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lUCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZVEsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVFeHBvbmVudFAsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVFeHBvbmVudFEsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgY3J0Q29lZmZpY2llbnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJTQU90aGVyUHJpbWVJbmZvW10gb3RoZXJQcmltZUluZm8pCisgICAgICogPC9jb2RlPiBjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgcHVibGljRXhwb25lbnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMwMygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMoCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBvcGkpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTlBFIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjNCBmb3IKKyAgICAgKiA8Y29kZT5SU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMoQmlnSW50ZWdlciBtb2R1bHVzLAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHB1YmxpY0V4cG9uZW50LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaXZhdGVFeHBvbmVudCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZVAsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVRLAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lRXhwb25lbnRQLAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lRXhwb25lbnRRLAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIGNydENvZWZmaWNpZW50LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSU0FPdGhlclByaW1lSW5mb1tdIG90aGVyUHJpbWVJbmZvKQorICAgICAqIDwvY29kZT4gY3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHByaXZhdGVFeHBvbmVudCBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYzA0KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYygKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIG9waSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOUEUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM1IGZvcgorICAgICAqIDxjb2RlPlJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYyhCaWdJbnRlZ2VyIG1vZHVsdXMsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHVibGljRXhwb25lbnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpdmF0ZUV4cG9uZW50LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lUCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZVEsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVFeHBvbmVudFAsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVFeHBvbmVudFEsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgY3J0Q29lZmZpY2llbnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJTQU90aGVyUHJpbWVJbmZvW10gb3RoZXJQcmltZUluZm8pCisgICAgICogPC9jb2RlPiBjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgcHJpbWVQIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjMDUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjKAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgb3BpKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE5QRSBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzYgZm9yCisgICAgICogPGNvZGU+UlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjKEJpZ0ludGVnZXIgbW9kdWx1cywKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwdWJsaWNFeHBvbmVudCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcml2YXRlRXhwb25lbnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVQLAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lUSwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZUV4cG9uZW50UCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZUV4cG9uZW50USwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBjcnRDb2VmZmljaWVudCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlNBT3RoZXJQcmltZUluZm9bXSBvdGhlclByaW1lSW5mbykKKyAgICAgKiA8L2NvZGU+IGN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBwcmltZVEgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMwNigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMoCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBvcGkpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTlBFIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjNyBmb3IKKyAgICAgKiA8Y29kZT5SU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMoQmlnSW50ZWdlciBtb2R1bHVzLAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHB1YmxpY0V4cG9uZW50LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaXZhdGVFeHBvbmVudCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZVAsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVRLAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lRXhwb25lbnRQLAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lRXhwb25lbnRRLAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIGNydENvZWZmaWNpZW50LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSU0FPdGhlclByaW1lSW5mb1tdIG90aGVyUHJpbWVJbmZvKQorICAgICAqIDwvY29kZT4gY3Rvcjxicj4KKyAgICAgKiBBc3NlcnRpb246IE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHByaW1lRXhwb25lbnRQIGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjMDcoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjKAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgb3BpKTsKKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIE5QRSBub3QgdGhyb3duIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzggZm9yCisgICAgICogPGNvZGU+UlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjKEJpZ0ludGVnZXIgbW9kdWx1cywKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwdWJsaWNFeHBvbmVudCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcml2YXRlRXhwb25lbnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVQLAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lUSwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZUV4cG9uZW50UCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZUV4cG9uZW50USwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBjcnRDb2VmZmljaWVudCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlNBT3RoZXJQcmltZUluZm9bXSBvdGhlclByaW1lSW5mbykKKyAgICAgKiA8L2NvZGU+IGN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBwcmltZUV4cG9uZW50USBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYzA4KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYygKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIG9waSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOUEUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM5IGZvcgorICAgICAqIDxjb2RlPlJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYyhCaWdJbnRlZ2VyIG1vZHVsdXMsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHVibGljRXhwb25lbnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpdmF0ZUV4cG9uZW50LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lUCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZVEsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVFeHBvbmVudFAsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVFeHBvbmVudFEsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgY3J0Q29lZmZpY2llbnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJTQU90aGVyUHJpbWVJbmZvW10gb3RoZXJQcmltZUluZm8pCisgICAgICogPC9jb2RlPiBjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgY3J0Q29lZmZpY2llbnQgaXMgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMwOSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMoCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICBvcGkpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTlBFIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMTAgZm9yCisgICAgICogPGNvZGU+UlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjKEJpZ0ludGVnZXIgbW9kdWx1cywKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwdWJsaWNFeHBvbmVudCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcml2YXRlRXhwb25lbnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVQLAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lUSwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZUV4cG9uZW50UCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZUV4cG9uZW50USwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBjcnRDb2VmZmljaWVudCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlNBT3RoZXJQcmltZUluZm9bXSBvdGhlclByaW1lSW5mbykKKyAgICAgKiA8L2NvZGU+IGN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiBvdGhlclByaW1lSW5mbyBjYW4gYmUgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMxMCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMoCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiBpcyB0aHJvd24iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzExIGZvcgorICAgICAqIDxjb2RlPlJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYyhCaWdJbnRlZ2VyIG1vZHVsdXMsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHVibGljRXhwb25lbnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpdmF0ZUV4cG9uZW50LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lUCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZVEsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVFeHBvbmVudFAsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVFeHBvbmVudFEsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgY3J0Q29lZmZpY2llbnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJTQU90aGVyUHJpbWVJbmZvW10gb3RoZXJQcmltZUluZm8pCisgICAgICogPC9jb2RlPiBjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIG90aGVyUHJpbWVJbmZvIGxlbmd0aCBpcyAwCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYzExKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbmV3IFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYygKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBuZXcgUlNBT3RoZXJQcmltZUluZm9bMF0pOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgSUFFIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzEyIGZvcgorICAgICAqIDxjb2RlPlJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYyhCaWdJbnRlZ2VyIG1vZHVsdXMsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHVibGljRXhwb25lbnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpdmF0ZUV4cG9uZW50LAorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lUCwKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZVEsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVFeHBvbmVudFAsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJpbWVFeHBvbmVudFEsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgY3J0Q29lZmZpY2llbnQsCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJTQU90aGVyUHJpbWVJbmZvW10gb3RoZXJQcmltZUluZm8pCisgICAgICogPC9jb2RlPiBjdG9yPGJyPgorICAgICAqIEFzc2VydGlvbjogY29uc3RydWN0cyA8Y29kZT5SU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWM8L2NvZGU+CisgICAgICogb2JqZWN0IHVzaW5nIHZhbGlkIHBhcmFtZXRlcnMuIENvbnN0cnVjdGVkIG9iamVjdCBtdXN0IGJlCisgICAgICogaW5zdGFuY2Ugb2YgUlNBUHJpdmF0ZUtleVNwZWMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYzEyKCkgeworICAgICAgICBLZXlTcGVjIGtzID0gbmV3IFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYygKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBvcGkpOworICAgICAgICBhc3NlcnRUcnVlKGtzIGluc3RhbmNlb2YgUlNBUHJpdmF0ZUtleVNwZWMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldENydENvZWZmaWNpZW50KCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgY3J0IGNvZWZmaWNpZW50CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldENydENvZWZmaWNpZW50KCkgeworICAgICAgICBSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMga3MgPQorICAgICAgICAgICAgbmV3IFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYygKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBvcGkpOworICAgICAgICBhc3NlcnRUcnVlKEJpZ0ludGVnZXIuT05FLmVxdWFscyhrcy5nZXRDcnRDb2VmZmljaWVudCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UHJpbWVFeHBvbmVudFAoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBwcmltZSBleHBvbmVudCBQCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFByaW1lRXhwb25lbnRQKCkgeworICAgICAgICBSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMga3MgPQorICAgICAgICAgICAgbmV3IFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYygKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBvcGkpOworICAgICAgICBhc3NlcnRUcnVlKEJpZ0ludGVnZXIuT05FLmVxdWFscyhrcy5nZXRQcmltZUV4cG9uZW50UCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UHJpbWVFeHBvbmVudFEoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBwcmltZSBleHBvbmVudCBRCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFByaW1lRXhwb25lbnRRKCkgeworICAgICAgICBSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMga3MgPQorICAgICAgICAgICAgbmV3IFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYygKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBvcGkpOworICAgICAgICBhc3NlcnRUcnVlKEJpZ0ludGVnZXIuT05FLmVxdWFscyhrcy5nZXRQcmltZUV4cG9uZW50USgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UHJpbWVQKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgcHJpbWUgUAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRQcmltZVAoKSB7CisgICAgICAgIFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYyBrcyA9CisgICAgICAgICAgICBuZXcgUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjKAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIG9waSk7CisgICAgICAgIGFzc2VydFRydWUoQmlnSW50ZWdlci5PTkUuZXF1YWxzKGtzLmdldFByaW1lUCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UHJpbWVRKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgcHJpbWUgUQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRQcmltZVEoKSB7CisgICAgICAgIFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYyBrcyA9CisgICAgICAgICAgICBuZXcgUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjKAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIG9waSk7CisgICAgICAgIGFzc2VydFRydWUoQmlnSW50ZWdlci5PTkUuZXF1YWxzKGtzLmdldFByaW1lUSgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UHVibGljRXhwb25lbnQoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBwdWJsaWMgZXhwb25lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0UHVibGljRXhwb25lbnQoKSB7CisgICAgICAgIFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYyBrcyA9CisgICAgICAgICAgICBuZXcgUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjKAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIG9waSk7CisgICAgICAgIGFzc2VydFRydWUoQmlnSW50ZWdlci5PTkUuZXF1YWxzKGtzLmdldFB1YmxpY0V4cG9uZW50KCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5nZXRPdGhlclByaW1lSW5mbygpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIGFycmF5IG9mIFJTQU90aGVyUHJpbWVJbmZvCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldE90aGVyUHJpbWVJbmZvMDEoKSB7CisgICAgICAgIFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYyBrcyA9CisgICAgICAgICAgICBuZXcgUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjKAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIG9waSk7CisgICAgICAgIGFzc2VydFRydWUoY2hlY2tPdGhlclByaW1lSW5mbyhrcy5nZXRPdGhlclByaW1lSW5mbygpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+Z2V0T3RoZXJQcmltZUluZm8oKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBudWxsIGlmIG51bGwgaGFzIGJlZW4gcGFzc2VkIHRvIHRoZQorICAgICAqIGNvbnN0cnVjdG9yIGFzIG90aGVyUHJpbWVJbmZvIHBhcmFtZXRlcgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRPdGhlclByaW1lSW5mbzAyKCkgeworICAgICAgICBSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMga3MgPQorICAgICAgICAgICAgbmV3IFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYygKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBudWxsKTsKKyAgICAgICAgYXNzZXJ0TnVsbChrcy5nZXRPdGhlclByaW1lSW5mbygpKTsKKyAgICB9CisKKyAgICAvLworICAgIC8vIGltbXV0YWJpbGl0eSB0ZXN0cworICAgIC8vCisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB0aGF0IGludGVybmFsIHN0YXRlIG9mIHRoZSBvYmplY3QKKyAgICAgKiBjYW4gbm90IGJlIG1vZGlmaWVkIGJ5IG1vZGlmeWluZyBpbml0aWFsIGFycmF5CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdElzU3RhdGVQcmVzZXJ2ZWQxKCkgeworICAgICAgICAvLyBDcmVhdGUgaW5pdGlhbCBhcnJheQorICAgICAgICBSU0FPdGhlclByaW1lSW5mb1tdIG9waTEgPSBvcGkuY2xvbmUoKTsKKworICAgICAgICBSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMga3MgPSBuZXcgUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjKAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIG9waTEpOworCisgICAgICAgIC8vIE1vZGlmeSBpbml0aWFsIGFycmF5CisgICAgICAgIG9waTFbMl0gPSBuZXcgUlNBT3RoZXJQcmltZUluZm8oQmlnSW50ZWdlci5aRVJPLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuWkVSTywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLlpFUk8pOworCisgICAgICAgIC8vIENoZWNrIHRoYXQgYWJvdmUgbW9kaWZpY2F0aW9uCisgICAgICAgIC8vIGRvZXMgbm90IGFmZmVjdCBpbnRlcm5hbCBzdGF0ZQorICAgICAgICBhc3NlcnRUcnVlKGNoZWNrT3RoZXJQcmltZUluZm8oa3MuZ2V0T3RoZXJQcmltZUluZm8oKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHRoYXQgaW50ZXJuYWwgc3RhdGUgb2YgdGhlIG9iamVjdAorICAgICAqIGNhbiBub3QgYmUgbW9kaWZpZWQgdXNpbmcgYXJyYXkgcmVmZXJlbmNlCisgICAgICogcmV0dXJuZWQgYnkgPGNvZGU+Z2V0T3RoZXJQcmltZUluZm8oKTwvY29kZT4KKyAgICAgKiBtZXRob2QKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0SXNTdGF0ZVByZXNlcnZlZDIoKSB7CisgICAgICAgIC8vIENyZWF0ZSBpbml0aWFsIGFycmF5CisgICAgICAgIFJTQU90aGVyUHJpbWVJbmZvW10gb3BpMSA9IG9waS5jbG9uZSgpOworCisgICAgICAgIFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYyBrcyA9IG5ldyBSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMoCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgb3BpMSk7CisKKyAgICAgICAgUlNBT3RoZXJQcmltZUluZm9bXSByZXQgPSBrcy5nZXRPdGhlclByaW1lSW5mbygpOworCisgICAgICAgIC8vIE1vZGlmeSByZXR1cm5lZCBhcnJheQorICAgICAgICByZXRbMl0gPSBuZXcgUlNBT3RoZXJQcmltZUluZm8oQmlnSW50ZWdlci5aRVJPLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuWkVSTywKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLlpFUk8pOworCisgICAgICAgIC8vIENoZWNrIHRoYXQgYWJvdmUgbW9kaWZpY2F0aW9uCisgICAgICAgIC8vIGRvZXMgbm90IGFmZmVjdCBpbnRlcm5hbCBzdGF0ZQorICAgICAgICBhc3NlcnRUcnVlKGNoZWNrT3RoZXJQcmltZUluZm8oa3MuZ2V0T3RoZXJQcmltZUluZm8oKSkpOworICAgIH0KKworICAgIC8vCisgICAgLy8gVGVzdHMgZm9yIGluaGVyaXRlZCBtZXRob2RzCisgICAgLy8KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldE1vZHVsdXMoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBtb2R1bHVzCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldE1vZHVsdXMoKSB7CisgICAgICAgIFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYyBrcyA9CisgICAgICAgICAgICBuZXcgUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlTcGVjKAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIG9waSk7CisgICAgICAgIGFzc2VydFRydWUoQmlnSW50ZWdlci5PTkUuZXF1YWxzKGtzLmdldE1vZHVsdXMoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldFByaXZhdGVFeHBvbmVudCgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHByaXZhdGUgZXhwb25lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0UHJpdmF0ZUV4cG9uZW50KCkgeworICAgICAgICBSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleVNwZWMga3MgPQorICAgICAgICAgICAgbmV3IFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5U3BlYygKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgICAgICBvcGkpOworICAgICAgICBhc3NlcnRUcnVlKEJpZ0ludGVnZXIuT05FLmVxdWFscyhrcy5nZXRQcml2YXRlRXhwb25lbnQoKSkpOworICAgIH0KKworLy8gcHJpdmF0ZSBzdHVmZgorLy8KKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyBhcnJheSBwYXNzZWQgYXMgYSBwYXJhbWV0ZXIgd2l0aCByZWZlcmVuY2Ugb25lPGJyPgorICAgICAqCisgICAgICogIDxjb2RlPnByaXZhdGUgc3RhdGljIGZpbmFsIFJTQU90aGVyUHJpbWVJbmZvW10gb3BpPC9jb2RlPgorICAgICAqCisgICAgICogQHBhcmFtIHRvQmVDaGVja2VkCisgICAgICogIEFycmF5IHRvIGJlIGNvbXBhcmVkCisgICAgICogQHJldHVybgorICAgICAqICB0cnVlIGlmIGFycmF5cyBhcmUgZXF1YWwKKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gY2hlY2tPdGhlclByaW1lSW5mbyhSU0FPdGhlclByaW1lSW5mb1tdIHRvQmVDaGVja2VkKSB7CisgICAgICAgIGlmICh0b0JlQ2hlY2tlZCA9PSBudWxsIHx8IHRvQmVDaGVja2VkLmxlbmd0aCAhPSBvcGkubGVuZ3RoKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPG9waS5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKG9waVtpXS5nZXRQcmltZSgpLmVxdWFscyh0b0JlQ2hlY2tlZFtpXS5nZXRQcmltZSgpKSAmJgorICAgICAgICAgICAgICAgIG9waVtpXS5nZXRFeHBvbmVudCgpLmVxdWFscyh0b0JlQ2hlY2tlZFtpXS5nZXRFeHBvbmVudCgpKSAmJgorICAgICAgICAgICAgICAgIG9waVtpXS5nZXRDcnRDb2VmZmljaWVudCgpLmVxdWFscyh0b0JlQ2hlY2tlZFtpXS5nZXRDcnRDb2VmZmljaWVudCgpKSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvUlNBT3RoZXJQcmltZUluZm9UZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9SU0FPdGhlclByaW1lSW5mb1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZDEyOGUwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvUlNBT3RoZXJQcmltZUluZm9UZXN0LmphdmEKQEAgLTAsMCArMSwxNDEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5SU0FPdGhlclByaW1lSW5mbzsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+UlNBT3RoZXJQcmltZUluZm88L2NvZGU+IGNsYXNzIGZpZWxkcyBhbmQgbWV0aG9kcy4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBSU0FPdGhlclByaW1lSW5mb1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5SU0FPdGhlclByaW1lSW5mbyhCaWdJbnRlZ2VyLEJpZ0ludGVnZXIsQmlnSW50ZWdlcik8L2NvZGU+IGN0b3IKKyAgICAgKiBBc3NlcnRpb246IGNvbnN0cnVjdHMgPGNvZGU+UlNBT3RoZXJQcmltZUluZm88L2NvZGU+CisgICAgICogb2JqZWN0IHVzaW5nIHZhbGlkIHBhcmFtZXRlcgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RSU0FPdGhlclByaW1lSW5mbzAxKCkgeworICAgICAgICBPYmplY3QgbyA9CisgICAgICAgICAgICBuZXcgUlNBT3RoZXJQcmltZUluZm8oQmlnSW50ZWdlci52YWx1ZU9mKDFMKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoMkwpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZigzTCkpOworICAgICAgICBhc3NlcnRUcnVlKG8gaW5zdGFuY2VvZiBSU0FPdGhlclByaW1lSW5mbyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+UlNBT3RoZXJQcmltZUluZm8oQmlnSW50ZWdlcixCaWdJbnRlZ2VyLEJpZ0ludGVnZXIpPC9jb2RlPiBjdG9yCisgICAgICogQXNzZXJ0aW9uOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBwcmltZSBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJTQU90aGVyUHJpbWVJbmZvMDIoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUlNBT3RoZXJQcmltZUluZm8obnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoMkwpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZigzTCkpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTlBFIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMyBmb3IgPGNvZGU+UlNBT3RoZXJQcmltZUluZm8oQmlnSW50ZWdlcixCaWdJbnRlZ2VyLEJpZ0ludGVnZXIpPC9jb2RlPiBjdG9yCisgICAgICogQXNzZXJ0aW9uOiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBwcmltZUV4cG9uZW50IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UlNBT3RoZXJQcmltZUluZm8wMygpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBSU0FPdGhlclByaW1lSW5mbyhCaWdJbnRlZ2VyLnZhbHVlT2YoMUwpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci52YWx1ZU9mKDNMKSk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOUEUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM0IGZvciA8Y29kZT5SU0FPdGhlclByaW1lSW5mbyhCaWdJbnRlZ2VyLEJpZ0ludGVnZXIsQmlnSW50ZWdlcik8L2NvZGU+IGN0b3IKKyAgICAgKiBBc3NlcnRpb246IE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGNydENvZWZmaWNpZW50IGlzIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UlNBT3RoZXJQcmltZUluZm8wNCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ldyBSU0FPdGhlclByaW1lSW5mbyhCaWdJbnRlZ2VyLnZhbHVlT2YoMUwpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZigyTCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBOUEUgbm90IHRocm93biIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICM1IGZvciA8Y29kZT5SU0FPdGhlclByaW1lSW5mbyhCaWdJbnRlZ2VyLEJpZ0ludGVnZXIsQmlnSW50ZWdlcik8L2NvZGU+IGN0b3IKKyAgICAgKiBBc3NlcnRpb246IE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHByaW1lIGFuZCBjcnRDb2VmZmljaWVudCBpcyBudWxsCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJTQU90aGVyUHJpbWVJbmZvMDUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBuZXcgUlNBT3RoZXJQcmltZUluZm8obnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoMkwpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOworICAgICAgICAgICAgZmFpbCgiRXhwZWN0ZWQgTlBFIG5vdCB0aHJvd24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0Q3J0Q29lZmZpY2llbnQoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBDUlQgY29lZmZpY2llbnQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0Q3J0Q29lZmZpY2llbnQoKSB7CisgICAgICAgIFJTQU90aGVyUHJpbWVJbmZvIHJvcGkgPQorICAgICAgICAgICAgbmV3IFJTQU90aGVyUHJpbWVJbmZvKEJpZ0ludGVnZXIudmFsdWVPZigxTCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci52YWx1ZU9mKDJMKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoM0wpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDNMLCByb3BpLmdldENydENvZWZmaWNpZW50KCkubG9uZ1ZhbHVlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldFByaW1lKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgcHJpbWUgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0UHJpbWUoKSB7CisgICAgICAgIFJTQU90aGVyUHJpbWVJbmZvIHJvcGkgPQorICAgICAgICAgICAgbmV3IFJTQU90aGVyUHJpbWVJbmZvKEJpZ0ludGVnZXIudmFsdWVPZigxTCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci52YWx1ZU9mKDJMKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoM0wpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDFMLCByb3BpLmdldFByaW1lKCkubG9uZ1ZhbHVlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEV4cG9uZW50KCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgcHJpbWUgZXhwb25lbnQgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0RXhwb25lbnQoKSB7CisgICAgICAgIFJTQU90aGVyUHJpbWVJbmZvIHJvcGkgPQorICAgICAgICAgICAgbmV3IFJTQU90aGVyUHJpbWVJbmZvKEJpZ0ludGVnZXIudmFsdWVPZigxTCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci52YWx1ZU9mKDJMKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoM0wpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDJMLCByb3BpLmdldEV4cG9uZW50KCkubG9uZ1ZhbHVlKCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvUlNBUHJpdmF0ZUNydEtleVNwZWNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9SU0FQcml2YXRlQ3J0S2V5U3BlY1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMTllY2M3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvUlNBUHJpdmF0ZUNydEtleVNwZWNUZXN0LmphdmEKQEAgLTAsMCArMSwyMzEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZsYWRpbWlyIE4uIE1vbG90a292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHkuc3BlYzsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5LZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5SU0FQcml2YXRlQ3J0S2V5U3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuUlNBUHJpdmF0ZUtleVNwZWM7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlJTQVByaXZhdGVDcnRLZXlTcGVjPC9jb2RlPiBjbGFzcyBmaWVsZHMgYW5kIG1ldGhvZHMKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBSU0FQcml2YXRlQ3J0S2V5U3BlY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5SU0FQcml2YXRlQ3J0S2V5U3BlYzwvY29kZT4gY29uc3RydWN0b3IKKyAgICAgKiBBc3NlcnRpb246IENvbnN0cnVjdHMgPGNvZGU+UlNBUHJpdmF0ZUNydEtleVNwZWM8L2NvZGU+CisgICAgICogb2JqZWN0IHVzaW5nIHZhbGlkIHBhcmFtZXRlcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UlNBUHJpdmF0ZUNydEtleVNwZWMwMSgpIHsKKyAgICAgICAgS2V5U3BlYyBrcyA9IG5ldyBSU0FQcml2YXRlQ3J0S2V5U3BlYygKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSk7CisgICAgICAgIGFzc2VydFRydWUoa3MgaW5zdGFuY2VvZiBSU0FQcml2YXRlQ3J0S2V5U3BlYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCAjMiBmb3IgPGNvZGU+UlNBUHJpdmF0ZUNydEtleVNwZWM8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBDb25zdHJ1Y3RzIDxjb2RlPlJTQVByaXZhdGVDcnRLZXlTcGVjPC9jb2RlPgorICAgICAqIG9iamVjdCB1c2luZyB2YWxpZCBwYXJhbWV0ZXJzCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJTQVByaXZhdGVDcnRLZXlTcGVjMDIoKSB7CisgICAgICAgIEtleVNwZWMga3MgPSBuZXcgUlNBUHJpdmF0ZUNydEtleVNwZWMoCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUpOworICAgICAgICBhc3NlcnRUcnVlKGtzIGluc3RhbmNlb2YgUlNBUHJpdmF0ZUtleVNwZWMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzMgZm9yIDxjb2RlPlJTQVByaXZhdGVDcnRLZXlTcGVjPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogQ29uc3RydWN0cyA8Y29kZT5SU0FQcml2YXRlQ3J0S2V5U3BlYzwvY29kZT4KKyAgICAgKiBvYmplY3QgdXNpbmcgdmFsaWQgcGFyYW1ldGVycworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RSU0FQcml2YXRlQ3J0S2V5U3BlYzAzKCkgeworICAgICAgICBuZXcgUlNBUHJpdmF0ZUNydEtleVNwZWMoCisgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgIG51bGwsCisgICAgICAgICAgICAgICAgbnVsbCwKKyAgICAgICAgICAgICAgICBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRDcnRDb2VmZmljaWVudCgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIGNydCBjb2VmZmljaWVudAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRDcnRDb2VmZmljaWVudCgpIHsKKyAgICAgICAgUlNBUHJpdmF0ZUNydEtleVNwZWMga3MgPSBuZXcgUlNBUHJpdmF0ZUNydEtleVNwZWMoCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci52YWx1ZU9mKDVMKSk7CisgICAgICAgIGFzc2VydFRydWUoQmlnSW50ZWdlci52YWx1ZU9mKDVMKS5lcXVhbHMoa3MuZ2V0Q3J0Q29lZmZpY2llbnQoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldFByaW1lRXhwb25lbnRQKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgcHJpbWUgZXhwb25lbnQgUAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRQcmltZUV4cG9uZW50UCgpIHsKKyAgICAgICAgUlNBUHJpdmF0ZUNydEtleVNwZWMga3MgPSBuZXcgUlNBUHJpdmF0ZUNydEtleVNwZWMoCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci52YWx1ZU9mKDVMKSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSk7CisgICAgICAgIGFzc2VydFRydWUoQmlnSW50ZWdlci52YWx1ZU9mKDVMKS5lcXVhbHMoa3MuZ2V0UHJpbWVFeHBvbmVudFAoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldFByaW1lRXhwb25lbnRRKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgcHJpbWUgZXhwb25lbnQgUQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRQcmltZUV4cG9uZW50USgpIHsKKyAgICAgICAgUlNBUHJpdmF0ZUNydEtleVNwZWMga3MgPSBuZXcgUlNBUHJpdmF0ZUNydEtleVNwZWMoCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci52YWx1ZU9mKDVMKSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSk7CisgICAgICAgIGFzc2VydFRydWUoQmlnSW50ZWdlci52YWx1ZU9mKDVMKS5lcXVhbHMoa3MuZ2V0UHJpbWVFeHBvbmVudFEoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldFByaW1lUCgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHByaW1lIFAKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0UHJpbWVQKCkgeworICAgICAgICBSU0FQcml2YXRlQ3J0S2V5U3BlYyBrcyA9IG5ldyBSU0FQcml2YXRlQ3J0S2V5U3BlYygKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoNUwpLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShCaWdJbnRlZ2VyLnZhbHVlT2YoNUwpLmVxdWFscyhrcy5nZXRQcmltZVAoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldFByaW1lUSgpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIHByaW1lIFEKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0UHJpbWVRKCkgeworICAgICAgICBSU0FQcml2YXRlQ3J0S2V5U3BlYyBrcyA9IG5ldyBSU0FQcml2YXRlQ3J0S2V5U3BlYygKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoNUwpLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShCaWdJbnRlZ2VyLnZhbHVlT2YoNUwpLmVxdWFscyhrcy5nZXRQcmltZVEoKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldFB1YmxpY0V4cG9uZW50KCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgcHVibGljIGV4cG9uZW50CisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldFB1YmxpY0V4cG9uZW50KCkgeworICAgICAgICBSU0FQcml2YXRlQ3J0S2V5U3BlYyBrcyA9IG5ldyBSU0FQcml2YXRlQ3J0S2V5U3BlYygKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoNUwpLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShCaWdJbnRlZ2VyLnZhbHVlT2YoNUwpLmVxdWFscyhrcy5nZXRQdWJsaWNFeHBvbmVudCgpKSk7CisgICAgfQorCisgICAgLy8KKyAgICAvLyBUZXN0cyBmb3IgaW5oZXJpdGVkIG1ldGhvZHMKKyAgICAvLworCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0TW9kdWx1cygpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIG1vZHVsdXMKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0TW9kdWx1cygpIHsKKyAgICAgICAgUlNBUHJpdmF0ZUNydEtleVNwZWMga3MgPSBuZXcgUlNBUHJpdmF0ZUNydEtleVNwZWMoCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci52YWx1ZU9mKDVMKSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSwKKyAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORSk7CisgICAgICAgIGFzc2VydFRydWUoQmlnSW50ZWdlci52YWx1ZU9mKDVMKS5lcXVhbHMoa3MuZ2V0TW9kdWx1cygpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UHJpdmF0ZUV4cG9uZW50KCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgcHJpdmF0ZSBleHBvbmVudAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRQcml2YXRlRXhwb25lbnQoKSB7CisgICAgICAgIFJTQVByaXZhdGVDcnRLZXlTcGVjIGtzID0gbmV3IFJTQVByaXZhdGVDcnRLZXlTcGVjKAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIuT05FLAorICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZig1TCksCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUsCisgICAgICAgICAgICAgICAgQmlnSW50ZWdlci5PTkUpOworICAgICAgICBhc3NlcnRUcnVlKEJpZ0ludGVnZXIudmFsdWVPZig1TCkuZXF1YWxzKGtzLmdldFByaXZhdGVFeHBvbmVudCgpKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9SU0FQcml2YXRlS2V5U3BlY1Rlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL1JTQVByaXZhdGVLZXlTcGVjVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQxMWQ0ZDIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9SU0FQcml2YXRlS2V5U3BlY1Rlc3QuamF2YQpAQCAtMCwwICsxLDcwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LnNwZWM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuS2V5U3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuUlNBUHJpdmF0ZUtleVNwZWM7CisKKy8qKgorICogVGVzdHMgZm9yIDxjb2RlPlJTQVByaXZhdGVLZXlTcGVjPC9jb2RlPiBjbGFzcyBmaWVsZHMgYW5kIG1ldGhvZHMKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBSU0FQcml2YXRlS2V5U3BlY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5SU0FQcml2YXRlS2V5U3BlYyhCaWdJbnRlZ2VyLEJpZ0ludGVnZXIpPC9jb2RlPiBjdG9yCisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIDxjb2RlPlJTQVByaXZhdGVLZXlTcGVjPC9jb2RlPgorICAgICAqIG9iamVjdCB1c2luZyB2YWxpZCBwYXJhbWV0ZXJzCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJTQVByaXZhdGVLZXlTcGVjKCkgeworICAgICAgICBLZXlTcGVjIGtzID0gbmV3IFJTQVByaXZhdGVLZXlTcGVjKEJpZ0ludGVnZXIudmFsdWVPZigxMjM0NTY3ODkwTCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci52YWx1ZU9mKDNMKSk7CisgICAgICAgIGFzc2VydFRydWUoa3MgaW5zdGFuY2VvZiBSU0FQcml2YXRlS2V5U3BlYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0TW9kdWx1cygpPC9jb2RlPiBtZXRob2Q8YnI+CisgICAgICogQXNzZXJ0aW9uOiByZXR1cm5zIG1vZHVsdXMKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0TW9kdWx1cygpIHsKKyAgICAgICAgUlNBUHJpdmF0ZUtleVNwZWMgcnBrcyA9CisgICAgICAgICAgICBuZXcgUlNBUHJpdmF0ZUtleVNwZWMoQmlnSW50ZWdlci52YWx1ZU9mKDEyMzQ1Njc4OTBMKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoM0wpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEyMzQ1Njc4OTBMLCBycGtzLmdldE1vZHVsdXMoKS5sb25nVmFsdWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UHJpdmF0ZUV4cG9uZW50KCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgcHJpdmF0ZSBleHBvbmVudAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRQcml2YXRlRXhwb25lbnQoKSB7CisgICAgICAgIFJTQVByaXZhdGVLZXlTcGVjIHJwa3MgPQorICAgICAgICAgICAgbmV3IFJTQVByaXZhdGVLZXlTcGVjKEJpZ0ludGVnZXIudmFsdWVPZigxMjM0NTY3ODkwTCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci52YWx1ZU9mKDNMKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzTCwgcnBrcy5nZXRQcml2YXRlRXhwb25lbnQoKS5sb25nVmFsdWUoKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9SU0FQdWJsaWNLZXlTcGVjVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvUlNBUHVibGljS2V5U3BlY1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NmExMDM0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWMvUlNBUHVibGljS2V5U3BlY1Rlc3QuamF2YQpAQCAtMCwwICsxLDg0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5LnNwZWM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuS2V5U3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuUlNBUHVibGljS2V5U3BlYzsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+UlNBUHVibGljS2V5U3BlYzwvY29kZT4gY2xhc3MgZmllbGRzIGFuZCBtZXRob2RzCisgKgorICovCitwdWJsaWMgY2xhc3MgUlNBUHVibGljS2V5U3BlY1Rlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICAvKioKKyAgICAgKiBUZXN0ICMxIGZvciA8Y29kZT5SU0FQdWJsaWNLZXlTcGVjPC9jb2RlPiBjb25zdHJ1Y3RvcgorICAgICAqIEFzc2VydGlvbjogQ29uc3RydWN0cyA8Y29kZT5SU0FQdWJsaWNLZXlTcGVjPC9jb2RlPgorICAgICAqIG9iamVjdCB1c2luZyB2YWxpZCBwYXJhbWV0ZXJzCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdFJTQVB1YmxpY0tleVNwZWMwMSgpIHsKKyAgICAgICAgS2V5U3BlYyBrcyA9CisgICAgICAgICAgICBuZXcgUlNBUHVibGljS2V5U3BlYyhCaWdJbnRlZ2VyLnZhbHVlT2YoMTIzNDU2Nzg5MEwpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci52YWx1ZU9mKDNMKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShrcyBpbnN0YW5jZW9mIFJTQVB1YmxpY0tleVNwZWMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgIzIgZm9yIDxjb2RlPlJTQVB1YmxpY0tleVNwZWM8L2NvZGU+IGNvbnN0cnVjdG9yCisgICAgICogQXNzZXJ0aW9uOiBDb25zdHJ1Y3RzIDxjb2RlPlJTQVB1YmxpY0tleVNwZWM8L2NvZGU+CisgICAgICogb2JqZWN0IHVzaW5nIHZhbGlkIHBhcmFtZXRlcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0UlNBUHVibGljS2V5U3BlYzAyKCkgeworICAgICAgICBLZXlTcGVjIGtzID0KKyAgICAgICAgICAgIG5ldyBSU0FQdWJsaWNLZXlTcGVjKG51bGwsIG51bGwpOworCisgICAgICAgIGFzc2VydFRydWUoa3MgaW5zdGFuY2VvZiBSU0FQdWJsaWNLZXlTcGVjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGZvciA8Y29kZT5nZXRNb2R1bHVzKCk8L2NvZGU+IG1ldGhvZDxicj4KKyAgICAgKiBBc3NlcnRpb246IHJldHVybnMgbW9kdWx1cworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRNb2R1bHVzKCkgeworICAgICAgICBSU0FQdWJsaWNLZXlTcGVjIHJwa3MgPQorICAgICAgICAgICAgbmV3IFJTQVB1YmxpY0tleVNwZWMoQmlnSW50ZWdlci52YWx1ZU9mKDEyMzQ1Njc4OTBMKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZigzTCkpOworICAgICAgICBhc3NlcnRUcnVlKEJpZ0ludGVnZXIudmFsdWVPZigxMjM0NTY3ODkwTCkuZXF1YWxzKHJwa3MuZ2V0TW9kdWx1cygpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0UHVibGljRXhwb25lbnQoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBwdWJsaWMgZXhwb25lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCB0ZXN0R2V0UHVibGljRXhwb25lbnQoKSB7CisgICAgICAgIFJTQVB1YmxpY0tleVNwZWMgcnBrcyA9CisgICAgICAgICAgICBuZXcgUlNBUHVibGljS2V5U3BlYyhCaWdJbnRlZ2VyLnZhbHVlT2YoM0wpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlci52YWx1ZU9mKDEyMzQ1Njc4OTBMKSk7CisgICAgICAgIGFzc2VydFRydWUoQmlnSW50ZWdlci52YWx1ZU9mKDEyMzQ1Njc4OTBMKS5lcXVhbHMocnBrcy5nZXRQdWJsaWNFeHBvbmVudCgpKSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9YNTA5RW5jb2RlZEtleVNwZWNUZXN0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvc3BlYy9YNTA5RW5jb2RlZEtleVNwZWNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTI5Mjk4MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjL1g1MDlFbmNvZGVkS2V5U3BlY1Rlc3QuamF2YQpAQCAtMCwwICsxLDEzNyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eS5zcGVjOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkVuY29kZWRLZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5QS0NTOEVuY29kZWRLZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5YNTA5RW5jb2RlZEtleVNwZWM7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKKworLyoqCisgKiBUZXN0cyBmb3IgPGNvZGU+WDUwOUVuY29kZWRLZXlTcGVjPC9jb2RlPiBjbGFzcyBmaWVsZHMgYW5kIG1ldGhvZHMKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBYNTA5RW5jb2RlZEtleVNwZWNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLy8KKyAgICAvLyBUZXN0IGNhc2VzCisgICAgLy8KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPlg1MDlFbmNvZGVkS2V5U3BlYzwvY29kZT4gY29uc3RydWN0b3I8YnI+CisgICAgICogQXNzZXJ0aW9uOiBjb25zdHJ1Y3RzIG5ldyA8Y29kZT5YNTA5RW5jb2RlZEtleVNwZWM8L2NvZGU+CisgICAgICogb2JqZWN0IHVzaW5nIHZhbGlkIHBhcmFtZXRlcgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RYNTA5RW5jb2RlZEtleVNwZWMoKSB7CisgICAgICAgIGJ5dGVbXSBlbmNvZGVkS2V5ID0gbmV3IGJ5dGVbXSB7KGJ5dGUpMSwoYnl0ZSkyLChieXRlKTMsKGJ5dGUpNH07CisKKyAgICAgICAgRW5jb2RlZEtleVNwZWMgZWtzID0gbmV3IFg1MDlFbmNvZGVkS2V5U3BlYyhlbmNvZGVkS2V5KTsKKworICAgICAgICBhc3NlcnRUcnVlKGVrcyBpbnN0YW5jZW9mIFg1MDlFbmNvZGVkS2V5U3BlYyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBla3MgPSBuZXcgWDUwOUVuY29kZWRLZXlTcGVjKG51bGwpOworICAgICAgICAgICAgZmFpbCgiZXhwZWN0ZWQgTnVsbFBvaW50ZXJFeGNlcHRpb24iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gb2sKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZm9yIDxjb2RlPmdldEVuY29kZWQoKTwvY29kZT4gbWV0aG9kPGJyPgorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBlbmNvZGVkIGtleQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RHZXRFbmNvZGVkKCkgeworICAgICAgICBieXRlW10gZW5jb2RlZEtleSA9IG5ldyBieXRlW10geyhieXRlKTEsKGJ5dGUpMiwoYnl0ZSkzLChieXRlKTR9OworCisgICAgICAgIFg1MDlFbmNvZGVkS2V5U3BlYyBla3MgPSBuZXcgWDUwOUVuY29kZWRLZXlTcGVjKGVuY29kZWRLZXkpOworCisgICAgICAgIGJ5dGVbXSBlayA9IGVrcy5nZXRFbmNvZGVkKCk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGVuY29kZWRLZXksIGVrKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBmb3IgPGNvZGU+Z2V0Rm9ybWF0KCk8L2NvZGU+IG1ldGhvZAorICAgICAqIEFzc2VydGlvbjogcmV0dXJucyBmb3JtYXQgbmFtZSAoYWx3YXlzICJYLjUwOSIpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdEdldEZvcm1hdCgpIHsKKyAgICAgICAgYnl0ZVtdIGVuY29kZWRLZXkgPSBuZXcgYnl0ZVtdIHsoYnl0ZSkxLChieXRlKTIsKGJ5dGUpMywoYnl0ZSk0fTsKKworICAgICAgICBYNTA5RW5jb2RlZEtleVNwZWMgbWVrcyA9IG5ldyBYNTA5RW5jb2RlZEtleVNwZWMoZW5jb2RlZEtleSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJYLjUwOSIsIG1la3MuZ2V0Rm9ybWF0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHRoYXQgaW50ZXJuYWwgc3RhdGUgb2YgdGhlIG9iamVjdAorICAgICAqIGNhbiBub3QgYmUgY2hhbmdlZCBieSBtb2RpZnlpbmcgaW5pdGlhbAorICAgICAqIGFycmF5IHZhbHVlCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgdGVzdElzU3RhdGVQcmVzZXJ2ZWQxKCkgeworICAgICAgICAvLyBSZWZlcmVuY2UgYXJyYXkKKyAgICAgICAgYnl0ZVtdIGVuY29kZWRLZXkgPSBuZXcgYnl0ZVtdIHsoYnl0ZSkxLChieXRlKTIsKGJ5dGUpMywoYnl0ZSk0fTsKKyAgICAgICAgLy8gUmVmZXJlbmNlIGFycmF5J3MgY29weSB3aWxsIGJlIHVzZWQgZm9yIHRlc3QKKyAgICAgICAgYnl0ZVtdIGVuY29kZWRLZXlDb3B5ID0gZW5jb2RlZEtleS5jbG9uZSgpOworCisgICAgICAgIFg1MDlFbmNvZGVkS2V5U3BlYyBtZWtzID0gbmV3IFg1MDlFbmNvZGVkS2V5U3BlYyhlbmNvZGVkS2V5Q29weSk7CisKKyAgICAgICAgLy8gTW9kaWZ5IGluaXRpYWwgYXJyYXkncyB2YWx1ZQorICAgICAgICBlbmNvZGVkS2V5Q29weVszXSA9IChieXRlKTU7CisKKyAgICAgICAgLy8gR2V0IGVuY29kZWQga2V5CisgICAgICAgIGJ5dGVbXSBlayA9IG1la3MuZ2V0RW5jb2RlZCgpOworCisgICAgICAgIC8vIENoZWNrICB1c2luZyByZWZlcmVuY2UgYXJyYXkgdGhhdAorICAgICAgICAvLyBieXRlIHZhbHVlIGhhcyBub3QgYmVlbiBjaGFuZ2VkCisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhlbmNvZGVkS2V5LCBlaykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHRoYXQgaW50ZXJuYWwgc3RhdGUgb2YgdGhlIG9iamVjdAorICAgICAqIGNhbiBub3QgYmUgbW9kaWZpZWQgdXNpbmcgcmV0dXJuZWQgdmFsdWUKKyAgICAgKiBvZiA8Y29kZT5nZXRFbmNvZGVkKCk8L2NvZGU+IG1ldGhvZAorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRlc3RJc1N0YXRlUHJlc2VydmVkMigpIHsKKyAgICAgICAgLy8gUmVmZXJlbmNlIGFycmF5CisgICAgICAgIGJ5dGVbXSBlbmNvZGVkS2V5ID0gbmV3IGJ5dGVbXSB7KGJ5dGUpMSwoYnl0ZSkyLChieXRlKTMsKGJ5dGUpNH07CisgICAgICAgIC8vIFJlZmVyZW5jZSBhcnJheSdzIGNvcHkgd2lsbCBiZSB1c2VkIGZvciB0ZXN0CisgICAgICAgIGJ5dGVbXSBlbmNvZGVkS2V5Q29weSA9IGVuY29kZWRLZXkuY2xvbmUoKTsKKworICAgICAgICBYNTA5RW5jb2RlZEtleVNwZWMgbWVrcyA9IG5ldyBYNTA5RW5jb2RlZEtleVNwZWMoZW5jb2RlZEtleUNvcHkpOworCisgICAgICAgIGJ5dGVbXSBlayA9IG1la3MuZ2V0RW5jb2RlZCgpOworCisgICAgICAgIC8vIE1vZGlmeSByZXR1cm5lZCBhcnJheQorICAgICAgICBla1szXSA9IChieXRlKTU7CisKKyAgICAgICAgLy8gR2V0IGVuY29kZWQga2V5IGFnYWluCisgICAgICAgIGJ5dGVbXSBlazEgPSBtZWtzLmdldEVuY29kZWQoKTsKKworICAgICAgICAvLyBDaGVjayB1c2luZyByZWZlcmVuY2UgYXJyYXkgdGhhdAorICAgICAgICAvLyBieXRlIHZhbHVlIGhhcyBub3QgYmVlbiBjaGFuZ2VkCisgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhlbmNvZGVkS2V5LCBlazEpKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjaWFsLXRlc3QtY2FzZXMudHh0IGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L3NwZWNpYWwtdGVzdC1jYXNlcy50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmJmNGEyMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9zcGVjaWFsLXRlc3QtY2FzZXMudHh0CkBAIC0wLDAgKzEsNyBAQAorLSBAVGVzdFRhcmdldENsYXNzKENlcnRQYXRoLmNsYXNzKSBpbiBDZXJ0UGF0aENlcnRQYXRoUmVwVGVzdCBzaG91bGQgYmUKKyAgQ2VydFBhdGguQ2VydFBhdGhSZXAuY2xhc3MsIGJ1dCB0aGlzIGNsYXNzIGlzIHByb3RlY3RlZCBhbmQgdGh1cyBub3QgdmlzaWJsZQorICAKKy0gc2FtZSBmb3IgQ2VydGlmaWNhdGUuQ2VydGlmaWNhdGVSZXAKKworCistID8gZm9yIFNpZ25hdHVyZVNQSS5lbmdpbmVHZXRQYXJhbWV0ZXJzKCk6IHNlZSBzb3VyY2UgY29kZSBjb21tZW50cwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvRGF0YWJhc2VDcmVhdG9yLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9EYXRhYmFzZUNyZWF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi4xMjc0NGRkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvRGF0YWJhc2VDcmVhdG9yLmphdmEKQEAgLTAsMCArMSw0MDEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuc3FsLkNvbm5lY3Rpb247CitpbXBvcnQgamF2YS5zcWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247CitpbXBvcnQgamF2YS5zcWwuU3RhdGVtZW50OworaW1wb3J0IGphdmEuc3FsLlRpbWU7CisKK3B1YmxpYyBjbGFzcyBEYXRhYmFzZUNyZWF0b3IgeworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGRlZmF1bHRJbnQgPSAyOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgZGVmYXVsdFN0cmluZyA9ICJzdHJpbmciOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgZGVmYXVsdENoYXJhY3RlciA9ICJjaHIiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBkb3VibGUgZGVmYXVsdERvdWJsZSA9IDAuMTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRFU1RfVEFCTEUxID0gInRhYmxlMSI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBURVNUX1RBQkxFMiA9ICJ0YWJsZTIiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEVTVF9UQUJMRTMgPSAidGFibGUzIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRFU1RfVEFCTEU0ID0gInRhYmxlNCI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTQUxFU1BFT1BMRV9UQUJMRSA9ICJTYWxlc3Blb3BsZSI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDVVNUT01FUlNfVEFCTEUgPSAiQ3VzdG9tZXJzIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE9SREVSU19UQUJMRSA9ICJPcmRlcnMiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUEFSRU5UX1RBQkxFID0gInRlc3RfbmFtZXMiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRktTVFJJQ1RfVEFCTEUgPSAidGVzdF9zdHJpY3QiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRktDQVNDQURFX1RBQkxFID0gInRlc3RfY2FzY2FkZSI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBURVNUX1RBQkxFNSA9ICJ0ZXN0IjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNJTVBMRV9UQUJMRTEgPSAic2ltcGxlX3RhYmxlMSI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTSU1QTEVfVEFCTEUyID0gInNpbXBsZV90YWJsZTIiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0lNUExFX1RBQkxFMyA9ICJzaW1wbGVfdGFibGUzIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENSRUFURV9UQUJMRTEgPSAiQ1JFQVRFIFRBQkxFICIgKyBURVNUX1RBQkxFMQorICAgICAgICAgICAgKyAiIChpZCBJTlRFR0VSIE5PVCBOVUxMLCIgKyAiIGZpZWxkMSBDSEFSKDEwMCkgREVGQVVMVCBOVUxMLCIKKyAgICAgICAgICAgICsgIiBmaWVsZDIgREVDSU1BTCAiIC8vKyBkZWZhdWx0SW50CisgICAgICAgICAgICArICIgQ09NTUVOVCAnZmllbGQyX3JlbScsIiArICIgZmllbGQzIERFQ0lNQUwsIiArICIgZmtleSBJTlRFR0VSLCIKKyAgICAgICAgICAgICsgIiBQUklNQVJZIEtFWSAoaWQpIEZPUkVJR04gS0VZIChma2V5KSBSRUZFUkVOQ0VTICIKKyAgICAgICAgICAgICsgVEVTVF9UQUJMRTMgKyAiKGZrKSkiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ1JFQVRFX1RBQkxFMiA9ICJDUkVBVEUgVEFCTEUgIiArIFRFU1RfVEFCTEUyCisgICAgICAgICAgICArICIgKCAiICsgImZpbnRlZ2VyIGludGVnZXIgTk9UIE5VTEwsICIgKyAiZnRleHQgdGV4dCwgIgorICAgICAgICAgICAgKyAiZmNoYXJhY3RlciBjaGFyYWN0ZXIgKDUpLCAiICsgImZkZWNpbWFsIGRlY2ltYWwgKDUsMSksICIKKyAgICAgICAgICAgICsgImZudW1lcmljIG51bWVyaWMgKDQsMSksICIgKyAiZnNtYWxsaW50IHNtYWxsaW50LCAiCisgICAgICAgICAgICArICJmZmxvYXQgZmxvYXQsICIgKyAiZnJlYWwgcmVhbCwgIiArICJmZG91YmxlIGRvdWJsZSwgIgorICAgICAgICAgICAgKyAiZmRhdGUgZGF0ZSwiICsgIiBmdGltZSB0aW1lLCBQUklNQVJZIEtFWSAoZmludGVnZXIpKSI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDUkVBVEVfVEFCTEUzID0gIkNSRUFURSBUQUJMRSAiICsgVEVTVF9UQUJMRTMKKyAgICAgICAgICAgICsgIiAoZmsgSU5URUdFUiBOT1QgTlVMTCwiICsgIiIgKyAiIFBSSU1BUlkgS0VZIChmaykpIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENSRUFURV9UQUJMRTQgPSAiQ1JFQVRFIFRBQkxFICIgKyBURVNUX1RBQkxFNAorICAgICAgICAgICAgKyAiIChmayBJTlRFR0VSIE5PVCBOVUxMLCIgKyAiIGZpZWxkMSBDSEFSKDEwMCkgTk9UIE5VTEwsIgorICAgICAgICAgICAgKyAiIFBSSU1BUlkgS0VZIChmaykpIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENSRUFURV9UQUJMRTUgPSAiQ1JFQVRFIFRBQkxFICIgKyBURVNUX1RBQkxFNQorICAgICAgICAgICAgKyAiKCB0ZXN0SWQgSU5URUdFUiBOT1QgTlVMTCwgdGVzdFZhbHVlIENIQVIoMjAwKSkiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ1JFQVRFX1RBQkxFX1NBTEVTUEVPUExFID0gIkNSRUFURSBUQUJMRSAiCisgICAgICAgICAgICArIFNBTEVTUEVPUExFX1RBQkxFICsgIiAoc251bSBpbnRlZ2VyLCBzbmFtZSBjaGFyYWN0ZXIgKDEwKSwiCisgICAgICAgICAgICArICIgY2l0eSBjaGFyYWN0ZXIgKDEwKSwgY29tbSByZWFsLCBQUklNQVJZIEtFWSAoc251bSkpIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENSRUFURV9UQUJMRV9DVVNUT01FUlMgPSAiQ1JFQVRFIFRBQkxFICIKKyAgICAgICAgICAgICsgQ1VTVE9NRVJTX1RBQkxFCisgICAgICAgICAgICArICIgKGNudW0gaW50ZWdlciwgY25hbWUgY2hhcmFjdGVyICgxMCksIGNpdHkgY2hhcmFjdGVyICgxMCksIgorICAgICAgICAgICAgKyAiIHJhdGluZyBpbnRlZ2VyLCBzbnVtIGludGVnZXIsIFBSSU1BUlkgS0VZIChjbnVtKSkiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ1JFQVRFX1RBQkxFX09SREVSUyA9ICJDUkVBVEUgVEFCTEUgIgorICAgICAgICAgICAgKyBPUkRFUlNfVEFCTEUKKyAgICAgICAgICAgICsgIiAob251bSBpbnRlZ2VyLCBhbXQgcmVhbCwgb2RhdGUgZGF0ZSwgY251bSBpbnRlZ2VyLCIKKyAgICAgICAgICAgICsgIiBzbnVtIGludGVnZXIsIFBSSU1BUlkgS0VZIChvbnVtKSkiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ1JFQVRFX1RBQkxFX1BBUkVOVCA9ICJDUkVBVEUgVEFCTEUgIgorICAgICAgICAgICAgKyBQQVJFTlRfVEFCTEUgKyAiKGlkIElOVEVHRVIgTk9UIE5VTEwsICIKKyAgICAgICAgICAgICsgIm5hbWUgQ0hBUigyMDApLCBQUklNQVJZIEtFWShpZCkpIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENSRUFURV9UQUJMRV9GS1NUUklDVCA9ICJDUkVBVEUgVEFCTEUgIgorICAgICAgICAgICAgKyBGS1NUUklDVF9UQUJMRSArICIoaWQgSU5URUdFUiBOT1QgTlVMTCwiICsgIm5hbWVfaWQgSU5URUdFUiwiCisgICAgICAgICAgICArICJ2YWx1ZSBDSEFSKDIwMCksIFBSSU1BUlkgS0VZKGlkKSwgIgorICAgICAgICAgICAgKyAiQ09OU1RSQUlOVCBmazEgRk9SRUlHTiBLRVkgKG5hbWVfaWQpICIgKyAiUkVGRVJFTkNFUyAiCisgICAgICAgICAgICArIFBBUkVOVF9UQUJMRSArICIgKGlkKSAiICsgIk9OIERFTEVURSBSRVNUUklDVCAiCisgICAgICAgICAgICArICJPTiBVUERBVEUgUkVTVFJJQ1QpIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENSRUFURV9UQUJMRV9GS0NBU0NBREUgPSAiQ1JFQVRFIFRBQkxFICIKKyAgICAgICAgICAgICsgRktDQVNDQURFX1RBQkxFICsgIihpZCBJTlRFR0VSIE5PVCBOVUxMLCIgKyAibmFtZV9pZCBJTlRFR0VSLCIKKyAgICAgICAgICAgICsgInZhbHVlIENIQVIoMjAwKSwgUFJJTUFSWSBLRVkoaWQpLCAiCisgICAgICAgICAgICArICJDT05TVFJBSU5UIGZrMiBGT1JFSUdOIEtFWSAobmFtZV9pZCkgIiArICJSRUZFUkVOQ0VTICIKKyAgICAgICAgICAgICsgUEFSRU5UX1RBQkxFICsgIiAoaWQpICIgKyAiT04gREVMRVRFIENBU0NBREUgIgorICAgICAgICAgICAgKyAiT04gVVBEQVRFIENBU0NBREUpIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENSRUFURV9UQUJMRV9TSU1QTEUxID0gIkNSRUFURSBUQUJMRSAiCisgICAgICAgICAgICArIFNJTVBMRV9UQUJMRTEgKyAiKGlkIElOVEVHRVIgTk9UIE5VTEwsIiArICJzcGVlZCBJTlRFR0VSLCIKKyAgICAgICAgICAgICsgInNpemUgSU5URUdFUikiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ1JFQVRFX1RBQkxFX1NJTVBMRTIgPSAiQ1JFQVRFIFRBQkxFICIKKyAgICAgICAgICAgICsgU0lNUExFX1RBQkxFMiArICIoaWQgSU5URUdFUiBOT1QgTlVMTCwiICsgInNwZWVkIElOVEVHRVIsIgorICAgICAgICAgICAgKyAic2l6ZSBJTlRFR0VSKSI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDUkVBVEVfVEFCTEVfU0lNUExFMyA9ICJDUkVBVEUgVEFCTEUgIgorICAgICAgICAgICAgKyBTSU1QTEVfVEFCTEUzICsgIihpZCBJTlRFR0VSIE5PVCBOVUxMLCIgKyAic3BlZWQgSU5URUdFUikiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFJPUF9UQUJMRTEgPSAiRFJPUCBUQUJMRSAiICsgVEVTVF9UQUJMRTE7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBEUk9QX1RBQkxFMiA9ICJEUk9QIFRBQkxFICIgKyBURVNUX1RBQkxFMjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERST1BfVEFCTEUzID0gIkRST1AgVEFCTEUgIiArIFRFU1RfVEFCTEUzOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFJPUF9UQUJMRTQgPSAiRFJPUCBUQUJMRSAiICsgVEVTVF9UQUJMRTQ7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBEUk9QX1RBQkxFNSA9ICJEUk9QIFRBQkxFICIgKyBURVNUX1RBQkxFNTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERST1BfVEFCTEVfQ1VTVE9NRVJTID0gIkRST1AgVEFCTEUgIgorICAgICAgICAgICAgKyBDVVNUT01FUlNfVEFCTEU7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBEUk9QX1RBQkxFX09SREVSUyA9ICJEUk9QIFRBQkxFICIgKyBPUkRFUlNfVEFCTEU7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBEUk9QX1RBQkxFX1NBTEVTUEVPUExFID0gIkRST1AgVEFCTEUgIgorICAgICAgICAgICAgKyBTQUxFU1BFT1BMRV9UQUJMRTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERST1BfVEFCTEVfUEFSRU5UID0gIkRST1AgVEFCTEUgIiArIFBBUkVOVF9UQUJMRTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERST1BfVEFCTEVfRktTVFJJQ1QgPSAiRFJPUCBUQUJMRSAiCisgICAgICAgICAgICArIEZLU1RSSUNUX1RBQkxFOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFJPUF9UQUJMRV9GS0NBU0NBREUgPSAiRFJPUCBUQUJMRSAiCisgICAgICAgICAgICArIEZLQ0FTQ0FERV9UQUJMRTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERST1BfVEFCTEVfU0lNUExFMSA9ICJEUk9QIFRBQkxFICIKKyAgICAgICAgICAgICsgU0lNUExFX1RBQkxFMTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERST1BfVEFCTEVfU0lNUExFMiA9ICJEUk9QIFRBQkxFICIKKyAgICAgICAgICAgICsgU0lNUExFX1RBQkxFMjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERST1BfVEFCTEVfU0lNUExFMyA9ICJEUk9QIFRBQkxFICIKKyAgICAgICAgICAgICsgU0lNUExFX1RBQkxFMzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOU0VSVF9TQUxFU1BFT1BMRTEgPSAiIElOU0VSVCBJTlRPICIKKyAgICAgICAgICAgICsgU0FMRVNQRU9QTEVfVEFCTEUgKyAiIChzbnVtLCBzbmFtZSwgY2l0eSwgY29tbSkgIgorICAgICAgICAgICAgKyAiVkFMVUVTICgxMDAxLCAnUGVlbCcsICdMb25kb24nLCAuMTIpIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOU0VSVF9TQUxFU1BFT1BMRTIgPSAiIElOU0VSVCBJTlRPICIKKyAgICAgICAgICAgICsgU0FMRVNQRU9QTEVfVEFCTEUgKyAiIChzbnVtLCBzbmFtZSwgY2l0eSwgY29tbSkgIgorICAgICAgICAgICAgKyAiVkFMVUVTICgxMDAyLCAnU2VycmVzJywgJ1Nhbkpvc2UnLCAuMTMpIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOU0VSVF9TQUxFU1BFT1BMRTMgPSAiIElOU0VSVCBJTlRPICIKKyAgICAgICAgICAgICsgU0FMRVNQRU9QTEVfVEFCTEUgKyAiIChzbnVtLCBzbmFtZSwgY2l0eSwgY29tbSkgIgorICAgICAgICAgICAgKyAiVkFMVUVTICgxMDA0LCAnTW90aWthJywgJ0xvbmRvbicsIC4xMSkiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5TRVJUX1NBTEVTUEVPUExFNCA9ICIgSU5TRVJUIElOVE8gIgorICAgICAgICAgICAgKyBTQUxFU1BFT1BMRV9UQUJMRSArICIgKHNudW0sIHNuYW1lLCBjaXR5LCBjb21tKSAiCisgICAgICAgICAgICArICJWQUxVRVMgKDEwMDcsICdSaWZraW4nLCAnQmFyY2Vsb25hJywgLjE1KSI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlNFUlRfU0FMRVNQRU9QTEU1ID0gIiBJTlNFUlQgSU5UTyAiCisgICAgICAgICAgICArIFNBTEVTUEVPUExFX1RBQkxFICsgIiAoc251bSwgc25hbWUsIGNpdHksIGNvbW0pICIKKyAgICAgICAgICAgICsgIlZBTFVFUyAoMTAwMywgJ0F4ZWxyb2QnLCAnTmV3WW9yaycsIC4xMCkiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5TRVJUX1NBTEVTUEVPUExFNiA9ICIgSU5TRVJUIElOVE8gIgorICAgICAgICAgICAgKyBTQUxFU1BFT1BMRV9UQUJMRSArICIgKHNudW0sIHNuYW1lLCBjaXR5LCBjb21tKSAiCisgICAgICAgICAgICArICJWQUxVRVMgKDEwMTMsICdTaW1wc29uJywgJ0thc2FuJywgLjI1KSI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlNFUlRfQ1VTVE9NRVJTMSA9ICIgSU5TRVJUIElOVE8gIgorICAgICAgICAgICAgKyBDVVNUT01FUlNfVEFCTEUgKyAiIChjbnVtLCBjbmFtZSwgY2l0eSwgcmF0aW5nLCBzbnVtKSIKKyAgICAgICAgICAgICsgIiBWQUxVRVMgKDIwMDEsICdIb2ZmbWFuJywgJ0xvbmRvbicsIDEwMCwgMTAwMSkiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5TRVJUX0NVU1RPTUVSUzIgPSAiIElOU0VSVCBJTlRPICIKKyAgICAgICAgICAgICsgQ1VTVE9NRVJTX1RBQkxFICsgIiAoY251bSwgY25hbWUsIGNpdHksIHJhdGluZywgc251bSkgIgorICAgICAgICAgICAgKyAiVkFMVUVTICgyMDAyLCAnR2lvdmFubmknLCAnUm9tZScsIDIwMCwgMTAwMykiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5TRVJUX0NVU1RPTUVSUzMgPSAiIElOU0VSVCBJTlRPICIKKyAgICAgICAgICAgICsgQ1VTVE9NRVJTX1RBQkxFICsgIiAoY251bSwgY25hbWUsIGNpdHksIHJhdGluZywgc251bSkgIgorICAgICAgICAgICAgKyAiVkFMVUVTICgyMDAzLCAnTGl1JywgJ1Nhbkpvc2UnLCAyMDAsIDEwMDIpIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOU0VSVF9DVVNUT01FUlM0ID0gIiBJTlNFUlQgSU5UTyAiCisgICAgICAgICAgICArIENVU1RPTUVSU19UQUJMRSArICIgKGNudW0sIGNuYW1lLCBjaXR5LCByYXRpbmcsIHNudW0pICIKKyAgICAgICAgICAgICsgIlZBTFVFUyAoMjAwNCwgJ0dyYXNzJywgJ0JlcmxpbicsIDMwMCwgMTAwMikiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5TRVJUX0NVU1RPTUVSUzUgPSAiIElOU0VSVCBJTlRPICIKKyAgICAgICAgICAgICsgQ1VTVE9NRVJTX1RBQkxFICsgIiAoY251bSwgY25hbWUsIGNpdHksIHJhdGluZywgc251bSkgIgorICAgICAgICAgICAgKyAiVkFMVUVTICgyMDA2LCAnQ2xlbWVucycsICdMb25kb24nLCAxMDAsIDEwMDEpIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOU0VSVF9DVVNUT01FUlM2ID0gIiBJTlNFUlQgSU5UTyAiCisgICAgICAgICAgICArIENVU1RPTUVSU19UQUJMRSArICIgKGNudW0sIGNuYW1lLCBjaXR5LCByYXRpbmcsIHNudW0pICIKKyAgICAgICAgICAgICsgIlZBTFVFUyAoMjAwOCwgJ0Npc25lcm9zJywgJ1Nhbkpvc2UnLCAzMDAsIDEwMDcpIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOU0VSVF9DVVNUT01FUlM3ID0gIiBJTlNFUlQgSU5UTyAiCisgICAgICAgICAgICArIENVU1RPTUVSU19UQUJMRSArICIgKGNudW0sIGNuYW1lLCBjaXR5LCByYXRpbmcsIHNudW0pICIKKyAgICAgICAgICAgICsgIlZBTFVFUyAoMjAwNywgJ1BlcmVpcmEnLCAnUm9tZScsIDEwMCwgMTAwNCkiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5TRVJUX09SREVSUzEgPSAiIElOU0VSVCBJTlRPICIgKyBPUkRFUlNfVEFCTEUKKyAgICAgICAgICAgICsgIiAob251bSwgYW10LCBvZGF0ZSwgY251bSwgc251bSkgIgorICAgICAgICAgICAgKyAiVkFMVUVTICgzMDAxLCAxOC42OSwgMTAvMDMvMTk5MCwgMjAwOCwgMTAwNykiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5TRVJUX09SREVSUzIgPSAiIElOU0VSVCBJTlRPICIgKyBPUkRFUlNfVEFCTEUKKyAgICAgICAgICAgICsgIiAob251bSwgYW10LCBvZGF0ZSwgY251bSwgc251bSkgIgorICAgICAgICAgICAgKyAiVkFMVUVTICgzMDAzLCA3NjcuMTksIDEwLzAzLzE5OTAsIDIwMDEsIDEwMDEpIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOU0VSVF9PUkRFUlMzID0gIiBJTlNFUlQgSU5UTyAiICsgT1JERVJTX1RBQkxFCisgICAgICAgICAgICArICIgKG9udW0sIGFtdCwgb2RhdGUsIGNudW0sIHNudW0pICIKKyAgICAgICAgICAgICsgIlZBTFVFUyAoMzAwMiwgMTkwMC4xMCwgMTAvMDMvMTk5MCwgMjAwNywgMTAwNCkiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5TRVJUX09SREVSUzQgPSAiIElOU0VSVCBJTlRPICIgKyBPUkRFUlNfVEFCTEUKKyAgICAgICAgICAgICsgIiAob251bSwgYW10LCBvZGF0ZSwgY251bSwgc251bSkgIgorICAgICAgICAgICAgKyAiVkFMVUVTICgzMDA1LCA1MTYwLjQ1LCAxMC8wMy8xOTkwLCAyMDAzLCAxMDAyKSI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlNFUlRfT1JERVJTNSA9ICIgSU5TRVJUIElOVE8gIiArIE9SREVSU19UQUJMRQorICAgICAgICAgICAgKyAiIChvbnVtLCBhbXQsIG9kYXRlLCBjbnVtLCBzbnVtKSAiCisgICAgICAgICAgICArICJWQUxVRVMgKDMwMDYsIDEwOTguMTYsIDEwLzAzLzE5OTAsIDIwMDgsIDEwMDcpIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOU0VSVF9PUkRFUlM2ID0gIiBJTlNFUlQgSU5UTyAiICsgT1JERVJTX1RBQkxFCisgICAgICAgICAgICArICIgKG9udW0sIGFtdCwgb2RhdGUsIGNudW0sIHNudW0pICIKKyAgICAgICAgICAgICsgIlZBTFVFUyAoMzAwOSwgMTcxMy4yMywgMTAvMDQvMTk5MCwgMjAwMiwgMTAwMykiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5TRVJUX09SREVSUzcgPSAiIElOU0VSVCBJTlRPICIgKyBPUkRFUlNfVEFCTEUKKyAgICAgICAgICAgICsgIiAob251bSwgYW10LCBvZGF0ZSwgY251bSwgc251bSkgIgorICAgICAgICAgICAgKyAiVkFMVUVTICgzMDA3LCA3NS43NSwgMTAvMDQvMTk5MCwgMjAwNCwgMTAwMikiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5TRVJUX09SREVSUzggPSAiIElOU0VSVCBJTlRPICIgKyBPUkRFUlNfVEFCTEUKKyAgICAgICAgICAgICsgIiAob251bSwgYW10LCBvZGF0ZSwgY251bSwgc251bSkgIgorICAgICAgICAgICAgKyAiVkFMVUVTICgzMDA4LCA0NzIzLjAxLCAxMC8wNS8xOTkwLCAyMDA2LCAxMDAxKSI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlNFUlRfT1JERVJTOSA9ICIgSU5TRVJUIElOVE8gIiArIE9SREVSU19UQUJMRQorICAgICAgICAgICAgKyAiIChvbnVtLCBhbXQsIG9kYXRlLCBjbnVtLCBzbnVtKSAiCisgICAgICAgICAgICArICJWQUxVRVMgKDMwMTAsIDEzMDkuOTUsIDEwLzA2LzE5OTAsIDIwMDQsIDEwMDIpIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOU0VSVF9PUkRFUlMxMCA9ICIgSU5TRVJUIElOVE8gIiArIE9SREVSU19UQUJMRQorICAgICAgICAgICAgKyAiIChvbnVtLCBhbXQsIG9kYXRlLCBjbnVtLCBzbnVtKSAiCisgICAgICAgICAgICArICJWQUxVRVMgKDMwMTEsIDk4OTEuODgsIDEwLzA2LzE5OTAsIDIwMDYsIDEwMDEpIjsKKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBmaWxsUGFyZW50VGFibGUoQ29ubmVjdGlvbiBjb25uKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0YXRlbWVudCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgIHN0YXRlbWVudAorICAgICAgICAgICAgICAgIC5leGVjdXRlKCJJTlNFUlQgSU5UTyAiICsgUEFSRU5UX1RBQkxFICsgIiBWQUxVRVMoMSwgJ3Rlc3QxJykiKTsKKyAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoIklOU0VSVCBJTlRPICIgKyBQQVJFTlRfVEFCTEUgKyAiIFZBTFVFUygyLCd0ZXN0MicpIik7CisgICAgICAgIHN0YXRlbWVudAorICAgICAgICAgICAgICAgIC5leGVjdXRlKCJJTlNFUlQgSU5UTyAiICsgUEFSRU5UX1RBQkxFICsgIiBWQUxVRVMoMywgJ3Rlc3QzJykiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmlsbEZLU3RyaWN0VGFibGUoQ29ubmVjdGlvbiBjb25uKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0YXRlbWVudCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKCJJTlNFUlQgSU5UTyAiICsgRktTVFJJQ1RfVEFCTEUKKyAgICAgICAgICAgICAgICArICIgVkFMVUVTKDEsIDEsICcxJykiKTsKKyAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoIklOU0VSVCBJTlRPICIgKyBGS1NUUklDVF9UQUJMRQorICAgICAgICAgICAgICAgICsgIiBWQUxVRVMoMiwgMiwgJzInKSIpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZSgiSU5TRVJUIElOVE8gIiArIEZLU1RSSUNUX1RBQkxFCisgICAgICAgICAgICAgICAgKyAiIFZBTFVFUygzLCAxLCAnMycpIik7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGZpbGxGS0Nhc2NhZGVUYWJsZShDb25uZWN0aW9uIGNvbm4pIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdGF0ZW1lbnQgc3RhdGVtZW50ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoIklOU0VSVCBJTlRPICIgKyBGS0NBU0NBREVfVEFCTEUKKyAgICAgICAgICAgICAgICArICIgVkFMVUVTKDEsIDEsICcxJykiKTsKKyAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoIklOU0VSVCBJTlRPICIgKyBGS0NBU0NBREVfVEFCTEUKKyAgICAgICAgICAgICAgICArICIgVkFMVUVTKDIsIDIsICcyJykiKTsKKyAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoIklOU0VSVCBJTlRPICIgKyBGS0NBU0NBREVfVEFCTEUKKyAgICAgICAgICAgICAgICArICIgVkFMVUVTKDMsIDEsICczJykiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmlsbFNpbXBsZVRhYmxlMShDb25uZWN0aW9uIGNvbm4pIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdGF0ZW1lbnQgc3RhdGVtZW50ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgc3RhdGVtZW50CisgICAgICAgICAgICAgICAgLmV4ZWN1dGUoIklOU0VSVCBJTlRPICIgKyBTSU1QTEVfVEFCTEUxICsgIiBWQUxVRVMoMSwgMTAsIDIwKSIpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZSgiSU5TRVJUIElOVE8gIiArIFNJTVBMRV9UQUJMRTEgKyAiIFZBTFVFUygyLCA1LCA3KSIpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBmaWxsU2ltcGxlVGFibGUzKENvbm5lY3Rpb24gY29ubikgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0YXRlbWVudCBzdGF0ZW1lbnQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZSgiSU5TRVJUIElOVE8gIiArIFNJTVBMRV9UQUJMRTMgKyAiIFZBTFVFUygxLCA4KSIpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZSgiSU5TRVJUIElOVE8gIiArIFNJTVBMRV9UQUJMRTMgKyAiIFZBTFVFUygyLCA2KSIpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZSgiSU5TRVJUIElOVE8gIiArIFNJTVBMRV9UQUJMRTMgKyAiIFZBTFVFUygzLCA0KSIpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBmaWxsU2FsZXNQZW9wbGVUYWJsZShDb25uZWN0aW9uIGNvbm4pCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0YXRlbWVudCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisKKyAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLklOU0VSVF9TQUxFU1BFT1BMRTEpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuSU5TRVJUX1NBTEVTUEVPUExFMik7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5JTlNFUlRfU0FMRVNQRU9QTEUzKTsKKyAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoRGF0YWJhc2VDcmVhdG9yLklOU0VSVF9TQUxFU1BFT1BMRTQpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuSU5TRVJUX1NBTEVTUEVPUExFNSk7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5JTlNFUlRfU0FMRVNQRU9QTEU2KTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmlsbEN1c3RvbWVyc1RhYmxlKENvbm5lY3Rpb24gY29ubikgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0YXRlbWVudCBzdGF0ZW1lbnQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworCisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5JTlNFUlRfQ1VTVE9NRVJTMSk7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5JTlNFUlRfQ1VTVE9NRVJTMik7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5JTlNFUlRfQ1VTVE9NRVJTMyk7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5JTlNFUlRfQ1VTVE9NRVJTNCk7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5JTlNFUlRfQ1VTVE9NRVJTNSk7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5JTlNFUlRfQ1VTVE9NRVJTNik7CisgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKERhdGFiYXNlQ3JlYXRvci5JTlNFUlRfQ1VTVE9NRVJTNyk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGZpbGxPcmRlcnNUYWJsZShDb25uZWN0aW9uIGNvbm4pIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdGF0ZW1lbnQgc3RhdGVtZW50ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuSU5TRVJUX09SREVSUzEpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuSU5TRVJUX09SREVSUzIpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuSU5TRVJUX09SREVSUzMpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuSU5TRVJUX09SREVSUzQpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuSU5TRVJUX09SREVSUzUpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuSU5TRVJUX09SREVSUzYpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuSU5TRVJUX09SREVSUzcpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuSU5TRVJUX09SREVSUzgpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuSU5TRVJUX09SREVSUzkpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZShEYXRhYmFzZUNyZWF0b3IuSU5TRVJUX09SREVSUzEwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmlsbFRlc3RUYWJsZTEoQ29ubmVjdGlvbiBjb25uLCBpbnQgbnVtYmVyT2ZSZWNvcmRzKQorICAgICAgICAgICAgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0YXRlbWVudCBzdGF0ZW1lbnQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICBmb3IgKGludCBpZCA9IDA7IGlkIDwgbnVtYmVyT2ZSZWNvcmRzOyBpZCsrKSB7CisgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBEYXRhYmFzZUNyZWF0b3IuZGVmYXVsdFN0cmluZyArIGlkOworICAgICAgICAgICAgU3RyaW5nIGluc2VydFF1ZXJ5ID0gIklOU0VSVCBJTlRPICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTEKKyAgICAgICAgICAgICAgICAgICAgKyAiIChpZCwgZmllbGQxLCBmaWVsZDIsIGZpZWxkMykgVkFMVUVTKCIgKyBpZCArICIsICciCisgICAgICAgICAgICAgICAgICAgICsgdmFsdWUgKyAiJywgIiArIGlkICsgIiwgIiArIGlkICsgIikiOworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoaW5zZXJ0UXVlcnkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGZpbGxUZXN0VGFibGUyKENvbm5lY3Rpb24gY29ubiwgaW50IHN0YXJ0SUQsIGludCBlbmRJRCwKKyAgICAgICAgICAgIGxvbmcgdGltZSkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0YXRlbWVudCBzdGF0ZW1lbnQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICBmb3IgKGludCBpZCA9IHN0YXJ0SUQ7IGlkIDw9IGVuZElEOyBpZCsrKSB7CisgICAgICAgICAgICBkb3VibGUgdmFsdWUgPSBpZCArIERhdGFiYXNlQ3JlYXRvci5kZWZhdWx0RG91YmxlOworICAgICAgICAgICAgU3RyaW5nIGluc2VydFF1ZXJ5ID0gIklOU0VSVCBJTlRPICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTIKKyAgICAgICAgICAgICAgICAgICAgKyAiIChmaW50ZWdlciwgZnRleHQsIGZjaGFyYWN0ZXIsIGZkZWNpbWFsLCBmbnVtZXJpYywiCisgICAgICAgICAgICAgICAgICAgICsgIiBmc21hbGxpbnQsIGZmbG9hdCwgZnJlYWwsIGZkb3VibGUsIGZkYXRlLCBmdGltZSkiCisgICAgICAgICAgICAgICAgICAgICsgIiBWQUxVRVMgKCIgKyBpZCArICIsICciICsgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRTdHJpbmcKKyAgICAgICAgICAgICAgICAgICAgKyBpZCArICInLCIgKyAiICciICsgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRDaGFyYWN0ZXIgKyBpZAorICAgICAgICAgICAgICAgICAgICArICInLCAiICsgdmFsdWUgKyAiLCAiICsgdmFsdWUgKyAiLCIgKyB2YWx1ZSArICIsICIgKyB2YWx1ZQorICAgICAgICAgICAgICAgICAgICArICIsICIgKyB2YWx1ZSArICIsIiArIHZhbHVlICsgIiwgJyIKKyAgICAgICAgICAgICAgICAgICAgKyBuZXcgRGF0ZSh0aW1lKS50b1N0cmluZygpICsgIicsIiArICIgJyIKKyAgICAgICAgICAgICAgICAgICAgKyBuZXcgVGltZSh0aW1lKS50b1N0cmluZygpICsgIicpIjsKKyAgICAgICAgICAgIHN0YXRlbWVudC5leGVjdXRlKGluc2VydFF1ZXJ5KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBmaWxsVGVzdFRhYmxlMihDb25uZWN0aW9uIGNvbm4sIGludCBudW1iZXJPZlJlY29yZHMpCisgICAgICAgICAgICB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgU3RhdGVtZW50IHN0YXRlbWVudCA9IGNvbm4uY3JlYXRlU3RhdGVtZW50KCk7CisgICAgICAgIGZvciAoaW50IGlkID0gMDsgaWQgPCBudW1iZXJPZlJlY29yZHM7IGlkKyspIHsKKyAgICAgICAgICAgIGRvdWJsZSB2YWx1ZSA9IGlkICsgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHREb3VibGU7CisgICAgICAgICAgICBTdHJpbmcgaW5zZXJ0UXVlcnkgPSAiSU5TRVJUIElOVE8gIiArIERhdGFiYXNlQ3JlYXRvci5URVNUX1RBQkxFMgorICAgICAgICAgICAgICAgICAgICArICIgKGZpbnRlZ2VyLCBmdGV4dCwgZmNoYXJhY3RlciwgZmRlY2ltYWwsIGZudW1lcmljLCIKKyAgICAgICAgICAgICAgICAgICAgKyAiIGZzbWFsbGludCwgZmZsb2F0LCBmcmVhbCwgZmRvdWJsZSkiICsgIiBWQUxVRVMgKCIgKyBpZAorICAgICAgICAgICAgICAgICAgICArICIsICciICsgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRTdHJpbmcgKyBpZCArICInLCIgKyAiICciCisgICAgICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRDaGFyYWN0ZXIgKyBpZCArICInLCAiICsgdmFsdWUKKyAgICAgICAgICAgICAgICAgICAgKyAiLCAiICsgdmFsdWUgKyAiLCIgKyB2YWx1ZSArICIsICIgKyB2YWx1ZSArICIsICIgKyB2YWx1ZQorICAgICAgICAgICAgICAgICAgICArICIsIiArIHZhbHVlICsgIikiOworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoaW5zZXJ0UXVlcnkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGZpbGxUZXN0VGFibGU0KENvbm5lY3Rpb24gY29ubiwgaW50IG51bWJlck9mUmVjb3JkcykKKyAgICAgICAgICAgIHRocm93cyBTUUxFeGNlcHRpb24geworICAgICAgICBTdGF0ZW1lbnQgc3RhdGVtZW50ID0gY29ubi5jcmVhdGVTdGF0ZW1lbnQoKTsKKyAgICAgICAgZm9yIChpbnQgaWQgPSAwOyBpZCA8IG51bWJlck9mUmVjb3JkczsgaWQrKykgeworICAgICAgICAgICAgU3RyaW5nIGluc2VydFF1ZXJ5ID0gIklOU0VSVCBJTlRPICIgKyBEYXRhYmFzZUNyZWF0b3IuVEVTVF9UQUJMRTQKKyAgICAgICAgICAgICAgICAgICAgKyAiIChmaywgZmllbGQxKSBWQUxVRVMoIiArIGlkICsgIiwgXCIiCisgICAgICAgICAgICAgICAgICAgICsgRGF0YWJhc2VDcmVhdG9yLmRlZmF1bHRTdHJpbmcgKyBpZCArICJcIikiOworICAgICAgICAgICAgc3RhdGVtZW50LmV4ZWN1dGUoaW5zZXJ0UXVlcnkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGZpbGxUZXN0VGFibGU1KENvbm5lY3Rpb24gY29ubikgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisgICAgICAgIFN0YXRlbWVudCBzdGF0ZW1lbnQgPSBjb25uLmNyZWF0ZVN0YXRlbWVudCgpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZSgiSU5TRVJUIElOVE8gIiArIFRFU1RfVEFCTEU1ICsgIiBWQUxVRVMoMSwgJzAnKSIpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZSgiSU5TRVJUIElOVE8gIiArIFRFU1RfVEFCTEU1ICsgIiBWQUxVRVMoMiwgJzMnKSIpOworICAgICAgICBzdGF0ZW1lbnQuZXhlY3V0ZSgiSU5TRVJUIElOVE8gIiArIFRFU1RfVEFCTEU1ICsgIiBWQUxVRVMoMywgJzQnKSIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L01vY2tDYWxsYmFjay5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvTW9ja0NhbGxiYWNrLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzYwNWMzOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L01vY2tDYWxsYmFjay5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDggVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBTUUxpdGUuQ2FsbGJhY2s7CisKKworcHVibGljIGNsYXNzIE1vY2tDYWxsYmFjayBpbXBsZW1lbnRzIENhbGxiYWNrIHsKKworICAgIHB1YmxpYyB2b2lkIGNvbHVtbnMoU3RyaW5nIGNvbHNbXSkgeworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiZsdDtUSCZndDsmbHQ7VFImZ3Q7Iik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IGNvbHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiJmx0O1REJmd0OyIgKyBjb2xzW2ldICsgIiZsdDsvVEQmZ3Q7Iik7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCImbHQ7L1RSJmd0OyZsdDsvVEgmZ3Q7Iik7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gbmV3cm93KFN0cmluZyBjb2xzW10pIHsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCImbHQ7VFImZ3Q7Iik7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IGNvbHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiJmx0O1REJmd0OyIgKyBjb2xzW2ldICsgIiZsdDsvVEQmZ3Q7Iik7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCImbHQ7L1RSJmd0OyIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdHlwZXMoU3RyaW5nW10gdHlwZXMpIHsKKyAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvTW9ja0Z1bmN0aW9uLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9Nb2NrRnVuY3Rpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMGIyZjc3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvTW9ja0Z1bmN0aW9uLmphdmEKQEAgLTAsMCArMSw1NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IFNRTGl0ZS5GdW5jdGlvbjsKK2ltcG9ydCBTUUxpdGUuRnVuY3Rpb25Db250ZXh0OworCisKK3B1YmxpYyBjbGFzcyBNb2NrRnVuY3Rpb24gaW1wbGVtZW50cyBTUUxpdGUuRnVuY3Rpb257CisgICAgcHJpdmF0ZSBTdHJpbmdCdWZmZXIgYWNjID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBnZXRBZ2dWYWx1ZUNhbGxlZCA9IGZhbHNlOworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBmdW5jdGlvbkNhbGxlZCA9IGZhbHNlOworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBzdGVwQ2FsbGVkID0gZmFsc2U7CisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGxhc3RTdGVwQ2FsbGVkID0gZmFsc2U7CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEFnZ1ZhbHVlKCkgeworICAgICAgICBnZXRBZ2dWYWx1ZUNhbGxlZCA9IHRydWU7CisgICAgICAgIHJldHVybiBhY2MudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBmdW5jdGlvbihGdW5jdGlvbkNvbnRleHQgZmMsIFN0cmluZyBhcmdzW10pIHsKKyAgICAgICAgZnVuY3Rpb25DYWxsZWQgPSB0cnVlOworICAgICAgICBpZiAoYXJncy5sZW5ndGggPiAwKSB7CisgICAgICAgICAgICBmYy5zZXRfcmVzdWx0KGFyZ3NbMF0udG9Mb3dlckNhc2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzdGVwKEZ1bmN0aW9uQ29udGV4dCBmYywgU3RyaW5nIGFyZ3NbXSkgeworICAgICAgICBzdGVwQ2FsbGVkID0gdHJ1ZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBhY2MuYXBwZW5kKGFyZ3NbaV0pOworICAgICAgICAgICAgYWNjLmFwcGVuZCgiICIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgbGFzdF9zdGVwKEZ1bmN0aW9uQ29udGV4dCBmYykgeworICAgICAgICBsYXN0U3RlcENhbGxlZCA9IHRydWU7CisgICAgICAgIGZjLnNldF9yZXN1bHQoYWNjLnRvU3RyaW5nKCkpOworICAgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1NRTC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9TUUwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNTZhMTM2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9TUUwuamF2YQpAQCAtMCwwICsxLDExOCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNxbC5Db25uZWN0aW9uOworaW1wb3J0IGphdmEuc3FsLkRyaXZlck1hbmFnZXI7CitpbXBvcnQgamF2YS5zcWwuU1FMRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9TUUwgeworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgc3FsRHJpdmVyID0gbnVsbDsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHNxbExvZ2luID0gbnVsbDsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHNxbENhdGFsb2cgPSBudWxsOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgc3FsSG9zdCA9IG51bGw7CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBzcWxVcmwgPSBudWxsOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgc3FsUGFzc3dvcmQgPSBudWxsOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgc3FsVXNlciA9IG51bGw7CisKKyAgICBwdWJsaWMgc3RhdGljIGludCBzcWxNYXhDb25uZWN0aW9ucyA9IDU7CisKKyAgICBwdWJsaWMgc3RhdGljIGludCBzcWxNYXhUYXNrcyA9IDE7CisKKyAgICBwcml2YXRlIHN0YXRpYyBGaWxlIGRiRmlsZSA9IG51bGw7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbG9hZERyaXZlcigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIElucHV0U3RyZWFtIGluID0gQ2xhc3MuZm9yTmFtZSgidGVzdHMuc3VwcG9ydC5TdXBwb3J0X1NRTCIpCisgICAgICAgICAgICAgICAgICAgIC5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvY29ubmVjdGlvbi5wcm9wZXJ0aWVzIik7CisgICAgICAgICAgICBsb2FkUHJvcGVydGllcyhpbik7CisgICAgICAgICAgICBpbi5jbG9zZSgpOworCisgICAgICAgICAgICBTdHJpbmcgdG1wID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmlvLnRtcGRpciIpOworICAgICAgICAgICAgRmlsZSB0bXBEaXIgPSBuZXcgRmlsZSh0bXApOworICAgICAgICAgICAgaWYgKHRtcERpci5pc0RpcmVjdG9yeSgpKSB7CisgICAgICAgICAgICAgICAgZGJGaWxlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgic3FsaXRlVGVzdCIsICIuZGIiLCB0bXBEaXIpOworICAgICAgICAgICAgICAgIGRiRmlsZS5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJqYXZhLmlvLnRtcGRpciBkb2VzIG5vdCBleGlzdCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQ2xhc3MuZm9yTmFtZSgiU1FMaXRlLkpEQkNEcml2ZXIiKS5uZXdJbnN0YW5jZSgpOworCisgICAgICAgICAgICAvLyBvdmVyd3JpdGUgc3FsVXJsIHRvIHBvaW50IHRvIHZhbGlkIGRpcmVjdG9yeQorICAgICAgICAgICAgc3FsVXJsID0gImpkYmM6c3FsaXRlOi8iICsgZGJGaWxlLmdldFBhdGgoKTsKKworICAgICAgICAgICAgQ2xhc3MuZm9yTmFtZShzcWxEcml2ZXIpLm5ld0luc3RhbmNlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBDb25uZWN0aW9uIGdldENvbm5lY3Rpb24oKSB0aHJvd3MgU1FMRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBEcml2ZXJNYW5hZ2VyLmdldENvbm5lY3Rpb24oU3VwcG9ydF9TUUwuc3FsVXJsLAorICAgICAgICAgICAgICAgICAgICBTdXBwb3J0X1NRTC5zcWxMb2dpbiwgU3VwcG9ydF9TUUwuc3FsUGFzc3dvcmQpOworICAgICAgICB9IGNhdGNoIChTUUxFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNRTEV4Y2VwdGlvbigiRmFpbGVkIHRvIGNvbm5lY3QuIHVybD0iICsgU3VwcG9ydF9TUUwuc3FsVXJsICsgIiwgc3FsTG9naW49IgorICAgICAgICAgICAgICAgICAgICArIFN1cHBvcnRfU1FMLnNxbExvZ2luICsgIiwgc3FsUGFzc3dvcmQ9IiArIFN1cHBvcnRfU1FMLnNxbFBhc3N3b3JkLCBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgQ29ubmVjdGlvbiBnZXRDb25uZWN0aW9uKFN0cmluZyB1cmwsIFN0cmluZyBsb2dpbiwKKyAgICAgICAgICAgIFN0cmluZyBwYXNzd29yZCkgdGhyb3dzIFNRTEV4Y2VwdGlvbiB7CisKKyAgICAgICAgcmV0dXJuIERyaXZlck1hbmFnZXIuZ2V0Q29ubmVjdGlvbih1cmwsIGxvZ2luLCBwYXNzd29yZCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzRXF1YWwoYnl0ZVtdIGIxLCBpbnQgb2ZmMSwgYnl0ZVtdIGIyLCBpbnQgb2ZmMiwKKyAgICAgICAgICAgIGludCBsZW4pIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47ICsraSkKKyAgICAgICAgICAgIGlmIChiMVtpICsgb2ZmMV0gIT0gYjJbaSArIG9mZjJdKQorICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBsb2FkUHJvcGVydGllcyhJbnB1dFN0cmVhbSBmaWxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgcHJvcGVydGllcy5sb2FkKGZpbGVOYW1lKTsKKyAgICAgICAgc3FsRHJpdmVyID0gcHJvcGVydGllcy5nZXRQcm9wZXJ0eSgic3FsRHJpdmVyIik7CisgICAgICAgIHNxbExvZ2luID0gcHJvcGVydGllcy5nZXRQcm9wZXJ0eSgic3FsTG9naW4iKTsKKyAgICAgICAgc3FsQ2F0YWxvZyA9IHByb3BlcnRpZXMuZ2V0UHJvcGVydHkoInNxbENhdGFsb2ciKTsKKyAgICAgICAgc3FsSG9zdCA9IHByb3BlcnRpZXMuZ2V0UHJvcGVydHkoInNxbEhvc3QiKTsKKyAgICAgICAgc3FsVXJsID0gcHJvcGVydGllcy5nZXRQcm9wZXJ0eSgic3FsVXJsUHJlZml4IikgKyBzcWxIb3N0ICsgIi8iCisgICAgICAgICAgICAgICAgKyBzcWxDYXRhbG9nOworICAgICAgICBzcWxQYXNzd29yZCA9IHByb3BlcnRpZXMuZ2V0UHJvcGVydHkoInNxbFBhc3N3b3JkIik7CisgICAgICAgIHNxbFVzZXIgPSBwcm9wZXJ0aWVzLmdldFByb3BlcnR5KCJzcWxVc2VyIik7CisgICAgICAgIHNxbE1heENvbm5lY3Rpb25zID0gSW50ZWdlci5wYXJzZUludChwcm9wZXJ0aWVzCisgICAgICAgICAgICAgICAgLmdldFByb3BlcnR5KCJzcWxNYXhDb25uZWN0aW9ucyIpKTsKKyAgICAgICAgc3FsTWF4VGFza3MgPSBJbnRlZ2VyLnBhcnNlSW50KHByb3BlcnRpZXMuZ2V0UHJvcGVydHkoInNxbE1heFRhc2tzIikpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEZpbGVuYW1lKCkgeworICAgICAgICByZXR1cm4gZGJGaWxlLmdldFBhdGgoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9UaHJlYWRQb29sLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9UaHJlYWRQb29sLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzVmYTMyMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1RocmVhZFBvb2wuamF2YQpAQCAtMCwwICsxLDEyMCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS51dGlsLkxpbmtlZExpc3Q7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nZ2VyOworCitwdWJsaWMgY2xhc3MgVGhyZWFkUG9vbCBleHRlbmRzIFRocmVhZEdyb3VwIHsKKworICAgIHByaXZhdGUgYm9vbGVhbiBpc0FsaXZlOworCisgICAgcHJpdmF0ZSBMaW5rZWRMaXN0PFJ1bm5hYmxlPiB0YXNrUXVldWU7CisKKyAgICBwcml2YXRlIGludCB0aHJlYWRJRDsKKworICAgIHByaXZhdGUgc3RhdGljIGludCB0aHJlYWRQb29sSUQ7CisKKyAgICBwdWJsaWMgVGhyZWFkUG9vbChpbnQgbnVtVGhyZWFkcykgeworICAgICAgICBzdXBlcigiVGhyZWFkUG9vbC0iICsgKHRocmVhZFBvb2xJRCsrKSk7CisgICAgICAgIHNldERhZW1vbih0cnVlKTsKKworICAgICAgICBpc0FsaXZlID0gdHJ1ZTsKKworICAgICAgICB0YXNrUXVldWUgPSBuZXcgTGlua2VkTGlzdDxSdW5uYWJsZT4oKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1UaHJlYWRzOyBpKyspIHsKKyAgICAgICAgICAgIG5ldyBQb29sZWRUaHJlYWQoKS5zdGFydCgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHJ1blRhc2soUnVubmFibGUgdGFzaykgeworICAgICAgICBpZiAoIWlzQWxpdmUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodGFzayAhPSBudWxsKSB7CisgICAgICAgICAgICB0YXNrUXVldWUuYWRkKHRhc2spOworICAgICAgICAgICAgbm90aWZ5KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIFJ1bm5hYmxlIGdldFRhc2soKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICB3aGlsZSAodGFza1F1ZXVlLnNpemUoKSA9PSAwKSB7CisgICAgICAgICAgICBpZiAoIWlzQWxpdmUpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHdhaXQoKTsKKyAgICAgICAgfQorICAgICAgICBMb2dnZXIuZ2xvYmFsLmluZm8oIjEgVGFzayBpcyByZW1vdmVkIik7CisgICAgICAgIHJldHVybiAoUnVubmFibGUpIHRhc2tRdWV1ZS5yZW1vdmVGaXJzdCgpOworICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHsKKyAgICAgICAgaWYgKGlzQWxpdmUpIHsKKyAgICAgICAgICAgIGlzQWxpdmUgPSBmYWxzZTsKKyAgICAgICAgICAgIHRhc2tRdWV1ZS5jbGVhcigpOworICAgICAgICAgICAgaW50ZXJydXB0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBqb2luKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGlzQWxpdmUgPSBmYWxzZTsKKyAgICAgICAgICAgIG5vdGlmeUFsbCgpOworICAgICAgICB9CisKKyAgICAgICAgVGhyZWFkW10gdGhyZWFkcyA9IG5ldyBUaHJlYWRbYWN0aXZlQ291bnQoKV07CisgICAgICAgIGludCBjb3VudCA9IGVudW1lcmF0ZSh0aHJlYWRzKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRocmVhZHNbaV0uam9pbigpOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgUG9vbGVkVGhyZWFkIGV4dGVuZHMgVGhyZWFkIHsKKworICAgICAgICBwdWJsaWMgUG9vbGVkVGhyZWFkKCkgeworICAgICAgICAgICAgc3VwZXIoVGhyZWFkUG9vbC50aGlzLCAiUG9vbGVkVGhyZWFkLSIgKyAodGhyZWFkSUQrKykpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgd2hpbGUgKCFpc0ludGVycnVwdGVkKCkpIHsKKworICAgICAgICAgICAgICAgIFJ1bm5hYmxlIHRhc2sgPSBudWxsOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHRhc2sgPSBnZXRUYXNrKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKHRhc2sgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmdsb2JhbC5pbmZvKCJUYXNrIGlzIHJ1biIpOworICAgICAgICAgICAgICAgICAgICB0YXNrLnJ1bigpOworCisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKHQuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9LZXlTdG9yZVRlc3QuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L0tleVN0b3JlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU1YmJiNjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9LZXlTdG9yZVRlc3QuamF2YQpAQCAtMCwwICsxLDE5MCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMudGFyZ2V0cy5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXJHZW5lcmF0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlLkVudHJ5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmUuUHJvdGVjdGlvblBhcmFtZXRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlVucmVjb3ZlcmFibGVFbnRyeUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgS2V5U3RvcmVUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgYWxnb3JpdGhtTmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBrZXlTdG9yZURhdGE7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcga2V5U3RvcmVQYXNzd29yZDsKKworICAgIHB1YmxpYyBLZXlTdG9yZVRlc3QoU3RyaW5nIGFsZ29yaXRobU5hbWUsIGJ5dGVbXSBrZXlTdG9yZURhdGEsCisgICAgICAgICAgICBTdHJpbmcga2V5U3RvcmVQYXNzd29yZCkgeworICAgICAgICB0aGlzLmFsZ29yaXRobU5hbWUgPSBhbGdvcml0aG1OYW1lOworICAgICAgICB0aGlzLmtleVN0b3JlRGF0YSA9IGtleVN0b3JlRGF0YTsKKyAgICAgICAgdGhpcy5rZXlTdG9yZVBhc3N3b3JkID0ga2V5U3RvcmVQYXNzd29yZDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5U3RvcmVMb2FkKCkgeworICAgICAgICBLZXlTdG9yZSBrZXlTdG9yZSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlTdG9yZSA9IEtleVN0b3JlLmdldEluc3RhbmNlKGFsZ29yaXRobU5hbWUpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlTdG9yZS5sb2FkKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShrZXlTdG9yZURhdGEpLAorICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZVBhc3N3b3JkLnRvQ2hhckFycmF5KCkpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJrZXlzdG9yZSBpcyBlbXB0eSIsIGtleVN0b3JlLmFsaWFzZXMoKQorICAgICAgICAgICAgICAgICAgICAuaGFzTW9yZUVsZW1lbnRzKCkpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RLZXlTdG9yZUNyZWF0ZSgpIHsKKyAgICAgICAgS2V5U3RvcmUga2V5U3RvcmUgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5U3RvcmUgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCAidGhlIHNlY3JldCBwYXNzd29yZCIudG9DaGFyQXJyYXkoKSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNlcnRpZmljYXRlRmFjdG9yeSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjZXJ0aWZpY2F0ZUZhY3RvcnkgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgQ2VydGlmaWNhdGUgY2VydGlmaWNhdGUgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2VydGlmaWNhdGUgPSBjZXJ0aWZpY2F0ZUZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdlbmVyYXRlQ2VydGlmaWNhdGUobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuY29kZWRDZXJ0aWZpY2F0ZS5nZXRCeXRlcygpKSk7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvciBnZW5lcmF0b3IgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZ2VuZXJhdG9yID0gS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZShjZXJ0aWZpY2F0ZS5nZXRQdWJsaWNLZXkoKQorICAgICAgICAgICAgICAgICAgICAuZ2V0QWxnb3JpdGhtKCkpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBLZXlQYWlyIGtleVBhaXIgPSBnZW5lcmF0b3IuZ2VuZXJhdGVLZXlQYWlyKCk7CisKKyAgICAgICAgUHJpdmF0ZUtleUVudHJ5IHByaXZhdGVLZXlFbnRyeSA9IG5ldyBQcml2YXRlS2V5RW50cnkoa2V5UGFpcgorICAgICAgICAgICAgICAgIC5nZXRQcml2YXRlKCksIG5ldyBDZXJ0aWZpY2F0ZVtdIHtjZXJ0aWZpY2F0ZX0pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlTdG9yZS5zZXRFbnRyeSgiYVByaXZhdGVLZXkiLCBwcml2YXRlS2V5RW50cnksCisgICAgICAgICAgICAgICAgICAgIG5ldyBQYXNzd29yZFByb3RlY3Rpb24oInRoZSBrZXkgcGFzc3dvcmQiLnRvQ2hhckFycmF5KCkpKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShrZXlTdG9yZS5jb250YWluc0FsaWFzKCJhUHJpdmF0ZUtleSIpKTsKKyAgICAgICAgfSBjYXRjaCAoS2V5U3RvcmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgUHJpdmF0ZUtleUVudHJ5IGVudHJ5ID0gKFByaXZhdGVLZXlFbnRyeSkga2V5U3RvcmUuZ2V0RW50cnkoCisgICAgICAgICAgICAgICAgICAgICJhUHJpdmF0ZUtleSIsIG5ldyBQYXNzd29yZFByb3RlY3Rpb24oInRoZSBrZXkgcGFzc3dvcmQiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRvQ2hhckFycmF5KCkpKTsKKyAgICAgICAgICAgIFByaXZhdGVLZXkgcHJpdmF0ZUtleSA9IGVudHJ5LmdldFByaXZhdGVLZXkoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhrZXlQYWlyLmdldFByaXZhdGUoKSwgcHJpdmF0ZUtleSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoVW5yZWNvdmVyYWJsZUVudHJ5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gc3RyZWFtID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAga2V5U3RvcmUuc3RvcmUoc3RyZWFtLCAidGhlIGtleXN0b3JlIHBhc3N3b3JkIi50b0NoYXJBcnJheSgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImtleXN0b3JlIG5vdCB3cml0dGVuIiwgc3RyZWFtLnNpemUoKSA+IDApOworICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyBlbmNvZGVkQ2VydGlmaWNhdGUgPSAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICAgICArICJNSUlEMGpDQ0F6dWdBd0lCQWdJQkFqQU5CZ2txaGtpRzl3MEJBUVFGQURDQm1qRUxNQWtHQTFVRUJoTUNWVXN4XG4iCisgICAgICAgICAgICArICJFakFRQmdOVkJBZ1RDVWhoYlhCemFHbHlaVEVUTUJFR0ExVUVCeE1LVjJsdVkyaGxjM1JsY2pFVE1CRUdBMVVFXG4iCisgICAgICAgICAgICArICJDaE1LU1VKTklGVkxJRXgwWkRFTU1Bb0dBMVVFQ3hNRFNsUkRNUll3RkFZRFZRUURFdzFRWVhWc0lFZ2dRV0ppXG4iCisgICAgICAgICAgICArICJiM1IwTVNjd0pRWUpLb1pJaHZjTkFRa0JGaGhRWVhWc1gwaGZRV0ppYjNSMFFIVnJMbWxpYlM1amIyMHdIaGNOXG4iCisgICAgICAgICAgICArICJNRFF3TmpJeU1qQTFNRFUxV2hjTk1EVXdOakl5TWpBMU1EVTFXakNCbURFTE1Ba0dBMVVFQmhNQ1ZVc3hFakFRXG4iCisgICAgICAgICAgICArICJCZ05WQkFnVENVaGhiWEJ6YUdseVpURVRNQkVHQTFVRUJ4TUtWMmx1WTJobGMzUmxjakVUTUJFR0ExVUVDaE1LXG4iCisgICAgICAgICAgICArICJTVUpOSUZWcklFeDBaREVNTUFvR0ExVUVDeE1EU2tWVU1SUXdFZ1lEVlFRREV3dFFZWFZzSUVGaVltOTBkREVuXG4iCisgICAgICAgICAgICArICJNQ1VHQ1NxR1NJYjNEUUVKQVJZWVVHRjFiRjlJWDBGaVltOTBkRUIxYXk1cFltMHVZMjl0TUlHZk1BMEdDU3FHXG4iCisgICAgICAgICAgICArICJTSWIzRFFFQkFRVUFBNEdOQURDQmlRS0JnUURpdFpCUTVkMThlY05KcGNudUtUcmFIWXRxc0F1Z29jOTUvTDVRXG4iCisgICAgICAgICAgICArICIyOHMzdDFRQXUyNTA1cVFSMU1aYUFrWTd0RE55bDF2UG5ab3ltK1kwNlVzd1RyWm9WWW8vZ1BOZXlXUE1Uc0xBXG4iCisgICAgICAgICAgICArICJ3elF2azUvNnlodEU5Y2lIN0IwU3FZdzZ1U2lEVGJVWS96UTZxZWQrVHNRaGpsYm4zUFVIUmpuSTJQOEEwNGNnXG4iCisgICAgICAgICAgICArICJMZ1lZR1FJREFRQUJvNElCSmpDQ0FTSXdDUVlEVlIwVEJBSXdBREFzQmdsZ2hrZ0JodmhDQVEwRUh4WWRUM0JsXG4iCisgICAgICAgICAgICArICJibE5UVENCSFpXNWxjbUYwWldRZ1EyVnlkR2xtYVdOaGRHVXdIUVlEVlIwT0JCWUVGUHBsUlBzNjVoVWZ4VUJzXG4iCisgICAgICAgICAgICArICI2L1RhcTduTjhpMVVNSUhIQmdOVkhTTUVnYjh3Z2J5QUZKT010UEF3bFhkWkxxRTdES1U2eHBMNkZqRnRvWUdnXG4iCisgICAgICAgICAgICArICJwSUdkTUlHYU1Rc3dDUVlEVlFRR0V3SlZTekVTTUJBR0ExVUVDQk1KU0dGdGNITm9hWEpsTVJNd0VRWURWUVFIXG4iCisgICAgICAgICAgICArICJFd3BYYVc1amFHVnpkR1Z5TVJNd0VRWURWUVFLRXdwSlFrMGdWVXNnVEhSa01Rd3dDZ1lEVlFRTEV3TktWRU14XG4iCisgICAgICAgICAgICArICJGakFVQmdOVkJBTVREVkJoZFd3Z1NDQkJZbUp2ZEhReEp6QWxCZ2txaGtpRzl3MEJDUUVXR0ZCaGRXeGZTRjlCXG4iCisgICAgICAgICAgICArICJZbUp2ZEhSQWRXc3VhV0p0TG1OdmJZSUJBREFOQmdrcWhraUc5dzBCQVFRRkFBT0JnUUFuUTIySncySFVyejdjXG4iCisgICAgICAgICAgICArICJWYU9hcDMxbVRpa3VRL0NReHB3UFlpU3lUSjRzOTllRXpuKzJ5QWs5dElESUpwcW9heS9maitPTGdQVVFLSUFvXG4iCisgICAgICAgICAgICArICJYcFJWdm1IbEdFN1VxTUtlYlp0U1pKUXpzNlZvZWVLRmhnSG1xZzhlVkMyQXNUYzRac3dKbWc0d0N1aTVBSDNhXG4iCisgICAgICAgICAgICArICJvcUc3UElNM0x4WnFYWVFsWmlQU1o2a0NwRE9XVmc9PVxuIgorICAgICAgICAgICAgKyAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLVxuIjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L0tleVN0b3JlVGVzdFBLQ1MxMi5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvS2V5U3RvcmVUZXN0UEtDUzEyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzQ1NTQ4NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L0tleVN0b3JlVGVzdFBLQ1MxMi5qYXZhCkBAIC0wLDAgKzEsNDgxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSB0ZXN0cy50YXJnZXRzLnNlY3VyaXR5OworCitwdWJsaWMgY2xhc3MgS2V5U3RvcmVUZXN0UEtDUzEyIGV4dGVuZHMgS2V5U3RvcmVUZXN0IHsKKworICAgIHB1YmxpYyBLZXlTdG9yZVRlc3RQS0NTMTIoKSB7CisgICAgICAgIHN1cGVyKCJQS0NTMTIiLCBrZXlTdG9yZURhdGEsIGtleVN0b3JlUGFzc3dvcmQpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGtleVN0b3JlUGFzc3dvcmQgPSAidGhlIGtleXN0b3JlIHBhc3N3b3JkIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZVtdIGtleVN0b3JlRGF0YSA9IG5ldyBieXRlW10geworICAgICAgICAgICAgKGJ5dGUpIDB4MzAsIChieXRlKSAweDgwLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAzLAorICAgICAgICAgICAgKGJ5dGUpIDB4MzAsIChieXRlKSAweDgwLCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MDksIChieXRlKSAweDJBLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODYsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4RjcsIChieXRlKSAweDBELAorICAgICAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweDA3LCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4QTAsIChieXRlKSAweDgwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjQsIChieXRlKSAweDgwLCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDAzLAorICAgICAgICAgICAgKGJ5dGUpIDB4RTgsIChieXRlKSAweDMwLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDgwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDYsIChieXRlKSAweDA5LCAoYnl0ZSkgMHgyQSwgKGJ5dGUpIDB4ODYsIChieXRlKSAweDQ4LAorICAgICAgICAgICAgKGJ5dGUpIDB4ODYsIChieXRlKSAweEY3LCAoYnl0ZSkgMHgwRCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDA3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweEEwLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4MjQsIChieXRlKSAweDgwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDQsIChieXRlKSAweDgyLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MTksIChieXRlKSAweDMwLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODIsIChieXRlKSAweDAzLCAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDgyLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDMsIChieXRlKSAweDExLCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MEIsIChieXRlKSAweDJBLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODYsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4RjcsIChieXRlKSAweDBELAorICAgICAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweDBDLCAoYnl0ZSkgMHgwQSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAyLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTAsIChieXRlKSAweDgyLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4QjIsIChieXRlKSAweDMwLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODIsIChieXRlKSAweDAyLCAoYnl0ZSkgMHhBRSwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDI4LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDYsIChieXRlKSAweDBBLCAoYnl0ZSkgMHgyQSwgKGJ5dGUpIDB4ODYsIChieXRlKSAweDQ4LAorICAgICAgICAgICAgKGJ5dGUpIDB4ODYsIChieXRlKSAweEY3LCAoYnl0ZSkgMHgwRCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDBDLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAzLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4MUEsIChieXRlKSAweDA0LAorICAgICAgICAgICAgKGJ5dGUpIDB4MTQsIChieXRlKSAweEQxLCAoYnl0ZSkgMHhCMiwgKGJ5dGUpIDB4NTQsIChieXRlKSAweDc1LAorICAgICAgICAgICAgKGJ5dGUpIDB4MEQsIChieXRlKSAweDdELCAoYnl0ZSkgMHgwQSwgKGJ5dGUpIDB4M0YsIChieXRlKSAweDBBLAorICAgICAgICAgICAgKGJ5dGUpIDB4NjMsIChieXRlKSAweDUyLCAoYnl0ZSkgMHhFQywgKGJ5dGUpIDB4MDAsIChieXRlKSAweEJFLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzksIChieXRlKSAweEQ1LCAoYnl0ZSkgMHhFMiwgKGJ5dGUpIDB4NjksIChieXRlKSAweEJDLAorICAgICAgICAgICAgKGJ5dGUpIDB4Q0MsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDQsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDQsIChieXRlKSAweDgyLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4ODAsIChieXRlKSAweDM0LAorICAgICAgICAgICAgKGJ5dGUpIDB4REUsIChieXRlKSAweDNDLCAoYnl0ZSkgMHg1NywgKGJ5dGUpIDB4MkYsIChieXRlKSAweEI3LAorICAgICAgICAgICAgKGJ5dGUpIDB4QzgsIChieXRlKSAweENBLCAoYnl0ZSkgMHg5MywgKGJ5dGUpIDB4NkUsIChieXRlKSAweEFBLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODIsIChieXRlKSAweEFELCAoYnl0ZSkgMHhERiwgKGJ5dGUpIDB4Q0EsIChieXRlKSAweDNGLAorICAgICAgICAgICAgKGJ5dGUpIDB4RjMsIChieXRlKSAweENFLCAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4RUIsIChieXRlKSAweEQ1LAorICAgICAgICAgICAgKGJ5dGUpIDB4NDIsIChieXRlKSAweEMyLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4QjMsIChieXRlKSAweDgzLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjEsIChieXRlKSAweEJCLCAoYnl0ZSkgMHg1RiwgKGJ5dGUpIDB4NjUsIChieXRlKSAweEU0LAorICAgICAgICAgICAgKGJ5dGUpIDB4MEMsIChieXRlKSAweEVELCAoYnl0ZSkgMHg4MywgKGJ5dGUpIDB4RjMsIChieXRlKSAweDc0LAorICAgICAgICAgICAgKGJ5dGUpIDB4NjYsIChieXRlKSAweEJELCAoYnl0ZSkgMHgxMywgKGJ5dGUpIDB4NzEsIChieXRlKSAweDBDLAorICAgICAgICAgICAgKGJ5dGUpIDB4M0QsIChieXRlKSAweEVCLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4NTMsIChieXRlKSAweDRELAorICAgICAgICAgICAgKGJ5dGUpIDB4N0IsIChieXRlKSAweEIwLCAoYnl0ZSkgMHgzQywgKGJ5dGUpIDB4QTEsIChieXRlKSAweDU5LAorICAgICAgICAgICAgKGJ5dGUpIDB4RDYsIChieXRlKSAweDQ5LCAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4NEEsIChieXRlKSAweDg0LAorICAgICAgICAgICAgKGJ5dGUpIDB4RDMsIChieXRlKSAweDc4LCAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4RTYsIChieXRlKSAweDlGLAorICAgICAgICAgICAgKGJ5dGUpIDB4QUYsIChieXRlKSAweEJCLCAoYnl0ZSkgMHhDQiwgKGJ5dGUpIDB4NzcsIChieXRlKSAweDVELAorICAgICAgICAgICAgKGJ5dGUpIDB4RTQsIChieXRlKSAweEQwLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4QkIsIChieXRlKSAweDA0LAorICAgICAgICAgICAgKGJ5dGUpIDB4NUYsIChieXRlKSAweERCLCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4QkYsIChieXRlKSAweDQzLAorICAgICAgICAgICAgKGJ5dGUpIDB4M0IsIChieXRlKSAweEQyLCAoYnl0ZSkgMHhFNCwgKGJ5dGUpIDB4QjksIChieXRlKSAweDEyLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTUsIChieXRlKSAweDE2LCAoYnl0ZSkgMHgzNywgKGJ5dGUpIDB4MkEsIChieXRlKSAweDhGLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODksIChieXRlKSAweDcwLCAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4MzMsIChieXRlKSAweDEzLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTMsIChieXRlKSAweEVGLCAoYnl0ZSkgMHhCOSwgKGJ5dGUpIDB4OUEsIChieXRlKSAweEQxLAorICAgICAgICAgICAgKGJ5dGUpIDB4RDEsIChieXRlKSAweEVDLCAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4MzYsIChieXRlKSAweDk2LAorICAgICAgICAgICAgKGJ5dGUpIDB4QUIsIChieXRlKSAweDFDLCAoYnl0ZSkgMHhBMiwgKGJ5dGUpIDB4QjIsIChieXRlKSAweDE2LAorICAgICAgICAgICAgKGJ5dGUpIDB4NjAsIChieXRlKSAweDRCLCAoYnl0ZSkgMHgzNywgKGJ5dGUpIDB4ODYsIChieXRlKSAweDFGLAorICAgICAgICAgICAgKGJ5dGUpIDB4RUQsIChieXRlKSAweEY0LCAoYnl0ZSkgMHgyRCwgKGJ5dGUpIDB4RjUsIChieXRlKSAweDQ3LAorICAgICAgICAgICAgKGJ5dGUpIDB4NEQsIChieXRlKSAweEVDLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4QUEsIChieXRlKSAweEQwLAorICAgICAgICAgICAgKGJ5dGUpIDB4OTUsIChieXRlKSAweDc0LCAoYnl0ZSkgMHgyNywgKGJ5dGUpIDB4QzMsIChieXRlKSAweEY5LAorICAgICAgICAgICAgKGJ5dGUpIDB4QzgsIChieXRlKSAweDMxLCAoYnl0ZSkgMHhBRSwgKGJ5dGUpIDB4Q0MsIChieXRlKSAweDVFLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzgsIChieXRlKSAweDk1LCAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4RTYsIChieXRlKSAweDQxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MzksIChieXRlKSAweEM4LCAoYnl0ZSkgMHg3QSwgKGJ5dGUpIDB4QzQsIChieXRlKSAweEM2LAorICAgICAgICAgICAgKGJ5dGUpIDB4MUQsIChieXRlKSAweDYxLCAoYnl0ZSkgMHg2QiwgKGJ5dGUpIDB4QTIsIChieXRlKSAweDEzLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDQsIChieXRlKSAweDA4LCAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4MTcsIChieXRlKSAweDU0LAorICAgICAgICAgICAgKGJ5dGUpIDB4Q0YsIChieXRlKSAweEUyLCAoYnl0ZSkgMHg5RSwgKGJ5dGUpIDB4OUMsIChieXRlKSAweDdDLAorICAgICAgICAgICAgKGJ5dGUpIDB4MkQsIChieXRlKSAweDlDLCAoYnl0ZSkgMHgxMywgKGJ5dGUpIDB4N0QsIChieXRlKSAweEI3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MjMsIChieXRlKSAweDM1LCAoYnl0ZSkgMHhDMCwgKGJ5dGUpIDB4QjEsIChieXRlKSAweDdGLAorICAgICAgICAgICAgKGJ5dGUpIDB4NUQsIChieXRlKSAweEI2LCAoYnl0ZSkgMHgxRiwgKGJ5dGUpIDB4RjYsIChieXRlKSAweEYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4RjYsIChieXRlKSAweDM5LCAoYnl0ZSkgMHgyRSwgKGJ5dGUpIDB4NTIsIChieXRlKSAweEQyLAorICAgICAgICAgICAgKGJ5dGUpIDB4RDAsIChieXRlKSAweDY5LCAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4NTEsIChieXRlKSAweDE3LAorICAgICAgICAgICAgKGJ5dGUpIDB4RDEsIChieXRlKSAweDM2LCAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4RTMsIChieXRlKSAweDA5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MzEsIChieXRlKSAweDZGLCAoYnl0ZSkgMHgwRiwgKGJ5dGUpIDB4NzksIChieXRlKSAweEMzLAorICAgICAgICAgICAgKGJ5dGUpIDB4RjksIChieXRlKSAweDlFLCAoYnl0ZSkgMHg5NSwgKGJ5dGUpIDB4RUYsIChieXRlKSAweEJBLAorICAgICAgICAgICAgKGJ5dGUpIDB4RUIsIChieXRlKSAweDVGLCAoYnl0ZSkgMHhDNiwgKGJ5dGUpIDB4MzgsIChieXRlKSAweDdELAorICAgICAgICAgICAgKGJ5dGUpIDB4ODgsIChieXRlKSAweEMwLCAoYnl0ZSkgMHgxMywgKGJ5dGUpIDB4QkEsIChieXRlKSAweEJFLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTYsIChieXRlKSAweDAzLCAoYnl0ZSkgMHhBNywgKGJ5dGUpIDB4NEMsIChieXRlKSAweEZBLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTUsIChieXRlKSAweDYwLCAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4ODUsIChieXRlKSAweEU3LAorICAgICAgICAgICAgKGJ5dGUpIDB4QkEsIChieXRlKSAweEVGLCAoYnl0ZSkgMHgzQiwgKGJ5dGUpIDB4RjQsIChieXRlKSAweDRELAorICAgICAgICAgICAgKGJ5dGUpIDB4ODcsIChieXRlKSAweDkzLCAoYnl0ZSkgMHhERCwgKGJ5dGUpIDB4RDYsIChieXRlKSAweDMwLAorICAgICAgICAgICAgKGJ5dGUpIDB4RjUsIChieXRlKSAweDQzLCAoYnl0ZSkgMHhCMiwgKGJ5dGUpIDB4QkYsIChieXRlKSAweDUzLAorICAgICAgICAgICAgKGJ5dGUpIDB4NTQsIChieXRlKSAweDQ3LCAoYnl0ZSkgMHhDQSwgKGJ5dGUpIDB4MTgsIChieXRlKSAweDU1LAorICAgICAgICAgICAgKGJ5dGUpIDB4ODYsIChieXRlKSAweDNBLCAoYnl0ZSkgMHg4QSwgKGJ5dGUpIDB4RDQsIChieXRlKSAweDI2LAorICAgICAgICAgICAgKGJ5dGUpIDB4ODgsIChieXRlKSAweENBLCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4QTMsIChieXRlKSAweEIwLAorICAgICAgICAgICAgKGJ5dGUpIDB4RTcsIChieXRlKSAweEE3LCAoYnl0ZSkgMHhCNywgKGJ5dGUpIDB4RjAsIChieXRlKSAweEMyLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTcsIChieXRlKSAweDgxLCAoYnl0ZSkgMHgwRCwgKGJ5dGUpIDB4RUQsIChieXRlKSAweDY0LAorICAgICAgICAgICAgKGJ5dGUpIDB4NDAsIChieXRlKSAweEQxLCAoYnl0ZSkgMHg3NywgKGJ5dGUpIDB4MkMsIChieXRlKSAweEU5LAorICAgICAgICAgICAgKGJ5dGUpIDB4NUMsIChieXRlKSAweDFELCAoYnl0ZSkgMHhFNiwgKGJ5dGUpIDB4NDEsIChieXRlKSAweDE5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MzAsIChieXRlKSAweDhCLCAoYnl0ZSkgMHg2QiwgKGJ5dGUpIDB4QzEsIChieXRlKSAweDA1LAorICAgICAgICAgICAgKGJ5dGUpIDB4NTIsIChieXRlKSAweDVDLCAoYnl0ZSkgMHg0QiwgKGJ5dGUpIDB4QjgsIChieXRlKSAweEY0LAorICAgICAgICAgICAgKGJ5dGUpIDB4RTMsIChieXRlKSAweDQxLCAoYnl0ZSkgMHhBMCwgKGJ5dGUpIDB4NTYsIChieXRlKSAweEE3LAorICAgICAgICAgICAgKGJ5dGUpIDB4RTAsIChieXRlKSAweDU5LCAoYnl0ZSkgMHhCOSwgKGJ5dGUpIDB4OTIsIChieXRlKSAweEFELAorICAgICAgICAgICAgKGJ5dGUpIDB4QjMsIChieXRlKSAweEU3LCAoYnl0ZSkgMHg3MCwgKGJ5dGUpIDB4MDMsIChieXRlKSAweDlDLAorICAgICAgICAgICAgKGJ5dGUpIDB4RUQsIChieXRlKSAweENDLCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4M0EsIChieXRlKSAweDZELAorICAgICAgICAgICAgKGJ5dGUpIDB4NzQsIChieXRlKSAweDJCLCAoYnl0ZSkgMHhDNiwgKGJ5dGUpIDB4OUIsIChieXRlKSAweEQyLAorICAgICAgICAgICAgKGJ5dGUpIDB4OUUsIChieXRlKSAweDI3LCAoYnl0ZSkgMHhFOSwgKGJ5dGUpIDB4MkEsIChieXRlKSAweEE5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MTAsIChieXRlKSAweERFLCAoYnl0ZSkgMHhCRiwgKGJ5dGUpIDB4NkEsIChieXRlKSAweEY2LAorICAgICAgICAgICAgKGJ5dGUpIDB4MzgsIChieXRlKSAweDMyLCAoYnl0ZSkgMHhCRSwgKGJ5dGUpIDB4RTEsIChieXRlKSAweDA1LAorICAgICAgICAgICAgKGJ5dGUpIDB4M0QsIChieXRlKSAweEQ1LCAoYnl0ZSkgMHhGNSwgKGJ5dGUpIDB4OEEsIChieXRlKSAweDk1LAorICAgICAgICAgICAgKGJ5dGUpIDB4REIsIChieXRlKSAweDYwLCAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4NDEsIChieXRlKSAweEYyLAorICAgICAgICAgICAgKGJ5dGUpIDB4OTgsIChieXRlKSAweDQxLCAoYnl0ZSkgMHhERCwgKGJ5dGUpIDB4QjgsIChieXRlKSAweEVELAorICAgICAgICAgICAgKGJ5dGUpIDB4OTIsIChieXRlKSAweDU1LCAoYnl0ZSkgMHhBNCwgKGJ5dGUpIDB4MjMsIChieXRlKSAweDBFLAorICAgICAgICAgICAgKGJ5dGUpIDB4QzYsIChieXRlKSAweDdDLCAoYnl0ZSkgMHg1NywgKGJ5dGUpIDB4MjksIChieXRlKSAweDEwLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTQsIChieXRlKSAweDZDLCAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4N0YsIChieXRlKSAweEZELAorICAgICAgICAgICAgKGJ5dGUpIDB4MkYsIChieXRlKSAweDk3LCAoYnl0ZSkgMHhFOCwgKGJ5dGUpIDB4NjAsIChieXRlKSAweDQxLAorICAgICAgICAgICAgKGJ5dGUpIDB4RTksIChieXRlKSAweDlFLCAoYnl0ZSkgMHhENiwgKGJ5dGUpIDB4QjQsIChieXRlKSAweEIwLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTgsIChieXRlKSAweDkxLCAoYnl0ZSkgMHhDNCwgKGJ5dGUpIDB4NUMsIChieXRlKSAweDZBLAorICAgICAgICAgICAgKGJ5dGUpIDB4RjUsIChieXRlKSAweDM0LCAoYnl0ZSkgMHgyQywgKGJ5dGUpIDB4MkYsIChieXRlKSAweERBLAorICAgICAgICAgICAgKGJ5dGUpIDB4QUQsIChieXRlKSAweDg1LCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4RDMsIChieXRlKSAweDE4LAorICAgICAgICAgICAgKGJ5dGUpIDB4QjQsIChieXRlKSAweDAzLCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4Q0EsIChieXRlKSAweDZFLAorICAgICAgICAgICAgKGJ5dGUpIDB4Q0MsIChieXRlKSAweDExLCAoYnl0ZSkgMHg2NiwgKGJ5dGUpIDB4MUYsIChieXRlKSAweDlBLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzYsIChieXRlKSAweDdDLCAoYnl0ZSkgMHhFNiwgKGJ5dGUpIDB4RjgsIChieXRlKSAweDAzLAorICAgICAgICAgICAgKGJ5dGUpIDB4MzQsIChieXRlKSAweDFGLCAoYnl0ZSkgMHgzRSwgKGJ5dGUpIDB4NEYsIChieXRlKSAweDFCLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTQsIChieXRlKSAweEZELCAoYnl0ZSkgMHg5RiwgKGJ5dGUpIDB4NDEsIChieXRlKSAweEZBLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzMsIChieXRlKSAweDM2LCAoYnl0ZSkgMHg0RSwgKGJ5dGUpIDB4NTIsIChieXRlKSAweDhELAorICAgICAgICAgICAgKGJ5dGUpIDB4ODQsIChieXRlKSAweDBELCAoYnl0ZSkgMHg3QywgKGJ5dGUpIDB4QjYsIChieXRlKSAweDI3LAorICAgICAgICAgICAgKGJ5dGUpIDB4NDksIChieXRlKSAweDAzLCAoYnl0ZSkgMHhDMSwgKGJ5dGUpIDB4NzAsIChieXRlKSAweDJFLAorICAgICAgICAgICAgKGJ5dGUpIDB4NUQsIChieXRlKSAweENCLCAoYnl0ZSkgMHgyQywgKGJ5dGUpIDB4NDUsIChieXRlKSAweDRCLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODYsIChieXRlKSAweEQ0LCAoYnl0ZSkgMHhEQSwgKGJ5dGUpIDB4NkIsIChieXRlKSAweDEzLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweDExLCAoYnl0ZSkgMHg0QSwgKGJ5dGUpIDB4RUQsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4OUQsIChieXRlKSAweEM1LCAoYnl0ZSkgMHhDMCwgKGJ5dGUpIDB4MTAsIChieXRlKSAweEJDLAorICAgICAgICAgICAgKGJ5dGUpIDB4NTksIChieXRlKSAweDU0LCAoYnl0ZSkgMHhDMywgKGJ5dGUpIDB4Q0YsIChieXRlKSAweDY1LAorICAgICAgICAgICAgKGJ5dGUpIDB4M0QsIChieXRlKSAweEFELCAoYnl0ZSkgMHhDOSwgKGJ5dGUpIDB4MjAsIChieXRlKSAweDlELAorICAgICAgICAgICAgKGJ5dGUpIDB4MUMsIChieXRlKSAweDMxLCAoYnl0ZSkgMHhFRSwgKGJ5dGUpIDB4NjgsIChieXRlKSAweDk4LAorICAgICAgICAgICAgKGJ5dGUpIDB4NzAsIChieXRlKSAweEU1LCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4QzQsIChieXRlKSAweEYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4OTAsIChieXRlKSAweEIwLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4RUMsIChieXRlKSAweEZBLAorICAgICAgICAgICAgKGJ5dGUpIDB4NDQsIChieXRlKSAweEZBLCAoYnl0ZSkgMHgzRSwgKGJ5dGUpIDB4MDQsIChieXRlKSAweDhBLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODgsIChieXRlKSAweEZBLCAoYnl0ZSkgMHhGMywgKGJ5dGUpIDB4MTUsIChieXRlKSAweDY3LAorICAgICAgICAgICAgKGJ5dGUpIDB4RTYsIChieXRlKSAweDdFLCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4OUYsIChieXRlKSAweEM5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MzEsIChieXRlKSAweDA4LCAoYnl0ZSkgMHhGNiwgKGJ5dGUpIDB4MkQsIChieXRlKSAweEVBLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTYsIChieXRlKSAweDlELCAoYnl0ZSkgMHg5QywgKGJ5dGUpIDB4RjEsIChieXRlKSAweDc5LAorICAgICAgICAgICAgKGJ5dGUpIDB4RTUsIChieXRlKSAweDlGLCAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDY5LAorICAgICAgICAgICAgKGJ5dGUpIDB4NjIsIChieXRlKSAweDU2LCAoYnl0ZSkgMHgyMSwgKGJ5dGUpIDB4QkQsIChieXRlKSAweDNCLAorICAgICAgICAgICAgKGJ5dGUpIDB4MzcsIChieXRlKSAweDlDLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4QzgsIChieXRlKSAweEJELAorICAgICAgICAgICAgKGJ5dGUpIDB4MEMsIChieXRlKSAweDA3LCAoYnl0ZSkgMHhDQSwgKGJ5dGUpIDB4QzEsIChieXRlKSAweEM0LAorICAgICAgICAgICAgKGJ5dGUpIDB4NDQsIChieXRlKSAweDQxLCAoYnl0ZSkgMHg2RSwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDU4LAorICAgICAgICAgICAgKGJ5dGUpIDB4RjMsIChieXRlKSAweDUyLCAoYnl0ZSkgMHg2QiwgKGJ5dGUpIDB4RjMsIChieXRlKSAweEU1LAorICAgICAgICAgICAgKGJ5dGUpIDB4REYsIChieXRlKSAweEQ2LCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4RUEsIChieXRlKSAweDVELAorICAgICAgICAgICAgKGJ5dGUpIDB4MDgsIChieXRlKSAweDZELCAoYnl0ZSkgMHg0NiwgKGJ5dGUpIDB4NDcsIChieXRlKSAweEQyLAorICAgICAgICAgICAgKGJ5dGUpIDB4Q0EsIChieXRlKSAweDAwLCAoYnl0ZSkgMHhDRCwgKGJ5dGUpIDB4MkMsIChieXRlKSAweDU1LAorICAgICAgICAgICAgKGJ5dGUpIDB4MEIsIChieXRlKSAweEQ0LCAoYnl0ZSkgMHhEOSwgKGJ5dGUpIDB4ODksIChieXRlKSAweDBFLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODMsIChieXRlKSAweDBELCAoYnl0ZSkgMHg0MywgKGJ5dGUpIDB4QUEsIChieXRlKSAweEI0LAorICAgICAgICAgICAgKGJ5dGUpIDB4QTYsIChieXRlKSAweEU1LCAoYnl0ZSkgMHg0RSwgKGJ5dGUpIDB4RTcsIChieXRlKSAweERELAorICAgICAgICAgICAgKGJ5dGUpIDB4RDYsIChieXRlKSAweDk0LCAoYnl0ZSkgMHhBOSwgKGJ5dGUpIDB4NTcsIChieXRlKSAweEYwLAorICAgICAgICAgICAgKGJ5dGUpIDB4QkIsIChieXRlKSAweEI0LCAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4NjEsIChieXRlKSAweDQ2LAorICAgICAgICAgICAgKGJ5dGUpIDB4NUYsIChieXRlKSAweDAzLCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4MDIsIChieXRlKSAweERDLAorICAgICAgICAgICAgKGJ5dGUpIDB4NTQsIChieXRlKSAweDZBLCAoYnl0ZSkgMHg5RSwgKGJ5dGUpIDB4MTYsIChieXRlKSAweDNCLAorICAgICAgICAgICAgKGJ5dGUpIDB4NEYsIChieXRlKSAweEY3LCAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4N0MsIChieXRlKSAweDUyLAorICAgICAgICAgICAgKGJ5dGUpIDB4NTQsIChieXRlKSAweENELCAoYnl0ZSkgMHhDMiwgKGJ5dGUpIDB4QzUsIChieXRlKSAweEE2LAorICAgICAgICAgICAgKGJ5dGUpIDB4QjksIChieXRlKSAweDAwLCAoYnl0ZSkgMHhDMiwgKGJ5dGUpIDB4OTcsIChieXRlKSAweDVGLAorICAgICAgICAgICAgKGJ5dGUpIDB4QjcsIChieXRlKSAweDIzLCAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4MDUsIChieXRlKSAweEYyLAorICAgICAgICAgICAgKGJ5dGUpIDB4NTksIChieXRlKSAweEIwLCAoYnl0ZSkgMHhFRCwgKGJ5dGUpIDB4NDgsIChieXRlKSAweEY5LAorICAgICAgICAgICAgKGJ5dGUpIDB4M0IsIChieXRlKSAweEE4LCAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4QjEsIChieXRlKSAweDE0LAorICAgICAgICAgICAgKGJ5dGUpIDB4NzIsIChieXRlKSAweDU5LCAoYnl0ZSkgMHg3RCwgKGJ5dGUpIDB4OUQsIChieXRlKSAweDhBLAorICAgICAgICAgICAgKGJ5dGUpIDB4MUMsIChieXRlKSAweDhFLCAoYnl0ZSkgMHhEMSwgKGJ5dGUpIDB4OTksIChieXRlKSAweDdFLAorICAgICAgICAgICAgKGJ5dGUpIDB4M0QsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhBQiwgKGJ5dGUpIDB4NzksIChieXRlKSAweDVDLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzUsIChieXRlKSAweDJELCAoYnl0ZSkgMHg4RiwgKGJ5dGUpIDB4QzksIChieXRlKSAweEUwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MUQsIChieXRlKSAweDFELCAoYnl0ZSkgMHg4NCwgKGJ5dGUpIDB4QUEsIChieXRlKSAweEQwLAorICAgICAgICAgICAgKGJ5dGUpIDB4NjMsIChieXRlKSAweDM1LCAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4RDksIChieXRlKSAweDM5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MTQsIChieXRlKSAweDY5LCAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4NjgsIChieXRlKSAweDIxLAorICAgICAgICAgICAgKGJ5dGUpIDB4OEEsIChieXRlKSAweENCLCAoYnl0ZSkgMHg5MSwgKGJ5dGUpIDB4RjYsIChieXRlKSAweDEyLAorICAgICAgICAgICAgKGJ5dGUpIDB4RDgsIChieXRlKSAweDUyLCAoYnl0ZSkgMHg4QSwgKGJ5dGUpIDB4MDYsIChieXRlKSAweDU0LAorICAgICAgICAgICAgKGJ5dGUpIDB4OTksIChieXRlKSAweEZGLCAoYnl0ZSkgMHg1OCwgKGJ5dGUpIDB4NDgsIChieXRlKSAweDMxLAorICAgICAgICAgICAgKGJ5dGUpIDB4NEMsIChieXRlKSAweDMwLCAoYnl0ZSkgMHgyMywgKGJ5dGUpIDB4MDYsIChieXRlKSAweDA5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MkEsIChieXRlKSAweDg2LCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4ODYsIChieXRlKSAweEY3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MEQsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwOSwgKGJ5dGUpIDB4MTUsIChieXRlKSAweDMxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTYsIChieXRlKSAweDA0LCAoYnl0ZSkgMHgxNCwgKGJ5dGUpIDB4NzMsIChieXRlKSAweDEwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTQsIChieXRlKSAweEU3LCAoYnl0ZSkgMHgyRSwgKGJ5dGUpIDB4NzUsIChieXRlKSAweEU3LAorICAgICAgICAgICAgKGJ5dGUpIDB4QzYsIChieXRlKSAweDcxLCAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4NEUsIChieXRlKSAweDNBLAorICAgICAgICAgICAgKGJ5dGUpIDB4OEYsIChieXRlKSAweDUwLCAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4QjIsIChieXRlKSAweDZFLAorICAgICAgICAgICAgKGJ5dGUpIDB4NTgsIChieXRlKSAweDA1LCAoYnl0ZSkgMHhGMywgKGJ5dGUpIDB4MzAsIChieXRlKSAweDI1LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDYsIChieXRlKSAweDA5LCAoYnl0ZSkgMHgyQSwgKGJ5dGUpIDB4ODYsIChieXRlKSAweDQ4LAorICAgICAgICAgICAgKGJ5dGUpIDB4ODYsIChieXRlKSAweEY3LCAoYnl0ZSkgMHgwRCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDA5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MTQsIChieXRlKSAweDMxLCAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4MUUsIChieXRlKSAweDE2LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDYxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4NTAsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzIsIChieXRlKSAweDAwLCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDc2LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDYxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4NzQsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4NjUsIChieXRlKSAweDAwLCAoYnl0ZSkgMHg0QiwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDY1LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDc5LCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDgwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDYsIChieXRlKSAweDA5LCAoYnl0ZSkgMHgyQSwgKGJ5dGUpIDB4ODYsIChieXRlKSAweDQ4LAorICAgICAgICAgICAgKGJ5dGUpIDB4ODYsIChieXRlKSAweEY3LCAoYnl0ZSkgMHgwRCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDA3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDYsIChieXRlKSAweEEwLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDgwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDIsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDgwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDYsIChieXRlKSAweDA5LCAoYnl0ZSkgMHgyQSwgKGJ5dGUpIDB4ODYsIChieXRlKSAweDQ4LAorICAgICAgICAgICAgKGJ5dGUpIDB4ODYsIChieXRlKSAweEY3LCAoYnl0ZSkgMHgwRCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDA3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweDMwLCAoYnl0ZSkgMHgyOCwgKGJ5dGUpIDB4MDYsIChieXRlKSAweDBBLAorICAgICAgICAgICAgKGJ5dGUpIDB4MkEsIChieXRlKSAweDg2LCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4ODYsIChieXRlKSAweEY3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MEQsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwQywgKGJ5dGUpIDB4MDEsIChieXRlKSAweDA2LAorICAgICAgICAgICAgKGJ5dGUpIDB4MzAsIChieXRlKSAweDFBLCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MTQsIChieXRlKSAweDdGLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTAsIChieXRlKSAweDMwLCAoYnl0ZSkgMHg5MywgKGJ5dGUpIDB4REQsIChieXRlKSAweDczLAorICAgICAgICAgICAgKGJ5dGUpIDB4RTUsIChieXRlKSAweEZELCAoYnl0ZSkgMHg4RSwgKGJ5dGUpIDB4QjAsIChieXRlKSAweEYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4OTIsIChieXRlKSAweDk1LCAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4MjcsIChieXRlKSAweDM3LAorICAgICAgICAgICAgKGJ5dGUpIDB4QzgsIChieXRlKSAweEMzLCAoYnl0ZSkgMHhFQywgKGJ5dGUpIDB4NjQsIChieXRlKSAweDAyLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDIsIChieXRlKSAweDA0LCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4QTAsIChieXRlKSAweDgwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDQsIChieXRlKSAweDgyLCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4RTAsIChieXRlKSAweDJELAorICAgICAgICAgICAgKGJ5dGUpIDB4NDYsIChieXRlKSAweDc2LCAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4RjYsIChieXRlKSAweDZGLAorICAgICAgICAgICAgKGJ5dGUpIDB4NDAsIChieXRlKSAweDExLCAoYnl0ZSkgMHg2NiwgKGJ5dGUpIDB4QUIsIChieXRlKSAweEM5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MjAsIChieXRlKSAweDU1LCAoYnl0ZSkgMHgwOSwgKGJ5dGUpIDB4MEEsIChieXRlKSAweEQ3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MUUsIChieXRlKSAweDE3LCAoYnl0ZSkgMHhGRCwgKGJ5dGUpIDB4Q0UsIChieXRlKSAweERELAorICAgICAgICAgICAgKGJ5dGUpIDB4NEQsIChieXRlKSAweDcwLCAoYnl0ZSkgMHhEQSwgKGJ5dGUpIDB4QkYsIChieXRlKSAweEZELAorICAgICAgICAgICAgKGJ5dGUpIDB4RkMsIChieXRlKSAweEZBLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4MUMsIChieXRlKSAweDYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4RDksIChieXRlKSAweEUxLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDJFLAorICAgICAgICAgICAgKGJ5dGUpIDB4RTMsIChieXRlKSAweDgxLCAoYnl0ZSkgMHg5NywgKGJ5dGUpIDB4RDMsIChieXRlKSAweDk2LAorICAgICAgICAgICAgKGJ5dGUpIDB4RDUsIChieXRlKSAweEY4LCAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4QUUsIChieXRlKSAweEFELAorICAgICAgICAgICAgKGJ5dGUpIDB4MkYsIChieXRlKSAweENELCAoYnl0ZSkgMHhCNiwgKGJ5dGUpIDB4REYsIChieXRlKSAweDdGLAorICAgICAgICAgICAgKGJ5dGUpIDB4Q0YsIChieXRlKSAweEQxLCAoYnl0ZSkgMHhBMiwgKGJ5dGUpIDB4MUQsIChieXRlKSAweDAxLAorICAgICAgICAgICAgKGJ5dGUpIDB4NjQsIChieXRlKSAweEI1LCAoYnl0ZSkgMHhENywgKGJ5dGUpIDB4MTQsIChieXRlKSAweDVDLAorICAgICAgICAgICAgKGJ5dGUpIDB4MkIsIChieXRlKSAweDk0LCAoYnl0ZSkgMHhFQSwgKGJ5dGUpIDB4N0MsIChieXRlKSAweDk1LAorICAgICAgICAgICAgKGJ5dGUpIDB4MTQsIChieXRlKSAweDg4LCAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4QTQsIChieXRlKSAweDAzLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTksIChieXRlKSAweDRDLCAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4MTksIChieXRlKSAweDMxLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODUsIChieXRlKSAweEU3LCAoYnl0ZSkgMHhBRCwgKGJ5dGUpIDB4RDYsIChieXRlKSAweDA3LAorICAgICAgICAgICAgKGJ5dGUpIDB4QUMsIChieXRlKSAweEJFLCAoYnl0ZSkgMHgyQywgKGJ5dGUpIDB4QUQsIChieXRlKSAweDkwLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODUsIChieXRlKSAweEYxLCAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4QTAsIChieXRlKSAweEJGLAorICAgICAgICAgICAgKGJ5dGUpIDB4QjMsIChieXRlKSAweDg0LCAoYnl0ZSkgMHg5RCwgKGJ5dGUpIDB4MjQsIChieXRlKSAweDBELAorICAgICAgICAgICAgKGJ5dGUpIDB4NTEsIChieXRlKSAweDA0LCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDMsIChieXRlKSAweEU4LAorICAgICAgICAgICAgKGJ5dGUpIDB4QzQsIChieXRlKSAweDM1LCAoYnl0ZSkgMHg4QiwgKGJ5dGUpIDB4NTIsIChieXRlKSAweDY4LAorICAgICAgICAgICAgKGJ5dGUpIDB4QzEsIChieXRlKSAweDVGLCAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4N0MsIChieXRlKSAweDZGLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTAsIChieXRlKSAweEY2LCAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4OUYsIChieXRlKSAweDE2LAorICAgICAgICAgICAgKGJ5dGUpIDB4QUEsIChieXRlKSAweEQxLCAoYnl0ZSkgMHg4RiwgKGJ5dGUpIDB4NjksIChieXRlKSAweDE1LAorICAgICAgICAgICAgKGJ5dGUpIDB4RkMsIChieXRlKSAweDUzLCAoYnl0ZSkgMHgxNCwgKGJ5dGUpIDB4QzgsIChieXRlKSAweENFLAorICAgICAgICAgICAgKGJ5dGUpIDB4NDMsIChieXRlKSAweDkzLCAoYnl0ZSkgMHhEMywgKGJ5dGUpIDB4RTcsIChieXRlKSAweEI5LAorICAgICAgICAgICAgKGJ5dGUpIDB4NjAsIChieXRlKSAweEMxLCAoYnl0ZSkgMHg0QywgKGJ5dGUpIDB4QjUsIChieXRlKSAweEUyLAorICAgICAgICAgICAgKGJ5dGUpIDB4MEIsIChieXRlKSAweEI2LCAoYnl0ZSkgMHhBMiwgKGJ5dGUpIDB4Q0YsIChieXRlKSAweEY4LAorICAgICAgICAgICAgKGJ5dGUpIDB4QTEsIChieXRlKSAweEFBLCAoYnl0ZSkgMHhDRSwgKGJ5dGUpIDB4MzQsIChieXRlKSAweEQwLAorICAgICAgICAgICAgKGJ5dGUpIDB4OEYsIChieXRlKSAweERELCAoYnl0ZSkgMHhDOSwgKGJ5dGUpIDB4QjcsIChieXRlKSAweDUyLAorICAgICAgICAgICAgKGJ5dGUpIDB4RUYsIChieXRlKSAweDlGLCAoYnl0ZSkgMHgxQSwgKGJ5dGUpIDB4M0MsIChieXRlKSAweEU3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MjUsIChieXRlKSAweDhGLCAoYnl0ZSkgMHg2QSwgKGJ5dGUpIDB4MUMsIChieXRlKSAweEE5LAorICAgICAgICAgICAgKGJ5dGUpIDB4OTAsIChieXRlKSAweDM2LCAoYnl0ZSkgMHhGNywgKGJ5dGUpIDB4NEUsIChieXRlKSAweDgwLAorICAgICAgICAgICAgKGJ5dGUpIDB4NDUsIChieXRlKSAweDg3LCAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4Q0QsIChieXRlKSAweEQ2LAorICAgICAgICAgICAgKGJ5dGUpIDB4ODAsIChieXRlKSAweEE4LCAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4RjksIChieXRlKSAweEI5LAorICAgICAgICAgICAgKGJ5dGUpIDB4RUUsIChieXRlKSAweDE1LCAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4MkUsIChieXRlKSAweDdFLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTksIChieXRlKSAweEJDLCAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4RjAsIChieXRlKSAweDNDLAorICAgICAgICAgICAgKGJ5dGUpIDB4QkEsIChieXRlKSAweERGLCAoYnl0ZSkgMHhDRiwgKGJ5dGUpIDB4MzMsIChieXRlKSAweEEzLAorICAgICAgICAgICAgKGJ5dGUpIDB4QjYsIChieXRlKSAweEJBLCAoYnl0ZSkgMHg1NSwgKGJ5dGUpIDB4RTQsIChieXRlKSAweDA1LAorICAgICAgICAgICAgKGJ5dGUpIDB4QjQsIChieXRlKSAweEMwLCAoYnl0ZSkgMHhBRiwgKGJ5dGUpIDB4QUEsIChieXRlKSAweEVCLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzUsIChieXRlKSAweDEzLCAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDJCLAorICAgICAgICAgICAgKGJ5dGUpIDB4NTYsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhGOSwgKGJ5dGUpIDB4RjgsIChieXRlKSAweDg3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MEIsIChieXRlKSAweEVDLCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4NEEsIChieXRlKSAweEIzLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTksIChieXRlKSAweDg0LCAoYnl0ZSkgMHg1RiwgKGJ5dGUpIDB4NkUsIChieXRlKSAweDhFLAorICAgICAgICAgICAgKGJ5dGUpIDB4NEIsIChieXRlKSAweEE4LCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4QjAsIChieXRlKSAweDFBLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODMsIChieXRlKSAweDk4LCAoYnl0ZSkgMHg1NiwgKGJ5dGUpIDB4MkEsIChieXRlKSAweDY5LAorICAgICAgICAgICAgKGJ5dGUpIDB4QzgsIChieXRlKSAweDZELCAoYnl0ZSkgMHhEMCwgKGJ5dGUpIDB4MTIsIChieXRlKSAweEMxLAorICAgICAgICAgICAgKGJ5dGUpIDB4NTAsIChieXRlKSAweENGLCAoYnl0ZSkgMHhCRCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDA0LAorICAgICAgICAgICAgKGJ5dGUpIDB4QjMsIChieXRlKSAweDZELCAoYnl0ZSkgMHhBRSwgKGJ5dGUpIDB4QjksIChieXRlKSAweDM1LAorICAgICAgICAgICAgKGJ5dGUpIDB4NDgsIChieXRlKSAweEI4LCAoYnl0ZSkgMHhGQywgKGJ5dGUpIDB4NzUsIChieXRlKSAweDEyLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODYsIChieXRlKSAweDUwLCAoYnl0ZSkgMHhCQywgKGJ5dGUpIDB4RUQsIChieXRlKSAweDUyLAorICAgICAgICAgICAgKGJ5dGUpIDB4QUIsIChieXRlKSAweDU5LCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4RDEsIChieXRlKSAweDZCLAorICAgICAgICAgICAgKGJ5dGUpIDB4M0IsIChieXRlKSAweDk2LCAoYnl0ZSkgMHg3NCwgKGJ5dGUpIDB4NzYsIChieXRlKSAweDhGLAorICAgICAgICAgICAgKGJ5dGUpIDB4QjAsIChieXRlKSAweEJBLCAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4NUMsIChieXRlKSAweEVFLAorICAgICAgICAgICAgKGJ5dGUpIDB4NTcsIChieXRlKSAweEJFLCAoYnl0ZSkgMHgxQiwgKGJ5dGUpIDB4NDksIChieXRlKSAweDY2LAorICAgICAgICAgICAgKGJ5dGUpIDB4OTMsIChieXRlKSAweDQ3LCAoYnl0ZSkgMHhCMiwgKGJ5dGUpIDB4RjQsIChieXRlKSAweDBBLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDgsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4NDMsIChieXRlKSAweERBLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTgsIChieXRlKSAweDlFLCAoYnl0ZSkgMHhCMywgKGJ5dGUpIDB4RTAsIChieXRlKSAweDM1LAorICAgICAgICAgICAgKGJ5dGUpIDB4REIsIChieXRlKSAweEJBLCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4REYsIChieXRlKSAweDUzLAorICAgICAgICAgICAgKGJ5dGUpIDB4NkMsIChieXRlKSAweDlCLCAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4MTEsIChieXRlKSAweEQwLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTIsIChieXRlKSAweDRDLCAoYnl0ZSkgMHgxRCwgKGJ5dGUpIDB4QTEsIChieXRlKSAweDFELAorICAgICAgICAgICAgKGJ5dGUpIDB4NTgsIChieXRlKSAweDQyLCAoYnl0ZSkgMHgxRSwgKGJ5dGUpIDB4MUYsIChieXRlKSAweDM0LAorICAgICAgICAgICAgKGJ5dGUpIDB4QkQsIChieXRlKSAweDRGLCAoYnl0ZSkgMHhDMSwgKGJ5dGUpIDB4MTUsIChieXRlKSAweDFDLAorICAgICAgICAgICAgKGJ5dGUpIDB4QzQsIChieXRlKSAweDE5LCAoYnl0ZSkgMHhDNCwgKGJ5dGUpIDB4NjcsIChieXRlKSAweDA0LAorICAgICAgICAgICAgKGJ5dGUpIDB4QUMsIChieXRlKSAweDczLCAoYnl0ZSkgMHhGOSwgKGJ5dGUpIDB4QUIsIChieXRlKSAweDM4LAorICAgICAgICAgICAgKGJ5dGUpIDB4MjMsIChieXRlKSAweEVDLCAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4QkQsIChieXRlKSAweDg3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MTksIChieXRlKSAweENCLCAoYnl0ZSkgMHhFRSwgKGJ5dGUpIDB4ODgsIChieXRlKSAweEI5LAorICAgICAgICAgICAgKGJ5dGUpIDB4QzcsIChieXRlKSAweDA0LCAoYnl0ZSkgMHhGQiwgKGJ5dGUpIDB4ODMsIChieXRlKSAweDJGLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTQsIChieXRlKSAweEIxLCAoYnl0ZSkgMHgxQiwgKGJ5dGUpIDB4OTMsIChieXRlKSAweEQwLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODgsIChieXRlKSAweERFLCAoYnl0ZSkgMHg0NywgKGJ5dGUpIDB4RTYsIChieXRlKSAweDhGLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzcsIChieXRlKSAweDk2LCAoYnl0ZSkgMHg1NSwgKGJ5dGUpIDB4NTYsIChieXRlKSAweEU0LAorICAgICAgICAgICAgKGJ5dGUpIDB4NEIsIChieXRlKSAweERCLCAoYnl0ZSkgMHg2RSwgKGJ5dGUpIDB4MjMsIChieXRlKSAweDlELAorICAgICAgICAgICAgKGJ5dGUpIDB4RTMsIChieXRlKSAweDhGLCAoYnl0ZSkgMHg5OSwgKGJ5dGUpIDB4MjksIChieXRlKSAweDAxLAorICAgICAgICAgICAgKGJ5dGUpIDB4QkQsIChieXRlKSAweDJDLCAoYnl0ZSkgMHg3NSwgKGJ5dGUpIDB4QTAsIChieXRlKSAweDlFLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTEsIChieXRlKSAweDZFLCAoYnl0ZSkgMHgxNCwgKGJ5dGUpIDB4OTUsIChieXRlKSAweEVDLAorICAgICAgICAgICAgKGJ5dGUpIDB4QjIsIChieXRlKSAweDgxLCAoYnl0ZSkgMHg0RCwgKGJ5dGUpIDB4MDUsIChieXRlKSAweDRBLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTEsIChieXRlKSAweDk1LCAoYnl0ZSkgMHhFMywgKGJ5dGUpIDB4ODgsIChieXRlKSAweDQwLAorICAgICAgICAgICAgKGJ5dGUpIDB4QkYsIChieXRlKSAweDJFLCAoYnl0ZSkgMHhERCwgKGJ5dGUpIDB4RkUsIChieXRlKSAweDRCLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjAsIChieXRlKSAweEM2LCAoYnl0ZSkgMHhBQiwgKGJ5dGUpIDB4MjEsIChieXRlKSAweEI4LAorICAgICAgICAgICAgKGJ5dGUpIDB4RjMsIChieXRlKSAweDlELCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDkzLAorICAgICAgICAgICAgKGJ5dGUpIDB4RkUsIChieXRlKSAweDcwLCAoYnl0ZSkgMHg3QSwgKGJ5dGUpIDB4OUQsIChieXRlKSAweEY4LAorICAgICAgICAgICAgKGJ5dGUpIDB4M0UsIChieXRlKSAweERBLCAoYnl0ZSkgMHgwOSwgKGJ5dGUpIDB4NTYsIChieXRlKSAweDMwLAorICAgICAgICAgICAgKGJ5dGUpIDB4RDIsIChieXRlKSAweDZBLCAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4NDIsIChieXRlKSAweEU2LAorICAgICAgICAgICAgKGJ5dGUpIDB4N0EsIChieXRlKSAweDI1LCAoYnl0ZSkgMHhGRCwgKGJ5dGUpIDB4OUUsIChieXRlKSAweDYyLAorICAgICAgICAgICAgKGJ5dGUpIDB4RjEsIChieXRlKSAweDQyLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4NjUsIChieXRlKSAweEJFLAorICAgICAgICAgICAgKGJ5dGUpIDB4OUIsIChieXRlKSAweDlFLCAoYnl0ZSkgMHhGNywgKGJ5dGUpIDB4NkQsIChieXRlKSAweDAyLAorICAgICAgICAgICAgKGJ5dGUpIDB4MEYsIChieXRlKSAweEQ0LCAoYnl0ZSkgMHgyQywgKGJ5dGUpIDB4QTQsIChieXRlKSAweDJBLAorICAgICAgICAgICAgKGJ5dGUpIDB4NDcsIChieXRlKSAweEVBLCAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4MTcsIChieXRlKSAweEQyLAorICAgICAgICAgICAgKGJ5dGUpIDB4RkMsIChieXRlKSAweDczLCAoYnl0ZSkgMHhBNSwgKGJ5dGUpIDB4MkMsIChieXRlKSAweDk1LAorICAgICAgICAgICAgKGJ5dGUpIDB4OEEsIChieXRlKSAweENFLCAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4RDUsIChieXRlKSAweDVDLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODYsIChieXRlKSAweENGLCAoYnl0ZSkgMHhBNSwgKGJ5dGUpIDB4MDMsIChieXRlKSAweENGLAorICAgICAgICAgICAgKGJ5dGUpIDB4MkUsIChieXRlKSAweEZGLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4RkUsIChieXRlKSAweEVELAorICAgICAgICAgICAgKGJ5dGUpIDB4Q0YsIChieXRlKSAweDM0LCAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4QTcsIChieXRlKSAweDM2LAorICAgICAgICAgICAgKGJ5dGUpIDB4MDgsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhBNSwgKGJ5dGUpIDB4MzYsIChieXRlKSAweERGLAorICAgICAgICAgICAgKGJ5dGUpIDB4NTgsIChieXRlKSAweDcxLCAoYnl0ZSkgMHhFMCwgKGJ5dGUpIDB4QUMsIChieXRlKSAweDlBLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDUsIChieXRlKSAweENFLCAoYnl0ZSkgMHg5OSwgKGJ5dGUpIDB4RUUsIChieXRlKSAweDRELAorICAgICAgICAgICAgKGJ5dGUpIDB4N0IsIChieXRlKSAweDk4LCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4MzMsIChieXRlKSAweDM2LAorICAgICAgICAgICAgKGJ5dGUpIDB4NzAsIChieXRlKSAweDk4LCAoYnl0ZSkgMHhGOSwgKGJ5dGUpIDB4RUMsIChieXRlKSAweDdDLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzcsIChieXRlKSAweDU1LCAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4OTksIChieXRlKSAweDdGLAorICAgICAgICAgICAgKGJ5dGUpIDB4NUMsIChieXRlKSAweENBLCAoYnl0ZSkgMHhGNywgKGJ5dGUpIDB4ODQsIChieXRlKSAweDE3LAorICAgICAgICAgICAgKGJ5dGUpIDB4QTgsIChieXRlKSAweDAwLCAoYnl0ZSkgMHg0RCwgKGJ5dGUpIDB4OEIsIChieXRlKSAweDdFLAorICAgICAgICAgICAgKGJ5dGUpIDB4RDMsIChieXRlKSAweDAyLCAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4NjQsIChieXRlKSAweDE2LAorICAgICAgICAgICAgKGJ5dGUpIDB4NTYsIChieXRlKSAweEM1LCAoYnl0ZSkgMHhBNSwgKGJ5dGUpIDB4MjEsIChieXRlKSAweEQ3LAorICAgICAgICAgICAgKGJ5dGUpIDB4NjYsIChieXRlKSAweDI3LCAoYnl0ZSkgMHhCQywgKGJ5dGUpIDB4QjUsIChieXRlKSAweDhDLAorICAgICAgICAgICAgKGJ5dGUpIDB4MzIsIChieXRlKSAweEMwLCAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4NzYsIChieXRlKSAweDI5LAorICAgICAgICAgICAgKGJ5dGUpIDB4OUUsIChieXRlKSAweEI0LCAoYnl0ZSkgMHgyMSwgKGJ5dGUpIDB4N0UsIChieXRlKSAweEVFLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjQsIChieXRlKSAweEI1LCAoYnl0ZSkgMHhDRCwgKGJ5dGUpIDB4MEMsIChieXRlKSAweDVFLAorICAgICAgICAgICAgKGJ5dGUpIDB4MkMsIChieXRlKSAweDg5LCAoYnl0ZSkgMHhDMCwgKGJ5dGUpIDB4NjUsIChieXRlKSAweDEyLAorICAgICAgICAgICAgKGJ5dGUpIDB4RkEsIChieXRlKSAweDU4LCAoYnl0ZSkgMHhFQiwgKGJ5dGUpIDB4MUQsIChieXRlKSAweDU3LAorICAgICAgICAgICAgKGJ5dGUpIDB4RTAsIChieXRlKSAweEM1LCAoYnl0ZSkgMHgxMiwgKGJ5dGUpIDB4M0MsIChieXRlKSAweDQzLAorICAgICAgICAgICAgKGJ5dGUpIDB4QkYsIChieXRlKSAweDZBLCAoYnl0ZSkgMHhGNywgKGJ5dGUpIDB4MzAsIChieXRlKSAweENGLAorICAgICAgICAgICAgKGJ5dGUpIDB4Q0MsIChieXRlKSAweDQyLCAoYnl0ZSkgMHg4RCwgKGJ5dGUpIDB4NUIsIChieXRlKSAweEJBLAorICAgICAgICAgICAgKGJ5dGUpIDB4N0QsIChieXRlKSAweEY5LCAoYnl0ZSkgMHg1NiwgKGJ5dGUpIDB4NDEsIChieXRlKSAweEY5LAorICAgICAgICAgICAgKGJ5dGUpIDB4QjIsIChieXRlKSAweDY2LCAoYnl0ZSkgMHg2RCwgKGJ5dGUpIDB4OUIsIChieXRlKSAweDM4LAorICAgICAgICAgICAgKGJ5dGUpIDB4QjAsIChieXRlKSAweEMzLCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4NEQsIChieXRlKSAweEM3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MzAsIChieXRlKSAweDhELCAoYnl0ZSkgMHg3OCwgKGJ5dGUpIDB4MEUsIChieXRlKSAweDdFLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzksIChieXRlKSAweDFCLCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4REYsIChieXRlKSAweDBELAorICAgICAgICAgICAgKGJ5dGUpIDB4QjksIChieXRlKSAweDY3LCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4OTMsIChieXRlKSAweEZCLAorICAgICAgICAgICAgKGJ5dGUpIDB4MzgsIChieXRlKSAweDJFLCAoYnl0ZSkgMHg5NCwgKGJ5dGUpIDB4OUMsIChieXRlKSAweEFBLAorICAgICAgICAgICAgKGJ5dGUpIDB4RjksIChieXRlKSAweEJGLCAoYnl0ZSkgMHg0NiwgKGJ5dGUpIDB4MjUsIChieXRlKSAweDQ5LAorICAgICAgICAgICAgKGJ5dGUpIDB4RjEsIChieXRlKSAweEJFLCAoYnl0ZSkgMHg4MywgKGJ5dGUpIDB4MDAsIChieXRlKSAweDBFLAorICAgICAgICAgICAgKGJ5dGUpIDB4QkYsIChieXRlKSAweEQzLCAoYnl0ZSkgMHg2RCwgKGJ5dGUpIDB4MDksIChieXRlKSAweEYzLAorICAgICAgICAgICAgKGJ5dGUpIDB4NUYsIChieXRlKSAweDJELCAoYnl0ZSkgMHgyRiwgKGJ5dGUpIDB4NTIsIChieXRlKSAweEVCLAorICAgICAgICAgICAgKGJ5dGUpIDB4QUMsIChieXRlKSAweEFGLCAoYnl0ZSkgMHgxMywgKGJ5dGUpIDB4REMsIChieXRlKSAweDY3LAorICAgICAgICAgICAgKGJ5dGUpIDB4ODUsIChieXRlKSAweDE2LCAoYnl0ZSkgMHg5RSwgKGJ5dGUpIDB4MTIsIChieXRlKSAweEJDLAorICAgICAgICAgICAgKGJ5dGUpIDB4QzcsIChieXRlKSAweEQwLCAoYnl0ZSkgMHhDQiwgKGJ5dGUpIDB4MDYsIChieXRlKSAweDdDLAorICAgICAgICAgICAgKGJ5dGUpIDB4RkIsIChieXRlKSAweDNFLCAoYnl0ZSkgMHhDMCwgKGJ5dGUpIDB4OTgsIChieXRlKSAweEI3LAorICAgICAgICAgICAgKGJ5dGUpIDB4NjUsIChieXRlKSAweDI2LCAoYnl0ZSkgMHg5MywgKGJ5dGUpIDB4MDQsIChieXRlKSAweDZFLAorICAgICAgICAgICAgKGJ5dGUpIDB4OTgsIChieXRlKSAweEQzLCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4OTQsIChieXRlKSAweDk5LAorICAgICAgICAgICAgKGJ5dGUpIDB4NjcsIChieXRlKSAweEYwLCAoYnl0ZSkgMHhDMiwgKGJ5dGUpIDB4OTQsIChieXRlKSAweDI3LAorICAgICAgICAgICAgKGJ5dGUpIDB4QUQsIChieXRlKSAweEEzLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4QTMsIChieXRlKSAweEJBLAorICAgICAgICAgICAgKGJ5dGUpIDB4MEMsIChieXRlKSAweDM4LCAoYnl0ZSkgMHg2NiwgKGJ5dGUpIDB4MDgsIChieXRlKSAweDk4LAorICAgICAgICAgICAgKGJ5dGUpIDB4ODMsIChieXRlKSAweDVBLCAoYnl0ZSkgMHhBMCwgKGJ5dGUpIDB4OTgsIChieXRlKSAweDhELAorICAgICAgICAgICAgKGJ5dGUpIDB4OUUsIChieXRlKSAweDNFLCAoYnl0ZSkgMHgzNCwgKGJ5dGUpIDB4NTMsIChieXRlKSAweDFGLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjcsIChieXRlKSAweEQxLCAoYnl0ZSkgMHhDRSwgKGJ5dGUpIDB4QTgsIChieXRlKSAweEM2LAorICAgICAgICAgICAgKGJ5dGUpIDB4NEEsIChieXRlKSAweEQ1LCAoYnl0ZSkgMHhBNCwgKGJ5dGUpIDB4NjYsIChieXRlKSAweEEwLAorICAgICAgICAgICAgKGJ5dGUpIDB4QjMsIChieXRlKSAweDUwLCAoYnl0ZSkgMHhGNywgKGJ5dGUpIDB4RTAsIChieXRlKSAweEY5LAorICAgICAgICAgICAgKGJ5dGUpIDB4RUUsIChieXRlKSAweDMyLCAoYnl0ZSkgMHg5NiwgKGJ5dGUpIDB4QjAsIChieXRlKSAweDM2LAorICAgICAgICAgICAgKGJ5dGUpIDB4OEIsIChieXRlKSAweEZFLCAoYnl0ZSkgMHhERSwgKGJ5dGUpIDB4NzIsIChieXRlKSAweEMyLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDIsIChieXRlKSAweEQyLCAoYnl0ZSkgMHg5NiwgKGJ5dGUpIDB4MjQsIChieXRlKSAweDNGLAorICAgICAgICAgICAgKGJ5dGUpIDB4QjUsIChieXRlKSAweDA5LCAoYnl0ZSkgMHhGNCwgKGJ5dGUpIDB4RTAsIChieXRlKSAweDQxLAorICAgICAgICAgICAgKGJ5dGUpIDB4QzEsIChieXRlKSAweDk0LCAoYnl0ZSkgMHhFOSwgKGJ5dGUpIDB4OTYsIChieXRlKSAweEY0LAorICAgICAgICAgICAgKGJ5dGUpIDB4NzQsIChieXRlKSAweEM5LCAoYnl0ZSkgMHg3NywgKGJ5dGUpIDB4QTAsIChieXRlKSAweDczLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTUsIChieXRlKSAweDM2LCAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4QTcsIChieXRlKSAweEJBLAorICAgICAgICAgICAgKGJ5dGUpIDB4RTksIChieXRlKSAweDQ0LCAoYnl0ZSkgMHg4QSwgKGJ5dGUpIDB4RjMsIChieXRlKSAweDQ2LAorICAgICAgICAgICAgKGJ5dGUpIDB4RTYsIChieXRlKSAweDQwLCAoYnl0ZSkgMHhGQiwgKGJ5dGUpIDB4NkEsIChieXRlKSAweEEyLAorICAgICAgICAgICAgKGJ5dGUpIDB4REIsIChieXRlKSAweDY2LCAoYnl0ZSkgMHhFMCwgKGJ5dGUpIDB4RjIsIChieXRlKSAweEY4LAorICAgICAgICAgICAgKGJ5dGUpIDB4MzEsIChieXRlKSAweDlDLCAoYnl0ZSkgMHhCRCwgKGJ5dGUpIDB4QTAsIChieXRlKSAweDFBLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTcsIChieXRlKSAweEY3LCAoYnl0ZSkgMHg1RiwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDA5LAorICAgICAgICAgICAgKGJ5dGUpIDB4QjAsIChieXRlKSAweDRFLCAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4OEYsIChieXRlKSAweDYzLAorICAgICAgICAgICAgKGJ5dGUpIDB4OTYsIChieXRlKSAweDlCLCAoYnl0ZSkgMHhFQiwgKGJ5dGUpIDB4N0QsIChieXRlKSAweDU0LAorICAgICAgICAgICAgKGJ5dGUpIDB4NUEsIChieXRlKSAweDYxLCAoYnl0ZSkgMHg3RCwgKGJ5dGUpIDB4RUQsIChieXRlKSAweDBELAorICAgICAgICAgICAgKGJ5dGUpIDB4MjIsIChieXRlKSAweDE0LCAoYnl0ZSkgMHg4QywgKGJ5dGUpIDB4QjYsIChieXRlKSAweEU0LAorICAgICAgICAgICAgKGJ5dGUpIDB4RUMsIChieXRlKSAweDc5LCAoYnl0ZSkgMHhCNCwgKGJ5dGUpIDB4QzUsIChieXRlKSAweDBGLAorICAgICAgICAgICAgKGJ5dGUpIDB4NEEsIChieXRlKSAweEQxLCAoYnl0ZSkgMHhFNywgKGJ5dGUpIDB4NjcsIChieXRlKSAweEI2LAorICAgICAgICAgICAgKGJ5dGUpIDB4QzcsIChieXRlKSAweERBLCAoYnl0ZSkgMHhDOSwgKGJ5dGUpIDB4RDEsIChieXRlKSAweDA0LAorICAgICAgICAgICAgKGJ5dGUpIDB4QzUsIChieXRlKSAweDRGLCAoYnl0ZSkgMHg3QiwgKGJ5dGUpIDB4NjcsIChieXRlKSAweDA1LAorICAgICAgICAgICAgKGJ5dGUpIDB4NTAsIChieXRlKSAweEZGLCAoYnl0ZSkgMHhBQSwgKGJ5dGUpIDB4RkQsIChieXRlKSAweDQ0LAorICAgICAgICAgICAgKGJ5dGUpIDB4QzgsIChieXRlKSAweDU0LCAoYnl0ZSkgMHg3NSwgKGJ5dGUpIDB4MzMsIChieXRlKSAweDExLAorICAgICAgICAgICAgKGJ5dGUpIDB4MzEsIChieXRlKSAweEIxLCAoYnl0ZSkgMHhFOSwgKGJ5dGUpIDB4NUYsIChieXRlKSAweDY0LAorICAgICAgICAgICAgKGJ5dGUpIDB4ODEsIChieXRlKSAweEM3LCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4QzEsIChieXRlKSAweDA1LAorICAgICAgICAgICAgKGJ5dGUpIDB4QzgsIChieXRlKSAweDNGLCAoYnl0ZSkgMHg4RSwgKGJ5dGUpIDB4ODYsIChieXRlKSAweDg2LAorICAgICAgICAgICAgKGJ5dGUpIDB4NUIsIChieXRlKSAweEI4LCAoYnl0ZSkgMHgwOCwgKGJ5dGUpIDB4QkIsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4OTQsIChieXRlKSAweDgzLCAoYnl0ZSkgMHhFOCwgKGJ5dGUpIDB4NTQsIChieXRlKSAweDc1LAorICAgICAgICAgICAgKGJ5dGUpIDB4QUEsIChieXRlKSAweDRCLCAoYnl0ZSkgMHg2QiwgKGJ5dGUpIDB4OUUsIChieXRlKSAweDc3LAorICAgICAgICAgICAgKGJ5dGUpIDB4MzcsIChieXRlKSAweDM5LCAoYnl0ZSkgMHgxOSwgKGJ5dGUpIDB4MEYsIChieXRlKSAweDQzLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODcsIChieXRlKSAweEI0LCAoYnl0ZSkgMHhGOCwgKGJ5dGUpIDB4NzYsIChieXRlKSAweEVCLAorICAgICAgICAgICAgKGJ5dGUpIDB4MkQsIChieXRlKSAweDJCLCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4NzksIChieXRlKSAweDIyLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODAsIChieXRlKSAweDIwLCAoYnl0ZSkgMHhDOCwgKGJ5dGUpIDB4MDksIChieXRlKSAweDQ5LAorICAgICAgICAgICAgKGJ5dGUpIDB4QjEsIChieXRlKSAweEVDLCAoYnl0ZSkgMHg0RCwgKGJ5dGUpIDB4RjksIChieXRlKSAweDE0LAorICAgICAgICAgICAgKGJ5dGUpIDB4NTgsIChieXRlKSAweDhDLCAoYnl0ZSkgMHg4QywgKGJ5dGUpIDB4REQsIChieXRlKSAweDQyLAorICAgICAgICAgICAgKGJ5dGUpIDB4REIsIChieXRlKSAweEU5LCAoYnl0ZSkgMHhBOSwgKGJ5dGUpIDB4MDMsIChieXRlKSAweDJFLAorICAgICAgICAgICAgKGJ5dGUpIDB4QkEsIChieXRlKSAweDcwLCAoYnl0ZSkgMHg5MSwgKGJ5dGUpIDB4MzAsIChieXRlKSAweEM3LAorICAgICAgICAgICAgKGJ5dGUpIDB4QjcsIChieXRlKSAweDE1LCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4N0MsIChieXRlKSAweEQyLAorICAgICAgICAgICAgKGJ5dGUpIDB4RTksIChieXRlKSAweDEzLCAoYnl0ZSkgMHg2NCwgKGJ5dGUpIDB4RDksIChieXRlKSAweDYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4NDUsIChieXRlKSAweDBGLCAoYnl0ZSkgMHhEMSwgKGJ5dGUpIDB4QjksIChieXRlKSAweDc5LAorICAgICAgICAgICAgKGJ5dGUpIDB4QTQsIChieXRlKSAweEE1LCAoYnl0ZSkgMHg0NiwgKGJ5dGUpIDB4NTYsIChieXRlKSAweDFGLAorICAgICAgICAgICAgKGJ5dGUpIDB4OTQsIChieXRlKSAweEY3LCAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweEIwLAorICAgICAgICAgICAgKGJ5dGUpIDB4RTQsIChieXRlKSAweDgyLCAoYnl0ZSkgMHg5QywgKGJ5dGUpIDB4QzAsIChieXRlKSAweDVCLAorICAgICAgICAgICAgKGJ5dGUpIDB4QzMsIChieXRlKSAweDRELCAoYnl0ZSkgMHhENSwgKGJ5dGUpIDB4RTgsIChieXRlKSAweDhCLAorICAgICAgICAgICAgKGJ5dGUpIDB4QzUsIChieXRlKSAweDlFLCAoYnl0ZSkgMHg3MywgKGJ5dGUpIDB4RUIsIChieXRlKSAweEU4LAorICAgICAgICAgICAgKGJ5dGUpIDB4MkMsIChieXRlKSAweDFDLCAoYnl0ZSkgMHhFQiwgKGJ5dGUpIDB4MzQsIChieXRlKSAweDM3LAorICAgICAgICAgICAgKGJ5dGUpIDB4QUQsIChieXRlKSAweEI5LCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4Q0UsIChieXRlKSAweDQ2LAorICAgICAgICAgICAgKGJ5dGUpIDB4QzUsIChieXRlKSAweDE2LCAoYnl0ZSkgMHg4NywgKGJ5dGUpIDB4MjQsIChieXRlKSAweDAyLAorICAgICAgICAgICAgKGJ5dGUpIDB4MEIsIChieXRlKSAweEVDLCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4ODYsIChieXRlKSAweDc4LAorICAgICAgICAgICAgKGJ5dGUpIDB4MTQsIChieXRlKSAweEVDLCAoYnl0ZSkgMHhFOCwgKGJ5dGUpIDB4MzAsIChieXRlKSAweEMwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MUIsIChieXRlKSAweDZBLCAoYnl0ZSkgMHhBRSwgKGJ5dGUpIDB4MEQsIChieXRlKSAweEFBLAorICAgICAgICAgICAgKGJ5dGUpIDB4RkIsIChieXRlKSAweDAzLCAoYnl0ZSkgMHgyMSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweEUxLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODAsIChieXRlKSAweDUwLCAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4ODAsIChieXRlKSAweEVCLAorICAgICAgICAgICAgKGJ5dGUpIDB4QzAsIChieXRlKSAweEMzLCAoYnl0ZSkgMHhBNywgKGJ5dGUpIDB4RUQsIChieXRlKSAweDJFLAorICAgICAgICAgICAgKGJ5dGUpIDB4ODMsIChieXRlKSAweDBELCAoYnl0ZSkgMHgwRSwgKGJ5dGUpIDB4ODgsIChieXRlKSAweDA0LAorICAgICAgICAgICAgKGJ5dGUpIDB4RTAsIChieXRlKSAweDc3LCAoYnl0ZSkgMHgzMSwgKGJ5dGUpIDB4N0EsIChieXRlKSAweEMzLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjAsIChieXRlKSAweEIxLCAoYnl0ZSkgMHg4RCwgKGJ5dGUpIDB4N0EsIChieXRlKSAweDAxLAorICAgICAgICAgICAgKGJ5dGUpIDB4NTEsIChieXRlKSAweEY5LCAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4QjUsIChieXRlKSAweDRFLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTMsIChieXRlKSAweDJELCAoYnl0ZSkgMHhENCwgKGJ5dGUpIDB4REUsIChieXRlKSAweDNGLAorICAgICAgICAgICAgKGJ5dGUpIDB4MkEsIChieXRlKSAweDY3LCAoYnl0ZSkgMHhFQSwgKGJ5dGUpIDB4MDUsIChieXRlKSAweDUyLAorICAgICAgICAgICAgKGJ5dGUpIDB4MTQsIChieXRlKSAweDk5LCAoYnl0ZSkgMHhCQSwgKGJ5dGUpIDB4OUEsIChieXRlKSAweDgxLAorICAgICAgICAgICAgKGJ5dGUpIDB4NjIsIChieXRlKSAweDFGLCAoYnl0ZSkgMHhDOCwgKGJ5dGUpIDB4REEsIChieXRlKSAweDk1LAorICAgICAgICAgICAgKGJ5dGUpIDB4OTIsIChieXRlKSAweEYyLCAoYnl0ZSkgMHhFQSwgKGJ5dGUpIDB4ODIsIChieXRlKSAweEJELAorICAgICAgICAgICAgKGJ5dGUpIDB4MEMsIChieXRlKSAweEM3LCAoYnl0ZSkgMHg3NCwgKGJ5dGUpIDB4NkYsIChieXRlKSAweEUzLAorICAgICAgICAgICAgKGJ5dGUpIDB4RUEsIChieXRlKSAweDA2LCAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4N0MsIChieXRlKSAweERELAorICAgICAgICAgICAgKGJ5dGUpIDB4MzgsIChieXRlKSAweDA1LCAoYnl0ZSkgMHhGRCwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDc2LAorICAgICAgICAgICAgKGJ5dGUpIDB4OTcsIChieXRlKSAweEM3LCAoYnl0ZSkgMHgwRSwgKGJ5dGUpIDB4MEIsIChieXRlKSAweDg5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MjksIChieXRlKSAweEEzLCAoYnl0ZSkgMHgxMSwgKGJ5dGUpIDB4M0UsIChieXRlKSAweDc1LAorICAgICAgICAgICAgKGJ5dGUpIDB4MjYsIChieXRlKSAweDA4LCAoYnl0ZSkgMHhBNSwgKGJ5dGUpIDB4MEUsIChieXRlKSAweDVDLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjMsIChieXRlKSAweDA2LCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4N0IsIChieXRlKSAweDYxLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDRGLCAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4NzEsIChieXRlKSAweEUzLAorICAgICAgICAgICAgKGJ5dGUpIDB4QUEsIChieXRlKSAweEZELCAoYnl0ZSkgMHg2QSwgKGJ5dGUpIDB4MjEsIChieXRlKSAweDEwLAorICAgICAgICAgICAgKGJ5dGUpIDB4RkUsIChieXRlKSAweDQwLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4NEMsIChieXRlKSAweDYwLAorICAgICAgICAgICAgKGJ5dGUpIDB4QjYsIChieXRlKSAweDM5LCAoYnl0ZSkgMHhGQywgKGJ5dGUpIDB4NTAsIChieXRlKSAweEQyLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDMsIChieXRlKSAweDA3LCAoYnl0ZSkgMHhCQywgKGJ5dGUpIDB4M0YsIChieXRlKSAweEY5LAorICAgICAgICAgICAgKGJ5dGUpIDB4RjksIChieXRlKSAweDQwLCAoYnl0ZSkgMHg5NiwgKGJ5dGUpIDB4MkYsIChieXRlKSAweDJGLAorICAgICAgICAgICAgKGJ5dGUpIDB4NUMsIChieXRlKSAweDIzLCAoYnl0ZSkgMHhDRiwgKGJ5dGUpIDB4ODgsIChieXRlKSAweDUyLAorICAgICAgICAgICAgKGJ5dGUpIDB4NEMsIChieXRlKSAweEI0LCAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4M0IsIChieXRlKSAweEEyLAorICAgICAgICAgICAgKGJ5dGUpIDB4RTMsIChieXRlKSAweDJFLCAoYnl0ZSkgMHhEMSwgKGJ5dGUpIDB4ODAsIChieXRlKSAweDUzLAorICAgICAgICAgICAgKGJ5dGUpIDB4NEEsIChieXRlKSAweEIzLCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4NDYsIChieXRlKSAweEZFLAorICAgICAgICAgICAgKGJ5dGUpIDB4NjksIChieXRlKSAweDNCLCAoYnl0ZSkgMHgzRiwgKGJ5dGUpIDB4MjcsIChieXRlKSAweEFELAorICAgICAgICAgICAgKGJ5dGUpIDB4MkUsIChieXRlKSAweDY0LCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweEJGLAorICAgICAgICAgICAgKGJ5dGUpIDB4NDEsIChieXRlKSAweDZDLCAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4MkYsIChieXRlKSAweEYwLAorICAgICAgICAgICAgKGJ5dGUpIDB4QUEsIChieXRlKSAweDZELCAoYnl0ZSkgMHhGQywgKGJ5dGUpIDB4MUUsIChieXRlKSAweENFLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDQsIChieXRlKSAweDgxLCAoYnl0ZSkgMHhBMywgKGJ5dGUpIDB4MTYsIChieXRlKSAweEQ4LAorICAgICAgICAgICAgKGJ5dGUpIDB4NDMsIChieXRlKSAweENBLCAoYnl0ZSkgMHg3QiwgKGJ5dGUpIDB4NjMsIChieXRlKSAweDgwLAorICAgICAgICAgICAgKGJ5dGUpIDB4QzksIChieXRlKSAweDIwLCAoYnl0ZSkgMHgxQywgKGJ5dGUpIDB4OUYsIChieXRlKSAweDA5LAorICAgICAgICAgICAgKGJ5dGUpIDB4MEMsIChieXRlKSAweDhDLCAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4QjMsIChieXRlKSAweDhELAorICAgICAgICAgICAgKGJ5dGUpIDB4MTAsIChieXRlKSAweDBCLCAoYnl0ZSkgMHg5MSwgKGJ5dGUpIDB4MEMsIChieXRlKSAweDQ1LAorICAgICAgICAgICAgKGJ5dGUpIDB4QTksIChieXRlKSAweENCLCAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4QUIsIChieXRlKSAweEZELAorICAgICAgICAgICAgKGJ5dGUpIDB4MDUsIChieXRlKSAweDJELCAoYnl0ZSkgMHhDQywgKGJ5dGUpIDB4OUUsIChieXRlKSAweEFDLAorICAgICAgICAgICAgKGJ5dGUpIDB4QzYsIChieXRlKSAweDVCLCAoYnl0ZSkgMHg5MCwgKGJ5dGUpIDB4NkQsIChieXRlKSAweERELAorICAgICAgICAgICAgKGJ5dGUpIDB4MkQsIChieXRlKSAweERFLCAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4OTksIChieXRlKSAweEUwLAorICAgICAgICAgICAgKGJ5dGUpIDB4RTIsIChieXRlKSAweDc3LCAoYnl0ZSkgMHgyMSwgKGJ5dGUpIDB4NTEsIChieXRlKSAweDk3LAorICAgICAgICAgICAgKGJ5dGUpIDB4NTcsIChieXRlKSAweDRGLCAoYnl0ZSkgMHhBQiwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDNDLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjksIChieXRlKSAweDMwLCAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4OEUsIChieXRlKSAweEU5LAorICAgICAgICAgICAgKGJ5dGUpIDB4RUUsIChieXRlKSAweDNCLCAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4RUUsIChieXRlKSAweEJFLAorICAgICAgICAgICAgKGJ5dGUpIDB4MkMsIChieXRlKSAweEUzLCAoYnl0ZSkgMHg5QiwgKGJ5dGUpIDB4NEEsIChieXRlKSAweDVDLAorICAgICAgICAgICAgKGJ5dGUpIDB4NzMsIChieXRlKSAweDEzLCAoYnl0ZSkgMHhEQiwgKGJ5dGUpIDB4RUMsIChieXRlKSAweDA0LAorICAgICAgICAgICAgKGJ5dGUpIDB4MTMsIChieXRlKSAweDdGLCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4RUUsIChieXRlKSAweDM0LAorICAgICAgICAgICAgKGJ5dGUpIDB4MjQsIChieXRlKSAweDM2LCAoYnl0ZSkgMHhDMiwgKGJ5dGUpIDB4MzIsIChieXRlKSAweEU2LAorICAgICAgICAgICAgKGJ5dGUpIDB4QTEsIChieXRlKSAweEZCLCAoYnl0ZSkgMHhGNSwgKGJ5dGUpIDB4OTUsIChieXRlKSAweENGLAorICAgICAgICAgICAgKGJ5dGUpIDB4RTcsIChieXRlKSAweEJELCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4NzksIChieXRlKSAweDQ4LAorICAgICAgICAgICAgKGJ5dGUpIDB4M0MsIChieXRlKSAweDY0LCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4NzksIChieXRlKSAweDdBLAorICAgICAgICAgICAgKGJ5dGUpIDB4N0MsIChieXRlKSAweDhCLCAoYnl0ZSkgMHgyNSwgKGJ5dGUpIDB4RTgsIChieXRlKSAweEZGLAorICAgICAgICAgICAgKGJ5dGUpIDB4MUMsIChieXRlKSAweEQ4LCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4NjksIChieXRlKSAweDk1LAorICAgICAgICAgICAgKGJ5dGUpIDB4NkUsIChieXRlKSAweENFLCAoYnl0ZSkgMHg1RSwgKGJ5dGUpIDB4QUQsIChieXRlKSAweEZGLAorICAgICAgICAgICAgKGJ5dGUpIDB4OEMsIChieXRlKSAweDI1LCAoYnl0ZSkgMHg5NCwgKGJ5dGUpIDB4MzUsIChieXRlKSAweDRCLAorICAgICAgICAgICAgKGJ5dGUpIDB4RDgsIChieXRlKSAweDJELCAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4ODgsIChieXRlKSAweDY1LAorICAgICAgICAgICAgKGJ5dGUpIDB4OEIsIChieXRlKSAweEY5LCAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4QTEsIChieXRlKSAweDk5LAorICAgICAgICAgICAgKGJ5dGUpIDB4RTAsIChieXRlKSAweERDLCAoYnl0ZSkgMHhCOSwgKGJ5dGUpIDB4NzgsIChieXRlKSAweDZDLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjcsIChieXRlKSAweDFDLCAoYnl0ZSkgMHg0OSwgKGJ5dGUpIDB4NUMsIChieXRlKSAweDg4LAorICAgICAgICAgICAgKGJ5dGUpIDB4NEYsIChieXRlKSAweDM0LCAoYnl0ZSkgMHhCRCwgKGJ5dGUpIDB4RTgsIChieXRlKSAweEU1LAorICAgICAgICAgICAgKGJ5dGUpIDB4NjMsIChieXRlKSAweEUzLCAoYnl0ZSkgMHg0RSwgKGJ5dGUpIDB4NDUsIChieXRlKSAweDE0LAorICAgICAgICAgICAgKGJ5dGUpIDB4QjQsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4NzUsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4M0QsIChieXRlKSAweDMwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MjEsIChieXRlKSAweDMwLCAoYnl0ZSkgMHgwOSwgKGJ5dGUpIDB4MDYsIChieXRlKSAweDA1LAorICAgICAgICAgICAgKGJ5dGUpIDB4MkIsIChieXRlKSAweDBFLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MDIsIChieXRlKSAweDFBLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDUsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MTQsIChieXRlKSAweDZBLAorICAgICAgICAgICAgKGJ5dGUpIDB4MzUsIChieXRlKSAweDkyLCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4QzYsIChieXRlKSAweDU0LAorICAgICAgICAgICAgKGJ5dGUpIDB4ODMsIChieXRlKSAweDFDLCAoYnl0ZSkgMHg2NCwgKGJ5dGUpIDB4QzUsIChieXRlKSAweDY0LAorICAgICAgICAgICAgKGJ5dGUpIDB4OEEsIChieXRlKSAweDJFLCAoYnl0ZSkgMHhEMCwgKGJ5dGUpIDB4NjMsIChieXRlKSAweEMyLAorICAgICAgICAgICAgKGJ5dGUpIDB4QTAsIChieXRlKSAweDczLCAoYnl0ZSkgMHhBQywgKGJ5dGUpIDB4NUIsIChieXRlKSAweDA0LAorICAgICAgICAgICAgKGJ5dGUpIDB4MTQsIChieXRlKSAweEI0LCAoYnl0ZSkgMHg4NywgKGJ5dGUpIDB4ODcsIChieXRlKSAweEY0LAorICAgICAgICAgICAgKGJ5dGUpIDB4MjgsIChieXRlKSAweDlGLCAoYnl0ZSkgMHhGMCwgKGJ5dGUpIDB4QTksIChieXRlKSAweDgyLAorICAgICAgICAgICAgKGJ5dGUpIDB4QkEsIChieXRlKSAweDFELCAoYnl0ZSkgMHgxMiwgKGJ5dGUpIDB4RTAsIChieXRlKSAweEVDLAorICAgICAgICAgICAgKGJ5dGUpIDB4Q0UsIChieXRlKSAweDBCLCAoYnl0ZSkgMHg0RiwgKGJ5dGUpIDB4N0EsIChieXRlKSAweDFGLAorICAgICAgICAgICAgKGJ5dGUpIDB4NjksIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDQsIChieXRlKSAweDAwLAorICAgICAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAwfTsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L01lc3NhZ2VEaWdlc3RUZXN0TUQyLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9NZXNzYWdlRGlnZXN0VGVzdE1EMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY4MTFiYzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9NZXNzYWdlRGlnZXN0VGVzdE1EMi5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLnRhcmdldHMuc2VjdXJpdHk7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5BbmRyb2lkT25seTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyaXR5OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIE1lc3NhZ2VEaWdlc3RUZXN0TUQyIGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgQEFuZHJvaWRPbmx5KCJBbmRyb2lkIGRvZXNuJ3QgaW5jbHVkZSBNRDIgbWVzc2FnZSBkaWdlc3QgYWxnb3JpdGhtIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWVzc2FnZURpZ2VzdDEoKSB0aHJvd3MgRXhjZXB0aW9ueworICAgICAgICB0cnkgeworICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBkaWdlc3QgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJNRDIiKTsKKyAgICAgICAgICAgIGZhaWwoIk1EMiBNZXNzYWdlRGlnZXN0IGFsZ29yaXRobSBtdXN0IG5vdCBiZSBzdXBwb3J0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBkaWdlc3QgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKAorICAgICAgICAgICAgICAgICAgICAiMS4yLjg0MC4xMTM1NDkuMi4yIik7CisgICAgICAgICAgICBmYWlsKCJNRDIgTWVzc2FnZURpZ2VzdCBhbGdvcml0aG0gbXVzdCBub3QgYmUgc3VwcG9ydGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisgICAgfQorCisgICAgQEFuZHJvaWRPbmx5KCJBbmRyb2lkIGFsbG93cyB1c2FnZSBvZiBNRDIgaW4gdGhpcmQgcGFydHkgcHJvdmlkZXJzIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWVzc2FnZURpZ2VzdDIoKSB0aHJvd3MgRXhjZXB0aW9ueworCisgICAgICAgIFByb3ZpZGVyIHByb3ZpZGVyICA9IG5ldyBNeVByb3ZpZGVyKCk7CisgICAgICAgIFNlY3VyaXR5LmFkZFByb3ZpZGVyKHByb3ZpZGVyKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTWVzc2FnZURpZ2VzdCBkaWdlc3QgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJNRDIiKTsKKworICAgICAgICAgICAgZGlnZXN0ID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZSgiMS4yLjg0MC4xMTM1NDkuMi4yIik7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcihwcm92aWRlci5nZXROYW1lKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIGNsYXNzIE15UHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlciB7CisgICAgICAgIHB1YmxpYyBNeVByb3ZpZGVyKCkgeworICAgICAgICAgICAgc3VwZXIoIk1lc3NhZ2VEaWdlc3RNRDJUZXN0IiwgMS4wMCwgIlRlc3RQcm92aWRlciIpOworICAgICAgICAgICAgcHV0KCJNZXNzYWdlRGlnZXN0Lk1EMiIsCisgICAgICAgICAgICAgICAgICAgICJ0ZXN0cy50YXJnZXRzLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3RUZXN0TUQyJE1EMiIpOworICAgICAgICAgICAgcHV0KCJBbGcuQWxpYXMuTWVzc2FnZURpZ2VzdC4xLjIuODQwLjExMzU0OS4yLjIiLCAiTUQyIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE1EMiBleHRlbmRzIE1lc3NhZ2VEaWdlc3QgeworCisgICAgICAgIHB1YmxpYyBNRDIoKSB7CisgICAgICAgICAgICBzdXBlcigiTUQyIik7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgTUQyKFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgICAgIHN1cGVyKGFsZ29yaXRobSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVEaWdlc3QoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVSZXNldCgpIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZSBpbnB1dCkgeworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShieXRlW10gaW5wdXQsIGludCBvZmZzZXQsIGludCBsZW4pIHsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L01lc3NhZ2VEaWdlc3RUZXN0TUQ1LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9NZXNzYWdlRGlnZXN0VGVzdE1ENS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE5OTdiMWUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9NZXNzYWdlRGlnZXN0VGVzdE1ENS5qYXZhCkBAIC0wLDAgKzEsMzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLnRhcmdldHMuc2VjdXJpdHk7CisKK2ltcG9ydCB0ZXN0cy5zZWN1cml0eS5NZXNzYWdlRGlnZXN0VGVzdDsKKworcHVibGljIGNsYXNzIE1lc3NhZ2VEaWdlc3RUZXN0TUQ1IGV4dGVuZHMgTWVzc2FnZURpZ2VzdFRlc3QgeworCisgICAgcHVibGljIE1lc3NhZ2VEaWdlc3RUZXN0TUQ1KCkgeworICAgICAgICBzdXBlcigiTUQ1Iik7CisKKyAgICAgICAgc3VwZXIuc291cmNlMSA9ICJhYmMiOworICAgICAgICBzdXBlci5zb3VyY2UyID0gImFiY2RlZmdoYmNkZWZnaGljZGVmZ2hpamRlZmdoaWprZWZnaGlqa2xmZ2hpamtsbWdoaWprbG1uaGlqa2xtbm9pamtsbW5vcGprbG1ub3Bxa2xtbm9wcXJsbW5vcHFyc21ub3BxcnN0bm9wcXJzdHUiOworICAgICAgICBzdXBlci5leHBlY3RlZDEgPSBzaW5nbGVibG9jazsKKyAgICAgICAgc3VwZXIuZXhwZWN0ZWQyID0gbXVsdGlibG9jazsKKyAgICAgICAgc3VwZXIuZXhwZWN0ZWQzID0gbG9uZ21lc3NhZ2U7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHNpbmdsZWJsb2NrID0gIjkwMDE1MDk4M2NkMjRmYjBkNjk2M2Y3ZDI4ZTE3ZjcyIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgbXVsdGlibG9jayA9ICIwM2RkODgwN2E5MzE3NWZiMDYyZGZiNTVkYzdkMzU5YyI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGxvbmdtZXNzYWdlID0gIjc3MDdkNmFlNGUwMjdjNzBlZWEyYTkzNWMyMjk2ZjIxIjsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdFRlc3RTSEExLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9NZXNzYWdlRGlnZXN0VGVzdFNIQTEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNzNkYTM3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdFRlc3RTSEExLmphdmEKQEAgLTAsMCArMSwzNyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMudGFyZ2V0cy5zZWN1cml0eTsKKworaW1wb3J0IHRlc3RzLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3RUZXN0OworCitwdWJsaWMgY2xhc3MgTWVzc2FnZURpZ2VzdFRlc3RTSEExIGV4dGVuZHMgTWVzc2FnZURpZ2VzdFRlc3QgeworCisgICAgcHVibGljIE1lc3NhZ2VEaWdlc3RUZXN0U0hBMSgpIHsKKyAgICAgICAgc3VwZXIoIlNIQS0xIik7CisKKyAgICAgICAgc3VwZXIuc291cmNlMSA9ICJhYmMiOworICAgICAgICBzdXBlci5zb3VyY2UyID0gImFiY2RiY2RlY2RlZmRlZmdlZmdoZmdoaWdoaWpoaWpraWprbGprbG1rbG1ubG1ub21ub3Bub3BxIjsKKyAgICAgICAgc3VwZXIuZXhwZWN0ZWQxID0gc2luZ2xlYmxvY2s7CisgICAgICAgIHN1cGVyLmV4cGVjdGVkMiA9IG11bHRpYmxvY2s7CisgICAgICAgIHN1cGVyLmV4cGVjdGVkMyA9IGxvbmdtZXNzYWdlOworICAgIH0KKworICAgIC8vIHJlc3VsdHMgZnJvbSBmaXBzMTgwLTIKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgc2luZ2xlYmxvY2sgPSAiYTk5OTNlMzY0NzA2ODE2YWJhM2UyNTcxNzg1MGMyNmM5Y2QwZDg5ZCI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIG11bHRpYmxvY2sgPSAiODQ5ODNlNDQxYzNiZDI2ZWJhYWU0YWExZjk1MTI5ZTVlNTQ2NzBmMSI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGxvbmdtZXNzYWdlID0gIjM0YWE5NzNjZDRjNGRhYTRmNjFlZWIyYmRiYWQyNzMxNjUzNDAxNmYiOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9NZXNzYWdlRGlnZXN0VGVzdFNIQTI1Ni5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdFRlc3RTSEEyNTYuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ODEzMzk2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdFRlc3RTSEEyNTYuamF2YQpAQCAtMCwwICsxLDM3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSB0ZXN0cy50YXJnZXRzLnNlY3VyaXR5OworCitpbXBvcnQgdGVzdHMuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdFRlc3Q7CisKK3B1YmxpYyBjbGFzcyBNZXNzYWdlRGlnZXN0VGVzdFNIQTI1NiBleHRlbmRzIE1lc3NhZ2VEaWdlc3RUZXN0IHsKKworICAgIHB1YmxpYyBNZXNzYWdlRGlnZXN0VGVzdFNIQTI1NigpIHsKKyAgICAgICAgc3VwZXIoIlNIQS0yNTYiKTsKKworICAgICAgICBzdXBlci5zb3VyY2UxID0gImFiYyI7CisgICAgICAgIHN1cGVyLnNvdXJjZTIgPSAiYWJjZGJjZGVjZGVmZGVmZ2VmZ2hmZ2hpZ2hpamhpamtpamtsamtsbWtsbW5sbW5vbW5vcG5vcHEiOworICAgICAgICBzdXBlci5leHBlY3RlZDEgPSBzaW5nbGVibG9jazsKKyAgICAgICAgc3VwZXIuZXhwZWN0ZWQyID0gbXVsdGlibG9jazsKKyAgICAgICAgc3VwZXIuZXhwZWN0ZWQzID0gbG9uZ21lc3NhZ2U7CisgICAgfQorCisgICAgLy8gcmVzdWx0cyBmcm9tIGZpcHMxODAtMgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBzaW5nbGVibG9jayA9ICJiYTc4MTZiZjhmMDFjZmVhNDE0MTQwZGU1ZGFlMjIyM2IwMDM2MWEzOTYxNzdhOWNiNDEwZmY2MWYyMDAxNWFkIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgbXVsdGlibG9jayA9ICIyNDhkNmE2MWQyMDYzOGI4ZTVjMDI2OTMwYzNlNjAzOWEzM2NlNDU5NjRmZjIxNjdmNmVjZWRkNDE5ZGIwNmMxIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgbG9uZ21lc3NhZ2UgPSAiY2RjNzZlNWM5OTE0ZmI5MjgxYTFjN2UyODRkNzNlNjdmMTgwOWE0OGE0OTcyMDBlMDQ2ZDM5Y2NjNzExMmNkMCI7CisKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L01lc3NhZ2VEaWdlc3RUZXN0U0hBMzg0LmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9NZXNzYWdlRGlnZXN0VGVzdFNIQTM4NC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI5Zjk0NzcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9NZXNzYWdlRGlnZXN0VGVzdFNIQTM4NC5qYXZhCkBAIC0wLDAgKzEsMzcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLnRhcmdldHMuc2VjdXJpdHk7CisKK2ltcG9ydCB0ZXN0cy5zZWN1cml0eS5NZXNzYWdlRGlnZXN0VGVzdDsKKworcHVibGljIGNsYXNzIE1lc3NhZ2VEaWdlc3RUZXN0U0hBMzg0IGV4dGVuZHMgTWVzc2FnZURpZ2VzdFRlc3QgeworCisgICAgcHVibGljIE1lc3NhZ2VEaWdlc3RUZXN0U0hBMzg0KCkgeworICAgICAgICBzdXBlcigiU0hBLTM4NCIpOworCisgICAgICAgIHN1cGVyLnNvdXJjZTEgPSAiYWJjIjsKKyAgICAgICAgc3VwZXIuc291cmNlMiA9ICJhYmNkZWZnaGJjZGVmZ2hpY2RlZmdoaWpkZWZnaGlqa2VmZ2hpamtsZmdoaWprbG1naGlqa2xtbmhpamtsbW5vaWprbG1ub3Bqa2xtbm9wcWtsbW5vcHFybG1ub3BxcnNtbm9wcXJzdG5vcHFyc3R1IjsKKyAgICAgICAgc3VwZXIuZXhwZWN0ZWQxID0gc2luZ2xlYmxvY2s7CisgICAgICAgIHN1cGVyLmV4cGVjdGVkMiA9IG11bHRpYmxvY2s7CisgICAgICAgIHN1cGVyLmV4cGVjdGVkMyA9IGxvbmdtZXNzYWdlOworICAgIH0KKworICAgIC8vIHJlc3VsdHMgZnJvbSBmaXBzMTgwLTIKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgc2luZ2xlYmxvY2sgPSAiY2IwMDc1M2Y0NWEzNWU4YmI1YTAzZDY5OWFjNjUwMDcyNzJjMzJhYjBlZGVkMTYzMWE4YjYwNWE0M2ZmNWJlZDgwODYwNzJiYTFlN2NjMjM1OGJhZWNhMTM0YzgyNWE3IjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgbXVsdGlibG9jayA9ICIwOTMzMGMzM2Y3MTE0N2U4M2QxOTJmYzc4MmNkMWI0NzUzMTExYjE3M2IzYjA1ZDIyZmEwODA4NmUzYjBmNzEyZmNjN2M3MWE1NTdlMmRiOTY2YzNlOWZhOTE3NDYwMzkiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBsb25nbWVzc2FnZSA9ICI5ZDBlMTgwOTcxNjQ3NGNiMDg2ZTgzNGUzMTBhNGExY2VkMTQ5ZTljMDBmMjQ4NTI3OTcyY2VjNTcwNGMyYTViMDdiOGIzZGMzOGVjYzRlYmFlOTdkZGQ4N2YzZDg5ODUiOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9NZXNzYWdlRGlnZXN0VGVzdFNIQTUxMi5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdFRlc3RTSEE1MTIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMGYyYzZiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdFRlc3RTSEE1MTIuamF2YQpAQCAtMCwwICsxLDM3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSB0ZXN0cy50YXJnZXRzLnNlY3VyaXR5OworCitpbXBvcnQgdGVzdHMuc2VjdXJpdHkuTWVzc2FnZURpZ2VzdFRlc3Q7CisKK3B1YmxpYyBjbGFzcyBNZXNzYWdlRGlnZXN0VGVzdFNIQTUxMiBleHRlbmRzIE1lc3NhZ2VEaWdlc3RUZXN0IHsKKworICAgIHB1YmxpYyBNZXNzYWdlRGlnZXN0VGVzdFNIQTUxMigpIHsKKyAgICAgICAgc3VwZXIoIlNIQS01MTIiKTsKKworICAgICAgICBzdXBlci5zb3VyY2UxID0gImFiYyI7CisgICAgICAgIHN1cGVyLnNvdXJjZTIgPSAiYWJjZGVmZ2hiY2RlZmdoaWNkZWZnaGlqZGVmZ2hpamtlZmdoaWprbGZnaGlqa2xtZ2hpamtsbW5oaWprbG1ub2lqa2xtbm9wamtsbW5vcHFrbG1ub3Bxcmxtbm9wcXJzbW5vcHFyc3Rub3BxcnN0dSI7CisgICAgICAgIHN1cGVyLmV4cGVjdGVkMSA9IHNpbmdsZWJsb2NrOworICAgICAgICBzdXBlci5leHBlY3RlZDIgPSBtdWx0aWJsb2NrOworICAgICAgICBzdXBlci5leHBlY3RlZDMgPSBsb25nbWVzc2FnZTsKKyAgICB9CisKKyAgICAvLyByZXN1bHRzIGZyb20gZmlwczE4MC0yCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHNpbmdsZWJsb2NrID0gImRkYWYzNWExOTM2MTdhYmFjYzQxNzM0OWFlMjA0MTMxMTJlNmZhNGU4OWE5N2VhMjBhOWVlZWU2NGI1NWQzOWEyMTkyOTkyYTI3NGZjMWE4MzZiYTNjMjNhM2ZlZWJiZDQ1NGQ0NDIzNjQzY2U4MGUyYTlhYzk0ZmE1NGNhNDlmIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgbXVsdGlibG9jayA9ICI4ZTk1OWI3NWRhZTMxM2RhOGNmNGY3MjgxNGZjMTQzZjhmNzc3OWM2ZWI5ZjdmYTE3Mjk5YWVhZGI2ODg5MDE4NTAxZDI4OWU0OTAwZjdlNDMzMWI5OWRlYzRiNTQzM2FjN2QzMjllZWI2ZGQyNjU0NWU5NmU1NWI4NzRiZTkwOSI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGxvbmdtZXNzYWdlID0gImU3MTg0ODNkMGNlNzY5NjQ0ZTJlNDJjN2JjMTViNDYzOGUxZjk4YjEzYjIwNDQyODU2MzJhODAzYWZhOTczZWJkZTBmZjI0NDg3N2VhNjBhNGNiMDQzMmNlNTc3YzMxYmViMDA5YzVjMmM0OWFhMmU0ZWFkYjIxN2FkOGNjMDliIjsKKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvU2VjdXJlUmFuZG9tVGVzdFNIQTFQUk5HLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9TZWN1cmVSYW5kb21UZXN0U0hBMVBSTkcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYWYwNGZjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvU2VjdXJlUmFuZG9tVGVzdFNIQTFQUk5HLmphdmEKQEAgLTAsMCArMSwyNiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMudGFyZ2V0cy5zZWN1cml0eTsKKworaW1wb3J0IHRlc3RzLnNlY3VyaXR5LlNlY3VyZVJhbmRvbVRlc3Q7CisKK3B1YmxpYyBjbGFzcyBTZWN1cmVSYW5kb21UZXN0U0hBMVBSTkcgZXh0ZW5kcyBTZWN1cmVSYW5kb21UZXN0IHsKKworICAgIHB1YmxpYyBTZWN1cmVSYW5kb21UZXN0U0hBMVBSTkcoKSB7CisgICAgICAgIHN1cGVyKCJTSEExUFJORyIpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvU2lnbmF0dXJlVGVzdE1EMndpdGhSU0EuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L1NpZ25hdHVyZVRlc3RNRDJ3aXRoUlNBLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzkxMjZlZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L1NpZ25hdHVyZVRlc3RNRDJ3aXRoUlNBLmphdmEKQEAgLTAsMCArMSwxNzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLnRhcmdldHMuc2VjdXJpdHk7CisKK2ltcG9ydCBkYWx2aWsuYW5ub3RhdGlvbi5BbmRyb2lkT25seTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmVFeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgU2lnbmF0dXJlVGVzdE1EMndpdGhSU0EgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBAQW5kcm9pZE9ubHkoIkFuZHJvaWQgZG9lc24ndCBpbmNsdWRlIE1EMndpdGhSU0Egc2lnbmF0dXJlIGFsZ29yaXRobSIpCisgICAgcHVibGljIHZvaWQgdGVzdFNpZ25hdHVyZSgpIHsKKworICAgICAgICAvLyBNRDIgbXVzdCBub3QgYmUgcGFydCBvZiBhbmRyb2lkLgorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTaWduYXR1cmUgc2lnbmF0dXJlID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCJNRDJ3aXRoUlNBIik7CisgICAgICAgICAgICBmYWlsKCJNRDJ3aXRoUlNBIGZvciBzaWduYXR1cmUgdmVyaWZpY2F0aW9uIG11c3Qgbm90IGJlIHN1cHBvcnRlZCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTaWduYXR1cmUgc2lnbmF0dXJlID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCJNRDJXaXRoUlNBIik7CisgICAgICAgICAgICBmYWlsKCJNRDJ3aXRoUlNBIGZvciBzaWduYXR1cmUgdmVyaWZpY2F0aW9uIG11c3Qgbm90IGJlIHN1cHBvcnRlZCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTaWduYXR1cmUgc2lnbmF0dXJlID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCJNRDJXSVRIUlNBIik7CisgICAgICAgICAgICBmYWlsKCJNRDJ3aXRoUlNBIGZvciBzaWduYXR1cmUgdmVyaWZpY2F0aW9uIG11c3Qgbm90IGJlIHN1cHBvcnRlZCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTaWduYXR1cmUgc2lnbmF0dXJlID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCJNRDJ3aXRoUlNBRW5jcnlwdGlvbiIpOworICAgICAgICAgICAgZmFpbCgiTUQyd2l0aFJTQSBmb3Igc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiBtdXN0IG5vdCBiZSBzdXBwb3J0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgU2lnbmF0dXJlIHNpZ25hdHVyZSA9IFNpZ25hdHVyZS5nZXRJbnN0YW5jZSgiTUQyV2l0aFJTQUVuY3J5cHRpb24iKTsKKyAgICAgICAgICAgIGZhaWwoIk1EMndpdGhSU0EgZm9yIHNpZ25hdHVyZSB2ZXJpZmljYXRpb24gbXVzdCBub3QgYmUgc3VwcG9ydGVkIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBleHBlY3RlZAorICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNpZ25hdHVyZSBzaWduYXR1cmUgPSBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIk1EMldJVEhSU0FFTkNSWVBUSU9OIik7CisgICAgICAgICAgICBmYWlsKCJNRDJ3aXRoUlNBIGZvciBzaWduYXR1cmUgdmVyaWZpY2F0aW9uIG11c3Qgbm90IGJlIHN1cHBvcnRlZCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTaWduYXR1cmUgc2lnbmF0dXJlID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCJNRDIvUlNBIik7CisgICAgICAgICAgICBmYWlsKCJNRDJ3aXRoUlNBIGZvciBzaWduYXR1cmUgdmVyaWZpY2F0aW9uIG11c3Qgbm90IGJlIHN1cHBvcnRlZCIpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTaWduYXR1cmUgc2lnbmF0dXJlID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCIxLjIuODQwLjExMzU0OS4xLjEuMiIpOworICAgICAgICAgICAgZmFpbCgiTUQyd2l0aFJTQSBmb3Igc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiBtdXN0IG5vdCBiZSBzdXBwb3J0ZWQiKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGV4cGVjdGVkCisgICAgICAgIH0KKyAgICB9CisKKyAgICBAQW5kcm9pZE9ubHkoIkFuZHJvaWQgYWxsb3dzIHVzYWdlIG9mIE1EMndpdGhSU0EgaW4gdGhpcmQgcGFydHkgcHJvdmlkZXJzIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2lnbmF0dXJlMigpIHRocm93cyBFeGNlcHRpb257CisKKyAgICAgICAgUHJvdmlkZXIgcHJvdmlkZXIgPSBuZXcgTXlQcm92aWRlcigpOworICAgICAgICBTZWN1cml0eS5hZGRQcm92aWRlcihwcm92aWRlcik7CisKKyAgICAgICAgU2lnbmF0dXJlIHNpZ25hdHVyZSA9IFNpZ25hdHVyZS5nZXRJbnN0YW5jZSgiTUQyd2l0aFJTQSIpOworICAgICAgICBzaWduYXR1cmUgPSBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIk1EMldpdGhSU0EiKTsKKyAgICAgICAgc2lnbmF0dXJlID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCJNRDJXSVRIUlNBIik7CisgICAgICAgIHNpZ25hdHVyZSA9IFNpZ25hdHVyZS5nZXRJbnN0YW5jZSgiTUQyd2l0aFJTQUVuY3J5cHRpb24iKTsKKyAgICAgICAgc2lnbmF0dXJlID0gU2lnbmF0dXJlLmdldEluc3RhbmNlKCJNRDJXaXRoUlNBRW5jcnlwdGlvbiIpOworICAgICAgICBzaWduYXR1cmUgPSBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIk1EMldJVEhSU0FFTkNSWVBUSU9OIik7CisgICAgICAgIHNpZ25hdHVyZSA9IFNpZ25hdHVyZS5nZXRJbnN0YW5jZSgiTUQyL1JTQSIpOworICAgICAgICBzaWduYXR1cmUgPSBTaWduYXR1cmUuZ2V0SW5zdGFuY2UoIjEuMi44NDAuMTEzNTQ5LjEuMS4yIik7CisKKyAgICAgICAgU2VjdXJpdHkucmVtb3ZlUHJvdmlkZXIocHJvdmlkZXIuZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgY2xhc3MgTXlQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyIHsKKyAgICAgICAgcHVibGljIE15UHJvdmlkZXIoKQorICAgICAgICB7CisgICAgICAgICAgICBzdXBlcigiU2lnbmF0dXJlTUQyV2l0aFJTQVRlc3QiLCAxLjAwLCAiVGVzdFByb3ZpZGVyIik7CisgICAgICAgICAgICBwdXQoIlNpZ25hdHVyZS5NRDJXaXRoUlNBRW5jcnlwdGlvbiIsCisgICAgICAgICAgICAgICAgICAgICJ0ZXN0cy50YXJnZXRzLnNlY3VyaXR5LlNpZ25hdHVyZVRlc3RNRDJ3aXRoUlNBJE1EMndpdGhSU0EiKTsKKyAgICAgICAgICAgIHB1dCgiQWxnLkFsaWFzLlNpZ25hdHVyZS5NRDJXSVRIUlNBRU5DUllQVElPTiIsCisgICAgICAgICAgICAgICAgICAgICJNRDJXaXRoUlNBRW5jcnlwdGlvbiIpOworICAgICAgICAgICAgcHV0KCJBbGcuQWxpYXMuU2lnbmF0dXJlLk1EMldpdGhSU0EiLCAiTUQyV2l0aFJTQUVuY3J5cHRpb24iKTsKKyAgICAgICAgICAgIHB1dCgiQWxnLkFsaWFzLlNpZ25hdHVyZS5NRDJ3aXRoUlNBIiwgIk1EMldpdGhSU0FFbmNyeXB0aW9uIik7CisgICAgICAgICAgICBwdXQoIkFsZy5BbGlhcy5TaWduYXR1cmUuTUQyL1JTQSIsICJNRDJXaXRoUlNBRW5jcnlwdGlvbiIpOworICAgICAgICAgICAgcHV0KCJBbGcuQWxpYXMuU2lnbmF0dXJlLjEuMi44NDAuMTEzNTQ5LjEuMS4yIiwKKyAgICAgICAgICAgICAgICAgICAgIk1EMldpdGhSU0FFbmNyeXB0aW9uIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE1EMndpdGhSU0EgZXh0ZW5kcyBTaWduYXR1cmUgeworCisgICAgICAgIHB1YmxpYyBNRDJ3aXRoUlNBKCkgeworICAgICAgICAgICAgc3VwZXIoIk1EMldpdGhSU0EiKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBNRDJ3aXRoUlNBKFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgICAgIHN1cGVyKGFsZ29yaXRobSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIE9iamVjdCBlbmdpbmVHZXRQYXJhbWV0ZXIoU3RyaW5nIHBhcmFtKQorICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXRTaWduKFByaXZhdGVLZXkgcHJpdmF0ZUtleSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdFZlcmlmeShQdWJsaWNLZXkgcHVibGljS2V5KQorICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVTZXRQYXJhbWV0ZXIoU3RyaW5nIHBhcmFtLCBPYmplY3QgdmFsdWUpCisgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBieXRlW10gZW5naW5lU2lnbigpIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGUgYikgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKQorICAgICAgICAgICAgICAgIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBib29sZWFuIGVuZ2luZVZlcmlmeShieXRlW10gc2lnQnl0ZXMpCisgICAgICAgICAgICAgICAgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoQnVpbGRlclRlc3RQS0lYLmphdmEgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoQnVpbGRlclRlc3RQS0lYLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmM2NzI2MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhCdWlsZGVyVGVzdFBLSVguamF2YQpAQCAtMCwwICsxLDEwNiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMudGFyZ2V0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhQYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRTdG9yZVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5QS0lYQnVpbGRlclBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0U2VsZWN0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsOworaW1wb3J0IHRlc3RzLnNlY3VyaXR5LkNlcnRQYXRoQnVpbGRlclRlc3Q7CisKK3B1YmxpYyBjbGFzcyBDZXJ0UGF0aEJ1aWxkZXJUZXN0UEtJWCBleHRlbmRzIENlcnRQYXRoQnVpbGRlclRlc3QgeworCisgICAgcHVibGljIENlcnRQYXRoQnVpbGRlclRlc3RQS0lYKCkgeworICAgICAgICBzdXBlcigiUEtJWCIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDZXJ0UGF0aFBhcmFtZXRlcnMgZ2V0Q2VydFBhdGhQYXJhbWV0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEtleVN0b3JlIGtleVN0b3JlID0gS2V5U3RvcmUuZ2V0SW5zdGFuY2UoS2V5U3RvcmUuZ2V0RGVmYXVsdFR5cGUoKSk7CisKKyAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCBudWxsKTsKKworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2VydGlmaWNhdGVGYWN0b3J5ID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKAorICAgICAgICAgICAgICAgICJYNTA5Iik7CisKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIHNlbGZTaWduZWRjZXJ0aWZpY2F0ZSA9CisgICAgICAgICAgICAgICAgKFg1MDlDZXJ0aWZpY2F0ZSkgY2VydGlmaWNhdGVGYWN0b3J5LmdlbmVyYXRlQ2VydGlmaWNhdGUoCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc2VsZlNpZ25lZENlcnQuZ2V0Qnl0ZXMoKSkpOworCisgICAgICAgIGtleVN0b3JlLnNldENlcnRpZmljYXRlRW50cnkoInNlbGZTaWduZWRDZXJ0Iiwgc2VsZlNpZ25lZGNlcnRpZmljYXRlKTsKKworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHRhcmdldENvbnN0cmFpbnRzID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKyAgICAgICAgdGFyZ2V0Q29uc3RyYWludHMuc2V0Q2VydGlmaWNhdGUoc2VsZlNpZ25lZGNlcnRpZmljYXRlKTsKKworICAgICAgICBMaXN0PENlcnRpZmljYXRlPiBjZXJ0TGlzdCA9IG5ldyBBcnJheUxpc3Q8Q2VydGlmaWNhdGU+KCk7CisgICAgICAgIGNlcnRMaXN0LmFkZChzZWxmU2lnbmVkY2VydGlmaWNhdGUpOworICAgICAgICBDZXJ0U3RvcmVQYXJhbWV0ZXJzIHN0b3JlUGFyYW1zID0gbmV3IENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzKAorICAgICAgICAgICAgICAgIGNlcnRMaXN0KTsKKworCisgICAgICAgIENlcnRTdG9yZSBjZXJ0U3RvcmUgPSBDZXJ0U3RvcmUuZ2V0SW5zdGFuY2UoIkNvbGxlY3Rpb24iLCBzdG9yZVBhcmFtcyk7CisKKworICAgICAgICBQS0lYQnVpbGRlclBhcmFtZXRlcnMgcGFyYW1ldGVycyA9IG5ldyBQS0lYQnVpbGRlclBhcmFtZXRlcnMoCisgICAgICAgICAgICAgICAga2V5U3RvcmUsIHRhcmdldENvbnN0cmFpbnRzKTsKKyAgICAgICAgcGFyYW1ldGVycy5hZGRDZXJ0U3RvcmUoY2VydFN0b3JlKTsKKyAgICAgICAgcGFyYW1ldGVycy5zZXRSZXZvY2F0aW9uRW5hYmxlZChmYWxzZSk7CisgICAgICAgIHJldHVybiBwYXJhbWV0ZXJzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlQ2VydFBhdGgoQ2VydFBhdGggcGF0aCkgeworICAgICAgICBMaXN0PD8gZXh0ZW5kcyBDZXJ0aWZpY2F0ZT4gY2VydGlmaWNhdGVzID0gcGF0aC5nZXRDZXJ0aWZpY2F0ZXMoKTsKKyAgICAgICAgQ2VydGlmaWNhdGUgY2VydGlmaWNhdGUgPSBjZXJ0aWZpY2F0ZXMuZ2V0KDApOworCisgICAgICAgIGFzc2VydEVxdWFscygidW5leHBlY3RlZCBjZXJ0aWZpY2F0ZSB0eXBlIiwgIlguNTA5IiwgY2VydGlmaWNhdGUKKyAgICAgICAgICAgICAgICAuZ2V0VHlwZSgpKTsKKworICAgICAgICBYNTA5Q2VydGlmaWNhdGUgeDUwOUNlcnRpZmljYXRlID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2VydGlmaWNhdGU7CisgICAgICAgIFg1MDBQcmluY2lwYWwgc3ViamVjdFg1MDBQcmluY2lwYWwgPSB4NTA5Q2VydGlmaWNhdGUKKyAgICAgICAgICAgICAgICAuZ2V0U3ViamVjdFg1MDBQcmluY2lwYWwoKTsKKworICAgICAgICBYNTAwUHJpbmNpcGFsIGV4cGVjdGVkUHJpbmNpcGFsID0gbmV3IFg1MDBQcmluY2lwYWwoIkNOPUFuZHJvaWQgQ1RTLCAiCisgICAgICAgICAgICAgICAgKyAiT1U9QW5kcm9pZCwgTz1BbmRyb2lkLCBMPUFuZHJvaWQsIFNUPUFuZHJvaWQsIEM9QU4iKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoInVuZXhwZWN0ZWQgcHJpbmNpcGFsIiwgZXhwZWN0ZWRQcmluY2lwYWwsCisgICAgICAgICAgICAgICAgc3ViamVjdFg1MDBQcmluY2lwYWwpOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIHNlbGZTaWduZWRDZXJ0ID0gIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICsgIk1JSUNTRENDQWJFQ0JFazJadnN3RFFZSktvWklodmNOQVFFRUJRQXdhekVMTUFrR0ExVUVCaE1DUVU0eEVEQU9CZ05WQkFnVEIwRnVcbiIKKyAgICArICJaSEp2YVdReEVEQU9CZ05WQkFjVEIwRnVaSEp2YVdReEVEQU9CZ05WQkFvVEIwRnVaSEp2YVdReEVEQU9CZ05WQkFzVEIwRnVaSEp2XG4iCisgICAgKyAiYVdReEZEQVNCZ05WQkFNVEMwRnVaSEp2YVdRZ1ExUlRNQjRYRFRBNE1USXdNekV4TURFeE5Wb1hEVE0yTURReU1ERXhNREV4TlZvd1xuIgorICAgICsgImF6RUxNQWtHQTFVRUJoTUNRVTR4RURBT0JnTlZCQWdUQjBGdVpISnZhV1F4RURBT0JnTlZCQWNUQjBGdVpISnZhV1F4RURBT0JnTlZcbiIKKyAgICArICJCQW9UQjBGdVpISnZhV1F4RURBT0JnTlZCQXNUQjBGdVpISnZhV1F4RkRBU0JnTlZCQU1UQzBGdVpISnZhV1FnUTFSVE1JR2ZNQTBHXG4iCisgICAgKyAiQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCaVFLQmdRQ0FNZCtOMUJ1MmVpSTRrdWtPTHZGbHBUU0VIVEdwbE4ydnZ3NzZUN2pTWmlueFxuIgorICAgICsgIldjcnRMZTZxSDF1UGZmYlZOVzQvQlJuNk95d2JjeW5hekVkcUVVYTA5aFd0SFltVXNYcFJQeUdVQlNjTm55Rjc1MVNHQTJKSVFVZmdcbiIKKyAgICArICIzZ2kzZ1QzaDMyWjY0QUlIbm41Z3NHREprZVdPSHg2L3VWT1Y3aXFyN2N3UGRMcDAzUUlEQVFBQk1BMEdDU3FHU0liM0RRRUJCQVVBXG4iCisgICAgKyAiQTRHQkFHRzQ2VWRzaDZVN2JTa0pzeVBQbVNDQ0VrR3IxNEw4RjQzMVV1YVdiTHZRVkR0eVB2OHZ0ZEppbHlVVFZubFdNNkpOR1YvcVxuIgorICAgICsgImJnSHVMYm9oa1ZYbjlsNjhHdGdRN1FEZXhISkU1aEVERy9TN2NZTmk5R2hyQ2Z6QWpFZWQxM1ZNbnRaSFowWFE0RTdqQk9taGNNQVlcbiIKKyAgICArICJEQzlCQngxc1ZLb2ppMTdSUDRSOENUZjFcbiIgKyAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLSI7Cit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoVmFsaWRhdG9yVGVzdFBLSVguamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhWYWxpZGF0b3JUZXN0UEtJWC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFmNDAzN2YKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoVmFsaWRhdG9yVGVzdFBLSVguamF2YQpAQCAtMCwwICsxLDExOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMudGFyZ2V0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhCdWlsZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aEJ1aWxkZXJSZXN1bHQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFN0b3JlUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LlBLSVhCdWlsZGVyUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5QS0lYUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgdGVzdHMuc2VjdXJpdHkuQ2VydFBhdGhWYWxpZGF0b3JUZXN0OworCitwdWJsaWMgY2xhc3MgQ2VydFBhdGhWYWxpZGF0b3JUZXN0UEtJWCBleHRlbmRzIENlcnRQYXRoVmFsaWRhdG9yVGVzdCB7CisKKyAgICBwcml2YXRlIENlcnRQYXRoIGNlcnRQYXRoOworICAgIHByaXZhdGUgUEtJWFBhcmFtZXRlcnMgcGFyYW1zOworCisgICAgcHVibGljIENlcnRQYXRoVmFsaWRhdG9yVGVzdFBLSVgoKSB7CisgICAgICAgIHN1cGVyKCJQS0lYIik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIENlcnRQYXRoIGdldENlcnRQYXRoKCkgeworICAgICAgICByZXR1cm4gY2VydFBhdGg7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgS2V5U3RvcmUga2V5U3RvcmUgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCBudWxsKTsKKworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2VydGlmaWNhdGVGYWN0b3J5ID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKAorICAgICAgICAgICAgICAgICJYNTA5Iik7CisKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIHNlbGZTaWduZWRjZXJ0aWZpY2F0ZSA9CisgICAgICAgICAgICAgICAgKFg1MDlDZXJ0aWZpY2F0ZSkgY2VydGlmaWNhdGVGYWN0b3J5LmdlbmVyYXRlQ2VydGlmaWNhdGUoCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc2VsZlNpZ25lZENlcnQuZ2V0Qnl0ZXMoKSkpOworCisgICAgICAgIGtleVN0b3JlLnNldENlcnRpZmljYXRlRW50cnkoInNlbGZTaWduZWRDZXJ0Iiwgc2VsZlNpZ25lZGNlcnRpZmljYXRlKTsKKworICAgICAgICBYNTA5Q2VydFNlbGVjdG9yIHRhcmdldENvbnN0cmFpbnRzID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKyAgICAgICAgdGFyZ2V0Q29uc3RyYWludHMuc2V0Q2VydGlmaWNhdGUoc2VsZlNpZ25lZGNlcnRpZmljYXRlKTsKKworICAgICAgICBMaXN0PENlcnRpZmljYXRlPiBjZXJ0TGlzdCA9IG5ldyBBcnJheUxpc3Q8Q2VydGlmaWNhdGU+KCk7CisgICAgICAgIGNlcnRMaXN0LmFkZChzZWxmU2lnbmVkY2VydGlmaWNhdGUpOworICAgICAgICBDZXJ0U3RvcmVQYXJhbWV0ZXJzIHN0b3JlUGFyYW1zID0gbmV3IENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzKAorICAgICAgICAgICAgICAgIGNlcnRMaXN0KTsKKworICAgICAgICBDZXJ0U3RvcmUgY2VydFN0b3JlID0gQ2VydFN0b3JlLmdldEluc3RhbmNlKCJDb2xsZWN0aW9uIiwgc3RvcmVQYXJhbXMpOworCisgICAgICAgIFBLSVhCdWlsZGVyUGFyYW1ldGVycyBwYXJhbWV0ZXJzID0gbmV3IFBLSVhCdWlsZGVyUGFyYW1ldGVycyhrZXlTdG9yZSwKKyAgICAgICAgICAgICAgICB0YXJnZXRDb25zdHJhaW50cyk7CisgICAgICAgIHBhcmFtZXRlcnMuYWRkQ2VydFN0b3JlKGNlcnRTdG9yZSk7CisgICAgICAgIHBhcmFtZXRlcnMuc2V0UmV2b2NhdGlvbkVuYWJsZWQoZmFsc2UpOworCisgICAgICAgIENlcnRQYXRoQnVpbGRlciBwYXRoQnVpbGRlciA9IENlcnRQYXRoQnVpbGRlci5nZXRJbnN0YW5jZSgiUEtJWCIpOworCisgICAgICAgIENlcnRQYXRoQnVpbGRlclJlc3VsdCBidWlsZGVyUmVzdWx0ID0gcGF0aEJ1aWxkZXIuYnVpbGQocGFyYW1ldGVycyk7CisKKyAgICAgICAgY2VydFBhdGggPSBidWlsZGVyUmVzdWx0LmdldENlcnRQYXRoKCk7CisKKyAgICAgICAgcGFyYW1zID0gbmV3IFBLSVhQYXJhbWV0ZXJzKGtleVN0b3JlKTsKKyAgICAgICAgcGFyYW1zLnNldFJldm9jYXRpb25FbmFibGVkKGZhbHNlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ2VydFBhdGhQYXJhbWV0ZXJzIGdldFBhcmFtcygpIHsKKyAgICAgICAgcmV0dXJuIHBhcmFtczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZVJlc3VsdChDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCB2YWxpZGF0b3JSZXN1bHQpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgidmFsaWRhdG9yIHJlc3VsdCBpcyBudWxsIiwgdmFsaWRhdG9yUmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgidmFsaWRhdG9yIHJlc3VsdCBpcyBub3QgUEtJWCIsCisgICAgICAgICAgICAgICAgdmFsaWRhdG9yUmVzdWx0IGluc3RhbmNlb2YgUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0KTsKKworICAgIH0KKworCisgICAgcHJpdmF0ZSBTdHJpbmcgc2VsZlNpZ25lZENlcnQgPSAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgKyAiTUlJQ1NEQ0NBYkVDQkVrMlp2c3dEUVlKS29aSWh2Y05BUUVFQlFBd2F6RUxNQWtHQTFVRUJoTUNRVTR4RURBT0JnTlZCQWdUQjBGdVxuIgorICAgICsgIlpISnZhV1F4RURBT0JnTlZCQWNUQjBGdVpISnZhV1F4RURBT0JnTlZCQW9UQjBGdVpISnZhV1F4RURBT0JnTlZCQXNUQjBGdVpISnZcbiIKKyAgICArICJhV1F4RkRBU0JnTlZCQU1UQzBGdVpISnZhV1FnUTFSVE1CNFhEVEE0TVRJd016RXhNREV4TlZvWERUTTJNRFF5TURFeE1ERXhOVm93XG4iCisgICAgKyAiYXpFTE1Ba0dBMVVFQmhNQ1FVNHhFREFPQmdOVkJBZ1RCMEZ1WkhKdmFXUXhFREFPQmdOVkJBY1RCMEZ1WkhKdmFXUXhFREFPQmdOVlxuIgorICAgICsgIkJBb1RCMEZ1WkhKdmFXUXhFREFPQmdOVkJBc1RCMEZ1WkhKdmFXUXhGREFTQmdOVkJBTVRDMEZ1WkhKdmFXUWdRMVJUTUlHZk1BMEdcbiIKKyAgICArICJDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FDQU1kK04xQnUyZWlJNGt1a09MdkZscFRTRUhUR3BsTjJ2dnc3NlQ3alNaaW54XG4iCisgICAgKyAiV2NydExlNnFIMXVQZmZiVk5XNC9CUm42T3l3YmN5bmF6RWRxRVVhMDloV3RIWW1Vc1hwUlB5R1VCU2NObnlGNzUxU0dBMkpJUVVmZ1xuIgorICAgICsgIjNnaTNnVDNoMzJaNjRBSUhubjVnc0dESmtlV09IeDYvdVZPVjdpcXI3Y3dQZExwMDNRSURBUUFCTUEwR0NTcUdTSWIzRFFFQkJBVUFcbiIKKyAgICArICJBNEdCQUdHNDZVZHNoNlU3YlNrSnN5UFBtU0NDRWtHcjE0TDhGNDMxVXVhV2JMdlFWRHR5UHY4dnRkSmlseVVUVm5sV002Sk5HVi9xXG4iCisgICAgKyAiYmdIdUxib2hrVlhuOWw2OEd0Z1E3UURleEhKRTVoRURHL1M3Y1lOaTlHaHJDZnpBakVlZDEzVk1udFpIWjBYUTRFN2pCT21oY01BWVxuIgorICAgICsgIkRDOUJCeDFzVktvamkxN1JQNFI4Q1RmMVxuIiArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tIjsKK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVGYWN0b3J5VGVzdFg1MDkuamF2YSBiL2x1bmkvc3JjL3Rlc3QvamF2YS90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVGYWN0b3J5VGVzdFg1MDkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kY2Y0MDgxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZUZhY3RvcnlUZXN0WDUwOS5qYXZhCkBAIC0wLDAgKzEsNTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIHRlc3RzLnRhcmdldHMuc2VjdXJpdHkuY2VydDsKKworaW1wb3J0IHRlc3RzLnNlY3VyaXR5LkNlcnRpZmljYXRlRmFjdG9yeVRlc3Q7CisKK3B1YmxpYyBjbGFzcyBDZXJ0aWZpY2F0ZUZhY3RvcnlUZXN0WDUwOSBleHRlbmRzIENlcnRpZmljYXRlRmFjdG9yeVRlc3QgeworCisgICAgcHVibGljIENlcnRpZmljYXRlRmFjdG9yeVRlc3RYNTA5KCkgeworICAgICAgICBzdXBlcigiWDUwOSIsIGVuY29kZWRDZXJ0aWZpY2F0ZS5nZXRCeXRlcygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBlbmNvZGVkQ2VydGlmaWNhdGUgPQorICAgICAgICAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICsgIk1JSUQwakNDQXp1Z0F3SUJBZ0lCQWpBTkJna3Foa2lHOXcwQkFRUUZBRENCbWpFTE1Ba0dBMVVFQmhNQ1ZVc3hcbiIKKyAgICAgICAgKyAiRWpBUUJnTlZCQWdUQ1VoaGJYQnphR2x5WlRFVE1CRUdBMVVFQnhNS1YybHVZMmhsYzNSbGNqRVRNQkVHQTFVRVxuIgorICAgICAgICArICJDaE1LU1VKTklGVkxJRXgwWkRFTU1Bb0dBMVVFQ3hNRFNsUkRNUll3RkFZRFZRUURFdzFRWVhWc0lFZ2dRV0ppXG4iCisgICAgICAgICsgImIzUjBNU2N3SlFZSktvWklodmNOQVFrQkZoaFFZWFZzWDBoZlFXSmliM1IwUUhWckxtbGliUzVqYjIwd0hoY05cbiIKKyAgICAgICAgKyAiTURRd05qSXlNakExTURVMVdoY05NRFV3TmpJeU1qQTFNRFUxV2pDQm1ERUxNQWtHQTFVRUJoTUNWVXN4RWpBUVxuIgorICAgICAgICArICJCZ05WQkFnVENVaGhiWEJ6YUdseVpURVRNQkVHQTFVRUJ4TUtWMmx1WTJobGMzUmxjakVUTUJFR0ExVUVDaE1LXG4iCisgICAgICAgICsgIlNVSk5JRlZySUV4MFpERU1NQW9HQTFVRUN4TURTa1ZVTVJRd0VnWURWUVFERXd0UVlYVnNJRUZpWW05MGRERW5cbiIKKyAgICAgICAgKyAiTUNVR0NTcUdTSWIzRFFFSkFSWVlVR0YxYkY5SVgwRmlZbTkwZEVCMWF5NXBZbTB1WTI5dE1JR2ZNQTBHQ1NxR1xuIgorICAgICAgICArICJTSWIzRFFFQkFRVUFBNEdOQURDQmlRS0JnUURpdFpCUTVkMThlY05KcGNudUtUcmFIWXRxc0F1Z29jOTUvTDVRXG4iCisgICAgICAgICsgIjI4czN0MVFBdTI1MDVxUVIxTVphQWtZN3RETnlsMXZQblpveW0rWTA2VXN3VHJab1ZZby9nUE5leVdQTVRzTEFcbiIKKyAgICAgICAgKyAid3pRdms1LzZ5aHRFOWNpSDdCMFNxWXc2dVNpRFRiVVkvelE2cWVkK1RzUWhqbGJuM1BVSFJqbkkyUDhBMDRjZ1xuIgorICAgICAgICArICJMZ1lZR1FJREFRQUJvNElCSmpDQ0FTSXdDUVlEVlIwVEJBSXdBREFzQmdsZ2hrZ0JodmhDQVEwRUh4WWRUM0JsXG4iCisgICAgICAgICsgImJsTlRUQ0JIWlc1bGNtRjBaV1FnUTJWeWRHbG1hV05oZEdVd0hRWURWUjBPQkJZRUZQcGxSUHM2NWhVZnhVQnNcbiIKKyAgICAgICAgKyAiNi9UYXE3bk44aTFVTUlISEJnTlZIU01FZ2I4d2dieUFGSk9NdFBBd2xYZFpMcUU3REtVNnhwTDZGakZ0b1lHZ1xuIgorICAgICAgICArICJwSUdkTUlHYU1Rc3dDUVlEVlFRR0V3SlZTekVTTUJBR0ExVUVDQk1KU0dGdGNITm9hWEpsTVJNd0VRWURWUVFIXG4iCisgICAgICAgICsgIkV3cFhhVzVqYUdWemRHVnlNUk13RVFZRFZRUUtFd3BKUWswZ1ZVc2dUSFJrTVF3d0NnWURWUVFMRXdOS1ZFTXhcbiIKKyAgICAgICAgKyAiRmpBVUJnTlZCQU1URFZCaGRXd2dTQ0JCWW1KdmRIUXhKekFsQmdrcWhraUc5dzBCQ1FFV0dGQmhkV3hmU0Y5QlxuIgorICAgICAgICArICJZbUp2ZEhSQWRXc3VhV0p0TG1OdmJZSUJBREFOQmdrcWhraUc5dzBCQVFRRkFBT0JnUUFuUTIySncySFVyejdjXG4iCisgICAgICAgICsgIlZhT2FwMzFtVGlrdVEvQ1F4cHdQWWlTeVRKNHM5OWVFem4rMnlBazl0SURJSnBxb2F5L2ZqK09MZ1BVUUtJQW9cbiIKKyAgICAgICAgKyAiWHBSVnZtSGxHRTdVcU1LZWJadFNaSlF6czZWb2VlS0ZoZ0htcWc4ZVZDMkFzVGM0WnN3Sm1nNHdDdWk1QUgzYVxuIgorICAgICAgICArICJvcUc3UElNM0x4WnFYWVFsWmlQU1o2a0NwRE9XVmc9PVxuIgorICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iOworCit9CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L2phdmEvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9jZXJ0L0NlcnRpZmljYXRlVGVzdC5qYXZhIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZDA2MjQ5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9qYXZhL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZVRlc3QuamF2YQpAQCAtMCwwICsxLDc0NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMudGFyZ2V0cy5zZWN1cml0eS5jZXJ0OworCitpbXBvcnQgZGFsdmlrLmFubm90YXRpb24uQW5kcm9pZE9ubHk7CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGg7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoVmFsaWRhdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LlBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuUEtJWFBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuU3RhbmRhcmROYW1lczsKKworcHVibGljIGNsYXNzIENlcnRpZmljYXRlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIC8qCisgICAgICogRm9sbG93aW5nIGNlcnRpZmljYXRlIGNoYWluIHdhcyB0YWtlbiBmcm9tIGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbSBhbmQKKyAgICAgKiB1c2VzIE1EMndpdGhSU0EgZm9yIHRoZSByb290IGNlcnRpZmljYXRlLiBUaGlzIGNoYWluIHN0b3BzIHZhbGlkYXRpbmcKKyAgICAgKiBpbiBOb3YgMjAxNi4KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIEEgc2VsZnNpZ25lZCBjZXJ0aWZpY2F0ZSB1c2luZyBNRDJ3aXRoUlNBCisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqIENlcnRpZmljYXRlOgorICAgICAqICAgICBEYXRhOgorICAgICAqICAgICAgICAgVmVyc2lvbjogMSAoMHgwKQorICAgICAqICAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgKiAgICAgICAgICAgICA3MDpiYTplNDoxZDoxMDpkOToyOTozNDpiNjozODpjYTo3YjowMzpjYzpiYTpiZgorICAgICAqICAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogbWQyV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgKiAgICAgICAgIElzc3VlcjogQz1VUywgTz1WZXJpU2lnbiwgSW5jLiwgT1U9Q2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQorICAgICAqICAgICAgICAgVmFsaWRpdHkKKyAgICAgKiAgICAgICAgICAgICBOb3QgQmVmb3JlOiBKYW4gMjkgMDA6MDA6MDAgMTk5NiBHTVQKKyAgICAgKiAgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBBdWcgIDEgMjM6NTk6NTkgMjAyOCBHTVQKKyAgICAgKiAgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89VmVyaVNpZ24sIEluYy4sIE9VPUNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkKKyAgICAgKiAgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAqICAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICogICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgxMDI0IGJpdCkKKyAgICAgKiAgICAgICAgICAgICAgICAgTW9kdWx1cyAoMTAyNCBiaXQpOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgMDA6Yzk6NWM6NTk6OWU6ZjI6MWI6OGE6MDE6MTQ6YjQ6MTA6ZGY6MDQ6NDA6CisgICAgICogICAgICAgICAgICAgICAgICAgICBkYjplMzo1NzphZjo2YTo0NTo0MDo4Zjo4NDowYzowYjpkMTozMzpkOTpkOToKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDExOmNmOmVlOjAyOjU4OjFmOjI1OmY3OjJhOmE4OjQ0OjA1OmFhOmVjOjAzOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgMWY6Nzg6N2Y6OWU6OTM6Yjk6OWE6MDA6YWE6MjM6N2Q6ZDY6YWM6ODU6YTI6CisgICAgICogICAgICAgICAgICAgICAgICAgICA2Mzo0NTpjNzo3MjoyNzpjYzpmNDo0YzpjNjo3NTo3MTpkMjozOTplZjo0ZjoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDQyOmYwOjc1OmRmOjBhOjkwOmM2OjhlOjIwOjZmOjk4OjBmOmY4OmFjOjIzOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgNWY6NzA6Mjk6MzY6YTQ6Yzk6ODY6ZTc6YjE6OWE6MjA6Y2I6NTM6YTU6ODU6CisgICAgICogICAgICAgICAgICAgICAgICAgICBlNzozZDpiZTo3ZDo5YTpmZToyNDo0NTozMzpkYzo3NjoxNTplZDowZjphMjoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDcxOjY0OjRjOjY1OjJlOjgxOjY4OjQ1OmE3CisgICAgICogICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgKiAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogbWQyV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgKiAgICAgICAgIGJiOjRjOjEyOjJiOmNmOjJjOjI2OjAwOjRmOjE0OjEzOmRkOmE2OmZiOmZjOjBhOjExOjg0OgorICAgICAqICAgICAgICAgOGM6ZjM6Mjg6MWM6Njc6OTI6MmY6N2M6YjY6YzU6ZmE6ZGY6ZjA6ZTg6OTU6YmM6MWQ6OGY6CisgICAgICogICAgICAgICA2YzoyYzphODo1MTpjYzo3MzpkODphNDpjMDo1MzpmMDo0ZTpkNjoyNjpjMDo3NjowMTo1NzoKKyAgICAgKiAgICAgICAgIDgxOjkyOjVlOjIxOmYxOmQxOmIxOmZmOmU3OmQwOjIxOjU4OmNkOjY5OjE3OmUzOjQ0OjFjOgorICAgICAqICAgICAgICAgOWM6MTk6NDQ6Mzk6ODk6NWM6ZGM6OWM6MDA6MGY6NTY6OGQ6MDI6OTk6ZWQ6YTI6OTA6NDU6CisgICAgICogICAgICAgICA0YzplNDpiYjoxMDphNDozZDpmMDozMjowMzowZTpmMTpjZTpmODplODpjOTo1MTo4YzplNjoKKyAgICAgKiAgICAgICAgIDYyOjlmOmU2OjlmOmMwOjdkOmI3OjcyOjljOmM5OjM2OjNhOjZiOjlmOjRlOmE4OmZmOjY0OgorICAgICAqICAgICAgICAgMGQ6NjQKKyAgICAgKiA8L3ByZT4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgc2VsZlNpZ25lZENlcnRNRDIgPQorICAgICAgICAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICsgIk1JSUNQRENDQWFVQ0VIQzY1QjBRMlNrMHRqaktld1BNdXI4d0RRWUpLb1pJaHZjTkFRRUNCUUF3WHpFTE1Ba0dcbiIKKyAgICAgICAgKyAiQTFVRUJoTUNWVk14RnpBVkJnTlZCQW9URGxabGNtbFRhV2R1TENCSmJtTXVNVGN3TlFZRFZRUUxFeTVEYkdGelxuIgorICAgICAgICArICJjeUF6SUZCMVlteHBZeUJRY21sdFlYSjVJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1CNFhEVGsyXG4iCisgICAgICAgICsgIk1ERXlPVEF3TURBd01Gb1hEVEk0TURnd01USXpOVGsxT1Zvd1h6RUxNQWtHQTFVRUJoTUNWVk14RnpBVkJnTlZcbiIKKyAgICAgICAgKyAiQkFvVERsWmxjbWxUYVdkdUxDQkpibU11TVRjd05RWURWUVFMRXk1RGJHRnpjeUF6SUZCMVlteHBZeUJRY21sdFxuIgorICAgICAgICArICJZWEo1SUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdOXG4iCisgICAgICAgICsgIkFEQ0JpUUtCZ1FESlhGbWU4aHVLQVJTMEVOOEVRTnZqVjY5cVJVQ1BoQXdMMFRQWjJSSFA3Z0pZSHlYM0txaEVcbiIKKyAgICAgICAgKyAiQmFyc0F4OTRmNTZUdVpvQXFpTjkxcXlGb21ORngzSW56UFJNeG5WeDBqbnZUMEx3ZGQ4S2tNYU9JRytZRC9pc1xuIgorICAgICAgICArICJJMTl3S1Rha3lZYm5zWm9neTFPbGhlYzl2bjJhL2lSRk05eDJGZTBQb25Ga1RHVXVnV2hGcHdJREFRQUJNQTBHXG4iCisgICAgICAgICsgIkNTcUdTSWIzRFFFQkFnVUFBNEdCQUx0TUVpdlBMQ1lBVHhRVDNhYjcvQW9SaEl6ektCeG5raTk4dHNYNjMvRG9cbiIKKyAgICAgICAgKyAibGJ3ZGoyd3NxRkhNYzlpa3dGUHdUdFltd0hZQlY0R1NYaUh4MGJILzU5QWhXTTFwRitORUhKd1pSRG1KWE55Y1xuIgorICAgICAgICArICJBQTlXalFLWjdhS1FSVXprdXhDa1BmQXlBdzd4enZqb3lWR001bUtmNXAvQWZiZHluTWsyT211ZlRxai9aQTFrXG4iCisgICAgICAgICsgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cbiI7CisKKyAgICAvKioKKyAgICAgKiBBIGNlcnRpZmljYXRlIHNpZ25lZCBieSBzZWxmU2lnbmVkQ2VydE1EMgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiBDZXJ0aWZpY2F0ZToKKyAgICAgKiAgICAgRGF0YToKKyAgICAgKiAgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgKiAgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICogICAgICAgICAgICAgNTc6YmY6ZmI6MDM6ZmI6MmM6NDY6ZDQ6ZTE6OWU6Y2U6ZTA6ZDc6NDM6N2Y6MTMKKyAgICAgKiAgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAqICAgICAgICAgSXNzdWVyOiBDPVVTLCBPPVZlcmlTaWduLCBJbmMuLCBPVT1DbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5CisgICAgICogICAgICAgICBWYWxpZGl0eQorICAgICAqICAgICAgICAgICAgIE5vdCBCZWZvcmU6IE5vdiAgOCAwMDowMDowMCAyMDA2IEdNVAorICAgICAqICAgICAgICAgICAgIE5vdCBBZnRlciA6IE5vdiAgNyAyMzo1OTo1OSAyMDIxIEdNVAorICAgICAqICAgICAgICAgU3ViamVjdDogQz1VUywgTz1WZXJpU2lnbiwgSW5jLiwgT1U9VmVyaVNpZ24gVHJ1c3QgTmV0d29yaywgT1U9KGMpIDIwMDYgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seSwgQ049VmVyaVNpZ24gQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc1CisgICAgICogICAgICAgICBTdWJqZWN0IFB1YmxpYyBLZXkgSW5mbzoKKyAgICAgKiAgICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgorICAgICAqICAgICAgICAgICAgIFJTQSBQdWJsaWMgS2V5OiAoMjA0OCBiaXQpCisgICAgICogICAgICAgICAgICAgICAgIE1vZHVsdXMgKDIwNDggYml0KToKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDAwOmFmOjI0OjA4OjA4OjI5OjdhOjM1OjllOjYwOjBjOmFhOmU3OjRiOjNiOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgNGU6ZGM6N2M6YmM6M2M6NDU6MWM6YmI6MmI6ZTA6ZmU6Mjk6MDI6Zjk6NTc6CisgICAgICogICAgICAgICAgICAgICAgICAgICAwODphMzo2NDo4NToxNToyNzpmNTpmMTphZDpjODozMTo4OTo1ZDoyMjplODoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDJhOmFhOmE2OjQyOmIzOjhmOmY4OmI5OjU1OmI3OmIxOmI3OjRiOmIzOmZlOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgOGY6N2U6MDc6NTc6ZWM6ZWY6NDM6ZGI6NjY6NjI6MTU6NjE6Y2Y6NjA6MGQ6CisgICAgICogICAgICAgICAgICAgICAgICAgICBhNDpkODpkZTpmODplMDpjMzo2MjowODozZDo1NDoxMzplYjo0OTpjYTo1OToKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDU0Ojg1OjI2OmU1OjJiOjhmOjFiOjlmOmViOmY1OmExOjkxOmMyOjMzOjQ5OgorICAgICAqICAgICAgICAgICAgICAgICAgICAgZDg6NDM6NjM6NmE6NTI6NGI6ZDI6OGY6ZTg6NzA6NTE6NGQ6ZDE6ODk6Njk6CisgICAgICogICAgICAgICAgICAgICAgICAgICA3YjpjNzo3MDpmNjpiMzpkYzoxMjo3NDpkYjo3Yjo1ZDo0Yjo1NjpkMzo5NjoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGJmOjE1Ojc3OmExOmIwOmY0OmEyOjI1OmYyOmFmOjFjOjkyOjY3OjE4OmU1OgorICAgICAqICAgICAgICAgICAgICAgICAgICAgZjQ6MDY6MDQ6ZWY6OTA6Yjk6ZTQ6MDA6ZTQ6ZGQ6M2E6YjU6MTk6ZmY6MDI6CisgICAgICogICAgICAgICAgICAgICAgICAgICBiYTpmNDozYzplZTplMDo4YjplYjozNzo4YjplYzpmNDpkNzphYzpmMjpmNjoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGYwOjNkOmFmOmRkOjc1OjkxOjMzOjE5OjFkOjFjOjQwOmNiOjc0OjI0OjE5OgorICAgICAqICAgICAgICAgICAgICAgICAgICAgMjE6OTM6ZDk6MTQ6ZmU6YWM6MmE6NTI6Yzc6OGY6ZDU6MDQ6NDk6ZTQ6OGQ6CisgICAgICogICAgICAgICAgICAgICAgICAgICA2Mzo0Nzo4ODozYzo2OTo4MzpjYjpmZTo0NzpiZDoyYjo3ZTo0ZjpjNTo5NToKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGFlOjBlOjlkOmQ0OmQxOjQzOmMwOjY3OjczOmUzOjE0OjA4OjdlOmU1OjNmOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgOWY6NzM6Yjg6MzM6MGE6Y2Y6NWQ6M2Y6MzQ6ODc6OTY6OGE6ZWU6NTM6ZTg6CisgICAgICogICAgICAgICAgICAgICAgICAgICAyNToxNQorICAgICAqICAgICAgICAgICAgICAgICBFeHBvbmVudDogNjU1MzcgKDB4MTAwMDEpCisgICAgICogICAgICAgICBYNTA5djMgZXh0ZW5zaW9uczoKKyAgICAgKiAgICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IGNyaXRpY2FsCisgICAgICogICAgICAgICAgICAgICAgIENBOlRSVUUKKyAgICAgKiAgICAgICAgICAgICBYNTA5djMgQ1JMIERpc3RyaWJ1dGlvbiBQb2ludHM6CisgICAgICogICAgICAgICAgICAgICAgIFVSSTpodHRwOi8vY3JsLnZlcmlzaWduLmNvbS9wY2EzLmNybAorICAgICAqICAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IGNyaXRpY2FsCisgICAgICogICAgICAgICAgICAgICAgIENlcnRpZmljYXRlIFNpZ24sIENSTCBTaWduCisgICAgICogICAgICAgICAgICAgMS4zLjYuMS41LjUuNy4xLjEyOgorICAgICAqICAgICAgICAgICAgICAgICAwXy5dLlswWTBXMFUuLmltYWdlL2dpZjAhMC4wLi4uKy4uLi4uLi4uLi4uLi4uay4uLmouSC4sey4uMCUuI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmCisgICAgICogICAgICAgICAgICAgWDUwOXYzIENlcnRpZmljYXRlIFBvbGljaWVzOgorICAgICAqICAgICAgICAgICAgICAgICBQb2xpY3k6IFg1MDl2MyBBbnkgUG9saWN5CisgICAgICogICAgICAgICAgICAgICAgICAgQ1BTOiBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vY3BzCisgICAgICogICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6CisgICAgICogICAgICAgICAgICAgICAgIDdGOkQzOjY1OkE3OkMyOkREOkVDOkJCOkYwOjMwOjA5OkYzOjQzOjM5OkZBOjAyOkFGOjMzOjMxOjMzCisgICAgICogICAgICAgICAgICAgWDUwOXYzIEV4dGVuZGVkIEtleSBVc2FnZToKKyAgICAgKiAgICAgICAgICAgICAgICAgTmV0c2NhcGUgU2VydmVyIEdhdGVkIENyeXB0bywgMi4xNi44NDAuMS4xMTM3MzMuMS44LjEsIFRMUyBXZWIgU2VydmVyIEF1dGhlbnRpY2F0aW9uLCBUTFMgV2ViIENsaWVudCBBdXRoZW50aWNhdGlvbgorICAgICAqICAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6CisgICAgICogICAgICAgICAgICAgICAgIERpck5hbWU6L0M9VVMvTz1WZXJpU2lnbiwgSW5jLi9PVT1DbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5CisgICAgICogICAgICAgICAgICAgICAgIHNlcmlhbDo3MDpCQTpFNDoxRDoxMDpEOToyOTozNDpCNjozODpDQTo3QjowMzpDQzpCQTpCRgorICAgICAqICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgKiAgICAgICAgIGE5OjdiOjY2OjI5OjMwOmY3OmQ1OmI0OmE2Ojk2OjEyOmQwOmVlOjcyOmYwOjU4OjExOjY5OgorICAgICAqICAgICAgICAgMTU6NTU6NWY6NDE6ZmY6ZDI6MTI6ODQ6MTM6YTQ6ZDk6MDM6NjY6ZmY6YTk6ZTA6NGM6Yzk6CisgICAgICogICAgICAgICBlZDo4Yzo3Mjo4YjpiNDpkNzo1NTozYjoyOToxNTo2MDpjODozYzoyMTplZjo0NDoyZTo5MzoKKyAgICAgKiAgICAgICAgIDNkOmM2OjBiOjBjOjhkOjI0OjNmOjFlOmZiOjAxOjVhOjdhOmRkOjgzOjY2OjE0OmQxOmM3OgorICAgICAqICAgICAgICAgZmQ6MzA6NTM6NDg6NTE6ODU6ODU6MTM6YTg6NTQ6ZTE6ZWU6NzY6YTI6ODk6MTg6ZDM6OTc6CisgICAgICogICAgICAgICA4OTo3YTpjNjpmZDpiMzpiZDo5NDo2MTo1YTozYTowODpjZjoxNDo5MzpiZDo5MzpmZDowOToKKyAgICAgKiAgICAgICAgIGE5OjdiOjU2OmM4OjAwOmI4OjQ0OjU4OmU5OmRlOjViOjc3OmJkOjA3OjFjOjZjOjBiOjMwOgorICAgICAqICAgICAgICAgMzA6YzcKKyAgICAgKiA8L3ByZT4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgc2lnbmVkQ2VydDFDaGFpbjEgPQorICAgICAgICAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICsgIk1JSUZFekNDQkh5Z0F3SUJBZ0lRVjcvN0Evc3NSdFRobnM3ZzEwTi9FekFOQmdrcWhraUc5dzBCQVFVRkFEQmZcbiIKKyAgICAgICAgKyAiTVFzd0NRWURWUVFHRXdKVlV6RVhNQlVHQTFVRUNoTU9WbVZ5YVZOcFoyNHNJRWx1WXk0eE56QTFCZ05WQkFzVFxuIgorICAgICAgICArICJMa05zWVhOeklETWdVSFZpYkdsaklGQnlhVzFoY25rZ1EyVnlkR2xtYVdOaGRHbHZiaUJCZFhSb2IzSnBkSGt3XG4iCisgICAgICAgICsgIkhoY05NRFl4TVRBNE1EQXdNREF3V2hjTk1qRXhNVEEzTWpNMU9UVTVXakNCeWpFTE1Ba0dBMVVFQmhNQ1ZWTXhcbiIKKyAgICAgICAgKyAiRnpBVkJnTlZCQW9URGxabGNtbFRhV2R1TENCSmJtTXVNUjh3SFFZRFZRUUxFeFpXWlhKcFUybG5iaUJVY25WelxuIgorICAgICAgICArICJkQ0JPWlhSM2IzSnJNVG93T0FZRFZRUUxFekVvWXlrZ01qQXdOaUJXWlhKcFUybG5iaXdnU1c1akxpQXRJRVp2XG4iCisgICAgICAgICsgImNpQmhkWFJvYjNKcGVtVmtJSFZ6WlNCdmJteDVNVVV3UXdZRFZRUURFenhXWlhKcFUybG5iaUJEYkdGemN5QXpcbiIKKyAgICAgICAgKyAiSUZCMVlteHBZeUJRY21sdFlYSjVJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNUlDMGdSelV3Z2dFaVxuIgorICAgICAgICArICJNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUN2SkFnSUtYbzFubUFNcXVkTE8wN2NmTHc4XG4iCisgICAgICAgICsgIlJSeTdLK0QrS1FMNVZ3aWpaSVVWSi9YeHJjZ3hpVjBpNkNxcXBrS3pqL2k1VmJleHQwdXovbzkrQjFmczcwUGJcbiIKKyAgICAgICAgKyAiWm1JVlljOWdEYVRZM3ZqZ3cySUlQVlFUNjBuS1dWU0ZKdVVyanh1ZjYvV2hrY0l6U2RoRFkycFNTOUtQNkhCUlxuIgorICAgICAgICArICJUZEdKYVh2SGNQYXozQkowMjN0ZFMxYlRscjhWZDZHdzlLSWw4cThja21jWTVmUUdCTytRdWVRQTVOMDZ0Um4vXG4iCisgICAgICAgICsgIkFycjBQTzdnaStzM2krejAxNnp5OXZBOXI5MTFrVE1aSFJ4QXkzUWtHU0dUMlJUK3JDcFN4NC9WQkVua2pXTkhcbiIKKyAgICAgICAgKyAiaUR4cGc4ditSNzByZmsvRmxhNE9uZFRSUThCbmMrTVVDSDdsUDU5enVETUt6MTAvTkllV2l1NVQ2Q1VWQWdNQlxuIgorICAgICAgICArICJBQUdqZ2dIZU1JSUIyakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NREVHQTFVZEh3UXFNQ2d3SnFBa29DS0dJR2gwXG4iCisgICAgICAgICsgImRIQTZMeTlqY213dWRtVnlhWE5wWjI0dVkyOXRMM0JqWVRNdVkzSnNNQTRHQTFVZER3RUIvd1FFQXdJQkJqQnRcbiIKKyAgICAgICAgKyAiQmdnckJnRUZCUWNCREFSaE1GK2hYYUJiTUZrd1Z6QlZGZ2xwYldGblpTOW5hV1l3SVRBZk1BY0dCU3NPQXdJYVxuIgorICAgICAgICArICJCQlNQNWRNYWhxeU5qbXZEejRCcTFFZ1lMSHNaTGpBbEZpTm9kSFJ3T2k4dmJHOW5ieTUyWlhKcGMybG5iaTVqXG4iCisgICAgICAgICsgImIyMHZkbk5zYjJkdkxtZHBaakE5QmdOVkhTQUVOakEwTURJR0JGVWRJQUF3S2pBb0JnZ3JCZ0VGQlFjQ0FSWWNcbiIKKyAgICAgICAgKyAiYUhSMGNITTZMeTkzZDNjdWRtVnlhWE5wWjI0dVkyOXRMMk53Y3pBZEJnTlZIUTRFRmdRVWY5TmxwOExkN0x2d1xuIgorICAgICAgICArICJNQW56UXpuNkFxOHpNVE13TkFZRFZSMGxCQzB3S3dZSllJWklBWWI0UWdRQkJncGdoa2dCaHZoRkFRZ0JCZ2dyXG4iCisgICAgICAgICsgIkJnRUZCUWNEQVFZSUt3WUJCUVVIQXdJd2dZQUdBMVVkSXdSNU1IZWhZNlJoTUY4eEN6QUpCZ05WQkFZVEFsVlRcbiIKKyAgICAgICAgKyAiTVJjd0ZRWURWUVFLRXc1V1pYSnBVMmxuYml3Z1NXNWpMakUzTURVR0ExVUVDeE11UTJ4aGMzTWdNeUJRZFdKc1xuIgorICAgICAgICArICJhV01nVUhKcGJXRnllU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVZSVFjTHJrSFJEWktUUzJPTXA3XG4iCisgICAgICAgICsgIkE4eTZ2ekFOQmdrcWhraUc5dzBCQVFVRkFBT0JnUUNwZTJZcE1QZlZ0S2FXRXREdWN2QllFV2tWVlY5Qi85SVNcbiIKKyAgICAgICAgKyAiaEJPazJRTm0vNm5nVE1udGpIS0x0TmRWT3lrVllNZzhJZTlFTHBNOXhnc01qU1EvSHZzQlducmRnMllVMGNmOVxuIgorICAgICAgICArICJNRk5JVVlXRkU2aFU0ZTUyb29rWTA1ZUplc2I5czcyVVlWbzZDTThVazcyVC9RbXBlMWJJQUxoRVdPbmVXM2U5XG4iCisgICAgICAgICsgIkJ4eHNDekF3eHc9PVxuIgorICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tIjsKKworICAgIC8qKgorICAgICAqIEEgY2VydGlmaWNhdGUgc2lnbmVkIGJ5IHNpZ25lZENlcnQxQ2hhaW4xCisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqIENlcnRpZmljYXRlOgorICAgICAqICAgICBEYXRhOgorICAgICAqICAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAqICAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgKiAgICAgICAgICAgICAxMToyYTowMDo2ZDozNzplNToxMDo2ZjpkNjpjYTo3YzpjMzplZjpiYTpjYzoxOAorICAgICAqICAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICogICAgICAgICBJc3N1ZXI6IEM9VVMsIE89VmVyaVNpZ24sIEluYy4sIE9VPVZlcmlTaWduIFRydXN0IE5ldHdvcmssIE9VPShjKSAyMDA2IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHksIENOPVZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHNQorICAgICAqICAgICAgICAgVmFsaWRpdHkKKyAgICAgKiAgICAgICAgICAgICBOb3QgQmVmb3JlOiBOb3YgIDggMDA6MDA6MDAgMjAwNiBHTVQKKyAgICAgKiAgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBOb3YgIDcgMjM6NTk6NTkgMjAxNiBHTVQKKyAgICAgKiAgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89VmVyaVNpZ24sIEluYy4sIE9VPVZlcmlTaWduIFRydXN0IE5ldHdvcmssIE9VPVRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTA2LCBDTj1WZXJpU2lnbiBDbGFzcyAzIEV4dGVuZGVkIFZhbGlkYXRpb24gU1NMIFNHQyBDQQorICAgICAqICAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICogICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgKiAgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAqICAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICogICAgICAgICAgICAgICAgICAgICAwMDpiZDo1Njo4ODpiYTo4ODozNDo2NDo2NDpjZjpjZDpjYTpiMDplZTplNzoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDE5OjczOmM1OjcyOmQ5OmJiOjQ1OmJjOmI1OmE4OmZmOjgzOmJlOjFjOjAzOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgZGI6ZWQ6ODk6Yjc6MmU6MTA6MWE6MjU6YmM6NTU6Y2E6NDE6YTE6OWY6MGI6CisgICAgICogICAgICAgICAgICAgICAgICAgICBjZjoxOTo1ZTo3MDpiOTo1ZTozOTo0Yjo5ZTozMToxYzo1Zjo4NzphZToyYToKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGFhOmE4OjJiOmEyOjFiOjNiOjEwOjIzOjVmOjEzOmIxOmRkOjA4OjhjOjRlOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgMTQ6ZGE6ODM6ODE6ZTM6YjU6OGM6ZTM6Njg6ZWQ6MjQ6Njc6Y2U6NTY6YjY6CisgICAgICogICAgICAgICAgICAgICAgICAgICBhYzo5Yjo3Mzo5Njo0NDpkYjo4YTo4YzpiMzpkNjpmMDo3MTo5Mzo4ZTpkYjoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDcxOjU0OjRhOmViOjczOjU5OjZhOjhmOjcwOjUxOjJjOjAzOjlmOjk3OmQxOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgY2M6MTE6N2E6YmM6NjI6MGQ6OTU6MmE6Yzk6MWM6NzU6NTc6ZTk6ZjU6Yzc6CisgICAgICogICAgICAgICAgICAgICAgICAgICBlYTpiYTo4NDozNTpjYjpjNzo4NTo1YTo3ZTplNDo0ZDplMToxMTo5Nzo3ZDoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDBlOjIwOjM0OjQ1OmRiOmYxOmEyOjA5OmViOmViOjNkOjllOmI4Ojk2OjQzOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgNWU6MzQ6NGI6MDg6MjU6MWU6NDM6MWE6YTI6ZDk6Yjc6OGE6MDE6MzQ6M2Q6CisgICAgICogICAgICAgICAgICAgICAgICAgICBjMzpmODplNTphZjo0Zjo4YzpmZjpjZDo2NTpmMDoyMzo0ZTpjNTo5NzpiMzoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDVjOmRhOjkwOjFjOjgyOjg1OjBkOjA2OjBkOmMxOjIyOmI2OjdiOjI4OmE0OgorICAgICAqICAgICAgICAgICAgICAgICAgICAgMDM6YzM6NGM6NTM6ZDE6NTg6YmM6NzI6YmM6MDg6Mzk6ZmM6YTA6NzY6YTg6CisgICAgICogICAgICAgICAgICAgICAgICAgICBhODplOTo0Yjo2ZTo4ODozZDplMzpiMzozMToyNTo4Yzo3MzoyOTo0ODowZToKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDMyOjc5OjA2OmVkOjNkOjQzOmY0OmY2OmU0OmU5OmZjOjdkOmJlOjhlOjA4OgorICAgICAqICAgICAgICAgICAgICAgICAgICAgZDU6MWYKKyAgICAgKiAgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAqICAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICogICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6CisgICAgICogICAgICAgICAgICAgICAgIDRFOjQzOkM4OjFEOjc2OkVGOjM3OjUzOjdBOjRGOkYyOjU4OjZGOjk0OkYzOjM4OkUyOkQ1OkJEOkRGCisgICAgICogICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAqICAgICAgICAgICAgICAgICBDQTpUUlVFLCBwYXRobGVuOjAKKyAgICAgKiAgICAgICAgICAgICBYNTA5djMgQ2VydGlmaWNhdGUgUG9saWNpZXM6CisgICAgICogICAgICAgICAgICAgICAgIFBvbGljeTogWDUwOXYzIEFueSBQb2xpY3kKKyAgICAgKiAgICAgICAgICAgICAgICAgICBDUFM6IGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9jcHMKKyAgICAgKiAgICAgICAgICAgICBYNTA5djMgQ1JMIERpc3RyaWJ1dGlvbiBQb2ludHM6CisgICAgICogICAgICAgICAgICAgICAgIFVSSTpodHRwOi8vRVZTZWN1cmUtY3JsLnZlcmlzaWduLmNvbS9wY2EzLWc1LmNybAorICAgICAqICAgICAgICAgICAgIFg1MDl2MyBFeHRlbmRlZCBLZXkgVXNhZ2U6CisgICAgICogICAgICAgICAgICAgICAgIE5ldHNjYXBlIFNlcnZlciBHYXRlZCBDcnlwdG8sIDIuMTYuODQwLjEuMTEzNzMzLjEuOC4xCisgICAgICogICAgICAgICAgICAgWDUwOXYzIEtleSBVc2FnZTogY3JpdGljYWwKKyAgICAgKiAgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgU2lnbiwgQ1JMIFNpZ24KKyAgICAgKiAgICAgICAgICAgICBOZXRzY2FwZSBDZXJ0IFR5cGU6CisgICAgICogICAgICAgICAgICAgICAgIFNTTCBDQSwgUy9NSU1FIENBCisgICAgICogICAgICAgICAgICAgMS4zLjYuMS41LjUuNy4xLjEyOgorICAgICAqICAgICAgICAgICAgICAgICAwXy5dLlswWTBXMFUuLmltYWdlL2dpZjAhMC4wLi4uKy4uLi4uLi4uLi4uLi4uay4uLmouSC4sey4uMCUuI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmCisgICAgICogICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgQWx0ZXJuYXRpdmUgTmFtZToKKyAgICAgKiAgICAgICAgICAgICAgICAgRGlyTmFtZTovQ049Q2xhc3MzQ0EyMDQ4LTEtNDgKKyAgICAgKiAgICAgICAgICAgICBBdXRob3JpdHkgSW5mb3JtYXRpb24gQWNjZXNzOgorICAgICAqICAgICAgICAgICAgICAgICBPQ1NQIC0gVVJJOmh0dHA6Ly9FVlNlY3VyZS1vY3NwLnZlcmlzaWduLmNvbQorICAgICAqICAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6CisgICAgICogICAgICAgICAgICAgICAgIGtleWlkOjdGOkQzOjY1OkE3OkMyOkREOkVDOkJCOkYwOjMwOjA5OkYzOjQzOjM5OkZBOjAyOkFGOjMzOjMxOjMzCisgICAgICogICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAqICAgICAgICAgNWE6YTI6YjE6YmY6ZWI6OGQ6ZDQ6Mzg6YTg6ODA6NzI6YzI6ZGM6Mzg6MmU6YWM6YTc6NzE6CisgICAgICogICAgICAgICBmOToyYjphMzpiYjo0NzpiYjo2ZDo2OTo2ZjoxMDozNjo5ODo4YzpjNzo1NjoyZTpiYjpiYzoKKyAgICAgKiAgICAgICAgIGFiOjRhOjliOjdhOmQ2OmYyOjgyOjkzOmUwOjE0OmZlOjhhOmNlOjgzOmI3OjgzOmRiOjkzOgorICAgICAqICAgICAgICAgODc6YWI6YWM6NjU6Nzk6NDk6ZmQ6NTc6YTk6YjE6Y2U6MDk6MWY6YmE6MTA6MTU6YzQ6MDk6CisgICAgICogICAgICAgICAwZTo2MjplMzpmOTowYToyNTpkNTo2NDo5ODpmMDpmMjphODowZjo3NjozMjo3ZTo5MTplNjoKKyAgICAgKiAgICAgICAgIDE4OmVlOmJjOmU3OmRhOmQwOjRlOjhkOjc4OmJiOmUyOjlkOmMwOjU5OjJiOmMwOmNlOjk1OgorICAgICAqICAgICAgICAgMGQ6MjQ6MGM6NzI6Y2E6MzQ6NWU6NzA6MjI6ODk6MmI6NGE6YjA6ZjE6Njg6ODc6ZjM6ZWU6CisgICAgICogICAgICAgICA0NDo4ZDoyODo0MDo3NzozOTo2ZTo0ODo3Mjo0NTozMTo1ZDo2YjozOTowZTo4NjowMjplYToKKyAgICAgKiAgICAgICAgIDY2Ojk5OjkzOjMxOjBmOmRmOjY3OmRlOmE2OjlmOjhjOjlkOjRjOmNlOjcxOjZmOjNhOjIxOgorICAgICAqICAgICAgICAgZjY6Yjk6MzQ6M2Y6Zjk6NmU6ZDg6OWE6Zjc6M2U6ZGE6ZjM6ODE6NWY6N2E6NWM6NmQ6OGY6CisgICAgICogICAgICAgICA3YzpmNjo5OTo3NDpiNzpmZjplNDoxNzo1ZDplZDo2MTo1ZTphYjo0ODpiYjo5Njo4ZDo2NjoKKyAgICAgKiAgICAgICAgIDQ1OjM5OmI0OjEyOjBhOmY2OjcwOmU5OjljOjc2OjIyOjRiOjYwOmU5OjJhOjFiOjM0OjQ5OgorICAgICAqICAgICAgICAgZjc6YTI6ZDQ6Njc6YzA6YjE6MjY6YWQ6MTM6YmE6ZDk6ODQ6MDE6YzE6YWI6ZTE6OGU6NmQ6CisgICAgICogICAgICAgICA3MDoxNjozYjo3NzphYzo5MTo5YTpiYjoxYToxZjpkYTo1ODphNzplNDo0ZjpjMTo2MTphZToKKyAgICAgKiAgICAgICAgIGJjOmEyOmZlOjRiCisgICAgICogPC9wcmU+CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHNpZ25lZENlcnQyQ2hhaW4xID0KKyAgICAgICAgIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICAgICArICJNSUlHQ2pDQ0JQS2dBd0lCQWdJUUVTb0FiVGZsRUcvV3luekQ3N3JNR0RBTkJna3Foa2lHOXcwQkFRVUZBRENCXG4iCisgICAgICAgICsgInlqRUxNQWtHQTFVRUJoTUNWVk14RnpBVkJnTlZCQW9URGxabGNtbFRhV2R1TENCSmJtTXVNUjh3SFFZRFZRUUxcbiIKKyAgICAgICAgKyAiRXhaV1pYSnBVMmxuYmlCVWNuVnpkQ0JPWlhSM2IzSnJNVG93T0FZRFZRUUxFekVvWXlrZ01qQXdOaUJXWlhKcFxuIgorICAgICAgICArICJVMmxuYml3Z1NXNWpMaUF0SUVadmNpQmhkWFJvYjNKcGVtVmtJSFZ6WlNCdmJteDVNVVV3UXdZRFZRUURFenhXXG4iCisgICAgICAgICsgIlpYSnBVMmxuYmlCRGJHRnpjeUF6SUZCMVlteHBZeUJRY21sdFlYSjVJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBcbiIKKyAgICAgICAgKyAiYUc5eWFYUjVJQzBnUnpVd0hoY05NRFl4TVRBNE1EQXdNREF3V2hjTk1UWXhNVEEzTWpNMU9UVTVXakNCdmpFTFxuIgorICAgICAgICArICJNQWtHQTFVRUJoTUNWVk14RnpBVkJnTlZCQW9URGxabGNtbFRhV2R1TENCSmJtTXVNUjh3SFFZRFZRUUxFeFpXXG4iCisgICAgICAgICsgIlpYSnBVMmxuYmlCVWNuVnpkQ0JPWlhSM2IzSnJNVHN3T1FZRFZRUUxFekpVWlhKdGN5QnZaaUIxYzJVZ1lYUWdcbiIKKyAgICAgICAgKyAiYUhSMGNITTZMeTkzZDNjdWRtVnlhWE5wWjI0dVkyOXRMM0p3WVNBb1l5a3dOakU0TURZR0ExVUVBeE12Vm1WeVxuIgorICAgICAgICArICJhVk5wWjI0Z1EyeGhjM01nTXlCRmVIUmxibVJsWkNCV1lXeHBaR0YwYVc5dUlGTlRUQ0JUUjBNZ1EwRXdnZ0VpXG4iCisgICAgICAgICsgIk1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQzlWb2k2aURSa1pNL055ckR1NXhsenhYTFpcbiIKKyAgICAgICAgKyAidTBXOHRhai9nNzRjQTl2dGliY3VFQm9sdkZYS1FhR2ZDODhaWG5DNVhqbExuakVjWDRldUtxcW9LNkliT3hBalxuIgorICAgICAgICArICJYeE94M1FpTVRoVGFnNEhqdFl6amFPMGtaODVXdHF5YmM1WkUyNHFNczlid2NaT08yM0ZVU3V0eldXcVBjRkVzXG4iCisgICAgICAgICsgIkE1K1gwY3dSZXJ4aURaVXF5UngxVituMXgrcTZoRFhMeDRWYWZ1Uk40UkdYZlE0Z05FWGI4YUlKNitzOW5yaVdcbiIKKyAgICAgICAgKyAiUTE0MFN3Z2xIa01hb3RtM2lnRTBQY1A0NWE5UGpQL05aZkFqVHNXWHMxemFrQnlDaFEwR0RjRWl0bnNvcEFQRFxuIgorICAgICAgICArICJURlBSV0x4eXZBZzUvS0IycUtqcFMyNklQZU96TVNXTWN5bElEako1QnUwOVEvVDI1T244ZmI2T0NOVWZBZ01CXG4iCisgICAgICAgICsgIkFBR2pnZ0gwTUlJQjhEQWRCZ05WSFE0RUZnUVVUa1BJSFhidk4xTjZUL0pZYjVUek9PTFZ2ZDh3RWdZRFZSMFRcbiIKKyAgICAgICAgKyAiQVFIL0JBZ3dCZ0VCL3dJQkFEQTlCZ05WSFNBRU5qQTBNRElHQkZVZElBQXdLakFvQmdnckJnRUZCUWNDQVJZY1xuIgorICAgICAgICArICJhSFIwY0hNNkx5OTNkM2N1ZG1WeWFYTnBaMjR1WTI5dEwyTndjekE5QmdOVkhSOEVOakEwTURLZ01LQXVoaXhvXG4iCisgICAgICAgICsgImRIUndPaTh2UlZaVFpXTjFjbVV0WTNKc0xuWmxjbWx6YVdkdUxtTnZiUzl3WTJFekxXYzFMbU55YkRBZ0JnTlZcbiIKKyAgICAgICAgKyAiSFNVRUdUQVhCZ2xnaGtnQmh2aENCQUVHQ21DR1NBR0crRVVCQ0FFd0RnWURWUjBQQVFIL0JBUURBZ0VHTUJFR1xuIgorICAgICAgICArICJDV0NHU0FHRytFSUJBUVFFQXdJQkJqQnRCZ2dyQmdFRkJRY0JEQVJoTUYraFhhQmJNRmt3VnpCVkZnbHBiV0ZuXG4iCisgICAgICAgICsgIlpTOW5hV1l3SVRBZk1BY0dCU3NPQXdJYUJCU1A1ZE1haHF5TmptdkR6NEJxMUVnWUxIc1pMakFsRmlOb2RIUndcbiIKKyAgICAgICAgKyAiT2k4dmJHOW5ieTUyWlhKcGMybG5iaTVqYjIwdmRuTnNiMmR2TG1kcFpqQXBCZ05WSFJFRUlqQWdwQjR3SERFYVxuIgorICAgICAgICArICJNQmdHQTFVRUF4TVJRMnhoYzNNelEwRXlNRFE0TFRFdE5EZ3dQUVlJS3dZQkJRVUhBUUVFTVRBdk1DMEdDQ3NHXG4iCisgICAgICAgICsgIkFRVUZCekFCaGlGb2RIUndPaTh2UlZaVFpXTjFjbVV0YjJOemNDNTJaWEpwYzJsbmJpNWpiMjB3SHdZRFZSMGpcbiIKKyAgICAgICAgKyAiQkJnd0ZvQVVmOU5scDhMZDdMdndNQW56UXpuNkFxOHpNVE13RFFZSktvWklodmNOQVFFRkJRQURnZ0VCQUZxaVxuIgorICAgICAgICArICJzYi9yamRRNHFJQnl3dHc0THF5bmNma3JvN3RIdTIxcGJ4QTJtSXpIVmk2N3ZLdEttM3JXOG9LVDRCVCtpczZEXG4iCisgICAgICAgICsgInQ0UGJrNGVyckdWNVNmMVhxYkhPQ1IrNkVCWEVDUTVpNC9rS0pkVmttUER5cUE5Mk1uNlI1aGp1dk9mYTBFNk5cbiIKKyAgICAgICAgKyAiZUx2aW5jQlpLOERPbFEwa0RITEtORjV3SW9rclNyRHhhSWZ6N2tTTktFQjNPVzVJY2tVeFhXczVEb1lDNm1hWlxuIgorICAgICAgICArICJrekVQMzJmZXBwK01uVXpPY1c4NklmYTVORC81YnRpYTl6N2E4NEZmZWx4dGozejJtWFMzLytRWFhlMWhYcXRJXG4iCisgICAgICAgICsgInU1YU5aa1U1dEJJSzluRHBuSFlpUzJEcEtoczBTZmVpMUdmQXNTYXRFN3JaaEFIQnErR09iWEFXTzNlc2tacTdcbiIKKyAgICAgICAgKyAiR2gvYVdLZmtUOEZocnJ5aS9rcz1cbiIKKyAgICAgICAgKyAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLSI7CisKKyAgICAvKgorICAgICAqIEZvbGxvd2luZyBjZXJ0aWZpY2F0ZSBjaGFpbiB3YXMgdGFrZW4gZnJvbSBodHRwczovL3d3dy50aGF3dGUuY29tIGFuZAorICAgICAqIHVzZXMgTUQ1d2l0aFJTQSBmb3IgdGhlIHJvb3QgY2VydGlmaWNhdGUuIFRoaXMgY2hhaW4gc3RvcHMgdmFsaWRhdGluZworICAgICAqIGluIE5vdiAyMDE2LgorICAgICAqLworCisgICAgLyoqCisgICAgICogQSBzZWxmc2lnbmVkIGNlcnRpZmljYXRlIHVzaW5nIE1ENXdpdGhSU0EKKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogQ2VydGlmaWNhdGU6CisgICAgICogICAgIERhdGE6CisgICAgICogICAgICAgICBWZXJzaW9uOiAzICgweDIpCisgICAgICogICAgICAgICBTZXJpYWwgTnVtYmVyOiAxICgweDEpCisgICAgICogICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBtZDVXaXRoUlNBRW5jcnlwdGlvbgorICAgICAqICAgICAgICAgSXNzdWVyOiBDPVpBLCBTVD1XZXN0ZXJuIENhcGUsIEw9Q2FwZSBUb3duLCBPPVRoYXd0ZSBDb25zdWx0aW5nIGNjLCBPVT1DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uLCBDTj1UaGF3dGUgUHJlbWl1bSBTZXJ2ZXIgQ0EvZW1haWxBZGRyZXNzPXByZW1pdW0tc2VydmVyQHRoYXd0ZS5jb20KKyAgICAgKiAgICAgICAgIFZhbGlkaXR5CisgICAgICogICAgICAgICAgICAgTm90IEJlZm9yZTogQXVnICAxIDAwOjAwOjAwIDE5OTYgR01UCisgICAgICogICAgICAgICAgICAgTm90IEFmdGVyIDogRGVjIDMxIDIzOjU5OjU5IDIwMjAgR01UCisgICAgICogICAgICAgICBTdWJqZWN0OiBDPVpBLCBTVD1XZXN0ZXJuIENhcGUsIEw9Q2FwZSBUb3duLCBPPVRoYXd0ZSBDb25zdWx0aW5nIGNjLCBPVT1DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uLCBDTj1UaGF3dGUgUHJlbWl1bSBTZXJ2ZXIgQ0EvZW1haWxBZGRyZXNzPXByZW1pdW0tc2VydmVyQHRoYXd0ZS5jb20KKyAgICAgKiAgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAqICAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICogICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgxMDI0IGJpdCkKKyAgICAgKiAgICAgICAgICAgICAgICAgTW9kdWx1cyAoMTAyNCBiaXQpOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgMDA6ZDI6MzY6MzY6NmE6OGI6ZDc6YzI6NWI6OWU6ZGE6ODE6NDE6NjI6OGY6CisgICAgICogICAgICAgICAgICAgICAgICAgICAzODplZTo0OTowNDo1NTpkNjpkMDplZjoxYzoxYjo5NToxNjo0NzplZjoxODoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDQ4OjM1OjNhOjUyOmY0OjJiOjZhOjA2OjhmOjNiOjJmOmVhOjU2OmUzOmFmOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgODY6OGQ6OWU6MTc6Zjc6OWU6YjQ6NjU6NzU6MDI6NGQ6ZWY6Y2I6MDk6YTI6CisgICAgICogICAgICAgICAgICAgICAgICAgICAyMTo1MTpkODo5YjpkMDo2NzpkMDpiYTowZDo5MjowNjoxNDo3MzpkNDo5MzoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGNiOjk3OjJhOjAwOjljOjVjOjRlOjBjOmJjOmZhOjE1OjUyOmZjOmYyOjQ0OgorICAgICAqICAgICAgICAgICAgICAgICAgICAgNmU6ZGE6MTE6NGE6NmU6MDg6OWY6MmY6MmQ6ZTM6Zjk6YWE6M2E6ODY6NzM6CisgICAgICogICAgICAgICAgICAgICAgICAgICBiNjo0Njo1Mzo1ODpjODo4OTowNTpiZDo4MzoxMTpiODo3MzozZjphYTowNzoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDhkOmY0OjQyOjRkOmU3OjQwOjlkOjFjOjM3CisgICAgICogICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgKiAgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAqICAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgKiAgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAqICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBtZDVXaXRoUlNBRW5jcnlwdGlvbgorICAgICAqICAgICAgICAgMjY6NDg6MmM6MTY6YzI6NTg6ZmE6ZTg6MTY6NzQ6MGM6YWE6YWE6NWY6NTQ6M2Y6ZjI6ZDc6CisgICAgICogICAgICAgICBjOTo3ODo2MDo1ZTo1ZTo2ZTozNzo2MzoyMjo3NzozNjo3ZTpiMjoxNzpjNDozNDpiOTpmNToKKyAgICAgKiAgICAgICAgIDA4Ojg1OmZjOmM5OjAxOjM4OmZmOjRkOmJlOmYyOjE2OjQyOjQzOmU3OmJiOjVhOjQ2OmZiOgorICAgICAqICAgICAgICAgYzE6YzY6MTE6MWY6ZjE6NGE6YjA6Mjg6NDY6Yzk6YzM6YzQ6NDI6N2Q6YmM6ZmE6YWI6NTk6CisgICAgICogICAgICAgICA2ZTpkNTpiNzo1MTo4ODoxMTplMzphNDo4NToxOTo2Yjo4Mjo0YzphNDowYzoxMjphZDplOToKKyAgICAgKiAgICAgICAgIGE0OmFlOjNmOmYxOmMzOjQ5OjY1OjlhOjhjOmM1OmM4OjNlOjI1OmI3Ojk0Ojk5OmJiOjkyOgorICAgICAqICAgICAgICAgMzI6NzE6MDc6ZjA6ODY6NWU6ZWQ6NTA6Mjc6YTY6MGQ6YTY6MjM6Zjk6YmI6Y2I6YTY6MDc6CisgICAgICogICAgICAgICAxNDo0MgorICAgICAqIDwvcHJlPgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBzZWxmU2lnbmVkQ2VydE1ENSA9CisgICAgICAgICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgKyAiTUlJREp6Q0NBcENnQXdJQkFnSUJBVEFOQmdrcWhraUc5dzBCQVFRRkFEQ0J6akVMTUFrR0ExVUVCaE1DV2tFeFxuIgorICAgICAgICArICJGVEFUQmdOVkJBZ1RERmRsYzNSbGNtNGdRMkZ3WlRFU01CQUdBMVVFQnhNSlEyRndaU0JVYjNkdU1SMHdHd1lEXG4iCisgICAgICAgICsgIlZRUUtFeFJVYUdGM2RHVWdRMjl1YzNWc2RHbHVaeUJqWXpFb01DWUdBMVVFQ3hNZlEyVnlkR2xtYVdOaGRHbHZcbiIKKyAgICAgICAgKyAiYmlCVFpYSjJhV05sY3lCRWFYWnBjMmx2YmpFaE1COEdBMVVFQXhNWVZHaGhkM1JsSUZCeVpXMXBkVzBnVTJWeVxuIgorICAgICAgICArICJkbVZ5SUVOQk1TZ3dKZ1lKS29aSWh2Y05BUWtCRmhsd2NtVnRhWFZ0TFhObGNuWmxja0IwYUdGM2RHVXVZMjl0XG4iCisgICAgICAgICsgIk1CNFhEVGsyTURnd01UQXdNREF3TUZvWERUSXdNVEl6TVRJek5UazFPVm93Z2M0eEN6QUpCZ05WQkFZVEFscEJcbiIKKyAgICAgICAgKyAiTVJVd0V3WURWUVFJRXd4WFpYTjBaWEp1SUVOaGNHVXhFakFRQmdOVkJBY1RDVU5oY0dVZ1ZHOTNiakVkTUJzR1xuIgorICAgICAgICArICJBMVVFQ2hNVVZHaGhkM1JsSUVOdmJuTjFiSFJwYm1jZ1kyTXhLREFtQmdOVkJBc1RIME5sY25ScFptbGpZWFJwXG4iCisgICAgICAgICsgImIyNGdVMlZ5ZG1salpYTWdSR2wyYVhOcGIyNHhJVEFmQmdOVkJBTVRHRlJvWVhkMFpTQlFjbVZ0YVhWdElGTmxcbiIKKyAgICAgICAgKyAiY25abGNpQkRRVEVvTUNZR0NTcUdTSWIzRFFFSkFSWVpjSEpsYldsMWJTMXpaWEoyWlhKQWRHaGhkM1JsTG1OdlxuIgorICAgICAgICArICJiVENCbnpBTkJna3Foa2lHOXcwQkFRRUZBQU9CalFBd2dZa0NnWUVBMGpZMmFvdlh3bHVlMm9GQllvODQ3a2tFXG4iCisgICAgICAgICsgIlZkYlE3eHdibFJaSDd4aElOVHBTOUN0cUJvODdMK3BXNDYrR2paNFg5NTYwWlhVQ1RlL0xDYUloVWRpYjBHZlFcbiIKKyAgICAgICAgKyAidWcyU0JoUnoxSlBMbHlvQW5GeE9ETHo2RlZMODhrUnUyaEZLYmdpZkx5M2orYW82aG5PMlJsTll5SWtGdllNUlxuIgorICAgICAgICArICJ1SE0vcWdlTjlFSk41MENkSERjQ0F3RUFBYU1UTUJFd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBTkJna3Foa2lHXG4iCisgICAgICAgICsgIjl3MEJBUVFGQUFPQmdRQW1TQ3dXd2xqNjZCWjBES3FxWDFRLzh0ZkplR0JlWG00M1l5SjNObjZ5RjhRMHVmVUlcbiIKKyAgICAgICAgKyAiaGZ6SkFUai9UYjd5RmtKRDU3dGFSdnZCeGhFZjhVcXdLRWJKdzhSQ2ZiejZxMWx1MWJkUmlCSGpwSVVaYTRKTVxuIgorICAgICAgICArICJwQXdTcmVta3JqL3h3MGxsbW96RnlENGx0NVNadTVJeWNRZndobDd0VUNlbURhWWorYnZMcGdjVVFnPT1cbiIKKyAgICAgICAgKyAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLSI7CisKKyAgICAvKioKKyAgICAgKiBBIGNlcnRpZmljYXRlIHNpZ25lZCBieSBzZWxmU2lnbmVkQ2VydE1ENQorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiBDZXJ0aWZpY2F0ZToKKyAgICAgKiAgICAgRGF0YToKKyAgICAgKiAgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgKiAgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICogICAgICAgICAgICAgNWY6YTY6YmU6ODA6YjY6ODY6YzY6MmY6MDE6ZWQ6MGM6YWI6YjE6OTY6YTE6MDUKKyAgICAgKiAgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAqICAgICAgICAgSXNzdWVyOiBDPVpBLCBTVD1XZXN0ZXJuIENhcGUsIEw9Q2FwZSBUb3duLCBPPVRoYXd0ZSBDb25zdWx0aW5nIGNjLCBPVT1DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uLCBDTj1UaGF3dGUgUHJlbWl1bSBTZXJ2ZXIgQ0EvZW1haWxBZGRyZXNzPXByZW1pdW0tc2VydmVyQHRoYXd0ZS5jb20KKyAgICAgKiAgICAgICAgIFZhbGlkaXR5CisgICAgICogICAgICAgICAgICAgTm90IEJlZm9yZTogTm92IDE3IDAwOjAwOjAwIDIwMDYgR01UCisgICAgICogICAgICAgICAgICAgTm90IEFmdGVyIDogRGVjIDMwIDIzOjU5OjU5IDIwMjAgR01UCisgICAgICogICAgICAgICBTdWJqZWN0OiBDPVVTLCBPPXRoYXd0ZSwgSW5jLiwgT1U9Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbiwgT1U9KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHksIENOPXRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EKKyAgICAgKiAgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAqICAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICogICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgyMDQ4IGJpdCkKKyAgICAgKiAgICAgICAgICAgICAgICAgTW9kdWx1cyAoMjA0OCBiaXQpOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgMDA6YWM6YTA6ZjA6ZmI6ODA6NTk6ZDQ6OWM6Yzc6YTQ6Y2Y6OWQ6YTE6NTk6CisgICAgICogICAgICAgICAgICAgICAgICAgICA3MzowOToxMDo0NTowYzowZDoyYzo2ZTo2ODpmMTo2Yzo1Yjo0ODo2ODo0OToKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDU5OjM3OmZjOjBiOjMzOjE5OmMyOjc3OjdmOmNjOjEwOjJkOjk1OjM0OjFjOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgZTY6ZWI6NGQ6MDk6YTc6MWM6ZDI6Yjg6Yzk6OTc6MzY6MDI6Yjc6ODk6ZDQ6CisgICAgICogICAgICAgICAgICAgICAgICAgICAyNDo1ZjowNjpjMDpjYzo0NDo5NDo5NDo4ZDowMjo2Mjo2ZjplYjo1YTpkZDoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDExOjhkOjI4OjlhOjVjOjg0OjkwOjEwOjdhOjBkOmJkOjc0OjY2OjJmOjZhOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgMzg6YTA6ZTI6ZDU6NTQ6NDQ6ZWI6MWQ6MDc6OWY6MDc6YmE6NmY6ZWU6ZTk6CisgICAgICogICAgICAgICAgICAgICAgICAgICBmZDo0ZTowYjoyOTpmNTozZTo4NDphMDowMTpmMTo5YzphYjpmODoxYzo3ZToKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDg5OmE0OmU4OmExOmQ4OjcxOjY1OjBkOmEzOjUxOjdiOmVlOmJjOmQyOjIyOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgNjA6MGQ6Yjk6NWI6OWQ6ZGY6YmE6ZmM6NTE6NWI6MGI6YWY6OTg6YjI6ZTk6CisgICAgICogICAgICAgICAgICAgICAgICAgICAyZTplOTowNDplODo2Mjo4NzpkZToyYjpjODpkNzo0ZTpjMTo0Yzo2NDoxZToKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGRkOmNmOjg3OjU4OmJhOjRhOjRmOmNhOjY4OjA3OjFkOjFjOjlkOjRhOmM2OgorICAgICAqICAgICAgICAgICAgICAgICAgICAgZDU6MmY6OTE6Y2M6N2M6NzE6NzI6MWM6YzU6YzA6Njc6ZWI6MzI6ZmQ6Yzk6CisgICAgICogICAgICAgICAgICAgICAgICAgICA5Mjo1Yzo5NDpkYTo4NTpjMDo5YjpiZjo1Mzo3ZDoyYjowOTpmNDo4Yzo5ZDoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDkxOjFmOjk3OjZhOjUyOmNiOmRlOjA5OjM2OmE0Ojc3OmQ4OjdiOjg3OjUwOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgNDQ6ZDU6M2U6NmU6Mjk6Njk6ZmI6Mzk6NDk6MjY6MWU6MDk6YTU6ODA6N2I6CisgICAgICogICAgICAgICAgICAgICAgICAgICA0MDoyZDplYjplODoyNzo4NTpjOTpmZTo2MTpmZDo3ZTplNjo3Yzo5NzoxZDoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGQ1OjlkCisgICAgICogICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgKiAgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAqICAgICAgICAgICAgIFg1MDl2MyBCYXNpYyBDb25zdHJhaW50czogY3JpdGljYWwKKyAgICAgKiAgICAgICAgICAgICAgICAgQ0E6VFJVRQorICAgICAqICAgICAgICAgICAgIFg1MDl2MyBDZXJ0aWZpY2F0ZSBQb2xpY2llczoKKyAgICAgKiAgICAgICAgICAgICAgICAgUG9saWN5OiBYNTA5djMgQW55IFBvbGljeQorICAgICAqICAgICAgICAgICAgICAgICAgIENQUzogaHR0cHM6Ly93d3cudGhhd3RlLmNvbS9jcHMKKyAgICAgKiAgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAqICAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAqICAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOgorICAgICAqICAgICAgICAgICAgICAgICA3Qjo1Qjo0NTpDRjpBRjpDRTpDQjo3QTpGRDozMTo5MjoxQTo2QTpCNjpGMzo0NjpFQjo1Nzo0ODo1MAorICAgICAqICAgICAgICAgICAgIFg1MDl2MyBDUkwgRGlzdHJpYnV0aW9uIFBvaW50czoKKyAgICAgKiAgICAgICAgICAgICAgICAgVVJJOmh0dHA6Ly9jcmwudGhhd3RlLmNvbS9UaGF3dGVQcmVtaXVtU2VydmVyQ0EuY3JsCisgICAgICogICAgICAgICAgICAgWDUwOXYzIEV4dGVuZGVkIEtleSBVc2FnZToKKyAgICAgKiAgICAgICAgICAgICAgICAgTmV0c2NhcGUgU2VydmVyIEdhdGVkIENyeXB0bywgMi4xNi44NDAuMS4xMTM3MzMuMS44LjEKKyAgICAgKiAgICAgICAgICAgICBYNTA5djMgQXV0aG9yaXR5IEtleSBJZGVudGlmaWVyOgorICAgICAqICAgICAgICAgICAgICAgICBEaXJOYW1lOi9DPVpBL1NUPVdlc3Rlcm4gQ2FwZS9MPUNhcGUgVG93bi9PPVRoYXd0ZSBDb25zdWx0aW5nIGNjL09VPUNlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24vQ049VGhhd3RlIFByZW1pdW0gU2VydmVyIENBL2VtYWlsQWRkcmVzcz1wcmVtaXVtLXNlcnZlckB0aGF3dGUuY29tCisgICAgICogICAgICAgICAgICAgICAgIHNlcmlhbDowMQorICAgICAqICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgKiAgICAgICAgIDJiOmNhOjEyOmM5OmRkOmQ3OmNjOjYzOjFjOjliOjMxOjM1OjRhOmRkOmU0OmI3OmY2OjlkOgorICAgICAqICAgICAgICAgZDE6YTQ6ZmI6MWU6Zjg6NDc6Zjk6YWU6MDc6OGU6MGQ6NTg6MTI6ZmI6ZGE6ZWQ6YjU6Y2M6CisgICAgICogICAgICAgICAzMzplNTo5Nzo2ODo0Nzo2MTo0MjpkNTo2NjphOTo2ZToxZTo0NzpiZjo4NTpkYjo3ZDo1ODoKKyAgICAgKiAgICAgICAgIGQxOjc3OjVhOmNjOjkwOjYxOjk4OjlhOjI5OmY1OjlkOmIxOmNmOmI4OmRjOmYzOjdiOjgwOgorICAgICAqICAgICAgICAgNDc6NDg6ZDE6N2Q6ZjQ6Njg6OGM6YzQ6NDE6Y2I6YjQ6ZTk6ZmQ6ZjA6MjM6ZTA6YjE6OWI6CisgICAgICogICAgICAgICA3NjoyYTo2ZDoyODo1NjphMzo4YzpjZDplOTplYzoyMTowMDo3MTpmMDo1ZjpkZDo1MDphNToKKyAgICAgKiAgICAgICAgIDY5OjQyOjFiOjgzOjExOjVkOjg0OjI4OmQzOjI3OmFlOmVjOjJhOmFiOjJmOjYwOjQyOmM1OgorICAgICAqICAgICAgICAgYzQ6NzgKKyAgICAgKiA8L3ByZT4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgc2lnbmVkQ2VydDFDaGFpbjIgPQorICAgICAgICAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICsgIk1JSUZVVENDQkxxZ0F3SUJBZ0lRWDZhK2dMYUd4aThCN1F5cnNaYWhCVEFOQmdrcWhraUc5dzBCQVFVRkFEQ0JcbiIKKyAgICAgICAgKyAiempFTE1Ba0dBMVVFQmhNQ1drRXhGVEFUQmdOVkJBZ1RERmRsYzNSbGNtNGdRMkZ3WlRFU01CQUdBMVVFQnhNSlxuIgorICAgICAgICArICJRMkZ3WlNCVWIzZHVNUjB3R3dZRFZRUUtFeFJVYUdGM2RHVWdRMjl1YzNWc2RHbHVaeUJqWXpFb01DWUdBMVVFXG4iCisgICAgICAgICsgIkN4TWZRMlZ5ZEdsbWFXTmhkR2x2YmlCVFpYSjJhV05sY3lCRWFYWnBjMmx2YmpFaE1COEdBMVVFQXhNWVZHaGhcbiIKKyAgICAgICAgKyAiZDNSbElGQnlaVzFwZFcwZ1UyVnlkbVZ5SUVOQk1TZ3dKZ1lKS29aSWh2Y05BUWtCRmhsd2NtVnRhWFZ0TFhObFxuIgorICAgICAgICArICJjblpsY2tCMGFHRjNkR1V1WTI5dE1CNFhEVEEyTVRFeE56QXdNREF3TUZvWERUSXdNVEl6TURJek5UazFPVm93XG4iCisgICAgICAgICsgImdha3hDekFKQmdOVkJBWVRBbFZUTVJVd0V3WURWUVFLRXd4MGFHRjNkR1VzSUVsdVl5NHhLREFtQmdOVkJBc1RcbiIKKyAgICAgICAgKyAiSDBObGNuUnBabWxqWVhScGIyNGdVMlZ5ZG1salpYTWdSR2wyYVhOcGIyNHhPREEyQmdOVkJBc1RMeWhqS1NBeVxuIgorICAgICAgICArICJNREEySUhSb1lYZDBaU3dnU1c1akxpQXRJRVp2Y2lCaGRYUm9iM0pwZW1Wa0lIVnpaU0J2Ym14NU1SOHdIUVlEXG4iCisgICAgICAgICsgIlZRUURFeFowYUdGM2RHVWdVSEpwYldGeWVTQlNiMjkwSUVOQk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NcbiIKKyAgICAgICAgKyAiQVE4QU1JSUJDZ0tDQVFFQXJLRHcrNEJaMUp6SHBNK2RvVmx6Q1JCRkRBMHNibWp4YkZ0SWFFbFpOL3dMTXhuQ1xuIgorICAgICAgICArICJkMy9NRUMyVk5Cem02MDBKcHh6U3VNbVhOZ0szaWRRa1h3YkF6RVNVbEkwQ1ltL3JXdDBSalNpYVhJU1FFSG9OXG4iCisgICAgICAgICsgInZYUm1MMm80b09MVlZFVHJIUWVmQjdwdjd1bjlUZ3NwOVQ2RW9BSHhuS3Y0SEg2SnBPaWgySEZsRGFOUmUrNjhcbiIKKyAgICAgICAgKyAiMGlKZ0RibGJuZCs2L0ZGYkM2K1lzdWt1NlFUb1lvZmVLOGpYVHNGTVpCN2R6NGRZdWtwUHltZ0hIUnlkU3NiVlxuIgorICAgICAgICArICJMNUhNZkhGeUhNWEFaK3N5L2NtU1hKVGFoY0NidjFOOUt3bjBqSjJSSDVkcVVzdmVDVGFrZDloN2gxQkUxVDV1XG4iCisgICAgICAgICsgIktXbjdPVWttSGdtbGdIdEFMZXZvSjRYSi9tSDlmdVo4bHgzVm5RSURBUUFCbzRJQnpUQ0NBY2t3RHdZRFZSMFRcbiIKKyAgICAgICAgKyAiQVFIL0JBVXdBd0VCL3pBN0JnTlZIU0FFTkRBeU1EQUdCRlVkSUFBd0tEQW1CZ2dyQmdFRkJRY0NBUllhYUhSMFxuIgorICAgICAgICArICJjSE02THk5M2QzY3VkR2hoZDNSbExtTnZiUzlqY0hNd0RnWURWUjBQQVFIL0JBUURBZ0VHTUIwR0ExVWREZ1FXXG4iCisgICAgICAgICsgIkJCUjdXMFhQcjg3TGV2MHhraHBxdHZORzYxZElVREJBQmdOVkhSOEVPVEEzTURXZ002QXhoaTlvZEhSd09pOHZcbiIKKyAgICAgICAgKyAiWTNKc0xuUm9ZWGQwWlM1amIyMHZWR2hoZDNSbFVISmxiV2wxYlZObGNuWmxja05CTG1OeWJEQWdCZ05WSFNVRVxuIgorICAgICAgICArICJHVEFYQmdsZ2hrZ0JodmhDQkFFR0NtQ0dTQUdHK0VVQkNBRXdnZVVHQTFVZEl3U0IzVENCMnFHQjFLU0IwVENCXG4iCisgICAgICAgICsgInpqRUxNQWtHQTFVRUJoTUNXa0V4RlRBVEJnTlZCQWdUREZkbGMzUmxjbTRnUTJGd1pURVNNQkFHQTFVRUJ4TUpcbiIKKyAgICAgICAgKyAiUTJGd1pTQlViM2R1TVIwd0d3WURWUVFLRXhSVWFHRjNkR1VnUTI5dWMzVnNkR2x1WnlCall6RW9NQ1lHQTFVRVxuIgorICAgICAgICArICJDeE1mUTJWeWRHbG1hV05oZEdsdmJpQlRaWEoyYVdObGN5QkVhWFpwYzJsdmJqRWhNQjhHQTFVRUF4TVlWR2hoXG4iCisgICAgICAgICsgImQzUmxJRkJ5WlcxcGRXMGdVMlZ5ZG1WeUlFTkJNU2d3SmdZSktvWklodmNOQVFrQkZobHdjbVZ0YVhWdExYTmxcbiIKKyAgICAgICAgKyAiY25abGNrQjBhR0YzZEdVdVkyOXRnZ0VCTUEwR0NTcUdTSWIzRFFFQkJRVUFBNEdCQUN2S0VzbmQxOHhqSEpzeFxuIgorICAgICAgICArICJOVXJkNUxmMm5kR2sreDc0Ui9tdUI0NE5XQkw3MnUyMXpEUGxsMmhIWVVMVlpxbHVIa2UvaGR0OVdORjNXc3lRXG4iCisgICAgICAgICsgIllaaWFLZldkc2MrNDNQTjdnRWRJMFgzMGFJekVRY3UwNmYzd0krQ3htM1lxYlNoV280ek42ZXdoQUhId1g5MVFcbiIKKyAgICAgICAgKyAicFdsQ0c0TVJYWVFvMHlldTdDcXJMMkJDeGNSNFxuIgorICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tIjsKKworICAgIC8qKgorICAgICAqIEEgY2VydGlmaWNhdGUgc2lnbmVkIGJ5IHNpZ25lZENlcnQxQ2hhaW4yCisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqIENlcnRpZmljYXRlOgorICAgICAqICAgICBEYXRhOgorICAgICAqICAgICAgICAgVmVyc2lvbjogMyAoMHgyKQorICAgICAqICAgICAgICAgU2VyaWFsIE51bWJlcjoKKyAgICAgKiAgICAgICAgICAgICA3YjoxMTo1NTplYjo3ODo5YTo5MDo4NTpiNTo4Yzo5MjpmZjo0MjpiNzpmZTo1NgorICAgICAqICAgICAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICogICAgICAgICBJc3N1ZXI6IEM9VVMsIE89dGhhd3RlLCBJbmMuLCBPVT1DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uLCBPVT0oYykgMjAwNiB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seSwgQ049dGhhd3RlIFByaW1hcnkgUm9vdCBDQQorICAgICAqICAgICAgICAgVmFsaWRpdHkKKyAgICAgKiAgICAgICAgICAgICBOb3QgQmVmb3JlOiBOb3YgMTcgMDA6MDA6MDAgMjAwNiBHTVQKKyAgICAgKiAgICAgICAgICAgICBOb3QgQWZ0ZXIgOiBOb3YgMTYgMjM6NTk6NTkgMjAxNiBHTVQKKyAgICAgKiAgICAgICAgIFN1YmplY3Q6IEM9VVMsIE89dGhhd3RlLCBJbmMuLCBPVT1UZXJtcyBvZiB1c2UgYXQgaHR0cHM6Ly93d3cudGhhd3RlLmNvbS9jcHMgKGMpMDYsIENOPXRoYXd0ZSBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBDQQorICAgICAqICAgICAgICAgU3ViamVjdCBQdWJsaWMgS2V5IEluZm86CisgICAgICogICAgICAgICAgICAgUHVibGljIEtleSBBbGdvcml0aG06IHJzYUVuY3J5cHRpb24KKyAgICAgKiAgICAgICAgICAgICBSU0EgUHVibGljIEtleTogKDIwNDggYml0KQorICAgICAqICAgICAgICAgICAgICAgICBNb2R1bHVzICgyMDQ4IGJpdCk6CisgICAgICogICAgICAgICAgICAgICAgICAgICAwMDpiNTo4ZDo0NzpmNzpiMDo0ODo3Njo5YjpiZDpmYjphOTpjYjpiZjowNDoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDMxOmEyOjNkOjlhOjdlOjMwOjI5OmQzOjI4OmI4OmZlOjY4OmNlOmNmOmU5OgorICAgICAqICAgICAgICAgICAgICAgICAgICAgMzA6NmE6NTM6OTU6MGU6NTA6NjU6ODA6MjY6Yzk6OTg6YmY6ZjI6MTQ6ZmY6CisgICAgICogICAgICAgICAgICAgICAgICAgICAwNjo3Yzo2YTo3YjpkYzo1MDowNzplMjo5ODpmYTpkZjpjZjozMDo1ZDpjYToKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGE4OmI5OjhhOjliOjJkOjJkOjdlOjU5OjhiOjFhOmY3OmIzOmM5OmMzOjY5OgorICAgICAqICAgICAgICAgICAgICAgICAgICAgODA6MGY6ODk6MTk6MDg6Nzc6YjI6NTI6NTU6YWQ6Nzg6ODM6OWQ6NmI6Yjk6CisgICAgICogICAgICAgICAgICAgICAgICAgICA4NzplNDo1MzoyNDozNzoyYzpmYzoxOTowZTo4Yjo3OToxNDo0ZDpiZTo4MDoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDllOmI0OjliOjczOjc0OjMxOmYyOjM4OmVjOjhhOmFmOjJhOjM2OjhlOjY0OgorICAgICAqICAgICAgICAgICAgICAgICAgICAgY2U6MzE6MjY6MTQ6MDM6NTQ6NTM6OGU6ZmI6ODQ6MDg6YzE6N2U6NDc6MzI6CisgICAgICogICAgICAgICAgICAgICAgICAgICAzZDo3MTplMDpiYTpiYTo4Yzo4Mjo1ODo5Njo0ZDo2ODo0Mzo1NjoxYTpmMzoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDQ2OjVhOjMyOjk5Ojk1OmIwOjYwOjZmOmU5OjQxOjhhOjQ4OmNjOjE2OjBkOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgNDQ6Njg6YjE6OGE6ZGQ6ZGQ6MTc6M2Q6YTQ6OWI6Nzg6N2Y6MmU6Mjk6MDY6CisgICAgICogICAgICAgICAgICAgICAgICAgICBmMDpkYzpkNTpkMjoxMzozZjpjMDozNjowNTpmZDpjNzpiNTpiOTo4MDoxYjoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDhhOjQ2Ojc0OjJmOmYxOmFiOjc5OjllOjk3OjZlOmY4OmE1OjEzOjVhOmYzOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgZmM6YjU6ZDc6Yzg6OTY6MTk6Mzc6ZWU6MDY6YmM6YzY6Mjc6MTQ6ODE6MDU6CisgICAgICogICAgICAgICAgICAgICAgICAgICAxNDozMzozODoxNjo5Zjo0YjplMjowZjpkYjozODpiYjpmMzowMTplZjozNToKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDJlOmRlOmFmOmYxOmU0OjZmOjZmOmY3Ojk2OjAwOjU2OjVlOjhmOjYwOjk0OgorICAgICAqICAgICAgICAgICAgICAgICAgICAgMWQ6MmYKKyAgICAgKiAgICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQorICAgICAqICAgICAgICAgWDUwOXYzIGV4dGVuc2lvbnM6CisgICAgICogICAgICAgICAgICAgQXV0aG9yaXR5IEluZm9ybWF0aW9uIEFjY2VzczoKKyAgICAgKiAgICAgICAgICAgICAgICAgT0NTUCAtIFVSSTpodHRwOi8vRVZTZWN1cmUtb2NzcC50aGF3dGUuY29tCisgICAgICogICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOiBjcml0aWNhbAorICAgICAqICAgICAgICAgICAgICAgICBDQTpUUlVFLCBwYXRobGVuOjAKKyAgICAgKiAgICAgICAgICAgICBYNTA5djMgQ2VydGlmaWNhdGUgUG9saWNpZXM6CisgICAgICogICAgICAgICAgICAgICAgIFBvbGljeTogWDUwOXYzIEFueSBQb2xpY3kKKyAgICAgKiAgICAgICAgICAgICAgICAgICBDUFM6IGh0dHBzOi8vd3d3LnRoYXd0ZS5jb20vY3BzCisgICAgICogICAgICAgICAgICAgWDUwOXYzIENSTCBEaXN0cmlidXRpb24gUG9pbnRzOgorICAgICAqICAgICAgICAgICAgICAgICBVUkk6aHR0cDovL2NybC50aGF3dGUuY29tL1RoYXd0ZVBDQS5jcmwKKyAgICAgKiAgICAgICAgICAgICBYNTA5djMgS2V5IFVzYWdlOiBjcml0aWNhbAorICAgICAqICAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBTaWduLCBDUkwgU2lnbgorICAgICAqICAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEFsdGVybmF0aXZlIE5hbWU6CisgICAgICogICAgICAgICAgICAgICAgIERpck5hbWU6L0NOPVByaXZhdGVMYWJlbDMtMjA0OC0yMzQKKyAgICAgKiAgICAgICAgICAgICBYNTA5djMgU3ViamVjdCBLZXkgSWRlbnRpZmllcjoKKyAgICAgKiAgICAgICAgICAgICAgICAgQ0Q6MzI6RTI6RjI6NUQ6MjU6NDc6MDI6QUE6OEY6Nzk6NEI6MzI6RUU6MDM6OTk6RkQ6MzA6NDk6RDEKKyAgICAgKiAgICAgICAgICAgICBYNTA5djMgQXV0aG9yaXR5IEtleSBJZGVudGlmaWVyOgorICAgICAqICAgICAgICAgICAgICAgICBrZXlpZDo3Qjo1Qjo0NTpDRjpBRjpDRTpDQjo3QTpGRDozMTo5MjoxQTo2QTpCNjpGMzo0NjpFQjo1Nzo0ODo1MAorICAgICAqICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgKiAgICAgICAgIDBiOmI0Ojk2OmNlOjAzOjBjOmQxOjlkOmFmOmNiOmUzOjM5OjU2OjBkOmM2OjIyOmEwOmM5OgorICAgICAqICAgICAgICAgNzE6N2Q6ZWE6NjU6OTU6MzE6ZjE6ZGM6YjY6MWU6ZjI6OGQ6MzE6NWQ6NjE6YjM6NTQ6ODQ6CisgICAgICogICAgICAgICAxMzpjYzoyYjozZjowMjo1YzpjNzoxZjoxNTowMTo4Mjo5MDoxZTozMToyNTowNjplMzozMjoKKyAgICAgKiAgICAgICAgIDBjOjg3OmYwOmMzOmJlOjlhOmM0OjAwOjQxOmY2OmM2OjkxOmU1OjZjOjNlOjkyOjVkOmEzOgorICAgICAqICAgICAgICAgZTQ6M2Q6MWY6MzI6MmQ6MzE6MWU6NTA6YzE6MDI6MjE6YjQ6MjM6ZTM6MDc6NzU6OWE6NTI6CisgICAgICogICAgICAgICA0NTo1MTpmYTpkMzoxZDpmZDowMTo2Zjo2MDo2ZDoyNTpkOTpiZjo0MzpiMTphNzo0Mzo2YzoKKyAgICAgKiAgICAgICAgIGFkOjhjOmJiOmJjOmY3Ojk5OjQxOmViOmQ2Ojk1OmNmOjIwOjVjOjdlOjZmOmM0OjJhOmRhOgorICAgICAqICAgICAgICAgNGI6NGQ6MWI6NWI6YzI6OWY6YjA6OTQ6ZDQ6YmY6NDc6OTc6ZmQ6OWQ6NDk6Nzk6NjA6OGU6CisgICAgICogICAgICAgICBhZTo5NjoxOTphMTpiMDplYjplODpkZjo0MjpjNzoyMjo3NDo2MTowYzoyNTphMzo3Zjo4ZjoKKyAgICAgKiAgICAgICAgIDQ1OmQyOjdlOmU3OjRhOjZlOjFkOjRmOjQ4OmJiOmMyOmRhOjFhOjdlOjRhOjU5OjgxOmZhOgorICAgICAqICAgICAgICAgMWM6ZTM6ZmI6MTQ6NzM6NDE6MDM6YTE6Nzc6ZmE6OWI6MDY6ZmM6N2M6MzM6YmQ6NDY6M2Q6CisgICAgICogICAgICAgICAwYzowNjoxNzo4NTo3YjoyYTo3YjplMzozNjplODo4MzpkZjpmYTphYTpjYjozMjowYzo3OToKKyAgICAgKiAgICAgICAgIGFhOjg2Ojc0OjZjOjQ0OjU0OmY2OmQ4OjA3OjllOmNkOjk4OmY0OjIzOjA1OjA5OjJmOmEyOgorICAgICAqICAgICAgICAgNTM6YjU6ZGI6MGE6ODE6Y2M6NWY6MjM6Y2I6Nzk6MTE6YzU6MTE6NWI6ODU6NmI6Mjc6MDE6CisgICAgICogICAgICAgICA4OTpmMzowZTpiYgorICAgICAqIDwvcHJlPgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBzaWduZWRDZXJ0MkNoYWluMiA9CisgICAgICAgICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgKyAiTUlJRkNqQ0NBL0tnQXdJQkFnSVFleEZWNjNpYWtJVzFqSkwvUXJmK1ZqQU5CZ2txaGtpRzl3MEJBUVVGQURDQlxuIgorICAgICAgICArICJxVEVMTUFrR0ExVUVCaE1DVlZNeEZUQVRCZ05WQkFvVERIUm9ZWGQwWlN3Z1NXNWpMakVvTUNZR0ExVUVDeE1mXG4iCisgICAgICAgICsgIlEyVnlkR2xtYVdOaGRHbHZiaUJUWlhKMmFXTmxjeUJFYVhacGMybHZiakU0TURZR0ExVUVDeE12S0dNcElESXdcbiIKKyAgICAgICAgKyAiTURZZ2RHaGhkM1JsTENCSmJtTXVJQzBnUm05eUlHRjFkR2h2Y21sNlpXUWdkWE5sSUc5dWJIa3hIekFkQmdOVlxuIgorICAgICAgICArICJCQU1URm5Sb1lYZDBaU0JRY21sdFlYSjVJRkp2YjNRZ1EwRXdIaGNOTURZeE1URTNNREF3TURBd1doY05NVFl4XG4iCisgICAgICAgICsgIk1URTJNak0xT1RVNVdqQ0JpekVMTUFrR0ExVUVCaE1DVlZNeEZUQVRCZ05WQkFvVERIUm9ZWGQwWlN3Z1NXNWpcbiIKKyAgICAgICAgKyAiTGpFNU1EY0dBMVVFQ3hNd1ZHVnliWE1nYjJZZ2RYTmxJR0YwSUdoMGRIQnpPaTh2ZDNkM0xuUm9ZWGQwWlM1alxuIgorICAgICAgICArICJiMjB2WTNCeklDaGpLVEEyTVNvd0tBWURWUVFERXlGMGFHRjNkR1VnUlhoMFpXNWtaV1FnVm1Gc2FXUmhkR2x2XG4iCisgICAgICAgICsgImJpQlRVMHdnUTBFd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUMxalVmM3NFaDJcbiIKKyAgICAgICAgKyAibTczN3FjdS9CREdpUFpwK01DblRLTGorYU03UDZUQnFVNVVPVUdXQUpzbVl2L0lVL3daOGFudmNVQWZpbVByZlxuIgorICAgICAgICArICJ6ekJkeXFpNWlwc3RMWDVaaXhyM3M4bkRhWUFQaVJrSWQ3SlNWYTE0ZzUxcnVZZmtVeVEzTFB3WkRvdDVGRTIrXG4iCisgICAgICAgICsgImdKNjBtM04wTWZJNDdJcXZLamFPWk00eEpoUURWRk9PKzRRSXdYNUhNajF4NExxNmpJSllsazFvUTFZYTgwWmFcbiIKKyAgICAgICAgKyAiTXBtVnNHQnY2VUdLU013V0RVUm9zWXJkM1JjOXBKdDRmeTRwQnZEYzFkSVRQOEEyQmYzSHRibUFHNHBHZEMveFxuIgorICAgICAgICArICJxM21lbDI3NHBSTmE4L3kxMThpV0dUZnVCcnpHSnhTQkJSUXpPQmFmUytJUDJ6aTc4d0h2TlM3ZXIvSGtiMi8zXG4iCisgICAgICAgICsgImxnQldYbzlnbEIwdkFnTUJBQUdqZ2dGSU1JSUJSREE3QmdnckJnRUZCUWNCQVFRdk1DMHdLd1lJS3dZQkJRVUhcbiIKKyAgICAgICAgKyAiTUFHR0gyaDBkSEE2THk5RlZsTmxZM1Z5WlMxdlkzTndMblJvWVhkMFpTNWpiMjB3RWdZRFZSMFRBUUgvQkFnd1xuIgorICAgICAgICArICJCZ0VCL3dJQkFEQTdCZ05WSFNBRU5EQXlNREFHQkZVZElBQXdLREFtQmdnckJnRUZCUWNDQVJZYWFIUjBjSE02XG4iCisgICAgICAgICsgIkx5OTNkM2N1ZEdoaGQzUmxMbU52YlM5amNITXdOQVlEVlIwZkJDMHdLekFwb0NlZ0pZWWphSFIwY0RvdkwyTnlcbiIKKyAgICAgICAgKyAiYkM1MGFHRjNkR1V1WTI5dEwxUm9ZWGQwWlZCRFFTNWpjbXd3RGdZRFZSMFBBUUgvQkFRREFnRUdNQzRHQTFVZFxuIgorICAgICAgICArICJFUVFuTUNXa0l6QWhNUjh3SFFZRFZRUURFeFpRY21sMllYUmxUR0ZpWld3ekxUSXdORGd0TWpNME1CMEdBMVVkXG4iCisgICAgICAgICsgIkRnUVdCQlROTXVMeVhTVkhBcXFQZVVzeTdnT1ovVEJKMFRBZkJnTlZIU01FR0RBV2dCUjdXMFhQcjg3TGV2MHhcbiIKKyAgICAgICAgKyAia2hwcXR2Tkc2MWRJVURBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQUM3U1d6Z01NMFoydnkrTTVWZzNHSXFESlxuIgorICAgICAgICArICJjWDNxWlpVeDhkeTJIdktOTVYxaHMxU0VFOHdyUHdKY3h4OFZBWUtRSGpFbEJ1TXlESWZ3dzc2YXhBQkI5c2FSXG4iCisgICAgICAgICsgIjVXdytrbDJqNUQwZk1pMHhIbERCQWlHMEkrTUhkWnBTUlZINjB4MzlBVzlnYlNYWnYwT3hwME5zcll5N3ZQZVpcbiIKKyAgICAgICAgKyAiUWV2V2xjOGdYSDV2eENyYVMwMGJXOEtmc0pUVXYwZVgvWjFKZVdDT3JwWVpvYkRyNk45Q3h5SjBZUXdsbzMrUFxuIgorICAgICAgICArICJSZEorNTBwdUhVOUl1OExhR241S1dZSDZIT1A3RkhOQkE2RjMrcHNHL0h3enZVWTlEQVlYaFhzcWUrTTI2SVBmXG4iCisgICAgICAgICsgIitxckxNZ3g1cW9aMGJFUlU5dGdIbnMyWTlDTUZDUytpVTdYYkNvSE1YeVBMZVJIRkVWdUZheWNCaWZNT3V3PT1cbiIKKyAgICAgICAgKyAiLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLSI7CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmVyaWZ5TUQ1KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFByb3ZpZGVyW10gcHJvdmlkZXJzID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKCJDZXJ0aWZpY2F0ZUZhY3RvcnkuWDUwOSIpOworICAgICAgICBmb3IgKFByb3ZpZGVyIHByb3ZpZGVyIDogcHJvdmlkZXJzKSB7CisgICAgICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2VydGlmaWNhdGVGYWN0b3J5ID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYNTA5IiwgcHJvdmlkZXIpOworCisgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBjZXJ0aWZpY2F0ZSA9IGNlcnRpZmljYXRlRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc2VsZlNpZ25lZENlcnRNRDUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0Qnl0ZXMoKSkpOworCisgICAgICAgICAgICBjZXJ0aWZpY2F0ZS52ZXJpZnkoY2VydGlmaWNhdGUuZ2V0UHVibGljS2V5KCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQEFuZHJvaWRPbmx5KCJNRDIgaXMgbm90IHN1cHBvcnRlZCBieSBBbmRyb2lkIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmVyaWZ5TUQyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFByb3ZpZGVyW10gcHJvdmlkZXJzID0gU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKCJDZXJ0aWZpY2F0ZUZhY3RvcnkuWDUwOSIpOworICAgICAgICBmb3IgKFByb3ZpZGVyIHByb3ZpZGVyIDogcHJvdmlkZXJzKSB7CisgICAgICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2VydGlmaWNhdGVGYWN0b3J5ID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYNTA5IiwgcHJvdmlkZXIpOworCisgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBjZXJ0aWZpY2F0ZSA9IGNlcnRpZmljYXRlRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc2VsZlNpZ25lZENlcnRNRDIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0Qnl0ZXMoKSkpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjZXJ0aWZpY2F0ZS52ZXJpZnkoY2VydGlmaWNhdGUuZ2V0UHVibGljS2V5KCkpOworICAgICAgICAgICAgICAgIGZhaWwoIk1EMiBzaG91bGQgbm90IGJlIGFsbG93ZWQiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHByb3ZpZGVyLmdldE5hbWUoKSwgZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmVyaWZ5TUQyX2NoYWluKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZXJ0aWZpY2F0ZUZhY3RvcnkgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlg1MDkiKTsKKworICAgICAgICAvLyBGaXJzdCBjaGVjayB3aXRoIHRoZSB0cnVzdCBhbmNob3Igbm90IGluY2x1ZGVkIGluIHRoZSBjaGFpbgorICAgICAgICBDZXJ0UGF0aCBwYXRoID0gY2VydGlmaWNhdGVGYWN0b3J5LmdlbmVyYXRlQ2VydFBhdGgoZ2V0Q2VydExpc3QodHJ1ZSwgZmFsc2UpKTsKKworICAgICAgICBDZXJ0UGF0aFZhbGlkYXRvciBjZXJ0UGF0aFZhbGlkYXRvciA9IENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKCJQS0lYIik7CisgICAgICAgIFBLSVhQYXJhbWV0ZXJzIHBhcmFtcyA9IGNyZWF0ZVBLSVhQYXJhbXMoKTsKKworICAgICAgICBDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCByZXMgPSBjZXJ0UGF0aFZhbGlkYXRvci52YWxpZGF0ZShwYXRoLCBwYXJhbXMpOworICAgICAgICBhc3NlcnRUcnVlKCJ3cm9uZyByZXN1bHQgdHlwZSIsCisgICAgICAgICAgICAgICAgICAgcmVzIGluc3RhbmNlb2YgUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0KTsKKworICAgICAgICBQS0lYQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHQgciA9IChQS0lYQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHQpIHJlczsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiV3JvbmcgdHJ1c3QgYW5jaG9yIHJldHVybmVkIiwKKyAgICAgICAgICAgICAgICAgICBwYXJhbXMuZ2V0VHJ1c3RBbmNob3JzKCkuY29udGFpbnMoci5nZXRUcnVzdEFuY2hvcigpKSk7CisKKyAgICAgICAgLy8gTm93IGNoZWNrIHdpdGggdGhlIHRydXN0IGFuY2hvciBpbmNsdWRlZCBpbiB0aGUgY2hhaW4KKyAgICAgICAgcGF0aCA9IGNlcnRpZmljYXRlRmFjdG9yeS5nZW5lcmF0ZUNlcnRQYXRoKGdldENlcnRMaXN0KHRydWUsIHRydWUpKTsKKworICAgICAgICBjZXJ0UGF0aFZhbGlkYXRvciA9IENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKCJQS0lYIik7CisgICAgICAgIHBhcmFtcyA9IGNyZWF0ZVBLSVhQYXJhbXMoKTsKKworICAgICAgICBpZiAoU3RhbmRhcmROYW1lcy5JU19SSSkgeworICAgICAgICAgICAgcmVzID0gY2VydFBhdGhWYWxpZGF0b3IudmFsaWRhdGUocGF0aCwgcGFyYW1zKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIndyb25nIHJlc3VsdCB0eXBlIiwgcmVzIGluc3RhbmNlb2YgUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0KTsKKworICAgICAgICAgICAgciA9IChQS0lYQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHQpIHJlczsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIldyb25nIHRydXN0IGFuY2hvciByZXR1cm5lZCIsCisgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcy5nZXRUcnVzdEFuY2hvcnMoKS5jb250YWlucyhyLmdldFRydXN0QW5jaG9yKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2VydFBhdGhWYWxpZGF0b3IudmFsaWRhdGUocGF0aCwgcGFyYW1zKTsKKyAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFZlcmlmeU1ENV9jaGFpbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2VydGlmaWNhdGVGYWN0b3J5ID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYNTA5Iik7CisKKyAgICAgICAgLy8gRmlyc3QgY2hlY2sgd2l0aCB0aGUgdHJ1c3QgYW5jaG9yIG5vdCBpbmNsdWRlZCBpbiB0aGUgY2hhaW4KKyAgICAgICAgQ2VydFBhdGggcGF0aCA9IGNlcnRpZmljYXRlRmFjdG9yeS5nZW5lcmF0ZUNlcnRQYXRoKGdldENlcnRMaXN0KGZhbHNlLCBmYWxzZSkpOworCisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yIGNlcnRQYXRoVmFsaWRhdG9yID0gQ2VydFBhdGhWYWxpZGF0b3IuZ2V0SW5zdGFuY2UoIlBLSVgiKTsKKyAgICAgICAgUEtJWFBhcmFtZXRlcnMgcGFyYW1zID0gY3JlYXRlUEtJWFBhcmFtcygpOworCisgICAgICAgIENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0IHJlcyA9IGNlcnRQYXRoVmFsaWRhdG9yLnZhbGlkYXRlKHBhdGgsIHBhcmFtcyk7CisgICAgICAgIGFzc2VydFRydWUoIndyb25nIHJlc3VsdCB0eXBlIiwKKyAgICAgICAgICAgICAgICAgICByZXMgaW5zdGFuY2VvZiBQS0lYQ2VydFBhdGhWYWxpZGF0b3JSZXN1bHQpOworCisgICAgICAgIFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCByID0gKFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCkgcmVzOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyB0cnVzdCBhbmNob3IgcmV0dXJuZWQiLAorICAgICAgICAgICAgICAgICAgIHBhcmFtcy5nZXRUcnVzdEFuY2hvcnMoKS5jb250YWlucyhyLmdldFRydXN0QW5jaG9yKCkpKTsKKworICAgICAgICAvLyBOb3cgY2hlY2sgd2l0aCB0aGUgdHJ1c3QgYW5jaG9yIGluY2x1ZGVkIGluIHRoZSBjaGFpbgorICAgICAgICBwYXRoID0gY2VydGlmaWNhdGVGYWN0b3J5LmdlbmVyYXRlQ2VydFBhdGgoZ2V0Q2VydExpc3QoZmFsc2UsIHRydWUpKTsKKworICAgICAgICBjZXJ0UGF0aFZhbGlkYXRvciA9IENlcnRQYXRoVmFsaWRhdG9yLmdldEluc3RhbmNlKCJQS0lYIik7CisgICAgICAgIHBhcmFtcyA9IGNyZWF0ZVBLSVhQYXJhbXMoKTsKKworICAgICAgICByZXMgPSBjZXJ0UGF0aFZhbGlkYXRvci52YWxpZGF0ZShwYXRoLCBwYXJhbXMpOworICAgICAgICBhc3NlcnRUcnVlKCJ3cm9uZyByZXN1bHQgdHlwZSIsCisgICAgICAgICAgICAgICAgcmVzIGluc3RhbmNlb2YgUEtJWENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0KTsKKworICAgICAgICByID0gKFBLSVhDZXJ0UGF0aFZhbGlkYXRvclJlc3VsdCkgcmVzOworICAgICAgICBhc3NlcnRUcnVlKCJXcm9uZyB0cnVzdCBhbmNob3IgcmV0dXJuZWQiLAorICAgICAgICAgICAgICAgICAgIHBhcmFtcy5nZXRUcnVzdEFuY2hvcnMoKS5jb250YWlucyhyLmdldFRydXN0QW5jaG9yKCkpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFg1MDlDZXJ0aWZpY2F0ZVtdIGNlcnRzPSBuZXcgWDUwOUNlcnRpZmljYXRlWzNdOworCisgICAgcHJpdmF0ZSBMaXN0PENlcnRpZmljYXRlPiBnZXRDZXJ0TGlzdChib29sZWFuIHVzZU1EMnJvb3QsCisgICAgICAgICAgICBib29sZWFuIGluY2x1ZGVSb290SW5DaGFpbikgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNlcnRpZmljYXRlRmFjdG9yeSA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWDUwOSIpOworCisgICAgICAgIGlmICh1c2VNRDJyb290KSB7CisgICAgICAgICAgICBjZXJ0c1swXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNlcnRpZmljYXRlRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZlNpZ25lZENlcnRNRDIuZ2V0Qnl0ZXMoKSkpOworICAgICAgICAgICAgY2VydHNbMV0gPSAoWDUwOUNlcnRpZmljYXRlKSBjZXJ0aWZpY2F0ZUZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdlbmVyYXRlQ2VydGlmaWNhdGUobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ25lZENlcnQxQ2hhaW4xLmdldEJ5dGVzKCkpKTsKKyAgICAgICAgICAgIGNlcnRzWzJdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2VydGlmaWNhdGVGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduZWRDZXJ0MkNoYWluMS5nZXRCeXRlcygpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjZXJ0c1swXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNlcnRpZmljYXRlRmFjdG9yeQorICAgICAgICAgICAgICAgICAgICAuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZlNpZ25lZENlcnRNRDUuZ2V0Qnl0ZXMoKSkpOworICAgICAgICAgICAgY2VydHNbMV0gPSAoWDUwOUNlcnRpZmljYXRlKSBjZXJ0aWZpY2F0ZUZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgLmdlbmVyYXRlQ2VydGlmaWNhdGUobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ25lZENlcnQxQ2hhaW4yLmdldEJ5dGVzKCkpKTsKKyAgICAgICAgICAgIGNlcnRzWzJdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2VydGlmaWNhdGVGYWN0b3J5CisgICAgICAgICAgICAgICAgICAgIC5nZW5lcmF0ZUNlcnRpZmljYXRlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduZWRDZXJ0MkNoYWluMi5nZXRCeXRlcygpKSk7CisgICAgICAgIH0KKworICAgICAgICBBcnJheUxpc3Q8Q2VydGlmaWNhdGU+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8Q2VydGlmaWNhdGU+KCk7CisgICAgICAgIHJlc3VsdC5hZGQoY2VydHNbMl0pOworICAgICAgICByZXN1bHQuYWRkKGNlcnRzWzFdKTsKKyAgICAgICAgaWYgKGluY2x1ZGVSb290SW5DaGFpbikgeworICAgICAgICAgICAgcmVzdWx0LmFkZChjZXJ0c1swXSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcml2YXRlIFBLSVhQYXJhbWV0ZXJzIGNyZWF0ZVBLSVhQYXJhbXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgS2V5U3RvcmUga2V5U3RvcmUgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAga2V5U3RvcmUubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAga2V5U3RvcmUuc2V0Q2VydGlmaWNhdGVFbnRyeSgic2VsZlNpZ25lZENlcnQiLCBjZXJ0c1swXSk7CisKKyAgICAgICAgUEtJWFBhcmFtZXRlcnMgcGFyYW1zOworICAgICAgICBwYXJhbXMgPSBuZXcgUEtJWFBhcmFtZXRlcnMoa2V5U3RvcmUpOworICAgICAgICBwYXJhbXMuc2V0UmV2b2NhdGlvbkVuYWJsZWQoZmFsc2UpOworICAgICAgICByZXR1cm4gcGFyYW1zOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL0hlbGxvV29ybGQudHh0IGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvSGVsbG9Xb3JsZC50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzQ5ZGIyYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL0hlbGxvV29ybGQudHh0CkBAIC0wLDAgKzEgQEAKK0hlbGxvLCBXb3JsZC4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL01FVEEtSU5GL3NlcnZpY2VzL2xpYmNvcmUuamF2YS51dGlsLlNlcnZpY2VMb2FkZXJUZXN0SW50ZXJmYWNlIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvTUVUQS1JTkYvc2VydmljZXMvbGliY29yZS5qYXZhLnV0aWwuU2VydmljZUxvYWRlclRlc3RJbnRlcmZhY2UKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGY4YTllYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL01FVEEtSU5GL3NlcnZpY2VzL2xpYmNvcmUuamF2YS51dGlsLlNlcnZpY2VMb2FkZXJUZXN0SW50ZXJmYWNlCkBAIC0wLDAgKzEsNyBAQAorIyB0aGlzIGlzIGEgY29tbWVudAorIyBmb2xsb3dlZCBieSBhIGJsYW5rIGxpbmUKKworbGliY29yZS5qYXZhLnV0aWwuU2VydmljZUxvYWRlclRlc3QkSW1wbDEKK2xpYmNvcmUuamF2YS51dGlsLlNlcnZpY2VMb2FkZXJUZXN0JEltcGwyICMgdGhpcyBjb21tZW50IGlzIHZhbGlkCitsaWJjb3JlLmphdmEudXRpbC5TZXJ2aWNlTG9hZGVyVGVzdCRJbXBsMiNhcyBpcyB0aGlzCitsaWJjb3JlLmphdmEudXRpbC5TZXJ2aWNlTG9hZGVyVGVzdCRJbXBsMiAjIGFuZCBkdXBsaWNhdGVzIGFyZSBhbGxvd2VkIHRvbwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvU2ltcGxlQnVpbGRlclRlc3QueG1sIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvU2ltcGxlQnVpbGRlclRlc3QueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzZWRjZTcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9TaW1wbGVCdWlsZGVyVGVzdC54bWwKQEAgLTAsMCArMSwyMSBAQAorPD94bWwgdmVyc2lvbj0iMS4wIj8+CisKKzwhLS0gRnJhZ2lsZSEgLS0+CisKKzwhLS0gSGFuZGxlIG1lIHdpdGggY2FyZSEgLS0+CisKKzw/Y21kIFRoZSBxdWljayBicm93biBmb3ggPz4KKworPHQ6c3R1ZmYgeG1sbnM6dD0iaHR0cDovL3d3dy5mb28uYmFyIiB4bWxuczp1PSJodHRwOi8vd3d3LmJhci5mb28iPgorCisJPG5lc3RlZFN0dWZmIG9uZT0iZWlucyI+VGhpcyBzcGFjZSBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsuPC9uZXN0ZWRTdHVmZj4KKworCTxuZXN0ZWRTdHVmZiB0d289Inp3ZWkiPk5vdGhpbmcgdG8gc2VlIGhlcmUgLSBwbGVhc2UgZ2V0IGFsb25nITwvbmVzdGVkU3R1ZmY+CisKKwk8bmVzdGVkU3R1ZmYgdGhyZWU9ImRyZWkiIHRpdGxlPSIiPlJlbnQgdGhpcyBzcGFjZSE8L25lc3RlZFN0dWZmPgorCisJPG5lc3RlZFN0dWZmIHQ6Zm91cj0idmllciIvPgorCis8L3Q6c3R1ZmY+CisKKzw/Y21kIGp1bXBzIG92ZXIgdGhlIGxhenkgZG9nLj8+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9TaW1wbGVQYXJzZXJUZXN0LnhtbCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL1NpbXBsZVBhcnNlclRlc3QueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUxOGJmM2UKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9TaW1wbGVQYXJzZXJUZXN0LnhtbApAQCAtMCwwICsxLDE5IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiPz4KKworPCEtLSBUaGlzIHNwYWNlIGludGVudGlvbmFsbHkgbGVmdCBibGFuay4gLS0+CisKKzw/VGhlIHF1aWNrPz4KKworPHQ6c3R1ZmYgeG1sbnM6dD0iaHR0cDovL3d3dy5mb29iYXIub3JnIj4KKworCTxuZXN0ZWRTdHVmZiBvbmU9ImVpbnMiPiAgIFNvbWUgdGV4dCBoZXJlICAgPC9uZXN0ZWRTdHVmZj4KKworCTxuZXN0ZWRTdHVmZiB0d289Inp3ZWkiPjwvbmVzdGVkU3R1ZmY+CisKKyAgICBzb21lIG1vcmUgaGVyZS4uLgorCisJPG5lc3RlZFN0dWZmIHRocmVlPSJkcmVpIiAvPgorCis8L3Q6c3R1ZmY+CisKKzw/YnJvd24gZm94Pz4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2Jsb2IuYyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2Jsb2IuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZWExZWQ3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvYmxvYi5jCkBAIC0wLDAgKzEsMiBAQAorLyogU29tZSByYW5kb20gZmlsZS4gKi8KK0xvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ciBhZGlwaXNpY2luZyBlbGl0LCBzZWQgZG8gZWl1c21vZCB0ZW1wb3IgaW5jaWRpZHVudCB1dCBsYWJvcmUgZXQgZG9sb3JlIG1hZ25hIGFsaXF1YS4gVXQgZW5pbSBhZCBtaW5pbSB2ZW5pYW0sIHF1aXMgbm9zdHJ1ZCBleGVyY2l0YXRpb24gdWxsYW1jbyBsYWJvcmlzIG5pc2kgdXQgYWxpcXVpcCBleCBlYSBjb21tb2RvIGNvbnNlcXVhdC4gRHVpcyBhdXRlIGlydXJlIGRvbG9yIGluIHJlcHJlaGVuZGVyaXQgaW4gdm9sdXB0YXRlIHZlbGl0IGVzc2UgY2lsbHVtIGRvbG9yZSBldSBmdWdpYXQgbnVsbGEgcGFyaWF0dXIuIEV4Y2VwdGV1ciBzaW50IG9jY2FlY2F0IGN1cGlkYXRhdCBub24gcHJvaWRlbnQsIHN1bnQgaW4gY3VscGEgcXVpIG9mZmljaWEgZGVzZXJ1bnQgbW9sbGl0IGFuaW0gaWQgZXN0IGxhYm9ydW0uCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9idW5kbGVzL2phdmEvdXRpbC9sb2dnaW5nL3Jlcy5wcm9wZXJ0aWVzIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvYnVuZGxlcy9qYXZhL3V0aWwvbG9nZ2luZy9yZXMucHJvcGVydGllcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYjQ1NWIwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvYnVuZGxlcy9qYXZhL3V0aWwvbG9nZ2luZy9yZXMucHJvcGVydGllcwpAQCAtMCwwICsxLDEyIEBACitsZXZlbDE9ZW5fVVNfbGV2ZWwxCitTRVZFUkU9VVNfU0VWRVJFCitXQVJOSU5HPVVTX1dBUk5JTkcKK0NPTkZJRz1VU19DT05GSUcKK0ZJTkU9VVNfRklORQorRklORVI9VVNfRklORVIKK0ZJTkVTVD1VU19GSU5FU1QKK0FMTD1VU19BTEwKK09GRj1VU19PRkYKK21zZz1VU19NU0cKK3BhdHRlcm49VVNfcGF0dGVybiB7MCwgbnVtYmVyfQorcGF0dGVybnswLG51bWJlcn09VVMKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9idW5kbGVzL2phdmEvdXRpbC9sb2dnaW5nL3JlczIucHJvcGVydGllcyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2J1bmRsZXMvamF2YS91dGlsL2xvZ2dpbmcvcmVzMi5wcm9wZXJ0aWVzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY2ZjAyZWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9idW5kbGVzL2phdmEvdXRpbC9sb2dnaW5nL3JlczIucHJvcGVydGllcwpAQCAtMCwwICsxLDEzIEBACitsZXZlbDE9bGV2ZWwxCitTRVZFUkU9U0VWRVJFMgorV0FSTklORz1XQVJOSU5HMgorQ09ORklHPUNPTkZJRzIKK0ZJTkU9RklORTIKK0ZJTkVSPUZJTkVSMgorRklORVNUPUZJTkVTVDIKK0FMTD1BTEwyCitPRkY9T0ZGMgorbXNnPU1TRzIKK3BhdHRlcm49cGF0dGVybiB7MCwgbnVtYmVyfTIKK3BhdHRlcm57MCxudW1iZXJ9PU5PTE9DQUxFMgorTE9HR0VSVEVTVD1UZXN0X05vTG9jYWxlMgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2J1bmRsZXMvamF2YS91dGlsL2xvZ2dpbmcvcmVzMy5wcm9wZXJ0aWVzIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvYnVuZGxlcy9qYXZhL3V0aWwvbG9nZ2luZy9yZXMzLnByb3BlcnRpZXMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjdiNGIyOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2J1bmRsZXMvamF2YS91dGlsL2xvZ2dpbmcvcmVzMy5wcm9wZXJ0aWVzCkBAIC0wLDAgKzEsMTMgQEAKK2xldmVsMT1sZXZlbDEzCitTRVZFUkU9U0VWRVJFMworV0FSTklORz1XQVJOSU5HMworQ09ORklHPUNPTkZJRzMKK0ZJTkU9RklORTMKK0ZJTkVSPUZJTkVSMworRklORVNUPUZJTkVTVDMKK0FMTD1BTEwzCitPRkY9T0ZGMworbXNnPU1TRzMKK3BhdHRlcm49cGF0dGVybiB7MCwgbnVtYmVyfTMKK3BhdHRlcm57MCxudW1iZXJ9PU5PTE9DQUxFMworTE9HR0VSVEVTVD1UZXN0X05vTG9jYWxlMwpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2J1bmRsZXMvamF2YS91dGlsL2xvZ2dpbmcvcmVzX2VuX1VTLnByb3BlcnRpZXMgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9idW5kbGVzL2phdmEvdXRpbC9sb2dnaW5nL3Jlc19lbl9VUy5wcm9wZXJ0aWVzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiNDU1YjAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9idW5kbGVzL2phdmEvdXRpbC9sb2dnaW5nL3Jlc19lbl9VUy5wcm9wZXJ0aWVzCkBAIC0wLDAgKzEsMTIgQEAKK2xldmVsMT1lbl9VU19sZXZlbDEKK1NFVkVSRT1VU19TRVZFUkUKK1dBUk5JTkc9VVNfV0FSTklORworQ09ORklHPVVTX0NPTkZJRworRklORT1VU19GSU5FCitGSU5FUj1VU19GSU5FUgorRklORVNUPVVTX0ZJTkVTVAorQUxMPVVTX0FMTAorT0ZGPVVTX09GRgorbXNnPVVTX01TRworcGF0dGVybj1VU19wYXR0ZXJuIHswLCBudW1iZXJ9CitwYXR0ZXJuezAsbnVtYmVyfT1VUwpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2J1bmRsZXMvamF2YS91dGlsL2xvZ2dpbmcvcmVzX3poX0NOLnByb3BlcnRpZXMgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9idW5kbGVzL2phdmEvdXRpbC9sb2dnaW5nL3Jlc196aF9DTi5wcm9wZXJ0aWVzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU5NjgwM2QKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9idW5kbGVzL2phdmEvdXRpbC9sb2dnaW5nL3Jlc196aF9DTi5wcm9wZXJ0aWVzCkBAIC0wLDAgKzEsMTMgQEAKK2xldmVsMT16aF9DTl9sZXZlbDEKK1NFVkVSRT16aF9DTl9TRVZFUkUKK1dBUk5JTkc9emhfQ05fV0FSTklORworQ09ORklHPVpIX0NOX0NPTkZJRworRklORT1aSF9DTl9GSU5FCitGSU5FUj1aSF9DTl9GSU5FUgorRklORVNUPVpIX0NOX0ZJTkVTVAorQUxMPVpIX0NOX0FMTAorT0ZGPVpIX0NOX09GRgorbXNnPVpIX0NOX01TRworcGF0dGVybj1aSF9DTl9wYXR0ZXJuIHswLCBudW1iZXJ9CitwYXR0ZXJuezAsbnVtYmVyfT1aSF9DTgorTE9HR0VSVEVTVD1UZXN0X1pIX0NOClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvY29uZmlnL2phdmEvdXRpbC9sb2dnaW5nL2xvZ2dpbmcuY29uZmlnIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvY29uZmlnL2phdmEvdXRpbC9sb2dnaW5nL2xvZ2dpbmcuY29uZmlnCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZlNzM5NGIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9jb25maWcvamF2YS91dGlsL2xvZ2dpbmcvbG9nZ2luZy5jb25maWcKQEAgLTAsMCArMSwzIEBACitoYW5kbGVycz1vcmcuYXBhY2hlLmhhcm1vbnkubG9nZ2luZy50ZXN0cy5qYXZhLnV0aWwubG9nZ2luZy5Mb2dNYW5hZ2VyVGVzdCRNb2NrSGFuZGxlciAsICBqYXZhLnV0aWwubG9nZ2luZy5Db25zb2xlSGFuZGxlcgorLmxldmVsPUFMTAorb3JnLmFwYWNoZS5oYXJtb255LmxvZ2dpbmcudGVzdHMuamF2YS51dGlsLmxvZ2dpbmcuTG9nTWFuYWdlclRlc3QkTW9ja0hhbmRsZXIubGV2ZWw9T0ZGClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvY29uZmlnL2phdmEvdXRpbC9sb2dnaW5nL2xvZ2dpbmcucHJvcGVydGllcyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2NvbmZpZy9qYXZhL3V0aWwvbG9nZ2luZy9sb2dnaW5nLnByb3BlcnRpZXMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmExZDAwOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2NvbmZpZy9qYXZhL3V0aWwvbG9nZ2luZy9sb2dnaW5nLnByb3BlcnRpZXMKQEAgLTAsMCArMSwzIEBACitoYW5kbGVycz1saWJjb3JlLmphdmEudXRpbC5sb2dnaW5nLk9sZExvZ01hbmFnZXJUZXN0JE1vY2tIYW5kbGVyIGphdmEudXRpbC5sb2dnaW5nLkNvbnNvbGVIYW5kbGVyCisubGV2ZWw9QUxMCitsaWJjb3JlLmphdmEudXRpbC5sb2dnaW5nLk9sZExvZ01hbmFnZXJUZXN0JE1vY2tIYW5kbGVyLmxldmVsPU9GRgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2Nvbm5lY3Rpb24ucHJvcGVydGllcyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2Nvbm5lY3Rpb24ucHJvcGVydGllcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNTE0ZTg1Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvY29ubmVjdGlvbi5wcm9wZXJ0aWVzCkBAIC0wLDAgKzEsOSBAQAorc3FsRHJpdmVyID0gU1FMaXRlLkpEQkNEcml2ZXIKK3NxbExvZ2luID0gCitzcWxDYXRhbG9nID1zcWxpdGVUZXN0LmRiCitzcWxIb3N0ID0KK3NxbFVybFByZWZpeCA9IGpkYmM6c3FsaXRlOgorc3FsUGFzc3dvcmQgPSAKK3NxbFVzZXIgPSAKK3NxbE1heENvbm5lY3Rpb25zID0gMzAKK3NxbE1heFRhc2tzID0gMTAwMApkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvZGFsdmlrL3N5c3RlbS9sb2FkaW5nLXRlc3QuZGV4IGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvZGFsdmlrL3N5c3RlbS9sb2FkaW5nLXRlc3QuZGV4Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk4ZmUyMWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9kYWx2aWsvc3lzdGVtL2xvYWRpbmctdGVzdC5kZXgKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvZGFsdmlrL3N5c3RlbS9sb2FkaW5nLXRlc3QuamFyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvZGFsdmlrL3N5c3RlbS9sb2FkaW5nLXRlc3QuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlZGVhNGMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9kYWx2aWsvc3lzdGVtL2xvYWRpbmctdGVzdC5qYXIKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvZGFsdmlrL3N5c3RlbS9sb2FkaW5nLXRlc3QyLmRleCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2RhbHZpay9zeXN0ZW0vbG9hZGluZy10ZXN0Mi5kZXgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzUwZDk4NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2RhbHZpay9zeXN0ZW0vbG9hZGluZy10ZXN0Mi5kZXgKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvZGFsdmlrL3N5c3RlbS9sb2FkaW5nLXRlc3QyLmphciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2RhbHZpay9zeXN0ZW0vbG9hZGluZy10ZXN0Mi5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDE1NWEzNwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2RhbHZpay9zeXN0ZW0vbG9hZGluZy10ZXN0Mi5qYXIKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvaHl0c19Gb28uYyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2h5dHNfRm9vLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTA3ZGU1OQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2h5dHNfRm9vLmMKQEAgLTAsMCArMSBAQAorLyogU29tZSByYW5kb20gZmlsZSBmb3IgaXQgdG8gbG9vayBhdC4gKi8KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0MS5jaXBoZXJ0ZXh0IGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDEuY2lwaGVydGV4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZDdiOTRiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDEuY2lwaGVydGV4dApAQCAtMCwwICsxIEBACishnSNvTnumQApcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QxLml2IGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDEuaXYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDAxZjMzNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QxLml2CkBAIC0wLDAgKzEgQEAKK570UQYyI1BcClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDEua2V5IGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDEua2V5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJmZmI1ZWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0MS5rZXkKQEAgLTAsMCArMSBAQAoraWfqjmtYjNy0dOp5QSOYeyAeho/0GfYkClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDEucGxhaW50ZXh0IGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDEucGxhaW50ZXh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk3ODdlZTIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0MS5wbGFpbnRleHQKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDIuY2lwaGVydGV4dCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QyLmNpcGhlcnRleHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWFlM2Y5NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QyLmNpcGhlcnRleHQKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDIuaXYgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0Mi5pdgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MjY2MGZjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDIuaXYKQEAgLTAsMCArMSBAQAorQPYijRXQlzwKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0Mi5rZXkgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0Mi5rZXkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTg3NmYzZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QyLmtleQpAQCAtMCwwICsxIEBACitxkjy7xSgTR+Xiwc6h1JGAH0meOsbhuScKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0Mi5wbGFpbnRleHQgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0Mi5wbGFpbnRleHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWI1ZWY0YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QyLnBsYWludGV4dApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0My5jaXBoZXJ0ZXh0IGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDMuY2lwaGVydGV4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOWRkNjAwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDMuY2lwaGVydGV4dApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0My5pdiBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QzLml2Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdhNmRlZDUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0My5pdgpAQCAtMCwwICsxIEBACiv3ln7eU3JbCQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QzLmtleSBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QzLmtleQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMThmZDg5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDMua2V5CkBAIC0wLDAgKzEgQEAKK+/dL11vs6hE0M61nlBlyQW1ruC4MD8GNgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QzLnBsYWludGV4dCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QzLnBsYWludGV4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNDViZDg4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDMucGxhaW50ZXh0CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2phcnMvY2hhcnNldF9wcm92aWRlci5qYXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9qYXJzL2NoYXJzZXRfcHJvdmlkZXIuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYxMjMwZDkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9qYXJzL2NoYXJzZXRfcHJvdmlkZXIuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2xpYmNvcmUvamF2YS9sYW5nL0hlbGxvV29ybGQudHh0IGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvbGliY29yZS9qYXZhL2xhbmcvSGVsbG9Xb3JsZC50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzQ5ZGIyYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2xpYmNvcmUvamF2YS9sYW5nL0hlbGxvV29ybGQudHh0CkBAIC0wLDAgKzEgQEAKK0hlbGxvLCBXb3JsZC4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2xpYmNvcmUvamF2YS9sYW5nL0hlbGxvV29ybGQxLnR4dCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL2xpYmNvcmUvamF2YS9sYW5nL0hlbGxvV29ybGQxLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNDlkYjJiCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvbGliY29yZS9qYXZhL2xhbmcvSGVsbG9Xb3JsZDEudHh0CkBAIC0wLDAgKzEgQEAKK0hlbGxvLCBXb3JsZC4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL253Zi9zdGFmZi5kdGQgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9ud2Yvc3RhZmYuZHRkCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAyYTk5NGQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9ud2Yvc3RhZmYuZHRkCkBAIC0wLDAgKzEsMTcgQEAKKzwhRUxFTUVOVCBlbXBsb3llZUlkICgjUENEQVRBKT4KKzwhRUxFTUVOVCBuYW1lICgjUENEQVRBKT4KKzwhRUxFTUVOVCBwb3NpdGlvbiAoI1BDREFUQSk+Cis8IUVMRU1FTlQgc2FsYXJ5ICgjUENEQVRBKT4KKzwhRUxFTUVOVCBhZGRyZXNzICgjUENEQVRBKT4KKzwhRUxFTUVOVCBlbnRFbGVtZW50ICggI1BDREFUQSApID4KKzwhRUxFTUVOVCBnZW5kZXIgKCAjUENEQVRBIHwgZW50RWxlbWVudCApKiA+Cis8IUVMRU1FTlQgZW1wbG95ZWUgKGVtcGxveWVlSWQsIG5hbWUsIHBvc2l0aW9uLCBzYWxhcnksIGdlbmRlciwgYWRkcmVzcykgPgorPCFFTEVNRU5UIHN0YWZmIChlbXBsb3llZSkrPgorPCFBVFRMSVNUIGVudEVsZW1lbnQgCisgICAgICAgICAgYXR0cjEgQ0RBVEEgIkF0dHIiPgorPCFBVFRMSVNUIGFkZHJlc3MKKyAgICAgICAgICBkb21lc3RpYyBDREFUQSAjSU1QTElFRCAKKyAgICAgICAgICBzdHJlZXQgQ0RBVEEgIlllcyI+Cis8IUFUVExJU1QgZW50RWxlbWVudCAKKyAgICAgICAgICBkb21lc3RpYyBDREFUQSAiTUFMRSIgPgorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9ud2Yvc3RhZmYueG1sIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvbndmL3N0YWZmLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNjAwZmNmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvbndmL3N0YWZmLnhtbApAQCAtMCwwICsxLDU3IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiPz48P1RFU1QtU1RZTEUgUElEQVRBPz4KKzwhRE9DVFlQRSBzdGFmZiBTWVNURU0gInN0YWZmLmR0ZCIgWworICAgPCFFTlRJVFkgZW50MSAiZXMiPgorICAgPCFFTlRJVFkgZW50MiAiMTkwMCBEYWxsYXMgUm9hZCI+CisgICA8IUVOVElUWSBlbnQzICJUZXhhcyI+CisgICA8IUVOVElUWSBlbnQ0ICI8ZW50RWxlbWVudCBkb21lc3RpYz0nWWVzJz5FbGVtZW50IGRhdGE8L2VudEVsZW1lbnQ+PD9QSXRhcmdldCBQSWRhdGE/PiI+CisgICA8IUVOVElUWSBlbnQ1IFBVQkxJQyAiZW50aXR5VVJJIiAiZW50aXR5RmlsZSIgTkRBVEEgbm90YXRpb24xPgorICAgPCFFTlRJVFkgZW50MSAiVGhpcyBlbnRpdHkgc2hvdWxkIGJlIGRpc2NhcmRlZCI+CisgICA8IU5PVEFUSU9OIG5vdGF0aW9uMSBQVUJMSUMgIm5vdGF0aW9uMUZpbGUiPgorICAgPCFOT1RBVElPTiBub3RhdGlvbjIgU1lTVEVNICJub3RhdGlvbjJGaWxlIj4KK10+Cis8IS0tIFRoaXMgaXMgY29tbWVudCBudW1iZXIgMS4tLT4KKzxzdGFmZj4KKyA8ZW1wbG95ZWUyMj4KKyAgPGVtcGxveWVlSWQ+RU1QMDAwMTwvZW1wbG95ZWVJZD4KKyAgPG5hbWU+TWFyZ2FyZXQgTWFydGluPC9uYW1lPgorICA8cG9zaXRpb24+QWNjb3VudGFudDwvcG9zaXRpb24+ICAgICAgICAgICAKKyAgPHNhbGFyeT41NiwwMDA8L3NhbGFyeT4KKyAgPGdlbmRlcj5GZW1hbGU8L2dlbmRlcj4KKyAgPGFkZHJlc3MgZG9tZXN0aWM9IlllcyI+MTIzMCBOb3J0aCBBdmUuIERhbGxhcywgVGV4YXMgOTg1NTE8L2FkZHJlc3M+CisgPC9lbXBsb3llZT4KKyA8ZW1wbG95ZWU+CisgIDxlbXBsb3llZUlkPkVNUDAwMDI8L2VtcGxveWVlSWQ+CisgIDxuYW1lPk1hcnRoYSBSYXlub2xkczwhW0NEQVRBW1RoaXMgaXMgYSBDREFUQVNlY3Rpb24gd2l0aCBFbnRpdHlSZWZlcmVuY2UgbnVtYmVyIDIgJmVudDI7XV0+Cis8IVtDREFUQVtUaGlzIGlzIGFuIGFkamFjZW50IENEQVRBU2VjdGlvbiB3aXRoIGEgcmVmZXJlbmNlIHRvIGEgdGFiICZ0YWI7XV0+PC9uYW1lPgorICA8cG9zaXRpb24+U2VjcmV0YXJ5PC9wb3NpdGlvbj4KKyAgPHNhbGFyeT4zNSwwMDA8L3NhbGFyeT4KKyAgPGdlbmRlcj5GZW1hbGU8L2dlbmRlcj4KKyAgPGFkZHJlc3MgZG9tZXN0aWM9IlllcyIgc3RyZWV0PSJZZXMiPiZlbnQyOyBEYWxsYXMsICZlbnQzOworIDk4NTU0PC9hZGRyZXNzPgorIDwvZW1wbG95ZWU+CisgPGVtcGxveWVlPgorICA8ZW1wbG95ZWVJZD5FTVAwMDAzPC9lbXBsb3llZUlkPgorICA8bmFtZT5Sb2dlcgorIEpvbmVzPC9uYW1lPgorICA8cG9zaXRpb24+RGVwYXJ0bWVudCBNYW5hZ2VyPC9wb3NpdGlvbj4KKyAgPHNhbGFyeT4xMDAsMDAwPC9zYWxhcnk+CisgIDxnZW5kZXI+JmVudDQ7PC9nZW5kZXI+CisgIDxhZGRyZXNzIGRvbWVzdGljPSJZZXMiIHN0cmVldD0iTm8iPlBPIEJveCAyNyBJcnZpbmcsIHRleGFzIDk4NTUzPC9hZGRyZXNzPgorIDwvZW1wbG95ZWU+CisgPGVtcGxveWVlPgorICA8ZW1wbG95ZWVJZD5FTVAwMDA0PC9lbXBsb3llZUlkPgorICA8bmFtZT5KZW55IE9jb25ub3I8L25hbWU+CisgIDxwb3NpdGlvbj5QZXJzb25uZWwgRGlyZWN0b3I8L3Bvc2l0aW9uPgorICA8c2FsYXJ5Pjk1LDAwMDwvc2FsYXJ5PgorICA8Z2VuZGVyPkZlbWFsZTwvZ2VuZGVyPgorICA8YWRkcmVzcyBkb21lc3RpYz0iWWVzIiBzdHJlZXQ9IlkmZW50MTsiPjI3IFNvdXRoIFJvYWQuIERhbGxhcywgVGV4YXMgOTg1NTY8L2FkZHJlc3M+CisgPC9lbXBsb3llZT4KKyA8ZW1wbG95ZWU+CisgIDxlbXBsb3llZUlkPkVNUDAwMDU8L2VtcGxveWVlSWQ+CisgIDxuYW1lPlJvYmVydCBNeWVyczwvbmFtZT4KKyAgPHBvc2l0aW9uPkNvbXB1dGVyIFNwZWNpYWxpc3Q8L3Bvc2l0aW9uPgorICA8c2FsYXJ5PjkwLDAwMDwvc2FsYXJ5PgorICA8Z2VuZGVyPm1hbGU8L2dlbmRlcj4KKyAgPGFkZHJlc3Mgc3RyZWV0PSJZZXMiPjE4MjEgTm9yZGljLiBSb2FkLCBJcnZpbmcgVGV4YXMgOTg1NTg8L2FkZHJlc3M+CisgPC9lbXBsb3llZT4KKyA8L3N0YWZmPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvT2JqZWN0U3RyZWFtQ2xhc3NUZXN0LmphciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL09iamVjdFN0cmVhbUNsYXNzVGVzdC5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2IzMDI5YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL09iamVjdFN0cmVhbUNsYXNzVGVzdC5qYXIKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9sYW5nL0EuY2xhc3MgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL2xhbmcvQS5jbGFzcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNmNjMzM0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9sYW5nL0EuY2xhc3MKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9sYW5nL2lsbGVnYWxDbGFzc2VzLmphciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9pbGxlZ2FsQ2xhc3Nlcy5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGE1ZjRlZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9pbGxlZ2FsQ2xhc3Nlcy5qYXIKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMva2V5X3N0b3JlLmJrcyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2tleV9zdG9yZS5ia3MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWFhNDNkOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2tleV9zdG9yZS5ia3MKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvb3V0X2RoL3N0YWZmLm91dCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL291dF9kaC9zdGFmZi5vdXQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDY3ZmQwOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL291dF9kaC9zdGFmZi5vdXQKQEAgLTAsMCArMSw0NSBAQAordHJ1ZV5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eI3RydWVeIworIAorICBFTVAwMDAxCisgIE1hcmdhcmV0IE1hcnRpbgorICBBY2NvdW50YW50ICAgICAgICAgICAKKyAgNTYsMDAwCisgIEZlbWFsZQorICAxMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyA5ODU1MQorIAorIAorICBFTVAwMDAyCisgIE1hcnRoYSBSYXlub2xkc1RoaXMgaXMgYSBDREFUQVNlY3Rpb24gd2l0aCBFbnRpdHlSZWZlcmVuY2UgbnVtYmVyIDIgJmVudDI7CitUaGlzIGlzIGFuIGFkamFjZW50IENEQVRBU2VjdGlvbiB3aXRoIGEgcmVmZXJlbmNlIHRvIGEgdGFiICZ0YWI7CisgIFNlY3JldGFyeQorICAzNSwwMDAKKyAgRmVtYWxlCisgIDE5MDAgRGFsbGFzIFJvYWQgRGFsbGFzLCBUZXhhcworIDk4NTU0CisgCisgCisgIEVNUDAwMDMKKyAgUm9nZXIKKyBKb25lcworICBEZXBhcnRtZW50IE1hbmFnZXIKKyAgMTAwLDAwMAorICBFbGVtZW50IGRhdGEKKyAgUE8gQm94IDI3IElydmluZywgdGV4YXMgOTg1NTMKKyAKKyAKKyAgRU1QMDAwNAorICBKZW55IE9jb25ub3IKKyAgUGVyc29ubmVsIERpcmVjdG9yCisgIDk1LDAwMAorICBGZW1hbGUKKyAgMjcgU291dGggUm9hZC4gRGFsbGFzLCBUZXhhcyA5ODU1NgorIAorIAorICBFTVAwMDA1CisgIFJvYmVydCBNeWVycworICBDb21wdXRlciBTcGVjaWFsaXN0CisgIDkwLDAwMAorICBtYWxlCisgIDE4MjEgTm9yZGljLiBSb2FkLCBJcnZpbmcgVGV4YXMgOTg1NTgKKyAKKyAjIyMjJGVtcGxveWVlSWQkZW1wbG95ZWVJZF4kbmFtZSRuYW1lXiRwb3NpdGlvbiRwb3NpdGlvbl4kc2FsYXJ5JHNhbGFyeV4kZ2VuZGVyJGdlbmRlcl4kYWRkcmVzcyRhZGRyZXNzXiRlbXBsb3llZSRlbXBsb3llZV4kZW1wbG95ZWVJZCRlbXBsb3llZUlkXiRuYW1lJG5hbWVeJHBvc2l0aW9uJHBvc2l0aW9uXiRzYWxhcnkkc2FsYXJ5XiRnZW5kZXIkZ2VuZGVyXiRhZGRyZXNzJGFkZHJlc3NeJGVtcGxveWVlJGVtcGxveWVlXiRlbXBsb3llZUlkJGVtcGxveWVlSWReJG5hbWUkbmFtZV4kcG9zaXRpb24kcG9zaXRpb25eJHNhbGFyeSRzYWxhcnleJGVudEVsZW1lbnQkZW50RWxlbWVudF4kZ2VuZGVyJGdlbmRlcl4kYWRkcmVzcyRhZGRyZXNzXiRlbXBsb3llZSRlbXBsb3llZV4kZW1wbG95ZWVJZCRlbXBsb3llZUlkXiRuYW1lJG5hbWVeJHBvc2l0aW9uJHBvc2l0aW9uXiRzYWxhcnkkc2FsYXJ5XiRnZW5kZXIkZ2VuZGVyXiRhZGRyZXNzJGFkZHJlc3NeJGVtcGxveWVlJGVtcGxveWVlXiRlbXBsb3llZUlkJGVtcGxveWVlSWReJG5hbWUkbmFtZV4kcG9zaXRpb24kcG9zaXRpb25eJHNhbGFyeSRzYWxhcnleJGdlbmRlciRnZW5kZXJeJGFkZHJlc3MkYWRkcmVzc14kZW1wbG95ZWUkZW1wbG95ZWVeJHN0YWZmJHN0YWZmXiMjVEVTVC1TVFlMRSRQSURBVEFeUEl0YXJnZXQkUElkYXRhXiMjJHN0YWZmJHN0YWZmJGVtcGxveWVlJGVtcGxveWVlJGVtcGxveWVlSWQkZW1wbG95ZWVJZCRuYW1lJG5hbWUkcG9zaXRpb24kcG9zaXRpb24kc2FsYXJ5JHNhbGFyeSRnZW5kZXIkZ2VuZGVyJGFkZHJlc3MkYWRkcmVzcyRkb21lc3RpYyRZZXMkZW1wbG95ZWUkZW1wbG95ZWUkZW1wbG95ZWVJZCRlbXBsb3llZUlkJG5hbWUkbmFtZSRwb3NpdGlvbiRwb3NpdGlvbiRzYWxhcnkkc2FsYXJ5JGdlbmRlciRnZW5kZXIkYWRkcmVzcyRhZGRyZXNzJGRvbWVzdGljJFllcyRzdHJlZXQkWWVzJGVtcGxveWVlJGVtcGxveWVlJGVtcGxveWVlSWQkZW1wbG95ZWVJZCRuYW1lJG5hbWUkcG9zaXRpb24kcG9zaXRpb24kc2FsYXJ5JHNhbGFyeSRnZW5kZXIkZ2VuZGVyJGVudEVsZW1lbnQkZW50RWxlbWVudCRkb21lc3RpYyRZZXMkYWRkcmVzcyRhZGRyZXNzJGRvbWVzdGljJFllcyRzdHJlZXQkTm8kZW1wbG95ZWUkZW1wbG95ZWUkZW1wbG95ZWVJZCRlbXBsb3llZUlkJG5hbWUkbmFtZSRwb3NpdGlvbiRwb3NpdGlvbiRzYWxhcnkkc2FsYXJ5JGdlbmRlciRnZW5kZXIkYWRkcmVzcyRhZGRyZXNzJGRvbWVzdGljJFllcyRzdHJlZXQkWWVzJGVtcGxveWVlJGVtcGxveWVlJGVtcGxveWVlSWQkZW1wbG95ZWVJZCRuYW1lJG5hbWUkcG9zaXRpb24kcG9zaXRpb24kc2FsYXJ5JHNhbGFyeSRnZW5kZXIkZ2VuZGVyJGFkZHJlc3MkYWRkcmVzcyRzdHJlZXQkWWVzIyMKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL291dF9oYi9zdGFmZi5vdXQgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9vdXRfaGIvc3RhZmYub3V0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM2ZDYxYWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9vdXRfaGIvc3RhZmYub3V0CkBAIC0wLDAgKzEsNDUgQEAKK3RydWVeI3RydWVeIworIAorICBFTVAwMDAxCisgIE1hcmdhcmV0IE1hcnRpbgorICBBY2NvdW50YW50ICAgICAgICAgICAKKyAgNTYsMDAwCisgIEZlbWFsZQorICAxMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyA5ODU1MQorIAorIAorICBFTVAwMDAyCisgIE1hcnRoYSBSYXlub2xkc1RoaXMgaXMgYSBDREFUQVNlY3Rpb24gd2l0aCBFbnRpdHlSZWZlcmVuY2UgbnVtYmVyIDIgJmVudDI7CitUaGlzIGlzIGFuIGFkamFjZW50IENEQVRBU2VjdGlvbiB3aXRoIGEgcmVmZXJlbmNlIHRvIGEgdGFiICZ0YWI7CisgIFNlY3JldGFyeQorICAzNSwwMDAKKyAgRmVtYWxlCisgIDE5MDAgRGFsbGFzIFJvYWQgRGFsbGFzLCBUZXhhcworIDk4NTU0CisgCisgCisgIEVNUDAwMDMKKyAgUm9nZXIKKyBKb25lcworICBEZXBhcnRtZW50IE1hbmFnZXIKKyAgMTAwLDAwMAorICBFbGVtZW50IGRhdGEKKyAgUE8gQm94IDI3IElydmluZywgdGV4YXMgOTg1NTMKKyAKKyAKKyAgRU1QMDAwNAorICBKZW55IE9jb25ub3IKKyAgUGVyc29ubmVsIERpcmVjdG9yCisgIDk1LDAwMAorICBGZW1hbGUKKyAgMjcgU291dGggUm9hZC4gRGFsbGFzLCBUZXhhcyA5ODU1NgorIAorIAorICBFTVAwMDA1CisgIFJvYmVydCBNeWVycworICBDb21wdXRlciBTcGVjaWFsaXN0CisgIDkwLDAwMAorICBtYWxlCisgIDE4MjEgTm9yZGljLiBSb2FkLCBJcnZpbmcgVGV4YXMgOTg1NTgKKyAKKyAjIyMjIyNURVNULVNUWUxFJFBJREFUQV5QSXRhcmdldCRQSWRhdGFeIyMjIwpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvcHJlZnMvamF2YS91dGlsL3ByZWZzL3VzZXJwcmVmcy1hc2NpaS54bWwgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9wcmVmcy9qYXZhL3V0aWwvcHJlZnMvdXNlcnByZWZzLWFzY2lpLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZDA2NmYxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvcHJlZnMvamF2YS91dGlsL3ByZWZzL3VzZXJwcmVmcy1hc2NpaS54bWwKQEAgLTAsMCArMSw2MyBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iYXNjaWkiPz4KKworPCEtLQorICAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAgICBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAgICBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICAgIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAgICB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgICAgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICAgIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgICAgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAgICAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAgICBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAgICBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgICAgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKworPCFET0NUWVBFIHByZWZlcmVuY2VzIFNZU1RFTSAnaHR0cDovL2phdmEuc3VuLmNvbS9kdGQvcHJlZmVyZW5jZXMuZHRkJz4KKworPHByZWZlcmVuY2VzIEVYVEVSTkFMX1hNTF9WRVJTSU9OPSIxLjAiPgorICA8cm9vdCB0eXBlPSJ1c2VyIj4KKyAgICA8bWFwIC8+CisgICAgPG5vZGUgbmFtZT0idGVzdHMiPgorICAgICAgPG1hcCAvPgorICAgICAgPG5vZGUgbmFtZT0iYXBpIj4KKyAgICAgICAgPG1hcCAvPgorICAgICAgICA8bm9kZSBuYW1lPSJqYXZhIj4KKyAgICAgICAgICA8bWFwIC8+CisgICAgICAgICAgPG5vZGUgbmFtZT0idXRpbCI+CisgICAgICAgICAgICA8bWFwIC8+CisgICAgICAgICAgICA8bm9kZSBuYW1lPSJwcmVmcyI+CisgICAgICAgICAgICAgIDxtYXA+CisgICAgICAgICAgICAgICAgPGVudHJ5IGtleT0icHJlZnNrZXkzIiB2YWx1ZT0ibmV3dmFsdWUzIiAvPgorICAgICAgICAgICAgICA8L21hcD4KKyAgICAgICAgICAgICAgPG5vZGUgbmFtZT0ibW9jayI+CisgICAgICAgICAgICAgICAgPG1hcCAvPgorICAgICAgICAgICAgICAgIDxub2RlIG5hbWU9ImNoaWxkIj4KKyAgICAgICAgICAgICAgICAgIDxtYXA+CisgICAgICAgICAgICAgICAgICAgIDxlbnRyeSBrZXk9ImtleTIiIHZhbHVlPSJ2YWx1ZTIiIC8+CisgICAgICAgICAgICAgICAgICA8L21hcD4KKyAgICAgICAgICAgICAgICAgIDxub2RlIG5hbWU9ImdyYW5kc29uIj4KKyAgICAgICAgICAgICAgICAgICAgPG1hcD4KKyAgICAgICAgICAgICAgICAgICAgICA8ZW50cnkga2V5PSJrZXkzIiB2YWx1ZT0idmFsdWUzIiAvPgorICAgICAgICAgICAgICAgICAgICA8L21hcD4KKyAgICAgICAgICAgICAgICAgICAgPG5vZGUgbmFtZT0iZ3JhbmRncmFuZHNvbiI+CisgICAgICAgICAgICAgICAgICAgICAgPG1hcD4KKyAgICAgICAgICAgICAgICAgICAgICAgIDxlbnRyeSBrZXk9ImtleTQiIHZhbHVlPSJ2YWx1ZTQiIC8+CisgICAgICAgICAgICAgICAgICAgICAgPC9tYXA+CisgICAgICAgICAgICAgICAgICAgIDwvbm9kZT4KKyAgICAgICAgICAgICAgICAgIDwvbm9kZT4KKyAgICAgICAgICAgICAgICA8L25vZGU+CisgICAgICAgICAgICAgIDwvbm9kZT4KKyAgICAgICAgICAgIDwvbm9kZT4KKyAgICAgICAgICA8L25vZGU+CisgICAgICAgIDwvbm9kZT4KKyAgICAgIDwvbm9kZT4KKyAgICA8L25vZGU+CisgIDwvcm9vdD4KKzwvcHJlZmVyZW5jZXM+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9wcmVmcy9qYXZhL3V0aWwvcHJlZnMvdXNlcnByZWZzLWJhZGVuY29kaW5nLnhtbCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3ByZWZzL2phdmEvdXRpbC9wcmVmcy91c2VycHJlZnMtYmFkZW5jb2RpbmcueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRiOTllMDQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9wcmVmcy9qYXZhL3V0aWwvcHJlZnMvdXNlcnByZWZzLWJhZGVuY29kaW5nLnhtbApAQCAtMCwwICsxLDY0IEBACivvu788P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJiYWRlbmNvZGluZyI/PgorCis8IS0tCisgICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICAgIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICAgIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgICAgcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICAgIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAgICAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgICAgd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAgICBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICAgICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICAgIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICAgIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAgICB1bmRlciB0aGUgTGljZW5zZS4KKy0tPgorCis8IURPQ1RZUEUgcHJlZmVyZW5jZXMgU1lTVEVNICdodHRwOi8vamF2YS5zdW4uY29tL2R0ZC9wcmVmZXJlbmNlcy5kdGQnPgorCis8cHJlZmVyZW5jZXMgRVhURVJOQUxfWE1MX1ZFUlNJT049IjEuMCI+CisgIDxyb290IHR5cGU9InVzZXIiPgorICAgIDxtYXAgLz4KKyAgICA8bm9kZSBuYW1lPSJ0ZXN0cyI+CisgICAgICA8bWFwIC8+CisgICAgICA8bm9kZSBuYW1lPSJhcGkiPgorICAgICAgICA8bWFwIC8+CisgICAgICAgIDxub2RlIG5hbWU9ImphdmEiPgorICAgICAgICAgIDxtYXAgLz4KKyAgICAgICAgICA8bm9kZSBuYW1lPSJ1dGlsIj4KKyAgICAgICAgICAgIDxtYXAgLz4KKyAgICAgICAgICAgIDxub2RlIG5hbWU9InByZWZzIj4KKyAgICAgICAgICAgICAgPG1hcD4KKyAgICAgICAgICAgICAgICA8ZW50cnkga2V5PSJwcmVmc2tleSIgdmFsdWU9Im5ld3ZhbHVlIiAvPgorICAgICAgICAgICAgICAgIDxlbnRyeSBrZXk9InByZWZza2V5MyIgdmFsdWU9Im5ld3ZhbHVlMyIgLz4KKyAgICAgICAgICAgICAgPC9tYXA+CisgICAgICAgICAgICAgIDxub2RlIG5hbWU9Im1vY2siPgorICAgICAgICAgICAgICAgIDxtYXAgLz4KKyAgICAgICAgICAgICAgICA8bm9kZSBuYW1lPSJjaGlsZCI+CisgICAgICAgICAgICAgICAgICA8bWFwPgorICAgICAgICAgICAgICAgICAgICA8ZW50cnkga2V5PSJrZXkyIiB2YWx1ZT0idmFsdWUyIiAvPgorICAgICAgICAgICAgICAgICAgPC9tYXA+CisgICAgICAgICAgICAgICAgICA8bm9kZSBuYW1lPSJncmFuZHNvbiI+CisgICAgICAgICAgICAgICAgICAgIDxtYXA+CisgICAgICAgICAgICAgICAgICAgICAgPGVudHJ5IGtleT0ia2V5MyIgdmFsdWU9InZhbHVlMyIgLz4KKyAgICAgICAgICAgICAgICAgICAgPC9tYXA+CisgICAgICAgICAgICAgICAgICAgIDxub2RlIG5hbWU9ImdyYW5kZ3JhbmRzb24iPgorICAgICAgICAgICAgICAgICAgICAgIDxtYXA+CisgICAgICAgICAgICAgICAgICAgICAgICA8ZW50cnkga2V5PSJrZXk0IiB2YWx1ZT0idmFsdWU0IiAvPgorICAgICAgICAgICAgICAgICAgICAgIDwvbWFwPgorICAgICAgICAgICAgICAgICAgICA8L25vZGU+CisgICAgICAgICAgICAgICAgICA8L25vZGU+CisgICAgICAgICAgICAgICAgPC9ub2RlPgorICAgICAgICAgICAgICA8L25vZGU+CisgICAgICAgICAgICA8L25vZGU+CisgICAgICAgICAgPC9ub2RlPgorICAgICAgICA8L25vZGU+CisgICAgICA8L25vZGU+CisgICAgPC9ub2RlPgorICA8L3Jvb3Q+Cis8L3ByZWZlcmVuY2VzPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvcHJlZnMvamF2YS91dGlsL3ByZWZzL3VzZXJwcmVmcy1iYWRmb3JtLnhtbCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3ByZWZzL2phdmEvdXRpbC9wcmVmcy91c2VycHJlZnMtYmFkZm9ybS54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmMyMzFiOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3ByZWZzL2phdmEvdXRpbC9wcmVmcy91c2VycHJlZnMtYmFkZm9ybS54bWwKQEAgLTAsMCArMSw1NCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KKworPCEtLQorICAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAgICBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAgICBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICAgIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAgICB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgICAgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICAgIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgICAgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAgICAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAgICBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAgICBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgICAgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKworPCFET0NUWVBFIHByZWZlcmVuY2VzIFNZU1RFTSAnaHR0cDovL2phdmEuc3VuLmNvbS9kdGQvcHJlZmVyZW5jZXMuZHRkJz4KKworPHByZWZlcmVuY2VzIEVYVEVSTkFMX1hNTF9WRVJTSU9OPSIxLjAiPgorICA8cm9vdCB0eXBlPSJ1c2VyIj4KKyAgICA8bWFwIC8+CisgICAgPG5vZGUgbmFtZT0iamF2YSI+CisgICAgICA8bWFwIC8+CisgICAgICA8bm9kZSBuYW1lPSJ1dGlsIj4KKyAgICAgICAgPG1hcCAvPgorICAgICAgICA8bm9kZSBuYW1lPSJwcmVmcyI+CisgICAgICAgICAgPG1hcCAvPgorICAgICAgICAgIDxub2RlIG5hbWU9Im1vY2siPgorICAgICAgICAgICAgPG1hcCAvPgorICAgICAgICAgICAgPG5vZGUgbmFtZT0iY2hpbGQiPgorICAgICAgICAgICAgICA8bWFwPgorICAgICAgICAgICAgICAgIDxlbnRyeSBrZXk9ImtleTIiIHZhbHVlPSJ2YWx1ZTIiIC8+CisgICAgICAgICAgICAgIDwvbWFwPgorICAgICAgICAgICAgICA8bm9kZSBuYW1lPSJncmFuZHNvbiI+CisgICAgICAgICAgICAgICAgPG1hcD4KKyAgICAgICAgICAgICAgICAgIDxlbnRyeSBrZXk9ImtleTMiIHZhbHVlPSJ2YWx1ZTMiIC8+CisgICAgICAgICAgICAgICAgPC9tYXA+CisgICAgICAgICAgICAgICAgPG5vZGUgbmFtZT0iZ3JhbmRncmFuZHNvbiI+CisgICAgICAgICAgICAgICAgICA8bWFwPgorICAgICAgICAgICAgICAgICAgICA8ZW50cnkga2V5PSJrZXk0IiB2YWx1ZT0idmFsdWU0IiAvPgorICAgICAgICAgICAgICAgICAgPC9tYXA+CisgICAgICAgICAgICAgICAgPC9ub2RlPgorICAgICAgICAgICAgICA8L25vZGU+CisgICAgICAgICAgICA8L25vZGU+CisgICAgICAgICAgPC9ub2RlPgorICAgICAgICA8L25vZGU+CisgICAgICA8L25vZGU+CisgICAgPC9ub2RlPgorICA8L3Jvb3Q+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9wcmVmcy9qYXZhL3V0aWwvcHJlZnMvdXNlcnByZWZzLWJhZHR5cGUueG1sIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvcHJlZnMvamF2YS91dGlsL3ByZWZzL3VzZXJwcmVmcy1iYWR0eXBlLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOTc0NjE3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvcHJlZnMvamF2YS91dGlsL3ByZWZzL3VzZXJwcmVmcy1iYWR0eXBlLnhtbApAQCAtMCwwICsxLDY0IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PgorCis8IS0tCisgICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICAgIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICAgIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgICAgcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICAgIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAgICAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgICAgd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAgICBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICAgICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICAgIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICAgIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAgICB1bmRlciB0aGUgTGljZW5zZS4KKy0tPgorCis8IURPQ1RZUEUgcHJlZmVyZW5jZXMgU1lTVEVNICdwcmVmZXJlbmNlcy5kdGQnPgorCis8cHJlZmVyZW5jZXMgRVhURVJOQUxfWE1MX1ZFUlNJT049IjEuMCI+CisgIDxyb290IHR5cGU9InVzZXIiPgorICAgIDxtYXAgLz4KKyAgICA8bm9kZSBuYW1lPSJ0ZXN0cyI+CisgICAgICA8bWFwIC8+CisgICAgICA8bm9kZSBuYW1lPSJhcGkiPgorICAgICAgICA8bWFwIC8+CisgICAgICAgIDxub2RlIG5hbWU9ImphdmEiPgorICAgICAgICAgIDxtYXAgLz4KKyAgICAgICAgICA8bm9kZSBuYW1lPSJ1dGlsIj4KKyAgICAgICAgICAgIDxtYXAgLz4KKyAgICAgICAgICAgIDxub2RlIG5hbWU9InByZWZzIj4KKyAgICAgICAgICAgICAgPG1hcD4KKyAgICAgICAgICAgICAgICA8ZW50cnkga2V5PSJwcmVmc2tleSIgdmFsdWU9Im5ld3ZhbHVlIiAvPgorICAgICAgICAgICAgICAgIDxlbnRyeSBrZXk9InByZWZza2V5MyIgdmFsdWU9Im5ld3ZhbHVlMyIgLz4KKyAgICAgICAgICAgICAgPC9tYXA+CisgICAgICAgICAgICAgIDxub2RlIG5hbWU9Im1vY2siPgorICAgICAgICAgICAgICAgIDxtYXAgLz4KKyAgICAgICAgICAgICAgICA8bm9kZSBuYW1lPSJjaGlsZCI+CisgICAgICAgICAgICAgICAgICA8bWFwPgorICAgICAgICAgICAgICAgICAgICA8ZW50cnkga2V5PSJrZXkyIiB2YWx1ZT0idmFsdWUyIiAvPgorICAgICAgICAgICAgICAgICAgPC9tYXA+CisgICAgICAgICAgICAgICAgICA8bm9kZSBuYW1lPSJncmFuZHNvbiI+CisgICAgICAgICAgICAgICAgICAgIDxtYXA+CisgICAgICAgICAgICAgICAgICAgICAgPGVudHJ5IGtleT0ia2V5MyIgdmFsdWU9InZhbHVlMyIgLz4KKyAgICAgICAgICAgICAgICAgICAgPC9tYXA+CisgICAgICAgICAgICAgICAgICAgIDxub2RlIG5hbWU9ImdyYW5kZ3JhbmRzb24iPgorICAgICAgICAgICAgICAgICAgICAgIDxtYXA+CisgICAgICAgICAgICAgICAgICAgICAgICA8ZW50cnkga2V5PSJrZXk0IiB2YWx1ZT0idmFsdWU0IiAvPgorICAgICAgICAgICAgICAgICAgICAgIDwvbWFwPgorICAgICAgICAgICAgICAgICAgICA8L25vZGU+CisgICAgICAgICAgICAgICAgICA8L25vZGU+CisgICAgICAgICAgICAgICAgPC9ub2RlPgorICAgICAgICAgICAgICA8L25vZGU+CisgICAgICAgICAgICA8L25vZGU+CisgICAgICAgICAgPC9ub2RlPgorICAgICAgICA8L25vZGU+CisgICAgICA8L25vZGU+CisgICAgPC9ub2RlPgorICA8L3Jvb3Q+Cis8L3ByZWZlcmVuY2VzPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvcHJlZnMvamF2YS91dGlsL3ByZWZzL3VzZXJwcmVmcy1oaWdoZXJ2ZXJzaW9uLnhtbCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3ByZWZzL2phdmEvdXRpbC9wcmVmcy91c2VycHJlZnMtaGlnaGVydmVyc2lvbi54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTdmNmFhOAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3ByZWZzL2phdmEvdXRpbC9wcmVmcy91c2VycHJlZnMtaGlnaGVydmVyc2lvbi54bWwKQEAgLTAsMCArMSw2NCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KKworPCEtLQorICAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAgICBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAgICBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICAgIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAgICB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgICAgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICAgIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgICAgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAgICAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAgICBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAgICBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgICAgdW5kZXIgdGhlIExpY2Vuc2UuICAgICAKKy0tPgorCis8IURPQ1RZUEUgcHJlZmVyZW5jZXMgU1lTVEVNICdodHRwOi8vamF2YS5zdW4uY29tL2R0ZC9wcmVmZXJlbmNlcy5kdGQnPgorCis8cHJlZmVyZW5jZXMgRVhURVJOQUxfWE1MX1ZFUlNJT049IjEuMSI+CisgIDxyb290IHR5cGU9InVzZXIiPgorICAgIDxtYXAgLz4KKyAgICA8bm9kZSBuYW1lPSJ0ZXN0cyI+CisgICAgICA8bWFwIC8+CisgICAgICA8bm9kZSBuYW1lPSJhcGkiPgorICAgICAgICA8bWFwIC8+CisgICAgICAgIDxub2RlIG5hbWU9ImphdmEiPgorICAgICAgICAgIDxtYXAgLz4KKyAgICAgICAgICA8bm9kZSBuYW1lPSJ1dGlsIj4KKyAgICAgICAgICAgIDxtYXAgLz4KKyAgICAgICAgICAgIDxub2RlIG5hbWU9InByZWZzIj4KKyAgICAgICAgICAgICAgPG1hcD4KKyAgICAgICAgICAgICAgICA8ZW50cnkga2V5PSJwcmVmc2tleSIgdmFsdWU9Im5ld3ZhbHVlIiAvPgorICAgICAgICAgICAgICAgIDxlbnRyeSBrZXk9InByZWZza2V5MyIgdmFsdWU9Im5ld3ZhbHVlMyIgLz4KKyAgICAgICAgICAgICAgPC9tYXA+CisgICAgICAgICAgICAgIDxub2RlIG5hbWU9Im1vY2siPgorICAgICAgICAgICAgICAgIDxtYXAgLz4KKyAgICAgICAgICAgICAgICA8bm9kZSBuYW1lPSJjaGlsZCI+CisgICAgICAgICAgICAgICAgICA8bWFwPgorICAgICAgICAgICAgICAgICAgICA8ZW50cnkga2V5PSJrZXkyIiB2YWx1ZT0idmFsdWUyIiAvPgorICAgICAgICAgICAgICAgICAgPC9tYXA+CisgICAgICAgICAgICAgICAgICA8bm9kZSBuYW1lPSJncmFuZHNvbiI+CisgICAgICAgICAgICAgICAgICAgIDxtYXA+CisgICAgICAgICAgICAgICAgICAgICAgPGVudHJ5IGtleT0ia2V5MyIgdmFsdWU9InZhbHVlMyIgLz4KKyAgICAgICAgICAgICAgICAgICAgPC9tYXA+CisgICAgICAgICAgICAgICAgICAgIDxub2RlIG5hbWU9ImdyYW5kZ3JhbmRzb24iPgorICAgICAgICAgICAgICAgICAgICAgIDxtYXA+CisgICAgICAgICAgICAgICAgICAgICAgICA8ZW50cnkga2V5PSJrZXk0IiB2YWx1ZT0idmFsdWU0IiAvPgorICAgICAgICAgICAgICAgICAgICAgIDwvbWFwPgorICAgICAgICAgICAgICAgICAgICA8L25vZGU+CisgICAgICAgICAgICAgICAgICA8L25vZGU+CisgICAgICAgICAgICAgICAgPC9ub2RlPgorICAgICAgICAgICAgICA8L25vZGU+CisgICAgICAgICAgICA8L25vZGU+CisgICAgICAgICAgPC9ub2RlPgorICAgICAgICA8L25vZGU+CisgICAgICA8L25vZGU+CisgICAgPC9ub2RlPgorICA8L3Jvb3Q+Cis8L3ByZWZlcmVuY2VzPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvcHJlZnMvamF2YS91dGlsL3ByZWZzL3VzZXJwcmVmcy54bWwgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9wcmVmcy9qYXZhL3V0aWwvcHJlZnMvdXNlcnByZWZzLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOTAxZjViCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvcHJlZnMvamF2YS91dGlsL3ByZWZzL3VzZXJwcmVmcy54bWwKQEAgLTAsMCArMSw3NiBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KKworPCEtLQorICAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAgICBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAgICBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICAgIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAgICB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgICAgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICAgIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgICAgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAgICAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAgICBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAgICBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgICAgdW5kZXIgdGhlIExpY2Vuc2UuICAgICAKKy0tPgorCis8IURPQ1RZUEUgcHJlZmVyZW5jZXMgU1lTVEVNICdodHRwOi8vamF2YS5zdW4uY29tL2R0ZC9wcmVmZXJlbmNlcy5kdGQnPgorCis8cHJlZmVyZW5jZXMgRVhURVJOQUxfWE1MX1ZFUlNJT049IjEuMCI+CisgIDxyb290IHR5cGU9InVzZXIiPgorICAgIDxtYXAgLz4KKyAgICA8bm9kZSBuYW1lPSJvcmciPgorICAgICAgPG1hcCAvPgorICAgICAgPG5vZGUgbmFtZT0iYXBhY2hlIj4KKyAgICAgICAgPG1hcCAvPgorICAgICAgICAgIDxub2RlIG5hbWU9Imhhcm1vbnkiPgorICAgICAgICAgICAgPG1hcCAvPgorICAgICAgICAgICAgPG5vZGUgbmFtZT0icHJlZnMiPgorICAgICAgICAgICAgICA8bWFwIC8+CisgICAgICAgICAgICAgIDxub2RlIG5hbWU9InRlc3RzIj4KKyAgICAgICAgICAgICAgICA8bWFwIC8+CisgICAgICAgICAgICAgICAgPG5vZGUgbmFtZT0iamF2YSI+CisgICAgICAgICAgICAgICAgICA8bWFwIC8+CisgICAgICAgICAgICAgICAgICA8bm9kZSBuYW1lPSJ1dGlsIj4KKyAgICAgICAgICAgICAgICAgICAgPG1hcCAvPgorICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgPG5vZGUgbmFtZT0icHJlZnMiPgorICAgICAgICAgICAgICAgICAgICAgIDxtYXA+CisgICAgICAgICAgICAgICAgICAgICAgICA8ZW50cnkga2V5PSJwcmVmc2tleSIgdmFsdWU9Im5ld3ZhbHVlIiAvPgorICAgICAgICAgICAgICAgICAgICAgICAgPGVudHJ5IGtleT0icHJlZnNrZXkzIiB2YWx1ZT0ibmV3dmFsdWUzIiAvPgorICAgICAgICAgICAgICAgICAgICAgIDwvbWFwPgorCisgICAgICAgICAgICAgICAgICAgICAgPG5vZGUgbmFtZT0ibW9jayI+CisgICAgICAgICAgICAgICAgICAgICAgICA8bWFwIC8+CisgICAgICAgICAgICAgICAgICAgICAgICA8bm9kZSBuYW1lPSJjaGlsZCI+CisgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXA+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGVudHJ5IGtleT0ia2V5MiIgdmFsdWU9InZhbHVlMiIgLz4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXA+CisgICAgICAgICAgICAgICAgICAgICAgICAgIDxub2RlIG5hbWU9ImdyYW5kc29uIj4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWFwPgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGVudHJ5IGtleT0ia2V5MyIgdmFsdWU9InZhbHVlMyIgLz4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hcD4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgPG5vZGUgbmFtZT0iZ3JhbmRncmFuZHNvbiI+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hcD4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxlbnRyeSBrZXk9ImtleTQiIHZhbHVlPSJ2YWx1ZTQiIC8+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXA+CisgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbm9kZT4gPCEtLWdyYW5kZ3JhbmRzb24tLT4KKyAgICAgICAgICAgICAgICAgICAgICAgIDwvbm9kZT4gPCEtLWdyYW5kc29uLS0+CisgICAgICAgICAgICAgICAgICAgICAgPC9ub2RlPiA8IS0tY2hpbGQtLT4KKyAgICAgICAgICAgICAgICAgICAgPC9ub2RlPiA8IS0tbW9jay0tPgorCisgICAgICAgICAgICAgICAgICA8L25vZGU+IDwhLS1wcmVmcy0tPgorICAgICAgICAgICAgICAgIDwvbm9kZT4gPCEtLXV0aWwtLT4KKyAgICAgICAgICAgICAgPC9ub2RlPiA8IS0tamF2YS0tPgorICAgICAgICAgICAgPC9ub2RlPiA8IS0tdGVzdHMtLT4KKyAgICAgICAgICA8L25vZGU+IDwhLS1wcmVmcy0tPgorICAgICAgICA8L25vZGU+IDwhLS1oYXJtb255LS0+CisgICAgICA8L25vZGU+IDwhLS1hcGFjaGUtLT4KKyAgICA8L25vZGU+IDwhLS1vcmctLT4KKyAgPC9yb290PgorPC9wcmVmZXJlbmNlcz4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3JlY2lwZS54bWwgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9yZWNpcGUueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3Y2YwZmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9yZWNpcGUueG1sCkBAIC0wLDAgKzEsMjQgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cis8IURPQ1RZUEUgY29sbGVjdGlvbiBTWVNURU0gIi4vcmVjaXB0LmR0ZCI+Cis8IS0tY29tbWVudDEgLS0+Cis8Y29sbGVjdGlvbj4KKyAgPGRlc2NyaXB0aW9uPgorICAgICBTb21lIHJlY2lwZXMgdXNlZCBmb3IgdGhlIFhNTCB0dXRvcmlhbC4KKyAgPC9kZXNjcmlwdGlvbj4KKyAgPHJlY2lwZT4KKyAgICA8dGl0bGU+QmVlZiBQYXJtZXNhbjwhW0NEQVRBWzx0aXRsZT4gd2l0aCBHYXJsaWMgQW5nZWwgSGFpciBQYXN0YTwvdGl0bGU+XV0+PC90aXRsZT4KKyAgICA8aW5ncmVkaWVudCBuYW1lPSJiZWVmIGN1YmUgc3RlYWsiIGFtb3VudD0iMS41IiB1bml0PSJwb3VuZCIvPgorICAgIDxwcmVwYXJhdGlvbj4KKyAgICAgIDxzdGVwPgorICAgICAgICBQcmVoZWF0IG92ZW4gdG8gMzUwIGRlZ3JlZXMgRiAoMTc1IGRlZ3JlZXMgQykuCisgICAgICA8L3N0ZXA+CisgICAgPC9wcmVwYXJhdGlvbj4KKyAgICA8Y29tbWVudD4KKyAgICAgIE1ha2UgdGhlIG1lYXQgYWhlYWQgb2YgdGltZSwgYW5kIHJlZnJpZ2VyYXRlIG92ZXIgbmlnaHQsIHRoZSBhY2lkIGluIHRoZQorICAgICAgdG9tYXRvIHNhdWNlIHdpbGwgdGVuZGVyaXplIHRoZSBtZWF0IGV2ZW4gbW9yZS4gSWYgeW91IGRvIHRoaXMsIHNhdmUgdGhlCisgICAgICBtb3p6YXJlbGxhIHRpbGwgdGhlIGxhc3QgbWludXRlLgorICAgIDwvY29tbWVudD4KKyAgICA8bnV0cml0aW9uIGNhbG9yaWVzPSIxMTY3IiBmYXQ9IjIzIiBjYXJib2h5ZHJhdGVzPSI0NSIgcHJvdGVpbj0iMzIiLz4KKyAgPC9yZWNpcGU+Cis8L2NvbGxlY3Rpb24+Cis8IS0tY29tbWVudDIgLS0+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9yZWNpcGUxLnhtbCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3JlY2lwZTEueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3Y2YwZmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9yZWNpcGUxLnhtbApAQCAtMCwwICsxLDI0IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PgorPCFET0NUWVBFIGNvbGxlY3Rpb24gU1lTVEVNICIuL3JlY2lwdC5kdGQiPgorPCEtLWNvbW1lbnQxIC0tPgorPGNvbGxlY3Rpb24+CisgIDxkZXNjcmlwdGlvbj4KKyAgICAgU29tZSByZWNpcGVzIHVzZWQgZm9yIHRoZSBYTUwgdHV0b3JpYWwuCisgIDwvZGVzY3JpcHRpb24+CisgIDxyZWNpcGU+CisgICAgPHRpdGxlPkJlZWYgUGFybWVzYW48IVtDREFUQVs8dGl0bGU+IHdpdGggR2FybGljIEFuZ2VsIEhhaXIgUGFzdGE8L3RpdGxlPl1dPjwvdGl0bGU+CisgICAgPGluZ3JlZGllbnQgbmFtZT0iYmVlZiBjdWJlIHN0ZWFrIiBhbW91bnQ9IjEuNSIgdW5pdD0icG91bmQiLz4KKyAgICA8cHJlcGFyYXRpb24+CisgICAgICA8c3RlcD4KKyAgICAgICAgUHJlaGVhdCBvdmVuIHRvIDM1MCBkZWdyZWVzIEYgKDE3NSBkZWdyZWVzIEMpLgorICAgICAgPC9zdGVwPgorICAgIDwvcHJlcGFyYXRpb24+CisgICAgPGNvbW1lbnQ+CisgICAgICBNYWtlIHRoZSBtZWF0IGFoZWFkIG9mIHRpbWUsIGFuZCByZWZyaWdlcmF0ZSBvdmVyIG5pZ2h0LCB0aGUgYWNpZCBpbiB0aGUKKyAgICAgIHRvbWF0byBzYXVjZSB3aWxsIHRlbmRlcml6ZSB0aGUgbWVhdCBldmVuIG1vcmUuIElmIHlvdSBkbyB0aGlzLCBzYXZlIHRoZQorICAgICAgbW96emFyZWxsYSB0aWxsIHRoZSBsYXN0IG1pbnV0ZS4KKyAgICA8L2NvbW1lbnQ+CisgICAgPG51dHJpdGlvbiBjYWxvcmllcz0iMTE2NyIgZmF0PSIyMyIgY2FyYm9oeWRyYXRlcz0iNDUiIHByb3RlaW49IjMyIi8+CisgIDwvcmVjaXBlPgorPC9jb2xsZWN0aW9uPgorPCEtLWNvbW1lbnQyIC0tPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvcmVjaXB0LmR0ZCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3JlY2lwdC5kdGQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzcwMTEyYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3JlY2lwdC5kdGQKQEAgLTAsMCArMSwxNyBAQAorPCFFTEVNRU5UIGNvbGxlY3Rpb24gKGRlc2NyaXB0aW9uLHJlY2lwZSspPgorPCFFTEVNRU5UIGRlc2NyaXB0aW9uIEFOWT4KKzwhRUxFTUVOVCByZWNpcGUgKHRpdGxlLGluZ3JlZGllbnQqLHByZXBhcmF0aW9uLGNvbW1lbnQ/LG51dHJpdGlvbik+Cis8IUVMRU1FTlQgdGl0bGUgKCNQQ0RBVEEpPgorPCFFTEVNRU5UIGluZ3JlZGllbnQgKGluZ3JlZGllbnQqLHByZXBhcmF0aW9uKT8+Cis8IUFUVExJU1QgaW5ncmVkaWVudCBuYW1lIENEQVRBICNSRVFVSVJFRAorICAgICAgICAgICAgICAgICAgICAgYW1vdW50IENEQVRBICNJTVBMSUVECisgICAgICAgICAgICAgICAgICAgICB1bml0IENEQVRBICNJTVBMSUVEPgorPCFFTEVNRU5UIHByZXBhcmF0aW9uIChzdGVwKik+Cis8IUVMRU1FTlQgc3RlcCAoI1BDREFUQSk+Cis8IUVMRU1FTlQgY29tbWVudCAoI1BDREFUQSk+Cis8IUVMRU1FTlQgbnV0cml0aW9uIEVNUFRZPgorPCFBVFRMSVNUIG51dHJpdGlvbiBwcm90ZWluIENEQVRBICNSRVFVSVJFRAorICAgICAgICAgICAgICAgICAgICBjYXJib2h5ZHJhdGVzIENEQVRBICNSRVFVSVJFRAorICAgICAgICAgICAgICAgICAgICBmYXQgQ0RBVEEgI1JFUVVJUkVECisgICAgICAgICAgICAgICAgICAgIGNhbG9yaWVzIENEQVRBICNSRVFVSVJFRAorICAgICAgICAgICAgICAgICAgICBhbGNvaG9sIENEQVRBICNJTVBMSUVEPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvcmVjaXB0LnhtbCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3JlY2lwdC54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDdjZjBmYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3JlY2lwdC54bWwKQEAgLTAsMCArMSwyNCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KKzwhRE9DVFlQRSBjb2xsZWN0aW9uIFNZU1RFTSAiLi9yZWNpcHQuZHRkIj4KKzwhLS1jb21tZW50MSAtLT4KKzxjb2xsZWN0aW9uPgorICA8ZGVzY3JpcHRpb24+CisgICAgIFNvbWUgcmVjaXBlcyB1c2VkIGZvciB0aGUgWE1MIHR1dG9yaWFsLgorICA8L2Rlc2NyaXB0aW9uPgorICA8cmVjaXBlPgorICAgIDx0aXRsZT5CZWVmIFBhcm1lc2FuPCFbQ0RBVEFbPHRpdGxlPiB3aXRoIEdhcmxpYyBBbmdlbCBIYWlyIFBhc3RhPC90aXRsZT5dXT48L3RpdGxlPgorICAgIDxpbmdyZWRpZW50IG5hbWU9ImJlZWYgY3ViZSBzdGVhayIgYW1vdW50PSIxLjUiIHVuaXQ9InBvdW5kIi8+CisgICAgPHByZXBhcmF0aW9uPgorICAgICAgPHN0ZXA+CisgICAgICAgIFByZWhlYXQgb3ZlbiB0byAzNTAgZGVncmVlcyBGICgxNzUgZGVncmVlcyBDKS4KKyAgICAgIDwvc3RlcD4KKyAgICA8L3ByZXBhcmF0aW9uPgorICAgIDxjb21tZW50PgorICAgICAgTWFrZSB0aGUgbWVhdCBhaGVhZCBvZiB0aW1lLCBhbmQgcmVmcmlnZXJhdGUgb3ZlciBuaWdodCwgdGhlIGFjaWQgaW4gdGhlCisgICAgICB0b21hdG8gc2F1Y2Ugd2lsbCB0ZW5kZXJpemUgdGhlIG1lYXQgZXZlbiBtb3JlLiBJZiB5b3UgZG8gdGhpcywgc2F2ZSB0aGUKKyAgICAgIG1venphcmVsbGEgdGlsbCB0aGUgbGFzdCBtaW51dGUuCisgICAgPC9jb21tZW50PgorICAgIDxudXRyaXRpb24gY2Fsb3JpZXM9IjExNjciIGZhdD0iMjMiIGNhcmJvaHlkcmF0ZXM9IjQ1IiBwcm90ZWluPSIzMiIvPgorICA8L3JlY2lwZT4KKzwvY29sbGVjdGlvbj4KKzwhLS1jb21tZW50MiAtLT4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3JlY2lwdFdyb25nLnhtbCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3JlY2lwdFdyb25nLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZTMyZDA5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvcmVjaXB0V3JvbmcueG1sCkBAIC0wLDAgKzEsMjEgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cis8IURPQ1RZUEUgY29sbGVjdGlvbiBTWVNURU0gIi4vcmVjaXB0LmR0ZCI+Cis8IS0tY29tbWVudDEgLS0+Cis8Y29sbGVjdGlvbj4KKyAgPHJlY2lwZT4KKyAgICA8dGl0bGU+QmVlZiBQYXJtZXNhbjwhW0NEQVRBWzx0aXRsZT4gd2l0aCBHYXJsaWMgQW5nZWwgSGFpciBQYXN0YTwvdGl0bGU+XV0+PC90aXRsZT4KKyAgICA8aW5ncmVkaWVudCBuYW1lPSJiZWVmIGN1YmUgc3RlYWsiIGFtb3VudD0iMS41IiB1bml0PSJwb3VuZCIvPgorICAgIDxwcmVwYXJhdGlvbj4KKyAgICAgIDxzdGVwPgorICAgICAgICBQcmVoZWF0IG92ZW4gdG8gMzUwIGRlZ3JlZXMgRiAoMTc1IGRlZ3JlZXMgQykuCisgICAgICA8L3N0ZXA+CisgICAgPC9wcmVwYXJhdGlvbj4KKyAgICA8Y29tbWVudD4KKyAgICAgIE1ha2UgdGhlIG1lYXQgYWhlYWQgb2YgdGltZSwgYW5kIHJlZnJpZ2VyYXRlIG92ZXIgbmlnaHQsIHRoZSBhY2lkIGluIHRoZQorICAgICAgdG9tYXRvIHNhdWNlIHdpbGwgdGVuZGVyaXplIHRoZSBtZWF0IGV2ZW4gbW9yZS4gSWYgeW91IGRvIHRoaXMsIHNhdmUgdGhlCisgICAgICBtb3p6YXJlbGxhIHRpbGwgdGhlIGxhc3QgbWludXRlLgorICAgIDwvY29tbWVudD4KKyAgICA8bnV0cml0aW9uIGNhbG9yaWVzPSIxMTY3IiBmYXQ9IjIzIiBjYXJib2h5ZHJhdGVzPSI0NSIgcHJvdGVpbj0iMzIiLz4KKyAgPC9yZWNpcGU+Cis8L2NvbGxlY3Rpb24+Cis8IS0tY29tbWVudDIgLS0+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL2phdmEvdGV4dC9EZWNpbWFsRm9ybWF0LnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vamF2YS90ZXh0L0RlY2ltYWxGb3JtYXQuc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyMGZhNzgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL2phdmEvdGV4dC9EZWNpbWFsRm9ybWF0LnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL2phdmEvdGV4dC9EZWNpbWFsRm9ybWF0U3ltYm9scy5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL2phdmEvdGV4dC9EZWNpbWFsRm9ybWF0U3ltYm9scy5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmUwODZhZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vamF2YS90ZXh0L0RlY2ltYWxGb3JtYXRTeW1ib2xzLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sb2dnaW5nL3Rlc3RzL2phdmEvdXRpbC9sb2dnaW5nL0xldmVsVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbG9nZ2luZy90ZXN0cy9qYXZhL3V0aWwvbG9nZ2luZy9MZXZlbFRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MjFhMzY4Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbG9nZ2luZy90ZXN0cy9qYXZhL3V0aWwvbG9nZ2luZy9MZXZlbFRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sb2dnaW5nL3Rlc3RzL2phdmEvdXRpbC9sb2dnaW5nL0xvZ1JlY29yZFRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2xvZ2dpbmcvdGVzdHMvamF2YS91dGlsL2xvZ2dpbmcvTG9nUmVjb3JkVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk1NWM2ZmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sb2dnaW5nL3Rlc3RzL2phdmEvdXRpbC9sb2dnaW5nL0xvZ1JlY29yZFRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvaW8vRmlsZVRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9pby9GaWxlVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBhMTVhNjEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvaW8vRmlsZVRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvaW8vdGVzdF9hcnJheV9pbnRlZ2Vycy5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvaW8vdGVzdF9hcnJheV9pbnRlZ2Vycy5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2M1YTVlMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9pby90ZXN0X2FycmF5X2ludGVnZXJzLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvaW8vdGVzdF9hcnJheV9zdHJpbmdzLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9pby90ZXN0X2FycmF5X3N0cmluZ3Muc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVlMmRlMWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvaW8vdGVzdF9hcnJheV9zdHJpbmdzLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9FbnVtVGVzdC5nb2xkZW4uMC5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9FbnVtVGVzdC5nb2xkZW4uMC5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjlhNGQ3NQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9sYW5nL0VudW1UZXN0LmdvbGRlbi4wLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9FbnVtVGVzdC5nb2xkZW4uMS5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9FbnVtVGVzdC5nb2xkZW4uMS5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmZlODhlZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9sYW5nL0VudW1UZXN0LmdvbGRlbi4xLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9FbnVtVGVzdC5nb2xkZW4uMi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9FbnVtVGVzdC5nb2xkZW4uMi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGVmOGYwYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9sYW5nL0VudW1UZXN0LmdvbGRlbi4yLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9FbnVtVGVzdC5nb2xkZW4uMy5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9FbnVtVGVzdC5nb2xkZW4uMy5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDBhYzYxNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9sYW5nL0VudW1UZXN0LmdvbGRlbi4zLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9FbnVtVGVzdC5oYXJtb255LnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9sYW5nL0VudW1UZXN0Lmhhcm1vbnkuc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhlZjhmMGIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9FbnVtVGVzdC5oYXJtb255LnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTk0ZThiZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9sYW5nL0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9JbGxlZ2FsU3RhdGVFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9JbGxlZ2FsU3RhdGVFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTRiOTAyYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9sYW5nL0lsbGVnYWxTdGF0ZUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9TZWN1cml0eUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9sYW5nL1NlY3VyaXR5RXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2YWJmZDEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9TZWN1cml0eUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9TdHJpbmdCdWZmZXJUZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9TdHJpbmdCdWZmZXJUZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODYxYjRhYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9sYW5nL1N0cmluZ0J1ZmZlclRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL2xhbmcvU3RyaW5nQnVpbGRlclRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYjU0MjkwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL2xhbmcvU3RyaW5nQnVpbGRlclRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9VbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9sYW5nL1Vuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkxOTcxODgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbGFuZy9VbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbmV0L0h0dHBSZXRyeUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS9uZXQvSHR0cFJldHJ5RXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQwNDEzZWIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvbmV0L0h0dHBSZXRyeUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Db2xsZWN0aW9uc19DaGVja2VkQ29sbGVjdGlvbi5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvQ29sbGVjdGlvbnNfQ2hlY2tlZENvbGxlY3Rpb24uZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZWM4NDBlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvQ29sbGVjdGlvbnNfQ2hlY2tlZENvbGxlY3Rpb24uZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Db2xsZWN0aW9uc19DaGVja2VkTGlzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvQ29sbGVjdGlvbnNfQ2hlY2tlZExpc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOWE0MTIyCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvQ29sbGVjdGlvbnNfQ2hlY2tlZExpc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Db2xsZWN0aW9uc19DaGVja2VkTGlzdFJhbmRvbUFjY2Vzcy5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvQ29sbGVjdGlvbnNfQ2hlY2tlZExpc3RSYW5kb21BY2Nlc3MuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZmEyZDQzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvQ29sbGVjdGlvbnNfQ2hlY2tlZExpc3RSYW5kb21BY2Nlc3MuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Db2xsZWN0aW9uc19DaGVja2VkTWFwLmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Db2xsZWN0aW9uc19DaGVja2VkTWFwLmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTM0MTVmNgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL0NvbGxlY3Rpb25zX0NoZWNrZWRNYXAuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Db2xsZWN0aW9uc19DaGVja2VkU2V0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Db2xsZWN0aW9uc19DaGVja2VkU2V0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWQxZjMwNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL0NvbGxlY3Rpb25zX0NoZWNrZWRTZXQuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Db2xsZWN0aW9uc19DaGVja2VkU29ydGVkTWFwLmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Db2xsZWN0aW9uc19DaGVja2VkU29ydGVkTWFwLmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWNhOGZmYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL0NvbGxlY3Rpb25zX0NoZWNrZWRTb3J0ZWRNYXAuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Db2xsZWN0aW9uc19DaGVja2VkU29ydGVkU2V0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Db2xsZWN0aW9uc19DaGVja2VkU29ydGVkU2V0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDUyMGVkNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL0NvbGxlY3Rpb25zX0NoZWNrZWRTb3J0ZWRTZXQuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9EdXBsaWNhdGVGb3JtYXRGbGFnc0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL0R1cGxpY2F0ZUZvcm1hdEZsYWdzRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYyNmVhZGUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9EdXBsaWNhdGVGb3JtYXRGbGFnc0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Gb3JtYXRGbGFnc0NvbnZlcnNpb25NaXNtYXRjaEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL0Zvcm1hdEZsYWdzQ29udmVyc2lvbk1pc21hdGNoRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZmMWFmYjIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Gb3JtYXRGbGFnc0NvbnZlcnNpb25NaXNtYXRjaEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Gb3JtYXR0ZXJDbG9zZWRFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Gb3JtYXR0ZXJDbG9zZWRFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDJlOGRiYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL0Zvcm1hdHRlckNsb3NlZEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9IYXNoTWFwVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvSGFzaE1hcFRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Mjk1MTJhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvSGFzaE1hcFRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9JZGVudGl0eUhhc2hNYXBUZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9JZGVudGl0eUhhc2hNYXBUZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTFkODg0NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL0lkZW50aXR5SGFzaE1hcFRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9JbGxlZ2FsRm9ybWF0Q29kZVBvaW50RXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvSWxsZWdhbEZvcm1hdENvZGVQb2ludEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yM2RiMmM2Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvSWxsZWdhbEZvcm1hdENvZGVQb2ludEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9JbGxlZ2FsRm9ybWF0Q29udmVyc2lvbkV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL0lsbGVnYWxGb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUyYzg4MTcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9JbGxlZ2FsRm9ybWF0Q29udmVyc2lvbkV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9JbGxlZ2FsRm9ybWF0RmxhZ3NFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9JbGxlZ2FsRm9ybWF0RmxhZ3NFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjE0OTg3ZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL0lsbGVnYWxGb3JtYXRGbGFnc0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9JbGxlZ2FsRm9ybWF0UHJlY2lzaW9uRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvSWxsZWdhbEZvcm1hdFByZWNpc2lvbkV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lODIyYWVjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvSWxsZWdhbEZvcm1hdFByZWNpc2lvbkV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9JbGxlZ2FsRm9ybWF0V2lkdGhFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9JbGxlZ2FsRm9ybWF0V2lkdGhFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGUxYTI1YgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL0lsbGVnYWxGb3JtYXRXaWR0aEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9JbnB1dE1pc21hdGNoRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvSW5wdXRNaXNtYXRjaEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Yjc2OTMzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvSW5wdXRNaXNtYXRjaEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9NaXNzaW5nRm9ybWF0QXJndW1lbnRFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9NaXNzaW5nRm9ybWF0QXJndW1lbnRFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWE2Nzk3ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL01pc3NpbmdGb3JtYXRBcmd1bWVudEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9NaXNzaW5nRm9ybWF0V2lkdGhFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9NaXNzaW5nRm9ybWF0V2lkdGhFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTk3NzNhNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL01pc3NpbmdGb3JtYXRXaWR0aEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9VVUlEVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvVVVJRFRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45OTQ3YTNhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbHVuaS90ZXN0cy9qYXZhL3V0aWwvVVVJRFRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Vbmtub3duRm9ybWF0Q29udmVyc2lvbkV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL1Vua25vd25Gb3JtYXRDb252ZXJzaW9uRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIwYTU5Y2MKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Vbmtub3duRm9ybWF0Q29udmVyc2lvbkV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Vbmtub3duRm9ybWF0RmxhZ3NFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9sdW5pL3Rlc3RzL2phdmEvdXRpbC9Vbmtub3duRm9ybWF0RmxhZ3NFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTRiMjI3OAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L2x1bmkvdGVzdHMvamF2YS91dGlsL1Vua25vd25Gb3JtYXRGbGFnc0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODBlOGY3YwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9CdWZmZXJPdmVyZmxvd0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vQnVmZmVyVW5kZXJmbG93RXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvL3Rlc3RzL2phdmEvbmlvL0J1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZTBmYzZkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvL3Rlc3RzL2phdmEvbmlvL0J1ZmZlclVuZGVyZmxvd0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vSW52YWxpZE1hcmtFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vSW52YWxpZE1hcmtFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzI5ZGViZgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9JbnZhbGlkTWFya0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vUmVhZE9ubHlCdWZmZXJFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vUmVhZE9ubHlCdWZmZXJFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmJiYzg3NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9SZWFkT25seUJ1ZmZlckV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvQWxyZWFkeUNvbm5lY3RlZEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9jaGFubmVscy9BbHJlYWR5Q29ubmVjdGVkRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjliZDUzOWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvQWxyZWFkeUNvbm5lY3RlZEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvQXN5bmNocm9ub3VzQ2xvc2VFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmRiYWM3ZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9jaGFubmVscy9Bc3luY2hyb25vdXNDbG9zZUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvQ2FuY2VsbGVkS2V5RXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvL3Rlc3RzL2phdmEvbmlvL2NoYW5uZWxzL0NhbmNlbGxlZEtleUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MDI4OGRmCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvL3Rlc3RzL2phdmEvbmlvL2NoYW5uZWxzL0NhbmNlbGxlZEtleUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWYxZTczYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9jaGFubmVscy9DbG9zZWRCeUludGVycnVwdEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9jaGFubmVscy9DbG9zZWRDaGFubmVsRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVhNWI4MGEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvQ2xvc2VkU2VsZWN0b3JFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvQ2xvc2VkU2VsZWN0b3JFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTgzMTc0NgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9jaGFubmVscy9DbG9zZWRTZWxlY3RvckV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvQ29ubmVjdGlvblBlbmRpbmdFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvQ29ubmVjdGlvblBlbmRpbmdFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWUxNzI2MwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9jaGFubmVscy9Db25uZWN0aW9uUGVuZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvRmlsZUxvY2tJbnRlcnJ1cHRpb25FeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvRmlsZUxvY2tJbnRlcnJ1cHRpb25FeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDAyNDE5MQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9jaGFubmVscy9GaWxlTG9ja0ludGVycnVwdGlvbkV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9jaGFubmVscy9JbGxlZ2FsQmxvY2tpbmdNb2RlRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxNWM2NmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvSWxsZWdhbEJsb2NraW5nTW9kZUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvSWxsZWdhbFNlbGVjdG9yRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvL3Rlc3RzL2phdmEvbmlvL2NoYW5uZWxzL0lsbGVnYWxTZWxlY3RvckV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OWVkMDkxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvL3Rlc3RzL2phdmEvbmlvL2NoYW5uZWxzL0lsbGVnYWxTZWxlY3RvckV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvTm9Db25uZWN0aW9uUGVuZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9jaGFubmVscy9Ob0Nvbm5lY3Rpb25QZW5kaW5nRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAyMmQzYmMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvTm9Db25uZWN0aW9uUGVuZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvTm9uUmVhZGFibGVDaGFubmVsRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvL3Rlc3RzL2phdmEvbmlvL2NoYW5uZWxzL05vblJlYWRhYmxlQ2hhbm5lbEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Y2Y3NjdjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvL3Rlc3RzL2phdmEvbmlvL2NoYW5uZWxzL05vblJlYWRhYmxlQ2hhbm5lbEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvTm9uV3JpdGFibGVDaGFubmVsRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvL3Rlc3RzL2phdmEvbmlvL2NoYW5uZWxzL05vbldyaXRhYmxlQ2hhbm5lbEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNGE0MmU5Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvL3Rlc3RzL2phdmEvbmlvL2NoYW5uZWxzL05vbldyaXRhYmxlQ2hhbm5lbEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvTm90WWV0Qm91bmRFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvTm90WWV0Qm91bmRFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjlkMWE1NwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9jaGFubmVscy9Ob3RZZXRCb3VuZEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvTm90WWV0Q29ubmVjdGVkRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvL3Rlc3RzL2phdmEvbmlvL2NoYW5uZWxzL05vdFlldENvbm5lY3RlZEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNWNjMDI3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvL3Rlc3RzL2phdmEvbmlvL2NoYW5uZWxzL05vdFlldENvbm5lY3RlZEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvT3ZlcmxhcHBpbmdGaWxlTG9ja0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9jaGFubmVscy9PdmVybGFwcGluZ0ZpbGVMb2NrRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjljMGUxNzUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvT3ZlcmxhcHBpbmdGaWxlTG9ja0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvVW5yZXNvbHZlZEFkZHJlc3NFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvVW5yZXNvbHZlZEFkZHJlc3NFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmEyNGRlYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9jaGFubmVscy9VbnJlc29sdmVkQWRkcmVzc0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvVW5zdXBwb3J0ZWRBZGRyZXNzVHlwZUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pby90ZXN0cy9qYXZhL25pby9jaGFubmVscy9VbnN1cHBvcnRlZEFkZHJlc3NUeXBlRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFkZDZhMDEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW8vdGVzdHMvamF2YS9uaW8vY2hhbm5lbHMvVW5zdXBwb3J0ZWRBZGRyZXNzVHlwZUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW9fY2hhci90ZXN0cy9qYXZhL25pby9jaGFyc2V0L0NoYXJhY3RlckNvZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pb19jaGFyL3Rlc3RzL2phdmEvbmlvL2NoYXJzZXQvQ2hhcmFjdGVyQ29kaW5nRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE5NWM0ZTQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW9fY2hhci90ZXN0cy9qYXZhL25pby9jaGFyc2V0L0NoYXJhY3RlckNvZGluZ0V4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW9fY2hhci90ZXN0cy9qYXZhL25pby9jaGFyc2V0L0NvZGVyTWFsZnVuY3Rpb25FcnJvclRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pb19jaGFyL3Rlc3RzL2phdmEvbmlvL2NoYXJzZXQvQ29kZXJNYWxmdW5jdGlvbkVycm9yVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZmNGE0ZTMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW9fY2hhci90ZXN0cy9qYXZhL25pby9jaGFyc2V0L0NvZGVyTWFsZnVuY3Rpb25FcnJvclRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW9fY2hhci90ZXN0cy9qYXZhL25pby9jaGFyc2V0L0lsbGVnYWxDaGFyc2V0TmFtZUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pb19jaGFyL3Rlc3RzL2phdmEvbmlvL2NoYXJzZXQvSWxsZWdhbENoYXJzZXROYW1lRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5ZTRkMGIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW9fY2hhci90ZXN0cy9qYXZhL25pby9jaGFyc2V0L0lsbGVnYWxDaGFyc2V0TmFtZUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW9fY2hhci90ZXN0cy9qYXZhL25pby9jaGFyc2V0L01hbGZvcm1lZElucHV0RXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvX2NoYXIvdGVzdHMvamF2YS9uaW8vY2hhcnNldC9NYWxmb3JtZWRJbnB1dEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMmYwZGVjCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvbmlvX2NoYXIvdGVzdHMvamF2YS9uaW8vY2hhcnNldC9NYWxmb3JtZWRJbnB1dEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW9fY2hhci90ZXN0cy9qYXZhL25pby9jaGFyc2V0L1VubWFwcGFibGVDaGFyYWN0ZXJFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW9fY2hhci90ZXN0cy9qYXZhL25pby9jaGFyc2V0L1VubWFwcGFibGVDaGFyYWN0ZXJFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzkzM2ZiOQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pb19jaGFyL3Rlc3RzL2phdmEvbmlvL2NoYXJzZXQvVW5tYXBwYWJsZUNoYXJhY3RlckV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW9fY2hhci90ZXN0cy9qYXZhL25pby9jaGFyc2V0L1Vuc3VwcG9ydGVkQ2hhcnNldEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L25pb19jaGFyL3Rlc3RzL2phdmEvbmlvL2NoYXJzZXQvVW5zdXBwb3J0ZWRDaGFyc2V0RXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA3YzYzYmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9uaW9fY2hhci90ZXN0cy9qYXZhL25pby9jaGFyc2V0L1Vuc3VwcG9ydGVkQ2hhcnNldEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9wcmVmcy90ZXN0cy9qYXZhL3V0aWwvcHJlZnMvQmFja2luZ1N0b3JlRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvcHJlZnMvdGVzdHMvamF2YS91dGlsL3ByZWZzL0JhY2tpbmdTdG9yZUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZDI2MTEzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvcHJlZnMvdGVzdHMvamF2YS91dGlsL3ByZWZzL0JhY2tpbmdTdG9yZUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9wcmVmcy90ZXN0cy9qYXZhL3V0aWwvcHJlZnMvSW52YWxpZFByZWZlcmVuY2VzRm9ybWF0RXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvcHJlZnMvdGVzdHMvamF2YS91dGlsL3ByZWZzL0ludmFsaWRQcmVmZXJlbmNlc0Zvcm1hdEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMTU5NDhkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvcHJlZnMvdGVzdHMvamF2YS91dGlsL3ByZWZzL0ludmFsaWRQcmVmZXJlbmNlc0Zvcm1hdEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9yZWdleC90ZXN0cy9qYXZhL3V0aWwvcmVnZXgvUGF0dGVyblN5bnRheEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L3JlZ2V4L3Rlc3RzL2phdmEvdXRpbC9yZWdleC9QYXR0ZXJuU3ludGF4RXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjYyM2Q2YWMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9yZWdleC90ZXN0cy9qYXZhL3V0aWwvcmVnZXgvUGF0dGVyblN5bnRheEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9yZWdleC90ZXN0cy9qYXZhL3V0aWwvcmVnZXgvUGF0dGVyblRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L3JlZ2V4L3Rlc3RzL2phdmEvdXRpbC9yZWdleC9QYXR0ZXJuVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjYxNTBhZGYKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9yZWdleC90ZXN0cy9qYXZhL3V0aWwvcmVnZXgvUGF0dGVyblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9zcWwvdGVzdHMvamF2YS9zcWwvQmF0Y2hVcGRhdGVFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9zcWwvdGVzdHMvamF2YS9zcWwvQmF0Y2hVcGRhdGVFeGNlcHRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDIwZWVkMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L3NxbC90ZXN0cy9qYXZhL3NxbC9CYXRjaFVwZGF0ZUV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9zcWwvdGVzdHMvamF2YS9zcWwvRGF0YVRydW5jYXRpb25UZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9zcWwvdGVzdHMvamF2YS9zcWwvRGF0YVRydW5jYXRpb25UZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWVjZDZlMQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L3NxbC90ZXN0cy9qYXZhL3NxbC9EYXRhVHJ1bmNhdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9zcWwvdGVzdHMvamF2YS9zcWwvU1FMRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvc3FsL3Rlc3RzL2phdmEvc3FsL1NRTEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZTU4NjYwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvc3FsL3Rlc3RzL2phdmEvc3FsL1NRTEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9zcWwvdGVzdHMvamF2YS9zcWwvU1FMV2FybmluZ1Rlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L3NxbC90ZXN0cy9qYXZhL3NxbC9TUUxXYXJuaW5nVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJlMzdjYjgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9zcWwvdGVzdHMvamF2YS9zcWwvU1FMV2FybmluZ1Rlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9zcWwvdGVzdHMvamF2YS9zcWwvVGltZXN0YW1wVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvc3FsL3Rlc3RzL2phdmEvc3FsL1RpbWVzdGFtcFRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZTUxYTBhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvc3FsL3Rlc3RzL2phdmEvc3FsL1RpbWVzdGFtcFRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9zcWwvdGVzdHMvamF2YXgvc3FsL0Nvbm5lY3Rpb25FdmVudFRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L3NxbC90ZXN0cy9qYXZheC9zcWwvQ29ubmVjdGlvbkV2ZW50VGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY0MmUyZmMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9zcWwvdGVzdHMvamF2YXgvc3FsL0Nvbm5lY3Rpb25FdmVudFRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9zcWwvdGVzdHMvamF2YXgvc3FsL3Jvd3NldC9Sb3dTZXRNZXRhRGF0YUltcGxUZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9zcWwvdGVzdHMvamF2YXgvc3FsL3Jvd3NldC9Sb3dTZXRNZXRhRGF0YUltcGxUZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWRkOGJlZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vb3JnL2FwYWNoZS9oYXJtb255L3NxbC90ZXN0cy9qYXZheC9zcWwvcm93c2V0L1Jvd1NldE1ldGFEYXRhSW1wbFRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL29yZy9hcGFjaGUvaGFybW9ueS9zcWwvdGVzdHMvamF2YXgvc3FsL3Jvd3NldC9zZXJpYWwvU2VyaWFsRXhjZXB0aW9uVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvc3FsL3Rlc3RzL2phdmF4L3NxbC9yb3dzZXQvc2VyaWFsL1NlcmlhbEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MWVkNDcxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi9vcmcvYXBhY2hlL2hhcm1vbnkvc3FsL3Rlc3RzL2phdmF4L3NxbC9yb3dzZXQvc2VyaWFsL1NlcmlhbEV4Y2VwdGlvblRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL2lvL3Rlc3RDb21wdXRlU1VJRENsYXNzLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vdGVzdHMvYXBpL2phdmEvaW8vdGVzdENvbXB1dGVTVUlEQ2xhc3Muc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI5M2RmMjQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL2lvL3Rlc3RDb21wdXRlU1VJRENsYXNzLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL2lvL3Rlc3RDb21wdXRlU1VJRENvbnN0cnVjdG9ycy5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL2lvL3Rlc3RDb21wdXRlU1VJRENvbnN0cnVjdG9ycy5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTMzM2Y0ZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vdGVzdHMvYXBpL2phdmEvaW8vdGVzdENvbXB1dGVTVUlEQ29uc3RydWN0b3JzLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL2lvL3Rlc3RDb21wdXRlU1VJREZpZWxkcy5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL2lvL3Rlc3RDb21wdXRlU1VJREZpZWxkcy5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2Y5MzEzNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vdGVzdHMvYXBpL2phdmEvaW8vdGVzdENvbXB1dGVTVUlERmllbGRzLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL2lvL3Rlc3RDb21wdXRlU1VJREludGVyZmFjZXMuc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi90ZXN0cy9hcGkvamF2YS9pby90ZXN0Q29tcHV0ZVNVSURJbnRlcmZhY2VzLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNTc5ZDE0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi90ZXN0cy9hcGkvamF2YS9pby90ZXN0Q29tcHV0ZVNVSURJbnRlcmZhY2VzLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL2lvL3Rlc3RDb21wdXRlU1VJRE1ldGhvZHMuc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi90ZXN0cy9hcGkvamF2YS9pby90ZXN0Q29tcHV0ZVNVSURNZXRob2RzLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ODYxOGViCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi90ZXN0cy9hcGkvamF2YS9pby90ZXN0Q29tcHV0ZVNVSURNZXRob2RzLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL3V0aWwvRW51bU1hcFRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vdGVzdHMvYXBpL2phdmEvdXRpbC9FbnVtTWFwVGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2Zjc2NjgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL3V0aWwvRW51bU1hcFRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL3V0aWwvRW51bVNldFRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vdGVzdHMvYXBpL2phdmEvdXRpbC9FbnVtU2V0VGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY2MDQwZTUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL3V0aWwvRW51bVNldFRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL3V0aWwvSGFzaFNldFRlc3QuZ29sZGVuLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vdGVzdHMvYXBpL2phdmEvdXRpbC9IYXNoU2V0VGVzdC5nb2xkZW4uc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVkNzZhMzIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL3V0aWwvSGFzaFNldFRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL3V0aWwvSWRlbnRpdHlIYXNoTWFwVGVzdC5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi90ZXN0cy9hcGkvamF2YS91dGlsL0lkZW50aXR5SGFzaE1hcFRlc3QuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZjI3OTM3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi90ZXN0cy9hcGkvamF2YS91dGlsL0lkZW50aXR5SGFzaE1hcFRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL2FwaS9qYXZhL3V0aWwvUHJpb3JpdHlRdWV1ZS5nb2xkZW4uc2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi90ZXN0cy9hcGkvamF2YS91dGlsL1ByaW9yaXR5UXVldWUuZ29sZGVuLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNzE2ZGRhCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi90ZXN0cy9hcGkvamF2YS91dGlsL1ByaW9yaXR5UXVldWUuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhUZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydFBhdGhUZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTYwMmUzNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aFRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVUZXN0LmdvbGRlbi5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zZXJpYWxpemF0aW9uL3Rlc3RzL3NlY3VyaXR5L2NlcnQvQ2VydGlmaWNhdGVUZXN0LmdvbGRlbi5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjdlMmE5YQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vdGVzdHMvc2VjdXJpdHkvY2VydC9DZXJ0aWZpY2F0ZVRlc3QuZ29sZGVuLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zaW1wbGUueG1sIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2ltcGxlLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZTM5MTgxCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2ltcGxlLnhtbApAQCAtMCwwICsxLDM0IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJJU08tODg1OS0xIj8+Cis8IS0tIEVkaXRlZCB3aXRoIFhNTCBTcHkgdjIwMDcgKGh0dHA6Ly93d3cuYWx0b3ZhLmNvbSkgLS0+Cis8YnJlYWtmYXN0X21lbnU+CisJPGZvb2Q+CisJCTxuYW1lPkJlbGdpYW4gV2FmZmxlczwvbmFtZT4KKwkJPHByaWNlPiQ1Ljk1PC9wcmljZT4KKwkJPGRlc2NyaXB0aW9uPnR3byBvZiBvdXIgZmFtb3VzIEJlbGdpYW4gV2FmZmxlcyB3aXRoIHBsZW50eSBvZiByZWFsIG1hcGxlIHN5cnVwPC9kZXNjcmlwdGlvbj4KKwkJPGNhbG9yaWVzPjY1MDwvY2Fsb3JpZXM+CisJPC9mb29kPgorCTxmb29kPgorCQk8bmFtZT5TdHJhd2JlcnJ5IEJlbGdpYW4gV2FmZmxlczwvbmFtZT4KKwkJPHByaWNlPiQ3Ljk1PC9wcmljZT4KKwkJPGRlc2NyaXB0aW9uPmxpZ2h0IEJlbGdpYW4gd2FmZmxlcyBjb3ZlcmVkIHdpdGggc3RyYXdiZXJyaWVzIGFuZCB3aGlwcGVkIGNyZWFtPC9kZXNjcmlwdGlvbj4KKwkJPGNhbG9yaWVzPjkwMDwvY2Fsb3JpZXM+CisJPC9mb29kPgorCTxmb29kPgorCQk8bmFtZT5CZXJyeS1CZXJyeSBCZWxnaWFuIFdhZmZsZXM8L25hbWU+CisJCTxwcmljZT4kOC45NTwvcHJpY2U+CisJCTxkZXNjcmlwdGlvbj5saWdodCBCZWxnaWFuIHdhZmZsZXMgY292ZXJlZCB3aXRoIGFuIGFzc29ydG1lbnQgb2YgZnJlc2ggYmVycmllcyBhbmQgd2hpcHBlZCBjcmVhbTwvZGVzY3JpcHRpb24+CisJCTxjYWxvcmllcz45MDA8L2NhbG9yaWVzPgorCTwvZm9vZD4KKwk8Zm9vZD4KKwkJPG5hbWU+RnJlbmNoIFRvYXN0PC9uYW1lPgorCQk8cHJpY2U+JDQuNTA8L3ByaWNlPgorCQk8ZGVzY3JpcHRpb24+dGhpY2sgc2xpY2VzIG1hZGUgZnJvbSBvdXIgaG9tZW1hZGUgc291cmRvdWdoIGJyZWFkPC9kZXNjcmlwdGlvbj4KKwkJPGNhbG9yaWVzPjYwMDwvY2Fsb3JpZXM+CisJPC9mb29kPgorCTxmb29kPgorCQk8bmFtZT5Ib21lc3R5bGUgQnJlYWtmYXN0PC9uYW1lPgorCQk8cHJpY2U+JDYuOTU8L3ByaWNlPgorCQk8ZGVzY3JpcHRpb24+dHdvIGVnZ3MsIGJhY29uIG9yIHNhdXNhZ2UsIHRvYXN0LCBhbmQgb3VyIGV2ZXItcG9wdWxhciBoYXNoIGJyb3duczwvZGVzY3JpcHRpb24+CisJCTxjYWxvcmllcz45NTA8L2NhbG9yaWVzPgorCTwvZm9vZD4KKzwvYnJlYWtmYXN0X21lbnU+CmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zaW1wbGVfbnMuZHRkIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2ltcGxlX25zLmR0ZApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NjQzNzczCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2ltcGxlX25zLmR0ZApAQCAtMCwwICsxLDQ1IEBACis8IUVMRU1FTlQgc3RhZmYgKGVtcGxveWVlKyxlbXA6ZW1wbG95ZWUsZW1wbG95ZWUpID4KKzwhRUxFTUVOVCBlbXBsb3llZSAoZW1wbG95ZWVJZCxuYW1lLHBvc2l0aW9uLHNhbGFyeSxnZW5kZXIsYWRkcmVzcykgPgorPCFBVFRMSVNUIGVtcGxveWVlIHhtbG5zIENEQVRBICNJTVBMSUVEPgorPCFBVFRMSVNUIGVtcGxveWVlIHhtbG5zOmRtc3RjIENEQVRBICNJTVBMSUVEPgorPCFBVFRMSVNUIGVtcGxveWVlIHhtbG5zOmVtcDIgQ0RBVEEgI0lNUExJRUQ+CisKKzwhRUxFTUVOVCBlbXBsb3llZUlkICgjUENEQVRBKSA+CisKKzwhRUxFTUVOVCBuYW1lICgjUENEQVRBKSA+CisKKzwhRUxFTUVOVCBwb3NpdGlvbiAoI1BDREFUQSkgPgorCis8IUVMRU1FTlQgc2FsYXJ5ICgjUENEQVRBKSA+CisKKzwhRUxFTUVOVCBlbnRFbGVtZW50MSAoI1BDREFUQSkgPgorPCFFTEVNRU5UIGdlbmRlciAoI1BDREFUQSB8IGVudEVsZW1lbnQxKSogPgorPCFBVFRMSVNUIGVudEVsZW1lbnQxIHhtbG5zOmxvY2FsMSBDREFUQSAjSU1QTElFRCA+CisKKzwhRUxFTUVOVCBhZGRyZXNzICgjUENEQVRBKSA+Cis8IUFUVExJU1QgYWRkcmVzcyBkbXN0Yzpkb21lc3RpYyBDREFUQSAjSU1QTElFRD4KKzwhQVRUTElTVCBhZGRyZXNzIHN0cmVldCBDREFUQSAjSU1QTElFRD4KKzwhQVRUTElTVCBhZGRyZXNzIGRvbWVzdGljIENEQVRBICNJTVBMSUVEPgorPCFBVFRMSVNUIGFkZHJlc3MgeG1sbnMgQ0RBVEEgI0lNUExJRUQ+CisKKzwhRUxFTUVOVCBlbXA6ZW1wbG95ZWUgKGVtcDplbXBsb3llZUlkLG5tOm5hbWUsZW1wOnBvc2l0aW9uLGVtcDpzYWxhcnksZW1wOmdlbmRlcixlbXA6YWRkcmVzcykgPgorPCFBVFRMSVNUIGVtcDplbXBsb3llZSB4bWxuczplbXAgQ0RBVEEgI0lNUExJRUQ+Cis8IUFUVExJU1QgZW1wOmVtcGxveWVlIHhtbG5zOm5tIENEQVRBICNJTVBMSUVEPgorPCFBVFRMSVNUIGVtcDplbXBsb3llZSBkZWZhdWx0QXR0ciBDREFUQSAnZGVmYXVsdFZhbCc+CisKKzwhRUxFTUVOVCBlbXA6ZW1wbG95ZWVJZCAoI1BDREFUQSkgPgorCis8IUVMRU1FTlQgbm06bmFtZSAoI1BDREFUQSkgPgorCis8IUVMRU1FTlQgZW1wOnBvc2l0aW9uICgjUENEQVRBKSA+CisKKzwhRUxFTUVOVCBlbXA6c2FsYXJ5ICgjUENEQVRBKSA+CisKKzwhRUxFTUVOVCBlbXA6Z2VuZGVyICgjUENEQVRBKSA+CisKKzwhRUxFTUVOVCBlbXA6YWRkcmVzcyAoI1BDREFUQSkgPgorPCFBVFRMSVNUIGVtcDphZGRyZXNzIGVtcDpkb21lc3RpYyBDREFUQSAjSU1QTElFRD4KKzwhQVRUTElTVCBlbXA6YWRkcmVzcyBzdHJlZXQgQ0RBVEEgI0lNUExJRUQ+Cis8IUFUVExJU1QgZW1wOmFkZHJlc3MgZW1wOnpvbmUgSUQgI0lNUExJRUQ+Cis8IUFUVExJU1QgZW1wOmFkZHJlc3MgZW1wOmRpc3RyaWN0IENEQVRBICdESVNUUklDVCc+Cis8IUFUVExJU1QgZW1wOmFkZHJlc3MgZW1wOmxvY2FsMSBDREFUQSAnRkFMU0UnPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc2ltcGxlX25zLnhtbCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NpbXBsZV9ucy54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTVkYzRhMwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3NpbXBsZV9ucy54bWwKQEAgLTAsMCArMSw1OSBAQAorPD94bWwgdmVyc2lvbj0iMS4wIj8+PD9URVNULVNUWUxFIFBJREFUQT8+Cis8IURPQ1RZUEUgc3RhZmYgUFVCTElDICJTVEFGRiIgInNpbXBsZV9ucy5kdGQiIAorWworICAgPCFFTlRJVFkgZW50MSAiZXMiPgorICAgPCFFTlRJVFkgZW50MiAiMTkwMCBEYWxsYXMgUm9hZCI+CisgICA8IUVOVElUWSBlbnQzICJUZXhhcyI+CisgICA8IUVOVElUWSBlbnQ0ICI8ZW50RWxlbWVudDEgeG1sbnM6bG9jYWwxPSd3d3cueHl6LmNvbSc+RWxlbWVudCBkYXRhPC9lbnRFbGVtZW50MT48P1BJdGFyZ2V0IFBJZGF0YT8+Ij4KKyAgIDwhRU5USVRZIGVudDUgUFVCTElDICJlbnRpdHlVUkkiICJlbnRpdHlGaWxlIiBOREFUQSBub3RhdGlvbjE+CisgICA8IUVOVElUWSBlbnQ2IFBVQkxJQyAidXJpIiAiZmlsZSIgTkRBVEEgbm90YXRpb24yPgorICAgPCFFTlRJVFkgZW50MSAiVGhpcyBlbnRpdHkgc2hvdWxkIGJlIGRpc2NhcmRlZCI+CisgICA8IU5PVEFUSU9OIG5vdGF0aW9uMSBQVUJMSUMgIm5vdGF0aW9uMUZpbGUiPgorICAgPCFOT1RBVElPTiBub3RhdGlvbjIgU1lTVEVNICJub3RhdGlvbjJGaWxlIj4KK10+Cis8IS0tIFRoaXMgaXMgY29tbWVudCBudW1iZXIgMS4tLT4KKzxzdGFmZj4KKyA8ZW1wbG95ZWUgeG1sbnM9Imh0dHA6Ly93d3cubmlzdC5nb3YiIHhtbG5zOmRtc3RjPSJodHRwOi8vd3d3LnVzYS5jb20iPgorICA8ZW1wbG95ZWVJZD5FTVAwMDAxPC9lbXBsb3llZUlkPgorICA8bmFtZT5NYXJnYXJldCBNYXJ0aW48L25hbWU+CisgIDxwb3NpdGlvbj5BY2NvdW50YW50PC9wb3NpdGlvbj4gICAgICAgICAgIAorICA8c2FsYXJ5PjU2LDAwMDwvc2FsYXJ5PgorICA8Z2VuZGVyPkZlbWFsZTwvZ2VuZGVyPgorICA8YWRkcmVzcyBkbXN0Yzpkb21lc3RpYz0iWWVzIj4xMjMwIE5vcnRoIEF2ZS4gRGFsbGFzLCBUZXhhcyA5ODU1MTwvYWRkcmVzcz4KKyA8L2VtcGxveWVlPgorIDxlbXBsb3llZSB4bWxuczpkbXN0Yz0iaHR0cDovL3d3dy51c2EuY29tIj4KKyAgPGVtcGxveWVlSWQ+RU1QMDAwMjwvZW1wbG95ZWVJZD4KKyAgPG5hbWU+TWFydGhhIFJheW5vbGRzCis8IVtDREFUQVtUaGlzIGlzIGEgQ0RBVEFTZWN0aW9uIHdpdGggRW50aXR5UmVmZXJlbmNlIG51bWJlciAyICZlbnQyO11dPgorPCFbQ0RBVEFbVGhpcyBpcyBhbiBhZGphY2VudCBDREFUQVNlY3Rpb24gd2l0aCBhIHJlZmVyZW5jZSB0byBhIHRhYiAmdGFiO11dPjwvbmFtZT4KKyAgPHBvc2l0aW9uPlNlY3JldGFyeTwvcG9zaXRpb24+CisgIDxzYWxhcnk+MzUsMDAwPC9zYWxhcnk+CisgIDxnZW5kZXI+RmVtYWxlPC9nZW5kZXI+CisgIDxhZGRyZXNzIGRtc3RjOmRvbWVzdGljPSJZZXMiIHN0cmVldD0iWWVzIj4mZW50MjsgRGFsbGFzLCAmZW50MzsKKyA5ODU1NDwvYWRkcmVzcz4KKyA8L2VtcGxveWVlPgorIDxlbXBsb3llZSB4bWxuczpkbXN0Yz0iaHR0cDovL3d3dy5uZXR6ZXJvLmNvbSI+CisgIDxlbXBsb3llZUlkPkVNUDAwMDM8L2VtcGxveWVlSWQ+CisgIDxuYW1lPlJvZ2VyCisgSm9uZXM8L25hbWU+CisgIDxwb3NpdGlvbj5EZXBhcnRtZW50IE1hbmFnZXI8L3Bvc2l0aW9uPgorICA8c2FsYXJ5PjEwMCwwMDA8L3NhbGFyeT4KKyAgPGdlbmRlcj4mZW50NDs8L2dlbmRlcj4KKyAgPGFkZHJlc3MgZG1zdGM6ZG9tZXN0aWM9IlllcyIgc3RyZWV0PSJObyI+UE8gQm94IDI3IElydmluZywgdGV4YXMgOTg1NTM8L2FkZHJlc3M+CisgPC9lbXBsb3llZT4KKyA8ZW1wOmVtcGxveWVlIHhtbG5zOmVtcD0iaHR0cDovL3d3dy5uaXN0LmdvdiIgeG1sbnM6bm09Imh0dHA6Ly93d3cuYWx0YXZpc3RhLmNvbSIgPiAgICA8ZW1wOmVtcGxveWVlSWQ+RU1QMDAwNDwvZW1wOmVtcGxveWVlSWQ+CisgIDxubTpuYW1lPkplbnkgT2Nvbm5vcjwvbm06bmFtZT4KKyAgPGVtcDpwb3NpdGlvbj5QZXJzb25uZWwgRGlyZWN0b3I8L2VtcDpwb3NpdGlvbj4KKyAgPGVtcDpzYWxhcnk+OTUsMDAwPC9lbXA6c2FsYXJ5PgorICA8ZW1wOmdlbmRlcj5GZW1hbGU8L2VtcDpnZW5kZXI+CisgIDxlbXA6YWRkcmVzcyBlbXA6ZG9tZXN0aWM9IlllcyIgc3RyZWV0PSJZJmVudDE7IiBlbXA6em9uZT0iQ0FOQURBIiBlbXA6bG9jYWwxPSJUUlVFIj4yNyBTb3V0aCBSb2FkLiBEYWxsYXMsIHRleGFzIDk4NTU2PC9lbXA6YWRkcmVzcz4KKyA8L2VtcDplbXBsb3llZT4KKyA8ZW1wbG95ZWUgeG1sbnM6ZW1wMj0iaHR0cDovL3d3dy5uaXN0LmdvdiI+CisgIDxlbXBsb3llZUlkPkVNUDAwMDU8L2VtcGxveWVlSWQ+CisgIDxuYW1lPlJvYmVydCBNeWVyczwvbmFtZT4KKyAgPHBvc2l0aW9uPkNvbXB1dGVyIFNwZWNpYWxpc3Q8L3Bvc2l0aW9uPgorICA8c2FsYXJ5PjkwLDAwMDwvc2FsYXJ5PgorICA8Z2VuZGVyPm1hbGU8L2dlbmRlcj4KKyAgPGFkZHJlc3Mgc3RyZWV0PSJZZXMiIHhtbG5zPSJodHRwOi8vd3d3Lm5pc3QuZ292Ij4xODIxIE5vcmRpYy4gUm9hZCwgSXJ2aW5nIFRleGFzIDk4NTU4PC9hZGRyZXNzPgorIDwvZW1wbG95ZWU+CisgPC9zdGFmZj4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3N0YWZmRW50UmVzLnhtbCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3N0YWZmRW50UmVzLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYzI0YzgzCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc3RhZmZFbnRSZXMueG1sCkBAIC0wLDAgKzEsNjAgQEAKKzw/eG1sIHZlcnNpb249IjEuMCI/Pjw/VEVTVC1TVFlMRSBQSURBVEE/PgorPCFET0NUWVBFIHN0YWZmCitbCisgICA8IUVOVElUWSBlbnQxICJlcyI+CisgICA8IUVOVElUWSBlbnQyICIxOTAwIERhbGxhcyBSb2FkIj4KKyAgIDwhRU5USVRZIGVudDMgIlRleGFzIj4KKyAgIDwhRU5USVRZIGNoYXAxIFNZU1RFTSAiY2hhcDEueG1sIj4KKyAgIDwhRU5USVRZIGVudDQgIjxlbnRFbGVtZW50MSB4bWxuczpsb2NhbDE9J3d3dy54eXouY29tJz5FbGVtZW50IGRhdGE8L2VudEVsZW1lbnQxPjw/UEl0YXJnZXQgUElkYXRhPz4iPgorICAgPCFFTlRJVFkgZW50NSBQVUJMSUMgImVudGl0eVVSSSIgImVudGl0eUZpbGUiIE5EQVRBIG5vdGF0aW9uMT4KKyAgIDwhRU5USVRZIGVudDYgUFVCTElDICJ1cmkiICJmaWxlIiBOREFUQSBub3RhdGlvbjI+CisgICA8IUVOVElUWSBlbnQxICJUaGlzIGVudGl0eSBzaG91bGQgYmUgZGlzY2FyZGVkIj4KKyAgIDwhTk9UQVRJT04gbm90YXRpb24xIFBVQkxJQyAibm90YXRpb24xRmlsZSI+CisgICA8IU5PVEFUSU9OIG5vdGF0aW9uMiBTWVNURU0gIm5vdGF0aW9uMkZpbGUiPgorXT4KKzwhLS0gVGhpcyBpcyBjb21tZW50IG51bWJlciAxLi0tPgorPHN0YWZmPgorIDxlbXBsb3llZSB4bWxucz0iaHR0cDovL3d3dy5uaXN0LmdvdiIgeG1sbnM6ZG1zdGM9Imh0dHA6Ly93d3cudXNhLmNvbSI+CisgIDxlbXBsb3llZUlkPkVNUDAwMDE8L2VtcGxveWVlSWQ+CisgIDxuYW1lPk1hcmdhcmV0IE1hcnRpbjwvbmFtZT4KKyAgPHBvc2l0aW9uPkFjY291bnRhbnQ8L3Bvc2l0aW9uPiAgICAgICAgICAgCisgIDxzYWxhcnk+NTYsMDAwPC9zYWxhcnk+CisgIDxnZW5kZXI+RmVtYWxlPC9nZW5kZXI+CisgIDxhZGRyZXNzIGRtc3RjOmRvbWVzdGljPSJZZXMiPjEyMzAgTm9ydGggQXZlLiBEYWxsYXMsIFRleGFzIDk4NTUxPC9hZGRyZXNzPgorIDwvZW1wbG95ZWU+CisgPGVtcGxveWVlIHhtbG5zOmRtc3RjPSJodHRwOi8vd3d3LnVzYS5jb20iPgorICA8ZW1wbG95ZWVJZD5FTVAwMDAyPC9lbXBsb3llZUlkPgorICA8bmFtZT5NYXJ0aGEgUmF5bm9sZHMgJmNoYXAxOyAKKzwhW0NEQVRBW1RoaXMgaXMgYSBDREFUQVNlY3Rpb24gd2l0aCBFbnRpdHlSZWZlcmVuY2UgbnVtYmVyIDIgJmVudDI7XV0+Cis8IVtDREFUQVtUaGlzIGlzIGFuIGFkamFjZW50IENEQVRBU2VjdGlvbiB3aXRoIGEgcmVmZXJlbmNlIHRvIGEgdGFiICZ0YWI7XV0+PC9uYW1lPgorICA8cG9zaXRpb24+U2VjcmV0YXJ5PC9wb3NpdGlvbj4KKyAgPHNhbGFyeT4zNSwwMDA8L3NhbGFyeT4KKyAgPGdlbmRlcj5GZW1hbGU8L2dlbmRlcj4KKyAgPGFkZHJlc3MgZG1zdGM6ZG9tZXN0aWM9IlllcyIgc3RyZWV0PSJZZXMiPiZlbnQyOyBEYWxsYXMsICZlbnQzOworIDk4NTU0PC9hZGRyZXNzPgorIDwvZW1wbG95ZWU+CisgPGVtcGxveWVlIHhtbG5zOmRtc3RjPSJodHRwOi8vd3d3Lm5ldHplcm8uY29tIj4KKyAgPGVtcGxveWVlSWQ+RU1QMDAwMzwvZW1wbG95ZWVJZD4KKyAgPG5hbWU+Um9nZXIKKyBKb25lczwvbmFtZT4KKyAgPHBvc2l0aW9uPkRlcGFydG1lbnQgTWFuYWdlcjwvcG9zaXRpb24+CisgIDxzYWxhcnk+MTAwLDAwMDwvc2FsYXJ5PgorICA8Z2VuZGVyPiZlbnQ0OzwvZ2VuZGVyPgorICA8YWRkcmVzcyBkbXN0Yzpkb21lc3RpYz0iWWVzIiBzdHJlZXQ9Ik5vIj5QTyBCb3ggMjcgSXJ2aW5nLCB0ZXhhcyA5ODU1MzwvYWRkcmVzcz4KKyA8L2VtcGxveWVlPgorIDxlbXA6ZW1wbG95ZWUgeG1sbnM6ZW1wPSJodHRwOi8vd3d3Lm5pc3QuZ292IiB4bWxuczpubT0iaHR0cDovL3d3dy5hbHRhdmlzdGEuY29tIiA+ICAgIDxlbXA6ZW1wbG95ZWVJZD5FTVAwMDA0PC9lbXA6ZW1wbG95ZWVJZD4KKyAgPG5tOm5hbWU+SmVueSBPY29ubm9yPC9ubTpuYW1lPgorICA8ZW1wOnBvc2l0aW9uPlBlcnNvbm5lbCBEaXJlY3RvcjwvZW1wOnBvc2l0aW9uPgorICA8ZW1wOnNhbGFyeT45NSwwMDA8L2VtcDpzYWxhcnk+CisgIDxlbXA6Z2VuZGVyPkZlbWFsZTwvZW1wOmdlbmRlcj4KKyAgPGVtcDphZGRyZXNzIGVtcDpkb21lc3RpYz0iWWVzIiBzdHJlZXQ9IlkmZW50MTsiIGVtcDp6b25lPSJDQU5BREEiIGVtcDpsb2NhbDE9IlRSVUUiPjI3IFNvdXRoIFJvYWQuIERhbGxhcywgdGV4YXMgOTg1NTY8L2VtcDphZGRyZXNzPgorIDwvZW1wOmVtcGxveWVlPgorIDxlbXBsb3llZSB4bWxuczplbXAyPSJodHRwOi8vd3d3Lm5pc3QuZ292Ij4KKyAgPGVtcGxveWVlSWQ+RU1QMDAwNTwvZW1wbG95ZWVJZD4KKyAgPG5hbWU+Um9iZXJ0IE15ZXJzPC9uYW1lPgorICA8cG9zaXRpb24+Q29tcHV0ZXIgU3BlY2lhbGlzdDwvcG9zaXRpb24+CisgIDxzYWxhcnk+OTAsMDAwPC9zYWxhcnk+CisgIDxnZW5kZXI+bWFsZTwvZ2VuZGVyPgorICA8YWRkcmVzcyBzdHJlZXQ9IlllcyIgeG1sbnM9Imh0dHA6Ly93d3cubmlzdC5nb3YiPjE4MjEgTm9yZGljLiBSb2FkLCBJcnZpbmcgVGV4YXMgOTg1NTg8L2FkZHJlc3M+CisgPC9lbXBsb3llZT4KKyA8L3N0YWZmPgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc3lzdGVtaWQueG1sIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc3lzdGVtaWQueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3Y2YwZmIKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zeXN0ZW1pZC54bWwKQEAgLTAsMCArMSwyNCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KKzwhRE9DVFlQRSBjb2xsZWN0aW9uIFNZU1RFTSAiLi9yZWNpcHQuZHRkIj4KKzwhLS1jb21tZW50MSAtLT4KKzxjb2xsZWN0aW9uPgorICA8ZGVzY3JpcHRpb24+CisgICAgIFNvbWUgcmVjaXBlcyB1c2VkIGZvciB0aGUgWE1MIHR1dG9yaWFsLgorICA8L2Rlc2NyaXB0aW9uPgorICA8cmVjaXBlPgorICAgIDx0aXRsZT5CZWVmIFBhcm1lc2FuPCFbQ0RBVEFbPHRpdGxlPiB3aXRoIEdhcmxpYyBBbmdlbCBIYWlyIFBhc3RhPC90aXRsZT5dXT48L3RpdGxlPgorICAgIDxpbmdyZWRpZW50IG5hbWU9ImJlZWYgY3ViZSBzdGVhayIgYW1vdW50PSIxLjUiIHVuaXQ9InBvdW5kIi8+CisgICAgPHByZXBhcmF0aW9uPgorICAgICAgPHN0ZXA+CisgICAgICAgIFByZWhlYXQgb3ZlbiB0byAzNTAgZGVncmVlcyBGICgxNzUgZGVncmVlcyBDKS4KKyAgICAgIDwvc3RlcD4KKyAgICA8L3ByZXBhcmF0aW9uPgorICAgIDxjb21tZW50PgorICAgICAgTWFrZSB0aGUgbWVhdCBhaGVhZCBvZiB0aW1lLCBhbmQgcmVmcmlnZXJhdGUgb3ZlciBuaWdodCwgdGhlIGFjaWQgaW4gdGhlCisgICAgICB0b21hdG8gc2F1Y2Ugd2lsbCB0ZW5kZXJpemUgdGhlIG1lYXQgZXZlbiBtb3JlLiBJZiB5b3UgZG8gdGhpcywgc2F2ZSB0aGUKKyAgICAgIG1venphcmVsbGEgdGlsbCB0aGUgbGFzdCBtaW51dGUuCisgICAgPC9jb21tZW50PgorICAgIDxudXRyaXRpb24gY2Fsb3JpZXM9IjExNjciIGZhdD0iMjMiIGNhcmJvaHlkcmF0ZXM9IjQ1IiBwcm90ZWluPSIzMiIvPgorICA8L3JlY2lwZT4KKzwvY29sbGVjdGlvbj4KKzwhLS1jb21tZW50MiAtLT4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3N5c3RlbWlkL3JlY2lwdC5kdGQgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zeXN0ZW1pZC9yZWNpcHQuZHRkCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM3MDExMmMKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy9zeXN0ZW1pZC9yZWNpcHQuZHRkCkBAIC0wLDAgKzEsMTcgQEAKKzwhRUxFTUVOVCBjb2xsZWN0aW9uIChkZXNjcmlwdGlvbixyZWNpcGUrKT4KKzwhRUxFTUVOVCBkZXNjcmlwdGlvbiBBTlk+Cis8IUVMRU1FTlQgcmVjaXBlICh0aXRsZSxpbmdyZWRpZW50KixwcmVwYXJhdGlvbixjb21tZW50PyxudXRyaXRpb24pPgorPCFFTEVNRU5UIHRpdGxlICgjUENEQVRBKT4KKzwhRUxFTUVOVCBpbmdyZWRpZW50IChpbmdyZWRpZW50KixwcmVwYXJhdGlvbik/PgorPCFBVFRMSVNUIGluZ3JlZGllbnQgbmFtZSBDREFUQSAjUkVRVUlSRUQKKyAgICAgICAgICAgICAgICAgICAgIGFtb3VudCBDREFUQSAjSU1QTElFRAorICAgICAgICAgICAgICAgICAgICAgdW5pdCBDREFUQSAjSU1QTElFRD4KKzwhRUxFTUVOVCBwcmVwYXJhdGlvbiAoc3RlcCopPgorPCFFTEVNRU5UIHN0ZXAgKCNQQ0RBVEEpPgorPCFFTEVNRU5UIGNvbW1lbnQgKCNQQ0RBVEEpPgorPCFFTEVNRU5UIG51dHJpdGlvbiBFTVBUWT4KKzwhQVRUTElTVCBudXRyaXRpb24gcHJvdGVpbiBDREFUQSAjUkVRVUlSRUQKKyAgICAgICAgICAgICAgICAgICAgY2FyYm9oeWRyYXRlcyBDREFUQSAjUkVRVUlSRUQKKyAgICAgICAgICAgICAgICAgICAgZmF0IENEQVRBICNSRVFVSVJFRAorICAgICAgICAgICAgICAgICAgICBjYWxvcmllcyBDREFUQSAjUkVRVUlSRUQKKyAgICAgICAgICAgICAgICAgICAgYWxjb2hvbCBDREFUQSAjSU1QTElFRD4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3N5c3RlbWlkL3N0YWZmLmR0ZCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3N5c3RlbWlkL3N0YWZmLmR0ZApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMmE5OTRkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvc3lzdGVtaWQvc3RhZmYuZHRkCkBAIC0wLDAgKzEsMTcgQEAKKzwhRUxFTUVOVCBlbXBsb3llZUlkICgjUENEQVRBKT4KKzwhRUxFTUVOVCBuYW1lICgjUENEQVRBKT4KKzwhRUxFTUVOVCBwb3NpdGlvbiAoI1BDREFUQSk+Cis8IUVMRU1FTlQgc2FsYXJ5ICgjUENEQVRBKT4KKzwhRUxFTUVOVCBhZGRyZXNzICgjUENEQVRBKT4KKzwhRUxFTUVOVCBlbnRFbGVtZW50ICggI1BDREFUQSApID4KKzwhRUxFTUVOVCBnZW5kZXIgKCAjUENEQVRBIHwgZW50RWxlbWVudCApKiA+Cis8IUVMRU1FTlQgZW1wbG95ZWUgKGVtcGxveWVlSWQsIG5hbWUsIHBvc2l0aW9uLCBzYWxhcnksIGdlbmRlciwgYWRkcmVzcykgPgorPCFFTEVNRU5UIHN0YWZmIChlbXBsb3llZSkrPgorPCFBVFRMSVNUIGVudEVsZW1lbnQgCisgICAgICAgICAgYXR0cjEgQ0RBVEEgIkF0dHIiPgorPCFBVFRMSVNUIGFkZHJlc3MKKyAgICAgICAgICBkb21lc3RpYyBDREFUQSAjSU1QTElFRCAKKyAgICAgICAgICBzdHJlZXQgQ0RBVEEgIlllcyI+Cis8IUFUVExJU1QgZW50RWxlbWVudCAKKyAgICAgICAgICBkb21lc3RpYyBDREFUQSAiTUFMRSIgPgorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9pby90ZXN0RmllbGRzLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL2FwaS9qYXZhL2lvL3Rlc3RGaWVsZHMuc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ4OGRkNWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9pby90ZXN0RmllbGRzLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9pby90ZXN0RmllbGRzRGVmYXVsdGVkLnNlciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL2FwaS9qYXZhL2lvL3Rlc3RGaWVsZHNEZWZhdWx0ZWQuc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAxMTI1YzcKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9pby90ZXN0RmllbGRzRGVmYXVsdGVkLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9pby90ZXN0RmllbGRzRGVwcmVjYXRlZC5zZXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9pby90ZXN0RmllbGRzRGVwcmVjYXRlZC5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjIxNDUyNAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL2FwaS9qYXZhL2lvL3Rlc3RGaWVsZHNEZXByZWNhdGVkLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9pby90ZXN0ZmlsZSBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL2FwaS9qYXZhL2lvL3Rlc3RmaWxlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJjNmM3MDgKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9pby90ZXN0ZmlsZQpAQCAtMCwwICsxIEBACitUaGlzIGlzIGEgdGVzdCBtZXNzYWdlIHdpdGggVW5pY29kZSBjaGFyYWN0ZXIuIFx1NGUyZFx1NTZmZCBpcyBDaGluYSdzIG5hbWUgaW4gQ2hpbmVzZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvYXBpL2phdmEvaW8vdGVzdGZpbGUtdXRmOC50eHQgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9pby90ZXN0ZmlsZS11dGY4LnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYzM1MzU0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvYXBpL2phdmEvaW8vdGVzdGZpbGUtdXRmOC50eHQKQEAgLTAsMCArMSBAQAor77u/VGhpcyBpcyBhIHRlc3QgbWVzc2FnZSB3aXRoIFVuaWNvZGUgY2hhcmFjdGVyLiDkuK3lm70gaXMgQ2hpbmEncyBuYW1lIGluIENoaW5lc2UKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9pby90ZXN0ZmlsZS50eHQgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9pby90ZXN0ZmlsZS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWFjYTY1NAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL2FwaS9qYXZhL2lvL3Rlc3RmaWxlLnR4dApAQCAtMCwwICsxIEBACitUaGlzIGlzIGEgdGVzdCBtZXNzYWdlIHdpdGggVW5pY29kZSBjaGFyYWN0ZXIuINbQufogaXMgQ2hpbmEncyBuYW1lIGluIENoaW5lc2UKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvZGV4MS5ieXRlcyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL2FwaS9qYXZhL2xhbmcvcmVmbGVjdC9kZXgxLmJ5dGVzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmZmY5NDkKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9sYW5nL3JlZmxlY3QvZGV4MS5ieXRlcwpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9uZXQvSW52YWxpZEphci5qYXIgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9uZXQvSW52YWxpZEphci5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzUzYjBmYwotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL2FwaS9qYXZhL25ldC9JbnZhbGlkSmFyLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9uZXQvVGVzdENvZGVTaWduZXJzLmphciBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL2FwaS9qYXZhL25ldC9UZXN0Q29kZVNpZ25lcnMuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE0YzQyYWEKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9uZXQvVGVzdENvZGVTaWduZXJzLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9uZXQvbGYuamFyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvYXBpL2phdmEvbmV0L2xmLmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hY2E4ZjM3Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvYXBpL2phdmEvbmV0L2xmLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS91dGlsL3N1cHBvcnQvQi5wcm9wZXJ0aWVzIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvYXBpL2phdmEvdXRpbC9zdXBwb3J0L0IucHJvcGVydGllcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMzFmM2Q0Ci0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvYXBpL2phdmEvdXRpbC9zdXBwb3J0L0IucHJvcGVydGllcwpAQCAtMCwwICsxIEBACituYW1lPU5hbWUKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9yZXNvdXJjZXMvaHl0c19iYWRwZW0uY2VyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvcmVzb3VyY2VzL2h5dHNfYmFkcGVtLmNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYzY2M2RlCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvcmVzb3VyY2VzL2h5dHNfYmFkcGVtLmNlcgpAQCAtMCwwICsxLDMxIEBACistLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0NCitNSUlGQVRDQ0ErbWded0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUVFGQURCL01Rc3dDUVlEVlFRR0V3SmtaVEVnDQorTUI0R0ExVUVDaE1YU1c1elpXTjFjbVZVWlhOMFEyVnlkR2xtYVdOaGRHVXhKekFsQmdOVkJBTVRIa1p2Y2lCVQ0KK1pYTjBjeUJQYm14NUlHNWxlSFFnWjJWdVpYSmhkR2x2YmpFbE1DTUdDU3FHU0liM0RRRUpBUllXYVc1elpXTjENCitjbVZBZEdWemRDNXBibk5sWTNWeVpUQWVGdzB3TWpBMk1qY3hNakUyTXpKYUZ3MHhNakEyTWpReE1qRTJNekphDQorTUg4eEN6QUpCZ05WQkFZVEFtUmxNU0F3SGdZRFZRUUtFeGRKYm5ObFkzVnlaVlJsYzNSRFpYSjBhV1pwWTJGMA0KK1pURW5NQ1VHQTFVRUF4TWVSbTl5SUZSbGMzUnpJRTl1YkhrZ2JtVjRkQ0JuWlc1bGNtRjBhVzl1TVNVd0l3WUoNCitLb1pJaHZjTkFRa0JGaFpwYm5ObFkzVnlaVUIwWlhOMExtbHVjMlZqZFhKbE1JSUJJakFOQmdrcWhraUc5dzBCDQorQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBcFUvWmpGVTY5YjFrT2E3UjE0Z1VBK2ZLNFcyZmlHNVJsN2wxWTlPYQ0KK3lrRFJRWE9YemIySnRxcnUwUjh3ZFlIcEtERGZKTW5mME5rTmJzTVQ5L0VQenR1RVhoeGdSTS9WMStHeGxacVINCit3M0I3dkRnNDF3akJ1cTgvOXhPZmQ4V3FkZVhJRDUvSlNvL3owUTJ2MGlmQmdDUDYwRGJDRnRQbmVJZEVsR1NZDQordENwTmQycUcwNkNOSno1Z3ZhSERJcFFiamdRMktpR1NKU3RIK2NZbHdmMjRKZFpnc2xYcW82SlZnMy83U01IcQ0KK21ZMkEvTUlGWlJ2VUV3YXRhWnh0bU9rYmEyQWh3RmVzS3ExVjREZUl2SDdWRDI5VWIwZEI0TzlyN0xIVGp4ekcNCitqNG5ScmtOaTZMNFI0SE44cTRDdHhiSk5hb012RkF1TUtUSWRpQkRqRUI1RzdRSURBUUFCbzRJQmhqQ0NBWUl3DQorRHdZRFZSMFRBUUgvQkFVd0F3RUIvekFMQmdOVkhROEVCQU1DQWVZd0hRWURWUjBPQkJZRUZJOElUNXhUd1Z6SQ0KKzVnelhFeTdMVWp3amxnSVVNSUdyQmdOVkhTTUVnYU13Z2FDQUZJOElUNXhUd1Z6STVnelhFeTdMVWp3amxnSVUNCitvWUdFcElHQk1IOHhDekFKQmdOVkJBWVRBbVJsTVNBd0hnWURWUVFLRXhkSmJuTmxZM1Z5WlZSbGMzUkRaWEowDQorYVdacFkyRjBaVEVuTUNVR0ExVUVBeE1lUm05eUlGUmxjM1J6SUU5dWJIa2dibVY0ZENCblpXNWxjbUYwYVc5dQ0KK01TVXdJd1lKS29aSWh2Y05BUWtCRmhacGJuTmxZM1Z5WlVCMFpYTjBMbWx1YzJWamRYSmxnZ0VBTUNFR0ExVWQNCitFUVFhTUJpQkZtbHVjMlZqZFhKbFFIUmxjM1F1YVc1elpXTjFjbVV3SVFZRFZSMFNCQm93R0lFV2FXNXpaV04xDQorY21WQWRHVnpkQzVwYm5ObFkzVnlaVEFSQmdsZ2hrZ0JodmhDQVFFRUJBTUNBQWN3UEFZSllJWklBWWI0UWdFTg0KK0JDOFdMVlJvYVhNZ1kyVnlkR2xtYVdOaGRHVWdkMkZ6SUdsemMzVmxaQ0JtYjNJZ2RHVnpkR2x1WnlCdmJteDUNCitJVEFOQmdrcWhraUc5dzBCQVFRRkFBT0NBUUVBS0c0Q2pkUTYwcHNrY1ZWUzliYXRQa09yM0hSKzIwamd4dGFXDQorQ3VsK1FtZXBKQ1pUajJYam1zcExsdzAwWlZjanhUdXhzQlZLUW9TUEEwVjd4ck5VNkdWWVF0Zm5ZV29RMUx3Kw0KK2MyK0o2WFo1aVY1OHV5ejRJSlZnZHEra3lYam9wTWlKVi9jSHFEWDVmUGVMVDM1TDNVTlp5OFRkaEhXK3RqN1gNCitzWmVsYks2a2lnOW16T0JWMmcwUGE4NkR3Y3RIeEwvZVJEcVgwK01rdnk5WUFzQlZoSERoVlJXQnBWTW1RRk1kDQorTmJFaUdSQjBGRUtUTSt6dGxiMFF5QnJocmpISTlhK1AyUTVpYXA3SHVpVXJEN0JSUThZV0VPVVdJOGpFZFJhSQ0KK2tDL0swVStXVEI2ZTMyWGlkalI3R0NxRlVMTENFNDVvZjVKV0ovZVY5Z0w1em5oYkVnPT0NCistLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tDQorDQorDQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvcmVzb3VyY2VzL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aC5Qa2lQYXRoIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvcmVzb3VyY2VzL2phdmEvc2VjdXJpdHkvY2VydC9DZXJ0UGF0aC5Qa2lQYXRoCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdkNDE1YzAKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9yZXNvdXJjZXMvamF2YS9zZWN1cml0eS9jZXJ0L0NlcnRQYXRoLlBraVBhdGgKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvcmVzb3VyY2VzL3Rlc3RkZXguamFyIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvcmVzb3VyY2VzL3Rlc3RkZXguamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU4YTkwZDQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9yZXNvdXJjZXMvdGVzdGRleC5qYXIKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9NRDUuY2hlY2sgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L01ENS5jaGVjawpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMzZiNTEwCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9NRDUuY2hlY2sKQEAgLTAsMCArMSBAQAor9Akzvdjy7fsInsDj72XqngpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvTUQ1LmRhdGEgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L01ENS5kYXRhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5YmUxMWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L01ENS5kYXRhCkBAIC0wLDAgKzEgQEAKK2hhbGxvIHdlbHQhClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9TSEEtMS5jaGVjayBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvU0hBLTEuY2hlY2sKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWNjMjBhZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvU0hBLTEuY2hlY2sKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9TSEEtMS5kYXRhIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9TSEEtMS5kYXRhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5YmUxMWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L1NIQS0xLmRhdGEKQEAgLTAsMCArMSBAQAoraGFsbG8gd2VsdCEKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L1NIQS0yMjQuY2hlY2sgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L1NIQS0yMjQuY2hlY2sKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTdhYWYxNQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvU0hBLTIyNC5jaGVjawpAQCAtMCwwICsxIEBACivk7Lg6ngfLvT7gfD2m2vvFvL68MF2V4kdRogjtClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9TSEEtMjI0LmRhdGEgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L1NIQS0yMjQuZGF0YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOWJlMTFkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9TSEEtMjI0LmRhdGEKQEAgLTAsMCArMSBAQAoraGFsbG8gd2VsdCEKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L1NIQS0yNTYuY2hlY2sgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L1NIQS0yNTYuY2hlY2sKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2MzZTFmYQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvU0hBLTI1Ni5jaGVjawpAQCAtMCwwICsxIEBACiuoeMVWNIuBkYQUJ35y3hEhO2KvJqzVXV523n7TC8Q2cgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvU0hBLTI1Ni5kYXRhIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9TSEEtMjU2LmRhdGEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzliZTExZAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvU0hBLTI1Ni5kYXRhCkBAIC0wLDAgKzEgQEAKK2hhbGxvIHdlbHQhClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9TSEEtMzg0LmNoZWNrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9TSEEtMzg0LmNoZWNrCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhiZjYyMmUKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L1NIQS0zODQuY2hlY2sKQEAgLTAsMCArMSwyIEBACitmNKFtda5liNiBnRRNtpL2ZcitEUMX7C5lkhUTxQLrPhGACEs9gworiF+GdFaC0fALClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9TSEEtMzg0LmRhdGEgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L1NIQS0zODQuZGF0YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOWJlMTFkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvdGVzdHMvdGFyZ2V0cy9zZWN1cml0eS9TSEEtMzg0LmRhdGEKQEAgLTAsMCArMSBAQAoraGFsbG8gd2VsdCEKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L1NIQS01MTIuY2hlY2sgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L1NIQS01MTIuY2hlY2sKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTQ3OTJmZQotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvU0hBLTUxMi5jaGVjawpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L1NIQS01MTIuZGF0YSBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3RzL3RhcmdldHMvc2VjdXJpdHkvU0hBLTUxMi5kYXRhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5YmUxMWQKLS0tIC9kZXYvbnVsbAorKysgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy90YXJnZXRzL3NlY3VyaXR5L1NIQS01MTIuZGF0YQpAQCAtMCwwICsxIEBACitoYWxsbyB3ZWx0IQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3dmL3N0YWZmLmR0ZCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3dmL3N0YWZmLmR0ZApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMmE5OTRkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvd2Yvc3RhZmYuZHRkCkBAIC0wLDAgKzEsMTcgQEAKKzwhRUxFTUVOVCBlbXBsb3llZUlkICgjUENEQVRBKT4KKzwhRUxFTUVOVCBuYW1lICgjUENEQVRBKT4KKzwhRUxFTUVOVCBwb3NpdGlvbiAoI1BDREFUQSk+Cis8IUVMRU1FTlQgc2FsYXJ5ICgjUENEQVRBKT4KKzwhRUxFTUVOVCBhZGRyZXNzICgjUENEQVRBKT4KKzwhRUxFTUVOVCBlbnRFbGVtZW50ICggI1BDREFUQSApID4KKzwhRUxFTUVOVCBnZW5kZXIgKCAjUENEQVRBIHwgZW50RWxlbWVudCApKiA+Cis8IUVMRU1FTlQgZW1wbG95ZWUgKGVtcGxveWVlSWQsIG5hbWUsIHBvc2l0aW9uLCBzYWxhcnksIGdlbmRlciwgYWRkcmVzcykgPgorPCFFTEVNRU5UIHN0YWZmIChlbXBsb3llZSkrPgorPCFBVFRMSVNUIGVudEVsZW1lbnQgCisgICAgICAgICAgYXR0cjEgQ0RBVEEgIkF0dHIiPgorPCFBVFRMSVNUIGFkZHJlc3MKKyAgICAgICAgICBkb21lc3RpYyBDREFUQSAjSU1QTElFRCAKKyAgICAgICAgICBzdHJlZXQgQ0RBVEEgIlllcyI+Cis8IUFUVExJU1QgZW50RWxlbWVudCAKKyAgICAgICAgICBkb21lc3RpYyBDREFUQSAiTUFMRSIgPgorCmRpZmYgLS1naXQgYS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy93Zi9zdGFmZi54bWwgYi9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy93Zi9zdGFmZi54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjg5YzUxMAotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3dmL3N0YWZmLnhtbApAQCAtMCwwICsxLDU3IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiPz48P1RFU1QtU1RZTEUgUElEQVRBPz4KKzwhRE9DVFlQRSBzdGFmZiBTWVNURU0gInN0YWZmLmR0ZCIgWworICAgPCFFTlRJVFkgZW50MSAiZXMiPgorICAgPCFFTlRJVFkgZW50MiAiMTkwMCBEYWxsYXMgUm9hZCI+CisgICA8IUVOVElUWSBlbnQzICJUZXhhcyI+CisgICA8IUVOVElUWSBlbnQ0ICI8ZW50RWxlbWVudCBkb21lc3RpYz0nWWVzJz5FbGVtZW50IGRhdGE8L2VudEVsZW1lbnQ+PD9QSXRhcmdldCBQSWRhdGE/PiI+CisgICA8IUVOVElUWSBlbnQ1IFBVQkxJQyAiZW50aXR5VVJJIiAiZW50aXR5RmlsZSIgTkRBVEEgbm90YXRpb24xPgorICAgPCFFTlRJVFkgZW50MSAiVGhpcyBlbnRpdHkgc2hvdWxkIGJlIGRpc2NhcmRlZCI+CisgICA8IU5PVEFUSU9OIG5vdGF0aW9uMSBQVUJMSUMgIm5vdGF0aW9uMUZpbGUiPgorICAgPCFOT1RBVElPTiBub3RhdGlvbjIgU1lTVEVNICJub3RhdGlvbjJGaWxlIj4KK10+Cis8IS0tIFRoaXMgaXMgY29tbWVudCBudW1iZXIgMS4tLT4KKzxzdGFmZj4KKyA8ZW1wbG95ZWU+CisgIDxlbXBsb3llZUlkPkVNUDAwMDE8L2VtcGxveWVlSWQ+CisgIDxuYW1lPk1hcmdhcmV0IE1hcnRpbjwvbmFtZT4KKyAgPHBvc2l0aW9uPkFjY291bnRhbnQ8L3Bvc2l0aW9uPiAgICAgICAgICAgCisgIDxzYWxhcnk+NTYsMDAwPC9zYWxhcnk+CisgIDxnZW5kZXI+RmVtYWxlPC9nZW5kZXI+CisgIDxhZGRyZXNzIGRvbWVzdGljPSJZZXMiPjEyMzAgTm9ydGggQXZlLiBEYWxsYXMsIFRleGFzIDk4NTUxPC9hZGRyZXNzPgorIDwvZW1wbG95ZWU+CisgPGVtcGxveWVlPgorICA8ZW1wbG95ZWVJZD5FTVAwMDAyPC9lbXBsb3llZUlkPgorICA8bmFtZT5NYXJ0aGEgUmF5bm9sZHM8IVtDREFUQVtUaGlzIGlzIGEgQ0RBVEFTZWN0aW9uIHdpdGggRW50aXR5UmVmZXJlbmNlIG51bWJlciAyICZlbnQyO11dPgorPCFbQ0RBVEFbVGhpcyBpcyBhbiBhZGphY2VudCBDREFUQVNlY3Rpb24gd2l0aCBhIHJlZmVyZW5jZSB0byBhIHRhYiAmdGFiO11dPjwvbmFtZT4KKyAgPHBvc2l0aW9uPlNlY3JldGFyeTwvcG9zaXRpb24+CisgIDxzYWxhcnk+MzUsMDAwPC9zYWxhcnk+CisgIDxnZW5kZXI+RmVtYWxlPC9nZW5kZXI+CisgIDxhZGRyZXNzIGRvbWVzdGljPSJZZXMiIHN0cmVldD0iWWVzIj4mZW50MjsgRGFsbGFzLCAmZW50MzsKKyA5ODU1NDwvYWRkcmVzcz4KKyA8L2VtcGxveWVlPgorIDxlbXBsb3llZT4KKyAgPGVtcGxveWVlSWQ+RU1QMDAwMzwvZW1wbG95ZWVJZD4KKyAgPG5hbWU+Um9nZXIKKyBKb25lczwvbmFtZT4KKyAgPHBvc2l0aW9uPkRlcGFydG1lbnQgTWFuYWdlcjwvcG9zaXRpb24+CisgIDxzYWxhcnk+MTAwLDAwMDwvc2FsYXJ5PgorICA8Z2VuZGVyPiZlbnQ0OzwvZ2VuZGVyPgorICA8YWRkcmVzcyBkb21lc3RpYz0iWWVzIiBzdHJlZXQ9Ik5vIj5QTyBCb3ggMjcgSXJ2aW5nLCB0ZXhhcyA5ODU1MzwvYWRkcmVzcz4KKyA8L2VtcGxveWVlPgorIDxlbXBsb3llZT4KKyAgPGVtcGxveWVlSWQ+RU1QMDAwNDwvZW1wbG95ZWVJZD4KKyAgPG5hbWU+SmVueSBPY29ubm9yPC9uYW1lPgorICA8cG9zaXRpb24+UGVyc29ubmVsIERpcmVjdG9yPC9wb3NpdGlvbj4KKyAgPHNhbGFyeT45NSwwMDA8L3NhbGFyeT4KKyAgPGdlbmRlcj5GZW1hbGU8L2dlbmRlcj4KKyAgPGFkZHJlc3MgZG9tZXN0aWM9IlllcyIgc3RyZWV0PSJZJmVudDE7Ij4yNyBTb3V0aCBSb2FkLiBEYWxsYXMsIFRleGFzIDk4NTU2PC9hZGRyZXNzPgorIDwvZW1wbG95ZWU+CisgPGVtcGxveWVlPgorICA8ZW1wbG95ZWVJZD5FTVAwMDA1PC9lbXBsb3llZUlkPgorICA8bmFtZT5Sb2JlcnQgTXllcnM8L25hbWU+CisgIDxwb3NpdGlvbj5Db21wdXRlciBTcGVjaWFsaXN0PC9wb3NpdGlvbj4KKyAgPHNhbGFyeT45MCwwMDA8L3NhbGFyeT4KKyAgPGdlbmRlcj5tYWxlPC9nZW5kZXI+CisgIDxhZGRyZXNzIHN0cmVldD0iWWVzIj4xODIxIE5vcmRpYy4gUm9hZCwgSXJ2aW5nIFRleGFzIDk4NTU4PC9hZGRyZXNzPgorIDwvZW1wbG95ZWU+CisgPC9zdGFmZj4KZGlmZiAtLWdpdCBhL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3dyb25nLnhtbCBiL2x1bmkvc3JjL3Rlc3QvcmVzb3VyY2VzL3dyb25nLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZDRiNDFkCi0tLSAvZGV2L251bGwKKysrIGIvbHVuaS9zcmMvdGVzdC9yZXNvdXJjZXMvd3JvbmcueG1sCkBAIC0wLDAgKzEgQEAKKzx3cm9uZzE+d3Jvbmc8L3dyb25nMj4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9sdW5pL3VuaWNvZGUtbGljZW5zZS50eHQgYi9sdW5pL3VuaWNvZGUtbGljZW5zZS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGEzMzUwYgotLS0gL2Rldi9udWxsCisrKyBiL2x1bmkvdW5pY29kZS1saWNlbnNlLnR4dApAQCAtMCwwICsxLDQ4IEBACitVTklDT0RFLCBJTkMuIExJQ0VOU0UgQUdSRUVNRU5UIC0gREFUQSBGSUxFUyBBTkQgU09GVFdBUkUKKworICAgIFVuaWNvZGUgRGF0YSBGaWxlcyBpbmNsdWRlIGFsbCBkYXRhIGZpbGVzIHVuZGVyIHRoZSBkaXJlY3RvcmllcworaHR0cDovL3d3dy51bmljb2RlLm9yZy9QdWJsaWMvLCBodHRwOi8vd3d3LnVuaWNvZGUub3JnL3JlcG9ydHMvLCBhbmQKK2h0dHA6Ly93d3cudW5pY29kZS5vcmcvY2xkci9kYXRhLyAuIFVuaWNvZGUgU29mdHdhcmUgaW5jbHVkZXMgYW55IHNvdXJjZSBjb2RlCitwdWJsaXNoZWQgaW4gdGhlIFVuaWNvZGUgU3RhbmRhcmQgb3IgdW5kZXIgdGhlIGRpcmVjdG9yaWVzCitodHRwOi8vd3d3LnVuaWNvZGUub3JnL1B1YmxpYy8sIGh0dHA6Ly93d3cudW5pY29kZS5vcmcvcmVwb3J0cy8sIGFuZAoraHR0cDovL3d3dy51bmljb2RlLm9yZy9jbGRyL2RhdGEvLgorCisgICAgTk9USUNFIFRPIFVTRVI6IENhcmVmdWxseSByZWFkIHRoZSBmb2xsb3dpbmcgbGVnYWwgYWdyZWVtZW50LiBCWQorRE9XTkxPQURJTkcsIElOU1RBTExJTkcsIENPUFlJTkcgT1IgT1RIRVJXSVNFIFVTSU5HIFVOSUNPREUgSU5DLidTIERBVEEgRklMRVMKKygiREFUQSBGSUxFUyIpLCBBTkQvT1IgU09GVFdBUkUgKCJTT0ZUV0FSRSIpLCBZT1UgVU5FUVVJVk9DQUxMWSBBQ0NFUFQsIEFORAorQUdSRUUgVE8gQkUgQk9VTkQgQlksIEFMTCBPRiBUSEUgVEVSTVMgQU5EIENPTkRJVElPTlMgT0YgVEhJUyBBR1JFRU1FTlQuIElGIFlPVQorRE8gTk9UIEFHUkVFLCBETyBOT1QgRE9XTkxPQUQsIElOU1RBTEwsIENPUFksIERJU1RSSUJVVEUgT1IgVVNFIFRIRSBEQVRBIEZJTEVTCitPUiBTT0ZUV0FSRS4KKworICAgIENPUFlSSUdIVCBBTkQgUEVSTUlTU0lPTiBOT1RJQ0UKKworICAgIENvcHlyaWdodCDCqSAxOTkxLTIwMDYgVW5pY29kZSwgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBEaXN0cmlidXRlZCB1bmRlcgordGhlIFRlcm1zIG9mIFVzZSBpbiBodHRwOi8vd3d3LnVuaWNvZGUub3JnL2NvcHlyaWdodC5odG1sLgorCisgICAgUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQorb2YgdGhlIFVuaWNvZGUgZGF0YSBmaWxlcyBhbmQgYW55IGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiAodGhlICJEYXRhIEZpbGVzIikgb3IKK1VuaWNvZGUgc29mdHdhcmUgYW5kIGFueSBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gKHRoZSAiU29mdHdhcmUiKSB0byBkZWFsIGluCit0aGUgRGF0YSBGaWxlcyBvciBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZQorcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgYW5kL29yIHNlbGwgY29waWVzIG9mCit0aGUgRGF0YSBGaWxlcyBvciBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIERhdGEgRmlsZXMgb3IKK1NvZnR3YXJlIGFyZSBmdXJuaXNoZWQgdG8gZG8gc28sIHByb3ZpZGVkIHRoYXQgKGEpIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlKHMpCithbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgd2l0aCBhbGwgY29waWVzIG9mIHRoZSBEYXRhIEZpbGVzIG9yIFNvZnR3YXJlLAorKGIpIGJvdGggdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UocykgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluCithc3NvY2lhdGVkIGRvY3VtZW50YXRpb24sIGFuZCAoYykgdGhlcmUgaXMgY2xlYXIgbm90aWNlIGluIGVhY2ggbW9kaWZpZWQgRGF0YQorRmlsZSBvciBpbiB0aGUgU29mdHdhcmUgYXMgd2VsbCBhcyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhlIERhdGEKK0ZpbGUocykgb3IgU29mdHdhcmUgdGhhdCB0aGUgZGF0YSBvciBzb2Z0d2FyZSBoYXMgYmVlbiBtb2RpZmllZC4KKworICAgIFRIRSBEQVRBIEZJTEVTIEFORCBTT0ZUV0FSRSBBUkUgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkKK0tJTkQsIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRgorTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5UIE9GIFRISVJECitQQVJUWSBSSUdIVFMuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIEhPTERFUlMgSU5DTFVERUQgSU4gVEhJUworTk9USUNFIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBPUiBBTlkgU1BFQ0lBTCBJTkRJUkVDVCBPUiBDT05TRVFVRU5USUFMCitEQU1BR0VTLCBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsCitXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcKK09VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSEUgREFUQSBGSUxFUyBPUgorU09GVFdBUkUuCisKKyAgICBFeGNlcHQgYXMgY29udGFpbmVkIGluIHRoaXMgbm90aWNlLCB0aGUgbmFtZSBvZiBhIGNvcHlyaWdodCBob2xkZXIgc2hhbGwgbm90CitiZSB1c2VkIGluIGFkdmVydGlzaW5nIG9yIG90aGVyd2lzZSB0byBwcm9tb3RlIHRoZSBzYWxlLCB1c2Ugb3Igb3RoZXIgZGVhbGluZ3MKK2luIHRoZXNlIERhdGEgRmlsZXMgb3IgU29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIGF1dGhvcml6YXRpb24gb2YgdGhlCitjb3B5cmlnaHQgaG9sZGVyLgpkaWZmIC0tZ2l0IGEvcnVuLWxpYmNvcmUtdGVzdHMgYi9ydW4tbGliY29yZS10ZXN0cwpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi43OWM0ZDA3Ci0tLSAvZGV2L251bGwKKysrIGIvcnVuLWxpYmNvcmUtdGVzdHMKQEAgLTAsMCArMSwyNyBAQAorIyEvYmluL2Jhc2gKKworIyBtYWtlIHN1cmUgdGhlcmUncyBhIHZvZ2FyIG9uIHRoZSBwYXRoLCBidXQgcHJlZmVyIHRoZSB1c2VyJ3Mgb25lLgorZXhwb3J0IFBBVEg9JFBBVEg6fmRhbHZpay1wcmVidWlsZC92b2dhci9iaW4KKworVk9HQVI9InZvZ2FyICRWT0dBUl9GTEFHUyIKKworIyBXZSBlbnVtZXJhdGUgdGhlIHRlc3QgcGFja2FnZXMgZm9yIHZvZ2FyIHJhdGhlciB0aGFuIGp1c3QgZ2l2aW5nIGl0IHRoZSBjbGFzc2VzLmphcgorIyBzbyBodW5kcmVkcyBvZiBwYWNrYWdlcyBjYW4gYmUgdGVzdGVkIGluIHBhcmFsbGVsLCByYXRoZXIgdGhhbiBvbmUgYmlnIGphciBmaWxlIHNlcmlhbGx5LgorYWxsX3Rlc3RfcGFja2FnZXM9JChmaW5kIGBkaXJuYW1lICQwYC8qL3NyYy90ZXN0IC1uYW1lICIqLmphdmEiIHwgXAorICBmZ3JlcCAtdiBqdW5pdCB8IFwKKyAgZmdyZXAgLXYgb3JnL3czYy9kb210cyB8IFwKKyAgeGFyZ3MgZ3JlcCAtaCAnXnBhY2thZ2UgJyB8IHNlZCAncy9ecGFja2FnZSAvLycgfCBzZWQgJ3MvOyQvLycgfCBzb3J0IHwgdW5pcSB8IHRyICJcbiIgIiAiKQorYWxsX3Rlc3RfcGFja2FnZXM9IiRhbGxfdGVzdF9wYWNrYWdlcyB0ZXN0cy5hcGkub3JnLnczYy5kb20iCisKKyMgVXNlIHRoZSBsaXN0IG9mIHBhY2thZ2VzIHN1cHBsaWVkIG9uIHRoZSBjb21tYW5kLWxpbmUsIGlmIGFueS4KK3Rlc3RfcGFja2FnZXM9JHsqOi0kYWxsX3Rlc3RfcGFja2FnZXN9CisKK2VjaG8gIlJ1bm5pbmcgdGVzdHMgZm9yIGZvbGxvd2luZyB0ZXN0IHBhY2thZ2VzOiIKK2VjaG8gJHRlc3RfcGFja2FnZXMgfCB0ciAiICIgIlxuIgorCiskVk9HQVIgXAorICAtLXZtLWFyZyAtWG14MzJNIFwKKyAgLS1jbGFzc3BhdGggb3V0L3RhcmdldC9jb21tb24vb2JqL0pBVkFfTElCUkFSSUVTL2NvcmUtdGVzdHNfaW50ZXJtZWRpYXRlcy9qYXZhbGliLmphciBcCisgIC0tY2xhc3NwYXRoIG91dC90YXJnZXQvY29tbW9uL29iai9KQVZBX0xJQlJBUklFUy9zcWxpdGUtamRiY19pbnRlcm1lZGlhdGVzL2NsYXNzZXMuamFyIFwKKyAgJHRlc3RfcGFja2FnZXMgXAorICB8fCB0cnVlCmRpZmYgLS1naXQgYS9zdXBwb3J0L01PRFVMRV9MSUNFTlNFX0FQQUNIRTIgYi9zdXBwb3J0L01PRFVMRV9MSUNFTlNFX0FQQUNIRTIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTY5ZGUyOQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvTU9EVUxFX0xJQ0VOU0VfQVBBQ0hFMgpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvZGFsdmlrL3N5c3RlbS9DbG9zZUd1YXJkVGVzdGVyLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvbGliY29yZS9kYWx2aWsvc3lzdGVtL0Nsb3NlR3VhcmRUZXN0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZWQ1OWEyCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvZGFsdmlrL3N5c3RlbS9DbG9zZUd1YXJkVGVzdGVyLmphdmEKQEAgLTAsMCArMSw2OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5kYWx2aWsuc3lzdGVtOworCitpbXBvcnQgZGFsdmlrLnN5c3RlbS5DbG9zZUd1YXJkOworaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29weU9uV3JpdGVBcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuQ29uc29sZUhhbmRsZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuSGFuZGxlcjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5Mb2dSZWNvcmQ7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nZ2VyOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5Bc3NlcnQ7CisKK3B1YmxpYyBmaW5hbCBjbGFzcyBDbG9zZUd1YXJkVGVzdGVyIGltcGxlbWVudHMgQ2xvc2VhYmxlIHsKKworICAgIHByaXZhdGUgZmluYWwgTGlzdDxMb2dSZWNvcmQ+IGxvZ1JlY29yZHMgPSBuZXcgQ29weU9uV3JpdGVBcnJheUxpc3Q8TG9nUmVjb3JkPigpOworICAgIHByaXZhdGUgZmluYWwgTG9nZ2VyIGxvZ2dlciA9IExvZ2dlci5nZXRMb2dnZXIoQ2xvc2VHdWFyZC5jbGFzcy5nZXROYW1lKCkpOworCisgICAgcHJpdmF0ZSBmaW5hbCBIYW5kbGVyIGxvZ1dhdGNoZXIgPSBuZXcgSGFuZGxlcigpIHsKKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNsb3NlKCkge30KKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGZsdXNoKCkge30KKyAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIHB1Ymxpc2goTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICAgICAgbG9nUmVjb3Jkcy5hZGQocmVjb3JkKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBwdWJsaWMgQ2xvc2VHdWFyZFRlc3RlcigpIHsKKyAgICAgICAgLyoKKyAgICAgICAgICogQ29sbGVjdCBpbW1lZGlhdGVseSBiZWZvcmUgd2Ugc3RhcnQgbW9uaXRvcmluZyB0aGUgQ2xvc2VHdWFyZCBsb2dzLgorICAgICAgICAgKiBUaGlzIGxvd2VycyB0aGUgY2hhbmNlIHRoYXQgd2UnbGwgcmVwb3J0IGFuIHVucmVsYXRlZCBsZWFrLgorICAgICAgICAgKi8KKyAgICAgICAgU3lzdGVtLmdjKCk7CisgICAgICAgIFN5c3RlbS5ydW5GaW5hbGl6YXRpb24oKTsKKyAgICAgICAgbG9nZ2VyLmFkZEhhbmRsZXIobG9nV2F0Y2hlcik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYXNzZXJ0RXZlcnl0aGluZ1dhc0Nsb3NlZCgpIHsKKyAgICAgICAgU3lzdGVtLmdjKCk7CisgICAgICAgIFN5c3RlbS5ydW5GaW5hbGl6YXRpb24oKTsKKworICAgICAgICBpZiAoIWxvZ1JlY29yZHMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAvLyBwcmludCB0aGUgbG9nIHJlY29yZHMgd2l0aCB0aGUgb3V0cHV0IG9mIHRoaXMgdGVzdAorICAgICAgICAgICAgZm9yIChMb2dSZWNvcmQgbGVhayA6IGxvZ1JlY29yZHMpIHsKKyAgICAgICAgICAgICAgICBuZXcgQ29uc29sZUhhbmRsZXIoKS5wdWJsaXNoKGxlYWspOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQXNzZXJ0LmZhaWwoIkNsb3NlR3VhcmQgZGV0ZWN0ZWQgdW5jbG9zZWQgcmVzb3VyY2VzISIpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgTG9nZ2VyLmdldExvZ2dlcihDbG9zZUd1YXJkLmNsYXNzLmdldE5hbWUoKSkucmVtb3ZlSGFuZGxlcihsb2dXYXRjaGVyKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL2lvL051bGxQcmludFN0cmVhbS5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9OdWxsUHJpbnRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMWRjZTgwCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9pby9OdWxsUHJpbnRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDY1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmEuaW87CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlByaW50U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CisKKy8qKiAKKyAqIEEgUHJpbnRTdHJlYW0gdGhhdCB0aHJvd3MgYXdheSBpdHMgb3V0cHV0LgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTnVsbFByaW50U3RyZWFtIGV4dGVuZHMgUHJpbnRTdHJlYW0geworICAgIHB1YmxpYyBOdWxsUHJpbnRTdHJlYW0oKSB7CisgICAgICAgIC8vIHN1cGVyIGNsYXNzIGNvbXBsYWlucyBpZiBhcmd1bWVudCBpcyBudWxsCisgICAgICAgIHN1cGVyKChPdXRwdXRTdHJlYW0pIG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKSk7CisgICAgfQorICAgIHB1YmxpYyBib29sZWFuIGNoZWNrRXJyb3IoKSB7IHJldHVybiBmYWxzZTsgfQorICAgIHByb3RlY3RlZCB2b2lkIGNsZWFyRXJyb3IoKSB7fQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkge30KKyAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHt9CisgICAgcHVibGljIFByaW50U3RyZWFtIGZvcm1hdChTdHJpbmcgZm9ybWF0LCBPYmplY3QuLi4gYXJncykgeyByZXR1cm4gdGhpczsgfQorICAgIHB1YmxpYyBQcmludFN0cmVhbSBmb3JtYXQoTG9jYWxlIGwsIFN0cmluZyBmb3JtYXQsIE9iamVjdC4uLiBhcmdzKSB7IHJldHVybiB0aGlzOyB9CisgICAgcHVibGljIFByaW50U3RyZWFtIHByaW50ZihTdHJpbmcgZm9ybWF0LCBPYmplY3QuLi4gYXJncykgeyByZXR1cm4gdGhpczsgfQorICAgIHB1YmxpYyBQcmludFN0cmVhbSBwcmludGYoTG9jYWxlIGwsIFN0cmluZyBmb3JtYXQsIE9iamVjdC4uLiBhcmdzKSB7IHJldHVybiB0aGlzOyB9CisgICAgcHVibGljIHZvaWQgcHJpbnQoY2hhcltdIGNoYXJBcnJheSkge30KKyAgICBwdWJsaWMgdm9pZCBwcmludChjaGFyIGNoKSB7fQorICAgIHB1YmxpYyB2b2lkIHByaW50KGRvdWJsZSBkbnVtKSB7fQorICAgIHB1YmxpYyB2b2lkIHByaW50KGZsb2F0IGZudW0pIHt9CisgICAgcHVibGljIHZvaWQgcHJpbnQoaW50IGludW0pIHt9CisgICAgcHVibGljIHZvaWQgcHJpbnQobG9uZyBsbnVtKSB7fQorICAgIHB1YmxpYyB2b2lkIHByaW50KE9iamVjdCBvYmopIHt9CisgICAgcHVibGljIHZvaWQgcHJpbnQoU3RyaW5nIHN0cikge30KKyAgICBwdWJsaWMgdm9pZCBwcmludChib29sZWFuIGJvb2wpIHt9CisgICAgcHVibGljIHZvaWQgcHJpbnRsbigpIHt9CisgICAgcHVibGljIHZvaWQgcHJpbnRsbihjaGFyW10gY2hhckFycmF5KSB7fQorICAgIHB1YmxpYyB2b2lkIHByaW50bG4oY2hhciBjaCkge30KKyAgICBwdWJsaWMgdm9pZCBwcmludGxuKGRvdWJsZSBkbnVtKSB7fQorICAgIHB1YmxpYyB2b2lkIHByaW50bG4oZmxvYXQgZm51bSkge30KKyAgICBwdWJsaWMgdm9pZCBwcmludGxuKGludCBpbnVtKSB7fQorICAgIHB1YmxpYyB2b2lkIHByaW50bG4obG9uZyBsbnVtKSB7fQorICAgIHB1YmxpYyB2b2lkIHByaW50bG4oT2JqZWN0IG9iaikge30KKyAgICBwdWJsaWMgdm9pZCBwcmludGxuKFN0cmluZyBzdHIpIHt9CisgICAgcHVibGljIHZvaWQgcHJpbnRsbihib29sZWFuIGJvb2wpIHt9CisgICAgcHJvdGVjdGVkIHZvaWQgc2V0RXJyb3IoKSB7fQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHt9CisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IG9uZUJ5dGUpIHt9CisgICAgcHVibGljIFByaW50U3RyZWFtIGFwcGVuZChjaGFyIGMpIHsgcmV0dXJuIHRoaXM7IH0KKyAgICBwdWJsaWMgUHJpbnRTdHJlYW0gYXBwZW5kKENoYXJTZXF1ZW5jZSBjc3EpIHsgcmV0dXJuIHRoaXM7IH0KKyAgICBwdWJsaWMgUHJpbnRTdHJlYW0gYXBwZW5kKENoYXJTZXF1ZW5jZSBjc3EsIGludCBzdGFydCwgaW50IGVuZCkgeyByZXR1cm4gdGhpczsgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zZWN1cml0eS9TdGFuZGFyZE5hbWVzLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZhL3NlY3VyaXR5L1N0YW5kYXJkTmFtZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMmY4NTM5Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zZWN1cml0eS9TdGFuZGFyZE5hbWVzLmphdmEKQEAgLTAsMCArMSw4MzAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkRTQVByaXZhdGVLZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5EU0FQdWJsaWNLZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FQ1ByaXZhdGVLZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5FQ1B1YmxpY0tleVNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLktleVNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLlJTQVByaXZhdGVDcnRLZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5SU0FQdWJsaWNLZXlTcGVjOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YXguY3J5cHRvLnNwZWMuREhQcml2YXRlS2V5U3BlYzsKK2ltcG9ydCBqYXZheC5jcnlwdG8uc3BlYy5ESFB1YmxpY0tleVNwZWM7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydDsKKworLyoqCisgKiBUaGlzIGNsYXNzIGRlZmluZXMgZXhwZWN0ZWQgc3RyaW5nIG5hbWVzIGZvciBwcm90b2NvbHMsIGtleSB0eXBlcywKKyAqIGNsaWVudCBhbmQgc2VydmVyIGF1dGggdHlwZXMsIGNpcGhlciBzdWl0ZXMuCisgKgorICogSW5pdGlhbGx5IGJhc2VkIG9uICJBcHBlbmRpeCBBOiBTdGFuZGFyZCBOYW1lcyIgb2YKKyAqIDxhIGhyZWY9Imh0dHA6Ly9qYXZhLnN1bi5jb20vajJzZS8xLjUuMC9kb2NzL2d1aWRlL3NlY3VyaXR5L2pzc2UvSlNTRVJlZkd1aWRlLmh0bWwjQXBwQSI+CisgKiBKYXZhICZ0cmFkZTsgU2VjdXJlIFNvY2tldCBFeHRlbnNpb24gKEpTU0UpIFJlZmVyZW5jZSBHdWlkZQorICogZm9yIHRoZSBKYXZhICZ0cmFkZTsgMiBQbGF0Zm9ybSBTdGFuZGFyZCBFZGl0aW9uIDUKKyAqIDwvYT4uCisgKgorICogVXBkYXRlZCBiYXNlZCBvbiB0aGUKKyAqIDxhIGhyZWY9Imh0dHA6Ly9kb3dubG9hZC5vcmFjbGUuY29tL2phdmFzZS83L2RvY3MvdGVjaG5vdGVzL2d1aWRlcy9zZWN1cml0eS9TdW5Qcm92aWRlcnMuaHRtbCI+CisgKiBKYXZhICZ0cmFkZTsgQ3J5cHRvZ3JhcGh5IEFyY2hpdGVjdHVyZSBPcmFjbGUgUHJvdmlkZXJzIERvY3VtZW50YXRpb24KKyAqIGZvciBKYXZhICZ0cmFkZTsgUGxhdGZvcm0gU3RhbmRhcmQgRWRpdGlvbiA3CisgKiA8L2E+LgorICogU2VlIGFsc28gdGhlCisgKiA8YSBocmVmPSJodHRwOi8vZG93bmxvYWQub3JhY2xlLmNvbS9qYXZhc2UvNy9kb2NzL3RlY2hub3Rlcy9ndWlkZXMvc2VjdXJpdHkvU3RhbmRhcmROYW1lcy5odG1sIj4KKyAqIEphdmEgJnRyYWRlOyBDcnlwdG9ncmFwaHkgQXJjaGl0ZWN0dXJlIFN0YW5kYXJkIEFsZ29yaXRobSBOYW1lIERvY3VtZW50YXRpb24KKyAqIDwvYT4uCisgKgorICogRnVydGhlciB1cGRhdGVzIGJhc2VkIG9uIHRoZQorICogPGEgaHJlZj1odHRwOi8vamF2YS5zdW4uY29tL2phdmFzZS82L2RvY3MvdGVjaG5vdGVzL2d1aWRlcy9zZWN1cml0eS9wMTFndWlkZS5odG1sIj4KKyAqIEphdmEgJnRyYWRlOyBQS0NTIzExIFJlZmVyZW5jZSBHdWlkZQorICogPC9hPi4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFN0YW5kYXJkTmFtZXMgZXh0ZW5kcyBBc3NlcnQgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBib29sZWFuIElTX1JJCisgICAgICAgICAgICA9ICEiRGFsdmlrIENvcmUgTGlicmFyeSIuZXF1YWxzKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5zcGVjaWZpY2F0aW9uLm5hbWUiKSk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSlNTRV9QUk9WSURFUl9OQU1FID0gKElTX1JJKSA/ICJTdW5KU1NFIiA6ICJBbmRyb2lkT3BlblNTTCI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VDVVJJVFlfUFJPVklERVJfTkFNRSA9IChJU19SSSkgPyAiU1VOIiA6ICJCQyI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBLRVlfTUFOQUdFUl9GQUNUT1JZX0RFRkFVTFQgPSAoSVNfUkkpID8gIlN1blg1MDkiIDogIlg1MDkiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRSVVNUX01BTkFHRVJfRkFDVE9SWV9ERUZBVUxUID0gKElTX1JJKSA/ICJQS0lYIiA6ICJYNTA5IjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEtFWV9TVE9SRV9BTEdPUklUSE0gPSAoSVNfUkkpID8gIkpLUyIgOiAiQktTIjsKKworICAgIC8qKgorICAgICAqIFJGQyA1NzQ2J3MgU2lnbmFsaW5nIENpcGhlciBTdWl0ZSBWYWx1ZSB0byBpbmRpY2F0ZSBhIHJlcXVlc3QgZm9yIHNlY3VyZSByZW5lZ290aWF0aW9uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0lQSEVSX1NVSVRFX1NFQ1VSRV9SRU5FR09USUFUSU9OCisgICAgICAgICAgICA9ICJUTFNfRU1QVFlfUkVORUdPVElBVElPTl9JTkZPX1NDU1YiOworCisgICAgLyoqCisgICAgICogQSBtYXAgZnJvbSBhbGdvcml0aG0gdHlwZSAoZS5nLiBDaXBoZXIpIHRvIGEgc2V0IG9mIGFsZ29yaXRobXMgKGUuZy4gQUVTLCBERVMsIC4uLikKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsU2V0PFN0cmluZz4+IFBST1ZJREVSX0FMR09SSVRITVMKKyAgICAgICAgICAgID0gbmV3IEhhc2hNYXA8U3RyaW5nLFNldDxTdHJpbmc+PigpOworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcHJvdmlkZShTdHJpbmcgdHlwZSwgU3RyaW5nIGFsZ29yaXRobSkgeworICAgICAgICBTZXQ8U3RyaW5nPiBhbGdvcml0aG1zID0gUFJPVklERVJfQUxHT1JJVEhNUy5nZXQodHlwZSk7CisgICAgICAgIGlmIChhbGdvcml0aG1zID09IG51bGwpIHsKKyAgICAgICAgICAgIGFsZ29yaXRobXMgPSBuZXcgSGFzaFNldCgpOworICAgICAgICAgICAgUFJPVklERVJfQUxHT1JJVEhNUy5wdXQodHlwZSwgYWxnb3JpdGhtcyk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiRHVwbGljYXRlICIgKyB0eXBlICsgIiAiICsgYWxnb3JpdGhtLAorICAgICAgICAgICAgICAgICAgIGFsZ29yaXRobXMuYWRkKGFsZ29yaXRobS50b1VwcGVyQ2FzZSgpKSk7CisgICAgfQorICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdW5wcm92aWRlKFN0cmluZyB0eXBlLCBTdHJpbmcgYWxnb3JpdGhtKSB7CisgICAgICAgIFNldDxTdHJpbmc+IGFsZ29yaXRobXMgPSBQUk9WSURFUl9BTEdPUklUSE1TLmdldCh0eXBlKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChhbGdvcml0aG1zKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShhbGdvcml0aG0sIGFsZ29yaXRobXMucmVtb3ZlKGFsZ29yaXRobS50b1VwcGVyQ2FzZSgpKSk7CisgICAgICAgIGlmIChhbGdvcml0aG1zLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChQUk9WSURFUl9BTEdPUklUSE1TLnJlbW92ZSh0eXBlKSk7CisgICAgICAgIH0KKyAgICB9CisgICAgc3RhdGljIHsKKyAgICAgICAgcHJvdmlkZSgiQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yIiwgIkRTQSIpOworICAgICAgICBwcm92aWRlKCJBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IiLCAiRGlmZmllSGVsbG1hbiIpOworICAgICAgICBwcm92aWRlKCJBbGdvcml0aG1QYXJhbWV0ZXJzIiwgIkFFUyIpOworICAgICAgICBwcm92aWRlKCJBbGdvcml0aG1QYXJhbWV0ZXJzIiwgIkJsb3dmaXNoIik7CisgICAgICAgIHByb3ZpZGUoIkFsZ29yaXRobVBhcmFtZXRlcnMiLCAiREVTIik7CisgICAgICAgIHByb3ZpZGUoIkFsZ29yaXRobVBhcmFtZXRlcnMiLCAiREVTZWRlIik7CisgICAgICAgIHByb3ZpZGUoIkFsZ29yaXRobVBhcmFtZXRlcnMiLCAiRFNBIik7CisgICAgICAgIHByb3ZpZGUoIkFsZ29yaXRobVBhcmFtZXRlcnMiLCAiRGlmZmllSGVsbG1hbiIpOworICAgICAgICBwcm92aWRlKCJBbGdvcml0aG1QYXJhbWV0ZXJzIiwgIk9BRVAiKTsKKyAgICAgICAgcHJvdmlkZSgiQWxnb3JpdGhtUGFyYW1ldGVycyIsICJQQkVXaXRoTUQ1QW5kREVTIik7CisgICAgICAgIHByb3ZpZGUoIkFsZ29yaXRobVBhcmFtZXRlcnMiLCAiUEJFV2l0aE1ENUFuZFRyaXBsZURFUyIpOworICAgICAgICBwcm92aWRlKCJBbGdvcml0aG1QYXJhbWV0ZXJzIiwgIlBCRVdpdGhTSEExQW5kREVTZWRlIik7CisgICAgICAgIHByb3ZpZGUoIkFsZ29yaXRobVBhcmFtZXRlcnMiLCAiUEJFV2l0aFNIQTFBbmRSQzJfNDAiKTsKKyAgICAgICAgcHJvdmlkZSgiQWxnb3JpdGhtUGFyYW1ldGVycyIsICJSQzIiKTsKKyAgICAgICAgcHJvdmlkZSgiQ2VydFBhdGhCdWlsZGVyIiwgIlBLSVgiKTsKKyAgICAgICAgcHJvdmlkZSgiQ2VydFBhdGhWYWxpZGF0b3IiLCAiUEtJWCIpOworICAgICAgICBwcm92aWRlKCJDZXJ0U3RvcmUiLCAiQ29sbGVjdGlvbiIpOworICAgICAgICBwcm92aWRlKCJDZXJ0U3RvcmUiLCAiTERBUCIpOworICAgICAgICBwcm92aWRlKCJDZXJ0aWZpY2F0ZUZhY3RvcnkiLCAiWC41MDkiKTsKKyAgICAgICAgcHJvdmlkZSgiQ2lwaGVyIiwgIkFFUyIpOworICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiQUVTV3JhcCIpOworICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiQVJDRk9VUiIpOworICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiQmxvd2Zpc2giKTsKKyAgICAgICAgcHJvdmlkZSgiQ2lwaGVyIiwgIkRFUyIpOworICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiREVTZWRlIik7CisgICAgICAgIHByb3ZpZGUoIkNpcGhlciIsICJERVNlZGVXcmFwIik7CisgICAgICAgIHByb3ZpZGUoIkNpcGhlciIsICJQQkVXaXRoTUQ1QW5kREVTIik7CisgICAgICAgIHByb3ZpZGUoIkNpcGhlciIsICJQQkVXaXRoTUQ1QW5kVHJpcGxlREVTIik7CisgICAgICAgIHByb3ZpZGUoIkNpcGhlciIsICJQQkVXaXRoU0hBMUFuZERFU2VkZSIpOworICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiUEJFV2l0aFNIQTFBbmRSQzJfNDAiKTsKKyAgICAgICAgcHJvdmlkZSgiQ2lwaGVyIiwgIlJDMiIpOworICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiUlNBIik7CisgICAgICAgIHByb3ZpZGUoIkNvbmZpZ3VyYXRpb24iLCAiSmF2YUxvZ2luQ29uZmlnIik7CisgICAgICAgIHByb3ZpZGUoIktleUFncmVlbWVudCIsICJEaWZmaWVIZWxsbWFuIik7CisgICAgICAgIHByb3ZpZGUoIktleUZhY3RvcnkiLCAiRFNBIik7CisgICAgICAgIHByb3ZpZGUoIktleUZhY3RvcnkiLCAiRGlmZmllSGVsbG1hbiIpOworICAgICAgICBwcm92aWRlKCJLZXlGYWN0b3J5IiwgIlJTQSIpOworICAgICAgICBwcm92aWRlKCJLZXlHZW5lcmF0b3IiLCAiQUVTIik7CisgICAgICAgIHByb3ZpZGUoIktleUdlbmVyYXRvciIsICJBUkNGT1VSIik7CisgICAgICAgIHByb3ZpZGUoIktleUdlbmVyYXRvciIsICJCbG93ZmlzaCIpOworICAgICAgICBwcm92aWRlKCJLZXlHZW5lcmF0b3IiLCAiREVTIik7CisgICAgICAgIHByb3ZpZGUoIktleUdlbmVyYXRvciIsICJERVNlZGUiKTsKKyAgICAgICAgcHJvdmlkZSgiS2V5R2VuZXJhdG9yIiwgIkhtYWNNRDUiKTsKKyAgICAgICAgcHJvdmlkZSgiS2V5R2VuZXJhdG9yIiwgIkhtYWNTSEExIik7CisgICAgICAgIHByb3ZpZGUoIktleUdlbmVyYXRvciIsICJIbWFjU0hBMjU2Iik7CisgICAgICAgIHByb3ZpZGUoIktleUdlbmVyYXRvciIsICJIbWFjU0hBMzg0Iik7CisgICAgICAgIHByb3ZpZGUoIktleUdlbmVyYXRvciIsICJIbWFjU0hBNTEyIik7CisgICAgICAgIHByb3ZpZGUoIktleUdlbmVyYXRvciIsICJSQzIiKTsKKyAgICAgICAgcHJvdmlkZSgiS2V5SW5mb0ZhY3RvcnkiLCAiRE9NIik7CisgICAgICAgIHByb3ZpZGUoIktleU1hbmFnZXJGYWN0b3J5IiwgIlN1blg1MDkiKTsKKyAgICAgICAgcHJvdmlkZSgiS2V5UGFpckdlbmVyYXRvciIsICJEU0EiKTsKKyAgICAgICAgcHJvdmlkZSgiS2V5UGFpckdlbmVyYXRvciIsICJEaWZmaWVIZWxsbWFuIik7CisgICAgICAgIHByb3ZpZGUoIktleVBhaXJHZW5lcmF0b3IiLCAiUlNBIik7CisgICAgICAgIHByb3ZpZGUoIktleVN0b3JlIiwgIkpDRUtTIik7CisgICAgICAgIHByb3ZpZGUoIktleVN0b3JlIiwgIkpLUyIpOworICAgICAgICBwcm92aWRlKCJLZXlTdG9yZSIsICJQS0NTMTIiKTsKKyAgICAgICAgcHJvdmlkZSgiTWFjIiwgIkhtYWNNRDUiKTsKKyAgICAgICAgcHJvdmlkZSgiTWFjIiwgIkhtYWNTSEExIik7CisgICAgICAgIHByb3ZpZGUoIk1hYyIsICJIbWFjU0hBMjU2Iik7CisgICAgICAgIHByb3ZpZGUoIk1hYyIsICJIbWFjU0hBMzg0Iik7CisgICAgICAgIHByb3ZpZGUoIk1hYyIsICJIbWFjU0hBNTEyIik7CisgICAgICAgIHByb3ZpZGUoIk1lc3NhZ2VEaWdlc3QiLCAiTUQyIik7CisgICAgICAgIHByb3ZpZGUoIk1lc3NhZ2VEaWdlc3QiLCAiTUQ1Iik7CisgICAgICAgIHByb3ZpZGUoIk1lc3NhZ2VEaWdlc3QiLCAiU0hBLTI1NiIpOworICAgICAgICBwcm92aWRlKCJNZXNzYWdlRGlnZXN0IiwgIlNIQS0zODQiKTsKKyAgICAgICAgcHJvdmlkZSgiTWVzc2FnZURpZ2VzdCIsICJTSEEtNTEyIik7CisgICAgICAgIHByb3ZpZGUoIlBvbGljeSIsICJKYXZhUG9saWN5Iik7CisgICAgICAgIHByb3ZpZGUoIlNTTENvbnRleHQiLCAiU1NMdjMiKTsKKyAgICAgICAgcHJvdmlkZSgiU1NMQ29udGV4dCIsICJUTFN2MSIpOworICAgICAgICBwcm92aWRlKCJTZWNyZXRLZXlGYWN0b3J5IiwgIkRFUyIpOworICAgICAgICBwcm92aWRlKCJTZWNyZXRLZXlGYWN0b3J5IiwgIkRFU2VkZSIpOworICAgICAgICBwcm92aWRlKCJTZWNyZXRLZXlGYWN0b3J5IiwgIlBCRVdpdGhNRDVBbmRERVMiKTsKKyAgICAgICAgcHJvdmlkZSgiU2VjcmV0S2V5RmFjdG9yeSIsICJQQkVXaXRoTUQ1QW5kVHJpcGxlREVTIik7CisgICAgICAgIHByb3ZpZGUoIlNlY3JldEtleUZhY3RvcnkiLCAiUEJFV2l0aFNIQTFBbmRERVNlZGUiKTsKKyAgICAgICAgcHJvdmlkZSgiU2VjcmV0S2V5RmFjdG9yeSIsICJQQkVXaXRoU0hBMUFuZFJDMl80MCIpOworICAgICAgICBwcm92aWRlKCJTZWNyZXRLZXlGYWN0b3J5IiwgIlBCS0RGMldpdGhIbWFjU0hBMSIpOworICAgICAgICBwcm92aWRlKCJTZWN1cmVSYW5kb20iLCAiU0hBMVBSTkciKTsKKyAgICAgICAgcHJvdmlkZSgiU2lnbmF0dXJlIiwgIk1EMndpdGhSU0EiKTsKKyAgICAgICAgcHJvdmlkZSgiU2lnbmF0dXJlIiwgIk1ENXdpdGhSU0EiKTsKKyAgICAgICAgcHJvdmlkZSgiU2lnbmF0dXJlIiwgIk5PTkV3aXRoRFNBIik7CisgICAgICAgIHByb3ZpZGUoIlNpZ25hdHVyZSIsICJTSEExd2l0aERTQSIpOworICAgICAgICBwcm92aWRlKCJTaWduYXR1cmUiLCAiU0hBMXdpdGhSU0EiKTsKKyAgICAgICAgcHJvdmlkZSgiU2lnbmF0dXJlIiwgIlNIQTI1NndpdGhSU0EiKTsKKyAgICAgICAgcHJvdmlkZSgiU2lnbmF0dXJlIiwgIlNIQTM4NHdpdGhSU0EiKTsKKyAgICAgICAgcHJvdmlkZSgiU2lnbmF0dXJlIiwgIlNIQTUxMndpdGhSU0EiKTsKKyAgICAgICAgcHJvdmlkZSgiVGVybWluYWxGYWN0b3J5IiwgIlBDL1NDIik7CisgICAgICAgIHByb3ZpZGUoIlRyYW5zZm9ybVNlcnZpY2UiLCAiaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2Jhc2U2NCIpOworICAgICAgICBwcm92aWRlKCJUcmFuc2Zvcm1TZXJ2aWNlIiwgImh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0dXJlIik7CisgICAgICAgIHByb3ZpZGUoIlRyYW5zZm9ybVNlcnZpY2UiLCAiaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIik7CisgICAgICAgIHByb3ZpZGUoIlRyYW5zZm9ybVNlcnZpY2UiLCAiaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jV2l0aENvbW1lbnRzIik7CisgICAgICAgIHByb3ZpZGUoIlRyYW5zZm9ybVNlcnZpY2UiLCAiaHR0cDovL3d3dy53My5vcmcvMjAwMi8wNi94bWxkc2lnLWZpbHRlcjIiKTsKKyAgICAgICAgcHJvdmlkZSgiVHJhbnNmb3JtU2VydmljZSIsICJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14cGF0aC0xOTk5MTExNiIpOworICAgICAgICBwcm92aWRlKCJUcmFuc2Zvcm1TZXJ2aWNlIiwgImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhzbHQtMTk5OTExMTYiKTsKKyAgICAgICAgcHJvdmlkZSgiVHJhbnNmb3JtU2VydmljZSIsICJodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy14bWwtYzE0bi0yMDAxMDMxNSIpOworICAgICAgICBwcm92aWRlKCJUcmFuc2Zvcm1TZXJ2aWNlIiwgImh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvUkVDLXhtbC1jMTRuLTIwMDEwMzE1I1dpdGhDb21tZW50cyIpOworICAgICAgICBwcm92aWRlKCJUcnVzdE1hbmFnZXJGYWN0b3J5IiwgIlBLSVgiKTsKKyAgICAgICAgcHJvdmlkZSgiWE1MU2lnbmF0dXJlRmFjdG9yeSIsICJET00iKTsKKworICAgICAgICAvLyBOb3QgY2xlYXJseSBkb2N1bWVudGVkIGJ5IFJJCisgICAgICAgIHByb3ZpZGUoIkdzc0FwaU1lY2hhbmlzbSIsICIxLjIuODQwLjExMzU1NC4xLjIuMiIpOworICAgICAgICBwcm92aWRlKCJHc3NBcGlNZWNoYW5pc20iLCAiMS4zLjYuMS41LjUuMiIpOworCisgICAgICAgIC8vIE5vdCBjb3JyZWN0bHkgZG9jdW1lbnRlZCBieSBSSSB3aGljaCBsZWZ0IG9mZiB0aGUgRmFjdG9yeSBzdWZmaXgKKyAgICAgICAgcHJvdmlkZSgiU2FzbENsaWVudEZhY3RvcnkiLCAiQ1JBTS1NRDUiKTsKKyAgICAgICAgcHJvdmlkZSgiU2FzbENsaWVudEZhY3RvcnkiLCAiRElHRVNULU1ENSIpOworICAgICAgICBwcm92aWRlKCJTYXNsQ2xpZW50RmFjdG9yeSIsICJFWFRFUk5BTCIpOworICAgICAgICBwcm92aWRlKCJTYXNsQ2xpZW50RmFjdG9yeSIsICJHU1NBUEkiKTsKKyAgICAgICAgcHJvdmlkZSgiU2FzbENsaWVudEZhY3RvcnkiLCAiUExBSU4iKTsKKyAgICAgICAgcHJvdmlkZSgiU2FzbFNlcnZlckZhY3RvcnkiLCAiQ1JBTS1NRDUiKTsKKyAgICAgICAgcHJvdmlkZSgiU2FzbFNlcnZlckZhY3RvcnkiLCAiRElHRVNULU1ENSIpOworICAgICAgICBwcm92aWRlKCJTYXNsU2VydmVyRmFjdG9yeSIsICJHU1NBUEkiKTsKKworICAgICAgICAvLyBEb2N1bWVudGF0aW9uIHNlZW1zIHRvIGxpc3QgYWxpYXMgaW5zdGVhZCBvZiBhY3R1YWwgbmFtZQorICAgICAgICAvLyBwcm92aWRlKCJNZXNzYWdlRGlnZXN0IiwgIlNIQS0xIik7CisgICAgICAgIHByb3ZpZGUoIk1lc3NhZ2VEaWdlc3QiLCAiU0hBIik7CisKKyAgICAgICAgLy8gTWVudGlvbmVkIGluIGphdmFkb2MsIG5vdCBkb2N1bWVudGF0aW9uCisgICAgICAgIHByb3ZpZGUoIlNTTENvbnRleHQiLCAiRGVmYXVsdCIpOworCisgICAgICAgIC8vIE5vdCBkb2N1bWVudGVkIGFzIGluIFJJIDYgYnV0IG1lbnRpb25lZCBpbiBTdGFuZGFyZCBOYW1lcworICAgICAgICBwcm92aWRlKCJBbGdvcml0aG1QYXJhbWV0ZXJzIiwgIlBCRSIpOworICAgICAgICBwcm92aWRlKCJTU0xDb250ZXh0IiwgIlNTTCIpOworICAgICAgICBwcm92aWRlKCJTU0xDb250ZXh0IiwgIlRMUyIpOworCisgICAgICAgIC8vIE5vdCBkb2N1bWVudGVkIGFzIGluIFJJIDYgYnV0IHRoYXQgZXhpc3QgaW4gUkkgNgorICAgICAgICBpZiAoSVNfUkkpIHsKKyAgICAgICAgICAgIHByb3ZpZGUoIkNlcnRTdG9yZSIsICJjb20uc3VuLnNlY3VyaXR5LkluZGV4ZWRDb2xsZWN0aW9uIik7CisgICAgICAgICAgICBwcm92aWRlKCJLZXlHZW5lcmF0b3IiLCAiU3VuVGxzS2V5TWF0ZXJpYWwiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIktleUdlbmVyYXRvciIsICJTdW5UbHNNYXN0ZXJTZWNyZXQiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIktleUdlbmVyYXRvciIsICJTdW5UbHNQcmYiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIktleUdlbmVyYXRvciIsICJTdW5UbHNSc2FQcmVtYXN0ZXJTZWNyZXQiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIktleU1hbmFnZXJGYWN0b3J5IiwgIk5ld1N1blg1MDkiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIktleVN0b3JlIiwgIkNhc2VFeGFjdEpLUyIpOworICAgICAgICAgICAgcHJvdmlkZSgiTWFjIiwgIkhtYWNQQkVTSEExIik7CisgICAgICAgICAgICBwcm92aWRlKCJNYWMiLCAiU3NsTWFjTUQ1Iik7CisgICAgICAgICAgICBwcm92aWRlKCJNYWMiLCAiU3NsTWFjU0hBMSIpOworICAgICAgICAgICAgcHJvdmlkZSgiU2VjdXJlUmFuZG9tIiwgIk5hdGl2ZVBSTkciKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNpZ25hdHVyZSIsICJNRDVhbmRTSEExd2l0aFJTQSIpOworICAgICAgICAgICAgcHJvdmlkZSgiVHJ1c3RNYW5hZ2VyRmFjdG9yeSIsICJTdW5YNTA5Iik7CisgICAgICAgIH0KKworICAgICAgICAvLyBPbmx5IGF2YWlsYWJsZSB3aXRoIHRoZSBTdW5QS0NTMTEtTlNTIHByb3ZpZGVyLAorICAgICAgICAvLyB3aGljaCBzZWVtcyB0byBiZSBlbmFibGVkIGluIE9wZW5KREsgNiBidXQgbm90IE9yYWNsZSBKYXZhIDYKKyAgICAgICAgaWYgKFNlY3VyaXR5LmdldFByb3ZpZGVyKCJTdW5QS0NTMTEtTlNTIikgIT0gbnVsbCkgeworICAgICAgICAgICAgcHJvdmlkZSgiQWxnb3JpdGhtUGFyYW1ldGVycyIsICJFQyIpOworICAgICAgICAgICAgcHJvdmlkZSgiQ2lwaGVyIiwgIkFFUy9DQkMvTk9QQURESU5HIik7CisgICAgICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiREVTL0NCQy9OT1BBRERJTkciKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIkNpcGhlciIsICJERVNFREUvQ0JDL05PUEFERElORyIpOworICAgICAgICAgICAgcHJvdmlkZSgiQ2lwaGVyIiwgIlJTQS9FQ0IvUEtDUzFQQURESU5HIik7CisgICAgICAgICAgICBwcm92aWRlKCJLZXlBZ3JlZW1lbnQiLCAiREgiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIktleUFncmVlbWVudCIsICJFQ0RIIik7CisgICAgICAgICAgICBwcm92aWRlKCJLZXlGYWN0b3J5IiwgIkRIIik7CisgICAgICAgICAgICBwcm92aWRlKCJLZXlGYWN0b3J5IiwgIkVDIik7CisgICAgICAgICAgICBwcm92aWRlKCJLZXlQYWlyR2VuZXJhdG9yIiwgIkRIIik7CisgICAgICAgICAgICBwcm92aWRlKCJLZXlQYWlyR2VuZXJhdG9yIiwgIkVDIik7CisgICAgICAgICAgICBwcm92aWRlKCJLZXlTdG9yZSIsICJQS0NTMTEiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIk1lc3NhZ2VEaWdlc3QiLCAiU0hBMSIpOworICAgICAgICAgICAgcHJvdmlkZSgiU2VjcmV0S2V5RmFjdG9yeSIsICJBRVMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNlY3JldEtleUZhY3RvcnkiLCAiQVJDRk9VUiIpOworICAgICAgICAgICAgcHJvdmlkZSgiU2VjdXJlUmFuZG9tIiwgIlBLQ1MxMSIpOworICAgICAgICAgICAgcHJvdmlkZSgiU2lnbmF0dXJlIiwgIkRTQSIpOworICAgICAgICAgICAgcHJvdmlkZSgiU2lnbmF0dXJlIiwgIk5PTkVXSVRIRUNEU0EiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNpZ25hdHVyZSIsICJSQVdEU0EiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNpZ25hdHVyZSIsICJTSEExV0lUSEVDRFNBIik7CisgICAgICAgICAgICBwcm92aWRlKCJTaWduYXR1cmUiLCAiU0hBMjU2V0lUSEVDRFNBIik7CisgICAgICAgICAgICBwcm92aWRlKCJTaWduYXR1cmUiLCAiU0hBMzg0V0lUSEVDRFNBIik7CisgICAgICAgICAgICBwcm92aWRlKCJTaWduYXR1cmUiLCAiU0hBNTEyV0lUSEVDRFNBIik7CisgICAgICAgIH0KKworICAgICAgICAvLyBGaXh1cHMgZm9yIGRhbHZpaworICAgICAgICBpZiAoIUlTX1JJKSB7CisKKyAgICAgICAgICAgIC8vIHdob2xlIHR5cGVzIHRoYXQgd2UgZG8gbm90IHByb3ZpZGUKKyAgICAgICAgICAgIFBST1ZJREVSX0FMR09SSVRITVMucmVtb3ZlKCJDb25maWd1cmF0aW9uIik7CisgICAgICAgICAgICBQUk9WSURFUl9BTEdPUklUSE1TLnJlbW92ZSgiR3NzQXBpTWVjaGFuaXNtIik7CisgICAgICAgICAgICBQUk9WSURFUl9BTEdPUklUSE1TLnJlbW92ZSgiS2V5SW5mb0ZhY3RvcnkiKTsKKyAgICAgICAgICAgIFBST1ZJREVSX0FMR09SSVRITVMucmVtb3ZlKCJQb2xpY3kiKTsKKyAgICAgICAgICAgIFBST1ZJREVSX0FMR09SSVRITVMucmVtb3ZlKCJTYXNsQ2xpZW50RmFjdG9yeSIpOworICAgICAgICAgICAgUFJPVklERVJfQUxHT1JJVEhNUy5yZW1vdmUoIlNhc2xTZXJ2ZXJGYWN0b3J5Iik7CisgICAgICAgICAgICBQUk9WSURFUl9BTEdPUklUSE1TLnJlbW92ZSgiVGVybWluYWxGYWN0b3J5Iik7CisgICAgICAgICAgICBQUk9WSURFUl9BTEdPUklUSE1TLnJlbW92ZSgiVHJhbnNmb3JtU2VydmljZSIpOworICAgICAgICAgICAgUFJPVklERVJfQUxHT1JJVEhNUy5yZW1vdmUoIlhNTFNpZ25hdHVyZUZhY3RvcnkiKTsKKworICAgICAgICAgICAgLy8gZGlmZmVyZW50IG5hbWVzIERpZmZpZS1IZWxsbWFuIHZzIERICisgICAgICAgICAgICB1bnByb3ZpZGUoIkFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvciIsICJEaWZmaWVIZWxsbWFuIik7CisgICAgICAgICAgICBwcm92aWRlKCJBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IiLCAiREgiKTsKKyAgICAgICAgICAgIHVucHJvdmlkZSgiQWxnb3JpdGhtUGFyYW1ldGVycyIsICJEaWZmaWVIZWxsbWFuIik7CisgICAgICAgICAgICBwcm92aWRlKCJBbGdvcml0aG1QYXJhbWV0ZXJzIiwgIkRIIik7CisgICAgICAgICAgICB1bnByb3ZpZGUoIktleUFncmVlbWVudCIsICJEaWZmaWVIZWxsbWFuIik7CisgICAgICAgICAgICBwcm92aWRlKCJLZXlBZ3JlZW1lbnQiLCAiREgiKTsKKyAgICAgICAgICAgIHVucHJvdmlkZSgiS2V5RmFjdG9yeSIsICJEaWZmaWVIZWxsbWFuIik7CisgICAgICAgICAgICBwcm92aWRlKCJLZXlGYWN0b3J5IiwgIkRIIik7CisgICAgICAgICAgICB1bnByb3ZpZGUoIktleVBhaXJHZW5lcmF0b3IiLCAiRGlmZmllSGVsbG1hbiIpOworICAgICAgICAgICAgcHJvdmlkZSgiS2V5UGFpckdlbmVyYXRvciIsICJESCIpOworCisgICAgICAgICAgICAvLyBkaWZmZXJlbnQgbmFtZXMgUEJFV2l0aFNIQTFBbmRERVNlZGUgdnMgUEJFV2l0aFNIQUFuZDMtS0VZVHJpcGxlREVTLUNCQworICAgICAgICAgICAgdW5wcm92aWRlKCJBbGdvcml0aG1QYXJhbWV0ZXJzIiwgIlBCRVdpdGhTSEExQW5kREVTZWRlIik7CisgICAgICAgICAgICB1bnByb3ZpZGUoIkNpcGhlciIsICJQQkVXaXRoU0hBMUFuZERFU2VkZSIpOworICAgICAgICAgICAgdW5wcm92aWRlKCJTZWNyZXRLZXlGYWN0b3J5IiwgIlBCRVdpdGhTSEExQW5kREVTZWRlIik7CisgICAgICAgICAgICBwcm92aWRlKCJBbGdvcml0aG1QYXJhbWV0ZXJzIiwgIlBLQ1MxMlBCRSIpOworICAgICAgICAgICAgcHJvdmlkZSgiQ2lwaGVyIiwgIlBCRVdpdGhTSEFBbmQzLUtFWVRyaXBsZURFUy1DQkMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNlY3JldEtleUZhY3RvcnkiLCAiUEJFV2l0aFNIQUFuZDMtS0VZVHJpcGxlREVTLUNCQyIpOworCisgICAgICAgICAgICAvLyBkaWZmZXJlbnQgbmFtZXM6IGRyb3BwZWQgU3VuCisgICAgICAgICAgICB1bnByb3ZpZGUoIktleU1hbmFnZXJGYWN0b3J5IiwgIlN1blg1MDkiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIktleU1hbmFnZXJGYWN0b3J5IiwgIlg1MDkiKTsKKworICAgICAgICAgICAgLy8gZGlmZmVyZW50IG5hbWVzOiBCb3VuY3lDYXN0bGUgYWN0dWFsbHkgdXNlcyB0aGUgU3RhbmRhcmQgbmFtZSBvZiBTSEEtMSB2cyBTSEEKKyAgICAgICAgICAgIHVucHJvdmlkZSgiTWVzc2FnZURpZ2VzdCIsICJTSEEiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIk1lc3NhZ2VEaWdlc3QiLCAiU0hBLTEiKTsKKworICAgICAgICAgICAgLy8gZGlmZmVyZW50IG5hbWVzOiBhZGRlZCAiRW5jcnlwdGlvbiIgc3VmZml4CisgICAgICAgICAgICB1bnByb3ZpZGUoIlNpZ25hdHVyZSIsICJNRDV3aXRoUlNBIik7CisgICAgICAgICAgICBwcm92aWRlKCJTaWduYXR1cmUiLCAiTUQ1V2l0aFJTQUVuY3J5cHRpb24iKTsKKyAgICAgICAgICAgIHVucHJvdmlkZSgiU2lnbmF0dXJlIiwgIlNIQTF3aXRoUlNBIik7CisgICAgICAgICAgICBwcm92aWRlKCJTaWduYXR1cmUiLCAiU0hBMVdpdGhSU0FFbmNyeXB0aW9uIik7CisgICAgICAgICAgICB1bnByb3ZpZGUoIlNpZ25hdHVyZSIsICJTSEEyNTZXaXRoUlNBIik7CisgICAgICAgICAgICBwcm92aWRlKCJTaWduYXR1cmUiLCAiU0hBMjU2V2l0aFJTQUVuY3J5cHRpb24iKTsKKyAgICAgICAgICAgIHVucHJvdmlkZSgiU2lnbmF0dXJlIiwgIlNIQTM4NFdpdGhSU0EiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNpZ25hdHVyZSIsICJTSEEzODRXaXRoUlNBRW5jcnlwdGlvbiIpOworICAgICAgICAgICAgdW5wcm92aWRlKCJTaWduYXR1cmUiLCAiU0hBNTEyV2l0aFJTQSIpOworICAgICAgICAgICAgcHJvdmlkZSgiU2lnbmF0dXJlIiwgIlNIQTUxMldpdGhSU0FFbmNyeXB0aW9uIik7CisKKyAgICAgICAgICAgIC8vIGRpZmZlcmVudCBuYW1lczogSlNTRSBSZWZlcmVuY2UgR3VpZGUgc2F5cyBQS0lYIGFrYSBYNTA5CisgICAgICAgICAgICB1bnByb3ZpZGUoIlRydXN0TWFuYWdlckZhY3RvcnkiLCAiUEtJWCIpOworICAgICAgICAgICAgcHJvdmlkZSgiVHJ1c3RNYW5hZ2VyRmFjdG9yeSIsICJYNTA5Iik7CisKKyAgICAgICAgICAgIC8vIGRpZmZlcmVudCBuYW1lczogQVJDRk9VUiB2cyBBUkM0CisgICAgICAgICAgICB1bnByb3ZpZGUoIkNpcGhlciIsICJBUkNGT1VSIik7CisgICAgICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiQVJDNCIpOworICAgICAgICAgICAgdW5wcm92aWRlKCJLZXlHZW5lcmF0b3IiLCAiQVJDRk9VUiIpOworICAgICAgICAgICAgcHJvdmlkZSgiS2V5R2VuZXJhdG9yIiwgIkFSQzQiKTsKKworICAgICAgICAgICAgLy8gZGlmZmVyZW50IGNhc2UgbmFtZXM6IEJsb3dmaXNoIHZzIEJMT1dGSVNICisgICAgICAgICAgICB1bnByb3ZpZGUoIkFsZ29yaXRobVBhcmFtZXRlcnMiLCAiQmxvd2Zpc2giKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIkFsZ29yaXRobVBhcmFtZXRlcnMiLCAiQkxPV0ZJU0giKTsKKyAgICAgICAgICAgIHVucHJvdmlkZSgiQ2lwaGVyIiwgIkJsb3dmaXNoIik7CisgICAgICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiQkxPV0ZJU0giKTsKKyAgICAgICAgICAgIHVucHJvdmlkZSgiS2V5R2VuZXJhdG9yIiwgIkJsb3dmaXNoIik7CisgICAgICAgICAgICBwcm92aWRlKCJLZXlHZW5lcmF0b3IiLCAiQkxPV0ZJU0giKTsKKworICAgICAgICAgICAgLy8gSGFybW9ueSBoYXMgWC41MDksIEJvdW5jeUNhc3RsZSBYNTA5CisgICAgICAgICAgICAvLyBUT0RPIHJlbW92ZSBvbmUsIHByb2JhYmx5IEhhcm1vbnkncworICAgICAgICAgICAgcHJvdmlkZSgiQ2VydGlmaWNhdGVGYWN0b3J5IiwgIlg1MDkiKTsKKworICAgICAgICAgICAgLy8gbm90IGp1c3QgZGlmZmVyZW50IG5hbWVzLCBidXQgZGlmZmVyZW50IGJpbmFyeSBmb3JtYXRzCisgICAgICAgICAgICB1bnByb3ZpZGUoIktleVN0b3JlIiwgIkpLUyIpOworICAgICAgICAgICAgcHJvdmlkZSgiS2V5U3RvcmUiLCAiQktTIik7CisgICAgICAgICAgICB1bnByb3ZpZGUoIktleVN0b3JlIiwgIkpDRUtTIik7CisgICAgICAgICAgICBwcm92aWRlKCJLZXlTdG9yZSIsICJCb3VuY3lDYXN0bGUiKTsKKworICAgICAgICAgICAgLy8gTm9pc2UgdG8gc3VwcG9ydCBLZXlTdG9yZS5QS0NTMTIKKyAgICAgICAgICAgIHByb3ZpZGUoIkNpcGhlciIsICJQQkVXSVRITUQ1QU5EMTI4QklUQUVTLUNCQy1PUEVOU1NMIik7CisgICAgICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiUEJFV0lUSE1ENUFORDE5MkJJVEFFUy1DQkMtT1BFTlNTTCIpOworICAgICAgICAgICAgcHJvdmlkZSgiQ2lwaGVyIiwgIlBCRVdJVEhNRDVBTkQyNTZCSVRBRVMtQ0JDLU9QRU5TU0wiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIkNpcGhlciIsICJQQkVXSVRITUQ1QU5EUkMyIik7CisgICAgICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiUEJFV0lUSFNIQTFBTkRERVMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIkNpcGhlciIsICJQQkVXSVRIU0hBMUFORFJDMiIpOworICAgICAgICAgICAgcHJvdmlkZSgiQ2lwaGVyIiwgIlBCRVdJVEhTSEEyNTZBTkQxMjhCSVRBRVMtQ0JDLUJDIik7CisgICAgICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiUEJFV0lUSFNIQTI1NkFORDE5MkJJVEFFUy1DQkMtQkMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIkNpcGhlciIsICJQQkVXSVRIU0hBMjU2QU5EMjU2QklUQUVTLUNCQy1CQyIpOworICAgICAgICAgICAgcHJvdmlkZSgiQ2lwaGVyIiwgIlBCRVdJVEhTSEFBTkQxMjhCSVRBRVMtQ0JDLUJDIik7CisgICAgICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiUEJFV0lUSFNIQUFORDEyOEJJVFJDMi1DQkMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIkNpcGhlciIsICJQQkVXSVRIU0hBQU5EMTI4QklUUkM0Iik7CisgICAgICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiUEJFV0lUSFNIQUFORDE5MkJJVEFFUy1DQkMtQkMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIkNpcGhlciIsICJQQkVXSVRIU0hBQU5EMi1LRVlUUklQTEVERVMtQ0JDIik7CisgICAgICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiUEJFV0lUSFNIQUFORDI1NkJJVEFFUy1DQkMtQkMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIkNpcGhlciIsICJQQkVXSVRIU0hBQU5ENDBCSVRSQzItQ0JDIik7CisgICAgICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiUEJFV0lUSFNIQUFORDQwQklUUkM0Iik7CisgICAgICAgICAgICBwcm92aWRlKCJDaXBoZXIiLCAiUEJFV0lUSFNIQUFORFRXT0ZJU0gtQ0JDIik7CisgICAgICAgICAgICBwcm92aWRlKCJNYWMiLCAiUEJFV0lUSEhNQUNTSEEiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIk1hYyIsICJQQkVXSVRISE1BQ1NIQTEiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNlY3JldEtleUZhY3RvcnkiLCAiUEJFV0lUSEhNQUNTSEExIik7CisgICAgICAgICAgICBwcm92aWRlKCJTZWNyZXRLZXlGYWN0b3J5IiwgIlBCRVdJVEhNRDVBTkQxMjhCSVRBRVMtQ0JDLU9QRU5TU0wiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNlY3JldEtleUZhY3RvcnkiLCAiUEJFV0lUSE1ENUFORDE5MkJJVEFFUy1DQkMtT1BFTlNTTCIpOworICAgICAgICAgICAgcHJvdmlkZSgiU2VjcmV0S2V5RmFjdG9yeSIsICJQQkVXSVRITUQ1QU5EMjU2QklUQUVTLUNCQy1PUEVOU1NMIik7CisgICAgICAgICAgICBwcm92aWRlKCJTZWNyZXRLZXlGYWN0b3J5IiwgIlBCRVdJVEhNRDVBTkRSQzIiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNlY3JldEtleUZhY3RvcnkiLCAiUEJFV0lUSFNIQTFBTkRERVMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNlY3JldEtleUZhY3RvcnkiLCAiUEJFV0lUSFNIQTFBTkRSQzIiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNlY3JldEtleUZhY3RvcnkiLCAiUEJFV0lUSFNIQTI1NkFORDEyOEJJVEFFUy1DQkMtQkMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNlY3JldEtleUZhY3RvcnkiLCAiUEJFV0lUSFNIQTI1NkFORDE5MkJJVEFFUy1DQkMtQkMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNlY3JldEtleUZhY3RvcnkiLCAiUEJFV0lUSFNIQTI1NkFORDI1NkJJVEFFUy1DQkMtQkMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNlY3JldEtleUZhY3RvcnkiLCAiUEJFV0lUSFNIQUFORDEyOEJJVEFFUy1DQkMtQkMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNlY3JldEtleUZhY3RvcnkiLCAiUEJFV0lUSFNIQUFORDEyOEJJVFJDMi1DQkMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNlY3JldEtleUZhY3RvcnkiLCAiUEJFV0lUSFNIQUFORDEyOEJJVFJDNCIpOworICAgICAgICAgICAgcHJvdmlkZSgiU2VjcmV0S2V5RmFjdG9yeSIsICJQQkVXSVRIU0hBQU5EMTkyQklUQUVTLUNCQy1CQyIpOworICAgICAgICAgICAgcHJvdmlkZSgiU2VjcmV0S2V5RmFjdG9yeSIsICJQQkVXSVRIU0hBQU5EMi1LRVlUUklQTEVERVMtQ0JDIik7CisgICAgICAgICAgICBwcm92aWRlKCJTZWNyZXRLZXlGYWN0b3J5IiwgIlBCRVdJVEhTSEFBTkQyNTZCSVRBRVMtQ0JDLUJDIik7CisgICAgICAgICAgICBwcm92aWRlKCJTZWNyZXRLZXlGYWN0b3J5IiwgIlBCRVdJVEhTSEFBTkQ0MEJJVFJDMi1DQkMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNlY3JldEtleUZhY3RvcnkiLCAiUEJFV0lUSFNIQUFORDQwQklUUkM0Iik7CisgICAgICAgICAgICBwcm92aWRlKCJTZWNyZXRLZXlGYWN0b3J5IiwgIlBCRVdJVEhTSEFBTkRUV09GSVNILUNCQyIpOworCisgICAgICAgICAgICAvLyByZW1vdmVkIExEQVAKKyAgICAgICAgICAgIHVucHJvdmlkZSgiQ2VydFN0b3JlIiwgIkxEQVAiKTsKKworICAgICAgICAgICAgLy8gcmVtb3ZlZCBNRDIKKyAgICAgICAgICAgIHVucHJvdmlkZSgiTWVzc2FnZURpZ2VzdCIsICJNRDIiKTsKKyAgICAgICAgICAgIHVucHJvdmlkZSgiU2lnbmF0dXJlIiwgIk1EMndpdGhSU0EiKTsKKworICAgICAgICAgICAgLy8gcmVtb3ZlZCBSQzIKKyAgICAgICAgICAgIC8vIE5PVEUgdGhlIGltcGxlbWVudGF0aW9uIHJlbWFpbnMgdG8gc3VwcG9ydCBQS0NTMTIga2V5c3RvcmVzCisgICAgICAgICAgICB1bnByb3ZpZGUoIkFsZ29yaXRobVBhcmFtZXRlcnMiLCAiUEJFV2l0aFNIQTFBbmRSQzJfNDAiKTsKKyAgICAgICAgICAgIHVucHJvdmlkZSgiQWxnb3JpdGhtUGFyYW1ldGVycyIsICJSQzIiKTsKKyAgICAgICAgICAgIHVucHJvdmlkZSgiQ2lwaGVyIiwgIlBCRVdpdGhTSEExQW5kUkMyXzQwIik7CisgICAgICAgICAgICB1bnByb3ZpZGUoIkNpcGhlciIsICJSQzIiKTsKKyAgICAgICAgICAgIHVucHJvdmlkZSgiS2V5R2VuZXJhdG9yIiwgIlJDMiIpOworICAgICAgICAgICAgdW5wcm92aWRlKCJTZWNyZXRLZXlGYWN0b3J5IiwgIlBCRVdpdGhTSEExQW5kUkMyXzQwIik7CisKKyAgICAgICAgICAgIC8vIFBCRVdpdGhNRDVBbmRUcmlwbGVERVMgaXMgU3VuIHByb3ByaWV0YXJ5CisgICAgICAgICAgICB1bnByb3ZpZGUoIkFsZ29yaXRobVBhcmFtZXRlcnMiLCAiUEJFV2l0aE1ENUFuZFRyaXBsZURFUyIpOworICAgICAgICAgICAgdW5wcm92aWRlKCJDaXBoZXIiLCAiUEJFV2l0aE1ENUFuZFRyaXBsZURFUyIpOworICAgICAgICAgICAgdW5wcm92aWRlKCJTZWNyZXRLZXlGYWN0b3J5IiwgIlBCRVdpdGhNRDVBbmRUcmlwbGVERVMiKTsKKworICAgICAgICAgICAgLy8gbWlzc2luZyBmcm9tIEJvdW5jeSBDYXN0bGUKKyAgICAgICAgICAgIC8vIFN0YW5kYXJkIE5hbWVzIGRvY3VtZW50IHNheXMgdG8gdXNlIHNwZWNpZmljIFBCRVdpdGgqQW5kKgorICAgICAgICAgICAgdW5wcm92aWRlKCJBbGdvcml0aG1QYXJhbWV0ZXJzIiwgIlBCRSIpOworCisgICAgICAgICAgICAvLyBtaXNzaW5nIGZyb20gQm91bmN5IENhc3RsZQorICAgICAgICAgICAgLy8gVE9ETyBhZGQgdG8gSkRLQWxnb3JpdGhtUGFyYW1ldGVycyBwZXJoYXBzIGFzIHdyYXBwZXIgb24gUEJFUzJQYXJhbWV0ZXJzCisgICAgICAgICAgICAvLyBGb3Igbm93LCBjYW4gdXNlIEFsZ29yaXRobVBhcmFtZXRlcnNTcGVjIGphdmF4LmNyeXB0by5zcGVjLlBCRVBhcmFtZXRlclNwZWMgaW5zdGVhZAorICAgICAgICAgICAgdW5wcm92aWRlKCJBbGdvcml0aG1QYXJhbWV0ZXJzIiwgIlBCRVdpdGhNRDVBbmRERVMiKTsgLy8gMS4yLjg0MC4xMTM1NDkuMS41LjMKKworICAgICAgICAgICAgLy8gRUMgc3VwcG9ydAorICAgICAgICAgICAgLy8gcHJvdmlkZSgiQWxnb3JpdGhtUGFyYW1ldGVycyIsICJFQyIpOworICAgICAgICAgICAgcHJvdmlkZSgiS2V5QWdyZWVtZW50IiwgIkVDREgiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIktleUZhY3RvcnkiLCAiRUMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIktleVBhaXJHZW5lcmF0b3IiLCAiRUMiKTsKKyAgICAgICAgICAgIHByb3ZpZGUoIlNpZ25hdHVyZSIsICJOT05FV0lUSEVDRFNBIik7CisgICAgICAgICAgICBwcm92aWRlKCJTaWduYXR1cmUiLCAiRUNEU0EiKTsgLy8gYXMgb3Bwb3NlZCB0byBTSEExV0lUSEVDRFNBCisgICAgICAgICAgICBwcm92aWRlKCJTaWduYXR1cmUiLCAiU0hBMjU2V0lUSEVDRFNBIik7CisgICAgICAgICAgICBwcm92aWRlKCJTaWduYXR1cmUiLCAiU0hBMzg0V0lUSEVDRFNBIik7CisgICAgICAgICAgICBwcm92aWRlKCJTaWduYXR1cmUiLCAiU0hBNTEyV0lUSEVDRFNBIik7CisKKyAgICAgICAgICAgIC8vIEFuZHJvaWQncyBDQSBzdG9yZQorICAgICAgICAgICAgcHJvdmlkZSgiS2V5U3RvcmUiLCAiQW5kcm9pZENBU3RvcmUiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNTTF9DT05URVhUX1BST1RPQ09MU19ERUZBVUxUID0gIkRlZmF1bHQiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU2V0PFN0cmluZz4gU1NMX0NPTlRFWFRfUFJPVE9DT0xTID0gbmV3IEhhc2hTZXQ8U3RyaW5nPihBcnJheXMuYXNMaXN0KAorICAgICAgICBTU0xfQ09OVEVYVF9QUk9UT0NPTFNfREVGQVVMVCwKKyAgICAgICAgIlNTTCIsCisgICAgICAgIC8vICJTU0x2MiIsCisgICAgICAgICJTU0x2MyIsCisgICAgICAgICJUTFMiLAorICAgICAgICAiVExTdjEiKSk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1NMX0NPTlRFWFRfUFJPVE9DT0xfREVGQVVMVCA9ICJUTFMiOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTZXQ8U3RyaW5nPiBLRVlfVFlQRVMgPSBuZXcgSGFzaFNldDxTdHJpbmc+KEFycmF5cy5hc0xpc3QoCisgICAgICAgICJSU0EiLAorICAgICAgICAiRFNBIiwKKyAgICAgICAgLy8gREhfKiBhcmUgc3BlY2lmaWVkIGJ5IHN0YW5kYXJkIG5hbWVzLCBidXQgZG8gbm90IHNlZW0gdG8gYmUgc3VwcG9ydGVkIGJ5IFJJCisgICAgICAgIC8vICJESF9SU0EiLAorICAgICAgICAvLyAiREhfRFNBIiwKKyAgICAgICAgIkVDIiwKKyAgICAgICAgIkVDX0VDIiwKKyAgICAgICAgIkVDX1JTQSIpKTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU2V0PFN0cmluZz4gU1NMX1NPQ0tFVF9QUk9UT0NPTFMgPSBuZXcgSGFzaFNldDxTdHJpbmc+KEFycmF5cy5hc0xpc3QoCisgICAgICAgIC8vICJTU0x2MiIsCisgICAgICAgICJTU0x2MyIsCisgICAgICAgICJUTFN2MSIpKTsKKyAgICBzdGF0aWMgeworICAgICAgICBpZiAoSVNfUkkpIHsKKyAgICAgICAgICAgIC8qIEV2ZW4gdGhvdWdoIHdlIHVzZSBPcGVuU1NMJ3MgU1NMdjIzX21ldGhvZCB3aGljaAorICAgICAgICAgICAgICogc3VwcG9ydHMgc2VuZGluZyBTU0x2MiBjbGllbnQgaGVsbG8gbWVzc2FnZXMsIHRoZQorICAgICAgICAgICAgICogT3BlblNTTCBpbXBsZW1lbnRhdGlvbiBpbiBzMjNfY2xpZW50X2hlbGxvIGRpc2FibGVzCisgICAgICAgICAgICAgKiB0aGlzIGlmIFNTTF9PUF9OT19TU0x2MiBpcyBzcGVjaWZpZWQsIHdoaWNoIHdlIGFsd2F5cworICAgICAgICAgICAgICogZG8gdG8gZGlzYWJsZSBnZW5lcmFsIHVzZSBvZiBTU0x2Mi4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgU1NMX1NPQ0tFVF9QUk9UT0NPTFMuYWRkKCJTU0x2MkhlbGxvIik7CisKKyAgICAgICAgICAgIFNTTF9TT0NLRVRfUFJPVE9DT0xTLmFkZCgiVExTdjEuMSIpOworICAgICAgICAgICAgU1NMX1NPQ0tFVF9QUk9UT0NPTFMuYWRkKCJUTFN2MS4yIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWYWxpZCB2YWx1ZXMgZm9yIFg1MDlUcnVzdE1hbmFnZXIuY2hlY2tDbGllbnRUcnVzdGVkIGF1dGhUeXBlLAorICAgICAqIGVpdGhlciB0aGUgYWxnb3JpdGhtIG9mIHRoZSBwdWJsaWMga2V5IG9yIFVOS05PV04uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTZXQ8U3RyaW5nPiBDTElFTlRfQVVUSF9UWVBFUyA9IG5ldyBIYXNoU2V0PFN0cmluZz4oQXJyYXlzLmFzTGlzdCgKKyAgICAgICAgIlJTQSIsCisgICAgICAgICJEU0EiLAorICAgICAgICAiRUMiLAorICAgICAgICAiVU5LTk9XTiIpKTsKKworICAgIC8qKgorICAgICAqIFZhbGlkIHZhbHVlcyBmb3IgWDUwOVRydXN0TWFuYWdlci5jaGVja1NlcnZlclRydXN0ZWQgYXV0aFR5cGUsCisgICAgICogZWl0aGVyIGtleSBleGNoYW5nZSBhbGdvcml0aG0gcGFydCBvZiB0aGUgY2lwaGVyIHN1aXRlCisgICAgICogb3IgVU5LTk9XTi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFNldDxTdHJpbmc+IFNFUlZFUl9BVVRIX1RZUEVTID0gbmV3IEhhc2hTZXQ8U3RyaW5nPihBcnJheXMuYXNMaXN0KAorICAgICAgICAiREhFX0RTUyIsCisgICAgICAgICJESEVfRFNTX0VYUE9SVCIsCisgICAgICAgICJESEVfUlNBIiwKKyAgICAgICAgIkRIRV9SU0FfRVhQT1JUIiwKKyAgICAgICAgIkRIX0RTU19FWFBPUlQiLAorICAgICAgICAiREhfUlNBX0VYUE9SVCIsCisgICAgICAgICJESF9hbm9uIiwKKyAgICAgICAgIkRIX2Fub25fRVhQT1JUIiwKKyAgICAgICAgIktSQjUiLAorICAgICAgICAiS1JCNV9FWFBPUlQiLAorICAgICAgICAiUlNBIiwKKyAgICAgICAgIlJTQV9FWFBPUlQiLAorICAgICAgICAiUlNBX0VYUE9SVDEwMjQiLAorICAgICAgICAiRUNESF9FQ0RTQSIsCisgICAgICAgICJFQ0RIX1JTQSIsCisgICAgICAgICJFQ0RIRV9FQ0RTQSIsCisgICAgICAgICJFQ0RIRV9SU0EiLAorICAgICAgICAiVU5LTk9XTiIpKTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENJUEhFUl9TVUlURV9JTlZBTElEID0gIlNTTF9OVUxMX1dJVEhfTlVMTF9OVUxMIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU2V0PFN0cmluZz4gQ0lQSEVSX1NVSVRFU19ORUlUSEVSID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTZXQ8U3RyaW5nPiBDSVBIRVJfU1VJVEVTX1JJID0gbmV3IExpbmtlZEhhc2hTZXQ8U3RyaW5nPigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU2V0PFN0cmluZz4gQ0lQSEVSX1NVSVRFU19PUEVOU1NMID0gbmV3IExpbmtlZEhhc2hTZXQ8U3RyaW5nPigpOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTZXQ8U3RyaW5nPiBDSVBIRVJfU1VJVEVTOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgdm9pZCBhZGRSaShTdHJpbmcgY2lwaGVyU3VpdGUpIHsKKyAgICAgICAgQ0lQSEVSX1NVSVRFU19SSS5hZGQoY2lwaGVyU3VpdGUpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHZvaWQgYWRkT3BlblNzbChTdHJpbmcgY2lwaGVyU3VpdGUpIHsKKyAgICAgICAgQ0lQSEVSX1NVSVRFU19PUEVOU1NMLmFkZChjaXBoZXJTdWl0ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgdm9pZCBhZGRCb3RoKFN0cmluZyBjaXBoZXJTdWl0ZSkgeworICAgICAgICBhZGRSaShjaXBoZXJTdWl0ZSk7CisgICAgICAgIGFkZE9wZW5Tc2woY2lwaGVyU3VpdGUpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHZvaWQgYWRkTmVpdGhlcihTdHJpbmcgY2lwaGVyU3VpdGUpIHsKKyAgICAgICAgQ0lQSEVSX1NVSVRFU19ORUlUSEVSLmFkZChjaXBoZXJTdWl0ZSk7CisgICAgfQorCisgICAgc3RhdGljIHsKKyAgICAgICAgLy8gTm90ZSB0aGVzZSBhcmUgYWRkZWQgaW4gcHJpb3JpdHkgb3JkZXIgYXMgZGVmaW5lZCBieSBSSSA3IGRvY3VtZW50YXRpb24uCisgICAgICAgIC8vIGRlZmF1bHRDaXBoZXJTdWl0ZXMKKyAgICAgICAgYWRkTmVpdGhlcigiVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBMzg0Iik7CisgICAgICAgIGFkZE5laXRoZXIoIlRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEzODQiKTsKKyAgICAgICAgYWRkTmVpdGhlcigiVExTX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQTI1NiIpOworICAgICAgICBhZGROZWl0aGVyKCJUTFNfRUNESF9FQ0RTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQTM4NCIpOworICAgICAgICBhZGROZWl0aGVyKCJUTFNfRUNESF9SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEzODQiKTsKKyAgICAgICAgYWRkTmVpdGhlcigiVExTX0RIRV9SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEyNTYiKTsKKyAgICAgICAgYWRkTmVpdGhlcigiVExTX0RIRV9EU1NfV0lUSF9BRVNfMjU2X0NCQ19TSEEyNTYiKTsKKyAgICAgICAgYWRkT3BlblNzbCgiVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBIik7CisgICAgICAgIGFkZE9wZW5Tc2woIlRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEiKTsKKyAgICAgICAgYWRkT3BlblNzbCgiVExTX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSIpOworICAgICAgICBhZGRPcGVuU3NsKCJUTFNfRUNESF9FQ0RTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSIpOworICAgICAgICBhZGRPcGVuU3NsKCJUTFNfRUNESF9SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEiKTsKKyAgICAgICAgYWRkT3BlblNzbCgiVExTX0RIRV9SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEiKTsKKyAgICAgICAgYWRkT3BlblNzbCgiVExTX0RIRV9EU1NfV0lUSF9BRVNfMjU2X0NCQ19TSEEiKTsKKyAgICAgICAgYWRkUmkoICAgICAiVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBMjU2Iik7CisgICAgICAgIGFkZFJpKCAgICAgIlRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEyNTYiKTsKKyAgICAgICAgYWRkUmkoICAgICAiVExTX1JTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQTI1NiIpOworICAgICAgICBhZGRSaSggICAgICJUTFNfRUNESF9FQ0RTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQTI1NiIpOworICAgICAgICBhZGRSaSggICAgICJUTFNfRUNESF9SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEyNTYiKTsKKyAgICAgICAgYWRkUmkoICAgICAiVExTX0RIRV9SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEyNTYiKTsKKyAgICAgICAgYWRkUmkoICAgICAiVExTX0RIRV9EU1NfV0lUSF9BRVNfMTI4X0NCQ19TSEEyNTYiKTsKKyAgICAgICAgYWRkQm90aCggICAiVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBIik7CisgICAgICAgIGFkZEJvdGgoICAgIlRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEiKTsKKyAgICAgICAgYWRkQm90aCggICAiVExTX1JTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSIpOworICAgICAgICBhZGRCb3RoKCAgICJUTFNfRUNESF9FQ0RTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSIpOworICAgICAgICBhZGRCb3RoKCAgICJUTFNfRUNESF9SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEiKTsKKyAgICAgICAgYWRkQm90aCggICAiVExTX0RIRV9SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEiKTsKKyAgICAgICAgYWRkQm90aCggICAiVExTX0RIRV9EU1NfV0lUSF9BRVNfMTI4X0NCQ19TSEEiKTsKKyAgICAgICAgYWRkQm90aCggICAiVExTX0VDREhFX0VDRFNBX1dJVEhfUkM0XzEyOF9TSEEiKTsKKyAgICAgICAgYWRkQm90aCggICAiVExTX0VDREhFX1JTQV9XSVRIX1JDNF8xMjhfU0hBIik7CisgICAgICAgIGFkZEJvdGgoICAgIlNTTF9SU0FfV0lUSF9SQzRfMTI4X1NIQSIpOworICAgICAgICBhZGRCb3RoKCAgICJUTFNfRUNESF9FQ0RTQV9XSVRIX1JDNF8xMjhfU0hBIik7CisgICAgICAgIGFkZEJvdGgoICAgIlRMU19FQ0RIX1JTQV9XSVRIX1JDNF8xMjhfU0hBIik7CisgICAgICAgIGFkZEJvdGgoICAgIlRMU19FQ0RIRV9FQ0RTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiKTsKKyAgICAgICAgYWRkQm90aCggICAiVExTX0VDREhFX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiKTsKKyAgICAgICAgYWRkQm90aCggICAiU1NMX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiKTsKKyAgICAgICAgYWRkQm90aCggICAiVExTX0VDREhfRUNEU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBIik7CisgICAgICAgIGFkZEJvdGgoICAgIlRMU19FQ0RIX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiKTsKKyAgICAgICAgYWRkQm90aCggICAiU1NMX0RIRV9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBIik7CisgICAgICAgIGFkZEJvdGgoICAgIlNTTF9ESEVfRFNTX1dJVEhfM0RFU19FREVfQ0JDX1NIQSIpOworICAgICAgICBhZGRCb3RoKCAgICJTU0xfUlNBX1dJVEhfUkM0XzEyOF9NRDUiKTsKKyAgICAgICAgLy8gUkZDIDU3NDYncyBTaWduYWxpbmcgQ2lwaGVyIFN1aXRlIFZhbHVlIHRvIGluZGljYXRlIGEgcmVxdWVzdCBmb3Igc2VjdXJlIHJlbmVnb3RpYXRpb24KKyAgICAgICAgYWRkQm90aChDSVBIRVJfU1VJVEVfU0VDVVJFX1JFTkVHT1RJQVRJT04pOworCisgICAgICAgIC8vIG5vbi1kZWZhdWx0Q2lwaGVyU3VpdGVzCisgICAgICAgIGFkZE5laXRoZXIoIlRMU19ESF9hbm9uX1dJVEhfQUVTXzI1Nl9DQkNfU0hBMjU2Iik7CisgICAgICAgIGFkZE9wZW5Tc2woIlRMU19FQ0RIX2Fub25fV0lUSF9BRVNfMjU2X0NCQ19TSEEiKTsKKyAgICAgICAgYWRkT3BlblNzbCgiVExTX0RIX2Fub25fV0lUSF9BRVNfMjU2X0NCQ19TSEEiKTsKKyAgICAgICAgYWRkUmkoICAgICAiVExTX0RIX2Fub25fV0lUSF9BRVNfMTI4X0NCQ19TSEEyNTYiKTsKKyAgICAgICAgYWRkQm90aCggICAiVExTX0VDREhfYW5vbl9XSVRIX0FFU18xMjhfQ0JDX1NIQSIpOworICAgICAgICBhZGRCb3RoKCAgICJUTFNfREhfYW5vbl9XSVRIX0FFU18xMjhfQ0JDX1NIQSIpOworICAgICAgICBhZGRCb3RoKCAgICJUTFNfRUNESF9hbm9uX1dJVEhfUkM0XzEyOF9TSEEiKTsKKyAgICAgICAgYWRkQm90aCggICAiU1NMX0RIX2Fub25fV0lUSF9SQzRfMTI4X01ENSIpOworICAgICAgICBhZGRCb3RoKCAgICJUTFNfRUNESF9hbm9uX1dJVEhfM0RFU19FREVfQ0JDX1NIQSIpOworICAgICAgICBhZGRCb3RoKCAgICJTU0xfREhfYW5vbl9XSVRIXzNERVNfRURFX0NCQ19TSEEiKTsKKyAgICAgICAgYWRkUmkoICAgICAiVExTX1JTQV9XSVRIX05VTExfU0hBMjU2Iik7CisgICAgICAgIGFkZEJvdGgoICAgIlRMU19FQ0RIRV9FQ0RTQV9XSVRIX05VTExfU0hBIik7CisgICAgICAgIGFkZEJvdGgoICAgIlRMU19FQ0RIRV9SU0FfV0lUSF9OVUxMX1NIQSIpOworICAgICAgICBhZGRCb3RoKCAgICJTU0xfUlNBX1dJVEhfTlVMTF9TSEEiKTsKKyAgICAgICAgYWRkQm90aCggICAiVExTX0VDREhfRUNEU0FfV0lUSF9OVUxMX1NIQSIpOworICAgICAgICBhZGRCb3RoKCAgICJUTFNfRUNESF9SU0FfV0lUSF9OVUxMX1NIQSIpOworICAgICAgICBhZGRCb3RoKCAgICJUTFNfRUNESF9hbm9uX1dJVEhfTlVMTF9TSEEiKTsKKyAgICAgICAgYWRkQm90aCggICAiU1NMX1JTQV9XSVRIX05VTExfTUQ1Iik7CisgICAgICAgIGFkZEJvdGgoICAgIlNTTF9SU0FfV0lUSF9ERVNfQ0JDX1NIQSIpOworICAgICAgICBhZGRCb3RoKCAgICJTU0xfREhFX1JTQV9XSVRIX0RFU19DQkNfU0hBIik7CisgICAgICAgIGFkZEJvdGgoICAgIlNTTF9ESEVfRFNTX1dJVEhfREVTX0NCQ19TSEEiKTsKKyAgICAgICAgYWRkQm90aCggICAiU1NMX0RIX2Fub25fV0lUSF9ERVNfQ0JDX1NIQSIpOworICAgICAgICBhZGRCb3RoKCAgICJTU0xfUlNBX0VYUE9SVF9XSVRIX1JDNF80MF9NRDUiKTsKKyAgICAgICAgYWRkQm90aCggICAiU1NMX0RIX2Fub25fRVhQT1JUX1dJVEhfUkM0XzQwX01ENSIpOworICAgICAgICBhZGRCb3RoKCAgICJTU0xfUlNBX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEiKTsKKyAgICAgICAgYWRkQm90aCggICAiU1NMX0RIRV9SU0FfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSIpOworICAgICAgICBhZGRCb3RoKCAgICJTU0xfREhFX0RTU19FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBIik7CisgICAgICAgIGFkZEJvdGgoICAgIlNTTF9ESF9hbm9uX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEiKTsKKworICAgICAgICAvLyBBbmRyb2lkIGRvZXMgbm90IGhhdmUgS2ViZXJvcyBzdXBwb3J0CisgICAgICAgIGFkZFJpKCAgICAgIlRMU19LUkI1X1dJVEhfUkM0XzEyOF9TSEEiKTsKKyAgICAgICAgYWRkUmkoICAgICAiVExTX0tSQjVfV0lUSF9SQzRfMTI4X01ENSIpOworICAgICAgICBhZGRSaSggICAgICJUTFNfS1JCNV9XSVRIXzNERVNfRURFX0NCQ19TSEEiKTsKKyAgICAgICAgYWRkUmkoICAgICAiVExTX0tSQjVfV0lUSF8zREVTX0VERV9DQkNfTUQ1Iik7CisgICAgICAgIGFkZFJpKCAgICAgIlRMU19LUkI1X1dJVEhfREVTX0NCQ19TSEEiKTsKKyAgICAgICAgYWRkUmkoICAgICAiVExTX0tSQjVfV0lUSF9ERVNfQ0JDX01ENSIpOworICAgICAgICBhZGRSaSggICAgICJUTFNfS1JCNV9FWFBPUlRfV0lUSF9SQzRfNDBfU0hBIik7CisgICAgICAgIGFkZFJpKCAgICAgIlRMU19LUkI1X0VYUE9SVF9XSVRIX1JDNF80MF9NRDUiKTsKKyAgICAgICAgYWRkUmkoICAgICAiVExTX0tSQjVfRVhQT1JUX1dJVEhfREVTX0NCQ180MF9TSEEiKTsKKyAgICAgICAgYWRkUmkoICAgICAiVExTX0tSQjVfRVhQT1JUX1dJVEhfREVTX0NCQ180MF9NRDUiKTsKKworICAgICAgICAvLyBEcm9wcGVkCisgICAgICAgIGFkZE5laXRoZXIoIlNTTF9ESF9EU1NfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSIpOworICAgICAgICBhZGROZWl0aGVyKCJTU0xfREhfUlNBX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEiKTsKKworICAgICAgICAvLyBPbGQgbm9uIHN0YW5kYXJkIGV4cG9ydGFibGUgZW5jcnlwdGlvbgorICAgICAgICBhZGROZWl0aGVyKCJTU0xfUlNBX0VYUE9SVDEwMjRfV0lUSF9ERVNfQ0JDX1NIQSIpOworICAgICAgICBhZGROZWl0aGVyKCJTU0xfUlNBX0VYUE9SVDEwMjRfV0lUSF9SQzRfNTZfU0hBIik7CisKKyAgICAgICAgLy8gTm8gUkMyCisgICAgICAgIGFkZE5laXRoZXIoIlNTTF9SU0FfRVhQT1JUX1dJVEhfUkMyX0NCQ180MF9NRDUiKTsKKyAgICAgICAgYWRkTmVpdGhlcigiVExTX0tSQjVfRVhQT1JUX1dJVEhfUkMyX0NCQ180MF9TSEEiKTsKKyAgICAgICAgYWRkTmVpdGhlcigiVExTX0tSQjVfRVhQT1JUX1dJVEhfUkMyX0NCQ180MF9NRDUiKTsKKworICAgICAgICBDSVBIRVJfU1VJVEVTID0gKElTX1JJKSA/IENJUEhFUl9TVUlURVNfUkkgOiBDSVBIRVJfU1VJVEVTX09QRU5TU0w7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBMaXN0PFN0cmluZz4gQ0lQSEVSX1NVSVRFU19ERUZBVUxUID0gKElTX1JJKQorICAgICAgICAgICAgPyBBcnJheXMuYXNMaXN0KCJUTFNfREhFX1JTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRMU19FQ0RIX0VDRFNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1NMX0RIRV9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1NMX1JTQV9XSVRIX1JDNF8xMjhfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVExTX0VDREhfRUNEU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVExTX0VDREhFX1JTQV9XSVRIX1JDNF8xMjhfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVExTX0VDREhfRUNEU0FfV0lUSF9SQzRfMTI4X1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRMU19FQ0RIRV9FQ0RTQV9XSVRIX1JDNF8xMjhfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVExTX0VDREhFX1JTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRMU19FQ0RIRV9FQ0RTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUTFNfRUNESF9SU0FfV0lUSF9SQzRfMTI4X1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRMU19FTVBUWV9SRU5FR09USUFUSU9OX0lORk9fU0NTViIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRMU19FQ0RIX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUTFNfRUNESF9SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUTFNfRUNESEVfRUNEU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUTFNfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVExTX0VDREhFX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTU0xfUlNBX1dJVEhfUkM0XzEyOF9NRDUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUTFNfREhFX0RTU19XSVRIX0FFU18xMjhfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNTTF9ESEVfRFNTX1dJVEhfM0RFU19FREVfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNTTF9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBIikKKyAgICAgICAgICAgIDogQXJyYXlzLmFzTGlzdCgiU1NMX1JTQV9XSVRIX1JDNF8xMjhfTUQ1IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1NMX1JTQV9XSVRIX1JDNF8xMjhfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVExTX1JTQV9XSVRIX0FFU18xMjhfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRMU19SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUTFNfRUNESF9FQ0RTQV9XSVRIX1JDNF8xMjhfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVExTX0VDREhfRUNEU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUTFNfRUNESF9FQ0RTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRMU19FQ0RIX1JTQV9XSVRIX1JDNF8xMjhfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVExTX0VDREhfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVExTX0VDREhfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVExTX0VDREhFX0VDRFNBX1dJVEhfUkM0XzEyOF9TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUTFNfRUNESEVfRUNEU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUTFNfRUNESEVfRUNEU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUTFNfRUNESEVfUlNBX1dJVEhfUkM0XzEyOF9TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUTFNfRUNESEVfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVExTX0VDREhFX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRMU19ESEVfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVExTX0RIRV9SU0FfV0lUSF9BRVNfMjU2X0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUTFNfREhFX0RTU19XSVRIX0FFU18xMjhfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRMU19ESEVfRFNTX1dJVEhfQUVTXzI1Nl9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1NMX1JTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUTFNfRUNESF9FQ0RTQV9XSVRIXzNERVNfRURFX0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUTFNfRUNESF9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVExTX0VDREhFX0VDRFNBX1dJVEhfM0RFU19FREVfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRMU19FQ0RIRV9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1NMX0RIRV9SU0FfV0lUSF8zREVTX0VERV9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1NMX0RIRV9EU1NfV0lUSF8zREVTX0VERV9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1NMX1JTQV9XSVRIX0RFU19DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1NMX0RIRV9SU0FfV0lUSF9ERVNfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNTTF9ESEVfRFNTX1dJVEhfREVTX0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTU0xfUlNBX0VYUE9SVF9XSVRIX1JDNF80MF9NRDUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTU0xfUlNBX0VYUE9SVF9XSVRIX0RFUzQwX0NCQ19TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTU0xfREhFX1JTQV9FWFBPUlRfV0lUSF9ERVM0MF9DQkNfU0hBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1NMX0RIRV9EU1NfRVhQT1JUX1dJVEhfREVTNDBfQ0JDX1NIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0lQSEVSX1NVSVRFX1NFQ1VSRV9SRU5FR09USUFUSU9OKTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU2V0PFN0cmluZz4gQ0lQSEVSX1NVSVRFU19TU0xFTkdJTkUgPSBuZXcgSGFzaFNldDxTdHJpbmc+KENJUEhFUl9TVUlURVMpOworICAgIHN0YXRpYyB7CisgICAgICAgIC8vIE5vIEVsbGlwdGljIEN1cnZlIHN1cHBvcnQgb24gU1NMRW5naW5lIGJhc2VkIHByb3ZpZGVyCisgICAgICAgIGlmICghSVNfUkkpIHsKKyAgICAgICAgICAgIEl0ZXJhdG9yPFN0cmluZz4gaSA9IENJUEhFUl9TVUlURVNfU1NMRU5HSU5FLml0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoaS5oYXNOZXh0KCkpIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgY3MgPSBpLm5leHQoKTsKKyAgICAgICAgICAgICAgICBpZiAoY3Muc3RhcnRzV2l0aCgiVExTX0VDIikgfHwgY3MuZXF1YWxzKENJUEhFUl9TVUlURV9TRUNVUkVfUkVORUdPVElBVElPTikpIHsKKyAgICAgICAgICAgICAgICAgICAgaS5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsIENsYXNzPD8gZXh0ZW5kcyBLZXlTcGVjPj4gUFJJVkFURV9LRVlfU1BFQ19DTEFTU0VTOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPFN0cmluZywgQ2xhc3M8PyBleHRlbmRzIEtleVNwZWM+PiBQVUJMSUNfS0VZX1NQRUNfQ0xBU1NFUzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsIEludGVnZXI+IE1JTklNVU1fS0VZX1NJWkU7CisgICAgc3RhdGljIHsKKyAgICAgICAgUFJJVkFURV9LRVlfU1BFQ19DTEFTU0VTID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBDbGFzczw/IGV4dGVuZHMgS2V5U3BlYz4+KCk7CisgICAgICAgIFBVQkxJQ19LRVlfU1BFQ19DTEFTU0VTID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBDbGFzczw/IGV4dGVuZHMgS2V5U3BlYz4+KCk7CisgICAgICAgIE1JTklNVU1fS0VZX1NJWkUgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIEludGVnZXI+KCk7CisgICAgICAgIFBSSVZBVEVfS0VZX1NQRUNfQ0xBU1NFUy5wdXQoIlJTQSIsIFJTQVByaXZhdGVDcnRLZXlTcGVjLmNsYXNzKTsKKyAgICAgICAgUFVCTElDX0tFWV9TUEVDX0NMQVNTRVMucHV0KCJSU0EiLCBSU0FQdWJsaWNLZXlTcGVjLmNsYXNzKTsKKyAgICAgICAgTUlOSU1VTV9LRVlfU0laRS5wdXQoIlJTQSIsIDI1Nik7CisgICAgICAgIFBSSVZBVEVfS0VZX1NQRUNfQ0xBU1NFUy5wdXQoIkRTQSIsIERTQVByaXZhdGVLZXlTcGVjLmNsYXNzKTsKKyAgICAgICAgUFVCTElDX0tFWV9TUEVDX0NMQVNTRVMucHV0KCJEU0EiLCBEU0FQdWJsaWNLZXlTcGVjLmNsYXNzKTsKKyAgICAgICAgTUlOSU1VTV9LRVlfU0laRS5wdXQoIkRTQSIsIDUxMik7CisgICAgICAgIFBSSVZBVEVfS0VZX1NQRUNfQ0xBU1NFUy5wdXQoIkRIIiwgREhQcml2YXRlS2V5U3BlYy5jbGFzcyk7CisgICAgICAgIFBVQkxJQ19LRVlfU1BFQ19DTEFTU0VTLnB1dCgiREgiLCBESFB1YmxpY0tleVNwZWMuY2xhc3MpOworICAgICAgICBNSU5JTVVNX0tFWV9TSVpFLnB1dCgiREgiLCAyNTYpOworICAgICAgICBQUklWQVRFX0tFWV9TUEVDX0NMQVNTRVMucHV0KCJFQyIsIEVDUHJpdmF0ZUtleVNwZWMuY2xhc3MpOworICAgICAgICBQVUJMSUNfS0VZX1NQRUNfQ0xBU1NFUy5wdXQoIkVDIiwgRUNQdWJsaWNLZXlTcGVjLmNsYXNzKTsKKyAgICAgICAgTUlOSU1VTV9LRVlfU0laRS5wdXQoIkVDIiwgMjU2KTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIENsYXNzPD8gZXh0ZW5kcyBLZXlTcGVjPiBnZXRQcml2YXRlS2V5U3BlY0NsYXNzKFN0cmluZyBhbGdOYW1lKSB7CisgICAgICAgIHJldHVybiBQUklWQVRFX0tFWV9TUEVDX0NMQVNTRVMuZ2V0KGFsZ05hbWUpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgQ2xhc3M8PyBleHRlbmRzIEtleVNwZWM+IGdldFB1YmxpY0tleVNwZWNDbGFzcyhTdHJpbmcgYWxnTmFtZSkgeworICAgICAgICByZXR1cm4gUFVCTElDX0tFWV9TUEVDX0NMQVNTRVMuZ2V0KGFsZ05hbWUpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldE1pbmltdW1LZXlTaXplKFN0cmluZyBhbGdOYW1lKSB7CisgICAgICAgIHJldHVybiBNSU5JTVVNX0tFWV9TSVpFLmdldChhbGdOYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBc3NlcnRzIHRoYXQgdGhlIGNpcGhlciBzdWl0ZXMgYXJyYXkgaXMgbm9uLW51bGwgYW5kIHRoYXQgaXQKKyAgICAgKiBhbGwgb2YgaXRzIGNvbnRlbnRzIGFyZSBjaXBoZXIgc3VpdGVzIGtub3duIHRvIHRoaXMKKyAgICAgKiBpbXBsZW1lbnRhdGlvbi4gQXMgYSBjb252ZW5pZW5jZSwgcmV0dXJucyBhbnkgdW5lbmFibGVkIGNpcGhlcgorICAgICAqIHN1aXRlcyBpbiBhIHRlc3QgZm9yIHRob3NlIHRoYXQgd2FudCB0byB2ZXJpZnkgc2VwYXJhdGVseSB0aGF0CisgICAgICogYWxsIGNpcGhlciBzdWl0ZXMgd2VyZSBpbmNsdWRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNldDxTdHJpbmc+IGFzc2VydFZhbGlkQ2lwaGVyU3VpdGVzKFNldDxTdHJpbmc+IGV4cGVjdGVkLCBTdHJpbmdbXSBjaXBoZXJTdWl0ZXMpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChjaXBoZXJTdWl0ZXMpOworICAgICAgICBhc3NlcnRUcnVlKGNpcGhlclN1aXRlcy5sZW5ndGggIT0gMCk7CisKKyAgICAgICAgLy8gTWFrZSBzdXJlIGFsbCBjaXBoZXJTdWl0ZXMgbmFtZXMgYXJlIGV4cGVjdGVkCisgICAgICAgIFNldCByZW1haW5pbmdDaXBoZXJTdWl0ZXMgPSBuZXcgSGFzaFNldDxTdHJpbmc+KGV4cGVjdGVkKTsKKyAgICAgICAgU2V0IHVua25vd25DaXBoZXJTdWl0ZXMgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7CisgICAgICAgIGZvciAoU3RyaW5nIGNpcGhlclN1aXRlIDogY2lwaGVyU3VpdGVzKSB7CisgICAgICAgICAgICBib29sZWFuIHJlbW92ZWQgPSByZW1haW5pbmdDaXBoZXJTdWl0ZXMucmVtb3ZlKGNpcGhlclN1aXRlKTsKKyAgICAgICAgICAgIGlmICghcmVtb3ZlZCkgeworICAgICAgICAgICAgICAgIHVua25vd25DaXBoZXJTdWl0ZXMuYWRkKGNpcGhlclN1aXRlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIlVua25vd24gY2lwaGVyIHN1aXRlcyIsIENvbGxlY3Rpb25zLkVNUFRZX1NFVCwgdW5rbm93bkNpcGhlclN1aXRlcyk7CisgICAgICAgIHJldHVybiByZW1haW5pbmdDaXBoZXJTdWl0ZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWZ0ZXIgdXNpbmcgYXNzZXJ0VmFsaWRDaXBoZXJTdWl0ZXMgb24gY2lwaGVyU3VpdGVzLAorICAgICAqIGFzc2VydFN1cHBvcnRlZENpcGhlclN1aXRlcyBhZGRpdGlvbmFsbHkgdmVyaWZpZXMgdGhhdCBhbGwKKyAgICAgKiBzdXBwb3J0ZWQgY2lwaGVyIHN1aXRlcyB3aGVyZSBpbiB0aGUgaW5wdXQgYXJyYXkuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydFN1cHBvcnRlZENpcGhlclN1aXRlcyhTZXQ8U3RyaW5nPiBleHBlY3RlZCwgU3RyaW5nW10gY2lwaGVyU3VpdGVzKSB7CisgICAgICAgIFNldDxTdHJpbmc+IHJlbWFpbmluZ0NpcGhlclN1aXRlcyA9IGFzc2VydFZhbGlkQ2lwaGVyU3VpdGVzKGV4cGVjdGVkLCBjaXBoZXJTdWl0ZXMpOworICAgICAgICBhc3NlcnRFcXVhbHMoIk1pc3NpbmcgY2lwaGVyIHN1aXRlcyIsIENvbGxlY3Rpb25zLkVNUFRZX1NFVCwgcmVtYWluaW5nQ2lwaGVyU3VpdGVzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLnNpemUoKSwgY2lwaGVyU3VpdGVzLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXNzZXJ0cyB0aGF0IHRoZSBwcm90b2NvbHMgYXJyYXkgaXMgbm9uLW51bGwgYW5kIHRoYXQgaXQgYWxsIG9mCisgICAgICogaXRzIGNvbnRlbnRzIGFyZSBwcm90b2NvbHMga25vd24gdG8gdGhpcyBpbXBsZW1lbnRhdGlvbi4gQXMgYQorICAgICAqIGNvbnZlbmllbmNlLCByZXR1cm5zIGFueSB1bmVuYWJsZWQgcHJvdG9jb2xzIGluIGEgdGVzdCBmb3IKKyAgICAgKiB0aG9zZSB0aGF0IHdhbnQgdG8gdmVyaWZ5IHNlcGFyYXRlbHkgdGhhdCBhbGwgcHJvdG9jb2xzIHdlcmUKKyAgICAgKiBpbmNsdWRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNldDxTdHJpbmc+IGFzc2VydFZhbGlkUHJvdG9jb2xzKFNldDxTdHJpbmc+IGV4cGVjdGVkLCBTdHJpbmdbXSBwcm90b2NvbHMpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChwcm90b2NvbHMpOworICAgICAgICBhc3NlcnRUcnVlKHByb3RvY29scy5sZW5ndGggIT0gMCk7CisKKyAgICAgICAgLy8gTWFrZSBzdXJlIGFsbCBwcm90b2NvbHMgbmFtZXMgYXJlIGV4cGVjdGVkCisgICAgICAgIFNldCByZW1haW5pbmdQcm90b2NvbHMgPSBuZXcgSGFzaFNldDxTdHJpbmc+KFN0YW5kYXJkTmFtZXMuU1NMX1NPQ0tFVF9QUk9UT0NPTFMpOworICAgICAgICBTZXQgdW5rbm93blByb3RvY29scyA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKyAgICAgICAgZm9yIChTdHJpbmcgcHJvdG9jb2wgOiBwcm90b2NvbHMpIHsKKyAgICAgICAgICAgIGlmICghcmVtYWluaW5nUHJvdG9jb2xzLnJlbW92ZShwcm90b2NvbCkpIHsKKyAgICAgICAgICAgICAgICB1bmtub3duUHJvdG9jb2xzLmFkZChwcm90b2NvbCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJVbmtub3duIHByb3RvY29scyIsIENvbGxlY3Rpb25zLkVNUFRZX1NFVCwgdW5rbm93blByb3RvY29scyk7CisgICAgICAgIHJldHVybiByZW1haW5pbmdQcm90b2NvbHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWZ0ZXIgdXNpbmcgYXNzZXJ0VmFsaWRQcm90b2NvbHMgb24gcHJvdG9jb2xzLAorICAgICAqIGFzc2VydFN1cHBvcnRlZFByb3RvY29scyBhZGRpdGlvbmFsbHkgdmVyaWZpZXMgdGhhdCBhbGwKKyAgICAgKiBzdXBwb3J0ZWQgcHJvdG9jb2xzIHdoZXJlIGluIHRoZSBpbnB1dCBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYXNzZXJ0U3VwcG9ydGVkUHJvdG9jb2xzKFNldDxTdHJpbmc+IGV4cGVjdGVkLCBTdHJpbmdbXSBwcm90b2NvbHMpIHsKKyAgICAgICAgU2V0PFN0cmluZz4gcmVtYWluaW5nUHJvdG9jb2xzID0gYXNzZXJ0VmFsaWRQcm90b2NvbHMoZXhwZWN0ZWQsIHByb3RvY29scyk7CisgICAgICAgIGFzc2VydEVxdWFscygiTWlzc2luZyBwcm90b2NvbHMiLCBDb2xsZWN0aW9ucy5FTVBUWV9TRVQsIHJlbWFpbmluZ1Byb3RvY29scyk7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZC5zaXplKCksIHByb3RvY29scy5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFzc2VydCBjaXBoZXIgc3VpdGVzIG1hdGNoIHRoZSBkZWZhdWx0IGxpc3QgaW4gY29udGVudCBhbmQgcHJpb3JpdHkgb3JkZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydERlZmF1bHRDaXBoZXJTdWl0ZXMoU3RyaW5nW10gY2lwaGVyU3VpdGVzKSB7CisgICAgICAgIGFzc2VydFZhbGlkQ2lwaGVyU3VpdGVzKENJUEhFUl9TVUlURVMsIGNpcGhlclN1aXRlcyk7CisgICAgICAgIGFzc2VydEVxdWFscyhDSVBIRVJfU1VJVEVTX0RFRkFVTFQsIEFycmF5cy5hc0xpc3QoY2lwaGVyU3VpdGVzKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YS9zZWN1cml0eS9UZXN0S2V5U3RvcmUuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvVGVzdEtleVN0b3JlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzBlNDBmYgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmEvc2VjdXJpdHkvVGVzdEtleVN0b3JlLmphdmEKQEAgLTAsMCArMSw4NzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YS5zZWN1cml0eTsKKworaW1wb3J0IGNvbS5hbmRyb2lkLm9yZy5ib3VuY3ljYXN0bGUuYXNuMS5ERVJPY3RldFN0cmluZzsKK2ltcG9ydCBjb20uYW5kcm9pZC5vcmcuYm91bmN5Y2FzdGxlLmFzbjEueDUwOS5CYXNpY0NvbnN0cmFpbnRzOworaW1wb3J0IGNvbS5hbmRyb2lkLm9yZy5ib3VuY3ljYXN0bGUuYXNuMS54NTA5LkdlbmVyYWxOYW1lOworaW1wb3J0IGNvbS5hbmRyb2lkLm9yZy5ib3VuY3ljYXN0bGUuYXNuMS54NTA5LkdlbmVyYWxOYW1lczsKK2ltcG9ydCBjb20uYW5kcm9pZC5vcmcuYm91bmN5Y2FzdGxlLmFzbjEueDUwOS5HZW5lcmFsU3VidHJlZTsKK2ltcG9ydCBjb20uYW5kcm9pZC5vcmcuYm91bmN5Y2FzdGxlLmFzbjEueDUwOS5LZXlVc2FnZTsKK2ltcG9ydCBjb20uYW5kcm9pZC5vcmcuYm91bmN5Y2FzdGxlLmFzbjEueDUwOS5OYW1lQ29uc3RyYWludHM7CitpbXBvcnQgY29tLmFuZHJvaWQub3JnLmJvdW5jeWNhc3RsZS5hc24xLng1MDkuWDUwOUV4dGVuc2lvbnM7CitpbXBvcnQgY29tLmFuZHJvaWQub3JnLmJvdW5jeWNhc3RsZS5qY2UucHJvdmlkZXIuQm91bmN5Q2FzdGxlUHJvdmlkZXI7CitpbXBvcnQgY29tLmFuZHJvaWQub3JnLmJvdW5jeWNhc3RsZS54NTA5Llg1MDlWM0NlcnRpZmljYXRlR2VuZXJhdG9yOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QcmludFN0cmVhbTsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmUuUGFzc3dvcmRQcm90ZWN0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmUuUHJpdmF0ZUtleUVudHJ5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmUuVHJ1c3RlZENlcnRpZmljYXRlRW50cnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuRUNQcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5QS0NTOEVuY29kZWRLZXlTcGVjOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CitpbXBvcnQgamF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlckZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXJGYWN0b3J5OworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC5YNTAwUHJpbmNpcGFsOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5Bc3NlcnQ7CitpbXBvcnQgbGliY29yZS5qYXZheC5uZXQuc3NsLlRlc3RLZXlNYW5hZ2VyOworaW1wb3J0IGxpYmNvcmUuamF2YXgubmV0LnNzbC5UZXN0VHJ1c3RNYW5hZ2VyOworCisvKioKKyAqIFRlc3RLZXlTdG9yZSBpcyBhIGNvbnZlbmllbmNlIGNsYXNzIGZvciBvdGhlciB0ZXN0cyB0aGF0CisgKiB3YW50IGEgY2FubmVkIEtleVN0b3JlIHdpdGggYSB2YXJpZXR5IG9mIGtleSBwYWlycy4KKyAqCisgKiBDcmVhdGluZyBhIGtleSBzdG9yZSBpcyByZWxhdGl2ZWx5IHNsb3csIHNvIGEgc2luZ2xldG9uIGluc3RhbmNlIGlzCisgKiBhY2Nlc3NpYmxlIHZpYSBUZXN0S2V5U3RvcmUuZ2V0KCkuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBUZXN0S2V5U3RvcmUgZXh0ZW5kcyBBc3NlcnQgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgVGVzdEtleVN0b3JlIFJPT1RfQ0E7CisKKyAgICBwcml2YXRlIHN0YXRpYyBUZXN0S2V5U3RvcmUgU0VSVkVSOworICAgIHByaXZhdGUgc3RhdGljIFRlc3RLZXlTdG9yZSBDTElFTlQ7CisgICAgcHJpdmF0ZSBzdGF0aWMgVGVzdEtleVN0b3JlIENMSUVOVF9DRVJUSUZJQ0FURTsKKworICAgIHByaXZhdGUgc3RhdGljIFRlc3RLZXlTdG9yZSBDTElFTlRfMjsKKworICAgIHN0YXRpYyB7CisgICAgICAgIGlmIChTdGFuZGFyZE5hbWVzLklTX1JJKSB7CisgICAgICAgICAgICAvLyBOZWVkZWQgdG8gY3JlYXRlIEJLUyBrZXlzdG9yZSBidXQgYWRkIGF0IGVuZCBzbyBtb3N0CisgICAgICAgICAgICAvLyBhbGdvcml0aG0gY29tZSBmcm9tIHRoZSBkZWZhdWx0IHByb3ZpZGVycworICAgICAgICAgICAgU2VjdXJpdHkuaW5zZXJ0UHJvdmlkZXJBdChuZXcgQm91bmN5Q2FzdGxlUHJvdmlkZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VjdXJpdHkuZ2V0UHJvdmlkZXJzKCkubGVuZ3RoKzEpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBURVNUX01BTkFHRVJTID0gdHJ1ZTsKKworICAgIHB1YmxpYyBmaW5hbCBLZXlTdG9yZSBrZXlTdG9yZTsKKyAgICBwdWJsaWMgZmluYWwgY2hhcltdIHN0b3JlUGFzc3dvcmQ7CisgICAgcHVibGljIGZpbmFsIGNoYXJbXSBrZXlQYXNzd29yZDsKKyAgICBwdWJsaWMgZmluYWwgS2V5TWFuYWdlcltdIGtleU1hbmFnZXJzOworICAgIHB1YmxpYyBmaW5hbCBUcnVzdE1hbmFnZXJbXSB0cnVzdE1hbmFnZXJzOworICAgIHB1YmxpYyBmaW5hbCBUZXN0S2V5TWFuYWdlciBrZXlNYW5hZ2VyOworICAgIHB1YmxpYyBmaW5hbCBUZXN0VHJ1c3RNYW5hZ2VyIHRydXN0TWFuYWdlcjsKKworICAgIHByaXZhdGUgVGVzdEtleVN0b3JlKEtleVN0b3JlIGtleVN0b3JlLCBjaGFyW10gc3RvcmVQYXNzd29yZCwgY2hhcltdIGtleVBhc3N3b3JkKSB7CisgICAgICAgIHRoaXMua2V5U3RvcmUgPSBrZXlTdG9yZTsKKyAgICAgICAgdGhpcy5zdG9yZVBhc3N3b3JkID0gc3RvcmVQYXNzd29yZDsKKyAgICAgICAgdGhpcy5rZXlQYXNzd29yZCA9IGtleVBhc3N3b3JkOworICAgICAgICB0aGlzLmtleU1hbmFnZXJzID0gY3JlYXRlS2V5TWFuYWdlcnMoa2V5U3RvcmUsIHN0b3JlUGFzc3dvcmQpOworICAgICAgICB0aGlzLnRydXN0TWFuYWdlcnMgPSBjcmVhdGVUcnVzdE1hbmFnZXJzKGtleVN0b3JlKTsKKyAgICAgICAgdGhpcy5rZXlNYW5hZ2VyID0gKFRlc3RLZXlNYW5hZ2VyKWtleU1hbmFnZXJzWzBdOworICAgICAgICB0aGlzLnRydXN0TWFuYWdlciA9IChUZXN0VHJ1c3RNYW5hZ2VyKXRydXN0TWFuYWdlcnNbMF07CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBLZXlNYW5hZ2VyW10gY3JlYXRlS2V5TWFuYWdlcnMoS2V5U3RvcmUga2V5U3RvcmUsIGNoYXJbXSBzdG9yZVBhc3N3b3JkKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcga21mYSA9IEtleU1hbmFnZXJGYWN0b3J5LmdldERlZmF1bHRBbGdvcml0aG0oKTsKKyAgICAgICAgICAgIEtleU1hbmFnZXJGYWN0b3J5IGttZiA9IEtleU1hbmFnZXJGYWN0b3J5LmdldEluc3RhbmNlKGttZmEpOworICAgICAgICAgICAga21mLmluaXQoa2V5U3RvcmUsIHN0b3JlUGFzc3dvcmQpOworICAgICAgICAgICAgcmV0dXJuIFRlc3RLZXlNYW5hZ2VyLndyYXAoa21mLmdldEtleU1hbmFnZXJzKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFRydXN0TWFuYWdlcltdIGNyZWF0ZVRydXN0TWFuYWdlcnMoZmluYWwgS2V5U3RvcmUga2V5U3RvcmUpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyB0bWZhID0gVHJ1c3RNYW5hZ2VyRmFjdG9yeS5nZXREZWZhdWx0QWxnb3JpdGhtKCk7CisgICAgICAgICAgICBUcnVzdE1hbmFnZXJGYWN0b3J5IHRtZiA9IFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UodG1mYSk7CisgICAgICAgICAgICB0bWYuaW5pdChrZXlTdG9yZSk7CisgICAgICAgICAgICByZXR1cm4gVGVzdFRydXN0TWFuYWdlci53cmFwKHRtZi5nZXRUcnVzdE1hbmFnZXJzKCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMYXppbHkgY3JlYXRlIHNoYXJlZCB0ZXN0IGNlcnRpZmljYXRlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBzeW5jaHJvbml6ZWQgdm9pZCBpbml0Q2VydHMoKSB7CisgICAgICAgIGlmIChST09UX0NBICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBST09UX0NBID0gbmV3IEJ1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5hbGlhc1ByZWZpeCgiUm9vdENBIikKKyAgICAgICAgICAgICAgICAuc3ViamVjdCgiQ049VGVzdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSIpCisgICAgICAgICAgICAgICAgLmNhKHRydWUpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgICAgIFRlc3RLZXlTdG9yZSBpbnRlcm1lZGlhdGVDYSA9IG5ldyBCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuYWxpYXNQcmVmaXgoIkludGVybWVkaWF0ZUNBIikKKyAgICAgICAgICAgICAgICAuc3ViamVjdCgiQ049VGVzdCBJbnRlcm1lZGlhdGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IikKKyAgICAgICAgICAgICAgICAuY2EodHJ1ZSkKKyAgICAgICAgICAgICAgICAuc2lnbmVyKFJPT1RfQ0EuZ2V0UHJpdmF0ZUtleSgiUlNBIiwgIlJTQSIpKQorICAgICAgICAgICAgICAgIC5yb290Q2EoUk9PVF9DQS5nZXRSb290Q2VydGlmaWNhdGUoIlJTQSIpKQorICAgICAgICAgICAgICAgIC5idWlsZCgpOworICAgICAgICBTRVJWRVIgPSBuZXcgQnVpbGRlcigpCisgICAgICAgICAgICAgICAgLmFsaWFzUHJlZml4KCJzZXJ2ZXIiKQorICAgICAgICAgICAgICAgIC5zaWduZXIoaW50ZXJtZWRpYXRlQ2EuZ2V0UHJpdmF0ZUtleSgiUlNBIiwgIlJTQSIpKQorICAgICAgICAgICAgICAgIC5yb290Q2EoaW50ZXJtZWRpYXRlQ2EuZ2V0Um9vdENlcnRpZmljYXRlKCJSU0EiKSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICAgICAgQ0xJRU5UID0gbmV3IFRlc3RLZXlTdG9yZShjcmVhdGVDbGllbnQoaW50ZXJtZWRpYXRlQ2Eua2V5U3RvcmUpLCBudWxsLCBudWxsKTsKKyAgICAgICAgQ0xJRU5UX0NFUlRJRklDQVRFID0gbmV3IEJ1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5hbGlhc1ByZWZpeCgiY2xpZW50IikKKyAgICAgICAgICAgICAgICAuc3ViamVjdCgiZW1haWxBZGRyZXNzPXRlc3RAdXNlciIpCisgICAgICAgICAgICAgICAgLnNpZ25lcihpbnRlcm1lZGlhdGVDYS5nZXRQcml2YXRlS2V5KCJSU0EiLCAiUlNBIikpCisgICAgICAgICAgICAgICAgLnJvb3RDYShpbnRlcm1lZGlhdGVDYS5nZXRSb290Q2VydGlmaWNhdGUoIlJTQSIpKQorICAgICAgICAgICAgICAgIC5idWlsZCgpOworICAgICAgICBUZXN0S2V5U3RvcmUgcm9vdENhMiA9IG5ldyBCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuYWxpYXNQcmVmaXgoIlJvb3RDQTIiKQorICAgICAgICAgICAgICAgIC5zdWJqZWN0KCJDTj1UZXN0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIiKQorICAgICAgICAgICAgICAgIC5jYSh0cnVlKQorICAgICAgICAgICAgICAgIC5idWlsZCgpOworICAgICAgICBDTElFTlRfMiA9IG5ldyBUZXN0S2V5U3RvcmUoY3JlYXRlQ2xpZW50KHJvb3RDYTIua2V5U3RvcmUpLCBudWxsLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBzZXJ2ZXIga2V5c3RvcmUgd2l0aCBhIG1hdGNoZWQgUlNBIGNlcnRpZmljYXRlIGFuZAorICAgICAqIHByaXZhdGUga2V5IGFzIHdlbGwgYXMgYSBDQSBjZXJ0aWZpY2F0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFRlc3RLZXlTdG9yZSBnZXRTZXJ2ZXIoKSB7CisgICAgICAgIGluaXRDZXJ0cygpOworICAgICAgICByZXR1cm4gU0VSVkVSOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIGtleXN0b3JlIHdpdGggYSBDQSBjZXJ0aWZpY2F0ZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVGVzdEtleVN0b3JlIGdldENsaWVudCgpIHsKKyAgICAgICAgaW5pdENlcnRzKCk7CisgICAgICAgIHJldHVybiBDTElFTlQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGEgY2xpZW50IGtleXN0b3JlIHdpdGggYSBtYXRjaGVkIFJTQSBjZXJ0aWZpY2F0ZSBhbmQKKyAgICAgKiBwcml2YXRlIGtleSBhcyB3ZWxsIGFzIGEgQ0EgY2VydGlmaWNhdGUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBUZXN0S2V5U3RvcmUgZ2V0Q2xpZW50Q2VydGlmaWNhdGUoKSB7CisgICAgICAgIGluaXRDZXJ0cygpOworICAgICAgICByZXR1cm4gQ0xJRU5UX0NFUlRJRklDQVRFOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIGtleXN0b3JlIHdpdGggYSBzZWNvbmQgQ0EgY2VydGlmaWNhdGUgdGhhdCBkb2VzIG5vdAorICAgICAqIHRydXN0IHRoZSBzZXJ2ZXIgY2VydGlmaWNhdGUgcmV0dXJuZWQgYnkgZ2V0U2VydmVyIGZvciBuZWdhdGl2ZQorICAgICAqIHRlc3RpbmcuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBUZXN0S2V5U3RvcmUgZ2V0Q2xpZW50Q0EyKCkgeworICAgICAgICBpbml0Q2VydHMoKTsKKyAgICAgICAgcmV0dXJuIENMSUVOVF8yOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgS2V5U3RvcmVzIGNvbnRhaW5pbmcgdGhlIHJlcXVlc3RlZCBrZXkgdHlwZXMuIFNpbmNlIGtleQorICAgICAqIGdlbmVyYXRpb24gY2FuIGJlIGV4cGVuc2l2ZSwgbW9zdCB0ZXN0cyBzaG91bGQgcmV1c2UgdGhlIFJTQS1vbmx5CisgICAgICogc2luZ2xldG9uIGluc3RhbmNlIHJldHVybmVkIGJ5IFRlc3RLZXlTdG9yZS5nZXQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBCdWlsZGVyIHsKKyAgICAgICAgcHJpdmF0ZSBTdHJpbmdbXSBrZXlBbGdvcml0aG1zID0geyAiUlNBIiB9OworICAgICAgICBwcml2YXRlIGNoYXJbXSBzdG9yZVBhc3N3b3JkOworICAgICAgICBwcml2YXRlIGNoYXJbXSBrZXlQYXNzd29yZDsKKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgYWxpYXNQcmVmaXg7CisgICAgICAgIHByaXZhdGUgWDUwMFByaW5jaXBhbCBzdWJqZWN0OworICAgICAgICBwcml2YXRlIGludCBrZXlVc2FnZTsKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGNhOworICAgICAgICBwcml2YXRlIFByaXZhdGVLZXlFbnRyeSBzaWduZXI7CisgICAgICAgIHByaXZhdGUgQ2VydGlmaWNhdGUgcm9vdENhOworICAgICAgICBwcml2YXRlIGZpbmFsIExpc3Q8R2VuZXJhbE5hbWU+IHN1YmplY3RBbHROYW1lcyA9IG5ldyBBcnJheUxpc3Q8R2VuZXJhbE5hbWU+KCk7CisgICAgICAgIHByaXZhdGUgZmluYWwgVmVjdG9yPEdlbmVyYWxTdWJ0cmVlPiBwZXJtaXR0ZWROYW1lQ29uc3RyYWludHMKKyAgICAgICAgICAgICAgICA9IG5ldyBWZWN0b3I8R2VuZXJhbFN1YnRyZWU+KCk7CisgICAgICAgIHByaXZhdGUgZmluYWwgVmVjdG9yPEdlbmVyYWxTdWJ0cmVlPiBleGNsdWRlZE5hbWVDb25zdHJhaW50cyA9IG5ldyBWZWN0b3I8R2VuZXJhbFN1YnRyZWU+KCk7CisKKyAgICAgICAgcHVibGljIEJ1aWxkZXIoKSB7CisgICAgICAgICAgICBzdWJqZWN0ID0gbG9jYWxob3N0KCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogU2V0cyB0aGUgcmVxdWVzdGVkIGtleSB0eXBlcyB0byBnZW5lcmF0ZSBhbmQgaW5jbHVkZS4gVGhlIGRlZmF1bHQgaXMKKyAgICAgICAgICogUlNBIG9ubHkuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQnVpbGRlciBrZXlBbGdvcml0aG1zKFN0cmluZy4uLiBrZXlBbGdvcml0aG1zKSB7CisgICAgICAgICAgICB0aGlzLmtleUFsZ29yaXRobXMgPSBrZXlBbGdvcml0aG1zOworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKworICAgICAgICAvKiogQSB1bmlxdWUgcHJlZml4IHRvIGlkZW50aWZ5IHRoZSBrZXkgYWxpYXNlcyAqLworICAgICAgICBwdWJsaWMgQnVpbGRlciBhbGlhc1ByZWZpeChTdHJpbmcgYWxpYXNQcmVmaXgpIHsKKyAgICAgICAgICAgIHRoaXMuYWxpYXNQcmVmaXggPSBhbGlhc1ByZWZpeDsKKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNldHMgdGhlIHN1YmplY3QgY29tbW9uIG5hbWUuIFRoZSBkZWZhdWx0IGlzIHRoZSBsb2NhbCBob3N0J3MKKyAgICAgICAgICogY2Fub25pY2FsIG5hbWUuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQnVpbGRlciBzdWJqZWN0KFg1MDBQcmluY2lwYWwgc3ViamVjdCkgeworICAgICAgICAgICAgdGhpcy5zdWJqZWN0ID0gc3ViamVjdDsKKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIEJ1aWxkZXIgc3ViamVjdChTdHJpbmcgY29tbW9uTmFtZSkgeworICAgICAgICAgICAgcmV0dXJuIHN1YmplY3QobmV3IFg1MDBQcmluY2lwYWwoY29tbW9uTmFtZSkpOworICAgICAgICB9CisKKyAgICAgICAgLyoqIHtAbGluayBLZXlVc2FnZX0gYml0IG1hc2sgZm9yIDIuNS4yOS4xNSBleHRlbnNpb24gKi8KKyAgICAgICAgcHVibGljIEJ1aWxkZXIga2V5VXNhZ2UoaW50IGtleVVzYWdlKSB7CisgICAgICAgICAgICB0aGlzLmtleVVzYWdlID0ga2V5VXNhZ2U7CisgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgfQorCisgICAgICAgIC8qKiB0cnVlIElmIHRoZSBrZXlzIGJlaW5nIGNyZWF0ZWQgYXJlIGZvciBhIENBICovCisgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNhKGJvb2xlYW4gY2EpIHsKKyAgICAgICAgICAgIHRoaXMuY2EgPSBjYTsKKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICB9CisKKyAgICAgICAgLyoqIGEgcHJpdmF0ZSBrZXkgZW50cnkgdG8gYmUgdXNlZCBmb3Igc2lnbmluZywgb3RoZXJ3aXNlIHNlbGYtc2lnbiAqLworICAgICAgICBwdWJsaWMgQnVpbGRlciBzaWduZXIoUHJpdmF0ZUtleUVudHJ5IHNpZ25lcikgeworICAgICAgICAgICAgdGhpcy5zaWduZXIgPSBzaWduZXI7CisgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgfQorCisgICAgICAgIC8qKiBhIHJvb3QgQ0EgdG8gaW5jbHVkZSBpbiB0aGUgZmluYWwgc3RvcmUgKi8KKyAgICAgICAgcHVibGljIEJ1aWxkZXIgcm9vdENhKENlcnRpZmljYXRlIHJvb3RDYSkgeworICAgICAgICAgICAgdGhpcy5yb290Q2EgPSByb290Q2E7CisgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgQnVpbGRlciBhZGRTdWJqZWN0QWx0TmFtZShHZW5lcmFsTmFtZSBnZW5lcmFsTmFtZSkgeworICAgICAgICAgICAgc3ViamVjdEFsdE5hbWVzLmFkZChnZW5lcmFsTmFtZSk7CisgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFN1YmplY3RBbHROYW1lSXBBZGRyZXNzKGJ5dGVbXSBpcEFkZHJlc3MpIHsKKyAgICAgICAgICAgIHJldHVybiBhZGRTdWJqZWN0QWx0TmFtZSgKKyAgICAgICAgICAgICAgICAgICAgbmV3IEdlbmVyYWxOYW1lKEdlbmVyYWxOYW1lLmlQQWRkcmVzcywgbmV3IERFUk9jdGV0U3RyaW5nKGlwQWRkcmVzcykpKTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgQnVpbGRlciBhZGROYW1lQ29uc3RyYWludChib29sZWFuIHBlcm1pdHRlZCwgR2VuZXJhbE5hbWUgZ2VuZXJhbE5hbWUpIHsKKyAgICAgICAgICAgIGlmIChwZXJtaXR0ZWQpIHsKKyAgICAgICAgICAgICAgICBwZXJtaXR0ZWROYW1lQ29uc3RyYWludHMuYWRkKG5ldyBHZW5lcmFsU3VidHJlZShnZW5lcmFsTmFtZSkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBleGNsdWRlZE5hbWVDb25zdHJhaW50cy5hZGQobmV3IEdlbmVyYWxTdWJ0cmVlKGdlbmVyYWxOYW1lKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZE5hbWVDb25zdHJhaW50KGJvb2xlYW4gcGVybWl0dGVkLCBieXRlW10gaXBBZGRyZXNzKSB7CisgICAgICAgICAgICByZXR1cm4gYWRkTmFtZUNvbnN0cmFpbnQocGVybWl0dGVkLAorICAgICAgICAgICAgICAgICAgICBuZXcgR2VuZXJhbE5hbWUoR2VuZXJhbE5hbWUuaVBBZGRyZXNzLCBuZXcgREVST2N0ZXRTdHJpbmcoaXBBZGRyZXNzKSkpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFRlc3RLZXlTdG9yZSBidWlsZCgpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKFN0YW5kYXJkTmFtZXMuSVNfUkkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gSktTIGRvZXMgbm90IGFsbG93IG51bGwgcGFzc3dvcmQKKyAgICAgICAgICAgICAgICAgICAgaWYgKHN0b3JlUGFzc3dvcmQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmVQYXNzd29yZCA9ICJwYXNzd29yZCIudG9DaGFyQXJyYXkoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoa2V5UGFzc3dvcmQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAga2V5UGFzc3dvcmQgPSAicGFzc3dvcmQiLnRvQ2hhckFycmF5KCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBLZXlTdG9yZSBrZXlTdG9yZSA9IGNyZWF0ZUtleVN0b3JlKCk7CisgICAgICAgICAgICAgICAgZm9yIChTdHJpbmcga2V5QWxnb3JpdGhtIDoga2V5QWxnb3JpdGhtcykgeworICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHVibGljQWxpYXMgID0gYWxpYXNQcmVmaXggKyAiLXB1YmxpYy0iICArIGtleUFsZ29yaXRobTsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHByaXZhdGVBbGlhcyA9IGFsaWFzUHJlZml4ICsgIi1wcml2YXRlLSIgKyBrZXlBbGdvcml0aG07CisgICAgICAgICAgICAgICAgICAgIGlmIChrZXlBbGdvcml0aG0uZXF1YWxzKCJFQ19SU0EiKSAmJiBzaWduZXIgPT0gbnVsbCAmJiByb290Q2EgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlS2V5cyhrZXlTdG9yZSwga2V5QWxnb3JpdGhtLCBwdWJsaWNBbGlhcywgcHJpdmF0ZUFsaWFzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlS2V5KGtleVN0b3JlLCBrZXlQYXNzd29yZCwgIlJTQSIsICJSU0EiKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBjcmVhdGVLZXlzKGtleVN0b3JlLCBrZXlBbGdvcml0aG0sIHB1YmxpY0FsaWFzLCBwcml2YXRlQWxpYXMsIHNpZ25lcik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChyb290Q2EgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBrZXlTdG9yZS5zZXRDZXJ0aWZpY2F0ZUVudHJ5KGFsaWFzUHJlZml4CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiLXJvb3QtY2EtIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgcm9vdENhLmdldFB1YmxpY0tleSgpLmdldEFsZ29yaXRobSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvb3RDYSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVGVzdEtleVN0b3JlKGtleVN0b3JlLCBzdG9yZVBhc3N3b3JkLCBrZXlQYXNzd29yZCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEFkZCBuZXdseSBnZW5lcmF0ZWQga2V5cyBvZiBhIGdpdmVuIGtleSB0eXBlIHRvIGFuIGV4aXN0aW5nCisgICAgICAgICAqIEtleVN0b3JlLiBUaGUgUHJpdmF0ZUtleSB3aWxsIGJlIHN0b3JlZCB1bmRlciB0aGUgc3BlY2lmaWVkCisgICAgICAgICAqIHByaXZhdGUgYWxpYXMgbmFtZS4gVGhlIFg1MDlDZXJ0aWZpY2F0ZSB3aWxsIGJlIHN0b3JlZCBvbiB0aGUKKyAgICAgICAgICogcHVibGljIGFsaWFzIG5hbWUgYW5kIGhhdmUgdGhlIGdpdmVuIHN1YmplY3QgZGlzdGluZ3Vpc2hlZAorICAgICAgICAgKiBuYW1lLgorICAgICAgICAgKgorICAgICAgICAgKiBJZiBhIENBIGlzIHByb3ZpZGVkLCBpdCB3aWxsIGJlIHVzZWQgdG8gc2lnbiB0aGUgZ2VuZXJhdGVkCisgICAgICAgICAqIGNlcnRpZmljYXRlLiBPdGhlcndpc2UsIHRoZSBjZXJ0aWZpY2F0ZSB3aWxsIGJlIHNlbGYKKyAgICAgICAgICogc2lnbmVkLiBUaGUgY2VydGlmaWNhdGUgd2lsbCBiZSB2YWxpZCBmb3Igb25lIGRheSBiZWZvcmUgYW5kCisgICAgICAgICAqIG9uZSBkYXkgYWZ0ZXIgdGhlIHRpbWUgb2YgY3JlYXRpb24uCisgICAgICAgICAqCisgICAgICAgICAqIEJhc2VkIG9uOgorICAgICAgICAgKiBvcmcuYm91bmN5Y2FzdGxlLmpjZS5wcm92aWRlci50ZXN0LlNpZ1Rlc3QKKyAgICAgICAgICogb3JnLmJvdW5jeWNhc3RsZS5qY2UucHJvdmlkZXIudGVzdC5DZXJ0VGVzdAorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBLZXlTdG9yZSBjcmVhdGVLZXlzKEtleVN0b3JlIGtleVN0b3JlLAorICAgICAgICAgICAgICAgIFN0cmluZyBrZXlBbGdvcml0aG0sCisgICAgICAgICAgICAgICAgU3RyaW5nIHB1YmxpY0FsaWFzLAorICAgICAgICAgICAgICAgIFN0cmluZyBwcml2YXRlQWxpYXMsCisgICAgICAgICAgICAgICAgUHJpdmF0ZUtleUVudHJ5IHNpZ25lcikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBQcml2YXRlS2V5IGNhS2V5OworICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlIGNhQ2VydDsKKyAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIGNhQ2VydENoYWluOworICAgICAgICAgICAgaWYgKHNpZ25lciA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY2FLZXkgPSBudWxsOworICAgICAgICAgICAgICAgIGNhQ2VydCA9IG51bGw7CisgICAgICAgICAgICAgICAgY2FDZXJ0Q2hhaW4gPSBudWxsOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBjYUtleSA9IHNpZ25lci5nZXRQcml2YXRlS2V5KCk7CisgICAgICAgICAgICAgICAgY2FDZXJ0ID0gKFg1MDlDZXJ0aWZpY2F0ZSlzaWduZXIuZ2V0Q2VydGlmaWNhdGUoKTsKKyAgICAgICAgICAgICAgICBjYUNlcnRDaGFpbiA9IChYNTA5Q2VydGlmaWNhdGVbXSlzaWduZXIuZ2V0Q2VydGlmaWNhdGVDaGFpbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBQcml2YXRlS2V5IHByaXZhdGVLZXk7CisgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGUgeDUwOWM7CisgICAgICAgICAgICBpZiAocHVibGljQWxpYXMgPT0gbnVsbCAmJiBwcml2YXRlQWxpYXMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIGRvbid0IHdhbnQgYW55dGhpbmcgYXBwYXJlbnRseQorICAgICAgICAgICAgICAgIHByaXZhdGVLZXkgPSBudWxsOworICAgICAgICAgICAgICAgIHg1MDljID0gbnVsbDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gMS4pIHdlIG1ha2UgdGhlIGtleXMKKyAgICAgICAgICAgICAgICBpbnQga2V5U2l6ZTsKKyAgICAgICAgICAgICAgICBpZiAoa2V5QWxnb3JpdGhtLmVxdWFscygiUlNBIikpIHsKKyAgICAgICAgICAgICAgICAgICAga2V5U2l6ZSA9IFN0YW5kYXJkTmFtZXMuSVNfUkkgPyAxMDI0IDogNTEyOyAvLyA1MTIgYnJlYWtzIFNTTF9SU0FfRVhQT1JUXyogb24gUkkKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGtleUFsZ29yaXRobS5lcXVhbHMoIkRTQSIpKSB7CisgICAgICAgICAgICAgICAgICAgIGtleVNpemUgPSA1MTI7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChrZXlBbGdvcml0aG0uZXF1YWxzKCJFQyIpKSB7CisgICAgICAgICAgICAgICAgICAgIGtleVNpemUgPSAyNTY7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChrZXlBbGdvcml0aG0uZXF1YWxzKCJFQ19SU0EiKSkgeworICAgICAgICAgICAgICAgICAgICBrZXlTaXplID0gMjU2OworICAgICAgICAgICAgICAgICAgICBrZXlBbGdvcml0aG0gPSAiRUMiOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlVua25vd24ga2V5IGFsZ29yaXRobSAiICsga2V5QWxnb3JpdGhtKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGtwZyA9IEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2Uoa2V5QWxnb3JpdGhtKTsKKyAgICAgICAgICAgICAgICBrcGcuaW5pdGlhbGl6ZShrZXlTaXplLCBuZXcgU2VjdXJlUmFuZG9tKCkpOworCisgICAgICAgICAgICAgICAgS2V5UGFpciBrcCA9IGtwZy5nZW5lcmF0ZUtleVBhaXIoKTsKKyAgICAgICAgICAgICAgICBwcml2YXRlS2V5ID0ga3AuZ2V0UHJpdmF0ZSgpOworICAgICAgICAgICAgICAgIFB1YmxpY0tleSBwdWJsaWNLZXkgID0ga3AuZ2V0UHVibGljKCk7CisKKyAgICAgICAgICAgICAgICAvLyAyLikgdXNlIGtleXMgdG8gbWFrZSBjZXJ0aWZpY2F0ZQorICAgICAgICAgICAgICAgIFg1MDBQcmluY2lwYWwgaXNzdWVyID0gKChjYUNlcnQgIT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGNhQ2VydC5nZXRTdWJqZWN0WDUwMFByaW5jaXBhbCgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBzdWJqZWN0KTsKKyAgICAgICAgICAgICAgICBQcml2YXRlS2V5IHNpZ25pbmdLZXkgPSAoY2FLZXkgPT0gbnVsbCkgPyBwcml2YXRlS2V5IDogY2FLZXk7CisgICAgICAgICAgICAgICAgeDUwOWMgPSBjcmVhdGVDZXJ0aWZpY2F0ZShwdWJsaWNLZXksIHNpZ25pbmdLZXksIHN1YmplY3QsIGlzc3Vlciwga2V5VXNhZ2UsIGNhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViamVjdEFsdE5hbWVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVybWl0dGVkTmFtZUNvbnN0cmFpbnRzLCBleGNsdWRlZE5hbWVDb25zdHJhaW50cyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIHg1MDljYzsKKyAgICAgICAgICAgIGlmIChwcml2YXRlQWxpYXMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIGRvbid0IG5lZWQgY2VydGlmaWNhdGUgY2hhaW4KKyAgICAgICAgICAgICAgICB4NTA5Y2MgPSBudWxsOworICAgICAgICAgICAgfSBlbHNlIGlmIChjYUNlcnRDaGFpbiA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgeDUwOWNjID0gbmV3IFg1MDlDZXJ0aWZpY2F0ZVtdIHsgeDUwOWMgfTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgeDUwOWNjID0gbmV3IFg1MDlDZXJ0aWZpY2F0ZVtjYUNlcnRDaGFpbi5sZW5ndGgrMV07CisgICAgICAgICAgICAgICAgeDUwOWNjWzBdID0geDUwOWM7CisgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShjYUNlcnRDaGFpbiwgMCwgeDUwOWNjLCAxLCBjYUNlcnRDaGFpbi5sZW5ndGgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyAzLikgcHV0IGNlcnRpZmljYXRlIGFuZCBwcml2YXRlIGtleSBpbnRvIHRoZSBrZXkgc3RvcmUKKyAgICAgICAgICAgIGlmIChwcml2YXRlQWxpYXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLnNldEtleUVudHJ5KHByaXZhdGVBbGlhcywgcHJpdmF0ZUtleSwga2V5UGFzc3dvcmQsIHg1MDljYyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAocHVibGljQWxpYXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGtleVN0b3JlLnNldENlcnRpZmljYXRlRW50cnkocHVibGljQWxpYXMsIHg1MDljKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBrZXlTdG9yZTsKKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgWDUwMFByaW5jaXBhbCBsb2NhbGhvc3QoKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgWDUwMFByaW5jaXBhbCgiQ049IiArIEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLmdldEhvc3ROYW1lKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBYNTA5Q2VydGlmaWNhdGUgY3JlYXRlQ2EoUHVibGljS2V5IHB1YmxpY0tleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcml2YXRlS2V5IHByaXZhdGVLZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN1YmplY3QpICB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBYNTAwUHJpbmNpcGFsIHByaW5jaXBhbCA9IG5ldyBYNTAwUHJpbmNpcGFsKHN1YmplY3QpOworICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUNlcnRpZmljYXRlKHB1YmxpY0tleSwgcHJpdmF0ZUtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmluY2lwYWwsIHByaW5jaXBhbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBWZWN0b3I8R2VuZXJhbE5hbWU+KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFZlY3RvcjxHZW5lcmFsU3VidHJlZT4oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVmVjdG9yPEdlbmVyYWxTdWJ0cmVlPigpKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgWDUwOUNlcnRpZmljYXRlIGNyZWF0ZUNlcnRpZmljYXRlKAorICAgICAgICAgICAgUHVibGljS2V5IHB1YmxpY0tleSwKKyAgICAgICAgICAgIFByaXZhdGVLZXkgcHJpdmF0ZUtleSwKKyAgICAgICAgICAgIFg1MDBQcmluY2lwYWwgc3ViamVjdCwKKyAgICAgICAgICAgIFg1MDBQcmluY2lwYWwgaXNzdWVyLAorICAgICAgICAgICAgaW50IGtleVVzYWdlLAorICAgICAgICAgICAgYm9vbGVhbiBjYSwKKyAgICAgICAgICAgIExpc3Q8R2VuZXJhbE5hbWU+IHN1YmplY3RBbHROYW1lcywKKyAgICAgICAgICAgIFZlY3RvcjxHZW5lcmFsU3VidHJlZT4gcGVybWl0dGVkTmFtZUNvbnN0cmFpbnRzLAorICAgICAgICAgICAgVmVjdG9yPEdlbmVyYWxTdWJ0cmVlPiBleGNsdWRlZE5hbWVDb25zdHJhaW50cykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIE5vdGUgdGhhdCB0aGVyZSBpcyBubyB3YXkgdG8gcHJvZ3JhbW1hdGljYWxseSBtYWtlIGEKKyAgICAgICAgLy8gQ2VydGlmaWNhdGUgdXNpbmcgamF2YS4qIG9yIGphdmF4LiogQVBJcy4gVGhlCisgICAgICAgIC8vIENlcnRpZmljYXRlRmFjdG9yeSBpbnRlcmZhY2UgYXNzdW1lcyB5b3Ugd2FudCB0byByZWFkCisgICAgICAgIC8vIGluIGEgc3RyZWFtIG9mIGJ5dGVzLCB0eXBpY2FsbHkgdGhlIFguNTA5IGZhY3Rvcnkgd291bGQKKyAgICAgICAgLy8gYWxsb3cgQVNOLjEgREVSIGVuY29kZWQgYnl0ZXMgYW5kIG9wdGlvbmFsbHkgc29tZSBQRU0KKyAgICAgICAgLy8gZm9ybWF0cy4gSGVyZSB3ZSB1c2UgQm91bmN5IENhc3RsZSdzCisgICAgICAgIC8vIFg1MDlWM0NlcnRpZmljYXRlR2VuZXJhdG9yIGFuZCByZWxhdGVkIGNsYXNzZXMuCisKKyAgICAgICAgbG9uZyBtaWxsaXNQZXJEYXkgPSAyNCAqIDYwICogNjAgKiAxMDAwOworICAgICAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICBEYXRlIHN0YXJ0ID0gbmV3IERhdGUobm93IC0gbWlsbGlzUGVyRGF5KTsKKyAgICAgICAgRGF0ZSBlbmQgPSBuZXcgRGF0ZShub3cgKyBtaWxsaXNQZXJEYXkpOworICAgICAgICBCaWdJbnRlZ2VyIHNlcmlhbCA9IEJpZ0ludGVnZXIudmFsdWVPZigxKTsKKworICAgICAgICBTdHJpbmcga2V5QWxnb3JpdGhtID0gcHJpdmF0ZUtleS5nZXRBbGdvcml0aG0oKTsKKyAgICAgICAgU3RyaW5nIHNpZ25hdHVyZUFsZ29yaXRobTsKKyAgICAgICAgaWYgKGtleUFsZ29yaXRobS5lcXVhbHMoIlJTQSIpKSB7CisgICAgICAgICAgICBzaWduYXR1cmVBbGdvcml0aG0gPSAic2hhMVdpdGhSU0EiOworICAgICAgICB9IGVsc2UgaWYgKGtleUFsZ29yaXRobS5lcXVhbHMoIkRTQSIpKSB7CisgICAgICAgICAgICBzaWduYXR1cmVBbGdvcml0aG0gPSAic2hhMVdpdGhEU0EiOworICAgICAgICB9IGVsc2UgaWYgKGtleUFsZ29yaXRobS5lcXVhbHMoIkVDIikpIHsKKyAgICAgICAgICAgIHNpZ25hdHVyZUFsZ29yaXRobSA9ICJzaGExV2l0aEVDRFNBIjsKKyAgICAgICAgfSBlbHNlIGlmIChrZXlBbGdvcml0aG0uZXF1YWxzKCJFQ19SU0EiKSkgeworICAgICAgICAgICAgc2lnbmF0dXJlQWxnb3JpdGhtID0gInNoYTFXaXRoUlNBIjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlVua25vd24ga2V5IGFsZ29yaXRobSAiICsga2V5QWxnb3JpdGhtKTsKKyAgICAgICAgfQorCisgICAgICAgIFg1MDlWM0NlcnRpZmljYXRlR2VuZXJhdG9yIHg1MDljZyA9IG5ldyBYNTA5VjNDZXJ0aWZpY2F0ZUdlbmVyYXRvcigpOworICAgICAgICB4NTA5Y2cuc2V0U3ViamVjdEROKHN1YmplY3QpOworICAgICAgICB4NTA5Y2cuc2V0SXNzdWVyRE4oaXNzdWVyKTsKKyAgICAgICAgeDUwOWNnLnNldE5vdEJlZm9yZShzdGFydCk7CisgICAgICAgIHg1MDljZy5zZXROb3RBZnRlcihlbmQpOworICAgICAgICB4NTA5Y2cuc2V0UHVibGljS2V5KHB1YmxpY0tleSk7CisgICAgICAgIHg1MDljZy5zZXRTaWduYXR1cmVBbGdvcml0aG0oc2lnbmF0dXJlQWxnb3JpdGhtKTsKKyAgICAgICAgeDUwOWNnLnNldFNlcmlhbE51bWJlcihzZXJpYWwpOworICAgICAgICBpZiAoa2V5VXNhZ2UgIT0gMCkgeworICAgICAgICAgICAgeDUwOWNnLmFkZEV4dGVuc2lvbihYNTA5RXh0ZW5zaW9ucy5LZXlVc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEtleVVzYWdlKGtleVVzYWdlKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNhKSB7CisgICAgICAgICAgICB4NTA5Y2cuYWRkRXh0ZW5zaW9uKFg1MDlFeHRlbnNpb25zLkJhc2ljQ29uc3RyYWludHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBCYXNpY0NvbnN0cmFpbnRzKHRydWUpKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKEdlbmVyYWxOYW1lIHN1YmplY3RBbHROYW1lIDogc3ViamVjdEFsdE5hbWVzKSB7CisgICAgICAgICAgICB4NTA5Y2cuYWRkRXh0ZW5zaW9uKFg1MDlFeHRlbnNpb25zLlN1YmplY3RBbHRlcm5hdGl2ZU5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgR2VuZXJhbE5hbWVzKHN1YmplY3RBbHROYW1lKS5nZXRFbmNvZGVkKCkpOworICAgICAgICB9CisgICAgICAgIGlmICghcGVybWl0dGVkTmFtZUNvbnN0cmFpbnRzLmlzRW1wdHkoKSB8fCAhZXhjbHVkZWROYW1lQ29uc3RyYWludHMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICB4NTA5Y2cuYWRkRXh0ZW5zaW9uKFg1MDlFeHRlbnNpb25zLk5hbWVDb25zdHJhaW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE5hbWVDb25zdHJhaW50cyhwZXJtaXR0ZWROYW1lQ29uc3RyYWludHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjbHVkZWROYW1lQ29uc3RyYWludHMpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChwcml2YXRlS2V5IGluc3RhbmNlb2YgRUNQcml2YXRlS2V5KSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogYm91bmN5Y2FzdGxlIG5lZWRzIGl0cyBvd24gRUNQcml2YXRlS2V5IGltcGxlbWVudGF0aW9uCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIEtleUZhY3Rvcnkga2YgPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKGtleUFsZ29yaXRobSwgIkJDIik7CisgICAgICAgICAgICBQS0NTOEVuY29kZWRLZXlTcGVjIGtzID0gbmV3IFBLQ1M4RW5jb2RlZEtleVNwZWMocHJpdmF0ZUtleS5nZXRFbmNvZGVkKCkpOworICAgICAgICAgICAgcHJpdmF0ZUtleSA9IGtmLmdlbmVyYXRlUHJpdmF0ZShrcyk7CisgICAgICAgIH0KKyAgICAgICAgWDUwOUNlcnRpZmljYXRlIHg1MDljID0geDUwOWNnLmdlbmVyYXRlWDUwOUNlcnRpZmljYXRlKHByaXZhdGVLZXkpOworICAgICAgICBpZiAoU3RhbmRhcmROYW1lcy5JU19SSSkgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFRoZSBSSSBjYW4ndCBoYW5kbGUgdGhlIEJDIEVDIHNpZ25hdHVyZSBhbGdvcml0aG0KKyAgICAgICAgICAgICAqIHN0cmluZyBvZiAiRUNEU0EiLCBzaW5jZSBpdCBleHBlY3RzICIuLi5XSVRIRUMuLi4iLAorICAgICAgICAgICAgICogc28gY29udmVydCBmcm9tIEJDIHRvIFJJIFg1MDlDZXJ0aWZpY2F0ZQorICAgICAgICAgICAgICogaW1wbGVtZW50YXRpb24gdmlhIGJ5dGVzLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiYWlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHg1MDljLmdldEVuY29kZWQoKSk7CisgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBjID0gY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShiYWlzKTsKKyAgICAgICAgICAgIHg1MDljID0gKFg1MDlDZXJ0aWZpY2F0ZSkgYzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4geDUwOWM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBrZXkgYWxnb3JpdGhtIGZvciBhIHBvc3NpYmxlIGNvbXBvdW5kIGFsZ29yaXRobQorICAgICAqIGlkZW50aWZpZXIgY29udGFpbmluZyBhbiB1bmRlcnNjb3JlLiBJZiBub3QgdW5kZXJzY29yZSBpcworICAgICAqIHByZXNlbnQsIHRoZSBhcmd1bWVudCBpcyByZXR1cm5lZCB1bm1vZGlmaWVkLiBIb3dldmVyIGZvciBhbgorICAgICAqIGFsZ29yaXRobSBzdWNoIGFzIEVDX1JTQSwgcmV0dXJuIEVDLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGtleUFsZ29yaXRobShTdHJpbmcgYWxnb3JpdGhtKSB7CisgICAgICAgIGludCBpbmRleCA9IGFsZ29yaXRobS5pbmRleE9mKCdfJyk7CisgICAgICAgIGlmIChpbmRleCA9PSAtMSkgeworICAgICAgICAgICAgcmV0dXJuIGFsZ29yaXRobTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYWxnb3JpdGhtLnN1YnN0cmluZygwLCBpbmRleCk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHNpZ25hdHVyZSBhbGdvcml0aG0gZm9yIGEgcG9zc2libGUgY29tcG91bmQKKyAgICAgKiBhbGdvcml0aG0gaWRlbnRpZmllciBjb250YWluaW5nIGFuIHVuZGVyc2NvcmUuIElmIG5vdAorICAgICAqIHVuZGVyc2NvcmUgaXMgcHJlc2VudCwgdGhlIGFyZ3VtZW50IGlzIHJldHVybmVkCisgICAgICogdW5tb2RpZmllZC4gSG93ZXZlciBmb3IgYW4gYWxnb3JpdGhtIHN1Y2ggYXMgRUNfUlNBLCByZXR1cm4KKyAgICAgKiBSU0EuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgc2lnbmF0dXJlQWxnb3JpdGhtKFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgaW50IGluZGV4ID0gYWxnb3JpdGhtLmluZGV4T2YoJ18nKTsKKyAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7CisgICAgICAgICAgICByZXR1cm4gYWxnb3JpdGhtOworICAgICAgICB9CisgICAgICAgIHJldHVybiBhbGdvcml0aG0uc3Vic3RyaW5nKGluZGV4KzEsIGFsZ29yaXRobS5sZW5ndGgoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuIGVtcHR5IEtleVN0b3JlCisgICAgICoKKyAgICAgKiBUaGUgS2V5U3RvcmUgaXMgb3B0aW9uYWxseSBwYXNzd29yZCBwcm90ZWN0ZWQgYnkgdGhlCisgICAgICoga2V5U3RvcmVQYXNzd29yZCBhcmd1bWVudCwgd2hpY2ggY2FuIGJlIG51bGwgaWYgYSBwYXNzd29yZCBpcworICAgICAqIG5vdCBkZXNpcmVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgS2V5U3RvcmUgY3JlYXRlS2V5U3RvcmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZSBrZXlTdG9yZSA9IEtleVN0b3JlLmdldEluc3RhbmNlKFN0YW5kYXJkTmFtZXMuS0VZX1NUT1JFX0FMR09SSVRITSk7CisgICAgICAgICAgICBrZXlTdG9yZS5sb2FkKG51bGwsIG51bGwpOworICAgICAgICAgICAgcmV0dXJuIGtleVN0b3JlOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG9ubHkgcHJpdmF0ZSBrZXkgaW4gYSBUZXN0S2V5U3RvcmUgZm9yIHRoZSBnaXZlbgorICAgICAqIGFsZ29yaXRobXMuIFRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlcmUgYXJlIGFyZSBtb3JlCisgICAgICogb3IgbGVzcyB0aGFuIG9uZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpdmF0ZUtleUVudHJ5IGdldFByaXZhdGVLZXkoU3RyaW5nIGtleUFsZ29yaXRobSwgU3RyaW5nIHNpZ25hdHVyZUFsZ29yaXRobSkgeworICAgICAgICByZXR1cm4gcHJpdmF0ZUtleShrZXlTdG9yZSwga2V5UGFzc3dvcmQsIGtleUFsZ29yaXRobSwgc2lnbmF0dXJlQWxnb3JpdGhtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG9ubHkgcHJpdmF0ZSBrZXkgaW4gYSBrZXlzdG9yZSBmb3IgdGhlIGdpdmVuCisgICAgICogYWxnb3JpdGhtcy4gVGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGVyZSBhcmUgYXJlIG1vcmUKKyAgICAgKiBvciBsZXNzIHRoYW4gb25lLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUHJpdmF0ZUtleUVudHJ5IHByaXZhdGVLZXkoS2V5U3RvcmUga2V5U3RvcmUsIGNoYXJbXSBrZXlQYXNzd29yZCwKKyAgICAgICAgICAgIFN0cmluZyBrZXlBbGdvcml0aG0sIFN0cmluZyBzaWduYXR1cmVBbGdvcml0aG0pIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFByaXZhdGVLZXlFbnRyeSBmb3VuZCA9IG51bGw7CisgICAgICAgICAgICBQYXNzd29yZFByb3RlY3Rpb24gcGFzc3dvcmQgPSBuZXcgUGFzc3dvcmRQcm90ZWN0aW9uKGtleVBhc3N3b3JkKTsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIGFsaWFzIDogQ29sbGVjdGlvbnMubGlzdChrZXlTdG9yZS5hbGlhc2VzKCkpKSB7CisgICAgICAgICAgICAgICAgaWYgKCFrZXlTdG9yZS5lbnRyeUluc3RhbmNlT2YoYWxpYXMsIFByaXZhdGVLZXlFbnRyeS5jbGFzcykpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIFByaXZhdGVLZXlFbnRyeSBwcml2YXRlS2V5ID0gKFByaXZhdGVLZXlFbnRyeSkga2V5U3RvcmUuZ2V0RW50cnkoYWxpYXMsIHBhc3N3b3JkKTsKKyAgICAgICAgICAgICAgICBpZiAoIXByaXZhdGVLZXkuZ2V0UHJpdmF0ZUtleSgpLmdldEFsZ29yaXRobSgpLmVxdWFscyhrZXlBbGdvcml0aG0pKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydGlmaWNhdGUgPSAoWDUwOUNlcnRpZmljYXRlKSBwcml2YXRlS2V5LmdldENlcnRpZmljYXRlKCk7CisgICAgICAgICAgICAgICAgaWYgKCFjZXJ0aWZpY2F0ZS5nZXRTaWdBbGdOYW1lKCkuY29udGFpbnMoc2lnbmF0dXJlQWxnb3JpdGhtKSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGZvdW5kICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiS2V5U3RvcmUgaGFzIG1vcmUgdGhhbiBvbmUgcHJpdmF0ZSBrZXkgZm9yICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIga2V5QWxnb3JpdGhtOiAiICsga2V5QWxnb3JpdGhtCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIHNpZ25hdHVyZUFsZ29yaXRobTogIiArIHNpZ25hdHVyZUFsZ29yaXRobQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIlxuZmlyc3Q6ICIgKyBmb3VuZC5nZXRQcml2YXRlS2V5KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJcbnNlY29uZDogIiArIHByaXZhdGVLZXkuZ2V0UHJpdmF0ZUtleSgpICk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZvdW5kID0gcHJpdmF0ZUtleTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChmb3VuZCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiS2V5U3RvcmUgY29udGFpbmVkIG5vIHByaXZhdGUga2V5IGZvciAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIga2V5QWxnb3JpdGhtOiAiICsga2V5QWxnb3JpdGhtCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgc2lnbmF0dXJlQWxnb3JpdGhtOiAiICsgc2lnbmF0dXJlQWxnb3JpdGhtKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmb3VuZDsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBpc3N1aW5nIENBIGNlcnRpZmljYXRlIG9mIHRoZSBnaXZlbgorICAgICAqIGNlcnRpZmljYXRlLiBUaHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZXJlIGFyZSBhcmUgbW9yZQorICAgICAqIG9yIGxlc3MgdGhhbiBvbmUuCisgICAgICovCisgICAgcHVibGljIENlcnRpZmljYXRlIGdldElzc3VlcihDZXJ0aWZpY2F0ZSBjZXJ0KSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGlzc3VlcihrZXlTdG9yZSwgY2VydCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBpc3N1aW5nIENBIGNlcnRpZmljYXRlIG9mIHRoZSBnaXZlbgorICAgICAqIGNlcnRpZmljYXRlLiBUaHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZXJlIGFyZSBhcmUgbW9yZQorICAgICAqIG9yIGxlc3MgdGhhbiBvbmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDZXJ0aWZpY2F0ZSBpc3N1ZXIoS2V5U3RvcmUga2V5U3RvcmUsIENlcnRpZmljYXRlIGMpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCEoYyBpbnN0YW5jZW9mIFg1MDlDZXJ0aWZpY2F0ZSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oImlzc3VlciByZXF1aXJlcyBhbiBYNTA5Q2VydGlmaWNhdGUsIGZvdW5kICIgKyBjKTsKKyAgICAgICAgfQorICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydCA9IChYNTA5Q2VydGlmaWNhdGUpIGM7CisKKyAgICAgICAgQ2VydGlmaWNhdGUgZm91bmQgPSBudWxsOworICAgICAgICBmb3IgKFN0cmluZyBhbGlhcyA6IENvbGxlY3Rpb25zLmxpc3Qoa2V5U3RvcmUuYWxpYXNlcygpKSkgeworICAgICAgICAgICAgaWYgKCFrZXlTdG9yZS5lbnRyeUluc3RhbmNlT2YoYWxpYXMsIFRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5LmNsYXNzKSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgVHJ1c3RlZENlcnRpZmljYXRlRW50cnkgY2VydGlmaWNhdGVFbnRyeSA9CisgICAgICAgICAgICAgICAgICAgIChUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeSkga2V5U3RvcmUuZ2V0RW50cnkoYWxpYXMsIG51bGwpOworICAgICAgICAgICAgQ2VydGlmaWNhdGUgY2VydGlmaWNhdGUgPSBjZXJ0aWZpY2F0ZUVudHJ5LmdldFRydXN0ZWRDZXJ0aWZpY2F0ZSgpOworICAgICAgICAgICAgaWYgKCEoY2VydGlmaWNhdGUgaW5zdGFuY2VvZiBYNTA5Q2VydGlmaWNhdGUpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGUgeCA9IChYNTA5Q2VydGlmaWNhdGUpIGNlcnRpZmljYXRlOworICAgICAgICAgICAgaWYgKCFjZXJ0LmdldElzc3VlckROKCkuZXF1YWxzKHguZ2V0U3ViamVjdEROKCkpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZm91bmQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIktleVN0b3JlIGhhcyBtb3JlIHRoYW4gb25lIGlzc3VpbmcgQ0EgZm9yICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgY2VydAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiXG5maXJzdDogIiArIGZvdW5kCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJcbnNlY29uZDogIiArIGNlcnRpZmljYXRlICk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmb3VuZCA9IGNlcnRpZmljYXRlOworICAgICAgICB9CisgICAgICAgIGlmIChmb3VuZCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJLZXlTdG9yZSBjb250YWluZWQgbm8gaXNzdWluZyBDQSBmb3IgIiArIGNlcnQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmb3VuZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG9ubHkgc2VsZi1zaWduZWQgcm9vdCBjZXJ0aWZpY2F0ZSBpbiBhIFRlc3RLZXlTdG9yZQorICAgICAqIGZvciB0aGUgZ2l2ZW4gYWxnb3JpdGhtLiBUaHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZXJlCisgICAgICogYXJlIGFyZSBtb3JlIG9yIGxlc3MgdGhhbiBvbmUuCisgICAgICovCisgICAgcHVibGljIFg1MDlDZXJ0aWZpY2F0ZSBnZXRSb290Q2VydGlmaWNhdGUoU3RyaW5nIGFsZ29yaXRobSkgIHsKKyAgICAgICAgcmV0dXJuIHJvb3RDZXJ0aWZpY2F0ZShrZXlTdG9yZSwgYWxnb3JpdGhtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG9ubHkgc2VsZi1zaWduZWQgcm9vdCBjZXJ0aWZpY2F0ZSBpbiBhIGtleXN0b3JlIGZvcgorICAgICAqIHRoZSBnaXZlbiBhbGdvcml0aG0uIFRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlcmUgYXJlCisgICAgICogYXJlIG1vcmUgb3IgbGVzcyB0aGFuIG9uZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFg1MDlDZXJ0aWZpY2F0ZSByb290Q2VydGlmaWNhdGUoS2V5U3RvcmUga2V5U3RvcmUsIFN0cmluZyBhbGdvcml0aG0pIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBmb3VuZCA9IG51bGw7CisgICAgICAgICAgICBmb3IgKFN0cmluZyBhbGlhcyA6IENvbGxlY3Rpb25zLmxpc3Qoa2V5U3RvcmUuYWxpYXNlcygpKSkgeworICAgICAgICAgICAgICAgIGlmICgha2V5U3RvcmUuZW50cnlJbnN0YW5jZU9mKGFsaWFzLCBUcnVzdGVkQ2VydGlmaWNhdGVFbnRyeS5jbGFzcykpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIFRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5IGNlcnRpZmljYXRlRW50cnkgPQorICAgICAgICAgICAgICAgICAgICAgICAgKFRydXN0ZWRDZXJ0aWZpY2F0ZUVudHJ5KSBrZXlTdG9yZS5nZXRFbnRyeShhbGlhcywgbnVsbCk7CisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGUgY2VydGlmaWNhdGUgPSBjZXJ0aWZpY2F0ZUVudHJ5LmdldFRydXN0ZWRDZXJ0aWZpY2F0ZSgpOworICAgICAgICAgICAgICAgIGlmICghY2VydGlmaWNhdGUuZ2V0UHVibGljS2V5KCkuZ2V0QWxnb3JpdGhtKCkuZXF1YWxzKGFsZ29yaXRobSkpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICghKGNlcnRpZmljYXRlIGluc3RhbmNlb2YgWDUwOUNlcnRpZmljYXRlKSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlIHggPSAoWDUwOUNlcnRpZmljYXRlKSBjZXJ0aWZpY2F0ZTsKKyAgICAgICAgICAgICAgICBpZiAoIXguZ2V0SXNzdWVyRE4oKS5lcXVhbHMoeC5nZXRTdWJqZWN0RE4oKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChmb3VuZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIktleVN0b3JlIGhhcyBtb3JlIHRoYW4gb25lIHJvb3QgQ0EgZm9yICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGFsZ29yaXRobQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIlxuZmlyc3Q6ICIgKyBmb3VuZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIlxuc2Vjb25kOiAiICsgY2VydGlmaWNhdGUgKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZm91bmQgPSB4OworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGZvdW5kID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJLZXlTdG9yZSBjb250YWluZWQgbm8gcm9vdCBDQSBmb3IgIiArIGFsZ29yaXRobSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gZm91bmQ7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIGNsaWVudCBrZXkgc3RvcmUgdGhhdCBvbmx5IGNvbnRhaW5zIHNlbGYtc2lnbmVkIGNlcnRpZmljYXRlcyBidXQgbm8gcHJpdmF0ZSBrZXlzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBLZXlTdG9yZSBjcmVhdGVDbGllbnQoS2V5U3RvcmUgY2FLZXlTdG9yZSkgeworICAgICAgICBLZXlTdG9yZSBjbGllbnRLZXlTdG9yZSA9IGNyZWF0ZUtleVN0b3JlKCk7CisgICAgICAgIGNvcHlTZWxmU2lnbmVkQ2VydGlmaWNhdGVzKGNsaWVudEtleVN0b3JlLCBjYUtleVN0b3JlKTsKKyAgICAgICAgcmV0dXJuIGNsaWVudEtleVN0b3JlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcHkgc2VsZi1zaWduZWQgY2VydGlmaWNhdGVzIGZyb20gb25lIGtleSBzdG9yZSB0byBhbm90aGVyLgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiBzdWNjZXNzZnVsLCBmYWxzZSBpZiBubyBtYXRjaCBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gY29weVNlbGZTaWduZWRDZXJ0aWZpY2F0ZXMoS2V5U3RvcmUgZHN0LCBLZXlTdG9yZSBzcmMpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJvb2xlYW4gY29waWVkID0gZmFsc2U7CisgICAgICAgICAgICBmb3IgKFN0cmluZyBhbGlhcyA6IENvbGxlY3Rpb25zLmxpc3Qoc3JjLmFsaWFzZXMoKSkpIHsKKyAgICAgICAgICAgICAgICBpZiAoIXNyYy5pc0NlcnRpZmljYXRlRW50cnkoYWxpYXMpKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGUgY2VydCA9IChYNTA5Q2VydGlmaWNhdGUpc3JjLmdldENlcnRpZmljYXRlKGFsaWFzKTsKKyAgICAgICAgICAgICAgICBpZiAoIWNlcnQuZ2V0U3ViamVjdEROKCkuZXF1YWxzKGNlcnQuZ2V0SXNzdWVyRE4oKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGRzdC5zZXRDZXJ0aWZpY2F0ZUVudHJ5KGFsaWFzLCBjZXJ0KTsKKyAgICAgICAgICAgICAgICBjb3BpZWQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGNvcGllZDsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29weSBuYW1lZCBjZXJ0aWZpY2F0ZXMgZnJvbSBvbmUga2V5IHN0b3JlIHRvIGFub3RoZXIuCisgICAgICogUmV0dXJucyB0cnVlIGlmIHN1Y2Nlc3NmdWwsIGZhbHNlIGlmIG5vIG1hdGNoIGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBjb3B5Q2VydGlmaWNhdGUoUHJpbmNpcGFsIHN1YmplY3QsIEtleVN0b3JlIGRzdCwgS2V5U3RvcmUgc3JjKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZvciAoU3RyaW5nIGFsaWFzIDogQ29sbGVjdGlvbnMubGlzdChzcmMuYWxpYXNlcygpKSkgeworICAgICAgICAgICAgaWYgKCFzcmMuaXNDZXJ0aWZpY2F0ZUVudHJ5KGFsaWFzKSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgWDUwOUNlcnRpZmljYXRlIGNlcnQgPSAoWDUwOUNlcnRpZmljYXRlKXNyYy5nZXRDZXJ0aWZpY2F0ZShhbGlhcyk7CisgICAgICAgICAgICBpZiAoIWNlcnQuZ2V0U3ViamVjdEROKCkuZXF1YWxzKHN1YmplY3QpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkc3Quc2V0Q2VydGlmaWNhdGVFbnRyeShhbGlhcywgY2VydCk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogRHVtcCBhIGtleSBzdG9yZSBmb3IgZGVidWdnaW5nLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBkdW1wKFN0cmluZyBjb250ZXh0LCBLZXlTdG9yZSBrZXlTdG9yZSwgY2hhcltdIGtleVBhc3N3b3JkKQorICAgICAgICAgICAgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICBQcmludFN0cmVhbSBvdXQgPSBTeXN0ZW0ub3V0OworICAgICAgICBvdXQucHJpbnRsbigiY29udGV4dD0iICsgY29udGV4dCk7CisgICAgICAgIG91dC5wcmludGxuKCJcdGtleVN0b3JlPSIgKyBrZXlTdG9yZSk7CisgICAgICAgIG91dC5wcmludGxuKCJcdGtleVN0b3JlLnR5cGU9IiArIGtleVN0b3JlLmdldFR5cGUoKSk7CisgICAgICAgIG91dC5wcmludGxuKCJcdGtleVN0b3JlLnByb3ZpZGVyPSIgKyBrZXlTdG9yZS5nZXRQcm92aWRlcigpKTsKKyAgICAgICAgb3V0LnByaW50bG4oIlx0a2V5UGFzc3dvcmQ9IgorICAgICAgICAgICAgICAgICAgICArICgoa2V5UGFzc3dvcmQgPT0gbnVsbCkgPyBudWxsIDogbmV3IFN0cmluZyhrZXlQYXNzd29yZCkpKTsKKyAgICAgICAgb3V0LnByaW50bG4oIlx0c2l6ZT0iICsga2V5U3RvcmUuc2l6ZSgpKTsKKyAgICAgICAgZm9yIChTdHJpbmcgYWxpYXMgOiBDb2xsZWN0aW9ucy5saXN0KGtleVN0b3JlLmFsaWFzZXMoKSkpIHsKKyAgICAgICAgICAgIG91dC5wcmludGxuKCJhbGlhcz0iICsgYWxpYXMpOworICAgICAgICAgICAgb3V0LnByaW50bG4oIlx0Y3JlYXRpb25EYXRlPSIgKyBrZXlTdG9yZS5nZXRDcmVhdGlvbkRhdGUoYWxpYXMpKTsKKyAgICAgICAgICAgIGlmIChrZXlTdG9yZS5pc0NlcnRpZmljYXRlRW50cnkoYWxpYXMpKSB7CisgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oIlx0Y2VydGlmaWNhdGU6Iik7CisgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpOworICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGtleVN0b3JlLmdldENlcnRpZmljYXRlKGFsaWFzKSk7CisgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGtleVN0b3JlLmlzS2V5RW50cnkoYWxpYXMpKSB7CisgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oIlx0a2V5OiIpOworICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcga2V5OworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGtleSA9ICgiS2V5IHJldHJpZXZlZCB1c2luZyBwYXNzd29yZFxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBrZXlTdG9yZS5nZXRLZXkoYWxpYXMsIGtleVBhc3N3b3JkKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiBlMSkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gKCJLZXkgcmV0cmlldmVkIHdpdGhvdXQgcGFzc3dvcmRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGtleVN0b3JlLmdldEtleShhbGlhcywgbnVsbCkpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uIGUyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSAiS2V5IGNvdWxkIG5vdCBiZSByZXRyaWV2ZWQiOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGtleSk7CisgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpOworICAgICAgICAgICAgICAgIENlcnRpZmljYXRlW10gY2hhaW4gPSBrZXlTdG9yZS5nZXRDZXJ0aWZpY2F0ZUNoYWluKGFsaWFzKTsKKyAgICAgICAgICAgICAgICBpZiAoY2hhaW4gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbigiTm8gY2VydGlmaWNhdGUgY2hhaW4gYXNzb2NpYXRlZCB3aXRoIGtleSIpOworICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbigiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Iik7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaGFpbi5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oIkNlcnRpZmljYXRlIGNoYWluIGVsZW1lbnQgIyIgKyBpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKGNoYWluW2ldKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG91dC5wcmludGxuKCJcdHVua25vd24gZW50cnkgdHlwZSIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydENoYWluTGVuZ3RoKE9iamVjdFtdIGNoYWluKSB7CisgICAgICAgIC8qCisgICAgICAgICAqIE5vdGUgY2hhaW4gaXMgT2JqZWN0W10gdG8gc3VwcG9ydCBib3RoCisgICAgICAgICAqIGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGUgYW5kCisgICAgICAgICAqIGphdmF4LnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlCisgICAgICAgICAqLworICAgICAgICBhc3NlcnRFcXVhbHMoMywgY2hhaW4ubGVuZ3RoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL0Zha2VTU0xTZXNzaW9uLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL0Zha2VTU0xTZXNzaW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGQ4NzZlNwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvRmFrZVNTTFNlc3Npb24uamF2YQpAQCAtMCwwICsxLDExNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbkNvbnRleHQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworCitwdWJsaWMgY2xhc3MgRmFrZVNTTFNlc3Npb24gaW1wbGVtZW50cyBTU0xTZXNzaW9uIHsKKyAgICBmaW5hbCBTdHJpbmcgaG9zdDsKKworICAgIHB1YmxpYyBGYWtlU1NMU2Vzc2lvbihTdHJpbmcgaG9zdCkgeworICAgICAgICB0aGlzLmhvc3QgPSBob3N0OworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0QXBwbGljYXRpb25CdWZmZXJTaXplKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldENpcGhlclN1aXRlKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBnZXRDcmVhdGlvblRpbWUoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0SWQoKSB7CisgICAgICAgIHJldHVybiBob3N0LmdldEJ5dGVzKCk7CisgICAgfQorCisgICAgcHVibGljIGxvbmcgZ2V0TGFzdEFjY2Vzc2VkVGltZSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgcHVibGljIENlcnRpZmljYXRlW10gZ2V0TG9jYWxDZXJ0aWZpY2F0ZXMoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0TG9jYWxQcmluY2lwYWwoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0UGFja2V0QnVmZmVyU2l6ZSgpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgcHVibGljIGphdmF4LnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlW10gZ2V0UGVlckNlcnRpZmljYXRlQ2hhaW4oKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZVtdIGdldFBlZXJDZXJ0aWZpY2F0ZXMoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGVlckhvc3QoKSB7CisgICAgICAgIHJldHVybiBob3N0OworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0UGVlclBvcnQoKSB7CisgICAgICAgIHJldHVybiA0NDM7CisgICAgfQorCisgICAgcHVibGljIFByaW5jaXBhbCBnZXRQZWVyUHJpbmNpcGFsKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFByb3RvY29sKCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU1NMU2Vzc2lvbkNvbnRleHQgZ2V0U2Vzc2lvbkNvbnRleHQoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0VmFsdWUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZ1tdIGdldFZhbHVlTmFtZXMoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGludmFsaWRhdGUoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzVmFsaWQoKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHB1dFZhbHVlKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVtb3ZlVmFsdWUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvbmV0L3NzbC9UZXN0S2V5TWFuYWdlci5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvbmV0L3NzbC9UZXN0S2V5TWFuYWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAzNDIwZmUKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL1Rlc3RLZXlNYW5hZ2VyLmphdmEKQEAgLTAsMCArMSwyMDYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuU29ja2V0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleU1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFbmdpbmU7CitpbXBvcnQgamF2YXgubmV0LnNzbC5YNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyOworaW1wb3J0IGxpYmNvcmUuamF2YS5pby5OdWxsUHJpbnRTdHJlYW07CitpbXBvcnQgbGliY29yZS5qYXZhLnNlY3VyaXR5LlN0YW5kYXJkTmFtZXM7CisKKy8qKgorICogVGVzdEtleU1hbmFnZXIgaXMgYSBzaW1wbGUgcHJveHkgY2xhc3MgdGhhdCB3cmFwcyBhbiBleGlzdGluZworICogWDUwOUV4dGVuZGVkS2V5TWFuYWdlciB0byBwcm92aWRlIGRlYnVnIGxvZ2dpbmcgYW5kIHJlY29yZGluZyBvZgorICogdmFsdWVzLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgVGVzdEtleU1hbmFnZXIgZXh0ZW5kcyBYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gTE9HID0gZmFsc2U7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUHJpbnRTdHJlYW0gb3V0ID0gTE9HID8gU3lzdGVtLm91dCA6IG5ldyBOdWxsUHJpbnRTdHJlYW0oKTsKKworICAgIHByaXZhdGUgZmluYWwgWDUwOUV4dGVuZGVkS2V5TWFuYWdlciBrZXlNYW5hZ2VyOworCisgICAgcHVibGljIHN0YXRpYyBLZXlNYW5hZ2VyW10gd3JhcChLZXlNYW5hZ2VyW10ga2V5TWFuYWdlcnMpIHsKKyAgICAgICAgS2V5TWFuYWdlcltdIHJlc3VsdCA9IGtleU1hbmFnZXJzLmNsb25lKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVzdWx0Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICByZXN1bHRbaV0gPSB3cmFwKHJlc3VsdFtpXSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIEtleU1hbmFnZXIgd3JhcChLZXlNYW5hZ2VyIGtleU1hbmFnZXIpIHsKKyAgICAgICAgaWYgKCEoa2V5TWFuYWdlciBpbnN0YW5jZW9mIFg1MDlFeHRlbmRlZEtleU1hbmFnZXIpKSB7CisgICAgICAgICAgICByZXR1cm4ga2V5TWFuYWdlcjsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFRlc3RLZXlNYW5hZ2VyKChYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyKSBrZXlNYW5hZ2VyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgVGVzdEtleU1hbmFnZXIoWDUwOUV4dGVuZGVkS2V5TWFuYWdlciBrZXlNYW5hZ2VyKSB7CisgICAgICAgIG91dC5wcmludGxuKCJUZXN0S2V5TWFuYWdlci48aW5pdD4ga2V5TWFuYWdlcj0iICsga2V5TWFuYWdlcik7CisgICAgICAgIHRoaXMua2V5TWFuYWdlciA9IGtleU1hbmFnZXI7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBjaG9vc2VDbGllbnRBbGlhcyhTdHJpbmdbXSBrZXlUeXBlcywgUHJpbmNpcGFsW10gaXNzdWVycywgU29ja2V0IHNvY2tldCkgeworICAgICAgICBvdXQucHJpbnQoIlRlc3RLZXlNYW5hZ2VyLmNob29zZUNsaWVudEFsaWFzIik7CisgICAgICAgIG91dC5wcmludCgiIHwga2V5VHlwZXM6ICIpOworICAgICAgICBmb3IgKFN0cmluZyBrZXlUeXBlIDoga2V5VHlwZXMpIHsKKyAgICAgICAgICAgIG91dC5wcmludChrZXlUeXBlKTsKKyAgICAgICAgICAgIG91dC5wcmludCgnICcpOworICAgICAgICB9CisgICAgICAgIGR1bXBJc3N1ZXJzKGlzc3VlcnMpOworICAgICAgICBkdW1wU29ja2V0KHNvY2tldCk7CisgICAgICAgIGFzc2VydEtleVR5cGVzKGtleVR5cGVzKTsKKyAgICAgICAgcmV0dXJuIGR1bXBBbGlhcyhrZXlNYW5hZ2VyLmNob29zZUNsaWVudEFsaWFzKGtleVR5cGVzLCBpc3N1ZXJzLCBzb2NrZXQpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0S2V5VHlwZXMoU3RyaW5nW10ga2V5VHlwZXMpIHsKKyAgICAgICAgZm9yIChTdHJpbmcga2V5VHlwZSA6IGtleVR5cGVzKSB7CisgICAgICAgICAgICBhc3NlcnRLZXlUeXBlKGtleVR5cGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydEtleVR5cGUoU3RyaW5nIGtleVR5cGUpIHsKKyAgICAgICAgaWYgKCFTdGFuZGFyZE5hbWVzLktFWV9UWVBFUy5jb250YWlucyhrZXlUeXBlKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJVbmV4cGVjdGVkIGtleSB0eXBlICIgKyBrZXlUeXBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgY2hvb3NlU2VydmVyQWxpYXMoU3RyaW5nIGtleVR5cGUsIFByaW5jaXBhbFtdIGlzc3VlcnMsIFNvY2tldCBzb2NrZXQpIHsKKyAgICAgICAgb3V0LnByaW50KCJUZXN0S2V5TWFuYWdlci5jaG9vc2VTZXJ2ZXJBbGlhcyIpOworICAgICAgICBvdXQucHJpbnQoIiB8IGtleVR5cGU6ICIpOworICAgICAgICBvdXQucHJpbnQoa2V5VHlwZSk7CisgICAgICAgIG91dC5wcmludCgnICcpOworICAgICAgICBkdW1wSXNzdWVycyhpc3N1ZXJzKTsKKyAgICAgICAgZHVtcFNvY2tldChzb2NrZXQpOworICAgICAgICBhc3NlcnRLZXlUeXBlKGtleVR5cGUpOworICAgICAgICByZXR1cm4gZHVtcEFsaWFzKGtleU1hbmFnZXIuY2hvb3NlU2VydmVyQWxpYXMoa2V5VHlwZSwgaXNzdWVycywgc29ja2V0KSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGR1bXBTb2NrZXQoU29ja2V0IHNvY2tldCkgeworICAgICAgICBvdXQucHJpbnQoIiB8IHNvY2tldDogIik7CisgICAgICAgIG91dC5wcmludChTdHJpbmcudmFsdWVPZihzb2NrZXQpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZHVtcElzc3VlcnMoUHJpbmNpcGFsW10gaXNzdWVycykgeworICAgICAgICBvdXQucHJpbnQoIiB8IGlzc3VlcnM6ICIpOworICAgICAgICBpZiAoaXNzdWVycyA9PSBudWxsKSB7CisgICAgICAgICAgICBvdXQucHJpbnQoIm51bGwiKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBmb3IgKFByaW5jaXBhbCBpc3N1ZXIgOiBpc3N1ZXJzKSB7CisgICAgICAgICAgICBvdXQucHJpbnQoaXNzdWVyKTsKKyAgICAgICAgICAgIG91dC5wcmludCgnICcpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgZHVtcEFsaWFzKFN0cmluZyBhbGlhcykgeworICAgICAgICBvdXQucHJpbnQoIiA9PiAiKTsKKyAgICAgICAgb3V0LnByaW50bG4oYWxpYXMpOworICAgICAgICByZXR1cm4gYWxpYXM7CisgICAgfQorCisgICAgcHVibGljIFg1MDlDZXJ0aWZpY2F0ZVtdIGdldENlcnRpZmljYXRlQ2hhaW4oU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIG91dC5wcmludCgiVGVzdEtleU1hbmFnZXIuZ2V0Q2VydGlmaWNhdGVDaGFpbiIpOworICAgICAgICBvdXQucHJpbnQoIiB8IGFsaWFzOiAiKTsKKyAgICAgICAgb3V0LnByaW50KGFsaWFzKTsKKyAgICAgICAgcmV0dXJuIGR1bXBDZXJ0cyhrZXlNYW5hZ2VyLmdldENlcnRpZmljYXRlQ2hhaW4oYWxpYXMpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFg1MDlDZXJ0aWZpY2F0ZVtdIGR1bXBDZXJ0cyhYNTA5Q2VydGlmaWNhdGVbXSBjZXJ0cykgeworICAgICAgICBvdXQucHJpbnQoIiA9PiAiKTsKKyAgICAgICAgZm9yIChYNTA5Q2VydGlmaWNhdGUgY2VydCA6IGNlcnRzKSB7CisgICAgICAgICAgICBvdXQucHJpbnQoY2VydC5nZXRTdWJqZWN0RE4oKSk7CisgICAgICAgICAgICBvdXQucHJpbnQoJyAnKTsKKyAgICAgICAgfQorICAgICAgICBvdXQucHJpbnRsbigpOworICAgICAgICByZXR1cm4gY2VydHM7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZ1tdIGdldENsaWVudEFsaWFzZXMoU3RyaW5nIGtleVR5cGUsIFByaW5jaXBhbFtdIGlzc3VlcnMpIHsKKyAgICAgICAgb3V0LnByaW50KCJUZXN0S2V5TWFuYWdlci5nZXRDbGllbnRBbGlhc2VzIik7CisgICAgICAgIG91dC5wcmludCgiIHwga2V5VHlwZTogIik7CisgICAgICAgIG91dC5wcmludChrZXlUeXBlKTsKKyAgICAgICAgZHVtcElzc3VlcnMoaXNzdWVycyk7CisgICAgICAgIGFzc2VydEtleVR5cGUoa2V5VHlwZSk7CisgICAgICAgIHJldHVybiBkdW1wQWxpYXNlcyhrZXlNYW5hZ2VyLmdldENsaWVudEFsaWFzZXMoa2V5VHlwZSwgaXNzdWVycykpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRTZXJ2ZXJBbGlhc2VzKFN0cmluZyBrZXlUeXBlLCBQcmluY2lwYWxbXSBpc3N1ZXJzKSB7CisgICAgICAgIG91dC5wcmludCgiVGVzdEtleU1hbmFnZXIuZ2V0U2VydmVyQWxpYXNlcyIpOworICAgICAgICBvdXQucHJpbnQoIiB8IGtleVR5cGU6ICIpOworICAgICAgICBvdXQucHJpbnQoa2V5VHlwZSk7CisgICAgICAgIGR1bXBJc3N1ZXJzKGlzc3VlcnMpOworICAgICAgICBhc3NlcnRLZXlUeXBlKGtleVR5cGUpOworICAgICAgICByZXR1cm4gZHVtcEFsaWFzZXMoa2V5TWFuYWdlci5nZXRTZXJ2ZXJBbGlhc2VzKGtleVR5cGUsIGlzc3VlcnMpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZ1tdIGR1bXBBbGlhc2VzKFN0cmluZ1tdIGFsaWFzZXMpIHsKKyAgICAgICAgb3V0LnByaW50KCIgPT4gIik7CisgICAgICAgIGZvciAoU3RyaW5nIGFsaWFzIDogYWxpYXNlcykgeworICAgICAgICAgICAgb3V0LnByaW50KGFsaWFzKTsKKyAgICAgICAgICAgIG91dC5wcmludCgnICcpOworICAgICAgICB9CisgICAgICAgIG91dC5wcmludGxuKCk7CisgICAgICAgIHJldHVybiBhbGlhc2VzOworICAgIH0KKworICAgIHB1YmxpYyBQcml2YXRlS2V5IGdldFByaXZhdGVLZXkoU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIG91dC5wcmludCgiVGVzdEtleU1hbmFnZXIuZ2V0UHJpdmF0ZUtleSIpOworICAgICAgICBvdXQucHJpbnQoIiB8IGFsaWFzOiAiKTsKKyAgICAgICAgb3V0LnByaW50KGFsaWFzKTsKKyAgICAgICAgUHJpdmF0ZUtleSBwayA9IGtleU1hbmFnZXIuZ2V0UHJpdmF0ZUtleShhbGlhcyk7CisgICAgICAgIG91dC5wcmludCgiID0+ICIpOworICAgICAgICBvdXQucHJpbnRsbihTdHJpbmcudmFsdWVPZihwaykpOworICAgICAgICByZXR1cm4gcGs7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBjaG9vc2VFbmdpbmVDbGllbnRBbGlhcyhTdHJpbmdbXSBrZXlUeXBlcywgUHJpbmNpcGFsW10gaXNzdWVycywgU1NMRW5naW5lIGUpIHsKKyAgICAgICAgb3V0LnByaW50KCJUZXN0S2V5TWFuYWdlci5jaG9vc2VFbmdpbmVDbGllbnRBbGlhcyIpOworICAgICAgICBvdXQucHJpbnQoIiB8IGtleVR5cGVzOiAiKTsKKyAgICAgICAgZm9yIChTdHJpbmcga2V5VHlwZSA6IGtleVR5cGVzKSB7CisgICAgICAgICAgICBvdXQucHJpbnQoa2V5VHlwZSk7CisgICAgICAgICAgICBvdXQucHJpbnQoJyAnKTsKKyAgICAgICAgfQorICAgICAgICBkdW1wSXNzdWVycyhpc3N1ZXJzKTsKKyAgICAgICAgZHVtcEVuZ2luZShlKTsKKyAgICAgICAgYXNzZXJ0S2V5VHlwZXMoa2V5VHlwZXMpOworICAgICAgICByZXR1cm4gZHVtcEFsaWFzKGtleU1hbmFnZXIuY2hvb3NlRW5naW5lQ2xpZW50QWxpYXMoa2V5VHlwZXMsIGlzc3VlcnMsIGUpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGNob29zZUVuZ2luZVNlcnZlckFsaWFzKFN0cmluZyBrZXlUeXBlLCBQcmluY2lwYWxbXSBpc3N1ZXJzLCBTU0xFbmdpbmUgZSkgeworICAgICAgICBvdXQucHJpbnQoIlRlc3RLZXlNYW5hZ2VyLmNob29zZUVuZ2luZVNlcnZlckFsaWFzIik7CisgICAgICAgIG91dC5wcmludCgiIHwga2V5VHlwZTogIik7CisgICAgICAgIG91dC5wcmludChrZXlUeXBlKTsKKyAgICAgICAgb3V0LnByaW50KCcgJyk7CisgICAgICAgIGR1bXBJc3N1ZXJzKGlzc3VlcnMpOworICAgICAgICBkdW1wRW5naW5lKGUpOworICAgICAgICBhc3NlcnRLZXlUeXBlKGtleVR5cGUpOworICAgICAgICByZXR1cm4gZHVtcEFsaWFzKGtleU1hbmFnZXIuY2hvb3NlRW5naW5lU2VydmVyQWxpYXMoa2V5VHlwZSwgaXNzdWVycywgZSkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBkdW1wRW5naW5lKFNTTEVuZ2luZSBlbmdpbmUpIHsKKyAgICAgICAgb3V0LnByaW50KCIgfCBlbmdpbmU6ICIpOworICAgICAgICBvdXQucHJpbnQoU3RyaW5nLnZhbHVlT2YoZW5naW5lKSk7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL1Rlc3RTU0xDb250ZXh0LmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL1Rlc3RTU0xDb250ZXh0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWM0MjRiYwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvVGVzdFNTTENvbnRleHQuamF2YQpAQCAtMCwwICsxLDMwNSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuVW5rbm93bkhvc3RFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTENvbnRleHQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTb2NrZXQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTb2NrZXRGYWN0b3J5OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuVHJ1c3RNYW5hZ2VyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuWDUwOUV4dGVuZGVkS2V5TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlg1MDlUcnVzdE1hbmFnZXI7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydDsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuU3RhbmRhcmROYW1lczsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuVGVzdEtleVN0b3JlOworCisvKioKKyAqIFRlc3RTU0xDb250ZXh0IGlzIGEgY29udmVuaWVuY2UgY2xhc3MgZm9yIG90aGVyIHRlc3RzIHRoYXQKKyAqIHdhbnQgYSBjYW5uZWQgU1NMQ29udGV4dCBhbmQgcmVsYXRlZCBzdGF0ZSBmb3IgdGVzdGluZyBzbyB0aGV5CisgKiBkb24ndCBoYXZlIHRvIGR1cGxpY2F0ZSB0aGUgbG9naWMuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBUZXN0U1NMQ29udGV4dCBleHRlbmRzIEFzc2VydCB7CisKKyAgICAvKgorICAgICAqIFRoZSBSSSBhbmQgQW5kcm9pZCBoYXZlIHZlcnkgZGlmZmVyZW50IGRlZmF1bHQgU1NMU2Vzc2lvbiBjYWNoZSBiZWhhdmlvcnMuCisgICAgICogVGhlIFJJIGtlZXBzIGFuIHVubGltaXRlZCBudW1iZXIgb2YgU1NMU2VzaW9ucyBhcm91bmQgZm9yIDEgZGF5LgorICAgICAqIEFuZHJvaWQga2VlcHMgMTAgU1NMU2Vzc2lvbnMgZm9yZXZlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIElTX1JJID0gU3RhbmRhcmROYW1lcy5JU19SSTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFWFBFQ1RFRF9ERUZBVUxUX0NMSUVOVF9TU0xfU0VTU0lPTl9DQUNIRV9TSVpFID0gKElTX1JJKSA/IDAgOiAxMDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFWFBFQ1RFRF9ERUZBVUxUX1NFUlZFUl9TU0xfU0VTU0lPTl9DQUNIRV9TSVpFID0gKElTX1JJKSA/IDAgOiAxMDA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVhQRUNURURfREVGQVVMVF9TU0xfU0VTU0lPTl9DQUNIRV9USU1FT1VUID0gKElTX1JJKSA/IDg2NDAwIDogMDsKKworICAgIC8qKgorICAgICAqIFRoZSBBbmRyb2lkIFNTTFNvY2tldCBhbmQgU1NMU2VydmVyU29ja2V0IGltcGxlbWVudGF0aW9ucyBhcmUKKyAgICAgKiBiYXNlZCBvbiBhIHZlcnNpb24gb2YgT3BlblNTTCB3aGljaCBpbmNsdWRlcyBzdXBwb3J0IGZvciBSRkMKKyAgICAgKiA0NTA3IHNlc3Npb24gdGlja2V0cy4gV2hlbiB1c2luZyBzZXNzaW9uIHRpY2tldHMsIHRoZSBzZXJ2ZXIKKyAgICAgKiBkb2VzIG5vdCBuZWVkIHRvIGtlZXAgYSBjYWNoZSBtYXBwaW5nIHNlc3Npb24gSURzIHRvIFNTTAorICAgICAqIHNlc3Npb25zIGZvciByZXVzZS4gSW5zdGVhZCwgdGhlIGNsaWVudCBwcmVzZW50cyB0aGUgc2VydmVyCisgICAgICogd2l0aCBhIHNlc3Npb24gdGlja2V0IGl0IHJlY2VpdmVkIGZyb20gdGhlIHNlcnZlciBlYXJsaWVyLAorICAgICAqIHdoaWNoIGlzIGFuIFNTTCBzZXNzaW9uIGVuY3J5cHRlZCBieSB0aGUgc2VydmVyJ3Mgc2VjcmV0CisgICAgICoga2V5LiBTaW5jZSBpbiB0aGlzIGNhc2UgdGhlIHNlcnZlciBkb2VzIG5vdCBuZWVkIHRvIGtlZXAgYQorICAgICAqIGNhY2hlLCBzb21lIHRlc3RzIG1heSBmaW5kIGRpZmZlcmVudCByZXN1bHRzIGRlcGVuZGluZyBvbgorICAgICAqIHdoZXRoZXIgb3Igbm90IHRoZSBzZXNzaW9uIHRpY2tldHMgYXJlIGluIHVzZS4gVGhlc2UgdGVzdHMgY2FuCisgICAgICogdXNlIHRoaXMgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGlmIGxvb3BiYWNrIFNTTCBjb25uZWN0aW9ucyBhcmUKKyAgICAgKiBleHBlY3RlZCB0byB1c2Ugc2Vzc2lvbiB0aWNrZXRzIGFuZCBjb25kaXRpb25hbGl6ZSB0aGVpcgorICAgICAqIHJlc3VsdHMgYXBwcm9wcmlhdGVseS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gc3NsU2VydmVyU29ja2V0U3VwcG9ydHNTZXNzaW9uVGlja2V0cyAoKSB7CisgICAgICAgIC8vIERpc2FibGVkIHNlc3Npb24gdGlja2V0cyBmb3IgYmV0dGVyIGNvbXBhdGFiaWxpdHkgYi8yNjgyODc2CisgICAgICAgIC8vIHJldHVybiAhSVNfUkk7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgS2V5U3RvcmUgY2xpZW50S2V5U3RvcmU7CisgICAgcHVibGljIGZpbmFsIGNoYXJbXSBjbGllbnRTdG9yZVBhc3N3b3JkOworICAgIHB1YmxpYyBmaW5hbCBLZXlTdG9yZSBzZXJ2ZXJLZXlTdG9yZTsKKyAgICBwdWJsaWMgZmluYWwgY2hhcltdIHNlcnZlclN0b3JlUGFzc3dvcmQ7CisgICAgcHVibGljIGZpbmFsIFg1MDlFeHRlbmRlZEtleU1hbmFnZXIgY2xpZW50S2V5TWFuYWdlcjsKKyAgICBwdWJsaWMgZmluYWwgWDUwOUV4dGVuZGVkS2V5TWFuYWdlciBzZXJ2ZXJLZXlNYW5hZ2VyOworICAgIHB1YmxpYyBmaW5hbCBYNTA5VHJ1c3RNYW5hZ2VyIGNsaWVudFRydXN0TWFuYWdlcjsKKyAgICBwdWJsaWMgZmluYWwgWDUwOVRydXN0TWFuYWdlciBzZXJ2ZXJUcnVzdE1hbmFnZXI7CisgICAgcHVibGljIGZpbmFsIFNTTENvbnRleHQgY2xpZW50Q29udGV4dDsKKyAgICBwdWJsaWMgZmluYWwgU1NMQ29udGV4dCBzZXJ2ZXJDb250ZXh0OworICAgIHB1YmxpYyBmaW5hbCBTU0xTZXJ2ZXJTb2NrZXQgc2VydmVyU29ja2V0OworICAgIHB1YmxpYyBmaW5hbCBJbmV0QWRkcmVzcyBob3N0OworICAgIHB1YmxpYyBmaW5hbCBpbnQgcG9ydDsKKworICAgIHByaXZhdGUgVGVzdFNTTENvbnRleHQoS2V5U3RvcmUgY2xpZW50S2V5U3RvcmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyW10gY2xpZW50U3RvcmVQYXNzd29yZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIEtleVN0b3JlIHNlcnZlcktleVN0b3JlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcltdIHNlcnZlclN0b3JlUGFzc3dvcmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyIGNsaWVudEtleU1hbmFnZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyIHNlcnZlcktleU1hbmFnZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYNTA5VHJ1c3RNYW5hZ2VyIGNsaWVudFRydXN0TWFuYWdlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFg1MDlUcnVzdE1hbmFnZXIgc2VydmVyVHJ1c3RNYW5hZ2VyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMQ29udGV4dCBjbGllbnRDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMQ29udGV4dCBzZXJ2ZXJDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMU2VydmVyU29ja2V0IHNlcnZlclNvY2tldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZXRBZGRyZXNzIGhvc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgcG9ydCkgeworICAgICAgICB0aGlzLmNsaWVudEtleVN0b3JlID0gY2xpZW50S2V5U3RvcmU7CisgICAgICAgIHRoaXMuY2xpZW50U3RvcmVQYXNzd29yZCA9IGNsaWVudFN0b3JlUGFzc3dvcmQ7CisgICAgICAgIHRoaXMuc2VydmVyS2V5U3RvcmUgPSBzZXJ2ZXJLZXlTdG9yZTsKKyAgICAgICAgdGhpcy5zZXJ2ZXJTdG9yZVBhc3N3b3JkID0gc2VydmVyU3RvcmVQYXNzd29yZDsKKyAgICAgICAgdGhpcy5jbGllbnRLZXlNYW5hZ2VyID0gY2xpZW50S2V5TWFuYWdlcjsKKyAgICAgICAgdGhpcy5zZXJ2ZXJLZXlNYW5hZ2VyID0gc2VydmVyS2V5TWFuYWdlcjsKKyAgICAgICAgdGhpcy5jbGllbnRUcnVzdE1hbmFnZXIgPSBjbGllbnRUcnVzdE1hbmFnZXI7CisgICAgICAgIHRoaXMuc2VydmVyVHJ1c3RNYW5hZ2VyID0gc2VydmVyVHJ1c3RNYW5hZ2VyOworICAgICAgICB0aGlzLmNsaWVudENvbnRleHQgPSBjbGllbnRDb250ZXh0OworICAgICAgICB0aGlzLnNlcnZlckNvbnRleHQgPSBzZXJ2ZXJDb250ZXh0OworICAgICAgICB0aGlzLnNlcnZlclNvY2tldCA9IHNlcnZlclNvY2tldDsKKyAgICAgICAgdGhpcy5ob3N0ID0gaG9zdDsKKyAgICAgICAgdGhpcy5wb3J0ID0gcG9ydDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlcnZlclNvY2tldC5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc3VhbCBUZXN0U1NMQ29udGV4dCBjcmVhdGlvbiBtZXRob2QsIGNyZWF0ZXMgdW5kZXJseWluZworICAgICAqIFNTTENvbnRleHQgd2l0aCBjZXJ0aWZpY2F0ZSBhbmQga2V5IGFzIHdlbGwgYXMgU1NMU2VydmVyU29ja2V0CisgICAgICogbGlzdGVuaW5nIHByb3ZpZGVkIGhvc3QgYW5kIHBvcnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBUZXN0U1NMQ29udGV4dCBjcmVhdGUoKSB7CisgICAgICAgIHJldHVybiBjcmVhdGUoVGVzdEtleVN0b3JlLmdldENsaWVudCgpLAorICAgICAgICAgICAgICAgICAgICAgIFRlc3RLZXlTdG9yZS5nZXRTZXJ2ZXIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdFNTTENvbnRleHQgY3JlYXRpb24gbWV0aG9kIHRoYXQgYWxsb3dzIHNlcGFyYXRlIGNyZWF0aW9uIG9mIHNlcnZlciBrZXkgc3RvcmUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFRlc3RTU0xDb250ZXh0IGNyZWF0ZShUZXN0S2V5U3RvcmUgY2xpZW50LCBUZXN0S2V5U3RvcmUgc2VydmVyKSB7CisgICAgICAgIFN0cmluZyBwcm92aWRlciA9IFN0YW5kYXJkTmFtZXMuSlNTRV9QUk9WSURFUl9OQU1FOworICAgICAgICByZXR1cm4gY3JlYXRlKGNsaWVudCwgc2VydmVyLCBwcm92aWRlciwgcHJvdmlkZXIpOworICAgIH0KKyAgICBwdWJsaWMgc3RhdGljIFRlc3RTU0xDb250ZXh0IGNyZWF0ZShUZXN0S2V5U3RvcmUgY2xpZW50LCBUZXN0S2V5U3RvcmUgc2VydmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjbGllbnRQcm92aWRlciwgU3RyaW5nIHNlcnZlclByb3ZpZGVyKSB7CisgICAgICAgIFN0cmluZyBwcm90b2NvbCA9ICJUTFMiOworICAgICAgICBTU0xDb250ZXh0IGNsaWVudENvbnRleHQgPSBjcmVhdGVTU0xDb250ZXh0KHByb3RvY29sLCBjbGllbnRQcm92aWRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnQua2V5TWFuYWdlcnMsIGNsaWVudC50cnVzdE1hbmFnZXJzKTsKKyAgICAgICAgU1NMQ29udGV4dCBzZXJ2ZXJDb250ZXh0ID0gY3JlYXRlU1NMQ29udGV4dChwcm90b2NvbCwgc2VydmVyUHJvdmlkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VydmVyLmtleU1hbmFnZXJzLCBzZXJ2ZXIudHJ1c3RNYW5hZ2Vycyk7CisgICAgICAgIHJldHVybiBjcmVhdGUoY2xpZW50LmtleVN0b3JlLCBjbGllbnQuc3RvcmVQYXNzd29yZCwKKyAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXIua2V5U3RvcmUsIHNlcnZlci5zdG9yZVBhc3N3b3JkLAorICAgICAgICAgICAgICAgICAgICAgIGNsaWVudC5rZXlNYW5hZ2Vyc1swXSwKKyAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXIua2V5TWFuYWdlcnNbMF0sCisgICAgICAgICAgICAgICAgICAgICAgY2xpZW50LnRydXN0TWFuYWdlcnNbMF0sCisgICAgICAgICAgICAgICAgICAgICAgc2VydmVyLnRydXN0TWFuYWdlcnNbMF0sCisgICAgICAgICAgICAgICAgICAgICAgY2xpZW50Q29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJDb250ZXh0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0U1NMQ29udGV4dCBjcmVhdGlvbiBtZXRob2QgdGhhdCBhbGxvd3Mgc2VwYXJhdGUgY3JlYXRpb24gb2YgY2xpZW50IGFuZCBzZXJ2ZXIga2V5IHN0b3JlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBUZXN0U1NMQ29udGV4dCBjcmVhdGUoS2V5U3RvcmUgY2xpZW50S2V5U3RvcmUsIGNoYXJbXSBjbGllbnRTdG9yZVBhc3N3b3JkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtleVN0b3JlIHNlcnZlcktleVN0b3JlLCBjaGFyW10gc2VydmVyU3RvcmVQYXNzd29yZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLZXlNYW5hZ2VyIGNsaWVudEtleU1hbmFnZXJzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtleU1hbmFnZXIgc2VydmVyS2V5TWFuYWdlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyIGNsaWVudFRydXN0TWFuYWdlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJ1c3RNYW5hZ2VyIHNlcnZlclRydXN0TWFuYWdlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMQ29udGV4dCBjbGllbnRDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTENvbnRleHQgc2VydmVyQ29udGV4dCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgU1NMU2VydmVyU29ja2V0IHNlcnZlclNvY2tldCA9IChTU0xTZXJ2ZXJTb2NrZXQpCisgICAgICAgICAgICAgICAgc2VydmVyQ29udGV4dC5nZXRTZXJ2ZXJTb2NrZXRGYWN0b3J5KCkuY3JlYXRlU2VydmVyU29ja2V0KDApOworICAgICAgICAgICAgSW5ldEFkZHJlc3MgaG9zdCA9IEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpOworICAgICAgICAgICAgaW50IHBvcnQgPSBzZXJ2ZXJTb2NrZXQuZ2V0TG9jYWxQb3J0KCk7CisKKyAgICAgICAgICAgIHJldHVybiBuZXcgVGVzdFNTTENvbnRleHQoY2xpZW50S2V5U3RvcmUsIGNsaWVudFN0b3JlUGFzc3dvcmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZlcktleVN0b3JlLCBzZXJ2ZXJTdG9yZVBhc3N3b3JkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoWDUwOUV4dGVuZGVkS2V5TWFuYWdlcikgY2xpZW50S2V5TWFuYWdlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChYNTA5RXh0ZW5kZWRLZXlNYW5hZ2VyKSBzZXJ2ZXJLZXlNYW5hZ2VycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFg1MDlUcnVzdE1hbmFnZXIpIGNsaWVudFRydXN0TWFuYWdlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChYNTA5VHJ1c3RNYW5hZ2VyKSBzZXJ2ZXJUcnVzdE1hbmFnZXJzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRDb250ZXh0LCBzZXJ2ZXJDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQsIGhvc3QsIHBvcnQpOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIFNTTENvbnRleHQgd2l0aCBhIEtleU1hbmFnZXIgdXNpbmcgdGhlIHByaXZhdGUga2V5IGFuZAorICAgICAqIGNlcnRpZmljYXRlIGNoYWluIGZyb20gdGhlIGdpdmVuIEtleVN0b3JlIGFuZCBhIFRydXN0TWFuYWdlcgorICAgICAqIHVzaW5nIHRoZSBjZXJ0aWZpY2F0ZXMgYXV0aG9yaXRpZXMgZnJvbSB0aGUgc2FtZSBLZXlTdG9yZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFNTTENvbnRleHQgY3JlYXRlU1NMQ29udGV4dChmaW5hbCBTdHJpbmcgcHJvdG9jb2wsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHByb3ZpZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEtleU1hbmFnZXJbXSBrZXlNYW5hZ2VycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBUcnVzdE1hbmFnZXJbXSB0cnVzdE1hbmFnZXJzKQorICAgIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNTTENvbnRleHQgY29udGV4dCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UocHJvdG9jb2wsIHByb3ZpZGVyKTsKKyAgICAgICAgICAgIGNvbnRleHQuaW5pdChrZXlNYW5hZ2VycywgdHJ1c3RNYW5hZ2VycywgbmV3IFNlY3VyZVJhbmRvbSgpKTsKKyAgICAgICAgICAgIHJldHVybiBjb250ZXh0OworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYXNzZXJ0Q2VydGlmaWNhdGVJbktleVN0b3JlKFByaW5jaXBhbCBwcmluY2lwYWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLZXlTdG9yZSBrZXlTdG9yZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzdWJqZWN0TmFtZSA9IHByaW5jaXBhbC5nZXROYW1lKCk7CisgICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChTdHJpbmcgYWxpYXM6IENvbGxlY3Rpb25zLmxpc3Qoa2V5U3RvcmUuYWxpYXNlcygpKSkgeworICAgICAgICAgICAgaWYgKCFrZXlTdG9yZS5pc0NlcnRpZmljYXRlRW50cnkoYWxpYXMpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGUga2V5U3RvcmVDZXJ0aWZpY2F0ZSA9IChYNTA5Q2VydGlmaWNhdGUpIGtleVN0b3JlLmdldENlcnRpZmljYXRlKGFsaWFzKTsKKyAgICAgICAgICAgIGlmIChzdWJqZWN0TmFtZS5lcXVhbHMoa2V5U3RvcmVDZXJ0aWZpY2F0ZS5nZXRTdWJqZWN0RE4oKS5nZXROYW1lKCkpKSB7CisgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoZm91bmQpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRDZXJ0aWZpY2F0ZUluS2V5U3RvcmUoQ2VydGlmaWNhdGUgY2VydGlmaWNhdGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLZXlTdG9yZSBrZXlTdG9yZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChTdHJpbmcgYWxpYXM6IENvbGxlY3Rpb25zLmxpc3Qoa2V5U3RvcmUuYWxpYXNlcygpKSkgeworICAgICAgICAgICAgaWYgKCFrZXlTdG9yZS5pc0NlcnRpZmljYXRlRW50cnkoYWxpYXMpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBrZXlTdG9yZUNlcnRpZmljYXRlID0ga2V5U3RvcmUuZ2V0Q2VydGlmaWNhdGUoYWxpYXMpOworICAgICAgICAgICAgaWYgKGNlcnRpZmljYXRlLmVxdWFscyhrZXlTdG9yZUNlcnRpZmljYXRlKSkgeworICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKGZvdW5kKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYXNzZXJ0U2VydmVyQ2VydGlmaWNhdGVDaGFpbihYNTA5VHJ1c3RNYW5hZ2VyIHRydXN0TWFuYWdlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZVtdIHNlcnZlckNoYWluKQorICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlW10gY2hhaW4gPSAoWDUwOUNlcnRpZmljYXRlW10pIHNlcnZlckNoYWluOworICAgICAgICB0cnVzdE1hbmFnZXIuY2hlY2tTZXJ2ZXJUcnVzdGVkKGNoYWluLCBjaGFpblswXS5nZXRQdWJsaWNLZXkoKS5nZXRBbGdvcml0aG0oKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydENsaWVudENlcnRpZmljYXRlQ2hhaW4oWDUwOVRydXN0TWFuYWdlciB0cnVzdE1hbmFnZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVbXSBjbGllbnRDaGFpbikKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZVtdIGNoYWluID0gKFg1MDlDZXJ0aWZpY2F0ZVtdKSBjbGllbnRDaGFpbjsKKyAgICAgICAgdHJ1c3RNYW5hZ2VyLmNoZWNrQ2xpZW50VHJ1c3RlZChjaGFpbiwgY2hhaW5bMF0uZ2V0UHVibGljS2V5KCkuZ2V0QWxnb3JpdGhtKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gU1NMU29ja2V0RmFjdG9yeSB0aGF0IGNhbGxzIHNldFdhbnRDbGllbnRBdXRoIGFuZAorICAgICAqIHNldE5lZWRDbGllbnRBdXRoIGFzIHNwZWNpZmllZCBvbiBhbGwgcmV0dXJuZWQgc29ja2V0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNTTFNvY2tldEZhY3RvcnkgY2xpZW50QXV0aChmaW5hbCBTU0xTb2NrZXRGYWN0b3J5IHNmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gd2FudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIG5lZWQpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTU0xTb2NrZXRGYWN0b3J5KCkgeworICAgICAgICAgICAgcHJpdmF0ZSBTU0xTb2NrZXQgc2V0KFNvY2tldCBzb2NrZXQpIHsKKyAgICAgICAgICAgICAgICBTU0xTb2NrZXQgcyA9IChTU0xTb2NrZXQpIHNvY2tldDsKKyAgICAgICAgICAgICAgICBzLnNldFdhbnRDbGllbnRBdXRoKHdhbnQpOworICAgICAgICAgICAgICAgIHMuc2V0TmVlZENsaWVudEF1dGgobmVlZCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldChTdHJpbmcgaG9zdCwgaW50IHBvcnQpCisgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgVW5rbm93bkhvc3RFeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiBzZXQoc2YuY3JlYXRlU29ja2V0KGhvc3QsIHBvcnQpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KFN0cmluZyBob3N0LCBpbnQgcG9ydCwgSW5ldEFkZHJlc3MgbG9jYWxIb3N0LCBpbnQgbG9jYWxQb3J0KQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc2V0KHNmLmNyZWF0ZVNvY2tldChob3N0LCBwb3J0LCBsb2NhbEhvc3QsIGxvY2FsUG9ydCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MgaG9zdCwgaW50IHBvcnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHNldChzZi5jcmVhdGVTb2NrZXQoaG9zdCwgcG9ydCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MgYWRkcmVzcywgaW50IHBvcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbEFkZHJlc3MsIGludCBsb2NhbFBvcnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHNldChzZi5jcmVhdGVTb2NrZXQoYWRkcmVzcywgcG9ydCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc2YuZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIFN0cmluZ1tdIGdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gc2YuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KFNvY2tldCBzLCBTdHJpbmcgaG9zdCwgaW50IHBvcnQsIGJvb2xlYW4gYXV0b0Nsb3NlKQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgIHJldHVybiBzZXQoc2YuY3JlYXRlU29ja2V0KHMsIGhvc3QsIHBvcnQsIGF1dG9DbG9zZSkpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvVGVzdFNTTEVuZ2luZVBhaXIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvVGVzdFNTTEVuZ2luZVBhaXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNmVmZGViCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL2xpYmNvcmUvamF2YXgvbmV0L3NzbC9UZXN0U1NMRW5naW5lUGFpci5qYXZhCkBAIC0wLDAgKzEsMTczIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBsaWJjb3JlLmphdmF4Lm5ldC5zc2w7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFbmdpbmU7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFbmdpbmVSZXN1bHQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFbmdpbmVSZXN1bHQuSGFuZHNoYWtlU3RhdHVzOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0OworCisvKioKKyAqIFRlc3RTU0xFbmdpbmVQYWlyIGlzIGEgY29udmVuaWVuY2UgY2xhc3MgZm9yIG90aGVyIHRlc3RzIHRoYXQgd2FudAorICogYSBwYWlyIG9mIGNvbm5lY3RlZCBhbmQgaGFuZHNoYWtlZCBjbGllbnQgYW5kIHNlcnZlciBTU0xFbmdpbmVzIGZvcgorICogdGVzdGluZy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFRlc3RTU0xFbmdpbmVQYWlyIGV4dGVuZHMgQXNzZXJ0IHsKKyAgICBwdWJsaWMgZmluYWwgVGVzdFNTTENvbnRleHQgYzsKKyAgICBwdWJsaWMgZmluYWwgU1NMRW5naW5lIHNlcnZlcjsKKyAgICBwdWJsaWMgZmluYWwgU1NMRW5naW5lIGNsaWVudDsKKworICAgIHByaXZhdGUgVGVzdFNTTEVuZ2luZVBhaXIoVGVzdFNTTENvbnRleHQgYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTTEVuZ2luZSBzZXJ2ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmUgY2xpZW50KSB7CisgICAgICAgIHRoaXMuYyA9IGM7CisgICAgICAgIHRoaXMuc2VydmVyID0gc2VydmVyOworICAgICAgICB0aGlzLmNsaWVudCA9IGNsaWVudDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFRlc3RTU0xFbmdpbmVQYWlyIGNyZWF0ZShIb29rcyBob29rcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGNyZWF0ZShUZXN0U1NMQ29udGV4dC5jcmVhdGUoKSwgaG9va3MpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgVGVzdFNTTEVuZ2luZVBhaXIgY3JlYXRlKFRlc3RTU0xDb250ZXh0IGMsIEhvb2tzIGhvb2tzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTU0xFbmdpbmVbXSBlbmdpbmVzID0gY29ubmVjdChjLCBob29rcyk7CisgICAgICAgIHJldHVybiBuZXcgVGVzdFNTTEVuZ2luZVBhaXIoYywgZW5naW5lc1swXSwgZW5naW5lc1sxXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IGNvbm5lY3RlZCBzZXJ2ZXIvY2xpZW50IGVuZ2luZSBwYWlyIHdpdGhpbiBhCisgICAgICogZXhpc3RpbmcgU1NMQ29udGV4dC4gT3B0aW9uYWxseSBzcGVjaWZ5IGNsaWVudENpcGhlclN1aXRlcyB0bworICAgICAqIGFsbG93IGZvcmNpbmcgbmV3IFNTTFNlc3Npb24gdG8gdGVzdCBTU0xTZXNzaW9uQ29udGV4dAorICAgICAqIGNhY2hpbmcuIE9wdGlvbmFsbHkgc3BlY2lmeSBzZXJ2ZXJDaXBoZXJTdWl0ZXMgZm9yIHRlc3RpbmcKKyAgICAgKiBjaXBoZXIgc3VpdGUgbmVnb3RpYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTU0xFbmdpbmVbXSBjb25uZWN0KGZpbmFsIFRlc3RTU0xDb250ZXh0IGMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhvb2tzIGhvb2tzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoaG9va3MgPT0gbnVsbCkgeworICAgICAgICAgICAgaG9va3MgPSBuZXcgSG9va3MoKTsKKyAgICAgICAgfQorCisgICAgICAgIFNTTFNlc3Npb24gc2Vzc2lvbiA9IGMuY2xpZW50Q29udGV4dC5jcmVhdGVTU0xFbmdpbmUoKS5nZXRTZXNzaW9uKCk7CisKKyAgICAgICAgaW50IHBhY2tldEJ1ZmZlclNpemUgPSBzZXNzaW9uLmdldFBhY2tldEJ1ZmZlclNpemUoKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBjbGllbnRUb1NlcnZlciA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUocGFja2V0QnVmZmVyU2l6ZSk7CisgICAgICAgIEJ5dGVCdWZmZXIgc2VydmVyVG9DbGllbnQgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKHBhY2tldEJ1ZmZlclNpemUpOworCisgICAgICAgIGludCBhcHBsaWNhdGlvbkJ1ZmZlclNpemUgPSBzZXNzaW9uLmdldEFwcGxpY2F0aW9uQnVmZmVyU2l6ZSgpOworICAgICAgICBCeXRlQnVmZmVyIHNjcmF0Y2ggPSBCeXRlQnVmZmVyLmFsbG9jYXRlKGFwcGxpY2F0aW9uQnVmZmVyU2l6ZSk7CisKKyAgICAgICAgU1NMRW5naW5lIGNsaWVudCA9IGMuY2xpZW50Q29udGV4dC5jcmVhdGVTU0xFbmdpbmUoKTsKKyAgICAgICAgU1NMRW5naW5lIHNlcnZlciA9IGMuc2VydmVyQ29udGV4dC5jcmVhdGVTU0xFbmdpbmUoKTsKKyAgICAgICAgY2xpZW50LnNldFVzZUNsaWVudE1vZGUodHJ1ZSk7CisgICAgICAgIHNlcnZlci5zZXRVc2VDbGllbnRNb2RlKGZhbHNlKTsKKyAgICAgICAgaG9va3MuYmVmb3JlQmVnaW5IYW5kc2hha2UoY2xpZW50LCBzZXJ2ZXIpOworICAgICAgICBjbGllbnQuYmVnaW5IYW5kc2hha2UoKTsKKyAgICAgICAgc2VydmVyLmJlZ2luSGFuZHNoYWtlKCk7CisKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIGJvb2xlYW4gY2xpZW50RG9uZSA9IGNsaWVudC5nZXRIYW5kc2hha2VTdGF0dXMoKSA9PSBIYW5kc2hha2VTdGF0dXMuTk9UX0hBTkRTSEFLSU5HOworICAgICAgICAgICAgYm9vbGVhbiBzZXJ2ZXJEb25lID0gc2VydmVyLmdldEhhbmRzaGFrZVN0YXR1cygpID09IEhhbmRzaGFrZVN0YXR1cy5OT1RfSEFORFNIQUtJTkc7CisgICAgICAgICAgICBpZiAoY2xpZW50RG9uZSAmJiBzZXJ2ZXJEb25lKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGJvb2xlYW4gcHJvZ3Jlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIGlmICghY2xpZW50RG9uZSkgeworICAgICAgICAgICAgICAgIHByb2dyZXNzIHw9IGhhbmRzaGFrZUNvbXBsZXRlZChjbGllbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudFRvU2VydmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJUb0NsaWVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NyYXRjaCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIXNlcnZlckRvbmUpIHsKKyAgICAgICAgICAgICAgICBwcm9ncmVzcyB8PSBoYW5kc2hha2VDb21wbGV0ZWQoc2VydmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJUb0NsaWVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50VG9TZXJ2ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcmF0Y2gpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFwcm9ncmVzcykgeworICAgICAgICAgICAgICAgIC8vIGxldCBjYWxsZXIgZGV0ZWN0IHRoZSBwcm9ibGVtLCBidXQgZG9uJ3QganVzdCBoYW5nIGhlcmUKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgU1NMRW5naW5lW10geyBzZXJ2ZXIsIGNsaWVudCB9OworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSG9va3MgeworICAgICAgICB2b2lkIGJlZm9yZUJlZ2luSGFuZHNoYWtlKFNTTEVuZ2luZSBjbGllbnQsIFNTTEVuZ2luZSBzZXJ2ZXIpIHt9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQnl0ZUJ1ZmZlciBFTVBUWV9CWVRFX0JVRkZFUiA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoMCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGhhbmRzaGFrZUNvbXBsZXRlZChTU0xFbmdpbmUgZW5naW5lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5dGVCdWZmZXIgb3V0cHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5dGVCdWZmZXIgaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnl0ZUJ1ZmZlciBzY3JhdGNoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gbWFrZSB0aGUgb3RoZXIgc2lkZSdzIG91dHB1dCBpbnRvIG91ciBpbnB1dAorICAgICAgICAgICAgaW5wdXQuZmxpcCgpOworCisgICAgICAgICAgICBIYW5kc2hha2VTdGF0dXMgc3RhdHVzID0gZW5naW5lLmdldEhhbmRzaGFrZVN0YXR1cygpOworICAgICAgICAgICAgc3dpdGNoIChzdGF0dXMpIHsKKworICAgICAgICAgICAgICAgIGNhc2UgTkVFRF9UQVNLOgorICAgICAgICAgICAgICAgICAgICBib29sZWFuIHByb2dyZXNzID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBSdW5uYWJsZSBydW5uYWJsZSA9IGVuZ2luZS5nZXREZWxlZ2F0ZWRUYXNrKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocnVubmFibGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwcm9ncmVzczsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHJ1bm5hYmxlLnJ1bigpOworICAgICAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3MgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBjYXNlIE5FRURfVU5XUkFQOgorICAgICAgICAgICAgICAgICAgICAvLyBhdm9pZCB1bmRlcmZsb3cKKyAgICAgICAgICAgICAgICAgICAgaWYgKGlucHV0LnJlbWFpbmluZygpID09IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBTU0xFbmdpbmVSZXN1bHQgdW53cmFwUmVzdWx0ID0gZW5naW5lLnVud3JhcChpbnB1dCwgc2NyYXRjaCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhTU0xFbmdpbmVSZXN1bHQuU3RhdHVzLk9LLCB1bndyYXBSZXN1bHQuZ2V0U3RhdHVzKCkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgc2NyYXRjaC5wb3NpdGlvbigpKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisKKyAgICAgICAgICAgICAgICBjYXNlIE5FRURfV1JBUDoKKyAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgcG9zc2libGUgb3ZlcmZsb3cKKyAgICAgICAgICAgICAgICAgICAgaWYgKG91dHB1dC5yZW1haW5pbmcoKSAhPSBvdXRwdXQuY2FwYWNpdHkoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIFNTTEVuZ2luZVJlc3VsdCB3cmFwUmVzdWx0ID0gZW5naW5lLndyYXAoRU1QVFlfQllURV9CVUZGRVIsIG91dHB1dCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhTU0xFbmdpbmVSZXN1bHQuU3RhdHVzLk9LLCB3cmFwUmVzdWx0LmdldFN0YXR1cygpKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisKKyAgICAgICAgICAgICAgICBjYXNlIE5PVF9IQU5EU0hBS0lORzoKKyAgICAgICAgICAgICAgICAgICAgLy8gc2hvdWxkIGhhdmUgYmVlbiBjaGVja2VkIGJ5IGNhbGxlciBiZWZvcmUgY2FsbGluZworICAgICAgICAgICAgICAgIGNhc2UgRklOSVNIRUQ6CisgICAgICAgICAgICAgICAgICAgIC8vIG9ubHkgcmV0dXJuZWQgYnkgd3JhcC91bnJhcCBzdGF0dXMsIG5vdCBnZXRIYW5kc2hha2VTdGF0dXMKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBIYW5kc2hha2VTdGF0dXMgPSAiICsgc3RhdHVzKTsKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJVbmtub3duIEhhbmRzaGFrZVN0YXR1cyA9ICIgKyBzdGF0dXMpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgLy8gc2hpZnQgY29uc3VtZWQgaW5wdXQsIHJlc3RvcmUgdG8gb3V0cHV0IG1vZGUKKyAgICAgICAgICAgIGlucHV0LmNvbXBhY3QoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvVGVzdFNTTFNlc3Npb25zLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL1Rlc3RTU0xTZXNzaW9ucy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmMDI3ZGIKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL1Rlc3RTU0xTZXNzaW9ucy5qYXZhCkBAIC0wLDAgKzEsNzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIGxpYmNvcmUuamF2YXgubmV0LnNzbDsKKworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3Rvcnk7CisKKy8qKgorICogVGVzdFNTTFNlc3Npb25zIGlzIGEgY29udmVuaWVuY2UgY2xhc3MgZm9yIG90aGVyIHRlc3RzIHRoYXQgd2FudAorICogcHJlY3JlYXRlZCBTU0xTZXNzaW9ucyBmb3IgdGVzdGluZy4gSXQgY29udGFpbnMgYSBjb25uZWN0ZWQKKyAqIGNsaWVudC9zZXJ2ZXIgcGFpciBvZiBTU0xTZXNzaW9uIGFzIHdlbGwgYXMgYW4gaW52YWxpZCBTU0xTZXNzaW9uLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgVGVzdFNTTFNlc3Npb25zIHsKKworICAgIC8qKgorICAgICAqIEFuIGludmFsaWQgc2Vzc2lvbiB0aGF0IGlzIG5vdCBjb25uZWN0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU1NMU2Vzc2lvbiBpbnZhbGlkOworCisgICAgLyoqCisgICAgICogVGhlIHNlcnZlciBzaWRlIG9mIGEgY29ubmVjdGVkIHNlc3Npb24KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgU1NMU2Vzc2lvbiBzZXJ2ZXI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY2xpZW50IHNpZGUgb2YgYSBjb25uZWN0ZWQgc2Vzc2lvbgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBTU0xTZXNzaW9uIGNsaWVudDsKKworICAgIC8qKgorICAgICAqIFRoZSBhc3NvY2lhdGVkIFNTTFNvY2tldFRlc3QuSGVscGVyIHRoYXQgaXMgdGhlIHNvdXJjZSBvZgorICAgICAqIHRoZSBjbGllbnQgYW5kIHNlcnZlciBTU0xTZXNzaW9ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgVGVzdFNTTFNvY2tldFBhaXIgczsKKworICAgIHByaXZhdGUgVGVzdFNTTFNlc3Npb25zKFNTTFNlc3Npb24gaW52YWxpZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xTZXNzaW9uIHNlcnZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xTZXNzaW9uIGNsaWVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBUZXN0U1NMU29ja2V0UGFpciBzKSB7CisgICAgICAgIHRoaXMuaW52YWxpZCA9IGludmFsaWQ7CisgICAgICAgIHRoaXMuc2VydmVyID0gc2VydmVyOworICAgICAgICB0aGlzLmNsaWVudCA9IGNsaWVudDsKKyAgICAgICAgdGhpcy5zID0gczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICAgICAgcy5jbG9zZSgpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVGVzdFNTTFNlc3Npb25zIGNyZWF0ZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFNTTFNvY2tldEZhY3Rvcnkgc2YgPSAoU1NMU29ja2V0RmFjdG9yeSkgU1NMU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCk7CisgICAgICAgICAgICBTU0xTb2NrZXQgc3NsID0gKFNTTFNvY2tldCkgc2YuY3JlYXRlU29ja2V0KCk7CisgICAgICAgICAgICBTU0xTZXNzaW9uIGludmFsaWQgPSBzc2wuZ2V0U2Vzc2lvbigpOworICAgICAgICAgICAgVGVzdFNTTFNvY2tldFBhaXIgcyA9IFRlc3RTU0xTb2NrZXRQYWlyLmNyZWF0ZSgpOworICAgICAgICAgICAgcmV0dXJuIG5ldyBUZXN0U1NMU2Vzc2lvbnMoaW52YWxpZCwgcy5zZXJ2ZXIuZ2V0U2Vzc2lvbigpLCBzLmNsaWVudC5nZXRTZXNzaW9uKCksIHMpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL1Rlc3RTU0xTb2NrZXRQYWlyLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL1Rlc3RTU0xTb2NrZXRQYWlyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTVjZTNiYgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvVGVzdFNTTFNvY2tldFBhaXIuamF2YQpAQCAtMCwwICsxLDEzMiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ2FsbGFibGU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcnM7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRnV0dXJlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0OworCisvKioKKyAqIFRlc3RTU0xTb2NrZXRQYWlyIGlzIGEgY29udmVuaWVuY2UgY2xhc3MgZm9yIG90aGVyIHRlc3RzIHRoYXQgd2FudAorICogYSBwYWlyIG9mIGNvbm5lY3RlZCBhbmQgaGFuZHNoYWtlZCBjbGllbnQgYW5kIHNlcnZlciBTU0xTb2NrZXRzIGZvcgorICogdGVzdGluZy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFRlc3RTU0xTb2NrZXRQYWlyIHsKKyAgICBwdWJsaWMgZmluYWwgVGVzdFNTTENvbnRleHQgYzsKKyAgICBwdWJsaWMgZmluYWwgU1NMU29ja2V0IHNlcnZlcjsKKyAgICBwdWJsaWMgZmluYWwgU1NMU29ja2V0IGNsaWVudDsKKworICAgIHByaXZhdGUgVGVzdFNTTFNvY2tldFBhaXIgKFRlc3RTU0xDb250ZXh0IGMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NMU29ja2V0IHNlcnZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTU0xTb2NrZXQgY2xpZW50KSB7CisgICAgICAgIHRoaXMuYyA9IGM7CisgICAgICAgIHRoaXMuc2VydmVyID0gc2VydmVyOworICAgICAgICB0aGlzLmNsaWVudCA9IGNsaWVudDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICAgICAgYy5jbG9zZSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VydmVyLmNsb3NlKCk7CisgICAgICAgICAgICBjbGllbnQuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogYmFzZWQgb24gdGVzdF9TU0xTb2NrZXRfc3RhcnRIYW5kc2hha2UKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFRlc3RTU0xTb2NrZXRQYWlyIGNyZWF0ZSAoKSB7CisgICAgICAgIFRlc3RTU0xDb250ZXh0IGMgPSBUZXN0U1NMQ29udGV4dC5jcmVhdGUoKTsKKyAgICAgICAgU1NMU29ja2V0W10gc29ja2V0cyA9IGNvbm5lY3QoYywgbnVsbCwgbnVsbCk7CisgICAgICAgIHJldHVybiBuZXcgVGVzdFNTTFNvY2tldFBhaXIoYywgc29ja2V0c1swXSwgc29ja2V0c1sxXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IGNvbm5lY3RlZCBzZXJ2ZXIvY2xpZW50IHNvY2tldCBwYWlyIHdpdGhpbiBhCisgICAgICogZXhpc3RpbmcgU1NMQ29udGV4dC4gT3B0aW9uYWxseSBzcGVjaWZ5IGNsaWVudENpcGhlclN1aXRlcyB0bworICAgICAqIGFsbG93IGZvcmNpbmcgbmV3IFNTTFNlc3Npb24gdG8gdGVzdCBTU0xTZXNzaW9uQ29udGV4dAorICAgICAqIGNhY2hpbmcuIE9wdGlvbmFsbHkgc3BlY2lmeSBzZXJ2ZXJDaXBoZXJTdWl0ZXMgZm9yIHRlc3RpbmcKKyAgICAgKiBjaXBoZXIgc3VpdGUgbmVnb3RpYXRpb24uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTU0xTb2NrZXRbXSBjb25uZWN0IChmaW5hbCBUZXN0U1NMQ29udGV4dCBjb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nW10gY2xpZW50Q2lwaGVyU3VpdGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nW10gc2VydmVyQ2lwaGVyU3VpdGVzKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBTU0xTb2NrZXQgY2xpZW50ID0gKFNTTFNvY2tldCkKKyAgICAgICAgICAgICAgICBjb250ZXh0LmNsaWVudENvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpLmNyZWF0ZVNvY2tldChjb250ZXh0Lmhvc3QsIGNvbnRleHQucG9ydCk7CisgICAgICAgICAgICBmaW5hbCBTU0xTb2NrZXQgc2VydmVyID0gKFNTTFNvY2tldCkgY29udGV4dC5zZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisKKyAgICAgICAgICAgIEV4ZWN1dG9yU2VydmljZSBleGVjdXRvciA9IEV4ZWN1dG9ycy5uZXdGaXhlZFRocmVhZFBvb2woMik7CisgICAgICAgICAgICBGdXR1cmUgcyA9IGV4ZWN1dG9yLnN1Ym1pdChuZXcgQ2FsbGFibGU8Vm9pZD4oKSB7CisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBWb2lkIGNhbGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZXJ2ZXJDaXBoZXJTdWl0ZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZlci5zZXRFbmFibGVkQ2lwaGVyU3VpdGVzKHNlcnZlckNpcGhlclN1aXRlcyk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXIuc3RhcnRIYW5kc2hha2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSk7CisgICAgICAgICAgICBGdXR1cmUgYyA9IGV4ZWN1dG9yLnN1Ym1pdChuZXcgQ2FsbGFibGU8Vm9pZD4oKSB7CisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBWb2lkIGNhbGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjbGllbnRDaXBoZXJTdWl0ZXMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudC5zZXRFbmFibGVkQ2lwaGVyU3VpdGVzKGNsaWVudENpcGhlclN1aXRlcyk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnQuc3RhcnRIYW5kc2hha2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSk7CisgICAgICAgICAgICBleGVjdXRvci5zaHV0ZG93bigpOworCisgICAgICAgICAgICAvLyBjYXRjaCBjbGllbnQgYW5kIHNlcnZlciBleGNlcHRpb25zIHNlcGFyYXRlbHkgc28gd2UgY2FuCisgICAgICAgICAgICAvLyBwb3RlbnRpYWxseSBsb2cgYm90aC4KKyAgICAgICAgICAgIEV4Y2VwdGlvbiBzZXJ2ZXJFeGNlcHRpb247CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHMuZ2V0KDMwLCBUaW1lVW5pdC5TRUNPTkRTKTsKKyAgICAgICAgICAgICAgICBzZXJ2ZXJFeGNlcHRpb24gPSBudWxsOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXJFeGNlcHRpb24gPSBlOworICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBFeGNlcHRpb24gY2xpZW50RXhjZXB0aW9uOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjLmdldCgzMCwgVGltZVVuaXQuU0VDT05EUyk7CisgICAgICAgICAgICAgICAgY2xpZW50RXhjZXB0aW9uID0gbnVsbDsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgY2xpZW50RXhjZXB0aW9uID0gZTsKKyAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHNlcnZlckV4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgc2VydmVyRXhjZXB0aW9uOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGNsaWVudEV4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgY2xpZW50RXhjZXB0aW9uOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG5ldyBTU0xTb2NrZXRbXSB7IHNlcnZlciwgY2xpZW50IH07CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL1Rlc3RUcnVzdE1hbmFnZXIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9saWJjb3JlL2phdmF4L25ldC9zc2wvVGVzdFRydXN0TWFuYWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMzNTExYjQKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvbGliY29yZS9qYXZheC9uZXQvc3NsL1Rlc3RUcnVzdE1hbmFnZXIuamF2YQpAQCAtMCwwICsxLDExNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgbGliY29yZS5qYXZheC5uZXQuc3NsOworCitpbXBvcnQgamF2YS5pby5QcmludFN0cmVhbTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlg1MDlUcnVzdE1hbmFnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CitpbXBvcnQgbGliY29yZS5qYXZhLmlvLk51bGxQcmludFN0cmVhbTsKK2ltcG9ydCBsaWJjb3JlLmphdmEuc2VjdXJpdHkuU3RhbmRhcmROYW1lczsKKworLyoqCisgKiBUZXN0VHJ1c3RNYW5hZ2VyIGlzIGEgc2ltcGxlIHByb3h5IGNsYXNzIHRoYXQgd3JhcHMgYW4gZXhpc3RpbmcKKyAqIFg1MDlUcnVzdE1hbmFnZXIgdG8gcHJvdmlkZSBkZWJ1ZyBsb2dnaW5nIGFuZCByZWNvcmRpbmcgb2YKKyAqIHZhbHVlcy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFRlc3RUcnVzdE1hbmFnZXIgaW1wbGVtZW50cyBYNTA5VHJ1c3RNYW5hZ2VyIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gTE9HID0gZmFsc2U7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUHJpbnRTdHJlYW0gb3V0ID0gTE9HID8gU3lzdGVtLm91dCA6IG5ldyBOdWxsUHJpbnRTdHJlYW0oKTsKKworICAgIHByaXZhdGUgZmluYWwgWDUwOVRydXN0TWFuYWdlciB0cnVzdE1hbmFnZXI7CisKKyAgICBwdWJsaWMgc3RhdGljIFRydXN0TWFuYWdlcltdIHdyYXAoVHJ1c3RNYW5hZ2VyW10gdHJ1c3RNYW5hZ2VycykgeworICAgICAgICBUcnVzdE1hbmFnZXJbXSByZXN1bHQgPSB0cnVzdE1hbmFnZXJzLmNsb25lKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVzdWx0Lmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICByZXN1bHRbaV0gPSB3cmFwKHJlc3VsdFtpXSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFRydXN0TWFuYWdlciB3cmFwKFRydXN0TWFuYWdlciB0cnVzdE1hbmFnZXIpIHsKKyAgICAgICAgaWYgKCEodHJ1c3RNYW5hZ2VyIGluc3RhbmNlb2YgWDUwOVRydXN0TWFuYWdlcikpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVzdE1hbmFnZXI7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBUZXN0VHJ1c3RNYW5hZ2VyKChYNTA5VHJ1c3RNYW5hZ2VyKSB0cnVzdE1hbmFnZXIpOworICAgIH0KKworICAgIHB1YmxpYyBUZXN0VHJ1c3RNYW5hZ2VyKFg1MDlUcnVzdE1hbmFnZXIgdHJ1c3RNYW5hZ2VyKSB7CisgICAgICAgIG91dC5wcmludGxuKCJUZXN0VHJ1c3RNYW5hZ2VyLjxpbml0PiB0cnVzdE1hbmFnZXI9IiArIHRydXN0TWFuYWdlcik7CisgICAgICAgIHRoaXMudHJ1c3RNYW5hZ2VyID0gdHJ1c3RNYW5hZ2VyOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrQ2xpZW50VHJ1c3RlZChYNTA5Q2VydGlmaWNhdGVbXSBjaGFpbiwgU3RyaW5nIGF1dGhUeXBlKQorICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LnByaW50KCJUZXN0VHJ1c3RNYW5hZ2VyLmNoZWNrQ2xpZW50VHJ1c3RlZCAiCisgICAgICAgICAgICAgICAgICArICJjaGFpbj0iICsgY2hhaW4ubGVuZ3RoICsgIiAiCisgICAgICAgICAgICAgICAgICArICJhdXRoVHlwZT0iICsgYXV0aFR5cGUgKyAiICIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0Q2xpZW50QXV0aFR5cGUoYXV0aFR5cGUpOworICAgICAgICAgICAgdHJ1c3RNYW5hZ2VyLmNoZWNrQ2xpZW50VHJ1c3RlZChjaGFpbiwgYXV0aFR5cGUpOworICAgICAgICAgICAgb3V0LnByaW50bG4oIk9LIik7CisgICAgICAgIH0gY2F0Y2ggKENlcnRpZmljYXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKG91dCk7CisgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydENsaWVudEF1dGhUeXBlKFN0cmluZyBhdXRoVHlwZSkgeworICAgICAgICBpZiAoIVN0YW5kYXJkTmFtZXMuQ0xJRU5UX0FVVEhfVFlQRVMuY29udGFpbnMoYXV0aFR5cGUpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIlVuZXhwZWN0ZWQgY2xpZW50IGF1dGggdHlwZSAiICsgYXV0aFR5cGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY2hlY2tTZXJ2ZXJUcnVzdGVkKFg1MDlDZXJ0aWZpY2F0ZVtdIGNoYWluLCBTdHJpbmcgYXV0aFR5cGUpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBvdXQucHJpbnQoIlRlc3RUcnVzdE1hbmFnZXIuY2hlY2tTZXJ2ZXJUcnVzdGVkICIKKyAgICAgICAgICAgICAgICAgICsgImNoYWluPSIgKyBjaGFpbi5sZW5ndGggKyAiICIKKyAgICAgICAgICAgICAgICAgICsgImF1dGhUeXBlPSIgKyBhdXRoVHlwZSArICIgIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRTZXJ2ZXJBdXRoVHlwZShhdXRoVHlwZSk7CisgICAgICAgICAgICB0cnVzdE1hbmFnZXIuY2hlY2tTZXJ2ZXJUcnVzdGVkKGNoYWluLCBhdXRoVHlwZSk7CisgICAgICAgICAgICBvdXQucHJpbnRsbigiT0siKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2Uob3V0KTsKKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0U2VydmVyQXV0aFR5cGUoU3RyaW5nIGF1dGhUeXBlKSB7CisgICAgICAgIGlmICghU3RhbmRhcmROYW1lcy5TRVJWRVJfQVVUSF9UWVBFUy5jb250YWlucyhhdXRoVHlwZSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiVW5leHBlY3RlZCBzZXJ2ZXIgYXV0aCB0eXBlICIgKyBhdXRoVHlwZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIGNlcnRpZmljYXRlIGlzc3VlciBhdXRob3JpdGllcyB3aGljaCBhcmUgdHJ1c3RlZCBmb3IKKyAgICAgKiBhdXRoZW50aWNhdGlvbiBvZiBwZWVycy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxpc3Qgb2YgY2VydGlmaWNhdGUgaXNzdWVyIGF1dGhvcml0aWVzIHdoaWNoIGFyZSB0cnVzdGVkIGZvcgorICAgICAqICAgICAgICAgYXV0aGVudGljYXRpb24gb2YgcGVlcnMuCisgICAgICovCisgICAgcHVibGljIFg1MDlDZXJ0aWZpY2F0ZVtdIGdldEFjY2VwdGVkSXNzdWVycygpIHsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlW10gcmVzdWx0ID0gdHJ1c3RNYW5hZ2VyLmdldEFjY2VwdGVkSXNzdWVycygpOworICAgICAgICBvdXQucHJpbnQoIlRlc3RUcnVzdE1hbmFnZXIuZ2V0QWNjZXB0ZWRJc3N1ZXJzIHJlc3VsdD0iICsgcmVzdWx0Lmxlbmd0aCk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvQ2VydGlmaWNhdGVTdHViLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvQ2VydGlmaWNhdGVTdHViLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzJlY2Q0MQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9DZXJ0aWZpY2F0ZVN0dWIuamF2YQpAQCAtMCwwICsxLDEwOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxla3NlaSBZLiBTZW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKKworLyoqCisgKiBTdHViIGZvciBpbnRlcmZhY2UgQ2VydGlmaWNhdGUsIG5lY2Vzc2FyeSBmb3IgdGVzdGluZworICovCitAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorcHVibGljIGNsYXNzIENlcnRpZmljYXRlU3R1YiBpbXBsZW1lbnRzIENlcnRpZmljYXRlIHsKKworICAgIFN0cmluZyBmb3JtYXQ7CisgICAgUHJpbmNpcGFsIGd1YXJhbnRvcjsKKyAgICBQcmluY2lwYWwgcHJpbmNpcGFsOworICAgIFB1YmxpY0tleSBrZXk7CisKKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVTdHViKFN0cmluZyBmb3JtYXQsIFByaW5jaXBhbCBndWFyYW50b3IsIFByaW5jaXBhbCBwcmluY2lwYWwsIFB1YmxpY0tleSBrZXkpeworICAgICAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDsKKyAgICAgICAgdGhpcy5ndWFyYW50b3IgPSBndWFyYW50b3I7CisgICAgICAgIHRoaXMucHJpbmNpcGFsID0gcHJpbmNpcGFsOworICAgICAgICB0aGlzLmtleSA9IGtleTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdHViIC0gZG9lcyBub3RoaW5nCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LkNlcnRpZmljYXRlI2RlY29kZShqYXZhLmlvLklucHV0U3RyZWFtKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRlY29kZShJbnB1dFN0cmVhbSBzdHJlYW0pIHRocm93cyBLZXlFeGNlcHRpb24sCisgICAgICAgICAgICBJT0V4Y2VwdGlvbiB7CisKKworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0dWIgLSBkb2VzIG5vdGhpbmcKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuQ2VydGlmaWNhdGUjZW5jb2RlKGphdmEuaW8uT3V0cHV0U3RyZWFtKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVuY29kZShPdXRwdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgSU9FeGNlcHRpb24geworCisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuQ2VydGlmaWNhdGUjZ2V0Rm9ybWF0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKworICAgICAgICByZXR1cm4gZm9ybWF0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5DZXJ0aWZpY2F0ZSNnZXRHdWFyYW50b3IoKQorICAgICAqLworICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0R3VhcmFudG9yKCkgeworCisgICAgICAgIHJldHVybiBndWFyYW50b3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LkNlcnRpZmljYXRlI2dldFByaW5jaXBhbCgpCisgICAgICovCisgICAgcHVibGljIFByaW5jaXBhbCBnZXRQcmluY2lwYWwoKSB7CisgICAgICAgIHJldHVybiBwcmluY2lwYWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LkNlcnRpZmljYXRlI2dldFB1YmxpY0tleSgpCisgICAgICovCisgICAgcHVibGljIFB1YmxpY0tleSBnZXRQdWJsaWNLZXkoKSB7CisgICAgICAgIHJldHVybiBrZXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3R1YiAtIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4KKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuQ2VydGlmaWNhdGUjdG9TdHJpbmcoYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGJvb2xlYW4gZGV0YWlsZWQpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvSWRlbnRpdHlTY29wZVN0dWIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9JZGVudGl0eVNjb3BlU3R1Yi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA2MTgyMGMKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvSWRlbnRpdHlTY29wZVN0dWIuamF2YQpAQCAtMCwwICsxLDEyNSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxla3NlaSBZLiBTZW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LklkZW50aXR5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuSWRlbnRpdHlTY29wZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleU1hbmFnZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworCisvKioKKyAqIFRoaXMgaXMgc3R1YiBpbXBsZW1lbnRhdGlvbiBvZiBJZGVudGl0eVNjb3BlIGZvciB0ZXN0aW5nIHB1cnBvc2VzCisgKi8KK0BTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCitwdWJsaWMgY2xhc3MgSWRlbnRpdHlTY29wZVN0dWIgZXh0ZW5kcyBJZGVudGl0eVNjb3BlIHsKKworCisgICAgLyoqCisgICAgICogU3R1YiBjb25zdHJ1Y3RvcgorICAgICAqLworICAgIHB1YmxpYyBJZGVudGl0eVNjb3BlU3R1YigpIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdHViIGNvbnN0cnVjdG9yCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgSWRlbnRpdHlTY29wZVN0dWIoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgc3VwZXIobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3R1YiBjb25zdHJ1Y3RvcgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogQHBhcmFtIHNjb3BlCisgICAgICogQHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIElkZW50aXR5U2NvcGVTdHViKFN0cmluZyBuYW1lLCBJZGVudGl0eVNjb3BlIHNjb3BlKQorICAgICAgICAgICAgdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24geworICAgICAgICBzdXBlcihuYW1lLCBzY29wZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3R1YiAtIHJldHVybnMgMAorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5JZGVudGl0eVNjb3BlI3NpemUoKQorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdHViIC0gcmV0dXJucyA8Y29kZT50aGlzPC9jb2RlPgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5JZGVudGl0eVNjb3BlI2dldElkZW50aXR5KGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIElkZW50aXR5IGdldElkZW50aXR5KFN0cmluZyBuYW1lKSB7CisKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3R1YiAtIHJldHVybnMgPGNvZGU+dGhpczwvY29kZT4KKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuSWRlbnRpdHlTY29wZSNnZXRJZGVudGl0eShqYXZhLnNlY3VyaXR5LlB1YmxpY0tleSkKKyAgICAgKi8KKyAgICBwdWJsaWMgSWRlbnRpdHkgZ2V0SWRlbnRpdHkoUHVibGljS2V5IGtleSkgeworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdHViIC0gZG9lcyBub3RoaW5nCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LklkZW50aXR5U2NvcGUjYWRkSWRlbnRpdHkoamF2YS5zZWN1cml0eS5JZGVudGl0eSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRJZGVudGl0eShJZGVudGl0eSBpZGVudGl0eSkgdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24geworCisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdHViIC0gZG9lcyBub3RoaW5nCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LklkZW50aXR5U2NvcGUjcmVtb3ZlSWRlbnRpdHkoamF2YS5zZWN1cml0eS5JZGVudGl0eSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVJZGVudGl0eShJZGVudGl0eSBpZGVudGl0eSkgdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb24geworCisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdHViIC0gcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5JZGVudGl0eVNjb3BlI2lkZW50aXRpZXMoKQorICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBpZGVudGl0aWVzKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBzeXN0ZW0ncyBpZGVudGl0eSBzY29wZQorICAgICAqIEBwYXJhbSBzY29wZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBteVNldFN5c3RlbVNjb3BlKElkZW50aXR5U2NvcGUgc2NvcGUpIHsKKworICAgICAgICBJZGVudGl0eVNjb3BlLnNldFN5c3RlbVNjb3BlKHNjb3BlKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9JZGVudGl0eVN0dWIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9JZGVudGl0eVN0dWIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MjBhMzY1Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L0lkZW50aXR5U3R1Yi5qYXZhCkBAIC0wLDAgKzEsODQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZWtzZWkgWS4gU2VtZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JZGVudGl0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LklkZW50aXR5U2NvcGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlNYW5hZ2VtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworCisvKioKKyAqIFN0dWIgZm9yIGFic3RyYWN0IGNsYXNzIElkZW50aXR5CisgKgorICovCitAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorcHVibGljIGNsYXNzIElkZW50aXR5U3R1YiBleHRlbmRzIElkZW50aXR5IHsKKworICAgIC8qKgorICAgICAqICBEZWZhdWx0IGNvbnN0cnVjdG9yCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgSWRlbnRpdHlTdHViKCkgeworICAgICAgICBzdXBlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRPRE8gUHV0IGN0b3IgZGVzY3JpcHRpb24gaGVyZQorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHB1YmxpYyBJZGVudGl0eVN0dWIoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgc3VwZXIobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVE9ETyBQdXQgY3RvciBkZXNjcmlwdGlvbiBoZXJlCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqIEBwYXJhbSBzY29wZQorICAgICAqIEB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCisgICAgcHVibGljIElkZW50aXR5U3R1YihTdHJpbmcgbmFtZSwgSWRlbnRpdHlTY29wZSBzY29wZSkKKyAgICAgICAgICAgIHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIobmFtZSwgc2NvcGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEF1eGlsaWFyeSBjb25zdHJ1Y3RvcgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogQHBhcmFtIGtleQorICAgICAqIEB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCisgICAgcHVibGljIElkZW50aXR5U3R1YihTdHJpbmcgbmFtZSwgUHVibGljS2V5IGtleSkgdGhyb3dzIEtleU1hbmFnZW1lbnRFeGNlcHRpb257CisgICAgICAgIHRoaXMobmFtZSk7CisgICAgICAgIHNldFB1YmxpY0tleShrZXkpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCisgICAgcHVibGljIGJvb2xlYW4gaWRlbnRpdHlFcXVhbHMoSWRlbnRpdHkgaWRlbnRpdHkpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmlkZW50aXR5RXF1YWxzKGlkZW50aXR5KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvS2V5U3RvcmVUZXN0U3VwcG9ydC5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L0tleVN0b3JlVGVzdFN1cHBvcnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MmJhYjQzCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L0tleVN0b3JlVGVzdFN1cHBvcnQuamF2YQpAQCAtMCwwICsxLDE3NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKKworaW1wb3J0IGphdmF4LmNyeXB0by5TZWNyZXRLZXk7CisKKy8qKgorICogU3VwcG9ydCBjbGFzcyBmb3IgS2V5U3RvcmUgdGVzdHMKKyAqCisgKi8KKworcHVibGljIGNsYXNzIEtleVN0b3JlVGVzdFN1cHBvcnQgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgc3J2S2V5U3RvcmUgPSAiS2V5U3RvcmUiOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmdbXSB2YWxpZFZhbHVlcyA9IHsgImJrcyIsICJCS1MiLCAiYktTIiwgIkJrcyIsICJiS3MiLAorICAgICAgICAgICAgIkJrUyIgfTsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGRlZmF1bHRUeXBlID0gImJrcyI7CisKKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gSktTU3VwcG9ydGVkID0gZmFsc2U7CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBkZWZhdWx0UHJvdmlkZXJOYW1lID0gbnVsbDsKKworICAgIHB1YmxpYyBzdGF0aWMgUHJvdmlkZXIgZGVmYXVsdFByb3ZpZGVyID0gbnVsbDsKKworICAgIHN0YXRpYyB7CisgICAgICAgIGRlZmF1bHRQcm92aWRlciA9IFNwaUVuZ1V0aWxzLmlzU3VwcG9ydChkZWZhdWx0VHlwZSwgc3J2S2V5U3RvcmUpOworICAgICAgICBKS1NTdXBwb3J0ZWQgPSAoZGVmYXVsdFByb3ZpZGVyICE9IG51bGwpOworICAgICAgICBkZWZhdWx0UHJvdmlkZXJOYW1lID0gKEpLU1N1cHBvcnRlZCA/IGRlZmF1bHRQcm92aWRlci5nZXROYW1lKCkgOiBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRpdGlvbmFsIGNsYXNzIHRvIGNyZWF0ZSBTZWNyZXRLZXkgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBTS2V5IGltcGxlbWVudHMgU2VjcmV0S2V5IHsKKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgdHlwZTsKKworICAgICAgICBwcml2YXRlIGJ5dGVbXSBlbmNvZGVkOworCisgICAgICAgIHB1YmxpYyBTS2V5KFN0cmluZyB0eXBlLCBieXRlW10gZW5jb2RlZCkgeworICAgICAgICAgICAgdGhpcy50eXBlID0gdHlwZTsKKyAgICAgICAgICAgIHRoaXMuZW5jb2RlZCA9IGVuY29kZWQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgIHJldHVybiB0eXBlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIGVuY29kZWQ7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgICAgIHJldHVybiAidGVzdCI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRpdGlvbmFsIGNsYXNzIHRvIGNyZWF0ZSBQcml2YXRlS2V5IG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTXlQcml2YXRlS2V5IGltcGxlbWVudHMgUHJpdmF0ZUtleSB7CisgICAgICAgIHByaXZhdGUgU3RyaW5nIGFsZ29yaXRobTsKKworICAgICAgICBwcml2YXRlIFN0cmluZyBmb3JtYXQ7CisKKyAgICAgICAgcHJpdmF0ZSBieXRlW10gZW5jb2RlZDsKKworICAgICAgICBwdWJsaWMgTXlQcml2YXRlS2V5KFN0cmluZyBhbGdvcml0aG0sIFN0cmluZyBmb3JtYXQsIGJ5dGVbXSBlbmNvZGVkKSB7CisgICAgICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICAgICAgICAgIHRoaXMuZm9ybWF0ID0gZm9ybWF0OworICAgICAgICAgICAgdGhpcy5lbmNvZGVkID0gZW5jb2RlZDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICAgICAgcmV0dXJuIGFsZ29yaXRobTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgcmV0dXJuIGZvcm1hdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBlbmNvZGVkOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkaXRpb25hbCBjbGFzcyB0byBjcmVhdGUgQ2VydGlmaWNhdGUgYW5kIEtleSBvYmplY3RzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBNQ2VydGlmaWNhdGUgZXh0ZW5kcyBDZXJ0aWZpY2F0ZSB7CisgICAgICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGVuY29kaW5nOworCisgICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHR5cGU7CisKKyAgICAgICAgcHVibGljIE1DZXJ0aWZpY2F0ZShTdHJpbmcgdHlwZSwgYnl0ZVtdIGVuY29kaW5nKSB7CisgICAgICAgICAgICBzdXBlcih0eXBlKTsKKyAgICAgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICAgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gZW5jb2RpbmcuY2xvbmUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5KSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBJbnZhbGlkS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLCBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgdmVyaWZ5KFB1YmxpY0tleSBrZXksIFN0cmluZyBzaWdQcm92aWRlcikKKyAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBJbnZhbGlkS2V5RXhjZXB0aW9uLCBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiAiW01DZXJ0aWZpY2F0ZSwgdHlwZTogIiArIGdldFR5cGUoKSArICJdIjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBQdWJsaWNLZXkgZ2V0UHVibGljS2V5KCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBQdWJsaWNLZXkoKSB7CisgICAgICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVuY29kaW5nOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gInRlc3QiOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRpdGlvbmFsIGNsYXNzIHRvIGNyZWF0ZSBQcm90ZWN0aW9uUGFyYW1ldGVyIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgUHJvdFBhciBpbXBsZW1lbnRzIEtleVN0b3JlLlByb3RlY3Rpb25QYXJhbWV0ZXIgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZGl0aW9uYWwgY2xhc3MgdG8gY3JlYXRlIEtleVN0b3JlLkVudHJ5IG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQW5vdGhlckVudHJ5IGltcGxlbWVudHMgS2V5U3RvcmUuRW50cnkgeworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L01ER29sZGVuRGF0YS5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L01ER29sZGVuRGF0YS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA5NTFmOWMKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvTURHb2xkZW5EYXRhLmphdmEKQEAgLTAsMCArMSwyMDEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CisKKy8qKgorICogR29sZGVuIGRhdGEgZm9yIE1lc3NhZ2UgRGlnZXN0IHJlbGF0ZWQgdGVzdHMuPGJyPgorICogRW5jYXBzdWxhdGVzIHRoZSBmb2xsb3dpbmcgZGF0YTo8YnI+CisgKiAtIHJlZmVyZW5jZSBtZXNzYWdlPGJyPgorICogLSByZWZlcmVuY2UgbWVzc2FnZSBkaWdlc3RzIGNhbGN1bGF0ZWQgdXNpbmcKKyAqICAgQkVBIEpSb2NraXQgajJzZGsxLjQuMl8wNCAoaHR0cDovL3d3dy5iZWEuY29tKQorICogICBmb3IgdmFyaW91cyBNRCBhbGdvcml0aG1zOgorICogICBTSEEtMSwgU0hBLTI1NiwgU0hBLTM4NCwgU0hBLTUxMiwgTUQtNS4KKyAqIFN0YW5kYXJkIGFsZ29yaXRobSBuYW1lcyBhcmUgZGVmaW5lZCBpbgorICogIkphdmFUTSBDcnlwdG9ncmFwaHkgQXJjaGl0ZWN0dXJlIEFQSSBTcGVjaWZpY2F0aW9uICYgUmVmZXJlbmNlIgorICoKKyAqLworcHVibGljIGNsYXNzIE1ER29sZGVuRGF0YSB7CisgICAgLy8gVGhlIGxlbmd0aCBvZiB0ZXN0IG1lc3NhZ2UKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTVlfTUVTU0FHRV9MRU4gPSAxMDI0OworICAgIC8vIFRlc3QgbWVzc2FnZSBmb3IgZGlnZXN0IGNvbXB1dGF0aW9ucworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBteU1lc3NhZ2UgPSBuZXcgYnl0ZVtNWV9NRVNTQUdFX0xFTl07CisgICAgLy8gUmVmZXJlbmNlIGRpZ2VzdHMgZm9yIHZhcmlvdXMgYWxnb3JpdGhtcyBjYWxjdWxhdGVkCisgICAgLy8gZm9yIDxjb2RlPm15TWVzc2FnZTwvY29kZT4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBIYXNoTWFwPFN0cmluZywgYnl0ZVtdPiBnb2xkZW5EYXRhID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBieXRlW10+KCk7CisKKyAgICBzdGF0aWMgeworICAgICAgICAvLyBmaWxsIG15TWVzc2FnZQorICAgICAgICBmb3IgKGludCBpPTA7IGk8bXlNZXNzYWdlLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBteU1lc3NhZ2VbaV0gPSAoYnl0ZSlpOworICAgICAgICB9CisgICAgICAgIC8vIGZpbGwgZ29sZGVuRGF0YQorICAgICAgICAvLyBkaWdlc3QgdXBkYXRlZCB3aXRoIG15TWVzc2FnZSBieXRlcworICAgICAgICBnb2xkZW5EYXRhLnB1dCgiU0hBLTEiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDViLCAoYnl0ZSkweDAwLCAoYnl0ZSkweDY2LCAoYnl0ZSkweDljLAorICAgICAgICAgICAgICAgIChieXRlKTB4NDgsIChieXRlKTB4MGQsIChieXRlKTB4NWMsIChieXRlKTB4ZmYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhiZCwgKGJ5dGUpMHhmYSwgKGJ5dGUpMHg4YiwgKGJ5dGUpMHhkYiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGE5LCAoYnl0ZSkweDk1LCAoYnl0ZSkweDYxLCAoYnl0ZSkweDE2LAorICAgICAgICAgICAgICAgIChieXRlKTB4MGYsIChieXRlKTB4MmQsIChieXRlKTB4MWIsIChieXRlKTB4NzcKKyAgICAgICAgfSk7CisgICAgICAgIC8vIGRpZ2VzdCB3aXRob3V0IHVwZGF0ZXMgYXQgYWxsOworICAgICAgICAvLyB1c2UgTUQgYWxnb3JpdGhtIG5hbWUgKyAiX05VIiBpZiBub3QgdXBkYXRlZCBNRCB2YWx1ZSBpcyBuZWVkZWQKKyAgICAgICAgZ29sZGVuRGF0YS5wdXQoIlNIQS0xX05VIiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgKGJ5dGUpMHhkYSwgKGJ5dGUpMHgzOSwgKGJ5dGUpMHhhMywgKGJ5dGUpMHhlZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDVlLCAoYnl0ZSkweDZiLCAoYnl0ZSkweDRiLCAoYnl0ZSkweDBkLAorICAgICAgICAgICAgICAgIChieXRlKTB4MzIsIChieXRlKTB4NTUsIChieXRlKTB4YmYsIChieXRlKTB4ZWYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg5NSwgKGJ5dGUpMHg2MCwgKGJ5dGUpMHgxOCwgKGJ5dGUpMHg5MCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGFmLCAoYnl0ZSkweGQ4LCAoYnl0ZSkweDA3LCAoYnl0ZSkweDA5CisgICAgICAgIH0pOworCisgICAgICAgIGdvbGRlbkRhdGEucHV0KCJTSEEiLCBnb2xkZW5EYXRhLmdldCgiU0hBLTEiKSk7CisgICAgICAgIGdvbGRlbkRhdGEucHV0KCJTSEFfTlUiLCBnb2xkZW5EYXRhLmdldCgiU0hBLTFfTlUiKSk7CisKKyAgICAgICAgZ29sZGVuRGF0YS5wdXQoIlNIQTEiLCBnb2xkZW5EYXRhLmdldCgiU0hBLTEiKSk7CisgICAgICAgIGdvbGRlbkRhdGEucHV0KCJTSEExX05VIiwgZ29sZGVuRGF0YS5nZXQoIlNIQS0xX05VIikpOworCisgICAgICAgIGdvbGRlbkRhdGEucHV0KCJTSEEtMjU2IiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgKGJ5dGUpMHg3OCwgKGJ5dGUpMHg1YiwgKGJ5dGUpMHgwNywgKGJ5dGUpMHg1MSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGZjLCAoYnl0ZSkweDJjLCAoYnl0ZSkweDUzLCAoYnl0ZSkweGRjLAorICAgICAgICAgICAgICAgIChieXRlKTB4MTQsIChieXRlKTB4YTQsIChieXRlKTB4Y2UsIChieXRlKTB4M2QsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg4MCwgKGJ5dGUpMHgwZSwgKGJ5dGUpMHg2OSwgKGJ5dGUpMHhlZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDljLCAoYnl0ZSkweGUxLCAoYnl0ZSkweDAwLCAoYnl0ZSkweDllLAorICAgICAgICAgICAgICAgIChieXRlKTB4YjMsIChieXRlKTB4MjcsIChieXRlKTB4Y2MsIChieXRlKTB4ZjQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1OCwgKGJ5dGUpMHhhZiwgKGJ5dGUpMHhlMCwgKGJ5dGUpMHg5YywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDI0LCAoYnl0ZSkweDJjLCAoYnl0ZSkweDI2LCAoYnl0ZSkweGM5CisgICAgICAgIH0pOworICAgICAgICBnb2xkZW5EYXRhLnB1dCgiU0hBLTI1Nl9OVSIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgIChieXRlKTB4ZTMsIChieXRlKTB4YjAsIChieXRlKTB4YzQsIChieXRlKTB4NDIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg5OCwgKGJ5dGUpMHhmYywgKGJ5dGUpMHgxYywgKGJ5dGUpMHgxNCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDlhLCAoYnl0ZSkweGZiLCAoYnl0ZSkweGY0LCAoYnl0ZSkweGM4LAorICAgICAgICAgICAgICAgIChieXRlKTB4OTksIChieXRlKTB4NmYsIChieXRlKTB4YjksIChieXRlKTB4MjQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgyNywgKGJ5dGUpMHhhZSwgKGJ5dGUpMHg0MSwgKGJ5dGUpMHhlNCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDY0LCAoYnl0ZSkweDliLCAoYnl0ZSkweDkzLCAoYnl0ZSkweDRjLAorICAgICAgICAgICAgICAgIChieXRlKTB4YTQsIChieXRlKTB4OTUsIChieXRlKTB4OTksIChieXRlKTB4MWIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg3OCwgKGJ5dGUpMHg1MiwgKGJ5dGUpMHhiOCwgKGJ5dGUpMHg1NQorICAgICAgICB9KTsKKyAgICAgICAgZ29sZGVuRGF0YS5wdXQoIlNIQS0zODQiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDU1LCAoYnl0ZSkweGZkLCAoYnl0ZSkweDE3LCAoYnl0ZSkweGVlLAorICAgICAgICAgICAgICAgIChieXRlKTB4YjEsIChieXRlKTB4NjEsIChieXRlKTB4MWYsIChieXRlKTB4OTEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg5MywgKGJ5dGUpMHhmNiwgKGJ5dGUpMHhhYywgKGJ5dGUpMHg2MCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAyLCAoYnl0ZSkweDM4LCAoYnl0ZSkweGNlLCAoYnl0ZSkweDYzLAorICAgICAgICAgICAgICAgIChieXRlKTB4YWEsIChieXRlKTB4MjksIChieXRlKTB4OGMsIChieXRlKTB4MmUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzMywgKGJ5dGUpMHgyZiwgKGJ5dGUpMHgwNCwgKGJ5dGUpMHgyYiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDgwLCAoYnl0ZSkweGM4LCAoYnl0ZSkweGY2LCAoYnl0ZSkweDkxLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZjgsIChieXRlKTB4MDAsIChieXRlKTB4ZTQsIChieXRlKTB4YzcsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1MCwgKGJ5dGUpMHg1YSwgKGJ5dGUpMHhmMiwgKGJ5dGUpMHgwYywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDFhLCAoYnl0ZSkweDg2LCAoYnl0ZSkweGEzLCAoYnl0ZSkweDFmLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDgsIChieXRlKTB4NTAsIChieXRlKTB4NDUsIChieXRlKTB4ODcsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzOSwgKGJ5dGUpMHg1ZiwgKGJ5dGUpMHgwOCwgKGJ5dGUpMHgxZgorICAgICAgICB9KTsKKyAgICAgICAgZ29sZGVuRGF0YS5wdXQoIlNIQS0zODRfTlUiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDM4LCAoYnl0ZSkweGIwLCAoYnl0ZSkweDYwLCAoYnl0ZSkweGE3LAorICAgICAgICAgICAgICAgIChieXRlKTB4NTEsIChieXRlKTB4YWMsIChieXRlKTB4OTYsIChieXRlKTB4MzgsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg0YywgKGJ5dGUpMHhkOSwgKGJ5dGUpMHgzMiwgKGJ5dGUpMHg3ZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGIxLCAoYnl0ZSkweGIxLCAoYnl0ZSkweGUzLCAoYnl0ZSkweDZhLAorICAgICAgICAgICAgICAgIChieXRlKTB4MjEsIChieXRlKTB4ZmQsIChieXRlKTB4YjcsIChieXRlKTB4MTEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgxNCwgKGJ5dGUpMHhiZSwgKGJ5dGUpMHgwNywgKGJ5dGUpMHg0MywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDRjLCAoYnl0ZSkweDBjLCAoYnl0ZSkweGM3LCAoYnl0ZSkweGJmLAorICAgICAgICAgICAgICAgIChieXRlKTB4NjMsIChieXRlKTB4ZjYsIChieXRlKTB4ZTEsIChieXRlKTB4ZGEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgyNywgKGJ5dGUpMHg0ZSwgKGJ5dGUpMHhkZSwgKGJ5dGUpMHhiZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGU3LCAoYnl0ZSkweDZmLCAoYnl0ZSkweDY1LCAoYnl0ZSkweGZiLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZDUsIChieXRlKTB4MWEsIChieXRlKTB4ZDIsIChieXRlKTB4ZjEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg0OCwgKGJ5dGUpMHg5OCwgKGJ5dGUpMHhiOSwgKGJ5dGUpMHg1YgorICAgICAgICB9KTsKKyAgICAgICAgZ29sZGVuRGF0YS5wdXQoIlNIQS01MTIiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDM3LCAoYnl0ZSkweGY2LCAoYnl0ZSkweDUyLCAoYnl0ZSkweGJlLAorICAgICAgICAgICAgICAgIChieXRlKTB4ODYsIChieXRlKTB4N2YsIChieXRlKTB4MjgsIChieXRlKTB4ZWQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwMywgKGJ5dGUpMHgzMiwgKGJ5dGUpMHg2OSwgKGJ5dGUpMHhjYiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGJhLCAoYnl0ZSkweDIwLCAoYnl0ZSkweDFhLCAoYnl0ZSkweGYyLAorICAgICAgICAgICAgICAgIChieXRlKTB4MTEsIChieXRlKTB4MmMsIChieXRlKTB4MmIsIChieXRlKTB4M2YsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhkMywgKGJ5dGUpMHgzNCwgKGJ5dGUpMHhhOCwgKGJ5dGUpMHg5ZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGQyLCAoYnl0ZSkweGY3LCAoYnl0ZSkweDU3LCAoYnl0ZSkweDkzLAorICAgICAgICAgICAgICAgIChieXRlKTB4OGQsIChieXRlKTB4ZGUsIChieXRlKTB4ZTgsIChieXRlKTB4MTUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg3OCwgKGJ5dGUpMHg3YywgKGJ5dGUpMHhjNiwgKGJ5dGUpMHgxZCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDZlLCAoYnl0ZSkweDI0LCAoYnl0ZSkweGE4LCAoYnl0ZSkweGEzLAorICAgICAgICAgICAgICAgIChieXRlKTB4MzMsIChieXRlKTB4NDAsIChieXRlKTB4ZDAsIChieXRlKTB4ZjcsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhlOCwgKGJ5dGUpMHg2ZiwgKGJ5dGUpMHhmYywgKGJ5dGUpMHgwNSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDg4LCAoYnl0ZSkweDE2LCAoYnl0ZSkweGI4LCAoYnl0ZSkweDg1LAorICAgICAgICAgICAgICAgIChieXRlKTB4MzAsIChieXRlKTB4NzYsIChieXRlKTB4NmIsIChieXRlKTB4YTYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhlMiwgKGJ5dGUpMHgzMSwgKGJ5dGUpMHg2MiwgKGJ5dGUpMHgwYSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDEzLCAoYnl0ZSkweDBiLCAoYnl0ZSkweDU2LCAoYnl0ZSkweDZjCisgICAgICAgIH0pOworICAgICAgICBnb2xkZW5EYXRhLnB1dCgiU0hBLTUxMl9OVSIsIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgIChieXRlKTB4Y2YsIChieXRlKTB4ODMsIChieXRlKTB4ZTEsIChieXRlKTB4MzUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg3ZSwgKGJ5dGUpMHhlZiwgKGJ5dGUpMHhiOCwgKGJ5dGUpMHhiZCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGYxLCAoYnl0ZSkweDU0LCAoYnl0ZSkweDI4LCAoYnl0ZSkweDUwLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZDYsIChieXRlKTB4NmQsIChieXRlKTB4ODAsIChieXRlKTB4MDcsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhkNiwgKGJ5dGUpMHgyMCwgKGJ5dGUpMHhlNCwgKGJ5dGUpMHgwNSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDBiLCAoYnl0ZSkweDU3LCAoYnl0ZSkweDE1LCAoYnl0ZSkweGRjLAorICAgICAgICAgICAgICAgIChieXRlKTB4ODMsIChieXRlKTB4ZjQsIChieXRlKTB4YTksIChieXRlKTB4MjEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhkMywgKGJ5dGUpMHg2YywgKGJ5dGUpMHhlOSwgKGJ5dGUpMHhjZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDQ3LCAoYnl0ZSkweGQwLCAoYnl0ZSkweGQxLCAoYnl0ZSkweDNjLAorICAgICAgICAgICAgICAgIChieXRlKTB4NWQsIChieXRlKTB4ODUsIChieXRlKTB4ZjIsIChieXRlKTB4YjAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhmZiwgKGJ5dGUpMHg4MywgKGJ5dGUpMHgxOCwgKGJ5dGUpMHhkMiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDg3LCAoYnl0ZSkweDdlLCAoYnl0ZSkweGVjLCAoYnl0ZSkweDJmLAorICAgICAgICAgICAgICAgIChieXRlKTB4NjMsIChieXRlKTB4YjksIChieXRlKTB4MzEsIChieXRlKTB4YmQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg0NywgKGJ5dGUpMHg0MSwgKGJ5dGUpMHg3YSwgKGJ5dGUpMHg4MSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGE1LCAoYnl0ZSkweDM4LCAoYnl0ZSkweDMyLCAoYnl0ZSkweDdhLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZjksIChieXRlKTB4MjcsIChieXRlKTB4ZGEsIChieXRlKTB4M2UKKyAgICAgICAgfSk7CisgICAgICAgIGdvbGRlbkRhdGEucHV0KCJNRDUiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGIyLCAoYnl0ZSkweGVhLCAoYnl0ZSkweDlmLCAoYnl0ZSkweDdmLAorICAgICAgICAgICAgICAgIChieXRlKTB4Y2UsIChieXRlKTB4YTgsIChieXRlKTB4MzEsIChieXRlKTB4YTQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhhNiwgKGJ5dGUpMHgzYiwgKGJ5dGUpMHgyMSwgKGJ5dGUpMHgzZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDQxLCAoYnl0ZSkweGE4LCAoYnl0ZSkweDg1LCAoYnl0ZSkweDViCisgICAgICAgIH0pOworICAgICAgICBnb2xkZW5EYXRhLnB1dCgiTUQ1X05VIiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgKGJ5dGUpMHhkNCwgKGJ5dGUpMHgxZCwgKGJ5dGUpMHg4YywgKGJ5dGUpMHhkOSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDhmLCAoYnl0ZSkweDAwLCAoYnl0ZSkweGIyLCAoYnl0ZSkweDA0LAorICAgICAgICAgICAgICAgIChieXRlKTB4ZTksIChieXRlKTB4ODAsIChieXRlKTB4MDksIChieXRlKTB4OTgsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhlYywgKGJ5dGUpMHhmOCwgKGJ5dGUpMHg0MiwgKGJ5dGUpMHg3ZQorICAgICAgICB9KTsKKyAgICB9CisKKyAgICAvLyBObyBuZWVkIHRvIGluc3RhbnRpYXRlCisgICAgcHJpdmF0ZSBNREdvbGRlbkRhdGEoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyByZWZlcmVuY2UgbWVzc2FnZQorICAgICAqCisgICAgICogQHJldHVybiByZWZlcmVuY2UgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIGdldE1lc3NhZ2UoKSB7CisgICAgICAgIHJldHVybiBteU1lc3NhZ2UuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGRpZ2VzdCBnb2xkZW4gZGF0YQorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqICBNRCBhbGdvcml0aG0gbmFtZSBvciBNRCBhbGdvcml0aG0gbmFtZSArICJfTlUiIGlmCisgICAgICogIG5vdCB1cGRhdGVkIE1EIHZhbHVlIHJlcXVlc3RlZAorICAgICAqIEByZXR1cm4KKyAgICAgKiAgcmVmZXJlbmNlIGRpZ2VzdCBmb3Igc3BlY2lmaWVkIE1EIGFsZ29yaXRobSBuYW1lCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gZ2V0RGlnZXN0KFN0cmluZyBrZXkpIHsKKyAgICAgICAgcmV0dXJuICgoYnl0ZVtdKWdvbGRlbkRhdGEuZ2V0KGtleSkpLmNsb25lKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvTXlBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JTcGkuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeUFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYxZTdjN2UKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvTXlBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JTcGkuamF2YQpAQCAtMCwwICsxLDU1IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CisKKy8qKgorICogQWRkaXRpb25hbCBjbGFzcyBmb3IgdmVyaWZpY2F0aW9uIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaSBhbmQKKyAqIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvciBjbGFzc2VzCisgKgorICovCisKK3B1YmxpYyBjbGFzcyBNeUFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaQorICAgICAgICBleHRlbmRzIEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclNwaSB7CisKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVJbml0KGludCBrZXlzaXplLCBTZWN1cmVSYW5kb20gcmFuZG9tKSB7CisgICAgICAgIGlmIChrZXlzaXplIDwgMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigia2V5c2l6ZSA8IDAiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVuZ2luZUluaXQoQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBnZW5QYXJhbVNwZWMsCisgICAgICAgICAgICBTZWN1cmVSYW5kb20gcmFuZG9tKSB7CisgICAgICAgIGlmIChyYW5kb20gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicmFuZG9tIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBBbGdvcml0aG1QYXJhbWV0ZXJzIGVuZ2luZUdlbmVyYXRlUGFyYW1ldGVycygpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeUJhc2ljUGVybWlzc2lvbi5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015QmFzaWNQZXJtaXNzaW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTBkYmNlYQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeUJhc2ljUGVybWlzc2lvbi5qYXZhCkBAIC0wLDAgKzEsMjkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkJhc2ljUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb247CisKK3B1YmxpYyBjbGFzcyBNeUJhc2ljUGVybWlzc2lvbiBleHRlbmRzIEJhc2ljUGVybWlzc2lvbiB7CisgICAgcHVibGljIE15QmFzaWNQZXJtaXNzaW9uKFN0cmluZyBuYW1lKSB7IHN1cGVyKCIiKTsgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgZ2V0QWN0aW9ucygpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpbXBsaWVzKFBlcm1pc3Npb24gcGVybWlzc2lvbikgeyByZXR1cm4gdHJ1ZTsgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015R3VhcmQuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeUd1YXJkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDczYzkyOAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeUd1YXJkLmphdmEKQEAgLTAsMCArMSwzOCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuR3VhcmQ7CisKK3B1YmxpYyBjbGFzcyBNeUd1YXJkIGltcGxlbWVudHMgR3VhcmQsIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1NzY3OTQ0NzI1NjE0ODIzMzczTDsKKworICAgIGZpbmFsIGJvb2xlYW4gZW5hYmxlZDsKKworICAgIHB1YmxpYyBNeUd1YXJkKGJvb2xlYW4gc3RhdGUpIHsKKyAgICAgICAgZW5hYmxlZCA9IHN0YXRlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrR3VhcmQoT2JqZWN0IG9iamVjdCkgeworICAgICAgICBpZiAoIWVuYWJsZWQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015S2V5UGFpckdlbmVyYXRvcjEuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeUtleVBhaXJHZW5lcmF0b3IxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODNhYWI2MwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeUtleVBhaXJHZW5lcmF0b3IxLmphdmEKQEAgLTAsMCArMSwxNDYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CisKKy8qKgorICogQWRkaXRpb25hbCBjbGFzcyBleHRlbmRzIEtleVBhaXJHZW5lcmF0b3IKKyAqCisgKi8KKworcHVibGljIGNsYXNzIE15S2V5UGFpckdlbmVyYXRvcjEgZXh0ZW5kcyBLZXlQYWlyR2VuZXJhdG9yIHsKKyAgICBwdWJsaWMgaW50IGtleVNpemU7CisKKyAgICBwdWJsaWMgU2VjdXJlUmFuZG9tIHNlY3VyZVJhbmRvbTsKKworICAgIHB1YmxpYyBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtU3BlYzsKKworICAgIHB1YmxpYyBNeUtleVBhaXJHZW5lcmF0b3IxKCkgeworICAgICAgICBzdXBlcigiTXlLZXlQYWlyR2VuZXJhdG9yMSIpOworICAgIH0KKworICAgIHB1YmxpYyBNeUtleVBhaXJHZW5lcmF0b3IxKFN0cmluZyBwcCkgeworICAgICAgICBzdXBlcihwcCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiAiTXlLZXlQYWlyR2VuZXJhdG9yMSI7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgZ2V0UmVzQWxnb3JpdGhtKCkgeworICAgICAgICByZXR1cm4gIk15S2V5UGFpckdlbmVyYXRvcjEiOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGluaXRpYWxpemUoaW50IGtleXNpemUsIFNlY3VyZVJhbmRvbSByYW5kb20pIHsKKyAgICAgICAgaWYgKChrZXlzaXplIDwgMCkgfHwgKChrZXlzaXplICUgMTAwKSAhPSAwKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24oIkluY29ycmVjdCBrZXlzaXplIHBhcmFtZXRlciIpOworICAgICAgICB9CisgICAgICAgIGlmIChyYW5kb20gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24oIkluY29ycmVjdCByYW5kb20iKTsKKyAgICAgICAgfQorICAgICAgICBrZXlTaXplID0ga2V5c2l6ZTsKKyAgICAgICAgc2VjdXJlUmFuZG9tID0gcmFuZG9tOworICAgIH0KKworICAgIHB1YmxpYyBLZXlQYWlyIGdlbmVyYXRlS2V5UGFpcigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgS2V5UGFpcihuZXcgUHViS2V5KCksIG5ldyBQcml2S2V5KCkpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgaW5pdGlhbGl6ZShBbGdvcml0aG1QYXJhbWV0ZXJTcGVjIHBhcmFtLCBTZWN1cmVSYW5kb20gcmFuZG9tKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBpZiAocmFuZG9tID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKCJJbmNvcnJlY3QgcmFuZG9tIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBhcmFtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uKCJJbmNvcnJlY3QgcGFyYW0iKTsKKyAgICAgICAgfQorICAgICAgICBwYXJhbVNwZWMgPSBwYXJhbTsKKyAgICAgICAgc2VjdXJlUmFuZG9tID0gcmFuZG9tOworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBQdWJLZXkgaW1wbGVtZW50cyBQdWJsaWNLZXkgeworICAgICAgICBwcml2YXRlIFN0cmluZyBhbGdvcml0aG07CisKKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgZm9ybWF0OworCisgICAgICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kZWQ7CisKKyAgICAgICAgcHVibGljIFB1YktleSgpIHsKKyAgICAgICAgICAgIHRoaXMuYWxnb3JpdGhtID0gIk15S2V5UGFpckdlbmVyYXRvcjEiOworICAgICAgICAgICAgdGhpcy5mb3JtYXQgPSAidGVzdDEiOworICAgICAgICAgICAgdGhpcy5lbmNvZGVkID0gbmV3IGJ5dGVbMTBdOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgICAgICByZXR1cm4gYWxnb3JpdGhtOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRGb3JtYXQoKSB7CisgICAgICAgICAgICByZXR1cm4gZm9ybWF0OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIGVuY29kZWQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgUHJpdktleSBpbXBsZW1lbnRzIFByaXZhdGVLZXkgeworICAgICAgICBwcml2YXRlIFN0cmluZyBhbGdvcml0aG07CisKKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgZm9ybWF0OworCisgICAgICAgIHByaXZhdGUgYnl0ZVtdIGVuY29kZWQ7CisKKyAgICAgICAgcHVibGljIFByaXZLZXkoKSB7CisgICAgICAgICAgICB0aGlzLmFsZ29yaXRobSA9ICJNeUtleVBhaXJHZW5lcmF0b3IxIjsKKyAgICAgICAgICAgIHRoaXMuZm9ybWF0ID0gInRlc3QxIjsKKyAgICAgICAgICAgIHRoaXMuZW5jb2RlZCA9IG5ldyBieXRlWzEwXTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICAgICAgcmV0dXJuIGFsZ29yaXRobTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgcmV0dXJuIGZvcm1hdDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBlbmNvZGVkOworICAgICAgICB9CisgICAgfQorCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015S2V5UGFpckdlbmVyYXRvcjIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeUtleVBhaXJHZW5lcmF0b3IyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWI5OTI2YgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeUtleVBhaXJHZW5lcmF0b3IyLmphdmEKQEAgLTAsMCArMSw2OCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXJHZW5lcmF0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CisKKy8qKgorICogIEFkZGl0aW9uYWwgY2xhc3MgZXh0ZW5kcyBLZXlQYWlyR2VuZXJhdG9yCisgKgorICovCisKK3B1YmxpYyBjbGFzcyBNeUtleVBhaXJHZW5lcmF0b3IyIGV4dGVuZHMgS2V5UGFpckdlbmVyYXRvciB7CisgICAgaW50IGtleVNpemU7CisKKyAgICBTZWN1cmVSYW5kb20gc2VjdXJlUmFuZG9tOworCisgICAgcHVibGljIE15S2V5UGFpckdlbmVyYXRvcjIoKSB7CisgICAgICAgIHN1cGVyKCJNeUtleVBhaXJHZW5lcmF0b3IyIik7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgIHJldHVybiAiTXlLZXlQYWlyR2VuZXJhdG9yMiI7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgZ2V0UmVzQWxnb3JpdGhtKCkgeworICAgICAgICByZXR1cm4gIk15S2V5UGFpckdlbmVyYXRvcjIiOworICAgIH0KKworICAgIHB1YmxpYyBNeUtleVBhaXJHZW5lcmF0b3IyKFN0cmluZyBwcCkgeworICAgICAgICBzdXBlcihwcCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgaW5pdGlhbGl6ZShpbnQga2V5c2l6ZSwgU2VjdXJlUmFuZG9tIHJhbmRvbSkgeworICAgICAgICBpZiAoa2V5c2l6ZSA8IDY0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbigiSW5jb3JyZWN0IGtleXNpemUgcGFyYW1ldGVyIik7CisgICAgICAgIH0KKyAgICAgICAga2V5U2l6ZSA9IGtleXNpemU7CisgICAgICAgIHNlY3VyZVJhbmRvbSA9IHJhbmRvbTsKKyAgICB9CisKKyAgICBwdWJsaWMgS2V5UGFpciBnZW5lcmF0ZUtleVBhaXIoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015S2V5UGFpckdlbmVyYXRvcjMuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeUtleVBhaXJHZW5lcmF0b3IzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzFlMzRhNwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeUtleVBhaXJHZW5lcmF0b3IzLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CisKKy8qKgorICogQWRkaXRpb25hbCBjbGFzcyBleHRlbmRzIEtleVBhaXJHZW5lcmF0b3IKKyAqCisgKi8KKworcHVibGljIGNsYXNzIE15S2V5UGFpckdlbmVyYXRvcjMgZXh0ZW5kcyBLZXlQYWlyR2VuZXJhdG9yIHsKKyAgICBwdWJsaWMgTXlLZXlQYWlyR2VuZXJhdG9yMygpIHsKKyAgICAgICAgc3VwZXIoIktQR2VuXzMiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTXlLZXlQYWlyR2VuZXJhdG9yMyhTdHJpbmcgcykgeworICAgICAgICBzdXBlcihzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgS2V5UGFpciBnZW5lcmF0ZUtleVBhaXIoKSB7CisgICAgICAgIFB1YmxpY0tleSBwdWJLID0gKG5ldyBNeUtleVBhaXJHZW5lcmF0b3IxKCkpLm5ldyBQdWJLZXkoKTsKKyAgICAgICAgUHJpdmF0ZUtleSBwcmlLID0gKG5ldyBNeUtleVBhaXJHZW5lcmF0b3IxKCkpLm5ldyBQcml2S2V5KCk7CisgICAgICAgIHJldHVybiBuZXcgS2V5UGFpcihwdWJLLCBwcmlLKTsKKyAgICB9CisKK30KKwpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015S2V5UGFpckdlbmVyYXRvclNwaS5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015S2V5UGFpckdlbmVyYXRvclNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk5MjBjMWEKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvTXlLZXlQYWlyR2VuZXJhdG9yU3BpLmphdmEKQEAgLTAsMCArMSw2MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yU3BpOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5BbGdvcml0aG1QYXJhbWV0ZXJTcGVjOworCisvKioKKyAqIEFkZGl0aW9uYWwgY2xhc3MgZm9yIHZlcmlmaWNhdGlvbiBvZiBLZXlQYWlyR2VuZXJhdG9yU3BpIGFuZCBLZXlQYWlyR2VuZXJhdG9yCisgKgorICovCisKK3B1YmxpYyBjbGFzcyBNeUtleVBhaXJHZW5lcmF0b3JTcGkgZXh0ZW5kcyBLZXlQYWlyR2VuZXJhdG9yU3BpIHsKKworICAgIHB1YmxpYyB2b2lkIGluaXRpYWxpemUoaW50IGtleXNpemUsIFNlY3VyZVJhbmRvbSByYW5kb20pIHsKKyAgICAgICAgaWYgKGtleXNpemUgPCAxMDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCBrZXlzaXplOiBsZXNzIHRoYW4gMTAwIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJhbmRvbSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIHJhbmRvbSIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIEtleVBhaXIgZ2VuZXJhdGVLZXlQYWlyKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBpbml0aWFsaXplKEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1zLCBTZWN1cmVSYW5kb20gcmFuZG9tKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBpZiAocmFuZG9tID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgIk5vdCBzdXBwb3J0ZWQgZm9yIG51bGwgcmFuZG9tIik7CisgICAgICAgIH0KKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015S2V5U3RvcmUuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeUtleVN0b3JlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmZkYzJjYQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeUtleVN0b3JlLmphdmEKQEAgLTAsMCArMSwyMzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZVNwaTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKKworLyoqCisgKiBBZGRpdGlvbmFsIGNsYXNzIGZvciBLZXlTdG9yZVNwaSBhbmQgS2V5U3RvcmUgdmVyaWZpY2F0aW9uCisgKgorICovCisKK3B1YmxpYyBjbGFzcyBNeUtleVN0b3JlIGV4dGVuZHMgS2V5U3RvcmVTcGkgeworICAgIHByaXZhdGUgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PiBLZXlzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKKworICAgIHByaXZhdGUgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PiBDZXJ0ID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKKworICAgIHByaXZhdGUgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PiBDaGFpbiA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CisKKyAgICBwcml2YXRlIEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4gRGF0ZXMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOworCisgICAgcHJpdmF0ZSBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+IEtleXNTTCA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CisKKyAgICBwcml2YXRlIEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4gQ2VydFNMID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKKworICAgIHByaXZhdGUgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PiBDaGFpblNMID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKKworICAgIHByaXZhdGUgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PiBEYXRlc1NMID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKKworICAgIHB1YmxpYyBLZXkgZW5naW5lR2V0S2V5KFN0cmluZyBhbGlhcywgY2hhcltdIHBhc3N3b3JkKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChLZXlzLmNvbnRhaW5zS2V5KGFsaWFzKSkgeworICAgICAgICAgICAgcmV0dXJuIChLZXkpIEtleXMuZ2V0KGFsaWFzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVbXSBlbmdpbmVHZXRDZXJ0aWZpY2F0ZUNoYWluKFN0cmluZyBhbGlhcykgeworICAgICAgICBpZiAoQ2hhaW4uY29udGFpbnNLZXkoYWxpYXMpKSB7CisgICAgICAgICAgICByZXR1cm4gKENlcnRpZmljYXRlW10pIENoYWluLmdldChhbGlhcyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIENlcnRpZmljYXRlIGVuZ2luZUdldENlcnRpZmljYXRlKFN0cmluZyBhbGlhcykgeworICAgICAgICBpZiAoQ2VydC5jb250YWluc0tleShhbGlhcykpIHsKKyAgICAgICAgICAgIHJldHVybiAoQ2VydGlmaWNhdGUpIENlcnQuZ2V0KGFsaWFzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgRGF0ZSBlbmdpbmVHZXRDcmVhdGlvbkRhdGUoU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIGlmIChEYXRlcy5jb250YWluc0tleShhbGlhcykpIHsKKyAgICAgICAgICAgIHJldHVybiAoRGF0ZSkgRGF0ZXMuZ2V0KGFsaWFzKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVTZXRLZXlFbnRyeShTdHJpbmcgYWxpYXMsIEtleSBrZXksIGNoYXJbXSBwYXNzd29yZCwKKyAgICAgICAgICAgIENlcnRpZmljYXRlW10gY2hhaW4pIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChDZXJ0LmNvbnRhaW5zS2V5KGFsaWFzKSkgeworICAgICAgICAgICAgQ2VydC5yZW1vdmUoYWxpYXMpOworICAgICAgICB9CisgICAgICAgIEtleXMucHV0KGFsaWFzLCBrZXkpOworICAgICAgICBpZiAoY2hhaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgQ2hhaW4ucHV0KGFsaWFzLCBjaGFpbik7CisgICAgICAgIH0KKyAgICAgICAgRGF0ZXMucHV0KGFsaWFzLCBuZXcgRGF0ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVTZXRLZXlFbnRyeShTdHJpbmcgYWxpYXMsIGJ5dGVbXSBrZXksIENlcnRpZmljYXRlW10gY2hhaW4pCisgICAgICAgICAgICB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBLZXlTdG9yZUV4Y2VwdGlvbigiTm90IFN1cHBvcnRlZCBmb3IgbnVsbCBrZXkiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoQ2VydC5jb250YWluc0tleShhbGlhcykpIHsKKyAgICAgICAgICAgIENlcnQucmVtb3ZlKGFsaWFzKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoQ2hhaW4uY29udGFpbnNLZXkoYWxpYXMpKSB7CisgICAgICAgICAgICBDaGFpbi5yZW1vdmUoYWxpYXMpOworICAgICAgICB9CisgICAgICAgIEtleVN0b3JlVGVzdFN1cHBvcnQuTXlQcml2YXRlS2V5IGtleUsgPSBuZXcgS2V5U3RvcmVUZXN0U3VwcG9ydC5NeVByaXZhdGVLZXkoCisgICAgICAgICAgICAgICAgYWxpYXMsIGFsaWFzLCBrZXkpOworICAgICAgICBLZXlzLnB1dChhbGlhcywga2V5Syk7CisgICAgICAgIGlmIChjaGFpbiAhPSBudWxsKSB7CisgICAgICAgICAgICBDaGFpbi5wdXQoYWxpYXMsIGNoYWluKTsKKyAgICAgICAgfQorICAgICAgICBEYXRlcy5wdXQoYWxpYXMsIG5ldyBEYXRlKCkpOworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5naW5lU2V0Q2VydGlmaWNhdGVFbnRyeShTdHJpbmcgYWxpYXMsIENlcnRpZmljYXRlIGNlcnQpCisgICAgICAgICAgICB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICBDZXJ0LnB1dChhbGlhcywgY2VydCk7CisgICAgICAgIERhdGVzLnB1dChhbGlhcywgbmV3IERhdGUoKSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5naW5lRGVsZXRlRW50cnkoU3RyaW5nIGFsaWFzKSB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICBpZiAoS2V5cy5jb250YWluc0tleShhbGlhcykpIHsKKyAgICAgICAgICAgIEtleXMucmVtb3ZlKGFsaWFzKTsKKyAgICAgICAgICAgIENoYWluLnJlbW92ZShhbGlhcyk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKENlcnQuY29udGFpbnNLZXkoYWxpYXMpKSB7CisgICAgICAgICAgICBDZXJ0LnJlbW92ZShhbGlhcyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBlbmdpbmVBbGlhc2VzKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlbmdpbmVDb250YWluc0FsaWFzKFN0cmluZyBhbGlhcykgeworICAgICAgICBpZiAoS2V5cy5jb250YWluc0tleShhbGlhcykpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIGlmIChDZXJ0LmNvbnRhaW5zS2V5KGFsaWFzKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZW5naW5lU2l6ZSgpIHsKKyAgICAgICAgcmV0dXJuIChLZXlzLnNpemUoKSArIENlcnQuc2l6ZSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlbmdpbmVJc0tleUVudHJ5KFN0cmluZyBhbGlhcykgeworICAgICAgICBpZiAoS2V5cy5jb250YWluc0tleShhbGlhcykpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlbmdpbmVJc0NlcnRpZmljYXRlRW50cnkoU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIGlmIChDZXJ0LmNvbnRhaW5zS2V5KGFsaWFzKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZW5naW5lR2V0Q2VydGlmaWNhdGVBbGlhcyhDZXJ0aWZpY2F0ZSBjZXJ0KSB7CisgICAgICAgIHJldHVybiAiIjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVTdG9yZShPdXRwdXRTdHJlYW0gc3RyZWFtLCBjaGFyW10gcGFzc3dvcmQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBpZiAoIShzdHJlYW0gaW5zdGFuY2VvZiBCeXRlQXJyYXlPdXRwdXRTdHJlYW0pKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkluY29ycmVjdCBzdHJlYW0iKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgYWxpYXM7CisgICAgICAgIEVudW1lcmF0aW9uIGUgPSBLZXlzLmtleXMoKTsKKyAgICAgICAgd2hpbGUgKGUuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKyAgICAgICAgICAgIGFsaWFzID0gKFN0cmluZykgZS5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgS2V5c1NMLnB1dChhbGlhcywgS2V5cy5nZXQoYWxpYXMpKTsKKyAgICAgICAgICAgIERhdGVzU0wucHV0KGFsaWFzLCBEYXRlcy5nZXQoYWxpYXMpKTsKKyAgICAgICAgICAgIGlmIChDaGFpbi5jb250YWluc0tleShhbGlhcykpIHsKKyAgICAgICAgICAgICAgICBDaGFpblNMLnB1dChhbGlhcywgQ2hhaW4uZ2V0KGFsaWFzKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZSA9IENlcnQua2V5cygpOworICAgICAgICB3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgYWxpYXMgPSAoU3RyaW5nKSBlLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICBDZXJ0U0wucHV0KGFsaWFzLCBDZXJ0LmdldChhbGlhcykpOworICAgICAgICAgICAgRGF0ZXNTTC5wdXQoYWxpYXMsIERhdGVzLmdldChhbGlhcykpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5naW5lTG9hZChJbnB1dFN0cmVhbSBzdHJlYW0sIGNoYXJbXSBwYXNzd29yZCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIEtleXMuY2xlYXIoKTsKKyAgICAgICAgQ2VydC5jbGVhcigpOworICAgICAgICBDaGFpbi5jbGVhcigpOworICAgICAgICBEYXRlcy5jbGVhcigpOworICAgICAgICBTdHJpbmcgYWxpYXM7CisgICAgICAgIEVudW1lcmF0aW9uIGUgPSBLZXlzU0wua2V5cygpOworICAgICAgICB3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgYWxpYXMgPSAoU3RyaW5nKSBlLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICBLZXlzLnB1dChhbGlhcywgS2V5c1NMLmdldChhbGlhcykpOworICAgICAgICAgICAgRGF0ZXMucHV0KGFsaWFzLCBEYXRlc1NMLmdldChhbGlhcykpOworICAgICAgICAgICAgaWYgKENoYWluU0wuY29udGFpbnNLZXkoYWxpYXMpKSB7CisgICAgICAgICAgICAgICAgQ2hhaW4ucHV0KGFsaWFzLCBDaGFpblNMLmdldChhbGlhcykpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGUgPSBDZXJ0U0wua2V5cygpOworICAgICAgICB3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgYWxpYXMgPSAoU3RyaW5nKSBlLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICBDZXJ0LnB1dChhbGlhcywgQ2VydFNMLmdldChhbGlhcykpOworICAgICAgICAgICAgRGF0ZXMucHV0KGFsaWFzLCBEYXRlc1NMLmdldChhbGlhcykpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5naW5lU3RvcmUoS2V5U3RvcmUuTG9hZFN0b3JlUGFyYW1ldGVyIHBhcmFtKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBhcmFtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigicGFyYW0gaXMgbnVsbCIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5naW5lTG9hZChLZXlTdG9yZS5Mb2FkU3RvcmVQYXJhbWV0ZXIgcGFyYW0pCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBpZiAoIShwYXJhbSBpbnN0YW5jZW9mIE15TG9hZFN0b3JlUGFyYW1zKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicGFyYW0gaXMgbm90IE15TG9hZFN0b3JlUGFyYW1zOiAiICsgcGFyYW0pOworICAgICAgICB9CisgICAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeUtleVN0b3JlU3BpLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvTXlLZXlTdG9yZVNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRlYzZkOWUKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvTXlLZXlTdG9yZVNwaS5qYXZhCkBAIC0wLDAgKzEsMTcxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyAqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorICogQHZlcnNpb24gJFJldmlzaW9uJAorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlU3BpOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKKworLyoqCisgKiBBZGRpdGlvbmFsIGNsYXNzIGZvciBLZXlTdG9yZVNwaSBhbmQgS2V5U3RvcmUgdmVyaWZpY2F0aW9uCisgKgorICovCisKK3B1YmxpYyBjbGFzcyBNeUtleVN0b3JlU3BpIGV4dGVuZHMgS2V5U3RvcmVTcGkgeworCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgICAgcHVibGljIEtleSBlbmdpbmVHZXRLZXkoU3RyaW5nIGFsaWFzLCBjaGFyW10gcGFzc3dvcmQpCisgICAgICAgICAgICB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIENlcnRpZmljYXRlW10gZW5naW5lR2V0Q2VydGlmaWNhdGVDaGFpbihTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIENlcnRpZmljYXRlIGVuZ2luZUdldENlcnRpZmljYXRlKFN0cmluZyBhbGlhcykgeworICAgICAgICBpZiAoYWxpYXMuZXF1YWxzKCJ0ZXN0X2VuZ2luZUVudHJ5SW5zdGFuY2VPZl9BbGlhczEiKSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBNeUNlcnRpZmljYXRlKCJUZXN0VHlwZSIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBEYXRlIGVuZ2luZUdldENyZWF0aW9uRGF0ZShTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBEYXRlKDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVuZ2luZVNldEtleUVudHJ5KFN0cmluZyBhbGlhcywgS2V5IGtleSwgY2hhcltdIHBhc3N3b3JkLAorICAgICAgICAgICAgQ2VydGlmaWNhdGVbXSBjaGFpbikgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IEtleVN0b3JlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJlbmdpbmVTZXRLZXlFbnRyeSBpcyBub3Qgc3VwcG9ydGVkIGluIG15S2V5U3RvcmVTcGkiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVTZXRLZXlFbnRyeShTdHJpbmcgYWxpYXMsIGJ5dGVbXSBrZXksIENlcnRpZmljYXRlW10gY2hhaW4pCisgICAgICAgICAgICB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgS2V5U3RvcmVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgImVuZ2luZVNldEtleUVudHJ5IGlzIG5vdCBzdXBwb3J0ZWQgaW4gbXlLZXlTdG9yZVNwaSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVuZ2luZVNldENlcnRpZmljYXRlRW50cnkoU3RyaW5nIGFsaWFzLCBDZXJ0aWZpY2F0ZSBjZXJ0KQorICAgICAgICAgICAgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IEtleVN0b3JlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJlbmdpbmVTZXRDZXJ0aWZpY2F0ZUVudHJ5IGlzIG5vdCBzdXBwb3J0ZWQgaW4gbXlLZXlTdG9yZVNwaSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVuZ2luZURlbGV0ZUVudHJ5KFN0cmluZyBhbGlhcykgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IEtleVN0b3JlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJlbmdpbmVEZWxldGVFbnRyeSBpcyBub3Qgc3VwcG9ydGVkIGluIG15S2V5U3RvcmVTcGkiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBlbmdpbmVBbGlhc2VzKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlbmdpbmVDb250YWluc0FsaWFzKFN0cmluZyBhbGlhcykgeworICAgICAgICBpZiAoYWxpYXMgIT0gbnVsbCkKKyAgICAgICAgeworICAgICAgICAgICAgcmV0dXJuIGFsaWFzLnN0YXJ0c1dpdGgoInRlc3RfZW5naW5lRW50cnkiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGludCBlbmdpbmVTaXplKCkgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlbmdpbmVJc0tleUVudHJ5KFN0cmluZyBhbGlhcykgeworICAgICAgICBpZiAoYWxpYXMuZXF1YWxzKCJ0ZXN0X2VuZ2luZUVudHJ5SW5zdGFuY2VPZl9BbGlhczEiKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVuZ2luZUlzQ2VydGlmaWNhdGVFbnRyeShTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgaWYgKGFsaWFzLmVxdWFscygidGVzdF9lbmdpbmVFbnRyeUluc3RhbmNlT2ZfQWxpYXMyIikpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBlbmdpbmVHZXRDZXJ0aWZpY2F0ZUFsaWFzKENlcnRpZmljYXRlIGNlcnQpIHsKKyAgICAgICAgcmV0dXJuICIiOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgIHB1YmxpYyB2b2lkIGVuZ2luZVN0b3JlKE91dHB1dFN0cmVhbSBzdHJlYW0sIGNoYXJbXSBwYXNzd29yZCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghKHN0cmVhbSBpbnN0YW5jZW9mIEJ5dGVBcnJheU91dHB1dFN0cmVhbSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW5jb3JyZWN0IHN0cmVhbSIpOworICAgICAgICB9CisgICAgICAgIGlmICgoKEJ5dGVBcnJheU91dHB1dFN0cmVhbSkgc3RyZWFtKS5zaXplKCkgPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbmNvcnJlY3Qgc3RyZWFtIHNpemUgIik7CisKKyAgICAgICAgfQorCisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgICAgcHVibGljIHZvaWQgZW5naW5lTG9hZChJbnB1dFN0cmVhbSBzdHJlYW0sIGNoYXJbXSBwYXNzd29yZCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgfQorCisgICAgY2xhc3MgTXlDZXJ0aWZpY2F0ZSBleHRlbmRzIENlcnRpZmljYXRlIHsKKyAgICAgICAgcHVibGljIE15Q2VydGlmaWNhdGUoU3RyaW5nIHR5cGUpIHsKKyAgICAgICAgICAgIHN1cGVyKHR5cGUpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUHVibGljS2V5IGdldFB1YmxpY0tleSgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgdmVyaWZ5KFB1YmxpY0tleSBrZXkpIHsKKworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgdmVyaWZ5KFB1YmxpY0tleSBrZXksIFN0cmluZyBzaWdQcm92aWRlcikgeworCisgICAgICAgIH0KKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015TG9hZFN0b3JlUGFyYW1zLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvTXlMb2FkU3RvcmVQYXJhbXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNzAzYjNhCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015TG9hZFN0b3JlUGFyYW1zLmphdmEKQEAgLTAsMCArMSw0MiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKKworLyoqCisgKiBBZGRpdGlvbmFsIGNsYXNzIGV4dGVuZHMgS2V5U3RvcmUuTG9hZFN0b3JlUGFyYW1ldGVyCisgKi8KK3B1YmxpYyBjbGFzcyBNeUxvYWRTdG9yZVBhcmFtcyBpbXBsZW1lbnRzCisgICAgICAgIEtleVN0b3JlLkxvYWRTdG9yZVBhcmFtZXRlciB7CisKKyAgICBLZXlTdG9yZS5Qcm90ZWN0aW9uUGFyYW1ldGVyIHByb3RQYXI7CisKKyAgICBwdWJsaWMgTXlMb2FkU3RvcmVQYXJhbXMoS2V5U3RvcmUuUHJvdGVjdGlvblBhcmFtZXRlciBwKSB7CisgICAgICAgIHRoaXMucHJvdFBhciA9IHA7CisgICAgfQorCisgICAgcHVibGljIEtleVN0b3JlLlByb3RlY3Rpb25QYXJhbWV0ZXIgZ2V0UHJvdGVjdGlvblBhcmFtZXRlcigpIHsKKyAgICAgICAgcmV0dXJuIHByb3RQYXI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015TWVzc2FnZURpZ2VzdDEuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeU1lc3NhZ2VEaWdlc3QxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjk4ZWQzOQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeU1lc3NhZ2VEaWdlc3QxLmphdmEKQEAgLTAsMCArMSw3OSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQm9yaXMgVi4gS3V6bmV0c292CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CisKKy8qKgorICogVGVzdHMgaW1wbGVtZW50YXRpb24gb2YgTWVzc2FnZURpZ2VzdAorICoKKyAqLworcHVibGljIGNsYXNzIE15TWVzc2FnZURpZ2VzdDEgZXh0ZW5kcyBNZXNzYWdlRGlnZXN0IHsKKworICAgIHB1YmxpYyBib29sZWFuIHJ1bkVuZ2luZVJlc2V0ID0gZmFsc2U7CisgICAgcHVibGljIGJvb2xlYW4gcnVuRW5naW5lRGlnZXN0ID0gZmFsc2U7CisgICAgcHVibGljIGJvb2xlYW4gcnVuRW5naW5lVXBkYXRlMSA9IGZhbHNlOworICAgIHB1YmxpYyBib29sZWFuIHJ1bkVuZ2luZVVwZGF0ZTIgPSBmYWxzZTsKKworICAgIHB1YmxpYyBNeU1lc3NhZ2VEaWdlc3QxKCkgeworICAgICAgICBzdXBlcihudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKi8KKyAgICBwdWJsaWMgTXlNZXNzYWdlRGlnZXN0MShTdHJpbmcgYWxnb3JpdGhtKSB7CisgICAgICAgIHN1cGVyKGFsZ29yaXRobSk7CisgICAgfQorCisgICAgLyoqCisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVSZXNldCgpIHsKKyAgICAgICAgcnVuRW5naW5lUmVzZXQgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBlbmdpbmVEaWdlc3QoKSB7CisgICAgICAgIHJ1bkVuZ2luZURpZ2VzdCA9IHRydWU7CisgICAgICAgIHJldHVybiBuZXcgYnl0ZVswXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVuZ2luZVVwZGF0ZShieXRlIGFyZzApIHsKKyAgICAgICAgcnVuRW5naW5lVXBkYXRlMSA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZVtdIGFyZzAsIGludCBhcmcxLCBpbnQgYXJnMikgeworICAgICAgICBydW5FbmdpbmVVcGRhdGUyID0gdHJ1ZTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeU1lc3NhZ2VEaWdlc3QyLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvTXlNZXNzYWdlRGlnZXN0Mi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI5ZmI5NTkKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvTXlNZXNzYWdlRGlnZXN0Mi5qYXZhCkBAIC0wLDAgKzEsNzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEJvcmlzIFYuIEt1em5ldHNvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0U3BpOworCisvKioKKyAqIFRlc3RzIGltcGxlbWVudGF0aW9uIG9mIE1lc3NhZ2VEaWdlc3QKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBNeU1lc3NhZ2VEaWdlc3QyIGV4dGVuZHMgTWVzc2FnZURpZ2VzdFNwaSB7CisKKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gcnVuRW5naW5lUmVzZXQgPSBmYWxzZTsKKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gcnVuRW5naW5lRGlnZXN0ID0gZmFsc2U7CisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIHJ1bkVuZ2luZVVwZGF0ZTEgPSBmYWxzZTsKKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gcnVuRW5naW5lVXBkYXRlMiA9IGZhbHNlOworCisgICAgLyoqCisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVSZXNldCgpIHsKKyAgICAgICAgcnVuRW5naW5lUmVzZXQgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBlbmdpbmVEaWdlc3QoKSB7CisgICAgICAgIHJ1bkVuZ2luZURpZ2VzdCA9IHRydWU7CisgICAgICAgIHJldHVybiBuZXcgYnl0ZVswXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVuZ2luZVVwZGF0ZShieXRlIGFyZzApIHsKKyAgICAgICAgcnVuRW5naW5lVXBkYXRlMSA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZVtdIGFyZzAsIGludCBhcmcxLCBpbnQgYXJnMikgeworICAgICAgICBydW5FbmdpbmVVcGRhdGUyID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gaXMgbm90IGNsb25lYWJsZQorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24oKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvTXlQcm92aWRlci5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015UHJvdmlkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45Yzc4YjZkCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015UHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDEyIEBACitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKKworcHVibGljIGNsYXNzIE15UHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlciB7CisKKyAgICBwdWJsaWMgTXlQcm92aWRlcigpIHsKKyAgICAgICAgc3VwZXIoIk15UHJvdmlkZXIiLCAxLjAsICJUZXN0IFByb3ZpZGVyIDEuMCIpOworICAgICAgICBwdXQoIktleVN0b3JlLlRlc3RLZXlTdG9yZSIsIFRlc3RLZXlTdG9yZVNwaS5jbGFzcy5nZXROYW1lKCkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015U1NMQ29udGV4dFNwaS5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015U1NMQ29udGV4dFNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlkYTdhNmYKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvTXlTU0xDb250ZXh0U3BpLmphdmEKQEAgLTAsMCArMSwxNTcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5TWFuYWdlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleU1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xDb250ZXh0U3BpOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMRW5naW5lUmVzdWx0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlcnZlclNvY2tldEZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbkNvbnRleHQ7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTb2NrZXRGYWN0b3J5OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuVHJ1c3RNYW5hZ2VyOworCisvKioKKyAqIEFkZGl0aW9uYWwgY2xhc3MgZm9yIHZlcmlmaWNhdGlvbiBvZiBTU0xDb250ZXh0U3BpIGFuZCBTU0xDb250ZXh0CisgKiBmdW5jdGlvbmFsaXR5CisgKgorICovCisKK3B1YmxpYyBjbGFzcyBNeVNTTENvbnRleHRTcGkgZXh0ZW5kcyBTU0xDb250ZXh0U3BpIHsKKworICAgIHByaXZhdGUgYm9vbGVhbiBpbml0ID0gZmFsc2U7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0KEtleU1hbmFnZXJbXSBrbSwgVHJ1c3RNYW5hZ2VyW10gdG0sCisgICAgICAgICAgICBTZWN1cmVSYW5kb20gc3IpIHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAic2VjdXJlUmFuZG9tIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpbml0ID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgU1NMU29ja2V0RmFjdG9yeSBlbmdpbmVHZXRTb2NrZXRGYWN0b3J5KCkgeworICAgICAgICBpZiAoIWluaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW5pdGlhbGlhemVkIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHJvdGVjdGVkIFNTTFNlcnZlclNvY2tldEZhY3RvcnkgZW5naW5lR2V0U2VydmVyU29ja2V0RmFjdG9yeSgpIHsKKyAgICAgICAgaWYgKCFpbml0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGluaXRpYWxpYXplZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHByb3RlY3RlZCBTU0xTZXNzaW9uQ29udGV4dCBlbmdpbmVHZXRTZXJ2ZXJTZXNzaW9uQ29udGV4dCgpIHsKKyAgICAgICAgaWYgKCFpbml0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGluaXRpYWxpYXplZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHByb3RlY3RlZCBTU0xTZXNzaW9uQ29udGV4dCBlbmdpbmVHZXRDbGllbnRTZXNzaW9uQ29udGV4dCgpIHsKKyAgICAgICAgaWYgKCFpbml0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGluaXRpYWxpYXplZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHByb3RlY3RlZCBTU0xQYXJhbWV0ZXJzIGVuZ2luZUdldERlZmF1bHRTU0xQYXJhbWV0ZXJzKCkgeworICAgICAgICBlbmdpbmVHZXRTb2NrZXRGYWN0b3J5KCk7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHByb3RlY3RlZCBTU0xQYXJhbWV0ZXJzIGVuZ2luZUdldFN1cHBvcnRlZFNTTFBhcmFtZXRlcnMoKSB7CisgICAgICAgIGVuZ2luZUdldFNvY2tldEZhY3RvcnkoKTsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBGSVhNRTogYWRkIHRoZXNlIG1ldGhvZHMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU1NMRW5naW5lIGVuZ2luZUNyZWF0ZVNTTEVuZ2luZShTdHJpbmcgaG9zdCwgaW50IHBvcnQpIHsKKyAgICAgICAgaWYgKCFpbml0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGluaXRpYWxpYXplZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgdG1wU1NMRW5naW5lKGhvc3QsIHBvcnQpOworICAgIH0KKworICAgIHByb3RlY3RlZCBTU0xFbmdpbmUgZW5naW5lQ3JlYXRlU1NMRW5naW5lKCkgeworICAgICAgICBpZiAoIWluaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW5pdGlhbGlhemVkIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyB0bXBTU0xFbmdpbmUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgdG1wU1NMRW5naW5lIGV4dGVuZHMgU1NMRW5naW5lIHsKKyAgICAgICAgU3RyaW5nIHRtcEhvc3Q7CisgICAgICAgIGludCB0bXBQb3J0OworICAgICAgICBwdWJsaWMgdG1wU1NMRW5naW5lKCkgeworICAgICAgICAgICAgdG1wSG9zdCA9IG51bGw7CisgICAgICAgICAgICB0bXBQb3J0ID0gMDsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgdG1wU1NMRW5naW5lKFN0cmluZyBob3N0LCBpbnQgcG9ydCkgeworICAgICAgICAgICAgdG1wSG9zdCA9IGhvc3Q7CisgICAgICAgICAgICB0bXBQb3J0ID0gcG9ydDsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFBlZXJIb3N0KCkgeworICAgICAgICAgICAgcmV0dXJuIHRtcEhvc3Q7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGludCBnZXRQZWVyUG9ydCgpIHsKKyAgICAgICAgICAgIHJldHVybiB0bXBQb3J0OworICAgICAgICB9CisgICAgICAgIHB1YmxpYyB2b2lkIGJlZ2luSGFuZHNoYWtlKCkgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7IH0KKyAgICAgICAgcHVibGljIHZvaWQgY2xvc2VJbmJvdW5kKCkgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7IH0KKyAgICAgICAgcHVibGljIHZvaWQgY2xvc2VPdXRib3VuZCgpIHt9CisgICAgICAgIHB1YmxpYyBSdW5uYWJsZSBnZXREZWxlZ2F0ZWRUYXNrKCkgeyByZXR1cm4gbnVsbDsgfQorICAgICAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpIHsgcmV0dXJuIG51bGw7IH0KKyAgICAgICAgcHVibGljIFN0cmluZ1tdIGdldEVuYWJsZWRQcm90b2NvbHMoKSB7cmV0dXJuIG51bGw7IH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCkgeyByZXR1cm4gdHJ1ZTsgfQorICAgICAgICBwdWJsaWMgU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cyBnZXRIYW5kc2hha2VTdGF0dXMoKSB7IHJldHVybiBudWxsOyB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGdldE5lZWRDbGllbnRBdXRoKCkgeyByZXR1cm4gdHJ1ZTsgfQorICAgICAgICBwdWJsaWMgU1NMU2Vzc2lvbiBnZXRTZXNzaW9uKCkgeyByZXR1cm4gbnVsbDsgfQorICAgICAgICBwdWJsaWMgU3RyaW5nW10gZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkgIHsgcmV0dXJuIG51bGw7IH0KKyAgICAgICAgcHVibGljIFN0cmluZ1tdIGdldFN1cHBvcnRlZFByb3RvY29scygpICB7IHJldHVybiBudWxsOyB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGdldFVzZUNsaWVudE1vZGUoKSAgeyByZXR1cm4gdHJ1ZTsgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBnZXRXYW50Q2xpZW50QXV0aCgpICB7IHJldHVybiB0cnVlOyB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzSW5ib3VuZERvbmUoKSAgeyByZXR1cm4gdHJ1ZTsgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc091dGJvdW5kRG9uZSgpICB7IHJldHVybiB0cnVlOyB9CisgICAgICAgIHB1YmxpYyB2b2lkIHNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoU3RyaW5nW10gc3VpdGVzKSB7IH0KKyAgICAgICAgcHVibGljIHZvaWQgc2V0RW5hYmxlZFByb3RvY29scyhTdHJpbmdbXSBwcm90b2NvbHMpIHsgfQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oYm9vbGVhbiBmbGFnKSB7IH0KKyAgICAgICAgcHVibGljIHZvaWQgc2V0TmVlZENsaWVudEF1dGgoYm9vbGVhbiBuZWVkKSB7IH0KKyAgICAgICAgcHVibGljIHZvaWQgc2V0VXNlQ2xpZW50TW9kZShib29sZWFuIG1vZGUpIHsgfQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRXYW50Q2xpZW50QXV0aChib29sZWFuIHdhbnQpIHsgfQorICAgICAgICBwdWJsaWMgU1NMRW5naW5lUmVzdWx0IHVud3JhcChCeXRlQnVmZmVyIHNyYywgQnl0ZUJ1ZmZlcltdIGRzdHMsCisgICAgICAgICAgICAgICAgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgU1NMRW5naW5lUmVzdWx0IHdyYXAoQnl0ZUJ1ZmZlcltdIHNyY3MsIGludCBvZmZzZXQsCisgICAgICAgICAgICAgICAgaW50IGxlbmd0aCwgQnl0ZUJ1ZmZlciBkc3QpIHRocm93cyBTU0xFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvTXlTaWduYXR1cmUxLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvTXlTaWduYXR1cmUxLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzk5YzUwOAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeVNpZ25hdHVyZTEuamF2YQpAQCAtMCwwICsxLDEyMSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorKiBAYXV0aG9yIEJvcmlzIFYuIEt1em5ldHNvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmVFeGNlcHRpb247CisKKy8qKgorICogVGVzdHMgaW1wbGVtZW50YXRpb24gb2YgU2lnbmF0dXJlCisgKgorICovCitwdWJsaWMgY2xhc3MgTXlTaWduYXR1cmUxIGV4dGVuZHMgU2lnbmF0dXJlIHsKKworICAgIHB1YmxpYyBib29sZWFuIHJ1bkVuZ2luZUluaXRWZXJpZnkgPSBmYWxzZTsKKyAgICBwdWJsaWMgYm9vbGVhbiBydW5FbmdpbmVJbml0U2lnbiA9IGZhbHNlOworICAgIHB1YmxpYyBib29sZWFuIHJ1bkVuZ2luZVVwZGF0ZTEgPSBmYWxzZTsKKyAgICBwdWJsaWMgYm9vbGVhbiBydW5FbmdpbmVVcGRhdGUyID0gZmFsc2U7CisgICAgcHVibGljIGJvb2xlYW4gcnVuRW5naW5lU2lnbiA9IGZhbHNlOworICAgIHB1YmxpYyBib29sZWFuIHJ1bkVuZ2luZVZlcmlmeSA9IGZhbHNlOworICAgIHB1YmxpYyBib29sZWFuIHJ1bkVuZ2luZVNldFBhcmFtZXRlciA9IGZhbHNlOworICAgIHB1YmxpYyBib29sZWFuIHJ1bkVuZ2luZUdldFBhcmFtZXRlciA9IGZhbHNlOworCisgICAgcHVibGljIHN0YXRpYyBpbnQgU0lHTiA9IFNpZ25hdHVyZS5TSUdOOworICAgIHB1YmxpYyBzdGF0aWMgaW50IFZFUklGWSA9IFNpZ25hdHVyZS5WRVJJRlk7CisgICAgcHVibGljIHN0YXRpYyBpbnQgVU5JTklUSUFMSVpFRCA9IFNpZ25hdHVyZS5VTklOSVRJQUxJWkVEOworICAgIHByaXZhdGUgZmluYWwgaW50IEJVRkZFUl9MRU5HVEggPSAxMDsKKyAgICAvKioKKyAgICAgKgorICAgICAqCisgICAgICovCisgICAgcHVibGljIE15U2lnbmF0dXJlMSgpIHsKKyAgICAgICAgc3VwZXIobnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWxnb3JpdGhtCisgICAgICovCisgICAgcHVibGljIE15U2lnbmF0dXJlMShTdHJpbmcgYWxnb3JpdGhtKSB7CisgICAgICAgIHN1cGVyKGFsZ29yaXRobSk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdFZlcmlmeShQdWJsaWNLZXkgcHVibGljS2V5KQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRLZXlFeGNlcHRpb24geworICAgICAgICBydW5FbmdpbmVJbml0VmVyaWZ5ID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0U2lnbihQcml2YXRlS2V5IHByaXZhdGVLZXkpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIHJ1bkVuZ2luZUluaXRTaWduID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZSBiKSB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgcnVuRW5naW5lVXBkYXRlMSA9IHRydWU7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lVXBkYXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKQorICAgICAgICAgICAgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChiID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICBpZiAob2ZmIDwgMCB8fCBvZmYgPiBiLmxlbmd0aCB8fCBvZmYgPiBsZW4pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImluY29ycmVjdCBwYXJhbWV0ZXIgb2ZmIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxlbiA8IDAgfHwgbGVuID4gYi5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImluY29ycmVjdCBwYXJhbWV0ZXIgbGVuIik7CisgICAgICAgIH0KKyAgICAgICAgcnVuRW5naW5lVXBkYXRlMiA9IHRydWU7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVTaWduKCkgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgIHJ1bkVuZ2luZVNpZ24gPSB0cnVlOworICAgICAgICBieXRlIFtdIG91dCA9IG5ldyBieXRlIFtCVUZGRVJfTEVOR1RIXTsKKyAgICAgICAgcmV0dXJuIG91dDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBlbmdpbmVWZXJpZnkoYnl0ZVtdIHNpZ0J5dGVzKSB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgcnVuRW5naW5lVmVyaWZ5ID0gdHJ1ZTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVNldFBhcmFtZXRlcihTdHJpbmcgcGFyYW0sIE9iamVjdCB2YWx1ZSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgcnVuRW5naW5lU2V0UGFyYW1ldGVyID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgT2JqZWN0IGVuZ2luZUdldFBhcmFtZXRlcihTdHJpbmcgcGFyYW0pCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIHJ1bkVuZ2luZUdldFBhcmFtZXRlciA9IHRydWU7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0U3RhdGUoKSB7CisgICAgICAgIHJldHVybiBzdGF0ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldEJ1ZmZlckxlbmd0aCgpIHsKKyAgICAgICAgcmV0dXJuIEJVRkZFUl9MRU5HVEg7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015U2lnbmF0dXJlMi5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015U2lnbmF0dXJlMi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE3NDI4MDAKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvTXlTaWduYXR1cmUyLmphdmEKQEAgLTAsMCArMSw4NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorKiBAYXV0aG9yIEJvcmlzIFYuIEt1em5ldHNvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TaWduYXR1cmVTcGk7CisKKy8qKgorICogVGVzdHMgaW1wbGVtZW50YXRpb24gb2YgU2lnbmF0dXJlCisgKgorICovCitwdWJsaWMgY2xhc3MgTXlTaWduYXR1cmUyIGV4dGVuZHMgU2lnbmF0dXJlU3BpIHsKKworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBydW5FbmdpbmVJbml0VmVyaWZ5ID0gZmFsc2U7CisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIHJ1bkVuZ2luZUluaXRTaWduID0gZmFsc2U7CisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIHJ1bkVuZ2luZVVwZGF0ZTEgPSBmYWxzZTsKKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gcnVuRW5naW5lVXBkYXRlMiA9IGZhbHNlOworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBydW5FbmdpbmVTaWduID0gZmFsc2U7CisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIHJ1bkVuZ2luZVZlcmlmeSA9IGZhbHNlOworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBydW5FbmdpbmVTZXRQYXJhbWV0ZXIgPSBmYWxzZTsKKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gcnVuRW5naW5lR2V0UGFyYW1ldGVyID0gZmFsc2U7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0VmVyaWZ5KFB1YmxpY0tleSBwdWJsaWNLZXkpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEtleUV4Y2VwdGlvbiB7CisgICAgICAgIHJ1bkVuZ2luZUluaXRWZXJpZnkgPSB0cnVlOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXRTaWduKFByaXZhdGVLZXkgcHJpdmF0ZUtleSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkS2V5RXhjZXB0aW9uIHsKKyAgICAgICAgcnVuRW5naW5lSW5pdFNpZ24gPSB0cnVlOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVVwZGF0ZShieXRlIGIpIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24geworICAgICAgICBydW5FbmdpbmVVcGRhdGUxID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pCisgICAgICAgICAgICB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgcnVuRW5naW5lVXBkYXRlMiA9IHRydWU7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVTaWduKCkgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgIHJ1bkVuZ2luZVNpZ24gPSB0cnVlOworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBlbmdpbmVWZXJpZnkoYnl0ZVtdIHNpZ0J5dGVzKSB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKKyAgICAgICAgcnVuRW5naW5lVmVyaWZ5ID0gdHJ1ZTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZVNldFBhcmFtZXRlcihTdHJpbmcgcGFyYW0sIE9iamVjdCB2YWx1ZSkKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgcnVuRW5naW5lU2V0UGFyYW1ldGVyID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgT2JqZWN0IGVuZ2luZUdldFBhcmFtZXRlcihTdHJpbmcgcGFyYW0pCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIHJ1bkVuZ2luZUdldFBhcmFtZXRlciA9IHRydWU7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeVRydXN0TWFuYWdlckZhY3RvcnlTcGkuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9NeVRydXN0TWFuYWdlckZhY3RvcnlTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYjllMGY4Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L015VHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaS5qYXZhCkBAIC0wLDAgKzEsNzEgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlRXhjZXB0aW9uOworCitpbXBvcnQgamF2YXgubmV0LnNzbC5NYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXJGYWN0b3J5U3BpOworCisvKioKKyAqIENsYXNzIGZvciB2ZXJ0aWZ5aW5nIFRydXN0TWFuYWdlckZhY3RvcnlTcGkgYW5kIFRydXN0TWFuYWdlckZhY3RvcnkKKyAqIGZ1bmN0aW9uYWxpdHkKKyAqCisgKi8KKworcHVibGljIGNsYXNzIE15VHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaSBleHRlbmRzIFRydXN0TWFuYWdlckZhY3RvcnlTcGkgeworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXQoS2V5U3RvcmUga3MpIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChrcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgS2V5U3RvcmVFeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgb3BlcmF0aW9uIGZvciBudWxsIEtleVN0b3JlIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0KE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyBzcGVjKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBpZiAoc3BlYyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbigiTnVsbCBwYXJhbWV0ZXIiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3BlYyBpbnN0YW5jZW9mIFBhcmFtZXRlcnMpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZW5naW5lSW5pdCgoKFBhcmFtZXRlcnMpc3BlYykuZ2V0S2V5U3RvcmUoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbigiSW52YWxpZCBwYXJhbWV0ZXIiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCBUcnVzdE1hbmFnZXJbXSBlbmdpbmVHZXRUcnVzdE1hbmFnZXJzKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgUGFyYW1ldGVycyBpbXBsZW1lbnRzIE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyB7CisgICAgICAgIHByaXZhdGUgS2V5U3RvcmUga2V5U3RvcmU7CisgICAgICAgIHB1YmxpYyBQYXJhbWV0ZXJzIChLZXlTdG9yZSBrcykgeworICAgICAgICAgICAgdGhpcy5rZXlTdG9yZSA9IGtzOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBLZXlTdG9yZSBnZXRLZXlTdG9yZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBrZXlTdG9yZTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9Qcml2YXRlS2V5U3R1Yi5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L1ByaXZhdGVLZXlTdHViLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjU5M2NmYwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9Qcml2YXRlS2V5U3R1Yi5qYXZhCkBAIC0wLDAgKzEsNzcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZWtzZWkgWS4gU2VtZW5vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworCisvKioKKyAqIFN0dWIgZm9yIGludGVyZmFjZSBQcml2YXRlS2V5IHRlc3RzCisgKi8KKworcHVibGljIGNsYXNzIFByaXZhdGVLZXlTdHViIGltcGxlbWVudHMgUHJpdmF0ZUtleSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxMTExMTExMTFMOworCisgICAgU3RyaW5nIGFsZ29yaXRobSA9IG51bGw7CisgICAgU3RyaW5nIGZvcm1hdCA9IG51bGw7CisgICAgYnl0ZSBbXSBlbmNvZGVkID0gbnVsbDsKKworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IKKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiBAcGFyYW0gZm9ybWF0CisgICAgICogQHBhcmFtIGVuY29kZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpdmF0ZUtleVN0dWIoU3RyaW5nIGFsZ29yaXRobSwgU3RyaW5nIGZvcm1hdCwgYnl0ZVtdIGVuY29kZWQpIHsKKyAgICAgICAgdGhpcy5hbGdvcml0aG0gPSBhbGdvcml0aG07CisgICAgICAgIHRoaXMuZm9ybWF0ID0gZm9ybWF0OworICAgICAgICB0aGlzLmVuY29kZWQgPSBlbmNvZGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYWxnb3JpdGhtCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LktleSNnZXRBbGdvcml0aG0oKQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxnb3JpdGhtKCkgeworICAgICAgICByZXR1cm4gYWxnb3JpdGhtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgZm9ybWF0CisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LktleSNnZXRGb3JtYXQoKQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICByZXR1cm4gZm9ybWF0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgZW5jb2RlZCBmb3JtCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LktleSNnZXRFbmNvZGVkKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIHJldHVybiBlbmNvZGVkOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L1B1YmxpY0tleVN0dWIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9QdWJsaWNLZXlTdHViLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTE2NDRlNwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9QdWJsaWNLZXlTdHViLmphdmEKQEAgLTAsMCArMSw3MyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxla3NlaSBZLiBTZW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQ7CisKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworCisKKy8qKgorICogU3R1YiBpbXBsZW1lbnRzIGludGVyZmFjZSBQdWJsaWNLZXkKKyAqCisgKi8KKworcHVibGljIGNsYXNzIFB1YmxpY0tleVN0dWIgaW1wbGVtZW50cyBQdWJsaWNLZXkgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzMzMzMzMzMzTDsKKworICAgIFN0cmluZyBhbGdvcml0aG0gPSBudWxsOworICAgIFN0cmluZyBmb3JtYXQgPSBudWxsOworICAgIGJ5dGUgW10gZW5jb2RlZCA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiAgY29uc3RydWN0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgUHVibGljS2V5U3R1YihTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgZm9ybWF0LCBieXRlW10gZW5jb2RlZCkgeworICAgICAgICB0aGlzLmFsZ29yaXRobSA9IGFsZ29yaXRobTsKKyAgICAgICAgdGhpcy5mb3JtYXQgPSBmb3JtYXQ7CisgICAgICAgIHRoaXMuZW5jb2RlZCA9IGVuY29kZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogcmV0dXJucyBhbGdvcml0aG0KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgcmV0dXJuIGFsZ29yaXRobTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiByZXR1cm5zIGZvcm1hdAorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5LZXkjZ2V0Rm9ybWF0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgcmV0dXJuIGZvcm1hdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiByZXR1cm5zIGVuY29kZWQKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuS2V5I2dldEVuY29kZWQoKQorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHsKKyAgICAgICAgcmV0dXJuIGVuY29kZWQ7CisgICAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9SYW5kb21JbXBsLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvUmFuZG9tSW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY0N2I1MTgKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvUmFuZG9tSW1wbC5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyogQGF1dGhvciBCb3JpcyBWLiBLdXpuZXRzb3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tU3BpOworCisvKioKKyAqIFRlc3QgaW1wbGVtZW50YXRpb24gb2YgU2VjdXJlUmFuZG9tCisgKgorICovCitwdWJsaWMgY2xhc3MgUmFuZG9tSW1wbCBleHRlbmRzIFNlY3VyZVJhbmRvbVNwaSB7CisKKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gcnVuRW5naW5lR2VuZXJhdGVTZWVkID0gZmFsc2U7CisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIHJ1bkVuZ2luZU5leHRCeXRlcyA9IGZhbHNlOworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBydW5FbmdpbmVTZXRTZWVkID0gZmFsc2U7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVTZXRTZWVkKGJ5dGVbXSBzZWVkKSB7CisgICAgICAgIHJ1bkVuZ2luZVNldFNlZWQgPSB0cnVlOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZU5leHRCeXRlcyhieXRlW10gYnl0ZXMpIHsKKyAgICAgICAgcnVuRW5naW5lTmV4dEJ5dGVzID0gdHJ1ZTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgYnl0ZXNbaV0gPSAoYnl0ZSkoaSArIDB4RjEpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBlbmdpbmVHZW5lcmF0ZVNlZWQoaW50IG51bUJ5dGVzKSB7CisgICAgICAgIHJ1bkVuZ2luZUdlbmVyYXRlU2VlZCA9IHRydWU7CisgICAgICAgIGJ5dGVbXSBiID0gbmV3IGJ5dGVbbnVtQnl0ZXNdOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGIubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGJbaV0gPSAoYnl0ZSlpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBiOworICAgIH0KKworfQorCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvU2VjdXJpdHlDaGVja2VyLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvU2VjdXJpdHlDaGVja2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmNmODQ2YQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9TZWN1cml0eUNoZWNrZXIuamF2YQpAQCAtMCwwICsxLDU4IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4ZXkgVi4gVmFybGFtb3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbjsKKworLyoqCisgKiBDdXN0b20gc2VjdXJpdHkgbWFuYWdlcgorICovCisKK3B1YmxpYyBjbGFzcyBTZWN1cml0eUNoZWNrZXIgZXh0ZW5kcyBTZWN1cml0eU1hbmFnZXIgeworCisgICAgcHVibGljIGJvb2xlYW4gZW5hYmxlQWNjZXNzOworCisgICAgcHVibGljIFBlcm1pc3Npb24gY2hlY2tUYXJnZXQ7CisKKyAgICBwdWJsaWMgYm9vbGVhbiBjaGVja0Fzc2VydGVkOworCisgICAgcHVibGljIFNlY3VyaXR5Q2hlY2tlcihQZXJtaXNzaW9uIHRhcmdldCwgYm9vbGVhbiBlbmFibGUpIHsKKyAgICAgICAgY2hlY2tBc3NlcnRlZCA9IGZhbHNlOworICAgICAgICBjaGVja1RhcmdldCA9IHRhcmdldDsKKyAgICAgICAgZW5hYmxlQWNjZXNzID0gZW5hYmxlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihQZXJtaXNzaW9uIHApIHsKKyAgICAgICAgaWYgKGNoZWNrVGFyZ2V0LmVxdWFscyhwKSkgeworICAgICAgICAgICAgY2hlY2tBc3NlcnRlZCA9IHRydWU7CisgICAgICAgICAgICBpZiAoIWVuYWJsZUFjY2VzcykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFNlY3VyaXR5Q2hlY2tlciByZXNldCgpIHsKKyAgICAgICAgY2hlY2tBc3NlcnRlZCA9IGZhbHNlOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L1NpZ25lclN0dWIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9TaWduZXJTdHViLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTVhNzZlYgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9TaWduZXJTdHViLmphdmEKQEAgLTAsMCArMSw2NCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgQWxla3NlaSBZLiBTZW1lbm92CisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LklkZW50aXR5U2NvcGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlNYW5hZ2VtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2lnbmVyOworCisvKioKKyAqIFN0dWIgZm9yIGFic3RyYWN0IGNsYXNzIFNpZ25lciwgbmVjZXNzYXJ5IGZvciB0ZXN0aW5nIHB1cnBvc2VzCisgKgorICovCitAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorcHVibGljIGNsYXNzIFNpZ25lclN0dWIgZXh0ZW5kcyBTaWduZXIgeworCisgICAgLyoqCisgICAgICogRGVmYXVsdCBjb25zdHJ1Y3RvcgorICAgICAqLworICAgIHB1YmxpYyBTaWduZXJTdHViKCkgeworICAgICAgICBzdXBlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLCBzZXRzIGdpdmVuIG5hbWUKKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICovCisgICAgcHVibGljIFNpZ25lclN0dWIoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgc3VwZXIobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IsIHNldHMgZ2l2ZW4gbmFtZSBhbmQgc2NvcGUKKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogQHBhcmFtIHNjb3BlCisgICAgICogQHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNpZ25lclN0dWIoU3RyaW5nIG5hbWUsIElkZW50aXR5U2NvcGUgc2NvcGUpCisgICAgICAgICAgICB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKG5hbWUsIHNjb3BlKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9TcGlFbmdVdGlscy5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L1NwaUVuZ1V0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzAwNDVlMQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9TcGlFbmdVdGlscy5qYXZhCkBAIC0wLDAgKzEsNjkgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKKworLyoqCisgKiBBZGRpdGlvbmFsIGNsYXNzIGZvciB2ZXJpZmljYXRpb24gc3BpLWVuZ2luZSBjbGFzc2VzCisgKgorICovCisKK3B1YmxpYyBjbGFzcyBTcGlFbmdVdGlscyB7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGludmFsaWRWYWx1ZXMgPSB7CisgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICJCYWRBbGdvcml0aG0iLAorICAgICAgICAgICAgIkxvbmcgbWVzc2FnZSBMb25nIG1lc3NhZ2UgTG9uZyBtZXNzYWdlIExvbmcgbWVzc2FnZSBMb25nIG1lc3NhZ2UgTG9uZyBtZXNzYWdlIExvbmcgbWVzc2FnZSBMb25nIG1lc3NhZ2UgTG9uZyBtZXNzYWdlIExvbmcgbWVzc2FnZSBMb25nIG1lc3NhZ2UgTG9uZyBtZXNzYWdlIExvbmcgbWVzc2FnZSIgfTsKKworICAgIC8qKgorICAgICAqIFZlcmlmaWNhdGlvbjogaXMgYWxnb3JpdGhtIHN1cHBvcnRlZCBvciBub3QKKyAgICAgKgorICAgICAqIEBwYXJhbSBhbGdvcml0aG0KKyAgICAgKiBAcGFyYW0gc2VydmljZQorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFByb3ZpZGVyIGlzU3VwcG9ydChTdHJpbmcgYWxnb3JpdGhtLCBTdHJpbmcgc2VydmljZSkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgUHJvdmlkZXJbXSBwcm92cyA9IFNlY3VyaXR5LmdldFByb3ZpZGVycyhzZXJ2aWNlLmNvbmNhdCgiLiIpCisgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoYWxnb3JpdGhtKSk7CisgICAgICAgICAgICBpZiAocHJvdnMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIChwcm92cy5sZW5ndGggPT0gMCA/IG51bGwgOiBwcm92c1swXSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBNeVByb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXIgeworCisgICAgICAgIHB1YmxpYyBNeVByb3ZpZGVyKFN0cmluZyBuYW1lLCBTdHJpbmcgaW5mbywgU3RyaW5nIGtleSwgU3RyaW5nIGNsTmFtZSkgeworICAgICAgICAgICAgc3VwZXIobmFtZSwgMS4wLCBpbmZvKTsKKyAgICAgICAgICAgIHB1dChrZXksIGNsTmFtZSk7CisgICAgICAgIH0KKworICAgIH0KKworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9UZXN0Q2VydFV0aWxzLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvVGVzdENlcnRVdGlscy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM5YjljOWEKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvVGVzdENlcnRVdGlscy5qYXZhCkBAIC0wLDAgKzEsODMxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBBbGV4YW5kZXIgVi4gQXN0YXBjaHVrCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLmlvLlN0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpbmNpcGFsOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cml0eTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZUV4Y2VwdGlvbjsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC4qOworaW1wb3J0IGphdmEudXRpbC4qOworCitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLlg1MDBQcmluY2lwYWw7CisKKy8qKgorICogVGhlIGNsYXNzIGNvbnRhaW5zIHZhcmlvdXMgdXRpbGl0eSBtZXRob2RzIHVzZWQgZHVyaW5nIHRoZSBqYXZhLnNlY3VyaXR5CisgKiBjbGFzc2VzIHRlc3RpbmcuCisgKgorICovCisKK3B1YmxpYyBmaW5hbCBjbGFzcyBUZXN0Q2VydFV0aWxzIHsKKworICAgIHByaXZhdGUgVGVzdENlcnRVdGlscygpIHsKKyAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJzdGF0aWNzIG9ubHkiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIG5ldyBpbnN0YW5jZSBvZiB0ZXN0IGNlcnRpZmljYXRlIGVhY2ggdGltZSB0aGUgbWV0aG9kIGlzIGNhbGxlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGVzdCBjZXJ0aWZpY2F0ZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ2VydGlmaWNhdGUgZ2V0Q2VydCgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBUZXN0Q2VydGlmaWNhdGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIDMgdGVzdCBjZXJ0aWZpY2F0ZXMuIElNUDogVGhlIGFycmF5IHJldHVybmVkIGlzIG5vdAorICAgICAqIHJlYWwgY2hhaW4gb2YgY2VydGlmaWNhdGVzLCBpdCdzIGp1c3QgYW4gYXJyYXkgb2YgMyBjZXJ0cy4gVGhlIG1ldGhvZAorICAgICAqIHJldHVybnMgbmV3IGFycmF5IGVhY2ggdGltZSBpdCdzIGNhbGxlZC4gVGhlIG51bWJlciBvZiAzIHdhcyBjaG9zZW4KKyAgICAgKiBhcmJpdHJhcmlseSBhbmQgaXMgc3ViamVjdCB0byBjaGFuZ2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIDMgY2VydGlmaWNhdGVzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDZXJ0aWZpY2F0ZVtdIGdldENlcnRDaGFpbigpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVbXSBjaGFpbiA9IHsgbmV3IFRlc3RDZXJ0aWZpY2F0ZSgpLCBuZXcgVGVzdENlcnRpZmljYXRlKCksCisgICAgICAgICAgICAgICAgbmV3IFRlc3RDZXJ0aWZpY2F0ZSgpIH07CisgICAgICAgIHJldHVybiBjaGFpbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgdGVzdCBDZXJ0UGF0aCwgd2hpY2ggdXNlcyBnZXRDZXJ0Q2hhaW4oKSB0byBvYnRhaW4gYSBsaXN0IG9mCisgICAgICogY2VydGlmaWNhdGVzIHRvIHN0b3JlLgorICAgICAqCisgICAgICogQHJldHVybiB0ZXN0IGNlcnQgcGF0aAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ2VydFBhdGggZ2V0Q2VydFBhdGgoKSB7CisgICAgICAgIHJldHVybiBuZXcgVGVzdENlcnRQYXRoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGVzIGFuZCByZXR1cm5zIGFuIGluc3RhbmNlIG9mIFRlc3RDZXJ0UGF0aC48YnI+CisgICAgICogVGVzdENlcnRpZmljYXRlLXMgaW5jbHVkZWQgaW4gdGhlIENlcnRQYXRoIHdpbGwgYmUgdW5pcSAod2lsbCBoYXZlCisgICAgICogZGlmZmVyZW50IG51bWJlcnMgcGFzc2VkIHRvIHRoZWlyIGN0b3ItcykuPGJyPgorICAgICAqIFRoZSBzZWNvbmQgYXJndW1lbnRzIHNob3dzIHdoaWNoIG51bWJlciB3aWxsIGhhdmUgdGhlIGZpcnN0IENlcnRpZmljYXRlCisgICAgICogaW4gdGhlIENlcnRQYXRoLiBUaGUgc2Vjb25kIGNlcnRpZmljYXRlIHdpbGwgaGF2ZSAoc3RhcnRJRCsxKSBudW1iZXIKKyAgICAgKiBhbmQgc28gb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaG93TWFueSAtIHNob3dzIGhvdyBtYW55IFRlc3RDZXJ0cyBtdXN0IGNvbnRhaW4gdGhlIENlcnRQYXRoIGdlbmVyYXRlZAorICAgICAqIEBwYXJhbSBzdGFydElEIC0gc3BlY2lmaWVzIHRoZSBzdGFydGluZyBJRCB3aGljaCB0aGUgZmlyc3QgY2VydGlmaWNhdGUgd2lsbCBoYXZlCisgICAgICogQHJldHVybiBUZXN0Q2VydFBhdGgKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIENlcnRQYXRoIGdlbkNlcnRQYXRoKGludCBob3dNYW55LCBpbnQgc3RhcnRJRCkgeworICAgICAgICBDZXJ0aWZpY2F0ZVtdIGNlcnRzID0gbmV3IENlcnRpZmljYXRlW2hvd01hbnldOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGhvd01hbnk7IGkrKykgeworICAgICAgICAgICAgY2VydHNbaV0gPSBuZXcgVGVzdENlcnRpZmljYXRlKEludGVnZXIudG9TdHJpbmcoc3RhcnRJRCArIGkpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IFRlc3RDZXJ0UGF0aChjZXJ0cyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgUHJvdmlkZXIgcHJvdmlkZXIgPSBudWxsOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHByb3ZpZGVyTmFtZSA9ICJUc3RQcnZkciI7CisKKyAgICAvKioKKyAgICAgKiBBIFByaW5jaXBhbCB1c2VkIHRvIGZvcm0gcm9vdENBJ3MgY2VydGlmaWNhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFg1MDBQcmluY2lwYWwgcm9vdFByaW5jaXBhbCA9IG5ldyBYNTAwUHJpbmNpcGFsKAorICAgICAgICAgICAgVW5pR2VuLnJvb3ROYW1lKTsKKworICAgIC8qKgorICAgICAqIFNvbWUgZmFrZSByb290Q0EncyBjZXJ0aWZpY2F0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFg1MDlDZXJ0aWZpY2F0ZSByb290Q0EgPSBuZXcgVGVzdFg1MDlDZXJ0aWZpY2F0ZSgKKyAgICAgICAgICAgIHJvb3RQcmluY2lwYWwsIHJvb3RQcmluY2lwYWwpOworCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGluc3RhbGxfdGVzdF94NTA5X2ZhY3RvcnkoKSB7CisgICAgICAgIGlmIChwcm92aWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICBwcm92aWRlciA9IG5ldyBUZXN0UHJvdmlkZXIocHJvdmlkZXJOYW1lLCAwLjAxLAorICAgICAgICAgICAgICAgICAgICAiVGVzdCBwcm92aWRlciBmb3Igc2VyaWFsaXphdGlvbiB0ZXN0aW5nIik7CisgICAgICAgICAgICBTZWN1cml0eS5pbnNlcnRQcm92aWRlckF0KHByb3ZpZGVyLCAxKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB1bmluc3RhbGxfdGVzdF94NTA5X2ZhY3RvcnkoKSB7CisgICAgICAgIGlmIChwcm92aWRlciAhPSBudWxsKSB7CisgICAgICAgICAgICBTZWN1cml0eS5yZW1vdmVQcm92aWRlcihwcm92aWRlck5hbWUpOworICAgICAgICAgICAgcHJvdmlkZXIgPSBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGNsYXNzIHJlcHJlc2VudHMgdGVzdCBjZXJ0aWZpY2F0ZSBwYXRoLgorICAgICAqCisgICAgICovCisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RDZXJ0UGF0aCBleHRlbmRzIENlcnRQYXRoIGltcGxlbWVudHMKKyAgICAgICAgICAgIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIGVuY29kZWQgPSBuZXcgYnl0ZVtdIHsgMSwgMiwgMywgNCwgNSwgNiwgNywKKyAgICAgICAgICAgICAgICA4LCA5LCAweEEsIDB4QiwgMHhDLCAweEQsIDB4RSwgMHhGIH07CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHNlcmlhbGl6ZWREYXRhID0gIkp1c3QgYSBkdW1teSBzdHJpbmcgdG8gYmUgc2VyaWFsaXplZCBpbnN0ZWFkIG9mIHJlYWwgZGF0YSI7CisKKyAgICAgICAgcHJpdmF0ZSBDZXJ0aWZpY2F0ZVtdIGNlcnRzOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBEZWZhdWx0IGN0b3IgZm9yIFRlc3RDZXJ0UGF0aC4gVXNlcyB7QGxpbmsgVGVzdENlcnRVdGlscyNnZXRDZXJ0Q2hhaW4oKX0KKyAgICAgICAgICogdG8gb2J0YWluIGxpc3Qgb2YgY2VydGlmaWNhdGVzLjxicj4KKyAgICAgICAgICogQWxsIFRlc3RDZXJ0UGF0aC1zIGNvbnN0cnVjdGVkIHZpYSB0aGlzIGN0b3Igd2lsbCBiZSBlcXVhbHMoKSB0byBlYWNoCisgICAgICAgICAqIG90aGVyLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIFRlc3RDZXJ0UGF0aCgpIHsKKyAgICAgICAgICAgIHN1cGVyKCJ0ZXN0Q2VydFBhdGgiKTsKKyAgICAgICAgICAgIGNlcnRzID0gZ2V0Q2VydENoYWluKCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQ29uc3RydWN0cyBUZXN0Q2VydFBhdGggYW5kIGtlZXBzIHRoZSBnaXZlbiBhcnJheSBvZiBjZXJ0aWZpY2F0ZXMuPGJyPgorICAgICAgICAgKiBUaGUgVGVzdENlcnRQYXRocyBjb25zdHJ1Y3RlZCB2aWEgdGhpcyBjdG9yIG1heSBiZSBkaWZmZXJlbnQgKGlmIHRoZXkKKyAgICAgICAgICogaGF2ZSBkaWZmZXJlbnQgc2V0IG9mIGNlcnRpZmljYXRlcyk8YnI+CisgICAgICAgICAqIEBzZWUgVGVzdENlcnRVdGlscyNnZW5DZXJ0UGF0aChpbnQsIGludCkKKyAgICAgICAgICogQHBhcmFtIGNlcnRzCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgVGVzdENlcnRQYXRoKENlcnRpZmljYXRlW10gY2VydHMpIHsKKyAgICAgICAgICAgIHN1cGVyKCJ0ZXN0Q2VydFBhdGgiKTsKKyAgICAgICAgICAgIHRoaXMuY2VydHMgPSBjZXJ0czsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aCNnZXRDZXJ0aWZpY2F0ZXMoKQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIExpc3Q8Q2VydGlmaWNhdGU+IGdldENlcnRpZmljYXRlcygpIHsKKyAgICAgICAgICAgIHJldHVybiBBcnJheXMuYXNMaXN0KGNlcnRzKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aCNnZXRFbmNvZGVkKCkKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZCgpIHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBlbmNvZGVkLmNsb25lKCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGgjZ2V0RW5jb2RlZChqYXZhLmxhbmcuU3RyaW5nKQorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKFN0cmluZyBlbmNvZGluZykKKyAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gZW5jb2RlZC5jbG9uZSgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoI2dldEVuY29kaW5ncygpCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgSXRlcmF0b3I8U3RyaW5nPiBnZXRFbmNvZGluZ3MoKSB7CisgICAgICAgICAgICBWZWN0b3I8U3RyaW5nPiB2ID0gbmV3IFZlY3RvcjxTdHJpbmc+KCk7CisgICAgICAgICAgICB2LmFkZCgibXlUZXN0RW5jb2RpbmciKTsKKyAgICAgICAgICAgIHJldHVybiB2Lml0ZXJhdG9yKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoMjAwKTsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIlRlc3RDZXJ0UGF0aC4gY2VydHMgY291bnQ9Iik7CisgICAgICAgICAgICBpZiggY2VydHMgPT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCIwXG4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoY2VydHMubGVuZ3RoKS5hcHBlbmQoIlxuIik7CisgICAgICAgICAgICAgICAgZm9yKCBpbnQgaT0wOyBpPGNlcnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIlx0IikuYXBwZW5kKGkpLmFwcGVuZCgiICIpOworICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGNlcnRzW2ldKS5hcHBlbmQoIlxuIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFdyaXRlczxicj4KKyAgICAgICAgICogKFN0cmluZykgc2VyaWFsaXplZERhdGE8YnI+CisgICAgICAgICAqIChpbnQpIG51bWJlciBvZiBjZXJ0aWZpY2F0ZXMgaW4gdGhpcyBDZXJ0UGF0aDxicj4KKyAgICAgICAgICogPGFycmF5IG9mIGNlcnRpZmljYXRlcz4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIG91dAorICAgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIG91dC53cml0ZVVURihzZXJpYWxpemVkRGF0YSk7CisgICAgICAgICAgICBpZiAoY2VydHMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC53cml0ZUludCgwKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlSW50KGNlcnRzLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjZXJ0cy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBvdXQud3JpdGVPYmplY3QoY2VydHNbaV0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgICAgICAgICAgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBTdHJpbmcgcyA9IGluLnJlYWRVVEYoKTsKKyAgICAgICAgICAgIGlmICghc2VyaWFsaXplZERhdGEuZXF1YWxzKHMpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbigiZXhwZWN0IFsiICsgc2VyaWFsaXplZERhdGEKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIl0gZ290IFsiICsgcyArICJdIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgY291bnQgPSBpbi5yZWFkSW50KCk7CisgICAgICAgICAgICBjZXJ0cyA9IG5ldyBDZXJ0aWZpY2F0ZVtjb3VudF07CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgICAgICAgICAgICBjZXJ0c1tpXSA9IChDZXJ0aWZpY2F0ZSkgaW4ucmVhZE9iamVjdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIE9iamVjdCB3cml0ZVJlcGxhY2UoKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCBPYmplY3QgcmVhZFJlc29sdmUoKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBjbGFzcyByZXByZXNlbnRzIGVtcHR5IFB1YmxpY0tleS4KKyAgICAgKgorICAgICAqLworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0UHVibGljS2V5IGltcGxlbWVudHMgUHVibGljS2V5IHsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGFsZ28gPSAidGVzdFB1YmxpY0tleUFsZ29yaXRobSI7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIGVuY29kZWQgPSBuZXcgYnl0ZVtdIHsgMSwgMiwgMywgNCwgNSwgNiwgNywKKyAgICAgICAgICAgICAgICA4LCA5LCAweEEsIDB4QiwgMHhDLCAweEQsIDB4RSwgMHhGIH07CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGZvcm1hdCA9ICJ0ZXN0UHVibGljS2V5Rm9ybWF0IjsKKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgIHJldHVybiBhbGdvOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgcmV0dXJuIGVuY29kZWQuY2xvbmUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgcmV0dXJuIGZvcm1hdDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBjbGFzcyByZXByZXNlbnRzIHRlc3QgY2VydGlmaWNhdGUuCisgICAgICoKKyAgICAgKi8KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgVGVzdENlcnRpZmljYXRlIGV4dGVuZHMgQ2VydGlmaWNhdGUgaW1wbGVtZW50cworICAgICAgICAgICAgU2VyaWFsaXphYmxlIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gZW5jb2RlZCA9IG5ldyBieXRlW10geyAxLCAyLCAzLCA0LCA1LCA2LCA3LAorICAgICAgICAgICAgICAgIDgsIDksIDB4QSwgMHhCLCAweEMsIDB4RCwgMHhFLCAweEYgfTsKKworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUWVBFID0gIlRlc3QiOworCisgICAgICAgIC8vCisgICAgICAgIC8vIEEgU3RyaW5nIHRoYXQgbWFrZXMgZGlmZmVyZW50IFRlc3RDZXJ0aWZpY2F0ZXMgdG8gYmUgZGlmZmVyZW50LgorICAgICAgICAvLworICAgICAgICBwcml2YXRlIFN0cmluZyBkaWZmID0gbnVsbDsKKworICAgICAgICAvKioKKyAgICAgICAgICogRGVmYXVsdCBjdG9yLiBBbGwgdGhlIFRlc3RDZXJ0aWZpY2F0ZS1zIGNyZWF0ZWQgd2l0aCB0aGlzIGN0b3IgYXJlIGVxdWFscygpIHRvIGVhY2ggb3RoZXIuCisgICAgICAgICAqIFVzZSBUZXN0Q2VydGlmaWNhdGUoU3RyaW5nKSBpZiB5b3UgbmVlZCBub24gZXF1YWwgVGVzdENlcnRpZmljYXRlLXMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgVGVzdENlcnRpZmljYXRlKCkgeworICAgICAgICAgICAgc3VwZXIoVFlQRSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQSBzcGVjaWFsIHB1cnBvc2UgY3Rvci4gUGFzcyBkaWZmZXJlbnQgU3RyaW5nLXMgdG8gaGF2ZSBkaWZmZXJlbnQgVGVzdENlcnRpZmljYXRlcy4KKyAgICAgICAgICogVGVzdENlcnRpZmljYXRlLXMgd2l0aCB0aGUgc2FtZSBTdHJpbmcgcGFzc2VkIHRvIHRoaXMgY3RvciBhcmUgY29uc2lkZXJlZCBlcXVhbC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBUZXN0Q2VydGlmaWNhdGUoU3RyaW5nIGRpZmYpIHsKKyAgICAgICAgICAgIHN1cGVyKFRZUEUpOworICAgICAgICAgICAgdGhpcy5kaWZmID0gZGlmZjsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBBIGN0b3IgdGhhdCBhbGxvd3MgdG8gc3BlY2lmeSBib3RoIHRoZSBUWVBFIG9mIGNlcnRpZmljYXRlIGFuZCB0aGUKKyAgICAgICAgICogZGlmZi4gTGVhdmUgdGhlIDxjb2RlPmRpZmY8L2NvZGU+IG51bGwgd2hlbiBubyBkaWZmZXJlbmNlIG5lZWRlZC4KKyAgICAgICAgICoKKyAgICAgICAgICogQHBhcmFtIGRpZmYKKyAgICAgICAgICogQHBhcmFtIHR5cGUKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBUZXN0Q2VydGlmaWNhdGUoU3RyaW5nIGRpZmYsIFN0cmluZyB0eXBlKSB7CisgICAgICAgICAgICBzdXBlcih0eXBlKTsKKyAgICAgICAgICAgIHRoaXMuZGlmZiA9IGRpZmY7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gZW5jb2RlZC5jbG9uZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgdmVyaWZ5KFB1YmxpY0tleSBrZXkpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIEludmFsaWRLZXlFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24sIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBkbyBub3RoaW5nCisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCB2ZXJpZnkoUHVibGljS2V5IGtleSwgU3RyaW5nIHNpZ1Byb3ZpZGVyKQorICAgICAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBkbyBub3RoaW5nCisKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICByZXR1cm4gIlRlc3QgY2VydGlmaWNhdGUgLSBmb3IgdW5pdCB0ZXN0aW5nIG9ubHkiOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgICAgIGlmIChvYmogPT0gbnVsbCB8fCAhKG9iaiBpbnN0YW5jZW9mIFRlc3RDZXJ0aWZpY2F0ZSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBUZXN0Q2VydGlmaWNhdGUgdGhhdCA9IChUZXN0Q2VydGlmaWNhdGUpIG9iajsKKyAgICAgICAgICAgIGlmICh0aGlzID09IHRoYXQpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh0aGlzLmRpZmYgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiB0aGF0LmRpZmYgPT0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0aGlzLmRpZmYuZXF1YWxzKHRoYXQuZGlmZik7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUHVibGljS2V5IGdldFB1YmxpY0tleSgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVGVzdFB1YmxpY0tleSgpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFdyaXRlczo8YnI+CisgICAgICAgICAqIGJvb2xlYW4gLSB0cnVlIGlmIHRoaXMgY2VydGlmaWNhdGUgaGFzIGEgZGlmZiBzdHJpbmcsCisgICAgICAgICAqIGZhbHNlIG90aGVyd2lzZSwgZm9sbG93ZWQgYnkgPGJyPgorICAgICAgICAgKiB3cml0ZVVURigpIG9mIHN0cmluZyAoaWYgcHJlc2VudGVkKQorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gb3V0CisgICAgICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaWYgKGRpZmYgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIG91dC53cml0ZUJvb2xlYW4oZmFsc2UpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBvdXQud3JpdGVCb29sZWFuKGZhbHNlKTsKKyAgICAgICAgICAgICAgICBvdXQud3JpdGVVVEYoZGlmZik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICAgICAgYm9vbGVhbiBoYXNEaWZmU3RyaW5nID0gaW4ucmVhZEJvb2xlYW4oKTsKKyAgICAgICAgICAgIGlmIChoYXNEaWZmU3RyaW5nKSB7CisgICAgICAgICAgICAgICAgZGlmZiA9IGluLnJlYWRVVEYoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHByb3RlY3RlZCBPYmplY3Qgd3JpdGVSZXBsYWNlKCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgT2JqZWN0IHJlYWRSZXNvbHZlKCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFRlc3RJbnZhbGlkWDUwOUNlcnRpZmljYXRlIGV4dGVuZHMgVGVzdFg1MDlDZXJ0aWZpY2F0ZSB7CisgICAgICAgIHB1YmxpYyBUZXN0SW52YWxpZFg1MDlDZXJ0aWZpY2F0ZShYNTAwUHJpbmNpcGFsIHN1YmosCisgICAgICAgICAgICAgICAgWDUwMFByaW5jaXBhbCBpc3N1ZXIpIHsKKyAgICAgICAgICAgIHN1cGVyKHN1YmosIGlzc3Vlcik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKgorICAgICAqIFRlc3RYNTA5Q0VydGlmaWNhdGUuPGJyPgorICAgICAqIERvZXMgbm90aGluZyBpbnRlcmVzdGluZywgYnV0PGJyPgorICAgICAqIGEpIGlzIG5vdCBhYnN0cmFjdCwgc28gaXQgY2FuIGJlIGluc3RhbnRpYXRlZDxicj4KKyAgICAgKiBiKSByZXR1cm5zIEVuY29kZWQgZm9ybTxicj4KKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgVGVzdFg1MDlDZXJ0aWZpY2F0ZSBleHRlbmRzIFg1MDlDZXJ0aWZpY2F0ZSB7CisgICAgICAgIHByaXZhdGUgWDUwMFByaW5jaXBhbCBzdWJqZWN0OworCisgICAgICAgIHByaXZhdGUgWDUwMFByaW5jaXBhbCBpc3N1ZXI7CisKKyAgICAgICAgcHVibGljIFRlc3RYNTA5Q2VydGlmaWNhdGUoWDUwMFByaW5jaXBhbCBzdWJqLCBYNTAwUHJpbmNpcGFsIGlzc3VlcikgeworICAgICAgICAgICAgdGhpcy5zdWJqZWN0ID0gc3ViajsKKyAgICAgICAgICAgIHRoaXMuaXNzdWVyID0gaXNzdWVyOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFg1MDBQcmluY2lwYWwgZ2V0SXNzdWVyWDUwMFByaW5jaXBhbCgpIHsKKyAgICAgICAgICAgIHJldHVybiBpc3N1ZXI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgWDUwMFByaW5jaXBhbCBnZXRTdWJqZWN0WDUwMFByaW5jaXBhbCgpIHsKKyAgICAgICAgICAgIHJldHVybiBzdWJqZWN0OworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBlbmNvZGVkIGZvciBvZiB0aGlzIFg1MDlDZXJ0aWZpY2F0ZSBpcyBhIGJ5dGUgYXJyYXkgd2hlcmUKKyAgICAgICAgICogZmlyc3QgYXJlIGJ5dGVzIG9mIGVuY29kZWQgZm9ybSBvZiBTdWJqZWN0IChhcyBYNTAwUHJpbmNpcGFsKSwKKyAgICAgICAgICogZm9sbG93ZWQgYnkgb25lIHplcm8gYnl0ZQorICAgICAgICAgKiBhbmQgZm9sbG93ZWQgYnkgdGhlIGVuY29kZWQgZm9ybSBvZiBJc3N1ZXIgKGFzIFg1MDBQcmluY2lwYWwpCisgICAgICAgICAqCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBieXRlW10gYXN1YmogPSBzdWJqZWN0LmdldEVuY29kZWQoKTsKKyAgICAgICAgICAgIGJ5dGVbXSBhaXNzdWVyID0gaXNzdWVyLmdldEVuY29kZWQoKTsKKyAgICAgICAgICAgIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbYXN1YmoubGVuZ3RoICsgYWlzc3Vlci5sZW5ndGggKyAxXTsKKworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhc3ViaiwgMCwgZGF0YSwgMCwgYXN1YmoubGVuZ3RoKTsKKyAgICAgICAgICAgIC8vZGF0YVthc3Viai5sZW5ndGhdID0gMDsKKyAgICAgICAgICAgIFN5c3RlbQorICAgICAgICAgICAgICAgICAgICAuYXJyYXljb3B5KGFpc3N1ZXIsIDAsIGRhdGEsIGFzdWJqLmxlbmd0aCArIDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWlzc3Vlci5sZW5ndGgpOworICAgICAgICAgICAgcmV0dXJuIGRhdGE7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBjaGVja1ZhbGlkaXR5KCkgdGhyb3dzIENlcnRpZmljYXRlRXhwaXJlZEV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZU5vdFlldFZhbGlkRXhjZXB0aW9uIHsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrVmFsaWRpdHkoRGF0ZSBkYXRlKQorICAgICAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4cGlyZWRFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVOb3RZZXRWYWxpZEV4Y2VwdGlvbiB7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldEJhc2ljQ29uc3RyYWludHMoKSB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0SXNzdWVyRE4oKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuW10gZ2V0SXNzdWVyVW5pcXVlSUQoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuW10gZ2V0S2V5VXNhZ2UoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBEYXRlIGdldE5vdEFmdGVyKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgRGF0ZSBnZXROb3RCZWZvcmUoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFNlcmlhbE51bWJlcigpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRTaWdBbGdOYW1lKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFNpZ0FsZ09JRCgpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRTaWdBbGdQYXJhbXMoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0U2lnbmF0dXJlKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgUHJpbmNpcGFsIGdldFN1YmplY3RETigpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW5bXSBnZXRTdWJqZWN0VW5pcXVlSUQoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0VEJTQ2VydGlmaWNhdGUoKSB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0VmVyc2lvbigpIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFNldCBnZXRDcml0aWNhbEV4dGVuc2lvbk9JRHMoKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RXh0ZW5zaW9uVmFsdWUoU3RyaW5nIG9pZCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU2V0IGdldE5vbkNyaXRpY2FsRXh0ZW5zaW9uT0lEcygpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzVW5zdXBwb3J0ZWRDcml0aWNhbEV4dGVuc2lvbigpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBQdWJsaWNLZXkgZ2V0UHVibGljS2V5KCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCB2ZXJpZnkoUHVibGljS2V5IGtleSwgU3RyaW5nIHNpZ1Byb3ZpZGVyKQorICAgICAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CisKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5KSB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBJbnZhbGlkS2V5RXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLCBTaWduYXR1cmVFeGNlcHRpb24geworCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0UHJvdmlkZXIuIERvZXMgbm90aGluZywgYnV0IHByZXRlbmRzIHRvCisgICAgICogaW1wbGVtZW50IFguNTA5IENlcnRpZmljYXRlRmFjdG9yeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFRlc3RQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyIHsKKworICAgICAgICBwcml2YXRlIFByb3ZpZGVyLlNlcnZpY2Ugc2VydjsKKworICAgICAgICBwdWJsaWMgVGVzdFByb3ZpZGVyKFN0cmluZyBuYW1lLCBkb3VibGUgdmVyc2lvbiwgU3RyaW5nIGluZm8pIHsKKyAgICAgICAgICAgIHN1cGVyKG5hbWUsIHZlcnNpb24sIGluZm8pOworICAgICAgICAgICAgc2VydiA9IG5ldyBQcm92aWRlci5TZXJ2aWNlKHRoaXMsICJDZXJ0aWZpY2F0ZUZhY3RvcnkiLCAiWC41MDkiLAorICAgICAgICAgICAgICAgICAgICBUZXN0RmFjdG9yeVNwaS5jbGFzcy5nZXROYW1lKCksIG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpLCBudWxsKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU2V0PFByb3ZpZGVyLlNlcnZpY2U+IGdldFNlcnZpY2VzKCkgeworICAgICAgICAgICAgSGFzaFNldDxQcm92aWRlci5TZXJ2aWNlPiBzID0gbmV3IEhhc2hTZXQ8U2VydmljZT4oKTsKKyAgICAgICAgICAgIHMuYWRkKHNlcnYpOworICAgICAgICAgICAgcmV0dXJuIHM7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTb21lIGtpbmQgb2YgQ2VydGlmaWNhdGUgRmFjdG9yeSwgdXNlZCBkdXJpbmcgdW5pdCB0ZXN0aW5nLgorICAgICAqCisgICAgICoKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFRlc3RGYWN0b3J5U3BpIGV4dGVuZHMgQ2VydGlmaWNhdGVGYWN0b3J5U3BpIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogVHJpZXMgdG8gY3JlYXRlIGFuIGluc3RhbmNlIG9mIFRlc3RYNTA5Q2VydGlmaWNhdGUsIGJhc2luZworICAgICAgICAgKiBvbiB0aGUgcHJlc3VtcHRpb24gdGhhdCBpdHMge0BsaW5rIFRlc3RYNTA5Q2VydGlmaWNhdGUjZ2V0RW5jb2RlZCgpCisgICAgICAgICAqIGVuY29kZWR9IGZvcm0gaXMgc3RvcmVkLjxicj4KKyAgICAgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiBpcyB0aGUgcHJlc3VtcHRpb24gaXMgbm90IG1ldCBvciBpZgorICAgICAgICAgKiBhbnkgSU8gcHJvYmxlbSBvY2N1cnMuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQ2VydGlmaWNhdGUgZW5naW5lR2VuZXJhdGVDZXJ0aWZpY2F0ZShJbnB1dFN0cmVhbSBpcykKKyAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICAgICAgYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVswXTsKKyAgICAgICAgICAgIGJ5dGVbXSBjaHVuayA9IG5ldyBieXRlWzEwMjRdOworICAgICAgICAgICAgaW50IGxlbjsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgd2hpbGUgKChsZW4gPSBpcy5yZWFkKGNodW5rKSkgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSB0bXAgPSBuZXcgYnl0ZVtkYXRhLmxlbmd0aCArIGxlbl07CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YSwgMCwgdG1wLCAwLCBkYXRhLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY2h1bmssIDAsIHRtcCwgZGF0YS5sZW5ndGgsIGxlbik7CisgICAgICAgICAgICAgICAgICAgIGRhdGEgPSB0bXA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oIklPIHByb2JsZW0iLCBleCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgcG9zID0gQXJyYXlzLmJpbmFyeVNlYXJjaChkYXRhLCAoYnl0ZSkgMCk7CisgICAgICAgICAgICBpZiAocG9zIDwgMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigiaW52YWxpZCBmb3JtYXQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ5dGVbXSBzdWJqTmFtZURhdGEgPSBuZXcgYnl0ZVtwb3NdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShkYXRhLCAwLCBzdWJqTmFtZURhdGEsIDAsIHN1YmpOYW1lRGF0YS5sZW5ndGgpOworICAgICAgICAgICAgYnl0ZVtdIGlzc05hbWVEYXRhID0gbmV3IGJ5dGVbZGF0YS5sZW5ndGggLSBwb3MgLSAxXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YSwgcG9zICsgMSwgaXNzTmFtZURhdGEsIDAsIGlzc05hbWVEYXRhLmxlbmd0aCk7CisgICAgICAgICAgICBYNTAwUHJpbmNpcGFsIHN1YmpOYW1lID0gbmV3IFg1MDBQcmluY2lwYWwoc3Viak5hbWVEYXRhKTsKKyAgICAgICAgICAgIFg1MDBQcmluY2lwYWwgaXNzTmFtZSA9IG5ldyBYNTAwUHJpbmNpcGFsKGlzc05hbWVEYXRhKTsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVGVzdFg1MDlDZXJ0aWZpY2F0ZShzdWJqTmFtZSwgaXNzTmFtZSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogTm90IHN1cHBvcnRlZCB5ZXQuCisgICAgICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBDb2xsZWN0aW9uIGVuZ2luZUdlbmVyYXRlQ2VydGlmaWNhdGVzKElucHV0U3RyZWFtIGluU3RyZWFtKQorICAgICAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIm5vdCB5ZXQuIik7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogTm90IHN1cHBvcnRlZCB5ZXQuCisgICAgICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBDUkwgZW5naW5lR2VuZXJhdGVDUkwoSW5wdXRTdHJlYW0gaW5TdHJlYW0pIHRocm93cyBDUkxFeGNlcHRpb24geworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJub3QgeWV0LiIpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE5vdCBzdXBwb3J0ZWQgeWV0LgorICAgICAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQ29sbGVjdGlvbiBlbmdpbmVHZW5lcmF0ZUNSTHMoSW5wdXRTdHJlYW0gaW5TdHJlYW0pCisgICAgICAgICAgICAgICAgdGhyb3dzIENSTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIm5vdCB5ZXQuIik7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiBUZXN0Q2VydFBhdGguPGJyPgorICAgICAgICAgKiBAdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIGlmCisgICAgICAgICAqIGEpIGFueSBvZiBDZXJ0aWZpY2F0ZXMgcGFzc2VkIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBYNTA5Q2VydGlmaWNhdGUKKyAgICAgICAgICogYikgYW55IG9mIENlcnRpZmljYXRlcyBwYXNzZWQgaXMgYW4gaW5zdGFuY2Ugb2YgVGVzdEludmFsaWRYNTA5Q2VydGlmaWNhdGUKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBDZXJ0UGF0aCBlbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKExpc3QgY2VydHMpCisgICAgICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIEFycmF5TGlzdDxDZXJ0aWZpY2F0ZT4gdmFsaWRDZXJ0cyA9IG5ldyBBcnJheUxpc3Q8Q2VydGlmaWNhdGU+KCk7CisgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yIGkgPSBjZXJ0cy5pdGVyYXRvcigpOyBpLmhhc05leHQoKTspIHsKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZSBjID0gKENlcnRpZmljYXRlKSBpLm5leHQoKTsKKyAgICAgICAgICAgICAgICBpZiAoIShjIGluc3RhbmNlb2YgWDUwOUNlcnRpZmljYXRlKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oIk5vdCBYNTA5OiAiICsgYyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChjIGluc3RhbmNlb2YgVGVzdEludmFsaWRYNTA5Q2VydGlmaWNhdGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKCJJbnZhbGlkICh0ZXN0KSBYNTA5OiAiICsgYyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHZhbGlkQ2VydHMuYWRkKGMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQ2VydGlmaWNhdGVbXSBhY2VydHMgPSBuZXcgQ2VydGlmaWNhdGVbdmFsaWRDZXJ0cy5zaXplKCldOworICAgICAgICAgICAgdmFsaWRDZXJ0cy50b0FycmF5KGFjZXJ0cyk7CisgICAgICAgICAgICByZXR1cm4gbmV3IFRlc3RDZXJ0UGF0aChhY2VydHMpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXRpbGl0eSBjbGFzcyB1c2VkIHRvIGdlbmVyYXRlIHNvbWUgYW1vdW50IG9mIHVuaXEgbmFtZXMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBVbmlHZW4geworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyByb290TmFtZSA9ICJDTj1BbGV4IEFzdGFwY2h1aywgT1U9U1NHLCBPPUludGVsIFpBTywgQz1SVSI7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGRhdGFzTmFtZXNbXSA9IHsgIkNOIiwgIk9VIiwgIk8iLCAiQyIgfTsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZGF0YXNbXVtdID0geworICAgICAgICAvLyBOYW1lcyBkYXRhYmFzZQorICAgICAgICAgICAgICAgIHsgIkFsZXggQXN0YXBjaHVrIiwgbnVsbCwgbnVsbCwgbnVsbCB9LAorICAgICAgICAgICAgICAgIHsgIkpvaG4gRG9lIiwgbnVsbCwgbnVsbCwgbnVsbCB9LAorICAgICAgICAgICAgICAgIC8vICdvcmdhbmlzYXRpb24gdW5pdCctcworICAgICAgICAgICAgICAgIHsgbnVsbCwgIlNTRyIsIG51bGwsIG51bGwgfSwgeyBudWxsLCAiU1NHL0RSTCIsIG51bGwsIG51bGwgfSwKKyAgICAgICAgICAgICAgICAvLyBvcmdhbml6YXRpb25zCisgICAgICAgICAgICAgICAgeyBudWxsLCBudWxsLCAiSW50ZWwgWkFPIiwgbnVsbCB9LAorICAgICAgICAgICAgICAgIHsgbnVsbCwgbnVsbCwgIkludGVsIEluYyIsIG51bGwgfSwKKyAgICAgICAgICAgICAgICAvLyBjb3VudHJpZXMKKyAgICAgICAgICAgICAgICB7IG51bGwsIG51bGwsIG51bGwsICJSVSIgfSwgeyBudWxsLCBudWxsLCBudWxsLCAiVVMiIH0sCisgICAgICAgICAgICAgICAgeyBudWxsLCBudWxsLCBudWxsLCAiR0IiIH0sIHsgbnVsbCwgbnVsbCwgbnVsbCwgIkpBIiB9LAorICAgICAgICAgICAgICAgIHsgbnVsbCwgbnVsbCwgbnVsbCwgIktPIiB9LCB7IG51bGwsIG51bGwsIG51bGwsICJUVyIgfSwgfTsKKworICAgICAgICAvLworICAgICAgICAvLyBSZXR1cm5zIGEgc3RyaW5nIGZyb20gPGNvZGU+ZGF0YTwvY29kZT4gZnJvbSBhIGdpdmVuIGNvbHVtbiBhbmQKKyAgICAgICAgLy8gcG9zaXRpb24uIFRoZSBwb3NpdGlvbnMgYXJlIGxvb2tlZCBmb3IgZmlyc3Qgbm9uLW51bGwgZW50cnkuIElmIHRoZXJlCisgICAgICAgIC8vIGFyZSBubyBub24gZW1wdHkgaXRlbXMgbGVmdCwgdGhlbiBpdCBzY2FucyBjb2x1bW4gc3RhcnRpbmcgZnJvbSB0aGUKKyAgICAgICAgLy8gYmVnaW5uaW5nLgorICAgICAgICAvLworICAgICAgICAvLyBAcGFyYW0gY29sCisgICAgICAgIC8vIEBwYXJhbSBzdGFydFJvdworICAgICAgICAvLyBAcmV0dXJuCisgICAgICAgIC8vCisgICAgICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXREYXRhKGludCBjb2wsIGludCBzdGFydFJvdykgeworICAgICAgICAgICAgc3RhcnRSb3cgPSBzdGFydFJvdyAlIGRhdGFzLmxlbmd0aDsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBzdGFydFJvdzsgaSA8IGRhdGFzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKGRhdGFzW2ldW2NvbF0gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YXNbaV1bY29sXTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBubyBub24tbnVsbCBlbnRyaWVzIGxlZnQsIGNoZWNrIGZyb20gdGhlIGJlZ2lubmluZworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkYXRhcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChkYXRhc1tpXVtjb2xdICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGFzW2ldW2NvbF07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gY2FuJ3QgYmUKKyAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpOworICAgICAgICB9CisKKyAgICAgICAgLy8KKyAgICAgICAgLy8gSW5jcmVtZW50cyBhIG51bS48YnI+CisgICAgICAgIC8vIDxjb2RlPm51bTwvY29kZT4gaXMgaW50ZXJwcmV0ZWQgYXMgYSBudW1iZXIgd2l0aCBhIGJhc2Ugb2YKKyAgICAgICAgLy8gPGNvZGU+YmFzZTwvY29kZT4gYW5kIGVhY2ggZGlnaXQgb2YgdGhpcyBudW1iZXIgaXMgc3RvcmVkIGFzIGEKKyAgICAgICAgLy8gc2VwYXJhdGUgbnVtJ3MgZWxlbWVudC4KKyAgICAgICAgLy8KKyAgICAgICAgLy8gQHBhcmFtIG51bQorICAgICAgICAvLyBAcGFyYW0gYmFzZQorICAgICAgICAvLyBAcmV0dXJuIDxiPnRydWU8L2I+IGlmIG92ZXJmbG93IGhhcHBlbmVkCisgICAgICAgIC8vCisgICAgICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaW5jKGludFtdIG51bSwgaW50IGJhc2UpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgICAgaWYgKCgrK251bVtpXSkgPj0gYmFzZSkgeworICAgICAgICAgICAgICAgICAgICBudW1baV0gPSAwOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBHZW5lcmF0ZXMgc29tZSBhbW91bnQgb2YgdW5pcSBuYW1lcywgbm9uZSBvZiB3aGljaCBpcyBlcXVhbHMgdG8KKyAgICAgICAgICoge0BsaW5rICNyb290TmFtZX0uCisgICAgICAgICAqIEBwYXJhbSBob3dNYW55CisgICAgICAgICAqIEByZXR1cm4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gZ2VuTmFtZXMoaW50IGhvd01hbnkpIHsKKyAgICAgICAgICAgIGludCBjb3VudHNbXSA9IG5ldyBpbnRbZGF0YXNOYW1lcy5sZW5ndGhdOworICAgICAgICAgICAgQXJyYXlMaXN0PFN0cmluZz4gYWwgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKworICAgICAgICAgICAgLy8gbm90IHJlYWxseSB0aGUgdGhyaWZ0eSBhbGdvcml0aG0uLi4KKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaG93TWFueTspIHsKKworICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiMiK2krIjogIik7CisgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgZm9yKCBpbnQgaj0wOyBqPGNvdW50cy5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIiK2NvdW50c1tqXSsifCIpOworICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKKworICAgICAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgICAgICAgICAgaW50IGogPSAwOworICAgICAgICAgICAgICAgIGZvciAoOyBqIDwgZGF0YXNOYW1lcy5sZW5ndGggLSAxOyBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBkYXRhc05hbWVzW2pdOworICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsID0gZ2V0RGF0YShqLCBjb3VudHNbal0pOworICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKG5hbWUpLmFwcGVuZCgnPScpLmFwcGVuZCh2YWwpLmFwcGVuZCgiLCIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGRhdGFzTmFtZXNbal07CisgICAgICAgICAgICAgICAgU3RyaW5nIHZhbCA9IGdldERhdGEoaiwgY291bnRzW2pdKTsKKyAgICAgICAgICAgICAgICBidWYuYXBwZW5kKG5hbWUpLmFwcGVuZCgnPScpLmFwcGVuZCh2YWwpOworCisgICAgICAgICAgICAgICAgbmFtZSA9IGJ1Zi50b1N0cmluZygpOworCisgICAgICAgICAgICAgICAgaWYgKCEocm9vdE5hbWUuZXF1YWxzKG5hbWUpIHx8IGFsLmNvbnRhaW5zKG5hbWUpKSkgeworICAgICAgICAgICAgICAgICAgICArK2k7CisgICAgICAgICAgICAgICAgICAgIGFsLmFkZChuYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZ2VuZXJhdGVkOiAiK25hbWUpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInJlamVjdGVkOiAiK25hbWUpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChpbmMoY291bnRzLCBkYXRhcy5sZW5ndGgpKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoaXMgaGFwcGVuZWQsIHRoZW4ganVzdCBhZGQgc29tZSBkYXRhIGludG8gJ2RhdGFzJworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNhbnQgZ2VuZXJhdGUgc28gbWFueSB1bmlxIG5hbWVzLiBzb3JyeS4gYWRkIHNvbWUgbW9yZSBkYXRhLiIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAoU3RyaW5nW10pIGFsLnRvQXJyYXkobmV3IFN0cmluZ1thbC5zaXplKCldKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBHZW5lcmF0ZXMgc29tZSBhbW91bnQgb2YgdW5pcSBYNTAwUHJpbmNpcGFscywgbm9uZSBvZiB3aGljaCBpcyBlcXVhbHMKKyAgICAgICAgICogaGFzIGEgc3RyaW5nIGVxdWFscyB0byB7QGxpbmsgI3Jvb3ROYW1lfS4KKyAgICAgICAgICogQHBhcmFtIGhvd01hbnkKKyAgICAgICAgICogQHJldHVybgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBYNTAwUHJpbmNpcGFsW10gZ2VuWDUwMHMoaW50IGhvd01hbnkpIHsKKyAgICAgICAgICAgIFN0cmluZyBuYW1lc1tdID0gZ2VuTmFtZXMoaG93TWFueSk7CisgICAgICAgICAgICBYNTAwUHJpbmNpcGFsW10gcHMgPSBuZXcgWDUwMFByaW5jaXBhbFtob3dNYW55XTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaG93TWFueTsgaSsrKSB7CisgICAgICAgICAgICAgICAgcHNbaV0gPSBuZXcgWDUwMFByaW5jaXBhbChuYW1lc1tpXSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcHM7CisgICAgICAgIH0KKworICAgIH0KKworfQorCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvVGVzdEtleVBhaXIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9UZXN0S2V5UGFpci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY3ZDEyZmMKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvVGVzdEtleVBhaXIuamF2YQpAQCAtMCwwICsxLDYwMiBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5RmFjdG9yeTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZhdGVLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QdWJsaWNLZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkludmFsaWRLZXlTcGVjRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5QS0NTOEVuY29kZWRLZXlTcGVjOworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5YNTA5RW5jb2RlZEtleVNwZWM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CisKKy8qKgorICogR2VuZXJhdGVzIGtleSBwYWlycyBiYXNlZCBvbiB0aGVpciBlbmNvZGluZ3MgZm9yIHNvbWUgYWxnb3JpdGhtcy4KKyAqIEVuY29kaW5ncyBnZW5lcmF0ZWQgdXNpbmcKKyAqIEJFQSBKUm9ja2l0IGoyc2RrMS40LjJfMDQgKGh0dHA6Ly93d3cuYmVhLmNvbSkKKyAqLworcHVibGljIGNsYXNzIFRlc3RLZXlQYWlyIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBIYXNoTWFwPFN0cmluZywgYnl0ZSBbXT4gcHJpdmF0ZUtleUVuY29kaW5nID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBieXRlW10+KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSGFzaE1hcDxTdHJpbmcsIGJ5dGUgW10+IHB1YmxpY0tleUVuY29kaW5nID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBieXRlW10+KCk7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgYWxnb3JpdGhtTmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIEtleUZhY3Rvcnkga2Y7CisgICAgc3RhdGljIHsKKyAgICAgICAgcHJpdmF0ZUtleUVuY29kaW5nLnB1dCgiUlNBIiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzMCwgKGJ5dGUpMHg4MiwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg3NywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAyLCAoYnl0ZSkweDAxLCAoYnl0ZSkweDAwLCAoYnl0ZSkweDMwLAorICAgICAgICAgICAgICAgIChieXRlKTB4MGQsIChieXRlKTB4MDYsIChieXRlKTB4MDksIChieXRlKTB4MmEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg4NiwgKGJ5dGUpMHg0OCwgKGJ5dGUpMHg4NiwgKGJ5dGUpMHhmNywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDBkLCAoYnl0ZSkweDAxLCAoYnl0ZSkweDAxLCAoYnl0ZSkweDAxLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDUsIChieXRlKTB4MDAsIChieXRlKTB4MDQsIChieXRlKTB4ODIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg2MSwgKGJ5dGUpMHgzMCwgKGJ5dGUpMHg4MiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAyLCAoYnl0ZSkweDVkLCAoYnl0ZSkweDAyLCAoYnl0ZSkweDAxLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDAsIChieXRlKTB4MDIsIChieXRlKTB4ODEsIChieXRlKTB4ODEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwMCwgKGJ5dGUpMHhiMiwgKGJ5dGUpMHg0YSwgKGJ5dGUpMHg5YiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDViLCAoYnl0ZSkweGJhLCAoYnl0ZSkweDAxLCAoYnl0ZSkweGMwLAorICAgICAgICAgICAgICAgIChieXRlKTB4Y2QsIChieXRlKTB4NjUsIChieXRlKTB4MDksIChieXRlKTB4NjMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg3MCwgKGJ5dGUpMHgwYiwgKGJ5dGUpMHg1YSwgKGJ5dGUpMHgxYiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDkyLCAoYnl0ZSkweDA4LCAoYnl0ZSkweGY4LCAoYnl0ZSkweDU1LAorICAgICAgICAgICAgICAgIChieXRlKTB4NWUsIChieXRlKTB4N2MsIChieXRlKTB4MWIsIChieXRlKTB4NTAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgxNywgKGJ5dGUpMHhlYywgKGJ5dGUpMHg0NCwgKGJ5dGUpMHg0YywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDU4LCAoYnl0ZSkweDQyLCAoYnl0ZSkweDJiLCAoYnl0ZSkweDQxLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDksIChieXRlKTB4NTksIChieXRlKTB4ZjIsIChieXRlKTB4ZTEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1ZCwgKGJ5dGUpMHg0MywgKGJ5dGUpMHg3MSwgKGJ5dGUpMHg0ZCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDkyLCAoYnl0ZSkweDAzLCAoYnl0ZSkweDFkLCAoYnl0ZSkweGI2LAorICAgICAgICAgICAgICAgIChieXRlKTB4NmMsIChieXRlKTB4N2YsIChieXRlKTB4NWQsIChieXRlKTB4NDgsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhjZCwgKGJ5dGUpMHgxNywgKGJ5dGUpMHhlYywgKGJ5dGUpMHhkNywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDRjLCAoYnl0ZSkweDM5LCAoYnl0ZSkweGIxLCAoYnl0ZSkweDdiLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZTIsIChieXRlKTB4YmYsIChieXRlKTB4OTYsIChieXRlKTB4NzcsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhiZSwgKGJ5dGUpMHhkMCwgKGJ5dGUpMHhhMCwgKGJ5dGUpMHhmMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDJkLCAoYnl0ZSkweDZiLCAoYnl0ZSkweDI0LCAoYnl0ZSkweGFhLAorICAgICAgICAgICAgICAgIChieXRlKTB4MTQsIChieXRlKTB4YmEsIChieXRlKTB4ODIsIChieXRlKTB4NzksCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgxMCwgKGJ5dGUpMHg5YiwgKGJ5dGUpMHgxNiwgKGJ5dGUpMHg2OCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDQ3LCAoYnl0ZSkweDgxLCAoYnl0ZSkweDU0LCAoYnl0ZSkweGEyLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZmEsIChieXRlKTB4OTEsIChieXRlKTB4OWUsIChieXRlKTB4MGEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgyYSwgKGJ5dGUpMHg1MywgKGJ5dGUpMHhhNiwgKGJ5dGUpMHhlNywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDllLCAoYnl0ZSkweDdkLCAoYnl0ZSkweDI5LCAoYnl0ZSkweDMzLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZDgsIChieXRlKTB4MDUsIChieXRlKTB4ZmMsIChieXRlKTB4MDIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzZiwgKGJ5dGUpMHhiZCwgKGJ5dGUpMHhjNywgKGJ5dGUpMHg2ZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGVkLCAoYnl0ZSkweGFhLCAoYnl0ZSkweDMwLCAoYnl0ZSkweDZjLAorICAgICAgICAgICAgICAgIChieXRlKTB4NWYsIChieXRlKTB4NTIsIChieXRlKTB4ZWQsIChieXRlKTB4MzUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2NSwgKGJ5dGUpMHg0YiwgKGJ5dGUpMHgwZSwgKGJ5dGUpMHhjOCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGE3LCAoYnl0ZSkweDEyLCAoYnl0ZSkweDEwLCAoYnl0ZSkweDU2LAorICAgICAgICAgICAgICAgIChieXRlKTB4MzcsIChieXRlKTB4YWYsIChieXRlKTB4MTEsIChieXRlKTB4ZmEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgyMSwgKGJ5dGUpMHgwZSwgKGJ5dGUpMHg5OSwgKGJ5dGUpMHhmZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGZhLCAoYnl0ZSkweDhjLCAoYnl0ZSkweDY1LCAoYnl0ZSkweDhlLAorICAgICAgICAgICAgICAgIChieXRlKTB4NmQsIChieXRlKTB4MDIsIChieXRlKTB4MDMsIChieXRlKTB4MDEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwMCwgKGJ5dGUpMHgwMSwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg4MSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDgwLCAoYnl0ZSkweDc4LCAoYnl0ZSkweDQxLCAoYnl0ZSkweDcyLAorICAgICAgICAgICAgICAgIChieXRlKTB4NDAsIChieXRlKTB4OTAsIChieXRlKTB4NTksIChieXRlKTB4OTYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1ZCwgKGJ5dGUpMHhmMywgKGJ5dGUpMHg4NCwgKGJ5dGUpMHgzZCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDk5LCAoYnl0ZSkweGQ5LCAoYnl0ZSkweDRlLCAoYnl0ZSkweDUxLAorICAgICAgICAgICAgICAgIChieXRlKTB4YzIsIChieXRlKTB4NTIsIChieXRlKTB4NjIsIChieXRlKTB4OGQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhkMiwgKGJ5dGUpMHg0OSwgKGJ5dGUpMHgwYiwgKGJ5dGUpMHg3MywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDFlLCAoYnl0ZSkweDZmLCAoYnl0ZSkweGIyLCAoYnl0ZSkweDMxLAorICAgICAgICAgICAgICAgIChieXRlKTB4N2MsIChieXRlKTB4NjYsIChieXRlKTB4NDUsIChieXRlKTB4MWUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg3YywgKGJ5dGUpMHhkYywgKGJ5dGUpMHgzYSwgKGJ5dGUpMHhjMiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDVmLCAoYnl0ZSkweDUxLCAoYnl0ZSkweDlhLCAoYnl0ZSkweDFlLAorICAgICAgICAgICAgICAgIChieXRlKTB4YTQsIChieXRlKTB4MTksIChieXRlKTB4OGQsIChieXRlKTB4ZjQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhmOSwgKGJ5dGUpMHg4MSwgKGJ5dGUpMHg3ZSwgKGJ5dGUpMHhiZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDE3LCAoYnl0ZSkweGY3LCAoYnl0ZSkweGM3LCAoYnl0ZSkweDNjLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDAsIChieXRlKTB4YTEsIChieXRlKTB4ZjksIChieXRlKTB4NjAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg4MiwgKGJ5dGUpMHgzNCwgKGJ5dGUpMHg4ZiwgKGJ5dGUpMHg5YywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGZkLCAoYnl0ZSkweDBiLCAoYnl0ZSkweDYzLCAoYnl0ZSkweDQyLAorICAgICAgICAgICAgICAgIChieXRlKTB4MWIsIChieXRlKTB4N2YsIChieXRlKTB4NDUsIChieXRlKTB4ZjEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzMSwgKGJ5dGUpMHhjMywgKGJ5dGUpMHg2MywgKGJ5dGUpMHg0NywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDVjLCAoYnl0ZSkweGMxLCAoYnl0ZSkweGIyLCAoYnl0ZSkweDVmLAorICAgICAgICAgICAgICAgIChieXRlKTB4NTcsIChieXRlKTB4ZWUsIChieXRlKTB4MDIsIChieXRlKTB4OWYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1ZSwgKGJ5dGUpMHgwOCwgKGJ5dGUpMHg0OCwgKGJ5dGUpMHhiYSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDc0LCAoYnl0ZSkweGJhLCAoYnl0ZSkweDgxLCAoYnl0ZSkweGI3LAorICAgICAgICAgICAgICAgIChieXRlKTB4MzAsIChieXRlKTB4YWMsIChieXRlKTB4NGMsIChieXRlKTB4MDEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzNSwgKGJ5dGUpMHhjZSwgKGJ5dGUpMHg0NiwgKGJ5dGUpMHg0NywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDhjLCAoYnl0ZSkweGU0LCAoYnl0ZSkweDYyLCAoYnl0ZSkweDM2LAorICAgICAgICAgICAgICAgIChieXRlKTB4MWEsIChieXRlKTB4NjUsIChieXRlKTB4MGUsIChieXRlKTB4MzMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1NiwgKGJ5dGUpMHhmOSwgKGJ5dGUpMHhiNywgKGJ5dGUpMHhhMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGM0LCAoYnl0ZSkweGI2LCAoYnl0ZSkweDgyLCAoYnl0ZSkweDU1LAorICAgICAgICAgICAgICAgIChieXRlKTB4N2QsIChieXRlKTB4MzYsIChieXRlKTB4NTUsIChieXRlKTB4YzAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1MiwgKGJ5dGUpMHg1ZSwgKGJ5dGUpMHgzNSwgKGJ5dGUpMHg1NCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGJkLCAoYnl0ZSkweDk3LCAoYnl0ZSkweDAxLCAoYnl0ZSkweDAwLAorICAgICAgICAgICAgICAgIChieXRlKTB4YmYsIChieXRlKTB4MTAsIChieXRlKTB4ZGMsIChieXRlKTB4MWIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1MSwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg0MSwgKGJ5dGUpMHgwMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGU3LCAoYnl0ZSkweDY4LCAoYnl0ZSkweDAzLCAoYnl0ZSkweDNlLAorICAgICAgICAgICAgICAgIChieXRlKTB4MjEsIChieXRlKTB4NjQsIChieXRlKTB4NjgsIChieXRlKTB4MjQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg3YiwgKGJ5dGUpMHhkMCwgKGJ5dGUpMHgzMSwgKGJ5dGUpMHhhMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGEyLCAoYnl0ZSkweGQ5LCAoYnl0ZSkweDg3LCAoYnl0ZSkweDZkLAorICAgICAgICAgICAgICAgIChieXRlKTB4NzksIChieXRlKTB4ODEsIChieXRlKTB4OGYsIChieXRlKTB4OGYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgyZCwgKGJ5dGUpMHg3YSwgKGJ5dGUpMHg5NSwgKGJ5dGUpMHgyZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDU1LCAoYnl0ZSkweDlmLCAoYnl0ZSkweGQ3LCAoYnl0ZSkweDg2LAorICAgICAgICAgICAgICAgIChieXRlKTB4MjksIChieXRlKTB4OTMsIChieXRlKTB4YmQsIChieXRlKTB4MDQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg3ZSwgKGJ5dGUpMHg0ZiwgKGJ5dGUpMHhkYiwgKGJ5dGUpMHg1NiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGYxLCAoYnl0ZSkweDc1LCAoYnl0ZSkweGQwLCAoYnl0ZSkweDRiLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDAsIChieXRlKTB4M2EsIChieXRlKTB4ZTAsIChieXRlKTB4MjYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhmNiwgKGJ5dGUpMHhhYiwgKGJ5dGUpMHg5ZSwgKGJ5dGUpMHgwYiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDJhLCAoYnl0ZSkweGY0LCAoYnl0ZSkweGE4LCAoYnl0ZSkweGQ3LAorICAgICAgICAgICAgICAgIChieXRlKTB4ZmYsIChieXRlKTB4YmUsIChieXRlKTB4MDEsIChieXRlKTB4ZWIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg5YiwgKGJ5dGUpMHg4MSwgKGJ5dGUpMHhjNywgKGJ5dGUpMHg1ZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAyLCAoYnl0ZSkweDczLCAoYnl0ZSkweGUxLCAoYnl0ZSkweDJiLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDIsIChieXRlKTB4NDEsIChieXRlKTB4MDAsIChieXRlKTB4YzUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzZCwgKGJ5dGUpMHg3OCwgKGJ5dGUpMHhhYiwgKGJ5dGUpMHhlNiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGFiLCAoYnl0ZSkweDNlLCAoYnl0ZSkweDI5LCAoYnl0ZSkweGZkLAorICAgICAgICAgICAgICAgIChieXRlKTB4OTgsIChieXRlKTB4ZDAsIChieXRlKTB4YTQsIChieXRlKTB4M2UsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1OCwgKGJ5dGUpMHhlZSwgKGJ5dGUpMHg0OCwgKGJ5dGUpMHg0NSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGEzLCAoYnl0ZSkweDY2LCAoYnl0ZSkweGFjLCAoYnl0ZSkweGU5LAorICAgICAgICAgICAgICAgIChieXRlKTB4NGQsIChieXRlKTB4YmQsIChieXRlKTB4NjAsIChieXRlKTB4ZWEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgyNCwgKGJ5dGUpMHhmZiwgKGJ5dGUpMHhlZCwgKGJ5dGUpMHgwYywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDY3LCAoYnl0ZSkweGM1LCAoYnl0ZSkweGZkLCAoYnl0ZSkweDM2LAorICAgICAgICAgICAgICAgIChieXRlKTB4MjgsIChieXRlKTB4ZWEsIChieXRlKTB4NzQsIChieXRlKTB4ODgsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhkMSwgKGJ5dGUpMHhkMSwgKGJ5dGUpMHhhZCwgKGJ5dGUpMHg1OCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGQ3LCAoYnl0ZSkweGYwLCAoYnl0ZSkweDY3LCAoYnl0ZSkweDIwLAorICAgICAgICAgICAgICAgIChieXRlKTB4YzEsIChieXRlKTB4ZTMsIChieXRlKTB4YjMsIChieXRlKTB4ZGIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1MiwgKGJ5dGUpMHhhZCwgKGJ5dGUpMHhmMywgKGJ5dGUpMHhjNCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDIxLCAoYnl0ZSkweGQ4LCAoYnl0ZSkweDhjLCAoYnl0ZSkweDRjLAorICAgICAgICAgICAgICAgIChieXRlKTB4NDEsIChieXRlKTB4MjcsIChieXRlKTB4ZGIsIChieXRlKTB4ZDAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzNSwgKGJ5dGUpMHg5MiwgKGJ5dGUpMHhjNywgKGJ5dGUpMHgwMiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDQxLCAoYnl0ZSkweDAwLCAoYnl0ZSkweGUwLCAoYnl0ZSkweDk5LAorICAgICAgICAgICAgICAgIChieXRlKTB4NDIsIChieXRlKTB4YjQsIChieXRlKTB4NzYsIChieXRlKTB4MDIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg5NywgKGJ5dGUpMHg1NSwgKGJ5dGUpMHhmOSwgKGJ5dGUpMHhkYSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDNiLCAoYnl0ZSkweGEwLCAoYnl0ZSkweGQ3LCAoYnl0ZSkweDBlLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZGMsIChieXRlKTB4ZjQsIChieXRlKTB4MzMsIChieXRlKTB4N2YsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhiZCwgKGJ5dGUpMHhjZiwgKGJ5dGUpMHhkMCwgKGJ5dGUpMHhlYiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDZlLCAoYnl0ZSkweDg5LCAoYnl0ZSkweGY3LCAoYnl0ZSkweDRmLAorICAgICAgICAgICAgICAgIChieXRlKTB4NWEsIChieXRlKTB4MDcsIChieXRlKTB4N2MsIChieXRlKTB4YTksCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg0OSwgKGJ5dGUpMHg0NywgKGJ5dGUpMHg2OCwgKGJ5dGUpMHgzNSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGE4LCAoYnl0ZSkweDA1LCAoYnl0ZSkweDNkLCAoYnl0ZSkweGZkLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDQsIChieXRlKTB4N2IsIChieXRlKTB4MTcsIChieXRlKTB4MzEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwZCwgKGJ5dGUpMHhjOCwgKGJ5dGUpMHhhMywgKGJ5dGUpMHg5OCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDM0LCAoYnl0ZSkweGEwLCAoYnl0ZSkweDUwLCAoYnl0ZSkweDQ0LAorICAgICAgICAgICAgICAgIChieXRlKTB4MDAsIChieXRlKTB4ZjEsIChieXRlKTB4MGMsIChieXRlKTB4ZTYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhlNSwgKGJ5dGUpMHhjNCwgKGJ5dGUpMHg0MSwgKGJ5dGUpMHgzZCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGY4LCAoYnl0ZSkweDNkLCAoYnl0ZSkweDRlLCAoYnl0ZSkweDBiLAorICAgICAgICAgICAgICAgIChieXRlKTB4MWMsIChieXRlKTB4ZGIsIChieXRlKTB4MDIsIChieXRlKTB4NDEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwMCwgKGJ5dGUpMHg4MiwgKGJ5dGUpMHg5YiwgKGJ5dGUpMHg4YSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGZkLCAoYnl0ZSkweGExLCAoYnl0ZSkweDk4LCAoYnl0ZSkweDQxLAorICAgICAgICAgICAgICAgIChieXRlKTB4NjgsIChieXRlKTB4YzIsIChieXRlKTB4ZDEsIChieXRlKTB4ZGYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg0ZSwgKGJ5dGUpMHhmMywgKGJ5dGUpMHgyZSwgKGJ5dGUpMHgyNiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDUzLCAoYnl0ZSkweDViLCAoYnl0ZSkweDMxLCAoYnl0ZSkweGIxLAorICAgICAgICAgICAgICAgIChieXRlKTB4N2EsIChieXRlKTB4Y2MsIChieXRlKTB4NWUsIChieXRlKTB4YmIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwOSwgKGJ5dGUpMHhhMiwgKGJ5dGUpMHhlMiwgKGJ5dGUpMHg2ZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDRhLCAoYnl0ZSkweDA0LCAoYnl0ZSkweDBkLCAoYnl0ZSkweGVmLAorICAgICAgICAgICAgICAgIChieXRlKTB4OTAsIChieXRlKTB4MTUsIChieXRlKTB4YmUsIChieXRlKTB4MTAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg0YSwgKGJ5dGUpMHhhYywgKGJ5dGUpMHg5MiwgKGJ5dGUpMHhlYiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGRhLCAoYnl0ZSkweDcyLCAoYnl0ZSkweGRiLCAoYnl0ZSkweDQzLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDgsIChieXRlKTB4YjcsIChieXRlKTB4MmIsIChieXRlKTB4NGMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhlMSwgKGJ5dGUpMHhiYiwgKGJ5dGUpMHg1OCwgKGJ5dGUpMHhjYiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDcxLCAoYnl0ZSkweDgwLCAoYnl0ZSkweGFkLCAoYnl0ZSkweGJjLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZGMsIChieXRlKTB4NjIsIChieXRlKTB4NWUsIChieXRlKTB4M2UsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhjYiwgKGJ5dGUpMHg5MiwgKGJ5dGUpMHhkYSwgKGJ5dGUpMHhmNiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGRmLCAoYnl0ZSkweDAyLCAoYnl0ZSkweDQwLCAoYnl0ZSkweDRkLAorICAgICAgICAgICAgICAgIChieXRlKTB4ODEsIChieXRlKTB4OTAsIChieXRlKTB4YzUsIChieXRlKTB4NzcsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzMCwgKGJ5dGUpMHhiNywgKGJ5dGUpMHgyOSwgKGJ5dGUpMHgwMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGE4LCAoYnl0ZSkweGYxLCAoYnl0ZSkweGI0LCAoYnl0ZSkweGFlLAorICAgICAgICAgICAgICAgIChieXRlKTB4NTIsIChieXRlKTB4NjMsIChieXRlKTB4MDAsIChieXRlKTB4YjIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgyZCwgKGJ5dGUpMHgzZSwgKGJ5dGUpMHg3ZCwgKGJ5dGUpMHhkNiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDRkLCAoYnl0ZSkweGY5LCAoYnl0ZSkweDhhLCAoYnl0ZSkweGMxLAorICAgICAgICAgICAgICAgIChieXRlKTB4YjEsIChieXRlKTB4OTgsIChieXRlKTB4ODksIChieXRlKTB4NTIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg0MCwgKGJ5dGUpMHgxNCwgKGJ5dGUpMHgxYiwgKGJ5dGUpMHgwZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDYxLCAoYnl0ZSkweDhmLCAoYnl0ZSkweGY0LCAoYnl0ZSkweGJlLAorICAgICAgICAgICAgICAgIChieXRlKTB4NTksIChieXRlKTB4NzksIChieXRlKTB4NzksIChieXRlKTB4OTUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgxOSwgKGJ5dGUpMHg1YywgKGJ5dGUpMHg1MSwgKGJ5dGUpMHgwOCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDY2LCAoYnl0ZSkweGMxLCAoYnl0ZSkweDQyLCAoYnl0ZSkweDMwLAorICAgICAgICAgICAgICAgIChieXRlKTB4YjMsIChieXRlKTB4N2EsIChieXRlKTB4ODYsIChieXRlKTB4OWYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzZSwgKGJ5dGUpMHhmNSwgKGJ5dGUpMHgxOSwgKGJ5dGUpMHhhMywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGFlLCAoYnl0ZSkweDY0LCAoYnl0ZSkweDY5LCAoYnl0ZSkweDE0LAorICAgICAgICAgICAgICAgIChieXRlKTB4MDcsIChieXRlKTB4NTAsIChieXRlKTB4OTcKKyAgICAgICAgfSk7CisgICAgICAgIHB1YmxpY0tleUVuY29kaW5nLnB1dCgiUlNBIiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzMCwgKGJ5dGUpMHg4MSwgKGJ5dGUpMHg5ZiwgKGJ5dGUpMHgzMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDBkLCAoYnl0ZSkweDA2LCAoYnl0ZSkweDA5LCAoYnl0ZSkweDJhLAorICAgICAgICAgICAgICAgIChieXRlKTB4ODYsIChieXRlKTB4NDgsIChieXRlKTB4ODYsIChieXRlKTB4ZjcsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwZCwgKGJ5dGUpMHgwMSwgKGJ5dGUpMHgwMSwgKGJ5dGUpMHgwMSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDA1LCAoYnl0ZSkweDAwLCAoYnl0ZSkweDAzLCAoYnl0ZSkweDgxLAorICAgICAgICAgICAgICAgIChieXRlKTB4OGQsIChieXRlKTB4MDAsIChieXRlKTB4MzAsIChieXRlKTB4ODEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg4OSwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg4MSwgKGJ5dGUpMHg4MSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAwLCAoYnl0ZSkweGIyLCAoYnl0ZSkweDRhLCAoYnl0ZSkweDliLAorICAgICAgICAgICAgICAgIChieXRlKTB4NWIsIChieXRlKTB4YmEsIChieXRlKTB4MDEsIChieXRlKTB4YzAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhjZCwgKGJ5dGUpMHg2NSwgKGJ5dGUpMHgwOSwgKGJ5dGUpMHg2MywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDcwLCAoYnl0ZSkweDBiLCAoYnl0ZSkweDVhLCAoYnl0ZSkweDFiLAorICAgICAgICAgICAgICAgIChieXRlKTB4OTIsIChieXRlKTB4MDgsIChieXRlKTB4ZjgsIChieXRlKTB4NTUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1ZSwgKGJ5dGUpMHg3YywgKGJ5dGUpMHgxYiwgKGJ5dGUpMHg1MCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDE3LCAoYnl0ZSkweGVjLCAoYnl0ZSkweDQ0LCAoYnl0ZSkweDRjLAorICAgICAgICAgICAgICAgIChieXRlKTB4NTgsIChieXRlKTB4NDIsIChieXRlKTB4MmIsIChieXRlKTB4NDEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwOSwgKGJ5dGUpMHg1OSwgKGJ5dGUpMHhmMiwgKGJ5dGUpMHhlMSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDVkLCAoYnl0ZSkweDQzLCAoYnl0ZSkweDcxLCAoYnl0ZSkweDRkLAorICAgICAgICAgICAgICAgIChieXRlKTB4OTIsIChieXRlKTB4MDMsIChieXRlKTB4MWQsIChieXRlKTB4YjYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2YywgKGJ5dGUpMHg3ZiwgKGJ5dGUpMHg1ZCwgKGJ5dGUpMHg0OCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGNkLCAoYnl0ZSkweDE3LCAoYnl0ZSkweGVjLCAoYnl0ZSkweGQ3LAorICAgICAgICAgICAgICAgIChieXRlKTB4NGMsIChieXRlKTB4MzksIChieXRlKTB4YjEsIChieXRlKTB4N2IsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhlMiwgKGJ5dGUpMHhiZiwgKGJ5dGUpMHg5NiwgKGJ5dGUpMHg3NywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGJlLCAoYnl0ZSkweGQwLCAoYnl0ZSkweGEwLCAoYnl0ZSkweGYwLAorICAgICAgICAgICAgICAgIChieXRlKTB4MmQsIChieXRlKTB4NmIsIChieXRlKTB4MjQsIChieXRlKTB4YWEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgxNCwgKGJ5dGUpMHhiYSwgKGJ5dGUpMHg4MiwgKGJ5dGUpMHg3OSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDEwLCAoYnl0ZSkweDliLCAoYnl0ZSkweDE2LCAoYnl0ZSkweDY4LAorICAgICAgICAgICAgICAgIChieXRlKTB4NDcsIChieXRlKTB4ODEsIChieXRlKTB4NTQsIChieXRlKTB4YTIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhmYSwgKGJ5dGUpMHg5MSwgKGJ5dGUpMHg5ZSwgKGJ5dGUpMHgwYSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDJhLCAoYnl0ZSkweDUzLCAoYnl0ZSkweGE2LCAoYnl0ZSkweGU3LAorICAgICAgICAgICAgICAgIChieXRlKTB4OWUsIChieXRlKTB4N2QsIChieXRlKTB4MjksIChieXRlKTB4MzMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhkOCwgKGJ5dGUpMHgwNSwgKGJ5dGUpMHhmYywgKGJ5dGUpMHgwMiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDNmLCAoYnl0ZSkweGJkLCAoYnl0ZSkweGM3LCAoYnl0ZSkweDZlLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZWQsIChieXRlKTB4YWEsIChieXRlKTB4MzAsIChieXRlKTB4NmMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1ZiwgKGJ5dGUpMHg1MiwgKGJ5dGUpMHhlZCwgKGJ5dGUpMHgzNSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDY1LCAoYnl0ZSkweDRiLCAoYnl0ZSkweDBlLCAoYnl0ZSkweGM4LAorICAgICAgICAgICAgICAgIChieXRlKTB4YTcsIChieXRlKTB4MTIsIChieXRlKTB4MTAsIChieXRlKTB4NTYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzNywgKGJ5dGUpMHhhZiwgKGJ5dGUpMHgxMSwgKGJ5dGUpMHhmYSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDIxLCAoYnl0ZSkweDBlLCAoYnl0ZSkweDk5LCAoYnl0ZSkweGZmLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZmEsIChieXRlKTB4OGMsIChieXRlKTB4NjUsIChieXRlKTB4OGUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2ZCwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHgwMywgKGJ5dGUpMHgwMSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAwLCAoYnl0ZSkweDAxCisgICAgICAgIH0pOworICAgICAgICBwcml2YXRlS2V5RW5jb2RpbmcucHV0KCJEU0EiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDMwLCAoYnl0ZSkweDgyLCAoYnl0ZSkweDAxLCAoYnl0ZSkweDRhLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDIsIChieXRlKTB4MDEsIChieXRlKTB4MDAsIChieXRlKTB4MzAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg4MiwgKGJ5dGUpMHgwMSwgKGJ5dGUpMHgyYiwgKGJ5dGUpMHgwNiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDA3LCAoYnl0ZSkweDJhLCAoYnl0ZSkweDg2LCAoYnl0ZSkweDQ4LAorICAgICAgICAgICAgICAgIChieXRlKTB4Y2UsIChieXRlKTB4MzgsIChieXRlKTB4MDQsIChieXRlKTB4MDEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzMCwgKGJ5dGUpMHg4MiwgKGJ5dGUpMHgwMSwgKGJ5dGUpMHgxZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAyLCAoYnl0ZSkweDgxLCAoYnl0ZSkweDgxLCAoYnl0ZSkweDAwLAorICAgICAgICAgICAgICAgIChieXRlKTB4Y2EsIChieXRlKTB4ODQsIChieXRlKTB4MWQsIChieXRlKTB4YTMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhhYiwgKGJ5dGUpMHhiOSwgKGJ5dGUpMHg5OCwgKGJ5dGUpMHhmNCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDYxLCAoYnl0ZSkweDhiLCAoYnl0ZSkweDY2LCAoYnl0ZSkweGRiLAorICAgICAgICAgICAgICAgIChieXRlKTB4NGUsIChieXRlKTB4M2EsIChieXRlKTB4YjIsIChieXRlKTB4MTEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg0ZSwgKGJ5dGUpMHhhOSwgKGJ5dGUpMHhkYSwgKGJ5dGUpMHgzNSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDkxLCAoYnl0ZSkweGM5LCAoYnl0ZSkweDRlLCAoYnl0ZSkweGMzLAorICAgICAgICAgICAgICAgIChieXRlKTB4MTYsIChieXRlKTB4YTcsIChieXRlKTB4ZWQsIChieXRlKTB4YjgsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg4ZiwgKGJ5dGUpMHhkNywgKGJ5dGUpMHhlYSwgKGJ5dGUpMHhlYSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGRiLCAoYnl0ZSkweDc3LCAoYnl0ZSkweGUxLCAoYnl0ZSkweDc3LAorICAgICAgICAgICAgICAgIChieXRlKTB4N2EsIChieXRlKTB4YzksIChieXRlKTB4ZjMsIChieXRlKTB4MzcsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzMywgKGJ5dGUpMHgwMSwgKGJ5dGUpMHg3MiwgKGJ5dGUpMHhiYywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGQwLCAoYnl0ZSkweDg5LCAoYnl0ZSkweDliLCAoYnl0ZSkweDE4LAorICAgICAgICAgICAgICAgIChieXRlKTB4ZmQsIChieXRlKTB4ODQsIChieXRlKTB4ZDYsIChieXRlKTB4ZTksCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhiZiwgKGJ5dGUpMHgxMywgKGJ5dGUpMHgzNSwgKGJ5dGUpMHg1ZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDQwLCAoYnl0ZSkweGY2LCAoYnl0ZSkweDlkLCAoYnl0ZSkweGQ5LAorICAgICAgICAgICAgICAgIChieXRlKTB4MWEsIChieXRlKTB4YmEsIChieXRlKTB4YTksIChieXRlKTB4YzMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg4YywgKGJ5dGUpMHhlMywgKGJ5dGUpMHg5NSwgKGJ5dGUpMHhjOCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGRmLCAoYnl0ZSkweDJlLCAoYnl0ZSkweDQxLCAoYnl0ZSkweGExLAorICAgICAgICAgICAgICAgIChieXRlKTB4YmYsIChieXRlKTB4ZGUsIChieXRlKTB4NWQsIChieXRlKTB4YWQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgyMSwgKGJ5dGUpMHhjYywgKGJ5dGUpMHgwZCwgKGJ5dGUpMHg0MiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDU2LCAoYnl0ZSkweGEwLCAoYnl0ZSkweDMyLCAoYnl0ZSkweGMwLAorICAgICAgICAgICAgICAgIChieXRlKTB4OTAsIChieXRlKTB4NzMsIChieXRlKTB4M2UsIChieXRlKTB4YTQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwZSwgKGJ5dGUpMHg1OCwgKGJ5dGUpMHhlNCwgKGJ5dGUpMHg2NCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAwLCAoYnl0ZSkweGEzLCAoYnl0ZSkweDI3LCAoYnl0ZSkweDQ5LAorICAgICAgICAgICAgICAgIChieXRlKTB4NTYsIChieXRlKTB4YjIsIChieXRlKTB4NDMsIChieXRlKTB4YmMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg3MiwgKGJ5dGUpMHhhOCwgKGJ5dGUpMHhkMiwgKGJ5dGUpMHgyNiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDg5LCAoYnl0ZSkweDM1LCAoYnl0ZSkweDM3LCAoYnl0ZSkweDI5LAorICAgICAgICAgICAgICAgIChieXRlKTB4OGQsIChieXRlKTB4MjEsIChieXRlKTB4YjUsIChieXRlKTB4OGUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1OSwgKGJ5dGUpMHhmYSwgKGJ5dGUpMHg5ZSwgKGJ5dGUpMHhkZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDM3LCAoYnl0ZSkweDBkLCAoYnl0ZSkweDllLCAoYnl0ZSkweGFiLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZmQsIChieXRlKTB4YmYsIChieXRlKTB4MWEsIChieXRlKTB4OWUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhmMywgKGJ5dGUpMHhlOCwgKGJ5dGUpMHgzYSwgKGJ5dGUpMHhmYiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAyLCAoYnl0ZSkweDE1LCAoYnl0ZSkweDAwLCAoYnl0ZSkweGEyLAorICAgICAgICAgICAgICAgIChieXRlKTB4NGUsIChieXRlKTB4NWQsIChieXRlKTB4ZTMsIChieXRlKTB4MTAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1ZCwgKGJ5dGUpMHhhOSwgKGJ5dGUpMHgzYSwgKGJ5dGUpMHg2YSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDRkLCAoYnl0ZSkweDA3LCAoYnl0ZSkweDNiLCAoYnl0ZSkweGFiLAorICAgICAgICAgICAgICAgIChieXRlKTB4Y2EsIChieXRlKTB4N2QsIChieXRlKTB4MDksIChieXRlKTB4ZDYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwNiwgKGJ5dGUpMHg3OSwgKGJ5dGUpMHg0OSwgKGJ5dGUpMHgwMiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDgxLCAoYnl0ZSkweDgwLCAoYnl0ZSkweDVhLCAoYnl0ZSkweDkxLAorICAgICAgICAgICAgICAgIChieXRlKTB4ODMsIChieXRlKTB4MWMsIChieXRlKTB4MDQsIChieXRlKTB4MzMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhjYSwgKGJ5dGUpMHgyNSwgKGJ5dGUpMHhiMCwgKGJ5dGUpMHg2OCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGIzLCAoYnl0ZSkweGIzLCAoYnl0ZSkweGFiLCAoYnl0ZSkweDU1LAorICAgICAgICAgICAgICAgIChieXRlKTB4MjksIChieXRlKTB4MzMsIChieXRlKTB4NGQsIChieXRlKTB4YTksCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzMywgKGJ5dGUpMHgzOSwgKGJ5dGUpMHhlZiwgKGJ5dGUpMHg3MSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGNhLCAoYnl0ZSkweDk1LCAoYnl0ZSkweGYzLCAoYnl0ZSkweGQ4LAorICAgICAgICAgICAgICAgIChieXRlKTB4MjcsIChieXRlKTB4NTYsIChieXRlKTB4NWYsIChieXRlKTB4NDIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhkYSwgKGJ5dGUpMHgzNiwgKGJ5dGUpMHg4MywgKGJ5dGUpMHhjNSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGYxLCAoYnl0ZSkweDUzLCAoYnl0ZSkweDYyLCAoYnl0ZSkweGE1LAorICAgICAgICAgICAgICAgIChieXRlKTB4ZGMsIChieXRlKTB4ZTYsIChieXRlKTB4NGUsIChieXRlKTB4NjksCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg0NSwgKGJ5dGUpMHg3MSwgKGJ5dGUpMHgxYSwgKGJ5dGUpMHg0YSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGMzLCAoYnl0ZSkweGY0LCAoYnl0ZSkweDdmLCAoYnl0ZSkweDBhLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZDEsIChieXRlKTB4NzgsIChieXRlKTB4ZWQsIChieXRlKTB4YmUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2ZSwgKGJ5dGUpMHhhNiwgKGJ5dGUpMHgzNiwgKGJ5dGUpMHgzNCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDRlLCAoYnl0ZSkweGMzLCAoYnl0ZSkweDFiLCAoYnl0ZSkweDE3LAorICAgICAgICAgICAgICAgIChieXRlKTB4YWEsIChieXRlKTB4YTQsIChieXRlKTB4NzYsIChieXRlKTB4NDQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg0NiwgKGJ5dGUpMHhhZiwgKGJ5dGUpMHgyNiwgKGJ5dGUpMHgxNiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDE0LCAoYnl0ZSkweGZiLCAoYnl0ZSkweDlmLCAoYnl0ZSkweDVkLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDgsIChieXRlKTB4YWYsIChieXRlKTB4OTIsIChieXRlKTB4ZGIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhiYSwgKGJ5dGUpMHhkMCwgKGJ5dGUpMHhjYiwgKGJ5dGUpMHg4YiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDFlLCAoYnl0ZSkweGMzLCAoYnl0ZSkweDhiLCAoYnl0ZSkweDM2LAorICAgICAgICAgICAgICAgIChieXRlKTB4M2IsIChieXRlKTB4NGMsIChieXRlKTB4MDIsIChieXRlKTB4YzMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2NiwgKGJ5dGUpMHgyOCwgKGJ5dGUpMHg2OSwgKGJ5dGUpMHhkMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDc0LCAoYnl0ZSkweDRmLCAoYnl0ZSkweDFjLCAoYnl0ZSkweDRmLAorICAgICAgICAgICAgICAgIChieXRlKTB4OTcsIChieXRlKTB4NzUsIChieXRlKTB4N2YsIChieXRlKTB4OWUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg4OSwgKGJ5dGUpMHg4MCwgKGJ5dGUpMHhjZiwgKGJ5dGUpMHhiMiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDE3LCAoYnl0ZSkweGQ2LCAoYnl0ZSkweDY2LCAoYnl0ZSkweDkxLAorICAgICAgICAgICAgICAgIChieXRlKTB4MTIsIChieXRlKTB4M2EsIChieXRlKTB4YjAsIChieXRlKTB4M2MsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzYywgKGJ5dGUpMHhjMiwgKGJ5dGUpMHgzMSwgKGJ5dGUpMHhkMSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDMxLCAoYnl0ZSkweDJhLCAoYnl0ZSkweDM1LCAoYnl0ZSkweGJlLAorICAgICAgICAgICAgICAgIChieXRlKTB4OWQsIChieXRlKTB4NTQsIChieXRlKTB4NzEsIChieXRlKTB4MDMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhjYiwgKGJ5dGUpMHhjYywgKGJ5dGUpMHgwNCwgKGJ5dGUpMHgxNiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAyLCAoYnl0ZSkweDE0LCAoYnl0ZSkweDUyLCAoYnl0ZSkweGZiLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZjksIChieXRlKTB4MTIsIChieXRlKTB4NDAsIChieXRlKTB4MDUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1OSwgKGJ5dGUpMHg4ZiwgKGJ5dGUpMHhkZSwgKGJ5dGUpMHg5ZCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGFjLCAoYnl0ZSkweGExLCAoYnl0ZSkweGUyLCAoYnl0ZSkweGVkLAorICAgICAgICAgICAgICAgIChieXRlKTB4NTYsIChieXRlKTB4NjIsIChieXRlKTB4NWYsIChieXRlKTB4NTYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2NywgKGJ5dGUpMHg3NAorICAgICAgICB9KTsKKyAgICAgICAgcHVibGljS2V5RW5jb2RpbmcucHV0KCJEU0EiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDMwLCAoYnl0ZSkweDgyLCAoYnl0ZSkweDAxLCAoYnl0ZSkweGI3LAorICAgICAgICAgICAgICAgIChieXRlKTB4MzAsIChieXRlKTB4ODIsIChieXRlKTB4MDEsIChieXRlKTB4MmIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwNiwgKGJ5dGUpMHgwNywgKGJ5dGUpMHgyYSwgKGJ5dGUpMHg4NiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDQ4LCAoYnl0ZSkweGNlLCAoYnl0ZSkweDM4LCAoYnl0ZSkweDA0LAorICAgICAgICAgICAgICAgIChieXRlKTB4MDEsIChieXRlKTB4MzAsIChieXRlKTB4ODIsIChieXRlKTB4MDEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgxZSwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg4MSwgKGJ5dGUpMHg4MSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDAwLCAoYnl0ZSkweGNhLCAoYnl0ZSkweDg0LCAoYnl0ZSkweDFkLAorICAgICAgICAgICAgICAgIChieXRlKTB4YTMsIChieXRlKTB4YWIsIChieXRlKTB4YjksIChieXRlKTB4OTgsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhmNCwgKGJ5dGUpMHg2MSwgKGJ5dGUpMHg4YiwgKGJ5dGUpMHg2NiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGRiLCAoYnl0ZSkweDRlLCAoYnl0ZSkweDNhLCAoYnl0ZSkweGIyLAorICAgICAgICAgICAgICAgIChieXRlKTB4MTEsIChieXRlKTB4NGUsIChieXRlKTB4YTksIChieXRlKTB4ZGEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzNSwgKGJ5dGUpMHg5MSwgKGJ5dGUpMHhjOSwgKGJ5dGUpMHg0ZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGMzLCAoYnl0ZSkweDE2LCAoYnl0ZSkweGE3LCAoYnl0ZSkweGVkLAorICAgICAgICAgICAgICAgIChieXRlKTB4YjgsIChieXRlKTB4OGYsIChieXRlKTB4ZDcsIChieXRlKTB4ZWEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhlYSwgKGJ5dGUpMHhkYiwgKGJ5dGUpMHg3NywgKGJ5dGUpMHhlMSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDc3LCAoYnl0ZSkweDdhLCAoYnl0ZSkweGM5LCAoYnl0ZSkweGYzLAorICAgICAgICAgICAgICAgIChieXRlKTB4MzcsIChieXRlKTB4MzMsIChieXRlKTB4MDEsIChieXRlKTB4NzIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhiYywgKGJ5dGUpMHhkMCwgKGJ5dGUpMHg4OSwgKGJ5dGUpMHg5YiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDE4LCAoYnl0ZSkweGZkLCAoYnl0ZSkweDg0LCAoYnl0ZSkweGQ2LAorICAgICAgICAgICAgICAgIChieXRlKTB4ZTksIChieXRlKTB4YmYsIChieXRlKTB4MTMsIChieXRlKTB4MzUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1ZSwgKGJ5dGUpMHg0MCwgKGJ5dGUpMHhmNiwgKGJ5dGUpMHg5ZCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGQ5LCAoYnl0ZSkweDFhLCAoYnl0ZSkweGJhLCAoYnl0ZSkweGE5LAorICAgICAgICAgICAgICAgIChieXRlKTB4YzMsIChieXRlKTB4OGMsIChieXRlKTB4ZTMsIChieXRlKTB4OTUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhjOCwgKGJ5dGUpMHhkZiwgKGJ5dGUpMHgyZSwgKGJ5dGUpMHg0MSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGExLCAoYnl0ZSkweGJmLCAoYnl0ZSkweGRlLCAoYnl0ZSkweDVkLAorICAgICAgICAgICAgICAgIChieXRlKTB4YWQsIChieXRlKTB4MjEsIChieXRlKTB4Y2MsIChieXRlKTB4MGQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg0MiwgKGJ5dGUpMHg1NiwgKGJ5dGUpMHhhMCwgKGJ5dGUpMHgzMiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGMwLCAoYnl0ZSkweDkwLCAoYnl0ZSkweDczLCAoYnl0ZSkweDNlLAorICAgICAgICAgICAgICAgIChieXRlKTB4YTQsIChieXRlKTB4MGUsIChieXRlKTB4NTgsIChieXRlKTB4ZTQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2NCwgKGJ5dGUpMHgwMCwgKGJ5dGUpMHhhMywgKGJ5dGUpMHgyNywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDQ5LCAoYnl0ZSkweDU2LCAoYnl0ZSkweGIyLCAoYnl0ZSkweDQzLAorICAgICAgICAgICAgICAgIChieXRlKTB4YmMsIChieXRlKTB4NzIsIChieXRlKTB4YTgsIChieXRlKTB4ZDIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgyNiwgKGJ5dGUpMHg4OSwgKGJ5dGUpMHgzNSwgKGJ5dGUpMHgzNywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDI5LCAoYnl0ZSkweDhkLCAoYnl0ZSkweDIxLCAoYnl0ZSkweGI1LAorICAgICAgICAgICAgICAgIChieXRlKTB4OGUsIChieXRlKTB4NTksIChieXRlKTB4ZmEsIChieXRlKTB4OWUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhkZiwgKGJ5dGUpMHgzNywgKGJ5dGUpMHgwZCwgKGJ5dGUpMHg5ZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGFiLCAoYnl0ZSkweGZkLCAoYnl0ZSkweGJmLCAoYnl0ZSkweDFhLAorICAgICAgICAgICAgICAgIChieXRlKTB4OWUsIChieXRlKTB4ZjMsIChieXRlKTB4ZTgsIChieXRlKTB4M2EsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhmYiwgKGJ5dGUpMHgwMiwgKGJ5dGUpMHgxNSwgKGJ5dGUpMHgwMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGEyLCAoYnl0ZSkweDRlLCAoYnl0ZSkweDVkLCAoYnl0ZSkweGUzLAorICAgICAgICAgICAgICAgIChieXRlKTB4MTAsIChieXRlKTB4NWQsIChieXRlKTB4YTksIChieXRlKTB4M2EsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2YSwgKGJ5dGUpMHg0ZCwgKGJ5dGUpMHgwNywgKGJ5dGUpMHgzYiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGFiLCAoYnl0ZSkweGNhLCAoYnl0ZSkweDdkLCAoYnl0ZSkweDA5LAorICAgICAgICAgICAgICAgIChieXRlKTB4ZDYsIChieXRlKTB4MDYsIChieXRlKTB4NzksIChieXRlKTB4NDksCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgwMiwgKGJ5dGUpMHg4MSwgKGJ5dGUpMHg4MCwgKGJ5dGUpMHg1YSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDkxLCAoYnl0ZSkweDgzLCAoYnl0ZSkweDFjLCAoYnl0ZSkweDA0LAorICAgICAgICAgICAgICAgIChieXRlKTB4MzMsIChieXRlKTB4Y2EsIChieXRlKTB4MjUsIChieXRlKTB4YjAsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg2OCwgKGJ5dGUpMHhiMywgKGJ5dGUpMHhiMywgKGJ5dGUpMHhhYiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDU1LCAoYnl0ZSkweDI5LCAoYnl0ZSkweDMzLCAoYnl0ZSkweDRkLAorICAgICAgICAgICAgICAgIChieXRlKTB4YTksIChieXRlKTB4MzMsIChieXRlKTB4MzksIChieXRlKTB4ZWYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg3MSwgKGJ5dGUpMHhjYSwgKGJ5dGUpMHg5NSwgKGJ5dGUpMHhmMywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGQ4LCAoYnl0ZSkweDI3LCAoYnl0ZSkweDU2LCAoYnl0ZSkweDVmLAorICAgICAgICAgICAgICAgIChieXRlKTB4NDIsIChieXRlKTB4ZGEsIChieXRlKTB4MzYsIChieXRlKTB4ODMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhjNSwgKGJ5dGUpMHhmMSwgKGJ5dGUpMHg1MywgKGJ5dGUpMHg2MiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGE1LCAoYnl0ZSkweGRjLCAoYnl0ZSkweGU2LCAoYnl0ZSkweDRlLAorICAgICAgICAgICAgICAgIChieXRlKTB4NjksIChieXRlKTB4NDUsIChieXRlKTB4NzEsIChieXRlKTB4MWEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg0YSwgKGJ5dGUpMHhjMywgKGJ5dGUpMHhmNCwgKGJ5dGUpMHg3ZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDBhLCAoYnl0ZSkweGQxLCAoYnl0ZSkweDc4LCAoYnl0ZSkweGVkLAorICAgICAgICAgICAgICAgIChieXRlKTB4YmUsIChieXRlKTB4NmUsIChieXRlKTB4YTYsIChieXRlKTB4MzYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzNCwgKGJ5dGUpMHg0ZSwgKGJ5dGUpMHhjMywgKGJ5dGUpMHgxYiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDE3LCAoYnl0ZSkweGFhLCAoYnl0ZSkweGE0LCAoYnl0ZSkweDc2LAorICAgICAgICAgICAgICAgIChieXRlKTB4NDQsIChieXRlKTB4NDYsIChieXRlKTB4YWYsIChieXRlKTB4MjYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgxNiwgKGJ5dGUpMHgxNCwgKGJ5dGUpMHhmYiwgKGJ5dGUpMHg5ZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDVkLCAoYnl0ZSkweDA4LCAoYnl0ZSkweGFmLCAoYnl0ZSkweDkyLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZGIsIChieXRlKTB4YmEsIChieXRlKTB4ZDAsIChieXRlKTB4Y2IsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg4YiwgKGJ5dGUpMHgxZSwgKGJ5dGUpMHhjMywgKGJ5dGUpMHg4YiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDM2LCAoYnl0ZSkweDNiLCAoYnl0ZSkweDRjLCAoYnl0ZSkweDAyLAorICAgICAgICAgICAgICAgIChieXRlKTB4YzMsIChieXRlKTB4NjYsIChieXRlKTB4MjgsIChieXRlKTB4NjksCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhkMCwgKGJ5dGUpMHg3NCwgKGJ5dGUpMHg0ZiwgKGJ5dGUpMHgxYywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDRmLCAoYnl0ZSkweDk3LCAoYnl0ZSkweDc1LCAoYnl0ZSkweDdmLAorICAgICAgICAgICAgICAgIChieXRlKTB4OWUsIChieXRlKTB4ODksIChieXRlKTB4ODAsIChieXRlKTB4Y2YsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhiMiwgKGJ5dGUpMHgxNywgKGJ5dGUpMHhkNiwgKGJ5dGUpMHg2NiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDkxLCAoYnl0ZSkweDEyLCAoYnl0ZSkweDNhLCAoYnl0ZSkweGIwLAorICAgICAgICAgICAgICAgIChieXRlKTB4M2MsIChieXRlKTB4M2MsIChieXRlKTB4YzIsIChieXRlKTB4MzEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhkMSwgKGJ5dGUpMHgzMSwgKGJ5dGUpMHgyYSwgKGJ5dGUpMHgzNSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGJlLCAoYnl0ZSkweDlkLCAoYnl0ZSkweDU0LCAoYnl0ZSkweDcxLAorICAgICAgICAgICAgICAgIChieXRlKTB4MDMsIChieXRlKTB4Y2IsIChieXRlKTB4Y2MsIChieXRlKTB4MDMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg4MSwgKGJ5dGUpMHg4NSwgKGJ5dGUpMHgwMCwgKGJ5dGUpMHgwMiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDgxLCAoYnl0ZSkweDgxLCAoYnl0ZSkweDAwLCAoYnl0ZSkweDk1LAorICAgICAgICAgICAgICAgIChieXRlKTB4Y2MsIChieXRlKTB4MTEsIChieXRlKTB4ZDQsIChieXRlKTB4NTMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgzZCwgKGJ5dGUpMHg5YywgKGJ5dGUpMHg1YywgKGJ5dGUpMHg3MywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGY0LCAoYnl0ZSkweDcwLCAoYnl0ZSkweGYwLCAoYnl0ZSkweGUxLAorICAgICAgICAgICAgICAgIChieXRlKTB4YWMsIChieXRlKTB4ZTMsIChieXRlKTB4MmMsIChieXRlKTB4MzIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgxNiwgKGJ5dGUpMHgxZCwgKGJ5dGUpMHgzNCwgKGJ5dGUpMHgxYSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDM4LCAoYnl0ZSkweDYzLCAoYnl0ZSkweDY5LCAoYnl0ZSkweDFhLAorICAgICAgICAgICAgICAgIChieXRlKTB4NzIsIChieXRlKTB4MzksIChieXRlKTB4NGUsIChieXRlKTB4NDEsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1MCwgKGJ5dGUpMHhmYSwgKGJ5dGUpMHhkYywgKGJ5dGUpMHg3OCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGE0LCAoYnl0ZSkweGI4LCAoYnl0ZSkweDE3LCAoYnl0ZSkweDVhLAorICAgICAgICAgICAgICAgIChieXRlKTB4ZTQsIChieXRlKTB4ZjksIChieXRlKTB4YTIsIChieXRlKTB4NTIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg0MSwgKGJ5dGUpMHg4NSwgKGJ5dGUpMHhhYiwgKGJ5dGUpMHgzZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGY0LCAoYnl0ZSkweDczLCAoYnl0ZSkweDJlLCAoYnl0ZSkweGFlLAorICAgICAgICAgICAgICAgIChieXRlKTB4YTksIChieXRlKTB4MjEsIChieXRlKTB4OGIsIChieXRlKTB4NWUsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg5NSwgKGJ5dGUpMHgxNSwgKGJ5dGUpMHhhMiwgKGJ5dGUpMHg4NiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDYzLCAoYnl0ZSkweDBkLCAoYnl0ZSkweGJhLCAoYnl0ZSkweDAxLAorICAgICAgICAgICAgICAgIChieXRlKTB4Y2IsIChieXRlKTB4ZTMsIChieXRlKTB4NjgsIChieXRlKTB4YzYsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHhhZiwgKGJ5dGUpMHg1NiwgKGJ5dGUpMHg1MSwgKGJ5dGUpMHg3YiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGE4LCAoYnl0ZSkweDg1LCAoYnl0ZSkweDNmLCAoYnl0ZSkweDAxLAorICAgICAgICAgICAgICAgIChieXRlKTB4ODAsIChieXRlKTB4OGIsIChieXRlKTB4MWYsIChieXRlKTB4YjQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg0YywgKGJ5dGUpMHg5MywgKGJ5dGUpMHg2YiwgKGJ5dGUpMHg0MiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGE2LCAoYnl0ZSkweGJkLCAoYnl0ZSkweDY3LCAoYnl0ZSkweDJhLAorICAgICAgICAgICAgICAgIChieXRlKTB4OTUsIChieXRlKTB4MDUsIChieXRlKTB4ZmYsIChieXRlKTB4MDMsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHgyZSwgKGJ5dGUpMHg2ZiwgKGJ5dGUpMHhkNCwgKGJ5dGUpMHhkMywKKyAgICAgICAgICAgICAgICAoYnl0ZSkweGYwLCAoYnl0ZSkweDE3LCAoYnl0ZSkweGRlLCAoYnl0ZSkweGNiLAorICAgICAgICAgICAgICAgIChieXRlKTB4N2QsIChieXRlKTB4ZDksIChieXRlKTB4NDIsIChieXRlKTB4NGQsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg5NywgKGJ5dGUpMHgyYywgKGJ5dGUpMHg1MywgKGJ5dGUpMHhlNiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDM5LCAoYnl0ZSkweDYxLCAoYnl0ZSkweGQyLCAoYnl0ZSkweDY5LAorICAgICAgICAgICAgICAgIChieXRlKTB4ZDEsIChieXRlKTB4MWMsIChieXRlKTB4OWEsIChieXRlKTB4OGIsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg1YiwgKGJ5dGUpMHg5YywgKGJ5dGUpMHhmYSwgKGJ5dGUpMHhmYSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkweDUwLCAoYnl0ZSkweDUwLCAoYnl0ZSkweGJiLCAoYnl0ZSkweGU0LAorICAgICAgICAgICAgICAgIChieXRlKTB4MmUsIChieXRlKTB4ODMsIChieXRlKTB4MDYsIChieXRlKTB4MDgsCisgICAgICAgICAgICAgICAgKGJ5dGUpMHg5NiwgKGJ5dGUpMHgyYSwgKGJ5dGUpMHg2OAorICAgICAgICB9KTsKKyAgICAgICAgcHJpdmF0ZUtleUVuY29kaW5nLnB1dCgiREgiLCBuZXcgYnl0ZVtdIHsKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4ZmZmZmZmODEsIChieXRlKSAweGZmZmZmZmUxLCAoYnl0ZSkgMHgyLAorICAgICAgICAgICAgICAgIChieXRlKSAweDEsIChieXRlKSAweDAsIChieXRlKSAweDMwLCAoYnl0ZSkgMHhmZmZmZmY4MSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmY5NywgKGJ5dGUpIDB4NiwgKGJ5dGUpIDB4OSwgKGJ5dGUpIDB4MmEsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmODYsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHhmZmZmZmY4NiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZmNywgKGJ5dGUpIDB4ZCwgKGJ5dGUpIDB4MSwgKGJ5dGUpIDB4MywKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgxLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4ZmZmZmZmODEsIChieXRlKSAweGZmZmZmZjg5LAorICAgICAgICAgICAgICAgIChieXRlKSAweDIsIChieXRlKSAweDQxLCAoYnl0ZSkgMHgwLCAoYnl0ZSkgMHhmZmZmZmZmMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZhYSwgKGJ5dGUpIDB4MjIsIChieXRlKSAweDVhLCAoYnl0ZSkgMHgyOSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZiMiwgKGJ5dGUpIDB4M2YsIChieXRlKSAweGZmZmZmZmM5LCAoYnl0ZSkgMHhiLAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZjg3LCAoYnl0ZSkgMHg1ZCwgKGJ5dGUpIDB4ZmZmZmZmOTEsIChieXRlKSAweDUxLAorICAgICAgICAgICAgICAgIChieXRlKSAweDEsIChieXRlKSAweGZmZmZmZmE0LCAoYnl0ZSkgMHhmZmZmZmZiOSwgKGJ5dGUpIDB4NGUsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MWUsIChieXRlKSAweGZmZmZmZjg1LCAoYnl0ZSkgMHhmZmZmZmZmYywKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZhNiwgKGJ5dGUpIDB4NWEsIChieXRlKSAweGZmZmZmZjk2LAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmIxLCAoYnl0ZSkgMHhmZmZmZmZjYiwgKGJ5dGUpIDB4ZmZmZmZmODEsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmYTMsIChieXRlKSAweDZlLCAoYnl0ZSkgMHhmZmZmZmY5MCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZiZCwgKGJ5dGUpIDB4ZmZmZmZmYTIsIChieXRlKSAweGUsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmYjQsIChieXRlKSAweGZmZmZmZmJhLCAoYnl0ZSkgMHgyYywgKGJ5dGUpIDB4NDUsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4OSwgKGJ5dGUpIDB4MWMsIChieXRlKSAweGZmZmZmZjk4LCAoYnl0ZSkgMHgzOSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgyNiwgKGJ5dGUpIDB4MjQsIChieXRlKSAweDQwLCAoYnl0ZSkgMHhmZmZmZmY4MCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZjZSwgKGJ5dGUpIDB4MTUsIChieXRlKSAweGZmZmZmZjhiLAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmUxLCAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4NDgsIChieXRlKSAweGZmZmZmZmYzLAorICAgICAgICAgICAgICAgIChieXRlKSAweDcwLCAoYnl0ZSkgMHhmZmZmZmY5OCwgKGJ5dGUpIDB4ZmZmZmZmY2EsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmYTcsIChieXRlKSAweDcxLCAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4ZmZmZmZmYjYsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NCwgKGJ5dGUpIDB4MTMsIChieXRlKSAweGZmZmZmZmU1LCAoYnl0ZSkgMHg2MSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgzYywgKGJ5dGUpIDB4MWYsIChieXRlKSAweDIsIChieXRlKSAweDQwLCAoYnl0ZSkgMHgxZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZkOCwgKGJ5dGUpIDB4NmYsIChieXRlKSAweGZmZmZmZmNlLCAoYnl0ZSkgMHgyMywKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4NmEsIChieXRlKSAweDJhLCAoYnl0ZSkgMHhmZmZmZmZhMywKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg0ZCwgKGJ5dGUpIDB4NjIsIChieXRlKSAweGZmZmZmZmU5LCAoYnl0ZSkgMHg1ZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4ZmZmZmZmYTgsIChieXRlKSAweGZmZmZmZmU4LAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmFhLCAoYnl0ZSkgMHhmZmZmZmY4YSwgKGJ5dGUpIDB4ZmZmZmZmOTUsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MjYsIChieXRlKSAweDdjLCAoYnl0ZSkgMHgzOCwgKGJ5dGUpIDB4ZmZmZmZmYTksCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MmIsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg1YSwgKGJ5dGUpIDB4MTYsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MTksIChieXRlKSAweGZmZmZmZmZhLCAoYnl0ZSkgMHhmZmZmZmY4MywKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZiOCwgKGJ5dGUpIDB4NzYsIChieXRlKSAweGZmZmZmZmFmLAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmI4LCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4NzIsIChieXRlKSAweDQ1LAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZjlmLCAoYnl0ZSkgMHhmZmZmZmY5NSwgKGJ5dGUpIDB4MWUsIChieXRlKSAweDYyLAorICAgICAgICAgICAgICAgIChieXRlKSAweDM2LCAoYnl0ZSkgMHhmZmZmZmY5NywgKGJ5dGUpIDB4ZmZmZmZmYmYsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmYWIsIChieXRlKSAweDIwLCAoYnl0ZSkgMHhmZmZmZmZiMCwgKGJ5dGUpIDB4NjEsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmYzUsIChieXRlKSAweDIxLCAoYnl0ZSkgMHhmZmZmZmY5ZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZlNCwgKGJ5dGUpIDB4ZmZmZmZmZGUsIChieXRlKSAweGZmZmZmZjkxLAorICAgICAgICAgICAgICAgIChieXRlKSAweDFjLCAoYnl0ZSkgMHg2YSwgKGJ5dGUpIDB4NywgKGJ5dGUpIDB4NDgsIChieXRlKSAweDc3LAorICAgICAgICAgICAgICAgIChieXRlKSAweDcwLCAoYnl0ZSkgMHgxZCwgKGJ5dGUpIDB4ZmZmZmZmZmYsIChieXRlKSAweDU4LAorICAgICAgICAgICAgICAgIChieXRlKSAweDIzLCAoYnl0ZSkgMHgyLCAoYnl0ZSkgMHgyLCAoYnl0ZSkgMHgxLAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmZmLCAoYnl0ZSkgMHg0LCAoYnl0ZSkgMHg0MiwgKGJ5dGUpIDB4MiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4NjksIChieXRlKSAweGZmZmZmZjg2LCAoYnl0ZSkgMHg0OCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1NywgKGJ5dGUpIDB4ZmZmZmZmYmYsIChieXRlKSAweGZmZmZmZmRlLCAoYnl0ZSkgMHg4LAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmM2LCAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4NmQsIChieXRlKSAweGYsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MjAsIChieXRlKSAweGZmZmZmZjk0LCAoYnl0ZSkgMHg0YSwgKGJ5dGUpIDB4MjIsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NmUsIChieXRlKSAweDI0LCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4ZmZmZmZmZDksCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmYTksIChieXRlKSAweGZmZmZmZmJkLCAoYnl0ZSkgMHgxZSwgKGJ5dGUpIDB4NjQsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmODksIChieXRlKSAweGZmZmZmZjgzLCAoYnl0ZSkgMHgzYywKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZlNywgKGJ5dGUpIDB4NzAsIChieXRlKSAweDI0LCAoYnl0ZSkgMHhmZmZmZmZlMSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmY4ZiwgKGJ5dGUpIDB4M2MsIChieXRlKSAweDRkLCAoYnl0ZSkgMHgzOSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1ZiwgKGJ5dGUpIDB4ZmZmZmZmOWUsIChieXRlKSAweGZmZmZmZjkzLCAoYnl0ZSkgMHgxMywKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmY4NiwgKGJ5dGUpIDB4ZmZmZmZmZTksIChieXRlKSAweGZmZmZmZjgwLAorICAgICAgICAgICAgICAgIChieXRlKSAweGYsIChieXRlKSAweGZmZmZmZmM0LCAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4ZmZmZmZmOGIsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmZjQsIChieXRlKSAweGZmZmZmZjhiLCAoYnl0ZSkgMHg2NSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZhNCwgKGJ5dGUpIDB4MWIsIChieXRlKSAweGQsIChieXRlKSAweDQsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NDgsIChieXRlKSAweDQwLCAoYnl0ZSkgMHhmZmZmZmZkNiwgKGJ5dGUpIDB4ZmZmZmZmYTIsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MCwgKGJ5dGUpIDB4ZmZmZmZmODUsIChieXRlKSAweGZmZmZmZmU5LAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmM0LCAoYnl0ZSkgMHg3NywgKGJ5dGUpIDB4ZmZmZmZmYjIsIChieXRlKSAweDI1LAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmQ4CisgICAgICAgIH0pOworICAgICAgICBwdWJsaWNLZXlFbmNvZGluZy5wdXQoIkRIIiwgbmV3IGJ5dGVbXSB7CisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MzAsIChieXRlKSAweGZmZmZmZjgxLCAoYnl0ZSkgMHhmZmZmZmZlMCwgKGJ5dGUpIDB4MzAsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmODEsIChieXRlKSAweGZmZmZmZjk3LCAoYnl0ZSkgMHg2LCAoYnl0ZSkgMHg5LAorICAgICAgICAgICAgICAgIChieXRlKSAweDJhLCAoYnl0ZSkgMHhmZmZmZmY4NiwgKGJ5dGUpIDB4NDgsIChieXRlKSAweGZmZmZmZjg2LAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmY3LCAoYnl0ZSkgMHhkLCAoYnl0ZSkgMHgxLCAoYnl0ZSkgMHgzLAorICAgICAgICAgICAgICAgIChieXRlKSAweDEsIChieXRlKSAweDMwLCAoYnl0ZSkgMHhmZmZmZmY4MSwgKGJ5dGUpIDB4ZmZmZmZmODksCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MiwgKGJ5dGUpIDB4NDEsIChieXRlKSAweDAsIChieXRlKSAweGZmZmZmZmYwLAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmFhLCAoYnl0ZSkgMHgyMiwgKGJ5dGUpIDB4NWEsIChieXRlKSAweDI5LAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmIyLCAoYnl0ZSkgMHgzZiwgKGJ5dGUpIDB4ZmZmZmZmYzksIChieXRlKSAweGIsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmODcsIChieXRlKSAweDVkLCAoYnl0ZSkgMHhmZmZmZmY5MSwgKGJ5dGUpIDB4NTEsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MSwgKGJ5dGUpIDB4ZmZmZmZmYTQsIChieXRlKSAweGZmZmZmZmI5LCAoYnl0ZSkgMHg0ZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgxZSwgKGJ5dGUpIDB4ZmZmZmZmODUsIChieXRlKSAweGZmZmZmZmZjLAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmE2LCAoYnl0ZSkgMHg1YSwgKGJ5dGUpIDB4ZmZmZmZmOTYsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmYjEsIChieXRlKSAweGZmZmZmZmNiLCAoYnl0ZSkgMHhmZmZmZmY4MSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZhMywgKGJ5dGUpIDB4NmUsIChieXRlKSAweGZmZmZmZjkwLAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmJkLCAoYnl0ZSkgMHhmZmZmZmZhMiwgKGJ5dGUpIDB4ZSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZiNCwgKGJ5dGUpIDB4ZmZmZmZmYmEsIChieXRlKSAweDJjLCAoYnl0ZSkgMHg0NSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg5LCAoYnl0ZSkgMHgxYywgKGJ5dGUpIDB4ZmZmZmZmOTgsIChieXRlKSAweDM5LAorICAgICAgICAgICAgICAgIChieXRlKSAweDI2LCAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4NDAsIChieXRlKSAweGZmZmZmZjgwLAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmNlLCAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4ZmZmZmZmOGIsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmZTEsIChieXRlKSAweDY3LCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4ZmZmZmZmZjMsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NzAsIChieXRlKSAweGZmZmZmZjk4LCAoYnl0ZSkgMHhmZmZmZmZjYSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZhNywgKGJ5dGUpIDB4NzEsIChieXRlKSAweDMzLCAoYnl0ZSkgMHhmZmZmZmZiNiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg0LCAoYnl0ZSkgMHgxMywgKGJ5dGUpIDB4ZmZmZmZmZTUsIChieXRlKSAweDYxLAorICAgICAgICAgICAgICAgIChieXRlKSAweDNjLCAoYnl0ZSkgMHgxZiwgKGJ5dGUpIDB4MiwgKGJ5dGUpIDB4NDAsIChieXRlKSAweDFlLAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmQ4LCAoYnl0ZSkgMHg2ZiwgKGJ5dGUpIDB4ZmZmZmZmY2UsIChieXRlKSAweDIzLAorICAgICAgICAgICAgICAgIChieXRlKSAweDcxLCAoYnl0ZSkgMHg2YSwgKGJ5dGUpIDB4MmEsIChieXRlKSAweGZmZmZmZmEzLAorICAgICAgICAgICAgICAgIChieXRlKSAweDRkLCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4ZmZmZmZmZTksIChieXRlKSAweDVmLAorICAgICAgICAgICAgICAgIChieXRlKSAweDE3LCAoYnl0ZSkgMHhmZmZmZmZhOCwgKGJ5dGUpIDB4ZmZmZmZmZTgsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmYWEsIChieXRlKSAweGZmZmZmZjhhLCAoYnl0ZSkgMHhmZmZmZmY5NSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgyNiwgKGJ5dGUpIDB4N2MsIChieXRlKSAweDM4LCAoYnl0ZSkgMHhmZmZmZmZhOSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgyYiwgKGJ5dGUpIDB4NDgsIChieXRlKSAweDVhLCAoYnl0ZSkgMHgxNiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgxOSwgKGJ5dGUpIDB4ZmZmZmZmZmEsIChieXRlKSAweGZmZmZmZjgzLAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmI4LCAoYnl0ZSkgMHg3NiwgKGJ5dGUpIDB4ZmZmZmZmYWYsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmYjgsIChieXRlKSAweDYyLCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4NDUsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmOWYsIChieXRlKSAweGZmZmZmZjk1LCAoYnl0ZSkgMHgxZSwgKGJ5dGUpIDB4NjIsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MzYsIChieXRlKSAweGZmZmZmZjk3LCAoYnl0ZSkgMHhmZmZmZmZiZiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZhYiwgKGJ5dGUpIDB4MjAsIChieXRlKSAweGZmZmZmZmIwLCAoYnl0ZSkgMHg2MSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZjNSwgKGJ5dGUpIDB4MjEsIChieXRlKSAweGZmZmZmZjllLAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmU0LCAoYnl0ZSkgMHhmZmZmZmZkZSwgKGJ5dGUpIDB4ZmZmZmZmOTEsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MWMsIChieXRlKSAweDZhLCAoYnl0ZSkgMHg3LCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4NzcsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NzAsIChieXRlKSAweDFkLCAoYnl0ZSkgMHhmZmZmZmZmZiwgKGJ5dGUpIDB4NTgsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4MjMsIChieXRlKSAweDIsIChieXRlKSAweDIsIChieXRlKSAweDEsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmZmYsIChieXRlKSAweDMsIChieXRlKSAweDQ0LCAoYnl0ZSkgMHgwLAorICAgICAgICAgICAgICAgIChieXRlKSAweDIsIChieXRlKSAweDQxLCAoYnl0ZSkgMHgwLCAoYnl0ZSkgMHhmZmZmZmY5ZCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZjNCwgKGJ5dGUpIDB4ZmZmZmZmY2QsIChieXRlKSAweDEwLAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmRmLCAoYnl0ZSkgMHg2NiwgKGJ5dGUpIDB4ZmZmZmZmOTIsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmZTEsIChieXRlKSAweDMzLCAoYnl0ZSkgMHhmZmZmZmZiMSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZjOSwgKGJ5dGUpIDB4ZmZmZmZmOWYsIChieXRlKSAweGZmZmZmZmI3LAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZmRkLCAoYnl0ZSkgMHhmZmZmZmY4NCwgKGJ5dGUpIDB4NGIsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmZTUsIChieXRlKSAweGZmZmZmZjg2LCAoYnl0ZSkgMHhmZmZmZmZmMCwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1MywgKGJ5dGUpIDB4MmEsIChieXRlKSAweGZmZmZmZmQ1LCAoYnl0ZSkgMHhmZmZmZmZjNiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4ZmZmZmZmOTQsIChieXRlKSAweGZmZmZmZmFlLCAoYnl0ZSkgMHgxMywKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg3YiwgKGJ5dGUpIDB4ZmZmZmZmOWQsIChieXRlKSAweDM3LCAoYnl0ZSkgMHhmZmZmZmY4YiwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHhmZmZmZmZjNiwgKGJ5dGUpIDB4ZmZmZmZmYzYsIChieXRlKSAweDc4LAorICAgICAgICAgICAgICAgIChieXRlKSAweGZmZmZmZjljLCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4ZmZmZmZmOGEsIChieXRlKSAweDZmLAorICAgICAgICAgICAgICAgIChieXRlKSAweDM1LCAoYnl0ZSkgMHgzOSwgKGJ5dGUpIDB4ZmZmZmZmZTAsIChieXRlKSAweDc4LAorICAgICAgICAgICAgICAgIChieXRlKSAweDMzLCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4ZmZmZmZmODksIChieXRlKSAweDMwLAorICAgICAgICAgICAgICAgIChieXRlKSAweDYxLCAoYnl0ZSkgMHhmZmZmZmY4NCwgKGJ5dGUpIDB4ZmZmZmZmOGEsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmYmMsIChieXRlKSAweGZmZmZmZjgwLCAoYnl0ZSkgMHg2YywgKGJ5dGUpIDB4MWMsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4NTUsIChieXRlKSAweGZmZmZmZjk2LCAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4ZmZmZmZmYjEsCisgICAgICAgICAgICAgICAgKGJ5dGUpIDB4ZmZmZmZmOTYsIChieXRlKSAweDUsIChieXRlKSAweDIxLCAoYnl0ZSkgMHg2NSwKKyAgICAgICAgICAgICAgICAoYnl0ZSkgMHg1NSwgKGJ5dGUpIDB4ZmZmZmZmYmIsIChieXRlKSAweGZmZmZmZmE0CisgICAgICAgIH0pOworICAgIH0KKworICAgIHB1YmxpYyBUZXN0S2V5UGFpcihTdHJpbmcgYWxnb3JpdGhtTmFtZSkgdGhyb3dzCisgICAgICAgICAgICBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24geworICAgICAgICB0aGlzLmFsZ29yaXRobU5hbWUgPSBhbGdvcml0aG1OYW1lOworICAgICAgICBpZiAoIXByaXZhdGVLZXlFbmNvZGluZy5jb250YWluc0tleSh0aGlzLmFsZ29yaXRobU5hbWUpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKCJFbmNvZGVkIGZvcm0gbm90IGF2YWlsYWJsZSBmb3IgIiArCisgICAgICAgICAgICAgICAgICAgIHRoaXMuYWxnb3JpdGhtTmFtZSk7CisgICAgICAgIH0KKyAgICAgICAga2YgPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKHRoaXMuYWxnb3JpdGhtTmFtZSk7CisgICAgfQorCisgICAgcHVibGljIFB1YmxpY0tleSBnZXRQdWJsaWMoKSB0aHJvd3MKKyAgICAgICAgICAgIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGtmLmdlbmVyYXRlUHVibGljKAorICAgICAgICAgICAgICAgIG5ldyBYNTA5RW5jb2RlZEtleVNwZWMoCisgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZVtdKXB1YmxpY0tleUVuY29kaW5nLmdldChhbGdvcml0aG1OYW1lKSkpOworICAgIH0KKworICAgIHB1YmxpYyBQcml2YXRlS2V5IGdldFByaXZhdGUoKSB0aHJvd3MKKyAgICAgICAgICAgIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIGtmLmdlbmVyYXRlUHJpdmF0ZSgKKyAgICAgICAgICAgICAgICBuZXcgUEtDUzhFbmNvZGVkS2V5U3BlYygKKyAgICAgICAgICAgICAgICAgICAgICAgIChieXRlW10pcHJpdmF0ZUtleUVuY29kaW5nLmdldChhbGdvcml0aG1OYW1lKSkpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L1Rlc3RLZXlTdG9yZVNwaS5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L1Rlc3RLZXlTdG9yZVNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg2YjU0YzQKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvVGVzdEtleVN0b3JlU3BpLmphdmEKQEAgLTAsMCArMSwyNjAgQEAKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0Lk15Q2VydGlmaWNhdGU7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlU3BpOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZS5Mb2FkU3RvcmVQYXJhbWV0ZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZS5QYXNzd29yZFByb3RlY3Rpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZS5Qcm90ZWN0aW9uUGFyYW1ldGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCitpbXBvcnQgamF2YXguY3J5cHRvLlNlY3JldEtleTsKKworcHVibGljIGNsYXNzIFRlc3RLZXlTdG9yZVNwaSBleHRlbmRzIEtleVN0b3JlU3BpIHsKKworICAgIE1hcDxTdHJpbmcsIE9iamVjdD4gYWxpYXNlcyA9IG5ldyBIYXNoTWFwPFN0cmluZywgT2JqZWN0PigpOworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDZXJ0aWZpY2F0ZSBDRVJUID0gbmV3IE15Q2VydGlmaWNhdGUoImNlcnR0eXBlIiwKKyAgICAgICAgICAgIG5ldyBieXRlW10ge30pOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2VydGlmaWNhdGVbXSBDRVJUQ0hBSU4gPSBuZXcgQ2VydGlmaWNhdGVbXSB7CisgICAgICAgICAgICBuZXcgTXlDZXJ0aWZpY2F0ZSgiY2VydDEiLCBuZXcgYnl0ZVtdIHt9KSwKKyAgICAgICAgICAgIG5ldyBNeUNlcnRpZmljYXRlKCJjZXJ0MiIsIG5ldyBieXRlW10ge30pfTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgS2V5IEtFWSA9IG5ldyBTZWNyZXRLZXkoKSB7CisKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRBbGdvcml0aG0oKSB7CisgICAgICAgICAgICByZXR1cm4gInNlY3JldCI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7NDJ9OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRGb3JtYXQoKSB7CisgICAgICAgICAgICByZXR1cm4gImZvcm1hdCI7CisgICAgICAgIH0KKworICAgIH07CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdCBEVU1NWSA9IG5ldyBPYmplY3QoKTsKKworICAgIHB1YmxpYyBUZXN0S2V5U3RvcmVTcGkoKSB7CisgICAgICAgIGFsaWFzZXMucHV0KCJjZXJ0YWxpYXMiLCBDRVJUKTsKKyAgICAgICAgYWxpYXNlcy5wdXQoImNoYWluYWxpYXMiLCBDRVJUQ0hBSU4pOworICAgICAgICBhbGlhc2VzLnB1dCgia2V5YWxpYXMiLCBLRVkpOworICAgICAgICBhbGlhc2VzLnB1dCgidW5rbm93bmFsaWFzIiwgRFVNTVkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGVuZ2luZUFsaWFzZXMoKSB7CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbnVtZXJhdGlvbihhbGlhc2VzLmtleVNldCgpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlbmdpbmVDb250YWluc0FsaWFzKFN0cmluZyBhbGlhcykgeworICAgICAgICByZXR1cm4gYWxpYXNlcy5jb250YWluc0tleShhbGlhcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZW5naW5lRGVsZXRlRW50cnkoU3RyaW5nIGFsaWFzKSB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgS2V5U3RvcmVFeGNlcHRpb24oImVudHJ5ICIgKyBhbGlhcyArICIgY2Fubm90IGJlIGRlbGV0ZWQiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQ2VydGlmaWNhdGUgZW5naW5lR2V0Q2VydGlmaWNhdGUoU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIHJldHVybiAoQ2VydGlmaWNhdGUpIGFsaWFzZXMuZ2V0KGFsaWFzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGVuZ2luZUdldENlcnRpZmljYXRlQWxpYXMoQ2VydGlmaWNhdGUgY2VydCkgeworICAgICAgICBpZiAoY2VydCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoTWFwLkVudHJ5PFN0cmluZywgT2JqZWN0PiBhbGlhcyA6IGFsaWFzZXMuZW50cnlTZXQoKSkgeworICAgICAgICAgICAgaWYgKGFsaWFzLmdldFZhbHVlKCkgPT0gY2VydCkgeworICAgICAgICAgICAgICAgIHJldHVybiBhbGlhcy5nZXRLZXkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZVtdIGVuZ2luZUdldENlcnRpZmljYXRlQ2hhaW4oU3RyaW5nIGFsaWFzKSB7CisgICAgICAgIHJldHVybiAoQ2VydGlmaWNhdGVbXSkgYWxpYXNlcy5nZXQoYWxpYXMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEYXRlIGVuZ2luZUdldENyZWF0aW9uRGF0ZShTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBEYXRlKDQyICogMTAyNCAqIDEwMjQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBLZXkgZW5naW5lR2V0S2V5KFN0cmluZyBhbGlhcywgY2hhcltdIHBhc3N3b3JkKQorICAgICAgICAgICAgdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChlbmdpbmVDb250YWluc0FsaWFzKGFsaWFzKSkgeworICAgICAgICAgICAgaWYgKCFlbmdpbmVJc0tleUVudHJ5KGFsaWFzKSkgeworICAgICAgICAgICAgICAgIGlmIChwYXNzd29yZCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oIm5vIHN1Y2ggYWxnIik7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAoS2V5KSBhbGlhc2VzLmdldChhbGlhcyk7CisgICAgICAgIH0KKworICAgICAgICB0aHJvdyBuZXcgVW5yZWNvdmVyYWJsZUtleUV4Y2VwdGlvbigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVuZ2luZUlzQ2VydGlmaWNhdGVFbnRyeShTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRpZmljYXRlIGMgPSAoQ2VydGlmaWNhdGUpIGFsaWFzZXMuZ2V0KGFsaWFzKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZW5naW5lSXNLZXlFbnRyeShTdHJpbmcgYWxpYXMpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEtleSBrID0gKEtleSkgYWxpYXNlcy5nZXQoYWxpYXMpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVMb2FkKElucHV0U3RyZWFtIHN0cmVhbSwgY2hhcltdIHBhc3N3b3JkKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHN0cmVhbSAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoc3RyZWFtLmF2YWlsYWJsZSgpID09IDApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBhc3N3b3JkID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24oKTsKKyAgICAgICAgfSBlbHNlIGlmIChwYXNzd29yZC5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVMb2FkKExvYWRTdG9yZVBhcmFtZXRlciBwYXJhbSkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwYXJhbSA9PSBudWxsKSB7CisgICAgICAgICAgICBlbmdpbmVMb2FkKG51bGwsIG51bGwpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgUHJvdGVjdGlvblBhcmFtZXRlciBwUGFyYW0gPSBwYXJhbS5nZXRQcm90ZWN0aW9uUGFyYW1ldGVyKCk7CisgICAgICAgIGlmIChwUGFyYW0gPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHBQYXJhbSBpbnN0YW5jZW9mIFBhc3N3b3JkUHJvdGVjdGlvbikgeworICAgICAgICAgICAgY2hhcltdIHBhc3N3b3JkID0gKChQYXNzd29yZFByb3RlY3Rpb24pIHBQYXJhbSkuZ2V0UGFzc3dvcmQoKTsKKyAgICAgICAgICAgIGlmIChwYXNzd29yZCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZW5naW5lU2V0Q2VydGlmaWNhdGVFbnRyeShTdHJpbmcgYWxpYXMsIENlcnRpZmljYXRlIGNlcnQpCisgICAgICAgICAgICB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICBpZiAoZW5naW5lQ29udGFpbnNBbGlhcyhhbGlhcykpIHsKKyAgICAgICAgICAgIGlmICghZW5naW5lSXNDZXJ0aWZpY2F0ZUVudHJ5KGFsaWFzKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBLZXlTdG9yZUV4Y2VwdGlvbigiYWxpYXMgaXMgbm90IGEgY2VydCBlbnRyeSIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFsaWFzZXMucHV0KGFsaWFzLCBjZXJ0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVTZXRLZXlFbnRyeShTdHJpbmcgYWxpYXMsIEtleSBrZXksIGNoYXJbXSBwYXNzd29yZCwKKyAgICAgICAgICAgIENlcnRpZmljYXRlW10gY2hhaW4pIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChlbmdpbmVDb250YWluc0FsaWFzKGFsaWFzKSkgeworICAgICAgICAgICAgaWYgKCFlbmdpbmVJc0tleUVudHJ5KGFsaWFzKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBLZXlTdG9yZUV4Y2VwdGlvbigiYWxpYXMgaXMgbm90IGEga2V5IGVucnR5Iik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoa2V5IGluc3RhbmNlb2YgUHJpdmF0ZUtleSkKKyAgICAgICAgeworICAgICAgICAgICAgaWYgKGNoYWluID09IG51bGwgfHwgY2hhaW4ubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBhbGlhc2VzLnB1dChhbGlhcywga2V5KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVTZXRLZXlFbnRyeShTdHJpbmcgYWxpYXMsIGJ5dGVbXSBrZXksIENlcnRpZmljYXRlW10gY2hhaW4pCisgICAgICAgICAgICB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgS2V5U3RvcmVFeGNlcHRpb24oInNldCBlbnRyeSBmYWlsZWQiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGVuZ2luZVNpemUoKSB7CisgICAgICAgIHJldHVybiBhbGlhc2VzLnNpemUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVTdG9yZShPdXRwdXRTdHJlYW0gc3RyZWFtLCBjaGFyW10gcGFzc3dvcmQpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBpZiAoc3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigic3RvcmUgZmFpbGVkIik7CisgICAgICAgIH0KKworICAgICAgICBpZiAocGFzc3dvcmQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbigpOworICAgICAgICB9IGVsc2UgaWYgKHBhc3N3b3JkLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGVuZ2luZVN0b3JlKExvYWRTdG9yZVBhcmFtZXRlciBwYXJhbSkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uLCBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChwYXJhbSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIFByb3RlY3Rpb25QYXJhbWV0ZXIgcFBhcmFtID0gcGFyYW0uZ2V0UHJvdGVjdGlvblBhcmFtZXRlcigpOworICAgICAgICBpZiAocFBhcmFtIGluc3RhbmNlb2YgUGFzc3dvcmRQcm90ZWN0aW9uKSB7CisgICAgICAgICAgICBjaGFyW10gcGFzc3dvcmQgPSAoKFBhc3N3b3JkUHJvdGVjdGlvbikgcFBhcmFtKS5nZXRQYXNzd29yZCgpOworICAgICAgICAgICAgaWYgKHBhc3N3b3JkID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHBhc3N3b3JkLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvVGVzdFV0aWxzLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvVGVzdFV0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDVkODg0MgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9UZXN0VXRpbHMuamF2YQpAQCAtMCwwICsxLDgwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKKy8qKgorICogVGVzdCB1dGlsaXR5IGNsYXNzCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0VXRpbHMgeworCisgICAgLyoqCisgICAgICogTm8gbmVlZCB0byBpbnN0YW50aWF0ZQorICAgICAqLworICAgIHByaXZhdGUgVGVzdFV0aWxzKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50cyBieXRlIGFycmF5IDxjb2RlPmRhdGE8L2NvZGU+IGFzIGhleCB0byB0aGUKKyAgICAgKiA8Y29kZT5TeXN0ZW0ub3V0PC9jb2RlPiBpbiB0aGUgY3VzdG9taXphYmxlIGZvcm0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGVyTGluZSBob3cgbWFueSBudW1iZXJzIHB1dCBvbiBzaW5nbGUgbGluZQorICAgICAqIEBwYXJhbSBwcmVmaXggY3VzdG9tIG91dHB1dCBudW1iZXIgcHJlZml4CisgICAgICogQHBhcmFtIGRlbGltaXRlciBjdXN0b20gb3V0cHV0IG51bWJlciBkZWxpbWl0ZXIKKyAgICAgKiBAcGFyYW0gZGF0YSBkYXRhIHRvIGJlIHByaW50ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcHJpbnRBc0hleChpbnQgcGVyTGluZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBkZWxpbWl0ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIGRhdGEpIHsKKyAgICAgICAgZm9yIChpbnQgaT0wOyBpPGRhdGEubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFN0cmluZyB0YWlsID0gSW50ZWdlci50b0hleFN0cmluZygweDAwMDAwMGZmICYgZGF0YVtpXSk7CisgICAgICAgICAgICBpZiAodGFpbC5sZW5ndGgoKSA9PSAxKSB7CisgICAgICAgICAgICAgICAgdGFpbCA9ICIwIiArIHRhaWw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KHByZWZpeCArICIweCIgKyB0YWlsICsgZGVsaW1pdGVyKTsKKworICAgICAgICAgICAgaWYgKCgoaSsxKSVwZXJMaW5lKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgc3lzdGVtIHByb3BlcnR5CisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5IC0gdGhlIG5hbWUgb2YgdGhlIHN5c3RlbSBwcm9wZXJ0eS4KKyAgICAgKiBAcGFyYW0gdmFsdWUgLSB0aGUgdmFsdWUgdG8gYmUgc2V0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldFN5c3RlbVByb3BlcnR5KFN0cmluZyBrZXksIFN0cmluZyB2YWx1ZSkgeworICAgICAgICBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBTeXN0ZW0uZ2V0UHJvcGVydGllcygpOworICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgcHJvcGVydGllcy5yZW1vdmUoa2V5KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoa2V5LCB2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnRpZXMocHJvcGVydGllcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L2NlcnQvTXlDUkwuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9jZXJ0L015Q1JMLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZThjNzM1NgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9jZXJ0L015Q1JMLmphdmEKQEAgLTAsMCArMSw2MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNSTDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CisKKy8qKgorICogU3R1YiBjbGFzcyBmb3IgPGNvZGU+amF2YS5zZWN1cml0eS5jZXJ0LkNSTDwvY29kZT4gdGVzdHMKKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBNeUNSTCBleHRlbmRzIENSTCB7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvcgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgTXlDUkwoU3RyaW5nIHR5cGUpIHsKKyAgICAgICAgc3VwZXIodHlwZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uCisgICAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I3RvU3RyaW5nKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gIk15Q1JMOiBbIiArIGdldFR5cGUoKSArICJdIjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gY2VydCA8Y29kZT5DZXJ0aWZpY2F0ZTwvY29kZT4gdG8gYmUgY2hlY2tlZAorICAgICAqIEByZXR1cm4gYWx3YXlzIDxjb2RlPmZhbHNlPC9jb2RlPgorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0LkNSTCNpc1Jldm9rZWQoamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlKQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUmV2b2tlZChDZXJ0aWZpY2F0ZSBjZXJ0KSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9jZXJ0L015Q2VydFBhdGguamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9jZXJ0L015Q2VydFBhdGguamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYWE0MjI2Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L2NlcnQvTXlDZXJ0UGF0aC5qYXZhCkBAIC0wLDAgKzEsMTQxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQ7CisKK2ltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGg7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworCisKKy8qKgorICogU3R1YiBjbGFzcyBmb3IgPGNvZGU+amF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoPC9jb2RlPiB0ZXN0cworICoKKyAqLworcHVibGljIGNsYXNzIE15Q2VydFBhdGggZXh0ZW5kcyBDZXJ0UGF0aCB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzQ0NDgzNTU5OTE2MTg3MDg5M0w7CisgICAgLyoqCisgICAgICogbXkgY2VydGlmaWNhdGVzIGxpc3QKKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFZlY3RvcjxNeUNlcnRpZmljYXRlPiBjZXJ0aWZpY2F0ZXM7CisKKyAgICAvKioKKyAgICAgKiBMaXN0IG9mIGVuY29kaW5ncyBzdXBwb3J0ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFZlY3RvcjxTdHJpbmc+IGVuY29kaW5nTmFtZXM7CisgICAgLyoqCisgICAgICogbXkgY2VydCBwYXRoIHRoZSBvbmx5IGVuY29kaW5nCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gZW5jb2Rpbmc7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIG5ldyBpbnN0YW5jZSBvZiA8Y29kZT5NeUNlcnRQYXRoPC9jb2RlPgorICAgICAqCisgICAgICovCisgICAgcHVibGljIE15Q2VydFBhdGgoYnl0ZVtdIGVuY29kaW5nKSB7CisgICAgICAgIHN1cGVyKCJNeUVuY29kaW5nIik7CisgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICAgICAgY2VydGlmaWNhdGVzID0gbmV3IFZlY3RvcjxNeUNlcnRpZmljYXRlPigpOworICAgICAgICBjZXJ0aWZpY2F0ZXMuYWRkKG5ldyBNeUNlcnRpZmljYXRlKCJNeUVuY29kaW5nIiwgZW5jb2RpbmcpKTsKKyAgICAgICAgZW5jb2RpbmdOYW1lcyA9IG5ldyBWZWN0b3I8U3RyaW5nPigpOworICAgICAgICBlbmNvZGluZ05hbWVzLmFkZCgiTXlFbmNvZGluZyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gY2VydGlmaWNhdGVzIGxpc3QKKyAgICAgKiBAc2VlIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aCNnZXRDZXJ0aWZpY2F0ZXMoKQorICAgICAqLworICAgIHB1YmxpYyBMaXN0PE15Q2VydGlmaWNhdGU+IGdldENlcnRpZmljYXRlcygpIHsKKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoY2VydGlmaWNhdGVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIGRlZmF1bHQgZW5jb2RlZCBmb3JtIG9mIHRoaXMgY2VydCBwYXRoCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGgjZ2V0RW5jb2RlZCgpCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgdGhyb3dzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZW5jb2RpbmcuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIGVuY29kZWQgZm9ybSBvZiB0aGlzIGNlcnQgcGF0aCBhcyBzcGVjaWZpZWQgYnkKKyAgICAgKiA8Y29kZT5lbmNvZGluZzwvY29kZT4gcGFyYW1ldGVyCisgICAgICogQHRocm93cyBDZXJ0aWZpY2F0ZUVuY29kaW5nRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgaWYgPGNvZGU+ZW5jb2Rpbmc8L2NvZGU+IG5vdCBlcXVhbHMgIk15RW5jb2RpbmciCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGgjZ2V0RW5jb2RlZChqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0RW5jb2RlZChTdHJpbmcgZW5jb2RpbmcpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChnZXRUeXBlKCkuZXF1YWxzKGVuY29kaW5nKSkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RpbmcuY2xvbmUoKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbigiRW5jb2Rpbmcgbm90IHN1cHBvcnRlZDogIiArCisgICAgICAgICAgICAgICAgZW5jb2RpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gaXRlcmF0b3IgdGhyb3VnaCBlbmNvZGluZ3Mgc3VwcG9ydGVkCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGgjZ2V0RW5jb2RpbmdzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgSXRlcmF0b3I8U3RyaW5nPiBnZXRFbmNvZGluZ3MoKSB7CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVDb2xsZWN0aW9uKGVuY29kaW5nTmFtZXMpLml0ZXJhdG9yKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiB0aGUgQ2VydFBhdGhSZXAgdG8gYmUgc2VyaWFsaXplZAorICAgICAqIEBzZWUgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoI3dyaXRlUmVwbGFjZSgpCisgICAgICovCisgICAgcHVibGljIE9iamVjdCB3cml0ZVJlcGxhY2UoKSB0aHJvd3MgT2JqZWN0U3RyZWFtRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLndyaXRlUmVwbGFjZSgpOworICAgIH0KKworICAgIHB1YmxpYyBjbGFzcyBNeUNlcnRQYXRoUmVwIGV4dGVuZHMgQ2VydFBhdGguQ2VydFBhdGhSZXAgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDE2MDkwMDAwODU0NTA0NzkxNzNMOworCisgICAgICAgIHByaXZhdGUgU3RyaW5nIHR5cGU7CisgICAgICAgIHByaXZhdGUgYnl0ZVtdIGRhdGE7CisKKyAgICAgICAgcHVibGljIE15Q2VydFBhdGhSZXAoU3RyaW5nIHR5cGUsIGJ5dGVbXSBkYXRhKSB7CisgICAgICAgICAgICBzdXBlcih0eXBlLCBkYXRhKTsKKyAgICAgICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7CisgICAgICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE9iamVjdCByZWFkUmVzb2x2ZSgpIHRocm93cyBPYmplY3RTdHJlYW1FeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnJlYWRSZXNvbHZlKCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoKSB7CisgICAgICAgICAgICByZXR1cm4gdHlwZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBieXRlW10gZ2V0RGF0YSgpIHsKKyAgICAgICAgICAgIHJldHVybiBkYXRhOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L2NlcnQvTXlDZXJ0UGF0aEJ1aWxkZXJTcGkuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9jZXJ0L015Q2VydFBhdGhCdWlsZGVyU3BpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWIxZTU5OAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9jZXJ0L015Q2VydFBhdGhCdWlsZGVyU3BpLmphdmEKQEAgLTAsMCArMSw0NyBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhCdWlsZGVyUmVzdWx0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aEJ1aWxkZXJTcGk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoUGFyYW1ldGVyczsKKworLyoqCisgKiBBZGRpdGlvbmFsIGNsYXNzIGZvciB2ZXJpZmljYXRpb24gQ2VydFBhdGhCdWlsZGVyU3BpCisgKiBhbmQgQ2VydFBhdGhCdWlsZGVyCisKKyAqLworCitwdWJsaWMgY2xhc3MgTXlDZXJ0UGF0aEJ1aWxkZXJTcGkgZXh0ZW5kcyBDZXJ0UGF0aEJ1aWxkZXJTcGkgeworICAgIHByaXZhdGUgaW50IHN3aSA9IDA7CisgICAgcHVibGljIENlcnRQYXRoQnVpbGRlclJlc3VsdCBlbmdpbmVCdWlsZChDZXJ0UGF0aFBhcmFtZXRlcnMgcGFyYW1zKQorICAgICAgICAgICAgdGhyb3dzIENlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbiwgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIHN3aSsrOworICAgICAgICBpZiAoKHBhcmFtcyA9PSBudWxsKSAmJiAoKHN3aSAlMiApICE9IDApKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydFBhdGhCdWlsZGVyRXhjZXB0aW9uKCJOdWxsIHBhcmFtZXRlciIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvY2VydC9NeUNlcnRQYXRoVmFsaWRhdG9yU3BpLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvY2VydC9NeUNlcnRQYXRoVmFsaWRhdG9yU3BpLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzc2M2MzZgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9jZXJ0L015Q2VydFBhdGhWYWxpZGF0b3JTcGkuamF2YQpAQCAtMCwwICsxLDU2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGg7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoVmFsaWRhdG9yUmVzdWx0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aFZhbGlkYXRvclNwaTsKKworLyoqCisgKiBBZGRpdGlvbmFsIGNsYXNzIGZvciB2ZXJpZmljYXRpb24gb2YgQ2VydFBhdGhWYWxpZGF0b3JTcGkKKyAqIGFuZCBDZXJ0UGF0aFZhbGlkYXRvcgorICoKKyAqLworCitwdWJsaWMgY2xhc3MgTXlDZXJ0UGF0aFZhbGlkYXRvclNwaSBleHRlbmRzIENlcnRQYXRoVmFsaWRhdG9yU3BpIHsKKyAgICBwcml2YXRlIGludCBzdyA9IDA7CisgICAgcHVibGljIENlcnRQYXRoVmFsaWRhdG9yUmVzdWx0IGVuZ2luZVZhbGlkYXRlKENlcnRQYXRoIGNlcnRQYXRoLAorICAgICAgICAgICAgQ2VydFBhdGhQYXJhbWV0ZXJzIHBhcmFtcykgdGhyb3dzIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uLAorICAgICAgICAgICAgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgICsrc3c7CisgICAgICAgIGlmIChjZXJ0UGF0aCA9PSBudWxsKSB7CisgICAgICAgICAgICBpZiAoKHN3ICUgMikgPT0gMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0UGF0aFZhbGlkYXRvckV4Y2VwdGlvbigiY2VydFBhdGggbnVsbCIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChwYXJhbXMgPT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKChzdyAlIDMpID09IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbigicGFyYW1zIG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvY2VydC9NeUNlcnRTdG9yZVBhcmFtZXRlcnMuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9jZXJ0L015Q2VydFN0b3JlUGFyYW1ldGVycy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZlNWM0MDgKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvY2VydC9NeUNlcnRTdG9yZVBhcmFtZXRlcnMuamF2YQpAQCAtMCwwICsxLDQzIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQuY2VydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0U3RvcmVQYXJhbWV0ZXJzOworCisvKioKKyAqIENsYXNzIGZvciB2ZXJpZmljYXRpb24gb2YgQ2VydFN0b3JlIGFuZCBDZXJ0U3RvcmVTcGkKKyAqCisgKi8KKworcHVibGljIGNsYXNzIE15Q2VydFN0b3JlUGFyYW1ldGVycyBpbXBsZW1lbnRzIENlcnRTdG9yZVBhcmFtZXRlcnMgeworICAgIHB1YmxpYyBNeUNlcnRTdG9yZVBhcmFtZXRlcnMoKSB7CisgICAgICAgIHN1cGVyKCk7CisgICAgfQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGUpOyAvLyBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9jZXJ0L015Q2VydFN0b3JlU3BpLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvY2VydC9NeUNlcnRTdG9yZVNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3ZGQ1NDkKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvY2VydC9NeUNlcnRTdG9yZVNwaS5qYXZhCkBAIC0wLDAgKzEsNjYgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIFZlcmEgWS4gUGV0cmFzaGtvdmEKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DUkw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNSTFNlbGVjdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0U2VsZWN0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRTdG9yZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFN0b3JlUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFN0b3JlU3BpOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKKworLyoqCisgKiBBZGRpdGlvbmFsIGNsYXNzIGZvciB2ZXJpZmljYXRpb24gQ2VydFN0b3JlU3BpCisgKiBhbmQgQ2VydFN0b3JlCisgKgorICovCisKK3B1YmxpYyBjbGFzcyBNeUNlcnRTdG9yZVNwaSBleHRlbmRzIENlcnRTdG9yZVNwaSB7CisKKyAgICBwdWJsaWMgTXlDZXJ0U3RvcmVTcGkoQ2VydFN0b3JlUGFyYW1ldGVycyBwYXJhbXMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyKHBhcmFtcyk7CisgICAgICAgIGlmICghKHBhcmFtcyBpbnN0YW5jZW9mIE15Q2VydFN0b3JlUGFyYW1ldGVycykpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uKCJJbnZhbGlkIHBhcmFtcyIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIENvbGxlY3Rpb248Q2VydGlmaWNhdGU+IGVuZ2luZUdldENlcnRpZmljYXRlcyhDZXJ0U2VsZWN0b3Igc2VsZWN0b3IpCisgICAgICAgICAgICB0aHJvd3MgQ2VydFN0b3JlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNlbGVjdG9yID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0U3RvcmVFeGNlcHRpb24oIlBhcmFtZXRlciBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIENvbGxlY3Rpb248Q1JMPiBlbmdpbmVHZXRDUkxzKENSTFNlbGVjdG9yIHNlbGVjdG9yKQorICAgICAgICAgICAgdGhyb3dzIENlcnRTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzZWxlY3RvciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydFN0b3JlRXhjZXB0aW9uKCJQYXJhbWV0ZXIgaXMgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9jZXJ0L015Q2VydGlmaWNhdGUuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9jZXJ0L015Q2VydGlmaWNhdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NjQ5OTJkCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L2NlcnQvTXlDZXJ0aWZpY2F0ZS5qYXZhCkBAIC0wLDAgKzEsMTYwIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQ7CisKK2ltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5RXh0ZW5zaW9uOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKKy8qKgorICogU3R1YiBjbGFzcyBmb3IgPGNvZGU+amF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlPC9jb2RlPiB0ZXN0cworICovCitwdWJsaWMgY2xhc3MgTXlDZXJ0aWZpY2F0ZSBleHRlbmRzIENlcnRpZmljYXRlIGltcGxlbWVudHMgWDUwOUV4dGVuc2lvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTgzNTMwMzI4MDcyNzE5MDA2Nkw7CisgICAgLy8gTXlDZXJ0aWZpY2F0ZSBlbmNvZGluZworICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGVuY29kaW5nOworCisgICAgcHVibGljIENlcnRpZmljYXRlUmVwIHJlcDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgbmV3IG9iamVjdCBvZiBjbGFzcyA8Y29kZT5NeUNlcnRpZmljYXRlPC9jb2RlPgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUKKyAgICAgKiBAcGFyYW0gZW5jb2RpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgTXlDZXJ0aWZpY2F0ZShTdHJpbmcgdHlwZSwgYnl0ZVtdIGVuY29kaW5nKSB7CisgICAgICAgIHN1cGVyKHR5cGUpOworICAgICAgICAvLyBkb24ndCBjb3B5IHRvIGFsbG93IG51bGwgcGFyYW1ldGVyIGluIHRlc3QKKyAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgPGNvZGU+TXlDZXJ0aWZpY2F0ZTwvY29kZT4gZW5jb2RpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIGRvIGNvcHkgdG8gZm9yY2UgTlBFIGluIHRlc3QKKyAgICAgICAgcmV0dXJuIGVuY29kaW5nLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRG9lcyBub3RoaW5nCisgICAgICovCisgICAgcHVibGljIHZvaWQgdmVyaWZ5KFB1YmxpY0tleSBrZXkpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwgSW52YWxpZEtleUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLCBTaWduYXR1cmVFeGNlcHRpb24geworICAgIH0KKworICAgIC8qKgorICAgICAqIERvZXMgbm90aGluZworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHZlcmlmeShQdWJsaWNLZXkga2V5LCBTdHJpbmcgc2lnUHJvdmlkZXIpCisgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRLZXlFeGNlcHRpb24sIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLCBTaWduYXR1cmVFeGNlcHRpb24geworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgZm9ybWF0dGVkIDxjb2RlPlN0cmluZzwvY29kZT4KKyAgICAgKiBkZXNjcmliaW5nIDxjb2RlPk15Q2VydGlmaWNhdGU8L2NvZGU+IG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiAiW015IHRlc3QgQ2VydGlmaWNhdGUsIHR5cGU6ICIgKyBnZXRUeXBlKCkgKyAiXSI7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCB3cml0ZVJlcGxhY2UoKSB0aHJvd3MgT2JqZWN0U3RyZWFtRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLndyaXRlUmVwbGFjZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgcHVibGljIGtleSAoc3R1YikgZnJvbSA8Y29kZT5NeUNlcnRpZmljYXRlPC9jb2RlPiBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgUHVibGljS2V5IGdldFB1YmxpY0tleSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBQdWJsaWNLZXkoKSB7CisgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDc4ODA3NzkyODMzNTU4OTgxNkw7CisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gIlRFU1QiOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgeworICAgICAgICAgICAgICAgIHJldHVybiBuZXcgYnl0ZVtdIHsoYnl0ZSkxLCAoYnl0ZSkyLCAoYnl0ZSkzfTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9ybWF0KCkgeworICAgICAgICAgICAgICAgIHJldHVybiAiVEVTVF9GT1JNQVQiOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KKworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZS5DZXJ0aWZpY2F0ZVJlcCBnZXRDZXJ0aWZpY2F0ZVJlcCgpCisgICAgICAgICAgICB0aHJvd3MgT2JqZWN0U3RyZWFtRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0IG9iaiA9IHN1cGVyLndyaXRlUmVwbGFjZSgpOworICAgICAgICByZXR1cm4gKE15Q2VydGlmaWNhdGVSZXApIG9iajsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgTXlDZXJ0aWZpY2F0ZVJlcCBleHRlbmRzIENlcnRpZmljYXRlLkNlcnRpZmljYXRlUmVwIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzQ3NDI4NDA0Mzk5NDYzNTU1M0w7CisKKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgdHlwZTsKKyAgICAgICAgcHJpdmF0ZSBieXRlW10gZGF0YTsKKworICAgICAgICBwdWJsaWMgTXlDZXJ0aWZpY2F0ZVJlcChTdHJpbmcgdHlwZSwgYnl0ZVtdIGRhdGEpIHsKKyAgICAgICAgICAgIHN1cGVyKHR5cGUsIGRhdGEpOworICAgICAgICAgICAgdGhpcy5kYXRhID0gZGF0YTsKKyAgICAgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgT2JqZWN0IHJlYWRSZXNvbHZlKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIucmVhZFJlc29sdmUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSgpIHsKKyAgICAgICAgICAgIHJldHVybiB0eXBlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJ5dGVbXSBnZXREYXRhKCkgeworICAgICAgICAgICAgcmV0dXJuIGRhdGE7CisgICAgICAgIH0KKyAgICB9CisgICAgcHVibGljIFNldDxTdHJpbmc+IGdldE5vbkNyaXRpY2FsRXh0ZW5zaW9uT0lEcygpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIFNldDxTdHJpbmc+IGdldENyaXRpY2FsRXh0ZW5zaW9uT0lEcygpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRFeHRlbnNpb25WYWx1ZShTdHJpbmcgb2lkKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGhhc1Vuc3VwcG9ydGVkQ3JpdGljYWxFeHRlbnNpb24oKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvY2VydC9NeUNlcnRpZmljYXRlRmFjdG9yeVNwaS5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L2NlcnQvTXlDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYTdlY2M4Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L2NlcnQvTXlDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkuamF2YQpAQCAtMCwwICsxLDEzOSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmVyYSBZLiBQZXRyYXNoa292YQorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQ7CisKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DUkw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNSTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGg7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5U3BpOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCisvKioKKyAqIEFkZGl0aW9uYWwgY2xhc3MgZm9yIHZlcmlmaWNhdGlvbiBDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkgYW5kCisgKiBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2xhc3NlcworICoKKyAqLworCitwdWJsaWMgY2xhc3MgTXlDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkgZXh0ZW5kcyBDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkgeworICAgIC8vIFZhcmlhbnRzIG9mIGV4ZWN1dGlvbjoKKyAgICAvLyBtb2RlOiBmYWxzZSAtIGxpc3Qgb2YgZW5jb2RpbmdzIGlzIGVtcHR5CisgICAgLy8gbW9kZTogdHJ1ZSAtIGxpc3Qgb2YgZW5jb2RpbmdzIGNvbnNpc3RzIG9mIDIgZWxlbWVudHMKKyAgICAvLyAgICAgICAgICAgICAgIHNvbWUgZXhjZXB0aW9ucyBhcmUgdGhyb3duIHdoZW4KKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIG1vZGU7CisKKyAgICBwcml2YXRlIFNldDxTdHJpbmc+IGxpc3Q7CisKKyAgICBwdWJsaWMgTXlDZXJ0aWZpY2F0ZUZhY3RvcnlTcGkoKSB7CisgICAgICAgIHN1cGVyKCk7CisgICAgICAgIG1vZGUgPSB0cnVlOworICAgICAgICBsaXN0ID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgICBsaXN0LmFkZCgiYWEiKTsKKyAgICAgICAgbGlzdC5hZGQoImJiIik7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHB1dE1vZGUoYm9vbGVhbiBuZXdNb2RlKSB7CisgICAgICAgIG1vZGUgPSBuZXdNb2RlOworICAgIH0KKworICAgIHB1YmxpYyBDZXJ0aWZpY2F0ZSBlbmdpbmVHZW5lcmF0ZUNlcnRpZmljYXRlKElucHV0U3RyZWFtIGluU3RyZWFtKQorICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCEoaW5TdHJlYW0gaW5zdGFuY2VvZiBEYXRhSW5wdXRTdHJlYW0pKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oIkluY29ycmVjdCBpbnB1dHN0cmVhbSIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBDb2xsZWN0aW9uIGVuZ2luZUdlbmVyYXRlQ2VydGlmaWNhdGVzKElucHV0U3RyZWFtIGluU3RyZWFtKQorICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCEoaW5TdHJlYW0gaW5zdGFuY2VvZiBEYXRhSW5wdXRTdHJlYW0pKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oIkluY29ycmVjdCBpbnB1dHN0cmVhbSIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBDUkwgZW5naW5lR2VuZXJhdGVDUkwoSW5wdXRTdHJlYW0gaW5TdHJlYW0pIHRocm93cyBDUkxFeGNlcHRpb24geworICAgICAgICBpZiAoIShpblN0cmVhbSBpbnN0YW5jZW9mIERhdGFJbnB1dFN0cmVhbSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDUkxFeGNlcHRpb24oIkluY29ycmVjdCBpbnB1dHN0cmVhbSIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBDb2xsZWN0aW9uIGVuZ2luZUdlbmVyYXRlQ1JMcyhJbnB1dFN0cmVhbSBpblN0cmVhbSkKKyAgICAgICAgICAgIHRocm93cyBDUkxFeGNlcHRpb24geworICAgICAgICBpZiAoIShpblN0cmVhbSBpbnN0YW5jZW9mIERhdGFJbnB1dFN0cmVhbSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBDUkxFeGNlcHRpb24oIkluY29ycmVjdCBpbnB1dHN0cmVhbSIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBDZXJ0UGF0aCBlbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKElucHV0U3RyZWFtIGluU3RyZWFtKQorICAgICAgICAgICAgdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCEoaW5TdHJlYW0gaW5zdGFuY2VvZiBEYXRhSW5wdXRTdHJlYW0pKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFeGNlcHRpb24oIkluY29ycmVjdCBpbnB1dHN0cmVhbSIpOworICAgICAgICB9CisgICAgICAgIEl0ZXJhdG9yPFN0cmluZz4gaXQgPSBlbmdpbmVHZXRDZXJ0UGF0aEVuY29kaW5ncygpOworICAgICAgICBpZiAoIWl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKCJUaGVyZSBhcmUgbm8gQ2VydFBhdGggZW5jb2RpbmdzIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGVuZ2luZUdlbmVyYXRlQ2VydFBhdGgoaW5TdHJlYW0sIGl0Lm5leHQoKSk7CisgICAgfQorCisgICAgcHVibGljIENlcnRQYXRoIGVuZ2luZUdlbmVyYXRlQ2VydFBhdGgoSW5wdXRTdHJlYW0gaW5TdHJlYW0sIFN0cmluZyBlbmNvZGluZykKKyAgICAgICAgICAgIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghKGluU3RyZWFtIGluc3RhbmNlb2YgRGF0YUlucHV0U3RyZWFtKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IENlcnRpZmljYXRlRXhjZXB0aW9uKCJJbmNvcnJlY3QgaW5wdXRzdHJlYW0iKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZW5jb2RpbmcubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgaWYgKG1vZGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJFbmNvZGluZyBpcyBlbXB0eSIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBDZXJ0UGF0aCBlbmdpbmVHZW5lcmF0ZUNlcnRQYXRoKExpc3Q8PyBleHRlbmRzIENlcnRpZmljYXRlPiBjZXJ0aWZpY2F0ZXMpIHsKKyAgICAgICAgaWYgKGNlcnRpZmljYXRlcyA9PSBudWxsKSB7CisgICAgICAgICAgICBpZiAobW9kZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiY2VydGlmaWNhdGVzIGlzIG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgSXRlcmF0b3I8U3RyaW5nPiBlbmdpbmVHZXRDZXJ0UGF0aEVuY29kaW5ncygpIHsKKyAgICAgICAgaWYgKCFtb2RlKSB7CisgICAgICAgICAgICBsaXN0LmNsZWFyKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGxpc3QuaXRlcmF0b3IoKTsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L2NlcnQvTXlGYWlsaW5nQ2VydFBhdGguamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9jZXJ0L015RmFpbGluZ0NlcnRQYXRoLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzhhNGZkYgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9jZXJ0L015RmFpbGluZ0NlcnRQYXRoLmphdmEKQEAgLTAsMCArMSwxNiBAQAorcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb247CisKK3B1YmxpYyBjbGFzcyBNeUZhaWxpbmdDZXJ0UGF0aCBleHRlbmRzIE15Q2VydFBhdGggeworCisgICAgcHVibGljIE15RmFpbGluZ0NlcnRQYXRoKGJ5dGVbXSBlbmNvZGluZykgeworICAgICAgICBzdXBlcihlbmNvZGluZyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgdGhyb3dzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbigidGVzdGluZyBwdXJwb3NlIik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvY2VydC9NeUZhaWxpbmdDZXJ0aWZpY2F0ZS5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L2NlcnQvTXlGYWlsaW5nQ2VydGlmaWNhdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNTIyYjI3Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L2NlcnQvTXlGYWlsaW5nQ2VydGlmaWNhdGUuamF2YQpAQCAtMCwwICsxLDE2IEBACitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmNlcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbjsKKworcHVibGljIGNsYXNzIE15RmFpbGluZ0NlcnRpZmljYXRlIGV4dGVuZHMgTXlDZXJ0aWZpY2F0ZSB7CisKKyAgICBwdWJsaWMgTXlGYWlsaW5nQ2VydGlmaWNhdGUoU3RyaW5nIHR5cGUsIGJ5dGVbXSBlbmNvZGluZykgeworICAgICAgICBzdXBlcih0eXBlLCBlbmNvZGluZyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGVbXSBnZXRFbmNvZGVkKCkgdGhyb3dzIENlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbigidGVzdGluZyBwdXJwb3NlIik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvY2VydC9UZXN0VXRpbHMuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9jZXJ0L1Rlc3RVdGlscy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ5MzZmZWQKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvY2VydC9UZXN0VXRpbHMuamF2YQpAQCAtMCwwICsxLDg0MCBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoqCisqIEBhdXRob3IgVmxhZGltaXIgTi4gTW9sb3Rrb3YKKyogQHZlcnNpb24gJFJldmlzaW9uJAorKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5jZXJ0OworCitpbXBvcnQgdGVzdHMuc3VwcG9ydC5yZXNvdXJjZS5TdXBwb3J0X1Jlc291cmNlczsKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5JbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aEJ1aWxkZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoQnVpbGRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydFBhdGhCdWlsZGVyUmVzdWx0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0UGF0aFBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0U3RvcmU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVGYWN0b3J5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5Db2xsZWN0aW9uQ2VydFN0b3JlUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5QS0lYQ2VydFBhdGhCdWlsZGVyUmVzdWx0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5QS0lYQ2VydFBhdGhDaGVja2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5Qb2xpY3lOb2RlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5Qb2xpY3lRdWFsaWZpZXJJbmZvOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5UcnVzdEFuY2hvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRTZWxlY3RvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCisvKioKKyAqIGphdmEuc2VjdXJpdHkuY2VydCB0ZXN0IHV0aWxpdGllcworICoKKyAqLworcHVibGljIGNsYXNzIFRlc3RVdGlscyB7CisgICAgLy8gQ2VydGlmaWNhdGUgdHlwZSB1c2VkIGR1cmluZyB0ZXN0aW5nCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGNlcnRUeXBlID0gIlguNTA5IjsKKyAgICAvLyBLZXkgc3RvcmUgdHlwZSB1c2VkIGR1cmluZyB0ZXN0aW5nCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGtleVN0b3JlVHlwZSA9ICJCS1MiOworICAgIC8vIFRoZSBmaWxlIG5hbWUgcHJlZml4IHRvIGxvYWQga2V5c3RvcmUgZnJvbQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBrZXlTdG9yZUZpbGVOYW1lID0gInRlc3QuIiArIGtleVN0b3JlVHlwZQorICAgICAgICAgICAgKyAiLmtzIjsKKyAgICAvLworICAgIC8vIFRoZSBmaWxlIG5hbWUgc3VmZml4ZXMgdG8gbG9hZCBrZXlzdG9yZSBmcm9tCisgICAgLy8gICoua3MxIC0ga2V5c3RvcmUgY29udGFpbmluZyB1bnRydXN0ZWQgY2VydGlmaWNhdGVzIG9ubHkKKyAgICAvLyAgKi5rczIgLSBrZXlzdG9yZSBjb250YWluaW5nIHRydXN0ZWQgY2VydGlmaWNhdGVzIG9ubHkKKyAgICAvLyAgKi5rczMgLSBrZXlzdG9yZSBjb250YWluaW5nIGJvdGggdHJ1c3RlZCBhbmQgdW50cnVzdGVkIGNlcnRpZmljYXRlcworICAgIC8vCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5UUlVTVEVEID0gMTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUUlVTVEVEID0gMjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUUlVTVEVEX0FORF9VTlRSVVNURUQgPSAzOworICAgIC8vCisgICAgLy8gQ29tbW9uIHBhc3N3b3JkcyBmb3IgYWxsIHRlc3Qga2V5c3RvcmVzCisgICAgLy8KKyAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBjaGFyW10gc3RvcmVwYXNzID0KKyAgICAgICAgbmV3IGNoYXJbXSB7J3MnLCd0JywnbycsJ3InLCdlJywncCcsJ3cnLCdkJ307CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIDxjb2RlPlRydXN0QW5jaG9yPC9jb2RlPiBpbnN0YW5jZQorICAgICAqIGNvbnN0cnVjdGVkIHVzaW5nIHNlbGYgc2lnbmVkIHRlc3QgY2VydGlmaWNhdGUKKyAgICAgKgorICAgICAqIEByZXR1cm4gPGNvZGU+VHJ1c3RBbmNob3I8L2NvZGU+IGluc3RhbmNlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBUcnVzdEFuY2hvciBnZXRUcnVzdEFuY2hvcigpIHsKKyAgICAgICAgQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKGNlcnRUeXBlKTsKKyAgICAgICAgfSBjYXRjaCAoQ2VydGlmaWNhdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gcmVxdWVzdGVkIGNlcnQgdHlwZSBpcyBub3QgYXZhaWxhYmxlIGluIHRoZQorICAgICAgICAgICAgLy8gZGVmYXVsdCBwcm92aWRlciBwYWNrYWdlIG9yIGFueSBvZiB0aGUgb3RoZXIgcHJvdmlkZXIgcGFja2FnZXMKKyAgICAgICAgICAgIC8vIHRoYXQgd2VyZSBzZWFyY2hlZAorICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICAgICAgQnVmZmVyZWRJbnB1dFN0cmVhbSBiaXMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYmlzID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgICAgICBnZXRFbmNvZGVkWDUwOUNlcnRpZmljYXRlKCkpKTsKKyAgICAgICAgICAgIFg1MDlDZXJ0aWZpY2F0ZSBjMSA9IChYNTA5Q2VydGlmaWNhdGUpY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShiaXMpOworCisgICAgICAgICAgICByZXR1cm4gbmV3IFRydXN0QW5jaG9yKGMxLCBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGFsbCBmYWlsdXJlcyBhcmUgZmF0YWwKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGJpcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgYmlzLmNsb3NlKCkgOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlnbikge30KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgPGNvZGU+U2V0PC9jb2RlPiBvZiA8Y29kZT5UcnVzdEFuY2hvcjwvY29kZT5zCisgICAgICogY29udGFpbmluZyBzaW5nbGUgZWxlbWVudCAoc2VsZiBzaWduZWQgdGVzdCBjZXJ0aWZpY2F0ZSkuCisgICAgICogQHJldHVybiBSZXR1cm5zIDxjb2RlPlNldDwvY29kZT4gb2YgPGNvZGU+VHJ1c3RBbmNob3I8L2NvZGU+cworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU2V0PFRydXN0QW5jaG9yPiBnZXRUcnVzdEFuY2hvclNldCgpIHsKKyAgICAgICAgVHJ1c3RBbmNob3IgdGEgPSBnZXRUcnVzdEFuY2hvcigpOworICAgICAgICBpZiAodGEgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgSGFzaFNldDxUcnVzdEFuY2hvcj4gc2V0ID0gbmV3IEhhc2hTZXQ8VHJ1c3RBbmNob3I+KCk7CisgICAgICAgIGlmICghc2V0LmFkZCh0YSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJDb3VsZCBub3QgY3JlYXRlIHRydXN0IGFuY2hvciBzZXQiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgdGVzdCA8Y29kZT5LZXlTdG9yZTwvY29kZT4gaW5zdGFuY2UKKyAgICAgKgorICAgICAqIEBwYXJhbSBpbml0aWFsaXplCisgICAgICogIERvIG5vdCBpbml0aWFsaXplIHJldHVybmVkIDxjb2RlPktleVN0b3JlPC9jb2RlPiBpZiBmYWxzZQorICAgICAqCisgICAgICogQHBhcmFtIHRlc3RLZXlTdG9yZVR5cGUKKyAgICAgKiAgdGhpcyBwYXJhbWV0ZXIgaWdub3JlZCBpZiA8Y29kZT5pbml0aWFsaXplPC9jb2RlPiBpcyBmYWxzZTsKKyAgICAgKiAgVGhlIGZvbGxvd2luZyB0eXBlcyBzdXBwb3J0ZWQ6PGJyPgorICAgICAqICAxIC0gPGNvZGU+S2V5U3RvcmU8L2NvZGU+IHdpdGggdW50cnVzdGVkIGNlcnRpZmljYXRlcyBvbmx5PGJyPgorICAgICAqICAyIC0gPGNvZGU+S2V5U3RvcmU8L2NvZGU+IHdpdGggdHJ1c3RlZCBjZXJ0aWZpY2F0ZXMgb25seTxicj4KKyAgICAgKiAgMyAtIDxjb2RlPktleVN0b3JlPC9jb2RlPiB3aXRoIGJvdGggdHJ1c3RlZCBhbmQgdW50cnVzdGVkIGNlcnRpZmljYXRlcworICAgICAqCisgICAgICogQHJldHVybiBSZXR1cm5zIHRlc3QgPGNvZGU+S2V5U3RvcmU8L2NvZGU+IGluc3RhbmNlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBLZXlTdG9yZSBnZXRLZXlTdG9yZShib29sZWFuIGluaXRpYWxpemUsCisgICAgICAgICAgICBpbnQgdGVzdEtleVN0b3JlVHlwZSkgeworICAgICAgICBCdWZmZXJlZElucHV0U3RyZWFtIGJpcyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBLZXlTdG9yZSBrcyA9IEtleVN0b3JlLmdldEluc3RhbmNlKGtleVN0b3JlVHlwZSk7CisgICAgICAgICAgICBpZiAoaW5pdGlhbGl6ZSkgeworICAgICAgICAgICAgICAgIFN0cmluZyBmaWxlTmFtZSA9IGtleVN0b3JlRmlsZU5hbWUgKyB0ZXN0S2V5U3RvcmVUeXBlOworICAgICAgICAgICAgICAgIGtzLmxvYWQoU3VwcG9ydF9SZXNvdXJjZXMuZ2V0UmVzb3VyY2VTdHJlYW0oZmlsZU5hbWUpLAorICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmVwYXNzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBrczsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGluaXRpYWxpemUgJiYgYmlzICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBiaXMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpZ24pIHt9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIDxjb2RlPkxpc3Q8L2NvZGU+IG9mIDxjb2RlPkNvbGxlY3Rpb25DZXJ0U3RvcmVzPC9jb2RlPgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgbGlzdCBjcmVhdGVkCisgICAgICoKKyAgICAgKiBAdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTGlzdDxDZXJ0U3RvcmU+IGdldENvbGxlY3Rpb25DZXJ0U3RvcmVzTGlzdCgpCisgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uLAorICAgICAgICAgICAgICAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgQ2VydFN0b3JlIGNzID0gQ2VydFN0b3JlLmdldEluc3RhbmNlKCJDb2xsZWN0aW9uIiwKKyAgICAgICAgICAgICAgICBuZXcgQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMoKSk7CisgICAgICAgIEFycmF5TGlzdDxDZXJ0U3RvcmU+IGwgPSBuZXcgQXJyYXlMaXN0PENlcnRTdG9yZT4oKTsKKyAgICAgICAgaWYgKCFsLmFkZChjcykpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJDb3VsZCBub3QgY3JlYXRlIGNlcnQgc3RvcmVzIGxpc3QiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHN0dWIgaW1wbGVtZW50YXRpb24gb2YgdGhlIDxjb2RlPlBLSVhDZXJ0UGF0aENoZWNrZXI8L2NvZGU+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIFN0dWIgaW1wbGVtZW50YXRpb24gb2YgdGhlIDxjb2RlPlBLSVhDZXJ0UGF0aENoZWNrZXI8L2NvZGU+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBQS0lYQ2VydFBhdGhDaGVja2VyIGdldFRlc3RDZXJ0UGF0aENoZWNrZXIoKSB7CisgICAgICAgIC8vIHN0dWIgaW1wbGVtZW50YXRpb24gZm9yIHRlc3RpbmcgcHVycG9zZXMgb25seQorICAgICAgICByZXR1cm4gbmV3IFBLSVhDZXJ0UGF0aENoZWNrZXIoKSB7CisgICAgICAgICAgICBwcml2YXRlIGJvb2xlYW4gZm9yd2FyZCA9IGZhbHNlOworCisKKyAgICAgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIiwgInVuY2hlY2tlZCJ9KQorICAgICAgICAgICAgcHVibGljIHZvaWQgY2hlY2soQ2VydGlmaWNhdGUgYXJnMCwgQ29sbGVjdGlvbiBhcmcxKQorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydFBhdGhWYWxpZGF0b3JFeGNlcHRpb24geworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgU2V0PFN0cmluZz4gZ2V0U3VwcG9ydGVkRXh0ZW5zaW9ucygpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBpbml0KGJvb2xlYW4gYXJnMCkgdGhyb3dzIENlcnRQYXRoVmFsaWRhdG9yRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBmb3J3YXJkID0gYXJnMDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaXNGb3J3YXJkQ2hlY2tpbmdTdXBwb3J0ZWQoKSB7CisgICAgICAgICAgICAgICAgLy8ganVzdCB0byBjaGVjayB0aGlzIGNoZWNrZXIgc3RhdGUKKyAgICAgICAgICAgICAgICByZXR1cm4gZm9yd2FyZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHBvbGljeSB0cmVlIHN0dWIgY29udGFpbmluZyB0d28gPGNvZGU+UG9saWN5Tm9kZTwvY29kZT5zCisgICAgICogZm9yIHRlc3RpbmcgcHVycG9zZXMKKyAgICAgKgorICAgICAqIEByZXR1cm4gcm9vdCA8Y29kZT5Qb2xpY3lOb2RlPC9jb2RlPiBvZiB0aGUgcG9saWN5IHRyZWUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFBvbGljeU5vZGUgZ2V0UG9saWN5VHJlZSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBQb2xpY3lOb2RlKCkgeworICAgICAgICAgICAgZmluYWwgUG9saWN5Tm9kZSBwYXJlbnQgPSB0aGlzOworICAgICAgICAgICAgcHVibGljIGludCBnZXREZXB0aCgpIHsKKyAgICAgICAgICAgICAgICAvLyBwYXJlbnQKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaXNDcml0aWNhbCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsaWRQb2xpY3koKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHB1YmxpYyBQb2xpY3lOb2RlIGdldFBhcmVudCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIEl0ZXJhdG9yPFBvbGljeU5vZGU+IGdldENoaWxkcmVuKCkgeworICAgICAgICAgICAgICAgIFBvbGljeU5vZGUgY2hpbGQgPSBuZXcgUG9saWN5Tm9kZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIGludCBnZXREZXB0aCgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoaWxkCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGlzQ3JpdGljYWwoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFZhbGlkUG9saWN5KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgUG9saWN5Tm9kZSBnZXRQYXJlbnQoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50OworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIEl0ZXJhdG9yPFBvbGljeU5vZGU+IGdldENoaWxkcmVuKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBwdWJsaWMgU2V0PFN0cmluZz4gZ2V0RXhwZWN0ZWRQb2xpY2llcygpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIFNldDw/IGV4dGVuZHMgUG9saWN5UXVhbGlmaWVySW5mbz4gZ2V0UG9saWN5UXVhbGlmaWVycygpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfTsKKyAgICAgICAgICAgICAgICBIYXNoU2V0PFBvbGljeU5vZGU+IHMgPSBuZXcgSGFzaFNldDxQb2xpY3lOb2RlPigpOworICAgICAgICAgICAgICAgIHMuYWRkKGNoaWxkKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gcy5pdGVyYXRvcigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgU2V0PFN0cmluZz4gZ2V0RXhwZWN0ZWRQb2xpY2llcygpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIFNldDw/IGV4dGVuZHMgUG9saWN5UXVhbGlmaWVySW5mbz4gZ2V0UG9saWN5UXVhbGlmaWVycygpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICB9CisgICAgLy8gWC41MDkgZW5jb2RlZCBjZXJ0aWZpY2F0ZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFTkNPREVEX1g1MDlfQ0VSVElGSUNBVEUgPSAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICAgICArICJNSUlESFRDQ0F0c0NCRUZUNzJzd0N3WUhLb1pJempnRUF3VUFNSFF4Q3pBSkJnTlZCQVlUQWxKVk1Rd3dDZ1lEVlFRSUV3Tk9VMDh4XG4iCisgICAgICAgICAgICArICJGREFTQmdOVkJBY1RDMDV2ZG05emFXSnBjbk5yTVE0d0RBWURWUVFLRXdWSmJuUmxiREVWTUJNR0ExVUVDeE1NUkZKTUlGTmxZM1Z5XG4iCisgICAgICAgICAgICArICJhWFI1TVJvd0dBWURWUVFERXhGV2JHRmthVzFwY2lCTmIyeHZkR3R2ZGpBZUZ3MHdOREE1TWpRd09UVTJOVGxhRncwd05qQTFNVGN3XG4iCisgICAgICAgICAgICArICJPVFUyTlRsYU1IUXhDekFKQmdOVkJBWVRBbEpWTVF3d0NnWURWUVFJRXdOT1UwOHhGREFTQmdOVkJBY1RDMDV2ZG05emFXSnBjbk5yXG4iCisgICAgICAgICAgICArICJNUTR3REFZRFZRUUtFd1ZKYm5SbGJERVZNQk1HQTFVRUN4TU1SRkpNSUZObFkzVnlhWFI1TVJvd0dBWURWUVFERXhGV2JHRmthVzFwXG4iCisgICAgICAgICAgICArICJjaUJOYjJ4dmRHdHZkakNDQWJnd2dnRXNCZ2NxaGtqT09BUUJNSUlCSHdLQmdRRDlmMU9CSFhVU0tWTGZTcHd1N09UbjloRzNVanp2XG4iCisgICAgICAgICAgICArICJSQURESGorQXRsRW1hVVZkUUNKUisxazlqVmo2djhYMXVqRDJ5NXRWYk5lQk80QWRORy95Wm1DM2E1bFFwYVNmbitnRWV4QWl3ays3XG4iCisgICAgICAgICAgICArICJxZGYrdDhZYitEdFg1OGFvcGhVUEJQdUQ5dFBGSHNNQ05WUVRXaGFSTXZaMTg2NHJZZGNxNy9JaUF4bWQwVWdCeHdJVkFKZGdVSThWXG4iCisgICAgICAgICAgICArICJJd3ZNc3BLNWdxTHJoQXZ3V0J6MUFvR0JBUGZob0lYV216M2V5N3lyWERhNFY3bDVsSys3K2pycWd2bFhUQXM5QjRKblVWbFhqcnJVXG4iCisgICAgICAgICAgICArICJXVS9tY1FjUWdZQzBTUlp4SStoTUtCWVR0ODhKTW96SXB1RThGbnFMVkh5TktPQ2pyaDRyczZaMWtXNmpmd3Y2SVRWaThmdGllZ0VrXG4iCisgICAgICAgICAgICArICJPOHlrOGI2b1VaQ0pxSVBmNFZybG53YVNpMlplZ0h0VkpXUUJURHYrejBrcUE0R0ZBQUtCZ1FEaU5tajlqZ1d1MUlMWXFZV2NVaE5OXG4iCisgICAgICAgICAgICArICI4Q2pqUml0ZjgweVdQL3MvNTY1d1p6M2FuYjJ3NzJqdW02M21kU2hEa285ZU9PT2QxaGlWdWlCbk5oU0w3RDZKZklZQkp2TlhyMWF2XG4iCisgICAgICAgICAgICArICJHdzU4M0JCdjEyT0JnZzBlQVcvR1JXQm4yQWsySmpzb0JjNXgyYzFIQUV1ZmFrZXA3VDZSb0MrbjNscWJLUEt5SFdWZGZxUTlLVEFMXG4iCisgICAgICAgICAgICArICJCZ2NxaGtqT09BUURCUUFETHdBd0xBSVVhUlMzQzlkWGNNYnJPQWhtaWRGQnI3b012SDBDRkVDM0xVd2ZMSlg1Z1k4UDZ1eHBrUHgzXG4iCisgICAgICAgICAgICArICJKRFNNXG4iICsgIi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cbiI7CisKKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBnZXRFbmNvZGVkWDUwOUNlcnRpZmljYXRlKCkgeworICAgICAgICByZXR1cm4gRU5DT0RFRF9YNTA5X0NFUlRJRklDQVRFLmdldEJ5dGVzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBYLjUwOSBjZXJ0aWZpY2F0ZSBlbmNvZGluZyBjb3JyZXNwb25kaW5nIHRvIHZlcnNpb24gdjEuCisgICAgICoKKyAgICAgKiBDZXJ0aWZpY2F0ZSBlbmNvZGluZyB3YXMgY3JlYXRlZCBieSBoYW5kcyBhY2NvcmRpbmcgdG8gWC41MDkgQ2VydGlmaWNhdGUKKyAgICAgKiBBU04uMSBub3RhdGlvbi4gVGhlIGNlcnRpZmljYXRlIGVuY29kaW5nIGhhcyB0aGUgZm9sbG93aW5nIGVuY29kZWQKKyAgICAgKiBmaWVsZCB2YWx1ZXM6PGJyPgorICAgICAqIC0gdmVyc2lvbjogMTxicj4KKyAgICAgKiAtIHNlcmlhbE51bWJlcjogNTxicj4KKyAgICAgKiAtIGlzc3VlcjogQ049Wjxicj4KKyAgICAgKiAtIG5vdEJlZm9yZTogMTMgRGVjIDE5OTkgMTQ6MTU6MTY8YnI+CisgICAgICogLSBub3RBZnRlcjogMDEgSmFuIDIwMDAgMDA6MDA6MDA8YnI+CisgICAgICogLSBzdWJqZWN0OiBDTj1ZPGJyPgorICAgICAqCisgICAgICogQHJldHVybiBYLjUwOSBjZXJ0aWZpY2F0ZSBlbmNvZGluZyBjb3JyZXNwb25kaW5nIHRvIHZlcnNpb24gdjEuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gZ2V0WDUwOUNlcnRpZmljYXRlX3YxKCkgeworICAgICAgICByZXR1cm4gbmV3IGJ5dGVbXSB7CisgICAgICAgIC8vIENlcnRpZmljYXRlOiBTRVFVRU5DRQorICAgICAgICAgICAgMHgzMCwgMHg2QiwKKworICAgICAgICAgICAgLy8KKyAgICAgICAgICAgIC8vIFRCU0NlcnRpZmljYXRlOiBTRVFVRU5DRSB7CisgICAgICAgICAgICAvLworICAgICAgICAgICAgMHgzMCwgMHg1QywKKworICAgICAgICAgICAgLy8gdmVyc2lvbjogWzBdIEVYUExJQ0lUIFZlcnNpb24gREVGQVVMVCB2MQorICAgICAgICAgICAgKGJ5dGUpIDB4QTAsIDB4MDMsIDB4MDIsIDB4MDEsIDB4MDAsCisKKyAgICAgICAgICAgIC8vIHNlcmlhbE51bWJlcjogQ2VydGlmaWNhdGVTZXJpYWxOdW1iZXIKKyAgICAgICAgICAgIDB4MDIsIDB4MDEsIDB4MDUsCisKKyAgICAgICAgICAgIC8vIHNpZ25hdHVyZTogQWxnb3JpdGhtSWRlbnRpZmllcgorICAgICAgICAgICAgMHgzMCwgMHgwNywgLy8gU0VRVUVOQ0UKKyAgICAgICAgICAgIDB4MDYsIDB4MDIsIDB4MDMsIDB4MDUsLy9PSUQKKyAgICAgICAgICAgIDB4MDEsIDB4MDEsIDB4MDcsIC8vQU5ZCisKKyAgICAgICAgICAgIC8vaXNzdWVyOiBOYW1lCisgICAgICAgICAgICAweDMwLCAweDBDLCAweDMxLCAweDBBLCAweDMwLCAweDA4LCAweDA2LCAweDAzLCAweDU1LCAweDA0LCAweDAzLAorICAgICAgICAgICAgMHgxMywgMHgwMSwgMHg1QSwgLy8gQ049WgorCisgICAgICAgICAgICAvL3ZhbGlkaXR5OiBWYWxpZGl0eQorICAgICAgICAgICAgMHgzMCwgMHgxRSwgLy8gU0VRVUVOQ0UKKyAgICAgICAgICAgIC8vIG5vdEJlZm9yZTogVVRDVGltZQorICAgICAgICAgICAgMHgxNywgMHgwRCwgMHgzOSwgMHgzOSwgMHgzMSwgMHgzMiwgMHgzMSwgMHgzMywgMHgzMSwgMHgzNCwgMHgzMSwKKyAgICAgICAgICAgIDB4MzUsIDB4MzEsIDB4MzYsIDB4NUEsIC8vIDEzIERlYyAxOTk5IDE0OjE1OjE2CisgICAgICAgICAgICAvLyBub3RBZnRlcjogIFVUQ1RpbWUKKyAgICAgICAgICAgIDB4MTcsIDB4MEQsIDB4MzAsIDB4MzAsIDB4MzAsIDB4MzEsIDB4MzAsIDB4MzEsIDB4MzAsIDB4MzAsIDB4MzAsCisgICAgICAgICAgICAweDMwLCAweDMwLCAweDMwLCAweDVBLCAvLyAwMSBKYW4gMjAwMCAwMDowMDowMAorCisgICAgICAgICAgICAvL3N1YmplY3Q6IE5hbWUKKyAgICAgICAgICAgIDB4MzAsIDB4MEMsIDB4MzEsIDB4MEEsIDB4MzAsIDB4MDgsIDB4MDYsIDB4MDMsIDB4NTUsIDB4MDQsIDB4MDMsCisgICAgICAgICAgICAweDEzLCAweDAxLCAweDU5LCAvLyBDTj1ZCisgICAgICAgICAgICAvL1N1YmplY3RQdWJsaWNLZXlJbmZvICA6Oj0gIFNFUVVFTkNFICB7CisgICAgICAgICAgICAvLyAgICBhbGdvcml0aG0gICAgICAgICAgICBBbGdvcml0aG1JZGVudGlmaWVyLAorICAgICAgICAgICAgLy8gICAgc3ViamVjdFB1YmxpY0tleSAgICAgQklUIFNUUklORyAgfQorICAgICAgICAgICAgMHgzMCwgMHgwRCwgLy8gU0VRVUVOQ0UKKyAgICAgICAgICAgIDB4MzAsIDB4MDcsIC8vIFNFUVVFTkNFCisgICAgICAgICAgICAweDA2LCAweDAyLCAweDAzLCAweDA1LC8vT0lECisgICAgICAgICAgICAweDAxLCAweDAxLCAweDA3LCAvL0FOWQorICAgICAgICAgICAgMHgwMywgMHgwMiwgMHgwMCwgMHgwMSwgLy8gc3ViamVjdFB1YmxpY0tleQorCisgICAgICAgICAgICAvLyBpc3N1ZXJVbmlxdWVJRCAtIG1pc3NlZAorICAgICAgICAgICAgLy8gc3ViamVjdFVuaXF1ZUlEIC0gbWlzc2VkCisgICAgICAgICAgICAvLyBleHRlbnNpb25zIC0gbWlzc2VkCisKKyAgICAgICAgICAgIC8vIH0gZW5kIFRCU0NlcnRpZmljYXRlCisKKyAgICAgICAgICAgIC8vCisgICAgICAgICAgICAvLyBzaWduYXR1cmVBbGdvcml0aG06IEFsZ29yaXRobUlkZW50aWZpZXIKKyAgICAgICAgICAgIC8vCisgICAgICAgICAgICAweDMwLCAweDA3LCAvLyBTRVFVRU5DRQorICAgICAgICAgICAgMHgwNiwgMHgwMiwgMHgwMywgMHgwNSwvL09JRAorICAgICAgICAgICAgMHgwMSwgMHgwMSwgMHgwNywgLy9BTlkKKworICAgICAgICAgICAgLy8KKyAgICAgICAgICAgIC8vIHNpZ25hdHVyZTogQklUIFNUUklORworICAgICAgICAgICAgLy8KKyAgICAgICAgICAgIDB4MDMsIDB4MDIsIDB4MDAsIDB4MDEgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIFguNTA5IGNlcnRpZmljYXRlIGVuY29kaW5nIGNvcnJlc3BvbmRpbmcgdG8gdmVyc2lvbiB2My4KKyAgICAgKgorICAgICAqIENlcnRpZmljYXRlIGVuY29kaW5nIHdhcyBjcmVhdGVkIGJ5IGhhbmRzIGFjY29yZGluZyB0byBYLjUwOSBDZXJ0aWZpY2F0ZQorICAgICAqIEFTTi4xIG5vdGF0aW9uLiBUaGUgY2VydGlmaWNhdGUgZW5jb2RpbmcgaGFzIHRoZSBmb2xsb3dpbmcgZW5jb2RlZAorICAgICAqIGZpZWxkIHZhbHVlczo8YnI+CisgICAgICogLSB2ZXJzaW9uOiAzPGJyPgorICAgICAqIC0gc2VyaWFsTnVtYmVyOiA1PGJyPgorICAgICAqIC0gaXNzdWVyOiBDTj1aPGJyPgorICAgICAqIC0gbm90QmVmb3JlOiAxMyBEZWMgMTk5OSAxNDoxNToxNjxicj4KKyAgICAgKiAtIG5vdEFmdGVyOiAwMSBKYW4gMjAwMCAwMDowMDowMDxicj4KKyAgICAgKiAtIHN1YmplY3Q6IENOPVk8YnI+CisgICAgICogLSBleHRlbnNpb25zOgorICAgICAqICAgICAgIDEpIEF1dGhvcml0eUtleUlkZW50aWZpZXIoT0lEPTIuNS4yOS4zNSk6IG5vIHZhbHVlcyBpbiBpdChlbXB0eSBzZXF1ZW5jZSkKKyAgICAgKgorICAgICAqIEByZXR1cm4gWC41MDkgY2VydGlmaWNhdGUgZW5jb2RpbmcgY29ycmVzcG9uZGluZyB0byB2ZXJzaW9uIHYzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIGdldFg1MDlDZXJ0aWZpY2F0ZV92MygpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBieXRlW10geworICAgICAgICAvLyBDZXJ0aWZpY2F0ZTogU0VRVUVOQ0UKKyAgICAgICAgICAgIDB4MzAsIDB4N0QsCisKKyAgICAgICAgICAgIC8vCisgICAgICAgICAgICAvLyBUQlNDZXJ0aWZpY2F0ZTogU0VRVUVOQ0UgeworICAgICAgICAgICAgLy8KKyAgICAgICAgICAgIDB4MzAsIDB4NkUsCisKKyAgICAgICAgICAgIC8vIHZlcnNpb246IFswXSBFWFBMSUNJVCBWZXJzaW9uIERFRkFVTFQgdjEKKyAgICAgICAgICAgIChieXRlKSAweEEwLCAweDAzLCAweDAyLCAweDAxLCAweDAyLAorCisgICAgICAgICAgICAvLyBzZXJpYWxOdW1iZXI6IENlcnRpZmljYXRlU2VyaWFsTnVtYmVyCisgICAgICAgICAgICAweDAyLCAweDAxLCAweDA1LAorCisgICAgICAgICAgICAvLyBzaWduYXR1cmU6IEFsZ29yaXRobUlkZW50aWZpZXIKKyAgICAgICAgICAgIDB4MzAsIDB4MDcsIC8vIFNFUVVFTkNFCisgICAgICAgICAgICAweDA2LCAweDAyLCAweDAzLCAweDA1LC8vT0lECisgICAgICAgICAgICAweDAxLCAweDAxLCAweDA3LCAvL0FOWQorCisgICAgICAgICAgICAvL2lzc3VlcjogTmFtZQorICAgICAgICAgICAgMHgzMCwgMHgwQywgMHgzMSwgMHgwQSwgMHgzMCwgMHgwOCwgMHgwNiwgMHgwMywgMHg1NSwgMHgwNCwgMHgwMywKKyAgICAgICAgICAgIDB4MTMsIDB4MDEsIDB4NUEsIC8vIENOPVoKKworICAgICAgICAgICAgLy92YWxpZGl0eTogVmFsaWRpdHkKKyAgICAgICAgICAgIDB4MzAsIDB4MUUsIC8vIFNFUVVFTkNFCisgICAgICAgICAgICAvLyBub3RCZWZvcmU6IFVUQ1RpbWUKKyAgICAgICAgICAgIDB4MTcsIDB4MEQsIDB4MzksIDB4MzksIDB4MzEsIDB4MzIsIDB4MzEsIDB4MzMsIDB4MzEsIDB4MzQsIDB4MzEsCisgICAgICAgICAgICAweDM1LCAweDMxLCAweDM2LCAweDVBLCAvLyAxMyBEZWMgMTk5OSAxNDoxNToxNgorICAgICAgICAgICAgLy8gbm90QWZ0ZXI6ICBVVENUaW1lCisgICAgICAgICAgICAweDE3LCAweDBELCAweDMwLCAweDMwLCAweDMwLCAweDMxLCAweDMwLCAweDMxLCAweDMwLCAweDMwLCAweDMwLAorICAgICAgICAgICAgMHgzMCwgMHgzMCwgMHgzMCwgMHg1QSwgLy8gMDEgSmFuIDIwMDAgMDA6MDA6MDAKKworICAgICAgICAgICAgLy9zdWJqZWN0OiBOYW1lCisgICAgICAgICAgICAweDMwLCAweDBDLCAweDMxLCAweDBBLCAweDMwLCAweDA4LCAweDA2LCAweDAzLCAweDU1LCAweDA0LCAweDAzLAorICAgICAgICAgICAgMHgxMywgMHgwMSwgMHg1OSwgLy8gQ049WQorICAgICAgICAgICAgLy9TdWJqZWN0UHVibGljS2V5SW5mbyAgOjo9ICBTRVFVRU5DRSAgeworICAgICAgICAgICAgLy8gICAgYWxnb3JpdGhtICAgICAgICAgICAgQWxnb3JpdGhtSWRlbnRpZmllciwKKyAgICAgICAgICAgIC8vICAgIHN1YmplY3RQdWJsaWNLZXkgICAgIEJJVCBTVFJJTkcgIH0KKyAgICAgICAgICAgIDB4MzAsIDB4MEQsIC8vIFNFUVVFTkNFCisgICAgICAgICAgICAweDMwLCAweDA3LCAvLyBTRVFVRU5DRQorICAgICAgICAgICAgMHgwNiwgMHgwMiwgMHgwMywgMHgwNSwvL09JRAorICAgICAgICAgICAgMHgwMSwgMHgwMSwgMHgwNywgLy9BTlkKKyAgICAgICAgICAgIDB4MDMsIDB4MDIsIDB4MDAsIDB4MDEsIC8vIHN1YmplY3RQdWJsaWNLZXkKKworICAgICAgICAgICAgLy8gaXNzdWVyVW5pcXVlSUQgLSBtaXNzZWQKKyAgICAgICAgICAgIC8vIHN1YmplY3RVbmlxdWVJRCAtIG1pc3NlZAorICAgICAgICAgICAgLy8gZXh0ZW5zaW9ucyA6IFszXSAgRVhQTElDSVQgRXh0ZW5zaW9ucyBPUFRJT05BTAorICAgICAgICAgICAgKGJ5dGUpIDB4QTMsIDB4MTAsCisgICAgICAgICAgICAvLyBFeHRlbnNpb25zICA6Oj0gIFNFUVVFTkNFIFNJWkUgKDEuLk1BWCkgT0YgRXh0ZW5zaW9uCisgICAgICAgICAgICAweDMwLCAweDBFLAorICAgICAgICAgICAgLy8gRXh0ZW5zaW9uICA6Oj0gIFNFUVVFTkNFICB7CisgICAgICAgICAgICAvLyBleHRuSUQgICAgICBPQkpFQ1QgSURFTlRJRklFUiwKKyAgICAgICAgICAgIC8vIGNyaXRpY2FsICAgIEJPT0xFQU4gREVGQVVMVCBGQUxTRSwKKyAgICAgICAgICAgIC8vIGV4dG5WYWx1ZSAgIE9DVEVUIFNUUklORyAgfQorCisgICAgICAgICAgICAvLyAxKSBBdXRob3JpdHlLZXlJZGVudGlmaWVyIGV4dGVuc2lvbiAoc2VlIEhBUk1PTlktMzM4NCkKKyAgICAgICAgICAgIDB4MzAsIDB4MEMsCisgICAgICAgICAgICAweDA2LCAweDAzLCAweDU1LCAweDFELCAweDIzLCAvLyBPSUQgPSAyLjUuMjkuMzUKKyAgICAgICAgICAgIDB4MDEsIDB4MDEsIDB4MDAsIC8vIGNyaXRpY2FsID0gRkFMU0UKKyAgICAgICAgICAgIDB4MDQsIDB4MDIsIDB4MzAsIDB4MDAsIC8vIGV4dG5WYWx1ZTogTVVTVCBiZSBlbXB0eSBzZXF1ZW5jZQorICAgICAgICAgICAgLy8gbWlzc2VkOiBrZXlJZGVudGlmaWVyCisgICAgICAgICAgICAvLyBtaXNzZWQ6IGF1dGhvcml0eUNlcnRJc3N1ZXIKKyAgICAgICAgICAgIC8vIG1pc3NlZCIgYXV0aG9yaXR5Q2VydFNlcmlhbE51bWJlcgorCisgICAgICAgICAgICAvLyB9IGVuZCBUQlNDZXJ0aWZpY2F0ZQorCisgICAgICAgICAgICAvLworICAgICAgICAgICAgLy8gc2lnbmF0dXJlQWxnb3JpdGhtOiBBbGdvcml0aG1JZGVudGlmaWVyCisgICAgICAgICAgICAvLworICAgICAgICAgICAgMHgzMCwgMHgwNywgLy8gU0VRVUVOQ0UKKyAgICAgICAgICAgIDB4MDYsIDB4MDIsIDB4MDMsIDB4MDUsLy9PSUQKKyAgICAgICAgICAgIDB4MDEsIDB4MDEsIDB4MDcsIC8vQU5ZCisKKyAgICAgICAgICAgIC8vCisgICAgICAgICAgICAvLyBzaWduYXR1cmU6IEJJVCBTVFJJTkcKKyAgICAgICAgICAgIC8vCisgICAgICAgICAgICAweDAzLCAweDAyLCAweDAwLCAweDAxIH07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBYLjUwOSBDUkwgZW5jb2RpbmcgY29ycmVzcG9uZGluZyB0byB2ZXJzaW9uIHYxLgorICAgICAqCisgICAgICogQ1JMIGVuY29kaW5nIHdhcyBjcmVhdGVkIGJ5IGhhbmRzIGFjY29yZGluZyB0byBYLjUwOSBDUkwgQVNOLjEKKyAgICAgKiBub3RhdGlvbi4gVGhlIENSTCBlbmNvZGluZyBoYXMgdGhlIGZvbGxvd2luZyBlbmNvZGVkIGZpZWxkIHZhbHVlczo8YnI+CisgICAgICogLSB2ZXJzaW9uOiAxPGJyPgorICAgICAqIC0gaXNzdWVyOiBDTj1aPGJyPgorICAgICAqIC0gdGhpc1VwZGF0ZTogMDEgSmFuIDIwMDEgMDE6MDI6MDM8YnI+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIFguNTA5IENSTCBlbmNvZGluZyBjb3JyZXNwb25kaW5nIHRvIHZlcnNpb24gdjEuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gZ2V0WDUwOUNSTF92MSgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBieXRlW10geworICAgICAgICAgICAgICAgIC8vQ2VydGlmaWNhdGVMaXN0OiBTRVFVRU5DRQorICAgICAgICAgICAgICAgIDB4MzAsIDB4MzUsCisKKyAgICAgICAgICAgICAgICAvLyBUQlNDZXJ0TGlzdDogU0VRVUVOQ0UKKyAgICAgICAgICAgICAgICAweDMwLCAweDI3LAorICAgICAgICAgICAgICAgIC8vIFZlcnNpb246IElOVEVHRVIgT1BUSU9OQUwKKyAgICAgICAgICAgICAgICAvLyAweDAyLCAweDAxLCAweDAxLCAtIG1pc3NlZCBoZXJlIGNhdXNlIGl0IGlzIHYxCisgICAgICAgICAgICAgICAgLy8gc2lnbmF0dXJlOiBBbGdvcml0aG1JZGVudGlmaWVyCisgICAgICAgICAgICAgICAgMHgzMCwgMHgwNiwgLy8gU0VRVUVOQ0UKKyAgICAgICAgICAgICAgICAweDA2LCAweDAxLCAweDAxLCAvLyBPSUQKKyAgICAgICAgICAgICAgICAweDAxLCAweDAxLCAweDExLCAvLyBBTlkKKyAgICAgICAgICAgICAgICAvLyBpc3N1ZXI6IE5hbWUKKyAgICAgICAgICAgICAgICAweDMwLCAweDBDLCAweDMxLCAweDBBLCAweDMwLCAweDA4LCAweDA2LCAweDAzLCAweDU1LCAweDA0LAorICAgICAgICAgICAgICAgIDB4MDMsIDB4MTMsIDB4MDEsIDB4NUEsIC8vIENOPVoKKyAgICAgICAgICAgICAgICAvLyB0aGlzVXBkYXRlOiBDaG9pY2VPZlRpbWUKKyAgICAgICAgICAgICAgICAvLyBHZW5lcmFsaXplZFRpbWU6IDAxIEphbiAyMDAxIDAxOjAyOjAzCisgICAgICAgICAgICAgICAgMHgxOCwgMHgwRiwgMHgzMiwgMHgzMCwgMHgzMCwgMHgzMSwgMHgzMCwgMHgzMSwgMHgzMCwgMHgzMSwKKyAgICAgICAgICAgICAgICAweDMwLCAweDMxLCAweDMwLCAweDMyLCAweDMwLCAweDMzLCAweDVBLAorCisgICAgICAgICAgICAgICAgLy8gbmV4dFVwZGF0ZSAtIG1pc3NlZAorICAgICAgICAgICAgICAgIC8vIHJldm9rZWRDZXJ0aWZpY2F0ZXMgLSBtaXNzZWQKKyAgICAgICAgICAgICAgICAvLyBjcmxFeHRlbnNpb25zIC0gbWlzc2VkCisKKyAgICAgICAgICAgICAgICAvLyBzaWduYXR1cmVBbGdvcml0aG06IEFsZ29yaXRobUlkZW50aWZpZXIKKyAgICAgICAgICAgICAgICAweDMwLCAweDA2LCAvLyBTRVFVRU5DRQorICAgICAgICAgICAgICAgIDB4MDYsIDB4MDEsIDB4MDEsIC8vT0lECisgICAgICAgICAgICAgICAgMHgwMSwgMHgwMSwgMHgxMSwgLy9BTlkKKyAgICAgICAgICAgICAgICAvLyBzaWduYXR1cmU6IEJJVCBTVFJJTkcKKyAgICAgICAgICAgICAgICAweDAzLCAweDAyLCAweDAwLCAweDAxIH07CisgICAgfQorICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIC8vIFNlY29uZCBleGFtcGxlCisgICAgLyoqCisgICAgICogQ2VydGlmaWNhdGU6CisgICAgICogPHByZT4KKyAgICAgKiAkIG9wZW5zc2wgcmVxIC14NTA5IC1ub2RlcyAtZGF5cyAzNjUgLXN1YmogJy9DPUFOL1NUPUFuZHJvaWQvTz1BbmRyb2lkL09VPUFuZHJvaWQvQ049QW5kcm9pZC9lbWFpbEFkZHJlc3M9YW5kcm9pZCcgLW5ld2tleSByc2E6MTAyNCAta2V5b3V0IHJvb3QucGVtIC1vdXQgcm9vdC5wZW0gLXRleHQgLWRheXMgMzY1MDAKKyAgICAgKiBHZW5lcmF0aW5nIGEgMTAyNCBiaXQgUlNBIHByaXZhdGUga2V5CisgICAgICogLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uKysrKysrCisgICAgICogLi4uLi4uLi4uLi4uLi4uLi4rKysrKysKKyAgICAgKiB3cml0aW5nIG5ldyBwcml2YXRlIGtleSB0byAncm9vdC5wZW0nCisgICAgICogLS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQorICAgICAqIE1JSUNYd0lCQUFLQmdRREtTK3FQMmtncVlCdHdZNFFvSjVwMHl5RWwzNXNCcjJaS3RBV242U0w0dlhndmFJcmoKKyAgICAgKiBLN3ZHOTNDdkcyMzliWGZhY25pR01FQml0ZWRCbGNxamRQUkVFWTBEUW4zakxYeUFPZDN0bmxLY3V0TkgzUmpBCisgICAgICogZlBsbkRXTkdLTG5EZFNkOVFaRWMwRzFNc01nL0hyRVJQbTFoTWZaUUc4NXpkdGJZbWkyQ0ovalM1d0lEQVFBQgorICAgICAqIEFvR0JBSVpodmRTSGpTN1JId2tlb25qR0xoMXRubng1T0kvN0F6bVdzcmNpOEw5SnBaL2drM3BxMzlkQkloTEEKKyAgICAgKiBadVZWcGF0d0pVNEdtWTY1QllFVXowS2IrM0pZMFBYYWd5cHdRS3VXczl3YjlDMGFSbkRWeTlETlhrYkorRCtMCisgICAgICogRE52eVpBRzVCTmtuWmFweHNGU2VuUjVVTzRCWTA4d0lzZEJ0V0QvQjdZY01UdXZ4QWtFQTl6S1AxOHBKQ21rdQorICAgICAqIFRVRFRKa29uRi9mR3ZJNFB2c0JtNllGeUlOYjEzMHlHektKS0NjRW41ajJGbSt3RitsR1k3bm10VUlnUWVrUm0KKyAgICAgKiBXa3diakcvdjN3SkJBTkdBQ2pLRlZJRnZ1WEg2RW95V3g5MHVZdzlDOCttMmpPdHJSYUFNZlJ5VWFuQ3ZGMkxpCisgICAgICogWllPTFRoUGN4di9RdnZRQWE3UktKanhzSzY5QWptK2IzZmtDUVFDUjd4V2dUVm1sZmNiSjhMVTI2NXY4dUZocAorICAgICAqIFJHempMZThUZDBvTFBSeFdRWFZySlh3VUdpWVY5TWdGN3Vid2ltK0FpZkRabEJvMk5GOUFlNkhmM00xOUFrRUEKKyAgICAgKiBuSkVHRGUrYTBnai9ISEQ1Zjl3SGpnTG13VGNXTm1uWk11OCtYM2cxNERBQ3hDZjJZRTQxODNNZWJMV29ldkkwCisgICAgICogWXdJVmUrMldXYjIxZ0FuTTZSZ2hjUUpCQUxxMFJaY1lrWm9RQThxcjlUUHV1TXppK2ZGM1krNG0vcEREY0NkNQorICAgICAqIHpYYnNyb0VaUGRXUGZBWEtUOTVqdVc5eUtkVnplT1pITzF1d1JXbVE5WmxQTWhZPQorICAgICAqIC0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCisgICAgICogLS0tLS0KKyAgICAgKiBDZXJ0aWZpY2F0ZToKKyAgICAgKiAgICAgRGF0YToKKyAgICAgKiAgICAgICAgIFZlcnNpb246IDMgKDB4MikKKyAgICAgKiAgICAgICAgIFNlcmlhbCBOdW1iZXI6CisgICAgICogICAgICAgICAgICAgOGE6MTI6Mzc6ZWQ6MmQ6YWQ6MDI6NmUKKyAgICAgKiAgICAgICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAqICAgICAgICAgSXNzdWVyOiBDPUFOLCBTVD1BbmRyb2lkLCBPPUFuZHJvaWQsIE9VPUFuZHJvaWQsIENOPUFuZHJvaWQvZW1haWxBZGRyZXNzPWFuZHJvaWQKKyAgICAgKiAgICAgICAgIFZhbGlkaXR5CisgICAgICogICAgICAgICAgICAgTm90IEJlZm9yZTogT2N0ICA0IDAyOjIwOjI4IDIwMTAgR01UCisgICAgICogICAgICAgICAgICAgTm90IEFmdGVyIDogU2VwIDEwIDAyOjIwOjI4IDIxMTAgR01UCisgICAgICogICAgICAgICBTdWJqZWN0OiBDPUFOLCBTVD1BbmRyb2lkLCBPPUFuZHJvaWQsIE9VPUFuZHJvaWQsIENOPUFuZHJvaWQvZW1haWxBZGRyZXNzPWFuZHJvaWQKKyAgICAgKiAgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAqICAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICogICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgxMDI0IGJpdCkKKyAgICAgKiAgICAgICAgICAgICAgICAgTW9kdWx1cyAoMTAyNCBiaXQpOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgMDA6Y2E6NGI6ZWE6OGY6ZGE6NDg6MmE6NjA6MWI6NzA6NjM6ODQ6Mjg6Mjc6CisgICAgICogICAgICAgICAgICAgICAgICAgICA5YTo3NDpjYjoyMToyNTpkZjo5YjowMTphZjo2Njo0YTpiNDowNTphNzplOToKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIDIyOmY4OmJkOjc4OjJmOjY4OjhhOmUzOjJiOmJiOmM2OmY3OjcwOmFmOjFiOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgNmQ6ZmQ6NmQ6Nzc6ZGE6NzI6Nzg6ODY6MzA6NDA6NjI6YjU6ZTc6NDE6OTU6CisgICAgICogICAgICAgICAgICAgICAgICAgICBjYTphMzo3NDpmNDo0NDoxMTo4ZDowMzo0Mjo3ZDplMzoyZDo3Yzo4MDozOToKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGRkOmVkOjllOjUyOjljOmJhOmQzOjQ3OmRkOjE4OmMwOjdjOmY5OjY3OjBkOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgNjM6NDY6Mjg6Yjk6YzM6NzU6Mjc6N2Q6NDE6OTE6MWM6ZDA6NmQ6NGM6YjA6CisgICAgICogICAgICAgICAgICAgICAgICAgICBjODozZjoxZTpiMToxMTozZTo2ZDo2MTozMTpmNjo1MDoxYjpjZTo3Mzo3NjoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGQ2OmQ4OjlhOjJkOjgyOjI3OmY4OmQyOmU3CisgICAgICogICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgKiAgICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgorICAgICAqICAgICAgICAgICAgIFg1MDl2MyBTdWJqZWN0IEtleSBJZGVudGlmaWVyOgorICAgICAqICAgICAgICAgICAgICAgICAxNDo3RDozNjpFRDo2Mzo0NDpCRjo0RjpEQjo3RDoyODo5Njo3ODo2QTpFNzpFQzpDRToyQzo0MDpCRgorICAgICAqICAgICAgICAgICAgIFg1MDl2MyBBdXRob3JpdHkgS2V5IElkZW50aWZpZXI6CisgICAgICogICAgICAgICAgICAgICAgIGtleWlkOjE0OjdEOjM2OkVEOjYzOjQ0OkJGOjRGOkRCOjdEOjI4Ojk2Ojc4OjZBOkU3OkVDOkNFOjJDOjQwOkJGCisgICAgICogICAgICAgICAgICAgICAgIERpck5hbWU6L0M9QU4vU1Q9QW5kcm9pZC9PPUFuZHJvaWQvT1U9QW5kcm9pZC9DTj1BbmRyb2lkL2VtYWlsQWRkcmVzcz1hbmRyb2lkCisgICAgICogICAgICAgICAgICAgICAgIHNlcmlhbDo4QToxMjozNzpFRDoyRDpBRDowMjo2RQorICAgICAqCisgICAgICogICAgICAgICAgICAgWDUwOXYzIEJhc2ljIENvbnN0cmFpbnRzOgorICAgICAqICAgICAgICAgICAgICAgICBDQTpUUlVFCisgICAgICogICAgIFNpZ25hdHVyZSBBbGdvcml0aG06IHNoYTFXaXRoUlNBRW5jcnlwdGlvbgorICAgICAqICAgICAgICAgN2M6ZjI6ODQ6YzA6ZWU6NDA6YTU6Yjk6OTQ6ODU6MTk6YWI6MzY6MDI6MWQ6MTc6NGI6OTg6CisgICAgICogICAgICAgICBmOTpiOTpjODpjNToxYTpiMDpjMTo0ZjowZjoxZDoxYzplODpjNDpjZjpjNzo4Nzo1MjoxOToKKyAgICAgKiAgICAgICAgIDllOjY0OjU1OjM1OmJiOjM0OmUxOjM4OjJmOjI3OjA4OmM1OmNhOmU3Ojk3OjAyOjkwOmZkOgorICAgICAqICAgICAgICAgMjc6Y2Q6OGU6NWE6MDg6NDA6ZjU6MzQ6ZmY6NzA6NjU6YzQ6ZDY6MWY6NzA6NGY6ZDY6MmM6CisgICAgICogICAgICAgICBjYjoyODpkODplZDo5MTpiNzplYjozNTowNjpjZDowZTowMjphODo1MTpjZDpiNzozZTpmOToKKyAgICAgKiAgICAgICAgIDg1OjE2Ojk3OjMxOjdiOjQyOjRjOmNiOjZmOmRlOjRiOmRkOmFlOjVlOjlkOmVmOjg0OjgzOgorICAgICAqICAgICAgICAgODk6Zjk6MGY6YTY6NWY6ZTQ6OTM6Y2M6MzA6YjU6ZTk6MWQ6ZjQ6MDg6ZjQ6ZTY6ZTk6NTg6CisgICAgICogICAgICAgICA0YjpiYQorICAgICAqIC0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQorICAgICAqIE1JSURMVENDQXBhZ0F3SUJBZ0lKQUlvU04rMHRyUUp1TUEwR0NTcUdTSWIzRFFFQkJRVUFNRzB4Q3pBSkJnTlYKKyAgICAgKiBCQVlUQWtGT01SQXdEZ1lEVlFRSUV3ZEJibVJ5YjJsa01SQXdEZ1lEVlFRS0V3ZEJibVJ5YjJsa01SQXdEZ1lECisgICAgICogVlFRTEV3ZEJibVJ5YjJsa01SQXdEZ1lEVlFRREV3ZEJibVJ5YjJsa01SWXdGQVlKS29aSWh2Y05BUWtCRmdkaAorICAgICAqIGJtUnliMmxrTUNBWERURXdNVEF3TkRBeU1qQXlPRm9ZRHpJeE1UQXdPVEV3TURJeU1ESTRXakJ0TVFzd0NRWUQKKyAgICAgKiBWUVFHRXdKQlRqRVFNQTRHQTFVRUNCTUhRVzVrY205cFpERVFNQTRHQTFVRUNoTUhRVzVrY205cFpERVFNQTRHCisgICAgICogQTFVRUN4TUhRVzVrY205cFpERVFNQTRHQTFVRUF4TUhRVzVrY205cFpERVdNQlFHQ1NxR1NJYjNEUUVKQVJZSAorICAgICAqIFlXNWtjbTlwWkRDQm56QU5CZ2txaGtpRzl3MEJBUUVGQUFPQmpRQXdnWWtDZ1lFQXlrdnFqOXBJS21BYmNHT0UKKyAgICAgKiBLQ2VhZE1zaEpkK2JBYTltU3JRRnAra2krTDE0TDJpSzR5dTd4dmR3cnh0dC9XMTMybko0aGpCQVlyWG5RWlhLCisgICAgICogbzNUMFJCR05BMEo5NHkxOGdEbmQ3WjVTbkxyVFI5MFl3SHo1WncxalJpaTV3M1VuZlVHUkhOQnRUTERJUHg2eAorICAgICAqIEVUNXRZVEgyVUJ2T2MzYlcySm90Z2lmNDB1Y0NBd0VBQWFPQjBqQ0J6ekFkQmdOVkhRNEVGZ1FVRkgwMjdXTkUKKyAgICAgKiB2MC9iZlNpV2VHcm43TTRzUUw4d2daOEdBMVVkSXdTQmx6Q0JsSUFVRkgwMjdXTkV2MC9iZlNpV2VHcm43TTRzCisgICAgICogUUwraGNhUnZNRzB4Q3pBSkJnTlZCQVlUQWtGT01SQXdEZ1lEVlFRSUV3ZEJibVJ5YjJsa01SQXdEZ1lEVlFRSworICAgICAqIEV3ZEJibVJ5YjJsa01SQXdEZ1lEVlFRTEV3ZEJibVJ5YjJsa01SQXdEZ1lEVlFRREV3ZEJibVJ5YjJsa01SWXcKKyAgICAgKiBGQVlKS29aSWh2Y05BUWtCRmdkaGJtUnliMmxrZ2drQWloSTM3UzJ0QW00d0RBWURWUjBUQkFVd0F3RUIvekFOCisgICAgICogQmdrcWhraUc5dzBCQVFVRkFBT0JnUUI4OG9UQTdrQ2x1WlNGR2FzMkFoMFhTNWo1dWNqRkdyREJUdzhkSE9qRQorICAgICAqIHo4ZUhVaG1lWkZVMXV6VGhPQzhuQ01YSzU1Y0NrUDBuelk1YUNFRDFOUDl3WmNUV0gzQlAxaXpMS05qdGtiZnIKKyAgICAgKiBOUWJORGdLb1VjMjNQdm1GRnBjeGUwSk15Mi9lUzkydVhwM3ZoSU9KK1ErbVgrU1R6REMxNlIzMENQVG02VmhMCisgICAgICogdWc9PQorICAgICAqIC0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KKyAgICAgKiAkCisgICAgICogPC9wcmU+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgcm9vdENlcnQgPSAiIgorICAgICAgICAgICAgKyAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICAgICArICJNSUlETFRDQ0FwYWdBd0lCQWdJSkFJb1NOKzB0clFKdU1BMEdDU3FHU0liM0RRRUJCUVVBTUcweEN6QUpCZ05WXG4iCisgICAgICAgICAgICArICJCQVlUQWtGT01SQXdEZ1lEVlFRSUV3ZEJibVJ5YjJsa01SQXdEZ1lEVlFRS0V3ZEJibVJ5YjJsa01SQXdEZ1lEXG4iCisgICAgICAgICAgICArICJWUVFMRXdkQmJtUnliMmxrTVJBd0RnWURWUVFERXdkQmJtUnliMmxrTVJZd0ZBWUpLb1pJaHZjTkFRa0JGZ2RoXG4iCisgICAgICAgICAgICArICJibVJ5YjJsa01DQVhEVEV3TVRBd05EQXlNakF5T0ZvWUR6SXhNVEF3T1RFd01ESXlNREk0V2pCdE1Rc3dDUVlEXG4iCisgICAgICAgICAgICArICJWUVFHRXdKQlRqRVFNQTRHQTFVRUNCTUhRVzVrY205cFpERVFNQTRHQTFVRUNoTUhRVzVrY205cFpERVFNQTRHXG4iCisgICAgICAgICAgICArICJBMVVFQ3hNSFFXNWtjbTlwWkRFUU1BNEdBMVVFQXhNSFFXNWtjbTlwWkRFV01CUUdDU3FHU0liM0RRRUpBUllIXG4iCisgICAgICAgICAgICArICJZVzVrY205cFpEQ0JuekFOQmdrcWhraUc5dzBCQVFFRkFBT0JqUUF3Z1lrQ2dZRUF5a3ZxajlwSUttQWJjR09FXG4iCisgICAgICAgICAgICArICJLQ2VhZE1zaEpkK2JBYTltU3JRRnAra2krTDE0TDJpSzR5dTd4dmR3cnh0dC9XMTMybko0aGpCQVlyWG5RWlhLXG4iCisgICAgICAgICAgICArICJvM1QwUkJHTkEwSjk0eTE4Z0RuZDdaNVNuTHJUUjkwWXdIejVadzFqUmlpNXczVW5mVUdSSE5CdFRMRElQeDZ4XG4iCisgICAgICAgICAgICArICJFVDV0WVRIMlVCdk9jM2JXMkpvdGdpZjQwdWNDQXdFQUFhT0IwakNCenpBZEJnTlZIUTRFRmdRVUZIMDI3V05FXG4iCisgICAgICAgICAgICArICJ2MC9iZlNpV2VHcm43TTRzUUw4d2daOEdBMVVkSXdTQmx6Q0JsSUFVRkgwMjdXTkV2MC9iZlNpV2VHcm43TTRzXG4iCisgICAgICAgICAgICArICJRTCtoY2FSdk1HMHhDekFKQmdOVkJBWVRBa0ZPTVJBd0RnWURWUVFJRXdkQmJtUnliMmxrTVJBd0RnWURWUVFLXG4iCisgICAgICAgICAgICArICJFd2RCYm1SeWIybGtNUkF3RGdZRFZRUUxFd2RCYm1SeWIybGtNUkF3RGdZRFZRUURFd2RCYm1SeWIybGtNUll3XG4iCisgICAgICAgICAgICArICJGQVlKS29aSWh2Y05BUWtCRmdkaGJtUnliMmxrZ2drQWloSTM3UzJ0QW00d0RBWURWUjBUQkFVd0F3RUIvekFOXG4iCisgICAgICAgICAgICArICJCZ2txaGtpRzl3MEJBUVVGQUFPQmdRQjg4b1RBN2tDbHVaU0ZHYXMyQWgwWFM1ajV1Y2pGR3JEQlR3OGRIT2pFXG4iCisgICAgICAgICAgICArICJ6OGVIVWhtZVpGVTF1elRoT0M4bkNNWEs1NWNDa1AwbnpZNWFDRUQxTlA5d1pjVFdIM0JQMWl6TEtOanRrYmZyXG4iCisgICAgICAgICAgICArICJOUWJORGdLb1VjMjNQdm1GRnBjeGUwSk15Mi9lUzkydVhwM3ZoSU9KK1ErbVgrU1R6REMxNlIzMENQVG02VmhMXG4iCisgICAgICAgICAgICArICJ1Zz09XG4iCisgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iOworCisgICAgLyoqCisgICAgICogQ2VydGlmaWNhdGU6CisgICAgICogPHByZT4KKyAgICAgKiAkIG9wZW5zc2wgcmVxIC1ub2RlcyAtZGF5cyAzNjUgLXN1YmogJy9DPUFOL1NUPUFuZHJvaWQvTD1BbmRyb2lkL089QW5kcm9pZC9PVT1BbmRyb2lkL0NOPUFuZHJvaWQgQ2VydGlmaWNhdGUvZW1haWxBZGRyZXNzPWFuZHJvaWQnIC1uZXdrZXkgcnNhOjEwMjQgLWtleW91dCBjZXJ0cmVxLnBlbSAtb3V0IGNlcnRyZXEucGVtIC10ZXh0IC1kYXlzIDM2NTAwCisgICAgICogR2VuZXJhdGluZyBhIDEwMjQgYml0IFJTQSBwcml2YXRlIGtleQorICAgICAqIC4uLi4uLi4rKysrKysKKyAgICAgKiAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uKysrKysrCisgICAgICogd3JpdGluZyBuZXcgcHJpdmF0ZSBrZXkgdG8gJ2NlcnRyZXEucGVtJworICAgICAqIC0tLS0tCisgICAgICogJCBvcGVuc3NsIHg1MDkgLXJlcSAtaW4gY2VydHJlcS5wZW0gLUNBIHJvb3QucGVtIC1DQWNyZWF0ZXNlcmlhbCAtb3V0IGNlcnQucGVtIC1kYXlzIDM2NTAwCisgICAgICogU2lnbmF0dXJlIG9rCisgICAgICogc3ViamVjdD0vQz1BTi9TVD1BbmRyb2lkL0w9QW5kcm9pZC9PPUFuZHJvaWQvT1U9QW5kcm9pZC9DTj1BbmRyb2lkIENlcnRpZmljYXRlL2VtYWlsQWRkcmVzcz1hbmRyb2lkCisgICAgICogR2V0dGluZyBQcml2YXRlIGtleQorICAgICAqICQgcm0gcm9vdC5zcmwKKyAgICAgKiAkIG9wZW5zc2wgcnNhIC1pbiBjZXJ0cmVxLnBlbQorICAgICAqIHdyaXRpbmcgUlNBIGtleQorICAgICAqIC0tLS0tQkVHSU4gUlNBIFBSSVZBVEUgS0VZLS0tLS0KKyAgICAgKiBNSUlDWFFJQkFBS0JnUURHdlFaUkI3ZnN1THZuWjBTeDQzc1RDa3Z3di9TRVlyelJ1bXlWMTZPQytsdktHQzJYCisgICAgICogbFlXOXF2N29mODhocVNWcTU4MjNNQit1RVAxeFpMV2FpS2tZeUVuNzJSd2dWL0hxQjhLRWdHWVhFYk1LS3pVdgorICAgICAqIGowRDFYOGtaL0VER3FzWmpGS2xrLzdzWlljZzNVcUNjR1VpRUVzelRhZGh5SjZGY293SE0xRWhyY1FJREFRQUIKKyAgICAgKiBBb0dBUzRDUW44UXc2ZXdjNXdMaXBEcHFEWWZCNWdybkdFeHlzN01CZ2NQVXlQUFlYMlRrSFV5ZTdMbkQ4Z3hzCisgICAgICogWXJ0aURjVlc4QnVHVFprQzBFdVVlc3NrZ2l3R0xpbU5pVTN2VTNMd0g3T3Z0ZlVUTWR2aHY5bmQyR0ZsZmlRbworICAgICAqIFBmd2hJVFo4NUd3aERraGlCQlhqVG9EY05jMG50WFZnQUNOQUtVMVpsSnlveXVrQ1FRRHdzR21EMEd3S0Z0SkgKKyAgICAgKiBjR1hJK0lLMGFCK3BYanVqWkpVL0lrZytlVFBNU1dEc0tENlJlWnU5dUpKYzhXMzZYaWtpL05vMS9OWnZqMGdCCisgICAgICogTXdnSWt3aDdBa0VBMDJGemFHY1dMRlNIYVJmVjF3cHgxRjNJdXUzWDJ3V3FUekJsaEdHOVpEUXl5N2dXWnFISgorICAgICAqIGpFbENkYWppTW5iaDBtazYyaG9iWXk0RmNMdXZra0pXQXdKQkFLN0ZLcGtRYXFNWTF6QVFxWmc0KzQvTVc5RTgKKyAgICAgKiBIOG9SYTE0Z29wemFuWVlsY2orSktZV3c3Q25qTUVSVSt5cmwzTEVQTWRRcDkvdWg2d01UN3kxcXRxa0NRQ05HCisgICAgICogbXhUc1J6WUVzVWhua3VjOU5mdmozdERiU20raHhXZEx3MVZSWG1Mdmx4NktUU3E1aTBJZkk3a3hBdmE3QWpxMAorICAgICAqIEZ2ODQ1aU1xRmZ4WFJoaVplM01DUVFDeEQwdkx6RUJlZ0xRUGdpYXZHWGZCblJQclJyWGdrdUFKZzdGcS8xVnQKKyAgICAgKiAzSW5TR2F0M1R2OEdXK3BDV1dWZ21WOGlRNHdXUmVnK0JkMDNTQ1NQNXVBWQorICAgICAqIC0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCisgICAgICogJCBvcGVuc3NsIHg1MDkgLWluIGNlcnQucGVtIC10ZXh0CisgICAgICogQ2VydGlmaWNhdGU6CisgICAgICogICAgIERhdGE6CisgICAgICogICAgICAgICBWZXJzaW9uOiAxICgweDApCisgICAgICogICAgICAgICBTZXJpYWwgTnVtYmVyOgorICAgICAqICAgICAgICAgICAgIDg5OjM0OjVmOmQ1OjAxOjJlOmEyOjJiCisgICAgICogICAgICAgICBTaWduYXR1cmUgQWxnb3JpdGhtOiBzaGExV2l0aFJTQUVuY3J5cHRpb24KKyAgICAgKiAgICAgICAgIElzc3VlcjogQz1BTiwgU1Q9QW5kcm9pZCwgTz1BbmRyb2lkLCBPVT1BbmRyb2lkLCBDTj1BbmRyb2lkL2VtYWlsQWRkcmVzcz1hbmRyb2lkCisgICAgICogICAgICAgICBWYWxpZGl0eQorICAgICAqICAgICAgICAgICAgIE5vdCBCZWZvcmU6IE9jdCAgNCAwNDo0MTo1NCAyMDEwIEdNVAorICAgICAqICAgICAgICAgICAgIE5vdCBBZnRlciA6IFNlcCAxMCAwNDo0MTo1NCAyMTEwIEdNVAorICAgICAqICAgICAgICAgU3ViamVjdDogQz1BTiwgU1Q9QW5kcm9pZCwgTD1BbmRyb2lkLCBPPUFuZHJvaWQsIE9VPUFuZHJvaWQsIENOPUFuZHJvaWQgQ2VydGlmaWNhdGUvZW1haWxBZGRyZXNzPWFuZHJvaWQKKyAgICAgKiAgICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgorICAgICAqICAgICAgICAgICAgIFB1YmxpYyBLZXkgQWxnb3JpdGhtOiByc2FFbmNyeXB0aW9uCisgICAgICogICAgICAgICAgICAgUlNBIFB1YmxpYyBLZXk6ICgxMDI0IGJpdCkKKyAgICAgKiAgICAgICAgICAgICAgICAgTW9kdWx1cyAoMTAyNCBiaXQpOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgMDA6YzY6YmQ6MDY6NTE6MDc6Yjc6ZWM6Yjg6YmI6ZTc6Njc6NDQ6YjE6ZTM6CisgICAgICogICAgICAgICAgICAgICAgICAgICA3YjoxMzowYTo0YjpmMDpiZjpmNDo4NDo2MjpiYzpkMTpiYTo2Yzo5NTpkNzoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGEzOjgyOmZhOjViOmNhOjE4OjJkOjk3Ojk1Ojg1OmJkOmFhOmZlOmU4OjdmOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgY2Y6MjE6YTk6MjU6NmE6ZTc6Y2Q6Yjc6MzA6MWY6YWU6MTA6ZmQ6NzE6NjQ6CisgICAgICogICAgICAgICAgICAgICAgICAgICBiNTo5YTo4ODphOToxODpjODo0OTpmYjpkOToxYzoyMDo1NzpmMTplYTowNzoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGMyOjg0OjgwOjY2OjE3OjExOmIzOjBhOjJiOjM1OjJmOjhmOjQwOmY1OjVmOgorICAgICAqICAgICAgICAgICAgICAgICAgICAgYzk6MTk6ZmM6NDA6YzY6YWE6YzY6NjM6MTQ6YTk6NjQ6ZmY6YmI6MTk6NjE6CisgICAgICogICAgICAgICAgICAgICAgICAgICBjODozNzo1MjphMDo5YzoxOTo0ODo4NDoxMjpjYzpkMzo2OTpkODo3MjoyNzoKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgIGExOjVjOmEzOjAxOmNjOmQ0OjQ4OjZiOjcxCisgICAgICogICAgICAgICAgICAgICAgIEV4cG9uZW50OiA2NTUzNyAoMHgxMDAwMSkKKyAgICAgKiAgICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMVdpdGhSU0FFbmNyeXB0aW9uCisgICAgICogICAgICAgICA4MDowNjo1NDpiYTo0YzphMjowZDoyZTo2YjpkNTpiMDpiMTo4OTpiMjpmYTpjMjpmZDpkNjoKKyAgICAgKiAgICAgICAgIDAyOmFiOjc0OmFmOmZiOjFjOmJjOjQ3OjQzOjU4Ojg5OjU3OjgwOmFkOjU5Ojc5OmU5OjJlOgorICAgICAqICAgICAgICAgZDk6NjA6YTc6YTY6MGY6OWM6MTA6OWY6ZTE6ODA6YTE6NjY6MTk6NTk6N2U6MTE6Mjg6MTc6CisgICAgICogICAgICAgICAxNzowYToxZDplOTo4ZDo3ODplODpjMjo2MTozNjowMzpmYzo0MjpiMTo1NDpiZDoyODozOToKKyAgICAgKiAgICAgICAgIDNjOjQ4OmZkOjNjOjc5OmU3OmNhOjFhOjE2OmMzOjhhOjc3OjQyOjA3Ojk2OjE0OjhjOmQyOgorICAgICAqICAgICAgICAgNTE6Y2E6OGU6ZGI6Yjg6ODI6MzE6ODQ6NWU6M2Y6Njg6YjE6YTU6ZjA6OTY6YWU6YTk6Y2E6CisgICAgICogICAgICAgICA4NjpmMzowMTo3Njo2Mzo5ODo2NTpkZDo0MTo4MToxMTpkNzo3MTpjODphZToxNzpjNzoyMDoKKyAgICAgKiAgICAgICAgIGU3OjIyCisgICAgICogLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCisgICAgICogTUlJQ2NqQ0NBZHNDQ1FDSk5GL1ZBUzZpS3pBTkJna3Foa2lHOXcwQkFRVUZBREJ0TVFzd0NRWURWUVFHRXdKQgorICAgICAqIFRqRVFNQTRHQTFVRUNCTUhRVzVrY205cFpERVFNQTRHQTFVRUNoTUhRVzVrY205cFpERVFNQTRHQTFVRUN4TUgKKyAgICAgKiBRVzVrY205cFpERVFNQTRHQTFVRUF4TUhRVzVrY205cFpERVdNQlFHQ1NxR1NJYjNEUUVKQVJZSFlXNWtjbTlwCisgICAgICogWkRBZ0Z3MHhNREV3TURRd05EUXhOVFJhR0E4eU1URXdNRGt4TURBME5ERTFORm93Z1lzeEN6QUpCZ05WQkFZVAorICAgICAqIEFrRk9NUkF3RGdZRFZRUUlFd2RCYm1SeWIybGtNUkF3RGdZRFZRUUhFd2RCYm1SeWIybGtNUkF3RGdZRFZRUUsKKyAgICAgKiBFd2RCYm1SeWIybGtNUkF3RGdZRFZRUUxFd2RCYm1SeWIybGtNUnd3R2dZRFZRUURFeE5CYm1SeWIybGtJRU5sCisgICAgICogY25ScFptbGpZWFJsTVJZd0ZBWUpLb1pJaHZjTkFRa0JGZ2RoYm1SeWIybGtNSUdmTUEwR0NTcUdTSWIzRFFFQgorICAgICAqIEFRVUFBNEdOQURDQmlRS0JnUURHdlFaUkI3ZnN1THZuWjBTeDQzc1RDa3Z3di9TRVlyelJ1bXlWMTZPQytsdksKKyAgICAgKiBHQzJYbFlXOXF2N29mODhocVNWcTU4MjNNQit1RVAxeFpMV2FpS2tZeUVuNzJSd2dWL0hxQjhLRWdHWVhFYk1LCisgICAgICogS3pVdmowRDFYOGtaL0VER3FzWmpGS2xrLzdzWlljZzNVcUNjR1VpRUVzelRhZGh5SjZGY293SE0xRWhyY1FJRAorICAgICAqIEFRQUJNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0R0JBSUFHVkxwTW9nMHVhOVd3c1lteStzTDkxZ0tyZEsvN0hMeEgKKyAgICAgKiBRMWlKVjRDdFdYbnBMdGxncDZZUG5CQ2Y0WUNoWmhsWmZoRW9GeGNLSGVtTmVPakNZVFlEL0VLeFZMMG9PVHhJCisgICAgICogL1R4NTU4b2FGc09LZDBJSGxoU00wbEhLanR1NGdqR0VYajlvc2FYd2xxNnB5b2J6QVhaam1HWGRRWUVSMTNISQorICAgICAqIHJoZkhJT2NpCisgICAgICogLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQorICAgICAqICQKKyAgICAgKiA8L3ByZT4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgZW5kQ2VydCA9ICIiCisgICAgICAgICAgICArICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICsgIk1JSUNjakNDQWRzQ0NRQ0pORi9WQVM2aUt6QU5CZ2txaGtpRzl3MEJBUVVGQURCdE1Rc3dDUVlEVlFRR0V3SkJcbiIKKyAgICAgICAgICAgICsgIlRqRVFNQTRHQTFVRUNCTUhRVzVrY205cFpERVFNQTRHQTFVRUNoTUhRVzVrY205cFpERVFNQTRHQTFVRUN4TUhcbiIKKyAgICAgICAgICAgICsgIlFXNWtjbTlwWkRFUU1BNEdBMVVFQXhNSFFXNWtjbTlwWkRFV01CUUdDU3FHU0liM0RRRUpBUllIWVc1a2NtOXBcbiIKKyAgICAgICAgICAgICsgIlpEQWdGdzB4TURFd01EUXdORFF4TlRSYUdBOHlNVEV3TURreE1EQTBOREUxTkZvd2dZc3hDekFKQmdOVkJBWVRcbiIKKyAgICAgICAgICAgICsgIkFrRk9NUkF3RGdZRFZRUUlFd2RCYm1SeWIybGtNUkF3RGdZRFZRUUhFd2RCYm1SeWIybGtNUkF3RGdZRFZRUUtcbiIKKyAgICAgICAgICAgICsgIkV3ZEJibVJ5YjJsa01SQXdEZ1lEVlFRTEV3ZEJibVJ5YjJsa01Sd3dHZ1lEVlFRREV4TkJibVJ5YjJsa0lFTmxcbiIKKyAgICAgICAgICAgICsgImNuUnBabWxqWVhSbE1SWXdGQVlKS29aSWh2Y05BUWtCRmdkaGJtUnliMmxrTUlHZk1BMEdDU3FHU0liM0RRRUJcbiIKKyAgICAgICAgICAgICsgIkFRVUFBNEdOQURDQmlRS0JnUURHdlFaUkI3ZnN1THZuWjBTeDQzc1RDa3Z3di9TRVlyelJ1bXlWMTZPQytsdktcbiIKKyAgICAgICAgICAgICsgIkdDMlhsWVc5cXY3b2Y4OGhxU1ZxNTgyM01CK3VFUDF4WkxXYWlLa1l5RW43MlJ3Z1YvSHFCOEtFZ0dZWEViTUtcbiIKKyAgICAgICAgICAgICsgIkt6VXZqMEQxWDhrWi9FREdxc1pqRktsay83c1pZY2czVXFDY0dVaUVFc3pUYWRoeUo2RmNvd0hNMUVocmNRSURcbiIKKyAgICAgICAgICAgICsgIkFRQUJNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0R0JBSUFHVkxwTW9nMHVhOVd3c1lteStzTDkxZ0tyZEsvN0hMeEhcbiIKKyAgICAgICAgICAgICsgIlExaUpWNEN0V1hucEx0bGdwNllQbkJDZjRZQ2haaGxaZmhFb0Z4Y0tIZW1OZU9qQ1lUWUQvRUt4Vkwwb09UeElcbiIKKyAgICAgICAgICAgICsgIi9UeDU1OG9hRnNPS2QwSUhsaFNNMGxIS2p0dTRnakdFWGo5b3NhWHdscTZweW9iekFYWmptR1hkUVlFUjEzSElcbiIKKyAgICAgICAgICAgICsgInJoZkhJT2NpXG4iCisgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iOworCisgICAgLyoqCisgICAgICogYSBzZWxmIHNpZ25lZCBjZXJ0aWZpY2F0ZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgWDUwOUNlcnRpZmljYXRlIHJvb3RDZXJ0aWZpY2F0ZVNTOworCisgICAgcHVibGljIHN0YXRpYyBYNTA5Q2VydGlmaWNhdGUgZW5kQ2VydGlmaWNhdGU7CisKKyAgICBwdWJsaWMgc3RhdGljIE15Q1JMIGNybDsKKworICAgIHB1YmxpYyBzdGF0aWMgWDUwOUNlcnRTZWxlY3RvciB0aGVDZXJ0U2VsZWN0b3I7CisKKyAgICBwdWJsaWMgc3RhdGljIENlcnRQYXRoQnVpbGRlciBidWlsZGVyOworICAgIHByaXZhdGUgc3RhdGljIENlcnRTdG9yZSBzdG9yZTsKKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBpbml0Q2VydFBhdGhTU0NlcnRDaGFpbigpIHRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gY3JlYXRlIGNlcnRpZmljYXRlcyBhbmQgQ1JMcworICAgICAgICBDZXJ0aWZpY2F0ZUZhY3RvcnkgY2YgPSBDZXJ0aWZpY2F0ZUZhY3RvcnkuZ2V0SW5zdGFuY2UoIlguNTA5Iik7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJpID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHJvb3RDZXJ0LmdldEJ5dGVzKCkpOworICAgICAgICByb290Q2VydGlmaWNhdGVTUyA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoYmkpOworICAgICAgICBiaSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShlbmRDZXJ0LmdldEJ5dGVzKCkpOworICAgICAgICBlbmRDZXJ0aWZpY2F0ZSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoYmkpOworICAgICAgICBCaWdJbnRlZ2VyIHJldm9rZWRTZXJpYWxOdW1iZXIgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoMSk7CisgICAgICAgIGNybCA9IG5ldyBNeUNSTCgiWC41MDkiKTsKKy8vICAgICAgICBYNTA5Q1JMIHJvb3RDUkwgPSBYNTA5Q1JMOworLy8gICAgICAgIFg1MDlDUkwgaW50ZXJDUkwgPSBYNTA5Q1JMRXhhbXBsZS5jcmVhdGVDUkwoaW50ZXJDZXJ0LCBpbnRlclBhaXIKKy8vICAgICAgICAgICAgICAgIC5nZXRQcml2YXRlKCksIHJldm9rZWRTZXJpYWxOdW1iZXIpOworCisgICAgICAgIC8vIGNyZWF0ZSBDZXJ0U3RvcmUgdG8gc3VwcG9ydCBwYXRoIGJ1aWxkaW5nCisgICAgICAgIExpc3Q8T2JqZWN0PiBsaXN0ID0gbmV3IEFycmF5TGlzdDxPYmplY3Q+KCk7CisKKyAgICAgICAgbGlzdC5hZGQocm9vdENlcnRpZmljYXRlU1MpOworICAgICAgICBsaXN0LmFkZChlbmRDZXJ0aWZpY2F0ZSk7CisKKyAgICAgICAgQ29sbGVjdGlvbkNlcnRTdG9yZVBhcmFtZXRlcnMgcGFyYW1zID0gbmV3IENvbGxlY3Rpb25DZXJ0U3RvcmVQYXJhbWV0ZXJzKAorICAgICAgICAgICAgICAgIGxpc3QpOworICAgICAgICBzdG9yZSA9IENlcnRTdG9yZS5nZXRJbnN0YW5jZSgiQ29sbGVjdGlvbiIsIHBhcmFtcyk7CisKKyAgICAgICAgdGhlQ2VydFNlbGVjdG9yID0gbmV3IFg1MDlDZXJ0U2VsZWN0b3IoKTsKKyAgICAgICAgdGhlQ2VydFNlbGVjdG9yLnNldENlcnRpZmljYXRlKGVuZENlcnRpZmljYXRlKTsKKyAgICAgICAgdGhlQ2VydFNlbGVjdG9yLnNldElzc3VlcihlbmRDZXJ0aWZpY2F0ZS5nZXRJc3N1ZXJYNTAwUHJpbmNpcGFsKCkKKyAgICAgICAgICAgICAgICAuZ2V0RW5jb2RlZCgpKTsKKworICAgICAgICAvLyBidWlsZCB0aGUgcGF0aAorICAgICAgICBidWlsZGVyID0gQ2VydFBhdGhCdWlsZGVyLmdldEluc3RhbmNlKCJQS0lYIik7CisKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIENlcnRQYXRoQnVpbGRlciBnZXRDZXJ0UGF0aEJ1aWxkZXIoKSB7CisgICAgICAgIGlmIChidWlsZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICAgIkNhbGwgaW5pdENlcnRQYXRoU1NDZXJ0Q2hhaW4gcHJpb3IgdG8gaW5pdENlcnRQYXRoU1NDZXJ0Q2hhaW4iKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnVpbGRlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIENlcnRQYXRoIGJ1aWxkQ2VydFBhdGhTU0NlcnRDaGFpbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZChnZXRDZXJ0UGF0aFBhcmFtZXRlcnMoKSkuZ2V0Q2VydFBhdGgoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIENlcnRQYXRoUGFyYW1ldGVycyBnZXRDZXJ0UGF0aFBhcmFtZXRlcnMoKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBpZiAoKHJvb3RDZXJ0aWZpY2F0ZVNTID09IG51bGwpIHx8ICh0aGVDZXJ0U2VsZWN0b3IgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICB8fCAoYnVpbGRlciA9PSBudWxsKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJDYWxsIGluaXRDZXJ0UGF0aFNTQ2VydENoYWluIHByaW9yIHRvIGJ1aWxkQ2VydFBhdGgiKTsKKyAgICAgICAgfQorICAgICAgICBQS0lYQnVpbGRlclBhcmFtZXRlcnMgYnVpbGRQYXJhbXMgPSBuZXcgUEtJWEJ1aWxkZXJQYXJhbWV0ZXJzKAorICAgICAgICAgICAgICAgIENvbGxlY3Rpb25zLnNpbmdsZXRvbihuZXcgVHJ1c3RBbmNob3Iocm9vdENlcnRpZmljYXRlU1MsIG51bGwpKSwKKyAgICAgICAgICAgICAgICB0aGVDZXJ0U2VsZWN0b3IpOworCisgICAgICAgIGJ1aWxkUGFyYW1zLmFkZENlcnRTdG9yZShzdG9yZSk7CisgICAgICAgIGJ1aWxkUGFyYW1zLnNldFJldm9jYXRpb25FbmFibGVkKGZhbHNlKTsKKworICAgICAgICByZXR1cm4gYnVpbGRQYXJhbXM7CisKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvaW50ZXJmYWNlcy9EU0FLZXlQYWlyR2VuZXJhdG9ySW1wbC5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L2ludGVyZmFjZXMvRFNBS2V5UGFpckdlbmVyYXRvckltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OGJkNzFlCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS9zZWN1cml0eS90ZXN0cy9zdXBwb3J0L2ludGVyZmFjZXMvRFNBS2V5UGFpckdlbmVyYXRvckltcGwuamF2YQpAQCAtMCwwICsxLDg0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmludGVyZmFjZXM7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuRFNBS2V5UGFpckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXJHZW5lcmF0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzLkRTQVBhcmFtczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb247CisKKy8qKgorICogQWRkaXRpb25hbCBjbGFzcyBmb3IgdmVyaWZpY2F0aW9uIERTQUtleVBhaXJHZW5lcmF0b3IgaW50ZXJmYWNlCisgKi8KK3B1YmxpYyBjbGFzcyBEU0FLZXlQYWlyR2VuZXJhdG9ySW1wbCBpbXBsZW1lbnRzIERTQUtleVBhaXJHZW5lcmF0b3IgeworCisgICAgcHJpdmF0ZSBLZXlQYWlyR2VuZXJhdG9yIGRzYUtleVBhaXJHZW5lcmF0b3IgPSBudWxsOworICAgIHByaXZhdGUgU2VjdXJlUmFuZG9tIHNlY3VyZVJhbmRvbSA9IG51bGw7CisgICAgcHJpdmF0ZSBEU0FQYXJhbXMgZHNhUGFyYW1zID0gbnVsbDsKKyAgICBwcml2YXRlIGludCBsZW5ndGhNb2R1bHVzID0gMDsKKworICAgIHB1YmxpYyBEU0FLZXlQYWlyR2VuZXJhdG9ySW1wbChEU0FQYXJhbXMgZHNhcCkgeworICAgICAgICBkc2FLZXlQYWlyR2VuZXJhdG9yID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRzYUtleVBhaXJHZW5lcmF0b3IgPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKCJEU0EiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGRzYUtleVBhaXJHZW5lcmF0b3IgPSBudWxsOworICAgICAgICB9CisgICAgICAgIGRzYVBhcmFtcyA9IGRzYXA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgaW5pdGlhbGl6ZShEU0FQYXJhbXMgcGFyYW1zLCBTZWN1cmVSYW5kb20gcmFuZG9tKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBpZiAocmFuZG9tID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKCJJbmNvcnJlY3QgcmFuZG9tIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBhcmFtcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFBhcmFtZXRlckV4Y2VwdGlvbigiSW5jb3JyZWN0IHBhcmFtcyIpOworICAgICAgICB9CisgICAgICAgIHNlY3VyZVJhbmRvbSA9IHJhbmRvbTsKKyAgICAgICAgZHNhUGFyYW1zID0gcGFyYW1zOworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgaW5pdGlhbGl6ZShpbnQgbW9kbGVuLCBib29sZWFuIGdlblBhcmFtcywgU2VjdXJlUmFuZG9tIHJhbmRvbSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IGxlbiA9IDUxMjsKKyAgICAgICAgd2hpbGUgKGxlbiA8PSAxMDI0KSB7CisgICAgICAgICAgICBpZiAobGVuID09IG1vZGxlbikgeworICAgICAgICAgICAgICAgIGxlbmd0aE1vZHVsdXMgPSBtb2RsZW47CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGxlbiA9IGxlbiArIDg7CisgICAgICAgICAgICAgICAgaWYgKGxlbiA9PSAxMDMyKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKCJJbmNvcnJlY3QgbW9kbGVuIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChtb2RsZW4gPCA1MTIgfHwgbW9kbGVuID4gMTAyNCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24oIkluY29ycmVjdCBtb2RsZW4iKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocmFuZG9tID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkUGFyYW1ldGVyRXhjZXB0aW9uKCJJbmNvcnJlY3QgcmFuZG9tIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGdlblBhcmFtcyA9PSBmYWxzZSAmJiBkc2FQYXJhbXMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24oInRoZXJlIGFyZSBub3QgcHJlY29tcHV0ZWQgcGFyYW1ldGVycyIpOworICAgICAgICB9CisgICAgICAgIHNlY3VyZVJhbmRvbSA9IHJhbmRvbTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvaW50ZXJmYWNlcy9SU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleUltcGwuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9pbnRlcmZhY2VzL1JTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjViM2ZlMTcKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvaW50ZXJmYWNlcy9SU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleUltcGwuamF2YQpAQCAtMCwwICsxLDkyIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LmludGVyZmFjZXM7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmludGVyZmFjZXMuUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXk7CitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLlJTQU90aGVyUHJpbWVJbmZvOworCisvKioKKyAqIEFkZGl0aW9uYWwgY2xhc3MgZm9yIHZlcmlmaWNhdGlvbiBSU0FNdWx0aVByaW1lUHJpdmF0ZUNydEtleSBpbnRlcmZhY2UKKyAqLworcHVibGljIGNsYXNzIFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5SW1wbCBpbXBsZW1lbnRzIFJTQU11bHRpUHJpbWVQcml2YXRlQ3J0S2V5IHsKKworICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxMjM7CisKKyAgICBwcml2YXRlIEJpZ0ludGVnZXIgY3J0Q29lZmZpY2llbnQgPSBudWxsOworICAgIHByaXZhdGUgQmlnSW50ZWdlciBwdWJsaWNFeHBvbmVudCA9IG51bGw7CisgICAgcHJpdmF0ZSBCaWdJbnRlZ2VyIHByaW1lRXhwb25lbnRQID0gbnVsbDsKKyAgICBwcml2YXRlIEJpZ0ludGVnZXIgcHJpbWVFeHBvbmVudFEgPSBudWxsOworICAgIHByaXZhdGUgQmlnSW50ZWdlciBwcmltZVAgPSBudWxsOworICAgIHByaXZhdGUgQmlnSW50ZWdlciBwcmltZVEgPSBudWxsOworICAgIHByaXZhdGUgUlNBT3RoZXJQcmltZUluZm9bXSBvdGhlclByaW1lSW5mbyA9IG51bGw7CisKKyAgICBwdWJsaWMgUlNBTXVsdGlQcmltZVByaXZhdGVDcnRLZXlJbXBsKEJpZ0ludGVnZXIgcHVibGljRXhwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwcmltZUV4cFAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHByaW1lRXhwUSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgcHJQLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnSW50ZWdlciBwclEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIGNydENmdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJTQU90aGVyUHJpbWVJbmZvW10gb3RoZXJQcm1JbmZvKSB7CisgICAgICAgIHB1YmxpY0V4cG9uZW50ID0gcHVibGljRXhwOworICAgICAgICBwcmltZUV4cG9uZW50UCA9IHByaW1lRXhwUDsKKyAgICAgICAgcHJpbWVFeHBvbmVudFEgPSBwcmltZUV4cFE7CisgICAgICAgIHByaW1lUCA9IHByUDsKKyAgICAgICAgcHJpbWVRID0gcHJROworICAgICAgICBjcnRDb2VmZmljaWVudCA9IGNydENmdDsKKyAgICAgICAgb3RoZXJQcmltZUluZm8gPSBvdGhlclBybUluZm87CisgICAgfQorCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0Q3J0Q29lZmZpY2llbnQoKSB7CisgICAgICAgIHJldHVybiBjcnRDb2VmZmljaWVudDsKKyAgICB9CisgICAgcHVibGljIFJTQU90aGVyUHJpbWVJbmZvW10gZ2V0T3RoZXJQcmltZUluZm8oKSB7CisgICAgICAgIHJldHVybiBvdGhlclByaW1lSW5mbzsKKyAgICB9CisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0UHJpbWVFeHBvbmVudFAoKSB7CisgICAgICAgIHJldHVybiBwcmltZUV4cG9uZW50UDsKKyAgICB9CisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0UHJpbWVFeHBvbmVudFEoKSB7CisgICAgICAgIHJldHVybiBwcmltZUV4cG9uZW50UTsKKyAgICB9CisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0UHJpbWVQKCkgeworICAgICAgICByZXR1cm4gcHJpbWVQOworICAgIH0KKyAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRQcmltZVEoKSB7CisgICAgICAgIHJldHVybiBwcmltZVE7CisgICAgfQorICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldFB1YmxpY0V4cG9uZW50KCkgeworICAgICAgICByZXR1cm4gcHVibGljRXhwb25lbnQ7CisgICAgfQorCisgICAgcHVibGljIEJpZ0ludGVnZXIgZ2V0UHJpdmF0ZUV4cG9uZW50KCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgICAgcHVibGljIFN0cmluZyBnZXRGb3JtYXQoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICBwdWJsaWMgYnl0ZVtdIGdldEVuY29kZWQoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICBwdWJsaWMgU3RyaW5nIGdldEFsZ29yaXRobSgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldE1vZHVsdXMoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvc3BlYy9NeUVuY29kZWRLZXlTcGVjLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvc3BlYy9NeUVuY29kZWRLZXlTcGVjLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmEzODQ3NAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC9zcGVjL015RW5jb2RlZEtleVNwZWMuamF2YQpAQCAtMCwwICsxLDQ5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWbGFkaW1pciBOLiBNb2xvdGtvdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS5zZWN1cml0eS50ZXN0cy5zdXBwb3J0LnNwZWM7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuRW5jb2RlZEtleVNwZWM7CisKKy8qKgorICogU3VwcG9ydCBjbGFzcyBmb3IgYWJzdHJhY3QgYmFzZSBjbGFzcyB0ZXN0aW5nCisgKi8KKworcHVibGljIGNsYXNzIE15RW5jb2RlZEtleVNwZWMgZXh0ZW5kcyBFbmNvZGVkS2V5U3BlYyB7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvcgorICAgICAqIEBwYXJhbSBlbmNvZGVkS2V5CisgICAgICovCisgICAgcHVibGljIE15RW5jb2RlZEtleVNwZWMoYnl0ZVtdIGVuY29kZWRLZXkpIHsKKyAgICAgICAgc3VwZXIoZW5jb2RlZEtleSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBmb3JtYXQgLSAiTXkiCisgICAgICogQHNlZSBqYXZhLnNlY3VyaXR5LnNwZWMuRW5jb2RlZEtleVNwZWMjZ2V0Rm9ybWF0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZvcm1hdCgpIHsKKyAgICAgICAgcmV0dXJuICJNeSI7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvdG1wQ2FsbGJhY2tIYW5kbGVyLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3NlY3VyaXR5L3Rlc3RzL3N1cHBvcnQvdG1wQ2FsbGJhY2tIYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmNkYWJlYQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvc2VjdXJpdHkvdGVzdHMvc3VwcG9ydC90bXBDYWxsYmFja0hhbmRsZXIuamF2YQpAQCAtMCwwICsxLDQ2IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisvKioKKyogQGF1dGhvciBWZXJhIFkuIFBldHJhc2hrb3ZhCisqIEB2ZXJzaW9uICRSZXZpc2lvbiQKKyovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnNlY3VyaXR5LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC5jYWxsYmFjay5DYWxsYmFjazsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLmNhbGxiYWNrLkNhbGxiYWNrSGFuZGxlcjsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLmNhbGxiYWNrLlVuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb247CisKKy8qKgorICogQWRkaXRpb25hbCBjbGFzcyBmb3IgY3JlYXRpbmcgQ2FsbEJhY2tIYW5kbGVyIG9iamVjdAorICoKKyAqLworCitwdWJsaWMgY2xhc3MgdG1wQ2FsbGJhY2tIYW5kbGVyIGltcGxlbWVudHMgQ2FsbGJhY2tIYW5kbGVyIHsKKyAgICBwdWJsaWMgdm9pZCBoYW5kbGUoQ2FsbGJhY2tbXSBjYWxsYmFjaykgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjYWxsYmFjayA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRDYWxsYmFja0V4Y2VwdGlvbihudWxsLCAiY2FsbGJhY2sgaXMgbnVsbCIpOworICAgICAgICB9CisgICAgICAgIGlmIChjYWxsYmFjay5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkQ2FsbGJhY2tFeGNlcHRpb24obnVsbCwgImNhbGxiYWNrIGlzIGVtcHR5Iik7CisgICAgICAgIH0KKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS90ZXN0ZnJhbWV3b3JrL3NlcmlhbGl6YXRpb24vU2VyaWFsaXphdGlvblRlc3QuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvdGVzdGZyYW1ld29yay9zZXJpYWxpemF0aW9uL1NlcmlhbGl6YXRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGQwYzNhNAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkvdGVzdGZyYW1ld29yay9zZXJpYWxpemF0aW9uL1NlcmlhbGl6YXRpb25UZXN0LmphdmEKQEAgLTAsMCArMSw0NzggQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8qKgorKiBAYXV0aG9yIEFsZXhleSBWLiBWYXJsYW1vdgorKiBAdmVyc2lvbiAkUmV2aXNpb24kCisqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS50ZXN0ZnJhbWV3b3JrLnNlcmlhbGl6YXRpb247CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb25Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogRnJhbWV3b3JrIGZvciBzZXJpYWxpemF0aW9uIHRlc3RpbmcuIFN1YmNsYXNzZXMgb25seSBuZWVkIHRvIG92ZXJyaWRlCisgKiBnZXREYXRhKCkgbWV0aG9kIGFuZCwgb3B0aW9uYWxseSwgYXNzZXJ0RGVzZXJpYWxpemVkKCkgbWV0aG9kLiBUaGUgZmlyc3Qgb25lCisgKiByZXR1cm5zIGFycmF5IG9mIG9iamVjdHMgdG8gYmUgZGUvc2VyaWFsaXplZCBpbiB0ZXN0cywgYW5kIHRoZSBzZWNvbmQKKyAqIGNvbXBhcmVzIHJlZmVyZW5jZSBhbmQgZGVzZXJpYWxpemVkIG9iamVjdHMgKG5lZWRlZCBvbmx5IGlmIHRlc3RlZCBvYmplY3RzIGRvCisgKiBub3QgcHJvdmlkZSBzcGVjaWZpYyBtZXRob2QgZXF1YWxzKCkpLiA8YnI+CisgKiBUaGVyZSBhcmUgdHdvIG1vZGVzIG9mIHRlc3QgcnVuOiA8Yj5yZWZlcmVuY2UgZ2VuZXJhdGlvbiBtb2RlIDwvYj4gYW5kCisgKiA8Yj50ZXN0aW5nIG1vZGUgPC9iPi4gVGhlIGFjdHVhbCBtb2RlIGlzIHNlbGVjdGVkIHZpYQorICogPGI+JnF1b3Q7dGVzdC5tb2RlJnF1b3Q7IDwvYj4gc3lzdGVtIHByb3BlcnR5LiBUaGUgPGI+dGVzdGluZyBtb2RlIDwvYj4gaXMKKyAqIHRoZSBkZWZhdWx0IG1vZGUuIDxicj4KKyAqIFRvIHR1cm4gb24gdGhlIDxiPnJlZmVyZW5jZSBnZW5lcmF0aW9uIG1vZGUgPC9iPiwgdGhlIHRlc3QubW9kZSBwcm9wZXJ0eQorICogc2hvdWxkIGJlIHNldCB0byB2YWx1ZSAmcXVvdDtzZXJpYWwucmVmZXJlbmNlJnF1b3Q7LiBJbiB0aGlzIG1vZGUsIG5vIHRlc3RpbmcKKyAqIGlzIHBlcmZvcm1lZCBidXQgZ29sZGVuIGZpbGVzIGFyZSBwcm9kdWNlZCwgd2hpY2ggY29udGFpbiByZWZlcmVuY2UKKyAqIHNlcmlhbGl6ZWQgb2JqZWN0cy4gVGhpcyBtb2RlIHNob3VsZCBiZSBydW4gb24gYSBwdXJlCisgKiBJbXBsZW1lbnRhdGlvbiBjbGFzc2VzLCB3aGljaCBhcmUgdGFyZ2V0ZWQgZm9yIGNvbXBhcnRpYmlsaXR5LiA8YnI+CisgKiBUaGUgbG9jYXRpb24gb2YgZ29sZGVuIGZpbGVzIChpbiBib3RoIG1vZGVzKSBpcyBjb250cm9sbGVkIHZpYQorICogPGI+JnF1b3Q7UkVTT1VSQ0VfRElSJnF1b3Q7IDwvYj4gc3lzdGVtIHByb3BlcnR5LgorICoKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFNlcmlhbGl6YXRpb25UZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgLyoqCisgICAgICogS2V5IHRvIGEgc3lzdGVtIHByb3BlcnR5IGRlZmluaW5nIHJvb3QgbG9jYXRpb24gb2YgZ29sZGVuIGZpbGVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdPTERFTl9QQVRIID0gIlJFU09VUkNFX0RJUiI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgb3V0cHV0UGF0aCA9IFN5c3RlbS5nZXRQcm9wZXJ0eShHT0xERU5fUEFUSCwKKyAgICAgICAgICAgICJzcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbiIpOworCisgICAgLyoqCisgICAgICogVGhpcyBpcyB0aGUgbWFpbiB3b3JraW5nIG1ldGhvZCBvZiB0aGlzIGZyYW1ld29yay4gU3ViY2xhc3NlcyBtdXN0CisgICAgICogb3ZlcnJpZGUgaXQgdG8gcHJvdmlkZSBhY3R1YWwgb2JqZWN0cyBmb3IgdGVzdGluZy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYXJyYXkgb2Ygb2JqZWN0cyB0byBiZSBkZS9zZXJpYWxpemVkIGluIHRlc3RzLgorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBPYmplY3RbXSBnZXREYXRhKCk7CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyB0aGF0IGRhdGEgb2JqZWN0cyBjYW4gYmUgc2VyaWFsaXplZCBhbmQgZGVzZXJpYWxpemVkIHdpdGhvdXQKKyAgICAgKiBleGNlcHRpb25zLCBhbmQgdGhhdCBkZXNlcmlhbGl6YXRpb24gcmVhbGx5IHByb2R1Y2VzIGRlZXBseSBjbG9uZWQKKyAgICAgKiBvYmplY3RzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHRlc3RTZWxmKCkgdGhyb3dzIFRocm93YWJsZSB7CisKKyAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBTZXJpYWxpemFibGVBc3NlcnQpIHsKKyAgICAgICAgICAgIHZlcmlmeVNlbGYoZ2V0RGF0YSgpLCAoU2VyaWFsaXphYmxlQXNzZXJ0KSB0aGlzKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHZlcmlmeVNlbGYoZ2V0RGF0YSgpKTsKKworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgdGhhdCBkYXRhIG9iamVjdHMgY2FuIGJlIGRlc2VyaWFsaXplZCBmcm9tIGdvbGRlbiBmaWxlcywgdG8gdmVyaWZ5CisgICAgICogY29tcGF0aWJpbGl0eSB3aXRoIFJlZmVyZW5jZSBJbXBsZW1lbnRhdGlvbi4KKyAgICAgKi8KKworICAgIHB1YmxpYyB2b2lkIHRlc3RHb2xkZW4oKSB0aHJvd3MgVGhyb3dhYmxlIHsKKworICAgICAgICB2ZXJpZnlHb2xkZW4odGhpcywgZ2V0RGF0YSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGdvbGRlbiBmaWxlIGZvciBhbiBvYmplY3QgYmVpbmcgdGVzdGVkLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IGFycmF5IGluZGV4IG9mIHRlc3RlZCBkYXRhIChhcyByZXR1cm5lZCBieQorICAgICAqICAgICAgICB7QGxpbmsgI2dldERhdGEoKSBnZXREYXRhKCl9KQorICAgICAqIEByZXR1cm4gY29ycmVzcG9uZGluZyBnb2xkZW4gZmlsZQorICAgICAqLworICAgIHByb3RlY3RlZCBGaWxlIGdldERhdGFGaWxlKGludCBpbmRleCkgeworICAgICAgICBTdHJpbmcgbmFtZSA9IHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCk7CisgICAgICAgIGludCBkb3QgPSBuYW1lLmxhc3RJbmRleE9mKCIuIik7CisgICAgICAgIFN0cmluZyBwYXRoID0gbmFtZS5zdWJzdHJpbmcoMCwgZG90KS5yZXBsYWNlKCcuJywgRmlsZS5zZXBhcmF0b3JDaGFyKTsKKyAgICAgICAgaWYgKG91dHB1dFBhdGggIT0gbnVsbCAmJiBvdXRwdXRQYXRoLmxlbmd0aCgpICE9IDApIHsKKyAgICAgICAgICAgIHBhdGggPSBvdXRwdXRQYXRoICsgRmlsZS5zZXBhcmF0b3IgKyBwYXRoOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ldyBGaWxlKHBhdGgsIG5hbWUuc3Vic3RyaW5nKGRvdCArIDEpICsgIi4iICsgaW5kZXggKyAiLmRhdCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdvcmtpbmcgbWV0aG9kIGZvciBmaWxlcyBnZW5lcmF0aW9uIG1vZGUuIFNlcmlhbGl6ZXMgdGVzdCBvYmplY3RzCisgICAgICogcmV0dXJuZWQgYnkge0BsaW5rICNnZXREYXRhKCkgZ2V0RGF0YSgpfXRvIGdvbGRlbiBmaWxlcywgZWFjaCBvYmplY3QgdG8KKyAgICAgKiBhIHNlcGFyYXRlIGZpbGUuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvZHVjZUdvbGRlbkZpbGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBTdHJpbmcgZ29sZGVuUGF0aCA9IG91dHB1dFBhdGggKyBGaWxlLnNlcGFyYXRvckNoYXIKKyAgICAgICAgICAgICAgICArIGdldENsYXNzKCkuZ2V0TmFtZSgpLnJlcGxhY2UoJy4nLCBGaWxlLnNlcGFyYXRvckNoYXIpCisgICAgICAgICAgICAgICAgKyAiLmdvbGRlbi4iOworCisgICAgICAgIE9iamVjdFtdIGRhdGEgPSBnZXREYXRhKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykgeworCisgICAgICAgICAgICBGaWxlIGdvbGRlbkZpbGUgPSBuZXcgRmlsZShnb2xkZW5QYXRoICsgaSArICIuc2VyIik7CisgICAgICAgICAgICBnb2xkZW5GaWxlLmdldFBhcmVudEZpbGUoKS5ta2RpcnMoKTsKKyAgICAgICAgICAgIGdvbGRlbkZpbGUuY3JlYXRlTmV3RmlsZSgpOworCisgICAgICAgICAgICBwdXRPYmplY3RUb1N0cmVhbShkYXRhW2ldLCBuZXcgRmlsZU91dHB1dFN0cmVhbShnb2xkZW5GaWxlKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXJpYWxpemVzIHNwZWNpZmllZCBvYmplY3QgdG8gYW4gb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcHV0T2JqZWN0VG9TdHJlYW0oT2JqZWN0IG9iaiwgT3V0cHV0U3RyZWFtIG9zKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtIG9vcyA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0ob3MpOworICAgICAgICBvb3Mud3JpdGVPYmplY3Qob2JqKTsKKyAgICAgICAgb29zLmZsdXNoKCk7CisgICAgICAgIG9vcy5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlc2VyaWFsaXplcyBzaW5nbGUgb2JqZWN0IGZyb20gYW4gaW5wdXQgc3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU2VyaWFsaXphYmxlIGdldE9iamVjdEZyb21TdHJlYW0oSW5wdXRTdHJlYW0gaXMpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBPYmplY3RJbnB1dFN0cmVhbSBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0oaXMpOworICAgICAgICBPYmplY3QgcmVzdWx0ID0gb2lzLnJlYWRPYmplY3QoKTsKKyAgICAgICAgb2lzLmNsb3NlKCk7CisgICAgICAgIHJldHVybiAoU2VyaWFsaXphYmxlKXJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnRlcmZhY2UgdG8gY29tcGFyZSAoZGUpc2VyaWFsaXplZCBvYmplY3RzCisgICAgICoKKyAgICAgKiBTaG91bGQgYmUgaW1wbGVtZW50ZWQgaWYgYSBjbGFzcyB1bmRlciB0ZXN0IGRvZXMgbm90IHByb3ZpZGUgc3BlY2lmaWMKKyAgICAgKiBlcXVhbHMoKSBtZXRob2QgYW5kIGl0J3MgaW5zdGFuY2VzIHNob3VsZCB0byBiZSBjb21wYXJlZCBtYW51YWxseS4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50ZXJmYWNlIFNlcmlhbGl6YWJsZUFzc2VydCB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIENvbXBhcmVzIGRlc2VyaWFsaXplZCBhbmQgcmVmZXJlbmNlIG9iamVjdHMuCisgICAgICAgICAqCisgICAgICAgICAqIEBwYXJhbSBpbml0aWFsIC0gaW5pdGlhbCBvYmplY3QgdXNlZCBmb3IgY3JlYXRpbmcgc2VyaWFsaXplZCBmb3JtCisgICAgICAgICAqIEBwYXJhbSBkZXNlcmlhbGl6ZWQgLSBkZXNlcmlhbGl6ZWQgb2JqZWN0CisgICAgICAgICAqLworICAgICAgICB2b2lkIGFzc2VydERlc2VyaWFsaXplZChTZXJpYWxpemFibGUgaW5pdGlhbCwgU2VyaWFsaXphYmxlIGRlc2VyaWFsaXplZCk7CisgICAgfQorCisgICAgLy8gZGVmYXVsdCBjb21wYXJhdG9yIGZvciBhIGNsYXNzIHRoYXQgaGFzIGVxdWFscyhPYmplY3QpIG1ldGhvZAorICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFNlcmlhbGl6YWJsZUFzc2VydCBERUZBVUxUX0NPTVBBUkFUT1IgPSBuZXcgU2VyaWFsaXphYmxlQXNzZXJ0KCkgeworICAgICAgICBwdWJsaWMgdm9pZCBhc3NlcnREZXNlcmlhbGl6ZWQoU2VyaWFsaXphYmxlIGluaXRpYWwsIFNlcmlhbGl6YWJsZSBkZXNlcmlhbGl6ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpbml0aWFsLCBkZXNlcmlhbGl6ZWQpOworICAgICAgICB9CisgICAgfTsKKworICAgIC8qKgorICAgICAqIENvbXBhcmF0b3IgZm9yIHZlcmlmeWluZyB0aGF0IGRlc2VyaWFsaXplZCBvYmplY3QgaXMgdGhlIHNhbWUgYXMgaW5pdGlhbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIFNlcmlhbGl6YWJsZUFzc2VydCBTQU1FX0NPTVBBUkFUT1IgPSBuZXcgU2VyaWFsaXphYmxlQXNzZXJ0KCkgeworICAgICAgICBwdWJsaWMgdm9pZCBhc3NlcnREZXNlcmlhbGl6ZWQoU2VyaWFsaXphYmxlIGluaXRpYWwsIFNlcmlhbGl6YWJsZSBkZXNlcmlhbGl6ZWQpIHsKKyAgICAgICAgICAgIGFzc2VydFNhbWUoaW5pdGlhbCwgZGVzZXJpYWxpemVkKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJhdG9yIGZvciBUaHJvd2FibGUgb2JqZWN0cworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU2VyaWFsaXphYmxlQXNzZXJ0IFRIUk9XQUJMRV9DT01QQVJBVE9SID0gbmV3IFNlcmlhbGl6YWJsZUFzc2VydCgpIHsKKyAgICAgICAgcHVibGljIHZvaWQgYXNzZXJ0RGVzZXJpYWxpemVkKFNlcmlhbGl6YWJsZSBpbml0aWFsLCBTZXJpYWxpemFibGUgZGVzZXJpYWxpemVkKSB7CisgICAgICAgICAgICBUaHJvd2FibGUgaW5pdFRociA9IChUaHJvd2FibGUpIGluaXRpYWw7CisgICAgICAgICAgICBUaHJvd2FibGUgZHNlclRociA9IChUaHJvd2FibGUpIGRlc2VyaWFsaXplZDsKKworICAgICAgICAgICAgLy8gdmVyaWZ5IGNsYXNzCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaW5pdFRoci5nZXRDbGFzcygpLCBkc2VyVGhyLmdldENsYXNzKCkpOworCisgICAgICAgICAgICAvLyB2ZXJpZnkgbWVzc2FnZQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGluaXRUaHIuZ2V0TWVzc2FnZSgpLCBkc2VyVGhyLmdldE1lc3NhZ2UoKSk7CisKKyAgICAgICAgICAgIC8vIHZlcmlmeSBjYXVzZQorICAgICAgICAgICAgaWYgKGluaXRUaHIuZ2V0Q2F1c2UoKSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChkc2VyVGhyLmdldENhdXNlKCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGRzZXJUaHIuZ2V0Q2F1c2UoKSk7CisgICAgICAgICAgICAgICAgVEhST1dBQkxFX0NPTVBBUkFUT1IuYXNzZXJ0RGVzZXJpYWxpemVkKGluaXRUaHIuZ2V0Q2F1c2UoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRzZXJUaHIuZ2V0Q2F1c2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9OworCisgICAgLyoqCisgICAgICogQ29tcGFyYXRvciBmb3IgUGVybWlzc2lvbkNvbGxlY3Rpb24gb2JqZWN0cworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU2VyaWFsaXphYmxlQXNzZXJ0IFBFUk1JU1NJT05fQ09MTEVDVElPTl9DT01QQVJBVE9SID0gbmV3IFNlcmlhbGl6YWJsZUFzc2VydCgpIHsKKyAgICAgICAgcHVibGljIHZvaWQgYXNzZXJ0RGVzZXJpYWxpemVkKFNlcmlhbGl6YWJsZSBpbml0aWFsLCBTZXJpYWxpemFibGUgZGVzZXJpYWxpemVkKSB7CisKKyAgICAgICAgICAgIFBlcm1pc3Npb25Db2xsZWN0aW9uIGluaXRQQyA9IChQZXJtaXNzaW9uQ29sbGVjdGlvbikgaW5pdGlhbDsKKyAgICAgICAgICAgIFBlcm1pc3Npb25Db2xsZWN0aW9uIGRzZXJQQyA9IChQZXJtaXNzaW9uQ29sbGVjdGlvbikgZGVzZXJpYWxpemVkOworCisgICAgICAgICAgICAvLyB2ZXJpZnkgY2xhc3MKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpbml0UEMuZ2V0Q2xhc3MoKSwgZHNlclBDLmdldENsYXNzKCkpOworCisgICAgICAgICAgICAvLyB2ZXJpZnkgJ3JlYWRPbmx5JyBmaWVsZAorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGluaXRQQy5pc1JlYWRPbmx5KCksIGRzZXJQQy5pc1JlYWRPbmx5KCkpOworCisgICAgICAgICAgICAvLyB2ZXJpZnkgY29sbGVjdGlvbiBvZiBwZXJtaXNzaW9ucworICAgICAgICAgICAgQ29sbGVjdGlvbjxQZXJtaXNzaW9uPiByZWZDb2xsZWN0aW9uID0gbmV3IEhhc2hTZXQ8UGVybWlzc2lvbj4oCisgICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb25zLmxpc3QoaW5pdFBDLmVsZW1lbnRzKCkpKTsKKyAgICAgICAgICAgIENvbGxlY3Rpb248UGVybWlzc2lvbj4gdHN0Q29sbGVjdGlvbiA9IG5ldyBIYXNoU2V0PFBlcm1pc3Npb24+KAorICAgICAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy5saXN0KGRzZXJQQy5lbGVtZW50cygpKSk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhyZWZDb2xsZWN0aW9uLCB0c3RDb2xsZWN0aW9uKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIDxjb2RlPmNvbXBhcmF0b3I8L2NvZGU+IGZvciBwcm92aWRlZCBzZXJpYWxpemFibGUKKyAgICAgKiA8Y29kZT5vYmplY3Q8L2NvZGU+LgorICAgICAqCisgICAgICogVGhlIDxjb2RlPmNvbXBhcmF0b3I8L2NvZGU+IGlzIHNlYXJjaGVkIGluIHRoZSBmb2xsb3dpbmcgb3JkZXI6IDxicj4KKyAgICAgKiAtIGlmIDxjb2RlPnRlc3Q8L2NvZGU+IGltcGxlbWVudHMgU2VyaWFsaXphYmxlQXNzZXJ0IGludGVyZmFjZSB0aGVuIGl0IGlzCisgICAgICogc2VsZWN0ZWQgYXMgPC9jb2RlPmNvbXBhcmF0b3I8L2NvZGU+Ljxicj4tIGlmIHBhc3NlZCA8Y29kZT5vYmplY3Q8L2NvZGU+CisgICAgICogaGFzIGNsYXNzIGluIGl0cyBjbGFzc2VzIGhpZXJhcmNoeSB0aGF0IG92ZXJyaWRlcyA8Y29kZT5lcXVhbHMoT2JqZWN0KTwvY29kZT4KKyAgICAgKiBtZXRob2QgdGhlbiA8Y29kZT5ERUZBVUxUX0NPTVBBUkFUT1I8L2NvZGU+IGlzIHNlbGVjdGVkLjxicj4gLSB0aGUKKyAgICAgKiBtZXRob2QgdHJpZXMgdG8gc2VsZWN0IG9uZSBvZiBrbm93biBjb21wYXJhdG9ycyBiYXNpbmcgb24gPGNvZGU+b2JqZWN0J3M8L2NvZGU+CisgICAgICogY2xhc3MsZm9yIGV4YW1wbGUsIGlmIHBhc3NlZCA8Y29kZT5vYmplY3Q8L2NvZGU+IGlzIGluc3RhbmNlIG9mCisgICAgICogVGhyb3dhYmxlIHRoZW4gPGNvZGU+VEhST1dBQkxFX0NPTVBBUkFUT1I8L2NvZGU+IGlzIHVzZWQuPGJyPgorICAgICAqIC0gb3RoZXJ3aXNlIFJ1bnRpbWVFeGNlcHRpb24gaXMgdGhyb3duCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGVzdCAtIHRlc3QgY2FzZQorICAgICAqIEBwYXJhbSBvYmplY3QgLSBvYmplY3QgdG8gYmUgY29tcGFyZWQKKyAgICAgKiBAcmV0dXJuIG9iamVjdCdzIGNvbXBhcmF0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNlcmlhbGl6YWJsZUFzc2VydCBkZWZpbmVDb21wYXJhdG9yKFRlc3RDYXNlIHRlc3QsIE9iamVjdCBvYmplY3QpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBpZiAodGVzdCBpbnN0YW5jZW9mIFNlcmlhbGl6YWJsZUFzc2VydCkgeworICAgICAgICAgICAgcmV0dXJuIChTZXJpYWxpemFibGVBc3NlcnQpIHRlc3Q7CisgICAgICAgIH0KKworICAgICAgICBNZXRob2QgbSA9IG9iamVjdC5nZXRDbGFzcygpLmdldE1ldGhvZCgiZXF1YWxzIiwgbmV3IENsYXNzW10geyBPYmplY3QuY2xhc3MgfSk7CisgICAgICAgIGlmIChtLmdldERlY2xhcmluZ0NsYXNzKCkgIT0gT2JqZWN0LmNsYXNzKSB7CisgICAgICAgICAgICAvLyBvbmUgb2YgY2xhc3NlcyBvdmVycmlkZXMgT2JqZWN0LmVxdWFscyhPYmplY3QpIG1ldGhvZAorICAgICAgICAgICAgLy8gdXNlIGRlZmF1bHQgY29tcGFyYXRvcgorICAgICAgICAgICAgcmV0dXJuIERFRkFVTFRfQ09NUEFSQVRPUjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRPRE8gdXNlIGdlbmVyaWNzIHRvIGRldGVjdCBjb21wYXJhdG9yCisgICAgICAgIC8vIGluc3RlYWQgb2YgJ2luc3RhbmNlb2YnIGZvciB0aGUgZmlyc3QgZWxlbWVudAorICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgVGhyb3dhYmxlKSB7CisgICAgICAgICAgICByZXR1cm4gVEhST1dBQkxFX0NPTVBBUkFUT1I7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIFBlcm1pc3Npb25Db2xsZWN0aW9uKSB7CisgICAgICAgICAgICByZXR1cm4gUEVSTUlTU0lPTl9DT0xMRUNUSU9OX0NPTVBBUkFUT1I7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkZhaWxlZCB0byBkZXRlY3QgY29tcGFyYXRvciIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFZlcmlmaWVzIHRoYXQgb2JqZWN0IGRlc2VyaWFsaXplZCBmcm9tIGdvbGRlbiBmaWxlIGNvcnJlY3RseS4KKyAgICAgKgorICAgICAqIFRoZSBtZXRob2QgaW52b2tlcyA8YnI+CisgICAgICogdmVyaWZ5R29sZGVuKHRlc3QsIG9iamVjdCwgZGVmaW5lQ29tcGFyYXRvcih0ZXN0LCBvYmplY3QpKTsKKyAgICAgKgorICAgICAqIEBwYXJhbSB0ZXN0IC0gdGVzdCBjYXNlCisgICAgICogQHBhcmFtIG9iamVjdCAtIHRvIGJlIGNvbXBhcmVkCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHZlcmlmeUdvbGRlbihUZXN0Q2FzZSB0ZXN0LCBPYmplY3Qgb2JqZWN0KSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdmVyaWZ5R29sZGVuKHRlc3QsIG9iamVjdCwgZGVmaW5lQ29tcGFyYXRvcih0ZXN0LCBvYmplY3QpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWZXJpZmllcyB0aGF0IG9iamVjdCBkZXNlcmlhbGl6ZWQgZnJvbSBnb2xkZW4gZmlsZSBjb3JyZWN0bHkuCisgICAgICoKKyAgICAgKiBUaGUgbWV0aG9kIGxvYWRzICI8Y29kZT50ZXN0TmFtZTwvY29kZT4uZ29sZGVuLnNlciIgcmVzb3VyY2UgZmlsZQorICAgICAqIGZyb20gIjxtb2R1bGUgcm9vdD4vc3JjL3Rlc3QvcmVzb3VyY2VzL3NlcmlhbGl6YXRpb24vPGNvZGU+dGVzdFBhY2thZ2U8L2NvZGU+IgorICAgICAqIGZvbGRlciwgcmVhZHMgYW4gb2JqZWN0IGZyb20gdGhlIGxvYWRlZCBmaWxlIGFuZCBjb21wYXJlcyBpdCB3aXRoCisgICAgICogPGNvZGU+b2JqZWN0PC9jb2RlPiB1c2luZyBzcGVjaWZpZWQgPGNvZGU+Y29tcGFyYXRvcjwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGVzdCAtIHRlc3QgY2FzZQorICAgICAqIEBwYXJhbSBvYmplY3QgLSB0byBiZSBjb21wYXJlZAorICAgICAqIEBwYXJhbSBjb21wYXJhdG9yIC0gZm9yIGNvbXBhcmluZyAoZGUpc2VyaWFsaXplZCBvYmplY3RzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHZlcmlmeUdvbGRlbihUZXN0Q2FzZSB0ZXN0LCBPYmplY3Qgb2JqZWN0LCBTZXJpYWxpemFibGVBc3NlcnQgY29tcGFyYXRvcikKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnROb3ROdWxsKCJOdWxsIGNvbXBhcmF0b3IiLCBjb21wYXJhdG9yKTsKKyAgICAgICAgU2VyaWFsaXphYmxlIGRlc2VyaWFsaXplZCA9IGdldE9iamVjdCh0ZXN0LCAiLmdvbGRlbi5zZXIiKTsKKyAgICAgICAgY29tcGFyYXRvci5hc3NlcnREZXNlcmlhbGl6ZWQoKFNlcmlhbGl6YWJsZSkgb2JqZWN0LCBkZXNlcmlhbGl6ZWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFZlcmlmaWVzIHRoYXQgb2JqZWN0cyBmcm9tIGFycmF5IGRlc2VyaWFsaXplZCBmcm9tIGdvbGRlbiBmaWxlcworICAgICAqIGNvcnJlY3RseS4KKyAgICAgKgorICAgICAqIFRoZSBtZXRob2QgaW52b2tlcyA8YnI+CisgICAgICogdmVyaWZ5R29sZGVuKHRlc3QsIG9iamVjdHMsIGRlZmluZUNvbXBhcmF0b3IodGVzdCwgb2JqZWN0WzBdKSk7CisgICAgICoKKyAgICAgKiBAcGFyYW0gdGVzdCAtIHRlc3QgY2FzZQorICAgICAqIEBwYXJhbSBvYmplY3RzIC0gYXJyYXkgb2Ygb2JqZWN0cyB0byBiZSBjb21wYXJlZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB2ZXJpZnlHb2xkZW4oVGVzdENhc2UgdGVzdCwgT2JqZWN0W10gb2JqZWN0cykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKCJFbXB0eSBhcnJheSIsIG9iamVjdHMubGVuZ3RoID09IDApOworICAgICAgICB2ZXJpZnlHb2xkZW4odGVzdCwgb2JqZWN0cywgZGVmaW5lQ29tcGFyYXRvcih0ZXN0LCBvYmplY3RzWzBdKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVmVyaWZpZXMgdGhhdCBvYmplY3RzIGZyb20gYXJyYXkgZGVzZXJpYWxpemVkIGZyb20gZ29sZGVuIGZpbGVzCisgICAgICogY29ycmVjdGx5LgorICAgICAqCisgICAgICogVGhlIG1ldGhvZCBsb2FkcyAiPGNvZGU+dGVzdE5hbWU8L2NvZGU+LmdvbGRlbi48Y29kZT5OPC9jb2RlPi5zZXIiCisgICAgICogcmVzb3VyY2UgZmlsZXMgZnJvbSAiPG1vZHVsZSByb290Pi9zcmMvdGVzdC9yZXNvdXJjZXMvc2VyaWFsaXphdGlvbi88Y29kZT50ZXN0UGFja2FnZTwvY29kZT4iCisgICAgICogZm9sZGVyLCBmcm9tIGVhY2ggbG9hZGVkIGZpbGUgaXQgcmVhZHMgYW4gb2JqZWN0IGZyb20gYW5kIGNvbXBhcmVzIGl0CisgICAgICogd2l0aCBjb3JyZXNwb25kaW5nIG9iamVjdCBpbiBwcm92aWRlZCBhcnJheSAoaS5lLiA8Y29kZT5vYmplY3RzW05dPC9jb2RlPikKKyAgICAgKiB1c2luZyBzcGVjaWZpZWQgPGNvZGU+Y29tcGFyYXRvcjwvY29kZT4uICg8Y29kZT5OPC9jb2RlPiBpcyBpbmRleAorICAgICAqIGluIG9iamVjdCdzIGFycmF5LikKKyAgICAgKgorICAgICAqIEBwYXJhbSB0ZXN0IC0gdGVzdCBjYXNlCisgICAgICogQHBhcmFtIG9iamVjdHMgLSBhcnJheSBvZiBvYmplY3RzIHRvIGJlIGNvbXBhcmVkCisgICAgICogQHBhcmFtIGNvbXBhcmF0b3IgLSBmb3IgY29tcGFyaW5nIChkZSlzZXJpYWxpemVkIG9iamVjdHMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdmVyaWZ5R29sZGVuKFRlc3RDYXNlIHRlc3QsIE9iamVjdFtdIG9iamVjdHMsIFNlcmlhbGl6YWJsZUFzc2VydCBjb21wYXJhdG9yKQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEZhbHNlKCJFbXB0eSBhcnJheSIsIG9iamVjdHMubGVuZ3RoID09IDApOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iamVjdHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFNlcmlhbGl6YWJsZSBkZXNlcmlhbGl6ZWQgPSBnZXRPYmplY3QodGVzdCwgIi5nb2xkZW4uIiArIGkgKyAiLnNlciIpOworICAgICAgICAgICAgY29tcGFyYXRvci5hc3NlcnREZXNlcmlhbGl6ZWQoKFNlcmlhbGl6YWJsZSkgb2JqZWN0c1tpXSwgZGVzZXJpYWxpemVkKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFZlcmlmaWVzIHRoYXQgb2JqZWN0IGNhbiBiZSBzbW9vdGhseSBzZXJpYWxpemVkL2Rlc2VyaWFsaXplZC4KKyAgICAgKgorICAgICAqIFRoZSBtZXRob2QgaW52b2tlcyA8YnI+CisgICAgICogdmVyaWZ5U2VsZihvYmplY3QsIGRlZmluZUNvbXBhcmF0b3IobnVsbCwgb2JqZWN0KSk7CisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqZWN0IC0gdG8gYmUgc2VyaWFsaXplZC9kZXNlcmlhbGl6ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdmVyaWZ5U2VsZihPYmplY3Qgb2JqZWN0KSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdmVyaWZ5U2VsZihvYmplY3QsIGRlZmluZUNvbXBhcmF0b3IobnVsbCwgb2JqZWN0KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVmVyaWZpZXMgdGhhdCBvYmplY3QgY2FuIGJlIHNtb290aGx5IHNlcmlhbGl6ZWQvZGVzZXJpYWxpemVkLgorICAgICAqCisgICAgICogVGhlIG1ldGhvZCBzZXJpYWxpemUvZGVzZXJpYWxpemUgPGNvZGU+b2JqZWN0PC9jb2RlPiBhbmQgY29tcGFyZSBpdAorICAgICAqIHdpdGggaW5pdGlhbCA8Y29kZT5vYmplY3Q8L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdCAtIG9iamVjdCB0byBiZSBzZXJpYWxpemVkL2Rlc2VyaWFsaXplZAorICAgICAqIEBwYXJhbSBjb21wYXJhdG9yIC0gZm9yIGNvbXBhcmluZyBzZXJpYWxpemVkL2Rlc2VyaWFsaXplZCBvYmplY3Qgd2l0aCBpbml0aWFsIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB2ZXJpZnlTZWxmKE9iamVjdCBvYmplY3QsIFNlcmlhbGl6YWJsZUFzc2VydCBjb21wYXJhdG9yKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2VyaWFsaXphYmxlIGluaXRpYWwgPSAoU2VyaWFsaXphYmxlKSBvYmplY3Q7CisgICAgICAgIGNvbXBhcmF0b3IuYXNzZXJ0RGVzZXJpYWxpemVkKGluaXRpYWwsIGNvcHlTZXJpYWxpemFibGUoaW5pdGlhbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFZlcmlmaWVzIHRoYXQgdGhhdCBvYmplY3RzIGZyb20gYXJyYXkgY2FuIGJlIHNtb290aGx5CisgICAgICogc2VyaWFsaXplZC9kZXNlcmlhbGl6ZWQuCisgICAgICoKKyAgICAgKiBUaGUgbWV0aG9kIGludm9rZXMgPGJyPgorICAgICAqIHZlcmlmeVNlbGYob2JqZWN0cywgZGVmaW5lQ29tcGFyYXRvcihudWxsLCBvYmplY3RbMF0pKTsKKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmplY3RzIC0gYXJyYXkgb2Ygb2JqZWN0cyB0byBiZSBzZXJpYWxpemVkL2Rlc2VyaWFsaXplZAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB2ZXJpZnlTZWxmKE9iamVjdFtdIG9iamVjdHMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZSgiRW1wdHkgYXJyYXkiLCBvYmplY3RzLmxlbmd0aCA9PSAwKTsKKyAgICAgICAgdmVyaWZ5U2VsZihvYmplY3RzLCBkZWZpbmVDb21wYXJhdG9yKG51bGwsIG9iamVjdHNbMF0pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBWZXJpZmllcyB0aGF0IHRoYXQgb2JqZWN0cyBmcm9tIGFycmF5IGNhbiBiZSBzbW9vdGhseQorICAgICAqIHNlcmlhbGl6ZWQvZGVzZXJpYWxpemVkLgorICAgICAqCisgICAgICogVGhlIG1ldGhvZCBzZXJpYWxpemUvZGVzZXJpYWxpemUgZWFjaCBvYmplY3QgaW4gPGNvZGU+b2JqZWN0czwvY29kZT4KKyAgICAgKiBhcnJheSBhbmQgY29tcGFyZSBpdCB3aXRoIGluaXRpYWwgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIG9iamVjdHMgLSBhcnJheSBvZiBvYmplY3RzIHRvIGJlIHNlcmlhbGl6ZWQvZGVzZXJpYWxpemVkCisgICAgICogQHBhcmFtIGNvbXBhcmF0b3IgLSBmb3IgY29tcGFyaW5nIHNlcmlhbGl6ZWQvZGVzZXJpYWxpemVkIG9iamVjdCB3aXRoIGluaXRpYWwgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHZlcmlmeVNlbGYoT2JqZWN0W10gb2JqZWN0cywgU2VyaWFsaXphYmxlQXNzZXJ0IGNvbXBhcmF0b3IpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RmFsc2UoIkVtcHR5IGFycmF5Iiwgb2JqZWN0cy5sZW5ndGggPT0gMCk7CisgICAgICAgIGZvciAoT2JqZWN0IGVudHJ5OiBvYmplY3RzKXsKKyAgICAgICAgICAgIHZlcmlmeVNlbGYoZW50cnksIGNvbXBhcmF0b3IpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU2VyaWFsaXphYmxlIGdldE9iamVjdChUZXN0Q2FzZSB0ZXN0LCBTdHJpbmcgdG9BcHBlbmQpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmdCdWlsZGVyIHBhdGggPSBuZXcgU3RyaW5nQnVpbGRlcigiL3NlcmlhbGl6YXRpb24iKTsKKyAgICAgICAgcGF0aC5hcHBlbmQoRmlsZS5zZXBhcmF0b3JDaGFyKTsKKyAgICAgICAgcGF0aC5hcHBlbmQodGVzdC5nZXRDbGFzcygpLmdldE5hbWUoKS5yZXBsYWNlKCcuJywgRmlsZS5zZXBhcmF0b3JDaGFyKSk7CisgICAgICAgIHBhdGguYXBwZW5kKHRvQXBwZW5kKTsKKworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IFNlcmlhbGl6YXRpb25UZXN0LmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0ocGF0aC50b1N0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiRmFpbGVkIHRvIGxvYWQgc2VyaWFsaXphdGlvbiByZXNvdXJjZSBmaWxlOiAiICsgcGF0aCwgaW4pOworICAgICAgICByZXR1cm4gZ2V0T2JqZWN0RnJvbVN0cmVhbShpbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBnb2xkZW4gZmlsZS4KKyAgICAgKgorICAgICAqIFRoZSBmb2xkZXIgZm9yIGNyZWF0ZWQgZmlsZSBpczogPGNvZGU+cm9vdCArIHRlc3QncyBwYWNrYWdlIG5hbWU8L2NvZGU+LgorICAgICAqIFRoZSBmaWxlIG5hbWUgaXM6IDxjb2RlPnRlc3QncyBuYW1lICsgImdvbGRlbi5zZXIiPC9jb2RlPgorICAgICAqCisgICAgICogQHBhcmFtIHJvb3QgLSByb290IGRpcmVjdG9yeSBmb3Igc2VyaWFsaXphdGlvbiByZXNvdXJjZSBmaWxlcworICAgICAqIEBwYXJhbSB0ZXN0IC0gdGVzdCBjYXNlCisgICAgICogQHBhcmFtIG9iamVjdCAtIHRvIGJlIHNlcmlhbGl6ZWQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIC0gaWYgSS9PIGVycm9yCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGNyZWF0ZUdvbGRlbkZpbGUoU3RyaW5nIHJvb3QsIFRlc3RDYXNlIHRlc3QsIE9iamVjdCBvYmplY3QpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgZ29sZGVuUGF0aCA9ICh0ZXN0LmdldENsYXNzKCkuZ2V0TmFtZSgpLnJlcGxhY2UoJy4nLCBGaWxlLnNlcGFyYXRvckNoYXIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIi5nb2xkZW4uc2VyIik7CisgICAgICAgIGlmIChyb290ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGdvbGRlblBhdGggPSByb290ICsgRmlsZS5zZXBhcmF0b3JDaGFyICsgZ29sZGVuUGF0aDsKKyAgICAgICAgfQorCisgICAgICAgIEZpbGUgZ29sZGVuRmlsZSA9IG5ldyBGaWxlKGdvbGRlblBhdGgpOworICAgICAgICBnb2xkZW5GaWxlLmdldFBhcmVudEZpbGUoKS5ta2RpcnMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ291bGQgbm90IGNyZWF0ZSAiICsgZ29sZGVuRmlsZS5nZXRQYXJlbnRGaWxlKCksCisgICAgICAgICAgICAgICAgICAgZ29sZGVuRmlsZS5nZXRQYXJlbnRGaWxlKCkuaXNEaXJlY3RvcnkoKSk7CisgICAgICAgIGdvbGRlbkZpbGUuY3JlYXRlTmV3RmlsZSgpOworICAgICAgICBwdXRPYmplY3RUb1N0cmVhbShvYmplY3QsIG5ldyBGaWxlT3V0cHV0U3RyZWFtKGdvbGRlbkZpbGUpKTsKKworICAgICAgICAvLyBkb24ndCBmb3JnZXQgdG8gcmVtb3ZlIGl0IGZyb20gdGVzdCBjYXNlIGFmdGVyIHVzaW5nCisgICAgICAgIGZhaWwoIkdlbmVyYXRpbmcgZ29sZGVuIGZpbGUuIEdvbGRlbiBmaWxlIG5hbWU6ICIgKyBnb2xkZW5GaWxlLmdldEFic29sdXRlUGF0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3BpZXMgYW4gb2JqZWN0IGJ5IHNlcmlhbGl6aW5nL2Rlc2VyaWFsaXppbmcgaXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5pdGlhbCAtIGFuIG9iamVjdCB0byBiZSBjb3BpZWQKKyAgICAgKiBAcmV0dXJuIGNvcHkgb2YgcHJvdmlkZWQgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTZXJpYWxpemFibGUgY29weVNlcmlhbGl6YWJsZShTZXJpYWxpemFibGUgaW5pdGlhbCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgIHB1dE9iamVjdFRvU3RyZWFtKGluaXRpYWwsIG91dCk7CisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG91dC50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgcmV0dXJuIGdldE9iamVjdEZyb21TdHJlYW0oaW4pOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC90ZXN0cy9zdXBwb3J0L0tleU1hbmFnZXJGYWN0b3J5U3BpSW1wbC5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Rlc3RzL3N1cHBvcnQvS2V5TWFuYWdlckZhY3RvcnlTcGlJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjQyN2Y4NAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC90ZXN0cy9zdXBwb3J0L0tleU1hbmFnZXJGYWN0b3J5U3BpSW1wbC5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQudGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5VbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uOworCitpbXBvcnQgamF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzOworCitwdWJsaWMgY2xhc3MgS2V5TWFuYWdlckZhY3RvcnlTcGlJbXBsIGV4dGVuZHMgTXlLZXlNYW5hZ2VyRmFjdG9yeVNwaSB7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNJbml0aWFsaXplZCA9IGZhbHNlOworCisgICAgcHVibGljIHZvaWQgZW5naW5lSW5pdChLZXlTdG9yZSBrcywgY2hhcltdIHBhc3N3b3JkKQorICAgICAgICAgICAgdGhyb3dzIEtleVN0b3JlRXhjZXB0aW9uLCBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sCisgICAgICAgICAgICBVbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uIHsKKworICAgICAgICBpZiAoa3MgPT0gbnVsbCAmJiBwYXNzd29yZCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoa3MgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEtleVN0b3JlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAocGFzc3dvcmQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGlzSW5pdGlhbGl6ZWQgPSB0cnVlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVuZ2luZUluaXQoTWFuYWdlckZhY3RvcnlQYXJhbWV0ZXJzIHNwZWMpCisgICAgICAgICAgICB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzcGVjID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uKCJJbmNvcnJlY3QgcGFyYW1ldGVyIik7CisgICAgICAgIH0KKyAgICAgICAgaXNJbml0aWFsaXplZCA9IHRydWU7CisgICAgfQorCisgICAgcHVibGljIEtleU1hbmFnZXJbXSBlbmdpbmVHZXRLZXlNYW5hZ2VycygpIHsKKyAgICAgICAgaWYoIWlzSW5pdGlhbGl6ZWQpCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJLZXlNYW5hZ2VyRmFjdG9yeUltcGwgaXMgbm90IGluaXRpYWxpemVkIik7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC90ZXN0cy9zdXBwb3J0L015S2V5TWFuYWdlckZhY3RvcnlTcGkuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC90ZXN0cy9zdXBwb3J0L015S2V5TWFuYWdlckZhY3RvcnlTcGkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hODJiYjlhCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Rlc3RzL3N1cHBvcnQvTXlLZXlNYW5hZ2VyRmFjdG9yeVNwaS5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQudGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5U3RvcmVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5VbnJlY292ZXJhYmxlS2V5RXhjZXB0aW9uOworCitpbXBvcnQgamF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuS2V5TWFuYWdlckZhY3RvcnlTcGk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5NYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnM7CisKKy8qKgorICogQ2xhc3MgZm9yIHZlcmlmaWNhdGlvbiBLZXlNYW5hZ2VyRmFjdG9yeVNwaSBhbmQgS2V5TWFuYWdlckZhY3RvcnkKKyAqIGZ1bmN0aW9uYWxpdHkKKyAqCisgKi8KKworcHVibGljIGNsYXNzIE15S2V5TWFuYWdlckZhY3RvcnlTcGkgZXh0ZW5kcyBLZXlNYW5hZ2VyRmFjdG9yeVNwaSB7CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0KEtleVN0b3JlIGtzLCBjaGFyW10gcGFzc3dvcmQpCisgICAgICAgICAgICB0aHJvd3MgS2V5U3RvcmVFeGNlcHRpb24sIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiwKKyAgICAgICAgICAgIFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24geworICAgICAgICBpZiAocGFzc3dvcmQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEtleVN0b3JlRXhjZXB0aW9uKCJJbmNvcnJlY3QgcGFzc3dvcmQiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoa3MgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVucmVjb3ZlcmFibGVLZXlFeGNlcHRpb24oIkluY29ycmVjdCBrZXlzdG9yZSIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgZW5naW5lSW5pdChNYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnMgc3BlYykKKyAgICAgICAgICAgIHRocm93cyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNwZWMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24oIkluY29ycmVjdCBwYXJhbWV0ZXIiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3BlYyBpbnN0YW5jZW9mIFBhcmFtZXRlcnMpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZW5naW5lSW5pdCgoKFBhcmFtZXRlcnMpc3BlYykuZ2V0S2V5U3RvcmUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICgoUGFyYW1ldGVycylzcGVjKS5nZXRQYXNzd29yZCgpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24oZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQWxnb3JpdGhtUGFyYW1ldGVyRXhjZXB0aW9uKCJJbnZhbGlkIHBhcmFtZXRlciIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIEtleU1hbmFnZXJbXSBlbmdpbmVHZXRLZXlNYW5hZ2VycygpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgUGFyYW1ldGVycyBpbXBsZW1lbnRzIE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyB7CisgICAgICAgIHByaXZhdGUgS2V5U3RvcmUga2V5U3RvcmU7CisgICAgICAgIHByaXZhdGUgY2hhcltdIHBhc3NXRDsKKyAgICAgICAgcHVibGljIFBhcmFtZXRlcnMgKEtleVN0b3JlIGtzLCBjaGFyW10gcGFzcykgeworICAgICAgICAgICAgdGhpcy5rZXlTdG9yZSA9IGtzOworICAgICAgICAgICAgdGhpcy5wYXNzV0QgPSBwYXNzOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBLZXlTdG9yZSBnZXRLZXlTdG9yZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBrZXlTdG9yZTsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgY2hhcltdIGdldFBhc3N3b3JkKCkgeworICAgICAgICAgICAgcmV0dXJuIHBhc3NXRDsKKyAgICAgICAgfQorICAgIH19CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvdGVzdHMvc3VwcG9ydC9NeVNTTENvbnRleHRTcGkuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC90ZXN0cy9zdXBwb3J0L015U1NMQ29udGV4dFNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU0ZTJhMDMKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvdGVzdHMvc3VwcG9ydC9NeVNTTENvbnRleHRTcGkuamF2YQpAQCAtMCwwICsxLDE1NSBAQAorLyoKKyAqICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC50ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleU1hbmFnZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CitpbXBvcnQgamF2YXgubmV0LnNzbC5LZXlNYW5hZ2VyOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMQ29udGV4dFNwaTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZVJlc3VsdDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFBhcmFtZXRlcnM7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb25Db250ZXh0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0RmFjdG9yeTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlRydXN0TWFuYWdlcjsKKworLyoqCisgKiBBZGRpdGlvbmFsIGNsYXNzIGZvciB2ZXJpZmljYXRpb24gb2YgU1NMQ29udGV4dFNwaSBhbmQgU1NMQ29udGV4dAorICogZnVuY3Rpb25hbGl0eQorICoKKyAqLworCitwdWJsaWMgY2xhc3MgTXlTU0xDb250ZXh0U3BpIGV4dGVuZHMgU1NMQ29udGV4dFNwaSB7CisgICAgcHJpdmF0ZSBib29sZWFuIGluaXQgPSBmYWxzZTsKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0KEtleU1hbmFnZXJbXSBrbSwgVHJ1c3RNYW5hZ2VyW10gdG0sCisgICAgICAgICAgICBTZWN1cmVSYW5kb20gc3IpIHRocm93cyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBLZXlNYW5hZ2VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAic2VjdXJlUmFuZG9tIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBpbml0ID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgU1NMU29ja2V0RmFjdG9yeSBlbmdpbmVHZXRTb2NrZXRGYWN0b3J5KCkgeworICAgICAgICBpZiAoIWluaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW5pdGlhbGlhemVkIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHJvdGVjdGVkIFNTTFNlcnZlclNvY2tldEZhY3RvcnkgZW5naW5lR2V0U2VydmVyU29ja2V0RmFjdG9yeSgpIHsKKyAgICAgICAgaWYgKCFpbml0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGluaXRpYWxpYXplZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHByb3RlY3RlZCBTU0xTZXNzaW9uQ29udGV4dCBlbmdpbmVHZXRTZXJ2ZXJTZXNzaW9uQ29udGV4dCgpIHsKKyAgICAgICAgaWYgKCFpbml0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGluaXRpYWxpYXplZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHByb3RlY3RlZCBTU0xTZXNzaW9uQ29udGV4dCBlbmdpbmVHZXRDbGllbnRTZXNzaW9uQ29udGV4dCgpIHsKKyAgICAgICAgaWYgKCFpbml0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGluaXRpYWxpYXplZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHByb3RlY3RlZCBTU0xQYXJhbWV0ZXJzIGVuZ2luZUdldERlZmF1bHRTU0xQYXJhbWV0ZXJzKCkgeworICAgICAgICBlbmdpbmVHZXRTb2NrZXRGYWN0b3J5KCk7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHByb3RlY3RlZCBTU0xQYXJhbWV0ZXJzIGVuZ2luZUdldFN1cHBvcnRlZFNTTFBhcmFtZXRlcnMoKSB7CisgICAgICAgIGVuZ2luZUdldFNvY2tldEZhY3RvcnkoKTsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBGSVhNRTogYWRkIHRoZXNlIG1ldGhvZHMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU1NMRW5naW5lIGVuZ2luZUNyZWF0ZVNTTEVuZ2luZShTdHJpbmcgaG9zdCwgaW50IHBvcnQpIHsKKyAgICAgICAgaWYgKCFpbml0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGluaXRpYWxpYXplZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgdG1wU1NMRW5naW5lKGhvc3QsIHBvcnQpOworICAgIH0KKworICAgIHByb3RlY3RlZCBTU0xFbmdpbmUgZW5naW5lQ3JlYXRlU1NMRW5naW5lKCkgeworICAgICAgICBpZiAoIWluaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW5pdGlhbGlhemVkIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyB0bXBTU0xFbmdpbmUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgY2xhc3MgdG1wU1NMRW5naW5lIGV4dGVuZHMgU1NMRW5naW5lIHsKKyAgICAgICAgU3RyaW5nIHRtcEhvc3Q7CisgICAgICAgIGludCB0bXBQb3J0OworICAgICAgICBwdWJsaWMgdG1wU1NMRW5naW5lKCkgeworICAgICAgICAgICAgdG1wSG9zdCA9IG51bGw7CisgICAgICAgICAgICB0bXBQb3J0ID0gMDsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgdG1wU1NMRW5naW5lKFN0cmluZyBob3N0LCBpbnQgcG9ydCkgeworICAgICAgICAgICAgdG1wSG9zdCA9IGhvc3Q7CisgICAgICAgICAgICB0bXBQb3J0ID0gcG9ydDsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFBlZXJIb3N0KCkgeworICAgICAgICAgICAgcmV0dXJuIHRtcEhvc3Q7CisgICAgICAgIH0KKyAgICAgICAgcHVibGljIGludCBnZXRQZWVyUG9ydCgpIHsKKyAgICAgICAgICAgIHJldHVybiB0bXBQb3J0OworICAgICAgICB9CisgICAgICAgIHB1YmxpYyB2b2lkIGJlZ2luSGFuZHNoYWtlKCkgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7IH0KKyAgICAgICAgcHVibGljIHZvaWQgY2xvc2VJbmJvdW5kKCkgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7IH0KKyAgICAgICAgcHVibGljIHZvaWQgY2xvc2VPdXRib3VuZCgpIHt9CisgICAgICAgIHB1YmxpYyBSdW5uYWJsZSBnZXREZWxlZ2F0ZWRUYXNrKCkgeyByZXR1cm4gbnVsbDsgfQorICAgICAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RW5hYmxlZENpcGhlclN1aXRlcygpIHsgcmV0dXJuIG51bGw7IH0KKyAgICAgICAgcHVibGljIFN0cmluZ1tdIGdldEVuYWJsZWRQcm90b2NvbHMoKSB7cmV0dXJuIG51bGw7IH0KKyAgICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RW5hYmxlU2Vzc2lvbkNyZWF0aW9uKCkgeyByZXR1cm4gdHJ1ZTsgfQorICAgICAgICBwdWJsaWMgU1NMRW5naW5lUmVzdWx0LkhhbmRzaGFrZVN0YXR1cyBnZXRIYW5kc2hha2VTdGF0dXMoKSB7IHJldHVybiBudWxsOyB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGdldE5lZWRDbGllbnRBdXRoKCkgeyByZXR1cm4gdHJ1ZTsgfQorICAgICAgICBwdWJsaWMgU1NMU2Vzc2lvbiBnZXRTZXNzaW9uKCkgeyByZXR1cm4gbnVsbDsgfQorICAgICAgICBwdWJsaWMgU3RyaW5nW10gZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkgIHsgcmV0dXJuIG51bGw7IH0KKyAgICAgICAgcHVibGljIFN0cmluZ1tdIGdldFN1cHBvcnRlZFByb3RvY29scygpICB7IHJldHVybiBudWxsOyB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGdldFVzZUNsaWVudE1vZGUoKSAgeyByZXR1cm4gdHJ1ZTsgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBnZXRXYW50Q2xpZW50QXV0aCgpICB7IHJldHVybiB0cnVlOyB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzSW5ib3VuZERvbmUoKSAgeyByZXR1cm4gdHJ1ZTsgfQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc091dGJvdW5kRG9uZSgpICB7IHJldHVybiB0cnVlOyB9CisgICAgICAgIHB1YmxpYyB2b2lkIHNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoU3RyaW5nW10gc3VpdGVzKSB7IH0KKyAgICAgICAgcHVibGljIHZvaWQgc2V0RW5hYmxlZFByb3RvY29scyhTdHJpbmdbXSBwcm90b2NvbHMpIHsgfQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRFbmFibGVTZXNzaW9uQ3JlYXRpb24oYm9vbGVhbiBmbGFnKSB7IH0KKyAgICAgICAgcHVibGljIHZvaWQgc2V0TmVlZENsaWVudEF1dGgoYm9vbGVhbiBuZWVkKSB7IH0KKyAgICAgICAgcHVibGljIHZvaWQgc2V0VXNlQ2xpZW50TW9kZShib29sZWFuIG1vZGUpIHsgfQorICAgICAgICBwdWJsaWMgdm9pZCBzZXRXYW50Q2xpZW50QXV0aChib29sZWFuIHdhbnQpIHsgfQorICAgICAgICBwdWJsaWMgU1NMRW5naW5lUmVzdWx0IHVud3JhcChCeXRlQnVmZmVyIHNyYywgQnl0ZUJ1ZmZlcltdIGRzdHMsCisgICAgICAgICAgICAgICAgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBwdWJsaWMgU1NMRW5naW5lUmVzdWx0IHdyYXAoQnl0ZUJ1ZmZlcltdIHNyY3MsIGludCBvZmZzZXQsCisgICAgICAgICAgICAgICAgaW50IGxlbmd0aCwgQnl0ZUJ1ZmZlciBkc3QpIHRocm93cyBTU0xFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvdGVzdHMvc3VwcG9ydC9NeVRydXN0TWFuYWdlckZhY3RvcnlTcGkuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC90ZXN0cy9zdXBwb3J0L015VHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmOWZhODYKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvdGVzdHMvc3VwcG9ydC9NeVRydXN0TWFuYWdlckZhY3RvcnlTcGkuamF2YQpAQCAtMCwwICsxLDcxIEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlRXhjZXB0aW9uOworCitpbXBvcnQgamF2YXgubmV0LnNzbC5NYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXI7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXJGYWN0b3J5U3BpOworCisvKioKKyAqIENsYXNzIGZvciB2ZXJ0aWZ5aW5nIFRydXN0TWFuYWdlckZhY3RvcnlTcGkgYW5kIFRydXN0TWFuYWdlckZhY3RvcnkKKyAqIGZ1bmN0aW9uYWxpdHkKKyAqCisgKi8KKworcHVibGljIGNsYXNzIE15VHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaSBleHRlbmRzIFRydXN0TWFuYWdlckZhY3RvcnlTcGkgeworICAgIHByb3RlY3RlZCB2b2lkIGVuZ2luZUluaXQoS2V5U3RvcmUga3MpIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChrcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgS2V5U3RvcmVFeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQgb3BlcmF0aW9uIGZvciBudWxsIEtleVN0b3JlIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBlbmdpbmVJbml0KE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyBzcGVjKQorICAgICAgICAgICAgdGhyb3dzIEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24geworICAgICAgICBpZiAoc3BlYyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbigiTnVsbCBwYXJhbWV0ZXIiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3BlYyBpbnN0YW5jZW9mIFBhcmFtZXRlcnMpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZW5naW5lSW5pdCgoKFBhcmFtZXRlcnMpc3BlYykuZ2V0S2V5U3RvcmUoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChLZXlTdG9yZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbigiSW52YWxpZCBwYXJhbWV0ZXIiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCBUcnVzdE1hbmFnZXJbXSBlbmdpbmVHZXRUcnVzdE1hbmFnZXJzKCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgUGFyYW1ldGVycyBpbXBsZW1lbnRzIE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyB7CisgICAgICAgIHByaXZhdGUgS2V5U3RvcmUga2V5U3RvcmU7CisgICAgICAgIHB1YmxpYyBQYXJhbWV0ZXJzIChLZXlTdG9yZSBrcykgeworICAgICAgICAgICAgdGhpcy5rZXlTdG9yZSA9IGtzOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBLZXlTdG9yZSBnZXRLZXlTdG9yZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBrZXlTdG9yZTsKKyAgICAgICAgfQorICAgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvdGVzdHMvc3VwcG9ydC9TU0xDb250ZXh0U3BpSW1wbC5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Rlc3RzL3N1cHBvcnQvU1NMQ29udGV4dFNwaUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MjQyYTBhCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Rlc3RzL3N1cHBvcnQvU1NMQ29udGV4dFNwaUltcGwuamF2YQpAQCAtMCwwICsxLDgxIEBACitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleU1hbmFnZW1lbnRFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5TZWN1cmVSYW5kb207CisKK2ltcG9ydCBqYXZheC5uZXQuc3NsLktleU1hbmFnZXI7CisvL2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTENvbnRleHRTcGk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xFbmdpbmU7CisvKmltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEVuZ2luZVJlc3VsdDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb247Ki8KK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb25Db250ZXh0OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2VydmVyU29ja2V0RmFjdG9yeTsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXI7CisKK3B1YmxpYyBjbGFzcyBTU0xDb250ZXh0U3BpSW1wbCBleHRlbmRzIE15U1NMQ29udGV4dFNwaSB7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaW5pdCA9IGZhbHNlOworCisgICAgcHVibGljIHZvaWQgZW5naW5lSW5pdChLZXlNYW5hZ2VyW10ga20sIFRydXN0TWFuYWdlcltdIHRtLAorICAgICAgICAgICAgU2VjdXJlUmFuZG9tIHNyKSB0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgInNlY3VyZVJhbmRvbSBpcyBudWxsIik7CisgICAgICAgIH0KKyAgICAgICAgaW5pdCA9IHRydWU7CisgICAgfQorCisgICAgcHVibGljIFNTTFNvY2tldEZhY3RvcnkgZW5naW5lR2V0U29ja2V0RmFjdG9yeSgpIHsKKyAgICAgICAgaWYgKCFpbml0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGluaXRpYWxpYXplZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBTU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5IGVuZ2luZUdldFNlcnZlclNvY2tldEZhY3RvcnkoKSB7CisgICAgICAgIGlmICghaW5pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbml0aWFsaWF6ZWQiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgU1NMU2Vzc2lvbkNvbnRleHQgZW5naW5lR2V0U2VydmVyU2Vzc2lvbkNvbnRleHQoKSB7CisgICAgICAgIGlmICghaW5pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbml0aWFsaWF6ZWQiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgU1NMU2Vzc2lvbkNvbnRleHQgZW5naW5lR2V0Q2xpZW50U2Vzc2lvbkNvbnRleHQoKSB7CisgICAgICAgIGlmICghaW5pdCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbml0aWFsaWF6ZWQiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEZJWE1FOiBhZGQgdGhlc2UgbWV0aG9kcworICAgICAqLworICAgIHB1YmxpYyBTU0xFbmdpbmUgZW5naW5lQ3JlYXRlU1NMRW5naW5lKFN0cmluZyBob3N0LCBpbnQgcG9ydCkgeworICAgICAgICBpbnQgbWF4ID0gNjU1MzU7CisKKyAgICAgICAgaWYgKHBvcnQgPCAwIHx8IHBvcnQgPiBtYXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklsbGVnYWwgcG9ydCIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFpbml0KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IGluaXRpYWxpYXplZCIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgdG1wU1NMRW5naW5lKGhvc3QsIHBvcnQpOworICAgIH0KKworICAgIHB1YmxpYyBTU0xFbmdpbmUgZW5naW5lQ3JlYXRlU1NMRW5naW5lKCkgeworICAgICAgICBpZiAoIWluaXQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW5pdGlhbGlhemVkIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyB0bXBTU0xFbmdpbmUoKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC90ZXN0cy9zdXBwb3J0L1NTTFNvY2tldEZhY3RvcnlJbXBsLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvdGVzdHMvc3VwcG9ydC9TU0xTb2NrZXRGYWN0b3J5SW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIzZGVlYjkKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvdGVzdHMvc3VwcG9ydC9TU0xTb2NrZXRGYWN0b3J5SW1wbC5qYXZhCkBAIC0wLDAgKzEsODEgQEAKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYXJtb255LnhuZXQudGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0RmFjdG9yeTsKKworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uOworCisKK3B1YmxpYyBjbGFzcyBTU0xTb2NrZXRGYWN0b3J5SW1wbCBleHRlbmRzIFNTTFNvY2tldEZhY3RvcnkgeworCisgICAgcHVibGljIFNTTFNvY2tldEZhY3RvcnlJbXBsKCkgeworICAgICAgICBzdXBlcigpOworICAgIH0KKworICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KFNvY2tldCBzb2NrZXQsIFN0cmluZyBzLCBpbnQgaSwgYm9vbGVhbiBmbGFnKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzb2NrZXQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJpbmNvcnJlY3Qgc29ja2V0Iik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGkgPCAwIHx8IGkgPiA2NTUzNSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJpbmNvcnJlY3QgcG9ydCIpOworICAgICAgICB9CisgICAgICAgIGlmIChzID09IG51bGwgfHwgcy5lcXVhbHMoIiIpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5rbm93bkhvc3RFeGNlcHRpb24oImluY29ycmVjdCBob3N0Iik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWZsYWcpIHsKKyAgICAgICAgICAgIHNvY2tldCA9IG5ldyBTb2NrZXQocywgaSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzb2NrZXQgPSBuZXcgU29ja2V0KHMsIGkpOworICAgICAgICAgICAgc29ja2V0LmNsb3NlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNvY2tldDsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZ1tdIGdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZheC5uZXQuU29ja2V0RmFjdG9yeSNjcmVhdGVTb2NrZXQoamF2YS5sYW5nLlN0cmluZywgaW50KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KFN0cmluZyBhcmcwLCBpbnQgYXJnMSkgdGhyb3dzIElPRXhjZXB0aW9uLCBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIGl0IGlzIGEgZmFrZQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5I2NyZWF0ZVNvY2tldChqYXZhLm5ldC5JbmV0QWRkcmVzcywgaW50KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzIGFyZzAsIGludCBhcmcxKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBpdCBpcyBhIGZha2UKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZheC5uZXQuU29ja2V0RmFjdG9yeSNjcmVhdGVTb2NrZXQoamF2YS5sYW5nLlN0cmluZywgaW50LCBqYXZhLm5ldC5JbmV0QWRkcmVzcywgaW50KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KFN0cmluZyBhcmcwLCBpbnQgYXJnMSwgSW5ldEFkZHJlc3MgYXJnMiwgaW50IGFyZzMpIHRocm93cyBJT0V4Y2VwdGlvbiwgVW5rbm93bkhvc3RFeGNlcHRpb24geworICAgICAgICAvLyBpdCBpcyBhIGZha2UKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZheC5uZXQuU29ja2V0RmFjdG9yeSNjcmVhdGVTb2NrZXQoamF2YS5uZXQuSW5ldEFkZHJlc3MsIGludCwgamF2YS5uZXQuSW5ldEFkZHJlc3MsIGludCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcyBhcmcwLCBpbnQgYXJnMSwgSW5ldEFkZHJlc3MgYXJnMiwgaW50IGFyZzMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vIGl0IGlzIGEgZmFrZQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvdGVzdHMvc3VwcG9ydC9UcnVzdE1hbmFnZXJGYWN0b3J5U3BpSW1wbC5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Rlc3RzL3N1cHBvcnQvVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaUltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OWJiMDVjCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Rlc3RzL3N1cHBvcnQvVHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaUltcGwuamF2YQpAQCAtMCwwICsxLDUyIEBACitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlTdG9yZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlRXhjZXB0aW9uOworCitpbXBvcnQgamF2YXgubmV0LnNzbC5NYW5hZ2VyRmFjdG9yeVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YXgubmV0LnNzbC5UcnVzdE1hbmFnZXI7CisKK3B1YmxpYyBjbGFzcyBUcnVzdE1hbmFnZXJGYWN0b3J5U3BpSW1wbCBleHRlbmRzIE15VHJ1c3RNYW5hZ2VyRmFjdG9yeVNwaSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzZW5naW5lSW5pdENhbGxlZCA9IGZhbHNlOworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNFbmdpbmVHZXRUcnVzdE1hbmFnZXJzQ2FsbGVkID0gZmFsc2U7CisgICAgcHJpdmF0ZSBzdGF0aWMgS2V5U3RvcmUga3MgPSBudWxsOworICAgIHByaXZhdGUgc3RhdGljIE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyBzcGVjID0gbnVsbDsKKworICAgIHB1YmxpYyB2b2lkIGVuZ2luZUluaXQoS2V5U3RvcmUga3MpIHRocm93cyBLZXlTdG9yZUV4Y2VwdGlvbiB7CisgICAgICAgIGlzZW5naW5lSW5pdENhbGxlZCA9IHRydWU7CisgICAgICAgIHRoaXMua3MgPSBrczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmdpbmVJbml0KE1hbmFnZXJGYWN0b3J5UGFyYW1ldGVycyBzcGVjKSB0aHJvd3MgSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiB7CisgICAgICAgIGlzZW5naW5lSW5pdENhbGxlZCA9IHRydWU7CisgICAgICAgIHRoaXMuc3BlYyA9IHNwZWM7CisgICAgfQorCisgICAgcHVibGljIFRydXN0TWFuYWdlcltdIGVuZ2luZUdldFRydXN0TWFuYWdlcnMoKSB7CisgICAgICAgIGlzRW5naW5lR2V0VHJ1c3RNYW5hZ2Vyc0NhbGxlZCA9IHRydWU7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgICAgICBpc2VuZ2luZUluaXRDYWxsZWQgPSBmYWxzZTsKKyAgICAgICAgaXNFbmdpbmVHZXRUcnVzdE1hbmFnZXJzQ2FsbGVkID0gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNFbmdpbmVHZXRUcnVzdE1hbmFnZXJzQ2FsbGVkKCkgeworICAgICAgICByZXR1cm4gaXNFbmdpbmVHZXRUcnVzdE1hbmFnZXJzQ2FsbGVkOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzRW5naW5lSW5pdENhbGxlZCgpIHsKKyAgICAgICAgcmV0dXJuIGlzZW5naW5lSW5pdENhbGxlZDsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEtzKCkgeworICAgICAgICByZXR1cm4ga3M7CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRTcGVjKCkgeworICAgICAgICByZXR1cm4gc3BlYzsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvdGVzdHMvc3VwcG9ydC9YNTA5S2V5TWFuYWdlckltcGwuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC90ZXN0cy9zdXBwb3J0L1g1MDlLZXlNYW5hZ2VySW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFkZTk5ZDIKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvdGVzdHMvc3VwcG9ydC9YNTA5S2V5TWFuYWdlckltcGwuamF2YQpAQCAtMCwwICsxLDIyNSBAQAorcGFja2FnZSBvcmcuYXBhY2hlLmhhcm1vbnkueG5ldC50ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVN0b3JlOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5QcmluY2lwYWw7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKKworaW1wb3J0IGphdmF4Lm5ldC5zc2wuWDUwOUtleU1hbmFnZXI7CisKK3B1YmxpYyBjbGFzcyBYNTA5S2V5TWFuYWdlckltcGwgaW1wbGVtZW50cyBYNTA5S2V5TWFuYWdlciB7CisKKyAgICBwcml2YXRlIFN0cmluZyBrZXlUeXBlOworICAgIHByaXZhdGUgU3RyaW5nIGNsaWVudCA9ICJDTElFTlQiOworICAgIHByaXZhdGUgU3RyaW5nIHNlcnZlciA9ICJTRVJWRVIiOworICAgIHByaXZhdGUgS2V5U3RvcmUga2V5VGVzdDsKKyAgICBwcml2YXRlIFg1MDlDZXJ0aWZpY2F0ZVtdIGNlcnQgPSBudWxsOworCisgICAgLy8gY3JlYXRpbmcgYSBjZXJ0aWZpY2F0ZQorICAgIFN0cmluZyBjZXJ0aWZpY2F0ZSA9ICItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbiIKKyAgICAgICAgICAgICsgIk1JSUNaVENDQWRJQ0JRTDNBQUMyTUEwR0NTcUdTSWIzRFFFQkFnVUFNRjh4Q3pBSkJnTlZCQVlUQWxWVE1TQXdcbiIKKyAgICAgICAgICAgICsgIkhnWURWUVFLRXhkU1UwRWdSR0YwWVNCVFpXTjFjbWwwZVN3Z1NXNWpMakV1TUN3R0ExVUVDeE1sVTJWamRYSmxcbiIKKyAgICAgICAgICAgICsgIklGTmxjblpsY2lCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVEFlRncwNU56QXlNakF3TURBd01EQmFcbiIKKyAgICAgICAgICAgICsgIkZ3MDVPREF5TWpBeU16VTVOVGxhTUlHV01Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZcbiIKKyAgICAgICAgICAgICsgImNtNXBZVEVTTUJBR0ExVUVCeE1KVUdGc2J5QkJiSFJ2TVI4d0hRWURWUVFLRXhaVGRXNGdUV2xqY205emVYTjBcbiIKKyAgICAgICAgICAgICsgIlpXMXpMQ0JKYm1NdU1TRXdId1lEVlFRTEV4aFVaWE4wSUdGdVpDQkZkbUZzZFdGMGFXOXVJRTl1YkhreEdqQVlcbiIKKyAgICAgICAgICAgICsgIkJnTlZCQU1URVdGeVoyOXVMbVZ1Wnk1emRXNHVZMjl0TUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JcbiIKKyAgICAgICAgICAgICsgImlRS0JnUUNvZm1kWStQaVVXTjAxRk96RWV3ZitHYUcrbEZmMTMyVXB6QVRtWUprQTRBRUEvanVXN2pTaStMSmtcbiIKKyAgICAgICAgICAgICsgIndKS2k1R080Unlab3lpbUFMLzV5SVdEVjZsMUtsdnh5S3NscjBSRWhNQmFELzNaM0VzTFRURWY1Z1ZyUVM2c1RcbiIKKyAgICAgICAgICAgICsgIldNb1NaQXl6QjM5a0Zmc0I2b1VYTnRWOCtVS0t4U3hLYnh2aFFuMjY3UGVDejVWWDJRSURBUUFCTUEwR0NTcUdcbiIKKyAgICAgICAgICAgICsgIlNJYjNEUUVCQWdVQUEzNEFYbDNhdDZsdWlWLzdJOU1ONUNYWW9QSllJOEJjZGMxaEJhZ0p2VE1jbWxxTDJ1T1pcbiIKKyAgICAgICAgICAgICsgIkg5VDVoTk1FTDlUazZhSTd5WlBYY3cveEkySzZwT1IvRnJNcDBVd0ptZHhYN2xqVjZadFVaZjdwWTQ5MlVxd0NcbiIKKyAgICAgICAgICAgICsgIjE3NzdYUTlVRVp5cktKdkY1bnRsZWVPMGF5QnFMR1ZLQ1d6V1pYOVlzWENwdjQ3Rk5MWmJ1cEU9XG4iCisgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iOworCisgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gY2VydEFycmF5ID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNlcnRpZmljYXRlCisgICAgICAgICAgICAuZ2V0Qnl0ZXMoKSk7CisKKyAgICBTdHJpbmcgY2VydGlmaWNhdGUyID0gIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxuIgorICAgICAgICAgICAgKyAiTUlJQ1p6Q0NBZENnQXdJQkFnSUJHekFOQmdrcWhraUc5dzBCQVFVRkFEQmhNUXN3Q1FZRFZRUUdFd0pWVXpFWVxuIgorICAgICAgICAgICAgKyAiTUJZR0ExVUVDaE1QVlM1VExpQkhiM1psY201dFpXNTBNUXd3Q2dZRFZRUUxFd05FYjBReEREQUtCZ05WQkFzVFxuIgorICAgICAgICAgICAgKyAiQTFCTFNURWNNQm9HQTFVRUF4TVRSRzlFSUZCTFNTQk5aV1FnVW05dmRDQkRRVEFlRncwNU9EQTRNRE15TWpBeVxuIgorICAgICAgICAgICAgKyAiTWpsYUZ3MHdPREE0TURReU1qQXlNamxhTUdFeEN6QUpCZ05WQkFZVEFsVlRNUmd3RmdZRFZRUUtFdzlWTGxNdVxuIgorICAgICAgICAgICAgKyAiSUVkdmRtVnlibTFsYm5ReEREQUtCZ05WQkFzVEEwUnZSREVNTUFvR0ExVUVDeE1EVUV0Sk1Sd3dHZ1lEVlFRRFxuIgorICAgICAgICAgICAgKyAiRXhORWIwUWdVRXRKSUUxbFpDQlNiMjkwSUVOQk1JR2ZNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCaVFLQlxuIgorICAgICAgICAgICAgKyAiZ1FEYnJNL0o5RnJKU1grenhGVWJzSTlWdzVRYmd1VkJJYTk1cndXLzBNOCtzTTByNWdkK0RZNml1Ym02d25Ya1xuIgorICAgICAgICAgICAgKyAiQ1N2YmZRbEZFRFNLcjRXWWVlR3ArZDlXbERuUWR0REZMZEE0NXRDaTVTSGpuVytoR0FtWm5sZDByejZ3UWVrRlxuIgorICAgICAgICAgICAgKyAiNXhRYWE1QTZ3amhNbExPamJoMjd6eXNjcm9yTUoxTzVGQk9XbkVIY1J2NnhxUUlEQVFBQm95OHdMVEFkQmdOVlxuIgorICAgICAgICAgICAgKyAiSFE0RUZnUVVWcm1ZUjZtOTcwMWNIUTNyNWtYeUc3enNDTjB3REFZRFZSMFRCQVV3QXdFQi96QU5CZ2txaGtpR1xuIgorICAgICAgICAgICAgKyAiOXcwQkFRVUZBQU9CZ1FEVlgxWTBZcUM3dmVrZVpqVnh0eXVDOE1ueGJyejZEMTA5QVgwN0xFSVJ6Tll6d1owd1xuIgorICAgICAgICAgICAgKyAiTVRJbVNwOXNFeldXKzNGdWVCSVU3QXhHeXMyTzdYMHFtTjN6Z3N6UGZTaW9jQnVRdVhJWVFjdEpoS2pGNUtWY1xuIgorICAgICAgICAgICAgKyAiVkdRUllZbHQrbXlobDJ2eTZ5UHpFVkNqaUt3TUViMVNwdTBpckNmK2xGVzJoc2Rqdm1TUU10WnZPdz09XG4iCisgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iOworCisgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gY2VydEFycmF5MiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShjZXJ0aWZpY2F0ZTIKKyAgICAgICAgICAgIC5nZXRCeXRlcygpKTsKKworICAgIFN0cmluZyBjZXJ0aWZpY2F0ZTMgPSAiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG4iCisgICAgICAgICAgICArICJNSUlEWERDQ0FzV2dBd0lCQWdJQlNqQU5CZ2txaGtpRzl3MEJBUVVGQURCV01Rc3dDUVlEVlFRR0V3SlZVekVZXG4iCisgICAgICAgICAgICArICJNQllHQTFVRUNoTVBWUzVUTGlCSGIzWmxjbTV0Wlc1ME1Rd3dDZ1lEVlFRTEV3TkViMFF4RERBS0JnTlZCQXNUXG4iCisgICAgICAgICAgICArICJBMUJMU1RFUk1BOEdBMVVFQXhNSVRXVmtJRU5CTFRFd0hoY05PVGd3T0RBeU1UZ3dNalF3V2hjTk1ERXdPREF5XG4iCisgICAgICAgICAgICArICJNVGd3TWpRd1dqQjBNUXN3Q1FZRFZRUUdFd0pWVXpFWU1CWUdBMVVFQ2hNUFZTNVRMaUJIYjNabGNtNXRaVzUwXG4iCisgICAgICAgICAgICArICJNUXd3Q2dZRFZRUUxFd05FYjBReEREQUtCZ05WQkFzVEExQkxTVEVOTUFzR0ExVUVDeE1FVlZOQlJqRWdNQjRHXG4iCisgICAgICAgICAgICArICJBMVVFQXhNWFIzVnRZbmt1U205elpYQm9MakF3TURBd01EVXdORFF3Z1o4d0RRWUpLb1pJaHZjTkFRRUJCUUFEXG4iCisgICAgICAgICAgICArICJnWTBBTUlHSkFvR0JBTFQvUjdiUHFzMWMxWXFYQWc1SE5wWkxnVzJIdUFjN1JDYVAwNmNFNFI0NEdCTHcvZlFjXG4iCisgICAgICAgICAgICArICJWUk5MbjVwZ2JUWHNEbmppWlZkOHFFZ1lxaktGUWthNC90TmhhRjdObzJ0QlpCK29ZTC9lUDBJV3RQK2gvVzZEXG4iCisgICAgICAgICAgICArICJLUjUrVXZJSWRnbXg3azN0OWpwMlE1MUpwSGhoS0ViOVdONTR0ckNPOVl1N1BZVStMSTg1akVJQkFnTUJBQUdqXG4iCisgICAgICAgICAgICArICJnZ0VhTUlJQkZqQVdCZ05WSFNBRUR6QU5NQXNHQ1dDR1NBRmxBZ0VMQXpBZkJnTlZIU01FR0RBV2dCUXpPaFRvXG4iCisgICAgICAgICAgICArICJDV2RoaUdVa0lPeDVjRUxYcHBNZTlqQWRCZ05WSFE0RUZnUVVrTEJKbCtheUtnek9wL3d3Qlg5TTFsU2tDZzR3XG4iCisgICAgICAgICAgICArICJEZ1lEVlIwUEFRSC9CQVFEQWdiQU1Bd0dBMVVkRXdFQi93UUNNQUF3Z1owR0ExVWRId1NCbFRDQmtqQ0JqNkNCXG4iCisgICAgICAgICAgICArICJqS0NCaVlhQmhteGtZWEE2THk5a2N5MHhMbU5vWVcxaUxtUnBjMkV1Yldsc0wyTnVKVE5rVFdWa0pUSXdRMEVsXG4iCisgICAgICAgICAgICArICJNbVF4SlRKamIzVWxNMlJRUzBrbE1tTnZkU1V6WkVSdlJDVXlZMjhsTTJSVkxsTXVKVEl3UjI5MlpYSnViV1Z1XG4iCisgICAgICAgICAgICArICJkQ1V5WTJNbE0yUlZVejlqWlhKMGFXWnBZMkYwWlZKbGRtOWpZWFJwYjI1TWFYTjBKVE5pWW1sdVlYSjVNQTBHXG4iCisgICAgICAgICAgICArICJDU3FHU0liM0RRRUJCUVVBQTRHQkFGamFwdURITXZJZFVlWVJ5RVlkU2hCUjFKWkMyMHRKM01RbnlCUXZlZGR6XG4iCisgICAgICAgICAgICArICJMR0ZER3BJa1JBUVU3VC81L25lOGxNZXh5eFZpQzIxeE9sSzlMZGJKQ2JWeXl3dmI5dUVtLzFqZTl3aWVRUXRyXG4iCisgICAgICAgICAgICArICJranlrdUIrV0I2cVRDSXNsQU8vZVVtZ3pmeklFTnZuSDhPK2ZIN1FUcjJQZGtGa2lQSXFCSllIdnc3RjNYRHF5XG4iCisgICAgICAgICAgICArICItLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tXG4iOworCisgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gY2VydEFycmF5MyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShjZXJ0aWZpY2F0ZTMKKyAgICAgICAgICAgIC5nZXRCeXRlcygpKTsKKworCisgICAgcHVibGljIFg1MDlLZXlNYW5hZ2VySW1wbChTdHJpbmcgbmFtZSkgeworICAgICAgICBrZXlUeXBlID0gbmFtZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENlcnRpZmljYXRlRmFjdG9yeSBjZiA9IENlcnRpZmljYXRlRmFjdG9yeS5nZXRJbnN0YW5jZSgiWC41MDkiKTsKKyAgICAgICAgICAgIGtleVRlc3QgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAgICAgIGtleVRlc3QubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGlmIChrZXlUeXBlLmVxdWFscyhjbGllbnQpKSB7CisgICAgICAgICAgICAgICAgY2VydCA9IG5ldyBYNTA5Q2VydGlmaWNhdGVbMl07CisgICAgICAgICAgICAgICAgY2VydFswXSA9IChYNTA5Q2VydGlmaWNhdGUpIGNmLmdlbmVyYXRlQ2VydGlmaWNhdGUoY2VydEFycmF5KTsKKyAgICAgICAgICAgICAgICBjZXJ0WzFdID0gKFg1MDlDZXJ0aWZpY2F0ZSkgY2YuZ2VuZXJhdGVDZXJ0aWZpY2F0ZShjZXJ0QXJyYXkyKTsKKyAgICAgICAgICAgICAgICAvL2tleVRlc3QgPSBLZXlTdG9yZS5nZXRJbnN0YW5jZShLZXlTdG9yZS5nZXREZWZhdWx0VHlwZSgpKTsKKyAgICAgICAgICAgICAgICAvL2tleVRlc3QubG9hZChudWxsLCBudWxsKTsKKyAgICAgICAgICAgICAgICBrZXlUZXN0LnNldENlcnRpZmljYXRlRW50cnkoImNsaWVudEFsaWFzXzAxIiwgY2VydFswXSk7CisgICAgICAgICAgICAgICAga2V5VGVzdC5zZXRDZXJ0aWZpY2F0ZUVudHJ5KCJjbGllbnRBbGlhc18wMiIsIGNlcnRbMF0pOworICAgICAgICAgICAgICAgIGtleVRlc3Quc2V0Q2VydGlmaWNhdGVFbnRyeSgiY2xpZW50QWxpYXNfMDMiLCBjZXJ0WzFdKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoa2V5VHlwZS5lcXVhbHMoc2VydmVyKSkgeworICAgICAgICAgICAgICAgIC8vQ2VydGlmaWNhdGVGYWN0b3J5IGNmID0gQ2VydGlmaWNhdGVGYWN0b3J5LmdldEluc3RhbmNlKCJYLjUwOSIpOworICAgICAgICAgICAgICAgIGNlcnQgPSBuZXcgWDUwOUNlcnRpZmljYXRlWzFdOworICAgICAgICAgICAgICAgIGNlcnRbMF0gPSAoWDUwOUNlcnRpZmljYXRlKSBjZi5nZW5lcmF0ZUNlcnRpZmljYXRlKGNlcnRBcnJheTMpOworICAgICAgICAgICAgICAgIC8va2V5VGVzdCA9IEtleVN0b3JlLmdldEluc3RhbmNlKEtleVN0b3JlLmdldERlZmF1bHRUeXBlKCkpOworICAgICAgICAgICAgICAgIC8va2V5VGVzdC5sb2FkKG51bGwsIG51bGwpOworICAgICAgICAgICAgICAgIGtleVRlc3Quc2V0Q2VydGlmaWNhdGVFbnRyeSgic2VydmVyQWxpYXNfMDAiLCBjZXJ0WzBdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0Q2xpZW50QWxpYXNlcyhTdHJpbmcgcywgUHJpbmNpcGFsW10gYXByaW5jaXBhbCkgeworICAgICAgICBpZiAocyA9PSBudWxsIHx8IHMuZXF1YWxzKCIiKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChzLmVxdWFscyhjbGllbnQpKSB7CisgICAgICAgICAgICAgICAgRW51bWVyYXRpb248U3RyaW5nPiBhbGlhc2UgPSBrZXlUZXN0LmFsaWFzZXMoKTsKKyAgICAgICAgICAgICAgICBWZWN0b3IgdmVjID0gbmV3IFZlY3RvcigpOworICAgICAgICAgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgICAgICAgICB3aGlsZSAoYWxpYXNlLmhhc01vcmVFbGVtZW50cygpKSB7CisgICAgICAgICAgICAgICAgICAgIHZlYy5hZGRFbGVtZW50KGFsaWFzZS5uZXh0RWxlbWVudCgpKTsKKyAgICAgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBTdHJpbmdbXSByZXMgPSBuZXcgU3RyaW5nW3ZlYy5zaXplKCldOworICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB2ZWMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzW2ldID0gdmVjLmVsZW1lbnRBdChpKS50b1N0cmluZygpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzOworICAgICAgICAgICAgfSBlbHNlIHJldHVybiBudWxsOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgY2hvb3NlQ2xpZW50QWxpYXMoU3RyaW5nW10gYXMsIFByaW5jaXBhbFtdIGFwcmluY2lwYWwsIFNvY2tldCBzb2NrZXQpIHsKKyAgICAgICAgU3RyaW5nIGFsaWFzID0gbnVsbDsKKyAgICAgICAgaWYgKGFzID09IG51bGwgfHwgYXMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoYXMubGVuZ3RoID09IDEgJiYgYXNbMF0uZXF1YWxzKGNsaWVudCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoc29ja2V0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYWxpYXMgPSBrZXlUZXN0LmdldENlcnRpZmljYXRlQWxpYXMoY2VydFswXSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYWxpYXMgPSBrZXlUZXN0LmdldENlcnRpZmljYXRlQWxpYXMoY2VydFsxXSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBhbGlhczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZ1tdIGdldFNlcnZlckFsaWFzZXMoU3RyaW5nIHMsIFByaW5jaXBhbCBhcHJpbmNpcGFsW10pIHsKKyAgICAgICAgaWYgKHMgPT0gbnVsbCB8fCBzLmVxdWFscygiIikpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAocy5lcXVhbHMoc2VydmVyKSkgeworICAgICAgICAgICAgICAgIEVudW1lcmF0aW9uPFN0cmluZz4gYWxpYXNlID0ga2V5VGVzdC5hbGlhc2VzKCk7CisgICAgICAgICAgICAgICAgVmVjdG9yIHZlYyA9IG5ldyBWZWN0b3IoKTsKKyAgICAgICAgICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgICAgICAgICAgd2hpbGUgKGFsaWFzZS5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgICAgICAgICB2ZWMuYWRkRWxlbWVudChhbGlhc2UubmV4dEVsZW1lbnQoKSk7CisgICAgICAgICAgICAgICAgICAgIGkrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgU3RyaW5nW10gcmVzID0gbmV3IFN0cmluZ1t2ZWMuc2l6ZSgpXTsKKyAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdmVjLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIHJlc1tpXSA9IHZlYy5lbGVtZW50QXQoaSkudG9TdHJpbmcoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKKyAgICAgICAgICAgIH0gZWxzZSByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGNob29zZVNlcnZlckFsaWFzKFN0cmluZyBhcywgUHJpbmNpcGFsW10gYXByaW5jaXBhbCwgU29ja2V0IHNvY2tldCkgeworICAgICAgICBTdHJpbmcgYWxpYXMgPSBudWxsOworICAgICAgICBpZiAoYXMgPT0gbnVsbCB8fCBhcy5lcXVhbHMoIiIpKSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGFzLmVxdWFscyhzZXJ2ZXIpICYmIHNvY2tldCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGFsaWFzID0ga2V5VGVzdC5nZXRDZXJ0aWZpY2F0ZUFsaWFzKGNlcnRbMF0pOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgWDUwOUNlcnRpZmljYXRlW10gZ2V0Q2VydGlmaWNhdGVDaGFpbihTdHJpbmcgcykgeworICAgICAgICAvKnRyeSB7CisgICAgICAgICAgICBpZiAocyAhPSBudWxsICYmICFzLmVxdWFscygiIikpIHsKKyAgICAgICAgICAgICAgICBYNTA5Q2VydGlmaWNhdGVbXSBjZXJ0ID0gKFg1MDlDZXJ0aWZpY2F0ZVtdKSBrZXlUZXN0LmdldENlcnRpZmljYXRlQ2hhaW4ocyk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNlcnQ7CisgICAgICAgICAgICB9IGVsc2UgcmV0dXJuIG51bGw7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9Ki8KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIFByaXZhdGVLZXkgZ2V0UHJpdmF0ZUtleShTdHJpbmcgcykgeworICAgICAgICAvKnRyeSB7CisgICAgICAgICAgICBpZiAocyAhPSBudWxsICYmICFzLmVxdWFscygiIikpIHsKKyAgICAgICAgICAgICAgICBDZXJ0aWZpY2F0ZVtdIGNlcnQgPSBrZXlUZXN0LmdldENlcnRpZmljYXRlQ2hhaW4ocyk7CisgICAgICAgICAgICAgICAgUHJpdmF0ZUtleSBwayA9IChQcml2YXRlS2V5KSBrZXlUZXN0LmdldEtleShzLCBudWxsKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gcGs7CisgICAgICAgICAgICB9IGVsc2UgcmV0dXJuIG51bGw7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihleC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9Ki8KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9oYXJtb255L3huZXQvdGVzdHMvc3VwcG9ydC9YNTA5VHJ1c3RNYW5hZ2VySW1wbC5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Rlc3RzL3N1cHBvcnQvWDUwOVRydXN0TWFuYWdlckltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MzI1OGI5Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Rlc3RzL3N1cHBvcnQvWDUwOVRydXN0TWFuYWdlckltcGwuamF2YQpAQCAtMCwwICsxLDQzIEBACitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlg1MDlUcnVzdE1hbmFnZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CisKK3B1YmxpYyBjbGFzcyBYNTA5VHJ1c3RNYW5hZ2VySW1wbCBpbXBsZW1lbnRzIFg1MDlUcnVzdE1hbmFnZXIgeworCisgICAgcHVibGljIHZvaWQgY2hlY2tDbGllbnRUcnVzdGVkKFg1MDlDZXJ0aWZpY2F0ZVtdIGF4NTA5Y2VydGlmaWNhdGUsIFN0cmluZyBzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworCisgICAgICAgIGlmKGF4NTA5Y2VydGlmaWNhdGUgPT0gbnVsbCB8fCBheDUwOWNlcnRpZmljYXRlLmxlbmd0aCA9PSAwKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibnVsbCBvciB6ZXJvLWxlbmd0aCBjZXJ0aWZpY2F0ZSBjaGFpbiIpOworICAgICAgICBpZihzID09IG51bGwgfHwgcy5sZW5ndGgoKSA9PSAwKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibnVsbCBvciB6ZXJvLWxlbmd0aCBhdXRoZW50aWNhdGlvbiB0eXBlIik7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBheDUwOWNlcnRpZmljYXRlLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYXg1MDljZXJ0aWZpY2F0ZVtpXS5nZXRWZXJzaW9uKCkgIT0gMykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY2hlY2tTZXJ2ZXJUcnVzdGVkKFg1MDlDZXJ0aWZpY2F0ZVtdIGF4NTA5Y2VydGlmaWNhdGUsIFN0cmluZyBzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgQ2VydGlmaWNhdGVFeGNlcHRpb24geworCisgICAgICAgIGlmKGF4NTA5Y2VydGlmaWNhdGUgPT0gbnVsbCB8fCBheDUwOWNlcnRpZmljYXRlLmxlbmd0aCA9PSAwKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibnVsbCBvciB6ZXJvLWxlbmd0aCBjZXJ0aWZpY2F0ZSBjaGFpbiIpOworICAgICAgICBpZihzID09IG51bGwgfHwgcy5sZW5ndGgoKSA9PSAwKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibnVsbCBvciB6ZXJvLWxlbmd0aCBhdXRoZW50aWNhdGlvbiB0eXBlIik7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBheDUwOWNlcnRpZmljYXRlLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYXg1MDljZXJ0aWZpY2F0ZVtpXS5nZXRWZXJzaW9uKCkgIT0gMykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFg1MDlDZXJ0aWZpY2F0ZVtdIGdldEFjY2VwdGVkSXNzdWVycygpIHsKKyAgICAgICAgWDUwOUNlcnRpZmljYXRlW10gY2VydCA9IG5ldyBYNTA5Q2VydGlmaWNhdGVbMF07CisgICAgICAgIHJldHVybiBjZXJ0OworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC90ZXN0cy9zdXBwb3J0L215U1NMU2Vzc2lvbi5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvaGFybW9ueS94bmV0L3Rlc3RzL3N1cHBvcnQvbXlTU0xTZXNzaW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmNhNjE3NwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2hhcm1vbnkveG5ldC90ZXN0cy9zdXBwb3J0L215U1NMU2Vzc2lvbi5qYXZhCkBAIC0wLDAgKzEsMTc2IEBACitwYWNrYWdlIG9yZy5hcGFjaGUuaGFybW9ueS54bmV0LnRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaW5jaXBhbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGU7CitpbXBvcnQgamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKKworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb247CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uQmluZGluZ0V2ZW50OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb25Db250ZXh0OworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVFeGNlcHRpb247CitpbXBvcnQgamF2YXguc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CisKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNlc3Npb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhcm1vbnkuc2VjdXJpdHkudGVzdHMuc3VwcG9ydC5UZXN0Q2VydFV0aWxzOworCitwdWJsaWMgY2xhc3MgbXlTU0xTZXNzaW9uIGltcGxlbWVudHMgU1NMU2Vzc2lvbiB7CisKKyAgICBwcml2YXRlIGJ5dGVbXSBpZERhdGE7CisgICAgcHJpdmF0ZSBTdHJpbmcgbmFtZUhvc3QgPSBudWxsOworICAgIHByaXZhdGUgaW50IG5hbWVQb3J0ID0gLTE7CisgICAgcHJpdmF0ZSBIYXNodGFibGUgdGFibGU7CisgICAgcHJpdmF0ZSBib29sZWFuIGludmFsaWRhdGVEb25lID0gZmFsc2U7CisgICAgcHJpdmF0ZSBDZXJ0aWZpY2F0ZVtdIGNlcnRzID0gbnVsbDsKKyAgICBwcml2YXRlIFg1MDlDZXJ0aWZpY2F0ZVtdIHhDZXJ0cyA9IG51bGw7CisKKyAgICBwdWJsaWMgbXlTU0xTZXNzaW9uKFN0cmluZyBob3N0LCBpbnQgcG9ydCwgYnl0ZVtdIGlkKSB7CisgICAgICAgIGNlcnRzID0gbnVsbDsKKyAgICAgICAgeENlcnRzID0gbnVsbDsKKyAgICAgICAgbmFtZUhvc3QgPSBob3N0OworICAgICAgICBuYW1lUG9ydCA9IHBvcnQ7CisgICAgICAgIGlkRGF0YSA9IGlkOworICAgICAgICB0YWJsZSA9IG5ldyBIYXNodGFibGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgbXlTU0xTZXNzaW9uKFg1MDlDZXJ0aWZpY2F0ZVtdIHhjKSB7CisgICAgICAgIGNlcnRzID0gVGVzdENlcnRVdGlscy5nZXRDZXJ0Q2hhaW4oKTsKKyAgICAgICAgeENlcnRzID0geGM7CisgICAgfQorCisgICAgcHVibGljIG15U1NMU2Vzc2lvbihDZXJ0aWZpY2F0ZVtdIHhjKSB0aHJvd3MgQ2VydGlmaWNhdGVFbmNvZGluZ0V4Y2VwdGlvbiwgQ2VydGlmaWNhdGVFeGNlcHRpb24geworICAgICAgICBjZXJ0cyA9IHhjOworICAgICAgICB4Q2VydHMgPSBuZXcgWDUwOUNlcnRpZmljYXRlW3hjLmxlbmd0aF07CisgICAgICAgIGludCBpID0gMDsKKyAgICAgICAgZm9yIChDZXJ0aWZpY2F0ZSBjZXJ0IDogeGMpIHsKKyAgICAgICAgICAgIHhDZXJ0c1tpKytdID0gWDUwOUNlcnRpZmljYXRlLmdldEluc3RhbmNlKGNlcnQuZ2V0RW5jb2RlZCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBteVNTTFNlc3Npb24oKSB7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRBcHBsaWNhdGlvbkJ1ZmZlclNpemUoKSB7CisgICAgICAgIHJldHVybiAxMjM0NTY3OworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2lwaGVyU3VpdGUoKSB7CisgICAgICAgIHJldHVybiAiU3VpdGVOYW1lIjsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBnZXRDcmVhdGlvblRpbWUoKSB7CisgICAgICAgIHJldHVybiAxMDAwbDsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldElkKCkgeworICAgICAgICByZXR1cm4gaWREYXRhOworICAgIH0KKworICAgIHB1YmxpYyBsb25nIGdldExhc3RBY2Nlc3NlZFRpbWUoKSB7CisgICAgICAgIHJldHVybiAyMDAwbDsKKyAgICB9CisKKyAgICBwdWJsaWMgQ2VydGlmaWNhdGVbXSBnZXRMb2NhbENlcnRpZmljYXRlcygpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIFByaW5jaXBhbCBnZXRMb2NhbFByaW5jaXBhbCgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRQYWNrZXRCdWZmZXJTaXplKCkgeworICAgICAgICByZXR1cm4gMTIzNDU7CisgICAgfQorCisgICAgcHVibGljIENlcnRpZmljYXRlW10gZ2V0UGVlckNlcnRpZmljYXRlcygpIHRocm93cyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmIChjZXJ0cyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24oInBlZXIgbm90IGF1dGhlbnRpY2F0ZWQiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBjZXJ0czsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBYNTA5Q2VydGlmaWNhdGVbXSBnZXRQZWVyQ2VydGlmaWNhdGVDaGFpbigpIHRocm93cyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbiB7CisgICAgICAgIGlmKHhDZXJ0cyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24oInBlZXIgbm90IGF1dGhlbnRpY2F0ZWQiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiB4Q2VydHM7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFBlZXJIb3N0KCkgeworICAgICAgICByZXR1cm4gbmFtZUhvc3Q7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRQZWVyUG9ydCgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWVQb3J0OworICAgIH0KKworICAgIHB1YmxpYyBQcmluY2lwYWwgZ2V0UGVlclByaW5jaXBhbCgpIHRocm93cyBTU0xQZWVyVW52ZXJpZmllZEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJvdG9jb2woKSB7CisgICAgICAgIHJldHVybiAiUHJvdG9jb2xOYW1lIjsKKyAgICB9CisKKyAgICBwdWJsaWMgU1NMU2Vzc2lvbkNvbnRleHQgZ2V0U2Vzc2lvbkNvbnRleHQoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHB1dFZhbHVlKFN0cmluZyBzLCBPYmplY3Qgb2JqKSB7CisgICAgICAgIGlmKHMgPT0gbnVsbCB8fCBvYmogPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImFyZ3VtZW50cyBjYW4gbm90IGJlIG51bGwiKTsKKyAgICAgICAgT2JqZWN0IG9iajEgPSB0YWJsZS5wdXQocywgb2JqKTsKKyAgICAgICAgaWYob2JqMSBpbnN0YW5jZW9mIFNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXIpIHsKKyAgICAgICAgICAgIFNTTFNlc3Npb25CaW5kaW5nRXZlbnQgc3Nsc2Vzc2lvbmJpbmRpbmdldmVudCA9IG5ldyBTU0xTZXNzaW9uQmluZGluZ0V2ZW50KHRoaXMsIHMpOworICAgICAgICAgICAgKChTU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyKW9iajEpLnZhbHVlVW5ib3VuZChzc2xzZXNzaW9uYmluZGluZ2V2ZW50KTsKKyAgICAgICAgfQorICAgICAgICBpZihvYmogaW5zdGFuY2VvZiBTU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyKSB7CisgICAgICAgICAgICBTU0xTZXNzaW9uQmluZGluZ0V2ZW50IHNzbHNlc3Npb25iaW5kaW5nZXZlbnQxID0gbmV3IFNTTFNlc3Npb25CaW5kaW5nRXZlbnQodGhpcywgcyk7CisgICAgICAgICAgICAoKFNTTFNlc3Npb25CaW5kaW5nTGlzdGVuZXIpb2JqKS52YWx1ZUJvdW5kKHNzbHNlc3Npb25iaW5kaW5nZXZlbnQxKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlbW92ZVZhbHVlKFN0cmluZyBzKSB7CisgICAgICAgIGlmKHMgPT0gbnVsbCkKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImFyZ3VtZW50IGNhbiBub3QgYmUgbnVsbCIpOworICAgICAgICBPYmplY3Qgb2JqID0gdGFibGUucmVtb3ZlKHMpOworICAgICAgICBpZihvYmogaW5zdGFuY2VvZiBTU0xTZXNzaW9uQmluZGluZ0xpc3RlbmVyKSB7CisgICAgICAgICAgICBTU0xTZXNzaW9uQmluZGluZ0V2ZW50IHNzbHNlc3Npb25iaW5kaW5nZXZlbnQgPSBuZXcgU1NMU2Vzc2lvbkJpbmRpbmdFdmVudCh0aGlzLCBzKTsKKyAgICAgICAgICAgICgoU1NMU2Vzc2lvbkJpbmRpbmdMaXN0ZW5lcilvYmopLnZhbHVlVW5ib3VuZChzc2xzZXNzaW9uYmluZGluZ2V2ZW50KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0VmFsdWUoU3RyaW5nIHMpIHsKKyAgICAgICAgaWYocyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJhcmd1bWVudCBjYW4gbm90IGJlIG51bGwiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiB0YWJsZS5nZXQocyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0VmFsdWVOYW1lcygpIHsKKyAgICAgICAgVmVjdG9yIHZlY3RvciA9IG5ldyBWZWN0b3IoKTsKKyAgICAgICAgRW51bWVyYXRpb24gZW51bWVyYXRpb24gPSB0YWJsZS5rZXlzKCk7CisgICAgICAgIHdoaWxlIChlbnVtZXJhdGlvbi5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgdmVjdG9yLmFkZEVsZW1lbnQoZW51bWVyYXRpb24ubmV4dEVsZW1lbnQoKSk7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIGFzW10gPSBuZXcgU3RyaW5nW3ZlY3Rvci5zaXplKCldOworICAgICAgICB2ZWN0b3IuY29weUludG8oYXMpOworICAgICAgICByZXR1cm4gYXM7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgaW52YWxpZGF0ZSgpIHsKKyAgICAgICAgaW52YWxpZGF0ZURvbmUgPSB0cnVlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzVmFsaWQoKSB7CisgICAgICAgIHJldHVybiBpbnZhbGlkYXRlRG9uZTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9odHRwL01vY2tSZXNwb25zZS5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL2h0dHAvTW9ja1Jlc3BvbnNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDNhYWE5ZAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9odHRwL01vY2tSZXNwb25zZS5qYXZhCkBAIC0wLDAgKzEsMTQ3IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5odHRwOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBzdGF0aWMgdGVzdHMuaHR0cC5Nb2NrV2ViU2VydmVyLkFTQ0lJOworCisvKioKKyAqIEEgc2NyaXB0ZWQgcmVzcG9uc2UgdG8gYmUgcmVwbGF5ZWQgYnkgdGhlIG1vY2sgd2ViIHNlcnZlci4KKyAqLworcHVibGljIGNsYXNzIE1vY2tSZXNwb25zZSBpbXBsZW1lbnRzIENsb25lYWJsZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJGQ18xMTIzX0RBVEVfRk9STUFUID0gIkVFRSwgZGQgTU1NIHl5eXkgSEg6bW06c3Mgenp6IjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU1QVFlfQk9EWV9IRUFERVIgPSAiQ29udGVudC1MZW5ndGg6IDAiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDSFVOS0VEX0JPRFlfSEVBREVSID0gIlRyYW5zZmVyLWVuY29kaW5nOiBjaHVua2VkIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gRU1QVFlfQk9EWSA9IG5ldyBieXRlWzBdOworCisgICAgcHJpdmF0ZSBTdHJpbmcgc3RhdHVzID0gIkhUVFAvMS4xIDIwMCBPSyI7CisgICAgcHJpdmF0ZSBMaXN0PFN0cmluZz4gaGVhZGVycyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworICAgIHByaXZhdGUgYnl0ZVtdIGJvZHkgPSBFTVBUWV9CT0RZOworICAgIHByaXZhdGUgU29ja2V0UG9saWN5IHNvY2tldFBvbGljeSA9IFNvY2tldFBvbGljeS5LRUVQX09QRU47CisKKyAgICBwdWJsaWMgTW9ja1Jlc3BvbnNlKCkgeworICAgICAgICBoZWFkZXJzLmFkZChFTVBUWV9CT0RZX0hFQURFUik7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBNb2NrUmVzcG9uc2UgY2xvbmUoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNb2NrUmVzcG9uc2UgcmVzdWx0ID0gKE1vY2tSZXNwb25zZSkgc3VwZXIuY2xvbmUoKTsKKyAgICAgICAgICAgIHJlc3VsdC5oZWFkZXJzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KHJlc3VsdC5oZWFkZXJzKTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgSFRUUCByZXNwb25zZSBsaW5lLCBzdWNoIGFzICJIVFRQLzEuMSAyMDAgT0siLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RhdHVzKCkgeworICAgICAgICByZXR1cm4gc3RhdHVzOworICAgIH0KKworICAgIHB1YmxpYyBNb2NrUmVzcG9uc2Ugc2V0UmVzcG9uc2VDb2RlKGludCBjb2RlKSB7CisgICAgICAgIHRoaXMuc3RhdHVzID0gIkhUVFAvMS4xICIgKyBjb2RlICsgIiBPSyI7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBNb2NrUmVzcG9uc2Ugc2V0U3RhdHVzKFN0cmluZyBzdGF0dXMpIHsKKyAgICAgICAgdGhpcy5zdGF0dXMgPSBzdGF0dXM7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIEhUVFAgaGVhZGVycywgc3VjaCBhcyAiQ29udGVudC1MZW5ndGg6IDAiLgorICAgICAqLworICAgIHB1YmxpYyBMaXN0PFN0cmluZz4gZ2V0SGVhZGVycygpIHsKKyAgICAgICAgcmV0dXJuIGhlYWRlcnM7CisgICAgfQorCisgICAgcHVibGljIE1vY2tSZXNwb25zZSBjbGVhckhlYWRlcnMoKSB7CisgICAgICAgIGhlYWRlcnMuY2xlYXIoKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIE1vY2tSZXNwb25zZSBhZGRIZWFkZXIoU3RyaW5nIGhlYWRlcikgeworICAgICAgICBoZWFkZXJzLmFkZChoZWFkZXIpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGlucHV0IHN0cmVhbSBjb250YWluaW5nIHRoZSByYXcgSFRUUCBwYXlsb2FkLgorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0Qm9keSgpIHsKKyAgICAgICAgcmV0dXJuIGJvZHk7CisgICAgfQorCisgICAgcHVibGljIE1vY2tSZXNwb25zZSBzZXRCb2R5KGJ5dGVbXSBib2R5KSB7CisgICAgICAgIGlmICh0aGlzLmJvZHkgPT0gRU1QVFlfQk9EWSkgeworICAgICAgICAgICAgaGVhZGVycy5yZW1vdmUoRU1QVFlfQk9EWV9IRUFERVIpOworICAgICAgICB9CisgICAgICAgIHRoaXMuaGVhZGVycy5hZGQoIkNvbnRlbnQtTGVuZ3RoOiAiICsgYm9keS5sZW5ndGgpOworICAgICAgICB0aGlzLmJvZHkgPSBib2R5OworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgTW9ja1Jlc3BvbnNlIHNldEJvZHkoU3RyaW5nIGJvZHkpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzZXRCb2R5KGJvZHkuZ2V0Qnl0ZXMoQVNDSUkpKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBNb2NrUmVzcG9uc2Ugc2V0Q2h1bmtlZEJvZHkoYnl0ZVtdIGJvZHksIGludCBtYXhDaHVua1NpemUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGhlYWRlcnMucmVtb3ZlKEVNUFRZX0JPRFlfSEVBREVSKTsKKyAgICAgICAgaGVhZGVycy5hZGQoQ0hVTktFRF9CT0RZX0hFQURFUik7CisKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVzT3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBpbnQgcG9zID0gMDsKKyAgICAgICAgd2hpbGUgKHBvcyA8IGJvZHkubGVuZ3RoKSB7CisgICAgICAgICAgICBpbnQgY2h1bmtTaXplID0gTWF0aC5taW4oYm9keS5sZW5ndGggLSBwb3MsIG1heENodW5rU2l6ZSk7CisgICAgICAgICAgICBieXRlc091dC53cml0ZShJbnRlZ2VyLnRvSGV4U3RyaW5nKGNodW5rU2l6ZSkuZ2V0Qnl0ZXMoQVNDSUkpKTsKKyAgICAgICAgICAgIGJ5dGVzT3V0LndyaXRlKCJcclxuIi5nZXRCeXRlcyhBU0NJSSkpOworICAgICAgICAgICAgYnl0ZXNPdXQud3JpdGUoYm9keSwgcG9zLCBjaHVua1NpemUpOworICAgICAgICAgICAgYnl0ZXNPdXQud3JpdGUoIlxyXG4iLmdldEJ5dGVzKEFTQ0lJKSk7CisgICAgICAgICAgICBwb3MgKz0gY2h1bmtTaXplOworICAgICAgICB9CisgICAgICAgIGJ5dGVzT3V0LndyaXRlKCIwXHJcblxyXG4iLmdldEJ5dGVzKEFTQ0lJKSk7IC8vIGxhc3QgY2h1bmsgKyBlbXB0eSB0cmFpbGVyICsgY3JsZgorICAgICAgICB0aGlzLmJvZHkgPSBieXRlc091dC50b0J5dGVBcnJheSgpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgTW9ja1Jlc3BvbnNlIHNldENodW5rZWRCb2R5KFN0cmluZyBib2R5LCBpbnQgbWF4Q2h1bmtTaXplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gc2V0Q2h1bmtlZEJvZHkoYm9keS5nZXRCeXRlcyhBU0NJSSksIG1heENodW5rU2l6ZSk7CisgICAgfQorCisgICAgcHVibGljIFNvY2tldFBvbGljeSBnZXRTb2NrZXRQb2xpY3koKSB7CisgICAgICAgIHJldHVybiBzb2NrZXRQb2xpY3k7CisgICAgfQorCisgICAgcHVibGljIE1vY2tSZXNwb25zZSBzZXRTb2NrZXRQb2xpY3koU29ja2V0UG9saWN5IHNvY2tldFBvbGljeSkgeworICAgICAgICB0aGlzLnNvY2tldFBvbGljeSA9IHNvY2tldFBvbGljeTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBzdGF0dXM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL2h0dHAvTW9ja1dlYlNlcnZlci5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL2h0dHAvTW9ja1dlYlNlcnZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhMDEzODAKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvaHR0cC9Nb2NrV2ViU2VydmVyLmphdmEKQEAgLTAsMCArMSw1MDIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmh0dHA7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CdWZmZXJlZE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uZXQuSHR0cFVSTENvbm5lY3Rpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlByb3h5OworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5CbG9ja2luZ1F1ZXVlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNvbmN1cnJlbnRIYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcnM7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuTGlua2VkQmxvY2tpbmdEZXF1ZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5MaW5rZWRCbG9ja2luZ1F1ZXVlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNJbnRlZ2VyOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxldmVsOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ2dlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3Rvcnk7CitpbXBvcnQgc3RhdGljIHRlc3RzLmh0dHAuU29ja2V0UG9saWN5LkRJU0NPTk5FQ1RfQVRfU1RBUlQ7CisKKy8qKgorICogQSBzY3JpcHRhYmxlIHdlYiBzZXJ2ZXIuIENhbGxlcnMgc3VwcGx5IGNhbm5lZCByZXNwb25zZXMgYW5kIHRoZSBzZXJ2ZXIKKyAqIHJlcGxheXMgdGhlbSB1cG9uIHJlcXVlc3QgaW4gc2VxdWVuY2UuCisgKgorICogQGRlcHJlY2F0ZWQgcHJlZmVyIGNvbS5nb29nbGUubW9ja3dlYnNlcnZlci5Nb2NrV2ViU2VydmVyCisgKi8KK0BEZXByZWNhdGVkCitwdWJsaWMgZmluYWwgY2xhc3MgTW9ja1dlYlNlcnZlciB7CisKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIEFTQ0lJID0gIlVTLUFTQ0lJIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvZ2dlciBsb2dnZXIgPSBMb2dnZXIuZ2V0TG9nZ2VyKE1vY2tXZWJTZXJ2ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICBwcml2YXRlIGZpbmFsIEJsb2NraW5nUXVldWU8UmVjb3JkZWRSZXF1ZXN0PiByZXF1ZXN0UXVldWUKKyAgICAgICAgICAgID0gbmV3IExpbmtlZEJsb2NraW5nUXVldWU8UmVjb3JkZWRSZXF1ZXN0PigpOworICAgIHByaXZhdGUgZmluYWwgQmxvY2tpbmdRdWV1ZTxNb2NrUmVzcG9uc2U+IHJlc3BvbnNlUXVldWUKKyAgICAgICAgICAgID0gbmV3IExpbmtlZEJsb2NraW5nRGVxdWU8TW9ja1Jlc3BvbnNlPigpOworICAgIHByaXZhdGUgZmluYWwgU2V0PFNvY2tldD4gb3BlbkNsaWVudFNvY2tldHMKKyAgICAgICAgICAgID0gQ29sbGVjdGlvbnMubmV3U2V0RnJvbU1hcChuZXcgQ29uY3VycmVudEhhc2hNYXA8U29ja2V0LCBCb29sZWFuPigpKTsKKyAgICBwcml2YXRlIGJvb2xlYW4gc2luZ2xlUmVzcG9uc2U7CisgICAgcHJpdmF0ZSBmaW5hbCBBdG9taWNJbnRlZ2VyIHJlcXVlc3RDb3VudCA9IG5ldyBBdG9taWNJbnRlZ2VyKCk7CisgICAgcHJpdmF0ZSBpbnQgYm9keUxpbWl0ID0gSW50ZWdlci5NQVhfVkFMVUU7CisgICAgcHJpdmF0ZSBTZXJ2ZXJTb2NrZXQgc2VydmVyU29ja2V0OworICAgIHByaXZhdGUgU1NMU29ja2V0RmFjdG9yeSBzc2xTb2NrZXRGYWN0b3J5OworICAgIHByaXZhdGUgRXhlY3V0b3JTZXJ2aWNlIGV4ZWN1dG9yOworICAgIHByaXZhdGUgYm9vbGVhbiB0dW5uZWxQcm94eTsKKworICAgIHByaXZhdGUgaW50IHBvcnQgPSAtMTsKKworICAgIHB1YmxpYyBpbnQgZ2V0UG9ydCgpIHsKKyAgICAgICAgaWYgKHBvcnQgPT0gLTEpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkNhbm5vdCByZXRyaWV2ZSBwb3J0IGJlZm9yZSBjYWxsaW5nIHBsYXkoKSIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBwb3J0OworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0SG9zdE5hbWUoKSB7CisgICAgICAgIHJldHVybiBJbmV0QWRkcmVzcy5nZXRMb29wYmFja0FkZHJlc3MoKS5nZXRIb3N0TmFtZSgpOworICAgIH0KKworICAgIHB1YmxpYyBQcm94eSB0b1Byb3h5QWRkcmVzcygpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBQcm94eShQcm94eS5UeXBlLkhUVFAsIG5ldyBJbmV0U29ja2V0QWRkcmVzcyhnZXRIb3N0TmFtZSgpLCBnZXRQb3J0KCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgVVJMIGZvciBjb25uZWN0aW5nIHRvIHRoaXMgc2VydmVyLgorICAgICAqCisgICAgICogQHBhcmFtIHBhdGggdGhlIHJlcXVlc3QgcGF0aCwgc3VjaCBhcyAiLyIuCisgICAgICovCisgICAgcHVibGljIFVSTCBnZXRVcmwoU3RyaW5nIHBhdGgpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24sIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNzbFNvY2tldEZhY3RvcnkgIT0gbnVsbAorICAgICAgICAgICAgICAgID8gbmV3IFVSTCgiaHR0cHM6Ly8iICsgZ2V0SG9zdE5hbWUoKSArICI6IiArIGdldFBvcnQoKSArIHBhdGgpCisgICAgICAgICAgICAgICAgOiBuZXcgVVJMKCJodHRwOi8vIiArIGdldEhvc3ROYW1lKCkgKyAiOiIgKyBnZXRQb3J0KCkgKyBwYXRoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBudW1iZXIgb2YgYnl0ZXMgb2YgdGhlIFBPU1QgYm9keSB0byBrZWVwIGluIG1lbW9yeSB0byB0aGUgZ2l2ZW4KKyAgICAgKiBsaW1pdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRCb2R5TGltaXQoaW50IG1heEJvZHlMZW5ndGgpIHsKKyAgICAgICAgdGhpcy5ib2R5TGltaXQgPSBtYXhCb2R5TGVuZ3RoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlcnZlIHJlcXVlc3RzIHdpdGggSFRUUFMgcmF0aGVyIHRoYW4gb3RoZXJ3aXNlLgorICAgICAqCisgICAgICogQHBhcmFtIHR1bm5lbFByb3h5IHdoZXRoZXIgdG8gZXhwZWN0IHRoZSBIVFRQIENPTk5FQ1QgbWV0aG9kIGJlZm9yZQorICAgICAqICAgICBuZWdvdGlhdGluZyBUTFMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXNlSHR0cHMoU1NMU29ja2V0RmFjdG9yeSBzc2xTb2NrZXRGYWN0b3J5LCBib29sZWFuIHR1bm5lbFByb3h5KSB7CisgICAgICAgIHRoaXMuc3NsU29ja2V0RmFjdG9yeSA9IHNzbFNvY2tldEZhY3Rvcnk7CisgICAgICAgIHRoaXMudHVubmVsUHJveHkgPSB0dW5uZWxQcm94eTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBd2FpdHMgdGhlIG5leHQgSFRUUCByZXF1ZXN0LCByZW1vdmVzIGl0LCBhbmQgcmV0dXJucyBpdC4gQ2FsbGVycyBzaG91bGQKKyAgICAgKiB1c2UgdGhpcyB0byB2ZXJpZnkgdGhlIHJlcXVlc3Qgc2VudCB3YXMgYXMgaW50ZW5kZWQuCisgICAgICovCisgICAgcHVibGljIFJlY29yZGVkUmVxdWVzdCB0YWtlUmVxdWVzdCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByZXF1ZXN0UXVldWUudGFrZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBIVFRQIHJlcXVlc3RzIHJlY2VpdmVkIHRodXMgZmFyIGJ5IHRoaXMgc2VydmVyLgorICAgICAqIFRoaXMgbWF5IGV4Y2VlZCB0aGUgbnVtYmVyIG9mIEhUVFAgY29ubmVjdGlvbnMgd2hlbiBjb25uZWN0aW9uIHJldXNlIGlzCisgICAgICogaW4gcHJhY3RpY2UuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSZXF1ZXN0Q291bnQoKSB7CisgICAgICAgIHJldHVybiByZXF1ZXN0Q291bnQuZ2V0KCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5xdWV1ZShNb2NrUmVzcG9uc2UgcmVzcG9uc2UpIHsKKyAgICAgICAgcmVzcG9uc2VRdWV1ZS5hZGQocmVzcG9uc2UuY2xvbmUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQnkgZGVmYXVsdCwgdGhpcyBjbGFzcyBwcm9jZXNzZXMgcmVxdWVzdHMgY29taW5nIGluIGJ5IGFkZGluZyB0aGVtIHRvIGEKKyAgICAgKiBxdWV1ZSBhbmQgc2VydmVzIHJlc3BvbnNlcyBieSByZW1vdmluZyB0aGVtIGZyb20gYW5vdGhlciBxdWV1ZS4gVGhpcyBtb2RlCisgICAgICogaXMgYXBwcm9wcmlhdGUgZm9yIGNvcnJlY3RuZXNzIHRlc3RpbmcuCisgICAgICoKKyAgICAgKiA8cD5TZXJ2aW5nIGEgc2luZ2xlIHJlc3BvbnNlIGNhdXNlcyB0aGUgc2VydmVyIHRvIGJlIHN0YXRlbGVzczogcmVxdWVzdHMKKyAgICAgKiBhcmUgbm90IGVucXVldWVkLCBhbmQgcmVzcG9uc2VzIGFyZSBub3QgZGVxdWV1ZWQuIFRoaXMgbW9kZSBpcyBhcHByb3ByaWF0ZQorICAgICAqIGZvciBiZW5jaG1hcmtpbmcuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2luZ2xlUmVzcG9uc2UoYm9vbGVhbiBzaW5nbGVSZXNwb25zZSkgeworICAgICAgICB0aGlzLnNpbmdsZVJlc3BvbnNlID0gc2luZ2xlUmVzcG9uc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgcGxheSgwKX0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcGxheSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHBsYXkoMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3RhcnRzIHRoZSBzZXJ2ZXIsIHNlcnZlcyBhbGwgZW5xdWV1ZWQgcmVxdWVzdHMsIGFuZCBzaHV0cyB0aGUgc2VydmVyCisgICAgICogZG93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwb3J0IHRoZSBwb3J0IHRvIGxpc3RlbiB0bywgb3IgMCBmb3IgYW55IGF2YWlsYWJsZSBwb3J0LgorICAgICAqICAgICBBdXRvbWF0ZWQgdGVzdHMgc2hvdWxkIGFsd2F5cyB1c2UgcG9ydCAwIHRvIGF2b2lkIGZsYWtpbmVzcyB3aGVuIGEKKyAgICAgKiAgICAgc3BlY2lmaWMgcG9ydCBpcyB1bmF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwbGF5KGludCBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBleGVjdXRvciA9IEV4ZWN1dG9ycy5uZXdDYWNoZWRUaHJlYWRQb29sKCk7CisgICAgICAgIHNlcnZlclNvY2tldCA9IG5ldyBTZXJ2ZXJTb2NrZXQocG9ydCk7CisgICAgICAgIHNlcnZlclNvY2tldC5zZXRSZXVzZUFkZHJlc3ModHJ1ZSk7CisKKyAgICAgICAgdGhpcy5wb3J0ID0gc2VydmVyU29ja2V0LmdldExvY2FsUG9ydCgpOworICAgICAgICBleGVjdXRvci5leGVjdXRlKG5hbWVkUnVubmFibGUoIk1vY2tXZWJTZXJ2ZXItYWNjZXB0LSIgKyBwb3J0LCBuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgYWNjZXB0Q29ubmVjdGlvbnMoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZSkgeworICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKExldmVsLldBUk5JTkcsICJNb2NrV2ViU2VydmVyIGNvbm5lY3Rpb24gZmFpbGVkIiwgZSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgKiBUaGlzIGduYXJseSBibG9jayBvZiBjb2RlIHdpbGwgcmVsZWFzZSBhbGwgc29ja2V0cyBhbmQKKyAgICAgICAgICAgICAgICAgKiBhbGwgdGhyZWFkLCBldmVuIGlmIGFueSBjbG9zZSBmYWlscy4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJTb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZSkgeworICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKExldmVsLldBUk5JTkcsICJNb2NrV2ViU2VydmVyIHNlcnZlciBzb2NrZXQgY2xvc2UgZmFpbGVkIiwgZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGZvciAoSXRlcmF0b3I8U29ja2V0PiBzID0gb3BlbkNsaWVudFNvY2tldHMuaXRlcmF0b3IoKTsgcy5oYXNOZXh0KCk7KSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzLm5leHQoKS5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgcy5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coTGV2ZWwuV0FSTklORywgIk1vY2tXZWJTZXJ2ZXIgc29ja2V0IGNsb3NlIGZhaWxlZCIsIGUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGV4ZWN1dG9yLnNodXRkb3duKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhMZXZlbC5XQVJOSU5HLCAiTW9ja1dlYlNlcnZlciBleGVjdXRvciBzaHV0ZG93biBmYWlsZWQiLCBlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHByaXZhdGUgdm9pZCBhY2NlcHRDb25uZWN0aW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICAgICAgU29ja2V0IHNvY2tldDsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNvY2tldCA9IHNlcnZlclNvY2tldC5hY2NlcHQoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoU29ja2V0RXhjZXB0aW9uIGlnbm9yZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIE1vY2tSZXNwb25zZSBwZWVrID0gcmVzcG9uc2VRdWV1ZS5wZWVrKCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChwZWVrICE9IG51bGwgJiYgcGVlay5nZXRTb2NrZXRQb2xpY3koKSA9PSBESVNDT05ORUNUX0FUX1NUQVJUKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZVF1ZXVlLnRha2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgb3BlbkNsaWVudFNvY2tldHMuYWRkKHNvY2tldCk7CisgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZUNvbm5lY3Rpb24oc29ja2V0KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gd2hpbGUgKCFyZXNwb25zZVF1ZXVlLmlzRW1wdHkoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0pKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzaHV0ZG93bigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChzZXJ2ZXJTb2NrZXQgIT0gbnVsbCkgeworICAgICAgICAgICAgc2VydmVyU29ja2V0LmNsb3NlKCk7IC8vIHNob3VsZCBjYXVzZSBhY2NlcHRDb25uZWN0aW9ucygpIHRvIGJyZWFrIG91dAorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHNlcnZlQ29ubmVjdGlvbihmaW5hbCBTb2NrZXQgcmF3KSB7CisgICAgICAgIFN0cmluZyBuYW1lID0gIk1vY2tXZWJTZXJ2ZXItIiArIHJhdy5nZXRSZW1vdGVTb2NrZXRBZGRyZXNzKCk7CisgICAgICAgIGV4ZWN1dG9yLmV4ZWN1dGUobmFtZWRSdW5uYWJsZShuYW1lLCBuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBpbnQgc2VxdWVuY2VOdW1iZXIgPSAwOworCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0Nvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKExldmVsLldBUk5JTkcsICJNb2NrV2ViU2VydmVyIGNvbm5lY3Rpb24gZmFpbGVkIiwgZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzQ29ubmVjdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAgICAgICAgIFNvY2tldCBzb2NrZXQ7CisgICAgICAgICAgICAgICAgaWYgKHNzbFNvY2tldEZhY3RvcnkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpZiAodHVubmVsUHJveHkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVR1bm5lbCgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHNvY2tldCA9IHNzbFNvY2tldEZhY3RvcnkuY3JlYXRlU29ja2V0KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhdywgcmF3LmdldEluZXRBZGRyZXNzKCkuZ2V0SG9zdEFkZHJlc3MoKSwgcmF3LmdldFBvcnQoKSwgdHJ1ZSk7CisgICAgICAgICAgICAgICAgICAgICgoU1NMU29ja2V0KSBzb2NrZXQpLnNldFVzZUNsaWVudE1vZGUoZmFsc2UpOworICAgICAgICAgICAgICAgICAgICBvcGVuQ2xpZW50U29ja2V0cy5hZGQoc29ja2V0KTsKKyAgICAgICAgICAgICAgICAgICAgb3BlbkNsaWVudFNvY2tldHMucmVtb3ZlKHJhdyk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgc29ja2V0ID0gcmF3OworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGluID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oc29ja2V0LmdldElucHV0U3RyZWFtKCkpOworICAgICAgICAgICAgICAgIE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnVmZmVyZWRPdXRwdXRTdHJlYW0oc29ja2V0LmdldE91dHB1dFN0cmVhbSgpKTsKKworICAgICAgICAgICAgICAgIHdoaWxlICghcmVzcG9uc2VRdWV1ZS5pc0VtcHR5KCkgJiYgcHJvY2Vzc09uZVJlcXVlc3QoaW4sIG91dCwgc29ja2V0KSkge30KKworICAgICAgICAgICAgICAgIGlmIChzZXF1ZW5jZU51bWJlciA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuaW5nKCJNb2NrV2ViU2VydmVyIGNvbm5lY3Rpb24gZGlkbid0IG1ha2UgYSByZXF1ZXN0Iik7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBzb2NrZXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2VRdWV1ZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgc2h1dGRvd24oKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgb3BlbkNsaWVudFNvY2tldHMucmVtb3ZlKHNvY2tldCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qKgorICAgICAgICAgICAgICogUmVzcG9uZCB0byBDT05ORUNUIHJlcXVlc3RzIHVudGlsIGEgU1dJVENIX1RPX1NTTF9BVF9FTkQgcmVzcG9uc2UKKyAgICAgICAgICAgICAqIGlzIGRpc3BhdGNoZWQuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHByaXZhdGUgdm9pZCBjcmVhdGVUdW5uZWwoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgICAgICBNb2NrUmVzcG9uc2UgY29ubmVjdCA9IHJlc3BvbnNlUXVldWUucGVlaygpOworICAgICAgICAgICAgICAgICAgICBpZiAoIXByb2Nlc3NPbmVSZXF1ZXN0KHJhdy5nZXRJbnB1dFN0cmVhbSgpLCByYXcuZ2V0T3V0cHV0U3RyZWFtKCksIHJhdykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIlR1bm5lbCB3aXRob3V0IGFueSBDT05ORUNUISIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChjb25uZWN0LmdldFNvY2tldFBvbGljeSgpID09IFNvY2tldFBvbGljeS5VUEdSQURFX1RPX1NTTF9BVF9FTkQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgKiBSZWFkcyBhIHJlcXVlc3QgYW5kIHdyaXRlcyBpdHMgcmVzcG9uc2UuIFJldHVybnMgdHJ1ZSBpZiBhIHJlcXVlc3QKKyAgICAgICAgICAgICAqIHdhcyBwcm9jZXNzZWQuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiBwcm9jZXNzT25lUmVxdWVzdChJbnB1dFN0cmVhbSBpbiwgT3V0cHV0U3RyZWFtIG91dCwgU29ja2V0IHNvY2tldCkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgUmVjb3JkZWRSZXF1ZXN0IHJlcXVlc3QgPSByZWFkUmVxdWVzdChpbiwgc2VxdWVuY2VOdW1iZXIpOworICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBNb2NrUmVzcG9uc2UgcmVzcG9uc2UgPSBkaXNwYXRjaChyZXF1ZXN0KTsKKyAgICAgICAgICAgICAgICB3cml0ZVJlc3BvbnNlKG91dCwgcmVzcG9uc2UpOworICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5nZXRTb2NrZXRQb2xpY3koKSA9PSBTb2NrZXRQb2xpY3kuRElTQ09OTkVDVF9BVF9FTkQpIHsKKyAgICAgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZS5nZXRTb2NrZXRQb2xpY3koKSA9PSBTb2NrZXRQb2xpY3kuU0hVVERPV05fSU5QVVRfQVRfRU5EKSB7CisgICAgICAgICAgICAgICAgICAgIHNvY2tldC5zaHV0ZG93bklucHV0KCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZS5nZXRTb2NrZXRQb2xpY3koKSA9PSBTb2NrZXRQb2xpY3kuU0hVVERPV05fT1VUUFVUX0FUX0VORCkgeworICAgICAgICAgICAgICAgICAgICBzb2NrZXQuc2h1dGRvd25PdXRwdXQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc2VxdWVuY2VOdW1iZXIrKzsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBzZXF1ZW5jZU51bWJlciB0aGUgaW5kZXggb2YgdGhpcyByZXF1ZXN0IG9uIHRoaXMgY29ubmVjdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIFJlY29yZGVkUmVxdWVzdCByZWFkUmVxdWVzdChJbnB1dFN0cmVhbSBpbiwgaW50IHNlcXVlbmNlTnVtYmVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTdHJpbmcgcmVxdWVzdDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlcXVlc3QgPSByZWFkQXNjaWlVbnRpbENybGYoaW4pOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBzdHJlYW1Jc0Nsb3NlZCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7IC8vIG5vIHJlcXVlc3QgYmVjYXVzZSB3ZSBjbG9zZWQgdGhlIHN0cmVhbQorICAgICAgICB9CisgICAgICAgIGlmIChyZXF1ZXN0LmlzRW1wdHkoKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7IC8vIG5vIHJlcXVlc3QgYmVjYXVzZSB0aGUgc3RyZWFtIGlzIGV4aGF1c3RlZAorICAgICAgICB9CisKKyAgICAgICAgTGlzdDxTdHJpbmc+IGhlYWRlcnMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKyAgICAgICAgaW50IGNvbnRlbnRMZW5ndGggPSAtMTsKKyAgICAgICAgYm9vbGVhbiBjaHVua2VkID0gZmFsc2U7CisgICAgICAgIFN0cmluZyBoZWFkZXI7CisgICAgICAgIHdoaWxlICghKGhlYWRlciA9IHJlYWRBc2NpaVVudGlsQ3JsZihpbikpLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgaGVhZGVycy5hZGQoaGVhZGVyKTsKKyAgICAgICAgICAgIFN0cmluZyBsb3dlcmNhc2VIZWFkZXIgPSBoZWFkZXIudG9Mb3dlckNhc2UoKTsKKyAgICAgICAgICAgIGlmIChjb250ZW50TGVuZ3RoID09IC0xICYmIGxvd2VyY2FzZUhlYWRlci5zdGFydHNXaXRoKCJjb250ZW50LWxlbmd0aDoiKSkgeworICAgICAgICAgICAgICAgIGNvbnRlbnRMZW5ndGggPSBJbnRlZ2VyLnBhcnNlSW50KGhlYWRlci5zdWJzdHJpbmcoMTUpLnRyaW0oKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobG93ZXJjYXNlSGVhZGVyLnN0YXJ0c1dpdGgoInRyYW5zZmVyLWVuY29kaW5nOiIpICYmCisgICAgICAgICAgICAgICAgICAgIGxvd2VyY2FzZUhlYWRlci5zdWJzdHJpbmcoMTgpLnRyaW0oKS5lcXVhbHMoImNodW5rZWQiKSkgeworICAgICAgICAgICAgICAgIGNodW5rZWQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBoYXNCb2R5ID0gZmFsc2U7CisgICAgICAgIFRydW5jYXRpbmdPdXRwdXRTdHJlYW0gcmVxdWVzdEJvZHkgPSBuZXcgVHJ1bmNhdGluZ091dHB1dFN0cmVhbSgpOworICAgICAgICBMaXN0PEludGVnZXI+IGNodW5rU2l6ZXMgPSBuZXcgQXJyYXlMaXN0PEludGVnZXI+KCk7CisgICAgICAgIGlmIChjb250ZW50TGVuZ3RoICE9IC0xKSB7CisgICAgICAgICAgICBoYXNCb2R5ID0gdHJ1ZTsKKyAgICAgICAgICAgIHRyYW5zZmVyKGNvbnRlbnRMZW5ndGgsIGluLCByZXF1ZXN0Qm9keSk7CisgICAgICAgIH0gZWxzZSBpZiAoY2h1bmtlZCkgeworICAgICAgICAgICAgaGFzQm9keSA9IHRydWU7CisgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgIGludCBjaHVua1NpemUgPSBJbnRlZ2VyLnBhcnNlSW50KHJlYWRBc2NpaVVudGlsQ3JsZihpbikudHJpbSgpLCAxNik7CisgICAgICAgICAgICAgICAgaWYgKGNodW5rU2l6ZSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJlYWRFbXB0eUxpbmUoaW4pOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY2h1bmtTaXplcy5hZGQoY2h1bmtTaXplKTsKKyAgICAgICAgICAgICAgICB0cmFuc2ZlcihjaHVua1NpemUsIGluLCByZXF1ZXN0Qm9keSk7CisgICAgICAgICAgICAgICAgcmVhZEVtcHR5TGluZShpbik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAocmVxdWVzdC5zdGFydHNXaXRoKCJPUFRJT05TICIpIHx8IHJlcXVlc3Quc3RhcnRzV2l0aCgiR0VUICIpCisgICAgICAgICAgICAgICAgfHwgcmVxdWVzdC5zdGFydHNXaXRoKCJIRUFEICIpIHx8IHJlcXVlc3Quc3RhcnRzV2l0aCgiREVMRVRFICIpCisgICAgICAgICAgICAgICAgfHwgcmVxdWVzdCAuc3RhcnRzV2l0aCgiVFJBQ0UgIikgfHwgcmVxdWVzdC5zdGFydHNXaXRoKCJDT05ORUNUICIpKSB7CisgICAgICAgICAgICBpZiAoaGFzQm9keSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlJlcXVlc3QgbXVzdCBub3QgaGF2ZSBhIGJvZHk6ICIgKyByZXF1ZXN0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChyZXF1ZXN0LnN0YXJ0c1dpdGgoIlBPU1QgIikgfHwgcmVxdWVzdC5zdGFydHNXaXRoKCJQVVQgIikpIHsKKyAgICAgICAgICAgIGlmICghaGFzQm9keSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlJlcXVlc3QgbXVzdCBoYXZlIGEgYm9keTogIiArIHJlcXVlc3QpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJVbmV4cGVjdGVkIG1ldGhvZDogIiArIHJlcXVlc3QpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIG5ldyBSZWNvcmRlZFJlcXVlc3QocmVxdWVzdCwgaGVhZGVycywgY2h1bmtTaXplcywKKyAgICAgICAgICAgICAgICByZXF1ZXN0Qm9keS5udW1CeXRlc1JlY2VpdmVkLCByZXF1ZXN0Qm9keS50b0J5dGVBcnJheSgpLCBzZXF1ZW5jZU51bWJlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHJlc3BvbnNlIHRvIHNhdGlzZnkge0Bjb2RlIHJlcXVlc3R9LgorICAgICAqLworICAgIHByaXZhdGUgTW9ja1Jlc3BvbnNlIGRpc3BhdGNoKFJlY29yZGVkUmVxdWVzdCByZXF1ZXN0KSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgICBpZiAocmVzcG9uc2VRdWV1ZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIlVuZXhwZWN0ZWQgcmVxdWVzdDogIiArIHJlcXVlc3QpOworICAgICAgICB9CisKKyAgICAgICAgLy8gdG8gcGVybWl0IGludGVyYWN0aXZlL2Jyb3dzZXIgdGVzdGluZywgaWdub3JlIHJlcXVlc3RzIGZvciBmYXZpY29ucworICAgICAgICBpZiAocmVxdWVzdC5nZXRSZXF1ZXN0TGluZSgpLmVxdWFscygiR0VUIC9mYXZpY29uLmljbyBIVFRQLzEuMSIpKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInNlcnZlZCAiICsgcmVxdWVzdC5nZXRSZXF1ZXN0TGluZSgpKTsKKyAgICAgICAgICAgIHJldHVybiBuZXcgTW9ja1Jlc3BvbnNlKCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRSZXNwb25zZUNvZGUoSHR0cFVSTENvbm5lY3Rpb24uSFRUUF9OT1RfRk9VTkQpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHNpbmdsZVJlc3BvbnNlKSB7CisgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2VRdWV1ZS5wZWVrKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXF1ZXN0Q291bnQuaW5jcmVtZW50QW5kR2V0KCk7CisgICAgICAgICAgICByZXF1ZXN0UXVldWUuYWRkKHJlcXVlc3QpOworICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlUXVldWUudGFrZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHdyaXRlUmVzcG9uc2UoT3V0cHV0U3RyZWFtIG91dCwgTW9ja1Jlc3BvbnNlIHJlc3BvbnNlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXQud3JpdGUoKHJlc3BvbnNlLmdldFN0YXR1cygpICsgIlxyXG4iKS5nZXRCeXRlcyhBU0NJSSkpOworICAgICAgICBmb3IgKFN0cmluZyBoZWFkZXIgOiByZXNwb25zZS5nZXRIZWFkZXJzKCkpIHsKKyAgICAgICAgICAgIG91dC53cml0ZSgoaGVhZGVyICsgIlxyXG4iKS5nZXRCeXRlcyhBU0NJSSkpOworICAgICAgICB9CisgICAgICAgIG91dC53cml0ZSgoIlxyXG4iKS5nZXRCeXRlcyhBU0NJSSkpOworICAgICAgICBvdXQud3JpdGUocmVzcG9uc2UuZ2V0Qm9keSgpKTsKKyAgICAgICAgb3V0LmZsdXNoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJhbnNmZXIgYnl0ZXMgZnJvbSB7QGNvZGUgaW59IHRvIHtAY29kZSBvdXR9IHVudGlsIGVpdGhlciB7QGNvZGUgbGVuZ3RofQorICAgICAqIGJ5dGVzIGhhdmUgYmVlbiB0cmFuc2ZlcnJlZCBvciB7QGNvZGUgaW59IGlzIGV4aGF1c3RlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgdHJhbnNmZXIoaW50IGxlbmd0aCwgSW5wdXRTdHJlYW0gaW4sIE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVsxMDI0XTsKKyAgICAgICAgd2hpbGUgKGxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgIGludCBjb3VudCA9IGluLnJlYWQoYnVmZmVyLCAwLCBNYXRoLm1pbihidWZmZXIubGVuZ3RoLCBsZW5ndGgpKTsKKyAgICAgICAgICAgIGlmIChjb3VudCA9PSAtMSkgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG91dC53cml0ZShidWZmZXIsIDAsIGNvdW50KTsKKyAgICAgICAgICAgIGxlbmd0aCAtPSBjb3VudDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRleHQgZnJvbSB7QGNvZGUgaW59IHVudGlsIHRoZSBuZXh0ICJcclxuIiwgb3IgbnVsbCBpZgorICAgICAqIHtAY29kZSBpbn0gaXMgZXhoYXVzdGVkLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHJlYWRBc2NpaVVudGlsQ3JsZihJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIGludCBjID0gaW4ucmVhZCgpOworICAgICAgICAgICAgaWYgKGMgPT0gJ1xuJyAmJiBidWlsZGVyLmxlbmd0aCgpID4gMCAmJiBidWlsZGVyLmNoYXJBdChidWlsZGVyLmxlbmd0aCgpIC0gMSkgPT0gJ1xyJykgeworICAgICAgICAgICAgICAgIGJ1aWxkZXIuZGVsZXRlQ2hhckF0KGJ1aWxkZXIubGVuZ3RoKCkgLSAxKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgICAgICAgICAgfSBlbHNlIGlmIChjID09IC0xKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoKGNoYXIpIGMpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRFbXB0eUxpbmUoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBsaW5lID0gcmVhZEFzY2lpVW50aWxDcmxmKGluKTsKKyAgICAgICAgaWYgKCFsaW5lLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiRXhwZWN0ZWQgZW1wdHkgYnV0IHdhczogIiArIGxpbmUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQW4gb3V0cHV0IHN0cmVhbSB0aGF0IGRyb3BzIGRhdGEgYWZ0ZXIgYm9keUxpbWl0IGJ5dGVzLgorICAgICAqLworICAgIHByaXZhdGUgY2xhc3MgVHJ1bmNhdGluZ091dHB1dFN0cmVhbSBleHRlbmRzIEJ5dGVBcnJheU91dHB1dFN0cmVhbSB7CisgICAgICAgIHByaXZhdGUgaW50IG51bUJ5dGVzUmVjZWl2ZWQgPSAwOworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbikgeworICAgICAgICAgICAgbnVtQnl0ZXNSZWNlaXZlZCArPSBsZW47CisgICAgICAgICAgICBzdXBlci53cml0ZShidWZmZXIsIG9mZnNldCwgTWF0aC5taW4obGVuLCBib2R5TGltaXQgLSBjb3VudCkpOworICAgICAgICB9CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgdm9pZCB3cml0ZShpbnQgb25lQnl0ZSkgeworICAgICAgICAgICAgbnVtQnl0ZXNSZWNlaXZlZCsrOworICAgICAgICAgICAgaWYgKGNvdW50IDwgYm9keUxpbWl0KSB7CisgICAgICAgICAgICAgICAgc3VwZXIud3JpdGUob25lQnl0ZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBSdW5uYWJsZSBuYW1lZFJ1bm5hYmxlKGZpbmFsIFN0cmluZyBuYW1lLCBmaW5hbCBSdW5uYWJsZSBydW5uYWJsZSkgeworICAgICAgICByZXR1cm4gbmV3IFJ1bm5hYmxlKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIFN0cmluZyBvcmlnaW5hbE5hbWUgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLnNldE5hbWUobmFtZSk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcnVubmFibGUucnVuKCk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5zZXROYW1lKG9yaWdpbmFsTmFtZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9odHRwL1JlY29yZGVkUmVxdWVzdC5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL2h0dHAvUmVjb3JkZWRSZXF1ZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzgwNTAwNgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9odHRwL1JlY29yZGVkUmVxdWVzdC5qYXZhCkBAIC0wLDAgKzEsODUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmh0dHA7CisKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBBbiBIVFRQIHJlcXVlc3QgdGhhdCBjYW1lIGludG8gdGhlIG1vY2sgd2ViIHNlcnZlci4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFJlY29yZGVkUmVxdWVzdCB7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcmVxdWVzdExpbmU7CisgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PFN0cmluZz4gaGVhZGVyczsKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8SW50ZWdlcj4gY2h1bmtTaXplczsKKyAgICBwcml2YXRlIGZpbmFsIGludCBib2R5U2l6ZTsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBib2R5OworICAgIHByaXZhdGUgZmluYWwgaW50IHNlcXVlbmNlTnVtYmVyOworCisgICAgUmVjb3JkZWRSZXF1ZXN0KFN0cmluZyByZXF1ZXN0TGluZSwgTGlzdDxTdHJpbmc+IGhlYWRlcnMsIExpc3Q8SW50ZWdlcj4gY2h1bmtTaXplcywKKyAgICAgICAgICAgIGludCBib2R5U2l6ZSwgYnl0ZVtdIGJvZHksIGludCBzZXF1ZW5jZU51bWJlcikgeworICAgICAgICB0aGlzLnJlcXVlc3RMaW5lID0gcmVxdWVzdExpbmU7CisgICAgICAgIHRoaXMuaGVhZGVycyA9IGhlYWRlcnM7CisgICAgICAgIHRoaXMuY2h1bmtTaXplcyA9IGNodW5rU2l6ZXM7CisgICAgICAgIHRoaXMuYm9keVNpemUgPSBib2R5U2l6ZTsKKyAgICAgICAgdGhpcy5ib2R5ID0gYm9keTsKKyAgICAgICAgdGhpcy5zZXF1ZW5jZU51bWJlciA9IHNlcXVlbmNlTnVtYmVyOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UmVxdWVzdExpbmUoKSB7CisgICAgICAgIHJldHVybiByZXF1ZXN0TGluZTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxTdHJpbmc+IGdldEhlYWRlcnMoKSB7CisgICAgICAgIHJldHVybiBoZWFkZXJzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNpemVzIG9mIHRoZSBjaHVua3Mgb2YgdGhpcyByZXF1ZXN0J3MgYm9keSwgb3IgYW4gZW1wdHkgbGlzdAorICAgICAqIGlmIHRoZSByZXF1ZXN0J3MgYm9keSB3YXMgZW1wdHkgb3IgdW5jaHVua2VkLgorICAgICAqLworICAgIHB1YmxpYyBMaXN0PEludGVnZXI+IGdldENodW5rU2l6ZXMoKSB7CisgICAgICAgIHJldHVybiBjaHVua1NpemVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRvdGFsIHNpemUgb2YgdGhlIGJvZHkgb2YgdGhpcyBQT1NUIHJlcXVlc3QgKGJlZm9yZQorICAgICAqIHRydW5jYXRpb24pLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Qm9keVNpemUoKSB7CisgICAgICAgIHJldHVybiBib2R5U2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBib2R5IG9mIHRoaXMgUE9TVCByZXF1ZXN0LiBUaGlzIG1heSBiZSB0cnVuY2F0ZWQuCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXRCb2R5KCkgeworICAgICAgICByZXR1cm4gYm9keTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGlzIHJlcXVlc3Qgb24gaXRzIEhUVFAgY29ubmVjdGlvbi4gU2luY2UgYSBzaW5nbGUKKyAgICAgKiBIVFRQIGNvbm5lY3Rpb24gbWF5IHNlcnZlIG11bHRpcGxlIHJlcXVlc3RzLCBlYWNoIHJlcXVlc3QgaXMgYXNzaWduZWQgaXRzCisgICAgICogb3duIHNlcXVlbmNlIG51bWJlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFNlcXVlbmNlTnVtYmVyKCkgeworICAgICAgICByZXR1cm4gc2VxdWVuY2VOdW1iZXI7CisgICAgfQorCisgICAgQE92ZXJyaWRlIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiByZXF1ZXN0TGluZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvaHR0cC9Tb2NrZXRQb2xpY3kuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9odHRwL1NvY2tldFBvbGljeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyMGI0MDAKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvaHR0cC9Tb2NrZXRQb2xpY3kuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5odHRwOworCisvKioKKyAqIFdoYXQgc2hvdWxkIGJlIGRvbmUgd2l0aCB0aGUgaW5jb21pbmcgc29ja2V0LgorICovCitwdWJsaWMgZW51bSBTb2NrZXRQb2xpY3kgeworCisgICAgLyoqCisgICAgICogS2VlcCB0aGUgc29ja2V0IG9wZW4gYWZ0ZXIgdGhlIHJlc3BvbnNlLiBUaGlzIGlzIHRoZSBkZWZhdWx0IEhUVFAvMS4xCisgICAgICogYmVoYXZpb3IuCisgICAgICovCisgICAgS0VFUF9PUEVOLAorCisgICAgLyoqCisgICAgICogQ2xvc2UgdGhlIHNvY2tldCBhZnRlciB0aGUgcmVzcG9uc2UuIFRoaXMgaXMgdGhlIGRlZmF1bHQgSFRUUC8xLjAKKyAgICAgKiBiZWhhdmlvci4KKyAgICAgKi8KKyAgICBESVNDT05ORUNUX0FUX0VORCwKKworICAgIC8qKgorICAgICAqIFdyYXAgdGhlIHNvY2tldCB3aXRoIFNTTCBhdCB0aGUgY29tcGxldGlvbiBvZiB0aGlzIHJlcXVlc3QvcmVzcG9uc2UKKyAgICAgKiBwYWlyLiBVc2VkIGZvciBDT05ORUNUIG1lc3NhZ2VzIHRvIHR1bm5lbCBTU0wgb3ZlciBhbiBIVFRQIHByb3h5LgorICAgICAqLworICAgIFVQR1JBREVfVE9fU1NMX0FUX0VORCwKKworICAgIC8qKgorICAgICAqIFJlcXVlc3QgaW1tZWRpYXRlIGNsb3NlIG9mIGNvbm5lY3Rpb24gd2l0aG91dCBldmVuIHJlYWRpbmcgdGhlCisgICAgICogcmVxdWVzdC4KKyAgICAgKgorICAgICAqIDxwPlVzZSB0byBzaW11bGF0ZSB0aGUgcmVhbCBsaWZlIGNhc2Ugb2YgbG9zaW5nIGNvbm5lY3Rpb24KKyAgICAgKiBiZWNhdXNlIG9mIGJ1Z2dlciBTU0wgc2VydmVyIGNsb3NlIGNvbm5lY3Rpb24gd2hlbiBpdCBzZWVtcworICAgICAqIHNvbWV0aGluZyBsaWtlIGEgY29tcHJlc3Npb24gbWV0aG9kIG9yIFRMUyBleHRlbnNpb24gaXQgZG9lc24ndAorICAgICAqIHVuZGVyc3RhbmQsIGluc3RlYWQgb2Ygc2ltcGx5IGlnbm9yaW5nIGl0IGxpa2UgaXQgc2hvdWxkLgorICAgICAqLworICAgIERJU0NPTk5FQ1RfQVRfU1RBUlQsCisKKyAgICAvKioKKyAgICAgKiBTaHV0ZG93biB0aGUgc29ja2V0IGlucHV0IGFmdGVyIHNlbmRpbmcgdGhlIHJlc3BvbnNlLiBGb3IgdGVzdGluZyBiYWQKKyAgICAgKiBiZWhhdmlvci4KKyAgICAgKi8KKyAgICBTSFVURE9XTl9JTlBVVF9BVF9FTkQsCisKKyAgICAvKioKKyAgICAgKiBTaHV0ZG93biB0aGUgc29ja2V0IG91dHB1dCBhZnRlciBzZW5kaW5nIHRoZSByZXNwb25zZS4gRm9yIHRlc3RpbmcgYmFkCisgICAgICogYmVoYXZpb3IuCisgICAgICovCisgICAgU0hVVERPV05fT1VUUFVUX0FUX0VORAorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL2lvL01vY2tPcy5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL2lvL01vY2tPcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3ZTI4NGYKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvaW8vTW9ja09zLmphdmEKQEAgLTAsMCArMSwxMjAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLmlvOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvbkhhbmRsZXI7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuUHJveHk7CitpbXBvcnQgamF2YS51dGlsLkFycmF5RGVxdWU7CitpbXBvcnQgamF2YS51dGlsLkRlcXVlOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgbGliY29yZS5pby5FcnJub0V4Y2VwdGlvbjsKK2ltcG9ydCBsaWJjb3JlLmlvLkxpYmNvcmU7CitpbXBvcnQgbGliY29yZS5pby5PczsKK2ltcG9ydCBsaWJjb3JlLmlvLk9zQ29uc3RhbnRzOworCisvKioKKyAqIEEgbW9ja2luZyBpbnRlcmNlcHRvciB0aGF0IHdyYXBzIGFub3RoZXIge0BsaW5rIE9zfSB0byBhZGQgZmF1bHRzLiBUaGlzIGNhbgorICogYmUgdXNlZnVsIHRvIHRlc3Qgb3RoZXJ3aXNlIGhhcmQtdG8tdGVzdCBzY2VuYXJpb3Mgc3VjaCBhcyBhIGZ1bGwgZGlzay4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE1vY2tPcyB7CisgICAgcHJpdmF0ZSBmaW5hbCBJbmhlcml0YWJsZVRocmVhZExvY2FsPE1hcDxTdHJpbmcsIERlcXVlPEludm9jYXRpb25IYW5kbGVyPj4+IGhhbmRsZXJzCisgICAgICAgICAgICA9IG5ldyBJbmhlcml0YWJsZVRocmVhZExvY2FsPE1hcDxTdHJpbmcsIERlcXVlPEludm9jYXRpb25IYW5kbGVyPj4+KCkgeworICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIE1hcDxTdHJpbmcsIERlcXVlPEludm9jYXRpb25IYW5kbGVyPj4gaW5pdGlhbFZhbHVlKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBIYXNoTWFwPFN0cmluZywgRGVxdWU8SW52b2NhdGlvbkhhbmRsZXI+PigpOworICAgICAgICB9CisgICAgfTsKKworICAgIHByaXZhdGUgT3MgZGVsZWdhdGU7CisgICAgcHJpdmF0ZSBmaW5hbCBJbnZvY2F0aW9uSGFuZGxlciBkZWxlZ2F0ZUhhbmRsZXIgPSBuZXcgSW52b2NhdGlvbkhhbmRsZXIoKSB7CisgICAgICAgIEBPdmVycmlkZSBwdWJsaWMgT2JqZWN0IGludm9rZShPYmplY3QgbywgTWV0aG9kIG1ldGhvZCwgT2JqZWN0W10gYXJncykgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJldHVybiBtZXRob2QuaW52b2tlKGRlbGVnYXRlLCBhcmdzKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHRocm93IGUuZ2V0Q2F1c2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH07CisKKyAgICBwcml2YXRlIGZpbmFsIEludm9jYXRpb25IYW5kbGVyIGludm9jYXRpb25IYW5kbGVyID0gbmV3IEludm9jYXRpb25IYW5kbGVyKCkgeworICAgICAgICBAT3ZlcnJpZGUgcHVibGljIE9iamVjdCBpbnZva2UoT2JqZWN0IHByb3h5LCBNZXRob2QgbWV0aG9kLCBPYmplY3RbXSBhcmdzKQorICAgICAgICAgICAgICAgIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICAgICAgSW52b2NhdGlvbkhhbmRsZXIgaGFuZGxlciA9IGdldEhhbmRsZXJzKG1ldGhvZC5nZXROYW1lKCkpLnBvbGwoKTsKKyAgICAgICAgICAgIGlmIChoYW5kbGVyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBoYW5kbGVyID0gZGVsZWdhdGVIYW5kbGVyOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGhhbmRsZXIuaW52b2tlKHByb3h5LCBtZXRob2QsIGFyZ3MpOworICAgICAgICB9CisgICAgfTsKKworICAgIHByaXZhdGUgZmluYWwgT3MgbW9ja09zID0gKE9zKSBQcm94eS5uZXdQcm94eUluc3RhbmNlKE1vY2tPcy5jbGFzcy5nZXRDbGFzc0xvYWRlcigpLAorICAgICAgICAgICAgbmV3IENsYXNzW10geyBPcy5jbGFzcyB9LCBpbnZvY2F0aW9uSGFuZGxlcik7CisKKyAgICBwdWJsaWMgdm9pZCBpbnN0YWxsKCkgeworICAgICAgICBpZiAoZGVsZWdhdGUgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiTW9ja09zIGFscmVhZHkgaW5zdGFsbGVkISIpOworICAgICAgICB9CisgICAgICAgIGRlbGVnYXRlID0gTGliY29yZS5vczsKKyAgICAgICAgTGliY29yZS5vcyA9IG1vY2tPczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bmluc3RhbGwoKSB7CisgICAgICAgIGlmIChkZWxlZ2F0ZSA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJNb2NrT3Mgbm90IGluc3RhbGxlZCEiKTsKKyAgICAgICAgfQorICAgICAgICBMaWJjb3JlLm9zID0gZGVsZWdhdGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW52b2NhdGlvbiBoYW5kbGVycyB0byBoYW5kbGUgdXBjb21pbmcgaW52b2NhdGlvbnMgb2YKKyAgICAgKiB7QGNvZGUgbWV0aG9kTmFtZX0uIElmIGVtcHR5LCBjYWxscyB3aWxsIGJlIGhhbmRsZWQgYnkgdGhlIGRlbGVnYXRlLgorICAgICAqLworICAgIHB1YmxpYyBEZXF1ZTxJbnZvY2F0aW9uSGFuZGxlcj4gZ2V0SGFuZGxlcnMoU3RyaW5nIG1ldGhvZE5hbWUpIHsKKyAgICAgICAgTWFwPFN0cmluZywgRGVxdWU8SW52b2NhdGlvbkhhbmRsZXI+PiB0aHJlYWRGYXVsdHMgPSBoYW5kbGVycy5nZXQoKTsKKyAgICAgICAgRGVxdWU8SW52b2NhdGlvbkhhbmRsZXI+IHJlc3VsdCA9IHRocmVhZEZhdWx0cy5nZXQobWV0aG9kTmFtZSk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmVzdWx0ID0gbmV3IEFycmF5RGVxdWU8SW52b2NhdGlvbkhhbmRsZXI+KCk7CisgICAgICAgICAgICB0aHJlYWRGYXVsdHMucHV0KG1ldGhvZE5hbWUsIHJlc3VsdCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbnF1ZXVlcyB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBub3JtYWwgb3BlcmF0aW9ucy4gVXNlZnVsIHRvIGRlbGF5CisgICAgICogZmF1bHRzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVucXVldWVOb3JtYWwoU3RyaW5nIG1ldGhvZE5hbWUsIGludCBjb3VudCkgeworICAgICAgICBEZXF1ZTxJbnZvY2F0aW9uSGFuZGxlcj4gaGFuZGxlcnMgPSBnZXRIYW5kbGVycyhtZXRob2ROYW1lKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CisgICAgICAgICAgICBoYW5kbGVycy5hZGQoZGVsZWdhdGVIYW5kbGVyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGVucXVldWVGYXVsdChTdHJpbmcgbWV0aG9kTmFtZSkgeworICAgICAgICBlbnF1ZXVlRmF1bHQobWV0aG9kTmFtZSwgT3NDb25zdGFudHMuRUlPKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbnF1ZXVlRmF1bHQoU3RyaW5nIG1ldGhvZE5hbWUsIGZpbmFsIGludCBlcnJubykgeworICAgICAgICBnZXRIYW5kbGVycyhtZXRob2ROYW1lKS5hZGQobmV3IEludm9jYXRpb25IYW5kbGVyKCkgeworICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBPYmplY3QgaW52b2tlKE9iamVjdCBwcm94eSwgTWV0aG9kIG1ldGhvZCwgT2JqZWN0W10gYXJncykgdGhyb3dzIEVycm5vRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJybm9FeGNlcHRpb24obWV0aG9kLmdldE5hbWUoKSwgZXJybm8pOworICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvbmV0L1N0dWNrU2VydmVyLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvbmV0L1N0dWNrU2VydmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWFiYWJjZQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9uZXQvU3R1Y2tTZXJ2ZXIuamF2YQpAQCAtMCwwICsxLDc1IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5uZXQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKKworLyoqCisgKiBBIHRlc3QgU2VydmVyU29ja2V0IHRoYXQgeW91IGNhbid0IGNvbm5lY3QgdG8gLS0tIGNvbm5lY3RzIHdpbGwgdGltZSBvdXQuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTdHVja1NlcnZlciB7CisgICAgcHJpdmF0ZSBTZXJ2ZXJTb2NrZXQgc2VydmVyU29ja2V0OworICAgIHByaXZhdGUgQXJyYXlMaXN0PFNvY2tldD4gY2xpZW50cyA9IG5ldyBBcnJheUxpc3Q8U29ja2V0PigpOworCisgICAgcHVibGljIFN0dWNrU2VydmVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gU2V0IGEgYmFja2xvZyBhbmQgdXNlIGl0IHVwIHNvIHRoYXQgd2UgY2FuIGV4cGVjdCB0aGUKKyAgICAgICAgLy8gY29ubmVjdGlvbiB0byB0aW1lIG91dC4gQWNjb3JkaW5nIHRvIFN0ZXZlbidzCisgICAgICAgIC8vIDQuNSAibGlzdGVuIGZ1bmN0aW9uIiwgTGludXggYWRkcyAzIHRvIHRoZSBzcGVjaWZpZWQKKyAgICAgICAgLy8gYmFja2xvZywgc28gd2UgbmVlZCB0byBjb25uZWN0IDQgdGltZXMgYmVmb3JlIGl0IHdpbGwgaGFuZy4KKyAgICAgICAgc2VydmVyU29ja2V0ID0gbmV3IFNlcnZlclNvY2tldCgwLCAxKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA0OyBpKyspIHsKKyAgICAgICAgICAgIGNsaWVudHMuYWRkKG5ldyBTb2NrZXQoc2VydmVyU29ja2V0LmdldEluZXRBZGRyZXNzKCksIHNlcnZlclNvY2tldC5nZXRMb2NhbFBvcnQoKSkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5ibG9ja0FmdGVyTXMoZmluYWwgaW50IG1zKSB7CisgICAgICAgIFRocmVhZCB0ID0gbmV3IFRocmVhZChuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcChtcyk7CisgICAgICAgICAgICAgICAgICAgIGZvciAoU29ja2V0IGNsaWVudCA6IGNsaWVudHMpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudC5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGNsaWVudHMuY2xlYXIoKTsKKyAgICAgICAgICAgICAgICAgICAgY2xpZW50cy5hZGQoc2VydmVyU29ja2V0LmFjY2VwdCgpKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAgICAgdC5zdGFydCgpOworICAgIH0KKworICAgIHB1YmxpYyBJbmV0U29ja2V0QWRkcmVzcyBnZXRMb2NhbFNvY2tldEFkZHJlc3MoKSB7CisgICAgICAgIHJldHVybiAoSW5ldFNvY2tldEFkZHJlc3MpIHNlcnZlclNvY2tldC5nZXRMb2NhbFNvY2tldEFkZHJlc3MoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldExvY2FsUG9ydCgpIHsKKyAgICAgICAgcmV0dXJuIHNlcnZlclNvY2tldC5nZXRMb2NhbFBvcnQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHNlcnZlclNvY2tldC5jbG9zZSgpOworICAgICAgICBmb3IgKFNvY2tldCBjbGllbnQgOiBjbGllbnRzKSB7CisgICAgICAgICAgICBjbGllbnQuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvQnJva2VuX2VudHJ5LmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvQnJva2VuX2VudHJ5LmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNmU3OTI3Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9Ccm9rZW5fZW50cnkuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvQnJva2VuX2VudHJ5X2RhdGEuamFyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9Ccm9rZW5fZW50cnlfZGF0YS5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWYzMzNlYQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvQnJva2VuX2VudHJ5X2RhdGEuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvQnJva2VuX21hbmlmZXN0LmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvQnJva2VuX21hbmlmZXN0LmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YzNmZjMxCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9Ccm9rZW5fbWFuaWZlc3QuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvQ3JlYXRlZF9ieV8xXzQuamFyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9DcmVhdGVkX2J5XzFfNC5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2E5MjRhMgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvQ3JlYXRlZF9ieV8xXzQuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvRW1wdHlFbnRyaWVzX3NpZ25lZC5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0VtcHR5RW50cmllc19zaWduZWQuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzN2QyNDQKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0VtcHR5RW50cmllc19zaWduZWQuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSGFybW9ueS5HSUYgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0hhcm1vbnkuR0lGCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJlMmRjNTYKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0hhcm1vbnkuR0lGCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSW5zZXJ0ZWRfRW50cnlfTWFuaWZlc3QuamFyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9JbnNlcnRlZF9FbnRyeV9NYW5pZmVzdC5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTU0ZDhkNgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSW5zZXJ0ZWRfRW50cnlfTWFuaWZlc3QuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSW5zZXJ0ZWRfRW50cnlfTWFuaWZlc3Rfd2l0aF9EaWdlc3RDb2RlLmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSW5zZXJ0ZWRfRW50cnlfTWFuaWZlc3Rfd2l0aF9EaWdlc3RDb2RlLmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOTRhZTQ5Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9JbnNlcnRlZF9FbnRyeV9NYW5pZmVzdF93aXRoX0RpZ2VzdENvZGUuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSW50ZWdyYXRlLmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSW50ZWdyYXRlLmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNmU5YzU1Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9JbnRlZ3JhdGUuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSmFySW5kZXgvaHl0c18xMS5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMTEuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE5Y2Y1ZjIKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMTEuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSmFySW5kZXgvaHl0c18xMi5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMTIuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzNjY1OWIKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMTIuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSmFySW5kZXgvaHl0c18xMy5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMTMuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjllYTY4MDYKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMTMuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSmFySW5kZXgvaHl0c18xNC5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMTQuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ4YmM0NGIKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMTQuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSmFySW5kZXgvaHl0c18yMS5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMjEuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyNWQ0YmYKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMjEuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSmFySW5kZXgvaHl0c18yMi1uZXcuamFyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9KYXJJbmRleC9oeXRzXzIyLW5ldy5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTQyYzIyYQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSmFySW5kZXgvaHl0c18yMi1uZXcuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSmFySW5kZXgvaHl0c18yMi5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMjIuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg0YzdhZjAKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMjIuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSmFySW5kZXgvaHl0c18yMy5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMjMuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE5MzIwNTIKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMjMuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSmFySW5kZXgvaHl0c18zMS5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMzEuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiNjk2OTYKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMzEuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSmFySW5kZXgvaHl0c18zMi5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMzIuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEyZGU2YmIKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMzIuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSmFySW5kZXgvaHl0c18zMy5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMzMuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA4NmU0OTQKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfMzMuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSmFySW5kZXgvaHl0c180MS5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfNDEuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZiNzFiZjgKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfNDEuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvSmFySW5kZXgvaHl0c180Mi5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfNDIuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA2YTM1Y2QKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL0phckluZGV4L2h5dHNfNDIuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvTW9kaWZpZWRfQ2xhc3MuamFyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9Nb2RpZmllZF9DbGFzcy5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDgxMTNjNwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvTW9kaWZpZWRfQ2xhc3MuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvTW9kaWZpZWRfTWFuaWZlc3RfRW50cnlBdHRyaWJ1dGVzLmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvTW9kaWZpZWRfTWFuaWZlc3RfRW50cnlBdHRyaWJ1dGVzLmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZDFkYmIxCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9Nb2RpZmllZF9NYW5pZmVzdF9FbnRyeUF0dHJpYnV0ZXMuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvTW9kaWZpZWRfTWFuaWZlc3RfTWFpbkF0dHJpYnV0ZXMuamFyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9Nb2RpZmllZF9NYW5pZmVzdF9NYWluQXR0cmlidXRlcy5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWJjNjBlNgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvTW9kaWZpZWRfTWFuaWZlc3RfTWFpbkF0dHJpYnV0ZXMuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvTW9kaWZpZWRfU0ZfRW50cnlBdHRyaWJ1dGVzLmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvTW9kaWZpZWRfU0ZfRW50cnlBdHRyaWJ1dGVzLmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43Yjc2Njk0Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9Nb2RpZmllZF9TRl9FbnRyeUF0dHJpYnV0ZXMuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX2FsbF9hdHRyaWJ1dGVzLmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX2FsbF9hdHRyaWJ1dGVzLmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZGUzZjRkCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9QYWNrYWdlL2h5dHNfYWxsX2F0dHJpYnV0ZXMuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX2FsbF9hdHRyaWJ1dGVzX2RleC5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL1BhY2thZ2UvaHl0c19hbGxfYXR0cmlidXRlc19kZXguamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI5ZGE0M2YKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL1BhY2thZ2UvaHl0c19hbGxfYXR0cmlidXRlc19kZXguamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX2MuamFyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9QYWNrYWdlL2h5dHNfYy5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTExZjczYwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX2MuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX2NfZGV4LmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX2NfZGV4LmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYzJiYTFiCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9QYWNrYWdlL2h5dHNfY19kZXguamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX25vX2F0dHJpYnV0ZXMuamFyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9QYWNrYWdlL2h5dHNfbm9fYXR0cmlidXRlcy5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTg3OWFjYgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX25vX2F0dHJpYnV0ZXMuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX25vX2F0dHJpYnV0ZXNfZGV4LmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX25vX2F0dHJpYnV0ZXNfZGV4LmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iM2M2MWVmCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9QYWNrYWdlL2h5dHNfbm9fYXR0cmlidXRlc19kZXguamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX25vX2VudHJ5LmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX25vX2VudHJ5LmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NjA5MGE1Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9QYWNrYWdlL2h5dHNfbm9fZW50cnkuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX25vX2VudHJ5X2RleC5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL1BhY2thZ2UvaHl0c19ub19lbnRyeV9kZXguamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2Nzc3ZjYKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL1BhY2thZ2UvaHl0c19ub19lbnRyeV9kZXguamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX3BhY2thZ2UuamFyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9QYWNrYWdlL2h5dHNfcGFja2FnZS5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODFmNzJjMQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX3BhY2thZ2UuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX3BhY2thZ2VfZGV4LmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX3BhY2thZ2VfZGV4LmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MzdhZDBkCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9QYWNrYWdlL2h5dHNfcGFja2FnZV9kZXguamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX3BxLmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX3BxLmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OTE5ZjZjCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9QYWNrYWdlL2h5dHNfcHEuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX3BxX2RleC5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL1BhY2thZ2UvaHl0c19wcV9kZXguamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjNDVkYzkKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL1BhY2thZ2UvaHl0c19wcV9kZXguamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX3NvbWVfYXR0cmlidXRlcy5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL1BhY2thZ2UvaHl0c19zb21lX2F0dHJpYnV0ZXMuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk1Yzg3YTgKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL1BhY2thZ2UvaHl0c19zb21lX2F0dHJpYnV0ZXMuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX3NvbWVfYXR0cmlidXRlc19kZXguamFyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9QYWNrYWdlL2h5dHNfc29tZV9hdHRyaWJ1dGVzX2RleC5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDZhYjhiOQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvUGFja2FnZS9oeXRzX3NvbWVfYXR0cmlidXRlc19kZXguamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvVGVzdENvZGVTaWduZXJzLmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvVGVzdENvZGVTaWduZXJzLmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNGM0MmFhCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9UZXN0Q29kZVNpZ25lcnMuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvY3RzX2RhbHZpa0V4ZWNUZXN0LmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvY3RzX2RhbHZpa0V4ZWNUZXN0LmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNmFmNzkxCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9jdHNfZGFsdmlrRXhlY1Rlc3QuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvY3RzX2RhbHZpa0V4ZWNUZXN0X2NsYXNzZXMuZGV4IGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9jdHNfZGFsdmlrRXhlY1Rlc3RfY2xhc3Nlcy5kZXgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDE1YzUwYQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvY3RzX2RhbHZpa0V4ZWNUZXN0X2NsYXNzZXMuZGV4CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19CYXIuc2VyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX0Jhci5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjgwMjUyOAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19CYXIuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19Gb28uc2VyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX0Zvby5zZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWY1MTFhYwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19Gb28uc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19Qcm9wZXJ0aWVzVGVzdC5wcm9wZXJ0aWVzIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX1Byb3BlcnRpZXNUZXN0LnByb3BlcnRpZXMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmMxYjk1MAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19Qcm9wZXJ0aWVzVGVzdC5wcm9wZXJ0aWVzCkBAIC0wLDAgKzEsMjkgQEAKKworCisgICAgCisgICAgCQkKKyAgIFwgXHIgXG4gXHQgXGYKKyAgIAorICAgICAgICAgICAgCQkJCQkKKyEgZHNoZmprbGFoZmprbGRhc2hnamw7YXMKKyAgICAgI2pkZmFnZGZqYWdrZGpmZ2hrc2RhamZkCisgICAgIAorISFwcm9wZXJ0aWVzCisKK2E9YQorYiBiYiBhcyxkbiAgIAorY1xyXCBcdFxudSA9OjogY3UKK2J1PSBiXAorCQl1CitkPWRcclxuZT1lCitmICAgOmZcCitmXAorCQkJZgorZwkJZworaFx1MDAyMGgKK1wgICBpPWkKK2o9XCAgIGoKK3NwYWNlPVwgICBjCisKK2RibGJhY2tzbGFzaD1cXAorICAgICAgICAgICAgICAgICAgICAgICAgClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX1ppcEZpbGUuemlwIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX1ppcEZpbGUuemlwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY5Y2Q2ZWQKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfWmlwRmlsZS56aXAKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2F0dC5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfYXR0LmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZjQ1MzBjCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2F0dC5qYXIKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2F2YWlsYWJsZS50c3QgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfYXZhaWxhYmxlLnRzdApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNjdiMmY0Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2F2YWlsYWJsZS50c3QKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2NoZWNrSW5wdXQudHh0IGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2NoZWNrSW5wdXQudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZkNDlkMzMKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfY2hlY2tJbnB1dC50eHQKQEAgLTAsMCArMSw0IEBACisJY3JjLnJlc2V0KCk7DQorCWNyYy51cGRhdGUoMSk7DQorCS8vU3lzdGVtLm91dC5wcmludCgidmFsdWUgb2YgY3JjIitjcmMuZ2V0VmFsdWUoKSk7IA0KKwkKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfY29tcERpY3Rpb24udHh0IGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2NvbXBEaWN0aW9uLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMDQ3OGM4Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2NvbXBEaWN0aW9uLnR4dApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfY29tcHJlc3NELnR4dCBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19jb21wcmVzc0QudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2Yzg5ZjIKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfY29tcHJlc3NELnR4dApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfY29uc3RydV9PLnR4dCBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19jb25zdHJ1X08udHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2YmQ3YjQKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfY29uc3RydV9PLnR4dApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfY29uc3RydV9PRC50eHQgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfY29uc3RydV9PRC50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDM1ZDEyZQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19jb25zdHJ1X09ELnR4dApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfY29uc3RydV9PREkudHh0IGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2NvbnN0cnVfT0RJLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZTVkMjg0Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2NvbnN0cnVfT0RJLnR4dApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QxLmNpcGhlcnRleHQgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QxLmNpcGhlcnRleHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmQ3Yjk0YgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDEuY2lwaGVydGV4dApAQCAtMCwwICsxIEBACishnSNvTnumQApcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDEuaXYgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QxLml2Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQwMWYzMzUKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QxLml2CkBAIC0wLDAgKzEgQEAKK570UQYyI1BcClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0MS5rZXkgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QxLmtleQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZmZiNWVhCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0MS5rZXkKQEAgLTAsMCArMSBAQAoraWfqjmtYjNy0dOp5QSOYeyAeho/0GfYkClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0MS5wbGFpbnRleHQgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QxLnBsYWludGV4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45Nzg3ZWUyCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0MS5wbGFpbnRleHQKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0Mi5jaXBoZXJ0ZXh0IGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0Mi5jaXBoZXJ0ZXh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFhZTNmOTYKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QyLmNpcGhlcnRleHQKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0Mi5pdiBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDIuaXYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzI2NjBmYwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDIuaXYKQEAgLTAsMCArMSBAQAorQPYijRXQlzwKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QyLmtleSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDIua2V5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk4NzZmM2YKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QyLmtleQpAQCAtMCwwICsxIEBACitxkjy7xSgTR+Xiwc6h1JGAH0meOsbhuScKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QyLnBsYWludGV4dCBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDIucGxhaW50ZXh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFiNWVmNGEKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QyLnBsYWludGV4dApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QzLmNpcGhlcnRleHQgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QzLmNpcGhlcnRleHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjlkZDYwMAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDMuY2lwaGVydGV4dApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfZGVzLWVkZTMtY2JjLnRlc3QzLml2IGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0My5pdgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YTZkZWQ1Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0My5pdgpAQCAtMCwwICsxIEBACiv3ln7eU3JbCQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDMua2V5IGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0My5rZXkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTE4ZmQ4OQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDMua2V5CkBAIC0wLDAgKzEgQEAKK+/dL11vs6hE0M61nlBlyQW1ruC4MD8GNgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDMucGxhaW50ZXh0IGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2Rlcy1lZGUzLWNiYy50ZXN0My5wbGFpbnRleHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjQ1YmQ4OAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19kZXMtZWRlMy1jYmMudGVzdDMucGxhaW50ZXh0CkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19odG1sdGVzdC5odG1sIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX2h0bWx0ZXN0Lmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTQ2NDM3MQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19odG1sdGVzdC5odG1sCkBAIC0wLDAgKzEsMzggQEAKKzxIVE1MPgorPFRJVExFPlRlc3QgSFRNTCBEb2N1bWVudDwvVElUTEU+Cis8Qk9EWT4KKzxIMj5UZXN0IEhUTUwgRG9jdW1lbnQ8L0gyPgorVGhpcyBmaWxlIGlzIHVzZWQgYnkgdGhlIDxDT0RFPlRlc3RfamF2YV9uZXRfVVJMLnRlc3RfZ2V0Q29udGVudCgpPC9DT0RFPi4KKzxwPgorSXQgY29udGFpbnMgdGhlIHN0cmluZyA8cXVvdGU+QSBTZWVtaW5nbHkgTm9uIEltcG9ydGFudCBTdHJpbmc8L3F1b3RlPi4gV2hpY2ggaXMKK2xvb2tlZCBmb3IgaW4gdGhlIHRlc3RjYXNlLjxQPgorPFVMPgorPExJPkEgTGluZSBvZiB0ZXh0PC9MST4KKzxMST5BIExpbmUgb2YgdGV4dDwvTEk+Cis8TEk+QSBMaW5lIG9mIHRleHQ8L0xJPgorPExJPkEgTGluZSBvZiB0ZXh0PC9MST4KKzxMST5BIExpbmUgb2YgdGV4dDwvTEk+Cis8TEk+QSBMaW5lIG9mIHRleHQ8L0xJPgorPExJPkEgTGluZSBvZiB0ZXh0PC9MST4KKzxMST5BIExpbmUgb2YgdGV4dDwvTEk+Cis8TEk+QSBMaW5lIG9mIHRleHQ8L0xJPgorPExJPkEgTGluZSBvZiB0ZXh0PC9MST4KKzxMST5BIExpbmUgb2YgdGV4dDwvTEk+Cis8TEk+QSBMaW5lIG9mIHRleHQ8L0xJPgorPExJPkEgTGluZSBvZiB0ZXh0PC9MST4KKzxMST5BIExpbmUgb2YgdGV4dDwvTEk+Cis8TEk+QSBMaW5lIG9mIHRleHQ8L0xJPgorPExJPkEgTGluZSBvZiB0ZXh0PC9MST4KKzxMST5BIExpbmUgb2YgdGV4dDwvTEk+Cis8TEk+QSBMaW5lIG9mIHRleHQ8L0xJPgorPExJPkEgTGluZSBvZiB0ZXh0PC9MST4KKzxMST5BIExpbmUgb2YgdGV4dDwvTEk+Cis8TEk+QSBMaW5lIG9mIHRleHQ8L0xJPgorPExJPkEgTGluZSBvZiB0ZXh0PC9MST4KKzwvVUw+Cis8cD4KK0EgYnVuY2ggb2YgdGV4dCByZXByZXNlbnRpbmcgcGFydCBvZiBhIHBhcmFncmFwaC4gQSBidW5jaCBvZiB0ZXh0IHJlcHJlc2VudGluZyBwYXJ0IG9mIGEgcGFyYWdyYXBoLiBBIGJ1bmNoIG9mIHRleHQgcmVwcmVzZW50aW5nIHBhcnQgb2YgYSBwYXJhZ3JhcGguIEEgYnVuY2ggb2YgdGV4dCByZXByZXNlbnRpbmcgcGFydCBvZiBhIHBhcmFncmFwaC4gQSBidW5jaCBvZiB0ZXh0IHJlcHJlc2VudGluZyBwYXJ0IG9mIGEgcGFyYWdyYXBoLiBBIGJ1bmNoIG9mIHRleHQgcmVwcmVzZW50aW5nIHBhcnQgb2YgYSBwYXJhZ3JhcGguIEEgYnVuY2ggb2YgdGV4dCByZXByZXNlbnRpbmcgcGFydCBvZiBhIHBhcmFncmFwaC4gQSBidW5jaCBvZiB0ZXh0IHJlcHJlc2VudGluZyBwYXJ0IG9mIGEgcGFyYWdyYXBoLiBBIGJ1bmNoIG9mIHRleHQgcmVwcmVzZW50aW5nIHBhcnQgb2YgYSBwYXJhZ3JhcGguIEEgYnVuY2ggb2YgdGV4dCByZXByZXNlbnRpbmcgcGFydCBvZiBhIHBhcmFncmFwaC4gQSBidW5jaCBvZiB0ZXh0IHJlcHJlc2VudGluZyBwYXJ0IG9mIGEgcGFyYWdyYXBoLiBBIGJ1bmNoIG9mIHRleHQgcmVwcmVzZW50aW5nIHBhcnQgb2YgYSBwYXJhZ3JhcGguIEEgYnVuY2ggb2YgdGV4dCByZXByZXNlbnRpbmcgcGFydCBvZiBhIHBhcmFncmFwaC4gQSBidW5jaCBvZiB0ZXh0IHJlcHJlc2VudGluZyBwYXJ0IG9mIGEgcGFyYWdyYXBoLiBBIGJ1bmNoIG9mIHRleHQgcmVwcmVzZW50aW5nIHBhcnQgb2YgYSBwYXJhZ3JhcGguIEEgYnVuY2ggb2YgdGV4dCByZXByZXNlbnRpbmcgcGFydCBvZiBhIHBhcmFncmFwaC4gQSBidW5jaCBvZiB0ZXh0IHJlcHJlc2VudGluZyBwYXJ0IG9mIGEgcGFyYWdyYXBoLiBBIGJ1bmNoIG9mIHRleHQgcmVwcmVzZW50aW5nIHBhcnQgb2YgYSBwYXJhZ3JhcGguIEEgYnVuY2ggb2YgdGV4dCByZXByZXNlbnRpbmcgcGFydCBvZiBhIHBhcmFncmFwaC4gQSBidW5jaCBvZiB0ZXh0IHJlcHJlc2VudGluZyBwYXJ0IG9mIGEgcGFyYWdyYXBoLiBBIGJ1bmNoIG9mIHRleHQgcmVwcmVzZW50aW5nIHBhcnQgb2YgYSBwYXJhZ3JhcGguIEEgYnVuY2ggb2YgdGV4dCByZXByZXNlbnRpbmcgcGFydCBvZiBhIHBhcmFncmFwaC4gQSBidW5jaCBvZiB0ZXh0IHJlcHJlc2VudGluZyBwYXJ0IG9mIGEgcGFyYWdyYXBoLiBBIGJ1bmNoIG9mIHRleHQgcmVwcmVzZW50aW5nIHBhcnQgb2YgYSBwYXJhZ3JhcGguIEEgYnVuY2ggb2YgdGV4dCByZXByZXNlbnRpbmcgcGFydCBvZiBhIHBhcmFncmFwaC4gQSBidW5jaCBvZiB0ZXh0IHJlcHJlc2VudGluZyBwYXJ0IG9mIGEgcGFyYWdyYXBoLiBBIGJ1bmNoIG9mIHRleHQgcmVwcmVzZW50aW5nIHBhcnQgb2YgYSBwYXJhZ3JhcGguIEEgYnVuY2ggb2YgdGV4dCByZXByZXNlbnRpbmcgcGFydCBvZiBhIHBhcmFncmFwaC4gQSBidW5jaCBvZiB0ZXh0IHJlcHJlc2VudGluZyBwYXJ0IG9mIGEgcGFyYWdyYXBoLiA8cD4KKworVGhlIEVuZC4KKzwvQk9EWT4KKzwvSFRNTD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfbWFpbkNsYXNzLnNlciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19tYWluQ2xhc3Muc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA0MjFiYTkKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfbWFpbkNsYXNzLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfbWFuaWZlc3QxLmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19tYW5pZmVzdDEuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZiMjkyYjIKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfbWFuaWZlc3QxLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfbWlzc2luZ2NsYXNzLnNlciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19taXNzaW5nY2xhc3Muc2VyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBhNzE0MDMKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfbWlzc2luZ2NsYXNzLnNlcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfcGF0Y2guamFyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX3BhdGNoLmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mM2M1MWQwCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX3BhdGNoLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfcGF0Y2gyLmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19wYXRjaDIuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyNmY5ZTcKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfcGF0Y2gyLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfcmVzb3VyY2UucHJvcGVydGllcyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19yZXNvdXJjZS5wcm9wZXJ0aWVzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmExNzJhM2UKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfcmVzb3VyY2UucHJvcGVydGllcwpAQCAtMCwwICsxLDIgQEAKK3Byb3BlcnR5PXBhcmVudAorIApcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19zZWN1cml0eS5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfc2VjdXJpdHkuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiZWY2NzUKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL2h5dHNfc2VjdXJpdHkuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19zaWduZWQuamFyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX3NpZ25lZC5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGVhODQ4OQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19zaWduZWQuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19zaWduZWRfaW5jLmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaHl0c19zaWduZWRfaW5jLmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNzVjZTA4Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9oeXRzX3NpZ25lZF9pbmMuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaWxsZWdhbENsYXNzZXMuamFyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9pbGxlZ2FsQ2xhc3Nlcy5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2UwZWI4NgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvaWxsZWdhbENsYXNzZXMuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvanVuaXQ0LTQuMy4xLmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvanVuaXQ0LTQuMy4xLmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YmNkYmE3Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9qdW5pdDQtNC4zLjEuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvbWFuaWZlc3QvaHl0c19NQU5JRkVTVC5NRiBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvbWFuaWZlc3QvaHl0c19NQU5JRkVTVC5NRgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNDAyYmNhCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9tYW5pZmVzdC9oeXRzX01BTklGRVNULk1GCkBAIC0wLDAgKzEsMjYgQEAKK01hbmlmZXN0LVZlcnNpb246IDEuMAorQnVuZGxlLU5hbWU6IENsaWVudFN1cHBvcnQKK0J1bmRsZS1EZXNjcmlwdGlvbjogUHJvdmlkZXMgU2Vzc2lvblNlcnZpY2UsIEF1dGhlbnRpY2F0aW9uU2VydmljZS4gRXh0ZW5kcyBSZWdpc3RyeVNlcnZpY2UuCitCdW5kbGUtQWN0aXZhdG9yOiBjb20uaWJtLml2ZS5lY2NvbW0uY2xpZW50LnN1cHBvcnQuQ2xpZW50U3VwcG9ydEFjdGl2YXRvcgorSW1wb3J0LVBhY2thZ2U6IGNvbS5pYm0uaXZlLmVjY29tbS5jbGllbnQuc2VydmljZXMubG9nLAorIGNvbS5pYm0uaXZlLmVjY29tbS5jbGllbnQuc2VydmljZXMucmVnaXN0cnksCisgY29tLmlibS5pdmUuZWNjb21tLnNlcnZpY2UucmVnaXN0cnk7IHNwZWNpZmljYXRpb24tdmVyc2lvbj0xLjAuMCwKKyBjb20uaWJtLml2ZS5lY2NvbW0uc2VydmljZS5zZXNzaW9uOyBzcGVjaWZpY2F0aW9uLXZlcnNpb249MS4wLjAsCisgY29tLmlibS5pdmUuZWNjb21tLnNlcnZpY2UuZnJhbWV3b3JrOyBzcGVjaWZpY2F0aW9uLXZlcnNpb249MS4yLjAsCisgb3JnLm9zZ2kuZnJhbWV3b3JrOyBzcGVjaWZpY2F0aW9uLXZlcnNpb249MS4wLjAsCisgb3JnLm9zZ2kuc2VydmljZS5sb2c7IHNwZWNpZmljYXRpb24tdmVyc2lvbj0xLjAuMCwKKyBjb20uaWJtLml2ZS5lY2NvbW0uZmxhc2g7IHNwZWNpZmljYXRpb24tdmVyc2lvbj0xLjIuMCwKKyBjb20uaWJtLml2ZS5lY2NvbW0uY2xpZW50LnhtbCwKKyBjb20uaWJtLml2ZS5lY2NvbW0uY2xpZW50Lmh0dHAuY29tbW9uLAorIGNvbS5pYm0uaXZlLmVjY29tbS5jbGllbnQuaHR0cC5jbGllbnQKK0ltcG9ydC1TZXJ2aWNlOiBvcmcub3NnaS5zZXJ2aWNlLmxvZy5Mb2dSZWFkZXJTZXJ2aWNlCisgb3JnLm9zZ2kuc2VydmljZS5sb2cuTG9nU2VydmljZSwKKyBjb20uaWJtLml2ZS5lY2NvbW0uc2VydmljZS5yZWdpc3RyeS5SZWdpc3RyeVNlcnZpY2UKK0V4cG9ydC1QYWNrYWdlOiBjb20uaWJtLml2ZS5lY2NvbW0uY2xpZW50LnNlcnZpY2VzLmF1dGhlbnRpY2F0aW9uOyBzcGVjaWZpY2F0aW9uLXZlcnNpb249MS4wLjAsCisgY29tLmlibS5pdmUuZWNjb21tLnNlcnZpY2UuYXV0aGVudGljYXRpb247IHNwZWNpZmljYXRpb24tdmVyc2lvbj0xLjAuMCwKKyBjb20uaWJtLml2ZS5lY2NvbW0uY29tbW9uOyBzcGVjaWZpY2F0aW9uLXZlcnNpb249MS4wLjAsCisgY29tLmlibS5pdmUuZWNjb21tLmNsaWVudC5zZXJ2aWNlcy5yZWdpc3RyeS5zdG9yZTsgc3BlY2lmaWNhdGlvbi12ZXJzaW9uPTEuMC4wCitFeHBvcnQtU2VydmljZTogY29tLmlibS5pdmUuZWNjb21tLnNlcnZpY2UuYXV0aGVudGljYXRpb24uQXV0aGVudGljYXRpb25TZXJ2aWNlLAorIGNvbS5pYm0uaXZlLmVjY29tbS5zZXJ2aWNlLnNlc3Npb24uU2Vzc2lvblNlcnZpY2UKK0J1bmRsZS1WZW5kb3I6IElCTQorQnVuZGxlLVZlcnNpb246IDEuMi4wCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL21vcmVzdHVmZi9oeXRzX3BhdGNoLmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvbW9yZXN0dWZmL2h5dHNfcGF0Y2guamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYzYzUxZDAKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL21vcmVzdHVmZi9oeXRzX3BhdGNoLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL21vcmVzdHVmZi9oeXRzX3BhdGNoMi5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL21vcmVzdHVmZi9oeXRzX3BhdGNoMi5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzI2ZjllNwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvbW9yZXN0dWZmL2h5dHNfcGF0Y2gyLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL25ldC9JbnZhbGlkSmFyLmphciBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvbmV0L0ludmFsaWRKYXIuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQyZGU0MDQKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL25ldC9JbnZhbGlkSmFyLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL25ldC9UZXN0Q29kZVNpZ25lcnMuamFyIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9uZXQvVGVzdENvZGVTaWduZXJzLmphcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNGM0MmFhCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9uZXQvVGVzdENvZGVTaWduZXJzLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL25ldC9sZi5qYXIgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL25ldC9sZi5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWNhOGYzNwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9yZXNvdXJjZXMvbmV0L2xmLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL3N1YmZvbGRlci90ZXN0cy9yZXNvdXJjZXMvaHl0c19yZXNvdXJjZS5wcm9wZXJ0aWVzIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9zdWJmb2xkZXIvdGVzdHMvcmVzb3VyY2VzL2h5dHNfcmVzb3VyY2UucHJvcGVydGllcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZjA2Zjk3Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy9zdWJmb2xkZXIvdGVzdHMvcmVzb3VyY2VzL2h5dHNfcmVzb3VyY2UucHJvcGVydGllcwpAQCAtMCwwICsxLDIgQEAKK3Byb3BlcnR5PXJlc291cmNlCisgClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy90ZXN0LmNlcnQgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvcmVzb3VyY2VzL3Rlc3QuY2VydApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZjEyZmViCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3Jlc291cmNlcy90ZXN0LmNlcnQKQEAgLTAsMCArMSwxNyBAQAorLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCitNSUlDcFRDQ0FnNENDUUNXOGM5b0cwS2M4REFOQmdrcWhraUc5dzBCQVFVRkFEQ0JsakVMTUFrR0ExVUVCaE1DCitRMGd4RHpBTkJnTlZCQWdUQmxwMWNtbGphREVUTUJFR0ExVUVCeE1LVjJsdWRHVnlkR2gxY2pFT01Bd0dBMVVFCitDaE1GVG05elpYSXhEVEFMQmdOVkJBc1RCRzV2Ym1VeEdEQVdCZ05WQkFNVEQwRnNaWGhoYm1SbGNpQkpjbWhwCitiakVvTUNZR0NTcUdTSWIzRFFFSkFSWVpRV3hsZUdGdVpHVnlMa2x5YUdsdVFHZHRZV2xzTG1OdmJUQWVGdzB3CitPREV4TVRNd09UVTFNVGRhRncwM05ERXdNall3TXpJM01ERmFNSUdXTVFzd0NRWURWUVFHRXdKRFNERVBNQTBHCitBMVVFQ0JNR1duVnlhV05vTVJNd0VRWURWUVFIRXdwWGFXNTBaWEowYUhWeU1RNHdEQVlEVlFRS0V3Vk9iM05sCitjakVOTUFzR0ExVUVDeE1FYm05dVpURVlNQllHQTFVRUF4TVBRV3hsZUdGdVpHVnlJRWx5YUdsdU1TZ3dKZ1lKCitLb1pJaHZjTkFRa0JGaGxCYkdWNFlXNWtaWEl1U1hKb2FXNUFaMjFoYVd3dVkyOXRNSUdmTUEwR0NTcUdTSWIzCitEUUVCQVFVQUE0R05BRENCaVFLQmdRREJxK25HUjVSVVZyQ1hWdnpzN0pjbWh3M2h0ZDhoLy9kT1h5d3ZpVHdFCitNQjllZzNpY1JVb0lvNVdUVURVVjNQaDcrZ2VuNHlxVFQ1ZkoydDNVK2Nxd2lqb29mVWVwdS95WUpSK0pMd04vCitoTXA3WmYzdk45amc1dHM2ZlhVVEZyTTZvcXJ1Mk85STdydER1cmVVY1prYU4vUHlMZWFucjVSdjdSYmRMbU1zCitsd0lEQVFBQk1BMEdDU3FHU0liM0RRRUJCUVVBQTRHQkFCMXl5YWY4UjhKVlNLZFZldmVmdjRLaC9wTVJZR3UzCit2MnFNcitTODZ5RmhoaGF2TEtOcng5WWovY1pLYWxFTDgvMzFYdEdmaWd4TzZZOVZ2QytMM0ptVlQvYW9NdWhECitYVGhWZzkxK1g0NE9Rc0hsNURpN2pRclZYQ05RUHg4MVo0NHR6QmZienA0ME9TRjFFSWg1MnY5a0ptUmluZ0NwCitSaUhnU1JOWXR1RmIKKy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9BbGdvcml0aG1QYXJhbWV0ZXJBc3ltbWV0cmljSGVscGVyLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvQWxnb3JpdGhtUGFyYW1ldGVyQXN5bW1ldHJpY0hlbHBlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg5ODA5ZTEKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvQWxnb3JpdGhtUGFyYW1ldGVyQXN5bW1ldHJpY0hlbHBlci5qYXZhCkBAIC0wLDAgKzEsMTAxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmF4LmNyeXB0by5CYWRQYWRkaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXI7CitpbXBvcnQgamF2YXguY3J5cHRvLklsbGVnYWxCbG9ja1NpemVFeGNlcHRpb247CitpbXBvcnQgamF2YXguY3J5cHRvLk5vU3VjaFBhZGRpbmdFeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydDsKKworcHVibGljIGNsYXNzIEFsZ29yaXRobVBhcmFtZXRlckFzeW1tZXRyaWNIZWxwZXIgZXh0ZW5kcyBUZXN0SGVscGVyPEFsZ29yaXRobVBhcmFtZXRlcnM+IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBwbGFpbkRhdGEgPSAic29tZSBkYXRhIHRvIGVuY3J5cHQgYW5kIGRlY3J5cHQiOworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGFsZ29yaXRobU5hbWU7CisKKyAgICBwdWJsaWMgQWxnb3JpdGhtUGFyYW1ldGVyQXN5bW1ldHJpY0hlbHBlcihTdHJpbmcgYWxnb3JpdGhtTmFtZSkgeworICAgICAgICB0aGlzLmFsZ29yaXRobU5hbWUgPSBhbGdvcml0aG1OYW1lOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHRlc3QoQWxnb3JpdGhtUGFyYW1ldGVycyBwYXJhbWV0ZXJzKSB7CisKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvciBnZW5lcmF0b3IgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZ2VuZXJhdG9yID0gS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGdlbmVyYXRvci5pbml0aWFsaXplKDEwMjQpOworCisgICAgICAgIEtleVBhaXIga2V5UGFpciA9IGdlbmVyYXRvci5nZW5lcmF0ZUtleVBhaXIoKTsKKworCisgICAgICAgIENpcGhlciBjaXBoZXIgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2lwaGVyID0gQ2lwaGVyLmdldEluc3RhbmNlKGFsZ29yaXRobU5hbWUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgQXNzZXJ0LmZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hQYWRkaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaXBoZXIuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBrZXlQYWlyLmdldFB1YmxpYygpLCBwYXJhbWV0ZXJzKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRBbGdvcml0aG1QYXJhbWV0ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgQXNzZXJ0LmZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZVtdIGJzID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJzID0gY2lwaGVyLmRvRmluYWwocGxhaW5EYXRhLmdldEJ5dGVzKCkpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoQmFkUGFkZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2lwaGVyLmluaXQoQ2lwaGVyLkRFQ1JZUFRfTU9ERSwga2V5UGFpci5nZXRQcml2YXRlKCksIHBhcmFtZXRlcnMpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBieXRlW10gZGVjcnlwdGVkID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRlY3J5cHRlZCA9IGNpcGhlci5kb0ZpbmFsKGJzKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKEJhZFBhZGRpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgQXNzZXJ0LmZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhwbGFpbkRhdGEuZ2V0Qnl0ZXMoKSwgZGVjcnlwdGVkKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvclRlc3QuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2JkNTJmMAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9BbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JUZXN0LmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGFsZ29yaXRobU5hbWU7CisgICAgcHJpdmF0ZSBmaW5hbCBUZXN0SGVscGVyPEFsZ29yaXRobVBhcmFtZXRlcnM+IGhlbHBlcjsKKworICAgIHByb3RlY3RlZCBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3JUZXN0KFN0cmluZyBhbGdvcml0aG1OYW1lLCBUZXN0SGVscGVyPEFsZ29yaXRobVBhcmFtZXRlcnM+IGhlbHBlcikgeworICAgICAgICB0aGlzLmFsZ29yaXRobU5hbWUgPSBhbGdvcml0aG1OYW1lOworICAgICAgICB0aGlzLmhlbHBlciA9IGhlbHBlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yKCkgeworICAgICAgICBBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IgZ2VuZXJhdG9yID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGdlbmVyYXRvciA9IEFsZ29yaXRobVBhcmFtZXRlckdlbmVyYXRvci5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgZ2VuZXJhdG9yLmluaXQoMTAyNCk7CisKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVycyBwYXJhbWV0ZXJzID0gZ2VuZXJhdG9yLmdlbmVyYXRlUGFyYW1ldGVycygpOworCisgICAgICAgIGFzc2VydE5vdE51bGwoImdlbmVyYXRlZCBwYXJhbWV0ZXJzIGFyZSBudWxsIiwgcGFyYW1ldGVycyk7CisKKyAgICAgICAgaGVscGVyLnRlc3QocGFyYW1ldGVycyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlcktleUFncmVlbWVudEhlbHBlci5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlcktleUFncmVlbWVudEhlbHBlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg3MGFiZjkKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvQWxnb3JpdGhtUGFyYW1ldGVyS2V5QWdyZWVtZW50SGVscGVyLmphdmEKQEAgLTAsMCArMSw3MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWxnb3JpdGhtUGFyYW1ldGVyczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uS2V5QWdyZWVtZW50OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5Bc3NlcnQ7CisKK3B1YmxpYyBjbGFzcyBBbGdvcml0aG1QYXJhbWV0ZXJLZXlBZ3JlZW1lbnRIZWxwZXIgZXh0ZW5kcyBUZXN0SGVscGVyPEFsZ29yaXRobVBhcmFtZXRlcnM+IHsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGFsZ29yaXRobU5hbWU7CisKKyAgICBwdWJsaWMgQWxnb3JpdGhtUGFyYW1ldGVyS2V5QWdyZWVtZW50SGVscGVyKFN0cmluZyBhbGdvcml0aG1OYW1lKSB7CisgICAgICAgIHRoaXMuYWxnb3JpdGhtTmFtZSA9IGFsZ29yaXRobU5hbWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgdGVzdChBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtZXRlcnMpIHsKKworICAgICAgICBLZXlQYWlyR2VuZXJhdG9yIGdlbmVyYXRvciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBnZW5lcmF0b3IgPSBLZXlQYWlyR2VuZXJhdG9yLmdldEluc3RhbmNlKGFsZ29yaXRobU5hbWUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgQXNzZXJ0LmZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgZ2VuZXJhdG9yLmluaXRpYWxpemUoMTAyNCk7CisKKyAgICAgICAgS2V5UGFpciBrZXlQYWlyID0gZ2VuZXJhdG9yLmdlbmVyYXRlS2V5UGFpcigpOworCisgICAgICAgIEtleUFncmVlbWVudCBrZXlBZ3JlZW1lbnQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5QWdyZWVtZW50ID0gS2V5QWdyZWVtZW50LmdldEluc3RhbmNlKGFsZ29yaXRobU5hbWUpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgQXNzZXJ0LmZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleUFncmVlbWVudC5pbml0KGtleVBhaXIuZ2V0UHJpdmF0ZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleUFncmVlbWVudC5kb1BoYXNlKGtleVBhaXIuZ2V0UHVibGljKCksIHRydWUpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiZ2VuZXJhdGVkIHNlY3JldCBpcyBudWxsIiwga2V5QWdyZWVtZW50CisgICAgICAgICAgICAgICAgLmdlbmVyYXRlU2VjcmV0KCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9BbGdvcml0aG1QYXJhbWV0ZXJTaWduYXR1cmVIZWxwZXIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9BbGdvcml0aG1QYXJhbWV0ZXJTaWduYXR1cmVIZWxwZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMTMyNTc4Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlclNpZ25hdHVyZUhlbHBlci5qYXZhCkBAIC0wLDAgKzEsMTE0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuS2V5UGFpckdlbmVyYXRvcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuQWxnb3JpdGhtUGFyYW1ldGVyU3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydDsKKworcHVibGljIGNsYXNzIEFsZ29yaXRobVBhcmFtZXRlclNpZ25hdHVyZUhlbHBlcjxUIGV4dGVuZHMgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYz4KKyAgICAgICAgZXh0ZW5kcyBUZXN0SGVscGVyPEFsZ29yaXRobVBhcmFtZXRlcnM+IHsKKworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGFsZ29yaXRobU5hbWU7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcGxhaW5EYXRhID0gInNvbWUgZGF0YSBkbyBzaWduIGFuZCB2ZXJpZnkiOworICAgIHByaXZhdGUgZmluYWwgQ2xhc3M8VD4gcGFyYW1ldGVyU3BlY0NsYXNzOworCisgICAgcHVibGljIEFsZ29yaXRobVBhcmFtZXRlclNpZ25hdHVyZUhlbHBlcihTdHJpbmcgYWxnb3JpdGhtTmFtZSwgQ2xhc3M8VD4gcGFyYW1ldGVyU3BlY0NsYTFzcykgeworICAgICAgICB0aGlzLmFsZ29yaXRobU5hbWUgPSBhbGdvcml0aG1OYW1lOworICAgICAgICB0aGlzLnBhcmFtZXRlclNwZWNDbGFzcyA9IHBhcmFtZXRlclNwZWNDbGExc3M7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgdGVzdChBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtZXRlcnMpIHsKKworICAgICAgICBTaWduYXR1cmUgc2lnbmF0dXJlID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZ25hdHVyZSA9IFNpZ25hdHVyZS5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisKKyAgICAgICAgVCBwYXJhbWV0ZXJTcGVjID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcmFtZXRlclNwZWMgPSBwYXJhbWV0ZXJzLmdldFBhcmFtZXRlclNwZWMocGFyYW1ldGVyU3BlY0NsYXNzKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgQXNzZXJ0LmZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgS2V5UGFpckdlbmVyYXRvciBnZW5lcmF0b3IgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZ2VuZXJhdG9yID0gS2V5UGFpckdlbmVyYXRvci5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBnZW5lcmF0b3IuaW5pdGlhbGl6ZShwYXJhbWV0ZXJTcGVjKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBLZXlQYWlyIGtleVBhaXIgPSBnZW5lcmF0b3IuZ2VuS2V5UGFpcigpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaWduYXR1cmUuaW5pdFNpZ24oa2V5UGFpci5nZXRQcml2YXRlKCkpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaWduYXR1cmUudXBkYXRlKHBsYWluRGF0YS5nZXRCeXRlcygpKTsKKyAgICAgICAgfSBjYXRjaCAoU2lnbmF0dXJlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGVbXSBzaWduZWQgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2lnbmVkID0gc2lnbmF0dXJlLnNpZ24oKTsKKyAgICAgICAgfSBjYXRjaCAoU2lnbmF0dXJlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaWduYXR1cmUuaW5pdFZlcmlmeShrZXlQYWlyLmdldFB1YmxpYygpKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2lnbmF0dXJlLnVwZGF0ZShwbGFpbkRhdGEuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIH0gY2F0Y2ggKFNpZ25hdHVyZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoInNpZ25hdHVyZSBjb3VsZCBub3QgYmUgdmVyaWZpZWQiLCBzaWduYXR1cmUKKyAgICAgICAgICAgICAgICAgICAgLnZlcmlmeShzaWduZWQpKTsKKyAgICAgICAgfSBjYXRjaCAoU2lnbmF0dXJlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9BbGdvcml0aG1QYXJhbWV0ZXJTeW1tZXRyaWNIZWxwZXIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9BbGdvcml0aG1QYXJhbWV0ZXJTeW1tZXRyaWNIZWxwZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NmQ4N2NlCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlclN5bW1ldHJpY0hlbHBlci5qYXZhCkBAIC0wLDAgKzEsMTE0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5BbGdvcml0aG1QYXJhbWV0ZXJzOworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZheC5jcnlwdG8uQmFkUGFkZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uQ2lwaGVyOworaW1wb3J0IGphdmF4LmNyeXB0by5JbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmNyeXB0by5LZXlHZW5lcmF0b3I7CitpbXBvcnQgamF2YXguY3J5cHRvLk5vU3VjaFBhZGRpbmdFeGNlcHRpb247CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydDsKKworcHVibGljIGNsYXNzIEFsZ29yaXRobVBhcmFtZXRlclN5bW1ldHJpY0hlbHBlciBleHRlbmRzIFRlc3RIZWxwZXI8QWxnb3JpdGhtUGFyYW1ldGVycz4geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHBsYWluRGF0YSA9ICJzb21lIGRhdGEgdG8gZW5jcnlwdCBhbmQgZGVjcnlwdCI7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgYWxnb3JpdGhtTmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIGludCBrZXlTaXplOworICAgIHByaXZhdGUgU3RyaW5nIGJsb2NrbW9kZTsKKworICAgIHB1YmxpYyBBbGdvcml0aG1QYXJhbWV0ZXJTeW1tZXRyaWNIZWxwZXIoU3RyaW5nIGFsZ29yaXRobU5hbWUsIGludCBrZXlTaXplKSB7CisgICAgICAgIHRoaXMuYWxnb3JpdGhtTmFtZSA9IGFsZ29yaXRobU5hbWU7CisgICAgICAgIHRoaXMua2V5U2l6ZSA9IGtleVNpemU7CisgICAgfQorCisgICAgcHVibGljIEFsZ29yaXRobVBhcmFtZXRlclN5bW1ldHJpY0hlbHBlcihTdHJpbmcgYWxnb3JpdGhtTmFtZSwgU3RyaW5nIGJsb2NrbW9kZSwgaW50IGtleVNpemUpIHsKKyAgICAgICAgdGhpcyhhbGdvcml0aG1OYW1lLCBrZXlTaXplKTsKKyAgICAgICAgdGhpcy5ibG9ja21vZGUgPSBibG9ja21vZGU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgdGVzdChBbGdvcml0aG1QYXJhbWV0ZXJzIHBhcmFtZXRlcnMpIHsKKworICAgICAgICBLZXlHZW5lcmF0b3IgZ2VuZXJhdG9yID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGdlbmVyYXRvciA9IEtleUdlbmVyYXRvci5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGdlbmVyYXRvci5pbml0KGtleVNpemUpOworCisgICAgICAgIEtleSBrZXkgPSBnZW5lcmF0b3IuZ2VuZXJhdGVLZXkoKTsKKworCisgICAgICAgIENpcGhlciBjaXBoZXIgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIHRyYW5zZm9ybWF0aW9uID0gYWxnb3JpdGhtTmFtZTsKKyAgICAgICAgICAgIGlmIChibG9ja21vZGUgIT0gbnVsbCkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICB0cmFuc2Zvcm1hdGlvbiArPSAiLyIgKyBibG9ja21vZGU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjaXBoZXIgPSBDaXBoZXIuZ2V0SW5zdGFuY2UodHJhbnNmb3JtYXRpb24pOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgQXNzZXJ0LmZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hQYWRkaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaXBoZXIuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBrZXksIHBhcmFtZXRlcnMpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBieXRlW10gYnMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYnMgPSBjaXBoZXIuZG9GaW5hbChwbGFpbkRhdGEuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxCbG9ja1NpemVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgQXNzZXJ0LmZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChCYWRQYWRkaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaXBoZXIuaW5pdChDaXBoZXIuREVDUllQVF9NT0RFLCBrZXksIHBhcmFtZXRlcnMpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEFsZ29yaXRobVBhcmFtZXRlckV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBieXRlW10gZGVjcnlwdGVkID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRlY3J5cHRlZCA9IGNpcGhlci5kb0ZpbmFsKGJzKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gY2F0Y2ggKEJhZFBhZGRpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgQXNzZXJ0LmZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgQXNzZXJ0LmFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhwbGFpbkRhdGEuZ2V0Qnl0ZXMoKSwgZGVjcnlwdGVkKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlcnNUZXN0LmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvQWxnb3JpdGhtUGFyYW1ldGVyc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOTNmMjE2Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0FsZ29yaXRobVBhcmFtZXRlcnNUZXN0LmphdmEKQEAgLTAsMCArMSw1NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFsZ29yaXRobVBhcmFtZXRlcnM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkFsZ29yaXRobVBhcmFtZXRlclNwZWM7CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLkludmFsaWRQYXJhbWV0ZXJTcGVjRXhjZXB0aW9uOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGFic3RyYWN0IGNsYXNzIEFsZ29yaXRobVBhcmFtZXRlcnNUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgYWxnb3JpdGhtTmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIFRlc3RIZWxwZXI8QWxnb3JpdGhtUGFyYW1ldGVycz4gaGVscGVyOworICAgIHByaXZhdGUgZmluYWwgQWxnb3JpdGhtUGFyYW1ldGVyU3BlYyBwYXJhbWV0ZXJEYXRhOworCisgICAgcHVibGljIEFsZ29yaXRobVBhcmFtZXRlcnNUZXN0KFN0cmluZyBhbGdvcml0aG1OYW1lLAorICAgICAgICAgICAgVGVzdEhlbHBlcjxBbGdvcml0aG1QYXJhbWV0ZXJzPiBoZWxwZXIsIEFsZ29yaXRobVBhcmFtZXRlclNwZWMgcGFyYW1ldGVyRGF0YSkgeworICAgICAgICB0aGlzLmFsZ29yaXRobU5hbWUgPSBhbGdvcml0aG1OYW1lOworICAgICAgICB0aGlzLmhlbHBlciA9IGhlbHBlcjsKKyAgICAgICAgdGhpcy5wYXJhbWV0ZXJEYXRhID0gcGFyYW1ldGVyRGF0YTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWxnb3JpdGhtUGFyYW1ldGVycygpIHsKKyAgICAgICAgQWxnb3JpdGhtUGFyYW1ldGVycyBhbGdvcml0aG1QYXJhbWV0ZXJzID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFsZ29yaXRobVBhcmFtZXRlcnMgPSBBbGdvcml0aG1QYXJhbWV0ZXJzCisgICAgICAgICAgICAgICAgICAgIC5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFsZ29yaXRobVBhcmFtZXRlcnMuaW5pdChwYXJhbWV0ZXJEYXRhKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhcmFtZXRlclNwZWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBoZWxwZXIudGVzdChhbGdvcml0aG1QYXJhbWV0ZXJzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvQ2lwaGVyQXN5bW1ldHJpY0NyeXB0SGVscGVyLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvQ2lwaGVyQXN5bW1ldHJpY0NyeXB0SGVscGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmU3YzcxNAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9DaXBoZXJBc3ltbWV0cmljQ3J5cHRIZWxwZXIuamF2YQpAQCAtMCwwICsxLDM0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnNlY3VyaXR5OworCitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXI7CisKK3B1YmxpYyBjbGFzcyBDaXBoZXJBc3ltbWV0cmljQ3J5cHRIZWxwZXIgZXh0ZW5kcyBDaXBoZXJIZWxwZXI8S2V5UGFpcj4geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHBsYWluRGF0YSA9ICJzb21lIGRhdGEgdG8gZW5jcnlwdCBhbmQgZGVjcnlwdCB0ZXN0IjsKKworICAgIHB1YmxpYyBDaXBoZXJBc3ltbWV0cmljQ3J5cHRIZWxwZXIoU3RyaW5nIGFsZ29yaXRobU5hbWUpIHsKKyAgICAgICAgc3VwZXIoYWxnb3JpdGhtTmFtZSwgcGxhaW5EYXRhLCBDaXBoZXIuRU5DUllQVF9NT0RFLAorICAgICAgICAgICAgICAgIENpcGhlci5ERUNSWVBUX01PREUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3QoS2V5UGFpciBrZXlQYWlyKSB7CisgICAgICAgIHRlc3Qoa2V5UGFpci5nZXRQcml2YXRlKCksIGtleVBhaXIuZ2V0UHVibGljKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9DaXBoZXJIZWxwZXIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9DaXBoZXJIZWxwZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYjFiYTg4Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0NpcGhlckhlbHBlci5qYXZhCkBAIC0wLDAgKzEsODMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YXguY3J5cHRvLkJhZFBhZGRpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXguY3J5cHRvLkNpcGhlcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uSWxsZWdhbEJsb2NrU2l6ZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0OworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ2lwaGVySGVscGVyPFQ+IGV4dGVuZHMgVGVzdEhlbHBlcjxUPiB7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBhbGdvcml0aG1OYW1lOworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHBsYWluRGF0YTsKKyAgICBwcml2YXRlIGZpbmFsIGludCBtb2RlMTsKKyAgICBwcml2YXRlIGZpbmFsIGludCBtb2RlMjsKKworICAgIHB1YmxpYyBDaXBoZXJIZWxwZXIoU3RyaW5nIGFsZ29yaXRobU5hbWUsIFN0cmluZyBwbGFpbkRhdGEsIGludCBtb2RlMSwgaW50IG1vZGUyKSB7CisgICAgICAgIHRoaXMuYWxnb3JpdGhtTmFtZSA9IGFsZ29yaXRobU5hbWU7CisgICAgICAgIHRoaXMucGxhaW5EYXRhID0gcGxhaW5EYXRhOworICAgICAgICB0aGlzLm1vZGUxID0gbW9kZTE7CisgICAgICAgIHRoaXMubW9kZTIgPSBtb2RlMjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0KEtleSBlbmNyeXB0S2V5LCBLZXkgZGVjcnlwdEtleSkgeworICAgICAgICBDaXBoZXIgY2lwaGVyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNpcGhlciA9IENpcGhlci5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNpcGhlci5pbml0KG1vZGUxLCBlbmNyeXB0S2V5KTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBieXRlW10gZW5jcnlwdGVkID0gY3J5cHQoY2lwaGVyLCBwbGFpbkRhdGEuZ2V0Qnl0ZXMoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNpcGhlci5pbml0KG1vZGUyLCBkZWNyeXB0S2V5KTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBieXRlW10gZGVjcnlwdGVkID0gY3J5cHQoY2lwaGVyLCBlbmNyeXB0ZWQpOworCisgICAgICAgIFN0cmluZyBkZWNyeXB0ZWRTdHJpbmcgPSBuZXcgU3RyaW5nKGRlY3J5cHRlZCk7CisKKyAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygidHJhbnNmb3JtZWQgZGF0YSBkb2VzIG5vdCBtYXRjaCIsIHBsYWluRGF0YSwKKyAgICAgICAgICAgICAgICBkZWNyeXB0ZWRTdHJpbmcpOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gY3J5cHQoQ2lwaGVyIGNpcGhlciwgYnl0ZVtdIGlucHV0KSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gY2lwaGVyLmRvRmluYWwoaW5wdXQpOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQmxvY2tTaXplRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoQmFkUGFkZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0NpcGhlclN5bW1ldHJpY0NyeXB0SGVscGVyLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvQ2lwaGVyU3ltbWV0cmljQ3J5cHRIZWxwZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YjkzMjExCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0NpcGhlclN5bW1ldHJpY0NyeXB0SGVscGVyLmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eTsKKworaW1wb3J0IGphdmF4LmNyeXB0by5DaXBoZXI7CitpbXBvcnQgamF2YXguY3J5cHRvLlNlY3JldEtleTsKKworcHVibGljIGNsYXNzIENpcGhlclN5bW1ldHJpY0NyeXB0SGVscGVyIGV4dGVuZHMgQ2lwaGVySGVscGVyPFNlY3JldEtleS8qLCBVKi8+IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBwbGFpbkRhdGEgPSAic29tZSBkYXRhIHRvIGVuY3J5cHQgYW5kIGRlY3J5cHQgdGVzdCI7CisKKyAgICBwdWJsaWMgQ2lwaGVyU3ltbWV0cmljQ3J5cHRIZWxwZXIoU3RyaW5nIGFsZ29yaXRobU5hbWUpIHsKKyAgICAgICAgc3VwZXIoYWxnb3JpdGhtTmFtZSwgcGxhaW5EYXRhLCBDaXBoZXIuRU5DUllQVF9NT0RFLAorICAgICAgICAgICAgICAgIENpcGhlci5ERUNSWVBUX01PREUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3QoU2VjcmV0S2V5IGtleSkgeworICAgICAgICB0ZXN0KGtleSwga2V5KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvRGVmYXVsdEtleXMuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9EZWZhdWx0S2V5cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU4M2VmYzYKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvRGVmYXVsdEtleXMuamF2YQpAQCAtMCwwICsxLDIwNiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuc3BlYy5JbnZhbGlkS2V5U3BlY0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuS2V5U3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuUEtDUzhFbmNvZGVkS2V5U3BlYzsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuWDUwOUVuY29kZWRLZXlTcGVjOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworCitwdWJsaWMgY2xhc3MgRGVmYXVsdEtleXMgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBSU0FfcHJpdmF0ZSA9IG5ldyBieXRlW10geworICAgICAgICAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDAyLCAoYnl0ZSkgMHg3NSwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDBELCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MDksIChieXRlKSAweDJBLCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4NDgsIChieXRlKSAweDg2LCAoYnl0ZSkgMHhGNywgKGJ5dGUpIDB4MEQsCisgICAgICAgIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDA1LCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDQsIChieXRlKSAweDgyLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4NUYsIChieXRlKSAweDMwLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDVCLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMiwKKyAgICAgICAgKGJ5dGUpIDB4ODEsIChieXRlKSAweDgxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4OTksIChieXRlKSAweEE1LCAoYnl0ZSkgMHg5NiwgKGJ5dGUpIDB4NzIsIChieXRlKSAweEFFLCAoYnl0ZSkgMHhCQiwgKGJ5dGUpIDB4NTksIChieXRlKSAweDM2LCAoYnl0ZSkgMHhBOCwgKGJ5dGUpIDB4MTIsIChieXRlKSAweDE3LCAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4NEMsIChieXRlKSAweDYzLAorICAgICAgICAoYnl0ZSkgMHg5RSwgKGJ5dGUpIDB4QjgsIChieXRlKSAweDg1LCAoYnl0ZSkgMHhENCwgKGJ5dGUpIDB4MkQsIChieXRlKSAweDcxLCAoYnl0ZSkgMHhENywgKGJ5dGUpIDB4MjksIChieXRlKSAweEI5LCAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4MEYsIChieXRlKSAweEI0LCAoYnl0ZSkgMHg1NywgKGJ5dGUpIDB4RkIsIChieXRlKSAweEQzLCAoYnl0ZSkgMHg5NSwgKGJ5dGUpIDB4NUMsCisgICAgICAgIChieXRlKSAweDIxLCAoYnl0ZSkgMHhFQywgKGJ5dGUpIDB4QjUsIChieXRlKSAweEVCLCAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4QTIsIChieXRlKSAweDRGLCAoYnl0ZSkgMHhDMSwgKGJ5dGUpIDB4OTMsIChieXRlKSAweEVGLCAoYnl0ZSkgMHg5NiwgKGJ5dGUpIDB4NDEsIChieXRlKSAweDA1LCAoYnl0ZSkgMHgzRCwgKGJ5dGUpIDB4QzUsIChieXRlKSAweDNFLCAoYnl0ZSkgMHgwNCwKKyAgICAgICAgKGJ5dGUpIDB4NEQsIChieXRlKSAweEM2LCAoYnl0ZSkgMHhDRiwgKGJ5dGUpIDB4MzIsIChieXRlKSAweDdDLCAoYnl0ZSkgMHgxRiwgKGJ5dGUpIDB4NjYsIChieXRlKSAweEEzLCAoYnl0ZSkgMHhDNSwgKGJ5dGUpIDB4MjcsIChieXRlKSAweDc5LCAoYnl0ZSkgMHhFQywgKGJ5dGUpIDB4MkUsIChieXRlKSAweDY3LCAoYnl0ZSkgMHhGQSwgKGJ5dGUpIDB4MTksIChieXRlKSAweDVCLAorICAgICAgICAoYnl0ZSkgMHhFMywgKGJ5dGUpIDB4QjEsIChieXRlKSAweDY5LCAoYnl0ZSkgMHhEQSwgKGJ5dGUpIDB4NjMsIChieXRlKSAweEJDLCAoYnl0ZSkgMHhEQSwgKGJ5dGUpIDB4RDMsIChieXRlKSAweEJCLCAoYnl0ZSkgMHhBRCwgKGJ5dGUpIDB4OEMsIChieXRlKSAweDM4LCAoYnl0ZSkgMHg3QiwgKGJ5dGUpIDB4NEEsIChieXRlKSAweDlDLCAoYnl0ZSkgMHhENCwgKGJ5dGUpIDB4NEQsCisgICAgICAgIChieXRlKSAweEQyLCAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4QjcsIChieXRlKSAweDRFLCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4QjYsIChieXRlKSAweERGLCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg1QywgKGJ5dGUpIDB4OTQsIChieXRlKSAweDAyLCAoYnl0ZSkgMHhGNywgKGJ5dGUpIDB4ODQsIChieXRlKSAweEU2LCAoYnl0ZSkgMHg5QiwKKyAgICAgICAgKGJ5dGUpIDB4NTcsIChieXRlKSAweEZGLCAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4MkEsIChieXRlKSAweEExLCAoYnl0ZSkgMHg3NCwgKGJ5dGUpIDB4OEQsIChieXRlKSAweDA3LCAoYnl0ZSkgMHhEOCwgKGJ5dGUpIDB4Q0UsIChieXRlKSAweEY3LCAoYnl0ZSkgMHgwQiwgKGJ5dGUpIDB4NTksIChieXRlKSAweEZCLCAoYnl0ZSkgMHgxMywgKGJ5dGUpIDB4NkUsIChieXRlKSAweEYxLAorICAgICAgICAoYnl0ZSkgMHhDMywgKGJ5dGUpIDB4QUIsIChieXRlKSAweDNFLCAoYnl0ZSkgMHg3MiwgKGJ5dGUpIDB4MUIsIChieXRlKSAweDYyLCAoYnl0ZSkgMHgwOSwgKGJ5dGUpIDB4RTgsIChieXRlKSAweEQ4LCAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4NjksIChieXRlKSAweEUxLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDMsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MDEsCisgICAgICAgIChieXRlKSAweDAyLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODAsIChieXRlKSAweDU3LCAoYnl0ZSkgMHhENiwgKGJ5dGUpIDB4MUMsIChieXRlKSAweDJFLCAoYnl0ZSkgMHgyRiwgKGJ5dGUpIDB4Q0EsIChieXRlKSAweDE2LCAoYnl0ZSkgMHhGNCwgKGJ5dGUpIDB4NzIsIChieXRlKSAweDFDLCAoYnl0ZSkgMHhGNSwgKGJ5dGUpIDB4NjAsIChieXRlKSAweDI4LCAoYnl0ZSkgMHgwRCwKKyAgICAgICAgKGJ5dGUpIDB4ODMsIChieXRlKSAweDdELCAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4QjQsIChieXRlKSAweDg4LCAoYnl0ZSkgMHhDRSwgKGJ5dGUpIDB4NUQsIChieXRlKSAweEVELCAoYnl0ZSkgMHgxMiwgKGJ5dGUpIDB4NDIsIChieXRlKSAweERDLCAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4ODMsIChieXRlKSAweDFCLCAoYnl0ZSkgMHgwQSwgKGJ5dGUpIDB4MTgsIChieXRlKSAweDg2LAorICAgICAgICAoYnl0ZSkgMHhGNSwgKGJ5dGUpIDB4MzUsIChieXRlKSAweEY3LCAoYnl0ZSkgMHhDMiwgKGJ5dGUpIDB4M0UsIChieXRlKSAweDFBLCAoYnl0ZSkgMHhDMiwgKGJ5dGUpIDB4NzEsIChieXRlKSAweEFELCAoYnl0ZSkgMHhGQSwgKGJ5dGUpIDB4RjcsIChieXRlKSAweEYwLCAoYnl0ZSkgMHhFRiwgKGJ5dGUpIDB4RTgsIChieXRlKSAweDIyLCAoYnl0ZSkgMHg0QywgKGJ5dGUpIDB4OTMsCisgICAgICAgIChieXRlKSAweEY1LCAoYnl0ZSkgMHg0QSwgKGJ5dGUpIDB4QzQsIChieXRlKSAweEM0LCAoYnl0ZSkgMHhERCwgKGJ5dGUpIDB4QzQsIChieXRlKSAweEFELCAoYnl0ZSkgMHhDRSwgKGJ5dGUpIDB4Q0UsIChieXRlKSAweDM1LCAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4MzQsIChieXRlKSAweDhBLCAoYnl0ZSkgMHg0QiwgKGJ5dGUpIDB4MTIsIChieXRlKSAweEU0LCAoYnl0ZSkgMHg2OSwKKyAgICAgICAgKGJ5dGUpIDB4RTYsIChieXRlKSAweERBLCAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4MUEsIChieXRlKSAweDc3LCAoYnl0ZSkgMHg1QywgKGJ5dGUpIDB4QTcsIChieXRlKSAweDIxLCAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4ODksIChieXRlKSAweDhDLCAoYnl0ZSkgMHg5NSwgKGJ5dGUpIDB4NkEsIChieXRlKSAweDVELCAoYnl0ZSkgMHg5QywgKGJ5dGUpIDB4M0MsIChieXRlKSAweEFFLAorICAgICAgICAoYnl0ZSkgMHhDMywgKGJ5dGUpIDB4RTQsIChieXRlKSAweDY0LCAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4REEsIChieXRlKSAweEZCLCAoYnl0ZSkgMHhCQSwgKGJ5dGUpIDB4QTYsIChieXRlKSAweEU1LCAoYnl0ZSkgMHg4QSwgKGJ5dGUpIDB4N0YsIChieXRlKSAweEZBLCAoYnl0ZSkgMHgxQSwgKGJ5dGUpIDB4M0YsIChieXRlKSAweDlCLCAoYnl0ZSkgMHhBQiwgKGJ5dGUpIDB4REEsCisgICAgICAgIChieXRlKSAweDNELCAoYnl0ZSkgMHgzQiwgKGJ5dGUpIDB4NDMsIChieXRlKSAweEYwLCAoYnl0ZSkgMHgwQywgKGJ5dGUpIDB4MDYsIChieXRlKSAweDU3LCAoYnl0ZSkgMHg0MywgKGJ5dGUpIDB4NDUsIChieXRlKSAweEVFLCAoYnl0ZSkgMHg4QywgKGJ5dGUpIDB4MjcsIChieXRlKSAweDA1LCAoYnl0ZSkgMHhBRiwgKGJ5dGUpIDB4Q0QsIChieXRlKSAweDVBLCAoYnl0ZSkgMHg0NywKKyAgICAgICAgKGJ5dGUpIDB4QjksIChieXRlKSAweEVBLCAoYnl0ZSkgMHhEOSwgKGJ5dGUpIDB4QUEsIChieXRlKSAweDY2LCAoYnl0ZSkgMHhEQiwgKGJ5dGUpIDB4RTMsIChieXRlKSAweERDLCAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4NDcsIChieXRlKSAweDYwLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDQxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4RUQsIChieXRlKSAweEU5LAorICAgICAgICAoYnl0ZSkgMHhCRCwgKGJ5dGUpIDB4RDUsIChieXRlKSAweDAyLCAoYnl0ZSkgMHg2RCwgKGJ5dGUpIDB4NDQsIChieXRlKSAweDBFLCAoYnl0ZSkgMHgzRiwgKGJ5dGUpIDB4NzQsIChieXRlKSAweDBDLCAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4NTQsIChieXRlKSAweDg4LCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4NUMsIChieXRlKSAweEZDLCAoYnl0ZSkgMHhGMiwgKGJ5dGUpIDB4MzEsCisgICAgICAgIChieXRlKSAweDdCLCAoYnl0ZSkgMHhBRiwgKGJ5dGUpIDB4MTUsIChieXRlKSAweDc3LCAoYnl0ZSkgMHg3QSwgKGJ5dGUpIDB4REMsIChieXRlKSAweEM2LCAoYnl0ZSkgMHg5RSwgKGJ5dGUpIDB4N0UsIChieXRlKSAweEMxLCAoYnl0ZSkgMHhDQSwgKGJ5dGUpIDB4ODQsIChieXRlKSAweEM3LCAoYnl0ZSkgMHg0QiwgKGJ5dGUpIDB4QzQsIChieXRlKSAweDQxLCAoYnl0ZSkgMHhFMSwKKyAgICAgICAgKGJ5dGUpIDB4ODUsIChieXRlKSAweEU0LCAoYnl0ZSkgMHg1QSwgKGJ5dGUpIDB4QTcsIChieXRlKSAweDNELCAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4ODcsIChieXRlKSAweDBELCAoYnl0ZSkgMHg3QSwgKGJ5dGUpIDB4QzUsIChieXRlKSAweDQ3LCAoYnl0ZSkgMHg1QywgKGJ5dGUpIDB4RjIsIChieXRlKSAweEFELCAoYnl0ZSkgMHgxNCwgKGJ5dGUpIDB4NEQsIChieXRlKSAweDYzLAorICAgICAgICAoYnl0ZSkgMHhCMCwgKGJ5dGUpIDB4REMsIChieXRlKSAweDM0LCAoYnl0ZSkgMHhCNSwgKGJ5dGUpIDB4REEsIChieXRlKSAweDE3LCAoYnl0ZSkgMHgwRCwgKGJ5dGUpIDB4NEUsIChieXRlKSAweDJCLCAoYnl0ZSkgMHg5RSwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDAyLCAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweEE1LCAoYnl0ZSkgMHg1MywgKGJ5dGUpIDB4REIsCisgICAgICAgIChieXRlKSAweEQ4LCAoYnl0ZSkgMHgyOCwgKGJ5dGUpIDB4NTcsIChieXRlKSAweDY1LCAoYnl0ZSkgMHgyQiwgKGJ5dGUpIDB4RkEsIChieXRlKSAweEYyLCAoYnl0ZSkgMHgyMSwgKGJ5dGUpIDB4QjgsIChieXRlKSAweDYwLCAoYnl0ZSkgMHhBRSwgKGJ5dGUpIDB4NDMsIChieXRlKSAweDRCLCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4ODUsIChieXRlKSAweENCLCAoYnl0ZSkgMHhEQSwKKyAgICAgICAgKGJ5dGUpIDB4ODksIChieXRlKSAweDVBLCAoYnl0ZSkgMHg3RCwgKGJ5dGUpIDB4MDUsIChieXRlKSAweERBLCAoYnl0ZSkgMHhGQywgKGJ5dGUpIDB4QUYsIChieXRlKSAweDQ2LCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4QkMsIChieXRlKSAweDNGLCAoYnl0ZSkgMHhEMSwgKGJ5dGUpIDB4RUEsIChieXRlKSAweEE0LCAoYnl0ZSkgMHg1NiwgKGJ5dGUpIDB4QTMsIChieXRlKSAweEU2LAorICAgICAgICAoYnl0ZSkgMHhENCwgKGJ5dGUpIDB4QTIsIChieXRlKSAweDA4LCAoYnl0ZSkgMHg5MywgKGJ5dGUpIDB4NjMsIChieXRlKSAweDIxLCAoYnl0ZSkgMHgwRSwgKGJ5dGUpIDB4QzUsIChieXRlKSAweDNDLCAoYnl0ZSkgMHg5NywgKGJ5dGUpIDB4N0UsIChieXRlKSAweDcxLCAoYnl0ZSkgMHgwQiwgKGJ5dGUpIDB4NzksIChieXRlKSAweEY4LCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4NzMsCisgICAgICAgIChieXRlKSAweEQxLCAoYnl0ZSkgMHhGOSwgKGJ5dGUpIDB4RDQsIChieXRlKSAweDY2LCAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4N0QsIChieXRlKSAweERDLCAoYnl0ZSkgMHgyMiwgKGJ5dGUpIDB4REIsIChieXRlKSAweDYxLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4NDAsIChieXRlKSAweDVELCAoYnl0ZSkgMHgzRCwgKGJ5dGUpIDB4RUYsIChieXRlKSAweDg1LCAoYnl0ZSkgMHg0RCwKKyAgICAgICAgKGJ5dGUpIDB4MjcsIChieXRlKSAweDJGLCAoYnl0ZSkgMHhCNSwgKGJ5dGUpIDB4RjksIChieXRlKSAweENFLCAoYnl0ZSkgMHg2QywgKGJ5dGUpIDB4ODQsIChieXRlKSAweEJCLCAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4RDksIChieXRlKSAweDUyLCAoYnl0ZSkgMHhFRSwgKGJ5dGUpIDB4NUIsIChieXRlKSAweEE5LCAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4MTUsIChieXRlKSAweDEyLAorICAgICAgICAoYnl0ZSkgMHg2RiwgKGJ5dGUpIDB4QkEsIChieXRlKSAweDNBLCAoYnl0ZSkgMHg0RSwgKGJ5dGUpIDB4QTksIChieXRlKSAweDhELCAoYnl0ZSkgMHg3QSwgKGJ5dGUpIDB4M0IsIChieXRlKSAweEY5LCAoYnl0ZSkgMHhERiwgKGJ5dGUpIDB4RjUsIChieXRlKSAweEU0LCAoYnl0ZSkgMHhEQywgKGJ5dGUpIDB4MDEsIChieXRlKSAweDFDLCAoYnl0ZSkgMHgyRCwgKGJ5dGUpIDB4OEMsCisgICAgICAgIChieXRlKSAweDBELCAoYnl0ZSkgMHhFMSwgKGJ5dGUpIDB4NkUsIChieXRlKSAweDgwLCAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4OUIsIChieXRlKSAweDBCLCAoYnl0ZSkgMHgzOCwgKGJ5dGUpIDB4NTUsIChieXRlKSAweEM4LCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4NjcsIChieXRlKSAweDEzLCAoYnl0ZSkgMHg5MSwgKGJ5dGUpIDB4OEYsIChieXRlKSAweDlFLCAoYnl0ZSkgMHgyRSwKKyAgICAgICAgKGJ5dGUpIDB4MTYsIChieXRlKSAweDVCLCAoYnl0ZSkgMHg3QywgKGJ5dGUpIDB4MEYsIChieXRlKSAweDVELCAoYnl0ZSkgMHhFNCwgKGJ5dGUpIDB4QTAsIChieXRlKSAweDgxLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4NDAsIChieXRlKSAweDIwLCAoYnl0ZSkgMHgxMiwgKGJ5dGUpIDB4MTEsIChieXRlKSAweDVFLCAoYnl0ZSkgMHg3MCwgKGJ5dGUpIDB4MEMsIChieXRlKSAweEVDLAorICAgICAgICAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4NDksIChieXRlKSAweDBFLCAoYnl0ZSkgMHhCOSwgKGJ5dGUpIDB4M0QsIChieXRlKSAweEQzLCAoYnl0ZSkgMHhGQiwgKGJ5dGUpIDB4NTksIChieXRlKSAweEYwLCAoYnl0ZSkgMHg3RCwgKGJ5dGUpIDB4NjIsIChieXRlKSAweEVGLCAoYnl0ZSkgMHhGNSwgKGJ5dGUpIDB4NzcsIChieXRlKSAweDk5LCAoYnl0ZSkgMHg4NywgKGJ5dGUpIDB4MTEsCisgICAgICAgIChieXRlKSAweDIwLCAoYnl0ZSkgMHhCNiwgKGJ5dGUpIDB4Q0QsIChieXRlKSAweEE1LCAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4QjMsIChieXRlKSAweDkyLCAoYnl0ZSkgMHhDOSwgKGJ5dGUpIDB4QkMsIChieXRlKSAweEIzLCAoYnl0ZSkgMHg5RSwgKGJ5dGUpIDB4NUUsIChieXRlKSAweEYzLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MjIsIChieXRlKSAweDVGLCAoYnl0ZSkgMHg3OSwKKyAgICAgICAgKGJ5dGUpIDB4N0YsIChieXRlKSAweENDLCAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4REEsIChieXRlKSAweDNCLCAoYnl0ZSkgMHhGMywgKGJ5dGUpIDB4QzMsIChieXRlKSAweDQyLCAoYnl0ZSkgMHg1OCwgKGJ5dGUpIDB4OTAsIChieXRlKSAweDkzLCAoYnl0ZSkgMHg3RSwgKGJ5dGUpIDB4REEsIChieXRlKSAweDU4LCAoYnl0ZSkgMHhDQywgKGJ5dGUpIDB4MTYsIChieXRlKSAweEM4LAorICAgICAgICAoYnl0ZSkgMHhBRSwgKGJ5dGUpIDB4OTksIChieXRlKSAweENDLCAoYnl0ZSkgMHg5RiwgKGJ5dGUpIDB4MzIsIChieXRlKSAweDYxLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4NDAsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4REIsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwRiwgKGJ5dGUpIDB4MEEsIChieXRlKSAweDE3LCAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4N0UsCisgICAgICAgIChieXRlKSAweEM1LCAoYnl0ZSkgMHhFQywgKGJ5dGUpIDB4MjEsIChieXRlKSAweDQ3LCAoYnl0ZSkgMHg2NSwgKGJ5dGUpIDB4REMsIChieXRlKSAweEU1LCAoYnl0ZSkgMHhDMiwgKGJ5dGUpIDB4MEQsIChieXRlKSAweDQyLCAoYnl0ZSkgMHgyOCwgKGJ5dGUpIDB4RTEsIChieXRlKSAweDE3LCAoYnl0ZSkgMHgxQSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweEJELCAoYnl0ZSkgMHhCRSwKKyAgICAgICAgKGJ5dGUpIDB4MUMsIChieXRlKSAweDdELCAoYnl0ZSkgMHhDQSwgKGJ5dGUpIDB4OTMsIChieXRlKSAweDY3LCAoYnl0ZSkgMHg4RiwgKGJ5dGUpIDB4MjgsIChieXRlKSAweEI3LCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4OEUsIChieXRlKSAweEYwLCAoYnl0ZSkgMHg1RCwgKGJ5dGUpIDB4Q0QsIChieXRlKSAweEZBLCAoYnl0ZSkgMHhERCwgKGJ5dGUpIDB4NkIsIChieXRlKSAweDcyLAorICAgICAgICAoYnl0ZSkgMHhGNywgKGJ5dGUpIDB4NDgsIChieXRlKSAweEQ5LCAoYnl0ZSkgMHgzQywgKGJ5dGUpIDB4NDAsIChieXRlKSAweDdDLCAoYnl0ZSkgMHhCMCwgKGJ5dGUpIDB4RDcsIChieXRlKSAweDU4LCAoYnl0ZSkgMHhDMiwgKGJ5dGUpIDB4NTMsIChieXRlKSAweEFELCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4RjYsIChieXRlKSAweDBCLCAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4NTEsCisgICAgICAgIChieXRlKSAweDQ1LCAoYnl0ZSkgMHhCOSwgKGJ5dGUpIDB4NEYsIChieXRlKSAweDQ5ICB9OworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gUlNBX3B1YmxpYyA9IG5ldyBieXRlW10geworICAgICAgICAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDlGLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4MEQsIChieXRlKSAweDA2LCAoYnl0ZSkgMHgwOSwgKGJ5dGUpIDB4MkEsIChieXRlKSAweDg2LCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4ODYsIChieXRlKSAweEY3LCAoYnl0ZSkgMHgwRCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDUsCisgICAgICAgIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4ODEsIChieXRlKSAweDhELCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4OSwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDk5LCAoYnl0ZSkgMHhBNSwgKGJ5dGUpIDB4OTYsIChieXRlKSAweDcyLCAoYnl0ZSkgMHhBRSwKKyAgICAgICAgKGJ5dGUpIDB4QkIsIChieXRlKSAweDU5LCAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4QTgsIChieXRlKSAweDEyLCAoYnl0ZSkgMHgxNywgKGJ5dGUpIDB4MDUsIChieXRlKSAweDRDLCAoYnl0ZSkgMHg2MywgKGJ5dGUpIDB4OUUsIChieXRlKSAweEI4LCAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4RDQsIChieXRlKSAweDJELCAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4RDcsIChieXRlKSAweDI5LAorICAgICAgICAoYnl0ZSkgMHhCOSwgKGJ5dGUpIDB4MDUsIChieXRlKSAweDBGLCAoYnl0ZSkgMHhCNCwgKGJ5dGUpIDB4NTcsIChieXRlKSAweEZCLCAoYnl0ZSkgMHhEMywgKGJ5dGUpIDB4OTUsIChieXRlKSAweDVDLCAoYnl0ZSkgMHgyMSwgKGJ5dGUpIDB4RUMsIChieXRlKSAweEI1LCAoYnl0ZSkgMHhFQiwgKGJ5dGUpIDB4NjcsIChieXRlKSAweEEyLCAoYnl0ZSkgMHg0RiwgKGJ5dGUpIDB4QzEsCisgICAgICAgIChieXRlKSAweDkzLCAoYnl0ZSkgMHhFRiwgKGJ5dGUpIDB4OTYsIChieXRlKSAweDQxLCAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4M0QsIChieXRlKSAweEM1LCAoYnl0ZSkgMHgzRSwgKGJ5dGUpIDB4MDQsIChieXRlKSAweDRELCAoYnl0ZSkgMHhDNiwgKGJ5dGUpIDB4Q0YsIChieXRlKSAweDMyLCAoYnl0ZSkgMHg3QywgKGJ5dGUpIDB4MUYsIChieXRlKSAweDY2LCAoYnl0ZSkgMHhBMywKKyAgICAgICAgKGJ5dGUpIDB4QzUsIChieXRlKSAweDI3LCAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4RUMsIChieXRlKSAweDJFLCAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4RkEsIChieXRlKSAweDE5LCAoYnl0ZSkgMHg1QiwgKGJ5dGUpIDB4RTMsIChieXRlKSAweEIxLCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4REEsIChieXRlKSAweDYzLCAoYnl0ZSkgMHhCQywgKGJ5dGUpIDB4REEsIChieXRlKSAweEQzLAorICAgICAgICAoYnl0ZSkgMHhCQiwgKGJ5dGUpIDB4QUQsIChieXRlKSAweDhDLCAoYnl0ZSkgMHgzOCwgKGJ5dGUpIDB4N0IsIChieXRlKSAweDRBLCAoYnl0ZSkgMHg5QywgKGJ5dGUpIDB4RDQsIChieXRlKSAweDRELCAoYnl0ZSkgMHhEMiwgKGJ5dGUpIDB4MzMsIChieXRlKSAweEI3LCAoYnl0ZSkgMHg0RSwgKGJ5dGUpIDB4MDQsIChieXRlKSAweEI2LCAoYnl0ZSkgMHhERiwgKGJ5dGUpIDB4NjIsCisgICAgICAgIChieXRlKSAweDU1LCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4NUMsIChieXRlKSAweDk0LCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4RjcsIChieXRlKSAweDg0LCAoYnl0ZSkgMHhFNiwgKGJ5dGUpIDB4OUIsIChieXRlKSAweDU3LCAoYnl0ZSkgMHhGRiwgKGJ5dGUpIDB4MTcsIChieXRlKSAweDJBLCAoYnl0ZSkgMHhBMSwgKGJ5dGUpIDB4NzQsIChieXRlKSAweDhELCAoYnl0ZSkgMHgwNywKKyAgICAgICAgKGJ5dGUpIDB4RDgsIChieXRlKSAweENFLCAoYnl0ZSkgMHhGNywgKGJ5dGUpIDB4MEIsIChieXRlKSAweDU5LCAoYnl0ZSkgMHhGQiwgKGJ5dGUpIDB4MTMsIChieXRlKSAweDZFLCAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4QzMsIChieXRlKSAweEFCLCAoYnl0ZSkgMHgzRSwgKGJ5dGUpIDB4NzIsIChieXRlKSAweDFCLCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4MDksIChieXRlKSAweEU4LAorICAgICAgICAoYnl0ZSkgMHhEOCwgKGJ5dGUpIDB4NDEsIChieXRlKSAweDY5LCAoYnl0ZSkgMHhFMSwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDAzLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAxICAgICB9OworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gRFNBX3ByaXZhdGUgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgKGJ5dGUpIDB4MzAsIChieXRlKSAweDgyLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4NEIsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDMwLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDJDLCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MDcsIChieXRlKSAweDJBLCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4NDgsIChieXRlKSAweENFLAorICAgICAgICAoYnl0ZSkgMHgzOCwgKGJ5dGUpIDB4MDQsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgxRiwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweEZELCAoYnl0ZSkgMHg3RiwgKGJ5dGUpIDB4NTMsIChieXRlKSAweDgxLCAoYnl0ZSkgMHgxRCwgKGJ5dGUpIDB4NzUsCisgICAgICAgIChieXRlKSAweDEyLCAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4NTIsIChieXRlKSAweERGLCAoYnl0ZSkgMHg0QSwgKGJ5dGUpIDB4OUMsIChieXRlKSAweDJFLCAoYnl0ZSkgMHhFQywgKGJ5dGUpIDB4RTQsIChieXRlKSAweEU3LCAoYnl0ZSkgMHhGNiwgKGJ5dGUpIDB4MTEsIChieXRlKSAweEI3LCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4M0MsIChieXRlKSAweEVGLCAoYnl0ZSkgMHg0NCwKKyAgICAgICAgKGJ5dGUpIDB4MDAsIChieXRlKSAweEMzLCAoYnl0ZSkgMHgxRSwgKGJ5dGUpIDB4M0YsIChieXRlKSAweDgwLCAoYnl0ZSkgMHhCNiwgKGJ5dGUpIDB4NTEsIChieXRlKSAweDI2LCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4NDUsIChieXRlKSAweDVELCAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4MjIsIChieXRlKSAweDUxLCAoYnl0ZSkgMHhGQiwgKGJ5dGUpIDB4NTksIChieXRlKSAweDNELAorICAgICAgICAoYnl0ZSkgMHg4RCwgKGJ5dGUpIDB4NTgsIChieXRlKSAweEZBLCAoYnl0ZSkgMHhCRiwgKGJ5dGUpIDB4QzUsIChieXRlKSAweEY1LCAoYnl0ZSkgMHhCQSwgKGJ5dGUpIDB4MzAsIChieXRlKSAweEY2LCAoYnl0ZSkgMHhDQiwgKGJ5dGUpIDB4OUIsIChieXRlKSAweDU1LCAoYnl0ZSkgMHg2QywgKGJ5dGUpIDB4RDcsIChieXRlKSAweDgxLCAoYnl0ZSkgMHgzQiwgKGJ5dGUpIDB4ODAsCisgICAgICAgIChieXRlKSAweDFELCAoYnl0ZSkgMHgzNCwgKGJ5dGUpIDB4NkYsIChieXRlKSAweEYyLCAoYnl0ZSkgMHg2NiwgKGJ5dGUpIDB4NjAsIChieXRlKSAweEI3LCAoYnl0ZSkgMHg2QiwgKGJ5dGUpIDB4OTksIChieXRlKSAweDUwLCAoYnl0ZSkgMHhBNSwgKGJ5dGUpIDB4QTQsIChieXRlKSAweDlGLCAoYnl0ZSkgMHg5RiwgKGJ5dGUpIDB4RTgsIChieXRlKSAweDA0LCAoYnl0ZSkgMHg3QiwKKyAgICAgICAgKGJ5dGUpIDB4MTAsIChieXRlKSAweDIyLCAoYnl0ZSkgMHhDMiwgKGJ5dGUpIDB4NEYsIChieXRlKSAweEJCLCAoYnl0ZSkgMHhBOSwgKGJ5dGUpIDB4RDcsIChieXRlKSAweEZFLCAoYnl0ZSkgMHhCNywgKGJ5dGUpIDB4QzYsIChieXRlKSAweDFCLCAoYnl0ZSkgMHhGOCwgKGJ5dGUpIDB4M0IsIChieXRlKSAweDU3LCAoYnl0ZSkgMHhFNywgKGJ5dGUpIDB4QzYsIChieXRlKSAweEE4LAorICAgICAgICAoYnl0ZSkgMHhBNiwgKGJ5dGUpIDB4MTUsIChieXRlKSAweDBGLCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4RkIsIChieXRlKSAweDgzLCAoYnl0ZSkgMHhGNiwgKGJ5dGUpIDB4RDMsIChieXRlKSAweEM1LCAoYnl0ZSkgMHgxRSwgKGJ5dGUpIDB4QzMsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4NTQsIChieXRlKSAweDEzLCAoYnl0ZSkgMHg1QSwgKGJ5dGUpIDB4MTYsCisgICAgICAgIChieXRlKSAweDkxLCAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4RjYsIChieXRlKSAweDc1LCAoYnl0ZSkgMHhGMywgKGJ5dGUpIDB4QUUsIChieXRlKSAweDJCLCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4RDcsIChieXRlKSAweDJBLCAoYnl0ZSkgMHhFRiwgKGJ5dGUpIDB4RjIsIChieXRlKSAweDIyLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MTksIChieXRlKSAweDlELCAoYnl0ZSkgMHhEMSwKKyAgICAgICAgKGJ5dGUpIDB4NDgsIChieXRlKSAweDAxLCAoYnl0ZSkgMHhDNywgKGJ5dGUpIDB4MDIsIChieXRlKSAweDE1LCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4OTcsIChieXRlKSAweDYwLCAoYnl0ZSkgMHg1MCwgKGJ5dGUpIDB4OEYsIChieXRlKSAweDE1LCAoYnl0ZSkgMHgyMywgKGJ5dGUpIDB4MEIsIChieXRlKSAweENDLCAoYnl0ZSkgMHhCMiwgKGJ5dGUpIDB4OTIsIChieXRlKSAweEI5LAorICAgICAgICAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4QTIsIChieXRlKSAweEVCLCAoYnl0ZSkgMHg4NCwgKGJ5dGUpIDB4MEIsIChieXRlKSAweEYwLCAoYnl0ZSkgMHg1OCwgKGJ5dGUpIDB4MUMsIChieXRlKSAweEY1LCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDgxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4RjcsIChieXRlKSAweEUxLCAoYnl0ZSkgMHhBMCwgKGJ5dGUpIDB4ODUsCisgICAgICAgIChieXRlKSAweEQ2LCAoYnl0ZSkgMHg5QiwgKGJ5dGUpIDB4M0QsIChieXRlKSAweERFLCAoYnl0ZSkgMHhDQiwgKGJ5dGUpIDB4QkMsIChieXRlKSAweEFCLCAoYnl0ZSkgMHg1QywgKGJ5dGUpIDB4MzYsIChieXRlKSAweEI4LCAoYnl0ZSkgMHg1NywgKGJ5dGUpIDB4QjksIChieXRlKSAweDc5LCAoYnl0ZSkgMHg5NCwgKGJ5dGUpIDB4QUYsIChieXRlKSAweEJCLCAoYnl0ZSkgMHhGQSwKKyAgICAgICAgKGJ5dGUpIDB4M0EsIChieXRlKSAweEVBLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4RjksIChieXRlKSAweDU3LCAoYnl0ZSkgMHg0QywgKGJ5dGUpIDB4MEIsIChieXRlKSAweDNELCAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4ODIsIChieXRlKSAweDY3LCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4NTksIChieXRlKSAweDU3LCAoYnl0ZSkgMHg4RSwgKGJ5dGUpIDB4QkEsIChieXRlKSAweEQ0LAorICAgICAgICAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4NEYsIChieXRlKSAweEU2LCAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4MDcsIChieXRlKSAweDEwLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODAsIChieXRlKSAweEI0LCAoYnl0ZSkgMHg0OSwgKGJ5dGUpIDB4MTYsIChieXRlKSAweDcxLCAoYnl0ZSkgMHgyMywgKGJ5dGUpIDB4RTgsIChieXRlKSAweDRDLCAoYnl0ZSkgMHgyOCwgKGJ5dGUpIDB4MTYsCisgICAgICAgIChieXRlKSAweDEzLCAoYnl0ZSkgMHhCNywgKGJ5dGUpIDB4Q0YsIChieXRlKSAweDA5LCAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4OEMsIChieXRlKSAweEM4LCAoYnl0ZSkgMHhBNiwgKGJ5dGUpIDB4RTEsIChieXRlKSAweDNDLCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4N0EsIChieXRlKSAweDhCLCAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4N0MsIChieXRlKSAweDhELCAoYnl0ZSkgMHgyOCwKKyAgICAgICAgKGJ5dGUpIDB4RTAsIChieXRlKSAweEEzLCAoYnl0ZSkgMHhBRSwgKGJ5dGUpIDB4MUUsIChieXRlKSAweDJCLCAoYnl0ZSkgMHhCMywgKGJ5dGUpIDB4QTYsIChieXRlKSAweDc1LCAoYnl0ZSkgMHg5MSwgKGJ5dGUpIDB4NkUsIChieXRlKSAweEEzLCAoYnl0ZSkgMHg3RiwgKGJ5dGUpIDB4MEIsIChieXRlKSAweEZBLCAoYnl0ZSkgMHgyMSwgKGJ5dGUpIDB4MzUsIChieXRlKSAweDYyLAorICAgICAgICAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4RkIsIChieXRlKSAweDYyLCAoYnl0ZSkgMHg3QSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDI0LCAoYnl0ZSkgMHgzQiwgKGJ5dGUpIDB4Q0MsIChieXRlKSAweEE0LCAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4QkUsIChieXRlKSAweEE4LCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4OTAsIChieXRlKSAweDg5LCAoYnl0ZSkgMHhBOCwgKGJ5dGUpIDB4ODMsCisgICAgICAgIChieXRlKSAweERGLCAoYnl0ZSkgMHhFMSwgKGJ5dGUpIDB4NUEsIChieXRlKSAweEU1LCAoYnl0ZSkgMHg5RiwgKGJ5dGUpIDB4MDYsIChieXRlKSAweDkyLCAoYnl0ZSkgMHg4QiwgKGJ5dGUpIDB4NjYsIChieXRlKSAweDVFLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4N0IsIChieXRlKSAweDU1LCAoYnl0ZSkgMHgyNSwgKGJ5dGUpIDB4NjQsIChieXRlKSAweDAxLCAoYnl0ZSkgMHg0QywKKyAgICAgICAgKGJ5dGUpIDB4M0IsIChieXRlKSAweEZFLCAoYnl0ZSkgMHhDRiwgKGJ5dGUpIDB4NDksIChieXRlKSAweDJBLCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MTYsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgxNCwgKGJ5dGUpIDB4MEUsIChieXRlKSAweDkwLCAoYnl0ZSkgMHhCNywgKGJ5dGUpIDB4OTIsIChieXRlKSAweDAxLCAoYnl0ZSkgMHg5OCwgKGJ5dGUpIDB4Q0QsIChieXRlKSAweDg1LAorICAgICAgICAoYnl0ZSkgMHg4NywgKGJ5dGUpIDB4NzcsIChieXRlKSAweDJGLCAoYnl0ZSkgMHhCNCwgKGJ5dGUpIDB4MzEsIChieXRlKSAweEZELCAoYnl0ZSkgMHhERSwgKGJ5dGUpIDB4RkEsIChieXRlKSAweDA4LCAoYnl0ZSkgMHg2RCwgKGJ5dGUpIDB4MEMsIChieXRlKSAweEUzICB9OworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gRFNBX3B1YmxpYyA9IG5ldyBieXRlW10geworICAgICAgICAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDAxLCAoYnl0ZSkgMHhCOCwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDgyLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MkMsIChieXRlKSAweDA2LCAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4MkEsIChieXRlKSAweDg2LCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4Q0UsIChieXRlKSAweDM4LCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4MDEsCisgICAgICAgIChieXRlKSAweDMwLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDFGLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDgxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4RkQsIChieXRlKSAweDdGLCAoYnl0ZSkgMHg1MywgKGJ5dGUpIDB4ODEsIChieXRlKSAweDFELCAoYnl0ZSkgMHg3NSwgKGJ5dGUpIDB4MTIsIChieXRlKSAweDI5LCAoYnl0ZSkgMHg1MiwKKyAgICAgICAgKGJ5dGUpIDB4REYsIChieXRlKSAweDRBLCAoYnl0ZSkgMHg5QywgKGJ5dGUpIDB4MkUsIChieXRlKSAweEVDLCAoYnl0ZSkgMHhFNCwgKGJ5dGUpIDB4RTcsIChieXRlKSAweEY2LCAoYnl0ZSkgMHgxMSwgKGJ5dGUpIDB4QjcsIChieXRlKSAweDUyLCAoYnl0ZSkgMHgzQywgKGJ5dGUpIDB4RUYsIChieXRlKSAweDQ0LCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4QzMsIChieXRlKSAweDFFLAorICAgICAgICAoYnl0ZSkgMHgzRiwgKGJ5dGUpIDB4ODAsIChieXRlKSAweEI2LCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4MjYsIChieXRlKSAweDY5LCAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4NUQsIChieXRlKSAweDQwLCAoYnl0ZSkgMHgyMiwgKGJ5dGUpIDB4NTEsIChieXRlKSAweEZCLCAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4M0QsIChieXRlKSAweDhELCAoYnl0ZSkgMHg1OCwgKGJ5dGUpIDB4RkEsCisgICAgICAgIChieXRlKSAweEJGLCAoYnl0ZSkgMHhDNSwgKGJ5dGUpIDB4RjUsIChieXRlKSAweEJBLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4RjYsIChieXRlKSAweENCLCAoYnl0ZSkgMHg5QiwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDZDLCAoYnl0ZSkgMHhENywgKGJ5dGUpIDB4ODEsIChieXRlKSAweDNCLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4MUQsIChieXRlKSAweDM0LCAoYnl0ZSkgMHg2RiwKKyAgICAgICAgKGJ5dGUpIDB4RjIsIChieXRlKSAweDY2LCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4QjcsIChieXRlKSAweDZCLCAoYnl0ZSkgMHg5OSwgKGJ5dGUpIDB4NTAsIChieXRlKSAweEE1LCAoYnl0ZSkgMHhBNCwgKGJ5dGUpIDB4OUYsIChieXRlKSAweDlGLCAoYnl0ZSkgMHhFOCwgKGJ5dGUpIDB4MDQsIChieXRlKSAweDdCLCAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4MjIsIChieXRlKSAweEMyLAorICAgICAgICAoYnl0ZSkgMHg0RiwgKGJ5dGUpIDB4QkIsIChieXRlKSAweEE5LCAoYnl0ZSkgMHhENywgKGJ5dGUpIDB4RkUsIChieXRlKSAweEI3LCAoYnl0ZSkgMHhDNiwgKGJ5dGUpIDB4MUIsIChieXRlKSAweEY4LCAoYnl0ZSkgMHgzQiwgKGJ5dGUpIDB4NTcsIChieXRlKSAweEU3LCAoYnl0ZSkgMHhDNiwgKGJ5dGUpIDB4QTgsIChieXRlKSAweEE2LCAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4MEYsCisgICAgICAgIChieXRlKSAweDA0LCAoYnl0ZSkgMHhGQiwgKGJ5dGUpIDB4ODMsIChieXRlKSAweEY2LCAoYnl0ZSkgMHhEMywgKGJ5dGUpIDB4QzUsIChieXRlKSAweDFFLCAoYnl0ZSkgMHhDMywgKGJ5dGUpIDB4MDIsIChieXRlKSAweDM1LCAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4MTMsIChieXRlKSAweDVBLCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4OTEsIChieXRlKSAweDMyLCAoYnl0ZSkgMHhGNiwKKyAgICAgICAgKGJ5dGUpIDB4NzUsIChieXRlKSAweEYzLCAoYnl0ZSkgMHhBRSwgKGJ5dGUpIDB4MkIsIChieXRlKSAweDYxLCAoYnl0ZSkgMHhENywgKGJ5dGUpIDB4MkEsIChieXRlKSAweEVGLCAoYnl0ZSkgMHhGMiwgKGJ5dGUpIDB4MjIsIChieXRlKSAweDAzLCAoYnl0ZSkgMHgxOSwgKGJ5dGUpIDB4OUQsIChieXRlKSAweEQxLCAoYnl0ZSkgMHg0OCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweEM3LAorICAgICAgICAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MTUsIChieXRlKSAweDAwLCAoYnl0ZSkgMHg5NywgKGJ5dGUpIDB4NjAsIChieXRlKSAweDUwLCAoYnl0ZSkgMHg4RiwgKGJ5dGUpIDB4MTUsIChieXRlKSAweDIzLCAoYnl0ZSkgMHgwQiwgKGJ5dGUpIDB4Q0MsIChieXRlKSAweEIyLCAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4QjksIChieXRlKSAweDgyLCAoYnl0ZSkgMHhBMiwgKGJ5dGUpIDB4RUIsCisgICAgICAgIChieXRlKSAweDg0LCAoYnl0ZSkgMHgwQiwgKGJ5dGUpIDB4RjAsIChieXRlKSAweDU4LCAoYnl0ZSkgMHgxQywgKGJ5dGUpIDB4RjUsIChieXRlKSAweDAyLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDAwLCAoYnl0ZSkgMHhGNywgKGJ5dGUpIDB4RTEsIChieXRlKSAweEEwLCAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4RDYsIChieXRlKSAweDlCLCAoYnl0ZSkgMHgzRCwKKyAgICAgICAgKGJ5dGUpIDB4REUsIChieXRlKSAweENCLCAoYnl0ZSkgMHhCQywgKGJ5dGUpIDB4QUIsIChieXRlKSAweDVDLCAoYnl0ZSkgMHgzNiwgKGJ5dGUpIDB4QjgsIChieXRlKSAweDU3LCAoYnl0ZSkgMHhCOSwgKGJ5dGUpIDB4NzksIChieXRlKSAweDk0LCAoYnl0ZSkgMHhBRiwgKGJ5dGUpIDB4QkIsIChieXRlKSAweEZBLCAoYnl0ZSkgMHgzQSwgKGJ5dGUpIDB4RUEsIChieXRlKSAweDgyLAorICAgICAgICAoYnl0ZSkgMHhGOSwgKGJ5dGUpIDB4NTcsIChieXRlKSAweDRDLCAoYnl0ZSkgMHgwQiwgKGJ5dGUpIDB4M0QsIChieXRlKSAweDA3LCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4NjcsIChieXRlKSAweDUxLCAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4NTcsIChieXRlKSAweDhFLCAoYnl0ZSkgMHhCQSwgKGJ5dGUpIDB4RDQsIChieXRlKSAweDU5LCAoYnl0ZSkgMHg0RiwgKGJ5dGUpIDB4RTYsCisgICAgICAgIChieXRlKSAweDcxLCAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4MTAsIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4QjQsIChieXRlKSAweDQ5LCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4NzEsIChieXRlKSAweDIzLCAoYnl0ZSkgMHhFOCwgKGJ5dGUpIDB4NEMsIChieXRlKSAweDI4LCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4MTMsIChieXRlKSAweEI3LCAoYnl0ZSkgMHhDRiwKKyAgICAgICAgKGJ5dGUpIDB4MDksIChieXRlKSAweDMyLCAoYnl0ZSkgMHg4QywgKGJ5dGUpIDB4QzgsIChieXRlKSAweEE2LCAoYnl0ZSkgMHhFMSwgKGJ5dGUpIDB4M0MsIChieXRlKSAweDE2LCAoYnl0ZSkgMHg3QSwgKGJ5dGUpIDB4OEIsIChieXRlKSAweDU0LCAoYnl0ZSkgMHg3QywgKGJ5dGUpIDB4OEQsIChieXRlKSAweDI4LCAoYnl0ZSkgMHhFMCwgKGJ5dGUpIDB4QTMsIChieXRlKSAweEFFLAorICAgICAgICAoYnl0ZSkgMHgxRSwgKGJ5dGUpIDB4MkIsIChieXRlKSAweEIzLCAoYnl0ZSkgMHhBNiwgKGJ5dGUpIDB4NzUsIChieXRlKSAweDkxLCAoYnl0ZSkgMHg2RSwgKGJ5dGUpIDB4QTMsIChieXRlKSAweDdGLCAoYnl0ZSkgMHgwQiwgKGJ5dGUpIDB4RkEsIChieXRlKSAweDIxLCAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4NjIsIChieXRlKSAweEYxLCAoYnl0ZSkgMHhGQiwgKGJ5dGUpIDB4NjIsCisgICAgICAgIChieXRlKSAweDdBLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MjQsIChieXRlKSAweDNCLCAoYnl0ZSkgMHhDQywgKGJ5dGUpIDB4QTQsIChieXRlKSAweEYxLCAoYnl0ZSkgMHhCRSwgKGJ5dGUpIDB4QTgsIChieXRlKSAweDUxLCAoYnl0ZSkgMHg5MCwgKGJ5dGUpIDB4ODksIChieXRlKSAweEE4LCAoYnl0ZSkgMHg4MywgKGJ5dGUpIDB4REYsIChieXRlKSAweEUxLCAoYnl0ZSkgMHg1QSwKKyAgICAgICAgKGJ5dGUpIDB4RTUsIChieXRlKSAweDlGLCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4OTIsIChieXRlKSAweDhCLCAoYnl0ZSkgMHg2NiwgKGJ5dGUpIDB4NUUsIChieXRlKSAweDgwLCAoYnl0ZSkgMHg3QiwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDI1LCAoYnl0ZSkgMHg2NCwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDRDLCAoYnl0ZSkgMHgzQiwgKGJ5dGUpIDB4RkUsIChieXRlKSAweENGLAorICAgICAgICAoYnl0ZSkgMHg0OSwgKGJ5dGUpIDB4MkEsIChieXRlKSAweDAzLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODUsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDgxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4OTgsIChieXRlKSAweDMzLCAoYnl0ZSkgMHg5MCwgKGJ5dGUpIDB4MTQsIChieXRlKSAweDc5LCAoYnl0ZSkgMHhDNywgKGJ5dGUpIDB4QzgsCisgICAgICAgIChieXRlKSAweDU3LCAoYnl0ZSkgMHhFMSwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDUzLCAoYnl0ZSkgMHg1QiwgKGJ5dGUpIDB4NkUsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4MUUsIChieXRlKSAweEE1LCAoYnl0ZSkgMHg5OCwgKGJ5dGUpIDB4QzQsIChieXRlKSAweDU3LCAoYnl0ZSkgMHg1RCwgKGJ5dGUpIDB4MjMsIChieXRlKSAweEFCLCAoYnl0ZSkgMHg3MiwKKyAgICAgICAgKGJ5dGUpIDB4OUEsIChieXRlKSAweEIzLCAoYnl0ZSkgMHgyRiwgKGJ5dGUpIDB4MzksIChieXRlKSAweENCLCAoYnl0ZSkgMHhDNSwgKGJ5dGUpIDB4RDAsIChieXRlKSAweDk3LCAoYnl0ZSkgMHhENSwgKGJ5dGUpIDB4NjIsIChieXRlKSAweDhDLCAoYnl0ZSkgMHhEOSwgKGJ5dGUpIDB4RTYsIChieXRlKSAweEUyLCAoYnl0ZSkgMHgwNSwgKGJ5dGUpIDB4QzYsIChieXRlKSAweDA1LAorICAgICAgICAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4MTYsIChieXRlKSAweEUzLCAoYnl0ZSkgMHhFOCwgKGJ5dGUpIDB4MDQsIChieXRlKSAweEU4LCAoYnl0ZSkgMHg0NiwgKGJ5dGUpIDB4MTIsIChieXRlKSAweDBDLCAoYnl0ZSkgMHhGOCwgKGJ5dGUpIDB4RkMsIChieXRlKSAweDhFLCAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4MjYsIChieXRlKSAweDMyLCAoYnl0ZSkgMHhGNywgKGJ5dGUpIDB4OEMsCisgICAgICAgIChieXRlKSAweDA0LCAoYnl0ZSkgMHgzQiwgKGJ5dGUpIDB4NTMsIChieXRlKSAweDY4LCAoYnl0ZSkgMHg5QSwgKGJ5dGUpIDB4QTMsIChieXRlKSAweEI3LCAoYnl0ZSkgMHg0RCwgKGJ5dGUpIDB4MTMsIChieXRlKSAweDQwLCAoYnl0ZSkgMHgwRiwgKGJ5dGUpIDB4QkUsIChieXRlKSAweDAzLCAoYnl0ZSkgMHg4NywgKGJ5dGUpIDB4RDgsIChieXRlKSAweEYxLCAoYnl0ZSkgMHhGRSwKKyAgICAgICAgKGJ5dGUpIDB4NEIsIChieXRlKSAweEY1LCAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4MTksIChieXRlKSAweDI5LCAoYnl0ZSkgMHhCQiwgKGJ5dGUpIDB4MEQsIChieXRlKSAweDBDLCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4QzYsIChieXRlKSAweDg0LCAoYnl0ZSkgMHgzMywgKGJ5dGUpIDB4NjIsIChieXRlKSAweDczLCAoYnl0ZSkgMHg1RCwgKGJ5dGUpIDB4MDMsIChieXRlKSAweEZGLAorICAgICAgICAoYnl0ZSkgMHg2RiwgKGJ5dGUpIDB4MEEsIChieXRlKSAweDVBLCAoYnl0ZSkgMHhGMywgKGJ5dGUpIDB4OUUsIChieXRlKSAweDUyLCAoYnl0ZSkgMHhGMiwgKGJ5dGUpIDB4QzIsIChieXRlKSAweEM4LCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4NTIsIChieXRlKSAweEM3LCAoYnl0ZSkgMHg3NSwgKGJ5dGUpIDB4QTQsIChieXRlKSAweEZELCAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4MkQsCisgICAgICAgIChieXRlKSAweDdCLCAoYnl0ZSkgMHg3QSwgKGJ5dGUpIDB4MzEsIChieXRlKSAweDI3LCAoYnl0ZSkgMHg2RSwgKGJ5dGUpIDB4QUMsIChieXRlKSAweEI2LCAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4MTQsIChieXRlKSAweDRFLCAoYnl0ZSkgMHhCNCwgKGJ5dGUpIDB4QkIsIChieXRlKSAweEIxLCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4NjMsIChieXRlKSAweDI5LCAoYnl0ZSkgMHg4MSwKKyAgICAgICAgKGJ5dGUpIDB4MDYsIChieXRlKSAweEY5ICAgIH07CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBESF9wcml2YXRlID0gbmV3IGJ5dGVbXSB7CisgICAgICAgIChieXRlKSAweDMwLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDEsIChieXRlKSAweEE4LCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDAwLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgxQiwgKGJ5dGUpIDB4MDYsIChieXRlKSAweDA5LCAoYnl0ZSkgMHgyQSwgKGJ5dGUpIDB4ODYsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg4NiwKKyAgICAgICAgKGJ5dGUpIDB4RjcsIChieXRlKSAweDBELCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4MDMsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4ODIsIChieXRlKSAweDAxLCAoYnl0ZSkgMHgwQywgKGJ5dGUpIDB4MDIsIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweEZELCAoYnl0ZSkgMHg3RiwgKGJ5dGUpIDB4NTMsIChieXRlKSAweDgxLAorICAgICAgICAoYnl0ZSkgMHgxRCwgKGJ5dGUpIDB4NzUsIChieXRlKSAweDEyLCAoYnl0ZSkgMHgyOSwgKGJ5dGUpIDB4NTIsIChieXRlKSAweERGLCAoYnl0ZSkgMHg0QSwgKGJ5dGUpIDB4OUMsIChieXRlKSAweDJFLCAoYnl0ZSkgMHhFQywgKGJ5dGUpIDB4RTQsIChieXRlKSAweEU3LCAoYnl0ZSkgMHhGNiwgKGJ5dGUpIDB4MTEsIChieXRlKSAweEI3LCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4M0MsCisgICAgICAgIChieXRlKSAweEVGLCAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4MDAsIChieXRlKSAweEMzLCAoYnl0ZSkgMHgxRSwgKGJ5dGUpIDB4M0YsIChieXRlKSAweDgwLCAoYnl0ZSkgMHhCNiwgKGJ5dGUpIDB4NTEsIChieXRlKSAweDI2LCAoYnl0ZSkgMHg2OSwgKGJ5dGUpIDB4NDUsIChieXRlKSAweDVELCAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4MjIsIChieXRlKSAweDUxLCAoYnl0ZSkgMHhGQiwKKyAgICAgICAgKGJ5dGUpIDB4NTksIChieXRlKSAweDNELCAoYnl0ZSkgMHg4RCwgKGJ5dGUpIDB4NTgsIChieXRlKSAweEZBLCAoYnl0ZSkgMHhCRiwgKGJ5dGUpIDB4QzUsIChieXRlKSAweEY1LCAoYnl0ZSkgMHhCQSwgKGJ5dGUpIDB4MzAsIChieXRlKSAweEY2LCAoYnl0ZSkgMHhDQiwgKGJ5dGUpIDB4OUIsIChieXRlKSAweDU1LCAoYnl0ZSkgMHg2QywgKGJ5dGUpIDB4RDcsIChieXRlKSAweDgxLAorICAgICAgICAoYnl0ZSkgMHgzQiwgKGJ5dGUpIDB4ODAsIChieXRlKSAweDFELCAoYnl0ZSkgMHgzNCwgKGJ5dGUpIDB4NkYsIChieXRlKSAweEYyLCAoYnl0ZSkgMHg2NiwgKGJ5dGUpIDB4NjAsIChieXRlKSAweEI3LCAoYnl0ZSkgMHg2QiwgKGJ5dGUpIDB4OTksIChieXRlKSAweDUwLCAoYnl0ZSkgMHhBNSwgKGJ5dGUpIDB4QTQsIChieXRlKSAweDlGLCAoYnl0ZSkgMHg5RiwgKGJ5dGUpIDB4RTgsCisgICAgICAgIChieXRlKSAweDA0LCAoYnl0ZSkgMHg3QiwgKGJ5dGUpIDB4MTAsIChieXRlKSAweDIyLCAoYnl0ZSkgMHhDMiwgKGJ5dGUpIDB4NEYsIChieXRlKSAweEJCLCAoYnl0ZSkgMHhBOSwgKGJ5dGUpIDB4RDcsIChieXRlKSAweEZFLCAoYnl0ZSkgMHhCNywgKGJ5dGUpIDB4QzYsIChieXRlKSAweDFCLCAoYnl0ZSkgMHhGOCwgKGJ5dGUpIDB4M0IsIChieXRlKSAweDU3LCAoYnl0ZSkgMHhFNywKKyAgICAgICAgKGJ5dGUpIDB4QzYsIChieXRlKSAweEE4LCAoYnl0ZSkgMHhBNiwgKGJ5dGUpIDB4MTUsIChieXRlKSAweDBGLCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4RkIsIChieXRlKSAweDgzLCAoYnl0ZSkgMHhGNiwgKGJ5dGUpIDB4RDMsIChieXRlKSAweEM1LCAoYnl0ZSkgMHgxRSwgKGJ5dGUpIDB4QzMsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgzNSwgKGJ5dGUpIDB4NTQsIChieXRlKSAweDEzLAorICAgICAgICAoYnl0ZSkgMHg1QSwgKGJ5dGUpIDB4MTYsIChieXRlKSAweDkxLCAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4RjYsIChieXRlKSAweDc1LCAoYnl0ZSkgMHhGMywgKGJ5dGUpIDB4QUUsIChieXRlKSAweDJCLCAoYnl0ZSkgMHg2MSwgKGJ5dGUpIDB4RDcsIChieXRlKSAweDJBLCAoYnl0ZSkgMHhFRiwgKGJ5dGUpIDB4RjIsIChieXRlKSAweDIyLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MTksCisgICAgICAgIChieXRlKSAweDlELCAoYnl0ZSkgMHhEMSwgKGJ5dGUpIDB4NDgsIChieXRlKSAweDAxLCAoYnl0ZSkgMHhDNywgKGJ5dGUpIDB4MDIsIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweEY3LCAoYnl0ZSkgMHhFMSwgKGJ5dGUpIDB4QTAsIChieXRlKSAweDg1LCAoYnl0ZSkgMHhENiwgKGJ5dGUpIDB4OUIsIChieXRlKSAweDNELCAoYnl0ZSkgMHhERSwKKyAgICAgICAgKGJ5dGUpIDB4Q0IsIChieXRlKSAweEJDLCAoYnl0ZSkgMHhBQiwgKGJ5dGUpIDB4NUMsIChieXRlKSAweDM2LCAoYnl0ZSkgMHhCOCwgKGJ5dGUpIDB4NTcsIChieXRlKSAweEI5LCAoYnl0ZSkgMHg3OSwgKGJ5dGUpIDB4OTQsIChieXRlKSAweEFGLCAoYnl0ZSkgMHhCQiwgKGJ5dGUpIDB4RkEsIChieXRlKSAweDNBLCAoYnl0ZSkgMHhFQSwgKGJ5dGUpIDB4ODIsIChieXRlKSAweEY5LAorICAgICAgICAoYnl0ZSkgMHg1NywgKGJ5dGUpIDB4NEMsIChieXRlKSAweDBCLCAoYnl0ZSkgMHgzRCwgKGJ5dGUpIDB4MDcsIChieXRlKSAweDgyLCAoYnl0ZSkgMHg2NywgKGJ5dGUpIDB4NTEsIChieXRlKSAweDU5LCAoYnl0ZSkgMHg1NywgKGJ5dGUpIDB4OEUsIChieXRlKSAweEJBLCAoYnl0ZSkgMHhENCwgKGJ5dGUpIDB4NTksIChieXRlKSAweDRGLCAoYnl0ZSkgMHhFNiwgKGJ5dGUpIDB4NzEsCisgICAgICAgIChieXRlKSAweDA3LCAoYnl0ZSkgMHgxMCwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDgwLCAoYnl0ZSkgMHhCNCwgKGJ5dGUpIDB4NDksIChieXRlKSAweDE2LCAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4MjMsIChieXRlKSAweEU4LCAoYnl0ZSkgMHg0QywgKGJ5dGUpIDB4MjgsIChieXRlKSAweDE2LCAoYnl0ZSkgMHgxMywgKGJ5dGUpIDB4QjcsIChieXRlKSAweENGLCAoYnl0ZSkgMHgwOSwKKyAgICAgICAgKGJ5dGUpIDB4MzIsIChieXRlKSAweDhDLCAoYnl0ZSkgMHhDOCwgKGJ5dGUpIDB4QTYsIChieXRlKSAweEUxLCAoYnl0ZSkgMHgzQywgKGJ5dGUpIDB4MTYsIChieXRlKSAweDdBLCAoYnl0ZSkgMHg4QiwgKGJ5dGUpIDB4NTQsIChieXRlKSAweDdDLCAoYnl0ZSkgMHg4RCwgKGJ5dGUpIDB4MjgsIChieXRlKSAweEUwLCAoYnl0ZSkgMHhBMywgKGJ5dGUpIDB4QUUsIChieXRlKSAweDFFLAorICAgICAgICAoYnl0ZSkgMHgyQiwgKGJ5dGUpIDB4QjMsIChieXRlKSAweEE2LCAoYnl0ZSkgMHg3NSwgKGJ5dGUpIDB4OTEsIChieXRlKSAweDZFLCAoYnl0ZSkgMHhBMywgKGJ5dGUpIDB4N0YsIChieXRlKSAweDBCLCAoYnl0ZSkgMHhGQSwgKGJ5dGUpIDB4MjEsIChieXRlKSAweDM1LCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4RjEsIChieXRlKSAweEZCLCAoYnl0ZSkgMHg2MiwgKGJ5dGUpIDB4N0EsCisgICAgICAgIChieXRlKSAweDAxLCAoYnl0ZSkgMHgyNCwgKGJ5dGUpIDB4M0IsIChieXRlKSAweENDLCAoYnl0ZSkgMHhBNCwgKGJ5dGUpIDB4RjEsIChieXRlKSAweEJFLCAoYnl0ZSkgMHhBOCwgKGJ5dGUpIDB4NTEsIChieXRlKSAweDkwLCAoYnl0ZSkgMHg4OSwgKGJ5dGUpIDB4QTgsIChieXRlKSAweDgzLCAoYnl0ZSkgMHhERiwgKGJ5dGUpIDB4RTEsIChieXRlKSAweDVBLCAoYnl0ZSkgMHhFNSwKKyAgICAgICAgKGJ5dGUpIDB4OUYsIChieXRlKSAweDA2LCAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4OEIsIChieXRlKSAweDY2LCAoYnl0ZSkgMHg1RSwgKGJ5dGUpIDB4ODAsIChieXRlKSAweDdCLCAoYnl0ZSkgMHg1NSwgKGJ5dGUpIDB4MjUsIChieXRlKSAweDY0LCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4NEMsIChieXRlKSAweDNCLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4Q0YsIChieXRlKSAweDQ5LAorICAgICAgICAoYnl0ZSkgMHgyQSwgKGJ5dGUpIDB4MDIsIChieXRlKSAweDAyLCAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4RkUsIChieXRlKSAweDA0LCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODMsIChieXRlKSAweDAyLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODAsIChieXRlKSAweDM1LCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4NDQsIChieXRlKSAweDBBLCAoYnl0ZSkgMHhBMywgKGJ5dGUpIDB4QTAsCisgICAgICAgIChieXRlKSAweENCLCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4QzIsIChieXRlKSAweDMyLCAoYnl0ZSkgMHhDQSwgKGJ5dGUpIDB4MzgsIChieXRlKSAweDFGLCAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4RUIsIChieXRlKSAweDI3LCAoYnl0ZSkgMHg2RSwgKGJ5dGUpIDB4NzcsIChieXRlKSAweDI1LCAoYnl0ZSkgMHg0MCwgKGJ5dGUpIDB4MUYsIChieXRlKSAweDY0LCAoYnl0ZSkgMHg1RCwKKyAgICAgICAgKGJ5dGUpIDB4NEIsIChieXRlKSAweDU5LCAoYnl0ZSkgMHg0MSwgKGJ5dGUpIDB4QjYsIChieXRlKSAweENCLCAoYnl0ZSkgMHhERiwgKGJ5dGUpIDB4NzMsIChieXRlKSAweEUwLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4NUEsIChieXRlKSAweDc5LCAoYnl0ZSkgMHgwRCwgKGJ5dGUpIDB4OEQsIChieXRlKSAweDA4LCAoYnl0ZSkgMHhFNiwgKGJ5dGUpIDB4N0YsIChieXRlKSAweDg2LAorICAgICAgICAoYnl0ZSkgMHg1OCwgKGJ5dGUpIDB4Q0YsIChieXRlKSAweDdGLCAoYnl0ZSkgMHg0QiwgKGJ5dGUpIDB4MkUsIChieXRlKSAweERCLCAoYnl0ZSkgMHg0QywgKGJ5dGUpIDB4REYsIChieXRlKSAweDc1LCAoYnl0ZSkgMHhCNSwgKGJ5dGUpIDB4MTYsIChieXRlKSAweEM0LCAoYnl0ZSkgMHhBOSwgKGJ5dGUpIDB4NDksIChieXRlKSAweEVFLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4NTYsCisgICAgICAgIChieXRlKSAweEEwLCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4MDgsIChieXRlKSAweDhFLCAoYnl0ZSkgMHgwRCwgKGJ5dGUpIDB4QzcsIChieXRlKSAweEM5LCAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4MEMsIChieXRlKSAweDVELCAoYnl0ZSkgMHhCNywgKGJ5dGUpIDB4NEMsIChieXRlKSAweEM0LCAoYnl0ZSkgMHg3RSwgKGJ5dGUpIDB4QUIsIChieXRlKSAweDFGLCAoYnl0ZSkgMHhFQSwKKyAgICAgICAgKGJ5dGUpIDB4Q0YsIChieXRlKSAweDA4LCAoYnl0ZSkgMHg2RCwgKGJ5dGUpIDB4MDUsIChieXRlKSAweEExLCAoYnl0ZSkgMHg3RiwgKGJ5dGUpIDB4NjMsIChieXRlKSAweDZGLCAoYnl0ZSkgMHhCMywgKGJ5dGUpIDB4OTEsIChieXRlKSAweEEzLCAoYnl0ZSkgMHhFMSwgKGJ5dGUpIDB4QjAsIChieXRlKSAweDM2LCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4M0YsIChieXRlKSAweDU1LAorICAgICAgICAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4MzgsIChieXRlKSAweDM3LCAoYnl0ZSkgMHg5QSwgKGJ5dGUpIDB4MTksIChieXRlKSAweEEzLCAoYnl0ZSkgMHhBRiwgKGJ5dGUpIDB4QzgsIChieXRlKSAweEQ1LCAoYnl0ZSkgMHgyMiwgKGJ5dGUpIDB4REQsIChieXRlKSAweDAwLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4MTksIChieXRlKSAweEI2LCAoYnl0ZSkgMHgzQywgKGJ5dGUpIDB4NUYsCisgICAgICAgIChieXRlKSAweEQ5LCAoYnl0ZSkgMHhERiwgKGJ5dGUpIDB4RkQsIChieXRlKSAweDU4LCAoYnl0ZSkgMHhCMSwgKGJ5dGUpIDB4RTYsIChieXRlKSAweEQxLCAoYnl0ZSkgMHhEMiwgKGJ5dGUpIDB4NTgsIChieXRlKSAweEVGLCAoYnl0ZSkgMHg0NCwgKGJ5dGUpIDB4NkUsIChieXRlKSAweDY2LCAoYnl0ZSkgMHg5MiwgKGJ5dGUpIDB4MUUsIChieXRlKSAweDMwLCAoYnl0ZSkgMHgwQiwKKyAgICAgICAgKGJ5dGUpIDB4OTAsIChieXRlKSAweDhFLCAoYnl0ZSkgMHgyOSAgIH07CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBESF9wdWJsaWMgPSBuZXcgYnl0ZVtdIHsKKyAgICAgICAgKGJ5dGUpIDB4MzAsIChieXRlKSAweDgyLCAoYnl0ZSkgMHgwMSwgKGJ5dGUpIDB4QTcsIChieXRlKSAweDMwLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDFCLCAoYnl0ZSkgMHgwNiwgKGJ5dGUpIDB4MDksIChieXRlKSAweDJBLCAoYnl0ZSkgMHg4NiwgKGJ5dGUpIDB4NDgsIChieXRlKSAweDg2LCAoYnl0ZSkgMHhGNywgKGJ5dGUpIDB4MEQsIChieXRlKSAweDAxLAorICAgICAgICAoYnl0ZSkgMHgwMywgKGJ5dGUpIDB4MDEsIChieXRlKSAweDMwLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDBDLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDgxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4RkQsIChieXRlKSAweDdGLCAoYnl0ZSkgMHg1MywgKGJ5dGUpIDB4ODEsIChieXRlKSAweDFELCAoYnl0ZSkgMHg3NSwgKGJ5dGUpIDB4MTIsCisgICAgICAgIChieXRlKSAweDI5LCAoYnl0ZSkgMHg1MiwgKGJ5dGUpIDB4REYsIChieXRlKSAweDRBLCAoYnl0ZSkgMHg5QywgKGJ5dGUpIDB4MkUsIChieXRlKSAweEVDLCAoYnl0ZSkgMHhFNCwgKGJ5dGUpIDB4RTcsIChieXRlKSAweEY2LCAoYnl0ZSkgMHgxMSwgKGJ5dGUpIDB4QjcsIChieXRlKSAweDUyLCAoYnl0ZSkgMHgzQywgKGJ5dGUpIDB4RUYsIChieXRlKSAweDQ0LCAoYnl0ZSkgMHgwMCwKKyAgICAgICAgKGJ5dGUpIDB4QzMsIChieXRlKSAweDFFLCAoYnl0ZSkgMHgzRiwgKGJ5dGUpIDB4ODAsIChieXRlKSAweEI2LCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4MjYsIChieXRlKSAweDY5LCAoYnl0ZSkgMHg0NSwgKGJ5dGUpIDB4NUQsIChieXRlKSAweDQwLCAoYnl0ZSkgMHgyMiwgKGJ5dGUpIDB4NTEsIChieXRlKSAweEZCLCAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4M0QsIChieXRlKSAweDhELAorICAgICAgICAoYnl0ZSkgMHg1OCwgKGJ5dGUpIDB4RkEsIChieXRlKSAweEJGLCAoYnl0ZSkgMHhDNSwgKGJ5dGUpIDB4RjUsIChieXRlKSAweEJBLCAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4RjYsIChieXRlKSAweENCLCAoYnl0ZSkgMHg5QiwgKGJ5dGUpIDB4NTUsIChieXRlKSAweDZDLCAoYnl0ZSkgMHhENywgKGJ5dGUpIDB4ODEsIChieXRlKSAweDNCLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4MUQsCisgICAgICAgIChieXRlKSAweDM0LCAoYnl0ZSkgMHg2RiwgKGJ5dGUpIDB4RjIsIChieXRlKSAweDY2LCAoYnl0ZSkgMHg2MCwgKGJ5dGUpIDB4QjcsIChieXRlKSAweDZCLCAoYnl0ZSkgMHg5OSwgKGJ5dGUpIDB4NTAsIChieXRlKSAweEE1LCAoYnl0ZSkgMHhBNCwgKGJ5dGUpIDB4OUYsIChieXRlKSAweDlGLCAoYnl0ZSkgMHhFOCwgKGJ5dGUpIDB4MDQsIChieXRlKSAweDdCLCAoYnl0ZSkgMHgxMCwKKyAgICAgICAgKGJ5dGUpIDB4MjIsIChieXRlKSAweEMyLCAoYnl0ZSkgMHg0RiwgKGJ5dGUpIDB4QkIsIChieXRlKSAweEE5LCAoYnl0ZSkgMHhENywgKGJ5dGUpIDB4RkUsIChieXRlKSAweEI3LCAoYnl0ZSkgMHhDNiwgKGJ5dGUpIDB4MUIsIChieXRlKSAweEY4LCAoYnl0ZSkgMHgzQiwgKGJ5dGUpIDB4NTcsIChieXRlKSAweEU3LCAoYnl0ZSkgMHhDNiwgKGJ5dGUpIDB4QTgsIChieXRlKSAweEE2LAorICAgICAgICAoYnl0ZSkgMHgxNSwgKGJ5dGUpIDB4MEYsIChieXRlKSAweDA0LCAoYnl0ZSkgMHhGQiwgKGJ5dGUpIDB4ODMsIChieXRlKSAweEY2LCAoYnl0ZSkgMHhEMywgKGJ5dGUpIDB4QzUsIChieXRlKSAweDFFLCAoYnl0ZSkgMHhDMywgKGJ5dGUpIDB4MDIsIChieXRlKSAweDM1LCAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4MTMsIChieXRlKSAweDVBLCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4OTEsCisgICAgICAgIChieXRlKSAweDMyLCAoYnl0ZSkgMHhGNiwgKGJ5dGUpIDB4NzUsIChieXRlKSAweEYzLCAoYnl0ZSkgMHhBRSwgKGJ5dGUpIDB4MkIsIChieXRlKSAweDYxLCAoYnl0ZSkgMHhENywgKGJ5dGUpIDB4MkEsIChieXRlKSAweEVGLCAoYnl0ZSkgMHhGMiwgKGJ5dGUpIDB4MjIsIChieXRlKSAweDAzLCAoYnl0ZSkgMHgxOSwgKGJ5dGUpIDB4OUQsIChieXRlKSAweEQxLCAoYnl0ZSkgMHg0OCwKKyAgICAgICAgKGJ5dGUpIDB4MDEsIChieXRlKSAweEM3LCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDgxLCAoYnl0ZSkgMHgwMCwgKGJ5dGUpIDB4RjcsIChieXRlKSAweEUxLCAoYnl0ZSkgMHhBMCwgKGJ5dGUpIDB4ODUsIChieXRlKSAweEQ2LCAoYnl0ZSkgMHg5QiwgKGJ5dGUpIDB4M0QsIChieXRlKSAweERFLCAoYnl0ZSkgMHhDQiwgKGJ5dGUpIDB4QkMsIChieXRlKSAweEFCLAorICAgICAgICAoYnl0ZSkgMHg1QywgKGJ5dGUpIDB4MzYsIChieXRlKSAweEI4LCAoYnl0ZSkgMHg1NywgKGJ5dGUpIDB4QjksIChieXRlKSAweDc5LCAoYnl0ZSkgMHg5NCwgKGJ5dGUpIDB4QUYsIChieXRlKSAweEJCLCAoYnl0ZSkgMHhGQSwgKGJ5dGUpIDB4M0EsIChieXRlKSAweEVBLCAoYnl0ZSkgMHg4MiwgKGJ5dGUpIDB4RjksIChieXRlKSAweDU3LCAoYnl0ZSkgMHg0QywgKGJ5dGUpIDB4MEIsCisgICAgICAgIChieXRlKSAweDNELCAoYnl0ZSkgMHgwNywgKGJ5dGUpIDB4ODIsIChieXRlKSAweDY3LCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4NTksIChieXRlKSAweDU3LCAoYnl0ZSkgMHg4RSwgKGJ5dGUpIDB4QkEsIChieXRlKSAweEQ0LCAoYnl0ZSkgMHg1OSwgKGJ5dGUpIDB4NEYsIChieXRlKSAweEU2LCAoYnl0ZSkgMHg3MSwgKGJ5dGUpIDB4MDcsIChieXRlKSAweDEwLCAoYnl0ZSkgMHg4MSwKKyAgICAgICAgKGJ5dGUpIDB4ODAsIChieXRlKSAweEI0LCAoYnl0ZSkgMHg0OSwgKGJ5dGUpIDB4MTYsIChieXRlKSAweDcxLCAoYnl0ZSkgMHgyMywgKGJ5dGUpIDB4RTgsIChieXRlKSAweDRDLCAoYnl0ZSkgMHgyOCwgKGJ5dGUpIDB4MTYsIChieXRlKSAweDEzLCAoYnl0ZSkgMHhCNywgKGJ5dGUpIDB4Q0YsIChieXRlKSAweDA5LCAoYnl0ZSkgMHgzMiwgKGJ5dGUpIDB4OEMsIChieXRlKSAweEM4LAorICAgICAgICAoYnl0ZSkgMHhBNiwgKGJ5dGUpIDB4RTEsIChieXRlKSAweDNDLCAoYnl0ZSkgMHgxNiwgKGJ5dGUpIDB4N0EsIChieXRlKSAweDhCLCAoYnl0ZSkgMHg1NCwgKGJ5dGUpIDB4N0MsIChieXRlKSAweDhELCAoYnl0ZSkgMHgyOCwgKGJ5dGUpIDB4RTAsIChieXRlKSAweEEzLCAoYnl0ZSkgMHhBRSwgKGJ5dGUpIDB4MUUsIChieXRlKSAweDJCLCAoYnl0ZSkgMHhCMywgKGJ5dGUpIDB4QTYsCisgICAgICAgIChieXRlKSAweDc1LCAoYnl0ZSkgMHg5MSwgKGJ5dGUpIDB4NkUsIChieXRlKSAweEEzLCAoYnl0ZSkgMHg3RiwgKGJ5dGUpIDB4MEIsIChieXRlKSAweEZBLCAoYnl0ZSkgMHgyMSwgKGJ5dGUpIDB4MzUsIChieXRlKSAweDYyLCAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4RkIsIChieXRlKSAweDYyLCAoYnl0ZSkgMHg3QSwgKGJ5dGUpIDB4MDEsIChieXRlKSAweDI0LCAoYnl0ZSkgMHgzQiwKKyAgICAgICAgKGJ5dGUpIDB4Q0MsIChieXRlKSAweEE0LCAoYnl0ZSkgMHhGMSwgKGJ5dGUpIDB4QkUsIChieXRlKSAweEE4LCAoYnl0ZSkgMHg1MSwgKGJ5dGUpIDB4OTAsIChieXRlKSAweDg5LCAoYnl0ZSkgMHhBOCwgKGJ5dGUpIDB4ODMsIChieXRlKSAweERGLCAoYnl0ZSkgMHhFMSwgKGJ5dGUpIDB4NUEsIChieXRlKSAweEU1LCAoYnl0ZSkgMHg5RiwgKGJ5dGUpIDB4MDYsIChieXRlKSAweDkyLAorICAgICAgICAoYnl0ZSkgMHg4QiwgKGJ5dGUpIDB4NjYsIChieXRlKSAweDVFLCAoYnl0ZSkgMHg4MCwgKGJ5dGUpIDB4N0IsIChieXRlKSAweDU1LCAoYnl0ZSkgMHgyNSwgKGJ5dGUpIDB4NjQsIChieXRlKSAweDAxLCAoYnl0ZSkgMHg0QywgKGJ5dGUpIDB4M0IsIChieXRlKSAweEZFLCAoYnl0ZSkgMHhDRiwgKGJ5dGUpIDB4NDksIChieXRlKSAweDJBLCAoYnl0ZSkgMHgwMiwgKGJ5dGUpIDB4MDIsCisgICAgICAgIChieXRlKSAweDAzLCAoYnl0ZSkgMHhGRSwgKGJ5dGUpIDB4MDMsIChieXRlKSAweDgxLCAoYnl0ZSkgMHg4NSwgKGJ5dGUpIDB4MDAsIChieXRlKSAweDAyLCAoYnl0ZSkgMHg4MSwgKGJ5dGUpIDB4ODEsIChieXRlKSAweDAwLCAoYnl0ZSkgMHhENCwgKGJ5dGUpIDB4QzIsIChieXRlKSAweEMyLCAoYnl0ZSkgMHg4NCwgKGJ5dGUpIDB4RUIsIChieXRlKSAweEVDLCAoYnl0ZSkgMHhCNiwKKyAgICAgICAgKGJ5dGUpIDB4RjEsIChieXRlKSAweDI5LCAoYnl0ZSkgMHgyQiwgKGJ5dGUpIDB4QUIsIChieXRlKSAweDhGLCAoYnl0ZSkgMHhDMSwgKGJ5dGUpIDB4NDgsIChieXRlKSAweDRDLCAoYnl0ZSkgMHg0NywgKGJ5dGUpIDB4Q0UsIChieXRlKSAweDBCLCAoYnl0ZSkgMHg5NywgKGJ5dGUpIDB4NEMsIChieXRlKSAweEZDLCAoYnl0ZSkgMHgyNywgKGJ5dGUpIDB4MTAsIChieXRlKSAweDBBLAorICAgICAgICAoYnl0ZSkgMHg1RiwgKGJ5dGUpIDB4M0UsIChieXRlKSAweEU2LCAoYnl0ZSkgMHhGOSwgKGJ5dGUpIDB4OUIsIChieXRlKSAweDE1LCAoYnl0ZSkgMHhERiwgKGJ5dGUpIDB4ODMsIChieXRlKSAweDAxLCAoYnl0ZSkgMHhGQSwgKGJ5dGUpIDB4NjksIChieXRlKSAweDU3LCAoYnl0ZSkgMHhFQywgKGJ5dGUpIDB4NkIsIChieXRlKSAweDY4LCAoYnl0ZSkgMHhDNywgKGJ5dGUpIDB4OTYsCisgICAgICAgIChieXRlKSAweDMzLCAoYnl0ZSkgMHg5OCwgKGJ5dGUpIDB4QTQsIChieXRlKSAweEIwLCAoYnl0ZSkgMHhBMywgKGJ5dGUpIDB4MTgsIChieXRlKSAweDAxLCAoYnl0ZSkgMHg2NiwgKGJ5dGUpIDB4N0EsIChieXRlKSAweDRBLCAoYnl0ZSkgMHhGMywgKGJ5dGUpIDB4M0MsIChieXRlKSAweEQ5LCAoYnl0ZSkgMHgyQSwgKGJ5dGUpIDB4NDgsIChieXRlKSAweEZELCAoYnl0ZSkgMHgzQSwKKyAgICAgICAgKGJ5dGUpIDB4MzEsIChieXRlKSAweEZDLCAoYnl0ZSkgMHg5NywgKGJ5dGUpIDB4NTIsIChieXRlKSAweDM2LCAoYnl0ZSkgMHgyMCwgKGJ5dGUpIDB4MEUsIChieXRlKSAweDY5LCAoYnl0ZSkgMHhCNiwgKGJ5dGUpIDB4MzIsIChieXRlKSAweDhCLCAoYnl0ZSkgMHg0RSwgKGJ5dGUpIDB4REEsIChieXRlKSAweDhCLCAoYnl0ZSkgMHgwNCwgKGJ5dGUpIDB4ODgsIChieXRlKSAweEY4LAorICAgICAgICAoYnl0ZSkgMHgzMCwgKGJ5dGUpIDB4QTksIChieXRlKSAweDY1LCAoYnl0ZSkgMHg2OCwgKGJ5dGUpIDB4NDcsIChieXRlKSAweEJCLCAoYnl0ZSkgMHhBMSwgKGJ5dGUpIDB4RjYsIChieXRlKSAweEQ2LCAoYnl0ZSkgMHgxOCwgKGJ5dGUpIDB4MTEsIChieXRlKSAweDQ4LCAoYnl0ZSkgMHg4RCwgKGJ5dGUpIDB4OEYsIChieXRlKSAweDRCLCAoYnl0ZSkgMHhDMSwgKGJ5dGUpIDB4RTEsCisgICAgICAgIChieXRlKSAweEE0LCAoYnl0ZSkgMHg0MywgKGJ5dGUpIDB4ODMsIChieXRlKSAweDFGLCAoYnl0ZSkgMHg2QiwgKGJ5dGUpIDB4NkQsIChieXRlKSAweEVFLCAoYnl0ZSkgMHhBNywgKGJ5dGUpIDB4QTMsIChieXRlKSAweDVGLCAoYnl0ZSkgMHhEMiwgKGJ5dGUpIDB4OTUsIChieXRlKSAweDA5LCAoYnl0ZSkgMHhENCwgKGJ5dGUpIDB4RUEsIChieXRlKSAweDg1LCAoYnl0ZSkgMHgwQywKKyAgICAgICAgKGJ5dGUpIDB4QTUsIChieXRlKSAweEM5LCAoYnl0ZSkgMHg5MywgKGJ5dGUpIDB4Q0UsIChieXRlKSAweEMxLCAoYnl0ZSkgMHgxRCwgKGJ5dGUpIDB4MzAsIChieXRlKSAweDczLCAoYnl0ZSkgMHhBMywgKGJ5dGUpIDB4RTEsIChieXRlKSAweDY5LCAoYnl0ZSkgMHhBOCwgKGJ5dGUpIDB4MTEsIChieXRlKSAweDk4LCAoYnl0ZSkgMHg3OCwgKGJ5dGUpIDB4RjMsIChieXRlKSAweEY5LAorICAgICAgICAoYnl0ZSkgMHg4RiwgKGJ5dGUpIDB4MDQgICAgfTsKKworCisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBIYXNoTWFwPFN0cmluZywgS2V5U3BlYz4ga2V5cyA9IG5ldyBIYXNoTWFwPFN0cmluZywgS2V5U3BlYz4oKTsKKyAgICBzdGF0aWMgeworICAgICAgICBrZXlzLnB1dCgiREhfcHVibGljIiwgbmV3IFg1MDlFbmNvZGVkS2V5U3BlYyhESF9wdWJsaWMpKTsKKyAgICAgICAga2V5cy5wdXQoIkRIX3ByaXZhdGUiLCBuZXcgUEtDUzhFbmNvZGVkS2V5U3BlYyhESF9wcml2YXRlKSk7CisgICAgICAgIGtleXMucHV0KCJEU0FfcHVibGljIiwgbmV3IFg1MDlFbmNvZGVkS2V5U3BlYyhEU0FfcHVibGljKSk7CisgICAgICAgIGtleXMucHV0KCJEU0FfcHJpdmF0ZSIsIG5ldyBQS0NTOEVuY29kZWRLZXlTcGVjKERTQV9wcml2YXRlKSk7CisgICAgICAgIGtleXMucHV0KCJSU0FfcHVibGljIiwgbmV3IFg1MDlFbmNvZGVkS2V5U3BlYyhSU0FfcHVibGljKSk7CisgICAgICAgIGtleXMucHV0KCJSU0FfcHJpdmF0ZSIsIG5ldyBQS0NTOEVuY29kZWRLZXlTcGVjKFJTQV9wcml2YXRlKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBQcml2YXRlS2V5IGdldFByaXZhdGVLZXkoU3RyaW5nIGFsZ29yaXRobU5hbWUpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgeworICAgICAgICBLZXlGYWN0b3J5IGZhY3RvcnkgPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKGFsZ29yaXRobU5hbWUpOworICAgICAgICByZXR1cm4gZmFjdG9yeS5nZW5lcmF0ZVByaXZhdGUoa2V5cy5nZXQoYWxnb3JpdGhtTmFtZSArICJfcHJpdmF0ZSIpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFB1YmxpY0tleSBnZXRQdWJsaWNLZXkoU3RyaW5nIGFsZ29yaXRobU5hbWUpIHRocm93cyBOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24sIEludmFsaWRLZXlTcGVjRXhjZXB0aW9uCisgICAgeworICAgICAgICBLZXlGYWN0b3J5IGZhY3RvcnkgPSBLZXlGYWN0b3J5LmdldEluc3RhbmNlKGFsZ29yaXRobU5hbWUpOworICAgICAgICByZXR1cm4gZmFjdG9yeS5nZW5lcmF0ZVB1YmxpYyhrZXlzLmdldChhbGdvcml0aG1OYW1lICsgIl9wdWJsaWMiKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0tleUFncmVlbWVudEhlbHBlci5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0tleUFncmVlbWVudEhlbHBlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU3NTkzYzUKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvS2V5QWdyZWVtZW50SGVscGVyLmphdmEKQEAgLTAsMCArMSw2NCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eTsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuSW52YWxpZEtleUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2YXRlS2V5OworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHVibGljS2V5OworaW1wb3J0IGphdmF4LmNyeXB0by5LZXlBZ3JlZW1lbnQ7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydDsKKworcHVibGljIGNsYXNzIEtleUFncmVlbWVudEhlbHBlciBleHRlbmRzIFRlc3RIZWxwZXI8S2V5UGFpcj4geworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgYWxnb3JpdGhtTmFtZTsKKworICAgIHB1YmxpYyBLZXlBZ3JlZW1lbnRIZWxwZXIoU3RyaW5nIGFsZ29yaXRobU5hbWUpIHsKKyAgICAgICAgdGhpcy5hbGdvcml0aG1OYW1lID0gYWxnb3JpdGhtTmFtZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIHZvaWQgdGVzdChLZXlQYWlyIGtleVBhaXIpIHsKKyAgICAgICAgdGVzdChrZXlQYWlyLmdldFByaXZhdGUoKSwga2V5UGFpci5nZXRQdWJsaWMoKSk7CisgICAgfQorCisgICAgdm9pZCB0ZXN0KFByaXZhdGVLZXkgZW5jcnlwdEtleSwgUHVibGljS2V5IGRlY3J5cHRLZXkpIHsKKworICAgICAgICBLZXlBZ3JlZW1lbnQga2V5QWdyZWVtZW50ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleUFncmVlbWVudCA9IEtleUFncmVlbWVudC5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXlBZ3JlZW1lbnQuaW5pdChlbmNyeXB0S2V5KTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBBc3NlcnQuZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleUFncmVlbWVudC5kb1BoYXNlKGRlY3J5cHRLZXksIHRydWUpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICBBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiZ2VuZXJhdGVkIHNlY3JldCBpcyBudWxsIiwga2V5QWdyZWVtZW50CisgICAgICAgICAgICAgICAgLmdlbmVyYXRlU2VjcmV0KCkpOworCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0tleUZhY3RvcnlUZXN0LmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvS2V5RmFjdG9yeVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMmY2ODdkCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0tleUZhY3RvcnlUZXN0LmphdmEKQEAgLTAsMCArMSw5NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleUZhY3Rvcnk7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LnNwZWMuSW52YWxpZEtleVNwZWNFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5zcGVjLktleVNwZWM7CitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgS2V5RmFjdG9yeVRlc3Q8UHVibGljS2V5U3BlYyBleHRlbmRzIEtleVNwZWMsIFByaXZhdGVLZXlTcGVjIGV4dGVuZHMgS2V5U3BlYz4KKyAgICAgICAgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBhbGdvcml0aG1OYW1lOworICAgIHByaXZhdGUgZmluYWwgQ2xhc3M8UHVibGljS2V5U3BlYz4gcHVibGljS2V5U3BlY0NsYXNzOworICAgIHByaXZhdGUgZmluYWwgQ2xhc3M8UHJpdmF0ZUtleVNwZWM+IHByaXZhdGVLZXlTcGVjQ2xhc3M7CisgICAgcHJpdmF0ZSBLZXlGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBwdWJsaWMgS2V5RmFjdG9yeVRlc3QoU3RyaW5nIGFsZ29yaXRobU5hbWUsCisgICAgICAgICAgICBDbGFzczxQdWJsaWNLZXlTcGVjPiBwdWJsaWNLZXlTcGVjQ2xhc3MsCisgICAgICAgICAgICBDbGFzczxQcml2YXRlS2V5U3BlYz4gcHJpdmF0ZUtleVNwZWNDbGFzcykgeworICAgICAgICB0aGlzLmFsZ29yaXRobU5hbWUgPSBhbGdvcml0aG1OYW1lOworICAgICAgICB0aGlzLnB1YmxpY0tleVNwZWNDbGFzcyA9IHB1YmxpY0tleVNwZWNDbGFzczsKKyAgICAgICAgdGhpcy5wcml2YXRlS2V5U3BlY0NsYXNzID0gcHJpdmF0ZUtleVNwZWNDbGFzczsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgICBmYWN0b3J5ID0gZ2V0RmFjdG9yeSgpOworICAgIH0KKworICAgIHByaXZhdGUgS2V5RmFjdG9yeSBnZXRGYWN0b3J5KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIEtleUZhY3RvcnkuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtTmFtZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0S2V5RmFjdG9yeSgpIHsKKyAgICAgICAgUHJpdmF0ZUtleVNwZWMgcHJpdmF0ZUtleVNwZWMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJpdmF0ZUtleVNwZWMgPSBmYWN0b3J5LmdldEtleVNwZWMoRGVmYXVsdEtleXMuZ2V0UHJpdmF0ZUtleShhbGdvcml0aG1OYW1lKSwKKyAgICAgICAgICAgICAgICAgICAgcHJpdmF0ZUtleVNwZWNDbGFzcyk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBQcml2YXRlS2V5IHByaXZhdGVLZXkgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHJpdmF0ZUtleSA9IGZhY3RvcnkuZ2VuZXJhdGVQcml2YXRlKHByaXZhdGVLZXlTcGVjKTsKKyAgICAgICAgfSBjYXRjaCAoSW52YWxpZEtleVNwZWNFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBQdWJsaWNLZXlTcGVjIHB1YmxpY0tleVNwZWMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcHVibGljS2V5U3BlYyA9IGZhY3RvcnkuZ2V0S2V5U3BlYyhEZWZhdWx0S2V5cy5nZXRQdWJsaWNLZXkoYWxnb3JpdGhtTmFtZSksCisgICAgICAgICAgICAgICAgICAgIHB1YmxpY0tleVNwZWNDbGFzcyk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKworICAgICAgICBQdWJsaWNLZXkgcHVibGljS2V5ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHB1YmxpY0tleSA9IGZhY3RvcnkuZ2VuZXJhdGVQdWJsaWMocHVibGljS2V5U3BlYyk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlTcGVjRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgY2hlY2sobmV3IEtleVBhaXIocHVibGljS2V5LCBwcml2YXRlS2V5KSk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgY2hlY2soS2V5UGFpciBrZXlQYWlyKSB7fQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0tleVBhaXJHZW5lcmF0b3JUZXN0LmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvS2V5UGFpckdlbmVyYXRvclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YWRlMGFmCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L0tleVBhaXJHZW5lcmF0b3JUZXN0LmphdmEKQEAgLTAsMCArMSw2MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LktleVBhaXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyR2VuZXJhdG9yOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGFic3RyYWN0IGNsYXNzIEtleVBhaXJHZW5lcmF0b3JUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgYWxnb3JpdGhtTmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIFRlc3RIZWxwZXI8S2V5UGFpcj4gaGVscGVyOworCisgICAgcHJpdmF0ZSBLZXlQYWlyR2VuZXJhdG9yIGdlbmVyYXRvcjsKKworICAgIHByb3RlY3RlZCBLZXlQYWlyR2VuZXJhdG9yVGVzdChTdHJpbmcgYWxnb3JpdGhtTmFtZSwgVGVzdEhlbHBlcjxLZXlQYWlyPiBoZWxwZXIpIHsKKyAgICAgICAgdGhpcy5hbGdvcml0aG1OYW1lID0gYWxnb3JpdGhtTmFtZTsKKyAgICAgICAgdGhpcy5oZWxwZXIgPSBoZWxwZXI7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgICAgZ2VuZXJhdG9yID0gZ2V0S2V5UGFpckdlbmVyYXRvcigpOworICAgIH0KKworICAgIHByaXZhdGUgS2V5UGFpckdlbmVyYXRvciBnZXRLZXlQYWlyR2VuZXJhdG9yKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIEtleVBhaXJHZW5lcmF0b3IuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtTmFtZSk7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJjYW5ub3QgZ2V0IEtleVBhaXJHZW5lcmF0b3I6ICIgKyBlKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdEtleVBhaXJHZW5lcmF0b3IoKSB0aHJvd3MgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHsKKyAgICAgICAgZ2VuZXJhdG9yLmluaXRpYWxpemUoMTAyNCk7CisKKyAgICAgICAgS2V5UGFpciBrZXlQYWlyID0gZ2VuZXJhdG9yLmdlbmVyYXRlS2V5UGFpcigpOworCisgICAgICAgIGFzc2VydE5vdE51bGwoIm5vIGtleXBhaXIgZ2VuZXJhdGVkIiwga2V5UGFpcik7CisgICAgICAgIGFzc2VydE5vdE51bGwoIm5vIHB1YmxpYyBrZXkgZ2VuZXJhdGVkIiwga2V5UGFpci5nZXRQdWJsaWMoKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoIm5vIHByaXZhdGUga2V5IGdlbmVyYXRlZCIsIGtleVBhaXIuZ2V0UHJpdmF0ZSgpKTsKKworICAgICAgICBoZWxwZXIudGVzdChrZXlQYWlyKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdFRlc3QuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9NZXNzYWdlRGlnZXN0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU0NTc2ODgKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdFRlc3QuamF2YQpAQCAtMCwwICsxLDIxNiBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGFic3RyYWN0IGNsYXNzIE1lc3NhZ2VEaWdlc3RUZXN0IGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBTdHJpbmcgZGlnZXN0QWxnb3JpdGhtTmFtZTsKKworICAgIHByb3RlY3RlZCBNZXNzYWdlRGlnZXN0VGVzdChTdHJpbmcgZGlnZXN0QWxnb3JpdGhtTmFtZSkgeworICAgICAgICBzdXBlcigpOworICAgICAgICB0aGlzLmRpZ2VzdEFsZ29yaXRobU5hbWUgPSBkaWdlc3RBbGdvcml0aG1OYW1lOworICAgIH0KKworICAgIHByaXZhdGUgTWVzc2FnZURpZ2VzdCBkaWdlc3Q7CisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBzb3VyY2VEYXRhOworICAgIHByaXZhdGUgYnl0ZVtdIGNoZWNrRGlnZXN0OworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuc2V0VXAoKTsKKworICAgICAgICB0aGlzLnNvdXJjZTMgPSBnZXRMb25nTWVzc2FnZSgxMDAwMDAwKTsKKyAgICAgICAgdGhpcy5kaWdlc3QgPSBnZXRNZXNzYWdlRGlnZXN0KCk7CisgICAgICAgIHRoaXMuc291cmNlRGF0YSA9IGdldFNvdXJjZURhdGEoKTsKKyAgICAgICAgdGhpcy5jaGVja0RpZ2VzdCA9IGdldENoZWNrRGlnZXN0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKworICAgICAgICAvLyBUaGlzIGlzIGNyaXRpY2FsLiBUaGUgTWVzc2FnZURpZ2VzdCB0ZXN0cyBjb25zdW1lIGEgbG90IG9mIG1lbW9yeSBkdWUKKyAgICAgICAgLy8gdG8gdGhlIDEgTUIgYnVmZmVycyBiZWluZyBhbGxvY2F0ZWQuIFdlIG5lZWQgdG8gbWFrZSBzdXJlIGFsbCBkYXRhIGlzCisgICAgICAgIC8vIGZyZWVkIGFmdGVyIGVhY2ggdGVzdC4gT3RoZXJ3aXNlIHRoZSBBbmRyb2lkIHJ1bnRpbWUgc2ltcGx5IGRpZXMgYXQKKyAgICAgICAgLy8gc29tZSBwb2ludC4KKyAgICAgICAgc291cmNlMSA9IG51bGw7CisgICAgICAgIHNvdXJjZTIgPSBudWxsOworICAgICAgICBzb3VyY2UzID0gbnVsbDsKKworICAgICAgICBleHBlY3RlZDEgPSBudWxsOworICAgICAgICBleHBlY3RlZDIgPSBudWxsOworICAgICAgICBleHBlY3RlZDMgPSBudWxsOworCisgICAgICAgIGRpZ2VzdCA9IG51bGw7CisgICAgICAgIHNvdXJjZURhdGEuY2xvc2UoKTsKKyAgICAgICAgc291cmNlRGF0YSA9IG51bGw7CisgICAgICAgIGNoZWNrRGlnZXN0ID0gbnVsbDsKKworICAgICAgICBTeXN0ZW0uZ2MoKTsKKyAgICB9CisKKyAgICBNZXNzYWdlRGlnZXN0IGdldE1lc3NhZ2VEaWdlc3QoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShkaWdlc3RBbGdvcml0aG1OYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoImZhaWxlZCB0byBnZXQgZGlnZXN0IGluc3RhbmNlOiAiICsgZSk7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIElucHV0U3RyZWFtIGdldFNvdXJjZURhdGEoKSB7CisgICAgICAgIElucHV0U3RyZWFtIHNvdXJjZVN0cmVhbSA9IGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbShkaWdlc3RBbGdvcml0aG1OYW1lICsgIi5kYXRhIik7CisgICAgICAgIGFzc2VydE5vdE51bGwoImRpZ2VzdCBzb3VyY2UgZGF0YSBub3QgZm91bmQ6ICIgKyBkaWdlc3RBbGdvcml0aG1OYW1lLCBzb3VyY2VTdHJlYW0pOworICAgICAgICByZXR1cm4gc291cmNlU3RyZWFtOworICAgIH0KKworICAgIGJ5dGVbXSBnZXRDaGVja0RpZ2VzdCgpIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gY2hlY2tEaWdlc3RTdHJlYW0gPQorICAgICAgICAgICAgICAgIGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbShkaWdlc3RBbGdvcml0aG1OYW1lICsgIi5jaGVjayIpOworICAgICAgICBieXRlW10gY2hlY2tEaWdlc3QgPSBuZXcgYnl0ZVtkaWdlc3QuZ2V0RGlnZXN0TGVuZ3RoKCldOworICAgICAgICBpbnQgcmVhZCA9IDA7CisgICAgICAgIGludCBpbmRleCA9IDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB3aGlsZSAoKHJlYWQgPSBjaGVja0RpZ2VzdFN0cmVhbS5yZWFkKCkpICE9IC0xKSB7CisgICAgICAgICAgICAgICAgY2hlY2tEaWdlc3RbaW5kZXgrK10gPSAoYnl0ZSlyZWFkOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2hlY2tEaWdlc3RTdHJlYW0uY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiZmFpbGVkIHRvIHJlYWQgZGlnZXN0IGdvbGRlbiBkYXRhOiAiICsgZGlnZXN0QWxnb3JpdGhtTmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNoZWNrRGlnZXN0OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNZXNzYWdlRGlnZXN0MSgpIHsKKyAgICAgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzEyOF07CisgICAgICAgIGludCByZWFkID0gMDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdoaWxlICgocmVhZCA9IHNvdXJjZURhdGEucmVhZChidWYpKSAhPSAtMSkgeworICAgICAgICAgICAgICAgIGRpZ2VzdC51cGRhdGUoYnVmLCAwLCByZWFkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNvdXJjZURhdGEuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiZmFpbGVkIHRvIHJlYWQgZGlnZXN0IGRhdGEiKTsKKyAgICAgICAgfQorCisgICAgICAgIGJ5dGVbXSBjb21wdXRlZERpZ2VzdCA9IGRpZ2VzdC5kaWdlc3QoKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKCJjb21wdXRlZCBkaWdlc3QgaXMgaXMgbnVsbCIsIGNvbXB1dGVkRGlnZXN0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJkaWdlc3QgbGVuZ3RoIG1pc21hdGNoIiwgY2hlY2tEaWdlc3QubGVuZ3RoLCBjb21wdXRlZERpZ2VzdC5sZW5ndGgpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2hlY2tEaWdlc3QubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiYnl0ZSAiICsgaSArICIgb2YgY29tcHV0ZWQgYW5kIGNoZWNrIGRpZ2VzdCBkaWZmZXIiLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrRGlnZXN0W2ldLCBjb21wdXRlZERpZ2VzdFtpXSk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RNZXNzYWdlRGlnZXN0MigpIHsKKyAgICAgICAgaW50IHZhbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdoaWxlICgodmFsID0gc291cmNlRGF0YS5yZWFkKCkpICE9IC0xKSB7CisgICAgICAgICAgICAgICAgZGlnZXN0LnVwZGF0ZSgoYnl0ZSl2YWwpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc291cmNlRGF0YS5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKCJmYWlsZWQgdG8gcmVhZCBkaWdlc3QgZGF0YSIpOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZVtdIGNvbXB1dGVkRGlnZXN0ID0gZGlnZXN0LmRpZ2VzdCgpOworCisgICAgICAgIGFzc2VydE5vdE51bGwoImNvbXB1dGVkIGRpZ2VzdCBpcyBpcyBudWxsIiwgY29tcHV0ZWREaWdlc3QpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRpZ2VzdCBsZW5ndGggbWlzbWF0Y2giLCBjaGVja0RpZ2VzdC5sZW5ndGgsIGNvbXB1dGVkRGlnZXN0Lmxlbmd0aCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2hlY2tEaWdlc3QubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiYnl0ZSAiICsgaSArICIgb2YgY29tcHV0ZWQgYW5kIGNoZWNrIGRpZ2VzdCBkaWZmZXIiLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrRGlnZXN0W2ldLCBjb21wdXRlZERpZ2VzdFtpXSk7CisgICAgICAgIH0KKworICAgIH0KKworCisgICAgLyoqCisgICAgICogT2ZmaWNpYWwgRklQUzE4MC0yIHRlc3RjYXNlcworICAgICAqLworCisgICAgcHJvdGVjdGVkIFN0cmluZyBzb3VyY2UxOworICAgIHByb3RlY3RlZCBTdHJpbmcgc291cmNlMjsKKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHNvdXJjZTM7CisgICAgcHJvdGVjdGVkIFN0cmluZyBleHBlY3RlZDE7CisgICAgcHJvdGVjdGVkIFN0cmluZyBleHBlY3RlZDI7CisgICAgcHJvdGVjdGVkIFN0cmluZyBleHBlY3RlZDM7CisKKyAgICBTdHJpbmcgZ2V0TG9uZ01lc3NhZ2UoaW50IGxlbmd0aCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIHNvdXJjZUJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcihsZW5ndGgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aCAvIDEwOyBpKyspIHsKKyAgICAgICAgICAgIHNvdXJjZUJ1aWxkZXIuYXBwZW5kKCJhYWFhYWFhYWFhIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNvdXJjZUJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0ZmlwczE4MF8yX3NpbmdsZWJsb2NrKCkgeworCisgICAgICAgIGRpZ2VzdC51cGRhdGUoc291cmNlMS5nZXRCeXRlcygpLCAwLCBzb3VyY2UxLmxlbmd0aCgpKTsKKworICAgICAgICBieXRlW10gY29tcHV0ZWREaWdlc3QgPSBkaWdlc3QuZGlnZXN0KCk7CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCgiY29tcHV0ZWQgZGlnZXN0IGlzIG51bGwiLCBjb21wdXRlZERpZ2VzdCk7CisKKyAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY29tcHV0ZWREaWdlc3QubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFN0cmluZyByZXMgPSBJbnRlZ2VyLnRvSGV4U3RyaW5nKGNvbXB1dGVkRGlnZXN0W2ldICYgMHhGRik7CisgICAgICAgICAgICBzYi5hcHBlbmQoKHJlcy5sZW5ndGgoKSA9PSAxID8gIjAiIDogIiIpICsgcmVzKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoImNvbXB1dGVkIGFuZCBjaGVjayBkaWdlc3QgZGlmZmVyIiwgZXhwZWN0ZWQxLCBzYi50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0ZmlwczE4MF8yX211bHRpYmxvY2soKSB7CisKKyAgICAgICAgZGlnZXN0LnVwZGF0ZShzb3VyY2UyLmdldEJ5dGVzKCksIDAsIHNvdXJjZTIubGVuZ3RoKCkpOworCisgICAgICAgIGJ5dGVbXSBjb21wdXRlZERpZ2VzdCA9IGRpZ2VzdC5kaWdlc3QoKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKCJjb21wdXRlZCBkaWdlc3QgaXMgbnVsbCIsIGNvbXB1dGVkRGlnZXN0KTsKKworICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb21wdXRlZERpZ2VzdC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIHJlcyA9IEludGVnZXIudG9IZXhTdHJpbmcoY29tcHV0ZWREaWdlc3RbaV0gJiAweEZGKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgocmVzLmxlbmd0aCgpID09IDEgPyAiMCIgOiAiIikgKyByZXMpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiY29tcHV0ZWQgYW5kIGNoZWNrIGRpZ2VzdCBkaWZmZXIiLCBleHBlY3RlZDIsIHNiLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RmaXBzMTgwXzJfbG9uZ01lc3NhZ2UoKSB7CisKKyAgICAgICAgZGlnZXN0LnVwZGF0ZShzb3VyY2UzLmdldEJ5dGVzKCksIDAsIHNvdXJjZTMubGVuZ3RoKCkpOworCisgICAgICAgIGJ5dGVbXSBjb21wdXRlZERpZ2VzdCA9IGRpZ2VzdC5kaWdlc3QoKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKCJjb21wdXRlZCBkaWdlc3QgaXMgbnVsbCIsIGNvbXB1dGVkRGlnZXN0KTsKKworICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb21wdXRlZERpZ2VzdC5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgU3RyaW5nIHJlcyA9IEludGVnZXIudG9IZXhTdHJpbmcoY29tcHV0ZWREaWdlc3RbaV0gJiAweEZGKTsKKyAgICAgICAgICAgIHNiLmFwcGVuZCgocmVzLmxlbmd0aCgpID09IDEgPyAiMCIgOiAiIikgKyByZXMpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiY29tcHV0ZWQgYW5kIGNoZWNrIGRpZ2VzdCBkaWZmZXIiLCBleHBlY3RlZDMsIHNiLnRvU3RyaW5nKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9TaWduYXR1cmVIZWxwZXIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9TaWduYXR1cmVIZWxwZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMjllZmFkCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L1NpZ25hdHVyZUhlbHBlci5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDkgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc2VjdXJpdHk7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkludmFsaWRLZXlFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5LZXlQYWlyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmF0ZUtleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlB1YmxpY0tleTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNpZ25hdHVyZUV4Y2VwdGlvbjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0OworCitwdWJsaWMgY2xhc3MgU2lnbmF0dXJlSGVscGVyIGV4dGVuZHMgVGVzdEhlbHBlcjxLZXlQYWlyPiB7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBhbGdvcml0aG1OYW1lOworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHBsYWluRGF0YSA9ICJzb21lIGRhdGEgZG8gc2lnbiBhbmQgdmVyaWZ5IjsKKworICAgIHB1YmxpYyBTaWduYXR1cmVIZWxwZXIoU3RyaW5nIGFsZ29yaXRobU5hbWUpIHsKKyAgICAgICAgdGhpcy5hbGdvcml0aG1OYW1lID0gYWxnb3JpdGhtTmFtZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB0ZXN0KEtleVBhaXIga2V5UGFpcikgeworICAgICAgICB0ZXN0KGtleVBhaXIuZ2V0UHJpdmF0ZSgpLCBrZXlQYWlyLmdldFB1YmxpYygpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0KFByaXZhdGVLZXkgZW5jcnlwdEtleSwgUHVibGljS2V5IGRlY3J5cHRLZXkpIHsKKworICAgICAgICBTaWduYXR1cmUgc2lnbmF0dXJlID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZ25hdHVyZSA9IFNpZ25hdHVyZS5nZXRJbnN0YW5jZShhbGdvcml0aG1OYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaWduYXR1cmUuaW5pdFNpZ24oZW5jcnlwdEtleSk7CisgICAgICAgIH0gY2F0Y2ggKEludmFsaWRLZXlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgQXNzZXJ0LmZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZ25hdHVyZS51cGRhdGUocGxhaW5EYXRhLmdldEJ5dGVzKCkpOworICAgICAgICB9IGNhdGNoIChTaWduYXR1cmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgQXNzZXJ0LmZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZVtdIHNpZ25lZCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaWduZWQgPSBzaWduYXR1cmUuc2lnbigpOworICAgICAgICB9IGNhdGNoIChTaWduYXR1cmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgQXNzZXJ0LmZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNpZ25hdHVyZS5pbml0VmVyaWZ5KGRlY3J5cHRLZXkpOworICAgICAgICB9IGNhdGNoIChJbnZhbGlkS2V5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzaWduYXR1cmUudXBkYXRlKHBsYWluRGF0YS5nZXRCeXRlcygpKTsKKyAgICAgICAgfSBjYXRjaCAoU2lnbmF0dXJlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIEFzc2VydC5mYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZSgic2lnbmF0dXJlIGNvdWxkIG5vdCBiZSB2ZXJpZmllZCIsIHNpZ25hdHVyZQorICAgICAgICAgICAgICAgICAgICAudmVyaWZ5KHNpZ25lZCkpOworICAgICAgICB9IGNhdGNoIChTaWduYXR1cmVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgQXNzZXJ0LmZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3NlY3VyaXR5L1Rlc3RIZWxwZXIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9UZXN0SGVscGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWE1YzlmZAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zZWN1cml0eS9UZXN0SGVscGVyLmphdmEKQEAgLTAsMCArMSwyMSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zZWN1cml0eTsKKworcHVibGljIGFic3RyYWN0IGNsYXNzIFRlc3RIZWxwZXI8VD4geworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHRlc3QoVCB0ZXN0T2JqZWN0KTsKK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA2Yzk4NmIKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNzYgQEAKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworLyoqCisgKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiB7QGNvZGUgSW5wdXRTdHJlYW19IHRoYXQgc2hvdWxkIHNlcnZlIGFzIHRoZQorICogdW5kZXJseWluZyBzdHJlYW0gZm9yIGNsYXNzZXMgdG8gYmUgdGVzdGVkLgorICogSW4gcGFydGljdWxhciB0aGlzIGltcGxlbWVudGF0aW9uIGFsbG93cyB0byBoYXZlIElPRXhlY3B0aW9ucyB0aHJvd24gb24gZGVtYW5kLgorICogRm9yIHNpbXBsaWNpdHkgb2YgdXNlIGFuZCB1bmRlcnN0YW5kaW5nIGFsbCBmaWVsZHMgYXJlIHB1YmxpYy4KKyAqLworcHVibGljIGNsYXNzIFN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9CVUZGRVJfU0laRSA9IDMyOworCisgICAgcHVibGljIGJ5dGVbXSBidWY7CisKKyAgICBwdWJsaWMgaW50IHBvczsKKworICAgIHB1YmxpYyBpbnQgbGVuOworCisgICAgLy8gU2V0IHRvIHRydWUgd2hlbiBleGNlcHRpb24gaXMgd2FudGVkOgorICAgIHB1YmxpYyBib29sZWFuIHRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gZmFsc2U7CisKKyAgICBwdWJsaWMgU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW0oKSB7CisgICAgICAgIHRoaXMoIkJFR0lOIEJsYSBibGEsIHNvbWUgdGV4dC4uLkVORCIpOworICAgIH0KKworICAgIHB1YmxpYyBTdXBwb3J0X0FTaW1wbGVJbnB1dFN0cmVhbShib29sZWFuIHRocm93RXhjZXB0aW9uKSB7CisgICAgICAgIHRoaXMoKTsKKyAgICAgICAgdGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0aHJvd0V4Y2VwdGlvbjsKKyAgICB9CisKKyAgICBwdWJsaWMgU3VwcG9ydF9BU2ltcGxlSW5wdXRTdHJlYW0oU3RyaW5nIGlucHV0KSB7CisgICAgICAgIGJ1ZiA9IGlucHV0LmdldEJ5dGVzKCk7CisgICAgICAgIHBvcyA9IDA7CisgICAgICAgIGxlbiA9IGJ1Zi5sZW5ndGg7CisgICAgfQorCisgICAgcHVibGljIFN1cHBvcnRfQVNpbXBsZUlucHV0U3RyZWFtKGJ5dGVbXSBpbnB1dCkgeworICAgICAgICBwb3MgPSAwOworICAgICAgICBsZW4gPSBpbnB1dC5sZW5ndGg7CisgICAgICAgIGJ1ZiA9IG5ldyBieXRlW2xlbl07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoaW5wdXQsIDAsIGJ1ZiwgMCwgbGVuKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJFeGNlcHRpb24gdGhyb3duIGZvciB0ZXN0aW5nIHB1cnBvc2UuIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJFeGNlcHRpb24gdGhyb3duIGZvciB0ZXN0aW5nIHB1cnBvc2UuIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGxlbiAtIHBvczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGhyb3dFeGNlcHRpb25Pbk5leHRVc2UpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRXhjZXB0aW9uIHRocm93biBmb3IgdGVzdGluZyBwdXJwb3NlLiIpOworICAgICAgICB9CisgICAgICAgIGlmIChwb3MgPCBsZW4pIHsKKyAgICAgICAgICAgIGludCByZXMgPSBidWZbcG9zXTsKKyAgICAgICAgICAgIHBvcysrOworICAgICAgICAgICAgcmV0dXJuIHJlczsKKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9BU2ltcGxlT3V0cHV0U3RyZWFtLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0FTaW1wbGVPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MGQ4NWJlCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9BU2ltcGxlT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw5OSBAQAorcGFja2FnZSB0ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworLyoqCisgKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiB7QGNvZGUgT3V0cHV0U3RyZWFtfSB0aGF0IHNob3VsZCBzZXJ2ZSBhcyB0aGUKKyAqIHVuZGVybHlpbmcgc3RyZWFtIGZvciBjbGFzc2VzIHRvIGJlIHRlc3RlZC4KKyAqIEluIHBhcnRpY3VsYXIgdGhpcyBpbXBsZW1lbnRhdGlvbiBhbGxvd3MgdG8gaGF2ZSBJT0V4ZWNwdGlvbnMgdGhyb3duIG9uIGRlbWFuZC4KKyAqIEZvciBzaW1wbGljaXR5IG9mIHVzZSBhbmQgdW5kZXJzdGFuZGluZyBhbGwgZmllbGRzIGFyZSBwdWJsaWMuCisgKi8KK3B1YmxpYyBjbGFzcyBTdXBwb3J0X0FTaW1wbGVPdXRwdXRTdHJlYW0gZXh0ZW5kcyBPdXRwdXRTdHJlYW0geworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9CVUZGRVJfU0laRSA9IDMyOworCisgICAgcHVibGljIGJ5dGVbXSBidWY7CisKKyAgICBwdWJsaWMgaW50IHBvczsKKworICAgIHB1YmxpYyBpbnQgc2l6ZTsKKworICAgIC8vIFNldCB0byB0cnVlIHdoZW4gZXhjZXB0aW9uIGlzIHdhbnRlZDoKKyAgICBwdWJsaWMgYm9vbGVhbiB0aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IGZhbHNlOworCisgICAgcHVibGljIFN1cHBvcnRfQVNpbXBsZU91dHB1dFN0cmVhbSgpIHsKKyAgICAgICAgdGhpcyhERUZBVUxUX0JVRkZFUl9TSVpFKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3VwcG9ydF9BU2ltcGxlT3V0cHV0U3RyZWFtKGJvb2xlYW4gdGhyb3dFeGNlcHRpb24pIHsKKyAgICAgICAgdGhpcyhERUZBVUxUX0JVRkZFUl9TSVpFKTsKKyAgICAgICAgdGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0aHJvd0V4Y2VwdGlvbjsKKyAgICB9CisKKyAgICBwdWJsaWMgU3VwcG9ydF9BU2ltcGxlT3V0cHV0U3RyZWFtKGludCBidWZmZXJTaXplKSB7CisgICAgICAgIGJ1ZiA9IG5ldyBieXRlW2J1ZmZlclNpemVdOworICAgICAgICBwb3MgPSAwOworICAgICAgICBzaXplID0gYnVmZmVyU2l6ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJFeGNlcHRpb24gdGhyb3duIGZvciB0ZXN0aW5nIHB1cnBvc2UuIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJFeGNlcHRpb24gdGhyb3duIGZvciB0ZXN0aW5nIHB1cnBvc2UuIik7CisgICAgICAgIH0KKyAgICB9CisKKy8vICAgIEBPdmVycmlkZQorLy8gICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZSBidWZmZXJbXSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKy8vICAgICAgICBpZiAodGhyb3dFeGNlcHRpb25Pbk5leHRVc2UpIHsKKy8vICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJFeGNlcHRpb24gdGhyb3duIGZvciB0ZXN0aW5nIHB1cnBvc2VzLiIpOworLy8gICAgICAgIH0KKy8vICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ1ZmZlci5sZW5ndGg7IGkrKykgeworLy8gICAgICAgICAgICB3cml0ZShidWZmZXJbaV0pOworLy8gICAgICAgIH0KKy8vICAgIH0KKy8vCisvLyAgICBAT3ZlcnJpZGUKKy8vICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGUgYnVmZmVyW10sIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKy8vICAgICAgICBpZiAodGhyb3dFeGNlcHRpb25Pbk5leHRVc2UpIHsKKy8vICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJFeGNlcHRpb24gdGhyb3duIGZvciB0ZXN0aW5nIHB1cnBvc2VzLiIpOworLy8gICAgICAgIH0KKy8vICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBjb3VudCA8IDAgfHwgKG9mZnNldCArIGNvdW50KSA+IGJ1ZmZlci5sZW5ndGgpIHsKKy8vICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKy8vICAgICAgICB9CisvLyAgICAgICAgZm9yIChpbnQgaSA9IG9mZnNldDsgaSA8IG9mZnNldCArIGNvdW50OyBpKyspIHsKKy8vICAgICAgICAgICAgd3JpdGUoYnVmZmVyW2ldKTsKKy8vICAgICAgICB9CisvLyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgb25lQnl0ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRocm93RXhjZXB0aW9uT25OZXh0VXNlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkV4Y2VwdGlvbiB0aHJvd24gZm9yIHRlc3RpbmcgcHVycG9zZS4iKTsKKyAgICAgICAgfQorICAgICAgICBpZiAocG9zIDwgc2l6ZSkgeworICAgICAgICAgICAgYnVmW3Bvc10gPSAoYnl0ZSkob25lQnl0ZSAmIDI1NSk7CisgICAgICAgICAgICBwb3MrKzsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW50ZXJuYWwgYnVmZmVyIG92ZXJmbG93LiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSB0b0J5dGVBcnJheSgpIHsKKyAgICAgICAgYnl0ZVtdIHRvUmV0dXJuID0gbmV3IGJ5dGVbcG9zXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWYsIDAsIHRvUmV0dXJuLCAwLCBwb3MpOworICAgICAgICByZXR1cm4gdG9SZXR1cm47CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoYnVmLCAwLCBwb3MpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfQVNpbXBsZVJlYWRlci5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9BU2ltcGxlUmVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmJjYjJmZgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfQVNpbXBsZVJlYWRlci5qYXZhCkBAIC0wLDAgKzEsNzAgQEAKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CisKKy8qKgorICogQW4gaW1wbGVtZW50YXRpb24gb2Yge0Bjb2RlIFJlYWRlcn0gdGhhdCBzaG91bGQgc2VydmUgYXMgdGhlCisgKiB1bmRlcmx5aW5nIHdyaXRlciBmb3IgY2xhc3NlcyB0byBiZSB0ZXN0ZWQuCisgKiBJbiBwYXJ0aWN1bGFyIHRoaXMgaW1wbGVtZW50YXRpb24gYWxsb3dzIHRvIGhhdmUgSU9FeGVjcHRpb25zIHRocm93biBvbiBkZW1hbmQuCisgKiBGb3Igc2ltcGxpY2l0eSBvZiB1c2UgYW5kIHVuZGVyc3RhbmRpbmcgYWxsIGZpZWxkcyBhcmUgcHVibGljLgorICovCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9BU2ltcGxlUmVhZGVyIGV4dGVuZHMgUmVhZGVyIHsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfQlVGRkVSX1NJWkUgPSAzMjsKKworICAgIHB1YmxpYyBjaGFyW10gYnVmOworCisgICAgcHVibGljIGludCBwb3M7CisKKyAgICBwdWJsaWMgaW50IGxlbjsKKworICAgIC8vIFNldCB0byB0cnVlIHdoZW4gZXhjZXB0aW9uIGlzIHdhbnRlZDoKKyAgICBwdWJsaWMgYm9vbGVhbiB0aHJvd0V4Y2VwdGlvbk9uTmV4dFVzZSA9IGZhbHNlOworCisgICAgcHVibGljIFN1cHBvcnRfQVNpbXBsZVJlYWRlcigpIHsKKyAgICAgICAgdGhpcygiQkVHSU4gQmxhIGJsYSwgc29tZSB0ZXh0Li4uRU5EIik7CisgICAgfQorCisgICAgcHVibGljIFN1cHBvcnRfQVNpbXBsZVJlYWRlcihib29sZWFuIHRocm93RXhjZXB0aW9uKSB7CisgICAgICAgIHRoaXMoKTsKKyAgICAgICAgdGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSB0aHJvd0V4Y2VwdGlvbjsKKyAgICB9CisKKyAgICBwdWJsaWMgU3VwcG9ydF9BU2ltcGxlUmVhZGVyKFN0cmluZyBpbnB1dCkgeworICAgICAgICBidWYgPSBpbnB1dC50b0NoYXJBcnJheSgpOworICAgICAgICBwb3MgPSAwOworICAgICAgICBsZW4gPSBidWYubGVuZ3RoOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRocm93RXhjZXB0aW9uT25OZXh0VXNlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkV4Y2VwdGlvbiB0aHJvd24gZm9yIHRlc3RpbmcgcHVycG9zZS4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIHJlYWR5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRocm93RXhjZXB0aW9uT25OZXh0VXNlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkV4Y2VwdGlvbiB0aHJvd24gZm9yIHRlc3RpbmcgcHVycG9zZS4iKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbGVuID4gcG9zOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChjaGFyW10gZGVzdCwgaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGhyb3dFeGNlcHRpb25Pbk5leHRVc2UpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRXhjZXB0aW9uIHRocm93biBmb3IgdGVzdGluZyBwdXJwb3NlLiIpOworICAgICAgICB9CisgICAgICAgIGludCBhdmFpbGFibGUgPSBsZW4gLSBwb3M7CisgICAgICAgIGlmIChhdmFpbGFibGUgPiAwKSB7CisgICAgICAgICAgICBpbnQgcmVhZGFibGUgPSAoYXZhaWxhYmxlIDwgY291bnQgPyBhdmFpbGFibGUgOiBjb3VudCk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZiwgcG9zLCBkZXN0LCBvZmZzZXQsIHJlYWRhYmxlKTsKKyAgICAgICAgICAgIHBvcyArPSByZWFkYWJsZTsKKyAgICAgICAgICAgIHJldHVybiByZWFkYWJsZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfQVNpbXBsZVdyaXRlci5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9BU2ltcGxlV3JpdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWY2NmY0NAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfQVNpbXBsZVdyaXRlci5qYXZhCkBAIC0wLDAgKzEsODAgQEAKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5Xcml0ZXI7CisKKy8qKgorICogQW4gaW1wbGVtZW50YXRpb24gb2Yge0Bjb2RlIE91dHB1dFN0cmVhbX0gdGhhdCBzaG91bGQgc2VydmUgYXMgdGhlCisgKiB1bmRlcmx5aW5nIHN0cmVhbSBmb3IgY2xhc3NlcyB0byBiZSB0ZXN0ZWQuCisgKiBJbiBwYXJ0aWN1bGFyIHRoaXMgaW1wbGVtZW50YXRpb24gYWxsb3dzIHRvIGhhdmUgSU9FeGVjcHRpb25zIHRocm93biBvbiBkZW1hbmQuCisgKiBGb3Igc2ltcGxpY2l0eSBvZiB1c2UgYW5kIHVuZGVyc3RhbmRpbmcgYWxsIGZpZWxkcyBhcmUgcHVibGljLgorICovCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9BU2ltcGxlV3JpdGVyIGV4dGVuZHMgV3JpdGVyIHsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfQlVGRkVSX1NJWkUgPSAzMjsKKworICAgIHB1YmxpYyBjaGFyW10gYnVmOworCisgICAgcHVibGljIGludCBwb3M7CisKKyAgICBwdWJsaWMgaW50IHNpemU7CisKKyAgICAvLyBTZXQgdG8gdHJ1ZSB3aGVuIGV4Y2VwdGlvbiBpcyB3YW50ZWQ6CisgICAgcHVibGljIGJvb2xlYW4gdGhyb3dFeGNlcHRpb25Pbk5leHRVc2UgPSBmYWxzZTsKKworICAgIHB1YmxpYyBTdXBwb3J0X0FTaW1wbGVXcml0ZXIoKSB7CisgICAgICAgIHRoaXMoREVGQVVMVF9CVUZGRVJfU0laRSk7CisgICAgfQorCisgICAgcHVibGljIFN1cHBvcnRfQVNpbXBsZVdyaXRlcihib29sZWFuIHRocm93RXhjZXB0aW9uKSB7CisgICAgICAgIHRoaXMoREVGQVVMVF9CVUZGRVJfU0laRSk7CisgICAgICAgIHRocm93RXhjZXB0aW9uT25OZXh0VXNlID0gdGhyb3dFeGNlcHRpb247CisgICAgfQorCisgICAgcHVibGljIFN1cHBvcnRfQVNpbXBsZVdyaXRlcihpbnQgYnVmZmVyU2l6ZSkgeworICAgICAgICBidWYgPSBuZXcgY2hhcltidWZmZXJTaXplXTsKKyAgICAgICAgcG9zID0gMDsKKyAgICAgICAgc2l6ZSA9IGJ1ZmZlclNpemU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGhyb3dFeGNlcHRpb25Pbk5leHRVc2UpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRXhjZXB0aW9uIHRocm93biBmb3IgdGVzdGluZyBwdXJwb3NlLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGhyb3dFeGNlcHRpb25Pbk5leHRVc2UpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRXhjZXB0aW9uIHRocm93biBmb3IgdGVzdGluZyBwdXJwb3NlLiIpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoY2hhcltdIHNyYywgaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGhyb3dFeGNlcHRpb25Pbk5leHRVc2UpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRXhjZXB0aW9uIHRocm93biBmb3IgdGVzdGluZyBwdXJwb3NlLiIpOworICAgICAgICB9CisgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IGNvdW50IDwgMCB8fCAob2Zmc2V0ICsgY291bnQpID4gYnVmLmxlbmd0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzcmMsIG9mZnNldCwgYnVmLCBwb3MsIGNvdW50KTsKKyAgICAgICAgICAgIHBvcyArPSBjb3VudDsKKyAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBwb3MgPSBzaXplOworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbnRlcm5hbCBCdWZmZXIgT3ZlcmZsb3ciKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gdG9CeXRlQXJyYXkoKSB7CisgICAgICAgIGJ5dGVbXSB0b1JldHVybiA9IG5ldyBieXRlW3Bvc107CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCAwLCB0b1JldHVybiwgMCwgcG9zKTsKKyAgICAgICAgcmV0dXJuIHRvUmV0dXJuOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGJ1ZiwgMCwgcG9zKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0NsYXNzTG9hZGVyLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0NsYXNzTG9hZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2JhMWQ3ZQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfQ2xhc3NMb2FkZXIuamF2YQpAQCAtMCwwICsxLDg0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5uZXQuVVJMQ2xhc3NMb2FkZXI7CisKK2ltcG9ydCBkYWx2aWsuc3lzdGVtLkRleENsYXNzTG9hZGVyOworCisvKioKKyAqIFN1cHBvcnQgY2xhc3MgZm9yIGNyZWF0aW5nIGEgZmlsZS1iYXNlZCBDbGFzc0xvYWRlci4gRGVsZWdhdGVzIHRvIGVpdGhlcgorICogRGFsdmlrJ3MgUGF0aENsYXNzTG9hZGVyIG9yIHRoZSBSSSdzIFVSTENsYXNzTG9hZGVyLCBidXQgZG9lcyBzbyBieS1uYW1lLgorICogVGhpcyBhbGxvd3MgdXMgdG8gcnVuIGNvcnJlc3BvbmRpbmcgdGVzdHMgaW4gYm90aCBlbnZpcm9ubWVudHMuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTdXBwb3J0X0NsYXNzTG9hZGVyIHsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBDbGFzc0xvYWRlciBnZXRDbGFzc0xvYWRlcihVUkwgdXJsLCBDbGFzc0xvYWRlciBwYXJlbnQpOworCisgICAgcHVibGljIHN0YXRpYyBDbGFzc0xvYWRlciBnZXRJbnN0YW5jZShVUkwgdXJsLCBDbGFzc0xvYWRlciBwYXJlbnQpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN1cHBvcnRfQ2xhc3NMb2FkZXIgZmFjdG9yeTsKKworICAgICAgICAgICAgaWYgKCJEYWx2aWsiLmVxdWFscyhTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEudm0ubmFtZSIpKSkgeworICAgICAgICAgICAgICAgIGZhY3RvcnkgPSAoU3VwcG9ydF9DbGFzc0xvYWRlcilDbGFzcy5mb3JOYW1lKAorICAgICAgICAgICAgICAgICAgICAidGVzdHMuc3VwcG9ydC5TdXBwb3J0X0NsYXNzTG9hZGVyJERhbHZpayIpLm5ld0luc3RhbmNlKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGZhY3RvcnkgPSAoU3VwcG9ydF9DbGFzc0xvYWRlcilDbGFzcy5mb3JOYW1lKAorICAgICAgICAgICAgICAgICAgICAidGVzdHMuc3VwcG9ydC5TdXBwb3J0X0NsYXNzTG9hZGVyJFJlZkltcGwiKS5uZXdJbnN0YW5jZSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gZmFjdG9yeS5nZXRDbGFzc0xvYWRlcih1cmwsIHBhcmVudCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuYWJsZSB0byBjcmVhdGUgQ2xhc3NMb2FkZXIiLCBleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbXBsZW1lbnRhdGlvbiBmb3IgRGFsdmlrLiBVc2VzIHRoZSBEZXhDbGFzc0xvYWRlciwgc28gd2UgY2FuIHdyaXRlCisgICAgICogdGVtcG9yYXJ5IERFWCBmaWxlcyB0byBhIHNwZWNpYWwgZGlyZWN0b3J5LiBXZSBkb24ndCB3YW50IHRvIHNwb2lsIHRoZQorICAgICAqIHN5c3RlbSdzIERFWCBjYWNoZSB3aXRoIG91ciBmaWxlcy4gQWxzbywgd2UgbWlnaHQgbm90IGhhdmUgd3JpdGUgYWNjZXNzCisgICAgICogdG8gdGhlIHN5c3RlbSdzIERFWCBjYWNoZSBhdCBhbGwgKHdoaWNoIGlzIHRoZSBjYXNlIHdoZW4gd2UncmUgcnVubmluZworICAgICAqIENUUykuCisgICAgICovCisgICAgc3RhdGljIGNsYXNzIERhbHZpayBleHRlbmRzIFN1cHBvcnRfQ2xhc3NMb2FkZXIgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIEZpbGUgdG1wOworCisgICAgICAgIHN0YXRpYyB7CisgICAgICAgICAgICB0bXAgPSBuZXcgRmlsZShTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaW8udG1wZGlyIiksICJkZXgtY2FjaGUiKTsKKyAgICAgICAgICAgIHRtcC5ta2RpcnMoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgQ2xhc3NMb2FkZXIgZ2V0Q2xhc3NMb2FkZXIoVVJMIHVybCwgQ2xhc3NMb2FkZXIgcGFyZW50KSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IERleENsYXNzTG9hZGVyKHVybC5nZXRQYXRoKCksIHRtcC5nZXRBYnNvbHV0ZVBhdGgoKSwKKyAgICAgICAgICAgICAgICAgICAgbnVsbCwgcGFyZW50KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEltcGxlbWVudGF0aW9uIGZvciB0aGUgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uLiBOb3RoaW5nIGludGVyZXN0aW5nIHRvCisgICAgICogc2VlIGhlcmUuIFBsZWFzZSBnZXQgYWxvbmcuCisgICAgICovCisgICAgc3RhdGljIGNsYXNzIFJlZkltcGwgZXh0ZW5kcyBTdXBwb3J0X0NsYXNzTG9hZGVyIHsKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBDbGFzc0xvYWRlciBnZXRDbGFzc0xvYWRlcihVUkwgdXJsLCBDbGFzc0xvYWRlciBwYXJlbnQpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgVVJMQ2xhc3NMb2FkZXIobmV3IFVSTFtdIHsgdXJsIH0sIHBhcmVudCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0NvbGxlY3Rpb25UZXN0LmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0NvbGxlY3Rpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTkwYzZiOQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfQ29sbGVjdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDEwNiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5UcmVlU2V0OworCisvKioKKyAqIGphdmEudXRpbC5Db2xsZWN0aW9uCisgKi8KK3B1YmxpYyBjbGFzcyBTdXBwb3J0X0NvbGxlY3Rpb25UZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKyAgICBDb2xsZWN0aW9uPEludGVnZXI+IGNvbDsgLy8gbXVzdCBjb250YWluIHRoZSBJbnRlZ2VycyAwIHRvIDk5CisKKyAgICBwdWJsaWMgU3VwcG9ydF9Db2xsZWN0aW9uVGVzdChTdHJpbmcgcDEpIHsKKyAgICAgICAgc3VwZXIocDEpOworICAgIH0KKworICAgIHB1YmxpYyBTdXBwb3J0X0NvbGxlY3Rpb25UZXN0KFN0cmluZyBwMSwgQ29sbGVjdGlvbjxJbnRlZ2VyPiBjKSB7CisgICAgICAgIHN1cGVyKHAxKTsKKyAgICAgICAgY29sID0gYzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgeworICAgICAgICBuZXcgU3VwcG9ydF9Vbm1vZGlmaWFibGVDb2xsZWN0aW9uVGVzdCgiIiwgY29sKS5ydW5UZXN0KCk7CisKKyAgICAgICAgLy8gc2V0dXAKKyAgICAgICAgQ29sbGVjdGlvbjxJbnRlZ2VyPiBteUNvbGxlY3Rpb24gPSBuZXcgVHJlZVNldDxJbnRlZ2VyPigpOworICAgICAgICBteUNvbGxlY3Rpb24uYWRkKG5ldyBJbnRlZ2VyKDEwMSkpOworICAgICAgICBteUNvbGxlY3Rpb24uYWRkKG5ldyBJbnRlZ2VyKDEwMikpOworICAgICAgICBteUNvbGxlY3Rpb24uYWRkKG5ldyBJbnRlZ2VyKDEwMykpOworCisgICAgICAgIC8vIGFkZAorICAgICAgICBhc3NlcnRUcnVlKCJDb2xsZWN0aW9uVGVzdCAtIGEpIGFkZCBkaWQgbm90IHdvcmsiLCBjb2wuYWRkKG5ldyBJbnRlZ2VyKAorICAgICAgICAgICAgICAgIDEwMSkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29sbGVjdGlvblRlc3QgLSBiKSBhZGQgZGlkIG5vdCB3b3JrIiwgY29sCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKG5ldyBJbnRlZ2VyKDEwMSkpKTsKKworICAgICAgICAvLyByZW1vdmUKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29sbGVjdGlvblRlc3QgLSBhKSByZW1vdmUgZGlkIG5vdCB3b3JrIiwgY29sCisgICAgICAgICAgICAgICAgLnJlbW92ZShuZXcgSW50ZWdlcigxMDEpKSk7CisgICAgICAgIGFzc2VydFRydWUoIkNvbGxlY3Rpb25UZXN0IC0gYikgcmVtb3ZlIGRpZCBub3Qgd29yayIsICFjb2wKKyAgICAgICAgICAgICAgICAuY29udGFpbnMobmV3IEludGVnZXIoMTAxKSkpOworCisgICAgICAgIC8vIGFkZEFsbAorICAgICAgICBhc3NlcnRUcnVlKCJDb2xsZWN0aW9uVGVzdCAtIGEpIGFkZEFsbCBmYWlsZWQiLCBjb2wKKyAgICAgICAgICAgICAgICAuYWRkQWxsKG15Q29sbGVjdGlvbikpOworICAgICAgICBhc3NlcnRUcnVlKCJDb2xsZWN0aW9uVGVzdCAtIGIpIGFkZEFsbCBmYWlsZWQiLCBjb2wKKyAgICAgICAgICAgICAgICAuY29udGFpbnNBbGwobXlDb2xsZWN0aW9uKSk7CisKKyAgICAgICAgLy8gY29udGFpbnNBbGwKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29sbGVjdGlvblRlc3QgLSBhKSBjb250YWluc0FsbCBmYWlsZWQiLCBjb2wKKyAgICAgICAgICAgICAgICAuY29udGFpbnNBbGwobXlDb2xsZWN0aW9uKSk7CisgICAgICAgIGNvbC5yZW1vdmUobmV3IEludGVnZXIoMTAxKSk7CisgICAgICAgIGFzc2VydFRydWUoIkNvbGxlY3Rpb25UZXN0IC0gYikgY29udGFpbnNBbGwgZmFpbGVkIiwgIWNvbAorICAgICAgICAgICAgICAgIC5jb250YWluc0FsbChteUNvbGxlY3Rpb24pKTsKKworICAgICAgICAvLyByZW1vdmVBbGwKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29sbGVjdGlvblRlc3QgLSBhKSByZW1vdmVBbGwgZmFpbGVkIiwgY29sCisgICAgICAgICAgICAgICAgLnJlbW92ZUFsbChteUNvbGxlY3Rpb24pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29sbGVjdGlvblRlc3QgLSBiKSByZW1vdmVBbGwgZmFpbGVkIiwgIWNvbAorICAgICAgICAgICAgICAgIC5yZW1vdmVBbGwobXlDb2xsZWN0aW9uKSk7IC8vIHNob3VsZCBub3QgY2hhbmdlIHRoZSBjb2xsZXRpb24KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIDJuZCB0aW1lIGFyb3VuZAorICAgICAgICBhc3NlcnRUcnVlKCJDb2xsZWN0aW9uVGVzdCAtIGMpIHJlbW92ZUFsbCBmYWlsZWQiLCAhY29sCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKG5ldyBJbnRlZ2VyKDEwMikpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29sbGVjdGlvblRlc3QgLSBkKSByZW1vdmVBbGwgZmFpbGVkIiwgIWNvbAorICAgICAgICAgICAgICAgIC5jb250YWlucyhuZXcgSW50ZWdlcigxMDMpKSk7CisKKyAgICAgICAgLy8gcmV0aWFuQWxsCisgICAgICAgIGNvbC5hZGRBbGwobXlDb2xsZWN0aW9uKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29sbGVjdGlvblRlc3QgLSBhKSByZXRhaW5BbGwgZmFpbGVkIiwgY29sCisgICAgICAgICAgICAgICAgLnJldGFpbkFsbChteUNvbGxlY3Rpb24pKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29sbGVjdGlvblRlc3QgLSBiKSByZXRhaW5BbGwgZmFpbGVkIiwgIWNvbAorICAgICAgICAgICAgICAgIC5yZXRhaW5BbGwobXlDb2xsZWN0aW9uKSk7IC8vIHNob3VsZCBub3QgY2hhbmdlIHRoZSBjb2xsZXRpb24KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIDJuZCB0aW1lIGFyb3VuZAorICAgICAgICBhc3NlcnRUcnVlKCJDb2xsZWN0aW9uVGVzdCAtIGMpIHJldGFpbkFsbCBmYWlsZWQiLCBjb2wKKyAgICAgICAgICAgICAgICAuY29udGFpbnNBbGwobXlDb2xsZWN0aW9uKSk7CisgICAgICAgIGFzc2VydFRydWUoIkNvbGxlY3Rpb25UZXN0IC0gZCkgcmV0YWluQWxsIGZhaWxlZCIsICFjb2wKKyAgICAgICAgICAgICAgICAuY29udGFpbnMobmV3IEludGVnZXIoMCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29sbGVjdGlvblRlc3QgLSBlKSByZXRhaW5BbGwgZmFpbGVkIiwgIWNvbAorICAgICAgICAgICAgICAgIC5jb250YWlucyhuZXcgSW50ZWdlcig1MCkpKTsKKworICAgICAgICAvLyBjbGVhcgorICAgICAgICBjb2wuY2xlYXIoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29sbGVjdGlvblRlc3QgLSBhKSBjbGVhciBmYWlsZWQiLCBjb2wuaXNFbXB0eSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiQ29sbGVjdGlvblRlc3QgLSBiKSBjbGVhciBmYWlsZWQiLCAhY29sCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zKG5ldyBJbnRlZ2VyKDEwMSkpKTsKKworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9Db25maWd1cmF0aW9uLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0NvbmZpZ3VyYXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZWQwYmM4Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9Db25maWd1cmF0aW9uLmphdmEKQEAgLTAsMCArMSw0MzMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIHJlc3BvbnNpYmxlIGZvciBwcm92aWRpbmcgdGhlIGR5bmFtaWMgbmFtZXMgYW5kIGFkZHJlc3NlcyBmb3IKKyAqIHRoZSBqYXZhLm5ldCBjbGFzc2VzLiBUaGVyZSBhcmUgdHdvIGRpcmVjdG9yaWVzIHdoaWNoIG5lZWQgdG8gYmUgcGxhY2VkIG9uIGFuCisgKiBmdHAgc2VydmVyIGFuZCBhbiBodHRwIHNlcnZlciB3aGljaCBzaG91bGQgYWNjb21wYW55IHRoaXMgc291cmNlLiBUaGUKKyAqIGZ0cC1maWxlcyBoYXZlIHRvIGJlIHBsYWNlZCBvbiBhbiBmdHAgc2VydmVyIGFuZCBoYXZlIHRvIGJlIHRoZSByb290IG9mIGEKKyAqIHVzZXIgamNsdGVzdCB3aXRoIHBhc3N3b3JkIGpjbHBhc3MuIFRoZSB0ZXN0cmVzIGZpbGVzIG11c3QgYmUgYXZhaWxhYmxlIG9uIGFuCisgKiBIVFRQIHNlcnZlciBhbmQgdGhlIG5hbWUgYW5kIGxvY2F0aW9uIGNhbiBiZSBjb25maWd1cmVkIGJlbG93LgorICovCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9Db25maWd1cmF0aW9uIHsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIERvbWFpbkFkZHJlc3MgPSAiYXBhY2hlLm9yZyI7CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBXZWJOYW1lID0gImpjbHRlc3QuIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEhvbWVBZGRyZXNzOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgVGVzdFJlc291cmNlc0RpciA9ICIvdGVzdHJlczIzMSI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUZXN0UmVzb3VyY2VzOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgSG9tZUFkZHJlc3NSZXNwb25zZSA9ICJIVFRQLzEuMSAyMDAgT0siOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgSG9tZUFkZHJlc3NTb2Z0d2FyZSA9ICJKZXR0eSg2LjAueCkiOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgU29ja3NTZXJ2ZXJUZXN0SG9zdCA9ICJqY2x0ZXN0LmFwYWNoZS5vcmciOworCisgICAgcHVibGljIHN0YXRpYyBpbnQgU29ja3NTZXJ2ZXJUZXN0UG9ydCA9IDEwODA7CisKKyAgICAvLyBOZWVkIGFuIElQIGFkZHJlc3MgdGhhdCBkb2VzIG5vdCByZXNvbHZlIHRvIGEgaG9zdCBuYW1lCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgVW5yZXNvbHZlZElQID0gIjE5Mi4xNjguOTkuOTkiOworCisgICAgLy8gdGhlIGJ5dGVzIGZvciBhbiBhZGRyZXNzIHdoaWNoIHJlcHJlc2VudHMgYW4gYWRkcmVzcyB3aGljaCBpcyBub3QKKyAgICAvLyBvbmUgb2YgdGhlIGFkZHJlc3NlcyBmb3IgYW55IG9mIG91ciBtYWNoaW5lcyBvbiB3aGljaCB0ZXN0cyB3aWxsIHJ1bgorICAgIC8vIGl0IGlzIHVzZWQgdG8gdmVyaWZ5IHdlIGdldCB0aGUgZXhwZWN0ZWQgZXJyb3Igd2hlbiB3ZSB0cnkgdG8gYmluZAorICAgIC8vIHRvIGFuIGFkZHJlc3MgdGhhdCBpcyBub3Qgb25lIG9mIHRoZSBtYWNoaW5lcyBsb2NhbCBhZGRyZXNzZXMKKyAgICBwdWJsaWMgc3RhdGljIGJ5dGUgbm9uTG9jYWxBZGRyZXNzQnl0ZXNbXSA9IHsgMSwgMCwgMCwgMCB9OworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgSW5ldFRlc3RBZGRyZXNzID0gImxvY2FsaG9zdCI7CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBJbmV0VGVzdElQID0gIjEyNy4wLjAuMSI7CisKKyAgICAvLyBCRUdJTiBhbmRyb2lkLWFkZGVkCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gSW5ldFRlc3RBZGRyID0gezEyNywgMCwgMCwgMX07CisgICAgLy8gRU5EIGFuZHJvaWQtYWRkZWQKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIEluZXRUZXN0QWRkcmVzczIgPSAibG9jYWxob3N0IjsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIEluZXRUZXN0SVAyID0gIjEyNy4wLjAuMSI7CisKKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBJbmV0VGVzdENhZGRyID0geyA5LCAyNiwgLTU2LCAtMTExIH07CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBJUHY2R2xvYmFsQWRkcmVzc0pjbDQgPSAiMjAwMTo0ODYwOjgwMDQ6OjY3IjsgLy8gaXB2Ni5nb29nbGUuY29tCisKKyAgICAvLyBpcCBhZGRyZXNzIHRoYXQgcmVzb2x2ZXMgdG8gYSBob3N0IHRoYXQgaXMgbm90IHByZXNlbnQgb24gdGhlIGxvY2FsCisgICAgLy8gbmV0d29yaworICAgIC8vIHRoaXMgYWxsb3dzIHVzIHRvIGNoZWNrIHRoZSB0aW1lb3V0cyBmb3IgY29ubmVjdAorICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIFJlc29sdmVkTm90RXhpc3RpbmdIb3N0ID0gIjkuMjYuMTk0LjcyIjsKKworICAgIC8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZAorICAgIC8qKgorICAgICAqIEFuIGFkZHJlc3MgdGhhdCByZXNvbHZlcyB0byBtb3JlIHRoYW4gb25lIElQIGFkZHJlc3Mgc28gdGhhdCB0aGUKKyAgICAgKiBnZXRBbGxCeU5hbWUgdGVzdCBoYXMgc29tZXRoaW5nIHRvIHRlc3QuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgU3BlY2lhbEluZXRUZXN0QWRkcmVzcyA9ICJ3d3cuZ29vZ2xlLmNvbSI7CisgICAgLy8gY2hhbmdlZCBmcm9tIGpjbHRlc3RtdWx0aXBsZS5hcGFjaGUub3JnIHRvIHd3dy5nb29nbGUuY29tIHNpbmNlCisgICAgLy8gdGhlIG9sZCBhZGRyZXNzIHZhaXNoZWQgZnJvbSB0aGUgbmV0LiB3d3cuZ29vZ2xlLmNvbSBoYXMgYWxzbyBtb3JlCisgICAgLy8gdGhhbiBvbmUgYWRkcmVzc2VzIHJldHVybmVkIGZvciB0aGlzIGhvc3QgbmFtZSBhcyBuZWVkZWQgYnkgYSB0ZXN0CisgICAgLy8gRU5EIGFuZHJvaWQtY2hhbmdlZAorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdGVzdFVSTCA9ICJoYXJtb255LmFwYWNoZS5vcmciOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgaFRUUFVSTHdFeHBpcmF0aW9uID0gImh0dHA6Ly9waHB3aWtpLnNvdXJjZWZvcmdlLm5ldC9waHB3aWtpLTEuMi8iOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgaFRUUFVSTHdMYXN0TW9kaWZpZWQgPSAiaHR0cDovL3d3dy5waHAubmV0L21hbnVhbC9lbi9mdW5jdGlvbi5leHBsb2RlLnBocCI7CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBoVFRQVVJMeWFob28gPSAiaHR0cDovL25ld3MueWFob28uY29tLyI7CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBoVFRQVVJMZ29vZ2xlID0gImh0dHA6Ly93d3cuZ29vZ2xlLmNvbS9pZSI7CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0ZXN0Q29udGVudEVuY29kaW5nID0gImh0dHA6Ly93d3cuYW1hem9uLmNvbS8iOworCisgICAgcHVibGljIHN0YXRpYyBpbnQgU3BlY2lhbEluZXRUZXN0QWRkcmVzc051bWJlciA9IDQ7CisKKyAgICAvKioKKyAgICAgKiBJbmV0QWxpYXMxIGFuZCBJbmV0QWxpYXMyIG11c3QgYmUgZGlmZmVyZW50IGhvc3QgbmFtZXMgdGhhdCByZXNvbHZlIHRvCisgICAgICogdGhlIHNhbWUgSVAgYWRkcmVzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBJbmV0QWxpYXMxID0gImFsaWFzMS5hcGFjaGUub3JnIjsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIEluZXRBbGlhczIgPSAiYWxpYXMyLmFwYWNoZS5vcmciOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgRlRQVGVzdEFkZHJlc3MgPSAiamNsdGVzdDpqY2xwYXNzQGxvY2FsaG9zdCI7CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBVUkxDb25uZWN0aW9uTGFzdE1vZGlmaWVkU3RyaW5nID0gIk1vbiwgMTQgSnVuIDE5OTkgMjE6MDY6MjIgR01UIjsKKworICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBVUkxDb25uZWN0aW9uTGFzdE1vZGlmaWVkID0gOTI5Mzk0MzgyMDAwTDsKKworICAgIHB1YmxpYyBzdGF0aWMgbG9uZyBVUkxDb25uZWN0aW9uRGF0ZSA9IDkyOTEwNjg3MjAwMEw7CisKKyAgICBzdGF0aWMgSGFzaHRhYmxlPFN0cmluZywgU3RyaW5nPiBwcm9wcyA9IG51bGw7CisgICAgc3RhdGljIHsKKyAgICAgICAgbG9hZFByb3BlcnRpZXMoKTsKKyAgICAgICAgSG9tZUFkZHJlc3MgPSBXZWJOYW1lICsgRG9tYWluQWRkcmVzczsKKyAgICAgICAgVGVzdFJlc291cmNlcyA9IEhvbWVBZGRyZXNzICsgVGVzdFJlc291cmNlc0RpcjsKKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBsb2FkUHJvcGVydGllcygpIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBudWxsOworICAgICAgICBIYXNodGFibGU8U3RyaW5nLCBTdHJpbmc+IHByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIFN0cmluZz4oKTsKKworICAgICAgICBTdHJpbmcgaW5pTmFtZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgidGVzdC5pbmkuZmlsZSIsICJKQ0xBdXRvLmluaSIpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oaW5pTmFtZSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiU3VwcG9ydENvbmZpZ3VyYXRpb24ubG9hZFByb3BlcnRpZXMoKSIpOworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGUpOworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW4gPT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDbGFzczw/PiBjbCA9IENsYXNzCisgICAgICAgICAgICAgICAgICAgICAgICAuZm9yTmFtZSgiY29tLmlibS5zdXBwb3J0LlN1cHBvcnRfQ29uZmlndXJhdGlvbiIpOworICAgICAgICAgICAgICAgIGluID0gY2wuZ2V0UmVzb3VyY2VBc1N0cmVhbShpbmlOYW1lKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoaW4gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGxvYWQoaW4sIHByb3BzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGlmIChwcm9wcy5zaXplKCkgPT0gMCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIFN0cmluZyB2YWx1ZTsKKworICAgICAgICB2YWx1ZSA9IHByb3BzLmdldCgiRG9tYWluQWRkcmVzcyIpOworICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgRG9tYWluQWRkcmVzcyA9IHZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgdmFsdWUgPSBwcm9wcy5nZXQoIldlYk5hbWUiKTsKKyAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgIFdlYk5hbWUgPSB2YWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHZhbHVlID0gcHJvcHMuZ2V0KCJUZXN0UmVzb3VyY2VzRGlyIik7CisgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7CisgICAgICAgICAgICBUZXN0UmVzb3VyY2VzRGlyID0gdmFsdWU7CisgICAgICAgIH0KKyAgICAgICAgdmFsdWUgPSBwcm9wcy5nZXQoIkhvbWVBZGRyZXNzUmVzcG9uc2UiKTsKKyAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgIEhvbWVBZGRyZXNzUmVzcG9uc2UgPSB2YWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHZhbHVlID0gcHJvcHMuZ2V0KCJIb21lQWRkcmVzc1NvZnR3YXJlIik7CisgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7CisgICAgICAgICAgICBIb21lQWRkcmVzc1NvZnR3YXJlID0gdmFsdWU7CisgICAgICAgIH0KKworICAgICAgICB2YWx1ZSA9IHByb3BzLmdldCgiU29ja3NTZXJ2ZXJUZXN0SG9zdCIpOworICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgU29ja3NTZXJ2ZXJUZXN0SG9zdCA9IHZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgdmFsdWUgPSBwcm9wcy5nZXQoIlNvY2tzU2VydmVyVGVzdFBvcnQiKTsKKyAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgIFNvY2tzU2VydmVyVGVzdFBvcnQgPSBJbnRlZ2VyLnBhcnNlSW50KHZhbHVlKTsKKyAgICAgICAgfQorCisgICAgICAgIHZhbHVlID0gcHJvcHMuZ2V0KCJVbnJlc29sdmVkSVAiKTsKKyAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgIFVucmVzb2x2ZWRJUCA9IHZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgdmFsdWUgPSBwcm9wcy5nZXQoIkluZXRUZXN0QWRkcmVzcyIpOworICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgSW5ldFRlc3RBZGRyZXNzID0gdmFsdWU7CisgICAgICAgIH0KKworICAgICAgICB2YWx1ZSA9IHByb3BzLmdldCgiSW5ldFRlc3RJUCIpOworICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgSW5ldFRlc3RJUCA9IHZhbHVlOworICAgICAgICAgICAgYnl0ZVtdIGFkZHIgPSBuZXcgYnl0ZVs0XTsKKyAgICAgICAgICAgIGludCBsYXN0ID0gMDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAzOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGRvdCA9IEluZXRUZXN0SVAuaW5kZXhPZignLicsIGxhc3QpOworICAgICAgICAgICAgICAgICAgICBhZGRyW2ldID0gKGJ5dGUpIEludGVnZXIucGFyc2VJbnQoSW5ldFRlc3RJUC5zdWJzdHJpbmcoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdCwgZG90KSk7CisgICAgICAgICAgICAgICAgICAgIGxhc3QgPSBkb3QgKyAxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhZGRyWzNdID0gKGJ5dGUpIEludGVnZXIucGFyc2VJbnQoSW5ldFRlc3RJUC5zdWJzdHJpbmcobGFzdCkpOworICAgICAgICAgICAgICAgIEluZXRUZXN0Q2FkZHIgPSBhZGRyOworICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFcnJvciBwYXJzaW5nIEluZXRUZXN0SVAgKCIgKyBJbmV0VGVzdElQCisgICAgICAgICAgICAgICAgICAgICAgICArICIpIik7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdmFsdWUgPSBwcm9wcy5nZXQoIk5vbkxvY2FsQWRkcmVzc0J5dGVzIik7CisgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgbm9uTG9jYWxBZGRyZXNzQnl0ZXNTdHJpbmcgPSB2YWx1ZTsKKyAgICAgICAgICAgIGJ5dGVbXSBhZGRyID0gbmV3IGJ5dGVbNF07CisgICAgICAgICAgICBpbnQgbGFzdCA9IDA7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGludCBkb3QgPSBub25Mb2NhbEFkZHJlc3NCeXRlc1N0cmluZy5pbmRleE9mKCcuJywgbGFzdCk7CisgICAgICAgICAgICAgICAgICAgIGFkZHJbaV0gPSAoYnl0ZSkgSW50ZWdlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wYXJzZUludChub25Mb2NhbEFkZHJlc3NCeXRlc1N0cmluZy5zdWJzdHJpbmcoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0LCBkb3QpKTsKKyAgICAgICAgICAgICAgICAgICAgbGFzdCA9IGRvdCArIDE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFkZHJbM10gPSAoYnl0ZSkgSW50ZWdlci5wYXJzZUludChub25Mb2NhbEFkZHJlc3NCeXRlc1N0cmluZworICAgICAgICAgICAgICAgICAgICAgICAgLnN1YnN0cmluZyhsYXN0KSk7CisgICAgICAgICAgICAgICAgbm9uTG9jYWxBZGRyZXNzQnl0ZXMgPSBhZGRyOworICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFcnJvciBwYXJzaW5nIE5vbkxvY2FsQWRkcmVzc0J5dGVzICgiCisgICAgICAgICAgICAgICAgICAgICAgICArIG5vbkxvY2FsQWRkcmVzc0J5dGVzU3RyaW5nICsgIikiKTsKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB2YWx1ZSA9IHByb3BzLmdldCgiSW5ldFRlc3RBZGRyZXNzMiIpOworICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgSW5ldFRlc3RBZGRyZXNzMiA9IHZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgdmFsdWUgPSBwcm9wcy5nZXQoIkluZXRUZXN0SVAyIik7CisgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7CisgICAgICAgICAgICBJbmV0VGVzdElQMiA9IHZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgdmFsdWUgPSBwcm9wcy5nZXQoIlNwZWNpYWxJbmV0VGVzdEFkZHJlc3MiKTsKKyAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgIFNwZWNpYWxJbmV0VGVzdEFkZHJlc3MgPSB2YWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHZhbHVlID0gcHJvcHMuZ2V0KCJTcGVjaWFsSW5ldFRlc3RBZGRyZXNzTnVtYmVyIik7CisgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7CisgICAgICAgICAgICBTcGVjaWFsSW5ldFRlc3RBZGRyZXNzTnVtYmVyID0gSW50ZWdlci5wYXJzZUludCh2YWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICB2YWx1ZSA9IHByb3BzLmdldCgiRlRQVGVzdEFkZHJlc3MiKTsKKyAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgIEZUUFRlc3RBZGRyZXNzID0gdmFsdWU7CisgICAgICAgIH0KKworICAgICAgICB2YWx1ZSA9IHByb3BzLmdldCgiVVJMQ29ubmVjdGlvbkxhc3RNb2RpZmllZFN0cmluZyIpOworICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgVVJMQ29ubmVjdGlvbkxhc3RNb2RpZmllZFN0cmluZyA9IHZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgdmFsdWUgPSBwcm9wcy5nZXQoIlVSTENvbm5lY3Rpb25MYXN0TW9kaWZpZWQiKTsKKyAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgIFVSTENvbm5lY3Rpb25MYXN0TW9kaWZpZWQgPSBMb25nLnBhcnNlTG9uZyh2YWx1ZSk7CisgICAgICAgIH0KKworICAgICAgICB2YWx1ZSA9IHByb3BzLmdldCgiVVJMQ29ubmVjdGlvbkRhdGUiKTsKKyAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgIFVSTENvbm5lY3Rpb25EYXRlID0gTG9uZy5wYXJzZUxvbmcodmFsdWUpOworICAgICAgICB9CisKKyAgICAgICAgdmFsdWUgPSBwcm9wcy5nZXQoIlJlc29sdmVkTm90RXhpc3RpbmdIb3N0Iik7CisgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7CisgICAgICAgICAgICBSZXNvbHZlZE5vdEV4aXN0aW5nSG9zdCA9IHZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgdmFsdWUgPSBwcm9wcy5nZXQoIkluZXRBbGlhczEiKTsKKyAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgIEluZXRBbGlhczEgPSB2YWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHZhbHVlID0gcHJvcHMuZ2V0KCJJbmV0QWxpYXMyIik7CisgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7CisgICAgICAgICAgICBJbmV0QWxpYXMyID0gdmFsdWU7CisgICAgICAgIH0KKworICAgICAgICB2YWx1ZSA9IHByb3BzLmdldCgiSVB2Nkdsb2JhbEFkZHJlc3NKY2w0Iik7CisgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7CisgICAgICAgICAgICBJUHY2R2xvYmFsQWRkcmVzc0pjbDQgPSB2YWx1ZTsKKyAgICAgICAgfQorCisgICAgfQorCisgICAgc3RhdGljIHZvaWQgbG9hZChJbnB1dFN0cmVhbSBpbiwgSGFzaHRhYmxlPFN0cmluZywgU3RyaW5nPiByZXN1bHQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBOT05FID0gMCwgU0xBU0ggPSAxLCBVTklDT0RFID0gMiwgQ09OVElOVUUgPSAzLCBET05FID0gNCwgSUdOT1JFID0gNTsKKyAgICAgICAgaW50IG1vZGUgPSBOT05FLCB1bmljb2RlID0gMCwgY291bnQgPSAwLCBuZXh0Q2hhcjsKKyAgICAgICAgU3RyaW5nQnVmZmVyIGtleSA9IG5ldyBTdHJpbmdCdWZmZXIoKSwgdmFsdWUgPSBuZXcgU3RyaW5nQnVmZmVyKCksIGJ1ZmZlciA9IGtleTsKKyAgICAgICAgYm9vbGVhbiBmaXJzdENoYXIgPSB0cnVlOworCisgICAgICAgIHdoaWxlICgobmV4dENoYXIgPSBpbi5yZWFkKCkpICE9IC0xKSB7CisgICAgICAgICAgICBpZiAobW9kZSA9PSBVTklDT0RFKSB7CisgICAgICAgICAgICAgICAgaW50IGRpZ2l0ID0gQ2hhcmFjdGVyLmRpZ2l0KChjaGFyKSBuZXh0Q2hhciwgMTYpOworICAgICAgICAgICAgICAgIGlmIChkaWdpdCA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHVuaWNvZGUgPSAodW5pY29kZSA8PCA0KSArIGRpZ2l0OworICAgICAgICAgICAgICAgICAgICBpZiAoKytjb3VudCA8IDQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG1vZGUgPSBOT05FOworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoKGNoYXIpIHVuaWNvZGUpOworICAgICAgICAgICAgICAgIGlmIChuZXh0Q2hhciAhPSAnXG4nKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChtb2RlID09IFNMQVNIKSB7CisgICAgICAgICAgICAgICAgbW9kZSA9IE5PTkU7CisgICAgICAgICAgICAgICAgc3dpdGNoIChuZXh0Q2hhcikgeworICAgICAgICAgICAgICAgIGNhc2UgJ1xyJzoKKyAgICAgICAgICAgICAgICAgICAgbW9kZSA9IENPTlRJTlVFOyAvLyBMb29rIGZvciBhIGZvbGxvd2luZyBcbgorICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICBjYXNlICdcbic6CisgICAgICAgICAgICAgICAgICAgIG1vZGUgPSBJR05PUkU7IC8vIElnbm9yZSB3aGl0ZXNwYWNlIG9uIHRoZSBuZXh0IGxpbmUKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgY2FzZSAnYic6CisgICAgICAgICAgICAgICAgICAgIG5leHRDaGFyID0gJ1xiJzsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAnZic6CisgICAgICAgICAgICAgICAgICAgIG5leHRDaGFyID0gJ1xmJzsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAnbic6CisgICAgICAgICAgICAgICAgICAgIG5leHRDaGFyID0gJ1xuJzsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAncic6CisgICAgICAgICAgICAgICAgICAgIG5leHRDaGFyID0gJ1xyJzsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAndCc6CisgICAgICAgICAgICAgICAgICAgIG5leHRDaGFyID0gJ1x0JzsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAndSc6CisgICAgICAgICAgICAgICAgICAgIG1vZGUgPSBVTklDT0RFOworICAgICAgICAgICAgICAgICAgICB1bmljb2RlID0gY291bnQgPSAwOworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHN3aXRjaCAobmV4dENoYXIpIHsKKyAgICAgICAgICAgICAgICBjYXNlICcjJzoKKyAgICAgICAgICAgICAgICBjYXNlICchJzoKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZpcnN0Q2hhcikgeworICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChuZXh0Q2hhciA9IGluLnJlYWQoKSkgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV4dENoYXIgPT0gJ1xyJyB8fCBuZXh0Q2hhciA9PSAnXG4nKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ1xuJzoKKyAgICAgICAgICAgICAgICAgICAgaWYgKG1vZGUgPT0gQ09OVElOVUUpIHsgLy8gUGFydCBvZiBhIFxyXG4gc2VxdWVuY2UKKyAgICAgICAgICAgICAgICAgICAgICAgIG1vZGUgPSBJR05PUkU7IC8vIElnbm9yZSB3aGl0ZXNwYWNlIG9uIHRoZSBuZXh0IGxpbmUKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8vIGZhbGwgaW50byB0aGUgbmV4dCBjYXNlCisgICAgICAgICAgICAgICAgY2FzZSAnXHInOgorICAgICAgICAgICAgICAgICAgICBtb2RlID0gTk9ORTsKKyAgICAgICAgICAgICAgICAgICAgZmlyc3RDaGFyID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGtleS5sZW5ndGgoKSA+IDAgfHwgYnVmZmVyID09IHZhbHVlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucHV0KGtleS50b1N0cmluZygpLCB2YWx1ZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBrZXkuc2V0TGVuZ3RoKDApOworICAgICAgICAgICAgICAgICAgICB2YWx1ZS5zZXRMZW5ndGgoMCk7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciA9IGtleTsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgY2FzZSAnXFwnOgorICAgICAgICAgICAgICAgICAgICBtb2RlID0gU0xBU0g7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIGNhc2UgJzonOgorICAgICAgICAgICAgICAgIGNhc2UgJz0nOgorICAgICAgICAgICAgICAgICAgICBpZiAoYnVmZmVyID09IGtleSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyID0gdmFsdWU7CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY2hhciBjID0gKGNoYXIpIG5leHRDaGFyOworICAgICAgICAgICAgICAgIGlmICgoYyA+PSAweDFjICYmIGMgPD0gMHgyMCkgfHwgKGMgPj0gMHg5ICYmIGMgPD0gMHhkKSkgeworICAgICAgICAgICAgICAgICAgICBpZiAobW9kZSA9PSBDT05USU5VRSkgeworICAgICAgICAgICAgICAgICAgICAgICAgbW9kZSA9IElHTk9SRTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoYnVmZmVyLmxlbmd0aCgpID09IDAgfHwgbW9kZSA9PSBJR05PUkUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChidWZmZXIgPT0ga2V5KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBtb2RlID0gRE9ORTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChtb2RlID09IElHTk9SRSB8fCBtb2RlID09IENPTlRJTlVFKSB7CisgICAgICAgICAgICAgICAgICAgIG1vZGUgPSBOT05FOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpcnN0Q2hhciA9IGZhbHNlOworICAgICAgICAgICAgaWYgKG1vZGUgPT0gRE9ORSkgeworICAgICAgICAgICAgICAgIGJ1ZmZlciA9IHZhbHVlOworICAgICAgICAgICAgICAgIG1vZGUgPSBOT05FOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgoY2hhcikgbmV4dENoYXIpOworICAgICAgICB9CisgICAgICAgIGlmIChrZXkubGVuZ3RoKCkgPiAwIHx8IGJ1ZmZlciA9PSB2YWx1ZSkgeworICAgICAgICAgICAgcmVzdWx0LnB1dChrZXkudG9TdHJpbmcoKSwgdmFsdWUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfRGVjaW1hbEZvcm1hdC5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9EZWNpbWFsRm9ybWF0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWJhYTRjYwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfRGVjaW1hbEZvcm1hdC5qYXZhCkBAIC0wLDAgKzEsMzA0IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXQ7CitpbXBvcnQgamF2YS50ZXh0Lk51bWJlckZvcm1hdDsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKK3B1YmxpYyBjbGFzcyBTdXBwb3J0X0RlY2ltYWxGb3JtYXQgZXh0ZW5kcyBTdXBwb3J0X0Zvcm1hdCB7CisKKyAgICBwdWJsaWMgU3VwcG9ydF9EZWNpbWFsRm9ybWF0KFN0cmluZyBwMSkgeworICAgICAgICBzdXBlcihwMSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHsKKyAgICAgICAgdF9mb3JtYXRUb0NoYXJhY3Rlckl0ZXJhdG9yKCk7CisgICAgICAgIHRfZm9ybWF0X3dpdGhfRmllbGRQb3NpdGlvbigpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAgICAgbmV3IFN1cHBvcnRfRGVjaW1hbEZvcm1hdCgiIikucnVuVGVzdCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRfZm9ybWF0X3dpdGhfRmllbGRQb3NpdGlvbigpIHsKKyAgICAgICAgRGVjaW1hbEZvcm1hdCBmb3JtYXQgPSAoRGVjaW1hbEZvcm1hdCkgTnVtYmVyRm9ybWF0CisgICAgICAgICAgICAgICAgLmdldEN1cnJlbmN5SW5zdGFuY2UoTG9jYWxlLlVTKTsKKyAgICAgICAgTnVtYmVyIG51bWJlciA9IG5ldyBEb3VibGUoMTAwMDAwMDAuNzYpOworICAgICAgICBTdHJpbmcgdGV4dCA9ICIkMTAsMDAwLDAwMC43NiI7CisKKyAgICAgICAgdF9Gb3JtYXRXaXRoRmllbGQoMCwgZm9ybWF0LCBudW1iZXIsIHRleHQsIE51bWJlckZvcm1hdC5GaWVsZC5DVVJSRU5DWSwKKyAgICAgICAgICAgICAgICAwLCAxKTsKKyAgICAgICAgdF9Gb3JtYXRXaXRoRmllbGQoMSwgZm9ybWF0LCBudW1iZXIsIHRleHQsIE51bWJlckZvcm1hdC5GaWVsZC5JTlRFR0VSLAorICAgICAgICAgICAgICAgIDEsIDExKTsKKyAgICAgICAgdF9Gb3JtYXRXaXRoRmllbGQoMiwgZm9ybWF0LCBudW1iZXIsIHRleHQsCisgICAgICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLkdST1VQSU5HX1NFUEFSQVRPUiwgMywgNCk7CisgICAgICAgIHRfRm9ybWF0V2l0aEZpZWxkKDMsIGZvcm1hdCwgbnVtYmVyLCB0ZXh0LAorICAgICAgICAgICAgICAgIE51bWJlckZvcm1hdC5GaWVsZC5ERUNJTUFMX1NFUEFSQVRPUiwgMTEsIDEyKTsKKyAgICAgICAgdF9Gb3JtYXRXaXRoRmllbGQoNCwgZm9ybWF0LCBudW1iZXIsIHRleHQsIE51bWJlckZvcm1hdC5GaWVsZC5GUkFDVElPTiwKKyAgICAgICAgICAgICAgICAxMiwgMTQpOworCisgICAgICAgIC8vIHRlc3QgZmllbGRzIHRoYXQgYXJlIG5vdCBpbmNsdWRlZCBpbiB0aGUgZm9ybWF0dGVkIHRleHQKKyAgICAgICAgdF9Gb3JtYXRXaXRoRmllbGQoNSwgZm9ybWF0LCBudW1iZXIsIHRleHQsIE51bWJlckZvcm1hdC5GaWVsZC5TSUdOLCAwLAorICAgICAgICAgICAgICAgIDApOworICAgICAgICB0X0Zvcm1hdFdpdGhGaWVsZCg2LCBmb3JtYXQsIG51bWJlciwgdGV4dCwgTnVtYmVyRm9ybWF0LkZpZWxkLkVYUE9ORU5ULAorICAgICAgICAgICAgICAgIDAsIDApOworICAgICAgICB0X0Zvcm1hdFdpdGhGaWVsZCg3LCBmb3JtYXQsIG51bWJlciwgdGV4dCwKKyAgICAgICAgICAgICAgICBOdW1iZXJGb3JtYXQuRmllbGQuRVhQT05FTlRfU0lHTiwgMCwgMCk7CisgICAgICAgIHRfRm9ybWF0V2l0aEZpZWxkKDgsIGZvcm1hdCwgbnVtYmVyLCB0ZXh0LAorICAgICAgICAgICAgICAgIE51bWJlckZvcm1hdC5GaWVsZC5FWFBPTkVOVF9TWU1CT0wsIDAsIDApOworICAgICAgICB0X0Zvcm1hdFdpdGhGaWVsZCg5LCBmb3JtYXQsIG51bWJlciwgdGV4dCwgTnVtYmVyRm9ybWF0LkZpZWxkLlBFUkNFTlQsCisgICAgICAgICAgICAgICAgMCwgMCk7CisgICAgICAgIHRfRm9ybWF0V2l0aEZpZWxkKDEwLCBmb3JtYXQsIG51bWJlciwgdGV4dCwKKyAgICAgICAgICAgICAgICBOdW1iZXJGb3JtYXQuRmllbGQuUEVSTUlMTEUsIDAsIDApOworCisgICAgICAgIC8vIHRlc3QgRXhwb25lbnRpYWwKKyAgICAgICAgZm9ybWF0ID0gbmV3IERlY2ltYWxGb3JtYXQoIjAwMDAwMDAwMC4wI0UwIik7CisgICAgICAgIHRleHQgPSAiMTAwMDAwMDA3LjZFLTEiOworICAgICAgICB0X0Zvcm1hdFdpdGhGaWVsZCgxMSwgZm9ybWF0LCBudW1iZXIsIHRleHQsIE51bWJlckZvcm1hdC5GaWVsZC5JTlRFR0VSLAorICAgICAgICAgICAgICAgIDAsIDkpOworICAgICAgICB0X0Zvcm1hdFdpdGhGaWVsZCgxMiwgZm9ybWF0LCBudW1iZXIsIHRleHQsCisgICAgICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLkRFQ0lNQUxfU0VQQVJBVE9SLCA5LCAxMCk7CisgICAgICAgIHRfRm9ybWF0V2l0aEZpZWxkKDEzLCBmb3JtYXQsIG51bWJlciwgdGV4dCwKKyAgICAgICAgICAgICAgICBOdW1iZXJGb3JtYXQuRmllbGQuRlJBQ1RJT04sIDEwLCAxMSk7CisgICAgICAgIHRfRm9ybWF0V2l0aEZpZWxkKDE0LCBmb3JtYXQsIG51bWJlciwgdGV4dCwKKyAgICAgICAgICAgICAgICBOdW1iZXJGb3JtYXQuRmllbGQuRVhQT05FTlRfU1lNQk9MLCAxMSwgMTIpOworICAgICAgICB0X0Zvcm1hdFdpdGhGaWVsZCgxNSwgZm9ybWF0LCBudW1iZXIsIHRleHQsCisgICAgICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLkVYUE9ORU5UX1NJR04sIDEyLCAxMyk7CisgICAgICAgIHRfRm9ybWF0V2l0aEZpZWxkKDE2LCBmb3JtYXQsIG51bWJlciwgdGV4dCwKKyAgICAgICAgICAgICAgICBOdW1iZXJGb3JtYXQuRmllbGQuRVhQT05FTlQsIDEzLCAxNCk7CisKKyAgICAgICAgLy8gdGVzdCBmaWVsZHMgdGhhdCBhcmUgbm90IGluY2x1ZGVkIGluIHRoZSBmb3JtYXR0ZWQgdGV4dAorICAgICAgICB0X0Zvcm1hdFdpdGhGaWVsZCgxNywgZm9ybWF0LCBudW1iZXIsIHRleHQsCisgICAgICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLkdST1VQSU5HX1NFUEFSQVRPUiwgMCwgMCk7CisgICAgICAgIHRfRm9ybWF0V2l0aEZpZWxkKDE4LCBmb3JtYXQsIG51bWJlciwgdGV4dCwgTnVtYmVyRm9ybWF0LkZpZWxkLlNJR04sIDAsCisgICAgICAgICAgICAgICAgMCk7CisgICAgICAgIHRfRm9ybWF0V2l0aEZpZWxkKDE5LCBmb3JtYXQsIG51bWJlciwgdGV4dCwKKyAgICAgICAgICAgICAgICBOdW1iZXJGb3JtYXQuRmllbGQuQ1VSUkVOQ1ksIDAsIDApOworICAgICAgICB0X0Zvcm1hdFdpdGhGaWVsZCgyMCwgZm9ybWF0LCBudW1iZXIsIHRleHQsIE51bWJlckZvcm1hdC5GaWVsZC5QRVJDRU5ULAorICAgICAgICAgICAgICAgIDAsIDApOworICAgICAgICB0X0Zvcm1hdFdpdGhGaWVsZCgyMSwgZm9ybWF0LCBudW1iZXIsIHRleHQsCisgICAgICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLlBFUk1JTExFLCAwLCAwKTsKKworICAgICAgICAvLyB0ZXN0IGN1cnJlbmN5IGluc3RhbmNlIHdpdGggVFIgTG9jYWxlCisgICAgICAgIG51bWJlciA9IG5ldyBEb3VibGUoMzUwLjc2KTsKKyAgICAgICAgZm9ybWF0ID0gKERlY2ltYWxGb3JtYXQpIE51bWJlckZvcm1hdC5nZXRDdXJyZW5jeUluc3RhbmNlKG5ldyBMb2NhbGUoCisgICAgICAgICAgICAgICAgImRlIiwgIkNIIikpOworICAgICAgICB0ZXh0ID0gIlNGci4gMzUwLjc2IjsKKyAgICAgICAgdF9Gb3JtYXRXaXRoRmllbGQoMjQsIGZvcm1hdCwgbnVtYmVyLCB0ZXh0LAorICAgICAgICAgICAgICAgIE51bWJlckZvcm1hdC5GaWVsZC5DVVJSRU5DWSwgMCwgNCk7CisgICAgICAgIHRfRm9ybWF0V2l0aEZpZWxkKDIyLCBmb3JtYXQsIG51bWJlciwgdGV4dCwgTnVtYmVyRm9ybWF0LkZpZWxkLklOVEVHRVIsCisgICAgICAgICAgICAgICAgNSwgOCk7CisgICAgICAgIHRfRm9ybWF0V2l0aEZpZWxkKDIzLCBmb3JtYXQsIG51bWJlciwgdGV4dCwKKyAgICAgICAgICAgICAgICBOdW1iZXJGb3JtYXQuRmllbGQuREVDSU1BTF9TRVBBUkFUT1IsIDgsIDkpOworICAgICAgICB0X0Zvcm1hdFdpdGhGaWVsZCgyMywgZm9ybWF0LCBudW1iZXIsIHRleHQsCisgICAgICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLkZSQUNUSU9OLCA5LCAxMSk7CisKKyAgICAgICAgLy8gdGVzdCBmaWVsZHMgdGhhdCBhcmUgbm90IGluY2x1ZGVkIGluIHRoZSBmb3JtYXR0ZWQgdGV4dAorICAgICAgICB0X0Zvcm1hdFdpdGhGaWVsZCgyNSwgZm9ybWF0LCBudW1iZXIsIHRleHQsCisgICAgICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLkdST1VQSU5HX1NFUEFSQVRPUiwgMCwgMCk7CisgICAgICAgIHRfRm9ybWF0V2l0aEZpZWxkKDI3LCBmb3JtYXQsIG51bWJlciwgdGV4dCwgTnVtYmVyRm9ybWF0LkZpZWxkLlNJR04sIDAsCisgICAgICAgICAgICAgICAgMCk7CisgICAgICAgIHRfRm9ybWF0V2l0aEZpZWxkKDI4LCBmb3JtYXQsIG51bWJlciwgdGV4dCwKKyAgICAgICAgICAgICAgICBOdW1iZXJGb3JtYXQuRmllbGQuRVhQT05FTlQsIDAsIDApOworICAgICAgICB0X0Zvcm1hdFdpdGhGaWVsZCgyOSwgZm9ybWF0LCBudW1iZXIsIHRleHQsCisgICAgICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLkVYUE9ORU5UX1NJR04sIDAsIDApOworICAgICAgICB0X0Zvcm1hdFdpdGhGaWVsZCgzMCwgZm9ybWF0LCBudW1iZXIsIHRleHQsCisgICAgICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLkVYUE9ORU5UX1NZTUJPTCwgMCwgMCk7CisgICAgICAgIHRfRm9ybWF0V2l0aEZpZWxkKDMxLCBmb3JtYXQsIG51bWJlciwgdGV4dCwgTnVtYmVyRm9ybWF0LkZpZWxkLlBFUkNFTlQsCisgICAgICAgICAgICAgICAgMCwgMCk7CisgICAgICAgIHRfRm9ybWF0V2l0aEZpZWxkKDMyLCBmb3JtYXQsIG51bWJlciwgdGV4dCwKKyAgICAgICAgICAgICAgICBOdW1iZXJGb3JtYXQuRmllbGQuUEVSTUlMTEUsIDAsIDApOworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgdF9mb3JtYXRUb0NoYXJhY3Rlckl0ZXJhdG9yKCkgeworCisgICAgICAgIE51bWJlciBudW1iZXIgPSBuZXcgRG91YmxlKDM1MC43Nik7CisgICAgICAgIE51bWJlciBsb25nTnVtYmVyID0gbmV3IExvbmcoMTAwMzAwNDAwKTsKKyAgICAgICAgTnVtYmVyIHplcm9OdW1iZXIgPSBuZXcgTG9uZygwKTsKKyAgICAgICAgTnVtYmVyIG5lZ2F0aXZlTnVtYmVyID0gbmV3IERvdWJsZSgtMzUwLjc2KTsKKworICAgICAgICBMb2NhbGUgdXMgPSBMb2NhbGUuVVM7CisgICAgICAgIExvY2FsZSB0ciA9IG5ldyBMb2NhbGUoImRlIiwgIkNIIik7CisKKyAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKHVzKSkgeworICAgICAgICAgICAgLy8gbG9jYWxlIGRlcGVuZGVudCB0ZXN0LCBidWcgMTk0MzI2OQorCisgICAgICAgICAgICAvLyB0ZXN0IG51bWJlciBpbnN0YW5jZQorICAgICAgICAgICAgdF9Gb3JtYXQoMSwgbnVtYmVyLCBOdW1iZXJGb3JtYXQuZ2V0TnVtYmVySW5zdGFuY2UodXMpLAorICAgICAgICAgICAgICAgICAgICBnZXROdW1iZXJWZWN0b3JVUygpKTsKKworICAgICAgICAgICAgLy8gdGVzdCBpbnRlZ2VyIGluc3RhbmNlCisgICAgICAgICAgICB0X0Zvcm1hdCgyLCBudW1iZXIsIE51bWJlckZvcm1hdC5nZXRJbnRlZ2VySW5zdGFuY2UodXMpLAorICAgICAgICAgICAgICAgICAgICBnZXRJbnRlZ2VyVmVjdG9yVVMoKSk7CisKKyAgICAgICAgICAgIC8vIHRlc3QgcGVyY2VudCBpbnN0YW5jZQorICAgICAgICAgICAgdF9Gb3JtYXQoMywgbnVtYmVyLCBOdW1iZXJGb3JtYXQuZ2V0UGVyY2VudEluc3RhbmNlKHVzKSwKKyAgICAgICAgICAgICAgICAgICAgZ2V0UGVyY2VudFZlY3RvclVTKCkpOworCisgICAgICAgICAgICAvLyB0ZXN0IGN1cnJlbmN5IGluc3RhbmNlIHdpdGggVVMgTG9jYWxlCisgICAgICAgICAgICB0X0Zvcm1hdCg0LCBudW1iZXIsIE51bWJlckZvcm1hdC5nZXRDdXJyZW5jeUluc3RhbmNlKHVzKSwKKyAgICAgICAgICAgICAgICAgICAgZ2V0UG9zaXRpdmVDdXJyZW5jeVZlY3RvclVTKCkpOworCisgICAgICAgICAgICAvLyB0ZXN0IG5lZ2F0aXZlIGN1cnJlbmN5IGluc3RhbmNlIHdpdGggVVMgTG9jYWxlCisgICAgICAgICAgICB0X0Zvcm1hdCg1LCBuZWdhdGl2ZU51bWJlciwgTnVtYmVyRm9ybWF0LmdldEN1cnJlbmN5SW5zdGFuY2UodXMpLAorICAgICAgICAgICAgICAgICAgICBnZXROZWdhdGl2ZUN1cnJlbmN5VmVjdG9yVVMoKSk7CisKKyAgICAgICAgICAgIC8vIHRlc3QgbXVsdGlwbGUgZ3JvdXBpbmcgc2VwZXJhdG9ycworICAgICAgICAgICAgdF9Gb3JtYXQoNiwgbG9uZ051bWJlciwgTnVtYmVyRm9ybWF0LmdldE51bWJlckluc3RhbmNlKHVzKSwKKyAgICAgICAgICAgICAgICAgICAgZ2V0TnVtYmVyVmVjdG9yMlVTKCkpOworCisgICAgICAgICAgICAvLyB0ZXN0IDAKKyAgICAgICAgICAgIHRfRm9ybWF0KDcsIHplcm9OdW1iZXIsIE51bWJlckZvcm1hdC5nZXROdW1iZXJJbnN0YW5jZSh1cyksCisgICAgICAgICAgICAgICAgICAgIGdldFplcm9WZWN0b3IoKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyB0ZXN0IHBlcm1pbGxlIHBhdHRlcm4KKyAgICAgICAgRGVjaW1hbEZvcm1hdCBmb3JtYXQgPSBuZXcgRGVjaW1hbEZvcm1hdCgiIyMjMC4jI1x1MjAzMCIpOworICAgICAgICB0X0Zvcm1hdCg4LCBudW1iZXIsIGZvcm1hdCwgZ2V0UGVybWlsbGVWZWN0b3IoKSk7CisKKyAgICAgICAgLy8gdGVzdCBleHBvbmVudGlhbCBwYXR0ZXJuIHdpdGggcG9zaXRpdmUgZXhwb25lbnQKKyAgICAgICAgZm9ybWF0ID0gbmV3IERlY2ltYWxGb3JtYXQoIjAwLjAjRTAiKTsKKyAgICAgICAgdF9Gb3JtYXQoOSwgbnVtYmVyLCBmb3JtYXQsIGdldFBvc2l0aXZlRXhwb25lbnRWZWN0b3IoKSk7CisKKyAgICAgICAgLy8gdGVzdCBleHBvbmVudGlhbCBwYXR0ZXJuIHdpdGggbmVnYXRpdmUgZXhwb25lbnQKKyAgICAgICAgZm9ybWF0ID0gbmV3IERlY2ltYWxGb3JtYXQoIjAwMDAuMCNFMCIpOworICAgICAgICB0X0Zvcm1hdCgxMCwgbnVtYmVyLCBmb3JtYXQsIGdldE5lZ2F0aXZlRXhwb25lbnRWZWN0b3IoKSk7CisKKyAgICAgICAgaWYgKFN1cHBvcnRfTG9jYWxlLmlzTG9jYWxlQXZhaWxhYmxlKHRyKSkgeworICAgICAgICAgICAgLy8gdGVzdCBjdXJyZW5jeSBpbnN0YW5jZSB3aXRoIFRSIExvY2FsZQorICAgICAgICAgICAgdF9Gb3JtYXQoMTEsIG51bWJlciwgTnVtYmVyRm9ybWF0LmdldEN1cnJlbmN5SW5zdGFuY2UodHIpLAorICAgICAgICAgICAgICAgICAgICBnZXRQb3NpdGl2ZUN1cnJlbmN5VmVjdG9yQ0goKSk7CisKKyAgICAgICAgICAgIC8vIHRlc3QgbmVnYXRpdmUgY3VycmVuY3kgaW5zdGFuY2Ugd2l0aCBUUiBMb2NhbGUKKyAgICAgICAgICAgIHRfRm9ybWF0KDEyLCBuZWdhdGl2ZU51bWJlciwgTnVtYmVyRm9ybWF0LmdldEN1cnJlbmN5SW5zdGFuY2UodHIpLAorICAgICAgICAgICAgICAgICAgICBnZXROZWdhdGl2ZUN1cnJlbmN5VmVjdG9yQ0goKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBWZWN0b3I8RmllbGRDb250YWluZXI+IGdldE51bWJlclZlY3RvclVTKCkgeworICAgICAgICBWZWN0b3I8RmllbGRDb250YWluZXI+IHYgPSBuZXcgVmVjdG9yPEZpZWxkQ29udGFpbmVyPigpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoMCwgMywgTnVtYmVyRm9ybWF0LkZpZWxkLklOVEVHRVIpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDMsIDQsIE51bWJlckZvcm1hdC5GaWVsZC5ERUNJTUFMX1NFUEFSQVRPUikpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoNCwgNiwgTnVtYmVyRm9ybWF0LkZpZWxkLkZSQUNUSU9OKSk7CisgICAgICAgIHJldHVybiB2OworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFZlY3RvcjxGaWVsZENvbnRhaW5lcj4gZ2V0SW50ZWdlclZlY3RvclVTKCkgeworICAgICAgICBWZWN0b3I8RmllbGRDb250YWluZXI+IHYgPSBuZXcgVmVjdG9yPEZpZWxkQ29udGFpbmVyPigpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoMCwgMywgTnVtYmVyRm9ybWF0LkZpZWxkLklOVEVHRVIpKTsKKyAgICAgICAgcmV0dXJuIHY7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgVmVjdG9yPEZpZWxkQ29udGFpbmVyPiBnZXRQb3NpdGl2ZUN1cnJlbmN5VmVjdG9yQ0goKSB7CisgICAgICAgIFZlY3RvcjxGaWVsZENvbnRhaW5lcj4gdiA9IG5ldyBWZWN0b3I8RmllbGRDb250YWluZXI+KCk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigwLCA0LCBOdW1iZXJGb3JtYXQuRmllbGQuQ1VSUkVOQ1kpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDUsIDgsIE51bWJlckZvcm1hdC5GaWVsZC5JTlRFR0VSKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcig4LCA5LCBOdW1iZXJGb3JtYXQuRmllbGQuREVDSU1BTF9TRVBBUkFUT1IpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDksIDExLCBOdW1iZXJGb3JtYXQuRmllbGQuRlJBQ1RJT04pKTsKKyAgICAgICAgcmV0dXJuIHY7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgVmVjdG9yPEZpZWxkQ29udGFpbmVyPiBnZXROZWdhdGl2ZUN1cnJlbmN5VmVjdG9yQ0goKSB7CisgICAgICAgIFZlY3RvcjxGaWVsZENvbnRhaW5lcj4gdiA9IG5ldyBWZWN0b3I8RmllbGRDb250YWluZXI+KCk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigwLCA0LCBOdW1iZXJGb3JtYXQuRmllbGQuQ1VSUkVOQ1kpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDQsIDUsIE51bWJlckZvcm1hdC5GaWVsZC5TSUdOKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcig1LCA4LCBOdW1iZXJGb3JtYXQuRmllbGQuSU5URUdFUikpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoOCwgOSwgTnVtYmVyRm9ybWF0LkZpZWxkLkRFQ0lNQUxfU0VQQVJBVE9SKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcig5LCAxMSwgTnVtYmVyRm9ybWF0LkZpZWxkLkZSQUNUSU9OKSk7CisgICAgICAgIHJldHVybiB2OworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFZlY3RvcjxGaWVsZENvbnRhaW5lcj4gZ2V0UG9zaXRpdmVDdXJyZW5jeVZlY3RvclVTKCkgeworICAgICAgICBWZWN0b3I8RmllbGRDb250YWluZXI+IHYgPSBuZXcgVmVjdG9yPEZpZWxkQ29udGFpbmVyPigpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoMCwgMSwgTnVtYmVyRm9ybWF0LkZpZWxkLkNVUlJFTkNZKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigxLCA0LCBOdW1iZXJGb3JtYXQuRmllbGQuSU5URUdFUikpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoNCwgNSwgTnVtYmVyRm9ybWF0LkZpZWxkLkRFQ0lNQUxfU0VQQVJBVE9SKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcig1LCA3LCBOdW1iZXJGb3JtYXQuRmllbGQuRlJBQ1RJT04pKTsKKyAgICAgICAgcmV0dXJuIHY7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgVmVjdG9yPEZpZWxkQ29udGFpbmVyPiBnZXROZWdhdGl2ZUN1cnJlbmN5VmVjdG9yVVMoKSB7CisgICAgICAgIFZlY3RvcjxGaWVsZENvbnRhaW5lcj4gdiA9IG5ldyBWZWN0b3I8RmllbGRDb250YWluZXI+KCk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigxLCAyLCBOdW1iZXJGb3JtYXQuRmllbGQuQ1VSUkVOQ1kpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDIsIDUsIE51bWJlckZvcm1hdC5GaWVsZC5JTlRFR0VSKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcig1LCA2LCBOdW1iZXJGb3JtYXQuRmllbGQuREVDSU1BTF9TRVBBUkFUT1IpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDYsIDgsIE51bWJlckZvcm1hdC5GaWVsZC5GUkFDVElPTikpOworICAgICAgICByZXR1cm4gdjsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBWZWN0b3I8RmllbGRDb250YWluZXI+IGdldFBlcmNlbnRWZWN0b3JVUygpIHsKKyAgICAgICAgVmVjdG9yPEZpZWxkQ29udGFpbmVyPiB2ID0gbmV3IFZlY3RvcjxGaWVsZENvbnRhaW5lcj4oKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDAsIDIsIE51bWJlckZvcm1hdC5GaWVsZC5JTlRFR0VSKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigyLCAzLCBOdW1iZXJGb3JtYXQuRmllbGQuSU5URUdFUikpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoMiwgMywgTnVtYmVyRm9ybWF0LkZpZWxkLkdST1VQSU5HX1NFUEFSQVRPUikpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoMywgNiwgTnVtYmVyRm9ybWF0LkZpZWxkLklOVEVHRVIpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDYsIDcsIE51bWJlckZvcm1hdC5GaWVsZC5QRVJDRU5UKSk7CisgICAgICAgIHJldHVybiB2OworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFZlY3RvcjxGaWVsZENvbnRhaW5lcj4gZ2V0UGVybWlsbGVWZWN0b3IoKSB7CisgICAgICAgIFZlY3RvcjxGaWVsZENvbnRhaW5lcj4gdiA9IG5ldyBWZWN0b3I8RmllbGRDb250YWluZXI+KCk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigwLCA2LCBOdW1iZXJGb3JtYXQuRmllbGQuSU5URUdFUikpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoNiwgNywgTnVtYmVyRm9ybWF0LkZpZWxkLlBFUk1JTExFKSk7CisgICAgICAgIHJldHVybiB2OworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFZlY3RvcjxGaWVsZENvbnRhaW5lcj4gZ2V0TmVnYXRpdmVFeHBvbmVudFZlY3RvcigpIHsKKyAgICAgICAgVmVjdG9yPEZpZWxkQ29udGFpbmVyPiB2ID0gbmV3IFZlY3RvcjxGaWVsZENvbnRhaW5lcj4oKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDAsIDQsIE51bWJlckZvcm1hdC5GaWVsZC5JTlRFR0VSKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcig0LCA1LCBOdW1iZXJGb3JtYXQuRmllbGQuREVDSU1BTF9TRVBBUkFUT1IpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDUsIDYsIE51bWJlckZvcm1hdC5GaWVsZC5GUkFDVElPTikpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoNiwgNywgTnVtYmVyRm9ybWF0LkZpZWxkLkVYUE9ORU5UX1NZTUJPTCkpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoNywgOCwgTnVtYmVyRm9ybWF0LkZpZWxkLkVYUE9ORU5UX1NJR04pKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDgsIDksIE51bWJlckZvcm1hdC5GaWVsZC5FWFBPTkVOVCkpOworICAgICAgICByZXR1cm4gdjsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBWZWN0b3I8RmllbGRDb250YWluZXI+IGdldFBvc2l0aXZlRXhwb25lbnRWZWN0b3IoKSB7CisgICAgICAgIFZlY3RvcjxGaWVsZENvbnRhaW5lcj4gdiA9IG5ldyBWZWN0b3I8RmllbGRDb250YWluZXI+KCk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigwLCAyLCBOdW1iZXJGb3JtYXQuRmllbGQuSU5URUdFUikpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoMiwgMywgTnVtYmVyRm9ybWF0LkZpZWxkLkRFQ0lNQUxfU0VQQVJBVE9SKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigzLCA1LCBOdW1iZXJGb3JtYXQuRmllbGQuRlJBQ1RJT04pKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDUsIDYsIE51bWJlckZvcm1hdC5GaWVsZC5FWFBPTkVOVF9TWU1CT0wpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDYsIDcsIE51bWJlckZvcm1hdC5GaWVsZC5FWFBPTkVOVCkpOworICAgICAgICByZXR1cm4gdjsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBWZWN0b3I8RmllbGRDb250YWluZXI+IGdldE51bWJlclZlY3RvcjJVUygpIHsKKyAgICAgICAgVmVjdG9yPEZpZWxkQ29udGFpbmVyPiB2ID0gbmV3IFZlY3RvcjxGaWVsZENvbnRhaW5lcj4oKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDAsIDMsIE51bWJlckZvcm1hdC5GaWVsZC5JTlRFR0VSKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigzLCA0LCBOdW1iZXJGb3JtYXQuRmllbGQuR1JPVVBJTkdfU0VQQVJBVE9SKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigzLCA0LCBOdW1iZXJGb3JtYXQuRmllbGQuSU5URUdFUikpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoNCwgNywgTnVtYmVyRm9ybWF0LkZpZWxkLklOVEVHRVIpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDcsIDgsIE51bWJlckZvcm1hdC5GaWVsZC5HUk9VUElOR19TRVBBUkFUT1IpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDcsIDgsIE51bWJlckZvcm1hdC5GaWVsZC5JTlRFR0VSKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcig4LCAxMSwgTnVtYmVyRm9ybWF0LkZpZWxkLklOVEVHRVIpKTsKKyAgICAgICAgcmV0dXJuIHY7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgVmVjdG9yPEZpZWxkQ29udGFpbmVyPiBnZXRaZXJvVmVjdG9yKCkgeworICAgICAgICBWZWN0b3I8RmllbGRDb250YWluZXI+IHYgPSBuZXcgVmVjdG9yPEZpZWxkQ29udGFpbmVyPigpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoMCwgMSwgTnVtYmVyRm9ybWF0LkZpZWxkLklOVEVHRVIpKTsKKyAgICAgICAgcmV0dXJuIHY7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0RlbGV0ZU9uRXhpdFRlc3QuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfRGVsZXRlT25FeGl0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMzZDNhOGIKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0RlbGV0ZU9uRXhpdFRlc3QuamF2YQpAQCAtMCwwICsxLDIwIEBACitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9EZWxldGVPbkV4aXRUZXN0IHsKKworICAgIC8qKgorICAgICAqIEBwYXJhbSBhcmdzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgZmlsZTEgPSBuZXcgRmlsZShhcmdzWzBdKTsKKyAgICAgICAgRmlsZSBmaWxlMiA9IG5ldyBGaWxlKGFyZ3NbMV0pOworCisgICAgICAgIGZpbGUxLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICBmaWxlMi5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgUnVudGltZS5nZXRSdW50aW1lKCkuZXhpdCgwKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfRXhlYy5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9FeGVjLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDUwMmI5YwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfRXhlYy5qYXZhCkBAIC0wLDAgKzEsMTUyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zdXBwb3J0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydGlvbkZhaWxlZEVycm9yOworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLlJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNhbGxhYmxlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcnM7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRnV0dXJlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0OworCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9FeGVjIGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBhZ2FpbnN0RGFsdmlrCisgICAgICAgICAgICA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS52ZW5kb3IiKS5jb250YWlucygiQW5kcm9pZCIpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGJ1aWxkZXIgY29uZmlndXJlZCB3aXRoIHRoZSBhcHByb3ByaWF0ZSBWTSAoImRhbHZpa3ZtIiBvcgorICAgICAqICJqYXZhIikgYW5kIGFyZ3VtZW50cyAoYXMgc3BlY2lmaWVkIGJ5IHRoZSBzeXN0ZW0gcHJvcGVydHkKKyAgICAgKiB7QGNvZGUgaHkudGVzdC52bWFyZ3N9KS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFByb2Nlc3NCdWlsZGVyIGphdmFQcm9jZXNzQnVpbGRlcigpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvY2Vzc0J1aWxkZXIgYnVpbGRlciA9IG5ldyBQcm9jZXNzQnVpbGRlcigpOworCisgICAgICAgIC8vIGNvbnN0cnVjdCB0aGUgbmFtZSBvZiBleGVjdXRhYmxlIGZpbGUKKyAgICAgICAgYnVpbGRlci5jb21tYW5kKCkuYWRkKGFnYWluc3REYWx2aWsgPyAiZGFsdmlrdm0iIDogImphdmEiKTsKKworICAgICAgICAvLyBwYXJzZSBoeS50ZXN0LnZtYXJncyBpZiB3YXMgZ2l2ZW4KKyAgICAgICAgU3RyaW5nIHRlc3RWTUFyZ3MgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImh5LnRlc3Qudm1hcmdzIik7CisgICAgICAgIGlmICh0ZXN0Vk1BcmdzICE9IG51bGwpIHsKKyAgICAgICAgICAgIGJ1aWxkZXIuY29tbWFuZCgpLmFkZEFsbChBcnJheXMuYXNMaXN0KHRlc3RWTUFyZ3Muc3BsaXQoIlxccysiKSkpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNvbW1hbmQtbGluZSByZWFkeSBwYXRoIGZvcm1lZCBieSBqb2luaW5nIHRoZSBwYXRoIGVsZW1lbnRzCisgICAgICogd2l0aCB0aGUgc3lzdGVtIHBhdGggc2VwYXJhdG9yIGFzIGEgc2VwYXJhdG9yLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGNyZWF0ZVBhdGgoU3RyaW5nLi4uIGVsZW1lbnRzKSB7CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgZm9yIChTdHJpbmcgZWxlbWVudCA6IGVsZW1lbnRzKSB7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKEZpbGUucGF0aFNlcGFyYXRvcik7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGVsZW1lbnQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdGFydHMgdGhlIHNwZWNpZmllZCBwcm9jZXNzLCBjb2xsZWN0cyBpdHMgb3V0cHV0IGZyb20gc3RhbmRhcmQgb3V0IGFuZAorICAgICAqIHN0YW5kYXJkIGVyciwgYW5kIHJldHVybnMuIElmIHRoZSBzdHJlYW0gZW1pdHMgYW55dGhpbmcgdG8gc3RhbmRhcmQgZXJyLAorICAgICAqIGFuIEFzc2VydGlvbkZhaWxlZEVycm9yIHdpbGwgYmUgdGhyb3duLgorICAgICAqCisgICAgICogPHA+VGhpcyBtZXRob2QgYXNzdW1lcyB0aGUgdGFyZ2V0IHByb2Nlc3Mgd2lsbCBjb21wbGV0ZSB3aXRoaW4gdGhpcnR5CisgICAgICogc2Vjb25kcy4gSWYgaXQgZG9lcyBub3QsIGFuIEFzc2VydGlvbkZhaWxlZEVycm9yIHdpbGwgYmUgdGhyb3duLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGV4ZWNBbmRHZXRPdXRwdXQoUHJvY2Vzc0J1aWxkZXIgYnVpbGRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvY2VzcyBwcm9jZXNzID0gYnVpbGRlci5zdGFydCgpOworICAgICAgICBFeGVjdXRvclNlcnZpY2UgZXhlY3V0b3JTZXJ2aWNlID0gRXhlY3V0b3JzLm5ld0ZpeGVkVGhyZWFkUG9vbCgyKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEZ1dHVyZTxTdHJpbmc+IGVyckZ1dHVyZSA9IGV4ZWN1dG9yU2VydmljZS5zdWJtaXQoCisgICAgICAgICAgICAgICAgICAgIHN0cmVhbVRvU3RyaW5nQ2FsbGFibGUocHJvY2Vzcy5nZXRFcnJvclN0cmVhbSgpKSk7CisgICAgICAgICAgICBGdXR1cmU8U3RyaW5nPiBvdXRGdXR1cmUgPSBleGVjdXRvclNlcnZpY2Uuc3VibWl0KAorICAgICAgICAgICAgICAgICAgICBzdHJlYW1Ub1N0cmluZ0NhbGxhYmxlKHByb2Nlc3MuZ2V0SW5wdXRTdHJlYW0oKSkpOworCisgICAgICAgICAgICBUaHJvd2FibGUgZmFpbHVyZTsKKyAgICAgICAgICAgIFN0cmluZyBvdXQgPSAiIjsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgb3V0ID0gb3V0RnV0dXJlLmdldCgzMCwgVGltZVVuaXQuU0VDT05EUyk7CisgICAgICAgICAgICAgICAgU3RyaW5nIGVyciA9IGVyckZ1dHVyZS5nZXQoMzAsIFRpbWVVbml0LlNFQ09ORFMpOworICAgICAgICAgICAgICAgIGZhaWx1cmUgPSBlcnIubGVuZ3RoKCkgPiAwCisgICAgICAgICAgICAgICAgICAgICAgICA/IG5ldyBBc3NlcnRpb25GYWlsZWRFcnJvcigiVW5leHBlY3RlZCBlcnIgc3RyZWFtIGRhdGE6XG4iICsgZXJyKQorICAgICAgICAgICAgICAgICAgICAgICAgOiBudWxsOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBmYWlsdXJlID0gZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGZhaWx1cmUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIEFzc2VydGlvbkZhaWxlZEVycm9yIGVycm9yID0gbmV3IEFzc2VydGlvbkZhaWxlZEVycm9yKAorICAgICAgICAgICAgICAgICAgICAgICAgIkZhaWxlZCB0byBleGVjdXRlICIgKyBidWlsZGVyLmNvbW1hbmQoKSArICI7IG91dHB1dCB3YXM6XG4iICsgb3V0KTsKKyAgICAgICAgICAgICAgICBlcnJvci5pbml0Q2F1c2UoZmFpbHVyZSk7CisgICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBvdXQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBleGVjdXRvclNlcnZpY2Uuc2h1dGRvd24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFN0YXJ0cyB0aGUgcHJvY2VzcyBkZXNjcmliZWQgYnkgJ2J1aWxkZXInLCBhbmQgYXNzZXJ0cyB0aGF0IGl0IHNlZXMKKyAgICAgKiAnZXhwZWN0ZWRPdXQnIG9uIHN0ZG91dCBhbmQgJ2V4cGVjdGVkRXJyJyBvbiBzdGRlcnIuIFRpbWVzIG91dCBhZnRlcgorICAgICAqIDEwcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZXhlY0FuZENoZWNrT3V0cHV0KFByb2Nlc3NCdWlsZGVyIGJ1aWxkZXIsCisgICAgICAgICAgICBTdHJpbmcgZXhwZWN0ZWRPdXQsIFN0cmluZyBleHBlY3RlZEVycikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFByb2Nlc3MgcHJvY2VzcyA9IGJ1aWxkZXIuc3RhcnQoKTsKKyAgICAgICAgRXhlY3V0b3JTZXJ2aWNlIGV4ZWN1dG9yU2VydmljZSA9IEV4ZWN1dG9ycy5uZXdGaXhlZFRocmVhZFBvb2woMik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBGdXR1cmU8U3RyaW5nPiBlcnJGdXR1cmUgPQorICAgICAgICAgICAgICAgICAgICBleGVjdXRvclNlcnZpY2Uuc3VibWl0KHN0cmVhbVRvU3RyaW5nQ2FsbGFibGUocHJvY2Vzcy5nZXRFcnJvclN0cmVhbSgpKSk7CisgICAgICAgICAgICBGdXR1cmU8U3RyaW5nPiBvdXRGdXR1cmUgPQorICAgICAgICAgICAgICAgICAgICBleGVjdXRvclNlcnZpY2Uuc3VibWl0KHN0cmVhbVRvU3RyaW5nQ2FsbGFibGUocHJvY2Vzcy5nZXRJbnB1dFN0cmVhbSgpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWRPdXQsIG91dEZ1dHVyZS5nZXQoMTAsIFRpbWVVbml0LlNFQ09ORFMpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZEVyciwgZXJyRnV0dXJlLmdldCgxMCwgVGltZVVuaXQuU0VDT05EUykpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZXhlY3V0b3JTZXJ2aWNlLnNodXRkb3duKCk7CisgICAgICAgICAgICBwcm9jZXNzLndhaXRGb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIENhbGxhYmxlPFN0cmluZz4gc3RyZWFtVG9TdHJpbmdDYWxsYWJsZShmaW5hbCBJbnB1dFN0cmVhbSBpbikgeworICAgICAgICByZXR1cm4gbmV3IENhbGxhYmxlPFN0cmluZz4oKSB7CisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGNhbGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICBTdHJpbmdXcml0ZXIgd3JpdGVyID0gbmV3IFN0cmluZ1dyaXRlcigpOworICAgICAgICAgICAgICAgIFJlYWRlciByZWFkZXIgPSBuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaW4pOworICAgICAgICAgICAgICAgIGludCBjOworICAgICAgICAgICAgICAgIHdoaWxlICgoYyA9IHJlYWRlci5yZWFkKCkpICE9IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShjKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHdyaXRlci50b1N0cmluZygpOworICAgICAgICAgICAgfQorICAgICAgICB9OworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfRmllbGQuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfRmllbGQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNmZmNzE4Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9GaWVsZC5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK3B1YmxpYyBjbGFzcyBTdXBwb3J0X0ZpZWxkIHsKKworICAgIHByb3RlY3RlZCBPYmplY3Qgb2JqZWN0RmllbGQ7CisKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBib29sZWFuRmllbGQ7CisKKyAgICBwcm90ZWN0ZWQgYnl0ZSBieXRlRmllbGQ7CisKKyAgICBwcm90ZWN0ZWQgY2hhciBjaGFyRmllbGQ7CisKKyAgICBwcm90ZWN0ZWQgc2hvcnQgc2hvcnRGaWVsZDsKKworICAgIHByb3RlY3RlZCBpbnQgaW50RmllbGQ7CisKKyAgICBwcm90ZWN0ZWQgbG9uZyBsb25nRmllbGQ7CisKKyAgICBwcm90ZWN0ZWQgZmxvYXQgZmxvYXRGaWVsZDsKKworICAgIHByb3RlY3RlZCBkb3VibGUgZG91YmxlRmllbGQ7CisKKyAgICAvKioKKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBTdXBwb3J0X0ZpZWxkKCkgeworICAgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0Zvcm1hdC5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9Gb3JtYXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNTNhMGJhCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9Gb3JtYXQuamF2YQpAQCAtMCwwICsxLDE0MyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEudGV4dC5BdHRyaWJ1dGVkQ2hhcmFjdGVySXRlcmF0b3I7CitpbXBvcnQgamF2YS50ZXh0LkZpZWxkUG9zaXRpb247CitpbXBvcnQgamF2YS50ZXh0LkZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBTdXBwb3J0X0Zvcm1hdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIHByb3RlY3RlZCBTdHJpbmcgdGV4dDsKKworICAgIHB1YmxpYyBTdXBwb3J0X0Zvcm1hdChTdHJpbmcgcDEpIHsKKyAgICAgICAgc3VwZXIocDEpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHRfRm9ybWF0V2l0aEZpZWxkKGludCBjb3VudCwgRm9ybWF0IGZvcm1hdCwgT2JqZWN0IG9iamVjdCwKKyAgICAgICAgICAgIFN0cmluZyB0ZXh0LCBGb3JtYXQuRmllbGQgZmllbGQsIGludCBiZWdpbiwgaW50IGVuZCkgeworICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBGaWVsZFBvc2l0aW9uIHBvcyA9IG5ldyBGaWVsZFBvc2l0aW9uKGZpZWxkKTsKKyAgICAgICAgZm9ybWF0LmZvcm1hdChvYmplY3QsIGJ1ZmZlciwgcG9zKTsKKworICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oYnVmZmVyKTsKKyAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKHBvcyk7CisKKyAgICAgICAgaWYgKHRleHQgPT0gbnVsbCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0ICIgKyBjb3VudCArICI6IGluY29ycmVjdCBmb3JtYXR0ZWQgdGV4dCIsCisgICAgICAgICAgICAgICAgICAgIHRoaXMudGV4dCwgYnVmZmVyLnRvU3RyaW5nKCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJUZXN0ICIgKyBjb3VudCArICI6IGluY29ycmVjdCBmb3JtYXR0ZWQgdGV4dCIsIHRleHQsCisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAiICsgY291bnQgKyAiOiBpbmNvcnJlY3QgYmVnaW4gaW5kZXggZm9yIGZpZWxkICIKKyAgICAgICAgICAgICAgICArIGZpZWxkLCBiZWdpbiwgcG9zLmdldEJlZ2luSW5kZXgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiVGVzdCAiICsgY291bnQgKyAiOiBpbmNvcnJlY3QgZW5kIGluZGV4IGZvciBmaWVsZCIKKyAgICAgICAgICAgICAgICArIGZpZWxkLCBlbmQsIHBvcy5nZXRFbmRJbmRleCgpKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCB0X0Zvcm1hdChpbnQgY291bnQsIE9iamVjdCBvYmplY3QsIEZvcm1hdCBmb3JtYXQsCisgICAgICAgICAgICBWZWN0b3I8RmllbGRDb250YWluZXI+IGV4cGVjdGVkUmVzdWx0cykgeworICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oZm9ybWF0LmZvcm1hdChvYmplY3QpKTsKKyAgICAgICAgVmVjdG9yPEZpZWxkQ29udGFpbmVyPiByZXN1bHRzID0gZmluZEZpZWxkcyhmb3JtYXQuZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcihvYmplY3QpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVGVzdCAiICsgY291bnQKKyAgICAgICAgICAgICAgICArICI6IEZvcm1hdCByZXR1cm5lZCBpbmNvcnJlY3QgQ2hhcmFjdGVySXRlcmF0b3IgZm9yICIKKyAgICAgICAgICAgICAgICArIGZvcm1hdC5mb3JtYXQob2JqZWN0KSwgY29tcGFyZShyZXN1bHRzLCBleHBlY3RlZFJlc3VsdHMpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBjb21wYXJlcyB0d28gdmVjdG9ycyByZWdhcmRsZXNzIG9mIHRoZSBvcmRlciBvZiB0aGVpciBlbGVtZW50cworICAgICAqLworICAgIHByb3RlY3RlZCBzdGF0aWMgYm9vbGVhbiBjb21wYXJlKFZlY3RvcjxGaWVsZENvbnRhaW5lcj4gdmVjdG9yMSwgVmVjdG9yPEZpZWxkQ29udGFpbmVyPiB2ZWN0b3IyKSB7CisgICAgICAgIHJldHVybiB2ZWN0b3IxLnNpemUoKSA9PSB2ZWN0b3IyLnNpemUoKSAmJiB2ZWN0b3IxLmNvbnRhaW5zQWxsKHZlY3RvcjIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGZpbmRzIGF0dHJpYnV0ZXMgd2l0aCByZWdhcmRzIHRvIGNoYXIgaW5kZXggaW4gdGhpcworICAgICAqIEF0dHJpYnV0ZWRDaGFyYWN0ZXJJdGVyYXRvciwgYW5kIHB1dHMgdGhlbSBpbiBhIHZlY3RvcgorICAgICAqCisgICAgICogQHBhcmFtIGl0ZXJhdG9yCisgICAgICogQHJldHVybiBhIHZlY3RvciwgZWFjaCBlbnRyeSBpbiB0aGlzIHZlY3RvciBhcmUgb2YgdHlwZSBGaWVsZENvbnRhaW5lciAsCisgICAgICogICAgICAgICB3aGljaCBzdG9yZXMgc3RhcnQgYW5kIGVuZCBpbmRleGVzIGFuZCBhbiBhdHRyaWJ1dGUgdGhpcyByYW5nZQorICAgICAqICAgICAgICAgaGFzCisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBWZWN0b3I8RmllbGRDb250YWluZXI+IGZpbmRGaWVsZHMoQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yIGl0ZXJhdG9yKSB7CisgICAgICAgIFZlY3RvcjxGaWVsZENvbnRhaW5lcj4gcmVzdWx0ID0gbmV3IFZlY3RvcjxGaWVsZENvbnRhaW5lcj4oKTsKKyAgICAgICAgd2hpbGUgKGl0ZXJhdG9yLmdldEluZGV4KCkgIT0gaXRlcmF0b3IuZ2V0RW5kSW5kZXgoKSkgeworICAgICAgICAgICAgaW50IHN0YXJ0ID0gaXRlcmF0b3IuZ2V0UnVuU3RhcnQoKTsKKyAgICAgICAgICAgIGludCBlbmQgPSBpdGVyYXRvci5nZXRSdW5MaW1pdCgpOworCisgICAgICAgICAgICBJdGVyYXRvcjxBdHRyaWJ1dGU+IGl0ID0gaXRlcmF0b3IuZ2V0QXR0cmlidXRlcygpLmtleVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSBhdHRyaWJ1dGUgPSBpdC5uZXh0KCk7CisgICAgICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gaXRlcmF0b3IuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZSk7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChuZXcgRmllbGRDb250YWluZXIoc3RhcnQsIGVuZCwgYXR0cmlidXRlLCB2YWx1ZSkpOworICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihzdGFydCArICIgIiArIGVuZCArICI6ICIgKyBhdHRyaWJ1dGUgKyAiLAorICAgICAgICAgICAgICAgIC8vICIgKyB2YWx1ZSApOworICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigidi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKCIgKyBzdGFydCArIiwiICsKKyAgICAgICAgICAgICAgICAvLyBlbmQgKyIsIiArIGF0dHJpYnV0ZSsgIiwiICsgdmFsdWUrICIpKTsiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGl0ZXJhdG9yLnNldEluZGV4KGVuZCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGNsYXNzIEZpZWxkQ29udGFpbmVyIHsKKyAgICAgICAgaW50IHN0YXJ0LCBlbmQ7CisKKyAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSBhdHRyaWJ1dGU7CisKKyAgICAgICAgT2JqZWN0IHZhbHVlOworCisgICAgICAgIC8vIGNhbGxlZCBmcm9tIHN1cHBvcnRfZGVjaW1hbGZvcm1hdCBhbmQgc3VwcG9ydF9zaW1wbGVkYXRlZm9ybWF0IHRlc3RzCisgICAgICAgIHB1YmxpYyBGaWVsZENvbnRhaW5lcihpbnQgc3RhcnQsIGludCBlbmQsCisgICAgICAgICAgICAgICAgQXR0cmlidXRlZENoYXJhY3Rlckl0ZXJhdG9yLkF0dHJpYnV0ZSBhdHRyaWJ1dGUpIHsKKyAgICAgICAgICAgIHRoaXMoc3RhcnQsIGVuZCwgYXR0cmlidXRlLCBhdHRyaWJ1dGUpOworICAgICAgICB9CisKKyAgICAgICAgLy8gY2FsbGVkIGZyb20gc3VwcG9ydF9tZXNzYWdlZm9ybWF0IHRlc3RzCisgICAgICAgIHB1YmxpYyBGaWVsZENvbnRhaW5lcihpbnQgc3RhcnQsIGludCBlbmQsIEF0dHJpYnV0ZSBhdHRyaWJ1dGUsIGludCB2YWx1ZSkgeworICAgICAgICAgICAgdGhpcyhzdGFydCwgZW5kLCBhdHRyaWJ1dGUsIG5ldyBJbnRlZ2VyKHZhbHVlKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBjYWxsZWQgZnJvbSBzdXBwb3J0X21lc3NhZ2Vmb3JtYXQgdGVzdHMKKyAgICAgICAgcHVibGljIEZpZWxkQ29udGFpbmVyKGludCBzdGFydCwgaW50IGVuZCwgQXR0cmlidXRlIGF0dHJpYnV0ZSwKKyAgICAgICAgICAgICAgICBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgICAgIHRoaXMuc3RhcnQgPSBzdGFydDsKKyAgICAgICAgICAgIHRoaXMuZW5kID0gZW5kOworICAgICAgICAgICAgdGhpcy5hdHRyaWJ1dGUgPSBhdHRyaWJ1dGU7CisgICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIEZpZWxkQ29udGFpbmVyKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgRmllbGRDb250YWluZXIgZmMgPSAoRmllbGRDb250YWluZXIpIG9iajsKKyAgICAgICAgICAgIHJldHVybiAoc3RhcnQgPT0gZmMuc3RhcnQgJiYgZW5kID09IGZjLmVuZAorICAgICAgICAgICAgICAgICAgICAmJiBhdHRyaWJ1dGUgPT0gZmMuYXR0cmlidXRlICYmIHZhbHVlLmVxdWFscyhmYy52YWx1ZSkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9HZXRMb2NhbC5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9HZXRMb2NhbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIxZjFlZmQKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0dldExvY2FsLmphdmEKQEAgLTAsMCArMSwxMDEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmV0LkphclVSTENvbm5lY3Rpb247CitpbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworCitpbXBvcnQgdGVzdHMuc3VwcG9ydC5yZXNvdXJjZS5TdXBwb3J0X1Jlc291cmNlczsKKworcHVibGljIGNsYXNzIFN1cHBvcnRfR2V0TG9jYWwgeworCisgICAgc3RhdGljIEhhc2h0YWJsZTxTdHJpbmcsIEZpbGU+IGNhY2hlID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIEZpbGU+KDIwKTsKKworICAgIHB1YmxpYyBzdGF0aWMgRmlsZSBnZXRMb2NhbEZpbGUoU3RyaW5nIHVybCkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICAgICAgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKyAgICAgICAgdXJsID0gU3VwcG9ydF9SZXNvdXJjZXMuUkVTT1VSQ0VfUEFDS0FHRSArIHVybDsKKyAgICAgICAgRmlsZSB0ZW1wID0gY2FjaGUuZ2V0KHVybCk7CisgICAgICAgIGlmICh0ZW1wID09IG51bGwpIHsKKyAgICAgICAgICAgIElucHV0U3RyZWFtIGluID0gU3VwcG9ydF9HZXRMb2NhbC5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKHVybCk7CisgICAgICAgICAgICB0ZW1wID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiaHl0c19sb2NhbCIsICIudG1wIiwgbnVsbCk7CisgICAgICAgICAgICB0ZW1wLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbSh0ZW1wKTsKKyAgICAgICAgICAgIGludCByZXN1bHQ7CisgICAgICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbNDA5Nl07CisgICAgICAgICAgICB3aGlsZSAoKHJlc3VsdCA9IGluLnJlYWQoYnVmKSkgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICBvdXQud3JpdGUoYnVmLCAwLCByZXN1bHQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgY2FjaGUucHV0KHVybCwgdGVtcCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRlbXA7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBGaWxlIGdldEV4dGVybmFsTG9jYWxGaWxlKFN0cmluZyB1cmwpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgdGVtcCA9IGNhY2hlLmdldCh1cmwpOworICAgICAgICBpZiAodGVtcCA9PSBudWxsKSB7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG5ldyBVUkwodXJsKS5vcGVuU3RyZWFtKCk7CisgICAgICAgICAgICB0ZW1wID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgiaHl0c19sb2NhbCIsICIudG1wIiwgbnVsbCk7CisgICAgICAgICAgICB0ZW1wLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbSh0ZW1wKTsKKyAgICAgICAgICAgIGludCByZXN1bHQ7CisgICAgICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbNDA5Nl07CisgICAgICAgICAgICB3aGlsZSAoKHJlc3VsdCA9IGluLnJlYWQoYnVmKSkgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICBvdXQud3JpdGUoYnVmLCAwLCByZXN1bHQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW4uY2xvc2UoKTsKKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgY2FjaGUucHV0KHVybCwgdGVtcCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRlbXA7CisgICAgfQorCisgICAgc3RhdGljIEJ5dGVBcnJheUlucHV0U3RyZWFtIGdldFN0cmVhbShTdHJpbmcgdXJsKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgICAgICBNYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG5ldyBVUkwodXJsKS5vcGVuU3RyZWFtKCk7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKDI1Nik7CisgICAgICAgIGludCByZXN1bHQ7CisgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsyNTZdOworICAgICAgICB3aGlsZSAoKHJlc3VsdCA9IGluLnJlYWQoYnVmKSkgIT0gLTEpIHsKKyAgICAgICAgICAgIG91dC53cml0ZShidWYsIDAsIHJlc3VsdCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShvdXQudG9CeXRlQXJyYXkoKSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBGaWxlIGNyZWF0ZVRlbXBGaWxlKFN0cmluZyBzdWZmaXgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJoeXRzXyIsIHN1ZmZpeCwgbnVsbCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBKYXJVUkxDb25uZWN0aW9uIGdldEphclVSTENvbm5lY3Rpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBKYXJVUkxDb25uZWN0aW9uIGNvbjEgPSBudWxsOworICAgICAgICBGaWxlIGZpbGUgPSBnZXRMb2NhbEZpbGUoImh5dHNfYXR0LmphciIpOworICAgICAgICBVUkwgZlVybDEgPSBuZXcgVVJMKCJqYXI6ZmlsZToiICsgZmlsZS5nZXRQYXRoKCkgKyAiIS8iKTsKKyAgICAgICAgY29uMSA9IChKYXJVUkxDb25uZWN0aW9uKSBmVXJsMS5vcGVuQ29ubmVjdGlvbigpOworICAgICAgICByZXR1cm4gY29uMTsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9HZXRQdXRGaWVsZHMuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfR2V0UHV0RmllbGRzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2NmMGQ5MQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfR2V0UHV0RmllbGRzLmphdmEKQEAgLTAsMCArMSwxMzMgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBTdXBwb3J0IGNsYXNzIHRvIHRlc3QgdGhlIG1ldGhvZHMgb2Yge0Bjb2RlIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkfSBhbmQKKyAqIHtAY29kZSBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGR9IHRvIHdyaXRlIGZpZWxkcyB0byBhbiBvdXRwdXQgc3RyZWFtIGFuZAorICogcmVhZCB0aGVtIGJhY2sgZnJvbSBhbiBpbnB1dCBzdHJlYW0uCisgKi8KK3B1YmxpYyBjbGFzcyBTdXBwb3J0X0dldFB1dEZpZWxkcyBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKworICAgIHB1YmxpYyBPYmplY3RJbnB1dFN0cmVhbS5HZXRGaWVsZCBnZXRGaWVsZDsKKyAgICBwdWJsaWMgT2JqZWN0T3V0cHV0U3RyZWFtLlB1dEZpZWxkIHB1dEZpZWxkOworCisgICAgcHVibGljIGJvb2xlYW4gYm9vbGVhblZhbHVlID0gZmFsc2U7CisgICAgcHVibGljIGJ5dGUgYnl0ZVZhbHVlID0gMDsKKyAgICBwdWJsaWMgY2hhciBjaGFyVmFsdWUgPSAwOworICAgIHB1YmxpYyBkb3VibGUgZG91YmxlVmFsdWUgPSAwLjA7CisgICAgcHVibGljIGZsb2F0IGZsb2F0VmFsdWUgPSAwLjBmOworICAgIHB1YmxpYyBsb25nIGxvbmdWYWx1ZSA9IDA7CisgICAgcHVibGljIGludCBpbnRWYWx1ZSA9IDA7CisgICAgcHVibGljIHNob3J0IHNob3J0VmFsdWUgPSAwOworICAgIHB1YmxpYyBTaW1wbGVDbGFzcyBvYmplY3RWYWx1ZSA9IG51bGw7CisKKyAgICBjbGFzcyBTaW1wbGVDbGFzcyBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisgICAgICAgIHByaXZhdGUgaW50IGE7CisgICAgICAgIHByaXZhdGUgU3RyaW5nIGI7CisKKyAgICAgICAgcHVibGljIFNpbXBsZUNsYXNzKGludCBhVmFsdWUsIFN0cmluZyBiVmFsdWUpIHsKKyAgICAgICAgICAgIGEgPSBhVmFsdWU7CisgICAgICAgICAgICBiID0gYlZhbHVlOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGludCBnZXRBKCkgeworICAgICAgICAgICAgcmV0dXJuIGE7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEIoKSB7CisgICAgICAgICAgICByZXR1cm4gYjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgICAgICBpZiAob2JqID09IG51bGwgfHwgb2JqLmdldENsYXNzKCkgIT0gdGhpcy5nZXRDbGFzcygpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBTaW1wbGVDbGFzcyBvdGhlciA9IChTaW1wbGVDbGFzcykgb2JqOworICAgICAgICAgICAgcmV0dXJuIChhID09IG90aGVyLmdldEEoKSAmJiBiLmVxdWFscyhvdGhlci5nZXRCKCkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGluaXRUZXN0VmFsdWVzKCkgeworICAgICAgICBib29sZWFuVmFsdWUgPSB0cnVlOworICAgICAgICBieXRlVmFsdWUgPSAoYnl0ZSkgMHhiZTsKKyAgICAgICAgY2hhclZhbHVlID0gJ0InOworICAgICAgICBkb3VibGVWYWx1ZSA9IDQyNDI0Mi40MjsKKyAgICAgICAgZmxvYXRWYWx1ZSA9IDI0LjEyZjsKKyAgICAgICAgbG9uZ1ZhbHVlID0gNjcwMDY1NDMyMWw7CisgICAgICAgIGludFZhbHVlID0gNzc3Nzc7CisgICAgICAgIG9iamVjdFZhbHVlID0gbmV3IFNpbXBsZUNsYXNzKDE5NjUsICJIZWxsbyBNYXJzIik7CisgICAgICAgIHNob3J0VmFsdWUgPSAxMjM0OworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgIGlmIChvYmogPT0gbnVsbCB8fCBvYmouZ2V0Q2xhc3MoKSAhPSB0aGlzLmdldENsYXNzKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIFN1cHBvcnRfR2V0UHV0RmllbGRzIG90aGVyID0gKFN1cHBvcnRfR2V0UHV0RmllbGRzKSBvYmo7CisgICAgICAgIHJldHVybiAoYm9vbGVhblZhbHVlID09IG90aGVyLmJvb2xlYW5WYWx1ZSAmJgorICAgICAgICAgICAgICAgIGJ5dGVWYWx1ZSA9PSBvdGhlci5ieXRlVmFsdWUgJiYKKyAgICAgICAgICAgICAgICBjaGFyVmFsdWUgPT0gb3RoZXIuY2hhclZhbHVlICYmCisgICAgICAgICAgICAgICAgZG91YmxlVmFsdWUgPT0gb3RoZXIuZG91YmxlVmFsdWUgJiYKKyAgICAgICAgICAgICAgICBmbG9hdFZhbHVlID09IG90aGVyLmZsb2F0VmFsdWUgJiYKKyAgICAgICAgICAgICAgICBsb25nVmFsdWUgPT0gb3RoZXIubG9uZ1ZhbHVlICYmCisgICAgICAgICAgICAgICAgaW50VmFsdWUgPT0gb3RoZXIuaW50VmFsdWUgJiYKKyAgICAgICAgICAgICAgICBvYmplY3RWYWx1ZS5lcXVhbHMob3RoZXIub2JqZWN0VmFsdWUpICYmCisgICAgICAgICAgICAgICAgc2hvcnRWYWx1ZSA9PSBvdGhlci5zaG9ydFZhbHVlCisgICAgICAgICAgICAgICAgKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBvaXMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBnZXRGaWVsZCA9IG9pcy5yZWFkRmllbGRzKCk7CisgICAgICAgIGJvb2xlYW5WYWx1ZSA9IGdldEZpZWxkLmdldCgiYm9vbGVhblZhbHVlIiwgZmFsc2UpOworICAgICAgICBieXRlVmFsdWUgPSBnZXRGaWVsZC5nZXQoImJ5dGVWYWx1ZSIsIChieXRlKSAwKTsKKyAgICAgICAgY2hhclZhbHVlID0gZ2V0RmllbGQuZ2V0KCJjaGFyVmFsdWUiLCAoY2hhcikgMCk7CisgICAgICAgIGRvdWJsZVZhbHVlID0gZ2V0RmllbGQuZ2V0KCJkb3VibGVWYWx1ZSIsIDAuMCk7CisgICAgICAgIGZsb2F0VmFsdWUgPSBnZXRGaWVsZC5nZXQoImZsb2F0VmFsdWUiLCAwLjBmKTsKKyAgICAgICAgbG9uZ1ZhbHVlID0gZ2V0RmllbGQuZ2V0KCJsb25nVmFsdWUiLCAobG9uZykgMCk7CisgICAgICAgIGludFZhbHVlID0gZ2V0RmllbGQuZ2V0KCJpbnRWYWx1ZSIsIDApOworICAgICAgICBvYmplY3RWYWx1ZSA9IChTdXBwb3J0X0dldFB1dEZpZWxkcy5TaW1wbGVDbGFzcykKKyAgICAgICAgICAgICAgICBnZXRGaWVsZC5nZXQoIm9iamVjdFZhbHVlIiwgKE9iamVjdCkgbnVsbCk7CisgICAgICAgIHNob3J0VmFsdWUgPSBnZXRGaWVsZC5nZXQoInNob3J0VmFsdWUiLCAoc2hvcnQpIDApOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gb29zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBwdXRGaWVsZCA9IG9vcy5wdXRGaWVsZHMoKTsKKyAgICAgICAgcHV0RmllbGQucHV0KCJib29sZWFuVmFsdWUiLCBib29sZWFuVmFsdWUpOworICAgICAgICBwdXRGaWVsZC5wdXQoImJ5dGVWYWx1ZSIsIGJ5dGVWYWx1ZSk7CisgICAgICAgIHB1dEZpZWxkLnB1dCgiY2hhclZhbHVlIiwgY2hhclZhbHVlKTsKKyAgICAgICAgcHV0RmllbGQucHV0KCJkb3VibGVWYWx1ZSIsIGRvdWJsZVZhbHVlKTsKKyAgICAgICAgcHV0RmllbGQucHV0KCJmbG9hdFZhbHVlIiwgZmxvYXRWYWx1ZSk7CisgICAgICAgIHB1dEZpZWxkLnB1dCgibG9uZ1ZhbHVlIiwgbG9uZ1ZhbHVlKTsKKyAgICAgICAgcHV0RmllbGQucHV0KCJpbnRWYWx1ZSIsIGludFZhbHVlKTsKKyAgICAgICAgcHV0RmllbGQucHV0KCJvYmplY3RWYWx1ZSIsIG9iamVjdFZhbHVlKTsKKyAgICAgICAgcHV0RmllbGQucHV0KCJzaG9ydFZhbHVlIiwgc2hvcnRWYWx1ZSk7CisgICAgICAgIG9vcy53cml0ZUZpZWxkcygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfR2V0UHV0RmllbGRzRGVmYXVsdGVkLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0dldFB1dEZpZWxkc0RlZmF1bHRlZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI1Yjc0MTcKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0dldFB1dEZpZWxkc0RlZmF1bHRlZC5qYXZhCkBAIC0wLDAgKzEsMTM5IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogU3VwcG9ydCBjbGFzcyB0byB2ZXJpZnkgdGhhdCB0aGUgbWV0aG9kcyBvZgorICoge0Bjb2RlIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkfSBoYW5kbGUgZGVmYXVsdCB2YWx1ZXMgY29ycmVjdGx5LgorICogPHA+CisgKiA8c3Ryb25nPkltcG9ydGFudDo8L3N0cm9uZz4gVGhlIHRlc3QgbWV0aG9kCisgKiB7QGNvZGUgdGVzdF9kZWZhdWx0ZWRMamF2YV9sYW5nX1N0cmluZygpfSBpbgorICoge0Bjb2RlIHRlc3RzLmFwaS5qYXZhLmlvLk9iamVjdElucHV0U3RyZWFtR2V0RmllbGRUZXN0fSBkZXBlbmRzIG9uIGEKKyAqIHJlZmVyZW5jZSBmaWxlIHdoaWNoIGNhbiBiZSBnZW5lcmF0ZWQgd2l0aAorICoge0Bjb2RlIHRlc3RzLnV0aWwuRmllbGRUZXN0RmlsZUdlbmVyYXRvcn0uIEhvd2V2ZXIsIHRoZSBkZWZhdWx0IG1lY2hhbmlzbSBvZgorICoge0Bjb2RlIEdldEZpZWxkfSBvbmx5IHdvcmtzIGlmIHRoZSBmaWVsZHMgdGhhdCBhcmUgc3VwcG9zZWQgdG8gYmUgcmVhZCBoYXZlCisgKiBub3QgYmVlbiB3cml0dGVuIHRvIHRoZSBmaWxlLiBUaGlzIGNhbiBvbmx5IGJlIGFjY29tcGxpc2hlZCBpZiB0aGUgZmllbGRzIGRvCisgKiBub3QgZXhpc3QgKGFyZSBub3QgZGVjbGFyZWQpIHdoZW4gd3JpdGluZyBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLgorICogVGhlcmVmb3JlLCB3aGVuIGV4ZWN1dGluZyB7QGNvZGUgdGVzdHMudXRpbC5GaWVsZFRlc3RGaWxlR2VuZXJhdG9yfSwgdGhlCisgKiBjb250ZW50cyBvZiB0aGlzIGNsYXNzIGhhdmUgdG8gYmUgY29tbWVudGVkIG91dC4KKyAqIDwvcD4KKyAqLworcHVibGljIGNsYXNzIFN1cHBvcnRfR2V0UHV0RmllbGRzRGVmYXVsdGVkIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgcHVibGljIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkIGdldEZpZWxkOworICAgIHB1YmxpYyBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGQgcHV0RmllbGQ7CisKKyAgICBwdWJsaWMgYm9vbGVhbiBib29sZWFuVmFsdWUgPSBmYWxzZTsKKyAgICBwdWJsaWMgYnl0ZSBieXRlVmFsdWUgPSAwOworICAgIHB1YmxpYyBjaGFyIGNoYXJWYWx1ZSA9IDA7CisgICAgcHVibGljIGRvdWJsZSBkb3VibGVWYWx1ZSA9IDAuMDsKKyAgICBwdWJsaWMgZmxvYXQgZmxvYXRWYWx1ZSA9IDAuMGY7CisgICAgcHVibGljIGxvbmcgbG9uZ1ZhbHVlID0gMDsKKyAgICBwdWJsaWMgaW50IGludFZhbHVlID0gMDsKKyAgICBwdWJsaWMgc2hvcnQgc2hvcnRWYWx1ZSA9IDA7CisgICAgcHVibGljIFNpbXBsZUNsYXNzIG9iamVjdFZhbHVlID0gbnVsbDsKKworICAgIGNsYXNzIFNpbXBsZUNsYXNzIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKyAgICAgICAgcHJpdmF0ZSBpbnQgYTsKKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgYjsKKworICAgICAgICBwdWJsaWMgU2ltcGxlQ2xhc3MoaW50IGFWYWx1ZSwgU3RyaW5nIGJWYWx1ZSkgeworICAgICAgICAgICAgYSA9IGFWYWx1ZTsKKyAgICAgICAgICAgIGIgPSBiVmFsdWU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgaW50IGdldEEoKSB7CisgICAgICAgICAgICByZXR1cm4gYTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0QigpIHsKKyAgICAgICAgICAgIHJldHVybiBiOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgICAgIGlmIChvYmogPT0gbnVsbCB8fCBvYmouZ2V0Q2xhc3MoKSAhPSB0aGlzLmdldENsYXNzKCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFNpbXBsZUNsYXNzIG90aGVyID0gKFNpbXBsZUNsYXNzKSBvYmo7CisgICAgICAgICAgICByZXR1cm4gKGEgPT0gb3RoZXIuZ2V0QSgpICYmIGIuZXF1YWxzKG90aGVyLmdldEIoKSkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgaW5pdFRlc3RWYWx1ZXMoKSB7CisgICAgICAgIGJvb2xlYW5WYWx1ZSA9IHRydWU7CisgICAgICAgIGJ5dGVWYWx1ZSA9IChieXRlKSAweDBiOworICAgICAgICBjaGFyVmFsdWUgPSAnRCc7CisgICAgICAgIGRvdWJsZVZhbHVlID0gNTIzNDUyLjQ1MzI7CisgICAgICAgIGZsb2F0VmFsdWUgPSAyOTguNTRmOworICAgICAgICBsb25nVmFsdWUgPSAxMjM0NTY3ODkwbDsKKyAgICAgICAgaW50VmFsdWUgPSA5OTk5OTk7CisgICAgICAgIG9iamVjdFZhbHVlID0gbmV3IFNpbXBsZUNsYXNzKDE5NjUsICJIZWxsbyBKdXBpdGVyIik7CisgICAgICAgIHNob3J0VmFsdWUgPSA0MzIxOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICAgIGlmIChvYmogPT0gbnVsbCB8fCBvYmouZ2V0Q2xhc3MoKSAhPSB0aGlzLmdldENsYXNzKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIFN1cHBvcnRfR2V0UHV0RmllbGRzRGVmYXVsdGVkIG90aGVyID0gKFN1cHBvcnRfR2V0UHV0RmllbGRzRGVmYXVsdGVkKSBvYmo7CisgICAgICAgIHJldHVybiAoYm9vbGVhblZhbHVlID09IG90aGVyLmJvb2xlYW5WYWx1ZSAmJgorICAgICAgICAgICAgICAgIGJ5dGVWYWx1ZSA9PSBvdGhlci5ieXRlVmFsdWUgJiYKKyAgICAgICAgICAgICAgICBjaGFyVmFsdWUgPT0gb3RoZXIuY2hhclZhbHVlICYmCisgICAgICAgICAgICAgICAgZG91YmxlVmFsdWUgPT0gb3RoZXIuZG91YmxlVmFsdWUgJiYKKyAgICAgICAgICAgICAgICBmbG9hdFZhbHVlID09IG90aGVyLmZsb2F0VmFsdWUgJiYKKyAgICAgICAgICAgICAgICBsb25nVmFsdWUgPT0gb3RoZXIubG9uZ1ZhbHVlICYmCisgICAgICAgICAgICAgICAgaW50VmFsdWUgPT0gb3RoZXIuaW50VmFsdWUgJiYKKyAgICAgICAgICAgICAgICBvYmplY3RWYWx1ZS5lcXVhbHMob3RoZXIub2JqZWN0VmFsdWUpICYmCisgICAgICAgICAgICAgICAgc2hvcnRWYWx1ZSA9PSBvdGhlci5zaG9ydFZhbHVlCisgICAgICAgICAgICAgICAgKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBvaXMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBnZXRGaWVsZCA9IG9pcy5yZWFkRmllbGRzKCk7CisgICAgICAgIGJvb2xlYW5WYWx1ZSA9IGdldEZpZWxkLmdldCgiYm9vbGVhblZhbHVlIiwgdHJ1ZSk7CisgICAgICAgIGJ5dGVWYWx1ZSA9IGdldEZpZWxkLmdldCgiYnl0ZVZhbHVlIiwgKGJ5dGUpIDB4MGIpOworICAgICAgICBjaGFyVmFsdWUgPSBnZXRGaWVsZC5nZXQoImNoYXJWYWx1ZSIsIChjaGFyKSAnRCcpOworICAgICAgICBkb3VibGVWYWx1ZSA9IGdldEZpZWxkLmdldCgiZG91YmxlVmFsdWUiLCA1MjM0NTIuNDUzMik7CisgICAgICAgIGZsb2F0VmFsdWUgPSBnZXRGaWVsZC5nZXQoImZsb2F0VmFsdWUiLCAyOTguNTRmKTsKKyAgICAgICAgbG9uZ1ZhbHVlID0gZ2V0RmllbGQuZ2V0KCJsb25nVmFsdWUiLCAobG9uZykgMTIzNDU2Nzg5MGwpOworICAgICAgICBpbnRWYWx1ZSA9IGdldEZpZWxkLmdldCgiaW50VmFsdWUiLCA5OTk5OTkpOworICAgICAgICBvYmplY3RWYWx1ZSA9IChTdXBwb3J0X0dldFB1dEZpZWxkc0RlZmF1bHRlZC5TaW1wbGVDbGFzcykKKyAgICAgICAgICAgICAgICAgICAgICAgZ2V0RmllbGQuZ2V0KCJvYmplY3RWYWx1ZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU2ltcGxlQ2xhc3MoMTk2NSwgIkhlbGxvIEp1cGl0ZXIiKSk7CisgICAgICAgIHNob3J0VmFsdWUgPSBnZXRGaWVsZC5nZXQoInNob3J0VmFsdWUiLCAoc2hvcnQpIDQzMjEpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gb29zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBwdXRGaWVsZCA9IG9vcy5wdXRGaWVsZHMoKTsKKyAgICAgICAgLy8gRG8gbm90IHB1dCBhbnl0aGluZyBpbnRvIHB1dEZpZWxkIHNvIHRoYXQgdGhlIGdldCBtZXRob2RzCisgICAgICAgIC8vIHdpbGwgaGF2ZSB0byB1c2UgZGVmYXVsdCB2YWx1ZXMuCisgICAgICAgIG9vcy53cml0ZUZpZWxkcygpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9HZXRQdXRGaWVsZHNEZXByZWNhdGVkLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0dldFB1dEZpZWxkc0RlcHJlY2F0ZWQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZjU0ZTNlCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9HZXRQdXRGaWVsZHNEZXByZWNhdGVkLmphdmEKQEAgLTAsMCArMSwxMzQgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworLyoqCisgKiBTdXBwb3J0IGNsYXNzIHRvIHRlc3QgdGhlIG1ldGhvZHMgb2Yge0Bjb2RlIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkfSBhbmQKKyAqIHtAY29kZSBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGR9LiBUaGUgZGlmZmVyZW5jZSB3aXRoIGNsYXNzCisgKiB7QGNvZGUgU3VwcG9ydF9HZXRQdXRGaWVsZHN9IGlzIHRoYXQgaXQgdXNlcyB0aGUgZGVwcmVjYXRlZCBtZXRob2QKKyAqIHtAY29kZSBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGQud3JpdGUoT2JqZWN0T3V0cHV0KX0gdG8gd3JpdGUgdGhlIGZpZWxkcworICogdG8gdGhlIG91dHB1dCBzdHJlYW0uCisgKi8KK3B1YmxpYyBjbGFzcyBTdXBwb3J0X0dldFB1dEZpZWxkc0RlcHJlY2F0ZWQgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICBwdWJsaWMgT2JqZWN0SW5wdXRTdHJlYW0uR2V0RmllbGQgZ2V0RmllbGQ7CisgICAgcHVibGljIE9iamVjdE91dHB1dFN0cmVhbS5QdXRGaWVsZCBwdXRGaWVsZDsKKworICAgIHB1YmxpYyBib29sZWFuIGJvb2xlYW5WYWx1ZSA9IGZhbHNlOworICAgIHB1YmxpYyBieXRlIGJ5dGVWYWx1ZSA9IDA7CisgICAgcHVibGljIGNoYXIgY2hhclZhbHVlID0gMDsKKyAgICBwdWJsaWMgZG91YmxlIGRvdWJsZVZhbHVlID0gMC4wOworICAgIHB1YmxpYyBmbG9hdCBmbG9hdFZhbHVlID0gMC4wZjsKKyAgICBwdWJsaWMgbG9uZyBsb25nVmFsdWUgPSAwOworICAgIHB1YmxpYyBpbnQgaW50VmFsdWUgPSAwOworICAgIHB1YmxpYyBzaG9ydCBzaG9ydFZhbHVlID0gMDsKKyAgICBwdWJsaWMgU2ltcGxlQ2xhc3Mgb2JqZWN0VmFsdWUgPSBudWxsOworCisgICAgY2xhc3MgU2ltcGxlQ2xhc3MgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworICAgICAgICBwcml2YXRlIGludCBhOworICAgICAgICBwcml2YXRlIFN0cmluZyBiOworCisgICAgICAgIHB1YmxpYyBTaW1wbGVDbGFzcyhpbnQgYVZhbHVlLCBTdHJpbmcgYlZhbHVlKSB7CisgICAgICAgICAgICBhID0gYVZhbHVlOworICAgICAgICAgICAgYiA9IGJWYWx1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0QSgpIHsKKyAgICAgICAgICAgIHJldHVybiBhOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRCKCkgeworICAgICAgICAgICAgcmV0dXJuIGI7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICAgICAgaWYgKG9iaiA9PSBudWxsIHx8IG9iai5nZXRDbGFzcygpICE9IHRoaXMuZ2V0Q2xhc3MoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU2ltcGxlQ2xhc3Mgb3RoZXIgPSAoU2ltcGxlQ2xhc3MpIG9iajsKKyAgICAgICAgICAgIHJldHVybiAoYSA9PSBvdGhlci5nZXRBKCkgJiYgYi5lcXVhbHMob3RoZXIuZ2V0QigpKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBpbml0VGVzdFZhbHVlcygpIHsKKyAgICAgICAgYm9vbGVhblZhbHVlID0gdHJ1ZTsKKyAgICAgICAgYnl0ZVZhbHVlID0gKGJ5dGUpIDB4YmU7CisgICAgICAgIGNoYXJWYWx1ZSA9ICdBJzsKKyAgICAgICAgZG91YmxlVmFsdWUgPSAxMjMxLjM0MjsKKyAgICAgICAgZmxvYXRWYWx1ZSA9IDQzLjIyZjsKKyAgICAgICAgbG9uZ1ZhbHVlID0gMTU2MDczMjMyMWw7CisgICAgICAgIGludFZhbHVlID0gMzMzMzM7CisgICAgICAgIG9iamVjdFZhbHVlID0gbmV3IFNpbXBsZUNsYXNzKDIwMDEsICJBIFNwYWNlIE9keXNzZXkiKTsKKyAgICAgICAgc2hvcnRWYWx1ZSA9IDMwNzg7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICAgICAgaWYgKG9iaiA9PSBudWxsIHx8IG9iai5nZXRDbGFzcygpICE9IHRoaXMuZ2V0Q2xhc3MoKSkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgU3VwcG9ydF9HZXRQdXRGaWVsZHMgb3RoZXIgPSAoU3VwcG9ydF9HZXRQdXRGaWVsZHMpIG9iajsKKyAgICAgICAgcmV0dXJuIChib29sZWFuVmFsdWUgPT0gb3RoZXIuYm9vbGVhblZhbHVlICYmCisgICAgICAgICAgICAgICAgYnl0ZVZhbHVlID09IG90aGVyLmJ5dGVWYWx1ZSAmJgorICAgICAgICAgICAgICAgIGNoYXJWYWx1ZSA9PSBvdGhlci5jaGFyVmFsdWUgJiYKKyAgICAgICAgICAgICAgICBkb3VibGVWYWx1ZSA9PSBvdGhlci5kb3VibGVWYWx1ZSAmJgorICAgICAgICAgICAgICAgIGZsb2F0VmFsdWUgPT0gb3RoZXIuZmxvYXRWYWx1ZSAmJgorICAgICAgICAgICAgICAgIGxvbmdWYWx1ZSA9PSBvdGhlci5sb25nVmFsdWUgJiYKKyAgICAgICAgICAgICAgICBpbnRWYWx1ZSA9PSBvdGhlci5pbnRWYWx1ZSAmJgorICAgICAgICAgICAgICAgIG9iamVjdFZhbHVlLmVxdWFscyhvdGhlci5vYmplY3RWYWx1ZSkgJiYKKyAgICAgICAgICAgICAgICBzaG9ydFZhbHVlID09IG90aGVyLnNob3J0VmFsdWUKKyAgICAgICAgICAgICAgICApOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIG9pcykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW5WYWx1ZSA9IGdldEZpZWxkLmdldCgiYm9vbGVhblZhbHVlIiwgZmFsc2UpOworICAgICAgICBieXRlVmFsdWUgPSBnZXRGaWVsZC5nZXQoImJ5dGVWYWx1ZSIsIChieXRlKSAwKTsKKyAgICAgICAgY2hhclZhbHVlID0gZ2V0RmllbGQuZ2V0KCJjaGFyVmFsdWUiLCAoY2hhcikgMCk7CisgICAgICAgIGRvdWJsZVZhbHVlID0gZ2V0RmllbGQuZ2V0KCJkb3VibGVWYWx1ZSIsIDAuMCk7CisgICAgICAgIGZsb2F0VmFsdWUgPSBnZXRGaWVsZC5nZXQoImZsb2F0VmFsdWUiLCAwLjBmKTsKKyAgICAgICAgbG9uZ1ZhbHVlID0gZ2V0RmllbGQuZ2V0KCJsb25nVmFsdWUiLCAobG9uZykgMCk7CisgICAgICAgIGludFZhbHVlID0gZ2V0RmllbGQuZ2V0KCJpbnRWYWx1ZSIsIDApOworICAgICAgICBvYmplY3RWYWx1ZSA9IChTdXBwb3J0X0dldFB1dEZpZWxkc0RlcHJlY2F0ZWQuU2ltcGxlQ2xhc3MpCisgICAgICAgICAgICAgICAgZ2V0RmllbGQuZ2V0KCJvYmplY3RWYWx1ZSIsIChPYmplY3QpIG51bGwpOworICAgICAgICBzaG9ydFZhbHVlID0gZ2V0RmllbGQuZ2V0KCJzaG9ydFZhbHVlIiwgKHNob3J0KSAwKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIG9vcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcHV0RmllbGQgPSBvb3MucHV0RmllbGRzKCk7CisgICAgICAgIHB1dEZpZWxkLnB1dCgiYm9vbGVhblZhbHVlIiwgYm9vbGVhblZhbHVlKTsKKyAgICAgICAgcHV0RmllbGQucHV0KCJieXRlVmFsdWUiLCBieXRlVmFsdWUpOworICAgICAgICBwdXRGaWVsZC5wdXQoImNoYXJWYWx1ZSIsIGNoYXJWYWx1ZSk7CisgICAgICAgIHB1dEZpZWxkLnB1dCgiZG91YmxlVmFsdWUiLCBkb3VibGVWYWx1ZSk7CisgICAgICAgIHB1dEZpZWxkLnB1dCgiZmxvYXRWYWx1ZSIsIGZsb2F0VmFsdWUpOworICAgICAgICBwdXRGaWVsZC5wdXQoImxvbmdWYWx1ZSIsIGxvbmdWYWx1ZSk7CisgICAgICAgIHB1dEZpZWxkLnB1dCgiaW50VmFsdWUiLCBpbnRWYWx1ZSk7CisgICAgICAgIHB1dEZpZWxkLnB1dCgib2JqZWN0VmFsdWUiLCBvYmplY3RWYWx1ZSk7CisgICAgICAgIHB1dEZpZWxkLnB1dCgic2hvcnRWYWx1ZSIsIHNob3J0VmFsdWUpOworICAgICAgICBwdXRGaWVsZC53cml0ZShvb3MpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfR2V0UmVzb3VyY2UuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfR2V0UmVzb3VyY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43Y2MyYjg4Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9HZXRSZXNvdXJjZS5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK3B1YmxpYyBjbGFzcyBTdXBwb3J0X0dldFJlc291cmNlIHsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFJlc291cmNlVVJMKFN0cmluZyByZXNvdXJjZSkgeworICAgICAgICByZXR1cm4gImh0dHA6Ly8iICsgU3VwcG9ydF9Db25maWd1cmF0aW9uLlRlc3RSZXNvdXJjZXMgKyByZXNvdXJjZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0h0dHBDb25zdGFudHMuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfSHR0cENvbnN0YW50cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU5OWJkYzEKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0h0dHBDb25zdGFudHMuamF2YQpAQCAtMCwwICsxLDE1NyBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworaW50ZXJmYWNlIFN1cHBvcnRfSHR0cENvbnN0YW50cyB7CisgICAgLyoqIDJYWDogZ2VuZXJhbGx5ICJPSyIgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX09LID0gMjAwOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfQ1JFQVRFRCA9IDIwMTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX0FDQ0VQVEVEID0gMjAyOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfTk9UX0FVVEhPUklUQVRJVkUgPSAyMDM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9OT19DT05URU5UID0gMjA0OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfUkVTRVQgPSAyMDU7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9QQVJUSUFMID0gMjA2OworCisgICAgLyoqIDNYWDogcmVsb2NhdGlvbi9yZWRpcmVjdCAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfTVVMVF9DSE9JQ0UgPSAzMDA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9NT1ZFRF9QRVJNID0gMzAxOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfTU9WRURfVEVNUCA9IDMwMjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX1NFRV9PVEhFUiA9IDMwMzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX05PVF9NT0RJRklFRCA9IDMwNDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX1VTRV9QUk9YWSA9IDMwNTsKKworICAgIC8qKiA0WFg6IGNsaWVudCBlcnJvciAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfQkFEX1JFUVVFU1QgPSA0MDA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9VTkFVVEhPUklaRUQgPSA0MDE7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9QQVlNRU5UX1JFUVVJUkVEID0gNDAyOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfRk9SQklEREVOID0gNDAzOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfTk9UX0ZPVU5EID0gNDA0OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfQkFEX01FVEhPRCA9IDQwNTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX05PVF9BQ0NFUFRBQkxFID0gNDA2OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfUFJPWFlfQVVUSCA9IDQwNzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX0NMSUVOVF9USU1FT1VUID0gNDA4OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfQ09ORkxJQ1QgPSA0MDk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9HT05FID0gNDEwOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfTEVOR1RIX1JFUVVJUkVEID0gNDExOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfUFJFQ09OX0ZBSUxFRCA9IDQxMjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX0VOVElUWV9UT09fTEFSR0UgPSA0MTM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9SRVFfVE9PX0xPTkcgPSA0MTQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9VTlNVUFBPUlRFRF9UWVBFID0gNDE1OworCisgICAgLyoqIDVYWDogc2VydmVyIGVycm9yICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9TRVJWRVJfRVJST1IgPSA1MDA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9JTlRFUk5BTF9FUlJPUiA9IDUwMTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVFRQX0JBRF9HQVRFV0FZID0gNTAyOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfVU5BVkFJTEFCTEUgPSA1MDM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9HQVRFV0FZX1RJTUVPVVQgPSA1MDQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9WRVJTSU9OID0gNTA1OworCisgICAgLyoqIE1ldGhvZCBJRHMgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTktOT1dOX01FVEhPRCA9IDA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgR0VUX01FVEhPRCA9IDE7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSEVBRF9NRVRIT0QgPSAyOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBPU1RfTUVUSE9EID0gMzsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nW10gcmVxdWVzdEhlYWRlcnMgPSB7CisgICAgICAgICJjYWNoZS1jb250cm9sIiwKKyAgICAgICAgImNvbm5lY3Rpb24iLAorICAgICAgICAiZGF0ZSIsCisgICAgICAgICJwcmFnbWEiLAorICAgICAgICAidHJhaWxlciIsCisgICAgICAgICJ0cmFuc2Zlci1lbmNvZGluZyIsCisgICAgICAgICJ1cGdyYWRlIiwKKyAgICAgICAgInZpYSIsCisgICAgICAgICJ3YXJuaW5nIiwKKyAgICAgICAgImFjY2VwdCIsCisgICAgICAgICJhY2NlcHQtY2hhcnNldCIsCisgICAgICAgICJhY2NlcHQtZW5jb2RpbmciLAorICAgICAgICAiYWNjZXB0LWxhbmd1YWdlIiwKKyAgICAgICAgImF1dGhvcml6YXRpb24iLAorICAgICAgICAiZXhwZWN0IiwKKyAgICAgICAgImZyb20iLAorICAgICAgICAiaG9zdCIsCisgICAgICAgICJpZi1tYXRjaCIsCisgICAgICAgICJpZi1tb2RpZmllZC1zaW5jZSIsCisgICAgICAgICJpZi1ub25lLW1hdGNoIiwKKyAgICAgICAgImlmLXJhbmdlIiwKKyAgICAgICAgImlmLXVubW9kaWZpZWQtc2luY2UiLAorICAgICAgICAibWF4LWZvcndhcmRzIiwKKyAgICAgICAgInByb3h5LWF1dGhlbnRpY2F0aW9uIiwKKyAgICAgICAgInJhbmdlIiwKKyAgICAgICAgInJlZmVyZXIiLAorICAgICAgICAidGUiLAorICAgICAgICAidXNlci1hZ2VudCIsCisgICAgICAgICJrZWVwLWFsaXZlIiwKKyAgICAgICAgImFsbG93IiwKKyAgICAgICAgImNvbnRlbnQtZW5jb2RpbmciLAorICAgICAgICAiY29udGVudC1sYW5ndWFnZSIsCisgICAgICAgICJjb250ZW50LWxlbmd0aCIsCisgICAgICAgICJjb250ZW50LWxvY2F0aW9uIiwKKyAgICAgICAgImNvbnRlbnQtbWQ1IiwKKyAgICAgICAgImNvbnRlbnQtcmFuZ2UiLAorICAgICAgICAiY29udGVudC10eXBlIiwKKyAgICAgICAgImV4cGlyZXMiLAorICAgICAgICAibGFzdC1tb2RpZmllZCIsCisgICAgICAgICJsb2NhdGlvbiIsCisgICAgICAgICJzZXJ2ZXIiCisKKyAgICB9OworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX1VOS05PV04gPSAtMTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFfQ0FDSEVfQ09OVFJPTCA9IDA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX0NPTk5FQ1RJT04gPSAxOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUV9EQVRFID0gMjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFfUFJBR01BID0gMzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFfVFJBSUxFUiA9IDQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX1RSQU5TRkVSX0VOQ09ESU5HID0gNTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFfVVBHUkFERSA9IDY7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX1ZJQSA9IDc7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX1dBUk5JTkcgPSA4OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUV9BQ0NFUFQgPSA5OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUV9BQ0NFUFRfQ0hBUlNFVCA9IDEwOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUV9BQ0NFUFRfRU5DT0RJTkcgPSAxMTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFfQUNDRVBUX0xBTkdVQUdFID0gMTI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX0FVVEhPUklaQVRJT04gPSAxMzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFfRVhQRUNUID0gMTQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX0ZST00gPSAxNTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFfSE9TVCA9IDE2OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUV9JRl9NQVRDSCA9IDE3OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUV9JRl9NT0RJRklFRF9TSU5DRSA9IDE4OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUV9JRl9OT05FX01BVENIID0gMTk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX0lGX1JBTkdFID0gMjA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX0lGX1VOTU9ESUZJRURfU0lOQ0UgPSAyMTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFfTUFYX0ZPUldBUkRTID0gMjI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX1BST1hZX0FVVEhFTlRJQ0FUSU9OID0gMjM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX1JBTkdFID0gMjQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX1JFRkVSRVIgPSAyNTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFfVEUgPSAyNjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFfVVNFUl9BR0VOVCA9IDI3OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUV9LRUVQX0FMSVZFID0gMjg7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX0FMTE9XID0gMjk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX0NPTlRFTlRfRU5DT0RJTkcgPSAzMDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFfQ09OVEVOVF9MQU5HVUFHRSA9IDMxOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUV9DT05URU5UX0xFTkdUSCA9IDMyOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUV9DT05URU5UX0xPQ0FUSU9OID0gMzM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX0NPTlRFTlRfTUQ1ID0gMzQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX0NPTlRFTlRfUkFOR0UgPSAzNTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFfQ09OVEVOVF9UWVBFID0gMzY7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRX0VYUElSRVMgPSAzNzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFfTEFTVF9NT0RJRklFRCA9IDM4OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUV9MT0NBVElPTiA9IDM5OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUV9TRVJWRVIgPSA0MDsKKworfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9MaXN0VGVzdC5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9MaXN0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhZWVlYWYKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0xpc3RUZXN0LmphdmEKQEAgLTAsMCArMSwyMjAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdEl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9MaXN0VGVzdCBleHRlbmRzIGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZSB7CisKKyAgICBMaXN0PEludGVnZXI+IGxpc3Q7IC8vIG11c3QgY29udGFpbiB0aGUgSW50ZWdlcnMgMCB0byA5OSBpbiBvcmRlcgorCisgICAgcHVibGljIFN1cHBvcnRfTGlzdFRlc3QoU3RyaW5nIHAxKSB7CisgICAgICAgIHN1cGVyKHAxKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3VwcG9ydF9MaXN0VGVzdChTdHJpbmcgcDEsIExpc3Q8SW50ZWdlcj4gbCkgeworICAgICAgICBzdXBlcihwMSk7CisgICAgICAgIGxpc3QgPSBsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB7CisgICAgICAgIGludCBoYXNoQ29kZSA9IDE7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgMTAwOyBjb3VudGVyKyspIHsKKyAgICAgICAgICAgIE9iamVjdCBlbGVtOworICAgICAgICAgICAgZWxlbSA9IGxpc3QuZ2V0KGNvdW50ZXIpOworICAgICAgICAgICAgaGFzaENvZGUgPSAzMSAqIGhhc2hDb2RlICsgZWxlbS5oYXNoQ29kZSgpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTGlzdFRlc3QgLSBnZXQgZmFpbGVkIiwgZWxlbQorICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKG5ldyBJbnRlZ2VyKGNvdW50ZXIpKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTGlzdFRlc3QgLSBoYXNoQ29kZSBmYWlsZWQiLCBoYXNoQ29kZSA9PSBsaXN0Lmhhc2hDb2RlKCkpOworCisgICAgICAgIGxpc3QuYWRkKDUwLCBuZXcgSW50ZWdlcigxMDAwKSk7CisgICAgICAgIGFzc2VydFRydWUoIkxpc3RUZXN0IC0gYSkgYWRkIHdpdGggaW5kZXggZmFpbGVkLS1kaWQgbm90IGluc2VydCIsIGxpc3QKKyAgICAgICAgICAgICAgICAuZ2V0KDUwKS5lcXVhbHMobmV3IEludGVnZXIoMTAwMCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiTGlzdFRlc3QgLSBiKSBhZGQgd2l0aCBpbmRleCBmYWlsZWQtLWRpZCBub3QgbW92ZSBmb2xsb3dpbmcgZWxlbWVudHMiLAorICAgICAgICAgICAgICAgIGxpc3QuZ2V0KDUxKS5lcXVhbHMobmV3IEludGVnZXIoNTApKSk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIkxpc3RUZXN0IC0gYykgYWRkIHdpdGggaW5kZXggZmFpbGVkLS1hZmZlY3RlZCBwcmV2aW91cyBlbGVtZW50cyIsCisgICAgICAgICAgICAgICAgbGlzdC5nZXQoNDkpLmVxdWFscyhuZXcgSW50ZWdlcig0OSkpKTsKKworICAgICAgICBsaXN0LnNldCg1MCwgbmV3IEludGVnZXIoMjAwMCkpOworICAgICAgICBhc3NlcnRUcnVlKCJMaXN0VGVzdCAtIGEpIHNldCBmYWlsZWQtLWRpZCBub3Qgc2V0IiwgbGlzdC5nZXQoNTApCisgICAgICAgICAgICAgICAgLmVxdWFscyhuZXcgSW50ZWdlcigyMDAwKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJMaXN0VGVzdCAtIGIpIHNldCBmYWlsZWQtLWFmZmVjdGVkIGZvbGxvd2luZyBlbGVtZW50cyIsCisgICAgICAgICAgICAgICAgbGlzdC5nZXQoNTEpLmVxdWFscyhuZXcgSW50ZWdlcig1MCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTGlzdFRlc3QgLSBjKSBzZXQgZmFpbGVkLS1hZmZlY3RlZCBwcmV2aW91cyBlbGVtZW50cyIsIGxpc3QKKyAgICAgICAgICAgICAgICAuZ2V0KDQ5KS5lcXVhbHMobmV3IEludGVnZXIoNDkpKSk7CisKKyAgICAgICAgbGlzdC5yZW1vdmUoNTApOworICAgICAgICBhc3NlcnRUcnVlKCJMaXN0VGVzdCAtIGEpIHJlbW92ZSB3aXRoIGluZGV4IGZhaWxlZC0tZGlkIG5vdCByZW1vdmUiLAorICAgICAgICAgICAgICAgIGxpc3QuZ2V0KDUwKS5lcXVhbHMobmV3IEludGVnZXIoNTApKSk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIkxpc3RUZXN0IC0gYikgcmVtb3ZlIHdpdGggaW5kZXggZmFpbGVkLS1kaWQgbm90IG1vdmUgZm9sbG93aW5nIGVsZW1lbnRzIiwKKyAgICAgICAgICAgICAgICBsaXN0LmdldCg1MSkuZXF1YWxzKG5ldyBJbnRlZ2VyKDUxKSkpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJMaXN0VGVzdCAtIGMpIHJlbW92ZSB3aXRoIGluZGV4IGZhaWxlZC0tYWZmZWN0ZWQgcHJldmlvdXMgZWxlbWVudHMiLAorICAgICAgICAgICAgICAgIGxpc3QuZ2V0KDQ5KS5lcXVhbHMobmV3IEludGVnZXIoNDkpKSk7CisKKyAgICAgICAgTGlzdDxJbnRlZ2VyPiBteUxpc3QgPSBuZXcgTGlua2VkTGlzdDxJbnRlZ2VyPigpOworICAgICAgICBteUxpc3QuYWRkKG5ldyBJbnRlZ2VyKDUwMCkpOworICAgICAgICBteUxpc3QuYWRkKG5ldyBJbnRlZ2VyKDUwMSkpOworICAgICAgICBteUxpc3QuYWRkKG5ldyBJbnRlZ2VyKDUwMikpOworCisgICAgICAgIGxpc3QuYWRkQWxsKDUwLCBteUxpc3QpOworICAgICAgICBhc3NlcnRUcnVlKCJMaXN0VGVzdCAtIGEpIGFkZEFsbCB3aXRoIGluZGV4IGZhaWxlZC0tZGlkIG5vdCBpbnNlcnQiLAorICAgICAgICAgICAgICAgIGxpc3QuZ2V0KDUwKS5lcXVhbHMobmV3IEludGVnZXIoNTAwKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJMaXN0VGVzdCAtIGIpIGFkZEFsbCB3aXRoIGluZGV4IGZhaWxlZC0tZGlkIG5vdCBpbnNlcnQiLAorICAgICAgICAgICAgICAgIGxpc3QuZ2V0KDUxKS5lcXVhbHMobmV3IEludGVnZXIoNTAxKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJMaXN0VGVzdCAtIGMpIGFkZEFsbCB3aXRoIGluZGV4IGZhaWxlZC0tZGlkIG5vdCBpbnNlcnQiLAorICAgICAgICAgICAgICAgIGxpc3QuZ2V0KDUyKS5lcXVhbHMobmV3IEludGVnZXIoNTAyKSkpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJMaXN0VGVzdCAtIGQpIGFkZEFsbCB3aXRoIGluZGV4IGZhaWxlZC0tZGlkIG5vdCBtb3ZlIGZvbGxvd2luZyBlbGVtZW50cyIsCisgICAgICAgICAgICAgICAgbGlzdC5nZXQoNTMpLmVxdWFscyhuZXcgSW50ZWdlcig1MCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiTGlzdFRlc3QgLSBlKSBhZGRBbGwgd2l0aCBpbmRleCBmYWlsZWQtLWFmZmVjdGVkIHByZXZpb3VzIGVsZW1lbnRzIiwKKyAgICAgICAgICAgICAgICBsaXN0LmdldCg0OSkuZXF1YWxzKG5ldyBJbnRlZ2VyKDQ5KSkpOworCisgICAgICAgIExpc3Q8SW50ZWdlcj4gbXlTdWJMaXN0ID0gbGlzdC5zdWJMaXN0KDUwLCA1Myk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBteVN1Ykxpc3Quc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiTGlzdFRlc3QgLSBhKSBzdWJsaXN0IEZhaWxlZC0tZG9lcyBub3QgY29udGFpbiBjb3JyZWN0IGVsZW1lbnRzIiwKKyAgICAgICAgICAgICAgICBteVN1Ykxpc3QuZ2V0KDApLmVxdWFscyhuZXcgSW50ZWdlcig1MDApKSk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIkxpc3RUZXN0IC0gYikgc3VibGlzdCBGYWlsZWQtLWRvZXMgbm90IGNvbnRhaW4gY29ycmVjdCBlbGVtZW50cyIsCisgICAgICAgICAgICAgICAgbXlTdWJMaXN0LmdldCgxKS5lcXVhbHMobmV3IEludGVnZXIoNTAxKSkpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJMaXN0VGVzdCAtIGMpIHN1Ymxpc3QgRmFpbGVkLS1kb2VzIG5vdCBjb250YWluIGNvcnJlY3QgZWxlbWVudHMiLAorICAgICAgICAgICAgICAgIG15U3ViTGlzdC5nZXQoMikuZXF1YWxzKG5ldyBJbnRlZ2VyKDUwMikpKTsKKworICAgICAgICB0X2xpc3RJdGVyYXRvcihteVN1Ykxpc3QpOworCisgICAgICAgIG15U3ViTGlzdC5jbGVhcigpOworICAgICAgICBhc3NlcnRFcXVhbHMoIkxpc3RUZXN0IC0gQ2xlYXJpbmcgdGhlIHN1Ymxpc3QgZGlkIG5vdCByZW1vdmUgdGhlIGFwcHJvcHJpYXRlIGVsZW1lbnRzIGZyb20gdGhlIG9yaWdpbmFsIGxpc3QiLAorICAgICAgICAgICAgICAgIDEwMCwgbGlzdC5zaXplKCkpOworCisgICAgICAgIHRfbGlzdEl0ZXJhdG9yKGxpc3QpOworICAgICAgICBMaXN0SXRlcmF0b3I8SW50ZWdlcj4gbGkgPSBsaXN0Lmxpc3RJdGVyYXRvcigpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgbGkuaGFzTmV4dCgpOyBjb3VudGVyKyspIHsKKyAgICAgICAgICAgIE9iamVjdCBlbGVtOworICAgICAgICAgICAgZWxlbSA9IGxpLm5leHQoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIkxpc3RUZXN0IC0gbGlzdEl0ZXJhdG9yIGZhaWxlZCIsIGVsZW0KKyAgICAgICAgICAgICAgICAgICAgLmVxdWFscyhuZXcgSW50ZWdlcihjb3VudGVyKSkpOworICAgICAgICB9CisKKyAgICAgICAgbmV3IFN1cHBvcnRfQ29sbGVjdGlvblRlc3QoIiIsIGxpc3QpLnJ1blRlc3QoKTsKKworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRfbGlzdEl0ZXJhdG9yKExpc3Q8SW50ZWdlcj4gbGlzdCkgeworICAgICAgICBMaXN0SXRlcmF0b3I8SW50ZWdlcj4gbGkgPSBsaXN0Lmxpc3RJdGVyYXRvcigxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibGlzdEl0ZXJhdG9yKDEpIiwgbGkubmV4dCgpID09IGxpc3QuZ2V0KDEpKTsKKworICAgICAgICBpbnQgb3JnU2l6ZSA9IGxpc3Quc2l6ZSgpOworICAgICAgICBsaSA9IGxpc3QubGlzdEl0ZXJhdG9yKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IG9yZ1NpemU7IGkrKykgeworICAgICAgICAgICAgaWYgKGkgPT0gMCkgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImxpc3QgaXRlcmF0b3IgaGFzUHJldmlvdXMoKTogIiArIGksICFsaQorICAgICAgICAgICAgICAgICAgICAgICAgLmhhc1ByZXZpb3VzKCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJsaXN0IGl0ZXJhdG9yIGhhc1ByZXZpb3VzKCk6ICIgKyBpLCBsaQorICAgICAgICAgICAgICAgICAgICAgICAgLmhhc1ByZXZpb3VzKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGkgPT0gbGlzdC5zaXplKCkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJsaXN0IGl0ZXJhdG9yIGhhc05leHQoKTogIiArIGksICFsaS5oYXNOZXh0KCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJsaXN0IGl0ZXJhdG9yIGhhc05leHQoKTogIiArIGksIGxpLmhhc05leHQoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJsaXN0IGl0ZXJhdG9yIG5leHRJbmRleCgpOiAiICsgaSwgbGkubmV4dEluZGV4KCkgPT0gaSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJsaXN0IGl0ZXJhdG9yIHByZXZpb3VzSW5kZXgoKTogIiArIGksIGxpCisgICAgICAgICAgICAgICAgICAgIC5wcmV2aW91c0luZGV4KCkgPT0gaSAtIDEpOworICAgICAgICAgICAgYm9vbGVhbiBleGNlcHRpb24gPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgibGlzdCBpdGVyYXRvciBuZXh0KCk6ICIgKyBpLCBsaS5uZXh0KCkgPT0gbGlzdAorICAgICAgICAgICAgICAgICAgICAgICAgLmdldChpKSk7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGkgPT0gbGlzdC5zaXplKCkpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJsaXN0IGl0ZXJhdG9yIG5leHQoKSBleGNlcHRpb246ICIgKyBpLCBleGNlcHRpb24pOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJsaXN0IGl0ZXJhdG9yIG5leHQoKSBleGNlcHRpb246ICIgKyBpLCAhZXhjZXB0aW9uKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSBvcmdTaXplIC0gMTsgaSA+PSAwOyBpLS0pIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImxpc3QgaXRlcmF0b3IgcHJldmlvdXMoKTogIiArIGksIGxpLnByZXZpb3VzKCkgPT0gbGlzdAorICAgICAgICAgICAgICAgICAgICAuZ2V0KGkpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoImxpc3QgaXRlcmF0b3IgbmV4dEluZGV4KCkyOiAiICsgaSwgbGkubmV4dEluZGV4KCkgPT0gaSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJsaXN0IGl0ZXJhdG9yIHByZXZpb3VzSW5kZXgoKTI6ICIgKyBpLCBsaQorICAgICAgICAgICAgICAgICAgICAucHJldmlvdXNJbmRleCgpID09IGkgLSAxKTsKKyAgICAgICAgICAgIGlmIChpID09IDApIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKCJsaXN0IGl0ZXJhdG9yIGhhc1ByZXZpb3VzKCkyOiAiICsgaSwgIWxpCisgICAgICAgICAgICAgICAgICAgICAgICAuaGFzUHJldmlvdXMoKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoImxpc3QgaXRlcmF0b3IgaGFzUHJldmlvdXMoKTI6ICIgKyBpLCBsaQorICAgICAgICAgICAgICAgICAgICAgICAgLmhhc1ByZXZpb3VzKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgibGlzdCBpdGVyYXRvciBoYXNOZXh0KCkyOiAiICsgaSwgbGkuaGFzTmV4dCgpKTsKKyAgICAgICAgfQorICAgICAgICBib29sZWFuIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbGkucHJldmlvdXMoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBleGNlcHRpb24gPSB0cnVlOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoImxpc3QgaXRlcmF0b3IgcHJldmlvdXMoKSBleGNlcHRpb24iLCBleGNlcHRpb24pOworCisgICAgICAgIEludGVnZXIgYWRkMSA9IG5ldyBJbnRlZ2VyKDYwMCk7CisgICAgICAgIEludGVnZXIgYWRkMiA9IG5ldyBJbnRlZ2VyKDYwMSk7CisgICAgICAgIGxpLmFkZChhZGQxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibGlzdCBpdGVyYXRvciBhZGQoKSwgc2l6ZSgpIiwgbGlzdC5zaXplKCkgPT0gKG9yZ1NpemUgKyAxKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibGlzdCBpdGVyYXRvciBhZGQoKSwgbmV4dEluZGV4KCkiLCAxLCBsaS5uZXh0SW5kZXgoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygibGlzdCBpdGVyYXRvciBhZGQoKSwgcHJldmlvdXNJbmRleCgpIiwKKyAgICAgICAgICAgICAgICAwLCBsaS5wcmV2aW91c0luZGV4KCkpOworICAgICAgICBPYmplY3QgbmV4dCA9IGxpLm5leHQoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibGlzdCBpdGVyYXRvciBhZGQoKSwgbmV4dCgpOiAiICsgbmV4dCwgbmV4dCA9PSBsaXN0LmdldCgxKSk7CisgICAgICAgIGxpLmFkZChhZGQyKTsKKyAgICAgICAgT2JqZWN0IHByZXZpb3VzID0gbGkucHJldmlvdXMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibGlzdCBpdGVyYXRvciBhZGQoKSwgcHJldmlvdXMoKTogIiArIHByZXZpb3VzLAorICAgICAgICAgICAgICAgIHByZXZpb3VzID09IGFkZDIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImxpc3QgaXRlcmF0b3IgYWRkKCksIG5leHRJbmRleCgpMiIsIDIsIGxpLm5leHRJbmRleCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJsaXN0IGl0ZXJhdG9yIGFkZCgpLCBwcmV2aW91c0luZGV4KCkyIiwKKyAgICAgICAgICAgICAgICAxLCBsaS5wcmV2aW91c0luZGV4KCkpOworCisgICAgICAgIGxpLnJlbW92ZSgpOworICAgICAgICBhc3NlcnRUcnVlKCJsaXN0IGl0ZXJhdG9yIHJlbW92ZSgpLCBzaXplKCkiLAorICAgICAgICAgICAgICAgIGxpc3Quc2l6ZSgpID09IChvcmdTaXplICsgMSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImxpc3QgaXRlcmF0b3IgcmVtb3ZlKCksIG5leHRJbmRleCgpIiwgMiwgbGkubmV4dEluZGV4KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImxpc3QgaXRlcmF0b3IgcmVtb3ZlKCksIHByZXZpb3VzSW5kZXgoKSIsIDEsIGxpCisgICAgICAgICAgICAgICAgLnByZXZpb3VzSW5kZXgoKSk7CisgICAgICAgIGFzc2VydFRydWUoImxpc3QgaXRlcmF0b3IgcHJldmlvdXMoKTIiLCBsaS5wcmV2aW91cygpID09IGxpc3QuZ2V0KDEpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibGlzdCBpdGVyYXRvciBwcmV2aW91cygpMyIsIGxpLnByZXZpb3VzKCkgPT0gbGlzdC5nZXQoMCkpOworICAgICAgICBhc3NlcnRUcnVlKCJsaXN0IGl0ZXJhdG9yIG5leHQoKTIiLCBsaS5uZXh0KCkgPT0gbGlzdC5nZXQoMCkpOworICAgICAgICBsaS5yZW1vdmUoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibGlzdCBpdGVyYXRvciBoYXNQcmV2aW91cygpMyIsICFsaS5oYXNQcmV2aW91cygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibGlzdCBpdGVyYXRvciBoYXNOZXh0KCkzIiwgbGkuaGFzTmV4dCgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgibGlzdCBpdGVyYXRvciBzaXplKCkiLCBsaXN0LnNpemUoKSA9PSBvcmdTaXplKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJsaXN0IGl0ZXJhdG9yIG5leHRJbmRleCgpMyIsIDAsIGxpLm5leHRJbmRleCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJsaXN0IGl0ZXJhdG9yIHByZXZpb3VzSW5kZXgoKTMiLCAtMSwgbGkucHJldmlvdXNJbmRleCgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X0xvY2FsZS5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9Mb2NhbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42OGYwMWM1Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9Mb2NhbGUuamF2YQpAQCAtMCwwICsxLDMzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKKy8qKgorICogSGVscGVyIGNsYXNzIGZvciB0ZXN0cyB0aGF0IHJlbHkgb24gbG9jYWxlIGRhdGEuCisgKi8KK3B1YmxpYyBjbGFzcyBTdXBwb3J0X0xvY2FsZSB7CisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTG9jYWxlQXZhaWxhYmxlKExvY2FsZSByZXF1aXJlZExvY2FsZSkgeworICAgICAgICBTZXQ8TG9jYWxlPiBsb2NhbGVTZXQgPSBuZXcgSGFzaFNldDxMb2NhbGU+KEFycmF5cy5hc0xpc3QoTG9jYWxlLmdldEF2YWlsYWJsZUxvY2FsZXMoKSkpOworICAgICAgICByZXR1cm4gbG9jYWxlU2V0LmNvbnRhaW5zKHJlcXVpcmVkTG9jYWxlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X01hcFRlc3QyLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X01hcFRlc3QyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDJiNWNiZgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfTWFwVGVzdDIuamF2YQpAQCAtMCwwICsxLDY2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK3B1YmxpYyBjbGFzcyBTdXBwb3J0X01hcFRlc3QyIGV4dGVuZHMgVGVzdENhc2UgeworCisgICAgTWFwPFN0cmluZywgU3RyaW5nPiBtYXA7CisKKyAgICBwdWJsaWMgU3VwcG9ydF9NYXBUZXN0MihNYXA8U3RyaW5nLCBTdHJpbmc+IG0pIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgbWFwID0gbTsKKyAgICAgICAgaWYgKCFtYXAuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBmYWlsKCJNYXAgbXVzdCBiZSBlbXB0eSIpOworICAgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1hcC5wdXQoIm9uZSIsICIxIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInNpemUgc2hvdWxkIGJlIG9uZSIsIDEsIG1hcC5zaXplKCkpOworICAgICAgICAgICAgbWFwLmNsZWFyKCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInNpemUgc2hvdWxkIGJlIHplcm8iLCAwLCBtYXAuc2l6ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBub3QgaGF2ZSBlbnRyaWVzIiwgIW1hcC5lbnRyeVNldCgpLml0ZXJhdG9yKCkKKyAgICAgICAgICAgICAgICAgICAgLmhhc05leHQoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgbm90IGhhdmUga2V5cyIsICFtYXAua2V5U2V0KCkuaXRlcmF0b3IoKQorICAgICAgICAgICAgICAgICAgICAuaGFzTmV4dCgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIlNob3VsZCBub3QgaGF2ZSB2YWx1ZXMiLCAhbWFwLnZhbHVlcygpLml0ZXJhdG9yKCkKKyAgICAgICAgICAgICAgICAgICAgLmhhc05leHQoKSk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtYXAucHV0KCJvbmUiLCAiMSIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJzaXplIHNob3VsZCBiZSBvbmUiLCAxLCBtYXAuc2l6ZSgpKTsKKyAgICAgICAgICAgIG1hcC5yZW1vdmUoIm9uZSIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJzaXplIHNob3VsZCBiZSB6ZXJvIiwgMCwgbWFwLnNpemUoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgbm90IGhhdmUgZW50cmllcyIsICFtYXAuZW50cnlTZXQoKS5pdGVyYXRvcigpCisgICAgICAgICAgICAgICAgICAgIC5oYXNOZXh0KCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiU2hvdWxkIG5vdCBoYXZlIGtleXMiLCAhbWFwLmtleVNldCgpLml0ZXJhdG9yKCkKKyAgICAgICAgICAgICAgICAgICAgLmhhc05leHQoKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJTaG91bGQgbm90IGhhdmUgdmFsdWVzIiwgIW1hcC52YWx1ZXMoKS5pdGVyYXRvcigpCisgICAgICAgICAgICAgICAgICAgIC5oYXNOZXh0KCkpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIH0KKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfTWVzc2FnZUZvcm1hdC5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9NZXNzYWdlRm9ybWF0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTJkNzg3YQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfTWVzc2FnZUZvcm1hdC5qYXZhCkBAIC0wLDAgKzEsMTE5IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS50ZXh0LkRhdGVGb3JtYXQ7CitpbXBvcnQgamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQ7CitpbXBvcnQgamF2YS50ZXh0Lk51bWJlckZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdC5GaWVsZDsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9NZXNzYWdlRm9ybWF0IGV4dGVuZHMgU3VwcG9ydF9Gb3JtYXQgeworCisgICAgcHVibGljIFN1cHBvcnRfTWVzc2FnZUZvcm1hdChTdHJpbmcgcDEpIHsKKyAgICAgICAgc3VwZXIocDEpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB7CisgICAgICAgIHRfZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcigpOworICAgICAgICB0X2Zvcm1hdF93aXRoX0ZpZWxkUG9zaXRpb24oKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CisgICAgICAgIG5ldyBTdXBwb3J0X01lc3NhZ2VGb3JtYXQoIiIpLnJ1blRlc3QoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0X2Zvcm1hdF93aXRoX0ZpZWxkUG9zaXRpb24oKSB7CisKKyAgICAgICAgU3RyaW5nIHBhdHRlcm4gPSAiT24gezQsZGF0ZX0gYXQgezMsdGltZX0sIGhlIGF0ZSB7MixudW1iZXIsIGludGVnZXJ9IGhhbWJ1cmdlcnsyLGNob2ljZSwxI3wxPHN9IGFuZCBkcmFuayB7MSwgbnVtYmVyfSBsaXRyZXMgb2YgY29rZS4gVGhhdCB3YXMgezAsY2hvaWNlLDEjanVzdCBlbm91Z2h8MTxtb3JlIHRoYW4gZW5vdWdofSBmb29kISI7CisgICAgICAgIE1lc3NhZ2VGb3JtYXQgZm9ybWF0ID0gbmV3IE1lc3NhZ2VGb3JtYXQocGF0dGVybiwgTG9jYWxlLlVTKTsKKworICAgICAgICBEYXRlIGRhdGUgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoMjAwNSwgMSwgMjgsIDE0LCAyMCwgMTYpLmdldFRpbWUoKTsKKyAgICAgICAgSW50ZWdlciBoYW1idXJnZXJzID0gbmV3IEludGVnZXIoOCk7CisgICAgICAgIE9iamVjdFtdIG9iamVjdHMgPSBuZXcgT2JqZWN0W10geyBoYW1idXJnZXJzLCBuZXcgRG91YmxlKDMuNSksCisgICAgICAgICAgICAgICAgaGFtYnVyZ2VycywgZGF0ZSwgZGF0ZSB9OworCisgICAgICAgIHN1cGVyLnRleHQgPSAiT24gRmViIDI4LCAyMDA1IGF0IDI6MjA6MTYgUE0sIGhlIGF0ZSA4IGhhbWJ1cmdlcnMgYW5kIGRyYW5rIDMuNSBsaXRyZXMgb2YgY29rZS4gVGhhdCB3YXMgbW9yZSB0aGFuIGVub3VnaCBmb29kISI7CisKKyAgICAgICAgLy8gdGVzdCB3aXRoIE1lc3NhZ2VGb3JtYXQuRmllbGQuQVJHVU1FTlQKKyAgICAgICAgdF9Gb3JtYXRXaXRoRmllbGQoMSwgZm9ybWF0LCBvYmplY3RzLCBudWxsLCBGaWVsZC5BUkdVTUVOVCwgMywgMTUpOworCisgICAgICAgIC8vIHRlc3Qgb3RoZXIgZm9ybWF0IGZpZWxkcyB0aGF0IGFyZSBpbmNsdWRlZCBpbiB0aGUgZm9ybWF0dGVkIHRleHQKKyAgICAgICAgdF9Gb3JtYXRXaXRoRmllbGQoMiwgZm9ybWF0LCBvYmplY3RzLCBudWxsLCBEYXRlRm9ybWF0LkZpZWxkLkFNX1BNLCAwLAorICAgICAgICAgICAgICAgIDApOworICAgICAgICB0X0Zvcm1hdFdpdGhGaWVsZCgzLCBmb3JtYXQsIG9iamVjdHMsIG51bGwsCisgICAgICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLkZSQUNUSU9OLCAwLCAwKTsKKworICAgICAgICAvLyB0ZXN0IGZpZWxkcyB0aGF0IGFyZSBub3QgaW5jbHVkZWQgaW4gdGhlIGZvcm1hdHRlZCB0ZXh0CisgICAgICAgIHRfRm9ybWF0V2l0aEZpZWxkKDQsIGZvcm1hdCwgb2JqZWN0cywgbnVsbCwgRGF0ZUZvcm1hdC5GaWVsZC5FUkEsIDAsIDApOworICAgICAgICB0X0Zvcm1hdFdpdGhGaWVsZCg1LCBmb3JtYXQsIG9iamVjdHMsIG51bGwsCisgICAgICAgICAgICAgICAgTnVtYmVyRm9ybWF0LkZpZWxkLkVYUE9ORU5UX1NJR04sIDAsIDApOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRfZm9ybWF0VG9DaGFyYWN0ZXJJdGVyYXRvcigpIHsKKworICAgICAgICBTdHJpbmcgcGF0dGVybiA9ICJPbiB7NCxkYXRlfSBhdCB7Myx0aW1lfSwgaGUgYXRlIHsyLG51bWJlciwgaW50ZWdlcn0gaGFtYnVyZ2VyezIsY2hvaWNlLDEjfDE8c30gYW5kIGRyYW5rIHsxLCBudW1iZXJ9IGxpdHJlcyBvZiBjb2tlLiBUaGF0IHdhcyB7MCxjaG9pY2UsMSNqdXN0IGVub3VnaHwxPG1vcmUgdGhhbiBlbm91Z2h9IGZvb2QhIjsKKyAgICAgICAgTWVzc2FnZUZvcm1hdCBmb3JtYXQgPSBuZXcgTWVzc2FnZUZvcm1hdChwYXR0ZXJuLCBMb2NhbGUuVVMpOworCisgICAgICAgIERhdGUgZGF0ZSA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigyMDA1LCAxLCAyOCwgMTQsIDIwLCAxNikuZ2V0VGltZSgpOworICAgICAgICBJbnRlZ2VyIGhhbWJ1cmdlcnMgPSBuZXcgSW50ZWdlcig4KTsKKyAgICAgICAgT2JqZWN0W10gb2JqZWN0cyA9IG5ldyBPYmplY3RbXSB7IGhhbWJ1cmdlcnMsIG5ldyBEb3VibGUoMy41KSwKKyAgICAgICAgICAgICAgICBoYW1idXJnZXJzLCBkYXRlLCBkYXRlIH07CisKKyAgICAgICAgdF9Gb3JtYXQoMSwgb2JqZWN0cywgZm9ybWF0LCBnZXRNZXNzYWdlVmVjdG9yMSgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFZlY3RvcjxGaWVsZENvbnRhaW5lcj4gZ2V0TWVzc2FnZVZlY3RvcjEoKSB7CisgICAgICAgIFZlY3RvcjxGaWVsZENvbnRhaW5lcj4gdiA9IG5ldyBWZWN0b3I8RmllbGRDb250YWluZXI+KCk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigzLCA2LCBGaWVsZC5BUkdVTUVOVCwgNCkpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoMywgNiwgRGF0ZUZvcm1hdC5GaWVsZC5NT05USCkpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoNiwgNywgRmllbGQuQVJHVU1FTlQsIDQpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDcsIDksIEZpZWxkLkFSR1VNRU5ULCA0KSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcig3LCA5LCBEYXRlRm9ybWF0LkZpZWxkLkRBWV9PRl9NT05USCkpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoOSwgMTEsIEZpZWxkLkFSR1VNRU5ULCA0KSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigxMSwgMTUsIEZpZWxkLkFSR1VNRU5ULCA0KSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigxMSwgMTUsIERhdGVGb3JtYXQuRmllbGQuWUVBUikpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoMTksIDIwLCBGaWVsZC5BUkdVTUVOVCwgMykpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoMTksIDIwLCBEYXRlRm9ybWF0LkZpZWxkLkhPVVIxKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigyMCwgMjEsIEZpZWxkLkFSR1VNRU5ULCAzKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigyMSwgMjMsIEZpZWxkLkFSR1VNRU5ULCAzKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigyMSwgMjMsIERhdGVGb3JtYXQuRmllbGQuTUlOVVRFKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigyMywgMjQsIEZpZWxkLkFSR1VNRU5ULCAzKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigyNCwgMjYsIEZpZWxkLkFSR1VNRU5ULCAzKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigyNCwgMjYsIERhdGVGb3JtYXQuRmllbGQuU0VDT05EKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigyNiwgMjcsIEZpZWxkLkFSR1VNRU5ULCAzKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigyNywgMjksIEZpZWxkLkFSR1VNRU5ULCAzKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcigyNywgMjksIERhdGVGb3JtYXQuRmllbGQuQU1fUE0pKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDM4LCAzOSwgRmllbGQuQVJHVU1FTlQsIDIpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDM4LCAzOSwgTnVtYmVyRm9ybWF0LkZpZWxkLklOVEVHRVIpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDQ5LCA1MCwgRmllbGQuQVJHVU1FTlQsIDIpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDYxLCA2MiwgRmllbGQuQVJHVU1FTlQsIDEpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDYxLCA2MiwgTnVtYmVyRm9ybWF0LkZpZWxkLklOVEVHRVIpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDYyLCA2MywgRmllbGQuQVJHVU1FTlQsIDEpKTsKKyAgICAgICAgdi5hZGQobmV3IEZpZWxkQ29udGFpbmVyKDYyLCA2MywgTnVtYmVyRm9ybWF0LkZpZWxkLkRFQ0lNQUxfU0VQQVJBVE9SKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcig2MywgNjQsIEZpZWxkLkFSR1VNRU5ULCAxKSk7CisgICAgICAgIHYuYWRkKG5ldyBGaWVsZENvbnRhaW5lcig2MywgNjQsIE51bWJlckZvcm1hdC5GaWVsZC5GUkFDVElPTikpOworICAgICAgICB2LmFkZChuZXcgRmllbGRDb250YWluZXIoOTAsIDEwNiwgRmllbGQuQVJHVU1FTlQsIDApKTsKKyAgICAgICAgcmV0dXJuIHY7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X091dHB1dFN0cmVhbS5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9PdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZTRmYTBmCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9PdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDExMCBAQAorcGFja2FnZSB0ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworLyoqCisgKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiB7QGNvZGUgT3V0cHV0U3RyZWFtfSB0aGF0IHN0b3JlcyB0aGUgd3JpdHRlbiBkYXRhIGluIGEKKyAqIGJ5dGUgYXJyYXkgb2YgZml4ZWQgc2l6ZS4gQXMgYSBzcGVjaWFsIGZlYXR1cmUsIGluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIGNhbgorICogYmUgaW5zdHJ1Y3RlZCB0byB0aHJvdyBhbiB7QGNvZGUgSU9FeGNlcHRpb259IHdoZW5ldmVyIGEgbWV0aG9kIGlzIGNhbGxlZC4KKyAqIFRoaXMgaXMgdXNlZCB0byB0ZXN0IHRoZSB7QGNvZGUgSU9FeGNlcHRpb259IGhhbmRsaW5nIG9mIGNsYXNzZXMgdGhhdCB3cml0ZQorICogdG8gYW4ge0Bjb2RlIE91dHB1dFN0cmVhbX0uCisgKi8KK3B1YmxpYyBjbGFzcyBTdXBwb3J0X091dHB1dFN0cmVhbSBleHRlbmRzIE91dHB1dFN0cmVhbSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9CVUZGRVJfU0laRSA9IDMyOworCisgICAgcHJpdmF0ZSBieXRlW10gYnVmZmVyOworCisgICAgcHJpdmF0ZSBpbnQgcG9zaXRpb247CisKKyAgICBwcml2YXRlIGludCBzaXplOworCisgICAgcHJpdmF0ZSBib29sZWFuIHRocm93c0V4Y2VwdGlvbjsKKworICAgIHB1YmxpYyBTdXBwb3J0X091dHB1dFN0cmVhbSgpIHsKKyAgICAgICAgdGhpcyhERUZBVUxUX0JVRkZFUl9TSVpFKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3VwcG9ydF9PdXRwdXRTdHJlYW0oYm9vbGVhbiB0aHJvd0V4Y2VwdGlvbikgeworICAgICAgICB0aGlzKERFRkFVTFRfQlVGRkVSX1NJWkUpOworICAgICAgICB0aHJvd3NFeGNlcHRpb24gPSB0aHJvd0V4Y2VwdGlvbjsKKyAgICB9CisKKyAgICBwdWJsaWMgU3VwcG9ydF9PdXRwdXRTdHJlYW0oaW50IGJ1ZmZlclNpemUpIHsKKyAgICAgICAgYnVmZmVyID0gbmV3IGJ5dGVbYnVmZmVyU2l6ZV07CisgICAgICAgIHBvc2l0aW9uID0gMDsKKyAgICAgICAgc2l6ZSA9IGJ1ZmZlclNpemU7CisgICAgICAgIHRocm93c0V4Y2VwdGlvbiA9IGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRocm93c0V4Y2VwdGlvbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJFeGNlcHRpb24gdGhyb3duIGZvciB0ZXN0aW5nIHB1cnBvc2VzLiIpOworICAgICAgICB9CisgICAgICAgIHN1cGVyLmNsb3NlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGhyb3dzRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkV4Y2VwdGlvbiB0aHJvd24gZm9yIHRlc3RpbmcgcHVycG9zZXMuIik7CisgICAgICAgIH0KKyAgICAgICAgc3VwZXIuZmx1c2goKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlIGJ1ZmZlcltdKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGhyb3dzRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkV4Y2VwdGlvbiB0aHJvd24gZm9yIHRlc3RpbmcgcHVycG9zZXMuIik7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBidWZmZXIubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIHdyaXRlKGJ1ZmZlcltpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlIGJ1ZmZlcltdLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0aHJvd3NFeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRXhjZXB0aW9uIHRocm93biBmb3IgdGVzdGluZyBwdXJwb3Nlcy4iKTsKKyAgICAgICAgfQorICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBjb3VudCA8IDAgfHwgKG9mZnNldCArIGNvdW50KSA+IGJ1ZmZlci5sZW5ndGgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IG9mZnNldDsgaSA8IG9mZnNldCArIGNvdW50OyBpKyspIHsKKyAgICAgICAgICAgIHdyaXRlKGJ1ZmZlcltpXSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgb25lQnl0ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRocm93c0V4Y2VwdGlvbikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJFeGNlcHRpb24gdGhyb3duIGZvciB0ZXN0aW5nIHB1cnBvc2VzLiIpOworICAgICAgICB9CisgICAgICAgIGlmIChwb3NpdGlvbiA8IHNpemUpIHsKKyAgICAgICAgICAgIGJ1ZmZlcltwb3NpdGlvbl0gPSAoYnl0ZSkob25lQnl0ZSAmIDI1NSk7CisgICAgICAgICAgICBwb3NpdGlvbisrOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbnRlcm5hbCBidWZmZXIgb3ZlcmZsb3cuIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIHRvQnl0ZUFycmF5KCkgeworICAgICAgICBieXRlW10gdG9SZXR1cm4gPSBuZXcgYnl0ZVtwb3NpdGlvbl07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCAwLCB0b1JldHVybiwgMCwgcG9zaXRpb24pOworICAgICAgICByZXR1cm4gdG9SZXR1cm47CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoYnVmZmVyLCAwLCBwb3NpdGlvbik7CisgICAgfQorCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICByZXR1cm4gcG9zaXRpb247CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGhyb3dzRXhjZXB0aW9uKGJvb2xlYW4gbmV3VmFsdWUpIHsKKyAgICAgICAgdGhyb3dzRXhjZXB0aW9uID0gbmV3VmFsdWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9QbGF0Zm9ybUZpbGUuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfUGxhdGZvcm1GaWxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTQ4NmIyMAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfUGxhdGZvcm1GaWxlLmphdmEKQEAgLTAsMCArMSwzNiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworcHVibGljIGNsYXNzIFN1cHBvcnRfUGxhdGZvcm1GaWxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBwbGF0Zm9ybUlkID0gbnVsbDsKKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldE5ld1BsYXRmb3JtRmlsZShTdHJpbmcgcHJlLCBTdHJpbmcgcG9zdCkgeworICAgICAgICBpZiAocGxhdGZvcm1JZCA9PSBudWxsKSB7CisgICAgICAgICAgICBTdHJpbmcgcHJvcGVydHkgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImNvbS5pYm0ub3RpLmNvbmZpZ3VyYXRpb24iKTsKKyAgICAgICAgICAgIGlmIChwcm9wZXJ0eSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcHJvcGVydHkgPSAiSkRLIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBsYXRmb3JtSWQgPSBwcm9wZXJ0eQorICAgICAgICAgICAgICAgICAgICArIFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS52bS52ZXJzaW9uIikucmVwbGFjZSgnLicsICctJyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHByZSArIHBsYXRmb3JtSWQgKyBwb3N0OworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9Qb3J0TWFuYWdlci5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9Qb3J0TWFuYWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlkMmZkODYKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1BvcnRNYW5hZ2VyLmphdmEKQEAgLTAsMCArMSwxMDUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLm5ldC5EYXRhZ3JhbVNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5TZXJ2ZXJTb2NrZXQ7CitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5UaW1lWm9uZTsKKworLyoqCisgKiBUaGUgcG9ydCBtYW5hZ2VyIGlzIHN1cHBvc2VkIHRvIGhlbHAgZmluZGluZyBhIGZyZWUKKyAqIG5ldHdvcmsgcG9ydCBvbiB0aGUgbWFjaGluZTsgaG93ZXZlciwgaXQgdXNlcyBzdHJhbmdlCisgKiBsb2dpYywgc28gbGVhdmUgaXQgdG8gdGhlIE9TLgorICoKKyAqIEBkZXByZWNhdGVkIFVzZSBPUyB0byBmaW5kIGZyZWUgcG9ydHMuCisgKi8KK3B1YmxpYyBjbGFzcyBTdXBwb3J0X1BvcnRNYW5hZ2VyIHsKKworICAgIHByaXZhdGUgc3RhdGljIGludCBsYXN0QXNzaWduZWRQb3J0ID0gc29tZXdoYXRSYW5kb21Qb3J0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBmYWlsZWRPbmNlID0gZmFsc2U7CisKKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBpbnQgZ2V0TmV4dFBvcnQoKSB7CisgICAgICAgIGlmICghZmFpbGVkT25jZSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTZXJ2ZXJTb2NrZXQgc3MgPSBuZXcgU2VydmVyU29ja2V0KDApOworICAgICAgICAgICAgICAgIGludCBwb3J0ID0gc3MuZ2V0TG9jYWxQb3J0KCk7CisKKyAgICAgICAgICAgICAgICBzcy5jbG9zZSgpOworICAgICAgICAgICAgICAgIHJldHVybiBwb3J0OworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgZmFpbGVkT25jZSA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGdldE5leHRQb3J0X3Vuc2FmZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgMSBmcmVlIHBvcnRzIHRvIGJlIHVzZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgaW50IGdldE5leHRQb3J0Rm9yVURQKCkgeworICAgICAgICByZXR1cm4gZ2V0TmV4dFBvcnRzRm9yVURQKDEpWzBdOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgZnJlZSBwb3J0cyB0byBiZSB1c2VkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIGludFtdIGdldE5leHRQb3J0c0ZvclVEUChpbnQgbnVtKSB7CisgICAgICAgIGlmIChudW0gPD0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBwb3J0cyBudW1iZXI6ICIgKyBudW0pOworICAgICAgICB9CisgICAgICAgIERhdGFncmFtU29ja2V0W10gZHNzID0gbmV3IERhdGFncmFtU29ja2V0W251bV07CisgICAgICAgIGludFtdIHBvcnRzID0gbmV3IGludFtudW1dOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bTsgKytpKSB7CisgICAgICAgICAgICAgICAgZHNzW2ldID0gbmV3IERhdGFncmFtU29ja2V0KDApOworICAgICAgICAgICAgICAgIHBvcnRzW2ldID0gZHNzW2ldLmdldExvY2FsUG9ydCgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiVW5hYmxlIHRvIGdldCAiICsgbnVtICsgIiBwb3J0cyBmb3IgVURQOiAiICsgZXgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW07ICsraSkgeworICAgICAgICAgICAgICAgIGlmIChkc3NbaV0gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBkc3NbaV0uY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHBvcnRzOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIGludCBnZXROZXh0UG9ydF91bnNhZmUoKSB7CisgICAgICAgIGlmICgrK2xhc3RBc3NpZ25lZFBvcnQgPiA2NTUzNCkgeworICAgICAgICAgICAgbGFzdEFzc2lnbmVkUG9ydCA9IDYwMDA7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGxhc3RBc3NpZ25lZFBvcnQ7CisgICAgfQorCisgICAgLyoKKyAgICAgICogUmV0dXJucyBhIGRpZmZlcmVudCBwb3J0IG51bWJlciBldmVyeSA2IHNlY29uZHMgb3Igc28uIFRoZSBwb3J0IG51bWJlcgorICAgICAgKiBzaG91bGQgYmUgYWJvdXQgKz0gMTAwIGF0IGVhY2ggNiBzZWNvbmQgaW50ZXJ2YWwKKyAgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHNvbWV3aGF0UmFuZG9tUG9ydCgpIHsKKyAgICAgICAgQ2FsZW5kYXIgYyA9IENhbGVuZGFyLmdldEluc3RhbmNlKFRpbWVab25lLmdldFRpbWVab25lKCJVVEMiKSk7CisgICAgICAgIGludCBtaW51dGVzID0gYy5nZXQoQ2FsZW5kYXIuTUlOVVRFKTsKKyAgICAgICAgaW50IHNlY29uZHMgPSBjLmdldChDYWxlbmRhci5TRUNPTkQpOworCisgICAgICAgIHJldHVybiA2MDAwICsgKDEwMDAgKiBtaW51dGVzKSArICgoc2Vjb25kcyAvIDYpICogMTAwKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfUHJvdmlkZXJUcnVzdC5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9Qcm92aWRlclRydXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWM0N2UxMAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfUHJvdmlkZXJUcnVzdC5qYXZhCkBAIC0wLDAgKzEsOTMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJvdmlkZXI7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGEgZHVtbXkgcHJvdmlkZXIuCisgKgorICovCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9Qcm92aWRlclRydXN0IGV4dGVuZHMgUHJvdmlkZXIgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgLy8gUHJvdmlkZXIgbmFtZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FID0gIlByb3ZpZGVyVHJ1c3QiOworCisgICAgLy8gVmVyc2lvbiBvZiB0aGUgc2VydmljZXMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBkb3VibGUgVkVSU0lPTiA9IDEuMDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBJTkZPID0gTkFNRQorICAgICAgICAgICAgKyAiIERTQSBrZXksIHBhcmFtZXRlciBnZW5lcmF0aW9uIGFuZCBzaWduaW5nOyBTSEEtMSBkaWdlc3Q7IFNIQTFQUk5HIFNlY3VyZVJhbmRvbSI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBkdW1teSBwcm92aWRlci4KKyAgICAgKgorICAgICAqLworICAgIHB1YmxpYyBTdXBwb3J0X1Byb3ZpZGVyVHJ1c3QoKSB7CisgICAgICAgIHN1cGVyKE5BTUUsIFZFUlNJT04sIElORk8pOworICAgICAgICByZWdpc3RlclNlcnZpY2VzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVnaXN0ZXIgdGhlIHNlcnZpY2VzIHRoZSByZWNlaXZlciBwcm92aWRlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVnaXN0ZXJTZXJ2aWNlcygpIHsKKyAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb248Vm9pZD4oKSB7CisgICAgICAgICAgICBwdWJsaWMgVm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgLy8gRGlnZXN0IGVuZ2luZQorICAgICAgICAgICAgICAgIHB1dCgiTWVzc2FnZURpZ2VzdC5TSEEiLAorICAgICAgICAgICAgICAgICAgICAgICAgIm1hZGUudXAucHJvdmlkZXIubmFtZS5NZXNzYWdlRGlnZXN0U0hBIik7CisgICAgICAgICAgICAgICAgcHV0KCJNZXNzYWdlRGlnZXN0Lk1ENSIsCisgICAgICAgICAgICAgICAgICAgICAgICAibWFkZS51cC5wcm92aWRlci5uYW1lLk1lc3NhZ2VEaWdlc3RNRDUiKTsKKworICAgICAgICAgICAgICAgIC8vIEFsZ29yaXRobSBwYXJhbWV0ZXIgZ2VuZXJhdG9yCisgICAgICAgICAgICAgICAgcHV0KCJBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IuRFNBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJtYWRlLnVwLnByb3ZpZGVyLm5hbWUuQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yRFNBIik7CisKKyAgICAgICAgICAgICAgICAvLyBBbGdvcml0aG0gcGFyYW1ldGVycworICAgICAgICAgICAgICAgIHB1dCgiQWxnb3JpdGhtUGFyYW1ldGVycy5EU0EiLAorICAgICAgICAgICAgICAgICAgICAgICAgIm1hZGUudXAucHJvdmlkZXIubmFtZS5BbGdvcml0aG1QYXJhbWV0ZXJzRFNBIik7CisKKyAgICAgICAgICAgICAgICAvLyBLZXkgcGFpciBnZW5lcmF0b3IKKyAgICAgICAgICAgICAgICBwdXQoIktleVBhaXJHZW5lcmF0b3IuRFNBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJtYWRlLnVwLnByb3ZpZGVyLm5hbWUuS2V5UGFpckdlbmVyYXRvckRTQSIpOworCisgICAgICAgICAgICAgICAgLy8gS2V5IGZhY3RvcnkKKyAgICAgICAgICAgICAgICBwdXQoIktleUZhY3RvcnkuRFNBIiwgIm1hZGUudXAucHJvdmlkZXIubmFtZS5LZXlGYWN0b3J5RFNBIik7CisgICAgICAgICAgICAgICAgcHV0KCJLZXlGYWN0b3J5LlJTQSIsICJtYWRlLnVwLnByb3ZpZGVyLm5hbWUuS2V5RmFjdG9yeVJTQSIpOworCisgICAgICAgICAgICAgICAgLy8gU2lnbmF0dXJlIGFsZ29yaXRobQorICAgICAgICAgICAgICAgIHB1dCgiU2lnbmF0dXJlLlNIQTF3aXRoRFNBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJtYWRlLnVwLnByb3ZpZGVyLm5hbWUuU2lnbmF0dXJlRFNBIik7CisKKyAgICAgICAgICAgICAgICAvLyBLZXlTdG9yZQorICAgICAgICAgICAgICAgIHB1dCgiS2V5U3RvcmUuUEtDUyMxMi9OZXRzY2FwZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAibWFkZS51cC5wcm92aWRlci5uYW1lLktleVN0b3JlIik7CisKKyAgICAgICAgICAgICAgICAvLyBDZXJ0aWZpY2F0ZQorICAgICAgICAgICAgICAgIHB1dCgiQ2VydGlmaWNhdGVGYWN0b3J5Llg1MDkiLAorICAgICAgICAgICAgICAgICAgICAgICAgIm1hZGUudXAucHJvdmlkZXIubmFtZS5DZXJ0aWZpY2F0ZUZhY3RvcnlYNTA5Iik7CisKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfUHJveHlfSTEuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfUHJveHlfSTEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNjdjOGFjCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9Qcm94eV9JMS5qYXZhCkBAIC0wLDAgKzEsMjggQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK3B1YmxpYyBpbnRlcmZhY2UgU3VwcG9ydF9Qcm94eV9JMSB7CisgICAgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pOworCisgICAgaW50W10gYXJyYXkobG9uZ1tdIGYpOworCisgICAgdm9pZCBmb28oaW50IGksIGJvb2xlYW4gYik7CisKKyAgICBTdHJpbmcgc3RyaW5nKFN0cmluZyBzKSB0aHJvd3MgU3VwcG9ydF9Qcm94eV9QYXJlbnRFeGNlcHRpb24sIExpbmthZ2VFcnJvcjsKK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfUHJveHlfSTIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfUHJveHlfSTIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNGIwZGQxCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9Qcm94eV9JMi5qYXZhCkBAIC0wLDAgKzEsMjcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK3B1YmxpYyBpbnRlcmZhY2UgU3VwcG9ydF9Qcm94eV9JMiB7CisKKyAgICBpbnRbXSBhcnJheShsb25nW10gZik7CisKKyAgICB2b2lkIGZvbyhib29sZWFuIGIsIGludCBpKTsKKworICAgIFN0cmluZyBzdHJpbmcoU3RyaW5nIHMpIHRocm93cyBTdXBwb3J0X1Byb3h5X1N1YkV4Y2VwdGlvbiwgRXJyb3I7Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1Byb3h5X1BhcmVudEV4Y2VwdGlvbi5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9Qcm94eV9QYXJlbnRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYzE1YjgxCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9Qcm94eV9QYXJlbnRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDIyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zdXBwb3J0OworCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9Qcm94eV9QYXJlbnRFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yNzYwMTUxODQ1NDEwODg3MDM4TDsKK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfUHJveHlfU3ViRXhjZXB0aW9uLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1Byb3h5X1N1YkV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk1YzIzYjQKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1Byb3h5X1N1YkV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMjMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK3B1YmxpYyBjbGFzcyBTdXBwb3J0X1Byb3h5X1N1YkV4Y2VwdGlvbiBleHRlbmRzIFN1cHBvcnRfUHJveHlfUGFyZW50RXhjZXB0aW9uIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjYxNTQ3MjkyNTgyNjU0MjkyNUw7CisKK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfU2V0VGVzdC5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9TZXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTRhMTQzMgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfU2V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsNDggQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9TZXRUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlIHsKKworICAgIFNldDxJbnRlZ2VyPiBzZXQ7IC8vIG11c3QgY29udGFpbiBvbmx5IHRoZSBJbnRlZ2VycyAwIHRvIDk5CisKKyAgICBwdWJsaWMgU3VwcG9ydF9TZXRUZXN0KFN0cmluZyBwMSkgeworICAgICAgICBzdXBlcihwMSk7CisgICAgfQorCisgICAgcHVibGljIFN1cHBvcnRfU2V0VGVzdChTdHJpbmcgcDEsIFNldDxJbnRlZ2VyPiBzKSB7CisgICAgICAgIHN1cGVyKHAxKTsKKyAgICAgICAgc2V0ID0gczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgeworICAgICAgICAvLyBhZGQKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiU2V0IFRlc3QgLSBBZGRpbmcgYSBkdXBsaWNhdGUgZWxlbWVudCBjaGFuZ2VkIHRoZSBzZXQiLAorICAgICAgICAgICAgICAgICFzZXQuYWRkKG5ldyBJbnRlZ2VyKDUwKSkpOworICAgICAgICBhc3NlcnRUcnVlKCJTZXQgVGVzdCAtIFJlbW92aW5nIGFuIGVsZW1lbnQgZGlkIG5vdCBjaGFuZ2UgdGhlIHNldCIsIHNldAorICAgICAgICAgICAgICAgIC5yZW1vdmUobmV3IEludGVnZXIoNTApKSk7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIlNldCBUZXN0IC0gQWRkaW5nIGFuZCByZW1vdmluZyBhIGR1cGxpY2F0ZSBlbGVtZW50IGZhaWxlZCB0byByZW1vdmUgaXQiLAorICAgICAgICAgICAgICAgICFzZXQuY29udGFpbnMobmV3IEludGVnZXIoNTApKSk7CisgICAgICAgIHNldC5hZGQobmV3IEludGVnZXIoNTApKTsKKyAgICAgICAgbmV3IFN1cHBvcnRfQ29sbGVjdGlvblRlc3QoIiIsIHNldCkucnVuVGVzdCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfU3RyaW5nUmVhZGVyLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1N0cmluZ1JlYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdmZmNhYTEKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1N0cmluZ1JlYWRlci5qYXZhCkBAIC0wLDAgKzEsMjQ3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlJlYWRlcjsKKworcHVibGljIGNsYXNzIFN1cHBvcnRfU3RyaW5nUmVhZGVyIGV4dGVuZHMgUmVhZGVyIHsKKyAgICBwcml2YXRlIFN0cmluZyBzdHI7CisKKyAgICBwcml2YXRlIGludCBtYXJrcG9zID0gLTE7CisKKyAgICBwcml2YXRlIGludCBwb3MgPSAwOworCisgICAgcHJpdmF0ZSBpbnQgY291bnQ7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBTdHJpbmdSZWFkZXIgb24gdGhlIFN0cmluZyA8Y29kZT5zdHI8L2NvZGU+LiBUaGUgc2l6ZSBvZgorICAgICAqIHRoZSByZWFkZXIgaXMgc2V0IHRvIHRoZSA8Y29kZT5sZW5ndGgoKTwvY29kZT4gb2YgdGhlIFN0cmluZyBhbmQgdGhlCisgICAgICogT2JqZWN0IHRvIHN5bmNocm9uaXplIGFjY2VzcyB0aHJvdWdoIGlzIHNldCB0byA8Y29kZT5zdHI8L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgdGhlIFN0cmluZyB0byBmaWx0ZXIgcmVhZHMgb24uCisgICAgICovCisgICAgcHVibGljIFN1cHBvcnRfU3RyaW5nUmVhZGVyKFN0cmluZyBzdHIpIHsKKyAgICAgICAgc3VwZXIoc3RyKTsKKyAgICAgICAgdGhpcy5zdHIgPSBzdHI7CisgICAgICAgIHRoaXMuY291bnQgPSBzdHIubGVuZ3RoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgY2xvc2VzIHRoaXMgU3RyaW5nUmVhZGVyLiBPbmNlIGl0IGlzIGNsb3NlZCwgeW91IGNhbiBubworICAgICAqIGxvbmdlciByZWFkIGZyb20gaXQuIE9ubHkgdGhlIGZpcnN0IGludm9jYXRpb24gb2YgdGhpcyBtZXRob2QgaGFzIGFueQorICAgICAqIGVmZmVjdC4KKyAgICAgKgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGlmIChpc09wZW4oKSkgeworICAgICAgICAgICAgICAgIHN0ciA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbnN3ZXIgYSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciBvciBub3QgdGhpcyBTdHJpbmdSZWFkZXIgaXMgb3Blbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNPcGVuKCkgeworICAgICAgICByZXR1cm4gc3RyICE9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IGEgTWFyayBwb3NpdGlvbiBpbiB0aGlzIFJlYWRlci4gVGhlIHBhcmFtZXRlciA8Y29kZT5yZWFkTGltaXQ8L2NvZGU+CisgICAgICogaXMgaWdub3JlZCBmb3IgU3RyaW5nUmVhZGVycy4gU2VuZGluZyByZXNldCgpIHdpbGwgcmVwb3NpdGlvbiB0aGUgcmVhZGVyCisgICAgICogYmFjayB0byB0aGUgbWFya2VkIHBvc2l0aW9uIHByb3ZpZGVkIHRoZSBtYXJrIGhhcyBub3QgYmVlbiBpbnZhbGlkYXRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWFkbGltaXQKKyAgICAgKiAgICAgICAgICAgIGlnbm9yZWQgZm9yIFN0cmluZ1JlYWRlcnMuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBJZiBhbiBlcnJvciBvY2N1cnMgYXR0ZW1wdGluZyBtYXJrIHRoaXMgU3RyaW5nUmVhZGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIG1hcmsoaW50IHJlYWRMaW1pdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHJlYWRMaW1pdCA+PSAwKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgICAgICBpZiAoaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgbWFya3BvcyA9IHBvczsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlN0cmluZ1JlYWRlciBpcyBjbG9zZWQiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbnN3ZXJzIGEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgb3Igbm90IHRoaXMgU3RyaW5nUmVhZGVyIHN1cHBvcnRzCisgICAgICogbWFyaygpIGFuZCByZXNldCgpLiBUaGlzIG1ldGhvZCBhbHdheXMgcmV0dXJucyB0cnVlLgorICAgICAqCisgICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiBtYXJrKCkgYW5kIHJlc2V0KCkgYXJlIHN1cHBvcnRlZCwKKyAgICAgKiAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuIFRoaXMgaW1wbGVtZW50YXRpb24gYWx3YXlzCisgICAgICogICAgICAgICByZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hcmtTdXBwb3J0ZWQoKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGEgc2luZ2xlIGNoYXJhY3RlciBmcm9tIHRoaXMgU3RyaW5nUmVhZGVyIGFuZCByZXR1cm5zIHRoZSByZXN1bHQgYXMKKyAgICAgKiBhbiBpbnQuIFRoZSAyIGhpZ2hlci1vcmRlciBieXRlcyBhcmUgc2V0IHRvIDAuIElmIHRoZSBlbmQgb2YgcmVhZGVyIHdhcworICAgICAqIGVuY291bnRlcmVkIHRoZW4gcmV0dXJuIC0xLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgY2hhcmFjdGVyIHJlYWQgb3IgLTEgaWYgZW5kIG9mIHJlYWRlci4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gamF2YS5pby5JT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIElmIHRoZSBTdHJpbmdSZWFkZXIgaXMgYWxyZWFkeSBjbG9zZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBpZiAoaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICBpZiAocG9zICE9IGNvdW50KSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHIuY2hhckF0KHBvcysrKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJTdHJpbmdSZWFkZXIgaXMgY2xvc2VkIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhdCBtb3N0IDxjb2RlPmNvdW50PC9jb2RlPiBjaGFyYWN0ZXJzIGZyb20gdGhpcyBTdHJpbmdSZWFkZXIgYW5kCisgICAgICogc3RvcmVzIHRoZW0gYXQgPGNvZGU+b2Zmc2V0PC9jb2RlPiBpbiB0aGUgY2hhcmFjdGVyIGFycmF5CisgICAgICogPGNvZGU+YnVmPC9jb2RlPi4gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgYWN0dWFsbHkgcmVhZCBvciAtMQorICAgICAqIGlmIHRoZSBlbmQgb2YgcmVhZGVyIHdhcyBlbmNvdW50ZXJlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBidWYKKyAgICAgKiAgICAgICAgICAgIGNoYXJhY3RlciBhcnJheSB0byBzdG9yZSB0aGUgcmVhZCBjaGFyYWN0ZXJzCisgICAgICogQHBhcmFtIG9mZnNldAorICAgICAqICAgICAgICAgICAgb2Zmc2V0IGluIGJ1ZiB0byBzdG9yZSB0aGUgcmVhZCBjaGFyYWN0ZXJzCisgICAgICogQHBhcmFtIGNvdW50CisgICAgICogICAgICAgICAgICBtYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyByZWFkIG9yIC0xIGlmIGVuZCBvZiByZWFkZXIuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBJZiB0aGUgU3RyaW5nUmVhZGVyIGlzIGNsb3NlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoY2hhciBidWZbXSwgaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBhdm9pZCBpbnQgb3ZlcmZsb3cKKyAgICAgICAgaWYgKDAgPD0gb2Zmc2V0ICYmIG9mZnNldCA8PSBidWYubGVuZ3RoICYmIDAgPD0gY291bnQKKyAgICAgICAgICAgICAgICAmJiBjb3VudCA8PSBidWYubGVuZ3RoIC0gb2Zmc2V0KSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgICAgICBpZiAoaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHBvcyA9PSB0aGlzLmNvdW50KSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaW50IGVuZCA9IHBvcyArIGNvdW50ID4gdGhpcy5jb3VudCA/IHRoaXMuY291bnQgOiBwb3MKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGNvdW50OworICAgICAgICAgICAgICAgICAgICBzdHIuZ2V0Q2hhcnMocG9zLCBlbmQsIGJ1Ziwgb2Zmc2V0KTsKKyAgICAgICAgICAgICAgICAgICAgaW50IHJlYWQgPSBlbmQgLSBwb3M7CisgICAgICAgICAgICAgICAgICAgIHBvcyA9IGVuZDsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU3RyaW5nUmVhZGVyIGlzIGNsb3NlZCIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbnN3ZXJzIGEgPGNvZGU+Ym9vbGVhbjwvY29kZT4gaW5kaWNhdGluZyB3aGV0aGVyIG9yIG5vdCB0aGlzCisgICAgICogU3RyaW5nUmVhZGVyIGlzIHJlYWR5IHRvIGJlIHJlYWQgd2l0aG91dCBibG9ja2luZy4gSWYgdGhlIHJlc3VsdCBpcworICAgICAqIDxjb2RlPnRydWU8L2NvZGU+LCB0aGUgbmV4dCA8Y29kZT5yZWFkKCk8L2NvZGU+IHdpbGwgbm90IGJsb2NrLiBJZgorICAgICAqIHRoZSByZXN1bHQgaXMgPGNvZGU+ZmFsc2U8L2NvZGU+IHRoaXMgUmVhZGVyIG1heSBvciBtYXkgbm90IGJsb2NrIHdoZW4KKyAgICAgKiA8Y29kZT5yZWFkKCk8L2NvZGU+IGlzIHNlbnQuIFRoZSBpbXBsZW1lbnRhdGlvbiBpbiBTdHJpbmdSZWFkZXIgYWx3YXlzCisgICAgICogcmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBldmVuIHdoZW4gaXQgaGFzIGJlZW4gY2xvc2VkLgorICAgICAqCisgICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgcmVjZWl2ZXIgd2lsbCBub3QgYmxvY2sgd2hlbgorICAgICAqICAgICAgICAgPGNvZGU+cmVhZCgpPC9jb2RlPiBpcyBjYWxsZWQsIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiB1bmtub3duCisgICAgICogICAgICAgICBvciBibG9ja2luZyB3aWxsIG9jY3VyLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBqYXZhLmlvLklPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgICAgSWYgYW4gSU8gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIHJlYWR5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBpZiAoaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU3RyaW5nUmVhZGVyIGlzIGNsb3NlZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzZXQgdGhpcyBTdHJpbmdSZWFkZXIncyBwb3NpdGlvbiB0byB0aGUgbGFzdCA8Y29kZT5tYXJrKCk8L2NvZGU+CisgICAgICogbG9jYXRpb24uIEludm9jYXRpb25zIG9mIDxjb2RlPnJlYWQoKS9za2lwKCk8L2NvZGU+IHdpbGwgb2NjdXIgZnJvbQorICAgICAqIHRoaXMgbmV3IGxvY2F0aW9uLiBJZiB0aGlzIFJlYWRlciB3YXMgbm90IG1hcmtlZCwgdGhlIFN0cmluZ1JlYWRlciBpcworICAgICAqIHJlc2V0IHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIFN0cmluZy4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gamF2YS5pby5JT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIElmIHRoaXMgU3RyaW5nUmVhZGVyIGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBpZiAoaXNPcGVuKCkpIHsKKyAgICAgICAgICAgICAgICBwb3MgPSBtYXJrcG9zICE9IC0xID8gbWFya3BvcyA6IDA7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU3RyaW5nUmVhZGVyIGlzIGNsb3NlZCIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcHMgPGNvZGU+Y291bnQ8L2NvZGU+IG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIHRoaXMgU3RyaW5nUmVhZGVyLgorICAgICAqIFN1YnNlcXVlbnQgPGNvZGU+cmVhZCgpPC9jb2RlPidzIHdpbGwgbm90IHJldHVybiB0aGVzZSBjaGFyYWN0ZXJzCisgICAgICogdW5sZXNzIDxjb2RlPnJlc2V0KCk8L2NvZGU+IGlzIHVzZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBza2lwLgorICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGFjdHVhbGx5IHNraXBwZWQuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBJZiB0aGlzIFN0cmluZ1JlYWRlciBoYXMgYWxyZWFkeSBiZWVuIGNsb3NlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBza2lwKGxvbmcgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgaWYgKGlzT3BlbigpKSB7CisgICAgICAgICAgICAgICAgaWYgKGNvdW50IDw9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGxvbmcgc2tpcHBlZCA9IDA7CisgICAgICAgICAgICAgICAgaWYgKGNvdW50IDwgdGhpcy5jb3VudCAtIHBvcykgeworICAgICAgICAgICAgICAgICAgICBwb3MgPSBwb3MgKyAoaW50KSBjb3VudDsKKyAgICAgICAgICAgICAgICAgICAgc2tpcHBlZCA9IGNvdW50OworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHNraXBwZWQgPSB0aGlzLmNvdW50IC0gcG9zOworICAgICAgICAgICAgICAgICAgICBwb3MgPSB0aGlzLmNvdW50OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gc2tpcHBlZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU3RyaW5nUmVhZGVyIGlzIGNsb3NlZCIpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9TdHJpbmdXcml0ZXIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfU3RyaW5nV3JpdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjlkZjAzYQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfU3RyaW5nV3JpdGVyLmphdmEKQEAgLTAsMCArMSwxNzggQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uV3JpdGVyOworCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9TdHJpbmdXcml0ZXIgZXh0ZW5kcyBXcml0ZXIgeworICAgIHByaXZhdGUgU3RyaW5nQnVmZmVyIGJ1ZjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgU3RyaW5nV3JpdGVyIHdoaWNoIGhhcyBhIFN0cmluZ0J1ZmZlciBhbGxvY2F0ZWQgd2l0aCB0aGUKKyAgICAgKiBkZWZhdWx0IHNpemUgb2YgMTYgY2hhcmFjdGVycy4gVGhlIFN0cmluZ0J1ZmZlciBpcyBhbHNvIHRoZQorICAgICAqIDxjb2RlPmxvY2s8L2NvZGU+IHVzZWQgdG8gc3luY2hyb25pemUgYWNjZXNzIHRvIHRoaXMgV3JpdGVyLgorICAgICAqLworICAgIHB1YmxpYyBTdXBwb3J0X1N0cmluZ1dyaXRlcigpIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigxNik7CisgICAgICAgIGxvY2sgPSBidWY7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBTdHJpbmdXcml0ZXIgd2hpY2ggaGFzIGEgU3RyaW5nQnVmZmVyIGFsbG9jYXRlZCB3aXRoIHRoZQorICAgICAqIHNpemUgb2YgPGNvZGU+aW5pdGlhbFNpemU8L2NvZGU+IGNoYXJhY3RlcnMuIFRoZSBTdHJpbmdCdWZmZXIgaXMgYWxzbworICAgICAqIHRoZSA8Y29kZT5sb2NrPC9jb2RlPiB1c2VkIHRvIHN5bmNocm9uaXplIGFjY2VzcyB0byB0aGlzIFdyaXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3VwcG9ydF9TdHJpbmdXcml0ZXIoaW50IGluaXRpYWxTaXplKSB7CisgICAgICAgIGlmIChpbml0aWFsU2l6ZSA+PSAwKSB7CisgICAgICAgICAgICBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKGluaXRpYWxTaXplKTsKKyAgICAgICAgICAgIGxvY2sgPSBidWY7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZSB0aGlzIFdyaXRlci4gVGhpcyBpcyB0aGUgY29uY3JldGUgaW1wbGVtZW50YXRpb24gcmVxdWlyZWQuIFRoaXMKKyAgICAgKiBwYXJ0aWN1bGFyIGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZy4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gamF2YS5pby5JT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIElmIGFuIElPIGVycm9yIG9jY3VycyBjbG9zaW5nIHRoaXMgU3RyaW5nV3JpdGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGbHVzaCB0aGlzIFdyaXRlci4gVGhpcyBpcyB0aGUgY29uY3JldGUgaW1wbGVtZW50YXRpb24gcmVxdWlyZWQuIFRoaXMKKyAgICAgKiBwYXJ0aWN1bGFyIGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZy4KKyAgICAgKgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEFuc3dlciB0aGUgY29udGVudHMgb2YgdGhpcyBTdHJpbmdXcml0ZXIgYXMgYSBTdHJpbmdCdWZmZXIuIEFueSBjaGFuZ2VzCisgICAgICogbWFkZSB0byB0aGUgU3RyaW5nQnVmZmVyIGJ5IHRoZSByZWNlaXZlciBvciB0aGUgY2FsbGVyIGFyZSByZWZsZWN0ZWQgaW4KKyAgICAgKiB0aGlzIFN0cmluZ1dyaXRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhpcyBTdHJpbmdXcml0ZXJzIGxvY2FsIFN0cmluZ0J1ZmZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGdldEJ1ZmZlcigpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICByZXR1cm4gYnVmOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQW5zd2VyIHRoZSBjb250ZW50cyBvZiB0aGlzIFN0cmluZ1dyaXRlciBhcyBhIFN0cmluZy4gQW55IGNoYW5nZXMgbWFkZSB0bworICAgICAqIHRoZSBTdHJpbmdCdWZmZXIgYnkgdGhlIHJlY2VpdmVyIGFmdGVyIHJldHVybmluZyB3aWxsIG5vdCBiZSByZWZsZWN0ZWQgaW4KKyAgICAgKiB0aGUgU3RyaW5nIHJldHVybmVkIHRvIHRoZSBjYWxsZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoaXMgU3RyaW5nV3JpdGVycyBjdXJyZW50IGNvbnRlbnRzIGFzIGEgU3RyaW5nLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIDxjb2RlPmNvdW50PC9jb2RlPiBjaGFyYWN0ZXJzIHN0YXJ0aW5nIGF0IDxjb2RlPm9mZnNldDwvY29kZT4KKyAgICAgKiBpbiA8Y29kZT5idWY8L2NvZGU+IHRvIHRoaXMgU3RyaW5nV3JpdGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGJ1ZgorICAgICAqICAgICAgICAgICAgdGhlIG5vbi1udWxsIGFycmF5IGNvbnRhaW5pbmcgY2hhcmFjdGVycyB0byB3cml0ZS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICBvZmZzZXQgaW4gYnVmIHRvIHJldHJpZXZlIGNoYXJhY3RlcnMKKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gd3JpdGUKKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgICAgIElmIG9mZnNldCBvciBjb3VudCBhcmUgb3V0c2lkZSBvZiBib3VuZHMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoY2hhcltdIGJ1ZiwgaW50IG9mZnNldCwgaW50IGNvdW50KSB7CisgICAgICAgIC8vIGF2b2lkIGludCBvdmVyZmxvdworICAgICAgICBpZiAoMCA8PSBvZmZzZXQgJiYgb2Zmc2V0IDw9IGJ1Zi5sZW5ndGggJiYgMCA8PSBjb3VudAorICAgICAgICAgICAgICAgICYmIGNvdW50IDw9IGJ1Zi5sZW5ndGggLSBvZmZzZXQpIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgICAgIHRoaXMuYnVmLmFwcGVuZChidWYsIG9mZnNldCwgY291bnQpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIDxjb2RlPm9uZUNoYXI8L2NvZGU+IHRvIHRoaXMKKyAgICAgKiBTdHJpbmdXcml0ZXIuIFRoaXMgaW1wbGVtZW50YXRpb24gd3JpdGVzIHRoZSBsb3cgb3JkZXIgdHdvIGJ5dGVzIHRvIHRoZQorICAgICAqIFN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvbmVDaGFyCisgICAgICogICAgICAgICAgICBUaGUgY2hhcmFjdGVyIHRvIHdyaXRlCisgICAgICoKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgb25lQ2hhcikgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoKGNoYXIpIG9uZUNoYXIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIHRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFN0cmluZyA8Y29kZT5zdHI8L2NvZGU+IHRvIHRoaXMKKyAgICAgKiBTdHJpbmdXcml0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RyCisgICAgICogICAgICAgICAgICB0aGUgbm9uLW51bGwgU3RyaW5nIGNvbnRhaW5pbmcgdGhlIGNoYXJhY3RlcnMgdG8gd3JpdGUuCisgICAgICoKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShTdHJpbmcgc3RyKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAgICAgYnVmLmFwcGVuZChzdHIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGVzIDxjb2RlPmNvdW50PC9jb2RlPiBudW1iZXIgb2YgY2hhcmFjdGVycyBzdGFydGluZyBhdAorICAgICAqIDxjb2RlPm9mZnNldDwvY29kZT4gZnJvbSB0aGUgU3RyaW5nIDxjb2RlPnN0cjwvY29kZT4gdG8gdGhpcworICAgICAqIFN0cmluZ1dyaXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHIKKyAgICAgKiAgICAgICAgICAgIHRoZSBub24tbnVsbCBTdHJpbmcgY29udGFpbmluZyB0aGUgY2hhcmFjdGVycyB0byB3cml0ZS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogICAgICAgICAgICB0aGUgc3RhcnRpbmcgcG9pbnQgdG8gcmV0cmlldmUgY2hhcmFjdGVycy4KKyAgICAgKiBAcGFyYW0gY291bnQKKyAgICAgKiAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZXRyaWV2ZSBhbmQgd3JpdGUuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICAgICBJZiBvZmZzZXQgb3IgY291bnQgYXJlIG91dHNpZGUgb2YgYm91bmRzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKFN0cmluZyBzdHIsIGludCBvZmZzZXQsIGludCBjb3VudCkgeworICAgICAgICBTdHJpbmcgc3ViID0gc3RyLnN1YnN0cmluZyhvZmZzZXQsIG9mZnNldCArIGNvdW50KTsKKyAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKHN1Yik7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1Rlc3RQcm92aWRlci5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9UZXN0UHJvdmlkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYjVkMzE5Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9UZXN0UHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDEyNSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcm92aWRlcjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYSBkdW1teSBwcm92aWRlci4KKyAqLworcHVibGljIGNsYXNzIFN1cHBvcnRfVGVzdFByb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXIgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgLy8gUHJvdmlkZXIgbmFtZQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FID0gIlRlc3RQcm92aWRlciI7CisKKyAgICAvLyBWZXJzaW9uIG9mIHRoZSBzZXJ2aWNlcyBwcm92aWRlZAorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGRvdWJsZSBWRVJTSU9OID0gMS4wOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIElORk8gPSBOQU1FCisgICAgICAgICAgICArICIgRFNBIGtleSwgcGFyYW1ldGVyIGdlbmVyYXRpb24gYW5kIHNpZ25pbmc7IFNIQS0xIGRpZ2VzdDsgIgorICAgICAgICAgICAgKyAiU0hBMVBSTkcgU2VjdXJlUmFuZG9tOyBQS0NTIzEyL05ldHNjYXBlIEtleVN0b3JlIjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGR1bW15IHByb3ZpZGVyLgorICAgICAqLworICAgIHB1YmxpYyBTdXBwb3J0X1Rlc3RQcm92aWRlcigpIHsKKyAgICAgICAgc3VwZXIoTkFNRSwgVkVSU0lPTiwgSU5GTyk7CisgICAgICAgIHJlZ2lzdGVyU2VydmljZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWdpc3RlciB0aGUgc2VydmljZXMgdGhlIHJlY2VpdmVyIHByb3ZpZGVzLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWdpc3RlclNlcnZpY2VzKCkgeworICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbjxWb2lkPigpIHsKKyAgICAgICAgICAgIHB1YmxpYyBWb2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICAvLyBEaWdlc3QgZW5naW5lCisgICAgICAgICAgICAgICAgcHV0KCJNZXNzYWdlRGlnZXN0LlNIQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAibWFkZS51cC5wcm92aWRlci5uYW1lLk1lc3NhZ2VEaWdlc3RTSEEiKTsKKyAgICAgICAgICAgICAgICBwdXQoIk1lc3NhZ2VEaWdlc3QuTUQ1IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJtYWRlLnVwLnByb3ZpZGVyLm5hbWUuTWVzc2FnZURpZ2VzdE1ENSIpOworICAgICAgICAgICAgICAgIC8vIGFsaWFzZXMKKyAgICAgICAgICAgICAgICBwdXQoIkFsZy5BbGlhcy5NZXNzYWdlRGlnZXN0LlNIQTEiLCAiU0hBIik7CisgICAgICAgICAgICAgICAgcHV0KCJBbGcuQWxpYXMuTWVzc2FnZURpZ2VzdC5TSEEtMSIsICJTSEEiKTsKKyAgICAgICAgICAgICAgICBwdXQoIkFsZy5BbGlhcy5NZXNzYWdlRGlnZXN0Lk9JRC4xLjMuMTQuMy4yLjI2IiwgIlNIQSIpOworICAgICAgICAgICAgICAgIHB1dCgiQWxnLkFsaWFzLk1lc3NhZ2VEaWdlc3QuMS4zLjE0LjMuMi4yNiIsICJTSEEiKTsKKworICAgICAgICAgICAgICAgIC8vIEFsZ29yaXRobSBwYXJhbWV0ZXIgZ2VuZXJhdG9yCisgICAgICAgICAgICAgICAgcHV0KCJBbGdvcml0aG1QYXJhbWV0ZXJHZW5lcmF0b3IuRFNBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJtYWRlLnVwLnByb3ZpZGVyLm5hbWUuQWxnb3JpdGhtUGFyYW1ldGVyR2VuZXJhdG9yRFNBIik7CisKKyAgICAgICAgICAgICAgICAvLyBBbGdvcml0aG0gcGFyYW1ldGVycworICAgICAgICAgICAgICAgIHB1dCgiQWxnb3JpdGhtUGFyYW1ldGVycy5EU0EiLAorICAgICAgICAgICAgICAgICAgICAgICAgIm1hZGUudXAucHJvdmlkZXIubmFtZS5BbGdvcml0aG1QYXJhbWV0ZXJzRFNBIik7CisgICAgICAgICAgICAgICAgLy8gYWxpYXNlcworICAgICAgICAgICAgICAgIHB1dCgiQWxnLkFsaWFzLkFsZ29yaXRobVBhcmFtZXRlcnMuMS4yLjg0MC4xMDA0MC40LjEiLCAiRFNBIik7CisgICAgICAgICAgICAgICAgcHV0KCJBbGcuQWxpYXMuQWxnb3JpdGhtUGFyYW1ldGVycy4xLjMuMTQuMy4yLjEyIiwgIkRTQSIpOworCisgICAgICAgICAgICAgICAgLy8gS2V5IHBhaXIgZ2VuZXJhdG9yCisgICAgICAgICAgICAgICAgcHV0KCJLZXlQYWlyR2VuZXJhdG9yLkRTQSIsCisgICAgICAgICAgICAgICAgICAgICAgICAibWFkZS51cC5wcm92aWRlci5uYW1lLktleVBhaXJHZW5lcmF0b3JEU0EiKTsKKyAgICAgICAgICAgICAgICAvLyBhbGlhc2VzCisgICAgICAgICAgICAgICAgcHV0KCJBbGcuQWxpYXMuS2V5UGFpckdlbmVyYXRvci5PSUQuMS4yLjg0MC4xMDA0MC40LjEiLCAiRFNBIik7CisgICAgICAgICAgICAgICAgcHV0KCJBbGcuQWxpYXMuS2V5UGFpckdlbmVyYXRvci4xLjIuODQwLjEwMDQwLjQuMSIsICJEU0EiKTsKKyAgICAgICAgICAgICAgICBwdXQoIkFsZy5BbGlhcy5LZXlQYWlyR2VuZXJhdG9yLjEuMy4xNC4zLjIuMTIiLCAiRFNBIik7CisKKyAgICAgICAgICAgICAgICAvLyBLZXkgZmFjdG9yeQorICAgICAgICAgICAgICAgIHB1dCgiS2V5RmFjdG9yeS5EU0EiLCAibWFkZS51cC5wcm92aWRlci5uYW1lLktleUZhY3RvcnlEU0EiKTsKKyAgICAgICAgICAgICAgICBwdXQoIktleUZhY3RvcnkuUlNBIiwgIm1hZGUudXAucHJvdmlkZXIubmFtZS5LZXlGYWN0b3J5UlNBIik7CisgICAgICAgICAgICAgICAgLy8gYWxpYXNlcworICAgICAgICAgICAgICAgIHB1dCgiQWxnLkFsaWFzLktleUZhY3RvcnkuMS4yLjg0MC4xMDA0MC40LjEiLCAiRFNBIik7CisgICAgICAgICAgICAgICAgcHV0KCJBbGcuQWxpYXMuS2V5RmFjdG9yeS4xLjMuMTQuMy4yLjEyIiwgIkRTQSIpOworCisgICAgICAgICAgICAgICAgLy8gU2lnbmF0dXJlIGFsZ29yaXRobQorICAgICAgICAgICAgICAgIHB1dCgiU2lnbmF0dXJlLlNIQTF3aXRoRFNBIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJtYWRlLnVwLnByb3ZpZGVyLm5hbWUuU2lnbmF0dXJlRFNBIik7CisKKyAgICAgICAgICAgICAgICAvLyBhbGlhc2VzCisgICAgICAgICAgICAgICAgcHV0KCJBbGcuQWxpYXMuU2lnbmF0dXJlLkRTQSIsICJTSEExd2l0aERTQSIpOworICAgICAgICAgICAgICAgIHB1dCgiQWxnLkFsaWFzLlNpZ25hdHVyZS5EU1MiLCAiU0hBMXdpdGhEU0EiKTsKKyAgICAgICAgICAgICAgICBwdXQoIkFsZy5BbGlhcy5TaWduYXR1cmUuU0hBL0RTQSIsICJTSEExd2l0aERTQSIpOworICAgICAgICAgICAgICAgIHB1dCgiQWxnLkFsaWFzLlNpZ25hdHVyZS5TSEExL0RTQSIsICJTSEExd2l0aERTQSIpOworICAgICAgICAgICAgICAgIHB1dCgiQWxnLkFsaWFzLlNpZ25hdHVyZS5TSEEtMS9EU0EiLCAiU0hBMXdpdGhEU0EiKTsKKyAgICAgICAgICAgICAgICBwdXQoIkFsZy5BbGlhcy5TaWduYXR1cmUuU0hBd2l0aERTQSIsICJTSEExd2l0aERTQSIpOworICAgICAgICAgICAgICAgIHB1dCgiQWxnLkFsaWFzLlNpZ25hdHVyZS5EU0F3aXRoU0hBMSIsICJTSEExd2l0aERTQSIpOworICAgICAgICAgICAgICAgIHB1dCgiQWxnLkFsaWFzLlNpZ25hdHVyZS5EU0FXaXRoU0hBMSIsICJTSEExd2l0aERTQSIpOworICAgICAgICAgICAgICAgIHB1dCgiQWxnLkFsaWFzLlNpZ25hdHVyZS5TSEEtMXdpdGhEU0EiLCAiU0hBMXdpdGhEU0EiKTsKKyAgICAgICAgICAgICAgICBwdXQoIkFsZy5BbGlhcy5TaWduYXR1cmUuT0lELjEuMi44NDAuMTAwNDAuNC4zIiwgIlNIQTF3aXRoRFNBIik7CisgICAgICAgICAgICAgICAgcHV0KCJBbGcuQWxpYXMuU2lnbmF0dXJlLjEuMi44NDAuMTAwNDAuNC4zIiwgIlNIQTF3aXRoRFNBIik7CisgICAgICAgICAgICAgICAgcHV0KCJBbGcuQWxpYXMuU2lnbmF0dXJlLjEuMy4xNC4zLjIuMTMiLCAiU0hBMXdpdGhEU0EiKTsKKyAgICAgICAgICAgICAgICBwdXQoIkFsZy5BbGlhcy5TaWduYXR1cmUuMS4zLjE0LjMuMi4yNyIsICJTSEExd2l0aERTQSIpOworICAgICAgICAgICAgICAgIHB1dCgiQWxnLkFsaWFzLlNpZ25hdHVyZS5PSUQuMS4zLjE0LjMuMi4xMyIsICJTSEExd2l0aERTQSIpOworICAgICAgICAgICAgICAgIHB1dCgiQWxnLkFsaWFzLlNpZ25hdHVyZS5PSUQuMS4zLjE0LjMuMi4yNyIsICJTSEExd2l0aERTQSIpOworCisgICAgICAgICAgICAgICAgcHV0KCJLZXlTdG9yZS5QS0NTIzEyL05ldHNjYXBlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJ0ZXN0cy5zdXBwb3J0LlN1cHBvcnRfRHVtbXlQS0NTMTJLZXlzdG9yZSIpOworCisgICAgICAgICAgICAgICAgLy8gQ2VydGlmaWNhdGUKKyAgICAgICAgICAgICAgICBwdXQoIkNlcnRpZmljYXRlRmFjdG9yeS5YNTA5IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJtYWRlLnVwLnByb3ZpZGVyLm5hbWUuQ2VydGlmaWNhdGVGYWN0b3J5WDUwOSIpOworICAgICAgICAgICAgICAgIC8vIGFsaWFzZXMKKyAgICAgICAgICAgICAgICBwdXQoIkFsZy5BbGlhcy5DZXJ0aWZpY2F0ZUZhY3RvcnkuWC41MDkiLCAiWDUwOSIpOworCisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1Rlc3RSZXNvdXJjZS5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9UZXN0UmVzb3VyY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMTgzMWY2Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9UZXN0UmVzb3VyY2UuamF2YQpAQCAtMCwwICsxLDMxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zdXBwb3J0OworCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9UZXN0UmVzb3VyY2UgZXh0ZW5kcyBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlIHsKKyAgICBmaW5hbCBTdHJpbmcgYXJyYXlbXSA9IHsiU3RyMSIsICJTdHIyIiwgIlN0cjMifTsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkgeworICAgICAgICBPYmplY3RbXVtdIGNvbnRlbnRzID0geyB7ICJwYXJlbnQxIiwgInBhcmVudFZhbHVlMSIgfSwKKyAgICAgICAgICAgICAgICB7ICJwYXJlbnQyIiwgInBhcmVudFZhbHVlMiIgfSwgeyAicGFyZW50MyIsICJwYXJlbnRWYWx1ZTMiIH0sCisgICAgICAgICAgICAgICAgeyAicGFyZW50NCIsICJwYXJlbnRWYWx1ZTQiIH0sIHsiSW50ZWdlclZhbCIsIDF9LCB7IlN0cmluZ0FycmF5IiwgYXJyYXl9fTsKKyAgICAgICAgcmV0dXJuIGNvbnRlbnRzOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9UZXN0UmVzb3VyY2VfZW4uamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfVGVzdFJlc291cmNlX2VuLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODAwMWRiMAotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfVGVzdFJlc291cmNlX2VuLmphdmEKQEAgLTAsMCArMSwzMCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworcHVibGljIGNsYXNzIFN1cHBvcnRfVGVzdFJlc291cmNlX2VuIGV4dGVuZHMgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZSB7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgT2JqZWN0W11bXSBnZXRDb250ZW50cygpIHsKKyAgICAgICAgT2JqZWN0W11bXSBjb250ZW50cyA9IHsgeyAicGFyZW50MiIsICJlblZhbHVlMiIgfSwKKyAgICAgICAgICAgICAgICB7ICJwYXJlbnQzIiwgImVuVmFsdWUzIiB9LCB7ICJwYXJlbnQ0IiwgImVuVmFsdWU0IiB9LAorICAgICAgICAgICAgICAgIHsgImNoaWxkMSIsICJlbkNoaWxkVmFsdWUxIiB9LCB9OworICAgICAgICByZXR1cm4gY29udGVudHM7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1Rlc3RSZXNvdXJjZV9lbl9VUy5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9UZXN0UmVzb3VyY2VfZW5fVVMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OTk1MWY0Ci0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9UZXN0UmVzb3VyY2VfZW5fVVMuamF2YQpAQCAtMCwwICsxLDMwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zdXBwb3J0OworCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9UZXN0UmVzb3VyY2VfZW5fVVMgZXh0ZW5kcyBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlIHsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkgeworICAgICAgICBPYmplY3RbXVtdIGNvbnRlbnRzID0geyB7ICJwYXJlbnQzIiwgImVuVVNWYWx1ZTMiIH0sCisgICAgICAgICAgICAgICAgeyAicGFyZW50NCIsICJlblVTVmFsdWU0IiB9LCB7ICJjaGlsZDEiLCAiZW5VU0NoaWxkVmFsdWUxIiB9LAorICAgICAgICAgICAgICAgIHsgImNoaWxkMiIsICJlblVTQ2hpbGRWYWx1ZTIiIH0sIH07CisgICAgICAgIHJldHVybiBjb250ZW50czsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfVGVzdFJlc291cmNlX2ZyLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1Rlc3RSZXNvdXJjZV9mci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRjYzQ1Y2YKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1Rlc3RSZXNvdXJjZV9mci5qYXZhCkBAIC0wLDAgKzEsMzAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK3B1YmxpYyBjbGFzcyBTdXBwb3J0X1Rlc3RSZXNvdXJjZV9mciBleHRlbmRzIGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGUgeworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKSB7CisgICAgICAgIE9iamVjdFtdW10gY29udGVudHMgPSB7IHsgInBhcmVudDIiLCAiZnJWYWx1ZTIiIH0sCisgICAgICAgICAgICAgICAgeyAicGFyZW50MyIsICJmclZhbHVlMyIgfSwgeyAicGFyZW50NCIsICJmclZhbHVlNCIgfSwKKyAgICAgICAgICAgICAgICB7ICJjaGlsZDEiLCAiZnJDaGlsZFZhbHVlMSIgfSwgfTsKKyAgICAgICAgcmV0dXJuIGNvbnRlbnRzOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9UZXN0UmVzb3VyY2VfZnJfRlIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfVGVzdFJlc291cmNlX2ZyX0ZSLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTdmNjEyMgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfVGVzdFJlc291cmNlX2ZyX0ZSLmphdmEKQEAgLTAsMCArMSwzMCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworcHVibGljIGNsYXNzIFN1cHBvcnRfVGVzdFJlc291cmNlX2ZyX0ZSIGV4dGVuZHMgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZSB7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgT2JqZWN0W11bXSBnZXRDb250ZW50cygpIHsKKyAgICAgICAgT2JqZWN0W11bXSBjb250ZW50cyA9IHsgeyAicGFyZW50MyIsICJmckZSVmFsdWUzIiB9LAorICAgICAgICAgICAgICAgIHsgInBhcmVudDQiLCAiZnJGUlZhbHVlNCIgfSwgeyAiY2hpbGQxIiwgImZyRlJDaGlsZFZhbHVlMSIgfSwKKyAgICAgICAgICAgICAgICB7ICJjaGlsZDIiLCAiZnJGUkNoaWxkVmFsdWUyIiB9LCB9OworICAgICAgICByZXR1cm4gY29udGVudHM7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1Rlc3RSZXNvdXJjZV9mcl9GUl9WQVIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfVGVzdFJlc291cmNlX2ZyX0ZSX1ZBUi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdkYjhhZDUKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1Rlc3RSZXNvdXJjZV9mcl9GUl9WQVIuamF2YQpAQCAtMCwwICsxLDMxIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworcHVibGljIGNsYXNzIFN1cHBvcnRfVGVzdFJlc291cmNlX2ZyX0ZSX1ZBUiBleHRlbmRzCisgICAgICAgIGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGUgeworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKSB7CisgICAgICAgIE9iamVjdFtdW10gY29udGVudHMgPSB7IHsgInBhcmVudDQiLCAiZnJGUlZBUlZhbHVlNCIgfSwKKyAgICAgICAgICAgICAgICB7ICJjaGlsZDEiLCAiZnJGUlZBUkNoaWxkVmFsdWUxIiB9LAorICAgICAgICAgICAgICAgIHsgImNoaWxkMiIsICJmckZSVkFSQ2hpbGRWYWx1ZTIiIH0sCisgICAgICAgICAgICAgICAgeyAiY2hpbGQzIiwgImZyRlJWQVJDaGlsZFZhbHVlMyIgfSwgfTsKKyAgICAgICAgcmV0dXJuIGNvbnRlbnRzOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9UZXN0V2ViRGF0YS5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9UZXN0V2ViRGF0YS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmZGQwMjEKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1Rlc3RXZWJEYXRhLmphdmEKQEAgLTAsMCArMSwxNjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CisKKy8qKgorICogUmVwcmVzZW50cyB0ZXN0IGRhdGEgdXNlZCBieSB0aGUgUmVxdWVzdCBBUEkgdGVzdHMKKyAqLworcHVibGljIGNsYXNzIFN1cHBvcnRfVGVzdFdlYkRhdGEgeworICBwdWJsaWMgZmluYWwgc3RhdGljIGJ5dGVbXSB0ZXN0MSA9IHV0ZkJ5dGVzKCk7CisgIHB1YmxpYyBmaW5hbCBzdGF0aWMgYnl0ZVtdIHRlc3QyID0gbmV3QmluYXJ5RmlsZSg4MTkyKTsKKworICBwcml2YXRlIHN0YXRpYyBieXRlW10gdXRmQnl0ZXMoKSB7CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiAiPGh0bWw+XG48Ym9keT5cbjxoMT5IZWxsbyBXb3JsZCE8L2gxPlxuPC9ib2R5PlxuPC9odG1sPlxuIi5nZXRCeXRlcygiVVRGLTgiKTsKKyAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGV4KSB7CisgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBieXRlW10gbmV3QmluYXJ5RmlsZShpbnQgYnl0ZUNvdW50KSB7CisgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW2J5dGVDb3VudF07CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXN1bHQubGVuZ3RoOyArK2kpIHsKKyAgICAgIHJlc3VsdFtpXSA9IChieXRlKSBpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLy8gc3RyaW5nIGZvciB0ZXN0IHJlcXVlc3QgcG9zdCBib2R5CisgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIHBvc3RDb250ZW50ID0gInVzZXI9MTExIjsKKworICAvLyBBcnJheSBvZiBhbGwgdGVzdCBkYXRhCisgIHB1YmxpYyBmaW5hbCBzdGF0aWMgYnl0ZVtdW10gdGVzdHMgPSB7CisgICAgdGVzdDEsCisgICAgdGVzdDIKKyAgfTsKKworICAvKioKKyAgICogTGlzdCBvZiBzdGF0aWMgdGVzdCBjYXNlcyBmb3IgdXNlIHdpdGggdGVzdCBzZXJ2ZXIKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3VwcG9ydF9UZXN0V2ViRGF0YVtdIHRlc3RQYXJhbXMgPSB7CisgICAgbmV3IFN1cHBvcnRfVGVzdFdlYkRhdGEodGVzdDEubGVuZ3RoLCAxNDAwMDAwMCwgInRlc3QxIiwgInRleHQvaHRtbCIsIGZhbHNlLCAwKSwKKyAgICBuZXcgU3VwcG9ydF9UZXN0V2ViRGF0YSh0ZXN0Mi5sZW5ndGgsIDE0MDAwMDAyLCAidGVzdDIiLCAidW5rbm93bi91bmtub3duIiwgZmFsc2UsCisgICAgICAgICAgICBuZXcgRGF0ZSgpLmdldFRpbWUoKSArIDEwMDAwMCkKKyAgfTsKKworICAvKioKKyAgICogTGlzdCBvZiByZXNwb25zZSBzdHJpbmdzIGZvciB1c2UgYnkgdGhlIHRlc3Qgc2VydmVyCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZ1tdIHRlc3RTZXJ2ZXJSZXNwb25zZSA9IHsKKyAgICAiUmVkaXJlY3RpbmcgMzAxIiwKKyAgICAiUmVkaXJlY3RpbmcgMzAyIiwKKyAgICAiUmVkaXJlY3RpbmcgMzAzIiwKKyAgICAiUmVkaXJlY3RpbmcgMzA3IgorICB9OworCisgIC8vIFJlZGlyZWN0aW9uIGluZGljZXMgaW50byB0ZXN0U2VydmVyUmVzcG9uc2UKKyAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgUkVESVJFQ1RfMzAxID0gMDsKKyAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgUkVESVJFQ1RfMzAyID0gMTsKKyAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgUkVESVJFQ1RfMzAzID0gMjsKKyAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgUkVESVJFQ1RfMzA3ID0gMzsKKworICAvKioKKyAgICogQ3JlYXRlcyBhIGRhdGEgcGFja2FnZSB3aXRoIGluZm9ybWF0aW9uIHVzZWQgYnkgdGhlIHNlcnZlciB3aGVuIHJlc3BvbmRpbmcKKyAgICogdG8gcmVxdWVzdHMKKyAgICovCisgIFN1cHBvcnRfVGVzdFdlYkRhdGEoaW50IGxlbmd0aCwgaW50IGxhc3RNb2RpZmllZCwgU3RyaW5nIG5hbWUsIFN0cmluZyB0eXBlLCBib29sZWFuIGlzRGlyLCBsb25nIGV4cERhdGUpIHsKKyAgICB0ZXN0TGVuZ3RoID0gbGVuZ3RoOworICAgIHRlc3RMYXN0TW9kaWZpZWQgPSBsYXN0TW9kaWZpZWQ7CisgICAgdGVzdE5hbWUgPSBuYW1lOworICAgIHRlc3RUeXBlID0gdHlwZTsKKyAgICB0ZXN0RGlyID0gaXNEaXI7CisgICAgdGVzdEV4cCA9IGV4cERhdGU7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlcyBhIGRhdGEgcGFja2FnZSB3aXRoIGluZm9ybWF0aW9uIHVzZWQgYnkgdGhlIHNlcnZlciB3aGVuIHJlc3BvbmRpbmcKKyAgICogdG8gcmVxdWVzdHMKKyAgICovCisgIHByaXZhdGUgU3VwcG9ydF9UZXN0V2ViRGF0YShTdHJpbmcgcGF0aCwgU3RyaW5nIHR5cGUpIHsKKyAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShwYXRoKTsKKyAgICB0ZXN0TGVuZ3RoID0gZmlsZS5sZW5ndGgoKTsKKyAgICB0ZXN0TGFzdE1vZGlmaWVkID0gZmlsZS5sYXN0TW9kaWZpZWQoKTsKKyAgICB0ZXN0TmFtZSA9IGZpbGUuZ2V0TmFtZSgpOworICAgIHRlc3RUeXBlID0gdHlwZTsKKyAgICB0ZXN0RGlyID0gZmlsZS5pc0RpcmVjdG9yeSgpOworICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgRmlsZUlucHV0U3RyZWFtIGluID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgICBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSk7CisgICAgICAgIHdoaWxlIChpbi5hdmFpbGFibGUoKSA+IDApIHsKKyAgICAgICAgICAgIG91dC53cml0ZShpbi5yZWFkKCkpOworICAgICAgICB9CisgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICB0ZXN0MERhdGEgPSBvdXQudG9CeXRlQXJyYXkoKTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgIHRlc3QwRGF0YUF2YWlsYWJsZSA9IHRydWU7CisgICAgICAgIHJldHVybjsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAvLyBpZ25vcmUKKyAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGluICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKG91dCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGlnbm9yZQorICAgICAgICB9CisgICAgfQorICB9CisKKyAgcHVibGljIHN0YXRpYyB2b2lkIGluaXREeW5hbWljVGVzdFdlYkRhdGEoU3RyaW5nIHBhdGgsIFN0cmluZyB0eXBlKSB7CisgICAgICB0ZXN0MFBhcmFtcyA9IG5ldyBTdXBwb3J0X1Rlc3RXZWJEYXRhKHBhdGgsIHR5cGUpOworICB9CisKKyAgLy8gTGVuZ3RoIG9mIHRlc3QgZW50aXR5IGJvZHkKKyAgcHVibGljIGxvbmcgdGVzdExlbmd0aDsKKworICAvLyBMYXN0IG1vZGlmaWVkIGRhdGUgdmFsdWUgKG1pbGxpc2Vjb25kcykKKyAgcHVibGljIGxvbmcgdGVzdExhc3RNb2RpZmllZDsKKworICAvLyBUZXN0IGlkZW50aWZpY2F0aW9uIG5hbWUKKyAgcHVibGljIFN0cmluZyB0ZXN0TmFtZTsKKworICAvLyBUaGUgTUlNRSB0eXBlIHRvIGFzc3VtZSBmb3IgdGhpcyB0ZXN0CisgIHB1YmxpYyBTdHJpbmcgdGVzdFR5cGU7CisKKyAgLy8gVGhlIGV4cGlyYXRpb24gZGF0ZQorICBwdWJsaWMgbG9uZyB0ZXN0RXhwOworCisgIC8vIEluZGljYXRlcyBpZiB0aGlzIGlzIGEgZGlyZWN0b3J5IG9yIG5vdAorICBwdWJsaWMgYm9vbGVhbiB0ZXN0RGlyOworCisgIC8vIEluZGljYXRlIGlmIHRlc3QwIGRhdGEgaGFzIGJpbiBpbml0aWFsaXplZAorICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gdGVzdDBEYXRhQXZhaWxhYmxlID0gZmFsc2U7CisKKyAgLy8gdGVzdDAgZGF0YQorICBwdWJsaWMgc3RhdGljIGJ5dGVbXSB0ZXN0MERhdGE7CisKKyAgLy8gdGVzdDAgcGFyYW1ldGVycworICBwdWJsaWMgc3RhdGljIFN1cHBvcnRfVGVzdFdlYkRhdGEgdGVzdDBQYXJhbXM7Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1Rlc3RXZWJTZXJ2ZXIuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfVGVzdFdlYlNlcnZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRkNmIwZDEKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1Rlc3RXZWJTZXJ2ZXIuamF2YQpAQCAtMCwwICsxLDg4NSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwNyBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLmxhbmcuVGhyZWFkOworaW1wb3J0IGphdmEubmV0Lio7CitpbXBvcnQgamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQ7CitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudEhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nZ2VyOworCisvKioKKyAqIFRlc3RXZWJTZXJ2ZXIgaXMgYSBzaW11bGF0ZWQgY29udHJvbGxhYmxlIHRlc3Qgc2VydmVyIHRoYXQKKyAqIGNhbiByZXNwb25kIHRvIHJlcXVlc3RzIGZyb20gSFRUUCBjbGllbnRzLgorICoKKyAqIFRoZSBzZXJ2ZXIgY2FuIGJlIGNvbnRyb2xsZWQgdG8gY2hhbmdlIGhvdyBpdCByZWFjdHMgdG8gYW55CisgKiByZXF1ZXN0cywgYW5kIGNhbiBiZSB0b2xkIHRvIHNpbXVsYXRlIHZhcmlvdXMgZXZlbnRzIChzdWNoIGFzCisgKiBuZXR3b3JrIGZhaWx1cmUpIHRoYXQgd291bGQgaGFwcGVuIGluIGEgcmVhbCBlbnZpcm9ubWVudC4KKyAqLworcHVibGljIGNsYXNzIFN1cHBvcnRfVGVzdFdlYlNlcnZlciBpbXBsZW1lbnRzIFN1cHBvcnRfSHR0cENvbnN0YW50cyB7CisKKyAgICAvKiBzdGF0aWMgY2xhc3MgZGF0YS9tZXRob2RzICovCisKKyAgICAvKiBUaGUgQU5EUk9JRF9MT0dfVEFHICovCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIExPR1RBRyA9ICJodHRwc3YiOworCisgICAgLyoqIG1hcHMgdGhlIHJlY2VudGx5IHJlcXVlc3RlZCBVUkxzIHRvIHRoZSBmdWxsIHJlcXVlc3Qgc25hcHNob3QgKi8KKyAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIFJlcXVlc3Q+IHBhdGhUb1JlcXVlc3QKKyAgICAgICAgICAgID0gbmV3IENvbmN1cnJlbnRIYXNoTWFwPFN0cmluZywgUmVxdWVzdD4oKTsKKworICAgIC8qIHRpbWVvdXQgb24gY2xpZW50IGNvbm5lY3Rpb25zICovCisgICAgaW50IHRpbWVvdXQgPSAwOworCisgICAgLyogRGVmYXVsdCBzb2NrZXQgdGltZW91dCB2YWx1ZSAqLworICAgIGZpbmFsIHN0YXRpYyBpbnQgREVGQVVMVF9USU1FT1VUID0gNTAwMDsKKworICAgIC8qIFZlcnNpb24gc3RyaW5nIChjb25maWd1cmFibGUpICovCisgICAgcHJvdGVjdGVkIFN0cmluZyBIVFRQX1ZFUlNJT05fU1RSSU5HID0gIkhUVFAvMS4xIjsKKworICAgIC8qIEluZGljYXRvciBmb3Igd2hldGhlciB0aGlzIHNlcnZlciBpcyBjb25maWd1cmVkIGFzIGEgSFRUUC8xLjEKKyAgICAgKiBvciBIVFRQLzEuMCBzZXJ2ZXIKKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaHR0cDExID0gdHJ1ZTsKKworICAgIC8qIFRoZSB0aHJlYWQgaGFuZGxpbmcgbmV3IHJlcXVlc3RzIGZyb20gY2xpZW50cyAqLworICAgIHByaXZhdGUgQWNjZXB0VGhyZWFkIGFjY2VwdFQ7CisKKyAgICAvKiB0aW1lb3V0IG9uIGNsaWVudCBjb25uZWN0aW9ucyAqLworICAgIGludCBtVGltZW91dDsKKworICAgIC8qIFNlcnZlciBwb3J0ICovCisgICAgaW50IG1Qb3J0OworCisgICAgLyogU3dpdGNoIG9uL29mZiBsb2dnaW5nICovCisgICAgYm9vbGVhbiBtTG9nID0gZmFsc2U7CisKKyAgICAvKiBJZiBzZXQsIHRoaXMgd2lsbCBrZWVwIGNvbm5lY3Rpb25zIGFsaXZlIGFmdGVyIGEgcmVxdWVzdCBoYXMgYmVlbgorICAgICAqIHByb2Nlc3NlZC4KKyAgICAgKi8KKyAgICBib29sZWFuIGtlZXBBbGl2ZSA9IHRydWU7CisKKyAgICAvKiBJZiBzZXQsIHRoaXMgd2lsbCBjYXVzZSByZXNwb25zZSBkYXRhIHRvIGJlIHNlbnQgaW4gJ2NodW5rZWQnIGZvcm1hdCAqLworICAgIGJvb2xlYW4gY2h1bmtlZCA9IGZhbHNlOworICAgIGludCBtYXhDaHVua1NpemUgPSAxMDI0OworCisgICAgLyogSWYgc2V0LCB0aGlzIHdpbGwgaW5kaWNhdGUgYSBuZXcgcmVkaXJlY3Rpb24gaG9zdCAqLworICAgIFN0cmluZyByZWRpcmVjdEhvc3QgPSBudWxsOworCisgICAgLyogSWYgc2V0LCB0aGlzIGluZGljYXRlcyB0aGUgcmVhc29uIGZvciByZWRpcmVjdGlvbiAqLworICAgIGludCByZWRpcmVjdENvZGUgPSAtMTsKKworICAgIC8qIFNldCB0aGUgbnVtYmVyIG9mIGNvbm5lY3Rpb25zIHRoZSBzZXJ2ZXIgd2lsbCBhY2NlcHQgYmVmb3JlIHNodXRkb3duICovCisgICAgaW50IGFjY2VwdExpbWl0ID0gMTAwOworCisgICAgLyogQ291bnQgb2YgbnVtYmVyIG9mIGFjY2VwdGVkIGNvbm5lY3Rpb25zICovCisgICAgaW50IGFjY2VwdGVkQ29ubmVjdGlvbnMgPSAwOworCisgICAgcHVibGljIFN1cHBvcnRfVGVzdFdlYlNlcnZlcigpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplIGEgbmV3IHNlcnZlciB3aXRoIGRlZmF1bHQgcG9ydCBhbmQgdGltZW91dC4KKyAgICAgKiBAcGFyYW0gbG9nIFNldCB0cnVlIGlmIHlvdSB3YW50IHRyYWNlIG91dHB1dAorICAgICAqLworICAgIHB1YmxpYyBpbnQgaW5pdFNlcnZlcihib29sZWFuIGxvZykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBpbml0U2VydmVyKDAsIERFRkFVTFRfVElNRU9VVCwgbG9nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplIGEgbmV3IHNlcnZlciB3aXRoIGRlZmF1bHQgdGltZW91dC4KKyAgICAgKiBAcGFyYW0gcG9ydCBTZXRzIHRoZSBzZXJ2ZXIgdG8gbGlzdGVuIG9uIHRoaXMgcG9ydCwgb3IgMCB0byBsZXQgdGhlIE9TIGNob29zZS4KKyAgICAgKiAgICAgICAgICAgICBIYXJkLWNvZGluZyBwb3J0cyBpcyBldmlsLCBzbyBhbHdheXMgcGFzcyAwLgorICAgICAqIEBwYXJhbSBsb2cgU2V0IHRydWUgaWYgeW91IHdhbnQgdHJhY2Ugb3V0cHV0CisgICAgICovCisgICAgcHVibGljIGludCBpbml0U2VydmVyKGludCBwb3J0LCBib29sZWFuIGxvZykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBpbml0U2VydmVyKHBvcnQsIERFRkFVTFRfVElNRU9VVCwgbG9nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplIGEgbmV3IHNlcnZlciB3aXRoIGRlZmF1bHQgdGltZW91dCBhbmQgZGlzYWJsZWQgbG9nLgorICAgICAqIEBwYXJhbSBwb3J0IFNldHMgdGhlIHNlcnZlciB0byBsaXN0ZW4gb24gdGhpcyBwb3J0LCBvciAwIHRvIGxldCB0aGUgT1MgY2hvb3NlLgorICAgICAqICAgICAgICAgICAgIEhhcmQtY29kaW5nIHBvcnRzIGlzIGV2aWwsIHNvIGFsd2F5cyBwYXNzIDAuCisgICAgICogQHBhcmFtIHNlcnZlUGF0aCB0aGUgcGF0aCB0byB0aGUgZHluYW1pYyB3ZWIgdGVzdCBkYXRhCisgICAgICogQHBhcmFtIGNvbnRlbnRUeXBlIHRoZSB0eXBlIG9mIHRoZSBkeW5hbWljIHdlYiB0ZXN0IGRhdGEKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGluaXRTZXJ2ZXIoaW50IHBvcnQsIFN0cmluZyBzZXJ2ZVBhdGgsIFN0cmluZyBjb250ZW50VHlwZSkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdXBwb3J0X1Rlc3RXZWJEYXRhLmluaXREeW5hbWljVGVzdFdlYkRhdGEoc2VydmVQYXRoLCBjb250ZW50VHlwZSk7CisgICAgICAgIHJldHVybiBpbml0U2VydmVyKHBvcnQsIERFRkFVTFRfVElNRU9VVCwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemUgYSBuZXcgc2VydmVyIHdpdGggZGVmYXVsdCBwb3J0IGFuZCB0aW1lb3V0LgorICAgICAqIEBwYXJhbSBwb3J0IFNldHMgdGhlIHNlcnZlciB0byBsaXN0ZW4gb24gdGhpcyBwb3J0LCBvciAwIHRvIGxldCB0aGUgT1MgY2hvb3NlLgorICAgICAqICAgICAgICAgICAgIEhhcmQtY29kaW5nIHBvcnRzIGlzIGV2aWwsIHNvIGFsd2F5cyBwYXNzIDAuCisgICAgICogQHBhcmFtIHRpbWVvdXQgSW5kaWNhdGVzIHRoZSBwZXJpb2Qgb2YgdGltZSB0byB3YWl0IHVudGlsIGEgc29ja2V0IGlzCisgICAgICogICAgICAgICAgICAgICAgY2xvc2VkCisgICAgICogQHBhcmFtIGxvZyBTZXQgdHJ1ZSBpZiB5b3Ugd2FudCB0cmFjZSBvdXRwdXQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGluaXRTZXJ2ZXIoaW50IHBvcnQsIGludCB0aW1lb3V0LCBib29sZWFuIGxvZykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIG1UaW1lb3V0ID0gdGltZW91dDsKKyAgICAgICAgbUxvZyA9IGxvZzsKKyAgICAgICAga2VlcEFsaXZlID0gdHJ1ZTsKKyAgICAgICAgaWYgKGFjY2VwdFQgPT0gbnVsbCkgeworICAgICAgICAgICAgYWNjZXB0VCA9IG5ldyBBY2NlcHRUaHJlYWQoKTsKKyAgICAgICAgICAgIG1Qb3J0ID0gYWNjZXB0VC5pbml0KHBvcnQpOworICAgICAgICAgICAgYWNjZXB0VC5zdGFydCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBtUG9ydDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmludCB0byB0aGUgbG9nIGZpbGUgKGlmIGxvZ2dpbmcgZW5hYmxlZCkKKyAgICAgKiBAcGFyYW0gcyBTdHJpbmcgdG8gc2VuZCB0byB0aGUgbG9nCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgbG9nKFN0cmluZyBzKSB7CisgICAgICAgIGlmIChtTG9nKSB7CisgICAgICAgICAgICBMb2dnZXIuZ2xvYmFsLmZpbmUocyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHNlcnZlciB0byBiZSBhbiBIVFRQLzEuMCBvciBIVFRQLzEuMSBzZXJ2ZXIuCisgICAgICogVGhpcyBzaG91bGQgYmUgY2FsbGVkIHByaW9yIHRvIGFueSByZXF1ZXN0cyBiZWluZyBzZW50CisgICAgICogdG8gdGhlIHNlcnZlci4KKyAgICAgKiBAcGFyYW0gc2V0IFRydWUgZm9yIHRoZSBzZXJ2ZXIgdG8gYmUgSFRUUC8xLjEsIGZhbHNlIGZvciBIVFRQLzEuMAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEh0dHBWZXJzaW9uMTEoYm9vbGVhbiBzZXQpIHsKKyAgICAgICAgaHR0cDExID0gc2V0OworICAgICAgICBpZiAoc2V0KSB7CisgICAgICAgICAgICBIVFRQX1ZFUlNJT05fU1RSSU5HID0gIkhUVFAvMS4xIjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIEhUVFBfVkVSU0lPTl9TVFJJTkcgPSAiSFRUUC8xLjAiOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbCB0aGlzIHRvIGRldGVybWluZSB3aGV0aGVyIHNlcnZlciBjb25uZWN0aW9uIHNob3VsZCByZW1haW4gb3BlbgorICAgICAqIEBwYXJhbSB2YWx1ZSBTZXQgdHJ1ZSB0byBrZWVwIGNvbm5lY3Rpb25zIG9wZW4gYWZ0ZXIgYSByZXF1ZXN0CisgICAgICogICAgICAgICAgICAgIGNvbXBsZXRlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEtlZXBBbGl2ZShib29sZWFuIHZhbHVlKSB7CisgICAgICAgIGtlZXBBbGl2ZSA9IHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGwgdGhpcyB0byBpbmRpY2F0ZSB3aGV0aGVyIGNodW5rZWQgZGF0YSBzaG91bGQgYmUgdXNlZAorICAgICAqIEBwYXJhbSB2YWx1ZSBTZXQgdHJ1ZSB0byBtYWtlIHNlcnZlciByZXNwb25kIHdpdGggY2h1bmsgZW5jb2RlZAorICAgICAqICAgICAgICAgICAgICBjb250ZW50IGRhdGEuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q2h1bmtlZChib29sZWFuIHZhbHVlKSB7CisgICAgICAgIGNodW5rZWQgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBtYXhpbXVtIGJ5dGUgY291bnQgb2YgYW55IGNodW5rIGlmIHRoZSBzZXJ2ZXIgaXMgdXNpbmcKKyAgICAgKiB0aGUgImNodW5rZWQiIHRyYW5zZmVyIGVuY29kaW5nLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1heENodW5rU2l6ZShpbnQgbWF4Q2h1bmtTaXplKSB7CisgICAgICAgIHRoaXMubWF4Q2h1bmtTaXplID0gbWF4Q2h1bmtTaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGwgdGhpcyB0byBzcGVjaWZ5IHRoZSBtYXhpbXVtIG51bWJlciBvZiBzb2NrZXRzIHRvIGFjY2VwdAorICAgICAqIEBwYXJhbSBsaW1pdCBUaGUgbnVtYmVyIG9mIHNvY2tldHMgdG8gYWNjZXB0CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0QWNjZXB0TGltaXQoaW50IGxpbWl0KSB7CisgICAgICAgIGFjY2VwdExpbWl0ID0gbGltaXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbCB0aGlzIHRvIGluZGljYXRlIHJlZGlyZWN0aW9uIHBvcnQgcmVxdWlyZW1lbnQuCisgICAgICogV2hlbiB0aGlzIHZhbHVlIGlzIHNldCwgdGhlIHNlcnZlciB3aWxsIHJlc3BvbmQgdG8gYSByZXF1ZXN0IHdpdGgKKyAgICAgKiBhIHJlZGlyZWN0IGNvZGUgd2l0aCB0aGUgTG9jYXRpb24gcmVzcG9uc2UgaGVhZGVyIHNldCB0byB0aGUgdmFsdWUKKyAgICAgKiBzcGVjaWZpZWQuCisgICAgICogQHBhcmFtIHJlZGlyZWN0IFRoZSBsb2NhdGlvbiB0byBiZSByZWRpcmVjdGVkIHRvCisgICAgICogQHBhcmFtIGNvZGUgVGhlIGNvZGUgdG8gc2VuZCB3aGVuIHJlZGlyZWN0aW5nCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmVkaXJlY3QoU3RyaW5nIHJlZGlyZWN0LCBpbnQgY29kZSkgeworICAgICAgICByZWRpcmVjdEhvc3QgPSByZWRpcmVjdDsKKyAgICAgICAgcmVkaXJlY3RDb2RlID0gY29kZTsKKyAgICAgICAgbG9nKCJTZXJ2ZXIgd2lsbCByZWRpcmVjdCBvdXRwdXQgdG8gIityZWRpcmVjdCsiIGNvZGUgIitjb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbWFwIGZyb20gcmVjZW50bHktcmVxdWVzdGVkIHBhdGhzIChsaWtlICIvaW5kZXguaHRtbCIpIHRvIGEKKyAgICAgKiBzbmFwc2hvdCBvZiB0aGUgcmVxdWVzdCBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyBNYXA8U3RyaW5nLCBSZXF1ZXN0PiBwYXRoVG9SZXF1ZXN0KCkgeworICAgICAgICByZXR1cm4gcGF0aFRvUmVxdWVzdDsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldE51bUFjY2VwdGVkQ29ubmVjdGlvbnMoKSB7CisgICAgICAgIHJldHVybiBhY2NlcHRlZENvbm5lY3Rpb25zOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhdXNlIHRoZSB0aHJlYWQgYWNjZXB0aW5nIGNvbm5lY3Rpb25zIG9uIHRoZSBzZXJ2ZXIgc29ja2V0IHRvIGNsb3NlCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgIC8qIFN0b3AgdGhlIEFjY2VwdCB0aHJlYWQgKi8KKyAgICAgICAgaWYgKGFjY2VwdFQgIT0gbnVsbCkgeworICAgICAgICAgICAgbG9nKCJDbG9zaW5nIEFjY2VwdFRocmVhZCIrYWNjZXB0VCk7CisgICAgICAgICAgICBhY2NlcHRULmNsb3NlKCk7CisgICAgICAgICAgICBhY2NlcHRUID0gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKyAgICAvKioKKyAgICAgKiBUaGUgQWNjZXB0VGhyZWFkIGlzIHJlc3BvbnNpYmxlIGZvciBpbml0aWF0aW5nIHdvcmtlciB0aHJlYWRzCisgICAgICogdG8gaGFuZGxlIGluY29taW5nIHJlcXVlc3RzIGZyb20gY2xpZW50cy4KKyAgICAgKi8KKyAgICBjbGFzcyBBY2NlcHRUaHJlYWQgZXh0ZW5kcyBUaHJlYWQgeworCisgICAgICAgIFNlcnZlclNvY2tldCBzcyA9IG51bGw7CisgICAgICAgIGJvb2xlYW4gcnVubmluZyA9IGZhbHNlOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBAcGFyYW0gcG9ydCB0aGUgcG9ydCB0byB1c2UsIG9yIDAgdG8gbGV0IHRoZSBPUyBjaG9vc2UuCisgICAgICAgICAqIEhhcmQtY29kaW5nIHBvcnRzIGlzIGV2aWwsIHNvIGFsd2F5cyBwYXNzIDAhCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgaW50IGluaXQoaW50IHBvcnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzcyA9IG5ldyBTZXJ2ZXJTb2NrZXQocG9ydCk7CisgICAgICAgICAgICBzcy5zZXRTb1RpbWVvdXQoNTAwMCk7CisgICAgICAgICAgICBzcy5zZXRSZXVzZUFkZHJlc3ModHJ1ZSk7CisgICAgICAgICAgICByZXR1cm4gc3MuZ2V0TG9jYWxQb3J0KCk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogTWFpbiB0aHJlYWQgcmVzcG9uZGluZyB0byBuZXcgY29ubmVjdGlvbnMKKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBydW4oKSB7CisgICAgICAgICAgICBydW5uaW5nID0gdHJ1ZTsKKyAgICAgICAgICAgIHdoaWxlIChydW5uaW5nKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgU29ja2V0IHMgPSBzcy5hY2NlcHQoKTsKKyAgICAgICAgICAgICAgICAgICAgYWNjZXB0ZWRDb25uZWN0aW9ucysrOworICAgICAgICAgICAgICAgICAgICBpZiAoYWNjZXB0ZWRDb25uZWN0aW9ucyA+PSBhY2NlcHRMaW1pdCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcnVubmluZyA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIG5ldyBUaHJlYWQobmV3IFdvcmtlcihzKSwgImFkZGl0aW9uYWwgd29ya2VyIikuc3RhcnQoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBsb2coZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgbG9nKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsb2coIkFjY2VwdFRocmVhZCB0ZXJtaW5hdGVkIiArIHRoaXMpOworICAgICAgICB9CisKKyAgICAgICAgLy8gQ2xvc2UgdGhpcyBzb2NrZXQKKyAgICAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHJ1bm5pbmcgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAvKiBTdG9wIHNlcnZlciBzb2NrZXQgZnJvbSBwcm9jZXNzaW5nIGZ1cnRoZXIuIEN1cnJlbnRseQorICAgICAgICAgICAgICAgICAgIHRoaXMgZG9lcyBub3QgY2F1c2UgdGhlIFNvY2tldEV4Y2VwdGlvbiBmcm9tIHNzLmFjY2VwdAorICAgICAgICAgICAgICAgICAgIHRoZXJlZm9yZSB0aGUgYWNjZXB0TGltaXQgZnVuY3Rpb25hbGl0eSBoYXMgYmVlbiBhZGRlZAorICAgICAgICAgICAgICAgICAgIHRvIGNpcmN1bXZlbnQgdGhpcyBsaW1pdGF0aW9uICovCisgICAgICAgICAgICAgICAgc3MuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvKiBXZSBhcmUgc2h1dHRpbmcgZG93biB0aGUgc2VydmVyLCBzbyB3ZSBleHBlY3QKKyAgICAgICAgICAgICAgICAgKiB0aGluZ3MgdG8gZGllLiBEb24ndCBwcm9wYWdhdGUuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgbG9nKCJJT0V4Y2VwdGlvbiBjYXVnaHQgYnkgc2VydmVyIHNvY2tldCBjbG9zZSIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLy8gU2l6ZSBvZiBidWZmZXIgZm9yIHJlYWRpbmcgZnJvbSB0aGUgY29ubmVjdGlvbgorICAgIGZpbmFsIHN0YXRpYyBpbnQgQlVGX1NJWkUgPSAyMDQ4OworCisgICAgLyogRW5kIG9mIGxpbmUgYnl0ZSBzZXF1ZW5jZSAqLworICAgIHN0YXRpYyBmaW5hbCBieXRlW10gRU9MID0geyhieXRlKSdccicsIChieXRlKSdcbicgfTsKKworICAgIC8qKgorICAgICAqIEFuIGltbXV0YWJsZSBzbmFwc2hvdCBvZiBhbiBIVFRQIHJlcXVlc3QuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBSZXF1ZXN0IHsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcGF0aDsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IGhlYWRlcnM7CisgICAgICAgIC8vIFRPRE86IGluY2x1ZGUgcG9zdGVkIGNvbnRlbnQ/CisKKyAgICAgICAgcHVibGljIFJlcXVlc3QoU3RyaW5nIHBhdGgsIE1hcDxTdHJpbmcsIFN0cmluZz4gaGVhZGVycykgeworICAgICAgICAgICAgdGhpcy5wYXRoID0gcGF0aDsKKyAgICAgICAgICAgIHRoaXMuaGVhZGVycyA9IG5ldyBMaW5rZWRIYXNoTWFwPFN0cmluZywgU3RyaW5nPihoZWFkZXJzKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGF0aCgpIHsKKyAgICAgICAgICAgIHJldHVybiBwYXRoOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE1hcDxTdHJpbmcsIFN0cmluZz4gZ2V0SGVhZGVycygpIHsKKyAgICAgICAgICAgIHJldHVybiBoZWFkZXJzOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIHdvcmtlciB0aHJlYWQgaGFuZGxlcyBhbGwgaW50ZXJhY3Rpb25zIHdpdGggYSBjdXJyZW50IG9wZW4KKyAgICAgKiBjb25uZWN0aW9uLiBJZiBwaXBlbGluaW5nIGlzIHR1cm5lZCBvbiwgdGhpcyB3aWxsIGFsbG93IHRoaXMKKyAgICAgKiB0aHJlYWQgdG8gY29udGludW91c2x5IG9wZXJhdGUgb24gbnVtZXJvdXMgcmVxdWVzdHMgYmVmb3JlIHRoZQorICAgICAqIGNvbm5lY3Rpb24gaXMgY2xvc2VkLgorICAgICAqLworICAgIGNsYXNzIFdvcmtlciBpbXBsZW1lbnRzIFN1cHBvcnRfSHR0cENvbnN0YW50cywgUnVubmFibGUgeworCisgICAgICAgIC8qIGJ1ZmZlciB0byB1c2UgdG8gaG9sZCByZXF1ZXN0IGRhdGEgKi8KKyAgICAgICAgYnl0ZVtdIGJ1ZjsKKworICAgICAgICAvKiBTb2NrZXQgdG8gY2xpZW50IHdlJ3JlIGhhbmRsaW5nICovCisgICAgICAgIHByaXZhdGUgU29ja2V0IHM7CisKKyAgICAgICAgLyogUmVmZXJlbmNlIHRvIGN1cnJlbnQgcmVxdWVzdCBtZXRob2QgSUQgKi8KKyAgICAgICAgcHJpdmF0ZSBpbnQgcmVxdWVzdE1ldGhvZDsKKworICAgICAgICAvKiBSZWZlcmVuY2UgdG8gY3VycmVudCByZXF1ZXN0cyB0ZXN0IGZpbGUvZGF0YSAqLworICAgICAgICBwcml2YXRlIFN0cmluZyB0ZXN0SUQ7CisKKyAgICAgICAgLyogVGhlIHJlcXVlc3RlZCBwYXRoLCBzdWNoIGFzICIvdGVzdDEiICovCisgICAgICAgIHByaXZhdGUgU3RyaW5nIHBhdGg7CisKKyAgICAgICAgLyogUmVmZXJlbmNlIHRvIHRlc3QgbnVtYmVyIGZyb20gdGVzdElEICovCisgICAgICAgIHByaXZhdGUgaW50IHRlc3ROdW07CisKKyAgICAgICAgLyogUmVmZXJlbmNlIHRvIHdoZXRoZXIgbmV3IHJlcXVlc3QgaGFzIGJlZW4gaW5pdGlhdGVkIHlldCAqLworICAgICAgICBwcml2YXRlIGJvb2xlYW4gcmVhZFN0YXJ0ZWQ7CisKKyAgICAgICAgLyogSW5kaWNhdGVzIHdoZXRoZXIgY3VycmVudCByZXF1ZXN0IGhhcyBhbnkgZGF0YSBjb250ZW50ICovCisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBoYXNDb250ZW50ID0gZmFsc2U7CisKKyAgICAgICAgLyogUmVxdWVzdCBoZWFkZXJzIGFyZSBzdG9yZWQgaGVyZSAqLworICAgICAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFN0cmluZz4gaGVhZGVycyA9IG5ldyBMaW5rZWRIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOworCisgICAgICAgIC8qIENyZWF0ZSBhIG5ldyB3b3JrZXIgdGhyZWFkICovCisgICAgICAgIFdvcmtlcihTb2NrZXQgcykgeworICAgICAgICAgICAgdGhpcy5idWYgPSBuZXcgYnl0ZVtCVUZfU0laRV07CisgICAgICAgICAgICB0aGlzLnMgPSBzOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaGFuZGxlQ2xpZW50KCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIGxvZygiRXhjZXB0aW9uIGR1cmluZyBoYW5kbGVDbGllbnQgaW4gdGhlIFRlc3RXZWJTZXJ2ZXI6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsb2codGhpcysiIHRlcm1pbmF0ZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBaZXJvIG91dCB0aGUgYnVmZmVyIGZyb20gbGFzdCB0aW1lCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIHZvaWQgY2xlYXJCdWZmZXIoKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEJVRl9TSVpFOyBpKyspIHsKKyAgICAgICAgICAgICAgICBidWZbaV0gPSAwOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFV0aWxpdHkgbWV0aG9kIHRvIHJlYWQgYSBsaW5lIG9mIGRhdGEgZnJvbSB0aGUgaW5wdXQgc3RyZWFtCisgICAgICAgICAqIEBwYXJhbSBpcyBJbnB1dHN0cmVhbSB0byByZWFkCisgICAgICAgICAqIEByZXR1cm4gbnVtYmVyIG9mIGJ5dGVzIHJlYWQKKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgaW50IHJlYWRPbmVMaW5lKElucHV0U3RyZWFtIGlzKSB7CisKKyAgICAgICAgICAgIGludCByZWFkID0gMDsKKworICAgICAgICAgICAgY2xlYXJCdWZmZXIoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbG9nKCJSZWFkaW5nIG9uZSBsaW5lOiBzdGFydGVkID0iK3JlYWRTdGFydGVkKyIgYXZhaWw9Iitpcy5hdmFpbGFibGUoKSk7CisgICAgICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBsb2cgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICAgICAgICAgIHdoaWxlICgoIXJlYWRTdGFydGVkKSB8fCAoaXMuYXZhaWxhYmxlKCkgPiAwKSkgeworICAgICAgICAgICAgICAgICAgICBpbnQgZGF0YSA9IGlzLnJlYWQoKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gV2Ugc2hvdWxkbid0IGdldCBFT0YgYnV0IHdlIG5lZWQgdGRvIGNoZWNrCisgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBsb2coIkVPRiByZXR1cm5lZCIpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgYnVmW3JlYWRdID0gKGJ5dGUpZGF0YTsKKworICAgICAgICAgICAgICAgICAgICBsb2cuYXBwZW5kKChjaGFyKWRhdGEpOworCisgICAgICAgICAgICAgICAgICAgIHJlYWRTdGFydGVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGJ1ZltyZWFkKytdPT0oYnl0ZSknXG4nKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBsb2cobG9nLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWQ7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgbG9nKCJJT0V4Y2VwdGlvbiBmcm9tIHJlYWRPbmVMaW5lIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gcmVhZDsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBSZWFkIGEgY2h1bmsgb2YgZGF0YQorICAgICAgICAgKiBAcGFyYW0gaXMgU3RyZWFtIGZyb20gd2hpY2ggdG8gcmVhZCBkYXRhCisgICAgICAgICAqIEBwYXJhbSBsZW5ndGggQW1vdW50IG9mIGRhdGEgdG8gcmVhZAorICAgICAgICAgKiBAcmV0dXJuIG51bWJlciBvZiBieXRlcyByZWFkCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGludCByZWFkRGF0YShJbnB1dFN0cmVhbSBpcywgaW50IGxlbmd0aCkgeworICAgICAgICAgICAgaW50IHJlYWQgPSAwOworICAgICAgICAgICAgaW50IGNvdW50OworICAgICAgICAgICAgLy8gQXQgdGhlIG1vbWVudCB3ZSdyZSBvbmx5IGV4cGVjdGluZyBzbWFsbCBkYXRhIGFtb3VudHMKKyAgICAgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVtsZW5ndGhdOworCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHdoaWxlIChpcy5hdmFpbGFibGUoKSA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgY291bnQgPSBpcy5yZWFkKGJ1ZiwgcmVhZCwgbGVuZ3RoLXJlYWQpOworICAgICAgICAgICAgICAgICAgICByZWFkICs9IGNvdW50OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBsb2coIklPRXhjZXB0aW9uIGZyb20gcmVhZERhdGEiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiByZWFkOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFJlYWQgdGhlIHN0YXR1cyBsaW5lIGZyb20gdGhlIGlucHV0IHN0cmVhbSBleHRyYWN0aW5nIG1ldGhvZAorICAgICAgICAgKiBpbmZvcm1hdGlvbi4KKyAgICAgICAgICogQHBhcmFtIGlzIElucHV0c3RyZWFtIHRvIHJlYWQKKyAgICAgICAgICogQHJldHVybiBudW1iZXIgb2YgYnl0ZXMgcmVhZAorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBpbnQgcGFyc2VTdGF0dXNMaW5lKElucHV0U3RyZWFtIGlzKSB7CisgICAgICAgICAgICBpbnQgaW5kZXg7CisgICAgICAgICAgICBpbnQgbnJlYWQgPSAwOworCisgICAgICAgICAgICBsb2coIlBhcnNlIHN0YXR1cyBsaW5lIik7CisgICAgICAgICAgICAvLyBDaGVjayBmb3Igc3RhdHVzIGxpbmUgZmlyc3QKKyAgICAgICAgICAgIG5yZWFkID0gcmVhZE9uZUxpbmUoaXMpOworICAgICAgICAgICAgLy8gQm9tYiBvdXQgaWYgc3RyZWFtIGNsb3NlcyBwcmVtYXR1cmVseQorICAgICAgICAgICAgaWYgKG5yZWFkID09IC0xKSB7CisgICAgICAgICAgICAgICAgcmVxdWVzdE1ldGhvZCA9IFVOS05PV05fTUVUSE9EOworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGJ1ZlswXSA9PSAoYnl0ZSknRycgJiYKKyAgICAgICAgICAgICAgICBidWZbMV0gPT0gKGJ5dGUpJ0UnICYmCisgICAgICAgICAgICAgICAgYnVmWzJdID09IChieXRlKSdUJyAmJgorICAgICAgICAgICAgICAgIGJ1ZlszXSA9PSAoYnl0ZSknICcpIHsKKyAgICAgICAgICAgICAgICByZXF1ZXN0TWV0aG9kID0gR0VUX01FVEhPRDsKKyAgICAgICAgICAgICAgICBsb2coIkdFVCByZXF1ZXN0Iik7CisgICAgICAgICAgICAgICAgaW5kZXggPSA0OworICAgICAgICAgICAgfSBlbHNlIGlmIChidWZbMF0gPT0gKGJ5dGUpJ0gnICYmCisgICAgICAgICAgICAgICAgICAgICAgIGJ1ZlsxXSA9PSAoYnl0ZSknRScgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgYnVmWzJdID09IChieXRlKSdBJyAmJgorICAgICAgICAgICAgICAgICAgICAgICBidWZbM10gPT0gKGJ5dGUpJ0QnICYmCisgICAgICAgICAgICAgICAgICAgICAgIGJ1Zls0XSA9PSAoYnl0ZSknICcpIHsKKyAgICAgICAgICAgICAgICByZXF1ZXN0TWV0aG9kID0gSEVBRF9NRVRIT0Q7CisgICAgICAgICAgICAgICAgbG9nKCJIRUFEIHJlcXVlc3QiKTsKKyAgICAgICAgICAgICAgICBpbmRleCA9IDU7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGJ1ZlswXSA9PSAoYnl0ZSknUCcgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgYnVmWzFdID09IChieXRlKSdPJyAmJgorICAgICAgICAgICAgICAgICAgICAgICBidWZbMl0gPT0gKGJ5dGUpJ1MnICYmCisgICAgICAgICAgICAgICAgICAgICAgIGJ1ZlszXSA9PSAoYnl0ZSknVCcgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgYnVmWzRdID09IChieXRlKScgJykgeworICAgICAgICAgICAgICAgIHJlcXVlc3RNZXRob2QgPSBQT1NUX01FVEhPRDsKKyAgICAgICAgICAgICAgICBsb2coIlBPU1QgcmVxdWVzdCIpOworICAgICAgICAgICAgICAgIGluZGV4ID0gNTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gVW5oYW5kbGVkIHJlcXVlc3QKKyAgICAgICAgICAgICAgICByZXF1ZXN0TWV0aG9kID0gVU5LTk9XTl9NRVRIT0Q7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBBIHZhbGlkIG1ldGhvZCB3ZSB1bmRlcnN0YW5kCisgICAgICAgICAgICBpZiAocmVxdWVzdE1ldGhvZCA+IFVOS05PV05fTUVUSE9EKSB7CisgICAgICAgICAgICAgICAgLy8gUmVhZCBmaWxlIG5hbWUKKyAgICAgICAgICAgICAgICBpbnQgaSA9IGluZGV4OworICAgICAgICAgICAgICAgIHdoaWxlIChidWZbaV0gIT0gKGJ5dGUpJyAnKSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFRoZXJlIHNob3VsZCBiZSBIVFRQLzEueCBhdCB0aGUgZW5kCisgICAgICAgICAgICAgICAgICAgIGlmICgoYnVmW2ldID09IChieXRlKSdcbicpIHx8IChidWZbaV0gPT0gKGJ5dGUpJ1xyJykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RNZXRob2QgPSBVTktOT1dOX01FVEhPRDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpKys7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgcGF0aCA9IG5ldyBTdHJpbmcoYnVmLCAwLCBpbmRleCwgaS1pbmRleCk7CisgICAgICAgICAgICAgICAgdGVzdElEID0gcGF0aC5zdWJzdHJpbmcoMSk7CisKKyAgICAgICAgICAgICAgICByZXR1cm4gbnJlYWQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmVhZCBhIGhlYWRlciBmcm9tIHRoZSBpbnB1dCBzdHJlYW0KKyAgICAgICAgICogQHBhcmFtIGlzIElucHV0c3RyZWFtIHRvIHJlYWQKKyAgICAgICAgICogQHJldHVybiBudW1iZXIgb2YgYnl0ZXMgcmVhZAorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBpbnQgcGFyc2VIZWFkZXIoSW5wdXRTdHJlYW0gaXMpIHsKKyAgICAgICAgICAgIGludCBpbmRleCA9IDA7CisgICAgICAgICAgICBpbnQgbnJlYWQgPSAwOworICAgICAgICAgICAgbG9nKCJQYXJzZSBhIGhlYWRlciIpOworICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIHN0YXR1cyBsaW5lIGZpcnN0CisgICAgICAgICAgICBucmVhZCA9IHJlYWRPbmVMaW5lKGlzKTsKKyAgICAgICAgICAgIC8vIEJvbWIgb3V0IGlmIHN0cmVhbSBjbG9zZXMgcHJlbWF0dXJlbHkKKyAgICAgICAgICAgIGlmIChucmVhZCA9PSAtMSkgeworICAgICAgICAgICAgICAgIHJlcXVlc3RNZXRob2QgPSBVTktOT1dOX01FVEhPRDsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBSZWFkIGhlYWRlciBlbnRyeSAnSGVhZGVyOiBkYXRhJworICAgICAgICAgICAgaW50IGkgPSBpbmRleDsKKyAgICAgICAgICAgIHdoaWxlIChidWZbaV0gIT0gKGJ5dGUpJzonKSB7CisgICAgICAgICAgICAgICAgLy8gVGhlcmUgc2hvdWxkIGJlIGFuIGVudHJ5IGFmdGVyIHRoZSBoZWFkZXIKKworICAgICAgICAgICAgICAgIGlmICgoYnVmW2ldID09IChieXRlKSdcbicpIHx8IChidWZbaV0gPT0gKGJ5dGUpJ1xyJykpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFVOS05PV05fTUVUSE9EOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpKys7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFN0cmluZyBoZWFkZXJOYW1lID0gbmV3IFN0cmluZyhidWYsIDAsIGkpOworICAgICAgICAgICAgaSsrOyAvLyBPdmVyICc6JworICAgICAgICAgICAgd2hpbGUgKGJ1ZltpXSA9PSAnICcpIHsKKyAgICAgICAgICAgICAgICBpKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTdHJpbmcgaGVhZGVyVmFsdWUgPSBuZXcgU3RyaW5nKGJ1ZiwgaSwgbnJlYWQgLSBpIC0gMik7IC8vIGRyb3AgXHJcbgorCisgICAgICAgICAgICBoZWFkZXJzLnB1dChoZWFkZXJOYW1lLCBoZWFkZXJWYWx1ZSk7CisgICAgICAgICAgICByZXR1cm4gbnJlYWQ7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmVhZCBhbGwgaGVhZGVycyBmcm9tIHRoZSBpbnB1dCBzdHJlYW0KKyAgICAgICAgICogQHBhcmFtIGlzIElucHV0c3RyZWFtIHRvIHJlYWQKKyAgICAgICAgICogQHJldHVybiBudW1iZXIgb2YgYnl0ZXMgcmVhZAorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBpbnQgcmVhZEhlYWRlcnMoSW5wdXRTdHJlYW0gaXMpIHsKKyAgICAgICAgICAgIGludCBucmVhZCA9IDA7CisgICAgICAgICAgICBsb2coIlJlYWQgaGVhZGVycyIpOworICAgICAgICAgICAgLy8gSGVhZGVycyBzaG91bGQgYmUgdGVybWluYXRlZCBieSBlbXB0eSBDUkxGIGxpbmUKKyAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgaW50IGhlYWRlckxlbiA9IDA7CisgICAgICAgICAgICAgICAgaGVhZGVyTGVuID0gcGFyc2VIZWFkZXIoaXMpOworICAgICAgICAgICAgICAgIGlmIChoZWFkZXJMZW4gPT0gLTEpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgICAgICBucmVhZCArPSBoZWFkZXJMZW47CisgICAgICAgICAgICAgICAgaWYgKGhlYWRlckxlbiA8PSAyKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBucmVhZDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogUmVhZCBjb250ZW50IGRhdGEgZnJvbSB0aGUgaW5wdXQgc3RyZWFtCisgICAgICAgICAqIEBwYXJhbSBpcyBJbnB1dHN0cmVhbSB0byByZWFkCisgICAgICAgICAqIEByZXR1cm4gbnVtYmVyIG9mIGJ5dGVzIHJlYWQKKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgaW50IHJlYWRDb250ZW50KElucHV0U3RyZWFtIGlzKSB7CisgICAgICAgICAgICBpbnQgbnJlYWQgPSAwOworICAgICAgICAgICAgbG9nKCJSZWFkIGNvbnRlbnQiKTsKKyAgICAgICAgICAgIFN0cmluZyBsZW5ndGhTdHJpbmcgPSBoZWFkZXJzLmdldChyZXF1ZXN0SGVhZGVyc1tSRVFfQ09OVEVOVF9MRU5HVEhdKTsKKyAgICAgICAgICAgIGludCBsZW5ndGggPSBuZXcgSW50ZWdlcihsZW5ndGhTdHJpbmcpLmludFZhbHVlKCk7CisKKyAgICAgICAgICAgIC8vIFJlYWQgY29udGVudAorICAgICAgICAgICAgbGVuZ3RoID0gcmVhZERhdGEoaXMsIGxlbmd0aCk7CisgICAgICAgICAgICByZXR1cm4gbGVuZ3RoOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBtYWluIGxvb3AsIHJlYWRpbmcgcmVxdWVzdHMuCisgICAgICAgICAqLworICAgICAgICB2b2lkIGhhbmRsZUNsaWVudCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKHMuZ2V0SW5wdXRTdHJlYW0oKSk7CisgICAgICAgICAgICBQcmludFN0cmVhbSBwcyA9IG5ldyBQcmludFN0cmVhbShzLmdldE91dHB1dFN0cmVhbSgpKTsKKyAgICAgICAgICAgIGludCBucmVhZCA9IDA7CisKKyAgICAgICAgICAgIC8qIHdlIHdpbGwgb25seSBibG9jayBpbiByZWFkIGZvciB0aGlzIG1hbnkgbWlsbGlzZWNvbmRzCisgICAgICAgICAgICAgKiBiZWZvcmUgd2UgZmFpbCB3aXRoIGphdmEuaW8uSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbiwKKyAgICAgICAgICAgICAqIGF0IHdoaWNoIHBvaW50IHdlIHdpbGwgYWJhbmRvbiB0aGUgY29ubmVjdGlvbi4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgcy5zZXRTb1RpbWVvdXQobVRpbWVvdXQpOworICAgICAgICAgICAgcy5zZXRUY3BOb0RlbGF5KHRydWUpOworCisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgbnJlYWQgPSBwYXJzZVN0YXR1c0xpbmUoaXMpOworICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0TWV0aG9kICE9IFVOS05PV05fTUVUSE9EKSB7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gSWYgc3RhdHVzIGxpbmUgZm91bmQsIHJlYWQgYW55IGhlYWRlcnMKKyAgICAgICAgICAgICAgICAgICAgbnJlYWQgPSByZWFkSGVhZGVycyhpcyk7CisKKyAgICAgICAgICAgICAgICAgICAgcGF0aFRvUmVxdWVzdCgpLnB1dChwYXRoLCBuZXcgUmVxdWVzdChwYXRoLCBoZWFkZXJzKSk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gVGhlbiByZWFkIGNvbnRlbnQgKGlmIGFueSkKKyAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyBoYW5kbGUgY2h1bmtlZCBlbmNvZGluZyBmcm9tIHRoZSBjbGllbnQKKyAgICAgICAgICAgICAgICAgICAgaWYgKGhlYWRlcnMuZ2V0KHJlcXVlc3RIZWFkZXJzW1JFUV9DT05URU5UX0xFTkdUSF0pICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG5yZWFkID0gcmVhZENvbnRlbnQoaXMpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5yZWFkID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgLyogd2UgZG9uJ3Qgc3VwcG9ydCB0aGlzIG1ldGhvZCAqLworICAgICAgICAgICAgICAgICAgICAgICAgcHMucHJpbnQoSFRUUF9WRVJTSU9OX1NUUklORyArICIgIiArIEhUVFBfQkFEX01FVEhPRCArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIHVuc3VwcG9ydGVkIG1ldGhvZCB0eXBlOiAiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBzLndyaXRlKGJ1ZiwgMCwgNSk7CisgICAgICAgICAgICAgICAgICAgICAgICBwcy53cml0ZShFT0wpOworICAgICAgICAgICAgICAgICAgICAgICAgcHMuZmx1c2goKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoIWtlZXBBbGl2ZSB8fCBucmVhZCA8PSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzLmNsZWFyKCk7CisgICAgICAgICAgICAgICAgICAgICAgICByZWFkU3RhcnRlZCA9IGZhbHNlOworCisgICAgICAgICAgICAgICAgICAgICAgICBsb2coIlNPQ0tFVCBDTE9TRUQiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIFJlc2V0IHRlc3QgbnVtYmVyIHByaW9yIHRvIG91dHB1dGluZyBkYXRhCisgICAgICAgICAgICAgICAgdGVzdE51bSA9IC0xOworCisgICAgICAgICAgICAgICAgLy8gV3JpdGUgb3V0IHRoZSBkYXRhCisgICAgICAgICAgICAgICAgcHJpbnRTdGF0dXMocHMpOworICAgICAgICAgICAgICAgIHByaW50SGVhZGVycyhwcyk7CisKKyAgICAgICAgICAgICAgICAvLyBXcml0ZSBsaW5lIGJldHdlZW4gaGVhZGVycyBhbmQgYm9keQorICAgICAgICAgICAgICAgIHBzV3JpdGVFT0wocHMpOworCisgICAgICAgICAgICAgICAgLy8gV3JpdGUgdGhlIGJvZHkKKyAgICAgICAgICAgICAgICBpZiAocmVkaXJlY3RDb2RlID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAocmVxdWVzdE1ldGhvZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBHRVRfTUVUSE9EOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgodGVzdE51bSA8IC0xKSB8fCAodGVzdE51bSA+IFN1cHBvcnRfVGVzdFdlYkRhdGEudGVzdHMubGVuZ3RoIC0gMSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZDQwNChwcyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZEZpbGUocHMpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSEVBRF9NRVRIT0Q6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90aGluZyB0byBkbworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBQT1NUX01FVEhPRDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQb3N0IG1ldGhvZCB3cml0ZSBib2R5IGRhdGEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKHRlc3ROdW0gPiAwKSB8fCAodGVzdE51bSA8IFN1cHBvcnRfVGVzdFdlYkRhdGEudGVzdHMubGVuZ3RoIC0gMSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZEZpbGUocHMpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIFJlZGlyZWN0aW5nCisgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAocmVkaXJlY3RDb2RlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDMwMToKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZWVtcyAzMDEgbmVlZHMgYSBib2R5IGJ5IG5lb24gKGFsdGhvdWdoIHNwZWMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzYXlzIFNIT1VMRCkuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHNQcmludChwcywgU3VwcG9ydF9UZXN0V2ViRGF0YS50ZXN0U2VydmVyUmVzcG9uc2VbU3VwcG9ydF9UZXN0V2ViRGF0YS5SRURJUkVDVF8zMDFdKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMzAyOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHNQcmludChwcywgU3VwcG9ydF9UZXN0V2ViRGF0YS50ZXN0U2VydmVyUmVzcG9uc2VbU3VwcG9ydF9UZXN0V2ViRGF0YS5SRURJUkVDVF8zMDJdKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMzAzOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzUHJpbnQocHMsIFN1cHBvcnRfVGVzdFdlYkRhdGEudGVzdFNlcnZlclJlc3BvbnNlW1N1cHBvcnRfVGVzdFdlYkRhdGEuUkVESVJFQ1RfMzAzXSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDMwNzoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc1ByaW50KHBzLCBTdXBwb3J0X1Rlc3RXZWJEYXRhLnRlc3RTZXJ2ZXJSZXNwb25zZVtTdXBwb3J0X1Rlc3RXZWJEYXRhLlJFRElSRUNUXzMwN10pOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHBzLmZsdXNoKCk7CisKKyAgICAgICAgICAgICAgICAvLyBSZXNldCBmb3IgbmV4dCByZXF1ZXN0CisgICAgICAgICAgICAgICAgcmVhZFN0YXJ0ZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBoZWFkZXJzLmNsZWFyKCk7CisKKyAgICAgICAgICAgIH0gd2hpbGUgKGtlZXBBbGl2ZSk7CisKKyAgICAgICAgICAgIGxvZygiU09DS0VUIENMT1NFRCIpOworICAgICAgICAgICAgcy5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gUHJpbnQgc3RyaW5nIHRvIGxvZyBhbmQgb3V0cHV0IHN0cmVhbQorICAgICAgICB2b2lkIHBzUHJpbnQoUHJpbnRTdHJlYW0gcHMsIFN0cmluZyBzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgbG9nKHMpOworICAgICAgICAgICAgcHMucHJpbnQocyk7CisgICAgICAgIH0KKworICAgICAgICAvLyBQcmludCBieXRlcyB0byBsb2cgYW5kIG91dHB1dCBzdHJlYW0KKyAgICAgICAgdm9pZCBwc1dyaXRlKFByaW50U3RyZWFtIHBzLCBieXRlW10gYnl0ZXMsIGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGxvZyhuZXcgU3RyaW5nKGJ5dGVzKSk7CisgICAgICAgICAgICBwcy53cml0ZShieXRlcywgb2Zmc2V0LCBjb3VudCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBQcmludCBDUkxGIHRvIGxvZyBhbmQgb3V0cHV0IHN0cmVhbQorICAgICAgICB2b2lkIHBzV3JpdGVFT0woUHJpbnRTdHJlYW0gcHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBsb2coIkNSTEYiKTsKKyAgICAgICAgICAgIHBzLndyaXRlKEVPTCk7CisgICAgICAgIH0KKworCisgICAgICAgIC8vIFByaW50IHN0YXR1cyB0byBsb2cgYW5kIG91dHB1dCBzdHJlYW0KKyAgICAgICAgdm9pZCBwcmludFN0YXR1cyhQcmludFN0cmVhbSBwcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIC8vIEhhbmRsZSByZWRpcmVjdHMgZmlyc3QuCisgICAgICAgICAgICBpZiAocmVkaXJlY3RDb2RlICE9IC0xKSB7CisgICAgICAgICAgICAgICAgbG9nKCJSRURJUkVDVElORyBUTyAiK3JlZGlyZWN0SG9zdCsiIHN0YXR1cyAiK3JlZGlyZWN0Q29kZSk7CisgICAgICAgICAgICAgICAgcHNQcmludChwcywgSFRUUF9WRVJTSU9OX1NUUklORyArICIgIiArIHJlZGlyZWN0Q29kZSArIiBNb3ZlZCBwZXJtYW5lbnRseSIpOworICAgICAgICAgICAgICAgIHBzV3JpdGVFT0wocHMpOworICAgICAgICAgICAgICAgIHBzUHJpbnQocHMsICJMb2NhdGlvbjogIiArIHJlZGlyZWN0SG9zdCk7CisgICAgICAgICAgICAgICAgcHNXcml0ZUVPTChwcyk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorCisKKyAgICAgICAgICAgIGlmICh0ZXN0SUQuc3RhcnRzV2l0aCgidGVzdCIpKSB7CisgICAgICAgICAgICAgICAgdGVzdE51bSA9IEludGVnZXIudmFsdWVPZih0ZXN0SUQuc3Vic3RyaW5nKDQpKS0xOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoKHRlc3ROdW0gPCAtMSkgfHwgKHRlc3ROdW0gPiBTdXBwb3J0X1Rlc3RXZWJEYXRhLnRlc3RzLmxlbmd0aCAtIDEpKSB7CisgICAgICAgICAgICAgICAgcHNQcmludChwcywgSFRUUF9WRVJTSU9OX1NUUklORyArICIgIiArIEhUVFBfTk9UX0ZPVU5EICsgIiBub3QgZm91bmQiKTsKKyAgICAgICAgICAgICAgICBwc1dyaXRlRU9MKHBzKTsKKyAgICAgICAgICAgIH0gIGVsc2UgeworICAgICAgICAgICAgICAgIHBzUHJpbnQocHMsIEhUVFBfVkVSU0lPTl9TVFJJTkcgKyAiICIgKyBIVFRQX09LKyIgT0siKTsKKyAgICAgICAgICAgICAgICBwc1dyaXRlRU9MKHBzKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgbG9nKCJTdGF0dXMgc2VudCIpOworICAgICAgICB9CisgICAgICAgIC8qKgorICAgICAgICAgKiBDcmVhdGUgdGhlIHNlcnZlciByZXNwb25zZSBhbmQgb3V0cHV0IHRvIHRoZSBzdHJlYW0KKyAgICAgICAgICogQHBhcmFtIHBzIFRoZSBQcmludFN0cmVhbSB0byBvdXRwdXQgcmVzcG9uc2UgaGVhZGVycyBhbmQgZGF0YSB0bworICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBwcmludEhlYWRlcnMoUHJpbnRTdHJlYW0gcHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoKHRlc3ROdW0gPCAtMSkgfHwgKHRlc3ROdW0gPiBTdXBwb3J0X1Rlc3RXZWJEYXRhLnRlc3RzLmxlbmd0aCAtIDEpKSB7CisgICAgICAgICAgICAgICAgLy8gNDA0IHN0YXR1cyBhbHJlYWR5IHNlbnQKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IGRmID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoIkVFLCBkZCBNTU0geXl5eSBISDptbTpzcyIpOworCisgICAgICAgICAgICBwc1ByaW50KHBzLCJTZXJ2ZXI6IFRlc3RXZWJTZXJ2ZXIiK21Qb3J0KTsKKyAgICAgICAgICAgIHBzV3JpdGVFT0wocHMpOworICAgICAgICAgICAgcHNQcmludChwcywgIkRhdGU6ICIgKyBkZi5mb3JtYXQobmV3IERhdGUoKSkpOworICAgICAgICAgICAgcHNXcml0ZUVPTChwcyk7CisgICAgICAgICAgICBwc1ByaW50KHBzLCAiQ29ubmVjdGlvbjogIiArICgoa2VlcEFsaXZlKSA/ICJLZWVwLUFsaXZlIiA6ICJDbG9zZSIpKTsKKyAgICAgICAgICAgIHBzV3JpdGVFT0wocHMpOworCisgICAgICAgICAgICAvLyBZdWssIGlmIHdlJ3JlIG5vdCByZWRpcmVjdGluZywgd2UgYWRkIHRoZSBmaWxlIGRldGFpbHMKKyAgICAgICAgICAgIGlmIChyZWRpcmVjdENvZGUgPT0gLTEpIHsKKworICAgICAgICAgICAgICAgIGlmICh0ZXN0TnVtID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICghU3VwcG9ydF9UZXN0V2ViRGF0YS50ZXN0MERhdGFBdmFpbGFibGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvZygidGVzdGRhdGEgd2FzIG5vdCBpbml0aWxhaXplZCIpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChjaHVua2VkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwc1ByaW50KHBzLCAiVHJhbnNmZXItRW5jb2Rpbmc6IGNodW5rZWQiKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBzUHJpbnQocHMsICJDb250ZW50LWxlbmd0aDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIFN1cHBvcnRfVGVzdFdlYkRhdGEudGVzdDBEYXRhLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcHNXcml0ZUVPTChwcyk7CisKKyAgICAgICAgICAgICAgICAgICAgcHNQcmludChwcywgIkxhc3QgTW9kaWZpZWQ6ICIgKyAobmV3IERhdGUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3VwcG9ydF9UZXN0V2ViRGF0YS50ZXN0MFBhcmFtcy50ZXN0TGFzdE1vZGlmaWVkKSkpOworICAgICAgICAgICAgICAgICAgICBwc1dyaXRlRU9MKHBzKTsKKworICAgICAgICAgICAgICAgICAgICBwc1ByaW50KHBzLCAiQ29udGVudC10eXBlOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBTdXBwb3J0X1Rlc3RXZWJEYXRhLnRlc3QwUGFyYW1zLnRlc3RUeXBlKTsKKyAgICAgICAgICAgICAgICAgICAgcHNXcml0ZUVPTChwcyk7CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKFN1cHBvcnRfVGVzdFdlYkRhdGEudGVzdFBhcmFtc1t0ZXN0TnVtXS50ZXN0RXhwID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBleHA7CisgICAgICAgICAgICAgICAgICAgICAgICBleHAgPSBTdXBwb3J0X1Rlc3RXZWJEYXRhLnRlc3RQYXJhbXNbdGVzdE51bV0udGVzdEV4cDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBzUHJpbnQocHMsICJleHBpcmVzOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZGYuZm9ybWF0KGV4cCkgKyAiIEdNVCIpOworICAgICAgICAgICAgICAgICAgICAgICAgcHNXcml0ZUVPTChwcyk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFTdXBwb3J0X1Rlc3RXZWJEYXRhLnRlc3RQYXJhbXNbdGVzdE51bV0udGVzdERpcikgeworICAgICAgICAgICAgICAgICAgICBpZiAoY2h1bmtlZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcHNQcmludChwcywgIlRyYW5zZmVyLUVuY29kaW5nOiBjaHVua2VkIik7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwc1ByaW50KHBzLCAiQ29udGVudC1sZW5ndGg6ICIrU3VwcG9ydF9UZXN0V2ViRGF0YS50ZXN0UGFyYW1zW3Rlc3ROdW1dLnRlc3RMZW5ndGgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHBzV3JpdGVFT0wocHMpOworCisgICAgICAgICAgICAgICAgICAgIHBzUHJpbnQocHMsIkxhc3QgTW9kaWZpZWQ6ICIgKyAobmV3CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0ZShTdXBwb3J0X1Rlc3RXZWJEYXRhLnRlc3RQYXJhbXNbdGVzdE51bV0udGVzdExhc3RNb2RpZmllZCkpKTsKKyAgICAgICAgICAgICAgICAgICAgcHNXcml0ZUVPTChwcyk7CisKKyAgICAgICAgICAgICAgICAgICAgcHNQcmludChwcywgIkNvbnRlbnQtdHlwZTogIiArIFN1cHBvcnRfVGVzdFdlYkRhdGEudGVzdFBhcmFtc1t0ZXN0TnVtXS50ZXN0VHlwZSk7CisgICAgICAgICAgICAgICAgICAgIHBzV3JpdGVFT0wocHMpOworCisgICAgICAgICAgICAgICAgICAgIGlmIChTdXBwb3J0X1Rlc3RXZWJEYXRhLnRlc3RQYXJhbXNbdGVzdE51bV0udGVzdEV4cCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgZXhwOworICAgICAgICAgICAgICAgICAgICAgICAgZXhwID0gU3VwcG9ydF9UZXN0V2ViRGF0YS50ZXN0UGFyYW1zW3Rlc3ROdW1dLnRlc3RFeHA7CisgICAgICAgICAgICAgICAgICAgICAgICBwc1ByaW50KHBzLCAiZXhwaXJlczogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGRmLmZvcm1hdChleHApICsgIiBHTVQiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBzV3JpdGVFT0wocHMpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcHNQcmludChwcywgIkNvbnRlbnQtdHlwZTogdGV4dC9odG1sIik7CisgICAgICAgICAgICAgICAgICAgIHBzV3JpdGVFT0wocHMpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gQ29udGVudC1sZW5ndGggb2YgMzAxLCAzMDIsIDMwMywgMzA3IGFyZSB0aGUgc2FtZS4KKyAgICAgICAgICAgICAgICBwc1ByaW50KHBzLCAiQ29udGVudC1sZW5ndGg6ICIrKFN1cHBvcnRfVGVzdFdlYkRhdGEudGVzdFNlcnZlclJlc3BvbnNlW1N1cHBvcnRfVGVzdFdlYkRhdGEuUkVESVJFQ1RfMzAxXSkubGVuZ3RoKCkpOworICAgICAgICAgICAgICAgIHBzV3JpdGVFT0wocHMpOworICAgICAgICAgICAgICAgIHBzV3JpdGVFT0wocHMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbG9nKCJIZWFkZXJzIHNlbnQiKTsKKworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNlbmRzIHRoZSA0MDQgbm90IGZvdW5kIG1lc3NhZ2UKKyAgICAgICAgICogQHBhcmFtIHBzIFRoZSBQcmludFN0cmVhbSB0byB3cml0ZSB0bworICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBzZW5kNDA0KFByaW50U3RyZWFtIHBzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcHMucHJpbnRsbigiTm90IEZvdW5kXG5cbiIrCisgICAgICAgICAgICAgICAgICAgICAgICJUaGUgcmVxdWVzdGVkIHJlc291cmNlIHdhcyBub3QgZm91bmQuXG4iKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBTZW5kcyB0aGUgZGF0YSBhc3NvY2lhdGVkIHdpdGggdGhlIGhlYWRlcnMKKyAgICAgICAgICogQHBhcmFtIHBzIFRoZSBQcmludFN0cmVhbSB0byB3cml0ZSB0bworICAgICAgICAgKi8KKyAgICAgICAgdm9pZCBzZW5kRmlsZShQcmludFN0cmVhbSBwcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGlmICh0ZXN0TnVtID09IC0xKSB7CisgICAgICAgICAgICAgICAgaWYgKCFTdXBwb3J0X1Rlc3RXZWJEYXRhLnRlc3QwRGF0YUF2YWlsYWJsZSkgeworICAgICAgICAgICAgICAgICAgICBsb2coInRlc3QgZGF0YSB3YXMgbm90IGluaXRpYWxpemVkIik7CisgICAgICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc2VuZEZpbGUocHMsIFN1cHBvcnRfVGVzdFdlYkRhdGEudGVzdDBEYXRhKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgc2VuZEZpbGUocHMsIFN1cHBvcnRfVGVzdFdlYkRhdGEudGVzdHNbdGVzdE51bV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdm9pZCBzZW5kRmlsZShQcmludFN0cmVhbSBwcywgYnl0ZVtdIGJ5dGVzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgaWYgKGNodW5rZWQpIHsKKyAgICAgICAgICAgICAgICBpbnQgb2Zmc2V0ID0gMDsKKyAgICAgICAgICAgICAgICB3aGlsZSAob2Zmc2V0IDwgYnl0ZXMubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgICAgIGludCBjaHVua1NpemUgPSBNYXRoLm1pbihieXRlcy5sZW5ndGggLSBvZmZzZXQsIG1heENodW5rU2l6ZSk7CisgICAgICAgICAgICAgICAgICAgIHBzUHJpbnQocHMsIEludGVnZXIudG9IZXhTdHJpbmcoY2h1bmtTaXplKSk7CisgICAgICAgICAgICAgICAgICAgIHBzV3JpdGVFT0wocHMpOworICAgICAgICAgICAgICAgICAgICBwc1dyaXRlKHBzLCBieXRlcywgb2Zmc2V0LCBjaHVua1NpemUpOworICAgICAgICAgICAgICAgICAgICBwc1dyaXRlRU9MKHBzKTsKKyAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IGNodW5rU2l6ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcHNQcmludChwcywgIjAiKTsKKyAgICAgICAgICAgICAgICBwc1dyaXRlRU9MKHBzKTsKKyAgICAgICAgICAgICAgICBwc1dyaXRlRU9MKHBzKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcHNXcml0ZShwcywgYnl0ZXMsIDAsIGJ5dGVzLmxlbmd0aCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1VubW9kaWZpYWJsZUNvbGxlY3Rpb25UZXN0LmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1VubW9kaWZpYWJsZUNvbGxlY3Rpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWUyNjZjNgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L1N1cHBvcnRfVW5tb2RpZmlhYmxlQ29sbGVjdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDExMSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMuc3VwcG9ydDsKKworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkU2V0OworaW1wb3J0IGphdmEudXRpbC5UcmVlU2V0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIFN1cHBvcnRfVW5tb2RpZmlhYmxlQ29sbGVjdGlvblRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgICBDb2xsZWN0aW9uPEludGVnZXI+IGNvbDsKKworICAgIC8vIG11c3QgYmUgYSBjb2xsZWN0aW9uIGNvbnRhaW5pbmcgdGhlIEludGVnZXJzIDAgdG8gOTkgKHdoaWNoIHdpbGwgaXRlcmF0ZQorICAgIC8vIGluIG9yZGVyKQorCisgICAgcHVibGljIFN1cHBvcnRfVW5tb2RpZmlhYmxlQ29sbGVjdGlvblRlc3QoU3RyaW5nIHAxKSB7CisgICAgICAgIHN1cGVyKHAxKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3VwcG9ydF9Vbm1vZGlmaWFibGVDb2xsZWN0aW9uVGVzdChTdHJpbmcgcDEsIENvbGxlY3Rpb248SW50ZWdlcj4gYykgeworICAgICAgICBzdXBlcihwMSk7CisgICAgICAgIGNvbCA9IGM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcnVuVGVzdCgpIHsKKworICAgICAgICAvLyBjb250YWlucworICAgICAgICBhc3NlcnRUcnVlKCJVbm1vZGlmaWFibGVDb2xsZWN0aW9uVGVzdCAtIHNob3VsZCBjb250YWluIDAiLCBjb2wKKyAgICAgICAgICAgICAgICAuY29udGFpbnMobmV3IEludGVnZXIoMCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVW5tb2RpZmlhYmxlQ29sbGVjdGlvblRlc3QgLSBzaG91bGQgY29udGFpbiA1MCIsIGNvbAorICAgICAgICAgICAgICAgIC5jb250YWlucyhuZXcgSW50ZWdlcig1MCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVW5tb2RpZmlhYmxlQ29sbGVjdGlvblRlc3QgLSBzaG91bGQgbm90IGNvbnRhaW4gMTAwIiwgIWNvbAorICAgICAgICAgICAgICAgIC5jb250YWlucyhuZXcgSW50ZWdlcigxMDApKSk7CisKKyAgICAgICAgLy8gY29udGFpbnNBbGwKKyAgICAgICAgSGFzaFNldDxJbnRlZ2VyPiBocyA9IG5ldyBIYXNoU2V0PEludGVnZXI+KCk7CisgICAgICAgIGhzLmFkZChuZXcgSW50ZWdlcigwKSk7CisgICAgICAgIGhzLmFkZChuZXcgSW50ZWdlcigyNSkpOworICAgICAgICBocy5hZGQobmV3IEludGVnZXIoOTkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiVW5tb2RpZmlhYmxlQ29sbGVjdGlvblRlc3QgLSBzaG91bGQgY29udGFpbiBzZXQgb2YgMCwgMjUsIGFuZCA5OSIsCisgICAgICAgICAgICAgICAgY29sLmNvbnRhaW5zQWxsKGhzKSk7CisgICAgICAgIGhzLmFkZChuZXcgSW50ZWdlcigxMDApKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiVW5tb2RpZmlhYmxlQ29sbGVjdGlvblRlc3QgLSBzaG91bGQgbm90IGNvbnRhaW4gc2V0IG9mIDAsIDI1LCA5OSBhbmQgMTAwIiwKKyAgICAgICAgICAgICAgICAhY29sLmNvbnRhaW5zQWxsKGhzKSk7CisKKyAgICAgICAgLy8gaXNFbXB0eQorICAgICAgICBhc3NlcnRUcnVlKCJVbm1vZGlmaWFibGVDb2xsZWN0aW9uVGVzdCAtIHNob3VsZCBub3QgYmUgZW1wdHkiLCAhY29sCisgICAgICAgICAgICAgICAgLmlzRW1wdHkoKSk7CisKKyAgICAgICAgLy8gaXRlcmF0b3IKKyAgICAgICAgSXRlcmF0b3I8SW50ZWdlcj4gaXQgPSBjb2wuaXRlcmF0b3IoKTsKKyAgICAgICAgU29ydGVkU2V0PEludGVnZXI+IHNzID0gbmV3IFRyZWVTZXQ8SW50ZWdlcj4oKTsKKyAgICAgICAgd2hpbGUgKGl0Lmhhc05leHQoKSkgeworICAgICAgICAgICAgc3MuYWRkKGl0Lm5leHQoKSk7CisgICAgICAgIH0KKyAgICAgICAgaXQgPSBzcy5pdGVyYXRvcigpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgaXQuaGFzTmV4dCgpOyBjb3VudGVyKyspIHsKKyAgICAgICAgICAgIGludCBuZXh0VmFsdWUgPSBpdC5uZXh0KCkuaW50VmFsdWUoKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJVbm1vZGlmaWFibGVDb2xsZWN0aW9uVGVzdCAtIEl0ZXJhdG9yIHJldHVybmVkIHdyb25nIHZhbHVlLiAgV2FudGVkOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBjb3VudGVyICsgIiBnb3Q6ICIgKyBuZXh0VmFsdWUsCisgICAgICAgICAgICAgICAgICAgIG5leHRWYWx1ZSA9PSBjb3VudGVyKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHNpemUKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiVW5tb2RpZmlhYmxlQ29sbGVjdGlvblRlc3QgLSByZXR1cm5lZCB3cm9uZyBzaXplLiAgV2FudGVkIDEwMCwgZ290OiAiCisgICAgICAgICAgICAgICAgICAgICAgICArIGNvbC5zaXplKCksIGNvbC5zaXplKCkgPT0gMTAwKTsKKworICAgICAgICAvLyB0b0FycmF5CisgICAgICAgIE9iamVjdFtdIG9iakFycmF5OworICAgICAgICBvYmpBcnJheSA9IGNvbC50b0FycmF5KCk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBpdC5oYXNOZXh0KCk7IGNvdW50ZXIrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlVubW9kaWZpYWJsZUNvbGxlY3Rpb25UZXN0IC0gdG9BcnJheSByZXR1cm5lZCBpbmNvcnJlY3QgYXJyYXkiLAorICAgICAgICAgICAgICAgICAgICBvYmpBcnJheVtjb3VudGVyXSA9PSBpdC5uZXh0KCkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gdG9BcnJheSAoT2JqZWN0W10pCisgICAgICAgIG9iakFycmF5ID0gbmV3IE9iamVjdFsxMDBdOworICAgICAgICBjb2wudG9BcnJheShvYmpBcnJheSk7CisgICAgICAgIGZvciAoaW50IGNvdW50ZXIgPSAwOyBpdC5oYXNOZXh0KCk7IGNvdW50ZXIrKykgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAgICAgIlVubW9kaWZpYWJsZUNvbGxlY3Rpb25UZXN0IC0gdG9BcnJheShPYmplY3QpIGZpbGxlZCBhcnJheSBpbmNvcnJlY3RseSIsCisgICAgICAgICAgICAgICAgICAgIG9iakFycmF5W2NvdW50ZXJdID09IGl0Lm5leHQoKSk7CisgICAgICAgIH0KKworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9Vbm1vZGlmaWFibGVNYXBUZXN0LmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1VubW9kaWZpYWJsZU1hcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lN2ExNjIwCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9Vbm1vZGlmaWFibGVNYXBUZXN0LmphdmEKQEAgLTAsMCArMSwxNjEgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworcHVibGljIGNsYXNzIFN1cHBvcnRfVW5tb2RpZmlhYmxlTWFwVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKworICAgIE1hcDxTdHJpbmcsIEludGVnZXI+IG1hcDsKKworICAgIC8vIG11c3QgYmUgYSBtYXAgY29udGFpbmluZyB0aGUgc3RyaW5nIGtleXMgIjAiLSI5OSIgcGFpcmVkIHdpdGggdGhlIEludGVnZXIKKyAgICAvLyB2YWx1ZXMgSW50ZWdlcigwKSB0byBJbnRlZ2VyKDk5KQorCisgICAgcHVibGljIFN1cHBvcnRfVW5tb2RpZmlhYmxlTWFwVGVzdChTdHJpbmcgcDEpIHsKKyAgICAgICAgc3VwZXIocDEpOworICAgIH0KKworICAgIHB1YmxpYyBTdXBwb3J0X1VubW9kaWZpYWJsZU1hcFRlc3QoU3RyaW5nIHAxLCBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBtKSB7CisgICAgICAgIHN1cGVyKHAxKTsKKyAgICAgICAgbWFwID0gbTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkgeworICAgICAgICAvLyBjb250YWluc0tleQorICAgICAgICBhc3NlcnRUcnVlKCJVbm1vZGlmaWFibGVNYXBUZXN0IC0gU2hvdWxkIGNvbnRhaW4gdGhlIGtleSBcIjBcIiIsIG1hcAorICAgICAgICAgICAgICAgIC5jb250YWluc0tleSgiMCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVW5tb2RpZmlhYmxlTWFwVGVzdCAtIFNob3VsZCBjb250YWluIHRoZSBrZXkgXCI1MFwiIiwgbWFwCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zS2V5KCI1MCIpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVW5tb2RpZmlhYmxlTWFwVGVzdCAtIFNob3VsZCBub3QgY29udGFpbiB0aGUga2V5IFwiMTAwXCIiLAorICAgICAgICAgICAgICAgICFtYXAuY29udGFpbnNLZXkoIjEwMCIpKTsKKworICAgICAgICAvLyBjb250YWluc1ZhbHVlCisgICAgICAgIGFzc2VydFRydWUoIlVubW9kaWZpYWJsZU1hcFRlc3QgLSBTaG91bGQgY29udGFpbiB0aGUgdmFsdWUgMCIsIG1hcAorICAgICAgICAgICAgICAgIC5jb250YWluc1ZhbHVlKG5ldyBJbnRlZ2VyKDApKSk7CisgICAgICAgIGFzc2VydFRydWUoIlVubW9kaWZpYWJsZU1hcFRlc3QgLSBTaG91bGQgY29udGFpbiB0aGUgdmFsdWUgNTAiLCBtYXAKKyAgICAgICAgICAgICAgICAuY29udGFpbnNWYWx1ZShuZXcgSW50ZWdlcig1MCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiVW5tb2RpZmlhYmxlTWFwVGVzdCAtIFNob3VsZCBub3QgY29udGFpbiB2YWx1ZSAxMDAiLCAhbWFwCisgICAgICAgICAgICAgICAgLmNvbnRhaW5zVmFsdWUobmV3IEludGVnZXIoMTAwKSkpOworCisgICAgICAgIC8vIGVudHJ5U2V0CisgICAgICAgIFNldDw/PiBlbnRyeVNldCA9IG1hcC5lbnRyeVNldCgpOworICAgICAgICBJdGVyYXRvcjw/PiBlbnRyeVNldEl0ZXJhdG9yID0gZW50cnlTZXQuaXRlcmF0b3IoKTsKKyAgICAgICAgaW50IG15Q291bnRlciA9IDA7CisgICAgICAgIHdoaWxlIChlbnRyeVNldEl0ZXJhdG9yLmhhc05leHQoKSkgeworICAgICAgICAgICAgTWFwLkVudHJ5PD8sID8+IG1lID0gKE1hcC5FbnRyeTw/LCA/PikgZW50cnlTZXRJdGVyYXRvci5uZXh0KCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJVbm1vZGlmaWFibGVNYXBUZXN0IC0gSW5jb3JyZWN0IE1hcC5FbnRyeSByZXR1cm5lZCIsCisgICAgICAgICAgICAgICAgICAgIG1hcC5nZXQobWUuZ2V0S2V5KCkpLmVxdWFscyhtZS5nZXRWYWx1ZSgpKSk7CisgICAgICAgICAgICBteUNvdW50ZXIrKzsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIlVubW9kaWZpYWJsZU1hcFRlc3QgLSBJbmNvcnJlY3QgbnVtYmVyIG9mIG1hcCBlbnRyaWVzIHJldHVybmVkIiwKKyAgICAgICAgICAgICAgICAxMDAsIG15Q291bnRlcik7CisKKyAgICAgICAgLy8gZ2V0CisgICAgICAgIGFzc2VydFRydWUoIlVubW9kaWZpYWJsZU1hcFRlc3QgLSBnZXR0aW5nIFwiMFwiIGRpZG4ndCByZXR1cm4gMCIsCisgICAgICAgICAgICAgICAgbWFwLmdldCgiMCIpLmludFZhbHVlKCkgPT0gMCk7CisgICAgICAgIGFzc2VydFRydWUoIlVubW9kaWZpYWJsZU1hcFRlc3QgLSBnZXR0aW5nIFwiNTBcIiBkaWRuJ3QgcmV0dXJuIDAiLAorICAgICAgICAgICAgICAgIG1hcC5nZXQoIjAiKS5pbnRWYWx1ZSgpID09IDApOworICAgICAgICBhc3NlcnROdWxsKCJVbm1vZGlmaWFibGVNYXBUZXN0IC0gZ2V0dGluZyBcIjEwMFwiIGRpZG4ndCByZXR1cm4gbnVsbCIsCisgICAgICAgICAgICAgICAgbWFwLmdldCgiMTAwIikpOworCisgICAgICAgIC8vIGlzRW1wdHkKKyAgICAgICAgYXNzZXJ0VHJ1ZSgKKyAgICAgICAgICAgICAgICAiVW5tb2RpZmlhYmxlTWFwVGVzdCAtIHNob3VsZCBoYXZlIHJldHVybmVkIGZhbHNlIHRvIGlzRW1wdHkiLAorICAgICAgICAgICAgICAgICFtYXAuaXNFbXB0eSgpKTsKKworICAgICAgICAvLyBrZXlTZXQKKyAgICAgICAgU2V0PD8+IGtleVNldCA9IG1hcC5rZXlTZXQoKTsKKyAgICAgICAgdF9LZXlTZXQoa2V5U2V0KTsKKworICAgICAgICAvLyBzaXplCisgICAgICAgIGFzc2VydFRydWUoIlNpemUgc2hvdWxkIHJldHVybiAxMDAsIHJldHVybmVkOiAiICsgbWFwLnNpemUoKSwgbWFwCisgICAgICAgICAgICAgICAgLnNpemUoKSA9PSAxMDApOworCisgICAgICAgIC8vIHZhbHVlcworICAgICAgICBuZXcgU3VwcG9ydF9Vbm1vZGlmaWFibGVDb2xsZWN0aW9uVGVzdCgiVW5tb2QtLWZyb20gbWFwIHRlc3QiLCBtYXAKKyAgICAgICAgICAgICAgICAudmFsdWVzKCkpOworCisgICAgfQorCisgICAgdm9pZCB0X0tleVNldChTZXQ8Pz4ga2V5U2V0KSB7CisgICAgICAgIC8vIGtleVNldCBzaG91bGQgYmUgYSBzZXQgb2YgdGhlIHN0cmluZ3MgIjAiIHRvICI5OSIKKworICAgICAgICAvLyBjb250YWlucworICAgICAgICBhc3NlcnRUcnVlKCJVbm1vZGlmaWFibGVNYXBUZXN0IC0ga2V5U2V0VGVzdCAtIHNob3VsZCBjb250YWluIFwiMFwiIiwKKyAgICAgICAgICAgICAgICBrZXlTZXQuY29udGFpbnMoIjAiKSk7CisgICAgICAgIGFzc2VydFRydWUoIlVubW9kaWZpYWJsZU1hcFRlc3QgLSBrZXlTZXRUZXN0IC0gc2hvdWxkIGNvbnRhaW4gXCI1MFwiIiwKKyAgICAgICAgICAgICAgICBrZXlTZXQuY29udGFpbnMoIjUwIikpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJVbm1vZGlmaWFibGVNYXBUZXN0IC0ga2V5U2V0VGVzdCAtIHNob3VsZCBub3QgY29udGFpbiBcIjEwMFwiIiwKKyAgICAgICAgICAgICAgICAha2V5U2V0LmNvbnRhaW5zKCIxMDAiKSk7CisKKyAgICAgICAgLy8gY29udGFpbnNBbGwKKyAgICAgICAgSGFzaFNldDxTdHJpbmc+IGhzID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgICBocy5hZGQoIjAiKTsKKyAgICAgICAgaHMuYWRkKCIyNSIpOworICAgICAgICBocy5hZGQoIjk5Iik7CisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIlVubW9kaWZpYWJsZU1hcFRlc3QgLSBrZXlTZXRUZXN0IC0gc2hvdWxkIGNvbnRhaW4gc2V0IG9mIFwiMFwiLCBcIjI1XCIsIGFuZCBcIjk5XCIiLAorICAgICAgICAgICAgICAgIGtleVNldC5jb250YWluc0FsbChocykpOworICAgICAgICBocy5hZGQoIjEwMCIpOworICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICJVbm1vZGlmaWFibGVNYXBUZXN0IC0ga2V5U2V0VGVzdCAtIHNob3VsZCBub3QgY29udGFpbiBzZXQgb2YgXCIwXCIsIFwiMjVcIiwgXCI5OVwiIGFuZCBcIjEwMFwiIiwKKyAgICAgICAgICAgICAgICAha2V5U2V0LmNvbnRhaW5zQWxsKGhzKSk7CisKKyAgICAgICAgLy8gaXNFbXB0eQorICAgICAgICBhc3NlcnRUcnVlKCJVbm1vZGlmaWFibGVNYXBUZXN0IC0ga2V5U2V0VGVzdCAtIHNob3VsZCBub3QgYmUgZW1wdHkiLAorICAgICAgICAgICAgICAgICFrZXlTZXQuaXNFbXB0eSgpKTsKKworICAgICAgICAvLyBpdGVyYXRvcgorICAgICAgICBJdGVyYXRvcjw/PiBpdCA9IGtleVNldC5pdGVyYXRvcigpOworICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKAorICAgICAgICAgICAgICAgICAgICAiVW5tb2RpZmlhYmxlTWFwVGVzdCAtIGtleVNldFRlc3QgLSBJdGVyYXRvciByZXR1cm5lZCB3cm9uZyB2YWx1ZXMiLAorICAgICAgICAgICAgICAgICAgICBrZXlTZXQuY29udGFpbnMoaXQubmV4dCgpKSk7CisgICAgICAgIH0KKworICAgICAgICAvLyBzaXplCisgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgIlVubW9kaWZpYWJsZU1hcFRlc3QgLSBrZXlTZXRUZXN0IC0gcmV0dXJuZWQgd3Jvbmcgc2l6ZS4gIFdhbnRlZCAxMDAsIGdvdDogIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBrZXlTZXQuc2l6ZSgpLCBrZXlTZXQuc2l6ZSgpID09IDEwMCk7CisKKyAgICAgICAgLy8gdG9BcnJheQorICAgICAgICBPYmplY3RbXSBvYmpBcnJheTsKKyAgICAgICAgb2JqQXJyYXkgPSBrZXlTZXQudG9BcnJheSgpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgaXQuaGFzTmV4dCgpOyBjb3VudGVyKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJVbm1vZGlmaWFibGVNYXBUZXN0IC0ga2V5U2V0VGVzdCAtIHRvQXJyYXkgcmV0dXJuZWQgaW5jb3JyZWN0IGFycmF5IiwKKyAgICAgICAgICAgICAgICAgICAgb2JqQXJyYXlbY291bnRlcl0gPT0gaXQubmV4dCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHRvQXJyYXkgKE9iamVjdFtdKQorICAgICAgICBvYmpBcnJheSA9IG5ldyBPYmplY3RbMTAwXTsKKyAgICAgICAga2V5U2V0LnRvQXJyYXkob2JqQXJyYXkpOworICAgICAgICBmb3IgKGludCBjb3VudGVyID0gMDsgaXQuaGFzTmV4dCgpOyBjb3VudGVyKyspIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoCisgICAgICAgICAgICAgICAgICAgICJVbm1vZGlmaWFibGVNYXBUZXN0IC0ga2V5U2V0VGVzdCAtIHRvQXJyYXkoT2JqZWN0KSBmaWxsZWQgYXJyYXkgaW5jb3JyZWN0bHkiLAorICAgICAgICAgICAgICAgICAgICBvYmpBcnJheVtjb3VudGVyXSA9PSBpdC5uZXh0KCkpOworICAgICAgICB9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9TdXBwb3J0X1htbC5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9YbWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZTc3MDJlCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvU3VwcG9ydF9YbWwuamF2YQpAQCAtMCwwICsxLDU0IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDA5IFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy5zdXBwb3J0OworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7CitpbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CitpbXBvcnQgc3RhdGljIGp1bml0LmZyYW1ld29yay5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9YbWwgeworICAgIHB1YmxpYyBzdGF0aWMgRG9jdW1lbnQgZG9tT2YoU3RyaW5nIHhtbCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIERvY3VtZW50QnVpbGRlclRlc3QgYXNzdW1lcyB3ZSdyZSB1c2luZyBEb2N1bWVudEJ1aWxkZXIgdG8gZG8gdGhpcyBwYXJzaW5nIQorICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGRiZiA9IERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgZGJmLnNldENvYWxlc2NpbmcodHJ1ZSk7CisgICAgICAgIGRiZi5zZXRFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKHRydWUpOworCisgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIHN0cmVhbSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSh4bWwuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOworCisgICAgICAgIHJldHVybiBidWlsZGVyLnBhcnNlKHN0cmVhbSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZmlyc3RDaGlsZFRleHRPZihEb2N1bWVudCBkb2MpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBOb2RlTGlzdCBjaGlsZHJlbiA9IGRvYy5nZXRGaXJzdENoaWxkKCkuZ2V0Q2hpbGROb2RlcygpOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgY2hpbGRyZW4uZ2V0TGVuZ3RoKCkpOworICAgICAgICByZXR1cm4gY2hpbGRyZW4uaXRlbSgwKS5nZXROb2RlVmFsdWUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIEVsZW1lbnQgZmlyc3RFbGVtZW50T2YoRG9jdW1lbnQgZG9jKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIChFbGVtZW50KSBkb2MuZ2V0Rmlyc3RDaGlsZCgpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGF0dHJPZihFbGVtZW50IGUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICByZXR1cm4gZS5nZXRBdHRyaWJ1dGUoImF0dHIiKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvc3VwcG9ydC9UaHJvd2luZ1JlYWRlci5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvVGhyb3dpbmdSZWFkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYmVmZWIxCi0tLSAvZGV2L251bGwKKysrIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvVGhyb3dpbmdSZWFkZXIuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKgorICogIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQ7CisKK2ltcG9ydCBqYXZhLmlvLkZpbHRlclJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUmVhZGVyOworCisvKioKKyAqIEEgcmVhZGVyIHRoYXQgYWx3YXlzIHRocm93cyBhZnRlciBhIHByZWRldGVybWluZWQgbnVtYmVyIG9mIGJ5dGVzIGhhdmUgYmVlbgorICogcmVhZC4KKyAqLworcHVibGljIGNsYXNzIFRocm93aW5nUmVhZGVyIGV4dGVuZHMgRmlsdGVyUmVhZGVyIHsKKworICAgIHByaXZhdGUgaW50IHRvdGFsID0gMDsKKyAgICBwcml2YXRlIGludCB0aHJvd0F0OworCisgICAgcHVibGljIFRocm93aW5nUmVhZGVyKFJlYWRlciBpbiwgaW50IHRocm93QXQpIHsKKyAgICAgICAgc3VwZXIoaW4pOworICAgICAgICB0aGlzLnRocm93QXQgPSB0aHJvd0F0OworICAgIH0KKworICAgIEBPdmVycmlkZSBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBleHBsb2RlSWZOZWNlc3NhcnkoKTsKKyAgICAgICAgaW50IHJlc3VsdCA9IHN1cGVyLnJlYWQoKTsKKyAgICAgICAgdG90YWwrKzsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUgcHVibGljIGludCByZWFkKGNoYXJbXSBidWYsIGludCBvZmZzZXQsIGludCBjb3VudCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGV4cGxvZGVJZk5lY2Vzc2FyeSgpOworCisgICAgICAgIGlmICh0b3RhbCA8IHRocm93QXQpIHsKKyAgICAgICAgICAgIGNvdW50ID0gTWF0aC5taW4oY291bnQsICh0aHJvd0F0IC0gdG90YWwpKTsKKyAgICAgICAgfQorCisgICAgICAgIGludCByZXR1cm5lZCA9IHN1cGVyLnJlYWQoYnVmLCBvZmZzZXQsIGNvdW50KTsKKyAgICAgICAgdG90YWwgKz0gcmV0dXJuZWQ7CisgICAgICAgIHJldHVybiByZXR1cm5lZDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZXhwbG9kZUlmTmVjZXNzYXJ5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRvdGFsID09IHRocm93QXQpIHsKKyAgICAgICAgICAgIHRocm93QXQgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3N1cHBvcnQvcmVzb3VyY2UvU3VwcG9ydF9SZXNvdXJjZXMuamF2YSBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L3Jlc291cmNlL1N1cHBvcnRfUmVzb3VyY2VzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODBhNTNmYgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy9zdXBwb3J0L3Jlc291cmNlL1N1cHBvcnRfUmVzb3VyY2VzLmphdmEKQEAgLTAsMCArMSwxODUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIHRlc3RzLnN1cHBvcnQucmVzb3VyY2U7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9Db25maWd1cmF0aW9uOworCitwdWJsaWMgY2xhc3MgU3VwcG9ydF9SZXNvdXJjZXMgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTT1VSQ0VfUEFDS0FHRSA9ICIvdGVzdHMvcmVzb3VyY2VzLyI7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNPVVJDRV9QQUNLQUdFX05BTUUgPSAidGVzdHMucmVzb3VyY2VzIjsKKworICAgIHB1YmxpYyBzdGF0aWMgSW5wdXRTdHJlYW0gZ2V0U3RyZWFtKFN0cmluZyBuYW1lKSB7CisgICAgICAgIFN0cmluZyBwYXRoID0gUkVTT1VSQ0VfUEFDS0FHRSArIG5hbWU7CisgICAgICAgIElucHV0U3RyZWFtIHJlc3VsdCA9IFN1cHBvcnRfUmVzb3VyY2VzLmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0ocGF0aCk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm8gc3VjaCByZXNvdXJjZTogIiArIHBhdGgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0VVJMKFN0cmluZyBuYW1lKSB7CisgICAgICAgIFN0cmluZyBmb2xkZXIgPSBudWxsOworICAgICAgICBTdHJpbmcgZmlsZU5hbWUgPSBuYW1lOworICAgICAgICBGaWxlIHJlc291cmNlcyA9IGNyZWF0ZVRlbXBGb2xkZXIoKTsKKyAgICAgICAgaW50IGluZGV4ID0gbmFtZS5sYXN0SW5kZXhPZigiLyIpOworICAgICAgICBpZiAoaW5kZXggIT0gLTEpIHsKKyAgICAgICAgICAgIGZvbGRlciA9IG5hbWUuc3Vic3RyaW5nKDAsIGluZGV4KTsKKyAgICAgICAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cmluZyhpbmRleCArIDEpOworICAgICAgICB9CisgICAgICAgIGNvcHlGaWxlKHJlc291cmNlcywgZm9sZGVyLCBuYW1lKTsKKyAgICAgICAgVVJMIHVybCA9IG51bGw7CisgICAgICAgIFN0cmluZyByZXNQYXRoID0gcmVzb3VyY2VzLnRvU3RyaW5nKCk7CisgICAgICAgIGlmIChyZXNQYXRoLmNoYXJBdCgwKSA9PSAnLycgfHwgcmVzUGF0aC5jaGFyQXQoMCkgPT0gJ1xcJykgeworICAgICAgICAgICAgcmVzUGF0aCA9IHJlc1BhdGguc3Vic3RyaW5nKDEpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB1cmwgPSBuZXcgVVJMKCJmaWxlOi8iICsgcmVzUGF0aCArICIvIiArIGZpbGVOYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgY2F0Y2ggYmxvY2sKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHVybC50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgRmlsZSBjcmVhdGVUZW1wRm9sZGVyKCkgeworCisgICAgICAgIEZpbGUgZm9sZGVyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZvbGRlciA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoImh5dHNfcmVzb3VyY2VzIiwgIiIsIG51bGwpOworICAgICAgICAgICAgZm9sZGVyLmRlbGV0ZSgpOworICAgICAgICAgICAgZm9sZGVyLm1rZGlycygpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIGNhdGNoIGJsb2NrCisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisgICAgICAgIGZvbGRlci5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgcmV0dXJuIGZvbGRlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIEZpbGUgY29weUZpbGUoRmlsZSByb290LCBTdHJpbmcgZm9sZGVyLCBTdHJpbmcgZmlsZSkgeworICAgICAgICBGaWxlIGY7CisgICAgICAgIGlmIChmb2xkZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgZiA9IG5ldyBGaWxlKHJvb3QudG9TdHJpbmcoKSArICIvIiArIGZvbGRlcik7CisgICAgICAgICAgICBpZiAoIWYuZXhpc3RzKCkpIHsKKyAgICAgICAgICAgICAgICBmLm1rZGlycygpOworICAgICAgICAgICAgICAgIGYuZGVsZXRlT25FeGl0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmID0gcm9vdDsKKyAgICAgICAgfQorCisgICAgICAgIEZpbGUgZGVzdCA9IG5ldyBGaWxlKGYudG9TdHJpbmcoKSArICIvIiArIGZpbGUpOworCisgICAgICAgIElucHV0U3RyZWFtIGluID0gU3VwcG9ydF9SZXNvdXJjZXMuZ2V0U3RyZWFtKGZvbGRlciA9PSBudWxsID8gZmlsZQorICAgICAgICAgICAgICAgIDogZm9sZGVyICsgIi8iICsgZmlsZSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjb3B5TG9jYWxGaWxldG8oZGVzdCwgaW4pOworICAgICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBjYXRjaCBibG9jaworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBjYXRjaCBibG9jaworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBkZXN0OworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgRmlsZSBjcmVhdGVUZW1wRmlsZShTdHJpbmcgc3VmZml4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gRmlsZS5jcmVhdGVUZW1wRmlsZSgiaHl0c18iLCBzdWZmaXgsIG51bGwpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjb3B5TG9jYWxGaWxldG8oRmlsZSBkZXN0LCBJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFkZXN0LmV4aXN0cygpKSB7CisgICAgICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGRlc3QpOworICAgICAgICAgICAgY29weShpbiwgb3V0KTsKKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgZGVzdC5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgfQorICAgICAgICBpbi5jbG9zZSgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGludCBjb3B5KElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpbnQgdG90YWwgPSAwOworICAgICAgICBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbODE5Ml07CisgICAgICAgIGludCBjOworICAgICAgICB3aGlsZSAoKGMgPSBpbi5yZWFkKGJ1ZmZlcikpICE9IC0xKSB7CisgICAgICAgICAgICB0b3RhbCArPSBjOworICAgICAgICAgICAgb3V0LndyaXRlKGJ1ZmZlciwgMCwgYyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRvdGFsOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgRmlsZSBnZXRFeHRlcm5hbExvY2FsRmlsZShTdHJpbmcgdXJsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBGaWxlIHJlc291cmNlcyA9IGNyZWF0ZVRlbXBGb2xkZXIoKTsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBuZXcgVVJMKHVybCkub3BlblN0cmVhbSgpOworICAgICAgICBGaWxlIHRlbXAgPSBuZXcgRmlsZShyZXNvdXJjZXMudG9TdHJpbmcoKSArICIvbG9jYWwudG1wIik7CisgICAgICAgIGNvcHlMb2NhbEZpbGV0byh0ZW1wLCBpbik7CisgICAgICAgIHJldHVybiB0ZW1wOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFJlc291cmNlVVJMKFN0cmluZyByZXNvdXJjZSkgeworICAgICAgICByZXR1cm4gImh0dHA6Ly8iICsgU3VwcG9ydF9Db25maWd1cmF0aW9uLlRlc3RSZXNvdXJjZXMgKyByZXNvdXJjZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVdGlsIG1ldGhvZCB0byBsb2FkIHJlc291cmNlIGZpbGVzCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSAtIG5hbWUgb2YgcmVzb3VyY2UgZmlsZQorICAgICAqIEByZXR1cm4gLSByZXNvdXJjZSBpbnB1dCBzdHJlYW0KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIElucHV0U3RyZWFtIGdldFJlc291cmNlU3RyZWFtKFN0cmluZyBuYW1lKSB7CisgICAgICAgIElucHV0U3RyZWFtIGlzID0gU3VwcG9ydF9SZXNvdXJjZXMuY2xhc3MuZ2V0UmVzb3VyY2VBc1N0cmVhbShuYW1lKTsKKworICAgICAgICBpZiAoaXMgPT0gbnVsbCkgeworICAgICAgICAgICAgbmFtZSA9IFJFU09VUkNFX1BBQ0tBR0UgKyBuYW1lOworICAgICAgICAgICAgaXMgPSBTdXBwb3J0X1Jlc291cmNlcy5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKG5hbWUpOworICAgICAgICAgICAgaWYgKGlzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiRmFpbGVkIHRvIGxvYWQgcmVzb3VyY2U6ICIgKyBuYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBpczsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIEZpbGUgcmVzb3VyY2VUb1RlbXBGaWxlKFN0cmluZyBwYXRoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBGaWxlIGYgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJvdXQiLCAiLnhtbCIpOworICAgICAgICBmLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGYpOworCisgICAgICAgIElucHV0U3RyZWFtIHhtbCA9IFN1cHBvcnRfUmVzb3VyY2VzLmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0ocGF0aCk7CisgICAgICAgIGludCBiOworICAgICAgICB3aGlsZSAoKGIgPSB4bWwucmVhZCgpKSAhPSAtMSkgeworICAgICAgICAgICAgb3V0LndyaXRlKGIpOworICAgICAgICB9CisgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgeG1sLmNsb3NlKCk7CisgICAgICAgIHJldHVybiBmOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy91dGlsL0NhbGxWZXJpZmljYXRpb25TdGFjay5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3V0aWwvQ2FsbFZlcmlmaWNhdGlvblN0YWNrLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmMxODgxYgotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy91dGlsL0NhbGxWZXJpZmljYXRpb25TdGFjay5qYXZhCkBAIC0wLDAgKzEsMzUzIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy51dGlsOworCitpbXBvcnQgamF2YS51dGlsLlN0YWNrOworCisvKioKKyAqIEEgc3RhY2sgdG8gc3RvcmUgdGhlIHBhcmFtZXRlcnMgb2YgYSBjYWxsLCBhcyB3ZWxsIGFzIHRoZSBjYWxsIHN0YWNrLgorICoKKyAqLworcHVibGljIGNsYXNzIENhbGxWZXJpZmljYXRpb25TdGFjayBleHRlbmRzIFN0YWNrPE9iamVjdD4geworCisgICAgLyoKKyAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAqIENsYXNzIHZhcmlhYmxlcworICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICovCisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKworICAgIC8vIHRoZSBzaW5nbGV0b24KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDYWxsVmVyaWZpY2F0aW9uU3RhY2sgX2luc3RhbmNlID0gbmV3IENhbGxWZXJpZmljYXRpb25TdGFjaygpOworCisgICAgLyoKKyAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAqIEluc3RhbmNlIHZhcmlhYmxlcworICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICovCisKKyAgICAvLyB0aGUgY2FsbCBzdGFjaywgc3RvcmUgU3RhY2tUcmFjZUVsZW1lbnQKKyAgICBwcml2YXRlIGZpbmFsIFN0YWNrPFN0YWNrVHJhY2VFbGVtZW50PiBjYWxsU3RhY2sgPSBuZXcgU3RhY2s8U3RhY2tUcmFjZUVsZW1lbnQ+KCk7CisKKyAgICAvKgorICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAgKiBDb25zdHJ1Y3RvcnMKKyAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICovCisKKyAgICAvKioKKyAgICAgKiBDYW4ndCBiZSBpbnN0YW50aWF0ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBDYWxsVmVyaWZpY2F0aW9uU3RhY2soKSB7CisgICAgICAgIC8vIGVtcHR5CisgICAgfQorCisgICAgLyoKKyAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICogTWV0aG9kcworICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIHNpbmdsZXRvbiBpbnN0YW5jZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNpbmdsZXRvbiBpbnN0YW5jZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgQ2FsbFZlcmlmaWNhdGlvblN0YWNrIGdldEluc3RhbmNlKCkgeworICAgICAgICByZXR1cm4gX2luc3RhbmNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFB1c2hlcyB0aGUgY2FsbCBzdGFjay4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcHVzaENhbGxTdGFjaygpIHsKKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnRbXSBlbGVzID0gKG5ldyBUaHJvd2FibGUoKSkuZ2V0U3RhY2tUcmFjZSgpOworICAgICAgICBpbnQgaTsKKyAgICAgICAgZm9yIChpID0gMTsgaSA8IGVsZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIGlmICghZWxlc1tpXS5nZXRDbGFzc05hbWUoKS5lcXVhbHModGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSkpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0aGlzLmNhbGxTdGFjay5wdXNoKGVsZXNbaV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlICJjdXJyZW50IiBjYWxsaW5nIGNsYXNzIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSAiY3VycmVudCIgY2FsbGluZyBjbGFzcyBuYW1lCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDdXJyZW50U291cmNlQ2xhc3MoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmNhbGxTdGFjay5wZWVrKCkuZ2V0Q2xhc3NOYW1lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgImN1cnJlbnQiIGNhbGxpbmcgbWV0aG9kIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSAiY3VycmVudCIgY2FsbGluZyBtZXRob2QgbmFtZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q3VycmVudFNvdXJjZU1ldGhvZCgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuY2FsbFN0YWNrLnBlZWsoKS5nZXRNZXRob2ROYW1lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xlYXIgdGhlIHBhcmFtZXRlciBzdGFjayBhbmQgdGhlIGNhbGwgc3RhY2suCisgICAgICoKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICAgICAgdGhpcy5jYWxsU3RhY2suY2xlYXIoKTsKKyAgICAgICAgc3VwZXIuY2xlYXIoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IHB1c2goT2JqZWN0IG8pIHsKKyAgICAgICAgcHVzaENhbGxTdGFjaygpOworICAgICAgICByZXR1cm4gc3VwZXIucHVzaChvKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQdXNoZXMgYSBib29sZWFuIG9udG8gdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIHB1c2gKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXNoKGJvb2xlYW4gdmFsKSB7CisgICAgICAgIHRoaXMucHVzaChuZXcgQmFzZVR5cGVXcmFwcGVyKHZhbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFB1c2hlcyBhIGNoYXIgb250byB0aGUgdG9wIG9mIHRoaXMgc3RhY2suCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gcHVzaAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1c2goY2hhciB2YWwpIHsKKyAgICAgICAgdGhpcy5wdXNoKG5ldyBCYXNlVHlwZVdyYXBwZXIodmFsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHVzaGVzIGEgZG91YmxlIG9udG8gdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIHB1c2gKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXNoKGRvdWJsZSB2YWwpIHsKKyAgICAgICAgdGhpcy5wdXNoKG5ldyBCYXNlVHlwZVdyYXBwZXIodmFsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHVzaGVzIGEgZmxvYXQgb250byB0aGUgdG9wIG9mIHRoaXMgc3RhY2suCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gcHVzaAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1c2goZmxvYXQgdmFsKSB7CisgICAgICAgIHRoaXMucHVzaChuZXcgQmFzZVR5cGVXcmFwcGVyKHZhbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFB1c2hlcyBhbiBpbnQgb250byB0aGUgdG9wIG9mIHRoaXMgc3RhY2suCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsCisgICAgICogICAgICAgICAgICB0aGUgdmFsdWUgdG8gcHVzaAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1c2goaW50IHZhbCkgeworICAgICAgICB0aGlzLnB1c2gobmV3IEJhc2VUeXBlV3JhcHBlcih2YWwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQdXNoZXMgYSBsb25nIG9udG8gdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIHB1c2gKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXNoKGxvbmcgdmFsKSB7CisgICAgICAgIHRoaXMucHVzaChuZXcgQmFzZVR5cGVXcmFwcGVyKHZhbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFB1c2hlcyBhIHNob3J0IG9udG8gdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgorICAgICAqCisgICAgICogQHBhcmFtIHZhbAorICAgICAqICAgICAgICAgICAgdGhlIHZhbHVlIHRvIHB1c2gKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXNoKHNob3J0IHZhbCkgeworICAgICAgICB0aGlzLnB1c2gobmV3IEJhc2VUeXBlV3JhcHBlcih2YWwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQb3AgYW4gb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgb2JqZWN0CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBwb3AoKSB7CisgICAgICAgIHRoaXMuY2FsbFN0YWNrLnBvcCgpOworICAgICAgICByZXR1cm4gc3VwZXIucG9wKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUG9wIGEgYm9vbGVhbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcG9wQm9vbGVhbigpIHsKKyAgICAgICAgQmFzZVR5cGVXcmFwcGVyIHdyYXBwZXIgPSAoQmFzZVR5cGVXcmFwcGVyKSB0aGlzLnBvcCgpOworICAgICAgICBCb29sZWFuIHZhbHVlID0gKEJvb2xlYW4pIHdyYXBwZXIuZ2V0VmFsdWUoKTsKKyAgICAgICAgcmV0dXJuIHZhbHVlLmJvb2xlYW5WYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBvcCBhIGNoYXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBjaGFyIHBvcENoYXIoKSB7CisgICAgICAgIEJhc2VUeXBlV3JhcHBlciB3cmFwcGVyID0gKEJhc2VUeXBlV3JhcHBlcikgdGhpcy5wb3AoKTsKKyAgICAgICAgQ2hhcmFjdGVyIHZhbHVlID0gKENoYXJhY3Rlcikgd3JhcHBlci5nZXRWYWx1ZSgpOworICAgICAgICByZXR1cm4gdmFsdWUuY2hhclZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUG9wIGEgZG91YmxlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZG91YmxlIHBvcERvdWJsZSgpIHsKKyAgICAgICAgQmFzZVR5cGVXcmFwcGVyIHdyYXBwZXIgPSAoQmFzZVR5cGVXcmFwcGVyKSB0aGlzLnBvcCgpOworICAgICAgICBEb3VibGUgdmFsdWUgPSAoRG91YmxlKSB3cmFwcGVyLmdldFZhbHVlKCk7CisgICAgICAgIHJldHVybiB2YWx1ZS5kb3VibGVWYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBvcCBhIGZsb2F0LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgZmxvYXQgcG9wRmxvYXQoKSB7CisgICAgICAgIEJhc2VUeXBlV3JhcHBlciB3cmFwcGVyID0gKEJhc2VUeXBlV3JhcHBlcikgdGhpcy5wb3AoKTsKKyAgICAgICAgRmxvYXQgdmFsdWUgPSAoRmxvYXQpIHdyYXBwZXIuZ2V0VmFsdWUoKTsKKyAgICAgICAgcmV0dXJuIHZhbHVlLmZsb2F0VmFsdWUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQb3AgYSBpbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgcG9wSW50KCkgeworICAgICAgICBCYXNlVHlwZVdyYXBwZXIgd3JhcHBlciA9IChCYXNlVHlwZVdyYXBwZXIpIHRoaXMucG9wKCk7CisgICAgICAgIEludGVnZXIgdmFsdWUgPSAoSW50ZWdlcikgd3JhcHBlci5nZXRWYWx1ZSgpOworICAgICAgICByZXR1cm4gdmFsdWUuaW50VmFsdWUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQb3AgYSBsb25nLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBwb3BMb25nKCkgeworICAgICAgICBCYXNlVHlwZVdyYXBwZXIgd3JhcHBlciA9IChCYXNlVHlwZVdyYXBwZXIpIHRoaXMucG9wKCk7CisgICAgICAgIExvbmcgdmFsdWUgPSAoTG9uZykgd3JhcHBlci5nZXRWYWx1ZSgpOworICAgICAgICByZXR1cm4gdmFsdWUubG9uZ1ZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUG9wIGEgc2hvcnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBzaG9ydCBwb3BTaG9ydCgpIHsKKyAgICAgICAgQmFzZVR5cGVXcmFwcGVyIHdyYXBwZXIgPSAoQmFzZVR5cGVXcmFwcGVyKSB0aGlzLnBvcCgpOworICAgICAgICBTaG9ydCB2YWx1ZSA9IChTaG9ydCkgd3JhcHBlci5nZXRWYWx1ZSgpOworICAgICAgICByZXR1cm4gdmFsdWUuc2hvcnRWYWx1ZSgpOworICAgIH0KKworICAgIC8qCisgICAgICogV3JhcHBlciBvZiBiYXNlIHR5cGVzLgorICAgICAqLworICAgIGNsYXNzIEJhc2VUeXBlV3JhcHBlciB7CisKKyAgICAgICAgLy8gdGhlIGludGVybmFsIHZhbHVlCisgICAgICAgIHByaXZhdGUgT2JqZWN0IHZhbHVlOworCisgICAgICAgIC8qCisgICAgICAgICAqIENvbnN0cnVjdHMgYSB3cmFwcGVyIG9iamVjdCBmb3IgdGhlIGJhc2UgdHlwZSA8Y29kZT4gYm9vbGVhbiA8L2NvZGU+IC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBCYXNlVHlwZVdyYXBwZXIoYm9vbGVhbiB2YWwpIHsKKyAgICAgICAgICAgIHRoaXMudmFsdWUgPSBuZXcgQm9vbGVhbih2YWwpOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogQ29uc3RydWN0cyBhIHdyYXBwZXIgb2JqZWN0IGZvciB0aGUgYmFzZSB0eXBlIDxjb2RlPiBjIDwvY29kZT4gLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEJhc2VUeXBlV3JhcHBlcihieXRlIHZhbCkgeworICAgICAgICAgICAgdGhpcy52YWx1ZSA9IG5ldyBCeXRlKHZhbCk7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgd3JhcHBlciBvYmplY3QgZm9yIHRoZSBiYXNlIHR5cGUgPGNvZGU+IGNoYXIgPC9jb2RlPiAuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQmFzZVR5cGVXcmFwcGVyKGNoYXIgdmFsKSB7CisgICAgICAgICAgICB0aGlzLnZhbHVlID0gbmV3IENoYXJhY3Rlcih2YWwpOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogQ29uc3RydWN0cyBhIHdyYXBwZXIgb2JqZWN0IGZvciB0aGUgYmFzZSB0eXBlIDxjb2RlPiBkb3VibGUgPC9jb2RlPiAuCisgICAgICAgICAqLworICAgICAgICBwdWJsaWMgQmFzZVR5cGVXcmFwcGVyKGRvdWJsZSB2YWwpIHsKKyAgICAgICAgICAgIHRoaXMudmFsdWUgPSBuZXcgRG91YmxlKHZhbCk7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgd3JhcHBlciBvYmplY3QgZm9yIHRoZSBiYXNlIHR5cGUgPGNvZGU+IGZsb2F0IDwvY29kZT4gLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEJhc2VUeXBlV3JhcHBlcihmbG9hdCB2YWwpIHsKKyAgICAgICAgICAgIHRoaXMudmFsdWUgPSBuZXcgRmxvYXQodmFsKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIENvbnN0cnVjdHMgYSB3cmFwcGVyIG9iamVjdCBmb3IgdGhlIGJhc2UgdHlwZSA8Y29kZT4gaW50IDwvY29kZT4gLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIEJhc2VUeXBlV3JhcHBlcihpbnQgdmFsKSB7CisgICAgICAgICAgICB0aGlzLnZhbHVlID0gbmV3IEludGVnZXIodmFsKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qCisgICAgICAgICAqIENvbnN0cnVjdHMgYSB3cmFwcGVyIG9iamVjdCBmb3IgdGhlIGJhc2UgdHlwZSA8Y29kZT4gbG9uZyA8L2NvZGU+IC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBCYXNlVHlwZVdyYXBwZXIobG9uZyB2YWwpIHsKKyAgICAgICAgICAgIHRoaXMudmFsdWUgPSBuZXcgTG9uZyh2YWwpOworICAgICAgICB9CisKKyAgICAgICAgLyoKKyAgICAgICAgICogQ29uc3RydWN0cyBhIHdyYXBwZXIgb2JqZWN0IGZvciB0aGUgYmFzZSB0eXBlIDxjb2RlPiBzaG9ydCA8L2NvZGU+IC4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBCYXNlVHlwZVdyYXBwZXIoc2hvcnQgdmFsKSB7CisgICAgICAgICAgICB0aGlzLnZhbHVlID0gbmV3IFNob3J0KHZhbCk7CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBHZXRzIHRoZSBpbnRlcm5hbCB2YWx1ZS4KKyAgICAgICAgICovCisgICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0VmFsdWUoKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy91dGlsL0NsYXNzTG9hZGVyQnVpbGRlci5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3V0aWwvQ2xhc3NMb2FkZXJCdWlsZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGZkNDE1OQotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy91dGlsL0NsYXNzTG9hZGVyQnVpbGRlci5qYXZhCkBAIC0wLDAgKzEsMTUwIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSB0ZXN0cy51dGlsOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5uZXQuVVJMQ2xhc3NMb2FkZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCisvKioKKyAqIEJ1aWxkcyBhIGNvbmZpZ3VyZWQgY2xhc3MgbG9hZGVyLiBUaGUgY29uc3RydWN0ZWQgY2xhc3MgbG9hZGVyIGNhbiBsb2FkIGEKKyAqIHByaXZhdGUgY29weSBvZiBhIGNsYXNzIGluIGFkZGl0aW9uIHRvIHRoZSBjb3B5IGluIHRoZSBhcHBsaWNhdGlvbiBjbGFzcworICogbG9hZGVyLiBJdCBjYW4gYWxzbyByZWZ1c2UgdG8gbG9hZCBhIGNsYXNzIGFsdG9nZXRoZXIsIGV2ZW4gaWYgdGhhdCBjbGFzcworICogZXhpc3RzIG9uIHRoZSBjbGFzc3BhdGguCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBDbGFzc0xvYWRlckJ1aWxkZXIgeworICAgIHByaXZhdGUgQ2xhc3NMb2FkZXIgcGFyZW50ID0gQ2xhc3NMb2FkZXJCdWlsZGVyLmNsYXNzLmdldENsYXNzTG9hZGVyKCk7CisgICAgcHJpdmF0ZSBmaW5hbCBTZXQ8U3RyaW5nPiBwcmVmaXhlc1RvTm90SW5oZXJpdCA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKyAgICBwcml2YXRlIGZpbmFsIFNldDxTdHJpbmc+IHByZWZpeGVzVG9Mb2FkID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworCisgICAgcHVibGljIENsYXNzTG9hZGVyQnVpbGRlciBwYXJlbnQoQ2xhc3NMb2FkZXIgcGFyZW50KSB7CisgICAgICAgIHRoaXMucGFyZW50ID0gcGFyZW50OworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gY2xhc3NOYW1lUHJlZml4IHRoZSBwcmVmaXggb2YgY2xhc3NlcyB0aGF0IGNhbiBiZSBsb2FkZWQgYnkgYm90aAorICAgICAqICAgICB0aGUgY29uc3RydWN0ZWQgY2xhc3MgbG9hZGVyIGFuZCB0aGUgYXBwbGljYXRpb24gY2xhc3MgbG9hZGVyLgorICAgICAqLworICAgIHB1YmxpYyBDbGFzc0xvYWRlckJ1aWxkZXIgd2l0aFByaXZhdGVDb3B5KFN0cmluZyBjbGFzc05hbWVQcmVmaXgpIHsKKyAgICAgICAgcHJlZml4ZXNUb0xvYWQuYWRkKGNsYXNzTmFtZVByZWZpeCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBjbGFzc05hbWVQcmVmaXggdGhlIHByZWZpeCBvZiBjbGFzc2VzIHRoYXQgd2lsbCBub3QgYmUgbG9hZGVkIGJ5CisgICAgICogICAgIHRoaXMgY2xhc3MgbG9hZGVyLiBBdHRlbXB0cyB0byBsb2FkIHN1Y2ggY2xhc3NlcyB3aWxsIGZhaWwgYXQgcnVudGltZQorICAgICAqICAgICB3aXRoIGEgTm9DbGFzc0RlZkZvdW5kRXJyb3IuCisgICAgICovCisgICAgcHVibGljIENsYXNzTG9hZGVyQnVpbGRlciB3aXRob3V0KFN0cmluZyBjbGFzc05hbWVQcmVmaXgpIHsKKyAgICAgICAgcHJlZml4ZXNUb05vdEluaGVyaXQuYWRkKGNsYXNzTmFtZVByZWZpeCk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBDbGFzc0xvYWRlciBidWlsZCgpIHsKKyAgICAgICAgLy8gbWFrZSBhIGRlZmVuc2l2ZSBjb3B5IGluIGNhc2UgdGhpcyBidWlsZGVyIGlzIHJldXNlZCEKKyAgICAgICAgZmluYWwgU2V0PFN0cmluZz4gcHJlZml4ZXNUb05vdEluaGVyaXQgPSBuZXcgSGFzaFNldDxTdHJpbmc+KHRoaXMucHJlZml4ZXNUb05vdEluaGVyaXQpOworICAgICAgICBmaW5hbCBTZXQ8U3RyaW5nPiBwcmVmaXhlc1RvTG9hZCA9IG5ldyBIYXNoU2V0PFN0cmluZz4odGhpcy5wcmVmaXhlc1RvTG9hZCk7CisKKyAgICAgICAgLyoKKyAgICAgICAgICogVG8gbG9hZCB0d28gY29waWVzIG9mIGEgZ2l2ZW4gY2xhc3MgaW4gdGhlIFZNLCB3ZSBlbmQgdXAgY3JlYXRpbmcgdHdvCisgICAgICAgICAqIG5ldyBjbGFzcyBsb2FkZXJzOiBhIGJyaWRnZSBjbGFzcyBsb2FkZXIgYW5kIGEgbGVhZiBjbGFzcyBsb2FkZXIuCisgICAgICAgICAqCisgICAgICAgICAqIFRoZSBicmlkZ2UgY2xhc3MgbG9hZGVyIGlzIGEgY2hpbGQgb2YgdGhlIGFwcGxpY2F0aW9uIGNsYXNzIGxvYWRlci4KKyAgICAgICAgICogSXQgbmV2ZXIgbG9hZHMgYW55IGNsYXNzZXMuIEFsbCBpdCBkb2VzIGlzIGRlY2lkZSB3aGVuIHRvIGRlbGVnYXRlIHRvCisgICAgICAgICAqIHRoZSBhcHBsaWNhdGlvbiBjbGFzcyBsb2FkZXIgKHdoaWNoIGhhcyBhIGNvcHkgb2YgZXZlcnl0aGluZykgYW5kCisgICAgICAgICAqIHdoZW4gdG8gZmFpbC4KKyAgICAgICAgICoKKyAgICAgICAgICogVGhlIGxlYWYgY2xhc3MgbG9hZGVyIGlzIGEgY2hpbGQgb2YgdGhlIGJyaWRnZSBjbGFzcyBsb2FkZXIuIEl0CisgICAgICAgICAqIHVzZXMgdGhlIHNhbWUgY2xhc3NwYXRoIGFzIHRoZSBhcHBsaWNhdGlvbiBjbGFzcyBsb2FkZXIuIEl0IGxvYWRzCisgICAgICAgICAqIGFueXRoaW5nIHRoYXQgaXRzIHBhcmVudCBmYWlsZWQgb24uCisgICAgICAgICAqLworCisgICAgICAgIENsYXNzTG9hZGVyIGJyaWRnZSA9IG5ldyBDbGFzc0xvYWRlcihwYXJlbnQpIHsKKyAgICAgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgQ2xhc3M8Pz4gbG9hZENsYXNzKFN0cmluZyBjbGFzc05hbWUsIGJvb2xlYW4gcmVzb2x2ZSkKKyAgICAgICAgICAgICAgICAgICAgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIHByZWZpeCA6IHByZWZpeGVzVG9Mb2FkKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChjbGFzc05hbWUuc3RhcnRzV2l0aChwcmVmaXgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvKiBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNhdXNlcyB0aGUgY2hpbGQgbG9hZGVyIHRvIGxvYWQgdGhlIGNsYXNzLiAqLworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzTm90Rm91bmRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIHByZWZpeCA6IHByZWZpeGVzVG9Ob3RJbmhlcml0KSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChjbGFzc05hbWUuc3RhcnRzV2l0aChwcmVmaXgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvKiBOb0NsYXNzRGVmRm91bmRFcnJvciBwcmV2ZW50cyB0aGUgY2xhc3MgZnJvbSBiZWluZyBsb2FkZWQgYXQgYWxsLiAqLworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vQ2xhc3NEZWZGb3VuZEVycm9yKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIubG9hZENsYXNzKGNsYXNzTmFtZSwgcmVzb2x2ZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGZpcnN0IHRyeSB0byBjcmVhdGUgYSBQYXRoQ2xhc3NMb2FkZXIgZm9yIGEgZGFsdmlrIFZNLi4uCisgICAgICAgICAgICBTdHJpbmcgY2xhc3NQYXRoID0gZ2V0QXBwbGljYXRpb25DbGFzc1BhdGgoKTsKKyAgICAgICAgICAgIHJldHVybiAoQ2xhc3NMb2FkZXIpIENsYXNzLmZvck5hbWUoImRhbHZpay5zeXN0ZW0uUGF0aENsYXNzTG9hZGVyIikKKyAgICAgICAgICAgICAgICAgICAgLmdldENvbnN0cnVjdG9yKFN0cmluZy5jbGFzcywgQ2xhc3NMb2FkZXIuY2xhc3MpCisgICAgICAgICAgICAgICAgICAgIC5uZXdJbnN0YW5jZShjbGFzc1BhdGgsIGJyaWRnZSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgIH0KKworICAgICAgICAvLyBmYWxsIGJhY2sgdG8gYSBVUkxDbGFzc0xvYWRlciBvbiBhIEpWTQorICAgICAgICBMaXN0PFVSTD4gY2xhc3NwYXRoID0gbmV3IEFycmF5TGlzdDxVUkw+KCk7CisgICAgICAgIGNsYXNzcGF0aC5hZGRBbGwoY2xhc3NwYXRoVG9VcmxzKCJqYXZhLmNsYXNzLnBhdGgiKSk7CisgICAgICAgIGNsYXNzcGF0aC5hZGRBbGwoY2xhc3NwYXRoVG9VcmxzKCJzdW4uYm9vdC5jbGFzcy5wYXRoIikpOworICAgICAgICByZXR1cm4gbmV3IFVSTENsYXNzTG9hZGVyKGNsYXNzcGF0aC50b0FycmF5KG5ldyBVUkxbY2xhc3NwYXRoLnNpemUoKV0pLCBicmlkZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBwYXRoIGNvbnRhaW5pbmcgdGhlIGFwcGxpY2F0aW9uJ3MgY2xhc3Nlcy4gV2hlbiBydW5uaW5nIGluIHRoZQorICAgICAqIEFuZHJvaWQgZnJhbWV3b3JrIHRoaXMgd2lsbCBiZSB0aGUgQVBLIGZpbGU7IG90aGVyd2lzZSBpdCdzIHRoZSBydW50aW1lJ3MKKyAgICAgKiByZXBvcnRlZCBjbGFzcyBwYXRoLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGdldEFwcGxpY2F0aW9uQ2xhc3NQYXRoKCkgeworICAgICAgICBTdHJpbmcgbWFuaWZlc3RGaWxlID0gIkFuZHJvaWRNYW5pZmVzdC54bWwiOworICAgICAgICBTdHJpbmcgc3VmZml4ID0gIiEvIiArIG1hbmlmZXN0RmlsZTsKKyAgICAgICAgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpOworICAgICAgICBVUkwgbWFuaWZlc3QgPSBjbGFzc0xvYWRlci5nZXRSZXNvdXJjZShtYW5pZmVzdEZpbGUpOworICAgICAgICBpZiAobWFuaWZlc3QgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIG1hbmlmZXN0U3RyaW5nID0gbWFuaWZlc3QudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGlmIChtYW5pZmVzdFN0cmluZy5lbmRzV2l0aChzdWZmaXgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG1hbmlmZXN0U3RyaW5nLnN1YnN0cmluZygwLCBtYW5pZmVzdFN0cmluZy5sZW5ndGgoKSAtIHN1ZmZpeC5sZW5ndGgoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5jbGFzcy5wYXRoIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBMaXN0PFVSTD4gY2xhc3NwYXRoVG9VcmxzKFN0cmluZyBwcm9wZXJ0eU5hbWUpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBjbGFzc3BhdGggPSBTeXN0ZW0uZ2V0UHJvcGVydHkocHJvcGVydHlOYW1lKTsKKyAgICAgICAgICAgIExpc3Q8VVJMPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PFVSTD4oKTsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIHBhdGhFbGVtZW50IDogY2xhc3NwYXRoLnNwbGl0KEZpbGUucGF0aFNlcGFyYXRvcikpIHsKKyAgICAgICAgICAgICAgICByZXN1bHQuYWRkKG5ldyBGaWxlKHBhdGhFbGVtZW50KS50b1VSSSgpLnRvVVJMKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3V0aWwvRmllbGRUZXN0RmlsZUdlbmVyYXRvci5qYXZhIGIvc3VwcG9ydC9zcmMvdGVzdC9qYXZhL3Rlc3RzL3V0aWwvRmllbGRUZXN0RmlsZUdlbmVyYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYwMDc5ZjYKLS0tIC9kZXYvbnVsbAorKysgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvdXRpbC9GaWVsZFRlc3RGaWxlR2VuZXJhdG9yLmphdmEKQEAgLTAsMCArMSwxMDcgQEAKKy8qCisgKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMudXRpbDsKKworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9HZXRQdXRGaWVsZHM7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0dldFB1dEZpZWxkc0RlcHJlY2F0ZWQ7CitpbXBvcnQgdGVzdHMuc3VwcG9ydC5TdXBwb3J0X0dldFB1dEZpZWxkc0RlZmF1bHRlZDsKKworLyoqCisgKiBXcml0ZXMgdGhyZWUgdGVzdCBmaWxlcyB0aGF0IGFyZSB1c2VkIGFzIHJlZmVyZW5jZSBpbgorICoge0Bjb2RlIHRlc3RzLmFwaS5qYXZhLmlvLk9iamVjdElucHV0U3RyZWFtR2V0RmllbGRUZXN0fSBhbmQKKyAqIHtAY29kZSB0ZXN0cy5hcGkuamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW1QdXRGaWVsZFRlc3R9LgorICogVGhlc2UgZmlsZXMgbXVzdCBiZSBtb3ZlZCB0bworICoge0Bjb2RlICRBTkRST0lEX0JVSUxEX1RPUC9kYWx2aWsvbGliY29yZS9sdW5pL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0cy9hcGkvamF2YS9pb30KKyAqIHRvIGJlIGluY2x1ZGVkIGF0IHRoZSBjb3JyZWN0IGxvY2F0aW9uIGluIHRoZSBjb3JlIHRlc3RzIHBhY2thZ2UuCisgKiA8cD4KKyAqIDxzdHJvbmc+SW1wb3J0YW50Ojwvc3Ryb25nPiBCZWZvcmUgZXhlY3V0aW5nIHRoaXMgY2xhc3MsIHRoZSBjb250ZW50cyBvZiBjbGFzcworICoge0Bjb2RlIHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9HZXRQdXRGaWVsZHNEZWZhdWx0ZWR9IG11c3QgYmUgY29tbWVudGVkIG91dC4gU2VlIHRoZQorICogZGVzY3JpcHRpb24gdGhlcmUgZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCisgKi8KK3B1YmxpYyBjbGFzcyBGaWVsZFRlc3RGaWxlR2VuZXJhdG9yIHsKKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gZm9zID0gbnVsbDsKKyAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtIG9vcyA9IG51bGw7CisgICAgICAgIFN1cHBvcnRfR2V0UHV0RmllbGRzIHRvU2VyaWFsaXplID0gbmV3IFN1cHBvcnRfR2V0UHV0RmllbGRzKCk7CisgICAgICAgIFN1cHBvcnRfR2V0UHV0RmllbGRzRGVwcmVjYXRlZCB0b1NlcmlhbGl6ZURlcHJlY2F0ZWQgPQorICAgICAgICAgICAgICAgIG5ldyBTdXBwb3J0X0dldFB1dEZpZWxkc0RlcHJlY2F0ZWQoKTsKKyAgICAgICAgU3VwcG9ydF9HZXRQdXRGaWVsZHNEZWZhdWx0ZWQgdG9TZXJpYWxpemVEZWZhdWx0ZWQgPQorICAgICAgICAgICAgICAgIG5ldyBTdXBwb3J0X0dldFB1dEZpZWxkc0RlZmF1bHRlZCgpOworICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSB0cnVlOworCisgICAgICAgIHRvU2VyaWFsaXplLmluaXRUZXN0VmFsdWVzKCk7CisgICAgICAgIHRvU2VyaWFsaXplRGVwcmVjYXRlZC5pbml0VGVzdFZhbHVlcygpOworICAgICAgICB0b1NlcmlhbGl6ZURlZmF1bHRlZC5pbml0VGVzdFZhbHVlcygpOworCisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVHJ5aW5nIHRvIHdyaXRlIHRoZSB0ZXN0IGZpbGUgJ3Rlc3RGaWVsZHMuc2VyJy4uLiIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZm9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oInRlc3RGaWVsZHMuc2VyIik7CisgICAgICAgICAgICBvb3MgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKGZvcyk7CisgICAgICAgICAgICBvb3Mud3JpdGVPYmplY3QodG9TZXJpYWxpemUpOworICAgICAgICAgICAgb29zLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkV4Y2VwdGlvbiBvY2N1cmVkIHdoaWxlIHdyaXRpbmcgdGhlIGZpbGU6ICIgKyBlKTsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChmb3MgIT0gbnVsbCkgZm9zLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRyeWluZyB0byB3cml0ZSB0aGUgdGVzdCBmaWxlICd0ZXN0RmllbGRzRGVwcmVjYXRlZC5zZXInLi4uIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbSgidGVzdEZpZWxkc0RlcHJlY2F0ZWQuc2VyIik7CisgICAgICAgICAgICBvb3MgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKGZvcyk7CisgICAgICAgICAgICBvb3Mud3JpdGVPYmplY3QodG9TZXJpYWxpemVEZXByZWNhdGVkKTsKKyAgICAgICAgICAgIG9vcy5jbG9zZSgpOworICAgICAgICB9CisgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFeGNlcHRpb24gb2NjdXJlZCB3aGlsZSB3cml0aW5nIHRoZSBmaWxlOiAiICsgZSk7CisgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgZmluYWxseSB7CisgICAgICAgICAgICBpZiAoZm9zICE9IG51bGwpIGZvcy5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUcnlpbmcgdG8gd3JpdGUgdGhlIHRlc3QgZmlsZSAndGVzdEZpZWxkc0RlZmF1bHRlZC5zZXInLi4uIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbSgidGVzdEZpZWxkc0RlZmF1bHRlZC5zZXIiKTsKKyAgICAgICAgICAgIG9vcyA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0oZm9zKTsKKyAgICAgICAgICAgIG9vcy53cml0ZU9iamVjdCh0b1NlcmlhbGl6ZURlZmF1bHRlZCk7CisgICAgICAgICAgICBvb3MuY2xvc2UoKTsKKyAgICAgICAgfQorICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXhjZXB0aW9uIG9jY3VyZWQgd2hpbGUgd3JpdGluZyB0aGUgZmlsZTogIiArIGUpOworICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlOworICAgICAgICB9CisgICAgICAgIGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGZvcyAhPSBudWxsKSBmb3MuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzdWNjZXNzKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlN1Y2Nlc3MhIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZhaWx1cmUhIik7CisgICAgICAgIH0KKworICAgIH0KKyB9CmRpZmYgLS1naXQgYS9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvdXRpbC9TZXJpYWxpemF0aW9uVGVzdGVyLmphdmEgYi9zdXBwb3J0L3NyYy90ZXN0L2phdmEvdGVzdHMvdXRpbC9TZXJpYWxpemF0aW9uVGVzdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmQ5YmM5MwotLS0gL2Rldi9udWxsCisrKyBiL3N1cHBvcnQvc3JjL3Rlc3QvamF2YS90ZXN0cy91dGlsL1NlcmlhbGl6YXRpb25UZXN0ZXIuamF2YQpAQCAtMCwwICsxLDI0NiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2UgdGVzdHMudXRpbDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CisKKy8qKgorICogVGhpcyBjbGFzcyBzaW1wbGlmaWVzIHRoZSBzZXJpYWxpemF0aW9uIHRlc3QuCisgKgorICovCitwdWJsaWMgY2xhc3MgU2VyaWFsaXphdGlvblRlc3RlciB7CisKKyAgICAvKgorICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICogQ2xhc3MgdmFyaWFibGVzCisgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAgKi8KKworICAgIC8vIHRoZSBsYXN0IGRlc2VyaWFsaXplZCBvYmplY3QKKyAgICBwcml2YXRlIHN0YXRpYyBPYmplY3QgbGFzdE91dHB1dCA9IG51bGw7CisKKyAgICAvKgorICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAgKiBDb25zdHJ1Y3RvcnMKKyAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgICovCisKKyAgICBwcml2YXRlIFNlcmlhbGl6YXRpb25UZXN0ZXIoKSB7CisKKyAgICB9CisKKyAgICAvKgorICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAgKiBNZXRob2RzCisgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICAqLworCisgICAgLyoqCisgICAgICogU2VyaWFsaXplIGFuIG9iamVjdCBhbmQgdGhlbiBkZXNlcmlhbGl6ZSBpdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dE9iamVjdAorICAgICAqICAgICAgICAgICAgdGhlIGlucHV0IG9iamVjdAorICAgICAqIEByZXR1cm4gdGhlIGRlc2VyaWFsaXplZCBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUPiBUIGdldERlc2VyaWFsaXplZE9iamVjdChUIGlucHV0T2JqZWN0KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtIG9vcyA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0oYm9zKTsKKyAgICAgICAgb29zLndyaXRlT2JqZWN0KGlucHV0T2JqZWN0KTsKKyAgICAgICAgb29zLmNsb3NlKCk7CisKKyAgICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJvcy50b0J5dGVBcnJheSgpKTsKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0gb2lzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKGJpcyk7CisgICAgICAgIE9iamVjdCBvdXRwdXRPYmplY3QgPSBvaXMucmVhZE9iamVjdCgpOworICAgICAgICBsYXN0T3V0cHV0ID0gb3V0cHV0T2JqZWN0OworICAgICAgICBvaXMuY2xvc2UoKTsKKyAgICAgICAgcmV0dXJuIChUKSBvdXRwdXRPYmplY3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgdGhlIHNlcmlhbGl6YXRpb24gYW5kIGRlc2VyaWFsaXphdGlvbiBvZiBjb25zdCBvYmplY3RzLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0T2JqZWN0CisgICAgICogICAgICAgICAgICBBIGNvbnN0IG9iamVjdAorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZGVzZXJpYWxpemVkIG9iamVjdCBpcyB0aGUgc2FtZSBhcyB0aGUgaW5wdXQgb2JqZWN0LAorICAgICAqICAgICAgICAgb3RoZXJ3aXNlIGZhbHNlCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICBJZiBhbnkgb2NjdXJzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBhc3NlcnRTYW1lKE9iamVjdCBpbnB1dE9iamVjdCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBpbnB1dE9iamVjdCA9PSBnZXREZXNlcmlhbGl6ZWRPYmplY3QoaW5wdXRPYmplY3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHRoZSBzZXJpYWxpemF0aW9uIGFuZCBkZXNlcmlhbGl6YXRpb24gb2YgaW5zdGFuY2Ugb2JqZWN0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dE9iamVjdAorICAgICAqICAgICAgICAgICAgQW4gb2JqZWN0CisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBkZXNlcmlhbGl6ZWQgb2JqZWN0IGlzIGVxdWFsIHRvIHRoZSBpbnB1dCBvYmplY3QsCisgICAgICogICAgICAgICBvdGhlcndpc2UgZmFsc2UKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFueSBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGFzc2VydEVxdWFscyhPYmplY3QgaW5wdXRPYmplY3QpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICByZXR1cm4gaW5wdXRPYmplY3QuZXF1YWxzKGdldERlc2VyaWFsaXplZE9iamVjdChpbnB1dE9iamVjdCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIHRoZSBzZXJpYWxpemF0aW9uIGNvbXBhdGliaWxpdHkgd2l0aCByZWZlcmVuY2UgY29uc3Qgb2JqZWN0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiAgICAgICAgICAgIHRoZSBvYmplY3QgdG8gYmUgY2hlY2tlZAorICAgICAqIEBwYXJhbSBmaWxlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHNlcmlhbGl6YXRpb24gb3V0cHV0IGZpbGUgZ2VuZXJhdGVkIGJ5IHJlZmVyZW5jZQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBjb21wYXRpYmxlLCBvdGhlcndpc2UgZmFsc2UKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFueSBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGFzc2VydENvbXBhdGliaWxpdHlTYW1lKE9iamVjdCBvYmosIFN0cmluZyBmaWxlTmFtZSkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICByZXR1cm4gb2JqID09IHJlYWRPYmplY3Qob2JqLCBmaWxlTmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgdGhlIHNlcmlhbGl6YXRpb24gY29tcGF0aWJpbGl0eSB3aXRoIHJlZmVyZW5jZSBmb3IgaW5zdGFuY2UKKyAgICAgKiBvYmplY3RzLgorICAgICAqCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBiZSBjaGVja2VkCisgICAgICogQHBhcmFtIGZpbGVOYW1lCisgICAgICogICAgICAgICAgICB0aGUgc2VyaWFsaXphdGlvbiBvdXRwdXQgZmlsZSBnZW5lcmF0ZWQgYnkgcmVmZXJlbmNlCisgICAgICogQHJldHVybiB0cnVlIGlmIGNvbXBhdGlibGUsIG90aGVyd2lzZSBmYWxzZQorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgSWYgYW55IG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gYXNzZXJ0Q29tcGF0aWJpbGl0eUVxdWFscyhPYmplY3Qgb2JqLCBTdHJpbmcgZmlsZU5hbWUpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG9iai5lcXVhbHMocmVhZE9iamVjdChvYmosIGZpbGVOYW1lKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVzZXJpYWxpemUgYW4gb2JqZWN0IGZyb20gYSBmaWxlLgorICAgICAqCisgICAgICogQHBhcmFtIG9iagorICAgICAqICAgICAgICAgICAgdGhlIG9iamVjdCB0byBiZSBzZXJpYWxpemVkIGlmIG5vIHNlcmlhbGl6YXRpb24gZmlsZSBpcyBmb3VuZAorICAgICAqIEBwYXJhbSBmaWxlTmFtZQorICAgICAqICAgICAgICAgICAgdGhlIHNlcmlhbGl6YXRpb24gZmlsZQorICAgICAqIEByZXR1cm4gdGhlIGRlc2VyaWFsaXplZCBvYmplY3QKKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIElmIGFueSBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBPYmplY3QgcmVhZE9iamVjdChPYmplY3Qgb2JqLCBTdHJpbmcgZmlsZU5hbWUpCisgICAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSW5wdXRTdHJlYW0gaW5wdXQgPSBudWxsOworICAgICAgICBPYmplY3RJbnB1dFN0cmVhbSBvaW5wdXQgPSBudWxsOworICAgICAgICBVUkwgdXJsID0gU2VyaWFsaXphdGlvblRlc3Rlci5jbGFzcy5nZXRSZXNvdXJjZSgKKyAgICAgICAgICAgICAgICBmaWxlTmFtZSk7CisgICAgICAgIGlmIChudWxsID09IHVybCkgeworICAgICAgICAgICAgLy8gc2VyaWFsaXphdGlvbiBmaWxlIGRvZXMgbm90IGV4aXN0LCBjcmVhdGUgb25lIGluIHRoZSBjdXJyZW50IGRpcgorICAgICAgICAgICAgd3JpdGVPYmplY3Qob2JqLCBuZXcgRmlsZShmaWxlTmFtZSkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigKKyAgICAgICAgICAgICAgICAgICAgIlNlcmlhbGl6YXRpb24gZmlsZSBkb2VzIG5vdCBleGlzdCwgY3JlYXRlZCBpbiB0aGUgY3VycmVudCBkaXIuIik7CisgICAgICAgIH0KKyAgICAgICAgaW5wdXQgPSB1cmwub3BlblN0cmVhbSgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgb2lucHV0ID0gbmV3IE9iamVjdElucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgICAgICAgIE9iamVjdCBuZXdPYmogPSBvaW5wdXQucmVhZE9iamVjdCgpOworICAgICAgICAgICAgcmV0dXJuIG5ld09iajsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKG51bGwgIT0gb2lucHV0KSB7CisgICAgICAgICAgICAgICAgICAgIG9pbnB1dC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gaWdub3JlCisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmIChudWxsICE9IGlucHV0KSB7CisgICAgICAgICAgICAgICAgICAgIGlucHV0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBpZ25vcmUKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogQ3JlYXRlcyBhIHNlcmlhbGl6YXRpb24gb3V0cHV0LgorICAgICAqCisgICAgICogQHBhcmFtIG9iaiB0aGUgb2JqZWN0IHRvIGJlIHNlcmlhbGl6ZWQgQHBhcmFtIGZpbGVOYW1lIHRoZSBvdXRwdXQgZmlsZQorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uIElmIGFueSBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdCBvYmosIFN0cmluZyBmaWxlTmFtZSkKKyAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBTdHJpbmcgcGF0aCA9IFNlcmlhbGl6YXRpb25UZXN0ZXIuY2xhc3MuZ2V0UmVzb3VyY2UoIi4iKS5nZXRQYXRoKCk7CisgICAgICAgIC8vIGlmIChwYXRoLmVuZHNXaXRoKCIuIikpIHsKKyAgICAgICAgLy8gcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGgubGVuZ3RoKCkgLSAxKTsKKyAgICAgICAgLy8gfQorICAgICAgICAvLyBpZiAoIXBhdGguZW5kc1dpdGgoIi8iKSkgeworICAgICAgICAvLyBwYXRoICs9ICIvIjsKKyAgICAgICAgLy8gfQorICAgICAgICAvLyBwYXRoICs9IGZpbGVOYW1lOworICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4ocGF0aCk7CisgICAgICAgIE91dHB1dFN0cmVhbSBvdXRwdXQgPSBudWxsOworICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0gb291dHB1dCA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBvdXRwdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlTmFtZSk7CisgICAgICAgICAgICBvb3V0cHV0ID0gbmV3IE9iamVjdE91dHB1dFN0cmVhbShvdXRwdXQpOworICAgICAgICAgICAgb291dHB1dC53cml0ZU9iamVjdChvYmopOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAobnVsbCAhPSBvb3V0cHV0KSB7CisgICAgICAgICAgICAgICAgICAgIG9vdXRwdXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGlnbm9yZQorICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAobnVsbCAhPSBvdXRwdXQpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0cHV0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBpZ25vcmUKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxhc3QgZGVzZXJpYWxpemVkIG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGxhc3QgZGVzZXJpYWxpemVkIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgT2JqZWN0IGdldExhc3RPdXRwdXQoKSB7CisgICAgICAgIHJldHVybiBsYXN0T3V0cHV0OworICAgIH0KKworICAgIC8qCisgICAgICogRm9yIHRlc3QgcHVycG9zZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEveG1sL3NyYy9tYWluL2phdmEvb3JnL2t4bWwyL1RoaXJkUGFydHlQcm9qZWN0LnByb3AgYi94bWwvc3JjL21haW4vamF2YS9vcmcva3htbDIvVGhpcmRQYXJ0eVByb2plY3QucHJvcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYWJiMWM3Ci0tLSAvZGV2L251bGwKKysrIGIveG1sL3NyYy9tYWluL2phdmEvb3JnL2t4bWwyL1RoaXJkUGFydHlQcm9qZWN0LnByb3AKQEAgLTAsMCArMSw5IEBACisjIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisjRnJpIEp1bCAxNiAxMDowMzowOSBQRFQgMjAxMAorY3VycmVudFZlcnNpb249Mi4zLjAKK3ZlcnNpb249VW5rbm93bgoraXNOYXRpdmU9ZmFsc2UKK25hbWU9a3htbAora2V5d29yZHM9a3htbAorb25EZXZpY2U9dHJ1ZQoraG9tZXBhZ2U9aHR0cFw6Ly9reG1sLnNvdXJjZWZvcmdlLm5ldC8KZGlmZiAtLWdpdCBhL3htbC9zcmMvbWFpbi9qYXZhL29yZy9reG1sMi9pby9LWG1sUGFyc2VyLmphdmEgYi94bWwvc3JjL21haW4vamF2YS9vcmcva3htbDIvaW8vS1htbFBhcnNlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiZThkMzYKLS0tIC9kZXYvbnVsbAorKysgYi94bWwvc3JjL21haW4vamF2YS9vcmcva3htbDIvaW8vS1htbFBhcnNlci5qYXZhCkBAIC0wLDAgKzEsMjE1NyBAQAorLyogQ29weXJpZ2h0IChjKSAyMDAyLDIwMDMsIFN0ZWZhbiBIYXVzdGVpbiwgT2JlcmhhdXNlbiwgUmhsZC4sIEdlcm1hbnkKKyAqCisgKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5CisgKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAorICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cworICogdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3IKKyAqIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzCisgKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgorICoKKyAqIFRoZSAgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgorICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCisgKgorICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKKyAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAorICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCisgKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCisgKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORworICogRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUworICogSU4gVEhFIFNPRlRXQVJFLiAqLworCisvLyBDb250cmlidXRvcnM6IFBhdWwgSGFja2VuYmVyZ2VyICh1bnRlcm1pbmF0ZWQgZW50aXR5IGhhbmRsaW5nIGluIHJlbGF4ZWQgbW9kZSkKKworcGFja2FnZSBvcmcua3htbDIuaW87CisKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLlJlYWRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGxpYmNvcmUuaW50ZXJuYWwuU3RyaW5nUG9vbDsKK2ltcG9ydCBvcmcueG1scHVsbC52MS5YbWxQdWxsUGFyc2VyOworaW1wb3J0IG9yZy54bWxwdWxsLnYxLlhtbFB1bGxQYXJzZXJFeGNlcHRpb247CisKKy8qKgorICogQW4gWE1MIHB1bGwgcGFyc2VyIHdpdGggbGltaXRlZCBzdXBwb3J0IGZvciBwYXJzaW5nIGludGVybmFsIERURHMuCisgKi8KK3B1YmxpYyBjbGFzcyBLWG1sUGFyc2VyIGltcGxlbWVudHMgWG1sUHVsbFBhcnNlciwgQ2xvc2VhYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QRVJUWV9YTUxERUNMX1ZFUlNJT04KKyAgICAgICAgICAgID0gImh0dHA6Ly94bWxwdWxsLm9yZy92MS9kb2MvcHJvcGVydGllcy5odG1sI3htbGRlY2wtdmVyc2lvbiI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZX1hNTERFQ0xfU1RBTkRBTE9ORQorICAgICAgICAgICAgPSAiaHR0cDovL3htbHB1bGwub3JnL3YxL2RvYy9wcm9wZXJ0aWVzLmh0bWwjeG1sZGVjbC1zdGFuZGFsb25lIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJPUEVSVFlfTE9DQVRJT04gPSAiaHR0cDovL3htbHB1bGwub3JnL3YxL2RvYy9wcm9wZXJ0aWVzLmh0bWwjbG9jYXRpb24iOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGRUFUVVJFX1JFTEFYRUQgPSAiaHR0cDovL3htbHB1bGwub3JnL3YxL2RvYy9mZWF0dXJlcy5odG1sI3JlbGF4ZWQiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBERUZBVUxUX0VOVElUSUVTID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CisgICAgc3RhdGljIHsKKyAgICAgICAgREVGQVVMVF9FTlRJVElFUy5wdXQoImx0IiwgIjwiKTsKKyAgICAgICAgREVGQVVMVF9FTlRJVElFUy5wdXQoImd0IiwgIj4iKTsKKyAgICAgICAgREVGQVVMVF9FTlRJVElFUy5wdXQoImFtcCIsICImIik7CisgICAgICAgIERFRkFVTFRfRU5USVRJRVMucHV0KCJhcG9zIiwgIiciKTsKKyAgICAgICAgREVGQVVMVF9FTlRJVElFUy5wdXQoInF1b3QiLCAiXCIiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRUxFTUVOVERFQ0wgPSAxMTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRU5USVRZREVDTCA9IDEyOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBVFRMSVNUREVDTCA9IDEzOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOT1RBVElPTkRFQ0wgPSAxNDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUEFSQU1FVEVSX0VOVElUWV9SRUYgPSAxNTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gU1RBUlRfQ09NTUVOVCA9IHsgJzwnLCAnIScsICctJywgJy0nIH07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIEVORF9DT01NRU5UID0geyAnLScsICctJywgJz4nIH07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIENPTU1FTlRfRE9VQkxFX0RBU0ggPSB7ICctJywgJy0nIH07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIFNUQVJUX0NEQVRBID0geyAnPCcsICchJywgJ1snLCAnQycsICdEJywgJ0EnLCAnVCcsICdBJywgJ1snIH07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIEVORF9DREFUQSA9IHsgJ10nLCAnXScsICc+JyB9OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBTVEFSVF9QUk9DRVNTSU5HX0lOU1RSVUNUSU9OID0geyAnPCcsICc/JyB9OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBFTkRfUFJPQ0VTU0lOR19JTlNUUlVDVElPTiA9IHsgJz8nLCAnPicgfTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gU1RBUlRfRE9DVFlQRSA9IHsgJzwnLCAnIScsICdEJywgJ08nLCAnQycsICdUJywgJ1knLCAnUCcsICdFJyB9OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBTWVNURU0gPSB7ICdTJywgJ1knLCAnUycsICdUJywgJ0UnLCAnTScgfTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gUFVCTElDID0geyAnUCcsICdVJywgJ0InLCAnTCcsICdJJywgJ0MnIH07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIFNUQVJUX0VMRU1FTlQgPSB7ICc8JywgJyEnLCAnRScsICdMJywgJ0UnLCAnTScsICdFJywgJ04nLCAnVCcgfTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gU1RBUlRfQVRUTElTVCA9IHsgJzwnLCAnIScsICdBJywgJ1QnLCAnVCcsICdMJywgJ0knLCAnUycsICdUJyB9OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBTVEFSVF9FTlRJVFkgPSB7ICc8JywgJyEnLCAnRScsICdOJywgJ1QnLCAnSScsICdUJywgJ1knIH07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIFNUQVJUX05PVEFUSU9OID0geyAnPCcsICchJywgJ04nLCAnTycsICdUJywgJ0EnLCAnVCcsICdJJywgJ08nLCAnTicgfTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gRU1QVFkgPSBuZXcgY2hhcltdIHsgJ0UnLCAnTScsICdQJywgJ1QnLCAnWScgfTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gQU5ZID0gbmV3IGNoYXJbXXsgJ0EnLCAnTicsICdZJyB9OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBOREFUQSA9IG5ldyBjaGFyW117ICdOJywgJ0QnLCAnQScsICdUJywgJ0EnIH07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIE5PVEFUSU9OID0gbmV3IGNoYXJbXXsgJ04nLCAnTycsICdUJywgJ0EnLCAnVCcsICdJJywgJ08nLCAnTicgfTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gUkVRVUlSRUQgPSBuZXcgY2hhcltdIHsgJ1InLCAnRScsICdRJywgJ1UnLCAnSScsICdSJywgJ0UnLCAnRCcgfTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gSU1QTElFRCA9IG5ldyBjaGFyW10geyAnSScsICdNJywgJ1AnLCAnTCcsICdJJywgJ0UnLCAnRCcgfTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gRklYRUQgPSBuZXcgY2hhcltdIHsgJ0YnLCAnSScsICdYJywgJ0UnLCAnRCcgfTsKKworICAgIHN0YXRpYyBmaW5hbCBwcml2YXRlIFN0cmluZyBVTkVYUEVDVEVEX0VPRiA9ICJVbmV4cGVjdGVkIEVPRiI7CisgICAgc3RhdGljIGZpbmFsIHByaXZhdGUgU3RyaW5nIElMTEVHQUxfVFlQRSA9ICJXcm9uZyBldmVudCB0eXBlIjsKKyAgICBzdGF0aWMgZmluYWwgcHJpdmF0ZSBpbnQgWE1MX0RFQ0xBUkFUSU9OID0gOTk4OworCisgICAgLy8gZ2VuZXJhbAorICAgIHByaXZhdGUgU3RyaW5nIGxvY2F0aW9uOworCisgICAgcHJpdmF0ZSBTdHJpbmcgdmVyc2lvbjsKKyAgICBwcml2YXRlIEJvb2xlYW4gc3RhbmRhbG9uZTsKKyAgICBwcml2YXRlIFN0cmluZyByb290RWxlbWVudE5hbWU7CisgICAgcHJpdmF0ZSBTdHJpbmcgc3lzdGVtSWQ7CisgICAgcHJpdmF0ZSBTdHJpbmcgcHVibGljSWQ7CisKKyAgICAvKioKKyAgICAgKiBUcnVlIGlmIHRoZSB7QGNvZGUgPCFET0NUWVBFPn0gY29udGVudHMgYXJlIGhhbmRsZWQuIFRoZSBEVEQgZGVmaW5lcworICAgICAqIGVudGl0eSB2YWx1ZXMgYW5kIGRlZmF1bHQgYXR0cmlidXRlIHZhbHVlcy4gVGhlc2UgdmFsdWVzIGFyZSBwYXJzZWQgYXQKKyAgICAgKiBpbmNsdXNpb24gdGltZSBhbmQgbWF5IGNvbnRhaW4gYm90aCB0YWdzIGFuZCBlbnRpdHkgcmVmZXJlbmNlcy4KKyAgICAgKgorICAgICAqIDxwPklmIHRoaXMgaXMgZmFsc2UsIHRoZSB1c2VyIG11c3Qge0BsaW5rICNkZWZpbmVFbnRpdHlSZXBsYWNlbWVudFRleHQKKyAgICAgKiBkZWZpbmUgZW50aXR5IHZhbHVlcyBtYW51YWxseX0uIFN1Y2ggZW50aXR5IHZhbHVlcyBhcmUgbGl0ZXJhbCBzdHJpbmdzCisgICAgICogYW5kIHdpbGwgbm90IGJlIHBhcnNlZC4gVGhlcmUgaXMgbm8gQVBJIHRvIGRlZmluZSBkZWZhdWx0IGF0dHJpYnV0ZXMKKyAgICAgKiBtYW51YWxseS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gcHJvY2Vzc0RvY0RlY2w7CisgICAgcHJpdmF0ZSBib29sZWFuIHByb2Nlc3NOc3A7CisgICAgcHJpdmF0ZSBib29sZWFuIHJlbGF4ZWQ7CisgICAgcHJpdmF0ZSBib29sZWFuIGtlZXBOYW1lc3BhY2VBdHRyaWJ1dGVzOworCisgICAgLyoqCisgICAgICogSWYgbm9uLW51bGwsIHRoZSBjb250ZW50cyBvZiB0aGUgcmVhZCBidWZmZXIgbXVzdCBiZSBjb3BpZWQgaW50byB0aGlzCisgICAgICogc3RyaW5nIGJ1aWxkZXIgYmVmb3JlIHRoZSByZWFkIGJ1ZmZlciBpcyBvdmVyd3JpdHRlbi4gVGhpcyBpcyB1c2VkIHRvCisgICAgICogY2FwdHVyZSB0aGUgcmF3IERURCB0ZXh0IHdoaWxlIHBhcnNpbmcgdGhlIERURC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZ0J1aWxkZXIgYnVmZmVyQ2FwdHVyZTsKKworICAgIC8qKgorICAgICAqIEVudGl0aWVzIGRlZmluZWQgaW4gb3IgZm9yIHRoaXMgZG9jdW1lbnQuIFRoaXMgbWFwIGlzIGNyZWF0ZWQgbGF6aWx5LgorICAgICAqLworICAgIHByaXZhdGUgTWFwPFN0cmluZywgY2hhcltdPiBkb2N1bWVudEVudGl0aWVzOworCisgICAgLyoqCisgICAgICogRGVmYXVsdCBhdHRyaWJ1dGVzIGluIHRoaXMgZG9jdW1lbnQuIFRoZSBvdXRlciBtYXAncyBrZXkgaXMgdGhlIGVsZW1lbnQKKyAgICAgKiBuYW1lOyB0aGUgaW5uZXIgbWFwJ3Mga2V5IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4gQm90aCBrZXlzIHNob3VsZCBiZQorICAgICAqIHdpdGhvdXQgbmFtZXNwYWNlIGFkanVzdG1lbnRzLiBUaGlzIG1hcCBpcyBjcmVhdGVkIGxhemlseS4KKyAgICAgKi8KKyAgICBwcml2YXRlIE1hcDxTdHJpbmcsIE1hcDxTdHJpbmcsIFN0cmluZz4+IGRlZmF1bHRBdHRyaWJ1dGVzOworCisKKyAgICBwcml2YXRlIGludCBkZXB0aDsKKyAgICBwcml2YXRlIFN0cmluZ1tdIGVsZW1lbnRTdGFjayA9IG5ldyBTdHJpbmdbMTZdOworICAgIHByaXZhdGUgU3RyaW5nW10gbnNwU3RhY2sgPSBuZXcgU3RyaW5nWzhdOworICAgIHByaXZhdGUgaW50W10gbnNwQ291bnRzID0gbmV3IGludFs0XTsKKworICAgIC8vIHNvdXJjZQorCisgICAgcHJpdmF0ZSBSZWFkZXIgcmVhZGVyOworICAgIHByaXZhdGUgU3RyaW5nIGVuY29kaW5nOworICAgIHByaXZhdGUgQ29udGVudFNvdXJjZSBuZXh0Q29udGVudFNvdXJjZTsKKyAgICBwcml2YXRlIGNoYXJbXSBidWZmZXIgPSBuZXcgY2hhcls4MTkyXTsKKyAgICBwcml2YXRlIGludCBwb3NpdGlvbiA9IDA7CisgICAgcHJpdmF0ZSBpbnQgbGltaXQgPSAwOworCisgICAgLyoKKyAgICAgKiBUcmFjayB0aGUgbnVtYmVyIG9mIG5ld2xpbmVzIGFuZCBjb2x1bW5zIHByZWNlZGluZyB0aGUgY3VycmVudCBidWZmZXIuIFRvCisgICAgICogY29tcHV0ZSB0aGUgbGluZSBhbmQgY29sdW1uIG9mIGEgcG9zaXRpb24gaW4gdGhlIGJ1ZmZlciwgY29tcHV0ZSB0aGUgbGluZQorICAgICAqIGFuZCBjb2x1bW4gaW4gdGhlIGJ1ZmZlciBhbmQgYWRkIHRoZSBwcmVjZWRpbmcgdmFsdWVzLgorICAgICAqLworICAgIHByaXZhdGUgaW50IGJ1ZmZlclN0YXJ0TGluZTsKKyAgICBwcml2YXRlIGludCBidWZmZXJTdGFydENvbHVtbjsKKworICAgIC8vIHRoZSBjdXJyZW50IHRva2VuCisKKyAgICBwcml2YXRlIGludCB0eXBlOworICAgIHByaXZhdGUgYm9vbGVhbiBpc1doaXRlc3BhY2U7CisgICAgcHJpdmF0ZSBTdHJpbmcgbmFtZXNwYWNlOworICAgIHByaXZhdGUgU3RyaW5nIHByZWZpeDsKKyAgICBwcml2YXRlIFN0cmluZyBuYW1lOworICAgIHByaXZhdGUgU3RyaW5nIHRleHQ7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gZGVnZW5lcmF0ZWQ7CisgICAgcHJpdmF0ZSBpbnQgYXR0cmlidXRlQ291bnQ7CisKKyAgICAvKgorICAgICAqIFRoZSBjdXJyZW50IGVsZW1lbnQncyBhdHRyaWJ1dGVzIGFycmFuZ2VkIGluIGdyb3VwcyBvZiA0OgorICAgICAqIGkgKyAwID0gYXR0cmlidXRlIG5hbWVzcGFjZSBVUkkKKyAgICAgKiBpICsgMSA9IGF0dHJpYnV0ZSBuYW1lc3BhY2UgcHJlZml4CisgICAgICogaSArIDIgPSBhdHRyaWJ1dGUgcXVhbGlmaWVkIG5hbWUgKG1heSBjb250YWluICI6IiwgYXMgaW4gImh0bWw6aDEiKQorICAgICAqIGkgKyAzID0gYXR0cmlidXRlIHZhbHVlCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmdbXSBhdHRyaWJ1dGVzID0gbmV3IFN0cmluZ1sxNl07CisKKyAgICBwcml2YXRlIFN0cmluZyBlcnJvcjsKKworICAgIHByaXZhdGUgYm9vbGVhbiB1bnJlc29sdmVkOworCisgICAgcHVibGljIGZpbmFsIFN0cmluZ1Bvb2wgc3RyaW5nUG9vbCA9IG5ldyBTdHJpbmdQb29sKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXRhaW5zIG5hbWVzcGFjZSBhdHRyaWJ1dGVzIGxpa2Uge0Bjb2RlIHhtbG5zPSJodHRwOi8vZm9vIn0gb3Ige0Bjb2RlIHhtbG5zOmZvbz0iaHR0cDpmb28ifQorICAgICAqIGluIHB1bGxlZCBlbGVtZW50cy4gTW9zdCBhcHBsaWNhdGlvbnMgd2lsbCBvbmx5IGJlIGludGVyZXN0ZWQgaW4gdGhlIGVmZmVjdGl2ZSBuYW1lc3BhY2VzIG9mCisgICAgICogdGhlaXIgZWxlbWVudHMsIHNvIHRoZXNlIGF0dHJpYnV0ZXMgYXJlbid0IHVzZWZ1bC4gQnV0IGZvciBzdHJ1Y3R1cmUgcHJlc2VydmluZyB3cmFwcGVycyBsaWtlCisgICAgICogRE9NLCBpdCBpcyBuZWNlc3NhcnkgdG8ga2VlcCB0aGUgbmFtZXNwYWNlIGRhdGEgYXJvdW5kLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGtlZXBOYW1lc3BhY2VBdHRyaWJ1dGVzKCkgeworICAgICAgICB0aGlzLmtlZXBOYW1lc3BhY2VBdHRyaWJ1dGVzID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gYWRqdXN0TnNwKCkgdGhyb3dzIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworICAgICAgICBib29sZWFuIGFueSA9IGZhbHNlOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXR0cmlidXRlQ291bnQgPDwgMjsgaSArPSA0KSB7CisgICAgICAgICAgICBTdHJpbmcgYXR0ck5hbWUgPSBhdHRyaWJ1dGVzW2kgKyAyXTsKKyAgICAgICAgICAgIGludCBjdXQgPSBhdHRyTmFtZS5pbmRleE9mKCc6Jyk7CisgICAgICAgICAgICBTdHJpbmcgcHJlZml4OworCisgICAgICAgICAgICBpZiAoY3V0ICE9IC0xKSB7CisgICAgICAgICAgICAgICAgcHJlZml4ID0gYXR0ck5hbWUuc3Vic3RyaW5nKDAsIGN1dCk7CisgICAgICAgICAgICAgICAgYXR0ck5hbWUgPSBhdHRyTmFtZS5zdWJzdHJpbmcoY3V0ICsgMSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGF0dHJOYW1lLmVxdWFscygieG1sbnMiKSkgeworICAgICAgICAgICAgICAgIHByZWZpeCA9IGF0dHJOYW1lOworICAgICAgICAgICAgICAgIGF0dHJOYW1lID0gbnVsbDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICghcHJlZml4LmVxdWFscygieG1sbnMiKSkgeworICAgICAgICAgICAgICAgIGFueSA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGludCBqID0gKG5zcENvdW50c1tkZXB0aF0rKykgPDwgMTsKKworICAgICAgICAgICAgICAgIG5zcFN0YWNrID0gZW5zdXJlQ2FwYWNpdHkobnNwU3RhY2ssIGogKyAyKTsKKyAgICAgICAgICAgICAgICBuc3BTdGFja1tqXSA9IGF0dHJOYW1lOworICAgICAgICAgICAgICAgIG5zcFN0YWNrW2ogKyAxXSA9IGF0dHJpYnV0ZXNbaSArIDNdOworCisgICAgICAgICAgICAgICAgaWYgKGF0dHJOYW1lICE9IG51bGwgJiYgYXR0cmlidXRlc1tpICsgM10uaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgICAgIGNoZWNrUmVsYXhlZCgiaWxsZWdhbCBlbXB0eSBuYW1lc3BhY2UiKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBpZiAoa2VlcE5hbWVzcGFjZUF0dHJpYnV0ZXMpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gZXhwbGljaXRseSBzZXQgdGhlIG5hbWVzcGFjZSBmb3IgdW5wcmVmaXhlZCBhdHRyaWJ1dGVzCisgICAgICAgICAgICAgICAgICAgIC8vIHN1Y2ggYXMgeG1sbnM9Imh0dHA6Ly9mb28iCisgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNbaV0gPSAiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iOworICAgICAgICAgICAgICAgICAgICBhbnkgPSB0cnVlOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpICsgNCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCgtLWF0dHJpYnV0ZUNvdW50KSA8PCAyKSAtIGkpOworCisgICAgICAgICAgICAgICAgICAgIGkgLT0gNDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoYW55KSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gKGF0dHJpYnV0ZUNvdW50IDw8IDIpIC0gNDsgaSA+PSAwOyBpIC09IDQpIHsKKworICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyTmFtZSA9IGF0dHJpYnV0ZXNbaSArIDJdOworICAgICAgICAgICAgICAgIGludCBjdXQgPSBhdHRyTmFtZS5pbmRleE9mKCc6Jyk7CisKKyAgICAgICAgICAgICAgICBpZiAoY3V0ID09IDAgJiYgIXJlbGF4ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgImlsbGVnYWwgYXR0cmlidXRlIG5hbWU6ICIgKyBhdHRyTmFtZSArICIgYXQgIiArIHRoaXMpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY3V0ICE9IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyUHJlZml4ID0gYXR0ck5hbWUuc3Vic3RyaW5nKDAsIGN1dCk7CisKKyAgICAgICAgICAgICAgICAgICAgYXR0ck5hbWUgPSBhdHRyTmFtZS5zdWJzdHJpbmcoY3V0ICsgMSk7CisKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF0dHJOcyA9IGdldE5hbWVzcGFjZShhdHRyUHJlZml4KTsKKworICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ck5zID09IG51bGwgJiYgIXJlbGF4ZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5kZWZpbmVkIFByZWZpeDogIiArIGF0dHJQcmVmaXggKyAiIGluICIgKyB0aGlzKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNbaV0gPSBhdHRyTnM7CisgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNbaSArIDFdID0gYXR0clByZWZpeDsKKyAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlc1tpICsgMl0gPSBhdHRyTmFtZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpbnQgY3V0ID0gbmFtZS5pbmRleE9mKCc6Jyk7CisKKyAgICAgICAgaWYgKGN1dCA9PSAwKSB7CisgICAgICAgICAgICBjaGVja1JlbGF4ZWQoImlsbGVnYWwgdGFnIG5hbWU6ICIgKyBuYW1lKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjdXQgIT0gLTEpIHsKKyAgICAgICAgICAgIHByZWZpeCA9IG5hbWUuc3Vic3RyaW5nKDAsIGN1dCk7CisgICAgICAgICAgICBuYW1lID0gbmFtZS5zdWJzdHJpbmcoY3V0ICsgMSk7CisgICAgICAgIH0KKworICAgICAgICB0aGlzLm5hbWVzcGFjZSA9IGdldE5hbWVzcGFjZShwcmVmaXgpOworCisgICAgICAgIGlmICh0aGlzLm5hbWVzcGFjZSA9PSBudWxsKSB7CisgICAgICAgICAgICBpZiAocHJlZml4ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBjaGVja1JlbGF4ZWQoInVuZGVmaW5lZCBwcmVmaXg6ICIgKyBwcmVmaXgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy5uYW1lc3BhY2UgPSBOT19OQU1FU1BBQ0U7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYW55OworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nW10gZW5zdXJlQ2FwYWNpdHkoU3RyaW5nW10gYXJyLCBpbnQgcmVxdWlyZWQpIHsKKyAgICAgICAgaWYgKGFyci5sZW5ndGggPj0gcmVxdWlyZWQpIHsKKyAgICAgICAgICAgIHJldHVybiBhcnI7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nW10gYmlnZ2VyID0gbmV3IFN0cmluZ1tyZXF1aXJlZCArIDE2XTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShhcnIsIDAsIGJpZ2dlciwgMCwgYXJyLmxlbmd0aCk7CisgICAgICAgIHJldHVybiBiaWdnZXI7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrUmVsYXhlZChTdHJpbmcgZXJyb3JNZXNzYWdlKSB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmICghcmVsYXhlZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFhtbFB1bGxQYXJzZXJFeGNlcHRpb24oZXJyb3JNZXNzYWdlLCB0aGlzLCBudWxsKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZXJyb3IgPT0gbnVsbCkgeworICAgICAgICAgICAgZXJyb3IgPSAiRXJyb3I6ICIgKyBlcnJvck1lc3NhZ2U7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgaW50IG5leHQoKSB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV4dChmYWxzZSk7CisgICAgfQorCisgICAgcHVibGljIGludCBuZXh0VG9rZW4oKSB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV4dCh0cnVlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBuZXh0KGJvb2xlYW4ganVzdE9uZVRva2VuKSB0aHJvd3MgSU9FeGNlcHRpb24sIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworICAgICAgICBpZiAocmVhZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uKCJzZXRJbnB1dCgpIG11c3QgYmUgY2FsbGVkIGZpcnN0LiIsIHRoaXMsIG51bGwpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHR5cGUgPT0gRU5EX1RBRykgeworICAgICAgICAgICAgZGVwdGgtLTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGRlZ2VuZXJhdGVkIG5lZWRzIHRvIGJlIGhhbmRsZWQgYmVmb3JlIGVycm9yIGJlY2F1c2Ugb2YgcG9zc2libGUKKyAgICAgICAgLy8gcHJvY2Vzc29yIGV4cGVjdGF0aW9ucyghKQorCisgICAgICAgIGlmIChkZWdlbmVyYXRlZCkgeworICAgICAgICAgICAgZGVnZW5lcmF0ZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIHR5cGUgPSBFTkRfVEFHOworICAgICAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZXJyb3IgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKGp1c3RPbmVUb2tlbikgeworICAgICAgICAgICAgICAgIHRleHQgPSBlcnJvcjsKKyAgICAgICAgICAgICAgICB0eXBlID0gQ09NTUVOVDsKKyAgICAgICAgICAgICAgICBlcnJvciA9IG51bGw7CisgICAgICAgICAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGVycm9yID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHR5cGUgPSBwZWVrVHlwZShmYWxzZSk7CisKKyAgICAgICAgaWYgKHR5cGUgPT0gWE1MX0RFQ0xBUkFUSU9OKSB7CisgICAgICAgICAgICByZWFkWG1sRGVjbGFyYXRpb24oKTsKKyAgICAgICAgICAgIHR5cGUgPSBwZWVrVHlwZShmYWxzZSk7CisgICAgICAgIH0KKworICAgICAgICB0ZXh0ID0gbnVsbDsKKyAgICAgICAgaXNXaGl0ZXNwYWNlID0gdHJ1ZTsKKyAgICAgICAgcHJlZml4ID0gbnVsbDsKKyAgICAgICAgbmFtZSA9IG51bGw7CisgICAgICAgIG5hbWVzcGFjZSA9IG51bGw7CisgICAgICAgIGF0dHJpYnV0ZUNvdW50ID0gLTE7CisgICAgICAgIGJvb2xlYW4gdGhyb3dPblJlc29sdmVGYWlsdXJlID0gIWp1c3RPbmVUb2tlbjsKKworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgc3dpdGNoICh0eXBlKSB7CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBSZXR1cm4gaW1tZWRpYXRlbHkgYWZ0ZXIgZW5jb3VudGVyaW5nIGEgc3RhcnQgdGFnLCBlbmQgdGFnLCBvcgorICAgICAgICAgICAgICogdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGNhc2UgU1RBUlRfVEFHOgorICAgICAgICAgICAgICAgIHBhcnNlU3RhcnRUYWcoZmFsc2UsIHRocm93T25SZXNvbHZlRmFpbHVyZSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgICAgICAgICBjYXNlIEVORF9UQUc6CisgICAgICAgICAgICAgICAgcmVhZEVuZFRhZygpOworICAgICAgICAgICAgICAgIHJldHVybiB0eXBlOworICAgICAgICAgICAgY2FzZSBFTkRfRE9DVU1FTlQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIHR5cGU7CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBSZXR1cm4gYWZ0ZXIgYW55IHRleHQgdG9rZW4gd2hlbiB3ZSdyZSBsb29raW5nIGZvciBhIHNpbmdsZQorICAgICAgICAgICAgICogdG9rZW4uIE90aGVyd2lzZSBjb25jYXRlbmF0ZSBhbGwgdGV4dCBiZXR3ZWVuIHRhZ3MuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGNhc2UgRU5USVRZX1JFRjoKKyAgICAgICAgICAgICAgICBpZiAoanVzdE9uZVRva2VuKSB7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgZW50aXR5VGV4dEJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICAgICAgICAgICAgICByZWFkRW50aXR5KGVudGl0eVRleHRCdWlsZGVyLCB0cnVlLCB0aHJvd09uUmVzb2x2ZUZhaWx1cmUsIFZhbHVlQ29udGV4dC5URVhUKTsKKyAgICAgICAgICAgICAgICAgICAgdGV4dCA9IGVudGl0eVRleHRCdWlsZGVyLnRvU3RyaW5nKCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvLyBmYWxsLXRocm91Z2gKKyAgICAgICAgICAgIGNhc2UgVEVYVDoKKyAgICAgICAgICAgICAgICB0ZXh0ID0gcmVhZFZhbHVlKCc8JywgIWp1c3RPbmVUb2tlbiwgdGhyb3dPblJlc29sdmVGYWlsdXJlLCBWYWx1ZUNvbnRleHQuVEVYVCk7CisgICAgICAgICAgICAgICAgaWYgKGRlcHRoID09IDAgJiYgaXNXaGl0ZXNwYWNlKSB7CisgICAgICAgICAgICAgICAgICAgIHR5cGUgPSBJR05PUkFCTEVfV0hJVEVTUEFDRTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIENEU0VDVDoKKyAgICAgICAgICAgICAgICByZWFkKFNUQVJUX0NEQVRBKTsKKyAgICAgICAgICAgICAgICB0ZXh0ID0gcmVhZFVudGlsKEVORF9DREFUQSwgdHJ1ZSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBDb21tZW50cywgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgYW5kIGRlY2xhcmF0aW9ucyBhcmUgcmV0dXJuZWQKKyAgICAgICAgICAgICAqIHdoZW4gd2UncmUgbG9va2luZyBmb3IgYSBzaW5nbGUgdG9rZW4uIE90aGVyd2lzZSB0aGV5J3JlIHNraXBwZWQuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGNhc2UgQ09NTUVOVDoKKyAgICAgICAgICAgICAgICBTdHJpbmcgY29tbWVudFRleHQgPSByZWFkQ29tbWVudChqdXN0T25lVG9rZW4pOworICAgICAgICAgICAgICAgIGlmIChqdXN0T25lVG9rZW4pIHsKKyAgICAgICAgICAgICAgICAgICAgdGV4dCA9IGNvbW1lbnRUZXh0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgUFJPQ0VTU0lOR19JTlNUUlVDVElPTjoKKyAgICAgICAgICAgICAgICByZWFkKFNUQVJUX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04pOworICAgICAgICAgICAgICAgIFN0cmluZyBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gPSByZWFkVW50aWwoRU5EX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04sIGp1c3RPbmVUb2tlbik7CisgICAgICAgICAgICAgICAgaWYgKGp1c3RPbmVUb2tlbikgeworICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gcHJvY2Vzc2luZ0luc3RydWN0aW9uOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgRE9DREVDTDoKKyAgICAgICAgICAgICAgICByZWFkRG9jdHlwZShqdXN0T25lVG9rZW4pOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uKCJVbmV4cGVjdGVkIHRva2VuIiwgdGhpcywgbnVsbCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChkZXB0aCA9PSAwICYmICh0eXBlID09IEVOVElUWV9SRUYgfHwgdHlwZSA9PSBURVhUIHx8IHR5cGUgPT0gQ0RTRUNUKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uKCJVbmV4cGVjdGVkIHRva2VuIiwgdGhpcywgbnVsbCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChqdXN0T25lVG9rZW4pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHlwZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHR5cGUgPT0gSUdOT1JBQkxFX1dISVRFU1BBQ0UpIHsKKyAgICAgICAgICAgICAgICB0ZXh0ID0gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFdlJ3ZlIHJlYWQgYWxsIHRoYXQgd2UgY2FuIG9mIGEgbm9uLWVtcHR5IHRleHQgYmxvY2suIEFsd2F5cworICAgICAgICAgICAgICogcmVwb3J0IHRoaXMgYXMgdGV4dCwgZXZlbiBpZiBpdCB3YXMgYSBDREFUQSBibG9jayBvciBlbnRpdHkKKyAgICAgICAgICAgICAqIHJlZmVyZW5jZS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaW50IHBlZWsgPSBwZWVrVHlwZShmYWxzZSk7CisgICAgICAgICAgICBpZiAodGV4dCAhPSBudWxsICYmICF0ZXh0LmlzRW1wdHkoKSAmJiBwZWVrIDwgVEVYVCkgeworICAgICAgICAgICAgICAgIHR5cGUgPSBURVhUOworICAgICAgICAgICAgICAgIHJldHVybiB0eXBlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0eXBlID0gcGVlazsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHRleHQgdW50aWwgdGhlIHNwZWNpZmllZCBkZWxpbWl0ZXIgaXMgZW5jb3VudGVyZWQuIENvbnN1bWVzIHRoZQorICAgICAqIHRleHQgYW5kIHRoZSBkZWxpbWl0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmV0dXJuVGV4dCB0cnVlIHRvIHJldHVybiB0aGUgcmVhZCB0ZXh0IGV4Y2x1ZGluZyB0aGUgZGVsaW1pdGVyOworICAgICAqICAgICBmYWxzZSB0byByZXR1cm4gbnVsbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyByZWFkVW50aWwoY2hhcltdIGRlbGltaXRlciwgYm9vbGVhbiByZXR1cm5UZXh0KQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHN0YXJ0ID0gcG9zaXRpb247CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbnVsbDsKKworICAgICAgICBpZiAocmV0dXJuVGV4dCAmJiB0ZXh0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHRleHQpOworICAgICAgICB9CisKKyAgICAgICAgc2VhcmNoOgorICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgaWYgKHBvc2l0aW9uICsgZGVsaW1pdGVyLmxlbmd0aCA+PSBsaW1pdCkgeworICAgICAgICAgICAgICAgIGlmIChzdGFydCA8IHBvc2l0aW9uICYmIHJldHVyblRleHQpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyLCBzdGFydCwgcG9zaXRpb24gLSBzdGFydCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICghZmlsbEJ1ZmZlcihkZWxpbWl0ZXIubGVuZ3RoKSkgeworICAgICAgICAgICAgICAgICAgICBjaGVja1JlbGF4ZWQoVU5FWFBFQ1RFRF9FT0YpOworICAgICAgICAgICAgICAgICAgICB0eXBlID0gQ09NTUVOVDsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHN0YXJ0ID0gcG9zaXRpb247CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIFRPRE86IHJlcGxhY2Ugd2l0aCBBcnJheXMuZXF1YWxzKGJ1ZmZlciwgcG9zaXRpb24sIGRlbGltaXRlciwgMCwgZGVsaW1pdGVyLmxlbmd0aCkKKyAgICAgICAgICAgIC8vIHdoZW4gdGhlIFZNIGhhcyBiZXR0ZXIgbWV0aG9kIGlubGluaW5nCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlbGltaXRlci5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIGlmIChidWZmZXJbcG9zaXRpb24gKyBpXSAhPSBkZWxpbWl0ZXJbaV0pIHsKKyAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24rKzsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWUgc2VhcmNoOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgICAgICBpbnQgZW5kID0gcG9zaXRpb247CisgICAgICAgIHBvc2l0aW9uICs9IGRlbGltaXRlci5sZW5ndGg7CisKKyAgICAgICAgaWYgKCFyZXR1cm5UZXh0KSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHN0cmluZ1Bvb2wuZ2V0KGJ1ZmZlciwgc3RhcnQsIGVuZCAtIHN0YXJ0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoYnVmZmVyLCBzdGFydCwgZW5kIC0gc3RhcnQpOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0cnVlIGlmIGFuIFhNTCBkZWNsYXJhdGlvbiB3YXMgcmVhZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZFhtbERlY2xhcmF0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGJ1ZmZlclN0YXJ0TGluZSAhPSAwIHx8IGJ1ZmZlclN0YXJ0Q29sdW1uICE9IDAgfHwgcG9zaXRpb24gIT0gMCkgeworICAgICAgICAgICAgY2hlY2tSZWxheGVkKCJwcm9jZXNzaW5nIGluc3RydWN0aW9ucyBtdXN0IG5vdCBzdGFydCB3aXRoIHhtbCIpOworICAgICAgICB9CisKKyAgICAgICAgcmVhZChTVEFSVF9QUk9DRVNTSU5HX0lOU1RSVUNUSU9OKTsKKyAgICAgICAgcGFyc2VTdGFydFRhZyh0cnVlLCB0cnVlKTsKKworICAgICAgICBpZiAoYXR0cmlidXRlQ291bnQgPCAxIHx8ICEidmVyc2lvbiIuZXF1YWxzKGF0dHJpYnV0ZXNbMl0pKSB7CisgICAgICAgICAgICBjaGVja1JlbGF4ZWQoInZlcnNpb24gZXhwZWN0ZWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIHZlcnNpb24gPSBhdHRyaWJ1dGVzWzNdOworCisgICAgICAgIGludCBwb3MgPSAxOworCisgICAgICAgIGlmIChwb3MgPCBhdHRyaWJ1dGVDb3VudCAmJiAiZW5jb2RpbmciLmVxdWFscyhhdHRyaWJ1dGVzWzIgKyA0XSkpIHsKKyAgICAgICAgICAgIGVuY29kaW5nID0gYXR0cmlidXRlc1szICsgNF07CisgICAgICAgICAgICBwb3MrKzsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChwb3MgPCBhdHRyaWJ1dGVDb3VudCAmJiAic3RhbmRhbG9uZSIuZXF1YWxzKGF0dHJpYnV0ZXNbNCAqIHBvcyArIDJdKSkgeworICAgICAgICAgICAgU3RyaW5nIHN0ID0gYXR0cmlidXRlc1szICsgNCAqIHBvc107CisgICAgICAgICAgICBpZiAoInllcyIuZXF1YWxzKHN0KSkgeworICAgICAgICAgICAgICAgIHN0YW5kYWxvbmUgPSBCb29sZWFuLlRSVUU7CisgICAgICAgICAgICB9IGVsc2UgaWYgKCJubyIuZXF1YWxzKHN0KSkgeworICAgICAgICAgICAgICAgIHN0YW5kYWxvbmUgPSBCb29sZWFuLkZBTFNFOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBjaGVja1JlbGF4ZWQoImlsbGVnYWwgc3RhbmRhbG9uZSB2YWx1ZTogIiArIHN0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBvcysrOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHBvcyAhPSBhdHRyaWJ1dGVDb3VudCkgeworICAgICAgICAgICAgY2hlY2tSZWxheGVkKCJ1bmV4cGVjdGVkIGF0dHJpYnV0ZXMgaW4gWE1MIGRlY2xhcmF0aW9uIik7CisgICAgICAgIH0KKworICAgICAgICBpc1doaXRlc3BhY2UgPSB0cnVlOworICAgICAgICB0ZXh0ID0gbnVsbDsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyByZWFkQ29tbWVudChib29sZWFuIHJldHVyblRleHQpIHRocm93cyBJT0V4Y2VwdGlvbiwgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiB7CisgICAgICAgIHJlYWQoU1RBUlRfQ09NTUVOVCk7CisKKyAgICAgICAgaWYgKHJlbGF4ZWQpIHsKKyAgICAgICAgICAgIHJldHVybiByZWFkVW50aWwoRU5EX0NPTU1FTlQsIHJldHVyblRleHQpOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGNvbW1lbnRUZXh0ID0gcmVhZFVudGlsKENPTU1FTlRfRE9VQkxFX0RBU0gsIHJldHVyblRleHQpOworICAgICAgICBpZiAocGVla0NoYXJhY3RlcigpICE9ICc+JykgeworICAgICAgICAgICAgdGhyb3cgbmV3IFhtbFB1bGxQYXJzZXJFeGNlcHRpb24oIkNvbW1lbnRzIG1heSBub3QgY29udGFpbiAtLSIsIHRoaXMsIG51bGwpOworICAgICAgICB9CisgICAgICAgIHBvc2l0aW9uKys7CisgICAgICAgIHJldHVybiBjb21tZW50VGV4dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIHRoZSBkb2N1bWVudCdzIERURC4gQWx0aG91Z2ggdGhpcyBwYXJzZXIgaXMgbm9uLXZhbGlkYXRpbmcsIHRoZSBEVEQKKyAgICAgKiBtdXN0IGJlIHBhcnNlZCB0byBjYXB0dXJlIGVudGl0eSB2YWx1ZXMgYW5kIGRlZmF1bHQgYXR0cmlidXRlIHZhbHVlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZERvY3R5cGUoYm9vbGVhbiBzYXZlRHRkVGV4dCkgdGhyb3dzIElPRXhjZXB0aW9uLCBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKyAgICAgICAgcmVhZChTVEFSVF9ET0NUWVBFKTsKKworICAgICAgICBpbnQgc3RhcnRQb3NpdGlvbiA9IC0xOworICAgICAgICBpZiAoc2F2ZUR0ZFRleHQpIHsKKyAgICAgICAgICAgIGJ1ZmZlckNhcHR1cmUgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICAgICAgc3RhcnRQb3NpdGlvbiA9IHBvc2l0aW9uOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBza2lwKCk7CisgICAgICAgICAgICByb290RWxlbWVudE5hbWUgPSByZWFkTmFtZSgpOworICAgICAgICAgICAgcmVhZEV4dGVybmFsSWQodHJ1ZSwgdHJ1ZSk7CisgICAgICAgICAgICBza2lwKCk7CisgICAgICAgICAgICBpZiAocGVla0NoYXJhY3RlcigpID09ICdbJykgeworICAgICAgICAgICAgICAgIHJlYWRJbnRlcm5hbFN1YnNldCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2tpcCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHNhdmVEdGRUZXh0KSB7CisgICAgICAgICAgICAgICAgYnVmZmVyQ2FwdHVyZS5hcHBlbmQoYnVmZmVyLCAwLCBwb3NpdGlvbik7CisgICAgICAgICAgICAgICAgYnVmZmVyQ2FwdHVyZS5kZWxldGUoMCwgc3RhcnRQb3NpdGlvbik7CisgICAgICAgICAgICAgICAgdGV4dCA9IGJ1ZmZlckNhcHR1cmUudG9TdHJpbmcoKTsKKyAgICAgICAgICAgICAgICBidWZmZXJDYXB0dXJlID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJlYWQoJz4nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhbiBleHRlcm5hbCBJRCBvZiBvbmUgb2YgdGhlc2UgdHdvIGZvcm1zOgorICAgICAqICAgU1lTVEVNICJxdW90ZWQgc3lzdGVtIG5hbWUiCisgICAgICogICBQVUJMSUMgInF1b3RlZCBwdWJsaWMgaWQiICJxdW90ZWQgc3lzdGVtIG5hbWUiCisgICAgICoKKyAgICAgKiBJZiB0aGUgc3lzdGVtIG5hbWUgaXMgbm90IHJlcXVpcmVkLCB0aGlzIGFsc28gc3VwcG9ydHMgbG9uZSBwdWJsaWMgSURzIG9mCisgICAgICogdGhpcyBmb3JtOgorICAgICAqICAgUFVCTElDICJxdW90ZWQgcHVibGljIGlkIgorICAgICAqCisgICAgICogUmV0dXJucyB0cnVlIGlmIGFueSBJRCB3YXMgcmVhZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gcmVhZEV4dGVybmFsSWQoYm9vbGVhbiByZXF1aXJlU3lzdGVtTmFtZSwgYm9vbGVhbiBhc3NpZ25GaWVsZHMpCisgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworICAgICAgICBza2lwKCk7CisgICAgICAgIGludCBjID0gcGVla0NoYXJhY3RlcigpOworCisgICAgICAgIGlmIChjID09ICdTJykgeworICAgICAgICAgICAgcmVhZChTWVNURU0pOworICAgICAgICB9IGVsc2UgaWYgKGMgPT0gJ1AnKSB7CisgICAgICAgICAgICByZWFkKFBVQkxJQyk7CisgICAgICAgICAgICBza2lwKCk7CisgICAgICAgICAgICBpZiAoYXNzaWduRmllbGRzKSB7CisgICAgICAgICAgICAgICAgcHVibGljSWQgPSByZWFkUXVvdGVkSWQodHJ1ZSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJlYWRRdW90ZWRJZChmYWxzZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBza2lwKCk7CisKKyAgICAgICAgaWYgKCFyZXF1aXJlU3lzdGVtTmFtZSkgeworICAgICAgICAgICAgaW50IGRlbGltaXRlciA9IHBlZWtDaGFyYWN0ZXIoKTsKKyAgICAgICAgICAgIGlmIChkZWxpbWl0ZXIgIT0gJyInICYmIGRlbGltaXRlciAhPSAnXCcnKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7IC8vIG5vIHN5c3RlbSBuYW1lIQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKGFzc2lnbkZpZWxkcykgeworICAgICAgICAgICAgc3lzdGVtSWQgPSByZWFkUXVvdGVkSWQodHJ1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZWFkUXVvdGVkSWQoZmFsc2UpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBTSU5HTEVfUVVPVEUgPSBuZXcgY2hhcltdIHsgJ1wnJyB9OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBET1VCTEVfUVVPVEUgPSBuZXcgY2hhcltdIHsgJyInIH07CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhIHF1b3RlZCBzdHJpbmcsIHBlcmZvcm1pbmcgbm8gZW50aXR5IGVzY2FwaW5nIG9mIHRoZSBjb250ZW50cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyByZWFkUXVvdGVkSWQoYm9vbGVhbiByZXR1cm5UZXh0KSB0aHJvd3MgSU9FeGNlcHRpb24sIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworICAgICAgICBpbnQgcXVvdGUgPSBwZWVrQ2hhcmFjdGVyKCk7CisgICAgICAgIGNoYXJbXSBkZWxpbWl0ZXI7CisgICAgICAgIGlmIChxdW90ZSA9PSAnIicpIHsKKyAgICAgICAgICAgIGRlbGltaXRlciA9IERPVUJMRV9RVU9URTsKKyAgICAgICAgfSBlbHNlIGlmIChxdW90ZSA9PSAnXCcnKSB7CisgICAgICAgICAgICBkZWxpbWl0ZXIgPSBTSU5HTEVfUVVPVEU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbigiRXhwZWN0ZWQgYSBxdW90ZWQgc3RyaW5nIiwgdGhpcywgbnVsbCk7CisgICAgICAgIH0KKyAgICAgICAgcG9zaXRpb24rKzsKKyAgICAgICAgcmV0dXJuIHJlYWRVbnRpbChkZWxpbWl0ZXIsIHJldHVyblRleHQpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkSW50ZXJuYWxTdWJzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24sIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworICAgICAgICByZWFkKCdbJyk7CisKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIHNraXAoKTsKKyAgICAgICAgICAgIGlmIChwZWVrQ2hhcmFjdGVyKCkgPT0gJ10nKSB7CisgICAgICAgICAgICAgICAgcG9zaXRpb24rKzsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGludCBkZWNsYXJhdGlvblR5cGUgPSBwZWVrVHlwZSh0cnVlKTsKKyAgICAgICAgICAgIHN3aXRjaCAoZGVjbGFyYXRpb25UeXBlKSB7CisgICAgICAgICAgICBjYXNlIEVMRU1FTlRERUNMOgorICAgICAgICAgICAgICAgIHJlYWRFbGVtZW50RGVjbGFyYXRpb24oKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBBVFRMSVNUREVDTDoKKyAgICAgICAgICAgICAgICByZWFkQXR0cmlidXRlTGlzdERlY2xhcmF0aW9uKCk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgRU5USVRZREVDTDoKKyAgICAgICAgICAgICAgICByZWFkRW50aXR5RGVjbGFyYXRpb24oKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBOT1RBVElPTkRFQ0w6CisgICAgICAgICAgICAgICAgcmVhZE5vdGF0aW9uRGVjbGFyYXRpb24oKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OOgorICAgICAgICAgICAgICAgIHJlYWQoU1RBUlRfUFJPQ0VTU0lOR19JTlNUUlVDVElPTik7CisgICAgICAgICAgICAgICAgcmVhZFVudGlsKEVORF9QUk9DRVNTSU5HX0lOU1RSVUNUSU9OLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgQ09NTUVOVDoKKyAgICAgICAgICAgICAgICByZWFkQ29tbWVudChmYWxzZSk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgUEFSQU1FVEVSX0VOVElUWV9SRUY6CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhtbFB1bGxQYXJzZXJFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIGVudGl0eSByZWZlcmVuY2VzIGFyZSBub3Qgc3VwcG9ydGVkIiwgdGhpcywgbnVsbCk7CisKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhtbFB1bGxQYXJzZXJFeGNlcHRpb24oIlVuZXhwZWN0ZWQgdG9rZW4iLCB0aGlzLCBudWxsKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgYW4gZWxlbWVudCBkZWNsYXJhdGlvbi4gVGhpcyBjb250YWlucyBhIG5hbWUgYW5kIGEgY29udGVudCBzcGVjLgorICAgICAqICAgPCFFTEVNRU5UIGZvbyBFTVBUWSA+CisgICAgICogICA8IUVMRU1FTlQgZm9vIChiYXI/LChiYXp8cXV1eCkpID4KKyAgICAgKiAgIDwhRUxFTUVOVCBmb28gKCNQQ0RBVEF8YmFyKSogPgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkRWxlbWVudERlY2xhcmF0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKyAgICAgICAgcmVhZChTVEFSVF9FTEVNRU5UKTsKKyAgICAgICAgc2tpcCgpOworICAgICAgICByZWFkTmFtZSgpOworICAgICAgICByZWFkQ29udGVudFNwZWMoKTsKKyAgICAgICAgc2tpcCgpOworICAgICAgICByZWFkKCc+Jyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCBhbiBlbGVtZW50IGNvbnRlbnQgc3BlYy4gVGhpcyBpcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbi1saWtlIHBhdHRlcm4KKyAgICAgKiBvZiBuYW1lcyBvciBvdGhlciBjb250ZW50IHNwZWNzLiBUaGUgZm9sbG93aW5nIG9wZXJhdG9ycyBhcmUgc3VwcG9ydGVkOgorICAgICAqICAgc2VxdWVuY2U6ICAgIChhLGIsYykKKyAgICAgKiAgIGNob2ljZTogICAgICAoYXxifGMpCisgICAgICogICBvcHRpb25hbDogICAgYT8KKyAgICAgKiAgIG9uZSBvciBtb3JlOiBhKworICAgICAqICAgYW55IG51bWJlcjogIGEqCisgICAgICoKKyAgICAgKiBUaGUgc3BlY2lhbCBuYW1lICcjUENEQVRBJyBpcyBwZXJtaXR0ZWQgYnV0IG9ubHkgaWYgaXQgaXMgdGhlIGZpcnN0CisgICAgICogZWxlbWVudCBvZiB0aGUgZmlyc3QgZ3JvdXA6CisgICAgICogICAoI1BDREFUQXxhfGIpCisgICAgICoKKyAgICAgKiBUaGUgdG9wLWxldmVsIGVsZW1lbnQgbXVzdCBiZSBlaXRoZXIgYSBjaG9pY2UsIGEgc2VxdWVuY2UsIG9yIG9uZSBvZiB0aGUKKyAgICAgKiBzcGVjaWFsIG5hbWVzIEVNUFRZIGFuZCBBTlkuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRDb250ZW50U3BlYygpIHRocm93cyBJT0V4Y2VwdGlvbiwgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiB7CisgICAgICAgIC8vIHRoaXMgaW1wbGVtZW50YXRpb24gaXMgdmVyeSBsZW5pZW50OyBpdCBzY2FucyBmb3IgYmFsYW5jZWQgcGFyZW5zIG9ubHkKKyAgICAgICAgc2tpcCgpOworICAgICAgICBpbnQgYyA9IHBlZWtDaGFyYWN0ZXIoKTsKKyAgICAgICAgaWYgKGMgPT0gJygnKSB7CisgICAgICAgICAgICBpbnQgZGVwdGggPSAwOworICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIGlmIChjID09ICcoJykgeworICAgICAgICAgICAgICAgICAgICBkZXB0aCsrOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PSAnKScpIHsKKyAgICAgICAgICAgICAgICAgICAgZGVwdGgtLTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcG9zaXRpb24rKzsKKyAgICAgICAgICAgICAgICBjID0gcGVla0NoYXJhY3RlcigpOworICAgICAgICAgICAgfSB3aGlsZSAoZGVwdGggPiAwKTsKKworICAgICAgICAgICAgaWYgKGMgPT0gJyonIHx8IGMgPT0gJz8nIHx8IGMgPT0gJysnKSB7CisgICAgICAgICAgICAgICAgcG9zaXRpb24rKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChjID09IEVNUFRZWzBdKSB7CisgICAgICAgICAgICByZWFkKEVNUFRZKTsKKyAgICAgICAgfSBlbHNlIGlmIChjID09IEFOWVswXSkgeworICAgICAgICAgICAgcmVhZChBTlkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IFhtbFB1bGxQYXJzZXJFeGNlcHRpb24oIkV4cGVjdGVkIGVsZW1lbnQgY29udGVudCBzcGVjIiwgdGhpcywgbnVsbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhbiBhdHRyaWJ1dGUgbGlzdCBkZWNsYXJhdGlvbiBzdWNoIGFzIHRoZSBmb2xsb3dpbmc6CisgICAgICogICA8IUFUVExJU1QgZm9vCisgICAgICogICAgICAgYmFyIENEQVRBICNJTVBMSUVECisgICAgICogICAgICAgcXV1eCAoYXxifGMpICJjIgorICAgICAqICAgICAgIGJheiBOT1RBVElPTiAoYXxifGMpICNGSVhFRCAiYyI+CisgICAgICoKKyAgICAgKiBFYWNoIGF0dHJpYnV0ZSBoYXMgYSBuYW1lLCB0eXBlIGFuZCBkZWZhdWx0LgorICAgICAqCisgICAgICogVHlwZXMgYXJlIG9uZSBvZiB0aGUgYnVpbHQtaW4gdHlwZXMgKENEQVRBLCBJRCwgSURSRUYsIElEUkVGUywgRU5USVRZLAorICAgICAqIEVOVElUSUVTLCBOTVRPS0VOLCBvciBOTVRPS0VOUyksIGFuIGVudW1lcmF0ZWQgdHlwZSAiKGxpc3R8b2Z8b3B0aW9ucykiCisgICAgICogb3IgTk9UQVRJT04gZm9sbG93ZWQgYnkgYW4gZW51bWVyYXRlZCB0eXBlLgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaXMgZWl0aGVyICNSRVFVSVJFRCwgI0lNUExJRUQsICNGSVhFRCwgYSBxdW90ZWQgdmFsdWUsIG9yCisgICAgICogI0ZJWEVEIHdpdGggYSBxdW90ZWQgdmFsdWUuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHJlYWRBdHRyaWJ1dGVMaXN0RGVjbGFyYXRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24sIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworICAgICAgICByZWFkKFNUQVJUX0FUVExJU1QpOworICAgICAgICBza2lwKCk7CisgICAgICAgIFN0cmluZyBlbGVtZW50TmFtZSA9IHJlYWROYW1lKCk7CisKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIHNraXAoKTsKKyAgICAgICAgICAgIGludCBjID0gcGVla0NoYXJhY3RlcigpOworICAgICAgICAgICAgaWYgKGMgPT0gJz4nKSB7CisgICAgICAgICAgICAgICAgcG9zaXRpb24rKzsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGF0dHJpYnV0ZSBuYW1lCisgICAgICAgICAgICBTdHJpbmcgYXR0cmlidXRlTmFtZSA9IHJlYWROYW1lKCk7CisKKyAgICAgICAgICAgIC8vIGF0dHJpYnV0ZSB0eXBlCisgICAgICAgICAgICBza2lwKCk7CisgICAgICAgICAgICBpZiAocG9zaXRpb24gKyAxID49IGxpbWl0ICYmICFmaWxsQnVmZmVyKDIpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhtbFB1bGxQYXJzZXJFeGNlcHRpb24oIk1hbGZvcm1lZCBhdHRyaWJ1dGUgbGlzdCIsIHRoaXMsIG51bGwpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGJ1ZmZlcltwb3NpdGlvbl0gPT0gTk9UQVRJT05bMF0gJiYgYnVmZmVyW3Bvc2l0aW9uICsgMV0gPT0gTk9UQVRJT05bMV0pIHsKKyAgICAgICAgICAgICAgICByZWFkKE5PVEFUSU9OKTsKKyAgICAgICAgICAgICAgICBza2lwKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjID0gcGVla0NoYXJhY3RlcigpOworICAgICAgICAgICAgaWYgKGMgPT0gJygnKSB7CisgICAgICAgICAgICAgICAgcG9zaXRpb24rKzsKKyAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgICAgICAgICBza2lwKCk7CisgICAgICAgICAgICAgICAgICAgIHJlYWROYW1lKCk7CisgICAgICAgICAgICAgICAgICAgIHNraXAoKTsKKyAgICAgICAgICAgICAgICAgICAgYyA9IHBlZWtDaGFyYWN0ZXIoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT0gJyknKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbisrOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PSAnfCcpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uKys7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbigiTWFsZm9ybWVkIGF0dHJpYnV0ZSB0eXBlIiwgdGhpcywgbnVsbCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJlYWROYW1lKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGRlZmF1bHQgdmFsdWUKKyAgICAgICAgICAgIHNraXAoKTsKKyAgICAgICAgICAgIGMgPSBwZWVrQ2hhcmFjdGVyKCk7CisgICAgICAgICAgICBpZiAoYyA9PSAnIycpIHsKKyAgICAgICAgICAgICAgICBwb3NpdGlvbisrOworICAgICAgICAgICAgICAgIGMgPSBwZWVrQ2hhcmFjdGVyKCk7CisgICAgICAgICAgICAgICAgaWYgKGMgPT0gJ1InKSB7CisgICAgICAgICAgICAgICAgICAgIHJlYWQoUkVRVUlSRUQpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PSAnSScpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVhZChJTVBMSUVEKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGMgPT0gJ0YnKSB7CisgICAgICAgICAgICAgICAgICAgIHJlYWQoRklYRUQpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uKCJNYWxmb3JtZWQgYXR0cmlidXRlIHR5cGUiLCB0aGlzLCBudWxsKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc2tpcCgpOworICAgICAgICAgICAgICAgIGMgPSBwZWVrQ2hhcmFjdGVyKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYyA9PSAnIicgfHwgYyA9PSAnXCcnKSB7CisgICAgICAgICAgICAgICAgcG9zaXRpb24rKzsKKyAgICAgICAgICAgICAgICAvLyBUT0RPOiBkb2VzIHRoaXMgZG8gZXNjYXBpbmcgY29ycmVjdGx5PworICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IHJlYWRWYWx1ZSgoY2hhcikgYywgdHJ1ZSwgdHJ1ZSwgVmFsdWVDb250ZXh0LkFUVFJJQlVURSk7CisgICAgICAgICAgICAgICAgcG9zaXRpb24rKzsKKyAgICAgICAgICAgICAgICBkZWZpbmVBdHRyaWJ1dGVEZWZhdWx0KGVsZW1lbnROYW1lLCBhdHRyaWJ1dGVOYW1lLCB2YWx1ZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZGVmaW5lQXR0cmlidXRlRGVmYXVsdChTdHJpbmcgZWxlbWVudE5hbWUsIFN0cmluZyBhdHRyaWJ1dGVOYW1lLCBTdHJpbmcgdmFsdWUpIHsKKyAgICAgICAgaWYgKGRlZmF1bHRBdHRyaWJ1dGVzID09IG51bGwpIHsKKyAgICAgICAgICAgIGRlZmF1bHRBdHRyaWJ1dGVzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBNYXA8U3RyaW5nLCBTdHJpbmc+PigpOworICAgICAgICB9CisgICAgICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gZWxlbWVudEF0dHJpYnV0ZXMgPSBkZWZhdWx0QXR0cmlidXRlcy5nZXQoZWxlbWVudE5hbWUpOworICAgICAgICBpZiAoZWxlbWVudEF0dHJpYnV0ZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgZWxlbWVudEF0dHJpYnV0ZXMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKKyAgICAgICAgICAgIGRlZmF1bHRBdHRyaWJ1dGVzLnB1dChlbGVtZW50TmFtZSwgZWxlbWVudEF0dHJpYnV0ZXMpOworICAgICAgICB9CisgICAgICAgIGVsZW1lbnRBdHRyaWJ1dGVzLnB1dChhdHRyaWJ1dGVOYW1lLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCBhbiBlbnRpdHkgZGVjbGFyYXRpb24uIFRoZSB2YWx1ZSBvZiBpbnRlcm5hbCBlbnRpdGllcyBhcmUgaW5saW5lOgorICAgICAqICAgPCFFTlRJVFkgZm9vICJiYXIiPgorICAgICAqCisgICAgICogVGhlIHZhbHVlcyBvZiBleHRlcm5hbCBlbnRpdGllcyBtdXN0IGJlIHJldHJpZXZlZCBieSBVUkwgb3IgcGF0aDoKKyAgICAgKiAgIDwhRU5USVRZIGZvbyBTWVNURU0gImh0dHA6Ly9ob3N0L2ZpbGUiPgorICAgICAqICAgPCFFTlRJVFkgZm9vIFBVQkxJQyAiLS8vQW5kcm9pZC8vRm9vLy9FTiIgImh0dHA6Ly9ob3N0L2ZpbGUiPgorICAgICAqICAgPCFFTlRJVFkgZm9vIFNZU1RFTSAiLi4vZmlsZS5wbmciIE5EQVRBIHBuZz4KKyAgICAgKgorICAgICAqIEVudGl0aWVzIG1heSBiZSBnZW5lcmFsIG9yIHBhcmFtZXRlcml6ZWQuIFBhcmFtZXRlcml6ZWQgZW50aXRpZXMgYXJlCisgICAgICogbWFya2VkIGJ5IGEgcGVyY2VudCBzaWduLiBTdWNoIGVudGl0aWVzIG1heSBvbmx5IGJlIHVzZWQgaW4gdGhlIERURDoKKyAgICAgKiAgIDwhRU5USVRZICUgZm9vICJiYXIiPgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkRW50aXR5RGVjbGFyYXRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24sIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworICAgICAgICByZWFkKFNUQVJUX0VOVElUWSk7CisgICAgICAgIGJvb2xlYW4gZ2VuZXJhbEVudGl0eSA9IHRydWU7CisKKyAgICAgICAgc2tpcCgpOworICAgICAgICBpZiAocGVla0NoYXJhY3RlcigpID09ICclJykgeworICAgICAgICAgICAgZ2VuZXJhbEVudGl0eSA9IGZhbHNlOworICAgICAgICAgICAgcG9zaXRpb24rKzsKKyAgICAgICAgICAgIHNraXAoKTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBuYW1lID0gcmVhZE5hbWUoKTsKKworICAgICAgICBza2lwKCk7CisgICAgICAgIGludCBxdW90ZSA9IHBlZWtDaGFyYWN0ZXIoKTsKKyAgICAgICAgU3RyaW5nIGVudGl0eVZhbHVlOworICAgICAgICBpZiAocXVvdGUgPT0gJyInIHx8IHF1b3RlID09ICdcJycpIHsKKyAgICAgICAgICAgIHBvc2l0aW9uKys7CisgICAgICAgICAgICBlbnRpdHlWYWx1ZSA9IHJlYWRWYWx1ZSgoY2hhcikgcXVvdGUsIHRydWUsIGZhbHNlLCBWYWx1ZUNvbnRleHQuRU5USVRZX0RFQ0xBUkFUSU9OKTsKKyAgICAgICAgICAgIHBvc2l0aW9uKys7CisgICAgICAgIH0gZWxzZSBpZiAocmVhZEV4dGVybmFsSWQodHJ1ZSwgZmFsc2UpKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogTWFwIGV4dGVybmFsIGVudGl0aWVzIHRvIHRoZSBlbXB0eSBzdHJpbmcuIFRoaXMgaXMgZGlzaG9uZXN0LAorICAgICAgICAgICAgICogYnV0IGl0J3MgY29uc2lzdGVudCB3aXRoIEFuZHJvaWQncyBFeHBhdCBwdWxsIHBhcnNlci4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgZW50aXR5VmFsdWUgPSAiIjsKKyAgICAgICAgICAgIHNraXAoKTsKKyAgICAgICAgICAgIGlmIChwZWVrQ2hhcmFjdGVyKCkgPT0gTkRBVEFbMF0pIHsKKyAgICAgICAgICAgICAgICByZWFkKE5EQVRBKTsKKyAgICAgICAgICAgICAgICBza2lwKCk7CisgICAgICAgICAgICAgICAgcmVhZE5hbWUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uKCJFeHBlY3RlZCBlbnRpdHkgdmFsdWUgb3IgZXh0ZXJuYWwgSUQiLCB0aGlzLCBudWxsKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChnZW5lcmFsRW50aXR5ICYmIHByb2Nlc3NEb2NEZWNsKSB7CisgICAgICAgICAgICBpZiAoZG9jdW1lbnRFbnRpdGllcyA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgZG9jdW1lbnRFbnRpdGllcyA9IG5ldyBIYXNoTWFwPFN0cmluZywgY2hhcltdPigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZG9jdW1lbnRFbnRpdGllcy5wdXQobmFtZSwgZW50aXR5VmFsdWUudG9DaGFyQXJyYXkoKSk7CisgICAgICAgIH0KKworICAgICAgICBza2lwKCk7CisgICAgICAgIHJlYWQoJz4nKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcmVhZE5vdGF0aW9uRGVjbGFyYXRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24sIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworICAgICAgICByZWFkKFNUQVJUX05PVEFUSU9OKTsKKyAgICAgICAgc2tpcCgpOworICAgICAgICByZWFkTmFtZSgpOworICAgICAgICBpZiAoIXJlYWRFeHRlcm5hbElkKGZhbHNlLCBmYWxzZSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAiRXhwZWN0ZWQgZXh0ZXJuYWwgSUQgb3IgcHVibGljIElEIGZvciBub3RhdGlvbiIsIHRoaXMsIG51bGwpOworICAgICAgICB9CisgICAgICAgIHNraXAoKTsKKyAgICAgICAgcmVhZCgnPicpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkRW5kVGFnKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKyAgICAgICAgcmVhZCgnPCcpOworICAgICAgICByZWFkKCcvJyk7CisgICAgICAgIG5hbWUgPSByZWFkTmFtZSgpOyAvLyBUT0RPOiBwYXNzIHRoZSBleHBlY3RlZCBuYW1lIGluIGFzIGEgaGludD8KKyAgICAgICAgc2tpcCgpOworICAgICAgICByZWFkKCc+Jyk7CisKKyAgICAgICAgaW50IHNwID0gKGRlcHRoIC0gMSkgKiA0OworCisgICAgICAgIGlmIChkZXB0aCA9PSAwKSB7CisgICAgICAgICAgICBjaGVja1JlbGF4ZWQoInJlYWQgZW5kIHRhZyAiICsgbmFtZSArICIgd2l0aCBubyB0YWdzIG9wZW4iKTsKKyAgICAgICAgICAgIHR5cGUgPSBDT01NRU5UOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG5hbWUuZXF1YWxzKGVsZW1lbnRTdGFja1tzcCArIDNdKSkgeworICAgICAgICAgICAgbmFtZXNwYWNlID0gZWxlbWVudFN0YWNrW3NwXTsKKyAgICAgICAgICAgIHByZWZpeCA9IGVsZW1lbnRTdGFja1tzcCArIDFdOworICAgICAgICAgICAgbmFtZSA9IGVsZW1lbnRTdGFja1tzcCArIDJdOworICAgICAgICB9IGVsc2UgaWYgKCFyZWxheGVkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgImV4cGVjdGVkOiAvIiArIGVsZW1lbnRTdGFja1tzcCArIDNdICsgIiByZWFkOiAiICsgbmFtZSwgdGhpcywgbnVsbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIG9mIHRoZSBuZXh0IHRva2VuLgorICAgICAqLworICAgIHByaXZhdGUgaW50IHBlZWtUeXBlKGJvb2xlYW4gaW5EZWNsYXJhdGlvbikgdGhyb3dzIElPRXhjZXB0aW9uLCBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID49IGxpbWl0ICYmICFmaWxsQnVmZmVyKDEpKSB7CisgICAgICAgICAgICByZXR1cm4gRU5EX0RPQ1VNRU5UOworICAgICAgICB9CisKKyAgICAgICAgc3dpdGNoIChidWZmZXJbcG9zaXRpb25dKSB7CisgICAgICAgIGNhc2UgJyYnOgorICAgICAgICAgICAgcmV0dXJuIEVOVElUWV9SRUY7IC8vICYKKyAgICAgICAgY2FzZSAnPCc6CisgICAgICAgICAgICBpZiAocG9zaXRpb24gKyAzID49IGxpbWl0ICYmICFmaWxsQnVmZmVyKDQpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhtbFB1bGxQYXJzZXJFeGNlcHRpb24oIkRhbmdsaW5nIDwiLCB0aGlzLCBudWxsKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc3dpdGNoIChidWZmZXJbcG9zaXRpb24gKyAxXSkgeworICAgICAgICAgICAgY2FzZSAnLyc6CisgICAgICAgICAgICAgICAgcmV0dXJuIEVORF9UQUc7IC8vIDwvCisgICAgICAgICAgICBjYXNlICc/JzoKKyAgICAgICAgICAgICAgICAvLyB3ZSdyZSBsb29raW5nIGZvciAiPD94bWwgIiB3aXRoIGNhc2UgaW5zZW5zaXRpdml0eQorICAgICAgICAgICAgICAgIGlmICgocG9zaXRpb24gKyA1IDwgbGltaXQgfHwgZmlsbEJ1ZmZlcig2KSkKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIChidWZmZXJbcG9zaXRpb24gKyAyXSA9PSAneCcgfHwgYnVmZmVyW3Bvc2l0aW9uICsgMl0gPT0gJ1gnKQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgKGJ1ZmZlcltwb3NpdGlvbiArIDNdID09ICdtJyB8fCBidWZmZXJbcG9zaXRpb24gKyAzXSA9PSAnTScpCisgICAgICAgICAgICAgICAgICAgICAgICAmJiAoYnVmZmVyW3Bvc2l0aW9uICsgNF0gPT0gJ2wnIHx8IGJ1ZmZlcltwb3NpdGlvbiArIDRdID09ICdMJykKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIChidWZmZXJbcG9zaXRpb24gKyA1XSA9PSAnICcpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBYTUxfREVDTEFSQVRJT047IC8vIDw/eG1sCisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFBST0NFU1NJTkdfSU5TVFJVQ1RJT047IC8vIDw/CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgY2FzZSAnISc6CisgICAgICAgICAgICAgICAgc3dpdGNoIChidWZmZXJbcG9zaXRpb24gKyAyXSkgeworICAgICAgICAgICAgICAgIGNhc2UgJ0QnOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gRE9DREVDTDsgLy8gPCFECisgICAgICAgICAgICAgICAgY2FzZSAnWyc6CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBDRFNFQ1Q7IC8vIDwhWworICAgICAgICAgICAgICAgIGNhc2UgJy0nOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ09NTUVOVDsgLy8gPCEtCisgICAgICAgICAgICAgICAgY2FzZSAnRSc6CisgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoYnVmZmVyW3Bvc2l0aW9uICsgM10pIHsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAnTCc6CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRUxFTUVOVERFQ0w7IC8vIDwhRUwKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAnTic6CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRU5USVRZREVDTDsgLy8gPCFFTgorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ0EnOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gQVRUTElTVERFQ0w7ICAvLyA8IUEKKyAgICAgICAgICAgICAgICBjYXNlICdOJzoKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5PVEFUSU9OREVDTDsgLy8gPCFOCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uKCJVbmV4cGVjdGVkIDwhIiwgdGhpcywgbnVsbCk7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIHJldHVybiBTVEFSVF9UQUc7IC8vIDwKKyAgICAgICAgICAgIH0KKyAgICAgICAgY2FzZSAnJSc6CisgICAgICAgICAgICByZXR1cm4gaW5EZWNsYXJhdGlvbiA/IFBBUkFNRVRFUl9FTlRJVFlfUkVGIDogVEVYVDsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHJldHVybiBURVhUOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBuYW1lIGFuZCBhdHRyaWJ1dGVzCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHBhcnNlU3RhcnRUYWcoYm9vbGVhbiB4bWxkZWNsLCBib29sZWFuIHRocm93T25SZXNvbHZlRmFpbHVyZSkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiB7CisgICAgICAgIGlmICgheG1sZGVjbCkgeworICAgICAgICAgICAgcmVhZCgnPCcpOworICAgICAgICB9CisgICAgICAgIG5hbWUgPSByZWFkTmFtZSgpOworICAgICAgICBhdHRyaWJ1dGVDb3VudCA9IDA7CisKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIHNraXAoKTsKKworICAgICAgICAgICAgaWYgKHBvc2l0aW9uID49IGxpbWl0ICYmICFmaWxsQnVmZmVyKDEpKSB7CisgICAgICAgICAgICAgICAgY2hlY2tSZWxheGVkKFVORVhQRUNURURfRU9GKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGludCBjID0gYnVmZmVyW3Bvc2l0aW9uXTsKKworICAgICAgICAgICAgaWYgKHhtbGRlY2wpIHsKKyAgICAgICAgICAgICAgICBpZiAoYyA9PSAnPycpIHsKKyAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24rKzsKKyAgICAgICAgICAgICAgICAgICAgcmVhZCgnPicpOworICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAoYyA9PSAnLycpIHsKKyAgICAgICAgICAgICAgICAgICAgZGVnZW5lcmF0ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbisrOworICAgICAgICAgICAgICAgICAgICBza2lwKCk7CisgICAgICAgICAgICAgICAgICAgIHJlYWQoJz4nKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjID09ICc+JykgeworICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbisrOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFN0cmluZyBhdHRyTmFtZSA9IHJlYWROYW1lKCk7CisKKyAgICAgICAgICAgIGludCBpID0gKGF0dHJpYnV0ZUNvdW50KyspICogNDsKKyAgICAgICAgICAgIGF0dHJpYnV0ZXMgPSBlbnN1cmVDYXBhY2l0eShhdHRyaWJ1dGVzLCBpICsgNCk7CisgICAgICAgICAgICBhdHRyaWJ1dGVzW2ldID0gIiI7CisgICAgICAgICAgICBhdHRyaWJ1dGVzW2kgKyAxXSA9IG51bGw7CisgICAgICAgICAgICBhdHRyaWJ1dGVzW2kgKyAyXSA9IGF0dHJOYW1lOworCisgICAgICAgICAgICBza2lwKCk7CisgICAgICAgICAgICBpZiAocG9zaXRpb24gPj0gbGltaXQgJiYgIWZpbGxCdWZmZXIoMSkpIHsKKyAgICAgICAgICAgICAgICBjaGVja1JlbGF4ZWQoVU5FWFBFQ1RFRF9FT0YpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGJ1ZmZlcltwb3NpdGlvbl0gPT0gJz0nKSB7CisgICAgICAgICAgICAgICAgcG9zaXRpb24rKzsKKworICAgICAgICAgICAgICAgIHNraXAoKTsKKyAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gPj0gbGltaXQgJiYgIWZpbGxCdWZmZXIoMSkpIHsKKyAgICAgICAgICAgICAgICAgICAgY2hlY2tSZWxheGVkKFVORVhQRUNURURfRU9GKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjaGFyIGRlbGltaXRlciA9IGJ1ZmZlcltwb3NpdGlvbl07CisKKyAgICAgICAgICAgICAgICBpZiAoZGVsaW1pdGVyID09ICdcJycgfHwgZGVsaW1pdGVyID09ICciJykgeworICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbisrOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVsYXhlZCkgeworICAgICAgICAgICAgICAgICAgICBkZWxpbWl0ZXIgPSAnICc7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhtbFB1bGxQYXJzZXJFeGNlcHRpb24oImF0dHIgdmFsdWUgZGVsaW1pdGVyIG1pc3NpbmchIiwgdGhpcywgbnVsbCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgYXR0cmlidXRlc1tpICsgM10gPSByZWFkVmFsdWUoZGVsaW1pdGVyLCB0cnVlLCB0aHJvd09uUmVzb2x2ZUZhaWx1cmUsCisgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZUNvbnRleHQuQVRUUklCVVRFKTsKKworICAgICAgICAgICAgICAgIGlmIChkZWxpbWl0ZXIgIT0gJyAnKSB7CisgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uKys7IC8vIGVuZCBxdW90ZQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAocmVsYXhlZCkgeworICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNbaSArIDNdID0gYXR0ck5hbWU7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGNoZWNrUmVsYXhlZCgiQXR0ci52YWx1ZSBtaXNzaW5nIGYuICIgKyBhdHRyTmFtZSk7CisgICAgICAgICAgICAgICAgYXR0cmlidXRlc1tpICsgM10gPSBhdHRyTmFtZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGludCBzcCA9IGRlcHRoKysgKiA0OworICAgICAgICBlbGVtZW50U3RhY2sgPSBlbnN1cmVDYXBhY2l0eShlbGVtZW50U3RhY2ssIHNwICsgNCk7CisgICAgICAgIGVsZW1lbnRTdGFja1tzcCArIDNdID0gbmFtZTsKKworICAgICAgICBpZiAoZGVwdGggPj0gbnNwQ291bnRzLmxlbmd0aCkgeworICAgICAgICAgICAgaW50W10gYmlnZ2VyID0gbmV3IGludFtkZXB0aCArIDRdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShuc3BDb3VudHMsIDAsIGJpZ2dlciwgMCwgbnNwQ291bnRzLmxlbmd0aCk7CisgICAgICAgICAgICBuc3BDb3VudHMgPSBiaWdnZXI7CisgICAgICAgIH0KKworICAgICAgICBuc3BDb3VudHNbZGVwdGhdID0gbnNwQ291bnRzW2RlcHRoIC0gMV07CisKKyAgICAgICAgaWYgKHByb2Nlc3NOc3ApIHsKKyAgICAgICAgICAgIGFkanVzdE5zcCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbmFtZXNwYWNlID0gIiI7CisgICAgICAgIH0KKworICAgICAgICAvLyBGb3IgY29uc2lzdGVuY3kgd2l0aCBFeHBhdCwgYWRkIGRlZmF1bHQgYXR0cmlidXRlcyBhZnRlciBmaXhpbmcgbmFtZXNwYWNlcy4KKyAgICAgICAgaWYgKGRlZmF1bHRBdHRyaWJ1dGVzICE9IG51bGwpIHsKKyAgICAgICAgICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gZWxlbWVudERlZmF1bHRBdHRyaWJ1dGVzID0gZGVmYXVsdEF0dHJpYnV0ZXMuZ2V0KG5hbWUpOworICAgICAgICAgICAgaWYgKGVsZW1lbnREZWZhdWx0QXR0cmlidXRlcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBTdHJpbmc+IGVudHJ5IDogZWxlbWVudERlZmF1bHRBdHRyaWJ1dGVzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGdldEF0dHJpYnV0ZVZhbHVlKG51bGwsIGVudHJ5LmdldEtleSgpKSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsgLy8gYW4gZXhwbGljaXQgdmFsdWUgb3ZlcnJpZGVzIHRoZSBkZWZhdWx0CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBpbnQgaSA9IChhdHRyaWJ1dGVDb3VudCsrKSAqIDQ7CisgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgPSBlbnN1cmVDYXBhY2l0eShhdHRyaWJ1dGVzLCBpICsgNCk7CisgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNbaV0gPSAiIjsKKyAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlc1tpICsgMV0gPSBudWxsOworICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzW2kgKyAyXSA9IGVudHJ5LmdldEtleSgpOworICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzW2kgKyAzXSA9IGVudHJ5LmdldFZhbHVlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZWxlbWVudFN0YWNrW3NwXSA9IG5hbWVzcGFjZTsKKyAgICAgICAgZWxlbWVudFN0YWNrW3NwICsgMV0gPSBwcmVmaXg7CisgICAgICAgIGVsZW1lbnRTdGFja1tzcCArIDJdID0gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBhbiBlbnRpdHkgcmVmZXJlbmNlIGZyb20gdGhlIGJ1ZmZlciwgcmVzb2x2ZXMgaXQsIGFuZCB3cml0ZXMgdGhlCisgICAgICogcmVzb2x2ZWQgZW50aXR5IHRvIHtAY29kZSBvdXR9LiBJZiB0aGUgZW50aXR5IGNhbm5vdCBiZSByZWFkIG9yIHJlc29sdmVkLAorICAgICAqIHtAY29kZSBvdXR9IHdpbGwgY29udGFpbiB0aGUgcGFydGlhbCBlbnRpdHkgcmVmZXJlbmNlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWFkRW50aXR5KFN0cmluZ0J1aWxkZXIgb3V0LCBib29sZWFuIGlzRW50aXR5VG9rZW4sIGJvb2xlYW4gdGhyb3dPblJlc29sdmVGYWlsdXJlLAorICAgICAgICAgICAgVmFsdWVDb250ZXh0IHZhbHVlQ29udGV4dCkgdGhyb3dzIElPRXhjZXB0aW9uLCBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHN0YXJ0ID0gb3V0Lmxlbmd0aCgpOworCisgICAgICAgIGlmIChidWZmZXJbcG9zaXRpb24rK10gIT0gJyYnKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKKyAgICAgICAgfQorCisgICAgICAgIG91dC5hcHBlbmQoJyYnKTsKKworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgaW50IGMgPSBwZWVrQ2hhcmFjdGVyKCk7CisKKyAgICAgICAgICAgIGlmIChjID09ICc7JykgeworICAgICAgICAgICAgICAgIG91dC5hcHBlbmQoJzsnKTsKKyAgICAgICAgICAgICAgICBwb3NpdGlvbisrOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICB9IGVsc2UgaWYgKGMgPj0gMTI4CisgICAgICAgICAgICAgICAgICAgIHx8IChjID49ICcwJyAmJiBjIDw9ICc5JykKKyAgICAgICAgICAgICAgICAgICAgfHwgKGMgPj0gJ2EnICYmIGMgPD0gJ3onKQorICAgICAgICAgICAgICAgICAgICB8fCAoYyA+PSAnQScgJiYgYyA8PSAnWicpCisgICAgICAgICAgICAgICAgICAgIHx8IGMgPT0gJ18nCisgICAgICAgICAgICAgICAgICAgIHx8IGMgPT0gJy0nCisgICAgICAgICAgICAgICAgICAgIHx8IGMgPT0gJyMnKSB7CisgICAgICAgICAgICAgICAgcG9zaXRpb24rKzsKKyAgICAgICAgICAgICAgICBvdXQuYXBwZW5kKChjaGFyKSBjKTsKKworICAgICAgICAgICAgfSBlbHNlIGlmIChyZWxheGVkKSB7CisgICAgICAgICAgICAgICAgLy8gaW50ZW50aW9uYWxseSBsZWF2ZSB0aGUgcGFydGlhbCByZWZlcmVuY2UgaW4gJ291dCcKKyAgICAgICAgICAgICAgICByZXR1cm47CisKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhtbFB1bGxQYXJzZXJFeGNlcHRpb24oInVudGVybWluYXRlZCBlbnRpdHkgcmVmIiwgdGhpcywgbnVsbCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgY29kZSA9IG91dC5zdWJzdHJpbmcoc3RhcnQgKyAxLCBvdXQubGVuZ3RoKCkgLSAxKTsKKworICAgICAgICBpZiAoaXNFbnRpdHlUb2tlbikgeworICAgICAgICAgICAgbmFtZSA9IGNvZGU7CisgICAgICAgIH0KKworICAgICAgICBpZiAoY29kZS5zdGFydHNXaXRoKCIjIikpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaW50IGMgPSBjb2RlLnN0YXJ0c1dpdGgoIiN4IikKKyAgICAgICAgICAgICAgICAgICAgICAgID8gSW50ZWdlci5wYXJzZUludChjb2RlLnN1YnN0cmluZygyKSwgMTYpCisgICAgICAgICAgICAgICAgICAgICAgICA6IEludGVnZXIucGFyc2VJbnQoY29kZS5zdWJzdHJpbmcoMSkpOworICAgICAgICAgICAgICAgIG91dC5kZWxldGUoc3RhcnQsIG91dC5sZW5ndGgoKSk7CisgICAgICAgICAgICAgICAgb3V0LmFwcGVuZENvZGVQb2ludChjKTsKKyAgICAgICAgICAgICAgICB1bnJlc29sdmVkID0gZmFsc2U7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIG5vdEFOdW1iZXIpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbigiSW52YWxpZCBjaGFyYWN0ZXIgcmVmZXJlbmNlOiAmIiArIGNvZGUpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGludmFsaWRDb2RlUG9pbnQpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbigiSW52YWxpZCBjaGFyYWN0ZXIgcmVmZXJlbmNlOiAmIiArIGNvZGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKHZhbHVlQ29udGV4dCA9PSBWYWx1ZUNvbnRleHQuRU5USVRZX0RFQ0xBUkFUSU9OKSB7CisgICAgICAgICAgICAvLyBrZWVwIHRoZSB1bnJlc29sdmVkICZjb2RlOyBpbiB0aGUgdGV4dCB0byByZXNvbHZlIGxhdGVyCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmcgZGVmYXVsdEVudGl0eSA9IERFRkFVTFRfRU5USVRJRVMuZ2V0KGNvZGUpOworICAgICAgICBpZiAoZGVmYXVsdEVudGl0eSAhPSBudWxsKSB7CisgICAgICAgICAgICBvdXQuZGVsZXRlKHN0YXJ0LCBvdXQubGVuZ3RoKCkpOworICAgICAgICAgICAgdW5yZXNvbHZlZCA9IGZhbHNlOworICAgICAgICAgICAgb3V0LmFwcGVuZChkZWZhdWx0RW50aXR5KTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGNoYXJbXSByZXNvbHZlZDsKKyAgICAgICAgaWYgKGRvY3VtZW50RW50aXRpZXMgIT0gbnVsbCAmJiAocmVzb2x2ZWQgPSBkb2N1bWVudEVudGl0aWVzLmdldChjb2RlKSkgIT0gbnVsbCkgeworICAgICAgICAgICAgb3V0LmRlbGV0ZShzdGFydCwgb3V0Lmxlbmd0aCgpKTsKKyAgICAgICAgICAgIHVucmVzb2x2ZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIGlmIChwcm9jZXNzRG9jRGVjbCkgeworICAgICAgICAgICAgICAgIHB1c2hDb250ZW50U291cmNlKHJlc29sdmVkKTsgLy8gcGFyc2UgdGhlIGVudGl0eSBhcyBYTUwKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgb3V0LmFwcGVuZChyZXNvbHZlZCk7IC8vIGluY2x1ZGUgdGhlIGVudGl0eSB2YWx1ZSBhcyB0ZXh0CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICAvKgorICAgICAgICAgKiBUaGUgcGFyc2VyIHNraXBwZWQgYW4gZXh0ZXJuYWwgRFRELCBhbmQgbm93IHdlJ3ZlIGVuY291bnRlcmVkIGFuCisgICAgICAgICAqIHVua25vd24gZW50aXR5IHRoYXQgY291bGQgaGF2ZSBiZWVuIGRlY2xhcmVkIHRoZXJlLiBNYXAgaXQgdG8gdGhlCisgICAgICAgICAqIGVtcHR5IHN0cmluZy4gVGhpcyBpcyBkaXNob25lc3QsIGJ1dCBpdCdzIGNvbnNpc3RlbnQgd2l0aCBBbmRyb2lkJ3MKKyAgICAgICAgICogb2xkIEV4cGF0UHVsbFBhcnNlci4KKyAgICAgICAgICovCisgICAgICAgIGlmIChzeXN0ZW1JZCAhPSBudWxsKSB7CisgICAgICAgICAgICBvdXQuZGVsZXRlKHN0YXJ0LCBvdXQubGVuZ3RoKCkpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLy8ga2VlcCB0aGUgdW5yZXNvbHZlZCBlbnRpdHkgIiZjb2RlOyIgaW4gdGhlIHRleHQgZm9yIHJlbGF4ZWQgY2xpZW50cworICAgICAgICB1bnJlc29sdmVkID0gdHJ1ZTsKKyAgICAgICAgaWYgKHRocm93T25SZXNvbHZlRmFpbHVyZSkgeworICAgICAgICAgICAgY2hlY2tSZWxheGVkKCJ1bnJlc29sdmVkOiAmIiArIGNvZGUgKyAiOyIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogV2hlcmUgYSB2YWx1ZSBpcyBmb3VuZCBpbXBhY3RzIGhvdyB0aGF0IHZhbHVlIGlzIGludGVycHJldGVkLiBGb3IKKyAgICAgKiBleGFtcGxlLCBpbiBhdHRyaWJ1dGVzLCAiXG4iIG11c3QgYmUgcmVwbGFjZWQgd2l0aCBhIHNwYWNlIGNoYXJhY3Rlci4gSW4KKyAgICAgKiB0ZXh0LCAiXV0+IiBpcyBmb3JiaWRkZW4uIEluIGVudGl0eSBkZWNsYXJhdGlvbnMsIG5hbWVkIHJlZmVyZW5jZXMgYXJlCisgICAgICogbm90IHJlc29sdmVkLgorICAgICAqLworICAgIGVudW0gVmFsdWVDb250ZXh0IHsKKyAgICAgICAgQVRUUklCVVRFLAorICAgICAgICBURVhULAorICAgICAgICBFTlRJVFlfREVDTEFSQVRJT04KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHRleHQgb3IgYXR0cmlidXRlIHZhbHVlLiBUaGlzIGFsc28gaGFzIHRoZSBzaWRlCisgICAgICogZWZmZWN0IG9mIHNldHRpbmcgaXNXaGl0ZXNwYWNlIHRvIGZhbHNlIGlmIGEgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVyIGlzCisgICAgICogZW5jb3VudGVyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGVsaW1pdGVyIHtAY29kZSA8fSBmb3IgdGV4dCwge0Bjb2RlICJ9IGFuZCB7QGNvZGUgJ30gZm9yIHF1b3RlZAorICAgICAqICAgICBhdHRyaWJ1dGVzLCBvciBhIHNwYWNlIGZvciB1bnF1b3RlZCBhdHRyaWJ1dGVzLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHJlYWRWYWx1ZShjaGFyIGRlbGltaXRlciwgYm9vbGVhbiByZXNvbHZlRW50aXRpZXMsIGJvb2xlYW4gdGhyb3dPblJlc29sdmVGYWlsdXJlLAorICAgICAgICAgICAgVmFsdWVDb250ZXh0IHZhbHVlQ29udGV4dCkgdGhyb3dzIElPRXhjZXB0aW9uLCBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKworICAgICAgICAvKgorICAgICAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIGFsbCBvZiB0aGUgY2hhcmFjdGVycyBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uCisgICAgICAgICAqIHRocm91Z2ggdG8gYW4gYXBwcm9wcmlhdGUgZGVsaW1pdGVyLgorICAgICAgICAgKgorICAgICAgICAgKiBJZiB3ZSdyZSBsdWNreSAod2hpY2ggd2UgdXN1YWxseSBhcmUpLCB3ZSdsbCByZXR1cm4gYSBzaW5nbGUgc2xpY2Ugb2YKKyAgICAgICAgICogdGhlIGJ1ZmZlci4gVGhpcyBmYXN0IHBhdGggYXZvaWRzIGFsbG9jYXRpbmcgYSBzdHJpbmcgYnVpbGRlci4KKyAgICAgICAgICoKKyAgICAgICAgICogVGhlcmUgYXJlIDYgdW5sdWNreSBjaGFyYWN0ZXJzIHdlIGNvdWxkIGVuY291bnRlcjoKKyAgICAgICAgICogIC0gIiYiOiAgZW50aXRpZXMgbXVzdCBiZSByZXNvbHZlZC4KKyAgICAgICAgICogIC0gIiUiOiAgcGFyYW1ldGVyIGVudGl0aWVzIGFyZSB1bnN1cHBvcnRlZCBpbiBlbnRpdHkgdmFsdWVzLgorICAgICAgICAgKiAgLSAiPCI6ICB0aGlzIGlzbid0IHBlcm1pdHRlZCBpbiBhdHRyaWJ1dGVzIHVubGVzcyByZWxheGVkLgorICAgICAgICAgKiAgLSAiXSI6ICB0aGlzIHJlcXVpcmVzIGEgbG9va2FoZWFkIHRvIGRlZmVuZCBhZ2FpbnN0IHRoZSBmb3JiaWRkZW4KKyAgICAgICAgICogICAgICAgICAgQ0RBVEEgc2VjdGlvbiBkZWxpbWl0ZXIgIl1dPiIuCisgICAgICAgICAqICAtICJcciI6IElmIGEgIlxyIiBpcyBmb2xsb3dlZCBieSBhICJcbiIsIHdlIGRpc2NhcmQgdGhlICJcciIuIElmIGl0CisgICAgICAgICAqICAgICAgICAgIGlzbid0IGZvbGxvd2VkIGJ5ICJcbiIsIHdlIHJlcGxhY2UgIlxyIiB3aXRoIGVpdGhlciBhICJcbiIKKyAgICAgICAgICogICAgICAgICAgaW4gdGV4dCBub2RlcyBvciBhIHNwYWNlIGluIGF0dHJpYnV0ZSB2YWx1ZXMuCisgICAgICAgICAqICAtICJcbiI6IEluIGF0dHJpYnV0ZSB2YWx1ZXMsICJcbiIgbXVzdCBiZSByZXBsYWNlZCB3aXRoIGEgc3BhY2UuCisgICAgICAgICAqCisgICAgICAgICAqIFdlIGNvdWxkIGFsc28gZ2V0IHVubHVja3kgYnkgbmVlZGluZyB0byByZWZpbGwgdGhlIGJ1ZmZlciBtaWR3YXkKKyAgICAgICAgICogdGhyb3VnaCB0aGUgdGV4dC4KKyAgICAgICAgICovCisKKyAgICAgICAgaW50IHN0YXJ0ID0gcG9zaXRpb247CisgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbnVsbDsKKworICAgICAgICAvLyBpZiBhIHRleHQgc2VjdGlvbiB3YXMgYWxyZWFkeSBzdGFydGVkLCBwcmVmaXggdGhlIHN0YXJ0CisgICAgICAgIGlmICh2YWx1ZUNvbnRleHQgPT0gVmFsdWVDb250ZXh0LlRFWFQgJiYgdGV4dCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCh0ZXh0KTsKKyAgICAgICAgfQorCisgICAgICAgIHdoaWxlICh0cnVlKSB7CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBNYWtlIHN1cmUgd2UgaGF2ZSBhdCBsZWFzdCBhIHNpbmdsZSBjaGFyYWN0ZXIgdG8gcmVhZCBmcm9tIHRoZQorICAgICAgICAgICAgICogYnVmZmVyLiBUaGlzIG11dGF0ZXMgdGhlIGJ1ZmZlciwgc28gc2F2ZSB0aGUgcGFydGlhbCByZXN1bHQKKyAgICAgICAgICAgICAqIHRvIHRoZSBzbG93IHBhdGggc3RyaW5nIGJ1aWxkZXIgZmlyc3QuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGlmIChwb3NpdGlvbiA+PSBsaW1pdCkgeworICAgICAgICAgICAgICAgIGlmIChzdGFydCA8IHBvc2l0aW9uKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlciwgc3RhcnQsIHBvc2l0aW9uIC0gc3RhcnQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoIWZpbGxCdWZmZXIoMSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCAhPSBudWxsID8gcmVzdWx0LnRvU3RyaW5nKCkgOiAiIjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc3RhcnQgPSBwb3NpdGlvbjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY2hhciBjID0gYnVmZmVyW3Bvc2l0aW9uXTsKKworICAgICAgICAgICAgaWYgKGMgPT0gZGVsaW1pdGVyCisgICAgICAgICAgICAgICAgICAgIHx8IChkZWxpbWl0ZXIgPT0gJyAnICYmIChjIDw9ICcgJyB8fCBjID09ICc+JykpCisgICAgICAgICAgICAgICAgICAgIHx8IGMgPT0gJyYnICYmICFyZXNvbHZlRW50aXRpZXMpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKGMgIT0gJ1xyJworICAgICAgICAgICAgICAgICAgICAmJiAoYyAhPSAnXG4nIHx8IHZhbHVlQ29udGV4dCAhPSBWYWx1ZUNvbnRleHQuQVRUUklCVVRFKQorICAgICAgICAgICAgICAgICAgICAmJiBjICE9ICcmJworICAgICAgICAgICAgICAgICAgICAmJiBjICE9ICc8JworICAgICAgICAgICAgICAgICAgICAmJiAoYyAhPSAnXScgfHwgdmFsdWVDb250ZXh0ICE9IFZhbHVlQ29udGV4dC5URVhUKQorICAgICAgICAgICAgICAgICAgICAmJiAoYyAhPSAnJScgfHwgdmFsdWVDb250ZXh0ICE9IFZhbHVlQ29udGV4dC5FTlRJVFlfREVDTEFSQVRJT04pKSB7CisgICAgICAgICAgICAgICAgaXNXaGl0ZXNwYWNlICY9IChjIDw9ICcgJyk7CisgICAgICAgICAgICAgICAgcG9zaXRpb24rKzsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFdlJ3ZlIGVuY291bnRlcmVkIGFuIHVubHVja3kgY2hhcmFjdGVyISBDb252ZXJ0IGZyb20gZmFzdAorICAgICAgICAgICAgICogcGF0aCB0byBzbG93IHBhdGggaWYgd2UgaGF2ZW4ndCBkb25lIHNvIGFscmVhZHkuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGJ1ZmZlciwgc3RhcnQsIHBvc2l0aW9uIC0gc3RhcnQpOworCisgICAgICAgICAgICBpZiAoYyA9PSAnXHInKSB7CisgICAgICAgICAgICAgICAgaWYgKChwb3NpdGlvbiArIDEgPCBsaW1pdCB8fCBmaWxsQnVmZmVyKDIpKSAmJiBidWZmZXJbcG9zaXRpb24gKyAxXSA9PSAnXG4nKSB7CisgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGMgPSAodmFsdWVDb250ZXh0ID09IFZhbHVlQ29udGV4dC5BVFRSSUJVVEUpID8gJyAnIDogJ1xuJzsKKworICAgICAgICAgICAgfSBlbHNlIGlmIChjID09ICdcbicpIHsKKyAgICAgICAgICAgICAgICBjID0gJyAnOworCisgICAgICAgICAgICB9IGVsc2UgaWYgKGMgPT0gJyYnKSB7CisgICAgICAgICAgICAgICAgaXNXaGl0ZXNwYWNlID0gZmFsc2U7IC8vIFRPRE86IHdoYXQgaWYgdGhlIGVudGl0eSByZXNvbHZlcyB0byB3aGl0ZXNwYWNlPworICAgICAgICAgICAgICAgIHJlYWRFbnRpdHkocmVzdWx0LCBmYWxzZSwgdGhyb3dPblJlc29sdmVGYWlsdXJlLCB2YWx1ZUNvbnRleHQpOworICAgICAgICAgICAgICAgIHN0YXJ0ID0gcG9zaXRpb247CisgICAgICAgICAgICAgICAgY29udGludWU7CisKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PSAnPCcpIHsKKyAgICAgICAgICAgICAgICBpZiAodmFsdWVDb250ZXh0ID09IFZhbHVlQ29udGV4dC5BVFRSSUJVVEUpIHsKKyAgICAgICAgICAgICAgICAgICAgY2hlY2tSZWxheGVkKCJJbGxlZ2FsOiBcIjxcIiBpbnNpZGUgYXR0cmlidXRlIHZhbHVlIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlzV2hpdGVzcGFjZSA9IGZhbHNlOworCisgICAgICAgICAgICB9IGVsc2UgaWYgKGMgPT0gJ10nKSB7CisgICAgICAgICAgICAgICAgaWYgKChwb3NpdGlvbiArIDIgPCBsaW1pdCB8fCBmaWxsQnVmZmVyKDMpKQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgYnVmZmVyW3Bvc2l0aW9uICsgMV0gPT0gJ10nICYmIGJ1ZmZlcltwb3NpdGlvbiArIDJdID09ICc+JykgeworICAgICAgICAgICAgICAgICAgICBjaGVja1JlbGF4ZWQoIklsbGVnYWw6IFwiXV0+XCIgb3V0c2lkZSBDREFUQSBzZWN0aW9uIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlzV2hpdGVzcGFjZSA9IGZhbHNlOworCisgICAgICAgICAgICB9IGVsc2UgaWYgKGMgPT0gJyUnKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhtbFB1bGxQYXJzZXJFeGNlcHRpb24oIlRoaXMgcGFyc2VyIGRvZXNuJ3Qgc3VwcG9ydCBwYXJhbWV0ZXIgZW50aXRpZXMiLAorICAgICAgICAgICAgICAgICAgICAgICAgdGhpcywgbnVsbCk7CisKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHBvc2l0aW9uKys7CisgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGMpOworICAgICAgICAgICAgc3RhcnQgPSBwb3NpdGlvbjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIHN0cmluZ1Bvb2wuZ2V0KGJ1ZmZlciwgc3RhcnQsIHBvc2l0aW9uIC0gc3RhcnQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChidWZmZXIsIHN0YXJ0LCBwb3NpdGlvbiAtIHN0YXJ0KTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkKGNoYXIgZXhwZWN0ZWQpIHRocm93cyBJT0V4Y2VwdGlvbiwgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiB7CisgICAgICAgIGludCBjID0gcGVla0NoYXJhY3RlcigpOworICAgICAgICBpZiAoYyAhPSBleHBlY3RlZCkgeworICAgICAgICAgICAgY2hlY2tSZWxheGVkKCJleHBlY3RlZDogJyIgKyBleHBlY3RlZCArICInIGFjdHVhbDogJyIgKyAoKGNoYXIpIGMpICsgIiciKTsKKyAgICAgICAgfQorICAgICAgICBwb3NpdGlvbisrOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkKGNoYXJbXSBjaGFycykgdGhyb3dzIElPRXhjZXB0aW9uLCBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uICsgY2hhcnMubGVuZ3RoID49IGxpbWl0ICYmICFmaWxsQnVmZmVyKGNoYXJzLmxlbmd0aCkpIHsKKyAgICAgICAgICAgIGNoZWNrUmVsYXhlZCgiZXhwZWN0ZWQ6ICciICsgbmV3IFN0cmluZyhjaGFycykgKyAiJyBidXQgd2FzIEVPRiIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLy8gVE9ETzogcmVwbGFjZSB3aXRoIEFycmF5cy5lcXVhbHMoYnVmZmVyLCBwb3NpdGlvbiwgZGVsaW1pdGVyLCAwLCBkZWxpbWl0ZXIubGVuZ3RoKQorICAgICAgICAvLyB3aGVuIHRoZSBWTSBoYXMgYmV0dGVyIG1ldGhvZCBpbmxpbmluZworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoYXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYnVmZmVyW3Bvc2l0aW9uICsgaV0gIT0gY2hhcnNbaV0pIHsKKyAgICAgICAgICAgICAgICBjaGVja1JlbGF4ZWQoImV4cGVjdGVkOiBcIiIgKyBuZXcgU3RyaW5nKGNoYXJzKSArICJcIiBidXQgd2FzIFwiIgorICAgICAgICAgICAgICAgICAgICAgICAgKyBuZXcgU3RyaW5nKGJ1ZmZlciwgcG9zaXRpb24sIGNoYXJzLmxlbmd0aCkgKyAiLi4uXCIiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHBvc2l0aW9uICs9IGNoYXJzLmxlbmd0aDsKKyAgICB9CisKKyAgICBwcml2YXRlIGludCBwZWVrQ2hhcmFjdGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uIDwgbGltaXQgfHwgZmlsbEJ1ZmZlcigxKSkgeworICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlcltwb3NpdGlvbl07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBvbmNlIHtAY29kZSBsaW1pdCAtIHBvc2l0aW9uID49IG1pbmltdW19LiBJZiB0aGUgZGF0YSBpcworICAgICAqIGV4aGF1c3RlZCBiZWZvcmUgdGhhdCBtYW55IGNoYXJhY3RlcnMgYXJlIGF2YWlsYWJsZSwgdGhpcyByZXR1cm5zCisgICAgICogZmFsc2UuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGZpbGxCdWZmZXIoaW50IG1pbmltdW0pIHRocm93cyBJT0V4Y2VwdGlvbiwgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiB7CisgICAgICAgIC8vIElmIHdlJ3ZlIGV4aGF1c3RlZCB0aGUgY3VycmVudCBjb250ZW50IHNvdXJjZSwgcmVtb3ZlIGl0CisgICAgICAgIHdoaWxlIChuZXh0Q29udGVudFNvdXJjZSAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAocG9zaXRpb24gPCBsaW1pdCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uKCJVbmJhbGFuY2VkIGVudGl0eSEiLCB0aGlzLCBudWxsKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHBvcENvbnRlbnRTb3VyY2UoKTsKKyAgICAgICAgICAgIGlmIChsaW1pdCAtIHBvc2l0aW9uID49IG1pbmltdW0pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIEJlZm9yZSBjbG9iYmVyaW5nIHRoZSBvbGQgY2hhcmFjdGVycywgdXBkYXRlIHdoZXJlIGJ1ZmZlciBzdGFydHMKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwb3NpdGlvbjsgaSsrKSB7CisgICAgICAgICAgICBpZiAoYnVmZmVyW2ldID09ICdcbicpIHsKKyAgICAgICAgICAgICAgICBidWZmZXJTdGFydExpbmUrKzsKKyAgICAgICAgICAgICAgICBidWZmZXJTdGFydENvbHVtbiA9IDA7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGJ1ZmZlclN0YXJ0Q29sdW1uKys7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoYnVmZmVyQ2FwdHVyZSAhPSBudWxsKSB7CisgICAgICAgICAgICBidWZmZXJDYXB0dXJlLmFwcGVuZChidWZmZXIsIDAsIHBvc2l0aW9uKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChsaW1pdCAhPSBwb3NpdGlvbikgeworICAgICAgICAgICAgbGltaXQgLT0gcG9zaXRpb247CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZmZlciwgcG9zaXRpb24sIGJ1ZmZlciwgMCwgbGltaXQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbGltaXQgPSAwOworICAgICAgICB9CisKKyAgICAgICAgcG9zaXRpb24gPSAwOworICAgICAgICBpbnQgdG90YWw7CisgICAgICAgIHdoaWxlICgodG90YWwgPSByZWFkZXIucmVhZChidWZmZXIsIGxpbWl0LCBidWZmZXIubGVuZ3RoIC0gbGltaXQpKSAhPSAtMSkgeworICAgICAgICAgICAgbGltaXQgKz0gdG90YWw7CisgICAgICAgICAgICBpZiAobGltaXQgPj0gbWluaW11bSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGVsZW1lbnQgb3IgYXR0cmlidXRlIG5hbWUuIFRoaXMgaXMgYWx3YXlzIG5vbi1lbXB0eSBmb3IKKyAgICAgKiBub24tcmVsYXhlZCBwYXJzZXJzLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHJlYWROYW1lKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHBvc2l0aW9uID49IGxpbWl0ICYmICFmaWxsQnVmZmVyKDEpKSB7CisgICAgICAgICAgICBjaGVja1JlbGF4ZWQoIm5hbWUgZXhwZWN0ZWQiKTsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorCisgICAgICAgIGludCBzdGFydCA9IHBvc2l0aW9uOworICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG51bGw7CisKKyAgICAgICAgLy8gcmVhZCB0aGUgZmlyc3QgY2hhcmFjdGVyCisgICAgICAgIGNoYXIgYyA9IGJ1ZmZlcltwb3NpdGlvbl07CisgICAgICAgIGlmICgoYyA+PSAnYScgJiYgYyA8PSAneicpCisgICAgICAgICAgICAgICAgfHwgKGMgPj0gJ0EnICYmIGMgPD0gJ1onKQorICAgICAgICAgICAgICAgIHx8IGMgPT0gJ18nCisgICAgICAgICAgICAgICAgfHwgYyA9PSAnOicKKyAgICAgICAgICAgICAgICB8fCBjID49ICdcdTAwYzAnIC8vIFRPRE86IGNoZWNrIHRoZSBYTUwgc3BlYworICAgICAgICAgICAgICAgIHx8IHJlbGF4ZWQpIHsKKyAgICAgICAgICAgIHBvc2l0aW9uKys7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjaGVja1JlbGF4ZWQoIm5hbWUgZXhwZWN0ZWQiKTsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorCisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogTWFrZSBzdXJlIHdlIGhhdmUgYXQgbGVhc3QgYSBzaW5nbGUgY2hhcmFjdGVyIHRvIHJlYWQgZnJvbSB0aGUKKyAgICAgICAgICAgICAqIGJ1ZmZlci4gVGhpcyBtdXRhdGVzIHRoZSBidWZmZXIsIHNvIHNhdmUgdGhlIHBhcnRpYWwgcmVzdWx0CisgICAgICAgICAgICAgKiB0byB0aGUgc2xvdyBwYXRoIHN0cmluZyBidWlsZGVyIGZpcnN0LgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAocG9zaXRpb24gPj0gbGltaXQpIHsKKyAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChidWZmZXIsIHN0YXJ0LCBwb3NpdGlvbiAtIHN0YXJ0KTsKKyAgICAgICAgICAgICAgICBpZiAoIWZpbGxCdWZmZXIoMSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzdGFydCA9IHBvc2l0aW9uOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyByZWFkIGFub3RoZXIgY2hhcmFjdGVyCisgICAgICAgICAgICBjID0gYnVmZmVyW3Bvc2l0aW9uXTsKKyAgICAgICAgICAgIGlmICgoYyA+PSAnYScgJiYgYyA8PSAneicpCisgICAgICAgICAgICAgICAgICAgIHx8IChjID49ICdBJyAmJiBjIDw9ICdaJykKKyAgICAgICAgICAgICAgICAgICAgfHwgKGMgPj0gJzAnICYmIGMgPD0gJzknKQorICAgICAgICAgICAgICAgICAgICB8fCBjID09ICdfJworICAgICAgICAgICAgICAgICAgICB8fCBjID09ICctJworICAgICAgICAgICAgICAgICAgICB8fCBjID09ICc6JworICAgICAgICAgICAgICAgICAgICB8fCBjID09ICcuJworICAgICAgICAgICAgICAgICAgICB8fCBjID49ICdcdTAwYjcnKSB7ICAvLyBUT0RPOiBjaGVjayB0aGUgWE1MIHNwZWMKKyAgICAgICAgICAgICAgICBwb3NpdGlvbisrOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB3ZSBlbmNvdW50ZXJlZCBhIG5vbi1uYW1lIGNoYXJhY3Rlci4gZG9uZSEKKyAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBzdHJpbmdQb29sLmdldChidWZmZXIsIHN0YXJ0LCBwb3NpdGlvbiAtIHN0YXJ0KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChidWZmZXIsIHN0YXJ0LCBwb3NpdGlvbiAtIHN0YXJ0KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc2tpcCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiB7CisgICAgICAgIHdoaWxlIChwb3NpdGlvbiA8IGxpbWl0IHx8IGZpbGxCdWZmZXIoMSkpIHsKKyAgICAgICAgICAgIGludCBjID0gYnVmZmVyW3Bvc2l0aW9uXTsKKyAgICAgICAgICAgIGlmIChjID4gJyAnKSB7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwb3NpdGlvbisrOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gIHB1YmxpYyBwYXJ0IHN0YXJ0cyBoZXJlLi4uCisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbnB1dChSZWFkZXIgcmVhZGVyKSB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMucmVhZGVyID0gcmVhZGVyOworCisgICAgICAgIHR5cGUgPSBTVEFSVF9ET0NVTUVOVDsKKyAgICAgICAgbmFtZSA9IG51bGw7CisgICAgICAgIG5hbWVzcGFjZSA9IG51bGw7CisgICAgICAgIGRlZ2VuZXJhdGVkID0gZmFsc2U7CisgICAgICAgIGF0dHJpYnV0ZUNvdW50ID0gLTE7CisgICAgICAgIGVuY29kaW5nID0gbnVsbDsKKyAgICAgICAgdmVyc2lvbiA9IG51bGw7CisgICAgICAgIHN0YW5kYWxvbmUgPSBudWxsOworCisgICAgICAgIGlmIChyZWFkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgcG9zaXRpb24gPSAwOworICAgICAgICBsaW1pdCA9IDA7CisgICAgICAgIGJ1ZmZlclN0YXJ0TGluZSA9IDA7CisgICAgICAgIGJ1ZmZlclN0YXJ0Q29sdW1uID0gMDsKKyAgICAgICAgZGVwdGggPSAwOworICAgICAgICBkb2N1bWVudEVudGl0aWVzID0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbnB1dChJbnB1dFN0cmVhbSBpcywgU3RyaW5nIGNoYXJzZXQpIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKyAgICAgICAgcG9zaXRpb24gPSAwOworICAgICAgICBsaW1pdCA9IDA7CisgICAgICAgIGJvb2xlYW4gZGV0ZWN0Q2hhcnNldCA9IChjaGFyc2V0ID09IG51bGwpOworCisgICAgICAgIGlmIChpcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGRldGVjdENoYXJzZXQpIHsKKyAgICAgICAgICAgICAgICAvLyByZWFkIHRoZSBmb3VyIGJ5dGVzIGxvb2tpbmcgZm9yIGFuIGluZGljYXRpb24gb2YgdGhlIGVuY29kaW5nIGluIHVzZQorICAgICAgICAgICAgICAgIGludCBmaXJzdEZvdXJCeXRlcyA9IDA7CisgICAgICAgICAgICAgICAgd2hpbGUgKGxpbWl0IDwgNCkgeworICAgICAgICAgICAgICAgICAgICBpbnQgaSA9IGlzLnJlYWQoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGZpcnN0Rm91ckJ5dGVzID0gKGZpcnN0Rm91ckJ5dGVzIDw8IDgpIHwgaTsKKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyW2xpbWl0KytdID0gKGNoYXIpIGk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGxpbWl0ID09IDQpIHsKKyAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChmaXJzdEZvdXJCeXRlcykgeworICAgICAgICAgICAgICAgICAgICBjYXNlIDB4MDAwMDBGRUZGOiAvLyBVVEYtMzJCRSBCT00KKyAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJzZXQgPSAiVVRGLTMyQkUiOworICAgICAgICAgICAgICAgICAgICAgICAgbGltaXQgPSAwOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAweDBGRkZFMDAwMDogLy8gVVRGLTMyTEUgQk9NCisgICAgICAgICAgICAgICAgICAgICAgICBjaGFyc2V0ID0gIlVURi0zMkxFIjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxpbWl0ID0gMDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICAgICAgICAgIGNhc2UgMHgwMDAwMDAzYzogLy8gJzwnIGluIFVURi0zMkJFCisgICAgICAgICAgICAgICAgICAgICAgICBjaGFyc2V0ID0gIlVURi0zMkJFIjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclswXSA9ICc8JzsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxpbWl0ID0gMTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICAgICAgICAgIGNhc2UgMHgwM2MwMDAwMDA6IC8vICc8JyBpbiBVVEYtMzJMRQorICAgICAgICAgICAgICAgICAgICAgICAgY2hhcnNldCA9ICJVVEYtMzJMRSI7CisgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXJbMF0gPSAnPCc7CisgICAgICAgICAgICAgICAgICAgICAgICBsaW1pdCA9IDE7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICAgICAgICBjYXNlIDB4MDAwM2MwMDNmOiAvLyAiPD8iIGluIFVURi0xNkJFCisgICAgICAgICAgICAgICAgICAgICAgICBjaGFyc2V0ID0gIlVURi0xNkJFIjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclswXSA9ICc8JzsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclsxXSA9ICc/JzsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxpbWl0ID0gMjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICAgICAgICAgIGNhc2UgMHgwM2MwMDNmMDA6IC8vICI8PyIgaW4gVVRGLTE2TEUKKyAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJzZXQgPSAiVVRGLTE2TEUiOworICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyWzBdID0gJzwnOworICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyWzFdID0gJz8nOworICAgICAgICAgICAgICAgICAgICAgICAgbGltaXQgPSAyOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAweDAzYzNmNzg2ZDogLy8gIjw/eG0iIGluIEFTQ0lJIGV0Yy4KKyAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGkgPSBpcy5yZWFkKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlcltsaW1pdCsrXSA9IChjaGFyKSBpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID09ICc+JykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcyA9IG5ldyBTdHJpbmcoYnVmZmVyLCAwLCBsaW1pdCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpMCA9IHMuaW5kZXhPZigiZW5jb2RpbmciKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkwICE9IC0xKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAocy5jaGFyQXQoaTApICE9ICciJyAmJiBzLmNoYXJBdChpMCkgIT0gJ1wnJykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkwKys7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyIGRlbGkgPSBzLmNoYXJBdChpMCsrKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpMSA9IHMuaW5kZXhPZihkZWxpLCBpMCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyc2V0ID0gcy5zdWJzdHJpbmcoaTAsIGkxKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZGxlIGEgYnl0ZSBvcmRlciBtYXJrIGZvbGxvd2VkIGJ5IHNvbWV0aGluZyBvdGhlciB0aGFuIDw/CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGZpcnN0Rm91ckJ5dGVzICYgMHgwZmZmZjAwMDApID09IDB4MGZlZmYwMDAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcnNldCA9ICJVVEYtMTZCRSI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyWzBdID0gKGNoYXIpICgoYnVmZmVyWzJdIDw8IDgpIHwgYnVmZmVyWzNdKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW1pdCA9IDE7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChmaXJzdEZvdXJCeXRlcyAmIDB4MGZmZmYwMDAwKSA9PSAweDBmZmZlMDAwMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJzZXQgPSAiVVRGLTE2TEUiOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclswXSA9IChjaGFyKSAoKGJ1ZmZlclszXSA8PCA4KSB8IGJ1ZmZlclsyXSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGltaXQgPSAxOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoZmlyc3RGb3VyQnl0ZXMgJiAweDBmZmZmZmYwMCkgPT0gMHgwZWZiYmJmMDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyc2V0ID0gIlVURi04IjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXJbMF0gPSBidWZmZXJbM107CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGltaXQgPSAxOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoY2hhcnNldCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgY2hhcnNldCA9ICJVVEYtOCI7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGludCBzYXZlZExpbWl0ID0gbGltaXQ7CisgICAgICAgICAgICBzZXRJbnB1dChuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaXMsIGNoYXJzZXQpKTsKKyAgICAgICAgICAgIGVuY29kaW5nID0gY2hhcnNldDsKKyAgICAgICAgICAgIGxpbWl0ID0gc2F2ZWRMaW1pdDsKKworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFNraXAgdGhlIG9wdGlvbmFsIEJPTSBpZiB3ZSBkaWRuJ3QgYWJvdmUuIFRoaXMgZGVjcmVtZW50cyBsaW1pdAorICAgICAgICAgICAgICogcmF0aGVyIHRoYW4gaW5jcmVtZW50aW5nIHBvc2l0aW9uIHNvIHRoYXQgPD94bWwgdmVyc2lvbj0nMS4wJz8+CisgICAgICAgICAgICAgKiBpcyBzdGlsbCBhdCBjaGFyYWN0ZXIgMC4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaWYgKCFkZXRlY3RDaGFyc2V0ICYmIHBlZWtDaGFyYWN0ZXIoKSA9PSAweGZlZmYpIHsKKyAgICAgICAgICAgICAgICBsaW1pdC0tOworICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCAxLCBidWZmZXIsIDAsIGxpbWl0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uKCJJbnZhbGlkIHN0cmVhbSBvciBlbmNvZGluZzogIiArIGUsIHRoaXMsIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAocmVhZGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlYWRlci5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZSkgeworICAgICAgICBpZiAoWG1sUHVsbFBhcnNlci5GRUFUVVJFX1BST0NFU1NfTkFNRVNQQUNFUy5lcXVhbHMoZmVhdHVyZSkpIHsKKyAgICAgICAgICAgIHJldHVybiBwcm9jZXNzTnNwOworICAgICAgICB9IGVsc2UgaWYgKEZFQVRVUkVfUkVMQVhFRC5lcXVhbHMoZmVhdHVyZSkpIHsKKyAgICAgICAgICAgIHJldHVybiByZWxheGVkOworICAgICAgICB9IGVsc2UgaWYgKEZFQVRVUkVfUFJPQ0VTU19ET0NERUNMLmVxdWFscyhmZWF0dXJlKSkgeworICAgICAgICAgICAgcmV0dXJuIHByb2Nlc3NEb2NEZWNsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRJbnB1dEVuY29kaW5nKCkgeworICAgICAgICByZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZGVmaW5lRW50aXR5UmVwbGFjZW1lbnRUZXh0KFN0cmluZyBlbnRpdHksIFN0cmluZyB2YWx1ZSkKKyAgICAgICAgICAgIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb2Nlc3NEb2NEZWNsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAiRW50aXR5IHJlcGxhY2VtZW50IHRleHQgbWF5IG5vdCBiZSBkZWZpbmVkIHdpdGggRE9DVFlQRSBwcm9jZXNzaW5nIGVuYWJsZWQuIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHJlYWRlciA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAiRW50aXR5IHJlcGxhY2VtZW50IHRleHQgbXVzdCBiZSBkZWZpbmVkIGFmdGVyIHNldElucHV0KCkiKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZG9jdW1lbnRFbnRpdGllcyA9PSBudWxsKSB7CisgICAgICAgICAgICBkb2N1bWVudEVudGl0aWVzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBjaGFyW10+KCk7CisgICAgICAgIH0KKyAgICAgICAgZG9jdW1lbnRFbnRpdGllcy5wdXQoZW50aXR5LCB2YWx1ZS50b0NoYXJBcnJheSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eSkgeworICAgICAgICBpZiAocHJvcGVydHkuZXF1YWxzKFBST1BFUlRZX1hNTERFQ0xfVkVSU0lPTikpIHsKKyAgICAgICAgICAgIHJldHVybiB2ZXJzaW9uOworICAgICAgICB9IGVsc2UgaWYgKHByb3BlcnR5LmVxdWFscyhQUk9QRVJUWV9YTUxERUNMX1NUQU5EQUxPTkUpKSB7CisgICAgICAgICAgICByZXR1cm4gc3RhbmRhbG9uZTsKKyAgICAgICAgfSBlbHNlIGlmIChwcm9wZXJ0eS5lcXVhbHMoUFJPUEVSVFlfTE9DQVRJT04pKSB7CisgICAgICAgICAgICByZXR1cm4gbG9jYXRpb24gIT0gbnVsbCA/IGxvY2F0aW9uIDogcmVhZGVyLnRvU3RyaW5nKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHJvb3QgZWxlbWVudCdzIG5hbWUgaWYgaXQgd2FzIGRlY2xhcmVkIGluIHRoZSBEVEQuIFRoaXMKKyAgICAgKiBlcXVhbHMgdGhlIGZpcnN0IHRhZydzIG5hbWUgZm9yIHZhbGlkIGRvY3VtZW50cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFJvb3RFbGVtZW50TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIHJvb3RFbGVtZW50TmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkb2N1bWVudCdzIHN5c3RlbSBJRCBpZiBpdCB3YXMgZGVjbGFyZWQuIFRoaXMgaXMgdHlwaWNhbGx5IGEKKyAgICAgKiBzdHJpbmcgbGlrZSB7QGNvZGUgaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQvc3RyaWN0LmR0ZH0uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKKyAgICAgICAgcmV0dXJuIHN5c3RlbUlkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRvY3VtZW50J3MgcHVibGljIElEIGlmIGl0IHdhcyBkZWNsYXJlZC4gVGhpcyBpcyB0eXBpY2FsbHkgYQorICAgICAqIHN0cmluZyBsaWtlIHtAY29kZSAtLy9XM0MvL0RURCBIVE1MIDQuMDEvL0VOfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCkgeworICAgICAgICByZXR1cm4gcHVibGljSWQ7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXROYW1lc3BhY2VDb3VudChpbnQgZGVwdGgpIHsKKyAgICAgICAgaWYgKGRlcHRoID4gdGhpcy5kZXB0aCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnNwQ291bnRzW2RlcHRoXTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVByZWZpeChpbnQgcG9zKSB7CisgICAgICAgIHJldHVybiBuc3BTdGFja1twb3MgKiAyXTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVyaShpbnQgcG9zKSB7CisgICAgICAgIHJldHVybiBuc3BTdGFja1socG9zICogMikgKyAxXTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZShTdHJpbmcgcHJlZml4KSB7CisgICAgICAgIGlmICgieG1sIi5lcXVhbHMocHJlZml4KSkgeworICAgICAgICAgICAgcmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiOworICAgICAgICB9CisgICAgICAgIGlmICgieG1sbnMiLmVxdWFscyhwcmVmaXgpKSB7CisgICAgICAgICAgICByZXR1cm4gImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIjsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAoZ2V0TmFtZXNwYWNlQ291bnQoZGVwdGgpIDw8IDEpIC0gMjsgaSA+PSAwOyBpIC09IDIpIHsKKyAgICAgICAgICAgIGlmIChwcmVmaXggPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmIChuc3BTdGFja1tpXSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuc3BTdGFja1tpICsgMV07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmIChwcmVmaXguZXF1YWxzKG5zcFN0YWNrW2ldKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBuc3BTdGFja1tpICsgMV07CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXREZXB0aCgpIHsKKyAgICAgICAgcmV0dXJuIGRlcHRoOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UG9zaXRpb25EZXNjcmlwdGlvbigpIHsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcih0eXBlIDwgVFlQRVMubGVuZ3RoID8gVFlQRVNbdHlwZV0gOiAidW5rbm93biIpOworICAgICAgICBidWYuYXBwZW5kKCcgJyk7CisKKyAgICAgICAgaWYgKHR5cGUgPT0gU1RBUlRfVEFHIHx8IHR5cGUgPT0gRU5EX1RBRykgeworICAgICAgICAgICAgaWYgKGRlZ2VuZXJhdGVkKSB7CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiKGVtcHR5KSAiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJzwnKTsKKyAgICAgICAgICAgIGlmICh0eXBlID09IEVORF9UQUcpIHsKKyAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCcvJyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChwcmVmaXggIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoInsiICsgbmFtZXNwYWNlICsgIn0iICsgcHJlZml4ICsgIjoiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQobmFtZSk7CisKKyAgICAgICAgICAgIGludCBjbnQgPSBhdHRyaWJ1dGVDb3VudCAqIDQ7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNudDsgaSArPSA0KSB7CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnICcpOworICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzW2kgKyAxXSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoInsiICsgYXR0cmlidXRlc1tpXSArICJ9IiArIGF0dHJpYnV0ZXNbaSArIDFdICsgIjoiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChhdHRyaWJ1dGVzW2kgKyAyXSArICI9JyIgKyBhdHRyaWJ1dGVzW2kgKyAzXSArICInIik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJz4nKTsKKyAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IElHTk9SQUJMRV9XSElURVNQQUNFKSB7CisgICAgICAgICAgICA7CisgICAgICAgIH0gZWxzZSBpZiAodHlwZSAhPSBURVhUKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKGdldFRleHQoKSk7CisgICAgICAgIH0gZWxzZSBpZiAoaXNXaGl0ZXNwYWNlKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKCIod2hpdGVzcGFjZSkiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFN0cmluZyB0ZXh0ID0gZ2V0VGV4dCgpOworICAgICAgICAgICAgaWYgKHRleHQubGVuZ3RoKCkgPiAxNikgeworICAgICAgICAgICAgICAgIHRleHQgPSB0ZXh0LnN1YnN0cmluZygwLCAxNikgKyAiLi4uIjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQodGV4dCk7CisgICAgICAgIH0KKworICAgICAgICBidWYuYXBwZW5kKCJAIiArIGdldExpbmVOdW1iZXIoKSArICI6IiArIGdldENvbHVtbk51bWJlcigpKTsKKyAgICAgICAgaWYgKGxvY2F0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIiBpbiAiKTsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQobG9jYXRpb24pOworICAgICAgICB9IGVsc2UgaWYgKHJlYWRlciAhPSBudWxsKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKCIgaW4gIik7CisgICAgICAgICAgICBidWYuYXBwZW5kKHJlYWRlci50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyKCkgeworICAgICAgICBpbnQgcmVzdWx0ID0gYnVmZmVyU3RhcnRMaW5lOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBvc2l0aW9uOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChidWZmZXJbaV0gPT0gJ1xuJykgeworICAgICAgICAgICAgICAgIHJlc3VsdCsrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQgKyAxOyAvLyB0aGUgZmlyc3QgbGluZSBpcyAnMScKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpIHsKKyAgICAgICAgaW50IHJlc3VsdCA9IGJ1ZmZlclN0YXJ0Q29sdW1uOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBvc2l0aW9uOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChidWZmZXJbaV0gPT0gJ1xuJykgeworICAgICAgICAgICAgICAgIHJlc3VsdCA9IDA7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJlc3VsdCsrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiByZXN1bHQgKyAxOyAvLyB0aGUgZmlyc3QgY29sdW1uIGlzICcxJworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzV2hpdGVzcGFjZSgpIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHR5cGUgIT0gVEVYVCAmJiB0eXBlICE9IElHTk9SQUJMRV9XSElURVNQQUNFICYmIHR5cGUgIT0gQ0RTRUNUKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbihJTExFR0FMX1RZUEUsIHRoaXMsIG51bGwpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpc1doaXRlc3BhY2U7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRUZXh0KCkgeworICAgICAgICBpZiAodHlwZSA8IFRFWFQgfHwgKHR5cGUgPT0gRU5USVRZX1JFRiAmJiB1bnJlc29sdmVkKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0gZWxzZSBpZiAodGV4dCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gIiI7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gdGV4dDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBjaGFyW10gZ2V0VGV4dENoYXJhY3RlcnMoaW50W10gcG9zbGVuKSB7CisgICAgICAgIFN0cmluZyB0ZXh0ID0gZ2V0VGV4dCgpOworICAgICAgICBpZiAodGV4dCA9PSBudWxsKSB7CisgICAgICAgICAgICBwb3NsZW5bMF0gPSAtMTsKKyAgICAgICAgICAgIHBvc2xlblsxXSA9IC0xOworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgY2hhcltdIHJlc3VsdCA9IHRleHQudG9DaGFyQXJyYXkoKTsKKyAgICAgICAgcG9zbGVuWzBdID0gMDsKKyAgICAgICAgcG9zbGVuWzFdID0gcmVzdWx0Lmxlbmd0aDsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWVzcGFjZTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KCkgeworICAgICAgICByZXR1cm4gcHJlZml4OworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHlFbGVtZW50VGFnKCkgdGhyb3dzIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworICAgICAgICBpZiAodHlwZSAhPSBTVEFSVF9UQUcpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uKElMTEVHQUxfVFlQRSwgdGhpcywgbnVsbCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRlZ2VuZXJhdGVkOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0QXR0cmlidXRlQ291bnQoKSB7CisgICAgICAgIHJldHVybiBhdHRyaWJ1dGVDb3VudDsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZVR5cGUoaW50IGluZGV4KSB7CisgICAgICAgIHJldHVybiAiQ0RBVEEiOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzQXR0cmlidXRlRGVmYXVsdChpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlTmFtZXNwYWNlKGludCBpbmRleCkgeworICAgICAgICBpZiAoaW5kZXggPj0gYXR0cmlidXRlQ291bnQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXNbaW5kZXggKiA0XTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZU5hbWUoaW50IGluZGV4KSB7CisgICAgICAgIGlmIChpbmRleCA+PSBhdHRyaWJ1dGVDb3VudCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYXR0cmlidXRlc1soaW5kZXggKiA0KSArIDJdOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlUHJlZml4KGludCBpbmRleCkgeworICAgICAgICBpZiAoaW5kZXggPj0gYXR0cmlidXRlQ291bnQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXNbKGluZGV4ICogNCkgKyAxXTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZVZhbHVlKGludCBpbmRleCkgeworICAgICAgICBpZiAoaW5kZXggPj0gYXR0cmlidXRlQ291bnQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXNbKGluZGV4ICogNCkgKyAzXTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZVZhbHVlKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAoYXR0cmlidXRlQ291bnQgKiA0KSAtIDQ7IGkgPj0gMDsgaSAtPSA0KSB7CisgICAgICAgICAgICBpZiAoYXR0cmlidXRlc1tpICsgMl0uZXF1YWxzKG5hbWUpCisgICAgICAgICAgICAgICAgICAgICYmIChuYW1lc3BhY2UgPT0gbnVsbCB8fCBhdHRyaWJ1dGVzW2ldLmVxdWFscyhuYW1lc3BhY2UpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBhdHRyaWJ1dGVzW2kgKyAzXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0RXZlbnRUeXBlKCkgdGhyb3dzIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworICAgICAgICByZXR1cm4gdHlwZTsKKyAgICB9CisKKyAgICAvLyB1dGlsaXR5IG1ldGhvZHMgdG8gbWFrZSBYTUwgcGFyc2luZyBlYXNpZXIgLi4uCisKKyAgICBwdWJsaWMgaW50IG5leHRUYWcoKSB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBuZXh0KCk7CisgICAgICAgIGlmICh0eXBlID09IFRFWFQgJiYgaXNXaGl0ZXNwYWNlKSB7CisgICAgICAgICAgICBuZXh0KCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAodHlwZSAhPSBFTkRfVEFHICYmIHR5cGUgIT0gU1RBUlRfVEFHKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbigidW5leHBlY3RlZCB0eXBlIiwgdGhpcywgbnVsbCk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gdHlwZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZXF1aXJlKGludCB0eXBlLCBTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgbmFtZSkKKyAgICAgICAgICAgIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0eXBlICE9IHRoaXMudHlwZQorICAgICAgICAgICAgICAgIHx8IChuYW1lc3BhY2UgIT0gbnVsbCAmJiAhbmFtZXNwYWNlLmVxdWFscyhnZXROYW1lc3BhY2UoKSkpCisgICAgICAgICAgICAgICAgfHwgKG5hbWUgIT0gbnVsbCAmJiAhbmFtZS5lcXVhbHMoZ2V0TmFtZSgpKSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAiZXhwZWN0ZWQ6ICIgKyBUWVBFU1t0eXBlXSArICIgeyIgKyBuYW1lc3BhY2UgKyAifSIgKyBuYW1lLCB0aGlzLCBudWxsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgbmV4dFRleHQoKSB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodHlwZSAhPSBTVEFSVF9UQUcpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uKCJwcmVjb25kaXRpb246IFNUQVJUX1RBRyIsIHRoaXMsIG51bGwpOworICAgICAgICB9CisKKyAgICAgICAgbmV4dCgpOworCisgICAgICAgIFN0cmluZyByZXN1bHQ7CisgICAgICAgIGlmICh0eXBlID09IFRFWFQpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IGdldFRleHQoKTsKKyAgICAgICAgICAgIG5leHQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlc3VsdCA9ICIiOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHR5cGUgIT0gRU5EX1RBRykgeworICAgICAgICAgICAgdGhyb3cgbmV3IFhtbFB1bGxQYXJzZXJFeGNlcHRpb24oIkVORF9UQUcgZXhwZWN0ZWQiLCB0aGlzLCBudWxsKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZSwgYm9vbGVhbiB2YWx1ZSkgdGhyb3dzIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworICAgICAgICBpZiAoWG1sUHVsbFBhcnNlci5GRUFUVVJFX1BST0NFU1NfTkFNRVNQQUNFUy5lcXVhbHMoZmVhdHVyZSkpIHsKKyAgICAgICAgICAgIHByb2Nlc3NOc3AgPSB2YWx1ZTsKKyAgICAgICAgfSBlbHNlIGlmIChYbWxQdWxsUGFyc2VyLkZFQVRVUkVfUFJPQ0VTU19ET0NERUNMLmVxdWFscyhmZWF0dXJlKSkgeworICAgICAgICAgICAgcHJvY2Vzc0RvY0RlY2wgPSB2YWx1ZTsKKyAgICAgICAgfSBlbHNlIGlmIChGRUFUVVJFX1JFTEFYRUQuZXF1YWxzKGZlYXR1cmUpKSB7CisgICAgICAgICAgICByZWxheGVkID0gdmFsdWU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbigidW5zdXBwb3J0ZWQgZmVhdHVyZTogIiArIGZlYXR1cmUsIHRoaXMsIG51bGwpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5LCBPYmplY3QgdmFsdWUpIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHByb3BlcnR5LmVxdWFscyhQUk9QRVJUWV9MT0NBVElPTikpIHsKKyAgICAgICAgICAgIGxvY2F0aW9uID0gU3RyaW5nLnZhbHVlT2YodmFsdWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IFhtbFB1bGxQYXJzZXJFeGNlcHRpb24oInVuc3VwcG9ydGVkIHByb3BlcnR5OiAiICsgcHJvcGVydHkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBjaGFpbiBvZiBidWZmZXJzIGNvbnRhaW5pbmcgWE1MIGNvbnRlbnQuIEVhY2ggY29udGVudCBzb3VyY2UgY29udGFpbnMKKyAgICAgKiB0aGUgcGFyc2VyJ3MgcHJpbWFyeSByZWFkIGJ1ZmZlciBvciB0aGUgY2hhcmFjdGVycyBvZiBlbnRpdGllcyBhY3RpdmVseQorICAgICAqIGJlaW5nIHBhcnNlZC4KKyAgICAgKgorICAgICAqIDxwPkZvciBleGFtcGxlLCBub3RlIHRoZSBidWZmZXJzIG5lZWRlZCB0byBwYXJzZSB0aGlzIGRvY3VtZW50OgorICAgICAqIDxwcmU+ICAge0Bjb2RlCisgICAgICogICA8IURPQ1RZUEUgZm9vIFsKKyAgICAgKiAgICAgICA8IUVOVElUWSBiYXogImdoaSI+CisgICAgICogICAgICAgPCFFTlRJVFkgYmFyICJkZWYgJmJhejsgamtsIj4KKyAgICAgKiAgIF0+CisgICAgICogICA8Zm9vPmFiYyAmYmFyOyBtbm88L2Zvbz4KKyAgICAgKiB9PC9wcmU+CisgICAgICoKKyAgICAgKiA8cD5UaGluZ3MgZ2V0IGludGVyZXN0aW5nIHdoZW4gdGhlIGJhciBlbnRpdHkgaXMgZW5jb3VudGVyZWQuIEF0IHRoYXQKKyAgICAgKiBwb2ludCB0d28gYnVmZmVycyBhcmUgYWN0aXZlOgorICAgICAqIDxvbD4KKyAgICAgKiA8bGk+VGhlIHZhbHVlIGZvciB0aGUgYmFyIGVudGl0eSwgY29udGFpbmluZyB7QGNvZGUgImRlZiAmYmF6OyBqa2wifQorICAgICAqIDxsaT5UaGUgcGFyc2VyJ3MgcHJpbWFyeSByZWFkIGJ1ZmZlciwgY29udGFpbmluZyB7QGNvZGUgIiBtbm88L2Zvbz4ifQorICAgICAqIDwvb2w+CisgICAgICogPHA+VGhlIHBhcnNlciB3aWxsIHJldHVybiB0aGUgY2hhcmFjdGVycyB7QGNvZGUgImRlZiAifSBmcm9tIHRoZSBiYXIKKyAgICAgKiBlbnRpdHkncyBidWZmZXIsIGFuZCB0aGVuIGl0IHdpbGwgZW5jb3VudGVyIHRoZSBiYXogZW50aXR5LiBUbyBoYW5kbGUKKyAgICAgKiB0aGF0LCB0aHJlZSBidWZmZXJzIHdpbGwgYmUgYWN0aXZlOgorICAgICAqIDxvbD4KKyAgICAgKiA8bGk+VGhlIHZhbHVlIGZvciB0aGUgYmF6IGVudGl0eSwgY29udGFpbmluZyB7QGNvZGUgImdoaSJ9CisgICAgICogPGxpPlRoZSByZW1haW5pbmcgdmFsdWUgZm9yIHRoZSBiYXIgZW50aXR5LCBjb250YWluaW5nIHtAY29kZSAiIGprbCJ9CisgICAgICogPGxpPlRoZSBwYXJzZXIncyBwcmltYXJ5IHJlYWQgYnVmZmVyLCBjb250YWluaW5nIHtAY29kZSAiIG1ubzwvZm9vPiJ9CisgICAgICogPC9vbD4KKyAgICAgKiA8cD5UaGUgcGFyc2VyIHdpbGwgdGhlbiByZXR1cm4gdGhlIGNoYXJhY3RlcnMge0Bjb2RlIGdoaSBqa2wgbW5vfSBpbiB0aGF0CisgICAgICogc2VxdWVuY2UgYnkgcmVhZGluZyBlYWNoIGJ1ZmZlciBpbiBzZXF1ZW5jZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgY2xhc3MgQ29udGVudFNvdXJjZSB7CisgICAgICAgIHByaXZhdGUgZmluYWwgQ29udGVudFNvdXJjZSBuZXh0OworICAgICAgICBwcml2YXRlIGZpbmFsIGNoYXJbXSBidWZmZXI7CisgICAgICAgIHByaXZhdGUgZmluYWwgaW50IHBvc2l0aW9uOworICAgICAgICBwcml2YXRlIGZpbmFsIGludCBsaW1pdDsKKyAgICAgICAgQ29udGVudFNvdXJjZShDb250ZW50U291cmNlIG5leHQsIGNoYXJbXSBidWZmZXIsIGludCBwb3NpdGlvbiwgaW50IGxpbWl0KSB7CisgICAgICAgICAgICB0aGlzLm5leHQgPSBuZXh0OworICAgICAgICAgICAgdGhpcy5idWZmZXIgPSBidWZmZXI7CisgICAgICAgICAgICB0aGlzLnBvc2l0aW9uID0gcG9zaXRpb247CisgICAgICAgICAgICB0aGlzLmxpbWl0ID0gbGltaXQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmVwZW5kcyB0aGUgY2hhcmFjdGVycyBvZiB7QGNvZGUgbmV3QnVmZmVyfSB0byBiZSByZWFkIGJlZm9yZSB0aGUKKyAgICAgKiBjdXJyZW50IGJ1ZmZlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcHVzaENvbnRlbnRTb3VyY2UoY2hhcltdIG5ld0J1ZmZlcikgeworICAgICAgICBuZXh0Q29udGVudFNvdXJjZSA9IG5ldyBDb250ZW50U291cmNlKG5leHRDb250ZW50U291cmNlLCBidWZmZXIsIHBvc2l0aW9uLCBsaW1pdCk7CisgICAgICAgIGJ1ZmZlciA9IG5ld0J1ZmZlcjsKKyAgICAgICAgcG9zaXRpb24gPSAwOworICAgICAgICBsaW1pdCA9IG5ld0J1ZmZlci5sZW5ndGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwbGFjZXMgdGhlIGN1cnJlbnQgZXhoYXVzdGVkIGJ1ZmZlciB3aXRoIHRoZSBuZXh0IGJ1ZmZlciBpbiB0aGUgY2hhaW4uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHBvcENvbnRlbnRTb3VyY2UoKSB7CisgICAgICAgIGJ1ZmZlciA9IG5leHRDb250ZW50U291cmNlLmJ1ZmZlcjsKKyAgICAgICAgcG9zaXRpb24gPSBuZXh0Q29udGVudFNvdXJjZS5wb3NpdGlvbjsKKyAgICAgICAgbGltaXQgPSBuZXh0Q29udGVudFNvdXJjZS5saW1pdDsKKyAgICAgICAgbmV4dENvbnRlbnRTb3VyY2UgPSBuZXh0Q29udGVudFNvdXJjZS5uZXh0OworICAgIH0KK30KZGlmZiAtLWdpdCBhL3htbC9zcmMvbWFpbi9qYXZhL29yZy9reG1sMi9pby9LWG1sU2VyaWFsaXplci5qYXZhIGIveG1sL3NyYy9tYWluL2phdmEvb3JnL2t4bWwyL2lvL0tYbWxTZXJpYWxpemVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDE5NjVkNgotLS0gL2Rldi9udWxsCisrKyBiL3htbC9zcmMvbWFpbi9qYXZhL29yZy9reG1sMi9pby9LWG1sU2VyaWFsaXplci5qYXZhCkBAIC0wLDAgKzEsNTgxIEBACisvKiBDb3B5cmlnaHQgKGMpIDIwMDIsMjAwMywgU3RlZmFuIEhhdXN0ZWluLCBPYmVyaGF1c2VuLCBSaGxkLiwgR2VybWFueQorICoKKyAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKKyAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCisgKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCisgKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vcgorICogc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKKyAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CisgKgorICogVGhlICBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCisgKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KKyAqCisgKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgorICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCisgKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKKyAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKKyAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HCisgKiBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTCisgKiBJTiBUSEUgU09GVFdBUkUuICovCisKKworcGFja2FnZSBvcmcua3htbDIuaW87CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBvcmcueG1scHVsbC52MS4qOworCitwdWJsaWMgY2xhc3MgS1htbFNlcmlhbGl6ZXIgaW1wbGVtZW50cyBYbWxTZXJpYWxpemVyIHsKKworICAgIC8vICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgVU5ERUZJTkVEID0gIjoiOworCisgICAgLy8gQkVHSU4gYW5kcm9pZC1hZGRlZAorICAgIC8qKiBzaXplIChpbiBjaGFyYWN0ZXJzKSBmb3IgdGhlIHdyaXRlIGJ1ZmZlciAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBXUklURV9CVUZGRVJfU0laRSA9IDUwMDsKKyAgICAvLyBFTkQgYW5kcm9pZC1hZGRlZAorCisgICAgLy8gQkVHSU4gYW5kcm9pZC1jaGFuZ2VkCisgICAgLy8gKEd1YXJhbnRlZSB0aGF0IHRoZSB3cml0ZXIgaXMgYWx3YXlzIGJ1ZmZlcmVkLikKKyAgICBwcml2YXRlIEJ1ZmZlcmVkV3JpdGVyIHdyaXRlcjsKKyAgICAvLyBFTkQgYW5kcm9pZC1jaGFuZ2VkCisKKyAgICBwcml2YXRlIGJvb2xlYW4gcGVuZGluZzsKKyAgICBwcml2YXRlIGludCBhdXRvOworICAgIHByaXZhdGUgaW50IGRlcHRoOworCisgICAgcHJpdmF0ZSBTdHJpbmdbXSBlbGVtZW50U3RhY2sgPSBuZXcgU3RyaW5nWzEyXTsKKyAgICAvL25zcC9wcmVmaXgvbmFtZQorICAgIHByaXZhdGUgaW50W10gbnNwQ291bnRzID0gbmV3IGludFs0XTsKKyAgICBwcml2YXRlIFN0cmluZ1tdIG5zcFN0YWNrID0gbmV3IFN0cmluZ1s4XTsKKyAgICAvL3ByZWZpeC9uc3A7IGJvdGggZW1wdHkgYXJlICIiCisgICAgcHJpdmF0ZSBib29sZWFuW10gaW5kZW50ID0gbmV3IGJvb2xlYW5bNF07CisgICAgcHJpdmF0ZSBib29sZWFuIHVuaWNvZGU7CisgICAgcHJpdmF0ZSBTdHJpbmcgZW5jb2Rpbmc7CisKKyAgICBwcml2YXRlIGZpbmFsIHZvaWQgY2hlY2soYm9vbGVhbiBjbG9zZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKCFwZW5kaW5nKQorICAgICAgICAgICAgcmV0dXJuOworCisgICAgICAgIGRlcHRoKys7CisgICAgICAgIHBlbmRpbmcgPSBmYWxzZTsKKworICAgICAgICBpZiAoaW5kZW50Lmxlbmd0aCA8PSBkZXB0aCkgeworICAgICAgICAgICAgYm9vbGVhbltdIGhscCA9IG5ldyBib29sZWFuW2RlcHRoICsgNF07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGluZGVudCwgMCwgaGxwLCAwLCBkZXB0aCk7CisgICAgICAgICAgICBpbmRlbnQgPSBobHA7CisgICAgICAgIH0KKyAgICAgICAgaW5kZW50W2RlcHRoXSA9IGluZGVudFtkZXB0aCAtIDFdOworCisgICAgICAgIGZvciAoaW50IGkgPSBuc3BDb3VudHNbZGVwdGggLSAxXTsgaSA8IG5zcENvdW50c1tkZXB0aF07IGkrKykgeworICAgICAgICAgICAgd3JpdGVyLndyaXRlKCcgJyk7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoInhtbG5zIik7CisgICAgICAgICAgICBpZiAoIW5zcFN0YWNrW2kgKiAyXS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJzonKTsKKyAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUobnNwU3RhY2tbaSAqIDJdKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgaWYgKGdldE5hbWVzcGFjZSgpLmlzRW1wdHkoKSAmJiAhbnNwU3RhY2tbaSAqIDIgKyAxXS5pc0VtcHR5KCkpCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiQ2Fubm90IHNldCBkZWZhdWx0IG5hbWVzcGFjZSBmb3IgZWxlbWVudHMgaW4gbm8gbmFtZXNwYWNlIik7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoIj1cIiIpOworICAgICAgICAgICAgd3JpdGVFc2NhcGVkKG5zcFN0YWNrW2kgKiAyICsgMV0sICciJyk7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoJyInKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChuc3BDb3VudHMubGVuZ3RoIDw9IGRlcHRoICsgMSkgeworICAgICAgICAgICAgaW50W10gaGxwID0gbmV3IGludFtkZXB0aCArIDhdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShuc3BDb3VudHMsIDAsIGhscCwgMCwgZGVwdGggKyAxKTsKKyAgICAgICAgICAgIG5zcENvdW50cyA9IGhscDsKKyAgICAgICAgfQorCisgICAgICAgIG5zcENvdW50c1tkZXB0aCArIDFdID0gbnNwQ291bnRzW2RlcHRoXTsKKyAgICAgICAgLy8gICBuc3BDb3VudHNbZGVwdGggKyAyXSA9IG5zcENvdW50c1tkZXB0aF07CisKKyAgICAgICAgd3JpdGVyLndyaXRlKGNsb3NlID8gIiAvPiIgOiAiPiIpOworICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgdm9pZCB3cml0ZUVzY2FwZWQoU3RyaW5nIHMsIGludCBxdW90KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHMubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgY2hhciBjID0gcy5jaGFyQXQoaSk7CisgICAgICAgICAgICBzd2l0Y2ggKGMpIHsKKyAgICAgICAgICAgICAgICBjYXNlICdcbic6CisgICAgICAgICAgICAgICAgY2FzZSAnXHInOgorICAgICAgICAgICAgICAgIGNhc2UgJ1x0JzoKKyAgICAgICAgICAgICAgICAgICAgaWYocXVvdCA9PSAtMSkKKyAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShjKTsKKyAgICAgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCImIyIrKChpbnQpIGMpKyc7Jyk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJyYnIDoKKyAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCImYW1wOyIpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICc+JyA6CisgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiJmd0OyIpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICc8JyA6CisgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiJmx0OyIpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PSBxdW90KSB7CisgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoYyA9PSAnIicgPyAiJnF1b3Q7IiA6ICImYXBvczsiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZDogcmVmdXNlIHRvIG91dHB1dCBpbnZhbGlkIGNoYXJhY3RlcnMKKyAgICAgICAgICAgICAgICAgICAgLy8gU2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwvI2NoYXJzZXRzIGZvciBkZWZpbml0aW9uLgorICAgICAgICAgICAgICAgICAgICAvLyBObyBvdGhlciBKYXZhIFhNTCB3cml0ZXIgd2Uga25vdyBvZiBkb2VzIHRoaXMsIGJ1dCBubyBKYXZhCisgICAgICAgICAgICAgICAgICAgIC8vIFhNTCByZWFkZXIgd2Uga25vdyBvZiBpcyBhYmxlIHRvIHBhcnNlIHRoZSBiYWQgb3V0cHV0IHdlJ2QKKyAgICAgICAgICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIGdlbmVyYXRlLgorICAgICAgICAgICAgICAgICAgICAvLyBOb3RlOiB0YWIsIG5ld2xpbmUsIGFuZCBjYXJyaWFnZSByZXR1cm4gaGF2ZSBhbHJlYWR5IGJlZW4KKyAgICAgICAgICAgICAgICAgICAgLy8gaGFuZGxlZCBhYm92ZS4KKyAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiB2YWxpZCA9IChjID49IDB4MjAgJiYgYyA8PSAweGQ3ZmYpIHx8IChjID49IDB4ZTAwMCAmJiBjIDw9IDB4ZmZmZCk7CisgICAgICAgICAgICAgICAgICAgIGlmICghdmFsaWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEludmFsaWRDaGFyYWN0ZXIoYyk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKHVuaWNvZGUgfHwgYyA8IDEyNykgeworICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKGMpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCImIyIgKyAoKGludCkgYykgKyAiOyIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIEJFR0lOIGFuZHJvaWQtYWRkZWQKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHJlcG9ydEludmFsaWRDaGFyYWN0ZXIoY2hhciBjaCkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbGxlZ2FsIGNoYXJhY3RlciAoIiArIEludGVnZXIudG9IZXhTdHJpbmcoKGludCkgY2gpICsgIikiKTsKKyAgICB9CisgICAgLy8gRU5EIGFuZHJvaWQtYWRkZWQKKworICAgIC8qCisgICAgICAgIHByaXZhdGUgZmluYWwgdm9pZCB3cml0ZUluZGVudCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoIlxyXG4iKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVwdGg7IGkrKykKKyAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJyAnKTsKKyAgICAgICAgfSovCisKKyAgICBwdWJsaWMgdm9pZCBkb2NkZWNsKFN0cmluZyBkZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGVyLndyaXRlKCI8IURPQ1RZUEUiKTsKKyAgICAgICAgd3JpdGVyLndyaXRlKGRkKTsKKyAgICAgICAgd3JpdGVyLndyaXRlKCI+Iik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB3aGlsZSAoZGVwdGggPiAwKSB7CisgICAgICAgICAgICBlbmRUYWcoZWxlbWVudFN0YWNrW2RlcHRoICogMyAtIDNdLCBlbGVtZW50U3RhY2tbZGVwdGggKiAzIC0gMV0pOworICAgICAgICB9CisgICAgICAgIGZsdXNoKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZW50aXR5UmVmKFN0cmluZyBuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVjayhmYWxzZSk7CisgICAgICAgIHdyaXRlci53cml0ZSgnJicpOworICAgICAgICB3cml0ZXIud3JpdGUobmFtZSk7CisgICAgICAgIHdyaXRlci53cml0ZSgnOycpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgLy9yZXR1cm4gZmFsc2U7CisgICAgICAgIHJldHVybiAoCisgICAgICAgICAgICAiaHR0cDovL3htbHB1bGwub3JnL3YxL2RvYy9mZWF0dXJlcy5odG1sI2luZGVudC1vdXRwdXQiCisgICAgICAgICAgICAgICAgLmVxdWFscygKKyAgICAgICAgICAgICAgICBuYW1lKSkKKyAgICAgICAgICAgID8gaW5kZW50W2RlcHRoXQorICAgICAgICAgICAgOiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeChTdHJpbmcgbmFtZXNwYWNlLCBib29sZWFuIGNyZWF0ZSkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGdldFByZWZpeChuYW1lc3BhY2UsIGZhbHNlLCBjcmVhdGUpOworICAgICAgICB9CisgICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZ2V0UHJlZml4KAorICAgICAgICBTdHJpbmcgbmFtZXNwYWNlLAorICAgICAgICBib29sZWFuIGluY2x1ZGVEZWZhdWx0LAorICAgICAgICBib29sZWFuIGNyZWF0ZSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICBmb3IgKGludCBpID0gbnNwQ291bnRzW2RlcHRoICsgMV0gKiAyIC0gMjsKKyAgICAgICAgICAgIGkgPj0gMDsKKyAgICAgICAgICAgIGkgLT0gMikgeworICAgICAgICAgICAgaWYgKG5zcFN0YWNrW2kgKyAxXS5lcXVhbHMobmFtZXNwYWNlKQorICAgICAgICAgICAgICAgICYmIChpbmNsdWRlRGVmYXVsdCB8fCAhbnNwU3RhY2tbaV0uaXNFbXB0eSgpKSkgeworICAgICAgICAgICAgICAgIFN0cmluZyBjYW5kID0gbnNwU3RhY2tbaV07CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IGkgKyAyOworICAgICAgICAgICAgICAgICAgICBqIDwgbnNwQ291bnRzW2RlcHRoICsgMV0gKiAyOworICAgICAgICAgICAgICAgICAgICBqKyspIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5zcFN0YWNrW2pdLmVxdWFscyhjYW5kKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgY2FuZCA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoY2FuZCAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2FuZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmICghY3JlYXRlKQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisKKyAgICAgICAgU3RyaW5nIHByZWZpeDsKKworICAgICAgICBpZiAobmFtZXNwYWNlLmlzRW1wdHkoKSkKKyAgICAgICAgICAgIHByZWZpeCA9ICIiOworICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICBwcmVmaXggPSAibiIgKyAoYXV0bysrKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gbnNwQ291bnRzW2RlcHRoICsgMV0gKiAyIC0gMjsKKyAgICAgICAgICAgICAgICAgICAgaSA+PSAwOworICAgICAgICAgICAgICAgICAgICBpIC09IDIpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHByZWZpeC5lcXVhbHMobnNwU3RhY2tbaV0pKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBudWxsOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICB3aGlsZSAocHJlZml4ID09IG51bGwpOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiBwID0gcGVuZGluZzsKKyAgICAgICAgcGVuZGluZyA9IGZhbHNlOworICAgICAgICBzZXRQcmVmaXgocHJlZml4LCBuYW1lc3BhY2UpOworICAgICAgICBwZW5kaW5nID0gcDsKKyAgICAgICAgcmV0dXJuIHByZWZpeDsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBuYW1lKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbnN1cHBvcnRlZCBwcm9wZXJ0eSIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoU3RyaW5nIHMpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRleHQocyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkgeworICAgICAgICBpZiAoImh0dHA6Ly94bWxwdWxsLm9yZy92MS9kb2MvZmVhdHVyZXMuaHRtbCNpbmRlbnQtb3V0cHV0IgorICAgICAgICAgICAgLmVxdWFscyhuYW1lKSkgeworICAgICAgICAgICAgaW5kZW50W2RlcHRoXSA9IHZhbHVlOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbnN1cHBvcnRlZCBGZWF0dXJlIik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICJVbnN1cHBvcnRlZCBQcm9wZXJ0eToiICsgdmFsdWUpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFByZWZpeChTdHJpbmcgcHJlZml4LCBTdHJpbmcgbmFtZXNwYWNlKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIGNoZWNrKGZhbHNlKTsKKyAgICAgICAgaWYgKHByZWZpeCA9PSBudWxsKQorICAgICAgICAgICAgcHJlZml4ID0gIiI7CisgICAgICAgIGlmIChuYW1lc3BhY2UgPT0gbnVsbCkKKyAgICAgICAgICAgIG5hbWVzcGFjZSA9ICIiOworCisgICAgICAgIFN0cmluZyBkZWZpbmVkID0gZ2V0UHJlZml4KG5hbWVzcGFjZSwgdHJ1ZSwgZmFsc2UpOworCisgICAgICAgIC8vIGJvaWwgb3V0IGlmIGFscmVhZHkgZGVmaW5lZAorCisgICAgICAgIGlmIChwcmVmaXguZXF1YWxzKGRlZmluZWQpKQorICAgICAgICAgICAgcmV0dXJuOworCisgICAgICAgIGludCBwb3MgPSAobnNwQ291bnRzW2RlcHRoICsgMV0rKykgPDwgMTsKKworICAgICAgICBpZiAobnNwU3RhY2subGVuZ3RoIDwgcG9zICsgMSkgeworICAgICAgICAgICAgU3RyaW5nW10gaGxwID0gbmV3IFN0cmluZ1tuc3BTdGFjay5sZW5ndGggKyAxNl07CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5zcFN0YWNrLCAwLCBobHAsIDAsIHBvcyk7CisgICAgICAgICAgICBuc3BTdGFjayA9IGhscDsKKyAgICAgICAgfQorCisgICAgICAgIG5zcFN0YWNrW3BvcysrXSA9IHByZWZpeDsKKyAgICAgICAgbnNwU3RhY2tbcG9zXSA9IG5hbWVzcGFjZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRPdXRwdXQoV3JpdGVyIHdyaXRlcikgeworICAgICAgICAvLyBCRUdJTiBhbmRyb2lkLWNoYW5nZWQKKyAgICAgICAgLy8gR3VhcmFudGVlIHRoYXQgdGhlIHdyaXRlciBpcyBhbHdheXMgYnVmZmVyZWQuCisgICAgICAgIGlmICh3cml0ZXIgaW5zdGFuY2VvZiBCdWZmZXJlZFdyaXRlcikgeworICAgICAgICAgICAgdGhpcy53cml0ZXIgPSAoQnVmZmVyZWRXcml0ZXIpIHdyaXRlcjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRoaXMud3JpdGVyID0gbmV3IEJ1ZmZlcmVkV3JpdGVyKHdyaXRlciwgV1JJVEVfQlVGRkVSX1NJWkUpOworICAgICAgICB9CisgICAgICAgIC8vIEVORCBhbmRyb2lkLWNoYW5nZWQKKworICAgICAgICAvLyBlbGVtZW50U3RhY2sgPSBuZXcgU3RyaW5nWzEyXTsgLy9uc3AvcHJlZml4L25hbWUKKyAgICAgICAgLy9uc3BDb3VudHMgPSBuZXcgaW50WzRdOworICAgICAgICAvL25zcFN0YWNrID0gbmV3IFN0cmluZ1s4XTsgLy9wcmVmaXgvbnNwCisgICAgICAgIC8vaW5kZW50ID0gbmV3IGJvb2xlYW5bNF07CisKKyAgICAgICAgbnNwQ291bnRzWzBdID0gMjsKKyAgICAgICAgbnNwQ291bnRzWzFdID0gMjsKKyAgICAgICAgbnNwU3RhY2tbMF0gPSAiIjsKKyAgICAgICAgbnNwU3RhY2tbMV0gPSAiIjsKKyAgICAgICAgbnNwU3RhY2tbMl0gPSAieG1sIjsKKyAgICAgICAgbnNwU3RhY2tbM10gPSAiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIjsKKyAgICAgICAgcGVuZGluZyA9IGZhbHNlOworICAgICAgICBhdXRvID0gMDsKKyAgICAgICAgZGVwdGggPSAwOworCisgICAgICAgIHVuaWNvZGUgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRPdXRwdXQoT3V0cHV0U3RyZWFtIG9zLCBTdHJpbmcgZW5jb2RpbmcpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChvcyA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgICAgICBzZXRPdXRwdXQoCisgICAgICAgICAgICBlbmNvZGluZyA9PSBudWxsCisgICAgICAgICAgICAgICAgPyBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG9zKQorICAgICAgICAgICAgICAgIDogbmV3IE91dHB1dFN0cmVhbVdyaXRlcihvcywgZW5jb2RpbmcpKTsKKyAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgICAgICBpZiAoZW5jb2RpbmcgIT0gbnVsbCAmJiBlbmNvZGluZy50b0xvd2VyQ2FzZShMb2NhbGUuVVMpLnN0YXJ0c1dpdGgoInV0ZiIpKSB7CisgICAgICAgICAgICB1bmljb2RlID0gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoU3RyaW5nIGVuY29kaW5nLCBCb29sZWFuIHN0YW5kYWxvbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlci53cml0ZSgiPD94bWwgdmVyc2lvbj0nMS4wJyAiKTsKKworICAgICAgICBpZiAoZW5jb2RpbmcgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgICAgICAgICAgaWYgKGVuY29kaW5nLnRvTG93ZXJDYXNlKExvY2FsZS5VUykuc3RhcnRzV2l0aCgidXRmIikpIHsKKyAgICAgICAgICAgICAgICB1bmljb2RlID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmICh0aGlzLmVuY29kaW5nICE9IG51bGwpIHsKKyAgICAgICAgICAgIHdyaXRlci53cml0ZSgiZW5jb2Rpbmc9JyIpOworICAgICAgICAgICAgd3JpdGVyLndyaXRlKHRoaXMuZW5jb2RpbmcpOworICAgICAgICAgICAgd3JpdGVyLndyaXRlKCInICIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHN0YW5kYWxvbmUgIT0gbnVsbCkgeworICAgICAgICAgICAgd3JpdGVyLndyaXRlKCJzdGFuZGFsb25lPSciKTsKKyAgICAgICAgICAgIHdyaXRlci53cml0ZSgKKyAgICAgICAgICAgICAgICBzdGFuZGFsb25lLmJvb2xlYW5WYWx1ZSgpID8gInllcyIgOiAibm8iKTsKKyAgICAgICAgICAgIHdyaXRlci53cml0ZSgiJyAiKTsKKyAgICAgICAgfQorICAgICAgICB3cml0ZXIud3JpdGUoIj8+Iik7CisgICAgfQorCisgICAgcHVibGljIFhtbFNlcmlhbGl6ZXIgc3RhcnRUYWcoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIG5hbWUpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrKGZhbHNlKTsKKworICAgICAgICAvLyAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBudWxsKQorICAgICAgICAvLyAgICAgICAgICAgIG5hbWVzcGFjZSA9ICIiOworCisgICAgICAgIGlmIChpbmRlbnRbZGVwdGhdKSB7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoIlxyXG4iKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVwdGg7IGkrKykKKyAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIiAgIik7CisgICAgICAgIH0KKworICAgICAgICBpbnQgZXNwID0gZGVwdGggKiAzOworCisgICAgICAgIGlmIChlbGVtZW50U3RhY2subGVuZ3RoIDwgZXNwICsgMykgeworICAgICAgICAgICAgU3RyaW5nW10gaGxwID0gbmV3IFN0cmluZ1tlbGVtZW50U3RhY2subGVuZ3RoICsgMTJdOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShlbGVtZW50U3RhY2ssIDAsIGhscCwgMCwgZXNwKTsKKyAgICAgICAgICAgIGVsZW1lbnRTdGFjayA9IGhscDsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBwcmVmaXggPQorICAgICAgICAgICAgbmFtZXNwYWNlID09IG51bGwKKyAgICAgICAgICAgICAgICA/ICIiCisgICAgICAgICAgICAgICAgOiBnZXRQcmVmaXgobmFtZXNwYWNlLCB0cnVlLCB0cnVlKTsKKworICAgICAgICBpZiAobmFtZXNwYWNlICE9IG51bGwgJiYgbmFtZXNwYWNlLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IG5zcENvdW50c1tkZXB0aF07CisgICAgICAgICAgICAgICAgaSA8IG5zcENvdW50c1tkZXB0aCArIDFdOworICAgICAgICAgICAgICAgIGkrKykgeworICAgICAgICAgICAgICAgIGlmIChuc3BTdGFja1tpICogMl0uaXNFbXB0eSgpICYmICFuc3BTdGFja1tpICogMiArIDFdLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDYW5ub3Qgc2V0IGRlZmF1bHQgbmFtZXNwYWNlIGZvciBlbGVtZW50cyBpbiBubyBuYW1lc3BhY2UiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBlbGVtZW50U3RhY2tbZXNwKytdID0gbmFtZXNwYWNlOworICAgICAgICBlbGVtZW50U3RhY2tbZXNwKytdID0gcHJlZml4OworICAgICAgICBlbGVtZW50U3RhY2tbZXNwXSA9IG5hbWU7CisKKyAgICAgICAgd3JpdGVyLndyaXRlKCc8Jyk7CisgICAgICAgIGlmICghcHJlZml4LmlzRW1wdHkoKSkgeworICAgICAgICAgICAgd3JpdGVyLndyaXRlKHByZWZpeCk7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoJzonKTsKKyAgICAgICAgfQorCisgICAgICAgIHdyaXRlci53cml0ZShuYW1lKTsKKworICAgICAgICBwZW5kaW5nID0gdHJ1ZTsKKworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgWG1sU2VyaWFsaXplciBhdHRyaWJ1dGUoCisgICAgICAgIFN0cmluZyBuYW1lc3BhY2UsCisgICAgICAgIFN0cmluZyBuYW1lLAorICAgICAgICBTdHJpbmcgdmFsdWUpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICghcGVuZGluZykKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oImlsbGVnYWwgcG9zaXRpb24gZm9yIGF0dHJpYnV0ZSIpOworCisgICAgICAgIC8vICAgICAgICBpbnQgY250ID0gbnNwQ291bnRzW2RlcHRoXTsKKworICAgICAgICBpZiAobmFtZXNwYWNlID09IG51bGwpCisgICAgICAgICAgICBuYW1lc3BhY2UgPSAiIjsKKworICAgICAgICAvLyAgICAgICAgZGVwdGgtLTsKKyAgICAgICAgLy8gICAgICAgIHBlbmRpbmcgPSBmYWxzZTsKKworICAgICAgICBTdHJpbmcgcHJlZml4ID0KKyAgICAgICAgICAgIG5hbWVzcGFjZS5pc0VtcHR5KCkKKyAgICAgICAgICAgICAgICA/ICIiCisgICAgICAgICAgICAgICAgOiBnZXRQcmVmaXgobmFtZXNwYWNlLCBmYWxzZSwgdHJ1ZSk7CisKKyAgICAgICAgLy8gICAgICAgIHBlbmRpbmcgPSB0cnVlOworICAgICAgICAvLyAgICAgICAgZGVwdGgrKzsKKworICAgICAgICAvKiAgICAgICAgaWYgKGNudCAhPSBuc3BDb3VudHNbZGVwdGhdKSB7CisgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnICcpOworICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoInhtbG5zIik7CisgICAgICAgICAgICAgICAgICAgIGlmIChuc3BTdGFja1tjbnQgKiAyXSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJzonKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShuc3BTdGFja1tjbnQgKiAyXSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCI9XCIiKTsKKyAgICAgICAgICAgICAgICAgICAgd3JpdGVFc2NhcGVkKG5zcFN0YWNrW2NudCAqIDIgKyAxXSwgJyInKTsKKyAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCciJyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICovCisKKyAgICAgICAgd3JpdGVyLndyaXRlKCcgJyk7CisgICAgICAgIGlmICghcHJlZml4LmlzRW1wdHkoKSkgeworICAgICAgICAgICAgd3JpdGVyLndyaXRlKHByZWZpeCk7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoJzonKTsKKyAgICAgICAgfQorICAgICAgICB3cml0ZXIud3JpdGUobmFtZSk7CisgICAgICAgIHdyaXRlci53cml0ZSgnPScpOworICAgICAgICBjaGFyIHEgPSB2YWx1ZS5pbmRleE9mKCciJykgPT0gLTEgPyAnIicgOiAnXCcnOworICAgICAgICB3cml0ZXIud3JpdGUocSk7CisgICAgICAgIHdyaXRlRXNjYXBlZCh2YWx1ZSwgcSk7CisgICAgICAgIHdyaXRlci53cml0ZShxKTsKKworICAgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrKGZhbHNlKTsKKyAgICAgICAgd3JpdGVyLmZsdXNoKCk7CisgICAgfQorICAgIC8qCisgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGNoZWNrKCk7CisgICAgICAgICAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICAgICAgfQorICAgICovCisgICAgcHVibGljIFhtbFNlcmlhbGl6ZXIgZW5kVGFnKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIGlmICghcGVuZGluZykKKyAgICAgICAgICAgIGRlcHRoLS07CisgICAgICAgIC8vICAgICAgICBpZiAobmFtZXNwYWNlID09IG51bGwpCisgICAgICAgIC8vICAgICAgICAgIG5hbWVzcGFjZSA9ICIiOworCisgICAgICAgIGlmICgobmFtZXNwYWNlID09IG51bGwKKyAgICAgICAgICAgICYmIGVsZW1lbnRTdGFja1tkZXB0aCAqIDNdICE9IG51bGwpCisgICAgICAgICAgICB8fCAobmFtZXNwYWNlICE9IG51bGwKKyAgICAgICAgICAgICAgICAmJiAhbmFtZXNwYWNlLmVxdWFscyhlbGVtZW50U3RhY2tbZGVwdGggKiAzXSkpCisgICAgICAgICAgICB8fCAhZWxlbWVudFN0YWNrW2RlcHRoICogMyArIDJdLmVxdWFscyhuYW1lKSkKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIjwveyIrbmFtZXNwYWNlKyJ9IituYW1lKyI+IGRvZXMgbm90IG1hdGNoIHN0YXJ0Iik7CisKKyAgICAgICAgaWYgKHBlbmRpbmcpIHsKKyAgICAgICAgICAgIGNoZWNrKHRydWUpOworICAgICAgICAgICAgZGVwdGgtLTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGlmIChpbmRlbnRbZGVwdGggKyAxXSkgeworICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiXHJcbiIpOworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVwdGg7IGkrKykKKyAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCIgICIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB3cml0ZXIud3JpdGUoIjwvIik7CisgICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gZWxlbWVudFN0YWNrW2RlcHRoICogMyArIDFdOworICAgICAgICAgICAgaWYgKCFwcmVmaXguaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKHByZWZpeCk7CisgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCc6Jyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB3cml0ZXIud3JpdGUobmFtZSk7CisgICAgICAgICAgICB3cml0ZXIud3JpdGUoJz4nKTsKKyAgICAgICAgfQorCisgICAgICAgIG5zcENvdW50c1tkZXB0aCArIDFdID0gbnNwQ291bnRzW2RlcHRoXTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoKSB7CisgICAgICAgIHJldHVybiBnZXREZXB0aCgpID09IDAgPyBudWxsIDogZWxlbWVudFN0YWNrW2dldERlcHRoKCkgKiAzIC0gM107CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gZ2V0RGVwdGgoKSA9PSAwID8gbnVsbCA6IGVsZW1lbnRTdGFja1tnZXREZXB0aCgpICogMyAtIDFdOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0RGVwdGgoKSB7CisgICAgICAgIHJldHVybiBwZW5kaW5nID8gZGVwdGggKyAxIDogZGVwdGg7CisgICAgfQorCisgICAgcHVibGljIFhtbFNlcmlhbGl6ZXIgdGV4dChTdHJpbmcgdGV4dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2soZmFsc2UpOworICAgICAgICBpbmRlbnRbZGVwdGhdID0gZmFsc2U7CisgICAgICAgIHdyaXRlRXNjYXBlZCh0ZXh0LCAtMSk7CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBYbWxTZXJpYWxpemVyIHRleHQoY2hhcltdIHRleHQsIGludCBzdGFydCwgaW50IGxlbikKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGV4dChuZXcgU3RyaW5nKHRleHQsIHN0YXJ0LCBsZW4pKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY2RzZWN0KFN0cmluZyBkYXRhKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGVjayhmYWxzZSk7CisgICAgICAgIC8vIEJFR0lOIGFuZHJvaWQtY2hhbmdlZDogXV0+IGlzIG5vdCBhbGxvd2VkIHdpdGhpbiBhIENEQVRBLAorICAgICAgICAvLyBzbyBicmVhayBhbmQgc3RhcnQgYSBuZXcgb25lIHdoZW4gbmVjZXNzYXJ5LgorICAgICAgICBkYXRhID0gZGF0YS5yZXBsYWNlKCJdXT4iLCAiXV1dXT48IVtDREFUQVs+Iik7CisgICAgICAgIGNoYXJbXSBjaGFycyA9IGRhdGEudG9DaGFyQXJyYXkoKTsKKyAgICAgICAgLy8gV2UgYWxzbyBhcmVuJ3QgYWxsb3dlZCBhbnkgaW52YWxpZCBjaGFyYWN0ZXJzLgorICAgICAgICBmb3IgKGNoYXIgY2ggOiBjaGFycykgeworICAgICAgICAgICAgYm9vbGVhbiB2YWxpZCA9IChjaCA+PSAweDIwICYmIGNoIDw9IDB4ZDdmZikgfHwKKyAgICAgICAgICAgICAgICAgICAgKGNoID09ICdcdCcgfHwgY2ggPT0gJ1xuJyB8fCBjaCA9PSAnXHInKSB8fAorICAgICAgICAgICAgICAgICAgICAoY2ggPj0gMHhlMDAwICYmIGNoIDw9IDB4ZmZmZCk7CisgICAgICAgICAgICBpZiAoIXZhbGlkKSB7CisgICAgICAgICAgICAgICAgcmVwb3J0SW52YWxpZENoYXJhY3RlcihjaCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgd3JpdGVyLndyaXRlKCI8IVtDREFUQVsiKTsKKyAgICAgICAgd3JpdGVyLndyaXRlKGNoYXJzLCAwLCBjaGFycy5sZW5ndGgpOworICAgICAgICB3cml0ZXIud3JpdGUoIl1dPiIpOworICAgICAgICAvLyBFTkQgYW5kcm9pZC1jaGFuZ2VkCisgICAgfQorCisgICAgcHVibGljIHZvaWQgY29tbWVudChTdHJpbmcgY29tbWVudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2soZmFsc2UpOworICAgICAgICB3cml0ZXIud3JpdGUoIjwhLS0iKTsKKyAgICAgICAgd3JpdGVyLndyaXRlKGNvbW1lbnQpOworICAgICAgICB3cml0ZXIud3JpdGUoIi0tPiIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgcGkpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrKGZhbHNlKTsKKyAgICAgICAgd3JpdGVyLndyaXRlKCI8PyIpOworICAgICAgICB3cml0ZXIud3JpdGUocGkpOworICAgICAgICB3cml0ZXIud3JpdGUoIj8+Iik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEveG1sL3NyYy9tYWluL2phdmEvb3JnL2t4bWwyL2tkb20vRG9jdW1lbnQuamF2YSBiL3htbC9zcmMvbWFpbi9qYXZhL29yZy9reG1sMi9rZG9tL0RvY3VtZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTEyM2U2MgotLS0gL2Rldi9udWxsCisrKyBiL3htbC9zcmMvbWFpbi9qYXZhL29yZy9reG1sMi9rZG9tL0RvY3VtZW50LmphdmEKQEAgLTAsMCArMSwxMjkgQEAKKy8qIENvcHlyaWdodCAoYykgMjAwMiwyMDAzLCBTdGVmYW4gSGF1c3RlaW4sIE9iZXJoYXVzZW4sIFJobGQuLCBHZXJtYW55CisgKgorICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQorICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKKyAqIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKKyAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yCisgKiBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcworICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKKyAqCisgKiBUaGUgIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KKyAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgorICoKKyAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCisgKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKKyAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQorICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgorICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcKKyAqIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MKKyAqIElOIFRIRSBTT0ZUV0FSRS4gKi8KKworCitwYWNrYWdlIG9yZy5reG1sMi5rZG9tOworCitpbXBvcnQgamF2YS5pby4qOworCitpbXBvcnQgb3JnLnhtbHB1bGwudjEuKjsKKy8qKiBUaGUgZG9jdW1lbnQgY29uc2lzdHMgb2Ygc29tZSBsZWdhY3kgZXZlbnRzIGFuZCBhIHNpbmdsZSByb290CisgICAgZWxlbWVudC4gVGhpcyBjbGFzcyBiYXNpY2FsbHkgYWRkcyBzb21lIGNvbnNpc3RlbmN5IGNoZWNrcyB0bworICAgIE5vZGUuICovCisKK3B1YmxpYyBjbGFzcyBEb2N1bWVudCBleHRlbmRzIE5vZGUgeworCisgICAgcHJvdGVjdGVkIGludCByb290SW5kZXggPSAtMTsKKyAgICBTdHJpbmcgZW5jb2Rpbmc7CisgICAgQm9vbGVhbiBzdGFuZGFsb25lOworCisgICAgLyoqIHJldHVybnMgIiNkb2N1bWVudCIgKi8KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcgKCkgeworICAgICAgICByZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RW5jb2RpbmcoU3RyaW5nIGVuYykgeworICAgICAgICB0aGlzLmVuY29kaW5nID0gZW5jOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN0YW5kYWxvbmUgKEJvb2xlYW4gc3RhbmRhbG9uZSkgeworICAgICAgICB0aGlzLnN0YW5kYWxvbmUgPSBzdGFuZGFsb25lOworICAgIH0KKworICAgIHB1YmxpYyBCb29sZWFuIGdldFN0YW5kYWxvbmUoKSB7CisgICAgICAgIHJldHVybiBzdGFuZGFsb25lOworICAgIH0KKworCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gIiNkb2N1bWVudCI7CisgICAgfQorCisgICAgLyoqIEFkZHMgYSBjaGlsZCBhdCB0aGUgZ2l2ZW4gaW5kZXggcG9zaXRpb24uIFRocm93cworICAgIGFuIGV4Y2VwdGlvbiB3aGVuIGEgc2Vjb25kIHJvb3QgZWxlbWVudCBpcyBhZGRlZCAqLworCisgICAgcHVibGljIHZvaWQgYWRkQ2hpbGQoaW50IGluZGV4LCBpbnQgdHlwZSwgT2JqZWN0IGNoaWxkKSB7CisgICAgICAgIGlmICh0eXBlID09IEVMRU1FTlQpIHsKKyAgICAgICAgIC8vICAgaWYgKHJvb3RJbmRleCAhPSAtMSkKKyAgICAgICAgICAgLy8gICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJPbmx5IG9uZSBkb2N1bWVudCByb290IGVsZW1lbnQgYWxsb3dlZCIpOworCisgICAgICAgICAgICByb290SW5kZXggPSBpbmRleDsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChyb290SW5kZXggPj0gaW5kZXgpCisgICAgICAgICAgICByb290SW5kZXgrKzsKKworICAgICAgICBzdXBlci5hZGRDaGlsZChpbmRleCwgdHlwZSwgY2hpbGQpOworICAgIH0KKworICAgIC8qKiByZWFkcyB0aGUgZG9jdW1lbnQgYW5kIGNoZWNrcyBpZiB0aGUgbGFzdCBldmVudAorICAgIGlzIEVORF9ET0NVTUVOVC4gSWYgbm90LCBhbiBleGNlcHRpb24gaXMgdGhyb3duLgorICAgIFRoZSBlbmQgZXZlbnQgaXMgY29uc3VtZWQuIEZvciBwYXJzaW5nIHBhcnRpYWwKKyAgICAgICAgWE1MIHN0cnVjdHVyZXMsIGNvbnNpZGVyIHVzaW5nIE5vZGUucGFyc2UgKCkuICovCisKKyAgICBwdWJsaWMgdm9pZCBwYXJzZShYbWxQdWxsUGFyc2VyIHBhcnNlcikKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIHsKKworICAgICAgICBwYXJzZXIucmVxdWlyZShYbWxQdWxsUGFyc2VyLlNUQVJUX0RPQ1VNRU5ULCBudWxsLCBudWxsKTsKKyAgICAgICAgcGFyc2VyLm5leHRUb2tlbiAoKTsKKworICAgICAgICBlbmNvZGluZyA9IHBhcnNlci5nZXRJbnB1dEVuY29kaW5nKCk7CisgICAgICAgIHN0YW5kYWxvbmUgPSAoQm9vbGVhbilwYXJzZXIuZ2V0UHJvcGVydHkgKCJodHRwOi8veG1scHVsbC5vcmcvdjEvZG9jL3Byb3BlcnRpZXMuaHRtbCN4bWxkZWNsLXN0YW5kYWxvbmUiKTsKKworICAgICAgICBzdXBlci5wYXJzZShwYXJzZXIpOworCisgICAgICAgIGlmIChwYXJzZXIuZ2V0RXZlbnRUeXBlKCkgIT0gWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQpCisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiRG9jdW1lbnQgZW5kIGV4cGVjdGVkISIpOworCisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVtb3ZlQ2hpbGQoaW50IGluZGV4KSB7CisgICAgICAgIGlmIChpbmRleCA9PSByb290SW5kZXgpCisgICAgICAgICAgICByb290SW5kZXggPSAtMTsKKyAgICAgICAgZWxzZSBpZiAoaW5kZXggPCByb290SW5kZXgpCisgICAgICAgICAgICByb290SW5kZXgtLTsKKworICAgICAgICBzdXBlci5yZW1vdmVDaGlsZChpbmRleCk7CisgICAgfQorCisgICAgLyoqIHJldHVybnMgdGhlIHJvb3QgZWxlbWVudCBvZiB0aGlzIGRvY3VtZW50LiAqLworCisgICAgcHVibGljIEVsZW1lbnQgZ2V0Um9vdEVsZW1lbnQoKSB7CisgICAgICAgIGlmIChyb290SW5kZXggPT0gLTEpCisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiRG9jdW1lbnQgaGFzIG5vIHJvb3QgZWxlbWVudCEiKTsKKworICAgICAgICByZXR1cm4gKEVsZW1lbnQpIGdldENoaWxkKHJvb3RJbmRleCk7CisgICAgfQorCisKKyAgICAvKiogV3JpdGVzIHRoaXMgbm9kZSB0byB0aGUgZ2l2ZW4gWG1sV3JpdGVyLiBGb3Igbm9kZSBhbmQgZG9jdW1lbnQsCisgICAgICAgIHRoaXMgbWV0aG9kIGlzIGlkZW50aWNhbCB0byB3cml0ZUNoaWxkcmVuLCBleGNlcHQgdGhhdCB0aGUKKyAgICAgICAgc3RyZWFtIGlzIGZsdXNoZWQgYXV0b21hdGljYWxseS4gKi8KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFhtbFNlcmlhbGl6ZXIgd3JpdGVyKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIHdyaXRlci5zdGFydERvY3VtZW50KGVuY29kaW5nLCBzdGFuZGFsb25lKTsKKyAgICAgICAgd3JpdGVDaGlsZHJlbih3cml0ZXIpOworICAgICAgICB3cml0ZXIuZW5kRG9jdW1lbnQoKTsKKyAgICB9CisKKworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3htbC9zcmMvbWFpbi9qYXZhL29yZy9reG1sMi9rZG9tL0VsZW1lbnQuamF2YSBiL3htbC9zcmMvbWFpbi9qYXZhL29yZy9reG1sMi9rZG9tL0VsZW1lbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOWNiNDI2Ci0tLSAvZGV2L251bGwKKysrIGIveG1sL3NyYy9tYWluL2phdmEvb3JnL2t4bWwyL2tkb20vRWxlbWVudC5qYXZhCkBAIC0wLDAgKzEsMzM1IEBACisvKiBDb3B5cmlnaHQgKGMpIDIwMDIsMjAwMywgU3RlZmFuIEhhdXN0ZWluLCBPYmVyaGF1c2VuLCBSaGxkLiwgR2VybWFueQorICoKKyAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKKyAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCisgKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCisgKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vcgorICogc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKKyAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CisgKgorICogVGhlICBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCisgKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KKyAqCisgKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgorICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCisgKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKKyAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKKyAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HCisgKiBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTCisgKiBJTiBUSEUgU09GVFdBUkUuICovCisKK3BhY2thZ2Ugb3JnLmt4bWwyLmtkb207CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLio7CisKK2ltcG9ydCBvcmcueG1scHVsbC52MS4qOworCisvKioKKyAqIEluIG9yZGVyIHRvIGNyZWF0ZSBhbiBlbGVtZW50LCBwbGVhc2UgdXNlIHRoZSBjcmVhdGVFbGVtZW50IG1ldGhvZAorICogaW5zdGVhZCBvZiBpbnZva2luZyB0aGUgY29uc3RydWN0b3IgZGlyZWN0bHkuIFRoZSByaWdodCBwbGFjZSB0bworICogYWRkIHVzZXIgZGVmaW5lZCBpbml0aWFsaXphdGlvbiBjb2RlIGlzIHRoZSBpbml0IG1ldGhvZC4gKi8KKworcHVibGljIGNsYXNzIEVsZW1lbnQgZXh0ZW5kcyBOb2RlIHsKKworICAgIHByb3RlY3RlZCBTdHJpbmcgbmFtZXNwYWNlOworICAgIHByb3RlY3RlZCBTdHJpbmcgbmFtZTsKKyAgICBwcm90ZWN0ZWQgVmVjdG9yIGF0dHJpYnV0ZXM7CisgICAgcHJvdGVjdGVkIE5vZGUgcGFyZW50OworICAgIHByb3RlY3RlZCBWZWN0b3IgcHJlZml4ZXM7CisKKyAgICBwdWJsaWMgRWxlbWVudCgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBjYWxsZWQgd2hlbiBhbGwgcHJvcGVydGllcyBhcmUgc2V0LCBidXQgYmVmb3JlIGNoaWxkcmVuCisgICAgICogYXJlIHBhcnNlZC4gUGxlYXNlIGRvIG5vdCB1c2Ugc2V0UGFyZW50IGZvciBpbml0aWFsaXphdGlvbgorICAgICAqIGNvZGUgYW55IGxvbmdlci4gKi8KKworICAgIHB1YmxpYyB2b2lkIGluaXQoKSB7CisgICAgfQorCisKKworCisgICAgLyoqCisgICAgICogcmVtb3ZlcyBhbGwgY2hpbGRyZW4gYW5kIGF0dHJpYnV0ZXMgKi8KKworICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgICAgICBhdHRyaWJ1dGVzID0gbnVsbDsKKyAgICAgICAgY2hpbGRyZW4gPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZvcndhcmRzIGNyZWF0aW9uIHJlcXVlc3QgdG8gcGFyZW50IGlmIGFueSwgb3RoZXJ3aXNlCisgICAgICogY2FsbHMgc3VwZXIuY3JlYXRlRWxlbWVudC4gKi8KKworICAgIHB1YmxpYyBFbGVtZW50IGNyZWF0ZUVsZW1lbnQoCisgICAgICAgIFN0cmluZyBuYW1lc3BhY2UsCisgICAgICAgIFN0cmluZyBuYW1lKSB7CisKKyAgICAgICAgcmV0dXJuICh0aGlzLnBhcmVudCA9PSBudWxsKQorICAgICAgICAgICAgPyBzdXBlci5jcmVhdGVFbGVtZW50KG5hbWVzcGFjZSwgbmFtZSkKKyAgICAgICAgICAgIDogdGhpcy5wYXJlbnQuY3JlYXRlRWxlbWVudChuYW1lc3BhY2UsIG5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIG9mIHRoaXMgZWxlbWVudC4gKi8KKworICAgIHB1YmxpYyBpbnQgZ2V0QXR0cmlidXRlQ291bnQoKSB7CisgICAgICAgIHJldHVybiBhdHRyaWJ1dGVzID09IG51bGwgPyAwIDogYXR0cmlidXRlcy5zaXplKCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVOYW1lc3BhY2UgKGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gKChTdHJpbmcgW10pIGF0dHJpYnV0ZXMuZWxlbWVudEF0IChpbmRleCkpIFswXTsKKyAgICB9CisKKy8qICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlUHJlZml4IChpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuICgoU3RyaW5nIFtdKSBhdHRyaWJ1dGVzLmVsZW1lbnRBdCAoaW5kZXgpKSBbMV07CisgICAgfSovCisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZU5hbWUgKGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gKChTdHJpbmcgW10pIGF0dHJpYnV0ZXMuZWxlbWVudEF0IChpbmRleCkpIFsxXTsKKyAgICB9CisKKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlVmFsdWUgKGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gKChTdHJpbmcgW10pIGF0dHJpYnV0ZXMuZWxlbWVudEF0IChpbmRleCkpIFsyXTsKKyAgICB9CisKKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlVmFsdWUgKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ2V0QXR0cmlidXRlQ291bnQgKCk7IGkrKykgeworICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzIChnZXRBdHRyaWJ1dGVOYW1lIChpKSkKKyAgICAgICAgICAgICAgICAmJiAobmFtZXNwYWNlID09IG51bGwgfHwgbmFtZXNwYWNlLmVxdWFscyAoZ2V0QXR0cmlidXRlTmFtZXNwYWNlKGkpKSkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gZ2V0QXR0cmlidXRlVmFsdWUgKGkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHJvb3Qgbm9kZSwgZGV0ZXJtaW5lZCBieSBhc2NlbmRpbmcgdG8gdGhlCisgICAgICogYWxsIHBhcmVudHMgdW4gb2YgdGhlIHJvb3QgZWxlbWVudC4gKi8KKworICAgIHB1YmxpYyBOb2RlIGdldFJvb3QoKSB7CisKKyAgICAgICAgRWxlbWVudCBjdXJyZW50ID0gdGhpczsKKworICAgICAgICB3aGlsZSAoY3VycmVudC5wYXJlbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKCEoY3VycmVudC5wYXJlbnQgaW5zdGFuY2VvZiBFbGVtZW50KSkgcmV0dXJuIGN1cnJlbnQucGFyZW50OworICAgICAgICAgICAgY3VycmVudCA9IChFbGVtZW50KSBjdXJyZW50LnBhcmVudDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjdXJyZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIHJldHVybnMgdGhlIChsb2NhbCkgbmFtZSBvZiB0aGUgZWxlbWVudCAqLworCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiByZXR1cm5zIHRoZSBuYW1lc3BhY2Ugb2YgdGhlIGVsZW1lbnQgKi8KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlKCkgeworICAgICAgICByZXR1cm4gbmFtZXNwYWNlOworICAgIH0KKworCisgICAgLyoqCisgICAgICogcmV0dXJucyB0aGUgbmFtZXNwYWNlIGZvciB0aGUgZ2l2ZW4gcHJlZml4ICovCisKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVyaSAoU3RyaW5nIHByZWZpeCkgeworICAgICAgICBpbnQgY250ID0gZ2V0TmFtZXNwYWNlQ291bnQgKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY250OyBpKyspIHsKKyAgICAgICAgICAgIGlmIChwcmVmaXggPT0gZ2V0TmFtZXNwYWNlUHJlZml4IChpKSB8fAorICAgICAgICAgICAgICAgIChwcmVmaXggIT0gbnVsbCAmJiBwcmVmaXguZXF1YWxzIChnZXROYW1lc3BhY2VQcmVmaXggKGkpKSkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGdldE5hbWVzcGFjZVVyaSAoaSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHBhcmVudCBpbnN0YW5jZW9mIEVsZW1lbnQgPyAoKEVsZW1lbnQpIHBhcmVudCkuZ2V0TmFtZXNwYWNlVXJpIChwcmVmaXgpIDogbnVsbDsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIHJldHVybnMgdGhlIG51bWJlciBvZiBkZWNsYXJlZCBuYW1lc3BhY2VzLCBOT1QgaW5jbHVkaW5nCisgICAgICogcGFyZW50IGVsZW1lbnRzICovCisKKyAgICBwdWJsaWMgaW50IGdldE5hbWVzcGFjZUNvdW50ICgpIHsKKyAgICAgICAgcmV0dXJuIChwcmVmaXhlcyA9PSBudWxsID8gMCA6IHByZWZpeGVzLnNpemUgKCkpOworICAgIH0KKworCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VQcmVmaXggKGludCBpKSB7CisgICAgICAgIHJldHVybiAoKFN0cmluZyBbXSkgcHJlZml4ZXMuZWxlbWVudEF0IChpKSkgWzBdOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVXJpIChpbnQgaSkgeworICAgICAgICByZXR1cm4gKChTdHJpbmcgW10pIHByZWZpeGVzLmVsZW1lbnRBdCAoaSkpIFsxXTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHBhcmVudCBub2RlIG9mIHRoaXMgZWxlbWVudCAqLworCisgICAgcHVibGljIE5vZGUgZ2V0UGFyZW50KCkgeworICAgICAgICByZXR1cm4gcGFyZW50OworICAgIH0KKworICAgIC8qCisgICAgICogUmV0dXJucyB0aGUgcGFyZW50IGVsZW1lbnQgaWYgYXZhaWxhYmxlLCBudWxsIG90aGVyd2lzZQorCisgICAgcHVibGljIEVsZW1lbnQgZ2V0UGFyZW50RWxlbWVudCgpIHsKKyAgICAgICAgcmV0dXJuIChwYXJlbnQgaW5zdGFuY2VvZiBFbGVtZW50KQorICAgICAgICAgICAgPyAoKEVsZW1lbnQpIHBhcmVudCkKKyAgICAgICAgICAgIDogbnVsbDsKKyAgICB9CisqLworCisgICAgLyoqCisgICAgICogQnVpbGRzIHRoZSBjaGlsZCBlbGVtZW50cyBmcm9tIHRoZSBnaXZlbiBQYXJzZXIuIEJ5IG92ZXJ3cml0aW5nCisgICAgICogcGFyc2UsIGFuIGVsZW1lbnQgY2FuIHRha2UgY29tcGxldGUgY29udHJvbCBvdmVyIHBhcnNpbmcgaXRzCisgICAgICogc3VidHJlZS4gKi8KKworICAgIHB1YmxpYyB2b2lkIHBhcnNlKFhtbFB1bGxQYXJzZXIgcGFyc2VyKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworCisgICAgICAgIGZvciAoaW50IGkgPSBwYXJzZXIuZ2V0TmFtZXNwYWNlQ291bnQgKHBhcnNlci5nZXREZXB0aCAoKSAtIDEpOworICAgICAgICAgICAgaSA8IHBhcnNlci5nZXROYW1lc3BhY2VDb3VudCAocGFyc2VyLmdldERlcHRoICgpKTsgaSsrKSB7CisgICAgICAgICAgICBzZXRQcmVmaXggKHBhcnNlci5nZXROYW1lc3BhY2VQcmVmaXggKGkpLCBwYXJzZXIuZ2V0TmFtZXNwYWNlVXJpKGkpKTsKKyAgICAgICAgfQorCisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJzZXIuZ2V0QXR0cmlidXRlQ291bnQgKCk7IGkrKykKKyAgICAgICAgICAgIHNldEF0dHJpYnV0ZSAocGFyc2VyLmdldEF0dHJpYnV0ZU5hbWVzcGFjZSAoaSksCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyLmdldEF0dHJpYnV0ZVByZWZpeCAoaSksCisgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlci5nZXRBdHRyaWJ1dGVOYW1lIChpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyLmdldEF0dHJpYnV0ZVZhbHVlIChpKSk7CisKKworICAgICAgICAvLyAgICAgICAgaWYgKHByZWZpeE1hcCA9PSBudWxsKSB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbiAoIiEhIik7CisKKyAgICAgICAgaW5pdCgpOworCisKKyAgICAgICAgaWYgKHBhcnNlci5pc0VtcHR5RWxlbWVudFRhZygpKQorICAgICAgICAgICAgcGFyc2VyLm5leHRUb2tlbiAoKTsKKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBwYXJzZXIubmV4dFRva2VuICgpOworICAgICAgICAgICAgc3VwZXIucGFyc2UocGFyc2VyKTsKKworICAgICAgICAgICAgaWYgKGdldENoaWxkQ291bnQoKSA9PSAwKQorICAgICAgICAgICAgICAgIGFkZENoaWxkKElHTk9SQUJMRV9XSElURVNQQUNFLCAiIik7CisgICAgICAgIH0KKworICAgICAgICBwYXJzZXIucmVxdWlyZSgKKyAgICAgICAgICAgIFhtbFB1bGxQYXJzZXIuRU5EX1RBRywKKyAgICAgICAgICAgIGdldE5hbWVzcGFjZSgpLAorICAgICAgICAgICAgZ2V0TmFtZSgpKTsKKworICAgICAgICBwYXJzZXIubmV4dFRva2VuICgpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZ2l2ZW4gYXR0cmlidXRlOyBhIHZhbHVlIG9mIG51bGwgcmVtb3ZlcyB0aGUgYXR0cmlidXRlICovCisKKyAgICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGUgKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpIHsKKyAgICAgICAgaWYgKGF0dHJpYnV0ZXMgPT0gbnVsbCkKKyAgICAgICAgICAgIGF0dHJpYnV0ZXMgPSBuZXcgVmVjdG9yICgpOworCisgICAgICAgIGlmIChuYW1lc3BhY2UgPT0gbnVsbCkKKyAgICAgICAgICAgIG5hbWVzcGFjZSA9ICIiOworCisgICAgICAgIGZvciAoaW50IGkgPSBhdHRyaWJ1dGVzLnNpemUoKS0xOyBpID49MDsgaS0tKXsKKyAgICAgICAgICAgIFN0cmluZ1tdIGF0dHJpYnV0ID0gKFN0cmluZ1tdKSBhdHRyaWJ1dGVzLmVsZW1lbnRBdChpKTsKKyAgICAgICAgICAgIGlmIChhdHRyaWJ1dFswXS5lcXVhbHMobmFtZXNwYWNlKSAmJgorICAgICAgICAgICAgICAgIGF0dHJpYnV0WzFdLmVxdWFscyhuYW1lKSl7CisKKyAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLnJlbW92ZUVsZW1lbnRBdChpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0WzJdID0gdmFsdWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGF0dHJpYnV0ZXMuYWRkRWxlbWVudAorICAgICAgICAgICAgKG5ldyBTdHJpbmcgW10ge25hbWVzcGFjZSwgbmFtZSwgdmFsdWV9KTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGdpdmVuIHByZWZpeDsgYSBuYW1lc3BhY2UgdmFsdWUgb2YgbnVsbCByZW1vdmVzcyB0aGUKKyAgICAgKiBwcmVmaXggKi8KKworICAgIHB1YmxpYyB2b2lkIHNldFByZWZpeCAoU3RyaW5nIHByZWZpeCwgU3RyaW5nIG5hbWVzcGFjZSkgeworICAgICAgICBpZiAocHJlZml4ZXMgPT0gbnVsbCkgcHJlZml4ZXMgPSBuZXcgVmVjdG9yICgpOworICAgICAgICBwcmVmaXhlcy5hZGRFbGVtZW50IChuZXcgU3RyaW5nIFtdIHtwcmVmaXgsIG5hbWVzcGFjZX0pOworICAgIH0KKworCisgICAgLyoqCisgICAgICogc2V0cyB0aGUgbmFtZSBvZiB0aGUgZWxlbWVudCAqLworCisgICAgcHVibGljIHZvaWQgc2V0TmFtZShTdHJpbmcgbmFtZSkgeworICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIHNldHMgdGhlIG5hbWVzcGFjZSBvZiB0aGUgZWxlbWVudC4gUGxlYXNlIG5vdGU6IEZvciBubworICAgICAqIG5hbWVzcGFjZSwgcGxlYXNlIHVzZSBYbWwuTk9fTkFNRVNQQUNFLCBudWxsIGlzIG5vdCBhIGxlZ2FsCisgICAgICogdmFsdWUuIEN1cnJlbnRseSwgbnVsbCBpcyBjb252ZXJ0ZWQgdG8gWG1sLk5PX05BTUVTUEFDRSwgYnV0CisgICAgICogZnV0dXJlIHZlcnNpb25zIG1heSB0aHJvdyBhbiBleGNlcHRpb24uICovCisKKyAgICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2UoU3RyaW5nIG5hbWVzcGFjZSkgeworICAgICAgICBpZiAobmFtZXNwYWNlID09IG51bGwpCisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24gKCJVc2UgXCJcIiBmb3IgZW1wdHkgbmFtZXNwYWNlIik7CisgICAgICAgIHRoaXMubmFtZXNwYWNlID0gbmFtZXNwYWNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIFBhcmVudCBvZiB0aGlzIGVsZW1lbnQuIEF1dG9tYXRpY2FsbHkgY2FsbGVkIGZyb20gdGhlCisgICAgICogYWRkIG1ldGhvZC4gIFBsZWFzZSB1c2Ugd2l0aCBjYXJlLCB5b3UgY2FuIHNpbXBseQorICAgICAqIGNyZWF0ZSBpbmNvbnNpdGVuY2llcyBpbiB0aGUgZG9jdW1lbnQgdHJlZSBzdHJ1Y3R1cmUgdXNpbmcKKyAgICAgKiB0aGlzIG1ldGhvZCEgICovCisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRQYXJlbnQoTm9kZSBwYXJlbnQpIHsKKyAgICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhpcyBlbGVtZW50IGFuZCBhbGwgY2hpbGRyZW4gdG8gdGhlIGdpdmVuIFhtbFdyaXRlci4gKi8KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFhtbFNlcmlhbGl6ZXIgd3JpdGVyKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICAgIGlmIChwcmVmaXhlcyAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHByZWZpeGVzLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgd3JpdGVyLnNldFByZWZpeCAoZ2V0TmFtZXNwYWNlUHJlZml4IChpKSwgZ2V0TmFtZXNwYWNlVXJpIChpKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB3cml0ZXIuc3RhcnRUYWcoCisgICAgICAgICAgICBnZXROYW1lc3BhY2UoKSwKKyAgICAgICAgICAgIGdldE5hbWUoKSk7CisKKyAgICAgICAgaW50IGxlbiA9IGdldEF0dHJpYnV0ZUNvdW50KCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgICAgICAgd3JpdGVyLmF0dHJpYnV0ZSgKKyAgICAgICAgICAgICAgICBnZXRBdHRyaWJ1dGVOYW1lc3BhY2UoaSksCisgICAgICAgICAgICAgICAgZ2V0QXR0cmlidXRlTmFtZShpKSwKKyAgICAgICAgICAgICAgICBnZXRBdHRyaWJ1dGVWYWx1ZShpKSk7CisgICAgICAgIH0KKworICAgICAgICB3cml0ZUNoaWxkcmVuKHdyaXRlcik7CisKKyAgICAgICAgd3JpdGVyLmVuZFRhZyhnZXROYW1lc3BhY2UgKCksIGdldE5hbWUgKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3htbC9zcmMvbWFpbi9qYXZhL29yZy9reG1sMi9rZG9tL05vZGUuamF2YSBiL3htbC9zcmMvbWFpbi9qYXZhL29yZy9reG1sMi9rZG9tL05vZGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MjAzOTBjCi0tLSAvZGV2L251bGwKKysrIGIveG1sL3NyYy9tYWluL2phdmEvb3JnL2t4bWwyL2tkb20vTm9kZS5qYXZhCkBAIC0wLDAgKzEsMzY2IEBACisvKiBDb3B5cmlnaHQgKGMpIDIwMDIsMjAwMywgU3RlZmFuIEhhdXN0ZWluLCBPYmVyaGF1c2VuLCBSaGxkLiwgR2VybWFueQorICoKKyAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKKyAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCisgKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCisgKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vcgorICogc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKKyAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CisgKgorICogVGhlICBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCisgKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KKyAqCisgKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgorICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCisgKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKKyAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKKyAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HCisgKiBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTCisgKiBJTiBUSEUgU09GVFdBUkUuICovCisKK3BhY2thZ2Ugb3JnLmt4bWwyLmtkb207CisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgb3JnLnhtbHB1bGwudjEuKjsKKy8qKiBBIGNvbW1vbiBiYXNlIGNsYXNzIGZvciBEb2N1bWVudCBhbmQgRWxlbWVudCwgYWxzbyB1c2VkIGZvcgorICAgIHN0b3JpbmcgWE1MIGZyYWdtZW50cy4gKi8KKworcHVibGljIGNsYXNzIE5vZGUgeyAvL2ltcGxlbWVudHMgWG1sSU97CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBET0NVTUVOVCA9IDA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUxFTUVOVCA9IDI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEVYVCA9IDQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0RTRUNUID0gNTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlRJVFlfUkVGID0gNjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJR05PUkFCTEVfV0hJVEVTUEFDRSA9IDc7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJPQ0VTU0lOR19JTlNUUlVDVElPTiA9IDg7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09NTUVOVCA9IDk7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRE9DREVDTCA9IDEwOworCisgICAgcHJvdGVjdGVkIFZlY3RvciBjaGlsZHJlbjsKKyAgICBwcm90ZWN0ZWQgU3RyaW5nQnVmZmVyIHR5cGVzOworCisgICAgLyoqIGluc2VydHMgdGhlIGdpdmVuIGNoaWxkIG9iamVjdCBvZiB0aGUgZ2l2ZW4gdHlwZSBhdCB0aGUKKyAgICBnaXZlbiBpbmRleC4gKi8KKworICAgIHB1YmxpYyB2b2lkIGFkZENoaWxkKGludCBpbmRleCwgaW50IHR5cGUsIE9iamVjdCBjaGlsZCkgeworCisgICAgICAgIGlmIChjaGlsZCA9PSBudWxsKQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisKKyAgICAgICAgaWYgKGNoaWxkcmVuID09IG51bGwpIHsKKyAgICAgICAgICAgIGNoaWxkcmVuID0gbmV3IFZlY3RvcigpOworICAgICAgICAgICAgdHlwZXMgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAodHlwZSA9PSBFTEVNRU5UKSB7CisgICAgICAgICAgICBpZiAoIShjaGlsZCBpbnN0YW5jZW9mIEVsZW1lbnQpKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJFbGVtZW50IG9iaiBleHBlY3RlZCkiKTsKKworICAgICAgICAgICAgKChFbGVtZW50KSBjaGlsZCkuc2V0UGFyZW50KHRoaXMpOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKCEoY2hpbGQgaW5zdGFuY2VvZiBTdHJpbmcpKQorICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlN0cmluZyBleHBlY3RlZCIpOworCisgICAgICAgIGNoaWxkcmVuLmluc2VydEVsZW1lbnRBdChjaGlsZCwgaW5kZXgpOworICAgICAgICB0eXBlcy5pbnNlcnQoaW5kZXgsIChjaGFyKSB0eXBlKTsKKyAgICB9CisKKyAgICAvKiogY29udmVuaWVuY2UgbWV0aG9kIGZvciBhZGRDaGlsZCAoZ2V0Q2hpbGRDb3VudCAoKSwgY2hpbGQpICovCisKKyAgICBwdWJsaWMgdm9pZCBhZGRDaGlsZChpbnQgdHlwZSwgT2JqZWN0IGNoaWxkKSB7CisgICAgICAgIGFkZENoaWxkKGdldENoaWxkQ291bnQoKSwgdHlwZSwgY2hpbGQpOworICAgIH0KKworICAgIC8qKiBCdWlsZHMgYSBkZWZhdWx0IGVsZW1lbnQgd2l0aCB0aGUgZ2l2ZW4gcHJvcGVydGllcy4gRWxlbWVudHMKKyAgICBzaG91bGQgYWx3YXlzIGJlIGNyZWF0ZWQgdXNpbmcgdGhpcyBtZXRob2QgaW5zdGVhZCBvZiB0aGUKKyAgICBjb25zdHJ1Y3RvciBpbiBvcmRlciB0byBlbmFibGUgY29uc3RydWN0aW9uIG9mIHNwZWNpYWxpemVkCisgICAgc3ViY2xhc3NlcyBieSBkZXJpdmluZyBjdXN0b20gRG9jdW1lbnQgY2xhc3Nlcy4gUGxlYXNlIG5vdGU6CisgICAgRm9yIG5vIG5hbWVzcGFjZSwgcGxlYXNlIHVzZSBYbWwuTk9fTkFNRVNQQUNFLCBudWxsIGlzIG5vdCBhCisgICAgbGVnYWwgdmFsdWUuIEN1cnJlbnRseSwgbnVsbCBpcyBjb252ZXJ0ZWQgdG8gWG1sLk5PX05BTUVTUEFDRSwKKyAgICBidXQgZnV0dXJlIHZlcnNpb25zIG1heSB0aHJvdyBhbiBleGNlcHRpb24uICovCisKKyAgICBwdWJsaWMgRWxlbWVudCBjcmVhdGVFbGVtZW50KFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lKSB7CisKKyAgICAgICAgRWxlbWVudCBlID0gbmV3IEVsZW1lbnQoKTsKKyAgICAgICAgZS5uYW1lc3BhY2UgPSBuYW1lc3BhY2UgPT0gbnVsbCA/ICIiIDogbmFtZXNwYWNlOworICAgICAgICBlLm5hbWUgPSBuYW1lOworICAgICAgICByZXR1cm4gZTsKKyAgICB9CisKKyAgICAvKiogUmV0dXJucyB0aGUgY2hpbGQgb2JqZWN0IGF0IHRoZSBnaXZlbiBpbmRleC4gIEZvciBjaGlsZAorICAgICAgICBlbGVtZW50cywgYW4gRWxlbWVudCBvYmplY3QgaXMgcmV0dXJuZWQuIEZvciBhbGwgb3RoZXIgY2hpbGQKKyAgICAgICAgdHlwZXMsIGEgU3RyaW5nIGlzIHJldHVybmVkLiAqLworCisgICAgcHVibGljIE9iamVjdCBnZXRDaGlsZChpbnQgaW5kZXgpIHsKKyAgICAgICAgcmV0dXJuIGNoaWxkcmVuLmVsZW1lbnRBdChpbmRleCk7CisgICAgfQorCisgICAgLyoqIFJldHVybnMgdGhlIG51bWJlciBvZiBjaGlsZCBvYmplY3RzICovCisKKyAgICBwdWJsaWMgaW50IGdldENoaWxkQ291bnQoKSB7CisgICAgICAgIHJldHVybiBjaGlsZHJlbiA9PSBudWxsID8gMCA6IGNoaWxkcmVuLnNpemUoKTsKKyAgICB9CisKKyAgICAvKiogcmV0dXJucyB0aGUgZWxlbWVudCBhdCB0aGUgZ2l2ZW4gaW5kZXguIElmIHRoZSBub2RlIGF0IHRoZQorICAgIGdpdmVuIGluZGV4IGlzIGEgdGV4dCBub2RlLCBudWxsIGlzIHJldHVybmVkICovCisKKyAgICBwdWJsaWMgRWxlbWVudCBnZXRFbGVtZW50KGludCBpbmRleCkgeworICAgICAgICBPYmplY3QgY2hpbGQgPSBnZXRDaGlsZChpbmRleCk7CisgICAgICAgIHJldHVybiAoY2hpbGQgaW5zdGFuY2VvZiBFbGVtZW50KSA/IChFbGVtZW50KSBjaGlsZCA6IG51bGw7CisgICAgfQorCisgICAgLyoqIFJldHVybnMgdGhlIGVsZW1lbnQgd2l0aCB0aGUgZ2l2ZW4gbmFtZXNwYWNlIGFuZCBuYW1lLiBJZiB0aGUKKyAgICAgICAgZWxlbWVudCBpcyBub3QgZm91bmQsIG9yIG1vcmUgdGhhbiBvbmUgbWF0Y2hpbmcgZWxlbWVudHMgYXJlCisgICAgICAgIGZvdW5kLCBhbiBleGNlcHRpb24gaXMgdGhyb3duLiAqLworCisgICAgcHVibGljIEVsZW1lbnQgZ2V0RWxlbWVudChTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgbmFtZSkgeworCisgICAgICAgIGludCBpID0gaW5kZXhPZihuYW1lc3BhY2UsIG5hbWUsIDApOworICAgICAgICBpbnQgaiA9IGluZGV4T2YobmFtZXNwYWNlLCBuYW1lLCBpICsgMSk7CisKKyAgICAgICAgaWYgKGkgPT0gLTEgfHwgaiAhPSAtMSkKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJFbGVtZW50IHsiCisgICAgICAgICAgICAgICAgICAgICsgbmFtZXNwYWNlCisgICAgICAgICAgICAgICAgICAgICsgIn0iCisgICAgICAgICAgICAgICAgICAgICsgbmFtZQorICAgICAgICAgICAgICAgICAgICArIChpID09IC0xID8gIiBub3QgZm91bmQgaW4gIiA6ICIgbW9yZSB0aGFuIG9uY2UgaW4gIikKKyAgICAgICAgICAgICAgICAgICAgKyB0aGlzKTsKKworICAgICAgICByZXR1cm4gZ2V0RWxlbWVudChpKTsKKyAgICB9CisKKyAgICAvKiByZXR1cm5zICIjZG9jdW1lbnQtZnJhZ21lbnQiLiBGb3IgZWxlbWVudHMsIHRoZSBlbGVtZW50IG5hbWUgaXMgcmV0dXJuZWQKKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuICIjZG9jdW1lbnQtZnJhZ21lbnQiOworICAgIH0KKworICAgIC8qKiBSZXR1cm5zIHRoZSBuYW1lc3BhY2Ugb2YgdGhlIGN1cnJlbnQgZWxlbWVudC4gRm9yIE5vZGUKKyAgICAgICAgYW5kIERvY3VtZW50LCBYbWwuTk9fTkFNRVNQQUNFIGlzIHJldHVybmVkLgorCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoKSB7CisgICAgICAgIHJldHVybiAiIjsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldE5hbWVzcGFjZUNvdW50ICgpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqIHJldHVybnMgdGhlIHRleHQgY29udGVudCBpZiB0aGUgZWxlbWVudCBoYXMgdGV4dC1vbmx5CisgICAgY29udGVudC4gVGhyb3dzIGFuIGV4Y2VwdGlvbiBmb3IgbWl4ZWQgY29udGVudAorCisgICAgcHVibGljIFN0cmluZyBnZXRUZXh0KCkgeworCisgICAgICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIGludCBsZW4gPSBnZXRDaGlsZENvdW50KCk7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgICAgICAgaWYgKGlzVGV4dChpKSkKKyAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGdldFRleHQoaSkpOworICAgICAgICAgICAgZWxzZSBpZiAoZ2V0VHlwZShpKSA9PSBFTEVNRU5UKQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJub3QgdGV4dC1vbmx5IGNvbnRlbnQhIik7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorICAgICovCisKKyAgICAvKiogUmV0dXJucyB0aGUgdGV4dCBub2RlIHdpdGggdGhlIGdpdmVuIGluZGV4IG9yIG51bGwgaWYgdGhlIG5vZGUKKyAgICAgICAgd2l0aCB0aGUgZ2l2ZW4gaW5kZXggaXMgbm90IGEgdGV4dCBub2RlLiAqLworCisgICAgcHVibGljIFN0cmluZyBnZXRUZXh0KGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gKGlzVGV4dChpbmRleCkpID8gKFN0cmluZykgZ2V0Q2hpbGQoaW5kZXgpIDogbnVsbDsKKyAgICB9CisKKyAgICAvKiogUmV0dXJucyB0aGUgdHlwZSBvZiB0aGUgY2hpbGQgYXQgdGhlIGdpdmVuIGluZGV4LiBQb3NzaWJsZQorICAgIHR5cGVzIGFyZSBFTEVNRU5ULCBURVhULCBDT01NRU5ULCBhbmQgUFJPQ0VTU0lOR19JTlNUUlVDVElPTiAqLworCisgICAgcHVibGljIGludCBnZXRUeXBlKGludCBpbmRleCkgeworICAgICAgICByZXR1cm4gdHlwZXMuY2hhckF0KGluZGV4KTsKKyAgICB9CisKKyAgICAvKiogQ29udmVuaWVuY2UgbWV0aG9kIGZvciBpbmRleE9mIChnZXROYW1lc3BhY2UgKCksIG5hbWUsCisgICAgICAgIHN0YXJ0SW5kZXgpLgorCisgICAgcHVibGljIGludCBpbmRleE9mKFN0cmluZyBuYW1lLCBpbnQgc3RhcnRJbmRleCkgeworICAgICAgICByZXR1cm4gaW5kZXhPZihnZXROYW1lc3BhY2UoKSwgbmFtZSwgc3RhcnRJbmRleCk7CisgICAgfQorICAgICovCisKKyAgICAvKiogUGVyZm9ybXMgc2VhcmNoIGZvciBhbiBlbGVtZW50IHdpdGggdGhlIGdpdmVuIG5hbWVzcGFjZSBhbmQKKyAgICBuYW1lLCBzdGFydGluZyBhdCB0aGUgZ2l2ZW4gc3RhcnQgaW5kZXguIEEgbnVsbCBuYW1lc3BhY2UKKyAgICBtYXRjaGVzIGFueSBuYW1lc3BhY2UsIHBsZWFzZSB1c2UgWG1sLk5PX05BTUVTUEFDRSBmb3Igbm8KKyAgICBuYW1lc3BhY2UpLiAgcmV0dXJucyAtMSBpZiBubyBtYXRjaGluZyBlbGVtZW50IHdhcyBmb3VuZC4gKi8KKworICAgIHB1YmxpYyBpbnQgaW5kZXhPZihTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgbmFtZSwgaW50IHN0YXJ0SW5kZXgpIHsKKworICAgICAgICBpbnQgbGVuID0gZ2V0Q2hpbGRDb3VudCgpOworCisgICAgICAgIGZvciAoaW50IGkgPSBzdGFydEluZGV4OyBpIDwgbGVuOyBpKyspIHsKKworICAgICAgICAgICAgRWxlbWVudCBjaGlsZCA9IGdldEVsZW1lbnQoaSk7CisKKyAgICAgICAgICAgIGlmIChjaGlsZCAhPSBudWxsCisgICAgICAgICAgICAgICAgJiYgbmFtZS5lcXVhbHMoY2hpbGQuZ2V0TmFtZSgpKQorICAgICAgICAgICAgICAgICYmIChuYW1lc3BhY2UgPT0gbnVsbCB8fCBuYW1lc3BhY2UuZXF1YWxzKGNoaWxkLmdldE5hbWVzcGFjZSgpKSkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzVGV4dChpbnQgaSkgeworICAgICAgICBpbnQgdCA9IGdldFR5cGUoaSk7CisgICAgICAgIHJldHVybiB0ID09IFRFWFQgfHwgdCA9PSBJR05PUkFCTEVfV0hJVEVTUEFDRSB8fCB0ID09IENEU0VDVDsKKyAgICB9CisKKyAgICAvKiogUmVjdXJzaXZlbHkgYnVpbGRzIHRoZSBjaGlsZCBlbGVtZW50cyBmcm9tIHRoZSBnaXZlbiBwYXJzZXIKKyAgICB1bnRpbCBhbiBlbmQgdGFnIG9yIGVuZCBkb2N1bWVudCBpcyBmb3VuZC4KKyAgICAgICAgVGhlIGVuZCB0YWcgaXMgbm90IGNvbnN1bWVkLiAqLworCisgICAgcHVibGljIHZvaWQgcGFyc2UoWG1sUHVsbFBhcnNlciBwYXJzZXIpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiB7CisKKyAgICAgICAgYm9vbGVhbiBsZWF2ZSA9IGZhbHNlOworCisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGludCB0eXBlID0gcGFyc2VyLmdldEV2ZW50VHlwZSgpOworCisgICAvLyAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihwYXJzZXIuZ2V0UG9zaXRpb25EZXNjcmlwdGlvbigpKTsKKworICAgICAgICAgICAgc3dpdGNoICh0eXBlKSB7CisKKyAgICAgICAgICAgICAgICBjYXNlIFhtbFB1bGxQYXJzZXIuU1RBUlRfVEFHIDoKKyAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgRWxlbWVudCBjaGlsZCA9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyLmdldE5hbWVzcGFjZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXIuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgIGNoaWxkLnNldEF0dHJpYnV0ZXMgKGV2ZW50LmdldEF0dHJpYnV0ZXMgKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2hpbGQoRUxFTUVOVCwgY2hpbGQpOworCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBvcmRlciBpcyBpbXBvcnRhbnQgaGVyZSBzaW5jZQorICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2V0cGFyZW50IG1heSBwZXJmb3JtIHNvbWUgaW5pdCBjb2RlIQorCisgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5wYXJzZShwYXJzZXIpOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGNhc2UgWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQgOgorICAgICAgICAgICAgICAgIGNhc2UgWG1sUHVsbFBhcnNlci5FTkRfVEFHIDoKKyAgICAgICAgICAgICAgICAgICAgbGVhdmUgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICAgIGRlZmF1bHQgOgorICAgICAgICAgICAgICAgICAgICBpZiAocGFyc2VyLmdldFRleHQoKSAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2hpbGQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9PSBYbWxQdWxsUGFyc2VyLkVOVElUWV9SRUYgPyBURVhUIDogdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXIuZ2V0VGV4dCgpKTsKKyAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoCisgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID09IFhtbFB1bGxQYXJzZXIuRU5USVRZX1JFRgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHBhcnNlci5nZXROYW1lKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2hpbGQoRU5USVRZX1JFRiwgcGFyc2VyLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcGFyc2VyLm5leHRUb2tlbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHdoaWxlICghbGVhdmUpOworICAgIH0KKworICAgIC8qKiBSZW1vdmVzIHRoZSBjaGlsZCBvYmplY3QgYXQgdGhlIGdpdmVuIGluZGV4ICovCisKKyAgICBwdWJsaWMgdm9pZCByZW1vdmVDaGlsZChpbnQgaWR4KSB7CisgICAgICAgIGNoaWxkcmVuLnJlbW92ZUVsZW1lbnRBdChpZHgpOworCisgICAgICAgIC8qKiogIE1vZGlmaWNhdGlvbiBieSBISFMgLSBzdGFydCAqKiovCisgICAgICAgIC8vICAgICAgdHlwZXMuZGVsZXRlQ2hhckF0IChpbmRleCk7CisgICAgICAgIC8qKiovCisgICAgICAgIGludCBuID0gdHlwZXMubGVuZ3RoKCkgLSAxOworCisgICAgICAgIGZvciAoaW50IGkgPSBpZHg7IGkgPCBuOyBpKyspCisgICAgICAgICAgICB0eXBlcy5zZXRDaGFyQXQoaSwgdHlwZXMuY2hhckF0KGkgKyAxKSk7CisKKyAgICAgICAgdHlwZXMuc2V0TGVuZ3RoKG4pOworCisgICAgICAgIC8qKiogIE1vZGlmaWNhdGlvbiBieSBISFMgLSBlbmQgICAqKiovCisgICAgfQorCisgICAgLyogcmV0dXJucyBhIHZhbGlkIFhNTCByZXByZXNlbnRhdGlvbiBvZiB0aGlzIEVsZW1lbnQgaW5jbHVkaW5nCisgICAgICAgIGF0dHJpYnV0ZXMgYW5kIGNoaWxkcmVuLgorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0KKyAgICAgICAgICAgICAgICBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICBYbWxXcml0ZXIgeHcgPQorICAgICAgICAgICAgICAgIG5ldyBYbWxXcml0ZXIobmV3IE91dHB1dFN0cmVhbVdyaXRlcihib3MpKTsKKyAgICAgICAgICAgIHdyaXRlKHh3KTsKKyAgICAgICAgICAgIHh3LmNsb3NlKCk7CisgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhib3MudG9CeXRlQXJyYXkoKSk7CisgICAgICAgIH0KKyAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisgICAgKi8KKworICAgIC8qKiBXcml0ZXMgdGhpcyBub2RlIHRvIHRoZSBnaXZlbiBYbWxXcml0ZXIuIEZvciBub2RlIGFuZCBkb2N1bWVudCwKKyAgICAgICAgdGhpcyBtZXRob2QgaXMgaWRlbnRpY2FsIHRvIHdyaXRlQ2hpbGRyZW4sIGV4Y2VwdCB0aGF0IHRoZQorICAgICAgICBzdHJlYW0gaXMgZmx1c2hlZCBhdXRvbWF0aWNhbGx5LiAqLworCisgICAgcHVibGljIHZvaWQgd3JpdGUoWG1sU2VyaWFsaXplciB3cml0ZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlQ2hpbGRyZW4od3JpdGVyKTsKKyAgICAgICAgd3JpdGVyLmZsdXNoKCk7CisgICAgfQorCisgICAgLyoqIFdyaXRlcyB0aGUgY2hpbGRyZW4gb2YgdGhpcyBub2RlIHRvIHRoZSBnaXZlbiBYbWxXcml0ZXIuICovCisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZUNoaWxkcmVuKFhtbFNlcmlhbGl6ZXIgd3JpdGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoY2hpbGRyZW4gPT0gbnVsbCkKKyAgICAgICAgICAgIHJldHVybjsKKworICAgICAgICBpbnQgbGVuID0gY2hpbGRyZW4uc2l6ZSgpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKyAgICAgICAgICAgIGludCB0eXBlID0gZ2V0VHlwZShpKTsKKyAgICAgICAgICAgIE9iamVjdCBjaGlsZCA9IGNoaWxkcmVuLmVsZW1lbnRBdChpKTsKKyAgICAgICAgICAgIHN3aXRjaCAodHlwZSkgeworICAgICAgICAgICAgICAgIGNhc2UgRUxFTUVOVCA6CisgICAgICAgICAgICAgICAgICAgICAoKEVsZW1lbnQpIGNoaWxkKS53cml0ZSh3cml0ZXIpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICAgIGNhc2UgVEVYVCA6CisgICAgICAgICAgICAgICAgICAgIHdyaXRlci50ZXh0KChTdHJpbmcpIGNoaWxkKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICBjYXNlIElHTk9SQUJMRV9XSElURVNQQUNFIDoKKyAgICAgICAgICAgICAgICAgICAgd3JpdGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UoKFN0cmluZykgY2hpbGQpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICAgIGNhc2UgQ0RTRUNUIDoKKyAgICAgICAgICAgICAgICAgICAgd3JpdGVyLmNkc2VjdCgoU3RyaW5nKSBjaGlsZCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICAgICAgY2FzZSBDT01NRU5UIDoKKyAgICAgICAgICAgICAgICAgICAgd3JpdGVyLmNvbW1lbnQoKFN0cmluZykgY2hpbGQpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICAgIGNhc2UgRU5USVRZX1JFRiA6CisgICAgICAgICAgICAgICAgICAgIHdyaXRlci5lbnRpdHlSZWYoKFN0cmluZykgY2hpbGQpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICAgIGNhc2UgUFJPQ0VTU0lOR19JTlNUUlVDVElPTiA6CisgICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oKFN0cmluZykgY2hpbGQpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICAgIGNhc2UgRE9DREVDTCA6CisgICAgICAgICAgICAgICAgICAgIHdyaXRlci5kb2NkZWNsKChTdHJpbmcpIGNoaWxkKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICBkZWZhdWx0IDoKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIklsbGVnYWwgdHlwZTogIiArIHR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEveG1sL3NyYy9tYWluL2phdmEvb3JnL3htbC9UaGlyZFBhcnR5UHJvamVjdC5wcm9wIGIveG1sL3NyYy9tYWluL2phdmEvb3JnL3htbC9UaGlyZFBhcnR5UHJvamVjdC5wcm9wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI4YWMwZGEKLS0tIC9kZXYvbnVsbAorKysgYi94bWwvc3JjL21haW4vamF2YS9vcmcveG1sL1RoaXJkUGFydHlQcm9qZWN0LnByb3AKQEAgLTAsMCArMSw5IEBACisjIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisjRnJpIEp1bCAxNiAxMDowMzowOSBQRFQgMjAxMAorY3VycmVudFZlcnNpb249Mi4wLjIKK3ZlcnNpb249Mi4wLjIKK2lzTmF0aXZlPWZhbHNlCituYW1lPXhtbF9zYXhfcGFyc2VyCitrZXl3b3Jkcz14bWwgc2F4IHBhcnNlcgorb25EZXZpY2U9dHJ1ZQoraG9tZXBhZ2U9aHR0cFw6Ly93d3cuc2F4cHJvamVjdC5vcmcKZGlmZiAtLWdpdCBhL3htbC9zcmMvbWFpbi9qYXZhL29yZy94bWxwdWxsL1RoaXJkUGFydHlQcm9qZWN0LnByb3AgYi94bWwvc3JjL21haW4vamF2YS9vcmcveG1scHVsbC9UaGlyZFBhcnR5UHJvamVjdC5wcm9wCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjljY2JmMDkKLS0tIC9kZXYvbnVsbAorKysgYi94bWwvc3JjL21haW4vamF2YS9vcmcveG1scHVsbC9UaGlyZFBhcnR5UHJvamVjdC5wcm9wCkBAIC0wLDAgKzEsOSBAQAorIyBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgorI0ZyaSBKdWwgMTYgMTA6MDM6MDkgUERUIDIwMTAKK2N1cnJlbnRWZXJzaW9uPTEuMS4zLjRjCit2ZXJzaW9uPVVua25vd24KK2lzTmF0aXZlPWZhbHNlCituYW1lPXhtbF9wdWxsX3BhcnNlcgora2V5d29yZHM9eG1sIHB1bGwgcGFyc2VyCitvbkRldmljZT10cnVlCitob21lcGFnZT1odHRwXDovL3htbHB1bGwub3JnCmRpZmYgLS1naXQgYS94bWwvc3JjL21haW4vamF2YS9vcmcveG1scHVsbC92MS9YbWxQdWxsUGFyc2VyLmphdmEgYi94bWwvc3JjL21haW4vamF2YS9vcmcveG1scHVsbC92MS9YbWxQdWxsUGFyc2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzZlNjAyNQotLS0gL2Rldi9udWxsCisrKyBiL3htbC9zcmMvbWFpbi9qYXZhL29yZy94bWxwdWxsL3YxL1htbFB1bGxQYXJzZXIuamF2YQpAQCAtMCwwICsxLDExMTQgQEAKKy8qIC0qLSAgICAgICAgICAgICBjLWJhc2ljLW9mZnNldDogNDsgaW5kZW50LXRhYnMtbW9kZTogbmlsOyAtKi0gIC8vLS0tLS0tMTAwLWNvbHVtbnMtd2lkZS0tLS0tLT58Ki8KKy8vIGZvciBsaWNlbnNlIHBsZWFzZSBzZWUgYWNjb21wYW55aW5nIExJQ0VOU0UudHh0IGZpbGUgKGF2YWlsYWJsZSBhbHNvIGF0IGh0dHA6Ly93d3cueG1scHVsbC5vcmcvKQorCitwYWNrYWdlIG9yZy54bWxwdWxsLnYxOworCitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUmVhZGVyOworCisvKioKKyAqIFhNTCBQdWxsIFBhcnNlciBpcyBhbiBpbnRlcmZhY2UgdGhhdCBkZWZpbmVzIHBhcnNpbmcgZnVuY3Rpb25hbGl0eSBwcm92aWRlZAorICogaW4gPGEgaHJlZj0iaHR0cDovL3d3dy54bWxwdWxsLm9yZy8iPlhNTFBVTEwgVjEgQVBJPC9hPiAodmlzaXQgdGhpcyB3ZWJzaXRlIHRvCisgKiBsZWFybiBtb3JlIGFib3V0IEFQSSBhbmQgaXRzIGltcGxlbWVudGF0aW9ucykuCisgKgorICogPHA+VGhlcmUgYXJlIGZvbGxvd2luZyBkaWZmZXJlbnQKKyAqIGtpbmRzIG9mIHBhcnNlciBkZXBlbmRpbmcgb24gd2hpY2ggZmVhdHVyZXMgYXJlIHNldDo8dWw+CisgKiA8bGk+PGI+bm9uLXZhbGlkYXRpbmc8L2I+IHBhcnNlciBhcyBkZWZpbmVkIGluIFhNTCAxLjAgc3BlYyB3aGVuCisgKiAgIEZFQVRVUkVfUFJPQ0VTU19ET0NERUNMIGlzIHNldCB0byB0cnVlCisgKiA8bGk+PGI+dmFsaWRhdGluZyBwYXJzZXI8L2I+IGFzIGRlZmluZWQgaW4gWE1MIDEuMCBzcGVjIHdoZW4KKyAqICAgRkVBVFVSRV9WQUxJREFUSU9OIGlzIHRydWUgKGFuZCB0aGF0IGltcGxpZXMgdGhhdCBGRUFUVVJFX1BST0NFU1NfRE9DREVDTCBpcyB0cnVlKQorICogPGxpPndoZW4gRkVBVFVSRV9QUk9DRVNTX0RPQ0RFQ0wgaXMgZmFsc2UgKHRoaXMgaXMgZGVmYXVsdCBhbmQKKyAqICAgaWYgZGlmZmVyZW50IHZhbHVlIGlzIHJlcXVpcmVkIG5lY2Vzc2FyeSBtdXN0IGJlIGNoYW5nZWQgYmVmb3JlIHBhcnNpbmcgaXMgc3RhcnRlZCkKKyAqICAgdGhlbiBwYXJzZXIgYmVoYXZlcyBsaWtlIFhNTCAxLjAgY29tcGxpYW50IG5vbi12YWxpZGF0aW5nIHBhcnNlciB1bmRlciBjb25kaXRpb24gdGhhdAorICogIDxlbT5ubyBET0NERUNMIGlzIHByZXNlbnQ8L2VtPiBpbiBYTUwgZG9jdW1lbnRzCisgKiAgIChpbnRlcm5hbCBlbnRpdGVzIGNhbiBzdGlsbCBiZSBkZWZpbmVkIHdpdGggZGVmaW5lRW50aXR5UmVwbGFjZW1lbnRUZXh0KCkpLgorICogICBUaGlzIG1vZGUgb2Ygb3BlcmF0aW9uIGlzIGludGVuZGVkIDxiPmZvciBvcGVyYXRpb24gaW4gY29uc3RyYWluZWQgZW52aXJvbm1lbnRzPC9iPiBzdWNoIGFzIEoyTUUuCisgKiA8L3VsPgorICoKKyAqCisgKiA8cD5UaGVyZSBhcmUgdHdvIGtleSBtZXRob2RzOiBuZXh0KCkgYW5kIG5leHRUb2tlbigpLiBXaGlsZSBuZXh0KCkgcHJvdmlkZXMKKyAqIGFjY2VzcyB0byBoaWdoIGxldmVsIHBhcnNpbmcgZXZlbnRzLCBuZXh0VG9rZW4oKSBhbGxvd3MgYWNjZXNzIHRvIGxvd2VyCisgKiBsZXZlbCB0b2tlbnMuCisgKgorICogPHA+VGhlIGN1cnJlbnQgZXZlbnQgc3RhdGUgb2YgdGhlIHBhcnNlcgorICogY2FuIGJlIGRldGVybWluZWQgYnkgY2FsbGluZyB0aGUKKyAqIDxhIGhyZWY9IiNnZXRFdmVudFR5cGUoKSI+Z2V0RXZlbnRUeXBlKCk8L2E+IG1ldGhvZC4KKyAqIEluaXRpYWxseSwgdGhlIHBhcnNlciBpcyBpbiB0aGUgPGEgaHJlZj0iI1NUQVJUX0RPQ1VNRU5UIj5TVEFSVF9ET0NVTUVOVDwvYT4KKyAqIHN0YXRlLgorICoKKyAqIDxwPlRoZSBtZXRob2QgPGEgaHJlZj0iI25leHQoKSI+bmV4dCgpPC9hPiBhZHZhbmNlcyB0aGUgcGFyc2VyIHRvIHRoZQorICogbmV4dCBldmVudC4gVGhlIGludCB2YWx1ZSByZXR1cm5lZCBmcm9tIG5leHQgZGV0ZXJtaW5lcyB0aGUgY3VycmVudCBwYXJzZXIKKyAqIHN0YXRlIGFuZCBpcyBpZGVudGljYWwgdG8gdGhlIHZhbHVlIHJldHVybmVkIGZyb20gZm9sbG93aW5nIGNhbGxzIHRvCisgKiBnZXRFdmVudFR5cGUgKCkuCisgKgorICogPHA+VGggZm9sbG93aW5nIGV2ZW50IHR5cGVzIGFyZSBzZWVuIGJ5IG5leHQoKTxkbD4KKyAqIDxkdD48YSBocmVmPSIjU1RBUlRfVEFHIj5TVEFSVF9UQUc8L2E+PGRkPiBBbiBYTUwgc3RhcnQgdGFnIHdhcyByZWFkLgorICogPGR0PjxhIGhyZWY9IiNURVhUIj5URVhUPC9hPjxkZD4gVGV4dCBjb250ZW50IHdhcyByZWFkOworICogdGhlIHRleHQgY29udGVudCBjYW4gYmUgcmV0cmlldmVkIHVzaW5nIHRoZSBnZXRUZXh0KCkgbWV0aG9kLgorICogICh3aGVuIGluIHZhbGlkYXRpbmcgbW9kZSBuZXh0KCkgd2lsbCBub3QgcmVwb3J0IGlnbm9yYWJsZSB3aGl0ZXNwYWNlLCB1c2UgbmV4dFRva2VuKCkgaW5zdGVhZCkKKyAqIDxkdD48YSBocmVmPSIjRU5EX1RBRyI+RU5EX1RBRzwvYT48ZGQ+IEFuIGVuZCB0YWcgd2FzIHJlYWQKKyAqIDxkdD48YSBocmVmPSIjRU5EX0RPQ1VNRU5UIj5FTkRfRE9DVU1FTlQ8L2E+PGRkPiBObyBtb3JlIGV2ZW50cyBhcmUgYXZhaWxhYmxlCisgKiA8L2RsPgorICoKKyAqIDxwPmFmdGVyIGZpcnN0IG5leHQoKSBvciBuZXh0VG9rZW4oKSAob3IgYW55IG90aGVyIG5leHQqKCkgbWV0aG9kKQorICogaXMgY2FsbGVkIHVzZXIgYXBwbGljYXRpb24gY2FuIG9idGFpbgorICogWE1MIHZlcnNpb24sIHN0YW5kYWxvbmUgYW5kIGVuY29kaW5nIGZyb20gWE1MIGRlY2xhcmF0aW9uCisgKiBpbiBmb2xsb3dpbmcgd2F5czo8dWw+CisgKiA8bGk+PGI+dmVyc2lvbjwvYj46CisgKiAgZ2V0UHJvcGVydHkoJnF1b3Q7PGEgaHJlZj0iaHR0cDovL3htbHB1bGwub3JnL3YxL2RvYy9wcm9wZXJ0aWVzLmh0bWwjeG1sZGVjbC12ZXJzaW9uIj5odHRwOi8veG1scHVsbC5vcmcvdjEvZG9jL3Byb3BlcnRpZXMuaHRtbCN4bWxkZWNsLXZlcnNpb248L2E+JnF1b3Q7KQorICogICAgICAgcmV0dXJucyBTdHJpbmcgKCIxLjAiKSBvciBudWxsIGlmIFhNTERlY2wgd2FzIG5vdCByZWFkIG9yIGlmIHByb3BlcnR5IGlzIG5vdCBzdXBwb3J0ZWQKKyAqIDxsaT48Yj5zdGFuZGFsb25lPC9iPjoKKyAqICBnZXRQcm9wZXJ0eSgmcXVvdDs8YSBocmVmPSJodHRwOi8veG1scHVsbC5vcmcvdjEvZG9jL3Byb3BlcnRpZXMuaHRtbCN4bWxkZWNsLXN0YW5kYWxvbmUiPmh0dHA6Ly94bWxwdWxsLm9yZy92MS9kb2MvcHJvcGVydGllcy5odG1sI3htbGRlY2wtc3RhbmRhbG9uZTwvYT4mcXVvdDspCisgKiAgICAgICByZXR1cm5zIEJvb2xlYW46IG51bGwgaWYgdGhlcmUgd2FzIG5vIHN0YW5kYWxvbmUgZGVjbGFyYXRpb24KKyAqICBvciBpZiBwcm9wZXJ0eSBpcyBub3Qgc3VwcG9ydGVkCisgKiAgICAgICAgIG90aGVyd2lzZSByZXR1cm5zIEJvb2xlYW4odHJ1ZSkgaWYgc3RhbmRhbG9uZT0ieWVzIiBhbmQgQm9vbGVhbihmYWxzZSkgd2hlbiBzdGFuZGFsb25lPSJubyIKKyAqIDxsaT48Yj5lbmNvZGluZzwvYj46IG9idGFpbmVkIGZyb20gZ2V0SW5wdXRFbmNvZGluZygpCisgKiAgICAgICBudWxsIGlmIHN0cmVhbSBoYWQgdW5rbm93biBlbmNvZGluZyAobm90IHNldCBpbiBzZXRJbnB1dFN0cmVhbSkKKyAqICAgICAgICAgICBhbmQgaXQgd2FzIG5vdCBkZWNsYXJlZCBpbiBYTUxEZWNsCisgKiA8L3VsPgorICoKKyAqIEEgbWluaW1hbCBleGFtcGxlIGZvciB1c2luZyB0aGlzIEFQSSBtYXkgbG9vayBhcyBmb2xsb3dzOgorICogPHByZT4KKyAqIGltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworICogaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOworICoKKyAqIGltcG9ydCBvcmcueG1scHVsbC52MS5YbWxQdWxsUGFyc2VyOworICogaW1wb3J0IG9yZy54bWxwdWxsLnYxLjxhIGhyZWY9IlhtbFB1bGxQYXJzZXJFeGNlcHRpb24uaHRtbCI+WG1sUHVsbFBhcnNlckV4Y2VwdGlvbjwvYT47CisgKiBpbXBvcnQgb3JnLnhtbHB1bGwudjEuPGEgaHJlZj0iWG1sUHVsbFBhcnNlckZhY3RvcnkuaHRtbCI+WG1sUHVsbFBhcnNlckZhY3Rvcnk8L2E+OworICoKKyAqIHB1YmxpYyBjbGFzcyBTaW1wbGVYbWxQdWxsQXBwCisgKiB7CisgKgorICogICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluIChTdHJpbmcgYXJnc1tdKQorICogICAgICAgICB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiwgSU9FeGNlcHRpb24KKyAqICAgICB7CisgKiAgICAgICAgIFhtbFB1bGxQYXJzZXJGYWN0b3J5IGZhY3RvcnkgPSBYbWxQdWxsUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICogICAgICAgICBmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOworICogICAgICAgICBYbWxQdWxsUGFyc2VyIHhwcCA9IGZhY3RvcnkubmV3UHVsbFBhcnNlcigpOworICoKKyAqICAgICAgICAgeHBwLjxhIGhyZWY9IiNzZXRJbnB1dCI+c2V0SW5wdXQ8L2E+KCBuZXcgU3RyaW5nUmVhZGVyICggIiZsdDtmb28+SGVsbG8gV29ybGQhJmx0Oy9mb28+IiApICk7CisgKiAgICAgICAgIGludCBldmVudFR5cGUgPSB4cHAuZ2V0RXZlbnRUeXBlKCk7CisgKiAgICAgICAgIHdoaWxlIChldmVudFR5cGUgIT0gWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQpIHsKKyAqICAgICAgICAgIGlmKGV2ZW50VHlwZSA9PSBYbWxQdWxsUGFyc2VyLlNUQVJUX0RPQ1VNRU5UKSB7CisgKiAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJTdGFydCBkb2N1bWVudCIpOworICogICAgICAgICAgfSBlbHNlIGlmKGV2ZW50VHlwZSA9PSBYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRykgeworICogICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiU3RhcnQgdGFnICIreHBwLjxhIGhyZWY9IiNnZXROYW1lKCkiPmdldE5hbWUoKTwvYT4pOworICogICAgICAgICAgfSBlbHNlIGlmKGV2ZW50VHlwZSA9PSBYbWxQdWxsUGFyc2VyLkVORF9UQUcpIHsKKyAqICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVuZCB0YWcgIit4cHAuZ2V0TmFtZSgpKTsKKyAqICAgICAgICAgIH0gZWxzZSBpZihldmVudFR5cGUgPT0gWG1sUHVsbFBhcnNlci5URVhUKSB7CisgKiAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUZXh0ICIreHBwLjxhIGhyZWY9IiNnZXRUZXh0KCkiPmdldFRleHQoKTwvYT4pOworICogICAgICAgICAgfQorICogICAgICAgICAgZXZlbnRUeXBlID0geHBwLm5leHQoKTsKKyAqICAgICAgICAgfQorICogICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVuZCBkb2N1bWVudCIpOworICogICAgIH0KKyAqIH0KKyAqIDwvcHJlPgorICoKKyAqIDxwPlRoZSBhYm92ZSBleGFtcGxlIHdpbGwgZ2VuZXJhdGUgdGhlIGZvbGxvd2luZyBvdXRwdXQ6CisgKiA8cHJlPgorICogU3RhcnQgZG9jdW1lbnQKKyAqIFN0YXJ0IHRhZyBmb28KKyAqIFRleHQgSGVsbG8gV29ybGQhCisgKiBFbmQgdGFnIGZvbworICogPC9wcmU+CisgKgorICogPHA+Rm9yIG1vcmUgZGV0YWlscyBvbiBBUEkgdXNhZ2UsIHBsZWFzZSByZWZlciB0byB0aGUKKyAqIHF1aWNrIEludHJvZHVjdGlvbiBhdmFpbGFibGUgYXQgPGEgaHJlZj0iaHR0cDovL3d3dy54bWxwdWxsLm9yZyI+aHR0cDovL3d3dy54bWxwdWxsLm9yZzwvYT4KKyAqCisgKiBAc2VlIFhtbFB1bGxQYXJzZXJGYWN0b3J5CisgKiBAc2VlICNkZWZpbmVFbnRpdHlSZXBsYWNlbWVudFRleHQKKyAqIEBzZWUgI2dldE5hbWUKKyAqIEBzZWUgI2dldE5hbWVzcGFjZQorICogQHNlZSAjZ2V0VGV4dAorICogQHNlZSAjbmV4dAorICogQHNlZSAjbmV4dFRva2VuCisgKiBAc2VlICNzZXRJbnB1dAorICogQHNlZSAjRkVBVFVSRV9QUk9DRVNTX0RPQ0RFQ0wKKyAqIEBzZWUgI0ZFQVRVUkVfVkFMSURBVElPTgorICogQHNlZSAjU1RBUlRfRE9DVU1FTlQKKyAqIEBzZWUgI1NUQVJUX1RBRworICogQHNlZSAjVEVYVAorICogQHNlZSAjRU5EX1RBRworICogQHNlZSAjRU5EX0RPQ1VNRU5UCisgKgorICogQGF1dGhvciA8YSBocmVmPSJodHRwOi8vd3d3LWFpLmNzLnVuaS1kb3J0bXVuZC5kZS9QRVJTT05BTC9oYXVzdGVpbi5odG1sIj5TdGVmYW4gSGF1c3RlaW48L2E+CisgKiBAYXV0aG9yIDxhIGhyZWY9Imh0dHA6Ly93d3cuZXh0cmVtZS5pbmRpYW5hLmVkdS9+YXNsb20vIj5BbGVrc2FuZGVyIFNsb21pbnNraTwvYT4KKyAqLworCitwdWJsaWMgaW50ZXJmYWNlIFhtbFB1bGxQYXJzZXIgeworCisgICAgLyoqIFRoaXMgY29uc3RhbnQgcmVwcmVzZW50cyB0aGUgZGVmYXVsdCBuYW1lc3BhY2UgKGVtcHR5IHN0cmluZyAiIikgKi8KKyAgICBTdHJpbmcgTk9fTkFNRVNQQUNFID0gIiI7CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gRVZFTlQgVFlQRVMgYXMgcmVwb3J0ZWQgYnkgbmV4dCgpCisKKyAgICAvKioKKyAgICAgKiBTaWduYWxpemUgdGhhdCBwYXJzZXIgaXMgYXQgdGhlIHZlcnkgYmVnaW5uaW5nIG9mIHRoZSBkb2N1bWVudAorICAgICAqIGFuZCBub3RoaW5nIHdhcyByZWFkIHlldC4KKyAgICAgKiBUaGlzIGV2ZW50IHR5cGUgY2FuIG9ubHkgYmUgb2JzZXJ2ZWQgYnkgY2FsbGluZyBnZXRFdmVudCgpCisgICAgICogYmVmb3JlIHRoZSBmaXJzdCBjYWxsIHRvIG5leHQoKSwgbmV4dFRva2VuLCBvciBuZXh0VGFnKCk8L2E+KS4KKyAgICAgKgorICAgICAqIEBzZWUgI25leHQKKyAgICAgKiBAc2VlICNuZXh0VG9rZW4KKyAgICAgKi8KKyAgICBpbnQgU1RBUlRfRE9DVU1FTlQgPSAwOworCisgICAgLyoqCisgICAgICogTG9naWNhbCBlbmQgb2YgdGhlIHhtbCBkb2N1bWVudC4gUmV0dXJuZWQgZnJvbSBnZXRFdmVudFR5cGUsIG5leHQoKQorICAgICAqIGFuZCBuZXh0VG9rZW4oKQorICAgICAqIHdoZW4gdGhlIGVuZCBvZiB0aGUgaW5wdXQgZG9jdW1lbnQgaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKiA8cD48c3Ryb25nPk5PVEU6PC9zdHJvbmc+IGNhbGxpbmcgYWdhaW4KKyAgICAgKiA8YSBocmVmPSIjbmV4dCgpIj5uZXh0KCk8L2E+IG9yIDxhIGhyZWY9IiNuZXh0VG9rZW4oKSI+bmV4dFRva2VuKCk8L2E+CisgICAgICogd2lsbCByZXN1bHQgaW4gZXhjZXB0aW9uIGJlaW5nIHRocm93bi4KKyAgICAgKgorICAgICAqIEBzZWUgI25leHQKKyAgICAgKiBAc2VlICNuZXh0VG9rZW4KKyAgICAgKi8KKyAgICBpbnQgRU5EX0RPQ1VNRU5UID0gMTsKKworICAgIC8qKgorICAgICAqIFJldHVybmVkIGZyb20gZ2V0RXZlbnRUeXBlKCksCisgICAgICogPGEgaHJlZj0iI25leHQoKSI+bmV4dCgpPC9hPiwgPGEgaHJlZj0iI25leHRUb2tlbigpIj5uZXh0VG9rZW4oKTwvYT4gd2hlbgorICAgICAqIGEgc3RhcnQgdGFnIHdhcyByZWFkLgorICAgICAqIFRoZSBuYW1lIG9mIHN0YXJ0IHRhZyBpcyBhdmFpbGFibGUgZnJvbSBnZXROYW1lKCksIGl0cyBuYW1lc3BhY2UgYW5kIHByZWZpeCBhcmUKKyAgICAgKiBhdmFpbGFibGUgZnJvbSBnZXROYW1lc3BhY2UoKSBhbmQgZ2V0UHJlZml4KCkKKyAgICAgKiBpZiA8YSBocmVmPScjRkVBVFVSRV9QUk9DRVNTX05BTUVTUEFDRVMnPm5hbWVzcGFjZXMgYXJlIGVuYWJsZWQ8L2E+LgorICAgICAqIFNlZSBnZXRBdHRyaWJ1dGUqIG1ldGhvZHMgdG8gcmV0cmlldmUgZWxlbWVudCBhdHRyaWJ1dGVzLgorICAgICAqIFNlZSBnZXROYW1lc3BhY2UqIG1ldGhvZHMgdG8gcmV0cmlldmUgbmV3bHkgZGVjbGFyZWQgbmFtZXNwYWNlcy4KKyAgICAgKgorICAgICAqIEBzZWUgI25leHQKKyAgICAgKiBAc2VlICNuZXh0VG9rZW4KKyAgICAgKiBAc2VlICNnZXROYW1lCisgICAgICogQHNlZSAjZ2V0UHJlZml4CisgICAgICogQHNlZSAjZ2V0TmFtZXNwYWNlCisgICAgICogQHNlZSAjZ2V0QXR0cmlidXRlQ291bnQKKyAgICAgKiBAc2VlICNnZXREZXB0aAorICAgICAqIEBzZWUgI2dldE5hbWVzcGFjZUNvdW50CisgICAgICogQHNlZSAjZ2V0TmFtZXNwYWNlCisgICAgICogQHNlZSAjRkVBVFVSRV9QUk9DRVNTX05BTUVTUEFDRVMKKyAgICAgKi8KKyAgICBpbnQgU1RBUlRfVEFHID0gMjsKKworICAgIC8qKgorICAgICAqIFJldHVybmVkIGZyb20gZ2V0RXZlbnRUeXBlKCksIDxhIGhyZWY9IiNuZXh0KCkiPm5leHQoKTwvYT4sIG9yCisgICAgICogPGEgaHJlZj0iI25leHRUb2tlbigpIj5uZXh0VG9rZW4oKTwvYT4gd2hlbiBhbiBlbmQgdGFnIHdhcyByZWFkLgorICAgICAqIFRoZSBuYW1lIG9mIHN0YXJ0IHRhZyBpcyBhdmFpbGFibGUgZnJvbSBnZXROYW1lKCksIGl0cworICAgICAqIG5hbWVzcGFjZSBhbmQgcHJlZml4IGFyZQorICAgICAqIGF2YWlsYWJsZSBmcm9tIGdldE5hbWVzcGFjZSgpIGFuZCBnZXRQcmVmaXgoKS4KKyAgICAgKgorICAgICAqIEBzZWUgI25leHQKKyAgICAgKiBAc2VlICNuZXh0VG9rZW4KKyAgICAgKiBAc2VlICNnZXROYW1lCisgICAgICogQHNlZSAjZ2V0UHJlZml4CisgICAgICogQHNlZSAjZ2V0TmFtZXNwYWNlCisgICAgICogQHNlZSAjRkVBVFVSRV9QUk9DRVNTX05BTUVTUEFDRVMKKyAgICAgKi8KKyAgICBpbnQgRU5EX1RBRyA9IDM7CisKKworICAgIC8qKgorICAgICAqIENoYXJhY3RlciBkYXRhIHdhcyByZWFkIGFuZCB3aWxsIGlzIGF2YWlsYWJsZSBieSBjYWxsaW5nIGdldFRleHQoKS4KKyAgICAgKiA8cD48c3Ryb25nPlBsZWFzZSBub3RlOjwvc3Ryb25nPiA8YSBocmVmPSIjbmV4dCgpIj5uZXh0KCk8L2E+IHdpbGwKKyAgICAgKiBhY2N1bXVsYXRlIG11bHRpcGxlCisgICAgICogZXZlbnRzIGludG8gb25lIFRFWFQgZXZlbnQsIHNraXBwaW5nIElHTk9SQUJMRV9XSElURVNQQUNFLAorICAgICAqIFBST0NFU1NJTkdfSU5TVFJVQ1RJT04gYW5kIENPTU1FTlQgZXZlbnRzLAorICAgICAqIEluIGNvbnRyYXN0LCA8YSBocmVmPSIjbmV4dFRva2VuKCkiPm5leHRUb2tlbigpPC9hPiB3aWxsIHN0b3AgcmVhZGluZworICAgICAqIHRleHQgd2hlbiBhbnkgb3RoZXIgZXZlbnQgaXMgb2JzZXJ2ZWQuCisgICAgICogQWxzbywgd2hlbiB0aGUgc3RhdGUgd2FzIHJlYWNoZWQgYnkgY2FsbGluZyBuZXh0KCksIHRoZSB0ZXh0IHZhbHVlIHdpbGwKKyAgICAgKiBiZSBub3JtYWxpemVkLCB3aGVyZWFzIGdldFRleHQoKSB3aWxsCisgICAgICogcmV0dXJuIHVubm9ybWFsaXplZCBjb250ZW50IGluIHRoZSBjYXNlIG9mIG5leHRUb2tlbigpLiBUaGlzIGFsbG93cworICAgICAqIGFuIGV4YWN0IHJvdW5kdHJpcCB3aXRob3V0IGNoYW5naW5nIGxpbmUgZW5kcyB3aGVuIGV4YW1pbmluZyBsb3cKKyAgICAgKiBsZXZlbCBldmVudHMsIHdoZXJlYXMgZm9yIGhpZ2ggbGV2ZWwgYXBwbGljYXRpb25zIHRoZSB0ZXh0IGlzCisgICAgICogbm9ybWFsaXplZCBhcHByb3ByaWF0ZWx5LgorICAgICAqCisgICAgICogQHNlZSAjbmV4dAorICAgICAqIEBzZWUgI25leHRUb2tlbgorICAgICAqIEBzZWUgI2dldFRleHQKKyAgICAgKi8KKyAgICBpbnQgVEVYVCA9IDQ7CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gYWRkaXRpb25hbCBldmVudHMgZXhwb3NlZCBieSBsb3dlciBsZXZlbCBuZXh0VG9rZW4oKQorCisgICAgLyoqCisgICAgICogQSBDREFUQSBzZWN0aW9ucyB3YXMganVzdCByZWFkOworICAgICAqIHRoaXMgdG9rZW4gaXMgYXZhaWxhYmxlIG9ubHkgZnJvbSBjYWxscyB0byA8YSBocmVmPSIjbmV4dFRva2VuKCkiPm5leHRUb2tlbigpPC9hPi4KKyAgICAgKiBBIGNhbGwgdG8gbmV4dCgpIHdpbGwgYWNjdW11bGF0ZSB2YXJpb3VzIHRleHQgZXZlbnRzIGludG8gYSBzaW5nbGUgZXZlbnQKKyAgICAgKiBvZiB0eXBlIFRFWFQuIFRoZSB0ZXh0IGNvbnRhaW5lZCBpbiB0aGUgQ0RBVEEgc2VjdGlvbiBpcyBhdmFpbGFibGUKKyAgICAgKiBieSBjYWxsaW5nIGdldFRleHQoKS4KKyAgICAgKgorICAgICAqIEBzZWUgI25leHRUb2tlbgorICAgICAqIEBzZWUgI2dldFRleHQKKyAgICAgKi8KKyAgICBpbnQgQ0RTRUNUID0gNTsKKworICAgIC8qKgorICAgICAqIEFuIGVudGl0eSByZWZlcmVuY2Ugd2FzIGp1c3QgcmVhZDsKKyAgICAgKiB0aGlzIHRva2VuIGlzIGF2YWlsYWJsZSBmcm9tIDxhIGhyZWY9IiNuZXh0VG9rZW4oKSI+bmV4dFRva2VuKCk8L2E+CisgICAgICogb25seS4gVGhlIGVudGl0eSBuYW1lIGlzIGF2YWlsYWJsZSBieSBjYWxsaW5nIGdldE5hbWUoKS4gSWYgYXZhaWxhYmxlLAorICAgICAqIHRoZSByZXBsYWNlbWVudCB0ZXh0IGNhbiBiZSBvYnRhaW5lZCBieSBjYWxsaW5nIGdldFRleHQoKTsgb3RoZXJ3aXNlLAorICAgICAqIHRoZSB1c2VyIGlzIHJlc3BvbnNpYmxlIGZvciByZXNvbHZpbmcgdGhlIGVudGl0eSByZWZlcmVuY2UuCisgICAgICogVGhpcyBldmVudCB0eXBlIGlzIG5ldmVyIHJldHVybmVkIGZyb20gbmV4dCgpOyBuZXh0KCkgd2lsbAorICAgICAqIGFjY3VtdWxhdGUgdGhlIHJlcGxhY2VtZW50IHRleHQgYW5kIG90aGVyIHRleHQKKyAgICAgKiBldmVudHMgdG8gYSBzaW5nbGUgVEVYVCBldmVudC4KKyAgICAgKgorICAgICAqIEBzZWUgI25leHRUb2tlbgorICAgICAqIEBzZWUgI2dldFRleHQKKyAgICAgKi8KKyAgICBpbnQgRU5USVRZX1JFRiA9IDY7CisKKyAgICAvKioKKyAgICAgKiBJZ25vcmFibGUgd2hpdGVzcGFjZSB3YXMganVzdCByZWFkLgorICAgICAqIFRoaXMgdG9rZW4gaXMgYXZhaWxhYmxlIG9ubHkgZnJvbSA8YSBocmVmPSIjbmV4dFRva2VuKCkiPm5leHRUb2tlbigpPC9hPikuCisgICAgICogRm9yIG5vbi12YWxpZGF0aW5nCisgICAgICogcGFyc2VycywgdGhpcyBldmVudCBpcyBvbmx5IHJlcG9ydGVkIGJ5IG5leHRUb2tlbigpIHdoZW4gb3V0c2lkZQorICAgICAqIHRoZSByb290IGVsZW1lbnQuCisgICAgICogVmFsaWRhdGluZyBwYXJzZXJzIG1heSBiZSBhYmxlIHRvIGRldGVjdCBpZ25vcmFibGUgd2hpdGVzcGFjZSBhdAorICAgICAqIG90aGVyIGxvY2F0aW9ucy4KKyAgICAgKiBUaGUgaWdub3JhYmxlIHdoaXRlc3BhY2Ugc3RyaW5nIGlzIGF2YWlsYWJsZSBieSBjYWxsaW5nIGdldFRleHQoKQorICAgICAqCisgICAgICogPHA+PHN0cm9uZz5OT1RFOjwvc3Ryb25nPiB0aGlzIGlzIGRpZmZlcmVudCBmcm9tIGNhbGxpbmcgdGhlCisgICAgICogIGlzV2hpdGVzcGFjZSgpIG1ldGhvZCwgc2luY2UgdGV4dCBjb250ZW50CisgICAgICogIG1heSBiZSB3aGl0ZXNwYWNlIGJ1dCBub3QgaWdub3JhYmxlLgorICAgICAqCisgICAgICogSWdub3JhYmxlIHdoaXRlc3BhY2UgaXMgc2tpcHBlZCBieSBuZXh0KCkgYXV0b21hdGljYWxseTsgdGhpcyBldmVudAorICAgICAqIHR5cGUgaXMgbmV2ZXIgcmV0dXJuZWQgZnJvbSBuZXh0KCkuCisgICAgICoKKyAgICAgKiBAc2VlICNuZXh0VG9rZW4KKyAgICAgKiBAc2VlICNnZXRUZXh0CisgICAgICovCisgICAgaW50IElHTk9SQUJMRV9XSElURVNQQUNFID0gNzsKKworICAgIC8qKgorICAgICAqIEFuIFhNTCBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGRlY2xhcmF0aW9uIHdhcyBqdXN0IHJlYWQuIFRoaXMKKyAgICAgKiBldmVudCB0eXBlIGlzIGF2YWlsYWJsZSBvbmx5IHZpYSA8YSBocmVmPSIjbmV4dFRva2VuKCkiPm5leHRUb2tlbigpPC9hPi4KKyAgICAgKiBnZXRUZXh0KCkgd2lsbCByZXR1cm4gdGV4dCB0aGF0IGlzIGluc2lkZSB0aGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4KKyAgICAgKiBDYWxscyB0byBuZXh0KCkgd2lsbCBza2lwIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIGF1dG9tYXRpY2FsbHkuCisgICAgICogQHNlZSAjbmV4dFRva2VuCisgICAgICogQHNlZSAjZ2V0VGV4dAorICAgICAqLworICAgIGludCBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OID0gODsKKworICAgIC8qKgorICAgICAqIEFuIFhNTCBjb21tZW50IHdhcyBqdXN0IHJlYWQuIFRoaXMgZXZlbnQgdHlwZSBpcyB0aGlzIHRva2VuIGlzCisgICAgICogYXZhaWxhYmxlIHZpYSA8YSBocmVmPSIjbmV4dFRva2VuKCkiPm5leHRUb2tlbigpPC9hPiBvbmx5OworICAgICAqIGNhbGxzIHRvIG5leHQoKSB3aWxsIHNraXAgY29tbWVudHMgYXV0b21hdGljYWxseS4KKyAgICAgKiBUaGUgY29udGVudCBvZiB0aGUgY29tbWVudCBjYW4gYmUgYWNjZXNzZWQgdXNpbmcgdGhlIGdldFRleHQoKQorICAgICAqIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBzZWUgI25leHRUb2tlbgorICAgICAqIEBzZWUgI2dldFRleHQKKyAgICAgKi8KKyAgICBpbnQgQ09NTUVOVCA9IDk7CisKKyAgICAvKioKKyAgICAgKiBBbiBYTUwgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiB3YXMganVzdCByZWFkLiBUaGlzIHRva2VuIGlzCisgICAgICogYXZhaWxhYmxlIGZyb20gPGEgaHJlZj0iI25leHRUb2tlbigpIj5uZXh0VG9rZW4oKTwvYT4gb25seS4KKyAgICAgKiBUaGUgdW5wYXJzZWQgdGV4dCBpbnNpZGUgdGhlIGRvY3R5cGUgaXMgYXZhaWxhYmxlIHZpYQorICAgICAqIHRoZSBnZXRUZXh0KCkgbWV0aG9kLgorICAgICAqCisgICAgICogQHNlZSAjbmV4dFRva2VuCisgICAgICogQHNlZSAjZ2V0VGV4dAorICAgICAqLworICAgIGludCBET0NERUNMID0gMTA7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGFycmF5IGNhbiBiZSB1c2VkIHRvIGNvbnZlcnQgdGhlIGV2ZW50IHR5cGUgaW50ZWdlciBjb25zdGFudHMKKyAgICAgKiBzdWNoIGFzIFNUQVJUX1RBRyBvciBURVhUIHRvCisgICAgICogdG8gYSBzdHJpbmcuIEZvciBleGFtcGxlLCB0aGUgdmFsdWUgb2YgVFlQRVNbU1RBUlRfVEFHXSBpcworICAgICAqIHRoZSBzdHJpbmcgIlNUQVJUX1RBRyIuCisgICAgICoKKyAgICAgKiBUaGlzIGFycmF5IGlzIGludGVuZGVkIGZvciBkaWFnbm9zdGljIG91dHB1dCBvbmx5LiBSZWx5aW5nCisgICAgICogb24gdGhlIGNvbnRlbnRzIG9mIHRoZSBhcnJheSBtYXkgYmUgZGFuZ2Vyb3VzIHNpbmNlIG1hbGljaW91cworICAgICAqIGFwcGxpY2F0aW9ucyBtYXkgYWx0ZXIgdGhlIGFycmF5LCBhbHRob3VnaCBpdCBpcyBmaW5hbCwgZHVlCisgICAgICogdG8gbGltaXRhdGlvbnMgb2YgdGhlIEphdmEgbGFuZ3VhZ2UuCisgICAgICovCisgICAgU3RyaW5nIFtdIFRZUEVTID0geworICAgICAgICAiU1RBUlRfRE9DVU1FTlQiLAorICAgICAgICAgICAgIkVORF9ET0NVTUVOVCIsCisgICAgICAgICAgICAiU1RBUlRfVEFHIiwKKyAgICAgICAgICAgICJFTkRfVEFHIiwKKyAgICAgICAgICAgICJURVhUIiwKKyAgICAgICAgICAgICJDRFNFQ1QiLAorICAgICAgICAgICAgIkVOVElUWV9SRUYiLAorICAgICAgICAgICAgIklHTk9SQUJMRV9XSElURVNQQUNFIiwKKyAgICAgICAgICAgICJQUk9DRVNTSU5HX0lOU1RSVUNUSU9OIiwKKyAgICAgICAgICAgICJDT01NRU5UIiwKKyAgICAgICAgICAgICJET0NERUNMIgorICAgIH07CisKKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAvLyBuYW1lc3BhY2UgcmVsYXRlZCBmZWF0dXJlcworCisgICAgLyoqCisgICAgICogVGhpcyBmZWF0dXJlIGRldGVybWluZXMgd2hldGhlciB0aGUgcGFyc2VyIHByb2Nlc3NlcworICAgICAqIG5hbWVzcGFjZXMuIEFzIGZvciBhbGwgZmVhdHVyZXMsIHRoZSBkZWZhdWx0IHZhbHVlIGlzIGZhbHNlLgorICAgICAqIDxwPjxzdHJvbmc+Tk9URTo8L3N0cm9uZz4gVGhlIHZhbHVlIGNhbiBub3QgYmUgY2hhbmdlZCBkdXJpbmcKKyAgICAgKiBwYXJzaW5nIGFuIG11c3QgYmUgc2V0IGJlZm9yZSBwYXJzaW5nLgorICAgICAqCisgICAgICogQHNlZSAjZ2V0RmVhdHVyZQorICAgICAqIEBzZWUgI3NldEZlYXR1cmUKKyAgICAgKi8KKyAgICBTdHJpbmcgRkVBVFVSRV9QUk9DRVNTX05BTUVTUEFDRVMgPQorICAgICAgICAiaHR0cDovL3htbHB1bGwub3JnL3YxL2RvYy9mZWF0dXJlcy5odG1sI3Byb2Nlc3MtbmFtZXNwYWNlcyI7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGZlYXR1cmUgZGV0ZXJtaW5lcyB3aGV0aGVyIG5hbWVzcGFjZSBhdHRyaWJ1dGVzIGFyZQorICAgICAqIGV4cG9zZWQgdmlhIHRoZSBhdHRyaWJ1dGUgYWNjZXNzIG1ldGhvZHMuIExpa2UgYWxsIGZlYXR1cmVzLAorICAgICAqIHRoZSBkZWZhdWx0IHZhbHVlIGlzIGZhbHNlLiBUaGlzIGZlYXR1cmUgY2Fubm90IGJlIGNoYW5nZWQKKyAgICAgKiBkdXJpbmcgcGFyc2luZy4KKyAgICAgKgorICAgICAqIEBzZWUgI2dldEZlYXR1cmUKKyAgICAgKiBAc2VlICNzZXRGZWF0dXJlCisgICAgICovCisgICAgU3RyaW5nIEZFQVRVUkVfUkVQT1JUX05BTUVTUEFDRV9BVFRSSUJVVEVTID0KKyAgICAgICAgImh0dHA6Ly94bWxwdWxsLm9yZy92MS9kb2MvZmVhdHVyZXMuaHRtbCNyZXBvcnQtbmFtZXNwYWNlLXByZWZpeGVzIjsKKworICAgIC8qKgorICAgICAqIFRoaXMgZmVhdHVyZSBkZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGRvY3VtZW50IGRlY2xhcmF0aW9uCisgICAgICogaXMgcHJvY2Vzc2VkLiBJZiBzZXQgdG8gZmFsc2UsCisgICAgICogdGhlIERPQ0RFQ0wgZXZlbnQgdHlwZSBpcyByZXBvcnRlZCBieSBuZXh0VG9rZW4oKQorICAgICAqIGFuZCBpZ25vcmVkIGJ5IG5leHQoKS4KKyAgICAgKgorICAgICAqIElmIHRoaXMgZmVhdHVyZSBpcyBhY3RpdmF0ZWQsIHRoZW4gdGhlIGRvY3VtZW50IGRlY2xhcmF0aW9uCisgICAgICogbXVzdCBiZSBwcm9jZXNzZWQgYnkgdGhlIHBhcnNlci4KKyAgICAgKgorICAgICAqIDxwPjxzdHJvbmc+UGxlYXNlIG5vdGU6PC9zdHJvbmc+IElmIHRoZSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uCisgICAgICogd2FzIGlnbm9yZWQsIGVudGl0eSByZWZlcmVuY2VzIG1heSBjYXVzZSBleGNlcHRpb25zCisgICAgICogbGF0ZXIgaW4gdGhlIHBhcnNpbmcgcHJvY2Vzcy4KKyAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGlzIGZlYXR1cmUgaXMgZmFsc2UuIEl0IGNhbm5vdCBiZSBjaGFuZ2VkCisgICAgICogZHVyaW5nIHBhcnNpbmcuCisgICAgICoKKyAgICAgKiBAc2VlICNnZXRGZWF0dXJlCisgICAgICogQHNlZSAjc2V0RmVhdHVyZQorICAgICAqLworICAgIFN0cmluZyBGRUFUVVJFX1BST0NFU1NfRE9DREVDTCA9CisgICAgICAgICJodHRwOi8veG1scHVsbC5vcmcvdjEvZG9jL2ZlYXR1cmVzLmh0bWwjcHJvY2Vzcy1kb2NkZWNsIjsKKworICAgIC8qKgorICAgICAqIElmIHRoaXMgZmVhdHVyZSBpcyBhY3RpdmF0ZWQsIGFsbCB2YWxpZGF0aW9uIGVycm9ycyBhcworICAgICAqIGRlZmluZWQgaW4gdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbiBhcmUgcmVwb3J0ZWQuCisgICAgICogVGhpcyBpbXBsaWVzIHRoYXQgRkVBVFVSRV9QUk9DRVNTX0RPQ0RFQ0wgaXMgdHJ1ZSBhbmQgYm90aCwgdGhlCisgICAgICogaW50ZXJuYWwgYW5kIGV4dGVybmFsIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24gd2lsbCBiZSBwcm9jZXNzZWQuCisgICAgICogPHA+PHN0cm9uZz5QbGVhc2UgTm90ZTo8L3N0cm9uZz4gVGhpcyBmZWF0dXJlIGNhbiBub3QgYmUgY2hhbmdlZAorICAgICAqIGR1cmluZyBwYXJzaW5nLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBmYWxzZS4KKyAgICAgKgorICAgICAqIEBzZWUgI2dldEZlYXR1cmUKKyAgICAgKiBAc2VlICNzZXRGZWF0dXJlCisgICAgICovCisgICAgU3RyaW5nIEZFQVRVUkVfVkFMSURBVElPTiA9CisgICAgICAgICJodHRwOi8veG1scHVsbC5vcmcvdjEvZG9jL2ZlYXR1cmVzLmh0bWwjdmFsaWRhdGlvbiI7CisKKyAgICAvKioKKyAgICAgKiBVc2UgdGhpcyBjYWxsIHRvIGNoYW5nZSB0aGUgZ2VuZXJhbCBiZWhhdmlvdXIgb2YgdGhlIHBhcnNlciwKKyAgICAgKiBzdWNoIGFzIG5hbWVzcGFjZSBwcm9jZXNzaW5nIG9yIGRvY3R5cGUgZGVjbGFyYXRpb24gaGFuZGxpbmcuCisgICAgICogVGhpcyBtZXRob2QgbXVzdCBiZSBjYWxsZWQgYmVmb3JlIHRoZSBmaXJzdCBjYWxsIHRvIG5leHQgb3IKKyAgICAgKiBuZXh0VG9rZW4uIE90aGVyd2lzZSwgYW4gZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKiA8cD5FeGFtcGxlOiBjYWxsIHNldEZlYXR1cmUoRkVBVFVSRV9QUk9DRVNTX05BTUVTUEFDRVMsIHRydWUpIGluIG9yZGVyCisgICAgICogdG8gc3dpdGNoIG9uIG5hbWVzcGFjZSBwcm9jZXNzaW5nLiBUaGUgaW5pdGlhbCBzZXR0aW5ncyBjb3JyZXNwb25kCisgICAgICogdG8gdGhlIHByb3BlcnRpZXMgcmVxdWVzdGVkIGZyb20gdGhlIFhNTCBQdWxsIFBhcnNlciBmYWN0b3J5LgorICAgICAqIElmIG5vbmUgd2VyZSByZXF1ZXN0ZWQsIGFsbCBmZWF0dXJlcyBhcmUgZGVhY3RpdmF0ZWQgYnkgZGVmYXVsdC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiBJZiB0aGUgZmVhdHVyZSBpcyBub3Qgc3VwcG9ydGVkIG9yIGNhbiBub3QgYmUgc2V0CisgICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgc3RyaW5nIHdpdGggdGhlIGZlYXR1cmUgbmFtZSBpcyBudWxsCisgICAgICovCisgICAgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBzdGF0ZSkgdGhyb3dzIFhtbFB1bGxQYXJzZXJFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBnaXZlbiBmZWF0dXJlLgorICAgICAqIDxwPjxzdHJvbmc+UGxlYXNlIG5vdGU6PC9zdHJvbmc+IHVua25vd24gZmVhdHVyZXMgYXJlCisgICAgICogPHN0cm9uZz5hbHdheXM8L3N0cm9uZz4gcmV0dXJuZWQgYXMgZmFsc2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiBmZWF0dXJlIHRvIGJlIHJldHJpZXZlZC4KKyAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgZmVhdHVyZS4KKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBzdHJpbmcgdGhlIGZlYXR1cmUgbmFtZSBpcyBudWxsCisgICAgICovCisKKyAgICBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpOworCisgICAgLyoqCisgICAgICogU2V0IHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LgorICAgICAqCisgICAgICogVGhlIHByb3BlcnR5IG5hbWUgaXMgYW55IGZ1bGx5LXF1YWxpZmllZCBVUkkuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24gSWYgdGhlIHByb3BlcnR5IGlzIG5vdCBzdXBwb3J0ZWQgb3IgY2FuIG5vdCBiZSBzZXQKKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiBzdHJpbmcgd2l0aCB0aGUgcHJvcGVydHkgbmFtZSBpcyBudWxsCisgICAgICovCisgICAgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgdmFsdWUpIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogTG9vayB1cCB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIFRoZSBwcm9wZXJ0eSBuYW1lIGlzIGFueSBmdWxseS1xdWFsaWZpZWQgVVJJLgorICAgICAqIDxwPjxzdHJvbmc+Tk9URTo8L3N0cm9uZz4gdW5rbm93biBwcm9wZXJ0aWVzIGFyZSA8c3Ryb25nPmFsd2F5czwvc3Ryb25nPgorICAgICAqIHJldHVybmVkIGFzIG51bGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiBwcm9wZXJ0eSB0byBiZSByZXRyaWV2ZWQuCisgICAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgbmFtZWQgcHJvcGVydHkuCisgICAgICovCisgICAgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBuYW1lKTsKKworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBpbnB1dCBzb3VyY2UgZm9yIHBhcnNlciB0byB0aGUgZ2l2ZW4gcmVhZGVyIGFuZAorICAgICAqIHJlc2V0cyB0aGUgcGFyc2VyLiBUaGUgZXZlbnQgdHlwZSBpcyBzZXQgdG8gdGhlIGluaXRpYWwgdmFsdWUKKyAgICAgKiBTVEFSVF9ET0NVTUVOVC4KKyAgICAgKiBTZXR0aW5nIHRoZSByZWFkZXIgdG8gbnVsbCB3aWxsIGp1c3Qgc3RvcCBwYXJzaW5nIGFuZAorICAgICAqIHJlc2V0IHBhcnNlciBzdGF0ZSwKKyAgICAgKiBhbGxvd2luZyB0aGUgcGFyc2VyIHRvIGZyZWUgaW50ZXJuYWwgcmVzb3VyY2VzCisgICAgICogc3VjaCBhcyBwYXJzaW5nIGJ1ZmZlcnMuCisgICAgICovCisgICAgdm9pZCBzZXRJbnB1dChSZWFkZXIgaW4pIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uOworCisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBpbnB1dCBzdHJlYW0gdGhlIHBhcnNlciBpcyBnb2luZyB0byBwcm9jZXNzLgorICAgICAqIFRoaXMgY2FsbCByZXNldHMgdGhlIHBhcnNlciBzdGF0ZSBhbmQgc2V0cyB0aGUgZXZlbnQgdHlwZQorICAgICAqIHRvIHRoZSBpbml0aWFsIHZhbHVlIFNUQVJUX0RPQ1VNRU5ULgorICAgICAqCisgICAgICogPHA+PHN0cm9uZz5OT1RFOjwvc3Ryb25nPiBJZiBhbiBpbnB1dCBlbmNvZGluZyBzdHJpbmcgaXMgcGFzc2VkLAorICAgICAqICBpdCBNVVNUIGJlIHVzZWQuIE90aGVyd2lzZSwKKyAgICAgKiAgaWYgaW5wdXRFbmNvZGluZyBpcyBudWxsLCB0aGUgcGFyc2VyIFNIT1VMRCB0cnkgdG8gZGV0ZXJtaW5lCisgICAgICogIGlucHV0IGVuY29kaW5nIGZvbGxvd2luZyBYTUwgMS4wIHNwZWNpZmljYXRpb24gKHNlZSBiZWxvdykuCisgICAgICogIElmIGVuY29kaW5nIGRldGVjdGlvbiBpcyBzdXBwb3J0ZWQgdGhlbiBmb2xsb3dpbmcgZmVhdHVyZQorICAgICAqICA8YSBocmVmPSJodHRwOi8veG1scHVsbC5vcmcvdjEvZG9jL2ZlYXR1cmVzLmh0bWwjZGV0ZWN0LWVuY29kaW5nIj5odHRwOi8veG1scHVsbC5vcmcvdjEvZG9jL2ZlYXR1cmVzLmh0bWwjZGV0ZWN0LWVuY29kaW5nPC9hPgorICAgICAqICBNVVNUIGJlIHRydWUgYW1kIG90aGVyd2lzZSBpdCBtdXN0IGJlIGZhbHNlCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXRTdHJlYW0gY29udGFpbnMgYSByYXcgYnl0ZSBpbnB1dCBzdHJlYW0gb2YgcG9zc2libHkKKyAgICAgKiAgICAgdW5rbm93biBlbmNvZGluZyAod2hlbiBpbnB1dEVuY29kaW5nIGlzIG51bGwpLgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0RW5jb2RpbmcgaWYgbm90IG51bGwgaXQgTVVTVCBiZSB1c2VkIGFzIGVuY29kaW5nIGZvciBpbnB1dFN0cmVhbQorICAgICAqLworICAgIHZvaWQgc2V0SW5wdXQoSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0sIFN0cmluZyBpbnB1dEVuY29kaW5nKQorICAgICAgICB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGlucHV0IGVuY29kaW5nIGlmIGtub3duLCBudWxsIG90aGVyd2lzZS4KKyAgICAgKiBJZiBzZXRJbnB1dChJbnB1dFN0cmVhbSwgaW5wdXRFbmNvZGluZykgd2FzIGNhbGxlZCB3aXRoIGFuIGlucHV0RW5jb2RpbmcKKyAgICAgKiB2YWx1ZSBvdGhlciB0aGFuIG51bGwsIHRoaXMgdmFsdWUgbXVzdCBiZSByZXR1cm5lZAorICAgICAqIGZyb20gdGhpcyBtZXRob2QuIE90aGVyd2lzZSwgaWYgaW5wdXRFbmNvZGluZyBpcyBudWxsIGFuZAorICAgICAqIHRoZSBwYXJzZXIgc3VwcG9ydHMgdGhlIGVuY29kaW5nIGRldGVjdGlvbiBmZWF0dXJlCisgICAgICogKGh0dHA6Ly94bWxwdWxsLm9yZy92MS9kb2MvZmVhdHVyZXMuaHRtbCNkZXRlY3QtZW5jb2RpbmcpLAorICAgICAqIGl0IG11c3QgcmV0dXJuIHRoZSBkZXRlY3RlZCBlbmNvZGluZy4KKyAgICAgKiBJZiBzZXRJbnB1dChSZWFkZXIpIHdhcyBjYWxsZWQsIG51bGwgaXMgcmV0dXJuZWQuCisgICAgICogQWZ0ZXIgZmlyc3QgY2FsbCB0byBuZXh0IGlmIFhNTCBkZWNsYXJhdGlvbiB3YXMgcHJlc2VudCB0aGlzIG1ldGhvZAorICAgICAqIHdpbGwgcmV0dXJuIGVuY29kaW5nIGRlY2xhcmVkLgorICAgICAqLworICAgIFN0cmluZyBnZXRJbnB1dEVuY29kaW5nKCk7CisKKyAgICAvKioKKyAgICAgKiBTZXQgbmV3IHZhbHVlIGZvciBlbnRpdHkgcmVwbGFjZW1lbnQgdGV4dCBhcyBkZWZpbmVkIGluCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCNpbnRlcm4tcmVwbGFjZW1lbnQiPlhNTCAxLjAgU2VjdGlvbiA0LjUKKyAgICAgKiBDb25zdHJ1Y3Rpb24gb2YgSW50ZXJuYWwgRW50aXR5IFJlcGxhY2VtZW50IFRleHQ8L2E+LgorICAgICAqIElmIEZFQVRVUkVfUFJPQ0VTU19ET0NERUNMIG9yIEZFQVRVUkVfVkFMSURBVElPTiBhcmUgc2V0LCBjYWxsaW5nIHRoaXMKKyAgICAgKiBmdW5jdGlvbiB3aWxsIHJlc3VsdCBpbiBhbiBleGNlcHRpb24gLS0gd2hlbiBwcm9jZXNzaW5nIG9mIERPQ0RFQ0wgaXMKKyAgICAgKiBlbmFibGVkLCB0aGVyZSBpcyBubyBuZWVkIHRvIHRoZSBlbnRpdHkgcmVwbGFjZW1lbnQgdGV4dCBtYW51YWxseS4KKyAgICAgKgorICAgICAqIDxwPlRoZSBtb3RpdmF0aW9uIGZvciB0aGlzIGZ1bmN0aW9uIGlzIHRvIGFsbG93IHZlcnkgc21hbGwKKyAgICAgKiBpbXBsZW1lbnRhdGlvbnMgb2YgWE1MUFVMTCB0aGF0IHdpbGwgd29yayBpbiBKMk1FIGVudmlyb25tZW50cy4KKyAgICAgKiBUaG91Z2ggdGhlc2UgaW1wbGVtZW50YXRpb25zIG1heSBub3QgYmUgYWJsZSB0byBwcm9jZXNzIHRoZSBkb2N1bWVudCB0eXBlCisgICAgICogZGVjbGFyYXRpb24sIHRoZXkgc3RpbGwgY2FuIHdvcmsgd2l0aCBrbm93biBEVERzIGJ5IHVzaW5nIHRoaXMgZnVuY3Rpb24uCisgICAgICoKKyAgICAgKiA8cD48Yj5QbGVhc2Ugbm90ZXM6PC9iPiBUaGUgZ2l2ZW4gdmFsdWUgaXMgdXNlZCBsaXRlcmFsbHkgYXMgcmVwbGFjZW1lbnQgdGV4dAorICAgICAqIGFuZCBpdCBjb3JyZXNwb25kcyB0byBkZWNsYXJpbmcgZW50aXR5IGluIERURCB0aGF0IGhhcyBhbGwgc3BlY2lhbCBjaGFyYWN0ZXJzCisgICAgICogZXNjYXBlZDogbGVmdCBhbmdsZSBicmFja2V0IGlzIHJlcGxhY2VkIHdpdGggJmFtcDtsdDssIGFtcGVyc2FuZCB3aXRoICZhbXA7YW1wOworICAgICAqIGFuZCBzbyBvbi4KKyAgICAgKgorICAgICAqIDxwPjxiPk5vdGU6PC9iPiBUaGUgZ2l2ZW4gdmFsdWUgaXMgdGhlIGxpdGVyYWwgcmVwbGFjZW1lbnQgdGV4dCBhbmQgbXVzdCBub3QKKyAgICAgKiBjb250YWluIGFueSBvdGhlciBlbnRpdHkgcmVmZXJlbmNlIChpZiBpdCBjb250YWlucyBhbnkgZW50aXR5IHJlZmVyZW5jZQorICAgICAqIHRoZXJlIHdpbGwgYmUgbm8gZnVydGhlciByZXBsYWNlbWVudCkuCisgICAgICoKKyAgICAgKiA8cD48Yj5Ob3RlOjwvYj4gVGhlIGxpc3Qgb2YgcHJlLWRlZmluZWQgZW50aXR5IG5hbWVzIHdpbGwKKyAgICAgKiBhbHdheXMgY29udGFpbiBzdGFuZGFyZCBYTUwgZW50aXRpZXMgc3VjaCBhcworICAgICAqIGFtcCAoJmFtcDthbXA7KSwgbHQgKCZhbXA7bHQ7KSwgZ3QgKCZhbXA7Z3Q7KSwgcXVvdCAoJmFtcDtxdW90OyksIGFuZCBhcG9zICgmYW1wO2Fwb3M7KS4KKyAgICAgKiBUaG9zZSBjYW5ub3QgYmUgcmVkZWZpbmVkIGJ5IHRoaXMgbWV0aG9kIQorICAgICAqCisgICAgICogQHNlZSAjc2V0SW5wdXQKKyAgICAgKiBAc2VlICNGRUFUVVJFX1BST0NFU1NfRE9DREVDTAorICAgICAqIEBzZWUgI0ZFQVRVUkVfVkFMSURBVElPTgorICAgICAqLworICAgIHZvaWQgZGVmaW5lRW50aXR5UmVwbGFjZW1lbnRUZXh0KCBTdHJpbmcgZW50aXR5TmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHJlcGxhY2VtZW50VGV4dCApIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVycyBvZiBlbGVtZW50cyBpbiB0aGUgbmFtZXNwYWNlIHN0YWNrIGZvciB0aGUgZ2l2ZW4KKyAgICAgKiBkZXB0aC4KKyAgICAgKiBJZiBuYW1lc3BhY2VzIGFyZSBub3QgZW5hYmxlZCwgMCBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIDxwPjxiPk5PVEU6PC9iPiB3aGVuIHBhcnNlciBpcyBvbiBFTkRfVEFHIHRoZW4gaXQgaXMgYWxsb3dlZCB0byBjYWxsCisgICAgICogIHRoaXMgZnVuY3Rpb24gd2l0aCBnZXREZXB0aCgpKzEgYXJndW1lbnQgdG8gcmV0cmlldmUgcG9zaXRpb24gb2YgbmFtZXNwYWNlCisgICAgICogIHByZWZpeGVzIGFuZCBVUklzIHRoYXQgd2VyZSBkZWNsYXJlZCBvbiBjb3JyZXNwb25kaW5nIFNUQVJUX1RBRy4KKyAgICAgKiA8cD48Yj5OT1RFOjwvYj4gdG8gcmV0cmlldmUgbGlzdCBvZiBuYW1lc3BhY2VzIGRlY2xhcmVkIGluIGN1cnJlbnQgZWxlbWVudDo8cHJlPgorICAgICAqICAgICAgIFhtbFB1bGxQYXJzZXIgcHAgPSAuLi4KKyAgICAgKiAgICAgICBpbnQgbnNTdGFydCA9IHBwLmdldE5hbWVzcGFjZUNvdW50KHBwLmdldERlcHRoKCktMSk7CisgICAgICogICAgICAgaW50IG5zRW5kID0gcHAuZ2V0TmFtZXNwYWNlQ291bnQocHAuZ2V0RGVwdGgoKSk7CisgICAgICogICAgICAgZm9yIChpbnQgaSA9IG5zU3RhcnQ7IGkgPCBuc0VuZDsgaSsrKSB7CisgICAgICogICAgICAgICAgU3RyaW5nIHByZWZpeCA9IHBwLmdldE5hbWVzcGFjZVByZWZpeChpKTsKKyAgICAgKiAgICAgICAgICBTdHJpbmcgbnMgPSBwcC5nZXROYW1lc3BhY2VVcmkoaSk7CisgICAgICogICAgICAgICAgIC8vIC4uLgorICAgICAqICAgICAgfQorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogQHNlZSAjZ2V0TmFtZXNwYWNlUHJlZml4CisgICAgICogQHNlZSAjZ2V0TmFtZXNwYWNlVXJpCisgICAgICogQHNlZSAjZ2V0TmFtZXNwYWNlKCkKKyAgICAgKiBAc2VlICNnZXROYW1lc3BhY2UoU3RyaW5nKQorICAgICAqLworICAgIGludCBnZXROYW1lc3BhY2VDb3VudChpbnQgZGVwdGgpIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZXNwYWNlIHByZWZpeCBmb3IgdGhlIGdpdmVuIHBvc2l0aW9uCisgICAgICogaW4gdGhlIG5hbWVzcGFjZSBzdGFjay4KKyAgICAgKiBEZWZhdWx0IG5hbWVzcGFjZSBkZWNsYXJhdGlvbiAoeG1sbnM9Jy4uLicpIHdpbGwgaGF2ZSBudWxsIGFzIHByZWZpeC4KKyAgICAgKiBJZiB0aGUgZ2l2ZW4gaW5kZXggaXMgb3V0IG9mIHJhbmdlLCBhbiBleGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIDxwPjxiPlBsZWFzZSBub3RlOjwvYj4gd2hlbiB0aGUgcGFyc2VyIGlzIG9uIGFuIEVORF9UQUcsCisgICAgICogbmFtZXNwYWNlIHByZWZpeGVzIHRoYXQgd2VyZSBkZWNsYXJlZAorICAgICAqIGluIHRoZSBjb3JyZXNwb25kaW5nIFNUQVJUX1RBRyBhcmUgc3RpbGwgYWNjZXNzaWJsZQorICAgICAqIGFsdGhvdWdoIHRoZXkgYXJlIG5vIGxvbmdlciBpbiBzY29wZS4KKyAgICAgKi8KKyAgICBTdHJpbmcgZ2V0TmFtZXNwYWNlUHJlZml4KGludCBwb3MpIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZXNwYWNlIFVSSSBmb3IgdGhlIGdpdmVuIHBvc2l0aW9uIGluIHRoZQorICAgICAqIG5hbWVzcGFjZSBzdGFjaworICAgICAqIElmIHRoZSBwb3NpdGlvbiBpcyBvdXQgb2YgcmFuZ2UsIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICogPHA+PGI+Tk9URTo8L2I+IHdoZW4gcGFyc2VyIGlzIG9uIEVORF9UQUcgdGhlbiBuYW1lc3BhY2UgcHJlZml4ZXMgdGhhdCB3ZXJlIGRlY2xhcmVkCisgICAgICogIGluIGNvcnJlc3BvbmRpbmcgU1RBUlRfVEFHIGFyZSBzdGlsbCBhY2Nlc3NpYmxlIGV2ZW4gdGhvdWdoIHRoZXkgYXJlIG5vdCBpbiBzY29wZQorICAgICAqLworICAgIFN0cmluZyBnZXROYW1lc3BhY2VVcmkoaW50IHBvcykgdGhyb3dzIFhtbFB1bGxQYXJzZXJFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBVUkkgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gcHJlZml4LAorICAgICAqIGRlcGVuZGluZyBvbiBjdXJyZW50IHN0YXRlIG9mIHRoZSBwYXJzZXIuCisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgcHJlZml4IHdhcyBub3QgZGVjbGFyZWQgaW4gdGhlIGN1cnJlbnQgc2NvcGUsCisgICAgICogbnVsbCBpcyByZXR1cm5lZC4gVGhlIGRlZmF1bHQgbmFtZXNwYWNlIGlzIGluY2x1ZGVkCisgICAgICogaW4gdGhlIG5hbWVzcGFjZSB0YWJsZSBhbmQgaXMgYXZhaWxhYmxlIHZpYQorICAgICAqIGdldE5hbWVzcGFjZSAobnVsbCkuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBhIGNvbnZlbmllbmNlIG1ldGhvZCBmb3IKKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogIGZvciAoaW50IGkgPSBnZXROYW1lc3BhY2VDb3VudChnZXREZXB0aCAoKSktMTsgaSA+PSAwOyBpLS0pIHsKKyAgICAgKiAgIGlmIChnZXROYW1lc3BhY2VQcmVmaXgoaSkuZXF1YWxzKCBwcmVmaXggKSkgeworICAgICAqICAgICByZXR1cm4gZ2V0TmFtZXNwYWNlVXJpKGkpOworICAgICAqICAgfQorICAgICAqICB9CisgICAgICogIHJldHVybiBudWxsOworICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogPHA+PHN0cm9uZz5QbGVhc2Ugbm90ZTo8L3N0cm9uZz4gcGFyc2VyIGltcGxlbWVudGF0aW9ucworICAgICAqIG1heSBwcm92aWRlIG1vcmUgZWZmaWNpZW50IGxvb2t1cCwgZS5nLiB1c2luZyBhIEhhc2h0YWJsZS4KKyAgICAgKiBUaGUgJ3htbCcgcHJlZml4IGlzIGJvdW5kIHRvICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiLCBhcworICAgICAqIGRlZmluZWQgaW4gdGhlCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8jbnMtdXNpbmciPk5hbWVzcGFjZXMgaW4gWE1MPC9hPgorICAgICAqIHNwZWNpZmljYXRpb24uIEFuYWxvZ291cywgdGhlICd4bWxucycgcHJlZml4IGlzIHJlc29sdmVkIHRvCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iPmh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvPC9hPgorICAgICAqCisgICAgICogQHNlZSAjZ2V0TmFtZXNwYWNlQ291bnQKKyAgICAgKiBAc2VlICNnZXROYW1lc3BhY2VQcmVmaXgKKyAgICAgKiBAc2VlICNnZXROYW1lc3BhY2VVcmkKKyAgICAgKi8KKyAgICBTdHJpbmcgZ2V0TmFtZXNwYWNlIChTdHJpbmcgcHJlZml4KTsKKworCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAvLyBtaXNjZWxsYW5lb3VzIHJlcG9ydGluZyBtZXRob2RzCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGRlcHRoIG9mIHRoZSBlbGVtZW50LgorICAgICAqIE91dHNpZGUgdGhlIHJvb3QgZWxlbWVudCwgdGhlIGRlcHRoIGlzIDAuIFRoZQorICAgICAqIGRlcHRoIGlzIGluY3JlbWVudGVkIGJ5IDEgd2hlbiBhIHN0YXJ0IHRhZyBpcyByZWFjaGVkLgorICAgICAqIFRoZSBkZXB0aCBpcyBkZWNyZW1lbnRlZCBBRlRFUiB0aGUgZW5kIHRhZworICAgICAqIGV2ZW50IHdhcyBvYnNlcnZlZC4KKyAgICAgKgorICAgICAqIDxwcmU+CisgICAgICogJmx0OyEtLSBvdXRzaWRlIC0tJmd0OyAgICAgMAorICAgICAqICZsdDtyb290PiAgICAgICAgICAgICAgICAgIDEKKyAgICAgKiAgIHNvbWV0ZXh0ICAgICAgICAgICAgICAgICAxCisgICAgICogICAgICZsdDtmb29iYXImZ3Q7ICAgICAgICAgMgorICAgICAqICAgICAmbHQ7L2Zvb2JhciZndDsgICAgICAgIDIKKyAgICAgKiAmbHQ7L3Jvb3QmZ3Q7ICAgICAgICAgICAgICAxCisgICAgICogJmx0OyEtLSBvdXRzaWRlIC0tJmd0OyAgICAgMAorICAgICAqIDwvcHJlPgorICAgICAqLworICAgIGludCBnZXREZXB0aCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHNob3J0IHRleHQgZGVzY3JpYmluZyB0aGUgY3VycmVudCBwYXJzZXIgc3RhdGUsIGluY2x1ZGluZworICAgICAqIHRoZSBwb3NpdGlvbiwgYQorICAgICAqIGRlc2NyaXB0aW9uIG9mIHRoZSBjdXJyZW50IGV2ZW50IGFuZCB0aGUgZGF0YSBzb3VyY2UgaWYga25vd24uCisgICAgICogVGhpcyBtZXRob2QgaXMgZXNwZWNpYWxseSB1c2VmdWwgdG8gcHJvdmlkZSBtZWFuaW5nZnVsCisgICAgICogZXJyb3IgbWVzc2FnZXMgYW5kIGZvciBkZWJ1Z2dpbmcgcHVycG9zZXMuCisgICAgICovCisgICAgU3RyaW5nIGdldFBvc2l0aW9uRGVzY3JpcHRpb24gKCk7CisKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgbGluZSBudW1iZXIsIHN0YXJ0aW5nIGZyb20gMS4KKyAgICAgKiBXaGVuIHRoZSBwYXJzZXIgZG9lcyBub3Qga25vdyB0aGUgY3VycmVudCBsaW5lIG51bWJlcgorICAgICAqIG9yIGNhbiBub3QgZGV0ZXJtaW5lIGl0LCAgLTEgaXMgcmV0dXJuZWQgKGUuZy4gZm9yIFdCWE1MKS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gY3VycmVudCBsaW5lIG51bWJlciBvciAtMSBpZiB1bmtub3duLgorICAgICAqLworICAgIGludCBnZXRMaW5lTnVtYmVyKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGNvbHVtbiBudW1iZXIsIHN0YXJ0aW5nIGZyb20gMC4KKyAgICAgKiBXaGVuIHRoZSBwYXJzZXIgZG9lcyBub3Qga25vdyB0aGUgY3VycmVudCBjb2x1bW4gbnVtYmVyCisgICAgICogb3IgY2FuIG5vdCBkZXRlcm1pbmUgaXQsICAtMSBpcyByZXR1cm5lZCAoZS5nLiBmb3IgV0JYTUwpLgorICAgICAqCisgICAgICogQHJldHVybiBjdXJyZW50IGNvbHVtbiBudW1iZXIgb3IgLTEgaWYgdW5rbm93bi4KKyAgICAgKi8KKyAgICBpbnQgZ2V0Q29sdW1uTnVtYmVyKCk7CisKKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gVEVYVCByZWxhdGVkIG1ldGhvZHMKKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBjdXJyZW50IFRFWFQgZXZlbnQgY29udGFpbnMgb25seSB3aGl0ZXNwYWNlCisgICAgICogY2hhcmFjdGVycy4KKyAgICAgKiBGb3IgSUdOT1JBQkxFX1dISVRFU1BBQ0UsIHRoaXMgaXMgYWx3YXlzIHRydWUuCisgICAgICogRm9yIFRFWFQgYW5kIENEU0VDVCwgZmFsc2UgaXMgcmV0dXJuZWQgd2hlbiB0aGUgY3VycmVudCBldmVudCB0ZXh0CisgICAgICogY29udGFpbnMgYXQgbGVhc3Qgb25lIG5vbi13aGl0ZSBzcGFjZSBjaGFyYWN0ZXIuIEZvciBhbnkgb3RoZXIKKyAgICAgKiBldmVudCB0eXBlIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCisgICAgICoKKyAgICAgKiA8cD48Yj5QbGVhc2Ugbm90ZTo8L2I+IG5vbi12YWxpZGF0aW5nIHBhcnNlcnMgYXJlIG5vdAorICAgICAqIGFibGUgdG8gZGlzdGluZ3Vpc2ggd2hpdGVzcGFjZSBhbmQgaWdub3JhYmxlIHdoaXRlc3BhY2UsCisgICAgICogZXhjZXB0IGZyb20gd2hpdGVzcGFjZSBvdXRzaWRlIHRoZSByb290IGVsZW1lbnQuIElnbm9yYWJsZQorICAgICAqIHdoaXRlc3BhY2UgaXMgcmVwb3J0ZWQgYXMgc2VwYXJhdGUgZXZlbnQsIHdoaWNoIGlzIGV4cG9zZWQKKyAgICAgKiB2aWEgbmV4dFRva2VuIG9ubHkuCisgICAgICoKKyAgICAgKi8KKyAgICBib29sZWFuIGlzV2hpdGVzcGFjZSgpIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdGV4dCBjb250ZW50IG9mIHRoZSBjdXJyZW50IGV2ZW50IGFzIFN0cmluZy4KKyAgICAgKiBUaGUgdmFsdWUgcmV0dXJuZWQgZGVwZW5kcyBvbiBjdXJyZW50IGV2ZW50IHR5cGUsCisgICAgICogZm9yIGV4YW1wbGUgZm9yIFRFWFQgZXZlbnQgaXQgaXMgZWxlbWVudCBjb250ZW50CisgICAgICogKHRoaXMgaXMgdHlwaWNhbCBjYXNlIHdoZW4gbmV4dCgpIGlzIHVzZWQpLgorICAgICAqCisgICAgICogU2VlIGRlc2NyaXB0aW9uIG9mIG5leHRUb2tlbigpIGZvciBkZXRhaWxlZCBkZXNjcmlwdGlvbiBvZgorICAgICAqIHBvc3NpYmxlIHJldHVybmVkIHZhbHVlcyBmb3IgZGlmZmVyZW50IHR5cGVzIG9mIGV2ZW50cy4KKyAgICAgKgorICAgICAqIDxwPjxzdHJvbmc+Tk9URTo8L3N0cm9uZz4gaW4gY2FzZSBvZiBFTlRJVFlfUkVGLCB0aGlzIG1ldGhvZCByZXR1cm5zCisgICAgICogdGhlIGVudGl0eSByZXBsYWNlbWVudCB0ZXh0IChvciBudWxsIGlmIG5vdCBhdmFpbGFibGUpLiBUaGlzIGlzCisgICAgICogdGhlIG9ubHkgY2FzZSB3aGVyZQorICAgICAqIGdldFRleHQoKSBhbmQgZ2V0VGV4dENoYXJhY3RlcnMoKSByZXR1cm4gZGlmZmVyZW50IHZhbHVlcy4KKyAgICAgKgorICAgICAqIEBzZWUgI2dldEV2ZW50VHlwZQorICAgICAqIEBzZWUgI25leHQKKyAgICAgKiBAc2VlICNuZXh0VG9rZW4KKyAgICAgKi8KKyAgICBTdHJpbmcgZ2V0VGV4dCAoKTsKKworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYnVmZmVyIHRoYXQgY29udGFpbnMgdGhlIHRleHQgb2YgdGhlIGN1cnJlbnQgZXZlbnQsCisgICAgICogYXMgd2VsbCBhcyB0aGUgc3RhcnQgb2Zmc2V0IGFuZCBsZW5ndGggcmVsZXZhbnQgZm9yIHRoZSBjdXJyZW50CisgICAgICogZXZlbnQuIFNlZSBnZXRUZXh0KCksIG5leHQoKSBhbmQgbmV4dFRva2VuKCkgZm9yIGRlc2NyaXB0aW9uIG9mIHBvc3NpYmxlIHJldHVybmVkIHZhbHVlcy4KKyAgICAgKgorICAgICAqIDxwPjxzdHJvbmc+UGxlYXNlIG5vdGU6PC9zdHJvbmc+IHRoaXMgYnVmZmVyIG11c3Qgbm90CisgICAgICogYmUgbW9kaWZpZWQgYW5kIGl0cyBjb250ZW50IE1BWSBjaGFuZ2UgYWZ0ZXIgYSBjYWxsIHRvCisgICAgICogbmV4dCgpIG9yIG5leHRUb2tlbigpLiBUaGlzIG1ldGhvZCB3aWxsIGFsd2F5cyByZXR1cm4gdGhlCisgICAgICogc2FtZSB2YWx1ZSBhcyBnZXRUZXh0KCksIGV4Y2VwdCBmb3IgRU5USVRZX1JFRi4gSW4gdGhlIGNhc2UKKyAgICAgKiBvZiBFTlRJVFkgcmVmLCBnZXRUZXh0KCkgcmV0dXJucyB0aGUgcmVwbGFjZW1lbnQgdGV4dCBhbmQKKyAgICAgKiB0aGlzIG1ldGhvZCByZXR1cm5zIHRoZSBhY3R1YWwgaW5wdXQgYnVmZmVyIGNvbnRhaW5pbmcgdGhlCisgICAgICogZW50aXR5IG5hbWUuCisgICAgICogSWYgZ2V0VGV4dCgpIHJldHVybnMgbnVsbCwgdGhpcyBtZXRob2QgcmV0dXJucyBudWxsIGFzIHdlbGwgYW5kCisgICAgICogdGhlIHZhbHVlcyByZXR1cm5lZCBpbiB0aGUgaG9sZGVyIGFycmF5IE1VU1QgYmUgLTEgKGJvdGggc3RhcnQKKyAgICAgKiBhbmQgbGVuZ3RoKS4KKyAgICAgKgorICAgICAqIEBzZWUgI2dldFRleHQKKyAgICAgKiBAc2VlICNuZXh0CisgICAgICogQHNlZSAjbmV4dFRva2VuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaG9sZGVyRm9yU3RhcnRBbmRMZW5ndGggTXVzdCBob2xkIGFuIDItZWxlbWVudCBpbnQgYXJyYXkKKyAgICAgKiBpbnRvIHdoaWNoIHRoZSBzdGFydCBvZmZzZXQgYW5kIGxlbmd0aCB2YWx1ZXMgd2lsbCBiZSB3cml0dGVuLgorICAgICAqIEByZXR1cm4gY2hhciBidWZmZXIgdGhhdCBjb250YWlucyB0aGUgdGV4dCBvZiB0aGUgY3VycmVudCBldmVudAorICAgICAqICAobnVsbCBpZiB0aGUgY3VycmVudCBldmVudCBoYXMgbm8gdGV4dCBhc3NvY2lhdGVkKS4KKyAgICAgKi8KKyAgICBjaGFyW10gZ2V0VGV4dENoYXJhY3RlcnMoaW50IFtdIGhvbGRlckZvclN0YXJ0QW5kTGVuZ3RoKTsKKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gU1RBUlRfVEFHIC8gRU5EX1RBRyBzaGFyZWQgbWV0aG9kcworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgY3VycmVudCBlbGVtZW50LgorICAgICAqIFRoZSBkZWZhdWx0IG5hbWVzcGFjZSBpcyByZXByZXNlbnRlZAorICAgICAqIGFzIGVtcHR5IHN0cmluZy4KKyAgICAgKiBJZiBuYW1lc3BhY2VzIGFyZSBub3QgZW5hYmxlZCwgYW4gZW1wdHkgU3RyaW5nICgiIikgaXMgYWx3YXlzIHJldHVybmVkLgorICAgICAqIFRoZSBjdXJyZW50IGV2ZW50IG11c3QgYmUgU1RBUlRfVEFHIG9yIEVORF9UQUc7IG90aGVyd2lzZSwKKyAgICAgKiBudWxsIGlzIHJldHVybmVkLgorICAgICAqLworICAgIFN0cmluZyBnZXROYW1lc3BhY2UgKCk7CisKKyAgICAvKioKKyAgICAgKiBGb3IgU1RBUlRfVEFHIG9yIEVORF9UQUcgZXZlbnRzLCB0aGUgKGxvY2FsKSBuYW1lIG9mIHRoZSBjdXJyZW50CisgICAgICogZWxlbWVudCBpcyByZXR1cm5lZCB3aGVuIG5hbWVzcGFjZXMgYXJlIGVuYWJsZWQuIFdoZW4gbmFtZXNwYWNlCisgICAgICogcHJvY2Vzc2luZyBpcyBkaXNhYmxlZCwgdGhlIHJhdyBuYW1lIGlzIHJldHVybmVkLgorICAgICAqIEZvciBFTlRJVFlfUkVGIGV2ZW50cywgdGhlIGVudGl0eSBuYW1lIGlzIHJldHVybmVkLgorICAgICAqIElmIHRoZSBjdXJyZW50IGV2ZW50IGlzIG5vdCBTVEFSVF9UQUcsIEVORF9UQUcsIG9yIEVOVElUWV9SRUYsCisgICAgICogbnVsbCBpcyByZXR1cm5lZC4KKyAgICAgKiA8cD48Yj5QbGVhc2Ugbm90ZTo8L2I+IFRvIHJlY29uc3RydWN0IHRoZSByYXcgZWxlbWVudCBuYW1lCisgICAgICogIHdoZW4gbmFtZXNwYWNlcyBhcmUgZW5hYmxlZCBhbmQgdGhlIHByZWZpeCBpcyBub3QgbnVsbCwKKyAgICAgKiB5b3Ugd2lsbCBuZWVkIHRvICBhZGQgdGhlIHByZWZpeCBhbmQgYSBjb2xvbiB0byBsb2NhbE5hbWUuLgorICAgICAqCisgICAgICovCisgICAgU3RyaW5nIGdldE5hbWUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByZWZpeCBvZiB0aGUgY3VycmVudCBlbGVtZW50LgorICAgICAqIElmIHRoZSBlbGVtZW50IGlzIGluIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSAoaGFzIG5vIHByZWZpeCksCisgICAgICogbnVsbCBpcyByZXR1cm5lZC4KKyAgICAgKiBJZiBuYW1lc3BhY2VzIGFyZSBub3QgZW5hYmxlZCwgb3IgdGhlIGN1cnJlbnQgZXZlbnQKKyAgICAgKiBpcyBub3QgIFNUQVJUX1RBRyBvciBFTkRfVEFHLCBudWxsIGlzIHJldHVybmVkLgorICAgICAqLworICAgIFN0cmluZyBnZXRQcmVmaXgoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY3VycmVudCBldmVudCBpcyBTVEFSVF9UQUcgYW5kIHRoZSB0YWcKKyAgICAgKiBpcyBkZWdlbmVyYXRlZAorICAgICAqIChlLmcuICZsdDtmb29iYXIvJmd0OykuCisgICAgICogPHA+PGI+Tk9URTo8L2I+IGlmIHRoZSBwYXJzZXIgaXMgbm90IG9uIFNUQVJUX1RBRywgYW4gZXhjZXB0aW9uCisgICAgICogd2lsbCBiZSB0aHJvd24uCisgICAgICovCisgICAgYm9vbGVhbiBpc0VtcHR5RWxlbWVudFRhZygpIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uOworCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAvLyBTVEFSVF9UQUcgQXR0cmlidXRlcyByZXRyaWV2YWwgbWV0aG9kcworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMgb2YgdGhlIGN1cnJlbnQgc3RhcnQgdGFnLCBvcgorICAgICAqIC0xIGlmIHRoZSBjdXJyZW50IGV2ZW50IHR5cGUgaXMgbm90IFNUQVJUX1RBRworICAgICAqCisgICAgICogQHNlZSAjZ2V0QXR0cmlidXRlTmFtZXNwYWNlCisgICAgICogQHNlZSAjZ2V0QXR0cmlidXRlTmFtZQorICAgICAqIEBzZWUgI2dldEF0dHJpYnV0ZVByZWZpeAorICAgICAqIEBzZWUgI2dldEF0dHJpYnV0ZVZhbHVlCisgICAgICovCisgICAgaW50IGdldEF0dHJpYnV0ZUNvdW50KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBhdHRyaWJ1dGUKKyAgICAgKiB3aXRoIHRoZSBnaXZlbiBpbmRleCAoc3RhcnRzIGZyb20gMCkuCisgICAgICogUmV0dXJucyBhbiBlbXB0eSBzdHJpbmcgKCIiKSBpZiBuYW1lc3BhY2VzIGFyZSBub3QgZW5hYmxlZAorICAgICAqIG9yIHRoZSBhdHRyaWJ1dGUgaGFzIG5vIG5hbWVzcGFjZS4KKyAgICAgKiBUaHJvd3MgYW4gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB0aGUgaW5kZXggaXMgb3V0IG9mIHJhbmdlCisgICAgICogb3IgdGhlIGN1cnJlbnQgZXZlbnQgdHlwZSBpcyBub3QgU1RBUlRfVEFHLgorICAgICAqCisgICAgICogPHA+PHN0cm9uZz5OT1RFOjwvc3Ryb25nPiBpZiBGRUFUVVJFX1JFUE9SVF9OQU1FU1BBQ0VfQVRUUklCVVRFUyBpcyBzZXQKKyAgICAgKiB0aGVuIG5hbWVzcGFjZSBhdHRyaWJ1dGVzICh4bWxuczpucz0nLi4uJykgbXVzdCBiZSByZXBvcnRlZAorICAgICAqIHdpdGggbmFtZXNwYWNlCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iPmh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvPC9hPgorICAgICAqICh2aXNpdCB0aGlzIFVSTCBmb3IgZGVzY3JpcHRpb24hKS4KKyAgICAgKiBUaGUgZGVmYXVsdCBuYW1lc3BhY2UgYXR0cmlidXRlICh4bWxucz0iLi4uIikgd2lsbCBiZSByZXBvcnRlZCB3aXRoIGVtcHR5IG5hbWVzcGFjZS4KKyAgICAgKiA8cD48c3Ryb25nPk5PVEU6PC9zdHJvbmc+VGhlIHhtbCBwcmVmaXggaXMgYm91bmQgYXMgZGVmaW5lZCBpbgorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI25zLXVzaW5nIj5OYW1lc3BhY2VzIGluIFhNTDwvYT4KKyAgICAgKiBzcGVjaWZpY2F0aW9uIHRvICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IHplcm8tYmFzZWQgaW5kZXggb2YgYXR0cmlidXRlCisgICAgICogQHJldHVybiBhdHRyaWJ1dGUgbmFtZXNwYWNlLAorICAgICAqICAgZW1wdHkgc3RyaW5nICgiIikgaXMgcmV0dXJuZWQgIGlmIG5hbWVzcGFjZXMgcHJvY2Vzc2luZyBpcyBub3QgZW5hYmxlZCBvcgorICAgICAqICAgbmFtZXNwYWNlcyBwcm9jZXNzaW5nIGlzIGVuYWJsZWQgYnV0IGF0dHJpYnV0ZSBoYXMgbm8gbmFtZXNwYWNlIChpdCBoYXMgbm8gcHJlZml4KS4KKyAgICAgKi8KKyAgICBTdHJpbmcgZ2V0QXR0cmlidXRlTmFtZXNwYWNlIChpbnQgaW5kZXgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZQorICAgICAqIGlmIG5hbWVzcGFjZXMgYXJlIGVuYWJsZWQgb3IganVzdCBhdHRyaWJ1dGUgbmFtZSBpZiBuYW1lc3BhY2VzIGFyZSBkaXNhYmxlZC4KKyAgICAgKiBUaHJvd3MgYW4gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB0aGUgaW5kZXggaXMgb3V0IG9mIHJhbmdlCisgICAgICogb3IgY3VycmVudCBldmVudCB0eXBlIGlzIG5vdCBTVEFSVF9UQUcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXggemVyby1iYXNlZCBpbmRleCBvZiBhdHRyaWJ1dGUKKyAgICAgKiBAcmV0dXJuIGF0dHJpYnV0ZSBuYW1lIChudWxsIGlzIG5ldmVyIHJldHVybmVkKQorICAgICAqLworICAgIFN0cmluZyBnZXRBdHRyaWJ1dGVOYW1lIChpbnQgaW5kZXgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcHJlZml4IG9mIHRoZSBzcGVjaWZpZWQgYXR0cmlidXRlCisgICAgICogUmV0dXJucyBudWxsIGlmIHRoZSBlbGVtZW50IGhhcyBubyBwcmVmaXguCisgICAgICogSWYgbmFtZXNwYWNlcyBhcmUgZGlzYWJsZWQgaXQgd2lsbCBhbHdheXMgcmV0dXJuIG51bGwuCisgICAgICogVGhyb3dzIGFuIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgdGhlIGluZGV4IGlzIG91dCBvZiByYW5nZQorICAgICAqIG9yIGN1cnJlbnQgZXZlbnQgdHlwZSBpcyBub3QgU1RBUlRfVEFHLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IHplcm8tYmFzZWQgaW5kZXggb2YgYXR0cmlidXRlCisgICAgICogQHJldHVybiBhdHRyaWJ1dGUgcHJlZml4IG9yIG51bGwgaWYgbmFtZXNwYWNlcyBwcm9jZXNzaW5nIGlzIG5vdCBlbmFibGVkLgorICAgICAqLworICAgIFN0cmluZyBnZXRBdHRyaWJ1dGVQcmVmaXgoaW50IGluZGV4KTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUKKyAgICAgKiBJZiBwYXJzZXIgaXMgbm9uLXZhbGlkYXRpbmcgaXQgTVVTVCByZXR1cm4gQ0RBVEEuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5kZXggemVyby1iYXNlZCBpbmRleCBvZiBhdHRyaWJ1dGUKKyAgICAgKiBAcmV0dXJuIGF0dHJpYnV0ZSB0eXBlIChudWxsIGlzIG5ldmVyIHJldHVybmVkKQorICAgICAqLworICAgIFN0cmluZyBnZXRBdHRyaWJ1dGVUeXBlKGludCBpbmRleCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGlmIHRoZSBzcGVjaWZpZWQgYXR0cmlidXRlIHdhcyBub3QgaW4gaW5wdXQgd2FzIGRlY2xhcmVkIGluIFhNTC4KKyAgICAgKiBJZiBwYXJzZXIgaXMgbm9uLXZhbGlkYXRpbmcgaXQgTVVTVCBhbHdheXMgcmV0dXJuIGZhbHNlLgorICAgICAqIFRoaXMgaW5mb3JtYXRpb24gaXMgcGFydCBvZiBYTUwgaW5mb3NldDoKKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleCB6ZXJvLWJhc2VkIGluZGV4IG9mIGF0dHJpYnV0ZQorICAgICAqIEByZXR1cm4gZmFsc2UgaWYgYXR0cmlidXRlIHdhcyBpbiBpbnB1dAorICAgICAqLworICAgIGJvb2xlYW4gaXNBdHRyaWJ1dGVEZWZhdWx0KGludCBpbmRleCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBnaXZlbiBhdHRyaWJ1dGVzIHZhbHVlLgorICAgICAqIFRocm93cyBhbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgcmFuZ2UKKyAgICAgKiBvciBjdXJyZW50IGV2ZW50IHR5cGUgaXMgbm90IFNUQVJUX1RBRy4KKyAgICAgKgorICAgICAqIDxwPjxzdHJvbmc+Tk9URTo8L3N0cm9uZz4gYXR0cmlidXRlIHZhbHVlIG11c3QgYmUgbm9ybWFsaXplZAorICAgICAqIChpbmNsdWRpbmcgZW50aXR5IHJlcGxhY2VtZW50IHRleHQgaWYgUFJPQ0VTU19ET0NERUNMIGlzIGZhbHNlKSBhcyBkZXNjcmliZWQgaW4KKyAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sI0FWTm9ybWFsaXplIj5YTUwgMS4wIHNlY3Rpb24KKyAgICAgKiAzLjMuMyBBdHRyaWJ1dGUtVmFsdWUgTm9ybWFsaXphdGlvbjwvYT4KKyAgICAgKgorICAgICAqIEBzZWUgI2RlZmluZUVudGl0eVJlcGxhY2VtZW50VGV4dAorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4IHplcm8tYmFzZWQgaW5kZXggb2YgYXR0cmlidXRlCisgICAgICogQHJldHVybiB2YWx1ZSBvZiBhdHRyaWJ1dGUgKG51bGwgaXMgbmV2ZXIgcmV0dXJuZWQpCisgICAgICovCisgICAgU3RyaW5nIGdldEF0dHJpYnV0ZVZhbHVlKGludCBpbmRleCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGVzIHZhbHVlIGlkZW50aWZpZWQgYnkgbmFtZXNwYWNlIFVSSSBhbmQgbmFtZXNwYWNlIGxvY2FsTmFtZS4KKyAgICAgKiBJZiBuYW1lc3BhY2VzIGFyZSBkaXNhYmxlZCBuYW1lc3BhY2UgbXVzdCBiZSBudWxsLgorICAgICAqIElmIGN1cnJlbnQgZXZlbnQgdHlwZSBpcyBub3QgU1RBUlRfVEFHIHRoZW4gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi4KKyAgICAgKgorICAgICAqIDxwPjxzdHJvbmc+Tk9URTo8L3N0cm9uZz4gYXR0cmlidXRlIHZhbHVlIG11c3QgYmUgbm9ybWFsaXplZAorICAgICAqIChpbmNsdWRpbmcgZW50aXR5IHJlcGxhY2VtZW50IHRleHQgaWYgUFJPQ0VTU19ET0NERUNMIGlzIGZhbHNlKSBhcyBkZXNjcmliZWQgaW4KKyAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sI0FWTm9ybWFsaXplIj5YTUwgMS4wIHNlY3Rpb24KKyAgICAgKiAzLjMuMyBBdHRyaWJ1dGUtVmFsdWUgTm9ybWFsaXphdGlvbjwvYT4KKyAgICAgKgorICAgICAqIEBzZWUgI2RlZmluZUVudGl0eVJlcGxhY2VtZW50VGV4dAorICAgICAqCisgICAgICogQHBhcmFtIG5hbWVzcGFjZSBOYW1lc3BhY2Ugb2YgdGhlIGF0dHJpYnV0ZSBpZiBuYW1lc3BhY2VzIGFyZSBlbmFibGVkIG90aGVyd2lzZSBtdXN0IGJlIG51bGwKKyAgICAgKiBAcGFyYW0gbmFtZSBJZiBuYW1lc3BhY2VzIGVuYWJsZWQgbG9jYWwgbmFtZSBvZiBhdHRyaWJ1dGUgb3RoZXJ3aXNlIGp1c3QgYXR0cmlidXRlIG5hbWUKKyAgICAgKiBAcmV0dXJuIHZhbHVlIG9mIGF0dHJpYnV0ZSBvciBudWxsIGlmIGF0dHJpYnV0ZSB3aXRoIGdpdmVuIG5hbWUgZG9lcyBub3QgZXhpc3QKKyAgICAgKi8KKyAgICBTdHJpbmcgZ2V0QXR0cmlidXRlVmFsdWUoU3RyaW5nIG5hbWVzcGFjZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lKTsKKworICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gYWN0dWFsIHBhcnNpbmcgbWV0aG9kcworCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdHlwZSBvZiB0aGUgY3VycmVudCBldmVudCAoU1RBUlRfVEFHLCBFTkRfVEFHLCBURVhULCBldGMuKQorICAgICAqCisgICAgICogQHNlZSAjbmV4dCgpCisgICAgICogQHNlZSAjbmV4dFRva2VuKCkKKyAgICAgKi8KKyAgICBpbnQgZ2V0RXZlbnRUeXBlKCkKKyAgICAgICAgdGhyb3dzIFhtbFB1bGxQYXJzZXJFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgbmV4dCBwYXJzaW5nIGV2ZW50IC0gZWxlbWVudCBjb250ZW50IHdpbCBiZSBjb2FsZXNjZWQgYW5kIG9ubHkgb25lCisgICAgICogVEVYVCBldmVudCBtdXN0IGJlIHJldHVybmVkIGZvciB3aG9sZSBlbGVtZW50IGNvbnRlbnQKKyAgICAgKiAoY29tbWVudHMgYW5kIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIHdpbGwgYmUgaWdub3JlZCBhbmQgZW50aXR5IHJlZmVyZW5jZXMKKyAgICAgKiBtdXN0IGJlIGV4cGFuZGVkIG9yIGV4Y2VwdGlvbiBtdXMgYmUgdGhyb3duIGlmIGVudGl0eSByZWZlcmVuY2UgY2FuIG5vdCBiZSBleHBhbmRlZCkuCisgICAgICogSWYgZWxlbWVudCBjb250ZW50IGlzIGVtcHR5IChjb250ZW50IGlzICIiKSB0aGVuIG5vIFRFWFQgZXZlbnQgd2lsbCBiZSByZXBvcnRlZC4KKyAgICAgKgorICAgICAqIDxwPjxiPk5PVEU6PC9iPiBlbXB0eSBlbGVtZW50IChzdWNoIGFzICZsdDt0YWcvPikgd2lsbCBiZSByZXBvcnRlZAorICAgICAqICB3aXRoICB0d28gc2VwYXJhdGUgZXZlbnRzOiBTVEFSVF9UQUcsIEVORF9UQUcgLSBpdCBtdXN0IGJlIHNvIHRvIHByZXNlcnZlCisgICAgICogICBwYXJzaW5nIGVxdWl2YWxlbmN5IG9mIGVtcHR5IGVsZW1lbnQgdG8gJmx0O3RhZz4mbHQ7L3RhZz4uCisgICAgICogIChzZWUgaXNFbXB0eUVsZW1lbnRUYWcgKCkpCisgICAgICoKKyAgICAgKiBAc2VlICNpc0VtcHR5RWxlbWVudFRhZworICAgICAqIEBzZWUgI1NUQVJUX1RBRworICAgICAqIEBzZWUgI1RFWFQKKyAgICAgKiBAc2VlICNFTkRfVEFHCisgICAgICogQHNlZSAjRU5EX0RPQ1VNRU5UCisgICAgICovCisKKyAgICBpbnQgbmV4dCgpCisgICAgICAgIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbjsKKworCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd29ya3Mgc2ltaWxhcmx5IHRvIG5leHQoKSBidXQgd2lsbCBleHBvc2UKKyAgICAgKiBhZGRpdGlvbmFsIGV2ZW50IHR5cGVzIChDT01NRU5ULCBDRFNFQ1QsIERPQ0RFQ0wsIEVOVElUWV9SRUYsIFBST0NFU1NJTkdfSU5TVFJVQ1RJT04sIG9yCisgICAgICogSUdOT1JBQkxFX1dISVRFU1BBQ0UpIGlmIHRoZXkgYXJlIGF2YWlsYWJsZSBpbiBpbnB1dC4KKyAgICAgKgorICAgICAqIDxwPklmIHNwZWNpYWwgZmVhdHVyZQorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly94bWxwdWxsLm9yZy92MS9kb2MvZmVhdHVyZXMuaHRtbCN4bWwtcm91bmR0cmlwIj5GRUFUVVJFX1hNTF9ST1VORFRSSVA8L2E+CisgICAgICogKGlkZW50aWZpZWQgYnkgVVJJOiBodHRwOi8veG1scHVsbC5vcmcvdjEvZG9jL2ZlYXR1cmVzLmh0bWwjeG1sLXJvdW5kdHJpcCkKKyAgICAgKiBpcyBlbmFibGVkIGl0IGlzIHBvc3NpYmxlIHRvIGRvIFhNTCBkb2N1bWVudCByb3VuZCB0cmlwIGllLiByZXByb2R1Y2UKKyAgICAgKiBleGVjdGx5IG9uIG91dHB1dCB0aGUgWE1MIGlucHV0IHVzaW5nIGdldFRleHQoKToKKyAgICAgKiByZXR1cm5lZCBjb250ZW50IGlzIGFsd2F5cyB1bm5vcm1hbGl6ZWQgKGV4YWN0bHkgYXMgaW4gaW5wdXQpLgorICAgICAqIE90aGVyd2lzZSByZXR1cm5lZCBjb250ZW50IGlzIGVuZC1vZi1saW5lIG5vcm1hbGl6ZWQgYXMgZGVzY3JpYmVkCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCNzZWMtbGluZS1lbmRzIj5YTUwgMS4wIEVuZC1vZi1MaW5lIEhhbmRsaW5nPC9hPgorICAgICAqIGFuZC4gQWxzbyB3aGVuIHRoaXMgZmVhdHVyZSBpcyBlbmFibGVkIGV4YWN0IGNvbnRlbnQgb2YgU1RBUlRfVEFHLCBFTkRfVEFHLAorICAgICAqIERPQ0RFQ0wgYW5kIFBST0NFU1NJTkdfSU5TVFJVQ1RJT04gaXMgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogPHA+SGVyZSBpcyB0aGUgbGlzdCBvZiB0b2tlbnMgdGhhdCBjYW4gYmUgIHJldHVybmVkIGZyb20gbmV4dFRva2VuKCkKKyAgICAgKiBhbmQgd2hhdCBnZXRUZXh0KCkgYW5kIGdldFRleHRDaGFyYWN0ZXJzKCkgcmV0dXJuczo8ZGw+CisgICAgICogPGR0PlNUQVJUX0RPQ1VNRU5UPGRkPm51bGwKKyAgICAgKiA8ZHQ+RU5EX0RPQ1VNRU5UPGRkPm51bGwKKyAgICAgKiA8ZHQ+U1RBUlRfVEFHPGRkPm51bGwgdW5sZXNzIEZFQVRVUkVfWE1MX1JPVU5EVFJJUAorICAgICAqICAgZW5hYmxlZCBhbmQgdGhlbiByZXR1cm5zIFhNTCB0YWcsIGV4OiAmbHQ7dGFnIGF0dHI9J3ZhbCc+CisgICAgICogPGR0PkVORF9UQUc8ZGQ+bnVsbCB1bmxlc3MgRkVBVFVSRV9YTUxfUk9VTkRUUklQCisgICAgICogIGlkIGVuYWJsZWQgYW5kIHRoZW4gcmV0dXJucyBYTUwgdGFnLCBleDogJmx0Oy90YWc+CisgICAgICogPGR0PlRFWFQ8ZGQ+cmV0dXJuIGVsZW1lbnQgY29udGVudC4KKyAgICAgKiAgPGJyPk5vdGU6IHRoYXQgZWxlbWVudCBjb250ZW50IG1heSBiZSBkZWxpdmVyZWQgaW4gbXVsdGlwbGUgY29uc2VjdXRpdmUgVEVYVCBldmVudHMuCisgICAgICogPGR0PklHTk9SQUJMRV9XSElURVNQQUNFPGRkPnJldHVybiBjaGFyYWN0ZXJzIHRoYXQgYXJlIGRldGVybWluZWQgdG8gYmUgaWdub3JhYmxlIHdoaXRlCisgICAgICogc3BhY2UuIElmIHRoZSBGRUFUVVJFX1hNTF9ST1VORFRSSVAgaXMgZW5hYmxlZCBhbGwgd2hpdGVzcGFjZSBjb250ZW50IG91dHNpZGUgcm9vdAorICAgICAqIGVsZW1lbnQgd2lsbCBhbHdheXMgcmVwb3J0ZWQgYXMgSUdOT1JBQkxFX1dISVRFU1BBQ0Ugb3RoZXJ3aXNlIHJlcG9ydGluZyBpcyBvcHRpb25hbC4KKyAgICAgKiAgPGJyPk5vdGU6IHRoYXQgZWxlbWVudCBjb250ZW50IG1heSBiZSBkZWxpdmVyZWQgaW4gbXVsdGlwbGUgY29uc2VjdXRpdmUgSUdOT1JBQkxFX1dISVRFU1BBQ0UgZXZlbnRzLgorICAgICAqIDxkdD5DRFNFQ1Q8ZGQ+CisgICAgICogcmV0dXJuIHRleHQgPGVtPmluc2lkZTwvZW0+IENEQVRBCisgICAgICogIChleC4gJ2ZvJmx0O28nIGZyb20gJmx0OyFDREFUQVtmbyZsdDtvXV0+KQorICAgICAqIDxkdD5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OPGRkPgorICAgICAqICBpZiBGRUFUVVJFX1hNTF9ST1VORFRSSVAgaXMgdHJ1ZQorICAgICAqICByZXR1cm4gZXhhY3QgUEkgY29udGVudCBleDogJ3BpIGZvbycgZnJvbSAmbHQ7P3BpIGZvbz8+CisgICAgICogIG90aGVyd2lzZSBpdCBtYXkgYmUgZXhhY3QgUEkgY29udGVudCBvciBjb25jYXRlbmF0aW9uIG9mIFBJIHRhcmdldCwKKyAgICAgKiBzcGFjZSBhbmQgZGF0YSBzbyBmb3IgZXhhbXBsZSBmb3IKKyAgICAgKiAgICZsdDs/dGFyZ2V0ICAgIGRhdGE/PiBzdHJpbmcgJnF1b3Q7dGFyZ2V0IGRhdGEmcXVvdDsgbWF5CisgICAgICogICAgICAgYmUgcmV0dXJuZWQgaWYgRkVBVFVSRV9YTUxfUk9VTkRUUklQIGlzIGZhbHNlLgorICAgICAqIDxkdD5DT01NRU5UPGRkPnJldHVybiBjb21tZW50IGNvbnRlbnQgZXguICdmb28gYmFyJyBmcm9tICZsdDshLS1mb28gYmFyLS0+CisgICAgICogPGR0PkVOVElUWV9SRUY8ZGQ+Z2V0VGV4dCgpIE1VU1QgcmV0dXJuIGVudGl0eSByZXBsYWNlbWVudCB0ZXh0IGlmIFBST0NFU1NfRE9DREVDTCBpcyBmYWxzZQorICAgICAqIG90aGVyd2lzZSBnZXRUZXh0KCkgTUFZIHJldHVybiBudWxsLAorICAgICAqIGFkZGl0aW9uYWxseSBnZXRUZXh0Q2hhcmFjdGVycygpIE1VU1QgcmV0dXJuIGVudGl0eSBuYW1lCisgICAgICogKGZvciBleGFtcGxlICdlbnRpdHlfbmFtZScgZm9yICZhbXA7ZW50aXR5X25hbWU7KS4KKyAgICAgKiA8YnI+PGI+Tk9URTo8L2I+IHRoaXMgaXMgdGhlIG9ubHkgcGxhY2Ugd2hlcmUgdmFsdWUgcmV0dXJuZWQgZnJvbSBnZXRUZXh0KCkgYW5kCisgICAgICogICBnZXRUZXh0Q2hhcmFjdGVycygpIDxiPmFyZSBkaWZmZXJlbnQ8L2I+CisgICAgICogPGJyPjxiPk5PVEU6PC9iPiBpdCBpcyB1c2VyIHJlc3BvbnNpYmlsaXR5IHRvIHJlc29sdmUgZW50aXR5IHJlZmVyZW5jZQorICAgICAqICAgIGlmIFBST0NFU1NfRE9DREVDTCBpcyBmYWxzZSBhbmQgdGhlcmUgaXMgbm8gZW50aXR5IHJlcGxhY2VtZW50IHRleHQgc2V0IGluCisgICAgICogICAgZGVmaW5lRW50aXR5UmVwbGFjZW1lbnRUZXh0KCkgbWV0aG9kIChnZXRUZXh0KCkgd2lsbCBiZSBudWxsKQorICAgICAqIDxicj48Yj5OT1RFOjwvYj4gY2hhcmFjdGVyIGVudGl0aWVzIChleC4gJmFtcDsjMzI7KSBhbmQgc3RhbmRhcmQgZW50aXRpZXMgc3VjaCBhcworICAgICAqICAmYW1wO2FtcDsgJmFtcDtsdDsgJmFtcDtndDsgJmFtcDtxdW90OyAmYW1wO2Fwb3M7IGFyZSByZXBvcnRlZCBhcyB3ZWxsCisgICAgICogIGFuZCBhcmUgPGI+bm90PC9iPiByZXBvcnRlZCBhcyBURVhUIHRva2VucyBidXQgYXMgRU5USVRZX1JFRiB0b2tlbnMhCisgICAgICogIFRoaXMgcmVxdWlyZW1lbnQgaXMgYWRkZWQgdG8gYWxsb3cgdG8gZG8gcm91bmR0cmlwIG9mIFhNTCBkb2N1bWVudHMhCisgICAgICogPGR0PkRPQ0RFQ0w8ZGQ+CisgICAgICogaWYgRkVBVFVSRV9YTUxfUk9VTkRUUklQIGlzIHRydWUgb3IgUFJPQ0VTU19ET0NERUNMIGlzIGZhbHNlCisgICAgICogdGhlbiByZXR1cm4gd2hhdCBpcyBpbnNpZGUgb2YgRE9DREVDTCBmb3IgZXhhbXBsZSBpdCByZXR1cm5zOjxwcmU+CisgICAgICogJnF1b3Q7IHRpdGxlcGFnZSBTWVNURU0gImh0dHA6Ly93d3cuZm9vLmJhci9kdGRzL3R5cG8uZHRkIgorICAgICAqIFsmbHQ7IUVOVElUWSAlIGFjdGl2ZS5saW5rcyAiSU5DTFVERSI+XSZxdW90OzwvcHJlPgorICAgICAqIDxwPmZvciBpbnB1dCBkb2N1bWVudCB0aGF0IGNvbnRhaW5lZDo8cHJlPgorICAgICAqICZsdDshRE9DVFlQRSB0aXRsZXBhZ2UgU1lTVEVNICJodHRwOi8vd3d3LmZvby5iYXIvZHRkcy90eXBvLmR0ZCIKKyAgICAgKiBbJmx0OyFFTlRJVFkgJSBhY3RpdmUubGlua3MgIklOQ0xVREUiPl0+PC9wcmU+CisgICAgICogb3RoZXJ3aXNlIGlmIEZFQVRVUkVfWE1MX1JPVU5EVFJJUCBpcyBmYWxzZSBhbmQgUFJPQ0VTU19ET0NERUNMIGlzIHRydWUKKyAgICAgKiAgICB0aGVuIHdoYXQgaXMgcmV0dXJuZWQgaXMgdW5kZWZpbmVkIChpdCBtYXkgYmUgZXZlbiBudWxsKQorICAgICAqIDwvZGQ+CisgICAgICogPC9kbD4KKyAgICAgKgorICAgICAqIDxwPjxzdHJvbmc+Tk9URTo8L3N0cm9uZz4gdGhlcmUgaXMgbm8gZ3VhcmFudGVlIHRoYXQgdGhlcmUgd2lsbCBvbmx5IG9uZSBURVhUIG9yCisgICAgICogSUdOT1JBQkxFX1dISVRFU1BBQ0UgZXZlbnQgZnJvbSBuZXh0VG9rZW4oKSBhcyBwYXJzZXIgbWF5IGNob3NlIHRvIGRlbGl2ZXIgZWxlbWVudCBjb250ZW50IGluCisgICAgICogbXVsdGlwbGUgdG9rZW5zIChkaXZpZGluZyBlbGVtZW50IGNvbnRlbnQgaW50byBjaHVua3MpCisgICAgICoKKyAgICAgKiA8cD48c3Ryb25nPk5PVEU6PC9zdHJvbmc+IHdoZXRoZXIgcmV0dXJuZWQgdGV4dCBvZiB0b2tlbiBpcyBlbmQtb2YtbGluZSBub3JtYWxpemVkCisgICAgICogIGlzIGRlcGVuZGluZyBvbiBGRUFUVVJFX1hNTF9ST1VORFRSSVAuCisgICAgICoKKyAgICAgKiA8cD48c3Ryb25nPk5PVEU6PC9zdHJvbmc+IFhNTERlY2wgKCZsdDs/eG1sIC4uLj8mZ3Q7KSBpcyBub3QgcmVwb3J0ZWQgYnV0IGl0cyBjb250ZW50CisgICAgICogaXMgYXZhaWxhYmxlIHRocm91Z2ggb3B0aW9uYWwgcHJvcGVydGllcyAoc2VlIGNsYXNzIGRlc2NyaXB0aW9uIGFib3ZlKS4KKyAgICAgKgorICAgICAqIEBzZWUgI25leHQKKyAgICAgKiBAc2VlICNTVEFSVF9UQUcKKyAgICAgKiBAc2VlICNURVhUCisgICAgICogQHNlZSAjRU5EX1RBRworICAgICAqIEBzZWUgI0VORF9ET0NVTUVOVAorICAgICAqIEBzZWUgI0NPTU1FTlQKKyAgICAgKiBAc2VlICNET0NERUNMCisgICAgICogQHNlZSAjUFJPQ0VTU0lOR19JTlNUUlVDVElPTgorICAgICAqIEBzZWUgI0VOVElUWV9SRUYKKyAgICAgKiBAc2VlICNJR05PUkFCTEVfV0hJVEVTUEFDRQorICAgICAqLworICAgIGludCBuZXh0VG9rZW4oKQorICAgICAgICB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiwgSU9FeGNlcHRpb247CisKKyAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLy8gdXRpbGl0eSBtZXRob2RzIHRvIG1hayBYTUwgcGFyc2luZyBlYXNpZXIgLi4uCisKKyAgICAvKioKKyAgICAgKiBUZXN0IGlmIHRoZSBjdXJyZW50IGV2ZW50IGlzIG9mIHRoZSBnaXZlbiB0eXBlIGFuZCBpZiB0aGUKKyAgICAgKiBuYW1lc3BhY2UgYW5kIG5hbWUgZG8gbWF0Y2guIG51bGwgd2lsbCBtYXRjaCBhbnkgbmFtZXNwYWNlCisgICAgICogYW5kIGFueSBuYW1lLiBJZiB0aGUgdGVzdCBpcyBub3QgcGFzc2VkLCBhbiBleGNlcHRpb24gaXMKKyAgICAgKiB0aHJvd24uIFRoZSBleGNlcHRpb24gdGV4dCBpbmRpY2F0ZXMgdGhlIHBhcnNlciBwb3NpdGlvbiwKKyAgICAgKiB0aGUgZXhwZWN0ZWQgZXZlbnQgYW5kIHRoZSBjdXJyZW50IGV2ZW50IHRoYXQgaXMgbm90IG1lZXRpbmcgdGhlCisgICAgICogcmVxdWlyZW1lbnQuCisgICAgICoKKyAgICAgKiA8cD5Fc3NlbnRpYWxseSBpdCBkb2VzIHRoaXMKKyAgICAgKiA8cHJlPgorICAgICAqICBpZiAodHlwZSAhPSBnZXRFdmVudFR5cGUoKQorICAgICAqICB8fCAobmFtZXNwYWNlICE9IG51bGwgJmFtcDsmYW1wOyAgIW5hbWVzcGFjZS5lcXVhbHMoIGdldE5hbWVzcGFjZSAoKSApICkKKyAgICAgKiAgfHwgKG5hbWUgIT0gbnVsbCAmYW1wOyZhbXA7ICAhbmFtZS5lcXVhbHMoIGdldE5hbWUoKSApICkgKQorICAgICAqICAgICB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiggImV4cGVjdGVkICIrIFRZUEVTWyB0eXBlIF0rZ2V0UG9zaXRpb25EZXNjcmlwdGlvbigpKTsKKyAgICAgKiA8L3ByZT4KKyAgICAgKi8KKyAgICB2b2lkIHJlcXVpcmUoaW50IHR5cGUsIFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lKQorICAgICAgICB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiwgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBJZiBjdXJyZW50IGV2ZW50IGlzIFNUQVJUX1RBRyB0aGVuIGlmIG5leHQgZWxlbWVudCBpcyBURVhUIHRoZW4gZWxlbWVudCBjb250ZW50IGlzIHJldHVybmVkCisgICAgICogb3IgaWYgbmV4dCBldmVudCBpcyBFTkRfVEFHIHRoZW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkLCBvdGhlcndpc2UgZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKiBBZnRlciBjYWxsaW5nIHRoaXMgZnVuY3Rpb24gc3VjY2Vzc2Z1bGx5IHBhcnNlciB3aWxsIGJlIHBvc2l0aW9uZWQgb24gRU5EX1RBRy4KKyAgICAgKgorICAgICAqIDxwPlRoZSBtb3RpdmF0aW9uIGZvciB0aGlzIGZ1bmN0aW9uIGlzIHRvIGFsbG93IHRvIHBhcnNlIGNvbnNpc3RlbnRseSBib3RoCisgICAgICogZW1wdHkgZWxlbWVudHMgYW5kIGVsZW1lbnRzIHRoYXQgaGFzIG5vbiBlbXB0eSBjb250ZW50LCBmb3IgZXhhbXBsZSBmb3IgaW5wdXQ6IDxvbD4KKyAgICAgKiA8bGk+Jmx0O3RhZyZndDtmb28mbHQ7L3RhZyZndDsKKyAgICAgKiA8bGk+Jmx0O3RhZyZndDsmbHQ7L3RhZyZndDsgKHdoaWNoIGlzIGVxdWl2YWxlbnQgdG8gJmx0O3RhZy8mZ3Q7CisgICAgICogYm90aCBpbnB1dCBjYW4gYmUgcGFyc2VkIHdpdGggdGhlIHNhbWUgY29kZToKKyAgICAgKiA8cHJlPgorICAgICAqICAgcC5uZXh0VGFnKCkKKyAgICAgKiAgIHAucmVxdWlyZUV2ZW50KHAuU1RBUlRfVEFHLCAiIiwgInRhZyIpOworICAgICAqICAgU3RyaW5nIGNvbnRlbnQgPSBwLm5leHRUZXh0KCk7CisgICAgICogICBwLnJlcXVpcmVFdmVudChwLkVORF9UQUcsICIiLCAidGFnIik7CisgICAgICogPC9wcmU+CisgICAgICogVGhpcyBmdW5jdGlvbiB0b2dldGhlciB3aXRoIG5leHRUYWcgbWFrZSBpdCB2ZXJ5IGVhc3kgdG8gcGFyc2UgWE1MIHRoYXQgaGFzCisgICAgICogbm8gbWl4ZWQgY29udGVudC4KKyAgICAgKgorICAgICAqCisgICAgICogPHA+RXNzZW50aWFsbHkgaXQgZG9lcyB0aGlzCisgICAgICogPHByZT4KKyAgICAgKiAgaWYoZ2V0RXZlbnRUeXBlKCkgIT0gU1RBUlRfVEFHKSB7CisgICAgICogICAgIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uKAorICAgICAqICAgICAgICJwYXJzZXIgbXVzdCBiZSBvbiBTVEFSVF9UQUcgdG8gcmVhZCBuZXh0IHRleHQiLCB0aGlzLCBudWxsKTsKKyAgICAgKiAgfQorICAgICAqICBpbnQgZXZlbnRUeXBlID0gbmV4dCgpOworICAgICAqICBpZihldmVudFR5cGUgPT0gVEVYVCkgeworICAgICAqICAgICBTdHJpbmcgcmVzdWx0ID0gZ2V0VGV4dCgpOworICAgICAqICAgICBldmVudFR5cGUgPSBuZXh0KCk7CisgICAgICogICAgIGlmKGV2ZW50VHlwZSAhPSBFTkRfVEFHKSB7CisgICAgICogICAgICAgdGhyb3cgbmV3IFhtbFB1bGxQYXJzZXJFeGNlcHRpb24oCisgICAgICogICAgICAgICAgImV2ZW50IFRFWFQgaXQgbXVzdCBiZSBpbW1lZGlhdGVseSBmb2xsb3dlZCBieSBFTkRfVEFHIiwgdGhpcywgbnVsbCk7CisgICAgICogICAgICB9CisgICAgICogICAgICByZXR1cm4gcmVzdWx0OworICAgICAqICB9IGVsc2UgaWYoZXZlbnRUeXBlID09IEVORF9UQUcpIHsKKyAgICAgKiAgICAgcmV0dXJuICIiOworICAgICAqICB9IGVsc2UgeworICAgICAqICAgICB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbigKKyAgICAgKiAgICAgICAicGFyc2VyIG11c3QgYmUgb24gU1RBUlRfVEFHIG9yIFRFWFQgdG8gcmVhZCB0ZXh0IiwgdGhpcywgbnVsbCk7CisgICAgICogIH0KKyAgICAgKiA8L3ByZT4KKyAgICAgKi8KKyAgICBTdHJpbmcgbmV4dFRleHQoKSB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiwgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDYWxsIG5leHQoKSBhbmQgcmV0dXJuIGV2ZW50IGlmIGl0IGlzIFNUQVJUX1RBRyBvciBFTkRfVEFHCisgICAgICogb3RoZXJ3aXNlIHRocm93IGFuIGV4Y2VwdGlvbi4KKyAgICAgKiBJdCB3aWxsIHNraXAgd2hpdGVzcGFjZSBURVhUIGJlZm9yZSBhY3R1YWwgdGFnIGlmIGFueS4KKyAgICAgKgorICAgICAqIDxwPmVzc2VudGlhbGx5IGl0IGRvZXMgdGhpcworICAgICAqIDxwcmU+CisgICAgICogICBpbnQgZXZlbnRUeXBlID0gbmV4dCgpOworICAgICAqICAgaWYoZXZlbnRUeXBlID09IFRFWFQgJmFtcDsmYW1wOyAgaXNXaGl0ZXNwYWNlKCkpIHsgICAvLyBza2lwIHdoaXRlc3BhY2UKKyAgICAgKiAgICAgIGV2ZW50VHlwZSA9IG5leHQoKTsKKyAgICAgKiAgIH0KKyAgICAgKiAgIGlmIChldmVudFR5cGUgIT0gU1RBUlRfVEFHICZhbXA7JmFtcDsgIGV2ZW50VHlwZSAhPSBFTkRfVEFHKSB7CisgICAgICogICAgICB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbigiZXhwZWN0ZWQgc3RhcnQgb3IgZW5kIHRhZyIsIHRoaXMsIG51bGwpOworICAgICAqICAgfQorICAgICAqICAgcmV0dXJuIGV2ZW50VHlwZTsKKyAgICAgKiA8L3ByZT4KKyAgICAgKi8KKyAgICBpbnQgbmV4dFRhZygpIHRocm93cyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbjsKKworfQpkaWZmIC0tZ2l0IGEveG1sL3NyYy9tYWluL2phdmEvb3JnL3htbHB1bGwvdjEvWG1sUHVsbFBhcnNlckV4Y2VwdGlvbi5qYXZhIGIveG1sL3NyYy9tYWluL2phdmEvb3JnL3htbHB1bGwvdjEvWG1sUHVsbFBhcnNlckV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI0YjRiNzEKLS0tIC9kZXYvbnVsbAorKysgYi94bWwvc3JjL21haW4vamF2YS9vcmcveG1scHVsbC92MS9YbWxQdWxsUGFyc2VyRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw3NiBAQAorLyogLSotICAgICAgICAgICAgIGMtYmFzaWMtb2Zmc2V0OiA0OyBpbmRlbnQtdGFicy1tb2RlOiBuaWw7IC0qLSAgLy8tLS0tLS0xMDAtY29sdW1ucy13aWRlLS0tLS0tPnwqLworLy8gZm9yIGxpY2Vuc2UgcGxlYXNlIHNlZSBhY2NvbXBhbnlpbmcgTElDRU5TRS50eHQgZmlsZSAoYXZhaWxhYmxlIGFsc28gYXQgaHR0cDovL3d3dy54bWxwdWxsLm9yZy8pCisKK3BhY2thZ2Ugb3JnLnhtbHB1bGwudjE7CisKKy8qKgorICogVGhpcyBleGNlcHRpb24gaXMgdGhyb3duIHRvIHNpZ25hbCBYTUwgUHVsbCBQYXJzZXIgcmVsYXRlZCBmYXVsdHMuCisgKgorICogQGF1dGhvciA8YSBocmVmPSJodHRwOi8vd3d3LmV4dHJlbWUuaW5kaWFuYS5lZHUvfmFzbG9tLyI+QWxla3NhbmRlciBTbG9taW5za2k8L2E+CisgKi8KK3B1YmxpYyBjbGFzcyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKyAgICBwcm90ZWN0ZWQgVGhyb3dhYmxlIGRldGFpbDsKKyAgICBwcm90ZWN0ZWQgaW50IHJvdyA9IC0xOworICAgIHByb3RlY3RlZCBpbnQgY29sdW1uID0gLTE7CisKKyAgICAvKiAgICBwdWJsaWMgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbigpIHsKKyAgICAgICAgICB9Ki8KKworICAgIHB1YmxpYyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uKFN0cmluZyBzKSB7CisgICAgICAgIHN1cGVyKHMpOworICAgIH0KKworICAgIC8qCisgICAgcHVibGljIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24oU3RyaW5nIHMsIFRocm93YWJsZSB0aHJ3YmxlKSB7CisgICAgICAgIHN1cGVyKHMpOworICAgICAgICB0aGlzLmRldGFpbCA9IHRocndibGU7CisgICAgICAgIH0KKworICAgIHB1YmxpYyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uKFN0cmluZyBzLCBpbnQgcm93LCBpbnQgY29sdW1uKSB7CisgICAgICAgIHN1cGVyKHMpOworICAgICAgICB0aGlzLnJvdyA9IHJvdzsKKyAgICAgICAgdGhpcy5jb2x1bW4gPSBjb2x1bW47CisgICAgfQorICAgICovCisKKyAgICBwdWJsaWMgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbihTdHJpbmcgbXNnLCBYbWxQdWxsUGFyc2VyIHBhcnNlciwgVGhyb3dhYmxlIGNoYWluKSB7CisgICAgICAgIHN1cGVyICgobXNnID09IG51bGwgPyAiIiA6IG1zZysiICIpCisgICAgICAgICAgICAgICArIChwYXJzZXIgPT0gbnVsbCA/ICIiIDogIihwb3NpdGlvbjoiK3BhcnNlci5nZXRQb3NpdGlvbkRlc2NyaXB0aW9uKCkrIikgIikKKyAgICAgICAgICAgICAgICsgKGNoYWluID09IG51bGwgPyAiIiA6ICJjYXVzZWQgYnk6ICIrY2hhaW4pKTsKKworICAgICAgICBpZiAocGFyc2VyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMucm93ID0gcGFyc2VyLmdldExpbmVOdW1iZXIoKTsKKyAgICAgICAgICAgIHRoaXMuY29sdW1uID0gcGFyc2VyLmdldENvbHVtbk51bWJlcigpOworICAgICAgICB9CisgICAgICAgIHRoaXMuZGV0YWlsID0gY2hhaW47CisgICAgfQorCisgICAgcHVibGljIFRocm93YWJsZSBnZXREZXRhaWwoKSB7IHJldHVybiBkZXRhaWw7IH0KKyAgICAvLyAgICBwdWJsaWMgdm9pZCBzZXREZXRhaWwoVGhyb3dhYmxlIGNhdXNlKSB7IHRoaXMuZGV0YWlsID0gY2F1c2U7IH0KKyAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKSB7IHJldHVybiByb3c7IH0KKyAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpIHsgcmV0dXJuIGNvbHVtbjsgfQorCisgICAgLyoKKyAgICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2UoKSB7CisgICAgICAgIGlmKGRldGFpbCA9PSBudWxsKQorICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldE1lc3NhZ2UoKTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldE1lc3NhZ2UoKSArICI7IG5lc3RlZCBleGNlcHRpb24gaXM6IFxuXHQiCisgICAgICAgICAgICAgICAgKyBkZXRhaWwuZ2V0TWVzc2FnZSgpOworICAgIH0KKyAgICAqLworCisgICAgLy9OT1RFOiBjb2RlIHRoYXQgcHJpbnRzIHRoaXMgYW5kIGRldGFpbCBpcyBkaWZmaWN1bHQgaW4gSjJNRQorICAgIHB1YmxpYyB2b2lkIHByaW50U3RhY2tUcmFjZSgpIHsKKyAgICAgICAgaWYgKGRldGFpbCA9PSBudWxsKSB7CisgICAgICAgICAgICBzdXBlci5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZChTeXN0ZW0uZXJyKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKHN1cGVyLmdldE1lc3NhZ2UoKSArICI7IG5lc3RlZCBleGNlcHRpb24gaXM6Iik7CisgICAgICAgICAgICAgICAgZGV0YWlsLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCit9CisKZGlmZiAtLWdpdCBhL3htbC9zcmMvbWFpbi9qYXZhL29yZy94bWxwdWxsL3YxL1htbFB1bGxQYXJzZXJGYWN0b3J5LmphdmEgYi94bWwvc3JjL21haW4vamF2YS9vcmcveG1scHVsbC92MS9YbWxQdWxsUGFyc2VyRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQzNzVhNDEKLS0tIC9kZXYvbnVsbAorKysgYi94bWwvc3JjL21haW4vamF2YS9vcmcveG1scHVsbC92MS9YbWxQdWxsUGFyc2VyRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMzQ1IEBACisvKiAtKi0gICAgICAgICAgICAgYy1iYXNpYy1vZmZzZXQ6IDQ7IGluZGVudC10YWJzLW1vZGU6IG5pbDsgLSotICAvLy0tLS0tLTEwMC1jb2x1bW5zLXdpZGUtLS0tLS0+fCovCisvLyBmb3IgbGljZW5zZSBwbGVhc2Ugc2VlIGFjY29tcGFueWluZyBMSUNFTlNFLnR4dCBmaWxlIChhdmFpbGFibGUgYWxzbyBhdCBodHRwOi8vd3d3LnhtbHB1bGwub3JnLykKKworcGFja2FnZSBvcmcueG1scHVsbC52MTsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyB1c2VkIHRvIGNyZWF0ZSBpbXBsZW1lbnRhdGlvbnMgb2YgWE1MIFB1bGwgUGFyc2VyIGRlZmluZWQgaW4gWE1QVUxMIFYxIEFQSS4KKyAqIFRoZSBuYW1lIG9mIGFjdHVhbCBmYWN0b3J5IGNsYXNzIHdpbGwgYmUgZGV0ZXJtaW5lZCBiYXNlZCBvbiBzZXZlcmFsIHBhcmFtZXRlcnMuCisgKiBJdCB3b3JrcyBzaW1pbGFyIHRvIEpBWFAgYnV0IHRhaWxvcmVkIHRvIHdvcmsgaW4gSjJNRSBlbnZpcm9ubWVudHMKKyAqIChubyBhY2Nlc3MgdG8gc3lzdGVtIHByb3BlcnRpZXMgb3IgZmlsZSBzeXN0ZW0pIHNvIG5hbWUgb2YgcGFyc2VyIGNsYXNzIGZhY3RvcnkgdG8gdXNlCisgKiBhbmQgaXRzIGNsYXNzIHVzZWQgZm9yIGxvYWRpbmcgKG5vIGNsYXNzIGxvYWRlciAtIG9uIEoyTUUgbm8gYWNjZXNzIHRvIGNvbnRleHQgY2xhc3MgbG9hZGVycykKKyAqIG11c3QgYmUgcGFzc2VkIGV4cGxpY2l0bHkuIElmIG5vIG5hbWUgb2YgcGFyc2VyIGZhY3Rvcnkgd2FzIHBhc3NlZCAob3IgaXMgbnVsbCkKKyAqIGl0IHdpbGwgdHJ5IHRvIGZpbmQgbmFtZSBieSBzZWFyY2hpbmcgaW4gQ0xBU1NQQVRIIGZvcgorICogTUVUQS1JTkYvc2VydmljZXMvb3JnLnhtbHB1bGwudjEuWG1sUHVsbFBhcnNlckZhY3RvcnkgcmVzb3VyY2UgdGhhdCBzaG91bGQgY29udGFpbgorICogYSBjb21tYSBzZXBhcmF0ZWQgbGlzdCBvZiBjbGFzcyBuYW1lcyBvZiBmYWN0b3JpZXMgb3IgcGFyc2VycyB0byB0cnkgKGluIG9yZGVyIGZyb20KKyAqIGxlZnQgdG8gdGhlIHJpZ2h0KS4gSWYgbm9uZSBmb3VuZCwgaXQgd2lsbCB0aHJvdyBhbiBleGNlcHRpb24uCisgKgorICogPGJyIC8+PHN0cm9uZz5OT1RFOjwvc3Ryb25nPkluIEoyU0Ugb3IgSjJFRSBlbnZpcm9ubWVudHMsIHlvdSBtYXkgd2FudCB0byB1c2UKKyAqIDxjb2RlPm5ld0luc3RhbmNlKHByb3BlcnR5LCBjbGFzc0xvYWRlckN0eCk8L2NvZGU+CisgKiB3aGVyZSBmaXJzdCBhcmd1bWVudCBpcworICogPGNvZGU+U3lzdGVtLmdldFByb3BlcnR5KFhtbFB1bGxQYXJzZXJGYWN0b3J5LlBST1BFUlRZX05BTUUpPC9jb2RlPgorICogYW5kIHNlY29uZCBpcyA8Y29kZT5UaHJlYWQuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkuZ2V0Q2xhc3MoKTwvY29kZT4gLgorICoKKyAqIEBzZWUgWG1sUHVsbFBhcnNlcgorICoKKyAqIEBhdXRob3IgPGEgaHJlZj0iaHR0cDovL3d3dy5leHRyZW1lLmluZGlhbmEuZWR1L35hc2xvbS8iPkFsZWtzYW5kZXIgU2xvbWluc2tpPC9hPgorICogQGF1dGhvciBTdGVmYW4gSGF1c3RlaW4KKyAqLworCitwdWJsaWMgY2xhc3MgWG1sUHVsbFBhcnNlckZhY3RvcnkgeworICAgIC8qKiB1c2VkIGFzIGRlZmF1bHQgY2xhc3MgdG8gc2VydmVyIGFzIGNvbnRleHQgY2xhc3MgaW4gbmV3SW5zdGFuY2UoKSAqLworICAgIGZpbmFsIHN0YXRpYyBDbGFzcyByZWZlcmVuY2VDb250ZXh0Q2xhc3M7CisKKyAgICBzdGF0aWMgeworICAgICAgICBYbWxQdWxsUGFyc2VyRmFjdG9yeSBmID0gbmV3IFhtbFB1bGxQYXJzZXJGYWN0b3J5KCk7CisgICAgICAgIHJlZmVyZW5jZUNvbnRleHRDbGFzcyA9IGYuZ2V0Q2xhc3MoKTsKKyAgICB9CisKKyAgICAvKiogTmFtZSBvZiB0aGUgc3lzdGVtIG9yIG1pZGxldCBwcm9wZXJ0eSB0aGF0IHNob3VsZCBiZSB1c2VkIGZvcgorICAgICBhIHN5c3RlbSBwcm9wZXJ0eSBjb250YWluaW5nIGEgY29tbWEgc2VwYXJhdGVkIGxpc3Qgb2YgZmFjdG9yeQorICAgICBvciBwYXJzZXIgY2xhc3MgbmFtZXMgKHZhbHVlOgorICAgICBvcmcueG1scHVsbC52MS5YbWxQdWxsUGFyc2VyRmFjdG9yeSkuICovCisKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZX05BTUUgPQorICAgICAgICAib3JnLnhtbHB1bGwudjEuWG1sUHVsbFBhcnNlckZhY3RvcnkiOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU09VUkNFX05BTUUgPQorICAgICAgICAiL01FVEEtSU5GL3NlcnZpY2VzLyIgKyBQUk9QRVJUWV9OQU1FOworCisKKyAgICAvLyBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX1BST1BFUlRZID0KKyAgICAvLyAgICAib3JnLnhtbHB1bGwueHBwMy5YbWxQdWxsUGFyc2VyLG9yZy5reG1sMi5pby5LWG1sUGFyc2VyIjsKKworCisgICAgcHJvdGVjdGVkIEFycmF5TGlzdCBwYXJzZXJDbGFzc2VzOworICAgIHByb3RlY3RlZCBTdHJpbmcgY2xhc3NOYW1lc0xvY2F0aW9uOworCisgICAgcHJvdGVjdGVkIEFycmF5TGlzdCBzZXJpYWxpemVyQ2xhc3NlczsKKworCisgICAgLy8gZmVhdHVyZXMgYXJlIGtlcHQgdGhlcmUKKyAgICBwcm90ZWN0ZWQgSGFzaE1hcCBmZWF0dXJlcyA9IG5ldyBIYXNoTWFwKCk7CisKKworICAgIC8qKgorICAgICAqIFByb3RlY3RlZCBjb25zdHJ1Y3RvciB0byBiZSBjYWxsZWQgYnkgZmFjdG9yeSBpbXBsZW1lbnRhdGlvbnMuCisgICAgICovCisKKyAgICBwcm90ZWN0ZWQgWG1sUHVsbFBhcnNlckZhY3RvcnkoKSB7CisgICAgfQorCisKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZmVhdHVyZXMgdG8gYmUgc2V0IHdoZW4gWE1MIFB1bGwgUGFyc2VyIGlzIGNyZWF0ZWQgYnkgdGhpcyBmYWN0b3J5LgorICAgICAqIDxwPjxiPk5PVEU6PC9iPiBmYWN0b3J5IGZlYXR1cmVzIGFyZSBub3QgdXNlZCBmb3IgWE1MIFNlcmlhbGl6ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBzdHJpbmcgd2l0aCBVUkkgaWRlbnRpZnlpbmcgZmVhdHVyZQorICAgICAqIEBwYXJhbSBzdGF0ZSBpZiB0cnVlIGZlYXR1cmUgd2lsbCBiZSBzZXQ7IGlmIGZhbHNlIHdpbGwgYmUgaWdub3JlZAorICAgICAqLworCisgICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgbmFtZSwgYm9vbGVhbiBzdGF0ZSkgdGhyb3dzIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworICAgICAgICBmZWF0dXJlcy5wdXQobmFtZSwgc3RhdGUpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBmZWF0dXJlIHdpdGggZ2l2ZW4gbmFtZS4KKyAgICAgKiA8cD48Yj5OT1RFOjwvYj4gZmFjdG9yeSBmZWF0dXJlcyBhcmUgbm90IHVzZWQgZm9yIFhNTCBTZXJpYWxpemVyLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgZmVhdHVyZSB0byBiZSByZXRyaWV2ZWQuCisgICAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgbmFtZWQgZmVhdHVyZS4KKyAgICAgKiAgICAgVW5rbm93biBmZWF0dXJlcyBhcmUgPHN0cmluZz5hbHdheXM8L3N0cm9uZz4gcmV0dXJuZWQgYXMgZmFsc2UKKyAgICAgKi8KKworICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUgKFN0cmluZyBuYW1lKSB7CisgICAgICAgIEJvb2xlYW4gdmFsdWUgPSAoQm9vbGVhbikgZmVhdHVyZXMuZ2V0KG5hbWUpOworICAgICAgICByZXR1cm4gdmFsdWUgIT0gbnVsbCA/IHZhbHVlLmJvb2xlYW5WYWx1ZSgpIDogZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3BlY2lmaWVzIHRoYXQgdGhlIHBhcnNlciBwcm9kdWNlZCBieSB0aGlzIGZhY3Rvcnkgd2lsbCBwcm92aWRlCisgICAgICogc3VwcG9ydCBmb3IgWE1MIG5hbWVzcGFjZXMuCisgICAgICogQnkgZGVmYXVsdCB0aGUgdmFsdWUgb2YgdGhpcyBpcyBzZXQgdG8gZmFsc2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXdhcmVuZXNzIHRydWUgaWYgdGhlIHBhcnNlciBwcm9kdWNlZCBieSB0aGlzIGNvZGUKKyAgICAgKiAgICB3aWxsIHByb3ZpZGUgc3VwcG9ydCBmb3IgWE1MIG5hbWVzcGFjZXM7ICBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisKKyAgICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2VBd2FyZShib29sZWFuIGF3YXJlbmVzcykgeworICAgICAgICBmZWF0dXJlcy5wdXQgKFhtbFB1bGxQYXJzZXIuRkVBVFVSRV9QUk9DRVNTX05BTUVTUEFDRVMsIGF3YXJlbmVzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBmYWN0b3J5IGlzIGNvbmZpZ3VyZWQgdG8gcHJvZHVjZQorICAgICAqIHBhcnNlcnMgd2hpY2ggYXJlIG5hbWVzcGFjZSBhd2FyZQorICAgICAqIChpdCBzaW1wbHkgc2V0IGZlYXR1cmUgWG1sUHVsbFBhcnNlci5GRUFUVVJFX1BST0NFU1NfTkFNRVNQQUNFUyB0byB0cnVlIG9yIGZhbHNlKS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gIHRydWUgaWYgdGhlIGZhY3RvcnkgaXMgY29uZmlndXJlZCB0byBwcm9kdWNlIHBhcnNlcnMKKyAgICAgKiAgICB3aGljaCBhcmUgbmFtZXNwYWNlIGF3YXJlOyBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc05hbWVzcGFjZUF3YXJlKCkgeworICAgICAgICByZXR1cm4gZ2V0RmVhdHVyZSAoWG1sUHVsbFBhcnNlci5GRUFUVVJFX1BST0NFU1NfTkFNRVNQQUNFUyk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBTcGVjaWZpZXMgdGhhdCB0aGUgcGFyc2VyIHByb2R1Y2VkIGJ5IHRoaXMgZmFjdG9yeSB3aWxsIGJlIHZhbGlkYXRpbmcKKyAgICAgKiAoaXQgc2ltcGx5IHNldCBmZWF0dXJlIFhtbFB1bGxQYXJzZXIuRkVBVFVSRV9WQUxJREFUSU9OIHRvIHRydWUgb3IgZmFsc2UpLgorICAgICAqCisgICAgICogQnkgZGVmYXVsdCB0aGUgdmFsdWUgb2YgdGhpcyBpcyBzZXQgdG8gZmFsc2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdmFsaWRhdGluZyAtIGlmIHRydWUgdGhlIHBhcnNlcnMgY3JlYXRlZCBieSB0aGlzIGZhY3RvcnkgIG11c3QgYmUgdmFsaWRhdGluZy4KKyAgICAgKi8KKworICAgIHB1YmxpYyB2b2lkIHNldFZhbGlkYXRpbmcoYm9vbGVhbiB2YWxpZGF0aW5nKSB7CisgICAgICAgIGZlYXR1cmVzLnB1dCAoWG1sUHVsbFBhcnNlci5GRUFUVVJFX1ZBTElEQVRJT04sIHZhbGlkYXRpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgZmFjdG9yeSBpcyBjb25maWd1cmVkIHRvIHByb2R1Y2UgcGFyc2VycworICAgICAqIHdoaWNoIHZhbGlkYXRlIHRoZSBYTUwgY29udGVudCBkdXJpbmcgcGFyc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuICAgdHJ1ZSBpZiB0aGUgZmFjdG9yeSBpcyBjb25maWd1cmVkIHRvIHByb2R1Y2UgcGFyc2VycworICAgICAqIHdoaWNoIHZhbGlkYXRlIHRoZSBYTUwgY29udGVudCBkdXJpbmcgcGFyc2U7IGZhbHNlIG90aGVyd2lzZS4KKyAgICAgKi8KKworICAgIHB1YmxpYyBib29sZWFuIGlzVmFsaWRhdGluZygpIHsKKyAgICAgICAgcmV0dXJuIGdldEZlYXR1cmUgKFhtbFB1bGxQYXJzZXIuRkVBVFVSRV9WQUxJREFUSU9OKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIGEgWE1MIFB1bGwgUGFyc2VyCisgICAgICogdXNpbmcgdGhlIGN1cnJlbnRseSBjb25maWd1cmVkIGZhY3RvcnkgZmVhdHVyZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEEgbmV3IGluc3RhbmNlIG9mIGEgWE1MIFB1bGwgUGFyc2VyLgorICAgICAqIEB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiBpZiBhIHBhcnNlciBjYW5ub3QgYmUgY3JlYXRlZCB3aGljaCBzYXRpc2ZpZXMgdGhlCisgICAgICogcmVxdWVzdGVkIGNvbmZpZ3VyYXRpb24uCisgICAgICovCisKKyAgICBwdWJsaWMgWG1sUHVsbFBhcnNlciBuZXdQdWxsUGFyc2VyKCkgdGhyb3dzIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworCisgICAgICAgIGlmIChwYXJzZXJDbGFzc2VzID09IG51bGwpIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uCisgICAgICAgICAgICAgICAgKCJGYWN0b3J5IGluaXRpYWxpemF0aW9uIHdhcyBpbmNvbXBsZXRlIC0gaGFzIG5vdCB0cmllZCAiK2NsYXNzTmFtZXNMb2NhdGlvbik7CisKKyAgICAgICAgaWYgKHBhcnNlckNsYXNzZXMuc2l6ZSgpID09IDApIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uCisgICAgICAgICAgICAgICAgKCJObyB2YWxpZCBwYXJzZXIgY2xhc3NlcyBmb3VuZCBpbiAiK2NsYXNzTmFtZXNMb2NhdGlvbik7CisKKyAgICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciBpc3N1ZXMgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyc2VyQ2xhc3Nlcy5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgZmluYWwgQ2xhc3MgcHBDbGFzcyA9IChDbGFzcykgcGFyc2VyQ2xhc3Nlcy5nZXQoaSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZpbmFsIFhtbFB1bGxQYXJzZXIgcHAgPSAoWG1sUHVsbFBhcnNlcikgcHBDbGFzcy5uZXdJbnN0YW5jZSgpOworCisgICAgICAgICAgICAgICAgZm9yIChJdGVyYXRvciBpdGVyID0gZmVhdHVyZXMua2V5U2V0KCkuaXRlcmF0b3IoKTsgaXRlci5oYXNOZXh0KCk7ICkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcga2V5ID0gKFN0cmluZykgaXRlci5uZXh0KCk7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIEJvb2xlYW4gdmFsdWUgPSAoQm9vbGVhbikgZmVhdHVyZXMuZ2V0KGtleSk7CisgICAgICAgICAgICAgICAgICAgIGlmKHZhbHVlICE9IG51bGwgJiYgdmFsdWUuYm9vbGVhblZhbHVlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBwLnNldEZlYXR1cmUoa2V5LCB0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gcHA7CisKKyAgICAgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgaXNzdWVzLmFwcGVuZCAocHBDbGFzcy5nZXROYW1lICgpICsgIjogIisgZXgudG9TdHJpbmcgKCkrIjsgIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiAoImNvdWxkIG5vdCBjcmVhdGUgcGFyc2VyOiAiK2lzc3Vlcyk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIGEgWE1MIFNlcmlhbGl6ZXIuCisgICAgICoKKyAgICAgKiA8cD48Yj5OT1RFOjwvYj4gZmFjdG9yeSBmZWF0dXJlcyBhcmUgbm90IHVzZWQgZm9yIFhNTCBTZXJpYWxpemVyLgorICAgICAqCisgICAgICogQHJldHVybiBBIG5ldyBpbnN0YW5jZSBvZiBhIFhNTCBTZXJpYWxpemVyLgorICAgICAqIEB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiBpZiBhIHBhcnNlciBjYW5ub3QgYmUgY3JlYXRlZCB3aGljaCBzYXRpc2ZpZXMgdGhlCisgICAgICogcmVxdWVzdGVkIGNvbmZpZ3VyYXRpb24uCisgICAgICovCisKKyAgICBwdWJsaWMgWG1sU2VyaWFsaXplciBuZXdTZXJpYWxpemVyKCkgdGhyb3dzIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworCisgICAgICAgIGlmIChzZXJpYWxpemVyQ2xhc3NlcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbgorICAgICAgICAgICAgICAgICgiRmFjdG9yeSBpbml0aWFsaXphdGlvbiBpbmNvbXBsZXRlIC0gaGFzIG5vdCB0cmllZCAiK2NsYXNzTmFtZXNMb2NhdGlvbik7CisgICAgICAgIH0KKyAgICAgICAgaWYoc2VyaWFsaXplckNsYXNzZXMuc2l6ZSgpID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBYbWxQdWxsUGFyc2VyRXhjZXB0aW9uCisgICAgICAgICAgICAgICAgKCJObyB2YWxpZCBzZXJpYWxpemVyIGNsYXNzZXMgZm91bmQgaW4gIitjbGFzc05hbWVzTG9jYXRpb24pOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciBpc3N1ZXMgPSBuZXcgU3RyaW5nQnVpbGRlciAoKTsKKworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNlcmlhbGl6ZXJDbGFzc2VzLnNpemUgKCk7IGkrKykgeworICAgICAgICAgICAgZmluYWwgQ2xhc3MgcHBDbGFzcyA9IChDbGFzcykgc2VyaWFsaXplckNsYXNzZXMuZ2V0KGkpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmaW5hbCBYbWxTZXJpYWxpemVyIHNlciA9IChYbWxTZXJpYWxpemVyKSBwcENsYXNzLm5ld0luc3RhbmNlKCk7CisKKyAgICAgICAgICAgICAgICByZXR1cm4gc2VyOworCisgICAgICAgICAgICB9IGNhdGNoKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIGlzc3Vlcy5hcHBlbmQgKHBwQ2xhc3MuZ2V0TmFtZSAoKSArICI6ICIrIGV4LnRvU3RyaW5nICgpKyI7ICIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdGhyb3cgbmV3IFhtbFB1bGxQYXJzZXJFeGNlcHRpb24gKCJjb3VsZCBub3QgY3JlYXRlIHNlcmlhbGl6ZXI6ICIraXNzdWVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgYSBQdWxsUGFyc2VyRmFjdG9yeSB0aGF0IGNhbiBiZSB1c2VkCisgICAgICogdG8gY3JlYXRlIFhNTCBwdWxsIHBhcnNlcnMgKHNlZSBjbGFzcyBkZXNjcmlwdGlvbiBmb3IgbW9yZQorICAgICAqIGRldGFpbHMpLgorICAgICAqCisgICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiBhIFB1bGxQYXJzZXJGYWN0b3J5LCBhcyByZXR1cm5lZCBieSBuZXdJbnN0YW5jZSAobnVsbCwgbnVsbCk7CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBYbWxQdWxsUGFyc2VyRmFjdG9yeSBuZXdJbnN0YW5jZSAoKSB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXdJbnN0YW5jZShudWxsLCBudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFhtbFB1bGxQYXJzZXJGYWN0b3J5IG5ld0luc3RhbmNlIChTdHJpbmcgY2xhc3NOYW1lcywgQ2xhc3MgY29udGV4dCkKKyAgICAgICAgdGhyb3dzIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworCisgICAgICAgIC8qCisgICAgICAgIGlmIChjb250ZXh0ID09IG51bGwpIHsKKyAgICAgICAgICAgIC8vTk9URTogbWFrZSBzdXJlIGNvbnRleHQgdXNlcyB0aGUgc2FtZSBjbGFzcyBsb2FkZXIgYXMgQVBJIGNsYXNzZXMKKyAgICAgICAgICAgIC8vICAgICAgdGhpcyBpcyB0aGUgYmVzdCB3ZSBjYW4gZG8gd2l0aG91dCBoYXZpbmcgYWNjZXNzIHRvIGNvbnRleHQgY2xhc3Nsb2FkZXIgaW4gSjJNRQorICAgICAgICAgICAgLy8gICAgICBpZiBBUEkgaXMgaW4gdGhlIHNhbWUgY2xhc3Nsb2FkZXIgYXMgaW1wbGVtZW50YXRpb24gdGhlbiB0aGlzIHdpbGwgd29yaworICAgICAgICAgICAgY29udGV4dCA9IHJlZmVyZW5jZUNvbnRleHRDbGFzczsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyAgY2xhc3NOYW1lc0xvY2F0aW9uID0gbnVsbDsKKworICAgICAgICBpZiAoY2xhc3NOYW1lcyA9PSBudWxsIHx8IGNsYXNzTmFtZXMubGVuZ3RoKCkgPT0gMCB8fCAiREVGQVVMVCIuZXF1YWxzKGNsYXNzTmFtZXMpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gY29udGV4dC5nZXRSZXNvdXJjZUFzU3RyZWFtIChSRVNPVVJDRV9OQU1FKTsKKworICAgICAgICAgICAgICAgIGlmIChpcyA9PSBudWxsKSB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbgorICAgICAgICAgICAgICAgICAgICAgICAgKCJyZXNvdXJjZSBub3QgZm91bmQ6ICIrUkVTT1VSQ0VfTkFNRQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIiBtYWtlIHN1cmUgdGhhdCBwYXJzZXIgaW1wbGVtZW50aW5nIFhtbFB1bGwgQVBJIGlzIGF2YWlsYWJsZSIpOworICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCisgICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGNoID0gaXMucmVhZCgpOworICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPCAwKSBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY2ggPiAnICcpCisgICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoKGNoYXIpIGNoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaXMuY2xvc2UgKCk7CisKKyAgICAgICAgICAgICAgICBjbGFzc05hbWVzID0gc2IudG9TdHJpbmcgKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiAobnVsbCwgbnVsbCwgZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjbGFzc05hbWVzTG9jYXRpb24gPSAicmVzb3VyY2UgIitSRVNPVVJDRV9OQU1FKyIgdGhhdCBjb250YWluZWQgJyIrY2xhc3NOYW1lcysiJyI7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBjbGFzc05hbWVzTG9jYXRpb24gPQorICAgICAgICAgICAgICAgICJwYXJhbWV0ZXIgY2xhc3NOYW1lcyB0byBuZXdJbnN0YW5jZSgpIHRoYXQgY29udGFpbmVkICciK2NsYXNzTmFtZXMrIiciOworICAgICAgICB9CisgICAgICAgICovCisgICAgICAgIGNsYXNzTmFtZXMgPSAib3JnLmt4bWwyLmlvLktYbWxQYXJzZXIsb3JnLmt4bWwyLmlvLktYbWxTZXJpYWxpemVyIjsKKworICAgICAgICBYbWxQdWxsUGFyc2VyRmFjdG9yeSBmYWN0b3J5ID0gbnVsbDsKKyAgICAgICAgZmluYWwgQXJyYXlMaXN0IHBhcnNlckNsYXNzZXMgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIGZpbmFsIEFycmF5TGlzdCBzZXJpYWxpemVyQ2xhc3NlcyA9IG5ldyBBcnJheUxpc3QoKTsKKyAgICAgICAgaW50IHBvcyA9IDA7CisKKyAgICAgICAgd2hpbGUgKHBvcyA8IGNsYXNzTmFtZXMubGVuZ3RoICgpKSB7CisgICAgICAgICAgICBpbnQgY3V0ID0gY2xhc3NOYW1lcy5pbmRleE9mICgnLCcsIHBvcyk7CisKKyAgICAgICAgICAgIGlmIChjdXQgPT0gLTEpIGN1dCA9IGNsYXNzTmFtZXMubGVuZ3RoICgpOworICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBjbGFzc05hbWVzLnN1YnN0cmluZyAocG9zLCBjdXQpOworCisgICAgICAgICAgICBDbGFzcyBjYW5kaWRhdGUgPSBudWxsOworICAgICAgICAgICAgT2JqZWN0IGluc3RhbmNlID0gbnVsbDsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjYW5kaWRhdGUgPSBDbGFzcy5mb3JOYW1lIChuYW1lKTsKKyAgICAgICAgICAgICAgICAvLyBuZWNlc3NhcnkgYmVjYXVzZSBvZiBKMk1FIC5jbGFzcyBpc3N1ZQorICAgICAgICAgICAgICAgIGluc3RhbmNlID0gY2FuZGlkYXRlLm5ld0luc3RhbmNlICgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7fQorCisgICAgICAgICAgICBpZiAoY2FuZGlkYXRlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBib29sZWFuIHJlY29nbml6ZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2UgaW5zdGFuY2VvZiBYbWxQdWxsUGFyc2VyKSB7CisgICAgICAgICAgICAgICAgICAgIHBhcnNlckNsYXNzZXMuYWRkKGNhbmRpZGF0ZSk7CisgICAgICAgICAgICAgICAgICAgIHJlY29nbml6ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2UgaW5zdGFuY2VvZiBYbWxTZXJpYWxpemVyKSB7CisgICAgICAgICAgICAgICAgICAgIHNlcmlhbGl6ZXJDbGFzc2VzLmFkZChjYW5kaWRhdGUpOworICAgICAgICAgICAgICAgICAgICByZWNvZ25pemVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlIGluc3RhbmNlb2YgWG1sUHVsbFBhcnNlckZhY3RvcnkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZhY3RvcnkgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgZmFjdG9yeSA9IChYbWxQdWxsUGFyc2VyRmFjdG9yeSkgaW5zdGFuY2U7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmVjb2duaXplZCA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICghcmVjb2duaXplZCkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiAoImluY29tcGF0aWJsZSBjbGFzczogIituYW1lKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwb3MgPSBjdXQgKyAxOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGZhY3RvcnkgPT0gbnVsbCkgeworICAgICAgICAgICAgZmFjdG9yeSA9IG5ldyBYbWxQdWxsUGFyc2VyRmFjdG9yeSAoKTsKKyAgICAgICAgfQorICAgICAgICBmYWN0b3J5LnBhcnNlckNsYXNzZXMgPSBwYXJzZXJDbGFzc2VzOworICAgICAgICBmYWN0b3J5LnNlcmlhbGl6ZXJDbGFzc2VzID0gc2VyaWFsaXplckNsYXNzZXM7CisgICAgICAgIGZhY3RvcnkuY2xhc3NOYW1lc0xvY2F0aW9uID0gIm9yZy5reG1sMi5pby5rWG1sUGFyc2VyLG9yZy5reG1sMi5pby5LWG1sU2VyaWFsaXplciI7CisgICAgICAgIHJldHVybiBmYWN0b3J5OworICAgIH0KK30KZGlmZiAtLWdpdCBhL3htbC9zcmMvbWFpbi9qYXZhL29yZy94bWxwdWxsL3YxL1htbFNlcmlhbGl6ZXIuamF2YSBiL3htbC9zcmMvbWFpbi9qYXZhL29yZy94bWxwdWxsL3YxL1htbFNlcmlhbGl6ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMDFhMjQ3Ci0tLSAvZGV2L251bGwKKysrIGIveG1sL3NyYy9tYWluL2phdmEvb3JnL3htbHB1bGwvdjEvWG1sU2VyaWFsaXplci5qYXZhCkBAIC0wLDAgKzEsMzI1IEBACitwYWNrYWdlIG9yZy54bWxwdWxsLnYxOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLldyaXRlcjsKKworLyoqCisgKiBEZWZpbmUgYW4gaW50ZXJmYWNlIHRvIHNlcmlhbGl6YXRpb24gb2YgWE1MIEluZm9zZXQuCisgKiBUaGlzIGludGVyZmFjZSBhYnN0cmFjdHMgYXdheSBpZiBzZXJpYWxpemVkIFhNTCBpcyBYTUwgMS4wIGNvbXBhdGlibGUgdGV4dCBvcgorICogb3RoZXIgZm9ybWF0cyBvZiBYTUwgMS4wIHNlcmlhbGl6YXRpb25zIChzdWNoIGFzIGJpbmFyeSBYTUwgZm9yIGV4YW1wbGUgd2l0aCBXQlhNTCkuCisgKgorICogPHA+PGI+UExFQVNFIE5PVEU6PC9iPiBUaGlzIGludGVyZmFjZSB3aWxsIGJlIHBhcnQgb2YgWG1sUHVsbCAxLjIgQVBJLgorICogSXQgaXMgaW5jbHVkZWQgYXMgYmFzaXMgZm9yIGRpc2N1c3Npb24uIEl0IG1heSBjaGFuZ2UgaW4gYW55IHdheS4KKyAqCisgKiA8cD5FeGNlcHRpb25zIHRoYXQgbWF5IGJlIHRocm93biBhcmU6IElPRXhjZXB0aW9uIG9yIHJ1bnRpbWUgZXhjZXB0aW9uCisgKiAobW9yZSBydW50aW1lIGV4Y2VwdGlvbnMgY2FuIGJlIHRocm93biBidXQgYXJlIG5vdCBkZWNsYXJlZCBhbmQgYXMgc3VjaAorICogaGF2ZSBubyBzZW1hbnRpY3MgZGVmaW5lZCBmb3IgdGhpcyBpbnRlcmZhY2UpOgorICogPHVsPgorICogPGxpPjxlbT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2VtPiAtIGZvciBhbG1vc3QgYWxsIG1ldGhvZHMgdG8gc2lnbmFsIHRoYXQKKyAqICAgICBhcmd1bWVudCBpcyBpbGxlZ2FsCisgKiA8bGk+PGVtPklsbGVnYWxTdGF0ZUV4Y2VwdGlvbjwvZW0+IC0gdG8gc2lnbmFsIHRoYXQgY2FsbCBoYXMgZ29vZCBhcmd1bWVudHMgYnV0CisgKiAgICAgaXMgbm90IGV4cGVjdGVkIGhlcmUgKHZpb2xhdGlvbiBvZiBjb250cmFjdCkgYW5kIGZvciBmZWF0dXJlcy9wcm9wZXJ0aWVzCisgKiAgICB3aGVuIHJlcXVlc3Rpbmcgc2V0dGluZyB1bmltcGxlbWVudGVkIGZlYXR1cmUvcHJvcGVydHkKKyAqICAgIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiB3b3VsZCBiZSBiZXR0ZXIgYnV0IGl0IGlzIG5vdCBpbiBNSURQKQorICogIDwvdWw+CisgKgorICogPHA+PGI+Tk9URTo8L2I+IHdyaXRpbmcgIENEU0VDVCwgRU5USVRZX1JFRiwgSUdOT1JBQkxFX1dISVRFU1BBQ0UsCisgKiAgUFJPQ0VTU0lOR19JTlNUUlVDVElPTiwgQ09NTUVOVCwgYW5kIERPQ0RFQ0wgaW4gc29tZSBpbXBsZW1lbnRhdGlvbnMKKyAqIG1heSBub3QgYmUgc3VwcG9ydGVkIChmb3IgZXhhbXBsZSB3aGVuIHNlcmlhbGl6aW5nIHRvIFdCWE1MKS4KKyAqIEluIHN1Y2ggY2FzZSBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gd2lsbCBiZSB0aHJvd24gYW5kIGl0IGlzIHJlY29tbWVuZGVkCisgKiB0byB1c2UgYW4gb3B0aW9uYWwgZmVhdHVyZSB0byBzaWduYWwgdGhhdCBpbXBsZW1lbnRhdGlvbiBpcyBub3QKKyAqIHN1cHBvcnRpbmcgdGhpcyBraW5kIG9mIG91dHB1dC4KKyAqLworCitwdWJsaWMgaW50ZXJmYWNlIFhtbFNlcmlhbGl6ZXIgeworCisgICAgLyoqCisgICAgICogU2V0IGZlYXR1cmUgaWRlbnRpZmllZCBieSBuYW1lIChyZWNvbW1lbmRlZCB0byBiZSBVUkkgZm9yIHVuaXF1ZW5lc3MpLgorICAgICAqIFNvbWUgd2VsbCBrbm93biBvcHRpb25hbCBmZWF0dXJlcyBhcmUgZGVmaW5lZCBpbgorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cueG1scHVsbC5vcmcvdjEvZG9jL2ZlYXR1cmVzLmh0bWwiPgorICAgICAqIGh0dHA6Ly93d3cueG1scHVsbC5vcmcvdjEvZG9jL2ZlYXR1cmVzLmh0bWw8L2E+LgorICAgICAqCisgICAgICogSWYgZmVhdHVyZSBpcyBub3QgcmVjb2duaXplZCBvciBjYW4gbm90IGJlIHNldAorICAgICAqIHRoZW4gSWxsZWdhbFN0YXRlRXhjZXB0aW9uIE1VU1QgYmUgdGhyb3duLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gSWYgdGhlIGZlYXR1cmUgaXMgbm90IHN1cHBvcnRlZCBvciBjYW4gbm90IGJlIHNldAorICAgICAqLworICAgIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gc3RhdGUpCisgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbjsKKworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBmZWF0dXJlIHdpdGggZ2l2ZW4gbmFtZS4KKyAgICAgKiA8cD48c3Ryb25nPk5PVEU6PC9zdHJvbmc+IHVua25vd24gcHJvcGVydGllcyBhcmUgPHN0cm9uZz5hbHdheXM8L3N0cm9uZz4gcmV0dXJuZWQgYXMgbnVsbAorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgZmVhdHVyZSB0byBiZSByZXRyaWV2ZWQuCisgICAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgbmFtZWQgZmVhdHVyZS4KKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBmZWF0dXJlIHN0cmluZyBpcyBudWxsCisgICAgICovCisgICAgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKTsKKworCisgICAgLyoqCisgICAgICogU2V0IHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LgorICAgICAqICh0aGUgcHJvcGVydHkgbmFtZSBpcyByZWNvbW1lbmRlZCB0byBiZSBVUkkgZm9yIHVuaXF1ZW5lc3MpLgorICAgICAqIFNvbWUgd2VsbCBrbm93biBvcHRpb25hbCBwcm9wZXJ0aWVzIGFyZSBkZWZpbmVkIGluCisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy54bWxwdWxsLm9yZy92MS9kb2MvcHJvcGVydGllcy5odG1sIj4KKyAgICAgKiBodHRwOi8vd3d3LnhtbHB1bGwub3JnL3YxL2RvYy9wcm9wZXJ0aWVzLmh0bWw8L2E+LgorICAgICAqCisgICAgICogSWYgcHJvcGVydHkgaXMgbm90IHJlY29nbml6ZWQgb3IgY2FuIG5vdCBiZSBzZXQKKyAgICAgKiB0aGVuIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBNVVNUIGJlIHRocm93bi4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZSBwcm9wZXJ0eSBpcyBub3Qgc3VwcG9ydGVkIG9yIGNhbiBub3QgYmUgc2V0CisgICAgICovCisgICAgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgdmFsdWUpCisgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIExvb2sgdXAgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkuCisgICAgICoKKyAgICAgKiBUaGUgcHJvcGVydHkgbmFtZSBpcyBhbnkgZnVsbHktcXVhbGlmaWVkIFVSSS4gSQorICAgICAqIDxwPjxzdHJvbmc+Tk9URTo8L3N0cm9uZz4gdW5rbm93biBwcm9wZXJ0aWVzIGFyZSA8c3RyaW5nPmFsd2F5czwvc3Ryb25nPiByZXR1cm5lZCBhcyBudWxsCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiBwcm9wZXJ0eSB0byBiZSByZXRyaWV2ZWQuCisgICAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgbmFtZWQgcHJvcGVydHkuCisgICAgICovCisgICAgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBuYW1lKTsKKworICAgIC8qKgorICAgICAqIFNldCB0byB1c2UgYmluYXJ5IG91dHB1dCBzdHJlYW0gd2l0aCBnaXZlbiBlbmNvZGluZy4KKyAgICAgKi8KKyAgICB2b2lkIHNldE91dHB1dCAoT3V0cHV0U3RyZWFtIG9zLCBTdHJpbmcgZW5jb2RpbmcpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbGxlZ2FsU3RhdGVFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIG91dHB1dCB0byB0aGUgZ2l2ZW4gd3JpdGVyLgorICAgICAqIDxwPjxiPldBUk5JTkc8L2I+IG5vIGluZm9ybWF0aW9uIGFib3V0IGVuY29kaW5nIGlzIGF2YWlsYWJsZSEKKyAgICAgKi8KKyAgICB2b2lkIHNldE91dHB1dCAoV3JpdGVyIHdyaXRlcikKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlICZsdDsmIzYzO3htbCBkZWNsYXJhdGlvbiB3aXRoIGVuY29kaW5nIChpZiBlbmNvZGluZyBub3QgbnVsbCkKKyAgICAgKiBhbmQgc3RhbmRhbG9uZSBmbGFnIChpZiBzdGFuZGFsb25lIG5vdCBudWxsKQorICAgICAqIFRoaXMgbWV0aG9kIGNhbiBvbmx5IGJlIGNhbGxlZCBqdXN0IGFmdGVyIHNldE91dHB1dC4KKyAgICAgKi8KKyAgICB2b2lkIHN0YXJ0RG9jdW1lbnQgKFN0cmluZyBlbmNvZGluZywgQm9vbGVhbiBzdGFuZGFsb25lKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSWxsZWdhbFN0YXRlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRmluaXNoIHdyaXRpbmcuIEFsbCB1bmNsb3NlZCBzdGFydCB0YWdzIHdpbGwgYmUgY2xvc2VkIGFuZCBvdXRwdXQKKyAgICAgKiB3aWxsIGJlIGZsdXNoZWQuIEFmdGVyIGNhbGxpbmcgdGhpcyBtZXRob2Qgbm8gbW9yZSBvdXRwdXQgY2FuIGJlCisgICAgICogc2VyaWFsaXplZCB1bnRpbCBuZXh0IGNhbGwgdG8gc2V0T3V0cHV0KCkKKyAgICAgKi8KKyAgICB2b2lkIGVuZERvY3VtZW50ICgpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbGxlZ2FsU3RhdGVFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBCaW5kcyB0aGUgZ2l2ZW4gcHJlZml4IHRvIHRoZSBnaXZlbiBuYW1lc3BhY2UuCisgICAgICogVGhpcyBjYWxsIGlzIHZhbGlkIGZvciB0aGUgbmV4dCBlbGVtZW50IGluY2x1ZGluZyBjaGlsZCBlbGVtZW50cy4KKyAgICAgKiBUaGUgcHJlZml4IGFuZCBuYW1lc3BhY2UgTVVTVCBiZSBhbHdheXMgZGVjbGFyZWQgZXZlbiBpZiBwcmVmaXgKKyAgICAgKiBpcyBub3QgdXNlZCBpbiBlbGVtZW50IChzdGFydFRhZygpIG9yIGF0dHJpYnV0ZSgpKSAtIGZvciBYTUwgMS4wCisgICAgICogaXQgbXVzdCByZXN1bHQgaW4gZGVjbGFyaW5nIDxjb2RlPnhtbG5zOnByZWZpeD0nbmFtZXNwYWNlJzwvY29kZT4KKyAgICAgKiAob3IgPGNvZGU+eG1sbnM6cHJlZml4PSJuYW1lc3BhY2UiPC9jb2RlPiBkZXBlbmRpbmcgd2hhdCBjaGFyYWN0ZXIgaXMgdXNlZAorICAgICAqIHRvIHF1b3RlIGF0dHJpYnV0ZSB2YWx1ZSkuCisgICAgICoKKyAgICAgKiA8cD48Yj5OT1RFOjwvYj4gdGhpcyBtZXRob2QgTVVTVCBiZSBjYWxsZWQgZGlyZWN0bHkgYmVmb3JlIHN0YXJ0VGFnKCkKKyAgICAgKiAgIGFuZCBpZiBhbnl0aGluZyBidXQgc3RhcnRUYWcoKSBvciBzZXRQcmVmaXgoKSBpcyBjYWxsZWQgbmV4dCB0aGVyZSB3aWxsIGJlIGV4Y2VwdGlvbi4KKyAgICAgKiA8cD48Yj5OT1RFOjwvYj4gcHJlZml4ZXMgInhtbCIgYW5kICJ4bWxucyIgYXJlIGFscmVhZHkgYm91bmQKKyAgICAgKiAgIGFuZCBjYW4gbm90IGJlIHJlZGVmaW5lZCBzZWU6CisgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvWE1ML3htbC1uYW1lcy0xOTk5MDExNC1lcnJhdGEjTkUwNSI+TmFtZXNwYWNlcyBpbiBYTUwgRXJyYXRhPC9hPi4KKyAgICAgKiA8cD48Yj5OT1RFOjwvYj4gdG8gc2V0IGRlZmF1bHQgbmFtZXNwYWNlIHVzZSBhcyBwcmVmaXggZW1wdHkgc3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHByZWZpeCBtdXN0IGJlIG5vdCBudWxsIChvciBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duKQorICAgICAqIEBwYXJhbSBuYW1lc3BhY2UgbXVzdCBiZSBub3QgbnVsbAorICAgICAqLworICAgIHZvaWQgc2V0UHJlZml4IChTdHJpbmcgcHJlZml4LCBTdHJpbmcgbmFtZXNwYWNlKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSWxsZWdhbFN0YXRlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJuIG5hbWVzcGFjZSB0aGF0IGNvcnJlc3BvbmRzIHRvIGdpdmVuIHByZWZpeAorICAgICAqIElmIHRoZXJlIGlzIG5vIHByZWZpeCBib3VuZCB0byB0aGlzIG5hbWVzcGFjZSByZXR1cm4gbnVsbAorICAgICAqIGJ1dCBpZiBnZW5lcmF0ZVByZWZpeCBpcyBmYWxzZSB0aGVuIHJldHVybiBnZW5lcmF0ZWQgcHJlZml4LgorICAgICAqCisgICAgICogPHA+PGI+Tk9URTo8L2I+IGlmIHRoZSBwcmVmaXggaXMgZW1wdHkgc3RyaW5nICIiIGFuZCBkZWZhdWx0IG5hbWVzcGFjZSBpcyBib3VuZAorICAgICAqIHRvIHRoaXMgcHJlZml4IHRoZW4gZW1wdHkgc3RyaW5nICgiIikgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiA8cD48Yj5OT1RFOjwvYj4gcHJlZml4ZXMgInhtbCIgYW5kICJ4bWxucyIgYXJlIGFscmVhZHkgYm91bmQKKyAgICAgKiAgIHdpbGwgaGF2ZSB2YWx1ZXMgYXMgZGVmaW5lZAorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvIj5OYW1lc3BhY2VzIGluIFhNTCBzcGVjaWZpY2F0aW9uPC9hPgorICAgICAqLworICAgIFN0cmluZyBnZXRQcmVmaXggKFN0cmluZyBuYW1lc3BhY2UsIGJvb2xlYW4gZ2VuZXJhdGVQcmVmaXgpCisgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGRlcHRoIG9mIHRoZSBlbGVtZW50LgorICAgICAqIE91dHNpZGUgdGhlIHJvb3QgZWxlbWVudCwgdGhlIGRlcHRoIGlzIDAuIFRoZQorICAgICAqIGRlcHRoIGlzIGluY3JlbWVudGVkIGJ5IDEgd2hlbiBzdGFydFRhZygpIGlzIGNhbGxlZC4KKyAgICAgKiBUaGUgZGVwdGggaXMgZGVjcmVtZW50ZWQgYWZ0ZXIgdGhlIGNhbGwgdG8gZW5kVGFnKCkKKyAgICAgKiBldmVudCB3YXMgb2JzZXJ2ZWQuCisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqICZsdDshLS0gb3V0c2lkZSAtLSZndDsgICAgIDAKKyAgICAgKiAmbHQ7cm9vdCZndDsgICAgICAgICAgICAgICAxCisgICAgICogICBzb21ldGV4dCAgICAgICAgICAgICAgICAgMQorICAgICAqICAgICAmbHQ7Zm9vYmFyJmd0OyAgICAgICAgIDIKKyAgICAgKiAgICAgJmx0Oy9mb29iYXImZ3Q7ICAgICAgICAyCisgICAgICogJmx0Oy9yb290Jmd0OyAgICAgICAgICAgICAgMQorICAgICAqICZsdDshLS0gb3V0c2lkZSAtLSZndDsgICAgIDAKKyAgICAgKiA8L3ByZT4KKyAgICAgKi8KKyAgICBpbnQgZ2V0RGVwdGgoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGN1cnJlbnQgZWxlbWVudCBhcyBzZXQgYnkgc3RhcnRUYWcoKS4KKyAgICAgKgorICAgICAqIDxwPjxiPk5PVEU6PC9iPiB0aGF0IG1lYW5zIGluIHBhcnRpY3VsYXIgdGhhdDogPHVsPgorICAgICAqIDxsaT5pZiB0aGVyZSB3YXMgc3RhcnRUYWcoIiIsIC4uLikgdGhlbiBnZXROYW1lc3BhY2UoKSByZXR1cm5zICIiCisgICAgICogPGxpPmlmIHRoZXJlIHdhcyBzdGFydFRhZyhudWxsLCAuLi4pIHRoZW4gZ2V0TmFtZXNwYWNlKCkgcmV0dXJucyBudWxsCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gbmFtZXNwYWNlIHNldCBieSBzdGFydFRhZygpIHRoYXQgaXMgY3VycmVudGx5IGluIHNjb3BlCisgICAgICovCisgICAgU3RyaW5nIGdldE5hbWVzcGFjZSAoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGN1cnJlbnQgZWxlbWVudCBhcyBzZXQgYnkgc3RhcnRUYWcoKS4KKyAgICAgKiBJdCBjYW4gb25seSBiZSBudWxsIGJlZm9yZSBmaXJzdCBjYWxsIHRvIHN0YXJ0VGFnKCkKKyAgICAgKiBvciB3aGVuIGxhc3QgZW5kVGFnKCkgaXMgY2FsbGVkIHRvIGNsb3NlIGZpcnN0IHN0YXJ0VGFnKCkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIG5hbWVzcGFjZSBzZXQgYnkgc3RhcnRUYWcoKSB0aGF0IGlzIGN1cnJlbnRseSBpbiBzY29wZQorICAgICAqLworICAgIFN0cmluZyBnZXROYW1lKCk7CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgYSBzdGFydCB0YWcgd2l0aCB0aGUgZ2l2ZW4gbmFtZXNwYWNlIGFuZCBuYW1lLgorICAgICAqIElmIHRoZXJlIGlzIG5vIHByZWZpeCBkZWZpbmVkIGZvciB0aGUgZ2l2ZW4gbmFtZXNwYWNlLAorICAgICAqIGEgcHJlZml4IHdpbGwgYmUgZGVmaW5lZCBhdXRvbWF0aWNhbGx5LgorICAgICAqIFRoZSBleHBsaWNpdCBwcmVmaXhlcyBmb3IgbmFtZXNwYWNlcyBjYW4gYmUgZXN0YWJsaXNoZWQgYnkgY2FsbGluZyBzZXRQcmVmaXgoKQorICAgICAqIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGlzIG1ldGhvZC4KKyAgICAgKiBJZiBuYW1lc3BhY2UgaXMgbnVsbCBubyBuYW1lc3BhY2UgcHJlZml4IGlzIHByaW50ZWQgYnV0IGp1c3QgbmFtZS4KKyAgICAgKiBJZiBuYW1lc3BhY2UgaXMgZW1wdHkgc3RyaW5nIHRoZW4gc2VyaWFsaXplciB3aWxsIG1ha2Ugc3VyZSB0aGF0CisgICAgICogZGVmYXVsdCBlbXB0eSBuYW1lc3BhY2UgaXMgZGVjbGFyZWQgKGluIFhNTCAxLjAgeG1sbnM9JycpCisgICAgICogb3IgdGhyb3cgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIGRlZmF1bHQgbmFtZXNwYWNlIGlzIGFscmVhZHkgYm91bmQKKyAgICAgKiB0byBub24tZW1wdHkgc3RyaW5nLgorICAgICAqLworICAgIFhtbFNlcmlhbGl6ZXIgc3RhcnRUYWcgKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSWxsZWdhbFN0YXRlRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogV3JpdGUgYW4gYXR0cmlidXRlLiBDYWxscyB0byBhdHRyaWJ1dGUoKSBNVVNUIGZvbGxvdyBhIGNhbGwgdG8KKyAgICAgKiBzdGFydFRhZygpIGltbWVkaWF0ZWx5LiBJZiB0aGVyZSBpcyBubyBwcmVmaXggZGVmaW5lZCBmb3IgdGhlCisgICAgICogZ2l2ZW4gbmFtZXNwYWNlLCBhIHByZWZpeCB3aWxsIGJlIGRlZmluZWQgYXV0b21hdGljYWxseS4KKyAgICAgKiBJZiBuYW1lc3BhY2UgaXMgbnVsbCBvciBlbXB0eSBzdHJpbmcKKyAgICAgKiBubyBuYW1lc3BhY2UgcHJlZml4IGlzIHByaW50ZWQgYnV0IGp1c3QgbmFtZS4KKyAgICAgKi8KKyAgICBYbWxTZXJpYWxpemVyIGF0dHJpYnV0ZSAoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlIGVuZCB0YWcuIFJlcGV0aXRpb24gb2YgbmFtZXNwYWNlIGFuZCBuYW1lIGlzIGp1c3QgZm9yIGF2b2lkaW5nIGVycm9ycy4KKyAgICAgKiA8cD48Yj5CYWNrZ3JvdW5kOjwvYj4gaW4ga1hNTCBlbmRUYWcgaGFkIG5vIGFyZ3VtZW50cywgYW5kIG5vbiBtYXRjaGluZyB0YWdzIHdlcmUKKyAgICAgKiAgdmVyeSBkaWZmaWN1bHQgdG8gZmluZC4uLgorICAgICAqIElmIG5hbWVzcGFjZSBpcyBudWxsIG5vIG5hbWVzcGFjZSBwcmVmaXggaXMgcHJpbnRlZCBidXQganVzdCBuYW1lLgorICAgICAqIElmIG5hbWVzcGFjZSBpcyBlbXB0eSBzdHJpbmcgdGhlbiBzZXJpYWxpemVyIHdpbGwgbWFrZSBzdXJlIHRoYXQKKyAgICAgKiBkZWZhdWx0IGVtcHR5IG5hbWVzcGFjZSBpcyBkZWNsYXJlZCAoaW4gWE1MIDEuMCB4bWxucz0nJykuCisgICAgICovCisgICAgWG1sU2VyaWFsaXplciBlbmRUYWcgKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSWxsZWdhbFN0YXRlRXhjZXB0aW9uOworCisKKyAgICAvLyAgICAvKioKKyAgICAvLyAgICAgKiBXcml0ZXMgYSBzdGFydCB0YWcgd2l0aCB0aGUgZ2l2ZW4gbmFtZXNwYWNlIGFuZCBuYW1lLgorICAgIC8vICAgICAqIDxiciAvPklmIHRoZXJlIGlzIG5vIHByZWZpeCBkZWZpbmVkIChwcmVmaXggPT0gbnVsbCkgZm9yIHRoZSBnaXZlbiBuYW1lc3BhY2UsCisgICAgLy8gICAgICogYSBwcmVmaXggd2lsbCBiZSBkZWZpbmVkIGF1dG9tYXRpY2FsbHkuCisgICAgLy8gICAgICogPGJyIC8+SWYgZXhwbGljaXQgcHJlZml4ZXMgaXMgcGFzc2VkIChwcmVmaXggIT0gbnVsbCkgdGhlbiBpdCB3aWxsIGJlIHVzZWQKKyAgICAvLyAgICAgICphbmQgbmFtZXNwYWNlIGRlY2xhcmVkIGlmIG5vdCBhbHJlYWR5IGRlY2xhcmVkIG9yCisgICAgLy8gICAgICogdGhyb3cgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHRoZSBzYW1lIHByZWZpeCB3YXMgYWxyZWFkeSBzZXQgb24gdGhpcworICAgIC8vICAgICAqIGVsZW1lbnQgKHNldFByZWZpeCgpKSBhbmQgd2FzIGJvdW5kIHRvIGRpZmZlcmVudCBuYW1lc3BhY2UuCisgICAgLy8gICAgICogPGJyIC8+SWYgbmFtZXNwYWNlIGlzIG51bGwgdGhlbiBwcmVmaXggbXVzdCBiZSBudWxsIHRvbyBvciBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaXMgdGhyb3duLgorICAgIC8vICAgICAqIDxiciAvPklmIG5hbWVzcGFjZSBpcyBudWxsIHRoZW4gbm8gbmFtZXNwYWNlIHByZWZpeCBpcyBwcmludGVkIGJ1dCBqdXN0IG5hbWUuCisgICAgLy8gICAgICogPGJyIC8+SWYgbmFtZXNwYWNlIGlzIGVtcHR5IHN0cmluZyB0aGVuIHNlcmlhbGl6ZXIgd2lsbCBtYWtlIHN1cmUgdGhhdAorICAgIC8vICAgICAqIGRlZmF1bHQgZW1wdHkgbmFtZXNwYWNlIGlzIGRlY2xhcmVkIChpbiBYTUwgMS4wIHhtbG5zPScnKQorICAgIC8vICAgICAqIG9yIHRocm93IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiBkZWZhdWx0IG5hbWVzcGFjZSBpcyBhbHJlYWR5IGJvdW5kCisgICAgLy8gICAgICogdG8gbm9uLWVtcHR5IHN0cmluZy4KKyAgICAvLyAgICAgKi8KKyAgICAvLyAgICBYbWxTZXJpYWxpemVyIHN0YXJ0VGFnIChTdHJpbmcgcHJlZml4LCBTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgbmFtZSkKKyAgICAvLyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbjsKKyAgICAvLworICAgIC8vICAgIC8qKgorICAgIC8vICAgICAqIFdyaXRlIGFuIGF0dHJpYnV0ZS4gQ2FsbHMgdG8gYXR0cmlidXRlKCkgTVVTVCBmb2xsb3cgYSBjYWxsIHRvCisgICAgLy8gICAgICogc3RhcnRUYWcoKSBpbW1lZGlhdGVseS4KKyAgICAvLyAgICAgKiA8YnIgLz5JZiB0aGVyZSBpcyBubyBwcmVmaXggZGVmaW5lZCAocHJlZml4ID09IG51bGwpIGZvciB0aGUgZ2l2ZW4gbmFtZXNwYWNlLAorICAgIC8vICAgICAqIGEgcHJlZml4IHdpbGwgYmUgZGVmaW5lZCBhdXRvbWF0aWNhbGx5LgorICAgIC8vICAgICAqIDxiciAvPklmIGV4cGxpY2l0IHByZWZpeGVzIGlzIHBhc3NlZCAocHJlZml4ICE9IG51bGwpIHRoZW4gaXQgd2lsbCBiZSB1c2VkCisgICAgLy8gICAgICogYW5kIG5hbWVzcGFjZSBkZWNsYXJlZCBpZiBub3QgYWxyZWFkeSBkZWNsYXJlZCBvcgorICAgIC8vICAgICAqIHRocm93IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB0aGUgc2FtZSBwcmVmaXggd2FzIGFscmVhZHkgc2V0IG9uIHRoaXMKKyAgICAvLyAgICAgKiBlbGVtZW50IChzZXRQcmVmaXgoKSkgYW5kIHdhcyBib3VuZCB0byBkaWZmZXJlbnQgbmFtZXNwYWNlLgorICAgIC8vICAgICAqIDxiciAvPklmIG5hbWVzcGFjZSBpcyBudWxsIHRoZW4gcHJlZml4IG11c3QgYmUgbnVsbCB0b28gb3IgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAvLyAgICAgKiA8YnIgLz5JZiBuYW1lc3BhY2UgaXMgbnVsbCB0aGVuIG5vIG5hbWVzcGFjZSBwcmVmaXggaXMgcHJpbnRlZCBidXQganVzdCBuYW1lLgorICAgIC8vICAgICAqIDxiciAvPklmIG5hbWVzcGFjZSBpcyBlbXB0eSBzdHJpbmcgdGhlbiBzZXJpYWxpemVyIHdpbGwgbWFrZSBzdXJlIHRoYXQKKyAgICAvLyAgICAgKiBkZWZhdWx0IGVtcHR5IG5hbWVzcGFjZSBpcyBkZWNsYXJlZCAoaW4gWE1MIDEuMCB4bWxucz0nJykKKyAgICAvLyAgICAgKiBvciB0aHJvdyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgZGVmYXVsdCBuYW1lc3BhY2UgaXMgYWxyZWFkeSBib3VuZAorICAgIC8vICAgICAqIHRvIG5vbi1lbXB0eSBzdHJpbmcuCisgICAgLy8gICAgICovCisgICAgLy8gICAgWG1sU2VyaWFsaXplciBhdHRyaWJ1dGUgKFN0cmluZyBwcmVmaXgsIFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCisgICAgLy8gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbGxlZ2FsU3RhdGVFeGNlcHRpb247CisgICAgLy8KKyAgICAvLyAgICAvKioKKyAgICAvLyAgICAgKiBXcml0ZSBlbmQgdGFnLiBSZXBldGl0aW9uIG9mIG5hbWVzcGFjZSwgcHJlZml4LCBhbmQgbmFtZSBpcyBqdXN0IGZvciBhdm9pZGluZyBlcnJvcnMuCisgICAgLy8gICAgICogPGJyIC8+SWYgbmFtZXNwYWNlIG9yIG5hbWUgYXJndW1lbnRzIGFyZSBkaWZmZXJlbnQgZnJvbSBjb3JyZXNwb25kaW5nIHN0YXJ0VGFnIGNhbGwKKyAgICAvLyAgICAgKiB0aGVuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyB0aHJvd24sIGlmIHByZWZpeCBhcmd1bWVudCBpcyBub3QgbnVsbCBhbmQgaXMgZGlmZmVyZW50CisgICAgLy8gICAgICogZnJvbSBjb3JyZXNwb25kaW5nIHN0YXJUYWcgdGhlbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhyb3duLgorICAgIC8vICAgICAqIDxiciAvPklmIG5hbWVzcGFjZSBpcyBudWxsIHRoZW4gcHJlZml4IG11c3QgYmUgbnVsbCB0b28gb3IgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAvLyAgICAgKiA8YnIgLz5JZiBuYW1lc3BhY2UgaXMgbnVsbCB0aGVuIG5vIG5hbWVzcGFjZSBwcmVmaXggaXMgcHJpbnRlZCBidXQganVzdCBuYW1lLgorICAgIC8vICAgICAqIDxiciAvPklmIG5hbWVzcGFjZSBpcyBlbXB0eSBzdHJpbmcgdGhlbiBzZXJpYWxpemVyIHdpbGwgbWFrZSBzdXJlIHRoYXQKKyAgICAvLyAgICAgKiBkZWZhdWx0IGVtcHR5IG5hbWVzcGFjZSBpcyBkZWNsYXJlZCAoaW4gWE1MIDEuMCB4bWxucz0nJykuCisgICAgLy8gICAgICogPHA+PGI+QmFja2dyb3VuZDo8L2I+IGluIGtYTUwgZW5kVGFnIGhhZCBubyBhcmd1bWVudHMsIGFuZCBub24gbWF0Y2hpbmcgdGFncyB3ZXJlCisgICAgLy8gICAgICogIHZlcnkgZGlmZmljdWx0IHRvIGZpbmQuLi48L3A+CisgICAgLy8gICAgICovCisgICAgLy8gQUxFSzogVGhpcyBpcyByZWFsbHkgb3B0aW9uYWwgYXMgcHJlZml4IGluIGVuZCB0YWcgTVVTVCBjb3JyZXNwb25kIHRvIHN0YXJ0IHRhZyBidXQgZ29vZCBmb3IgZXJyb3IgY2hlY2tpbmcKKyAgICAvLyAgICBYbWxTZXJpYWxpemVyIGVuZFRhZyAoU3RyaW5nIHByZWZpeCwgU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIG5hbWUpCisgICAgLy8gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbGxlZ2FsU3RhdGVFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGV4dCwgd2hlcmUgc3BlY2lhbCBYTUwgY2hhcnMgYXJlIGVzY2FwZWQgYXV0b21hdGljYWxseQorICAgICAqLworICAgIFhtbFNlcmlhbGl6ZXIgdGV4dCAoU3RyaW5nIHRleHQpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbGxlZ2FsU3RhdGVFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGV4dCwgd2hlcmUgc3BlY2lhbCBYTUwgY2hhcnMgYXJlIGVzY2FwZWQgYXV0b21hdGljYWxseQorICAgICAqLworICAgIFhtbFNlcmlhbGl6ZXIgdGV4dCAoY2hhciBbXSBidWYsIGludCBzdGFydCwgaW50IGxlbikKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbjsKKworICAgIHZvaWQgY2RzZWN0IChTdHJpbmcgdGV4dCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbjsKKyAgICB2b2lkIGVudGl0eVJlZiAoU3RyaW5nIHRleHQpICB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSWxsZWdhbFN0YXRlRXhjZXB0aW9uOworICAgIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uIChTdHJpbmcgdGV4dCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbjsKKyAgICB2b2lkIGNvbW1lbnQgKFN0cmluZyB0ZXh0KQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSWxsZWdhbFN0YXRlRXhjZXB0aW9uOworICAgIHZvaWQgZG9jZGVjbCAoU3RyaW5nIHRleHQpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbGxlZ2FsU3RhdGVFeGNlcHRpb247CisgICAgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlIChTdHJpbmcgdGV4dCkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFdyaXRlIGFsbCBwZW5kaW5nIG91dHB1dCB0byB0aGUgc3RyZWFtLgorICAgICAqIElmIG1ldGhvZCBzdGFydFRhZygpIG9yIGF0dHJpYnV0ZSgpIHdhcyBjYWxsZWQgdGhlbiBzdGFydCB0YWcgaXMgY2xvc2VkIChmaW5hbCAmZ3Q7KQorICAgICAqIGJlZm9yZSBmbHVzaCgpIGlzIGNhbGxlZCBvbiB1bmRlcmx5aW5nIG91dHB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiA8cD48Yj5OT1RFOjwvYj4gaWYgdGhlcmUgaXMgbmVlZCB0byBjbG9zZSBzdGFydCB0YWcKKyAgICAgKiAoc28gbm8gbW9yZSBhdHRyaWJ1dGUoKSBjYWxscyBhcmUgYWxsb3dlZCkgYnV0IHdpdGhvdXQgZmx1c2hpbmcgb3V0cHV0CisgICAgICogY2FsbCBtZXRob2QgdGV4dCgpIHdpdGggZW1wdHkgc3RyaW5nICh0ZXh0KCIiKSkuCisgICAgICoKKyAgICAgKi8KKyAgICB2b2lkIGZsdXNoICgpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKworfQpkaWZmIC0tZ2l0IGEveG1sL3NyYy9tYWluL2phdmEvb3JnL3htbHB1bGwvdjEvc2F4Mi9Ecml2ZXIuamF2YSBiL3htbC9zcmMvbWFpbi9qYXZhL29yZy94bWxwdWxsL3YxL3NheDIvRHJpdmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODhjZmZkNwotLS0gL2Rldi9udWxsCisrKyBiL3htbC9zcmMvbWFpbi9qYXZhL29yZy94bWxwdWxsL3YxL3NheDIvRHJpdmVyLmphdmEKQEAgLTAsMCArMSw0NjkgQEAKKy8qIC0qLSAgICAgICAgICAgICBjLWJhc2ljLW9mZnNldDogNDsgaW5kZW50LXRhYnMtbW9kZTogbmlsOyAtKi0gIC8vLS0tLS0tMTAwLWNvbHVtbnMtd2lkZS0tLS0tLT58Ki8KKy8vIGZvciBsaWNlbnNlIHBsZWFzZSBzZWUgYWNjb21wYW55aW5nIExJQ0VOU0UudHh0IGZpbGUgKGF2YWlsYWJsZSBhbHNvIGF0IGh0dHA6Ly93d3cueG1scHVsbC5vcmcvKQorCitwYWNrYWdlIG9yZy54bWxwdWxsLnYxLnNheDI7CisKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CisKKy8vIG5vdCBKMk1FIGNsYXNzZXMgLS0gcmVtb3ZlIGlmIHlvdSB3YW50IHRvIHJ1biBpbiBNSURQIGRldmljZXMKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CitpbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOworCisKKy8vIG5vdCBKMk1FIGNsYXNzZXMKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7CitpbXBvcnQgb3JnLnhtbC5zYXguRFRESGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKK2ltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7CitpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CitpbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOworaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuRGVmYXVsdEhhbmRsZXI7CisKK2ltcG9ydCBvcmcueG1scHVsbC52MS5YbWxQdWxsUGFyc2VyOworaW1wb3J0IG9yZy54bWxwdWxsLnYxLlhtbFB1bGxQYXJzZXJFeGNlcHRpb247CitpbXBvcnQgb3JnLnhtbHB1bGwudjEuWG1sUHVsbFBhcnNlckZhY3Rvcnk7CisKKy8qKgorICogU0FYMiBEcml2ZXIgdGhhdCBwdWxscyBldmVudHMgZnJvbSBYbWxQdWxsUGFyc2VyCisgKiBhbmQgY29tdmVydHMgdGhlbSBpbnRvIFNBWDIgY2FsbGJhY2tzLgorICoKKyAqIEBhdXRob3IgPGEgaHJlZj0iaHR0cDovL3d3dy5leHRyZW1lLmluZGlhbmEuZWR1L35hc2xvbS8iPkFsZWtzYW5kZXIgU2xvbWluc2tpPC9hPgorICovCisKK3B1YmxpYyBjbGFzcyBEcml2ZXIgaW1wbGVtZW50cyBMb2NhdG9yLCBYTUxSZWFkZXIsIEF0dHJpYnV0ZXMKK3sKKworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERFQ0xBUkFUSU9OX0hBTkRMRVJfUFJPUEVSVFkgPQorICAgICAgICAiaHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvZGVjbGFyYXRpb24taGFuZGxlciI7CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBMRVhJQ0FMX0hBTkRMRVJfUFJPUEVSVFkgPQorICAgICAgICAiaHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvbGV4aWNhbC1oYW5kbGVyIjsKKworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRVNfRkVBVFVSRSA9CisgICAgICAgICJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlcyI7CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VfUFJFRklYRVNfRkVBVFVSRSA9CisgICAgICAgICJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzIjsKKworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT05fRkVBVFVSRSA9CisgICAgICAgICJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvdmFsaWRhdGlvbiI7CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBBUEFDSEVfU0NIRU1BX1ZBTElEQVRJT05fRkVBVFVSRSA9CisgICAgICAgICJodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9zY2hlbWEiOworCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVBBQ0hFX0RZTkFNSUNfVkFMSURBVElPTl9GRUFUVVJFID0KKyAgICAgICAgImh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL2R5bmFtaWMiOworCisgICAgcHJvdGVjdGVkIENvbnRlbnRIYW5kbGVyIGNvbnRlbnRIYW5kbGVyID0gbmV3IERlZmF1bHRIYW5kbGVyKCk7CisgICAgcHJvdGVjdGVkIEVycm9ySGFuZGxlciBlcnJvckhhbmRsZXIgPSBuZXcgRGVmYXVsdEhhbmRsZXIoKTs7CisKKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHN5c3RlbUlkOworCisgICAgcHJvdGVjdGVkIFhtbFB1bGxQYXJzZXIgcHA7CisKKyAgICAvL3ByaXZhdGUgZmluYWwgc3RhdGljIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqLworICAgIHB1YmxpYyBEcml2ZXIoKSB0aHJvd3MgWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFhtbFB1bGxQYXJzZXJGYWN0b3J5IGZhY3RvcnkgPSBYbWxQdWxsUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOworICAgICAgICBmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOworICAgICAgICBwcCA9IGZhY3RvcnkubmV3UHVsbFBhcnNlcigpOworICAgIH0KKworICAgIHB1YmxpYyBEcml2ZXIoWG1sUHVsbFBhcnNlciBwcCkgdGhyb3dzIFhtbFB1bGxQYXJzZXJFeGNlcHRpb24geworICAgICAgICB0aGlzLnBwID0gcHA7CisgICAgfQorCisgICAgLy8gLS0gQXR0cmlidXRlcyBpbnRlcmZhY2UKKworICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgeyByZXR1cm4gcHAuZ2V0QXR0cmlidXRlQ291bnQoKTsgfQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0VVJJKGludCBpbmRleCkgeyByZXR1cm4gcHAuZ2V0QXR0cmlidXRlTmFtZXNwYWNlKGluZGV4KTsgfQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKGludCBpbmRleCkgeyByZXR1cm4gcHAuZ2V0QXR0cmlidXRlTmFtZShpbmRleCk7IH0KKyAgICBwdWJsaWMgU3RyaW5nIGdldFFOYW1lKGludCBpbmRleCkgeworICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4ID0gcHAuZ2V0QXR0cmlidXRlUHJlZml4KGluZGV4KTsKKyAgICAgICAgaWYocHJlZml4ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBwcmVmaXgrJzonK3BwLmdldEF0dHJpYnV0ZU5hbWUoaW5kZXgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIHBwLmdldEF0dHJpYnV0ZU5hbWUoaW5kZXgpOworICAgICAgICB9CisgICAgfQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZShpbnQgaW5kZXgpIHsgcmV0dXJuIHBwLmdldEF0dHJpYnV0ZVR5cGUoaW5kZXgpOyB9CisgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZShpbnQgaW5kZXgpIHsgcmV0dXJuIHBwLmdldEF0dHJpYnV0ZVZhbHVlKGluZGV4KTsgfQorCisgICAgcHVibGljIGludCBnZXRJbmRleChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHAuZ2V0QXR0cmlidXRlQ291bnQoKTsgaSsrKQorICAgICAgICB7CisgICAgICAgICAgICBpZihwcC5nZXRBdHRyaWJ1dGVOYW1lc3BhY2UoaSkuZXF1YWxzKHVyaSkKKyAgICAgICAgICAgICAgICYmIHBwLmdldEF0dHJpYnV0ZU5hbWUoaSkuZXF1YWxzKGxvY2FsTmFtZSkpCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRJbmRleChTdHJpbmcgcU5hbWUpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcC5nZXRBdHRyaWJ1dGVDb3VudCgpOyBpKyspCisgICAgICAgIHsKKyAgICAgICAgICAgIGlmKHBwLmdldEF0dHJpYnV0ZU5hbWUoaSkuZXF1YWxzKHFOYW1lKSkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBwLmdldEF0dHJpYnV0ZUNvdW50KCk7IGkrKykKKyAgICAgICAgeworICAgICAgICAgICAgaWYocHAuZ2V0QXR0cmlidXRlTmFtZXNwYWNlKGkpLmVxdWFscyh1cmkpCisgICAgICAgICAgICAgICAmJiBwcC5nZXRBdHRyaWJ1dGVOYW1lKGkpLmVxdWFscyhsb2NhbE5hbWUpKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIHJldHVybiBwcC5nZXRBdHRyaWJ1dGVUeXBlKGkpOworICAgICAgICAgICAgfQorCisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZShTdHJpbmcgcU5hbWUpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcC5nZXRBdHRyaWJ1dGVDb3VudCgpOyBpKyspCisgICAgICAgIHsKKyAgICAgICAgICAgIGlmKHBwLmdldEF0dHJpYnV0ZU5hbWUoaSkuZXF1YWxzKHFOYW1lKSkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcHAuZ2V0QXR0cmlidXRlVHlwZShpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpIHsKKyAgICAgICAgcmV0dXJuIHBwLmdldEF0dHJpYnV0ZVZhbHVlKHVyaSwgbG9jYWxOYW1lKTsKKyAgICB9CisgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZShTdHJpbmcgcU5hbWUpIHsKKyAgICAgICAgcmV0dXJuIHBwLmdldEF0dHJpYnV0ZVZhbHVlKG51bGwsIHFOYW1lKTsKKyAgICB9CisKKyAgICAvLyAtLSBMb2NhdG9yIGludGVyZmFjZQorCisgICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpIHsgcmV0dXJuIG51bGw7IH0KKyAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkgeyByZXR1cm4gc3lzdGVtSWQ7IH0KKyAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKSB7IHJldHVybiBwcC5nZXRMaW5lTnVtYmVyKCk7IH0KKyAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpIHsgcmV0dXJuIHBwLmdldENvbHVtbk51bWJlcigpOyB9CisKKyAgICAvLyAtLS0gWE1MUmVhZGVyIGludGVyZmFjZQorCisgICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSkKKyAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgaWYoTkFNRVNQQUNFU19GRUFUVVJFLmVxdWFscyhuYW1lKSkgeworICAgICAgICAgICAgcmV0dXJuIHBwLmdldEZlYXR1cmUoWG1sUHVsbFBhcnNlci5GRUFUVVJFX1BST0NFU1NfTkFNRVNQQUNFUyk7CisgICAgICAgIH0gZWxzZSBpZihOQU1FU1BBQ0VfUFJFRklYRVNfRkVBVFVSRS5lcXVhbHMobmFtZSkpIHsKKyAgICAgICAgICAgIHJldHVybiBwcC5nZXRGZWF0dXJlKFhtbFB1bGxQYXJzZXIuRkVBVFVSRV9SRVBPUlRfTkFNRVNQQUNFX0FUVFJJQlVURVMpOworICAgICAgICB9IGVsc2UgaWYoVkFMSURBVElPTl9GRUFUVVJFLmVxdWFscyhuYW1lKSkgeworICAgICAgICAgICAgcmV0dXJuIHBwLmdldEZlYXR1cmUoWG1sUHVsbFBhcnNlci5GRUFUVVJFX1ZBTElEQVRJT04pOworICAgICAgICAgICAgLy8gICAgICAgIH0gZWxzZSBpZihBUEFDSEVfU0NIRU1BX1ZBTElEQVRJT05fRkVBVFVSRS5lcXVhbHMobmFtZSkpIHsKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAgLy9UT0RPCisgICAgICAgICAgICAvLyAgICAgICAgfSBlbHNlIGlmKEFQQUNIRV9EWU5BTUlDX1ZBTElEQVRJT05fRkVBVFVSRS5lcXVhbHMobmFtZSkpIHsKKyAgICAgICAgICAgIC8vICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvL1RPRE8KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBwcC5nZXRGZWF0dXJlKG5hbWUpOworICAgICAgICAgICAgLy90aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigidW5yZWNvZ25pemVkIGZlYXR1cmUgIituYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUgKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKQorICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uCisgICAgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYoTkFNRVNQQUNFU19GRUFUVVJFLmVxdWFscyhuYW1lKSkgeworICAgICAgICAgICAgICAgIHBwLnNldEZlYXR1cmUoWG1sUHVsbFBhcnNlci5GRUFUVVJFX1BST0NFU1NfTkFNRVNQQUNFUywgdmFsdWUpOworICAgICAgICAgICAgfSBlbHNlIGlmKE5BTUVTUEFDRV9QUkVGSVhFU19GRUFUVVJFLmVxdWFscyhuYW1lKSkgeworICAgICAgICAgICAgICAgIGlmKHBwLmdldEZlYXR1cmUoWG1sUHVsbFBhcnNlci5GRUFUVVJFX1JFUE9SVF9OQU1FU1BBQ0VfQVRUUklCVVRFUykgIT0gdmFsdWUpIHsKKyAgICAgICAgICAgICAgICAgICAgcHAuc2V0RmVhdHVyZShYbWxQdWxsUGFyc2VyLkZFQVRVUkVfUkVQT1JUX05BTUVTUEFDRV9BVFRSSUJVVEVTLCB2YWx1ZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIGlmKFZBTElEQVRJT05fRkVBVFVSRS5lcXVhbHMobmFtZSkpIHsKKyAgICAgICAgICAgICAgICBwcC5zZXRGZWF0dXJlKFhtbFB1bGxQYXJzZXIuRkVBVFVSRV9WQUxJREFUSU9OLCB2YWx1ZSk7CisgICAgICAgICAgICAgICAgLy8gICAgICAgICAgfSBlbHNlIGlmKEFQQUNIRV9TQ0hFTUFfVkFMSURBVElPTl9GRUFUVVJFLmVxdWFscyhuYW1lKSkgeworICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAvLyBjYW4gaWdub3JlIGFzIHZhbGlkYXRpb24gbXVzdCBiZSBmYWxzZSAuLi4KKyAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgIGlmKHRydWUgPT0gdmFsdWUpIHsKKyAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJzY2hlbWEgdmFsaWRhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgIC8vICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gICAgICAgICAgfSBlbHNlIGlmKEFQQUNIRV9EWU5BTUlDX1ZBTElEQVRJT05fRkVBVFVSRS5lcXVhbHMobmFtZSkpIHsKKyAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgaWYodHJ1ZSA9PSB2YWx1ZSkgeworICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiZHluYW1pYyB2YWxpZGF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBwcC5zZXRGZWF0dXJlKG5hbWUsIHZhbHVlKTsKKyAgICAgICAgICAgICAgICAvL3Rocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKCJ1bnJlY29nbml6ZWQgZmVhdHVyZSAiK25hbWUpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoKFhtbFB1bGxQYXJzZXJFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgLy8gdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigicHJvYmxlbSB3aXRoIHNldHRpbmcgZmVhdHVyZSAiK25hbWUrIjogIitleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5IChTdHJpbmcgbmFtZSkKKyAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgaWYoREVDTEFSQVRJT05fSEFORExFUl9QUk9QRVJUWS5lcXVhbHMobmFtZSkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9IGVsc2UgaWYoTEVYSUNBTF9IQU5ETEVSX1BST1BFUlRZLmVxdWFscyhuYW1lKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gcHAuZ2V0UHJvcGVydHkobmFtZSk7CisgICAgICAgICAgICAvL3Rocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKCJub3QgcmVjb2duaXplZCBnZXQgcHJvcGVydHkgIituYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5IChTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKQorICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uCisgICAgeworICAgICAgICAvLworICAgICAgICBpZihERUNMQVJBVElPTl9IQU5ETEVSX1BST1BFUlRZLmVxdWFscyhuYW1lKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigibm90IHN1cHBvcnRlZCBzZXR0aW5nIHByb3BlcnR5ICIrbmFtZSk7Ly8rIiB0byAiK3ZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmKExFWElDQUxfSEFORExFUl9QUk9QRVJUWS5lcXVhbHMobmFtZSkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIm5vdCBzdXBwb3J0ZWQgc2V0dGluZyBwcm9wZXJ0eSAiK25hbWUpOy8vKyIgdG8gIit2YWx1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHBwLnNldFByb3BlcnR5KG5hbWUsIHZhbHVlKTsKKyAgICAgICAgICAgIH0gY2F0Y2goWG1sUHVsbFBhcnNlckV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIm5vdCBzdXBwb3J0ZWQgc2V0IHByb3BlcnR5ICIrbmFtZSsiOiAiKyBleCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvL3Rocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKCJub3QgcmVjb2duaXplZCBzZXQgcHJvcGVydHkgIituYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyIChFbnRpdHlSZXNvbHZlciByZXNvbHZlcikge30KKworICAgIHB1YmxpYyBFbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlciAoKSB7IHJldHVybiBudWxsOyB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyIChEVERIYW5kbGVyIGhhbmRsZXIpIHt9CisKKyAgICBwdWJsaWMgRFRESGFuZGxlciBnZXREVERIYW5kbGVyICgpIHsgcmV0dXJuIG51bGw7IH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyIChDb250ZW50SGFuZGxlciBoYW5kbGVyKQorICAgIHsKKyAgICAgICAgdGhpcy5jb250ZW50SGFuZGxlciA9IGhhbmRsZXI7CisgICAgfQorCisgICAgcHVibGljIENvbnRlbnRIYW5kbGVyIGdldENvbnRlbnRIYW5kbGVyKCkgeyByZXR1cm4gY29udGVudEhhbmRsZXI7IH0KKworICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgaGFuZGxlcikgeworICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGhhbmRsZXI7CisgICAgfQorCisgICAgcHVibGljIEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7IHJldHVybiBlcnJvckhhbmRsZXI7IH0KKworICAgIHB1YmxpYyB2b2lkIHBhcnNlKElucHV0U291cmNlIHNvdXJjZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24KKyAgICB7CisKKyAgICAgICAgc3lzdGVtSWQgPSBzb3VyY2UuZ2V0U3lzdGVtSWQoKTsKKyAgICAgICAgY29udGVudEhhbmRsZXIuc2V0RG9jdW1lbnRMb2NhdG9yKHRoaXMpOworCisgICAgICAgIGZpbmFsIFJlYWRlciByZWFkZXIgPSBzb3VyY2UuZ2V0Q2hhcmFjdGVyU3RyZWFtKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAocmVhZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBzdHJlYW0gPSBzb3VyY2UuZ2V0Qnl0ZVN0cmVhbSgpOworICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBlbmNvZGluZyA9IHNvdXJjZS5nZXRFbmNvZGluZygpOworCisgICAgICAgICAgICAgICAgaWYgKHN0cmVhbSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHN5c3RlbUlkID0gc291cmNlLmdldFN5c3RlbUlkKCk7CisgICAgICAgICAgICAgICAgICAgIGlmKHN5c3RlbUlkID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFNBWFBhcnNlRXhjZXB0aW9uIHNheEV4Y2VwdGlvbiA9IG5ldyBTQVhQYXJzZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAibnVsbCBzb3VyY2Ugc3lzdGVtSWQiICwgdGhpcyk7CisgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuZmF0YWxFcnJvcihzYXhFeGNlcHRpb24pOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8vIE5PVEU6IHJlcGxhY2Ugd2l0aCBDb25uZWN0aW9uIHRvIHJ1biBpbiBKMk1FIGVudmlyb25tZW50CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBVUkwgdXJsID0gbmV3IFVSTChzeXN0ZW1JZCk7CisgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0gPSB1cmwub3BlblN0cmVhbSgpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gbnVlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbSA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oc3lzdGVtSWQpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGZuZmUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTQVhQYXJzZUV4Y2VwdGlvbiBzYXhFeGNlcHRpb24gPSBuZXcgU0FYUGFyc2VFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb3VsZCBub3Qgb3BlbiBmaWxlIHdpdGggc3lzdGVtSWQgIitzeXN0ZW1JZCwgdGhpcywgZm5mZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmZhdGFsRXJyb3Ioc2F4RXhjZXB0aW9uKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcHAuc2V0SW5wdXQoc3RyZWFtLCBlbmNvZGluZyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHBwLnNldElucHV0KHJlYWRlcik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFhtbFB1bGxQYXJzZXJFeGNlcHRpb24gZXgpICB7CisgICAgICAgICAgICBmaW5hbCBTQVhQYXJzZUV4Y2VwdGlvbiBzYXhFeGNlcHRpb24gPSBuZXcgU0FYUGFyc2VFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgInBhcnNpbmcgaW5pdGlhbGl6YXRpb24gZXJyb3I6ICIrZXgsIHRoaXMsIGV4KTsKKyAgICAgICAgICAgIC8vaWYoREVCVUcpIGV4LnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmZhdGFsRXJyb3Ioc2F4RXhjZXB0aW9uKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHN0YXJ0IHBhcnNpbmcgLSBtb3ZlIHRvIGZpcnN0IHN0YXJ0IHRhZworICAgICAgICB0cnkgeworICAgICAgICAgICAgY29udGVudEhhbmRsZXIuc3RhcnREb2N1bWVudCgpOworICAgICAgICAgICAgLy8gZ2V0IGZpcnN0IGV2ZW50CisgICAgICAgICAgICBwcC5uZXh0KCk7CisgICAgICAgICAgICAvLyBpdCBzaG91bGQgYmUgc3RhcnQgdGFnLi4uCisgICAgICAgICAgICBpZihwcC5nZXRFdmVudFR5cGUoKSAhPSBYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRykgeworICAgICAgICAgICAgICAgIGZpbmFsIFNBWFBhcnNlRXhjZXB0aW9uIHNheEV4Y2VwdGlvbiA9IG5ldyBTQVhQYXJzZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgImV4cGVjdGVkIHN0YXJ0IHRhZyBub3QiK3BwLmdldFBvc2l0aW9uRGVzY3JpcHRpb24oKSwgdGhpcyk7CisgICAgICAgICAgICAgICAgLy90aHJvdyBzYXhFeGNlcHRpb247CisgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmZhdGFsRXJyb3Ioc2F4RXhjZXB0aW9uKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFhtbFB1bGxQYXJzZXJFeGNlcHRpb24gZXgpICB7CisgICAgICAgICAgICBmaW5hbCBTQVhQYXJzZUV4Y2VwdGlvbiBzYXhFeGNlcHRpb24gPSBuZXcgU0FYUGFyc2VFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgInBhcnNpbmcgaW5pdGlhbGl6YXRpb24gZXJyb3I6ICIrZXgsIHRoaXMsIGV4KTsKKyAgICAgICAgICAgIC8vZXgucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBlcnJvckhhbmRsZXIuZmF0YWxFcnJvcihzYXhFeGNlcHRpb24pOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLy8gbm93IHJlYWwgcGFyc2luZyBjYW4gc3RhcnQhCisKKyAgICAgICAgcGFyc2VTdWJUcmVlKHBwKTsKKworICAgICAgICAvLyBhbmQgZmluaXNoZWQgLi4uCisKKyAgICAgICAgY29udGVudEhhbmRsZXIuZW5kRG9jdW1lbnQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBwYXJzZShTdHJpbmcgc3lzdGVtSWQpIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcGFyc2UobmV3IElucHV0U291cmNlKHN5c3RlbUlkKSk7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCBwYXJzZVN1YlRyZWUoWG1sUHVsbFBhcnNlciBwcCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLnBwID0gcHA7CisgICAgICAgIGZpbmFsIGJvb2xlYW4gbmFtZXNwYWNlQXdhcmUgPSBwcC5nZXRGZWF0dXJlKFhtbFB1bGxQYXJzZXIuRkVBVFVSRV9QUk9DRVNTX05BTUVTUEFDRVMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYocHAuZ2V0RXZlbnRUeXBlKCkgIT0gWG1sUHVsbFBhcnNlci5TVEFSVF9UQUcpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAic3RhcnQgdGFnIG11c3QgYmUgcmVhZCBiZWZvcmUgc2tpcGluZyBzdWJ0cmVlIitwcC5nZXRQb3NpdGlvbkRlc2NyaXB0aW9uKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmluYWwgaW50W10gaG9sZGVyRm9yU3RhcnRBbmRMZW5ndGggPSBuZXcgaW50WzJdOworICAgICAgICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciByYXdOYW1lID0gbmV3IFN0cmluZ0J1aWxkZXIoMTYpOworICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IG51bGw7CisgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IG51bGw7CisgICAgICAgICAgICBpbnQgbGV2ZWwgPSBwcC5nZXREZXB0aCgpIC0gMTsKKyAgICAgICAgICAgIGludCB0eXBlID0gWG1sUHVsbFBhcnNlci5TVEFSVF9UQUc7CisKKyAgICAgICAgICAgIExPT1A6CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgc3dpdGNoKHR5cGUpIHsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSBYbWxQdWxsUGFyc2VyLlNUQVJUX1RBRzoKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmKG5hbWVzcGFjZUF3YXJlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGRlcHRoID0gcHAuZ2V0RGVwdGgoKSAtIDE7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGNvdW50UHJldiA9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsZXZlbCA+IGRlcHRoKSA/IHBwLmdldE5hbWVzcGFjZUNvdW50KGRlcHRoKSA6IDA7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pbnQgY291bnRQcmV2ID0gcHAuZ2V0TmFtZXNwYWNlQ291bnQocHAuZ2V0RGVwdGgoKSAtIDEpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBjb3VudCA9IHBwLmdldE5hbWVzcGFjZUNvdW50KGRlcHRoICsgMSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGNvdW50UHJldjsgaSA8IGNvdW50OyBpKyspCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50SGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcC5nZXROYW1lc3BhY2VQcmVmaXgoaSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcC5nZXROYW1lc3BhY2VVcmkoaSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9IHBwLmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBwcC5nZXRQcmVmaXgoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihwcmVmaXggIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdOYW1lLnNldExlbmd0aCgwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3TmFtZS5hcHBlbmQocHJlZml4KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3TmFtZS5hcHBlbmQoJzonKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3TmFtZS5hcHBlbmQobmFtZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0RWxlbWVudChwcC5nZXROYW1lc3BhY2UoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyBGaXhlZCB0aGlzLiBXYXMgIm5vdCBlcXVhbHMiLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPT0gbnVsbCA/IG5hbWUgOiByYXdOYW1lLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydEVsZW1lbnQocHAuZ2V0TmFtZXNwYWNlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBwLmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHAuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIC8vKytsZXZlbDsKKworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgWG1sUHVsbFBhcnNlci5URVhUOgorICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgY2hhcltdIGNoYXJzID0gcHAuZ2V0VGV4dENoYXJhY3RlcnMoaG9sZGVyRm9yU3RhcnRBbmRMZW5ndGgpOworICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEhhbmRsZXIuY2hhcmFjdGVycyhjaGFycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG9sZGVyRm9yU3RhcnRBbmRMZW5ndGhbMF0sIC8vc3RhcnQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG9sZGVyRm9yU3RhcnRBbmRMZW5ndGhbMV0gLy9sZW4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgWG1sUHVsbFBhcnNlci5FTkRfVEFHOgorICAgICAgICAgICAgICAgICAgICAgICAgLy8tLWxldmVsOworICAgICAgICAgICAgICAgICAgICAgICAgaWYobmFtZXNwYWNlQXdhcmUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gcHAuZ2V0TmFtZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IHBwLmdldFByZWZpeCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHByZWZpeCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd05hbWUuc2V0TGVuZ3RoKDApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdOYW1lLmFwcGVuZChwcmVmaXgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdOYW1lLmFwcGVuZCgnOicpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdOYW1lLmFwcGVuZChuYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEhhbmRsZXIuZW5kRWxlbWVudChwcC5nZXROYW1lc3BhY2UoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggIT0gbnVsbCA/IG5hbWUgOiByYXdOYW1lLnRvU3RyaW5nKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3aGVuIGVudGVyaW5nIHNob3cgcHJlZml4ZXMgZm9yIGFsbCBsZXZlbHMhISEhCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGRlcHRoID0gcHAuZ2V0RGVwdGgoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgY291bnRQcmV2ID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxldmVsID4gZGVwdGgpID8gcHAuZ2V0TmFtZXNwYWNlQ291bnQocHAuZ2V0RGVwdGgoKSkgOiAwOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb3VudCA9IHBwLmdldE5hbWVzcGFjZUNvdW50KHBwLmdldERlcHRoKCkgLSAxKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1bmRlY2xhcmUgdGhlbSBpbiByZXZlcnNlIG9yZGVyCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGNvdW50IC0gMTsgaSA+PSBjb3VudFByZXY7IGktLSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcC5nZXROYW1lc3BhY2VQcmVmaXgoaSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLmVuZEVsZW1lbnQocHAuZ2V0TmFtZXNwYWNlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcC5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcC5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGNhc2UgWG1sUHVsbFBhcnNlci5FTkRfRE9DVU1FTlQ6CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBMT09QOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0eXBlID0gcHAubmV4dCgpOworICAgICAgICAgICAgfSB3aGlsZShwcC5nZXREZXB0aCgpID4gbGV2ZWwpOworICAgICAgICB9IGNhdGNoIChYbWxQdWxsUGFyc2VyRXhjZXB0aW9uIGV4KSAgeworICAgICAgICAgICAgZmluYWwgU0FYUGFyc2VFeGNlcHRpb24gc2F4RXhjZXB0aW9uID0gbmV3IFNBWFBhcnNlRXhjZXB0aW9uKCJwYXJzaW5nIGVycm9yOiAiK2V4LCB0aGlzLCBleCk7CisgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGVycm9ySGFuZGxlci5mYXRhbEVycm9yKHNheEV4Y2VwdGlvbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxscyB7QGxpbmsgQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50KFN0cmluZywgU3RyaW5nLCBTdHJpbmcsIEF0dHJpYnV0ZXMpIHN0YXJ0RWxlbWVudH0KKyAgICAgKiBvbiB0aGUgPGNvZGU+Q29udGVudEhhbmRsZXI8L2NvZGU+IHdpdGggPGNvZGU+dGhpczwvY29kZT4gZHJpdmVyIG9iamVjdCBhcyB0aGUKKyAgICAgKiB7QGxpbmsgQXR0cmlidXRlc30gaW1wbGVtZW50YXRpb24uIEluIGRlZmF1bHQgaW1wbGVtZW50YXRpb24KKyAgICAgKiB7QGxpbmsgQXR0cmlidXRlc30gb2JqZWN0IGlzIHZhbGlkIG9ubHkgZHVyaW5nIHRoaXMgbWV0aG9kIGNhbGwgYW5kIG1heSBub3QKKyAgICAgKiBiZSBzdG9yZWQuIFN1Yi1jbGFzc2VzIGNhbiBvdmVyd3JpdGUgdGhpcyBtZXRob2QgdG8gY2FjaGUgYXR0cmlidXRlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKKyAgICAgICAgY29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KG5hbWVzcGFjZSwgbG9jYWxOYW1lLCBxTmFtZSwgdGhpcyk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS94bWwvc3JjL3Rlc3QvamF2YS9vcmcva3htbDIvaW8vS1htbFNlcmlhbGl6ZXJUZXN0LmphdmEgYi94bWwvc3JjL3Rlc3QvamF2YS9vcmcva3htbDIvaW8vS1htbFNlcmlhbGl6ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2FiYTc0NgotLS0gL2Rldi9udWxsCisrKyBiL3htbC9zcmMvdGVzdC9qYXZhL29yZy9reG1sMi9pby9LWG1sU2VyaWFsaXplclRlc3QuamF2YQpAQCAtMCwwICsxLDExOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAwOSBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmt4bWwyLmlvOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKK2ltcG9ydCBvcmcueG1scHVsbC52MS5YbWxTZXJpYWxpemVyOworCitpbXBvcnQgc3RhdGljIHRlc3RzLnN1cHBvcnQuU3VwcG9ydF9YbWwuKjsKKworcHVibGljIGNsYXNzIEtYbWxTZXJpYWxpemVyVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNWYWxpZFhtbENvZGVQb2ludChpbnQgYykgeworICAgICAgICAvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLyNjaGFyc2V0cworICAgICAgICByZXR1cm4gKGMgPj0gMHgyMCAmJiBjIDw9IDB4ZDdmZikgfHwgKGMgPT0gMHg5KSB8fCAoYyA9PSAweGEpIHx8IChjID09IDB4ZCkgfHwKKyAgICAgICAgICAgICAgICAoYyA+PSAweGUwMDAgJiYgYyA8PSAweGZmZmQpIHx8IChjID49IDB4MTAwMDAgJiYgYyA8PSAweDEwZmZmZik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgWG1sU2VyaWFsaXplciBuZXdTZXJpYWxpemVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVzT3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICBYbWxTZXJpYWxpemVyIHNlcmlhbGl6ZXIgPSBuZXcgS1htbFNlcmlhbGl6ZXIoKTsKKyAgICAgICAgc2VyaWFsaXplci5zZXRPdXRwdXQoYnl0ZXNPdXQsICJVVEYtOCIpOworICAgICAgICBzZXJpYWxpemVyLnN0YXJ0RG9jdW1lbnQoIlVURi04IiwgbnVsbCk7CisgICAgICAgIHJldHVybiBzZXJpYWxpemVyOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkQ2hhcmFjdGVyc0luVGV4dCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFhtbFNlcmlhbGl6ZXIgc2VyaWFsaXplciA9IG5ld1NlcmlhbGl6ZXIoKTsKKyAgICAgICAgc2VyaWFsaXplci5zdGFydFRhZyhOQU1FU1BBQ0UsICJyb290Iik7CisgICAgICAgIGZvciAoaW50IGNoID0gMDsgY2ggPD0gMHhmZmZmOyArK2NoKSB7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcyA9IENoYXJhY3Rlci50b1N0cmluZygoY2hhcikgY2gpOworICAgICAgICAgICAgaWYgKGlzVmFsaWRYbWxDb2RlUG9pbnQoY2gpKSB7CisgICAgICAgICAgICAgICAgc2VyaWFsaXplci50ZXh0KCJhIiArIHMgKyAiYiIpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzZXJpYWxpemVyLnRleHQoImEiICsgcyArICJiIik7CisgICAgICAgICAgICAgICAgICAgIGZhaWwocyk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHNlcmlhbGl6ZXIuZW5kVGFnKE5BTUVTUEFDRSwgInJvb3QiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZENoYXJhY3RlcnNJbkF0dHJpYnV0ZVZhbHVlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFhtbFNlcmlhbGl6ZXIgc2VyaWFsaXplciA9IG5ld1NlcmlhbGl6ZXIoKTsKKyAgICAgICAgc2VyaWFsaXplci5zdGFydFRhZyhOQU1FU1BBQ0UsICJyb290Iik7CisgICAgICAgIGZvciAoaW50IGNoID0gMDsgY2ggPD0gMHhmZmZmOyArK2NoKSB7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcyA9IENoYXJhY3Rlci50b1N0cmluZygoY2hhcikgY2gpOworICAgICAgICAgICAgaWYgKGlzVmFsaWRYbWxDb2RlUG9pbnQoY2gpKSB7CisgICAgICAgICAgICAgICAgc2VyaWFsaXplci5hdHRyaWJ1dGUoTkFNRVNQQUNFLCAiYSIsICJhIiArIHMgKyAiYiIpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzZXJpYWxpemVyLmF0dHJpYnV0ZShOQU1FU1BBQ0UsICJhIiwgImEiICsgcyArICJiIik7CisgICAgICAgICAgICAgICAgICAgIGZhaWwocyk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHNlcmlhbGl6ZXIuZW5kVGFnKE5BTUVTUEFDRSwgInJvb3QiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZENoYXJhY3RlcnNJbkNkYXRhU2VjdGlvbnMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBYbWxTZXJpYWxpemVyIHNlcmlhbGl6ZXIgPSBuZXdTZXJpYWxpemVyKCk7CisgICAgICAgIHNlcmlhbGl6ZXIuc3RhcnRUYWcoTkFNRVNQQUNFLCAicm9vdCIpOworICAgICAgICBmb3IgKGludCBjaCA9IDA7IGNoIDw9IDB4ZmZmZjsgKytjaCkgeworICAgICAgICAgICAgZmluYWwgU3RyaW5nIHMgPSBDaGFyYWN0ZXIudG9TdHJpbmcoKGNoYXIpIGNoKTsKKyAgICAgICAgICAgIGlmIChpc1ZhbGlkWG1sQ29kZVBvaW50KGNoKSkgeworICAgICAgICAgICAgICAgIHNlcmlhbGl6ZXIuY2RzZWN0KCJhIiArIHMgKyAiYiIpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBzZXJpYWxpemVyLmNkc2VjdCgiYSIgKyBzICsgImIiKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbChzKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgc2VyaWFsaXplci5lbmRUYWcoTkFNRVNQQUNFLCAicm9vdCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRlc3RDZGF0YVdpdGhUZXJtaW5hdG9ySW5zaWRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1dyaXRlciB3cml0ZXIgPSBuZXcgU3RyaW5nV3JpdGVyKCk7CisgICAgICAgIFhtbFNlcmlhbGl6ZXIgc2VyaWFsaXplciA9IG5ldyBLWG1sU2VyaWFsaXplcigpOworICAgICAgICBzZXJpYWxpemVyLnNldE91dHB1dCh3cml0ZXIpOworICAgICAgICBzZXJpYWxpemVyLnN0YXJ0RG9jdW1lbnQoIlVURi04IiwgbnVsbCk7CisgICAgICAgIHNlcmlhbGl6ZXIuc3RhcnRUYWcoTkFNRVNQQUNFLCAicCIpOworICAgICAgICBzZXJpYWxpemVyLmNkc2VjdCgiYV1dPmIiKTsKKyAgICAgICAgc2VyaWFsaXplci5lbmRUYWcoTkFNRVNQQUNFLCAicCIpOworICAgICAgICBzZXJpYWxpemVyLmVuZERvY3VtZW50KCk7CisgICAgICAgIC8vIEFkamFjZW50IENEQVRBIHNlY3Rpb25zIGFyZW4ndCBtZXJnZWQsIHNvIGxldCdzIHN0aWNrIHRoZW0gdG9nZXRoZXIgb3Vyc2VsdmVzLi4uCisgICAgICAgIERvY3VtZW50IGRvYyA9IGRvbU9mKHdyaXRlci50b1N0cmluZygpKTsKKyAgICAgICAgTm9kZUxpc3QgY2hpbGRyZW4gPSBkb2MuZ2V0Rmlyc3RDaGlsZCgpLmdldENoaWxkTm9kZXMoKTsKKyAgICAgICAgU3RyaW5nIHRleHQgPSAiIjsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaGlsZHJlbi5nZXRMZW5ndGgoKTsgKytpKSB7CisgICAgICAgICAgICB0ZXh0ICs9IGNoaWxkcmVuLml0ZW0oaSkuZ2V0Tm9kZVZhbHVlKCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJhXV0+YiIsIHRleHQpOworICAgIH0KK30K